summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/imagebuilder/Makefile3
-rw-r--r--target/linux/apm821xx/base-files/etc/board.d/01_leds12
-rw-r--r--target/linux/apm821xx/base-files/etc/board.d/02_network3
-rw-r--r--target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version2
-rw-r--r--target/linux/apm821xx/base-files/lib/preinit/05_set_iface_mac_apm821xx13
-rw-r--r--target/linux/apm821xx/dts/meraki-mr24.dts20
-rw-r--r--target/linux/apm821xx/dts/meraki-mx60.dts264
-rw-r--r--target/linux/apm821xx/dts/netgear-wndap6x0.dtsi2
-rw-r--r--target/linux/apm821xx/dts/netgear-wndr4700.dts93
-rw-r--r--target/linux/apm821xx/image/nand.mk6
-rw-r--r--target/linux/apm821xx/nand/config-default12
-rw-r--r--target/linux/archs38/Makefile2
-rw-r--r--target/linux/archs38/config-6.1268
-rw-r--r--target/linux/archs38/config-6.6279
-rw-r--r--target/linux/archs38/generic/target.mk2
-rw-r--r--target/linux/armsr/armv8/config-6.63
-rw-r--r--target/linux/armsr/base-files/etc/inittab2
-rw-r--r--target/linux/armsr/config-6.61
-rw-r--r--target/linux/armsr/image/Makefile1
-rw-r--r--target/linux/armsr/modules.mk2
-rw-r--r--target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch23
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch44
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch99
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch88
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch50
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch101
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch73
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch111
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch28
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch93
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch320
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch203
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch113
-rw-r--r--target/linux/at91/Makefile2
-rw-r--r--target/linux/at91/files/arch/arm/boot/dts/at91-q5xr5.dts193
-rw-r--r--target/linux/at91/files/arch/arm/boot/dts/lmu5000.dts124
-rw-r--r--target/linux/at91/image/Makefile1
-rw-r--r--target/linux/at91/image/sam9x.mk1
-rw-r--r--target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch34
-rw-r--r--target/linux/at91/sam9x/config-6.1341
-rw-r--r--target/linux/at91/sam9x/config-6.6346
-rw-r--r--target/linux/at91/sama5/config-6.1517
-rw-r--r--target/linux/at91/sama5/config-6.6524
-rw-r--r--target/linux/at91/sama7/config-6.1424
-rw-r--r--target/linux/at91/sama7/config-6.6431
-rw-r--r--target/linux/ath79/config-6.68
-rw-r--r--target/linux/ath79/dts/ar7100.dtsi2
-rw-r--r--target/linux/ath79/dts/ar7100_mikrotik_routerboard-4xx.dtsi5
-rw-r--r--target/linux/ath79/dts/ar7240.dtsi4
-rw-r--r--target/linux/ath79/dts/ar7242.dtsi2
-rw-r--r--target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts2
-rw-r--r--target/linux/ath79/dts/ar724x.dtsi2
-rw-r--r--target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts243
-rw-r--r--target/linux/ath79/dts/ar9344_nec_aterm.dtsi300
-rw-r--r--target/linux/ath79/dts/ar9344_nec_wg600hp.dts16
-rw-r--r--target/linux/ath79/dts/ar9344_nec_wr8750n.dts16
-rw-r--r--target/linux/ath79/dts/ar9344_nec_wr9500n.dts39
-rw-r--r--target/linux/ath79/dts/ar9344_qihoo_c301.dts8
-rw-r--r--target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts4
-rw-r--r--target/linux/ath79/dts/qca9531_glinet_gl-s200.dtsi1
-rw-r--r--target/linux/ath79/dts/qca953x.dtsi2
-rw-r--r--target/linux/ath79/dts/qca9557_sophos_ap15.dts148
-rw-r--r--target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts2
-rw-r--r--target/linux/ath79/dts/qca9558_sophos_ap15.dts163
-rw-r--r--target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts2
-rw-r--r--target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts2
-rw-r--r--target/linux/ath79/dts/qca955x.dtsi4
-rw-r--r--target/linux/ath79/dts/qca955x_elecom_wab.dtsi17
-rw-r--r--target/linux/ath79/dts/qca9561_nec_wf1200cr.dts7
-rw-r--r--target/linux/ath79/dts/qca9563_nec_wg1200cr.dts7
-rw-r--r--target/linux/ath79/dts/qca9563_nec_wg800hp.dts29
-rw-r--r--target/linux/ath79/dts/qca956x.dtsi2
-rw-r--r--target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c41
-rw-r--r--target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c30
-rw-r--r--target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c18
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Kconfig8
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Makefile14
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h10
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_legacy_debugfs.c (renamed from target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c)0
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_legacy_mdio.c250
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c31
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c250
-rw-r--r--target/linux/ath79/generic/base-files/etc/board.d/02_network5
-rw-r--r--target/linux/ath79/generic/base-files/etc/board.d/03_gpio_switches92
-rw-r--r--target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom10
-rw-r--r--target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac12
-rw-r--r--target/linux/ath79/generic/base-files/lib/upgrade/platform.sh3
-rw-r--r--target/linux/ath79/generic/config-default2
-rw-r--r--target/linux/ath79/image/common-nec.mk25
-rw-r--r--target/linux/ath79/image/generic-ubnt.mk1
-rw-r--r--target/linux/ath79/image/generic.mk22
-rw-r--r--target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h1
-rw-r--r--target/linux/ath79/image/lzma-loader/src/board.c89
-rw-r--r--target/linux/ath79/image/nand.mk2
-rw-r--r--target/linux/ath79/image/tiny.mk31
-rw-r--r--target/linux/ath79/mikrotik/config-default2
-rw-r--r--target/linux/ath79/nand/base-files/etc/board.d/03_gpio_switches2
-rw-r--r--target/linux/ath79/nand/config-default1
-rw-r--r--target/linux/ath79/patches-6.6/001-v6.11-gpio-ath79-convert-to-dynamic-GPIO-base-allocation.patch32
-rw-r--r--target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch34
-rw-r--r--target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch41
-rw-r--r--target/linux/ath79/patches-6.6/330-missing-registers.patch2
-rw-r--r--target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch4
-rw-r--r--target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch2
-rw-r--r--target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch26
-rw-r--r--target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch4
-rw-r--r--target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch2
-rw-r--r--target/linux/ath79/patches-6.6/710-net-use-downstream-ag71xx.patch24
-rw-r--r--target/linux/ath79/patches-6.6/730-ar8216-make-reg-access-atomic.patch6
-rw-r--r--target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch2
-rw-r--r--target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch14
-rw-r--r--target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch2
-rw-r--r--target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch2
-rw-r--r--target/linux/ath79/tiny/base-files/etc/board.d/02_network17
-rw-r--r--target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh18
-rw-r--r--target/linux/ath79/tiny/config-default2
-rw-r--r--target/linux/bcm27xx/base-files/etc/diag.sh26
-rw-r--r--target/linux/bcm27xx/bcm2708/config-6.64
-rw-r--r--target/linux/bcm27xx/bcm2709/config-6.64
-rw-r--r--target/linux/bcm27xx/bcm2710/config-6.67
-rw-r--r--target/linux/bcm27xx/bcm2711/config-6.67
-rw-r--r--target/linux/bcm27xx/bcm2712/config-6.68
-rw-r--r--target/linux/bcm27xx/config-6.61
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch8
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0301-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0343-drm-panel-simple-add-Geekworm-MZP280-Panel.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0359-mm-page_alloc-cma-introduce-a-customisable-threshold.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0398-drm-panel-panel-ilitek9881c-Use-cansleep-methods.patch37
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0401-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch49
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0513-mmc-brcmstb-add-support-for-BCM2712.patch18
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0514-sdhci-Add-SD-Express-hook.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch20
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch10
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0536-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch328
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0636-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch41
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0716-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0757-drm-panel-add-panel-dsi.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0835-mmc-sdhci-brcmstb-remove-32-bit-accessors-for-BCM271.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch8
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0891-drivers-mmc-sdhci-brcmstb-fix-usage-of-SD_PIN_SEL-on.patch10
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0980-drivers-mmc-add-SD-support-for-Command-Queueing.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0981-drivers-sdhci-brcmstb-set-CQE-timer-clock-frequency.patch10
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0983-drivers-mmc-preallocate-a-block-for-SD-extension-reg.patch20
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0988-drivers-sdhci-brcmstb-work-around-mystery-CQE-CMD_ID.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0993-drivers-mmc-cqhci-clear-CQHCI_CTL-if-halt-fails.patch9
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0994-drivers-mmc-export-SD-extension-register-read-write-.patch22
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0995-drivers-mmc-be-more-cautious-when-manipulating-Comma.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0996-drivers-mmc-add-debugfs-entries-for-SD-extension-reg.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0997-drivers-mmc-handle-1024-byte-SD-General-Info-lengths.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1018-drivers-mmc-apply-SD-quirks-earlier-during-probe.patch77
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1020-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS400es-a.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1069-drm-panel-simple-Fix-7inch-panel-mode-for-misalignme.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1070-drm-panel-simple-Increase-pixel-clock-on-Pi-7inch-pa.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1112-mmc-sdhci-brcmstb-add-hs400_downgrade-callback-for-b.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1116-mmc-sdhci-extend-maximum-ADMA-transfer-length-to-4Mi.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1133-drivers-mmc-sdhci-brcmstb-improve-bcm2712-card-remov.patch52
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1136-feat-Add-support-for-SunFounder-PiPower-3-overlay.patch193
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1137-pwm-gpio-pwm-follow-pwm_apply_might_sleep-rename.patch32
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1138-drm-bridge-panel-Ensure-backlight-is-reachable.patch29
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch36
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1142-fixup-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS4.patch26
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1144-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch346
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1145-fixup-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch89
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch260
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch27
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch101
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch1171
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch86
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch106
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch97
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch162
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch2927
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch29
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch32
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch89
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch30
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch82
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch886
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch36
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch158
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch108
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch1288
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch52
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch157
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch70
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch28
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch25
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch25
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch132
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch92
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch313
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch9749
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch92
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch408
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch24
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch288
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch36
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch36
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch66
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch186
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch41
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch35
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch124
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch30
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch27
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch99
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch30
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch204
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch26
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch143
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch26
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch26
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch31
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch23
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch125
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch28
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch39
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch50
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch23
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch24
-rw-r--r--target/linux/bcm47xx/Makefile3
-rw-r--r--target/linux/bcm47xx/config-6.1190
-rw-r--r--target/linux/bcm47xx/patches-6.1/030-v6.3-MIPS-BCM47XX-Add-support-for-Linksys-E2500-V3.patch65
-rw-r--r--target/linux/bcm47xx/patches-6.1/130-MIPS-BCM47XX-Add-support-for-Huawei-B593u-12.patch61
-rw-r--r--target/linux/bcm47xx/patches-6.1/159-cpu_fixes.patch484
-rw-r--r--target/linux/bcm47xx/patches-6.1/160-kmap_coherent.patch78
-rw-r--r--target/linux/bcm47xx/patches-6.1/209-b44-register-adm-switch.patch121
-rw-r--r--target/linux/bcm47xx/patches-6.1/210-b44_phy_fix.patch54
-rw-r--r--target/linux/bcm47xx/patches-6.1/280-activate_ssb_support_in_usb.patch25
-rw-r--r--target/linux/bcm47xx/patches-6.1/300-fork_cacheflush.patch21
-rw-r--r--target/linux/bcm47xx/patches-6.1/310-no_highpage.patch74
-rw-r--r--target/linux/bcm47xx/patches-6.1/400-mtd-bcm47xxpart-get-nvram.patch34
-rw-r--r--target/linux/bcm47xx/patches-6.1/700-net-bgmac-connect-to-PHY-even-if-it-is-BGMAC_PHY_NOR.patch42
-rw-r--r--target/linux/bcm47xx/patches-6.1/701-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch33
-rw-r--r--target/linux/bcm47xx/patches-6.1/791-tg3-no-pci-sleep.patch17
-rw-r--r--target/linux/bcm47xx/patches-6.1/800-bcma-add-table-of-serial-flashes-with-smaller-blocks.patch73
-rw-r--r--target/linux/bcm47xx/patches-6.1/820-wgt634u-nvram-fix.patch296
-rw-r--r--target/linux/bcm47xx/patches-6.1/830-huawei_e970_support.patch101
-rw-r--r--target/linux/bcm47xx/patches-6.1/831-old_gpio_wdt.patch360
-rw-r--r--target/linux/bcm47xx/patches-6.1/900-ssb-reject-PCI-writes-setting-CardBus-bridge-resourc.patch30
-rw-r--r--target/linux/bcm47xx/patches-6.1/940-bcm47xx-yenta.patch48
-rw-r--r--target/linux/bcm47xx/patches-6.1/976-ssb_increase_pci_delay.patch11
-rw-r--r--target/linux/bcm47xx/patches-6.6/160-kmap_coherent.patch69
-rw-r--r--target/linux/bcm47xx/patches-6.6/300-fork_cacheflush.patch21
-rw-r--r--target/linux/bcm47xx/patches-6.6/310-no_highpage.patch75
-rw-r--r--target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch8
-rw-r--r--target/linux/bcm4908/Makefile3
-rw-r--r--target/linux/bcm4908/config-6.1245
-rw-r--r--target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch31
-rw-r--r--target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch46
-rw-r--r--target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch134
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch367
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch81
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch38
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch41
-rw-r--r--target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch152
-rw-r--r--target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch45
-rw-r--r--target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch31
-rw-r--r--target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch32
-rw-r--r--target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch23
-rw-r--r--target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch30
-rw-r--r--target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch46
-rw-r--r--target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch30
-rw-r--r--target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch2
-rw-r--r--target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch2
-rw-r--r--target/linux/bcm53xx/Makefile3
-rw-r--r--target/linux/bcm53xx/config-5.15317
-rw-r--r--target/linux/bcm53xx/config-6.1339
-rw-r--r--target/linux/bcm53xx/image/Makefile4
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch97
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch29
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch113
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch30
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch85
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch148
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch90
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch340
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch386
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch27
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch47
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch28
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch52
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch290
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch59
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch57
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch41
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch242
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch42
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch29
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch104
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch104
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch54
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch42
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch25
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch45
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch109
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch103
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch40
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch62
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch42
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch31
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch40
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch29
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch43
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch65
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch39
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch300
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch32
-rw-r--r--target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch912
-rw-r--r--target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch108
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch165
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch242
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch99
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch1698
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch487
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch136
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch249
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch203
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch336
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch90
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch82
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch54
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch31
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch106
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch838
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch63
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch54
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch61
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch59
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch37
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch107
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch53
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch75
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch36
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch31
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch97
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch36
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch73
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch39
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch431
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch56
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch44
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch57
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch104
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch377
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch47
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch63
-rw-r--r--target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch129
-rw-r--r--target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch28
-rw-r--r--target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch43
-rw-r--r--target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch119
-rw-r--r--target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch101
-rw-r--r--target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch675
-rw-r--r--target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch64
-rw-r--r--target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch59
-rw-r--r--target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch36
-rw-r--r--target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch33
-rw-r--r--target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch80
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch165
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch242
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch99
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch1700
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch487
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch136
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch249
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch203
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch336
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch90
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch82
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch54
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch31
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch106
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch838
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch63
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch54
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch61
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch59
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch37
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch107
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch53
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch57
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch75
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch36
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch97
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch36
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch73
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch39
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch431
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch56
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch44
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch57
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch104
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch377
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch47
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch63
-rw-r--r--target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch28
-rw-r--r--target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch43
-rw-r--r--target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch118
-rw-r--r--target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch101
-rw-r--r--target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch675
-rw-r--r--target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch64
-rw-r--r--target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch59
-rw-r--r--target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch36
-rw-r--r--target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch33
-rw-r--r--target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch80
-rw-r--r--target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch2
-rw-r--r--target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds3
-rw-r--r--target/linux/bmips/bcm6318/base-files/etc/board.d/02_network3
-rw-r--r--target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc3
-rw-r--r--target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds1
-rw-r--r--target/linux/bmips/bcm6328/base-files/etc/board.d/02_network1
-rw-r--r--target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc1
-rw-r--r--target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts253
-rw-r--r--target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts273
-rw-r--r--target/linux/bmips/dts/bcm6328-inteno-xg6846.dts279
-rw-r--r--target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts28
-rw-r--r--target/linux/bmips/dts/bcm6358.dtsi2
-rw-r--r--target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts4
-rw-r--r--target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts4
-rw-r--r--target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts14
-rw-r--r--target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts10
-rw-r--r--target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts10
-rw-r--r--target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi22
-rw-r--r--target/linux/bmips/dts/bcm6368-observa-vh4032n.dts16
-rw-r--r--target/linux/bmips/dts/bcm6368.dtsi2
-rw-r--r--target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts12
-rw-r--r--target/linux/bmips/dts/bcm6369-netgear-evg2000.dts18
-rw-r--r--target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6348-enet.c7
-rw-r--r--target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c7
-rw-r--r--target/linux/bmips/image/bcm6318.mk20
-rw-r--r--target/linux/bmips/image/bcm6328.mk21
-rw-r--r--target/linux/bmips/patches-6.6/010-v6.10-mips-bmips-BCM6358-make-sure-CBR-is-correctly-set.patch35
-rw-r--r--target/linux/gemini/config-6.62
-rw-r--r--target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch73
-rw-r--r--target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch60
-rw-r--r--target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch43
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch425
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch153
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch275
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch82
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch807
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch1447
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch491
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch1687
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch315
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch498
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch226
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch579
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch32
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch124
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch49
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch96
-rw-r--r--target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch113
-rw-r--r--target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch56
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch196
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch125
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch348
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch162
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch188
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch287
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch161
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch868
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch196
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch34
-rw-r--r--target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch88
-rw-r--r--target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch266
-rw-r--r--target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch65
-rw-r--r--target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch31
-rw-r--r--target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch3078
-rw-r--r--target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch1005
-rw-r--r--target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch120
-rw-r--r--target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch61
-rw-r--r--target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch387
-rw-r--r--target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch123
-rw-r--r--target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch188
-rw-r--r--target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch122
-rw-r--r--target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch105
-rw-r--r--target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch37
-rw-r--r--target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch49
-rw-r--r--target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch997
-rw-r--r--target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch128
-rw-r--r--target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch48
-rw-r--r--target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch166
-rw-r--r--target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch33
-rw-r--r--target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch63
-rw-r--r--target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch162
-rw-r--r--target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch62
-rw-r--r--target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch186
-rw-r--r--target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch219
-rw-r--r--target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch1552
-rw-r--r--target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch32
-rw-r--r--target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch64
-rw-r--r--target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch166
-rw-r--r--target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch39
-rw-r--r--target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch194
-rw-r--r--target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch90
-rw-r--r--target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch95
-rw-r--r--target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch57
-rw-r--r--target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch49
-rw-r--r--target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch72
-rw-r--r--target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch302
-rw-r--r--target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch106
-rw-r--r--target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch72
-rw-r--r--target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch30
-rw-r--r--target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch101
-rw-r--r--target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch65
-rw-r--r--target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch84
-rw-r--r--target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch32
-rw-r--r--target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch47
-rw-r--r--target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch54
-rw-r--r--target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch33
-rw-r--r--target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch36
-rw-r--r--target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch32
-rw-r--r--target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch32
-rw-r--r--target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch58
-rw-r--r--target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch33
-rw-r--r--target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch84
-rw-r--r--target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch91
-rw-r--r--target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch229
-rw-r--r--target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch49
-rw-r--r--target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch73
-rw-r--r--target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch325
-rw-r--r--target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch172
-rw-r--r--target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch321
-rw-r--r--target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch35
-rw-r--r--target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch47
-rw-r--r--target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch165
-rw-r--r--target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch140
-rw-r--r--target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch77
-rw-r--r--target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch55
-rw-r--r--target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch147
-rw-r--r--target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch99
-rw-r--r--target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch137
-rw-r--r--target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch31
-rw-r--r--target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch65
-rw-r--r--target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch40
-rw-r--r--target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch41
-rw-r--r--target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch279
-rw-r--r--target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch274
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch327
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch1679
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch269
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch79
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch29
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch159
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch424
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch44
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch553
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch56
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch25
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch35
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch33
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch22
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch26
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch52
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch206
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch167
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch78
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch109
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch39
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch102
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch46
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch68
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch814
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch917
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch135
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch33
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch138
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch25
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch47
-rw-r--r--target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch28
-rw-r--r--target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch948
-rw-r--r--target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch24
-rw-r--r--target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch98
-rw-r--r--target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch63
-rw-r--r--target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch149
-rw-r--r--target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch51
-rw-r--r--target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch59
-rw-r--r--target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch61
-rw-r--r--target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch197
-rw-r--r--target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch341
-rw-r--r--target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch106
-rw-r--r--target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch43
-rw-r--r--target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch36
-rw-r--r--target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch115
-rw-r--r--target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch88
-rw-r--r--target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch48
-rw-r--r--target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch35
-rw-r--r--target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch55
-rw-r--r--target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch72
-rw-r--r--target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch29
-rw-r--r--target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch43
-rw-r--r--target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch75
-rw-r--r--target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch42
-rw-r--r--target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch84
-rw-r--r--target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch29
-rw-r--r--target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch40
-rw-r--r--target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch35
-rw-r--r--target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch40
-rw-r--r--target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch40
-rw-r--r--target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch60
-rw-r--r--target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch101
-rw-r--r--target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch60
-rw-r--r--target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch89
-rw-r--r--target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch38
-rw-r--r--target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch57
-rw-r--r--target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch254
-rw-r--r--target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch262
-rw-r--r--target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch106
-rw-r--r--target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch166
-rw-r--r--target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch172
-rw-r--r--target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch34
-rw-r--r--target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch86
-rw-r--r--target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch131
-rw-r--r--target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch385
-rw-r--r--target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch80
-rw-r--r--target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch34
-rw-r--r--target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch116
-rw-r--r--target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch87
-rw-r--r--target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch117
-rw-r--r--target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch330
-rw-r--r--target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch291
-rw-r--r--target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch110
-rw-r--r--target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch340
-rw-r--r--target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch95
-rw-r--r--target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch113
-rw-r--r--target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch218
-rw-r--r--target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch394
-rw-r--r--target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch62
-rw-r--r--target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch37
-rw-r--r--target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch74
-rw-r--r--target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch31
-rw-r--r--target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch27
-rw-r--r--target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch64
-rw-r--r--target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch33
-rw-r--r--target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch35
-rw-r--r--target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch127
-rw-r--r--target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch199
-rw-r--r--target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch318
-rw-r--r--target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch80
-rw-r--r--target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch251
-rw-r--r--target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch27
-rw-r--r--target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch28
-rw-r--r--target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch189
-rw-r--r--target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch942
-rw-r--r--target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch230
-rw-r--r--target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch882
-rw-r--r--target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch46
-rw-r--r--target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch26
-rw-r--r--target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch49
-rw-r--r--target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch32
-rw-r--r--target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch37
-rw-r--r--target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch73
-rw-r--r--target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch47
-rw-r--r--target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch43
-rw-r--r--target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch35
-rw-r--r--target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch107
-rw-r--r--target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch591
-rw-r--r--target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch737
-rw-r--r--target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch79
-rw-r--r--target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch1521
-rw-r--r--target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch149
-rw-r--r--target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch98
-rw-r--r--target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch36
-rw-r--r--target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch63
-rw-r--r--target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch80
-rw-r--r--target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch85
-rw-r--r--target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch52
-rw-r--r--target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch98
-rw-r--r--target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch309
-rw-r--r--target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch103
-rw-r--r--target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch103
-rw-r--r--target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch52
-rw-r--r--target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch75
-rw-r--r--target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch70
-rw-r--r--target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch107
-rw-r--r--target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch262
-rw-r--r--target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch249
-rw-r--r--target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch124
-rw-r--r--target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch106
-rw-r--r--target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch22
-rw-r--r--target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch143
-rw-r--r--target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch52
-rw-r--r--target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch654
-rw-r--r--target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch20
-rw-r--r--target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch93
-rw-r--r--target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch72
-rw-r--r--target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch192
-rw-r--r--target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch37
-rw-r--r--target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch42
-rw-r--r--target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch54
-rw-r--r--target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch129
-rw-r--r--target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch26
-rw-r--r--target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch61
-rw-r--r--target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch58
-rw-r--r--target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch31
-rw-r--r--target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch99
-rw-r--r--target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch93
-rw-r--r--target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch96
-rw-r--r--target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch294
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch60
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch55
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch74
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch46
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch130
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch52
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch48
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch48
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch52
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch63
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch132
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch119
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch52
-rw-r--r--target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch33
-rw-r--r--target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch48
-rw-r--r--target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch103
-rw-r--r--target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch200
-rw-r--r--target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch76
-rw-r--r--target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch512
-rw-r--r--target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch21
-rw-r--r--target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch46
-rw-r--r--target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch28
-rw-r--r--target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch428
-rw-r--r--target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch51
-rw-r--r--target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch201
-rw-r--r--target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch31
-rw-r--r--target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch84
-rw-r--r--target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch54
-rw-r--r--target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch58
-rw-r--r--target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch71
-rw-r--r--target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch148
-rw-r--r--target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch2310
-rw-r--r--target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch183
-rw-r--r--target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch504
-rw-r--r--target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch100
-rw-r--r--target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch59
-rw-r--r--target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch58
-rw-r--r--target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch48
-rw-r--r--target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch131
-rw-r--r--target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch42
-rw-r--r--target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch32
-rw-r--r--target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch205
-rw-r--r--target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch65
-rw-r--r--target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch45
-rw-r--r--target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch95
-rw-r--r--target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch131
-rw-r--r--target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch91
-rw-r--r--target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch27
-rw-r--r--target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch127
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch80
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch30
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch127
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch29
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch153
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch295
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch33
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch65
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch37
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch92
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch32
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch78
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch159
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch124
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch26
-rw-r--r--target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch631
-rw-r--r--target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch28
-rw-r--r--target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch151
-rw-r--r--target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch47
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch78
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch141
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch81
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch550
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch29
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch186
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch307
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch193
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch132
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch477
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch27
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch135
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch78
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch52
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch44
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch188
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch254
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch166
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch44
-rw-r--r--target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch33
-rw-r--r--target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch271
-rw-r--r--target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch37
-rw-r--r--target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch334
-rw-r--r--target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch342
-rw-r--r--target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch45
-rw-r--r--target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch47
-rw-r--r--target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch29
-rw-r--r--target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch26
-rw-r--r--target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch68
-rw-r--r--target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch232
-rw-r--r--target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch234
-rw-r--r--target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch52
-rw-r--r--target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch87
-rw-r--r--target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch88
-rw-r--r--target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch71
-rw-r--r--target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch27
-rw-r--r--target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch217
-rw-r--r--target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch1280
-rw-r--r--target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch95
-rw-r--r--target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch465
-rw-r--r--target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch483
-rw-r--r--target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch78
-rw-r--r--target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch432
-rw-r--r--target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch587
-rw-r--r--target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch48
-rw-r--r--target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch46
-rw-r--r--target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch29
-rw-r--r--target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch507
-rw-r--r--target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch25
-rw-r--r--target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch46
-rw-r--r--target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch249
-rw-r--r--target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch120
-rw-r--r--target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch53
-rw-r--r--target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch78
-rw-r--r--target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch142
-rw-r--r--target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch155
-rw-r--r--target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch288
-rw-r--r--target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch40
-rw-r--r--target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch52
-rw-r--r--target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch34
-rw-r--r--target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch91
-rw-r--r--target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch78
-rw-r--r--target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch118
-rw-r--r--target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch115
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch254
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch89
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch86
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch71
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch27
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch110
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch45
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch116
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch67
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch363
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch226
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch287
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch208
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch164
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch206
-rw-r--r--target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch104
-rw-r--r--target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch28
-rw-r--r--target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch34
-rw-r--r--target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch79
-rw-r--r--target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch116
-rw-r--r--target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch173
-rw-r--r--target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch39
-rw-r--r--target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch33
-rw-r--r--target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch44
-rw-r--r--target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch7389
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch157
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch77
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch6532
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch135
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch145
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch137
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch281
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch237
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch227
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch704
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch232
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch448
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch384
-rw-r--r--target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch102
-rw-r--r--target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch29
-rw-r--r--target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch77
-rw-r--r--target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch52
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch141
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch118
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch270
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch51
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch61
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch115
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch57
-rw-r--r--target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch107
-rw-r--r--target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch142
-rw-r--r--target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch37
-rw-r--r--target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch1289
-rw-r--r--target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch1161
-rw-r--r--target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch73
-rw-r--r--target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch156
-rw-r--r--target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch81
-rw-r--r--target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch102
-rw-r--r--target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch34
-rw-r--r--target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch172
-rw-r--r--target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch150
-rw-r--r--target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch73
-rw-r--r--target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch193
-rw-r--r--target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch95
-rw-r--r--target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch56
-rw-r--r--target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch31
-rw-r--r--target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch80
-rw-r--r--target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch37
-rw-r--r--target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch130
-rw-r--r--target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch98
-rw-r--r--target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch291
-rw-r--r--target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch69
-rw-r--r--target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch48
-rw-r--r--target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch79
-rw-r--r--target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch514
-rw-r--r--target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch37
-rw-r--r--target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch55
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch32
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch111
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch74
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch224
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch54
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch273
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch75
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch155
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch55
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch692
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch47
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch421
-rw-r--r--target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch118
-rw-r--r--target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch1724
-rw-r--r--target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch49
-rw-r--r--target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch140
-rw-r--r--target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch26
-rw-r--r--target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch29
-rw-r--r--target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch107
-rw-r--r--target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch343
-rw-r--r--target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch100
-rw-r--r--target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch302
-rw-r--r--target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch34
-rw-r--r--target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch170
-rw-r--r--target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch81
-rw-r--r--target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch38
-rw-r--r--target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch172
-rw-r--r--target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch44
-rw-r--r--target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch136
-rw-r--r--target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch158
-rw-r--r--target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch46
-rw-r--r--target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch55
-rw-r--r--target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch70
-rw-r--r--target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch129
-rw-r--r--target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch398
-rw-r--r--target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch83
-rw-r--r--target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch47
-rw-r--r--target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch30
-rw-r--r--target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch35
-rw-r--r--target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch326
-rw-r--r--target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch36
-rw-r--r--target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch68
-rw-r--r--target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch34
-rw-r--r--target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch125
-rw-r--r--target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch356
-rw-r--r--target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch30
-rw-r--r--target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch28
-rw-r--r--target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch30
-rw-r--r--target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch456
-rw-r--r--target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch82
-rw-r--r--target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch92
-rw-r--r--target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch47
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch72
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch58
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch30
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch29
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch38
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch28
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch139
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch32
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch291
-rw-r--r--target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch146
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch32
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch30
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch27
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch41
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch38
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch130
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch31
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch109
-rw-r--r--target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch38
-rw-r--r--target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch389
-rw-r--r--target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch32
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch286
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch29
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch281
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch535
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch31
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch274
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch32
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch34
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch59
-rw-r--r--target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch35
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch82
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch34
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch26
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch27
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch27
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch67
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch30
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch55
-rw-r--r--target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch48
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch26
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch180
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch78
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch65
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch122
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch93
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch562
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch85
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch32
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch43
-rw-r--r--target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch46
-rw-r--r--target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch59
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch35
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch387
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch61
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch52
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch86
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch59
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch81
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch68
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch76
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch215
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch306
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch32
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch120
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch39
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch39
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch32
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch115
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch81
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch42
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch39
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch39
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch24
-rw-r--r--target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch31
-rw-r--r--target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch100
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch31
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch71
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch81
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch166
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch62
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch31
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch71
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch129
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch26
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch230
-rw-r--r--target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch96
-rw-r--r--target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch39
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch67
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch435
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch74
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch59
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch191
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch97
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch112
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch73
-rw-r--r--target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch104
-rw-r--r--target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch38
-rw-r--r--target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch87
-rw-r--r--target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch149
-rw-r--r--target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch82
-rw-r--r--target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch106
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch74
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch37
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch113
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch69
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch54
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch42
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch28
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch107
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch58
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch53
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch54
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch200
-rw-r--r--target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch70
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch36
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch30
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch34
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch36
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch31
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch30
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch59
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch29
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch133
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch37
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch152
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch30
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch40
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch35
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch29
-rw-r--r--target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch44
-rw-r--r--target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch37
-rw-r--r--target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch330
-rw-r--r--target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch77
-rw-r--r--target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch77
-rw-r--r--target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch45
-rw-r--r--target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch261
-rw-r--r--target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch51
-rw-r--r--target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch29
-rw-r--r--target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch70
-rw-r--r--target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch68
-rw-r--r--target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch66
-rw-r--r--target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch359
-rw-r--r--target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch58
-rw-r--r--target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch34
-rw-r--r--target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch30
-rw-r--r--target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch37
-rw-r--r--target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch29
-rw-r--r--target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch103
-rw-r--r--target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch173
-rw-r--r--target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch160
-rw-r--r--target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch131
-rw-r--r--target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch75
-rw-r--r--target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch45
-rw-r--r--target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch31
-rw-r--r--target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch207
-rw-r--r--target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch201
-rw-r--r--target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch244
-rw-r--r--target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch167
-rw-r--r--target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch47
-rw-r--r--target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch128
-rw-r--r--target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch29
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch95
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch91
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch79
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch169
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch763
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch240
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch65
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch94
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch72
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch53
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch126
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch81
-rw-r--r--target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch62
-rw-r--r--target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch34
-rw-r--r--target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch35
-rw-r--r--target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch49
-rw-r--r--target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch71
-rw-r--r--target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch58
-rw-r--r--target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch118
-rw-r--r--target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch63
-rw-r--r--target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch40
-rw-r--r--target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch106
-rw-r--r--target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch49
-rw-r--r--target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch46
-rw-r--r--target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch31
-rw-r--r--target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch69
-rw-r--r--target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch52
-rw-r--r--target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch113
-rw-r--r--target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch165
-rw-r--r--target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch139
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch352
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch192
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch294
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch166
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch876
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch202
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch38
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch92
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch191
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch129
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch67
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch57
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch243
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch427
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch40
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch135
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch148
-rw-r--r--target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch273
-rw-r--r--target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch58
-rw-r--r--target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch63
-rw-r--r--target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch161
-rw-r--r--target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch107
-rw-r--r--target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch36
-rw-r--r--target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch65
-rw-r--r--target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch84
-rw-r--r--target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch47
-rw-r--r--target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch117
-rw-r--r--target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch32
-rw-r--r--target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch32
-rw-r--r--target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch229
-rw-r--r--target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch35
-rw-r--r--target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch33
-rw-r--r--target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch49
-rw-r--r--target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch47
-rw-r--r--target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch107
-rw-r--r--target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch41
-rw-r--r--target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch32
-rw-r--r--target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch2306
-rw-r--r--target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch183
-rw-r--r--target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch504
-rw-r--r--target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch326
-rw-r--r--target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch105
-rw-r--r--target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch32
-rw-r--r--target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch70
-rw-r--r--target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch73
-rw-r--r--target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch76
-rw-r--r--target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch48
-rw-r--r--target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch98
-rw-r--r--target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch55
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch69
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch129
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch155
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch94
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch78
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch86
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch92
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch78
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch78
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch297
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch114
-rw-r--r--target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch219
-rw-r--r--target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch116
-rw-r--r--target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch97
-rw-r--r--target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch27
-rw-r--r--target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch38
-rw-r--r--target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch152
-rw-r--r--target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch62
-rw-r--r--target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch118
-rw-r--r--target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch182
-rw-r--r--target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch62
-rw-r--r--target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch408
-rw-r--r--target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch5598
-rw-r--r--target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch243
-rw-r--r--target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch638
-rw-r--r--target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch1014
-rw-r--r--target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch1936
-rw-r--r--target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch394
-rw-r--r--target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch28
-rw-r--r--target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch341
-rw-r--r--target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch116
-rw-r--r--target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch196
-rw-r--r--target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch103
-rw-r--r--target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch384
-rw-r--r--target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch2451
-rw-r--r--target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch93
-rw-r--r--target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch39
-rw-r--r--target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch48
-rw-r--r--target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch250
-rw-r--r--target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch48
-rw-r--r--target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch31
-rw-r--r--target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch32
-rw-r--r--target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch64
-rw-r--r--target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch177
-rw-r--r--target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch88
-rw-r--r--target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch38
-rw-r--r--target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch44
-rw-r--r--target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch149
-rw-r--r--target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch147
-rw-r--r--target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch71
-rw-r--r--target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch64
-rw-r--r--target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch76
-rw-r--r--target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch100
-rw-r--r--target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch55
-rw-r--r--target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch324
-rw-r--r--target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch45
-rw-r--r--target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch187
-rw-r--r--target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch101
-rw-r--r--target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch55
-rw-r--r--target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch30
-rw-r--r--target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch36
-rw-r--r--target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch41
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch211
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch185
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch583
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch100
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch668
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch179
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch172
-rw-r--r--target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch326
-rw-r--r--target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch51
-rw-r--r--target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch45
-rw-r--r--target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch205
-rw-r--r--target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch92
-rw-r--r--target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch26
-rw-r--r--target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch591
-rw-r--r--target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch737
-rw-r--r--target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch79
-rw-r--r--target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch1521
-rw-r--r--target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch149
-rw-r--r--target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch36
-rw-r--r--target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch80
-rw-r--r--target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch85
-rw-r--r--target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch52
-rw-r--r--target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch98
-rw-r--r--target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch309
-rw-r--r--target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch103
-rw-r--r--target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch103
-rw-r--r--target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch52
-rw-r--r--target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch75
-rw-r--r--target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch70
-rw-r--r--target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch107
-rw-r--r--target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch262
-rw-r--r--target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch249
-rw-r--r--target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch124
-rw-r--r--target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch106
-rw-r--r--target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch22
-rw-r--r--target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch143
-rw-r--r--target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch52
-rw-r--r--target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch654
-rw-r--r--target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch20
-rw-r--r--target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch93
-rw-r--r--target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch72
-rw-r--r--target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch192
-rw-r--r--target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch42
-rw-r--r--target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch54
-rw-r--r--target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch129
-rw-r--r--target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch26
-rw-r--r--target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch61
-rw-r--r--target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch58
-rw-r--r--target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch31
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch55
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch74
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch46
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch130
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch52
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch48
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch48
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch52
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch63
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch132
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch119
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch52
-rw-r--r--target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch33
-rw-r--r--target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch48
-rw-r--r--target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch103
-rw-r--r--target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch206
-rw-r--r--target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch76
-rw-r--r--target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch512
-rw-r--r--target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch46
-rw-r--r--target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch28
-rw-r--r--target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch403
-rw-r--r--target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch58
-rw-r--r--target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch201
-rw-r--r--target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch31
-rw-r--r--target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch27
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch78
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch141
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch81
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch550
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch29
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch186
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch307
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch193
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch132
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch477
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch27
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch135
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch78
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch52
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch44
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch188
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch254
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch166
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch44
-rw-r--r--target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch33
-rw-r--r--target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch271
-rw-r--r--target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch37
-rw-r--r--target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch334
-rw-r--r--target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch342
-rw-r--r--target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch45
-rw-r--r--target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch47
-rw-r--r--target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch29
-rw-r--r--target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch26
-rw-r--r--target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch68
-rw-r--r--target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch232
-rw-r--r--target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch234
-rw-r--r--target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch52
-rw-r--r--target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch87
-rw-r--r--target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch88
-rw-r--r--target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch71
-rw-r--r--target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch217
-rw-r--r--target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch1280
-rw-r--r--target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch95
-rw-r--r--target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch465
-rw-r--r--target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch483
-rw-r--r--target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch78
-rw-r--r--target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch432
-rw-r--r--target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch587
-rw-r--r--target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch102
-rw-r--r--target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch60
-rw-r--r--target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch59
-rw-r--r--target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch99
-rw-r--r--target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch117
-rw-r--r--target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch96
-rw-r--r--target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch77
-rw-r--r--target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch96
-rw-r--r--target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch38
-rw-r--r--target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch150
-rw-r--r--target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch73
-rw-r--r--target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch63
-rw-r--r--target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch261
-rw-r--r--target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch78
-rw-r--r--target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch146
-rw-r--r--target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch53
-rw-r--r--target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch111
-rw-r--r--target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch158
-rw-r--r--target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch61
-rw-r--r--target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch32
-rw-r--r--target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch477
-rw-r--r--target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch32
-rw-r--r--target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch111
-rw-r--r--target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch74
-rw-r--r--target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch224
-rw-r--r--target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch54
-rw-r--r--target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch273
-rw-r--r--target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch75
-rw-r--r--target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch155
-rw-r--r--target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch54
-rw-r--r--target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch695
-rw-r--r--target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch47
-rw-r--r--target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch421
-rw-r--r--target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch118
-rw-r--r--target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch35
-rw-r--r--target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch58
-rw-r--r--target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch51
-rw-r--r--target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch40
-rw-r--r--target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch116
-rw-r--r--target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch34
-rw-r--r--target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch125
-rw-r--r--target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch45
-rw-r--r--target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch227
-rw-r--r--target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch133
-rw-r--r--target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch95
-rw-r--r--target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch42
-rw-r--r--target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch62
-rw-r--r--target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch58
-rw-r--r--target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch53
-rw-r--r--target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch146
-rw-r--r--target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch97
-rw-r--r--target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch148
-rw-r--r--target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch36
-rw-r--r--target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch38
-rw-r--r--target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch81
-rw-r--r--target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch31
-rw-r--r--target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch41
-rw-r--r--target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch217
-rw-r--r--target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch305
-rw-r--r--target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch48
-rw-r--r--target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch57
-rw-r--r--target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch68
-rw-r--r--target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch83
-rw-r--r--target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch135
-rw-r--r--target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch49
-rw-r--r--target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch238
-rw-r--r--target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch186
-rw-r--r--target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch88
-rw-r--r--target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch200
-rw-r--r--target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch185
-rw-r--r--target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch169
-rw-r--r--target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch201
-rw-r--r--target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch257
-rw-r--r--target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch117
-rw-r--r--target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch39
-rw-r--r--target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch75
-rw-r--r--target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch33
-rw-r--r--target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch71
-rw-r--r--target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch46
-rw-r--r--target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch57
-rw-r--r--target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch37
-rw-r--r--target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch33
-rw-r--r--target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch45
-rw-r--r--target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch45
-rw-r--r--target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch1724
-rw-r--r--target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch49
-rw-r--r--target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch140
-rw-r--r--target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch26
-rw-r--r--target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch29
-rw-r--r--target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch107
-rw-r--r--target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch343
-rw-r--r--target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch100
-rw-r--r--target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch302
-rw-r--r--target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch34
-rw-r--r--target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch170
-rw-r--r--target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch173
-rw-r--r--target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch44
-rw-r--r--target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch136
-rw-r--r--target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch158
-rw-r--r--target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch46
-rw-r--r--target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch55
-rw-r--r--target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch70
-rw-r--r--target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch129
-rw-r--r--target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch39
-rw-r--r--target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch398
-rw-r--r--target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch83
-rw-r--r--target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch47
-rw-r--r--target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch122
-rw-r--r--target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch30
-rw-r--r--target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch35
-rw-r--r--target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch326
-rw-r--r--target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch36
-rw-r--r--target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch89
-rw-r--r--target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch1140
-rw-r--r--target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch47
-rw-r--r--target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch39
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch67
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch435
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch74
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch59
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch191
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch97
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch112
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch73
-rw-r--r--target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch104
-rw-r--r--target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch38
-rw-r--r--target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch87
-rw-r--r--target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch149
-rw-r--r--target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch82
-rw-r--r--target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch106
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch74
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch37
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch113
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch69
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch54
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch42
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch28
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch107
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch58
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch53
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch54
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch200
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch70
-rw-r--r--target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch242
-rw-r--r--target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch138
-rw-r--r--target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch45
-rw-r--r--target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch64
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch64
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch31
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch69
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch52
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch110
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch153
-rw-r--r--target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch82
-rw-r--r--target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch34
-rw-r--r--target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch26
-rw-r--r--target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch27
-rw-r--r--target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch27
-rw-r--r--target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch67
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch26
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch180
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch78
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch65
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch122
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch93
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch562
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch85
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch32
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch43
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch46
-rw-r--r--target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch75
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch35
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch387
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch61
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch52
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch86
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch59
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch81
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch68
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch76
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch215
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch306
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch32
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch120
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch39
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch39
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch32
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch115
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch81
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch42
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch39
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch39
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch24
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch31
-rw-r--r--target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch100
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch31
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch71
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch81
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch166
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch62
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch31
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch71
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch129
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch26
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch230
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch96
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch36
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch30
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch34
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch36
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch31
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch30
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch59
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch29
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch133
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch37
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch152
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch30
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch40
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch35
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch29
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch44
-rw-r--r--target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch29
-rw-r--r--target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch207
-rw-r--r--target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch202
-rw-r--r--target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch244
-rw-r--r--target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch167
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch37
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch330
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch77
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch77
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch45
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch261
-rw-r--r--target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch34
-rw-r--r--target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch35
-rw-r--r--target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch140
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch95
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch91
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch79
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch169
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch763
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch240
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch65
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch94
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch72
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch53
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch126
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch81
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch62
-rw-r--r--target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch65
-rw-r--r--target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch43
-rw-r--r--target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch67
-rw-r--r--target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch44
-rw-r--r--target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch31
-rw-r--r--target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch57
-rw-r--r--target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch149
-rw-r--r--target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch344
-rw-r--r--target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch31
-rw-r--r--target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch58
-rw-r--r--target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch34
-rw-r--r--target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch30
-rw-r--r--target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch37
-rw-r--r--target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch29
-rw-r--r--target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch103
-rw-r--r--target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch173
-rw-r--r--target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch160
-rw-r--r--target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch131
-rw-r--r--target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch207
-rw-r--r--target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch171
-rw-r--r--target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch55
-rw-r--r--target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch70
-rw-r--r--target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch51
-rw-r--r--target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch109
-rw-r--r--target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch93
-rw-r--r--target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch82
-rw-r--r--target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch29
-rw-r--r--target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch111
-rw-r--r--target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch98
-rw-r--r--target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch170
-rw-r--r--target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch43
-rw-r--r--target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch55
-rw-r--r--target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch32
-rw-r--r--target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch34
-rw-r--r--target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch66
-rw-r--r--target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch68
-rw-r--r--target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch49
-rw-r--r--target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch67
-rw-r--r--target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch34
-rw-r--r--target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch49
-rw-r--r--target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch34
-rw-r--r--target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch36
-rw-r--r--target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch33
-rw-r--r--target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch175
-rw-r--r--target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch62
-rw-r--r--target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch28
-rw-r--r--target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch80
-rw-r--r--target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch82
-rw-r--r--target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch28
-rw-r--r--target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch343
-rw-r--r--target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch256
-rw-r--r--target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch129
-rw-r--r--target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch367
-rw-r--r--target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch383
-rw-r--r--target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch40
-rw-r--r--target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch106
-rw-r--r--target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch49
-rw-r--r--target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch139
-rw-r--r--target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch60
-rw-r--r--target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch46
-rw-r--r--target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch76
-rw-r--r--target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch47
-rw-r--r--target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch58
-rw-r--r--target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch95
-rw-r--r--target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch130
-rw-r--r--target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch50
-rw-r--r--target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch44
-rw-r--r--target/linux/generic/backport-6.6/0080-v6.9-smp-Avoid-setup_max_cpus_namespace_collision_shadowing.patch56
-rw-r--r--target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch20
-rw-r--r--target/linux/generic/backport-6.6/320-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch (renamed from target/linux/bmips/patches-6.6/020-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch)0
-rw-r--r--target/linux/generic/backport-6.6/321-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch (renamed from target/linux/bmips/patches-6.6/021-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch)0
-rw-r--r--target/linux/generic/backport-6.6/322-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch (renamed from target/linux/bmips/patches-6.6/022-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch)0
-rw-r--r--target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch30
-rw-r--r--target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch94
-rw-r--r--target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch69
-rw-r--r--target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch86
-rw-r--r--target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch26
-rw-r--r--target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch4
-rw-r--r--target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch4
-rw-r--r--target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch2
-rw-r--r--target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch2
-rw-r--r--target/linux/generic/backport-6.6/752-28-v6.10-net-ethernet-mediatek-Allow-gaps-in-MAC-allocation.patch32
-rw-r--r--target/linux/generic/backport-6.6/752-29-v6.10-net-ethernet-mtk_ppe-Change-PPE-entries-number-to-16.patch29
-rw-r--r--target/linux/generic/backport-6.6/752-30-v6.10-net-ethernet-mtk_eth_soc-implement-.-get-set-_pausep.patch55
-rw-r--r--target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch319
-rw-r--r--target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch173
-rw-r--r--target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch75
-rw-r--r--target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch27
-rw-r--r--target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch47
-rw-r--r--target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch355
-rw-r--r--target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch41
-rw-r--r--target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch319
-rw-r--r--target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch244
-rw-r--r--target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch75
-rw-r--r--target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch25
-rw-r--r--target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch30
-rw-r--r--target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch96
-rw-r--r--target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch147
-rw-r--r--target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch355
-rw-r--r--target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch31
-rw-r--r--target/linux/generic/backport-6.6/780-09-v6.9-r8169-improve-checking-for-valid-LED-modes.patch (renamed from target/linux/generic/backport-6.6/780-04-v6.9-r8169-improve-checking-for-valid-LED-modes.patch)0
-rw-r--r--target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch39
-rw-r--r--target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch244
-rw-r--r--target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch91
-rw-r--r--target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch30
-rw-r--r--target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch55
-rw-r--r--target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch25
-rw-r--r--target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch147
-rw-r--r--target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch31
-rw-r--r--target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch30
-rw-r--r--target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch60
-rw-r--r--target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch34
-rw-r--r--target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch32
-rw-r--r--target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch245
-rw-r--r--target/linux/generic/backport-6.6/780-23-v6.12-r8169-Fix-spelling-mistake-tx_underun-tx_underrun.patch38
-rw-r--r--target/linux/generic/backport-6.6/780-24-v6.12-r8169-disable-ALDPS-per-default-for-RTL8125.patch41
-rw-r--r--target/linux/generic/backport-6.6/780-25-v6.12-r8169-add-tally-counter-fields-added-with-RTL8125.patch56
-rw-r--r--target/linux/generic/backport-6.6/780-26-v6.12-r8169-add-missing-MODULE_FIRMWARE-entry-for-RTL8126A.patch26
-rw-r--r--target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch40
-rw-r--r--target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch93
-rw-r--r--target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch42
-rw-r--r--target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch52
-rw-r--r--target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch209
-rw-r--r--target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch77
-rw-r--r--target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch218
-rw-r--r--target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch125
-rw-r--r--target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch48
-rw-r--r--target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch33
-rw-r--r--target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch151
-rw-r--r--target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch42
-rw-r--r--target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch2
-rw-r--r--target/linux/generic/backport-6.6/817-v6.9-of-property-Make-no-port-node-found-output-a-debug.patch33
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch6
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch6
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch20
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch6
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch53
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch126
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch81
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch62
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch69
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch97
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch243
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch35
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch33
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch32
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch61
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch28
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch28
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch32
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch57
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch50
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch48
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch48
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch25
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch26
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch42
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch83
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch61
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch30
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch122
-rw-r--r--target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch73
-rw-r--r--target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch44
-rw-r--r--target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch525
-rw-r--r--target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch2
-rw-r--r--target/linux/generic/backport-6.6/836-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch103
-rw-r--r--target/linux/generic/backport-6.6/853-v6.10-bus-mhi-host-Add-mhi_power_down_keep_dev-API-to-supp.patch140
-rw-r--r--target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch2
-rw-r--r--target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch2
-rw-r--r--target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch2
-rw-r--r--target/linux/generic/backport-6.6/898-v6.7-mtd-spinand-winbond-add-support-for-serial-NAND-flash.patch75
-rw-r--r--target/linux/generic/backport-6.6/899-v6.9-mtd-spinand-winbond-add-W25N04KV.patch53
-rw-r--r--target/linux/generic/backport-6.6/900-v6.11-net-free_netdev-exit-earlier-if-dummy.patch35
-rw-r--r--target/linux/generic/config-5.157617
-rw-r--r--target/linux/generic/config-6.17947
-rw-r--r--target/linux/generic/config-6.633
-rw-r--r--target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c4
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.c9
-rw-r--r--target/linux/generic/files/drivers/net/phy/rtl8366_smi.h14
-rw-r--r--target/linux/generic/files/drivers/net/phy/rtl8367.c47
-rw-r--r--target/linux/generic/files/drivers/net/phy/rtl8367b.c561
-rw-r--r--target/linux/generic/files/drivers/net/phy/swconfig.c3
-rw-r--r--target/linux/generic/files/drivers/net/phy/swconfig_leds.c16
-rw-r--r--target/linux/generic/hack-5.15/204-module_strip.patch212
-rw-r--r--target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch41
-rw-r--r--target/linux/generic/hack-5.15/210-darwin_scripts_include.patch3053
-rw-r--r--target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch22
-rw-r--r--target/linux/generic/hack-5.15/212-tools_portability.patch110
-rw-r--r--target/linux/generic/hack-5.15/214-spidev_h_portability.patch24
-rw-r--r--target/linux/generic/hack-5.15/220-arm-gc_sections.patch123
-rw-r--r--target/linux/generic/hack-5.15/221-module_exports.patch126
-rw-r--r--target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch34
-rw-r--r--target/linux/generic/hack-5.15/250-netfilter_depends.patch27
-rw-r--r--target/linux/generic/hack-5.15/251-kconfig.patch157
-rw-r--r--target/linux/generic/hack-5.15/253-ksmbd-config.patch32
-rw-r--r--target/linux/generic/hack-5.15/259-regmap_dynamic.patch144
-rw-r--r--target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch52
-rw-r--r--target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch24
-rw-r--r--target/linux/generic/hack-5.15/280-rfkill-stubs.patch84
-rw-r--r--target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch64
-rw-r--r--target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch98
-rw-r--r--target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch24
-rw-r--r--target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch120
-rw-r--r--target/linux/generic/hack-5.15/430-mtk-bmt-support.patch33
-rw-r--r--target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch214
-rw-r--r--target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch865
-rw-r--r--target/linux/generic/hack-5.15/651-wireless_mesh_header.patch24
-rw-r--r--target/linux/generic/hack-5.15/660-fq_codel_defaults.patch27
-rw-r--r--target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch25
-rw-r--r--target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch131
-rw-r--r--target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch21
-rw-r--r--target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch178
-rw-r--r--target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch148
-rw-r--r--target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch34
-rw-r--r--target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch63
-rw-r--r--target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch53
-rw-r--r--target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch74
-rw-r--r--target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch54
-rw-r--r--target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch105
-rw-r--r--target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch72
-rw-r--r--target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch98
-rw-r--r--target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch69
-rw-r--r--target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch69
-rw-r--r--target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch65
-rw-r--r--target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch167
-rw-r--r--target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch190
-rw-r--r--target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch187
-rw-r--r--target/linux/generic/hack-5.15/901-debloat_sock_diag.patch172
-rw-r--r--target/linux/generic/hack-5.15/902-debloat_proc.patch408
-rw-r--r--target/linux/generic/hack-5.15/904-debloat_dma_buf.patch92
-rw-r--r--target/linux/generic/hack-5.15/910-kobject_uevent.patch32
-rw-r--r--target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch76
-rw-r--r--target/linux/generic/hack-5.15/920-device_tree_cmdline.patch21
-rw-r--r--target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch30
-rw-r--r--target/linux/generic/hack-6.1/204-module_strip.patch210
-rw-r--r--target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch41
-rw-r--r--target/linux/generic/hack-6.1/210-darwin_scripts_include.patch3053
-rw-r--r--target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch22
-rw-r--r--target/linux/generic/hack-6.1/212-tools_portability.patch360
-rw-r--r--target/linux/generic/hack-6.1/214-spidev_h_portability.patch24
-rw-r--r--target/linux/generic/hack-6.1/220-arm-gc_sections.patch123
-rw-r--r--target/linux/generic/hack-6.1/221-module_exports.patch126
-rw-r--r--target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch38
-rw-r--r--target/linux/generic/hack-6.1/250-netfilter_depends.patch27
-rw-r--r--target/linux/generic/hack-6.1/251-kconfig.patch157
-rw-r--r--target/linux/generic/hack-6.1/253-ksmbd-config.patch32
-rw-r--r--target/linux/generic/hack-6.1/259-regmap_dynamic.patch144
-rw-r--r--target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch52
-rw-r--r--target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch24
-rw-r--r--target/linux/generic/hack-6.1/280-rfkill-stubs.patch84
-rw-r--r--target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch64
-rw-r--r--target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch112
-rw-r--r--target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch24
-rw-r--r--target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch120
-rw-r--r--target/linux/generic/hack-6.1/430-mtk-bmt-support.patch33
-rw-r--r--target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch24
-rw-r--r--target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch214
-rw-r--r--target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch812
-rw-r--r--target/linux/generic/hack-6.1/651-wireless_mesh_header.patch24
-rw-r--r--target/linux/generic/hack-6.1/660-fq_codel_defaults.patch27
-rw-r--r--target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch25
-rw-r--r--target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch131
-rw-r--r--target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch21
-rw-r--r--target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch167
-rw-r--r--target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch148
-rw-r--r--target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch34
-rw-r--r--target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch63
-rw-r--r--target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch53
-rw-r--r--target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch74
-rw-r--r--target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch54
-rw-r--r--target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch105
-rw-r--r--target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch72
-rw-r--r--target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch98
-rw-r--r--target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch69
-rw-r--r--target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch69
-rw-r--r--target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch63
-rw-r--r--target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch190
-rw-r--r--target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch187
-rw-r--r--target/linux/generic/hack-6.1/901-debloat_sock_diag.patch174
-rw-r--r--target/linux/generic/hack-6.1/902-debloat_proc.patch419
-rw-r--r--target/linux/generic/hack-6.1/904-debloat_dma_buf.patch93
-rw-r--r--target/linux/generic/hack-6.1/910-kobject_uevent.patch32
-rw-r--r--target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch76
-rw-r--r--target/linux/generic/hack-6.1/920-device_tree_cmdline.patch21
-rw-r--r--target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch30
-rw-r--r--target/linux/generic/hack-6.6/200-tools_portability.patch162
-rw-r--r--target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch2
-rw-r--r--target/linux/generic/hack-6.6/253-ksmbd-config.patch4
-rw-r--r--target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch2
-rw-r--r--target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch8
-rw-r--r--target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch2
-rw-r--r--target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch6
-rw-r--r--target/linux/generic/hack-6.6/760-net-usb-r8152-add-LED-configuration-from-OF.patch8
-rw-r--r--target/linux/generic/hack-6.6/765-mxl-gpy-control-LED-reg-from-DT.patch13
-rw-r--r--target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch6
-rw-r--r--target/linux/generic/hack-6.6/790-SFP-GE-T-ignore-TX_FAULT.patch4
-rw-r--r--target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch8
-rw-r--r--target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch2
-rw-r--r--target/linux/generic/hack-6.6/901-debloat_sock_diag.patch2
-rw-r--r--target/linux/generic/hack-6.6/902-debloat_proc.patch10
-rw-r--r--target/linux/generic/hack-6.6/904-debloat_dma_buf.patch2
-rw-r--r--target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch4
-rw-r--r--target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch2
-rw-r--r--target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch29
-rw-r--r--target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch57
-rw-r--r--target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch21
-rw-r--r--target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch75
-rw-r--r--target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch82
-rw-r--r--target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch81
-rw-r--r--target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch73
-rw-r--r--target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch20
-rw-r--r--target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch45
-rw-r--r--target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch37
-rw-r--r--target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch94
-rw-r--r--target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch70
-rw-r--r--target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch119
-rw-r--r--target/linux/generic/pending-5.15/205-backtrace_module_info.patch41
-rw-r--r--target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch30
-rw-r--r--target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch20
-rw-r--r--target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch31
-rw-r--r--target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch40
-rw-r--r--target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch71
-rw-r--r--target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch22
-rw-r--r--target/linux/generic/pending-5.15/305-mips_module_reloc.patch370
-rw-r--r--target/linux/generic/pending-5.15/308-mips32r2_tune.patch22
-rw-r--r--target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch22
-rw-r--r--target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch282
-rw-r--r--target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch84
-rw-r--r--target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch24
-rw-r--r--target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch25
-rw-r--r--target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch113
-rw-r--r--target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch328
-rw-r--r--target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch48
-rw-r--r--target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch245
-rw-r--r--target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch75
-rw-r--r--target/linux/generic/pending-5.15/420-mtd-redboot_space.patch41
-rw-r--r--target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch229
-rw-r--r--target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch68
-rw-r--r--target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch37
-rw-r--r--target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch38
-rw-r--r--target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch25
-rw-r--r--target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch17
-rw-r--r--target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch18
-rw-r--r--target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch18
-rw-r--r--target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch21
-rw-r--r--target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch79
-rw-r--r--target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch22
-rw-r--r--target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch21
-rw-r--r--target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch23
-rw-r--r--target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch24
-rw-r--r--target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch143
-rw-r--r--target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch168
-rw-r--r--target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch22
-rw-r--r--target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch97
-rw-r--r--target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch69
-rw-r--r--target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch53
-rw-r--r--target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch34
-rw-r--r--target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch60
-rw-r--r--target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch52
-rw-r--r--target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch216
-rw-r--r--target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch34
-rw-r--r--target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch30
-rw-r--r--target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch52
-rw-r--r--target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch4581
-rw-r--r--target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch65
-rw-r--r--target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch88
-rw-r--r--target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch110
-rw-r--r--target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch106
-rw-r--r--target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch22
-rw-r--r--target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch86
-rw-r--r--target/linux/generic/pending-5.15/630-packet_socket_type.patch138
-rw-r--r--target/linux/generic/pending-5.15/655-increase_skb_pad.patch20
-rw-r--r--target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch511
-rw-r--r--target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch263
-rw-r--r--target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch50
-rw-r--r--target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch149
-rw-r--r--target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch75
-rw-r--r--target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch110
-rw-r--r--target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch29
-rw-r--r--target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch41
-rw-r--r--target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch38
-rw-r--r--target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch111
-rw-r--r--target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch42
-rw-r--r--target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch59
-rw-r--r--target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch65
-rw-r--r--target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch179
-rw-r--r--target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch28
-rw-r--r--target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch174
-rw-r--r--target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch106
-rw-r--r--target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch61
-rw-r--r--target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch28
-rw-r--r--target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch65
-rw-r--r--target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch43
-rw-r--r--target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch35
-rw-r--r--target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch60
-rw-r--r--target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch28
-rw-r--r--target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch84
-rw-r--r--target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch71
-rw-r--r--target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch75
-rw-r--r--target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch44
-rw-r--r--target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch94
-rw-r--r--target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch21
-rw-r--r--target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch42
-rw-r--r--target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch33
-rw-r--r--target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch1605
-rw-r--r--target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch46
-rw-r--r--target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch22
-rw-r--r--target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch35
-rw-r--r--target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch232
-rw-r--r--target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch27
-rw-r--r--target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch174
-rw-r--r--target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch108
-rw-r--r--target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch195
-rw-r--r--target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch123
-rw-r--r--target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch189
-rw-r--r--target/linux/generic/pending-5.15/778-net-l2tp-drop-flow-hash-on-forward.patch31
-rw-r--r--target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch30
-rw-r--r--target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch61
-rw-r--r--target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch48
-rw-r--r--target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch43
-rw-r--r--target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch45
-rw-r--r--target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch73
-rw-r--r--target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch222
-rw-r--r--target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch47
-rw-r--r--target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch124
-rw-r--r--target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch62
-rw-r--r--target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch115
-rw-r--r--target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch26
-rw-r--r--target/linux/generic/pending-5.15/834-ledtrig-libata.patch149
-rw-r--r--target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch26
-rw-r--r--target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch102
-rw-r--r--target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch114
-rw-r--r--target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch107
-rw-r--r--target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch345
-rw-r--r--target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch61
-rw-r--r--target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch43
-rw-r--r--target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch37
-rw-r--r--target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch37
-rw-r--r--target/linux/generic/pending-5.15/920-mangle_bootargs.patch71
-rw-r--r--target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch51
-rw-r--r--target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch29
-rw-r--r--target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch57
-rw-r--r--target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch21
-rw-r--r--target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch75
-rw-r--r--target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch82
-rw-r--r--target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch81
-rw-r--r--target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch73
-rw-r--r--target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch20
-rw-r--r--target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch45
-rw-r--r--target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch37
-rw-r--r--target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch94
-rw-r--r--target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch71
-rw-r--r--target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch118
-rw-r--r--target/linux/generic/pending-6.1/205-backtrace_module_info.patch41
-rw-r--r--target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch30
-rw-r--r--target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch20
-rw-r--r--target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch31
-rw-r--r--target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch40
-rw-r--r--target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch71
-rw-r--r--target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch22
-rw-r--r--target/linux/generic/pending-6.1/305-mips_module_reloc.patch370
-rw-r--r--target/linux/generic/pending-6.1/308-mips32r2_tune.patch22
-rw-r--r--target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch22
-rw-r--r--target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch282
-rw-r--r--target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch84
-rw-r--r--target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch24
-rw-r--r--target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch25
-rw-r--r--target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch74
-rw-r--r--target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch113
-rw-r--r--target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch328
-rw-r--r--target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch48
-rw-r--r--target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch245
-rw-r--r--target/linux/generic/pending-6.1/420-mtd-redboot_space.patch41
-rw-r--r--target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch229
-rw-r--r--target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch68
-rw-r--r--target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch37
-rw-r--r--target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch38
-rw-r--r--target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch121
-rw-r--r--target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch48
-rw-r--r--target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch225
-rw-r--r--target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch264
-rw-r--r--target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch226
-rw-r--r--target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch65
-rw-r--r--target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch246
-rw-r--r--target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch120
-rw-r--r--target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch77
-rw-r--r--target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch29
-rw-r--r--target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch235
-rw-r--r--target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch74
-rw-r--r--target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch23
-rw-r--r--target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch39
-rw-r--r--target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch22
-rw-r--r--target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch25
-rw-r--r--target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch17
-rw-r--r--target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch18
-rw-r--r--target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch19
-rw-r--r--target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch21
-rw-r--r--target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch81
-rw-r--r--target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch23
-rw-r--r--target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch23
-rw-r--r--target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch24
-rw-r--r--target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch25
-rw-r--r--target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch143
-rw-r--r--target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch168
-rw-r--r--target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch23
-rw-r--r--target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch98
-rw-r--r--target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch77
-rw-r--r--target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch53
-rw-r--r--target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch34
-rw-r--r--target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch60
-rw-r--r--target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch52
-rw-r--r--target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch216
-rw-r--r--target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch32
-rw-r--r--target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch30
-rw-r--r--target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch52
-rw-r--r--target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch733
-rw-r--r--target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch25
-rw-r--r--target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch5180
-rw-r--r--target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch65
-rw-r--r--target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch90
-rw-r--r--target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch110
-rw-r--r--target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch106
-rw-r--r--target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch22
-rw-r--r--target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch86
-rw-r--r--target/linux/generic/pending-6.1/630-packet_socket_type.patch138
-rw-r--r--target/linux/generic/pending-6.1/655-increase_skb_pad.patch20
-rw-r--r--target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch511
-rw-r--r--target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch263
-rw-r--r--target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch50
-rw-r--r--target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch627
-rw-r--r--target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch75
-rw-r--r--target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch110
-rw-r--r--target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch29
-rw-r--r--target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch21
-rw-r--r--target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch38
-rw-r--r--target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch24
-rw-r--r--target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch28
-rw-r--r--target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch174
-rw-r--r--target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch86
-rw-r--r--target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch37
-rw-r--r--target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch158
-rw-r--r--target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch57
-rw-r--r--target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch25
-rw-r--r--target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch106
-rw-r--r--target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch61
-rw-r--r--target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch65
-rw-r--r--target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch43
-rw-r--r--target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch35
-rw-r--r--target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch60
-rw-r--r--target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch28
-rw-r--r--target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch84
-rw-r--r--target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch71
-rw-r--r--target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch59
-rw-r--r--target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch44
-rw-r--r--target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch94
-rw-r--r--target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch21
-rw-r--r--target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch42
-rw-r--r--target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch33
-rw-r--r--target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch936
-rw-r--r--target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch46
-rw-r--r--target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch136
-rw-r--r--target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch498
-rw-r--r--target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch371
-rw-r--r--target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch81
-rw-r--r--target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch547
-rw-r--r--target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch22
-rw-r--r--target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch75
-rw-r--r--target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch45
-rw-r--r--target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch227
-rw-r--r--target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch27
-rw-r--r--target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch174
-rw-r--r--target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch108
-rw-r--r--target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch195
-rw-r--r--target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch123
-rw-r--r--target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch189
-rw-r--r--target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch61
-rw-r--r--target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch48
-rw-r--r--target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch73
-rw-r--r--target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch222
-rw-r--r--target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch108
-rw-r--r--target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch47
-rw-r--r--target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch124
-rw-r--r--target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch62
-rw-r--r--target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch115
-rw-r--r--target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch26
-rw-r--r--target/linux/generic/pending-6.1/834-ledtrig-libata.patch149
-rw-r--r--target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch26
-rw-r--r--target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch102
-rw-r--r--target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch114
-rw-r--r--target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch107
-rw-r--r--target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch345
-rw-r--r--target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch61
-rw-r--r--target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch43
-rw-r--r--target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch37
-rw-r--r--target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch37
-rw-r--r--target/linux/generic/pending-6.1/920-mangle_bootargs.patch71
-rw-r--r--target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch51
-rw-r--r--target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch63
-rw-r--r--target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch99
-rw-r--r--target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch49
-rw-r--r--target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch33
-rw-r--r--target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch63
-rw-r--r--target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch2
-rw-r--r--target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch4
-rw-r--r--target/linux/generic/pending-6.6/530-jffs2_make_lzma_available.patch2
-rw-r--r--target/linux/generic/pending-6.6/600-netfilter_conntrack_flush.patch4
-rw-r--r--target/linux/generic/pending-6.6/630-packet_socket_type.patch16
-rw-r--r--target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch42
-rw-r--r--target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch18
-rw-r--r--target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch24
-rw-r--r--target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch14
-rw-r--r--target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch129
-rw-r--r--target/linux/generic/pending-6.6/684-gso-fix-gso-fraglist-segmentation-after-pull-from-fr.patch53
-rw-r--r--target/linux/generic/pending-6.6/685-net-gso-fix-tcp-fraglist-segmentation-after-pull-fro.patch74
-rw-r--r--target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch2
-rw-r--r--target/linux/generic/pending-6.6/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch2
-rw-r--r--target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch81
-rw-r--r--target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch63
-rw-r--r--target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch35
-rw-r--r--target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch26
-rw-r--r--target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch28
-rw-r--r--target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch100
-rw-r--r--target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch52
-rw-r--r--target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch102
-rw-r--r--target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch106
-rw-r--r--target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch61
-rw-r--r--target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch65
-rw-r--r--target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch43
-rw-r--r--target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch35
-rw-r--r--target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch60
-rw-r--r--target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch28
-rw-r--r--target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch84
-rw-r--r--target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch49
-rw-r--r--target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch71
-rw-r--r--target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch44
-rw-r--r--target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch54
-rw-r--r--target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch75
-rw-r--r--target/linux/generic/pending-6.6/750-net-phy-aquantia-fix-setting-active_low-bit.patch55
-rw-r--r--target/linux/generic/pending-6.6/751-net-phy-aquantia-fix-applying-active_low-bit-after-reset.patch72
-rw-r--r--target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch104
-rw-r--r--target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch2
-rw-r--r--target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch10
-rw-r--r--target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch4
-rw-r--r--target/linux/generic/pending-6.6/834-ledtrig-libata.patch24
-rw-r--r--target/linux/generic/pending-6.6/900-net-ag71xx-fix-qca9530-and-qca9550-mdio-probe.patch25
-rw-r--r--target/linux/imx/Makefile3
-rw-r--r--target/linux/imx/config-6.1486
-rw-r--r--target/linux/imx/config-6.63
-rw-r--r--target/linux/imx/image/cortexa7.mk2
-rw-r--r--target/linux/imx/image/cortexa9.mk2
-rw-r--r--target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch49
-rw-r--r--target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch99
-rw-r--r--target/linux/imx/patches-6.1/100-bootargs.patch11
-rw-r--r--target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch96
-rw-r--r--target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch78
-rw-r--r--target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch24
-rw-r--r--target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch23
-rw-r--r--target/linux/ipq40xx/Makefile2
-rw-r--r--target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches3
-rw-r--r--target/linux/ipq40xx/config-6.66
-rw-r--r--target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts4
-rw-r--r--target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts2
-rw-r--r--target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4019-habanero-dvk.dts27
-rw-r--r--target/linux/ipq40xx/generic/config-default6
-rw-r--r--target/linux/ipq40xx/generic/target.mk2
-rw-r--r--target/linux/ipq40xx/image/generic.mk11
-rw-r--r--target/linux/ipq40xx/mikrotik/config-default6
-rw-r--r--target/linux/ipq40xx/mikrotik/target.mk2
-rw-r--r--target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch2
-rw-r--r--target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch4
-rw-r--r--target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts2
-rw-r--r--target/linux/ipq806x/image/generic.mk6
-rw-r--r--target/linux/kirkwood/Makefile3
-rw-r--r--target/linux/kirkwood/config-6.1309
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts202
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts8
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts243
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts8
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts135
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts199
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts234
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts144
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts165
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts227
-rw-r--r--target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts2
-rw-r--r--target/linux/kirkwood/image/Makefile8
-rw-r--r--target/linux/kirkwood/image/generic.mk177
-rw-r--r--target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch301
-rw-r--r--target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch249
-rw-r--r--target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch108
-rw-r--r--target/linux/kirkwood/patches-6.1/100-ib62x0.patch53
-rw-r--r--target/linux/kirkwood/patches-6.1/101-iconnect.patch80
-rw-r--r--target/linux/kirkwood/patches-6.1/102-dockstar.patch62
-rw-r--r--target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch71
-rw-r--r--target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch59
-rw-r--r--target/linux/kirkwood/patches-6.1/106-goflexnet.patch53
-rw-r--r--target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch48
-rw-r--r--target/linux/kirkwood/patches-6.1/107-03-nsa325.patch54
-rw-r--r--target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch87
-rw-r--r--target/linux/kirkwood/patches-6.1/110-pogo_e02.patch68
-rw-r--r--target/linux/kirkwood/patches-6.1/111-l-50.patch47
-rw-r--r--target/linux/kirkwood/patches-6.1/112-sheevaplug.patch47
-rw-r--r--target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch76
-rw-r--r--target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch58
-rw-r--r--target/linux/kirkwood/patches-6.1/115-nsa310s.patch35
-rw-r--r--target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch34
-rw-r--r--target/linux/kirkwood/patches-6.1/117-netgear_stora.patch10
-rw-r--r--target/linux/kirkwood/patches-6.1/118-dns-320l.patch35
-rw-r--r--target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch10
-rw-r--r--target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch62
-rw-r--r--target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch99
-rw-r--r--target/linux/lantiq/Makefile3
-rw-r--r--target/linux/lantiq/ase/config-5.1524
-rw-r--r--target/linux/lantiq/ase/config-6.124
-rw-r--r--target/linux/lantiq/config-5.15172
-rw-r--r--target/linux/lantiq/config-6.1182
-rw-r--r--target/linux/lantiq/falcon/config-5.159
-rw-r--r--target/linux/lantiq/falcon/config-6.19
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts2
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts7
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi3
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts2
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts2
-rw-r--r--target/linux/lantiq/image/ar9.mk2
-rw-r--r--target/linux/lantiq/image/vr9.mk4
-rw-r--r--target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch5550
-rw-r--r--target/linux/lantiq/patches-5.15/0004-MIPS-lantiq-add-atm-hack.patch482
-rw-r--r--target/linux/lantiq/patches-5.15/0008-MIPS-lantiq-backport-old-timer-code.patch1076
-rw-r--r--target/linux/lantiq/patches-5.15/0018-MTD-nand-lots-of-xrx200-fixes.patch121
-rw-r--r--target/linux/lantiq/patches-5.15/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch25
-rw-r--r--target/linux/lantiq/patches-5.15/0023-NET-PHY-add-led-support-for-intel-xway.patch294
-rw-r--r--target/linux/lantiq/patches-5.15/0028-NET-lantiq-various-etop-fixes.patch864
-rw-r--r--target/linux/lantiq/patches-5.15/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch1034
-rw-r--r--target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch218
-rw-r--r--target/linux/lantiq/patches-5.15/0042-arch-mips-increase-io_space_limit.patch24
-rw-r--r--target/linux/lantiq/patches-5.15/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch78
-rw-r--r--target/linux/lantiq/patches-5.15/0051-MIPS-lantiq-improve-USB-initialization.patch49
-rw-r--r--target/linux/lantiq/patches-5.15/0101-find_active_root.patch103
-rw-r--r--target/linux/lantiq/patches-5.15/0151-lantiq-ifxmips_pcie-use-of.patch486
-rw-r--r--target/linux/lantiq/patches-5.15/0152-lantiq-VPE.patch187
-rw-r--r--target/linux/lantiq/patches-5.15/0154-lantiq-pci-bar11mask-fix.patch32
-rw-r--r--target/linux/lantiq/patches-5.15/0155-lantiq-VPE-nosmp.patch24
-rw-r--r--target/linux/lantiq/patches-5.15/0160-owrt-lantiq-multiple-flash.patch230
-rw-r--r--target/linux/lantiq/patches-5.15/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch97
-rw-r--r--target/linux/lantiq/patches-5.15/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch21
-rw-r--r--target/linux/lantiq/patches-5.15/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch40
-rw-r--r--target/linux/lantiq/patches-5.15/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch62
-rw-r--r--target/linux/lantiq/patches-5.15/0310-v5.16-MIPS-lantiq-dma-make-the-burst-length-configurable-b.patch86
-rw-r--r--target/linux/lantiq/patches-5.15/0320-v6.1-MIPS-lantiq-enable-all-hardware-interrupts-on-second.patch87
-rw-r--r--target/linux/lantiq/patches-5.15/0321-v6.8-MIPS-lantiq-register-smp_ops-on-non-smp-platforms.patch34
-rw-r--r--target/linux/lantiq/patches-5.15/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch38
-rw-r--r--target/linux/lantiq/patches-5.15/0701-NET-lantiq-etop-of-mido.patch47
-rw-r--r--target/linux/lantiq/patches-5.15/0702-v5.16-net-lantiq-add-support-for-jumbo-frames.patch145
-rw-r--r--target/linux/lantiq/patches-5.15/0703-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch122
-rw-r--r--target/linux/lantiq/patches-5.15/0704-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch104
-rw-r--r--target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch127
-rw-r--r--target/linux/lantiq/patches-5.15/0710-v5.16-net-lantiq-configure-the-burst-length-in-ethernet-dr.patch126
-rw-r--r--target/linux/lantiq/patches-5.15/0711-v5.16-net-lantiq_xrx200-Hardcode-the-burst-length-value.patch73
-rw-r--r--target/linux/lantiq/patches-5.15/0712-v5.16-net-ethernet-lantiq_etop-Fix-compilation-error.patch26
-rw-r--r--target/linux/lantiq/patches-5.15/0713-v5.17-MIPS-lantiq-dma-increase-descritor-count.patch28
-rw-r--r--target/linux/lantiq/patches-5.15/0714-v5.17-net-lantiq_xrx200-increase-napi-poll-weigth.patch32
-rw-r--r--target/linux/lantiq/patches-5.15/0715-v5.17-net-lantiq_xrx200-convert-to-build_skb.patch206
-rw-r--r--target/linux/lantiq/patches-5.15/0716-v5.17-net-lantiq_xrx200-fix-use-after-free-bug.patch30
-rw-r--r--target/linux/lantiq/patches-5.15/0717-v6.0-net-lantiq_xrx200-confirm-skb-is-allocated-before-us.patch33
-rw-r--r--target/linux/lantiq/patches-5.15/0718-v6.0-net-lantiq_xrx200-fix-lock-under-memory-pressure.patch33
-rw-r--r--target/linux/lantiq/patches-5.15/0719-v6.0-net-lantiq_xrx200-restore-buffer-if-memory-allocatio.patch27
-rw-r--r--target/linux/lantiq/patches-5.15/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch32
-rw-r--r--target/linux/lantiq/patches-5.15/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch33
-rw-r--r--target/linux/lantiq/patches-5.15/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch145
-rw-r--r--target/linux/lantiq/patches-5.15/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch25
-rw-r--r--target/linux/lantiq/patches-5.15/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch70
-rw-r--r--target/linux/lantiq/patches-5.15/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch30
-rw-r--r--target/linux/lantiq/patches-5.15/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch24
-rw-r--r--target/linux/lantiq/patches-5.15/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch47
-rw-r--r--target/linux/lantiq/patches-5.15/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch26
-rw-r--r--target/linux/lantiq/patches-5.15/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch26
-rw-r--r--target/linux/lantiq/patches-5.15/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch36
-rw-r--r--target/linux/lantiq/patches-5.15/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch33
-rw-r--r--target/linux/lantiq/patches-5.15/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch26
-rw-r--r--target/linux/lantiq/patches-6.1/0001-MIPS-lantiq-add-pcie-driver.patch5550
-rw-r--r--target/linux/lantiq/patches-6.1/0004-MIPS-lantiq-add-atm-hack.patch482
-rw-r--r--target/linux/lantiq/patches-6.1/0008-MIPS-lantiq-backport-old-timer-code.patch1076
-rw-r--r--target/linux/lantiq/patches-6.1/0018-MTD-nand-lots-of-xrx200-fixes.patch121
-rw-r--r--target/linux/lantiq/patches-6.1/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch25
-rw-r--r--target/linux/lantiq/patches-6.1/0023-NET-PHY-add-led-support-for-intel-xway.patch294
-rw-r--r--target/linux/lantiq/patches-6.1/0028-NET-lantiq-various-etop-fixes.patch886
-rw-r--r--target/linux/lantiq/patches-6.1/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch1034
-rw-r--r--target/linux/lantiq/patches-6.1/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch218
-rw-r--r--target/linux/lantiq/patches-6.1/0042-arch-mips-increase-io_space_limit.patch24
-rw-r--r--target/linux/lantiq/patches-6.1/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch80
-rw-r--r--target/linux/lantiq/patches-6.1/0051-MIPS-lantiq-improve-USB-initialization.patch49
-rw-r--r--target/linux/lantiq/patches-6.1/0101-find_active_root.patch103
-rw-r--r--target/linux/lantiq/patches-6.1/0151-lantiq-ifxmips_pcie-use-of.patch486
-rw-r--r--target/linux/lantiq/patches-6.1/0152-lantiq-VPE.patch187
-rw-r--r--target/linux/lantiq/patches-6.1/0154-lantiq-pci-bar11mask-fix.patch32
-rw-r--r--target/linux/lantiq/patches-6.1/0155-lantiq-VPE-nosmp.patch24
-rw-r--r--target/linux/lantiq/patches-6.1/0160-owrt-lantiq-multiple-flash.patch230
-rw-r--r--target/linux/lantiq/patches-6.1/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch99
-rw-r--r--target/linux/lantiq/patches-6.1/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch21
-rw-r--r--target/linux/lantiq/patches-6.1/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch40
-rw-r--r--target/linux/lantiq/patches-6.1/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch62
-rw-r--r--target/linux/lantiq/patches-6.1/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch38
-rw-r--r--target/linux/lantiq/patches-6.1/0701-NET-lantiq-etop-of-mido.patch47
-rw-r--r--target/linux/lantiq/patches-6.1/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch32
-rw-r--r--target/linux/lantiq/patches-6.1/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch33
-rw-r--r--target/linux/lantiq/patches-6.1/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch145
-rw-r--r--target/linux/lantiq/patches-6.1/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch25
-rw-r--r--target/linux/lantiq/patches-6.1/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch70
-rw-r--r--target/linux/lantiq/patches-6.1/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch30
-rw-r--r--target/linux/lantiq/patches-6.1/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch24
-rw-r--r--target/linux/lantiq/patches-6.1/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch47
-rw-r--r--target/linux/lantiq/patches-6.1/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch26
-rw-r--r--target/linux/lantiq/patches-6.1/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch26
-rw-r--r--target/linux/lantiq/patches-6.1/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch36
-rw-r--r--target/linux/lantiq/patches-6.1/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch33
-rw-r--r--target/linux/lantiq/patches-6.1/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch26
-rw-r--r--target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch2
-rw-r--r--target/linux/lantiq/patches-6.6/0025-v6.12-net-ethernet-lantiq_etop-fix-memory-disclosure.patch42
-rw-r--r--target/linux/lantiq/patches-6.6/0026-v6.12-net-ethernet-lantiq_etop-remove-unused-variable.patch24
-rw-r--r--target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch31
-rw-r--r--target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch133
-rw-r--r--target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch2
-rw-r--r--target/linux/lantiq/patches-6.6/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch80
-rw-r--r--target/linux/lantiq/patches-6.6/0050-v6.11-usb-dwc2-add-support-for-other-Lantiq-SoCs.patch85
-rw-r--r--target/linux/lantiq/patches-6.6/0051-MIPS-lantiq-improve-USB-initialization.patch49
-rw-r--r--target/linux/lantiq/patches-6.6/0051-v6.11-MIPS-lantiq-improve-USB-initialization.patch51
-rw-r--r--target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch4
-rw-r--r--target/linux/lantiq/patches-6.6/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch32
-rw-r--r--target/linux/lantiq/patches-6.6/0731-v6.11-dt-bindings-net-dsa-lantiq-gswip-convert-to-YAML-schema.patch392
-rw-r--r--target/linux/lantiq/patches-6.6/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch33
-rw-r--r--target/linux/lantiq/patches-6.6/0732-v6.11-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on-the-CPU-port.patch38
-rw-r--r--target/linux/lantiq/patches-6.6/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch145
-rw-r--r--target/linux/lantiq/patches-6.6/0733-v6.11-net-dsa-lantiq_gswip-add-terminating-n-where-missing.patch82
-rw-r--r--target/linux/lantiq/patches-6.6/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch25
-rw-r--r--target/linux/lantiq/patches-6.6/0734-v6.11-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch149
-rw-r--r--target/linux/lantiq/patches-6.6/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch70
-rw-r--r--target/linux/lantiq/patches-6.6/0735-v6.11-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch29
-rw-r--r--target/linux/lantiq/patches-6.6/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch30
-rw-r--r--target/linux/lantiq/patches-6.6/0736-v6.11-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch73
-rw-r--r--target/linux/lantiq/patches-6.6/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch24
-rw-r--r--target/linux/lantiq/patches-6.6/0737-v6.11-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch35
-rw-r--r--target/linux/lantiq/patches-6.6/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch47
-rw-r--r--target/linux/lantiq/patches-6.6/0738-v6.11-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch29
-rw-r--r--target/linux/lantiq/patches-6.6/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch26
-rw-r--r--target/linux/lantiq/patches-6.6/0739-v6.11-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch82
-rw-r--r--target/linux/lantiq/patches-6.6/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch26
-rw-r--r--target/linux/lantiq/patches-6.6/0740-v6.11-net-dsa-lantiq_gswip-Remove-dead-code-from-gswip_add_single_port_br.patch35
-rw-r--r--target/linux/lantiq/patches-6.6/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch36
-rw-r--r--target/linux/lantiq/patches-6.6/0741-v6.11-net-dsa-lantiq_gswip-Update-comments-in-gswip_port_vlan.patch41
-rw-r--r--target/linux/lantiq/patches-6.6/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch33
-rw-r--r--target/linux/lantiq/patches-6.6/0742-v6.11-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch30
-rw-r--r--target/linux/lantiq/patches-6.6/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch26
-rw-r--r--target/linux/lantiq/xrx200/base-files/etc/board.d/02_network4
-rw-r--r--target/linux/lantiq/xrx200/config-5.1591
-rw-r--r--target/linux/lantiq/xrx200/config-6.196
-rw-r--r--target/linux/lantiq/xway/config-5.1576
-rw-r--r--target/linux/lantiq/xway/config-6.181
-rw-r--r--target/linux/lantiq/xway_legacy/config-5.1530
-rw-r--r--target/linux/lantiq/xway_legacy/config-6.130
-rw-r--r--target/linux/layerscape/Makefile3
-rw-r--r--target/linux/layerscape/armv7/config-6.1699
-rw-r--r--target/linux/layerscape/armv7/config-6.64
-rw-r--r--target/linux/layerscape/armv8_64b/config-6.1905
-rw-r--r--target/linux/layerscape/armv8_64b/config-6.611
-rw-r--r--target/linux/layerscape/armv8_64b/target.mk1
-rw-r--r--target/linux/layerscape/image/armv7.mk4
-rw-r--r--target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch288
-rw-r--r--target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch41
-rw-r--r--target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch29
-rw-r--r--target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch34
-rw-r--r--target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch27
-rw-r--r--target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch11808
-rw-r--r--target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch54
-rw-r--r--target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch239
-rw-r--r--target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch42
-rw-r--r--target/linux/loongarch64/config-6.64
-rw-r--r--target/linux/malta/be64/target.mk1
-rw-r--r--target/linux/malta/config-6.63
-rw-r--r--target/linux/malta/le/target.mk1
-rw-r--r--target/linux/malta/le64/target.mk1
-rw-r--r--target/linux/mediatek/Makefile4
-rw-r--r--target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface4
-rw-r--r--target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing16
-rw-r--r--target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts300
-rw-r--r--target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts1
-rw-r--r--target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi2
-rw-r--r--target/linux/mediatek/dts/mt7981b-abt-asr3000.dts275
-rw-r--r--target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso74
-rw-r--r--target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso31
-rw-r--r--target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts3
-rw-r--r--target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts209
-rw-r--r--target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts2
-rw-r--r--target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts9
-rw-r--r--target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts9
-rw-r--r--target/linux/mediatek/dts/mt7981b-openwrt-one.dts31
-rw-r--r--target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts9
-rw-r--r--target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts2
-rw-r--r--target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts12
-rw-r--r--target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts12
-rw-r--r--target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts2
-rw-r--r--target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts2
-rw-r--r--target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts4
-rw-r--r--target/linux/mediatek/dts/mt7986a-netcore-n60.dts9
-rw-r--r--target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts390
-rw-r--r--target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts17
-rw-r--r--target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts4
-rw-r--r--target/linux/mediatek/dts/mt7986b-tplink-re6000xd.dts298
-rw-r--r--target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi8
-rw-r--r--target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts153
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso14
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts3
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso2
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso2
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi17
-rw-r--r--target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c321
-rw-r--r--target/linux/mediatek/files/block/partitions/fit.c307
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/board.d/01_leds19
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/board.d/02_network35
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata13
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac28
-rw-r--r--target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part3
-rw-r--r--target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh6
-rwxr-xr-xtarget/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh109
-rw-r--r--target/linux/mediatek/filogic/config-6.63
-rw-r--r--target/linux/mediatek/image/filogic.mk89
-rw-r--r--target/linux/mediatek/image/mt7622.mk12
-rw-r--r--target/linux/mediatek/image/mt7629.mk16
-rwxr-xr-xtarget/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh21
-rw-r--r--target/linux/mediatek/mt7622/config-6.63
-rwxr-xr-xtarget/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh7
-rw-r--r--target/linux/mediatek/mt7623/config-6.61
-rw-r--r--target/linux/mediatek/mt7629/base-files/etc/board.d/02_network8
-rwxr-xr-xtarget/linux/mediatek/mt7629/base-files/etc/init.d/bootcount3
-rwxr-xr-xtarget/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh5
-rw-r--r--target/linux/mediatek/mt7629/config-6.61
-rw-r--r--target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch216
-rw-r--r--target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch6
-rw-r--r--target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch3
-rw-r--r--target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch16
-rw-r--r--target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch2
-rw-r--r--target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch8
-rw-r--r--target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch3513
-rw-r--r--target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch62
-rw-r--r--target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch742
-rw-r--r--target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch70
-rw-r--r--target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch141
-rw-r--r--target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch146
-rw-r--r--target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch54
-rw-r--r--target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch182
-rw-r--r--target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch614
-rw-r--r--target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch219
-rw-r--r--target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch477
-rw-r--r--target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch130
-rw-r--r--target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch65
-rw-r--r--target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch39
-rw-r--r--target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch6
-rw-r--r--target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch14
-rw-r--r--target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch6
-rw-r--r--target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch4
-rw-r--r--target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch6
-rw-r--r--target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch2
-rw-r--r--target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch4
-rw-r--r--target/linux/mpc85xx/Makefile5
-rw-r--r--target/linux/mpc85xx/base-files/etc/board.d/02_network5
-rw-r--r--target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom33
-rw-r--r--target/linux/mpc85xx/config-6.1295
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts5
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts166
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c73
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c16
-rw-r--r--target/linux/mpc85xx/image/p1010.mk1
-rw-r--r--target/linux/mpc85xx/image/p1020.mk2
-rw-r--r--target/linux/mpc85xx/p1010/config-default3
-rw-r--r--target/linux/mpc85xx/p1020/config-default19
-rw-r--r--target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch10
-rw-r--r--target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch61
-rw-r--r--target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch83
-rw-r--r--target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch58
-rw-r--r--target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch37
-rw-r--r--target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch29
-rw-r--r--target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch170
-rw-r--r--target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch30
-rw-r--r--target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch60
-rw-r--r--target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch67
-rw-r--r--target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch29
-rw-r--r--target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch48
-rw-r--r--target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch57
-rw-r--r--target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch31
-rw-r--r--target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch41
-rw-r--r--target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch42
-rw-r--r--target/linux/mvebu/config-6.61
-rw-r--r--target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds4
-rw-r--r--target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh162
-rwxr-xr-xtarget/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh2
-rw-r--r--target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-3xe.dtsi4
-rw-r--r--target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-5xe.dtsi4
-rw-r--r--target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-xxe.dtsi18
-rw-r--r--target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts1
-rw-r--r--target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-7040-rb5009.dts26
-rw-r--r--target/linux/mvebu/image/cortexa53.mk1
-rw-r--r--target/linux/mvebu/image/cortexa9.mk3
-rw-r--r--target/linux/mvebu/image/gl-mv1000.bootscript28
-rw-r--r--target/linux/mvebu/modules.mk21
-rw-r--r--target/linux/mvebu/patches-6.6/701-mvpp2-read-mac-address-from-nvmem.patch2
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch125
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch922
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch1311
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch415
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch250
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch225
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch69
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch46
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch32
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch32
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch45
-rw-r--r--target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch2
-rw-r--r--target/linux/octeon/Makefile2
-rw-r--r--target/linux/octeon/base-files/lib/preinit/79_move_config28
-rwxr-xr-xtarget/linux/octeon/base-files/lib/upgrade/platform.sh62
-rw-r--r--target/linux/octeon/config-6.1274
-rw-r--r--target/linux/octeon/config-6.6283
-rw-r--r--target/linux/octeon/image/Makefile8
-rw-r--r--target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch38
-rw-r--r--target/linux/octeon/patches-6.1/130-add_itus_support.patch42
-rw-r--r--target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch46
-rw-r--r--target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch38
-rw-r--r--target/linux/octeon/patches-6.6/100-ubnt_edgerouter2_support.patch (renamed from target/linux/octeon/patches-6.1/100-ubnt_edgerouter2_support.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/110-er200-ethernet_probe_order.patch (renamed from target/linux/octeon/patches-6.1/110-er200-ethernet_probe_order.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/120-cmdline-hack.patch (renamed from target/linux/octeon/patches-6.1/120-cmdline-hack.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/130-add_itus_support.patch42
-rw-r--r--target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch46
-rw-r--r--target/linux/octeon/patches-6.6/700-allocate_interface_by_label.patch (renamed from target/linux/octeon/patches-6.1/700-allocate_interface_by_label.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/701-honor_sgmii_node_device_tree_status.patch (renamed from target/linux/octeon/patches-6.1/701-honor_sgmii_node_device_tree_status.patch)0
-rw-r--r--target/linux/omap/Makefile4
-rw-r--r--target/linux/omap/config-6.1711
-rw-r--r--target/linux/omap/config-6.6720
-rw-r--r--target/linux/omap/image/Makefile1
-rw-r--r--target/linux/omap/patches-6.6/900-use-cpsw-ethernet-driver.patch93
-rw-r--r--target/linux/pistachio/Makefile2
-rw-r--r--target/linux/pistachio/config-6.1335
-rw-r--r--target/linux/pistachio/config-6.6361
-rw-r--r--target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch68
-rw-r--r--target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch198
-rw-r--r--target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch64
-rw-r--r--target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch120
-rw-r--r--target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch53
-rw-r--r--target/linux/pistachio/patches-6.6/101-dmaengine-img-mdc-Handle-early-status-read.patch68
-rw-r--r--target/linux/pistachio/patches-6.6/102-spi-img-spfi-Implement-dual-and-quad-mode.patch198
-rw-r--r--target/linux/pistachio/patches-6.6/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch64
-rw-r--r--target/linux/pistachio/patches-6.6/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch (renamed from target/linux/pistachio/patches-6.1/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch)0
-rw-r--r--target/linux/pistachio/patches-6.6/106-spi-img-spfi-finish-every-transfer-cleanly.patch120
-rw-r--r--target/linux/pistachio/patches-6.6/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch (renamed from target/linux/pistachio/patches-6.1/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch)0
-rw-r--r--target/linux/pistachio/patches-6.6/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch (renamed from target/linux/pistachio/patches-6.1/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch)0
-rw-r--r--target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch61
-rw-r--r--target/linux/pistachio/patches-6.6/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch (renamed from target/linux/pistachio/patches-6.1/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch)0
-rw-r--r--target/linux/pistachio/patches-6.6/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch (renamed from target/linux/pistachio/patches-6.1/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch)0
-rw-r--r--target/linux/pistachio/patches-6.6/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch (renamed from target/linux/pistachio/patches-6.1/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch)0
-rw-r--r--target/linux/pistachio/patches-6.6/904-MIPS-DTS-img-marduk-Add-partition-name.patch (renamed from target/linux/pistachio/patches-6.1/904-MIPS-DTS-img-marduk-Add-partition-name.patch)0
-rw-r--r--target/linux/pistachio/patches-6.6/905-MIPS-DTS-img-marduk-Add-led-aliases.patch (renamed from target/linux/pistachio/patches-6.1/905-MIPS-DTS-img-marduk-Add-led-aliases.patch)0
-rw-r--r--target/linux/qoriq/Makefile2
-rw-r--r--target/linux/qoriq/config-6.1422
-rw-r--r--target/linux/qoriq/config-6.6430
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts454
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi52
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts131
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi746
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rt-ax89x.dts741
-rw-r--r--target/linux/qualcommax/image/ipq60xx.mk13
-rw-r--r--target/linux/qualcommax/image/ipq807x.mk69
-rw-r--r--target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network3
-rw-r--r--target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata10
-rw-r--r--target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh4
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds5
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network10
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata11
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data19
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh110
-rw-r--r--target/linux/qualcommax/ipq807x/config-default10
-rw-r--r--target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch6
-rw-r--r--target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch6
-rw-r--r--target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch6
-rw-r--r--target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch2
-rw-r--r--target/linux/ramips/dts/mt7620a.dtsi78
-rw-r--r--target/linux/ramips/dts/mt7620a_bolt_bl100.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_domywifi.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts16
-rw-r--r--target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_netcore_nw5212.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_phicomm_k2x.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts6
-rw-r--r--target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts201
-rw-r--r--target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts4
-rw-r--r--target/linux/ramips/dts/mt7620n.dtsi20
-rw-r--r--target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts2
-rw-r--r--target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts2
-rw-r--r--target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts2
-rw-r--r--target/linux/ramips/dts/mt7621.dtsi51
-rw-r--r--target/linux/ramips/dts/mt7621_arcadyan_we420223-99.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_dlink_dir-2150-r1.dts199
-rw-r--r--target/linux/ramips/dts/mt7621_dna_valokuitu-plus-ex400.dts130
-rw-r--r--target/linux/ramips/dts/mt7621_elecom_wmc-x1800gst.dts69
-rw-r--r--target/linux/ramips/dts/mt7621_elecom_wsc-x1800gs.dts33
-rw-r--r--target/linux/ramips/dts/mt7621_elecom_wxc-x1800gsx.dtsi235
-rw-r--r--target/linux/ramips/dts/mt7621_iptime_a6004ns-m.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_jcg_y2.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts247
-rw-r--r--target/linux/ramips/dts/mt7621_mtc_wr1201.dts10
-rw-r--r--target/linux/ramips/dts/mt7621_netgear_wax214v2.dts228
-rw-r--r--target/linux/ramips/dts/mt7621_netis_n6.dts227
-rw-r--r--[-rwxr-xr-x]target/linux/ramips/dts/mt7621_openfi_5pro.dts0
-rw-r--r--target/linux/ramips/dts/mt7621_ruijie_rg-ew1200g-pro-v1.1.dts142
-rw-r--r--target/linux/ramips/dts/mt7621_snr_snr-cpe-me2-lite.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_tplink_er605-v2.dts10
-rw-r--r--target/linux/ramips/dts/mt7621_tplink_mr600-v2-eu.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi2
-rw-r--r--[-rwxr-xr-x]target/linux/ramips/dts/mt7621_winstars_ws-wn536p3.dts0
-rw-r--r--target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts153
-rw-r--r--target/linux/ramips/dts/mt7621_yuncore_ax820.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_yuncore_fap640.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_yuncore_fap690.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts168
-rw-r--r--target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts165
-rw-r--r--target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi171
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nr7101.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_wap6805.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_wsm20.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an.dtsi58
-rw-r--r--target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_duzun_dm06.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts12
-rw-r--r--target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi1
-rw-r--r--target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_minew_g1-c.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_motorola_mwr03.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi2
-rw-r--r--target/linux/ramips/dts/mt7628an_onion_omega2.dtsi1
-rw-r--r--target/linux/ramips/dts/mt7628an_tplink_archer-mr200-v5.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_widora_neo.dtsi1
-rw-r--r--target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts94
-rw-r--r--target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts165
-rw-r--r--target/linux/ramips/dts/mt7628an_yuncore_m300.dts148
-rw-r--r--target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts2
-rw-r--r--target/linux/ramips/dts/rt2880.dtsi5
-rw-r--r--target/linux/ramips/dts/rt3050.dtsi21
-rw-r--r--target/linux/ramips/dts/rt3052_zyxel_keenetic.dts2
-rw-r--r--target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts2
-rw-r--r--target/linux/ramips/dts/rt3352.dtsi29
-rw-r--r--target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_asus_rt-n56u.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_dlink_dir-645.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts2
-rw-r--r--target/linux/ramips/dts/rt3883.dtsi44
-rw-r--r--target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts113
-rw-r--r--target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi120
-rw-r--r--target/linux/ramips/dts/rt5350.dtsi22
-rw-r--r--target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts2
-rw-r--r--target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts4
-rw-r--r--target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts2
-rw-r--r--target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c2
-rw-r--r--target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c41
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c2
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c61
-rw-r--r--target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c1128
-rw-r--r--target/linux/ramips/image/mt7620.mk60
-rw-r--r--target/linux/ramips/image/mt7621.mk301
-rw-r--r--target/linux/ramips/image/mt76x8.mk38
-rw-r--r--target/linux/ramips/image/rt305x.mk12
-rw-r--r--target/linux/ramips/image/rt3883.mk3
-rw-r--r--target/linux/ramips/modules.mk21
-rw-r--r--target/linux/ramips/mt7620/base-files/etc/board.d/02_network5
-rw-r--r--target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches26
-rw-r--r--target/linux/ramips/mt7620/config-6.67
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/board.d/01_leds4
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/board.d/02_network22
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches20
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version3
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/hotplug.d/firmware/11-mt76-caldata21
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate3
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac22
-rwxr-xr-xtarget/linux/ramips/mt7621/base-files/etc/init.d/bootcount4
-rw-r--r--target/linux/ramips/mt7621/base-files/lib/upgrade/dna.sh44
-rwxr-xr-xtarget/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh9
-rw-r--r--target/linux/ramips/mt7621/config-6.66
-rw-r--r--target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds7
-rw-r--r--target/linux/ramips/mt76x8/base-files/etc/board.d/02_network11
-rw-r--r--target/linux/ramips/mt76x8/config-6.66
-rw-r--r--target/linux/ramips/patches-6.6/100-clk-ralink-mtmips-fix-clock-plan-for-Ralink-SoC-RT3883.patch45
-rw-r--r--target/linux/ramips/patches-6.6/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch68
-rw-r--r--target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch2
-rw-r--r--target/linux/ramips/patches-6.6/801-DT-Add-documentation-for-gpio-ralink.patch18
-rw-r--r--target/linux/ramips/patches-6.6/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch149
-rw-r--r--target/linux/ramips/patches-6.6/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch15
-rw-r--r--target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch1190
-rw-r--r--target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch26
-rw-r--r--target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch41
-rw-r--r--target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch62
-rw-r--r--target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch47
-rw-r--r--target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch72
-rw-r--r--target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch50
-rw-r--r--target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch61
-rw-r--r--target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch52
-rw-r--r--target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch40
-rw-r--r--target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch41
-rw-r--r--target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch62
-rw-r--r--target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch72
-rw-r--r--target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch18
-rw-r--r--target/linux/ramips/patches-6.6/825-i2c-MIPS-adds-ralink-I2C-driver.patch75
-rw-r--r--target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch39
-rw-r--r--target/linux/ramips/rt288x/config-6.65
-rw-r--r--target/linux/ramips/rt305x/config-6.65
-rw-r--r--target/linux/ramips/rt3883/config-6.65
-rw-r--r--target/linux/realtek/Makefile2
-rw-r--r--target/linux/realtek/base-files/etc/board.d/02_network13
-rw-r--r--target/linux/realtek/base-files/etc/uci-defaults/04_dlinkfan26
-rwxr-xr-xtarget/linux/realtek/base-files/sbin/fan_ctrl.sh13
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g.dtsi112
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts75
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts12
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts12
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts12
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28.dts11
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28_common.dtsi91
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28mp-f.dts40
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_hpe_1920.dtsi117
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts36
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts128
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts63
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts63
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts125
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts121
-rw-r--r--target/linux/realtek/dts-5.15/rtl8393_d-link_dgs-1210-52.dts163
-rw-r--r--target/linux/realtek/dts/rtl8380_d-link_dgs-1210-10mp-f.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_d-link_dgs-1210-10mp-f.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_engenius_ews2910p.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_engenius_ews2910p.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_hpe_1920-8g-poe-180w.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g-poe-180w.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_hpe_1920-8g-poe-65w.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g-poe-65w.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_hpe_1920-8g.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_hpe_1920-8g.dtsi112
-rw-r--r--target/linux/realtek/dts/rtl8380_linksys_lgs310c.dts212
-rw-r--r--target/linux/realtek/dts/rtl8380_netgear_gigabit.dtsi (renamed from target/linux/realtek/dts-5.15/rtl8380_netgear_gigabit.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl8380_netgear_gs108t-v3.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_netgear_gs108t-v3.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_netgear_gs110tpp-v1.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_netgear_gs110tpp-v1.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_netgear_gs110tup-v1.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_netgear_gs110tup-v1.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_netgear_gs308t-v1.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_netgear_gs308t-v1.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_netgear_gs310tp-v1.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_netgear_gs310tp-v1.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_panasonic_m8eg-pn28080k.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_panasonic_m8eg-pn28080k.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_tplink_sg2008p-v1.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_tplink_sg2008p-v1.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_tplink_sg2210p-v3.dts (renamed from target/linux/realtek/dts-5.15/rtl8380_tplink_sg2210p-v3.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8380_tplink_sg2xxx.dtsi (renamed from target/linux/realtek/dts-5.15/rtl8380_tplink_sg2xxx.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts75
-rw-r--r--target/linux/realtek/dts/rtl8380_zyxel_gs1900-8.dts12
-rw-r--r--target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v1.dts12
-rw-r--r--target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v2.dts12
-rw-r--r--target/linux/realtek/dts/rtl8380_zyxel_gs1900.dtsi (renamed from target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl8382_allnet_all-sg8208m.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_allnet_all-sg8208m.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_apresia_aplgs120gtss.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_apresia_aplgs120gtss.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-10p.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-10p.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-16.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-16.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-20.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-20.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28.dts12
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28_common.dtsi92
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28mp-f.dts14
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p-f.dts13
-rw-r--r--target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p_common.dtsi48
-rw-r--r--target/linux/realtek/dts/rtl8382_hpe_1920-16g.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_hpe_1920-16g.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_hpe_1920-24g.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_hpe_1920-24g.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_hpe_1920.dtsi117
-rw-r--r--target/linux/realtek/dts/rtl8382_inaba_aml2-17gp.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_inaba_aml2-17gp.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_iodata_bsh-g24mb.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_iodata_bsh-g24mb.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_panasonic_m16eg-pn28160k.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_panasonic_m16eg-pn28160k.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_panasonic_m24eg-pn28240k.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_panasonic_m24eg-pn28240k.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_tplink_t1600g-28ts-v3.dts (renamed from target/linux/realtek/dts-5.15/rtl8382_tplink_t1600g-28ts-v3.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8382_zyxel_gs1900-16.dts36
-rw-r--r--target/linux/realtek/dts/rtl8382_zyxel_gs1900-24-v1.dts128
-rw-r--r--target/linux/realtek/dts/rtl8382_zyxel_gs1900-24e.dts63
-rw-r--r--target/linux/realtek/dts/rtl8382_zyxel_gs1900-24ep.dts63
-rw-r--r--target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v1.dts125
-rw-r--r--target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v2.dts121
-rw-r--r--target/linux/realtek/dts/rtl838x.dtsi (renamed from target/linux/realtek/dts-5.15/rtl838x.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl8393_d-link_dgs-1210-52.dts163
-rw-r--r--target/linux/realtek/dts/rtl8393_hpe_1920-48g-poe.dts12
-rw-r--r--target/linux/realtek/dts/rtl8393_hpe_1920-48g.dts8
-rw-r--r--target/linux/realtek/dts/rtl8393_hpe_1920.dtsi246
-rw-r--r--target/linux/realtek/dts/rtl8393_netgear_gs750e.dts (renamed from target/linux/realtek/dts-5.15/rtl8393_netgear_gs750e.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8393_panasonic_m48eg-pn28480k.dts (renamed from target/linux/realtek/dts-5.15/rtl8393_panasonic_m48eg-pn28480k.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8393_tplink_sg2452p-v4.dts (renamed from target/linux/realtek/dts-5.15/rtl8393_tplink_sg2452p-v4.dts)0
-rw-r--r--target/linux/realtek/dts/rtl8393_zyxel_gs1900-48.dts (renamed from target/linux/realtek/dts-5.15/rtl8393_zyxel_gs1900-48.dts)0
-rw-r--r--target/linux/realtek/dts/rtl839x.dtsi (renamed from target/linux/realtek/dts-5.15/rtl839x.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_common.dtsi (renamed from target/linux/realtek/dts-5.15/rtl83xx_d-link_dgs-1210_common.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_gpio.dtsi (renamed from target/linux/realtek/dts-5.15/rtl83xx_d-link_dgs-1210_gpio.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_gpio_sfp.dtsi (renamed from target/linux/realtek/dts-5.15/rtl839x_d-link_dgs-1210_gpio.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl83xx_hpe_1920.dtsi (renamed from target/linux/realtek/dts-5.15/rtl838x_hpe_1920.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl83xx_panasonic_mxxeg-pn28xx0k.dtsi (renamed from target/linux/realtek/dts-5.15/rtl83xx_panasonic_mxxeg-pn28xx0k.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl9302_zyxel_xgs1250-12.dts (renamed from target/linux/realtek/dts-5.15/rtl9302_zyxel_xgs1250-12.dts)0
-rw-r--r--target/linux/realtek/dts/rtl930x.dtsi (renamed from target/linux/realtek/dts-5.15/rtl930x.dtsi)0
-rw-r--r--target/linux/realtek/dts/rtl931x.dtsi (renamed from target/linux/realtek/dts-5.15/rtl931x.dtsi)0
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c1717
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c2218
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h1103
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c1694
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c410
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c2599
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h458
-rw-r--r--target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c3988
-rw-r--r--target/linux/realtek/files-6.6/Documentation/devicetree/bindings/realtek,otto-timer.yaml (renamed from target/linux/realtek/files-5.15/Documentation/devicetree/bindings/realtek,otto-timer.yaml)0
-rw-r--r--target/linux/realtek/files-6.6/arch/mips/include/asm/mach-rtl838x/ioremap.h (renamed from target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/ioremap.h)0
-rw-r--r--target/linux/realtek/files-6.6/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h (renamed from target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h)0
-rw-r--r--target/linux/realtek/files-6.6/arch/mips/rtl838x/Makefile (renamed from target/linux/realtek/files-5.15/arch/mips/rtl838x/Makefile)0
-rw-r--r--target/linux/realtek/files-6.6/arch/mips/rtl838x/Platform (renamed from target/linux/realtek/files-5.15/arch/mips/rtl838x/Platform)0
-rw-r--r--target/linux/realtek/files-6.6/arch/mips/rtl838x/prom.c (renamed from target/linux/realtek/files-5.15/arch/mips/rtl838x/prom.c)0
-rw-r--r--target/linux/realtek/files-6.6/arch/mips/rtl838x/setup.c (renamed from target/linux/realtek/files-5.15/arch/mips/rtl838x/setup.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/clk/realtek/Kconfig (renamed from target/linux/realtek/files-5.15/drivers/clk/realtek/Kconfig)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/clk/realtek/Makefile (renamed from target/linux/realtek/files-5.15/drivers/clk/realtek/Makefile)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl838x-sram.S (renamed from target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl838x-sram.S)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl839x-sram.S (renamed from target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl839x-sram.S)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl83xx.c (renamed from target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl83xx.h (renamed from target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.h)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/clocksource/timer-rtl-otto.c (renamed from target/linux/realtek/files-5.15/drivers/clocksource/timer-rtl-otto.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/gpio/gpio-rtl8231.c (renamed from target/linux/realtek/files-5.15/drivers/gpio/gpio-rtl8231.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/i2c/busses/i2c-rtl9300.c (renamed from target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/i2c/busses/i2c-rtl9300.h (renamed from target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.h)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/i2c/muxes/i2c-mux-rtl9300.c (renamed from target/linux/realtek/files-5.15/drivers/i2c/muxes/i2c-mux-rtl9300.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/Kconfig (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Kconfig)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/Makefile (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Makefile)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c1733
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/debugfs.c (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/debugfs.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c2284
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/qos.c (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/qos.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.c (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h1117
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl839x.c (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl839x.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl83xx.h (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl930x.c (renamed from target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl930x.c)0
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl931x.c1694
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/tc.c410
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c2718
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h470
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c4001
-rw-r--r--target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.h (renamed from target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.h)0
-rw-r--r--target/linux/realtek/files-6.6/include/dt-bindings/clock/rtl83xx-clk.h (renamed from target/linux/realtek/files-5.15/include/dt-bindings/clock/rtl83xx-clk.h)0
-rw-r--r--target/linux/realtek/image/Makefile15
-rw-r--r--target/linux/realtek/image/common.mk2
-rw-r--r--target/linux/realtek/image/rtl838x.mk34
-rw-r--r--target/linux/realtek/image/rtl839x.mk17
-rw-r--r--target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch467
-rw-r--r--target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch53
-rw-r--r--target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch123
-rw-r--r--target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch153
-rw-r--r--target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch29
-rw-r--r--target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch30
-rw-r--r--target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch86
-rw-r--r--target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch50
-rw-r--r--target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch93
-rw-r--r--target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch26
-rw-r--r--target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch25
-rw-r--r--target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch25
-rw-r--r--target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch32
-rw-r--r--target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch28
-rw-r--r--target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch46
-rw-r--r--target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch402
-rw-r--r--target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch51
-rw-r--r--target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch368
-rw-r--r--target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch33
-rw-r--r--target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch159
-rw-r--r--target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch42
-rw-r--r--target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch61
-rw-r--r--target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch48
-rw-r--r--target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch34
-rw-r--r--target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch61
-rw-r--r--target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch62
-rw-r--r--target/linux/realtek/patches-5.15/705-add-rtl-phy.patch39
-rw-r--r--target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch32
-rw-r--r--target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch26
-rw-r--r--target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch148
-rw-r--r--target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch99
-rw-r--r--target/linux/realtek/patches-5.15/800-net-mdio-support-hardware-assisted-indirect-access.patch840
-rw-r--r--target/linux/realtek/patches-6.6/300-mips-add-rtl838x-platform.patch86
-rw-r--r--target/linux/realtek/patches-6.6/301-gpio-add-rtl8231-driver.patch50
-rw-r--r--target/linux/realtek/patches-6.6/302-clocksource-add-otto-driver.patch93
-rw-r--r--target/linux/realtek/patches-6.6/303-gpio-update-dependencies-for-gpio-realtek-otto.patch26
-rw-r--r--target/linux/realtek/patches-6.6/304-spi-update-dependency-for-spi-realtek-rtl.patch25
-rw-r--r--target/linux/realtek/patches-6.6/305-irqchip-update-dependency-for-irq-realtek-rtl.patch25
-rw-r--r--target/linux/realtek/patches-6.6/307-wdt-update-dependency-for-realtek-otto-wdt.patch32
-rw-r--r--target/linux/realtek/patches-6.6/310-add-i2c-rtl9300-support.patch46
-rw-r--r--target/linux/realtek/patches-6.6/311-add-i2c-mux-rtl9300-support.patch (renamed from target/linux/realtek/patches-5.15/311-add-i2c-mux-rtl9300-support.patch)0
-rw-r--r--target/linux/realtek/patches-6.6/314-irqchip-irq-realtek-rtl-add-VPE-support.patch427
-rw-r--r--target/linux/realtek/patches-6.6/318-add-rtl83xx-clk-support.patch33
-rw-r--r--target/linux/realtek/patches-6.6/320-harden-fw_init_cmdline.patch38
-rw-r--r--target/linux/realtek/patches-6.6/700-net-dsa-increase-dsa-max-ports-for-rtl838x.patch (renamed from target/linux/realtek/patches-5.15/702-net-dsa-increase-dsa-max-ports-for-rtl838x.patch)0
-rw-r--r--target/linux/realtek/patches-6.6/702-include-linux-add-phy-hsgmii-mode.patch79
-rw-r--r--target/linux/realtek/patches-6.6/704-include-linux-phy-increase-phy-address-number-for-rtl839x.patch32
-rw-r--r--target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch34
-rw-r--r--target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch61
-rw-r--r--target/linux/realtek/patches-6.6/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch26
-rw-r--r--target/linux/realtek/patches-6.6/712-net-phy-add-an-MDIO-SMBus-library.patch148
-rw-r--r--target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch127
-rw-r--r--target/linux/realtek/patches-6.6/716-net-ethernet-add-support-for-rtl838x-ethernet.patch48
-rw-r--r--target/linux/realtek/patches-6.6/718-net-dsa-add-support-for-rtl838x-switch.patch42
-rw-r--r--target/linux/realtek/patches-6.6/720-add-rtl-phy.patch39
-rw-r--r--target/linux/realtek/patches-6.6/722-net-dsa-add-rtl838x-support-for-tag-trailer.patch61
-rw-r--r--target/linux/realtek/rtl838x/config-6.6 (renamed from target/linux/realtek/rtl838x/config-5.15)0
-rw-r--r--target/linux/realtek/rtl839x/config-5.15241
-rw-r--r--target/linux/realtek/rtl839x/config-6.6244
-rw-r--r--target/linux/realtek/rtl930x/config-6.6 (renamed from target/linux/realtek/rtl930x/config-5.15)0
-rw-r--r--target/linux/realtek/rtl931x/config-5.15241
-rw-r--r--target/linux/realtek/rtl931x/config-6.6242
-rw-r--r--target/linux/rockchip/armv8/base-files/etc/board.d/01_leds6
-rw-r--r--target/linux/rockchip/armv8/base-files/etc/board.d/02_network16
-rw-r--r--target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity18
-rw-r--r--target/linux/rockchip/armv8/config-6.622
-rw-r--r--target/linux/rockchip/armv8/target.mk4
-rw-r--r--target/linux/rockchip/image/Makefile7
-rw-r--r--target/linux/rockchip/image/armv8.mk122
-rw-r--r--target/linux/rockchip/image/default.bootscript2
-rw-r--r--target/linux/rockchip/image/radxa-e25.bootscript7
-rw-r--r--target/linux/rockchip/image/rock-pi-s.bootscript7
-rw-r--r--target/linux/rockchip/patches-6.6/001-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch (renamed from target/linux/rockchip/patches-6.6/023-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch)0
-rw-r--r--target/linux/rockchip/patches-6.6/002-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch (renamed from target/linux/rockchip/patches-6.6/030-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch)0
-rw-r--r--target/linux/rockchip/patches-6.6/003-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch (renamed from target/linux/rockchip/patches-6.6/031-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch)0
-rw-r--r--target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch86
-rw-r--r--target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch28
-rw-r--r--target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch84
-rw-r--r--target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch152
-rw-r--r--target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch769
-rw-r--r--target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch657
-rw-r--r--target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch64
-rw-r--r--target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch101
-rw-r--r--target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch815
-rw-r--r--target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch78
-rw-r--r--target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch59
-rw-r--r--target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch78
-rw-r--r--target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch24
-rw-r--r--target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch25
-rw-r--r--target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch28
-rw-r--r--target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch1670
-rw-r--r--target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch43
-rw-r--r--target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch79
-rw-r--r--target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch106
-rw-r--r--target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch91
-rw-r--r--target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch58
-rw-r--r--target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch32
-rw-r--r--target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch37
-rw-r--r--target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch50
-rw-r--r--target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch48
-rw-r--r--target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch139
-rw-r--r--target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch34
-rw-r--r--target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch34
-rw-r--r--target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch120
-rw-r--r--target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch51
-rw-r--r--target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch25
-rw-r--r--target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch81
-rw-r--r--target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch384
-rw-r--r--target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch53
-rw-r--r--target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch175
-rw-r--r--target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch75
-rw-r--r--target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch74
-rw-r--r--target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch14208
-rw-r--r--target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch193
-rw-r--r--target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch50
-rw-r--r--target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch205
-rw-r--r--target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch140
-rw-r--r--target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch177
-rw-r--r--target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch39
-rw-r--r--target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch56
-rw-r--r--target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch45
-rw-r--r--target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch110
-rw-r--r--target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch72
-rw-r--r--target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch73
-rw-r--r--target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch80
-rw-r--r--target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch93
-rw-r--r--target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch65
-rw-r--r--target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch32
-rw-r--r--target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch57
-rw-r--r--target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch39
-rw-r--r--target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch31
-rw-r--r--target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch34
-rw-r--r--target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch43
-rw-r--r--target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch55
-rw-r--r--target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch67
-rw-r--r--target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch39
-rw-r--r--target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch792
-rw-r--r--target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch42
-rw-r--r--target/linux/rockchip/patches-6.6/055-01-v6.8-arm64-dts-rockchip-Support-poweroff-on-NanoPC-T6.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/055-02-v6.9-arm64-dts-rockchip-nanopc-t6-sdmmc-beautification.patch33
-rw-r--r--target/linux/rockchip/patches-6.6/055-03-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-nanopc-t.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/055-04-v6.9-arm64-dts-rockchip-enable-NanoPC-T6-MiniPCIe-power.patch57
-rw-r--r--target/linux/rockchip/patches-6.6/055-05-v6.9-arm64-dts-rockchip-add-sdmmc-card-detect-to-the-nanopc-t6.patch25
-rw-r--r--target/linux/rockchip/patches-6.6/055-06-v6.9-arm64-dts-rockchip-fix-nanopc-t6-sdmmc-regulator.patch44
-rw-r--r--target/linux/rockchip/patches-6.6/055-08-v6.12-arm64-dts-rockchip-prepare-NanoPC-T6-for-LTS-board.patch1916
-rw-r--r--target/linux/rockchip/patches-6.6/055-09-v6.12-arm64-dts-rockchip-move-NanoPC-T6-parts-to-DTS.patch85
-rw-r--r--target/linux/rockchip/patches-6.6/055-10-v6.12-arm64-dts-rockchip-add-SPI-flash-on-NanoPC-T6.patch40
-rw-r--r--target/linux/rockchip/patches-6.6/055-11-v6.12-arm64-dts-rockchip-add-IR-receiver-to-NanoPC-T6.patch53
-rw-r--r--target/linux/rockchip/patches-6.6/055-12-v6.12-arm64-dts-rockchip-enable-GPU-on-NanoPC-T6.patch28
-rw-r--r--target/linux/rockchip/patches-6.6/055-13-v6.12-arm64-dts-rockchip-enable-USB-C-on-NanoPC-T6.patch130
-rw-r--r--target/linux/rockchip/patches-6.6/055-14-v6.12-arm64-dts-rockchip-add-Mask-Rom-key-on-NanoPC-T6.patch45
-rw-r--r--target/linux/rockchip/patches-6.6/055-15-v6.12-arm64-dts-rockchip-use-correct-fcs-suspend-voltage-selecto.patch28
-rw-r--r--target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch778
-rw-r--r--target/linux/rockchip/patches-6.6/056-02-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch79
-rw-r--r--target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases-and-stop-heartbeat.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases.patch24
-rw-r--r--target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch22
-rw-r--r--target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch11
-rw-r--r--target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch30
-rw-r--r--target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/125-arm64-dts-rockchip-Update-LED-properties-for-ArmSom-Sige7.patch25
-rw-r--r--target/linux/rockchip/patches-6.6/126-arm64-dts-rockchip-lower-mmc-speed-for-ArmSom-Sige7.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch340
-rw-r--r--target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch290
-rw-r--r--target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch49
-rw-r--r--target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch56
-rw-r--r--target/linux/rockchip/patches-6.6/400-1-arm64-dts-rockchip-Add-common-definitions-for-NanoPi.patch1573
-rw-r--r--target/linux/rockchip/patches-6.6/400-2-arm64-dts-rockchip-Fix-regulators-gmac-and-naming-on.patch470
-rw-r--r--target/linux/rockchip/patches-6.6/400-3-arm64-dts-rockchip-Improve-LEDs-on-NanoPi-R6C-R6S.patch184
-rw-r--r--target/linux/rockchip/patches-6.6/400-4-arm64-dts-rockchip-Enable-lower-USB3-port-on-NanoPi-.patch62
-rw-r--r--target/linux/rockchip/patches-6.6/400-5-arm64-dts-rockchip-Enable-GPU-on-NanoPi-R6C-R6S.patch27
-rw-r--r--target/linux/sifiveu/patches-6.6/0005-riscv-sifive-unleashed-define-opp-table-cpufreq.patch2
-rw-r--r--target/linux/siflower/Makefile18
-rw-r--r--target/linux/siflower/dts/sf19a2890.dtsi651
-rw-r--r--target/linux/siflower/dts/sf19a2890_evb.dts140
-rw-r--r--target/linux/siflower/files-6.6/arch/mips/include/asm/mach-siflower/kmalloc.h9
-rw-r--r--target/linux/siflower/files-6.6/drivers/clk/siflower/Kconfig27
-rw-r--r--target/linux/siflower/files-6.6/drivers/clk/siflower/Makefile2
-rw-r--r--target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890-periph.c170
-rw-r--r--target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890.c414
-rw-r--r--target/linux/siflower/files-6.6/drivers/gpio/gpio-siflower.c346
-rw-r--r--target/linux/siflower/files-6.6/drivers/net/ethernet/stmicro/stmmac/dwmac-sf19a2890.c193
-rw-r--r--target/linux/siflower/files-6.6/drivers/phy/siflower/Kconfig6
-rw-r--r--target/linux/siflower/files-6.6/drivers/phy/siflower/Makefile2
-rw-r--r--target/linux/siflower/files-6.6/drivers/phy/siflower/phy-sf19a2890-usb.c145
-rw-r--r--target/linux/siflower/files-6.6/drivers/pinctrl/pinctrl-sf19a2890.c515
-rw-r--r--target/linux/siflower/files-6.6/drivers/reset/reset-sf19a2890-periph.c131
-rw-r--r--target/linux/siflower/files-6.6/include/dt-bindings/clock/siflower,sf19a2890-clk.h27
-rw-r--r--target/linux/siflower/image/Makefile28
-rw-r--r--target/linux/siflower/modules.mk15
-rw-r--r--target/linux/siflower/patches-6.6/001-mips-add-support-for-Siflower-SF19A2890.patch59
-rw-r--r--target/linux/siflower/patches-6.6/002-clk-add-drivers-for-sf19a2890.patch31
-rw-r--r--target/linux/siflower/patches-6.6/003-reset-add-support-for-sf19a2890.patch38
-rw-r--r--target/linux/siflower/patches-6.6/004-gpio-add-support-for-siflower-socs.patch37
-rw-r--r--target/linux/siflower/patches-6.6/005-pinctrl-add-driver-for-siflower-sf19a2890.patch39
-rw-r--r--target/linux/siflower/patches-6.6/006-stmmac-add-support-for-sf19a2890.patch38
-rw-r--r--target/linux/siflower/patches-6.6/007-phy-add-support-for-SF19A2890-USB-PHY.patch31
-rw-r--r--target/linux/siflower/patches-6.6/008-usb-dwc2-add-support-for-Siflower-SF19A2890.patch36
-rw-r--r--target/linux/siflower/patches-6.6/009-usb-dwc2-handle-OTG-interrupt-regardless-of-GINTSTS.patch67
-rw-r--r--target/linux/siflower/sf19a2890/base-files/etc/board.d/02_network42
-rw-r--r--target/linux/siflower/sf19a2890/base-files/lib/upgrade/platform.sh22
-rw-r--r--target/linux/siflower/sf19a2890/config-6.6266
-rw-r--r--target/linux/siflower/sf19a2890/target.mk12
-rw-r--r--target/linux/starfive/Makefile2
-rw-r--r--target/linux/starfive/config-6.1555
-rw-r--r--target/linux/starfive/config-6.6579
-rw-r--r--target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch482
-rw-r--r--target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch176
-rw-r--r--target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch53
-rw-r--r--target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch749
-rw-r--r--target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch290
-rw-r--r--target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch1249
-rw-r--r--target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch30
-rw-r--r--target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch436
-rw-r--r--target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch390
-rw-r--r--target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch215
-rw-r--r--target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch167
-rw-r--r--target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch146
-rw-r--r--target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch557
-rw-r--r--target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch206
-rw-r--r--target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch113
-rw-r--r--target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch50
-rw-r--r--target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch128
-rw-r--r--target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch27
-rw-r--r--target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch28
-rw-r--r--target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch27
-rw-r--r--target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch549
-rw-r--r--target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch331
-rw-r--r--target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch290
-rw-r--r--target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch43
-rw-r--r--target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch349
-rw-r--r--target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch303
-rw-r--r--target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch176
-rw-r--r--target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch1581
-rw-r--r--target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch224
-rw-r--r--target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch228
-rw-r--r--target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch80
-rw-r--r--target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch786
-rw-r--r--target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch75
-rw-r--r--target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch71
-rw-r--r--target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch86
-rw-r--r--target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch478
-rw-r--r--target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch98
-rw-r--r--target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch52
-rw-r--r--target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch48
-rw-r--r--target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch49
-rw-r--r--target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch29
-rw-r--r--target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch46
-rw-r--r--target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch190
-rw-r--r--target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch187
-rw-r--r--target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch93
-rw-r--r--target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch101
-rw-r--r--target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch128
-rw-r--r--target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch147
-rw-r--r--target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch34
-rw-r--r--target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch34
-rw-r--r--target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch193
-rw-r--r--target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch218
-rw-r--r--target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch156
-rw-r--r--target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch293
-rw-r--r--target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch163
-rw-r--r--target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch284
-rw-r--r--target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch61
-rw-r--r--target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch819
-rw-r--r--target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch113
-rw-r--r--target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch540
-rw-r--r--target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch36
-rw-r--r--target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch71
-rw-r--r--target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch294
-rw-r--r--target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch90
-rw-r--r--target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch337
-rw-r--r--target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch29
-rw-r--r--target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch23
-rw-r--r--target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch117
-rw-r--r--target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch744
-rw-r--r--target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch32
-rw-r--r--target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch28
-rw-r--r--target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch175
-rw-r--r--target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch119
-rw-r--r--target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch88
-rw-r--r--target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch365
-rw-r--r--target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch306
-rw-r--r--target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch55
-rw-r--r--target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch129
-rw-r--r--target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch141
-rw-r--r--target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch23
-rw-r--r--target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch197
-rw-r--r--target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch106
-rw-r--r--target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch630
-rw-r--r--target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch992
-rw-r--r--target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch1667
-rw-r--r--target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch1694
-rw-r--r--target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch68
-rw-r--r--target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch77
-rw-r--r--target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch192
-rw-r--r--target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch250
-rw-r--r--target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch135
-rw-r--r--target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch78
-rw-r--r--target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch298
-rw-r--r--target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch181
-rw-r--r--target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch79
-rw-r--r--target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch1004
-rw-r--r--target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch24
-rw-r--r--target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch1034
-rw-r--r--target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch48
-rw-r--r--target/linux/starfive/patches-6.1/0100-Add-readme.patch75
-rw-r--r--target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch76
-rw-r--r--target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch457
-rw-r--r--target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch28
-rw-r--r--target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch91
-rw-r--r--target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch675
-rw-r--r--target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch31
-rw-r--r--target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch95
-rw-r--r--target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch250
-rw-r--r--target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch89
-rw-r--r--target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch451
-rw-r--r--target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch62
-rw-r--r--target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch122
-rw-r--r--target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch29
-rw-r--r--target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch50
-rw-r--r--target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch136
-rw-r--r--target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch673
-rw-r--r--target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch25
-rw-r--r--target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch21
-rw-r--r--target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch21
-rw-r--r--target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch92
-rw-r--r--target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch63
-rw-r--r--target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch23
-rw-r--r--target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch25
-rw-r--r--target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch40
-rw-r--r--target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch32
-rw-r--r--target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch21
-rw-r--r--target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch28
-rw-r--r--target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch55
-rw-r--r--target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch64
-rw-r--r--target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch127
-rw-r--r--target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch302
-rw-r--r--target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch25
-rw-r--r--target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch94
-rw-r--r--target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch30
-rw-r--r--target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch477
-rw-r--r--target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch309
-rw-r--r--target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch105
-rw-r--r--target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch30
-rw-r--r--target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch77
-rw-r--r--target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch159
-rw-r--r--target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch48
-rw-r--r--target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch56
-rw-r--r--target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch144
-rw-r--r--target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch28
-rw-r--r--target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch1265
-rw-r--r--target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch20
-rw-r--r--target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch76
-rw-r--r--target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch114
-rw-r--r--target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch428
-rw-r--r--target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch34
-rw-r--r--target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch199
-rw-r--r--target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch79
-rw-r--r--target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch285
-rw-r--r--target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch117
-rw-r--r--target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch25
-rw-r--r--target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch200
-rw-r--r--target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch46
-rw-r--r--target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch125
-rw-r--r--target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch33
-rw-r--r--target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch183
-rw-r--r--target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch2523
-rw-r--r--target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch259
-rw-r--r--target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch107
-rw-r--r--target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch347
-rw-r--r--target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch87
-rw-r--r--target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch76
-rw-r--r--target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch49
-rw-r--r--target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch200
-rw-r--r--target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch336
-rw-r--r--target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch65
-rw-r--r--target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch114
-rw-r--r--target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch56
-rw-r--r--target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch167
-rw-r--r--target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch144
-rw-r--r--target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch1028
-rw-r--r--target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch67
-rw-r--r--target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch256
-rw-r--r--target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch140
-rw-r--r--target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch55
-rw-r--r--target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch623
-rw-r--r--target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch97
-rw-r--r--target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch574
-rw-r--r--target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch32
-rw-r--r--target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch52
-rw-r--r--target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch35
-rw-r--r--target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch31
-rw-r--r--target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch179
-rw-r--r--target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch122
-rw-r--r--target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch36
-rw-r--r--target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch69
-rw-r--r--target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch31
-rw-r--r--target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch32
-rw-r--r--target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch30
-rw-r--r--target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch536
-rw-r--r--target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch147
-rw-r--r--target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch64
-rw-r--r--target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch60
-rw-r--r--target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch30
-rw-r--r--target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch67
-rw-r--r--target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch24
-rw-r--r--target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch22
-rw-r--r--target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch2623
-rw-r--r--target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch728
-rw-r--r--target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch485
-rw-r--r--target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch385
-rw-r--r--target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch318
-rw-r--r--target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch344
-rw-r--r--target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch33
-rw-r--r--target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch26
-rw-r--r--target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch808
-rw-r--r--target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch789
-rw-r--r--target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch96
-rw-r--r--target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch29
-rw-r--r--target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch32
-rw-r--r--target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch113
-rw-r--r--target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch1317
-rw-r--r--target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch204
-rw-r--r--target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch40
-rw-r--r--target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch93
-rw-r--r--target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch55
-rw-r--r--target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch42
-rw-r--r--target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch30
-rw-r--r--target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch24
-rw-r--r--target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch4748
-rw-r--r--target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch1169
-rw-r--r--target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch537
-rw-r--r--target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch55
-rw-r--r--target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch444
-rw-r--r--target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch246
-rw-r--r--target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch24014
-rw-r--r--target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch135
-rw-r--r--target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch1971
-rw-r--r--target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch69
-rw-r--r--target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch270
-rw-r--r--target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch82
-rw-r--r--target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch22
-rw-r--r--target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch506
-rw-r--r--target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch37
-rw-r--r--target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch856
-rw-r--r--target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch249
-rw-r--r--target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch117
-rw-r--r--target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch226
-rw-r--r--target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch36
-rw-r--r--target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch26
-rw-r--r--target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch22
-rw-r--r--target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch232
-rw-r--r--target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch92
-rw-r--r--target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch403
-rw-r--r--target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch38
-rw-r--r--target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch444
-rw-r--r--target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch759
-rw-r--r--target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch71
-rw-r--r--target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch23
-rw-r--r--target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch297
-rw-r--r--target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch106
-rw-r--r--target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch139
-rw-r--r--target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch34
-rw-r--r--target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch6063
-rw-r--r--target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch67
-rw-r--r--target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch53
-rw-r--r--target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch32
-rw-r--r--target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch25
-rw-r--r--target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch32
-rw-r--r--target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch28
-rw-r--r--target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch55
-rw-r--r--target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch64
-rw-r--r--target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch127
-rw-r--r--target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch302
-rw-r--r--target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch25
-rw-r--r--target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch94
-rw-r--r--target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch30
-rw-r--r--target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch477
-rw-r--r--target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch309
-rw-r--r--target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch48
-rw-r--r--target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch56
-rw-r--r--target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch144
-rw-r--r--target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch28
-rw-r--r--target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch160
-rw-r--r--target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch44
-rw-r--r--target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch26
-rw-r--r--target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch50
-rw-r--r--target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch61
-rw-r--r--target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch49
-rw-r--r--target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch85
-rw-r--r--target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch33
-rw-r--r--target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch1138
-rw-r--r--target/linux/sunxi/config-6.62
-rw-r--r--target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch32
-rw-r--r--target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch29
-rw-r--r--target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch149
-rw-r--r--target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch132
-rw-r--r--target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch122
-rw-r--r--target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch188
-rw-r--r--target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch86
-rw-r--r--target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch51
-rw-r--r--target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch34
-rw-r--r--target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch2
-rw-r--r--target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch107
-rw-r--r--target/linux/tegra/Makefile3
-rw-r--r--target/linux/tegra/config-5.15506
-rw-r--r--target/linux/tegra/image/Makefile4
-rw-r--r--target/linux/tegra/patches-5.15/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch77
-rw-r--r--target/linux/tegra/patches-5.15/101-ARM-dtc-tegra-enable-front-panel-leds-in-TrimSlice.patch46
-rw-r--r--target/linux/x86/64/config-6.65
-rw-r--r--target/linux/x86/base-files/etc/board.d/02_network3
-rw-r--r--target/linux/x86/config-6.61
-rw-r--r--target/linux/x86/generic/config-6.65
-rw-r--r--target/linux/x86/image/Makefile2
-rw-r--r--target/linux/x86/legacy/config-6.65
-rw-r--r--target/linux/zynq/Makefile2
-rw-r--r--target/linux/zynq/config-6.1566
-rw-r--r--target/linux/zynq/config-6.6570
-rw-r--r--target/linux/zynq/image/Makefile1
3574 files changed, 180316 insertions, 421957 deletions
diff --git a/target/imagebuilder/Makefile b/target/imagebuilder/Makefile
index 7fd2aa0920..7127df5ebc 100644
--- a/target/imagebuilder/Makefile
+++ b/target/imagebuilder/Makefile
@@ -112,6 +112,9 @@ endif
-cp $(LINUX_DIR)/.config $(IB_LDIR)/
rm -f $(IB_KDIR)/root.*
rm -f $(IB_KDIR)/vmlinux.debug
+ # remove any file for initramfs and Per Device Rootfs initramfs files
+ rm -f $(IB_KDIR)/vmlinux-initramfs*
+ rm -f $(IB_KDIR)/Image-initramfs*
if [ -x $(LINUX_DIR)/scripts/dtc/dtc ]; then \
$(INSTALL_DIR) $(IB_LDIR)/scripts/dtc; \
$(INSTALL_BIN) $(LINUX_DIR)/scripts/dtc/dtc $(IB_LDIR)/scripts/dtc/dtc; \
diff --git a/target/linux/apm821xx/base-files/etc/board.d/01_leds b/target/linux/apm821xx/base-files/etc/board.d/01_leds
index c384d24a30..f83888deeb 100644
--- a/target/linux/apm821xx/base-files/etc/board.d/01_leds
+++ b/target/linux/apm821xx/base-files/etc/board.d/01_leds
@@ -14,14 +14,6 @@ meraki,mr24)
ucidef_set_led_wlan "wlan2g_0" "WIFI 2.4GHz-0" "green:wlan-3" "phy0radio"
;;
-meraki,mx60)
- ucidef_set_led_switch "wan" "WAN" "green:wan" "switch0" "0x20"
- ucidef_set_led_switch "lan1" "LAN1" "green:lan-0" "switch0" "0x10"
- ucidef_set_led_switch "lan2" "LAN2" "green:lan-1" "switch0" "0x08"
- ucidef_set_led_switch "lan3" "LAN3" "green:lan-2" "switch0" "0x04"
- ucidef_set_led_switch "lan4" "LAN4" "green:lan-3" "switch0" "0x02"
- ;;
-
netgear,wndap620)
ucidef_set_led_switch "lan_act" "LAN (Activity)" "green:activity" "switch0" "0x04" "0x0f" "rx tx"
ucidef_set_led_switch "lan_100" "LAN 100Mbps" "amber:lan" "switch0" "0x04" "0x04" "link"
@@ -39,8 +31,8 @@ netgear,wndap660)
;;
netgear,wndr4700)
- ucidef_set_led_switch "wan_green" "WAN (green)" "green:wan" "switch0" "0x20"
- ucidef_set_led_netdev "wan_yellow" "WAN (yellow)" "yellow:wan" "eth0.2" "tx rx"
+ ucidef_set_led_netdev "wan_green" "WAN (green)" "green:wan" "wan" "link"
+ ucidef_set_led_netdev "wan_yellow" "WAN (yellow)" "yellow:wan" "wan" "tx rx"
;;
esac
diff --git a/target/linux/apm821xx/base-files/etc/board.d/02_network b/target/linux/apm821xx/base-files/etc/board.d/02_network
index 756ea348b4..dfcf4be8b9 100644
--- a/target/linux/apm821xx/base-files/etc/board.d/02_network
+++ b/target/linux/apm821xx/base-files/etc/board.d/02_network
@@ -20,8 +20,7 @@ netgear,wndap660)
;;
meraki,mx60|\
netgear,wndr4700)
- ucidef_add_switch "switch0" \
- "0@eth0" "4:lan" "3:lan" "2:lan" "1:lan" "5:wan"
+ ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
;;
*)
diff --git a/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version b/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version
index d34b4051be..00d3954e5f 100644
--- a/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version
+++ b/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version
@@ -5,7 +5,7 @@ meraki,mx60|\
netgear,wndap620|\
netgear,wndap660|\
netgear,wndr4700)
- uci set system.@system[0].compat_version="2.0"
+ uci set system.@system[0].compat_version="3.0"
uci commit system
;;
esac
diff --git a/target/linux/apm821xx/base-files/lib/preinit/05_set_iface_mac_apm821xx b/target/linux/apm821xx/base-files/lib/preinit/05_set_iface_mac_apm821xx
deleted file mode 100644
index 5f92c01931..0000000000
--- a/target/linux/apm821xx/base-files/lib/preinit/05_set_iface_mac_apm821xx
+++ /dev/null
@@ -1,13 +0,0 @@
-preinit_set_mac_address() {
- . /lib/functions.sh
-
- case $(board_name) in
- meraki,mr24|\
- meraki,mx60)
- mac_lan=$(mtd_get_mac_binary_ubi board-config 0x66)
- [ -n "$mac_lan" ] && ip link set eth0 address "$mac_lan"
- ;;
- esac
-}
-
-boot_hook_add preinit_main preinit_set_mac_address
diff --git a/target/linux/apm821xx/dts/meraki-mr24.dts b/target/linux/apm821xx/dts/meraki-mr24.dts
index a49a4de13f..24ae3dd13f 100644
--- a/target/linux/apm821xx/dts/meraki-mr24.dts
+++ b/target/linux/apm821xx/dts/meraki-mr24.dts
@@ -86,8 +86,25 @@
};
partition@180000 {
+ compatible = "linux,ubi";
label = "ubi";
reg = <0x00180000 0x01e80000>;
+
+ volumes {
+ ubi-volume-board-config {
+ volume = "board-config";
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_board_66: macaddr@66 {
+ reg = <0x66 0x6>;
+ };
+ };
+ };
+ };
};
};
};
@@ -110,6 +127,9 @@
&EMAC0 {
status = "okay";
+ nvmem-cells = <&macaddr_board_66>;
+ nvmem-cell-names = "mac-address";
+
phy-mode = "rgmii-id";
phy-map = <0x2>;
phy-address = <0x1>;
diff --git a/target/linux/apm821xx/dts/meraki-mx60.dts b/target/linux/apm821xx/dts/meraki-mx60.dts
index d9568d9263..10ced9fc09 100644
--- a/target/linux/apm821xx/dts/meraki-mx60.dts
+++ b/target/linux/apm821xx/dts/meraki-mx60.dts
@@ -71,8 +71,27 @@
};
partition@240000 {
+ compatible = "linux,ubi";
label = "ubi";
reg = <0x00240000 0x3fdc0000>;
+
+ volumes {
+ ubi-volume-board-config {
+ volume = "board-config";
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_board_66: macaddr@66 {
+ compatible = "mac-base";
+ reg = <0x66 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+ };
};
};
};
@@ -92,23 +111,246 @@
&EMAC0 {
status = "okay";
- phy-handle = <&phy0>;
+
+ nvmem-cells = <&macaddr_board_66 0>;
+ nvmem-cell-names = "mac-address";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
mdio {
#address-cells = <1>;
#size-cells = <0>;
- phy0: ethernet-phy@0 {
+
+ phy_port1: phy@0 {
compatible = "ethernet-phy-id004d.d034";
reg = <0>;
- qca,mib-poll-interval = <500>;
-
- qca,ar8327-initvals = <
- 0x0010 0x40000000
- 0x0624 0x007f7f7f
- 0x0004 0x07a00000 /* PAD0_MODE */
- 0x000c 0x01000000 /* PAD6_MODE */
- 0x007c 0x0000007e /* PORT0_STATUS */
- >;
+ };
+
+ phy_port2: phy@1 {
+ compatible = "ethernet-phy-id004d.d034";
+ reg = <1>;
+ };
+
+ phy_port3: phy@2 {
+ compatible = "ethernet-phy-id004d.d034";
+ reg = <2>;
+ };
+
+ phy_port4: phy@3 {
+ compatible = "ethernet-phy-id004d.d034";
+ reg = <3>;
+ };
+
+ phy_port5: phy@4 {
+ compatible = "ethernet-phy-id004d.d034";
+ reg = <4>;
+ };
+
+ switch0@10 {
+ compatible = "qca,qca8327";
+ reg = <0x10>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ ethernet = <&EMAC0>;
+ phy-mode = "rgmii-id";
+ tx-internal-delay-ps = <2000>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan4";
+ phy-mode = "internal";
+ phy-handle = <&phy_port1>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <0>;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <2>;
+ default-state = "keep";
+ };
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ phy-mode = "internal";
+ phy-handle = <&phy_port2>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <0>;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <2>;
+ default-state = "keep";
+ };
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan2";
+ phy-mode = "internal";
+ phy-handle = <&phy_port3>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <0>;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <2>;
+ default-state = "keep";
+ };
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "lan1";
+ phy-mode = "internal";
+ phy-handle = <&phy_port4>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <0>;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <2>;
+ default-state = "keep";
+ };
+ };
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "wan";
+ phy-mode = "internal";
+ phy-handle = <&phy_port5>;
+ nvmem-cells = <&macaddr_board_66 1>;
+ nvmem-cell-names = "mac-address";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ function-enumerator = <0>;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_WAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ function-enumerator = <2>;
+ default-state = "keep";
+ };
+ };
+ };
+ };
};
};
};
diff --git a/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi b/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi
index 9d98776626..7c9faa883f 100644
--- a/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi
+++ b/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi
@@ -224,7 +224,7 @@
rtl8367b {
compatible = "realtek,rtl8367b";
- realtek,extif0 = <1 2 1 1 1 1 1 1 2>;
+ realtek,extif = <5 1 2 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
};
};
diff --git a/target/linux/apm821xx/dts/netgear-wndr4700.dts b/target/linux/apm821xx/dts/netgear-wndr4700.dts
index 851a3192b3..4ef05937d3 100644
--- a/target/linux/apm821xx/dts/netgear-wndr4700.dts
+++ b/target/linux/apm821xx/dts/netgear-wndr4700.dts
@@ -350,24 +350,93 @@
&EMAC0 {
status = "okay";
- phy-handle = <&phy0>;
fifo-entry-size = <10>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+
mdio {
#address-cells = <1>;
#size-cells = <0>;
- phy0: ethernet-phy@0 {
- device_type = "ethernet-phy";
+
+ phy_port1: phy@0 {
reg = <0>;
- qca,mib-poll-interval = <500>;
-
- qca,ar8327-initvals = <
- 0x0010 0x40000000
- 0x0624 0x007f7f7f
- 0x0004 0x07a00000 /* PAD0_MODE */
- 0x000c 0x01000000 /* PAD6_MODE */
- 0x007c 0x0000007e /* PORT0_STATUS */
- >;
+ };
+
+ phy_port2: phy@1 {
+ reg = <1>;
+ };
+
+ phy_port3: phy@2 {
+ reg = <2>;
+ };
+
+ phy_port4: phy@3 {
+ reg = <3>;
+ };
+
+ phy_port5: phy@4 {
+ reg = <4>;
+ };
+
+ switch0@10 {
+ compatible = "qca,qca8327";
+ reg = <0x10>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "cpu";
+ ethernet = <&EMAC0>;
+ phy-mode = "rgmii-id";
+ tx-internal-delay-ps = <2000>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan4";
+ phy-mode = "internal";
+ phy-handle = <&phy_port1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ phy-mode = "internal";
+ phy-handle = <&phy_port2>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan2";
+ phy-mode = "internal";
+ phy-handle = <&phy_port3>;
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "lan1";
+ phy-mode = "internal";
+ phy-handle = <&phy_port4>;
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "wan";
+ phy-mode = "internal";
+ phy-handle = <&phy_port5>;
+ };
+ };
};
};
};
diff --git a/target/linux/apm821xx/image/nand.mk b/target/linux/apm821xx/image/nand.mk
index 69eb386126..92bdaa87d0 100644
--- a/target/linux/apm821xx/image/nand.mk
+++ b/target/linux/apm821xx/image/nand.mk
@@ -50,8 +50,9 @@ define Device/meraki_mx60
KERNEL := kernel-bin | libdeflate-gzip | MuImage-initramfs gzip
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
UBINIZE_OPTS := -E 5
- DEVICE_COMPAT_VERSION := 2.0
+ DEVICE_COMPAT_VERSION := 3.0
DEVICE_COMPAT_MESSAGE := uboot's bootcmd has to be updated to support standard multi-image uImages. \
+ Network swconfig configuration cannot be upgraded to DSA. \
Upgrade via sysupgrade mechanism is not possible.
endef
TARGET_DEVICES += meraki_mx60
@@ -88,6 +89,9 @@ endef
TARGET_DEVICES += netgear_wndap660
define Device/netgear_wndr4700
+ DEVICE_COMPAT_VERSION := 3.0
+ DEVICE_COMPAT_MESSAGE := Network swconfig configuration cannot be upgraded to DSA. \
+ Upgrade via sysupgrade mechanism is not possible.
DEVICE_VENDOR := NETGEAR
DEVICE_MODEL := Centria N900 WNDR4700
DEVICE_ALT0_VENDOR := NETGEAR
diff --git a/target/linux/apm821xx/nand/config-default b/target/linux/apm821xx/nand/config-default
index 7070b34b93..ab7d790870 100644
--- a/target/linux/apm821xx/nand/config-default
+++ b/target/linux/apm821xx/nand/config-default
@@ -1,5 +1,3 @@
-CONFIG_AT803X_PHY=y
-CONFIG_AR8216_PHY=y
# CONFIG_SATA_DWC_OLD_DMA is not set
CONFIG_IKAREM=y
# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
@@ -26,6 +24,15 @@ CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_QCA8K=y
+CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y
+CONFIG_NET_DSA_TAG_QCA=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_PHYLINK=y
+CONFIG_QCA83XX_PHY=y
+CONFIG_QCOM_NET_PHYLIB=y
CONFIG_UBIFS_FS=y
CONFIG_RTL8366_SMI=y
CONFIG_RTL8367B_PHY=y
@@ -33,4 +40,3 @@ CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_TC654=y
CONFIG_SWCONFIG=y
CONFIG_SWCONFIG_LEDS=y
-
diff --git a/target/linux/archs38/Makefile b/target/linux/archs38/Makefile
index e352c58957..0b3feb9889 100644
--- a/target/linux/archs38/Makefile
+++ b/target/linux/archs38/Makefile
@@ -11,7 +11,7 @@ BOARDNAME:=Synopsys DesignWare ARC HS38
FEATURES:=source-only
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
DEVICE_TYPE:=basic
diff --git a/target/linux/archs38/config-6.1 b/target/linux/archs38/config-6.1
deleted file mode 100644
index 9fe6ba2932..0000000000
--- a/target/linux/archs38/config-6.1
+++ /dev/null
@@ -1,268 +0,0 @@
-# CONFIG_16KSTACKS is not set
-CONFIG_ARC=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARC_BUILTIN_DTB_NAME=""
-CONFIG_ARC_CACHE=y
-CONFIG_ARC_CACHE_LINE_SHIFT=6
-CONFIG_ARC_CACHE_PAGES=y
-CONFIG_ARC_CPU_HS=y
-CONFIG_ARC_CURR_IN_REG=y
-CONFIG_ARC_DBG=y
-# CONFIG_ARC_DSP_AGU_USERSPACE is not set
-# CONFIG_ARC_DSP_KERNEL is not set
-CONFIG_ARC_DSP_NONE=y
-# CONFIG_ARC_DSP_USERSPACE is not set
-CONFIG_ARC_DW2_UNWIND=y
-CONFIG_ARC_FPU_SAVE_RESTORE=y
-CONFIG_ARC_HAS_ACCL_REGS=y
-CONFIG_ARC_HAS_DCACHE=y
-# CONFIG_ARC_HAS_DCCM is not set
-CONFIG_ARC_HAS_DIV_REM=y
-CONFIG_ARC_HAS_ICACHE=y
-# CONFIG_ARC_HAS_ICCM is not set
-CONFIG_ARC_HAS_LL64=y
-CONFIG_ARC_HAS_LLSC=y
-# CONFIG_ARC_HAS_PAE40 is not set
-CONFIG_ARC_HAS_SWAPE=y
-CONFIG_ARC_IRQ_NO_AUTOSAVE=y
-CONFIG_ARC_KVADDR_SIZE=256
-# CONFIG_ARC_LPB_DISABLE is not set
-CONFIG_ARC_MCIP=y
-# CONFIG_ARC_METAWARE_HLINK is not set
-CONFIG_ARC_MMU_V4=y
-# CONFIG_ARC_PAGE_SIZE_16K is not set
-# CONFIG_ARC_PAGE_SIZE_4K is not set
-CONFIG_ARC_PAGE_SIZE_8K=y
-CONFIG_ARC_PLAT_AXS10X=y
-# CONFIG_ARC_PLAT_TB10X is not set
-# CONFIG_ARC_SMP_HALT_ON_RESET is not set
-CONFIG_ARC_SOC_HSDK=y
-CONFIG_ARC_TIMERS=y
-CONFIG_ARC_TIMERS_64BIT=y
-CONFIG_ARC_TUNE_MCPU=""
-CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS=y
-CONFIG_AXS103=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_SD=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLK_HSDK=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECHAINIV=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DTC=y
-CONFIG_DWMAC_ANARION=y
-CONFIG_DWMAC_GENERIC=y
-CONFIG_DW_APB_ICTL=y
-CONFIG_DW_AXI_DMAC=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_FAT_FS=y
-CONFIG_FB=y
-CONFIG_FB_CMDLINE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_DWAPB=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_SNPS_CREG=y
-CONFIG_GRACE_PERIOD=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_ST_PRESS=y
-CONFIG_IIO_ST_PRESS_I2C=y
-CONFIG_IIO_ST_PRESS_SPI=y
-CONFIG_IIO_ST_SENSORS_CORE=y
-CONFIG_IIO_ST_SENSORS_I2C=y
-CONFIG_IIO_ST_SENSORS_SPI=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_TRIGGERED_BUFFER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISA_ARCOMPACT is not set
-CONFIG_ISA_ARCV2=y
-CONFIG_JBD2=y
-CONFIG_KALLSYMS=y
-CONFIG_KERNEL_GZIP=y
-CONFIG_LIBFDT=y
-CONFIG_LINUX_LINK_BASE=0x90000000
-CONFIG_LINUX_RAM_BASE=0x80000000
-CONFIG_LOCKD=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MICREL_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_DW=y
-# CONFIG_MMC_DW_BLUEFIELD is not set
-# CONFIG_MMC_DW_EXYNOS is not set
-# CONFIG_MMC_DW_HI3798CV200 is not set
-# CONFIG_MMC_DW_K3 is not set
-CONFIG_MMC_DW_PLTFM=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NAMESPACES=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_NS=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NFS_ACL_SUPPORT=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NO_IOPORT_MAP=y
-CONFIG_NR_CPUS=4
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCS_XPCS=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PPS=y
-CONFIG_PREEMPT=y
-CONFIG_PREEMPTION=y
-CONFIG_PREEMPT_BUILD=y
-CONFIG_PREEMPT_COUNT=y
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_RCU=y
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_RESET_AXS10X=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_HSDK=y
-CONFIG_RESET_SIMPLE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_ARC=y
-CONFIG_SERIAL_ARC_CONSOLE=y
-CONFIG_SERIAL_ARC_NR_PORTS=1
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOFTLOCKUP_DETECTOR=y
-CONFIG_SPI=y
-CONFIG_SPI_DESIGNWARE=y
-# CONFIG_SPI_DW_DMA is not set
-CONFIG_SPI_DW_MMIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-# CONFIG_STANDALONE is not set
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_SUNRPC=y
-CONFIG_SWPHY=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TI_ADC108S102=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_USB_SUPPORT=y
-# CONFIG_USER_NS is not set
-CONFIG_VFAT_FS=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
diff --git a/target/linux/archs38/config-6.6 b/target/linux/archs38/config-6.6
new file mode 100644
index 0000000000..6298ce9e46
--- /dev/null
+++ b/target/linux/archs38/config-6.6
@@ -0,0 +1,279 @@
+# CONFIG_16KSTACKS is not set
+CONFIG_ARC=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARC_BUILTIN_DTB_NAME=""
+CONFIG_ARC_CACHE=y
+CONFIG_ARC_CACHE_LINE_SHIFT=6
+CONFIG_ARC_CACHE_PAGES=y
+CONFIG_ARC_CPU_HS=y
+CONFIG_ARC_CURR_IN_REG=y
+CONFIG_ARC_DBG=y
+# CONFIG_ARC_DSP_AGU_USERSPACE is not set
+# CONFIG_ARC_DSP_KERNEL is not set
+CONFIG_ARC_DSP_NONE=y
+# CONFIG_ARC_DSP_USERSPACE is not set
+CONFIG_ARC_DW2_UNWIND=y
+CONFIG_ARC_FPU_SAVE_RESTORE=y
+CONFIG_ARC_HAS_ACCL_REGS=y
+CONFIG_ARC_HAS_DCACHE=y
+# CONFIG_ARC_HAS_DCCM is not set
+CONFIG_ARC_HAS_DIV_REM=y
+CONFIG_ARC_HAS_ICACHE=y
+# CONFIG_ARC_HAS_ICCM is not set
+CONFIG_ARC_HAS_LL64=y
+CONFIG_ARC_HAS_LLSC=y
+# CONFIG_ARC_HAS_PAE40 is not set
+CONFIG_ARC_HAS_SWAPE=y
+CONFIG_ARC_IRQ_NO_AUTOSAVE=y
+CONFIG_ARC_KVADDR_SIZE=256
+# CONFIG_ARC_LPB_DISABLE is not set
+CONFIG_ARC_MCIP=y
+# CONFIG_ARC_METAWARE_HLINK is not set
+CONFIG_ARC_MMU_V4=y
+# CONFIG_ARC_PAGE_SIZE_16K is not set
+# CONFIG_ARC_PAGE_SIZE_4K is not set
+CONFIG_ARC_PAGE_SIZE_8K=y
+CONFIG_ARC_PLAT_AXS10X=y
+# CONFIG_ARC_PLAT_TB10X is not set
+# CONFIG_ARC_SMP_HALT_ON_RESET is not set
+CONFIG_ARC_SOC_HSDK=y
+CONFIG_ARC_TIMERS=y
+CONFIG_ARC_TIMERS_64BIT=y
+CONFIG_ARC_TUNE_MCPU=""
+CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS=y
+CONFIG_AXS103=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_SD=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLK_HSDK=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_GENIV=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+CONFIG_DWMAC_ANARION=y
+CONFIG_DWMAC_GENERIC=y
+CONFIG_DW_APB_ICTL=y
+CONFIG_DW_AXI_DMAC=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_FAT_FS=y
+CONFIG_FB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_IOMEM_FOPS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_SNPS_CREG=y
+CONFIG_GRACE_PERIOD=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_ST_PRESS=y
+CONFIG_IIO_ST_PRESS_I2C=y
+CONFIG_IIO_ST_PRESS_SPI=y
+CONFIG_IIO_ST_SENSORS_CORE=y
+CONFIG_IIO_ST_SENSORS_I2C=y
+CONFIG_IIO_ST_SENSORS_SPI=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISA_ARCOMPACT is not set
+CONFIG_ISA_ARCV2=y
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KERNEL_GZIP=y
+CONFIG_LEGACY_DIRECT_IO=y
+CONFIG_LIBFDT=y
+CONFIG_LINUX_LINK_BASE=0x90000000
+CONFIG_LINUX_RAM_BASE=0x80000000
+CONFIG_LOCKD=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MICREL_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
+# CONFIG_MMC_DW_EXYNOS is not set
+# CONFIG_MMC_DW_HI3798CV200 is not set
+# CONFIG_MMC_DW_K3 is not set
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NAMESPACES=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_HANDSHAKE=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_NS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_XGRESS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NO_IOPORT_MAP=y
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCS_XPCS=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PPS=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPTION=y
+CONFIG_PREEMPT_BUILD=y
+CONFIG_PREEMPT_COUNT=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_RESET_AXS10X=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_HSDK=y
+CONFIG_RESET_SIMPLE=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_ARC=y
+CONFIG_SERIAL_ARC_CONSOLE=y
+CONFIG_SERIAL_ARC_NR_PORTS=1
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_SPI=y
+CONFIG_SPI_DESIGNWARE=y
+# CONFIG_SPI_DW_DMA is not set
+CONFIG_SPI_DW_MMIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_STACKTRACE=y
+# CONFIG_STANDALONE is not set
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_SUNRPC=y
+CONFIG_SWPHY=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TI_ADC108S102=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USER_NS is not set
+CONFIG_VFAT_FS=y
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XPS=y
diff --git a/target/linux/archs38/generic/target.mk b/target/linux/archs38/generic/target.mk
index 7642c6b261..dfe0474fd8 100644
--- a/target/linux/archs38/generic/target.mk
+++ b/target/linux/archs38/generic/target.mk
@@ -1,5 +1,5 @@
BOARDNAME:=Generic
-FEATURES += ext4 usb ramdisk
+FEATURES += ext4 usb ramdisk rootfs-part
define Target/Description
Build firmware images for ARC HS38 based boards.
diff --git a/target/linux/armsr/armv8/config-6.6 b/target/linux/armsr/armv8/config-6.6
index 3ce25c60d8..a5a90ff9a8 100644
--- a/target/linux/armsr/armv8/config-6.6
+++ b/target/linux/armsr/armv8/config-6.6
@@ -59,10 +59,8 @@ CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_AMU_EXTN=y
CONFIG_ARM64_BTI=y
-CONFIG_ARM64_CNP=y
CONFIG_ARM64_CRYPTO=y
CONFIG_ARM64_E0PD=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1024718=y
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
@@ -93,7 +91,6 @@ CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_MTE=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
diff --git a/target/linux/armsr/base-files/etc/inittab b/target/linux/armsr/base-files/etc/inittab
index b3033a3ced..7ca0231a22 100644
--- a/target/linux/armsr/base-files/etc/inittab
+++ b/target/linux/armsr/base-files/etc/inittab
@@ -2,7 +2,7 @@
::shutdown:/etc/init.d/rcS K shutdown
ttyAMA0::askfirst:/usr/libexec/login.sh
@GRUB_SERIAL@::askfirst:/usr/libexec/login.sh
-tty0::askfirst:/usr/libexec/login.sh
+tty1::askfirst:/usr/libexec/login.sh
hvc0::askfirst:/usr/libexec/login.sh
ttymxc0::askfirst:/usr/libexec/login.sh
ttymxc1::askfirst:/usr/libexec/login.sh
diff --git a/target/linux/armsr/config-6.6 b/target/linux/armsr/config-6.6
index 304602ebbd..2588ccd3b9 100644
--- a/target/linux/armsr/config-6.6
+++ b/target/linux/armsr/config-6.6
@@ -55,6 +55,7 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
# CONFIG_ARM64_ACPI_PARKING_PROTOCOL is not set
+CONFIG_ARM64_ERRATUM_3194386=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
CONFIG_ARM64_PA_BITS=48
diff --git a/target/linux/armsr/image/Makefile b/target/linux/armsr/image/Makefile
index 7d04a2e8f6..66f027c732 100644
--- a/target/linux/armsr/image/Makefile
+++ b/target/linux/armsr/image/Makefile
@@ -12,6 +12,7 @@ GRUB_TERMINAL_CONFIG =
GRUB_CONSOLE_CMDLINE = earlycon
ifneq ($(CONFIG_GRUB_CONSOLE),)
+ GRUB_CONSOLE_CMDLINE += console=tty1
GRUB_TERMINALS += console
endif
diff --git a/target/linux/armsr/modules.mk b/target/linux/armsr/modules.mk
index b793f3ff49..15acfd9e48 100644
--- a/target/linux/armsr/modules.mk
+++ b/target/linux/armsr/modules.mk
@@ -92,7 +92,7 @@ define KernelPackage/fsl-enetc-net
CONFIG_FSL_ENETC_QOS=y
FILES:= \
$(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc.ko \
- $(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc-core.ko@ge6.3 \
+ $(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc-core.ko \
$(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc-vf.ko \
$(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc-mdio.ko \
$(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc-ierb.ko
diff --git a/target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch b/target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch
deleted file mode 100644
index 7c0b4b1920..0000000000
--- a/target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From b77c0ecdc7915e5c5c515da1aa6cfaf6f4eb8351 Mon Sep 17 00:00:00 2001
-From: Mathew McBride <matt@traverse.com.au>
-Date: Wed, 28 Sep 2022 16:39:31 +1000
-Subject: [PATCH] arm: disable code size reduction measures
- (gc-sections,-f*-sections)
-
-This interferes with the EFI boot stub on armv7l.
-
-Signed-off-by: Mathew McBride <matt@traverse.com.au>
----
- arch/arm/Kconfig | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -124,7 +124,6 @@ config ARM
- select HAVE_VIRT_CPU_ACCOUNTING_GEN
- select IRQ_FORCED_THREADING
- select LOCK_MM_AND_FIND_VMA
-- select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
- select MODULES_USE_ELF_REL
- select NEED_DMA_MAP_STATE
- select OF_EARLY_FLATTREE if OF
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch b/target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch
deleted file mode 100644
index ec72f91d0f..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From f3763a0c1b07273218cbf5886bdf8df9df501111 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:10 +0200
-Subject: [PATCH 03/14] net: dpaa2-eth: don't use -ENOTSUPP error code
-
-dpaa2_eth_setup_dpni() is called from the probe path and
-dpaa2_eth_set_link_ksettings() is propagated to user space.
-
-include/linux/errno.h says that ENOTSUPP is "Defined for the NFSv3
-protocol". Conventional wisdom has it to not use it in networking
-drivers. Replace it with -EOPNOTSUPP.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +-
- drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-@@ -3614,7 +3614,7 @@ static int dpaa2_eth_setup_dpni(struct f
- dev_err(dev, "DPNI version %u.%u not supported, need >= %u.%u\n",
- priv->dpni_ver_major, priv->dpni_ver_minor,
- DPNI_VER_MAJOR, DPNI_VER_MINOR);
-- err = -ENOTSUPP;
-+ err = -EOPNOTSUPP;
- goto close;
- }
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
-@@ -118,7 +118,7 @@ dpaa2_eth_set_link_ksettings(struct net_
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-
- if (!dpaa2_eth_is_type_phy(priv))
-- return -ENOTSUPP;
-+ return -EOPNOTSUPP;
-
- return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings);
- }
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch b/target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch
deleted file mode 100644
index 501eaf42ff..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 022a11062261dc4703da846d3bf4d194ef6bebf5 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:11 +0200
-Subject: [PATCH 04/14] net: dpaa2: replace dpaa2_mac_is_type_fixed() with
- dpaa2_mac_is_type_phy()
-
-dpaa2_mac_is_type_fixed() is a header with no implementation and no
-callers, which is referenced from the documentation though. It can be
-deleted.
-
-On the other hand, it would be useful to reuse the code between
-dpaa2_eth_is_type_phy() and dpaa2_switch_port_is_type_phy(). That common
-code should be called dpaa2_mac_is_type_phy(), so let's create that.
-
-The removal and the addition are merged into the same patch because,
-in fact, is_type_phy() is the logical opposite of is_type_fixed().
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../ethernet/freescale/dpaa2/mac-phy-support.rst | 9 ++++++---
- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 7 +------
- drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h | 10 ++++++++--
- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h | 7 +------
- 4 files changed, 16 insertions(+), 17 deletions(-)
-
---- a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst
-+++ b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst
-@@ -181,10 +181,13 @@ when necessary using the below listed AP
- - int dpaa2_mac_connect(struct dpaa2_mac *mac);
- - void dpaa2_mac_disconnect(struct dpaa2_mac *mac);
-
--A phylink integration is necessary only when the partner DPMAC is not of TYPE_FIXED.
--One can check for this condition using the below API::
-+A phylink integration is necessary only when the partner DPMAC is not of
-+``TYPE_FIXED``. This means it is either of ``TYPE_PHY``, or of
-+``TYPE_BACKPLANE`` (the difference being the two that in the ``TYPE_BACKPLANE``
-+mode, the MC firmware does not access the PCS registers). One can check for
-+this condition using the following helper::
-
-- - bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,struct fsl_mc_io *mc_io);
-+ - static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac);
-
- Before connection to a MAC, the caller must allocate and populate the
- dpaa2_mac structure with the associated net_device, a pointer to the MC portal
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
-@@ -733,12 +733,7 @@ static inline unsigned int dpaa2_eth_rx_
-
- static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv)
- {
-- if (priv->mac &&
-- (priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
-- priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE))
-- return true;
--
-- return false;
-+ return dpaa2_mac_is_type_phy(priv->mac);
- }
-
- static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv)
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
-@@ -30,8 +30,14 @@ struct dpaa2_mac {
- struct phy *serdes_phy;
- };
-
--bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,
-- struct fsl_mc_io *mc_io);
-+static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac)
-+{
-+ if (!mac)
-+ return false;
-+
-+ return mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
-+ mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE;
-+}
-
- int dpaa2_mac_open(struct dpaa2_mac *mac);
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
-@@ -230,12 +230,7 @@ static inline bool dpaa2_switch_supports
- static inline bool
- dpaa2_switch_port_is_type_phy(struct ethsw_port_priv *port_priv)
- {
-- if (port_priv->mac &&
-- (port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
-- port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE))
-- return true;
--
-- return false;
-+ return dpaa2_mac_is_type_phy(port_priv->mac);
- }
-
- static inline bool dpaa2_switch_port_has_mac(struct ethsw_port_priv *port_priv)
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch b/target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch
deleted file mode 100644
index af5ff2aea6..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 97c07369ab8bf9895e05d4b468f18e6567263154 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:12 +0200
-Subject: [PATCH 05/14] net: dpaa2-mac: absorb phylink_start() call into
- dpaa2_mac_start()
-
-The phylink handling is intended to be hidden inside the dpaa2_mac
-object. Move the phylink_start() call into dpaa2_mac_start(), and
-phylink_stop() into dpaa2_mac_stop().
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 5 +----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 8 ++++++++
- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 5 +----
- 3 files changed, 10 insertions(+), 8 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-@@ -2083,10 +2083,8 @@ static int dpaa2_eth_open(struct net_dev
- goto enable_err;
- }
-
-- if (dpaa2_eth_is_type_phy(priv)) {
-+ if (dpaa2_eth_is_type_phy(priv))
- dpaa2_mac_start(priv->mac);
-- phylink_start(priv->mac->phylink);
-- }
-
- return 0;
-
-@@ -2160,7 +2158,6 @@ static int dpaa2_eth_stop(struct net_dev
- int retries = 10;
-
- if (dpaa2_eth_is_type_phy(priv)) {
-- phylink_stop(priv->mac->phylink);
- dpaa2_mac_stop(priv->mac);
- } else {
- netif_tx_stop_all_queues(net_dev);
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-@@ -336,12 +336,20 @@ static void dpaa2_mac_set_supported_inte
-
- void dpaa2_mac_start(struct dpaa2_mac *mac)
- {
-+ ASSERT_RTNL();
-+
- if (mac->serdes_phy)
- phy_power_on(mac->serdes_phy);
-+
-+ phylink_start(mac->phylink);
- }
-
- void dpaa2_mac_stop(struct dpaa2_mac *mac)
- {
-+ ASSERT_RTNL();
-+
-+ phylink_stop(mac->phylink);
-+
- if (mac->serdes_phy)
- phy_power_off(mac->serdes_phy);
- }
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-@@ -703,10 +703,8 @@ static int dpaa2_switch_port_open(struct
-
- dpaa2_switch_enable_ctrl_if_napi(ethsw);
-
-- if (dpaa2_switch_port_is_type_phy(port_priv)) {
-+ if (dpaa2_switch_port_is_type_phy(port_priv))
- dpaa2_mac_start(port_priv->mac);
-- phylink_start(port_priv->mac->phylink);
-- }
-
- return 0;
- }
-@@ -718,7 +716,6 @@ static int dpaa2_switch_port_stop(struct
- int err;
-
- if (dpaa2_switch_port_is_type_phy(port_priv)) {
-- phylink_stop(port_priv->mac->phylink);
- dpaa2_mac_stop(port_priv->mac);
- } else {
- netif_tx_stop_all_queues(netdev);
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch b/target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch
deleted file mode 100644
index c3028357fe..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 095ef388f714d622aa503fcccf20dc4095b72762 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:13 +0200
-Subject: [PATCH 06/14] net: dpaa2-mac: remove defensive check in
- dpaa2_mac_disconnect()
-
-dpaa2_mac_disconnect() will only be called with a NULL mac->phylink if
-dpaa2_mac_connect() failed, or was never called.
-
-The callers are these:
-
-dpaa2_eth_disconnect_mac():
-
- if (dpaa2_eth_is_type_phy(priv))
- dpaa2_mac_disconnect(priv->mac);
-
-dpaa2_switch_port_disconnect_mac():
-
- if (dpaa2_switch_port_is_type_phy(port_priv))
- dpaa2_mac_disconnect(port_priv->mac);
-
-priv->mac can be NULL, but in that case, dpaa2_eth_is_type_phy() returns
-false, and dpaa2_mac_disconnect() is never called. Similar for
-dpaa2-switch.
-
-When priv->mac is non-NULL, it means that dpaa2_mac_connect() returned
-zero (success), and therefore, priv->mac->phylink is also a valid
-pointer.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-@@ -446,9 +446,6 @@ err_pcs_destroy:
-
- void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
- {
-- if (!mac->phylink)
-- return;
--
- phylink_disconnect_phy(mac->phylink);
- phylink_destroy(mac->phylink);
- dpaa2_pcs_destroy(mac);
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch b/target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch
deleted file mode 100644
index c31a470182..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 06efc9b8a1360cad83cae6e71558e5458cc1fbf3 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:14 +0200
-Subject: [PATCH 07/14] net: dpaa2-eth: assign priv->mac after
- dpaa2_mac_connect() call
-
-There are 2 requirements for correct code:
-
-- Any time the driver accesses the priv->mac pointer at runtime, it
- either holds NULL to indicate a DPNI-DPNI connection (or unconnected
- DPNI), or a struct dpaa2_mac whose phylink instance was fully
- initialized (created and connected to the PHY). No changes are made to
- priv->mac while it is being used. Currently, rtnl_lock() watches over
- the call to dpaa2_eth_connect_mac(), so it serves the purpose of
- serializing this with all readers of priv->mac.
-
-- dpaa2_mac_connect() should run unlocked, because inside it are 2
- phylink calls with incompatible locking requirements: phylink_create()
- requires that the rtnl_mutex isn't held, and phylink_fwnode_phy_connect()
- requires that the rtnl_mutex is held. The only way to solve those
- contradictory requirements is to let dpaa2_mac_connect() take
- rtnl_lock() when it needs to.
-
-To solve both requirements, we need to identify the writer side of the
-priv->mac pointer, which can be wrapped in a mutex private to the driver
-in a future patch. The dpaa2_mac_connect() cannot be part of the writer
-side critical section, because of an AB/BA deadlock with rtnl_lock().
-
-So the strategy needs to be that where we prepare the DPMAC by calling
-dpaa2_mac_connect(), and only make priv->mac point to it once it's fully
-prepared. This ensures that the writer side critical section has the
-absolute minimum surface it can.
-
-The reverse strategy is adopted in the dpaa2_eth_disconnect_mac() code
-path. This makes sure that priv->mac is NULL when we start tearing down
-the DPMAC that we disconnected from, and concurrent code will simply not
-see it.
-
-No locking changes in this patch (concurrent code is still blocked by
-the rtnl_mutex).
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 21 +++++++++++--------
- 1 file changed, 12 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-@@ -4444,9 +4444,8 @@ static int dpaa2_eth_connect_mac(struct
- err = dpaa2_mac_open(mac);
- if (err)
- goto err_free_mac;
-- priv->mac = mac;
-
-- if (dpaa2_eth_is_type_phy(priv)) {
-+ if (dpaa2_mac_is_type_phy(mac)) {
- err = dpaa2_mac_connect(mac);
- if (err && err != -EPROBE_DEFER)
- netdev_err(priv->net_dev, "Error connecting to the MAC endpoint: %pe",
-@@ -4455,11 +4454,12 @@ static int dpaa2_eth_connect_mac(struct
- goto err_close_mac;
- }
-
-+ priv->mac = mac;
-+
- return 0;
-
- err_close_mac:
- dpaa2_mac_close(mac);
-- priv->mac = NULL;
- err_free_mac:
- kfree(mac);
- return err;
-@@ -4467,15 +4467,18 @@ err_free_mac:
-
- static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
- {
-- if (dpaa2_eth_is_type_phy(priv))
-- dpaa2_mac_disconnect(priv->mac);
-+ struct dpaa2_mac *mac = priv->mac;
-+
-+ priv->mac = NULL;
-
-- if (!dpaa2_eth_has_mac(priv))
-+ if (!mac)
- return;
-
-- dpaa2_mac_close(priv->mac);
-- kfree(priv->mac);
-- priv->mac = NULL;
-+ if (dpaa2_mac_is_type_phy(mac))
-+ dpaa2_mac_disconnect(mac);
-+
-+ dpaa2_mac_close(mac);
-+ kfree(mac);
- }
-
- static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch b/target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch
deleted file mode 100644
index e63654984a..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From a5e7f7e277bd4403c45c1c7922d56d0eb08dbc7c Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:15 +0200
-Subject: [PATCH 08/14] net: dpaa2-switch: assign port_priv->mac after
- dpaa2_mac_connect() call
-
-The dpaa2-switch has the exact same locking requirements when connected
-to a DPMAC, so it needs port_priv->mac to always point either to NULL,
-or to a DPMAC with a fully initialized phylink instance.
-
-Make the same preparatory change in the dpaa2-switch driver as in the
-dpaa2-eth one.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 21 +++++++++++--------
- 1 file changed, 12 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-@@ -1450,9 +1450,8 @@ static int dpaa2_switch_port_connect_mac
- err = dpaa2_mac_open(mac);
- if (err)
- goto err_free_mac;
-- port_priv->mac = mac;
-
-- if (dpaa2_switch_port_is_type_phy(port_priv)) {
-+ if (dpaa2_mac_is_type_phy(mac)) {
- err = dpaa2_mac_connect(mac);
- if (err) {
- netdev_err(port_priv->netdev,
-@@ -1462,11 +1461,12 @@ static int dpaa2_switch_port_connect_mac
- }
- }
-
-+ port_priv->mac = mac;
-+
- return 0;
-
- err_close_mac:
- dpaa2_mac_close(mac);
-- port_priv->mac = NULL;
- err_free_mac:
- kfree(mac);
- return err;
-@@ -1474,15 +1474,18 @@ err_free_mac:
-
- static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
- {
-- if (dpaa2_switch_port_is_type_phy(port_priv))
-- dpaa2_mac_disconnect(port_priv->mac);
-+ struct dpaa2_mac *mac = port_priv->mac;
-+
-+ port_priv->mac = NULL;
-
-- if (!dpaa2_switch_port_has_mac(port_priv))
-+ if (!mac)
- return;
-
-- dpaa2_mac_close(port_priv->mac);
-- kfree(port_priv->mac);
-- port_priv->mac = NULL;
-+ if (dpaa2_mac_is_type_phy(mac))
-+ dpaa2_mac_disconnect(mac);
-+
-+ dpaa2_mac_close(mac);
-+ kfree(mac);
- }
-
- static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch b/target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch
deleted file mode 100644
index c790ba1bd5..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From ce44b6ed9ee65efa9b3025552c513842eabcab88 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:16 +0200
-Subject: [PATCH 09/14] net: dpaa2: publish MAC stringset to ethtool -S even if
- MAC is missing
-
-DPNIs and DPSW objects can connect and disconnect at runtime from DPMAC
-objects on the same fsl-mc bus. The DPMAC object also holds "ethtool -S"
-unstructured counters. Those counters are only shown for the entity
-owning the netdev (DPNI, DPSW) if it's connected to a DPMAC.
-
-The ethtool stringset code path is split into multiple callbacks, but
-currently, connecting and disconnecting the DPMAC takes the rtnl_lock().
-This blocks the entire ethtool code path from running, see
-ethnl_default_doit() -> rtnl_lock() -> ops->prepare_data() ->
-strset_prepare_data().
-
-This is going to be a problem if we are going to no longer require
-rtnl_lock() when connecting/disconnecting the DPMAC, because the DPMAC
-could appear between ops->get_sset_count() and ops->get_strings().
-If it appears out of the blue, we will provide a stringset into an array
-that was dimensioned thinking the DPMAC wouldn't be there => array
-accessed out of bounds.
-
-There isn't really a good way to work around that, and I don't want to
-put too much pressure on the ethtool framework by playing locking games.
-Just make the DPMAC counters be always available. They'll be zeroes if
-the DPNI or DPSW isn't connected to a DPMAC.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 12 +++---------
- .../ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 11 ++---------
- 2 files changed, 5 insertions(+), 18 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
-@@ -186,7 +186,6 @@ static int dpaa2_eth_set_pauseparam(stru
- static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
- u8 *data)
- {
-- struct dpaa2_eth_priv *priv = netdev_priv(netdev);
- u8 *p = data;
- int i;
-
-@@ -200,22 +199,17 @@ static void dpaa2_eth_get_strings(struct
- strscpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-- if (dpaa2_eth_has_mac(priv))
-- dpaa2_mac_get_strings(p);
-+ dpaa2_mac_get_strings(p);
- break;
- }
- }
-
- static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset)
- {
-- int num_ss_stats = DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS;
-- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
--
- switch (sset) {
- case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */
-- if (dpaa2_eth_has_mac(priv))
-- num_ss_stats += dpaa2_mac_get_sset_count();
-- return num_ss_stats;
-+ return DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS +
-+ dpaa2_mac_get_sset_count();
- default:
- return -EOPNOTSUPP;
- }
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
-@@ -145,14 +145,9 @@ dpaa2_switch_set_link_ksettings(struct n
- static int
- dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset)
- {
-- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
-- int num_ss_stats = DPAA2_SWITCH_NUM_COUNTERS;
--
- switch (sset) {
- case ETH_SS_STATS:
-- if (port_priv->mac)
-- num_ss_stats += dpaa2_mac_get_sset_count();
-- return num_ss_stats;
-+ return DPAA2_SWITCH_NUM_COUNTERS + dpaa2_mac_get_sset_count();
- default:
- return -EOPNOTSUPP;
- }
-@@ -161,7 +156,6 @@ dpaa2_switch_ethtool_get_sset_count(stru
- static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev,
- u32 stringset, u8 *data)
- {
-- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- u8 *p = data;
- int i;
-
-@@ -172,8 +166,7 @@ static void dpaa2_switch_ethtool_get_str
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-- if (port_priv->mac)
-- dpaa2_mac_get_strings(p);
-+ dpaa2_mac_get_strings(p);
- break;
- }
- }
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch b/target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch
deleted file mode 100644
index 0663bf6fb1..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From c838d9fd7e6ba9ddd6006bf0a296396266e9f121 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:17 +0200
-Subject: [PATCH 10/14] net: dpaa2-switch replace direct MAC access with
- dpaa2_switch_port_has_mac()
-
-The helper function will gain a lockdep annotation in a future patch.
-Make sure to benefit from it.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
-@@ -189,7 +189,7 @@ static void dpaa2_switch_ethtool_get_sta
- dpaa2_switch_ethtool_counters[i].name, err);
- }
-
-- if (port_priv->mac)
-+ if (dpaa2_switch_port_has_mac(port_priv))
- dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
- }
-
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch b/target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch
deleted file mode 100644
index 4e39e9a0ac..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From e0ea63162cb5f1ca7f844d6ef5fc4079448ee2d5 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:18 +0200
-Subject: [PATCH 11/14] net: dpaa2-eth: connect to MAC before requesting the
- "endpoint changed" IRQ
-
-dpaa2_eth_connect_mac() is called both from dpaa2_eth_probe() and from
-dpni_irq0_handler_thread().
-
-It could happen that the DPNI gets connected to a DPMAC on the fsl-mc
-bus exactly during probe, as soon as the "endpoint change" interrupt is
-requested in dpaa2_eth_setup_irqs(). This will cause the
-dpni_irq0_handler_thread() to register a phylink instance for that DPMAC.
-
-Then, the probing function will also try to register a phylink instance
-for the same DPMAC, operation which should fail (and this will fail the
-probing of the driver).
-
-Reorder dpaa2_eth_setup_irqs() and dpaa2_eth_connect_mac(), such that
-dpni_irq0_handler_thread() never races with the DPMAC-related portion of
-the probing path.
-
-Also reorder dpaa2_eth_disconnect_mac() to be in the mirror position of
-dpaa2_eth_connect_mac() in the teardown path.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-@@ -4711,6 +4711,10 @@ static int dpaa2_eth_probe(struct fsl_mc
- }
- #endif
-
-+ err = dpaa2_eth_connect_mac(priv);
-+ if (err)
-+ goto err_connect_mac;
-+
- err = dpaa2_eth_setup_irqs(dpni_dev);
- if (err) {
- netdev_warn(net_dev, "Failed to set link interrupt, fall back to polling\n");
-@@ -4723,10 +4727,6 @@ static int dpaa2_eth_probe(struct fsl_mc
- priv->do_link_poll = true;
- }
-
-- err = dpaa2_eth_connect_mac(priv);
-- if (err)
-- goto err_connect_mac;
--
- err = dpaa2_eth_dl_alloc(priv);
- if (err)
- goto err_dl_register;
-@@ -4762,13 +4762,13 @@ err_dl_port_add:
- err_dl_trap_register:
- dpaa2_eth_dl_free(priv);
- err_dl_register:
-- dpaa2_eth_disconnect_mac(priv);
--err_connect_mac:
- if (priv->do_link_poll)
- kthread_stop(priv->poll_thread);
- else
- fsl_mc_free_irqs(dpni_dev);
- err_poll_thread:
-+ dpaa2_eth_disconnect_mac(priv);
-+err_connect_mac:
- dpaa2_eth_free_rings(priv);
- err_alloc_rings:
- err_csum:
-@@ -4816,9 +4816,6 @@ static int dpaa2_eth_remove(struct fsl_m
- #endif
-
- unregister_netdev(net_dev);
-- rtnl_lock();
-- dpaa2_eth_disconnect_mac(priv);
-- rtnl_unlock();
-
- dpaa2_eth_dl_port_del(priv);
- dpaa2_eth_dl_traps_unregister(priv);
-@@ -4829,6 +4826,9 @@ static int dpaa2_eth_remove(struct fsl_m
- else
- fsl_mc_free_irqs(ls_dev);
-
-+ rtnl_lock();
-+ dpaa2_eth_disconnect_mac(priv);
-+ rtnl_unlock();
- dpaa2_eth_free_rings(priv);
- free_percpu(priv->fd);
- free_percpu(priv->sgt_cache);
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch b/target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch
deleted file mode 100644
index 9b068ce8f5..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch
+++ /dev/null
@@ -1,320 +0,0 @@
-From 5e448a17dfa2e95166534df7f677a3694ef6187d Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:19 +0200
-Subject: [PATCH 12/14] net: dpaa2-eth: serialize changes to priv->mac with a
- mutex
-
-The dpaa2 architecture permits dynamic connections between objects on
-the fsl-mc bus, specifically between a DPNI object (represented by a
-struct net_device) and a DPMAC object (represented by a struct phylink).
-
-The DPNI driver is notified when those connections are created/broken
-through the dpni_irq0_handler_thread() method. To ensure that ethtool
-operations, as well as netdev up/down operations serialize with the
-connection/disconnection of the DPNI with a DPMAC,
-dpni_irq0_handler_thread() takes the rtnl_lock() to block those other
-operations from taking place.
-
-There is code called by dpaa2_mac_connect() which wants to acquire the
-rtnl_mutex once again, see phylink_create() -> phylink_register_sfp() ->
-sfp_bus_add_upstream() -> rtnl_lock(). So the strategy doesn't quite
-work out, even though it's fairly simple.
-
-Create a different strategy, where all code paths in the dpaa2-eth
-driver access priv->mac only while they are holding priv->mac_lock.
-The phylink instance is not created or connected to the PHY under the
-priv->mac_lock, but only assigned to priv->mac then. This will eliminate
-the reliance on the rtnl_mutex.
-
-Add lockdep annotations and put comments where holding the lock is not
-necessary, and priv->mac can be dereferenced freely.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 ++++++++++++--
- .../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 6 ++
- .../ethernet/freescale/dpaa2/dpaa2-ethtool.c | 58 +++++++++++++++----
- 3 files changed, 91 insertions(+), 16 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-@@ -2021,8 +2021,11 @@ static int dpaa2_eth_link_state_update(s
-
- /* When we manage the MAC/PHY using phylink there is no need
- * to manually update the netif_carrier.
-+ * We can avoid locking because we are called from the "link changed"
-+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler
-+ * (the writer to priv->mac), so we cannot race with it.
- */
-- if (dpaa2_eth_is_type_phy(priv))
-+ if (dpaa2_mac_is_type_phy(priv->mac))
- goto out;
-
- /* Chech link state; speed / duplex changes are not treated yet */
-@@ -2061,6 +2064,8 @@ static int dpaa2_eth_open(struct net_dev
- priv->dpbp_dev->obj_desc.id, priv->bpid);
- }
-
-+ mutex_lock(&priv->mac_lock);
-+
- if (!dpaa2_eth_is_type_phy(priv)) {
- /* We'll only start the txqs when the link is actually ready;
- * make sure we don't race against the link up notification,
-@@ -2079,6 +2084,7 @@ static int dpaa2_eth_open(struct net_dev
-
- err = dpni_enable(priv->mc_io, 0, priv->mc_token);
- if (err < 0) {
-+ mutex_unlock(&priv->mac_lock);
- netdev_err(net_dev, "dpni_enable() failed\n");
- goto enable_err;
- }
-@@ -2086,6 +2092,8 @@ static int dpaa2_eth_open(struct net_dev
- if (dpaa2_eth_is_type_phy(priv))
- dpaa2_mac_start(priv->mac);
-
-+ mutex_unlock(&priv->mac_lock);
-+
- return 0;
-
- enable_err:
-@@ -2157,6 +2165,8 @@ static int dpaa2_eth_stop(struct net_dev
- int dpni_enabled = 0;
- int retries = 10;
-
-+ mutex_lock(&priv->mac_lock);
-+
- if (dpaa2_eth_is_type_phy(priv)) {
- dpaa2_mac_stop(priv->mac);
- } else {
-@@ -2164,6 +2174,8 @@ static int dpaa2_eth_stop(struct net_dev
- netif_carrier_off(net_dev);
- }
-
-+ mutex_unlock(&priv->mac_lock);
-+
- /* On dpni_disable(), the MC firmware will:
- * - stop MAC Rx and wait for all Rx frames to be enqueued to software
- * - cut off WRIOP dequeues from egress FQs and wait until transmission
-@@ -2489,12 +2501,20 @@ static int dpaa2_eth_ts_ioctl(struct net
- static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
- {
- struct dpaa2_eth_priv *priv = netdev_priv(dev);
-+ int err;
-
- if (cmd == SIOCSHWTSTAMP)
- return dpaa2_eth_ts_ioctl(dev, rq, cmd);
-
-- if (dpaa2_eth_is_type_phy(priv))
-- return phylink_mii_ioctl(priv->mac->phylink, rq, cmd);
-+ mutex_lock(&priv->mac_lock);
-+
-+ if (dpaa2_eth_is_type_phy(priv)) {
-+ err = phylink_mii_ioctl(priv->mac->phylink, rq, cmd);
-+ mutex_unlock(&priv->mac_lock);
-+ return err;
-+ }
-+
-+ mutex_unlock(&priv->mac_lock);
-
- return -EOPNOTSUPP;
- }
-@@ -4454,7 +4474,9 @@ static int dpaa2_eth_connect_mac(struct
- goto err_close_mac;
- }
-
-+ mutex_lock(&priv->mac_lock);
- priv->mac = mac;
-+ mutex_unlock(&priv->mac_lock);
-
- return 0;
-
-@@ -4467,9 +4489,12 @@ err_free_mac:
-
- static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
- {
-- struct dpaa2_mac *mac = priv->mac;
-+ struct dpaa2_mac *mac;
-
-+ mutex_lock(&priv->mac_lock);
-+ mac = priv->mac;
- priv->mac = NULL;
-+ mutex_unlock(&priv->mac_lock);
-
- if (!mac)
- return;
-@@ -4488,6 +4513,7 @@ static irqreturn_t dpni_irq0_handler_thr
- struct fsl_mc_device *dpni_dev = to_fsl_mc_device(dev);
- struct net_device *net_dev = dev_get_drvdata(dev);
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ bool had_mac;
- int err;
-
- err = dpni_get_irq_status(dpni_dev->mc_io, 0, dpni_dev->mc_handle,
-@@ -4505,7 +4531,12 @@ static irqreturn_t dpni_irq0_handler_thr
- dpaa2_eth_update_tx_fqids(priv);
-
- rtnl_lock();
-- if (dpaa2_eth_has_mac(priv))
-+ /* We can avoid locking because the "endpoint changed" IRQ
-+ * handler is the only one who changes priv->mac at runtime,
-+ * so we are not racing with anyone.
-+ */
-+ had_mac = !!priv->mac;
-+ if (had_mac)
- dpaa2_eth_disconnect_mac(priv);
- else
- dpaa2_eth_connect_mac(priv);
-@@ -4606,6 +4637,8 @@ static int dpaa2_eth_probe(struct fsl_mc
- priv = netdev_priv(net_dev);
- priv->net_dev = net_dev;
-
-+ mutex_init(&priv->mac_lock);
-+
- priv->iommu_domain = iommu_get_domain_for_dev(dev);
-
- priv->tx_tstamp_type = HWTSTAMP_TX_OFF;
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
-@@ -580,6 +580,8 @@ struct dpaa2_eth_priv {
- #endif
-
- struct dpaa2_mac *mac;
-+ /* Serializes changes to priv->mac */
-+ struct mutex mac_lock;
- struct workqueue_struct *dpaa2_ptp_wq;
- struct work_struct tx_onestep_tstamp;
- struct sk_buff_head tx_skbs;
-@@ -733,11 +735,15 @@ static inline unsigned int dpaa2_eth_rx_
-
- static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv)
- {
-+ lockdep_assert_held(&priv->mac_lock);
-+
- return dpaa2_mac_is_type_phy(priv->mac);
- }
-
- static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv)
- {
-+ lockdep_assert_held(&priv->mac_lock);
-+
- return priv->mac ? true : false;
- }
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
-@@ -86,11 +86,16 @@ static void dpaa2_eth_get_drvinfo(struct
- static int dpaa2_eth_nway_reset(struct net_device *net_dev)
- {
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ int err = -EOPNOTSUPP;
-+
-+ mutex_lock(&priv->mac_lock);
-
- if (dpaa2_eth_is_type_phy(priv))
-- return phylink_ethtool_nway_reset(priv->mac->phylink);
-+ err = phylink_ethtool_nway_reset(priv->mac->phylink);
-+
-+ mutex_unlock(&priv->mac_lock);
-
-- return -EOPNOTSUPP;
-+ return err;
- }
-
- static int
-@@ -98,10 +103,18 @@ dpaa2_eth_get_link_ksettings(struct net_
- struct ethtool_link_ksettings *link_settings)
- {
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ int err;
-
-- if (dpaa2_eth_is_type_phy(priv))
-- return phylink_ethtool_ksettings_get(priv->mac->phylink,
-- link_settings);
-+ mutex_lock(&priv->mac_lock);
-+
-+ if (dpaa2_eth_is_type_phy(priv)) {
-+ err = phylink_ethtool_ksettings_get(priv->mac->phylink,
-+ link_settings);
-+ mutex_unlock(&priv->mac_lock);
-+ return err;
-+ }
-+
-+ mutex_unlock(&priv->mac_lock);
-
- link_settings->base.autoneg = AUTONEG_DISABLE;
- if (!(priv->link_state.options & DPNI_LINK_OPT_HALF_DUPLEX))
-@@ -116,11 +129,17 @@ dpaa2_eth_set_link_ksettings(struct net_
- const struct ethtool_link_ksettings *link_settings)
- {
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ int err = -EOPNOTSUPP;
-
-- if (!dpaa2_eth_is_type_phy(priv))
-- return -EOPNOTSUPP;
-+ mutex_lock(&priv->mac_lock);
-+
-+ if (dpaa2_eth_is_type_phy(priv))
-+ err = phylink_ethtool_ksettings_set(priv->mac->phylink,
-+ link_settings);
-
-- return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings);
-+ mutex_unlock(&priv->mac_lock);
-+
-+ return err;
- }
-
- static void dpaa2_eth_get_pauseparam(struct net_device *net_dev,
-@@ -129,11 +148,16 @@ static void dpaa2_eth_get_pauseparam(str
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
- u64 link_options = priv->link_state.options;
-
-+ mutex_lock(&priv->mac_lock);
-+
- if (dpaa2_eth_is_type_phy(priv)) {
- phylink_ethtool_get_pauseparam(priv->mac->phylink, pause);
-+ mutex_unlock(&priv->mac_lock);
- return;
- }
-
-+ mutex_unlock(&priv->mac_lock);
-+
- pause->rx_pause = dpaa2_eth_rx_pause_enabled(link_options);
- pause->tx_pause = dpaa2_eth_tx_pause_enabled(link_options);
- pause->autoneg = AUTONEG_DISABLE;
-@@ -152,9 +176,17 @@ static int dpaa2_eth_set_pauseparam(stru
- return -EOPNOTSUPP;
- }
-
-- if (dpaa2_eth_is_type_phy(priv))
-- return phylink_ethtool_set_pauseparam(priv->mac->phylink,
-- pause);
-+ mutex_lock(&priv->mac_lock);
-+
-+ if (dpaa2_eth_is_type_phy(priv)) {
-+ err = phylink_ethtool_set_pauseparam(priv->mac->phylink,
-+ pause);
-+ mutex_unlock(&priv->mac_lock);
-+ return err;
-+ }
-+
-+ mutex_unlock(&priv->mac_lock);
-+
- if (pause->autoneg)
- return -EOPNOTSUPP;
-
-@@ -307,8 +339,12 @@ static void dpaa2_eth_get_ethtool_stats(
- }
- *(data + i++) = buf_cnt;
-
-+ mutex_lock(&priv->mac_lock);
-+
- if (dpaa2_eth_has_mac(priv))
- dpaa2_mac_get_ethtool_stats(priv->mac, data + i);
-+
-+ mutex_unlock(&priv->mac_lock);
- }
-
- static int dpaa2_eth_prep_eth_rule(struct ethhdr *eth_value, struct ethhdr *eth_mask,
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch b/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch
deleted file mode 100644
index 9d6f5c52dc..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 80d12452a5f160c39d63efc1be07df36f9d07133 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:20 +0200
-Subject: [PATCH 13/14] net: dpaa2-switch: serialize changes to priv->mac with
- a mutex
-
-The dpaa2-switch driver uses a DPMAC in the same way as the dpaa2-eth
-driver, so we need to duplicate the locking solution established by the
-previous change to the switch driver as well.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../freescale/dpaa2/dpaa2-switch-ethtool.c | 32 +++++++++++++++----
- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 31 ++++++++++++++++--
- .../ethernet/freescale/dpaa2/dpaa2-switch.h | 2 ++
- 3 files changed, 55 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
-@@ -60,11 +60,18 @@ dpaa2_switch_get_link_ksettings(struct n
- {
- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- struct dpsw_link_state state = {0};
-- int err = 0;
-+ int err;
-
-- if (dpaa2_switch_port_is_type_phy(port_priv))
-- return phylink_ethtool_ksettings_get(port_priv->mac->phylink,
-- link_ksettings);
-+ mutex_lock(&port_priv->mac_lock);
-+
-+ if (dpaa2_switch_port_is_type_phy(port_priv)) {
-+ err = phylink_ethtool_ksettings_get(port_priv->mac->phylink,
-+ link_ksettings);
-+ mutex_unlock(&port_priv->mac_lock);
-+ return err;
-+ }
-+
-+ mutex_unlock(&port_priv->mac_lock);
-
- err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
- port_priv->ethsw_data->dpsw_handle,
-@@ -99,9 +106,16 @@ dpaa2_switch_set_link_ksettings(struct n
- bool if_running;
- int err = 0, ret;
-
-- if (dpaa2_switch_port_is_type_phy(port_priv))
-- return phylink_ethtool_ksettings_set(port_priv->mac->phylink,
-- link_ksettings);
-+ mutex_lock(&port_priv->mac_lock);
-+
-+ if (dpaa2_switch_port_is_type_phy(port_priv)) {
-+ err = phylink_ethtool_ksettings_set(port_priv->mac->phylink,
-+ link_ksettings);
-+ mutex_unlock(&port_priv->mac_lock);
-+ return err;
-+ }
-+
-+ mutex_unlock(&port_priv->mac_lock);
-
- /* Interface needs to be down to change link settings */
- if_running = netif_running(netdev);
-@@ -189,8 +203,12 @@ static void dpaa2_switch_ethtool_get_sta
- dpaa2_switch_ethtool_counters[i].name, err);
- }
-
-+ mutex_lock(&port_priv->mac_lock);
-+
- if (dpaa2_switch_port_has_mac(port_priv))
- dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
-+
-+ mutex_unlock(&port_priv->mac_lock);
- }
-
- const struct ethtool_ops dpaa2_switch_port_ethtool_ops = {
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-@@ -603,8 +603,11 @@ static int dpaa2_switch_port_link_state_
-
- /* When we manage the MAC/PHY using phylink there is no need
- * to manually update the netif_carrier.
-+ * We can avoid locking because we are called from the "link changed"
-+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler
-+ * (the writer to port_priv->mac), so we cannot race with it.
- */
-- if (dpaa2_switch_port_is_type_phy(port_priv))
-+ if (dpaa2_mac_is_type_phy(port_priv->mac))
- return 0;
-
- /* Interrupts are received even though no one issued an 'ifconfig up'
-@@ -684,6 +687,8 @@ static int dpaa2_switch_port_open(struct
- struct ethsw_core *ethsw = port_priv->ethsw_data;
- int err;
-
-+ mutex_lock(&port_priv->mac_lock);
-+
- if (!dpaa2_switch_port_is_type_phy(port_priv)) {
- /* Explicitly set carrier off, otherwise
- * netif_carrier_ok() will return true and cause 'ip link show'
-@@ -697,6 +702,7 @@ static int dpaa2_switch_port_open(struct
- port_priv->ethsw_data->dpsw_handle,
- port_priv->idx);
- if (err) {
-+ mutex_unlock(&port_priv->mac_lock);
- netdev_err(netdev, "dpsw_if_enable err %d\n", err);
- return err;
- }
-@@ -706,6 +712,8 @@ static int dpaa2_switch_port_open(struct
- if (dpaa2_switch_port_is_type_phy(port_priv))
- dpaa2_mac_start(port_priv->mac);
-
-+ mutex_unlock(&port_priv->mac_lock);
-+
- return 0;
- }
-
-@@ -715,6 +723,8 @@ static int dpaa2_switch_port_stop(struct
- struct ethsw_core *ethsw = port_priv->ethsw_data;
- int err;
-
-+ mutex_lock(&port_priv->mac_lock);
-+
- if (dpaa2_switch_port_is_type_phy(port_priv)) {
- dpaa2_mac_stop(port_priv->mac);
- } else {
-@@ -722,6 +732,8 @@ static int dpaa2_switch_port_stop(struct
- netif_carrier_off(netdev);
- }
-
-+ mutex_unlock(&port_priv->mac_lock);
-+
- err = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
- port_priv->ethsw_data->dpsw_handle,
- port_priv->idx);
-@@ -1461,7 +1473,9 @@ static int dpaa2_switch_port_connect_mac
- }
- }
-
-+ mutex_lock(&port_priv->mac_lock);
- port_priv->mac = mac;
-+ mutex_unlock(&port_priv->mac_lock);
-
- return 0;
-
-@@ -1474,9 +1488,12 @@ err_free_mac:
-
- static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
- {
-- struct dpaa2_mac *mac = port_priv->mac;
-+ struct dpaa2_mac *mac;
-
-+ mutex_lock(&port_priv->mac_lock);
-+ mac = port_priv->mac;
- port_priv->mac = NULL;
-+ mutex_unlock(&port_priv->mac_lock);
-
- if (!mac)
- return;
-@@ -1495,6 +1512,7 @@ static irqreturn_t dpaa2_switch_irq0_han
- struct ethsw_port_priv *port_priv;
- u32 status = ~0;
- int err, if_id;
-+ bool had_mac;
-
- err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
- DPSW_IRQ_INDEX_IF, &status);
-@@ -1513,7 +1531,12 @@ static irqreturn_t dpaa2_switch_irq0_han
-
- if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
- rtnl_lock();
-- if (dpaa2_switch_port_has_mac(port_priv))
-+ /* We can avoid locking because the "endpoint changed" IRQ
-+ * handler is the only one who changes priv->mac at runtime,
-+ * so we are not racing with anyone.
-+ */
-+ had_mac = !!port_priv->mac;
-+ if (had_mac)
- dpaa2_switch_port_disconnect_mac(port_priv);
- else
- dpaa2_switch_port_connect_mac(port_priv);
-@@ -3249,6 +3272,8 @@ static int dpaa2_switch_probe_port(struc
- port_priv->netdev = port_netdev;
- port_priv->ethsw_data = ethsw;
-
-+ mutex_init(&port_priv->mac_lock);
-+
- port_priv->idx = port_idx;
- port_priv->stp_state = BR_STATE_FORWARDING;
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
-@@ -161,6 +161,8 @@ struct ethsw_port_priv {
-
- struct dpaa2_switch_filter_block *filter_block;
- struct dpaa2_mac *mac;
-+ /* Protects against changes to port_priv->mac */
-+ struct mutex mac_lock;
- };
-
- /* Switch data */
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch b/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch
deleted file mode 100644
index 521c9d4a54..0000000000
--- a/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 4ea2faf5bb13d9ba9f07e996d495c4cbe34a4236 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 29 Nov 2022 16:12:21 +0200
-Subject: [PATCH 14/14] net: dpaa2-mac: move rtnl_lock() only around
- phylink_{,dis}connect_phy()
-
-After the introduction of a private mac_lock that serializes access to
-priv->mac (and port_priv->mac in the switch), the only remaining purpose
-of rtnl_lock() is to satisfy the locking requirements of
-phylink_fwnode_phy_connect() and phylink_disconnect_phy().
-
-But the functions these live in, dpaa2_mac_connect() and
-dpaa2_mac_disconnect(), have contradictory locking requirements.
-While phylink_fwnode_phy_connect() wants rtnl_lock() to be held,
-phylink_create() wants it to not be held.
-
-Move the rtnl_lock() from top-level (in the dpaa2-eth and dpaa2-switch
-drivers) to only surround the phylink calls that require it, in the
-dpaa2-mac library code.
-
-This is possible because dpaa2_mac_connect() and dpaa2_mac_disconnect()
-run unlocked, and there isn't any danger of an AB/BA deadlock between
-the rtnl_mutex and other private locks.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 5 +++++
- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 4 ----
- 3 files changed, 5 insertions(+), 8 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
-@@ -4530,7 +4530,6 @@ static irqreturn_t dpni_irq0_handler_thr
- dpaa2_eth_set_mac_addr(netdev_priv(net_dev));
- dpaa2_eth_update_tx_fqids(priv);
-
-- rtnl_lock();
- /* We can avoid locking because the "endpoint changed" IRQ
- * handler is the only one who changes priv->mac at runtime,
- * so we are not racing with anyone.
-@@ -4540,7 +4539,6 @@ static irqreturn_t dpni_irq0_handler_thr
- dpaa2_eth_disconnect_mac(priv);
- else
- dpaa2_eth_connect_mac(priv);
-- rtnl_unlock();
- }
-
- return IRQ_HANDLED;
-@@ -4859,9 +4857,7 @@ static int dpaa2_eth_remove(struct fsl_m
- else
- fsl_mc_free_irqs(ls_dev);
-
-- rtnl_lock();
- dpaa2_eth_disconnect_mac(priv);
-- rtnl_unlock();
- dpaa2_eth_free_rings(priv);
- free_percpu(priv->fd);
- free_percpu(priv->sgt_cache);
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-@@ -428,7 +428,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *
- }
- mac->phylink = phylink;
-
-+ rtnl_lock();
- err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
-+ rtnl_unlock();
- if (err) {
- netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
- goto err_phylink_destroy;
-@@ -446,7 +448,10 @@ err_pcs_destroy:
-
- void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
- {
-+ rtnl_lock();
- phylink_disconnect_phy(mac->phylink);
-+ rtnl_unlock();
-+
- phylink_destroy(mac->phylink);
- dpaa2_pcs_destroy(mac);
- of_phy_put(mac->serdes_phy);
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
-@@ -1530,7 +1530,6 @@ static irqreturn_t dpaa2_switch_irq0_han
- }
-
- if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
-- rtnl_lock();
- /* We can avoid locking because the "endpoint changed" IRQ
- * handler is the only one who changes priv->mac at runtime,
- * so we are not racing with anyone.
-@@ -1540,7 +1539,6 @@ static irqreturn_t dpaa2_switch_irq0_han
- dpaa2_switch_port_disconnect_mac(port_priv);
- else
- dpaa2_switch_port_connect_mac(port_priv);
-- rtnl_unlock();
- }
-
- out:
-@@ -2951,9 +2949,7 @@ static void dpaa2_switch_remove_port(str
- {
- struct ethsw_port_priv *port_priv = ethsw->ports[port_idx];
-
-- rtnl_lock();
- dpaa2_switch_port_disconnect_mac(port_priv);
-- rtnl_unlock();
- free_netdev(port_priv->netdev);
- ethsw->ports[port_idx] = NULL;
- }
diff --git a/target/linux/at91/Makefile b/target/linux/at91/Makefile
index d02a32071b..8fd4a01834 100644
--- a/target/linux/at91/Makefile
+++ b/target/linux/at91/Makefile
@@ -10,7 +10,7 @@ BOARDNAME:=Microchip (Atmel AT91)
FEATURES:=ext4 squashfs targz usbgadget ubifs
SUBTARGETS:=sama7 sama5 sam9x
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/at91/files/arch/arm/boot/dts/at91-q5xr5.dts b/target/linux/at91/files/arch/arm/boot/dts/at91-q5xr5.dts
deleted file mode 100644
index 7de05ee749..0000000000
--- a/target/linux/at91/files/arch/arm/boot/dts/at91-q5xr5.dts
+++ /dev/null
@@ -1,193 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * q5xr5.dts - Device Tree file for Exegin Q5xR5 board
- *
- * Copyright (C) 2014 Owen Kirby <osk@exegin.com>
- */
-
-/dts-v1/;
-#include "at91sam9g20.dtsi"
-
-/ {
- model = "Exegin Q5x (rev5)";
- compatible = "exegin,q5xr5", "atmel,at91sam9g20", "atmel,at91sam9";
-
- chosen {
- bootargs = "console=ttyS0,115200 rootfstype=squashfs,jffs2";
- };
-
- memory {
- reg = <0x20000000 0x0>;
- };
-
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- main_clock: clock@0 {
- compatible = "atmel,osc", "fixed-clock";
- clock-frequency = <18432000>;
- };
-
- slow_xtal {
- clock-frequency = <32768>;
- };
-
- main_xtal {
- clock-frequency = <18432000>;
- };
- };
-
- ahb {
- apb {
- pinctrl@fffff400 {
- board {
- pinctrl_pck0_as_mck: pck0_as_mck {
- atmel,pins = <2 1 0x2 0x0>; /* PC1 periph B */
- };
- pinctrl_spi0_npcs0: spi0_npcs0 {
- atmel,pins = <0 3 0x1 0x0>; /* PA3 periph A */
- };
- pinctrl_spi0_npcs1: spi0_npcs1 {
- atmel,pins = <2 11 0x2 0x0>; /* PC11 periph B */
- };
- pinctrl_spi1_npcs0: spi1_npcs0 {
- atmel,pins = <1 3 0x1 0x0>; /* PB3 periph A */
- };
- pinctrl_spi1_npcs1: spi1_npcs1 {
- atmel,pins = <2 5 0x2 0x0>; /* PC5 periph B */
- };
- };
-
- spi0 {
- pinctrl_spi0: spi0-0 {
- atmel,pins =
- <0 0 0x1 0x0 /* PA0 periph A SPI0_MISO pin */
- 0 1 0x1 0x0 /* PA1 periph A SPI0_MOSI pin */
- 0 2 0x1 0x0>; /* PA2 periph A SPI0_SPCK pin */
- };
- };
-
- spi1 {
- pinctrl_spi1: spi1-0 {
- atmel,pins =
- <1 0 0x1 0x0 /* PB0 periph A SPI1_MISO pin */
- 1 1 0x1 0x0 /* PB1 periph A SPI1_MOSI pin */
- 1 2 0x1 0x0>; /* PB2 periph A SPI1_SPCK pin */
- };
- };
- };
-
- dbgu: serial@fffff200 {
- status = "okay";
- };
-
- usart0: serial@fffb0000 {
- pinctrl-0 =
- <&pinctrl_usart0
- &pinctrl_usart0_rts
- &pinctrl_usart0_cts
- &pinctrl_usart0_dtr_dsr
- &pinctrl_usart0_dcd
- &pinctrl_usart0_ri>;
- status = "okay";
- };
-
- macb0: ethernet@fffc4000 {
- phy-mode = "mii";
- status = "okay";
- };
-
- usb1: gadget@fffa4000 {
- status = "okay";
- };
-
- watchdog@fffffd40 {
- status = "okay";
- };
-
- spi0: spi@fffc8000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "atmel,at91rm9200-spi";
- reg = <0xfffc8000 0x200>;
- interrupts = <12 4 3>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_spi0>;
- status = "okay";
- cs-gpios = <&pioA 3 0>, <&pioC 11 1>, <0>, <0>;
-
- m25p80@0 {
- compatible = "sst,sst25vf040b";
- spi-max-frequency = <20000000>;
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- at91boot@0 {
- label = "at91boot";
- reg = <0x0 0x4000>;
- };
- uenv@4000 {
- label = "uboot-env";
- reg = <0x4000 0x4000>;
- };
- uboot@8000 {
- label = "uboot";
- reg = <0x8000 0x3E000>;
- };
- };
- spidev@1 {
- compatible = "spidev";
- spi-max-frequency = <2000000>;
- reg = <1>;
- };
- };
- spi1: spi@fffcc000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "atmel,at91rm9200-spi";
- reg = <0xfffcc000 0x200>;
- interrupts = <13 4 3>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_spi1>;
- cs-gpios = <&pioB 3 0>, <&pioC 5 1>, <0>, <0>;
- status = "okay";
-
- spidev@0 {
- compatible = "spidev";
- spi-max-frequency = <2000000>;
- reg = <0>;
- };
- spidev@1 {
- compatible = "spidev";
- spi-max-frequency = <2000000>;
- reg = <1>;
- };
- };
- };
-
- usb0: ohci@500000 {
- num-ports = <2>;
- status = "okay";
- };
- };
-
- flash@10000000 {
- compatible = "cfi-flash";
- bank-width = <2>;
- reg = <0x10000000 0x00800000>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- kernel@0 {
- label = "kernel";
- reg = <0x0 0x200000>;
- };
- rootfs@200000 {
- label = "rootfs";
- reg = <0x200000 0x600000>;
- };
- };
-};
diff --git a/target/linux/at91/files/arch/arm/boot/dts/lmu5000.dts b/target/linux/at91/files/arch/arm/boot/dts/lmu5000.dts
deleted file mode 100644
index d9d7da619a..0000000000
--- a/target/linux/at91/files/arch/arm/boot/dts/lmu5000.dts
+++ /dev/null
@@ -1,124 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * lmu5000.dst - Device Tree file for CalAmp LMU5000 board
- *
- * Copyright (C) 2013 Adam Porter <porter.adam@gmail.com>
- */
-
-/dts-v1/;
-#include "at91sam9g20.dtsi"
-
-/ {
- model = "CalAmp LMU5000";
- compatible = "calamp,lmu5000", "atmel,at91sam9g20", "atmel,at91sam9";
-
- chosen {
- bootargs = "mem=64M console=ttyS0,115200 rootfstype=jffs2";
- };
-
- memory {
- reg = <0x20000000 0x4000000>;
- };
-
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- main_clock: clock@0 {
- compatible = "atmel,osc", "fixed-clock";
- clock-frequency = <18432000>;
- };
- };
-
- ahb {
- apb {
- pinctrl@fffff400 {
- board {
- pinctrl_pck0_as_mck: pck0_as_mck {
- atmel,pins =
- <2 1 0x2 0x0>; /* PC1 periph B */
- };
- };
- };
-
- dbgu: serial@fffff200 {
- status = "okay";
- };
-
- usart0: serial@fffb0000 {
- pinctrl-0 =
- <&pinctrl_usart0
- &pinctrl_usart0_rts
- &pinctrl_usart0_cts
- &pinctrl_usart0_dtr_dsr
- &pinctrl_usart0_dcd
- &pinctrl_usart0_ri>;
- status = "okay";
- };
-
- usart2: serial@fffb8000 {
- status = "okay";
- };
-
- uart0: serial@fffd4000 {
- status = "okay";
- };
-
- uart1: serial@fffd8000 {
- status = "okay";
- };
-
- macb0: ethernet@fffc4000 {
- phy-mode = "mii";
- status = "okay";
- };
-
- usb1: gadget@fffa4000 {
- atmel,vbus-gpio = <&pioC 5 0>;
- status = "okay";
- };
-
- ssc0: ssc@fffbc000 {
- status = "okay";
- pinctrl-0 = <&pinctrl_ssc0_tx>;
- };
-
- watchdog@fffffd40 {
- status = "okay";
- };
- };
-
- nand0: nand@40000000 {
- nand-bus-width = <8>;
- nand-ecc-mode = "soft";
- nand-on-flash-bbt;
- status = "okay";
-
- kernel@0 {
- label = "kernel";
- reg = <0x0 0x400000>;
- };
-
- rootfs@400000 {
- label = "rootfs";
- reg = <0x400000 0x3C00000>;
- };
-
- user1@4000000 {
- label = "user1";
- reg = <0x4000000 0x2000000>;
- };
-
- user2@6000000 {
- label = "user2";
- reg = <0x6000000 0x2000000>;
- };
- };
-
- usb0: ohci@500000 {
- num-ports = <2>;
- status = "okay";
- };
- };
-};
diff --git a/target/linux/at91/image/Makefile b/target/linux/at91/image/Makefile
index e17e4d6a52..b825a41247 100644
--- a/target/linux/at91/image/Makefile
+++ b/target/linux/at91/image/Makefile
@@ -19,6 +19,7 @@ FAT32_BLOCKS:=$(shell echo \
$$(($(AT91_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE))))
define Device/Default
+ DEVICE_DTS_DIR := $(DTS_DIR)/microchip
$(Device/default-nand)
PROFILES := Default
FILESYSTEMS := squashfs ubifs ext4
diff --git a/target/linux/at91/image/sam9x.mk b/target/linux/at91/image/sam9x.mk
index 409e43ca6e..d0722c5d30 100644
--- a/target/linux/at91/image/sam9x.mk
+++ b/target/linux/at91/image/sam9x.mk
@@ -125,6 +125,7 @@ define Device/calamp_lmu5000
$(Device/production)
DEVICE_VENDOR := CalAmp
DEVICE_MODEL := LMU5000
+ DEVICE_DTS := at91-lmu5000
DEVICE_PACKAGES := kmod-rtc-pcf2123 kmod-usb-acm \
kmod-usb-serial-option kmod-usb-serial-sierrawireless \
kmod-pinctrl-mcp23s08-spi
diff --git a/target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch b/target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch
deleted file mode 100644
index 874e33059a..0000000000
--- a/target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 5d8ae2928f71f0f9c2c3f8f13d00ecec35649ad3 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Thu, 15 Dec 2022 17:42:54 +0100
-Subject: [PATCH] pinctrl: at91: convert to NOIRQ_SYSTEM_SLEEP_PM_OPS
-
-With the old SET_NOIRQ_SYSTEM_SLEEP_PM_OPS, some configs result in a
-build warning:
-
-drivers/pinctrl/pinctrl-at91.c:1668:12: error: 'at91_gpio_resume' defined but not used [-Werror=unused-function]
- 1668 | static int at91_gpio_resume(struct device *dev)
- | ^~~~~~~~~~~~~~~~
-drivers/pinctrl/pinctrl-at91.c:1650:12: error: 'at91_gpio_suspend' defined but not used [-Werror=unused-function]
- 1650 | static int at91_gpio_suspend(struct device *dev)
- | ^~~~~~~~~~~~~~~~~
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Reviewed-by: Ryan Wanner <Ryan.Wanner@microchip.com>
-Link: https://lore.kernel.org/r/20221215164301.934805-1-arnd@kernel.org
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-at91.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-at91.c
-+++ b/drivers/pinctrl/pinctrl-at91.c
-@@ -1921,7 +1921,7 @@ err:
- }
-
- static const struct dev_pm_ops at91_gpio_pm_ops = {
-- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(at91_gpio_suspend, at91_gpio_resume)
-+ NOIRQ_SYSTEM_SLEEP_PM_OPS(at91_gpio_suspend, at91_gpio_resume)
- };
-
- static struct platform_driver at91_gpio_driver = {
diff --git a/target/linux/at91/sam9x/config-6.1 b/target/linux/at91/sam9x/config-6.1
deleted file mode 100644
index ac4d7cd666..0000000000
--- a/target/linux/at91/sam9x/config-6.1
+++ /dev/null
@@ -1,341 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-# CONFIG_ARCH_MULTI_V4 is not set
-CONFIG_ARCH_MULTI_V4T=y
-CONFIG_ARCH_MULTI_V4_V5=y
-CONFIG_ARCH_MULTI_V5=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_L1_CACHE_SHIFT=5
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-# CONFIG_AT91RM9200_WATCHDOG is not set
-CONFIG_AT91SAM9X_WATCHDOG=y
-# CONFIG_AT91_ADC is not set
-CONFIG_AT91_SAMA5D2_ADC=y
-CONFIG_AT91_SOC_ID=y
-# CONFIG_AT91_SOC_SFR is not set
-CONFIG_ATMEL_AIC5_IRQ=y
-CONFIG_ATMEL_AIC_IRQ=y
-CONFIG_ATMEL_CLOCKSOURCE_PIT=y
-CONFIG_ATMEL_CLOCKSOURCE_TCB=y
-CONFIG_ATMEL_EBI=y
-CONFIG_ATMEL_PIT=y
-CONFIG_ATMEL_PM=y
-CONFIG_ATMEL_SDRAMC=y
-CONFIG_ATMEL_SSC=y
-CONFIG_ATMEL_ST=y
-CONFIG_ATMEL_TCB_CLKSRC=y
-CONFIG_AT_HDMAC=y
-CONFIG_AT_XDMAC=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_PM=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_AT91=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CPU_32v4T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV4T=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_ARM920T=y
-CONFIG_CPU_ARM926T=y
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-CONFIG_CPU_CACHE_V4WT=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_NO_EFFICIENT_FFS=y
-CONFIG_CPU_PABRT_LEGACY=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_USE_DOMAINS=y
-CONFIG_CRC16=y
-CONFIG_CRC7=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DTC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FREEZER=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_CACHE=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_PCI_IOMAP=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_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=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_ATMEL=y
-CONFIG_HZ=128
-CONFIG_HZ_FIXED=128
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_AT91=y
-# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_GPIO=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_TRIGGERED_BUFFER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_PWM=y
-CONFIG_LEDS_TRIGGER_CPU=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACB=y
-CONFIG_MACB_USE_HWSTAMP=y
-# CONFIG_MCHP_EIC is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MFD_AT91_USART=y
-CONFIG_MFD_ATMEL_FLEXCOM=y
-CONFIG_MFD_ATMEL_HLCDC=y
-CONFIG_MFD_ATMEL_SMC=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MICREL_PHY=y
-CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B=y
-CONFIG_MICROCHIP_PIT64B=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_ATMELMCI=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF_AT91=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_DATAFLASH=y
-# CONFIG_MTD_DATAFLASH_OTP is not set
-# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-# CONFIG_MTD_UBI_BLOCK is not set
-CONFIG_MTD_UBI_FASTMAP=y
-CONFIG_MTD_UBI_GLUEBI=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_KUSER_HELPERS=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-# CONFIG_NVMEM_MICROCHIP_OTPC is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_AT91=y
-# CONFIG_PINCTRL_AT91PIO4 is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_SLEEP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_AT91_POWEROFF=y
-CONFIG_POWER_RESET_AT91_RESET=y
-CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_ATMEL=y
-CONFIG_PWM_ATMEL_HLCDC_PWM=y
-CONFIG_PWM_ATMEL_TCB=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_SAMA5D4_WATCHDOG=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_SERIAL_ATMEL_PDC=y
-# CONFIG_SERIAL_ATMEL_TTYAT is not set
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SOC_AT91RM9200=y
-CONFIG_SOC_AT91SAM9=y
-CONFIG_SOC_BUS=y
-CONFIG_SOC_SAM9X60=y
-CONFIG_SOC_SAM_V4_V5=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-# CONFIG_SPI_AT91_USART is not set
-CONFIG_SPI_ATMEL=y
-CONFIG_SPI_ATMEL_QUADSPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_SPIDEV=y
-CONFIG_SPLIT_PTLOCK_CPUS=999999
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWPHY=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UBIFS_FS_ADVANCED_COMPR=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_ACM=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-# CONFIG_USB_AT91 is not set
-# CONFIG_USB_ATMEL_USBA is not set
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_AT91=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_AT91=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_SERIAL=y
-# CONFIG_USB_SERIAL_CONSOLE is not set
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_PL2303=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-# CONFIG_VIDEO_ATMEL_XISC is not set
-# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XXHASH=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/at91/sam9x/config-6.6 b/target/linux/at91/sam9x/config-6.6
new file mode 100644
index 0000000000..d5cfa5f753
--- /dev/null
+++ b/target/linux/at91/sam9x/config-6.6
@@ -0,0 +1,346 @@
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_V4 is not set
+CONFIG_ARCH_MULTI_V4T=y
+CONFIG_ARCH_MULTI_V4_V5=y
+CONFIG_ARCH_MULTI_V5=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_AT91RM9200_WATCHDOG is not set
+CONFIG_AT91SAM9X_WATCHDOG=y
+# CONFIG_AT91_ADC is not set
+CONFIG_AT91_SAMA5D2_ADC=y
+CONFIG_AT91_SOC_ID=y
+# CONFIG_AT91_SOC_SFR is not set
+CONFIG_ATMEL_AIC5_IRQ=y
+CONFIG_ATMEL_AIC_IRQ=y
+CONFIG_ATMEL_CLOCKSOURCE_PIT=y
+CONFIG_ATMEL_CLOCKSOURCE_TCB=y
+CONFIG_ATMEL_EBI=y
+CONFIG_ATMEL_PIT=y
+CONFIG_ATMEL_PM=y
+CONFIG_ATMEL_SSC=y
+CONFIG_ATMEL_ST=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_AT_HDMAC=y
+CONFIG_AT_XDMAC=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_PM=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_AT91=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_ARM926T=y
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_NO_EFFICIENT_FFS=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_USE_DOMAINS=y
+CONFIG_CRC16=y
+CONFIG_CRC7=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FREEZER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_CACHE=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_PCI_IOMAP=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_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_ATMEL=y
+CONFIG_HZ=128
+CONFIG_HZ_FIXED=128
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_GPIO=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACB=y
+CONFIG_MACB_USE_HWSTAMP=y
+# CONFIG_MCHP_EIC is not set
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMORY=y
+CONFIG_MFD_AT91_USART=y
+CONFIG_MFD_ATMEL_FLEXCOM=y
+CONFIG_MFD_ATMEL_HLCDC=y
+CONFIG_MFD_ATMEL_SMC=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MICREL_PHY=y
+CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B=y
+CONFIG_MICROCHIP_PIT64B=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_OF_AT91=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_OTP is not set
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_BLOCK is not set
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_KUSER_HELPERS=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+# CONFIG_NVMEM_MICROCHIP_OTPC is not set
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+# CONFIG_PINCTRL_AT91PIO4 is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_SLEEP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_AT91_POWEROFF=y
+CONFIG_POWER_RESET_AT91_RESET=y
+CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
+CONFIG_PWM_ATMEL_HLCDC_PWM=y
+CONFIG_PWM_ATMEL_TCB=y
+CONFIG_PWM_SYSFS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_SAMA5D4_WATCHDOG=y
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SOC_AT91RM9200=y
+CONFIG_SOC_AT91SAM9=y
+CONFIG_SOC_BUS=y
+CONFIG_SOC_SAM9X60=y
+CONFIG_SOC_SAM_V4_V5=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+# CONFIG_SPI_AT91_USART is not set
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_ATMEL_QUADSPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SRAM=y
+CONFIG_SRAM_EXEC=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWPHY=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_ACM=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+# CONFIG_USB_AT91 is not set
+# CONFIG_USB_ATMEL_USBA is not set
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_AT91=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_AT91=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+# CONFIG_VFP is not set
+# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set
+# CONFIG_VIDEO_MICROCHIP_ISC is not set
+# CONFIG_VIDEO_MICROCHIP_XISC is not set
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XXHASH=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/at91/sama5/config-6.1 b/target/linux/at91/sama5/config-6.1
deleted file mode 100644
index a3168040c2..0000000000
--- a/target/linux/at91/sama5/config-6.1
+++ /dev/null
@@ -1,517 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_AT91_CPUIDLE=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-CONFIG_AT91_ADC=y
-CONFIG_AT91_SAMA5D2_ADC=y
-CONFIG_AT91_SOC_ID=y
-# CONFIG_AT91_SOC_SFR is not set
-CONFIG_ATMEL_AIC5_IRQ=y
-# CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
-CONFIG_ATMEL_CLOCKSOURCE_TCB=y
-CONFIG_ATMEL_EBI=y
-CONFIG_ATMEL_PM=y
-CONFIG_ATMEL_SDRAMC=y
-# CONFIG_ATMEL_SECURE_PM is not set
-CONFIG_ATMEL_SSC=y
-CONFIG_ATMEL_TCB_CLKSRC=y
-CONFIG_AT_HDMAC=y
-CONFIG_AT_XDMAC=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_PWM=y
-CONFIG_BATTERY_ACT8945A=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=4
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_PM=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_AT91=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_COREDUMP=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRASH_CORE=y
-CONFIG_CRASH_DUMP=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_SEQIV=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_USER=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DNOTIFY=y
-CONFIG_DRM=y
-CONFIG_DRM_ATMEL_HLCDC=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_FBDEV_EMULATION=y
-CONFIG_DRM_FBDEV_OVERALLOC=100
-CONFIG_DRM_GEM_DMA_HELPER=y
-CONFIG_DRM_KMS_HELPER=y
-CONFIG_DRM_NOMODESET=y
-CONFIG_DRM_PANEL=y
-CONFIG_DRM_PANEL_BRIDGE=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_DTC=y
-CONFIG_DVB_CORE=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-CONFIG_ELF_CORE=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_FAT_FS=y
-CONFIG_FB=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_CMDLINE=y
-CONFIG_FB_DEFERRED_IO=y
-CONFIG_FB_SYS_COPYAREA=y
-CONFIG_FB_SYS_FILLRECT=y
-CONFIG_FB_SYS_FOPS=y
-CONFIG_FB_SYS_IMAGEBLIT=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FREEZER=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_CACHE=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PINCONF=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_GENERIC_VDSO_32=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-# CONFIG_HARDEN_BRANCH_HISTORY is not set
-# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HDMI=y
-CONFIG_HID=y
-CONFIG_HID_GENERIC=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_ATMEL=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_AT91=y
-# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_GPIO=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_TRIGGERED_BUFFER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_LEDS=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-# CONFIG_JFFS2_FS is not set
-CONFIG_KCMP=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_XZ is not set
-CONFIG_KEXEC=y
-CONFIG_KEXEC_CORE=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_QT1070=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_PWM=y
-CONFIG_LEDS_TRIGGER_CPU=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACB=y
-CONFIG_MACB_USE_HWSTAMP=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_MCHP_EIC is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
-CONFIG_MEDIA_ATTACH=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
-CONFIG_MEDIA_PLATFORM_SUPPORT=y
-CONFIG_MEDIA_RADIO_SUPPORT=y
-CONFIG_MEDIA_SDR_SUPPORT=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_TEST_SUPPORT=y
-CONFIG_MEDIA_TUNER=y
-CONFIG_MEDIA_USB_SUPPORT=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MFD_ACT8945A=y
-CONFIG_MFD_AT91_USART=y
-CONFIG_MFD_ATMEL_FLEXCOM=y
-CONFIG_MFD_ATMEL_HLCDC=y
-CONFIG_MFD_ATMEL_SMC=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MICREL_PHY=y
-# CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B is not set
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_ATMELMCI=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF_AT91=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-# CONFIG_MTD_UBI_BLOCK is not set
-CONFIG_MTD_UBI_FASTMAP=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-# CONFIG_NEON is not set
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-# CONFIG_NVMEM_MICROCHIP_OTPC is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_AT91=y
-CONFIG_PINCTRL_AT91PIO4=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_SLEEP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_AT91_POWEROFF=y
-CONFIG_POWER_RESET_AT91_RESET=y
-CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_VMCORE=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_ATMEL=y
-CONFIG_PWM_ATMEL_HLCDC_PWM=y
-CONFIG_PWM_ATMEL_TCB=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_ACT8865=y
-CONFIG_REGULATOR_ACT8945A=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-# CONFIG_RTC_DRV_AT91SAM9 is not set
-# CONFIG_RTC_DRV_CMOS is not set
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_SAMA5D4_WATCHDOG=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_SERIAL_ATMEL_PDC=y
-# CONFIG_SERIAL_ATMEL_TTYAT is not set
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SND=y
-CONFIG_SND_ARM=y
-# CONFIG_SND_AT73C213 is not set
-# CONFIG_SND_AT91_SOC_SAM9G20_WM8731 is not set
-# CONFIG_SND_AT91_SOC_SAM9X5_WM8731 is not set
-CONFIG_SND_ATMEL_SOC=y
-CONFIG_SND_ATMEL_SOC_CLASSD=y
-CONFIG_SND_ATMEL_SOC_DMA=y
-CONFIG_SND_ATMEL_SOC_I2S=y
-CONFIG_SND_ATMEL_SOC_PDC=y
-# CONFIG_SND_ATMEL_SOC_PDMIC is not set
-CONFIG_SND_ATMEL_SOC_SSC=y
-CONFIG_SND_ATMEL_SOC_SSC_DMA=y
-# CONFIG_SND_ATMEL_SOC_SSC_PDC is not set
-# CONFIG_SND_ATMEL_SOC_TSE850_PCM5142 is not set
-CONFIG_SND_ATMEL_SOC_WM8904=y
-# CONFIG_SND_COMPRESS_OFFLOAD is not set
-CONFIG_SND_DMAENGINE_PCM=y
-CONFIG_SND_JACK=y
-CONFIG_SND_JACK_INPUT_DEV=y
-# CONFIG_SND_MCHP_SOC_I2S_MCC is not set
-# CONFIG_SND_MCHP_SOC_PDMC is not set
-# CONFIG_SND_MCHP_SOC_SPDIFRX is not set
-# CONFIG_SND_MCHP_SOC_SPDIFTX is not set
-CONFIG_SND_PCM=y
-CONFIG_SND_PCM_TIMER=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-CONFIG_SND_SOC_MIKROE_PROTO=y
-CONFIG_SND_SOC_WM8731=y
-CONFIG_SND_SOC_WM8904=y
-CONFIG_SND_SPI=y
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_TIMER=y
-CONFIG_SOC_BUS=y
-# CONFIG_SOC_LAN966 is not set
-CONFIG_SOC_SAMA5=y
-CONFIG_SOC_SAMA5D2=y
-CONFIG_SOC_SAMA5D3=y
-CONFIG_SOC_SAMA5D4=y
-# CONFIG_SOC_SAMA7G5 is not set
-CONFIG_SOC_SAM_V7=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-# CONFIG_SPI_AT91_USART is not set
-CONFIG_SPI_ATMEL=y
-CONFIG_SPI_ATMEL_QUADSPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SQUASHFS is not set
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-# CONFIG_STANDALONE is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWPHY=y
-# CONFIG_SWP_EMULATE is not set
-CONFIG_SYNC_FILE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_TOUCHSCREEN_ATMEL_MXT=y
-CONFIG_UACCESS_WITH_MEMCPY=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_ACM=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-# CONFIG_USB_AT91 is not set
-# CONFIG_USB_ATMEL_USBA is not set
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_AT91=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_HID=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_AT91=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-# CONFIG_USB_PWC is not set
-CONFIG_USB_SERIAL=y
-# CONFIG_USB_SERIAL_CONSOLE is not set
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_PL2303=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_VFAT_FS=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-# CONFIG_VIDEO_ATMEL_XISC is not set
-CONFIG_VIDEOMODE_HELPERS=y
-CONFIG_VIDEO_DEV=y
-# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set
-CONFIG_VIDEO_V4L2_I2C=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XXHASH=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/at91/sama5/config-6.6 b/target/linux/at91/sama5/config-6.6
new file mode 100644
index 0000000000..04eee7a210
--- /dev/null
+++ b/target/linux/at91/sama5/config-6.6
@@ -0,0 +1,524 @@
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM=y
+CONFIG_ARM_AT91_CPUIDLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_AT91_ADC=y
+CONFIG_AT91_SAMA5D2_ADC=y
+CONFIG_AT91_SOC_ID=y
+# CONFIG_AT91_SOC_SFR is not set
+CONFIG_ATMEL_AIC5_IRQ=y
+# CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
+CONFIG_ATMEL_CLOCKSOURCE_TCB=y
+CONFIG_ATMEL_EBI=y
+CONFIG_ATMEL_PM=y
+# CONFIG_ATMEL_SECURE_PM is not set
+CONFIG_ATMEL_SSC=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_AT_HDMAC=y
+CONFIG_AT_XDMAC=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BATTERY_ACT8945A=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_PM=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=16
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SYSFS is not set
+CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_AT91=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_COREDUMP=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRASH_CORE=y
+CONFIG_CRASH_DUMP=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_GENIV=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_USER=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DNOTIFY=y
+CONFIG_DRM=y
+CONFIG_DRM_ATMEL_HLCDC=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_FBDEV_EMULATION=y
+CONFIG_DRM_FBDEV_OVERALLOC=100
+CONFIG_DRM_GEM_DMA_HELPER=y
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DTC=y
+CONFIG_DVB_CORE=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+CONFIG_ELF_CORE=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_FAT_FS=y
+CONFIG_FB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_DEFERRED_IO=y
+CONFIG_FB_DMAMEM_HELPERS=y
+CONFIG_FB_IOMEM_FOPS=y
+CONFIG_FB_SYSMEM_HELPERS=y
+CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FREEZER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_CACHE=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PINCONF=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_GENERIC_VDSO_32=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+# CONFIG_HARDEN_BRANCH_HISTORY is not set
+# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_SMP=y
+CONFIG_HDMI=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_ATMEL=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_LEDS=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+# CONFIG_JFFS2_FS is not set
+CONFIG_KCMP=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_XZ is not set
+CONFIG_KEXEC=y
+CONFIG_KEXEC_CORE=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_QT1070=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEGACY_DIRECT_IO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACB=y
+CONFIG_MACB_USE_HWSTAMP=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_MCHP_EIC is not set
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_RADIO_SUPPORT=y
+CONFIG_MEDIA_SDR_SUPPORT=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_TEST_SUPPORT=y
+CONFIG_MEDIA_TUNER=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_MEMORY=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MFD_ACT8945A=y
+CONFIG_MFD_AT91_USART=y
+CONFIG_MFD_ATMEL_FLEXCOM=y
+CONFIG_MFD_ATMEL_HLCDC=y
+CONFIG_MFD_ATMEL_SMC=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MICREL_PHY=y
+# CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B is not set
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_OF_AT91=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_BLOCK is not set
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_NEON is not set
+CONFIG_NET_EGRESS=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+# CONFIG_NVMEM_MICROCHIP_OTPC is not set
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_PINCTRL_AT91PIO4=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_SLEEP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_AT91_POWEROFF=y
+CONFIG_POWER_RESET_AT91_RESET=y
+CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_VMCORE=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
+CONFIG_PWM_ATMEL_HLCDC_PWM=y
+CONFIG_PWM_ATMEL_TCB=y
+CONFIG_PWM_SYSFS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_ACT8865=y
+CONFIG_REGULATOR_ACT8945A=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91RM9200=y
+# CONFIG_RTC_DRV_AT91SAM9 is not set
+# CONFIG_RTC_DRV_CMOS is not set
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_SAMA5D4_WATCHDOG=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SND=y
+CONFIG_SND_ARM=y
+# CONFIG_SND_AT73C213 is not set
+# CONFIG_SND_AT91_SOC_SAM9G20_WM8731 is not set
+# CONFIG_SND_AT91_SOC_SAM9X5_WM8731 is not set
+CONFIG_SND_ATMEL_SOC=y
+CONFIG_SND_ATMEL_SOC_CLASSD=y
+CONFIG_SND_ATMEL_SOC_DMA=y
+CONFIG_SND_ATMEL_SOC_I2S=y
+CONFIG_SND_ATMEL_SOC_PDC=y
+# CONFIG_SND_ATMEL_SOC_PDMIC is not set
+CONFIG_SND_ATMEL_SOC_SSC=y
+CONFIG_SND_ATMEL_SOC_SSC_DMA=y
+# CONFIG_SND_ATMEL_SOC_SSC_PDC is not set
+# CONFIG_SND_ATMEL_SOC_TSE850_PCM5142 is not set
+CONFIG_SND_ATMEL_SOC_WM8904=y
+# CONFIG_SND_COMPRESS_OFFLOAD is not set
+CONFIG_SND_DMAENGINE_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_JACK_INPUT_DEV=y
+# CONFIG_SND_MCHP_SOC_I2S_MCC is not set
+# CONFIG_SND_MCHP_SOC_PDMC is not set
+# CONFIG_SND_MCHP_SOC_SPDIFRX is not set
+# CONFIG_SND_MCHP_SOC_SPDIFTX is not set
+CONFIG_SND_PCM=y
+CONFIG_SND_PCM_TIMER=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_MIKROE_PROTO=y
+CONFIG_SND_SOC_WM8731=y
+CONFIG_SND_SOC_WM8904=y
+CONFIG_SND_SPI=y
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_TIMER=y
+CONFIG_SOC_BUS=y
+# CONFIG_SOC_LAN966 is not set
+CONFIG_SOC_SAMA5=y
+CONFIG_SOC_SAMA5D2=y
+CONFIG_SOC_SAMA5D3=y
+CONFIG_SOC_SAMA5D4=y
+# CONFIG_SOC_SAMA7G5 is not set
+CONFIG_SOC_SAM_V7=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+# CONFIG_SPI_AT91_USART is not set
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_ATMEL_QUADSPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SQUASHFS is not set
+CONFIG_SRAM=y
+CONFIG_SRAM_EXEC=y
+# CONFIG_STANDALONE is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWPHY=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SYNC_FILE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_UBIFS_FS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_ACM=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+# CONFIG_USB_AT91 is not set
+# CONFIG_USB_ATMEL_USBA is not set
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_AT91=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_AT91=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+# CONFIG_USB_PWC is not set
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_VFAT_FS=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VIDEOMODE_HELPERS=y
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set
+# CONFIG_VIDEO_MICROCHIP_ISC is not set
+# CONFIG_VIDEO_MICROCHIP_XISC is not set
+CONFIG_VIDEO_NOMODESET=y
+CONFIG_VIDEO_V4L2_I2C=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XXHASH=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/at91/sama7/config-6.1 b/target/linux/at91/sama7/config-6.1
deleted file mode 100644
index 0fd9a69367..0000000000
--- a/target/linux/at91/sama7/config-6.1
+++ /dev/null
@@ -1,424 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_ALLOW_DEV_COREDUMP is not set
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-# CONFIG_ARM_PATCH_IDIV is not set
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-# CONFIG_AT91SAM9X_WATCHDOG is not set
-# CONFIG_AT91_ADC is not set
-CONFIG_AT91_SAMA5D2_ADC=y
-CONFIG_AT91_SOC_ID=y
-# CONFIG_AT91_SOC_SFR is not set
-CONFIG_ATMEL_CLOCKSOURCE_TCB=y
-# CONFIG_ATMEL_EBI is not set
-CONFIG_ATMEL_SDRAMC=y
-CONFIG_ATMEL_TCB_CLKSRC=y
-# CONFIG_AT_HDMAC is not set
-CONFIG_AT_XDMAC=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CACHE_L2X0 is not set
-CONFIG_CAN=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=9
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=256
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk nocache ignore_loglevel"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_AT91=y
-# CONFIG_COMPACTION is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-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_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_SPECTRE=y
-# CONFIG_CPU_SW_DOMAIN_PAN is not set
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRYPTO_CMAC=y
-CONFIG_CRYPTO_CRC32C=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_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_AT91_SAMA7G5_FLEXCOM3=y
-CONFIG_DEBUG_AT91_UART=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/at91.S"
-CONFIG_DEBUG_UART_PHYS=0xe1824200
-CONFIG_DEBUG_UART_VIRT=0xe0824200
-CONFIG_DEBUG_USER=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_DMADEVICES=y
-CONFIG_DMATEST=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_ENGINE_RAID=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-# CONFIG_EFI_PARTITION is not set
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_FANOTIFY=y
-CONFIG_FAT_FS=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_PCI_IOMAP=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_GENERIC_VDSO_32=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GRACE_PERIOD=y
-# CONFIG_HARDEN_BRANCH_HISTORY is not set
-# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_AT91=y
-# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_CONFIGFS=y
-# CONFIG_IIO_HRTIMER_TRIGGER is not set
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_SW_TRIGGER=y
-# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_TRIGGERED_BUFFER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_BOOTP is not set
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCKD=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_LSM="N"
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACB=y
-CONFIG_MACB_USE_HWSTAMP=y
-# CONFIG_MCHP_EIC is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_MEDIA_PLATFORM_SUPPORT=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_SUPPORT_FILTER=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
-CONFIG_MFD_AT91_USART=y
-CONFIG_MFD_ATMEL_FLEXCOM=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MICREL_PHY=y
-CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B=y
-CONFIG_MICROCHIP_PIT64B=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-# CONFIG_MMC_ATMELMCI is not set
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF_AT91=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NEON=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NFS_FS=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-# CONFIG_NVMEM_MICROCHIP_OTPC is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCCARD=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_AT91=y
-CONFIG_PINCTRL_AT91PIO4=y
-CONFIG_PM_OPP=y
-CONFIG_POWER_RESET=y
-# CONFIG_POWER_RESET_AT91_POWEROFF is not set
-CONFIG_POWER_RESET_AT91_RESET=y
-CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_PRINTK_TIME=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_ATMEL=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_MCP16502=y
-CONFIG_ROOT_NFS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-# CONFIG_RUNTIME_TESTING_MENU is not set
-CONFIG_SAMA5D4_WATCHDOG=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_SERIAL_ATMEL_PDC=y
-# CONFIG_SERIAL_ATMEL_TTYAT is not set
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SND=y
-CONFIG_SND_ATMEL_SOC=y
-# CONFIG_SND_ATMEL_SOC_CLASSD is not set
-# CONFIG_SND_ATMEL_SOC_I2S is not set
-# CONFIG_SND_ATMEL_SOC_PDMIC is not set
-# CONFIG_SND_COMPRESS_OFFLOAD is not set
-CONFIG_SND_DMAENGINE_PCM=y
-CONFIG_SND_JACK=y
-CONFIG_SND_JACK_INPUT_DEV=y
-CONFIG_SND_MCHP_SOC_I2S_MCC=y
-# CONFIG_SND_MCHP_SOC_PDMC is not set
-CONFIG_SND_MCHP_SOC_SPDIFRX=y
-CONFIG_SND_MCHP_SOC_SPDIFTX=y
-CONFIG_SND_PCM=y
-CONFIG_SND_SIMPLE_CARD=y
-CONFIG_SND_SIMPLE_CARD_UTILS=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SOC_MIKROE_PROTO is not set
-CONFIG_SND_SOC_PCM5102A=y
-CONFIG_SND_SOC_SPDIF=y
-CONFIG_SOC_BUS=y
-# CONFIG_SOC_LAN966 is not set
-# CONFIG_SOC_SAMA5D2 is not set
-# CONFIG_SOC_SAMA5D3 is not set
-# CONFIG_SOC_SAMA5D4 is not set
-CONFIG_SOC_SAMA7=y
-CONFIG_SOC_SAMA7G5=y
-CONFIG_SOC_SAM_V7=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-# CONFIG_SPI_AT91_USART is not set
-CONFIG_SPI_ATMEL=y
-# CONFIG_SPI_ATMEL_QUADSPI is not set
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-# CONFIG_STANDALONE is not set
-CONFIG_SUNRPC=y
-# CONFIG_SWAP is not set
-CONFIG_SWPHY=y
-# CONFIG_SWP_EMULATE is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_UACCESS_WITH_MEMCPY=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USE_OF=y
-CONFIG_VFAT_FS=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-# CONFIG_VIDEO_ATMEL_XISC is not set
-CONFIG_VIDEO_DEV=y
-# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set
-CONFIG_VIDEO_V4L2_I2C=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/at91/sama7/config-6.6 b/target/linux/at91/sama7/config-6.6
new file mode 100644
index 0000000000..e3455c5e37
--- /dev/null
+++ b/target/linux/at91/sama7/config-6.6
@@ -0,0 +1,431 @@
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_PATCH_IDIV is not set
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+# CONFIG_AT91SAM9X_WATCHDOG is not set
+# CONFIG_AT91_ADC is not set
+CONFIG_AT91_SAMA5D2_ADC=y
+CONFIG_AT91_SOC_ID=y
+# CONFIG_AT91_SOC_SFR is not set
+CONFIG_ATMEL_CLOCKSOURCE_TCB=y
+# CONFIG_ATMEL_EBI is not set
+CONFIG_ATMEL_TCB_CLKSRC=y
+# CONFIG_AT_HDMAC is not set
+CONFIG_AT_XDMAC=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_SD=y
+CONFIG_BUFFER_HEAD=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_CAN=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=9
+CONFIG_CMA_AREAS=7
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=256
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SYSFS is not set
+CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk nocache ignore_loglevel"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_AT91=y
+# CONFIG_COMPACTION is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+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_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_SPECTRE=y
+# CONFIG_CPU_SW_DOMAIN_PAN is not set
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32C=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_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_AT91_SAMA7G5_FLEXCOM3=y
+CONFIG_DEBUG_AT91_UART=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_INCLUDE="debug/at91.S"
+CONFIG_DEBUG_UART_PHYS=0xe1824200
+CONFIG_DEBUG_UART_VIRT=0xe0824200
+CONFIG_DEBUG_USER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMADEVICES=y
+CONFIG_DMATEST=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_ENGINE_RAID=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_FAT_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_PCI_IOMAP=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_GENERIC_VDSO_32=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GRACE_PERIOD=y
+# CONFIG_HARDEN_BRANCH_HISTORY is not set
+# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_SMP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_CONFIGFS=y
+# CONFIG_IIO_HRTIMER_TRIGGER is not set
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_SW_TRIGGER=y
+# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_BOOTP is not set
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEGACY_DIRECT_IO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCKD=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_LSM="N"
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACB=y
+CONFIG_MACB_USE_HWSTAMP=y
+# CONFIG_MCHP_EIC is not set
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_SUPPORT_FILTER=y
+CONFIG_MEMORY=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
+CONFIG_MFD_AT91_USART=y
+CONFIG_MFD_ATMEL_FLEXCOM=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MICREL_PHY=y
+CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B=y
+CONFIG_MICROCHIP_PIT64B=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_OF_AT91=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NEON=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_HANDSHAKE=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NFS_FS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+# CONFIG_NVMEM_MICROCHIP_OTPC is not set
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCCARD=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_PINCTRL_AT91PIO4=y
+CONFIG_PM_OPP=y
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_AT91_POWEROFF is not set
+CONFIG_POWER_RESET_AT91_RESET=y
+CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
+CONFIG_PWM_SYSFS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_MCP16502=y
+CONFIG_ROOT_NFS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_SAMA5D4_WATCHDOG=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SND=y
+CONFIG_SND_ATMEL_SOC=y
+# CONFIG_SND_ATMEL_SOC_CLASSD is not set
+# CONFIG_SND_ATMEL_SOC_I2S is not set
+# CONFIG_SND_ATMEL_SOC_PDMIC is not set
+# CONFIG_SND_COMPRESS_OFFLOAD is not set
+CONFIG_SND_DMAENGINE_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_JACK_INPUT_DEV=y
+CONFIG_SND_MCHP_SOC_I2S_MCC=y
+# CONFIG_SND_MCHP_SOC_PDMC is not set
+CONFIG_SND_MCHP_SOC_SPDIFRX=y
+CONFIG_SND_MCHP_SOC_SPDIFTX=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_SND_SIMPLE_CARD_UTILS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_MIKROE_PROTO is not set
+CONFIG_SND_SOC_PCM5102A=y
+CONFIG_SND_SOC_SPDIF=y
+CONFIG_SOC_BUS=y
+# CONFIG_SOC_LAN966 is not set
+# CONFIG_SOC_SAMA5D2 is not set
+# CONFIG_SOC_SAMA5D3 is not set
+# CONFIG_SOC_SAMA5D4 is not set
+CONFIG_SOC_SAMA7=y
+CONFIG_SOC_SAMA7G5=y
+CONFIG_SOC_SAM_V7=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+# CONFIG_SPI_AT91_USART is not set
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_ATMEL_QUADSPI is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_STACKTRACE=y
+# CONFIG_STANDALONE is not set
+CONFIG_SUNRPC=y
+# CONFIG_SWAP is not set
+CONFIG_SWPHY=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+CONFIG_USE_OF=y
+CONFIG_VFAT_FS=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set
+# CONFIG_VIDEO_MICROCHIP_ISC is not set
+# CONFIG_VIDEO_MICROCHIP_XISC is not set
+CONFIG_VIDEO_V4L2_I2C=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_WATCHDOG_CORE=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/ath79/config-6.6 b/target/linux/ath79/config-6.6
index f2d0646039..92057c343c 100644
--- a/target/linux/ath79/config-6.6
+++ b/target/linux/ath79/config-6.6
@@ -1,6 +1,7 @@
-CONFIG_AG71XX=y
-# CONFIG_AG71XX_DEBUG is not set
-CONFIG_AG71XX_DEBUG_FS=y
+# CONFIG_AG71XX is not set
+CONFIG_AG71XX_LEGACY=y
+# CONFIG_AG71XX_LEGACY_DEBUG is not set
+CONFIG_AG71XX_LEGACY_DEBUG_FS=y
CONFIG_AR8216_PHY=y
CONFIG_AR8216_PHY_LEDS=y
CONFIG_ARCH_32BIT_OFF_T=y
@@ -51,6 +52,7 @@ CONFIG_EARLY_PRINTK=y
CONFIG_ETHERNET_PACKET_MANGLE=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_FIXED_PHY=y
+CONFIG_FORCE_NR_CPUS=y
CONFIG_FS_IOMAP=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
diff --git a/target/linux/ath79/dts/ar7100.dtsi b/target/linux/ath79/dts/ar7100.dtsi
index 6648311619..5237157458 100644
--- a/target/linux/ath79/dts/ar7100.dtsi
+++ b/target/linux/ath79/dts/ar7100.dtsi
@@ -67,7 +67,7 @@
reg = <0x18040000 0x28>;
interrupts = <2>;
- ngpios = <16>;
+ ngpios = <12>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/target/linux/ath79/dts/ar7100_mikrotik_routerboard-4xx.dtsi b/target/linux/ath79/dts/ar7100_mikrotik_routerboard-4xx.dtsi
index 6ec700f179..41629da750 100644
--- a/target/linux/ath79/dts/ar7100_mikrotik_routerboard-4xx.dtsi
+++ b/target/linux/ath79/dts/ar7100_mikrotik_routerboard-4xx.dtsi
@@ -49,12 +49,9 @@
};
&gpio {
- ngpios = <31>;
gpio-line-names =
"", "", "", "", "LED", "RDY", "", "MDC",
- "MDIO", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "";
+ "MDIO", "", "", "";
};
&pcie0 {
diff --git a/target/linux/ath79/dts/ar7240.dtsi b/target/linux/ath79/dts/ar7240.dtsi
index afbae33a80..eb4b2e4aa3 100644
--- a/target/linux/ath79/dts/ar7240.dtsi
+++ b/target/linux/ath79/dts/ar7240.dtsi
@@ -15,6 +15,10 @@
};
};
+&gpio {
+ ngpios = <18>;
+};
+
&ahb {
usb: usb@1b000000 {
compatible = "generic-ohci";
diff --git a/target/linux/ath79/dts/ar7242.dtsi b/target/linux/ath79/dts/ar7242.dtsi
index 96b0442614..aab6c28f7b 100644
--- a/target/linux/ath79/dts/ar7242.dtsi
+++ b/target/linux/ath79/dts/ar7242.dtsi
@@ -16,7 +16,7 @@
};
&gpio {
- ngpios = <20>;
+ ngpios = <18>;
};
&ahb {
diff --git a/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts b/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts
index 77eeedc588..0124ddff87 100644
--- a/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts
+++ b/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts
@@ -78,7 +78,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio 6 GPIO_ACTIVE_HIGH>;
- realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <9 1 0 1 1 1 1 1 1 2>;
mdio-bus {
#address-cells = <1>;
diff --git a/target/linux/ath79/dts/ar724x.dtsi b/target/linux/ath79/dts/ar724x.dtsi
index c758fc244e..7b4bf3e3f2 100644
--- a/target/linux/ath79/dts/ar724x.dtsi
+++ b/target/linux/ath79/dts/ar724x.dtsi
@@ -60,8 +60,6 @@
reg = <0x18040000 0x28>;
interrupts = <2>;
- ngpios = <18>;
-
gpio-controller;
#gpio-cells = <2>;
diff --git a/target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts b/target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts
new file mode 100644
index 0000000000..2f2e6e2331
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Huawei AP6010DN";
+ compatible = "huawei,ap6010dn", "qca,ar9344";
+
+ chosen {
+ bootargs = "console=ttyS0,9600n8";
+ };
+
+ aliases {
+ led-boot = &led_function_green;
+ led-failsafe = &led_function_red;
+ led-running = &led_function_green;
+ led-upgrade = &led_function_red;
+ label-mac-device = &eth0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_function_green: led-status-green {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_function_red: led-status-red {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+ };
+
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ restart {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
+ debounce-interval = <60>;
+ };
+ };
+
+ watchdog {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wdt_gpio15>;
+
+ compatible = "linux,wdt-gpio";
+ gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+ hw_algo = "toggle";
+ hw_margin_ms = <100>;
+ always-running;
+ };
+
+ virtual_flash {
+ compatible = "mtd-concat";
+ devices = <&fwconcat0 &fwconcat1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x1e00000>;
+ compatible = "openwrt,uimage", "denx,uimage";
+ };
+ };
+ };
+};
+
+&spi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot-a";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "BootupA";
+ reg = <0x80000 0x20000>;
+ };
+
+ partition@a0000 {
+ label = "BootupB";
+ reg = <0xa0000 0x20000>;
+ };
+
+ partition@c0000 {
+ label = "u-boot-env";
+ reg = <0xc0000 0x20000>;
+ read-only;
+ };
+
+ partition@e0000 {
+ label = "BoardData";
+ reg = <0xe0000 0x20000>;
+ read-only;
+ };
+
+ // In the vendor layout, there are the "SysImageA" (12 MiB)
+ // and the "ConfigA" (3 MiB) partitions here.
+ fwconcat0: partition@100000 {
+ label = "fwconcat0";
+ reg = <0x100000 0xf00000>;
+ };
+
+ partition@1000000 {
+ label = "u-boot-b";
+ reg = <0x1000000 0x80000>;
+ read-only;
+ };
+
+ partition@1080000 {
+ label = "ResultA";
+ reg = <0x1080000 0x20000>;
+ read-only;
+ };
+
+ partition@10a0000 {
+ label = "ResultB";
+ reg = <0x10a0000 0x20000>;
+ read-only;
+ };
+
+ // In the vendor layout, there are the "SysImageB" (12 MiB)
+ // and the "ConfigB" (3 MiB) partitions here.
+ fwconcat1: partition@10c0000 {
+ label = "fwconcat1";
+ reg = <0x10c0000 0xf00000>;
+ };
+
+ art: partition@1fc0000 {
+ label = "art";
+ reg = <0x1fc0000 0x40000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_art_2005b: macaddr@2005b {
+ compatible = "mac-base";
+ reg = <0x2005b 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ cal_art_1000: cal@1000 {
+ reg = <0x1000 0x440>;
+ };
+
+ cal_art_5000: cal@5000 {
+ reg = <0x5000 0x844>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_art_2005b 1>, <&cal_art_1000>;
+ nvmem-cell-names = "mac-address", "calibration";
+};
+
+&pcie {
+ status = "okay";
+
+ ath9k: wifi@0,0 {
+ compatible = "pci168c,0033";
+ reg = <0x0000 0 0 0 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ nvmem-cells = <&macaddr_art_2005b 2>, <&cal_art_5000>;
+ nvmem-cell-names = "mac-address", "calibration";
+ };
+};
+
+&ref {
+ clock-frequency = <40000000>;
+};
+
+&eth0 {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_art_2005b 0>;
+ nvmem-cell-names = "mac-address";
+
+ pll-data = <0x06000000 0x04000101 0x0c001313>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&phy>;
+
+ gmac-config {
+ device = <&gmac>;
+ rgmii-gmac0 = <1>;
+ rxdv-delay = <3>;
+ rxd-delay = <3>;
+ };
+};
+
+&mdio0 {
+ status = "okay";
+
+ phy: ethernet-phy@18 {
+ reg = <0x4>;
+ };
+};
+
+&pinmux {
+ wdt_gpio15: pinmux_wdt_gpio15 {
+ pinctrl-single,bits = <0xc 0x0 0xFF000000>;
+ };
+};
+
+&wdt {
+ status = "disabled";
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_aterm.dtsi b/target/linux/ath79/dts/ar9344_nec_aterm.dtsi
new file mode 100644
index 0000000000..dfe2b064b7
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_aterm.dtsi
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "ar9344.dtsi"
+
+/ {
+ aliases {
+ led-running = &led_power_green;
+ led-upgrade = &led_power_green;
+ };
+
+ chosen {
+ /*
+ * don't specify bootargs property in DeviceTree to
+ * enable a console with a default baudrate (9600)
+ * or passed console= parameter from the bootloader
+ */
+ /delete-property/ bootargs;
+ stdout-path = &uart;
+ };
+
+ keys: keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&jtag_disable_pins>;
+
+ button-eco {
+ label = "eco";
+ gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ debounce-interval = <60>;
+ };
+
+ switch-ap {
+ label = "ap";
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_1>;
+ debounce-interval = <60>;
+ };
+
+ button-reset {
+ label = "reset";
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+
+ button-wps {
+ label = "wps";
+ gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ debounce-interval = <60>;
+ };
+ };
+
+ ath9k_leds: ath9k-leds {
+ /* all LEDs are connected to ath9k chip (AR938x) */
+ compatible = "gpio-leds";
+
+ led_power_green: led-0 {
+ gpios = <&ath9k 0 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ default-state = "on";
+ };
+
+ led-1 {
+ gpios = <&ath9k 1 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+ };
+
+ led-2 {
+ gpios = <&ath9k 2 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN_ONLINE;
+ };
+
+ led-3 {
+ gpios = <&ath9k 3 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WAN_ONLINE;
+ };
+
+ led-4 {
+ gpios = <&ath9k 4 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ linux,default-trigger = "phy0tpt";
+ };
+
+ led-5 {
+ gpios = <&ath9k 5 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ };
+
+ led-6 {
+ gpios = <&ath9k 6 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ linux,default-trigger = "phy1tpt";
+ };
+
+ led-7 {
+ gpios = <&ath9k 7 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ };
+
+ led-8 {
+ gpios = <&ath9k 12 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = "tv";
+ };
+
+ led-9 {
+ gpios = <&ath9k 13 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = "tv";
+ };
+ };
+
+ regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "usb-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+};
+
+&ref {
+ clock-frequency = <40000000>;
+};
+
+&spi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ partitions: partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * since the OEM bootloader requires unknown
+ * filesystem on firmware area, needs to be
+ * replaced to u-boot before OpenWrt installation
+ */
+ partition@0 {
+ label = "bootloader";
+ reg = <0x000000 0x020000>;
+ };
+
+ /* not compatible with u-boot */
+ partition@20000 {
+ label = "config";
+ reg = <0x020000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_config_6: macaddr@6 {
+ reg = <0x6 0x6>;
+ };
+ };
+ };
+
+ partition@30000 {
+ label = "art";
+ reg = <0x030000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
+ cal_art_5000: calibration@5000 {
+ reg = <0x5000 0x440>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&mdio0 {
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+
+ qca,ar8327-initvals = <
+ 0x04 0x07a00000 /* PORT0_PAD_MODE_CTRL */
+ 0x08 0x00000000 /* PORT5_PAD_MODE_CTRL */
+ 0x0c 0x00000000 /* PORT6_PAD_MODE_CTRL */
+ 0x10 0x81000080 /* POWER_ON_STRAP */
+ 0x50 0xcf37cf37 /* LED_CTRL0 */
+ 0x54 0x00000000 /* LED_CTRL1 */
+ 0x58 0x00000000 /* LED_CTRL2 */
+ 0x5c 0x03ffff00 /* LED_CTRL3 */
+ 0x7c 0x0000007e /* PORT0_STATUS */
+ >;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ pll-data = <0x06000000 0x00000101 0x00001616>;
+
+ phy-mode = "rgmii";
+ phy-handle = <&phy0>;
+
+ nvmem-cells = <&macaddr_config_6>;
+ nvmem-cell-names = "mac-address";
+
+ gmac-config {
+ device = <&gmac>;
+
+ rgmii-gmac0 = <1>;
+ rxdv-delay = <0>;
+ rxd-delay = <0>;
+ txd-delay = <0>;
+ txen-delay = <0>;
+ };
+};
+
+&gpio {
+ switch-reset {
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+};
+
+&pcie {
+ status = "okay";
+
+ ath9k: wifi@0,0 {
+ compatible = "pci168c,0030";
+ reg = <0x0000 0 0 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ nvmem-cells = <&cal_art_5000>;
+ nvmem-cell-names = "calibration";
+
+ usb-hub-reset {
+ gpio-hog;
+ gpios = <10 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dr_mode = "host";
+
+ /delete-node/ port@1;
+
+ /* NEC uPD720114 */
+ hub@1 {
+ compatible = "usb0409,005a";
+ reg = <1>;
+ };
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_wg600hp.dts b/target/linux/ath79/dts/ar9344_nec_wg600hp.dts
new file mode 100644
index 0000000000..e586dce7ca
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_wg600hp.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344_nec_aterm.dtsi"
+
+/ {
+ compatible = "nec,wg600hp", "qca,ar9344";
+ model = "NEC Aterm WG600HP";
+};
+
+&partitions {
+ partition@40000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x040000 0x7c0000>;
+ };
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_wr8750n.dts b/target/linux/ath79/dts/ar9344_nec_wr8750n.dts
new file mode 100644
index 0000000000..47e49dddc5
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_wr8750n.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344_nec_aterm.dtsi"
+
+/ {
+ compatible = "nec,wr8750n", "qca,ar9344";
+ model = "NEC Aterm WR8750N";
+};
+
+&partitions {
+ partition@40000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x040000 0x7c0000>;
+ };
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_wr9500n.dts b/target/linux/ath79/dts/ar9344_nec_wr9500n.dts
new file mode 100644
index 0000000000..1919e09829
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_wr9500n.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344_nec_aterm.dtsi"
+
+/ {
+ compatible = "nec,wr9500n", "qca,ar9344";
+ model = "NEC Aterm WR9500N";
+};
+
+&keys {
+ switch-converter {
+ label = "cnv";
+ gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_2>;
+ debounce-interval = <60>;
+ };
+};
+
+&ath9k_leds {
+ led-10 {
+ gpios = <&ath9k 14 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = "converter";
+ };
+
+ led-11 {
+ gpios = <&ath9k 15 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = "converter";
+ };
+};
+
+&partitions {
+ partition@40000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x040000 0xfc0000>;
+ };
+};
diff --git a/target/linux/ath79/dts/ar9344_qihoo_c301.dts b/target/linux/ath79/dts/ar9344_qihoo_c301.dts
index 1d9c6ca9a4..0e9104dbb9 100644
--- a/target/linux/ath79/dts/ar9344_qihoo_c301.dts
+++ b/target/linux/ath79/dts/ar9344_qihoo_c301.dts
@@ -166,6 +166,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_radiocfg_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
cal_radiocfg_5000: calibration@5000 {
reg = <0x5000 0x844>;
};
@@ -220,7 +224,9 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+
+ nvmem-cells = <&cal_radiocfg_1000>;
+ nvmem-cell-names = "calibration";
};
&eth1 {
diff --git a/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts b/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts
index 4d809b922a..802d90b752 100644
--- a/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts
+++ b/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts
@@ -63,8 +63,8 @@
i2c {
compatible = "i2c-gpio";
- sda-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
- scl-gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+ sda-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/target/linux/ath79/dts/qca9531_glinet_gl-s200.dtsi b/target/linux/ath79/dts/qca9531_glinet_gl-s200.dtsi
index f6ff4f3a10..648c3a9c8e 100644
--- a/target/linux/ath79/dts/qca9531_glinet_gl-s200.dtsi
+++ b/target/linux/ath79/dts/qca9531_glinet_gl-s200.dtsi
@@ -91,7 +91,6 @@
};
&gpio {
- ngpios = <17>;
gpio-line-names =
"","reset-zigbee","reset-zwave","reset",
"LED-orange","","","","","","",
diff --git a/target/linux/ath79/dts/qca953x.dtsi b/target/linux/ath79/dts/qca953x.dtsi
index cc26db5ba2..0e52a80f6e 100644
--- a/target/linux/ath79/dts/qca953x.dtsi
+++ b/target/linux/ath79/dts/qca953x.dtsi
@@ -72,7 +72,7 @@
reg = <0x18040000 0x28>;
interrupts = <2>;
- ngpios = <20>;
+ ngpios = <18>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/target/linux/ath79/dts/qca9557_sophos_ap15.dts b/target/linux/ath79/dts/qca9557_sophos_ap15.dts
new file mode 100644
index 0000000000..773b423cde
--- /dev/null
+++ b/target/linux/ath79/dts/qca9557_sophos_ap15.dts
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qca955x.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "sophos,ap15", "qca,qca9557";
+ model = "Sophos AP15";
+
+ aliases {
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_yellow;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_yellow;
+ label-mac-device = &eth0;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_green: status_green {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ led_status_yellow: status_yellow {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_YELLOW>;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&spi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x000000 0x040000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "u-boot-env";
+ reg = <0x040000 0x010000>;
+ };
+
+ partition@50000 {
+ label = "art";
+ reg = <0x050000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+ };
+ };
+
+ partition@60000 {
+ label = "config";
+ reg = <0x060000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_config_201a: macaddr@201a {
+ reg = <0x201a 0x6>;
+ };
+ };
+ };
+
+ partition@70000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x070000 0xf90000>;
+ };
+ };
+ };
+};
+
+&mdio0 {
+ status = "okay";
+
+ phy-mask = <0x10>;
+
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ eee-broken-100tx;
+ eee-broken-1000t;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ pll-data = <0xa6000000 0xa0000101 0xa0001313>;
+
+ nvmem-cells = <&macaddr_config_201a>;
+ nvmem-cell-names = "mac-address";
+
+ phy-mode = "rgmii-id";
+ phy-handle = <&phy4>;
+
+ gmac_config: gmac-config {
+ device = <&gmac>;
+
+ rgmii-enabled = <1>;
+
+ rxdv-delay = <3>;
+ rxd-delay = <3>;
+ txen-delay = <3>;
+ txd-delay = <3>;
+ };
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
+};
diff --git a/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts b/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts
index 4372a07d51..828096f8f6 100644
--- a/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts
+++ b/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg6616", "qca,qca9557";
- model = "ZyXEL NBG6616";
+ model = "Zyxel NBG6616";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ath79/dts/qca9558_sophos_ap15.dts b/target/linux/ath79/dts/qca9558_sophos_ap15.dts
deleted file mode 100644
index 7949d3e88f..0000000000
--- a/target/linux/ath79/dts/qca9558_sophos_ap15.dts
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "qca955x.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-
-/ {
- compatible = "sophos,ap15", "qca,qca9558";
- model = "Sophos AP15";
-
- aliases {
- led-boot = &led_status_green;
- led-failsafe = &led_status_yellow;
- led-running = &led_status_green;
- led-upgrade = &led_status_yellow;
- label-mac-device = &eth0;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8";
- };
-
- leds {
- compatible = "gpio-leds";
-
- led_status_green: status_green {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
- led_status_yellow: status_yellow {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_YELLOW>;
- gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&pcie0 {
- status = "okay";
-
- wifi@0,0 {
- compatible = "qcom,ath10k";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&cal_art_5000>;
- nvmem-cell-names = "calibration";
- };
-};
-
-&spi {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <25000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x000000 0x040000>;
- read-only;
- };
-
- partition@40000 {
- label = "u-boot-env";
- reg = <0x040000 0x010000>;
- };
-
- partition@50000 {
- label = "art";
- reg = <0x050000 0x010000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- cal_art_1000: calibration@1000 {
- reg = <0x1000 0x440>;
- };
-
- cal_art_5000: calibration@5000 {
- reg = <0x5000 0x844>;
- };
- };
- };
-
- partition@60000 {
- label = "config";
- reg = <0x060000 0x010000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_config_201a: macaddr@201a {
- reg = <0x201a 0x6>;
- };
- };
- };
-
- partition@70000 {
- compatible = "denx,uimage";
- label = "firmware";
- reg = <0x070000 0xf90000>;
- };
- };
- };
-};
-
-&mdio0 {
- status = "okay";
-
- phy-mask = <0x10>;
-
- phy4: ethernet-phy@4 {
- reg = <4>;
- eee-broken-100tx;
- eee-broken-1000t;
- };
-};
-
-&eth0 {
- status = "okay";
-
- pll-data = <0xa6000000 0xa0000101 0xa0001313>;
-
- nvmem-cells = <&macaddr_config_201a>;
- nvmem-cell-names = "mac-address";
-
- phy-mode = "rgmii-id";
- phy-handle = <&phy4>;
-
- gmac_config: gmac-config {
- device = <&gmac>;
-
- rgmii-enabled = <1>;
-
- rxdv-delay = <3>;
- rxd-delay = <3>;
- txen-delay = <3>;
- txd-delay = <3>;
- };
-};
-
-&wmac {
- status = "okay";
-
- nvmem-cells = <&cal_art_1000>;
- nvmem-cell-names = "calibration";
-};
diff --git a/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts b/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts
index c00109a5b4..bf8d0f2f95 100644
--- a/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts
+++ b/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts
@@ -4,5 +4,5 @@
/ {
compatible = "zyxel,emg2926-q10a", "zyxel,nbg6716", "qca,qca9558";
- model = "ZyXEL EMG2926-Q10A";
+ model = "Zyxel EMG2926-Q10A";
};
diff --git a/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts b/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts
index 19f1245022..463553fe27 100644
--- a/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts
+++ b/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg6716", "qca,qca9558";
- model = "ZyXEL NBG6716";
+ model = "Zyxel NBG6716";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ath79/dts/qca955x.dtsi b/target/linux/ath79/dts/qca955x.dtsi
index 9d410ceb46..c6cf83d4da 100644
--- a/target/linux/ath79/dts/qca955x.dtsi
+++ b/target/linux/ath79/dts/qca955x.dtsi
@@ -362,6 +362,8 @@
resets = <&rst 9>, <&rst 22>;
reset-names = "mac", "mdio";
+ clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_REF>;
+ clock-names = "eth", "mdio";
};
&mdio1 {
@@ -379,4 +381,6 @@
resets = <&rst 13>, <&rst 23>;
reset-names = "mac", "mdio";
+ clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_REF>;
+ clock-names = "eth", "mdio";
};
diff --git a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi
index 43e34c6029..53bb5b0141 100644
--- a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi
+++ b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi
@@ -8,6 +8,7 @@
/ {
aliases {
+ label-mac-device = &eth0;
led-boot = &led_status;
led-failsafe = &led_status;
led-upgrade = &led_status;
@@ -107,6 +108,9 @@
phy-mode = "rgmii-rxid";
pll-data = <0xae000000 0x80000101 0x80001313>;
+ nvmem-cells = <&macaddr_uboot_ethaddr 0>;
+ nvmem-cell-names = "mac-address";
+
gmac-config {
device = <&gmac>;
@@ -144,8 +148,8 @@
wifi@0,0 {
compatible = "qcom,ath10k";
reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&cal_art_5000>;
- nvmem-cell-names = "calibration";
+ nvmem-cells = <&cal_art_5000>, <&macaddr_uboot_ethaddr 1>;
+ nvmem-cell-names = "calibration", "mac-address";
};
};
@@ -169,9 +173,14 @@
};
partition@40000 {
+ compatible = "u-boot,env";
label = "u-boot-env";
reg = <0x40000 0x10000>;
read-only;
+
+ macaddr_uboot_ethaddr: ethaddr {
+ #nvmem-cell-cells = <1>;
+ };
};
partition@50000 {
@@ -252,6 +261,6 @@
&wmac {
status = "okay";
- nvmem-cells = <&cal_art_1000>;
- nvmem-cell-names = "calibration";
+ nvmem-cells = <&cal_art_1000>, <&macaddr_uboot_ethaddr 0>;
+ nvmem-cell-names = "calibration", "mac-address";
};
diff --git a/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts b/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts
index c4671bf57f..4e66f45ebe 100644
--- a/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts
+++ b/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts
@@ -114,6 +114,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
precal_art_5000: pre-calibration@5000 {
reg = <0x5000 0x2f20>;
};
@@ -177,5 +181,6 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
};
diff --git a/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts b/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts
index 7f8866bd36..c9e47938d3 100644
--- a/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts
+++ b/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts
@@ -129,6 +129,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
precal_art_5000: pre-calibration@5000 {
reg = <0x5000 0x2f20>;
};
@@ -178,5 +182,6 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
};
diff --git a/target/linux/ath79/dts/qca9563_nec_wg800hp.dts b/target/linux/ath79/dts/qca9563_nec_wg800hp.dts
index d2621fa304..d8ecf46201 100644
--- a/target/linux/ath79/dts/qca9563_nec_wg800hp.dts
+++ b/target/linux/ath79/dts/qca9563_nec_wg800hp.dts
@@ -142,6 +142,24 @@
#address-cells = <1>;
#size-cells = <1>;
+ macaddr_board_data_280: macaddr@280 {
+ compatible = "mac-base";
+ reg = <0x280 0x11>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_board_data_480: macaddr@480 {
+ compatible = "mac-base";
+ reg = <0x480 0x11>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_board_data_680: macaddr@680 {
+ compatible = "mac-base";
+ reg = <0x680 0x11>;
+ #nvmem-cell-cells = <1>;
+ };
+
macaddr_board_data_880: macaddr@880 {
compatible = "mac-base";
reg = <0x880 0x11>;
@@ -160,6 +178,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
cal_art_5000: calibration@5000 {
reg = <0x5000 0x844>;
};
@@ -191,6 +213,9 @@
phy-mode = "sgmii";
phy-handle = <&phy0>;
+
+ nvmem-cells = <&macaddr_board_data_280 0>;
+ nvmem-cell-names = "mac-address";
};
&pcie {
@@ -206,5 +231,7 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+
+ nvmem-cells = <&macaddr_board_data_680 0>, <&cal_art_1000>;
+ nvmem-cell-names = "mac-address", "calibration";
};
diff --git a/target/linux/ath79/dts/qca956x.dtsi b/target/linux/ath79/dts/qca956x.dtsi
index 8b261568f0..de685d053c 100644
--- a/target/linux/ath79/dts/qca956x.dtsi
+++ b/target/linux/ath79/dts/qca956x.dtsi
@@ -61,7 +61,7 @@
reg = <0x18040000 0x28>;
interrupts = <2>;
- ngpios = <24>;
+ ngpios = <23>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c b/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c
index 8f53974e46..70f091b79f 100644
--- a/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c
+++ b/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c
@@ -110,7 +110,6 @@ static int gpio_latch_probe(struct platform_device *pdev)
struct gpio_latch_chip *glc;
struct gpio_chip *gc;
struct device *dev = &pdev->dev;
- struct fwnode_handle *fwnode = dev->fwnode;
int i, n;
glc = devm_kzalloc(dev, sizeof(*glc), GFP_KERNEL);
@@ -121,24 +120,19 @@ static int gpio_latch_probe(struct platform_device *pdev)
mutex_init(&glc->latch_mutex);
n = gpiod_count(dev, NULL);
- if (n <= 0) {
- dev_err(dev, "failed to get gpios: %d\n", n);
- return n;
- } else if (n != GPIO_LATCH_LINES) {
- dev_err(dev, "expected %d gpios\n", GPIO_LATCH_LINES);
+ if (n <= 0)
+ return dev_err_probe(dev, n, "failed to get gpios");
+ if (n != GPIO_LATCH_LINES) {
+ dev_err(dev, "expected %d gpios", GPIO_LATCH_LINES);
return -EINVAL;
}
for (i = 0; i < n; i++) {
glc->gpios[i] = devm_gpiod_get_index_optional(dev, NULL, i,
GPIOD_OUT_LOW);
- if (IS_ERR(glc->gpios[i])) {
- if (PTR_ERR(glc->gpios[i]) != -EPROBE_DEFER) {
- dev_err(dev, "failed to get gpio %d: %ld\n", i,
- PTR_ERR(glc->gpios[i]));
- }
- return PTR_ERR(glc->gpios[i]);
- }
+ if (IS_ERR(glc->gpios[i]))
+ return dev_err_probe(dev, PTR_ERR(glc->gpios[i]),
+ "failed to get gpio %d", i);
}
glc->le_gpio = 8;
@@ -152,31 +146,15 @@ static int gpio_latch_probe(struct platform_device *pdev)
gc = &glc->gc;
gc->label = GPIO_LATCH_DRIVER_NAME;
+ gc->parent = dev;
gc->can_sleep = true;
gc->base = -1;
gc->ngpio = GPIO_LATCH_LINES;
gc->get = gpio_latch_get;
gc->set = gpio_latch_set;
gc->direction_output = gpio_latch_direction_output;
- gc->fwnode = fwnode;
- platform_set_drvdata(pdev, glc);
-
- i = gpiochip_add(&glc->gc);
- if (i) {
- dev_err(dev, "gpiochip_add() failed: %d\n", i);
- return i;
- }
-
- return 0;
-}
-
-static int gpio_latch_remove(struct platform_device *pdev)
-{
- struct gpio_latch_chip *glc = platform_get_drvdata(pdev);
-
- gpiochip_remove(&glc->gc);
- return 0;
+ return devm_gpiochip_add_data(dev, gc, glc);
}
static const struct of_device_id gpio_latch_match[] = {
@@ -188,7 +166,6 @@ MODULE_DEVICE_TABLE(of, gpio_latch_match);
static struct platform_driver gpio_latch_driver = {
.probe = gpio_latch_probe,
- .remove = gpio_latch_remove,
.driver = {
.name = GPIO_LATCH_DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c b/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c
index 8996b2a906..4b21c93469 100644
--- a/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c
+++ b/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c
@@ -144,8 +144,6 @@ static int gpio_rb91x_key_probe(struct platform_device *pdev)
struct gpio_rb91x_key *drvdata;
struct gpio_chip *gc;
struct device *dev = &pdev->dev;
- struct fwnode_handle *fwnode = dev->fwnode;
- int r;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
@@ -155,16 +153,12 @@ static int gpio_rb91x_key_probe(struct platform_device *pdev)
mutex_init(&drvdata->poll_mutex);
drvdata->gpio = devm_gpiod_get(dev, NULL, GPIOD_OUT_LOW);
- if (IS_ERR(drvdata->gpio)) {
- if (PTR_ERR(drvdata->gpio) != -EPROBE_DEFER) {
- dev_err(dev, "failed to get gpio: %ld\n",
- PTR_ERR(drvdata->gpio));
- }
- return PTR_ERR(drvdata->gpio);
- }
+ if (IS_ERR(drvdata->gpio))
+ return dev_err_probe(dev, PTR_ERR(drvdata->gpio), "failed to get gpio");
gc = &drvdata->gc;
gc->label = GPIO_RB91X_KEY_DRIVER_NAME;
+ gc->parent = dev;
gc->can_sleep = 1;
gc->base = -1;
gc->ngpio = GPIO_RB91X_KEY_NGPIOS;
@@ -172,25 +166,10 @@ static int gpio_rb91x_key_probe(struct platform_device *pdev)
gc->set = gpio_rb91x_key_set;
gc->direction_output = gpio_rb91x_key_direction_output;
gc->direction_input = gpio_rb91x_key_direction_input;
- gc->fwnode = fwnode;
platform_set_drvdata(pdev, drvdata);
- r = gpiochip_add(&drvdata->gc);
- if (r) {
- dev_err(dev, "gpiochip_add() failed: %d\n", r);
- return r;
- }
-
- return 0;
-}
-
-static int gpio_rb91x_key_remove(struct platform_device *pdev)
-{
- struct gpio_rb91x_key *drvdata = platform_get_drvdata(pdev);
-
- gpiochip_remove(&drvdata->gc);
- return 0;
+ return devm_gpiochip_add_data(dev, gc, drvdata);
}
static const struct of_device_id gpio_rb91x_key_match[] = {
@@ -202,7 +181,6 @@ MODULE_DEVICE_TABLE(of, gpio_rb91x_key_match);
static struct platform_driver gpio_rb91x_key_driver = {
.probe = gpio_rb91x_key_probe,
- .remove = gpio_rb91x_key_remove,
.driver = {
.name = GPIO_RB91X_KEY_DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c b/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c
index c502f4a064..092cd85d82 100644
--- a/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c
+++ b/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c
@@ -284,13 +284,8 @@ static int rb91x_nand_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, drvdata);
gpios = gpiod_get_array(dev, NULL, GPIOD_OUT_LOW);
- if (IS_ERR(gpios)) {
- if (PTR_ERR(gpios) != -EPROBE_DEFER) {
- dev_err(dev, "failed to get gpios: %ld\n",
- PTR_ERR(gpios));
- }
- return PTR_ERR(gpios);
- }
+ if (IS_ERR(gpios))
+ return dev_err_probe(dev, PTR_ERR(gpios), "failed to get gpios");
if (gpios->ndescs != RB91X_NAND_GPIOS) {
dev_err(dev, "expected %d gpios\n", RB91X_NAND_GPIOS);
@@ -333,16 +328,11 @@ static int rb91x_nand_probe(struct platform_device *pdev)
r = mtd_device_register(mtd, NULL, 0);
if (r) {
- dev_err(dev, "mtd_device_register() failed: %d\n",
- r);
- goto err_release_nand;
+ rb91x_nand_release(drvdata);
+ return dev_err_probe(dev, r, "mtd_device_register() failed");
}
return 0;
-
-err_release_nand:
- rb91x_nand_release(drvdata);
- return r;
}
static int rb91x_nand_remove(struct platform_device *pdev)
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Kconfig b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Kconfig
index dfcedcf70e..e1504b9234 100644
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Kconfig
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Kconfig
@@ -1,4 +1,4 @@
-config AG71XX
+config AG71XX_LEGACY
tristate "Atheros AR7XXX/AR9XXX built-in ethernet mac support"
depends on ATH79
select PHYLIB
@@ -6,14 +6,14 @@ config AG71XX
If you wish to compile a kernel for AR7XXX/91XXX and enable
ethernet support, then you should always answer Y to this.
-if AG71XX
+if AG71XX_LEGACY
-config AG71XX_DEBUG
+config AG71XX_LEGACY_DEBUG
bool "Atheros AR71xx built-in ethernet driver debugging"
help
Atheros AR71xx built-in ethernet driver debugging messages.
-config AG71XX_DEBUG_FS
+config AG71XX_LEGACY_DEBUG_FS
bool "Atheros AR71xx built-in ethernet driver debugfs support"
depends on DEBUG_FS
help
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Makefile b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Makefile
index 87add0d208..86e47290e6 100644
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Makefile
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/Makefile
@@ -2,12 +2,12 @@
# Makefile for the Atheros AR71xx built-in ethernet macs
#
-ag71xx-y += ag71xx_main.o
-ag71xx-y += ag71xx_gmac.o
-ag71xx-y += ag71xx_ethtool.o
-ag71xx-y += ag71xx_phy.o
+ag71xx_legacy-y += ag71xx_main.o
+ag71xx_legacy-y += ag71xx_gmac.o
+ag71xx_legacy-y += ag71xx_ethtool.o
+ag71xx_legacy-y += ag71xx_phy.o
-ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o
+ag71xx_legacy-$(CONFIG_AG71XX_LEGACY_DEBUG_FS) += ag71xx_legacy_debugfs.o
-obj-$(CONFIG_AG71XX) += ag71xx_mdio.o
-obj-$(CONFIG_AG71XX) += ag71xx.o
+obj-$(CONFIG_AG71XX_LEGACY) += ag71xx_legacy_mdio.o
+obj-$(CONFIG_AG71XX_LEGACY) += ag71xx_legacy.o
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index fca072a83a..da716d94c3 100644
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -40,7 +40,7 @@
#include <asm/mach-ath79/ar71xx_regs.h>
#include <asm/mach-ath79/ath79.h>
-#define AG71XX_DRV_NAME "ag71xx"
+#define AG71XX_DRV_NAME "ag71xx-legacy"
/*
* For our NAPI weight bigger does *NOT* mean better - it means more
@@ -68,7 +68,7 @@
#define AG71XX_TX_RING_SIZE_MAX 256
#define AG71XX_RX_RING_SIZE_MAX 256
-#ifdef CONFIG_AG71XX_DEBUG
+#ifdef CONFIG_AG71XX_LEGACY_DEBUG
#define DBG(fmt, args...) pr_debug(fmt, ## args)
#else
#define DBG(fmt, args...) do {} while (0)
@@ -195,7 +195,7 @@ struct ag71xx {
u32 pllreg[3];
struct regmap *pllregmap;
-#ifdef CONFIG_AG71XX_DEBUG_FS
+#ifdef CONFIG_AG71XX_LEGACY_DEBUG_FS
struct ag71xx_debug debug;
#endif
};
@@ -425,7 +425,7 @@ static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
}
-#ifdef CONFIG_AG71XX_DEBUG_FS
+#ifdef CONFIG_AG71XX_LEGACY_DEBUG_FS
int ag71xx_debugfs_root_init(void);
void ag71xx_debugfs_root_exit(void);
int ag71xx_debugfs_init(struct ag71xx *ag);
@@ -441,7 +441,7 @@ static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag,
u32 status) {}
static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag,
int rx, int tx) {}
-#endif /* CONFIG_AG71XX_DEBUG_FS */
+#endif /* CONFIG_AG71XX_LEGACY_DEBUG_FS */
int ag71xx_ar7240_init(struct ag71xx *ag, struct device_node *np);
void ag71xx_ar7240_cleanup(struct ag71xx *ag);
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_legacy_debugfs.c
index 20cf1c15c8..20cf1c15c8 100644
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_legacy_debugfs.c
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_legacy_mdio.c b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_legacy_mdio.c
new file mode 100644
index 0000000000..fda561a374
--- /dev/null
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_legacy_mdio.c
@@ -0,0 +1,250 @@
+/*
+ * Atheros AR71xx built-in ethernet mac driver
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Based on Atheros' AG7100 driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/of_mdio.h>
+#include "ag71xx.h"
+
+#define AG71XX_MDIO_RETRY 1000
+#define AG71XX_MDIO_DELAY 5
+
+static int bus_count;
+
+static int ag71xx_mdio_wait_busy(struct ag71xx_mdio *am)
+{
+ int i;
+
+ for (i = 0; i < AG71XX_MDIO_RETRY; i++) {
+ u32 busy;
+
+ udelay(AG71XX_MDIO_DELAY);
+
+ regmap_read(am->mii_regmap, AG71XX_REG_MII_IND, &busy);
+ if (!busy)
+ return 0;
+
+ udelay(AG71XX_MDIO_DELAY);
+ }
+
+ pr_err("%s: MDIO operation timed out\n", am->mii_bus->name);
+
+ return -ETIMEDOUT;
+}
+
+static int ag71xx_mdio_mii_read(struct mii_bus *bus, int addr, int reg)
+{
+ struct ag71xx_mdio *am = bus->priv;
+ int err;
+ int ret;
+
+ err = ag71xx_mdio_wait_busy(am);
+ if (err)
+ return 0xffff;
+
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_ADDR,
+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_CMD, MII_CMD_READ);
+
+ err = ag71xx_mdio_wait_busy(am);
+ if (err)
+ return 0xffff;
+
+ regmap_read(am->mii_regmap, AG71XX_REG_MII_STATUS, &ret);
+ ret &= 0xffff;
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
+
+ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
+
+ return ret;
+}
+
+static int ag71xx_mdio_mii_write(struct mii_bus *bus, int addr, int reg, u16 val)
+{
+ struct ag71xx_mdio *am = bus->priv;
+
+ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
+
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_ADDR,
+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_CTRL, val);
+
+ ag71xx_mdio_wait_busy(am);
+
+ return 0;
+}
+
+static const u32 ar71xx_mdio_div_table[] = {
+ 4, 4, 6, 8, 10, 14, 20, 28,
+};
+
+static const u32 ar7240_mdio_div_table[] = {
+ 2, 2, 4, 6, 8, 12, 18, 26, 32, 40, 48, 56, 62, 70, 78, 96,
+};
+
+static const u32 ar933x_mdio_div_table[] = {
+ 4, 4, 6, 8, 10, 14, 20, 28, 34, 42, 50, 58, 66, 74, 82, 98,
+};
+
+static int ag71xx_mdio_get_divider(struct device_node *np, u32 *div)
+{
+ struct clk *ref_clk = of_clk_get(np, 0);
+ unsigned long ref_clock;
+ u32 mdio_clock;
+ const u32 *table;
+ int ndivs, i;
+
+ if (IS_ERR(ref_clk))
+ return -EINVAL;
+
+ ref_clock = clk_get_rate(ref_clk);
+ clk_put(ref_clk);
+
+ if(of_property_read_u32(np, "qca,mdio-max-frequency", &mdio_clock)) {
+ if (of_property_read_bool(np, "builtin-switch"))
+ mdio_clock = 5000000;
+ else
+ mdio_clock = 2000000;
+ }
+
+ if (of_device_is_compatible(np, "qca,ar9330-mdio") ||
+ of_device_is_compatible(np, "qca,ar9340-mdio")) {
+ table = ar933x_mdio_div_table;
+ ndivs = ARRAY_SIZE(ar933x_mdio_div_table);
+ } else if (of_device_is_compatible(np, "qca,ar7240-mdio")) {
+ table = ar7240_mdio_div_table;
+ ndivs = ARRAY_SIZE(ar7240_mdio_div_table);
+ } else {
+ table = ar71xx_mdio_div_table;
+ ndivs = ARRAY_SIZE(ar71xx_mdio_div_table);
+ }
+
+ for (i = 0; i < ndivs; i++) {
+ unsigned long t;
+
+ t = ref_clock / table[i];
+ if (t <= mdio_clock) {
+ *div = i;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+static int ag71xx_mdio_reset(struct mii_bus *bus)
+{
+ struct device_node *np = bus->dev.of_node;
+ struct ag71xx_mdio *am = bus->priv;
+ bool builtin_switch;
+ u32 t;
+
+ builtin_switch = of_property_read_bool(np, "builtin-switch");
+
+ if (ag71xx_mdio_get_divider(np, &t)) {
+ if (of_device_is_compatible(np, "qca,ar9340-mdio"))
+ t = MII_CFG_CLK_DIV_58;
+ else if (builtin_switch)
+ t = MII_CFG_CLK_DIV_10;
+ else
+ t = MII_CFG_CLK_DIV_28;
+ }
+
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_CFG, t | MII_CFG_RESET);
+ udelay(100);
+
+ regmap_write(am->mii_regmap, AG71XX_REG_MII_CFG, t);
+ udelay(100);
+
+ return 0;
+}
+
+static int ag71xx_mdio_probe(struct platform_device *pdev)
+{
+ struct device *amdev = &pdev->dev;
+ struct device_node *np = pdev->dev.of_node;
+ struct ag71xx_mdio *am;
+ struct mii_bus *mii_bus;
+ bool builtin_switch;
+ int i, err;
+
+ am = devm_kzalloc(amdev, sizeof(*am), GFP_KERNEL);
+ if (!am)
+ return -ENOMEM;
+
+ am->mii_regmap = syscon_regmap_lookup_by_phandle(np, "regmap");
+ if (IS_ERR(am->mii_regmap))
+ return PTR_ERR(am->mii_regmap);
+
+ mii_bus = devm_mdiobus_alloc(amdev);
+ if (!mii_bus)
+ return -ENOMEM;
+
+ am->mdio_reset = devm_reset_control_get_exclusive(amdev, "mdio");
+ builtin_switch = of_property_read_bool(np, "builtin-switch");
+
+ mii_bus->name = "ag71xx_mdio";
+ mii_bus->read = ag71xx_mdio_mii_read;
+ mii_bus->write = ag71xx_mdio_mii_write;
+ mii_bus->reset = ag71xx_mdio_reset;
+ mii_bus->priv = am;
+ mii_bus->parent = amdev;
+ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s.%d", np->name, bus_count++);
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ mii_bus->irq[i] = PHY_POLL;
+
+ if (!IS_ERR(am->mdio_reset)) {
+ reset_control_assert(am->mdio_reset);
+ msleep(100);
+ reset_control_deassert(am->mdio_reset);
+ msleep(200);
+ }
+
+ err = of_mdiobus_register(mii_bus, np);
+ if (err)
+ return err;
+
+ am->mii_bus = mii_bus;
+ platform_set_drvdata(pdev, am);
+
+ return 0;
+}
+
+static int ag71xx_mdio_remove(struct platform_device *pdev)
+{
+ struct ag71xx_mdio *am = platform_get_drvdata(pdev);
+
+ mdiobus_unregister(am->mii_bus);
+ return 0;
+}
+
+static const struct of_device_id ag71xx_mdio_match[] = {
+ { .compatible = "qca,ar7240-mdio" },
+ { .compatible = "qca,ar9330-mdio" },
+ { .compatible = "qca,ar9340-mdio" },
+ { .compatible = "qca,ath79-mdio" },
+ {}
+};
+
+static struct platform_driver ag71xx_mdio_driver = {
+ .probe = ag71xx_mdio_probe,
+ .remove = ag71xx_mdio_remove,
+ .driver = {
+ .name = "ag71xx-legacy-mdio",
+ .of_match_table = ag71xx_mdio_match,
+ }
+};
+
+module_platform_driver(ag71xx_mdio_driver);
+MODULE_LICENSE("GPL");
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index f63e93f978..c6fcea1abd 100644
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -1162,33 +1162,10 @@ static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct ag71xx *ag = netdev_priv(dev);
+ if (ag->phy_dev == NULL)
+ return -ENODEV;
- switch (cmd) {
- case SIOCSIFHWADDR:
- if (copy_from_user
- ((void*)dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
- return -EFAULT;
- return 0;
-
- case SIOCGIFHWADDR:
- if (copy_to_user
- (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
- return -EFAULT;
- return 0;
-
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
- if (ag->phy_dev == NULL)
- break;
-
- return phy_mii_ioctl(ag->phy_dev, ifr, cmd);
-
- default:
- break;
- }
-
- return -EOPNOTSUPP;
+ return phy_mii_ioctl(ag->phy_dev, ifr, cmd);
}
static void ag71xx_oom_timer_handler(struct timer_list *t)
@@ -1501,7 +1478,7 @@ static const struct net_device_ops ag71xx_netdev_ops = {
.ndo_open = ag71xx_open,
.ndo_stop = ag71xx_stop,
.ndo_start_xmit = ag71xx_hard_start_xmit,
- .ndo_do_ioctl = ag71xx_do_ioctl,
+ .ndo_eth_ioctl = ag71xx_do_ioctl,
.ndo_tx_timeout = ag71xx_tx_timeout,
.ndo_change_mtu = ag71xx_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c
deleted file mode 100644
index fd05dbd0ca..0000000000
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Atheros AR71xx built-in ethernet mac driver
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * Based on Atheros' AG7100 driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/of_mdio.h>
-#include "ag71xx.h"
-
-#define AG71XX_MDIO_RETRY 1000
-#define AG71XX_MDIO_DELAY 5
-
-static int bus_count;
-
-static int ag71xx_mdio_wait_busy(struct ag71xx_mdio *am)
-{
- int i;
-
- for (i = 0; i < AG71XX_MDIO_RETRY; i++) {
- u32 busy;
-
- udelay(AG71XX_MDIO_DELAY);
-
- regmap_read(am->mii_regmap, AG71XX_REG_MII_IND, &busy);
- if (!busy)
- return 0;
-
- udelay(AG71XX_MDIO_DELAY);
- }
-
- pr_err("%s: MDIO operation timed out\n", am->mii_bus->name);
-
- return -ETIMEDOUT;
-}
-
-static int ag71xx_mdio_mii_read(struct mii_bus *bus, int addr, int reg)
-{
- struct ag71xx_mdio *am = bus->priv;
- int err;
- int ret;
-
- err = ag71xx_mdio_wait_busy(am);
- if (err)
- return 0xffff;
-
- regmap_write(am->mii_regmap, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
- regmap_write(am->mii_regmap, AG71XX_REG_MII_ADDR,
- ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
- regmap_write(am->mii_regmap, AG71XX_REG_MII_CMD, MII_CMD_READ);
-
- err = ag71xx_mdio_wait_busy(am);
- if (err)
- return 0xffff;
-
- regmap_read(am->mii_regmap, AG71XX_REG_MII_STATUS, &ret);
- ret &= 0xffff;
- regmap_write(am->mii_regmap, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
-
- DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
-
- return ret;
-}
-
-static int ag71xx_mdio_mii_write(struct mii_bus *bus, int addr, int reg, u16 val)
-{
- struct ag71xx_mdio *am = bus->priv;
-
- DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
-
- regmap_write(am->mii_regmap, AG71XX_REG_MII_ADDR,
- ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
- regmap_write(am->mii_regmap, AG71XX_REG_MII_CTRL, val);
-
- ag71xx_mdio_wait_busy(am);
-
- return 0;
-}
-
-static const u32 ar71xx_mdio_div_table[] = {
- 4, 4, 6, 8, 10, 14, 20, 28,
-};
-
-static const u32 ar7240_mdio_div_table[] = {
- 2, 2, 4, 6, 8, 12, 18, 26, 32, 40, 48, 56, 62, 70, 78, 96,
-};
-
-static const u32 ar933x_mdio_div_table[] = {
- 4, 4, 6, 8, 10, 14, 20, 28, 34, 42, 50, 58, 66, 74, 82, 98,
-};
-
-static int ag71xx_mdio_get_divider(struct device_node *np, u32 *div)
-{
- struct clk *ref_clk = of_clk_get(np, 0);
- unsigned long ref_clock;
- u32 mdio_clock;
- const u32 *table;
- int ndivs, i;
-
- if (IS_ERR(ref_clk))
- return -EINVAL;
-
- ref_clock = clk_get_rate(ref_clk);
- clk_put(ref_clk);
-
- if(of_property_read_u32(np, "qca,mdio-max-frequency", &mdio_clock)) {
- if (of_property_read_bool(np, "builtin-switch"))
- mdio_clock = 5000000;
- else
- mdio_clock = 2000000;
- }
-
- if (of_device_is_compatible(np, "qca,ar9330-mdio") ||
- of_device_is_compatible(np, "qca,ar9340-mdio")) {
- table = ar933x_mdio_div_table;
- ndivs = ARRAY_SIZE(ar933x_mdio_div_table);
- } else if (of_device_is_compatible(np, "qca,ar7240-mdio")) {
- table = ar7240_mdio_div_table;
- ndivs = ARRAY_SIZE(ar7240_mdio_div_table);
- } else {
- table = ar71xx_mdio_div_table;
- ndivs = ARRAY_SIZE(ar71xx_mdio_div_table);
- }
-
- for (i = 0; i < ndivs; i++) {
- unsigned long t;
-
- t = ref_clock / table[i];
- if (t <= mdio_clock) {
- *div = i;
- return 0;
- }
- }
-
- return -ENOENT;
-}
-
-static int ag71xx_mdio_reset(struct mii_bus *bus)
-{
- struct device_node *np = bus->dev.of_node;
- struct ag71xx_mdio *am = bus->priv;
- bool builtin_switch;
- u32 t;
-
- builtin_switch = of_property_read_bool(np, "builtin-switch");
-
- if (ag71xx_mdio_get_divider(np, &t)) {
- if (of_device_is_compatible(np, "qca,ar9340-mdio"))
- t = MII_CFG_CLK_DIV_58;
- else if (builtin_switch)
- t = MII_CFG_CLK_DIV_10;
- else
- t = MII_CFG_CLK_DIV_28;
- }
-
- regmap_write(am->mii_regmap, AG71XX_REG_MII_CFG, t | MII_CFG_RESET);
- udelay(100);
-
- regmap_write(am->mii_regmap, AG71XX_REG_MII_CFG, t);
- udelay(100);
-
- return 0;
-}
-
-static int ag71xx_mdio_probe(struct platform_device *pdev)
-{
- struct device *amdev = &pdev->dev;
- struct device_node *np = pdev->dev.of_node;
- struct ag71xx_mdio *am;
- struct mii_bus *mii_bus;
- bool builtin_switch;
- int i, err;
-
- am = devm_kzalloc(amdev, sizeof(*am), GFP_KERNEL);
- if (!am)
- return -ENOMEM;
-
- am->mii_regmap = syscon_regmap_lookup_by_phandle(np, "regmap");
- if (IS_ERR(am->mii_regmap))
- return PTR_ERR(am->mii_regmap);
-
- mii_bus = devm_mdiobus_alloc(amdev);
- if (!mii_bus)
- return -ENOMEM;
-
- am->mdio_reset = devm_reset_control_get_exclusive(amdev, "mdio");
- builtin_switch = of_property_read_bool(np, "builtin-switch");
-
- mii_bus->name = "ag71xx_mdio";
- mii_bus->read = ag71xx_mdio_mii_read;
- mii_bus->write = ag71xx_mdio_mii_write;
- mii_bus->reset = ag71xx_mdio_reset;
- mii_bus->priv = am;
- mii_bus->parent = amdev;
- snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s.%d", np->name, bus_count++);
-
- for (i = 0; i < PHY_MAX_ADDR; i++)
- mii_bus->irq[i] = PHY_POLL;
-
- if (!IS_ERR(am->mdio_reset)) {
- reset_control_assert(am->mdio_reset);
- msleep(100);
- reset_control_deassert(am->mdio_reset);
- msleep(200);
- }
-
- err = of_mdiobus_register(mii_bus, np);
- if (err)
- return err;
-
- am->mii_bus = mii_bus;
- platform_set_drvdata(pdev, am);
-
- return 0;
-}
-
-static int ag71xx_mdio_remove(struct platform_device *pdev)
-{
- struct ag71xx_mdio *am = platform_get_drvdata(pdev);
-
- mdiobus_unregister(am->mii_bus);
- return 0;
-}
-
-static const struct of_device_id ag71xx_mdio_match[] = {
- { .compatible = "qca,ar7240-mdio" },
- { .compatible = "qca,ar9330-mdio" },
- { .compatible = "qca,ar9340-mdio" },
- { .compatible = "qca,ath79-mdio" },
- {}
-};
-
-static struct platform_driver ag71xx_mdio_driver = {
- .probe = ag71xx_mdio_probe,
- .remove = ag71xx_mdio_remove,
- .driver = {
- .name = "ag71xx-mdio",
- .of_match_table = ag71xx_mdio_match,
- }
-};
-
-module_platform_driver(ag71xx_mdio_driver);
-MODULE_LICENSE("GPL");
diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network
index 7905d6e496..742892a2f3 100644
--- a/target/linux/ath79/generic/base-files/etc/board.d/02_network
+++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network
@@ -52,6 +52,7 @@ ath79_setup_interfaces()
glinet,gl-ar300m-lite|\
glinet,gl-usb150|\
hak5,wifi-pineapple-nano|\
+ huawei,ap6010dn|\
meraki,mr16|\
netgear,ex7300|\
netgear,ex7300-v2|\
@@ -711,9 +712,6 @@ ath79_setup_macs()
lan_mac=$(mtd_get_mac_ascii devdata "lanmac")
wan_mac=$(mtd_get_mac_ascii devdata "wanmac")
;;
- elecom,wab-i1750-ps|\
- elecom,wab-s1167-ps|\
- elecom,wab-s600-ps|\
engenius,ecb1200|\
engenius,ecb1750)
lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr)
@@ -783,7 +781,6 @@ ath79_setup_macs()
label_mac=$wan_mac
;;
nec,wg800hp)
- lan_mac=$(mtd_get_mac_text board_data 0x280)
wan_mac=$(mtd_get_mac_text board_data 0x480)
label_mac=$wan_mac
;;
diff --git a/target/linux/ath79/generic/base-files/etc/board.d/03_gpio_switches b/target/linux/ath79/generic/base-files/etc/board.d/03_gpio_switches
index 279f518409..d5b41dc0b8 100644
--- a/target/linux/ath79/generic/base-files/etc/board.d/03_gpio_switches
+++ b/target/linux/ath79/generic/base-files/etc/board.d/03_gpio_switches
@@ -11,62 +11,62 @@ board=$(board_name)
case "$board" in
adtran,bsap1800-v2|\
adtran,bsap1840)
- ucidef_add_gpio_switch "wifi1_ext_a" "5GHz External Antenna A" "489" "1"
- ucidef_add_gpio_switch "wifi1_int_a" "5GHz Internal Antenna A" "493"
- ucidef_add_gpio_switch "wifi1_ext_b" "5GHz External Antenna B" "494" "1"
- ucidef_add_gpio_switch "wifi1_int_b" "5GHz Internal Antenna B" "495"
- ucidef_add_gpio_switch "wifi1_ext_c" "5GHz External Antenna C" "496" "1"
- ucidef_add_gpio_switch "wifi1_int_c" "5GHz Internal Antenna C" "497"
- ucidef_add_gpio_switch "wifi0_ext_a" "2.4GHz External Antenna A" "505" "1"
- ucidef_add_gpio_switch "wifi0_int_a" "2.4GHz Internal Antenna A" "506"
- ucidef_add_gpio_switch "wifi0_ext_b" "2.4GHz External Antenna B" "507" "1"
- ucidef_add_gpio_switch "wifi0_int_b" "2.4GHz Internal Antenna B" "508"
- ucidef_add_gpio_switch "wifi0_ext_c" "2.4GHz External Antenna C" "509" "1"
- ucidef_add_gpio_switch "wifi0_int_c" "2.4GHz Internal Antenna C" "510"
+ ucidef_add_gpio_switch "wifi1_ext_a" "5GHz External Antenna A" "534" "1"
+ ucidef_add_gpio_switch "wifi1_int_a" "5GHz Internal Antenna A" "535"
+ ucidef_add_gpio_switch "wifi1_ext_b" "5GHz External Antenna B" "536" "1"
+ ucidef_add_gpio_switch "wifi1_int_b" "5GHz Internal Antenna B" "537"
+ ucidef_add_gpio_switch "wifi1_ext_c" "5GHz External Antenna C" "538" "1"
+ ucidef_add_gpio_switch "wifi1_int_c" "5GHz Internal Antenna C" "539"
+ ucidef_add_gpio_switch "wifi0_ext_a" "2.4GHz External Antenna A" "527" "1"
+ ucidef_add_gpio_switch "wifi0_int_a" "2.4GHz Internal Antenna A" "528"
+ ucidef_add_gpio_switch "wifi0_ext_b" "2.4GHz External Antenna B" "529" "1"
+ ucidef_add_gpio_switch "wifi0_int_b" "2.4GHz Internal Antenna B" "530"
+ ucidef_add_gpio_switch "wifi0_ext_c" "2.4GHz External Antenna C" "531" "1"
+ ucidef_add_gpio_switch "wifi0_int_c" "2.4GHz Internal Antenna C" "532"
;;
asus,pl-ac56)
- ucidef_add_gpio_switch "plc_enable" "PLC enable" "14" "1"
+ ucidef_add_gpio_switch "plc_enable" "PLC enable" "526" "1"
;;
comfast,cf-e5|\
telco,t1)
- ucidef_add_gpio_switch "lte_power" "LTE Power" "14" "1"
- ucidef_add_gpio_switch "lte_wakeup" "LTE Wakeup" "11" "1"
- ucidef_add_gpio_switch "lte_poweroff" "LTE Poweroff" "1" "1"
- ucidef_add_gpio_switch "lte_reset" "LTE Reset" "12" "1"
+ ucidef_add_gpio_switch "lte_power" "LTE Power" "526" "1"
+ ucidef_add_gpio_switch "lte_wakeup" "LTE Wakeup" "523" "1"
+ ucidef_add_gpio_switch "lte_poweroff" "LTE Poweroff" "513" "1"
+ ucidef_add_gpio_switch "lte_reset" "LTE Reset" "524" "1"
;;
devolo,dlan-pro-1200plus-ac)
- ucidef_add_gpio_switch "plc_enable" "PLC enable" "13" "0"
+ ucidef_add_gpio_switch "plc_enable" "PLC enable" "525" "0"
;;
devolo,magic-2-wifi)
- ucidef_add_gpio_switch "plc_pairing" "PLC pairing" "11" "1"
- ucidef_add_gpio_switch "plc_enable" "PLC enable" "13" "1"
+ ucidef_add_gpio_switch "plc_pairing" "PLC pairing" "523" "1"
+ ucidef_add_gpio_switch "plc_enable" "PLC enable" "525" "1"
;;
dlink,dir-825-c1|\
dlink,dir-835-a1)
- ucidef_add_gpio_switch "wan_led_auto" "WAN LED Auto" "20" "0"
+ ucidef_add_gpio_switch "wan_led_auto" "WAN LED Auto" "532" "0"
;;
librerouter,librerouter-v1)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "1" "0"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "513" "0"
;;
teltonika,rut955)
- ucidef_add_gpio_switch "sim_sel" "SIM select" "503" "1"
- ucidef_add_gpio_switch "DOUT1" "DOUT1 (OC)" "504" "0"
- ucidef_add_gpio_switch "DOUT2" "DOUT2 (Relay)" "505" "0"
- ucidef_add_gpio_switch "modem_vbus" "Modem enable" "506" "1"
- ucidef_add_gpio_switch "modem_rst" "Modem reset" "507" "0"
- ucidef_add_gpio_switch "DOUT3" "DOUT3" "508" "0"
+ ucidef_add_gpio_switch "sim_sel" "SIM select" "542" "1"
+ ucidef_add_gpio_switch "DOUT1" "DOUT1 (OC)" "543" "0"
+ ucidef_add_gpio_switch "DOUT2" "DOUT2 (Relay)" "544" "0"
+ ucidef_add_gpio_switch "modem_vbus" "Modem enable" "545" "1"
+ ucidef_add_gpio_switch "modem_rst" "Modem reset" "546" "0"
+ ucidef_add_gpio_switch "DOUT3" "DOUT3" "547" "0"
;;
teltonika,rut955-h7v3c0)
- ucidef_add_gpio_switch "sim_sel" "SIM select" "503" "1"
- ucidef_add_gpio_switch "DOUT1" "DOUT1 (OC)" "504" "0"
- ucidef_add_gpio_switch "DOUT2" "DOUT2 (Relay)" "505" "0"
- ucidef_add_gpio_switch "modem_vbus" "Modem enable" "508" "1"
- ucidef_add_gpio_switch "modem_rst" "Modem reset" "509" "0"
+ ucidef_add_gpio_switch "sim_sel" "SIM select" "542" "1"
+ ucidef_add_gpio_switch "DOUT1" "DOUT1 (OC)" "543" "0"
+ ucidef_add_gpio_switch "DOUT2" "DOUT2 (Relay)" "544" "0"
+ ucidef_add_gpio_switch "modem_vbus" "Modem enable" "547" "1"
+ ucidef_add_gpio_switch "modem_rst" "Modem reset" "548" "0"
;;
tplink,archer-c25-v1)
- ucidef_add_gpio_switch "led_control" "LED control" "21" "0"
- ucidef_add_gpio_switch "led_reset" "LED reset" "19" "1"
+ ucidef_add_gpio_switch "led_control" "LED control" "533" "0"
+ ucidef_add_gpio_switch "led_reset" "LED reset" "531" "1"
;;
tplink,cpe210-v1|\
tplink,cpe220-v2|\
@@ -76,31 +76,31 @@ tplink,wbs210-v1|\
tplink,wbs210-v2|\
tplink,wbs510-v1|\
tplink,wbs510-v2)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "20"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "532"
;;
ubnt,aircube-ac|\
ubnt,nanobeam-ac-gen2|\
ubnt,nanostation-ac)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "3"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "515"
;;
ubnt,aircube-isp)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "11"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "523"
;;
ubnt,nanostation-m)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "8"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "520"
;;
ubnt,nanostation-m-xw)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "2"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "514"
;;
ubnt,uk-ultra)
- ucidef_add_gpio_switch "ant0_internal" "ANT0 Internal" "5" "1"
- ucidef_add_gpio_switch "ant1_internal" "ANT1 Internal" "6" "1"
+ ucidef_add_gpio_switch "ant0_internal" "ANT0 Internal" "517" "1"
+ ucidef_add_gpio_switch "ant1_internal" "ANT1 Internal" "518" "1"
;;
zbtlink,zbt-wd323)
- ucidef_add_gpio_switch "io0" "IO#0" "0"
- ucidef_add_gpio_switch "io1" "IO#1" "1"
- ucidef_add_gpio_switch "io2" "IO#2" "2"
- ucidef_add_gpio_switch "io14" "IO#14" "14"
+ ucidef_add_gpio_switch "io0" "IO#0" "512"
+ ucidef_add_gpio_switch "io1" "IO#1" "513"
+ ucidef_add_gpio_switch "io2" "IO#2" "514"
+ ucidef_add_gpio_switch "io14" "IO#14" "526"
;;
esac
diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
index ddcef7b685..6341c56a8b 100644
--- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
+++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
@@ -30,8 +30,6 @@ case "$FIRMWARE" in
dlink,dir-842-c1|\
dlink,dir-842-c2|\
dlink,dir-842-c3|\
- nec,wf1200cr|\
- nec,wg1200cr|\
wd,mynet-n600|\
wd,mynet-n750)
caldata_extract "art" 0x1000 0x440
@@ -63,14 +61,6 @@ case "$FIRMWARE" in
caldata_extract "art" 0x1000 0x440
ath9k_patch_mac $(mtd_get_mac_ascii u-boot-env mac_addr)
;;
- nec,wg800hp)
- caldata_extract "art" 0x1000 0x440
- ath9k_patch_mac $(mtd_get_mac_text board_data 0x680)
- ;;
- qihoo,c301)
- caldata_extract "radiocfg" 0x1000 0x440
- ath9k_patch_mac $(mtd_get_mac_ascii devdata "wlan24mac")
- ;;
tplink,deco-s4-v2)
caldata_extract "art" 0x1000 0x440
base_mac=$(mtd_get_mac_encrypted_deco $(find_mtd_part config))
diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
index 2a1f230eb4..6676e4d509 100644
--- a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
+++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
@@ -42,16 +42,6 @@ case "$board" in
[ "$PHYNBR" -eq 1 ] && \
mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress
;;
- elecom,wab-i1750-ps|\
- elecom,wab-s1167-ps|\
- elecom,wab-s600-ps)
- # set the 5G MAC address (= ethaddr + 1)
- [ "$PHYNBR" -eq 0 ] && \
- macaddr_add "$(mtd_get_mac_ascii u-boot-env ethaddr)" 1 > /sys${DEVPATH}/macaddress
- # set the 2.4G MAC address (= ethaddr)
- [ "$PHYNBR" -eq 1 ] && \
- mtd_get_mac_ascii u-boot-env "ethaddr" > /sys${DEVPATH}/macaddress
- ;;
engenius,ecb1200|\
engenius,ecb1750)
[ "$PHYNBR" -eq 0 ] && \
@@ -93,6 +83,8 @@ case "$board" in
qihoo,c301)
[ "$PHYNBR" -eq 0 ] && \
mtd_get_mac_ascii devdata wlan5mac > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" -eq 1 ] && \
+ mtd_get_mac_ascii devdata wlan24mac > /sys${DEVPATH}/macaddress
;;
phicomm,k2t)
[ "$PHYNBR" -eq 0 ] && \
diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh
index 076a785cbf..c61c48b00e 100644
--- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh
@@ -68,7 +68,8 @@ platform_do_upgrade() {
ROOTFS_FILE="root.squashfs"
platform_do_upgrade_failsafe_datachk "$1"
;;
- huawei,ap5030dn)
+ huawei,ap5030dn|\
+ huawei,ap6010dn)
# Store beginning address of the "firmware" partition
# as KernelA address and KernelB address, each to BootupA & BootupB
# This is the address from which the bootloader will try to load the kernel.
diff --git a/target/linux/ath79/generic/config-default b/target/linux/ath79/generic/config-default
index a37d341821..1141d7ae47 100644
--- a/target/linux/ath79/generic/config-default
+++ b/target/linux/ath79/generic/config-default
@@ -20,8 +20,6 @@ CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
CONFIG_MTD_SPLIT_EVA_FW=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVMEM_U_BOOT_ENV=y
-CONFIG_PHY_AR7100_USB=y
-CONFIG_PHY_AR7200_USB=y
CONFIG_REALTEK_PHY=y
CONFIG_REGMAP_I2C=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
diff --git a/target/linux/ath79/image/common-nec.mk b/target/linux/ath79/image/common-nec.mk
new file mode 100644
index 0000000000..7981a72d8e
--- /dev/null
+++ b/target/linux/ath79/image/common-nec.mk
@@ -0,0 +1,25 @@
+DEVICE_VARS += NEC_FW_TYPE
+
+define Build/nec-usbaterm-fw
+ $(STAGING_DIR_HOST)/bin/nec-usbatermfw $@.new -t $(NEC_FW_TYPE) $(1)
+ mv $@.new $@
+endef
+
+define Device/nec-netbsd-aterm
+ DEVICE_VENDOR := NEC
+ LOADER_TYPE := bin
+ KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | uImage none
+ KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | uImage none
+ ARTIFACTS := uboot.bin
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+ COMPILE := loader-$(1).bin
+ COMPILE/loader-$(1).bin := loader-okli-compile
+ ARTIFACTS += initramfs-factory.bin
+ ARTIFACT/initramfs-factory.bin := append-image-stage initramfs-kernel.bin | \
+ pad-to 4 skip=16 | \
+ nec-usbaterm-fw -f 0x0003 -d $$(KDIR)/loader-$(1).bin -d $$$$@ | check-size
+endif
+ UBOOT_PATH := $$(STAGING_DIR_IMAGE)/$$(SOC)_nec_aterm-u-boot.bin
+ ARTIFACT/uboot.bin := append-uboot | check-size 128k
+ DEVICE_PACKAGES := kmod-usb2 -uboot-envtools
+endef
diff --git a/target/linux/ath79/image/generic-ubnt.mk b/target/linux/ath79/image/generic-ubnt.mk
index f7bab4b697..2faf51949a 100644
--- a/target/linux/ath79/image/generic-ubnt.mk
+++ b/target/linux/ath79/image/generic-ubnt.mk
@@ -24,6 +24,7 @@ define Device/ubnt_amplifi-router-hd
UBNT_TYPE := AFi-R
UBNT_VERSION := 3.6.3
SOC := qca9563
+ DEVICE_VENDOR := Ubiquiti
DEVICE_MODEL := AmpliFi Router HD
UBNT_CHIP := qca956x
DEVICE_PACKAGES += kmod-ath10k-ct-smallbuffers ath10k-firmware-qca988x-ct kmod-usb2
diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk
index f6dba8604d..459d595a42 100644
--- a/target/linux/ath79/image/generic.mk
+++ b/target/linux/ath79/image/generic.mk
@@ -1806,6 +1806,21 @@ define Device/huawei_ap5030dn
endef
TARGET_DEVICES += huawei_ap5030dn
+define Device/huawei_ap6010dn
+ SOC := ar9344
+ DEVICE_VENDOR := Huawei
+ DEVICE_MODEL := AP6010DN
+ LOADER_TYPE := bin
+ LOADER_FLASH_OFFS := 0x111DC0
+ KERNEL_SIZE := 15360k
+ IMAGE_SIZE := 30720k
+ COMPILE := loader-$(1).bin
+ COMPILE/loader-$(1).bin := loader-okli-compile | pad-to 64k | uImage none
+ KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49 | loader-okli $(1) 8128
+ KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | uImage none
+endef
+TARGET_DEVICES += huawei_ap6010dn
+
define Device/iodata_etg3-r
SOC := ar9342
DEVICE_VENDOR := I-O DATA
@@ -2898,10 +2913,9 @@ endef
TARGET_DEVICES += sitecom_wlr-8100
define Device/sophos_ap15
- SOC := qca9558
+ SOC := qca9557
DEVICE_VENDOR := Sophos
DEVICE_MODEL := AP15
- DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct
IMAGE_SIZE := 15936k
endef
TARGET_DEVICES += sophos_ap15
@@ -3248,7 +3262,7 @@ TARGET_DEVICES += zbtlink_zbt-wd323
define Device/zyxel_nwa11xx
$(Device/loader-okli-uimage)
SOC := ar9342
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
LOADER_FLASH_OFFS := 0x050000
KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49
IMAGE_SIZE := 8192k
@@ -3295,7 +3309,7 @@ TARGET_DEVICES += zyxel_nwa1123-ni
define Device/zyxel_nbg6616
SOC := qca9557
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6616
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-rtc-pcf8563 \
kmod-ath10k-ct ath10k-firmware-qca988x-ct
diff --git a/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h b/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h
index e7d7683973..9dc7c0f817 100644
--- a/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h
+++ b/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h
@@ -670,6 +670,7 @@
#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13)
#define AR934X_GPIO_OUT_GPIO 0x00
+#define AR934X_GPIO_OUTSEL_CLK_OBS4 0x14
#define QCA955X_GPIO_OUTSEL_CLK_OBS5 0x54
diff --git a/target/linux/ath79/image/lzma-loader/src/board.c b/target/linux/ath79/image/lzma-loader/src/board.c
index 13926e9b1e..0d92f3174b 100644
--- a/target/linux/ath79/image/lzma-loader/src/board.c
+++ b/target/linux/ath79/image/lzma-loader/src/board.c
@@ -182,34 +182,107 @@ static inline void mr18_init(void)
static inline void mr18_init(void) { }
#endif
-#ifdef CONFIG_BOARD_HUAWEI_AP5030DN
-static inline void ap5030dn_init(void)
+#if defined(CONFIG_BOARD_HUAWEI_AP5030DN) || defined(CONFIG_BOARD_HUAWEI_AP6010DN)
+static inline void huawei_ap_init(void)
{
- const unsigned int ap5030dn_watchdog_gpio = 15;
+ const unsigned int watchdog_gpio = 15;
unsigned int gpiobase, reg;
gpiobase = KSEG1ADDR(AR71XX_GPIO_BASE);
- printf("Huawei AP5030DN\n");
+ printf("Huawei AP\n");
reg = READREG(gpiobase + AR71XX_GPIO_REG_OE);
WRITEREG(gpiobase + AR71XX_GPIO_REG_OE,
- reg & ~(1 << ap5030dn_watchdog_gpio));
+ reg & ~(1 << watchdog_gpio));
/* Set GPIO15 MUX to output CLK_OBS5 (= CPU_CLK/4)
- * to keep the watchdog happy until wdt-gpio takes over
+ * or CLK_OBS4 (= AHB_CLK/2) to keep the watchdog happy
+ * until wdt-gpio takes over
*/
reg = READREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3);
+#if defined(CONFIG_BOARD_HUAWEI_AP5030DN)
WRITEREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3,
reg | (QCA955X_GPIO_OUTSEL_CLK_OBS5 << 24));
+#else if defined(CONFIG_BOARD_HUAWEI_AP6010DN)
+ WRITEREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3,
+ reg | (AR934X_GPIO_OUTSEL_CLK_OBS4 << 24));
+#endif
+}
+#else
+static inline void huawei_ap_init(void) {}
+#endif
+
+#if defined(CONFIG_BOARD_NEC_WG600HP) || \
+ defined(CONFIG_BOARD_NEC_WR8750N) || \
+ defined(CONFIG_BOARD_NEC_WR9500N)
+
+#define AR934X_PLL_SWITCH_CLK_CTRL_REG 0x24
+#define AR934X_PLL_SWITCH_CLK_CTRL_SWITCHCLK_SEL BIT(0)
+
+static inline void nec_aterm_init(void)
+{
+ unsigned int reg, val;
+
+ printf("NEC Aterm series (AR9344)\n");
+
+ /* set REFCLK=40MHz to switch PLL */
+ reg = KSEG1ADDR(AR71XX_PLL_BASE);
+ val = READREG(reg + AR934X_PLL_SWITCH_CLK_CTRL_REG);
+ val &= ~AR934X_PLL_SWITCH_CLK_CTRL_SWITCHCLK_SEL;
+ WRITEREG(reg + AR934X_PLL_SWITCH_CLK_CTRL_REG, val);
+
+ reg = KSEG1ADDR(AR71XX_RESET_BASE);
+#ifndef LOADADDR
+ /*
+ * This is for initramfs-factory image.
+ * When the system was reset by power source or FULL_CHIP_RESET
+ * and started from the OEM bootloader with a dummy tp data
+ * (this loader), reset again by timeout of the watchdog timer
+ * to load an actual OpenWrt initramfs image in firmware block
+ * in a factory image.
+ * Note: On the stock firmware, TP block contains a POST function
+ * and sub commands of "tp" command.
+ *
+ * Behaviors of OEM bootloader:
+ *
+ * - reset by watchdog (ex.: rebooting on the stock firmware):
+ * called as "SOFT-RESET", boot a firmware without POST
+ *
+ * - reset by FULL_CHIP_RESET (or powering on):
+ * called as "HARD-RESET", run POST and boot a firmware
+ */
+ printf("\n## booted with dummy tp (lzma-loader),"
+ " waiting reset... (count: 0x%08x) ##\n",
+ READREG(reg + AR71XX_RESET_REG_WDOG));
+ while (1);
+#endif
+ /*
+ * set maximum watchdog count to avoid reset while
+ * booting from stock bootloader
+ */
+ WRITEREG(reg + AR71XX_RESET_REG_WDOG, 0xffffffff);
+
+ /*
+ * deassert some RESET bits not handled by drivers
+ * and mainline U-Boot
+ *
+ * - ETH_SWITCH(_ANALOG): eth0
+ * - RTC : wmac
+ */
+ val = READREG(reg + AR934X_RESET_REG_RESET_MODULE);
+ val &= ~(AR934X_RESET_ETH_SWITCH | AR934X_RESET_ETH_SWITCH_ANALOG |
+ AR934X_RESET_RTC);
+ WRITEREG(reg + AR934X_RESET_REG_RESET_MODULE, val);
}
#else
-static inline void ap5030dn_init(void) { }
+static inline void nec_aterm_init(void) {}
#endif
void board_init(void)
{
tlwr1043nd_init();
mr18_init();
- ap5030dn_init();
+ huawei_ap_init();
+ nec_aterm_init();
}
diff --git a/target/linux/ath79/image/nand.mk b/target/linux/ath79/image/nand.mk
index 1a7eebc92a..a3bdedaf6d 100644
--- a/target/linux/ath79/image/nand.mk
+++ b/target/linux/ath79/image/nand.mk
@@ -487,7 +487,7 @@ TARGET_DEVICES += zte_mf286r
define Device/zyxel_nbg6716
SOC := qca9558
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6716
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct \
ath10k-firmware-qca988x-ct
diff --git a/target/linux/ath79/image/tiny.mk b/target/linux/ath79/image/tiny.mk
index 955d0fbff2..53111119d8 100644
--- a/target/linux/ath79/image/tiny.mk
+++ b/target/linux/ath79/image/tiny.mk
@@ -1,4 +1,5 @@
include ./common-buffalo.mk
+include ./common-nec.mk
include ./common-senao.mk
define Device/buffalo_whr-g301n
@@ -120,6 +121,36 @@ define Device/engenius_enh202-v1
endef
TARGET_DEVICES += engenius_enh202-v1
+define Device/nec_wg600hp
+ DEVICE_MODEL := Aterm WG600HP
+ SOC := ar9344
+ BLOCKSIZE := 4k
+ IMAGE_SIZE := 7936k
+ NEC_FW_TYPE := H044
+ $(Device/nec-netbsd-aterm)
+endef
+TARGET_DEVICES += nec_wg600hp
+
+define Device/nec_wr8750n
+ SOC := ar9344
+ DEVICE_MODEL := Aterm WR8750N
+ BLOCKSIZE := 4k
+ IMAGE_SIZE := 7936k
+ NEC_FW_TYPE := H033a
+ $(Device/nec-netbsd-aterm)
+endef
+TARGET_DEVICES += nec_wr8750n
+
+define Device/nec_wr9500n
+ SOC := ar9344
+ DEVICE_MODEL := Aterm WR9500N
+ BLOCKSIZE := 4k
+ IMAGE_SIZE := 16128k
+ NEC_FW_TYPE := H033
+ $(Device/nec-netbsd-aterm)
+endef
+TARGET_DEVICES += nec_wr9500n
+
define Device/pqi_air-pen
SOC := ar9330
DEVICE_VENDOR := PQI
diff --git a/target/linux/ath79/mikrotik/config-default b/target/linux/ath79/mikrotik/config-default
index 71b64b26ad..0dd79d9adc 100644
--- a/target/linux/ath79/mikrotik/config-default
+++ b/target/linux/ath79/mikrotik/config-default
@@ -35,8 +35,6 @@ CONFIG_NET_DSA=y
CONFIG_NET_SWITCHDEV=y
# CONFIG_NVMEM_LAYOUT_MIKROTIK is not set
CONFIG_PHYLINK=y
-CONFIG_PHY_AR7100_USB=y
-CONFIG_PHY_AR7200_USB=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_SGL_ALLOC=y
CONFIG_SPI_RB4XX=y
diff --git a/target/linux/ath79/nand/base-files/etc/board.d/03_gpio_switches b/target/linux/ath79/nand/base-files/etc/board.d/03_gpio_switches
index 775778a2be..1fe83bc65c 100644
--- a/target/linux/ath79/nand/base-files/etc/board.d/03_gpio_switches
+++ b/target/linux/ath79/nand/base-files/etc/board.d/03_gpio_switches
@@ -11,7 +11,7 @@ board=$(board_name)
case "$board" in
zte,mf286a|\
zte,mf286r)
- ucidef_add_gpio_switch "power_btn_block" "Power button blocker" "20" "0"
+ ucidef_add_gpio_switch "power_btn_block" "Power button blocker" "532" "0"
;;
esac
diff --git a/target/linux/ath79/nand/config-default b/target/linux/ath79/nand/config-default
index dd47d2a3ea..71ce1caad7 100644
--- a/target/linux/ath79/nand/config-default
+++ b/target/linux/ath79/nand/config-default
@@ -18,7 +18,6 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
# CONFIG_PCI_AR71XX is not set
-CONFIG_PHY_AR7200_USB=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_SGL_ALLOC=y
diff --git a/target/linux/ath79/patches-6.6/001-v6.11-gpio-ath79-convert-to-dynamic-GPIO-base-allocation.patch b/target/linux/ath79/patches-6.6/001-v6.11-gpio-ath79-convert-to-dynamic-GPIO-base-allocation.patch
new file mode 100644
index 0000000000..4222639d4d
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/001-v6.11-gpio-ath79-convert-to-dynamic-GPIO-base-allocation.patch
@@ -0,0 +1,32 @@
+From 9a473c2a093e0d1c466bf86073230e2c8b658977 Mon Sep 17 00:00:00 2001
+From: Shiji Yang <yangshiji66@outlook.com>
+Date: Wed, 26 Jun 2024 08:33:18 +0800
+Subject: gpio: ath79: convert to dynamic GPIO base allocation
+
+ath79 target has already been converted to device tree based platform.
+Use dynamic GPIO numberspace base to suppress the warning:
+
+gpio gpiochip0: Static allocation of GPIO base is deprecated, use dynamic allocation.
+
+Tested on Atheros AR7241 and AR9344.
+
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+Suggested-by: Jonas Gorski <jonas.gorski@gmail.com>
+Link: https://lore.kernel.org/r/TYCP286MB089598EA71E964BD8AB9EFD3BCD62@TYCP286MB0895.JPNP286.PROD.OUTLOOK.COM
+[Bartosz: tweaked the commit message]
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+---
+ drivers/gpio/gpio-ath79.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/gpio/gpio-ath79.c
++++ b/drivers/gpio/gpio-ath79.c
+@@ -273,8 +273,6 @@ static int ath79_gpio_probe(struct platf
+ dev_err(dev, "bgpio_init failed\n");
+ return err;
+ }
+- /* Use base 0 to stay compatible with legacy platforms */
+- ctrl->gc.base = 0;
+
+ /* Optional interrupt setup */
+ if (!np || of_property_read_bool(np, "interrupt-controller")) {
diff --git a/target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch b/target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch
new file mode 100644
index 0000000000..dfb7e483a7
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch
@@ -0,0 +1,34 @@
+From f2ca10b22ace3ce53b4e3f189bf1dd53a4482475 Mon Sep 17 00:00:00 2001
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+Date: Fri, 26 Apr 2024 23:53:58 +0900
+Subject: [PATCH 1/2] MIPS: pci-ar724x: clear power down of pll on AR934x
+
+Fix PCIe initialization on AR934x by clearing PLL_PWD bit in addition to
+PPL_RESET bit of AR724x.
+
+Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+---
+
+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+@@ -347,6 +347,8 @@
+ #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
+ #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
++#define AR934X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
++
+ #define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+
+ #define QCA953X_PLL_CPU_CONFIG_REG 0x00
+--- a/arch/mips/pci/pci-ar724x.c
++++ b/arch/mips/pci/pci-ar724x.c
+@@ -360,7 +360,8 @@ static void ar724x_pci_hw_init(struct ar
+ } else {
+ /* remove the reset of the PCIE PLL */
+ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
++ ppl &= ~(AR934X_PLL_PCIE_CONFIG_PLL_PWD |
++ AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET);
+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+
+ /* deassert bypass for the PCIE PLL */
diff --git a/target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch b/target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch
new file mode 100644
index 0000000000..c906bdbbb6
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch
@@ -0,0 +1,41 @@
+From 859c93981a8994ffa69967b44b247d2e7d6a01f1 Mon Sep 17 00:00:00 2001
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+Date: Fri, 26 Apr 2024 23:54:57 +0900
+Subject: [PATCH 2/2] MIPS: pci-ar724x: deassert the reset of PCIe endpoint
+
+Fix PCIe initialization by de-assertion of PCIe endpoint reset.
+
+Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+---
+
+--- a/arch/mips/pci/pci-ar724x.c
++++ b/arch/mips/pci/pci-ar724x.c
+@@ -25,6 +25,7 @@
+
+ #define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
+
++#define AR724X_PCI_RESET_EP_RESET_L BIT(2)
+ #define AR724X_PCI_RESET_LINK_UP BIT(0)
+
+ #define AR724X_PCI_INT_DEV0 BIT(14)
+@@ -340,7 +341,7 @@ static void ar724x_pci_irq_init(struct a
+
+ static void ar724x_pci_hw_init(struct ar724x_pci_controller *apc)
+ {
+- u32 ppl, app;
++ u32 ppl, rst, app;
+ int wait = 0;
+
+ /* deassert PCIe host controller and PCIe PHY reset */
+@@ -370,6 +371,11 @@ static void ar724x_pci_hw_init(struct ar
+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+ }
+
++ /* deassert the reset state of the PCIE endpoint */
++ rst = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
++ rst |= AR724X_PCI_RESET_EP_RESET_L;
++ __raw_writel(rst, apc->ctrl_base + AR724X_PCI_REG_RESET);
++
+ /* set PCIE Application Control to ready */
+ app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP);
+ app |= AR724X_PCI_APP_LTSSM_ENABLE;
diff --git a/target/linux/ath79/patches-6.6/330-missing-registers.patch b/target/linux/ath79/patches-6.6/330-missing-registers.patch
index 74789437ec..d05e741c7e 100644
--- a/target/linux/ath79/patches-6.6/330-missing-registers.patch
+++ b/target/linux/ath79/patches-6.6/330-missing-registers.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] ath79: gmac: add parsers for rxd(v)- and tx(d|en)-delay for
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1231,6 +1231,10 @@
+@@ -1233,6 +1233,10 @@
#define AR934X_ETH_CFG_RDV_DELAY BIT(16)
#define AR934X_ETH_CFG_RDV_DELAY_MASK 0x3
#define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16
diff --git a/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch b/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch
index c2f228dfe1..5d9c77c69f 100644
--- a/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch
+++ b/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch
@@ -16,7 +16,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1251,7 +1251,12 @@
+@@ -1253,7 +1253,12 @@
*/
#define QCA955X_GMAC_REG_ETH_CFG 0x00
@@ -29,7 +29,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
#define QCA955X_ETH_CFG_RGMII_EN BIT(0)
#define QCA955X_ETH_CFG_MII_GE0 BIT(1)
-@@ -1273,9 +1278,58 @@
+@@ -1275,9 +1280,58 @@
#define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3
#define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20
diff --git a/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch b/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch
index a6a50e4a8a..6f6217ce75 100644
--- a/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch
+++ b/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch
@@ -21,7 +21,7 @@ Submitted-by: David Bauer <mail@david-bauer.net>
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1380,5 +1380,6 @@
+@@ -1382,5 +1382,6 @@
#define QCA956X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
#define QCA956X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
diff --git a/target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch b/target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch
new file mode 100644
index 0000000000..a3bdf890c4
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch
@@ -0,0 +1,26 @@
+From: John Crispin <john@phrozen.org>
+Subject: ath79: Register GPIO driver earlier
+
+HACK: register the GPIO driver earlier to ensure that gpio_request calls
+from mach files succeed.
+
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ drivers/gpio/gpio-ath79.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpio-ath79.c
++++ b/drivers/gpio/gpio-ath79.c
+@@ -300,7 +300,11 @@ static struct platform_driver ath79_gpio
+ .probe = ath79_gpio_probe,
+ };
+
+-module_platform_driver(ath79_gpio_driver);
++static int __init ath79_gpio_init(void)
++{
++ return platform_driver_register(&ath79_gpio_driver);
++}
++postcore_initcall(ath79_gpio_init);
+
+ MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X GPIO API support");
+ MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch b/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch
index b24ff21692..ae2f5aa0cd 100644
--- a/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch
+++ b/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch
@@ -45,8 +45,8 @@ Submitted-by: Daniel Golle <daniel@makrotopia.org>
goto err_iounmap;
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -348,6 +348,7 @@
- #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+@@ -350,6 +350,7 @@
+ #define AR934X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
diff --git a/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch b/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch
index 603750cbe9..fc4c3804a7 100644
--- a/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch
+++ b/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch
@@ -9,7 +9,7 @@ SVN-Revision: 33385
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -543,4 +543,12 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
+@@ -542,4 +542,12 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
load time (assuming you build diskonchip as a module) with the module
parameter "inftl_bbt_write=1".
diff --git a/target/linux/ath79/patches-6.6/710-net-use-downstream-ag71xx.patch b/target/linux/ath79/patches-6.6/710-net-use-downstream-ag71xx.patch
index 54e64fb11c..0997aa1ab8 100644
--- a/target/linux/ath79/patches-6.6/710-net-use-downstream-ag71xx.patch
+++ b/target/linux/ath79/patches-6.6/710-net-use-downstream-ag71xx.patch
@@ -13,30 +13,22 @@ Submitted-by: John Crispin <john@phrozen.org>
--- a/drivers/net/ethernet/atheros/Kconfig
+++ b/drivers/net/ethernet/atheros/Kconfig
-@@ -17,14 +17,7 @@ config NET_VENDOR_ATHEROS
+@@ -26,6 +26,8 @@ config AG71XX
+ If you wish to compile a kernel for AR7XXX/91XXX and enable
+ ethernet support, then you should always answer Y to this.
- if NET_VENDOR_ATHEROS
-
--config AG71XX
-- tristate "Atheros AR7XXX/AR9XXX built-in ethernet mac support"
-- depends on ATH79
-- select PHYLINK
-- imply NET_SELFTESTS
-- help
-- If you wish to compile a kernel for AR7XXX/91XXX and enable
-- ethernet support, then you should always answer Y to this.
+source "drivers/net/ethernet/atheros/ag71xx/Kconfig"
-
++
config ATL2
tristate "Atheros L2 Fast Ethernet support"
+ depends on PCI
--- a/drivers/net/ethernet/atheros/Makefile
+++ b/drivers/net/ethernet/atheros/Makefile
-@@ -3,7 +3,7 @@
- # Makefile for the Atheros network device drivers.
+@@ -4,6 +4,7 @@
#
--obj-$(CONFIG_AG71XX) += ag71xx.o
-+obj-$(CONFIG_AG71XX) += ag71xx/
+ obj-$(CONFIG_AG71XX) += ag71xx.o
++obj-$(CONFIG_AG71XX_LEGACY) += ag71xx/
obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_ATL2) += atlx/
obj-$(CONFIG_ATL1E) += atl1e/
diff --git a/target/linux/ath79/patches-6.6/730-ar8216-make-reg-access-atomic.patch b/target/linux/ath79/patches-6.6/730-ar8216-make-reg-access-atomic.patch
index 02f763534e..16d9005699 100644
--- a/target/linux/ath79/patches-6.6/730-ar8216-make-reg-access-atomic.patch
+++ b/target/linux/ath79/patches-6.6/730-ar8216-make-reg-access-atomic.patch
@@ -14,7 +14,7 @@ with interrupts used.
---
--- a/drivers/net/phy/ar8216.c
+++ b/drivers/net/phy/ar8216.c
-@@ -252,6 +252,7 @@ ar8xxx_mii_write32(struct ar8xxx_priv *p
+@@ -251,6 +251,7 @@ ar8xxx_mii_write32(struct ar8xxx_priv *p
u32
ar8xxx_read(struct ar8xxx_priv *priv, int reg)
{
@@ -22,7 +22,7 @@ with interrupts used.
struct mii_bus *bus = priv->mii_bus;
u16 r1, r2, page;
u32 val;
-@@ -259,11 +260,13 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
+@@ -258,11 +259,13 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
split_addr((u32) reg, &r1, &r2, &page);
mutex_lock(&bus->mdio_lock);
@@ -36,7 +36,7 @@ with interrupts used.
mutex_unlock(&bus->mdio_lock);
return val;
-@@ -272,17 +275,20 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
+@@ -271,17 +274,20 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
void
ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val)
{
diff --git a/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch b/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch
index 980c265fe6..330c0d139b 100644
--- a/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch
+++ b/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch
@@ -22,7 +22,7 @@ Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
-@@ -86,6 +86,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
+@@ -89,6 +89,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
* drawing board.
*/
static const char * const of_irq_imap_abusers[] = {
diff --git a/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch b/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch
index 49a65ec622..720c3bfcdd 100644
--- a/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch
+++ b/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch
@@ -259,7 +259,7 @@ SVN-Revision: 35130
#include <linux/uaccess.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
-@@ -897,10 +898,10 @@ static void tcp_v6_send_response(const s
+@@ -893,10 +894,10 @@ static void tcp_v6_send_response(const s
topt = (__be32 *)(t1 + 1);
if (tsecr) {
@@ -350,7 +350,7 @@ SVN-Revision: 35130
list_for_each_entry(p, head, list) {
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
-@@ -620,48 +620,53 @@ static void tcp_options_write(struct tcp
+@@ -622,48 +622,53 @@ static void tcp_options_write(struct tcp
u16 options = opts->options; /* mungable copy */
if (unlikely(OPTION_MD5 & options)) {
@@ -427,7 +427,7 @@ SVN-Revision: 35130
}
if (unlikely(opts->num_sack_blocks)) {
-@@ -669,16 +674,17 @@ static void tcp_options_write(struct tcp
+@@ -671,16 +676,17 @@ static void tcp_options_write(struct tcp
tp->duplicate_sack : tp->selective_acks;
int this_sack;
@@ -451,7 +451,7 @@ SVN-Revision: 35130
}
tp->rx_opt.dsack = 0;
-@@ -691,13 +697,14 @@ static void tcp_options_write(struct tcp
+@@ -693,13 +699,14 @@ static void tcp_options_write(struct tcp
if (foc->exp) {
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
@@ -751,7 +751,7 @@ SVN-Revision: 35130
EXPORT_SYMBOL(xfrm_parse_spi);
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
-@@ -4188,14 +4188,16 @@ static bool tcp_parse_aligned_timestamp(
+@@ -4221,14 +4221,16 @@ static bool tcp_parse_aligned_timestamp(
{
const __be32 *ptr = (const __be32 *)(th + 1);
@@ -867,7 +867,7 @@ SVN-Revision: 35130
iph->daddr == iph2->daddr && iph->saddr == iph2->saddr)
return segs;
-@@ -255,7 +255,7 @@ struct sk_buff *tcp_gro_lookup(struct li
+@@ -264,7 +264,7 @@ struct sk_buff *tcp_gro_lookup(struct li
continue;
th2 = tcp_hdr(p);
@@ -876,7 +876,7 @@ SVN-Revision: 35130
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
-@@ -321,8 +321,8 @@ struct sk_buff *tcp_gro_receive(struct l
+@@ -330,8 +330,8 @@ struct sk_buff *tcp_gro_receive(struct l
~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
for (i = sizeof(*th); i < thlen; i += 4)
diff --git a/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch b/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch
index 980f29eef1..674cc2fe66 100644
--- a/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch
+++ b/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch
@@ -97,7 +97,7 @@ Submitted-by: Christopher Hill <ch6574@gmail.com>
obj-$(CONFIG_GPIO_RDA) += gpio-rda.o
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -551,4 +551,11 @@ config MTD_NAND_AR934X
+@@ -550,4 +550,11 @@ config MTD_NAND_AR934X
Enables support for NAND controller on Qualcomm Atheros SoCs.
This controller is found on AR934x and QCA955x SoCs.
diff --git a/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch b/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch
index e610a4ff14..ddb7b52cbe 100644
--- a/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch
+++ b/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch
@@ -73,7 +73,7 @@ Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
obj-$(CONFIG_GPIO_RDA) += gpio-rda.o
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -558,4 +558,10 @@ config MTD_NAND_RB4XX
+@@ -557,4 +557,10 @@ config MTD_NAND_RB4XX
Enables support for the NAND flash chip on Mikrotik Routerboard
RB4xx series.
diff --git a/target/linux/ath79/tiny/base-files/etc/board.d/02_network b/target/linux/ath79/tiny/base-files/etc/board.d/02_network
index fa2ea3aa6f..a204e820ca 100644
--- a/target/linux/ath79/tiny/base-files/etc/board.d/02_network
+++ b/target/linux/ath79/tiny/base-files/etc/board.d/02_network
@@ -69,6 +69,13 @@ ath79_setup_interfaces()
ucidef_add_switch "switch0" \
"0@eth1" "4:lan:1"
;;
+ nec,wg600hp|\
+ nec,wr8750n|\
+ nec,wr9500n|\
+ tplink,tl-wr941n-v7-cn)
+ ucidef_add_switch "switch0" \
+ "0@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan"
+ ;;
tplink,tl-mr3220-v1|\
tplink,tl-mr3420-v1|\
tplink,tl-mr3420-v3|\
@@ -105,10 +112,6 @@ ath79_setup_interfaces()
tplink,tl-wr941-v2)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
;;
- tplink,tl-wr941n-v7-cn)
- ucidef_add_switch "switch0" \
- "0@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan"
- ;;
ubnt,airrouter)
ucidef_set_interface_wan "eth1"
ucidef_add_switch "switch0" \
@@ -152,6 +155,12 @@ ath79_setup_macs()
ubnt,picostation-m)
label_mac=$(cat /sys/class/ieee80211/phy0/macaddress)
;;
+ nec,wg600hp|\
+ nec,wr8750n|\
+ nec,wr9500n)
+ wan_mac=$(mtd_get_mac_binary config 0xc)
+ label_mac=$wan_mac
+ ;;
tplink,tl-wr941-v2|\
tplink,tl-wr941n-v7-cn)
base_mac=$(mtd_get_mac_binary u-boot 0x1fc00)
diff --git a/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh b/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh
index eb8441c6d2..8fc0efcfbd 100644
--- a/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh
@@ -9,7 +9,23 @@ RAMFS_COPY_BIN='fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config'
platform_check_image() {
- return 0
+ local board=$(board_name)
+
+ case "$board" in
+ nec,wg600hp|\
+ nec,wr8750n|\
+ nec,wr9500n)
+ local uboot_mtd=$(find_mtd_part "bootloader")
+
+ # check "U-Boot <year>.<month>" string in the "bootloader" partition
+ if ! grep -q "U-Boot [0-9]\{4\}\.[0-9]\{2\}" $uboot_mtd; then
+ v "The bootloader doesn't seem to be replaced to U-Boot!"
+ return 1
+ fi
+ ;;
+ *)
+ return 0
+ esac
}
platform_do_upgrade() {
diff --git a/target/linux/ath79/tiny/config-default b/target/linux/ath79/tiny/config-default
index c738309ce4..e47260df82 100644
--- a/target/linux/ath79/tiny/config-default
+++ b/target/linux/ath79/tiny/config-default
@@ -8,6 +8,4 @@ CONFIG_NET_SWITCHDEV=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVMEM_U_BOOT_ENV=y
CONFIG_PHYLINK=y
-CONFIG_PHY_AR7100_USB=y
-CONFIG_PHY_AR7200_USB=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
diff --git a/target/linux/bcm27xx/base-files/etc/diag.sh b/target/linux/bcm27xx/base-files/etc/diag.sh
index 601448fbe3..c0c8e7f2cf 100644
--- a/target/linux/bcm27xx/base-files/etc/diag.sh
+++ b/target/linux/bcm27xx/base-files/etc/diag.sh
@@ -5,11 +5,23 @@
. /lib/functions.sh
. /lib/functions/leds.sh
+status_led_restore_trigger() {
+ local led_lc=$(echo "$status_led" | awk '{print tolower($0)}')
+ local led_path="/proc/device-tree/leds/led-$led_lc"
+ local led_trigger
+
+ [ -d "$led_path" ] && \
+ led_trigger=$(cat "$led_path/linux,default-trigger" 2>/dev/null)
+
+ [ -n "$led_trigger" ] && \
+ led_set_attr $status_led "trigger" "$led_trigger"
+}
+
set_state() {
- if [ -d "/sys/class/leds/PWR" ]; then
- status_led="PWR"
- else
+ if [ -d "/sys/class/leds/ACT" ]; then
status_led="ACT"
+ else
+ return
fi
case "$1" in
@@ -22,11 +34,11 @@ set_state() {
preinit_regular)
status_led_blink_preinit_regular
;;
- upgrade)
- status_led_blink_preinit_regular
- ;;
+ upgrade)
+ status_led_blink_preinit_regular
+ ;;
done)
- status_led_on
+ status_led_restore_trigger
;;
esac
}
diff --git a/target/linux/bcm27xx/bcm2708/config-6.6 b/target/linux/bcm27xx/bcm2708/config-6.6
index cd978837ea..a50596e45e 100644
--- a/target/linux/bcm27xx/bcm2708/config-6.6
+++ b/target/linux/bcm27xx/bcm2708/config-6.6
@@ -142,8 +142,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -168,7 +166,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FREEZER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
@@ -372,7 +369,6 @@ CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TINY_SRCU=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_UEVENT_HELPER_PATH=""
# CONFIG_UID16 is not set
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
diff --git a/target/linux/bcm27xx/bcm2709/config-6.6 b/target/linux/bcm27xx/bcm2709/config-6.6
index 1a034b3e71..23e93241df 100644
--- a/target/linux/bcm27xx/bcm2709/config-6.6
+++ b/target/linux/bcm27xx/bcm2709/config-6.6
@@ -180,8 +180,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -208,7 +206,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
@@ -466,7 +463,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
# CONFIG_UCLAMP_TASK is not set
diff --git a/target/linux/bcm27xx/bcm2710/config-6.6 b/target/linux/bcm27xx/bcm2710/config-6.6
index 4ab0e03ee2..5b7d6ae4f1 100644
--- a/target/linux/bcm27xx/bcm2710/config-6.6
+++ b/target/linux/bcm27xx/bcm2710/config-6.6
@@ -23,8 +23,6 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_819472=y
CONFIG_ARM64_ERRATUM_824069=y
CONFIG_ARM64_ERRATUM_826319=y
@@ -34,7 +32,6 @@ CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -188,8 +185,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -217,7 +212,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -465,7 +459,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/bcm27xx/bcm2711/config-6.6 b/target/linux/bcm27xx/bcm2711/config-6.6
index 915fe29cae..33458c27d7 100644
--- a/target/linux/bcm27xx/bcm2711/config-6.6
+++ b/target/linux/bcm27xx/bcm2711/config-6.6
@@ -23,13 +23,10 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1319367=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -188,8 +185,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -217,7 +212,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -471,7 +465,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/bcm27xx/bcm2712/config-6.6 b/target/linux/bcm27xx/bcm2712/config-6.6
index f61986338b..734b19612b 100644
--- a/target/linux/bcm27xx/bcm2712/config-6.6
+++ b/target/linux/bcm27xx/bcm2712/config-6.6
@@ -24,15 +24,13 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
CONFIG_ARM64_ERRATUM_1463225=y
+CONFIG_ARM64_ERRATUM_3194386=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -230,8 +228,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -259,7 +255,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -589,7 +584,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/bcm27xx/config-6.6 b/target/linux/bcm27xx/config-6.6
index 55f5523ab5..b44aa9f8a9 100644
--- a/target/linux/bcm27xx/config-6.6
+++ b/target/linux/bcm27xx/config-6.6
@@ -23,6 +23,7 @@
# CONFIG_RASPBERRYPI_GPIOMEM is not set
# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2 is not set
# CONFIG_SENSORS_RP1_ADC is not set
+# CONFIG_SPI_RP2040_GPIO_BRIDGE is not set
# CONFIG_VIDEO_AD5398 is not set
# CONFIG_VIDEO_ARDUCAM_64MP is not set
# CONFIG_VIDEO_ARDUCAM_PIVARIETY is not set
diff --git a/target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch b/target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch
index 6b5bd616e6..5e3446d6f1 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch
@@ -24,16 +24,16 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
-@@ -2221,7 +2221,7 @@ mackey_and_ltk:
+@@ -2215,7 +2215,7 @@ mackey_and_ltk:
if (err)
return SMP_UNSPECIFIED;
- if (smp->method == REQ_OOB) {
+ if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
- if (hcon->out) {
+ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) {
sc_dhkey_check(smp);
SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
-@@ -2236,9 +2236,6 @@ mackey_and_ltk:
+@@ -2230,9 +2230,6 @@ mackey_and_ltk:
confirm_hint = 0;
confirm:
diff --git a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch
index 71ba361232..8a06ec387e 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch
@@ -17,7 +17,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
-@@ -6051,6 +6051,9 @@ int __init cgroup_init_early(void)
+@@ -6060,6 +6060,9 @@ int __init cgroup_init_early(void)
return 0;
}
@@ -27,7 +27,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
/**
* cgroup_init - cgroup initialization
*
-@@ -6084,6 +6087,12 @@ int __init cgroup_init(void)
+@@ -6093,6 +6096,12 @@ int __init cgroup_init(void)
cgroup_unlock();
@@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
for_each_subsys(ss, ssid) {
if (ss->early_init) {
struct cgroup_subsys_state *css =
-@@ -6724,6 +6733,10 @@ static int __init cgroup_disable(char *s
+@@ -6733,6 +6742,10 @@ static int __init cgroup_disable(char *s
strcmp(token, ss->legacy_name))
continue;
@@ -51,7 +51,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
static_branch_disable(cgroup_subsys_enabled_key[i]);
pr_info("Disabling %s control group subsystem\n",
ss->name);
-@@ -6742,6 +6755,31 @@ static int __init cgroup_disable(char *s
+@@ -6751,6 +6764,31 @@ static int __init cgroup_disable(char *s
}
__setup("cgroup_disable=", cgroup_disable);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch b/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch
index cbd2877f51..a83a51eae2 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch
@@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
-@@ -719,7 +719,7 @@ MODULE_DEVICE_TABLE(spi, spidev_spi_ids)
+@@ -721,7 +721,7 @@ MODULE_DEVICE_TABLE(spi, spidev_spi_ids)
*/
static int spidev_of_check(struct device *dev)
{
diff --git a/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch b/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch
index 3b3b8e3b57..48baa90403 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch
@@ -344,7 +344,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
}
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
-@@ -130,6 +130,14 @@ static const struct mmc_fixup __maybe_un
+@@ -134,6 +134,14 @@ static const struct mmc_fixup __maybe_un
MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_DISCARD),
@@ -1993,7 +1993,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
#define MAX_TUNING_LOOP 40
-@@ -3209,7 +3209,7 @@ static void sdhci_timeout_timer(struct t
+@@ -3212,7 +3212,7 @@ static void sdhci_timeout_timer(struct t
spin_lock_irqsave(&host->lock, flags);
if (host->cmd && !sdhci_data_line_cmd(host->cmd)) {
@@ -2002,7 +2002,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
mmc_hostname(host->mmc));
sdhci_err_stats_inc(host, REQ_TIMEOUT);
sdhci_dumpregs(host);
-@@ -3232,7 +3232,7 @@ static void sdhci_timeout_data_timer(str
+@@ -3235,7 +3235,7 @@ static void sdhci_timeout_data_timer(str
if (host->data || host->data_cmd ||
(host->cmd && sdhci_data_line_cmd(host->cmd))) {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch b/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch
index 2d546c7502..92fd35d936 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch
@@ -99,7 +99,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
#endif
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
-@@ -509,6 +509,9 @@ do { \
+@@ -499,6 +499,9 @@ do { \
extern unsigned long __must_check
arm_copy_from_user(void *to, const void __user *from, unsigned long n);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch
index 0474076e77..b35df5a381 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch
@@ -1541,7 +1541,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+zidoo Shenzhen Zidoo Technology Co., Ltd.
+zii Zodiac Inflight Innovations
+zte ZTE Corp.
-+zyxel ZyXEL Communications Corp.
++zyxel Zyxel Communications Corp.
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -196,6 +196,8 @@ patternProperties:
@@ -17583,7 +17583,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
* For devices with more than one control interface, we assume the
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
-@@ -2185,6 +2185,8 @@ static const struct usb_audio_quirk_flag
+@@ -2191,6 +2191,8 @@ static const struct usb_audio_quirk_flag
QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
QUIRK_FLAG_ALIGN_TRANSFER),
diff --git a/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch b/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch
index 14f92dfadd..1a84fb14b1 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch
@@ -10,7 +10,7 @@ Subject: [PATCH 0113/1085] ARM64: Force hardware emulation of deprecated
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
-@@ -539,9 +539,14 @@ static void __init register_insn_emulati
+@@ -542,9 +542,14 @@ static void __init register_insn_emulati
switch (insn->status) {
case INSN_DEPRECATED:
diff --git a/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
index 73baf3312b..f5eea9b47d 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
@@ -15,7 +15,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
-@@ -1487,6 +1487,109 @@ command_cleanup:
+@@ -1497,6 +1497,109 @@ command_cleanup:
}
/*
@@ -125,7 +125,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
* non-error returns are a promise to giveback() the urb later
* we drop ownership so next owner (or urb unlink) can get it
*/
-@@ -5316,6 +5419,7 @@ static const struct hc_driver xhci_hc_dr
+@@ -5328,6 +5431,7 @@ static const struct hc_driver xhci_hc_dr
.endpoint_reset = xhci_endpoint_reset,
.check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth,
diff --git a/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch b/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch
index 957ed42407..1e5bb6059d 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch
@@ -19,7 +19,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
-@@ -1576,7 +1576,7 @@ static void xhci_fixup_endpoint(struct u
+@@ -1586,7 +1586,7 @@ static void xhci_fixup_endpoint(struct u
return;
}
ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
index 8ff54e98f8..b102bc33fc 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
@@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
#define USB_VENDOR_ID_BELKIN 0x050d
#define USB_DEVICE_ID_FLIP_KVM 0x3201
-@@ -1404,6 +1407,9 @@
+@@ -1409,6 +1412,9 @@
#define USB_VENDOR_ID_XIAOMI 0x2717
#define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014
diff --git a/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch b/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch
index 9b5a0fa088..29f8ebf0d6 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch
@@ -17,7 +17,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
-@@ -57,6 +57,8 @@
+@@ -58,6 +58,8 @@
#define extra_checks 0
#endif
@@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
/* Device and char device-related information */
static DEFINE_IDA(gpio_ida);
static dev_t gpio_devt;
-@@ -2591,8 +2593,8 @@ int gpiod_direction_output(struct gpio_d
+@@ -2592,8 +2594,8 @@ int gpiod_direction_output(struct gpio_d
value = !!value;
/* GPIOs used for enabled IRQs shall not be set as output */
@@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
gpiod_err(desc,
"%s: tried to set a GPIO tied to an IRQ as output\n",
__func__);
-@@ -3470,8 +3472,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
+@@ -3471,8 +3473,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
}
/* To be valid for IRQ the line needs to be input or open drain */
diff --git a/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch b/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
index b5e790665e..2e3de46259 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
@@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
-@@ -428,6 +428,12 @@ cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ;
+@@ -432,6 +432,12 @@ cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ;
$(DTC) -@ -H epapr -O dtb -o $@ -b 0 \
-i $(dir $<) $(DTC_FLAGS) \
-Wno-interrupts_property \
diff --git a/target/linux/bcm27xx/patches-6.6/950-0301-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch b/target/linux/bcm27xx/patches-6.6/950-0301-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch
index 15162cf6df..d5cee828b0 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0301-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0301-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch
@@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
-@@ -3375,6 +3375,31 @@ static const struct panel_desc rocktech_
+@@ -3376,6 +3376,31 @@ static const struct panel_desc rocktech_
.connector_type = DRM_MODE_CONNECTOR_DPI,
};
@@ -47,7 +47,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
static const struct display_timing rocktech_rk070er9427_timing = {
.pixelclock = { 26400000, 33300000, 46800000 },
.hactive = { 800, 800, 800 },
-@@ -4426,6 +4451,9 @@ static const struct of_device_id platfor
+@@ -4427,6 +4452,9 @@ static const struct of_device_id platfor
.compatible = "rocktech,rk043fn48h",
.data = &rocktech_rk043fn48h,
}, {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch b/target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch
index 6f22bfd578..da1bbb7886 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch
@@ -20,6 +20,6 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
static const struct spi_device_id spidev_spi_ids[] = {
+ { .name = "spidev" },
+ { .name = "bh2228fv" },
{ .name = "dh2228fv" },
- { .name = "ltc2488" },
- { .name = "sx1301" },
+ { .name = "jg10309-01" },
diff --git a/target/linux/bcm27xx/patches-6.6/950-0343-drm-panel-simple-add-Geekworm-MZP280-Panel.patch b/target/linux/bcm27xx/patches-6.6/950-0343-drm-panel-simple-add-Geekworm-MZP280-Panel.patch
index f6a3746e8d..d5a071364a 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0343-drm-panel-simple-add-Geekworm-MZP280-Panel.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0343-drm-panel-simple-add-Geekworm-MZP280-Panel.patch
@@ -46,7 +46,7 @@ Acked-by: Maxime Ripard <maxime@cerno.tech>
static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
.clock = 9000,
.hdisplay = 480,
-@@ -4301,6 +4327,9 @@ static const struct of_device_id platfor
+@@ -4302,6 +4328,9 @@ static const struct of_device_id platfor
.compatible = "friendlyarm,hd702e",
.data = &friendlyarm_hd702e,
}, {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0359-mm-page_alloc-cma-introduce-a-customisable-threshold.patch b/target/linux/bcm27xx/patches-6.6/950-0359-mm-page_alloc-cma-introduce-a-customisable-threshold.patch
index 9b5cba8dab..8c39ae9931 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0359-mm-page_alloc-cma-introduce-a-customisable-threshold.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0359-mm-page_alloc-cma-introduce-a-customisable-threshold.patch
@@ -48,7 +48,7 @@ Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
/*
* A cached value of the page's pageblock's migratetype, used when the page is
* put on a pcplist. Used to avoid the pageblock migratetype lookup when
-@@ -2090,12 +2111,13 @@ __rmqueue(struct zone *zone, unsigned in
+@@ -2095,12 +2116,13 @@ __rmqueue(struct zone *zone, unsigned in
if (IS_ENABLED(CONFIG_CMA)) {
/*
* Balance movable allocations between regular and CMA areas by
diff --git a/target/linux/bcm27xx/patches-6.6/950-0398-drm-panel-panel-ilitek9881c-Use-cansleep-methods.patch b/target/linux/bcm27xx/patches-6.6/950-0398-drm-panel-panel-ilitek9881c-Use-cansleep-methods.patch
deleted file mode 100644
index 8e68d404f6..0000000000
--- a/target/linux/bcm27xx/patches-6.6/950-0398-drm-panel-panel-ilitek9881c-Use-cansleep-methods.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 79f7bcfff7a02fd32019cac8df7908dd61e1c7f7 Mon Sep 17 00:00:00 2001
-From: Mark Williams <mwp@mwp.id.au>
-Date: Wed, 7 Dec 2022 18:20:40 -0700
-Subject: [PATCH 0398/1085] drm/panel: panel-ilitek9881c: Use cansleep methods
-
-Use cansleep version of gpiod_set_value so external IO drivers (like
-via I2C) can be used.
-
-Signed-off-by: Mark Williams <mwp@mwp.id.au>
----
- drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
-+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
-@@ -1107,10 +1107,10 @@ static int ili9881c_prepare(struct drm_p
- msleep(5);
-
- /* And reset it */
-- gpiod_set_value(ctx->reset, 1);
-+ gpiod_set_value_cansleep(ctx->reset, 1);
- msleep(20);
-
-- gpiod_set_value(ctx->reset, 0);
-+ gpiod_set_value_cansleep(ctx->reset, 0);
- msleep(20);
-
- for (i = 0; i < ctx->desc->init_length; i++) {
-@@ -1165,7 +1165,7 @@ static int ili9881c_unprepare(struct drm
-
- mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);
- regulator_disable(ctx->power);
-- gpiod_set_value(ctx->reset, 1);
-+ gpiod_set_value_cansleep(ctx->reset, 1);
-
- return 0;
- }
diff --git a/target/linux/bcm27xx/patches-6.6/950-0401-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch b/target/linux/bcm27xx/patches-6.6/950-0401-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch
index a7eaaf102a..d8376a3fe5 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0401-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0401-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch
@@ -165,7 +165,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
static const struct drm_display_mode innolux_at070tn92_mode = {
.clock = 33333,
.hdisplay = 800,
-@@ -4351,6 +4383,9 @@ static const struct of_device_id platfor
+@@ -4352,6 +4384,9 @@ static const struct of_device_id platfor
.compatible = "innolux,at043tn24",
.data = &innolux_at043tn24,
}, {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch b/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch
index b9ec31caa5..aa11729b71 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch
@@ -10,7 +10,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
-@@ -1345,6 +1345,7 @@ static const struct of_device_id pca953x
+@@ -1347,6 +1347,7 @@ static const struct of_device_id pca953x
{ .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
{ .compatible = "ti,tca9538", .data = OF_953X( 8, PCA_INT), },
{ .compatible = "ti,tca9539", .data = OF_953X(16, PCA_INT), },
diff --git a/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch b/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch
index 9aa16d6b25..0e404906be 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch
@@ -20,7 +20,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
-@@ -4659,6 +4659,7 @@ static const struct {
+@@ -4861,6 +4861,7 @@ static const struct {
*/
static int hci_dev_setup_sync(struct hci_dev *hdev)
{
@@ -28,7 +28,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
int ret = 0;
bool invalid_bdaddr;
size_t i;
-@@ -4687,7 +4688,8 @@ static int hci_dev_setup_sync(struct hci
+@@ -4889,7 +4890,8 @@ static int hci_dev_setup_sync(struct hci
test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
if (!ret) {
if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) &&
diff --git a/target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch b/target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch
deleted file mode 100644
index 1b0a29a777..0000000000
--- a/target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 3b391ceadf0d4ab5ce45f98d2f1d41f40e5aedd7 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson <dave.stevenson@raspberrypi.com>
-Date: Fri, 1 Sep 2023 12:23:30 +0100
-Subject: [PATCH 0490/1085] input: ads7846: Add missing spi_device_id strings
-
-The SPI core logs error messages if a compatible string device
-name is not also present as an spi_device_id.
-
-No spi_device_id values are specified by the driver, therefore
-we get 4 log lines every time it is loaded:
-SPI driver ads7846 has no spi_device_id for ti,tsc2046
-SPI driver ads7846 has no spi_device_id for ti,ads7843
-SPI driver ads7846 has no spi_device_id for ti,ads7845
-SPI driver ads7846 has no spi_device_id for ti,ads7873
-
-Add the spi_device_id values for these devices.
-
-Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
----
- drivers/input/touchscreen/ads7846.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/input/touchscreen/ads7846.c
-+++ b/drivers/input/touchscreen/ads7846.c
-@@ -1114,6 +1114,16 @@ static const struct of_device_id ads7846
- };
- MODULE_DEVICE_TABLE(of, ads7846_dt_ids);
-
-+static const struct spi_device_id ads7846_spi_ids[] = {
-+ { "tsc2046", 0 },
-+ { "ads7843", 0 },
-+ { "ads7845", 0 },
-+ { "ads7846", 0 },
-+ { "ads7873", 0 },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(spi, ads7846_spi_ids);
-+
- static const struct ads7846_platform_data *ads7846_get_props(struct device *dev)
- {
- struct ads7846_platform_data *pdata;
-@@ -1390,6 +1400,7 @@ static struct spi_driver ads7846_driver
- .pm = pm_sleep_ptr(&ads7846_pm),
- .of_match_table = ads7846_dt_ids,
- },
-+ .id_table = ads7846_spi_ids,
- .probe = ads7846_probe,
- .remove = ads7846_remove,
- };
diff --git a/target/linux/bcm27xx/patches-6.6/950-0513-mmc-brcmstb-add-support-for-BCM2712.patch b/target/linux/bcm27xx/patches-6.6/950-0513-mmc-brcmstb-add-support-for-BCM2712.patch
index 2b0cbcd26f..5ecdd9cd18 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0513-mmc-brcmstb-add-support-for-BCM2712.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0513-mmc-brcmstb-add-support-for-BCM2712.patch
@@ -63,7 +63,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
#include "sdhci-cqhci.h"
#include "sdhci-pltfm.h"
-@@ -26,18 +28,43 @@
+@@ -27,18 +29,43 @@
#define BRCMSTB_PRIV_FLAGS_HAS_CQE BIT(0)
#define BRCMSTB_PRIV_FLAGS_GATE_CLOCK BIT(1)
@@ -107,7 +107,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
struct sdhci_ops *ops;
const unsigned int flags;
};
-@@ -94,6 +121,124 @@ static void sdhci_brcmstb_set_clock(stru
+@@ -95,6 +122,124 @@ static void sdhci_brcmstb_set_clock(stru
sdhci_enable_clk(host, clk);
}
@@ -232,7 +232,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static void sdhci_brcmstb_set_uhs_signaling(struct sdhci_host *host,
unsigned int timing)
{
-@@ -123,6 +268,146 @@ static void sdhci_brcmstb_set_uhs_signal
+@@ -124,6 +269,146 @@ static void sdhci_brcmstb_set_uhs_signal
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
}
@@ -379,7 +379,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static void sdhci_brcmstb_dumpregs(struct mmc_host *mmc)
{
sdhci_dumpregs(mmc_priv(mmc));
-@@ -155,6 +440,21 @@ static struct sdhci_ops sdhci_brcmstb_op
+@@ -156,6 +441,21 @@ static struct sdhci_ops sdhci_brcmstb_op
.set_uhs_signaling = sdhci_set_uhs_signaling,
};
@@ -401,7 +401,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static struct sdhci_ops sdhci_brcmstb_ops_7216 = {
.set_clock = sdhci_brcmstb_set_clock,
.set_bus_width = sdhci_set_bus_width,
-@@ -179,10 +479,16 @@ static const struct brcmstb_match_priv m
+@@ -180,10 +480,16 @@ static const struct brcmstb_match_priv m
.ops = &sdhci_brcmstb_ops_7216,
};
@@ -418,7 +418,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
{},
};
-@@ -255,6 +561,8 @@ static int sdhci_brcmstb_probe(struct pl
+@@ -256,6 +562,8 @@ static int sdhci_brcmstb_probe(struct pl
struct sdhci_brcmstb_priv *priv;
u32 actual_clock_mhz;
struct sdhci_host *host;
@@ -427,7 +427,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
struct clk *clk;
struct clk *base_clk = NULL;
int res;
-@@ -283,6 +591,11 @@ static int sdhci_brcmstb_probe(struct pl
+@@ -284,6 +592,11 @@ static int sdhci_brcmstb_probe(struct pl
match_priv->ops->irq = sdhci_brcmstb_cqhci_irq;
}
@@ -439,7 +439,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/* Map in the non-standard CFG registers */
priv->cfg_regs = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
if (IS_ERR(priv->cfg_regs)) {
-@@ -295,6 +608,43 @@ static int sdhci_brcmstb_probe(struct pl
+@@ -296,6 +609,43 @@ static int sdhci_brcmstb_probe(struct pl
if (res)
goto err;
@@ -483,7 +483,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Automatic clock gating does not work for SD cards that may
* voltage switch so only enable it for non-removable devices.
-@@ -311,6 +661,13 @@ static int sdhci_brcmstb_probe(struct pl
+@@ -312,6 +662,13 @@ static int sdhci_brcmstb_probe(struct pl
(host->mmc->caps2 & MMC_CAP2_HS400_ES))
host->mmc_host_ops.hs400_enhanced_strobe = match_priv->hs400es;
diff --git a/target/linux/bcm27xx/patches-6.6/950-0514-sdhci-Add-SD-Express-hook.patch b/target/linux/bcm27xx/patches-6.6/950-0514-sdhci-Add-SD-Express-hook.patch
index 377e5a2385..17c7d2f965 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0514-sdhci-Add-SD-Express-hook.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0514-sdhci-Add-SD-Express-hook.patch
@@ -26,7 +26,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv)
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
-@@ -3047,6 +3047,15 @@ static void sdhci_card_event(struct mmc_
+@@ -3050,6 +3050,15 @@ static void sdhci_card_event(struct mmc_
spin_unlock_irqrestore(&host->lock, flags);
}
@@ -42,7 +42,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
static const struct mmc_host_ops sdhci_ops = {
.request = sdhci_request,
.post_req = sdhci_post_req,
-@@ -3062,6 +3071,7 @@ static const struct mmc_host_ops sdhci_o
+@@ -3065,6 +3074,7 @@ static const struct mmc_host_ops sdhci_o
.execute_tuning = sdhci_execute_tuning,
.card_event = sdhci_card_event,
.card_busy = sdhci_card_busy,
@@ -50,7 +50,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
};
/*****************************************************************************\
-@@ -4580,6 +4590,15 @@ int sdhci_setup_host(struct sdhci_host *
+@@ -4583,6 +4593,15 @@ int sdhci_setup_host(struct sdhci_host *
!(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50))
mmc->caps |= MMC_CAP_UHS_DDR50;
diff --git a/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch b/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch
index 4baa0a18d8..f771fc8750 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch
@@ -212,7 +212,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
},
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
-@@ -1163,6 +1163,24 @@ static void dwc3_config_threshold(struct
+@@ -1202,6 +1202,24 @@ static void dwc3_config_threshold(struct
}
}
@@ -237,7 +237,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/**
* dwc3_core_init - Low-level initialization of DWC3 Core
* @dwc: Pointer to our controller context structure
-@@ -1228,6 +1246,8 @@ static int dwc3_core_init(struct dwc3 *d
+@@ -1267,6 +1285,8 @@ static int dwc3_core_init(struct dwc3 *d
dwc3_set_incr_burst_type(dwc);
@@ -246,7 +246,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
ret = dwc3_phy_power_on(dwc);
if (ret)
goto err_exit_phy;
-@@ -1302,6 +1322,24 @@ static int dwc3_core_init(struct dwc3 *d
+@@ -1356,6 +1376,24 @@ static int dwc3_core_init(struct dwc3 *d
dwc3_config_threshold(dwc);
@@ -271,7 +271,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
return 0;
err_power_off_phy:
-@@ -1445,6 +1483,7 @@ static void dwc3_get_properties(struct d
+@@ -1499,6 +1537,7 @@ static void dwc3_get_properties(struct d
u8 tx_thr_num_pkt_prd = 0;
u8 tx_max_burst_prd = 0;
u8 tx_fifo_resize_max_num;
@@ -279,7 +279,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
const char *usb_psy_name;
int ret;
-@@ -1467,6 +1506,9 @@ static void dwc3_get_properties(struct d
+@@ -1521,6 +1560,9 @@ static void dwc3_get_properties(struct d
*/
tx_fifo_resize_max_num = 6;
@@ -289,7 +289,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
dwc->maximum_speed = usb_get_maximum_speed(dev);
dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev);
dwc->dr_mode = usb_get_dr_mode(dev);
-@@ -1588,6 +1630,9 @@ static void dwc3_get_properties(struct d
+@@ -1642,6 +1684,9 @@ static void dwc3_get_properties(struct d
dwc->dis_split_quirk = device_property_read_bool(dev,
"snps,dis-split-quirk");
@@ -299,7 +299,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
-@@ -1605,6 +1650,8 @@ static void dwc3_get_properties(struct d
+@@ -1659,6 +1704,8 @@ static void dwc3_get_properties(struct d
dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd;
dwc->tx_max_burst_prd = tx_max_burst_prd;
@@ -308,7 +308,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
dwc->imod_interval = 0;
dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num;
-@@ -1880,6 +1927,12 @@ static int dwc3_probe(struct platform_de
+@@ -1934,6 +1981,12 @@ static int dwc3_probe(struct platform_de
dwc3_get_properties(dwc);
@@ -333,7 +333,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/* Global Debug LSP MUX Select */
#define DWC3_GDBGLSPMUX_ENDBC BIT(15) /* Host only */
#define DWC3_GDBGLSPMUX_HOSTSELECT(n) ((n) & 0x3fff)
-@@ -1060,6 +1063,7 @@ struct dwc3_scratchpad_array {
+@@ -1061,6 +1064,7 @@ struct dwc3_scratchpad_array {
* @tx_max_burst_prd: max periodic ESS transmit burst size
* @tx_fifo_resize_max_num: max number of fifos allocated during txfifo resize
* @clear_stall_protocol: endpoint number that requires a delayed status phase
@@ -341,7 +341,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
* @hsphy_interface: "utmi" or "ulpi"
* @connected: true when we're connected to a host, false otherwise
* @softconnect: true when gadget connect is called, false when disconnect runs
-@@ -1293,6 +1297,7 @@ struct dwc3 {
+@@ -1296,6 +1300,7 @@ struct dwc3 {
u8 tx_max_burst_prd;
u8 tx_fifo_resize_max_num;
u8 clear_stall_protocol;
diff --git a/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch b/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch
index 764a38ff19..b900c1edae 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch
@@ -39,11 +39,11 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
depends on I2C && OF
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
-@@ -285,3 +285,5 @@ rsmu-i2c-objs := rsmu_core.o rsmu_i2c.
- rsmu-spi-objs := rsmu_core.o rsmu_spi.o
- obj-$(CONFIG_MFD_RSMU_I2C) += rsmu-i2c.o
- obj-$(CONFIG_MFD_RSMU_SPI) += rsmu-spi.o
-+
+@@ -283,3 +283,5 @@ obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x
+
+ obj-$(CONFIG_MFD_RSMU_I2C) += rsmu_i2c.o rsmu_core.o
+ obj-$(CONFIG_MFD_RSMU_SPI) += rsmu_spi.o rsmu_core.o
++
+obj-$(CONFIG_MFD_RP1) += rp1.o
--- /dev/null
+++ b/drivers/mfd/rp1.c
diff --git a/target/linux/bcm27xx/patches-6.6/950-0536-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch b/target/linux/bcm27xx/patches-6.6/950-0536-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch
deleted file mode 100644
index 47da512954..0000000000
--- a/target/linux/bcm27xx/patches-6.6/950-0536-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch
+++ /dev/null
@@ -1,328 +0,0 @@
-From c6cd3e6878e32548ea90c4160c534e952221c194 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.com>
-Date: Wed, 28 Apr 2021 17:46:01 +0100
-Subject: [PATCH 0536/1085] dmaengine: dw-axi-dmac: Fixes for RP1
-
-Don't assume that DMA addresses of devices are the same as their
-physical addresses - convert correctly.
-
-The CFG2 register layout is used when there are more than 8 channels,
-but also when configured for more than 16 target peripheral devices
-because the index of the handshake signal has to be made wider.
-
-Reset the DMAC on probe
-
-The driver goes to the trouble of tracking when transfers have been
-paused, but then doesn't report that state when queried.
-
-Not having APB registers is not an error - for most use cases it's
-not even of interest, it's expected. Demote the message to debug level,
-which is disabled by default.
-
-Each channel has a descriptor pool, which is shared between transfers.
-It is unsafe to treat the total number of descriptors allocated from a
-pool as the number allocated to a specific transfer; doing so leads
-to releasing buffers that shouldn't be released and walking off the
-ends of descriptor lists. Instead, give each transfer descriptor its
-own count.
-
-Support partial transfers:
-Some use cases involve streaming from a device where the transfer only
-proceeds when the device's FIFO occupancy exceeds a certain threshold.
-In such cases (e.g. when pulling data from a UART) it is important to
-know how much data has been transferred so far, in order that remaining
-bytes can be read from the FIFO directly by software.
-
-Add the necessary code to provide this "residue" value with a finer,
-sub-transfer granularity.
-
-In order to prevent the occasional byte getting stuck in the DMA
-controller's internal buffers, restrict the destination memory width
-to the source register width.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.com>
----
- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 132 +++++++++++++++---
- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
- 2 files changed, 113 insertions(+), 20 deletions(-)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -12,6 +12,7 @@
- #include <linux/device.h>
- #include <linux/dmaengine.h>
- #include <linux/dmapool.h>
-+#include <linux/dma-direct.h>
- #include <linux/dma-mapping.h>
- #include <linux/err.h>
- #include <linux/interrupt.h>
-@@ -84,6 +85,17 @@ axi_chan_iowrite64(struct axi_dma_chan *
- iowrite32(upper_32_bits(val), chan->chan_regs + reg + 4);
- }
-
-+static inline u64
-+axi_chan_ioread64(struct axi_dma_chan *chan, u32 reg)
-+{
-+ /*
-+ * We split one 64 bit read into two 32 bit reads as some HW doesn't
-+ * support 64 bit access.
-+ */
-+ return ((u64)ioread32(chan->chan_regs + reg + 4) << 32) +
-+ ioread32(chan->chan_regs + reg);
-+}
-+
- static inline void axi_chan_config_write(struct axi_dma_chan *chan,
- struct axi_dma_chan_config *config)
- {
-@@ -220,7 +232,18 @@ static void axi_dma_hw_init(struct axi_d
- {
- int ret;
- u32 i;
-+ int retries = 1000;
-
-+ axi_dma_iowrite32(chip, DMAC_RESET, 1);
-+ while (axi_dma_ioread32(chip, DMAC_RESET)) {
-+ retries--;
-+ if (!retries) {
-+ dev_err(chip->dev, "%s: DMAC failed to reset\n",
-+ __func__);
-+ return;
-+ }
-+ cpu_relax();
-+ }
- for (i = 0; i < chip->dw->hdata->nr_channels; i++) {
- axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
- axi_chan_disable(&chip->dw->chan[i]);
-@@ -282,7 +305,7 @@ static struct axi_dma_lli *axi_desc_get(
- static void axi_desc_put(struct axi_dma_desc *desc)
- {
- struct axi_dma_chan *chan = desc->chan;
-- int count = atomic_read(&chan->descs_allocated);
-+ u32 count = desc->hw_desc_count;
- struct axi_dma_hw_desc *hw_desc;
- int descs_put;
-
-@@ -304,6 +327,48 @@ static void vchan_desc_put(struct virt_d
- axi_desc_put(vd_to_axi_desc(vdesc));
- }
-
-+static u32 axi_dma_desc_src_pos(struct axi_dma_desc *desc, dma_addr_t addr)
-+{
-+ unsigned int idx = 0;
-+ u32 pos = 0;
-+
-+ while (pos < desc->length) {
-+ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++];
-+ u32 len = hw_desc->len;
-+ dma_addr_t start = le64_to_cpu(hw_desc->lli->sar);
-+
-+ if (addr >= start && addr <= (start + len)) {
-+ pos += addr - start;
-+ break;
-+ }
-+
-+ pos += len;
-+ }
-+
-+ return pos;
-+}
-+
-+static u32 axi_dma_desc_dst_pos(struct axi_dma_desc *desc, dma_addr_t addr)
-+{
-+ unsigned int idx = 0;
-+ u32 pos = 0;
-+
-+ while (pos < desc->length) {
-+ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++];
-+ u32 len = hw_desc->len;
-+ dma_addr_t start = le64_to_cpu(hw_desc->lli->dar);
-+
-+ if (addr >= start && addr <= (start + len)) {
-+ pos += addr - start;
-+ break;
-+ }
-+
-+ pos += len;
-+ }
-+
-+ return pos;
-+}
-+
- static enum dma_status
- dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
- struct dma_tx_state *txstate)
-@@ -313,10 +378,7 @@ dma_chan_tx_status(struct dma_chan *dcha
- enum dma_status status;
- u32 completed_length;
- unsigned long flags;
-- u32 completed_blocks;
- size_t bytes = 0;
-- u32 length;
-- u32 len;
-
- status = dma_cookie_status(dchan, cookie, txstate);
- if (status == DMA_COMPLETE || !txstate)
-@@ -325,16 +387,31 @@ dma_chan_tx_status(struct dma_chan *dcha
- spin_lock_irqsave(&chan->vc.lock, flags);
-
- vdesc = vchan_find_desc(&chan->vc, cookie);
-- if (vdesc) {
-- length = vd_to_axi_desc(vdesc)->length;
-- completed_blocks = vd_to_axi_desc(vdesc)->completed_blocks;
-- len = vd_to_axi_desc(vdesc)->hw_desc[0].len;
-- completed_length = completed_blocks * len;
-- bytes = length - completed_length;
-+ if (vdesc && vdesc == vchan_next_desc(&chan->vc)) {
-+ /* This descriptor is in-progress */
-+ struct axi_dma_desc *desc = vd_to_axi_desc(vdesc);
-+ dma_addr_t addr;
-+
-+ if (chan->direction == DMA_MEM_TO_DEV) {
-+ addr = axi_chan_ioread64(chan, CH_SAR);
-+ completed_length = axi_dma_desc_src_pos(desc, addr);
-+ } else if (chan->direction == DMA_DEV_TO_MEM) {
-+ addr = axi_chan_ioread64(chan, CH_DAR);
-+ completed_length = axi_dma_desc_dst_pos(desc, addr);
-+ } else {
-+ completed_length = 0;
-+ }
-+ bytes = desc->length - completed_length;
-+ } else if (vdesc) {
-+ /* Still in the queue so not started */
-+ bytes = vd_to_axi_desc(vdesc)->length;
- }
-
-- spin_unlock_irqrestore(&chan->vc.lock, flags);
-+ if (chan->is_paused && status == DMA_IN_PROGRESS)
-+ status = DMA_PAUSED;
-+
- dma_set_residue(txstate, bytes);
-+ spin_unlock_irqrestore(&chan->vc.lock, flags);
-
- return status;
- }
-@@ -522,7 +599,7 @@ static void dw_axi_dma_set_hw_channel(st
- unsigned long reg_value, val;
-
- if (!chip->apb_regs) {
-- dev_err(chip->dev, "apb_regs not initialized\n");
-+ dev_dbg(chip->dev, "apb_regs not initialized\n");
- return;
- }
-
-@@ -626,18 +703,25 @@ static int dw_axi_dma_set_hw_desc(struct
- switch (chan->direction) {
- case DMA_MEM_TO_DEV:
- reg_width = __ffs(chan->config.dst_addr_width);
-- device_addr = chan->config.dst_addr;
-+ device_addr = phys_to_dma(chan->chip->dev, chan->config.dst_addr);
- ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS |
- mem_width << CH_CTL_L_SRC_WIDTH_POS |
-+ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_DST_MSIZE_POS |
-+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
- DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS |
- DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS;
- block_ts = len >> mem_width;
- break;
- case DMA_DEV_TO_MEM:
- reg_width = __ffs(chan->config.src_addr_width);
-- device_addr = chan->config.src_addr;
-+ /* Prevent partial access units getting lost */
-+ if (mem_width > reg_width)
-+ mem_width = reg_width;
-+ device_addr = phys_to_dma(chan->chip->dev, chan->config.src_addr);
- ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS |
- mem_width << CH_CTL_L_DST_WIDTH_POS |
-+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
-+ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_SRC_MSIZE_POS |
- DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
- DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS;
- block_ts = len >> reg_width;
-@@ -673,9 +757,6 @@ static int dw_axi_dma_set_hw_desc(struct
- }
-
- hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
--
-- ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
-- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
- hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
-
- set_desc_src_master(hw_desc);
-@@ -770,6 +851,8 @@ dw_axi_dma_chan_prep_cyclic(struct dma_c
- src_addr += segment_len;
- }
-
-+ desc->hw_desc_count = total_segments;
-+
- llp = desc->hw_desc[0].llp;
-
- /* Managed transfer list */
-@@ -849,6 +932,8 @@ dw_axi_dma_chan_prep_slave_sg(struct dma
- } while (len >= segment_len);
- }
-
-+ desc->hw_desc_count = loop;
-+
- /* Set end-of-link to the last link descriptor of list */
- set_desc_last(&desc->hw_desc[num_sgs - 1]);
-
-@@ -956,6 +1041,8 @@ dma_chan_prep_dma_memcpy(struct dma_chan
- num++;
- }
-
-+ desc->hw_desc_count = num;
-+
- /* Set end-of-link to the last link descriptor of list */
- set_desc_last(&desc->hw_desc[num - 1]);
- /* Managed transfer list */
-@@ -1004,7 +1091,7 @@ static void axi_chan_dump_lli(struct axi
- static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
- struct axi_dma_desc *desc_head)
- {
-- int count = atomic_read(&chan->descs_allocated);
-+ u32 count = desc_head->hw_desc_count;
- int i;
-
- for (i = 0; i < count; i++)
-@@ -1047,11 +1134,11 @@ out:
-
- static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
- {
-- int count = atomic_read(&chan->descs_allocated);
- struct axi_dma_hw_desc *hw_desc;
- struct axi_dma_desc *desc;
- struct virt_dma_desc *vd;
- unsigned long flags;
-+ u32 count;
- u64 llp;
- int i;
-
-@@ -1073,6 +1160,7 @@ static void axi_chan_block_xfer_complete
- if (chan->cyclic) {
- desc = vd_to_axi_desc(vd);
- if (desc) {
-+ count = desc->hw_desc_count;
- llp = lo_hi_readq(chan->chan_regs + CH_LLP);
- for (i = 0; i < count; i++) {
- hw_desc = &desc->hw_desc[i];
-@@ -1325,6 +1413,10 @@ static int parse_device_properties(struc
-
- chip->dw->hdata->nr_masters = tmp;
-
-+ ret = device_property_read_u32(dev, "snps,dma-targets", &tmp);
-+ if (!ret && tmp > 16)
-+ chip->dw->hdata->use_cfg2 = true;
-+
- ret = device_property_read_u32(dev, "snps,data-width", &tmp);
- if (ret)
- return ret;
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-@@ -101,6 +101,7 @@ struct axi_dma_desc {
-
- struct virt_dma_desc vd;
- struct axi_dma_chan *chan;
-+ u32 hw_desc_count;
- u32 completed_blocks;
- u32 length;
- u32 period_len;
diff --git a/target/linux/bcm27xx/patches-6.6/950-0636-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch b/target/linux/bcm27xx/patches-6.6/950-0636-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch
index ea841d4248..b72020d7e4 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0636-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0636-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch
@@ -16,7 +16,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
-@@ -3437,11 +3437,11 @@ static const struct panel_desc rocktech_
+@@ -3438,11 +3438,11 @@ static const struct panel_desc rocktech_
};
static const struct drm_display_mode raspberrypi_7inch_mode = {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch b/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch
index 5ccd9497e7..f94efc25b2 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch
@@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
-@@ -1837,7 +1837,7 @@ __drm_fb_helper_initial_config_and_unloc
+@@ -1851,7 +1851,7 @@ __drm_fb_helper_initial_config_and_unloc
struct drm_device *dev = fb_helper->dev;
struct fb_info *info;
unsigned int width, height;
@@ -24,7 +24,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
width = dev->mode_config.max_width;
height = dev->mode_config.max_height;
-@@ -1868,6 +1868,15 @@ __drm_fb_helper_initial_config_and_unloc
+@@ -1879,6 +1879,15 @@ __drm_fb_helper_initial_config_and_unloc
* register the fbdev emulation instance in kernel_fb_helper_list. */
mutex_unlock(&fb_helper->lock);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch b/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch
index 588d113376..60cabdffc3 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch
@@ -12,7 +12,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
-@@ -1868,11 +1868,11 @@ __drm_fb_helper_initial_config_and_unloc
+@@ -1879,11 +1879,11 @@ __drm_fb_helper_initial_config_and_unloc
* register the fbdev emulation instance in kernel_fb_helper_list. */
mutex_unlock(&fb_helper->lock);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch b/target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch
deleted file mode 100644
index 2a2ba5d037..0000000000
--- a/target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 6aab06ff9f81e186b1a02b53b514e691472e5a61 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.com>
-Date: Tue, 7 Nov 2023 14:49:47 +0000
-Subject: [PATCH 0714/1085] spi: dw-dma: Get the last DMA scoop out of the FIFO
-
-With a DMA FIFO threshold greater than 1 (encoded as 0), it is possible
-for data in the FIFO to be inaccessible, causing the transfer to fail
-after a timeout. If the transfer includes a transmission, reduce the
-RX threshold when the TX completes, otherwise use 1 for the whole
-transfer (inefficient, but not catastrophic at SPI data rates).
-
-See: https://github.com/raspberrypi/linux/issues/5696
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.com>
----
- drivers/spi/spi-dw-dma.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/spi/spi-dw-dma.c
-+++ b/drivers/spi/spi-dw-dma.c
-@@ -315,8 +315,10 @@ static void dw_spi_dma_tx_done(void *arg
- struct dw_spi *dws = arg;
-
- clear_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy);
-- if (test_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy))
-+ if (test_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy)) {
-+ dw_writel(dws, DW_SPI_DMARDLR, 0);
- return;
-+ }
-
- complete(&dws->dma_completion);
- }
-@@ -642,6 +644,8 @@ static int dw_spi_dma_transfer(struct dw
-
- nents = max(xfer->tx_sg.nents, xfer->rx_sg.nents);
-
-+ dw_writel(dws, DW_SPI_DMARDLR, xfer->tx_buf ? (dws->rxburst - 1) : 0);
-+
- /*
- * Execute normal DMA-based transfer (which submits the Rx and Tx SG
- * lists directly to the DMA engine at once) if either full hardware
diff --git a/target/linux/bcm27xx/patches-6.6/950-0716-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch b/target/linux/bcm27xx/patches-6.6/950-0716-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch
index 77361dc84c..aacc0e7653 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0716-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0716-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch
@@ -36,7 +36,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
return true;
-@@ -3306,6 +3312,11 @@ static void sdhci_cmd_irq(struct sdhci_h
+@@ -3309,6 +3315,11 @@ static void sdhci_cmd_irq(struct sdhci_h
if (intmask & SDHCI_INT_TIMEOUT) {
host->cmd->error = -ETIMEDOUT;
sdhci_err_stats_inc(host, CMD_TIMEOUT);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0757-drm-panel-add-panel-dsi.patch b/target/linux/bcm27xx/patches-6.6/950-0757-drm-panel-add-panel-dsi.patch
index d421386183..989fe3315f 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0757-drm-panel-add-panel-dsi.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0757-drm-panel-add-panel-dsi.patch
@@ -23,7 +23,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
/**
* struct panel_desc - Describes a simple panel.
-@@ -4874,6 +4875,9 @@ static const struct panel_desc_dsi osd10
+@@ -4875,6 +4876,9 @@ static const struct panel_desc_dsi osd10
.lanes = 4,
};
@@ -33,7 +33,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
static const struct of_device_id dsi_of_match[] = {
{
.compatible = "auo,b080uan01",
-@@ -4897,20 +4901,137 @@ static const struct of_device_id dsi_of_
+@@ -4898,20 +4902,137 @@ static const struct of_device_id dsi_of_
.compatible = "osddisplays,osd101t2045-53ts",
.data = &osd101t2045_53ts
}, {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0835-mmc-sdhci-brcmstb-remove-32-bit-accessors-for-BCM271.patch b/target/linux/bcm27xx/patches-6.6/950-0835-mmc-sdhci-brcmstb-remove-32-bit-accessors-for-BCM271.patch
index 88361d889e..04ca482a63 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0835-mmc-sdhci-brcmstb-remove-32-bit-accessors-for-BCM271.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0835-mmc-sdhci-brcmstb-remove-32-bit-accessors-for-BCM271.patch
@@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
default ARCH_BRCMSTB || BMIPS_GENERIC
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
-@@ -49,10 +49,6 @@ struct sdhci_brcmstb_priv {
+@@ -50,10 +50,6 @@ struct sdhci_brcmstb_priv {
unsigned int flags;
struct clk *base_clk;
u32 base_freq_hz;
@@ -37,7 +37,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
struct regulator *sde_1v8;
struct device_node *sde_pcie;
void *__iomem sde_ioaddr;
-@@ -121,113 +117,6 @@ static void sdhci_brcmstb_set_clock(stru
+@@ -122,113 +118,6 @@ static void sdhci_brcmstb_set_clock(stru
sdhci_enable_clk(host, clk);
}
@@ -151,7 +151,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static void sdhci_brcmstb_set_power(struct sdhci_host *host, unsigned char mode,
unsigned short vdd)
{
-@@ -441,12 +330,6 @@ static struct sdhci_ops sdhci_brcmstb_op
+@@ -442,12 +331,6 @@ static struct sdhci_ops sdhci_brcmstb_op
};
static struct sdhci_ops sdhci_brcmstb_ops_2712 = {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch b/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch
index 612179f5e4..e089be3f37 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch
@@ -16,7 +16,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
-@@ -1312,6 +1312,9 @@ static int dwc3_core_init(struct dwc3 *d
+@@ -1366,6 +1366,9 @@ static int dwc3_core_init(struct dwc3 *d
if (dwc->parkmode_disable_hs_quirk)
reg |= DWC3_GUCTL1_PARKMODE_DISABLE_HS;
@@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (DWC3_VER_IS_WITHIN(DWC3, 290A, ANY) &&
(dwc->maximum_speed == USB_SPEED_HIGH ||
dwc->maximum_speed == USB_SPEED_FULL))
-@@ -1610,6 +1613,8 @@ static void dwc3_get_properties(struct d
+@@ -1664,6 +1667,8 @@ static void dwc3_get_properties(struct d
"snps,parkmode-disable-ss-quirk");
dwc->parkmode_disable_hs_quirk = device_property_read_bool(dev,
"snps,parkmode-disable-hs-quirk");
@@ -45,7 +45,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
#define DWC3_GUCTL1_RESUME_OPMODE_HS_HOST BIT(10)
/* Global Status Register */
-@@ -1115,10 +1116,12 @@ struct dwc3_scratchpad_array {
+@@ -1116,10 +1117,12 @@ struct dwc3_scratchpad_array {
* generation after resume from suspend.
* @ulpi_ext_vbus_drv: Set to confiure the upli chip to drives CPEN pin
* VBUS with an external supply.
@@ -62,7 +62,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
* @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
* @tx_de_emphasis: Tx de-emphasis value
* 0 - -6dB de-emphasis
-@@ -1341,6 +1344,7 @@ struct dwc3 {
+@@ -1344,6 +1347,7 @@ struct dwc3 {
unsigned ulpi_ext_vbus_drv:1;
unsigned parkmode_disable_ss_quirk:1;
unsigned parkmode_disable_hs_quirk:1;
diff --git a/target/linux/bcm27xx/patches-6.6/950-0891-drivers-mmc-sdhci-brcmstb-fix-usage-of-SD_PIN_SEL-on.patch b/target/linux/bcm27xx/patches-6.6/950-0891-drivers-mmc-sdhci-brcmstb-fix-usage-of-SD_PIN_SEL-on.patch
index 1ccb6e6a1f..1880914986 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0891-drivers-mmc-sdhci-brcmstb-fix-usage-of-SD_PIN_SEL-on.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0891-drivers-mmc-sdhci-brcmstb-fix-usage-of-SD_PIN_SEL-on.patch
@@ -22,7 +22,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
-@@ -38,7 +38,8 @@
+@@ -39,7 +39,8 @@
#define SDIO_CFG_SD_PIN_SEL 0x44
#define SDIO_CFG_SD_PIN_SEL_MASK 0x3
@@ -32,7 +32,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
#define SDIO_CFG_MAX_50MHZ_MODE 0x1ac
#define SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE BIT(31)
-@@ -102,6 +103,42 @@ static void sdhci_brcmstb_hs400es(struct
+@@ -103,6 +104,42 @@ static void sdhci_brcmstb_hs400es(struct
writel(reg, host->ioaddr + SDHCI_VENDOR);
}
@@ -75,7 +75,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static void sdhci_brcmstb_set_clock(struct sdhci_host *host, unsigned int clock)
{
u16 clk;
-@@ -161,22 +198,16 @@ static void sdhci_brcmstb_cfginit_2712(s
+@@ -162,22 +199,16 @@ static void sdhci_brcmstb_cfginit_2712(s
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_brcmstb_priv *brcmstb_priv = sdhci_pltfm_priv(pltfm_host);
@@ -102,7 +102,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_MAX_50MHZ_MODE);
reg &= ~SDIO_CFG_MAX_50MHZ_MODE_ENABLE;
reg |= SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE;
-@@ -190,12 +221,6 @@ static void sdhci_brcmstb_cfginit_2712(s
+@@ -191,12 +222,6 @@ static void sdhci_brcmstb_cfginit_2712(s
reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV;
reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN;
writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_CTRL);
@@ -115,7 +115,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
}
}
-@@ -330,7 +355,7 @@ static struct sdhci_ops sdhci_brcmstb_op
+@@ -331,7 +356,7 @@ static struct sdhci_ops sdhci_brcmstb_op
};
static struct sdhci_ops sdhci_brcmstb_ops_2712 = {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch b/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch
index 8be04170e3..ac6a07f16e 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch
@@ -30,7 +30,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -465,8 +465,6 @@ static void axi_chan_block_xfer_start(st
+@@ -389,8 +389,6 @@ static void axi_chan_block_xfer_start(st
return;
}
diff --git a/target/linux/bcm27xx/patches-6.6/950-0980-drivers-mmc-add-SD-support-for-Command-Queueing.patch b/target/linux/bcm27xx/patches-6.6/950-0980-drivers-mmc-add-SD-support-for-Command-Queueing.patch
index fa22327131..14eb62cfac 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0980-drivers-mmc-add-SD-support-for-Command-Queueing.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0980-drivers-mmc-add-SD-support-for-Command-Queueing.patch
@@ -91,7 +91,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
-@@ -1015,8 +1015,8 @@ static bool mmc_sd_card_using_v18(struct
+@@ -1016,8 +1016,8 @@ static bool mmc_sd_card_using_v18(struct
(SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
}
@@ -102,7 +102,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
{
struct mmc_host *host = card->host;
struct mmc_request mrq = {};
-@@ -1174,8 +1174,14 @@ static int sd_parse_ext_reg_perf(struct
+@@ -1175,8 +1175,14 @@ static int sd_parse_ext_reg_perf(struct
card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
/* Command queue support indicated via queue depth bits (0 to 4). */
@@ -118,7 +118,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
card->ext_perf.fno = fno;
card->ext_perf.page = page;
-@@ -1559,13 +1565,41 @@ cont:
+@@ -1563,13 +1569,41 @@ cont:
goto free_card;
}
diff --git a/target/linux/bcm27xx/patches-6.6/950-0981-drivers-sdhci-brcmstb-set-CQE-timer-clock-frequency.patch b/target/linux/bcm27xx/patches-6.6/950-0981-drivers-sdhci-brcmstb-set-CQE-timer-clock-frequency.patch
index fec43e0be6..cd3417e194 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0981-drivers-sdhci-brcmstb-set-CQE-timer-clock-frequency.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0981-drivers-sdhci-brcmstb-set-CQE-timer-clock-frequency.patch
@@ -17,7 +17,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
-@@ -41,6 +41,9 @@
+@@ -42,6 +42,9 @@
#define SDIO_CFG_SD_PIN_SEL_SD BIT(1)
#define SDIO_CFG_SD_PIN_SEL_MMC BIT(0)
@@ -27,7 +27,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
#define SDIO_CFG_MAX_50MHZ_MODE 0x1ac
#define SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE BIT(31)
#define SDIO_CFG_MAX_50MHZ_MODE_ENABLE BIT(0)
-@@ -201,7 +204,7 @@ static void sdhci_brcmstb_cfginit_2712(s
+@@ -202,7 +205,7 @@ static void sdhci_brcmstb_cfginit_2712(s
u32 uhs_mask = (MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104);
u32 hsemmc_mask = (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS200_1_2V_SDR |
MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V);
@@ -36,7 +36,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* If we support a speed that requires tuning,
-@@ -222,6 +225,11 @@ static void sdhci_brcmstb_cfginit_2712(s
+@@ -223,6 +226,11 @@ static void sdhci_brcmstb_cfginit_2712(s
reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN;
writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_CTRL);
}
@@ -48,7 +48,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
}
static int bcm2712_init_sd_express(struct sdhci_host *host, struct mmc_ios *ios)
-@@ -493,6 +501,8 @@ static int sdhci_brcmstb_probe(struct pl
+@@ -494,6 +502,8 @@ static int sdhci_brcmstb_probe(struct pl
return PTR_ERR(host);
pltfm_host = sdhci_priv(host);
@@ -57,7 +57,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
priv = sdhci_pltfm_priv(pltfm_host);
if (device_property_read_bool(&pdev->dev, "supports-cqe")) {
priv->flags |= BRCMSTB_PRIV_FLAGS_HAS_CQE;
-@@ -623,7 +633,6 @@ add_host:
+@@ -627,7 +637,6 @@ add_host:
if (res)
goto err;
diff --git a/target/linux/bcm27xx/patches-6.6/950-0983-drivers-mmc-preallocate-a-block-for-SD-extension-reg.patch b/target/linux/bcm27xx/patches-6.6/950-0983-drivers-mmc-preallocate-a-block-for-SD-extension-reg.patch
index b62fab5393..4d90245f36 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0983-drivers-mmc-preallocate-a-block-for-SD-extension-reg.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0983-drivers-mmc-preallocate-a-block-for-SD-extension-reg.patch
@@ -30,7 +30,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
kfree(card);
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
-@@ -1025,9 +1025,8 @@ int sd_write_ext_reg(struct mmc_card *ca
+@@ -1026,9 +1026,8 @@ int sd_write_ext_reg(struct mmc_card *ca
struct scatterlist sg;
u8 *reg_buf;
@@ -42,7 +42,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
mrq.cmd = &cmd;
mrq.data = &data;
-@@ -1059,8 +1058,6 @@ int sd_write_ext_reg(struct mmc_card *ca
+@@ -1060,8 +1059,6 @@ int sd_write_ext_reg(struct mmc_card *ca
mmc_set_data_timeout(&data, card);
mmc_wait_for_req(host, &mrq);
@@ -51,7 +51,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Note that, the SD card is allowed to signal busy on DAT0 up to 1s
* after the CMD49. Although, let's leave this to be managed by the
-@@ -1101,9 +1098,7 @@ static int sd_parse_ext_reg_power(struct
+@@ -1102,9 +1099,7 @@ static int sd_parse_ext_reg_power(struct
int err;
u8 *reg_buf;
@@ -62,7 +62,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/* Read the extension register for power management function. */
err = sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
-@@ -1133,7 +1128,6 @@ static int sd_parse_ext_reg_power(struct
+@@ -1134,7 +1129,6 @@ static int sd_parse_ext_reg_power(struct
card->ext_power.offset = offset;
out:
@@ -70,7 +70,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
return err;
}
-@@ -1143,9 +1137,7 @@ static int sd_parse_ext_reg_perf(struct
+@@ -1144,9 +1138,7 @@ static int sd_parse_ext_reg_perf(struct
int err;
u8 *reg_buf;
@@ -81,7 +81,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
err = sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
if (err) {
-@@ -1188,7 +1180,6 @@ static int sd_parse_ext_reg_perf(struct
+@@ -1189,7 +1181,6 @@ static int sd_parse_ext_reg_perf(struct
card->ext_perf.offset = offset;
out:
@@ -89,7 +89,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
return err;
}
-@@ -1259,6 +1250,12 @@ static int sd_read_ext_regs(struct mmc_c
+@@ -1260,6 +1251,12 @@ static int sd_read_ext_regs(struct mmc_c
if (!gen_info_buf)
return -ENOMEM;
@@ -102,7 +102,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Read 512 bytes of general info, which is found at function number 0,
* at page 0 and with no offset.
-@@ -1325,9 +1322,7 @@ static int sd_flush_cache(struct mmc_hos
+@@ -1326,9 +1323,7 @@ static int sd_flush_cache(struct mmc_hos
if (!sd_cache_enabled(host))
return 0;
@@ -113,7 +113,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Set Flush Cache at bit 0 in the performance enhancement register at
-@@ -1363,21 +1358,15 @@ static int sd_flush_cache(struct mmc_hos
+@@ -1364,21 +1359,15 @@ static int sd_flush_cache(struct mmc_hos
if (reg_buf[0] & BIT(0))
err = -ETIMEDOUT;
out:
@@ -135,7 +135,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Set Cache Enable at bit 0 in the performance enhancement register at
* 260 bytes offset.
-@@ -1396,7 +1385,6 @@ static int sd_enable_cache(struct mmc_ca
+@@ -1397,7 +1386,6 @@ static int sd_enable_cache(struct mmc_ca
card->ext_perf.feature_enabled |= SD_EXT_PERF_CACHE;
out:
diff --git a/target/linux/bcm27xx/patches-6.6/950-0988-drivers-sdhci-brcmstb-work-around-mystery-CQE-CMD_ID.patch b/target/linux/bcm27xx/patches-6.6/950-0988-drivers-sdhci-brcmstb-work-around-mystery-CQE-CMD_ID.patch
index 342328ea2b..0e018a8242 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0988-drivers-sdhci-brcmstb-work-around-mystery-CQE-CMD_ID.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0988-drivers-sdhci-brcmstb-work-around-mystery-CQE-CMD_ID.patch
@@ -17,7 +17,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
-@@ -338,6 +338,7 @@ static void sdhci_brcmstb_dumpregs(struc
+@@ -339,6 +339,7 @@ static void sdhci_brcmstb_dumpregs(struc
static void sdhci_brcmstb_cqe_enable(struct mmc_host *mmc)
{
struct sdhci_host *host = mmc_priv(mmc);
@@ -25,7 +25,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
u32 reg;
reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
-@@ -347,6 +348,9 @@ static void sdhci_brcmstb_cqe_enable(str
+@@ -348,6 +349,9 @@ static void sdhci_brcmstb_cqe_enable(str
}
sdhci_cqe_enable(mmc);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0993-drivers-mmc-cqhci-clear-CQHCI_CTL-if-halt-fails.patch b/target/linux/bcm27xx/patches-6.6/950-0993-drivers-mmc-cqhci-clear-CQHCI_CTL-if-halt-fails.patch
index b572499935..bda518fc81 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0993-drivers-mmc-cqhci-clear-CQHCI_CTL-if-halt-fails.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0993-drivers-mmc-cqhci-clear-CQHCI_CTL-if-halt-fails.patch
@@ -31,15 +31,6 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc));
if (cq_host->ops->post_disable)
-@@ -612,7 +614,7 @@ static int cqhci_request(struct mmc_host
- cqhci_writel(cq_host, 0, CQHCI_CTL);
- mmc->cqe_on = true;
- pr_debug("%s: cqhci: CQE on\n", mmc_hostname(mmc));
-- if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) {
-+ if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) {
- pr_err("%s: cqhci: CQE failed to exit halt state\n",
- mmc_hostname(mmc));
- }
@@ -975,8 +977,11 @@ static bool cqhci_halt(struct mmc_host *
ret = cqhci_halted(cq_host);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0994-drivers-mmc-export-SD-extension-register-read-write-.patch b/target/linux/bcm27xx/patches-6.6/950-0994-drivers-mmc-export-SD-extension-register-read-write-.patch
index 78679702b2..e2347ed9d2 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0994-drivers-mmc-export-SD-extension-register-read-write-.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0994-drivers-mmc-export-SD-extension-register-read-write-.patch
@@ -16,7 +16,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
-@@ -1015,83 +1015,6 @@ static bool mmc_sd_card_using_v18(struct
+@@ -1016,83 +1016,6 @@ static bool mmc_sd_card_using_v18(struct
(SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
}
@@ -100,7 +100,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static int sd_parse_ext_reg_power(struct mmc_card *card, u8 fno, u8 page,
u16 offset)
{
-@@ -1101,7 +1024,7 @@ static int sd_parse_ext_reg_power(struct
+@@ -1102,7 +1025,7 @@ static int sd_parse_ext_reg_power(struct
reg_buf = card->ext_reg_buf;
/* Read the extension register for power management function. */
@@ -109,7 +109,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d reading PM func of ext reg\n",
mmc_hostname(card->host), err);
-@@ -1139,7 +1062,7 @@ static int sd_parse_ext_reg_perf(struct
+@@ -1140,7 +1063,7 @@ static int sd_parse_ext_reg_perf(struct
reg_buf = card->ext_reg_buf;
@@ -118,7 +118,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d reading PERF func of ext reg\n",
mmc_hostname(card->host), err);
-@@ -1234,7 +1157,7 @@ static int sd_parse_ext_reg(struct mmc_c
+@@ -1235,7 +1158,7 @@ static int sd_parse_ext_reg(struct mmc_c
return 0;
}
@@ -127,7 +127,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
{
int err, i;
u8 num_ext, *gen_info_buf;
-@@ -1260,7 +1183,7 @@ static int sd_read_ext_regs(struct mmc_c
+@@ -1261,7 +1184,7 @@ static int sd_read_ext_regs(struct mmc_c
* Read 512 bytes of general info, which is found at function number 0,
* at page 0 and with no offset.
*/
@@ -136,7 +136,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_err("%s: error %d reading general info of SD ext reg\n",
mmc_hostname(card->host), err);
-@@ -1332,7 +1255,7 @@ static int sd_flush_cache(struct mmc_hos
+@@ -1333,7 +1256,7 @@ static int sd_flush_cache(struct mmc_hos
page = card->ext_perf.page;
offset = card->ext_perf.offset + 261;
@@ -145,7 +145,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d writing Cache Flush bit\n",
mmc_hostname(host), err);
-@@ -1348,7 +1271,7 @@ static int sd_flush_cache(struct mmc_hos
+@@ -1349,7 +1272,7 @@ static int sd_flush_cache(struct mmc_hos
* Read the Flush Cache bit. The card shall reset it, to confirm that
* it's has completed the flushing of the cache.
*/
@@ -154,7 +154,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d reading Cache Flush bit\n",
mmc_hostname(host), err);
-@@ -1371,7 +1294,7 @@ static int sd_enable_cache(struct mmc_ca
+@@ -1372,7 +1295,7 @@ static int sd_enable_cache(struct mmc_ca
* Set Cache Enable at bit 0 in the performance enhancement register at
* 260 bytes offset.
*/
@@ -163,7 +163,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
card->ext_perf.offset + 260, BIT(0));
if (err) {
pr_warn("%s: error %d writing Cache Enable bit\n",
-@@ -1541,7 +1464,7 @@ retry:
+@@ -1545,7 +1468,7 @@ retry:
cont:
if (!oldcard) {
/* Read/parse the extension registers. */
@@ -172,7 +172,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err)
goto free_card;
}
-@@ -1668,7 +1591,7 @@ static int sd_busy_poweroff_notify_cb(vo
+@@ -1672,7 +1595,7 @@ static int sd_busy_poweroff_notify_cb(vo
* one byte offset and is one byte long. The Power Off Notification
* Ready is bit 0.
*/
@@ -181,7 +181,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
card->ext_power.offset + 1, 1, data->reg_buf);
if (err) {
pr_warn("%s: error %d reading status reg of PM func\n",
-@@ -1694,7 +1617,7 @@ static int sd_poweroff_notify(struct mmc
+@@ -1698,7 +1621,7 @@ static int sd_poweroff_notify(struct mmc
* Set the Power Off Notification bit in the power management settings
* register at 2 bytes offset.
*/
diff --git a/target/linux/bcm27xx/patches-6.6/950-0995-drivers-mmc-be-more-cautious-when-manipulating-Comma.patch b/target/linux/bcm27xx/patches-6.6/950-0995-drivers-mmc-be-more-cautious-when-manipulating-Comma.patch
index 125f21cc7a..6a855757ac 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0995-drivers-mmc-be-more-cautious-when-manipulating-Comma.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0995-drivers-mmc-be-more-cautious-when-manipulating-Comma.patch
@@ -17,7 +17,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
-@@ -1088,8 +1088,12 @@ static int sd_parse_ext_reg_perf(struct
+@@ -1089,8 +1089,12 @@ static int sd_parse_ext_reg_perf(struct
if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card))
card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
diff --git a/target/linux/bcm27xx/patches-6.6/950-0996-drivers-mmc-add-debugfs-entries-for-SD-extension-reg.patch b/target/linux/bcm27xx/patches-6.6/950-0996-drivers-mmc-add-debugfs-entries-for-SD-extension-reg.patch
index 581fd19fc5..c12229ece9 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0996-drivers-mmc-add-debugfs-entries-for-SD-extension-reg.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0996-drivers-mmc-add-debugfs-entries-for-SD-extension-reg.patch
@@ -27,7 +27,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
pr_info("%s: Host Software Queue enabled\n",
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
-@@ -714,7 +714,8 @@ MMC_DEV_ATTR(oemid, "0x%04x\n", card->ci
+@@ -715,7 +715,8 @@ MMC_DEV_ATTR(oemid, "0x%04x\n", card->ci
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
@@ -37,7 +37,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static ssize_t mmc_dsr_show(struct device *dev, struct device_attribute *attr,
char *buf)
-@@ -776,6 +777,8 @@ static struct attribute *sd_std_attrs[]
+@@ -777,6 +778,8 @@ static struct attribute *sd_std_attrs[]
&dev_attr_ocr.attr,
&dev_attr_rca.attr,
&dev_attr_dsr.attr,
@@ -46,7 +46,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
NULL,
};
-@@ -1508,8 +1511,8 @@ cont:
+@@ -1512,8 +1515,8 @@ cont:
host->cqe_enabled = true;
if (card->ext_csd.cmdq_en) {
diff --git a/target/linux/bcm27xx/patches-6.6/950-0997-drivers-mmc-handle-1024-byte-SD-General-Info-lengths.patch b/target/linux/bcm27xx/patches-6.6/950-0997-drivers-mmc-handle-1024-byte-SD-General-Info-lengths.patch
index 318bd191f6..55b369d659 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0997-drivers-mmc-handle-1024-byte-SD-General-Info-lengths.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0997-drivers-mmc-handle-1024-byte-SD-General-Info-lengths.patch
@@ -14,7 +14,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
-@@ -1176,7 +1176,7 @@ static int mmc_sd_read_ext_regs(struct m
+@@ -1177,7 +1177,7 @@ static int mmc_sd_read_ext_regs(struct m
if (!(card->scr.cmds & SD_SCR_CMD48_SUPPORT))
return 0;
@@ -23,7 +23,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (!gen_info_buf)
return -ENOMEM;
-@@ -1207,14 +1207,23 @@ static int mmc_sd_read_ext_regs(struct m
+@@ -1208,14 +1208,23 @@ static int mmc_sd_read_ext_regs(struct m
num_ext = gen_info_buf[4];
/*
diff --git a/target/linux/bcm27xx/patches-6.6/950-1018-drivers-mmc-apply-SD-quirks-earlier-during-probe.patch b/target/linux/bcm27xx/patches-6.6/950-1018-drivers-mmc-apply-SD-quirks-earlier-during-probe.patch
deleted file mode 100644
index 3225d87ff1..0000000000
--- a/target/linux/bcm27xx/patches-6.6/950-1018-drivers-mmc-apply-SD-quirks-earlier-during-probe.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 598e155f3467316b9ad70bde46b92fc30e3eea73 Mon Sep 17 00:00:00 2001
-From: Jonathan Bell <jonathan@raspberrypi.com>
-Date: Mon, 8 Apr 2024 16:01:34 +0100
-Subject: [PATCH 1018/1085] drivers: mmc: apply SD quirks earlier during probe
-
-Applying MMC_QUIRK_BROKEN_SD_CACHE is broken, as the card's extended
-registers are parsed prior to the quirk being applied in mmc_blk.
-
-Split this out into an SD-specific list of quirks and apply in
-mmc_sd_init_card instead.
-
-Fixes: c467c8f08185 ("mmc: Add MMC_QUIRK_BROKEN_SD_CACHE for Kingston Canvas Go Plus from 11/2019")
-
-Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
----
- drivers/mmc/core/quirks.h | 22 +++++++++++++---------
- drivers/mmc/core/sd.c | 4 ++++
- 2 files changed, 17 insertions(+), 9 deletions(-)
-
---- a/drivers/mmc/core/quirks.h
-+++ b/drivers/mmc/core/quirks.h
-@@ -15,6 +15,19 @@
-
- #include "card.h"
-
-+static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
-+ /*
-+ * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
-+ * This has so far only been observed on cards from 11/2019, while new
-+ * cards from 2023/05 do not exhibit this behavior.
-+ */
-+ _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
-+ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
-+ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
-+
-+ END_FIXUP
-+};
-+
- static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
- #define INAND_CMD38_ARG_EXT_CSD 113
- #define INAND_CMD38_ARG_ERASE 0x00
-@@ -54,15 +67,6 @@ static const struct mmc_fixup __maybe_un
- MMC_QUIRK_BLK_NO_CMD23),
-
- /*
-- * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
-- * This has so far only been observed on cards from 11/2019, while new
-- * cards from 2023/05 do not exhibit this behavior.
-- */
-- _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
-- 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
-- MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
--
-- /*
- * Some SD cards lockup while using CMD23 multiblock transfers.
- */
- MMC_FIXUP("AF SD", CID_MANFID_ATP, CID_OEMID_ANY, add_quirk_sd,
---- a/drivers/mmc/core/sd.c
-+++ b/drivers/mmc/core/sd.c
-@@ -26,6 +26,7 @@
- #include "host.h"
- #include "bus.h"
- #include "mmc_ops.h"
-+#include "quirks.h"
- #include "sd.h"
- #include "sd_ops.h"
-
-@@ -1408,6 +1409,9 @@ retry:
- goto free_card;
- }
-
-+ /* Apply quirks prior to card setup */
-+ mmc_fixup_device(card, mmc_sd_fixups);
-+
- err = mmc_sd_setup_card(host, card, oldcard != NULL);
- if (err)
- goto free_card;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1020-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS400es-a.patch b/target/linux/bcm27xx/patches-6.6/950-1020-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS400es-a.patch
index 110c705c64..d1cf7811b0 100644
--- a/target/linux/bcm27xx/patches-6.6/950-1020-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS400es-a.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-1020-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS400es-a.patch
@@ -14,7 +14,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
-@@ -400,6 +400,8 @@ static const struct brcmstb_match_priv m
+@@ -401,6 +401,8 @@ static const struct brcmstb_match_priv m
};
static const struct brcmstb_match_priv match_priv_2712 = {
diff --git a/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch b/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch
index 36d5b7cf1d..d7d4ca6172 100644
--- a/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch
@@ -22,7 +22,7 @@ Signed-off-by: Dom Cobley <popcornmix@gmail.com>
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -916,6 +916,9 @@ dw_axi_dma_chan_prep_slave_sg(struct dma
+@@ -834,6 +834,9 @@ dw_axi_dma_chan_prep_slave_sg(struct dma
mem = sg_dma_address(sg);
len = sg_dma_len(sg);
num_segments = DIV_ROUND_UP(sg_dma_len(sg), axi_block_len);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1069-drm-panel-simple-Fix-7inch-panel-mode-for-misalignme.patch b/target/linux/bcm27xx/patches-6.6/950-1069-drm-panel-simple-Fix-7inch-panel-mode-for-misalignme.patch
index 29f4fb78af..6a413ec90b 100644
--- a/target/linux/bcm27xx/patches-6.6/950-1069-drm-panel-simple-Fix-7inch-panel-mode-for-misalignme.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-1069-drm-panel-simple-Fix-7inch-panel-mode-for-misalignme.patch
@@ -16,7 +16,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
-@@ -3420,11 +3420,11 @@ static const struct drm_display_mode ras
+@@ -3421,11 +3421,11 @@ static const struct drm_display_mode ras
.hdisplay = 800,
.hsync_start = 800 + 59,
.hsync_end = 800 + 59 + 2,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1070-drm-panel-simple-Increase-pixel-clock-on-Pi-7inch-pa.patch b/target/linux/bcm27xx/patches-6.6/950-1070-drm-panel-simple-Increase-pixel-clock-on-Pi-7inch-pa.patch
index 30f56faf4d..68129c8de9 100644
--- a/target/linux/bcm27xx/patches-6.6/950-1070-drm-panel-simple-Increase-pixel-clock-on-Pi-7inch-pa.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-1070-drm-panel-simple-Increase-pixel-clock-on-Pi-7inch-pa.patch
@@ -21,7 +21,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
-@@ -3416,11 +3416,11 @@ static const struct panel_desc rocktech_
+@@ -3417,11 +3417,11 @@ static const struct panel_desc rocktech_
};
static const struct drm_display_mode raspberrypi_7inch_mode = {
diff --git a/target/linux/bcm27xx/patches-6.6/950-1112-mmc-sdhci-brcmstb-add-hs400_downgrade-callback-for-b.patch b/target/linux/bcm27xx/patches-6.6/950-1112-mmc-sdhci-brcmstb-add-hs400_downgrade-callback-for-b.patch
index 3238a62827..0c9a842ce6 100644
--- a/target/linux/bcm27xx/patches-6.6/950-1112-mmc-sdhci-brcmstb-add-hs400_downgrade-callback-for-b.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-1112-mmc-sdhci-brcmstb-add-hs400_downgrade-callback-for-b.patch
@@ -17,7 +17,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
-@@ -197,6 +197,20 @@ static void sdhci_brcmstb_set_uhs_signal
+@@ -198,6 +198,20 @@ static void sdhci_brcmstb_set_uhs_signal
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
}
@@ -38,7 +38,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static void sdhci_brcmstb_cfginit_2712(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-@@ -215,6 +229,8 @@ static void sdhci_brcmstb_cfginit_2712(s
+@@ -216,6 +230,8 @@ static void sdhci_brcmstb_cfginit_2712(s
reg &= ~SDIO_CFG_MAX_50MHZ_MODE_ENABLE;
reg |= SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE;
writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_MAX_50MHZ_MODE);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1116-mmc-sdhci-extend-maximum-ADMA-transfer-length-to-4Mi.patch b/target/linux/bcm27xx/patches-6.6/950-1116-mmc-sdhci-extend-maximum-ADMA-transfer-length-to-4Mi.patch
index 812d43b6cf..f0756b5945 100644
--- a/target/linux/bcm27xx/patches-6.6/950-1116-mmc-sdhci-extend-maximum-ADMA-transfer-length-to-4Mi.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-1116-mmc-sdhci-extend-maximum-ADMA-transfer-length-to-4Mi.patch
@@ -24,7 +24,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
BUG_ON(data->blksz > host->mmc->max_blk_size);
BUG_ON(data->blocks > 65535);
-@@ -4724,11 +4724,16 @@ int sdhci_setup_host(struct sdhci_host *
+@@ -4727,11 +4727,16 @@ int sdhci_setup_host(struct sdhci_host *
spin_lock_init(&host->lock);
/*
diff --git a/target/linux/bcm27xx/patches-6.6/950-1133-drivers-mmc-sdhci-brcmstb-improve-bcm2712-card-remov.patch b/target/linux/bcm27xx/patches-6.6/950-1133-drivers-mmc-sdhci-brcmstb-improve-bcm2712-card-remov.patch
new file mode 100644
index 0000000000..6b772084fb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1133-drivers-mmc-sdhci-brcmstb-improve-bcm2712-card-remov.patch
@@ -0,0 +1,52 @@
+From 5c0f94088e0694220a2f0d8ad6e8216b50a80f2e Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Thu, 13 Jun 2024 15:01:02 +0100
+Subject: [PATCH 1133/1145] drivers: mmc: sdhci-brcmstb: improve bcm2712 card
+ removal handling
+
+If the controller is being reset, then the CQE needs to be reset as well.
+
+For removable cards, CQHCI_SSC1 must specify a polling mode (CBC=0)
+otherwise it's possible that the controller stops emitting periodic
+CMD13s on card removal, without raising an error status interrupt.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/mmc/host/sdhci-brcmstb.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -366,8 +366,21 @@ static void sdhci_brcmstb_cqe_enable(str
+
+ sdhci_cqe_enable(mmc);
+
+- /* Reset CMD13 polling timer back to eMMC specification default */
+- cqhci_writel(cq_host, 0x00011000, CQHCI_SSC1);
++ /*
++ * The controller resets this register to a very short default interval
++ * whenever CQHCI is disabled.
++ *
++ * For removable cards CBC needs to be clear or card removal can hang
++ * the CQE. In polling mode, a CIT of 0x4000 "cycles" seems to produce the best
++ * throughput.
++ *
++ * For nonremovable cards, the specification default of CBC=1 CIT=0x1000
++ * suffices.
++ */
++ if (mmc->caps & MMC_CAP_NONREMOVABLE)
++ cqhci_writel(cq_host, 0x00011000, CQHCI_SSC1);
++ else
++ cqhci_writel(cq_host, 0x00004000, CQHCI_SSC1);
+ }
+
+ static const struct cqhci_host_ops sdhci_brcmstb_cqhci_ops = {
+@@ -387,7 +400,7 @@ static struct sdhci_ops sdhci_brcmstb_op
+ .set_clock = sdhci_bcm2712_set_clock,
+ .set_power = sdhci_brcmstb_set_power,
+ .set_bus_width = sdhci_set_bus_width,
+- .reset = sdhci_reset,
++ .reset = brcmstb_reset,
+ .set_uhs_signaling = sdhci_set_uhs_signaling,
+ .init_sd_express = bcm2712_init_sd_express,
+ };
diff --git a/target/linux/bcm27xx/patches-6.6/950-1136-feat-Add-support-for-SunFounder-PiPower-3-overlay.patch b/target/linux/bcm27xx/patches-6.6/950-1136-feat-Add-support-for-SunFounder-PiPower-3-overlay.patch
new file mode 100644
index 0000000000..45b94b7f17
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1136-feat-Add-support-for-SunFounder-PiPower-3-overlay.patch
@@ -0,0 +1,193 @@
+From a1d3defcca200077e1e382fe049ca613d16efd2b Mon Sep 17 00:00:00 2001
+From: Cavon Lee <cavonxx@gmail.com>
+Date: Tue, 18 Jun 2024 14:01:23 +0800
+Subject: [PATCH 1136/1145] feat: Add support for SunFounder PiPower 3 overlay
+ fix: Fix wrong Pironman 5 ir default pin number fix: Change space indentation
+ to tab
+
+Signed-off-by: Cavon Lee <cavonxx@gmail.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 8 +-
+ .../overlays/sunfounder-pipower3-overlay.dts | 44 ++++++++++
+ .../overlays/sunfounder-pironman5-overlay.dts | 88 ++++++++++---------
+ 4 files changed, 98 insertions(+), 43 deletions(-)
+ create mode 100644 arch/arm/boot/dts/overlays/sunfounder-pipower3-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -275,6 +275,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ ssd1306-spi.dtbo \
+ ssd1331-spi.dtbo \
+ ssd1351-spi.dtbo \
++ sunfounder-pipower3.dtbo \
+ sunfounder-pironman5.dtbo \
+ superaudioboard.dtbo \
+ sx150x.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -4695,11 +4695,17 @@ Params: speed SPI bus
+ reset_pin GPIO pin for RESET (default 25)
+
+
++Name: sunfounder-pipower3
++Info: Overlay for SunFounder PiPower 3
++Load: dtoverlay=sunfounder-pipower3,<param>=<val>
++Params: poweroff_pin Change poweroff pin (default 26)
++
++
+ Name: sunfounder-pironman5
+ Info: Overlay for SunFounder Pironman 5
+ Load: dtoverlay=sunfounder-pironman5,<param>=<val>
+ Params: ir Enable IR or not (on or off, default on)
+- ir_pins Change IR receiver pin (default 12)
++ ir_pins Change IR receiver pin (default 13)
+
+
+ Name: superaudioboard
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/sunfounder-pipower3-overlay.dts
+@@ -0,0 +1,44 @@
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target-path = "/chosen";
++ __overlay__ {
++ power: power {
++ hat_current_supply = <5000>;
++ };
++ };
++ };
++ fragment@1 {
++ target = <&i2c1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++ fragment@2 {
++ target-path = "/";
++ __overlay__ {
++ power_ctrl: power_ctrl {
++ compatible = "gpio-poweroff";
++ gpios = <&gpio 26 0>;
++ force;
++ };
++ };
++ };
++ fragment@3 {
++ target = <&gpio>;
++ __overlay__ {
++ power_ctrl_pins: power_ctrl_pins {
++ brcm,pins = <26>;
++ brcm,function = <1>; // out
++ };
++ };
++ };
++ __overrides__ {
++ poweroff_pin = <&power_ctrl>,"gpios:4",
++ <&power_ctrl_pins>,"brcm,pins:0";
++ };
++};
+--- a/arch/arm/boot/dts/overlays/sunfounder-pironman5-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sunfounder-pironman5-overlay.dts
+@@ -2,50 +2,54 @@
+ /plugin/;
+
+ / {
+- compatible = "brcm,bcm2835";
++ compatible = "brcm,bcm2835";
+
+- fragment@0 {
+- target = <&i2c1>;
+- __overlay__ {
+- status = "okay";
+- };
+- };
+- fragment@1 {
+- target = <&spi0>;
+- __overlay__ {
+- status = "okay";
+- };
+- };
+- fragment@2 {
+- target-path = "/";
+- __overlay__ {
+- gpio_ir: ir-receiver@c {
+- compatible = "gpio-ir-receiver";
+- pinctrl-names = "default";
+- pinctrl-0 = <&gpio_ir_pins>;
++ fragment@0 {
++ target = <&i2c1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++ fragment@1 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++ fragment@2 {
++ target-path = "/";
++ __overlay__ {
++ gpio_ir: ir-receiver@d {
++ compatible = "gpio-ir-receiver";
++ pinctrl-names = "default";
++ pinctrl-0 = <&gpio_ir_pins>;
+
+- // pin number, high or low
+- gpios = <&gpio 12 1>;
++ // pin number, high or low
++ gpios = <&gpio 13 1>;
+
+- // parameter for keymap name
+- linux,rc-map-name = "rc-rc6-mce";
++ // parameter for keymap name
++ linux,rc-map-name = "rc-rc6-mce";
+
+- status = "okay";
+- };
+- };
+- };
+- fragment@3 {
+- target = <&gpio>;
+- __overlay__ {
+- gpio_ir_pins: gpio_ir_pins@c {
+- brcm,pins = <12>;
+- brcm,function = <0>;
+- brcm,pull = <2>;
+- };
+- };
+- };
+- __overrides__ {
+- ir = <&gpio_ir>,"status";
+- ir_pins = <&gpio_ir>,"gpios:4", <&gpio_ir>,"reg:0", <&gpio_ir_pins>,"brcm,pins:0", <&gpio_ir_pins>,"reg:0";
+- };
++ status = "okay";
++ };
++ };
++ };
++ fragment@3 {
++ target = <&gpio>;
++ __overlay__ {
++ gpio_ir_pins: gpio_ir_pins@d {
++ brcm,pins = <13>;
++ brcm,function = <0>;
++ brcm,pull = <2>;
++ };
++ };
++ };
++ __overrides__ {
++ ir = <&gpio_ir>,"status";
++ ir_pins =
++ <&gpio_ir>,"gpios:4",
++ <&gpio_ir>,"reg:0",
++ <&gpio_ir_pins>,"brcm,pins:0",
++ <&gpio_ir_pins>,"reg:0";
++ };
+ };
diff --git a/target/linux/bcm27xx/patches-6.6/950-1137-pwm-gpio-pwm-follow-pwm_apply_might_sleep-rename.patch b/target/linux/bcm27xx/patches-6.6/950-1137-pwm-gpio-pwm-follow-pwm_apply_might_sleep-rename.patch
new file mode 100644
index 0000000000..b763006154
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1137-pwm-gpio-pwm-follow-pwm_apply_might_sleep-rename.patch
@@ -0,0 +1,32 @@
+From cd92a9591833ea06d1f12391f6b027fcecf436a9 Mon Sep 17 00:00:00 2001
+From: Ratchanan Srirattanamet <peathot@hotmail.com>
+Date: Tue, 18 Jun 2024 15:44:13 +0700
+Subject: [PATCH 1137/1145] pwm: gpio-pwm: follow pwm_apply_might_sleep()
+ rename
+
+Fixes: 03286093be68("drivers/gpio: Add a driver that wraps the PWM API as a GPIO controller")
+Signed-off-by: Ratchanan Srirattanamet <peathot@hotmail.com>
+---
+ drivers/gpio/gpio-pwm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpio/gpio-pwm.c
++++ b/drivers/gpio/gpio-pwm.c
+@@ -34,7 +34,7 @@ static void pwm_gpio_set(struct gpio_chi
+
+ pwm_get_state(pwm_gpio->pwm[off], &state);
+ state.duty_cycle = val ? state.period : 0;
+- pwm_apply_state(pwm_gpio->pwm[off], &state);
++ pwm_apply_might_sleep(pwm_gpio->pwm[off], &state);
+ }
+
+ static int pwm_gpio_parse_dt(struct pwm_gpio *pwm_gpio,
+@@ -79,7 +79,7 @@ static int pwm_gpio_parse_dt(struct pwm_
+ pwm_init_state(pwm_gpio->pwm[i], &state);
+
+ state.duty_cycle = 0;
+- pwm_apply_state(pwm_gpio->pwm[i], &state);
++ pwm_apply_might_sleep(pwm_gpio->pwm[i], &state);
+ }
+
+ pwm_gpio->gc.ngpio = num_gpios;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1138-drm-bridge-panel-Ensure-backlight-is-reachable.patch b/target/linux/bcm27xx/patches-6.6/950-1138-drm-bridge-panel-Ensure-backlight-is-reachable.patch
new file mode 100644
index 0000000000..b19941bc8a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1138-drm-bridge-panel-Ensure-backlight-is-reachable.patch
@@ -0,0 +1,29 @@
+From da87f91ad8450ccc5274cd7b6ba8d823b396c96f Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 18 Jun 2024 15:33:30 +0100
+Subject: [PATCH 1138/1145] drm/bridge: panel: Ensure backlight is reachable
+
+Ensure that the various options of modules vs builtin results
+in being able to call into the backlight code.
+
+https://github.com/raspberrypi/linux/issues/6198
+
+Fixes: 573f8fd0abf1 ("drm/bridge: panel: Name an associated backlight device")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/bridge/panel.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpu/drm/bridge/panel.c
++++ b/drivers/gpu/drm/bridge/panel.c
+@@ -87,8 +87,10 @@ static int panel_bridge_attach(struct dr
+ drm_connector_attach_encoder(&panel_bridge->connector,
+ bridge->encoder);
+
++#if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE)
+ backlight_set_display_name(panel_bridge->panel->backlight,
+ panel_bridge->connector.name);
++#endif
+
+ if (bridge->dev->registered) {
+ if (connector->funcs->reset)
diff --git a/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch b/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch
new file mode 100644
index 0000000000..b05a8276df
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch
@@ -0,0 +1,36 @@
+From 7af85d54e39733bb9a236b95ea5ed1ab8277d560 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Tue, 11 Jun 2024 16:12:47 +0100
+Subject: [PATCH 1141/1145] fs/ntfs3: Fix memory corruption when page_size
+ changes
+
+The rework in fs/ntfs3: Reduce stack usage
+changes log->page_size but doesn't change the associated
+log->page_mask and log->page_bits.
+
+That results in the bytes value in read_log_page
+getting a negative value, which is bad when it is
+passed to memcpy.
+
+The kernel panic can be observed when connecting an
+ntfs formatted drive that has previously been connected
+to a Windows machine to a Raspberry Pi 5, which by defauilt
+uses a 16K kernel pagesize.
+
+Fixes: 865e7a7700d9 ("fs/ntfs3: Reduce stack usage")
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ fs/ntfs3/fslog.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -3914,6 +3914,8 @@ check_restart_area:
+ log->l_size = log->orig_file_size;
+ log->page_size = norm_file_page(t32, &log->l_size,
+ t32 == DefaultLogPageSize);
++ log->page_mask = log->page_size - 1;
++ log->page_bits = blksize_bits(log->page_size);
+ }
+
+ if (log->page_size != t32 ||
diff --git a/target/linux/bcm27xx/patches-6.6/950-1142-fixup-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS4.patch b/target/linux/bcm27xx/patches-6.6/950-1142-fixup-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS4.patch
new file mode 100644
index 0000000000..227d54cbbf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1142-fixup-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS4.patch
@@ -0,0 +1,26 @@
+From d2813c02131b9ddf938277f4123da7ccbd113ea7 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 24 Jun 2024 22:35:42 +0100
+Subject: [PATCH 1142/1145] fixup! drivers: mmc: sdhci-brcmstb: bcm2712
+ supports HS400es and clock gating
+
+Declaring auto-clockgate support for a host that can interface with
+SDIO cards is a bug.
+
+See: https://github.com/raspberrypi/linux/issues/6237
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/mmc/host/sdhci-brcmstb.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -430,7 +430,6 @@ static const struct brcmstb_match_priv m
+ };
+
+ static const struct brcmstb_match_priv match_priv_2712 = {
+- .flags = BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE,
+ .hs400es = sdhci_brcmstb_hs400es,
+ .cfginit = sdhci_brcmstb_cfginit_2712,
+ .ops = &sdhci_brcmstb_ops_2712,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1144-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch b/target/linux/bcm27xx/patches-6.6/950-1144-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch
new file mode 100644
index 0000000000..ad364196e9
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1144-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch
@@ -0,0 +1,346 @@
+From 3b42260d2130b5ca110c5340ab2bd055eede5968 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 28 Apr 2021 17:46:01 +0100
+Subject: [PATCH 1144/1145] dmaengine: dw-axi-dmac: Fixes for RP1
+
+Don't assume that DMA addresses of devices are the same as their
+physical addresses - convert correctly.
+
+The CFG2 register layout is used when there are more than 8 channels,
+but also when configured for more than 16 target peripheral devices
+because the index of the handshake signal has to be made wider.
+
+Reset the DMAC on probe
+
+The driver goes to the trouble of tracking when transfers have been
+paused, but then doesn't report that state when queried.
+
+Not having APB registers is not an error - for most use cases it's
+not even of interest, it's expected. Demote the message to debug level,
+which is disabled by default.
+
+Each channel has a descriptor pool, which is shared between transfers.
+It is unsafe to treat the total number of descriptors allocated from a
+pool as the number allocated to a specific transfer; doing so leads
+to releasing buffers that shouldn't be released and walking off the
+ends of descriptor lists. Instead, give each transfer descriptor its
+own count.
+
+Support partial transfers:
+Some use cases involve streaming from a device where the transfer only
+proceeds when the device's FIFO occupancy exceeds a certain threshold.
+In such cases (e.g. when pulling data from a UART) it is important to
+know how much data has been transferred so far, in order that remaining
+bytes can be read from the FIFO directly by software.
+
+Add the necessary code to provide this "residue" value with a finer,
+sub-transfer granularity.
+
+In order to prevent the occasional byte getting stuck in the DMA
+controller's internal buffers, restrict the destination memory width
+to the source register width.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 136 +++++++++++++++---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
+ 2 files changed, 116 insertions(+), 21 deletions(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -12,6 +12,7 @@
+ #include <linux/device.h>
+ #include <linux/dmaengine.h>
+ #include <linux/dmapool.h>
++#include <linux/dma-direct.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/err.h>
+ #include <linux/interrupt.h>
+@@ -84,6 +85,17 @@ axi_chan_iowrite64(struct axi_dma_chan *
+ iowrite32(upper_32_bits(val), chan->chan_regs + reg + 4);
+ }
+
++static inline u64
++axi_chan_ioread64(struct axi_dma_chan *chan, u32 reg)
++{
++ /*
++ * We split one 64 bit read into two 32 bit reads as some HW doesn't
++ * support 64 bit access.
++ */
++ return ((u64)ioread32(chan->chan_regs + reg + 4) << 32) +
++ ioread32(chan->chan_regs + reg);
++}
++
+ static inline void axi_chan_config_write(struct axi_dma_chan *chan,
+ struct axi_dma_chan_config *config)
+ {
+@@ -220,7 +232,18 @@ static void axi_dma_hw_init(struct axi_d
+ {
+ int ret;
+ u32 i;
++ int retries = 1000;
+
++ axi_dma_iowrite32(chip, DMAC_RESET, 1);
++ while (axi_dma_ioread32(chip, DMAC_RESET)) {
++ retries--;
++ if (!retries) {
++ dev_err(chip->dev, "%s: DMAC failed to reset\n",
++ __func__);
++ return;
++ }
++ cpu_relax();
++ }
+ for (i = 0; i < chip->dw->hdata->nr_channels; i++) {
+ axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
+ axi_chan_disable(&chip->dw->chan[i]);
+@@ -256,7 +279,6 @@ static struct axi_dma_desc *axi_desc_all
+ kfree(desc);
+ return NULL;
+ }
+- desc->nr_hw_descs = num;
+
+ return desc;
+ }
+@@ -283,7 +305,7 @@ static struct axi_dma_lli *axi_desc_get(
+ static void axi_desc_put(struct axi_dma_desc *desc)
+ {
+ struct axi_dma_chan *chan = desc->chan;
+- int count = desc->nr_hw_descs;
++ u32 count = desc->hw_desc_count;
+ struct axi_dma_hw_desc *hw_desc;
+ int descs_put;
+
+@@ -305,6 +327,48 @@ static void vchan_desc_put(struct virt_d
+ axi_desc_put(vd_to_axi_desc(vdesc));
+ }
+
++static u32 axi_dma_desc_src_pos(struct axi_dma_desc *desc, dma_addr_t addr)
++{
++ unsigned int idx = 0;
++ u32 pos = 0;
++
++ while (pos < desc->length) {
++ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++];
++ u32 len = hw_desc->len;
++ dma_addr_t start = le64_to_cpu(hw_desc->lli->sar);
++
++ if (addr >= start && addr <= (start + len)) {
++ pos += addr - start;
++ break;
++ }
++
++ pos += len;
++ }
++
++ return pos;
++}
++
++static u32 axi_dma_desc_dst_pos(struct axi_dma_desc *desc, dma_addr_t addr)
++{
++ unsigned int idx = 0;
++ u32 pos = 0;
++
++ while (pos < desc->length) {
++ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++];
++ u32 len = hw_desc->len;
++ dma_addr_t start = le64_to_cpu(hw_desc->lli->dar);
++
++ if (addr >= start && addr <= (start + len)) {
++ pos += addr - start;
++ break;
++ }
++
++ pos += len;
++ }
++
++ return pos;
++}
++
+ static enum dma_status
+ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+@@ -314,10 +378,7 @@ dma_chan_tx_status(struct dma_chan *dcha
+ enum dma_status status;
+ u32 completed_length;
+ unsigned long flags;
+- u32 completed_blocks;
+ size_t bytes = 0;
+- u32 length;
+- u32 len;
+
+ status = dma_cookie_status(dchan, cookie, txstate);
+ if (status == DMA_COMPLETE || !txstate)
+@@ -326,16 +387,31 @@ dma_chan_tx_status(struct dma_chan *dcha
+ spin_lock_irqsave(&chan->vc.lock, flags);
+
+ vdesc = vchan_find_desc(&chan->vc, cookie);
+- if (vdesc) {
+- length = vd_to_axi_desc(vdesc)->length;
+- completed_blocks = vd_to_axi_desc(vdesc)->completed_blocks;
+- len = vd_to_axi_desc(vdesc)->hw_desc[0].len;
+- completed_length = completed_blocks * len;
+- bytes = length - completed_length;
++ if (vdesc && vdesc == vchan_next_desc(&chan->vc)) {
++ /* This descriptor is in-progress */
++ struct axi_dma_desc *desc = vd_to_axi_desc(vdesc);
++ dma_addr_t addr;
++
++ if (chan->direction == DMA_MEM_TO_DEV) {
++ addr = axi_chan_ioread64(chan, CH_SAR);
++ completed_length = axi_dma_desc_src_pos(desc, addr);
++ } else if (chan->direction == DMA_DEV_TO_MEM) {
++ addr = axi_chan_ioread64(chan, CH_DAR);
++ completed_length = axi_dma_desc_dst_pos(desc, addr);
++ } else {
++ completed_length = 0;
++ }
++ bytes = desc->length - completed_length;
++ } else if (vdesc) {
++ /* Still in the queue so not started */
++ bytes = vd_to_axi_desc(vdesc)->length;
+ }
+
+- spin_unlock_irqrestore(&chan->vc.lock, flags);
++ if (chan->is_paused && status == DMA_IN_PROGRESS)
++ status = DMA_PAUSED;
++
+ dma_set_residue(txstate, bytes);
++ spin_unlock_irqrestore(&chan->vc.lock, flags);
+
+ return status;
+ }
+@@ -521,7 +597,7 @@ static void dw_axi_dma_set_hw_channel(st
+ unsigned long reg_value, val;
+
+ if (!chip->apb_regs) {
+- dev_err(chip->dev, "apb_regs not initialized\n");
++ dev_dbg(chip->dev, "apb_regs not initialized\n");
+ return;
+ }
+
+@@ -625,18 +701,25 @@ static int dw_axi_dma_set_hw_desc(struct
+ switch (chan->direction) {
+ case DMA_MEM_TO_DEV:
+ reg_width = __ffs(chan->config.dst_addr_width);
+- device_addr = chan->config.dst_addr;
++ device_addr = phys_to_dma(chan->chip->dev, chan->config.dst_addr);
+ ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS |
+ mem_width << CH_CTL_L_SRC_WIDTH_POS |
++ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_DST_MSIZE_POS |
++ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
+ DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS |
+ DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS;
+ block_ts = len >> mem_width;
+ break;
+ case DMA_DEV_TO_MEM:
+ reg_width = __ffs(chan->config.src_addr_width);
+- device_addr = chan->config.src_addr;
++ /* Prevent partial access units getting lost */
++ if (mem_width > reg_width)
++ mem_width = reg_width;
++ device_addr = phys_to_dma(chan->chip->dev, chan->config.src_addr);
+ ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS |
+ mem_width << CH_CTL_L_DST_WIDTH_POS |
++ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
++ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_SRC_MSIZE_POS |
+ DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
+ DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS;
+ block_ts = len >> reg_width;
+@@ -672,9 +755,6 @@ static int dw_axi_dma_set_hw_desc(struct
+ }
+
+ hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
+-
+- ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
+ hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
+
+ set_desc_src_master(hw_desc);
+@@ -769,6 +849,8 @@ dw_axi_dma_chan_prep_cyclic(struct dma_c
+ src_addr += segment_len;
+ }
+
++ desc->hw_desc_count = total_segments;
++
+ llp = desc->hw_desc[0].llp;
+
+ /* Managed transfer list */
+@@ -851,6 +933,8 @@ dw_axi_dma_chan_prep_slave_sg(struct dma
+ } while (len >= segment_len);
+ }
+
++ desc->hw_desc_count = loop;
++
+ /* Set end-of-link to the last link descriptor of list */
+ set_desc_last(&desc->hw_desc[num_sgs - 1]);
+
+@@ -958,6 +1042,8 @@ dma_chan_prep_dma_memcpy(struct dma_chan
+ num++;
+ }
+
++ desc->hw_desc_count = num;
++
+ /* Set end-of-link to the last link descriptor of list */
+ set_desc_last(&desc->hw_desc[num - 1]);
+ /* Managed transfer list */
+@@ -1006,7 +1092,7 @@ static void axi_chan_dump_lli(struct axi
+ static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
+ struct axi_dma_desc *desc_head)
+ {
+- int count = atomic_read(&chan->descs_allocated);
++ u32 count = desc_head->hw_desc_count;
+ int i;
+
+ for (i = 0; i < count; i++)
+@@ -1049,11 +1135,11 @@ out:
+
+ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
+ {
+- int count = atomic_read(&chan->descs_allocated);
+ struct axi_dma_hw_desc *hw_desc;
+ struct axi_dma_desc *desc;
+ struct virt_dma_desc *vd;
+ unsigned long flags;
++ u32 count;
+ u64 llp;
+ int i;
+
+@@ -1075,6 +1161,7 @@ static void axi_chan_block_xfer_complete
+ if (chan->cyclic) {
+ desc = vd_to_axi_desc(vd);
+ if (desc) {
++ count = desc->hw_desc_count;
+ llp = lo_hi_readq(chan->chan_regs + CH_LLP);
+ for (i = 0; i < count; i++) {
+ hw_desc = &desc->hw_desc[i];
+@@ -1095,6 +1182,9 @@ static void axi_chan_block_xfer_complete
+ /* Remove the completed descriptor from issued list before completing */
+ list_del(&vd->node);
+ vchan_cookie_complete(vd);
++
++ /* Submit queued descriptors after processing the completed ones */
++ axi_chan_start_first_queued(chan);
+ }
+
+ out:
+@@ -1324,6 +1414,10 @@ static int parse_device_properties(struc
+
+ chip->dw->hdata->nr_masters = tmp;
+
++ ret = device_property_read_u32(dev, "snps,dma-targets", &tmp);
++ if (!ret && tmp > 16)
++ chip->dw->hdata->use_cfg2 = true;
++
+ ret = device_property_read_u32(dev, "snps,data-width", &tmp);
+ if (ret)
+ return ret;
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -101,6 +101,7 @@ struct axi_dma_desc {
+
+ struct virt_dma_desc vd;
+ struct axi_dma_chan *chan;
++ u32 hw_desc_count;
+ u32 completed_blocks;
+ u32 length;
+ u32 period_len;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1145-fixup-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch b/target/linux/bcm27xx/patches-6.6/950-1145-fixup-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch
new file mode 100644
index 0000000000..adefd4ab54
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1145-fixup-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch
@@ -0,0 +1,89 @@
+From 769634f344626ed73bcda14c91b567067974d7b2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Sat, 29 Jun 2024 09:30:23 +0100
+Subject: [PATCH 1145/1145] fixup! dmaengine: dw-axi-dmac: Fixes for RP1
+
+nr_hw_descs is the upstream version of what count_hw_descs, so make
+(more) use of it instead.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 14 +++++++-------
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 -
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -305,7 +305,7 @@ static struct axi_dma_lli *axi_desc_get(
+ static void axi_desc_put(struct axi_dma_desc *desc)
+ {
+ struct axi_dma_chan *chan = desc->chan;
+- u32 count = desc->hw_desc_count;
++ int count = desc->nr_hw_descs;
+ struct axi_dma_hw_desc *hw_desc;
+ int descs_put;
+
+@@ -849,7 +849,7 @@ dw_axi_dma_chan_prep_cyclic(struct dma_c
+ src_addr += segment_len;
+ }
+
+- desc->hw_desc_count = total_segments;
++ desc->nr_hw_descs = total_segments;
+
+ llp = desc->hw_desc[0].llp;
+
+@@ -933,7 +933,7 @@ dw_axi_dma_chan_prep_slave_sg(struct dma
+ } while (len >= segment_len);
+ }
+
+- desc->hw_desc_count = loop;
++ desc->nr_hw_descs = loop;
+
+ /* Set end-of-link to the last link descriptor of list */
+ set_desc_last(&desc->hw_desc[num_sgs - 1]);
+@@ -1042,7 +1042,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan
+ num++;
+ }
+
+- desc->hw_desc_count = num;
++ desc->nr_hw_descs = num;
+
+ /* Set end-of-link to the last link descriptor of list */
+ set_desc_last(&desc->hw_desc[num - 1]);
+@@ -1092,7 +1092,7 @@ static void axi_chan_dump_lli(struct axi
+ static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
+ struct axi_dma_desc *desc_head)
+ {
+- u32 count = desc_head->hw_desc_count;
++ int count = desc_head->nr_hw_descs;
+ int i;
+
+ for (i = 0; i < count; i++)
+@@ -1139,7 +1139,7 @@ static void axi_chan_block_xfer_complete
+ struct axi_dma_desc *desc;
+ struct virt_dma_desc *vd;
+ unsigned long flags;
+- u32 count;
++ int count;
+ u64 llp;
+ int i;
+
+@@ -1161,7 +1161,7 @@ static void axi_chan_block_xfer_complete
+ if (chan->cyclic) {
+ desc = vd_to_axi_desc(vd);
+ if (desc) {
+- count = desc->hw_desc_count;
++ count = desc->nr_hw_descs;
+ llp = lo_hi_readq(chan->chan_regs + CH_LLP);
+ for (i = 0; i < count; i++) {
+ hw_desc = &desc->hw_desc[i];
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -101,7 +101,6 @@ struct axi_dma_desc {
+
+ struct virt_dma_desc vd;
+ struct axi_dma_chan *chan;
+- u32 hw_desc_count;
+ u32 completed_blocks;
+ u32 length;
+ u32 period_len;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch b/target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch
new file mode 100644
index 0000000000..b5f117f7f7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch
@@ -0,0 +1,260 @@
+From 65fddc7301f52470fd846acede96d240a1902e67 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Fri, 5 Jul 2024 14:00:38 +0100
+Subject: [PATCH 1146/1215] drivers: dwc_otg: use C11 style variable array
+ declarations
+
+The kernel C standard changed in 5.18.
+
+Remove a layer of indirection around the FIQ bounce buffers, be consistent
+with pointers to FIQ bounce buffers, and remove open-coded 32-bit clamping
+of DMA addresses.
+
+Also remove a pointless fiq_state initialisation loop.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 12 ++++----
+ drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 8 ++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 34 ++++++++++-----------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 4 +--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 4 +--
+ 5 files changed, 28 insertions(+), 34 deletions(-)
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
+@@ -240,8 +240,8 @@ static int notrace fiq_increment_dma_buf
+ hcdma_data_t hcdma;
+ int i = st->channel[n].dma_info.index;
+ int len;
+- struct fiq_dma_blob *blob =
+- (struct fiq_dma_blob *)(uintptr_t)st->dma_base;
++ struct fiq_dma_channel *split_dma =
++ (struct fiq_dma_channel *)(uintptr_t)st->dma_base;
+
+ len = fiq_get_xfer_len(st, n);
+ fiq_print(FIQDBG_INT, st, "LEN: %03d", len);
+@@ -250,7 +250,7 @@ static int notrace fiq_increment_dma_buf
+ if (i > 6)
+ BUG();
+
+- hcdma.d32 = (u32)(uintptr_t)&blob->channel[n].index[i].buf[0];
++ hcdma.d32 = lower_32_bits((uintptr_t)&split_dma[n].index[i].buf[0]);
+ FIQ_WRITE(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA, hcdma.d32);
+ st->channel[n].dma_info.index = i;
+ return 0;
+@@ -290,8 +290,8 @@ static int notrace fiq_iso_out_advance(s
+ hcsplt_data_t hcsplt;
+ hctsiz_data_t hctsiz;
+ hcdma_data_t hcdma;
+- struct fiq_dma_blob *blob =
+- (struct fiq_dma_blob *)(uintptr_t)st->dma_base;
++ struct fiq_dma_channel *split_dma =
++ (struct fiq_dma_channel *)(uintptr_t)st->dma_base;
+ int last = 0;
+ int i = st->channel[n].dma_info.index;
+
+@@ -303,7 +303,7 @@ static int notrace fiq_iso_out_advance(s
+ last = 1;
+
+ /* New DMA address - address of bounce buffer referred to in index */
+- hcdma.d32 = (u32)(uintptr_t)blob->channel[n].index[i].buf;
++ hcdma.d32 = lower_32_bits((uintptr_t)&split_dma[n].index[i].buf[0]);
+ //hcdma.d32 = FIQ_READ(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA);
+ //hcdma.d32 += st->channel[n].dma_info.slot_len[i];
+ fiq_print(FIQDBG_INT, st, "LAST: %01d ", last);
+--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
+@@ -263,10 +263,6 @@ struct fiq_dma_channel {
+ struct fiq_split_dma_slot index[6];
+ } __attribute__((packed));
+
+-struct fiq_dma_blob {
+- struct fiq_dma_channel channel[0];
+-} __attribute__((packed));
+-
+ /**
+ * struct fiq_hs_isoc_info - USB2.0 isochronous data
+ * @iso_frame: Pointer to the array of OTG URB iso_frame_descs.
+@@ -352,7 +348,7 @@ struct fiq_state {
+ mphi_regs_t mphi_regs;
+ void *dwc_regs_base;
+ dma_addr_t dma_base;
+- struct fiq_dma_blob *fiq_dmab;
++ struct fiq_dma_channel *fiq_dmab;
+ void *dummy_send;
+ dma_addr_t dummy_send_dma;
+ gintmsk_data_t gintmsk_saved;
+@@ -365,7 +361,7 @@ struct fiq_state {
+ char * buffer;
+ unsigned int bufsiz;
+ #endif
+- struct fiq_channel_state channel[0];
++ struct fiq_channel_state channel[];
+ };
+
+ #ifdef CONFIG_ARM64
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
+@@ -58,6 +58,7 @@ static int last_sel_trans_num_avail_hc_a
+ static int last_sel_trans_num_avail_hc_at_end = 0;
+ #endif /* DEBUG_HOST_CHANNELS */
+
++static_assert(FIQ_PASSTHROUGH == 0);
+
+ dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
+ {
+@@ -876,7 +877,7 @@ void dwc_otg_hcd_power_up(void *ptr)
+ void dwc_otg_cleanup_fiq_channel(dwc_otg_hcd_t *hcd, uint32_t num)
+ {
+ struct fiq_channel_state *st = &hcd->fiq_state->channel[num];
+- struct fiq_dma_blob *blob = hcd->fiq_dmab;
++ struct fiq_dma_channel *split_dma = hcd->fiq_dmab;
+ int i;
+
+ st->fsm = FIQ_PASSTHROUGH;
+@@ -898,7 +899,7 @@ void dwc_otg_cleanup_fiq_channel(dwc_otg
+ st->hs_isoc_info.iso_desc = NULL;
+ st->hs_isoc_info.nrframes = 0;
+
+- DWC_MEMSET(&blob->channel[num].index[0], 0x6b, 1128);
++ DWC_MEMSET(&split_dma[num].index[0], 0x6b, 1128);
+ }
+
+ /**
+@@ -1045,9 +1046,6 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
+ spin_lock_init(&hcd->fiq_state->lock);
+ #endif
+
+- for (i = 0; i < num_channels; i++) {
+- hcd->fiq_state->channel[i].fsm = FIQ_PASSTHROUGH;
+- }
+ hcd->fiq_state->dummy_send = DWC_DMA_ALLOC_ATOMIC(dev, 16,
+ &hcd->fiq_state->dummy_send_dma);
+
+@@ -1561,7 +1559,7 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ int frame_length, i = 0;
+ uint8_t *ptr = NULL;
+ dwc_hc_t *hc = qh->channel;
+- struct fiq_dma_blob *blob;
++ struct fiq_dma_channel *split_dma;
+ struct dwc_otg_hcd_iso_packet_desc *frame_desc;
+
+ for (i = 0; i < 6; i++) {
+@@ -1576,10 +1574,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ * Pointer arithmetic on hcd->fiq_state->dma_base (a dma_addr_t)
+ * to point it to the correct offset in the allocated buffers.
+ */
+- blob = (struct fiq_dma_blob *)
++ split_dma = (struct fiq_dma_channel *)
+ (uintptr_t)hcd->fiq_state->dma_base;
+- st->hcdma_copy.d32 =(u32)(uintptr_t)
+- blob->channel[hc->hc_num].index[0].buf;
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)
++ &split_dma[hc->hc_num].index[0].buf[0]);
+
+ /* Calculate the max number of CSPLITS such that the FIQ can time out
+ * a transaction if it fails.
+@@ -1600,7 +1598,7 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ frame_length = frame_desc->length;
+
+ /* Virtual address for bounce buffers */
+- blob = hcd->fiq_dmab;
++ split_dma = hcd->fiq_dmab;
+
+ ptr = qtd->urb->buf + frame_desc->offset;
+ if (frame_length == 0) {
+@@ -1613,11 +1611,11 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ } else {
+ do {
+ if (frame_length <= 188) {
+- dwc_memcpy(&blob->channel[hc->hc_num].index[i].buf[0], ptr, frame_length);
++ dwc_memcpy(&split_dma[hc->hc_num].index[i].buf[0], ptr, frame_length);
+ st->dma_info.slot_len[i] = frame_length;
+ ptr += frame_length;
+ } else {
+- dwc_memcpy(&blob->channel[hc->hc_num].index[i].buf[0], ptr, 188);
++ dwc_memcpy(&split_dma[hc->hc_num].index[i].buf[0], ptr, 188);
+ st->dma_info.slot_len[i] = 188;
+ ptr += 188;
+ }
+@@ -1634,10 +1632,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ * dma_addr_t) to point it to the correct offset in the
+ * allocated buffers.
+ */
+- blob = (struct fiq_dma_blob *)
++ split_dma = (struct fiq_dma_channel *)
+ (uintptr_t)hcd->fiq_state->dma_base;
+- st->hcdma_copy.d32 = (u32)(uintptr_t)
+- blob->channel[hc->hc_num].index[0].buf;
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)
++ &split_dma[hc->hc_num].index[0].buf[0]);
+
+ /* fixup xfersize to the actual packet size */
+ st->hctsiz_copy.b.pid = 0;
+@@ -1917,14 +1915,14 @@ int fiq_fsm_queue_split_transaction(dwc_
+ if (hc->align_buff) {
+ st->hcdma_copy.d32 = hc->align_buff;
+ } else {
+- st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)hc->xfer_buff);
+ }
+ }
+ } else {
+ if (hc->align_buff) {
+ st->hcdma_copy.d32 = hc->align_buff;
+ } else {
+- st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)hc->xfer_buff);
+ }
+ }
+ /* The FIQ depends upon no other interrupts being enabled except channel halt.
+@@ -1944,7 +1942,7 @@ int fiq_fsm_queue_split_transaction(dwc_
+ if (hc->align_buff) {
+ st->hcdma_copy.d32 = hc->align_buff;
+ } else {
+- st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)hc->xfer_buff);
+ }
+ }
+ DWC_WRITE_REG32(&hc_regs->hcdma, st->hcdma_copy.d32);
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
+@@ -88,7 +88,7 @@ struct dwc_otg_hcd_urb {
+ uint32_t flags;
+ uint16_t interval;
+ struct dwc_otg_hcd_pipe_info pipe_info;
+- struct dwc_otg_hcd_iso_packet_desc iso_descs[0];
++ struct dwc_otg_hcd_iso_packet_desc iso_descs[];
+ };
+
+ static inline uint8_t dwc_otg_hcd_get_ep_num(struct dwc_otg_hcd_pipe_info *pipe)
+@@ -592,7 +592,7 @@ struct dwc_otg_hcd {
+ struct fiq_state *fiq_state;
+
+ /** Virtual address for split transaction DMA bounce buffers */
+- struct fiq_dma_blob *fiq_dmab;
++ struct fiq_dma_channel *fiq_dmab;
+
+ #ifdef DEBUG
+ uint32_t frrem_samples;
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+@@ -2332,7 +2332,7 @@ void dwc_otg_fiq_unmangle_isoc(dwc_otg_h
+ int dwc_otg_fiq_unsetup_per_dma(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, dwc_otg_qtd_t *qtd, uint32_t num)
+ {
+ dwc_hc_t *hc = qh->channel;
+- struct fiq_dma_blob *blob = hcd->fiq_dmab;
++ struct fiq_dma_channel *split_dma = hcd->fiq_dmab;
+ struct fiq_channel_state *st = &hcd->fiq_state->channel[num];
+ uint8_t *ptr = NULL;
+ int index = 0, len = 0;
+@@ -2352,7 +2352,7 @@ int dwc_otg_fiq_unsetup_per_dma(dwc_otg_
+
+ for (i = 0; i < st->dma_info.index; i++) {
+ len += st->dma_info.slot_len[i];
+- dwc_memcpy(ptr, &blob->channel[num].index[i].buf[0], st->dma_info.slot_len[i]);
++ dwc_memcpy(ptr, &split_dma[num].index[i].buf[0], st->dma_info.slot_len[i]);
+ ptr += st->dma_info.slot_len[i];
+ }
+ return len;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch b/target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch
new file mode 100644
index 0000000000..14d0a79a73
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch
@@ -0,0 +1,27 @@
+From 8dea9155ab081289edd618f8373d5f980d5bb664 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 23 Feb 2024 10:40:47 +0100
+Subject: [PATCH 1147/1215] media: uapi: pixfmt-luma: Document MIPI CSI-2
+ packing
+
+The Y10P, Y12P and Y14P format variants are packed according to
+the RAW10, RAW12 and RAW14 formats as defined by the MIPI CSI-2
+specification. Document it.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
++++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
+@@ -161,3 +161,7 @@ are often referred to as greyscale forma
+ For Y012 and Y12 formats, Y012 places its data in the 12 high bits, with
+ padding zeros in the 4 low bits, in contrast to the Y12 format, which has
+ its padding located in the most significant bits of the 16 bit word.
++
++ The 'P' variations of the Y10, Y12 and Y14 formats are packed according to
++ the RAW10, RAW12 and RAW14 packing scheme as defined by the MIPI CSI-2
++ specification.
diff --git a/target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch b/target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch
new file mode 100644
index 0000000000..2f459044a3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch
@@ -0,0 +1,101 @@
+From 814c088cb7183f79ba68c8f9459505e2ac4dde3a Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 26 Jan 2024 15:03:18 +0100
+Subject: [PATCH 1148/1215] media: uapi: Add a pixel format for BGR48 and RGB48
+
+Add BGR48 and RGB48 16-bit per component image formats.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../userspace-api/media/v4l/pixfmt-rgb.rst | 54 +++++++++++++++++++
+ drivers/media/v4l2-core/v4l2-common.c | 2 +
+ include/uapi/linux/videodev2.h | 2 +
+ 3 files changed, 58 insertions(+)
+
+--- a/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
++++ b/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
+@@ -996,6 +996,60 @@ arranged in little endian order.
+
+ \normalsize
+
++16 Bits Per Component
++=====================
++
++These formats store an RGB triplet in six bytes, with 16 bits per component
++stored in memory in little endian byte order. They are named based on the order
++of the RGB components as stored in memory. For instance, RGB48 stores R\
++:sub:`7:0` and R\ :sub:`15:8` in bytes 0 and 1 respectively. This differs from
++the DRM format nomenclature that instead uses the order of components as seen in
++the 48-bits little endian word.
++
++.. raw:: latex
++
++ \small
++
++.. flat-table:: RGB Formats With 16 Bits Per Component
++ :header-rows: 1
++
++ * - Identifier
++ - Code
++ - Byte 0
++ - Byte 1
++ - Byte 2
++ - Byte 3
++ - Byte 4
++ - Byte 5
++
++ * .. _V4L2-PIX-FMT-BGR48:
++
++ - ``V4L2_PIX_FMT_BGR48``
++ - 'BGR6'
++
++ - B\ :sub:`7-0`
++ - B\ :sub:`15-8`
++ - G\ :sub:`7-0`
++ - G\ :sub:`15-8`
++ - R\ :sub:`7-0`
++ - R\ :sub:`15-8`
++
++ * .. _V4L2-PIX-FMT-RGB48:
++
++ - ``V4L2_PIX_FMT_RGB48``
++ - 'RGB6'
++
++ - R\ :sub:`7-0`
++ - R\ :sub:`15-8`
++ - G\ :sub:`7-0`
++ - G\ :sub:`15-8`
++ - B\ :sub:`7-0`
++ - B\ :sub:`15-8`
++
++.. raw:: latex
++
++ \normalsize
++
+ Deprecated RGB Formats
+ ======================
+
+--- a/drivers/media/v4l2-core/v4l2-common.c
++++ b/drivers/media/v4l2-core/v4l2-common.c
+@@ -253,6 +253,8 @@ const struct v4l2_format_info *v4l2_form
+ { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_BGR48_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
++ { .format = V4L2_PIX_FMT_BGR48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
++ { .format = V4L2_PIX_FMT_RGB48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_ABGR64_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+
+ /* YUV packed formats */
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -587,6 +587,8 @@ struct v4l2_pix_format {
+
+ /* RGB formats (6 or 8 bytes per pixel) */
+ #define V4L2_PIX_FMT_BGR48_12 v4l2_fourcc('B', '3', '1', '2') /* 48 BGR 12-bit per component */
++#define V4L2_PIX_FMT_BGR48 v4l2_fourcc('B', 'G', 'R', '6') /* 48 BGR 16-bit per component */
++#define V4L2_PIX_FMT_RGB48 v4l2_fourcc('R', 'G', 'B', '6') /* 48 RGB 16-bit per component */
+ #define V4L2_PIX_FMT_ABGR64_12 v4l2_fourcc('B', '4', '1', '2') /* 64 BGRA 12-bit per component */
+
+ /* RGB formats (6 bytes per pixel) */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch b/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch
new file mode 100644
index 0000000000..a59bcb1e97
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch
@@ -0,0 +1,1171 @@
+From be6996ad702fac96b36ea209ae04a71bd1c6e1d4 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 24 May 2024 15:18:21 +0200
+Subject: [PATCH 1149/1215] media: uapi: Add Raspberry Pi PiSP Back End uAPI
+
+Add the Raspberry Pi PiSP Back End uAPI header.
+
+The header defines the data type used to configure the PiSP Back End
+ISP.
+
+The detailed description of the types and of the ISP configuration
+procedure is available at
+https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ MAINTAINERS | 7 +
+ .../linux/media/raspberrypi/pisp_be_config.h | 927 ++++++++++++++++++
+ .../linux/media/raspberrypi/pisp_common.h | 199 ++++
+ 3 files changed, 1133 insertions(+)
+ create mode 100644 include/uapi/linux/media/raspberrypi/pisp_be_config.h
+ create mode 100644 include/uapi/linux/media/raspberrypi/pisp_common.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18032,6 +18032,13 @@ L: linux-wireless@vger.kernel.org
+ S: Orphan
+ F: drivers/net/wireless/legacy/ray*
+
++RASPBERRY PI PISP BACK END
++M: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
++L: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
++L: linux-media@vger.kernel.org
++S: Maintained
++F: include/uapi/linux/media/raspberrypi/
++
+ RC-CORE / LIRC FRAMEWORK
+ M: Sean Young <sean@mess.org>
+ L: linux-media@vger.kernel.org
+--- /dev/null
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -0,0 +1,927 @@
++/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
++/*
++ * PiSP Back End configuration definitions.
++ *
++ * Copyright (C) 2021 - Raspberry Pi Ltd
++ *
++ */
++#ifndef _UAPI_PISP_BE_CONFIG_H_
++#define _UAPI_PISP_BE_CONFIG_H_
++
++#include <linux/types.h>
++
++#include "pisp_common.h"
++
++/* byte alignment for inputs */
++#define PISP_BACK_END_INPUT_ALIGN 4u
++/* alignment for compressed inputs */
++#define PISP_BACK_END_COMPRESSED_ALIGN 8u
++/* minimum required byte alignment for outputs */
++#define PISP_BACK_END_OUTPUT_MIN_ALIGN 16u
++/* preferred byte alignment for outputs */
++#define PISP_BACK_END_OUTPUT_MAX_ALIGN 64u
++
++/* minimum allowed tile width anywhere in the pipeline */
++#define PISP_BACK_END_MIN_TILE_WIDTH 16u
++/* minimum allowed tile width anywhere in the pipeline */
++#define PISP_BACK_END_MIN_TILE_HEIGHT 16u
++
++#define PISP_BACK_END_NUM_OUTPUTS 2
++#define PISP_BACK_END_HOG_OUTPUT 1
++
++#define PISP_BACK_END_NUM_TILES 64
++
++enum pisp_be_bayer_enable {
++ PISP_BE_BAYER_ENABLE_INPUT = 0x000001,
++ PISP_BE_BAYER_ENABLE_DECOMPRESS = 0x000002,
++ PISP_BE_BAYER_ENABLE_DPC = 0x000004,
++ PISP_BE_BAYER_ENABLE_GEQ = 0x000008,
++ PISP_BE_BAYER_ENABLE_TDN_INPUT = 0x000010,
++ PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS = 0x000020,
++ PISP_BE_BAYER_ENABLE_TDN = 0x000040,
++ PISP_BE_BAYER_ENABLE_TDN_COMPRESS = 0x000080,
++ PISP_BE_BAYER_ENABLE_TDN_OUTPUT = 0x000100,
++ PISP_BE_BAYER_ENABLE_SDN = 0x000200,
++ PISP_BE_BAYER_ENABLE_BLC = 0x000400,
++ PISP_BE_BAYER_ENABLE_STITCH_INPUT = 0x000800,
++ PISP_BE_BAYER_ENABLE_STITCH_DECOMPRESS = 0x001000,
++ PISP_BE_BAYER_ENABLE_STITCH = 0x002000,
++ PISP_BE_BAYER_ENABLE_STITCH_COMPRESS = 0x004000,
++ PISP_BE_BAYER_ENABLE_STITCH_OUTPUT = 0x008000,
++ PISP_BE_BAYER_ENABLE_WBG = 0x010000,
++ PISP_BE_BAYER_ENABLE_CDN = 0x020000,
++ PISP_BE_BAYER_ENABLE_LSC = 0x040000,
++ PISP_BE_BAYER_ENABLE_TONEMAP = 0x080000,
++ PISP_BE_BAYER_ENABLE_CAC = 0x100000,
++ PISP_BE_BAYER_ENABLE_DEBIN = 0x200000,
++ PISP_BE_BAYER_ENABLE_DEMOSAIC = 0x400000,
++};
++
++enum pisp_be_rgb_enable {
++ PISP_BE_RGB_ENABLE_INPUT = 0x000001,
++ PISP_BE_RGB_ENABLE_CCM = 0x000002,
++ PISP_BE_RGB_ENABLE_SAT_CONTROL = 0x000004,
++ PISP_BE_RGB_ENABLE_YCBCR = 0x000008,
++ PISP_BE_RGB_ENABLE_FALSE_COLOUR = 0x000010,
++ PISP_BE_RGB_ENABLE_SHARPEN = 0x000020,
++ /* Preferred colours would occupy 0x000040 */
++ PISP_BE_RGB_ENABLE_YCBCR_INVERSE = 0x000080,
++ PISP_BE_RGB_ENABLE_GAMMA = 0x000100,
++ PISP_BE_RGB_ENABLE_CSC0 = 0x000200,
++ PISP_BE_RGB_ENABLE_CSC1 = 0x000400,
++ PISP_BE_RGB_ENABLE_DOWNSCALE0 = 0x001000,
++ PISP_BE_RGB_ENABLE_DOWNSCALE1 = 0x002000,
++ PISP_BE_RGB_ENABLE_RESAMPLE0 = 0x008000,
++ PISP_BE_RGB_ENABLE_RESAMPLE1 = 0x010000,
++ PISP_BE_RGB_ENABLE_OUTPUT0 = 0x040000,
++ PISP_BE_RGB_ENABLE_OUTPUT1 = 0x080000,
++ PISP_BE_RGB_ENABLE_HOG = 0x200000
++};
++
++#define PISP_BE_RGB_ENABLE_CSC(i) (PISP_BE_RGB_ENABLE_CSC0 << (i))
++#define PISP_BE_RGB_ENABLE_DOWNSCALE(i) (PISP_BE_RGB_ENABLE_DOWNSCALE0 << (i))
++#define PISP_BE_RGB_ENABLE_RESAMPLE(i) (PISP_BE_RGB_ENABLE_RESAMPLE0 << (i))
++#define PISP_BE_RGB_ENABLE_OUTPUT(i) (PISP_BE_RGB_ENABLE_OUTPUT0 << (i))
++
++/*
++ * We use the enable flags to show when blocks are "dirty", but we need some
++ * extra ones too.
++ */
++enum pisp_be_dirty {
++ PISP_BE_DIRTY_GLOBAL = 0x0001,
++ PISP_BE_DIRTY_SH_FC_COMBINE = 0x0002,
++ PISP_BE_DIRTY_CROP = 0x0004
++};
++
++/**
++ * struct pisp_be_global_config - PiSP global enable bitmaps
++ * @bayer_enables: Bayer input enable flags
++ * @rgb_enables: RGB output enable flags
++ * @bayer_order: Bayer input format ordering
++ * @pad: Padding bytes
++ */
++struct pisp_be_global_config {
++ __u32 bayer_enables;
++ __u32 rgb_enables;
++ __u8 bayer_order;
++ __u8 pad[3];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_input_buffer_config - PiSP Back End input buffer
++ * @addr: Input buffer address
++ */
++struct pisp_be_input_buffer_config {
++ /* low 32 bits followed by high 32 bits (for each of up to 3 planes) */
++ __u32 addr[3][2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_dpc_config - PiSP Back End DPC config
++ *
++ * Defective Pixel Correction configuration
++ *
++ * @coeff_level: Coefficient for the darkest neighbouring pixel value
++ * @coeff_range: Coefficient for the range of pixels for this Bayer channel
++ * @pad: Padding byte
++ * @flags: DPC configuration flags
++ */
++struct pisp_be_dpc_config {
++ __u8 coeff_level;
++ __u8 coeff_range;
++ __u8 pad;
++#define PISP_BE_DPC_FLAG_FOLDBACK 1
++ __u8 flags;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_geq_config - PiSP Back End GEQ config
++ *
++ * Green Equalisation configuration
++ *
++ * @offset: Offset value for threshold calculation
++ * @slope_sharper: Slope/Sharper configuration
++ * @min: Minimum value the threshold may have
++ * @max: Maximum value the threshold may have
++ */
++struct pisp_be_geq_config {
++ __u16 offset;
++#define PISP_BE_GEQ_SHARPER BIT(15)
++#define PISP_BE_GEQ_SLOPE ((1 << 10) - 1)
++ /* top bit is the "sharper" flag, slope value is bottom 10 bits */
++ __u16 slope_sharper;
++ __u16 min;
++ __u16 max;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tdn_input_buffer_config - PiSP Back End TDN input buffer
++ * @addr: TDN input buffer address
++ */
++struct pisp_be_tdn_input_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tdn_config - PiSP Back End TDN config
++ *
++ * Temporal Denoise configuration
++ *
++ * @black_level: Black level value subtracted from pixels
++ * @ratio: Multiplier for the LTA input frame
++ * @noise_constant: Constant offset value used in noise estimation
++ * @noise_slope: Noise estimation multiplier
++ * @threshold: Threshold for TDN operations
++ * @reset: Disable TDN operations
++ * @pad: Padding byte
++ */
++struct pisp_be_tdn_config {
++ __u16 black_level;
++ __u16 ratio;
++ __u16 noise_constant;
++ __u16 noise_slope;
++ __u16 threshold;
++ __u8 reset;
++ __u8 pad;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tdn_output_buffer_config - PiSP Back End TDN output buffer
++ * @addr: TDN output buffer address
++ */
++struct pisp_be_tdn_output_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_sdn_config - PiSP Back End SDN config
++ *
++ * Spatial Denoise configuration
++ *
++ * @black_level: Black level subtracted from pixel for noise estimation
++ * @leakage: Proportion of the original undenoised value to mix in
++ * denoised output
++ * @pad: Padding byte
++ * @noise_constant: Noise constant used for noise estimation
++ * @noise_slope: Noise slope value used for noise estimation
++ * @noise_constant2: Second noise constant used for noise estimation
++ * @noise_slope2: Second slope value used for noise estimation
++ */
++struct pisp_be_sdn_config {
++ __u16 black_level;
++ __u8 leakage;
++ __u8 pad;
++ __u16 noise_constant;
++ __u16 noise_slope;
++ __u16 noise_constant2;
++ __u16 noise_slope2;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_stitch_input_buffer_config - PiSP Back End Stitch input
++ * @addr: Stitch input buffer address
++ */
++struct pisp_be_stitch_input_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++#define PISP_BE_STITCH_STREAMING_LONG 0x8000
++#define PISP_BE_STITCH_EXPOSURE_RATIO_MASK 0x7fff
++
++/**
++ * struct pisp_be_stitch_config - PiSP Back End Stitch config
++ *
++ * Stitch block configuration
++ *
++ * @threshold_lo: Low threshold value
++ * @threshold_diff_power: Low and high threshold difference
++ * @pad: Padding bytes
++ * @exposure_ratio: Multiplier to convert long exposure pixels into
++ * short exposure pixels
++ * @motion_threshold_256: Motion threshold above which short exposure
++ * pixels are used
++ * @motion_threshold_recip: Reciprocal of motion_threshold_256 value
++ */
++struct pisp_be_stitch_config {
++ __u16 threshold_lo;
++ __u8 threshold_diff_power;
++ __u8 pad;
++
++ /* top bit indicates whether streaming input is the long exposure */
++ __u16 exposure_ratio;
++
++ __u8 motion_threshold_256;
++ __u8 motion_threshold_recip;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_stitch_output_buffer_config - PiSP Back End Stitch output
++ * @addr: Stitch input buffer address
++ */
++struct pisp_be_stitch_output_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_cdn_config - PiSP Back End CDN config
++ *
++ * Colour Denoise configuration
++ *
++ * @thresh: Constant for noise estimation
++ * @iir_strength: Relative strength of the IIR part of the filter
++ * @g_adjust: Proportion of the change assigned to the G channel
++ */
++struct pisp_be_cdn_config {
++ __u16 thresh;
++ __u8 iir_strength;
++ __u8 g_adjust;
++} __attribute__((packed));
++
++#define PISP_BE_LSC_LOG_GRID_SIZE 5
++#define PISP_BE_LSC_GRID_SIZE (1 << PISP_BE_LSC_LOG_GRID_SIZE)
++#define PISP_BE_LSC_STEP_PRECISION 18
++
++/**
++ * struct pisp_be_lsc_config - PiSP Back End LSC config
++ *
++ * Lens Shading Correction configuration
++ *
++ * @grid_step_x: Reciprocal of cell size width
++ * @grid_step_y: Reciprocal of cell size height
++ * @lut_packed: Jointly-coded RGB gains for each LSC grid
++ */
++struct pisp_be_lsc_config {
++ /* (1<<18) / grid_cell_width */
++ __u16 grid_step_x;
++ /* (1<<18) / grid_cell_height */
++ __u16 grid_step_y;
++ /* RGB gains jointly encoded in 32 bits */
++#define PISP_BE_LSC_LUT_SIZE (PISP_BE_LSC_GRID_SIZE + 1)
++ __u32 lut_packed[PISP_BE_LSC_LUT_SIZE][PISP_BE_LSC_LUT_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_lsc_extra - PiSP Back End LSC Extra config
++ * @offset_x: Horizontal offset into the LSC table of this tile
++ * @offset_y: Vertical offset into the LSC table of this tile
++ */
++struct pisp_be_lsc_extra {
++ __u16 offset_x;
++ __u16 offset_y;
++} __attribute__((packed));
++
++#define PISP_BE_CAC_LOG_GRID_SIZE 3
++#define PISP_BE_CAC_GRID_SIZE (1 << PISP_BE_CAC_LOG_GRID_SIZE)
++#define PISP_BE_CAC_STEP_PRECISION 20
++
++/**
++ * struct pisp_be_cac_config - PiSP Back End CAC config
++ *
++ * Chromatic Aberration Correction config
++ *
++ * @grid_step_x: Reciprocal of cell size width
++ * @grid_step_y: Reciprocal of cell size height
++ * @lut: Pixel shift for the CAC grid
++ */
++struct pisp_be_cac_config {
++ /* (1<<20) / grid_cell_width */
++ __u16 grid_step_x;
++ /* (1<<20) / grid_cell_height */
++ __u16 grid_step_y;
++ /* [gridy][gridx][rb][xy] */
++#define PISP_BE_CAC_LUT_SIZE (PISP_BE_CAC_GRID_SIZE + 1)
++ __s8 lut[PISP_BE_CAC_LUT_SIZE][PISP_BE_CAC_LUT_SIZE][2][2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_cac_extra - PiSP Back End CAC extra config
++ * @offset_x: Horizontal offset into the CAC table of this tile
++ * @offset_y: Horizontal offset into the CAC table of this tile
++ */
++struct pisp_be_cac_extra {
++ __u16 offset_x;
++ __u16 offset_y;
++} __attribute__((packed));
++
++#define PISP_BE_DEBIN_NUM_COEFFS 4
++
++/**
++ * struct pisp_be_debin_config - PiSP Back End Debin config
++ *
++ * Debinning configuration
++ *
++ * @coeffs: Filter coefficients for debinning
++ * @h_enable: Horizontal debinning enable
++ * @v_enable: Vertical debinning enable
++ * @pad: Padding bytes
++ */
++struct pisp_be_debin_config {
++ __s8 coeffs[PISP_BE_DEBIN_NUM_COEFFS];
++ __s8 h_enable;
++ __s8 v_enable;
++ __s8 pad[2];
++} __attribute__((packed));
++
++#define PISP_BE_TONEMAP_LUT_SIZE 64
++
++/**
++ * struct pisp_be_tonemap_config - PiSP Back End Tonemap config
++ *
++ * Tonemapping configuration
++ *
++ * @detail_constant: Constant value for threshold calculation
++ * @detail_slope: Slope value for threshold calculation
++ * @iir_strength: Relative strength of the IIR fiter
++ * @strength: Strength factor
++ * @lut: Look-up table for tonemap curve
++ */
++struct pisp_be_tonemap_config {
++ __u16 detail_constant;
++ __u16 detail_slope;
++ __u16 iir_strength;
++ __u16 strength;
++ __u32 lut[PISP_BE_TONEMAP_LUT_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_demosaic_config - PiSP Back End Demosaic config
++ *
++ * Demosaic configuration
++ *
++ * @sharper: Use other Bayer channels to increase sharpness
++ * @fc_mode: Built-in false colour suppression mode
++ * @pad: Padding bytes
++ */
++struct pisp_be_demosaic_config {
++ __u8 sharper;
++ __u8 fc_mode;
++ __u8 pad[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_ccm_config - PiSP Back End CCM config
++ *
++ * Colour Correction Matrix configuration
++ *
++ * @coeffs: Matrix coefficients
++ * @pad: Padding bytes
++ * @offsets: Offsets triplet
++ */
++struct pisp_be_ccm_config {
++ __s16 coeffs[9];
++ __u8 pad[2];
++ __s32 offsets[3];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_sat_control_config - PiSP Back End SAT config
++ *
++ * Saturation Control configuration
++ *
++ * @shift_r: Left shift for Red colour channel
++ * @shift_g: Left shift for Green colour channel
++ * @shift_b: Left shift for Blue colour channel
++ * @pad: Padding byte
++ */
++struct pisp_be_sat_control_config {
++ __u8 shift_r;
++ __u8 shift_g;
++ __u8 shift_b;
++ __u8 pad;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_false_colour_config - PiSP Back End False Colour config
++ *
++ * False Colour configuration
++ *
++ * @distance: Distance of neighbouring pixels, either 1 or 2
++ * @pad: Padding bytes
++ */
++struct pisp_be_false_colour_config {
++ __u8 distance;
++ __u8 pad[3];
++} __attribute__((packed));
++
++#define PISP_BE_SHARPEN_SIZE 5
++#define PISP_BE_SHARPEN_FUNC_NUM_POINTS 9
++
++/**
++ * struct pisp_be_sharpen_config - PiSP Back End Sharpening config
++ *
++ * Sharpening configuration
++ *
++ * @kernel0: Coefficient for filter 0
++ * @pad0: Padding byte
++ * @kernel1: Coefficient for filter 1
++ * @pad1: Padding byte
++ * @kernel2: Coefficient for filter 2
++ * @pad2: Padding byte
++ * @kernel3: Coefficient for filter 3
++ * @pad3: Padding byte
++ * @kernel4: Coefficient for filter 4
++ * @pad4: Padding byte
++ * @threshold_offset0: Offset for filter 0 response calculation
++ * @threshold_slope0: Slope multiplier for the filter 0 response calculation
++ * @scale0: Scale factor for filter 0 response calculation
++ * @pad5: Padding byte
++ * @threshold_offset1: Offset for filter 0 response calculation
++ * @threshold_slope1: Slope multiplier for the filter 0 response calculation
++ * @scale1: Scale factor for filter 0 response calculation
++ * @pad6: Padding byte
++ * @threshold_offset2: Offset for filter 0 response calculation
++ * @threshold_slope2: Slope multiplier for the filter 0 response calculation
++ * @scale2: Scale factor for filter 0 response calculation
++ * @pad7: Padding byte
++ * @threshold_offset3: Offset for filter 0 response calculation
++ * @threshold_slope3: Slope multiplier for the filter 0 response calculation
++ * @scale3: Scale factor for filter 0 response calculation
++ * @pad8: Padding byte
++ * @threshold_offset4: Offset for filter 0 response calculation
++ * @threshold_slope4: Slope multiplier for the filter 0 response calculation
++ * @scale4: Scale factor for filter 0 response calculation
++ * @pad9: Padding byte
++ * @positive_strength: Factor to scale the positive sharpening strength
++ * @positive_pre_limit: Maximum allowed possible positive sharpening value
++ * @positive_func: Gain factor applied to positive sharpening response
++ * @positive_limit: Final gain factor applied to positive sharpening
++ * @negative_strength: Factor to scale the negative sharpening strength
++ * @negative_pre_limit: Maximum allowed possible negative sharpening value
++ * @negative_func: Gain factor applied to negative sharpening response
++ * @negative_limit: Final gain factor applied to negative sharpening
++ * @enables: Filter enable mask
++ * @white: White output pixel filter mask
++ * @black: Black output pixel filter mask
++ * @grey: Grey output pixel filter mask
++ */
++struct pisp_be_sharpen_config {
++ __s8 kernel0[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad0[3];
++ __s8 kernel1[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad1[3];
++ __s8 kernel2[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad2[3];
++ __s8 kernel3[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad3[3];
++ __s8 kernel4[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad4[3];
++ __u16 threshold_offset0;
++ __u16 threshold_slope0;
++ __u16 scale0;
++ __u16 pad5;
++ __u16 threshold_offset1;
++ __u16 threshold_slope1;
++ __u16 scale1;
++ __u16 pad6;
++ __u16 threshold_offset2;
++ __u16 threshold_slope2;
++ __u16 scale2;
++ __u16 pad7;
++ __u16 threshold_offset3;
++ __u16 threshold_slope3;
++ __u16 scale3;
++ __u16 pad8;
++ __u16 threshold_offset4;
++ __u16 threshold_slope4;
++ __u16 scale4;
++ __u16 pad9;
++ __u16 positive_strength;
++ __u16 positive_pre_limit;
++ __u16 positive_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
++ __u16 positive_limit;
++ __u16 negative_strength;
++ __u16 negative_pre_limit;
++ __u16 negative_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
++ __u16 negative_limit;
++ __u8 enables;
++ __u8 white;
++ __u8 black;
++ __u8 grey;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_sh_fc_combine_config - PiSP Back End Sharpening and
++ * False Colour config
++ *
++ * Sharpening and False Colour configuration
++ *
++ * @y_factor: Control amount of desaturation of pixels being darkened
++ * @c1_factor: Control amount of brightening of a pixel for the Cb
++ * channel
++ * @c2_factor: Control amount of brightening of a pixel for the Cr
++ * channel
++ * @pad: Padding byte
++ */
++struct pisp_be_sh_fc_combine_config {
++ __u8 y_factor;
++ __u8 c1_factor;
++ __u8 c2_factor;
++ __u8 pad;
++} __attribute__((packed));
++
++#define PISP_BE_GAMMA_LUT_SIZE 64
++
++/**
++ * struct pisp_be_gamma_config - PiSP Back End Gamma configuration
++ * @lut: Gamma curve look-up table
++ */
++struct pisp_be_gamma_config {
++ __u32 lut[PISP_BE_GAMMA_LUT_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_crop_config - PiSP Back End Crop config
++ *
++ * Crop configuration
++ *
++ * @offset_x: Number of pixels cropped from the left of the tile
++ * @offset_y: Number of pixels cropped from the top of the tile
++ * @width: Width of the cropped tile output
++ * @height: Height of the cropped tile output
++ */
++struct pisp_be_crop_config {
++ __u16 offset_x, offset_y;
++ __u16 width, height;
++} __attribute__((packed));
++
++#define PISP_BE_RESAMPLE_FILTER_SIZE 96
++
++/**
++ * struct pisp_be_resample_config - PiSP Back End Resampling config
++ *
++ * Resample configuration
++ *
++ * @scale_factor_h: Horizontal scale factor
++ * @scale_factor_v: Vertical scale factor
++ * @coef: Resample coefficients
++ */
++struct pisp_be_resample_config {
++ __u16 scale_factor_h, scale_factor_v;
++ __s16 coef[PISP_BE_RESAMPLE_FILTER_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_resample_extra - PiSP Back End Resample config
++ *
++ * Resample configuration
++ *
++ * @scaled_width: Width in pixels of the scaled output
++ * @scaled_height: Height in pixels of the scaled output
++ * @initial_phase_h: Initial horizontal phase
++ * @initial_phase_v: Initial vertical phase
++ */
++struct pisp_be_resample_extra {
++ __u16 scaled_width;
++ __u16 scaled_height;
++ __s16 initial_phase_h[3];
++ __s16 initial_phase_v[3];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_downscale_config - PiSP Back End Downscale config
++ *
++ * Downscale configuration
++ *
++ * @scale_factor_h: Horizontal scale factor
++ * @scale_factor_v: Vertical scale factor
++ * @scale_recip_h: Horizontal reciprocal factor
++ * @scale_recip_v: Vertical reciprocal factor
++ */
++struct pisp_be_downscale_config {
++ __u16 scale_factor_h;
++ __u16 scale_factor_v;
++ __u16 scale_recip_h;
++ __u16 scale_recip_v;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_downscale_extra - PiSP Back End Downscale Extra config
++ * @scaled_width: Scaled image width
++ * @scaled_height: Scaled image height
++ */
++struct pisp_be_downscale_extra {
++ __u16 scaled_width;
++ __u16 scaled_height;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_hog_config - PiSP Back End HOG config
++ *
++ * Histogram of Oriented Gradients configuration
++ *
++ * @compute_signed: Set 0 for unsigned gradients, 1 for signed
++ * @channel_mix: Channels proportions to use
++ * @stride: Stride in bytes between blocks directly below
++ */
++struct pisp_be_hog_config {
++ __u8 compute_signed;
++ __u8 channel_mix[3];
++ __u32 stride;
++} __attribute__((packed));
++
++struct pisp_be_axi_config {
++ __u8 r_qos; /* Read QoS */
++ __u8 r_cache_prot; /* Read { prot[2:0], cache[3:0] } */
++ __u8 w_qos; /* Write QoS */
++ __u8 w_cache_prot; /* Write { prot[2:0], cache[3:0] } */
++} __attribute__((packed));
++
++/**
++ * enum pisp_be_transform - PiSP Back End Transform flags
++ * @PISP_BE_TRANSFORM_NONE: No transform
++ * @PISP_BE_TRANSFORM_HFLIP: Horizontal flip
++ * @PISP_BE_TRANSFORM_VFLIP: Vertical flip
++ * @PISP_BE_TRANSFORM_ROT180: 180 degress rotation
++ */
++enum pisp_be_transform {
++ PISP_BE_TRANSFORM_NONE = 0x0,
++ PISP_BE_TRANSFORM_HFLIP = 0x1,
++ PISP_BE_TRANSFORM_VFLIP = 0x2,
++ PISP_BE_TRANSFORM_ROT180 =
++ (PISP_BE_TRANSFORM_HFLIP | PISP_BE_TRANSFORM_VFLIP)
++};
++
++struct pisp_be_output_format_config {
++ struct pisp_image_format_config image;
++ __u8 transform;
++ __u8 pad[3];
++ __u16 lo;
++ __u16 hi;
++ __u16 lo2;
++ __u16 hi2;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_output_buffer_config - PiSP Back End Output buffer
++ * @addr: Output buffer address
++ */
++struct pisp_be_output_buffer_config {
++ /* low 32 bits followed by high 32 bits (for each of 3 planes) */
++ __u32 addr[3][2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_hog_buffer_config - PiSP Back End HOG buffer
++ * @addr: HOG buffer address
++ */
++struct pisp_be_hog_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_config - RaspberryPi PiSP Back End Processing configuration
++ *
++ * @global: Global PiSP configuration
++ * @input_format: Input image format
++ * @decompress: Decompress configuration
++ * @dpc: Defective Pixel Correction configuration
++ * @geq: Green Equalisation configuration
++ * @tdn_input_format: Temporal Denoise input format
++ * @tdn_decompress: Temporal Denoise decompress configuration
++ * @tdn: Temporal Denoise configuration
++ * @tdn_compress: Temporal Denoise compress configuration
++ * @tdn_output_format: Temporal Denoise output format
++ * @sdn: Spatial Denoise configuration
++ * @blc: Black Level Correction configuration
++ * @stitch_compress: Stitch compress configuration
++ * @stitch_output_format: Stitch output format
++ * @stitch_input_format: Stitch input format
++ * @stitch_decompress: Stitch decompress configuration
++ * @stitch: Stitch configuration
++ * @lsc: Lens Shading Correction configuration
++ * @wbg: White Balance Gain configuration
++ * @cdn: Colour Denoise configuration
++ * @cac: Colour Aberration Correction configuration
++ * @debin: Debinning configuration
++ * @tonemap: Tonemapping configuration
++ * @demosaic: Demosaicing configuration
++ * @ccm: Colour Correction Matrix configuration
++ * @sat_control: Saturation Control configuration
++ * @ycbcr: YCbCr colour correction configuration
++ * @sharpen: Sharpening configuration
++ * @false_colour: False colour correction
++ * @sh_fc_combine: Sharpening and False Colour correction
++ * @ycbcr_inverse: Inverse YCbCr colour correction
++ * @gamma: Gamma curve configuration
++ * @csc: Color Space Conversion configuration
++ * @downscale: Downscale configuration
++ * @resample: Resampling configuration
++ * @output_format: Output format configuration
++ * @hog: HOG configuration
++ */
++struct pisp_be_config {
++ struct pisp_be_global_config global;
++ struct pisp_image_format_config input_format;
++ struct pisp_decompress_config decompress;
++ struct pisp_be_dpc_config dpc;
++ struct pisp_be_geq_config geq;
++ struct pisp_image_format_config tdn_input_format;
++ struct pisp_decompress_config tdn_decompress;
++ struct pisp_be_tdn_config tdn;
++ struct pisp_compress_config tdn_compress;
++ struct pisp_image_format_config tdn_output_format;
++ struct pisp_be_sdn_config sdn;
++ struct pisp_bla_config blc;
++ struct pisp_compress_config stitch_compress;
++ struct pisp_image_format_config stitch_output_format;
++ struct pisp_image_format_config stitch_input_format;
++ struct pisp_decompress_config stitch_decompress;
++ struct pisp_be_stitch_config stitch;
++ struct pisp_be_lsc_config lsc;
++ struct pisp_wbg_config wbg;
++ struct pisp_be_cdn_config cdn;
++ struct pisp_be_cac_config cac;
++ struct pisp_be_debin_config debin;
++ struct pisp_be_tonemap_config tonemap;
++ struct pisp_be_demosaic_config demosaic;
++ struct pisp_be_ccm_config ccm;
++ struct pisp_be_sat_control_config sat_control;
++ struct pisp_be_ccm_config ycbcr;
++ struct pisp_be_sharpen_config sharpen;
++ struct pisp_be_false_colour_config false_colour;
++ struct pisp_be_sh_fc_combine_config sh_fc_combine;
++ struct pisp_be_ccm_config ycbcr_inverse;
++ struct pisp_be_gamma_config gamma;
++ struct pisp_be_ccm_config csc[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_downscale_config downscale[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_resample_config resample[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_output_format_config
++ output_format[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_hog_config hog;
++} __attribute__((packed));
++
++/**
++ * enum pisp_tile_edge - PiSP Back End Tile position
++ * @PISP_LEFT_EDGE: Left edge tile
++ * @PISP_RIGHT_EDGE: Right edge tile
++ * @PISP_TOP_EDGE: Top edge tile
++ * @PISP_BOTTOM_EDGE: Bottom edge tile
++ */
++enum pisp_tile_edge {
++ PISP_LEFT_EDGE = (1 << 0),
++ PISP_RIGHT_EDGE = (1 << 1),
++ PISP_TOP_EDGE = (1 << 2),
++ PISP_BOTTOM_EDGE = (1 << 3)
++};
++
++/**
++ * struct pisp_tile - Raspberry Pi PiSP Back End tile configuration
++ *
++ * Tile parameters: each set of tile parameters is a 160-bytes block of data
++ * which contains the tile processing parameters.
++ *
++ * @edge: Edge tile flag
++ * @pad0: Padding bytes
++ * @input_addr_offset: Top-left pixel offset, in bytes
++ * @input_addr_offset2: Top-left pixel offset, in bytes for the second/
++ * third image planes
++ * @input_offset_x: Horizontal offset in pixels of this tile in the
++ * input image
++ * @input_offset_y: Vertical offset in pixels of this tile in the
++ * input image
++ * @input_width: Width in pixels of this tile
++ * @input_height: Height in pixels of the this tile
++ * @tdn_input_addr_offset: TDN input image offset, in bytes
++ * @tdn_output_addr_offset: TDN output image offset, in bytes
++ * @stitch_input_addr_offset: Stitch input image offset, in bytes
++ * @stitch_output_addr_offset: Stitch output image offset, in bytes
++ * @lsc_grid_offset_x: Horizontal offset in the LSC table for this tile
++ * @lsc_grid_offset_y: Vertical offset in the LSC table for this tile
++ * @cac_grid_offset_x: Horizontal offset in the CAC table for this tile
++ * @cac_grid_offset_y: Horizontal offset in the CAC table for this tile
++ * @crop_x_start: Number of pixels cropped from the left of the
++ * tile
++ * @crop_x_end: Number of pixels cropped from the right of the
++ * tile
++ * @crop_y_start: Number of pixels cropped from the top of the
++ * tile
++ * @crop_y_end: Number of pixels cropped from the bottom of the
++ * tile
++ * @downscale_phase_x: Initial horizontal phase in pixels
++ * @downscale_phase_y: Initial vertical phase in pixels
++ * @resample_in_width: Width in pixels of the tile entering the
++ * Resample block
++ * @resample_in_height: Height in pixels of the tile entering the
++ * Resample block
++ * @resample_phase_x: Initial horizontal phase for the Resample block
++ * @resample_phase_y: Initial vertical phase for the Resample block
++ * @output_offset_x: Horizontal offset in pixels where the tile will
++ * be written into the output image
++ * @output_offset_y: Vertical offset in pixels where the tile will be
++ * written into the output image
++ * @output_width: Width in pixels in the output image of this tile
++ * @output_height: Height in pixels in the output image of this tile
++ * @output_addr_offset: Offset in bytes into the output buffer
++ * @output_addr_offset2: Offset in bytes into the output buffer for the
++ * second and third plane
++ * @output_hog_addr_offset: Offset in bytes into the HOG buffer where
++ * results of this tile are to be written
++ */
++struct pisp_tile {
++ __u8 edge; /* enum pisp_tile_edge */
++ __u8 pad0[3];
++ /* 4 bytes */
++ __u32 input_addr_offset;
++ __u32 input_addr_offset2;
++ __u16 input_offset_x;
++ __u16 input_offset_y;
++ __u16 input_width;
++ __u16 input_height;
++ /* 20 bytes */
++ __u32 tdn_input_addr_offset;
++ __u32 tdn_output_addr_offset;
++ __u32 stitch_input_addr_offset;
++ __u32 stitch_output_addr_offset;
++ /* 36 bytes */
++ __u32 lsc_grid_offset_x;
++ __u32 lsc_grid_offset_y;
++ /* 44 bytes */
++ __u32 cac_grid_offset_x;
++ __u32 cac_grid_offset_y;
++ /* 52 bytes */
++ __u16 crop_x_start[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 crop_x_end[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 crop_y_start[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 crop_y_end[PISP_BACK_END_NUM_OUTPUTS];
++ /* 68 bytes */
++ /* Ordering is planes then branches */
++ __u16 downscale_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
++ __u16 downscale_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
++ /* 92 bytes */
++ __u16 resample_in_width[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 resample_in_height[PISP_BACK_END_NUM_OUTPUTS];
++ /* 100 bytes */
++ /* Ordering is planes then branches */
++ __u16 resample_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
++ __u16 resample_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
++ /* 124 bytes */
++ __u16 output_offset_x[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 output_offset_y[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 output_width[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 output_height[PISP_BACK_END_NUM_OUTPUTS];
++ /* 140 bytes */
++ __u32 output_addr_offset[PISP_BACK_END_NUM_OUTPUTS];
++ __u32 output_addr_offset2[PISP_BACK_END_NUM_OUTPUTS];
++ /* 156 bytes */
++ __u32 output_hog_addr_offset;
++ /* 160 bytes */
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tiles_config - Raspberry Pi PiSP Back End configuration
++ * @tiles: Tile descriptors
++ * @num_tiles: Number of tiles
++ * @config: PiSP Back End configuration
++ */
++struct pisp_be_tiles_config {
++ struct pisp_tile tiles[PISP_BACK_END_NUM_TILES];
++ __u32 num_tiles;
++ struct pisp_be_config config;
++} __attribute__((packed));
++
++#endif /* _UAPI_PISP_BE_CONFIG_H_ */
+--- /dev/null
++++ b/include/uapi/linux/media/raspberrypi/pisp_common.h
+@@ -0,0 +1,199 @@
++/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
++/*
++ * RP1 PiSP common definitions.
++ *
++ * Copyright (C) 2021 - Raspberry Pi Ltd.
++ *
++ */
++#ifndef _UAPI_PISP_COMMON_H_
++#define _UAPI_PISP_COMMON_H_
++
++#include <linux/types.h>
++
++struct pisp_image_format_config {
++ /* size in pixels */
++ __u16 width;
++ __u16 height;
++ /* must match struct pisp_image_format below */
++ __u32 format;
++ __s32 stride;
++ /* some planar image formats will need a second stride */
++ __s32 stride2;
++} __attribute__((packed));
++
++enum pisp_bayer_order {
++ /*
++ * Note how bayer_order&1 tells you if G is on the even pixels of the
++ * checkerboard or not, and bayer_order&2 tells you if R is on the even
++ * rows or is swapped with B. Note that if the top (of the 8) bits is
++ * set, this denotes a monochrome or greyscale image, and the lower bits
++ * should all be ignored.
++ */
++ PISP_BAYER_ORDER_RGGB = 0,
++ PISP_BAYER_ORDER_GBRG = 1,
++ PISP_BAYER_ORDER_BGGR = 2,
++ PISP_BAYER_ORDER_GRBG = 3,
++ PISP_BAYER_ORDER_GREYSCALE = 128
++};
++
++enum pisp_image_format {
++ /*
++ * Precise values are mostly tbd. Generally these will be portmanteau
++ * values comprising bit fields and flags. This format must be shared
++ * throughout the PiSP.
++ */
++ PISP_IMAGE_FORMAT_BPS_8 = 0x00000000,
++ PISP_IMAGE_FORMAT_BPS_10 = 0x00000001,
++ PISP_IMAGE_FORMAT_BPS_12 = 0x00000002,
++ PISP_IMAGE_FORMAT_BPS_16 = 0x00000003,
++ PISP_IMAGE_FORMAT_BPS_MASK = 0x00000003,
++
++ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED = 0x00000000,
++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR = 0x00000010,
++ PISP_IMAGE_FORMAT_PLANARITY_PLANAR = 0x00000020,
++ PISP_IMAGE_FORMAT_PLANARITY_MASK = 0x00000030,
++
++ PISP_IMAGE_FORMAT_SAMPLING_444 = 0x00000000,
++ PISP_IMAGE_FORMAT_SAMPLING_422 = 0x00000100,
++ PISP_IMAGE_FORMAT_SAMPLING_420 = 0x00000200,
++ PISP_IMAGE_FORMAT_SAMPLING_MASK = 0x00000300,
++
++ PISP_IMAGE_FORMAT_ORDER_NORMAL = 0x00000000,
++ PISP_IMAGE_FORMAT_ORDER_SWAPPED = 0x00001000,
++
++ PISP_IMAGE_FORMAT_SHIFT_0 = 0x00000000,
++ PISP_IMAGE_FORMAT_SHIFT_1 = 0x00010000,
++ PISP_IMAGE_FORMAT_SHIFT_2 = 0x00020000,
++ PISP_IMAGE_FORMAT_SHIFT_3 = 0x00030000,
++ PISP_IMAGE_FORMAT_SHIFT_4 = 0x00040000,
++ PISP_IMAGE_FORMAT_SHIFT_5 = 0x00050000,
++ PISP_IMAGE_FORMAT_SHIFT_6 = 0x00060000,
++ PISP_IMAGE_FORMAT_SHIFT_7 = 0x00070000,
++ PISP_IMAGE_FORMAT_SHIFT_8 = 0x00080000,
++ PISP_IMAGE_FORMAT_SHIFT_MASK = 0x000f0000,
++
++ PISP_IMAGE_FORMAT_UNCOMPRESSED = 0x00000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MODE_1 = 0x01000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MODE_2 = 0x02000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MODE_3 = 0x03000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MASK = 0x03000000,
++
++ PISP_IMAGE_FORMAT_HOG_SIGNED = 0x04000000,
++ PISP_IMAGE_FORMAT_HOG_UNSIGNED = 0x08000000,
++ PISP_IMAGE_FORMAT_INTEGRAL_IMAGE = 0x10000000,
++ PISP_IMAGE_FORMAT_WALLPAPER_ROLL = 0x20000000,
++ PISP_IMAGE_FORMAT_THREE_CHANNEL = 0x40000000,
++
++ /* Lastly a few specific instantiations of the above. */
++ PISP_IMAGE_FORMAT_SINGLE_16 = PISP_IMAGE_FORMAT_BPS_16,
++ PISP_IMAGE_FORMAT_THREE_16 = PISP_IMAGE_FORMAT_BPS_16 |
++ PISP_IMAGE_FORMAT_THREE_CHANNEL
++};
++
++#define PISP_IMAGE_FORMAT_bps_8(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_8)
++#define PISP_IMAGE_FORMAT_bps_10(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_10)
++#define PISP_IMAGE_FORMAT_bps_12(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_12)
++#define PISP_IMAGE_FORMAT_bps_16(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_16)
++#define PISP_IMAGE_FORMAT_bps(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) ? \
++ 8 + (2 << (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) - 1)) : 8)
++#define PISP_IMAGE_FORMAT_shift(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SHIFT_MASK) / PISP_IMAGE_FORMAT_SHIFT_1)
++#define PISP_IMAGE_FORMAT_three_channel(fmt) \
++ ((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL)
++#define PISP_IMAGE_FORMAT_single_channel(fmt) \
++ (!((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL))
++#define PISP_IMAGE_FORMAT_compressed(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_COMPRESSION_MASK) != \
++ PISP_IMAGE_FORMAT_UNCOMPRESSED)
++#define PISP_IMAGE_FORMAT_sampling_444(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
++ PISP_IMAGE_FORMAT_SAMPLING_444)
++#define PISP_IMAGE_FORMAT_sampling_422(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
++ PISP_IMAGE_FORMAT_SAMPLING_422)
++#define PISP_IMAGE_FORMAT_sampling_420(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
++ PISP_IMAGE_FORMAT_SAMPLING_420)
++#define PISP_IMAGE_FORMAT_order_normal(fmt) \
++ (!((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED))
++#define PISP_IMAGE_FORMAT_order_swapped(fmt) \
++ ((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED)
++#define PISP_IMAGE_FORMAT_interleaved(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
++ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED)
++#define PISP_IMAGE_FORMAT_semiplanar(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR)
++#define PISP_IMAGE_FORMAT_planar(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
++ PISP_IMAGE_FORMAT_PLANARITY_PLANAR)
++#define PISP_IMAGE_FORMAT_wallpaper(fmt) \
++ ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
++#define PISP_IMAGE_FORMAT_HOG(fmt) \
++ ((fmt) & \
++ (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED))
++
++#define PISP_WALLPAPER_WIDTH 128 /* in bytes */
++
++struct pisp_bla_config {
++ __u16 black_level_r;
++ __u16 black_level_gr;
++ __u16 black_level_gb;
++ __u16 black_level_b;
++ __u16 output_black_level;
++ __u8 pad[2];
++} __attribute__((packed));
++
++struct pisp_wbg_config {
++ __u16 gain_r;
++ __u16 gain_g;
++ __u16 gain_b;
++ __u8 pad[2];
++} __attribute__((packed));
++
++struct pisp_compress_config {
++ /* value subtracted from incoming data */
++ __u16 offset;
++ __u8 pad;
++ /* 1 => Companding; 2 => Delta (recommended); 3 => Combined (for HDR) */
++ __u8 mode;
++} __attribute__((packed));
++
++struct pisp_decompress_config {
++ /* value added to reconstructed data */
++ __u16 offset;
++ __u8 pad;
++ /* 1 => Companding; 2 => Delta (recommended); 3 => Combined (for HDR) */
++ __u8 mode;
++} __attribute__((packed));
++
++enum pisp_axi_flags {
++ /*
++ * round down bursts to end at a 32-byte boundary, to align following
++ * bursts
++ */
++ PISP_AXI_FLAG_ALIGN = 128,
++ /* for FE writer: force WSTRB high, to pad output to 16-byte boundary */
++ PISP_AXI_FLAG_PAD = 64,
++ /* for FE writer: Use Output FIFO level to trigger "panic" */
++ PISP_AXI_FLAG_PANIC = 32,
++};
++
++struct pisp_axi_config {
++ /*
++ * burst length minus one, which must be in the range 0:15; OR'd with
++ * flags
++ */
++ __u8 maxlen_flags;
++ /* { prot[2:0], cache[3:0] } fields, echoed on AXI bus */
++ __u8 cache_prot;
++ /* QoS field(s) (4x4 bits for FE writer; 4 bits for other masters) */
++ __u16 qos;
++} __attribute__((packed));
++
++#endif /* _UAPI_PISP_COMMON_H_ */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch b/target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch
new file mode 100644
index 0000000000..0ee62a7d33
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch
@@ -0,0 +1,86 @@
+From 7ca73020a5b26599d539083e413784e79891107e Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 26 Jan 2024 15:04:59 +0100
+Subject: [PATCH 1150/1215] media: uapi: Document meta pixel format for PiSP BE
+ config
+
+Add format description for the PiSP Back End configuration parameter
+buffer.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../userspace-api/media/v4l/meta-formats.rst | 1 +
+ .../media/v4l/metafmt-pisp-be.rst | 56 +++++++++++++++++++
+ 2 files changed, 57 insertions(+)
+ create mode 100644 Documentation/userspace-api/media/v4l/metafmt-pisp-be.rst
+
+--- a/Documentation/userspace-api/media/v4l/meta-formats.rst
++++ b/Documentation/userspace-api/media/v4l/meta-formats.rst
+@@ -15,6 +15,7 @@ These formats are used for the :ref:`met
+ metafmt-bcm2835-isp-stats
+ metafmt-d4xx
+ metafmt-intel-ipu3
++ metafmt-pisp-be
+ metafmt-rkisp1
+ metafmt-sensor-data
+ metafmt-uvc
+--- /dev/null
++++ b/Documentation/userspace-api/media/v4l/metafmt-pisp-be.rst
+@@ -0,0 +1,56 @@
++.. SPDX-License-Identifier: GPL-2.0
++
++.. _v4l2-meta-fmt-rpi-be-cfg:
++
++************************
++V4L2_META_FMT_RPI_BE_CFG
++************************
++
++Raspberry Pi PiSP Back End configuration format
++===============================================
++
++The Raspberry Pi PiSP Back End memory-to-memory image signal processor is
++configured by userspace by providing a buffer of configuration parameters
++to the `pispbe-config` output video device node using the
++:c:type:`v4l2_meta_format` interface.
++
++The PiSP Back End processes images in tiles, and its configuration requires
++specifying two different sets of parameters by populating the members of
++:c:type:`pisp_be_tiles_config` defined in the ``pisp_be_config.h`` header file.
++
++The `Raspberry Pi PiSP technical specification
++<https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf>`_
++provide detailed description of the ISP back end configuration and programming
++model.
++
++Global configuration data
++-------------------------
++
++The global configuration data describe how the pixels in a particular image are
++to be processed and is therefore shared across all the tiles of the image. So
++for example, LSC (Lens Shading Correction) or Denoise parameters would be common
++across all tiles from the same frame.
++
++Global configuration data are passed to the ISP by populating the member of
++:c:type:`pisp_be_config`.
++
++Tile parameters
++---------------
++
++As the ISP processes images in tiles, each set of tiles parameters describe how
++a single tile in an image is going to be processed. A single set of tile
++parameters consist of 160 bytes of data and to process a batch of tiles several
++sets of tiles parameters are required.
++
++Tiles parameters are passed to the ISP by populating the member of
++``pisp_tile`` and the ``num_tiles`` fields of :c:type:`pisp_be_tiles_config`.
++
++Raspberry Pi PiSP Back End uAPI data types
++==========================================
++
++This section describes the data types exposed to userspace by the Raspberry Pi
++PiSP Back End. The section is informative only, for a detailed description of
++each field refer to the `Raspberry Pi PiSP technical specification
++<https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf>`_.
++
++.. kernel-doc:: include/uapi/linux/media/raspberrypi/pisp_be_config.h
diff --git a/target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch b/target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch
new file mode 100644
index 0000000000..aa4b003e5b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch
@@ -0,0 +1,106 @@
+From 5d6318f242cce5f9b5677baedde736a2b81061df Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Wed, 17 Jan 2024 11:21:50 +0200
+Subject: [PATCH 1151/1215] media: uapi: Document PiSP Compressed RAW Bayer
+ formats
+
+Document the Raspberry Pi compressed RAW Bayer formats.
+
+The compression algorithm description is provided by Nick Hollinghurst
+<nick.hollinghurst@raspberrypi.com> from Raspberry Pi.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../userspace-api/media/v4l/pixfmt-bayer.rst | 1 +
+ .../media/v4l/pixfmt-srggb8-pisp-comp.rst | 74 +++++++++++++++++++
+ 2 files changed, 75 insertions(+)
+ create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-srggb8-pisp-comp.rst
+
+--- a/Documentation/userspace-api/media/v4l/pixfmt-bayer.rst
++++ b/Documentation/userspace-api/media/v4l/pixfmt-bayer.rst
+@@ -20,6 +20,7 @@ orders. See also `the Wikipedia article
+ :maxdepth: 1
+
+ pixfmt-srggb8
++ pixfmt-srggb8-pisp-comp
+ pixfmt-srggb10
+ pixfmt-srggb10p
+ pixfmt-srggb10alaw8
+--- /dev/null
++++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb8-pisp-comp.rst
+@@ -0,0 +1,74 @@
++.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
++
++.. _v4l2-pix-fmt-pisp-comp1-rggb:
++.. _v4l2-pix-fmt-pisp-comp1-grbg:
++.. _v4l2-pix-fmt-pisp-comp1-gbrg:
++.. _v4l2-pix-fmt-pisp-comp1-bggr:
++.. _v4l2-pix-fmt-pisp-comp1-mono:
++.. _v4l2-pix-fmt-pisp-comp2-rggb:
++.. _v4l2-pix-fmt-pisp-comp2-grbg:
++.. _v4l2-pix-fmt-pisp-comp2-gbrg:
++.. _v4l2-pix-fmt-pisp-comp2-bggr:
++.. _v4l2-pix-fmt-pisp-comp2-mono:
++
++**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
++V4L2_PIX_FMT_PISP_COMP1_RGGB ('PC1R'), V4L2_PIX_FMT_PISP_COMP1_GRBG ('PC1G'), V4L2_PIX_FMT_PISP_COMP1_GBRG ('PC1g'), V4L2_PIX_FMT_PISP_COMP1_BGGR ('PC1B), V4L2_PIX_FMT_PISP_COMP1_MONO ('PC1M'), V4L2_PIX_FMT_PISP_COMP2_RGGB ('PC2R'), V4L2_PIX_FMT_PISP_COMP2_GRBG ('PC2G'), V4L2_PIX_FMT_PISP_COMP2_GBRG ('PC2g'), V4L2_PIX_FMT_PISP_COMP2_BGGR ('PC2B), V4L2_PIX_FMT_PISP_COMP2_MONO ('PC2M')
++**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
++
++================================================
++Raspberry Pi PiSP compressed 8-bit Bayer formats
++================================================
++
++Description
++===========
++
++The Raspberry Pi ISP (PiSP) uses a family of three fixed-rate compressed Bayer
++formats. A black-level offset may be subtracted to improve compression
++efficiency; the nominal black level and amount of offset must be signalled out
++of band. Each scanline is padded to a multiple of 8 pixels wide, and each block
++of 8 horizontally-contiguous pixels is coded using 8 bytes.
++
++Mode 1 uses a quantization and delta-based coding scheme which preserves up to
++12 significant bits. Mode 2 is a simple sqrt-like companding scheme with 6 PWL
++chords, preserving up to 12 significant bits. Mode 3 combines both companding
++(with 4 chords) and the delta scheme, preserving up to 14 significant bits.
++
++The remainder of this description applies to Modes 1 and 3.
++
++Each block of 8 pixels is separated into even and odd phases of 4 pixels,
++coded independently by 32-bit words at successive locations in memory.
++The two LS bits of each 32-bit word give its "quantization mode".
++
++In quantization mode 0, the lowest 321 quantization levels are multiples of
++FSD/4096 and the remaining levels are successive multiples of FSD/2048.
++Quantization modes 1 and 2 use linear quantization with step sizes of
++FSD/1024 and FSD/512 respectively. Each of the four pixels is quantized
++independently, with rounding to the nearest level.
++In quantization mode 2 where the middle two samples have quantized values
++(q1,q2) both in the range [384..511], they are coded using 9 bits for q1
++followed by 7 bits for (q2 & 127). Otherwise, for quantization modes
++0, 1 and 2: a 9-bit field encodes MIN(q1,q2) which must be in the range
++[0..511] and a 7-bit field encodes (q2-q1+64) which must be in [0..127].
++
++Each of the outer samples (q0,q3) is encoded using a 7-bit field based
++on its inner neighbour q1 or q2. In quantization mode 2 where the inner
++sample has a quantized value in the range [448..511], the field value is
++(q0-384). Otherwise for quantization modes 0, 1 and 2: The outer sample
++is encoded as (q0-MAX(0,q1-64)). q3 is likewise coded based on q2.
++Each of these values must be in the range [0..127]. All these fields
++of 2, 9, 7, 7, 7 bits respectively are packed in little-endian order
++to give a 32-bit word with LE byte order.
++
++Quantization mode 3 has a "7.5-bit" escape, used when none of the above
++encodings will fit. Each pixel value is quantized to the nearest of 176
++levels, where the lowest 95 levels are multiples of FSD/256 and the
++remaining levels are multiples of FSD/128 (level 175 represents values
++very close to FSD and may require saturating arithmetic to decode).
++
++Each pair of quantized pixels (q0,q1) or (q2,q3) is jointly coded
++by a 15-bit field: 2816*(q0>>4) + 16*q1 + (q0&15).
++Three fields of 2, 15, 15 bits are packed in LE order {15,15,2}.
++
++An implementation of a software decoder of compressed formats is available
++in `Raspberry Pi camera applications code base
++<https://github.com/raspberrypi/rpicam-apps/blob/main/image/dng.cpp>`_.
diff --git a/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch b/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch
new file mode 100644
index 0000000000..30c5cb3506
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch
@@ -0,0 +1,97 @@
+From c38a898c6877c6722ebfecea99f42e5a84c3e453 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 25 Jan 2024 16:42:33 +0100
+Subject: [PATCH 1152/1215] media: dt-bindings: Add bindings for Raspberry Pi
+ PiSP Back End
+
+Add bindings for the Raspberry Pi PiSP Back End memory-to-memory image
+signal processor.
+
+Datasheet:
+https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../bindings/media/raspberrypi,pispbe.yaml | 63 +++++++++++++++++++
+ MAINTAINERS | 1 +
+ 2 files changed, 64 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
+@@ -0,0 +1,63 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/media/raspberrypi,pispbe.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Raspberry Pi PiSP Image Signal Processor (ISP) Back End
++
++maintainers:
++ - Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
++ - Jacopo Mondi <jacopo.mondi@ideasonboard.com>
++
++description: |
++ The Raspberry Pi PiSP Image Signal Processor (ISP) Back End is an image
++ processor that fetches images in Bayer or Grayscale format from DRAM memory
++ in tiles and produces images consumable by applications.
++
++ The full ISP documentation is available at
++ https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
++
++properties:
++ compatible:
++ items:
++ - enum:
++ - brcm,bcm2712-pispbe
++ - const: raspberrypi,pispbe
++
++ reg:
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ iommus:
++ maxItems: 1
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/interrupt-controller/arm-gic.h>
++
++ soc {
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ isp@880000 {
++ compatible = "brcm,bcm2712-pispbe", "raspberrypi,pispbe";
++ reg = <0x10 0x00880000 0x0 0x4000>;
++ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&firmware_clocks 7>;
++ iommus = <&iommu2>;
++ };
++ };
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18037,6 +18037,7 @@ M: Jacopo Mondi <jacopo.mondi@ideasonboa
+ L: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
+ L: linux-media@vger.kernel.org
+ S: Maintained
++F: Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
+ F: include/uapi/linux/media/raspberrypi/
+
+ RC-CORE / LIRC FRAMEWORK
diff --git a/target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch b/target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch
new file mode 100644
index 0000000000..f443cc78c7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch
@@ -0,0 +1,162 @@
+From d68e76260316002869aea1b0edf4be399bb592b8 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Mon, 29 Jan 2024 17:23:55 +0100
+Subject: [PATCH 1153/1215] media: admin-guide: Document the Raspberry Pi PiSP
+ BE
+
+Add documentation for the PiSP Back End memory-to-memory ISP.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../admin-guide/media/raspberrypi-pisp-be.dot | 20 ++++
+ .../admin-guide/media/raspberrypi-pisp-be.rst | 109 ++++++++++++++++++
+ .../admin-guide/media/v4l-drivers.rst | 1 +
+ 3 files changed, 130 insertions(+)
+ create mode 100644 Documentation/admin-guide/media/raspberrypi-pisp-be.dot
+ create mode 100644 Documentation/admin-guide/media/raspberrypi-pisp-be.rst
+
+--- /dev/null
++++ b/Documentation/admin-guide/media/raspberrypi-pisp-be.dot
+@@ -0,0 +1,20 @@
++digraph board {
++ rankdir=TB
++ n00000001 [label="{{<port0> 0 | <port1> 1 | <port2> 2 | <port7> 7} | pispbe\n | {<port3> 3 | <port4> 4 | <port5> 5 | <port6> 6}}", shape=Mrecord, style=filled, fillcolor=green]
++ n00000001:port3 -> n0000001c [style=bold]
++ n00000001:port4 -> n00000022 [style=bold]
++ n00000001:port5 -> n00000028 [style=bold]
++ n00000001:port6 -> n0000002e [style=bold]
++ n0000000a [label="pispbe-input\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
++ n0000000a -> n00000001:port0 [style=bold]
++ n00000010 [label="pispbe-tdn_input\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
++ n00000010 -> n00000001:port1 [style=bold]
++ n00000016 [label="pispbe-stitch_input\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
++ n00000016 -> n00000001:port2 [style=bold]
++ n0000001c [label="pispbe-output0\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
++ n00000022 [label="pispbe-output1\n/dev/video4", shape=box, style=filled, fillcolor=yellow]
++ n00000028 [label="pispbe-tdn_output\n/dev/video5", shape=box, style=filled, fillcolor=yellow]
++ n0000002e [label="pispbe-stitch_output\n/dev/video6", shape=box, style=filled, fillcolor=yellow]
++ n00000034 [label="pispbe-config\n/dev/video7", shape=box, style=filled, fillcolor=yellow]
++ n00000034 -> n00000001:port7 [style=bold]
++}
+--- /dev/null
++++ b/Documentation/admin-guide/media/raspberrypi-pisp-be.rst
+@@ -0,0 +1,109 @@
++.. SPDX-License-Identifier: GPL-2.0
++
++=========================================================
++Raspberry Pi PiSP Back End Memory-to-Memory ISP (pisp-be)
++=========================================================
++
++The PiSP Back End
++=================
++
++The PiSP Back End is a memory-to-memory Image Signal Processor (ISP) which reads
++image data from DRAM memory and performs image processing as specified by the
++application through the parameters in a configuration buffer, before writing
++pixel data back to memory through two distinct output channels.
++
++The ISP registers and programming model are documented in the `Raspberry Pi
++Image Signal Processor (PiSP) Specification document`_
++
++The PiSP Back End ISP processes images in tiles. The handling of image
++tessellation and the computation of low-level configuration parameters is
++realized by a free software library called `libpisp
++<https://github.com/raspberrypi/libpisp>`_.
++
++The full image processing pipeline, which involves capturing RAW Bayer data from
++an image sensor through a MIPI CSI-2 compatible capture interface, storing them
++in DRAM memory and processing them in the PiSP Back End to obtain images usable
++by an application is implemented in `libcamera <https://libcamera.org>`_ as
++part of the Raspberry Pi platform support.
++
++The pisp-be driver
++==================
++
++The Raspberry Pi PiSP Back End (pisp-be) driver is located under
++drivers/media/platform/raspberrypi/pisp-be. It uses the `V4L2 API` to register
++a number of video capture and output devices, the `V4L2 subdev API` to register
++a subdevice for the ISP that connects the video devices in a single media graph
++realized using the `Media Controller (MC) API`.
++
++The media topology registered by the `pisp-be` driver is represented below:
++
++.. _pips-be-topology:
++
++.. kernel-figure:: raspberrypi-pisp-be.dot
++ :alt: Diagram of the default media pipeline topology
++ :align: center
++
++
++The media graph registers the following video device nodes:
++
++- pispbe-input: output device for images to be submitted to the ISP for
++ processing.
++- pispbe-tdn_input: output device for temporal denoise.
++- pispbe-stitch_input: output device for image stitching (HDR).
++- pispbe-output0: first capture device for processed images.
++- pispbe-output1: second capture device for processed images.
++- pispbe-tdn_output: capture device for temporal denoise.
++- pispbe-stitch_output: capture device for image stitching (HDR).
++- pispbe-config: output device for ISP configuration parameters.
++
++pispbe-input
++------------
++
++Images to be processed by the ISP are queued to the `pispbe-input` output device
++node. For a list of image formats supported as input to the ISP refer to the
++`Raspberry Pi Image Signal Processor (PiSP) Specification document`_.
++
++pispbe-tdn_input, pispbe-tdn_output
++-----------------------------------
++
++The `pispbe-tdn_input` output video device receives images to be processed by
++the temporal denoise block which are captured from the `pispbe-tdn_output`
++capture video device. Userspace is responsible for maintaining queues on both
++devices, and ensuring that buffers completed on the output are queued to the
++input.
++
++pispbe-stitch_input, pispbe-stitch_output
++-----------------------------------------
++
++To realize HDR (high dynamic range) image processing the image stitching and
++tonemapping blocks are used. The `pispbe-stitch_output` writes images to memory
++and the `pispbe-stitch_input` receives the previously written frame to process
++it along with the current input image. Userspace is responsible for maintaining
++queues on both devices, and ensuring that buffers completed on the output are
++queued to the input.
++
++pispbe-output0, pispbe-output1
++------------------------------
++
++The two capture devices write to memory the pixel data as processed by the ISP.
++
++pispbe-config
++-------------
++
++The `pispbe-config` output video devices receives a buffer of configuration
++parameters that define the desired image processing to be performed by the ISP.
++
++The format of the ISP configuration parameter is defined by
++:c:type:`pisp_be_tiles_config` C structure and the meaning of each parameter is
++described in the `Raspberry Pi Image Signal Processor (PiSP) Specification
++document`_.
++
++ISP configuration
++=================
++
++The ISP configuration is described solely by the content of the parameters
++buffer. The only parameter that userspace needs to configure using the V4L2 API
++is the image format on the output and capture video devices for validation of
++the content of the parameters buffer.
++
++.. _Raspberry Pi Image Signal Processor (PiSP) Specification document: https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
+--- a/Documentation/admin-guide/media/v4l-drivers.rst
++++ b/Documentation/admin-guide/media/v4l-drivers.rst
+@@ -21,6 +21,7 @@ Video4Linux (V4L) driver-specific docume
+ omap4_camera
+ philips
+ qcom_camss
++ raspberrypi-pisp-be
+ rcar-fdp1
+ rkisp1
+ saa7134
diff --git a/target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch b/target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch
new file mode 100644
index 0000000000..a0123995fe
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch
@@ -0,0 +1,2927 @@
+From c75989589bf77530f4013e0bc799169504c69937 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 27 Jun 2024 11:41:22 +0200
+Subject: [PATCH 1154/1215] media: pisp-be: Backport the mainline PiSP BE
+ driver
+
+Backport to rpi-6.6.y the mainline version of the PiSP BE driver.
+
+The backported version of the driver corresponds to the one available
+at:
+https://lore.kernel.org/all/20240626181440.195137-1-jacopo.mondi@ideasonboard.com/
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../platform/raspberrypi/pisp_be/Kconfig | 4 +-
+ .../platform/raspberrypi/pisp_be/pisp_be.c | 1288 +++++++----------
+ .../raspberrypi/pisp_be/pisp_be_config.h | 533 -------
+ .../raspberrypi/pisp_be/pisp_be_formats.h | 44 +-
+ 4 files changed, 572 insertions(+), 1297 deletions(-)
+ delete mode 100644 drivers/media/platform/raspberrypi/pisp_be/pisp_be_config.h
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/Kconfig
++++ b/drivers/media/platform/raspberrypi/pisp_be/Kconfig
+@@ -1,10 +1,10 @@
+ config VIDEO_RASPBERRYPI_PISP_BE
+ tristate "Raspberry Pi PiSP Backend (BE) ISP driver"
+- depends on VIDEO_DEV && PM
++ depends on V4L_PLATFORM_DRIVERS
++ depends on VIDEO_DEV
+ select VIDEO_V4L2_SUBDEV_API
+ select MEDIA_CONTROLLER
+ select VIDEOBUF2_DMA_CONTIG
+- select V4L2_FWNODE
+ help
+ Say Y here to enable support for the PiSP Backend (BE) ISP driver.
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
+@@ -1,12 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+ * PiSP Back End driver.
+- * Copyright (c) 2021-2022 Raspberry Pi Limited.
++ * Copyright (c) 2021-2024 Raspberry Pi Limited.
+ *
+ */
+ #include <linux/clk.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/lockdep.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+@@ -15,49 +17,39 @@
+ #include <media/videobuf2-dma-contig.h>
+ #include <media/videobuf2-vmalloc.h>
+
+-#include "pisp_be_config.h"
+-#include "pisp_be_formats.h"
+-
+-MODULE_DESCRIPTION("PiSP Back End driver");
+-MODULE_AUTHOR("David Plowman <david.plowman@raspberrypi.com>");
+-MODULE_AUTHOR("Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>");
+-MODULE_LICENSE("GPL v2");
++#include <uapi/linux/media/raspberrypi/pisp_be_config.h>
+
+-/* Offset to use when registering the /dev/videoX node */
+-#define PISPBE_VIDEO_NODE_OFFSET 20
++#include "pisp_be_formats.h"
+
+ /* Maximum number of config buffers possible */
+ #define PISP_BE_NUM_CONFIG_BUFFERS VB2_MAX_FRAME
+
+-/*
+- * We want to support 2 independent instances allowing 2 simultaneous users
+- * of the ISP-BE (of course they share hardware, platform resources and mutex).
+- * Each such instance comprises a group of device nodes representing input
+- * and output queues, and a media controller device node to describe them.
+- */
+-#define PISPBE_NUM_NODE_GROUPS 2
+-
+ #define PISPBE_NAME "pispbe"
+
+ /* Some ISP-BE registers */
+-#define PISP_BE_VERSION_OFFSET (0x0)
+-#define PISP_BE_CONTROL_OFFSET (0x4)
+-#define PISP_BE_TILE_ADDR_LO_OFFSET (0x8)
+-#define PISP_BE_TILE_ADDR_HI_OFFSET (0xc)
+-#define PISP_BE_STATUS_OFFSET (0x10)
+-#define PISP_BE_BATCH_STATUS_OFFSET (0x14)
+-#define PISP_BE_INTERRUPT_EN_OFFSET (0x18)
+-#define PISP_BE_INTERRUPT_STATUS_OFFSET (0x1c)
+-#define PISP_BE_AXI_OFFSET (0x20)
+-#define PISP_BE_CONFIG_BASE_OFFSET (0x40)
+-#define PISP_BE_IO_INPUT_ADDR0_LO_OFFSET (PISP_BE_CONFIG_BASE_OFFSET)
+-#define PISP_BE_GLOBAL_BAYER_ENABLE_OFFSET (PISP_BE_CONFIG_BASE_OFFSET + 0x70)
+-#define PISP_BE_GLOBAL_RGB_ENABLE_OFFSET (PISP_BE_CONFIG_BASE_OFFSET + 0x74)
+-#define N_HW_ADDRESSES 14
+-#define N_HW_ENABLES 2
++#define PISP_BE_VERSION_REG 0x0
++#define PISP_BE_CONTROL_REG 0x4
++#define PISP_BE_CONTROL_COPY_CONFIG BIT(1)
++#define PISP_BE_CONTROL_QUEUE_JOB BIT(0)
++#define PISP_BE_CONTROL_NUM_TILES(n) ((n) << 16)
++#define PISP_BE_TILE_ADDR_LO_REG 0x8
++#define PISP_BE_TILE_ADDR_HI_REG 0xc
++#define PISP_BE_STATUS_REG 0x10
++#define PISP_BE_STATUS_QUEUED BIT(0)
++#define PISP_BE_BATCH_STATUS_REG 0x14
++#define PISP_BE_INTERRUPT_EN_REG 0x18
++#define PISP_BE_INTERRUPT_STATUS_REG 0x1c
++#define PISP_BE_AXI_REG 0x20
++#define PISP_BE_CONFIG_BASE_REG 0x40
++#define PISP_BE_IO_ADDR_LOW(n) (PISP_BE_CONFIG_BASE_REG + 8 * (n))
++#define PISP_BE_IO_ADDR_HIGH(n) (PISP_BE_IO_ADDR_LOW((n)) + 4)
++#define PISP_BE_GLOBAL_BAYER_ENABLE 0xb0
++#define PISP_BE_GLOBAL_RGB_ENABLE 0xb4
++#define N_HW_ADDRESSES 13
++#define N_HW_ENABLES 2
+
+-#define PISP_BE_VERSION_2712C1 0x02252700
+-#define PISP_BE_VERSION_MINOR_BITS 0xF
++#define PISP_BE_VERSION_2712 0x02252700
++#define PISP_BE_VERSION_MINOR_BITS 0xf
+
+ /*
+ * This maps our nodes onto the inputs/outputs of the actual PiSP Back End.
+@@ -65,11 +57,10 @@ MODULE_LICENSE("GPL v2");
+ * context it means an input to the hardware (source image or metadata).
+ * Elsewhere it means an output from the hardware.
+ */
+-enum node_ids {
++enum pispbe_node_ids {
+ MAIN_INPUT_NODE,
+ TDN_INPUT_NODE,
+ STITCH_INPUT_NODE,
+- HOG_OUTPUT_NODE,
+ OUTPUT0_NODE,
+ OUTPUT1_NODE,
+ TDN_OUTPUT_NODE,
+@@ -78,13 +69,13 @@ enum node_ids {
+ PISPBE_NUM_NODES
+ };
+
+-struct node_description {
++struct pispbe_node_description {
+ const char *ent_name;
+ enum v4l2_buf_type buf_type;
+ unsigned int caps;
+ };
+
+-static const struct node_description node_desc[PISPBE_NUM_NODES] = {
++static const struct pispbe_node_description node_desc[PISPBE_NUM_NODES] = {
+ /* MAIN_INPUT_NODE */
+ {
+ .ent_name = PISPBE_NAME "-input",
+@@ -103,12 +94,6 @@ static const struct node_description nod
+ .buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ .caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE,
+ },
+- /* HOG_OUTPUT_NODE */
+- {
+- .ent_name = PISPBE_NAME "-hog_output",
+- .buf_type = V4L2_BUF_TYPE_META_CAPTURE,
+- .caps = V4L2_CAP_META_CAPTURE,
+- },
+ /* OUTPUT0_NODE */
+ {
+ .ent_name = PISPBE_NAME "-output0",
+@@ -147,14 +132,12 @@ static const struct node_description nod
+ ((desc)->buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
+
+ #define NODE_IS_META(node) ( \
+- ((node)->buf_type == V4L2_BUF_TYPE_META_OUTPUT) || \
+- ((node)->buf_type == V4L2_BUF_TYPE_META_CAPTURE))
++ ((node)->buf_type == V4L2_BUF_TYPE_META_OUTPUT))
+ #define NODE_IS_OUTPUT(node) ( \
+ ((node)->buf_type == V4L2_BUF_TYPE_META_OUTPUT) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
+ #define NODE_IS_CAPTURE(node) ( \
+- ((node)->buf_type == V4L2_BUF_TYPE_META_CAPTURE) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
+ #define NODE_IS_MPLANE(node) ( \
+@@ -173,9 +156,12 @@ struct pispbe_node {
+ struct media_pad pad;
+ struct media_intf_devnode *intf_devnode;
+ struct media_link *intf_link;
+- struct pispbe_node_group *node_group;
++ struct pispbe_dev *pispbe;
++ /* Video device lock */
+ struct mutex node_lock;
++ /* vb2_queue lock */
+ struct mutex queue_lock;
++ /* Protect pispbe_node->ready_queue and pispbe_buffer->ready_list */
+ spinlock_t ready_lock;
+ struct list_head ready_queue;
+ struct vb2_queue queue;
+@@ -186,29 +172,10 @@ struct pispbe_node {
+ /* For logging only, use the entity name with "pispbe" and separator removed */
+ #define NODE_NAME(node) \
+ (node_desc[(node)->id].ent_name + sizeof(PISPBE_NAME))
+-#define NODE_GET_V4L2(node) ((node)->node_group->v4l2_dev)
+-
+-/*
+- * Node group structure, which comprises all the input and output nodes that a
+- * single PiSP client will need, along with its own v4l2 and media devices.
+- */
+-struct pispbe_node_group {
+- unsigned int id;
+- struct v4l2_device v4l2_dev;
+- struct v4l2_subdev sd;
+- struct pispbe_dev *pispbe;
+- struct media_device mdev;
+- struct pispbe_node node[PISPBE_NUM_NODES];
+- u32 streaming_map; /* bitmap of which nodes are streaming */
+- struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
+- struct pisp_be_tiles_config *config;
+- dma_addr_t config_dma_addr;
+- unsigned int sequence;
+-};
+
+ /* Records details of the jobs currently running or queued on the h/w. */
+ struct pispbe_job {
+- struct pispbe_node_group *node_group;
++ bool valid;
+ /*
+ * An array of buffer pointers - remember it's source buffers first,
+ * then captures, then metadata last.
+@@ -216,85 +183,66 @@ struct pispbe_job {
+ struct pispbe_buffer *buf[PISPBE_NUM_NODES];
+ };
+
++struct pispbe_hw_enables {
++ u32 bayer_enables;
++ u32 rgb_enables;
++};
++
++/* Records a job configuration and memory addresses. */
++struct pispbe_job_descriptor {
++ dma_addr_t hw_dma_addrs[N_HW_ADDRESSES];
++ struct pisp_be_tiles_config *config;
++ struct pispbe_hw_enables hw_enables;
++ dma_addr_t tiles;
++};
++
+ /*
+ * Structure representing the entire PiSP Back End device, comprising several
+- * node groups which share platform resources and a mutex for the actual HW.
++ * nodes which share platform resources and a mutex for the actual HW.
+ */
+ struct pispbe_dev {
+ struct device *dev;
+- struct pispbe_node_group node_group[PISPBE_NUM_NODE_GROUPS];
+- int hw_busy; /* non-zero if a job is queued or is being started */
+- struct pispbe_job queued_job, running_job;
++ struct pispbe_dev *pispbe;
++ struct pisp_be_tiles_config *config;
+ void __iomem *be_reg_base;
+ struct clk *clk;
++ struct v4l2_device v4l2_dev;
++ struct v4l2_subdev sd;
++ struct media_device mdev;
++ struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
++ struct pispbe_node node[PISPBE_NUM_NODES];
++ dma_addr_t config_dma_addr;
++ unsigned int sequence;
++ u32 streaming_map;
++ struct pispbe_job queued_job, running_job;
++ spinlock_t hw_lock; /* protects "hw_busy" flag and streaming_map */
++ bool hw_busy; /* non-zero if a job is queued or is being started */
+ int irq;
+ u32 hw_version;
+ u8 done, started;
+- spinlock_t hw_lock; /* protects "hw_busy" flag and streaming_map */
+ };
+
+-static inline u32 read_reg(struct pispbe_dev *pispbe, unsigned int offset)
++static u32 pispbe_rd(struct pispbe_dev *pispbe, unsigned int offset)
+ {
+ return readl(pispbe->be_reg_base + offset);
+ }
+
+-static inline void write_reg(struct pispbe_dev *pispbe, unsigned int offset,
+- u32 val)
++static void pispbe_wr(struct pispbe_dev *pispbe, unsigned int offset, u32 val)
+ {
+ writel(val, pispbe->be_reg_base + offset);
+ }
+
+-/* Check and initialize hardware. */
+-static int hw_init(struct pispbe_dev *pispbe)
+-{
+- u32 u;
+-
+- /* Check the HW is present and has a known version */
+- u = read_reg(pispbe, PISP_BE_VERSION_OFFSET);
+- dev_info(pispbe->dev, "pispbe_probe: HW version: 0x%08x", u);
+- pispbe->hw_version = u;
+- if ((u & ~PISP_BE_VERSION_MINOR_BITS) != PISP_BE_VERSION_2712C1)
+- return -ENODEV;
+-
+- /* Clear leftover interrupts */
+- write_reg(pispbe, PISP_BE_INTERRUPT_STATUS_OFFSET, 0xFFFFFFFFu);
+- u = read_reg(pispbe, PISP_BE_BATCH_STATUS_OFFSET);
+- dev_info(pispbe->dev, "pispbe_probe: BatchStatus: 0x%08x", u);
+- pispbe->done = (uint8_t)u;
+- pispbe->started = (uint8_t)(u >> 8);
+- u = read_reg(pispbe, PISP_BE_STATUS_OFFSET);
+- dev_info(pispbe->dev, "pispbe_probe: Status: 0x%08x", u);
+- if (u != 0 || pispbe->done != pispbe->started) {
+- dev_err(pispbe->dev, "pispbe_probe: HW is stuck or busy\n");
+- return -EBUSY;
+- }
+- /*
+- * AXI QOS=0, CACHE=4'b0010, PROT=3'b011
+- * Also set "chicken bits" 22:20 which enable sub-64-byte bursts
+- * and AXI AWID/BID variability (on versions which support this).
+- */
+- write_reg(pispbe, PISP_BE_AXI_OFFSET, 0x32703200u);
+-
+- /* Enable both interrupt flags */
+- write_reg(pispbe, PISP_BE_INTERRUPT_EN_OFFSET, 0x00000003u);
+- return 0;
+-}
+-
+ /*
+ * Queue a job to the h/w. If the h/w is idle it will begin immediately.
+ * Caller must ensure it is "safe to queue", i.e. we don't already have a
+ * queued, unstarted job.
+ */
+-static void hw_queue_job(struct pispbe_dev *pispbe,
+- dma_addr_t hw_dma_addrs[N_HW_ADDRESSES],
+- u32 hw_enables[N_HW_ENABLES],
+- struct pisp_be_config *config, dma_addr_t tiles,
+- unsigned int num_tiles)
++static void pispbe_queue_job(struct pispbe_dev *pispbe,
++ struct pispbe_job_descriptor *job)
+ {
+ unsigned int begin, end;
+- unsigned int u;
+
+- if (read_reg(pispbe, PISP_BE_STATUS_OFFSET) & 1)
++ if (pispbe_rd(pispbe, PISP_BE_STATUS_REG) & PISP_BE_STATUS_QUEUED)
+ dev_err(pispbe->dev, "ERROR: not safe to queue new job!\n");
+
+ /*
+@@ -303,51 +251,49 @@ static void hw_queue_job(struct pispbe_d
+ * and we don't want to modify (or be vulnerable to modifications of)
+ * the mmap'd buffer.
+ */
+- for (u = 0; u < N_HW_ADDRESSES; ++u) {
+- write_reg(pispbe, PISP_BE_IO_INPUT_ADDR0_LO_OFFSET + 8 * u,
+- (u32)(hw_dma_addrs[u]));
+- write_reg(pispbe, PISP_BE_IO_INPUT_ADDR0_LO_OFFSET + 8 * u + 4,
+- (u32)(hw_dma_addrs[u] >> 32));
+- }
+- write_reg(pispbe, PISP_BE_GLOBAL_BAYER_ENABLE_OFFSET, hw_enables[0]);
+- write_reg(pispbe, PISP_BE_GLOBAL_RGB_ENABLE_OFFSET, hw_enables[1]);
++ for (unsigned int u = 0; u < N_HW_ADDRESSES; ++u) {
++ pispbe_wr(pispbe, PISP_BE_IO_ADDR_LOW(u),
++ lower_32_bits(job->hw_dma_addrs[u]));
++ pispbe_wr(pispbe, PISP_BE_IO_ADDR_HIGH(u),
++ upper_32_bits(job->hw_dma_addrs[u]));
++ }
++ pispbe_wr(pispbe, PISP_BE_GLOBAL_BAYER_ENABLE,
++ job->hw_enables.bayer_enables);
++ pispbe_wr(pispbe, PISP_BE_GLOBAL_RGB_ENABLE,
++ job->hw_enables.rgb_enables);
+
+- /*
+- * Everything else is as supplied by the user. XXX Buffer sizes not
+- * checked!
+- */
++ /* Everything else is as supplied by the user. */
+ begin = offsetof(struct pisp_be_config, global.bayer_order) /
+- sizeof(u32);
+- end = offsetof(struct pisp_be_config, axi) / sizeof(u32);
+- for (u = begin; u < end; u++) {
+- unsigned int val = ((u32 *)config)[u];
+-
+- write_reg(pispbe, PISP_BE_CONFIG_BASE_OFFSET + 4 * u, val);
+- }
++ sizeof(u32);
++ end = sizeof(struct pisp_be_config) / sizeof(u32);
++ for (unsigned int u = begin; u < end; u++)
++ pispbe_wr(pispbe, PISP_BE_CONFIG_BASE_REG + sizeof(u32) * u,
++ ((u32 *)job->config)[u]);
+
+ /* Read back the addresses -- an error here could be fatal */
+- for (u = 0; u < N_HW_ADDRESSES; ++u) {
+- unsigned int offset = PISP_BE_IO_INPUT_ADDR0_LO_OFFSET + 8 * u;
+- u64 along = read_reg(pispbe, offset);
+-
+- along += ((u64)read_reg(pispbe, offset + 4)) << 32;
+- if (along != (u64)(hw_dma_addrs[u])) {
+- dev_err(pispbe->dev,
++ for (unsigned int u = 0; u < N_HW_ADDRESSES; ++u) {
++ unsigned int offset = PISP_BE_IO_ADDR_LOW(u);
++ u64 along = pispbe_rd(pispbe, offset);
++
++ along += ((u64)pispbe_rd(pispbe, offset + 4)) << 32;
++ if (along != (u64)(job->hw_dma_addrs[u])) {
++ dev_dbg(pispbe->dev,
+ "ISP BE config error: check if ISP RAMs enabled?\n");
+ return;
+ }
+ }
+
+ /*
+- * Write tile pointer to hardware. XXX Tile offsets and sizes not
+- * checked (and even if checked, the user could subsequently modify
+- * them)!
++ * Write tile pointer to hardware. The IOMMU should prevent
++ * out-of-bounds offsets reaching non-ISP buffers.
+ */
+- write_reg(pispbe, PISP_BE_TILE_ADDR_LO_OFFSET, (u32)tiles);
+- write_reg(pispbe, PISP_BE_TILE_ADDR_HI_OFFSET, (u32)(tiles >> 32));
++ pispbe_wr(pispbe, PISP_BE_TILE_ADDR_LO_REG, lower_32_bits(job->tiles));
++ pispbe_wr(pispbe, PISP_BE_TILE_ADDR_HI_REG, upper_32_bits(job->tiles));
+
+ /* Enqueue the job */
+- write_reg(pispbe, PISP_BE_CONTROL_OFFSET, 3 + 65536 * num_tiles);
++ pispbe_wr(pispbe, PISP_BE_CONTROL_REG,
++ PISP_BE_CONTROL_COPY_CONFIG | PISP_BE_CONTROL_QUEUE_JOB |
++ PISP_BE_CONTROL_NUM_TILES(job->config->num_tiles));
+ }
+
+ struct pispbe_buffer {
+@@ -356,8 +302,8 @@ struct pispbe_buffer {
+ unsigned int config_index;
+ };
+
+-static int get_addr_3(dma_addr_t addr[3], struct pispbe_buffer *buf,
+- struct pispbe_node *node)
++static int pispbe_get_planes_addr(dma_addr_t addr[3], struct pispbe_buffer *buf,
++ struct pispbe_node *node)
+ {
+ unsigned int num_planes = node->format.fmt.pix_mp.num_planes;
+ unsigned int plane_factor = 0;
+@@ -367,22 +313,20 @@ static int get_addr_3(dma_addr_t addr[3]
+ if (!buf || !node->pisp_format)
+ return 0;
+
+- WARN_ON(!NODE_IS_MPLANE(node));
+-
+ /*
+ * Determine the base plane size. This will not be the same
+ * as node->format.fmt.pix_mp.plane_fmt[0].sizeimage for a single
+ * plane buffer in an mplane format.
+ */
+ size = node->format.fmt.pix_mp.plane_fmt[0].bytesperline *
+- node->format.fmt.pix_mp.height;
++ node->format.fmt.pix_mp.height;
+
+- for (p = 0; p < num_planes && p < 3; p++) {
++ for (p = 0; p < num_planes && p < PISPBE_MAX_PLANES; p++) {
+ addr[p] = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, p);
+ plane_factor += node->pisp_format->plane_factor[p];
+ }
+
+- for (; p < MAX_PLANES && node->pisp_format->plane_factor[p]; p++) {
++ for (; p < PISPBE_MAX_PLANES && node->pisp_format->plane_factor[p]; p++) {
+ /*
+ * Calculate the address offset of this plane as needed
+ * by the hardware. This is specifically for non-mplane
+@@ -396,41 +340,41 @@ static int get_addr_3(dma_addr_t addr[3]
+ return num_planes;
+ }
+
+-static dma_addr_t get_addr(struct pispbe_buffer *buf)
++static dma_addr_t pispbe_get_addr(struct pispbe_buffer *buf)
+ {
+ if (buf)
+ return vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
++
+ return 0;
+ }
+
+-static void
+-fixup_addrs_enables(dma_addr_t addrs[N_HW_ADDRESSES],
+- u32 hw_enables[N_HW_ENABLES],
+- struct pisp_be_tiles_config *config,
+- struct pispbe_buffer *buf[PISPBE_NUM_NODES],
+- struct pispbe_node_group *node_group)
+-{
+- int ret, i;
++static void pispbe_xlate_addrs(struct pispbe_dev *pispbe,
++ struct pispbe_job_descriptor *job,
++ struct pispbe_buffer *buf[PISPBE_NUM_NODES])
++{
++ struct pispbe_hw_enables *hw_en = &job->hw_enables;
++ struct pisp_be_tiles_config *config = job->config;
++ dma_addr_t *addrs = job->hw_dma_addrs;
++ int ret;
+
+ /* Take a copy of the "enable" bitmaps so we can modify them. */
+- hw_enables[0] = config->config.global.bayer_enables;
+- hw_enables[1] = config->config.global.rgb_enables;
++ hw_en->bayer_enables = config->config.global.bayer_enables;
++ hw_en->rgb_enables = config->config.global.rgb_enables;
+
+ /*
+ * Main input first. There are 3 address pointers, corresponding to up
+ * to 3 planes.
+ */
+- ret = get_addr_3(addrs, buf[MAIN_INPUT_NODE],
+- &node_group->node[MAIN_INPUT_NODE]);
++ ret = pispbe_get_planes_addr(addrs, buf[MAIN_INPUT_NODE],
++ &pispbe->node[MAIN_INPUT_NODE]);
+ if (ret <= 0) {
+ /*
+ * This shouldn't happen; pispbe_schedule_internal should insist
+ * on an input.
+ */
+- dev_warn(node_group->pispbe->dev,
+- "ISP-BE missing input\n");
+- hw_enables[0] = 0;
+- hw_enables[1] = 0;
++ dev_warn(pispbe->dev, "ISP-BE missing input\n");
++ hw_en->bayer_enables = 0;
++ hw_en->rgb_enables = 0;
+ return;
+ }
+
+@@ -439,118 +383,114 @@ fixup_addrs_enables(dma_addr_t addrs[N_H
+ * used with Bayer input. Input enables must match the requirements
+ * of the processing stages, otherwise the hardware can lock up!
+ */
+- if (hw_enables[0] & PISP_BE_BAYER_ENABLE_INPUT) {
+- addrs[3] = get_addr(buf[TDN_INPUT_NODE]);
++ if (hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_INPUT) {
++ addrs[3] = pispbe_get_addr(buf[TDN_INPUT_NODE]);
+ if (addrs[3] == 0 ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_TDN_INPUT) ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_TDN) ||
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_TDN_INPUT) ||
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_TDN) ||
+ (config->config.tdn.reset & 1)) {
+- hw_enables[0] &= ~(PISP_BE_BAYER_ENABLE_TDN_INPUT |
+- PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS);
++ hw_en->bayer_enables &=
++ ~(PISP_BE_BAYER_ENABLE_TDN_INPUT |
++ PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS);
+ if (!(config->config.tdn.reset & 1))
+- hw_enables[0] &= ~PISP_BE_BAYER_ENABLE_TDN;
++ hw_en->bayer_enables &=
++ ~PISP_BE_BAYER_ENABLE_TDN;
+ }
+
+- addrs[4] = get_addr(buf[STITCH_INPUT_NODE]);
++ addrs[4] = pispbe_get_addr(buf[STITCH_INPUT_NODE]);
+ if (addrs[4] == 0 ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_STITCH_INPUT) ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_STITCH)) {
+- hw_enables[0] &=
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_INPUT) ||
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_STITCH)) {
++ hw_en->bayer_enables &=
+ ~(PISP_BE_BAYER_ENABLE_STITCH_INPUT |
+ PISP_BE_BAYER_ENABLE_STITCH_DECOMPRESS |
+ PISP_BE_BAYER_ENABLE_STITCH);
+ }
+
+- addrs[5] = get_addr(buf[TDN_OUTPUT_NODE]);
++ addrs[5] = pispbe_get_addr(buf[TDN_OUTPUT_NODE]);
+ if (addrs[5] == 0)
+- hw_enables[0] &= ~(PISP_BE_BAYER_ENABLE_TDN_COMPRESS |
+- PISP_BE_BAYER_ENABLE_TDN_OUTPUT);
++ hw_en->bayer_enables &=
++ ~(PISP_BE_BAYER_ENABLE_TDN_COMPRESS |
++ PISP_BE_BAYER_ENABLE_TDN_OUTPUT);
+
+- addrs[6] = get_addr(buf[STITCH_OUTPUT_NODE]);
++ addrs[6] = pispbe_get_addr(buf[STITCH_OUTPUT_NODE]);
+ if (addrs[6] == 0)
+- hw_enables[0] &=
++ hw_en->bayer_enables &=
+ ~(PISP_BE_BAYER_ENABLE_STITCH_COMPRESS |
+ PISP_BE_BAYER_ENABLE_STITCH_OUTPUT);
+ } else {
+ /* No Bayer input? Disable entire Bayer pipe (else lockup) */
+- hw_enables[0] = 0;
++ hw_en->bayer_enables = 0;
+ }
+
+ /* Main image output channels. */
+- for (i = 0; i < PISP_BACK_END_NUM_OUTPUTS; i++) {
+- ret = get_addr_3(addrs + 7 + 3 * i, buf[OUTPUT0_NODE + i],
+- &node_group->node[OUTPUT0_NODE + i]);
++ for (unsigned int i = 0; i < PISP_BACK_END_NUM_OUTPUTS; i++) {
++ ret = pispbe_get_planes_addr(addrs + 7 + 3 * i,
++ buf[OUTPUT0_NODE + i],
++ &pispbe->node[OUTPUT0_NODE + i]);
+ if (ret <= 0)
+- hw_enables[1] &= ~(PISP_BE_RGB_ENABLE_OUTPUT0 << i);
++ hw_en->rgb_enables &= ~(PISP_BE_RGB_ENABLE_OUTPUT0 << i);
+ }
+-
+- /* HoG output (always single plane). */
+- addrs[13] = get_addr(buf[HOG_OUTPUT_NODE]);
+- if (addrs[13] == 0)
+- hw_enables[1] &= ~PISP_BE_RGB_ENABLE_HOG;
+ }
+
+ /*
+- * Internal function. Called from pispbe_schedule_one/all. Returns non-zero if
+- * we started a job.
++ * Prepare a job description to be submitted to the HW.
++ *
++ * To schedule a job, we need all streaming nodes (apart from Output0,
++ * Output1, Tdn and Stitch) to have a buffer ready, which must
++ * include at least a config buffer and a main input image.
+ *
+- * Warning: needs to be called with hw_lock taken, and releases it if it
+- * schedules a job.
++ * For Output0, Output1, Tdn and Stitch, a buffer only needs to be
++ * available if the blocks are enabled in the config.
++ *
++ * Needs to be called with hw_lock held.
++ *
++ * Returns 0 if a job has been successfully prepared, < 0 otherwise.
+ */
+-static int pispbe_schedule_internal(struct pispbe_node_group *node_group,
+- unsigned long flags)
++static int pispbe_prepare_job(struct pispbe_dev *pispbe,
++ struct pispbe_job_descriptor *job)
+ {
+- struct pisp_be_tiles_config *config_tiles_buffer;
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- struct pispbe_buffer *buf[PISPBE_NUM_NODES];
+- dma_addr_t hw_dma_addrs[N_HW_ADDRESSES];
+- dma_addr_t tiles;
+- u32 hw_enables[N_HW_ENABLES];
+- struct pispbe_node *node;
+- unsigned long flags1;
++ struct pispbe_buffer *buf[PISPBE_NUM_NODES] = {};
+ unsigned int config_index;
+- int i;
++ struct pispbe_node *node;
++ unsigned long flags;
++
++ lockdep_assert_held(&pispbe->hw_lock);
++
++ memset(job, 0, sizeof(struct pispbe_job_descriptor));
+
+- /*
+- * To schedule a job, we need all streaming nodes (apart from Output0,
+- * Output1, Tdn and Stitch) to have a buffer ready, which must
+- * include at least a config buffer and a main input image.
+- *
+- * For Output0, Output1, Tdn and Stitch, a buffer only needs to be
+- * available if the blocks are enabled in the config.
+- *
+- * (Note that streaming_map is protected by hw_lock, which is held.)
+- */
+ if (((BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)) &
+- node_group->streaming_map) !=
+- (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE))) {
+- dev_dbg(pispbe->dev, "Nothing to do\n");
+- return 0;
+- }
++ pispbe->streaming_map) !=
++ (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)))
++ return -ENODEV;
+
+- node = &node_group->node[CONFIG_NODE];
+- spin_lock_irqsave(&node->ready_lock, flags1);
+- buf[CONFIG_NODE] =
+- list_first_entry_or_null(&node->ready_queue, struct pispbe_buffer,
+- ready_list);
+- spin_unlock_irqrestore(&node->ready_lock, flags1);
++ node = &pispbe->node[CONFIG_NODE];
++ spin_lock_irqsave(&node->ready_lock, flags);
++ buf[CONFIG_NODE] = list_first_entry_or_null(&node->ready_queue,
++ struct pispbe_buffer,
++ ready_list);
++ if (buf[CONFIG_NODE]) {
++ list_del(&buf[CONFIG_NODE]->ready_list);
++ pispbe->queued_job.buf[CONFIG_NODE] = buf[CONFIG_NODE];
++ }
++ spin_unlock_irqrestore(&node->ready_lock, flags);
+
+ /* Exit early if no config buffer has been queued. */
+ if (!buf[CONFIG_NODE])
+- return 0;
++ return -ENODEV;
+
+ config_index = buf[CONFIG_NODE]->vb.vb2_buf.index;
+- config_tiles_buffer = &node_group->config[config_index];
+- tiles = (dma_addr_t)node_group->config_dma_addr +
+- config_index * sizeof(struct pisp_be_tiles_config) +
+- offsetof(struct pisp_be_tiles_config, tiles);
++ job->config = &pispbe->config[config_index];
++ job->tiles = pispbe->config_dma_addr +
++ config_index * sizeof(struct pisp_be_tiles_config) +
++ offsetof(struct pisp_be_tiles_config, tiles);
+
+ /* remember: srcimages, captures then metadata */
+- for (i = 0; i < PISPBE_NUM_NODES; i++) {
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+ unsigned int bayer_en =
+- config_tiles_buffer->config.global.bayer_enables;
++ job->config->config.global.bayer_enables;
+ unsigned int rgb_en =
+- config_tiles_buffer->config.global.rgb_enables;
++ job->config->config.global.rgb_enables;
+ bool ignore_buffers = false;
+
+ /* Config node is handled outside the loop above. */
+@@ -558,7 +498,7 @@ static int pispbe_schedule_internal(stru
+ continue;
+
+ buf[i] = NULL;
+- if (!(node_group->streaming_map & BIT(i)))
++ if (!(pispbe->streaming_map & BIT(i)))
+ continue;
+
+ if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0) &&
+@@ -578,119 +518,103 @@ static int pispbe_schedule_internal(stru
+ * global enables aren't set for these blocks. If a
+ * buffer has been provided, we dequeue it back to the
+ * user with the other in-use buffers.
+- *
+ */
+ ignore_buffers = true;
+ }
+
+- node = &node_group->node[i];
++ node = &pispbe->node[i];
+
+- spin_lock_irqsave(&node->ready_lock, flags1);
++ /* Pull a buffer from each V4L2 queue to form the queued job */
++ spin_lock_irqsave(&node->ready_lock, flags);
+ buf[i] = list_first_entry_or_null(&node->ready_queue,
+ struct pispbe_buffer,
+ ready_list);
+- spin_unlock_irqrestore(&node->ready_lock, flags1);
+- if (!buf[i] && !ignore_buffers) {
+- dev_dbg(pispbe->dev, "Nothing to do\n");
+- return 0;
+- }
+- }
+-
+- /* Pull a buffer from each V4L2 queue to form the queued job */
+- for (i = 0; i < PISPBE_NUM_NODES; i++) {
+ if (buf[i]) {
+- node = &node_group->node[i];
+-
+- spin_lock_irqsave(&node->ready_lock, flags1);
+ list_del(&buf[i]->ready_list);
+- spin_unlock_irqrestore(&node->ready_lock,
+- flags1);
++ pispbe->queued_job.buf[i] = buf[i];
+ }
+- pispbe->queued_job.buf[i] = buf[i];
++ spin_unlock_irqrestore(&node->ready_lock, flags);
++
++ if (!buf[i] && !ignore_buffers)
++ goto err_return_buffers;
+ }
+
+- pispbe->queued_job.node_group = node_group;
+- pispbe->hw_busy = 1;
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+-
+- /*
+- * We can kick the job off without the hw_lock, as this can
+- * never run again until hw_busy is cleared, which will happen
+- * only when the following job has been queued.
+- */
+- dev_dbg(pispbe->dev, "Have buffers - starting hardware\n");
++ pispbe->queued_job.valid = true;
+
+ /* Convert buffers to DMA addresses for the hardware */
+- fixup_addrs_enables(hw_dma_addrs, hw_enables,
+- config_tiles_buffer, buf, node_group);
+- /*
+- * This could be a spot to fill in the
+- * buf[i]->vb.vb2_buf.planes[j].bytesused fields?
+- */
+- i = config_tiles_buffer->num_tiles;
+- if (i <= 0 || i > PISP_BACK_END_NUM_TILES ||
+- !((hw_enables[0] | hw_enables[1]) &
+- PISP_BE_BAYER_ENABLE_INPUT)) {
+- /*
+- * Bad job. We can't let it proceed as it could lock up
+- * the hardware, or worse!
+- *
+- * XXX How to deal with this most cleanly? For now, just
+- * force num_tiles to 0, which causes the H/W to do
+- * something bizarre but survivable. It increments
+- * (started,done) counters by more than 1, but we seem
+- * to survive...
+- */
+- dev_err(pispbe->dev, "PROBLEM: Bad job");
+- i = 0;
+- }
+- hw_queue_job(pispbe, hw_dma_addrs, hw_enables,
+- &config_tiles_buffer->config, tiles, i);
++ pispbe_xlate_addrs(pispbe, job, buf);
+
+- return 1;
+-}
++ return 0;
+
+-/* Try and schedule a job for just a single node group. */
+-static void pispbe_schedule_one(struct pispbe_node_group *node_group)
+-{
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- unsigned long flags;
+- int ret;
++err_return_buffers:
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
++ struct pispbe_node *n = &pispbe->node[i];
+
+- spin_lock_irqsave(&pispbe->hw_lock, flags);
+- if (pispbe->hw_busy) {
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+- return;
++ if (!buf[i])
++ continue;
++
++ /* Return the buffer to the ready_list queue */
++ spin_lock_irqsave(&n->ready_lock, flags);
++ list_add(&buf[i]->ready_list, &n->ready_queue);
++ spin_unlock_irqrestore(&n->ready_lock, flags);
+ }
+
+- /* A non-zero return means the lock was released. */
+- ret = pispbe_schedule_internal(node_group, flags);
+- if (!ret)
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++ memset(&pispbe->queued_job, 0, sizeof(pispbe->queued_job));
++
++ return -ENODEV;
+ }
+
+-/* Try and schedule a job for any of the node groups. */
+-static void pispbe_schedule_any(struct pispbe_dev *pispbe, int clear_hw_busy)
++static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy)
+ {
++ struct pispbe_job_descriptor job;
+ unsigned long flags;
++ int ret;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+
+ if (clear_hw_busy)
+- pispbe->hw_busy = 0;
+- if (pispbe->hw_busy == 0) {
+- unsigned int i;
++ pispbe->hw_busy = false;
+
+- for (i = 0; i < PISPBE_NUM_NODE_GROUPS; i++) {
+- /*
+- * A non-zero return from pispbe_schedule_internal means
+- * the lock was released.
+- */
+- if (pispbe_schedule_internal(&pispbe->node_group[i],
+- flags))
+- return;
+- }
++ if (pispbe->hw_busy)
++ goto unlock_and_return;
++
++ ret = pispbe_prepare_job(pispbe, &job);
++ if (ret)
++ goto unlock_and_return;
++
++ /*
++ * We can kick the job off without the hw_lock, as this can
++ * never run again until hw_busy is cleared, which will happen
++ * only when the following job has been queued and an interrupt
++ * is rised.
++ */
++ pispbe->hw_busy = true;
++ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++
++ if (job.config->num_tiles <= 0 ||
++ job.config->num_tiles > PISP_BACK_END_NUM_TILES ||
++ !((job.hw_enables.bayer_enables | job.hw_enables.rgb_enables) &
++ PISP_BE_BAYER_ENABLE_INPUT)) {
++ /*
++ * Bad job. We can't let it proceed as it could lock up
++ * the hardware, or worse!
++ *
++ * For now, just force num_tiles to 0, which causes the
++ * H/W to do something bizarre but survivable. It
++ * increments (started,done) counters by more than 1,
++ * but we seem to survive...
++ */
++ dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n",
++ job.config->num_tiles);
++ job.config->num_tiles = 0;
+ }
++
++ pispbe_queue_job(pispbe, &job);
++
++ return;
++
++unlock_and_return:
++ /* No job has been queued, just release the lock and return. */
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+ }
+
+@@ -699,62 +623,53 @@ static void pispbe_isr_jobdone(struct pi
+ {
+ struct pispbe_buffer **buf = job->buf;
+ u64 ts = ktime_get_ns();
+- int i;
+
+- for (i = 0; i < PISPBE_NUM_NODES; i++) {
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+ if (buf[i]) {
+ buf[i]->vb.vb2_buf.timestamp = ts;
+- buf[i]->vb.sequence = job->node_group->sequence;
++ buf[i]->vb.sequence = pispbe->sequence;
+ vb2_buffer_done(&buf[i]->vb.vb2_buf,
+ VB2_BUF_STATE_DONE);
+ }
+ }
+
+- job->node_group->sequence++;
++ pispbe->sequence++;
+ }
+
+ static irqreturn_t pispbe_isr(int irq, void *dev)
+ {
+ struct pispbe_dev *pispbe = (struct pispbe_dev *)dev;
++ bool can_queue_another = false;
+ u8 started, done;
+- int can_queue_another = 0;
+ u32 u;
+
+- u = read_reg(pispbe, PISP_BE_INTERRUPT_STATUS_OFFSET);
++ u = pispbe_rd(pispbe, PISP_BE_INTERRUPT_STATUS_REG);
+ if (u == 0)
+ return IRQ_NONE;
+
+- write_reg(pispbe, PISP_BE_INTERRUPT_STATUS_OFFSET, u);
+- dev_dbg(pispbe->dev, "Hardware interrupt\n");
+- u = read_reg(pispbe, PISP_BE_BATCH_STATUS_OFFSET);
++ pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, u);
++ u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG);
+ done = (uint8_t)u;
+ started = (uint8_t)(u >> 8);
+- dev_dbg(pispbe->dev,
+- "H/W started %d done %d, previously started %d done %d\n",
+- (int)started, (int)done, (int)pispbe->started,
+- (int)pispbe->done);
+
+ /*
+ * Be aware that done can go up by 2 and started by 1 when: a job that
+ * we previously saw "start" now finishes, and we then queued a new job
+ * which we see both start and finish "simultaneously".
+ */
+- if (pispbe->running_job.node_group && pispbe->done != done) {
++ if (pispbe->running_job.valid && pispbe->done != done) {
+ pispbe_isr_jobdone(pispbe, &pispbe->running_job);
+ memset(&pispbe->running_job, 0, sizeof(pispbe->running_job));
+ pispbe->done++;
+- dev_dbg(pispbe->dev, "Job done (1)\n");
+ }
+
+ if (pispbe->started != started) {
+ pispbe->started++;
+ can_queue_another = 1;
+- dev_dbg(pispbe->dev, "Job started\n");
+
+- if (pispbe->done != done && pispbe->queued_job.node_group) {
++ if (pispbe->done != done && pispbe->queued_job.valid) {
+ pispbe_isr_jobdone(pispbe, &pispbe->queued_job);
+ pispbe->done++;
+- dev_dbg(pispbe->dev, "Job done (2)\n");
+ } else {
+ pispbe->running_job = pispbe->queued_job;
+ }
+@@ -763,74 +678,81 @@ static irqreturn_t pispbe_isr(int irq, v
+ }
+
+ if (pispbe->done != done || pispbe->started != started) {
+- dev_err(pispbe->dev, "PROBLEM: counters not matching!\n");
++ dev_dbg(pispbe->dev,
++ "Job counters not matching: done = %u, expected %u - started = %u, expected %u\n",
++ pispbe->done, done, pispbe->started, started);
+ pispbe->started = started;
+ pispbe->done = done;
+ }
+
+ /* check if there's more to do before going to sleep */
+- pispbe_schedule_any(pispbe, can_queue_another);
++ pispbe_schedule(pispbe, can_queue_another);
+
+ return IRQ_HANDLED;
+ }
+
+-static int pisp_be_validate_config(struct pispbe_node_group *node_group,
++static int pisp_be_validate_config(struct pispbe_dev *pispbe,
+ struct pisp_be_tiles_config *config)
+ {
+ u32 bayer_enables = config->config.global.bayer_enables;
+ u32 rgb_enables = config->config.global.rgb_enables;
+- struct device *dev = node_group->pispbe->dev;
++ struct device *dev = pispbe->dev;
+ struct v4l2_format *fmt;
+- unsigned int bpl, size, i, j;
++ unsigned int bpl, size;
+
+ if (!(bayer_enables & PISP_BE_BAYER_ENABLE_INPUT) ==
+ !(rgb_enables & PISP_BE_RGB_ENABLE_INPUT)) {
+- dev_err(dev, "%s: Not one input enabled\n", __func__);
++ dev_dbg(dev, "%s: Not one input enabled\n", __func__);
+ return -EIO;
+ }
+
+ /* Ensure output config strides and buffer sizes match the V4L2 formats. */
+- fmt = &node_group->node[TDN_OUTPUT_NODE].format;
++ fmt = &pispbe->node[TDN_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_TDN_OUTPUT) {
+ bpl = config->config.tdn_output_format.stride;
+ size = bpl * config->config.tdn_output_format.height;
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].bytesperline < bpl) {
+- dev_err(dev, "%s: bpl mismatch on tdn_output\n",
++ dev_dbg(dev, "%s: bpl mismatch on tdn_output\n",
+ __func__);
+ return -EINVAL;
+ }
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].sizeimage < size) {
+- dev_err(dev, "%s: size mismatch on tdn_output\n",
++ dev_dbg(dev, "%s: size mismatch on tdn_output\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+- fmt = &node_group->node[STITCH_OUTPUT_NODE].format;
++ fmt = &pispbe->node[STITCH_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_OUTPUT) {
+ bpl = config->config.stitch_output_format.stride;
+ size = bpl * config->config.stitch_output_format.height;
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].bytesperline < bpl) {
+- dev_err(dev, "%s: bpl mismatch on stitch_output\n",
++ dev_dbg(dev, "%s: bpl mismatch on stitch_output\n",
+ __func__);
+ return -EINVAL;
+ }
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].sizeimage < size) {
+- dev_err(dev, "%s: size mismatch on stitch_output\n",
++ dev_dbg(dev, "%s: size mismatch on stitch_output\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+- for (j = 0; j < PISP_BACK_END_NUM_OUTPUTS; j++) {
++ for (unsigned int j = 0; j < PISP_BACK_END_NUM_OUTPUTS; j++) {
+ if (!(rgb_enables & PISP_BE_RGB_ENABLE_OUTPUT(j)))
+ continue;
++
+ if (config->config.output_format[j].image.format &
+ PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
+ continue; /* TODO: Size checks for wallpaper formats */
+
+- fmt = &node_group->node[OUTPUT0_NODE + j].format;
+- for (i = 0; i < fmt->fmt.pix_mp.num_planes; i++) {
++ fmt = &pispbe->node[OUTPUT0_NODE + j].format;
++ for (unsigned int i = 0; i < fmt->fmt.pix_mp.num_planes; i++) {
+ bpl = !i ? config->config.output_format[j].image.stride
+ : config->config.output_format[j].image.stride2;
+ size = bpl * config->config.output_format[j].image.height;
+@@ -838,13 +760,15 @@ static int pisp_be_validate_config(struc
+ if (config->config.output_format[j].image.format &
+ PISP_IMAGE_FORMAT_SAMPLING_420)
+ size >>= 1;
++
+ if (fmt->fmt.pix_mp.plane_fmt[i].bytesperline < bpl) {
+- dev_err(dev, "%s: bpl mismatch on output %d\n",
++ dev_dbg(dev, "%s: bpl mismatch on output %d\n",
+ __func__, j);
+ return -EINVAL;
+ }
++
+ if (fmt->fmt.pix_mp.plane_fmt[i].sizeimage < size) {
+- dev_err(dev, "%s: size mismatch on output\n",
++ dev_dbg(dev, "%s: size mismatch on output\n",
+ __func__);
+ return -EINVAL;
+ }
+@@ -859,32 +783,32 @@ static int pispbe_node_queue_setup(struc
+ struct device *alloc_devs[])
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
++ unsigned int num_planes = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.num_planes : 1;
+
+- *nplanes = 1;
+- if (NODE_IS_MPLANE(node)) {
+- unsigned int i;
+-
+- *nplanes = node->format.fmt.pix_mp.num_planes;
+- for (i = 0; i < *nplanes; i++) {
+- unsigned int size =
+- node->format.fmt.pix_mp.plane_fmt[i].sizeimage;
+- if (sizes[i] && sizes[i] < size) {
+- dev_err(pispbe->dev, "%s: size %u < %u\n",
+- __func__, sizes[i], size);
++ if (*nplanes) {
++ if (*nplanes != num_planes)
++ return -EINVAL;
++
++ for (unsigned int i = 0; i < *nplanes; i++) {
++ unsigned int size = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.plane_fmt[i].sizeimage :
++ node->format.fmt.meta.buffersize;
++
++ if (sizes[i] < size)
+ return -EINVAL;
+- }
+- sizes[i] = size;
+ }
+- } else if (NODE_IS_META(node)) {
+- sizes[0] = node->format.fmt.meta.buffersize;
+- /*
+- * Limit the config node buffer count to the number of internal
+- * buffers allocated.
+- */
+- if (node->id == CONFIG_NODE)
+- *nbuffers = min_t(unsigned int, *nbuffers,
+- PISP_BE_NUM_CONFIG_BUFFERS);
++
++ return 0;
++ }
++
++ *nplanes = num_planes;
++ for (unsigned int i = 0; i < *nplanes; i++) {
++ unsigned int size = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.plane_fmt[i].sizeimage :
++ node->format.fmt.meta.buffersize;
++ sizes[i] = size;
+ }
+
+ dev_dbg(pispbe->dev,
+@@ -897,19 +821,17 @@ static int pispbe_node_queue_setup(struc
+ static int pispbe_node_buffer_prepare(struct vb2_buffer *vb)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(vb->vb2_queue);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- unsigned long size = 0;
++ struct pispbe_dev *pispbe = node->pispbe;
+ unsigned int num_planes = NODE_IS_MPLANE(node) ?
+- node->format.fmt.pix_mp.num_planes : 1;
+- unsigned int i;
++ node->format.fmt.pix_mp.num_planes : 1;
+
+- for (i = 0; i < num_planes; i++) {
+- size = NODE_IS_MPLANE(node)
+- ? node->format.fmt.pix_mp.plane_fmt[i].sizeimage
+- : node->format.fmt.meta.buffersize;
++ for (unsigned int i = 0; i < num_planes; i++) {
++ unsigned long size = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.plane_fmt[i].sizeimage :
++ node->format.fmt.meta.buffersize;
+
+ if (vb2_plane_size(vb, i) < size) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "data will not fit into plane %d (%lu < %lu)\n",
+ i, vb2_plane_size(vb, i), size);
+ return -EINVAL;
+@@ -919,11 +841,12 @@ static int pispbe_node_buffer_prepare(st
+ }
+
+ if (node->id == CONFIG_NODE) {
+- void *dst = &node->node_group->config[vb->index];
++ void *dst = &node->pispbe->config[vb->index];
+ void *src = vb2_plane_vaddr(vb, 0);
+
+ memcpy(dst, src, sizeof(struct pisp_be_tiles_config));
+- return pisp_be_validate_config(node->node_group, dst);
++
++ return pisp_be_validate_config(pispbe, dst);
+ }
+
+ return 0;
+@@ -936,8 +859,7 @@ static void pispbe_node_buffer_queue(str
+ struct pispbe_buffer *buffer =
+ container_of(vbuf, struct pispbe_buffer, vb);
+ struct pispbe_node *node = vb2_get_drv_priv(buf->vb2_queue);
+- struct pispbe_node_group *node_group = node->node_group;
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+ unsigned long flags;
+
+ dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
+@@ -947,44 +869,53 @@ static void pispbe_node_buffer_queue(str
+
+ /*
+ * Every time we add a buffer, check if there's now some work for the hw
+- * to do, but only for this client.
++ * to do.
+ */
+- pispbe_schedule_one(node_group);
++ pispbe_schedule(pispbe, false);
+ }
+
+ static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+- unsigned long flags;
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_node_group *node_group = node->node_group;
+- struct pispbe_dev *pispbe = node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_buffer *buf, *tmp;
++ unsigned long flags;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(pispbe->dev);
+ if (ret < 0)
+- return ret;
++ goto err_return_buffers;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- node->node_group->streaming_map |= BIT(node->id);
+- node->node_group->sequence = 0;
++ node->pispbe->streaming_map |= BIT(node->id);
++ node->pispbe->sequence = 0;
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n",
+ __func__, NODE_NAME(node), count);
+- dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
+- node->node_group->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
++ node->pispbe->streaming_map);
+
+ /* Maybe we're ready to run. */
+- pispbe_schedule_one(node_group);
++ pispbe_schedule(pispbe, false);
+
+ return 0;
++
++err_return_buffers:
++ spin_lock_irqsave(&pispbe->hw_lock, flags);
++ list_for_each_entry_safe(buf, tmp, &node->ready_queue, ready_list) {
++ list_del(&buf->ready_list);
++ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
++ }
++ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++
++ return ret;
+ }
+
+ static void pispbe_node_stop_streaming(struct vb2_queue *q)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_node_group *node_group = node->node_group;
+- struct pispbe_dev *pispbe = node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+ struct pispbe_buffer *buf;
+ unsigned long flags;
+
+@@ -994,7 +925,8 @@ static void pispbe_node_stop_streaming(s
+ * partial set of buffers was queued and cannot be run. For now, just
+ * cancel all buffers stuck in the "ready queue", then wait for any
+ * running job.
+- * XXX This may return buffers out of order.
++ *
++ * This may return buffers out of order.
+ */
+ dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+@@ -1016,14 +948,14 @@ static void pispbe_node_stop_streaming(s
+ vb2_wait_for_all_buffers(&node->queue);
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- node_group->streaming_map &= ~BIT(node->id);
++ pispbe->streaming_map &= ~BIT(node->id);
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+- dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
+- node_group->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
++ pispbe->streaming_map);
+ }
+
+ static const struct vb2_ops pispbe_node_queue_ops = {
+@@ -1047,22 +979,15 @@ static int pispbe_node_querycap(struct f
+ struct v4l2_capability *cap)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ strscpy(cap->driver, PISPBE_NAME, sizeof(cap->driver));
+ strscpy(cap->card, PISPBE_NAME, sizeof(cap->card));
+- snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+- dev_name(pispbe->dev));
+-
+- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+- V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+- V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS |
+- V4L2_CAP_META_OUTPUT | V4L2_CAP_META_CAPTURE;
+- cap->device_caps = node->vfd.device_caps;
+
+ dev_dbg(pispbe->dev, "Caps for node %s: %x and %x (dev %x)\n",
+ NODE_NAME(node), cap->capabilities, cap->device_caps,
+ node->vfd.device_caps);
++
+ return 0;
+ }
+
+@@ -1070,17 +995,19 @@ static int pispbe_node_g_fmt_vid_cap(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot get capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
++
+ *f = node->format;
+ dev_dbg(pispbe->dev, "Get capture format for node %s\n",
+ NODE_NAME(node));
++
+ return 0;
+ }
+
+@@ -1088,17 +1015,19 @@ static int pispbe_node_g_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot get capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
++
+ *f = node->format;
+ dev_dbg(pispbe->dev, "Get output format for node %s\n",
+ NODE_NAME(node));
++
+ return 0;
+ }
+
+@@ -1106,98 +1035,42 @@ static int pispbe_node_g_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot get capture fmt for meta output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
+- *f = node->format;
+- dev_dbg(pispbe->dev, "Get output format for meta node %s\n",
+- NODE_NAME(node));
+- return 0;
+-}
+
+-static int pispbe_node_g_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+-
+- if (!NODE_IS_META(node) || NODE_IS_OUTPUT(node)) {
+- dev_err(pispbe->dev,
+- "Cannot get capture fmt for meta output node %s\n",
+- NODE_NAME(node));
+- return -EINVAL;
+- }
+ *f = node->format;
+ dev_dbg(pispbe->dev, "Get output format for meta node %s\n",
+ NODE_NAME(node));
+- return 0;
+-}
+-
+-static int verify_be_pix_format(const struct v4l2_format *f,
+- struct pispbe_node *node)
+-{
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- unsigned int nplanes = f->fmt.pix_mp.num_planes;
+- unsigned int i;
+-
+- if (f->fmt.pix_mp.width == 0 || f->fmt.pix_mp.height == 0) {
+- dev_err(pispbe->dev, "Details incorrect for output node %s\n",
+- NODE_NAME(node));
+- return -EINVAL;
+- }
+-
+- if (nplanes == 0 || nplanes > MAX_PLANES) {
+- dev_err(pispbe->dev,
+- "Bad number of planes for output node %s, req =%d\n",
+- NODE_NAME(node), nplanes);
+- return -EINVAL;
+- }
+-
+- for (i = 0; i < nplanes; i++) {
+- const struct v4l2_plane_pix_format *p;
+-
+- p = &f->fmt.pix_mp.plane_fmt[i];
+- if (p->bytesperline == 0 || p->sizeimage == 0) {
+- dev_err(pispbe->dev,
+- "Invalid plane %d for output node %s\n",
+- i, NODE_NAME(node));
+- return -EINVAL;
+- }
+- }
+
+ return 0;
+ }
+
+-static const struct pisp_be_format *find_format(unsigned int fourcc)
++static const struct pisp_be_format *pispbe_find_fmt(unsigned int fourcc)
+ {
+- const struct pisp_be_format *fmt;
+- unsigned int i;
+-
+- for (i = 0; i < ARRAY_SIZE(supported_formats); i++) {
+- fmt = &supported_formats[i];
+- if (fmt->fourcc == fourcc)
+- return fmt;
++ for (unsigned int i = 0; i < ARRAY_SIZE(supported_formats); i++) {
++ if (supported_formats[i].fourcc == fourcc)
++ return &supported_formats[i];
+ }
+
+ return NULL;
+ }
+
+-static void set_plane_params(struct v4l2_format *f,
+- const struct pisp_be_format *fmt)
++static void pispbe_set_plane_params(struct v4l2_format *f,
++ const struct pisp_be_format *fmt)
+ {
+ unsigned int nplanes = f->fmt.pix_mp.num_planes;
+ unsigned int total_plane_factor = 0;
+- unsigned int i;
+
+- for (i = 0; i < MAX_PLANES; i++)
++ for (unsigned int i = 0; i < PISPBE_MAX_PLANES; i++)
+ total_plane_factor += fmt->plane_factor[i];
+
+- for (i = 0; i < nplanes; i++) {
++ for (unsigned int i = 0; i < nplanes; i++) {
+ struct v4l2_plane_pix_format *p = &f->fmt.pix_mp.plane_fmt[i];
+ unsigned int bpl, plane_size;
+
+@@ -1217,28 +1090,25 @@ static void set_plane_params(struct v4l2
+ }
+ }
+
+-static int try_format(struct v4l2_format *f, struct pispbe_node *node)
++static void pispbe_try_format(struct v4l2_format *f, struct pispbe_node *node)
+ {
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
++ u32 pixfmt = f->fmt.pix_mp.pixelformat;
+ const struct pisp_be_format *fmt;
+- unsigned int i;
+ bool is_rgb;
+- u32 pixfmt = f->fmt.pix_mp.pixelformat;
+
+ dev_dbg(pispbe->dev,
+- "%s: [%s] req %ux%u " V4L2_FOURCC_CONV ", planes %d\n",
++ "%s: [%s] req %ux%u %p4cc, planes %d\n",
+ __func__, NODE_NAME(node), f->fmt.pix_mp.width,
+- f->fmt.pix_mp.height, V4L2_FOURCC_CONV_ARGS(pixfmt),
++ f->fmt.pix_mp.height, &pixfmt,
+ f->fmt.pix_mp.num_planes);
+
+- if (pixfmt == V4L2_PIX_FMT_RPI_BE)
+- return verify_be_pix_format(f, node);
+-
+- fmt = find_format(pixfmt);
++ fmt = pispbe_find_fmt(pixfmt);
+ if (!fmt) {
+- dev_dbg(pispbe->dev, "%s: [%s] Format not found, defaulting to YUV420\n",
++ dev_dbg(pispbe->dev,
++ "%s: [%s] Format not found, defaulting to YUV420\n",
+ __func__, NODE_NAME(node));
+- fmt = find_format(V4L2_PIX_FMT_YUV420);
++ fmt = pispbe_find_fmt(V4L2_PIX_FMT_YUV420);
+ }
+
+ f->fmt.pix_mp.pixelformat = fmt->fourcc;
+@@ -1254,7 +1124,8 @@ static int try_format(struct v4l2_format
+ * not supported. This also catches the case when the "default"
+ * colour space was requested (as that's never in the mask).
+ */
+- if (!(V4L2_COLORSPACE_MASK(f->fmt.pix_mp.colorspace) & fmt->colorspace_mask))
++ if (!(V4L2_COLORSPACE_MASK(f->fmt.pix_mp.colorspace) &
++ fmt->colorspace_mask))
+ f->fmt.pix_mp.colorspace = fmt->colorspace_default;
+
+ /* In all cases, we only support the defaults for these: */
+@@ -1269,9 +1140,9 @@ static int try_format(struct v4l2_format
+ f->fmt.pix_mp.ycbcr_enc);
+
+ /* Set plane size and bytes/line for each plane. */
+- set_plane_params(f, fmt);
++ pispbe_set_plane_params(f, fmt);
+
+- for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
++ for (unsigned int i = 0; i < f->fmt.pix_mp.num_planes; i++) {
+ dev_dbg(pispbe->dev,
+ "%s: [%s] calc plane %d, %ux%u, depth %u, bpl %u size %u\n",
+ __func__, NODE_NAME(node), i, f->fmt.pix_mp.width,
+@@ -1279,27 +1150,22 @@ static int try_format(struct v4l2_format
+ f->fmt.pix_mp.plane_fmt[i].bytesperline,
+ f->fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+-
+- return 0;
+ }
+
+ static int pispbe_node_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot set capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
+
+- ret = try_format(f, node);
+- if (ret < 0)
+- return ret;
++ pispbe_try_format(f, node);
+
+ return 0;
+ }
+@@ -1308,19 +1174,16 @@ static int pispbe_node_try_fmt_vid_out(s
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_OUTPUT(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot set capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
+
+- ret = try_format(f, node);
+- if (ret < 0)
+- return ret;
++ pispbe_try_format(f, node);
+
+ return 0;
+ }
+@@ -1329,10 +1192,10 @@ static int pispbe_node_try_fmt_meta_out(
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot set capture fmt for meta output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+@@ -1344,43 +1207,26 @@ static int pispbe_node_try_fmt_meta_out(
+ return 0;
+ }
+
+-static int pispbe_node_try_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+-
+- if (!NODE_IS_META(node) || NODE_IS_OUTPUT(node)) {
+- dev_err(pispbe->dev,
+- "Cannot set capture fmt for meta output node %s\n",
+- NODE_NAME(node));
+- return -EINVAL;
+- }
+-
+- f->fmt.meta.dataformat = V4L2_PIX_FMT_RPI_BE;
+- if (!f->fmt.meta.buffersize)
+- f->fmt.meta.buffersize = BIT(20);
+-
+- return 0;
+-}
+-
+ static int pispbe_node_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_vid_cap(file, priv, f);
++ struct pispbe_dev *pispbe = node->pispbe;
++ int ret;
+
++ ret = pispbe_node_try_fmt_vid_cap(file, priv, f);
+ if (ret < 0)
+ return ret;
+
++ if (vb2_is_busy(&node->queue))
++ return -EBUSY;
++
+ node->format = *f;
+- node->pisp_format = find_format(f->fmt.pix_mp.pixelformat);
++ node->pisp_format = pispbe_find_fmt(f->fmt.pix_mp.pixelformat);
++
++ dev_dbg(pispbe->dev, "Set capture format for node %s to %p4cc\n",
++ NODE_NAME(node), &f->fmt.pix_mp.pixelformat);
+
+- dev_dbg(pispbe->dev,
+- "Set capture format for node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.pix_mp.pixelformat));
+ return 0;
+ }
+
+@@ -1388,19 +1234,22 @@ static int pispbe_node_s_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_vid_out(file, priv, f);
++ struct pispbe_dev *pispbe = node->pispbe;
++ int ret;
+
++ ret = pispbe_node_try_fmt_vid_out(file, priv, f);
+ if (ret < 0)
+ return ret;
+
++ if (vb2_is_busy(&node->queue))
++ return -EBUSY;
++
+ node->format = *f;
+- node->pisp_format = find_format(f->fmt.pix_mp.pixelformat);
++ node->pisp_format = pispbe_find_fmt(f->fmt.pix_mp.pixelformat);
++
++ dev_dbg(pispbe->dev, "Set output format for node %s to %p4cc\n",
++ NODE_NAME(node), &f->fmt.pix_mp.pixelformat);
+
+- dev_dbg(pispbe->dev,
+- "Set output format for node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.pix_mp.pixelformat));
+ return 0;
+ }
+
+@@ -1408,39 +1257,22 @@ static int pispbe_node_s_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_meta_out(file, priv, f);
++ struct pispbe_dev *pispbe = node->pispbe;
++ int ret;
+
++ ret = pispbe_node_try_fmt_meta_out(file, priv, f);
+ if (ret < 0)
+ return ret;
+
++ if (vb2_is_busy(&node->queue))
++ return -EBUSY;
++
+ node->format = *f;
+ node->pisp_format = &meta_out_supported_formats[0];
+
+- dev_dbg(pispbe->dev,
+- "Set output format for meta node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.meta.dataformat));
+- return 0;
+-}
+-
+-static int pispbe_node_s_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_meta_cap(file, priv, f);
+-
+- if (ret < 0)
+- return ret;
+-
+- node->format = *f;
+- node->pisp_format = find_format(f->fmt.meta.dataformat);
++ dev_dbg(pispbe->dev, "Set output format for meta node %s to %p4cc\n",
++ NODE_NAME(node), &f->fmt.meta.dataformat);
+
+- dev_dbg(pispbe->dev,
+- "Set capture format for meta node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.meta.dataformat));
+ return 0;
+ }
+
+@@ -1456,10 +1288,7 @@ static int pispbe_node_enum_fmt(struct f
+ if (f->index)
+ return -EINVAL;
+
+- if (NODE_IS_OUTPUT(node))
+- f->pixelformat = V4L2_META_FMT_RPI_BE_CFG;
+- else
+- f->pixelformat = V4L2_PIX_FMT_RPI_BE;
++ f->pixelformat = V4L2_META_FMT_RPI_BE_CFG;
+ f->flags = 0;
+ return 0;
+ }
+@@ -1477,13 +1306,13 @@ static int pispbe_enum_framesizes(struct
+ struct v4l2_frmsizeenum *fsize)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (NODE_IS_META(node) || fsize->index)
+ return -EINVAL;
+
+- if (!find_format(fsize->pixel_format)) {
+- dev_err(pispbe->dev, "Invalid pixel code: %x\n",
++ if (!pispbe_find_fmt(fsize->pixel_format)) {
++ dev_dbg(pispbe->dev, "Invalid pixel code: %x\n",
+ fsize->pixel_format);
+ return -EINVAL;
+ }
+@@ -1500,49 +1329,19 @@ static int pispbe_enum_framesizes(struct
+ return 0;
+ }
+
+-static int pispbe_node_streamon(struct file *file, void *priv,
+- enum v4l2_buf_type type)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+-
+- /* Do we need a node->stream_lock mutex? */
+-
+- dev_dbg(pispbe->dev, "Stream on for node %s\n", NODE_NAME(node));
+-
+- /* Do we care about the type? Each node has only one queue. */
+-
+- INIT_LIST_HEAD(&node->ready_queue);
+-
+- /* locking should be handled by the queue->lock? */
+- return vb2_streamon(&node->queue, type);
+-}
+-
+-static int pispbe_node_streamoff(struct file *file, void *priv,
+- enum v4l2_buf_type type)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+-
+- return vb2_streamoff(&node->queue, type);
+-}
+-
+ static const struct v4l2_ioctl_ops pispbe_node_ioctl_ops = {
+ .vidioc_querycap = pispbe_node_querycap,
+ .vidioc_g_fmt_vid_cap_mplane = pispbe_node_g_fmt_vid_cap,
+ .vidioc_g_fmt_vid_out_mplane = pispbe_node_g_fmt_vid_out,
+ .vidioc_g_fmt_meta_out = pispbe_node_g_fmt_meta_out,
+- .vidioc_g_fmt_meta_cap = pispbe_node_g_fmt_meta_cap,
+ .vidioc_try_fmt_vid_cap_mplane = pispbe_node_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_out_mplane = pispbe_node_try_fmt_vid_out,
+ .vidioc_try_fmt_meta_out = pispbe_node_try_fmt_meta_out,
+- .vidioc_try_fmt_meta_cap = pispbe_node_try_fmt_meta_cap,
+ .vidioc_s_fmt_vid_cap_mplane = pispbe_node_s_fmt_vid_cap,
+ .vidioc_s_fmt_vid_out_mplane = pispbe_node_s_fmt_vid_out,
+ .vidioc_s_fmt_meta_out = pispbe_node_s_fmt_meta_out,
+- .vidioc_s_fmt_meta_cap = pispbe_node_s_fmt_meta_cap,
+ .vidioc_enum_fmt_vid_cap = pispbe_node_enum_fmt,
+ .vidioc_enum_fmt_vid_out = pispbe_node_enum_fmt,
+- .vidioc_enum_fmt_meta_cap = pispbe_node_enum_fmt,
+ .vidioc_enum_fmt_meta_out = pispbe_node_enum_fmt,
+ .vidioc_enum_framesizes = pispbe_enum_framesizes,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+@@ -1552,8 +1351,8 @@ static const struct v4l2_ioctl_ops pispb
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+- .vidioc_streamon = pispbe_node_streamon,
+- .vidioc_streamoff = pispbe_node_streamoff,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
+ };
+
+ static const struct video_device pispbe_videodev = {
+@@ -1565,7 +1364,7 @@ static const struct video_device pispbe_
+ .release = video_device_release_empty,
+ };
+
+-static void node_set_default_format(struct pispbe_node *node)
++static void pispbe_node_def_fmt(struct pispbe_node *node)
+ {
+ if (NODE_IS_META(node) && NODE_IS_OUTPUT(node)) {
+ /* Config node */
+@@ -1574,44 +1373,35 @@ static void node_set_default_format(stru
+ f->fmt.meta.dataformat = V4L2_META_FMT_RPI_BE_CFG;
+ f->fmt.meta.buffersize = sizeof(struct pisp_be_tiles_config);
+ f->type = node->buf_type;
+- } else if (NODE_IS_META(node) && NODE_IS_CAPTURE(node)) {
+- /* HOG output node */
+- struct v4l2_format *f = &node->format;
+-
+- f->fmt.meta.dataformat = V4L2_PIX_FMT_RPI_BE;
+- f->fmt.meta.buffersize = BIT(20);
+- f->type = node->buf_type;
+ } else {
+- struct v4l2_format f = {0};
+-
+- f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420;
+- f.fmt.pix_mp.width = 1920;
+- f.fmt.pix_mp.height = 1080;
+- f.type = node->buf_type;
+- try_format(&f, node);
++ struct v4l2_format f = {
++ .fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420,
++ .fmt.pix_mp.width = 1920,
++ .fmt.pix_mp.height = 1080,
++ .type = node->buf_type,
++ };
++ pispbe_try_format(&f, node);
+ node->format = f;
+ }
+
+- node->pisp_format = find_format(node->format.fmt.pix_mp.pixelformat);
++ node->pisp_format = pispbe_find_fmt(node->format.fmt.pix_mp.pixelformat);
+ }
+
+ /*
+ * Initialise a struct pispbe_node and register it as /dev/video<N>
+ * to represent one of the PiSP Back End's input or output streams.
+ */
+-static int
+-pispbe_init_node(struct pispbe_node_group *node_group, unsigned int id)
++static int pispbe_init_node(struct pispbe_dev *pispbe, unsigned int id)
+ {
+ bool output = NODE_DESC_IS_OUTPUT(&node_desc[id]);
+- struct pispbe_node *node = &node_group->node[id];
+- struct pispbe_dev *pispbe = node_group->pispbe;
++ struct pispbe_node *node = &pispbe->node[id];
+ struct media_entity *entity = &node->vfd.entity;
+ struct video_device *vdev = &node->vfd;
+ struct vb2_queue *q = &node->queue;
+ int ret;
+
+ node->id = id;
+- node->node_group = node_group;
++ node->pispbe = pispbe;
+ node->buf_type = node_desc[id].buf_type;
+
+ mutex_init(&node->node_lock);
+@@ -1620,7 +1410,7 @@ pispbe_init_node(struct pispbe_node_grou
+ spin_lock_init(&node->ready_lock);
+
+ node->format.type = node->buf_type;
+- node_set_default_format(node);
++ pispbe_node_def_fmt(node);
+
+ q->type = node->buf_type;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+@@ -1629,19 +1419,19 @@ pispbe_init_node(struct pispbe_node_grou
+ q->ops = &pispbe_node_queue_ops;
+ q->buf_struct_size = sizeof(struct pispbe_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+- q->dev = node->node_group->pispbe->dev;
++ q->dev = pispbe->dev;
+ /* get V4L2 to handle node->queue locking */
+ q->lock = &node->queue_lock;
+
+ ret = vb2_queue_init(q);
+ if (ret < 0) {
+ dev_err(pispbe->dev, "vb2_queue_init failed\n");
+- return ret;
++ goto err_mutex_destroy;
+ }
+
+ *vdev = pispbe_videodev; /* default initialization */
+ strscpy(vdev->name, node_desc[id].ent_name, sizeof(vdev->name));
+- vdev->v4l2_dev = &node_group->v4l2_dev;
++ vdev->v4l2_dev = &pispbe->v4l2_dev;
+ vdev->vfl_dir = output ? VFL_DIR_TX : VFL_DIR_RX;
+ /* get V4L2 to serialise our ioctls */
+ vdev->lock = &node->node_lock;
+@@ -1657,8 +1447,7 @@ pispbe_init_node(struct pispbe_node_grou
+ goto err_unregister_queue;
+ }
+
+- ret = video_register_device(vdev, VFL_TYPE_VIDEO,
+- PISPBE_VIDEO_NODE_OFFSET);
++ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(pispbe->dev,
+ "Failed to register video %s device node\n",
+@@ -1668,25 +1457,28 @@ pispbe_init_node(struct pispbe_node_grou
+ video_set_drvdata(vdev, node);
+
+ if (output)
+- ret = media_create_pad_link(entity, 0, &node_group->sd.entity,
++ ret = media_create_pad_link(entity, 0, &pispbe->sd.entity,
+ id, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ else
+- ret = media_create_pad_link(&node_group->sd.entity, id, entity,
++ ret = media_create_pad_link(&pispbe->sd.entity, id, entity,
+ 0, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ goto err_unregister_video_dev;
+
+- dev_info(pispbe->dev,
+- "%s device node registered as /dev/video%d\n",
+- NODE_NAME(node), node->vfd.num);
++ dev_dbg(pispbe->dev, "%s device node registered as /dev/video%d\n",
++ NODE_NAME(node), node->vfd.num);
++
+ return 0;
+
+ err_unregister_video_dev:
+ video_unregister_device(&node->vfd);
+ err_unregister_queue:
+ vb2_queue_release(&node->queue);
++err_mutex_destroy:
++ mutex_destroy(&node->node_lock);
++ mutex_destroy(&node->queue_lock);
+ return ret;
+ }
+
+@@ -1698,11 +1490,9 @@ static const struct v4l2_subdev_ops pisp
+ .pad = &pispbe_pad_ops,
+ };
+
+-static int pispbe_init_subdev(struct pispbe_node_group *node_group)
++static int pispbe_init_subdev(struct pispbe_dev *pispbe)
+ {
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- struct v4l2_subdev *sd = &node_group->sd;
+- unsigned int i;
++ struct v4l2_subdev *sd = &pispbe->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &pispbe_sd_ops);
+@@ -1711,17 +1501,17 @@ static int pispbe_init_subdev(struct pis
+ sd->dev = pispbe->dev;
+ strscpy(sd->name, PISPBE_NAME, sizeof(sd->name));
+
+- for (i = 0; i < PISPBE_NUM_NODES; i++)
+- node_group->pad[i].flags =
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++)
++ pispbe->pad[i].flags =
+ NODE_DESC_IS_OUTPUT(&node_desc[i]) ?
+ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&sd->entity, PISPBE_NUM_NODES,
+- node_group->pad);
++ pispbe->pad);
+ if (ret)
+ goto error;
+
+- ret = v4l2_device_register_subdev(&node_group->v4l2_dev, sd);
++ ret = v4l2_device_register_subdev(&pispbe->v4l2_dev, sd);
+ if (ret)
+ goto error;
+
+@@ -1732,45 +1522,36 @@ error:
+ return ret;
+ }
+
+-static int pispbe_init_group(struct pispbe_dev *pispbe, unsigned int id)
++static int pispbe_init_devices(struct pispbe_dev *pispbe)
+ {
+- struct pispbe_node_group *node_group = &pispbe->node_group[id];
+ struct v4l2_device *v4l2_dev;
+ struct media_device *mdev;
+- unsigned int num_registered = 0;
++ unsigned int num_regist;
+ int ret;
+
+- node_group->id = id;
+- node_group->pispbe = pispbe;
+- node_group->streaming_map = 0;
+-
+- dev_info(pispbe->dev, "Register nodes for group %u\n", id);
+-
+ /* Register v4l2_device and media_device */
+- mdev = &node_group->mdev;
+- mdev->hw_revision = node_group->pispbe->hw_version;
+- mdev->dev = node_group->pispbe->dev;
++ mdev = &pispbe->mdev;
++ mdev->hw_revision = pispbe->hw_version;
++ mdev->dev = pispbe->dev;
+ strscpy(mdev->model, PISPBE_NAME, sizeof(mdev->model));
+- snprintf(mdev->bus_info, sizeof(mdev->bus_info),
+- "platform:%s", dev_name(node_group->pispbe->dev));
+ media_device_init(mdev);
+
+- v4l2_dev = &node_group->v4l2_dev;
+- v4l2_dev->mdev = &node_group->mdev;
++ v4l2_dev = &pispbe->v4l2_dev;
++ v4l2_dev->mdev = &pispbe->mdev;
+ strscpy(v4l2_dev->name, PISPBE_NAME, sizeof(v4l2_dev->name));
+
+- ret = v4l2_device_register(pispbe->dev, &node_group->v4l2_dev);
++ ret = v4l2_device_register(pispbe->dev, v4l2_dev);
+ if (ret)
+ goto err_media_dev_cleanup;
+
+ /* Register the PISPBE subdevice. */
+- ret = pispbe_init_subdev(node_group);
++ ret = pispbe_init_subdev(pispbe);
+ if (ret)
+ goto err_unregister_v4l2;
+
+ /* Create device video nodes */
+- for (; num_registered < PISPBE_NUM_NODES; num_registered++) {
+- ret = pispbe_init_node(node_group, num_registered);
++ for (num_regist = 0; num_regist < PISPBE_NUM_NODES; num_regist++) {
++ ret = pispbe_init_node(pispbe, num_regist);
+ if (ret)
+ goto err_unregister_nodes;
+ }
+@@ -1779,12 +1560,12 @@ static int pispbe_init_group(struct pisp
+ if (ret)
+ goto err_unregister_nodes;
+
+- node_group->config =
++ pispbe->config =
+ dma_alloc_coherent(pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- &node_group->config_dma_addr, GFP_KERNEL);
+- if (!node_group->config) {
++ &pispbe->config_dma_addr, GFP_KERNEL);
++ if (!pispbe->config) {
+ dev_err(pispbe->dev, "Unable to allocate cached config buffers.\n");
+ ret = -ENOMEM;
+ goto err_unregister_mdev;
+@@ -1795,12 +1576,12 @@ static int pispbe_init_group(struct pisp
+ err_unregister_mdev:
+ media_device_unregister(mdev);
+ err_unregister_nodes:
+- while (num_registered-- > 0) {
+- video_unregister_device(&node_group->node[num_registered].vfd);
+- vb2_queue_release(&node_group->node[num_registered].queue);
++ while (num_regist-- > 0) {
++ video_unregister_device(&pispbe->node[num_regist].vfd);
++ vb2_queue_release(&pispbe->node[num_regist].queue);
+ }
+- v4l2_device_unregister_subdev(&node_group->sd);
+- media_entity_cleanup(&node_group->sd.entity);
++ v4l2_device_unregister_subdev(&pispbe->sd);
++ media_entity_cleanup(&pispbe->sd.entity);
+ err_unregister_v4l2:
+ v4l2_device_unregister(v4l2_dev);
+ err_media_dev_cleanup:
+@@ -1808,32 +1589,31 @@ err_media_dev_cleanup:
+ return ret;
+ }
+
+-static void pispbe_destroy_node_group(struct pispbe_node_group *node_group)
++static void pispbe_destroy_devices(struct pispbe_dev *pispbe)
+ {
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- int i;
+-
+- if (node_group->config) {
+- dma_free_coherent(node_group->pispbe->dev,
++ if (pispbe->config) {
++ dma_free_coherent(pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- node_group->config,
+- node_group->config_dma_addr);
++ pispbe->config,
++ pispbe->config_dma_addr);
+ }
+
+- dev_info(pispbe->dev, "Unregister from media controller\n");
++ dev_dbg(pispbe->dev, "Unregister from media controller\n");
+
+- v4l2_device_unregister_subdev(&node_group->sd);
+- media_entity_cleanup(&node_group->sd.entity);
+- media_device_unregister(&node_group->mdev);
++ v4l2_device_unregister_subdev(&pispbe->sd);
++ media_entity_cleanup(&pispbe->sd.entity);
++ media_device_unregister(&pispbe->mdev);
+
+- for (i = PISPBE_NUM_NODES - 1; i >= 0; i--) {
+- video_unregister_device(&node_group->node[i].vfd);
+- vb2_queue_release(&node_group->node[i].queue);
++ for (int i = PISPBE_NUM_NODES - 1; i >= 0; i--) {
++ video_unregister_device(&pispbe->node[i].vfd);
++ vb2_queue_release(&pispbe->node[i].queue);
++ mutex_destroy(&pispbe->node[i].node_lock);
++ mutex_destroy(&pispbe->node[i].queue_lock);
+ }
+
+- media_device_cleanup(&node_group->mdev);
+- v4l2_device_unregister(&node_group->v4l2_dev);
++ media_device_cleanup(&pispbe->mdev);
++ v4l2_device_unregister(&pispbe->v4l2_dev);
+ }
+
+ static int pispbe_runtime_suspend(struct device *dev)
+@@ -1862,13 +1642,48 @@ static int pispbe_runtime_resume(struct
+ return 0;
+ }
+
+-/*
+- * Probe the ISP-BE hardware block, as a single platform device.
+- * This will instantiate multiple "node groups" each with many device nodes.
+- */
++static int pispbe_hw_init(struct pispbe_dev *pispbe)
++{
++ u32 u;
++
++ /* Check the HW is present and has a known version */
++ u = pispbe_rd(pispbe, PISP_BE_VERSION_REG);
++ dev_dbg(pispbe->dev, "pispbe_probe: HW version: 0x%08x", u);
++ pispbe->hw_version = u;
++ if ((u & ~PISP_BE_VERSION_MINOR_BITS) != PISP_BE_VERSION_2712)
++ return -ENODEV;
++
++ /* Clear leftover interrupts */
++ pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, 0xFFFFFFFFu);
++ u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG);
++ dev_dbg(pispbe->dev, "pispbe_probe: BatchStatus: 0x%08x", u);
++
++ pispbe->done = (uint8_t)u;
++ pispbe->started = (uint8_t)(u >> 8);
++ u = pispbe_rd(pispbe, PISP_BE_STATUS_REG);
++ dev_dbg(pispbe->dev, "pispbe_probe: Status: 0x%08x", u);
++
++ if (u != 0 || pispbe->done != pispbe->started) {
++ dev_err(pispbe->dev, "pispbe_probe: HW is stuck or busy\n");
++ return -EBUSY;
++ }
++
++ /*
++ * AXI QOS=0, CACHE=4'b0010, PROT=3'b011
++ * Also set "chicken bits" 22:20 which enable sub-64-byte bursts
++ * and AXI AWID/BID variability (on versions which support this).
++ */
++ pispbe_wr(pispbe, PISP_BE_AXI_REG, 0x32703200u);
++
++ /* Enable both interrupt flags */
++ pispbe_wr(pispbe, PISP_BE_INTERRUPT_EN_REG, 0x00000003u);
++
++ return 0;
++}
++
++/* Probe the ISP-BE hardware block, as a single platform device. */
+ static int pispbe_probe(struct platform_device *pdev)
+ {
+- unsigned int num_groups = 0;
+ struct pispbe_dev *pispbe;
+ int ret;
+
+@@ -1913,55 +1728,43 @@ static int pispbe_probe(struct platform_
+ pm_runtime_use_autosuspend(pispbe->dev);
+ pm_runtime_enable(pispbe->dev);
+
+- ret = pm_runtime_resume_and_get(pispbe->dev);
++ ret = pispbe_runtime_resume(pispbe->dev);
+ if (ret)
+ goto pm_runtime_disable_err;
+
+- pispbe->hw_busy = 0;
++ pispbe->hw_busy = false;
+ spin_lock_init(&pispbe->hw_lock);
+- ret = hw_init(pispbe);
++ ret = pispbe_hw_init(pispbe);
+ if (ret)
+- goto pm_runtime_put_err;
++ goto pm_runtime_suspend_err;
+
+- /*
+- * Initialise and register devices for each node_group, including media
+- * device
+- */
+- for (num_groups = 0;
+- num_groups < PISPBE_NUM_NODE_GROUPS;
+- num_groups++) {
+- ret = pispbe_init_group(pispbe, num_groups);
+- if (ret)
+- goto disable_nodes_err;
+- }
++ ret = pispbe_init_devices(pispbe);
++ if (ret)
++ goto disable_devs_err;
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+ return 0;
+
+-disable_nodes_err:
+- while (num_groups-- > 0)
+- pispbe_destroy_node_group(&pispbe->node_group[num_groups]);
+-pm_runtime_put_err:
+- pm_runtime_put(pispbe->dev);
++disable_devs_err:
++ pispbe_destroy_devices(pispbe);
++pm_runtime_suspend_err:
++ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_disable_err:
+ pm_runtime_dont_use_autosuspend(pispbe->dev);
+ pm_runtime_disable(pispbe->dev);
+
+- dev_err(&pdev->dev, "%s: returning %d", __func__, ret);
+-
+ return ret;
+ }
+
+ static int pispbe_remove(struct platform_device *pdev)
+ {
+ struct pispbe_dev *pispbe = platform_get_drvdata(pdev);
+- int i;
+
+- for (i = PISPBE_NUM_NODE_GROUPS - 1; i >= 0; i--)
+- pispbe_destroy_node_group(&pispbe->node_group[i]);
++ pispbe_destroy_devices(pispbe);
+
++ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_dont_use_autosuspend(pispbe->dev);
+ pm_runtime_disable(pispbe->dev);
+
+@@ -1991,3 +1794,8 @@ static struct platform_driver pispbe_pdr
+ };
+
+ module_platform_driver(pispbe_pdrv);
++
++MODULE_DESCRIPTION("PiSP Back End driver");
++MODULE_AUTHOR("David Plowman <david.plowman@raspberrypi.com>");
++MODULE_AUTHOR("Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>");
++MODULE_LICENSE("GPL");
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be_config.h
++++ /dev/null
+@@ -1,533 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+-/*
+- * PiSP Back End configuration definitions.
+- *
+- * Copyright (C) 2021 - Raspberry Pi Ltd
+- *
+- */
+-#ifndef _PISP_BE_CONFIG_H_
+-#define _PISP_BE_CONFIG_H_
+-
+-#include <linux/types.h>
+-
+-#include <media/raspberrypi/pisp_common.h>
+-
+-/* byte alignment for inputs */
+-#define PISP_BACK_END_INPUT_ALIGN 4u
+-/* alignment for compressed inputs */
+-#define PISP_BACK_END_COMPRESSED_ALIGN 8u
+-/* minimum required byte alignment for outputs */
+-#define PISP_BACK_END_OUTPUT_MIN_ALIGN 16u
+-/* preferred byte alignment for outputs */
+-#define PISP_BACK_END_OUTPUT_MAX_ALIGN 64u
+-
+-/* minimum allowed tile width anywhere in the pipeline */
+-#define PISP_BACK_END_MIN_TILE_WIDTH 16u
+-/* minimum allowed tile width anywhere in the pipeline */
+-#define PISP_BACK_END_MIN_TILE_HEIGHT 16u
+-
+-#define PISP_BACK_END_NUM_OUTPUTS 2
+-#define PISP_BACK_END_HOG_OUTPUT 1
+-
+-#define PISP_BACK_END_NUM_TILES 64
+-
+-enum pisp_be_bayer_enable {
+- PISP_BE_BAYER_ENABLE_INPUT = 0x000001,
+- PISP_BE_BAYER_ENABLE_DECOMPRESS = 0x000002,
+- PISP_BE_BAYER_ENABLE_DPC = 0x000004,
+- PISP_BE_BAYER_ENABLE_GEQ = 0x000008,
+- PISP_BE_BAYER_ENABLE_TDN_INPUT = 0x000010,
+- PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS = 0x000020,
+- PISP_BE_BAYER_ENABLE_TDN = 0x000040,
+- PISP_BE_BAYER_ENABLE_TDN_COMPRESS = 0x000080,
+- PISP_BE_BAYER_ENABLE_TDN_OUTPUT = 0x000100,
+- PISP_BE_BAYER_ENABLE_SDN = 0x000200,
+- PISP_BE_BAYER_ENABLE_BLC = 0x000400,
+- PISP_BE_BAYER_ENABLE_STITCH_INPUT = 0x000800,
+- PISP_BE_BAYER_ENABLE_STITCH_DECOMPRESS = 0x001000,
+- PISP_BE_BAYER_ENABLE_STITCH = 0x002000,
+- PISP_BE_BAYER_ENABLE_STITCH_COMPRESS = 0x004000,
+- PISP_BE_BAYER_ENABLE_STITCH_OUTPUT = 0x008000,
+- PISP_BE_BAYER_ENABLE_WBG = 0x010000,
+- PISP_BE_BAYER_ENABLE_CDN = 0x020000,
+- PISP_BE_BAYER_ENABLE_LSC = 0x040000,
+- PISP_BE_BAYER_ENABLE_TONEMAP = 0x080000,
+- PISP_BE_BAYER_ENABLE_CAC = 0x100000,
+- PISP_BE_BAYER_ENABLE_DEBIN = 0x200000,
+- PISP_BE_BAYER_ENABLE_DEMOSAIC = 0x400000,
+-};
+-
+-enum pisp_be_rgb_enable {
+- PISP_BE_RGB_ENABLE_INPUT = 0x000001,
+- PISP_BE_RGB_ENABLE_CCM = 0x000002,
+- PISP_BE_RGB_ENABLE_SAT_CONTROL = 0x000004,
+- PISP_BE_RGB_ENABLE_YCBCR = 0x000008,
+- PISP_BE_RGB_ENABLE_FALSE_COLOUR = 0x000010,
+- PISP_BE_RGB_ENABLE_SHARPEN = 0x000020,
+- /* Preferred colours would occupy 0x000040 */
+- PISP_BE_RGB_ENABLE_YCBCR_INVERSE = 0x000080,
+- PISP_BE_RGB_ENABLE_GAMMA = 0x000100,
+- PISP_BE_RGB_ENABLE_CSC0 = 0x000200,
+- PISP_BE_RGB_ENABLE_CSC1 = 0x000400,
+- PISP_BE_RGB_ENABLE_DOWNSCALE0 = 0x001000,
+- PISP_BE_RGB_ENABLE_DOWNSCALE1 = 0x002000,
+- PISP_BE_RGB_ENABLE_RESAMPLE0 = 0x008000,
+- PISP_BE_RGB_ENABLE_RESAMPLE1 = 0x010000,
+- PISP_BE_RGB_ENABLE_OUTPUT0 = 0x040000,
+- PISP_BE_RGB_ENABLE_OUTPUT1 = 0x080000,
+- PISP_BE_RGB_ENABLE_HOG = 0x200000
+-};
+-
+-#define PISP_BE_RGB_ENABLE_CSC(i) (PISP_BE_RGB_ENABLE_CSC0 << (i))
+-#define PISP_BE_RGB_ENABLE_DOWNSCALE(i) (PISP_BE_RGB_ENABLE_DOWNSCALE0 << (i))
+-#define PISP_BE_RGB_ENABLE_RESAMPLE(i) (PISP_BE_RGB_ENABLE_RESAMPLE0 << (i))
+-#define PISP_BE_RGB_ENABLE_OUTPUT(i) (PISP_BE_RGB_ENABLE_OUTPUT0 << (i))
+-
+-/*
+- * We use the enable flags to show when blocks are "dirty", but we need some
+- * extra ones too.
+- */
+-enum pisp_be_dirty {
+- PISP_BE_DIRTY_GLOBAL = 0x0001,
+- PISP_BE_DIRTY_SH_FC_COMBINE = 0x0002,
+- PISP_BE_DIRTY_CROP = 0x0004
+-};
+-
+-struct pisp_be_global_config {
+- u32 bayer_enables;
+- u32 rgb_enables;
+- u8 bayer_order;
+- u8 pad[3];
+-};
+-
+-struct pisp_be_input_buffer_config {
+- /* low 32 bits followed by high 32 bits (for each of up to 3 planes) */
+- u32 addr[3][2];
+-};
+-
+-struct pisp_be_dpc_config {
+- u8 coeff_level;
+- u8 coeff_range;
+- u8 pad;
+-#define PISP_BE_DPC_FLAG_FOLDBACK 1
+- u8 flags;
+-};
+-
+-struct pisp_be_geq_config {
+- u16 offset;
+-#define PISP_BE_GEQ_SHARPER BIT(15)
+-#define PISP_BE_GEQ_SLOPE ((1 << 10) - 1)
+- /* top bit is the "sharper" flag, slope value is bottom 10 bits */
+- u16 slope_sharper;
+- u16 min;
+- u16 max;
+-};
+-
+-struct pisp_be_tdn_input_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_tdn_config {
+- u16 black_level;
+- u16 ratio;
+- u16 noise_constant;
+- u16 noise_slope;
+- u16 threshold;
+- u8 reset;
+- u8 pad;
+-};
+-
+-struct pisp_be_tdn_output_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_sdn_config {
+- u16 black_level;
+- u8 leakage;
+- u8 pad;
+- u16 noise_constant;
+- u16 noise_slope;
+- u16 noise_constant2;
+- u16 noise_slope2;
+-};
+-
+-struct pisp_be_stitch_input_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-#define PISP_BE_STITCH_STREAMING_LONG 0x8000
+-#define PISP_BE_STITCH_EXPOSURE_RATIO_MASK 0x7fff
+-
+-struct pisp_be_stitch_config {
+- u16 threshold_lo;
+- u8 threshold_diff_power;
+- u8 pad;
+-
+- /* top bit indicates whether streaming input is the long exposure */
+- u16 exposure_ratio;
+-
+- u8 motion_threshold_256;
+- u8 motion_threshold_recip;
+-};
+-
+-struct pisp_be_stitch_output_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_cdn_config {
+- u16 thresh;
+- u8 iir_strength;
+- u8 g_adjust;
+-};
+-
+-#define PISP_BE_LSC_LOG_GRID_SIZE 5
+-#define PISP_BE_LSC_GRID_SIZE (1 << PISP_BE_LSC_LOG_GRID_SIZE)
+-#define PISP_BE_LSC_STEP_PRECISION 18
+-
+-struct pisp_be_lsc_config {
+- /* (1<<18) / grid_cell_width */
+- u16 grid_step_x;
+- /* (1<<18) / grid_cell_height */
+- u16 grid_step_y;
+- /* RGB gains jointly encoded in 32 bits */
+- u32 lut_packed[PISP_BE_LSC_GRID_SIZE + 1]
+- [PISP_BE_LSC_GRID_SIZE + 1];
+-};
+-
+-struct pisp_be_lsc_extra {
+- u16 offset_x;
+- u16 offset_y;
+-};
+-
+-#define PISP_BE_CAC_LOG_GRID_SIZE 3
+-#define PISP_BE_CAC_GRID_SIZE (1 << PISP_BE_CAC_LOG_GRID_SIZE)
+-#define PISP_BE_CAC_STEP_PRECISION 20
+-
+-struct pisp_be_cac_config {
+- /* (1<<20) / grid_cell_width */
+- u16 grid_step_x;
+- /* (1<<20) / grid_cell_height */
+- u16 grid_step_y;
+- /* [gridy][gridx][rb][xy] */
+- s8 lut[PISP_BE_CAC_GRID_SIZE + 1][PISP_BE_CAC_GRID_SIZE + 1][2][2];
+-};
+-
+-struct pisp_be_cac_extra {
+- u16 offset_x;
+- u16 offset_y;
+-};
+-
+-#define PISP_BE_DEBIN_NUM_COEFFS 4
+-
+-struct pisp_be_debin_config {
+- s8 coeffs[PISP_BE_DEBIN_NUM_COEFFS];
+- s8 h_enable;
+- s8 v_enable;
+- s8 pad[2];
+-};
+-
+-#define PISP_BE_TONEMAP_LUT_SIZE 64
+-
+-struct pisp_be_tonemap_config {
+- u16 detail_constant;
+- u16 detail_slope;
+- u16 iir_strength;
+- u16 strength;
+- u32 lut[PISP_BE_TONEMAP_LUT_SIZE];
+-};
+-
+-struct pisp_be_demosaic_config {
+- u8 sharper;
+- u8 fc_mode;
+- u8 pad[2];
+-};
+-
+-struct pisp_be_ccm_config {
+- s16 coeffs[9];
+- u8 pad[2];
+- s32 offsets[3];
+-};
+-
+-struct pisp_be_sat_control_config {
+- u8 shift_r;
+- u8 shift_g;
+- u8 shift_b;
+- u8 pad;
+-};
+-
+-struct pisp_be_false_colour_config {
+- u8 distance;
+- u8 pad[3];
+-};
+-
+-#define PISP_BE_SHARPEN_SIZE 5
+-#define PISP_BE_SHARPEN_FUNC_NUM_POINTS 9
+-
+-struct pisp_be_sharpen_config {
+- s8 kernel0[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad0[3];
+- s8 kernel1[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad1[3];
+- s8 kernel2[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad2[3];
+- s8 kernel3[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad3[3];
+- s8 kernel4[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad4[3];
+- u16 threshold_offset0;
+- u16 threshold_slope0;
+- u16 scale0;
+- u16 pad5;
+- u16 threshold_offset1;
+- u16 threshold_slope1;
+- u16 scale1;
+- u16 pad6;
+- u16 threshold_offset2;
+- u16 threshold_slope2;
+- u16 scale2;
+- u16 pad7;
+- u16 threshold_offset3;
+- u16 threshold_slope3;
+- u16 scale3;
+- u16 pad8;
+- u16 threshold_offset4;
+- u16 threshold_slope4;
+- u16 scale4;
+- u16 pad9;
+- u16 positive_strength;
+- u16 positive_pre_limit;
+- u16 positive_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
+- u16 positive_limit;
+- u16 negative_strength;
+- u16 negative_pre_limit;
+- u16 negative_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
+- u16 negative_limit;
+- u8 enables;
+- u8 white;
+- u8 black;
+- u8 grey;
+-};
+-
+-struct pisp_be_sh_fc_combine_config {
+- u8 y_factor;
+- u8 c1_factor;
+- u8 c2_factor;
+- u8 pad;
+-};
+-
+-#define PISP_BE_GAMMA_LUT_SIZE 64
+-
+-struct pisp_be_gamma_config {
+- u32 lut[PISP_BE_GAMMA_LUT_SIZE];
+-};
+-
+-struct pisp_be_crop_config {
+- u16 offset_x, offset_y;
+- u16 width, height;
+-};
+-
+-#define PISP_BE_RESAMPLE_FILTER_SIZE 96
+-
+-struct pisp_be_resample_config {
+- u16 scale_factor_h, scale_factor_v;
+- s16 coef[PISP_BE_RESAMPLE_FILTER_SIZE];
+-};
+-
+-struct pisp_be_resample_extra {
+- u16 scaled_width;
+- u16 scaled_height;
+- s16 initial_phase_h[3];
+- s16 initial_phase_v[3];
+-};
+-
+-struct pisp_be_downscale_config {
+- u16 scale_factor_h;
+- u16 scale_factor_v;
+- u16 scale_recip_h;
+- u16 scale_recip_v;
+-};
+-
+-struct pisp_be_downscale_extra {
+- u16 scaled_width;
+- u16 scaled_height;
+-};
+-
+-struct pisp_be_hog_config {
+- u8 compute_signed;
+- u8 channel_mix[3];
+- u32 stride;
+-};
+-
+-struct pisp_be_axi_config {
+- u8 r_qos; /* Read QoS */
+- u8 r_cache_prot; /* Read { prot[2:0], cache[3:0] } */
+- u8 w_qos; /* Write QoS */
+- u8 w_cache_prot; /* Write { prot[2:0], cache[3:0] } */
+-};
+-
+-enum pisp_be_transform {
+- PISP_BE_TRANSFORM_NONE = 0x0,
+- PISP_BE_TRANSFORM_HFLIP = 0x1,
+- PISP_BE_TRANSFORM_VFLIP = 0x2,
+- PISP_BE_TRANSFORM_ROT180 =
+- (PISP_BE_TRANSFORM_HFLIP | PISP_BE_TRANSFORM_VFLIP)
+-};
+-
+-struct pisp_be_output_format_config {
+- struct pisp_image_format_config image;
+- u8 transform;
+- u8 pad[3];
+- u16 lo;
+- u16 hi;
+- u16 lo2;
+- u16 hi2;
+-};
+-
+-struct pisp_be_output_buffer_config {
+- /* low 32 bits followed by high 32 bits (for each of 3 planes) */
+- u32 addr[3][2];
+-};
+-
+-struct pisp_be_hog_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_config {
+- /* I/O configuration: */
+- struct pisp_be_input_buffer_config input_buffer;
+- struct pisp_be_tdn_input_buffer_config tdn_input_buffer;
+- struct pisp_be_stitch_input_buffer_config stitch_input_buffer;
+- struct pisp_be_tdn_output_buffer_config tdn_output_buffer;
+- struct pisp_be_stitch_output_buffer_config stitch_output_buffer;
+- struct pisp_be_output_buffer_config
+- output_buffer[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_hog_buffer_config hog_buffer;
+- /* Processing configuration: */
+- struct pisp_be_global_config global;
+- struct pisp_image_format_config input_format;
+- struct pisp_decompress_config decompress;
+- struct pisp_be_dpc_config dpc;
+- struct pisp_be_geq_config geq;
+- struct pisp_image_format_config tdn_input_format;
+- struct pisp_decompress_config tdn_decompress;
+- struct pisp_be_tdn_config tdn;
+- struct pisp_compress_config tdn_compress;
+- struct pisp_image_format_config tdn_output_format;
+- struct pisp_be_sdn_config sdn;
+- struct pisp_bla_config blc;
+- struct pisp_compress_config stitch_compress;
+- struct pisp_image_format_config stitch_output_format;
+- struct pisp_image_format_config stitch_input_format;
+- struct pisp_decompress_config stitch_decompress;
+- struct pisp_be_stitch_config stitch;
+- struct pisp_be_lsc_config lsc;
+- struct pisp_wbg_config wbg;
+- struct pisp_be_cdn_config cdn;
+- struct pisp_be_cac_config cac;
+- struct pisp_be_debin_config debin;
+- struct pisp_be_tonemap_config tonemap;
+- struct pisp_be_demosaic_config demosaic;
+- struct pisp_be_ccm_config ccm;
+- struct pisp_be_sat_control_config sat_control;
+- struct pisp_be_ccm_config ycbcr;
+- struct pisp_be_sharpen_config sharpen;
+- struct pisp_be_false_colour_config false_colour;
+- struct pisp_be_sh_fc_combine_config sh_fc_combine;
+- struct pisp_be_ccm_config ycbcr_inverse;
+- struct pisp_be_gamma_config gamma;
+- struct pisp_be_ccm_config csc[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_downscale_config downscale[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_resample_config resample[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_output_format_config
+- output_format[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_hog_config hog;
+- struct pisp_be_axi_config axi;
+- /* Non-register fields: */
+- struct pisp_be_lsc_extra lsc_extra;
+- struct pisp_be_cac_extra cac_extra;
+- struct pisp_be_downscale_extra
+- downscale_extra[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_resample_extra resample_extra[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_crop_config crop;
+- struct pisp_image_format_config hog_format;
+- u32 dirty_flags_bayer; /* these use pisp_be_bayer_enable */
+- u32 dirty_flags_rgb; /* use pisp_be_rgb_enable */
+- u32 dirty_flags_extra; /* these use pisp_be_dirty_t */
+-};
+-
+-/*
+- * We also need a tile structure to describe the size of the tiles going
+- * through the pipeline.
+- */
+-
+-enum pisp_tile_edge {
+- PISP_LEFT_EDGE = (1 << 0),
+- PISP_RIGHT_EDGE = (1 << 1),
+- PISP_TOP_EDGE = (1 << 2),
+- PISP_BOTTOM_EDGE = (1 << 3)
+-};
+-
+-struct pisp_tile {
+- u8 edge; // enum pisp_tile_edge
+- u8 pad0[3];
+- // 4 bytes
+- u32 input_addr_offset;
+- u32 input_addr_offset2;
+- u16 input_offset_x;
+- u16 input_offset_y;
+- u16 input_width;
+- u16 input_height;
+- // 20 bytes
+- u32 tdn_input_addr_offset;
+- u32 tdn_output_addr_offset;
+- u32 stitch_input_addr_offset;
+- u32 stitch_output_addr_offset;
+- // 36 bytes
+- u32 lsc_grid_offset_x;
+- u32 lsc_grid_offset_y;
+- // 44 bytes
+- u32 cac_grid_offset_x;
+- u32 cac_grid_offset_y;
+- // 52 bytes
+- u16 crop_x_start[PISP_BACK_END_NUM_OUTPUTS];
+- u16 crop_x_end[PISP_BACK_END_NUM_OUTPUTS];
+- u16 crop_y_start[PISP_BACK_END_NUM_OUTPUTS];
+- u16 crop_y_end[PISP_BACK_END_NUM_OUTPUTS];
+- // 68 bytes
+- /* Ordering is planes then branches */
+- u16 downscale_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
+- u16 downscale_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
+- // 92 bytes
+- u16 resample_in_width[PISP_BACK_END_NUM_OUTPUTS];
+- u16 resample_in_height[PISP_BACK_END_NUM_OUTPUTS];
+- // 100 bytes
+- /* Ordering is planes then branches */
+- u16 resample_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
+- u16 resample_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
+- // 124 bytes
+- u16 output_offset_x[PISP_BACK_END_NUM_OUTPUTS];
+- u16 output_offset_y[PISP_BACK_END_NUM_OUTPUTS];
+- u16 output_width[PISP_BACK_END_NUM_OUTPUTS];
+- u16 output_height[PISP_BACK_END_NUM_OUTPUTS];
+- // 140 bytes
+- u32 output_addr_offset[PISP_BACK_END_NUM_OUTPUTS];
+- u32 output_addr_offset2[PISP_BACK_END_NUM_OUTPUTS];
+- // 156 bytes
+- u32 output_hog_addr_offset;
+- // 160 bytes
+-};
+-
+-static_assert(sizeof(struct pisp_tile) == 160);
+-
+-struct pisp_be_tiles_config {
+- struct pisp_be_config config;
+- struct pisp_tile tiles[PISP_BACK_END_NUM_TILES];
+- int num_tiles;
+-};
+-
+-#endif /* _PISP_BE_CONFIG_H_ */
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be_formats.h
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be_formats.h
+@@ -2,7 +2,7 @@
+ /*
+ * PiSP Back End driver image format definitions.
+ *
+- * Copyright (c) 2021 Raspberry Pi Ltd
++ * Copyright (c) 2021-2024 Raspberry Pi Ltd
+ */
+
+ #ifndef _PISP_BE_FORMATS_
+@@ -11,15 +11,15 @@
+ #include <linux/bits.h>
+ #include <linux/videodev2.h>
+
+-#define MAX_PLANES 3
+-#define P3(x) ((x) * 8)
++#define PISPBE_MAX_PLANES 3
++#define P3(x) ((x) * 8)
+
+ struct pisp_be_format {
+ unsigned int fourcc;
+ unsigned int align;
+ unsigned int bit_depth;
+ /* 0P3 factor for plane sizing */
+- unsigned int plane_factor[MAX_PLANES];
++ unsigned int plane_factor[PISPBE_MAX_PLANES];
+ unsigned int num_planes;
+ unsigned int colorspace_mask;
+ enum v4l2_colorspace colorspace_default;
+@@ -27,14 +27,19 @@ struct pisp_be_format {
+
+ #define V4L2_COLORSPACE_MASK(colorspace) BIT(colorspace)
+
+-#define V4L2_COLORSPACE_MASK_JPEG V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_JPEG)
+-#define V4L2_COLORSPACE_MASK_SMPTE170M V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SMPTE170M)
+-#define V4L2_COLORSPACE_MASK_REC709 V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_REC709)
+-#define V4L2_COLORSPACE_MASK_SRGB V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SRGB)
+-#define V4L2_COLORSPACE_MASK_RAW V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_RAW)
++#define V4L2_COLORSPACE_MASK_JPEG \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_JPEG)
++#define V4L2_COLORSPACE_MASK_SMPTE170M \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SMPTE170M)
++#define V4L2_COLORSPACE_MASK_REC709 \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_REC709)
++#define V4L2_COLORSPACE_MASK_SRGB \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SRGB)
++#define V4L2_COLORSPACE_MASK_RAW \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_RAW)
+
+ /*
+- * All three colour spaces JPEG, SMPTE170M and REC709 are fundamentally sRGB
++ * All three colour spaces SRGB, SMPTE170M and REC709 are fundamentally sRGB
+ * underneath (as near as makes no difference to us), just with different YCbCr
+ * encodings. Therefore the ISP can generate sRGB on its main output and any of
+ * the others on its low resolution output. Applications should, when using both
+@@ -43,9 +48,9 @@ struct pisp_be_format {
+ * producing an RGB format. In turn this requires us to allow all these colour
+ * spaces for every YUV/RGB output format.
+ */
+-#define V4L2_COLORSPACE_MASK_ALL_SRGB (V4L2_COLORSPACE_MASK_JPEG | \
+- V4L2_COLORSPACE_MASK_SRGB | \
+- V4L2_COLORSPACE_MASK_SMPTE170M | \
++#define V4L2_COLORSPACE_MASK_ALL_SRGB (V4L2_COLORSPACE_MASK_JPEG | \
++ V4L2_COLORSPACE_MASK_SRGB | \
++ V4L2_COLORSPACE_MASK_SMPTE170M | \
+ V4L2_COLORSPACE_MASK_REC709)
+
+ static const struct pisp_be_format supported_formats[] = {
+@@ -58,7 +63,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(0.25), P3(0.25) },
+ .num_planes = 1,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YVU420,
+@@ -132,7 +137,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(0.25), P3(0.25) },
+ .num_planes = 3,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV12M,
+@@ -168,7 +173,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(0.5), P3(0.5) },
+ .num_planes = 3,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YVU422M,
+@@ -186,7 +191,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(1), P3(1) },
+ .num_planes = 3,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YVU444M,
+@@ -502,11 +507,6 @@ static const struct pisp_be_format suppo
+ .colorspace_mask = V4L2_COLORSPACE_MASK_RAW,
+ .colorspace_default = V4L2_COLORSPACE_RAW,
+ },
+- /* Opaque BE format for HW verification. */
+- {
+- .fourcc = V4L2_PIX_FMT_RPI_BE,
+- .align = 32,
+- },
+ };
+
+ static const struct pisp_be_format meta_out_supported_formats[] = {
diff --git a/target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch b/target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch
new file mode 100644
index 0000000000..f59c02c5b1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch
@@ -0,0 +1,29 @@
+From b58aeea7e2e3afd4fb3b6dcbe5e382b2244b33a4 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 27 Jun 2024 13:40:29 +0200
+Subject: [PATCH 1155/1215] media: uapi: pisp_be_config: Drop BIT() from uAPI
+
+The pisp_be_config.h uAPI header file contains a bit-field definition
+that uses the BIT() helper macro.
+
+As the BIT() identifier is not defined in userspace, drop it from the
+uAPI header.
+
+Fixes: c6c49bac8770 ("media: uapi: Add Raspberry Pi PiSP Back End uAPI")
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+---
+ include/uapi/linux/media/raspberrypi/pisp_be_config.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_be_config.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -146,7 +146,7 @@ struct pisp_be_dpc_config {
+ */
+ struct pisp_be_geq_config {
+ __u16 offset;
+-#define PISP_BE_GEQ_SHARPER BIT(15)
++#define PISP_BE_GEQ_SHARPER (1U << 15)
+ #define PISP_BE_GEQ_SLOPE ((1 << 10) - 1)
+ /* top bit is the "sharper" flag, slope value is bottom 10 bits */
+ __u16 slope_sharper;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch b/target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch
new file mode 100644
index 0000000000..0cb94fe933
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch
@@ -0,0 +1,32 @@
+From 7c36a1feb61d964055bee777efc1db60790aa215 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 27 Jun 2024 16:07:43 +0200
+Subject: [PATCH 1156/1215] media: uapi: pisp_common: Add 32 bpp format test
+
+Add definition and test for 32-bits image formats to the pisp_common.h
+uAPI header.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ include/uapi/linux/media/raspberrypi/pisp_common.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_common.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_common.h
+@@ -72,6 +72,8 @@ enum pisp_image_format {
+ PISP_IMAGE_FORMAT_SHIFT_8 = 0x00080000,
+ PISP_IMAGE_FORMAT_SHIFT_MASK = 0x000f0000,
+
++ PISP_IMAGE_FORMAT_BPP_32 = 0x00100000,
++
+ PISP_IMAGE_FORMAT_UNCOMPRESSED = 0x00000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MODE_1 = 0x01000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MODE_2 = 0x02000000,
+@@ -134,6 +136,7 @@ enum pisp_image_format {
+ PISP_IMAGE_FORMAT_PLANARITY_PLANAR)
+ #define PISP_IMAGE_FORMAT_wallpaper(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
++#define PISP_IMAGE_FORMAT_bpp_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32)
+ #define PISP_IMAGE_FORMAT_HOG(fmt) \
+ ((fmt) & \
+ (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED))
diff --git a/target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch b/target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch
new file mode 100644
index 0000000000..fac2ccf163
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch
@@ -0,0 +1,89 @@
+From 20a3671be178fd98aac08931d809e689eaa7a9d9 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 10:10:10 +0200
+Subject: [PATCH 1157/1215] media: uapi: Capitalize all macros
+
+The macro used to inspect an image format characteristic use a mixture
+of capitalized and non-capitalized letters, which is rather unusual for
+the Linux kernel style.
+
+Capitalize all identifiers.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../linux/media/raspberrypi/pisp_common.h | 38 +++++++++----------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_common.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_common.h
+@@ -92,51 +92,51 @@ enum pisp_image_format {
+ PISP_IMAGE_FORMAT_THREE_CHANNEL
+ };
+
+-#define PISP_IMAGE_FORMAT_bps_8(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_8(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_8)
+-#define PISP_IMAGE_FORMAT_bps_10(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_10(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_10)
+-#define PISP_IMAGE_FORMAT_bps_12(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_12(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_12)
+-#define PISP_IMAGE_FORMAT_bps_16(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_16(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_16)
+-#define PISP_IMAGE_FORMAT_bps(fmt) \
++#define PISP_IMAGE_FORMAT_BPS(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) ? \
+ 8 + (2 << (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) - 1)) : 8)
+-#define PISP_IMAGE_FORMAT_shift(fmt) \
++#define PISP_IMAGE_FORMAT_SHIFT(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SHIFT_MASK) / PISP_IMAGE_FORMAT_SHIFT_1)
+-#define PISP_IMAGE_FORMAT_three_channel(fmt) \
++#define PISP_IMAGE_FORMAT_THREE_CHANNEL(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL)
+-#define PISP_IMAGE_FORMAT_single_channel(fmt) \
++#define PISP_IMAGE_FORMAT_SINGLE_CHANNEL(fmt) \
+ (!((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL))
+-#define PISP_IMAGE_FORMAT_compressed(fmt) \
++#define PISP_IMAGE_FORMAT_COMPRESSED(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_COMPRESSION_MASK) != \
+ PISP_IMAGE_FORMAT_UNCOMPRESSED)
+-#define PISP_IMAGE_FORMAT_sampling_444(fmt) \
++#define PISP_IMAGE_FORMAT_SAMPLING_444(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
+ PISP_IMAGE_FORMAT_SAMPLING_444)
+-#define PISP_IMAGE_FORMAT_sampling_422(fmt) \
++#define PISP_IMAGE_FORMAT_SAMPLING_422(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
+ PISP_IMAGE_FORMAT_SAMPLING_422)
+-#define PISP_IMAGE_FORMAT_sampling_420(fmt) \
++#define PISP_IMAGE_FORMAT_SAMPLING_420(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
+ PISP_IMAGE_FORMAT_SAMPLING_420)
+-#define PISP_IMAGE_FORMAT_order_normal(fmt) \
++#define PISP_IMAGE_FORMAT_ORDER_NORMAL(fmt) \
+ (!((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED))
+-#define PISP_IMAGE_FORMAT_order_swapped(fmt) \
++#define PISP_IMAGE_FORMAT_ORDER_SWAPPED(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED)
+-#define PISP_IMAGE_FORMAT_interleaved(fmt) \
++#define PISP_IMAGE_FORMAT_INTERLEAVED(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
+ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED)
+-#define PISP_IMAGE_FORMAT_semiplanar(fmt) \
++#define PISP_IMAGE_FORMAT_SEMIPLANAR(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
+ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR)
+-#define PISP_IMAGE_FORMAT_planar(fmt) \
++#define PISP_IMAGE_FORMAT_PLANAR(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
+ PISP_IMAGE_FORMAT_PLANARITY_PLANAR)
+-#define PISP_IMAGE_FORMAT_wallpaper(fmt) \
++#define PISP_IMAGE_FORMAT_WALLPAPER(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
+-#define PISP_IMAGE_FORMAT_bpp_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32)
++#define PISP_IMAGE_FORMAT_BPP_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32)
+ #define PISP_IMAGE_FORMAT_HOG(fmt) \
+ ((fmt) & \
+ (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED))
diff --git a/target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch b/target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch
new file mode 100644
index 0000000000..49ff9d73ff
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch
@@ -0,0 +1,30 @@
+From ce89955e44f3ab41262b02d8e1e65c3455d66c4d Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 13:59:40 +0200
+Subject: [PATCH 1158/1215] media: uapi: pisp_be_config: Re-sort
+ pisp_be_tiles_config
+
+The order of the members of pisp_be_tiles_config is relevant
+as the driver logic assumes 'config' to be at offset 0.
+
+Re-sort the member to match the driver's expectations.
+
+Fixes: c6c49bac8770 ("media: uapi: Add Raspberry Pi PiSP Back End uAPI")
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ include/uapi/linux/media/raspberrypi/pisp_be_config.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_be_config.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -919,9 +919,9 @@ struct pisp_tile {
+ * @config: PiSP Back End configuration
+ */
+ struct pisp_be_tiles_config {
++ struct pisp_be_config config;
+ struct pisp_tile tiles[PISP_BACK_END_NUM_TILES];
+ __u32 num_tiles;
+- struct pisp_be_config config;
+ } __attribute__((packed));
+
+ #endif /* _UAPI_PISP_BE_CONFIG_H_ */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch b/target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch
new file mode 100644
index 0000000000..d18d12ec67
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch
@@ -0,0 +1,82 @@
+From abf30420f943d03cc28fec38612d2c5f5e6edf1f Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 14:11:14 +0200
+Subject: [PATCH 1159/1215] media: uapi: pisp_be_config: Add extra config
+ fields
+
+Complete the pisp_be_config strcture by adding fields that even if not
+written to the HW are relevant to complete the uAPI and put it in par
+with the BSP driver.
+
+Fixes: c6c49bac8770 ("media: uapi: Add Raspberry Pi PiSP Back End uAPI")
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../linux/media/raspberrypi/pisp_be_config.h | 41 +++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_be_config.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -716,6 +716,13 @@ struct pisp_be_hog_buffer_config {
+ /**
+ * struct pisp_be_config - RaspberryPi PiSP Back End Processing configuration
+ *
++ * @input_buffer: Input buffer addresses
++ * @tdn_input_buffer: TDN input buffer addresses
++ * @stitch_input_buffer: Stitch input buffer addresses
++ * @tdn_output_buffer: TDN output buffer addresses
++ * @stitch_output_buffer: Stitch output buffer addresses
++ * @output_buffer: Output buffers addresses
++ * @hog_buffer: HOG buffer addresses
+ * @global: Global PiSP configuration
+ * @input_format: Input image format
+ * @decompress: Decompress configuration
+@@ -753,8 +760,30 @@ struct pisp_be_hog_buffer_config {
+ * @resample: Resampling configuration
+ * @output_format: Output format configuration
+ * @hog: HOG configuration
++ * @axi: AXI bus configuration
++ * @lsc_extra: LSC extra info
++ * @cac_extra: CAC extra info
++ * @downscale_extra: Downscaler extra info
++ * @resample_extra: Resample extra info
++ * @crop: Crop configuration
++ * @hog_format: HOG format info
++ * @dirty_flags_bayer: Bayer enable dirty flags
++ * (:c:type:`pisp_be_bayer_enable`)
++ * @dirty_flags_rgb: RGB enable dirty flags
++ * (:c:type:`pisp_be_rgb_enable`)
++ * @dirty_flags_extra: Extra dirty flags
+ */
+ struct pisp_be_config {
++ /* I/O configuration: */
++ struct pisp_be_input_buffer_config input_buffer;
++ struct pisp_be_tdn_input_buffer_config tdn_input_buffer;
++ struct pisp_be_stitch_input_buffer_config stitch_input_buffer;
++ struct pisp_be_tdn_output_buffer_config tdn_output_buffer;
++ struct pisp_be_stitch_output_buffer_config stitch_output_buffer;
++ struct pisp_be_output_buffer_config
++ output_buffer[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_hog_buffer_config hog_buffer;
++ /* Processing configuration: */
+ struct pisp_be_global_config global;
+ struct pisp_image_format_config input_format;
+ struct pisp_decompress_config decompress;
+@@ -793,6 +822,18 @@ struct pisp_be_config {
+ struct pisp_be_output_format_config
+ output_format[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_hog_config hog;
++ struct pisp_be_axi_config axi;
++ /* Non-register fields: */
++ struct pisp_be_lsc_extra lsc_extra;
++ struct pisp_be_cac_extra cac_extra;
++ struct pisp_be_downscale_extra
++ downscale_extra[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_resample_extra resample_extra[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_crop_config crop;
++ struct pisp_image_format_config hog_format;
++ __u32 dirty_flags_bayer; /* these use pisp_be_bayer_enable */
++ __u32 dirty_flags_rgb; /* use pisp_be_rgb_enable */
++ __u32 dirty_flags_extra; /* these use pisp_be_dirty_t */
+ } __attribute__((packed));
+
+ /**
diff --git a/target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch b/target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch
new file mode 100644
index 0000000000..ad667a1e69
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch
@@ -0,0 +1,886 @@
+From 033e037013f2c092501a03bb1bf5bbf7b4045aa0 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 17:26:26 +0200
+Subject: [PATCH 1160/1215] media: pisp_be: Re-introduce multi-context support
+
+Re-introduce multi-context support that was dropped from the
+mainline driver version.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../platform/raspberrypi/pisp_be/pisp_be.c | 355 ++++++++++--------
+ 1 file changed, 208 insertions(+), 147 deletions(-)
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
+@@ -24,6 +24,14 @@
+ /* Maximum number of config buffers possible */
+ #define PISP_BE_NUM_CONFIG_BUFFERS VB2_MAX_FRAME
+
++/*
++ * We want to support 2 independent instances allowing 2 simultaneous users
++ * of the ISP-BE (of course they share hardware, platform resources and mutex).
++ * Each such instance comprises a group of device nodes representing input
++ * and output queues, and a media controller device node to describe them.
++ */
++#define PISPBE_NUM_NODE_GROUPS 2
++
+ #define PISPBE_NAME "pispbe"
+
+ /* Some ISP-BE registers */
+@@ -156,7 +164,7 @@ struct pispbe_node {
+ struct media_pad pad;
+ struct media_intf_devnode *intf_devnode;
+ struct media_link *intf_link;
+- struct pispbe_dev *pispbe;
++ struct pispbe_node_group *node_group;
+ /* Video device lock */
+ struct mutex node_lock;
+ /* vb2_queue lock */
+@@ -173,9 +181,27 @@ struct pispbe_node {
+ #define NODE_NAME(node) \
+ (node_desc[(node)->id].ent_name + sizeof(PISPBE_NAME))
+
++/*
++ * Node group structure, which comprises all the input and output nodes that a
++ * single PiSP client will need, along with its own v4l2 and media devices.
++ */
++struct pispbe_node_group {
++ unsigned int id;
++ struct v4l2_device v4l2_dev;
++ struct v4l2_subdev sd;
++ struct pispbe_dev *pispbe;
++ struct media_device mdev;
++ struct pispbe_node node[PISPBE_NUM_NODES];
++ u32 streaming_map; /* bitmap of which nodes are streaming */
++ struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
++ struct pisp_be_tiles_config *config;
++ dma_addr_t config_dma_addr;
++ unsigned int sequence;
++};
++
+ /* Records details of the jobs currently running or queued on the h/w. */
+ struct pispbe_job {
+- bool valid;
++ struct pispbe_node_group *node_group;
+ /*
+ * An array of buffer pointers - remember it's source buffers first,
+ * then captures, then metadata last.
+@@ -198,22 +224,13 @@ struct pispbe_job_descriptor {
+
+ /*
+ * Structure representing the entire PiSP Back End device, comprising several
+- * nodes which share platform resources and a mutex for the actual HW.
++ * nodes groups which share platform resources and a mutex for the actual HW.
+ */
+ struct pispbe_dev {
+ struct device *dev;
+- struct pispbe_dev *pispbe;
+- struct pisp_be_tiles_config *config;
+ void __iomem *be_reg_base;
+ struct clk *clk;
+- struct v4l2_device v4l2_dev;
+- struct v4l2_subdev sd;
+- struct media_device mdev;
+- struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
+- struct pispbe_node node[PISPBE_NUM_NODES];
+- dma_addr_t config_dma_addr;
+- unsigned int sequence;
+- u32 streaming_map;
++ struct pispbe_node_group node_group[PISPBE_NUM_NODE_GROUPS];
+ struct pispbe_job queued_job, running_job;
+ spinlock_t hw_lock; /* protects "hw_busy" flag and streaming_map */
+ bool hw_busy; /* non-zero if a job is queued or is being started */
+@@ -348,9 +365,9 @@ static dma_addr_t pispbe_get_addr(struct
+ return 0;
+ }
+
+-static void pispbe_xlate_addrs(struct pispbe_dev *pispbe,
+- struct pispbe_job_descriptor *job,
+- struct pispbe_buffer *buf[PISPBE_NUM_NODES])
++static void pispbe_xlate_addrs(struct pispbe_job_descriptor *job,
++ struct pispbe_buffer *buf[PISPBE_NUM_NODES],
++ struct pispbe_node_group *node_group)
+ {
+ struct pispbe_hw_enables *hw_en = &job->hw_enables;
+ struct pisp_be_tiles_config *config = job->config;
+@@ -366,13 +383,13 @@ static void pispbe_xlate_addrs(struct pi
+ * to 3 planes.
+ */
+ ret = pispbe_get_planes_addr(addrs, buf[MAIN_INPUT_NODE],
+- &pispbe->node[MAIN_INPUT_NODE]);
++ &node_group->node[MAIN_INPUT_NODE]);
+ if (ret <= 0) {
+ /*
+ * This shouldn't happen; pispbe_schedule_internal should insist
+ * on an input.
+ */
+- dev_warn(pispbe->dev, "ISP-BE missing input\n");
++ dev_warn(node_group->pispbe->dev, "ISP-BE missing input\n");
+ hw_en->bayer_enables = 0;
+ hw_en->rgb_enables = 0;
+ return;
+@@ -427,7 +444,7 @@ static void pispbe_xlate_addrs(struct pi
+ for (unsigned int i = 0; i < PISP_BACK_END_NUM_OUTPUTS; i++) {
+ ret = pispbe_get_planes_addr(addrs + 7 + 3 * i,
+ buf[OUTPUT0_NODE + i],
+- &pispbe->node[OUTPUT0_NODE + i]);
++ &node_group->node[OUTPUT0_NODE + i]);
+ if (ret <= 0)
+ hw_en->rgb_enables &= ~(PISP_BE_RGB_ENABLE_OUTPUT0 << i);
+ }
+@@ -447,10 +464,11 @@ static void pispbe_xlate_addrs(struct pi
+ *
+ * Returns 0 if a job has been successfully prepared, < 0 otherwise.
+ */
+-static int pispbe_prepare_job(struct pispbe_dev *pispbe,
++static int pispbe_prepare_job(struct pispbe_node_group *node_group,
+ struct pispbe_job_descriptor *job)
+ {
+ struct pispbe_buffer *buf[PISPBE_NUM_NODES] = {};
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ unsigned int config_index;
+ struct pispbe_node *node;
+ unsigned long flags;
+@@ -460,11 +478,11 @@ static int pispbe_prepare_job(struct pis
+ memset(job, 0, sizeof(struct pispbe_job_descriptor));
+
+ if (((BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)) &
+- pispbe->streaming_map) !=
++ node_group->streaming_map) !=
+ (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)))
+ return -ENODEV;
+
+- node = &pispbe->node[CONFIG_NODE];
++ node = &node_group->node[CONFIG_NODE];
+ spin_lock_irqsave(&node->ready_lock, flags);
+ buf[CONFIG_NODE] = list_first_entry_or_null(&node->ready_queue,
+ struct pispbe_buffer,
+@@ -480,8 +498,8 @@ static int pispbe_prepare_job(struct pis
+ return -ENODEV;
+
+ config_index = buf[CONFIG_NODE]->vb.vb2_buf.index;
+- job->config = &pispbe->config[config_index];
+- job->tiles = pispbe->config_dma_addr +
++ job->config = &node_group->config[config_index];
++ job->tiles = node_group->config_dma_addr +
+ config_index * sizeof(struct pisp_be_tiles_config) +
+ offsetof(struct pisp_be_tiles_config, tiles);
+
+@@ -498,7 +516,7 @@ static int pispbe_prepare_job(struct pis
+ continue;
+
+ buf[i] = NULL;
+- if (!(pispbe->streaming_map & BIT(i)))
++ if (!(node_group->streaming_map & BIT(i)))
+ continue;
+
+ if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0) &&
+@@ -522,7 +540,7 @@ static int pispbe_prepare_job(struct pis
+ ignore_buffers = true;
+ }
+
+- node = &pispbe->node[i];
++ node = &node_group->node[i];
+
+ /* Pull a buffer from each V4L2 queue to form the queued job */
+ spin_lock_irqsave(&node->ready_lock, flags);
+@@ -539,16 +557,16 @@ static int pispbe_prepare_job(struct pis
+ goto err_return_buffers;
+ }
+
+- pispbe->queued_job.valid = true;
++ pispbe->queued_job.node_group = node_group;
+
+ /* Convert buffers to DMA addresses for the hardware */
+- pispbe_xlate_addrs(pispbe, job, buf);
++ pispbe_xlate_addrs(job, buf, node_group);
+
+ return 0;
+
+ err_return_buffers:
+ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+- struct pispbe_node *n = &pispbe->node[i];
++ struct pispbe_node *n = &node_group->node[i];
+
+ if (!buf[i])
+ continue;
+@@ -564,11 +582,12 @@ err_return_buffers:
+ return -ENODEV;
+ }
+
+-static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy)
++static void pispbe_schedule(struct pispbe_dev *pispbe,
++ struct pispbe_node_group *node_group,
++ bool clear_hw_busy)
+ {
+ struct pispbe_job_descriptor job;
+ unsigned long flags;
+- int ret;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+
+@@ -578,40 +597,53 @@ static void pispbe_schedule(struct pispb
+ if (pispbe->hw_busy)
+ goto unlock_and_return;
+
+- ret = pispbe_prepare_job(pispbe, &job);
+- if (ret)
+- goto unlock_and_return;
++ for (unsigned int i = 0; i < PISPBE_NUM_NODE_GROUPS; i++) {
++ int ret;
+
+- /*
+- * We can kick the job off without the hw_lock, as this can
+- * never run again until hw_busy is cleared, which will happen
+- * only when the following job has been queued and an interrupt
+- * is rised.
+- */
+- pispbe->hw_busy = true;
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++ /* Schedule jobs only for a specific group. */
++ if (node_group && &pispbe->node_group[i] != node_group)
++ continue;
+
+- if (job.config->num_tiles <= 0 ||
+- job.config->num_tiles > PISP_BACK_END_NUM_TILES ||
+- !((job.hw_enables.bayer_enables | job.hw_enables.rgb_enables) &
+- PISP_BE_BAYER_ENABLE_INPUT)) {
+ /*
+- * Bad job. We can't let it proceed as it could lock up
+- * the hardware, or worse!
+- *
+- * For now, just force num_tiles to 0, which causes the
+- * H/W to do something bizarre but survivable. It
+- * increments (started,done) counters by more than 1,
+- * but we seem to survive...
++ * Prepare a job for this group, if the group is not ready
++ * continue and try with the next one.
+ */
+- dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n",
+- job.config->num_tiles);
+- job.config->num_tiles = 0;
+- }
++ ret = pispbe_prepare_job(&pispbe->node_group[i], &job);
++ if (ret)
++ continue;
++
++ /*
++ * We can kick the job off without the hw_lock, as this can
++ * never run again until hw_busy is cleared, which will happen
++ * only when the following job has been queued and an interrupt
++ * is rised.
++ */
++ pispbe->hw_busy = true;
++ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++
++ if (job.config->num_tiles <= 0 ||
++ job.config->num_tiles > PISP_BACK_END_NUM_TILES ||
++ !((job.hw_enables.bayer_enables |
++ job.hw_enables.rgb_enables) &
++ PISP_BE_BAYER_ENABLE_INPUT)) {
++ /*
++ * Bad job. We can't let it proceed as it could lock up
++ * the hardware, or worse!
++ *
++ * For now, just force num_tiles to 0, which causes the
++ * H/W to do something bizarre but survivable. It
++ * increments (started,done) counters by more than 1,
++ * but we seem to survive...
++ */
++ dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n",
++ job.config->num_tiles);
++ job.config->num_tiles = 0;
++ }
+
+- pispbe_queue_job(pispbe, &job);
++ pispbe_queue_job(pispbe, &job);
+
+- return;
++ return;
++ }
+
+ unlock_and_return:
+ /* No job has been queued, just release the lock and return. */
+@@ -627,13 +659,13 @@ static void pispbe_isr_jobdone(struct pi
+ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+ if (buf[i]) {
+ buf[i]->vb.vb2_buf.timestamp = ts;
+- buf[i]->vb.sequence = pispbe->sequence;
++ buf[i]->vb.sequence = job->node_group->sequence;
+ vb2_buffer_done(&buf[i]->vb.vb2_buf,
+ VB2_BUF_STATE_DONE);
+ }
+ }
+
+- pispbe->sequence++;
++ job->node_group->sequence++;
+ }
+
+ static irqreturn_t pispbe_isr(int irq, void *dev)
+@@ -657,7 +689,7 @@ static irqreturn_t pispbe_isr(int irq, v
+ * we previously saw "start" now finishes, and we then queued a new job
+ * which we see both start and finish "simultaneously".
+ */
+- if (pispbe->running_job.valid && pispbe->done != done) {
++ if (pispbe->running_job.node_group && pispbe->done != done) {
+ pispbe_isr_jobdone(pispbe, &pispbe->running_job);
+ memset(&pispbe->running_job, 0, sizeof(pispbe->running_job));
+ pispbe->done++;
+@@ -667,7 +699,7 @@ static irqreturn_t pispbe_isr(int irq, v
+ pispbe->started++;
+ can_queue_another = 1;
+
+- if (pispbe->done != done && pispbe->queued_job.valid) {
++ if (pispbe->done != done && pispbe->queued_job.node_group) {
+ pispbe_isr_jobdone(pispbe, &pispbe->queued_job);
+ pispbe->done++;
+ } else {
+@@ -686,17 +718,17 @@ static irqreturn_t pispbe_isr(int irq, v
+ }
+
+ /* check if there's more to do before going to sleep */
+- pispbe_schedule(pispbe, can_queue_another);
++ pispbe_schedule(pispbe, NULL, can_queue_another);
+
+ return IRQ_HANDLED;
+ }
+
+-static int pisp_be_validate_config(struct pispbe_dev *pispbe,
++static int pisp_be_validate_config(struct pispbe_node_group *node_group,
+ struct pisp_be_tiles_config *config)
+ {
+ u32 bayer_enables = config->config.global.bayer_enables;
+ u32 rgb_enables = config->config.global.rgb_enables;
+- struct device *dev = pispbe->dev;
++ struct device *dev = node_group->pispbe->dev;
+ struct v4l2_format *fmt;
+ unsigned int bpl, size;
+
+@@ -707,7 +739,7 @@ static int pisp_be_validate_config(struc
+ }
+
+ /* Ensure output config strides and buffer sizes match the V4L2 formats. */
+- fmt = &pispbe->node[TDN_OUTPUT_NODE].format;
++ fmt = &node_group->node[TDN_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_TDN_OUTPUT) {
+ bpl = config->config.tdn_output_format.stride;
+ size = bpl * config->config.tdn_output_format.height;
+@@ -725,7 +757,7 @@ static int pisp_be_validate_config(struc
+ }
+ }
+
+- fmt = &pispbe->node[STITCH_OUTPUT_NODE].format;
++ fmt = &node_group->node[STITCH_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_OUTPUT) {
+ bpl = config->config.stitch_output_format.stride;
+ size = bpl * config->config.stitch_output_format.height;
+@@ -751,7 +783,7 @@ static int pisp_be_validate_config(struc
+ PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
+ continue; /* TODO: Size checks for wallpaper formats */
+
+- fmt = &pispbe->node[OUTPUT0_NODE + j].format;
++ fmt = &node_group->node[OUTPUT0_NODE + j].format;
+ for (unsigned int i = 0; i < fmt->fmt.pix_mp.num_planes; i++) {
+ bpl = !i ? config->config.output_format[j].image.stride
+ : config->config.output_format[j].image.stride2;
+@@ -783,7 +815,7 @@ static int pispbe_node_queue_setup(struc
+ struct device *alloc_devs[])
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ unsigned int num_planes = NODE_IS_MPLANE(node) ?
+ node->format.fmt.pix_mp.num_planes : 1;
+
+@@ -821,7 +853,7 @@ static int pispbe_node_queue_setup(struc
+ static int pispbe_node_buffer_prepare(struct vb2_buffer *vb)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(vb->vb2_queue);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ unsigned int num_planes = NODE_IS_MPLANE(node) ?
+ node->format.fmt.pix_mp.num_planes : 1;
+
+@@ -841,12 +873,12 @@ static int pispbe_node_buffer_prepare(st
+ }
+
+ if (node->id == CONFIG_NODE) {
+- void *dst = &node->pispbe->config[vb->index];
++ void *dst = &node->node_group->config[vb->index];
+ void *src = vb2_plane_vaddr(vb, 0);
+
+ memcpy(dst, src, sizeof(struct pisp_be_tiles_config));
+
+- return pisp_be_validate_config(pispbe, dst);
++ return pisp_be_validate_config(node->node_group, dst);
+ }
+
+ return 0;
+@@ -859,7 +891,8 @@ static void pispbe_node_buffer_queue(str
+ struct pispbe_buffer *buffer =
+ container_of(vbuf, struct pispbe_buffer, vb);
+ struct pispbe_node *node = vb2_get_drv_priv(buf->vb2_queue);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_node_group *node_group = node->node_group;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ unsigned long flags;
+
+ dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
+@@ -869,15 +902,16 @@ static void pispbe_node_buffer_queue(str
+
+ /*
+ * Every time we add a buffer, check if there's now some work for the hw
+- * to do.
++ * to do, but only for this client.
+ */
+- pispbe_schedule(pispbe, false);
++ pispbe_schedule(node_group->pispbe, node_group, false);
+ }
+
+ static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_node_group *node_group = node->node_group;
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ struct pispbe_buffer *buf, *tmp;
+ unsigned long flags;
+ int ret;
+@@ -887,17 +921,17 @@ static int pispbe_node_start_streaming(s
+ goto err_return_buffers;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- node->pispbe->streaming_map |= BIT(node->id);
+- node->pispbe->sequence = 0;
++ node->node_group->streaming_map |= BIT(node->id);
++ node->node_group->sequence = 0;
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n",
+ __func__, NODE_NAME(node), count);
+- dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
+- node->pispbe->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
++ node->node_group->streaming_map);
+
+ /* Maybe we're ready to run. */
+- pispbe_schedule(pispbe, false);
++ pispbe_schedule(node_group->pispbe, node_group, false);
+
+ return 0;
+
+@@ -915,7 +949,8 @@ err_return_buffers:
+ static void pispbe_node_stop_streaming(struct vb2_queue *q)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_node_group *node_group = node->node_group;
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ struct pispbe_buffer *buf;
+ unsigned long flags;
+
+@@ -948,14 +983,14 @@ static void pispbe_node_stop_streaming(s
+ vb2_wait_for_all_buffers(&node->queue);
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- pispbe->streaming_map &= ~BIT(node->id);
++ node_group->streaming_map &= ~BIT(node->id);
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+- dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
+- pispbe->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
++ node_group->streaming_map);
+ }
+
+ static const struct vb2_ops pispbe_node_queue_ops = {
+@@ -979,7 +1014,7 @@ static int pispbe_node_querycap(struct f
+ struct v4l2_capability *cap)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ strscpy(cap->driver, PISPBE_NAME, sizeof(cap->driver));
+ strscpy(cap->card, PISPBE_NAME, sizeof(cap->card));
+@@ -995,7 +1030,7 @@ static int pispbe_node_g_fmt_vid_cap(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1015,7 +1050,7 @@ static int pispbe_node_g_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1035,7 +1070,7 @@ static int pispbe_node_g_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1092,7 +1127,7 @@ static void pispbe_set_plane_params(stru
+
+ static void pispbe_try_format(struct v4l2_format *f, struct pispbe_node *node)
+ {
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ u32 pixfmt = f->fmt.pix_mp.pixelformat;
+ const struct pisp_be_format *fmt;
+ bool is_rgb;
+@@ -1156,7 +1191,7 @@ static int pispbe_node_try_fmt_vid_cap(s
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1174,7 +1209,7 @@ static int pispbe_node_try_fmt_vid_out(s
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_OUTPUT(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1192,7 +1227,7 @@ static int pispbe_node_try_fmt_meta_out(
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1211,7 +1246,7 @@ static int pispbe_node_s_fmt_vid_cap(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ int ret;
+
+ ret = pispbe_node_try_fmt_vid_cap(file, priv, f);
+@@ -1234,7 +1269,7 @@ static int pispbe_node_s_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ int ret;
+
+ ret = pispbe_node_try_fmt_vid_out(file, priv, f);
+@@ -1257,7 +1292,7 @@ static int pispbe_node_s_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ int ret;
+
+ ret = pispbe_node_try_fmt_meta_out(file, priv, f);
+@@ -1306,7 +1341,7 @@ static int pispbe_enum_framesizes(struct
+ struct v4l2_frmsizeenum *fsize)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (NODE_IS_META(node) || fsize->index)
+ return -EINVAL;
+@@ -1391,17 +1426,19 @@ static void pispbe_node_def_fmt(struct p
+ * Initialise a struct pispbe_node and register it as /dev/video<N>
+ * to represent one of the PiSP Back End's input or output streams.
+ */
+-static int pispbe_init_node(struct pispbe_dev *pispbe, unsigned int id)
++static int pispbe_init_node(struct pispbe_node_group *node_group,
++ unsigned int id)
+ {
+ bool output = NODE_DESC_IS_OUTPUT(&node_desc[id]);
+- struct pispbe_node *node = &pispbe->node[id];
++ struct pispbe_node *node = &node_group->node[id];
+ struct media_entity *entity = &node->vfd.entity;
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ struct video_device *vdev = &node->vfd;
+ struct vb2_queue *q = &node->queue;
+ int ret;
+
+ node->id = id;
+- node->pispbe = pispbe;
++ node->node_group = node_group;
+ node->buf_type = node_desc[id].buf_type;
+
+ mutex_init(&node->node_lock);
+@@ -1419,7 +1456,7 @@ static int pispbe_init_node(struct pispb
+ q->ops = &pispbe_node_queue_ops;
+ q->buf_struct_size = sizeof(struct pispbe_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+- q->dev = pispbe->dev;
++ q->dev = node->node_group->pispbe->dev;
+ /* get V4L2 to handle node->queue locking */
+ q->lock = &node->queue_lock;
+
+@@ -1431,7 +1468,7 @@ static int pispbe_init_node(struct pispb
+
+ *vdev = pispbe_videodev; /* default initialization */
+ strscpy(vdev->name, node_desc[id].ent_name, sizeof(vdev->name));
+- vdev->v4l2_dev = &pispbe->v4l2_dev;
++ vdev->v4l2_dev = &node_group->v4l2_dev;
+ vdev->vfl_dir = output ? VFL_DIR_TX : VFL_DIR_RX;
+ /* get V4L2 to serialise our ioctls */
+ vdev->lock = &node->node_lock;
+@@ -1457,11 +1494,11 @@ static int pispbe_init_node(struct pispb
+ video_set_drvdata(vdev, node);
+
+ if (output)
+- ret = media_create_pad_link(entity, 0, &pispbe->sd.entity,
++ ret = media_create_pad_link(entity, 0, &node_group->sd.entity,
+ id, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ else
+- ret = media_create_pad_link(&pispbe->sd.entity, id, entity,
++ ret = media_create_pad_link(&node_group->sd.entity, id, entity,
+ 0, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+@@ -1490,9 +1527,10 @@ static const struct v4l2_subdev_ops pisp
+ .pad = &pispbe_pad_ops,
+ };
+
+-static int pispbe_init_subdev(struct pispbe_dev *pispbe)
++static int pispbe_init_subdev(struct pispbe_node_group *node_group)
+ {
+- struct v4l2_subdev *sd = &pispbe->sd;
++ struct pispbe_dev *pispbe = node_group->pispbe;
++ struct v4l2_subdev *sd = &node_group->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &pispbe_sd_ops);
+@@ -1502,16 +1540,16 @@ static int pispbe_init_subdev(struct pis
+ strscpy(sd->name, PISPBE_NAME, sizeof(sd->name));
+
+ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++)
+- pispbe->pad[i].flags =
++ node_group->pad[i].flags =
+ NODE_DESC_IS_OUTPUT(&node_desc[i]) ?
+ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&sd->entity, PISPBE_NUM_NODES,
+- pispbe->pad);
++ node_group->pad);
+ if (ret)
+ goto error;
+
+- ret = v4l2_device_register_subdev(&pispbe->v4l2_dev, sd);
++ ret = v4l2_device_register_subdev(&node_group->v4l2_dev, sd);
+ if (ret)
+ goto error;
+
+@@ -1522,36 +1560,43 @@ error:
+ return ret;
+ }
+
+-static int pispbe_init_devices(struct pispbe_dev *pispbe)
++static int pispbe_init_group(struct pispbe_dev *pispbe, unsigned int id)
+ {
++ struct pispbe_node_group *node_group = &pispbe->node_group[id];
+ struct v4l2_device *v4l2_dev;
+ struct media_device *mdev;
+ unsigned int num_regist;
+ int ret;
+
++ node_group->id = id;
++ node_group->pispbe = pispbe;
++ node_group->streaming_map = 0;
++
++ dev_dbg(pispbe->dev, "Register nodes for group %u\n", id);
++
+ /* Register v4l2_device and media_device */
+- mdev = &pispbe->mdev;
+- mdev->hw_revision = pispbe->hw_version;
+- mdev->dev = pispbe->dev;
++ mdev = &node_group->mdev;
++ mdev->hw_revision = node_group->pispbe->hw_version;
++ mdev->dev = node_group->pispbe->dev;
+ strscpy(mdev->model, PISPBE_NAME, sizeof(mdev->model));
+ media_device_init(mdev);
+
+- v4l2_dev = &pispbe->v4l2_dev;
+- v4l2_dev->mdev = &pispbe->mdev;
++ v4l2_dev = &node_group->v4l2_dev;
++ v4l2_dev->mdev = &node_group->mdev;
+ strscpy(v4l2_dev->name, PISPBE_NAME, sizeof(v4l2_dev->name));
+
+- ret = v4l2_device_register(pispbe->dev, v4l2_dev);
++ ret = v4l2_device_register(pispbe->dev, &node_group->v4l2_dev);
+ if (ret)
+ goto err_media_dev_cleanup;
+
+ /* Register the PISPBE subdevice. */
+- ret = pispbe_init_subdev(pispbe);
++ ret = pispbe_init_subdev(node_group);
+ if (ret)
+ goto err_unregister_v4l2;
+
+ /* Create device video nodes */
+ for (num_regist = 0; num_regist < PISPBE_NUM_NODES; num_regist++) {
+- ret = pispbe_init_node(pispbe, num_regist);
++ ret = pispbe_init_node(node_group, num_regist);
+ if (ret)
+ goto err_unregister_nodes;
+ }
+@@ -1560,12 +1605,12 @@ static int pispbe_init_devices(struct pi
+ if (ret)
+ goto err_unregister_nodes;
+
+- pispbe->config =
++ node_group->config =
+ dma_alloc_coherent(pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- &pispbe->config_dma_addr, GFP_KERNEL);
+- if (!pispbe->config) {
++ &node_group->config_dma_addr, GFP_KERNEL);
++ if (!node_group->config) {
+ dev_err(pispbe->dev, "Unable to allocate cached config buffers.\n");
+ ret = -ENOMEM;
+ goto err_unregister_mdev;
+@@ -1577,11 +1622,11 @@ err_unregister_mdev:
+ media_device_unregister(mdev);
+ err_unregister_nodes:
+ while (num_regist-- > 0) {
+- video_unregister_device(&pispbe->node[num_regist].vfd);
+- vb2_queue_release(&pispbe->node[num_regist].queue);
++ video_unregister_device(&node_group->node[num_regist].vfd);
++ vb2_queue_release(&node_group->node[num_regist].queue);
+ }
+- v4l2_device_unregister_subdev(&pispbe->sd);
+- media_entity_cleanup(&pispbe->sd.entity);
++ v4l2_device_unregister_subdev(&node_group->sd);
++ media_entity_cleanup(&node_group->sd.entity);
+ err_unregister_v4l2:
+ v4l2_device_unregister(v4l2_dev);
+ err_media_dev_cleanup:
+@@ -1589,31 +1634,33 @@ err_media_dev_cleanup:
+ return ret;
+ }
+
+-static void pispbe_destroy_devices(struct pispbe_dev *pispbe)
++static void pispbe_destroy_node_group(struct pispbe_node_group *node_group)
+ {
+- if (pispbe->config) {
+- dma_free_coherent(pispbe->dev,
++ struct pispbe_dev *pispbe = node_group->pispbe;
++
++ if (node_group->config) {
++ dma_free_coherent(node_group->pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- pispbe->config,
+- pispbe->config_dma_addr);
++ node_group->config,
++ node_group->config_dma_addr);
+ }
+
+ dev_dbg(pispbe->dev, "Unregister from media controller\n");
+
+- v4l2_device_unregister_subdev(&pispbe->sd);
+- media_entity_cleanup(&pispbe->sd.entity);
+- media_device_unregister(&pispbe->mdev);
++ v4l2_device_unregister_subdev(&node_group->sd);
++ media_entity_cleanup(&node_group->sd.entity);
++ media_device_unregister(&node_group->mdev);
+
+ for (int i = PISPBE_NUM_NODES - 1; i >= 0; i--) {
+- video_unregister_device(&pispbe->node[i].vfd);
+- vb2_queue_release(&pispbe->node[i].queue);
+- mutex_destroy(&pispbe->node[i].node_lock);
+- mutex_destroy(&pispbe->node[i].queue_lock);
++ video_unregister_device(&node_group->node[i].vfd);
++ vb2_queue_release(&node_group->node[i].queue);
++ mutex_destroy(&node_group->node[i].node_lock);
++ mutex_destroy(&node_group->node[i].queue_lock);
+ }
+
+- media_device_cleanup(&pispbe->mdev);
+- v4l2_device_unregister(&pispbe->v4l2_dev);
++ media_device_cleanup(&node_group->mdev);
++ v4l2_device_unregister(&node_group->v4l2_dev);
+ }
+
+ static int pispbe_runtime_suspend(struct device *dev)
+@@ -1681,9 +1728,13 @@ static int pispbe_hw_init(struct pispbe_
+ return 0;
+ }
+
+-/* Probe the ISP-BE hardware block, as a single platform device. */
++/*
++ * Probe the ISP-BE hardware block, as a single platform device.
++ * This will instantiate multiple "node groups" each with many device nodes.
++ */
+ static int pispbe_probe(struct platform_device *pdev)
+ {
++ unsigned int num_groups = 0;
+ struct pispbe_dev *pispbe;
+ int ret;
+
+@@ -1738,17 +1789,26 @@ static int pispbe_probe(struct platform_
+ if (ret)
+ goto pm_runtime_suspend_err;
+
+- ret = pispbe_init_devices(pispbe);
+- if (ret)
+- goto disable_devs_err;
++ /*
++ * Initialise and register devices for each node_group, including media
++ * device
++ */
++ for (num_groups = 0;
++ num_groups < PISPBE_NUM_NODE_GROUPS;
++ num_groups++) {
++ ret = pispbe_init_group(pispbe, num_groups);
++ if (ret)
++ goto disable_nodes_err;
++ }
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+ return 0;
+
+-disable_devs_err:
+- pispbe_destroy_devices(pispbe);
++disable_nodes_err:
++ while (num_groups-- > 0)
++ pispbe_destroy_node_group(&pispbe->node_group[num_groups]);
+ pm_runtime_suspend_err:
+ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_disable_err:
+@@ -1762,7 +1822,8 @@ static int pispbe_remove(struct platform
+ {
+ struct pispbe_dev *pispbe = platform_get_drvdata(pdev);
+
+- pispbe_destroy_devices(pispbe);
++ for (int i = PISPBE_NUM_NODE_GROUPS - 1; i >= 0; i--)
++ pispbe_destroy_node_group(&pispbe->node_group[i]);
+
+ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_dont_use_autosuspend(pispbe->dev);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch b/target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch
new file mode 100644
index 0000000000..0586f5c620
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch
@@ -0,0 +1,36 @@
+From f372f2854279828a33b9b3debc233d366fb4c124 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Mon, 8 Jul 2024 11:47:49 +0100
+Subject: [PATCH 1161/1215] media: pisp_be: Re-introduce video node offset
+
+Offset the backend dev-nodes starting at /dev/video20
+onwards to maintain backward compatibility with the
+pre-upstreamed kernel driver.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/platform/raspberrypi/pisp_be/pisp_be.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
+@@ -21,6 +21,9 @@
+
+ #include "pisp_be_formats.h"
+
++/* Offset to use when registering the /dev/videoX node */
++#define PISPBE_VIDEO_NODE_OFFSET 20
++
+ /* Maximum number of config buffers possible */
+ #define PISP_BE_NUM_CONFIG_BUFFERS VB2_MAX_FRAME
+
+@@ -1484,7 +1487,8 @@ static int pispbe_init_node(struct pispb
+ goto err_unregister_queue;
+ }
+
+- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
++ ret = video_register_device(vdev, VFL_TYPE_VIDEO,
++ PISPBE_VIDEO_NODE_OFFSET);
+ if (ret) {
+ dev_err(pispbe->dev,
+ "Failed to register video %s device node\n",
diff --git a/target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch b/target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch
new file mode 100644
index 0000000000..38c1d3b9b6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch
@@ -0,0 +1,158 @@
+From 6e4ad40811170653431fc40a6fdc3f486863b40f Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 4 Jul 2024 18:15:00 +0100
+Subject: [PATCH 1163/1215] dts: Make camN_reg and camN_reg_gpio overrides
+ generic
+
+The camera regulator GPIO can be used for other purposes,
+so the camN_reg override to allow disabling is potentially
+useful on any platform.
+camN_gpio is less useful, but isn't invalid.
+
+Move these overrides from the CM dt files to bcm270x-rpi.dtsi
+and bcm2712-rpi.dtsi.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi | 4 ----
+ .../arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts | 4 ----
+ arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi | 7 +++++++
+ .../arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts | 4 ----
+ .../arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts | 7 -------
+ .../boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 5 -----
+ arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi | 8 ++++++++
+ arch/arm/boot/dts/overlays/README | 20 +++++++++----------
+ 8 files changed, 25 insertions(+), 34 deletions(-)
+
+--- a/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi
++++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi
+@@ -19,9 +19,5 @@ i2c_vc: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts
+@@ -211,9 +211,5 @@ i2c_csi_dsi0: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi
++++ b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi
+@@ -111,6 +111,13 @@
+ <&csi0>, "sync-gpios:4",
+ <&csi0>, "sync-gpios:8=", <GPIO_ACTIVE_LOW>;
+
++ cam0_reg = <&cam0_reg>,"status";
++ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
++ <&cam0_reg>,"gpio:0=", <&gpio>;
++ cam1_reg = <&cam1_reg>,"status";
++ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
++ <&cam1_reg>,"gpio:0=", <&gpio>;
++
+ strict_gpiod = <&chosen>, "bootargs=pinctrl_bcm2835.persist_gpio_outputs=n";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts
+@@ -211,9 +211,5 @@ i2c_csi_dsi0: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts
+@@ -498,13 +498,6 @@ i2c_csi_dsi0: &i2c0 {
+ <&ant2>, "output-high?=off",
+ <&ant2>, "output-low?=on";
+
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4",
+- <&cam0_reg>,"gpio:0=", <&gpio>;
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4",
+- <&cam1_reg>,"gpio:0=", <&gpio>;
+-
+ pcie_tperst_clk_ms = <&pcie0>,"brcm,tperst-clk-ms:0";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts
+@@ -289,10 +289,5 @@ i2c_csi_dsi0: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+-
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -106,6 +106,14 @@
+ nvmem_priv_rw = <&nvmem_priv>,"rw?";
+ nvmem_mac_rw = <&nvmem_mac>,"rw?";
+ strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
++
++ cam0_reg = <&cam0_reg>,"status";
++ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
++ <&cam0_reg>,"gpio:0=", <&gpio>;
++ cam1_reg = <&cam1_reg>,"status";
++ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
++ <&cam1_reg>,"gpio:0=", <&gpio>;
++
+ };
+ };
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -171,21 +171,21 @@ Params:
+ button_debounce Set the debounce delay (in ms) on the power/
+ shutdown button (default 50ms)
+
+- cam0_reg Enables CAM 0 regulator.
+- Only required on CM1 & 3.
++ cam0_reg Controls CAM 0 regulator.
++ Disabled by default on CM1 & 3.
++ Enabled by default on all other boards.
+
+ cam0_reg_gpio Set GPIO for CAM 0 regulator.
+- Default 31 on CM1, 3, and 4S.
+- Default of GPIO expander 5 on CM4, but override
+- switches to normal GPIO.
++ NB override switches to the normal GPIO driver,
++ even if the original was on the GPIO expander.
+
+- cam1_reg Enables CAM 1 regulator.
+- Only required on CM1 & 3.
++ cam1_reg Controls CAM 1 regulator.
++ Disabled by default on CM1 & 3.
++ Enabled by default on all other boards.
+
+ cam1_reg_gpio Set GPIO for CAM 1 regulator.
+- Default 3 on CM1, 3, and 4S.
+- Default of GPIO expander 5 on CM4, but override
+- switches to normal GPIO.
++ NB override switches to the normal GPIO driver,
++ even if the original was on the GPIO expander.
+
+ cam0_sync Enable a GPIO to reflect frame sync from CSI0,
+ going high on frame start, and low on frame end.
diff --git a/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch b/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch
new file mode 100644
index 0000000000..487e508ea4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch
@@ -0,0 +1,108 @@
+From afd949f5f64d224cf7a016ef933257842bc170ab Mon Sep 17 00:00:00 2001
+From: Richard Oliver <richard.oliver@raspberrypi.com>
+Date: Fri, 24 May 2024 10:34:45 +0100
+Subject: [PATCH 1164/1215] spi: dt-bindings: Add RPI RP2040 GPIO Bridge
+
+Add YAML device tree bindings for the Raspberry Pi RP2040 GPIO Bridge.
+
+Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
+---
+ .../spi/raspberrypi,rp2040-gpio-bridge.yaml | 77 +++++++++++++++++++
+ MAINTAINERS | 5 ++
+ 2 files changed, 82 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
+@@ -0,0 +1,77 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/spi/raspberrypi,rp2040-gpio-bridge.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Raspberry Pi RP2040 GPIO Bridge
++
++maintainers:
++ - Raspberry Pi <kernel-list@raspberrypi.com>
++
++description: |-
++ The Raspberry Pi PR2040 GPIO bridge can be used as a GPIO expander and
++ Tx-only SPI master.
++
++properties:
++ reg:
++ description: I2C slave address
++ const: 0x40
++
++ compatible:
++ const: raspberrypi,rp2040-gpio-bridge
++
++ power-supply:
++ description: Phandle to the regulator that powers the RP2040.
++
++ '#address-cells':
++ const: 1
++
++ '#size-cells':
++ const: 0
++
++ '#gpio-cells':
++ const: 2
++
++ gpio-controller: true
++
++ fast_xfer_requires_i2c_lock:
++ description: Set if I2C bus should be locked during fast transfer.
++
++ fast_xfer_recv_gpio_base:
++ description: RP2040 GPIO base for fast transfer pair.
++
++ fast_xfer-gpios:
++ description: RP1 GPIOs to use for fast transfer clock and data.
++
++required:
++ - reg
++ - compatible
++ - power-supply
++ - '#gpio-cells'
++ - gpio-controller
++
++additionalProperties: false
++
++examples:
++ - |
++ i2c {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spi@40 {
++ reg = <0x40>;
++ compatible = "raspberrypi,rp2040-gpio-bridge";
++ status = "disabled";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ power-supply = <&cam_dummy_reg>;
++
++ #gpio-cells = <2>;
++ gpio-controller;
++ };
++ };
++
++...
++
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18027,6 +18027,11 @@ F: drivers/ras/
+ F: include/linux/ras.h
+ F: include/ras/ras_event.h
+
++RASPBERRY PI RP2040 GPIO BRIDGE DRIVER
++M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
++S: Maintained
++F: Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
++
+ RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
+ L: linux-wireless@vger.kernel.org
+ S: Orphan
diff --git a/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch b/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch
new file mode 100644
index 0000000000..68e2ef6007
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch
@@ -0,0 +1,1288 @@
+From 99ae83f1944f47d4338ef7a6f02536927fc6ce57 Mon Sep 17 00:00:00 2001
+From: Richard Oliver <richard.oliver@raspberrypi.com>
+Date: Tue, 21 May 2024 13:47:23 +0100
+Subject: [PATCH 1165/1215] spi: Add a driver for the RPI RP2040 GPIO bridge
+
+The Raspberry Pi RP2040 GPIO bridge is an I2C-attached device exposing
+both a Tx-only SPI controller, and a GPIO controller.
+
+Due to the relative difference in transfer rates between standard-mode
+I2C and SPI, the GPIO bridge makes use of 12 MiB of non-volatile storage
+to cache repeated transfers. This cache is arranged in ~8 KiB blocks and
+is addressed by the MD5 digest of the data contained therein.
+
+Optionally, this driver is able to take advantage of Raspberry Pi RP1
+GPIOs to achieve faster than I2C data transfer rates.
+
+Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
+---
+ MAINTAINERS | 1 +
+ drivers/spi/Kconfig | 12 +
+ drivers/spi/Makefile | 1 +
+ drivers/spi/spi-rp2040-gpio-bridge.c | 1219 ++++++++++++++++++++++++++
+ 4 files changed, 1233 insertions(+)
+ create mode 100644 drivers/spi/spi-rp2040-gpio-bridge.c
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18031,6 +18031,7 @@ RASPBERRY PI RP2040 GPIO BRIDGE DRIVER
+ M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
+ S: Maintained
+ F: Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
++F: drivers/spi/spi-rp2040-gpio-bridge.c
+
+ RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
+ L: linux-wireless@vger.kernel.org
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -846,6 +846,18 @@ config SPI_RB4XX
+ help
+ SPI controller driver for the Mikrotik RB4xx series boards.
+
++config SPI_RP2040_GPIO_BRIDGE
++ tristate "Raspberry Pi RP2040 GPIO Bridge"
++ depends on I2C && SPI && GPIOLIB
++ help
++ Support for the Raspberry Pi RP2040 GPIO bridge.
++
++ This driver provides support for the Raspberry Pi PR2040 GPIO bridge.
++ It can be used as a GPIO expander and a Tx-only SPI master.
++
++ Optionally, this driver is able to take advantage of Raspberry Pi RP1
++ GPIOs to achieve faster than I2C data transfer rates.
++
+ config SPI_RPCIF
+ tristate "Renesas RPC-IF SPI driver"
+ depends on RENESAS_RPCIF
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -115,6 +115,7 @@ obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockc
+ obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o
+ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
+ obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
++obj-$(CONFIG_SPI_RP2040_GPIO_BRIDGE) += spi-rp2040-gpio-bridge.o
+ obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
+ obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
+ obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o
+--- /dev/null
++++ b/drivers/spi/spi-rp2040-gpio-bridge.c
+@@ -0,0 +1,1219 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * RP2040 GPIO Bridge
++ *
++ * Copyright (C) 2023, 2024, Raspberry Pi Ltd
++ */
++
++#include <crypto/hash.h>
++#include <linux/crypto.h>
++#include <linux/delay.h>
++#include <linux/firmware.h>
++#include <linux/gpio/driver.h>
++#include <linux/i2c.h>
++#include <linux/kernel.h>
++#include <linux/minmax.h>
++#include <linux/of_address.h>
++#include <linux/pm_runtime.h>
++#include <linux/spi/spi.h>
++#include <linux/stddef.h>
++#include <linux/types.h>
++
++#define MODULE_NAME "rp2040-gpio-bridge"
++
++#define I2C_RETRIES 4U
++
++#define ONE_KIB 1024U
++#define MD5_SUFFIX_SIZE 9U
++
++#define RP2040_GBDG_FLASH_BLOCK_SIZE (8U * ONE_KIB)
++#define RP2040_GBDG_BLOCK_SIZE (RP2040_GBDG_FLASH_BLOCK_SIZE - MD5_SUFFIX_SIZE)
++
++/*
++ * 1MiB transfer size is an arbitrary limit
++ * Max value is 4173330 (using a single manifest)
++ */
++#define MAX_TRANSFER_SIZE (1024U * ONE_KIB)
++
++#define HALF_BUFFER (4U * ONE_KIB)
++
++#define STATUS_SIZE 4
++#define MD5_DIGEST_SIZE 16
++#define VERSION_SIZE 4
++#define ID_SIZE 8
++#define TOTAL_RD_HDR_SIZE \
++ (STATUS_SIZE + MD5_DIGEST_SIZE + VERSION_SIZE + ID_SIZE)
++
++struct rp2040_gbdg_device_info {
++ u8 md5[MD5_DIGEST_SIZE];
++ u64 id;
++ u32 version;
++ u32 status;
++};
++
++static_assert(sizeof(struct rp2040_gbdg_device_info) == TOTAL_RD_HDR_SIZE);
++
++#define MANIFEST_UNIT_SIZE 16
++static_assert(MD5_DIGEST_SIZE == MANIFEST_UNIT_SIZE);
++#define MANIFEST_HEADER_UNITS 1
++#define MANIFEST_DATA_UNITS \
++ DIV_ROUND_UP(MAX_TRANSFER_SIZE, RP2040_GBDG_BLOCK_SIZE)
++
++#define STATUS_BUSY 0x01
++
++#define DIRECT_PREFIX 0x00
++#define DIRECT_CMD_CS 0x07
++#define DIRECT_CMD_EMIT 0x08
++
++#define WRITE_DATA_PREFIX 0x80
++#define WRITE_DATA_PREFIX_SIZE 1
++
++#define FIXED_SIZE_CMD_PREFIX 0x81
++
++#define WRITE_DATA_UPPER_PREFIX 0x82
++#define WRITE_DATA_UPPER_PREFIX_SIZE 1
++
++#define NUM_GPIO 24
++
++enum rp2040_gbdg_fixed_size_commands {
++ /* 10-byte commands */
++ CMD_SAVE_CACHE = 0x07,
++ CMD_SEND_RB = 0x08,
++ CMD_GPIO_ST_CL = 0x0b,
++ CMD_GPIO_OE = 0x0c,
++ CMD_DAT_RECV = 0x0d,
++ CMD_DAT_EMIT = 0x0e,
++ /* 18-byte commands */
++ CMD_READ_CSUM = 0x11,
++ CMD_SEND_MANI = 0x13,
++};
++
++struct rp2040_gbdg {
++ struct spi_controller *controller;
++
++ struct i2c_client *client;
++ struct crypto_shash *shash;
++ struct shash_desc *shash_desc;
++
++ struct regulator *regulator;
++
++ struct gpio_chip gc;
++ u32 gpio_requested;
++ u32 gpio_direction;
++
++ bool fast_xfer_requires_i2c_lock;
++ struct gpio_descs *fast_xfer_gpios;
++ u32 fast_xfer_recv_gpio_base;
++ u8 fast_xfer_data_index;
++ u8 fast_xfer_clock_index;
++ void __iomem *gpio_base;
++ void __iomem *rio_base;
++
++ bool bypass_cache;
++
++ u8 buffer[2 + HALF_BUFFER];
++ u8 manifest_prep[(MANIFEST_HEADER_UNITS + MANIFEST_DATA_UNITS) *
++ MANIFEST_UNIT_SIZE];
++};
++
++static int rp2040_gbdg_gpio_dir_in(struct gpio_chip *gc, unsigned int offset);
++static void rp2040_gbdg_gpio_set(struct gpio_chip *gc, unsigned int offset,
++ int value);
++static int rp2040_gbdg_fast_xfer(struct rp2040_gbdg *priv_data, const u8 *data,
++ size_t len);
++
++static int rp2040_gbdg_rp1_calc_offsets(u8 gpio, size_t *bank_offset,
++ u8 *shift_offset)
++{
++ if (!bank_offset || !shift_offset || gpio >= 54)
++ return -EINVAL;
++ if (gpio < 28) {
++ *bank_offset = 0x0000;
++ *shift_offset = gpio;
++ } else if (gpio < 34) {
++ *bank_offset = 0x4000;
++ *shift_offset = gpio - 28;
++ } else {
++ *bank_offset = 0x8000;
++ *shift_offset = gpio - 34;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_calc_mux_offset(u8 gpio, size_t *offset)
++{
++ size_t bank_offset;
++ u8 shift_offset;
++ int ret;
++
++ ret = rp2040_gbdg_rp1_calc_offsets(gpio, &bank_offset, &shift_offset);
++ if (ret)
++ return ret;
++ *offset = bank_offset + shift_offset * 8 + 0x4;
++
++ return 0;
++}
++
++static int rp2040_gbdg_rp1_read_mux(struct rp2040_gbdg *priv_data, u8 gpio,
++ u32 *data)
++{
++ size_t offset;
++ int ret;
++
++ ret = rp2040_gbdg_calc_mux_offset(gpio, &offset);
++ if (ret)
++ return ret;
++
++ *data = readl(priv_data->gpio_base + offset);
++
++ return 0;
++}
++
++static int rp2040_gbdg_rp1_write_mux(struct rp2040_gbdg *priv_data, u8 gpio,
++ u32 val)
++{
++ size_t offset;
++ int ret;
++
++ ret = rp2040_gbdg_calc_mux_offset(gpio, &offset);
++ if (ret)
++ return ret;
++
++ writel(val, priv_data->gpio_base + offset);
++
++ return 0;
++}
++
++static size_t rp2040_gbdg_max_transfer_size(struct spi_device *spi)
++{
++ return MAX_TRANSFER_SIZE;
++}
++
++static int rp2040_gbdg_get_device_info(struct i2c_client *client,
++ struct rp2040_gbdg_device_info *info)
++{
++ u8 buf[TOTAL_RD_HDR_SIZE];
++ u8 retries = I2C_RETRIES;
++ u8 *read_pos = buf;
++ size_t field_size;
++ int ret;
++
++ do {
++ ret = i2c_master_recv(client, buf, sizeof(buf));
++ if (!retries--)
++ break;
++ } while (ret == -ETIMEDOUT);
++
++ if (ret != sizeof(buf))
++ return ret < 0 ? ret : -EIO;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, status);
++ memcpy(&info->status, read_pos, field_size);
++ read_pos += field_size;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, md5);
++ memcpy(&info->md5, read_pos, field_size);
++ read_pos += field_size;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, version);
++ memcpy(&info->version, read_pos, field_size);
++ read_pos += field_size;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, id);
++ memcpy(&info->id, read_pos, field_size);
++
++ return 0;
++}
++
++static int rp2040_gbdg_poll_device_info(struct i2c_client *client,
++ struct rp2040_gbdg_device_info *info)
++{
++ struct rp2040_gbdg_device_info itnl;
++ int ret;
++
++ itnl.status = STATUS_BUSY;
++
++ while (itnl.status & STATUS_BUSY) {
++ ret = rp2040_gbdg_get_device_info(client, &itnl);
++ if (ret)
++ return ret;
++ }
++ memcpy(info, &itnl, sizeof(itnl));
++
++ return 0;
++}
++
++static int rp2040_gbdg_get_buffer_hash(struct i2c_client *client, u8 *md5)
++{
++ struct rp2040_gbdg_device_info info;
++ int ret;
++
++ ret = rp2040_gbdg_poll_device_info(client, &info);
++ if (ret)
++ return ret;
++
++ memcpy(md5, info.md5, MD5_DIGEST_SIZE);
++
++ return 0;
++}
++
++static int rp2040_gbdg_wait_until_free(struct i2c_client *client, u8 *status)
++{
++ struct rp2040_gbdg_device_info info;
++ int ret;
++
++ ret = rp2040_gbdg_poll_device_info(client, &info);
++ if (ret)
++ return ret;
++
++ if (status)
++ *status = info.status;
++
++ return 0;
++}
++
++static int rp2040_gbdg_i2c_send(struct i2c_client *client, const u8 *buf,
++ size_t len)
++{
++ u8 retries = I2C_RETRIES;
++ int ret;
++
++ ret = rp2040_gbdg_wait_until_free(client, NULL);
++ if (ret) {
++ dev_err(&client->dev,
++ "%s() rp2040_gbdg_wait_until_free failed\n", __func__);
++ return ret;
++ }
++
++ do {
++ ret = i2c_master_send(client, buf, len);
++ if (!retries--)
++ break;
++ } while (ret == -ETIMEDOUT);
++
++ if (ret != len) {
++ dev_err(&client->dev, "%s() i2c_master_send returned %d\n",
++ __func__, ret);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_10byte_cmd(struct i2c_client *client, u8 cmd, u32 addr,
++ u32 len)
++{
++ u8 buffer[10];
++
++ buffer[0] = FIXED_SIZE_CMD_PREFIX;
++ buffer[1] = cmd;
++ memcpy(&buffer[2], &addr, sizeof(addr));
++ memcpy(&buffer[6], &len, sizeof(len));
++
++ return rp2040_gbdg_i2c_send(client, buffer, sizeof(buffer));
++}
++
++static int rp2040_gbdg_18byte_cmd(struct i2c_client *client, u8 cmd,
++ const u8 *digest)
++{
++ u8 buffer[18];
++
++ buffer[0] = FIXED_SIZE_CMD_PREFIX;
++ buffer[1] = cmd;
++ memcpy(&buffer[2], digest, MD5_DIGEST_SIZE);
++
++ return rp2040_gbdg_i2c_send(client, buffer, sizeof(buffer));
++}
++
++static int rp2040_gbdg_block_hash(struct rp2040_gbdg *priv_data, const u8 *data,
++ size_t len, u8 *out)
++{
++ size_t remaining = RP2040_GBDG_BLOCK_SIZE;
++ size_t pad;
++ int ret;
++
++ static const u8 padding[64] = {
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF,
++ };
++
++ if (len > RP2040_GBDG_BLOCK_SIZE) {
++ return -EMSGSIZE;
++ } else if (len == RP2040_GBDG_BLOCK_SIZE) {
++ return crypto_shash_digest(priv_data->shash_desc, data, len,
++ out);
++ } else {
++ ret = crypto_shash_init(priv_data->shash_desc);
++ if (ret)
++ return ret;
++
++ ret = crypto_shash_update(priv_data->shash_desc, data, len);
++ if (ret)
++ return ret;
++ remaining -= len;
++
++ /* Pad up-to a 64-byte boundary, unless that takes us over. */
++ pad = round_up(len, 64);
++ if (pad != len && pad < RP2040_GBDG_BLOCK_SIZE) {
++ ret = crypto_shash_update(priv_data->shash_desc,
++ padding, pad - len);
++ if (ret)
++ return ret;
++ remaining -= (pad - len);
++ }
++
++ /* Pad up-to RP2040_GBDG_BLOCK_SIZE in, preferably, 64-byte chunks */
++ while (remaining) {
++ pad = min_t(size_t, remaining, (size_t)64U);
++ ret = crypto_shash_update(priv_data->shash_desc,
++ padding, pad);
++ if (ret)
++ return ret;
++ remaining -= pad;
++ }
++ return crypto_shash_final(priv_data->shash_desc, out);
++ }
++}
++
++static int rp2040_gbdg_set_remote_buffer_fast(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++ if (!priv_data->fast_xfer_gpios)
++ return -EIO;
++
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_DAT_RECV,
++ priv_data->fast_xfer_recv_gpio_base, len);
++ if (ret) {
++ dev_err(&client->dev, "%s() failed to enter fast data mode\n",
++ __func__);
++ return ret;
++ }
++
++ return rp2040_gbdg_fast_xfer(priv_data, data, len);
++}
++
++static int rp2040_gbdg_set_remote_buffer_i2c(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ unsigned int write_len;
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++
++ priv_data->buffer[0] = WRITE_DATA_PREFIX;
++ write_len = min(len, HALF_BUFFER);
++ memcpy(&priv_data->buffer[1], data, write_len);
++
++ ret = rp2040_gbdg_i2c_send(client, priv_data->buffer, write_len + 1);
++ if (ret)
++ return ret;
++
++ len -= write_len;
++ data += write_len;
++
++ if (!len)
++ return 0;
++
++ priv_data->buffer[0] = WRITE_DATA_UPPER_PREFIX;
++ memcpy(&priv_data->buffer[1], data, len);
++ ret = rp2040_gbdg_i2c_send(client, priv_data->buffer, len + 1);
++
++ return ret;
++}
++
++static int rp2040_gbdg_set_remote_buffer(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ if (priv_data->fast_xfer_gpios)
++ return rp2040_gbdg_set_remote_buffer_fast(priv_data, data, len);
++ else
++ return rp2040_gbdg_set_remote_buffer_i2c(priv_data, data, len);
++}
++
++/* Loads data by checksum if available or resorts to sending byte-by-byte */
++static int rp2040_gbdg_load_block_remote(struct rp2040_gbdg *priv_data,
++ const void *data, unsigned int len,
++ u8 *digest, bool persist)
++{
++ u8 ascii_digest[MD5_DIGEST_SIZE * 2 + 1] = { 0 };
++ struct i2c_client *client = priv_data->client;
++ u8 remote_digest[MD5_DIGEST_SIZE];
++ u8 local_digest[MD5_DIGEST_SIZE];
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++
++ ret = rp2040_gbdg_block_hash(priv_data, data, len, local_digest);
++ if (ret)
++ return ret;
++
++ if (digest)
++ memcpy(digest, local_digest, MD5_DIGEST_SIZE);
++
++ /* Check if the RP2040 has the data already */
++ ret = rp2040_gbdg_18byte_cmd(client, CMD_READ_CSUM, local_digest);
++ if (ret)
++ return ret;
++
++ ret = rp2040_gbdg_get_buffer_hash(client, remote_digest);
++ if (ret)
++ return ret;
++
++ if (memcmp(local_digest, remote_digest, MD5_DIGEST_SIZE)) {
++ bin2hex(ascii_digest, local_digest, MD5_DIGEST_SIZE);
++ dev_info(&client->dev, "%s() device missing data: %s\n",
++ __func__, ascii_digest);
++ /*
++ * N.B. We're fine to send (the potentially shorter) transfer->len
++ * number of bytes here as the RP2040 will pad with 0xFF up to buffer
++ * size once we stop sending.
++ */
++ ret = rp2040_gbdg_set_remote_buffer(priv_data, data, len);
++ if (ret)
++ return ret;
++
++ /* Make sure the data actually arrived. */
++ ret = rp2040_gbdg_get_buffer_hash(client, remote_digest);
++ if (memcmp(local_digest, remote_digest, MD5_DIGEST_SIZE)) {
++ dev_err(&priv_data->client->dev,
++ "%s() unable to send data to device\n",
++ __func__);
++ return -EREMOTEIO;
++ }
++
++ if (persist) {
++ dev_info(&client->dev,
++ "%s() sent missing data to device, saving\n",
++ __func__);
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_SAVE_CACHE, 0,
++ 0);
++ if (ret)
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_block(struct rp2040_gbdg *priv_data,
++ const void *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++
++ ret = rp2040_gbdg_load_block_remote(priv_data, data, len, NULL, true);
++ if (ret)
++ return ret;
++
++ /* Remote rambuffer now has correct contents, send it */
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_SEND_RB, 0, len);
++ if (ret)
++ return ret;
++
++ /*
++ * Wait for data to have actually completed sending as we may be de-asserting CS too quickly
++ * otherwise.
++ */
++ ret = rp2040_gbdg_wait_until_free(client, NULL);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_manifest(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ static const char magic[] = "DATA_MANFST";
++ unsigned int remaining = len;
++ const u32 data_length = len;
++ u8 digest[MD5_DIGEST_SIZE];
++ u8 *digest_write_pos;
++ u8 status;
++ int ret;
++
++ memcpy(priv_data->manifest_prep, magic, sizeof(magic));
++ memcpy(priv_data->manifest_prep + sizeof(magic), &data_length,
++ sizeof(data_length));
++ digest_write_pos =
++ priv_data->manifest_prep + sizeof(magic) + sizeof(data_length);
++
++ while (remaining) {
++ unsigned int size = min(remaining, RP2040_GBDG_BLOCK_SIZE);
++
++ ret = rp2040_gbdg_block_hash(priv_data, data, size,
++ digest_write_pos);
++ if (ret)
++ return ret;
++
++ remaining -= size;
++ data += size;
++ digest_write_pos += MD5_DIGEST_SIZE;
++ }
++
++ ret = rp2040_gbdg_load_block_remote(
++ priv_data, priv_data->manifest_prep,
++ digest_write_pos - priv_data->manifest_prep, digest, true);
++ if (ret)
++ return ret;
++
++ dev_info(&client->dev, "%s() issue CMD_SEND_MANI\n", __func__);
++ ret = rp2040_gbdg_18byte_cmd(client, CMD_SEND_MANI, digest);
++ if (ret)
++ return ret;
++
++ ret = rp2040_gbdg_wait_until_free(client, &status);
++ if (ret)
++ return ret;
++
++ dev_info(&client->dev, "%s() SEND_MANI response: %02x\n", __func__,
++ status);
++
++ return status;
++}
++
++/* Precondition: correctly initialised fast_xfer_*, gpio_base, rio_base */
++static int rp2040_gbdg_fast_xfer(struct rp2040_gbdg *priv_data, const u8 *data,
++ size_t len)
++{
++ struct i2c_client *client = priv_data->client;
++ void __iomem *clock_toggle;
++ void __iomem *data_set;
++ size_t clock_bank;
++ size_t data_bank;
++ u8 clock_offset;
++ u8 data_offset;
++ u32 clock_mux;
++ u32 data_mux;
++
++ if (priv_data->fast_xfer_requires_i2c_lock)
++ i2c_lock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
++
++ rp2040_gbdg_rp1_read_mux(priv_data, priv_data->fast_xfer_data_index,
++ &data_mux);
++ rp2040_gbdg_rp1_read_mux(priv_data, priv_data->fast_xfer_clock_index,
++ &clock_mux);
++
++ gpiod_direction_output(priv_data->fast_xfer_gpios->desc[0], 1);
++ gpiod_direction_output(priv_data->fast_xfer_gpios->desc[1], 0);
++
++ rp2040_gbdg_rp1_calc_offsets(priv_data->fast_xfer_data_index,
++ &data_bank, &data_offset);
++ rp2040_gbdg_rp1_calc_offsets(priv_data->fast_xfer_clock_index,
++ &clock_bank, &clock_offset);
++
++ data_set = priv_data->rio_base + data_bank + 0x2000; /* SET offset */
++ clock_toggle =
++ priv_data->rio_base + clock_bank + 0x1000; /* XOR offset */
++
++ while (len--) {
++ /* MSB first ordering */
++ u32 d = ~(*data++) << 4U;
++ /*
++ * Clock out each bit of data, LSB first
++ * (DDR, achieves approx 5 Mbps)
++ */
++ for (size_t i = 0; i < 8; i++) {
++ /* Branchless set/clr data */
++ writel(1 << data_offset,
++ data_set + ((d <<= 1) & 0x1000) /* CLR offset */
++ );
++
++ /* Toggle the clock */
++ writel(1 << clock_offset, clock_toggle);
++ }
++ }
++
++ rp2040_gbdg_rp1_write_mux(priv_data, priv_data->fast_xfer_data_index,
++ data_mux);
++ rp2040_gbdg_rp1_write_mux(priv_data, priv_data->fast_xfer_clock_index,
++ clock_mux);
++
++ if (priv_data->fast_xfer_requires_i2c_lock)
++ i2c_unlock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_bypass(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int length)
++{
++ int ret;
++ u8 *buf;
++
++ if (priv_data->fast_xfer_gpios) {
++ ret = rp2040_gbdg_10byte_cmd(
++ priv_data->client, CMD_DAT_EMIT,
++ priv_data->fast_xfer_recv_gpio_base, length);
++ return ret ? ret :
++ rp2040_gbdg_fast_xfer(priv_data, data, length);
++ }
++
++ buf = priv_data->buffer;
++
++ while (length) {
++ unsigned int xfer = min(length, HALF_BUFFER);
++
++ buf[0] = DIRECT_PREFIX;
++ buf[1] = DIRECT_CMD_EMIT;
++ memcpy(&buf[2], data, xfer);
++ ret = rp2040_gbdg_i2c_send(priv_data->client, buf, xfer + 2);
++ if (ret)
++ return ret;
++ length -= xfer;
++ data += xfer;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_cached(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int length)
++{
++ int ret;
++
++ /*
++ * Caching mechanism divides data into '8KiB - 9' (8183 byte)
++ * 'RP2040_GBDG_BLOCK_SIZE' blocks.
++ *
++ * If there's a large amount of data to send, instead, attempt to make use
++ * of a manifest.
++ */
++ if (length > (2 * RP2040_GBDG_BLOCK_SIZE)) {
++ if (!rp2040_gbdg_transfer_manifest(priv_data, data, length))
++ return 0;
++ }
++
++ while (length) {
++ unsigned int xfer = min(length, RP2040_GBDG_BLOCK_SIZE);
++
++ ret = rp2040_gbdg_transfer_block(priv_data, data, xfer);
++ if (ret)
++ return ret;
++ length -= xfer;
++ data += xfer;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_one(struct spi_controller *ctlr,
++ struct spi_device *spi,
++ struct spi_transfer *transfer)
++{
++ /* All transfers are performed in a synchronous manner. As such, return '0'
++ * on success or -ve on failure. (Returning +ve indicates async xfer)
++ */
++
++ struct rp2040_gbdg *priv_data = spi_controller_get_devdata(ctlr);
++
++ if (priv_data->bypass_cache) {
++ return rp2040_gbdg_transfer_bypass(priv_data, transfer->tx_buf,
++ transfer->len);
++ } else {
++ return rp2040_gbdg_transfer_cached(priv_data, transfer->tx_buf,
++ transfer->len);
++ }
++}
++
++static void rp2040_gbdg_set_cs(struct spi_device *spi, bool enable)
++{
++ static const char disable_cs[] = { DIRECT_PREFIX, DIRECT_CMD_CS, 0x00 };
++ static const char enable_cs[] = { DIRECT_PREFIX, DIRECT_CMD_CS, 0x10 };
++ struct rp2040_gbdg *p_data;
++
++ p_data = spi_controller_get_devdata(spi->controller);
++
++ /*
++ * 'enable' is inverted and instead describes the logic level of an
++ * active-low CS.
++ */
++ rp2040_gbdg_i2c_send(p_data->client, enable ? disable_cs : enable_cs,
++ 3);
++}
++
++static int rp2040_gbdg_gpio_request(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ u32 pattern;
++ int ret;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ pattern = (1 << (offset + 8));
++ if (pattern & priv_data->gpio_requested)
++ return -EBUSY;
++
++ /* Resume if previously no gpio requested */
++ if (!priv_data->gpio_requested) {
++ ret = pm_runtime_resume_and_get(&priv_data->client->dev);
++ if (ret) {
++ dev_err(&priv_data->client->dev,
++ "%s(%u) unable to resume\n", __func__, offset);
++ return ret;
++ }
++ }
++
++ priv_data->gpio_requested |= pattern;
++
++ return 0;
++}
++
++static void rp2040_gbdg_gpio_free(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ u32 pattern;
++ int ret;
++
++ if (offset >= NUM_GPIO || !priv_data->gpio_requested)
++ return;
++
++ pattern = (1 << (offset + 8));
++
++ priv_data->gpio_requested &= ~pattern;
++ rp2040_gbdg_gpio_dir_in(gc, offset);
++ rp2040_gbdg_gpio_set(gc, offset, 0);
++
++ if (!priv_data->gpio_requested) {
++ ret = pm_runtime_put_autosuspend(&priv_data->client->dev);
++ if (ret) {
++ dev_err(&priv_data->client->dev,
++ "%s(%u) unable to put_autosuspend\n", __func__,
++ offset);
++ }
++ }
++}
++
++static int rp2040_gbdg_gpio_get_direction(struct gpio_chip *gc,
++ unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ return (priv_data->gpio_direction & (1 << (offset + 8))) ?
++ GPIO_LINE_DIRECTION_IN :
++ GPIO_LINE_DIRECTION_OUT;
++}
++
++static int rp2040_gbdg_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ priv_data->gpio_direction |= (1 << (offset + 8));
++
++ return rp2040_gbdg_10byte_cmd(client, CMD_GPIO_OE,
++ ~priv_data->gpio_direction,
++ priv_data->gpio_direction);
++}
++
++static int rp2040_gbdg_gpio_dir_out(struct gpio_chip *gc, unsigned int offset,
++ int value)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++ u32 pattern;
++ int ret;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ pattern = (1 << (offset + 8));
++
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_GPIO_ST_CL,
++ value ? pattern : 0, !value ? pattern : 0);
++ if (ret) {
++ dev_err(&client->dev, "%s(%u, %d) could not ST_CL\n", __func__,
++ offset, value);
++ return ret;
++ }
++
++ priv_data->gpio_direction &= ~pattern;
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_GPIO_OE,
++ ~priv_data->gpio_direction,
++ priv_data->gpio_direction);
++
++ return ret;
++}
++
++static int rp2040_gbdg_gpio_get(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++ struct rp2040_gbdg_device_info info;
++ int ret;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ ret = rp2040_gbdg_get_device_info(client, &info);
++ if (ret)
++ return ret;
++
++ return info.status & (1 << (offset + 8)) ? 1 : 0;
++}
++
++static void rp2040_gbdg_gpio_set(struct gpio_chip *gc, unsigned int offset,
++ int value)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++ u32 pattern;
++
++ if (offset >= NUM_GPIO)
++ return;
++
++ pattern = (1 << (offset + 8));
++ rp2040_gbdg_10byte_cmd(client, CMD_GPIO_ST_CL, value ? pattern : 0,
++ !value ? pattern : 0);
++}
++
++static int rp2040_gbdg_get_regulator(struct device *dev,
++ struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct regulator *reg = devm_regulator_get(dev, "power");
++
++ if (IS_ERR(reg))
++ return PTR_ERR(reg);
++
++ rp2040_gbdg->regulator = reg;
++
++ return 0;
++}
++
++static void rp2040_gbdg_parse_dt(struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct i2c_client *client = rp2040_gbdg->client;
++ struct of_phandle_args of_args[2] = { 0 };
++ struct device *dev = &client->dev;
++ struct device_node *dn;
++
++ rp2040_gbdg->bypass_cache =
++ of_property_read_bool(client->dev.of_node, "bypass-cache");
++
++ /* Optionally configure fast_xfer if RP1 is being used */
++ if (of_parse_phandle_with_args(client->dev.of_node, "fast_xfer-gpios",
++ "#gpio-cells", 0, &of_args[0]) ||
++ of_parse_phandle_with_args(client->dev.of_node, "fast_xfer-gpios",
++ "#gpio-cells", 1, &of_args[1])) {
++ dev_info(dev, "Could not parse fast_xfer-gpios phandles\n");
++ goto node_put;
++ }
++
++ if (of_args[0].np != of_args[1].np) {
++ dev_info(
++ dev,
++ "fast_xfer-gpios are not provided by the same controller\n");
++ goto node_put;
++ }
++ dn = of_args[0].np;
++ if (!of_device_is_compatible(dn, "raspberrypi,rp1-gpio")) {
++ dev_info(dev, "fast_xfer-gpios controller is not an rp1\n");
++ goto node_put;
++ }
++ if (of_args[0].args_count != 2 || of_args[1].args_count != 2) {
++ dev_info(dev, "of_args count is %d\n", of_args[0].args_count);
++ goto node_put;
++ }
++
++ if (of_property_read_u32_index(
++ client->dev.of_node, "fast_xfer_recv_gpio_base", 0,
++ &rp2040_gbdg->fast_xfer_recv_gpio_base)) {
++ dev_info(dev, "Could not read fast_xfer_recv_gpio_base\n");
++ goto node_put;
++ }
++
++ rp2040_gbdg->fast_xfer_gpios =
++ devm_gpiod_get_array_optional(dev, "fast_xfer", GPIOD_ASIS);
++ if (!rp2040_gbdg->fast_xfer_gpios) {
++ dev_info(dev, "Could not acquire fast_xfer-gpios\n");
++ goto node_put;
++ }
++
++ rp2040_gbdg->fast_xfer_data_index = of_args[0].args[0];
++ rp2040_gbdg->fast_xfer_clock_index = of_args[1].args[0];
++ rp2040_gbdg->fast_xfer_requires_i2c_lock = of_property_read_bool(
++ client->dev.of_node, "fast_xfer_requires_i2c_lock");
++
++ rp2040_gbdg->gpio_base = of_iomap(dn, 0);
++ if (IS_ERR_OR_NULL(rp2040_gbdg->gpio_base)) {
++ dev_info(&client->dev, "%s() unable to map gpio_base\n",
++ __func__);
++ rp2040_gbdg->gpio_base = NULL;
++ devm_gpiod_put_array(dev, rp2040_gbdg->fast_xfer_gpios);
++ rp2040_gbdg->fast_xfer_gpios = NULL;
++ goto node_put;
++ }
++
++ rp2040_gbdg->rio_base = of_iomap(dn, 1);
++ if (IS_ERR_OR_NULL(rp2040_gbdg->rio_base)) {
++ dev_info(&client->dev, "%s() unable to map rio_base\n",
++ __func__);
++ rp2040_gbdg->rio_base = NULL;
++ iounmap(rp2040_gbdg->gpio_base);
++ rp2040_gbdg->gpio_base = NULL;
++ devm_gpiod_put_array(dev, rp2040_gbdg->fast_xfer_gpios);
++ rp2040_gbdg->fast_xfer_gpios = NULL;
++ goto node_put;
++ }
++
++node_put:
++ if (of_args[0].np)
++ of_node_put(of_args[0].np);
++ if (of_args[1].np)
++ of_node_put(of_args[1].np);
++}
++
++static int rp2040_gbdg_power_off(struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct device *dev = &rp2040_gbdg->client->dev;
++ int ret;
++
++ ret = regulator_disable(rp2040_gbdg->regulator);
++ if (ret) {
++ dev_err(dev, "%s: Could not disable regulator\n", __func__);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_power_on(struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct device *dev = &rp2040_gbdg->client->dev;
++ int ret;
++
++ ret = regulator_enable(rp2040_gbdg->regulator);
++ if (ret) {
++ dev_err(dev, "%s: Could not enable regulator\n", __func__);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_probe(struct i2c_client *client)
++{
++ struct rp2040_gbdg_device_info info;
++ struct spi_controller *controller;
++ struct device *dev = &client->dev;
++ struct rp2040_gbdg *rp2040_gbdg;
++ struct device_node *np;
++ int ret;
++
++ np = dev->of_node;
++
++ controller = devm_spi_alloc_master(dev, sizeof(struct rp2040_gbdg));
++ if (!controller)
++ return dev_err_probe(dev, ENOMEM,
++ "could not alloc spi controller\n");
++
++ rp2040_gbdg = spi_controller_get_devdata(controller);
++ i2c_set_clientdata(client, rp2040_gbdg);
++ rp2040_gbdg->controller = controller;
++ rp2040_gbdg->client = client;
++
++ ret = rp2040_gbdg_get_regulator(dev, rp2040_gbdg);
++ if (ret < 0)
++ return dev_err_probe(dev, ret, "Cannot get regulator\n");
++
++ ret = rp2040_gbdg_power_on(rp2040_gbdg);
++ if (ret)
++ return dev_err_probe(dev, ret, "Could not power on device\n");
++
++ pm_runtime_set_active(dev);
++ pm_runtime_get_noresume(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_set_autosuspend_delay(dev, 1000);
++ pm_runtime_use_autosuspend(dev);
++
++ ret = rp2040_gbdg_get_device_info(client, &info);
++ if (ret) {
++ dev_err(dev, "Could not get device info\n");
++ goto err_pm;
++ }
++
++ dev_info(dev, "%s() found dev ID: %llx, fw ver. %u\n", __func__,
++ info.id, info.version);
++
++ rp2040_gbdg->shash = crypto_alloc_shash("md5", 0, 0);
++ if (IS_ERR(rp2040_gbdg->shash)) {
++ ret = PTR_ERR(rp2040_gbdg->shash);
++ dev_err(dev, "Could not allocate shash\n");
++ goto err_pm;
++ }
++
++ if (crypto_shash_digestsize(rp2040_gbdg->shash) != MD5_DIGEST_SIZE) {
++ ret = -EINVAL;
++ dev_err(dev, "error: Unexpected hash digest size\n");
++ goto err_shash;
++ }
++
++ rp2040_gbdg->shash_desc =
++ devm_kmalloc(dev,
++ sizeof(struct shash_desc) +
++ crypto_shash_descsize(rp2040_gbdg->shash),
++ 0);
++
++ if (!rp2040_gbdg->shash_desc) {
++ ret = -ENOMEM;
++ dev_err(dev,
++ "error: Could not allocate memory for shash_desc\n");
++ goto err_shash;
++ }
++ rp2040_gbdg->shash_desc->tfm = rp2040_gbdg->shash;
++
++ controller->bus_num = -1;
++ controller->num_chipselect = 1;
++ controller->mode_bits = SPI_CPOL | SPI_CPHA;
++ controller->bits_per_word_mask = SPI_BPW_MASK(8);
++ controller->min_speed_hz = 35000000;
++ controller->max_speed_hz = 35000000;
++ controller->max_transfer_size = rp2040_gbdg_max_transfer_size;
++ controller->max_message_size = rp2040_gbdg_max_transfer_size;
++ controller->transfer_one = rp2040_gbdg_transfer_one;
++ controller->set_cs = rp2040_gbdg_set_cs;
++
++ controller->dev.of_node = np;
++ controller->auto_runtime_pm = true;
++
++ ret = devm_spi_register_controller(dev, controller);
++ if (ret) {
++ dev_err(dev, "error: Could not register SPI controller\n");
++ goto err_shash;
++ }
++
++ memset(&rp2040_gbdg->gc, 0, sizeof(struct gpio_chip));
++ rp2040_gbdg->gc.parent = dev;
++ rp2040_gbdg->gc.label = MODULE_NAME;
++ rp2040_gbdg->gc.owner = THIS_MODULE;
++ rp2040_gbdg->gc.base = -1;
++ rp2040_gbdg->gc.ngpio = NUM_GPIO;
++
++ rp2040_gbdg->gc.request = rp2040_gbdg_gpio_request;
++ rp2040_gbdg->gc.free = rp2040_gbdg_gpio_free;
++ rp2040_gbdg->gc.get_direction = rp2040_gbdg_gpio_get_direction;
++ rp2040_gbdg->gc.direction_input = rp2040_gbdg_gpio_dir_in;
++ rp2040_gbdg->gc.direction_output = rp2040_gbdg_gpio_dir_out;
++ rp2040_gbdg->gc.get = rp2040_gbdg_gpio_get;
++ rp2040_gbdg->gc.set = rp2040_gbdg_gpio_set;
++ rp2040_gbdg->gc.can_sleep = true;
++
++ rp2040_gbdg->gpio_requested = 0;
++
++ /* Coming out of reset, all GPIOs are inputs */
++ rp2040_gbdg->gpio_direction = ~0;
++
++ ret = devm_gpiochip_add_data(dev, &rp2040_gbdg->gc, rp2040_gbdg);
++ if (ret) {
++ dev_err(dev, "error: Could not add data to gpiochip\n");
++ goto err_shash;
++ }
++
++ rp2040_gbdg_parse_dt(rp2040_gbdg);
++
++ pm_runtime_mark_last_busy(dev);
++ pm_runtime_put_autosuspend(dev);
++
++ return 0;
++
++err_shash:
++ crypto_free_shash(rp2040_gbdg->shash);
++err_pm:
++ pm_runtime_disable(dev);
++ pm_runtime_put_noidle(dev);
++ rp2040_gbdg_power_off(rp2040_gbdg);
++
++ return ret;
++}
++
++static void rp2040_gbdg_remove(struct i2c_client *client)
++{
++ struct rp2040_gbdg *priv_data = i2c_get_clientdata(client);
++
++ crypto_free_shash(priv_data->shash);
++
++ if (priv_data->gpio_base) {
++ iounmap(priv_data->gpio_base);
++ priv_data->gpio_base = NULL;
++ }
++ if (priv_data->rio_base) {
++ iounmap(priv_data->rio_base);
++ priv_data->rio_base = NULL;
++ }
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ rp2040_gbdg_power_off(priv_data);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct i2c_device_id rp2040_gbdg_id[] = {
++ { "rp2040-gpio-bridge", 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, rp2040_gbdg_id);
++
++static const struct of_device_id rp2040_gbdg_of_match[] = {
++ { .compatible = "raspberrypi,rp2040-gpio-bridge" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rp2040_gbdg_of_match);
++
++static int rp2040_gbdg_runtime_suspend(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++
++ return rp2040_gbdg_power_off(i2c_get_clientdata(client));
++}
++
++static int rp2040_gbdg_runtime_resume(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++
++ return rp2040_gbdg_power_on(i2c_get_clientdata(client));
++}
++
++static const struct dev_pm_ops rp2040_gbdg_pm_ops = { SET_RUNTIME_PM_OPS(
++ rp2040_gbdg_runtime_suspend, rp2040_gbdg_runtime_resume, NULL) };
++
++static struct i2c_driver rp2040_gbdg_driver = {
++ .driver = {
++ .name = MODULE_NAME,
++ .of_match_table = of_match_ptr(rp2040_gbdg_of_match),
++ .pm = &rp2040_gbdg_pm_ops,
++ },
++ .probe = rp2040_gbdg_probe,
++ .remove = rp2040_gbdg_remove,
++ .id_table = rp2040_gbdg_id,
++};
++
++module_i2c_driver(rp2040_gbdg_driver);
++
++MODULE_AUTHOR("Richard Oliver <richard.oliver@raspberrypi.com>");
++MODULE_DESCRIPTION("Raspberry Pi RP2040 GPIO Bridge");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch b/target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch
new file mode 100644
index 0000000000..85b1cf6448
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch
@@ -0,0 +1,52 @@
+From 475cddaba6b02584157e1c128a5a6858770a3d06 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 10 Jul 2024 14:47:17 +0100
+Subject: [PATCH 1166/1215] dmaengine: dw-axi-dmac: Honour snps,block-size
+
+The snps,block-size DT property declares the maximum block size for each
+channel of the dw-axi-dmac. However, the driver ignores these when
+setting max_seg_size and uses MAX_BLOCK_SIZE (4096) instead.
+
+To take advantage of the efficiencies of larger blocks, calculate the
+minimum block size across all channels and use that instead.
+
+See: https://github.com/raspberrypi/linux/issues/6256
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -1470,6 +1470,7 @@ static int dw_probe(struct platform_devi
+ struct dw_axi_dma *dw;
+ struct dw_axi_dma_hcfg *hdata;
+ struct reset_control *resets;
++ unsigned int max_seg_size;
+ unsigned int flags;
+ u32 i;
+ int ret;
+@@ -1585,9 +1586,21 @@ static int dw_probe(struct platform_devi
+ * Synopsis DesignWare AxiDMA datasheet mentioned Maximum
+ * supported blocks is 1024. Device register width is 4 bytes.
+ * Therefore, set constraint to 1024 * 4.
++ * However, if all channels specify a greater value, use that instead.
+ */
++
+ dw->dma.dev->dma_parms = &dw->dma_parms;
+- dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
++ max_seg_size = UINT_MAX;
++ for (i = 0; i < dw->hdata->nr_channels; i++) {
++ unsigned int block_size = chip->dw->hdata->block_size[i];
++
++ if (!block_size)
++ block_size = MAX_BLOCK_SIZE;
++ max_seg_size = min(block_size, max_seg_size);
++ }
++
++ dma_set_max_seg_size(&pdev->dev, max_seg_size);
++
+ platform_set_drvdata(pdev, chip);
+
+ pm_runtime_enable(chip->dev);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch b/target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch
new file mode 100644
index 0000000000..2ba494958e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch
@@ -0,0 +1,157 @@
+From e6c1e862b2b8150a419f4208e5bd7749662b16a1 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Thu, 20 Jun 2024 14:31:20 +0100
+Subject: [PATCH 1167/1215] mmc: restrict posted write counts for SD cards in
+ CQ mode
+
+Command Queueing requires Write Cache and Power off Notification support
+from the card - but using the write cache forms a contract with the host
+whereby the card expects to be told about impending power-down.
+
+The implication is that (for performance) the card can do unsafe things
+with pending write data - including reordering what gets committed to
+nonvolatile storage at what time.
+
+Exposed SD slots and platforms powered by hotpluggable means (i.e.
+Raspberry Pis) can't guarantee that surprise removal won't happen.
+
+To limit the scope for cards to invent new ways to trash filesystems,
+limit pending writes to 1 (equivalent to the non-CQ behaviour).
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/mmc/core/block.c | 11 +++++++++--
+ drivers/mmc/core/mmc.c | 1 +
+ drivers/mmc/core/queue.c | 9 +++++++++
+ drivers/mmc/core/queue.h | 1 +
+ drivers/mmc/core/sd.c | 8 ++++++++
+ include/linux/mmc/card.h | 2 ++
+ 6 files changed, 30 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -1555,6 +1555,8 @@ static void mmc_blk_cqe_complete_rq(stru
+
+ spin_lock_irqsave(&mq->lock, flags);
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ mq->in_flight[issue_type] -= 1;
+
+ put_card = (mmc_tot_in_flight(mq) == 0);
+@@ -2071,6 +2073,8 @@ static void mmc_blk_mq_complete_rq(struc
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ unsigned int nr_bytes = mqrq->brq.data.bytes_xfered;
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ if (nr_bytes) {
+ if (blk_update_request(req, BLK_STS_OK, nr_bytes))
+ blk_mq_requeue_request(req, true);
+@@ -2165,13 +2169,16 @@ static void mmc_blk_mq_poll_completion(s
+ mmc_blk_urgent_bkops(mq, mqrq);
+ }
+
+-static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type)
++static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type,
++ struct request *req)
+ {
+ unsigned long flags;
+ bool put_card;
+
+ spin_lock_irqsave(&mq->lock, flags);
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ mq->in_flight[issue_type] -= 1;
+
+ put_card = (mmc_tot_in_flight(mq) == 0);
+@@ -2205,7 +2212,7 @@ static void mmc_blk_mq_post_req(struct m
+ blk_mq_complete_request(req);
+ }
+
+- mmc_blk_mq_dec_in_flight(mq, issue_type);
++ mmc_blk_mq_dec_in_flight(mq, issue_type, req);
+ }
+
+ void mmc_blk_mq_recovery(struct mmc_queue *mq)
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -1922,6 +1922,7 @@ static int mmc_init_card(struct mmc_host
+ pr_info("%s: Host Software Queue enabled\n",
+ mmc_hostname(host));
+ }
++ card->max_posted_writes = card->ext_csd.cmdq_depth;
+ }
+ }
+
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -268,6 +268,11 @@ static blk_status_t mmc_mq_queue_rq(stru
+ spin_unlock_irq(&mq->lock);
+ return BLK_STS_RESOURCE;
+ }
++ if (host->cqe_enabled && req_op(req) == REQ_OP_WRITE &&
++ mq->pending_writes >= card->max_posted_writes) {
++ spin_unlock_irq(&mq->lock);
++ return BLK_STS_RESOURCE;
++ }
+ break;
+ default:
+ /*
+@@ -284,6 +289,8 @@ static blk_status_t mmc_mq_queue_rq(stru
+ /* Parallel dispatch of requests is not supported at the moment */
+ mq->busy = true;
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes++;
+ mq->in_flight[issue_type] += 1;
+ get_card = (mmc_tot_in_flight(mq) == 1);
+ cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1);
+@@ -323,6 +330,8 @@ static blk_status_t mmc_mq_queue_rq(stru
+ bool put_card = false;
+
+ spin_lock_irq(&mq->lock);
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ mq->in_flight[issue_type] -= 1;
+ if (mmc_tot_in_flight(mq) == 0)
+ put_card = true;
+--- a/drivers/mmc/core/queue.h
++++ b/drivers/mmc/core/queue.h
+@@ -79,6 +79,7 @@ struct mmc_queue {
+ struct request_queue *queue;
+ spinlock_t lock;
+ int in_flight[MMC_ISSUE_MAX];
++ int pending_writes;
+ unsigned int cqe_busy;
+ #define MMC_CQE_DCMD_BUSY BIT(0)
+ bool busy;
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1104,6 +1104,14 @@ static int sd_parse_ext_reg_perf(struct
+ pr_debug("%s: Command Queue supported depth %u\n",
+ mmc_hostname(card->host),
+ card->ext_csd.cmdq_depth);
++ /*
++ * If CQ is enabled, there is a contract between host and card such that VDD will
++ * be maintained and removed only if a power off notification is provided.
++ * An SD card in an accessible slot means surprise removal is a possibility.
++ * As a middle ground, limit max posted writes to 1 unless the card is "hardwired".
++ */
++ if (mmc_card_is_removable(card->host))
++ card->max_posted_writes = 1;
+ }
+
+ card->ext_perf.fno = fno;
+--- a/include/linux/mmc/card.h
++++ b/include/linux/mmc/card.h
+@@ -343,6 +343,8 @@ struct mmc_card {
+ unsigned int nr_parts;
+
+ struct workqueue_struct *complete_wq; /* Private workqueue */
++
++ unsigned int max_posted_writes; /* command queue posted write limit */
+ };
+
+ static inline bool mmc_large_sector(struct mmc_card *card)
diff --git a/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch b/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch
new file mode 100644
index 0000000000..4f1d02c74d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch
@@ -0,0 +1,70 @@
+From 19682239a60c1b53cad8319eaeb58e71d4213cee Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 15 Jul 2024 13:38:38 +0100
+Subject: [PATCH 1168/1215] fixup: mmc: restrict posted write counts for SD
+ cards in CQ mode
+
+Leaving card->max_posted_writes unintialised was a bad thing to do.
+
+Also, cqe_enable is 1 if hsq is enabled as hsq substitutes the cqhci
+implementation with its own.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/mmc/core/mmc.c | 1 +
+ drivers/mmc/core/queue.c | 2 +-
+ drivers/mmc/core/sd.c | 14 ++++++++------
+ 3 files changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -1663,6 +1663,7 @@ static int mmc_init_card(struct mmc_host
+ card->ocr = ocr;
+ card->type = MMC_TYPE_MMC;
+ card->rca = 1;
++ card->max_posted_writes = 1;
+ memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
+ }
+
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -268,7 +268,7 @@ static blk_status_t mmc_mq_queue_rq(stru
+ spin_unlock_irq(&mq->lock);
+ return BLK_STS_RESOURCE;
+ }
+- if (host->cqe_enabled && req_op(req) == REQ_OP_WRITE &&
++ if (!host->hsq_enabled && host->cqe_enabled && req_op(req) == REQ_OP_WRITE &&
+ mq->pending_writes >= card->max_posted_writes) {
+ spin_unlock_irq(&mq->lock);
+ return BLK_STS_RESOURCE;
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1105,13 +1105,14 @@ static int sd_parse_ext_reg_perf(struct
+ mmc_hostname(card->host),
+ card->ext_csd.cmdq_depth);
+ /*
+- * If CQ is enabled, there is a contract between host and card such that VDD will
+- * be maintained and removed only if a power off notification is provided.
+- * An SD card in an accessible slot means surprise removal is a possibility.
+- * As a middle ground, limit max posted writes to 1 unless the card is "hardwired".
++ * If CQ is enabled, there is a contract between host and card such that
++ * VDD will be maintained and removed only if a power off notification
++ * is provided. An SD card in an accessible slot means surprise removal
++ * is a possibility. As a middle ground, keep the default maximum of 1
++ * posted write unless the card is "hardwired".
+ */
+- if (mmc_card_is_removable(card->host))
+- card->max_posted_writes = 1;
++ if (!mmc_card_is_removable(card->host))
++ card->max_posted_writes = card->ext_csd.cmdq_depth;
+ }
+
+ card->ext_perf.fno = fno;
+@@ -1383,6 +1384,7 @@ retry:
+
+ card->ocr = ocr;
+ card->type = MMC_TYPE_SD;
++ card->max_posted_writes = 1;
+ memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
+ }
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch b/target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch
new file mode 100644
index 0000000000..0d4d6cba19
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch
@@ -0,0 +1,28 @@
+From 1abc413af44652d6a76d5b5c2afe90788595008e Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 15 Jul 2024 13:57:01 +0100
+Subject: [PATCH 1169/1215] mmc: brcmstb: don't squash card-busy detection on
+ bcm2712
+
+Commit 485d9421719b ("mmc: sdhci-brcmstb: check R1_STATUS for
+erase/trim/discard") introduced a new flag and defaulted to disabling
+card busy detection across all platforms with this controller.
+
+This is required for IO voltage switching, as the card drives CMD low
+while the switch is in progress.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/mmc/host/sdhci-brcmstb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -430,6 +430,7 @@ static const struct brcmstb_match_priv m
+ };
+
+ static const struct brcmstb_match_priv match_priv_2712 = {
++ .flags = BRCMSTB_MATCH_FLAGS_USE_CARD_BUSY,
+ .hs400es = sdhci_brcmstb_hs400es,
+ .cfginit = sdhci_brcmstb_cfginit_2712,
+ .ops = &sdhci_brcmstb_ops_2712,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch b/target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch
new file mode 100644
index 0000000000..1923b7aec0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch
@@ -0,0 +1,25 @@
+From 31eb43be8cad2818b4458cf1fd2dfa60031ee5f4 Mon Sep 17 00:00:00 2001
+From: Matthew <sirfragles@gmail.com>
+Date: Tue, 16 Jul 2024 11:20:54 +0200
+Subject: [PATCH 1172/1215] Revert "Update DAC8x to support 384khz (#6187)"
+
+This reverts commit dd7a15472b18d4bce738bb9213443c140473833b.
+---
+ sound/soc/bcm/rpi-simple-soundcard.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/bcm/rpi-simple-soundcard.c
++++ b/sound/soc/bcm/rpi-simple-soundcard.c
+@@ -324,10 +324,10 @@ static int hifiberry_dac8x_init(struct s
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+
+ /* override the defaults to reflect 4 x PCM5102A on the card
+- * and limit the sample rate to 384ksps
++ * and limit the sample rate to 192ksps
+ */
+ codec_dai->driver->playback.channels_max = 8;
+- codec_dai->driver->playback.rates = SNDRV_PCM_RATE_8000_384000;
++ codec_dai->driver->playback.rates = SNDRV_PCM_RATE_8000_192000;
+
+ return 0;
+ }
diff --git a/target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch b/target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch
new file mode 100644
index 0000000000..af740bd305
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch
@@ -0,0 +1,25 @@
+From 3224569a3e279bbeae4e975dfa1a890f3f595239 Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:18:44 +0100
+Subject: [PATCH 1176/1215] dt-bindings: clk: rp1: Add clocks representing MIPI
+ DSI byteclock
+
+Define two new RP1 clocks, representing the MIPI DSI byteclock
+sources for the dividers used to generate MIPI[01] DPI pixel clocks.
+(Previously they were represented by "fake" fixed clocks sources).
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ include/dt-bindings/clock/rp1.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/include/dt-bindings/clock/rp1.h
++++ b/include/dt-bindings/clock/rp1.h
+@@ -54,3 +54,7 @@
+ /* Extra PLL output channels - RP1B0 only */
+ #define RP1_PLL_VIDEO_PRI_PH 43
+ #define RP1_PLL_AUDIO_TERN 44
++
++/* MIPI clocks managed by the DSI driver */
++#define RP1_CLK_MIPI0_DSI_BYTECLOCK 45
++#define RP1_CLK_MIPI1_DSI_BYTECLOCK 46
diff --git a/target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch b/target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch
new file mode 100644
index 0000000000..564ef84c9e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch
@@ -0,0 +1,132 @@
+From 126560c909f38f00c08dd5f35f50c981d5e25e1f Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:30:44 +0100
+Subject: [PATCH 1177/1215] clk: clk-rp1: Add "varsrc" clocks to represent MIPI
+ byte clocks
+
+Add a new class of clocks to RP1 to represent clock sources whose
+frequency changes at run-time as a side-effect of some other driver.
+Specifically this is for the two MIPI DSI byte-clock sources.
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ drivers/clk/clk-rp1.c | 73 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 73 insertions(+)
+
+--- a/drivers/clk/clk-rp1.c
++++ b/drivers/clk/clk-rp1.c
+@@ -394,6 +394,11 @@ struct rp1_clock {
+ unsigned long cached_rate;
+ };
+
++struct rp1_varsrc {
++ struct clk_hw hw;
++ struct rp1_clockman *clockman;
++ unsigned long rate;
++};
+
+ struct rp1_clk_change {
+ struct clk_hw *hw;
+@@ -1414,6 +1419,34 @@ static void rp1_clk_debug_init(struct cl
+ rp1_debugfs_regset(clockman, 0, regs, i, dentry);
+ }
+
++static int rp1_varsrc_set_rate(struct clk_hw *hw,
++ unsigned long rate, unsigned long parent_rate)
++{
++ struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
++
++ /*
++ * "varsrc" exists purely to let clock dividers know the frequency
++ * of an externally-managed clock source (such as MIPI DSI byte-clock)
++ * which may change at run-time as a side-effect of some other driver.
++ */
++ varsrc->rate = rate;
++ return 0;
++}
++
++static unsigned long rp1_varsrc_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
++
++ return varsrc->rate;
++}
++
++static long rp1_varsrc_round_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long *parent_rate)
++{
++ return rate;
++}
++
+ static const struct clk_ops rp1_pll_core_ops = {
+ .is_prepared = rp1_pll_core_is_on,
+ .prepare = rp1_pll_core_on,
+@@ -1464,6 +1497,12 @@ static const struct clk_ops rp1_clk_ops
+ .debug_init = rp1_clk_debug_init,
+ };
+
++static const struct clk_ops rp1_varsrc_ops = {
++ .set_rate = rp1_varsrc_set_rate,
++ .recalc_rate = rp1_varsrc_recalc_rate,
++ .round_rate = rp1_varsrc_round_rate,
++};
++
+ static bool rp1_clk_is_claimed(const char *name);
+
+ static struct clk_hw *rp1_register_pll_core(struct rp1_clockman *clockman,
+@@ -1647,6 +1686,35 @@ static struct clk_hw *rp1_register_clock
+ return &clock->hw;
+ }
+
++static struct clk_hw *rp1_register_varsrc(struct rp1_clockman *clockman,
++ const void *data)
++{
++ const char *name = *(char const * const *)data;
++ struct rp1_varsrc *clock;
++ struct clk_init_data init;
++ int ret;
++
++ memset(&init, 0, sizeof(init));
++ init.parent_names = &ref_clock;
++ init.num_parents = 1;
++ init.name = name;
++ init.flags = CLK_IGNORE_UNUSED;
++ init.ops = &rp1_varsrc_ops;
++
++ clock = devm_kzalloc(clockman->dev, sizeof(*clock), GFP_KERNEL);
++ if (!clock)
++ return NULL;
++
++ clock->clockman = clockman;
++ clock->hw.init = &init;
++
++ ret = devm_clk_hw_register(clockman->dev, &clock->hw);
++ if (ret)
++ return ERR_PTR(ret);
++
++ return &clock->hw;
++}
++
+ struct rp1_clk_desc {
+ struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
+ const void *data);
+@@ -1676,6 +1744,8 @@ struct rp1_clk_desc {
+ &(struct rp1_clock_data) \
+ {__VA_ARGS__})
+
++#define REGISTER_VARSRC(n) _REGISTER(&rp1_register_varsrc, &(const char *){n})
++
+ static const struct rp1_clk_desc clk_desc_array[] = {
+ [RP1_PLL_SYS_CORE] = REGISTER_PLL_CORE(
+ .name = "pll_sys_core",
+@@ -2318,6 +2388,9 @@ static const struct rp1_clk_desc clk_des
+ .max_freq = 200 * MHz,
+ .fc0_src = FC_NUM(3, 6),
+ ),
++
++ [RP1_CLK_MIPI0_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi0_dsi_byteclk"),
++ [RP1_CLK_MIPI1_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi1_dsi_byteclk"),
+ };
+
+ static bool rp1_clk_claimed[ARRAY_SIZE(clk_desc_array)];
diff --git a/target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch b/target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch
new file mode 100644
index 0000000000..7e6032dd1f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch
@@ -0,0 +1,92 @@
+From 9a108c82b6f6526e0aa8a19befa1ed3f31f8fe52 Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:42:29 +0100
+Subject: [PATCH 1178/1215] dts: rp1: DSI drivers to use newly defined MIPI
+ byte source clocks.
+
+Remove the "dummy" 72MHz fixed clock sources and associate DSI driver
+with the new "variable" clock sources now defined in RP1 clocks.
+
+Also add PLLSYS clock to DSI, which it will need as an alternative
+clock source in those cases where DPI pixclock > DSI byteclock.
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ arch/arm/boot/dts/broadcom/rp1.dtsi | 50 +++++++++--------------------
+ 1 file changed, 15 insertions(+), 35 deletions(-)
+
+--- a/arch/arm/boot/dts/broadcom/rp1.dtsi
++++ b/arch/arm/boot/dts/broadcom/rp1.dtsi
+@@ -1109,16 +1109,15 @@
+
+ interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
+
+- clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>, // required, config bus clock
+- <&rp1_clocks RP1_CLK_MIPI0_DPI>, // required, pixel clock
+- <&clksrc_mipi0_dsi_byteclk>, // internal, parent for divide
+- <&clk_xosc>; // hardwired to DSI "refclk"
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk";
++ clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI0_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI0_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI0_DPI>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+ assigned-clock-rates = <25000000>;
+- assigned-clock-parents = <0>, <&clksrc_mipi0_dsi_byteclk>;
+ };
+
+ rp1_dsi1: dsi@128000 {
+@@ -1130,16 +1129,15 @@
+
+ interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
+
+- clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>, // required, config bus clock
+- <&rp1_clocks RP1_CLK_MIPI1_DPI>, // required, pixel clock
+- <&clksrc_mipi1_dsi_byteclk>, // internal, parent for divide
+- <&clk_xosc>; // hardwired to DSI "refclk"
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk";
++ clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI1_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI1_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI1_DPI>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+ assigned-clock-rates = <25000000>;
+- assigned-clock-parents = <0>, <&clksrc_mipi1_dsi_byteclk>;
+ };
+
+ /* VEC and DPI both need to control PLL_VIDEO and cannot work together; */
+@@ -1216,24 +1214,6 @@
+ clock-output-names = "core";
+ clock-frequency = <50000000>;
+ };
+- clksrc_mipi0_dsi_byteclk: clksrc_mipi0_dsi_byteclk {
+- // This clock is synthesized by MIPI0 D-PHY, when DSI is running.
+- // Its frequency is not known a priori (until a panel driver attaches)
+- // so assign a made-up frequency of 72MHz so it can be divided for DPI.
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "clksrc_mipi0_dsi_byteclk";
+- clock-frequency = <72000000>;
+- };
+- clksrc_mipi1_dsi_byteclk: clksrc_mipi1_dsi_byteclk {
+- // This clock is synthesized by MIPI1 D-PHY, when DSI is running.
+- // Its frequency is not known a priori (until a panel driver attaches)
+- // so assign a made-up frequency of 72MHz so it can be divided for DPI.
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "clksrc_mipi1_dsi_byteclk";
+- clock-frequency = <72000000>;
+- };
+ /* GPIO derived clock sources. Each GPIO with a GPCLK function
+ * can drive its output from the respective GPCLK
+ * generator, and provide a clock source to other internal
diff --git a/target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch b/target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch
new file mode 100644
index 0000000000..a80af9839d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch
@@ -0,0 +1,313 @@
+From f5de8d46da4b40f2180be502c1e547fe8c9b2ac2 Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:48:15 +0100
+Subject: [PATCH 1179/1215] drm: rp1: rp1-dsi: Switch to PLL_SYS source for DPI
+ when 8 * lanes > bpp
+
+To support 4 lanes, re-parent DPI clock source between DSI byteclock
+(using the new "variable sources" defined in clk-rp1) and PLL_SYS.
+This is to cover cases in which byteclock < pixclock <= 200MHz.
+
+Tidying: All frequencies now in Hz (not kHz), where DSI speed is now
+represented by byteclock to simplify arithmetic. Clamp DPI and byte
+clocks to their legal ranges; fix up HSTX timeout to avoid an unsafe
+assumption that it would return to LP state for every scanline.
+
+Because of RP1's clock topology, the ratio between DSI and DPI clocks
+may not be exact with 3 or 4 lanes, leading to slightly irregular
+timings each time DSI switches between HS and LP states. Tweak to
+inhibit LP during Horizontal BP when sync pulses were requested.
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c | 3 +-
+ drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h | 3 +-
+ drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c | 130 +++++++++++++---------
+ 3 files changed, 80 insertions(+), 56 deletions(-)
+
+--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
+@@ -54,6 +54,7 @@ static void rp1_dsi_bridge_pre_enable(st
+ struct rp1_dsi *dsi = bridge_to_rp1_dsi(bridge);
+
+ rp1dsi_dsi_setup(dsi, &dsi->pipe.crtc.state->adjusted_mode);
++ dsi->dsi_running = true;
+ }
+
+ static void rp1_dsi_bridge_enable(struct drm_bridge *bridge,
+@@ -443,7 +444,7 @@ static int rp1dsi_platform_probe(struct
+ /* Hardware resources */
+ for (i = 0; i < RP1DSI_NUM_CLOCKS; i++) {
+ static const char * const myclocknames[RP1DSI_NUM_CLOCKS] = {
+- "cfgclk", "dpiclk", "byteclk", "refclk"
++ "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys"
+ };
+ dsi->clocks[i] = devm_clk_get(dev, myclocknames[i]);
+ if (IS_ERR(dsi->clocks[i])) {
+--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
+@@ -30,7 +30,8 @@
+ #define RP1DSI_CLOCK_DPI 1
+ #define RP1DSI_CLOCK_BYTE 2
+ #define RP1DSI_CLOCK_REF 3
+-#define RP1DSI_NUM_CLOCKS 4
++#define RP1DSI_CLOCK_PLLSYS 4
++#define RP1DSI_NUM_CLOCKS 5
+
+ /* ---------------------------------------------------------------------- */
+
+--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
+@@ -7,6 +7,7 @@
+
+ #include <linux/delay.h>
+ #include <linux/errno.h>
++#include <linux/math64.h>
+ #include <linux/platform_device.h>
+ #include <linux/rp1_platform.h>
+ #include "drm/drm_print.h"
+@@ -1111,7 +1112,7 @@ static void dphy_transaction(struct rp1_
+ DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
+ }
+
+-static uint8_t dphy_get_div(u32 refclk_khz, u32 vco_freq_khz, u32 *ptr_m, u32 *ptr_n)
++static u64 dphy_get_div(u32 refclk, u64 vco_freq, u32 *ptr_m, u32 *ptr_n)
+ {
+ /*
+ * See pg 77-78 of dphy databook
+@@ -1124,19 +1125,23 @@ static uint8_t dphy_get_div(u32 refclk_k
+ * In practice, given a 50MHz reference clock, it can produce any
+ * multiple of 10MHz, 11.1111MHz, 12.5MHz, 14.286MHz or 16.667MHz
+ * with < 1% error for all frequencies above 495MHz.
++ *
++ * vco_freq should be set to the lane bit rate (not the MIPI clock
++ * which is half of this). These frequencies are now measured in Hz.
++ * They should fit within u32, but u64 is needed for calculations.
+ */
+
+- static const u32 REF_DIVN_MAX = 40000u;
+- static const u32 REF_DIVN_MIN = 5000u;
+- u32 best_n, best_m, best_err = 0x7fffffff;
+- unsigned int n;
++ static const u32 REF_DIVN_MAX = 40000000;
++ static const u32 REF_DIVN_MIN = 5000000;
++ u32 n, best_n, best_m;
++ u64 best_err = vco_freq;
+
+- for (n = 1 + refclk_khz / REF_DIVN_MAX; n * REF_DIVN_MIN <= refclk_khz && n < 100; ++n) {
+- u32 half_m = (n * vco_freq_khz + refclk_khz) / (2 * refclk_khz);
++ for (n = 1 + refclk / REF_DIVN_MAX; n * REF_DIVN_MIN <= refclk && n < 100; ++n) {
++ u32 half_m = DIV_U64_ROUND_CLOSEST(n * vco_freq, 2 * refclk);
+
+ if (half_m < 150) {
+- u32 f = (2 * half_m * refclk_khz) / n;
+- u32 err = (f > vco_freq_khz) ? f - vco_freq_khz : vco_freq_khz - f;
++ u64 f = div_u64(mul_u32_u32(2 * half_m, refclk), n);
++ u64 err = (f > vco_freq) ? f - vco_freq : vco_freq - f;
+
+ if (err < best_err) {
+ best_n = n;
+@@ -1148,12 +1153,12 @@ static uint8_t dphy_get_div(u32 refclk_k
+ }
+ }
+
+- if (64 * best_err < vco_freq_khz) { /* tolerate small error */
+- *ptr_n = best_n;
+- *ptr_m = best_m;
+- return 1;
+- }
+- return 0;
++ if (64 * best_err >= vco_freq)
++ return 0;
++
++ *ptr_n = best_n;
++ *ptr_m = best_m;
++ return div_u64(mul_u32_u32(best_m, refclk), best_n);
+ }
+
+ struct hsfreq_range {
+@@ -1226,13 +1231,14 @@ static void dphy_set_hsfreqrange(struct
+ hsfreq_table[i].hsfreqrange << 1);
+ }
+
+-static void dphy_configure_pll(struct rp1_dsi *dsi, u32 refclk_khz, u32 vco_freq_khz)
++static u32 dphy_configure_pll(struct rp1_dsi *dsi, u32 refclk, u32 vco_freq)
+ {
+ u32 m = 0;
+ u32 n = 0;
++ u32 actual_vco_freq = dphy_get_div(refclk, vco_freq, &m, &n);
+
+- if (dphy_get_div(refclk_khz, vco_freq_khz, &m, &n)) {
+- dphy_set_hsfreqrange(dsi, vco_freq_khz / 1000);
++ if (actual_vco_freq) {
++ dphy_set_hsfreqrange(dsi, actual_vco_freq / 1000000);
+ /* Program m,n from registers */
+ dphy_transaction(dsi, DPHY_PLL_DIV_CTRL_OFFSET, 0x30);
+ /* N (program N-1) */
+@@ -1242,18 +1248,21 @@ static void dphy_configure_pll(struct rp
+ /* M[4:0] (program M-1) */
+ dphy_transaction(dsi, DPHY_PLL_LOOP_DIV_OFFSET, ((m - 1) & 0x1F));
+ drm_dbg_driver(dsi->drm,
+- "DPHY: vco freq want %dkHz got %dkHz = %d * (%dkHz / %d), hsfreqrange = 0x%02x\r\n",
+- vco_freq_khz, refclk_khz * m / n, m, refclk_khz,
+- n, hsfreq_table[dsi->hsfreq_index].hsfreqrange);
++ "DPHY: vco freq want %uHz got %uHz = %d * (%uHz / %d), hsfreqrange = 0x%02x\n",
++ vco_freq, actual_vco_freq, m, refclk, n,
++ hsfreq_table[dsi->hsfreq_index].hsfreqrange);
+ } else {
+- drm_info(dsi->drm,
+- "rp1dsi: Error configuring DPHY PLL! %dkHz = %d * (%dkHz / %d)\r\n",
+- vco_freq_khz, m, refclk_khz, n);
++ drm_warn(dsi->drm,
++ "rp1dsi: Error configuring DPHY PLL %uHz\n", vco_freq);
+ }
++
++ return actual_vco_freq;
+ }
+
+-static void dphy_init_khz(struct rp1_dsi *dsi, u32 ref_freq, u32 vco_freq)
++static u32 dphy_init(struct rp1_dsi *dsi, u32 ref_freq, u32 vco_freq)
+ {
++ u32 actual_vco_freq;
++
+ /* Reset the PHY */
+ DSI_WRITE(DSI_PHYRSTZ, 0);
+ DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
+@@ -1263,13 +1272,15 @@ static void dphy_init_khz(struct rp1_dsi
+ DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
+ udelay(1);
+ /* Since we are in DSI (not CSI2) mode here, start the PLL */
+- dphy_configure_pll(dsi, ref_freq, vco_freq);
++ actual_vco_freq = dphy_configure_pll(dsi, ref_freq, vco_freq);
+ udelay(1);
+ /* Unreset */
+ DSI_WRITE(DSI_PHYRSTZ, DSI_PHYRSTZ_SHUTDOWNZ_BITS);
+ udelay(1);
+ DSI_WRITE(DSI_PHYRSTZ, (DSI_PHYRSTZ_SHUTDOWNZ_BITS | DSI_PHYRSTZ_RSTZ_BITS));
+ udelay(1); /* so we can see PLL coming up? */
++
++ return actual_vco_freq;
+ }
+
+ void rp1dsi_mipicfg_setup(struct rp1_dsi *dsi)
+@@ -1290,23 +1301,30 @@ static unsigned long rp1dsi_refclk_freq(
+ return u;
+ }
+
+-static void rp1dsi_dpiclk_start(struct rp1_dsi *dsi, unsigned int bpp, unsigned int lanes)
++static void rp1dsi_dpiclk_start(struct rp1_dsi *dsi, u32 byte_clock,
++ unsigned int bpp, unsigned int lanes)
+ {
+- unsigned long u;
+-
+- if (dsi->clocks[RP1DSI_CLOCK_DPI]) {
+- u = (dsi->clocks[RP1DSI_CLOCK_BYTE]) ?
+- clk_get_rate(dsi->clocks[RP1DSI_CLOCK_BYTE]) : 0;
+- drm_info(dsi->drm,
+- "rp1dsi: Nominal byte clock %lu; scale by %u/%u",
+- u, 4 * lanes, (bpp >> 1));
+- if (u < 1 || u >= (1ul << 28))
+- u = 72000000ul; /* default DUMMY frequency for byteclock */
++ /* Dummy clk_set_rate() to declare the actual DSI byte-clock rate */
++ clk_set_rate(dsi->clocks[RP1DSI_CLOCK_BYTE], byte_clock);
+
++ /*
++ * Prefer the DSI byte-clock source where possible, so that DSI and DPI
++ * clocks will be in an exact ratio and downstream devices can recover
++ * perfect timings. But when DPI clock is faster, fall back on PLL_SYS.
++ * To defeat rounding errors, specify explicitly which source to use.
++ */
++ if (bpp >= 8 * lanes)
+ clk_set_parent(dsi->clocks[RP1DSI_CLOCK_DPI], dsi->clocks[RP1DSI_CLOCK_BYTE]);
+- clk_set_rate(dsi->clocks[RP1DSI_CLOCK_DPI], (4 * lanes * u) / (bpp >> 1));
+- clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_DPI]);
+- }
++ else if (dsi->clocks[RP1DSI_CLOCK_PLLSYS])
++ clk_set_parent(dsi->clocks[RP1DSI_CLOCK_DPI], dsi->clocks[RP1DSI_CLOCK_PLLSYS]);
++
++ clk_set_rate(dsi->clocks[RP1DSI_CLOCK_DPI], (4 * lanes * byte_clock) / (bpp >> 1));
++ clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_DPI]);
++ drm_info(dsi->drm,
++ "rp1dsi: Nominal Byte clock %u DPI clock %lu (parent rate %lu)",
++ byte_clock,
++ clk_get_rate(dsi->clocks[RP1DSI_CLOCK_DPI]),
++ clk_get_rate(clk_get_parent(dsi->clocks[RP1DSI_CLOCK_DPI])));
+ }
+
+ static void rp1dsi_dpiclk_stop(struct rp1_dsi *dsi)
+@@ -1336,18 +1354,21 @@ static u32 get_colorcode(enum mipi_dsi_p
+ return 0x005;
+ }
+
+-/* Maximum frequency for LP escape clock (20MHz), and some magic numbers */
+-#define RP1DSI_ESC_CLK_KHZ 20000
+-#define RP1DSI_TO_CLK_DIV 5
+-#define RP1DSI_HSTX_TO_MIN 0x200
+-#define RP1DSI_LPRX_TO_VAL 0x400
++/* Frequency limits for DPI, HS and LP clocks, and some magic numbers */
++#define RP1DSI_DPI_MAX_KHZ 200000
++#define RP1DSI_BYTE_CLK_MIN 10000000
++#define RP1DSI_BYTE_CLK_MAX 187500000
++#define RP1DSI_ESC_CLK_MAX 20000000
++#define RP1DSI_TO_CLK_DIV 0x50
++#define RP1DSI_LPRX_TO_VAL 0x40
+ #define RP1DSI_BTA_TO_VAL 0xd00
+
+ void rp1dsi_dsi_setup(struct rp1_dsi *dsi, struct drm_display_mode const *mode)
+ {
+ u32 timeout, mask, vid_mode_cfg;
+- int lane_kbps;
+ unsigned int bpp = mipi_dsi_pixel_format_to_bpp(dsi->display_format);
++ u32 byte_clock = clamp((bpp * 125 * min(mode->clock, RP1DSI_DPI_MAX_KHZ)) / dsi->lanes,
++ RP1DSI_BYTE_CLK_MIN, RP1DSI_BYTE_CLK_MAX);
+
+ DSI_WRITE(DSI_PHY_IF_CFG, dsi->lanes - 1);
+ DSI_WRITE(DSI_DPI_CFG_POL, 0);
+@@ -1360,6 +1381,8 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ vid_mode_cfg = 0xbf00;
+ if (!(dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
+ vid_mode_cfg |= 0x01;
++ else if (8 * dsi->lanes > bpp)
++ vid_mode_cfg &= ~0x400; /* PULSE && inexact DPICLK => fix HBP time */
+ if (dsi->display_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ vid_mode_cfg |= 0x02;
+ DSI_WRITE(DSI_VID_MODE_CFG, vid_mode_cfg);
+@@ -1369,15 +1392,14 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ DSI_WRITE(DSI_MODE_CFG, 1);
+
+ /* Set timeouts and clock dividers */
+- DSI_WRITE(DSI_TO_CNT_CFG,
+- (max((bpp * mode->htotal) / (7 * RP1DSI_TO_CLK_DIV * dsi->lanes),
+- RP1DSI_HSTX_TO_MIN) << 16) |
+- RP1DSI_LPRX_TO_VAL);
++ timeout = (bpp * mode->htotal * mode->vdisplay) / (7 * RP1DSI_TO_CLK_DIV * dsi->lanes);
++ if (timeout > 0xFFFFu)
++ timeout = 0;
++ DSI_WRITE(DSI_TO_CNT_CFG, (timeout << 16) | RP1DSI_LPRX_TO_VAL);
+ DSI_WRITE(DSI_BTA_TO_CNT, RP1DSI_BTA_TO_VAL);
+- lane_kbps = (bpp * mode->clock) / dsi->lanes;
+ DSI_WRITE(DSI_CLKMGR_CFG,
+ (RP1DSI_TO_CLK_DIV << 8) |
+- max(2, lane_kbps / (8 * RP1DSI_ESC_CLK_KHZ) + 1));
++ max(2u, 1u + byte_clock / RP1DSI_ESC_CLK_MAX));
+
+ /* Configure video timings */
+ DSI_WRITE(DSI_VID_PKT_SIZE, mode->hdisplay);
+@@ -1394,7 +1416,7 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ DSI_WRITE(DSI_VID_VACTIVE_LINES, mode->vdisplay);
+
+ /* Init PHY */
+- dphy_init_khz(dsi, rp1dsi_refclk_freq(dsi) / 1000, lane_kbps);
++ byte_clock = dphy_init(dsi, rp1dsi_refclk_freq(dsi), 8 * byte_clock) >> 3;
+
+ DSI_WRITE(DSI_PHY_TMR_LPCLK_CFG,
+ (hsfreq_table[dsi->hsfreq_index].clk_lp2hs << DSI_PHY_TMR_LP2HS_LSB) |
+@@ -1418,7 +1440,7 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ DSI_WRITE(DSI_PWR_UP, 0x1); /* power up */
+
+ /* Now it should be safe to start the external DPI clock divider */
+- rp1dsi_dpiclk_start(dsi, bpp, dsi->lanes);
++ rp1dsi_dpiclk_start(dsi, byte_clock, bpp, dsi->lanes);
+
+ /* Wait for all lane(s) to be in Stopstate */
+ mask = (1 << 4);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch b/target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch
new file mode 100644
index 0000000000..2856bb5cd8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch
@@ -0,0 +1,9749 @@
+From 10c77e119eaaa2677009dea58cf69a8e5383925b Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 17 Jul 2024 17:27:36 +0100
+Subject: [PATCH 1180/1215] arm64: dts: Move bcm2712 and rp1 here
+
+It is pointless having the bcm2712 family of dts files and rp1.dtsi
+in the arch/arm directory tree, since they then require placeholders
+to include them in arch/arm64 where they are built. The files have
+no dependencies on other files in the arch/arm tree, so simply move
+them here.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 867 ------------------
+ .../dts/broadcom/bcm2712-rpi-cm5-cm4io.dts | 20 -
+ .../dts/broadcom/bcm2712-rpi-cm5-cm5io.dts | 10 -
+ .../boot/dts/broadcom/bcm2712d0-rpi-5-b.dts | 107 ---
+ .../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 867 +++++++++++++++++-
+ .../dts/broadcom/bcm2712-rpi-cm5-cm4io.dts | 20 +-
+ .../dts/broadcom/bcm2712-rpi-cm5-cm5io.dts | 10 +-
+ .../boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 10 +-
+ .../boot/dts/broadcom/bcm2712-rpi.dtsi | 0
+ .../boot/dts/broadcom/bcm2712.dtsi | 0
+ .../boot/dts/broadcom/bcm2712d0-rpi-5-b.dts | 107 ++-
+ .../{arm => arm64}/boot/dts/broadcom/rp1.dtsi | 0
+ 12 files changed, 1002 insertions(+), 1016 deletions(-)
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
+ rename arch/{arm => arm64}/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi (98%)
+ rename arch/{arm => arm64}/boot/dts/broadcom/bcm2712-rpi.dtsi (100%)
+ rename arch/{arm => arm64}/boot/dts/broadcom/bcm2712.dtsi (100%)
+ rename arch/{arm => arm64}/boot/dts/broadcom/rp1.dtsi (100%)
+
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts
++++ /dev/null
+@@ -1,867 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/dts-v1/;
+-
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/clock/rp1.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/mfd/rp1.h>
+-#include <dt-bindings/pwm/pwm.h>
+-#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
+-
+-#define i2c0 _i2c0
+-#define i2c3 _i2c3
+-#define i2c4 _i2c4
+-#define i2c5 _i2c5
+-#define i2c6 _i2c6
+-#define i2c8 _i2c8
+-#define i2s _i2s
+-#define pwm0 _pwm0
+-#define pwm1 _pwm1
+-#define spi0 _spi0
+-#define spi3 _spi3
+-#define spi4 _spi4
+-#define spi5 _spi5
+-#define spi6 _spi6
+-#define uart0 _uart0
+-#define uart2 _uart2
+-#define uart5 _uart5
+-
+-#include "bcm2712.dtsi"
+-
+-#undef i2c0
+-#undef i2c3
+-#undef i2c4
+-#undef i2c5
+-#undef i2c6
+-#undef i2c8
+-#undef i2s
+-#undef pwm0
+-#undef pwm1
+-#undef spi0
+-#undef spi3
+-#undef spi4
+-#undef spi5
+-#undef spi6
+-#undef uart0
+-#undef uart2
+-#undef uart3
+-#undef uart4
+-#undef uart5
+-
+-/ {
+- compatible = "raspberrypi,5-model-b", "brcm,bcm2712";
+- model = "Raspberry Pi 5";
+-
+- /* Will be filled by the bootloader */
+- memory@0 {
+- device_type = "memory";
+- reg = <0 0 0x28000000>;
+- };
+-
+- leds: leds {
+- compatible = "gpio-leds";
+-
+- led_pwr: led-pwr {
+- label = "PWR";
+- gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "none";
+- };
+-
+- led_act: led-act {
+- label = "ACT";
+- gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "mmc0";
+- };
+- };
+-
+- sd_io_1v8_reg: sd_io_1v8_reg {
+- compatible = "regulator-gpio";
+- regulator-name = "vdd-sd-io";
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- regulator-always-on;
+- regulator-settling-time-us = <5000>;
+- gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
+- states = <1800000 0x1
+- 3300000 0x0>;
+- status = "okay";
+- };
+-
+- sd_vcc_reg: sd_vcc_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc-sd";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- enable-active-high;
+- gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
+- status = "okay";
+- };
+-
+- wl_on_reg: wl_on_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "wl-on-regulator";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- pinctrl-0 = <&wl_on_pins>;
+- pinctrl-names = "default";
+-
+- gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
+-
+- startup-delay-us = <150000>;
+- enable-active-high;
+- };
+-
+- clocks: clocks {
+- };
+-
+- cam1_clk: cam1_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_clk: cam0_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_reg: cam0_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam0_reg";
+- enable-active-high;
+- status = "okay";
+- gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to MIPI 0 connector
+- };
+-
+- cam1_reg: cam1_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam1_reg";
+- enable-active-high;
+- status = "okay";
+- gpio = <&rp1_gpio 46 0>; // CD1_IO0_MICCLK, to MIPI 1 connector
+- };
+-
+- cam_dummy_reg: cam_dummy_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam-dummy-reg";
+- status = "okay";
+- };
+-
+- dummy: dummy {
+- // A target for unwanted overlay fragments
+- };
+-
+-
+- // A few extra labels to keep overlays happy
+-
+- i2c0if: i2c0if {};
+- i2c0mux: i2c0mux {};
+-};
+-
+-rp1_target: &pcie2 {
+- brcm,enable-mps-rcb;
+- brcm,vdm-qos-map = <0xbbaa9888>;
+- aspm-no-l0s;
+- status = "okay";
+-};
+-
+-&pcie1 {
+- brcm,vdm-qos-map = <0x33333333>;
+-};
+-
+-// Add some labels to 2712 device
+-
+-// The system UART
+-uart10: &_uart0 { status = "okay"; };
+-
+-// The system SPI for the bootloader EEPROM
+-spi10: &_spi0 { status = "okay"; };
+-
+-i2c_rp1boot: &_i2c3 { };
+-
+-#include "rp1.dtsi"
+-
+-&rp1 {
+- // PCIe address space layout:
+- // 00_00000000-00_00xxxxxx = RP1 peripherals
+- // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
+-
+- // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
+- // This is the RP1 peripheral space
+- ranges = <0xc0 0x40000000
+- 0x02000000 0x00 0x00000000
+- 0x00 0x00400000>;
+-
+- dma-ranges =
+- // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x10 0x00000000
+- 0x43000000 0x10 0x00000000
+- 0x10 0x00000000>,
+-
+- // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
+- // This allows the RP1 DMA controller to address RP1 hardware
+- <0xc0 0x40000000
+- 0x02000000 0x0 0x00000000
+- 0x0 0x00400000>,
+-
+- // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x00 0x00000000
+- 0x02000000 0x10 0x00000000
+- 0x10 0x00000000>;
+-};
+-
+-// Expose RP1 nodes as system nodes with labels
+-
+-&rp1_dma {
+- status = "okay";
+-};
+-
+-&rp1_eth {
+- status = "okay";
+- phy-handle = <&phy1>;
+- phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
+- phy-reset-duration = <5>;
+-
+- phy1: ethernet-phy@1 {
+- reg = <0x1>;
+- brcm,powerdown-enable;
+- };
+-};
+-
+-gpio: &rp1_gpio {
+- status = "okay";
+-};
+-
+-aux: &dummy {};
+-
+-&rp1_usb0 {
+- pinctrl-0 = <&usb_vbus_pins>;
+- pinctrl-names = "default";
+- status = "okay";
+-};
+-
+-&rp1_usb1 {
+- status = "okay";
+-};
+-
+-#include "bcm2712-rpi.dtsi"
+-
+-i2c_csi_dsi0: &i2c6 { // Note: This is for MIPI0 connector only
+- pinctrl-0 = <&rp1_i2c6_38_39>;
+- pinctrl-names = "default";
+- clock-frequency = <100000>;
+-};
+-
+-i2c_csi_dsi1: &i2c4 { // Note: This is for MIPI1 connector only
+- pinctrl-0 = <&rp1_i2c4_40_41>;
+- pinctrl-names = "default";
+- clock-frequency = <100000>;
+-};
+-
+-i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
+-
+-csi0: &rp1_csi0 { };
+-csi1: &rp1_csi1 { };
+-dsi0: &rp1_dsi0 { };
+-dsi1: &rp1_dsi1 { };
+-dpi: &rp1_dpi { };
+-vec: &rp1_vec { };
+-dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
+-dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
+-dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
+-dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
+-dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
+-dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
+-dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
+-dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
+-dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
+-dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
+-
+-/* Add the IOMMUs for some RP1 bus masters */
+-
+-&csi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&csi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dpi {
+- iommus = <&iommu5>;
+-};
+-
+-&vec {
+- iommus = <&iommu5>;
+-};
+-
+-&ddc0 {
+- status = "disabled";
+-};
+-
+-&ddc1 {
+- status = "disabled";
+-};
+-
+-&hdmi0 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hdmi1 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hvs {
+- clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
+- clock-names = "core", "disp";
+-};
+-
+-&mop {
+- status = "disabled";
+-};
+-
+-&moplet {
+- status = "disabled";
+-};
+-
+-&pixelvalve0 {
+- status = "disabled";
+-};
+-
+-&pixelvalve1 {
+- status = "disabled";
+-};
+-
+-&disp_intr {
+- status = "disabled";
+-};
+-
+-/* SDIO1 is used to drive the SD card */
+-&sdio1 {
+- pinctrl-0 = <&emmc_sd_pulls>, <&emmc_aon_cd_pins>;
+- pinctrl-names = "default";
+- vqmmc-supply = <&sd_io_1v8_reg>;
+- vmmc-supply = <&sd_vcc_reg>;
+- bus-width = <4>;
+- sd-uhs-sdr50;
+- sd-uhs-ddr50;
+- sd-uhs-sdr104;
+- cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>;
+- //no-1-8-v;
+- status = "okay";
+-};
+-
+-&pinctrl_aon {
+- emmc_aon_cd_pins: emmc_aon_cd_pins {
+- function = "sd_card_g";
+- pins = "aon_gpio5";
+- bias-pull-up;
+- };
+-
+- /* Slight hack - only one PWM pin (status LED) is usable */
+- aon_pwm_1pin: aon_pwm_1pin {
+- function = "aon_pwm";
+- pins = "aon_gpio9";
+- };
+-};
+-
+-&pinctrl {
+- pwr_button_pins: pwr_button_pins {
+- function = "gpio";
+- pins = "gpio20";
+- bias-pull-up;
+- };
+-
+- wl_on_pins: wl_on_pins {
+- function = "gpio";
+- pins = "gpio28";
+- };
+-
+- bt_shutdown_pins: bt_shutdown_pins {
+- function = "gpio";
+- pins = "gpio29";
+- };
+-
+- emmc_sd_pulls: emmc_sd_pulls {
+- pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3";
+- bias-pull-up;
+- };
+-};
+-
+-/* uarta communicates with the BT module */
+-&uarta {
+- uart-has-rtscts;
+- auto-flow-control;
+- status = "okay";
+- clock-frequency = <96000000>;
+- pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
+- pinctrl-names = "default";
+-
+- bluetooth: bluetooth {
+- compatible = "brcm,bcm43438-bt";
+- max-speed = <3000000>;
+- shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
+- local-bd-address = [ 00 00 00 00 00 00 ];
+- };
+-};
+-
+-&i2c_rp1boot {
+- clock-frequency = <400000>;
+- pinctrl-0 = <&i2c3_m4_agpio0_pins>;
+- pinctrl-names = "default";
+-};
+-
+-/ {
+- chosen: chosen {
+- bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe";
+- stdout-path = "serial10:115200n8";
+- };
+-
+- fan: cooling_fan {
+- status = "disabled";
+- compatible = "pwm-fan";
+- #cooling-cells = <2>;
+- cooling-min-state = <0>;
+- cooling-max-state = <3>;
+- cooling-levels = <0 75 125 175 250>;
+- pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
+- rpm-regmap = <&rp1_pwm1>;
+- rpm-offset = <0x3c>;
+- };
+-
+- pwr_button {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&pwr_button_pins>;
+- status = "okay";
+-
+- pwr_key: pwr {
+- label = "pwr_button";
+- // linux,code = <205>; // KEY_SUSPEND
+- linux,code = <116>; // KEY_POWER
+- gpios = <&gio 20 GPIO_ACTIVE_LOW>;
+- debounce-interval = <50>; // ms
+- };
+- };
+-};
+-
+-&usb {
+- power-domains = <&power RPI_POWER_DOMAIN_USB>;
+-};
+-
+-/* SDIO2 drives the WLAN interface */
+-&sdio2 {
+- pinctrl-0 = <&sdio2_30_pins>;
+- pinctrl-names = "default";
+- bus-width = <4>;
+- vmmc-supply = <&wl_on_reg>;
+- sd-uhs-ddr50;
+- non-removable;
+- status = "okay";
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- wifi: wifi@1 {
+- reg = <1>;
+- compatible = "brcm,bcm4329-fmac";
+- local-mac-address = [00 00 00 00 00 00];
+- };
+-};
+-
+-&rpivid {
+- status = "okay";
+-};
+-
+-&pinctrl {
+- spi10_gpio2: spi10_gpio2 {
+- function = "vc_spi0";
+- pins = "gpio2", "gpio3", "gpio4";
+- bias-disable;
+- };
+-
+- spi10_cs_gpio1: spi10_cs_gpio1 {
+- function = "gpio";
+- pins = "gpio1";
+- bias-pull-up;
+- };
+-};
+-
+-spi10_pins: &spi10_gpio2 {};
+-spi10_cs_pins: &spi10_cs_gpio1 {};
+-
+-&spi10 {
+- pinctrl-names = "default";
+- cs-gpios = <&gio 1 1>;
+- pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
+-
+- spidev10: spidev@0 {
+- compatible = "spidev";
+- reg = <0>; /* CE0 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <20000000>;
+- status = "okay";
+- };
+-};
+-
+-// =============================================
+-// Board specific stuff here
+-
+-&gio_aon {
+- // Don't use GIO_AON as an interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- /delete-property/ interrupt-controller;
+-};
+-
+-&main_aon_irq {
+- // Don't use the MAIN_AON_IRQ interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- status = "disabled";
+-};
+-
+-&rp1_pwm1 {
+- status = "disabled";
+- pinctrl-0 = <&rp1_pwm1_gpio45>;
+- pinctrl-names = "default";
+-};
+-
+-&thermal_trips {
+- cpu_tepid: cpu-tepid {
+- temperature = <50000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_warm: cpu-warm {
+- temperature = <60000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_hot: cpu-hot {
+- temperature = <67500>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_vhot: cpu-vhot {
+- temperature = <75000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-};
+-
+-&cooling_maps {
+- tepid {
+- trip = <&cpu_tepid>;
+- cooling-device = <&fan 1 1>;
+- };
+-
+- warm {
+- trip = <&cpu_warm>;
+- cooling-device = <&fan 2 2>;
+- };
+-
+- hot {
+- trip = <&cpu_hot>;
+- cooling-device = <&fan 3 3>;
+- };
+-
+- vhot {
+- trip = <&cpu_vhot>;
+- cooling-device = <&fan 4 4>;
+- };
+-
+- melt {
+- trip = <&cpu_crit>;
+- cooling-device = <&fan 4 4>;
+- };
+-};
+-
+-&gio {
+- // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
+- // to reduce the clutter in gpioinfo/pinctrl
+- brcm,gpio-bank-widths = <32 4>;
+-
+- gpio-line-names =
+- "-", // GPIO_000
+- "2712_BOOT_CS_N", // GPIO_001
+- "2712_BOOT_MISO", // GPIO_002
+- "2712_BOOT_MOSI", // GPIO_003
+- "2712_BOOT_SCLK", // GPIO_004
+- "-", // GPIO_005
+- "-", // GPIO_006
+- "-", // GPIO_007
+- "-", // GPIO_008
+- "-", // GPIO_009
+- "-", // GPIO_010
+- "-", // GPIO_011
+- "-", // GPIO_012
+- "-", // GPIO_013
+- "PCIE_SDA", // GPIO_014
+- "PCIE_SCL", // GPIO_015
+- "-", // GPIO_016
+- "-", // GPIO_017
+- "-", // GPIO_018
+- "-", // GPIO_019
+- "PWR_GPIO", // GPIO_020
+- "2712_G21_FS", // GPIO_021
+- "-", // GPIO_022
+- "-", // GPIO_023
+- "BT_RTS", // GPIO_024
+- "BT_CTS", // GPIO_025
+- "BT_TXD", // GPIO_026
+- "BT_RXD", // GPIO_027
+- "WL_ON", // GPIO_028
+- "BT_ON", // GPIO_029
+- "WIFI_SDIO_CLK", // GPIO_030
+- "WIFI_SDIO_CMD", // GPIO_031
+- "WIFI_SDIO_D0", // GPIO_032
+- "WIFI_SDIO_D1", // GPIO_033
+- "WIFI_SDIO_D2", // GPIO_034
+- "WIFI_SDIO_D3"; // GPIO_035
+-};
+-
+-&gio_aon {
+- gpio-line-names =
+- "RP1_SDA", // AON_GPIO_00
+- "RP1_SCL", // AON_GPIO_01
+- "RP1_RUN", // AON_GPIO_02
+- "SD_IOVDD_SEL", // AON_GPIO_03
+- "SD_PWR_ON", // AON_GPIO_04
+- "SD_CDET_N", // AON_GPIO_05
+- "SD_FLG_N", // AON_GPIO_06
+- "-", // AON_GPIO_07
+- "2712_WAKE", // AON_GPIO_08
+- "2712_STAT_LED", // AON_GPIO_09
+- "-", // AON_GPIO_10
+- "-", // AON_GPIO_11
+- "PMIC_INT", // AON_GPIO_12
+- "UART_TX_FS", // AON_GPIO_13
+- "UART_RX_FS", // AON_GPIO_14
+- "-", // AON_GPIO_15
+- "-", // AON_GPIO_16
+-
+- // Pad bank0 out to 32 entries
+- "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+-
+- "HDMI0_SCL", // AON_SGPIO_00
+- "HDMI0_SDA", // AON_SGPIO_01
+- "HDMI1_SCL", // AON_SGPIO_02
+- "HDMI1_SDA", // AON_SGPIO_03
+- "PMIC_SCL", // AON_SGPIO_04
+- "PMIC_SDA"; // AON_SGPIO_05
+-
+- rp1_run_hog {
+- gpio-hog;
+- gpios = <2 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "RP1 RUN pin";
+- };
+-};
+-
+-&rp1_gpio {
+- gpio-line-names =
+- "ID_SDA", // GPIO0
+- "ID_SCL", // GPIO1
+- "GPIO2", // GPIO2
+- "GPIO3", // GPIO3
+- "GPIO4", // GPIO4
+- "GPIO5", // GPIO5
+- "GPIO6", // GPIO6
+- "GPIO7", // GPIO7
+- "GPIO8", // GPIO8
+- "GPIO9", // GPIO9
+- "GPIO10", // GPIO10
+- "GPIO11", // GPIO11
+- "GPIO12", // GPIO12
+- "GPIO13", // GPIO13
+- "GPIO14", // GPIO14
+- "GPIO15", // GPIO15
+- "GPIO16", // GPIO16
+- "GPIO17", // GPIO17
+- "GPIO18", // GPIO18
+- "GPIO19", // GPIO19
+- "GPIO20", // GPIO20
+- "GPIO21", // GPIO21
+- "GPIO22", // GPIO22
+- "GPIO23", // GPIO23
+- "GPIO24", // GPIO24
+- "GPIO25", // GPIO25
+- "GPIO26", // GPIO26
+- "GPIO27", // GPIO27
+-
+- "PCIE_RP1_WAKE", // GPIO28
+- "FAN_TACH", // GPIO29
+- "HOST_SDA", // GPIO30
+- "HOST_SCL", // GPIO31
+- "ETH_RST_N", // GPIO32
+- "-", // GPIO33
+-
+- "CD0_IO0_MICCLK", // GPIO34
+- "CD0_IO0_MICDAT0", // GPIO35
+- "RP1_PCIE_CLKREQ_N", // GPIO36
+- "-", // GPIO37
+- "CD0_SDA", // GPIO38
+- "CD0_SCL", // GPIO39
+- "CD1_SDA", // GPIO40
+- "CD1_SCL", // GPIO41
+- "USB_VBUS_EN", // GPIO42
+- "USB_OC_N", // GPIO43
+- "RP1_STAT_LED", // GPIO44
+- "FAN_PWM", // GPIO45
+- "CD1_IO0_MICCLK", // GPIO46
+- "2712_WAKE", // GPIO47
+- "CD1_IO1_MICDAT1", // GPIO48
+- "EN_MAX_USB_CUR", // GPIO49
+- "-", // GPIO50
+- "-", // GPIO51
+- "-", // GPIO52
+- "-"; // GPIO53
+-
+- usb_vbus_pins: usb_vbus_pins {
+- function = "vbus1";
+- pins = "gpio42", "gpio43";
+- };
+-};
+-
+-/ {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+- __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+- sd_cqe = <&sdio1>, "supports-cqe?";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
+- act_led_activelow = <&led_act>,"gpios:8";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_gpio = <&led_pwr>,"gpios:4";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
++++ /dev/null
+@@ -1,20 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/dts-v1/;
+-
+-#include "bcm2712-rpi-cm5.dtsi"
+-
+-// The RP1 USB3 interfaces are not usable on CM4IO
+-
+-&rp1_usb0 {
+- status = "disabled";
+-};
+-
+-&rp1_usb1 {
+- status = "disabled";
+-};
+-
+-/ {
+- __overrides__ {
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
++++ /dev/null
+@@ -1,10 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/dts-v1/;
+-
+-#include "bcm2712-rpi-cm5.dtsi"
+-
+-/ {
+- __overrides__ {
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
++++ /dev/null
+@@ -1,107 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-#include "bcm2712-rpi-5-b.dts"
+-
+-&gio {
+- brcm,gpio-bank-widths = <32 4>;
+-
+- gpio-line-names =
+- "", // GPIO_000
+- "2712_BOOT_CS_N", // GPIO_001
+- "2712_BOOT_MISO", // GPIO_002
+- "2712_BOOT_MOSI", // GPIO_003
+- "2712_BOOT_SCLK", // GPIO_004
+- "", // GPIO_005
+- "", // GPIO_006
+- "", // GPIO_007
+- "", // GPIO_008
+- "", // GPIO_009
+- "", // GPIO_010
+- "", // GPIO_011
+- "", // GPIO_012
+- "", // GPIO_013
+- "PCIE_SDA", // GPIO_014
+- "PCIE_SCL", // GPIO_015
+- "", // GPIO_016
+- "", // GPIO_017
+- "-", // GPIO_018
+- "-", // GPIO_019
+- "PWR_GPIO", // GPIO_020
+- "2712_G21_FS", // GPIO_021
+- "-", // GPIO_022
+- "-", // GPIO_023
+- "BT_RTS", // GPIO_024
+- "BT_CTS", // GPIO_025
+- "BT_TXD", // GPIO_026
+- "BT_RXD", // GPIO_027
+- "WL_ON", // GPIO_028
+- "BT_ON", // GPIO_029
+- "WIFI_SDIO_CLK", // GPIO_030
+- "WIFI_SDIO_CMD", // GPIO_031
+- "WIFI_SDIO_D0", // GPIO_032
+- "WIFI_SDIO_D1", // GPIO_033
+- "WIFI_SDIO_D2", // GPIO_034
+- "WIFI_SDIO_D3"; // GPIO_035
+-};
+-
+-&gio_aon {
+- brcm,gpio-bank-widths = <15 6>;
+-
+- gpio-line-names =
+- "RP1_SDA", // AON_GPIO_00
+- "RP1_SCL", // AON_GPIO_01
+- "RP1_RUN", // AON_GPIO_02
+- "SD_IOVDD_SEL", // AON_GPIO_03
+- "SD_PWR_ON", // AON_GPIO_04
+- "SD_CDET_N", // AON_GPIO_05
+- "SD_FLG_N", // AON_GPIO_06
+- "", // AON_GPIO_07
+- "2712_WAKE", // AON_GPIO_08
+- "2712_STAT_LED", // AON_GPIO_09
+- "", // AON_GPIO_10
+- "", // AON_GPIO_11
+- "PMIC_INT", // AON_GPIO_12
+- "UART_TX_FS", // AON_GPIO_13
+- "UART_RX_FS", // AON_GPIO_14
+- "", // AON_GPIO_15
+- "", // AON_GPIO_16
+-
+- // Pad bank0 out to 32 entries
+- "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+-
+- "HDMI0_SCL", // AON_SGPIO_00
+- "HDMI0_SDA", // AON_SGPIO_01
+- "HDMI1_SCL", // AON_SGPIO_02
+- "HDMI1_SDA", // AON_SGPIO_03
+- "PMIC_SCL", // AON_SGPIO_04
+- "PMIC_SDA"; // AON_SGPIO_05
+-};
+-
+-&pinctrl {
+- compatible = "brcm,bcm2712d0-pinctrl";
+- reg = <0x7d504100 0x20>;
+-};
+-
+-&pinctrl_aon {
+- compatible = "brcm,bcm2712d0-aon-pinctrl";
+- reg = <0x7d510700 0x1c>;
+-};
+-
+-&vc4 {
+- compatible = "brcm,bcm2712d0-vc6";
+-};
+-
+-&uart10 {
+- interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+-};
+-
+-&spi10 {
+- dmas = <&dma40 3>, <&dma40 4>;
+-};
+-
+-&hdmi0 {
+- dmas = <&dma40 (12|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+-
+-&hdmi1 {
+- dmas = <&dma40 (13|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+@@ -1,2 +1,867 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "arm/broadcom/bcm2712-rpi-5-b.dts"
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/clock/rp1.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/mfd/rp1.h>
++#include <dt-bindings/pwm/pwm.h>
++#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
++
++#define i2c0 _i2c0
++#define i2c3 _i2c3
++#define i2c4 _i2c4
++#define i2c5 _i2c5
++#define i2c6 _i2c6
++#define i2c8 _i2c8
++#define i2s _i2s
++#define pwm0 _pwm0
++#define pwm1 _pwm1
++#define spi0 _spi0
++#define spi3 _spi3
++#define spi4 _spi4
++#define spi5 _spi5
++#define spi6 _spi6
++#define uart0 _uart0
++#define uart2 _uart2
++#define uart5 _uart5
++
++#include "bcm2712.dtsi"
++
++#undef i2c0
++#undef i2c3
++#undef i2c4
++#undef i2c5
++#undef i2c6
++#undef i2c8
++#undef i2s
++#undef pwm0
++#undef pwm1
++#undef spi0
++#undef spi3
++#undef spi4
++#undef spi5
++#undef spi6
++#undef uart0
++#undef uart2
++#undef uart3
++#undef uart4
++#undef uart5
++
++/ {
++ compatible = "raspberrypi,5-model-b", "brcm,bcm2712";
++ model = "Raspberry Pi 5";
++
++ /* Will be filled by the bootloader */
++ memory@0 {
++ device_type = "memory";
++ reg = <0 0 0x28000000>;
++ };
++
++ leds: leds {
++ compatible = "gpio-leds";
++
++ led_pwr: led-pwr {
++ label = "PWR";
++ gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "none";
++ };
++
++ led_act: led-act {
++ label = "ACT";
++ gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "mmc0";
++ };
++ };
++
++ sd_io_1v8_reg: sd_io_1v8_reg {
++ compatible = "regulator-gpio";
++ regulator-name = "vdd-sd-io";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ regulator-settling-time-us = <5000>;
++ gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
++ states = <1800000 0x1
++ 3300000 0x0>;
++ status = "okay";
++ };
++
++ sd_vcc_reg: sd_vcc_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-sd";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ enable-active-high;
++ gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++ };
++
++ wl_on_reg: wl_on_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "wl-on-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ pinctrl-0 = <&wl_on_pins>;
++ pinctrl-names = "default";
++
++ gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
++
++ startup-delay-us = <150000>;
++ enable-active-high;
++ };
++
++ clocks: clocks {
++ };
++
++ cam1_clk: cam1_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_clk: cam0_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_reg: cam0_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam0_reg";
++ enable-active-high;
++ status = "okay";
++ gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to MIPI 0 connector
++ };
++
++ cam1_reg: cam1_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam1_reg";
++ enable-active-high;
++ status = "okay";
++ gpio = <&rp1_gpio 46 0>; // CD1_IO0_MICCLK, to MIPI 1 connector
++ };
++
++ cam_dummy_reg: cam_dummy_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dummy-reg";
++ status = "okay";
++ };
++
++ dummy: dummy {
++ // A target for unwanted overlay fragments
++ };
++
++
++ // A few extra labels to keep overlays happy
++
++ i2c0if: i2c0if {};
++ i2c0mux: i2c0mux {};
++};
++
++rp1_target: &pcie2 {
++ brcm,enable-mps-rcb;
++ brcm,vdm-qos-map = <0xbbaa9888>;
++ aspm-no-l0s;
++ status = "okay";
++};
++
++&pcie1 {
++ brcm,vdm-qos-map = <0x33333333>;
++};
++
++// Add some labels to 2712 device
++
++// The system UART
++uart10: &_uart0 { status = "okay"; };
++
++// The system SPI for the bootloader EEPROM
++spi10: &_spi0 { status = "okay"; };
++
++i2c_rp1boot: &_i2c3 { };
++
++#include "rp1.dtsi"
++
++&rp1 {
++ // PCIe address space layout:
++ // 00_00000000-00_00xxxxxx = RP1 peripherals
++ // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
++
++ // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
++ // This is the RP1 peripheral space
++ ranges = <0xc0 0x40000000
++ 0x02000000 0x00 0x00000000
++ 0x00 0x00400000>;
++
++ dma-ranges =
++ // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x10 0x00000000
++ 0x43000000 0x10 0x00000000
++ 0x10 0x00000000>,
++
++ // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
++ // This allows the RP1 DMA controller to address RP1 hardware
++ <0xc0 0x40000000
++ 0x02000000 0x0 0x00000000
++ 0x0 0x00400000>,
++
++ // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x00 0x00000000
++ 0x02000000 0x10 0x00000000
++ 0x10 0x00000000>;
++};
++
++// Expose RP1 nodes as system nodes with labels
++
++&rp1_dma {
++ status = "okay";
++};
++
++&rp1_eth {
++ status = "okay";
++ phy-handle = <&phy1>;
++ phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
++ phy-reset-duration = <5>;
++
++ phy1: ethernet-phy@1 {
++ reg = <0x1>;
++ brcm,powerdown-enable;
++ };
++};
++
++gpio: &rp1_gpio {
++ status = "okay";
++};
++
++aux: &dummy {};
++
++&rp1_usb0 {
++ pinctrl-0 = <&usb_vbus_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&rp1_usb1 {
++ status = "okay";
++};
++
++#include "bcm2712-rpi.dtsi"
++
++i2c_csi_dsi0: &i2c6 { // Note: This is for MIPI0 connector only
++ pinctrl-0 = <&rp1_i2c6_38_39>;
++ pinctrl-names = "default";
++ clock-frequency = <100000>;
++};
++
++i2c_csi_dsi1: &i2c4 { // Note: This is for MIPI1 connector only
++ pinctrl-0 = <&rp1_i2c4_40_41>;
++ pinctrl-names = "default";
++ clock-frequency = <100000>;
++};
++
++i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
++
++csi0: &rp1_csi0 { };
++csi1: &rp1_csi1 { };
++dsi0: &rp1_dsi0 { };
++dsi1: &rp1_dsi1 { };
++dpi: &rp1_dpi { };
++vec: &rp1_vec { };
++dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
++dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
++dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
++dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
++dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
++dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
++dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
++dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
++dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
++dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
++
++/* Add the IOMMUs for some RP1 bus masters */
++
++&csi0 {
++ iommus = <&iommu5>;
++};
++
++&csi1 {
++ iommus = <&iommu5>;
++};
++
++&dsi0 {
++ iommus = <&iommu5>;
++};
++
++&dsi1 {
++ iommus = <&iommu5>;
++};
++
++&dpi {
++ iommus = <&iommu5>;
++};
++
++&vec {
++ iommus = <&iommu5>;
++};
++
++&ddc0 {
++ status = "disabled";
++};
++
++&ddc1 {
++ status = "disabled";
++};
++
++&hdmi0 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hdmi1 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hvs {
++ clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
++ clock-names = "core", "disp";
++};
++
++&mop {
++ status = "disabled";
++};
++
++&moplet {
++ status = "disabled";
++};
++
++&pixelvalve0 {
++ status = "disabled";
++};
++
++&pixelvalve1 {
++ status = "disabled";
++};
++
++&disp_intr {
++ status = "disabled";
++};
++
++/* SDIO1 is used to drive the SD card */
++&sdio1 {
++ pinctrl-0 = <&emmc_sd_pulls>, <&emmc_aon_cd_pins>;
++ pinctrl-names = "default";
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ vmmc-supply = <&sd_vcc_reg>;
++ bus-width = <4>;
++ sd-uhs-sdr50;
++ sd-uhs-ddr50;
++ sd-uhs-sdr104;
++ cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>;
++ //no-1-8-v;
++ status = "okay";
++};
++
++&pinctrl_aon {
++ emmc_aon_cd_pins: emmc_aon_cd_pins {
++ function = "sd_card_g";
++ pins = "aon_gpio5";
++ bias-pull-up;
++ };
++
++ /* Slight hack - only one PWM pin (status LED) is usable */
++ aon_pwm_1pin: aon_pwm_1pin {
++ function = "aon_pwm";
++ pins = "aon_gpio9";
++ };
++};
++
++&pinctrl {
++ pwr_button_pins: pwr_button_pins {
++ function = "gpio";
++ pins = "gpio20";
++ bias-pull-up;
++ };
++
++ wl_on_pins: wl_on_pins {
++ function = "gpio";
++ pins = "gpio28";
++ };
++
++ bt_shutdown_pins: bt_shutdown_pins {
++ function = "gpio";
++ pins = "gpio29";
++ };
++
++ emmc_sd_pulls: emmc_sd_pulls {
++ pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3";
++ bias-pull-up;
++ };
++};
++
++/* uarta communicates with the BT module */
++&uarta {
++ uart-has-rtscts;
++ auto-flow-control;
++ status = "okay";
++ clock-frequency = <96000000>;
++ pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
++ pinctrl-names = "default";
++
++ bluetooth: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
++ shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
++ local-bd-address = [ 00 00 00 00 00 00 ];
++ };
++};
++
++&i2c_rp1boot {
++ clock-frequency = <400000>;
++ pinctrl-0 = <&i2c3_m4_agpio0_pins>;
++ pinctrl-names = "default";
++};
++
++/ {
++ chosen: chosen {
++ bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe";
++ stdout-path = "serial10:115200n8";
++ };
++
++ fan: cooling_fan {
++ status = "disabled";
++ compatible = "pwm-fan";
++ #cooling-cells = <2>;
++ cooling-min-state = <0>;
++ cooling-max-state = <3>;
++ cooling-levels = <0 75 125 175 250>;
++ pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
++ rpm-regmap = <&rp1_pwm1>;
++ rpm-offset = <0x3c>;
++ };
++
++ pwr_button {
++ compatible = "gpio-keys";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwr_button_pins>;
++ status = "okay";
++
++ pwr_key: pwr {
++ label = "pwr_button";
++ // linux,code = <205>; // KEY_SUSPEND
++ linux,code = <116>; // KEY_POWER
++ gpios = <&gio 20 GPIO_ACTIVE_LOW>;
++ debounce-interval = <50>; // ms
++ };
++ };
++};
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
++
++/* SDIO2 drives the WLAN interface */
++&sdio2 {
++ pinctrl-0 = <&sdio2_30_pins>;
++ pinctrl-names = "default";
++ bus-width = <4>;
++ vmmc-supply = <&wl_on_reg>;
++ sd-uhs-ddr50;
++ non-removable;
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ wifi: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ local-mac-address = [00 00 00 00 00 00];
++ };
++};
++
++&rpivid {
++ status = "okay";
++};
++
++&pinctrl {
++ spi10_gpio2: spi10_gpio2 {
++ function = "vc_spi0";
++ pins = "gpio2", "gpio3", "gpio4";
++ bias-disable;
++ };
++
++ spi10_cs_gpio1: spi10_cs_gpio1 {
++ function = "gpio";
++ pins = "gpio1";
++ bias-pull-up;
++ };
++};
++
++spi10_pins: &spi10_gpio2 {};
++spi10_cs_pins: &spi10_cs_gpio1 {};
++
++&spi10 {
++ pinctrl-names = "default";
++ cs-gpios = <&gio 1 1>;
++ pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
++
++ spidev10: spidev@0 {
++ compatible = "spidev";
++ reg = <0>; /* CE0 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <20000000>;
++ status = "okay";
++ };
++};
++
++// =============================================
++// Board specific stuff here
++
++&gio_aon {
++ // Don't use GIO_AON as an interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ /delete-property/ interrupt-controller;
++};
++
++&main_aon_irq {
++ // Don't use the MAIN_AON_IRQ interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ status = "disabled";
++};
++
++&rp1_pwm1 {
++ status = "disabled";
++ pinctrl-0 = <&rp1_pwm1_gpio45>;
++ pinctrl-names = "default";
++};
++
++&thermal_trips {
++ cpu_tepid: cpu-tepid {
++ temperature = <50000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_warm: cpu-warm {
++ temperature = <60000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_hot: cpu-hot {
++ temperature = <67500>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_vhot: cpu-vhot {
++ temperature = <75000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++};
++
++&cooling_maps {
++ tepid {
++ trip = <&cpu_tepid>;
++ cooling-device = <&fan 1 1>;
++ };
++
++ warm {
++ trip = <&cpu_warm>;
++ cooling-device = <&fan 2 2>;
++ };
++
++ hot {
++ trip = <&cpu_hot>;
++ cooling-device = <&fan 3 3>;
++ };
++
++ vhot {
++ trip = <&cpu_vhot>;
++ cooling-device = <&fan 4 4>;
++ };
++
++ melt {
++ trip = <&cpu_crit>;
++ cooling-device = <&fan 4 4>;
++ };
++};
++
++&gio {
++ // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
++ // to reduce the clutter in gpioinfo/pinctrl
++ brcm,gpio-bank-widths = <32 4>;
++
++ gpio-line-names =
++ "-", // GPIO_000
++ "2712_BOOT_CS_N", // GPIO_001
++ "2712_BOOT_MISO", // GPIO_002
++ "2712_BOOT_MOSI", // GPIO_003
++ "2712_BOOT_SCLK", // GPIO_004
++ "-", // GPIO_005
++ "-", // GPIO_006
++ "-", // GPIO_007
++ "-", // GPIO_008
++ "-", // GPIO_009
++ "-", // GPIO_010
++ "-", // GPIO_011
++ "-", // GPIO_012
++ "-", // GPIO_013
++ "PCIE_SDA", // GPIO_014
++ "PCIE_SCL", // GPIO_015
++ "-", // GPIO_016
++ "-", // GPIO_017
++ "-", // GPIO_018
++ "-", // GPIO_019
++ "PWR_GPIO", // GPIO_020
++ "2712_G21_FS", // GPIO_021
++ "-", // GPIO_022
++ "-", // GPIO_023
++ "BT_RTS", // GPIO_024
++ "BT_CTS", // GPIO_025
++ "BT_TXD", // GPIO_026
++ "BT_RXD", // GPIO_027
++ "WL_ON", // GPIO_028
++ "BT_ON", // GPIO_029
++ "WIFI_SDIO_CLK", // GPIO_030
++ "WIFI_SDIO_CMD", // GPIO_031
++ "WIFI_SDIO_D0", // GPIO_032
++ "WIFI_SDIO_D1", // GPIO_033
++ "WIFI_SDIO_D2", // GPIO_034
++ "WIFI_SDIO_D3"; // GPIO_035
++};
++
++&gio_aon {
++ gpio-line-names =
++ "RP1_SDA", // AON_GPIO_00
++ "RP1_SCL", // AON_GPIO_01
++ "RP1_RUN", // AON_GPIO_02
++ "SD_IOVDD_SEL", // AON_GPIO_03
++ "SD_PWR_ON", // AON_GPIO_04
++ "SD_CDET_N", // AON_GPIO_05
++ "SD_FLG_N", // AON_GPIO_06
++ "-", // AON_GPIO_07
++ "2712_WAKE", // AON_GPIO_08
++ "2712_STAT_LED", // AON_GPIO_09
++ "-", // AON_GPIO_10
++ "-", // AON_GPIO_11
++ "PMIC_INT", // AON_GPIO_12
++ "UART_TX_FS", // AON_GPIO_13
++ "UART_RX_FS", // AON_GPIO_14
++ "-", // AON_GPIO_15
++ "-", // AON_GPIO_16
++
++ // Pad bank0 out to 32 entries
++ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
++
++ "HDMI0_SCL", // AON_SGPIO_00
++ "HDMI0_SDA", // AON_SGPIO_01
++ "HDMI1_SCL", // AON_SGPIO_02
++ "HDMI1_SDA", // AON_SGPIO_03
++ "PMIC_SCL", // AON_SGPIO_04
++ "PMIC_SDA"; // AON_SGPIO_05
++
++ rp1_run_hog {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RP1 RUN pin";
++ };
++};
++
++&rp1_gpio {
++ gpio-line-names =
++ "ID_SDA", // GPIO0
++ "ID_SCL", // GPIO1
++ "GPIO2", // GPIO2
++ "GPIO3", // GPIO3
++ "GPIO4", // GPIO4
++ "GPIO5", // GPIO5
++ "GPIO6", // GPIO6
++ "GPIO7", // GPIO7
++ "GPIO8", // GPIO8
++ "GPIO9", // GPIO9
++ "GPIO10", // GPIO10
++ "GPIO11", // GPIO11
++ "GPIO12", // GPIO12
++ "GPIO13", // GPIO13
++ "GPIO14", // GPIO14
++ "GPIO15", // GPIO15
++ "GPIO16", // GPIO16
++ "GPIO17", // GPIO17
++ "GPIO18", // GPIO18
++ "GPIO19", // GPIO19
++ "GPIO20", // GPIO20
++ "GPIO21", // GPIO21
++ "GPIO22", // GPIO22
++ "GPIO23", // GPIO23
++ "GPIO24", // GPIO24
++ "GPIO25", // GPIO25
++ "GPIO26", // GPIO26
++ "GPIO27", // GPIO27
++
++ "PCIE_RP1_WAKE", // GPIO28
++ "FAN_TACH", // GPIO29
++ "HOST_SDA", // GPIO30
++ "HOST_SCL", // GPIO31
++ "ETH_RST_N", // GPIO32
++ "-", // GPIO33
++
++ "CD0_IO0_MICCLK", // GPIO34
++ "CD0_IO0_MICDAT0", // GPIO35
++ "RP1_PCIE_CLKREQ_N", // GPIO36
++ "-", // GPIO37
++ "CD0_SDA", // GPIO38
++ "CD0_SCL", // GPIO39
++ "CD1_SDA", // GPIO40
++ "CD1_SCL", // GPIO41
++ "USB_VBUS_EN", // GPIO42
++ "USB_OC_N", // GPIO43
++ "RP1_STAT_LED", // GPIO44
++ "FAN_PWM", // GPIO45
++ "CD1_IO0_MICCLK", // GPIO46
++ "2712_WAKE", // GPIO47
++ "CD1_IO1_MICDAT1", // GPIO48
++ "EN_MAX_USB_CUR", // GPIO49
++ "-", // GPIO50
++ "-", // GPIO51
++ "-", // GPIO52
++ "-"; // GPIO53
++
++ usb_vbus_pins: usb_vbus_pins {
++ function = "vbus1";
++ pins = "gpio42", "gpio43";
++ };
++};
++
++/ {
++ aliases: aliases {
++ blconfig = &blconfig;
++ blpubkey = &blpubkey;
++ bluetooth = &bluetooth;
++ console = &uart10;
++ ethernet0 = &rp1_eth;
++ wifi0 = &wifi;
++ fb = &fb;
++ mailbox = &mailbox;
++ mmc0 = &sdio1;
++ uart0 = &uart0;
++ uart1 = &uart1;
++ uart2 = &uart2;
++ uart3 = &uart3;
++ uart4 = &uart4;
++ uart10 = &uart10;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial10 = &uart10;
++ i2c = &i2c_arm;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c10 = &i2c_rp1boot;
++ // Bit-bashed i2c_gpios start at 10
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ spi5 = &spi5;
++ spi10 = &spi10;
++ gpio0 = &gpio;
++ gpio1 = &gio;
++ gpio2 = &gio_aon;
++ gpio3 = &pinctrl;
++ gpio4 = &pinctrl_aon;
++ usb0 = &rp1_usb0;
++ usb1 = &rp1_usb1;
++ drm-dsi1 = &dsi0;
++ drm-dsi2 = &dsi1;
++ };
++
++ __overrides__ {
++ bdaddr = <&bluetooth>, "local-bd-address[";
++ button_debounce = <&pwr_key>, "debounce-interval:0";
++ cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
++ uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
++ i2c0 = <&i2c0>, "status";
++ i2c1 = <&i2c1>, "status";
++ i2c = <&i2c1>, "status";
++ i2c_arm = <&i2c_arm>, "status";
++ i2c_vc = <&i2c_vc>, "status";
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
++ i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
++ i2c0_baudrate = <&i2c0>, "clock-frequency:0";
++ i2c1_baudrate = <&i2c1>, "clock-frequency:0";
++ i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
++ krnbt = <&bluetooth>, "status";
++ nvme = <&pciex1>, "status";
++ pciex1 = <&pciex1>, "status";
++ pciex1_gen = <&pciex1> , "max-link-speed:0";
++ pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
++ pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ random = <&random>, "status";
++ rtc = <&rpi_rtc>, "status";
++ rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
++ sd_cqe = <&sdio1>, "supports-cqe?";
++ spi = <&spi0>, "status";
++ suspend = <&pwr_key>, "linux,code:0=205";
++ uart0 = <&uart0>, "status";
++ wifiaddr = <&wifi>, "local-mac-address[";
++
++ act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
++ act_led_activelow = <&led_act>,"gpios:8";
++ act_led_trigger = <&led_act>, "linux,default-trigger";
++ pwr_led_gpio = <&led_pwr>,"gpios:4";
++ pwr_led_activelow = <&led_pwr>, "gpios:8";
++ pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++ drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
++ drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
++ drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
++ drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
++ drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
++ drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
++ drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
++ drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
++ drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
++ drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
++ drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
++ drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
++
++ fan_temp0 = <&cpu_tepid>,"temperature:0";
++ fan_temp1 = <&cpu_warm>,"temperature:0";
++ fan_temp2 = <&cpu_hot>,"temperature:0";
++ fan_temp3 = <&cpu_vhot>,"temperature:0";
++ fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
++ fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
++ fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
++ fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
++ fan_temp0_speed = <&fan>, "cooling-levels:4";
++ fan_temp1_speed = <&fan>, "cooling-levels:8";
++ fan_temp2_speed = <&fan>, "cooling-levels:12";
++ fan_temp3_speed = <&fan>, "cooling-levels:16";
++ };
++};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
+@@ -1,2 +1,20 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "arm/broadcom/bcm2712-rpi-cm5-cm4io.dts"
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5.dtsi"
++
++// The RP1 USB3 interfaces are not usable on CM4IO
++
++&rp1_usb0 {
++ status = "disabled";
++};
++
++&rp1_usb1 {
++ status = "disabled";
++};
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
+@@ -1,2 +1,10 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "arm/broadcom/bcm2712-rpi-cm5-cm5io.dts"
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5.dtsi"
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
++++ /dev/null
+@@ -1,890 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/clock/rp1.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/mfd/rp1.h>
+-#include <dt-bindings/pwm/pwm.h>
+-#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
+-
+-#define i2c0 _i2c0
+-#define i2c3 _i2c3
+-#define i2c4 _i2c4
+-#define i2c5 _i2c5
+-#define i2c6 _i2c6
+-#define i2c8 _i2c8
+-#define i2s _i2s
+-#define pwm0 _pwm0
+-#define pwm1 _pwm1
+-#define spi0 _spi0
+-#define spi3 _spi3
+-#define spi4 _spi4
+-#define spi5 _spi5
+-#define spi6 _spi6
+-#define uart0 _uart0
+-#define uart2 _uart2
+-#define uart5 _uart5
+-
+-#include "bcm2712.dtsi"
+-
+-#undef i2c0
+-#undef i2c3
+-#undef i2c4
+-#undef i2c5
+-#undef i2c6
+-#undef i2c8
+-#undef i2s
+-#undef pwm0
+-#undef pwm1
+-#undef spi0
+-#undef spi3
+-#undef spi4
+-#undef spi5
+-#undef spi6
+-#undef uart0
+-#undef uart2
+-#undef uart3
+-#undef uart4
+-#undef uart5
+-
+-/ {
+- compatible = "raspberrypi,5-compute-module", "brcm,bcm2712";
+- model = "Raspberry Pi Compute Module 5";
+-
+- /* Will be filled by the bootloader */
+- memory@0 {
+- device_type = "memory";
+- reg = <0 0 0x28000000>;
+- };
+-
+- leds: leds {
+- compatible = "gpio-leds";
+-
+- led_pwr: led-pwr {
+- label = "PWR";
+- gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "none";
+- };
+-
+- led_act: led-act {
+- label = "ACT";
+- gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "mmc0";
+- };
+- };
+-
+- sd_io_1v8_reg: sd_io_1v8_reg {
+- compatible = "regulator-gpio";
+- regulator-name = "vdd-sd-io";
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- regulator-always-on;
+- regulator-settling-time-us = <5000>;
+- gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
+- states = <1800000 0x1
+- 3300000 0x0>;
+- status = "okay";
+- };
+-
+- sd_vcc_reg: sd_vcc_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc-sd";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- enable-active-high;
+- gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
+- status = "okay";
+- };
+-
+- wl_on_reg: wl_on_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "wl-on-regulator";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- pinctrl-0 = <&wl_on_pins>;
+- pinctrl-names = "default";
+-
+- gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
+-
+- startup-delay-us = <150000>;
+- enable-active-high;
+- };
+-
+- clocks: clocks {
+- };
+-
+- cam1_clk: cam1_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_clk: cam0_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_reg: cam0_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam0_reg";
+- enable-active-high;
+- status = "okay";
+- gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to CAM_GPIO on connector
+- };
+-
+- cam_dummy_reg: cam_dummy_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam-dummy-reg";
+- status = "okay";
+- };
+-
+- dummy: dummy {
+- // A target for unwanted overlay fragments
+- };
+-
+-
+- // A few extra labels to keep overlays happy
+-
+- i2c0if: i2c0if {};
+- i2c0mux: i2c0mux {};
+-};
+-
+-rp1_target: &pcie2 {
+- brcm,enable-mps-rcb;
+- brcm,vdm-qos-map = <0xbbaa9888>;
+- aspm-no-l0s;
+- status = "okay";
+-};
+-
+-// Add some labels to 2712 device
+-
+-// The system UART
+-uart10: &_uart0 { status = "okay"; };
+-
+-// The system SPI for the bootloader EEPROM
+-spi10: &_spi0 { status = "okay"; };
+-
+-i2c_rp1boot: &_i2c3 { };
+-
+-#include "rp1.dtsi"
+-
+-&rp1 {
+- // PCIe address space layout:
+- // 00_00000000-00_00xxxxxx = RP1 peripherals
+- // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
+-
+- // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
+- // This is the RP1 peripheral space
+- ranges = <0xc0 0x40000000
+- 0x02000000 0x00 0x00000000
+- 0x00 0x00400000>;
+-
+- dma-ranges =
+- // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x10 0x00000000
+- 0x43000000 0x10 0x00000000
+- 0x10 0x00000000>,
+-
+- // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
+- // This allows the RP1 DMA controller to address RP1 hardware
+- <0xc0 0x40000000
+- 0x02000000 0x0 0x00000000
+- 0x0 0x00400000>,
+-
+- // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x00 0x00000000
+- 0x02000000 0x10 0x00000000
+- 0x10 0x00000000>;
+-};
+-
+-// Expose RP1 nodes as system nodes with labels
+-
+-&rp1_dma {
+- status = "okay";
+-};
+-
+-&rp1_eth {
+- status = "okay";
+- phy-handle = <&phy1>;
+- phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
+- phy-reset-duration = <5>;
+-
+- phy1: ethernet-phy@1 {
+- reg = <0x1>;
+- brcm,powerdown-enable;
+- interrupt-parent = <&gpio>;
+- interrupts = <37 IRQ_TYPE_LEVEL_LOW>;
+- };
+-};
+-
+-gpio: &rp1_gpio {
+- status = "okay";
+-};
+-
+-aux: &dummy {};
+-
+-&rp1_usb0 {
+- pinctrl-0 = <&usb_vbus_pins>;
+- pinctrl-names = "default";
+- status = "okay";
+-};
+-
+-&rp1_usb1 {
+- status = "okay";
+-};
+-
+-#include "bcm2712-rpi.dtsi"
+-
+-i2c_csi_dsi0: &i2c6 { // Note: This is for MIPI0 connector only
+- pinctrl-0 = <&rp1_i2c6_38_39>;
+- pinctrl-names = "default";
+- clock-frequency = <100000>;
+-};
+-
+-i2c_csi_dsi1: &i2c0 { // Note: This is for MIPI1 connector
+-};
+-
+-i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
+-
+-cam1_reg: &cam0_reg { // Shares CAM_GPIO with cam0_reg
+-};
+-
+-csi0: &rp1_csi0 { };
+-csi1: &rp1_csi1 { };
+-dsi0: &rp1_dsi0 { };
+-dsi1: &rp1_dsi1 { };
+-dpi: &rp1_dpi { };
+-vec: &rp1_vec { };
+-dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
+-dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
+-dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
+-dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
+-dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
+-dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
+-dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
+-dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
+-dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
+-dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
+-
+-/* Add the IOMMUs for some RP1 bus masters */
+-
+-&csi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&csi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dpi {
+- iommus = <&iommu5>;
+-};
+-
+-&vec {
+- iommus = <&iommu5>;
+-};
+-
+-&ddc0 {
+- status = "disabled";
+-};
+-
+-&ddc1 {
+- status = "disabled";
+-};
+-
+-&hdmi0 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hdmi1 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hvs {
+- clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
+- clock-names = "core", "disp";
+-};
+-
+-&mop {
+- status = "disabled";
+-};
+-
+-&moplet {
+- status = "disabled";
+-};
+-
+-&pixelvalve0 {
+- status = "disabled";
+-};
+-
+-&pixelvalve1 {
+- status = "disabled";
+-};
+-
+-&disp_intr {
+- status = "disabled";
+-};
+-
+-/* SDIO1 is used to drive the eMMC/SD card */
+-&sdio1 {
+- pinctrl-0 = <&emmc_cmddat_pulls>, <&emmc_ds_pull>;
+- pinctrl-names = "default";
+- vqmmc-supply = <&sd_io_1v8_reg>;
+- vmmc-supply = <&sd_vcc_reg>;
+- bus-width = <8>;
+- sd-uhs-sdr50;
+- sd-uhs-ddr50;
+- sd-uhs-sdr104;
+- mmc-hs200-1_8v;
+- mmc-hs400-1_8v;
+- mmc-hs400-enhanced-strobe;
+- broken-cd;
+- supports-cqe;
+- status = "okay";
+-};
+-
+-&pinctrl_aon {
+- ant_pins: ant_pins {
+- function = "gpio";
+- pins = "aon_gpio5", "aon_gpio6";
+- };
+-
+- /* Slight hack - only one PWM pin (status LED) is usable */
+- aon_pwm_1pin: aon_pwm_1pin {
+- function = "aon_pwm";
+- pins = "aon_gpio9";
+- };
+-};
+-
+-&pinctrl {
+- pwr_button_pins: pwr_button_pins {
+- function = "gpio";
+- pins = "gpio20";
+- bias-pull-up;
+- };
+-
+- wl_on_pins: wl_on_pins {
+- function = "gpio";
+- pins = "gpio28";
+- };
+-
+- bt_shutdown_pins: bt_shutdown_pins {
+- function = "gpio";
+- pins = "gpio29";
+- };
+-
+- emmc_ds_pull: emmc_ds_pull {
+- pins = "emmc_ds";
+- bias-pull-down;
+- };
+-
+- emmc_cmddat_pulls: emmc_cmddat_pulls {
+- pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3",
+- "emmc_dat4", "emmc_dat5", "emmc_dat6", "emmc_dat7";
+- bias-pull-up;
+- };
+-};
+-
+-/* uarta communicates with the BT module */
+-&uarta {
+- uart-has-rtscts;
+- auto-flow-control;
+- status = "okay";
+- clock-frequency = <96000000>;
+- pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
+- pinctrl-names = "default";
+-
+- bluetooth: bluetooth {
+- compatible = "brcm,bcm43438-bt";
+- max-speed = <3000000>;
+- shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
+- local-bd-address = [ 00 00 00 00 00 00 ];
+- };
+-};
+-
+-&i2c_rp1boot {
+- clock-frequency = <400000>;
+- pinctrl-0 = <&i2c3_m4_agpio0_pins>;
+- pinctrl-names = "default";
+-};
+-
+-/ {
+- chosen: chosen {
+- bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe";
+- stdout-path = "serial10:115200n8";
+- };
+-
+- fan: cooling_fan {
+- status = "disabled";
+- compatible = "pwm-fan";
+- #cooling-cells = <2>;
+- cooling-min-state = <0>;
+- cooling-max-state = <3>;
+- cooling-levels = <0 75 125 175 250>;
+- pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
+- rpm-regmap = <&rp1_pwm1>;
+- rpm-offset = <0x3c>;
+- };
+-
+- pwr_button {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&pwr_button_pins>;
+- status = "okay";
+-
+- pwr_key: pwr {
+- label = "pwr_button";
+- // linux,code = <205>; // KEY_SUSPEND
+- linux,code = <116>; // KEY_POWER
+- gpios = <&gio 20 GPIO_ACTIVE_LOW>;
+- debounce-interval = <50>; // ms
+- };
+- };
+-};
+-
+-&usb {
+- power-domains = <&power RPI_POWER_DOMAIN_USB>;
+-};
+-
+-/* SDIO2 drives the WLAN interface */
+-&sdio2 {
+- pinctrl-0 = <&sdio2_30_pins>, <&ant_pins>;
+- pinctrl-names = "default";
+- bus-width = <4>;
+- vmmc-supply = <&wl_on_reg>;
+- sd-uhs-ddr50;
+- non-removable;
+- status = "okay";
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- wifi: wifi@1 {
+- reg = <1>;
+- compatible = "brcm,bcm4329-fmac";
+- local-mac-address = [00 00 00 00 00 00];
+- };
+-};
+-
+-&rpivid {
+- status = "okay";
+-};
+-
+-&pinctrl {
+- spi10_gpio2: spi10_gpio2 {
+- function = "vc_spi0";
+- pins = "gpio2", "gpio3", "gpio4";
+- bias-disable;
+- };
+-
+- spi10_cs_gpio1: spi10_cs_gpio1 {
+- function = "gpio";
+- pins = "gpio1";
+- bias-pull-up;
+- };
+-};
+-
+-spi10_pins: &spi10_gpio2 {};
+-spi10_cs_pins: &spi10_cs_gpio1 {};
+-
+-&spi10 {
+- pinctrl-names = "default";
+- cs-gpios = <&gio 1 1>;
+- pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
+-
+- spidev10: spidev@0 {
+- compatible = "spidev";
+- reg = <0>; /* CE0 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <20000000>;
+- status = "okay";
+- };
+-};
+-
+-// =============================================
+-// Board specific stuff here
+-
+-&gio_aon {
+- // Don't use GIO_AON as an interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- /delete-property/ interrupt-controller;
+-};
+-
+-&main_aon_irq {
+- // Don't use the MAIN_AON_IRQ interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- status = "disabled";
+-};
+-
+-&rp1_pwm1 {
+- status = "disabled";
+- pinctrl-0 = <&rp1_pwm1_gpio45>;
+- pinctrl-names = "default";
+-};
+-
+-&thermal_trips {
+- cpu_tepid: cpu-tepid {
+- temperature = <50000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_warm: cpu-warm {
+- temperature = <60000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_hot: cpu-hot {
+- temperature = <67500>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_vhot: cpu-vhot {
+- temperature = <75000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-};
+-
+-&cooling_maps {
+- tepid {
+- trip = <&cpu_tepid>;
+- cooling-device = <&fan 1 1>;
+- };
+-
+- warm {
+- trip = <&cpu_warm>;
+- cooling-device = <&fan 2 2>;
+- };
+-
+- hot {
+- trip = <&cpu_hot>;
+- cooling-device = <&fan 3 3>;
+- };
+-
+- vhot {
+- trip = <&cpu_vhot>;
+- cooling-device = <&fan 4 4>;
+- };
+-
+- melt {
+- trip = <&cpu_crit>;
+- cooling-device = <&fan 4 4>;
+- };
+-};
+-
+-&gio {
+- // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
+- // to reduce the clutter in gpioinfo/pinctrl
+- brcm,gpio-bank-widths = <32 4>;
+-
+- gpio-line-names =
+- "-", // GPIO_000
+- "2712_BOOT_CS_N", // GPIO_001
+- "2712_BOOT_MISO", // GPIO_002
+- "2712_BOOT_MOSI", // GPIO_003
+- "2712_BOOT_SCLK", // GPIO_004
+- "-", // GPIO_005
+- "-", // GPIO_006
+- "-", // GPIO_007
+- "-", // GPIO_008
+- "-", // GPIO_009
+- "-", // GPIO_010
+- "-", // GPIO_011
+- "-", // GPIO_012
+- "-", // GPIO_013
+- "-", // GPIO_014
+- "-", // GPIO_015
+- "-", // GPIO_016
+- "-", // GPIO_017
+- "-", // GPIO_018
+- "-", // GPIO_019
+- "PWR_GPIO", // GPIO_020
+- "2712_G21_FS", // GPIO_021
+- "-", // GPIO_022
+- "-", // GPIO_023
+- "BT_RTS", // GPIO_024
+- "BT_CTS", // GPIO_025
+- "BT_TXD", // GPIO_026
+- "BT_RXD", // GPIO_027
+- "WL_ON", // GPIO_028
+- "BT_ON", // GPIO_029
+- "WIFI_SDIO_CLK", // GPIO_030
+- "WIFI_SDIO_CMD", // GPIO_031
+- "WIFI_SDIO_D0", // GPIO_032
+- "WIFI_SDIO_D1", // GPIO_033
+- "WIFI_SDIO_D2", // GPIO_034
+- "WIFI_SDIO_D3"; // GPIO_035
+-};
+-
+-&gio_aon {
+- gpio-line-names =
+- "RP1_SDA", // AON_GPIO_00
+- "RP1_SCL", // AON_GPIO_01
+- "RP1_RUN", // AON_GPIO_02
+- "SD_IOVDD_SEL", // AON_GPIO_03
+- "SD_PWR_ON", // AON_GPIO_04
+- "ANT1", // AON_GPIO_05
+- "ANT2", // AON_GPIO_06
+- "-", // AON_GPIO_07
+- "2712_WAKE", // AON_GPIO_08
+- "2712_STAT_LED", // AON_GPIO_09
+- "-", // AON_GPIO_10
+- "-", // AON_GPIO_11
+- "PMIC_INT", // AON_GPIO_12
+- "UART_TX_FS", // AON_GPIO_13
+- "UART_RX_FS", // AON_GPIO_14
+- "-", // AON_GPIO_15
+- "-", // AON_GPIO_16
+-
+- // Pad bank0 out to 32 entries
+- "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+-
+- "HDMI0_SCL", // AON_SGPIO_00
+- "HDMI0_SDA", // AON_SGPIO_01
+- "HDMI1_SCL", // AON_SGPIO_02
+- "HDMI1_SDA", // AON_SGPIO_03
+- "PMIC_SCL", // AON_SGPIO_04
+- "PMIC_SDA"; // AON_SGPIO_05
+-
+- rp1_run_hog {
+- gpio-hog;
+- gpios = <2 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "RP1 RUN pin";
+- };
+-
+- ant1: ant1-hog {
+- gpio-hog;
+- gpios = <5 GPIO_ACTIVE_HIGH>;
+- /* internal antenna enabled */
+- output-high;
+- line-name = "ant1";
+- };
+-
+- ant2: ant2-hog {
+- gpio-hog;
+- gpios = <6 GPIO_ACTIVE_HIGH>;
+- /* external antenna disabled */
+- output-low;
+- line-name = "ant2";
+- };
+-};
+-
+-&rp1_gpio {
+- gpio-line-names =
+- "ID_SDA", // GPIO0
+- "ID_SCL", // GPIO1
+- "GPIO2", // GPIO2
+- "GPIO3", // GPIO3
+- "GPIO4", // GPIO4
+- "GPIO5", // GPIO5
+- "GPIO6", // GPIO6
+- "GPIO7", // GPIO7
+- "GPIO8", // GPIO8
+- "GPIO9", // GPIO9
+- "GPIO10", // GPIO10
+- "GPIO11", // GPIO11
+- "GPIO12", // GPIO12
+- "GPIO13", // GPIO13
+- "GPIO14", // GPIO14
+- "GPIO15", // GPIO15
+- "GPIO16", // GPIO16
+- "GPIO17", // GPIO17
+- "GPIO18", // GPIO18
+- "GPIO19", // GPIO19
+- "GPIO20", // GPIO20
+- "GPIO21", // GPIO21
+- "GPIO22", // GPIO22
+- "GPIO23", // GPIO23
+- "GPIO24", // GPIO24
+- "GPIO25", // GPIO25
+- "GPIO26", // GPIO26
+- "GPIO27", // GPIO27
+-
+- "PCIE_PWR_EN", // GPIO28
+- "FAN_TACH", // GPIO29
+- "HOST_SDA", // GPIO30
+- "HOST_SCL", // GPIO31
+- "ETH_RST_N", // GPIO32
+- "PCIE_DET_WAKE", // GPIO33
+-
+- "CD0_IO0_MICCLK", // GPIO34
+- "CD0_IO0_MICDAT0", // GPIO35
+- "RP1_PCIE_CLKREQ_N", // GPIO36
+- "ETH_IRQ_N", // GPIO37
+- "SDA0", // GPIO38
+- "SCL0", // GPIO39
+- "-", // GPIO40
+- "-", // GPIO41
+- "USB_VBUS_EN", // GPIO42
+- "USB_OC_N", // GPIO43
+- "RP1_STAT_LED", // GPIO44
+- "FAN_PWM", // GPIO45
+- "-", // GPIO46
+- "2712_WAKE", // GPIO47
+- "-", // GPIO48
+- "-", // GPIO49
+- "-", // GPIO50
+- "-", // GPIO51
+- "-", // GPIO52
+- "-"; // GPIO53
+-
+- usb_vbus_pins: usb_vbus_pins {
+- function = "vbus1";
+- pins = "gpio42", "gpio43";
+- };
+-};
+-
+-/ {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+- __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_activelow = <&led_act>, "active-low?";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+- ant1 = <&ant1>,"output-high?=on",
+- <&ant1>, "output-low?=off",
+- <&ant2>, "output-high?=off",
+- <&ant2>, "output-low?=on";
+- ant2 = <&ant1>,"output-high?=off",
+- <&ant1>, "output-low?=on",
+- <&ant2>, "output-high?=on",
+- <&ant2>, "output-low?=off";
+- noant = <&ant1>,"output-high?=off",
+- <&ant1>, "output-low?=on",
+- <&ant2>, "output-high?=off",
+- <&ant2>, "output-low?=on";
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+- };
+-};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
+@@ -0,0 +1,884 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/clock/rp1.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/mfd/rp1.h>
++#include <dt-bindings/pwm/pwm.h>
++#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
++
++#define i2c0 _i2c0
++#define i2c3 _i2c3
++#define i2c4 _i2c4
++#define i2c5 _i2c5
++#define i2c6 _i2c6
++#define i2c8 _i2c8
++#define i2s _i2s
++#define pwm0 _pwm0
++#define pwm1 _pwm1
++#define spi0 _spi0
++#define spi3 _spi3
++#define spi4 _spi4
++#define spi5 _spi5
++#define spi6 _spi6
++#define uart0 _uart0
++#define uart2 _uart2
++#define uart5 _uart5
++
++#include "bcm2712.dtsi"
++
++#undef i2c0
++#undef i2c3
++#undef i2c4
++#undef i2c5
++#undef i2c6
++#undef i2c8
++#undef i2s
++#undef pwm0
++#undef pwm1
++#undef spi0
++#undef spi3
++#undef spi4
++#undef spi5
++#undef spi6
++#undef uart0
++#undef uart2
++#undef uart3
++#undef uart4
++#undef uart5
++
++/ {
++ compatible = "raspberrypi,5-compute-module", "brcm,bcm2712";
++ model = "Raspberry Pi Compute Module 5";
++
++ /* Will be filled by the bootloader */
++ memory@0 {
++ device_type = "memory";
++ reg = <0 0 0x28000000>;
++ };
++
++ leds: leds {
++ compatible = "gpio-leds";
++
++ led_pwr: led-pwr {
++ label = "PWR";
++ gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "none";
++ };
++
++ led_act: led-act {
++ label = "ACT";
++ gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "mmc0";
++ };
++ };
++
++ sd_io_1v8_reg: sd_io_1v8_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vdd-sd-io";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ };
++
++ sd_vcc_reg: sd_vcc_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-sd";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ enable-active-high;
++ gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++ };
++
++ wl_on_reg: wl_on_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "wl-on-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ pinctrl-0 = <&wl_on_pins>;
++ pinctrl-names = "default";
++
++ gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
++
++ startup-delay-us = <150000>;
++ enable-active-high;
++ };
++
++ clocks: clocks {
++ };
++
++ cam1_clk: cam1_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_clk: cam0_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_reg: cam0_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam0_reg";
++ enable-active-high;
++ status = "okay";
++ gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to CAM_GPIO on connector
++ };
++
++ cam_dummy_reg: cam_dummy_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dummy-reg";
++ status = "okay";
++ };
++
++ dummy: dummy {
++ // A target for unwanted overlay fragments
++ };
++
++
++ // A few extra labels to keep overlays happy
++
++ i2c0if: i2c0if {};
++ i2c0mux: i2c0mux {};
++};
++
++rp1_target: &pcie2 {
++ brcm,enable-mps-rcb;
++ brcm,vdm-qos-map = <0xbbaa9888>;
++ aspm-no-l0s;
++ status = "okay";
++};
++
++// Add some labels to 2712 device
++
++// The system UART
++uart10: &_uart0 { status = "okay"; };
++
++// The system SPI for the bootloader EEPROM
++spi10: &_spi0 { status = "okay"; };
++
++i2c_rp1boot: &_i2c3 { };
++
++#include "rp1.dtsi"
++
++&rp1 {
++ // PCIe address space layout:
++ // 00_00000000-00_00xxxxxx = RP1 peripherals
++ // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
++
++ // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
++ // This is the RP1 peripheral space
++ ranges = <0xc0 0x40000000
++ 0x02000000 0x00 0x00000000
++ 0x00 0x00400000>;
++
++ dma-ranges =
++ // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x10 0x00000000
++ 0x43000000 0x10 0x00000000
++ 0x10 0x00000000>,
++
++ // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
++ // This allows the RP1 DMA controller to address RP1 hardware
++ <0xc0 0x40000000
++ 0x02000000 0x0 0x00000000
++ 0x0 0x00400000>,
++
++ // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x00 0x00000000
++ 0x02000000 0x10 0x00000000
++ 0x10 0x00000000>;
++};
++
++// Expose RP1 nodes as system nodes with labels
++
++&rp1_dma {
++ status = "okay";
++};
++
++&rp1_eth {
++ status = "okay";
++ phy-handle = <&phy1>;
++ phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
++ phy-reset-duration = <5>;
++
++ phy1: ethernet-phy@1 {
++ reg = <0x1>;
++ brcm,powerdown-enable;
++ interrupt-parent = <&gpio>;
++ interrupts = <37 IRQ_TYPE_LEVEL_LOW>;
++ };
++};
++
++gpio: &rp1_gpio {
++ status = "okay";
++};
++
++aux: &dummy {};
++
++&rp1_usb0 {
++ pinctrl-0 = <&usb_vbus_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&rp1_usb1 {
++ status = "okay";
++};
++
++#include "bcm2712-rpi.dtsi"
++
++i2c_csi_dsi0: &i2c6 { // Note: This is for MIPI0 connector only
++ pinctrl-0 = <&rp1_i2c6_38_39>;
++ pinctrl-names = "default";
++ clock-frequency = <100000>;
++};
++
++i2c_csi_dsi1: &i2c0 { // Note: This is for MIPI1 connector
++};
++
++i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
++
++cam1_reg: &cam0_reg { // Shares CAM_GPIO with cam0_reg
++};
++
++csi0: &rp1_csi0 { };
++csi1: &rp1_csi1 { };
++dsi0: &rp1_dsi0 { };
++dsi1: &rp1_dsi1 { };
++dpi: &rp1_dpi { };
++vec: &rp1_vec { };
++dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
++dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
++dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
++dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
++dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
++dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
++dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
++dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
++dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
++dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
++
++/* Add the IOMMUs for some RP1 bus masters */
++
++&csi0 {
++ iommus = <&iommu5>;
++};
++
++&csi1 {
++ iommus = <&iommu5>;
++};
++
++&dsi0 {
++ iommus = <&iommu5>;
++};
++
++&dsi1 {
++ iommus = <&iommu5>;
++};
++
++&dpi {
++ iommus = <&iommu5>;
++};
++
++&vec {
++ iommus = <&iommu5>;
++};
++
++&ddc0 {
++ status = "disabled";
++};
++
++&ddc1 {
++ status = "disabled";
++};
++
++&hdmi0 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hdmi1 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hvs {
++ clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
++ clock-names = "core", "disp";
++};
++
++&mop {
++ status = "disabled";
++};
++
++&moplet {
++ status = "disabled";
++};
++
++&pixelvalve0 {
++ status = "disabled";
++};
++
++&pixelvalve1 {
++ status = "disabled";
++};
++
++&disp_intr {
++ status = "disabled";
++};
++
++/* SDIO1 is used to drive the eMMC/SD card */
++&sdio1 {
++ pinctrl-0 = <&emmc_cmddat_pulls>, <&emmc_ds_pull>;
++ pinctrl-names = "default";
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ vmmc-supply = <&sd_vcc_reg>;
++ bus-width = <8>;
++ sd-uhs-sdr50;
++ sd-uhs-ddr50;
++ sd-uhs-sdr104;
++ mmc-hs200-1_8v;
++ mmc-hs400-1_8v;
++ mmc-hs400-enhanced-strobe;
++ broken-cd;
++ supports-cqe;
++ status = "okay";
++};
++
++&pinctrl_aon {
++ ant_pins: ant_pins {
++ function = "gpio";
++ pins = "aon_gpio5", "aon_gpio6";
++ };
++
++ /* Slight hack - only one PWM pin (status LED) is usable */
++ aon_pwm_1pin: aon_pwm_1pin {
++ function = "aon_pwm";
++ pins = "aon_gpio9";
++ };
++};
++
++&pinctrl {
++ pwr_button_pins: pwr_button_pins {
++ function = "gpio";
++ pins = "gpio20";
++ bias-pull-up;
++ };
++
++ wl_on_pins: wl_on_pins {
++ function = "gpio";
++ pins = "gpio28";
++ };
++
++ bt_shutdown_pins: bt_shutdown_pins {
++ function = "gpio";
++ pins = "gpio29";
++ };
++
++ emmc_ds_pull: emmc_ds_pull {
++ pins = "emmc_ds";
++ bias-pull-down;
++ };
++
++ emmc_cmddat_pulls: emmc_cmddat_pulls {
++ pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3",
++ "emmc_dat4", "emmc_dat5", "emmc_dat6", "emmc_dat7";
++ bias-pull-up;
++ };
++};
++
++/* uarta communicates with the BT module */
++&uarta {
++ uart-has-rtscts;
++ auto-flow-control;
++ status = "okay";
++ clock-frequency = <96000000>;
++ pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
++ pinctrl-names = "default";
++
++ bluetooth: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
++ shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
++ local-bd-address = [ 00 00 00 00 00 00 ];
++ };
++};
++
++&i2c_rp1boot {
++ clock-frequency = <400000>;
++ pinctrl-0 = <&i2c3_m4_agpio0_pins>;
++ pinctrl-names = "default";
++};
++
++/ {
++ chosen: chosen {
++ bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe";
++ stdout-path = "serial10:115200n8";
++ };
++
++ fan: cooling_fan {
++ status = "disabled";
++ compatible = "pwm-fan";
++ #cooling-cells = <2>;
++ cooling-min-state = <0>;
++ cooling-max-state = <3>;
++ cooling-levels = <0 75 125 175 250>;
++ pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
++ rpm-regmap = <&rp1_pwm1>;
++ rpm-offset = <0x3c>;
++ };
++
++ pwr_button {
++ compatible = "gpio-keys";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwr_button_pins>;
++ status = "okay";
++
++ pwr_key: pwr {
++ label = "pwr_button";
++ // linux,code = <205>; // KEY_SUSPEND
++ linux,code = <116>; // KEY_POWER
++ gpios = <&gio 20 GPIO_ACTIVE_LOW>;
++ debounce-interval = <50>; // ms
++ };
++ };
++};
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
++
++/* SDIO2 drives the WLAN interface */
++&sdio2 {
++ pinctrl-0 = <&sdio2_30_pins>, <&ant_pins>;
++ pinctrl-names = "default";
++ bus-width = <4>;
++ vmmc-supply = <&wl_on_reg>;
++ sd-uhs-ddr50;
++ non-removable;
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ wifi: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ local-mac-address = [00 00 00 00 00 00];
++ };
++};
++
++&rpivid {
++ status = "okay";
++};
++
++&pinctrl {
++ spi10_gpio2: spi10_gpio2 {
++ function = "vc_spi0";
++ pins = "gpio2", "gpio3", "gpio4";
++ bias-disable;
++ };
++
++ spi10_cs_gpio1: spi10_cs_gpio1 {
++ function = "gpio";
++ pins = "gpio1";
++ bias-pull-up;
++ };
++};
++
++spi10_pins: &spi10_gpio2 {};
++spi10_cs_pins: &spi10_cs_gpio1 {};
++
++&spi10 {
++ pinctrl-names = "default";
++ cs-gpios = <&gio 1 1>;
++ pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
++
++ spidev10: spidev@0 {
++ compatible = "spidev";
++ reg = <0>; /* CE0 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <20000000>;
++ status = "okay";
++ };
++};
++
++// =============================================
++// Board specific stuff here
++
++&gio_aon {
++ // Don't use GIO_AON as an interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ /delete-property/ interrupt-controller;
++};
++
++&main_aon_irq {
++ // Don't use the MAIN_AON_IRQ interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ status = "disabled";
++};
++
++&rp1_pwm1 {
++ status = "disabled";
++ pinctrl-0 = <&rp1_pwm1_gpio45>;
++ pinctrl-names = "default";
++};
++
++&thermal_trips {
++ cpu_tepid: cpu-tepid {
++ temperature = <50000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_warm: cpu-warm {
++ temperature = <60000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_hot: cpu-hot {
++ temperature = <67500>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_vhot: cpu-vhot {
++ temperature = <75000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++};
++
++&cooling_maps {
++ tepid {
++ trip = <&cpu_tepid>;
++ cooling-device = <&fan 1 1>;
++ };
++
++ warm {
++ trip = <&cpu_warm>;
++ cooling-device = <&fan 2 2>;
++ };
++
++ hot {
++ trip = <&cpu_hot>;
++ cooling-device = <&fan 3 3>;
++ };
++
++ vhot {
++ trip = <&cpu_vhot>;
++ cooling-device = <&fan 4 4>;
++ };
++
++ melt {
++ trip = <&cpu_crit>;
++ cooling-device = <&fan 4 4>;
++ };
++};
++
++&gio {
++ // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
++ // to reduce the clutter in gpioinfo/pinctrl
++ brcm,gpio-bank-widths = <32 4>;
++
++ gpio-line-names =
++ "-", // GPIO_000
++ "2712_BOOT_CS_N", // GPIO_001
++ "2712_BOOT_MISO", // GPIO_002
++ "2712_BOOT_MOSI", // GPIO_003
++ "2712_BOOT_SCLK", // GPIO_004
++ "-", // GPIO_005
++ "-", // GPIO_006
++ "-", // GPIO_007
++ "-", // GPIO_008
++ "-", // GPIO_009
++ "-", // GPIO_010
++ "-", // GPIO_011
++ "-", // GPIO_012
++ "-", // GPIO_013
++ "-", // GPIO_014
++ "-", // GPIO_015
++ "-", // GPIO_016
++ "-", // GPIO_017
++ "-", // GPIO_018
++ "-", // GPIO_019
++ "PWR_GPIO", // GPIO_020
++ "2712_G21_FS", // GPIO_021
++ "-", // GPIO_022
++ "-", // GPIO_023
++ "BT_RTS", // GPIO_024
++ "BT_CTS", // GPIO_025
++ "BT_TXD", // GPIO_026
++ "BT_RXD", // GPIO_027
++ "WL_ON", // GPIO_028
++ "BT_ON", // GPIO_029
++ "WIFI_SDIO_CLK", // GPIO_030
++ "WIFI_SDIO_CMD", // GPIO_031
++ "WIFI_SDIO_D0", // GPIO_032
++ "WIFI_SDIO_D1", // GPIO_033
++ "WIFI_SDIO_D2", // GPIO_034
++ "WIFI_SDIO_D3"; // GPIO_035
++};
++
++&gio_aon {
++ gpio-line-names =
++ "RP1_SDA", // AON_GPIO_00
++ "RP1_SCL", // AON_GPIO_01
++ "RP1_RUN", // AON_GPIO_02
++ "SD_IOVDD_SEL", // AON_GPIO_03
++ "SD_PWR_ON", // AON_GPIO_04
++ "ANT1", // AON_GPIO_05
++ "ANT2", // AON_GPIO_06
++ "-", // AON_GPIO_07
++ "2712_WAKE", // AON_GPIO_08
++ "2712_STAT_LED", // AON_GPIO_09
++ "-", // AON_GPIO_10
++ "-", // AON_GPIO_11
++ "PMIC_INT", // AON_GPIO_12
++ "UART_TX_FS", // AON_GPIO_13
++ "UART_RX_FS", // AON_GPIO_14
++ "-", // AON_GPIO_15
++ "-", // AON_GPIO_16
++
++ // Pad bank0 out to 32 entries
++ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
++
++ "HDMI0_SCL", // AON_SGPIO_00
++ "HDMI0_SDA", // AON_SGPIO_01
++ "HDMI1_SCL", // AON_SGPIO_02
++ "HDMI1_SDA", // AON_SGPIO_03
++ "PMIC_SCL", // AON_SGPIO_04
++ "PMIC_SDA"; // AON_SGPIO_05
++
++ rp1_run_hog {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RP1 RUN pin";
++ };
++
++ ant1: ant1-hog {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ /* internal antenna enabled */
++ output-high;
++ line-name = "ant1";
++ };
++
++ ant2: ant2-hog {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ /* external antenna disabled */
++ output-low;
++ line-name = "ant2";
++ };
++};
++
++&rp1_gpio {
++ gpio-line-names =
++ "ID_SDA", // GPIO0
++ "ID_SCL", // GPIO1
++ "GPIO2", // GPIO2
++ "GPIO3", // GPIO3
++ "GPIO4", // GPIO4
++ "GPIO5", // GPIO5
++ "GPIO6", // GPIO6
++ "GPIO7", // GPIO7
++ "GPIO8", // GPIO8
++ "GPIO9", // GPIO9
++ "GPIO10", // GPIO10
++ "GPIO11", // GPIO11
++ "GPIO12", // GPIO12
++ "GPIO13", // GPIO13
++ "GPIO14", // GPIO14
++ "GPIO15", // GPIO15
++ "GPIO16", // GPIO16
++ "GPIO17", // GPIO17
++ "GPIO18", // GPIO18
++ "GPIO19", // GPIO19
++ "GPIO20", // GPIO20
++ "GPIO21", // GPIO21
++ "GPIO22", // GPIO22
++ "GPIO23", // GPIO23
++ "GPIO24", // GPIO24
++ "GPIO25", // GPIO25
++ "GPIO26", // GPIO26
++ "GPIO27", // GPIO27
++
++ "PCIE_PWR_EN", // GPIO28
++ "FAN_TACH", // GPIO29
++ "HOST_SDA", // GPIO30
++ "HOST_SCL", // GPIO31
++ "ETH_RST_N", // GPIO32
++ "PCIE_DET_WAKE", // GPIO33
++
++ "CD0_IO0_MICCLK", // GPIO34
++ "CD0_IO0_MICDAT0", // GPIO35
++ "RP1_PCIE_CLKREQ_N", // GPIO36
++ "ETH_IRQ_N", // GPIO37
++ "SDA0", // GPIO38
++ "SCL0", // GPIO39
++ "-", // GPIO40
++ "-", // GPIO41
++ "USB_VBUS_EN", // GPIO42
++ "USB_OC_N", // GPIO43
++ "RP1_STAT_LED", // GPIO44
++ "FAN_PWM", // GPIO45
++ "-", // GPIO46
++ "2712_WAKE", // GPIO47
++ "-", // GPIO48
++ "-", // GPIO49
++ "-", // GPIO50
++ "-", // GPIO51
++ "-", // GPIO52
++ "-"; // GPIO53
++
++ usb_vbus_pins: usb_vbus_pins {
++ function = "vbus1";
++ pins = "gpio42", "gpio43";
++ };
++};
++
++/ {
++ aliases: aliases {
++ blconfig = &blconfig;
++ blpubkey = &blpubkey;
++ bluetooth = &bluetooth;
++ console = &uart10;
++ ethernet0 = &rp1_eth;
++ wifi0 = &wifi;
++ fb = &fb;
++ mailbox = &mailbox;
++ mmc0 = &sdio1;
++ uart0 = &uart0;
++ uart1 = &uart1;
++ uart2 = &uart2;
++ uart3 = &uart3;
++ uart4 = &uart4;
++ uart10 = &uart10;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial10 = &uart10;
++ i2c = &i2c_arm;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c10 = &i2c_rp1boot;
++ // Bit-bashed i2c_gpios start at 10
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ spi5 = &spi5;
++ spi10 = &spi10;
++ gpio0 = &gpio;
++ gpio1 = &gio;
++ gpio2 = &gio_aon;
++ gpio3 = &pinctrl;
++ gpio4 = &pinctrl_aon;
++ usb0 = &rp1_usb0;
++ usb1 = &rp1_usb1;
++ drm-dsi1 = &dsi0;
++ drm-dsi2 = &dsi1;
++ };
++
++ __overrides__ {
++ bdaddr = <&bluetooth>, "local-bd-address[";
++ button_debounce = <&pwr_key>, "debounce-interval:0";
++ cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
++ uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
++ i2c0 = <&i2c0>, "status";
++ i2c1 = <&i2c1>, "status";
++ i2c = <&i2c1>, "status";
++ i2c_arm = <&i2c_arm>, "status";
++ i2c_vc = <&i2c_vc>, "status";
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
++ i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
++ i2c0_baudrate = <&i2c0>, "clock-frequency:0";
++ i2c1_baudrate = <&i2c1>, "clock-frequency:0";
++ i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
++ krnbt = <&bluetooth>, "status";
++ nvme = <&pciex1>, "status";
++ pciex1 = <&pciex1>, "status";
++ pciex1_gen = <&pciex1> , "max-link-speed:0";
++ pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
++ pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ random = <&random>, "status";
++ rtc = <&rpi_rtc>, "status";
++ rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
++ spi = <&spi0>, "status";
++ suspend = <&pwr_key>, "linux,code:0=205";
++ uart0 = <&uart0>, "status";
++ wifiaddr = <&wifi>, "local-mac-address[";
++
++ act_led_activelow = <&led_act>, "active-low?";
++ act_led_trigger = <&led_act>, "linux,default-trigger";
++ pwr_led_activelow = <&led_pwr>, "gpios:8";
++ pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++ drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
++ drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
++ drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
++ drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
++ drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
++ drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
++ drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
++ drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
++ drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
++ drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
++ drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
++ drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
++
++ ant1 = <&ant1>,"output-high?=on",
++ <&ant1>, "output-low?=off",
++ <&ant2>, "output-high?=off",
++ <&ant2>, "output-low?=on";
++ ant2 = <&ant1>,"output-high?=off",
++ <&ant1>, "output-low?=on",
++ <&ant2>, "output-high?=on",
++ <&ant2>, "output-low?=off";
++ noant = <&ant1>,"output-high?=off",
++ <&ant1>, "output-low?=on",
++ <&ant2>, "output-high?=off",
++ <&ant2>, "output-low?=on";
++
++ fan_temp0 = <&cpu_tepid>,"temperature:0";
++ fan_temp1 = <&cpu_warm>,"temperature:0";
++ fan_temp2 = <&cpu_hot>,"temperature:0";
++ fan_temp3 = <&cpu_vhot>,"temperature:0";
++ fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
++ fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
++ fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
++ fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
++ fan_temp0_speed = <&fan>, "cooling-levels:4";
++ fan_temp1_speed = <&fan>, "cooling-levels:8";
++ fan_temp2_speed = <&fan>, "cooling-levels:12";
++ fan_temp3_speed = <&fan>, "cooling-levels:16";
++ };
++};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
+@@ -1,2 +1,107 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "../../../../arm/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts"
++#include "bcm2712-rpi-5-b.dts"
++
++&gio {
++ brcm,gpio-bank-widths = <32 4>;
++
++ gpio-line-names =
++ "", // GPIO_000
++ "2712_BOOT_CS_N", // GPIO_001
++ "2712_BOOT_MISO", // GPIO_002
++ "2712_BOOT_MOSI", // GPIO_003
++ "2712_BOOT_SCLK", // GPIO_004
++ "", // GPIO_005
++ "", // GPIO_006
++ "", // GPIO_007
++ "", // GPIO_008
++ "", // GPIO_009
++ "", // GPIO_010
++ "", // GPIO_011
++ "", // GPIO_012
++ "", // GPIO_013
++ "PCIE_SDA", // GPIO_014
++ "PCIE_SCL", // GPIO_015
++ "", // GPIO_016
++ "", // GPIO_017
++ "-", // GPIO_018
++ "-", // GPIO_019
++ "PWR_GPIO", // GPIO_020
++ "2712_G21_FS", // GPIO_021
++ "-", // GPIO_022
++ "-", // GPIO_023
++ "BT_RTS", // GPIO_024
++ "BT_CTS", // GPIO_025
++ "BT_TXD", // GPIO_026
++ "BT_RXD", // GPIO_027
++ "WL_ON", // GPIO_028
++ "BT_ON", // GPIO_029
++ "WIFI_SDIO_CLK", // GPIO_030
++ "WIFI_SDIO_CMD", // GPIO_031
++ "WIFI_SDIO_D0", // GPIO_032
++ "WIFI_SDIO_D1", // GPIO_033
++ "WIFI_SDIO_D2", // GPIO_034
++ "WIFI_SDIO_D3"; // GPIO_035
++};
++
++&gio_aon {
++ brcm,gpio-bank-widths = <15 6>;
++
++ gpio-line-names =
++ "RP1_SDA", // AON_GPIO_00
++ "RP1_SCL", // AON_GPIO_01
++ "RP1_RUN", // AON_GPIO_02
++ "SD_IOVDD_SEL", // AON_GPIO_03
++ "SD_PWR_ON", // AON_GPIO_04
++ "SD_CDET_N", // AON_GPIO_05
++ "SD_FLG_N", // AON_GPIO_06
++ "", // AON_GPIO_07
++ "2712_WAKE", // AON_GPIO_08
++ "2712_STAT_LED", // AON_GPIO_09
++ "", // AON_GPIO_10
++ "", // AON_GPIO_11
++ "PMIC_INT", // AON_GPIO_12
++ "UART_TX_FS", // AON_GPIO_13
++ "UART_RX_FS", // AON_GPIO_14
++ "", // AON_GPIO_15
++ "", // AON_GPIO_16
++
++ // Pad bank0 out to 32 entries
++ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
++
++ "HDMI0_SCL", // AON_SGPIO_00
++ "HDMI0_SDA", // AON_SGPIO_01
++ "HDMI1_SCL", // AON_SGPIO_02
++ "HDMI1_SDA", // AON_SGPIO_03
++ "PMIC_SCL", // AON_SGPIO_04
++ "PMIC_SDA"; // AON_SGPIO_05
++};
++
++&pinctrl {
++ compatible = "brcm,bcm2712d0-pinctrl";
++ reg = <0x7d504100 0x20>;
++};
++
++&pinctrl_aon {
++ compatible = "brcm,bcm2712d0-aon-pinctrl";
++ reg = <0x7d510700 0x1c>;
++};
++
++&vc4 {
++ compatible = "brcm,bcm2712d0-vc6";
++};
++
++&uart10 {
++ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
++};
++
++&spi10 {
++ dmas = <&dma40 3>, <&dma40 4>;
++};
++
++&hdmi0 {
++ dmas = <&dma40 (12|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
++
++&hdmi1 {
++ dmas = <&dma40 (13|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ /dev/null
+@@ -1,351 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-
+-#include <dt-bindings/power/raspberrypi-power.h>
+-
+-&soc {
+- firmware: firmware {
+- compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- mboxes = <&mailbox>;
+- dma-ranges;
+-
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+- reset: reset {
+- compatible = "raspberrypi,firmware-reset";
+- #reset-cells = <1>;
+- };
+-
+- vcio: vcio {
+- compatible = "raspberrypi,vcio";
+- };
+- };
+-
+- power: power {
+- compatible = "raspberrypi,bcm2835-power";
+- firmware = <&firmware>;
+- #power-domain-cells = <1>;
+- };
+-
+- fb: fb {
+- compatible = "brcm,bcm2708-fb";
+- firmware = <&firmware>;
+- status = "okay";
+- };
+-
+- rpi_rtc: rpi_rtc {
+- compatible = "raspberrypi,rpi-rtc";
+- firmware = <&firmware>;
+- status = "okay";
+- trickle-charge-microvolt = <0>;
+- };
+-
+- nvmem {
+- compatible = "simple-bus";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- nvmem_otp: nvmem_otp {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <0 192>;
+- status = "okay";
+- };
+-
+- nvmem_cust: nvmem_cust {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <1 8>;
+- status = "okay";
+- };
+-
+- nvmem_mac: nvmem_mac {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <2 6>;
+- status = "okay";
+- };
+-
+- nvmem_priv: nvmem_priv {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <3 16>;
+- status = "okay";
+- };
+- };
+-
+- /* Define these notional regulators for use by overlays, etc. */
+- vdd_3v3_reg: fixedregulator_3v3 {
+- compatible = "regulator-fixed";
+- regulator-always-on;
+- regulator-max-microvolt = <3300000>;
+- regulator-min-microvolt = <3300000>;
+- regulator-name = "3v3";
+- };
+-
+- vdd_5v0_reg: fixedregulator_5v0 {
+- compatible = "regulator-fixed";
+- regulator-always-on;
+- regulator-max-microvolt = <5000000>;
+- regulator-min-microvolt = <5000000>;
+- regulator-name = "5v0";
+- };
+-};
+-
+-/ {
+- __overrides__ {
+- arm_freq;
+- axiperf = <&axiperf>,"status";
+-
+- nvmem_cust_rw = <&nvmem_cust>,"rw?";
+- nvmem_priv_rw = <&nvmem_priv>,"rw?";
+- nvmem_mac_rw = <&nvmem_mac>,"rw?";
+- strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
+-
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4",
+- <&cam0_reg>,"gpio:0=", <&gpio>;
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4",
+- <&cam1_reg>,"gpio:0=", <&gpio>;
+-
+- };
+-};
+-
+-pciex1: &pcie1 { };
+-pciex4: &pcie2 { };
+-
+-&dma32 {
+- /* The VPU firmware uses DMA channel 11 for VCHIQ */
+- brcm,dma-channel-mask = <0x03f>;
+-};
+-
+-&dma40 {
+- /* The VPU firmware DMA channel 11 for VCHIQ */
+- brcm,dma-channel-mask = <0x07c0>;
+-};
+-
+-&hdmi0 {
+- dmas = <&dma40 (10|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+-
+-&hdmi1 {
+- dmas = <&dma40 (17|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+-
+-&spi10 {
+- dmas = <&dma40 6>, <&dma40 7>;
+- dma-names = "tx", "rx";
+-};
+-
+-&usb {
+- power-domains = <&power RPI_POWER_DOMAIN_USB>;
+-};
+-
+-&rmem {
+- /*
+- * RPi5's co-processor will copy the board's bootloader configuration
+- * into memory for the OS to consume. It'll also update this node with
+- * its placement information.
+- */
+- blconfig: nvram@0 {
+- compatible = "raspberrypi,bootloader-config", "nvmem-rmem";
+- #address-cells = <1>;
+- #size-cells = <1>;
+- reg = <0x0 0x0 0x0>;
+- no-map;
+- status = "disabled";
+- };
+- /*
+- * RPi5 will copy the binary public key blob (if present) from the bootloader
+- * into memory for use by the OS.
+- */
+- blpubkey: nvram@1 {
+- compatible = "raspberrypi,bootloader-public-key", "nvmem-rmem";
+- #address-cells = <1>;
+- #size-cells = <1>;
+- reg = <0x0 0x0 0x0>;
+- no-map;
+- status = "disabled";
+- };
+-};
+-
+-&rp1_adc {
+- status = "okay";
+-};
+-
+-/* Add some gpiomem nodes to make the devices accessible to userspace.
+- * /dev/gpiomem<n> should expose the registers for the interface with DT alias
+- * gpio<n>.
+- */
+-
+-&rp1 {
+- gpiomem@d0000 {
+- /* Export IO_BANKs, RIO_BANKs and PADS_BANKs to userspace */
+- compatible = "raspberrypi,gpiomem";
+- reg = <0xc0 0x400d0000 0x0 0x30000>;
+- chardev-name = "gpiomem0";
+- };
+-};
+-
+-&soc {
+- gpiomem@7d508500 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d508500 0x40>;
+- chardev-name = "gpiomem1";
+- };
+-
+- gpiomem@7d517c00 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d517c00 0x40>;
+- chardev-name = "gpiomem2";
+- };
+-
+- gpiomem@7d504100 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d504100 0x20>;
+- chardev-name = "gpiomem3";
+- };
+-
+- gpiomem@7d510700 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d510700 0x20>;
+- chardev-name = "gpiomem4";
+- };
+-
+- sound: sound {
+- status = "disabled";
+- };
+-};
+-
+-i2c0: &rp1_i2c0 { };
+-i2c1: &rp1_i2c1 { };
+-i2c2: &rp1_i2c2 { };
+-i2c3: &rp1_i2c3 { };
+-i2c4: &rp1_i2c4 { };
+-i2c5: &rp1_i2c5 { };
+-i2c6: &rp1_i2c6 { };
+-i2s: &rp1_i2s0 { };
+-i2s_clk_producer: &rp1_i2s0 { };
+-i2s_clk_consumer: &rp1_i2s1 { };
+-pwm0: &rp1_pwm0 { };
+-pwm1: &rp1_pwm1 { };
+-pwm: &pwm0 { };
+-spi0: &rp1_spi0 { };
+-spi1: &rp1_spi1 { };
+-spi2: &rp1_spi2 { };
+-spi3: &rp1_spi3 { };
+-spi4: &rp1_spi4 { };
+-spi5: &rp1_spi5 { };
+-
+-uart0_pins: &rp1_uart0_14_15 {};
+-uart0_ctsrts_pins: &rp1_uart0_ctsrts_16_17 {};
+-uart0: &rp1_uart0 {
+- pinctrl-0 = <&uart0_pins>;
+-};
+-
+-uart1_pins: &rp1_uart1_0_1 {};
+-uart1_ctsrts_pins: &rp1_uart1_ctsrts_2_3 {};
+-uart1: &rp1_uart1 { };
+-
+-uart2_pins: &rp1_uart2_4_5 {};
+-uart2_ctsrts_pins: &rp1_uart2_ctsrts_6_7 {};
+-uart2: &rp1_uart2 { };
+-
+-uart3_pins: &rp1_uart3_8_9 {};
+-uart3_ctsrts_pins: &rp1_uart3_ctsrts_10_11 {};
+-uart3: &rp1_uart3 { };
+-
+-uart4_pins: &rp1_uart4_12_13 {};
+-uart4_ctsrts_pins: &rp1_uart4_ctsrts_14_15 {};
+-uart4: &rp1_uart4 { };
+-
+-i2c0_pins: &rp1_i2c0_0_1 {};
+-i2c_vc: &i2c0 { // This is pins 27,28 on the header (not MIPI)
+- pinctrl-0 = <&i2c0_pins>;
+- pinctrl-names = "default";
+- clock-frequency = <100000>;
+-};
+-
+-i2c1_pins: &rp1_i2c1_2_3 {};
+-i2c_arm: &i2c1 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c1_pins>;
+- clock-frequency = <100000>;
+-};
+-
+-i2c2_pins: &rp1_i2c2_4_5 {};
+-&i2c2 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c2_pins>;
+-};
+-
+-i2c3_pins: &rp1_i2c3_6_7 {};
+-&i2c3 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c3_pins>;
+-};
+-
+-&i2s_clk_producer {
+- pinctrl-names = "default";
+- pinctrl-0 = <&rp1_i2s0_18_21>;
+-};
+-
+-&i2s_clk_consumer {
+- pinctrl-names = "default";
+- pinctrl-0 = <&rp1_i2s1_18_21>;
+-};
+-
+-spi0_pins: &rp1_spi0_gpio9 {};
+-spi0_cs_pins: &rp1_spi0_cs_gpio7 {};
+-
+-&spi0 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
+- cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
+-
+- spidev0: spidev@0 {
+- compatible = "spidev";
+- reg = <0>; /* CE0 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <125000000>;
+- };
+-
+- spidev1: spidev@1 {
+- compatible = "spidev";
+- reg = <1>; /* CE1 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <125000000>;
+- };
+-};
+-
+-spi2_pins: &rp1_spi2_gpio1 {};
+-&spi2 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi2_pins>;
+-};
+-
+-spi3_pins: &rp1_spi3_gpio5 {};
+-&spi3 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi3_pins>;
+-};
+-
+-spi4_pins: &rp1_spi4_gpio9 {};
+-&spi4 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi4_pins>;
+-};
+-
+-spi5_pins: &rp1_spi5_gpio13 {};
+-&spi5 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi5_pins>;
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712.dtsi
++++ /dev/null
+@@ -1,1302 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-#include <dt-bindings/interrupt-controller/arm-gic.h>
+-#include <dt-bindings/soc/bcm2835-pm.h>
+-#include <dt-bindings/phy/phy.h>
+-
+-/ {
+- compatible = "brcm,bcm2712", "brcm,bcm2711";
+- model = "BCM2712";
+-
+- #address-cells = <2>;
+- #size-cells = <1>;
+-
+- interrupt-parent = <&gicv2>;
+-
+- rmem: reserved-memory {
+- #address-cells = <2>;
+- #size-cells = <1>;
+- ranges;
+-
+- atf@0 {
+- reg = <0x0 0x0 0x80000>;
+- no-map;
+- };
+-
+- cma: linux,cma {
+- compatible = "shared-dma-pool";
+- size = <0x4000000>; /* 64MB */
+- reusable;
+- linux,cma-default;
+-
+- /*
+- * arm64 reserves the CMA by default somewhere in
+- * ZONE_DMA32, that's not good enough for the BCM2711
+- * as some devices can only address the lower 1G of
+- * memory (ZONE_DMA).
+- */
+- alloc-ranges = <0x0 0x00000000 0x40000000>;
+- };
+- };
+-
+- thermal-zones {
+- cpu_thermal: cpu-thermal {
+- polling-delay-passive = <2000>;
+- polling-delay = <1000>;
+- coefficients = <(-550) 450000>;
+- thermal-sensors = <&thermal>;
+-
+- thermal_trips: trips {
+- cpu_crit: cpu-crit {
+- temperature = <110000>;
+- hysteresis = <0>;
+- type = "critical";
+- };
+- };
+-
+- cooling_maps: cooling-maps {
+- };
+- };
+- };
+-
+- clk_27MHz: clk-27M {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <27000000>;
+- clock-output-names = "27MHz-clock";
+- };
+-
+- clk_108MHz: clk-108M {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <108000000>;
+- clock-output-names = "108MHz-clock";
+- };
+-
+- hvs: hvs@107c580000 {
+- compatible = "brcm,bcm2712-hvs";
+- reg = <0x10 0x7c580000 0x1a000>;
+- interrupt-parent = <&disp_intr>;
+- interrupts = <2>, <9>, <16>;
+- interrupt-names = "ch0-eof", "ch1-eof", "ch2-eof";
+- //iommus = <&iommu4>;
+- status = "disabled";
+- };
+-
+- soc: soc {
+- compatible = "simple-bus";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- ranges = <0x7c000000 0x10 0x7c000000 0x04000000>;
+- /* Emulate a contiguous 30-bit address range for DMA */
+- dma-ranges = <0xc0000000 0x00 0x00000000 0x40000000>,
+- <0x7c000000 0x10 0x7c000000 0x04000000>;
+-
+- system_timer: timer@7c003000 {
+- compatible = "brcm,bcm2835-system-timer";
+- reg = <0x7c003000 0x1000>;
+- interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+- clock-frequency = <1000000>;
+- };
+-
+- firmwarekms: firmwarekms@7d503000 {
+- compatible = "raspberrypi,rpi-firmware-kms-2712";
+- /* SUN_L2 interrupt reg */
+- reg = <0x7d503000 0x18>;
+- interrupt-parent = <&cpu_l2_irq>;
+- interrupts = <19>;
+- brcm,firmware = <&firmware>;
+- status = "disabled";
+- };
+-
+- axiperf: axiperf {
+- compatible = "brcm,bcm2712-axiperf";
+- reg = <0x7c012800 0x100>,
+- <0x7e000000 0x100>;
+- firmware = <&firmware>;
+- status = "disabled";
+- };
+-
+- mailbox: mailbox@7c013880 {
+- compatible = "brcm,bcm2835-mbox";
+- reg = <0x7c013880 0x40>;
+- interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+- #mbox-cells = <0>;
+- };
+-
+- pixelvalve0: pixelvalve@7c410000 {
+- compatible = "brcm,bcm2712-pixelvalve0";
+- reg = <0x7c410000 0x100>;
+- interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- pixelvalve1: pixelvalve@7c411000 {
+- compatible = "brcm,bcm2712-pixelvalve1";
+- reg = <0x7c411000 0x100>;
+- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- mop: mop@7c500000 {
+- compatible = "brcm,bcm2712-mop";
+- reg = <0x7c500000 0x28>;
+- interrupt-parent = <&disp_intr>;
+- interrupts = <1>;
+- status = "disabled";
+- };
+-
+- moplet: moplet@7c501000 {
+- compatible = "brcm,bcm2712-moplet";
+- reg = <0x7c501000 0x20>;
+- interrupt-parent = <&disp_intr>;
+- interrupts = <0>;
+- status = "disabled";
+- };
+-
+- disp_intr: interrupt-controller@7c502000 {
+- compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
+- reg = <0x7c502000 0x30>;
+- interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- status = "disabled";
+- };
+-
+- dvp: clock@7c700000 {
+- compatible = "brcm,brcm2711-dvp";
+- reg = <0x7c700000 0x10>;
+- clocks = <&clk_108MHz>;
+- #clock-cells = <1>;
+- #reset-cells = <1>;
+- };
+-
+- /*
+- * This node is the provider for the enable-method for
+- * bringing up secondary cores.
+- */
+- local_intc: local_intc@7cd00000 {
+- compatible = "brcm,bcm2836-l1-intc";
+- reg = <0x7cd00000 0x100>;
+- };
+-
+- uart0: serial@7d001000 {
+- compatible = "arm,pl011", "arm,primecell";
+- reg = <0x7d001000 0x200>;
+- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_uart>,
+- <&clk_vpu>;
+- clock-names = "uartclk", "apb_pclk";
+- arm,primecell-periphid = <0x00241011>;
+- status = "disabled";
+- };
+-
+- uart2: serial@7d001400 {
+- compatible = "arm,pl011", "arm,primecell";
+- reg = <0x7d001400 0x200>;
+- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_uart>,
+- <&clk_vpu>;
+- clock-names = "uartclk", "apb_pclk";
+- arm,primecell-periphid = <0x00241011>;
+- status = "disabled";
+- };
+-
+- uart5: serial@7d001a00 {
+- compatible = "arm,pl011", "arm,primecell";
+- reg = <0x7d001a00 0x200>;
+- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_uart>,
+- <&clk_vpu>;
+- clock-names = "uartclk", "apb_pclk";
+- arm,primecell-periphid = <0x00241011>;
+- status = "disabled";
+- };
+-
+- sdhost: mmc@7d002000 {
+- compatible = "brcm,bcm2835-sdhost";
+- reg = <0x7d002000 0x100>;
+- //interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- status = "disabled";
+- };
+-
+- i2s: i2s@7d003000 {
+- compatible = "brcm,bcm2835-i2s";
+- reg = <0x7d003000 0x24>;
+- //clocks = <&cprman BCM2835_CLOCK_PCM>;
+- status = "disabled";
+- };
+-
+- spi0: spi@7d004000 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004000 0x200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- num-cs = <1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi3: spi@7d004600 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004600 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi4: spi@7d004800 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004800 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi5: spi@7d004a00 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004a00 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi6: spi@7d004c00 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004c00 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c0: i2c@7d005000 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005000 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c3: i2c@7d005600 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005600 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c4: i2c@7d005800 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005800 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c5: i2c@7d005a00 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005a00 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c6: i2c@7d005c00 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005c00 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c8: i2c@7d005e00 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005e00 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- pwm0: pwm@7d00c000 {
+- compatible = "brcm,bcm2835-pwm";
+- reg = <0x7d00c000 0x28>;
+- assigned-clock-rates = <50000000>;
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm1: pwm@7d00c800 {
+- compatible = "brcm,bcm2835-pwm";
+- reg = <0x7d00c800 0x28>;
+- assigned-clock-rates = <50000000>;
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pm: watchdog@7d200000 {
+- compatible = "brcm,bcm2712-pm";
+- reg = <0x7d200000 0x308>;
+- reg-names = "pm";
+- #power-domain-cells = <1>;
+- #reset-cells = <1>;
+- //clocks = <&cprman BCM2835_CLOCK_V3D>,
+- // <&cprman BCM2835_CLOCK_PERI_IMAGE>,
+- // <&cprman BCM2835_CLOCK_H264>,
+- // <&cprman BCM2835_CLOCK_ISP>;
+- clock-names = "v3d", "peri_image", "h264", "isp";
+- system-power-controller;
+- };
+-
+- cprman: cprman@7d202000 {
+- compatible = "brcm,bcm2711-cprman";
+- reg = <0x7d202000 0x2000>;
+- #clock-cells = <1>;
+-
+- /* CPRMAN derives almost everything from the
+- * platform's oscillator. However, the DSI
+- * pixel clocks come from the DSI analog PHY.
+- */
+- clocks = <&clk_osc>;
+- status = "disabled";
+- };
+-
+- random: rng@7d208000 {
+- compatible = "brcm,bcm2711-rng200";
+- reg = <0x7d208000 0x28>;
+- status = "okay";
+- };
+-
+- cpu_l2_irq: intc@7d503000 {
+- compatible = "brcm,l2-intc";
+- reg = <0x7d503000 0x18>;
+- interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- pinctrl: pinctrl@7d504100 {
+- compatible = "brcm,bcm2712-pinctrl";
+- reg = <0x7d504100 0x30>;
+-
+- uarta_24_pins: uarta_24_pins {
+- pin_rts {
+- function = "uart0";
+- pins = "gpio24";
+- bias-disable;
+- };
+- pin_cts {
+- function = "uart0";
+- pins = "gpio25";
+- bias-pull-up;
+- };
+- pin_txd {
+- function = "uart0";
+- pins = "gpio26";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart0";
+- pins = "gpio27";
+- bias-pull-up;
+- };
+- };
+-
+- sdio2_30_pins: sdio2_30_pins {
+- pin_clk {
+- function = "sd2";
+- pins = "gpio30";
+- bias-disable;
+- };
+- pin_cmd {
+- function = "sd2";
+- pins = "gpio31";
+- bias-pull-up;
+- };
+- pins_dat {
+- function = "sd2";
+- pins = "gpio32", "gpio33", "gpio34", "gpio35";
+- bias-pull-up;
+- };
+- };
+- };
+-
+- ddc0: i2c@7d508200 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d508200 0x58>;
+- interrupt-parent = <&bsc_irq>;
+- interrupts = <1>;
+- clock-frequency = <97500>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- ddc1: i2c@7d508280 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d508280 0x58>;
+- interrupt-parent = <&bsc_irq>;
+- interrupts = <2>;
+- clock-frequency = <97500>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- bscd: i2c@7d508300 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d508300 0x58>;
+- interrupt-parent = <&bsc_irq>;
+- interrupts = <0>;
+- clock-frequency = <200000>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- bsc_irq: intc@7d508380 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d508380 0x10>;
+- interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- main_irq: intc@7d508400 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d508400 0x10>;
+- interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- gio: gpio@7d508500 {
+- compatible = "brcm,brcmstb-gpio";
+- reg = <0x7d508500 0x40>;
+- interrupt-parent = <&main_irq>;
+- interrupts = <0>;
+- gpio-controller;
+- #gpio-cells = <2>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,gpio-bank-widths = <32 22>;
+- brcm,gpio-direct;
+- };
+-
+- uarta: serial@7d50c000 {
+- compatible = "brcm,bcm7271-uart";
+- reg = <0x7d50c000 0x20>;
+- reg-names = "uart";
+- reg-shift = <2>;
+- reg-io-width = <4>;
+- interrupts = <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
+- skip-init;
+- status = "disabled";
+- };
+-
+- uartb: serial@7d50d000 {
+- compatible = "brcm,bcm7271-uart";
+- reg = <0x7d50d000 0x20>;
+- reg-names = "uart";
+- reg-shift = <2>;
+- reg-io-width = <4>;
+- interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
+- skip-init;
+- status = "disabled";
+- };
+-
+- aon_intr: interrupt-controller@7d510600 {
+- compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
+- reg = <0x7d510600 0x30>;
+- interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- status = "disabled";
+- };
+-
+- pinctrl_aon: pinctrl@7d510700 {
+- compatible = "brcm,bcm2712-aon-pinctrl";
+- reg = <0x7d510700 0x20>;
+-
+- i2c3_m4_agpio0_pins: i2c3_m4_agpio0_pins {
+- function = "vc_i2c3";
+- pins = "aon_gpio0", "aon_gpio1";
+- bias-pull-up;
+- };
+-
+- bsc_m1_agpio13_pins: bsc_m1_agpio13_pins {
+- function = "bsc_m1";
+- pins = "aon_gpio13", "aon_gpio14";
+- bias-pull-up;
+- };
+-
+- bsc_pmu_sgpio4_pins: bsc_pmu_sgpio4_pins {
+- function = "avs_pmu_bsc";
+- pins = "aon_sgpio4", "aon_sgpio5";
+- };
+-
+- bsc_m2_sgpio4_pins: bsc_m2_sgpio4_pins {
+- function = "bsc_m2";
+- pins = "aon_sgpio4", "aon_sgpio5";
+- };
+-
+- pwm_aon_agpio1_pins: pwm_aon_agpio1_pins {
+- function = "aon_pwm";
+- pins = "aon_gpio1", "aon_gpio2";
+- };
+-
+- pwm_aon_agpio4_pins: pwm_aon_agpio4_pins {
+- function = "vc_pwm0";
+- pins = "aon_gpio4", "aon_gpio5";
+- };
+-
+- pwm_aon_agpio7_pins: pwm_aon_agpio7_pins {
+- function = "aon_pwm";
+- pins = "aon_gpio7", "aon_gpio9";
+- };
+- };
+-
+- intc@7d517000 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d517000 0x10>;
+- interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- status = "disabled";
+- };
+-
+- bscc: i2c@7d517a00 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d517a00 0x58>;
+- interrupt-parent = <&bsc_aon_irq>;
+- interrupts = <0>;
+- clock-frequency = <200000>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- pwm_aon: pwm@7d517a80 {
+- compatible = "brcm,bcm7038-pwm";
+- reg = <0x7d517a80 0x28>;
+- #pwm-cells = <3>;
+- clocks = <&clk_27MHz>;
+- };
+-
+- main_aon_irq: intc@7d517ac0 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d517ac0 0x10>;
+- interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- bsc_aon_irq: intc@7d517b00 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d517b00 0x10>;
+- interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- gio_aon: gpio@7d517c00 {
+- compatible = "brcm,brcmstb-gpio";
+- reg = <0x7d517c00 0x40>;
+- interrupt-parent = <&main_aon_irq>;
+- interrupts = <0>;
+- gpio-controller;
+- #gpio-cells = <2>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,gpio-bank-widths = <17 6>;
+- brcm,gpio-direct;
+- };
+-
+- avs_monitor: avs-monitor@7d542000 {
+- compatible = "brcm,bcm2711-avs-monitor",
+- "syscon", "simple-mfd";
+- reg = <0x7d542000 0xf00>;
+- status = "okay";
+-
+- thermal: thermal {
+- compatible = "brcm,bcm2711-thermal";
+- #thermal-sensor-cells = <0>;
+- };
+- };
+-
+- bsc_pmu: i2c@7d544000 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d544000 0x58>;
+- interrupt-parent = <&bsc_aon_irq>;
+- interrupts = <1>;
+- clock-frequency = <200000>;
+- status = "disabled";
+- };
+-
+- hdmi0: hdmi@7ef00700 {
+- compatible = "brcm,bcm2712-hdmi0";
+- reg = <0x7c701400 0x300>,
+- <0x7c701000 0x200>,
+- <0x7c701d00 0x300>,
+- <0x7c702000 0x80>,
+- <0x7c703800 0x200>,
+- <0x7c704000 0x800>,
+- <0x7c700100 0x80>,
+- <0x7d510800 0x100>,
+- <0x7c720000 0x100>;
+- reg-names = "hdmi",
+- "dvp",
+- "phy",
+- "rm",
+- "packet",
+- "metadata",
+- "csc",
+- "cec",
+- "hd";
+- resets = <&dvp 1>;
+- interrupt-parent = <&aon_intr>;
+- interrupts = <1>, <2>, <3>,
+- <7>, <8>;
+- interrupt-names = "cec-tx", "cec-rx", "cec-low",
+- "hpd-connected", "hpd-removed";
+- ddc = <&ddc0>;
+- dmas = <&dma32 10>;
+- dma-names = "audio-rx";
+- status = "disabled";
+- };
+-
+- hdmi1: hdmi@7ef05700 {
+- compatible = "brcm,bcm2712-hdmi1";
+- reg = <0x7c706400 0x300>,
+- <0x7c706000 0x200>,
+- <0x7c706d00 0x300>,
+- <0x7c707000 0x80>,
+- <0x7c708800 0x200>,
+- <0x7c709000 0x800>,
+- <0x7c700180 0x80>,
+- <0x7d511000 0x100>,
+- <0x7c720000 0x100>;
+- reg-names = "hdmi",
+- "dvp",
+- "phy",
+- "rm",
+- "packet",
+- "metadata",
+- "csc",
+- "cec",
+- "hd";
+- ddc = <&ddc1>;
+- resets = <&dvp 2>;
+- interrupt-parent = <&aon_intr>;
+- interrupts = <11>, <12>, <13>,
+- <14>, <15>;
+- interrupt-names = "cec-tx", "cec-rx", "cec-low",
+- "hpd-connected", "hpd-removed";
+- dmas = <&dma32 17>;
+- dma-names = "audio-rx";
+- status = "disabled";
+- };
+- };
+-
+- arm-pmu {
+- compatible = "arm,cortex-a76-pmu";
+- interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+- };
+-
+- timer {
+- compatible = "arm,armv8-timer";
+- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>,
+- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>,
+- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>,
+- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>;
+- /* This only applies to the ARMv7 stub */
+- arm,cpu-registers-not-fw-configured;
+- };
+-
+- cpus: cpus {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
+-
+- /* Source for d/i cache-line-size, cache-sets, cache-size
+- * https://developer.arm.com/documentation/100798/0401
+- * /L1-memory-system/About-the-L1-memory-system?lang=en
+- */
+- cpu0: cpu@0 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x000>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l0>;
+- };
+-
+- cpu1: cpu@1 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x100>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l1>;
+- };
+-
+- cpu2: cpu@2 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x200>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l2>;
+- };
+-
+- cpu3: cpu@3 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x300>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l3>;
+- };
+-
+- /* Source for cache-line-size and cache-sets:
+- * https://developer.arm.com/documentation/100798/0401
+- * /L2-memory-system/About-the-L2-memory-system?lang=en
+- * and for cache-size:
+- * https://www.raspberrypi.com/documentation/computers
+- * /processors.html#bcm2712
+- */
+- l2_cache_l0: l2-cache-l0 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l1: l2-cache-l1 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l2: l2-cache-l2 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l3: l2-cache-l3 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- /* Source for cache-line-size and cache-sets:
+- * https://developer.arm.com/documentation/100453/0401/L3-cache?lang=en
+- * Source for cache-size:
+- * https://www.raspberrypi.com/documentation/computers/processors.html#bcm2712
+- */
+- l3_cache: l3-cache {
+- compatible = "cache";
+- cache-size = <0x200000>;
+- cache-line-size = <64>;
+- cache-sets = <2048>; // 2MiB(size)/64(line-size)=32768ways/16-way set
+- cache-level = <3>;
+- };
+- };
+-
+- psci {
+- method = "smc";
+- compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+- cpu_on = <0xc4000003>;
+- cpu_suspend = <0xc4000001>;
+- cpu_off = <0x84000002>;
+- };
+-
+- axi: axi {
+- compatible = "simple-bus";
+- #address-cells = <2>;
+- #size-cells = <2>;
+-
+- ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
+- <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
+- <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
+- <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
+- <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
+-
+- dma-ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
+- <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
+- <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
+- <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
+- <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
+-
+- vc4: gpu {
+- compatible = "brcm,bcm2712-vc6";
+- };
+-
+- iommu2: iommu@5100 {
+- /* IOMMU2 for PISP-BE, HEVC; and (unused) H264 accelerators */
+- compatible = "brcm,bcm2712-iommu";
+- reg = <0x10 0x5100 0x0 0x80>;
+- cache = <&iommuc>;
+- #iommu-cells = <0>;
+- };
+-
+- iommu4: iommu@5200 {
+- /* IOMMU4 for HVS, MPL/TXP; and (unused) Unicam, PISP-FE, MiniBVN */
+- compatible = "brcm,bcm2712-iommu";
+- reg = <0x10 0x5200 0x0 0x80>;
+- cache = <&iommuc>;
+- #iommu-cells = <0>;
+- #interconnect-cells = <0>;
+- };
+-
+- iommu5: iommu@5280 {
+- /* IOMMU5 for PCIe2 (RP1); and (unused) BSTM */
+- compatible = "brcm,bcm2712-iommu";
+- reg = <0x10 0x5280 0x0 0x80>;
+- cache = <&iommuc>;
+- #iommu-cells = <0>;
+- dma-iova-offset = <0x10 0x00000000>; // HACK for RP1 masters over PCIe
+- };
+-
+- iommuc: iommuc@5b00 {
+- compatible = "brcm,bcm2712-iommuc";
+- reg = <0x10 0x5b00 0x0 0x80>;
+- };
+-
+- dma32: dma@10000 {
+- compatible = "brcm,bcm2712-dma";
+- reg = <0x10 0x00010000 0 0x600>;
+- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "dma0",
+- "dma1",
+- "dma2",
+- "dma3",
+- "dma4",
+- "dma5";
+- #dma-cells = <1>;
+- brcm,dma-channel-mask = <0x0035>;
+- };
+-
+- dma40: dma@10600 {
+- compatible = "brcm,bcm2712-dma";
+- reg = <0x10 0x00010600 0 0x600>;
+- interrupts =
+- <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, /* dma4 6 */
+- <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, /* dma4 7 */
+- <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, /* dma4 8 */
+- <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, /* dma4 9 */
+- <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, /* dma4 10 */
+- <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; /* dma4 11 */
+- interrupt-names = "dma6",
+- "dma7",
+- "dma8",
+- "dma9",
+- "dma10",
+- "dma11";
+- #dma-cells = <1>;
+- brcm,dma-channel-mask = <0x0fc0>;
+- };
+-
+- // Single-lane Gen3 PCIe
+- // Outbound window at 0x14_000000-0x17_ffffff
+- pcie0: pcie@100000 {
+- compatible = "brcm,bcm2712-pcie";
+- reg = <0x10 0x00100000 0x0 0x9310>;
+- device_type = "pci";
+- max-link-speed = <2>;
+- #address-cells = <3>;
+- #interrupt-cells = <1>;
+- #size-cells = <2>;
+- /*
+- * Unused interrupts:
+- * 208: AER
+- * 215: NMI
+- * 216: PME
+- */
+- interrupt-parent = <&gicv2>;
+- interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "pcie", "msi";
+- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+- interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 209
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 2 &gicv2 GIC_SPI 210
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 3 &gicv2 GIC_SPI 211
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 4 &gicv2 GIC_SPI 212
+- IRQ_TYPE_LEVEL_HIGH>;
+- resets = <&bcm_reset 5>, <&bcm_reset 42>, <&pcie_rescal>;
+- reset-names = "swinit", "bridge", "rescal";
+- msi-controller;
+- msi-parent = <&pcie0>;
+-
+- ranges = <0x02000000 0x00 0x00000000
+- 0x17 0x00000000
+- 0x0 0xfffffffc>,
+- <0x43000000 0x04 0x00000000
+- 0x14 0x00000000
+- 0x3 0x00000000>;
+-
+- dma-ranges = <0x43000000 0x10 0x00000000
+- 0x00 0x00000000
+- 0x10 0x00000000>;
+-
+- status = "disabled";
+- };
+-
+- // Single-lane Gen3 PCIe
+- // Outbound window at 0x18_000000-0x1b_ffffff
+- pcie1: pcie@110000 {
+- compatible = "brcm,bcm2712-pcie";
+- reg = <0x10 0x00110000 0x0 0x9310>;
+- device_type = "pci";
+- max-link-speed = <2>;
+- #address-cells = <3>;
+- #interrupt-cells = <1>;
+- #size-cells = <2>;
+- /*
+- * Unused interrupts:
+- * 218: AER
+- * 225: NMI
+- * 226: PME
+- */
+- interrupt-parent = <&gicv2>;
+- interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "pcie", "msi";
+- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+- interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 219
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 2 &gicv2 GIC_SPI 220
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 3 &gicv2 GIC_SPI 221
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 4 &gicv2 GIC_SPI 222
+- IRQ_TYPE_LEVEL_HIGH>;
+- resets = <&bcm_reset 7>, <&bcm_reset 43>, <&pcie_rescal>;
+- reset-names = "swinit", "bridge", "rescal";
+- msi-controller;
+- msi-parent = <&mip1>;
+-
+- ranges = <0x02000000 0x00 0x00000000
+- 0x1b 0x00000000
+- 0x00 0xfffffffc>,
+- <0x43000000 0x04 0x00000000
+- 0x18 0x00000000
+- 0x03 0x00000000>;
+-
+- dma-ranges = <0x03000000 0x10 0x00000000
+- 0x00 0x00000000
+- 0x10 0x00000000>;
+-
+- status = "disabled";
+- };
+-
+- pcie_rescal: reset-controller@119500 {
+- compatible = "brcm,bcm7216-pcie-sata-rescal";
+- reg = <0x10 0x00119500 0x0 0x10>;
+- #reset-cells = <0>;
+- };
+-
+- // Quad-lane Gen3 PCIe
+- // Outbound window at 0x1c_000000-0x1f_ffffff
+- pcie2: pcie@120000 {
+- compatible = "brcm,bcm2712-pcie";
+- reg = <0x10 0x00120000 0x0 0x9310>;
+- device_type = "pci";
+- max-link-speed = <2>;
+- #address-cells = <3>;
+- #interrupt-cells = <1>;
+- #size-cells = <2>;
+- /*
+- * Unused interrupts:
+- * 228: AER
+- * 235: NMI
+- * 236: PME
+- */
+- interrupt-parent = <&gicv2>;
+- interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "pcie", "msi";
+- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+- interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 229
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 2 &gicv2 GIC_SPI 230
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 3 &gicv2 GIC_SPI 231
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 4 &gicv2 GIC_SPI 232
+- IRQ_TYPE_LEVEL_HIGH>;
+- resets = <&bcm_reset 32>, <&bcm_reset 44>, <&pcie_rescal>;
+- reset-names = "swinit", "bridge", "rescal";
+- msi-controller;
+- msi-parent = <&mip0>;
+-
+- // ~4GB, 32-bit, not-prefetchable at PCIe 00_00000000
+- ranges = <0x02000000 0x00 0x00000000
+- 0x1f 0x00000000
+- 0x0 0xfffffffc>,
+- // 12GB, 64-bit, prefetchable at PCIe 04_00000000
+- <0x43000000 0x04 0x00000000
+- 0x1c 0x00000000
+- 0x03 0x00000000>;
+-
+- // 64GB system RAM space at PCIe 10_00000000
+- dma-ranges = <0x02000000 0x00 0x00000000
+- 0x1f 0x00000000
+- 0x00 0x00400000>,
+- <0x43000000 0x10 0x00000000
+- 0x00 0x00000000
+- 0x10 0x00000000>;
+-
+- status = "disabled";
+- };
+-
+- mip0: msi-controller@130000 {
+- compatible = "brcm,bcm2712-mip-intc";
+- reg = <0x10 0x00130000 0x0 0xc0>;
+- msi-controller;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,msi-base-spi = <128>;
+- brcm,msi-num-spis = <64>;
+- brcm,msi-offset = <0>;
+- brcm,msi-pci-addr = <0xff 0xfffff000>;
+- };
+-
+- mip1: msi-controller@131000 {
+- compatible = "brcm,bcm2712-mip-intc";
+- reg = <0x10 0x00131000 0x0 0xc0>;
+- msi-controller;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,msi-base-spi = <247>;
+- /* Actually 20 total, but the others are
+- * both sparse and non-consecutive */
+- brcm,msi-num-spis = <8>;
+- brcm,msi-offset = <8>;
+- brcm,msi-pci-addr = <0xff 0xffffe000>;
+- };
+-
+- syscon_piarbctl: syscon@400018 {
+- compatible = "brcm,syscon-piarbctl", "syscon", "simple-mfd";
+- reg = <0x10 0x00400018 0x0 0x18>;
+- };
+-
+- usb: usb@480000 {
+- compatible = "brcm,bcm2835-usb";
+- reg = <0x10 0x00480000 0x0 0x10000>;
+- interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- clocks = <&clk_usb>;
+- clock-names = "otg";
+- phys = <&usbphy>;
+- phy-names = "usb2-phy";
+- status = "disabled";
+- };
+-
+- rpivid: codec@800000 {
+- compatible = "raspberrypi,rpivid-vid-decoder";
+- reg = <0x10 0x00800000 0x0 0x10000>, /* HEVC */
+- <0x10 0x00840000 0x0 0x1000>; /* INTC */
+- reg-names = "hevc",
+- "intc";
+-
+- interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&firmware_clocks 11>;
+- clock-names = "hevc";
+- iommus = <&iommu2>;
+- status = "disabled";
+- };
+-
+- sdio1: mmc@fff000 {
+- compatible = "brcm,bcm2712-sdhci";
+- reg = <0x10 0x00fff000 0x0 0x260>,
+- <0x10 0x00fff400 0x0 0x200>,
+- <0x10 0x015040b0 0x0 0x4>, // Bus isolation control
+- <0x10 0x015200f0 0x0 0x24>; // LCPLL control misc0-8
+- reg-names = "host", "cfg", "busisol", "lcpll";
+- interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_emmc2>;
+- sdhci-caps-mask = <0x0000C000 0x0>;
+- sdhci-caps = <0x0 0x0>;
+- mmc-ddr-3_3v;
+- };
+-
+- sdio2: mmc@1100000 {
+- compatible = "brcm,bcm2712-sdhci";
+- reg = <0x10 0x01100000 0x0 0x260>,
+- <0x10 0x01100400 0x0 0x200>;
+- reg-names = "host", "cfg";
+- interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_emmc2>;
+- sdhci-caps-mask = <0x0000C000 0x0>;
+- sdhci-caps = <0x0 0x0>;
+- supports-cqe;
+- mmc-ddr-3_3v;
+- status = "disabled";
+- };
+-
+- bcm_reset: reset-controller@1504318 {
+- compatible = "brcm,brcmstb-reset";
+- reg = <0x10 0x01504318 0x0 0x30>;
+- #reset-cells = <1>;
+- };
+-
+- v3d: v3d@2000000 {
+- compatible = "brcm,2712-v3d";
+- reg = <0x10 0x02000000 0x0 0x4000>,
+- <0x10 0x02008000 0x0 0x6000>;
+- reg-names = "hub", "core0";
+-
+- power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
+- resets = <&pm BCM2835_RESET_V3D>;
+- clocks = <&firmware_clocks 5>;
+- clocks-names = "v3d";
+- interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- gicv2: interrupt-controller@7fff9000 {
+- interrupt-controller;
+- #interrupt-cells = <3>;
+- compatible = "arm,gic-400";
+- reg = <0x10 0x7fff9000 0x0 0x1000>,
+- <0x10 0x7fffa000 0x0 0x2000>,
+- <0x10 0x7fffc000 0x0 0x2000>,
+- <0x10 0x7fffe000 0x0 0x2000>;
+- interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_HIGH)>;
+- };
+-
+- pisp_be: pisp_be@880000 {
+- compatible = "raspberrypi,pispbe";
+- reg = <0x10 0x00880000 0x0 0x4000>;
+- interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&firmware_clocks 7>;
+- clocks-names = "isp_be";
+- status = "okay";
+- iommus = <&iommu2>;
+- };
+- };
+-
+- clocks {
+- /* The oscillator is the root of the clock tree. */
+- clk_osc: clk-osc {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "osc";
+- clock-frequency = <54000000>;
+- };
+-
+- clk_usb: clk-usb {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "otg";
+- clock-frequency = <480000000>;
+- };
+-
+- clk_vpu: clk_vpu {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <750000000>;
+- clock-output-names = "vpu-clock";
+- };
+-
+- clk_uart: clk_uart {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <9216000>;
+- clock-output-names = "uart-clock";
+- };
+-
+- clk_emmc2: clk_emmc2 {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <200000000>;
+- clock-output-names = "emmc2-clock";
+- };
+- };
+-
+- usbphy: phy {
+- compatible = "usb-nop-xceiv";
+- #phy-cells = <0>;
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/rp1.dtsi
++++ /dev/null
+@@ -1,1287 +0,0 @@
+-#include <dt-bindings/clock/rp1.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/mfd/rp1.h>
+-
+-&rp1_target {
+- rp1: rp1 {
+- compatible = "simple-bus";
+- #address-cells = <2>;
+- #size-cells = <2>;
+- #interrupt-cells = <2>;
+- interrupt-controller;
+- interrupt-parent = <&rp1>;
+-
+- // ranges and dma-ranges must be provided by the includer
+-
+- rp1_clocks: clocks@18000 {
+- compatible = "raspberrypi,rp1-clocks";
+- #clock-cells = <1>;
+- reg = <0xc0 0x40018000 0x0 0x10038>;
+- clocks = <&clk_xosc>;
+-
+- assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
+- <&rp1_clocks RP1_PLL_AUDIO_CORE>,
+- // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
+- <&rp1_clocks RP1_PLL_SYS>,
+- <&rp1_clocks RP1_PLL_SYS_SEC>,
+- <&rp1_clocks RP1_PLL_AUDIO>,
+- <&rp1_clocks RP1_PLL_AUDIO_SEC>,
+- <&rp1_clocks RP1_CLK_SYS>,
+- <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
+- // RP1_CLK_SLOW_SYS is used for the frequency counter (FC0)
+- <&rp1_clocks RP1_CLK_SLOW_SYS>,
+- <&rp1_clocks RP1_CLK_SDIO_TIMER>,
+- <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
+- <&rp1_clocks RP1_CLK_ETH_TSU>;
+-
+- assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
+- <1536000000>, // RP1_PLL_AUDIO_CORE
+- <200000000>, // RP1_PLL_SYS
+- <125000000>, // RP1_PLL_SYS_SEC
+- <61440000>, // RP1_PLL_AUDIO
+- <192000000>, // RP1_PLL_AUDIO_SEC
+- <200000000>, // RP1_CLK_SYS
+- <100000000>, // RP1_PLL_SYS_PRI_PH
+- // Must match the XOSC frequency
+- <50000000>, // RP1_CLK_SLOW_SYS
+- <1000000>, // RP1_CLK_SDIO_TIMER
+- <200000000>, // RP1_CLK_SDIO_ALT_SRC
+- <50000000>; // RP1_CLK_ETH_TSU
+- };
+-
+- rp1_uart0: serial@30000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40030000 0x0 0x100>;
+- interrupts = <RP1_INT_UART0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- dmas = <&rp1_dma RP1_DMA_UART0_TX>,
+- <&rp1_dma RP1_DMA_UART0_RX>;
+- dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart1: serial@34000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40034000 0x0 0x100>;
+- interrupts = <RP1_INT_UART1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART1_TX>,
+- // <&rp1_dma RP1_DMA_UART1_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart2: serial@38000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40038000 0x0 0x100>;
+- interrupts = <RP1_INT_UART2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART2_TX>,
+- // <&rp1_dma RP1_DMA_UART2_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart3: serial@3c000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x4003c000 0x0 0x100>;
+- interrupts = <RP1_INT_UART3 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART3_TX>,
+- // <&rp1_dma RP1_DMA_UART3_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart4: serial@40000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40040000 0x0 0x100>;
+- interrupts = <RP1_INT_UART4 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART4_TX>,
+- // <&rp1_dma RP1_DMA_UART4_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart5: serial@44000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40044000 0x0 0x100>;
+- interrupts = <RP1_INT_UART5 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART5_TX>,
+- // <&rp1_dma RP1_DMA_UART5_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_spi8: spi@4c000 {
+- reg = <0xc0 0x4004c000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI8 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI8_TX>,
+- <&rp1_dma RP1_DMA_SPI8_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi0: spi@50000 {
+- reg = <0xc0 0x40050000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI0_TX>,
+- <&rp1_dma RP1_DMA_SPI0_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi1: spi@54000 {
+- reg = <0xc0 0x40054000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI1_TX>,
+- <&rp1_dma RP1_DMA_SPI1_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi2: spi@58000 {
+- reg = <0xc0 0x40058000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI2_TX>,
+- <&rp1_dma RP1_DMA_SPI2_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi3: spi@5c000 {
+- reg = <0xc0 0x4005c000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI3 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI3_TX>,
+- <&rp1_dma RP1_DMA_SPI3_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- // SPI4 is a target/slave interface
+- rp1_spi4: spi@60000 {
+- reg = <0xc0 0x40060000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI4 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <0>;
+- #size-cells = <0>;
+- num-cs = <1>;
+- spi-slave;
+- dmas = <&rp1_dma RP1_DMA_SPI4_TX>,
+- <&rp1_dma RP1_DMA_SPI4_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+-
+- slave {
+- compatible = "spidev";
+- spi-max-frequency = <1000000>;
+- };
+- };
+-
+- rp1_spi5: spi@64000 {
+- reg = <0xc0 0x40064000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI5 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI5_TX>,
+- <&rp1_dma RP1_DMA_SPI5_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi6: spi@68000 {
+- reg = <0xc0 0x40068000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI6 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI6_TX>,
+- <&rp1_dma RP1_DMA_SPI6_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- // SPI7 is a target/slave interface
+- rp1_spi7: spi@6c000 {
+- reg = <0xc0 0x4006c000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI7 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <0>;
+- #size-cells = <0>;
+- num-cs = <1>;
+- spi-slave;
+- dmas = <&rp1_dma RP1_DMA_SPI7_TX>,
+- <&rp1_dma RP1_DMA_SPI7_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+-
+- slave {
+- compatible = "spidev";
+- spi-max-frequency = <1000000>;
+- };
+- };
+-
+- rp1_i2c0: i2c@70000 {
+- reg = <0xc0 0x40070000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c1: i2c@74000 {
+- reg = <0xc0 0x40074000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c2: i2c@78000 {
+- reg = <0xc0 0x40078000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c3: i2c@7c000 {
+- reg = <0xc0 0x4007c000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C3 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c4: i2c@80000 {
+- reg = <0xc0 0x40080000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C4 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c5: i2c@84000 {
+- reg = <0xc0 0x40084000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C5 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c6: i2c@88000 {
+- reg = <0xc0 0x40088000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C6 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_pwm0: pwm@98000 {
+- compatible = "raspberrypi,rp1-pwm";
+- reg = <0xc0 0x40098000 0x0 0x100>;
+- #pwm-cells = <3>;
+- clocks = <&rp1_clocks RP1_CLK_PWM0>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_PWM0>;
+- assigned-clock-rates = <50000000>;
+- status = "disabled";
+- };
+-
+- rp1_pwm1: pwm@9c000 {
+- compatible = "raspberrypi,rp1-pwm";
+- reg = <0xc0 0x4009c000 0x0 0x100>;
+- #pwm-cells = <3>;
+- clocks = <&rp1_clocks RP1_CLK_PWM1>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_PWM1>;
+- assigned-clock-rates = <50000000>;
+- status = "disabled";
+- };
+-
+- rp1_i2s0: i2s@a0000 {
+- reg = <0xc0 0x400a0000 0x0 0x1000>;
+- compatible = "snps,designware-i2s";
+- // Providing an interrupt disables DMA
+- // interrupts = <RP1_INT_I2S0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_I2S>;
+- clock-names = "i2sclk";
+- #sound-dai-cells = <0>;
+- dmas = <&rp1_dma RP1_DMA_I2S0_TX>,<&rp1_dma RP1_DMA_I2S0_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_i2s1: i2s@a4000 {
+- reg = <0xc0 0x400a4000 0x0 0x1000>;
+- compatible = "snps,designware-i2s";
+- // Providing an interrupt disables DMA
+- // interrupts = <RP1_INT_I2S1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_I2S>;
+- clock-names = "i2sclk";
+- #sound-dai-cells = <0>;
+- dmas = <&rp1_dma RP1_DMA_I2S1_TX>,<&rp1_dma RP1_DMA_I2S1_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_i2s2: i2s@a8000 {
+- reg = <0xc0 0x400a8000 0x0 0x1000>;
+- compatible = "snps,designware-i2s";
+- // Providing an interrupt disables DMA
+- // interrupts = <RP1_INT_I2S2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_I2S>;
+- status = "disabled";
+- };
+-
+- rp1_sdio_clk0: sdio_clk0@b0004 {
+- compatible = "raspberrypi,rp1-sdio-clk";
+- reg = <0xc0 0x400b0004 0x0 0x1c>;
+- clocks = <&sdio_src &sdhci_core>;
+- clock-names = "src", "base";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_sdio_clk1: sdio_clk1@b4004 {
+- compatible = "raspberrypi,rp1-sdio-clk";
+- reg = <0xc0 0x400b4004 0x0 0x1c>;
+- clocks = <&sdio_src &sdhci_core>;
+- clock-names = "src", "base";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_adc: adc@c8000 {
+- compatible = "raspberrypi,rp1-adc";
+- reg = <0xc0 0x400c8000 0x0 0x4000>;
+- clocks = <&rp1_clocks RP1_CLK_ADC>;
+- clock-names = "adcclk";
+- #clock-cells = <0>;
+- vref-supply = <&rp1_vdd_3v3>;
+- status = "disabled";
+- };
+-
+- rp1_gpio: gpio@d0000 {
+- reg = <0xc0 0x400d0000 0x0 0xc000>,
+- <0xc0 0x400e0000 0x0 0xc000>,
+- <0xc0 0x400f0000 0x0 0xc000>;
+- compatible = "raspberrypi,rp1-gpio";
+- interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
+- <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
+- <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
+- gpio-controller;
+- #gpio-cells = <2>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- gpio-ranges = <&rp1_gpio 0 0 54>;
+-
+- rp1_uart0_14_15: rp1_uart0_14_15 {
+- pin_txd {
+- function = "uart0";
+- pins = "gpio14";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart0";
+- pins = "gpio15";
+- bias-pull-up;
+- };
+- };
+- rp1_uart0_ctsrts_16_17: rp1_uart0_ctsrts_16_17 {
+- pin_cts {
+- function = "uart0";
+- pins = "gpio16";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart0";
+- pins = "gpio17";
+- bias-disable;
+- };
+- };
+- rp1_uart1_0_1: rp1_uart1_0_1 {
+- pin_txd {
+- function = "uart1";
+- pins = "gpio0";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart1";
+- pins = "gpio1";
+- bias-pull-up;
+- };
+- };
+- rp1_uart1_ctsrts_2_3: rp1_uart1_ctsrts_2_3 {
+- pin_cts {
+- function = "uart1";
+- pins = "gpio2";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart1";
+- pins = "gpio3";
+- bias-disable;
+- };
+- };
+- rp1_uart2_4_5: rp1_uart2_4_5 {
+- pin_txd {
+- function = "uart2";
+- pins = "gpio4";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart2";
+- pins = "gpio5";
+- bias-pull-up;
+- };
+- };
+- rp1_uart2_ctsrts_6_7: rp1_uart2_ctsrts_6_7 {
+- pin_cts {
+- function = "uart2";
+- pins = "gpio6";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart2";
+- pins = "gpio7";
+- bias-disable;
+- };
+- };
+- rp1_uart3_8_9: rp1_uart3_8_9 {
+- pin_txd {
+- function = "uart3";
+- pins = "gpio8";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart3";
+- pins = "gpio9";
+- bias-pull-up;
+- };
+- };
+- rp1_uart3_ctsrts_10_11: rp1_uart3_ctsrts_10_11 {
+- pin_cts {
+- function = "uart3";
+- pins = "gpio10";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart3";
+- pins = "gpio11";
+- bias-disable;
+- };
+- };
+- rp1_uart4_12_13: rp1_uart4_12_13 {
+- pin_txd {
+- function = "uart4";
+- pins = "gpio12";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart4";
+- pins = "gpio13";
+- bias-pull-up;
+- };
+- };
+- rp1_uart4_ctsrts_14_15: rp1_uart4_ctsrts_14_15 {
+- pin_cts {
+- function = "uart4";
+- pins = "gpio14";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart4";
+- pins = "gpio15";
+- bias-disable;
+- };
+- };
+-
+- rp1_sdio0_22_27: rp1_sdio0_22_27 {
+- pin_clk {
+- function = "sd0";
+- pins = "gpio22";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pin_cmd {
+- function = "sd0";
+- pins = "gpio23";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pins_dat {
+- function = "sd0";
+- pins = "gpio24", "gpio25", "gpio26", "gpio27";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- };
+-
+- rp1_sdio1_28_33: rp1_sdio1_28_33 {
+- pin_clk {
+- function = "sd1";
+- pins = "gpio28";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pin_cmd {
+- function = "sd1";
+- pins = "gpio29";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pins_dat {
+- function = "sd1";
+- pins = "gpio30", "gpio31", "gpio32", "gpio33";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- };
+-
+- rp1_i2s0_18_21: rp1_i2s0_18_21 {
+- function = "i2s0";
+- pins = "gpio18", "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- };
+-
+- rp1_i2s1_18_21: rp1_i2s1_18_21 {
+- function = "i2s1";
+- pins = "gpio18", "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- };
+-
+- rp1_i2c4_34_35: rp1_i2c4_34_35 {
+- function = "i2c4";
+- pins = "gpio34", "gpio35";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c6_38_39: rp1_i2c6_38_39 {
+- function = "i2c6";
+- pins = "gpio38", "gpio39";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c4_40_41: rp1_i2c4_40_41 {
+- function = "i2c4";
+- pins = "gpio40", "gpio41";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c5_44_45: rp1_i2c5_44_45 {
+- function = "i2c5";
+- pins = "gpio44", "gpio45";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c0_0_1: rp1_i2c0_0_1 {
+- function = "i2c0";
+- pins = "gpio0", "gpio1";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c0_8_9: rp1_i2c0_8_9 {
+- function = "i2c0";
+- pins = "gpio8", "gpio9";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c1_2_3: rp1_i2c1_2_3 {
+- function = "i2c1";
+- pins = "gpio2", "gpio3";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c1_10_11: rp1_i2c1_10_11 {
+- function = "i2c1";
+- pins = "gpio10", "gpio11";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c2_4_5: rp1_i2c2_4_5 {
+- function = "i2c2";
+- pins = "gpio4", "gpio5";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c2_12_13: rp1_i2c2_12_13 {
+- function = "i2c2";
+- pins = "gpio12", "gpio13";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c3_6_7: rp1_i2c3_6_7 {
+- function = "i2c3";
+- pins = "gpio6", "gpio7";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c3_14_15: rp1_i2c3_14_15 {
+- function = "i2c3";
+- pins = "gpio14", "gpio15";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c3_22_23: rp1_i2c3_22_23 {
+- function = "i2c3";
+- pins = "gpio22", "gpio23";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+-
+- // DPI mappings with HSYNC,VSYNC but without PIXCLK,DE
+- rp1_dpi_16bit_gpio2: rp1_dpi_16bit_gpio2 { /* Mode 2, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio10", "gpio11", "gpio12", "gpio13",
+- "gpio14", "gpio15", "gpio16", "gpio17",
+- "gpio18", "gpio19";
+- bias-disable;
+- };
+- rp1_dpi_16bit_cpadhi_gpio2: rp1_dpi_16bit_cpadhi_gpio2 { /* Mode 3 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24";
+- bias-disable;
+- };
+- rp1_dpi_16bit_pad666_gpio2: rp1_dpi_16bit_pad666_gpio2 { /* Mode 4 */
+- function = "dpi";
+- pins = "gpio2", "gpio3",
+- "gpio5", "gpio6", "gpio7", "gpio8",
+- "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio21", "gpio22", "gpio23", "gpio24",
+- "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_18bit_gpio2: rp1_dpi_18bit_gpio2 { /* Mode 5, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio10", "gpio11", "gpio12", "gpio13",
+- "gpio14", "gpio15", "gpio16", "gpio17",
+- "gpio18", "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- };
+- rp1_dpi_18bit_cpadhi_gpio2: rp1_dpi_18bit_cpadhi_gpio2 { /* Mode 6 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24", "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_24bit_gpio2: rp1_dpi_24bit_gpio2 { /* Mode 7 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio10", "gpio11", "gpio12", "gpio13",
+- "gpio14", "gpio15", "gpio16", "gpio17",
+- "gpio18", "gpio19", "gpio20", "gpio21",
+- "gpio22", "gpio23", "gpio24", "gpio25",
+- "gpio26", "gpio27";
+- bias-disable;
+- };
+- rp1_dpi_hvsync: rp1_dpi_hvsync { /* Sync only, for use with int VDAC */
+- function = "dpi";
+- pins = "gpio2", "gpio3";
+- bias-disable;
+- };
+-
+- // More DPI mappings, including PIXCLK,DE on GPIOs 0,1
+- rp1_dpi_16bit_gpio0: rp1_dpi_16bit_gpio0 { /* Mode 2, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17", "gpio18", "gpio19";
+- bias-disable;
+- };
+- rp1_dpi_16bit_cpadhi_gpio0: rp1_dpi_16bit_cpadhi_gpio0 { /* Mode 3 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24";
+- bias-disable;
+- };
+- rp1_dpi_16bit_pad666_gpio0: rp1_dpi_16bit_pad666_gpio0 { /* Mode 4 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio5", "gpio6", "gpio7", "gpio8",
+- "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio21", "gpio22", "gpio23", "gpio24",
+- "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_18bit_gpio0: rp1_dpi_18bit_gpio0 { /* Mode 5, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17", "gpio18", "gpio19",
+- "gpio20", "gpio21";
+- bias-disable;
+- };
+- rp1_dpi_18bit_cpadhi_gpio0: rp1_dpi_18bit_cpadhi_gpio0 { /* Mode 6 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24", "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_24bit_gpio0: rp1_dpi_24bit_gpio0 { /* Mode 7 -- All GPIOs used! */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17", "gpio18", "gpio19",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24", "gpio25", "gpio26", "gpio27";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc0_gpio4: rp1_gpclksrc0_gpio4 {
+- function = "gpclk0";
+- pins = "gpio4";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc0_gpio20: rp1_gpclksrc0_gpio20 {
+- function = "gpclk0";
+- pins = "gpio20";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc1_gpio5: rp1_gpclksrc1_gpio5 {
+- function = "gpclk1";
+- pins = "gpio5";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc1_gpio18: rp1_gpclksrc1_gpio18 {
+- function = "gpclk1";
+- pins = "gpio18";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc1_gpio21: rp1_gpclksrc1_gpio21 {
+- function = "gpclk1";
+- pins = "gpio21";
+- bias-disable;
+- };
+-
+- rp1_pwm1_gpio45: rp1_pwm1_gpio45 {
+- function = "pwm1";
+- pins = "gpio45";
+- bias-pull-down;
+- };
+-
+- rp1_spi0_gpio9: rp1_spi0_gpio9 {
+- function = "spi0";
+- pins = "gpio9", "gpio10", "gpio11";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi0_cs_gpio7: rp1_spi0_cs_gpio7 {
+- function = "spi0";
+- pins = "gpio7", "gpio8";
+- bias-pull-up;
+- };
+-
+- rp1_spi1_gpio19: rp1_spi1_gpio19 {
+- function = "spi1";
+- pins = "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi2_gpio1: rp1_spi2_gpio1 {
+- function = "spi2";
+- pins = "gpio1", "gpio2", "gpio3";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi3_gpio5: rp1_spi3_gpio5 {
+- function = "spi3";
+- pins = "gpio5", "gpio6", "gpio7";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi4_gpio9: rp1_spi4_gpio9 {
+- function = "spi4";
+- pins = "gpio9", "gpio10", "gpio11";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi5_gpio13: rp1_spi5_gpio13 {
+- function = "spi5";
+- pins = "gpio13", "gpio14", "gpio15";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi8_gpio49: rp1_spi8_gpio49 {
+- function = "spi8";
+- pins = "gpio49", "gpio50", "gpio51";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi8_cs_gpio52: rp1_spi8_cs_gpio52 {
+- function = "spi0";
+- pins = "gpio52", "gpio53";
+- bias-pull-up;
+- };
+- };
+-
+- rp1_eth: ethernet@100000 {
+- reg = <0xc0 0x40100000 0x0 0x4000>;
+- compatible = "cdns,macb";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&macb_pclk &macb_hclk &rp1_clocks RP1_CLK_ETH_TSU>;
+- clock-names = "pclk", "hclk", "tsu_clk";
+- phy-mode = "rgmii-id";
+- cdns,aw2w-max-pipe = /bits/ 8 <8>;
+- cdns,ar2r-max-pipe = /bits/ 8 <8>;
+- cdns,use-aw2b-fill;
+- local-mac-address = [00 00 00 00 00 00];
+- status = "disabled";
+- };
+-
+- rp1_csi0: csi@110000 {
+- compatible = "raspberrypi,rp1-cfe";
+- reg = <0xc0 0x40110000 0x0 0x100>, // CSI2 DMA address
+- <0xc0 0x40114000 0x0 0x100>, // PHY/CSI Host address
+- <0xc0 0x40120000 0x0 0x100>, // MIPI CFG address
+- <0xc0 0x40124000 0x0 0x1000>; // PiSP FE address
+-
+- // interrupts must match rp1_pisp_fe setup
+- interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+- assigned-clock-rates = <25000000>;
+-
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_csi1: csi@128000 {
+- compatible = "raspberrypi,rp1-cfe";
+- reg = <0xc0 0x40128000 0x0 0x100>, // CSI2 DMA address
+- <0xc0 0x4012c000 0x0 0x100>, // PHY/CSI Host address
+- <0xc0 0x40138000 0x0 0x100>, // MIPI CFG address
+- <0xc0 0x4013c000 0x0 0x1000>; // PiSP FE address
+-
+- // interrupts must match rp1_pisp_fe setup
+- interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+- assigned-clock-rates = <25000000>;
+-
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_mmc0: mmc@180000 {
+- reg = <0xc0 0x40180000 0x0 0x100>;
+- compatible = "raspberrypi,rp1-dwcmshc";
+- interrupts = <RP1_INT_SDIO0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
+- &rp1_clocks RP1_CLK_SDIO_TIMER
+- &rp1_sdio_clk0>;
+- clock-names = "bus", "core", "timeout", "sdio";
+- /* Bank 0 VDDIO is fixed */
+- no-1-8-v;
+- bus-width = <4>;
+- vmmc-supply = <&rp1_vdd_3v3>;
+- broken-cd;
+- status = "disabled";
+- };
+-
+- rp1_mmc1: mmc@184000 {
+- reg = <0xc0 0x40184000 0x0 0x100>;
+- compatible = "raspberrypi,rp1-dwcmshc";
+- interrupts = <RP1_INT_SDIO1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
+- &rp1_clocks RP1_CLK_SDIO_TIMER
+- &rp1_sdio_clk1>;
+- clock-names = "bus", "core", "timeout", "sdio";
+- bus-width = <4>;
+- vmmc-supply = <&rp1_vdd_3v3>;
+- /* Nerf SDR speeds */
+- sdhci-caps-mask = <0x3 0x0>;
+- broken-cd;
+- status = "disabled";
+- };
+-
+- rp1_dma: dma@188000 {
+- reg = <0xc0 0x40188000 0x0 0x1000>;
+- compatible = "snps,axi-dma-1.01a";
+- interrupts = <RP1_INT_DMA IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&sdhci_core &rp1_clocks RP1_CLK_SYS>;
+- clock-names = "core-clk", "cfgr-clk";
+-
+- #dma-cells = <1>;
+- dma-channels = <8>;
+- snps,dma-masters = <1>;
+- snps,dma-targets = <64>;
+- snps,data-width = <4>; // (8 << 4) == 128 bits
+- snps,block-size = <0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000>;
+- snps,priority = <0 1 2 3 4 5 6 7>;
+- snps,axi-max-burst-len = <8>;
+- status = "disabled";
+- };
+-
+- rp1_usb0: usb@200000 {
+- reg = <0xc0 0x40200000 0x0 0x100000>;
+- compatible = "snps,dwc3";
+- dr_mode = "host";
+- usb3-lpm-capable;
+- snps,axi-pipe-limit = /bits/ 8 <8>;
+- snps,dis_rxdet_inp3_quirk;
+- snps,parkmode-disable-ss-quirk;
+- snps,parkmode-disable-hs-quirk;
+- snps,parkmode-disable-fsls-quirk;
+- snps,tx-max-burst = /bits/ 8 <8>;
+- snps,tx-thr-num-pkt = /bits/ 8 <2>;
+- interrupts = <RP1_INT_USBHOST0_0 IRQ_TYPE_EDGE_RISING>;
+- status = "disabled";
+- };
+-
+- rp1_usb1: usb@300000 {
+- reg = <0xc0 0x40300000 0x0 0x100000>;
+- compatible = "snps,dwc3";
+- dr_mode = "host";
+- usb3-lpm-capable;
+- snps,axi-pipe-limit = /bits/ 8 <8>;
+- snps,dis_rxdet_inp3_quirk;
+- snps,parkmode-disable-ss-quirk;
+- snps,parkmode-disable-hs-quirk;
+- snps,parkmode-disable-fsls-quirk;
+- snps,tx-max-burst = /bits/ 8 <8>;
+- snps,tx-thr-num-pkt = /bits/ 8 <2>;
+- interrupts = <RP1_INT_USBHOST1_0 IRQ_TYPE_EDGE_RISING>;
+- status = "disabled";
+- };
+-
+- rp1_dsi0: dsi@110000 {
+- compatible = "raspberrypi,rp1dsi";
+- status = "disabled";
+- reg = <0xc0 0x40118000 0x0 0x1000>, // MIPI0 DSI DMA (ArgonDPI)
+- <0xc0 0x4011c000 0x0 0x1000>, // MIPI0 DSI Host (SNPS)
+- <0xc0 0x40120000 0x0 0x1000>; // MIPI0 CFG
+-
+- interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI0_DPI>,
+- <&rp1_clocks RP1_CLK_MIPI0_DSI_BYTECLOCK>,
+- <&clk_xosc>, // hardwired to DSI "refclk"
+- <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+-
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+- assigned-clock-rates = <25000000>;
+- };
+-
+- rp1_dsi1: dsi@128000 {
+- compatible = "raspberrypi,rp1dsi";
+- status = "disabled";
+- reg = <0xc0 0x40130000 0x0 0x1000>, // MIPI1 DSI DMA (ArgonDPI)
+- <0xc0 0x40134000 0x0 0x1000>, // MIPI1 DSI Host (SNPS)
+- <0xc0 0x40138000 0x0 0x1000>; // MIPI1 CFG
+-
+- interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI1_DPI>,
+- <&rp1_clocks RP1_CLK_MIPI1_DSI_BYTECLOCK>,
+- <&clk_xosc>, // hardwired to DSI "refclk"
+- <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+-
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+- assigned-clock-rates = <25000000>;
+- };
+-
+- /* VEC and DPI both need to control PLL_VIDEO and cannot work together; */
+- /* config.txt should enable one or other using dtparam=vec or an overlay. */
+- rp1_vec: vec@144000 {
+- compatible = "raspberrypi,rp1vec";
+- status = "disabled";
+- reg = <0xc0 0x40144000 0x0 0x1000>, // VIDEO_OUT_VEC
+- <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
+-
+- interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_VEC>;
+-
+- assigned-clocks = <&rp1_clocks RP1_PLL_VIDEO_CORE>,
+- <&rp1_clocks RP1_PLL_VIDEO_SEC>,
+- <&rp1_clocks RP1_CLK_VEC>;
+- assigned-clock-rates = <1188000000>,
+- <108000000>,
+- <108000000>;
+- assigned-clock-parents = <0>,
+- <&rp1_clocks RP1_PLL_VIDEO_CORE>,
+- <&rp1_clocks RP1_PLL_VIDEO_SEC>;
+- };
+-
+- rp1_dpi: dpi@148000 {
+- compatible = "raspberrypi,rp1dpi";
+- status = "disabled";
+- reg = <0xc0 0x40148000 0x0 0x1000>, // VIDEO_OUT DPI
+- <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
+-
+- interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_DPI>, // DPI pixel clock
+- <&rp1_clocks RP1_PLL_VIDEO>, // PLL primary divider, and
+- <&rp1_clocks RP1_PLL_VIDEO_CORE>; // VCO, which we also control
+- clock-names = "dpiclk", "plldiv", "pllcore";
+-
+- assigned-clocks = <&rp1_clocks RP1_CLK_DPI>;
+- assigned-clock-parents = <&rp1_clocks RP1_PLL_VIDEO>;
+- };
+- };
+-};
+-
+-&clocks {
+- clk_xosc: clk_xosc {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "xosc";
+- clock-frequency = <50000000>;
+- };
+- macb_pclk: macb_pclk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "pclk";
+- clock-frequency = <200000000>;
+- };
+- macb_hclk: macb_hclk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "hclk";
+- clock-frequency = <200000000>;
+- };
+- sdio_src: sdio_src {
+- // 400 MHz on FPGA. PLL sys VCO on asic
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "src";
+- clock-frequency = <1000000000>;
+- };
+- sdhci_core: sdhci_core {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "core";
+- clock-frequency = <50000000>;
+- };
+- /* GPIO derived clock sources. Each GPIO with a GPCLK function
+- * can drive its output from the respective GPCLK
+- * generator, and provide a clock source to other internal
+- * dividers. Add dummy sources here so that they can be overridden
+- * with overlays.
+- */
+- clksrc_gp0: clksrc_gp0 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP0>;
+- clock-output-names = "clksrc_gp0";
+- };
+- clksrc_gp1: clksrc_gp1 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP1>;
+- clock-output-names = "clksrc_gp1";
+- };
+- clksrc_gp2: clksrc_gp2 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- clock-div = <1>;
+- clock-mult = <1>;
+- #clock-cells = <0>;
+- clocks = <&rp1_clocks RP1_CLK_GP2>;
+- clock-output-names = "clksrc_gp2";
+- };
+- clksrc_gp3: clksrc_gp3 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- clock-div = <1>;
+- clock-mult = <1>;
+- #clock-cells = <0>;
+- clocks = <&rp1_clocks RP1_CLK_GP3>;
+- clock-output-names = "clksrc_gp3";
+- };
+- clksrc_gp4: clksrc_gp4 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP4>;
+- clock-output-names = "clksrc_gp4";
+- };
+- clksrc_gp5: clksrc_gp5 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP5>;
+- clock-output-names = "clksrc_gp5";
+- };
+-};
+-
+-/ {
+- rp1_vdd_3v3: rp1_vdd_3v3 {
+- compatible = "regulator-fixed";
+- regulator-name = "vdd-3v3";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+- };
+-};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -0,0 +1,351 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <dt-bindings/power/raspberrypi-power.h>
++
++&soc {
++ firmware: firmware {
++ compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ mboxes = <&mailbox>;
++ dma-ranges;
++
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
++ reset: reset {
++ compatible = "raspberrypi,firmware-reset";
++ #reset-cells = <1>;
++ };
++
++ vcio: vcio {
++ compatible = "raspberrypi,vcio";
++ };
++ };
++
++ power: power {
++ compatible = "raspberrypi,bcm2835-power";
++ firmware = <&firmware>;
++ #power-domain-cells = <1>;
++ };
++
++ fb: fb {
++ compatible = "brcm,bcm2708-fb";
++ firmware = <&firmware>;
++ status = "okay";
++ };
++
++ rpi_rtc: rpi_rtc {
++ compatible = "raspberrypi,rpi-rtc";
++ firmware = <&firmware>;
++ status = "okay";
++ trickle-charge-microvolt = <0>;
++ };
++
++ nvmem {
++ compatible = "simple-bus";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ nvmem_otp: nvmem_otp {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <0 192>;
++ status = "okay";
++ };
++
++ nvmem_cust: nvmem_cust {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <1 8>;
++ status = "okay";
++ };
++
++ nvmem_mac: nvmem_mac {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <2 6>;
++ status = "okay";
++ };
++
++ nvmem_priv: nvmem_priv {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <3 16>;
++ status = "okay";
++ };
++ };
++
++ /* Define these notional regulators for use by overlays, etc. */
++ vdd_3v3_reg: fixedregulator_3v3 {
++ compatible = "regulator-fixed";
++ regulator-always-on;
++ regulator-max-microvolt = <3300000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-name = "3v3";
++ };
++
++ vdd_5v0_reg: fixedregulator_5v0 {
++ compatible = "regulator-fixed";
++ regulator-always-on;
++ regulator-max-microvolt = <5000000>;
++ regulator-min-microvolt = <5000000>;
++ regulator-name = "5v0";
++ };
++};
++
++/ {
++ __overrides__ {
++ arm_freq;
++ axiperf = <&axiperf>,"status";
++
++ nvmem_cust_rw = <&nvmem_cust>,"rw?";
++ nvmem_priv_rw = <&nvmem_priv>,"rw?";
++ nvmem_mac_rw = <&nvmem_mac>,"rw?";
++ strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
++
++ cam0_reg = <&cam0_reg>,"status";
++ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
++ <&cam0_reg>,"gpio:0=", <&gpio>;
++ cam1_reg = <&cam1_reg>,"status";
++ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
++ <&cam1_reg>,"gpio:0=", <&gpio>;
++
++ };
++};
++
++pciex1: &pcie1 { };
++pciex4: &pcie2 { };
++
++&dma32 {
++ /* The VPU firmware uses DMA channel 11 for VCHIQ */
++ brcm,dma-channel-mask = <0x03f>;
++};
++
++&dma40 {
++ /* The VPU firmware DMA channel 11 for VCHIQ */
++ brcm,dma-channel-mask = <0x07c0>;
++};
++
++&hdmi0 {
++ dmas = <&dma40 (10|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
++
++&hdmi1 {
++ dmas = <&dma40 (17|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
++
++&spi10 {
++ dmas = <&dma40 6>, <&dma40 7>;
++ dma-names = "tx", "rx";
++};
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
++
++&rmem {
++ /*
++ * RPi5's co-processor will copy the board's bootloader configuration
++ * into memory for the OS to consume. It'll also update this node with
++ * its placement information.
++ */
++ blconfig: nvram@0 {
++ compatible = "raspberrypi,bootloader-config", "nvmem-rmem";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ reg = <0x0 0x0 0x0>;
++ no-map;
++ status = "disabled";
++ };
++ /*
++ * RPi5 will copy the binary public key blob (if present) from the bootloader
++ * into memory for use by the OS.
++ */
++ blpubkey: nvram@1 {
++ compatible = "raspberrypi,bootloader-public-key", "nvmem-rmem";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ reg = <0x0 0x0 0x0>;
++ no-map;
++ status = "disabled";
++ };
++};
++
++&rp1_adc {
++ status = "okay";
++};
++
++/* Add some gpiomem nodes to make the devices accessible to userspace.
++ * /dev/gpiomem<n> should expose the registers for the interface with DT alias
++ * gpio<n>.
++ */
++
++&rp1 {
++ gpiomem@d0000 {
++ /* Export IO_BANKs, RIO_BANKs and PADS_BANKs to userspace */
++ compatible = "raspberrypi,gpiomem";
++ reg = <0xc0 0x400d0000 0x0 0x30000>;
++ chardev-name = "gpiomem0";
++ };
++};
++
++&soc {
++ gpiomem@7d508500 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d508500 0x40>;
++ chardev-name = "gpiomem1";
++ };
++
++ gpiomem@7d517c00 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d517c00 0x40>;
++ chardev-name = "gpiomem2";
++ };
++
++ gpiomem@7d504100 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d504100 0x20>;
++ chardev-name = "gpiomem3";
++ };
++
++ gpiomem@7d510700 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d510700 0x20>;
++ chardev-name = "gpiomem4";
++ };
++
++ sound: sound {
++ status = "disabled";
++ };
++};
++
++i2c0: &rp1_i2c0 { };
++i2c1: &rp1_i2c1 { };
++i2c2: &rp1_i2c2 { };
++i2c3: &rp1_i2c3 { };
++i2c4: &rp1_i2c4 { };
++i2c5: &rp1_i2c5 { };
++i2c6: &rp1_i2c6 { };
++i2s: &rp1_i2s0 { };
++i2s_clk_producer: &rp1_i2s0 { };
++i2s_clk_consumer: &rp1_i2s1 { };
++pwm0: &rp1_pwm0 { };
++pwm1: &rp1_pwm1 { };
++pwm: &pwm0 { };
++spi0: &rp1_spi0 { };
++spi1: &rp1_spi1 { };
++spi2: &rp1_spi2 { };
++spi3: &rp1_spi3 { };
++spi4: &rp1_spi4 { };
++spi5: &rp1_spi5 { };
++
++uart0_pins: &rp1_uart0_14_15 {};
++uart0_ctsrts_pins: &rp1_uart0_ctsrts_16_17 {};
++uart0: &rp1_uart0 {
++ pinctrl-0 = <&uart0_pins>;
++};
++
++uart1_pins: &rp1_uart1_0_1 {};
++uart1_ctsrts_pins: &rp1_uart1_ctsrts_2_3 {};
++uart1: &rp1_uart1 { };
++
++uart2_pins: &rp1_uart2_4_5 {};
++uart2_ctsrts_pins: &rp1_uart2_ctsrts_6_7 {};
++uart2: &rp1_uart2 { };
++
++uart3_pins: &rp1_uart3_8_9 {};
++uart3_ctsrts_pins: &rp1_uart3_ctsrts_10_11 {};
++uart3: &rp1_uart3 { };
++
++uart4_pins: &rp1_uart4_12_13 {};
++uart4_ctsrts_pins: &rp1_uart4_ctsrts_14_15 {};
++uart4: &rp1_uart4 { };
++
++i2c0_pins: &rp1_i2c0_0_1 {};
++i2c_vc: &i2c0 { // This is pins 27,28 on the header (not MIPI)
++ pinctrl-0 = <&i2c0_pins>;
++ pinctrl-names = "default";
++ clock-frequency = <100000>;
++};
++
++i2c1_pins: &rp1_i2c1_2_3 {};
++i2c_arm: &i2c1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ clock-frequency = <100000>;
++};
++
++i2c2_pins: &rp1_i2c2_4_5 {};
++&i2c2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
++};
++
++i2c3_pins: &rp1_i2c3_6_7 {};
++&i2c3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c3_pins>;
++};
++
++&i2s_clk_producer {
++ pinctrl-names = "default";
++ pinctrl-0 = <&rp1_i2s0_18_21>;
++};
++
++&i2s_clk_consumer {
++ pinctrl-names = "default";
++ pinctrl-0 = <&rp1_i2s1_18_21>;
++};
++
++spi0_pins: &rp1_spi0_gpio9 {};
++spi0_cs_pins: &rp1_spi0_cs_gpio7 {};
++
++&spi0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
++
++ spidev0: spidev@0 {
++ compatible = "spidev";
++ reg = <0>; /* CE0 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <125000000>;
++ };
++
++ spidev1: spidev@1 {
++ compatible = "spidev";
++ reg = <1>; /* CE1 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <125000000>;
++ };
++};
++
++spi2_pins: &rp1_spi2_gpio1 {};
++&spi2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins>;
++};
++
++spi3_pins: &rp1_spi3_gpio5 {};
++&spi3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi3_pins>;
++};
++
++spi4_pins: &rp1_spi4_gpio9 {};
++&spi4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi4_pins>;
++};
++
++spi5_pins: &rp1_spi5_gpio13 {};
++&spi5 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi5_pins>;
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -0,0 +1,1302 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/soc/bcm2835-pm.h>
++#include <dt-bindings/phy/phy.h>
++
++/ {
++ compatible = "brcm,bcm2712", "brcm,bcm2711";
++ model = "BCM2712";
++
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ interrupt-parent = <&gicv2>;
++
++ rmem: reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <1>;
++ ranges;
++
++ atf@0 {
++ reg = <0x0 0x0 0x80000>;
++ no-map;
++ };
++
++ cma: linux,cma {
++ compatible = "shared-dma-pool";
++ size = <0x4000000>; /* 64MB */
++ reusable;
++ linux,cma-default;
++
++ /*
++ * arm64 reserves the CMA by default somewhere in
++ * ZONE_DMA32, that's not good enough for the BCM2711
++ * as some devices can only address the lower 1G of
++ * memory (ZONE_DMA).
++ */
++ alloc-ranges = <0x0 0x00000000 0x40000000>;
++ };
++ };
++
++ thermal-zones {
++ cpu_thermal: cpu-thermal {
++ polling-delay-passive = <2000>;
++ polling-delay = <1000>;
++ coefficients = <(-550) 450000>;
++ thermal-sensors = <&thermal>;
++
++ thermal_trips: trips {
++ cpu_crit: cpu-crit {
++ temperature = <110000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling_maps: cooling-maps {
++ };
++ };
++ };
++
++ clk_27MHz: clk-27M {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <27000000>;
++ clock-output-names = "27MHz-clock";
++ };
++
++ clk_108MHz: clk-108M {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <108000000>;
++ clock-output-names = "108MHz-clock";
++ };
++
++ hvs: hvs@107c580000 {
++ compatible = "brcm,bcm2712-hvs";
++ reg = <0x10 0x7c580000 0x1a000>;
++ interrupt-parent = <&disp_intr>;
++ interrupts = <2>, <9>, <16>;
++ interrupt-names = "ch0-eof", "ch1-eof", "ch2-eof";
++ //iommus = <&iommu4>;
++ status = "disabled";
++ };
++
++ soc: soc {
++ compatible = "simple-bus";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ ranges = <0x7c000000 0x10 0x7c000000 0x04000000>;
++ /* Emulate a contiguous 30-bit address range for DMA */
++ dma-ranges = <0xc0000000 0x00 0x00000000 0x40000000>,
++ <0x7c000000 0x10 0x7c000000 0x04000000>;
++
++ system_timer: timer@7c003000 {
++ compatible = "brcm,bcm2835-system-timer";
++ reg = <0x7c003000 0x1000>;
++ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
++ clock-frequency = <1000000>;
++ };
++
++ firmwarekms: firmwarekms@7d503000 {
++ compatible = "raspberrypi,rpi-firmware-kms-2712";
++ /* SUN_L2 interrupt reg */
++ reg = <0x7d503000 0x18>;
++ interrupt-parent = <&cpu_l2_irq>;
++ interrupts = <19>;
++ brcm,firmware = <&firmware>;
++ status = "disabled";
++ };
++
++ axiperf: axiperf {
++ compatible = "brcm,bcm2712-axiperf";
++ reg = <0x7c012800 0x100>,
++ <0x7e000000 0x100>;
++ firmware = <&firmware>;
++ status = "disabled";
++ };
++
++ mailbox: mailbox@7c013880 {
++ compatible = "brcm,bcm2835-mbox";
++ reg = <0x7c013880 0x40>;
++ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
++ #mbox-cells = <0>;
++ };
++
++ pixelvalve0: pixelvalve@7c410000 {
++ compatible = "brcm,bcm2712-pixelvalve0";
++ reg = <0x7c410000 0x100>;
++ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ pixelvalve1: pixelvalve@7c411000 {
++ compatible = "brcm,bcm2712-pixelvalve1";
++ reg = <0x7c411000 0x100>;
++ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ mop: mop@7c500000 {
++ compatible = "brcm,bcm2712-mop";
++ reg = <0x7c500000 0x28>;
++ interrupt-parent = <&disp_intr>;
++ interrupts = <1>;
++ status = "disabled";
++ };
++
++ moplet: moplet@7c501000 {
++ compatible = "brcm,bcm2712-moplet";
++ reg = <0x7c501000 0x20>;
++ interrupt-parent = <&disp_intr>;
++ interrupts = <0>;
++ status = "disabled";
++ };
++
++ disp_intr: interrupt-controller@7c502000 {
++ compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
++ reg = <0x7c502000 0x30>;
++ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ status = "disabled";
++ };
++
++ dvp: clock@7c700000 {
++ compatible = "brcm,brcm2711-dvp";
++ reg = <0x7c700000 0x10>;
++ clocks = <&clk_108MHz>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ /*
++ * This node is the provider for the enable-method for
++ * bringing up secondary cores.
++ */
++ local_intc: local_intc@7cd00000 {
++ compatible = "brcm,bcm2836-l1-intc";
++ reg = <0x7cd00000 0x100>;
++ };
++
++ uart0: serial@7d001000 {
++ compatible = "arm,pl011", "arm,primecell";
++ reg = <0x7d001000 0x200>;
++ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_uart>,
++ <&clk_vpu>;
++ clock-names = "uartclk", "apb_pclk";
++ arm,primecell-periphid = <0x00241011>;
++ status = "disabled";
++ };
++
++ uart2: serial@7d001400 {
++ compatible = "arm,pl011", "arm,primecell";
++ reg = <0x7d001400 0x200>;
++ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_uart>,
++ <&clk_vpu>;
++ clock-names = "uartclk", "apb_pclk";
++ arm,primecell-periphid = <0x00241011>;
++ status = "disabled";
++ };
++
++ uart5: serial@7d001a00 {
++ compatible = "arm,pl011", "arm,primecell";
++ reg = <0x7d001a00 0x200>;
++ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_uart>,
++ <&clk_vpu>;
++ clock-names = "uartclk", "apb_pclk";
++ arm,primecell-periphid = <0x00241011>;
++ status = "disabled";
++ };
++
++ sdhost: mmc@7d002000 {
++ compatible = "brcm,bcm2835-sdhost";
++ reg = <0x7d002000 0x100>;
++ //interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ status = "disabled";
++ };
++
++ i2s: i2s@7d003000 {
++ compatible = "brcm,bcm2835-i2s";
++ reg = <0x7d003000 0x24>;
++ //clocks = <&cprman BCM2835_CLOCK_PCM>;
++ status = "disabled";
++ };
++
++ spi0: spi@7d004000 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004000 0x200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ num-cs = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi3: spi@7d004600 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004600 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi4: spi@7d004800 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004800 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi5: spi@7d004a00 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004a00 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi6: spi@7d004c00 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004c00 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c0: i2c@7d005000 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005000 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@7d005600 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005600 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@7d005800 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005800 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c5: i2c@7d005a00 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005a00 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c6: i2c@7d005c00 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005c00 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c8: i2c@7d005e00 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005e00 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ pwm0: pwm@7d00c000 {
++ compatible = "brcm,bcm2835-pwm";
++ reg = <0x7d00c000 0x28>;
++ assigned-clock-rates = <50000000>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@7d00c800 {
++ compatible = "brcm,bcm2835-pwm";
++ reg = <0x7d00c800 0x28>;
++ assigned-clock-rates = <50000000>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pm: watchdog@7d200000 {
++ compatible = "brcm,bcm2712-pm";
++ reg = <0x7d200000 0x308>;
++ reg-names = "pm";
++ #power-domain-cells = <1>;
++ #reset-cells = <1>;
++ //clocks = <&cprman BCM2835_CLOCK_V3D>,
++ // <&cprman BCM2835_CLOCK_PERI_IMAGE>,
++ // <&cprman BCM2835_CLOCK_H264>,
++ // <&cprman BCM2835_CLOCK_ISP>;
++ clock-names = "v3d", "peri_image", "h264", "isp";
++ system-power-controller;
++ };
++
++ cprman: cprman@7d202000 {
++ compatible = "brcm,bcm2711-cprman";
++ reg = <0x7d202000 0x2000>;
++ #clock-cells = <1>;
++
++ /* CPRMAN derives almost everything from the
++ * platform's oscillator. However, the DSI
++ * pixel clocks come from the DSI analog PHY.
++ */
++ clocks = <&clk_osc>;
++ status = "disabled";
++ };
++
++ random: rng@7d208000 {
++ compatible = "brcm,bcm2711-rng200";
++ reg = <0x7d208000 0x28>;
++ status = "okay";
++ };
++
++ cpu_l2_irq: intc@7d503000 {
++ compatible = "brcm,l2-intc";
++ reg = <0x7d503000 0x18>;
++ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ pinctrl: pinctrl@7d504100 {
++ compatible = "brcm,bcm2712-pinctrl";
++ reg = <0x7d504100 0x30>;
++
++ uarta_24_pins: uarta_24_pins {
++ pin_rts {
++ function = "uart0";
++ pins = "gpio24";
++ bias-disable;
++ };
++ pin_cts {
++ function = "uart0";
++ pins = "gpio25";
++ bias-pull-up;
++ };
++ pin_txd {
++ function = "uart0";
++ pins = "gpio26";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart0";
++ pins = "gpio27";
++ bias-pull-up;
++ };
++ };
++
++ sdio2_30_pins: sdio2_30_pins {
++ pin_clk {
++ function = "sd2";
++ pins = "gpio30";
++ bias-disable;
++ };
++ pin_cmd {
++ function = "sd2";
++ pins = "gpio31";
++ bias-pull-up;
++ };
++ pins_dat {
++ function = "sd2";
++ pins = "gpio32", "gpio33", "gpio34", "gpio35";
++ bias-pull-up;
++ };
++ };
++ };
++
++ ddc0: i2c@7d508200 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d508200 0x58>;
++ interrupt-parent = <&bsc_irq>;
++ interrupts = <1>;
++ clock-frequency = <97500>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ ddc1: i2c@7d508280 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d508280 0x58>;
++ interrupt-parent = <&bsc_irq>;
++ interrupts = <2>;
++ clock-frequency = <97500>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ bscd: i2c@7d508300 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d508300 0x58>;
++ interrupt-parent = <&bsc_irq>;
++ interrupts = <0>;
++ clock-frequency = <200000>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ bsc_irq: intc@7d508380 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d508380 0x10>;
++ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ main_irq: intc@7d508400 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d508400 0x10>;
++ interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ gio: gpio@7d508500 {
++ compatible = "brcm,brcmstb-gpio";
++ reg = <0x7d508500 0x40>;
++ interrupt-parent = <&main_irq>;
++ interrupts = <0>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,gpio-bank-widths = <32 22>;
++ brcm,gpio-direct;
++ };
++
++ uarta: serial@7d50c000 {
++ compatible = "brcm,bcm7271-uart";
++ reg = <0x7d50c000 0x20>;
++ reg-names = "uart";
++ reg-shift = <2>;
++ reg-io-width = <4>;
++ interrupts = <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
++ skip-init;
++ status = "disabled";
++ };
++
++ uartb: serial@7d50d000 {
++ compatible = "brcm,bcm7271-uart";
++ reg = <0x7d50d000 0x20>;
++ reg-names = "uart";
++ reg-shift = <2>;
++ reg-io-width = <4>;
++ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
++ skip-init;
++ status = "disabled";
++ };
++
++ aon_intr: interrupt-controller@7d510600 {
++ compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
++ reg = <0x7d510600 0x30>;
++ interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ status = "disabled";
++ };
++
++ pinctrl_aon: pinctrl@7d510700 {
++ compatible = "brcm,bcm2712-aon-pinctrl";
++ reg = <0x7d510700 0x20>;
++
++ i2c3_m4_agpio0_pins: i2c3_m4_agpio0_pins {
++ function = "vc_i2c3";
++ pins = "aon_gpio0", "aon_gpio1";
++ bias-pull-up;
++ };
++
++ bsc_m1_agpio13_pins: bsc_m1_agpio13_pins {
++ function = "bsc_m1";
++ pins = "aon_gpio13", "aon_gpio14";
++ bias-pull-up;
++ };
++
++ bsc_pmu_sgpio4_pins: bsc_pmu_sgpio4_pins {
++ function = "avs_pmu_bsc";
++ pins = "aon_sgpio4", "aon_sgpio5";
++ };
++
++ bsc_m2_sgpio4_pins: bsc_m2_sgpio4_pins {
++ function = "bsc_m2";
++ pins = "aon_sgpio4", "aon_sgpio5";
++ };
++
++ pwm_aon_agpio1_pins: pwm_aon_agpio1_pins {
++ function = "aon_pwm";
++ pins = "aon_gpio1", "aon_gpio2";
++ };
++
++ pwm_aon_agpio4_pins: pwm_aon_agpio4_pins {
++ function = "vc_pwm0";
++ pins = "aon_gpio4", "aon_gpio5";
++ };
++
++ pwm_aon_agpio7_pins: pwm_aon_agpio7_pins {
++ function = "aon_pwm";
++ pins = "aon_gpio7", "aon_gpio9";
++ };
++ };
++
++ intc@7d517000 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d517000 0x10>;
++ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ status = "disabled";
++ };
++
++ bscc: i2c@7d517a00 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d517a00 0x58>;
++ interrupt-parent = <&bsc_aon_irq>;
++ interrupts = <0>;
++ clock-frequency = <200000>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ pwm_aon: pwm@7d517a80 {
++ compatible = "brcm,bcm7038-pwm";
++ reg = <0x7d517a80 0x28>;
++ #pwm-cells = <3>;
++ clocks = <&clk_27MHz>;
++ };
++
++ main_aon_irq: intc@7d517ac0 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d517ac0 0x10>;
++ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ bsc_aon_irq: intc@7d517b00 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d517b00 0x10>;
++ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ gio_aon: gpio@7d517c00 {
++ compatible = "brcm,brcmstb-gpio";
++ reg = <0x7d517c00 0x40>;
++ interrupt-parent = <&main_aon_irq>;
++ interrupts = <0>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,gpio-bank-widths = <17 6>;
++ brcm,gpio-direct;
++ };
++
++ avs_monitor: avs-monitor@7d542000 {
++ compatible = "brcm,bcm2711-avs-monitor",
++ "syscon", "simple-mfd";
++ reg = <0x7d542000 0xf00>;
++ status = "okay";
++
++ thermal: thermal {
++ compatible = "brcm,bcm2711-thermal";
++ #thermal-sensor-cells = <0>;
++ };
++ };
++
++ bsc_pmu: i2c@7d544000 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d544000 0x58>;
++ interrupt-parent = <&bsc_aon_irq>;
++ interrupts = <1>;
++ clock-frequency = <200000>;
++ status = "disabled";
++ };
++
++ hdmi0: hdmi@7ef00700 {
++ compatible = "brcm,bcm2712-hdmi0";
++ reg = <0x7c701400 0x300>,
++ <0x7c701000 0x200>,
++ <0x7c701d00 0x300>,
++ <0x7c702000 0x80>,
++ <0x7c703800 0x200>,
++ <0x7c704000 0x800>,
++ <0x7c700100 0x80>,
++ <0x7d510800 0x100>,
++ <0x7c720000 0x100>;
++ reg-names = "hdmi",
++ "dvp",
++ "phy",
++ "rm",
++ "packet",
++ "metadata",
++ "csc",
++ "cec",
++ "hd";
++ resets = <&dvp 1>;
++ interrupt-parent = <&aon_intr>;
++ interrupts = <1>, <2>, <3>,
++ <7>, <8>;
++ interrupt-names = "cec-tx", "cec-rx", "cec-low",
++ "hpd-connected", "hpd-removed";
++ ddc = <&ddc0>;
++ dmas = <&dma32 10>;
++ dma-names = "audio-rx";
++ status = "disabled";
++ };
++
++ hdmi1: hdmi@7ef05700 {
++ compatible = "brcm,bcm2712-hdmi1";
++ reg = <0x7c706400 0x300>,
++ <0x7c706000 0x200>,
++ <0x7c706d00 0x300>,
++ <0x7c707000 0x80>,
++ <0x7c708800 0x200>,
++ <0x7c709000 0x800>,
++ <0x7c700180 0x80>,
++ <0x7d511000 0x100>,
++ <0x7c720000 0x100>;
++ reg-names = "hdmi",
++ "dvp",
++ "phy",
++ "rm",
++ "packet",
++ "metadata",
++ "csc",
++ "cec",
++ "hd";
++ ddc = <&ddc1>;
++ resets = <&dvp 2>;
++ interrupt-parent = <&aon_intr>;
++ interrupts = <11>, <12>, <13>,
++ <14>, <15>;
++ interrupt-names = "cec-tx", "cec-rx", "cec-low",
++ "hpd-connected", "hpd-removed";
++ dmas = <&dma32 17>;
++ dma-names = "audio-rx";
++ status = "disabled";
++ };
++ };
++
++ arm-pmu {
++ compatible = "arm,cortex-a76-pmu";
++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>;
++ /* This only applies to the ARMv7 stub */
++ arm,cpu-registers-not-fw-configured;
++ };
++
++ cpus: cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
++
++ /* Source for d/i cache-line-size, cache-sets, cache-size
++ * https://developer.arm.com/documentation/100798/0401
++ * /L1-memory-system/About-the-L1-memory-system?lang=en
++ */
++ cpu0: cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x000>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l0>;
++ };
++
++ cpu1: cpu@1 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x100>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l1>;
++ };
++
++ cpu2: cpu@2 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x200>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l2>;
++ };
++
++ cpu3: cpu@3 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x300>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l3>;
++ };
++
++ /* Source for cache-line-size and cache-sets:
++ * https://developer.arm.com/documentation/100798/0401
++ * /L2-memory-system/About-the-L2-memory-system?lang=en
++ * and for cache-size:
++ * https://www.raspberrypi.com/documentation/computers
++ * /processors.html#bcm2712
++ */
++ l2_cache_l0: l2-cache-l0 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l1: l2-cache-l1 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l2: l2-cache-l2 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l3: l2-cache-l3 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ /* Source for cache-line-size and cache-sets:
++ * https://developer.arm.com/documentation/100453/0401/L3-cache?lang=en
++ * Source for cache-size:
++ * https://www.raspberrypi.com/documentation/computers/processors.html#bcm2712
++ */
++ l3_cache: l3-cache {
++ compatible = "cache";
++ cache-size = <0x200000>;
++ cache-line-size = <64>;
++ cache-sets = <2048>; // 2MiB(size)/64(line-size)=32768ways/16-way set
++ cache-level = <3>;
++ };
++ };
++
++ psci {
++ method = "smc";
++ compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
++ cpu_on = <0xc4000003>;
++ cpu_suspend = <0xc4000001>;
++ cpu_off = <0x84000002>;
++ };
++
++ axi: axi {
++ compatible = "simple-bus";
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
++ <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
++ <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
++ <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
++ <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
++
++ dma-ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
++ <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
++ <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
++ <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
++ <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
++
++ vc4: gpu {
++ compatible = "brcm,bcm2712-vc6";
++ };
++
++ iommu2: iommu@5100 {
++ /* IOMMU2 for PISP-BE, HEVC; and (unused) H264 accelerators */
++ compatible = "brcm,bcm2712-iommu";
++ reg = <0x10 0x5100 0x0 0x80>;
++ cache = <&iommuc>;
++ #iommu-cells = <0>;
++ };
++
++ iommu4: iommu@5200 {
++ /* IOMMU4 for HVS, MPL/TXP; and (unused) Unicam, PISP-FE, MiniBVN */
++ compatible = "brcm,bcm2712-iommu";
++ reg = <0x10 0x5200 0x0 0x80>;
++ cache = <&iommuc>;
++ #iommu-cells = <0>;
++ #interconnect-cells = <0>;
++ };
++
++ iommu5: iommu@5280 {
++ /* IOMMU5 for PCIe2 (RP1); and (unused) BSTM */
++ compatible = "brcm,bcm2712-iommu";
++ reg = <0x10 0x5280 0x0 0x80>;
++ cache = <&iommuc>;
++ #iommu-cells = <0>;
++ dma-iova-offset = <0x10 0x00000000>; // HACK for RP1 masters over PCIe
++ };
++
++ iommuc: iommuc@5b00 {
++ compatible = "brcm,bcm2712-iommuc";
++ reg = <0x10 0x5b00 0x0 0x80>;
++ };
++
++ dma32: dma@10000 {
++ compatible = "brcm,bcm2712-dma";
++ reg = <0x10 0x00010000 0 0x600>;
++ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "dma0",
++ "dma1",
++ "dma2",
++ "dma3",
++ "dma4",
++ "dma5";
++ #dma-cells = <1>;
++ brcm,dma-channel-mask = <0x0035>;
++ };
++
++ dma40: dma@10600 {
++ compatible = "brcm,bcm2712-dma";
++ reg = <0x10 0x00010600 0 0x600>;
++ interrupts =
++ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, /* dma4 6 */
++ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, /* dma4 7 */
++ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, /* dma4 8 */
++ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, /* dma4 9 */
++ <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, /* dma4 10 */
++ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; /* dma4 11 */
++ interrupt-names = "dma6",
++ "dma7",
++ "dma8",
++ "dma9",
++ "dma10",
++ "dma11";
++ #dma-cells = <1>;
++ brcm,dma-channel-mask = <0x0fc0>;
++ };
++
++ // Single-lane Gen3 PCIe
++ // Outbound window at 0x14_000000-0x17_ffffff
++ pcie0: pcie@100000 {
++ compatible = "brcm,bcm2712-pcie";
++ reg = <0x10 0x00100000 0x0 0x9310>;
++ device_type = "pci";
++ max-link-speed = <2>;
++ #address-cells = <3>;
++ #interrupt-cells = <1>;
++ #size-cells = <2>;
++ /*
++ * Unused interrupts:
++ * 208: AER
++ * 215: NMI
++ * 216: PME
++ */
++ interrupt-parent = <&gicv2>;
++ interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "pcie", "msi";
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 209
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 2 &gicv2 GIC_SPI 210
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 3 &gicv2 GIC_SPI 211
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 4 &gicv2 GIC_SPI 212
++ IRQ_TYPE_LEVEL_HIGH>;
++ resets = <&bcm_reset 5>, <&bcm_reset 42>, <&pcie_rescal>;
++ reset-names = "swinit", "bridge", "rescal";
++ msi-controller;
++ msi-parent = <&pcie0>;
++
++ ranges = <0x02000000 0x00 0x00000000
++ 0x17 0x00000000
++ 0x0 0xfffffffc>,
++ <0x43000000 0x04 0x00000000
++ 0x14 0x00000000
++ 0x3 0x00000000>;
++
++ dma-ranges = <0x43000000 0x10 0x00000000
++ 0x00 0x00000000
++ 0x10 0x00000000>;
++
++ status = "disabled";
++ };
++
++ // Single-lane Gen3 PCIe
++ // Outbound window at 0x18_000000-0x1b_ffffff
++ pcie1: pcie@110000 {
++ compatible = "brcm,bcm2712-pcie";
++ reg = <0x10 0x00110000 0x0 0x9310>;
++ device_type = "pci";
++ max-link-speed = <2>;
++ #address-cells = <3>;
++ #interrupt-cells = <1>;
++ #size-cells = <2>;
++ /*
++ * Unused interrupts:
++ * 218: AER
++ * 225: NMI
++ * 226: PME
++ */
++ interrupt-parent = <&gicv2>;
++ interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "pcie", "msi";
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 219
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 2 &gicv2 GIC_SPI 220
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 3 &gicv2 GIC_SPI 221
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 4 &gicv2 GIC_SPI 222
++ IRQ_TYPE_LEVEL_HIGH>;
++ resets = <&bcm_reset 7>, <&bcm_reset 43>, <&pcie_rescal>;
++ reset-names = "swinit", "bridge", "rescal";
++ msi-controller;
++ msi-parent = <&mip1>;
++
++ ranges = <0x02000000 0x00 0x00000000
++ 0x1b 0x00000000
++ 0x00 0xfffffffc>,
++ <0x43000000 0x04 0x00000000
++ 0x18 0x00000000
++ 0x03 0x00000000>;
++
++ dma-ranges = <0x03000000 0x10 0x00000000
++ 0x00 0x00000000
++ 0x10 0x00000000>;
++
++ status = "disabled";
++ };
++
++ pcie_rescal: reset-controller@119500 {
++ compatible = "brcm,bcm7216-pcie-sata-rescal";
++ reg = <0x10 0x00119500 0x0 0x10>;
++ #reset-cells = <0>;
++ };
++
++ // Quad-lane Gen3 PCIe
++ // Outbound window at 0x1c_000000-0x1f_ffffff
++ pcie2: pcie@120000 {
++ compatible = "brcm,bcm2712-pcie";
++ reg = <0x10 0x00120000 0x0 0x9310>;
++ device_type = "pci";
++ max-link-speed = <2>;
++ #address-cells = <3>;
++ #interrupt-cells = <1>;
++ #size-cells = <2>;
++ /*
++ * Unused interrupts:
++ * 228: AER
++ * 235: NMI
++ * 236: PME
++ */
++ interrupt-parent = <&gicv2>;
++ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "pcie", "msi";
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 229
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 2 &gicv2 GIC_SPI 230
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 3 &gicv2 GIC_SPI 231
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 4 &gicv2 GIC_SPI 232
++ IRQ_TYPE_LEVEL_HIGH>;
++ resets = <&bcm_reset 32>, <&bcm_reset 44>, <&pcie_rescal>;
++ reset-names = "swinit", "bridge", "rescal";
++ msi-controller;
++ msi-parent = <&mip0>;
++
++ // ~4GB, 32-bit, not-prefetchable at PCIe 00_00000000
++ ranges = <0x02000000 0x00 0x00000000
++ 0x1f 0x00000000
++ 0x0 0xfffffffc>,
++ // 12GB, 64-bit, prefetchable at PCIe 04_00000000
++ <0x43000000 0x04 0x00000000
++ 0x1c 0x00000000
++ 0x03 0x00000000>;
++
++ // 64GB system RAM space at PCIe 10_00000000
++ dma-ranges = <0x02000000 0x00 0x00000000
++ 0x1f 0x00000000
++ 0x00 0x00400000>,
++ <0x43000000 0x10 0x00000000
++ 0x00 0x00000000
++ 0x10 0x00000000>;
++
++ status = "disabled";
++ };
++
++ mip0: msi-controller@130000 {
++ compatible = "brcm,bcm2712-mip-intc";
++ reg = <0x10 0x00130000 0x0 0xc0>;
++ msi-controller;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,msi-base-spi = <128>;
++ brcm,msi-num-spis = <64>;
++ brcm,msi-offset = <0>;
++ brcm,msi-pci-addr = <0xff 0xfffff000>;
++ };
++
++ mip1: msi-controller@131000 {
++ compatible = "brcm,bcm2712-mip-intc";
++ reg = <0x10 0x00131000 0x0 0xc0>;
++ msi-controller;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,msi-base-spi = <247>;
++ /* Actually 20 total, but the others are
++ * both sparse and non-consecutive */
++ brcm,msi-num-spis = <8>;
++ brcm,msi-offset = <8>;
++ brcm,msi-pci-addr = <0xff 0xffffe000>;
++ };
++
++ syscon_piarbctl: syscon@400018 {
++ compatible = "brcm,syscon-piarbctl", "syscon", "simple-mfd";
++ reg = <0x10 0x00400018 0x0 0x18>;
++ };
++
++ usb: usb@480000 {
++ compatible = "brcm,bcm2835-usb";
++ reg = <0x10 0x00480000 0x0 0x10000>;
++ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ clocks = <&clk_usb>;
++ clock-names = "otg";
++ phys = <&usbphy>;
++ phy-names = "usb2-phy";
++ status = "disabled";
++ };
++
++ rpivid: codec@800000 {
++ compatible = "raspberrypi,rpivid-vid-decoder";
++ reg = <0x10 0x00800000 0x0 0x10000>, /* HEVC */
++ <0x10 0x00840000 0x0 0x1000>; /* INTC */
++ reg-names = "hevc",
++ "intc";
++
++ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&firmware_clocks 11>;
++ clock-names = "hevc";
++ iommus = <&iommu2>;
++ status = "disabled";
++ };
++
++ sdio1: mmc@fff000 {
++ compatible = "brcm,bcm2712-sdhci";
++ reg = <0x10 0x00fff000 0x0 0x260>,
++ <0x10 0x00fff400 0x0 0x200>,
++ <0x10 0x015040b0 0x0 0x4>, // Bus isolation control
++ <0x10 0x015200f0 0x0 0x24>; // LCPLL control misc0-8
++ reg-names = "host", "cfg", "busisol", "lcpll";
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_emmc2>;
++ sdhci-caps-mask = <0x0000C000 0x0>;
++ sdhci-caps = <0x0 0x0>;
++ mmc-ddr-3_3v;
++ };
++
++ sdio2: mmc@1100000 {
++ compatible = "brcm,bcm2712-sdhci";
++ reg = <0x10 0x01100000 0x0 0x260>,
++ <0x10 0x01100400 0x0 0x200>;
++ reg-names = "host", "cfg";
++ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_emmc2>;
++ sdhci-caps-mask = <0x0000C000 0x0>;
++ sdhci-caps = <0x0 0x0>;
++ supports-cqe;
++ mmc-ddr-3_3v;
++ status = "disabled";
++ };
++
++ bcm_reset: reset-controller@1504318 {
++ compatible = "brcm,brcmstb-reset";
++ reg = <0x10 0x01504318 0x0 0x30>;
++ #reset-cells = <1>;
++ };
++
++ v3d: v3d@2000000 {
++ compatible = "brcm,2712-v3d";
++ reg = <0x10 0x02000000 0x0 0x4000>,
++ <0x10 0x02008000 0x0 0x6000>;
++ reg-names = "hub", "core0";
++
++ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
++ resets = <&pm BCM2835_RESET_V3D>;
++ clocks = <&firmware_clocks 5>;
++ clocks-names = "v3d";
++ interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ gicv2: interrupt-controller@7fff9000 {
++ interrupt-controller;
++ #interrupt-cells = <3>;
++ compatible = "arm,gic-400";
++ reg = <0x10 0x7fff9000 0x0 0x1000>,
++ <0x10 0x7fffa000 0x0 0x2000>,
++ <0x10 0x7fffc000 0x0 0x2000>,
++ <0x10 0x7fffe000 0x0 0x2000>;
++ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_HIGH)>;
++ };
++
++ pisp_be: pisp_be@880000 {
++ compatible = "raspberrypi,pispbe";
++ reg = <0x10 0x00880000 0x0 0x4000>;
++ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&firmware_clocks 7>;
++ clocks-names = "isp_be";
++ status = "okay";
++ iommus = <&iommu2>;
++ };
++ };
++
++ clocks {
++ /* The oscillator is the root of the clock tree. */
++ clk_osc: clk-osc {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "osc";
++ clock-frequency = <54000000>;
++ };
++
++ clk_usb: clk-usb {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "otg";
++ clock-frequency = <480000000>;
++ };
++
++ clk_vpu: clk_vpu {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <750000000>;
++ clock-output-names = "vpu-clock";
++ };
++
++ clk_uart: clk_uart {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <9216000>;
++ clock-output-names = "uart-clock";
++ };
++
++ clk_emmc2: clk_emmc2 {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <200000000>;
++ clock-output-names = "emmc2-clock";
++ };
++ };
++
++ usbphy: phy {
++ compatible = "usb-nop-xceiv";
++ #phy-cells = <0>;
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
+@@ -0,0 +1,1287 @@
++#include <dt-bindings/clock/rp1.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/mfd/rp1.h>
++
++&rp1_target {
++ rp1: rp1 {
++ compatible = "simple-bus";
++ #address-cells = <2>;
++ #size-cells = <2>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&rp1>;
++
++ // ranges and dma-ranges must be provided by the includer
++
++ rp1_clocks: clocks@18000 {
++ compatible = "raspberrypi,rp1-clocks";
++ #clock-cells = <1>;
++ reg = <0xc0 0x40018000 0x0 0x10038>;
++ clocks = <&clk_xosc>;
++
++ assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
++ <&rp1_clocks RP1_PLL_AUDIO_CORE>,
++ // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
++ <&rp1_clocks RP1_PLL_SYS>,
++ <&rp1_clocks RP1_PLL_SYS_SEC>,
++ <&rp1_clocks RP1_PLL_AUDIO>,
++ <&rp1_clocks RP1_PLL_AUDIO_SEC>,
++ <&rp1_clocks RP1_CLK_SYS>,
++ <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
++ // RP1_CLK_SLOW_SYS is used for the frequency counter (FC0)
++ <&rp1_clocks RP1_CLK_SLOW_SYS>,
++ <&rp1_clocks RP1_CLK_SDIO_TIMER>,
++ <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
++ <&rp1_clocks RP1_CLK_ETH_TSU>;
++
++ assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
++ <1536000000>, // RP1_PLL_AUDIO_CORE
++ <200000000>, // RP1_PLL_SYS
++ <125000000>, // RP1_PLL_SYS_SEC
++ <61440000>, // RP1_PLL_AUDIO
++ <192000000>, // RP1_PLL_AUDIO_SEC
++ <200000000>, // RP1_CLK_SYS
++ <100000000>, // RP1_PLL_SYS_PRI_PH
++ // Must match the XOSC frequency
++ <50000000>, // RP1_CLK_SLOW_SYS
++ <1000000>, // RP1_CLK_SDIO_TIMER
++ <200000000>, // RP1_CLK_SDIO_ALT_SRC
++ <50000000>; // RP1_CLK_ETH_TSU
++ };
++
++ rp1_uart0: serial@30000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40030000 0x0 0x100>;
++ interrupts = <RP1_INT_UART0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ dmas = <&rp1_dma RP1_DMA_UART0_TX>,
++ <&rp1_dma RP1_DMA_UART0_RX>;
++ dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart1: serial@34000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40034000 0x0 0x100>;
++ interrupts = <RP1_INT_UART1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART1_TX>,
++ // <&rp1_dma RP1_DMA_UART1_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart2: serial@38000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40038000 0x0 0x100>;
++ interrupts = <RP1_INT_UART2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART2_TX>,
++ // <&rp1_dma RP1_DMA_UART2_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart3: serial@3c000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x4003c000 0x0 0x100>;
++ interrupts = <RP1_INT_UART3 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART3_TX>,
++ // <&rp1_dma RP1_DMA_UART3_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart4: serial@40000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40040000 0x0 0x100>;
++ interrupts = <RP1_INT_UART4 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART4_TX>,
++ // <&rp1_dma RP1_DMA_UART4_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart5: serial@44000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40044000 0x0 0x100>;
++ interrupts = <RP1_INT_UART5 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART5_TX>,
++ // <&rp1_dma RP1_DMA_UART5_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_spi8: spi@4c000 {
++ reg = <0xc0 0x4004c000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI8 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI8_TX>,
++ <&rp1_dma RP1_DMA_SPI8_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi0: spi@50000 {
++ reg = <0xc0 0x40050000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI0_TX>,
++ <&rp1_dma RP1_DMA_SPI0_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi1: spi@54000 {
++ reg = <0xc0 0x40054000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI1_TX>,
++ <&rp1_dma RP1_DMA_SPI1_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi2: spi@58000 {
++ reg = <0xc0 0x40058000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI2_TX>,
++ <&rp1_dma RP1_DMA_SPI2_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi3: spi@5c000 {
++ reg = <0xc0 0x4005c000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI3 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI3_TX>,
++ <&rp1_dma RP1_DMA_SPI3_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ // SPI4 is a target/slave interface
++ rp1_spi4: spi@60000 {
++ reg = <0xc0 0x40060000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI4 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <0>;
++ #size-cells = <0>;
++ num-cs = <1>;
++ spi-slave;
++ dmas = <&rp1_dma RP1_DMA_SPI4_TX>,
++ <&rp1_dma RP1_DMA_SPI4_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++
++ slave {
++ compatible = "spidev";
++ spi-max-frequency = <1000000>;
++ };
++ };
++
++ rp1_spi5: spi@64000 {
++ reg = <0xc0 0x40064000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI5 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI5_TX>,
++ <&rp1_dma RP1_DMA_SPI5_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi6: spi@68000 {
++ reg = <0xc0 0x40068000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI6 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI6_TX>,
++ <&rp1_dma RP1_DMA_SPI6_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ // SPI7 is a target/slave interface
++ rp1_spi7: spi@6c000 {
++ reg = <0xc0 0x4006c000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI7 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <0>;
++ #size-cells = <0>;
++ num-cs = <1>;
++ spi-slave;
++ dmas = <&rp1_dma RP1_DMA_SPI7_TX>,
++ <&rp1_dma RP1_DMA_SPI7_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++
++ slave {
++ compatible = "spidev";
++ spi-max-frequency = <1000000>;
++ };
++ };
++
++ rp1_i2c0: i2c@70000 {
++ reg = <0xc0 0x40070000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c1: i2c@74000 {
++ reg = <0xc0 0x40074000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c2: i2c@78000 {
++ reg = <0xc0 0x40078000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c3: i2c@7c000 {
++ reg = <0xc0 0x4007c000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C3 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c4: i2c@80000 {
++ reg = <0xc0 0x40080000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C4 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c5: i2c@84000 {
++ reg = <0xc0 0x40084000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C5 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c6: i2c@88000 {
++ reg = <0xc0 0x40088000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C6 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_pwm0: pwm@98000 {
++ compatible = "raspberrypi,rp1-pwm";
++ reg = <0xc0 0x40098000 0x0 0x100>;
++ #pwm-cells = <3>;
++ clocks = <&rp1_clocks RP1_CLK_PWM0>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_PWM0>;
++ assigned-clock-rates = <50000000>;
++ status = "disabled";
++ };
++
++ rp1_pwm1: pwm@9c000 {
++ compatible = "raspberrypi,rp1-pwm";
++ reg = <0xc0 0x4009c000 0x0 0x100>;
++ #pwm-cells = <3>;
++ clocks = <&rp1_clocks RP1_CLK_PWM1>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_PWM1>;
++ assigned-clock-rates = <50000000>;
++ status = "disabled";
++ };
++
++ rp1_i2s0: i2s@a0000 {
++ reg = <0xc0 0x400a0000 0x0 0x1000>;
++ compatible = "snps,designware-i2s";
++ // Providing an interrupt disables DMA
++ // interrupts = <RP1_INT_I2S0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_I2S>;
++ clock-names = "i2sclk";
++ #sound-dai-cells = <0>;
++ dmas = <&rp1_dma RP1_DMA_I2S0_TX>,<&rp1_dma RP1_DMA_I2S0_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_i2s1: i2s@a4000 {
++ reg = <0xc0 0x400a4000 0x0 0x1000>;
++ compatible = "snps,designware-i2s";
++ // Providing an interrupt disables DMA
++ // interrupts = <RP1_INT_I2S1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_I2S>;
++ clock-names = "i2sclk";
++ #sound-dai-cells = <0>;
++ dmas = <&rp1_dma RP1_DMA_I2S1_TX>,<&rp1_dma RP1_DMA_I2S1_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_i2s2: i2s@a8000 {
++ reg = <0xc0 0x400a8000 0x0 0x1000>;
++ compatible = "snps,designware-i2s";
++ // Providing an interrupt disables DMA
++ // interrupts = <RP1_INT_I2S2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_I2S>;
++ status = "disabled";
++ };
++
++ rp1_sdio_clk0: sdio_clk0@b0004 {
++ compatible = "raspberrypi,rp1-sdio-clk";
++ reg = <0xc0 0x400b0004 0x0 0x1c>;
++ clocks = <&sdio_src &sdhci_core>;
++ clock-names = "src", "base";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_sdio_clk1: sdio_clk1@b4004 {
++ compatible = "raspberrypi,rp1-sdio-clk";
++ reg = <0xc0 0x400b4004 0x0 0x1c>;
++ clocks = <&sdio_src &sdhci_core>;
++ clock-names = "src", "base";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_adc: adc@c8000 {
++ compatible = "raspberrypi,rp1-adc";
++ reg = <0xc0 0x400c8000 0x0 0x4000>;
++ clocks = <&rp1_clocks RP1_CLK_ADC>;
++ clock-names = "adcclk";
++ #clock-cells = <0>;
++ vref-supply = <&rp1_vdd_3v3>;
++ status = "disabled";
++ };
++
++ rp1_gpio: gpio@d0000 {
++ reg = <0xc0 0x400d0000 0x0 0xc000>,
++ <0xc0 0x400e0000 0x0 0xc000>,
++ <0xc0 0x400f0000 0x0 0xc000>;
++ compatible = "raspberrypi,rp1-gpio";
++ interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
++ <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
++ <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ gpio-ranges = <&rp1_gpio 0 0 54>;
++
++ rp1_uart0_14_15: rp1_uart0_14_15 {
++ pin_txd {
++ function = "uart0";
++ pins = "gpio14";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart0";
++ pins = "gpio15";
++ bias-pull-up;
++ };
++ };
++ rp1_uart0_ctsrts_16_17: rp1_uart0_ctsrts_16_17 {
++ pin_cts {
++ function = "uart0";
++ pins = "gpio16";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart0";
++ pins = "gpio17";
++ bias-disable;
++ };
++ };
++ rp1_uart1_0_1: rp1_uart1_0_1 {
++ pin_txd {
++ function = "uart1";
++ pins = "gpio0";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart1";
++ pins = "gpio1";
++ bias-pull-up;
++ };
++ };
++ rp1_uart1_ctsrts_2_3: rp1_uart1_ctsrts_2_3 {
++ pin_cts {
++ function = "uart1";
++ pins = "gpio2";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart1";
++ pins = "gpio3";
++ bias-disable;
++ };
++ };
++ rp1_uart2_4_5: rp1_uart2_4_5 {
++ pin_txd {
++ function = "uart2";
++ pins = "gpio4";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart2";
++ pins = "gpio5";
++ bias-pull-up;
++ };
++ };
++ rp1_uart2_ctsrts_6_7: rp1_uart2_ctsrts_6_7 {
++ pin_cts {
++ function = "uart2";
++ pins = "gpio6";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart2";
++ pins = "gpio7";
++ bias-disable;
++ };
++ };
++ rp1_uart3_8_9: rp1_uart3_8_9 {
++ pin_txd {
++ function = "uart3";
++ pins = "gpio8";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart3";
++ pins = "gpio9";
++ bias-pull-up;
++ };
++ };
++ rp1_uart3_ctsrts_10_11: rp1_uart3_ctsrts_10_11 {
++ pin_cts {
++ function = "uart3";
++ pins = "gpio10";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart3";
++ pins = "gpio11";
++ bias-disable;
++ };
++ };
++ rp1_uart4_12_13: rp1_uart4_12_13 {
++ pin_txd {
++ function = "uart4";
++ pins = "gpio12";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart4";
++ pins = "gpio13";
++ bias-pull-up;
++ };
++ };
++ rp1_uart4_ctsrts_14_15: rp1_uart4_ctsrts_14_15 {
++ pin_cts {
++ function = "uart4";
++ pins = "gpio14";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart4";
++ pins = "gpio15";
++ bias-disable;
++ };
++ };
++
++ rp1_sdio0_22_27: rp1_sdio0_22_27 {
++ pin_clk {
++ function = "sd0";
++ pins = "gpio22";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pin_cmd {
++ function = "sd0";
++ pins = "gpio23";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pins_dat {
++ function = "sd0";
++ pins = "gpio24", "gpio25", "gpio26", "gpio27";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ };
++
++ rp1_sdio1_28_33: rp1_sdio1_28_33 {
++ pin_clk {
++ function = "sd1";
++ pins = "gpio28";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pin_cmd {
++ function = "sd1";
++ pins = "gpio29";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pins_dat {
++ function = "sd1";
++ pins = "gpio30", "gpio31", "gpio32", "gpio33";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ };
++
++ rp1_i2s0_18_21: rp1_i2s0_18_21 {
++ function = "i2s0";
++ pins = "gpio18", "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ };
++
++ rp1_i2s1_18_21: rp1_i2s1_18_21 {
++ function = "i2s1";
++ pins = "gpio18", "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ };
++
++ rp1_i2c4_34_35: rp1_i2c4_34_35 {
++ function = "i2c4";
++ pins = "gpio34", "gpio35";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c6_38_39: rp1_i2c6_38_39 {
++ function = "i2c6";
++ pins = "gpio38", "gpio39";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c4_40_41: rp1_i2c4_40_41 {
++ function = "i2c4";
++ pins = "gpio40", "gpio41";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c5_44_45: rp1_i2c5_44_45 {
++ function = "i2c5";
++ pins = "gpio44", "gpio45";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c0_0_1: rp1_i2c0_0_1 {
++ function = "i2c0";
++ pins = "gpio0", "gpio1";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c0_8_9: rp1_i2c0_8_9 {
++ function = "i2c0";
++ pins = "gpio8", "gpio9";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c1_2_3: rp1_i2c1_2_3 {
++ function = "i2c1";
++ pins = "gpio2", "gpio3";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c1_10_11: rp1_i2c1_10_11 {
++ function = "i2c1";
++ pins = "gpio10", "gpio11";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c2_4_5: rp1_i2c2_4_5 {
++ function = "i2c2";
++ pins = "gpio4", "gpio5";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c2_12_13: rp1_i2c2_12_13 {
++ function = "i2c2";
++ pins = "gpio12", "gpio13";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c3_6_7: rp1_i2c3_6_7 {
++ function = "i2c3";
++ pins = "gpio6", "gpio7";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c3_14_15: rp1_i2c3_14_15 {
++ function = "i2c3";
++ pins = "gpio14", "gpio15";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c3_22_23: rp1_i2c3_22_23 {
++ function = "i2c3";
++ pins = "gpio22", "gpio23";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++
++ // DPI mappings with HSYNC,VSYNC but without PIXCLK,DE
++ rp1_dpi_16bit_gpio2: rp1_dpi_16bit_gpio2 { /* Mode 2, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio10", "gpio11", "gpio12", "gpio13",
++ "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19";
++ bias-disable;
++ };
++ rp1_dpi_16bit_cpadhi_gpio2: rp1_dpi_16bit_cpadhi_gpio2 { /* Mode 3 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24";
++ bias-disable;
++ };
++ rp1_dpi_16bit_pad666_gpio2: rp1_dpi_16bit_pad666_gpio2 { /* Mode 4 */
++ function = "dpi";
++ pins = "gpio2", "gpio3",
++ "gpio5", "gpio6", "gpio7", "gpio8",
++ "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio21", "gpio22", "gpio23", "gpio24",
++ "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_18bit_gpio2: rp1_dpi_18bit_gpio2 { /* Mode 5, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio10", "gpio11", "gpio12", "gpio13",
++ "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ };
++ rp1_dpi_18bit_cpadhi_gpio2: rp1_dpi_18bit_cpadhi_gpio2 { /* Mode 6 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_24bit_gpio2: rp1_dpi_24bit_gpio2 { /* Mode 7 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio10", "gpio11", "gpio12", "gpio13",
++ "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19", "gpio20", "gpio21",
++ "gpio22", "gpio23", "gpio24", "gpio25",
++ "gpio26", "gpio27";
++ bias-disable;
++ };
++ rp1_dpi_hvsync: rp1_dpi_hvsync { /* Sync only, for use with int VDAC */
++ function = "dpi";
++ pins = "gpio2", "gpio3";
++ bias-disable;
++ };
++
++ // More DPI mappings, including PIXCLK,DE on GPIOs 0,1
++ rp1_dpi_16bit_gpio0: rp1_dpi_16bit_gpio0 { /* Mode 2, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17", "gpio18", "gpio19";
++ bias-disable;
++ };
++ rp1_dpi_16bit_cpadhi_gpio0: rp1_dpi_16bit_cpadhi_gpio0 { /* Mode 3 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24";
++ bias-disable;
++ };
++ rp1_dpi_16bit_pad666_gpio0: rp1_dpi_16bit_pad666_gpio0 { /* Mode 4 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio5", "gpio6", "gpio7", "gpio8",
++ "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio21", "gpio22", "gpio23", "gpio24",
++ "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_18bit_gpio0: rp1_dpi_18bit_gpio0 { /* Mode 5, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17", "gpio18", "gpio19",
++ "gpio20", "gpio21";
++ bias-disable;
++ };
++ rp1_dpi_18bit_cpadhi_gpio0: rp1_dpi_18bit_cpadhi_gpio0 { /* Mode 6 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_24bit_gpio0: rp1_dpi_24bit_gpio0 { /* Mode 7 -- All GPIOs used! */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17", "gpio18", "gpio19",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25", "gpio26", "gpio27";
++ bias-disable;
++ };
++
++ rp1_gpclksrc0_gpio4: rp1_gpclksrc0_gpio4 {
++ function = "gpclk0";
++ pins = "gpio4";
++ bias-disable;
++ };
++
++ rp1_gpclksrc0_gpio20: rp1_gpclksrc0_gpio20 {
++ function = "gpclk0";
++ pins = "gpio20";
++ bias-disable;
++ };
++
++ rp1_gpclksrc1_gpio5: rp1_gpclksrc1_gpio5 {
++ function = "gpclk1";
++ pins = "gpio5";
++ bias-disable;
++ };
++
++ rp1_gpclksrc1_gpio18: rp1_gpclksrc1_gpio18 {
++ function = "gpclk1";
++ pins = "gpio18";
++ bias-disable;
++ };
++
++ rp1_gpclksrc1_gpio21: rp1_gpclksrc1_gpio21 {
++ function = "gpclk1";
++ pins = "gpio21";
++ bias-disable;
++ };
++
++ rp1_pwm1_gpio45: rp1_pwm1_gpio45 {
++ function = "pwm1";
++ pins = "gpio45";
++ bias-pull-down;
++ };
++
++ rp1_spi0_gpio9: rp1_spi0_gpio9 {
++ function = "spi0";
++ pins = "gpio9", "gpio10", "gpio11";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi0_cs_gpio7: rp1_spi0_cs_gpio7 {
++ function = "spi0";
++ pins = "gpio7", "gpio8";
++ bias-pull-up;
++ };
++
++ rp1_spi1_gpio19: rp1_spi1_gpio19 {
++ function = "spi1";
++ pins = "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi2_gpio1: rp1_spi2_gpio1 {
++ function = "spi2";
++ pins = "gpio1", "gpio2", "gpio3";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi3_gpio5: rp1_spi3_gpio5 {
++ function = "spi3";
++ pins = "gpio5", "gpio6", "gpio7";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi4_gpio9: rp1_spi4_gpio9 {
++ function = "spi4";
++ pins = "gpio9", "gpio10", "gpio11";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi5_gpio13: rp1_spi5_gpio13 {
++ function = "spi5";
++ pins = "gpio13", "gpio14", "gpio15";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi8_gpio49: rp1_spi8_gpio49 {
++ function = "spi8";
++ pins = "gpio49", "gpio50", "gpio51";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi8_cs_gpio52: rp1_spi8_cs_gpio52 {
++ function = "spi0";
++ pins = "gpio52", "gpio53";
++ bias-pull-up;
++ };
++ };
++
++ rp1_eth: ethernet@100000 {
++ reg = <0xc0 0x40100000 0x0 0x4000>;
++ compatible = "cdns,macb";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&macb_pclk &macb_hclk &rp1_clocks RP1_CLK_ETH_TSU>;
++ clock-names = "pclk", "hclk", "tsu_clk";
++ phy-mode = "rgmii-id";
++ cdns,aw2w-max-pipe = /bits/ 8 <8>;
++ cdns,ar2r-max-pipe = /bits/ 8 <8>;
++ cdns,use-aw2b-fill;
++ local-mac-address = [00 00 00 00 00 00];
++ status = "disabled";
++ };
++
++ rp1_csi0: csi@110000 {
++ compatible = "raspberrypi,rp1-cfe";
++ reg = <0xc0 0x40110000 0x0 0x100>, // CSI2 DMA address
++ <0xc0 0x40114000 0x0 0x100>, // PHY/CSI Host address
++ <0xc0 0x40120000 0x0 0x100>, // MIPI CFG address
++ <0xc0 0x40124000 0x0 0x1000>; // PiSP FE address
++
++ // interrupts must match rp1_pisp_fe setup
++ interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
++ assigned-clock-rates = <25000000>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_csi1: csi@128000 {
++ compatible = "raspberrypi,rp1-cfe";
++ reg = <0xc0 0x40128000 0x0 0x100>, // CSI2 DMA address
++ <0xc0 0x4012c000 0x0 0x100>, // PHY/CSI Host address
++ <0xc0 0x40138000 0x0 0x100>, // MIPI CFG address
++ <0xc0 0x4013c000 0x0 0x1000>; // PiSP FE address
++
++ // interrupts must match rp1_pisp_fe setup
++ interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
++ assigned-clock-rates = <25000000>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_mmc0: mmc@180000 {
++ reg = <0xc0 0x40180000 0x0 0x100>;
++ compatible = "raspberrypi,rp1-dwcmshc";
++ interrupts = <RP1_INT_SDIO0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
++ &rp1_clocks RP1_CLK_SDIO_TIMER
++ &rp1_sdio_clk0>;
++ clock-names = "bus", "core", "timeout", "sdio";
++ /* Bank 0 VDDIO is fixed */
++ no-1-8-v;
++ bus-width = <4>;
++ vmmc-supply = <&rp1_vdd_3v3>;
++ broken-cd;
++ status = "disabled";
++ };
++
++ rp1_mmc1: mmc@184000 {
++ reg = <0xc0 0x40184000 0x0 0x100>;
++ compatible = "raspberrypi,rp1-dwcmshc";
++ interrupts = <RP1_INT_SDIO1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
++ &rp1_clocks RP1_CLK_SDIO_TIMER
++ &rp1_sdio_clk1>;
++ clock-names = "bus", "core", "timeout", "sdio";
++ bus-width = <4>;
++ vmmc-supply = <&rp1_vdd_3v3>;
++ /* Nerf SDR speeds */
++ sdhci-caps-mask = <0x3 0x0>;
++ broken-cd;
++ status = "disabled";
++ };
++
++ rp1_dma: dma@188000 {
++ reg = <0xc0 0x40188000 0x0 0x1000>;
++ compatible = "snps,axi-dma-1.01a";
++ interrupts = <RP1_INT_DMA IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&sdhci_core &rp1_clocks RP1_CLK_SYS>;
++ clock-names = "core-clk", "cfgr-clk";
++
++ #dma-cells = <1>;
++ dma-channels = <8>;
++ snps,dma-masters = <1>;
++ snps,dma-targets = <64>;
++ snps,data-width = <4>; // (8 << 4) == 128 bits
++ snps,block-size = <0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000>;
++ snps,priority = <0 1 2 3 4 5 6 7>;
++ snps,axi-max-burst-len = <8>;
++ status = "disabled";
++ };
++
++ rp1_usb0: usb@200000 {
++ reg = <0xc0 0x40200000 0x0 0x100000>;
++ compatible = "snps,dwc3";
++ dr_mode = "host";
++ usb3-lpm-capable;
++ snps,axi-pipe-limit = /bits/ 8 <8>;
++ snps,dis_rxdet_inp3_quirk;
++ snps,parkmode-disable-ss-quirk;
++ snps,parkmode-disable-hs-quirk;
++ snps,parkmode-disable-fsls-quirk;
++ snps,tx-max-burst = /bits/ 8 <8>;
++ snps,tx-thr-num-pkt = /bits/ 8 <2>;
++ interrupts = <RP1_INT_USBHOST0_0 IRQ_TYPE_EDGE_RISING>;
++ status = "disabled";
++ };
++
++ rp1_usb1: usb@300000 {
++ reg = <0xc0 0x40300000 0x0 0x100000>;
++ compatible = "snps,dwc3";
++ dr_mode = "host";
++ usb3-lpm-capable;
++ snps,axi-pipe-limit = /bits/ 8 <8>;
++ snps,dis_rxdet_inp3_quirk;
++ snps,parkmode-disable-ss-quirk;
++ snps,parkmode-disable-hs-quirk;
++ snps,parkmode-disable-fsls-quirk;
++ snps,tx-max-burst = /bits/ 8 <8>;
++ snps,tx-thr-num-pkt = /bits/ 8 <2>;
++ interrupts = <RP1_INT_USBHOST1_0 IRQ_TYPE_EDGE_RISING>;
++ status = "disabled";
++ };
++
++ rp1_dsi0: dsi@110000 {
++ compatible = "raspberrypi,rp1dsi";
++ status = "disabled";
++ reg = <0xc0 0x40118000 0x0 0x1000>, // MIPI0 DSI DMA (ArgonDPI)
++ <0xc0 0x4011c000 0x0 0x1000>, // MIPI0 DSI Host (SNPS)
++ <0xc0 0x40120000 0x0 0x1000>; // MIPI0 CFG
++
++ interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI0_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI0_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
++
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
++ assigned-clock-rates = <25000000>;
++ };
++
++ rp1_dsi1: dsi@128000 {
++ compatible = "raspberrypi,rp1dsi";
++ status = "disabled";
++ reg = <0xc0 0x40130000 0x0 0x1000>, // MIPI1 DSI DMA (ArgonDPI)
++ <0xc0 0x40134000 0x0 0x1000>, // MIPI1 DSI Host (SNPS)
++ <0xc0 0x40138000 0x0 0x1000>; // MIPI1 CFG
++
++ interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI1_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI1_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
++
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
++ assigned-clock-rates = <25000000>;
++ };
++
++ /* VEC and DPI both need to control PLL_VIDEO and cannot work together; */
++ /* config.txt should enable one or other using dtparam=vec or an overlay. */
++ rp1_vec: vec@144000 {
++ compatible = "raspberrypi,rp1vec";
++ status = "disabled";
++ reg = <0xc0 0x40144000 0x0 0x1000>, // VIDEO_OUT_VEC
++ <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
++
++ interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_VEC>;
++
++ assigned-clocks = <&rp1_clocks RP1_PLL_VIDEO_CORE>,
++ <&rp1_clocks RP1_PLL_VIDEO_SEC>,
++ <&rp1_clocks RP1_CLK_VEC>;
++ assigned-clock-rates = <1188000000>,
++ <108000000>,
++ <108000000>;
++ assigned-clock-parents = <0>,
++ <&rp1_clocks RP1_PLL_VIDEO_CORE>,
++ <&rp1_clocks RP1_PLL_VIDEO_SEC>;
++ };
++
++ rp1_dpi: dpi@148000 {
++ compatible = "raspberrypi,rp1dpi";
++ status = "disabled";
++ reg = <0xc0 0x40148000 0x0 0x1000>, // VIDEO_OUT DPI
++ <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
++
++ interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_DPI>, // DPI pixel clock
++ <&rp1_clocks RP1_PLL_VIDEO>, // PLL primary divider, and
++ <&rp1_clocks RP1_PLL_VIDEO_CORE>; // VCO, which we also control
++ clock-names = "dpiclk", "plldiv", "pllcore";
++
++ assigned-clocks = <&rp1_clocks RP1_CLK_DPI>;
++ assigned-clock-parents = <&rp1_clocks RP1_PLL_VIDEO>;
++ };
++ };
++};
++
++&clocks {
++ clk_xosc: clk_xosc {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "xosc";
++ clock-frequency = <50000000>;
++ };
++ macb_pclk: macb_pclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "pclk";
++ clock-frequency = <200000000>;
++ };
++ macb_hclk: macb_hclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "hclk";
++ clock-frequency = <200000000>;
++ };
++ sdio_src: sdio_src {
++ // 400 MHz on FPGA. PLL sys VCO on asic
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "src";
++ clock-frequency = <1000000000>;
++ };
++ sdhci_core: sdhci_core {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "core";
++ clock-frequency = <50000000>;
++ };
++ /* GPIO derived clock sources. Each GPIO with a GPCLK function
++ * can drive its output from the respective GPCLK
++ * generator, and provide a clock source to other internal
++ * dividers. Add dummy sources here so that they can be overridden
++ * with overlays.
++ */
++ clksrc_gp0: clksrc_gp0 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP0>;
++ clock-output-names = "clksrc_gp0";
++ };
++ clksrc_gp1: clksrc_gp1 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP1>;
++ clock-output-names = "clksrc_gp1";
++ };
++ clksrc_gp2: clksrc_gp2 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ clock-div = <1>;
++ clock-mult = <1>;
++ #clock-cells = <0>;
++ clocks = <&rp1_clocks RP1_CLK_GP2>;
++ clock-output-names = "clksrc_gp2";
++ };
++ clksrc_gp3: clksrc_gp3 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ clock-div = <1>;
++ clock-mult = <1>;
++ #clock-cells = <0>;
++ clocks = <&rp1_clocks RP1_CLK_GP3>;
++ clock-output-names = "clksrc_gp3";
++ };
++ clksrc_gp4: clksrc_gp4 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP4>;
++ clock-output-names = "clksrc_gp4";
++ };
++ clksrc_gp5: clksrc_gp5 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP5>;
++ clock-output-names = "clksrc_gp5";
++ };
++};
++
++/ {
++ rp1_vdd_3v3: rp1_vdd_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "vdd-3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ };
++};
diff --git a/target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch b/target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch
new file mode 100644
index 0000000000..4f0544386a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch
@@ -0,0 +1,92 @@
+From 4de4f56af7d803fa7dd9ffe42d4719b428d73e6c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 17 Jul 2024 17:31:58 +0100
+Subject: [PATCH 1181/1215] arm64: dts: Add cm5l files
+
+CM5 Lite DTBs require minor changes compared to the "heavy" variants.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/Makefile | 2 ++
+ .../dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts | 20 ++++++++++++++++
+ .../dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts | 10 ++++++++
+ .../boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi | 24 +++++++++++++++++++
+ 4 files changed, 56 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
+
+--- a/arch/arm64/boot/dts/broadcom/Makefile
++++ b/arch/arm64/boot/dts/broadcom/Makefile
+@@ -24,6 +24,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rp
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2712d0-rpi-5-b.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5-cm5io.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5-cm4io.dtb
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5l-cm5io.dtb
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5l-cm4io.dtb
+
+ subdir-y += bcmbca
+ subdir-y += northstar2
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts
+@@ -0,0 +1,20 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5l.dtsi"
++
++// The RP1 USB3 interfaces are not usable on CM4IO
++
++&rp1_usb0 {
++ status = "disabled";
++};
++
++&rp1_usb1 {
++ status = "disabled";
++};
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts
+@@ -0,0 +1,10 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5l.dtsi"
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
+@@ -0,0 +1,24 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5.dtsi"
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
++
++&sd_io_1v8_reg {
++ compatible = "regulator-gpio";
++ regulator-max-microvolt = <3300000>;
++ regulator-settling-time-us = <5000>;
++ gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
++ states = <1800000 0x1
++ 3300000 0x0>;
++};
++
++&sdio1 {
++ /delete-property/ mmc-hs400-1_8v;
++ /delete-property/ mmc-hs400-enhanced-strobe;
++};
diff --git a/target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch b/target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch
new file mode 100644
index 0000000000..6cffbdd9be
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch
@@ -0,0 +1,408 @@
+From e1c56acf3355cd539447511fdc1b886e5eb5cca3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 16:57:31 +0100
+Subject: [PATCH 1182/1215] dts: bcm2712: Dedup the aliases and overrides
+
+Move the aliases and overrrides shared by Pi 5 and CM5 into
+bcm2712-rpi.dtsi.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 115 -----------------
+ .../boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 114 -----------------
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 117 +++++++++++++++++-
+ 3 files changed, 113 insertions(+), 233 deletions(-)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+@@ -746,122 +746,7 @@ spi10_cs_pins: &spi10_cs_gpio1 {};
+ };
+
+ / {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+ __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+ sd_cqe = <&sdio1>, "supports-cqe?";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
+- act_led_activelow = <&led_act>,"gpios:8";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_gpio = <&led_pwr>,"gpios:4";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+ };
+ };
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
+@@ -753,108 +753,7 @@ spi10_cs_pins: &spi10_cs_gpio1 {};
+ };
+
+ / {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+ __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_activelow = <&led_act>, "active-low?";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+ ant1 = <&ant1>,"output-high?=on",
+ <&ant1>, "output-low?=off",
+ <&ant2>, "output-high?=off",
+@@ -867,18 +766,5 @@ spi10_cs_pins: &spi10_cs_gpio1 {};
+ <&ant1>, "output-low?=on",
+ <&ant2>, "output-high?=off",
+ <&ant2>, "output-low?=on";
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+ };
+ };
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -98,14 +98,124 @@
+ };
+
+ / {
++ aliases: aliases {
++ blconfig = &blconfig;
++ blpubkey = &blpubkey;
++ bluetooth = &bluetooth;
++ console = &uart10;
++ drm-dsi1 = &dsi0;
++ drm-dsi2 = &dsi1;
++ ethernet0 = &rp1_eth;
++ fb = &fb;
++ gpio0 = &gpio;
++ gpio1 = &gio;
++ gpio2 = &gio_aon;
++ gpio3 = &pinctrl;
++ gpio4 = &pinctrl_aon;
++ i2c = &i2c_arm;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c10 = &i2c_rp1boot;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ mailbox = &mailbox;
++ mmc0 = &sdio1;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial10 = &uart10;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi10 = &spi10;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ spi5 = &spi5;
++ uart0 = &uart0;
++ uart1 = &uart1;
++ uart10 = &uart10;
++ uart2 = &uart2;
++ uart3 = &uart3;
++ uart4 = &uart4;
++ usb0 = &rp1_usb0;
++ usb1 = &rp1_usb1;
++ wifi0 = &wifi;
++ };
++
+ __overrides__ {
+- arm_freq;
++ act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
++ act_led_activelow = <&led_act>, "gpios:8";
++ act_led_trigger = <&led_act>, "linux,default-trigger";
+ axiperf = <&axiperf>,"status";
+-
++ bdaddr = <&bluetooth>, "local-bd-address[";
++ button_debounce = <&pwr_key>, "debounce-interval:0";
++ cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
++ drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
++ drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
++ drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
++ drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
++ drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
++ drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
++ drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
++ drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
++ drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
++ drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
++ drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
++ drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++ fan_temp0 = <&cpu_tepid>,"temperature:0";
++ fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
++ fan_temp0_speed = <&fan>, "cooling-levels:4";
++ fan_temp1 = <&cpu_warm>,"temperature:0";
++ fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
++ fan_temp1_speed = <&fan>, "cooling-levels:8";
++ fan_temp2 = <&cpu_hot>,"temperature:0";
++ fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
++ fan_temp2_speed = <&fan>, "cooling-levels:12";
++ fan_temp3 = <&cpu_vhot>,"temperature:0";
++ fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
++ fan_temp3_speed = <&fan>, "cooling-levels:16";
++ i2c = <&i2c1>, "status";
++ i2c_arm = <&i2c_arm>, "status";
++ i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
++ i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
++ i2c_vc = <&i2c_vc>, "status";
++ i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
++ i2c0 = <&i2c0>, "status";
++ i2c0_baudrate = <&i2c0>, "clock-frequency:0";
++ i2c1 = <&i2c1>, "status";
++ i2c1_baudrate = <&i2c1>, "clock-frequency:0";
++ krnbt = <&bluetooth>, "status";
++ nvme = <&pciex1>, "status";
+ nvmem_cust_rw = <&nvmem_cust>,"rw?";
+- nvmem_priv_rw = <&nvmem_priv>,"rw?";
+ nvmem_mac_rw = <&nvmem_mac>,"rw?";
++ nvmem_priv_rw = <&nvmem_priv>,"rw?";
++ pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pciex1 = <&pciex1>, "status";
++ pciex1_gen = <&pciex1> , "max-link-speed:0";
++ pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
++ pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pwr_led_gpio = <&led_pwr>, "gpios:4";
++ pwr_led_activelow = <&led_pwr>, "gpios:8";
++ pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
++ random = <&random>, "status";
++ rtc = <&rpi_rtc>, "status";
++ rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
++ spi = <&spi0>, "status";
+ strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
++ suspend = <&pwr_key>, "linux,code:0=205";
++ uart0 = <&uart0>, "status";
++ uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
++ wifiaddr = <&wifi>, "local-mac-address[";
+
+ cam0_reg = <&cam0_reg>,"status";
+ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
+@@ -113,7 +223,6 @@
+ cam1_reg = <&cam1_reg>,"status";
+ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
+ <&cam1_reg>,"gpio:0=", <&gpio>;
+-
+ };
+ };
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch b/target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch
new file mode 100644
index 0000000000..72279e130c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch
@@ -0,0 +1,24 @@
+From ad110e5ff36de6096e1b9d7e0fe125326f45ed7d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 19 Jul 2024 13:18:47 +0100
+Subject: [PATCH 1183/1215] arm64: dts: Give cm5l its own model name
+
+The bootloader patches the DT with the correct model string, but it
+is better not to rely on that by setting it from the start.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
+@@ -4,6 +4,8 @@
+ #include "bcm2712-rpi-cm5.dtsi"
+
+ / {
++ model = "Raspberry Pi Compute Module 5 Lite";
++
+ __overrides__ {
+ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+ };
diff --git a/target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch b/target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch
new file mode 100644
index 0000000000..fecfb7a200
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch
@@ -0,0 +1,288 @@
+From d24229dcef58e0162780ceffa02eb5f6a01b9a4d Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Tue, 16 Jul 2024 16:47:08 +0100
+Subject: [PATCH 1185/1215] pinctrl: rp1: jump through hoops to avoid PCIe
+ latency issues
+
+Automatic link power saving plus the ability of a root complex to buffer
+pending posted write transfers (and consider them complete before being
+transmitted on the wire) causes compression of updates to GPIO state.
+
+The large bandwidth of a Gen 2 x4 link means the writes toggle state
+inside RP1 as fast as it can go (~20MHz), which is bad for applications
+wanting bitbash with at least a few microseconds of delay between
+updates.
+
+By tailoring IO access patterns to a special Root Complex register,
+writes to GPIOs can be stalled until the link wakes - meaning all writes
+end up with a reasonably consistent minimum pacing (~200ns).
+
+Additionally, write barriers have no effect other than to arbitrarily
+delay some writes by a small, variable amount - so remove the vast
+majority of these in areas that could be hot-paths.
+
+Although the IO memory is mapped with Device strongly-ordered semantics,
+this doesn't prevent the splitter inside BCM2712 from letting an MMIO
+read request to a GPIO register get ahead of the pacing writes to the
+Root Complex register. So each pin state read must flush writes out to
+the Outer-Shareable domain.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/pinctrl/pinctrl-rp1.c | 120 +++++++++++++++++++++++++++++-----
+ 1 file changed, 105 insertions(+), 15 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-rp1.c
++++ b/drivers/pinctrl/pinctrl-rp1.c
+@@ -197,6 +197,7 @@ struct rp1_pin_info {
+ void __iomem *inte;
+ void __iomem *ints;
+ void __iomem *pad;
++ void __iomem *dummy;
+ };
+
+ enum funcs {
+@@ -276,6 +277,7 @@ struct rp1_pinctrl {
+ void __iomem *gpio_base;
+ void __iomem *rio_base;
+ void __iomem *pads_base;
++ void __iomem *dummy_base;
+ int irq[RP1_NUM_BANKS];
+ struct rp1_pin_info pins[RP1_NUM_GPIOS];
+
+@@ -577,6 +579,42 @@ static bool persist_gpio_outputs = true;
+ module_param(persist_gpio_outputs, bool, 0644);
+ MODULE_PARM_DESC(persist_gpio_outputs, "Enable GPIO_OUT persistence when pin is freed");
+
++static bool pace_pin_updates = true;
++module_param(pace_pin_updates, bool, 0644);
++MODULE_PARM_DESC(pace_pin_updates, "Update pin states with guaranteed monotonicity if PCIe ASPM is enabled");
++
++static inline void rp1_pin_writel(u32 val, void __iomem *dummy, void __iomem *reg)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ /*
++ * Issuing 6 pipelined writes to the RC's Slot Control register will stall the
++ * peripheral bus inside 2712 if the link is in L1. This acts as a lightweight
++ * "fence" operation preventing back-to-back writes arriving at RP1 on a wake.
++ */
++ if (dummy) {
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ }
++ writel_relaxed(val, reg);
++ local_irq_restore(flags);
++}
++
++static inline u32 rp1_pin_readl(const void __iomem *ioaddr)
++{
++ /*
++ * Prior posted writes may not yet have been emitted by the CPU - do a store-flush
++ * before reading GPIO state, as this will serialise writes versus the next issued read.
++ */
++ __dma_wmb();
++ return readl(ioaddr);
++}
++
+ static int rp1_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int offset, unsigned long *configs,
+ unsigned int num_configs);
+@@ -603,12 +641,12 @@ static struct rp1_pin_info *rp1_get_pin_
+
+ static void rp1_pad_update(struct rp1_pin_info *pin, u32 clr, u32 set)
+ {
+- u32 padctrl = readl(pin->pad);
++ u32 padctrl = rp1_pin_readl(pin->pad);
+
+ padctrl &= ~clr;
+ padctrl |= set;
+
+- writel(padctrl, pin->pad);
++ rp1_pin_writel(padctrl, pin->dummy, pin->pad);
+ }
+
+ static void rp1_input_enable(struct rp1_pin_info *pin, int value)
+@@ -625,7 +663,7 @@ static void rp1_output_enable(struct rp1
+
+ static u32 rp1_get_fsel(struct rp1_pin_info *pin)
+ {
+- u32 ctrl = readl(pin->gpio + RP1_GPIO_CTRL);
++ u32 ctrl = rp1_pin_readl(pin->gpio + RP1_GPIO_CTRL);
+ u32 oeover = FLD_GET(ctrl, RP1_GPIO_CTRL_OEOVER);
+ u32 fsel = FLD_GET(ctrl, RP1_GPIO_CTRL_FUNCSEL);
+
+@@ -637,7 +675,7 @@ static u32 rp1_get_fsel(struct rp1_pin_i
+
+ static void rp1_set_fsel(struct rp1_pin_info *pin, u32 fsel)
+ {
+- u32 ctrl = readl(pin->gpio + RP1_GPIO_CTRL);
++ u32 ctrl = rp1_pin_readl(pin->gpio + RP1_GPIO_CTRL);
+
+ if (fsel >= RP1_FSEL_COUNT)
+ fsel = RP1_FSEL_NONE_HW;
+@@ -652,12 +690,12 @@ static void rp1_set_fsel(struct rp1_pin_
+ FLD_SET(ctrl, RP1_GPIO_CTRL_OEOVER, RP1_OEOVER_PERI);
+ }
+ FLD_SET(ctrl, RP1_GPIO_CTRL_FUNCSEL, fsel);
+- writel(ctrl, pin->gpio + RP1_GPIO_CTRL);
++ rp1_pin_writel(ctrl, pin->dummy, pin->gpio + RP1_GPIO_CTRL);
+ }
+
+ static int rp1_get_dir(struct rp1_pin_info *pin)
+ {
+- return !(readl(pin->rio + RP1_RIO_OE) & (1 << pin->offset)) ?
++ return !(rp1_pin_readl(pin->rio + RP1_RIO_OE) & (1 << pin->offset)) ?
+ RP1_DIR_INPUT : RP1_DIR_OUTPUT;
+ }
+
+@@ -665,19 +703,19 @@ static void rp1_set_dir(struct rp1_pin_i
+ {
+ int offset = is_input ? RP1_CLR_OFFSET : RP1_SET_OFFSET;
+
+- writel(1 << pin->offset, pin->rio + RP1_RIO_OE + offset);
++ rp1_pin_writel(1 << pin->offset, pin->dummy, pin->rio + RP1_RIO_OE + offset);
+ }
+
+ static int rp1_get_value(struct rp1_pin_info *pin)
+ {
+- return !!(readl(pin->rio + RP1_RIO_IN) & (1 << pin->offset));
++ return !!(rp1_pin_readl(pin->rio + RP1_RIO_IN) & (1 << pin->offset));
+ }
+
+ static void rp1_set_value(struct rp1_pin_info *pin, int value)
+ {
+ /* Assume the pin is already an output */
+- writel(1 << pin->offset,
+- pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
++ rp1_pin_writel(1 << pin->offset, pin->dummy,
++ pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
+ }
+
+ static int rp1_gpio_get(struct gpio_chip *chip, unsigned offset)
+@@ -1298,7 +1336,7 @@ static const struct pinmux_ops rp1_pmx_o
+
+ static void rp1_pull_config_set(struct rp1_pin_info *pin, unsigned int arg)
+ {
+- u32 padctrl = readl(pin->pad);
++ u32 padctrl = rp1_pin_readl(pin->pad);
+
+ FLD_SET(padctrl, RP1_PAD_PULL, arg & 0x3);
+
+@@ -1398,7 +1436,7 @@ static int rp1_pinconf_get(struct pinctr
+ if (!pin)
+ return -EINVAL;
+
+- padctrl = readl(pin->pad);
++ padctrl = rp1_pin_readl(pin->pad);
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_ENABLE:
+@@ -1493,6 +1531,7 @@ static int rp1_pinctrl_probe(struct plat
+ {
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
++ struct device_node *rp1_node = NULL;
+ struct rp1_pinctrl *pc;
+ struct gpio_irq_chip *girq;
+ int err, i;
+@@ -1528,6 +1567,40 @@ static int rp1_pinctrl_probe(struct plat
+ pc->gpio_chip = rp1_gpio_chip;
+ pc->gpio_chip.parent = dev;
+
++ /*
++ * Workaround for the vagaries of PCIe on BCM2712
++ *
++ * If the link to RP1 is in L1, then the BRCMSTB RC will buffer many
++ * outbound writes - and generate write responses for them, despite the
++ * fact that the link is not yet active. This has the effect of compressing
++ * multiple writes to GPIOs together, destroying any pacing that an application
++ * may require in the 1-10us range.
++ *
++ * The RC Slot Control configuration register is special. It emits a
++ * MsgD for every write to it, will stall further writes until the message
++ * goes out on the wire. This can be (ab)used to force CPU stalls when the
++ * link is inactive, at the cost of a small amount of downstream bandwidth
++ * and some 200ns of added latency for each write.
++ *
++ * Several back-to-back configuration writes are necessary to "fill the pipe",
++ * otherwise the outbound MAC can consume a pending MMIO write and reorder
++ * it with respect to the config writes - undoing the intent.
++ *
++ * of_iomap() is used directly here as the address overlaps with the RC driver's
++ * usage.
++ */
++ rp1_node = of_find_node_by_name(NULL, "rp1");
++ if (!rp1_node)
++ dev_err(&pdev->dev, "failed to find RP1 DT node\n");
++ else if (pace_pin_updates &&
++ of_device_is_compatible(rp1_node->parent, "brcm,bcm2712-pcie")) {
++ pc->dummy_base = of_iomap(rp1_node->parent, 0);
++ if (IS_ERR(pc->dummy_base)) {
++ dev_warn(&pdev->dev, "could not map bcm2712 root complex registers\n");
++ pc->dummy_base = NULL;
++ }
++ }
++
+ for (i = 0; i < RP1_NUM_BANKS; i++) {
+ const struct rp1_iobank_desc *bank = &rp1_iobanks[i];
+ int j;
+@@ -1547,14 +1620,17 @@ static int rp1_pinctrl_probe(struct plat
+ pin->rio = pc->rio_base + bank->rio_offset;
+ pin->pad = pc->pads_base + bank->pads_offset +
+ j * sizeof(u32);
++ pin->dummy = pc->dummy_base ? pc->dummy_base + 0xc0 : NULL;
+ }
+
+ raw_spin_lock_init(&pc->irq_lock[i]);
+ }
+
+ pc->pctl_dev = devm_pinctrl_register(dev, &rp1_pinctrl_desc, pc);
+- if (IS_ERR(pc->pctl_dev))
+- return PTR_ERR(pc->pctl_dev);
++ if (IS_ERR(pc->pctl_dev)) {
++ err = PTR_ERR(pc->pctl_dev);
++ goto out_iounmap;
++ }
+
+ girq = &pc->gpio_chip.irq;
+ girq->chip = &rp1_gpio_irq_chip;
+@@ -1583,7 +1659,7 @@ static int rp1_pinctrl_probe(struct plat
+ err = devm_gpiochip_add_data(dev, &pc->gpio_chip, pc);
+ if (err) {
+ dev_err(dev, "could not add GPIO chip\n");
+- return err;
++ goto out_iounmap;
+ }
+
+ pc->gpio_range = rp1_pinctrl_gpio_range;
+@@ -1592,10 +1668,24 @@ static int rp1_pinctrl_probe(struct plat
+ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
+
+ return 0;
++
++out_iounmap:
++ if (pc->dummy_base)
++ iounmap(pc->dummy_base);
++ return err;
++}
++
++static void rp1_pinctrl_remove(struct platform_device *pdev)
++{
++ struct rp1_pinctrl *pc = platform_get_drvdata(pdev);
++
++ if (pc->dummy_base)
++ iounmap(pc->dummy_base);
+ }
+
+ static struct platform_driver rp1_pinctrl_driver = {
+ .probe = rp1_pinctrl_probe,
++ .remove_new = rp1_pinctrl_remove,
+ .driver = {
+ .name = MODULE_NAME,
+ .of_match_table = rp1_pinctrl_match,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch b/target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch
new file mode 100644
index 0000000000..a8fbeaf062
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch
@@ -0,0 +1,36 @@
+From 43fa967811484afde0bbbee182ff8f29dc0550c2 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 5 Jul 2024 15:57:25 +0100
+Subject: [PATCH 1186/1215] staging: bcm2835-codec: Disable HEADER_ON_OPEN for
+ video encode
+
+Video encode can defer generating the header until the first
+frame is presented, which allows it to take the colourspace
+information from the frame rather than just the format.
+
+Enable that for the V4L2 driver now that the firmware populates
+all the parameters.
+
+https://github.com/raspberrypi/firmware/issues/1885
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -2731,6 +2731,13 @@ static int bcm2835_codec_create_componen
+ &params,
+ sizeof(params));
+
++ } else if (dev->role == ENCODE) {
++ enable = 0;
++ vchiq_mmal_port_parameter_set(dev->instance,
++ &ctx->component->control,
++ MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN,
++ &enable,
++ sizeof(enable));
+ } else if (dev->role == ENCODE_IMAGE) {
+ enable = 0;
+ vchiq_mmal_port_parameter_set(dev->instance,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch b/target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch
new file mode 100644
index 0000000000..f3c53adf50
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch
@@ -0,0 +1,36 @@
+From 31b9871b8895d7931ee88d7cda7861f829b21d63 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 17 Jul 2024 16:59:08 +0100
+Subject: [PATCH 1188/1215] staging: bcm2835-codec: Add support for H264 level
+ 5.0 and 5.1
+
+We do NOT claim to support decoding in real-time for these levels,
+but can transcode some content, and handle 1920x1200.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -3273,7 +3273,7 @@ static void dec_add_profile_ctrls(struct
+ case V4L2_PIX_FMT_H264:
+ ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+- V4L2_MPEG_VIDEO_H264_LEVEL_4_2,
++ V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+ ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+@@ -3287,7 +3287,9 @@ static void dec_add_profile_ctrls(struct
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2)),
++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1)),
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch b/target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch
new file mode 100644
index 0000000000..66ff22eb7f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch
@@ -0,0 +1,66 @@
+From 6014649de765a8a1f95c146ca72214ff0ba4ba89 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 1 Jul 2024 15:49:14 +0100
+Subject: [PATCH 1189/1215] spi: dw: Save bandwidth with the TMOD_TO feature
+
+TMOD_TO is the transmit-only mode that doesn't put data into the receive
+FIFO. Using TMOD_TO when the user doesn't want the received data saves
+CPU time and memory bandwidth.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -225,12 +225,17 @@ static irqreturn_t dw_spi_transfer_handl
+ * final stage of the transfer. By doing so we'll get the next IRQ
+ * right when the leftover incoming data is received.
+ */
+- dw_reader(dws);
+- if (!dws->rx_len) {
+- dw_spi_mask_intr(dws, 0xff);
++ if (dws->rx_len) {
++ dw_reader(dws);
++ if (!dws->rx_len) {
++ dw_spi_mask_intr(dws, 0xff);
++ spi_finalize_current_transfer(dws->host);
++ } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
++ dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
++ }
++ } else if (!dws->tx_len) {
++ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+ spi_finalize_current_transfer(dws->host);
+- } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
+- dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
+ }
+
+ /*
+@@ -239,12 +244,9 @@ static irqreturn_t dw_spi_transfer_handl
+ * have the TXE IRQ flood at the final stage of the transfer.
+ */
+ if (irq_status & DW_SPI_INT_TXEI) {
+- dw_writer(dws);
+- if (!dws->tx_len) {
++ if (!dws->tx_len)
+ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+- if (!dws->rx_len)
+- spi_finalize_current_transfer(dws->host);
+- }
++ dw_writer(dws);
+ }
+
+ return IRQ_HANDLED;
+@@ -437,6 +439,11 @@ static int dw_spi_transfer_one(struct sp
+ dws->rx = transfer->rx_buf;
+ dws->rx_len = dws->tx_len;
+
++ if (!dws->rx) {
++ dws->rx_len = 0;
++ cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
++ }
++
+ /* Ensure the data above is visible for all CPUs */
+ smp_mb();
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch b/target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch
new file mode 100644
index 0000000000..7791b99b6d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch
@@ -0,0 +1,186 @@
+From cd9084ceb606a2f06c3429c2d3beae2d7c3ebd23 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 1 Jul 2024 16:41:04 +0100
+Subject: [PATCH 1190/1215] spi: dw: Save bandwidth with the TMOD_RO feature
+
+TMOD_RO is the receive-only mode that doesn't require data in the
+transmit FIFO in order to generate clock cycles. Using TMOD_RO when the
+device doesn't care about the data sent to it saves CPU time and memory
+bandwidth.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 31 +++++++++++++++++++++-------
+ drivers/spi/spi-dw-dma.c | 43 +++++++++++++++++++++++++--------------
+ 2 files changed, 52 insertions(+), 22 deletions(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -367,18 +367,18 @@ static void dw_spi_irq_setup(struct dw_s
+ * will be adjusted at the final stage of the IRQ-based SPI transfer
+ * execution so not to lose the leftover of the incoming data.
+ */
+- level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len);
++ level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len ? dws->tx_len : dws->rx_len);
+ dw_writel(dws, DW_SPI_TXFTLR, level);
+ dw_writel(dws, DW_SPI_RXFTLR, level - 1);
+
+ dws->transfer_handler = dw_spi_transfer_handler;
+
+- imask = 0;
+- if (dws->tx_len)
+- imask |= DW_SPI_INT_TXEI | DW_SPI_INT_TXOI;
++ imask = DW_SPI_INT_TXEI | DW_SPI_INT_TXOI;
+ if (dws->rx_len)
+ imask |= DW_SPI_INT_RXUI | DW_SPI_INT_RXOI | DW_SPI_INT_RXFI;
+ dw_spi_umask_intr(dws, imask);
++ if (!dws->tx_len)
++ dw_writel(dws, DW_SPI_DR, 0);
+ }
+
+ /*
+@@ -401,13 +401,18 @@ static int dw_spi_poll_transfer(struct d
+ delay.unit = SPI_DELAY_UNIT_SCK;
+ nbits = dws->n_bytes * BITS_PER_BYTE;
+
++ if (!dws->tx_len)
++ dw_writel(dws, DW_SPI_DR, 0);
++
+ do {
+- dw_writer(dws);
++ if (dws->tx_len)
++ dw_writer(dws);
+
+ delay.value = nbits * (dws->rx_len - dws->tx_len);
+ spi_delay_exec(&delay, transfer);
+
+- dw_reader(dws);
++ if (dws->rx_len)
++ dw_reader(dws);
+
+ ret = dw_spi_check_status(dws, true);
+ if (ret)
+@@ -427,6 +432,7 @@ static int dw_spi_transfer_one(struct sp
+ .dfs = transfer->bits_per_word,
+ .freq = transfer->speed_hz,
+ };
++ int buswidth;
+ int ret;
+
+ dws->dma_mapped = 0;
+@@ -444,6 +450,18 @@ static int dw_spi_transfer_one(struct sp
+ cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
+ }
+
++ if (!dws->rx) {
++ dws->rx_len = 0;
++ cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
++ }
++ if (!dws->tx) {
++ dws->tx_len = 0;
++ cfg.tmode = DW_SPI_CTRLR0_TMOD_RO;
++ cfg.ndf = dws->rx_len;
++ }
++ buswidth = transfer->rx_buf ? transfer->rx_nbits :
++ (transfer->tx_buf ? transfer->tx_nbits : 1);
++
+ /* Ensure the data above is visible for all CPUs */
+ smp_mb();
+
+@@ -961,7 +979,6 @@ int dw_spi_add_host(struct device *dev,
+ dev_warn(dev, "DMA init failed\n");
+ } else {
+ host->can_dma = dws->dma_ops->can_dma;
+- host->flags |= SPI_CONTROLLER_MUST_TX;
+ }
+ }
+
+--- a/drivers/spi/spi-dw-dma.c
++++ b/drivers/spi/spi-dw-dma.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/completion.h>
++#include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dmaengine.h>
+ #include <linux/irqreturn.h>
+@@ -470,13 +471,12 @@ static int dw_spi_dma_setup(struct dw_sp
+ u16 imr, dma_ctrl;
+ int ret;
+
+- if (!xfer->tx_buf)
+- return -EINVAL;
+-
+ /* Setup DMA channels */
+- ret = dw_spi_dma_config_tx(dws);
+- if (ret)
+- return ret;
++ if (xfer->tx_buf) {
++ ret = dw_spi_dma_config_tx(dws);
++ if (ret)
++ return ret;
++ }
+
+ if (xfer->rx_buf) {
+ ret = dw_spi_dma_config_rx(dws);
+@@ -485,13 +485,17 @@ static int dw_spi_dma_setup(struct dw_sp
+ }
+
+ /* Set the DMA handshaking interface */
+- dma_ctrl = DW_SPI_DMACR_TDMAE;
++ dma_ctrl = 0;
++ if (xfer->tx_buf)
++ dma_ctrl |= DW_SPI_DMACR_TDMAE;
+ if (xfer->rx_buf)
+ dma_ctrl |= DW_SPI_DMACR_RDMAE;
+ dw_writel(dws, DW_SPI_DMACR, dma_ctrl);
+
+ /* Set the interrupt mask */
+- imr = DW_SPI_INT_TXOI;
++ imr = 0;
++ if (xfer->tx_buf)
++ imr |= DW_SPI_INT_TXOI;
+ if (xfer->rx_buf)
+ imr |= DW_SPI_INT_RXUI | DW_SPI_INT_RXOI;
+ dw_spi_umask_intr(dws, imr);
+@@ -508,15 +512,16 @@ static int dw_spi_dma_transfer_all(struc
+ {
+ int ret;
+
+- /* Submit the DMA Tx transfer */
+- ret = dw_spi_dma_submit_tx(dws, xfer->tx_sg.sgl, xfer->tx_sg.nents);
+- if (ret)
+- goto err_clear_dmac;
++ /* Submit the DMA Tx transfer if required */
++ if (xfer->tx_buf) {
++ ret = dw_spi_dma_submit_tx(dws, xfer->tx_sg.sgl, xfer->tx_sg.nents);
++ if (ret)
++ goto err_clear_dmac;
++ }
+
+ /* Submit the DMA Rx transfer if required */
+ if (xfer->rx_buf) {
+- ret = dw_spi_dma_submit_rx(dws, xfer->rx_sg.sgl,
+- xfer->rx_sg.nents);
++ ret = dw_spi_dma_submit_rx(dws, xfer->rx_sg.sgl, xfer->rx_sg.nents);
+ if (ret)
+ goto err_clear_dmac;
+
+@@ -524,7 +529,15 @@ static int dw_spi_dma_transfer_all(struc
+ dma_async_issue_pending(dws->rxchan);
+ }
+
+- dma_async_issue_pending(dws->txchan);
++ if (xfer->tx_buf) {
++ dma_async_issue_pending(dws->txchan);
++ } else {
++ /* Pause to allow DMA channel to fetch RX descriptor */
++ usleep_range(5, 10);
++
++ /* Write something to the TX FIFO to start the transfer */
++ dw_writel(dws, DW_SPI_DR, 0);
++ }
+
+ ret = dw_spi_dma_wait(dws, xfer->len, xfer->effective_speed_hz);
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch b/target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch
new file mode 100644
index 0000000000..45400204c4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch
@@ -0,0 +1,41 @@
+From 3af7822df36e36b5a74d877df7654695c0e0d34a Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 22 Jul 2024 15:27:51 +0100
+Subject: [PATCH 1191/1215] spi: dw: don't immediately kill DMA transfers if an
+ error occurs
+
+Disabling the peripheral resets controller state which has a dangerous
+side-effect of disabling the DMA handshake interface while it is active.
+This can cause DMA channels to hang.
+
+The error recovery pathway will wait for DMA to stop and reset the chip
+anyway, so mask further FIFO interrupts and let the transfer finish
+gracefully.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -200,7 +200,18 @@ int dw_spi_check_status(struct dw_spi *d
+
+ /* Generically handle the erroneous situation */
+ if (ret) {
+- dw_spi_reset_chip(dws);
++ /*
++ * Forcibly halting the controller can cause DMA to hang.
++ * Defer to dw_spi_handle_err outside of interrupt context
++ * and mask further interrupts for the current transfer.
++ */
++ if (dws->dma_mapped) {
++ dw_spi_mask_intr(dws, 0xff);
++ dw_readl(dws, DW_SPI_ICR);
++ } else {
++ dw_spi_reset_chip(dws);
++ }
++
+ if (dws->host->cur_msg)
+ dws->host->cur_msg->status = ret;
+ }
diff --git a/target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch b/target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch
new file mode 100644
index 0000000000..9cfdefec7d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch
@@ -0,0 +1,35 @@
+From 4c1a665b465fa0e9d3369a467fc563ec812a47ce Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Fri, 19 Jul 2024 13:07:59 +0100
+Subject: [PATCH 1192/1215] dts: rp1: hobble DMA AXI burst lengths
+
+Channels 1-2 have a statically configured maximum MSIZE of 8, and
+channels 3-8 have MSIZE set to 4. The DMAC "helpfully" silently
+truncates bursts to the hardware supported maximum, so any FIFO read
+operation with an oversized burst threshold will leave a residue of
+threshold minus MSIZE rows.
+
+As channel allocation is dynamic, this means every client needs to use a
+maximum of 4 for burst length.
+
+AXI AWLEN/ARLEN constraints aren't strictly related to MSIZE, except
+that bursts won't be issued that are longer than MSIZE beats. Therefore,
+it's a useful proxy to tell clients of the DMAC the hardware
+limitations.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/rp1.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
++++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
+@@ -1064,7 +1064,7 @@
+ snps,data-width = <4>; // (8 << 4) == 128 bits
+ snps,block-size = <0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000>;
+ snps,priority = <0 1 2 3 4 5 6 7>;
+- snps,axi-max-burst-len = <8>;
++ snps,axi-max-burst-len = <4>;
+ status = "disabled";
+ };
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch b/target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch
new file mode 100644
index 0000000000..d336532f46
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch
@@ -0,0 +1,124 @@
+From ce56098eb4dc2985f27f30ad7b7f5aed6bcf7fb1 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Fri, 19 Jul 2024 15:55:56 +0100
+Subject: [PATCH 1193/1215] drivers: dw-axi-dmac: make more sensible choices
+ about memory accesses
+
+There's no real need to constrain MEM access widths to 32-bit (or
+narrower), as the DMAC is intelligent enough to size memory accesses
+appropriately. Wider accesses are more efficient.
+
+Similarly, MEM burst lengths don't need to be a function of DEV burst
+lengths - the DMAC packs/unpacks data into/from its internal channel
+FIFOs appropriately. Longer accesses are more efficient.
+
+However, the DMAC doesn't have complete support for unaligned accesses,
+and blocks are always defined in integer multiples of SRC_WIDTH, so odd
+source lengths or buffer alignments will prevent wide accesses being
+used, as before.
+
+There is an implicit requirement to limit requested DEV read burst
+lengths to less than the hardware's maximum configured MSIZE - otherwise
+RX data will be left over at the end of a block. There is no config
+register that reports this value, so the AXI burst length parameter is
+used to produce a facsimile of it. Warn if such a request arrives that
+doesn't respect this.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 38 ++++++++++++-------
+ 1 file changed, 25 insertions(+), 13 deletions(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -261,6 +261,15 @@ static u32 axi_chan_get_xfer_width(struc
+ return __ffs(src | dst | len | BIT(max_width));
+ }
+
++static u32 axi_dma_encode_msize(u32 max_burst)
++{
++ if (max_burst <= 1)
++ return DWAXIDMAC_BURST_TRANS_LEN_1;
++ if (max_burst > 1024)
++ return DWAXIDMAC_BURST_TRANS_LEN_1024;
++ return fls(max_burst) - 2;
++}
++
+ static inline const char *axi_chan_name(struct axi_dma_chan *chan)
+ {
+ return dma_chan_name(&chan->vc.chan);
+@@ -685,41 +694,41 @@ static int dw_axi_dma_set_hw_desc(struct
+ size_t axi_block_ts;
+ size_t block_ts;
+ u32 ctllo, ctlhi;
+- u32 burst_len;
++ u32 burst_len = 0, mem_burst_msize, reg_burst_msize;
+
+ axi_block_ts = chan->chip->dw->hdata->block_size[chan->id];
+
+ mem_width = __ffs(data_width | mem_addr | len);
+- if (mem_width > DWAXIDMAC_TRANS_WIDTH_32)
+- mem_width = DWAXIDMAC_TRANS_WIDTH_32;
+
+ if (!IS_ALIGNED(mem_addr, 4)) {
+ dev_err(chan->chip->dev, "invalid buffer alignment\n");
+ return -EINVAL;
+ }
+
++ /* Use a reasonable upper limit otherwise residue reporting granularity grows large */
++ mem_burst_msize = axi_dma_encode_msize(16);
++
+ switch (chan->direction) {
+ case DMA_MEM_TO_DEV:
++ reg_burst_msize = axi_dma_encode_msize(chan->config.dst_maxburst);
+ reg_width = __ffs(chan->config.dst_addr_width);
+ device_addr = phys_to_dma(chan->chip->dev, chan->config.dst_addr);
+ ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS |
+ mem_width << CH_CTL_L_SRC_WIDTH_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_DST_MSIZE_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
++ reg_burst_msize << CH_CTL_L_DST_MSIZE_POS |
++ mem_burst_msize << CH_CTL_L_SRC_MSIZE_POS |
+ DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS |
+ DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS;
+ block_ts = len >> mem_width;
+ break;
+ case DMA_DEV_TO_MEM:
++ reg_burst_msize = axi_dma_encode_msize(chan->config.src_maxburst);
+ reg_width = __ffs(chan->config.src_addr_width);
+- /* Prevent partial access units getting lost */
+- if (mem_width > reg_width)
+- mem_width = reg_width;
+ device_addr = phys_to_dma(chan->chip->dev, chan->config.src_addr);
+ ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS |
+ mem_width << CH_CTL_L_DST_WIDTH_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_SRC_MSIZE_POS |
++ mem_burst_msize << CH_CTL_L_DST_MSIZE_POS |
++ reg_burst_msize << CH_CTL_L_SRC_MSIZE_POS |
+ DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
+ DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS;
+ block_ts = len >> reg_width;
+@@ -760,6 +769,12 @@ static int dw_axi_dma_set_hw_desc(struct
+ set_desc_src_master(hw_desc);
+
+ hw_desc->len = len;
++
++ if (burst_len && (chan->config.src_maxburst > burst_len))
++ dev_warn_ratelimited(chan2dev(chan),
++ "%s: requested source burst length %u exceeds supported burst length %u - data may be lost\n",
++ axi_chan_name(chan), chan->config.src_maxburst, burst_len);
++
+ return 0;
+ }
+
+@@ -776,9 +791,6 @@ static size_t calculate_block_len(struct
+ case DMA_MEM_TO_DEV:
+ data_width = BIT(chan->chip->dw->hdata->m_data_width);
+ mem_width = __ffs(data_width | dma_addr | buf_len);
+- if (mem_width > DWAXIDMAC_TRANS_WIDTH_32)
+- mem_width = DWAXIDMAC_TRANS_WIDTH_32;
+-
+ block_len = axi_block_ts << mem_width;
+ break;
+ case DMA_DEV_TO_MEM:
diff --git a/target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch b/target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch
new file mode 100644
index 0000000000..62731aeb34
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch
@@ -0,0 +1,30 @@
+From f3cb675102a2a5a330038c4e748f02b02cec989e Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 22 Jul 2024 09:30:54 +0100
+Subject: [PATCH 1195/1215] tty/serial: pl011: restrict RX burst FIFO threshold
+
+If the associated DMA controller has lower burst length support than the
+level the FIFO is set to, then bytes will be left in the RX FIFO at the
+end of a DMA block - requiring a round-trip through the timeout interrupt
+handler rather than an end-of-block DMA interrupt.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/tty/serial/amba-pl011.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -487,6 +487,12 @@ static void pl011_dma_probe(struct uart_
+ "RX DMA disabled - no residue processing\n");
+ return;
+ }
++ /*
++ * DMA controllers with smaller burst capabilities than 1/4
++ * the FIFO depth will leave more bytes than expected in the
++ * RX FIFO if mismatched.
++ */
++ rx_conf.src_maxburst = min(caps.max_burst, rx_conf.src_maxburst);
+ }
+ dmaengine_slave_config(chan, &rx_conf);
+ uap->dmarx.chan = chan;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch b/target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch
new file mode 100644
index 0000000000..0d0afc2f9c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch
@@ -0,0 +1,27 @@
+From 5112fd8cce4f1dc9bf43f0f90d35e273e1a0f555 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 22 Jul 2024 14:32:32 +0100
+Subject: [PATCH 1196/1215] DT: bindings: add a dma-maxburst property to
+ snps,designware-i2s
+
+Do an end-run around ASoC in lieu of not being able to easily find the
+associated DMA controller capabilities.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ .../devicetree/bindings/sound/snps,designware-i2s.yaml | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml
++++ b/Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml
+@@ -69,6 +69,10 @@ properties:
+ - description: RX DMA Channel
+ minItems: 1
+
++ dma-maxburst:
++ description: FIFO DMA burst threshold limit
++ maxItems: 1
++
+ dma-names:
+ items:
+ - const: tx
diff --git a/target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch b/target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch
new file mode 100644
index 0000000000..d0e3bc1fab
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch
@@ -0,0 +1,99 @@
+From b6b4260fa546d1dc7421c7cfed059052dae04227 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Thu, 18 Jul 2024 09:40:03 +0100
+Subject: [PATCH 1197/1215] sound/soc: dwc-i2s: choose FIFO thresholds based on
+ DMA burst constraints
+
+Valid ranges for the I2S peripheral's FIFO configuration include a depth
+of 16 - unconditionally setting the burst length to 16 with a fifo
+threshold of size/2 will cause under/overflows.
+
+For DMA engines with restricted capabilities the requested burst length
+and FIFO thresholds need to be adjusted downward accordingly.
+
+Both the RX and TX FIFOs operate on "less-than" thresholds. Setting the
+TX threshold to fifo_size minus burst means the FIFO is kept nearly-full.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ sound/soc/dwc/dwc-i2s.c | 21 ++++++++++++++++-----
+ sound/soc/dwc/local.h | 1 +
+ 2 files changed, 17 insertions(+), 5 deletions(-)
+
+--- a/sound/soc/dwc/dwc-i2s.c
++++ b/sound/soc/dwc/dwc-i2s.c
+@@ -236,6 +236,8 @@ static void dw_i2s_config(struct dw_i2s_
+ u32 ch_reg;
+ struct i2s_clk_config_data *config = &dev->config;
+ u32 dmacr;
++ u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
++ u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
+
+ i2s_disable_channels(dev, stream);
+
+@@ -251,7 +253,7 @@ static void dw_i2s_config(struct dw_i2s_
+ i2s_write_reg(dev->i2s_base, TCR(ch_reg),
+ dev->xfer_resolution);
+ i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
+- dev->fifo_th - 1);
++ fifo_depth - dev->fifo_th - 1);
+ i2s_write_reg(dev->i2s_base, TER(ch_reg), TER_TXCHEN |
+ dev->tdm_mask << TER_TXSLOT_SHIFT);
+ dmacr |= (DMACR_DMAEN_TXCH0 << ch_reg);
+@@ -783,8 +785,8 @@ static int dw_configure_dai_by_pd(struct
+ dev->capture_dma_data.pd.data = pdata->capture_dma_data;
+ dev->play_dma_data.pd.addr = res->start + I2S_TXDMA;
+ dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA;
+- dev->play_dma_data.pd.max_burst = 16;
+- dev->capture_dma_data.pd.max_burst = 16;
++ dev->play_dma_data.pd.max_burst = dev->fifo_th;
++ dev->capture_dma_data.pd.max_burst = dev->fifo_th;
+ dev->play_dma_data.pd.addr_width = bus_widths[idx];
+ dev->capture_dma_data.pd.addr_width = bus_widths[idx];
+ dev->play_dma_data.pd.filter = pdata->filter;
+@@ -815,7 +817,10 @@ static int dw_configure_dai_by_dt(struct
+ dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
+ dev->play_dma_data.dt.fifo_size = fifo_depth *
+ (fifo_width[idx2]) >> 8;
+- dev->play_dma_data.dt.maxburst = 16;
++ if (dev->max_dma_burst)
++ dev->play_dma_data.dt.maxburst = dev->max_dma_burst;
++ else
++ dev->play_dma_data.dt.maxburst = fifo_depth / 2;
+ }
+ if (COMP1_RX_ENABLED(comp1)) {
+ idx2 = COMP2_RX_WORDSIZE_0(comp2);
+@@ -824,9 +829,14 @@ static int dw_configure_dai_by_dt(struct
+ dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
+ dev->capture_dma_data.dt.fifo_size = fifo_depth *
+ (fifo_width[idx2] >> 8);
+- dev->capture_dma_data.dt.maxburst = 16;
++ if (dev->max_dma_burst)
++ dev->capture_dma_data.dt.maxburst = dev->max_dma_burst;
++ else
++ dev->capture_dma_data.dt.maxburst = fifo_depth / 2;
+ }
+
++ if (dev->max_dma_burst)
++ dev->fifo_th = min(dev->max_dma_burst, dev->fifo_th);
+ return 0;
+
+ }
+@@ -1070,6 +1080,7 @@ static int dw_i2s_probe(struct platform_
+ }
+ }
+
++ of_property_read_u32(pdev->dev.of_node, "dma-maxburst", &dev->max_dma_burst);
+ dev->bclk_ratio = 0;
+ dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
+ dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
+--- a/sound/soc/dwc/local.h
++++ b/sound/soc/dwc/local.h
+@@ -133,6 +133,7 @@ struct dw_i2s_dev {
+ u32 ccr;
+ u32 xfer_resolution;
+ u32 fifo_th;
++ u32 max_dma_burst;
+ u32 l_reg;
+ u32 r_reg;
+ bool is_jh7110; /* Flag for StarFive JH7110 SoC */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch b/target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch
new file mode 100644
index 0000000000..30b8a9f9b8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch
@@ -0,0 +1,30 @@
+From 062434ab3be76d4fa5973bb199ccfd5b68c11720 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Tue, 23 Jul 2024 11:21:47 +0100
+Subject: [PATCH 1198/1215] dts: rp1: restrict i2s burst lengths to 4
+
+The associated DMAC has channels that do not support longer bursts.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/rp1.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
++++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
+@@ -400,6 +400,7 @@
+ #sound-dai-cells = <0>;
+ dmas = <&rp1_dma RP1_DMA_I2S0_TX>,<&rp1_dma RP1_DMA_I2S0_RX>;
+ dma-names = "tx", "rx";
++ dma-maxburst = <4>;
+ status = "disabled";
+ };
+
+@@ -413,6 +414,7 @@
+ #sound-dai-cells = <0>;
+ dmas = <&rp1_dma RP1_DMA_I2S1_TX>,<&rp1_dma RP1_DMA_I2S1_RX>;
+ dma-names = "tx", "rx";
++ dma-maxburst = <4>;
+ status = "disabled";
+ };
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch b/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch
new file mode 100644
index 0000000000..4c429e284d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch
@@ -0,0 +1,204 @@
+From 485d11cfa7df2d2deb39c9b3455cebcb1a85cea2 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jul 2024 14:36:32 +0100
+Subject: [PATCH 1199/1215] drm/vc4: Disable the 2pixel/clock odd timings
+ workaround for interlaced
+
+Whilst BCM2712 does fix using odd horizontal timings, it doesn't
+work with interlaced modes.
+
+Drop the workaround for interlaced modes and revert to the same
+behaviour as BCM2711.
+
+https://github.com/raspberrypi/linux/issues/6281
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 20 +++++++++++++++++---
+ drivers/gpu/drm/vc4/vc4_drv.h | 2 ++
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 8 +++++++-
+ drivers/gpu/drm/vc4/vc4_hdmi.h | 4 ++++
+ 4 files changed, 30 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -378,7 +378,9 @@ static void vc4_crtc_config_pv(struct dr
+ bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
+ bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC;
+ u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
+- u8 ppc = pv_data->pixels_per_clock;
++ u8 ppc = (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
++ pv_data->pixels_per_clock_int :
++ pv_data->pixels_per_clock;
+
+ u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end;
+ u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start;
+@@ -443,7 +445,8 @@ static void vc4_crtc_config_pv(struct dr
+ */
+ CRTC_WRITE(PV_V_CONTROL,
+ PV_VCONTROL_CONTINUOUS |
+- (vc4->gen >= VC4_GEN_6 ? PV_VCONTROL_ODD_TIMING : 0) |
++ (vc4->gen >= VC4_GEN_6 && ppc == 1 ?
++ PV_VCONTROL_ODD_TIMING : 0) |
+ (is_dsi ? PV_VCONTROL_DSI : 0) |
+ PV_VCONTROL_INTERLACE |
+ (odd_field_first
+@@ -455,7 +458,8 @@ static void vc4_crtc_config_pv(struct dr
+ } else {
+ CRTC_WRITE(PV_V_CONTROL,
+ PV_VCONTROL_CONTINUOUS |
+- (vc4->gen >= VC4_GEN_6 ? PV_VCONTROL_ODD_TIMING : 0) |
++ (vc4->gen >= VC4_GEN_6 && ppc == 1 ?
++ PV_VCONTROL_ODD_TIMING : 0) |
+ (is_dsi ? PV_VCONTROL_DSI : 0));
+ CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+ }
+@@ -1223,6 +1227,7 @@ const struct vc4_pv_data bcm2835_pv0_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
+@@ -1238,6 +1243,7 @@ const struct vc4_pv_data bcm2835_pv1_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
+@@ -1253,6 +1259,7 @@ const struct vc4_pv_data bcm2835_pv2_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI0,
+ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
+@@ -1268,6 +1275,7 @@ const struct vc4_pv_data bcm2711_pv0_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_DSI0,
+ [1] = VC4_ENCODER_TYPE_DPI,
+@@ -1283,6 +1291,7 @@ const struct vc4_pv_data bcm2711_pv1_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_DSI1,
+ [1] = VC4_ENCODER_TYPE_SMI,
+@@ -1298,6 +1307,7 @@ const struct vc4_pv_data bcm2711_pv2_dat
+ },
+ .fifo_depth = 256,
+ .pixels_per_clock = 2,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI0,
+ },
+@@ -1312,6 +1322,7 @@ const struct vc4_pv_data bcm2711_pv3_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
+ },
+@@ -1326,6 +1337,7 @@ const struct vc4_pv_data bcm2711_pv4_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 2,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI1,
+ },
+@@ -1339,6 +1351,7 @@ const struct vc4_pv_data bcm2712_pv0_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI0,
+ },
+@@ -1352,6 +1365,7 @@ const struct vc4_pv_data bcm2712_pv1_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI1,
+ },
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -569,6 +569,8 @@ struct vc4_pv_data {
+
+ /* Number of pixels output per clock period */
+ u8 pixels_per_clock;
++ /* Number of pixels output per clock period when in an interlaced mode */
++ u8 pixels_per_clock_int;
+
+ enum vc4_encoder_type encoder_types[4];
+ };
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2263,7 +2263,9 @@ static int vc4_hdmi_encoder_atomic_check
+ unsigned long long tmds_bit_rate;
+ int ret;
+
+- if (vc4_hdmi->variant->unsupported_odd_h_timings) {
++ if (vc4_hdmi->variant->unsupported_odd_h_timings ||
++ (vc4_hdmi->variant->unsupported_int_odd_h_timings &&
++ (mode->flags & DRM_MODE_FLAG_INTERLACE))) {
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
+ /* Only try to fixup DBLCLK modes to get 480i and 576i
+ * working.
+@@ -3974,6 +3976,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_CK,
+ },
+ .unsupported_odd_h_timings = true,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+@@ -4003,6 +4006,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_2,
+ },
+ .unsupported_odd_h_timings = true,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+@@ -4032,6 +4036,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_CK,
+ },
+ .unsupported_odd_h_timings = false,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+@@ -4059,6 +4064,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_CK,
+ },
+ .unsupported_odd_h_timings = false,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -49,6 +49,10 @@ struct vc4_hdmi_variant {
+
+ /* The BCM2711 cannot deal with odd horizontal pixel timings */
+ bool unsupported_odd_h_timings;
++ /* The BCM2712 can handle odd horizontal pixel timings, but not in
++ * interlaced modes
++ */
++ bool unsupported_int_odd_h_timings;
+
+ /*
+ * The BCM2711 CEC/hotplug IRQ controller is shared between the
diff --git a/target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch b/target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch
new file mode 100644
index 0000000000..8a7d86d745
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch
@@ -0,0 +1,26 @@
+From 70636ad110715b5e1ec6b08e24f0ddaf5df7186d Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Tue, 30 Jul 2024 19:00:03 +0100
+Subject: [PATCH 1200/1215] ARM: dts: bcm2712: Fix invalid
+ polling-delay-passive setting
+
+This produces a hard fail on later (6.11) kernels.
+
+See: https://lore.kernel.org/all/5802156.DvuYhMxLoT@rjwysocki.net/
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -40,7 +40,7 @@
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+- polling-delay-passive = <2000>;
++ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+ coefficients = <(-550) 450000>;
+ thermal-sensors = <&thermal>;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch b/target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch
new file mode 100644
index 0000000000..6545c09186
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch
@@ -0,0 +1,143 @@
+From 199e611183de09ad91fe01fc79da78cc9d11ccb6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 29 Jul 2024 11:12:38 +0100
+Subject: [PATCH 1201/1215] spi: dw: Fix non-DMA transmit-only transfers
+
+Ensure the transmit FIFO has emptied before ending the transfer by
+dropping the TX threshold to 0 when the last byte has been pushed into
+the FIFO. Include a similar fix for the non-IRQ paths.
+
+See: https://github.com/raspberrypi/linux/issues/6285
+Fixes: 6014649de765 ("spi: dw: Save bandwidth with the TMOD_TO feature")
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 62 +++++++++++++++++++++++++++++++++------
+ drivers/spi/spi-dw.h | 3 ++
+ 2 files changed, 56 insertions(+), 9 deletions(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -220,6 +220,32 @@ int dw_spi_check_status(struct dw_spi *d
+ }
+ EXPORT_SYMBOL_NS_GPL(dw_spi_check_status, SPI_DW_CORE);
+
++static inline bool dw_spi_ctlr_busy(struct dw_spi *dws)
++{
++ return dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_BUSY;
++}
++
++static enum hrtimer_restart dw_spi_hrtimer_handler(struct hrtimer *hr)
++{
++ struct dw_spi *dws = container_of(hr, struct dw_spi, hrtimer);
++
++ if (!dw_spi_ctlr_busy(dws)) {
++ spi_finalize_current_transfer(dws->host);
++ return HRTIMER_NORESTART;
++ }
++
++ if (!dws->idle_wait_retries) {
++ dev_err(&dws->host->dev, "controller stuck at busy\n");
++ spi_finalize_current_transfer(dws->host);
++ return HRTIMER_NORESTART;
++ }
++
++ dws->idle_wait_retries--;
++ hrtimer_forward_now(hr, dws->idle_wait_interval);
++
++ return HRTIMER_RESTART;
++}
++
+ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
+ {
+ u16 irq_status = dw_readl(dws, DW_SPI_ISR);
+@@ -246,7 +272,22 @@ static irqreturn_t dw_spi_transfer_handl
+ }
+ } else if (!dws->tx_len) {
+ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+- spi_finalize_current_transfer(dws->host);
++ if (dw_spi_ctlr_busy(dws)) {
++ ktime_t period = ns_to_ktime(DIV_ROUND_UP(NSEC_PER_SEC, dws->current_freq));
++
++ /*
++ * Make the initial wait an underestimate of how long the transfer
++ * should take, then poll rapidly to reduce the delay
++ */
++ hrtimer_start(&dws->hrtimer,
++ period * (8 * dws->n_bytes - 1),
++ HRTIMER_MODE_REL);
++ dws->idle_wait_retries = 10;
++ dws->idle_wait_interval = period;
++ } else {
++ spi_finalize_current_transfer(dws->host);
++ }
++ return IRQ_HANDLED;
+ }
+
+ /*
+@@ -255,9 +296,13 @@ static irqreturn_t dw_spi_transfer_handl
+ * have the TXE IRQ flood at the final stage of the transfer.
+ */
+ if (irq_status & DW_SPI_INT_TXEI) {
+- if (!dws->tx_len)
+- dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+ dw_writer(dws);
++ if (!dws->tx_len) {
++ if (dws->rx_len)
++ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
++ else
++ dw_writel(dws, DW_SPI_TXFTLR, 0);
++ }
+ }
+
+ return IRQ_HANDLED;
+@@ -428,7 +473,7 @@ static int dw_spi_poll_transfer(struct d
+ ret = dw_spi_check_status(dws, true);
+ if (ret)
+ return ret;
+- } while (dws->rx_len);
++ } while (dws->rx_len || dws->tx_len || dw_spi_ctlr_busy(dws));
+
+ return 0;
+ }
+@@ -652,11 +697,6 @@ static int dw_spi_write_then_read(struct
+ return 0;
+ }
+
+-static inline bool dw_spi_ctlr_busy(struct dw_spi *dws)
+-{
+- return dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_BUSY;
+-}
+-
+ static int dw_spi_wait_mem_op_done(struct dw_spi *dws)
+ {
+ int retry = DW_SPI_WAIT_RETRIES;
+@@ -993,6 +1033,9 @@ int dw_spi_add_host(struct device *dev,
+ }
+ }
+
++ hrtimer_init(&dws->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
++ dws->hrtimer.function = dw_spi_hrtimer_handler;
++
+ ret = spi_register_controller(host);
+ if (ret) {
+ dev_err_probe(dev, ret, "problem registering spi host\n");
+@@ -1018,6 +1061,7 @@ void dw_spi_remove_host(struct dw_spi *d
+ {
+ dw_spi_debugfs_remove(dws);
+
++ hrtimer_cancel(&dws->hrtimer);
+ spi_unregister_controller(dws->host);
+
+ if (dws->dma_ops && dws->dma_ops->dma_exit)
+--- a/drivers/spi/spi-dw.h
++++ b/drivers/spi/spi-dw.h
+@@ -180,6 +180,9 @@ struct dw_spi {
+ u32 current_freq; /* frequency in hz */
+ u32 cur_rx_sample_dly;
+ u32 def_rx_sample_dly_ns;
++ struct hrtimer hrtimer;
++ ktime_t idle_wait_interval;
++ int idle_wait_retries;
+
+ /* Custom memory operations */
+ struct spi_controller_mem_ops mem_ops;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch b/target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch
new file mode 100644
index 0000000000..585173aa44
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch
@@ -0,0 +1,26 @@
+From e9294823cf02068189a0e901223ed4991923c689 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 31 Jul 2024 10:55:19 +0100
+Subject: [PATCH 1202/1215] spi: dw: Clamp the minimum clock speed
+
+The DW SPI interface has a 16-bit clock divider, where the bottom bit
+of the divisor must be 0. Limit how low the clock speed can go to
+prevent the clock divider from being truncated, as that could lead to
+a much higher clock rate than requested.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -397,7 +397,7 @@ void dw_spi_update_config(struct dw_spi
+ dw_writel(dws, DW_SPI_CTRLR1, cfg->ndf ? cfg->ndf - 1 : 0);
+
+ /* Note DW APB SSI clock divider doesn't support odd numbers */
+- clk_div = (DIV_ROUND_UP(dws->max_freq, cfg->freq) + 1) & 0xfffe;
++ clk_div = min(DIV_ROUND_UP(dws->max_freq, cfg->freq) + 1, 0xfffe) & 0xfffe;
+ speed_hz = dws->max_freq / clk_div;
+
+ if (dws->current_freq != speed_hz) {
diff --git a/target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch b/target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch
new file mode 100644
index 0000000000..afd6c415ba
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch
@@ -0,0 +1,26 @@
+From 05e3687c6c973c30bf35f3b7f4a7589b5030a830 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 31 Jul 2024 13:19:26 +0100
+Subject: [PATCH 1203/1215] overlays: i2c-rtc: Correct bq32000 property name
+
+The DT property for the BQ32000 controlled by trickle-resistor-ohms
+parameter should be "trickle-resistor-ohms", not "abracon,tc-resistor".
+
+See: https://github.com/raspberrypi/linux/issues/6291
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/i2c-rtc-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-common.dtsi
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-common.dtsi
+@@ -354,7 +354,7 @@
+ <&rv3028>,"trickle-resistor-ohms:0",
+ <&rv3032>,"trickle-resistor-ohms:0",
+ <&rv1805>,"abracon,tc-resistor:0",
+- <&bq32000>,"abracon,tc-resistor:0";
++ <&bq32000>,"trickle-resistor-ohms:0";
+ trickle-voltage-mv = <&rv3032>,"trickle-voltage-millivolts:0";
+ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0";
+ wakeup-source = <&ds1339>,"wakeup-source?",
diff --git a/target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch b/target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch
new file mode 100644
index 0000000000..cc54c62b91
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch
@@ -0,0 +1,31 @@
+From 16d0ee22d2c0b32cc67db73ce03263b740bba2a7 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 31 Jul 2024 15:02:47 +0100
+Subject: [PATCH 1204/1215] hwmon: (adt7410) Add DT compatible strings
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/hwmon/adt7410.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/hwmon/adt7410.c
++++ b/drivers/hwmon/adt7410.c
+@@ -94,10 +94,18 @@ static const struct i2c_device_id adt741
+ };
+ MODULE_DEVICE_TABLE(i2c, adt7410_ids);
+
++static const struct of_device_id adt7410_of_ids[] = {
++ { .compatible = "adi,adt7410" },
++ { .compatible = "adi,adt7420" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, adt7410_of_ids);
++
+ static struct i2c_driver adt7410_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adt7410",
++ .of_match_table = adt7410_of_ids,
+ .pm = pm_sleep_ptr(&adt7x10_dev_pm_ops),
+ },
+ .probe = adt7410_i2c_probe,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch b/target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch
new file mode 100644
index 0000000000..fb786e172e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch
@@ -0,0 +1,23 @@
+From a4bf61fad9fe102514243ed263c458b053c87681 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 2 Aug 2024 11:29:03 +0100
+Subject: [PATCH 1205/1215] fixup! pinctrl: bcm2712 pinctrl/pinconf driver
+
+Fix cut-and-paste error spotted during upstreaming process.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/pinctrl/bcm/pinctrl-bcm2712.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pinctrl/bcm/pinctrl-bcm2712.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm2712.c
+@@ -1029,7 +1029,7 @@ static int bcm2712_pinconf_get(struct pi
+
+ *config = pinconf_to_config_packed(param, arg);
+
+- return -ENOTSUPP;
++ return 0;
+ }
+
+ static int bcm2712_pinconf_set(struct pinctrl_dev *pctldev,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch b/target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch
new file mode 100644
index 0000000000..db5f472ff0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch
@@ -0,0 +1,125 @@
+From e94e761305fa2281718adcf625d78f3cf662e12d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 1 Aug 2024 18:12:50 +0100
+Subject: [PATCH 1206/1215] dtoverlays: Add overlay for HD44780 via I2C PCF8574
+ backpack
+
+Many HD44780 LCD displays are connected via very common I2C
+GPIO expander.
+We have an overlay for connecting the displays directly to GPIOs,
+but not one for it connected via a backpack. Add such an overlay.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 27 +++++++++
+ .../dts/overlays/hd44780-i2c-lcd-overlay.dts | 57 +++++++++++++++++++
+ 3 files changed, 85 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/hd44780-i2c-lcd-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -82,6 +82,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ gpio-no-irq.dtbo \
+ gpio-poweroff.dtbo \
+ gpio-shutdown.dtbo \
++ hd44780-i2c-lcd.dtbo \
+ hd44780-lcd.dtbo \
+ hdmi-backlight-hwhack-gpio.dtbo \
+ hifiberry-amp.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1705,6 +1705,33 @@ Params: gpio_pin GPIO pin
+ (default 100)
+
+
++Name: hd44780-i2c-lcd
++Info: Configures an HD44780 compatible LCD display connected via a PCF8574 as
++ is often found as a backpack interface for these displays.
++Load: dtoverlay=hd44780-i2c-lcd,<param>=<val>
++Params: addr I2C address of PCF8574
++ pin_d4 GPIO pin for data pin D4 (default 4)
++
++ pin_d5 GPIO pin for data pin D5 (default 5)
++
++ pin_d6 GPIO pin for data pin D6 (default 6)
++
++ pin_d7 GPIO pin for data pin D7 (default 7)
++
++ pin_en GPIO pin for "Enable" (default 2)
++
++ pin_rs GPIO pin for "Register Select" (default 0)
++
++ pin_rw GPIO pin for R/W select (default 1)
++
++ pin_bl GPIO pin for enabling/disabling the display
++ backlight. (default 3)
++
++ display_height Height of the display in characters (default 2)
++
++ display_width Width of the display in characters (default 16)
++
++
+ Name: hd44780-lcd
+ Info: Configures an HD44780 compatible LCD display. Uses 4 gpio pins for
+ data, 2 gpio pins for enable and register select and 1 optional pin
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/hd44780-i2c-lcd-overlay.dts
+@@ -0,0 +1,57 @@
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2c_arm>;
++ __overlay__ {
++ status = "okay";
++
++ pcf857x: pcf857x@27 {
++ compatible = "nxp,pcf8574";
++ reg = <0x27>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@1 {
++ target-path = "/";
++ __overlay__ {
++ lcd_screen: auxdisplay {
++ compatible = "hit,hd44780";
++
++ data-gpios = <&pcf857x 4 0>,
++ <&pcf857x 5 0>,
++ <&pcf857x 6 0>,
++ <&pcf857x 7 0>;
++ enable-gpios = <&pcf857x 2 0>;
++ rs-gpios = <&pcf857x 0 0>;
++ rw-gpios = <&pcf857x 1 0>;
++ backlight-gpios = <&pcf857x 3 0>;
++
++ display-width-chars = <16>;
++ display-height-chars = <2>;
++ };
++ };
++ };
++
++ __overrides__ {
++ pin_d4 = <&lcd_screen>,"data-gpios:4";
++ pin_d5 = <&lcd_screen>,"data-gpios:16";
++ pin_d6 = <&lcd_screen>,"data-gpios:28";
++ pin_d7 = <&lcd_screen>,"data-gpios:40";
++ pin_en = <&lcd_screen>,"enable-gpios:4";
++ pin_rs = <&lcd_screen>,"rs-gpios:4";
++ pin_rw = <&lcd_screen>,"rw-gpios:4";
++ pin_bl = <&lcd_screen>,"backlight-gpios:4";
++ display_height = <&lcd_screen>,"display-height-chars:0";
++ display_width = <&lcd_screen>,"display-width-chars:0";
++ addr = <&pcf857x>,"reg:0";
++ };
++
++};
diff --git a/target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch b/target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch
new file mode 100644
index 0000000000..793cd49310
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch
@@ -0,0 +1,28 @@
+From 3c319a466a1c718f66c471a9d5ec60de6de44612 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 2 Aug 2024 10:41:28 +0100
+Subject: [PATCH 1207/1215] dtoverlays: Document display_[width|height] on
+ hd44780-lcd overlay
+
+The default values defining a 16x2 display weren't documented,
+so add them.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1752,9 +1752,9 @@ Params: pin_d4 GPIO pin
+ pin_bl Optional pin for enabling/disabling the
+ display backlight. (default disabled)
+
+- display_height Height of the display in characters
++ display_height Height of the display in characters (default 2)
+
+- display_width Width of the display in characters
++ display_width Width of the display in characters (default 16)
+
+
+ Name: hdmi-backlight-hwhack-gpio
diff --git a/target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch b/target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch
new file mode 100644
index 0000000000..16e7603498
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch
@@ -0,0 +1,39 @@
+From 216df57950849f905c398904e7d6cbdf278b5717 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 5 Aug 2024 11:28:36 +0100
+Subject: [PATCH 1208/1215] DTS: bcm2712: enable SD slot CQE by default on Pi 5
+
+The corresponding driver implementation has seen sufficient testing,
+so enable by default. Retain the dtparam so it can be turned off for test.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 6 +++---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -378,9 +378,9 @@ Params:
+ non-lite SKU of CM4).
+ (default "on")
+
+- sd_cqe Use to enable Command Queueing on the SD
+- interface for faster Class A2 card performance
+- (Pi 5 only, default "off")
++ sd_cqe Set to "off" to disable Command Queueing if you
++ have an incompatible Class A2 SD card
++ (Pi 5 only, default "on")
+
+ sd_overclock Clock (in MHz) to use when the MMC framework
+ requests 50MHz
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+@@ -363,6 +363,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_g
+ sd-uhs-sdr50;
+ sd-uhs-ddr50;
+ sd-uhs-sdr104;
++ supports-cqe;
+ cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>;
+ //no-1-8-v;
+ status = "okay";
diff --git a/target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch b/target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch
new file mode 100644
index 0000000000..d909c6f9a2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch
@@ -0,0 +1,50 @@
+From 53b9d9bbb57e292c6b332a2fb9899003586e17ca Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 16:17:02 +0100
+Subject: [PATCH 1211/1215] gpiolib: Override gpiochip numbers with DT aliases
+
+In the same way that other subsystems support the setting of device
+id numbers from Device Tree aliases, allow gpiochip numbers to be
+derived from "gpiochip<n>" aliases.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/gpio/gpiolib.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -111,6 +111,7 @@ static int gpiochip_irqchip_init_valid_m
+ static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc);
+
+ static bool gpiolib_initialized;
++static int first_dynamic_gpiochip_num = -1;
+
+ static inline void desc_set_label(struct gpio_desc *d, const char *label)
+ {
+@@ -746,6 +747,7 @@ int gpiochip_add_data_with_key(struct gp
+ unsigned int i;
+ int base = 0;
+ int ret = 0;
++ int id;
+
+ /*
+ * First: allocate and populate the internal stat container, and
+@@ -770,7 +772,16 @@ int gpiochip_add_data_with_key(struct gp
+ else if (gc->parent)
+ device_set_node(&gdev->dev, dev_fwnode(gc->parent));
+
+- gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
++ if (first_dynamic_gpiochip_num < 0) {
++ id = of_alias_get_highest_id("gpiochip");
++ first_dynamic_gpiochip_num = (id >= 0) ? (id + 1) : 0;
++ }
++
++ id = of_alias_get_id(gdev->dev.of_node, "gpiochip");
++ if (id < 0)
++ id = first_dynamic_gpiochip_num;
++
++ gdev->id = ida_alloc_range(&gpio_ida, id, ~0, GFP_KERNEL);
+ if (gdev->id < 0) {
+ ret = gdev->id;
+ goto err_free_gdev;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch b/target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch
new file mode 100644
index 0000000000..21913760a7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch
@@ -0,0 +1,23 @@
+From 1162316fd26eeb4193b23fcc1bb332f42938aa70 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 16:58:59 +0100
+Subject: [PATCH 1212/1215] dts: bcm2712-rpi: Add gpiochip0 alias
+
+Add a gpiochip0 aliase pointing to the rp1 GPIO node, making it appear
+as gpiochip0.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -112,6 +112,7 @@
+ gpio2 = &gio_aon;
+ gpio3 = &pinctrl;
+ gpio4 = &pinctrl_aon;
++ gpiochip0 = &gpio;
+ i2c = &i2c_arm;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch b/target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch
new file mode 100644
index 0000000000..5bf54c3fb0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch
@@ -0,0 +1,24 @@
+From 70c640ce992234aacba5a717f3fb47319f451431 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 17:40:25 +0100
+Subject: [PATCH 1213/1215] dts: bcm2712-rpi: The SoC gpiochips start at 10
+
+Make the BCM2712's onboard GPIOs start at gpiochip10, marking them out
+as system resources and preventing accidental use by existing Pi 5
+code.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -113,6 +113,7 @@
+ gpio3 = &pinctrl;
+ gpio4 = &pinctrl_aon;
+ gpiochip0 = &gpio;
++ gpiochip10 = &gio;
+ i2c = &i2c_arm;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
diff --git a/target/linux/bcm47xx/Makefile b/target/linux/bcm47xx/Makefile
index 325a207d08..428fa75e70 100644
--- a/target/linux/bcm47xx/Makefile
+++ b/target/linux/bcm47xx/Makefile
@@ -10,8 +10,7 @@ BOARDNAME:=Broadcom BCM47xx/53xx (MIPS)
FEATURES:=squashfs usb
SUBTARGETS:=generic mips74k legacy
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Broadcom based BCM47xx/53xx routers with MIPS CPU, *not* ARM.
diff --git a/target/linux/bcm47xx/config-6.1 b/target/linux/bcm47xx/config-6.1
deleted file mode 100644
index d86e79d98b..0000000000
--- a/target/linux/bcm47xx/config-6.1
+++ /dev/null
@@ -1,190 +0,0 @@
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_BCM47XX=y
-CONFIG_BCM47XX_BCMA=y
-CONFIG_BCM47XX_NVRAM=y
-CONFIG_BCM47XX_SPROM=y
-CONFIG_BCM47XX_SSB=y
-CONFIG_BCM47XX_WDT=y
-CONFIG_BCMA=y
-CONFIG_BCMA_BLOCKIO=y
-CONFIG_BCMA_DEBUG=y
-CONFIG_BCMA_DRIVER_GMAC_CMN=y
-CONFIG_BCMA_DRIVER_GPIO=y
-CONFIG_BCMA_DRIVER_MIPS=y
-CONFIG_BCMA_DRIVER_PCI=y
-CONFIG_BCMA_DRIVER_PCI_HOSTMODE=y
-CONFIG_BCMA_FALLBACK_SPROM=y
-CONFIG_BCMA_HOST_PCI=y
-CONFIG_BCMA_HOST_PCI_POSSIBLE=y
-CONFIG_BCMA_HOST_SOC=y
-CONFIG_BCMA_NFLASH=y
-CONFIG_BCMA_PFLASH=y
-CONFIG_BCMA_SFLASH=y
-# CONFIG_BGMAC_BCMA is not set
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="noinitrd console=ttyS0,115200"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-# CONFIG_COMMON_CLK is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-# CONFIG_CPU_BMIPS is not set
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-CONFIG_CPU_MIPS32_R1=y
-# CONFIG_CPU_MIPS32_R2 is not set
-CONFIG_CPU_MIPSR1=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DMA_NONCOHERENT=y
-# CONFIG_EARLY_PRINTK is not set
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_FIXED_PHY=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_WDT=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LEDS_GPIO_REGISTER=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_BCM47XXSFLASH=y
-CONFIG_MTD_BCM47XX_PARTS=y
-CONFIG_MTD_NAND_BCM47XXNFLASH=y
-CONFIG_MTD_NAND_BRCMNAND=y
-CONFIG_MTD_NAND_BRCMNAND_BCMA=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NO_EXCEPT_FILL=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-# CONFIG_OF is not set
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SRCU=y
-CONFIG_SSB=y
-CONFIG_SSB_B43_PCI_BRIDGE=y
-CONFIG_SSB_BLOCKIO=y
-CONFIG_SSB_DRIVER_EXTIF=y
-CONFIG_SSB_DRIVER_GIGE=y
-CONFIG_SSB_DRIVER_GPIO=y
-CONFIG_SSB_DRIVER_MIPS=y
-CONFIG_SSB_DRIVER_PCICORE=y
-CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-CONFIG_SSB_EMBEDDED=y
-CONFIG_SSB_FALLBACK_SPROM=y
-CONFIG_SSB_HOST_SOC=y
-CONFIG_SSB_PCICORE_HOSTMODE=y
-CONFIG_SSB_PCIHOST=y
-CONFIG_SSB_PCIHOST_POSSIBLE=y
-CONFIG_SSB_SERIAL=y
-CONFIG_SSB_SFLASH=y
-CONFIG_SSB_SPROM=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_B53=y
-CONFIG_SWCONFIG_B53_PHY_DRIVER=y
-CONFIG_SWCONFIG_B53_PHY_FIXUP=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_BMIPS=y
-CONFIG_SYS_HAS_CPU_BMIPS32_3300=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=1
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_ZBOOT_LOAD_ADDRESS=0xffffffff80400000
diff --git a/target/linux/bcm47xx/patches-6.1/030-v6.3-MIPS-BCM47XX-Add-support-for-Linksys-E2500-V3.patch b/target/linux/bcm47xx/patches-6.1/030-v6.3-MIPS-BCM47XX-Add-support-for-Linksys-E2500-V3.patch
deleted file mode 100644
index 4faecdc7d5..0000000000
--- a/target/linux/bcm47xx/patches-6.1/030-v6.3-MIPS-BCM47XX-Add-support-for-Linksys-E2500-V3.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From fc605b914167de75432c3b5aae239fb191e84a31 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 8 Feb 2023 08:03:01 +0100
-Subject: [PATCH] MIPS: BCM47XX: Add support for Linksys E2500 V3
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's a BCM5358 based home WiFi router. 16 MiB flash, 64 MiB RAM, BCM5325
-switch, on-SoC 802.11n radio.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/bcm47xx/board.c | 1 +
- arch/mips/bcm47xx/buttons.c | 9 +++++++++
- arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | 1 +
- 3 files changed, 11 insertions(+)
-
---- a/arch/mips/bcm47xx/board.c
-+++ b/arch/mips/bcm47xx/board.c
-@@ -130,6 +130,7 @@ struct bcm47xx_board_type_list2 bcm47xx_
- {{BCM47XX_BOARD_LINKSYS_E1000V21, "Linksys E1000 V2.1"}, "E1000", "2.1"},
- {{BCM47XX_BOARD_LINKSYS_E1200V2, "Linksys E1200 V2"}, "E1200", "2.0"},
- {{BCM47XX_BOARD_LINKSYS_E2000V1, "Linksys E2000 V1"}, "Linksys E2000", "1.0"},
-+ {{BCM47XX_BOARD_LINKSYS_E2500V3, "Linksys E2500 V3"}, "E2500", "1.0"},
- /* like WRT610N v2.0 */
- {{BCM47XX_BOARD_LINKSYS_E3000V1, "Linksys E3000 V1"}, "E300", "1.0"},
- {{BCM47XX_BOARD_LINKSYS_E3200V1, "Linksys E3200 V1"}, "E3200", "1.0"},
---- a/arch/mips/bcm47xx/buttons.c
-+++ b/arch/mips/bcm47xx/buttons.c
-@@ -223,6 +223,12 @@ bcm47xx_buttons_linksys_e2000v1[] __init
- };
-
- static const struct gpio_keys_button
-+bcm47xx_buttons_linksys_e2500v3[] __initconst = {
-+ BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON),
-+ BCM47XX_GPIO_KEY(10, KEY_RESTART),
-+};
-+
-+static const struct gpio_keys_button
- bcm47xx_buttons_linksys_e3000v1[] __initconst = {
- BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
- BCM47XX_GPIO_KEY(6, KEY_RESTART),
-@@ -617,6 +623,9 @@ int __init bcm47xx_buttons_register(void
- case BCM47XX_BOARD_LINKSYS_E2000V1:
- err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e2000v1);
- break;
-+ case BCM47XX_BOARD_LINKSYS_E2500V3:
-+ err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e2500v3);
-+ break;
- case BCM47XX_BOARD_LINKSYS_E3000V1:
- err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3000v1);
- break;
---- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
-+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
-@@ -61,6 +61,7 @@ enum bcm47xx_board {
- BCM47XX_BOARD_LINKSYS_E1000V21,
- BCM47XX_BOARD_LINKSYS_E1200V2,
- BCM47XX_BOARD_LINKSYS_E2000V1,
-+ BCM47XX_BOARD_LINKSYS_E2500V3,
- BCM47XX_BOARD_LINKSYS_E3000V1,
- BCM47XX_BOARD_LINKSYS_E3200V1,
- BCM47XX_BOARD_LINKSYS_E4200V1,
diff --git a/target/linux/bcm47xx/patches-6.1/130-MIPS-BCM47XX-Add-support-for-Huawei-B593u-12.patch b/target/linux/bcm47xx/patches-6.1/130-MIPS-BCM47XX-Add-support-for-Huawei-B593u-12.patch
deleted file mode 100644
index 333c3d7b87..0000000000
--- a/target/linux/bcm47xx/patches-6.1/130-MIPS-BCM47XX-Add-support-for-Huawei-B593u-12.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 27 Feb 2023 07:44:38 +0100
-Subject: [PATCH] MIPS: BCM47XX: Add support for Huawei B593u-12
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's a BCM5358 based home router. One of very few bcm47xx devices with
-cellular modems (here: LTE).
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- arch/mips/bcm47xx/board.c | 1 +
- arch/mips/bcm47xx/leds.c | 8 ++++++++
- arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | 1 +
- 3 files changed, 10 insertions(+)
-
---- a/arch/mips/bcm47xx/board.c
-+++ b/arch/mips/bcm47xx/board.c
-@@ -193,6 +193,7 @@ struct bcm47xx_board_type_list1 bcm47xx_
- /* boardtype, boardnum, boardrev */
- static const
- struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = {
-+ {{BCM47XX_BOARD_HUAWEI_B593U_12, "Huawei B593u-12"}, "0x053d", "1234", "0x1301"},
- {{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"},
- {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
- {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
---- a/arch/mips/bcm47xx/leds.c
-+++ b/arch/mips/bcm47xx/leds.c
-@@ -223,6 +223,11 @@ bcm47xx_leds_dlink_dir330[] __initconst
- /* Huawei */
-
- static const struct gpio_led
-+bcm47xx_leds_huawei_b593u_12[] __initconst = {
-+ BCM47XX_GPIO_LED(5, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
-+};
-+
-+static const struct gpio_led
- bcm47xx_leds_huawei_e970[] __initconst = {
- BCM47XX_GPIO_LED(0, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
- };
-@@ -672,6 +677,9 @@ void __init bcm47xx_leds_register(void)
- bcm47xx_set_pdata(bcm47xx_leds_dlink_dir330);
- break;
-
-+ case BCM47XX_BOARD_HUAWEI_B593U_12:
-+ bcm47xx_set_pdata(bcm47xx_leds_huawei_b593u_12);
-+ break;
- case BCM47XX_BOARD_HUAWEI_E970:
- bcm47xx_set_pdata(bcm47xx_leds_huawei_e970);
- break;
---- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
-+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
-@@ -53,6 +53,7 @@ enum bcm47xx_board {
- BCM47XX_BOARD_DLINK_DIR130,
- BCM47XX_BOARD_DLINK_DIR330,
-
-+ BCM47XX_BOARD_HUAWEI_B593U_12,
- BCM47XX_BOARD_HUAWEI_E970,
-
- BCM47XX_BOARD_LINKSYS_E900V1,
diff --git a/target/linux/bcm47xx/patches-6.1/159-cpu_fixes.patch b/target/linux/bcm47xx/patches-6.1/159-cpu_fixes.patch
deleted file mode 100644
index f51ed83d93..0000000000
--- a/target/linux/bcm47xx/patches-6.1/159-cpu_fixes.patch
+++ /dev/null
@@ -1,484 +0,0 @@
---- a/arch/mips/include/asm/r4kcache.h
-+++ b/arch/mips/include/asm/r4kcache.h
-@@ -27,6 +27,38 @@
- extern void (*r4k_blast_dcache)(void);
- extern void (*r4k_blast_icache)(void);
-
-+#if defined(CONFIG_BCM47XX) && !defined(CONFIG_CPU_MIPS32_R2)
-+#include <asm/paccess.h>
-+#include <linux/ssb/ssb.h>
-+#define BCM4710_DUMMY_RREG() bcm4710_dummy_rreg()
-+
-+static inline unsigned long bcm4710_dummy_rreg(void)
-+{
-+ return *(volatile unsigned long *)(KSEG1ADDR(SSB_ENUM_BASE));
-+}
-+
-+#define BCM4710_FILL_TLB(addr) bcm4710_fill_tlb((void *)(addr))
-+
-+static inline unsigned long bcm4710_fill_tlb(void *addr)
-+{
-+ return *(unsigned long *)addr;
-+}
-+
-+#define BCM4710_PROTECTED_FILL_TLB(addr) bcm4710_protected_fill_tlb((void *)(addr))
-+
-+static inline void bcm4710_protected_fill_tlb(void *addr)
-+{
-+ unsigned long x;
-+ get_dbe(x, (unsigned long *)addr);;
-+}
-+
-+#else
-+#define BCM4710_DUMMY_RREG()
-+
-+#define BCM4710_FILL_TLB(addr)
-+#define BCM4710_PROTECTED_FILL_TLB(addr)
-+#endif
-+
- /*
- * This macro return a properly sign-extended address suitable as base address
- * for indexed cache operations. Two issues here:
-@@ -60,6 +92,7 @@ static inline void flush_icache_line_ind
-
- static inline void flush_dcache_line_indexed(unsigned long addr)
- {
-+ BCM4710_DUMMY_RREG();
- cache_op(Index_Writeback_Inv_D, addr);
- }
-
-@@ -83,11 +116,13 @@ static inline void flush_icache_line(uns
-
- static inline void flush_dcache_line(unsigned long addr)
- {
-+ BCM4710_DUMMY_RREG();
- cache_op(Hit_Writeback_Inv_D, addr);
- }
-
- static inline void invalidate_dcache_line(unsigned long addr)
- {
-+ BCM4710_DUMMY_RREG();
- cache_op(Hit_Invalidate_D, addr);
- }
-
-@@ -160,6 +195,7 @@ static inline int protected_flush_icache
- return protected_cache_op(Hit_Invalidate_I_Loongson2, addr);
-
- default:
-+ BCM4710_DUMMY_RREG();
- return protected_cache_op(Hit_Invalidate_I, addr);
- }
- }
-@@ -172,6 +208,7 @@ static inline int protected_flush_icache
- */
- static inline int protected_writeback_dcache_line(unsigned long addr)
- {
-+ BCM4710_DUMMY_RREG();
- return protected_cache_op(Hit_Writeback_Inv_D, addr);
- }
-
-@@ -193,8 +230,51 @@ static inline void invalidate_tcache_pag
- unroll(times, _cache_op, insn, op, (addr) + (i++ * (lsize))); \
- } while (0)
-
-+static inline void blast_dcache(void)
-+{
-+ unsigned long start = KSEG0;
-+ unsigned long dcache_size = current_cpu_data.dcache.waysize * current_cpu_data.dcache.ways;
-+ unsigned long end = (start + dcache_size);
-+
-+ do {
-+ BCM4710_DUMMY_RREG();
-+ cache_op(Index_Writeback_Inv_D, start);
-+ start += current_cpu_data.dcache.linesz;
-+ } while(start < end);
-+}
-+
-+static inline void blast_dcache_page(unsigned long page)
-+{
-+ unsigned long start = page;
-+ unsigned long end = start + PAGE_SIZE;
-+
-+ BCM4710_FILL_TLB(start);
-+ do {
-+ BCM4710_DUMMY_RREG();
-+ cache_op(Hit_Writeback_Inv_D, start);
-+ start += current_cpu_data.dcache.linesz;
-+ } while(start < end);
-+}
-+
-+static inline void blast_dcache_page_indexed(unsigned long page)
-+{
-+ unsigned long start = page;
-+ unsigned long end = start + PAGE_SIZE;
-+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-+ unsigned long ws_end = current_cpu_data.dcache.ways <<
-+ current_cpu_data.dcache.waybit;
-+ unsigned long ws, addr;
-+ for (ws = 0; ws < ws_end; ws += ws_inc) {
-+ start = page + ws;
-+ for (addr = start; addr < end; addr += current_cpu_data.dcache.linesz) {
-+ BCM4710_DUMMY_RREG();
-+ cache_op(Index_Writeback_Inv_D, addr);
-+ }
-+ }
-+}
-+
- /* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
--#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra) \
-+#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra, war) \
- static inline void extra##blast_##pfx##cache##lsize(void) \
- { \
- unsigned long start = INDEX_BASE; \
-@@ -204,6 +284,7 @@ static inline void extra##blast_##pfx##c
- current_cpu_data.desc.waybit; \
- unsigned long ws, addr; \
- \
-+ war \
- for (ws = 0; ws < ws_end; ws += ws_inc) \
- for (addr = start; addr < end; addr += lsize * 32) \
- cache_unroll(32, kernel_cache, indexop, \
-@@ -215,6 +296,7 @@ static inline void extra##blast_##pfx##c
- unsigned long start = page; \
- unsigned long end = page + PAGE_SIZE; \
- \
-+ war \
- do { \
- cache_unroll(32, kernel_cache, hitop, start, lsize); \
- start += lsize * 32; \
-@@ -231,32 +313,33 @@ static inline void extra##blast_##pfx##c
- current_cpu_data.desc.waybit; \
- unsigned long ws, addr; \
- \
-+ war \
- for (ws = 0; ws < ws_end; ws += ws_inc) \
- for (addr = start; addr < end; addr += lsize * 32) \
- cache_unroll(32, kernel_cache, indexop, \
- addr | ws, lsize); \
- }
-
--__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, )
--__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, )
--__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, )
--__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, )
--__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, )
--__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_)
--__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, )
--__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, )
--__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, )
--__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, )
--__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, )
--__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, )
--__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, )
--
--__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, )
--__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, )
--__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, )
--__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, )
--__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, )
--__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, )
-+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, , )
-+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, , BCM4710_FILL_TLB(start);)
-+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, , )
-+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, , )
-+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, , BCM4710_FILL_TLB(start);)
-+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_, BCM4710_FILL_TLB(start);)
-+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, , )
-+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, , )
-+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, , BCM4710_FILL_TLB(start);)
-+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, , )
-+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, , )
-+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, , )
-+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, , )
-+
-+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, , )
-+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, , )
-+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, , )
-+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, , )
-+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, , )
-+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, , )
-
- #define __BUILD_BLAST_USER_CACHE(pfx, desc, indexop, hitop, lsize) \
- static inline void blast_##pfx##cache##lsize##_user_page(unsigned long page) \
-@@ -281,65 +364,36 @@ __BUILD_BLAST_USER_CACHE(d, dcache, Inde
- __BUILD_BLAST_USER_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
-
- /* build blast_xxx_range, protected_blast_xxx_range */
--#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra) \
-+#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra, war, war2) \
- static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, \
- unsigned long end) \
- { \
- unsigned long lsize = cpu_##desc##_line_size(); \
-- unsigned long lsize_2 = lsize * 2; \
-- unsigned long lsize_3 = lsize * 3; \
-- unsigned long lsize_4 = lsize * 4; \
-- unsigned long lsize_5 = lsize * 5; \
-- unsigned long lsize_6 = lsize * 6; \
-- unsigned long lsize_7 = lsize * 7; \
-- unsigned long lsize_8 = lsize * 8; \
- unsigned long addr = start & ~(lsize - 1); \
-- unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \
-- int lines = (aend - addr) / lsize; \
-- \
-- while (lines >= 8) { \
-- prot##cache_op(hitop, addr); \
-- prot##cache_op(hitop, addr + lsize); \
-- prot##cache_op(hitop, addr + lsize_2); \
-- prot##cache_op(hitop, addr + lsize_3); \
-- prot##cache_op(hitop, addr + lsize_4); \
-- prot##cache_op(hitop, addr + lsize_5); \
-- prot##cache_op(hitop, addr + lsize_6); \
-- prot##cache_op(hitop, addr + lsize_7); \
-- addr += lsize_8; \
-- lines -= 8; \
-- } \
-+ unsigned long aend = (end - 1) & ~(lsize - 1); \
- \
-- if (lines & 0x4) { \
-- prot##cache_op(hitop, addr); \
-- prot##cache_op(hitop, addr + lsize); \
-- prot##cache_op(hitop, addr + lsize_2); \
-- prot##cache_op(hitop, addr + lsize_3); \
-- addr += lsize_4; \
-- } \
-- \
-- if (lines & 0x2) { \
-- prot##cache_op(hitop, addr); \
-- prot##cache_op(hitop, addr + lsize); \
-- addr += lsize_2; \
-- } \
-+ war \
- \
-- if (lines & 0x1) { \
-+ while (1) { \
-+ war2 \
- prot##cache_op(hitop, addr); \
-+ if (addr == aend) \
-+ break; \
-+ addr += lsize; \
- } \
- }
-
--__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, )
--__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, )
--__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, )
-+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, , BCM4710_PROTECTED_FILL_TLB(addr); BCM4710_PROTECTED_FILL_TLB(aend);, BCM4710_DUMMY_RREG();)
-+__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, , , )
-+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, , , )
- __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I_Loongson2, \
-- protected_, loongson2_)
--__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , )
--__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, , )
--__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , )
-+ protected_, loongson2_, , )
-+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , , BCM4710_FILL_TLB(addr); BCM4710_FILL_TLB(aend);, BCM4710_DUMMY_RREG();)
-+__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, , , , )
-+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , , , )
- /* blast_inv_dcache_range */
--__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , )
--__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , )
-+__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , , , BCM4710_DUMMY_RREG();)
-+__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , , , )
-
- /* Currently, this is very specific to Loongson-3 */
- #define __BUILD_BLAST_CACHE_NODE(pfx, desc, indexop, hitop, lsize) \
---- a/arch/mips/include/asm/stackframe.h
-+++ b/arch/mips/include/asm/stackframe.h
-@@ -429,6 +429,10 @@
- #else
- .set push
- .set arch=r4000
-+#ifdef CONFIG_BCM47XX
-+ nop
-+ nop
-+#endif
- eret
- .set pop
- #endif
---- a/arch/mips/kernel/genex.S
-+++ b/arch/mips/kernel/genex.S
-@@ -21,6 +21,19 @@
- #include <asm/sync.h>
- #include <asm/thread_info.h>
-
-+#ifdef CONFIG_BCM47XX
-+# ifdef eret
-+# undef eret
-+# endif
-+# define eret \
-+ .set push; \
-+ .set noreorder; \
-+ nop; \
-+ nop; \
-+ eret; \
-+ .set pop;
-+#endif
-+
- __INIT
-
- /*
-@@ -32,6 +45,9 @@
- NESTED(except_vec3_generic, 0, sp)
- .set push
- .set noat
-+#ifdef CONFIG_BCM47XX
-+ nop
-+#endif
- mfc0 k1, CP0_CAUSE
- andi k1, k1, 0x7c
- #ifdef CONFIG_64BIT
-@@ -52,6 +68,9 @@ NESTED(except_vec3_r4000, 0, sp)
- .set push
- .set arch=r4000
- .set noat
-+#ifdef CONFIG_BCM47XX
-+ nop
-+#endif
- mfc0 k1, CP0_CAUSE
- li k0, 31<<2
- andi k1, k1, 0x7c
---- a/arch/mips/mm/c-r4k.c
-+++ b/arch/mips/mm/c-r4k.c
-@@ -37,6 +37,9 @@
- #include <asm/traps.h>
- #include <asm/mips-cps.h>
-
-+/* For enabling BCM4710 cache workarounds */
-+static int bcm4710 = 0;
-+
- /*
- * Bits describing what cache ops an SMP callback function may perform.
- *
-@@ -189,6 +192,9 @@ static void r4k_blast_dcache_user_page_s
- {
- unsigned long dc_lsize = cpu_dcache_line_size();
-
-+ if (bcm4710)
-+ r4k_blast_dcache_page = blast_dcache_page;
-+ else
- if (dc_lsize == 0)
- r4k_blast_dcache_user_page = (void *)cache_noop;
- else if (dc_lsize == 16)
-@@ -207,6 +213,9 @@ static void r4k_blast_dcache_page_indexe
- {
- unsigned long dc_lsize = cpu_dcache_line_size();
-
-+ if (bcm4710)
-+ r4k_blast_dcache_page_indexed = blast_dcache_page_indexed;
-+ else
- if (dc_lsize == 0)
- r4k_blast_dcache_page_indexed = (void *)cache_noop;
- else if (dc_lsize == 16)
-@@ -226,6 +235,9 @@ static void r4k_blast_dcache_setup(void)
- {
- unsigned long dc_lsize = cpu_dcache_line_size();
-
-+ if (bcm4710)
-+ r4k_blast_dcache = blast_dcache;
-+ else
- if (dc_lsize == 0)
- r4k_blast_dcache = (void *)cache_noop;
- else if (dc_lsize == 16)
-@@ -1779,6 +1791,17 @@ static void coherency_setup(void)
- * silly idea of putting something else there ...
- */
- switch (current_cpu_type()) {
-+ case CPU_BMIPS3300:
-+ {
-+ u32 cm;
-+ cm = read_c0_diag();
-+ /* Enable icache */
-+ cm |= (1 << 31);
-+ /* Enable dcache */
-+ cm |= (1 << 30);
-+ write_c0_diag(cm);
-+ }
-+ break;
- case CPU_R4000PC:
- case CPU_R4000SC:
- case CPU_R4000MC:
-@@ -1825,6 +1848,15 @@ void r4k_cache_init(void)
- extern void build_copy_page(void);
- struct cpuinfo_mips *c = &current_cpu_data;
-
-+ /* Check if special workarounds are required */
-+#if defined(CONFIG_BCM47XX) && !defined(CONFIG_CPU_MIPS32_R2)
-+ if (current_cpu_data.cputype == CPU_BMIPS32 && (current_cpu_data.processor_id & 0xff) == 0) {
-+ printk("Enabling BCM4710A0 cache workarounds.\n");
-+ bcm4710 = 1;
-+ } else
-+#endif
-+ bcm4710 = 0;
-+
- probe_pcache();
- probe_vcache();
- setup_scache();
-@@ -1897,7 +1929,15 @@ void r4k_cache_init(void)
- */
- local_r4k___flush_cache_all(NULL);
-
-+#ifdef CONFIG_BCM47XX
-+ {
-+ static void (*_coherency_setup)(void);
-+ _coherency_setup = (void (*)(void)) KSEG1ADDR(coherency_setup);
-+ _coherency_setup();
-+ }
-+#else
- coherency_setup();
-+#endif
- board_cache_error_setup = r4k_cache_error_setup;
-
- /*
---- a/arch/mips/mm/tlbex.c
-+++ b/arch/mips/mm/tlbex.c
-@@ -958,6 +958,9 @@ void build_get_pgde32(u32 **p, unsigned
- uasm_i_srl(p, ptr, ptr, SMP_CPUID_PTRSHIFT);
- uasm_i_addu(p, ptr, tmp, ptr);
- #else
-+#ifdef CONFIG_BCM47XX
-+ uasm_i_nop(p);
-+#endif
- UASM_i_LA_mostly(p, ptr, pgdc);
- #endif
- uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
-@@ -1304,6 +1307,9 @@ static void build_r4000_tlb_refill_handl
- #ifdef CONFIG_64BIT
- build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
- #else
-+# ifdef CONFIG_BCM47XX
-+ uasm_i_nop(&p);
-+# endif
- build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
- #endif
-
-@@ -1315,6 +1321,9 @@ static void build_r4000_tlb_refill_handl
- build_update_entries(&p, K0, K1);
- build_tlb_write_entry(&p, &l, &r, tlb_random);
- uasm_l_leave(&l, p);
-+#ifdef CONFIG_BCM47XX
-+ uasm_i_nop(&p);
-+#endif
- uasm_i_eret(&p); /* return from trap */
- }
- #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
-@@ -2016,6 +2025,9 @@ build_r4000_tlbchange_handler_head(u32 *
- #ifdef CONFIG_64BIT
- build_get_pmde64(p, l, r, wr.r1, wr.r2); /* get pmd in ptr */
- #else
-+# ifdef CONFIG_BCM47XX
-+ uasm_i_nop(p);
-+# endif
- build_get_pgde32(p, wr.r1, wr.r2); /* get pgd in ptr */
- #endif
-
-@@ -2062,6 +2074,9 @@ build_r4000_tlbchange_handler_tail(u32 *
- build_tlb_write_entry(p, l, r, tlb_indexed);
- uasm_l_leave(l, *p);
- build_restore_work_registers(p);
-+#ifdef CONFIG_BCM47XX
-+ uasm_i_nop(p);
-+#endif
- uasm_i_eret(p); /* return from trap */
-
- #ifdef CONFIG_64BIT
diff --git a/target/linux/bcm47xx/patches-6.1/160-kmap_coherent.patch b/target/linux/bcm47xx/patches-6.1/160-kmap_coherent.patch
deleted file mode 100644
index 2af9d42fe5..0000000000
--- a/target/linux/bcm47xx/patches-6.1/160-kmap_coherent.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From: Jeff Hansen <jhansen@cardaccess-inc.com>
-Subject: [PATCH] kmap_coherent
-
-On ASUS WL-500gP there are some "Data bus error"s when executing simple
-commands liks "ps" or "cat /proc/1/cmdline".
-
-This fixes OpenWrt ticket #1485: https://dev.openwrt.org/ticket/1485
----
---- a/arch/mips/include/asm/cpu-features.h
-+++ b/arch/mips/include/asm/cpu-features.h
-@@ -257,6 +257,9 @@
- #ifndef cpu_has_pindexed_dcache
- #define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
- #endif
-+#ifndef cpu_use_kmap_coherent
-+#define cpu_use_kmap_coherent 1
-+#endif
-
- /*
- * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
---- a/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
-+++ b/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
-@@ -79,4 +79,6 @@
- #define cpu_scache_line_size() 0
- #define cpu_has_vz 0
-
-+#define cpu_use_kmap_coherent 0
-+
- #endif /* __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H */
---- a/arch/mips/mm/c-r4k.c
-+++ b/arch/mips/mm/c-r4k.c
-@@ -701,7 +701,7 @@ static inline void local_r4k_flush_cache
- map_coherent = (cpu_has_dc_aliases &&
- page_mapcount(page) &&
- !Page_dcache_dirty(page));
-- if (map_coherent)
-+ if (map_coherent && cpu_use_kmap_coherent)
- vaddr = kmap_coherent(page, addr);
- else
- vaddr = kmap_atomic(page);
-@@ -728,7 +728,7 @@ static inline void local_r4k_flush_cache
- }
-
- if (vaddr) {
-- if (map_coherent)
-+ if (map_coherent && cpu_use_kmap_coherent)
- kunmap_coherent();
- else
- kunmap_atomic(vaddr);
---- a/arch/mips/mm/init.c
-+++ b/arch/mips/mm/init.c
-@@ -172,7 +172,7 @@ void copy_user_highpage(struct page *to,
- void *vfrom, *vto;
-
- vto = kmap_atomic(to);
-- if (cpu_has_dc_aliases &&
-+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
- page_mapcount(from) && !Page_dcache_dirty(from)) {
- vfrom = kmap_coherent(from, vaddr);
- copy_page(vto, vfrom);
-@@ -194,7 +194,7 @@ void copy_to_user_page(struct vm_area_st
- struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
- {
-- if (cpu_has_dc_aliases &&
-+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
- page_mapcount(page) && !Page_dcache_dirty(page)) {
- void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
- memcpy(vto, src, len);
-@@ -212,7 +212,7 @@ void copy_from_user_page(struct vm_area_
- struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
- {
-- if (cpu_has_dc_aliases &&
-+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
- page_mapcount(page) && !Page_dcache_dirty(page)) {
- void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
- memcpy(dst, vfrom, len);
diff --git a/target/linux/bcm47xx/patches-6.1/209-b44-register-adm-switch.patch b/target/linux/bcm47xx/patches-6.1/209-b44-register-adm-switch.patch
deleted file mode 100644
index 1b9dcb3adc..0000000000
--- a/target/linux/bcm47xx/patches-6.1/209-b44-register-adm-switch.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From b36f694256f41bc71571f467646d015dda128d14 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sat, 9 Nov 2013 17:03:59 +0100
-Subject: [PATCH 210/210] b44: register adm switch
-
----
- drivers/net/ethernet/broadcom/b44.c | 57 +++++++++++++++++++++++++++++++++++
- drivers/net/ethernet/broadcom/b44.h | 3 ++
- 2 files changed, 60 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/b44.c
-+++ b/drivers/net/ethernet/broadcom/b44.c
-@@ -31,6 +31,8 @@
- #include <linux/ssb/ssb.h>
- #include <linux/slab.h>
- #include <linux/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/platform_data/adm6996-gpio.h>
-
- #include <linux/uaccess.h>
- #include <asm/io.h>
-@@ -2251,6 +2253,69 @@ static void b44_adjust_link(struct net_d
- }
- }
-
-+#ifdef CONFIG_BCM47XX
-+static int b44_register_adm_switch(struct b44 *bp)
-+{
-+ int gpio;
-+ struct platform_device *pdev;
-+ struct adm6996_gpio_platform_data adm_data = {0};
-+ struct platform_device_info info = {0};
-+
-+ adm_data.model = ADM6996L;
-+ gpio = bcm47xx_nvram_gpio_pin("adm_eecs");
-+ if (gpio >= 0)
-+ adm_data.eecs = gpio;
-+ else
-+ adm_data.eecs = 2;
-+
-+ gpio = bcm47xx_nvram_gpio_pin("adm_eesk");
-+ if (gpio >= 0)
-+ adm_data.eesk = gpio;
-+ else
-+ adm_data.eesk = 3;
-+
-+ gpio = bcm47xx_nvram_gpio_pin("adm_eedi");
-+ if (gpio >= 0)
-+ adm_data.eedi = gpio;
-+ else
-+ adm_data.eedi = 4;
-+
-+ /*
-+ * We ignore the "adm_rc" GPIO here. The driver does not use it,
-+ * and it conflicts with the Reset button GPIO on the Linksys WRT54GSv1.
-+ */
-+
-+ info.parent = bp->sdev->dev;
-+ info.name = "adm6996_gpio";
-+ info.id = -1;
-+ info.data = &adm_data;
-+ info.size_data = sizeof(adm_data);
-+
-+ if (!bp->adm_switch) {
-+ pdev = platform_device_register_full(&info);
-+ if (IS_ERR(pdev))
-+ return PTR_ERR(pdev);
-+
-+ bp->adm_switch = pdev;
-+ }
-+ return 0;
-+}
-+static void b44_unregister_adm_switch(struct b44 *bp)
-+{
-+ if (bp->adm_switch)
-+ platform_device_unregister(bp->adm_switch);
-+}
-+#else
-+static int b44_register_adm_switch(struct b44 *bp)
-+{
-+ return 0;
-+}
-+static void b44_unregister_adm_switch(struct b44 *bp)
-+{
-+
-+}
-+#endif /* CONFIG_BCM47XX */
-+
- static int b44_register_phy_one(struct b44 *bp)
- {
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-@@ -2287,6 +2352,9 @@ static int b44_register_phy_one(struct b
- if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
- (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
-
-+ if (sprom->boardflags_lo & B44_BOARDFLAG_ADM)
-+ b44_register_adm_switch(bp);
-+
- dev_info(sdev->dev,
- "could not find PHY at %i, use fixed one\n",
- bp->phy_addr);
-@@ -2481,6 +2549,7 @@ static void b44_remove_one(struct ssb_de
- unregister_netdev(dev);
- if (bp->flags & B44_FLAG_EXTERNAL_PHY)
- b44_unregister_phy_one(bp);
-+ b44_unregister_adm_switch(bp);
- ssb_device_disable(sdev, 0);
- ssb_bus_may_powerdown(sdev->bus);
- netif_napi_del(&bp->napi);
---- a/drivers/net/ethernet/broadcom/b44.h
-+++ b/drivers/net/ethernet/broadcom/b44.h
-@@ -408,6 +408,9 @@ struct b44 {
- struct mii_bus *mii_bus;
- int old_link;
- struct mii_if_info mii_if;
-+
-+ /* platform device for associated switch */
-+ struct platform_device *adm_switch;
- };
-
- #endif /* _B44_H */
diff --git a/target/linux/bcm47xx/patches-6.1/210-b44_phy_fix.patch b/target/linux/bcm47xx/patches-6.1/210-b44_phy_fix.patch
deleted file mode 100644
index af9736518b..0000000000
--- a/target/linux/bcm47xx/patches-6.1/210-b44_phy_fix.patch
+++ /dev/null
@@ -1,54 +0,0 @@
---- a/drivers/net/ethernet/broadcom/b44.c
-+++ b/drivers/net/ethernet/broadcom/b44.c
-@@ -430,10 +430,34 @@ static void b44_wap54g10_workaround(stru
- error:
- pr_warn("PHY: cannot reset MII transceiver isolate bit\n");
- }
-+
-+static void b44_bcm47xx_workarounds(struct b44 *bp)
-+{
-+ char buf[20];
-+ struct ssb_device *sdev = bp->sdev;
-+
-+ /* Toshiba WRC-1000, Siemens SE505 v1, Askey RT-210W, RT-220W */
-+ if (sdev->bus->sprom.board_num == 100) {
-+ bp->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY;
-+ } else {
-+ /* WL-HDD */
-+ if (bcm47xx_nvram_getenv("hardware_version", buf, sizeof(buf)) >= 0 &&
-+ !strncmp(buf, "WL300-", strlen("WL300-"))) {
-+ if (sdev->bus->sprom.et0phyaddr == 0 &&
-+ sdev->bus->sprom.et1phyaddr == 1)
-+ bp->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY;
-+ }
-+ }
-+ return;
-+}
- #else
- static inline void b44_wap54g10_workaround(struct b44 *bp)
- {
- }
-+
-+static inline void b44_bcm47xx_workarounds(struct b44 *bp)
-+{
-+}
- #endif
-
- static int b44_setup_phy(struct b44 *bp)
-@@ -442,6 +466,7 @@ static int b44_setup_phy(struct b44 *bp)
- int err;
-
- b44_wap54g10_workaround(bp);
-+ b44_bcm47xx_workarounds(bp);
-
- if (bp->flags & B44_FLAG_EXTERNAL_PHY)
- return 0;
-@@ -2181,6 +2206,8 @@ static int b44_get_invariants(struct b44
- * valid PHY address. */
- bp->phy_addr &= 0x1F;
-
-+ b44_bcm47xx_workarounds(bp);
-+
- eth_hw_addr_set(bp->dev, addr);
-
- if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
diff --git a/target/linux/bcm47xx/patches-6.1/280-activate_ssb_support_in_usb.patch b/target/linux/bcm47xx/patches-6.1/280-activate_ssb_support_in_usb.patch
deleted file mode 100644
index f6e9e6d30a..0000000000
--- a/target/linux/bcm47xx/patches-6.1/280-activate_ssb_support_in_usb.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-This prevents the options from being delete with make kernel_oldconfig.
----
- drivers/ssb/Kconfig | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -36,6 +36,7 @@ config BCMA_HOST_PCI
- config BCMA_HOST_SOC
- bool "Support for BCMA in a SoC"
- depends on HAS_IOMEM
-+ select USB_HCD_BCMA if USB_EHCI_HCD || USB_OHCI_HCD
- help
- Host interface for a Broadcom AIX bus directly mapped into
- the memory. This only works with the Broadcom SoCs from the
---- a/drivers/ssb/Kconfig
-+++ b/drivers/ssb/Kconfig
-@@ -141,6 +141,7 @@ config SSB_SFLASH
- config SSB_EMBEDDED
- bool
- depends on SSB_DRIVER_MIPS && SSB_PCICORE_HOSTMODE
-+ select USB_HCD_SSB if USB_EHCI_HCD || USB_OHCI_HCD
- default y
-
- config SSB_DRIVER_EXTIF
diff --git a/target/linux/bcm47xx/patches-6.1/300-fork_cacheflush.patch b/target/linux/bcm47xx/patches-6.1/300-fork_cacheflush.patch
deleted file mode 100644
index daa2c1adf0..0000000000
--- a/target/linux/bcm47xx/patches-6.1/300-fork_cacheflush.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Wolfram Joost <dbox2@frokaschwei.de>
-Subject: [PATCH] fork_cacheflush
-
-On ASUS WL-500gP there are many unexpected "Segmentation fault"s that
-seem to be caused by a kernel. They can be avoided by:
-1) Disabling highpage
-2) Using flush_cache_mm in flush_cache_dup_mm
-
-For details see OpenWrt ticket #2035 https://dev.openwrt.org/ticket/2035
----
---- a/arch/mips/include/asm/cacheflush.h
-+++ b/arch/mips/include/asm/cacheflush.h
-@@ -46,7 +46,7 @@
- extern void (*flush_cache_all)(void);
- extern void (*__flush_cache_all)(void);
- extern void (*flush_cache_mm)(struct mm_struct *mm);
--#define flush_cache_dup_mm(mm) do { (void) (mm); } while (0)
-+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
- extern void (*flush_cache_range)(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
- extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
diff --git a/target/linux/bcm47xx/patches-6.1/310-no_highpage.patch b/target/linux/bcm47xx/patches-6.1/310-no_highpage.patch
deleted file mode 100644
index 8f368e3e9e..0000000000
--- a/target/linux/bcm47xx/patches-6.1/310-no_highpage.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From: Jeff Hansen <jhansen@cardaccess-inc.com>
-Subject: [PATCH] no highpage
-
-On ASUS WL-500gP there are many unexpected "Segmentation fault"s that
-seem to be caused by a kernel. They can be avoided by:
-1) Disabling highpage
-2) Using flush_cache_mm in flush_cache_dup_mm
-
-For details see OpenWrt ticket #2035 https://dev.openwrt.org/ticket/2035
----
---- a/arch/mips/include/asm/page.h
-+++ b/arch/mips/include/asm/page.h
-@@ -71,6 +71,7 @@ static inline unsigned int page_size_ftl
- #endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
-
- #include <linux/pfn.h>
-+#include <asm/cpu-features.h>
-
- extern void build_clear_page(void);
- extern void build_copy_page(void);
-@@ -110,11 +111,16 @@ static inline void clear_user_page(void
- flush_data_cache_page((unsigned long)addr);
- }
-
--struct vm_area_struct;
--extern void copy_user_highpage(struct page *to, struct page *from,
-- unsigned long vaddr, struct vm_area_struct *vma);
-+static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
-+ struct page *to)
-+{
-+ extern void (*flush_data_cache_page)(unsigned long addr);
-
--#define __HAVE_ARCH_COPY_USER_HIGHPAGE
-+ copy_page(vto, vfrom);
-+ if (!cpu_has_ic_fills_f_dc ||
-+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
-+ flush_data_cache_page((unsigned long)vto);
-+}
-
- /*
- * These are used to make use of C type-checking..
---- a/arch/mips/mm/init.c
-+++ b/arch/mips/mm/init.c
-@@ -166,30 +166,6 @@ void kunmap_coherent(void)
- preempt_enable();
- }
-
--void copy_user_highpage(struct page *to, struct page *from,
-- unsigned long vaddr, struct vm_area_struct *vma)
--{
-- void *vfrom, *vto;
--
-- vto = kmap_atomic(to);
-- if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
-- page_mapcount(from) && !Page_dcache_dirty(from)) {
-- vfrom = kmap_coherent(from, vaddr);
-- copy_page(vto, vfrom);
-- kunmap_coherent();
-- } else {
-- vfrom = kmap_atomic(from);
-- copy_page(vto, vfrom);
-- kunmap_atomic(vfrom);
-- }
-- if ((!cpu_has_ic_fills_f_dc) ||
-- pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
-- flush_data_cache_page((unsigned long)vto);
-- kunmap_atomic(vto);
-- /* Make sure this page is cleared on other CPU's too before using it */
-- smp_wmb();
--}
--
- void copy_to_user_page(struct vm_area_struct *vma,
- struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
diff --git a/target/linux/bcm47xx/patches-6.1/400-mtd-bcm47xxpart-get-nvram.patch b/target/linux/bcm47xx/patches-6.1/400-mtd-bcm47xxpart-get-nvram.patch
deleted file mode 100644
index 17abe89d1d..0000000000
--- a/target/linux/bcm47xx/patches-6.1/400-mtd-bcm47xxpart-get-nvram.patch
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/drivers/mtd/parsers/bcm47xxpart.c
-+++ b/drivers/mtd/parsers/bcm47xxpart.c
-@@ -98,6 +98,7 @@ static int bcm47xxpart_parse(struct mtd_
- int trx_num = 0; /* Number of found TRX partitions */
- int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
- int err;
-+ bool found_nvram = false;
-
- /*
- * Some really old flashes (like AT45DB*) had smaller erasesize-s, but
-@@ -279,12 +280,23 @@ static int bcm47xxpart_parse(struct mtd_
- if (buf[0] == NVRAM_HEADER) {
- bcm47xxpart_add_part(&parts[curr_part++], "nvram",
- master->size - blocksize, 0);
-+ found_nvram = true;
- break;
- }
- }
-
- kfree(buf);
-
-+ if (!found_nvram) {
-+ pr_err("can not find a nvram partition reserve last block\n");
-+ bcm47xxpart_add_part(&parts[curr_part++], "nvram_guess",
-+ master->size - blocksize * 2, MTD_WRITEABLE);
-+ for (i = 0; i < curr_part; i++) {
-+ if (parts[i].size + parts[i].offset == master->size)
-+ parts[i].offset -= blocksize * 2;
-+ }
-+ }
-+
- /*
- * Assume that partitions end at the beginning of the one they are
- * followed by.
diff --git a/target/linux/bcm47xx/patches-6.1/700-net-bgmac-connect-to-PHY-even-if-it-is-BGMAC_PHY_NOR.patch b/target/linux/bcm47xx/patches-6.1/700-net-bgmac-connect-to-PHY-even-if-it-is-BGMAC_PHY_NOR.patch
deleted file mode 100644
index 2fcfbb7438..0000000000
--- a/target/linux/bcm47xx/patches-6.1/700-net-bgmac-connect-to-PHY-even-if-it-is-BGMAC_PHY_NOR.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 7 Nov 2021 14:20:40 +0100
-Subject: [PATCH] net: bgmac: connect to PHY even if it is BGMAC_PHY_NOREGS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Recent bgmac change was meant to just fix a race between "Generic PHY"
-and "bcm53xx" drivers after -EPROBE_DEFER. It modified bgmac to use
-phy_connect() only if there is a real PHY device connected.
-
-That change broke bgmac on bcm47xx. bcma_phy_connect() now registers a
-fixed PHY with the bgmac_phy_connect_direct(). That fails as another
-fixed PHY (also using address 0) is already registered - by bcm47xx arch
-code bcm47xx_register_bus_complete().
-
-This change brings origial behaviour. It connects Ethernet interface
-with pseudo-PHY (switch device) and adjusts Ethernet interface link to
-match connected switch.
-
-This fixes:
-[ 2.548098] bgmac_bcma bcma0:1: Failed to register fixed PHY device
-[ 2.554584] bgmac_bcma bcma0:1: Cannot connect to phy
-
-Fixes: b5375509184d ("net: bgmac: improve handling PHY")
-Link: https://lore.kernel.org/netdev/3639116e-9292-03ca-b9d9-d741118a4541@gmail.com/T/#u
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/ethernet/broadcom/bgmac-bcma.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -94,7 +94,7 @@ static int bcma_phy_connect(struct bgmac
- return 0;
-
- /* Connect to the PHY */
-- if (bgmac->mii_bus && bgmac->phyaddr != BGMAC_PHY_NOREGS) {
-+ if (bgmac->mii_bus) {
- snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
- bgmac->phyaddr);
- phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
diff --git a/target/linux/bcm47xx/patches-6.1/701-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch b/target/linux/bcm47xx/patches-6.1/701-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
deleted file mode 100644
index 3a2f4b06ed..0000000000
--- a/target/linux/bcm47xx/patches-6.1/701-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 10 Jun 2022 13:10:47 +0200
-Subject: [PATCH] bgmac: reduce max frame size to support just MTU 1500
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-bgmac allocates new replacement buffer before handling each received
-frame. Allocating & DMA-preparing 9724 B each time consumes a lot of CPU
-time. Ideally bgmac should just respect currently set MTU but it isn't
-the case right now. For now just revert back to the old limited frame
-size.
-
-This change bumps NAT masquarade speed by ~95%.
-
-Ref: 8c7da63978f1 ("bgmac: configure MTU and add support for frames beyond 8192 byte size")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/ethernet/broadcom/bgmac.h | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -328,8 +328,7 @@
- #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
- #define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \
- BGMAC_RX_FRAME_OFFSET)
--/* Jumbo frame size with FCS */
--#define BGMAC_RX_MAX_FRAME_SIZE 9724
-+#define BGMAC_RX_MAX_FRAME_SIZE 1536
- #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
- #define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
diff --git a/target/linux/bcm47xx/patches-6.1/791-tg3-no-pci-sleep.patch b/target/linux/bcm47xx/patches-6.1/791-tg3-no-pci-sleep.patch
deleted file mode 100644
index 76e979ad58..0000000000
--- a/target/linux/bcm47xx/patches-6.1/791-tg3-no-pci-sleep.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-When the Ethernet controller is powered down and someone wants to
-access the mdio bus like the witch driver (b53) the system crashed if
-PCI_D3hot was set before. This patch deactivates this power sawing mode
-when a switch driver is in use.
-
---- a/drivers/net/ethernet/broadcom/tg3.c
-+++ b/drivers/net/ethernet/broadcom/tg3.c
-@@ -4269,7 +4269,8 @@ static int tg3_power_down_prepare(struct
- static void tg3_power_down(struct tg3 *tp)
- {
- pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
-- pci_set_power_state(tp->pdev, PCI_D3hot);
-+ if (!tg3_flag(tp, ROBOSWITCH))
-+ pci_set_power_state(tp->pdev, PCI_D3hot);
- }
-
- static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u32 *speed, u8 *duplex)
diff --git a/target/linux/bcm47xx/patches-6.1/800-bcma-add-table-of-serial-flashes-with-smaller-blocks.patch b/target/linux/bcm47xx/patches-6.1/800-bcma-add-table-of-serial-flashes-with-smaller-blocks.patch
deleted file mode 100644
index 318dc55810..0000000000
--- a/target/linux/bcm47xx/patches-6.1/800-bcma-add-table-of-serial-flashes-with-smaller-blocks.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 597715c61ae75a05ab3310a34ff3857a006f0f63 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 20 Nov 2014 21:32:42 +0100
-Subject: [PATCH] bcma: add table of serial flashes with smaller blocks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/bcma/driver_chipcommon_sflash.c | 29 +++++++++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
---- a/drivers/bcma/driver_chipcommon_sflash.c
-+++ b/drivers/bcma/driver_chipcommon_sflash.c
-@@ -9,6 +9,7 @@
-
- #include <linux/platform_device.h>
- #include <linux/bcma/bcma.h>
-+#include <bcm47xx_board.h>
-
- static struct resource bcma_sflash_resource = {
- .name = "bcma_sflash",
-@@ -42,6 +43,13 @@ static const struct bcma_sflash_tbl_e bc
- { NULL },
- };
-
-+/* Some devices use smaller blocks (and have more of them) */
-+static const struct bcma_sflash_tbl_e bcma_sflash_st_shrink_tbl[] = {
-+ { "M25P16", 0x14, 0x1000, 512, },
-+ { "M25P32", 0x15, 0x1000, 1024, },
-+ { NULL },
-+};
-+
- static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
- { "SST25WF512", 1, 0x1000, 16, },
- { "SST25VF512", 0x48, 0x1000, 16, },
-@@ -85,6 +93,24 @@ static void bcma_sflash_cmd(struct bcma_
- bcma_err(cc->core->bus, "SFLASH control command failed (timeout)!\n");
- }
-
-+const struct bcma_sflash_tbl_e *bcma_sflash_shrink_flash(u32 id)
-+{
-+ enum bcm47xx_board board = bcm47xx_board_get();
-+ const struct bcma_sflash_tbl_e *e;
-+
-+ switch (board) {
-+ case BCM47XX_BOARD_NETGEAR_WGR614_V10:
-+ case BCM47XX_BOARD_NETGEAR_WNR1000_V3:
-+ for (e = bcma_sflash_st_shrink_tbl; e->name; e++) {
-+ if (e->id == id)
-+ return e;
-+ }
-+ return NULL;
-+ default:
-+ return NULL;
-+ }
-+}
-+
- /* Initialize serial flash access */
- int bcma_sflash_init(struct bcma_drv_cc *cc)
- {
-@@ -115,6 +141,10 @@ int bcma_sflash_init(struct bcma_drv_cc
- case 0x13:
- return -ENOTSUPP;
- default:
-+ e = bcma_sflash_shrink_flash(id);
-+ if (e)
-+ break;
-+
- for (e = bcma_sflash_st_tbl; e->name; e++) {
- if (e->id == id)
- break;
diff --git a/target/linux/bcm47xx/patches-6.1/820-wgt634u-nvram-fix.patch b/target/linux/bcm47xx/patches-6.1/820-wgt634u-nvram-fix.patch
deleted file mode 100644
index 82997ca65a..0000000000
--- a/target/linux/bcm47xx/patches-6.1/820-wgt634u-nvram-fix.patch
+++ /dev/null
@@ -1,296 +0,0 @@
-The Netgear wgt634u uses a different format for storing the
-configuration. This patch is needed to read out the correct
-configuration. The cfe_env.c file uses a different method way to read
-out the configuration than the in kernel cfe config reader.
-
---- a/drivers/firmware/broadcom/Makefile
-+++ b/drivers/firmware/broadcom/Makefile
-@@ -1,4 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o
-+obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o cfe_env.o
- obj-$(CONFIG_BCM47XX_SPROM) += bcm47xx_sprom.o
- obj-$(CONFIG_TEE_BNXT_FW) += tee_bnxt_fw.o
---- /dev/null
-+++ b/drivers/firmware/broadcom/cfe_env.c
-@@ -0,0 +1,228 @@
-+/*
-+ * CFE environment variable access
-+ *
-+ * Copyright 2001-2003, Broadcom Corporation
-+ * Copyright 2006, Felix Fietkau <nbd@nbd.name>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <asm/io.h>
-+#include <linux/uaccess.h>
-+
-+#define NVRAM_SIZE (0x1ff0)
-+static char _nvdata[NVRAM_SIZE];
-+static char _valuestr[256];
-+
-+/*
-+ * TLV types. These codes are used in the "type-length-value"
-+ * encoding of the items stored in the NVRAM device (flash or EEPROM)
-+ *
-+ * The layout of the flash/nvram is as follows:
-+ *
-+ * <type> <length> <data ...> <type> <length> <data ...> <type_end>
-+ *
-+ * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
-+ * The "length" field marks the length of the data section, not
-+ * including the type and length fields.
-+ *
-+ * Environment variables are stored as follows:
-+ *
-+ * <type_env> <length> <flags> <name> = <value>
-+ *
-+ * If bit 0 (low bit) is set, the length is an 8-bit value.
-+ * If bit 0 (low bit) is clear, the length is a 16-bit value
-+ *
-+ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still
-+ * indicates the size of the length field.
-+ *
-+ * Flags are from the constants below:
-+ *
-+ */
-+#define ENV_LENGTH_16BITS 0x00 /* for low bit */
-+#define ENV_LENGTH_8BITS 0x01
-+
-+#define ENV_TYPE_USER 0x80
-+
-+#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
-+#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
-+
-+/*
-+ * The actual TLV types we support
-+ */
-+
-+#define ENV_TLV_TYPE_END 0x00
-+#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
-+
-+/*
-+ * Environment variable flags
-+ */
-+
-+#define ENV_FLG_NORMAL 0x00 /* normal read/write */
-+#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */
-+#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */
-+
-+#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */
-+#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */
-+
-+
-+/* *********************************************************************
-+ * _nvram_read(buffer,offset,length)
-+ *
-+ * Read data from the NVRAM device
-+ *
-+ * Input parameters:
-+ * buffer - destination buffer
-+ * offset - offset of data to read
-+ * length - number of bytes to read
-+ *
-+ * Return value:
-+ * number of bytes read, or <0 if error occured
-+ ********************************************************************* */
-+static int
-+_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
-+{
-+ int i;
-+ if (offset > NVRAM_SIZE)
-+ return -1;
-+
-+ for ( i = 0; i < length; i++) {
-+ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
-+ }
-+ return length;
-+}
-+
-+
-+static char*
-+_strnchr(const char *dest,int c,size_t cnt)
-+{
-+ while (*dest && (cnt > 0)) {
-+ if (*dest == c) return (char *) dest;
-+ dest++;
-+ cnt--;
-+ }
-+ return NULL;
-+}
-+
-+
-+
-+/*
-+ * Core support API: Externally visible.
-+ */
-+
-+/*
-+ * Get the value of an NVRAM variable
-+ * @param name name of variable to get
-+ * @return value of variable or NULL if undefined
-+ */
-+
-+char *cfe_env_get(unsigned char *nv_buf, const char *name)
-+{
-+ int size;
-+ unsigned char *buffer;
-+ unsigned char *ptr;
-+ unsigned char *envval;
-+ unsigned int reclen;
-+ unsigned int rectype;
-+ int offset;
-+ int flg;
-+
-+ if (!strcmp(name, "nvram_type"))
-+ return "cfe";
-+
-+ size = NVRAM_SIZE;
-+ buffer = &_nvdata[0];
-+
-+ ptr = buffer;
-+ offset = 0;
-+
-+ /* Read the record type and length */
-+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
-+ goto error;
-+ }
-+
-+ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
-+
-+ /* Adjust pointer for TLV type */
-+ rectype = *(ptr);
-+ offset++;
-+ size--;
-+
-+ /*
-+ * Read the length. It can be either 1 or 2 bytes
-+ * depending on the code
-+ */
-+ if (rectype & ENV_LENGTH_8BITS) {
-+ /* Read the record type and length - 8 bits */
-+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
-+ goto error;
-+ }
-+ reclen = *(ptr);
-+ size--;
-+ offset++;
-+ }
-+ else {
-+ /* Read the record type and length - 16 bits, MSB first */
-+ if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
-+ goto error;
-+ }
-+ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
-+ size -= 2;
-+ offset += 2;
-+ }
-+
-+ if (reclen > size)
-+ break; /* should not happen, bad NVRAM */
-+
-+ switch (rectype) {
-+ case ENV_TLV_TYPE_ENV:
-+ /* Read the TLV data */
-+ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
-+ goto error;
-+ flg = *ptr++;
-+ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
-+ if (envval) {
-+ *envval++ = '\0';
-+ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
-+ _valuestr[(reclen-1)-(envval-ptr)] = '\0';
-+#if 0
-+ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
-+#endif
-+ if(!strcmp(ptr, name)){
-+ return _valuestr;
-+ }
-+ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
-+ return _valuestr;
-+ }
-+ break;
-+
-+ default:
-+ /* Unknown TLV type, skip it. */
-+ break;
-+ }
-+
-+ /*
-+ * Advance to next TLV
-+ */
-+
-+ size -= (int)reclen;
-+ offset += reclen;
-+
-+ /* Read the next record type */
-+ ptr = buffer;
-+ if (_nvram_read(nv_buf, ptr,offset,1) != 1)
-+ goto error;
-+ }
-+
-+error:
-+ return NULL;
-+
-+}
-+
---- a/drivers/firmware/broadcom/bcm47xx_nvram.c
-+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
-@@ -33,6 +33,8 @@ struct nvram_header {
- static char nvram_buf[NVRAM_SPACE];
- static size_t nvram_len;
- static const u32 nvram_sizes[] = {0x6000, 0x8000, 0xF000, 0x10000};
-+static int cfe_env;
-+extern char *cfe_env_get(char *nv_buf, const char *name);
-
- /**
- * bcm47xx_nvram_is_valid - check for a valid NVRAM at specified memory
-@@ -80,6 +82,26 @@ static int bcm47xx_nvram_find_and_copy(v
- return -EEXIST;
- }
-
-+ cfe_env = 0;
-+
-+ /* XXX: hack for supporting the CFE environment stuff on WGT634U */
-+ if (res_size >= 8 * 1024 * 1024) {
-+ u32 *src = (u32 *)(flash_start + 8 * 1024 * 1024 - 0x2000);
-+ u32 *dst = (u32 *)nvram_buf;
-+
-+ if ((*src & 0xff00ff) == 0x000001) {
-+ printk("early_nvram_init: WGT634U NVRAM found.\n");
-+
-+ for (i = 0; i < 0x1ff0; i++) {
-+ if (*src == 0xFFFFFFFF)
-+ break;
-+ *dst++ = *src++;
-+ }
-+ cfe_env = 1;
-+ return 0;
-+ }
-+ }
-+
- /* TODO: when nvram is on nand flash check for bad blocks first. */
-
- /* Try every possible flash size and check for NVRAM at its end */
-@@ -190,6 +212,13 @@ int bcm47xx_nvram_getenv(const char *nam
- if (!name)
- return -EINVAL;
-
-+ if (cfe_env) {
-+ value = cfe_env_get(nvram_buf, name);
-+ if (!value)
-+ return -ENOENT;
-+ return snprintf(val, val_len, "%s", value);
-+ }
-+
- if (!nvram_len) {
- err = nvram_init();
- if (err)
diff --git a/target/linux/bcm47xx/patches-6.1/830-huawei_e970_support.patch b/target/linux/bcm47xx/patches-6.1/830-huawei_e970_support.patch
deleted file mode 100644
index 1746fee592..0000000000
--- a/target/linux/bcm47xx/patches-6.1/830-huawei_e970_support.patch
+++ /dev/null
@@ -1,101 +0,0 @@
---- a/arch/mips/bcm47xx/setup.c
-+++ b/arch/mips/bcm47xx/setup.c
-@@ -37,6 +37,7 @@
- #include <linux/ssb/ssb.h>
- #include <linux/ssb/ssb_embedded.h>
- #include <linux/bcma/bcma_soc.h>
-+#include <linux/old_gpio_wdt.h>
- #include <asm/bootinfo.h>
- #include <asm/idle.h>
- #include <asm/prom.h>
-@@ -254,6 +255,33 @@ static struct fixed_phy_status bcm47xx_f
- .duplex = DUPLEX_FULL,
- };
-
-+static struct gpio_wdt_platform_data gpio_wdt_data;
-+
-+static struct platform_device gpio_wdt_device = {
-+ .name = "gpio-wdt",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &gpio_wdt_data,
-+ },
-+};
-+
-+static int __init bcm47xx_register_gpio_watchdog(void)
-+{
-+ enum bcm47xx_board board = bcm47xx_board_get();
-+
-+ switch (board) {
-+ case BCM47XX_BOARD_HUAWEI_E970:
-+ pr_info("bcm47xx: detected Huawei E970 or similar, starting early gpio_wdt timer\n");
-+ gpio_wdt_data.gpio = 7;
-+ gpio_wdt_data.interval = HZ;
-+ gpio_wdt_data.first_interval = HZ / 5;
-+ return platform_device_register(&gpio_wdt_device);
-+ default:
-+ /* Nothing to do */
-+ return 0;
-+ }
-+}
-+
- static int __init bcm47xx_register_bus_complete(void)
- {
- switch (bcm47xx_bus_type) {
-@@ -275,6 +303,7 @@ static int __init bcm47xx_register_bus_c
- bcm47xx_workarounds();
-
- fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
-+ bcm47xx_register_gpio_watchdog();
- return 0;
- }
- device_initcall(bcm47xx_register_bus_complete);
---- a/arch/mips/configs/bcm47xx_defconfig
-+++ b/arch/mips/configs/bcm47xx_defconfig
-@@ -63,6 +63,7 @@ CONFIG_HW_RANDOM=y
- CONFIG_GPIO_SYSFS=y
- CONFIG_WATCHDOG=y
- CONFIG_BCM47XX_WDT=y
-+CONFIG_GPIO_WDT=y
- CONFIG_SSB_DRIVER_GIGE=y
- CONFIG_BCMA_DRIVER_GMAC_CMN=y
- CONFIG_USB=y
---- a/drivers/ssb/embedded.c
-+++ b/drivers/ssb/embedded.c
-@@ -34,11 +34,36 @@ int ssb_watchdog_timer_set(struct ssb_bu
- }
- EXPORT_SYMBOL(ssb_watchdog_timer_set);
-
-+#ifdef CONFIG_BCM47XX
-+#include <bcm47xx_board.h>
-+
-+static bool ssb_watchdog_supported(void)
-+{
-+ enum bcm47xx_board board = bcm47xx_board_get();
-+
-+ /* The Huawei E970 has a hardware watchdog using a GPIO */
-+ switch (board) {
-+ case BCM47XX_BOARD_HUAWEI_E970:
-+ return false;
-+ default:
-+ return true;
-+ }
-+}
-+#else
-+static bool ssb_watchdog_supported(void)
-+{
-+ return true;
-+}
-+#endif
-+
- int ssb_watchdog_register(struct ssb_bus *bus)
- {
- struct bcm47xx_wdt wdt = {};
- struct platform_device *pdev;
-
-+ if (!ssb_watchdog_supported())
-+ return 0;
-+
- if (ssb_chipco_available(&bus->chipco)) {
- wdt.driver_data = &bus->chipco;
- wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt;
diff --git a/target/linux/bcm47xx/patches-6.1/831-old_gpio_wdt.patch b/target/linux/bcm47xx/patches-6.1/831-old_gpio_wdt.patch
deleted file mode 100644
index 55639c6d2e..0000000000
--- a/target/linux/bcm47xx/patches-6.1/831-old_gpio_wdt.patch
+++ /dev/null
@@ -1,360 +0,0 @@
-This generic GPIO watchdog is used on Huawei E970 (bcm47xx)
-
-Signed-off-by: Mathias Adam <m.adam--openwrt@adamis.de>
-
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -1728,6 +1728,15 @@ config WDT_MTX1
- Hardware driver for the MTX-1 boards. This is a watchdog timer that
- will reboot the machine after a 100 seconds timer expired.
-
-+config GPIO_WDT
-+ tristate "GPIO Hardware Watchdog"
-+ help
-+ Hardware driver for GPIO-controlled watchdogs. GPIO pin and
-+ toggle interval settings are platform-specific. The driver
-+ will stop toggling the GPIO (i.e. machine reboots) after a
-+ 100 second timer expired and no process has written to
-+ /dev/watchdog during that time.
-+
- config SIBYTE_WDOG
- tristate "Sibyte SoC hardware watchdog"
- depends on CPU_SB1
---- a/drivers/watchdog/Makefile
-+++ b/drivers/watchdog/Makefile
-@@ -164,6 +164,7 @@ obj-$(CONFIG_RC32434_WDT) += rc32434_wdt
- obj-$(CONFIG_INDYDOG) += indydog.o
- obj-$(CONFIG_JZ4740_WDT) += jz4740_wdt.o
- obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
-+obj-$(CONFIG_GPIO_WDT) += old_gpio_wdt.o
- obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
- obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
- obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
---- /dev/null
-+++ b/drivers/watchdog/old_gpio_wdt.c
-@@ -0,0 +1,301 @@
-+/*
-+ * Driver for GPIO-controlled Hardware Watchdogs.
-+ *
-+ * Copyright (C) 2013 Mathias Adam <m.adam--linux@adamis.de>
-+ *
-+ * Replaces mtx1_wdt (driver for the MTX-1 Watchdog):
-+ *
-+ * (C) Copyright 2005 4G Systems <info@4g-systems.biz>,
-+ * All Rights Reserved.
-+ * http://www.4g-systems.biz
-+ *
-+ * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
-+ *
-+ * 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.
-+ *
-+ * Neither Michael Stickel nor 4G Systems admit liability nor provide
-+ * warranty for any of this software. This material is provided
-+ * "AS-IS" and at no charge.
-+ *
-+ * (c) Copyright 2005 4G Systems <info@4g-systems.biz>
-+ *
-+ * Release 0.01.
-+ * Author: Michael Stickel michael.stickel@4g-systems.biz
-+ *
-+ * Release 0.02.
-+ * Author: Florian Fainelli florian@openwrt.org
-+ * use the Linux watchdog/timer APIs
-+ *
-+ * Release 0.03.
-+ * Author: Mathias Adam <m.adam--linux@adamis.de>
-+ * make it a generic gpio watchdog driver
-+ *
-+ * The Watchdog is configured to reset the MTX-1
-+ * if it is not triggered for 100 seconds.
-+ * It should not be triggered more often than 1.6 seconds.
-+ *
-+ * A timer triggers the watchdog every 5 seconds, until
-+ * it is opened for the first time. After the first open
-+ * it MUST be triggered every 2..95 seconds.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/fs.h>
-+#include <linux/init.h>
-+#include <linux/ioport.h>
-+#include <linux/timer.h>
-+#include <linux/completion.h>
-+#include <linux/jiffies.h>
-+#include <linux/watchdog.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/uaccess.h>
-+#include <linux/gpio.h>
-+#include <linux/old_gpio_wdt.h>
-+
-+static int ticks = 100 * HZ;
-+
-+static struct {
-+ struct completion stop;
-+ spinlock_t lock;
-+ int running;
-+ struct timer_list timer;
-+ int queue;
-+ int default_ticks;
-+ unsigned long inuse;
-+ unsigned gpio;
-+ unsigned int gstate;
-+ int interval;
-+ int first_interval;
-+} gpio_wdt_device;
-+
-+static void gpio_wdt_trigger(struct timer_list *unused)
-+{
-+ spin_lock(&gpio_wdt_device.lock);
-+ if (gpio_wdt_device.running && ticks > 0)
-+ ticks -= gpio_wdt_device.interval;
-+
-+ /* toggle wdt gpio */
-+ gpio_wdt_device.gstate = !gpio_wdt_device.gstate;
-+ gpio_set_value(gpio_wdt_device.gpio, gpio_wdt_device.gstate);
-+
-+ if (gpio_wdt_device.queue && ticks > 0)
-+ mod_timer(&gpio_wdt_device.timer, jiffies + gpio_wdt_device.interval);
-+ else
-+ complete(&gpio_wdt_device.stop);
-+ spin_unlock(&gpio_wdt_device.lock);
-+}
-+
-+static void gpio_wdt_reset(void)
-+{
-+ ticks = gpio_wdt_device.default_ticks;
-+}
-+
-+
-+static void gpio_wdt_start(void)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&gpio_wdt_device.lock, flags);
-+ if (!gpio_wdt_device.queue) {
-+ gpio_wdt_device.queue = 1;
-+ gpio_wdt_device.gstate = 1;
-+ gpio_set_value(gpio_wdt_device.gpio, 1);
-+ mod_timer(&gpio_wdt_device.timer, jiffies + gpio_wdt_device.first_interval);
-+ }
-+ gpio_wdt_device.running++;
-+ spin_unlock_irqrestore(&gpio_wdt_device.lock, flags);
-+}
-+
-+static int gpio_wdt_stop(void)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&gpio_wdt_device.lock, flags);
-+ if (gpio_wdt_device.queue) {
-+ gpio_wdt_device.queue = 0;
-+ gpio_wdt_device.gstate = 0;
-+ gpio_set_value(gpio_wdt_device.gpio, 0);
-+ }
-+ ticks = gpio_wdt_device.default_ticks;
-+ spin_unlock_irqrestore(&gpio_wdt_device.lock, flags);
-+ return 0;
-+}
-+
-+/* Filesystem functions */
-+
-+static int gpio_wdt_open(struct inode *inode, struct file *file)
-+{
-+ if (test_and_set_bit(0, &gpio_wdt_device.inuse))
-+ return -EBUSY;
-+ return nonseekable_open(inode, file);
-+}
-+
-+
-+static int gpio_wdt_release(struct inode *inode, struct file *file)
-+{
-+ clear_bit(0, &gpio_wdt_device.inuse);
-+ return 0;
-+}
-+
-+static long gpio_wdt_ioctl(struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ void __user *argp = (void __user *)arg;
-+ int __user *p = (int __user *)argp;
-+ unsigned int value;
-+ static const struct watchdog_info ident = {
-+ .options = WDIOF_CARDRESET,
-+ .identity = "GPIO WDT",
-+ };
-+
-+ switch (cmd) {
-+ case WDIOC_GETSUPPORT:
-+ if (copy_to_user(argp, &ident, sizeof(ident)))
-+ return -EFAULT;
-+ break;
-+ case WDIOC_GETSTATUS:
-+ case WDIOC_GETBOOTSTATUS:
-+ put_user(0, p);
-+ break;
-+ case WDIOC_SETOPTIONS:
-+ if (get_user(value, p))
-+ return -EFAULT;
-+ if (value & WDIOS_ENABLECARD)
-+ gpio_wdt_start();
-+ else if (value & WDIOS_DISABLECARD)
-+ gpio_wdt_stop();
-+ else
-+ return -EINVAL;
-+ return 0;
-+ case WDIOC_KEEPALIVE:
-+ gpio_wdt_reset();
-+ break;
-+ default:
-+ return -ENOTTY;
-+ }
-+ return 0;
-+}
-+
-+
-+static ssize_t gpio_wdt_write(struct file *file, const char *buf,
-+ size_t count, loff_t *ppos)
-+{
-+ if (!count)
-+ return -EIO;
-+ gpio_wdt_reset();
-+ return count;
-+}
-+
-+static const struct file_operations gpio_wdt_fops = {
-+ .owner = THIS_MODULE,
-+ .llseek = no_llseek,
-+ .unlocked_ioctl = gpio_wdt_ioctl,
-+ .open = gpio_wdt_open,
-+ .write = gpio_wdt_write,
-+ .release = gpio_wdt_release,
-+};
-+
-+
-+static struct miscdevice gpio_wdt_misc = {
-+ .minor = WATCHDOG_MINOR,
-+ .name = "watchdog",
-+ .fops = &gpio_wdt_fops,
-+};
-+
-+
-+static int gpio_wdt_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ struct gpio_wdt_platform_data *gpio_wdt_data = pdev->dev.platform_data;
-+
-+ gpio_wdt_device.gpio = gpio_wdt_data->gpio;
-+ gpio_wdt_device.interval = gpio_wdt_data->interval;
-+ gpio_wdt_device.first_interval = gpio_wdt_data->first_interval;
-+ if (gpio_wdt_device.first_interval <= 0) {
-+ gpio_wdt_device.first_interval = gpio_wdt_device.interval;
-+ }
-+
-+ ret = gpio_request(gpio_wdt_device.gpio, "gpio-wdt");
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "failed to request gpio");
-+ return ret;
-+ }
-+
-+ spin_lock_init(&gpio_wdt_device.lock);
-+ init_completion(&gpio_wdt_device.stop);
-+ gpio_wdt_device.queue = 0;
-+ clear_bit(0, &gpio_wdt_device.inuse);
-+ timer_setup(&gpio_wdt_device.timer, gpio_wdt_trigger, 0L);
-+ gpio_wdt_device.default_ticks = ticks;
-+
-+ gpio_wdt_start();
-+ dev_info(&pdev->dev, "GPIO Hardware Watchdog driver (gpio=%i interval=%i/%i)\n",
-+ gpio_wdt_data->gpio, gpio_wdt_data->first_interval, gpio_wdt_data->interval);
-+ return 0;
-+}
-+
-+static int gpio_wdt_remove(struct platform_device *pdev)
-+{
-+ /* FIXME: do we need to lock this test ? */
-+ if (gpio_wdt_device.queue) {
-+ gpio_wdt_device.queue = 0;
-+ wait_for_completion(&gpio_wdt_device.stop);
-+ }
-+
-+ gpio_free(gpio_wdt_device.gpio);
-+ misc_deregister(&gpio_wdt_misc);
-+ return 0;
-+}
-+
-+static struct platform_driver gpio_wdt_driver = {
-+ .probe = gpio_wdt_probe,
-+ .remove = gpio_wdt_remove,
-+ .driver.name = "gpio-wdt",
-+ .driver.owner = THIS_MODULE,
-+};
-+
-+static int __init gpio_wdt_init(void)
-+{
-+ return platform_driver_register(&gpio_wdt_driver);
-+}
-+arch_initcall(gpio_wdt_init);
-+
-+/*
-+ * We do wdt initialization in two steps: arch_initcall probes the wdt
-+ * very early to start pinging the watchdog (misc devices are not yet
-+ * available), and later module_init() just registers the misc device.
-+ */
-+static int gpio_wdt_init_late(void)
-+{
-+ int ret;
-+
-+ ret = misc_register(&gpio_wdt_misc);
-+ if (ret < 0) {
-+ pr_err("GPIO_WDT: failed to register misc device\n");
-+ return ret;
-+ }
-+ return 0;
-+}
-+#ifndef MODULE
-+module_init(gpio_wdt_init_late);
-+#endif
-+
-+static void __exit gpio_wdt_exit(void)
-+{
-+ platform_driver_unregister(&gpio_wdt_driver);
-+}
-+module_exit(gpio_wdt_exit);
-+
-+MODULE_AUTHOR("Michael Stickel, Florian Fainelli, Mathias Adam");
-+MODULE_DESCRIPTION("Driver for GPIO hardware watchdogs");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-+MODULE_ALIAS("platform:gpio-wdt");
---- /dev/null
-+++ b/include/linux/old_gpio_wdt.h
-@@ -0,0 +1,21 @@
-+/*
-+ * Definitions for the GPIO watchdog driver
-+ *
-+ * Copyright (C) 2013 Mathias Adam <m.adam--linux@adamis.de>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#ifndef _GPIO_WDT_H_
-+#define _GPIO_WDT_H_
-+
-+struct gpio_wdt_platform_data {
-+ int gpio; /* GPIO line number */
-+ int interval; /* watchdog reset interval in system ticks */
-+ int first_interval; /* first wd reset interval in system ticks */
-+};
-+
-+#endif /* _GPIO_WDT_H_ */
diff --git a/target/linux/bcm47xx/patches-6.1/900-ssb-reject-PCI-writes-setting-CardBus-bridge-resourc.patch b/target/linux/bcm47xx/patches-6.1/900-ssb-reject-PCI-writes-setting-CardBus-bridge-resourc.patch
deleted file mode 100644
index 970e36eb68..0000000000
--- a/target/linux/bcm47xx/patches-6.1/900-ssb-reject-PCI-writes-setting-CardBus-bridge-resourc.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 5c81397a0147ea59c778d1de14ef54e2268221f6 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Wed, 8 Apr 2015 06:58:11 +0200
-Subject: [PATCH] ssb: reject PCI writes setting CardBus bridge resources
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-If SoC has a CardBus we can set resources of device at slot 1 only. It's
-impossigle to set bridge resources as it simply overwrites device 1
-configuration and usually results in Data bus error-s.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/ssb/driver_pcicore.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/ssb/driver_pcicore.c
-+++ b/drivers/ssb/driver_pcicore.c
-@@ -165,6 +165,10 @@ static int ssb_extpci_write_config(struc
- WARN_ON(!pc->hostmode);
- if (unlikely(len != 1 && len != 2 && len != 4))
- goto out;
-+ /* CardBus SoCs allow configuring dev 1 resources only */
-+ if (extpci_core->cardbusmode && dev != 1 &&
-+ off >= PCI_BASE_ADDRESS_0 && off <= PCI_BASE_ADDRESS_5)
-+ goto out;
- addr = get_cfgspace_addr(pc, bus, dev, func, off);
- if (unlikely(!addr))
- goto out;
diff --git a/target/linux/bcm47xx/patches-6.1/940-bcm47xx-yenta.patch b/target/linux/bcm47xx/patches-6.1/940-bcm47xx-yenta.patch
deleted file mode 100644
index f1b46c2ce4..0000000000
--- a/target/linux/bcm47xx/patches-6.1/940-bcm47xx-yenta.patch
+++ /dev/null
@@ -1,48 +0,0 @@
---- a/drivers/pcmcia/yenta_socket.c
-+++ b/drivers/pcmcia/yenta_socket.c
-@@ -925,6 +925,8 @@ static struct cardbus_type cardbus_type[
-
- static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
- {
-+/* WRT54G3G does not like this */
-+#ifndef CONFIG_BCM47XX
- int i;
- unsigned long val;
- u32 mask;
-@@ -953,6 +955,9 @@ static unsigned int yenta_probe_irq(stru
- mask = probe_irq_mask(val) & 0xffff;
-
- return mask;
-+#else
-+ return 0;
-+#endif
- }
-
-
-@@ -1033,6 +1038,10 @@ static void yenta_get_socket_capabilitie
- else
- socket->socket.irq_mask = 0;
-
-+ /* irq mask probing is broken for the WRT54G3G */
-+ if (socket->socket.irq_mask == 0)
-+ socket->socket.irq_mask = 0x6f8;
-+
- dev_info(&socket->dev->dev, "ISA IRQ mask 0x%04x, PCI irq %d\n",
- socket->socket.irq_mask, socket->cb_irq);
- }
-@@ -1264,6 +1273,15 @@ static int yenta_probe(struct pci_dev *d
- dev_info(&dev->dev, "Socket status: %08x\n",
- cb_readl(socket, CB_SOCKET_STATE));
-
-+ /* Generate an interrupt on card insert/remove */
-+ config_writew(socket, CB_SOCKET_MASK, CB_CSTSMASK | CB_CDMASK);
-+
-+ /* Set up Multifunction Routing Status Register */
-+ config_writew(socket, 0x8C, 0x1000 /* MFUNC3 to GPIO3 */ | 0x2 /* MFUNC0 to INTA */);
-+
-+ /* Switch interrupts to parallelized */
-+ config_writeb(socket, 0x92, 0x64);
-+
- yenta_fixup_parent_bridge(dev->subordinate);
-
- /* Register it with the pcmcia layer.. */
diff --git a/target/linux/bcm47xx/patches-6.1/976-ssb_increase_pci_delay.patch b/target/linux/bcm47xx/patches-6.1/976-ssb_increase_pci_delay.patch
deleted file mode 100644
index 201be1b187..0000000000
--- a/target/linux/bcm47xx/patches-6.1/976-ssb_increase_pci_delay.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/ssb/driver_pcicore.c
-+++ b/drivers/ssb/driver_pcicore.c
-@@ -394,7 +394,7 @@ static void ssb_pcicore_init_hostmode(st
- /* Give some time to the PCI controller to configure itself with the new
- * values. Not waiting at this point causes crashes of the machine.
- */
-- mdelay(10);
-+ mdelay(300);
- register_pci_controller(&ssb_pcicore_controller);
- }
-
diff --git a/target/linux/bcm47xx/patches-6.6/160-kmap_coherent.patch b/target/linux/bcm47xx/patches-6.6/160-kmap_coherent.patch
deleted file mode 100644
index 19ab8df7c4..0000000000
--- a/target/linux/bcm47xx/patches-6.6/160-kmap_coherent.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From: Jeff Hansen <jhansen@cardaccess-inc.com>
-Subject: [PATCH] kmap_coherent
-
-On ASUS WL-500gP there are some "Data bus error"s when executing simple
-commands liks "ps" or "cat /proc/1/cmdline".
-
-This fixes OpenWrt ticket #1485: https://dev.openwrt.org/ticket/1485
----
---- a/arch/mips/include/asm/cpu-features.h
-+++ b/arch/mips/include/asm/cpu-features.h
-@@ -257,6 +257,9 @@
- #ifndef cpu_has_pindexed_dcache
- #define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
- #endif
-+#ifndef cpu_use_kmap_coherent
-+#define cpu_use_kmap_coherent 1
-+#endif
-
- /*
- * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
---- a/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
-+++ b/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
-@@ -79,4 +79,6 @@
- #define cpu_scache_line_size() 0
- #define cpu_has_vz 0
-
-+#define cpu_use_kmap_coherent 0
-+
- #endif /* __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H */
---- a/arch/mips/mm/c-r4k.c
-+++ b/arch/mips/mm/c-r4k.c
-@@ -618,7 +618,7 @@ static inline void local_r4k_flush_cache
- }
-
- if (vaddr) {
-- if (map_coherent)
-+ if (map_coherent && cpu_use_kmap_coherent)
- kunmap_coherent();
- else
- kunmap_atomic(vaddr);
---- a/arch/mips/mm/init.c
-+++ b/arch/mips/mm/init.c
-@@ -173,7 +173,7 @@ void copy_user_highpage(struct page *to,
- void *vfrom, *vto;
-
- vto = kmap_atomic(to);
-- if (cpu_has_dc_aliases &&
-+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
- folio_mapped(src) && !folio_test_dcache_dirty(src)) {
- vfrom = kmap_coherent(from, vaddr);
- copy_page(vto, vfrom);
-@@ -197,7 +197,7 @@ void copy_to_user_page(struct vm_area_st
- {
- struct folio *folio = page_folio(page);
-
-- if (cpu_has_dc_aliases &&
-+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
- folio_mapped(folio) && !folio_test_dcache_dirty(folio)) {
- void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
- memcpy(vto, src, len);
-@@ -217,7 +217,7 @@ void copy_from_user_page(struct vm_area_
- {
- struct folio *folio = page_folio(page);
-
-- if (cpu_has_dc_aliases &&
-+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
- folio_mapped(folio) && !folio_test_dcache_dirty(folio)) {
- void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
- memcpy(dst, vfrom, len);
diff --git a/target/linux/bcm47xx/patches-6.6/300-fork_cacheflush.patch b/target/linux/bcm47xx/patches-6.6/300-fork_cacheflush.patch
deleted file mode 100644
index daa2c1adf0..0000000000
--- a/target/linux/bcm47xx/patches-6.6/300-fork_cacheflush.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Wolfram Joost <dbox2@frokaschwei.de>
-Subject: [PATCH] fork_cacheflush
-
-On ASUS WL-500gP there are many unexpected "Segmentation fault"s that
-seem to be caused by a kernel. They can be avoided by:
-1) Disabling highpage
-2) Using flush_cache_mm in flush_cache_dup_mm
-
-For details see OpenWrt ticket #2035 https://dev.openwrt.org/ticket/2035
----
---- a/arch/mips/include/asm/cacheflush.h
-+++ b/arch/mips/include/asm/cacheflush.h
-@@ -46,7 +46,7 @@
- extern void (*flush_cache_all)(void);
- extern void (*__flush_cache_all)(void);
- extern void (*flush_cache_mm)(struct mm_struct *mm);
--#define flush_cache_dup_mm(mm) do { (void) (mm); } while (0)
-+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
- extern void (*flush_cache_range)(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
- extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
diff --git a/target/linux/bcm47xx/patches-6.6/310-no_highpage.patch b/target/linux/bcm47xx/patches-6.6/310-no_highpage.patch
deleted file mode 100644
index 7a4cd6ed90..0000000000
--- a/target/linux/bcm47xx/patches-6.6/310-no_highpage.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From: Jeff Hansen <jhansen@cardaccess-inc.com>
-Subject: [PATCH] no highpage
-
-On ASUS WL-500gP there are many unexpected "Segmentation fault"s that
-seem to be caused by a kernel. They can be avoided by:
-1) Disabling highpage
-2) Using flush_cache_mm in flush_cache_dup_mm
-
-For details see OpenWrt ticket #2035 https://dev.openwrt.org/ticket/2035
----
---- a/arch/mips/include/asm/page.h
-+++ b/arch/mips/include/asm/page.h
-@@ -71,6 +71,7 @@ static inline unsigned int page_size_ftl
- #endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
-
- #include <linux/pfn.h>
-+#include <asm/cpu-features.h>
-
- extern void build_clear_page(void);
- extern void build_copy_page(void);
-@@ -110,11 +111,16 @@ static inline void clear_user_page(void
- flush_data_cache_page((unsigned long)addr);
- }
-
--struct vm_area_struct;
--extern void copy_user_highpage(struct page *to, struct page *from,
-- unsigned long vaddr, struct vm_area_struct *vma);
-+static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
-+ struct page *to)
-+{
-+ extern void (*flush_data_cache_page)(unsigned long addr);
-
--#define __HAVE_ARCH_COPY_USER_HIGHPAGE
-+ copy_page(vto, vfrom);
-+ if (!cpu_has_ic_fills_f_dc ||
-+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
-+ flush_data_cache_page((unsigned long)vto);
-+}
-
- /*
- * These are used to make use of C type-checking..
---- a/arch/mips/mm/init.c
-+++ b/arch/mips/mm/init.c
-@@ -166,31 +166,6 @@ void kunmap_coherent(void)
- preempt_enable();
- }
-
--void copy_user_highpage(struct page *to, struct page *from,
-- unsigned long vaddr, struct vm_area_struct *vma)
--{
-- struct folio *src = page_folio(from);
-- void *vfrom, *vto;
--
-- vto = kmap_atomic(to);
-- if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
-- folio_mapped(src) && !folio_test_dcache_dirty(src)) {
-- vfrom = kmap_coherent(from, vaddr);
-- copy_page(vto, vfrom);
-- kunmap_coherent();
-- } else {
-- vfrom = kmap_atomic(from);
-- copy_page(vto, vfrom);
-- kunmap_atomic(vfrom);
-- }
-- if ((!cpu_has_ic_fills_f_dc) ||
-- pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
-- flush_data_cache_page((unsigned long)vto);
-- kunmap_atomic(vto);
-- /* Make sure this page is cleared on other CPU's too before using it */
-- smp_wmb();
--}
--
- void copy_to_user_page(struct vm_area_struct *vma,
- struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
diff --git a/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch b/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch
index 21ab40206f..08813da1ba 100644
--- a/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch
+++ b/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch
@@ -1,14 +1,14 @@
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
-@@ -37,6 +37,7 @@
- #include <linux/ssb/ssb.h>
+@@ -38,6 +38,7 @@
#include <linux/ssb/ssb_embedded.h>
#include <linux/bcma/bcma_soc.h>
+ #include <asm/bmips.h>
+#include <linux/old_gpio_wdt.h>
#include <asm/bootinfo.h>
#include <asm/idle.h>
#include <asm/prom.h>
-@@ -254,6 +255,33 @@ static struct fixed_phy_status bcm47xx_f
+@@ -262,6 +263,33 @@ static struct fixed_phy_status bcm47xx_f
.duplex = DUPLEX_FULL,
};
@@ -42,7 +42,7 @@
static int __init bcm47xx_register_bus_complete(void)
{
switch (bcm47xx_bus_type) {
-@@ -275,6 +303,7 @@ static int __init bcm47xx_register_bus_c
+@@ -283,6 +311,7 @@ static int __init bcm47xx_register_bus_c
bcm47xx_workarounds();
fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
diff --git a/target/linux/bcm4908/Makefile b/target/linux/bcm4908/Makefile
index b4d238eff6..2d12bd7815 100644
--- a/target/linux/bcm4908/Makefile
+++ b/target/linux/bcm4908/Makefile
@@ -9,8 +9,7 @@ FEATURES:=squashfs nand usb gpio
CPU_TYPE:=cortex-a53
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Broadcom BCM4908 SoC family routers.
diff --git a/target/linux/bcm4908/config-6.1 b/target/linux/bcm4908/config-6.1
deleted file mode 100644
index 086d387bc7..0000000000
--- a/target/linux/bcm4908/config-6.1
+++ /dev/null
@@ -1,245 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_ARCH_BCM=y
-CONFIG_ARCH_BCMBCA=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_KEEP_MEMBLOCK=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_MIN=11
-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_LD_HAS_FIX_ERRATUM_843419=y
-CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PA_BITS=48
-CONFIG_ARM64_PA_BITS_48=y
-CONFIG_ARM64_PTR_AUTH=y
-CONFIG_ARM64_PTR_AUTH_KERNEL=y
-CONFIG_ARM64_SVE=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_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-CONFIG_ARM_PSCI_FW=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_B53=y
-CONFIG_BCM4908_ENET=y
-CONFIG_BCM7038_WDT=y
-CONFIG_BCM7XXX_PHY=y
-CONFIG_BCM_NET_PHYLIB=y
-CONFIG_BCM_PMB=y
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_BLK_PM=y
-CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
-CONFIG_CLK_BCM_63XX=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640 console=ttyS0,115200"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_COMMON_CLK=y
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_RMAP=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_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_SIMD=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_REMAP=y
-CONFIG_DTC=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FRAME_POINTER=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_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GRO_CELLS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_BRCMSTB=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_LEDS_BCM63138=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BCM_UNIMAC=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MTD_BRCM_U_BOOT=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_NAND_BRCMNAND=y
-CONFIG_MTD_NAND_BRCMNAND_BCMBCA=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_OF_PARTS_BCM4908=y
-# CONFIG_MTD_OF_PARTS_LINKSYS_NS is not set
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPLIT_CFE_BOOTFS=y
-# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-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_BCM_SF2=y
-CONFIG_NET_DSA_TAG_BRCM=y
-CONFIG_NET_DSA_TAG_BRCM_COMMON=y
-CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
-CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NO_IOPORT_MAP=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_NVMEM_U_BOOT_ENV=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PADATA=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-# CONFIG_PHY_BRCM_SATA is not set
-CONFIG_PHY_BRCM_USB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_BCM4908=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RELOCATABLE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_BCM63XX=y
-CONFIG_SERIAL_BCM63XX_CONSOLE=y
-CONFIG_SGL_ALLOC=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_SRCU=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_USB_SUPPORT=y
-CONFIG_VMAP_STACK=y
-CONFIG_WATCHDOG_CORE=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
diff --git a/target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch b/target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch
deleted file mode 100644
index e175f27891..0000000000
--- a/target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 68064196cffea33f090bd2e8d81cd5e20107ecf1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 3 Nov 2022 11:53:16 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add TWD block timer
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM4908 TWD contains block with 4 timers. Add binding for it.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221103105316.21294-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -280,6 +280,11 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ timer@0 {
-+ compatible = "brcm,bcm63138-timer";
-+ reg = <0x0 0x28>;
-+ };
-+
- watchdog@28 {
- compatible = "brcm,bcm6345-wdt";
- reg = <0x28 0x8>;
diff --git a/target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch b/target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch
deleted file mode 100644
index e8e81ae544..0000000000
--- a/target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 4f9fb09175e87a233787a2dee1e5dabb14deb022 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 3 Nov 2022 12:00:15 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm6858: add TWD block
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM6858 contains TWD block with timers, watchdog, and reset subblocks.
-Describe it.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221103110015.21761-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/broadcom/bcmbca/bcm6858.dtsi | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-@@ -109,6 +109,25 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x62000>;
-
-+ twd: timer-mfd@400 {
-+ compatible = "brcm,bcm4908-twd", "simple-mfd", "syscon";
-+ reg = <0x400 0x4c>;
-+ ranges = <0x0 0x400 0x4c>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ timer@0 {
-+ compatible = "brcm,bcm63138-timer";
-+ reg = <0x0 0x28>;
-+ };
-+
-+ watchdog@28 {
-+ compatible = "brcm,bcm6345-wdt";
-+ reg = <0x28 0x8>;
-+ };
-+ };
-+
- uart0: serial@640 {
- compatible = "brcm,bcm6345-uart";
- reg = <0x640 0x18>;
diff --git a/target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch b/target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch
deleted file mode 100644
index a19ab8cf8f..0000000000
--- a/target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From e567e58d6819adc002c57b81e16b88da24d3b4aa Mon Sep 17 00:00:00 2001
-From: Pierre Gondois <pierre.gondois@arm.com>
-Date: Tue, 22 Nov 2022 17:32:07 +0100
-Subject: [PATCH] arm64: dts: Update cache properties for broadcom
-
-The DeviceTree Specification v0.3 specifies that the cache node
-'compatible' and 'cache-level' properties are 'required'. Cf.
-s3.8 Multi-level and Shared Cache Nodes
-The 'cache-unified' property should be present if one of the
-properties for unified cache is present ('cache-size', ...).
-
-Update the Device Trees accordingly.
-
-Acked-by: William Zhang <william.zhang@broadcom.com>
-Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
-Link: https://lore.kernel.org/r/20221122163208.3810985-3-pierre.gondois@arm.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi | 4 ++++
- 9 files changed, 12 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -63,6 +63,7 @@
-
- l2: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-@@ -51,6 +51,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-@@ -35,6 +35,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-@@ -51,6 +51,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-@@ -51,6 +51,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-@@ -35,6 +35,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-@@ -50,6 +50,7 @@
- };
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
-@@ -79,6 +79,7 @@
-
- CLUSTER0_L2: l2-cache@0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
-@@ -108,18 +108,22 @@
-
- CLUSTER0_L2: l2-cache@0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
-
- CLUSTER1_L2: l2-cache@100 {
- compatible = "cache";
-+ cache-level = <2>;
- };
-
- CLUSTER2_L2: l2-cache@200 {
- compatible = "cache";
-+ cache-level = <2>;
- };
-
- CLUSTER3_L2: l2-cache@300 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch
deleted file mode 100644
index 7476aed05b..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch
+++ /dev/null
@@ -1,367 +0,0 @@
-From f5d83b714e304d5f3229da434af2eeea033c4f5d Mon Sep 17 00:00:00 2001
-From: William Zhang <william.zhang@broadcom.com>
-Date: Mon, 6 Feb 2023 22:58:15 -0800
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: Add spi controller node
-
-Add support for HSSPI controller in ARMv8 chip dts files.
-
-Signed-off-by: William Zhang <william.zhang@broadcom.com>
-Link: https://lore.kernel.org/r/20230207065826.285013-5-william.zhang@broadcom.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/broadcom/bcmbca/bcm4908.dtsi | 18 +++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm4912.dtsi | 20 +++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm63146.dtsi | 19 ++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm63158.dtsi | 19 ++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm6813.dtsi | 20 +++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm6856.dtsi | 18 +++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm6858.dtsi | 18 +++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm94908.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm94912.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm963146.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm963158.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm96813.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm96856.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm96858.dts | 4 ++++
- 14 files changed, 160 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -107,6 +107,12 @@
- clock-frequency = <50000000>;
- clock-output-names = "periph";
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- soc {
-@@ -528,6 +534,18 @@
- #size-cells = <0>;
- };
-
-+ hsspi: spi@1000{
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm4908-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- nand-controller@1800 {
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-@@ -79,6 +79,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -86,6 +87,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <200000000>;
-+ };
- };
-
- psci {
-@@ -117,6 +124,19 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm4912-hsspi", "brcm,bcmbca-hsspi-v1.1";
-+ reg = <0x1000 0x600>, <0x2610 0x4>;
-+ reg-names = "hsspi", "spim-ctrl";
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-@@ -60,6 +60,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -67,6 +68,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <200000000>;
-+ };
- };
-
- psci {
-@@ -99,6 +106,18 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm63146-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-@@ -79,6 +79,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -86,6 +87,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- psci {
-@@ -117,6 +124,18 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm63158-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-@@ -79,6 +79,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -86,6 +87,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <200000000>;
-+ };
- };
-
- psci {
-@@ -117,6 +124,19 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm6813-hsspi", "brcm,bcmbca-hsspi-v1.1";
-+ reg = <0x1000 0x600>, <0x2610 0x4>;
-+ reg-names = "hsspi", "spim-ctrl";
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-@@ -60,6 +60,12 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- psci {
-@@ -100,5 +106,17 @@
- clock-names = "refclk";
- status = "disabled";
- };
-+
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm6856-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-@@ -78,6 +78,12 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- psci {
-@@ -137,5 +143,17 @@
- clock-names = "refclk";
- status = "disabled";
- };
-+
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm6858-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch
deleted file mode 100644
index 47b2455ae6..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 477cad715de1dfc256a20da3ed83b62f3cb2944d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 28 Feb 2023 15:45:18 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add on-SoC USB ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM4908 has 3 USB controllers each with 2 USB ports. Home routers often
-have LEDs indicating state of selected USB ports. Describe those SoC USB
-ports to allow using them as LED trigger sources.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/all/20230228144520.21816-1-zajec5@gmail.com/
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/broadcom/bcmbca/bcm4908.dtsi | 39 +++++++++++++++++++
- 1 file changed, 39 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -148,6 +148,19 @@
- interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&usb_phy PHY_TYPE_USB2>;
- status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ehci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ehci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
- };
-
- ohci: usb@c400 {
-@@ -156,6 +169,19 @@
- interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&usb_phy PHY_TYPE_USB2>;
- status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ohci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ohci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
- };
-
- xhci: usb@d000 {
-@@ -164,6 +190,19 @@
- interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&usb_phy PHY_TYPE_USB3>;
- status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ xhci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ xhci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
- };
-
- bus@80000 {
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch
deleted file mode 100644
index 3e210d68e1..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 889e53ccccc29ff4bf8d4c89cca34e8768845747 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 28 Feb 2023 15:45:19 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add Netgear R8000P USB
- LED triggers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This device has 2 USB LEDs meant to be triggered by devices in relevant
-USB ports.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/all/20230228144520.21816-2-zajec5@gmail.com/
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
-@@ -58,12 +58,16 @@
- function = "usb2";
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
- };
-
- led-usb3 {
- function = "usb3";
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port2>, <&ehci_port2>, <&xhci_port2>;
-+ linux,default-trigger = "usbport";
- };
-
- led-wifi {
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch
deleted file mode 100644
index 959ccd4fa3..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From e6d356b146b75f1f77621aab7950a1eb550859f9 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 28 Feb 2023 15:45:20 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add TP-Link C2300 USB
- LED triggers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This device has 2 USB LEDs meant to be triggered by devices in relevant
-USB ports.
-
-While at it fix typo in USB LED name.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/all/20230228144520.21816-3-zajec5@gmail.com/
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
-@@ -64,12 +64,16 @@
- function = "usb2";
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
- };
-
- led-usb3 {
-- function = "usbd3";
-+ function = "usb3";
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port2>, <&ehci_port2>, <&xhci_port2>;
-+ linux,default-trigger = "usbport";
- };
-
- led-brightness {
diff --git a/target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch b/target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch
deleted file mode 100644
index 1b4cc9e24c..0000000000
--- a/target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 3a1cc23a75abcd9cea585eb84846507363d58397 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 25 Oct 2022 15:22:45 +0200
-Subject: [PATCH] net: broadcom: bcm4908_enet: use build_skb()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-RX code can be more efficient with the build_skb(). Allocating actual
-SKB around eth packet buffer - right before passing it up - results in
-a better cache usage.
-
-Without RPS (echo 0 > rps_cpus) BCM4908 NAT masq performance "jumps"
-between two speeds: ~900 Mbps and 940 Mbps (it's a 4 CPUs SoC). This
-change bumps the lower speed from 905 Mb/s to 918 Mb/s (tested using
-single stream iperf 2.0.5 traffic).
-
-There are more optimizations to consider. One obvious to try is GRO
-however as BCM4908 doesn't do hw csum is may actually lower performance.
-Sometimes. Some early testing:
-
-┌─────────────────────────────────┬─────────────────────┬────────────────────┐
-│ │ netif_receive_skb() │ napi_gro_receive() │
-├─────────────────────────────────┼─────────────────────┼────────────────────┤
-│ netdev_alloc_skb() │ 905 Mb/s │ 892 Mb/s │
-│ napi_alloc_frag() + build_skb() │ 918 Mb/s │ 917 Mb/s │
-└─────────────────────────────────┴─────────────────────┴────────────────────┘
-
-Another ideas:
-1. napi_build_skb()
-2. skb_copy_from_linear_data() for small packets
-
-Those need proper testing first though. That can be done later.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221025132245.22871-1-zajec5@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/broadcom/bcm4908_enet.c | 53 +++++++++++++-------
- 1 file changed, 36 insertions(+), 17 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
-+++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
-@@ -36,13 +36,24 @@
- #define ENET_MAX_ETH_OVERHEAD (ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \
- ETH_FCS_LEN + 4) /* 32 */
-
-+#define ENET_RX_SKB_BUF_SIZE (NET_SKB_PAD + NET_IP_ALIGN + \
-+ ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \
-+ ENET_MTU_MAX + ETH_FCS_LEN + 4)
-+#define ENET_RX_SKB_BUF_ALLOC_SIZE (SKB_DATA_ALIGN(ENET_RX_SKB_BUF_SIZE) + \
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-+#define ENET_RX_BUF_DMA_OFFSET (NET_SKB_PAD + NET_IP_ALIGN)
-+#define ENET_RX_BUF_DMA_SIZE (ENET_RX_SKB_BUF_SIZE - ENET_RX_BUF_DMA_OFFSET)
-+
- struct bcm4908_enet_dma_ring_bd {
- __le32 ctl;
- __le32 addr;
- } __packed;
-
- struct bcm4908_enet_dma_ring_slot {
-- struct sk_buff *skb;
-+ union {
-+ void *buf; /* RX */
-+ struct sk_buff *skb; /* TX */
-+ };
- unsigned int len;
- dma_addr_t dma_addr;
- };
-@@ -260,22 +271,21 @@ static int bcm4908_enet_dma_alloc_rx_buf
- u32 tmp;
- int err;
-
-- slot->len = ENET_MTU_MAX + ENET_MAX_ETH_OVERHEAD;
--
-- slot->skb = netdev_alloc_skb(enet->netdev, slot->len);
-- if (!slot->skb)
-+ slot->buf = napi_alloc_frag(ENET_RX_SKB_BUF_ALLOC_SIZE);
-+ if (!slot->buf)
- return -ENOMEM;
-
-- slot->dma_addr = dma_map_single(dev, slot->skb->data, slot->len, DMA_FROM_DEVICE);
-+ slot->dma_addr = dma_map_single(dev, slot->buf + ENET_RX_BUF_DMA_OFFSET,
-+ ENET_RX_BUF_DMA_SIZE, DMA_FROM_DEVICE);
- err = dma_mapping_error(dev, slot->dma_addr);
- if (err) {
- dev_err(dev, "Failed to map DMA buffer: %d\n", err);
-- kfree_skb(slot->skb);
-- slot->skb = NULL;
-+ skb_free_frag(slot->buf);
-+ slot->buf = NULL;
- return err;
- }
-
-- tmp = slot->len << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT;
-+ tmp = ENET_RX_BUF_DMA_SIZE << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT;
- tmp |= DMA_CTL_STATUS_OWN;
- if (idx == enet->rx_ring.length - 1)
- tmp |= DMA_CTL_STATUS_WRAP;
-@@ -315,11 +325,11 @@ static void bcm4908_enet_dma_uninit(stru
-
- for (i = rx_ring->length - 1; i >= 0; i--) {
- slot = &rx_ring->slots[i];
-- if (!slot->skb)
-+ if (!slot->buf)
- continue;
- dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_FROM_DEVICE);
-- kfree_skb(slot->skb);
-- slot->skb = NULL;
-+ skb_free_frag(slot->buf);
-+ slot->buf = NULL;
- }
- }
-
-@@ -575,6 +585,7 @@ static int bcm4908_enet_poll_rx(struct n
- while (handled < weight) {
- struct bcm4908_enet_dma_ring_bd *buf_desc;
- struct bcm4908_enet_dma_ring_slot slot;
-+ struct sk_buff *skb;
- u32 ctl;
- int len;
- int err;
-@@ -598,16 +609,24 @@ static int bcm4908_enet_poll_rx(struct n
-
- if (len < ETH_ZLEN ||
- (ctl & (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) != (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) {
-- kfree_skb(slot.skb);
-+ skb_free_frag(slot.buf);
- enet->netdev->stats.rx_dropped++;
- break;
- }
-
-- dma_unmap_single(dev, slot.dma_addr, slot.len, DMA_FROM_DEVICE);
-+ dma_unmap_single(dev, slot.dma_addr, ENET_RX_BUF_DMA_SIZE, DMA_FROM_DEVICE);
-+
-+ skb = build_skb(slot.buf, ENET_RX_SKB_BUF_ALLOC_SIZE);
-+ if (unlikely(!skb)) {
-+ skb_free_frag(slot.buf);
-+ enet->netdev->stats.rx_dropped++;
-+ break;
-+ }
-+ skb_reserve(skb, ENET_RX_BUF_DMA_OFFSET);
-+ skb_put(skb, len - ETH_FCS_LEN);
-+ skb->protocol = eth_type_trans(skb, enet->netdev);
-
-- skb_put(slot.skb, len - ETH_FCS_LEN);
-- slot.skb->protocol = eth_type_trans(slot.skb, enet->netdev);
-- netif_receive_skb(slot.skb);
-+ netif_receive_skb(skb);
-
- enet->netdev->stats.rx_packets++;
- enet->netdev->stats.rx_bytes += len;
diff --git a/target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch b/target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch
deleted file mode 100644
index 544f899070..0000000000
--- a/target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 471ef777ec79baadc5cd9773d08f95f49cf5e2b1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 31 Oct 2022 11:48:56 +0100
-Subject: [PATCH] net: broadcom: bcm4908_enet: report queued and transmitted
- bytes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows BQL to operate avoiding buffer bloat and reducing latency.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221031104856.32388-1-zajec5@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/broadcom/bcm4908_enet.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
-+++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
-@@ -505,6 +505,7 @@ static int bcm4908_enet_stop(struct net_
- netif_carrier_off(netdev);
- napi_disable(&rx_ring->napi);
- napi_disable(&tx_ring->napi);
-+ netdev_reset_queue(netdev);
-
- bcm4908_enet_dma_rx_ring_disable(enet, &enet->rx_ring);
- bcm4908_enet_dma_tx_ring_disable(enet, &enet->tx_ring);
-@@ -564,6 +565,8 @@ static netdev_tx_t bcm4908_enet_start_xm
- if (ring->write_idx + 1 == ring->length - 1)
- tmp |= DMA_CTL_STATUS_WRAP;
-
-+ netdev_sent_queue(enet->netdev, skb->len);
-+
- buf_desc->addr = cpu_to_le32((uint32_t)slot->dma_addr);
- buf_desc->ctl = cpu_to_le32(tmp);
-
-@@ -671,6 +674,7 @@ static int bcm4908_enet_poll_tx(struct n
- tx_ring->read_idx = 0;
- }
-
-+ netdev_completed_queue(enet->netdev, handled, bytes);
- enet->netdev->stats.tx_packets += handled;
- enet->netdev->stats.tx_bytes += bytes;
-
diff --git a/target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch b/target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch
deleted file mode 100644
index 46d632e95d..0000000000
--- a/target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 28 Mar 2024 10:24:34 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: set
- brcm,wp-not-connected
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Every described BCM4908 board has WP pin not connected. This caused
-problems for drivers since day 0 but there was no property to describe
-that properly. Projects like OpenWrt were modifying Linux driver to deal
-with it.
-
-It's not clear if that is hardware limitation or just reference design
-being copied over and over but this applies to all known / supported
-BCM4908 boards. Handle it by marking WP as not connected by default.
-
-Fixes: 2961f69f151c ("arm64: dts: broadcom: add BCM4908 and Asus GT-AC5300 early DTS files")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -593,6 +593,7 @@
- reg-names = "nand", "nand-int-base";
- interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "nand_ctlrdy";
-+ brcm,wp-not-connected;
- status = "okay";
-
- nandcs: nand@0 {
diff --git a/target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch b/target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch
deleted file mode 100644
index d3375a74c7..0000000000
--- a/target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 14 Jul 2023 08:28:41 +0200
-Subject: [PATCH] leds: bcm63138: rename dependency symbol ARCH_BCM4908 to
- ARCH_BCMBCA
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Symbol ARCH_BCM4908 has been merged/removed without updating leds
-Kconfig.
-
-Fixes: dd5c672d7ca9 ("arm64: bcmbca: Merge ARCH_BCM4908 to ARCH_BCMBCA")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/leds/blink/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/blink/Kconfig
-+++ b/drivers/leds/blink/Kconfig
-@@ -1,10 +1,10 @@
- config LEDS_BCM63138
- tristate "LED Support for Broadcom BCM63138 SoC"
- depends on LEDS_CLASS
-- depends on ARCH_BCM4908 || ARCH_BCM_5301X || BCM63XX || COMPILE_TEST
-+ depends on ARCH_BCMBCA || ARCH_BCM_5301X || BCM63XX || COMPILE_TEST
- depends on HAS_IOMEM
- depends on OF
-- default ARCH_BCM4908
-+ default ARCH_BCMBCA
- help
- This option enables support for LED controller that is part of
- BCM63138 SoC. The same hardware block is known to be also used
diff --git a/target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch b/target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch
deleted file mode 100644
index 4adeef8319..0000000000
--- a/target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Feb 2021 22:01:03 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: limit amount of GPIOs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Linux driver can't handle more than 64 GPIOs
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -340,7 +340,7 @@
- gpio0: gpio-controller@500 {
- compatible = "brcm,bcm6345-gpio";
- reg-names = "dirout", "dat";
-- reg = <0x500 0x28>, <0x528 0x28>;
-+ reg = <0x500 0x8>, <0x528 0x8>;
-
- #gpio-cells = <2>;
- gpio-controller;
diff --git a/target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch b/target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch
deleted file mode 100644
index 8c71301c21..0000000000
--- a/target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 12 Aug 2021 11:52:42 +0200
-Subject: [PATCH] arm64: don't issue HVC on boot
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom's CFE loader seems to miss setting SCR_EL3.HCE which results in
-generating an UNDEF and kernel panic on the first HVC.
-
-HVC gets issued by kernels 5.12+ while booting, by kexec and KVM. Until
-someone finds a workaround we have to avoid all above.
-
-Workarounds: 0c93df9622d4 ("arm64: Initialise as nVHE before switching to VHE")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- arch/arm64/kernel/hyp-stub.S | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm64/kernel/hyp-stub.S
-+++ b/arch/arm64/kernel/hyp-stub.S
-@@ -301,7 +301,7 @@ SYM_FUNC_START(finalise_el2)
- b.ne 1f
-
- mov x0, #HVC_FINALISE_EL2
-- hvc #0
-+// hvc #0
- 1:
- ret
- SYM_FUNC_END(finalise_el2)
diff --git a/target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch b/target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
deleted file mode 100644
index cf089fec61..0000000000
--- a/target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Feb 2021 23:59:26 +0100
-Subject: [PATCH] net: dsa: bcm_sf2: enable GPHY for switch probing
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-GPHY needs to be enabled to succesfully probe & setup switch port
-connected to it. Otherwise hardcoding PHY OUI would be required.
-
-Before:
-brcm-sf2 80080000.switch lan4 (uninitialized): PHY [800c05c0.mdio--1:08] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan3 (uninitialized): PHY [800c05c0.mdio--1:09] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan2 (uninitialized): PHY [800c05c0.mdio--1:0a] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan1 (uninitialized): PHY [800c05c0.mdio--1:0b] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch wan (uninitialized): error -5 setting up PHY for tree 0, switch 0, port 7
-
-After:
-brcm-sf2 80080000.switch lan4 (uninitialized): PHY [800c05c0.mdio--1:08] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan3 (uninitialized): PHY [800c05c0.mdio--1:09] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan2 (uninitialized): PHY [800c05c0.mdio--1:0a] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan1 (uninitialized): PHY [800c05c0.mdio--1:0b] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch wan (uninitialized): PHY [800c05c0.mdio--1:0c] driver [Generic PHY] (irq=POLL)
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/dsa/bcm_sf2.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/dsa/bcm_sf2.c
-+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1522,10 +1522,14 @@ static int bcm_sf2_sw_probe(struct platf
- rev = reg_readl(priv, REG_PHY_REVISION);
- priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
-
-+ bcm_sf2_gphy_enable_set(priv->dev->ds, true);
-+
- ret = b53_switch_register(dev);
- if (ret)
- goto out_mdio;
-
-+ bcm_sf2_gphy_enable_set(priv->dev->ds, false);
-+
- dev_info(&pdev->dev,
- "Starfighter 2 top: %x.%02x, core: %x.%02x, IRQs: %d, %d\n",
- priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
diff --git a/target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch b/target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
deleted file mode 100644
index 865eac729a..0000000000
--- a/target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 16 Feb 2021 00:06:35 +0100
-Subject: [PATCH] net: dsa: bcm_sf2: keep GPHY enabled on the BCM4908
-
-Trying to access disabled PHY results in MDIO_READ_FAIL and:
-[ 11.962886] brcm-sf2 80080000.switch wan: configuring for phy/internal link mode
-[ 11.972500] 8021q: adding VLAN 0 to HW filter on device wan
-[ 11.980205] ------------[ cut here ]------------
-[ 11.984885] WARNING: CPU: 0 PID: 7 at phy_error+0x10/0x58
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/dsa/bcm_sf2.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/dsa/bcm_sf2.c
-+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1536,6 +1536,12 @@ static int bcm_sf2_sw_probe(struct platf
- priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
- priv->irq0, priv->irq1);
-
-+ /* BCM4908 has 5 GPHYs which means bcm_sf2_port_setup() will not enable
-+ * GPHY when needed. Leave it enabled here.
-+ */
-+ if (priv->type == BCM4908_DEVICE_ID)
-+ bcm_sf2_gphy_enable_set(priv->dev->ds, true);
-+
- return 0;
-
- out_mdio:
diff --git a/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch b/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
index cf089fec61..8961bb298c 100644
--- a/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
+++ b/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
@@ -29,7 +29,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1522,10 +1522,14 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1524,10 +1524,14 @@ static int bcm_sf2_sw_probe(struct platf
rev = reg_readl(priv, REG_PHY_REVISION);
priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
diff --git a/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch b/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
index 865eac729a..ff3f44910b 100644
--- a/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
+++ b/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
@@ -15,7 +15,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1536,6 +1536,12 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1538,6 +1538,12 @@ static int bcm_sf2_sw_probe(struct platf
priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
priv->irq0, priv->irq1);
diff --git a/target/linux/bcm53xx/Makefile b/target/linux/bcm53xx/Makefile
index 5b778454fa..b858d2fdbb 100644
--- a/target/linux/bcm53xx/Makefile
+++ b/target/linux/bcm53xx/Makefile
@@ -11,8 +11,7 @@ FEATURES:=squashfs nand usb pci pcie gpio pwm
CPU_TYPE:=cortex-a9
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Broadcom based BCM47xx/53xx routers with ARM CPU, *not* MIPS.
diff --git a/target/linux/bcm53xx/config-5.15 b/target/linux/bcm53xx/config-5.15
deleted file mode 100644
index 9cd1f079d1..0000000000
--- a/target/linux/bcm53xx/config-5.15
+++ /dev/null
@@ -1,317 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_BCM=y
-CONFIG_ARCH_BCM_5301X=y
-CONFIG_ARCH_BCM_53573=y
-# CONFIG_ARCH_BCM_HR2 is not set
-CONFIG_ARCH_BCM_IPROC=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_CRYPTO=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=1
-CONFIG_ARM_HAS_SG_CHAIN=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_B53=y
-CONFIG_B53_MDIO_DRIVER=y
-CONFIG_B53_SRAB_DRIVER=y
-CONFIG_BCM47XX_NVRAM=y
-CONFIG_BCM47XX_SPROM=y
-CONFIG_BCM47XX_WDT=y
-CONFIG_BCMA=y
-CONFIG_BCMA_BLOCKIO=y
-CONFIG_BCMA_DEBUG=y
-CONFIG_BCMA_DRIVER_GMAC_CMN=y
-CONFIG_BCMA_DRIVER_GPIO=y
-CONFIG_BCMA_DRIVER_PCI=y
-CONFIG_BCMA_FALLBACK_SPROM=y
-CONFIG_BCMA_HOST_PCI=y
-CONFIG_BCMA_HOST_PCI_POSSIBLE=y
-CONFIG_BCMA_HOST_SOC=y
-CONFIG_BCMA_SFLASH=y
-# CONFIG_BCM_CYGNUS_PHY is not set
-CONFIG_BCM_NET_PHYLIB=y
-CONFIG_BCM_NS_THERMAL=y
-CONFIG_BCM_SR_THERMAL=y
-CONFIG_BGMAC=y
-CONFIG_BGMAC_BCMA=y
-# CONFIG_BGMAC_PLATFORM is not set
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOUNCE=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
-CONFIG_CLKSRC_MMIO=y
-# CONFIG_CLK_BCM_NS2 is not set
-CONFIG_CLK_BCM_NSP=y
-# CONFIG_CLK_BCM_SR is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_IPROC=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BCM_5301X=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=0
-CONFIG_DEBUG_UART_PHYS=0x18000300
-CONFIG_DEBUG_UART_VIRT=0xf1000300
-CONFIG_DEBUG_UNCOMPRESS=y
-CONFIG_DEBUG_USER=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_REMAP=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXTCON=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=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_GENERIC_VDSO_32=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_74X164=y
-CONFIG_GPIO_BCM_XGS_IPROC=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GRO_CELLS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_BCM2835=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-# CONFIG_LEDS_BCM63138 is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BCM_IPROC=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_BUS_MUX=y
-# CONFIG_MDIO_BUS_MUX_BCM_IPROC is not set
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_BCM47XXSFLASH=y
-CONFIG_MTD_BCM47XX_PARTS=y
-CONFIG_MTD_NAND_BRCMNAND=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_OF_PARTS_LINKSYS_NS=y
-CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_TAG_BRCM=y
-CONFIG_NET_DSA_TAG_BRCM_COMMON=y
-CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
-CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-CONFIG_NVMEM_BRCM_NVRAM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PCI=y
-CONFIG_PCIE_IPROC=y
-CONFIG_PCIE_IPROC_BCMA=y
-# CONFIG_PCIE_IPROC_PLATFORM is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_BCM_NS_USB2 is not set
-# CONFIG_PHY_BCM_NS_USB3 is not set
-# CONFIG_PHY_BCM_SR_PCIE is not set
-CONFIG_PHY_BCM_SR_USB=y
-# CONFIG_PHY_BRCM_SATA is not set
-# CONFIG_PHY_NS2_USB_DRD is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IPROC_GPIO is not set
-CONFIG_PINCTRL_NS=y
-# CONFIG_PINCTRL_NS2_MUX is not set
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_BCM_IPROC=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BCM_QSPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=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_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/bcm53xx/config-6.1 b/target/linux/bcm53xx/config-6.1
deleted file mode 100644
index 259c6559a6..0000000000
--- a/target/linux/bcm53xx/config-6.1
+++ /dev/null
@@ -1,339 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_BCM=y
-CONFIG_ARCH_BCM_5301X=y
-CONFIG_ARCH_BCM_53573=y
-CONFIG_ARCH_BCM_IPROC=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=1
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_B53=y
-CONFIG_B53_MDIO_DRIVER=y
-CONFIG_B53_SRAB_DRIVER=y
-CONFIG_BCM47XX_NVRAM=y
-CONFIG_BCM47XX_SPROM=y
-CONFIG_BCM47XX_WDT=y
-CONFIG_BCMA=y
-CONFIG_BCMA_BLOCKIO=y
-CONFIG_BCMA_DEBUG=y
-CONFIG_BCMA_DRIVER_GMAC_CMN=y
-CONFIG_BCMA_DRIVER_GPIO=y
-CONFIG_BCMA_DRIVER_PCI=y
-CONFIG_BCMA_FALLBACK_SPROM=y
-CONFIG_BCMA_HOST_PCI=y
-CONFIG_BCMA_HOST_PCI_POSSIBLE=y
-CONFIG_BCMA_HOST_SOC=y
-CONFIG_BCMA_SFLASH=y
-# CONFIG_BCM_CYGNUS_PHY is not set
-CONFIG_BCM_NET_PHYLIB=y
-CONFIG_BCM_NS_THERMAL=y
-CONFIG_BCM_SR_THERMAL=y
-CONFIG_BGMAC=y
-CONFIG_BGMAC_BCMA=y
-# CONFIG_BGMAC_PLATFORM is not set
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOUNCE=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
-CONFIG_CLKSRC_MMIO=y
-# CONFIG_CLK_BCM_NS2 is not set
-CONFIG_CLK_BCM_NSP=y
-# CONFIG_CLK_BCM_SR is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_IPROC=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BCM_5301X=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=0
-CONFIG_DEBUG_UART_PHYS=0x18000300
-CONFIG_DEBUG_UART_VIRT=0xf1000300
-CONFIG_DEBUG_USER=y
-CONFIG_DMA_OPS=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXTCON=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=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_GENERIC_VDSO_32=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_74X164=y
-CONFIG_GPIO_BCM_XGS_IPROC=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_BCM2835=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-# CONFIG_LEDS_BCM63138 is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BCM_IPROC=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_BUS_MUX=y
-# CONFIG_MDIO_BUS_MUX_BCM_IPROC is not set
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_BCM47XXSFLASH=y
-CONFIG_MTD_BCM47XX_PARTS=y
-CONFIG_MTD_NAND_BRCMNAND=y
-CONFIG_MTD_NAND_BRCMNAND_IPROC=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_OF_PARTS_LINKSYS_NS=y
-CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_TAG_BRCM=y
-CONFIG_NET_DSA_TAG_BRCM_COMMON=y
-CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
-CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-CONFIG_NVMEM_BRCM_NVRAM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCIE_IPROC=y
-CONFIG_PCIE_IPROC_BCMA=y
-# CONFIG_PCIE_IPROC_PLATFORM is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_BCM_NS_USB2 is not set
-# CONFIG_PHY_BCM_NS_USB3 is not set
-# CONFIG_PHY_BCM_SR_PCIE is not set
-CONFIG_PHY_BCM_SR_USB=y
-# CONFIG_PHY_BRCM_SATA is not set
-# CONFIG_PHY_NS2_USB_DRD is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IPROC_GPIO is not set
-CONFIG_PINCTRL_NS=y
-# CONFIG_PINCTRL_NS2_MUX is not set
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_BCM_IPROC=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BCM_QSPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=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_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/bcm53xx/image/Makefile b/target/linux/bcm53xx/image/Makefile
index 88590c3755..e02eba387c 100644
--- a/target/linux/bcm53xx/image/Makefile
+++ b/target/linux/bcm53xx/image/Makefile
@@ -127,11 +127,7 @@ define Build/dwl8610ap-image
mv $@.new $@
endef
-ifneq ($(KERNEL),5.15)
-ifneq ($(KERNEL),6.1)
DTS_DIR := $(DTS_DIR)/broadcom
-endif
-endif
DEVICE_VARS += ASUS_PRODUCTID
DEVICE_VARS += BUFFALO_TAG_PLATFORM BUFFALO_TAG_VERSION BUFFALO_TAG_MINOR
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch
deleted file mode 100644
index c994953d4d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 465078bfdf5271601f098450ae2fc974865c59fd Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Thu, 10 Jun 2021 21:35:10 +0100
-Subject: [PATCH] ARM: dts: NSP: add device names to compatible
-
-Currently only the SoC type and platform are specified for all NSP
-devices. This patch adds the device names.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958522er.dts | 2 +-
- arch/arm/boot/dts/bcm958525er.dts | 2 +-
- arch/arm/boot/dts/bcm958525xmc.dts | 2 +-
- arch/arm/boot/dts/bcm958622hr.dts | 2 +-
- arch/arm/boot/dts/bcm958625hr.dts | 2 +-
- arch/arm/boot/dts/bcm958625k.dts | 2 +-
- arch/arm/boot/dts/bcm988312hr.dts | 2 +-
- 7 files changed, 7 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm958522er.dts
-+++ b/arch/arm/boot/dts/bcm958522er.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958522ER)";
-- compatible = "brcm,bcm58522", "brcm,nsp";
-+ compatible = "brcm,bcm958522er", "brcm,bcm58522", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958525er.dts
-+++ b/arch/arm/boot/dts/bcm958525er.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958525ER)";
-- compatible = "brcm,bcm58525", "brcm,nsp";
-+ compatible = "brcm,bcm958525er", "brcm,bcm58525", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958525xmc.dts
-+++ b/arch/arm/boot/dts/bcm958525xmc.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus XMC (BCM958525xmc)";
-- compatible = "brcm,bcm58525", "brcm,nsp";
-+ compatible = "brcm,bcm958525xmc", "brcm,bcm58525", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958622hr.dts
-+++ b/arch/arm/boot/dts/bcm958622hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958622HR)";
-- compatible = "brcm,bcm58622", "brcm,nsp";
-+ compatible = "brcm,bcm958622hr", "brcm,bcm58622", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958625hr.dts
-+++ b/arch/arm/boot/dts/bcm958625hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958625HR)";
-- compatible = "brcm,bcm58625", "brcm,nsp";
-+ compatible = "brcm,bcm958625hr", "brcm,bcm58625", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958625k.dts
-+++ b/arch/arm/boot/dts/bcm958625k.dts
-@@ -36,7 +36,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958625K)";
-- compatible = "brcm,bcm58625", "brcm,nsp";
-+ compatible = "brcm,bcm958625k", "brcm,bcm58625", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm988312hr.dts
-+++ b/arch/arm/boot/dts/bcm988312hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM988312HR)";
-- compatible = "brcm,bcm88312", "brcm,nsp";
-+ compatible = "brcm,bcm988312hr", "brcm,bcm88312", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch
deleted file mode 100644
index d84124d2dd..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 1b90dde4278a7b459979706b572785bc3a10bbb5 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Thu, 10 Jun 2021 21:35:12 +0100
-Subject: [PATCH] ARM: dts: NSP: enable DMA on bcm988312hr
-
-The previous patch "ARM: dts: NSP: Disable PL330 by default, add
-dma-coherent property" set the DMAC to disabled by default, requiring it
-to be manually enabled on each device. The bcm988312hr was mistakenly
-omitted. This patch adds it back.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm988312hr.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/boot/dts/bcm988312hr.dts
-+++ b/arch/arm/boot/dts/bcm988312hr.dts
-@@ -58,6 +58,10 @@
-
- /* USB 3 support needed to be complete */
-
-+&dma {
-+ status = "okay";
-+};
-+
- &amac0 {
- status = "okay";
- };
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch
deleted file mode 100644
index e540245b0f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 091a12b1814142eac16a115dab206f735b5476a9 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 13 Jun 2021 10:46:34 +0100
-Subject: [PATCH] ARM: dts: NSP: disable qspi node by default
-
-The QSPI bus is enabled by default, however this may not used on all
-devices. This patch disables by default, requiring it to be explicitly
-enabled where required.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 1 +
- arch/arm/boot/dts/bcm958522er.dts | 1 +
- arch/arm/boot/dts/bcm958525er.dts | 1 +
- arch/arm/boot/dts/bcm958525xmc.dts | 1 +
- arch/arm/boot/dts/bcm958622hr.dts | 1 +
- arch/arm/boot/dts/bcm958623hr.dts | 1 +
- arch/arm/boot/dts/bcm958625hr.dts | 1 +
- arch/arm/boot/dts/bcm958625k.dts | 1 +
- arch/arm/boot/dts/bcm988312hr.dts | 1 +
- 9 files changed, 9 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -310,6 +310,7 @@
- num-cs = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
-+ status = "disabled";
- };
-
- xhci: usb@29000 {
---- a/arch/arm/boot/dts/bcm958522er.dts
-+++ b/arch/arm/boot/dts/bcm958522er.dts
-@@ -134,6 +134,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958525er.dts
-+++ b/arch/arm/boot/dts/bcm958525er.dts
-@@ -134,6 +134,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958525xmc.dts
-+++ b/arch/arm/boot/dts/bcm958525xmc.dts
-@@ -150,6 +150,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958622hr.dts
-+++ b/arch/arm/boot/dts/bcm958622hr.dts
-@@ -138,6 +138,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958623hr.dts
-+++ b/arch/arm/boot/dts/bcm958623hr.dts
-@@ -142,6 +142,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625hr.dts
-+++ b/arch/arm/boot/dts/bcm958625hr.dts
-@@ -149,6 +149,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625k.dts
-+++ b/arch/arm/boot/dts/bcm958625k.dts
-@@ -153,6 +153,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm988312hr.dts
-+++ b/arch/arm/boot/dts/bcm988312hr.dts
-@@ -138,6 +138,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch
deleted file mode 100644
index 6164a22c76..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 236b31b1d84eb0e4f10c5f113a2675529456f919 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 13 Jun 2021 10:46:36 +0100
-Subject: [PATCH] ARM: dts: NSP: add MDIO bus controller node
-
-This patch adds the node for the MDIO bus controller, present on the NSP
-SoC.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -363,6 +363,13 @@
- status = "disabled";
- };
-
-+ mdio: mdio@32000 {
-+ compatible = "brcm,iproc-mdio";
-+ reg = <0x32000 0x8>;
-+ #size-cells = <0>;
-+ #address-cells = <1>;
-+ };
-+
- rng: rng@33000 {
- compatible = "brcm,bcm-nsp-rng";
- reg = <0x33000 0x14>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch
deleted file mode 100644
index b760e0fcf2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 1c615401bddb1be21e1d375aaa071680f40f1ae2 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 13 Jun 2021 10:46:37 +0100
-Subject: [PATCH] ARM: dts: NSP: Move USB3 PHY to internal MDIO bus
-
-This patch largely replicates Vivek Unune's patch "ARM: dts:
-BCM5301X:Make usb3 phy use mdio phy driver"[1] for the NSP platform,
-whereby we need to create an mdio-mux to facilitate switches
-configured via external MDIO, in this case on the Meraki MX65.
-
-However in doing so, we are creating an overlap with usb3_phy's
-ccb-mii range. To resolve this, usb3_phy should be moved to a child
-node of the internal MDIO bus. The result is heavily based upon Vivek's
-patch. This has also been cross-referenced with Yendapally Reddy's
-earlier work which utilised the subsequently dropped brcm,nsp-usb3-phy
-driver: "[PATCH v2 4/4] arm: dts: nsp: Add USB nodes to device tree"
-[2]. Finally, this change provides conformance to the bcm-ns-usb3-phy
-documentation, utilising the required usb3-dmp-syscon property. Note
-that support for the deprecated ccb-mii bindings has been dropped as of
-"phy: phy-bcm-ns-usb3: drop support for deprecated DT binding"[3].
-
-[1] https://lore.kernel.org/patchwork/patch/933971/
-[2] https://www.spinics.net/lists/arm-kernel/msg555132.html
-[3] https://lore.kernel.org/linux-devicetree/20201113113423.9466-1-zajec5@gmail.com/
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 38 +++++++++++++++++++++++++++-------
- 1 file changed, 31 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -370,6 +370,35 @@
- #address-cells = <1>;
- };
-
-+ mdio-mux@32000 {
-+ compatible = "mdio-mux-mmioreg";
-+ reg = <0x32000 0x4>;
-+ mux-mask = <0x200>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ mdio-parent-bus = <&mdio>;
-+
-+ mdio_int: mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ usb3_phy: usb3-phy@10 {
-+ compatible = "brcm,ns-bx-usb3-phy";
-+ reg = <0x10>;
-+ usb3-dmp-syscon = <&usb3_dmp>;
-+ #phy-cells = <0>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ mdio_ext: mdio@200 {
-+ reg = <0x200>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+
- rng: rng@33000 {
- compatible = "brcm,bcm-nsp-rng";
- reg = <0x33000 0x14>;
-@@ -528,13 +557,8 @@
- };
- };
-
-- usb3_phy: usb3-phy@104000 {
-- compatible = "brcm,ns-bx-usb3-phy";
-- reg = <0x104000 0x1000>,
-- <0x032000 0x1000>;
-- reg-names = "dmp", "ccb-mii";
-- #phy-cells = <0>;
-- status = "disabled";
-+ usb3_dmp: syscon@104000 {
-+ reg = <0x104000 0x1000>;
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch
deleted file mode 100644
index aebf62af9b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From f111016a8293b968f05450fec83020c94d0f88c2 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:32 +0100
-Subject: [PATCH] ARM: dts: NSP: Add common bindings for MX64/MX65
-
-These bindings are required for all Meraki MX64/MX65 devices. These
-common bindings include memory (2GB), PWM LEDs, AMAC, I2C (AT24), NAND
-partitions, EHCI, OHCI and pinctrl.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../dts/bcm958625-meraki-mx6x-common.dtsi | 129 ++++++++++++++++++
- 1 file changed, 129 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -0,0 +1,129 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Common Bindings for Cisco Meraki MX64 (Kingpin) and MX65 (Alamo) devices.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+#include "bcm-nsp.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ pwm-leds {
-+ compatible = "pwm-leds";
-+
-+ led-1 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ pwms = <&pwm 1 50000>;
-+ max-brightness = <255>;
-+ };
-+
-+ led-2 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_GREEN>;
-+ pwms = <&pwm 2 50000>;
-+ max-brightness = <255>;
-+ };
-+
-+ led-3 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_BLUE>;
-+ pwms = <&pwm 3 50000>;
-+ max-brightness = <255>;
-+ };
-+ };
-+};
-+
-+&amac2 {
-+ status = "okay";
-+};
-+
-+&ehci0 {
-+ status = "okay";
-+};
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ at24@50 {
-+ compatible = "atmel,24c64";
-+ reg = <0x50>;
-+ pagesize = <32>;
-+ read-only;
-+ };
-+};
-+
-+&nand_controller {
-+ nand@0 {
-+ compatible = "brcm,nandcs";
-+ reg = <0>;
-+ nand-on-flash-bbt;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ nand-ecc-strength = <24>;
-+ nand-ecc-step-size = <1024>;
-+
-+ brcm,nand-oob-sector-size = <27>;
-+
-+ partition@0 {
-+ label = "u-boot";
-+ reg = <0x0 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "shmoo";
-+ reg = <0x80000 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@100000 {
-+ label = "bootkernel1";
-+ reg = <0x100000 0x300000>;
-+ };
-+
-+ partition@400000 {
-+ label = "nvram";
-+ reg = <0x400000 0x100000>;
-+ };
-+
-+ partition@500000 {
-+ label = "bootkernel2";
-+ reg = <0x500000 0x300000>;
-+ };
-+
-+ partition@800000 {
-+ label = "ubi";
-+ reg = <0x800000 0x3f700000>;
-+ };
-+ };
-+};
-+
-+&ohci0 {
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_leds>;
-+
-+ pwm_leds: pwm_leds {
-+ function = "pwm";
-+ groups = "pwm1_grp", "pwm2_grp", "pwm3_grp";
-+ };
-+};
-+
-+&pwm {
-+ status = "okay";
-+ #pwm-cells = <2>;
-+};
-+
-+&uart0 {
-+ clock-frequency = <62500000>;
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch
deleted file mode 100644
index 39a69bd9a8..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 2addf9266a1d0f4ba59c9868b3effcd50de441a4 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:33 +0100
-Subject: [PATCH] ARM: dts: NSP: Add Ax stepping modifications
-
-While uncommon, some Ax NSP SoCs exist in the wild. This stepping
-requires a modified secondary CPU boot-reg and removal of DMA coherency
-properties. Without these modifications, the secondary CPU will be
-inactive and many peripherals will exhibit undefined behaviour.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp-ax.dtsi | 70 +++++++++++++++++++++++++++++++
- 1 file changed, 70 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm-nsp-ax.dtsi
-
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm-nsp-ax.dtsi
-@@ -0,0 +1,70 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Broadcom Northstar Plus Ax stepping-specific bindings.
-+ * Notable differences from B0+ are the secondary-boot-reg and
-+ * lack of DMA coherency.
-+ */
-+
-+&cpu1 {
-+ secondary-boot-reg = <0xffff042c>;
-+};
-+
-+&dma {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&sdio {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&amac0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&amac1 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&amac2 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&ehci0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&mailbox {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&xhci {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&ehci0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&ohci0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&i2c0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&sata {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&pcie0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&pcie1 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&pcie2 {
-+ /delete-property/ dma-coherent;
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch
deleted file mode 100644
index ffdd64fb59..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch
+++ /dev/null
@@ -1,340 +0,0 @@
-From 3f902645280baf0d7dab57c227cc14f43edb45ef Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:34 +0100
-Subject: [PATCH] ARM: dts: NSP: Add DT files for Meraki MX64 series
-
-MX64 & MX64W Hardware info:
- - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
- - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
- - Storage: 1 GB (Micron MT29F8G08ABACA)
- - Networking: BCM58625 internal switch (5x 1GbE ports)
- - USB: 1x USB2.0
- - Serial: Internal header
- - WLAN(MX64W only): 2x Broadcom BCM43520KMLG on the PCI bus
-
-This patch adds the Meraki MX64 series-specific bindings. Since some
-devices make use of the older A0 SoC, changes need to be made to
-accommodate this case, including removal of coherency options and
-modification to the secondary-boot-reg.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 4 +
- .../boot/dts/bcm958625-meraki-kingpin.dtsi | 163 ++++++++++++++++++
- .../arm/boot/dts/bcm958625-meraki-mx64-a0.dts | 25 +++
- arch/arm/boot/dts/bcm958625-meraki-mx64.dts | 24 +++
- .../boot/dts/bcm958625-meraki-mx64w-a0.dts | 33 ++++
- arch/arm/boot/dts/bcm958625-meraki-mx64w.dts | 32 ++++
- 6 files changed, 281 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -158,6 +158,10 @@ dtb-$(CONFIG_ARCH_BCM_NSP) += \
- bcm958525xmc.dtb \
- bcm958622hr.dtb \
- bcm958623hr.dtb \
-+ bcm958625-meraki-mx64.dtb \
-+ bcm958625-meraki-mx64-a0.dtb \
-+ bcm958625-meraki-mx64w.dtb \
-+ bcm958625-meraki-mx64w-a0.dtb \
- bcm958625hr.dtb \
- bcm988312hr.dtb \
- bcm958625k.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-@@ -0,0 +1,163 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64 series (Kingpin).
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+#include "bcm958625-meraki-mx6x-common.dtsi"
-+
-+/ {
-+
-+ keys {
-+ compatible = "gpio-keys-polled";
-+ autorepeat;
-+ poll-interval = <20>;
-+
-+ reset {
-+ label = "reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&gpioa 6 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-0 {
-+ /* green:lan1-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <0>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 19 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-1 {
-+ /* green:lan1-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <1>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-2 {
-+ /* green:lan2-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <2>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 24 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-3 {
-+ /* green:lan2-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <3>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-4 {
-+ /* green:lan3-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <4>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 26 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-5 {
-+ /* green:lan3-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <5>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 25 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-6 {
-+ /* green:lan4-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <6>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 28 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-7 {
-+ /* green:lan4-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <7>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 27 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-8 {
-+ /* green:wan-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <8>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 30 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-9 {
-+ /* green:wan-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <9>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 29 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-a {
-+ /* amber:power */
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpioa 0 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ };
-+
-+ led-b {
-+ /* white:status */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_WHITE>;
-+ gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm58625-srab", "brcm,nsp-srab";
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ reg = <4>;
-+ };
-+
-+ port@8 {
-+ ethernet = <&amac2>;
-+ reg = <8>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
-@@ -0,0 +1,25 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64 with A0 SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+#include "bcm-nsp-ax.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64(A0)";
-+ compatible = "meraki,mx64-a0", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64.dts
-@@ -0,0 +1,24 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64 with B0+ SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64";
-+ compatible = "meraki,mx64", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
-@@ -0,0 +1,33 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64W with A0 SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+#include "bcm-nsp-ax.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64W(A0)";
-+ compatible = "meraki,mx64w-a0", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ status = "okay";
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64w.dts
-@@ -0,0 +1,32 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64W with B0+ SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64W";
-+ compatible = "meraki,mx64w", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch
deleted file mode 100644
index 29f8b5d0fe..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch
+++ /dev/null
@@ -1,386 +0,0 @@
-From 702a8f4744ed5b480f2b2411858184afdb10f9fd Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:35 +0100
-Subject: [PATCH] ARM: dts: NSP: Add DT files for Meraki MX65 series
-
-MX65 & MX65W Hardware info:
- - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
- - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
- - Storage: 1 GB (Micron MT29F8G08ABACA)
- - Networking: BCM58625 switch (2x 1GbE ports)
- 2x Qualcomm QCA8337 switches (10x 1GbE ports total)
- - PSE: Broadcom BCM59111KMLG connected to LAN ports 11 & 12
- - USB: 1x USB2.0
- - Serial: Internal header
- - WLAN(MX65W Only): 2x Broadcom BCM43520KMLG on the PCI bus.
-
-Note that a driver and firmware image for the BCM59111 PSE has been
-released under GPL, but this is not present in the kernel.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 2 +
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 279 ++++++++++++++++++
- arch/arm/boot/dts/bcm958625-meraki-mx65.dts | 24 ++
- arch/arm/boot/dts/bcm958625-meraki-mx65w.dts | 32 ++
- 4 files changed, 337 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65w.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -162,6 +162,8 @@ dtb-$(CONFIG_ARCH_BCM_NSP) += \
- bcm958625-meraki-mx64-a0.dtb \
- bcm958625-meraki-mx64w.dtb \
- bcm958625-meraki-mx64w-a0.dtb \
-+ bcm958625-meraki-mx65.dtb \
-+ bcm958625-meraki-mx65w.dtb \
- bcm958625hr.dtb \
- bcm988312hr.dtb \
- bcm958625k.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -0,0 +1,279 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX65 series (Alamo).
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+#include "bcm958625-meraki-mx6x-common.dtsi"
-+
-+/ {
-+ keys {
-+ compatible = "gpio-keys-polled";
-+ autorepeat;
-+ poll-interval = <20>;
-+
-+ reset {
-+ label = "reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&gpioa 8 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-0 {
-+ /* green:wan1-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <0>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 25 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-1 {
-+ /* green:wan1-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <1>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 24 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-2 {
-+ /* green:wan2-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <2>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 27 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-3 {
-+ /* green:wan2-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <3>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 26 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-4 {
-+ /* amber:power */
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpioa 3 GPIO_ACTIVE_HIGH>;
-+ default-state = "on";
-+ };
-+
-+ led-5 {
-+ /* white:status */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_WHITE>;
-+ gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ mdio-mii-mux {
-+ compatible = "mdio-mux-mmioreg";
-+ reg = <0x1803f1c0 0x4>;
-+ mux-mask = <0x2000>;
-+ mdio-parent-bus = <&mdio_ext>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ phy_port6: phy@0 {
-+ reg = <0>;
-+ };
-+
-+ phy_port7: phy@1 {
-+ reg = <1>;
-+ };
-+
-+ phy_port8: phy@2 {
-+ reg = <2>;
-+ };
-+
-+ phy_port9: phy@3 {
-+ reg = <3>;
-+ };
-+
-+ phy_port10: phy@4 {
-+ reg = <4>;
-+ };
-+
-+ switch@10 {
-+ compatible = "qca,qca8337";
-+ reg = <0x10>;
-+ dsa,member = <1 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ port@0 {
-+ reg = <0>;
-+ ethernet = <&sgmii1>;
-+ phy-mode = "sgmii";
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan8";
-+ phy-handle = <&phy_port6>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan9";
-+ phy-handle = <&phy_port7>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan10";
-+ phy-handle = <&phy_port8>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan11";
-+ phy-handle = <&phy_port9>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "lan12";
-+ phy-handle = <&phy_port10>;
-+ };
-+ };
-+ };
-+ };
-+
-+ mdio-mii@2000 {
-+ reg = <0x2000>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ phy_port1: phy@0 {
-+ reg = <0>;
-+ };
-+
-+ phy_port2: phy@1 {
-+ reg = <1>;
-+ };
-+
-+ phy_port3: phy@2 {
-+ reg = <2>;
-+ };
-+
-+ phy_port4: phy@3 {
-+ reg = <3>;
-+ };
-+
-+ phy_port5: phy@4 {
-+ reg = <4>;
-+ };
-+
-+ switch@10 {
-+ compatible = "qca,qca8337";
-+ reg = <0x10>;
-+ dsa,member = <2 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ port@0 {
-+ reg = <0>;
-+ ethernet = <&sgmii0>;
-+ phy-mode = "sgmii";
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ phy-handle = <&phy_port1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan4";
-+ phy-handle = <&phy_port2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan5";
-+ phy-handle = <&phy_port3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan6";
-+ phy-handle = <&phy_port4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "lan7";
-+ phy-handle = <&phy_port5>;
-+ };
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm58625-srab", "brcm,nsp-srab";
-+ status = "okay";
-+ dsa,member = <0 0>;
-+
-+ ports {
-+ port@0 {
-+ label = "wan1";
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ label = "wan2";
-+ reg = <1>;
-+ };
-+
-+ sgmii0: port@4 {
-+ label = "sw0";
-+ reg = <4>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ sgmii1: port@5 {
-+ label = "sw1";
-+ reg = <5>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@8 {
-+ ethernet = <&amac2>;
-+ reg = <8>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx65.dts
-@@ -0,0 +1,24 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX65.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-alamo.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX65";
-+ compatible = "meraki,mx65", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx65w.dts
-@@ -0,0 +1,32 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX65W.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-alamo.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX65W";
-+ compatible = "meraki,mx65w", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch
deleted file mode 100644
index c5f28474e3..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 695717eb4c61173d05a277e37132b5e2c6531bf1 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:47 +0000
-Subject: [PATCH] ARM: dts: NSP: Add bcm958623hr board name to dts
-
-This board was previously added to
-Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml
-however the dts file was not updated to reflect this change. This patch
-corrects bcm958623hr.dts by adding the board name to the compatible.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958623hr.dts | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm958623hr.dts
-+++ b/arch/arm/boot/dts/bcm958623hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958623HR)";
-- compatible = "brcm,bcm58623", "brcm,nsp";
-+ compatible = "brcm,bcm958623hr", "brcm,bcm58623", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch
deleted file mode 100644
index a7c0f16719..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 38f8111369f318a538e9d4d89d8e48030c22fb40 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:49 +0000
-Subject: [PATCH] ARM: dts: NSP: Fix MDIO mux node names
-
-While functional, the mdio-mux-mmioreg binding does not conform to
-Documentation/devicetree/bindings/net/mdio-mux-mmioreg.yaml in that an
-mdio-mux compatible is also required. Without this the following output
-is observed when running dtbs_check:
-
-mdio-mux@32000: compatible: ['mdio-mux-mmioreg'] is too short
-
-This change brings conformance to this requirement and corresponds
-likewise to Rafal Milecki's change to the BCM5301x platform[1].
-
-[1] https://lore.kernel.org/linux-arm-kernel/20210822191256.3715003-1-f.fainelli@gmail.com/T/
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 2 +-
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -371,7 +371,7 @@
- };
-
- mdio-mux@32000 {
-- compatible = "mdio-mux-mmioreg";
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
- reg = <0x32000 0x4>;
- mux-mask = <0x200>;
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -72,7 +72,7 @@
- };
-
- mdio-mii-mux {
-- compatible = "mdio-mux-mmioreg";
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
- reg = <0x1803f1c0 0x4>;
- mux-mask = <0x2000>;
- mdio-parent-bus = <&mdio_ext>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch
deleted file mode 100644
index 4cffad1f4e..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 56e4e548427240d85fd220460d0ab5987e1dec00 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:50 +0000
-Subject: [PATCH] ARM: dts: NSP: Fix MX64/MX65 eeprom node name
-
-Running dtbs_check yields the following message when checking the
-MX64/MX65 devicetree:
-at24@50: $nodename:0: 'at24@50' does not match '^eeprom@[0-9a-f]{1,2}$'
-
-This patch fixes the issue by renaming the at24 node appropriately.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -48,7 +48,7 @@
- &i2c0 {
- status = "okay";
-
-- at24@50 {
-+ eeprom@50 {
- compatible = "atmel,24c64";
- reg = <0x50>;
- pagesize = <32>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch
deleted file mode 100644
index cad7388685..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From f5fc9044e5d45a4d97b5240c8723f4677f647c9f Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:51 +0000
-Subject: [PATCH] ARM: dts: NSP: Fix MX65 MDIO mux warnings
-
-The naming of this node is based upon that of the initial EA9500 dts[1].
-However this does not conform with the mdio-mux format, yielding the
-following message when running dtbs_check:
-mdio-mii-mux: $nodename:0: 'mdio-mii-mux' does not match '^mdio-mux[\\-@]?'
-
-Secondly, this node should be moved to within the axi node and given the
-appropriate unit address. This also requires exposing the axi node via a
-label in bcm-nsp.dtsi. This fixes the following warning:
-Warning (unit_address_vs_reg): /mdio-mii-mux: node has a reg or ranges property, but no unit name
-
-[1]https://patchwork.ozlabs.org/project/linux-imx/patch/20180618174159.86150-1-npcomplete13@gmail.com/#1941353
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 2 +-
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 6 ++++--
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -166,7 +166,7 @@
- };
- };
-
-- axi@18000000 {
-+ axi: axi@18000000 {
- compatible = "simple-bus";
- ranges = <0x00000000 0x18000000 0x0011c40c>;
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -70,10 +70,12 @@
- gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
- };
- };
-+};
-
-- mdio-mii-mux {
-+&axi {
-+ mdio-mux@3f1c0 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
-- reg = <0x1803f1c0 0x4>;
-+ reg = <0x3f1c0 0x4>;
- mux-mask = <0x2000>;
- mdio-parent-bus = <&mdio_ext>;
- #address-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch
deleted file mode 100644
index b309771369..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch
+++ /dev/null
@@ -1,290 +0,0 @@
-From 225ffaf3d0e00daa2d0c7b68e8fd731ebbde3c03 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 7 Sep 2021 08:00:48 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Specify switch ports for more devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Those are remaining models I have that didn't have ports yet. All
-tested.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 37 ++++++++++++++++
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 37 ++++++++++++++++
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 42 +++++++++++++++++++
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 42 +++++++++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 37 ++++++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 37 ++++++++++++++++
- 6 files changed, 232 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -94,3 +94,40 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -117,3 +117,40 @@
- };
- };
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -187,3 +187,45 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -118,3 +118,45 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -68,3 +68,40 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan4";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan2";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan1";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -68,3 +68,40 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan4";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan2";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan1";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch
deleted file mode 100644
index c6d995723c..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 64612828628cca6e3992e421f45c242dc6625647 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 20 Sep 2021 16:10:24 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add Tenda AC9 switch ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This router has 1 WAN and 4 LAN ports.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 37 ++++++++++++++++++++++++
- 1 file changed, 37 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -105,3 +105,40 @@
- };
- };
- };
-+
-+&switch {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch
deleted file mode 100644
index 35f697c66f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 6abc4ca5a28070945e0d68cb4160b309bfbf4b8b Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Sat, 18 Sep 2021 19:29:30 +0200
-Subject: [PATCH] ARM: BCM53016: Specify switch ports for Meraki MR32
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-the switch identifies itself as a BCM53012 (rev 5)...
-This patch has been tested & verified on OpenWrt's
-snapshot with Linux 5.10 (didn't test any older kernels).
-The MR32 is able to "talk to the network" as before with
-OpenWrt's SWITCHDEV b53 driver.
-
-| b53-srab-switch 18007000.ethernet-switch: found switch: BCM53012, rev 5
-| libphy: dsa slave smi: probed
-| b53-srab-switch 18007000.ethernet-switch poe (uninitialized):
-| PHY [dsa-0.0:00] driver [Generic PHY] (irq=POLL)
-| b53-srab-switch 18007000.ethernet-switch: Using legacy PHYLIB callbacks.
-| Please migrate to PHYLINK!
-| DSA: tree 0 setup
-
-Reported-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -217,3 +217,25 @@
- };
- };
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "poe";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ duplex-full;
-+ };
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch
deleted file mode 100644
index 70a18822a9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 477ffdbdf389cc91294d66e251cc6f856da5820c Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Sat, 18 Sep 2021 19:29:31 +0200
-Subject: [PATCH] ARM: BCM53016: MR32: get mac-address from nvmem
-
-The MAC-Address of the MR32's sole ethernet port is
-located in offset 0x66 of the attached AT24C64 eeprom.
-
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -110,6 +110,12 @@
- reg = <0x50>;
- pagesize = <32>;
- read-only;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ mac_address: mac-address@66 {
-+ reg = <0x66 0x6>;
-+ };
- };
- };
- };
-@@ -133,6 +139,11 @@
- */
- };
-
-+&gmac0 {
-+ nvmem-cell-names = "mac-address";
-+ nvmem-cells = <&mac_address>;
-+};
-+
- &gmac1 {
- status = "disabled";
- };
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch
deleted file mode 100644
index 667ccea0a9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From beff77b93452cd2057c859694709dd34a181488f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 21 Sep 2021 20:19:01 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Hardware Info
--------------
-
-Processor - Broadcom BCM4709C0KFEBG dual-core @ 1.4 GHz
-Switch - BCM53012 in BCM4709C0KFEBG & external RTL8365MB
-DDR3 RAM - 512 MB
-Flash - 128 MB (ESMT F59L1G81LA-25T)
-2.4GHz - BCM4366 4×4 2.4/5G single chip 802.11ac SoC
-5GHz - BCM4366 4×4 2.4/5G single chip 802.11ac SoC
-Ports - 8 Ports, 1 WAN Ports
-
-Tested on OpenWrt on kernel 5.10 built with DSA driver.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 200 +++++++++++++++++++
- 2 files changed, 201 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -117,6 +117,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-netgear-r7000.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
-+ bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
- bcm47094-linksys-panamera.dtb \
- bcm47094-luxul-abr-4500.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -0,0 +1,200 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (C) 2021 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ compatible = "asus,rt-ac88u", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "Asus RT-AC88U";
-+
-+ chosen {
-+ bootargs = "earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+ nvram@1c080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1c080000 0x00180000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ power {
-+ label = "white:power";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wan-red {
-+ label = "red:wan";
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ lan {
-+ label = "white:lan";
-+ gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ usb2 {
-+ label = "white:usb2";
-+ gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ usb3 {
-+ label = "white:usb3";
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port1>, <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ wps {
-+ label = "white:wps";
-+ gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ reset {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wifi {
-+ label = "Wi-Fi";
-+ linux,code = <KEY_RFKILL>;
-+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led {
-+ label = "Backlight";
-+ linux,code = <KEY_BRIGHTNESS_ZERO>;
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-+ status = "okay";
-+ dsa,member = <0 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ sw0_p5: port@5 {
-+ reg = <5>;
-+ label = "extsw";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@7 {
-+ reg = <7>;
-+ ethernet = <&gmac1>;
-+ label = "cpu";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac2>;
-+ label = "cpu";
-+ status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x00000000 0x00080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "nvram";
-+ reg = <0x00080000 0x00180000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x00200000 0x07e00000>;
-+ compatible = "brcm,trx";
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch
deleted file mode 100644
index a0be1eda4d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 58d3d07985c1adab31a3ed76360d016bb1c5b358 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 15 Oct 2021 23:50:22 +0100
-Subject: [PATCH] ARM: dts: NSP: MX65: add qca8k falling-edge, PLL properties
-
-This patch enables two properties for the QCA8337 switches on the MX65.
-
-Set the SGMII transmit clock to falling edge
-"qca,sgmii-txclk-falling-edge" to conform to the OEM configuration [1].
-
-The new explicit PLL enable option "qca,sgmii-enable-pll" is required
-[2].
-
-[1] https://git.kernel.org/netdev/net-next/c/6c43809bf1be
-[2] https://git.kernel.org/netdev/net-next/c/bbc4799e8bb6
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -118,6 +118,8 @@
- reg = <0>;
- ethernet = <&sgmii1>;
- phy-mode = "sgmii";
-+ qca,sgmii-enable-pll;
-+ qca,sgmii-txclk-falling-edge;
- fixed-link {
- speed = <1000>;
- full-duplex;
-@@ -194,6 +196,8 @@
- reg = <0>;
- ethernet = <&sgmii0>;
- phy-mode = "sgmii";
-+ qca,sgmii-enable-pll;
-+ qca,sgmii-txclk-falling-edge;
- fixed-link {
- speed = <1000>;
- full-duplex;
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch
deleted file mode 100644
index 3c3725adec..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 835992e7eca4b29a87c204cefff2f7863fd087f3 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Wed, 27 Oct 2021 00:57:03 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: remove unnecessary address & size cells
- from Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove the unnecessary #address-cells & #size-cells in the gpio-keys node
-from the device tree of Asus RT-AC88U.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -68,8 +68,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- wps {
- label = "WPS";
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
deleted file mode 100644
index 562d5a22c7..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From b6c99228c8edc5e67d8229ba1c5f76cce210ddfc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Wed, 27 Oct 2021 00:57:06 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Define the Realtek RTL8365MB switch without interrupt support on the device
-tree of Asus RT-AC88U.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 77 ++++++++++++++++++++
- 1 file changed, 77 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -93,6 +93,83 @@
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
- };
-+
-+ switch {
-+ compatible = "realtek,rtl8365mb";
-+ /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-+ mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
-+ mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
-+ reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-+ realtek,disable-leds;
-+ dsa,member = <1 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "lan5";
-+ phy-handle = <&ethphy0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan6";
-+ phy-handle = <&ethphy1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan7";
-+ phy-handle = <&ethphy2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan8";
-+ phy-handle = <&ethphy3>;
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&sw0_p5>;
-+ phy-mode = "rgmii";
-+ tx-internal-delay-ps = <2000>;
-+ rx-internal-delay-ps = <2000>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+ };
-+
-+ mdio {
-+ compatible = "realtek,smi-mdio";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ethphy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+
-+ ethphy1: ethernet-phy@1 {
-+ reg = <1>;
-+ };
-+
-+ ethphy2: ethernet-phy@2 {
-+ reg = <2>;
-+ };
-+
-+ ethphy3: ethernet-phy@3 {
-+ reg = <3>;
-+ };
-+ };
-+ };
- };
-
- &srab {
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch
deleted file mode 100644
index 6118e98cc5..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From de7880016665afe7fa7d40e1fafa859260d53ba1 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 28 Oct 2021 09:03:44 +0200
-Subject: [PATCH] ARM: BCM53016: MR32: convert to Broadcom iProc I2C Driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-replaces the bit-banged i2c-gpio provided i2c functionality
-with the hardware in the SoC.
-
-During review of the MR32, Florian Fainelli pointed out that the
-SoC has a real I2C-controller. Furthermore, the connected pins
-(SDA and SCL) would line up perfectly for use. Back then I couldn't
-get it working though and I left it with i2c-gpio (which worked).
-
-Now we know the reason: the interrupt was incorrectly specified.
-(Hence, this patch depends on Florian Fainelli's
-"ARM: dts: BCM5301X: Fix I2C controller interrupt" patch).
-
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Cc: Rafał Miłecki <zajec5@gmail.com>
-Cc: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 62 ++++++++++------------
- 1 file changed, 28 insertions(+), 34 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -84,40 +84,6 @@
- max-brightness = <255>;
- };
- };
--
-- i2c {
-- /*
-- * The platform provided I2C does not budge.
-- * This is a replacement until I can figure
-- * out what are the missing bits...
-- */
--
-- compatible = "i2c-gpio";
-- sda-gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-- scl-gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
-- i2c-gpio,delay-us = <10>; /* close to 100 kHz */
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- current_sense: ina219@45 {
-- compatible = "ti,ina219";
-- reg = <0x45>;
-- shunt-resistor = <60000>; /* = 60 mOhms */
-- };
--
-- eeprom: eeprom@50 {
-- compatible = "atmel,24c64";
-- reg = <0x50>;
-- pagesize = <32>;
-- read-only;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- mac_address: mac-address@66 {
-- reg = <0x66 0x6>;
-- };
-- };
-- };
- };
-
- &uart0 {
-@@ -250,3 +216,31 @@
- };
- };
- };
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinmux_i2c>;
-+
-+ clock-frequency = <100000>;
-+
-+ current_sense: ina219@45 {
-+ compatible = "ti,ina219";
-+ reg = <0x45>;
-+ shunt-resistor = <60000>; /* = 60 mOhms */
-+ };
-+
-+ eeprom: eeprom@50 {
-+ compatible = "atmel,24c64";
-+ reg = <0x50>;
-+ pagesize = <32>;
-+ read-only;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ mac_address: mac-address@66 {
-+ reg = <0x66 0x6>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch
deleted file mode 100644
index e01927bedf..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 1a46061a2a4130a08841941ce6dcaa32be2ce312 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 23 Nov 2021 10:03:33 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: use non-deprecated USB 2.0 PHY binding
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The new binding covers a single reg and uses syscon to reference shared
-register.
-
-References: 55b9b741712d ("dt-bindings: phy: brcm,ns-usb2-phy: bind just a PHY block")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm5301x.dtsi | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -148,15 +148,6 @@
- };
- };
-
-- usb2_phy: usb2-phy@1800c000 {
-- compatible = "brcm,ns-usb2-phy";
-- reg = <0x1800c000 0x1000>;
-- reg-names = "dmu";
-- #phy-cells = <0>;
-- clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-- clock-names = "phy-ref-clk";
-- };
--
- axi@18000000 {
- compatible = "brcm,bus-axi";
- reg = <0x18000000 0x1000>;
-@@ -450,7 +441,16 @@
- "sata1", "sata2";
- };
-
-- syscon@180 {
-+ usb2_phy: phy@164 {
-+ compatible = "brcm,ns-usb2-phy";
-+ reg = <0x164 0x4>;
-+ brcm,syscon-clkset = <&cru_clkset>;
-+ clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-+ clock-names = "phy-ref-clk";
-+ #phy-cells = <0>;
-+ };
-+
-+ cru_clkset: syscon@180 {
- compatible = "brcm,cru-clkset", "syscon";
- reg = <0x180 0x4>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch
deleted file mode 100644
index 730b989808..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 69c4e53bdd055ecc27761f6971a50c631ff9072e Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Thu, 2 Dec 2021 15:16:27 -0800
-Subject: [PATCH] ARM: dts: NSP: Fixed iProc PCIe MSI sub-node
-
-Rename the msi controller unit name to 'msi' to avoid collisions with
-the 'msi-controller' boolean property.
-
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -587,7 +587,7 @@
- status = "disabled";
-
- msi-parent = <&msi0>;
-- msi0: msi-controller {
-+ msi0: msi {
- compatible = "brcm,iproc-msi";
- msi-controller;
- interrupt-parent = <&gic>;
-@@ -624,7 +624,7 @@
- status = "disabled";
-
- msi-parent = <&msi1>;
-- msi1: msi-controller {
-+ msi1: msi {
- compatible = "brcm,iproc-msi";
- msi-controller;
- interrupt-parent = <&gic>;
-@@ -661,7 +661,7 @@
- status = "disabled";
-
- msi-parent = <&msi2>;
-- msi2: msi-controller {
-+ msi2: msi {
- compatible = "brcm,iproc-msi";
- msi-controller;
- interrupt-parent = <&gic>;
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch
deleted file mode 100644
index fd90fbf1f6..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 9a68c53f875e88edd3403c001ad85f4ac0ed3486 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Tue, 7 Dec 2021 10:19:09 -0800
-Subject: [PATCH] ARM: dts: NSP: Rename SATA unit name
-
-Rename the SATA controller unit name from ahci to sata in preparation
-for adding the Broadcom SATA3 controller YAML binding which will bring
-validation.
-
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -534,7 +534,7 @@
- };
- };
-
-- sata: ahci@41000 {
-+ sata: sata@41000 {
- compatible = "brcm,bcm-nsp-ahci";
- reg-names = "ahci", "top-ctrl";
- reg = <0x41000 0x1000>, <0x40020 0x1c>;
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch
deleted file mode 100644
index e81ec169b9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 5e33f1c4a7cb914a003a304ab8eef705b17aabb7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 17 Dec 2021 00:03:19 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: correct RX delay and enable flow control
- on Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The current 'rx-internal-delay-ps' property value on the Realtek switch
-node, 2000, will be divided by 300, resulting in 6.66, which will be
-rounded to the closest step value, 7. Change it to 2100 to be accurate.
-See ef136837aaf6 ("net: dsa: rtl8365mb: set RGMII RX delay in steps of
-0.3 ns") for reference.
-
-Flow control needs to be enabled on both sides of the internal and
-external switch. It is already enabled on the CPU port of the Realtek
-switch so we also enable it on the external switch port of the Broadcom
-switch as well.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -138,7 +138,7 @@
- ethernet = <&sw0_p5>;
- phy-mode = "rgmii";
- tx-internal-delay-ps = <2000>;
-- rx-internal-delay-ps = <2000>;
-+ rx-internal-delay-ps = <2100>;
-
- fixed-link {
- speed = <1000>;
-@@ -213,6 +213,7 @@
- fixed-link {
- speed = <1000>;
- full-duplex;
-+ pause;
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch
deleted file mode 100644
index 3d814b1252..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 8b0c59c622dc4dab970ec63264fb5b152944ac80 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Thu, 23 Dec 2021 00:17:17 +0100
-Subject: [PATCH] Revert "ARM: dts: BCM5301X: define RTL8365MB switch on Asus
- RT-AC88U"
-
-This reverts commit 3d2d52a0d1835b56f6bd67d268f6c39df0e41692, it caused
-a build regression:
-
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts:109.4-14: Warning (reg_format): /switch/ports:reg: property has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (pci_device_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts:106.9-149.5: Warning (avoid_default_addr_size): /switch/ports: Relying on default #address-cells value
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts:106.9-149.5: Warning (avoid_default_addr_size): /switch/ports: Relying on default #size-cells value
-
-Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 77 --------------------
- 1 file changed, 77 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -93,83 +93,6 @@
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
- };
--
-- switch {
-- compatible = "realtek,rtl8365mb";
-- /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-- mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
-- mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
-- reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-- realtek,disable-leds;
-- dsa,member = <1 0>;
--
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
-- reg = <0>;
--
-- port@0 {
-- reg = <0>;
-- label = "lan5";
-- phy-handle = <&ethphy0>;
-- };
--
-- port@1 {
-- reg = <1>;
-- label = "lan6";
-- phy-handle = <&ethphy1>;
-- };
--
-- port@2 {
-- reg = <2>;
-- label = "lan7";
-- phy-handle = <&ethphy2>;
-- };
--
-- port@3 {
-- reg = <3>;
-- label = "lan8";
-- phy-handle = <&ethphy3>;
-- };
--
-- port@6 {
-- reg = <6>;
-- label = "cpu";
-- ethernet = <&sw0_p5>;
-- phy-mode = "rgmii";
-- tx-internal-delay-ps = <2000>;
-- rx-internal-delay-ps = <2100>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- pause;
-- };
-- };
-- };
--
-- mdio {
-- compatible = "realtek,smi-mdio";
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ethphy0: ethernet-phy@0 {
-- reg = <0>;
-- };
--
-- ethphy1: ethernet-phy@1 {
-- reg = <1>;
-- };
--
-- ethphy2: ethernet-phy@2 {
-- reg = <2>;
-- };
--
-- ethphy3: ethernet-phy@3 {
-- reg = <3>;
-- };
-- };
-- };
- };
-
- &srab {
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
deleted file mode 100644
index 77d3420ff8..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 441d531ec9b766f49e01c107a3043235daa4493f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sun, 2 Jan 2022 23:33:04 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Define the Realtek RTL8365MB switch without interrupt support on the device
-tree of Asus RT-AC88U.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 76 ++++++++++++++++++++
- 1 file changed, 76 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -93,6 +93,82 @@
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
- };
-+
-+ switch {
-+ compatible = "realtek,rtl8365mb";
-+ /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-+ mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
-+ mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
-+ reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-+ realtek,disable-leds;
-+ dsa,member = <1 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "lan5";
-+ phy-handle = <&ethphy0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan6";
-+ phy-handle = <&ethphy1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan7";
-+ phy-handle = <&ethphy2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan8";
-+ phy-handle = <&ethphy3>;
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&sw0_p5>;
-+ phy-mode = "rgmii";
-+ tx-internal-delay-ps = <2000>;
-+ rx-internal-delay-ps = <2100>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+ };
-+
-+ mdio {
-+ compatible = "realtek,smi-mdio";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ethphy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+
-+ ethphy1: ethernet-phy@1 {
-+ reg = <1>;
-+ };
-+
-+ ethphy2: ethernet-phy@2 {
-+ reg = <2>;
-+ };
-+
-+ ethphy3: ethernet-phy@3 {
-+ reg = <3>;
-+ };
-+ };
-+ };
- };
-
- &srab {
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch
deleted file mode 100644
index 19cf1fe952..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 66848aff05f669e95795b5f3a163f4762781333e Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Wed, 23 Feb 2022 23:50:39 +0000
-Subject: [PATCH] ARM: dts: NSP: MX6X: get mac-address from eeprom
-
-The MAC address on the MX64/MX65 series is located on the AT24 EEPROM.
-This is the same as other Meraki devices such as the MR32 [1].
-
-[1] https://lore.kernel.org/linux-arm-kernel/fa8271d02ef74a687f365cebe5c55ec846963ab7.1631986106.git.chunkeey@gmail.com/
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -39,6 +39,8 @@
-
- &amac2 {
- status = "okay";
-+ nvmem-cells = <&mac_address>;
-+ nvmem-cell-names = "mac-address";
- };
-
- &ehci0 {
-@@ -53,6 +55,12 @@
- reg = <0x50>;
- pagesize = <32>;
- read-only;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ mac_address: mac-address@66 {
-+ reg = <0x66 0x6>;
-+ };
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch
deleted file mode 100644
index 2da45ff9da..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 482c85c7fc95c572d368b2214b9e9d2c4a2e5789 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Wed, 23 Feb 2022 23:50:40 +0000
-Subject: [PATCH] ARM: dts: NSP: MX6X: correct LED function types
-
-Currently, the amber LED will remain always on. This is due to a
-misinterpretation of the LED sub-node properties, where-by "default-state"
-was used to indicate the initial state when powering on the device. When in
-use, however, this resulted in the amber LED always being on. Instead change
-this to only indicate a fault state.
-
-Assign LED_FUNCTION_POWER to the green PWM LED.
-
-These changes bring the MX64/65 in line with the MR32's devicetree.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 3 +--
- arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi | 3 +--
- arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 2 +-
- 3 files changed, 3 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -57,10 +57,9 @@
-
- led-4 {
- /* amber:power */
-- function = LED_FUNCTION_POWER;
-+ function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&gpioa 3 GPIO_ACTIVE_HIGH>;
-- default-state = "on";
- };
-
- led-5 {
---- a/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-@@ -106,10 +106,9 @@
-
- led-a {
- /* amber:power */
-- function = LED_FUNCTION_POWER;
-+ function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&gpioa 0 GPIO_ACTIVE_LOW>;
-- default-state = "on";
- };
-
- led-b {
---- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -22,7 +22,7 @@
- };
-
- led-2 {
-- function = LED_FUNCTION_INDICATOR;
-+ function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
- pwms = <&pwm 2 50000>;
- max-brightness = <255>;
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch
deleted file mode 100644
index c70fbc398b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From c8442f0fb09ca3d842b9b23d1d0650f649fd10f8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 28 Feb 2022 10:52:07 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: Add Ethernet MAC address to Luxul
- XWR-3150
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Luxul XWR-3150 stores MAC as NVRAM variable. Add NVMEM cell for it and
-reference it in the Ethernet interface node.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -25,6 +25,9 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
- };
-
- leds {
-@@ -72,6 +75,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb3 {
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch
deleted file mode 100644
index e61fef8aab..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 90103611d573c5c238350f9b1d7cb682c62f5681 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:19:58 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Fix DTC warning for NAND node
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove the unnecessary #address-cells and #size-cells properties on the
-nand@0 node to fix the warning below.
-
-Warning (avoid_unnecessary_addr_size): /nand-controller@18028000/nand@0: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-@@ -10,8 +10,6 @@
- nandcs: nand@0 {
- compatible = "brcm,nandcs";
- reg = <0>;
-- #address-cells = <1>;
-- #size-cells = <1>;
-
- partitions {
- compatible = "brcm,bcm947xx-cfe-partitions";
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch
deleted file mode 100644
index 6ef8720b1d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From e5ff0a7aab3ef5dd8ec7636b936c95179aa5ddfa Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:19:59 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Remove cell properties from srab ports on
- Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove #address-cells and #size-cells properties from the ports node of
-&srab. They are already defined on bcm5301x.dtsi, there's no need to define
-them again.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- /*
-- * Copyright (C) 2021 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ * Copyright (C) 2021-2022 Arınç ÜNAL <arinc.unal@arinc9.com>
- */
-
- /dts-v1/;
-@@ -177,9 +177,6 @@
- dsa,member = <0 0>;
-
- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
--
- port@0 {
- reg = <0>;
- label = "lan4";
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch
deleted file mode 100644
index aa192b3a11..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 4b7a67420a34ebd8fbf0111221a8bfd8001d418d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:20:00 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Add rgmii to port@5 of Broadcom switch on
- Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Define phy-mode of the Broadcom switch's port@5 as rgmii. This doesn't seem
-to matter but let's explicitly define it since phy-mode as rgmii is defined
-on the other side which is port@6 of the Realtek switch.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -205,6 +205,7 @@
- sw0_p5: port@5 {
- reg = <5>;
- label = "extsw";
-+ phy-mode = "rgmii";
-
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch
deleted file mode 100644
index 4c0858be0a..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 7f7f8c7b9f3cbae1355fb3b0ce4ea9d6f1552521 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:20:01 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Retrieve gmac1 MAC address from NVRAM on
- Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The et1macaddr NVRAM variable contains a MAC address for gmac1 on Asus
-RT-AC88U. Add NVMEM cell for it and reference it in the gmac1 node.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -25,6 +25,9 @@
- nvram@1c080000 {
- compatible = "brcm,nvram";
- reg = <0x1c080000 0x00180000>;
-+
-+ et1macaddr: et1macaddr {
-+ };
- };
-
- leds {
-@@ -239,6 +242,11 @@
- };
- };
-
-+&gmac1 {
-+ nvmem-cells = <&et1macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb2 {
- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch
deleted file mode 100644
index 59e99dae62..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 69bb5c6f3f41fe6baa86a775c8a3e69dd27f85d6 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sat, 2 Apr 2022 23:46:21 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Fix compatible strings for BCM53012 and
- BCM53016 SoC
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Fix compatible strings for devicetrees using the BCM53012 and BCM53016 SoC.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +-
- arch/arm/boot/dts/bcm953012er.dts | 2 +-
- arch/arm/boot/dts/bcm953012hr.dts | 2 +-
- arch/arm/boot/dts/bcm953012k.dts | 2 +-
- 4 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -13,7 +13,7 @@
- #include <dt-bindings/leds/common.h>
-
- / {
-- compatible = "meraki,mr32", "brcm,brcm53016", "brcm,bcm4708";
-+ compatible = "meraki,mr32", "brcm,bcm53016", "brcm,bcm4708";
- model = "Meraki MR32";
-
- chosen {
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Enterprise Router (BCM953012ER)";
-- compatible = "brcm,bcm953012er", "brcm,brcm53012", "brcm,bcm4708";
-+ compatible = "brcm,bcm953012er", "brcm,bcm53012", "brcm,bcm4708";
-
- memory@0 {
- device_type = "memory";
---- a/arch/arm/boot/dts/bcm953012hr.dts
-+++ b/arch/arm/boot/dts/bcm953012hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar HR (BCM953012HR)";
-- compatible = "brcm,bcm953012hr", "brcm,brcm53012", "brcm,bcm4708";
-+ compatible = "brcm,bcm953012hr", "brcm,bcm53012", "brcm,bcm4708";
-
- aliases {
- ethernet0 = &gmac0;
---- a/arch/arm/boot/dts/bcm953012k.dts
-+++ b/arch/arm/boot/dts/bcm953012k.dts
-@@ -36,7 +36,7 @@
-
- / {
- model = "NorthStar SVK (BCM953012K)";
-- compatible = "brcm,bcm953012k", "brcm,brcm53012", "brcm,bcm4708";
-+ compatible = "brcm,bcm953012k", "brcm,bcm53012", "brcm,bcm4708";
-
- aliases {
- serial0 = &uart0;
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch
deleted file mode 100644
index f75a53777f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From b9cff8783439ff1803709128af3a0e04c5f5f047 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sun, 10 Apr 2022 12:44:55 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Disable gmac0 and enable port@8 on Asus
- RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Disable gmac0 which is not connected to any switch MAC. Enable port@8 of
-the Broadcom switch which is connected to gmac2.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -232,7 +232,6 @@
- reg = <8>;
- ethernet = <&gmac2>;
- label = "cpu";
-- status = "disabled";
-
- fixed-link {
- speed = <1000>;
-@@ -242,6 +241,10 @@
- };
- };
-
-+&gmac0 {
-+ status = "disabled";
-+};
-+
- &gmac1 {
- nvmem-cells = <&et1macaddr>;
- nvmem-cell-names = "mac-address";
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch
deleted file mode 100644
index c6f1cbd5e2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch
+++ /dev/null
@@ -1,300 +0,0 @@
-From 417aea4436bb658d8c5c4dcd0e3c255931d0ee96 Mon Sep 17 00:00:00 2001
-From: SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-Date: Fri, 22 Apr 2022 00:10:54 +0900
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for WZR-1166DHP,DHP2
-
-Buffalo WZR-1166DHP/WZR-1166DHP2 wireless router with
-
- - BCM4708A0
- - 128MiB NAND flash
- - 2T2R 11ac/a/b/g/n Wi-Fi
- - 4x 10/100/1000M ethernet switch
- - 1x USB 3.0 port
-
- WZR-1166DHP and WZR-1166DHP2 have different memory capacity.
-
- WZR-1166DHP
- - 512 MiB DDR2 SDRAM
-
- WZR-1166DHP2
- - 256 MiB DDR2 SDRAM
-
- These hardware components are very similar to the WZR-1750DHP
- except for the number of antennas.
-
-Signed-off-by: SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 2 +
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 192 ++++++++++++++++++
- .../boot/dts/bcm4708-buffalo-wzr-1166dhp.dts | 26 +++
- .../boot/dts/bcm4708-buffalo-wzr-1166dhp2.dts | 26 +++
- 4 files changed, 246 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
- create mode 100644 arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp.dts
- create mode 100644 arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp2.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -98,6 +98,8 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4708-asus-rt-ac56u.dtb \
- bcm4708-asus-rt-ac68u.dtb \
- bcm4708-buffalo-wzr-1750dhp.dtb \
-+ bcm4708-buffalo-wzr-1166dhp.dtb \
-+ bcm4708-buffalo-wzr-1166dhp2.dtb \
- bcm4708-linksys-ea6300-v1.dtb \
- bcm4708-linksys-ea6500-v2.dtb \
- bcm4708-luxul-xap-1510.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -0,0 +1,192 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * DTS for Buffalo WZR-1166DHP and WZR-1166DHP2
-+ *
-+ * Copyright (C) 2014 Rafał Miłecki <zajec5@gmail.com>
-+ * Copyright (C) 2022 SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-+ */
-+
-+
-+#include "bcm4708.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ spi {
-+ compatible = "spi-gpio";
-+ num-chipselects = <1>;
-+ gpio-sck = <&chipcommon 7 0>;
-+ gpio-mosi = <&chipcommon 4 0>;
-+ cs-gpios = <&chipcommon 6 0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ hc595: gpio_spi@0 {
-+ compatible = "fairchild,74hc595";
-+ reg = <0>;
-+ registers-number = <1>;
-+ spi-max-frequency = <100000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ usb {
-+ /* label = "bcm53xx:blue:usb"; */
-+ function = LED_FUNCTION_USB;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>,
-+ <&xhci_port1>, <&ohci_port2>,
-+ <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ power0 {
-+ /* label = "bcm53xx:red:power"; */
-+ function = LED_FUNCTION_FAULT;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ power1 {
-+ /* label = "bcm53xx:white:power"; */
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_WHITE>;
-+ gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ router0 {
-+ /* label = "bcm53xx:blue:router"; */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ router1 {
-+ /* label = "bcm53xx:amber:router"; */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ wan {
-+ /* label = "bcm53xx:blue:wan"; */
-+ function = LED_FUNCTION_WAN;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wireless0 {
-+ /* label = "bcm53xx:blue:wireless"; */
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ wireless1 {
-+ /* label = "bcm53xx:amber:wireless"; */
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ restart {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ aoss {
-+ label = "AOSS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Commit mode set by switch? */
-+ mode {
-+ label = "Mode";
-+ linux,code = <KEY_SETUP>;
-+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Switch: AP mode */
-+ sw_ap {
-+ label = "AP";
-+ linux,code = <BTN_0>;
-+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ eject {
-+ label = "USB eject";
-+ linux,code = <KEY_EJECTCD>;
-+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3 {
-+ vcc-gpio = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-+};
-+
-+&spi_nor {
-+ status = "okay";
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp.dts
-@@ -0,0 +1,26 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindigs for Buffalo WZR-1166DHP
-+ *
-+ * Copyright (C) 2022 SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4708-buffalo-wzr-1166dhp-common.dtsi"
-+
-+/ {
-+ compatible = "buffalo,wzr-1166dhp", "brcm,bcm4708";
-+ model = "Buffalo WZR-1166DHP";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp2.dts
-@@ -0,0 +1,26 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindigs for Buffalo WZR-1166DHP2
-+ *
-+ * Copyright (C) 2022 SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4708-buffalo-wzr-1166dhp-common.dtsi"
-+
-+/ {
-+ compatible = "buffalo,wzr-1166dhp2", "brcm,bcm4708";
-+ model = "Buffalo WZR-1166DHP2";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch
deleted file mode 100644
index cc7e9741a7..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 18176b9d82eebaf4408dc0440f54d57a8cbced83 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Fri, 13 May 2022 11:11:07 +0200
-Subject: [PATCH] Revert "ARM: dts: BCM5301X: Fix DTC warning for NAND node"
-
-This reverts commit 90103611d573, which caused a new DTC warning
-
-arch/arm/boot/dts/bcm953012hr.dts:57.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@0:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dts:62.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@200000:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dts:66.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@600000:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dts:70.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@1000000:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (pci_device_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-@@ -10,6 +10,8 @@
- nandcs: nand@0 {
- compatible = "brcm,nandcs";
- reg = <0>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-
- partitions {
- compatible = "brcm,bcm947xx-cfe-partitions";
diff --git a/target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch b/target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch
deleted file mode 100644
index 1c0708a5f0..0000000000
--- a/target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch
+++ /dev/null
@@ -1,912 +0,0 @@
-From c5aec5611aec8fb1ca68f68e41acaefccfc93c16 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Thu, 9 Jun 2022 13:39:30 +0200
-Subject: [PATCH] ARM: dts: broadcom: align gpio-key node names with dtschema
-
-The node names should be generic and DT schema expects certain pattern
-(e.g. with key/button/switch).
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 6 +++---
- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 8 ++++----
- .../boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 10 +++++-----
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 10 +++++-----
- arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts | 4 ++--
- arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts | 4 ++--
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 2 +-
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 6 +++---
- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 6 +++---
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 6 +++---
- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 8 ++++----
- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 2 +-
- arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts | 4 ++--
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 4 ++--
- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 12 ++++++------
- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 4 ++--
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 6 +++---
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 8 ++++----
- arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts | 4 ++--
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 8 ++++----
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 6 +++---
- arch/arm/boot/dts/bcm47094-linksys-panamera.dts | 6 +++---
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 2 +-
- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 8 ++++----
- arch/arm/boot/dts/bcm47094-phicomm-k3.dts | 2 +-
- arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 2 +-
- arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 2 +-
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 6 +++---
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +-
- arch/arm/boot/dts/bcm911360_entphn.dts | 4 ++--
- arch/arm/boot/dts/bcm947189acdbmr.dts | 4 ++--
- arch/arm/boot/dts/bcm953012er.dts | 4 ++--
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 2 +-
- arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi | 2 +-
- 43 files changed, 97 insertions(+), 97 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -70,19 +70,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -54,25 +54,25 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- brightness {
-+ button-brightness {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -104,33 +104,33 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
- /* Commit mode set by switch? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: AP mode */
-- sw_ap {
-+ button-sw-ap {
- label = "AP";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -100,33 +100,33 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
- /* Commit mode set by switch? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: AP mode */
-- sw_ap {
-+ button-sw-ap {
- label = "AP";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-@@ -29,13 +29,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-@@ -26,13 +26,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -45,7 +45,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -52,7 +52,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -63,19 +63,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -59,19 +59,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -94,19 +94,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -60,13 +60,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -91,26 +91,26 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch device mode? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -96,7 +96,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -45,7 +45,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -94,7 +94,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -77,13 +77,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -50,13 +50,13 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -80,39 +80,39 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- power {
-+ button-power {
- label = "Power";
- linux,code = <KEY_POWER>;
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- };
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
- /* Commit mode set by switch? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: AP mode */
-- sw_ap {
-+ button-sw-ap {
- label = "AP";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -32,13 +32,13 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -75,19 +75,19 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -102,25 +102,25 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- brightness {
-+ button-brightness {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -80,13 +80,13 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -72,25 +72,25 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
- };
-
-- reset {
-+ button-reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- wifi {
-+ button-wifi {
- label = "Wi-Fi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
-
-- led {
-+ button-led {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -86,20 +86,20 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: router / extender */
-- extender {
-+ button-extender {
- label = "Extender";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -30,19 +30,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
-- reset {
-+ button-reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -49,7 +49,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -43,7 +43,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -49,7 +49,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -37,7 +37,7 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -89,7 +89,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -67,7 +67,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -65,25 +65,25 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- brightness {
-+ button-brightness {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -22,7 +22,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -38,7 +38,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -47,7 +47,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -59,19 +59,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -50,7 +50,7 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm911360_entphn.dts
-+++ b/arch/arm/boot/dts/bcm911360_entphn.dts
-@@ -47,10 +47,10 @@
- stdout-path = "serial0:115200n8";
- };
-
-- gpio_keys {
-+ gpio-keys {
- compatible = "gpio-keys";
-
-- hook {
-+ button-hook {
- label = "HOOK";
- linux,code = <KEY_O>;
- gpios = <&gpio_asiu 48 0>;
---- a/arch/arm/boot/dts/bcm947189acdbmr.dts
-+++ b/arch/arm/boot/dts/bcm947189acdbmr.dts
-@@ -44,13 +44,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -47,13 +47,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -13,7 +13,7 @@
- autorepeat;
- poll-interval = <20>;
-
-- reset {
-+ button-reset {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&gpioa 8 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-@@ -14,7 +14,7 @@
- autorepeat;
- poll-interval = <20>;
-
-- reset {
-+ button-reset {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&gpioa 6 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch b/target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch
deleted file mode 100644
index 7bded431b0..0000000000
--- a/target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From d634a6969c03803a945fdc2bccbe7d813420e569 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Thu, 9 Jun 2022 13:39:31 +0200
-Subject: [PATCH] ARM: dts: broadcom: correct gpio-keys properties
-
-gpio-keys children do not use unit addresses.
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 2 --
- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 2 --
- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 2 --
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 2 --
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 2 --
- arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts | 2 --
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 --
- 8 files changed, 16 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -47,8 +47,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -77,8 +77,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-power {
- label = "Power";
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -29,8 +29,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -72,8 +72,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -99,8 +99,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-rfkill {
- label = "WiFi";
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -77,8 +77,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -34,8 +34,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-restart {
- label = "Reset";
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -47,8 +47,6 @@
-
- keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-restart {
- label = "Reset";
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
deleted file mode 100644
index 206726f5f6..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From 9f66e1dd82e3186aee95282657512ca2aef1afe0 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 19 Oct 2022 21:34:49 +0200
-Subject: [PATCH] ARM: dts: bcm53016: Add devicetree for D-Link DWL-8610AP
-
-This adds a device tree for the BCM53016-based D-Link DWL-8610AP
-access point wireless router.
-
-The TRX-format partitions had to be named "firmware" due to
-an OpenWrt patch that only accepts parting such nodes if they
-are named "firmware".
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221019193449.3036010-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 131 ++++++++++++++++++
- 2 files changed, 132 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -131,6 +131,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm47094-netgear-r8500.dtb \
- bcm47094-phicomm-k3.dtb \
- bcm53015-meraki-mr26.dtb \
-+ bcm53016-dlink-dwl-8610ap.dtb \
- bcm53016-meraki-mr32.dtb \
- bcm94708.dtb \
- bcm94709.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -0,0 +1,131 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+ model = "D-Link DWL-8610AP";
-+ compatible = "dlink,dwl-8610ap", "brcm,bcm53016", "brcm,bcm4708";
-+
-+ memory@0 {
-+ device_type = "memory";
-+ /* 512 MB RAM in 2 x Macronix D9PSH chips */
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ power {
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ };
-+
-+ diag {
-+ /* Actually "diag" unclear what this means */
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ linux,default-trigger = "heartbeat";
-+ };
-+
-+ wlan-2g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wlan-5g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio_keys {
-+ compatible = "gpio-keys";
-+
-+ button-reset {
-+ debounce-interval = <100>;
-+ wakeup-source;
-+ linux,code = <KEY_RESTART>;
-+ label = "reset";
-+ /* This GPIO is actually stored in NVRAM, but it's not gonna change */
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * Flash memory at 0x1e000000-0x1fffffff
-+ * Macronix 32 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e080000 0x00020000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+
-+ et1macaddr: et1macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&gmac1 {
-+ nvmem-cells = <&et1macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ /* Serial SPI NOR Flash MX 25L1606E */
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /*
-+ * Spansion S34ML01G100TFI00 128 MB NAND Flash memory
-+ *
-+ * This ECC is a bit unorthodox but it is what the stock firmware
-+ * is using, so to be able to mount the original partitions
-+ * this is necessary.
-+ */
-+ nand-ecc-strength = <5>;
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /* This is named nflash1.trx in CFE */
-+ trx@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.trx2 in CFE */
-+ trx2@2800000 {
-+ label = "firmware2";
-+ reg = <0x02800000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.rwfs in CFE */
-+ free@5000000 {
-+ label = "free";
-+ reg = <0x05000000 0x03000000>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
deleted file mode 100644
index 4842e16649..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From b1ba87897ceda8e49a47aa92832dd7bff8583e21 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Nov 2022 14:41:04 +0100
-Subject: [PATCH] ARM: dts: bcm47094: Add devicetree for D-Link DIR-890L
-
-This adds a device tree for the D-Link DIR-890L. This device
-is very similar to D-Link DIR-885L, the differences are detailed
-as a comment in the DTS file.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221107134104.1422169-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 211 ++++++++++++++++++
- 2 files changed, 212 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -121,6 +121,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
-+ bcm47094-dlink-dir-890l.dtb \
- bcm47094-linksys-panamera.dtb \
- bcm47094-luxul-abr-4500.dtb \
- bcm47094-luxul-xap-1610.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -0,0 +1,211 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device tree for D-Link DIR-890L
-+ * D-Link calls this board "WRGAC36"
-+ * this router has the same looks and form factor as D-Link DIR-885L.
-+ *
-+ * Some differences from DIR-885L include a separate USB2 port, separate LEDs
-+ * for USB2 and USB3, a separate VCC supply for the USB2 slot and no
-+ * router/extender switch is mounted (there is an empty mount point on the
-+ * PCB) so this device is a pure router. Also the LAN ports are in the right
-+ * order.
-+ *
-+ * Based on the device tree for DIR-885L
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ * Copyright (C) 2022 Linus Walleij
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch1.dtsi"
-+
-+/ {
-+ compatible = "dlink,dir-890l", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "D-Link DIR-890L";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200 earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ /*
-+ * LED information is derived from the boot log which
-+ * conveniently lists all the LEDs.
-+ */
-+ compatible = "gpio-leds";
-+
-+ power-white {
-+ label = "bcm53xx:white:power";
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wan-white {
-+ label = "bcm53xx:white:wan";
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ power-amber {
-+ label = "bcm53xx:amber:power";
-+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wan-amber {
-+ label = "bcm53xx:amber:wan";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ usb3-white {
-+ label = "bcm53xx:white:usb3";
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ usb2-white {
-+ label = "bcm53xx:white:usb2";
-+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ 2ghz {
-+ label = "bcm53xx:white:2ghz";
-+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ 5ghz {
-+ label = "bcm53xx:white:5ghz";
-+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Called "factory reset" in the vendor dmesg */
-+ button-restart {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * The flash memory is memory mapped at 0x1e000000-0x1fffffff
-+ * 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e1f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e1f0000 0x00010000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac2 {
-+ /*
-+ * The NVRAM curiously does not contain a MAC address
-+ * for et2 so since that is the only ethernet interface
-+ * actually in use on the platform, we use this et0 MAC
-+ * address for et2.
-+ */
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /* Spansion S34ML01G2, 128MB with 128KB erase blocks */
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /*
-+ * This is called "nflash" in the vendor kernel with
-+ * "upgrade" and "rootfs" (probably using OpenWrt
-+ * splitpart). We call it "firmware" like standard tools
-+ * assume. The CFE loader contains incorrect information
-+ * about TRX partitions, ignore this, there are no TRX
-+ * partitions: this device uses SEAMA.
-+ */
-+ firmware@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x08000000>;
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3 {
-+ vcc-gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
deleted file mode 100644
index 4c4ed036b9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From c8ee9f119bfb4244f76c9971c341ec06b49332cd Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 8 Nov 2022 12:07:08 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: Correct description of TP-Link partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-TP-Link routers have flash space partitioned according to the partitions
-table. It may look like fixed partitioning but those partitions can be
-actually reorganized. New can be added (or some removed), offsets and
-sizes may change.
-
-Fix DT to use binding for the TP-Link SafeLoader partitioning method.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221108110708.13693-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 25 ++++---------------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 25 ++++---------------
- 2 files changed, 10 insertions(+), 40 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -95,30 +95,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -104,30 +104,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
deleted file mode 100644
index a53070a506..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
+++ /dev/null
@@ -1,1698 +0,0 @@
-From af84101e3f2258a303fa2461ebec0878ce23ea10 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Fri, 25 Nov 2022 15:41:27 +0100
-Subject: [PATCH] ARM: dts: broadcom: align LED node names with dtschema
-
-The node names should be generic and DT schema expects certain pattern:
-
- bcm4708-asus-rt-ac68u.dtb: leds: 'logo', 'power', 'usb2', 'usb3' do not match any of the regexes: '(^led-[0-9a-f]$|led)', 'pinctrl-[0-9]+'
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20221125144128.477059-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 15 +++++-----
- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 8 +++---
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 16 +++++------
- .../boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 6 ++--
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 10 +++----
- .../arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 10 +++----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 22 +++++++--------
- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 10 +++----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 14 +++++-----
- .../boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 6 ++--
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 20 ++++++-------
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 6 ++--
- .../boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 16 +++++------
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 22 +++++++--------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 18 ++++++------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 12 ++++----
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 16 +++++------
- .../boot/dts/bcm47094-linksys-panamera.dts | 28 +++++++++----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 6 ++--
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 20 ++++++-------
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 10 +++----
- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 4 +--
- arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 10 +++----
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 14 +++++-----
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 8 +++---
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 6 ++--
- arch/arm/boot/dts/bcm947189acdbmr.dts | 6 ++--
- 37 files changed, 223 insertions(+), 224 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -28,40 +28,39 @@
- leds {
- compatible = "gpio-leds";
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- all {
-+ led-all {
- label = "bcm53xx:blue:all";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
--
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -28,24 +28,24 @@
- leds {
- compatible = "gpio-leds";
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -37,7 +37,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- /* label = "bcm53xx:blue:usb"; */
- function = LED_FUNCTION_USB;
- color = <LED_COLOR_ID_BLUE>;
-@@ -48,14 +48,14 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- /* label = "bcm53xx:red:power"; */
- function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_RED>;
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- /* label = "bcm53xx:white:power"; */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_WHITE>;
-@@ -63,7 +63,7 @@
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- /* label = "bcm53xx:blue:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_BLUE>;
-@@ -71,14 +71,14 @@
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- /* label = "bcm53xx:amber:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- /* label = "bcm53xx:blue:wan"; */
- function = LED_FUNCTION_WAN;
- color = <LED_COLOR_ID_BLUE>;
-@@ -86,14 +86,14 @@
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- /* label = "bcm53xx:blue:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- /* label = "bcm53xx:amber:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_AMBER>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -49,7 +49,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -58,40 +58,40 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:white:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:blue:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:blue:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -42,7 +42,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -29,24 +29,24 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -54,7 +54,7 @@
- linux,default-trigger = "usbport";
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -28,29 +28,29 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -28,64 +28,64 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-green {
-+ led-usb3-green {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- status-red {
-+ led-status-red {
- label = "bcm53xx:red:status";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- status-green {
-+ led-status-green {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- status-blue {
-+ led-status-blue {
- label = "bcm53xx:blue:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-red {
-+ led-wan-red {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -28,30 +28,30 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -49,40 +49,40 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -49,45 +49,45 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -29,62 +29,62 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -23,50 +23,50 @@
- leds {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:green:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port1 {
-+ led-usb2-port1 {
- label = "bcm53xx:green:usb2-port1";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wan-green {
-+ led-wan-green {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:green:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port2 {
-+ led-usb2-port2 {
- label = "bcm53xx:green:usb2-port2";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -28,18 +28,18 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -28,48 +28,48 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router-amber {
-+ led-router-amber {
- label = "bcm53xx:amber:router";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- };
-
-- router-white {
-+ led-router-white {
- label = "bcm53xx:white:router";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-amber {
-+ led-wireless-amber {
- label = "bcm53xx:amber:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-white {
-+ led-wireless-white {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -28,43 +28,43 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -39,59 +39,59 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -23,27 +23,27 @@
- leds {
- compatible = "gpio-leds";
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -51,24 +51,24 @@
- linux,default-trigger = "usbport";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- wan-blue {
-+ led-wan-blue {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -33,37 +33,37 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "white:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-red {
-+ led-wan-red {
- label = "red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "white:lan";
- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "white:usb2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port1>, <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "white:wps";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -43,28 +43,28 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,12 +72,12 @@
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -41,47 +41,47 @@
- */
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb2-white {
-+ led-usb2-white {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -52,19 +52,19 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 22 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:green:usb2";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,58 +72,58 @@
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wifi-disabled {
-+ led-wifi-disabled {
- label = "bcm53xx:amber:wifi-disabled";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wifi-enabled {
-+ led-wifi-enabled {
- label = "bcm53xx:white:wifi-enabled";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar1 {
-+ led-bluebar1 {
- label = "bcm53xx:white:bluebar1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar2 {
-+ led-bluebar2 {
- label = "bcm53xx:white:bluebar2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar3 {
-+ led-bluebar3 {
- label = "bcm53xx:white:bluebar3";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- };
-
-- bluebar4 {
-+ led-bluebar4 {
- label = "bcm53xx:white:bluebar4";
- gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar5 {
-+ led-bluebar5 {
- label = "bcm53xx:white:bluebar5";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar6 {
-+ led-bluebar6 {
- label = "bcm53xx:white:bluebar6";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar7 {
-+ led-bluebar7 {
- label = "bcm53xx:white:bluebar7";
- gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar8 {
-+ led-bluebar8 {
- label = "bcm53xx:white:bluebar8";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -23,18 +23,18 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -25,7 +25,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -30,38 +30,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -69,18 +69,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -33,13 +33,13 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -47,18 +47,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -25,38 +25,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -23,12 +23,12 @@
- leds {
- compatible = "gpio-leds";
-
-- wlan {
-+ led-wlan {
- label = "bcm53xx:blue:wlan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -20,25 +20,25 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -20,37 +20,37 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:blue:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -20,14 +20,14 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
-- diag {
-+ led-diag {
- /* Actually "diag" unclear what this means */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -36,13 +36,13 @@
- linux,default-trigger = "heartbeat";
- };
-
-- wlan-2g {
-+ led-wlan-2g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- wlan-5g {
-+ led-wlan-5g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -58,7 +58,7 @@
- pwm-leds {
- compatible = "pwm-leds";
-
-- red {
-+ led-0 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -66,7 +66,7 @@
- max-brightness = <255>;
- };
-
-- green {
-+ led-1 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
-@@ -74,7 +74,7 @@
- max-brightness = <255>;
- };
-
-- blue {
-+ led-2 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_BLUE>;
---- a/arch/arm/boot/dts/bcm947189acdbmr.dts
-+++ b/arch/arm/boot/dts/bcm947189acdbmr.dts
-@@ -25,17 +25,17 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
deleted file mode 100644
index 3bb39dfd50..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From 915fac07f053418d0ab9075af64da2872ca8a7f8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:10 +0200
-Subject: [PATCH] =?UTF-8?q?ARM:=20dts:=20BCM5301X:=20Relicense=20Rafa?=
- =?UTF-8?q?=C5=82's=20code=20to=20the=20GPL=202.0+=20/=20MIT?=
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-Introduce a new .dtsi file with a proper SPDX tag.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- MAINTAINERS | 1 +
- arch/arm/boot/dts/bcm-ns.dtsi | 202 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 192 +-----------------------------
- 3 files changed, 205 insertions(+), 190 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm-ns.dtsi
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -3579,6 +3579,7 @@ M: Rafał Miłecki <zajec5@gmail.com>
- M: bcm-kernel-feedback-list@broadcom.com
- L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
- S: Maintained
-+F: arch/arm/boot/dts/bcm-ns.dtsi
- F: arch/arm/boot/dts/bcm470*
- F: arch/arm/boot/dts/bcm5301*
- F: arch/arm/boot/dts/bcm953012*
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -0,0 +1,202 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+
-+#include <dt-bindings/clock/bcm-nsp.h>
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+
-+/ {
-+ axi@18000000 {
-+ compatible = "brcm,bus-axi";
-+ reg = <0x18000000 0x1000>;
-+ ranges = <0x00000000 0x18000000 0x00100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon: chipcommon@0 {
-+ reg = <0x00000000 0x1000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+
-+ pcie0: pcie@12000 {
-+ reg = <0x00012000 0x1000>;
-+ };
-+
-+ pcie1: pcie@13000 {
-+ reg = <0x00013000 0x1000>;
-+ };
-+
-+ usb2: usb2@21000 {
-+ reg = <0x00021000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ ehci: usb@21000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ehci";
-+ reg = <0x00021000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb2_phy>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ehci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ehci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+
-+ ohci: usb@22000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ohci";
-+ reg = <0x00022000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ohci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ohci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ usb3: usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ xhci: usb@23000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-xhci";
-+ reg = <0x00023000 0x1000>;
-+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb3_phy>;
-+ phy-names = "usb";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ xhci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+ };
-+
-+ mdio: mdio@18003000 {
-+ compatible = "brcm,iproc-mdio";
-+ reg = <0x18003000 0x8>;
-+ #size-cells = <0>;
-+ #address-cells = <1>;
-+ };
-+
-+ dmu-bus@1800c000 {
-+ compatible = "simple-bus";
-+ ranges = <0 0x1800c000 0x1000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ cru-bus@100 {
-+ compatible = "brcm,ns-cru", "simple-mfd";
-+ reg = <0x100 0x1a4>;
-+ ranges;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ usb2_phy: phy@164 {
-+ compatible = "brcm,ns-usb2-phy";
-+ reg = <0x164 0x4>;
-+ brcm,syscon-clkset = <&cru_clkset>;
-+ clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-+ clock-names = "phy-ref-clk";
-+ #phy-cells = <0>;
-+ };
-+
-+ cru_clkset: syscon@180 {
-+ compatible = "brcm,cru-clkset", "syscon";
-+ reg = <0x180 0x4>;
-+ };
-+
-+ pinctrl: pinctrl@1c0 {
-+ compatible = "brcm,bcm4708-pinmux";
-+ reg = <0x1c0 0x24>;
-+ reg-names = "cru_gpio_control";
-+
-+ spi-pins {
-+ groups = "spi_grp";
-+ function = "spi";
-+ };
-+
-+ pinmux_i2c: i2c-pins {
-+ groups = "i2c_grp";
-+ function = "i2c";
-+ };
-+
-+ pinmux_pwm: pwm-pins {
-+ groups = "pwm0_grp", "pwm1_grp",
-+ "pwm2_grp", "pwm3_grp";
-+ function = "pwm";
-+ };
-+
-+ pinmux_uart1: uart1-pins {
-+ groups = "uart1_grp";
-+ function = "uart1";
-+ };
-+ };
-+
-+ thermal: thermal@2c0 {
-+ compatible = "brcm,ns-thermal";
-+ reg = <0x2c0 0x10>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ thermal-zones {
-+ cpu_thermal: cpu-thermal {
-+ polling-delay-passive = <0>;
-+ polling-delay = <1000>;
-+ coefficients = <(-556) 418000>;
-+ thermal-sensors = <&thermal>;
-+
-+ trips {
-+ cpu-crit {
-+ temperature = <125000>;
-+ hysteresis = <0>;
-+ type = "critical";
-+ };
-+ };
-+
-+ cooling-maps {
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -8,11 +8,7 @@
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
--#include <dt-bindings/clock/bcm-nsp.h>
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/input/input.h>
--#include <dt-bindings/interrupt-controller/irq.h>
--#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include "bcm-ns.dtsi"
-
- / {
- #address-cells = <1>;
-@@ -149,12 +145,6 @@
- };
-
- axi@18000000 {
-- compatible = "brcm,bus-axi";
-- reg = <0x18000000 0x1000>;
-- ranges = <0x00000000 0x18000000 0x00100000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- #interrupt-cells = <1>;
- interrupt-map-mask = <0x000fffff 0xffff>;
- interrupt-map =
-@@ -228,108 +218,15 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon: chipcommon@0 {
-- reg = <0x00000000 0x1000>;
--
-- gpio-controller;
-- #gpio-cells = <2>;
-+ chipcommon@0 {
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
-- pcie0: pcie@12000 {
-- reg = <0x00012000 0x1000>;
-- };
--
-- pcie1: pcie@13000 {
-- reg = <0x00013000 0x1000>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
-
-- usb2: usb2@21000 {
-- reg = <0x00021000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- ehci: usb@21000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ehci";
-- reg = <0x00021000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb2_phy>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ehci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ehci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
--
-- ohci: usb@22000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ohci";
-- reg = <0x00022000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ohci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ohci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
-- usb3: usb3@23000 {
-- reg = <0x00023000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- xhci: usb@23000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-xhci";
-- reg = <0x00023000 0x1000>;
-- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb3_phy>;
-- phy-names = "usb";
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- xhci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
- };
-@@ -355,13 +252,6 @@
- status = "disabled";
- };
-
-- mdio: mdio@18003000 {
-- compatible = "brcm,iproc-mdio";
-- reg = <0x18003000 0x8>;
-- #size-cells = <0>;
-- #address-cells = <1>;
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -409,18 +299,7 @@
- };
-
- dmu-bus@1800c000 {
-- compatible = "simple-bus";
-- ranges = <0 0x1800c000 0x1000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- cru-bus@100 {
-- compatible = "brcm,ns-cru", "simple-mfd";
-- reg = <0x100 0x1a4>;
-- ranges;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- lcpll0: clock-controller@100 {
- #clock-cells = <1>;
- compatible = "brcm,nsp-lcpll0";
-@@ -440,53 +319,6 @@
- "usbclk", "iprocfast",
- "sata1", "sata2";
- };
--
-- usb2_phy: phy@164 {
-- compatible = "brcm,ns-usb2-phy";
-- reg = <0x164 0x4>;
-- brcm,syscon-clkset = <&cru_clkset>;
-- clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-- clock-names = "phy-ref-clk";
-- #phy-cells = <0>;
-- };
--
-- cru_clkset: syscon@180 {
-- compatible = "brcm,cru-clkset", "syscon";
-- reg = <0x180 0x4>;
-- };
--
-- pinctrl: pinctrl@1c0 {
-- compatible = "brcm,bcm4708-pinmux";
-- reg = <0x1c0 0x24>;
-- reg-names = "cru_gpio_control";
--
-- spi-pins {
-- groups = "spi_grp";
-- function = "spi";
-- };
--
-- pinmux_i2c: i2c-pins {
-- groups = "i2c_grp";
-- function = "i2c";
-- };
--
-- pinmux_pwm: pwm-pins {
-- groups = "pwm0_grp", "pwm1_grp",
-- "pwm2_grp", "pwm3_grp";
-- function = "pwm";
-- };
--
-- pinmux_uart1: uart1-pins {
-- groups = "uart1_grp";
-- function = "uart1";
-- };
-- };
--
-- thermal: thermal@2c0 {
-- compatible = "brcm,ns-thermal";
-- reg = <0x2c0 0x10>;
-- #thermal-sensor-cells = <0>;
-- };
- };
- };
-
-@@ -557,24 +389,4 @@
- };
- };
- };
--
-- thermal-zones {
-- cpu_thermal: cpu-thermal {
-- polling-delay-passive = <0>;
-- polling-delay = <1000>;
-- coefficients = <(-556) 418000>;
-- thermal-sensors = <&thermal>;
--
-- trips {
-- cpu-crit {
-- temperature = <125000>;
-- hysteresis = <0>;
-- type = "critical";
-- };
-- };
--
-- cooling-maps {
-- };
-- };
-- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
deleted file mode 100644
index b98f2daa67..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 916553449561c4f0b61c71b751b7bb583f5dddd4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Florian's code to the GPL 2.0+
- / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 36 ++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 39 ---------------------------------
- 2 files changed, 36 insertions(+), 39 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -19,6 +19,8 @@
-
- gpio-controller;
- #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
- };
-
- pcie0: pcie@12000 {
-@@ -109,6 +111,22 @@
- };
- };
- };
-+
-+ gmac0: ethernet@24000 {
-+ reg = <0x24000 0x800>;
-+ };
-+
-+ gmac1: ethernet@25000 {
-+ reg = <0x25000 0x800>;
-+ };
-+
-+ gmac2: ethernet@26000 {
-+ reg = <0x26000 0x800>;
-+ };
-+
-+ gmac3: ethernet@27000 {
-+ reg = <0x27000 0x800>;
-+ };
- };
-
- mdio: mdio@18003000 {
-@@ -118,6 +136,24 @@
- #address-cells = <1>;
- };
-
-+ rng: rng@18004000 {
-+ compatible = "brcm,bcm5301x-rng";
-+ reg = <0x18004000 0x14>;
-+ };
-+
-+ srab: ethernet-switch@18007000 {
-+ compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-+ reg = <0x18007000 0x1000>;
-+
-+ status = "disabled";
-+
-+ /* ports are defined in board DTS */
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -218,30 +218,9 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon@0 {
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
--
-- gmac0: ethernet@24000 {
-- reg = <0x24000 0x800>;
-- };
--
-- gmac1: ethernet@25000 {
-- reg = <0x25000 0x800>;
-- };
--
-- gmac2: ethernet@26000 {
-- reg = <0x26000 0x800>;
-- };
--
-- gmac3: ethernet@27000 {
-- reg = <0x27000 0x800>;
-- };
- };
-
- pwm: pwm@18002000 {
-@@ -322,24 +301,6 @@
- };
- };
-
-- srab: ethernet-switch@18007000 {
-- compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-- reg = <0x18007000 0x1000>;
--
-- status = "disabled";
--
-- /* ports are defined in board DTS */
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
-- };
-- };
--
-- rng: rng@18004000 {
-- compatible = "brcm,bcm5301x-rng";
-- reg = <0x18004000 0x14>;
-- };
--
- nand_controller: nand-controller@18028000 {
- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 328748c8e0..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From b3b3cd885ed39cb4b38319a1c4fa4e41db6fee72 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:20 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Hauke's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Hauke to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 90 +++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 85 -------------------------------
- 2 files changed, 90 insertions(+), 85 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -1,4 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ */
-
- #include <dt-bindings/clock/bcm-nsp.h>
- #include <dt-bindings/gpio/gpio.h>
-@@ -7,6 +10,81 @@
- #include <dt-bindings/interrupt-controller/arm-gic.h>
-
- / {
-+ interrupt-parent = <&gic>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon-a-bus@18000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x18000000 0x00001000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ uart0: serial@300 {
-+ compatible = "ns16550";
-+ reg = <0x0300 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@400 {
-+ compatible = "ns16550";
-+ reg = <0x0400 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinmux_uart1>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ mpcore-bus@19000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x19000000 0x00023000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ scu@20000 {
-+ compatible = "arm,cortex-a9-scu";
-+ reg = <0x20000 0x100>;
-+ };
-+
-+ timer@20200 {
-+ compatible = "arm,cortex-a9-global-timer";
-+ reg = <0x20200 0x100>;
-+ interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ timer@20600 {
-+ compatible = "arm,cortex-a9-twd-timer";
-+ reg = <0x20600 0x20>;
-+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-+ IRQ_TYPE_EDGE_RISING)>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ gic: interrupt-controller@21000 {
-+ compatible = "arm,cortex-a9-gic";
-+ #interrupt-cells = <3>;
-+ #address-cells = <0>;
-+ interrupt-controller;
-+ reg = <0x21000 0x1000>,
-+ <0x20100 0x100>;
-+ };
-+
-+ L2: cache-controller@22000 {
-+ compatible = "arm,pl310-cache";
-+ reg = <0x22000 0x1000>;
-+ cache-unified;
-+ arm,shared-override;
-+ prefetch-data = <1>;
-+ prefetch-instr = <1>;
-+ cache-level = <2>;
-+ };
-+ };
-+
- axi@18000000 {
- compatible = "brcm,bus-axi";
- reg = <0x18000000 0x1000>;
-@@ -216,6 +294,18 @@
- };
- };
-
-+ nand_controller: nand-controller@18028000 {
-+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-+ reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-+ reg-names = "nand", "iproc-idm", "iproc-ext";
-+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcm,nand-has-wp;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -11,41 +11,7 @@
- #include "bcm-ns.dtsi"
-
- / {
-- #address-cells = <1>;
-- #size-cells = <1>;
-- interrupt-parent = <&gic>;
--
-- chipcommon-a-bus@18000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x18000000 0x00001000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- uart0: serial@300 {
-- compatible = "ns16550";
-- reg = <0x0300 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- status = "disabled";
-- };
--
-- uart1: serial@400 {
-- compatible = "ns16550";
-- reg = <0x0400 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&pinmux_uart1>;
-- status = "disabled";
-- };
-- };
--
- mpcore-bus@19000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x19000000 0x00023000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- a9pll: arm_clk@0 {
- #clock-cells = <0>;
- compatible = "brcm,nsp-armpll";
-@@ -53,26 +19,6 @@
- reg = <0x00000 0x1000>;
- };
-
-- scu@20000 {
-- compatible = "arm,cortex-a9-scu";
-- reg = <0x20000 0x100>;
-- };
--
-- timer@20200 {
-- compatible = "arm,cortex-a9-global-timer";
-- reg = <0x20200 0x100>;
-- interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-- clocks = <&periph_clk>;
-- };
--
-- timer@20600 {
-- compatible = "arm,cortex-a9-twd-timer";
-- reg = <0x20600 0x20>;
-- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-- IRQ_TYPE_EDGE_RISING)>;
-- clocks = <&periph_clk>;
-- };
--
- watchdog@20620 {
- compatible = "arm,cortex-a9-twd-wdt";
- reg = <0x20620 0x20>;
-@@ -80,25 +26,6 @@
- IRQ_TYPE_EDGE_RISING)>;
- clocks = <&periph_clk>;
- };
--
-- gic: interrupt-controller@21000 {
-- compatible = "arm,cortex-a9-gic";
-- #interrupt-cells = <3>;
-- #address-cells = <0>;
-- interrupt-controller;
-- reg = <0x21000 0x1000>,
-- <0x20100 0x100>;
-- };
--
-- L2: cache-controller@22000 {
-- compatible = "arm,pl310-cache";
-- reg = <0x22000 0x1000>;
-- cache-unified;
-- arm,shared-override;
-- prefetch-data = <1>;
-- prefetch-instr = <1>;
-- cache-level = <2>;
-- };
- };
-
- pmu {
-@@ -301,18 +228,6 @@
- };
- };
-
-- nand_controller: nand-controller@18028000 {
-- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-- reg-names = "nand", "iproc-idm", "iproc-ext";
-- interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- brcm,nand-has-wp;
-- };
--
- spi@18029200 {
- compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi";
- reg = <0x18029200 0x184>,
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
deleted file mode 100644
index ef29266d0b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 3b3e35b279bee5e51580c648399e20323467f58c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:21 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense AXI interrupts code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Those entries were added by:
-1. Hauke in commits dec378827c4a ("ARM: BCM5301X: Add IRQs to Broadcom's
- bus-axi in DTS file") and 1f80de6863ca ("ARM: BCM5301X: add IRQ
- numbers for PCIe controller")
-2. Florian in the commit 2cd0c0202f13 ("ARM: dts: BCM5301X: Add SRAB
- interrupts")
-
-Move them to the bcm-ns.dtsi which uses dual licensing. That syncs more
-Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 73 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 75 ---------------------------------
- 2 files changed, 73 insertions(+), 75 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -92,6 +92,79 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ #interrupt-cells = <1>;
-+ interrupt-map-mask = <0x000fffff 0xffff>;
-+ interrupt-map =
-+ /* ChipCommon */
-+ <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Switch Register Access Block */
-+ <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 0 */
-+ <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 1 */
-+ <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 2 */
-+ <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 2.0 Controller */
-+ <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 3.0 Controller */
-+ <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 0 */
-+ <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 1 */
-+ <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 2 */
-+ <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 3 */
-+ <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* NAND Controller */
-+ <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-+
- chipcommon: chipcommon@0 {
- reg = <0x00000000 0x1000>;
-
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -3,8 +3,6 @@
- * Generic DTS part for all BCM53010, BCM53011, BCM53012, BCM53014, BCM53015,
- * BCM53016, BCM53017, BCM53018, BCM4707, BCM4708 and BCM4709 SoCs
- *
-- * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-- *
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
-@@ -72,79 +70,6 @@
- };
-
- axi@18000000 {
-- #interrupt-cells = <1>;
-- interrupt-map-mask = <0x000fffff 0xffff>;
-- interrupt-map =
-- /* ChipCommon */
-- <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Switch Register Access Block */
-- <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 0 */
-- <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 1 */
-- <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 2 */
-- <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 2.0 Controller */
-- <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 3.0 Controller */
-- <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 0 */
-- <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 1 */
-- <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 2 */
-- <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 3 */
-- <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* NAND Controller */
-- <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
deleted file mode 100644
index 7d9b297191..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
+++ /dev/null
@@ -1,336 +0,0 @@
-From dfa6570eb5ce2f24059caadbe2ed70034b5337bc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 10:33:08 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Specify MAC addresses on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use NRAM (NVMEM device) and its "et0macaddr" variable (NVMEM cell) to
-point Ethernet devices to their MAC addresses.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230515083308.7612-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 5 ++++-
- 10 files changed, 113 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -24,6 +24,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -60,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -24,6 +24,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -106,6 +110,11 @@
- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -137,6 +146,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -51,6 +59,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -22,6 +22,14 @@
- <0x88000000 0x18000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -47,6 +55,11 @@
- status = "okay";
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -101,6 +105,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -136,6 +145,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -27,6 +27,7 @@
- reg = <0x1eff0000 0x10000>;
-
- et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
- };
- };
-
-@@ -76,7 +77,7 @@
- };
-
- &gmac0 {
-- nvmem-cells = <&et0macaddr>;
-+ nvmem-cells = <&et0macaddr 0>;
- nvmem-cell-names = "mac-address";
- };
-
-@@ -119,6 +120,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
deleted file mode 100644
index 5f5890e291..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 9d7121f1d2faa0b50bf5b462adcd2dd91970c45e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 20 May 2023 13:26:01 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated device "compatible" strings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar binding was updated to use minus/hyphen char between model and
-version for all devices.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230520112601.11821-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 2 +-
- 6 files changed, 6 insertions(+), 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -8,7 +8,7 @@
- #include "bcm4708.dtsi"
-
- / {
-- compatible = "luxul,xap-1510v1", "brcm,bcm4708";
-+ compatible = "luxul,xap-1510-v1", "brcm,bcm4708";
- model = "Luxul XAP-1510 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -13,7 +13,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6250v1", "brcm,bcm4708";
-+ compatible = "netgear,r6250-v1", "brcm,bcm4708";
- model = "Netgear R6250 V1 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -12,7 +12,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6300v2", "brcm,bcm4708";
-+ compatible = "netgear,r6300-v2", "brcm,bcm4708";
- model = "Netgear R6300 V2 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -8,7 +8,7 @@
- #include "bcm47081.dtsi"
-
- / {
-- compatible = "luxul,xap-1410v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xap-1410-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XAP-1410 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-1200v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xwr-1200-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XWR-1200 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-3100v1", "brcm,bcm47094", "brcm,bcm4708";
-+ compatible = "luxul,xwr-3100-v1", "brcm,bcm47094", "brcm,bcm4708";
- model = "Luxul XWR-3100 V1";
-
- chosen {
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
deleted file mode 100644
index c16587f684..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 04afb51c1dce90051487d3c7b70a1b1b246ce29a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 17:10:23 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated "spi-gpio" binding properties
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Switch away from deprecated properties.
-
-This fixes:
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-sck: False schema does not allow [[6, 7, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-mosi: False schema does not allow [[6, 4, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: 'sck-gpios' is a required property
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: Unevaluated properties are not allowed ('gpio-mosi', 'gpio-sck' were unexpected)
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602151023.8607-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 4 ++--
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 4 ++--
- 4 files changed, 8 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -16,8 +16,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
deleted file mode 100644
index 59fa457aee..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From c3acdd4901192bc69dc577012663d5abae21661e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:54 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid #usb-cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Such property simply doesn't exist (is not documented or used anywhere).
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@21000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ehci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@22000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ohci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@23000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-xhci.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -192,8 +192,6 @@
- interrupt-parent = <&gic>;
-
- ehci: usb@21000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ehci";
- reg = <0x00021000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -214,8 +212,6 @@
- };
-
- ohci: usb@22000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ohci";
- reg = <0x00022000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -245,8 +241,6 @@
- interrupt-parent = <&gic>;
-
- xhci: usb@23000 {
-- #usb-cells = <0>;
--
- compatible = "generic-xhci";
- reg = <0x00023000 0x1000>;
- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
deleted file mode 100644
index b8411fc719..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 676bf7d062c14191c3fc12f1e36e1f3809041483 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid properties from Meraki MR32
- keys
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm53015-meraki-mr26.dtb: keys: '#address-cells', '#size-cells' do not match any of the regexes: '^(button|event|key|switch|(button|event|key|switch)-[a-z0-9-]+|[a-z0-9-]+-(button|event|key|switch))$', 'pinctrl-[0-9]+'
- From schema: Documentation/devicetree/bindings/input/gpio-keys.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -39,8 +39,6 @@
-
- keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- key-restart {
- label = "Reset";
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
deleted file mode 100644
index 7496321269..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 1d5682ccc7d6088179b6cfd50a3e3bb6d2b0527e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 08:10:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Christian's code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Christian to the bcm-ns.dtsi which uses dual
-licensing. That syncs more Northstar code to be based on the same
-licensing schema.
-
-Cc: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/20230605061049.16136-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 21 +++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 23 -----------------------
- 2 files changed, 21 insertions(+), 23 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -182,6 +182,10 @@
- reg = <0x00013000 0x1000>;
- };
-
-+ pcie2: pcie@14000 {
-+ reg = <0x00014000 0x1000>;
-+ };
-+
- usb2: usb2@21000 {
- reg = <0x00021000 0x1000>;
-
-@@ -274,6 +278,14 @@
- };
- };
-
-+ pwm: pwm@18002000 {
-+ compatible = "brcm,iproc-pwm";
-+ reg = <0x18002000 0x28>;
-+ clocks = <&osc>;
-+ #pwm-cells = <3>;
-+ status = "disabled";
-+ };
-+
- mdio: mdio@18003000 {
- compatible = "brcm,iproc-mdio";
- reg = <0x18003000 0x8>;
-@@ -299,6 +311,15 @@
- };
- };
-
-+ uart2: serial@18008000 {
-+ compatible = "ns16550a";
-+ reg = <0x18008000 0x20>;
-+ clocks = <&iprocslow>;
-+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -69,20 +69,6 @@
- };
- };
-
-- axi@18000000 {
-- pcie2: pcie@14000 {
-- reg = <0x00014000 0x1000>;
-- };
-- };
--
-- pwm: pwm@18002000 {
-- compatible = "brcm,iproc-pwm";
-- reg = <0x18002000 0x28>;
-- clocks = <&osc>;
-- #pwm-cells = <3>;
-- status = "disabled";
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -110,15 +96,6 @@
- reg = <0x18105000 0x1000>;
- };
-
-- uart2: serial@18008000 {
-- compatible = "ns16550a";
-- reg = <0x18008000 0x20>;
-- clocks = <&iprocslow>;
-- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-- reg-shift = <2>;
-- status = "disabled";
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
deleted file mode 100644
index fa2f21af53..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
+++ /dev/null
@@ -1,838 +0,0 @@
-From ba4aebce23b2affb810b8a60eae853674d2cded2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 15:21:09 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Describe switch ports in the main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All Northstar SoCs have BCM5301x switches (BCM53011, BCM53012) with 8
-ports (0-8 without 6). By design 3 switch ports (5, 7 and 8) are
-hardwired to 3 on-SoC Ethernet interfaces. Switch port 8 requires
-forcing link state.
-
-It seems that global Northstar .dtsi file is the best place to describe
-those hw details. Only device specific bits (like labels) should go to
-device .dts files.
-
-This seems to fit well with a tiny exception of Asus RT-AC88U which
-somehow was designed to have switch 5 connected to an extra switch. This
-case was simply handled with a /delete-property/.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Christian Lamparter <chunkeey@gmail.com> (MR32+MR26)
-Link: https://lore.kernel.org/r/20230605132109.7933-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 41 ++++++++++++++++++-
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 7 ----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 4 --
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 3 --
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 7 ----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 7 ----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 7 ----
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 3 --
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 7 ----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 12 ------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 17 +-------
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 12 ------
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 12 ------
- .../boot/dts/bcm47094-linksys-panamera.dts | 34 ++++-----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 4 --
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 3 --
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 7 ----
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 7 ----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 3 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 3 --
- 22 files changed, 51 insertions(+), 163 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -304,10 +304,49 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac0>;
-+ };
-+
-+ port@7 {
-+ reg = <7>;
-+ ethernet = <&gmac1>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -159,34 +159,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -75,19 +75,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -82,14 +82,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -100,34 +100,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -75,14 +75,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -124,36 +124,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -191,39 +191,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -181,32 +181,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- sw0_p5: port@5 {
-- reg = <5>;
-+ /delete-property/ethernet;
-+
- label = "extsw";
- phy-mode = "rgmii";
-
-@@ -218,8 +214,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
-
- fixed-link {
-@@ -229,14 +223,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -124,39 +124,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -172,40 +172,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
- phy-mode = "rgmii";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -207,29 +207,32 @@
- dsa,member = <0 0>;
-
- ports {
-+ sw0_p0: port@0 {
-+ label = "extsw";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@1 {
-- reg = <1>;
- label = "lan7";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan4";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan8";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
-- ethernet = <&gmac0>;
- label = "cpu";
- status = "disabled";
-
-@@ -240,8 +243,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
- status = "disabled";
-
-@@ -252,24 +253,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- sw0_p0: port@0 {
-- reg = <0>;
-- label = "extsw";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -73,19 +73,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -69,14 +69,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -123,36 +123,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -98,36 +98,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -115,14 +115,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -176,14 +176,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
deleted file mode 100644
index ea571f459a..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From a6a1a156f5debaebf9f61850d111b966e9be9ee9 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR26: MR32: remove bogus nand-ecc-algo
- property
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-| bcm53015-meraki-mr26.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-| bcm53016-meraki-mr32.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-
-original ECC values for these old Merakis are sadly not
-provided by the vendor. It looks like Meraki just stuck
-with what Broadcom's SDK was doing... which left this
-up to the proprietary nand driver.
-
-Note: The invalid setting was and is handled by brcmnand. It
-falls back to "bch" in brcmnand_setup_dev() when ecc.algo is
-set to NAND_ECC_ALGO_UNKNOWN (since "hw" is not in the list
-above).
-
-A correct nand-ecc-algo = "bch"; is already specified in the
-included "bcm5301x-nand-cs0-bch8.dtsi". So this line can be
-dropped.
-
-Reported-by: Rafał Miłecki <zajec5@gmail.com> (per Mail)
-Fixes: 935327a73553 ("ARM: dts: BCM5301X: Add DT for Meraki MR26")
-Fixes: ec88a9c344d9 ("ARM: BCM5301X: Add DT for Meraki MR32")
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/2c4d00dd40124c2ddc0b139cbce7531b108f9052.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 --
- 2 files changed, 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -72,8 +72,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <0x1>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -125,8 +125,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- /*
- * The partition autodetection does not work for this device.
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
deleted file mode 100644
index 8eb5442d17..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From d68b2f7d7d06872450d4f39d84d5926d7e7ae88c Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:28 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR32: remove partition index numbers
-
-removes the partition indexes in the node names under.
-This brings the device tree source in line with others.
-
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/627f57d568030a56499361790524b4d4f3381619.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -138,31 +138,31 @@
- #address-cells = <0x1>;
- #size-cells = <0x1>;
-
-- partition0@0 {
-+ partition@0 {
- label = "u-boot";
- reg = <0x0 0x100000>;
- read-only;
- };
-
-- partition1@100000 {
-+ partition@100000 {
- label = "bootkernel1";
- reg = <0x100000 0x300000>;
- read-only;
- };
-
-- partition2@400000 {
-+ partition@400000 {
- label = "nvram";
- reg = <0x400000 0x100000>;
- read-only;
- };
-
-- partition3@500000 {
-+ partition@500000 {
- label = "bootkernel2";
- reg = <0x500000 0x300000>;
- read-only;
- };
-
-- partition4@800000 {
-+ partition@800000 {
- label = "ubi";
- reg = <0x800000 0x7780000>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
deleted file mode 100644
index 3ffe0b2f17..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 752a63b8dbe6cc6900efd1035bea427a778a4b55 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:59:25 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Netgear R8000 WiFi regulator mappings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602135925.14143-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -137,8 +137,10 @@
- #size-cells = <2>;
-
- wifi@0,1,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5735000 5835000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
-@@ -159,6 +161,19 @@
- #address-cells = <3>;
- #size-cells = <2>;
-
-+ bridge@1,0 {
-+ reg = <0x800 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
-+ };
-+ };
-+
- bridge@1,2,2 {
- reg = <0x1000 0 0 0 0>;
-
-@@ -166,8 +181,10 @@
- #size-cells = <2>;
-
- wifi@1,4,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5170000 5730000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
deleted file mode 100644
index 454ce4c278..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From b67cad33176e472df6d16a24ee7624299bdcd5d5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Jun 2023 12:58:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add cells sizes to PCIe nodes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-
-Two properties that need to be added later are "device_type" and
-"ranges". Adding "device_type" on its own causes a new warning and the
-value of "ranges" needs to be determined yet.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230616105827.21656-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -176,14 +176,23 @@
-
- pcie0: pcie@12000 {
- reg = <0x00012000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie1: pcie@13000 {
- reg = <0x00013000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- usb2: usb2@21000 {
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
deleted file mode 100644
index 9811757ee2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 4b8e16de053fc88eac406ad63da2693dd8279043 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Wed, 5 Jul 2023 17:01:07 +0200
-Subject: [PATCH] ARM: dts: broadcom: add missing space before {
-
-Add missing whitespace between node name/label and opening {.
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20230705150108.293999-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-linksys-panamera.dts | 2 +-
- arch/arm/boot/dts/broadcom/bcm47094-phicomm-k3.dts | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -279,7 +279,7 @@
- reg = <0x080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "devinfo";
- reg = <0x0180000 0x080000>;
- };
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -55,7 +55,7 @@
- reg = <0x0080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "phicomm";
- reg = <0x0180000 0x0280000>;
- read-only;
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
deleted file mode 100644
index e5143abf58..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 8960f095de3b80beb3639075f0c8161b6ea98c61 Mon Sep 17 00:00:00 2001
-From: Dan Haab <dan.haab@luxul.com>
-Date: Wed, 5 Jul 2023 09:32:51 -0600
-Subject: [PATCH] ARM: dts: BCM5301X: Add Wi-Fi regulatory mappings for Luxul
- devices
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Dan Haab <dan.haab@luxul.com>
-Link: https://lore.kernel.org/r/20230705153251.739236-1-riproute@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-luxul-xap-1610.dts | 37 +++++++++++++++++++
- .../broadcom/bcm47094-luxul-xwr-3150-v1.dts | 36 ++++++++++++++++++
- 2 files changed, 73 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -64,6 +64,43 @@
- nvmem-cell-names = "mac-address";
- };
-
-+
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -81,6 +81,42 @@
- nvmem-cell-names = "mac-address";
- };
-
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
- &usb3 {
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index 4b2e608ec2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 2ce61fa62183cf994666fcc911da34075c7183b5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 7 Jul 2023 11:15:19 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar SoCs have 3 usable Ethernet interfaces each connected to one
-of switch ports. They all use fixed links.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230707091519.21673-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -272,14 +272,32 @@
-
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac1: ethernet@25000 {
- reg = <0x25000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac2: ethernet@26000 {
- reg = <0x26000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac3: ethernet@27000 {
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
deleted file mode 100644
index 7930c52b16..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 44ad8207806973f4e4f7d870fff36cc01f494250 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 13 Jul 2023 13:11:45 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Fix Ethernet info for Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Both Luxul's XAP devices (XAP-810 and XAP-1440) are access points that
-use a non-default design. They don't include switch but have a single
-Ethernet port and BCM54210E PHY connected to the Ethernet controller's
-MDIO bus.
-
-Support for those devices regressed due to two changes:
-
-1. Describing MDIO bus with switch
-After commit 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125
-rev 4 switch") Linux stopped probing for MDIO devices.
-
-2. Dropping hardcoded BCM54210E delays
-In commit fea7fda7f50a ("net: phy: broadcom: Fix RGMII delays
-configuration for BCM54210E") support for other PHY modes was added but
-that requires a proper "phy-mode" value in DT.
-
-Both above changes are correct (they don't need to be reverted or
-anything) but they need this fix for DT data to be correct and for Linux
-to work properly.
-
-Fixes: 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125 rev 4 switch")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230713111145.14864-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 13 +++++++++++++
- .../boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 13 +++++++++++++
- 2 files changed, 26 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -58,3 +58,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -94,3 +94,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
deleted file mode 100644
index f23873e111..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 72ec77d74d28be7359ef77971cdee38b60af9e49 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Thu, 13 Jul 2023 00:16:42 +0200
-Subject: [PATCH] ARM: dts: bcm5301x: Add SEAMA compatibles
-
-This adds SEAMA compatibles to the firmware partition of these
-two D-Link devices.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230713-seama-partitions-v4-2-69e577453d40@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 1 +
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -33,6 +33,7 @@
- #size-cells = <1>;
-
- partition@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -149,6 +149,7 @@
- * partitions: this device uses SEAMA.
- */
- firmware@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch
deleted file mode 100644
index d5cb817e8e..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 7141209db9c335ab261a17933809a3e660ebdc12 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:14 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Fix Tenda AC9 switch CPU port
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Primary Ethernet interface is connected to the port 8 (not 5).
-
-Fixes: 64612828628c ("ARM: dts: BCM53573: Add Tenda AC9 switch ports")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-tenda-ac9.dts | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -135,8 +135,8 @@
- label = "lan4";
- };
-
-- port@5 {
-- reg = <5>;
-+ port@8 {
-+ reg = <8>;
- label = "cpu";
- ethernet = <&gmac0>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
deleted file mode 100644
index ab27495078..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 8d6b61ecad2f1c939813c5c4517d53e04672dc48 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:15 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Describe BCM53125 switch ports in the
- main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53125 always has 5 ports with GPHYs (for LAN/WAN ports) and 2 IMP
-ports. It seems the best place to describe that in the main .dtsi.
-Device specific bits can go to device .dts files. This will help
-avoiding some code duplication.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-tenda-ac9.dts | 7 -----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 26 ++++++++++++++++++-
- 2 files changed, 25 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -111,34 +111,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan1";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan3";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan4";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -192,10 +192,34 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac0>;
-+ };
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
deleted file mode 100644
index cc9e86ac75..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From d95b1caeea194962220db1778ce7fe71cdba788b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:16 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add BCM53125 switch port 5
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's connected to the extra Ethernet interface.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -216,6 +216,16 @@
- reg = <4>;
- };
-
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac1>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@8 {
- reg = <8>;
- ethernet = <&gmac0>;
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index f97d4edd75..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From e0ae343a2c1b782a346d9b844ea65e1d49c428b2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:12:27 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53573 has 2 Ethernet interfaces each connected to one of switch ports
-in the default design. They both use fixed links.
-
-An exception are Luxul XAP devices that have switch replaced by a single
-PHY.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101227.5420-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 2 ++
- .../arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 2 ++
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 12 ++++++++++++
- 3 files changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -50,6 +50,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -86,6 +86,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -181,6 +181,12 @@
-
- gmac0: ethernet@5000 {
- reg = <0x5000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-
- mdio {
- #address-cells = <1>;
-@@ -237,6 +243,12 @@
-
- gmac1: ethernet@b000 {
- reg = <0xb000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- pmu@12000 {
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
deleted file mode 100644
index e9e347075d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From d8835601e3c306fda78f8736f1aef688e99e892d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:11:59 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Disable second Ethernet on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-XAP-810 and XAP-1440 both have a single Ethernet port and BCM54210E PHY.
-Their second Ethernet interface is not connected to anything.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101159.5289-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 4 ++++
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 4 ++++
- 2 files changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -73,3 +73,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -109,3 +109,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
deleted file mode 100644
index 6c2af02589..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
+++ /dev/null
@@ -1,431 +0,0 @@
-From 2900083269f7c0f0ff430bffc6ced2038aed9b6b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Thu, 3 Aug 2023 10:14:54 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for ASUS RT-AC3100
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-ASUS RT-AC3100 is ASUS RT-AC88U without the external switch. Move the
-shared bindings to bcm47094-asus-rt-ac3100.dtsi.
-
-Remove the fixed-link node on port@7 as commit ba4aebce23b2 ("ARM: dts:
-BCM5301X: Describe switch ports in the main DTS") states it's not
-necessary.
-
-Replace the copyright notice with an author notice.
-
-Rename the model name from Asus to ASUS on bcm47094-asus-rt-ac88u.dts.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230803071454.5902-2-arinc.unal@arinc9.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../dts/bcm47094-asus-rt-ac3100.dts | 23 +++
- .../dts/bcm47094-asus-rt-ac3100.dtsi | 163 ++++++++++++++++++
- .../dts/bcm47094-asus-rt-ac88u.dts | 155 +----------------
- 4 files changed, 190 insertions(+), 152 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -119,6 +119,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-netgear-r7000.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
-+ bcm47094-asus-rt-ac3100.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
- bcm47094-dlink-dir-890l.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
-@@ -0,0 +1,23 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-+
-+/ {
-+ compatible = "asus,rt-ac3100", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "ASUS RT-AC3100";
-+
-+ nvram@1c080000 {
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-@@ -0,0 +1,163 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ chosen {
-+ bootargs = "earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+ nvram@1c080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1c080000 0x00180000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-power {
-+ label = "white:power";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ led-wan-red {
-+ label = "red:wan";
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-lan {
-+ label = "white:lan";
-+ gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-usb2 {
-+ label = "white:usb2";
-+ gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-usb3 {
-+ label = "white:usb3";
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port1>, <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-wps {
-+ label = "white:wps";
-+ gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-reset {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-wifi {
-+ label = "Wi-Fi";
-+ linux,code = <KEY_RFKILL>;
-+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-led {
-+ label = "Backlight";
-+ linux,code = <KEY_BRIGHTNESS_ZERO>;
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x00000000 0x00080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "nvram";
-+ reg = <0x00080000 0x00180000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x00200000 0x07e00000>;
-+ compatible = "brcm,trx";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -1,102 +1,21 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- /*
-- * Copyright (C) 2021-2022 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
- */
-
- /dts-v1/;
-
--#include "bcm47094.dtsi"
--#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-
- / {
- compatible = "asus,rt-ac88u", "brcm,bcm47094", "brcm,bcm4708";
-- model = "Asus RT-AC88U";
--
-- chosen {
-- bootargs = "earlycon";
-- };
--
-- memory@0 {
-- device_type = "memory";
-- reg = <0x00000000 0x08000000>,
-- <0x88000000 0x18000000>;
-- };
-+ model = "ASUS RT-AC88U";
-
- nvram@1c080000 {
-- compatible = "brcm,nvram";
-- reg = <0x1c080000 0x00180000>;
--
- et1macaddr: et1macaddr {
- };
- };
-
-- leds {
-- compatible = "gpio-leds";
--
-- led-power {
-- label = "white:power";
-- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-- linux,default-trigger = "default-on";
-- };
--
-- led-wan-red {
-- label = "red:wan";
-- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-- };
--
-- led-lan {
-- label = "white:lan";
-- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-- };
--
-- led-usb2 {
-- label = "white:usb2";
-- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port2>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-usb3 {
-- label = "white:usb3";
-- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port1>, <&xhci_port1>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-wps {
-- label = "white:wps";
-- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-- };
-- };
--
-- gpio-keys {
-- compatible = "gpio-keys";
--
-- button-wps {
-- label = "WPS";
-- linux,code = <KEY_WPS_BUTTON>;
-- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-- };
--
-- button-reset {
-- label = "Reset";
-- linux,code = <KEY_RESTART>;
-- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-- };
--
-- button-wifi {
-- label = "Wi-Fi";
-- linux,code = <KEY_RFKILL>;
-- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-- };
--
-- button-led {
-- label = "Backlight";
-- linux,code = <KEY_BRIGHTNESS_ZERO>;
-- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-- };
-- };
--
- switch {
- compatible = "realtek,rtl8365mb";
- /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-@@ -175,31 +94,9 @@
- };
-
- &srab {
-- compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-- status = "okay";
- dsa,member = <0 0>;
-
- ports {
-- port@0 {
-- label = "lan4";
-- };
--
-- port@1 {
-- label = "lan3";
-- };
--
-- port@2 {
-- label = "lan2";
-- };
--
-- port@3 {
-- label = "lan1";
-- };
--
-- port@4 {
-- label = "wan";
-- };
--
- sw0_p5: port@5 {
- /delete-property/ethernet;
-
-@@ -212,19 +109,6 @@
- pause;
- };
- };
--
-- port@7 {
-- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- port@8 {
-- label = "cpu";
-- };
- };
- };
-
-@@ -236,36 +120,3 @@
- nvmem-cells = <&et1macaddr>;
- nvmem-cell-names = "mac-address";
- };
--
--&usb2 {
-- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
--};
--
--&usb3_phy {
-- status = "okay";
--};
--
--&nandcs {
-- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- partition@0 {
-- label = "boot";
-- reg = <0x00000000 0x00080000>;
-- read-only;
-- };
--
-- partition@80000 {
-- label = "nvram";
-- reg = <0x00080000 0x00180000>;
-- };
--
-- partition@200000 {
-- label = "firmware";
-- reg = <0x00200000 0x07e00000>;
-- compatible = "brcm,trx";
-- };
-- };
--};
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
deleted file mode 100644
index 78b8975f1f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 5cbee5828219c4f7b33e96b5d8ce5e467b2857c8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 12:55:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MACs for D-Link DIR-885L
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et2macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901105549.7076-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-dlink-dir-885l.dts | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -25,6 +25,15 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1e3f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e3f0000 0x10000>;
-+
-+ et2macaddr: et2macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -112,6 +121,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et2macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -142,6 +156,8 @@
-
- port@4 {
- label = "wan";
-+ nvmem-cells = <&et2macaddr 3>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
deleted file mode 100644
index 11ce7acb53..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From a9e79863b62aaaefcdf469fc331bf482ae00db0d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 14:43:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MAC address for Asus RT-AC87U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et1macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901124311.31156-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -25,6 +25,12 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1c080000 {
-+ et1macaddr: et1macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -62,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et1macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb3_phy {
- status = "okay";
- };
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 6df1e555e9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 81ea360a16978a4df61df9db56b171909bd659c0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:30:57 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Felix's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Felix to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 1ff80363524c ("ARM: BCM5301X: Add
-profiling support").
-
-Cc: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Felix Fietkau <nbd@nbd.name>
-Link: https://lore.kernel.org/r/20230916083057.10458-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 7 +++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 7 -------
- 2 files changed, 7 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -14,6 +14,13 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ pmu {
-+ compatible = "arm,cortex-a9-pmu";
-+ interrupts =
-+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
- chipcommon-a-bus@18000000 {
- compatible = "simple-bus";
- ranges = <0x00000000 0x18000000 0x00001000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -26,13 +26,6 @@
- };
- };
-
-- pmu {
-- compatible = "arm,cortex-a9-pmu";
-- interrupts =
-- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-- };
--
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 66db4a291f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From b8d4f7c1be04d66c37c119c501c87bccc4197694 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:58:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Vivek's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Vivek to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 37f6130ec39f ("ARM: dts: BCM5301X:
-Make USB 3.0 PHY use MDIO PHY driver").
-
-Cc: Vivek Unune <npcomplete13@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Vivek Unune <npcomplete13@gmail.com>
-Link: https://lore.kernel.org/r/20230916085855.28375-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 27 ++++++++++++++++++++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 27 ------------------------
- 2 files changed, 27 insertions(+), 27 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -327,6 +327,29 @@
- #address-cells = <1>;
- };
-
-+ mdio-mux@18003000 {
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
-+ mdio-parent-bus = <&mdio>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x18003000 0x4>;
-+ mux-mask = <0x200>;
-+
-+ mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ usb3_phy: usb3-phy@10 {
-+ compatible = "brcm,ns-ax-usb3-phy";
-+ reg = <0x10>;
-+ usb3-dmp-syscon = <&usb3_dmp>;
-+ #phy-cells = <0>;
-+ status = "disabled";
-+ };
-+ };
-+ };
-+
- rng: rng@18004000 {
- compatible = "brcm,bcm5301x-rng";
- reg = <0x18004000 0x14>;
-@@ -467,6 +490,10 @@
- brcm,nand-has-wp;
- };
-
-+ usb3_dmp: syscon@18105000 {
-+ reg = <0x18105000 0x1000>;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -62,33 +62,6 @@
- };
- };
-
-- mdio-mux@18003000 {
-- compatible = "mdio-mux-mmioreg", "mdio-mux";
-- mdio-parent-bus = <&mdio>;
-- #address-cells = <1>;
-- #size-cells = <0>;
-- reg = <0x18003000 0x4>;
-- mux-mask = <0x200>;
--
-- mdio@0 {
-- reg = <0x0>;
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- usb3_phy: usb3-phy@10 {
-- compatible = "brcm,ns-ax-usb3-phy";
-- reg = <0x10>;
-- usb3-dmp-syscon = <&usb3_dmp>;
-- #phy-cells = <0>;
-- status = "disabled";
-- };
-- };
-- };
--
-- usb3_dmp: syscon@18105000 {
-- reg = <0x18105000 0x1000>;
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
deleted file mode 100644
index 72e5c6b061..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
+++ /dev/null
@@ -1,377 +0,0 @@
-From 473baeab929444295b0530f8766e4becb6a08973 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:13 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Explicitly disable unused switch CPU
- ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When redescribing ports I assumed that missing "label" (like "cpu")
-means switch port isn't used. That was incorrect and I realized my
-change made Linux always use the first (5) CPU port (there are 3 of
-them).
-
-While above should technically be possible it often isn't correct:
-1. Non-default switch ports are often connected to Ethernet interfaces
- not fully covered by vendor setup (they may miss MACs)
-2. On some devices non-default ports require specifying fixed link
-
-This fixes network connectivity for some devices. It was reported &
-tested for Netgear R8000. It also affects Linksys EA9200 with its
-downstream DTS.
-
-Fixes: ba4aebce23b2 ("ARM: dts: BCM5301X: Describe switch ports in the main DTS")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts | 8 ++++++++
- .../boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm953012er.dts | 8 ++++++++
- 20 files changed, 160 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -181,5 +181,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -85,5 +85,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -88,5 +88,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -122,5 +122,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -145,6 +145,14 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -145,5 +145,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -81,5 +81,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -148,5 +148,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -227,6 +227,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -160,6 +160,14 @@
- nvmem-cell-names = "mac-address";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -192,6 +192,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- phy-mode = "rgmii";
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -120,5 +120,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -75,5 +75,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -147,5 +147,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -158,5 +158,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -124,6 +124,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -185,6 +185,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -84,6 +84,14 @@
- label = "cpu";
- ethernet = <&gmac0>;
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
deleted file mode 100644
index 0b2b7b36a3..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From d313b0e9070a7100ca55e64fe3b081d176d8806d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:14 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set fixed-link for extra Netgear R8000
- CPU ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Ports 5 and 7 are disabled by default because the standard use case is
-for port 8 to manage all CPU directed traffic. For experimentation
-purposes however it is desirable to provide adequate properties such
-that people can experiment with using different ports without having to
-figure out their configuration. Some of the use cases include but are
-not limited to doubling or tripling the bandwidth by leveraging the
-additional ports/Ethernet MAC combinations.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -229,10 +229,20 @@
-
- port@5 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@7 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
deleted file mode 100644
index 4528c95a5a..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 253358f373492608348136e569366d73cb969f6a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 24 Oct 2023 09:26:05 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set switch ports for Linksys EA9200
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch was developed as OpenWrt downstream change and was recently
-confirmed to work as expected.
-
-Tested-by: Rani Hod <rani.hod@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231024072605.32517-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4709-linksys-ea9200.dts | 38 +++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -47,3 +47,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch b/target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch
deleted file mode 100644
index e4a0f314dc..0000000000
--- a/target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From d3bc6269e21fc474763708e79c7a118740befb94 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 26 Oct 2021 11:37:16 +0200
-Subject: [PATCH] phy: bcm-ns-usb2: support updated DT binding with PHY reg
- space
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Updated DT binding maps just a PHY's register space instead of the whole
-DMU block. Accessing a common CRU reg is handled using syscon &
-regmap.
-
-The old binding has been deprecated and remains supported as a fallback
-method.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20211026093716.5567-1-zajec5@gmail.com
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/phy/broadcom/phy-bcm-ns-usb2.c | 52 +++++++++++++++++++++-----
- 1 file changed, 43 insertions(+), 9 deletions(-)
-
---- a/drivers/phy/broadcom/phy-bcm-ns-usb2.c
-+++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c
-@@ -9,17 +9,23 @@
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <linux/err.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
- #include <linux/of_address.h>
- #include <linux/of_platform.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-+#include <linux/regmap.h>
- #include <linux/slab.h>
-
- struct bcm_ns_usb2 {
- struct device *dev;
- struct clk *ref_clk;
- struct phy *phy;
-+ struct regmap *clkset;
-+ void __iomem *base;
-+
-+ /* Deprecated binding */
- void __iomem *dmu;
- };
-
-@@ -27,7 +33,6 @@ static int bcm_ns_usb2_phy_init(struct p
- {
- struct bcm_ns_usb2 *usb2 = phy_get_drvdata(phy);
- struct device *dev = usb2->dev;
-- void __iomem *dmu = usb2->dmu;
- u32 ref_clk_rate, usb2ctl, usb_pll_ndiv, usb_pll_pdiv;
- int err = 0;
-
-@@ -44,7 +49,10 @@ static int bcm_ns_usb2_phy_init(struct p
- goto err_clk_off;
- }
-
-- usb2ctl = readl(dmu + BCMA_DMU_CRU_USB2_CONTROL);
-+ if (usb2->base)
-+ usb2ctl = readl(usb2->base);
-+ else
-+ usb2ctl = readl(usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
-
- if (usb2ctl & BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK) {
- usb_pll_pdiv = usb2ctl;
-@@ -58,15 +66,24 @@ static int bcm_ns_usb2_phy_init(struct p
- usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate;
-
- /* Unlock DMU PLL settings with some magic value */
-- writel(0x0000ea68, dmu + BCMA_DMU_CRU_CLKSET_KEY);
-+ if (usb2->clkset)
-+ regmap_write(usb2->clkset, 0, 0x0000ea68);
-+ else
-+ writel(0x0000ea68, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
-
- /* Write USB 2.0 PLL control setting */
- usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK;
- usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT;
-- writel(usb2ctl, dmu + BCMA_DMU_CRU_USB2_CONTROL);
-+ if (usb2->base)
-+ writel(usb2ctl, usb2->base);
-+ else
-+ writel(usb2ctl, usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
-
- /* Lock DMU PLL settings */
-- writel(0x00000000, dmu + BCMA_DMU_CRU_CLKSET_KEY);
-+ if (usb2->clkset)
-+ regmap_write(usb2->clkset, 0, 0x00000000);
-+ else
-+ writel(0x00000000, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
-
- err_clk_off:
- clk_disable_unprepare(usb2->ref_clk);
-@@ -90,10 +107,27 @@ static int bcm_ns_usb2_probe(struct plat
- return -ENOMEM;
- usb2->dev = dev;
-
-- usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
-- if (IS_ERR(usb2->dmu)) {
-- dev_err(dev, "Failed to map DMU regs\n");
-- return PTR_ERR(usb2->dmu);
-+ if (of_find_property(dev->of_node, "brcm,syscon-clkset", NULL)) {
-+ usb2->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(usb2->base)) {
-+ dev_err(dev, "Failed to map control reg\n");
-+ return PTR_ERR(usb2->base);
-+ }
-+
-+ usb2->clkset = syscon_regmap_lookup_by_phandle(dev->of_node,
-+ "brcm,syscon-clkset");
-+ if (IS_ERR(usb2->clkset)) {
-+ dev_err(dev, "Failed to lookup clkset regmap\n");
-+ return PTR_ERR(usb2->clkset);
-+ }
-+ } else {
-+ usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
-+ if (IS_ERR(usb2->dmu)) {
-+ dev_err(dev, "Failed to map DMU regs\n");
-+ return PTR_ERR(usb2->dmu);
-+ }
-+
-+ dev_warn(dev, "using deprecated DT binding\n");
- }
-
- usb2->ref_clk = devm_clk_get(dev, "phy-ref-clk");
diff --git a/target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch b/target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch
deleted file mode 100644
index 5ebc78ca20..0000000000
--- a/target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From b9457a04eb89645049fdf427c13e6a18d5501895 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Tue, 11 Oct 2022 14:24:40 +0200
-Subject: [PATCH] bcma: support SPROM rev 11
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Rev 11 works fine for me to set the MAC address of gmac0 and
-gmac1 in the D-Link DWL-8610AP.
-
-Cc: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/bcma/sprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/bcma/sprom.c
-+++ b/drivers/bcma/sprom.c
-@@ -170,7 +170,7 @@ static int bcma_sprom_valid(struct bcma_
- return err;
-
- revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
-- if (revision != 8 && revision != 9 && revision != 10) {
-+ if (revision < 8 || revision > 11) {
- pr_err("Unsupported SPROM revision: %d\n", revision);
- return -ENOENT;
- }
diff --git a/target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch b/target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
deleted file mode 100644
index e1933e75c7..0000000000
--- a/target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 13 Apr 2021 18:25:20 +0200
-Subject: [PATCH] mtd: parsers: trx: parse "firmware" MTD partitions only
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Parsing every partition with "compatible" set to "brcm,trx" results in
-parsing both: firmware partition and failsafe partition on devices that
-implement failsafe booting. This affects e.g. Linksys EA9500 which has:
-
-partition@200000 {
- reg = <0x0200000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-partition@1f00000 {
- reg = <0x01f00000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-Check for MTD partition name "firmware" before parsing. Recently added
-ofpart_linksys_ns.c creates "firmware" and "failsafe" depending on
-bootloader setup.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/mtd/parsers/parser_trx.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/parsers/parser_trx.c
-+++ b/drivers/mtd/parsers/parser_trx.c
-@@ -92,6 +92,10 @@ static int parser_trx_parse(struct mtd_i
- if (err != 0 && err != -EINVAL)
- pr_err("failed to parse \"brcm,trx-magic\" DT attribute, using default: %d\n", err);
-
-+ /* Don't parse any failsafe / backup partitions */
-+ if (strcmp(mtd->name, "firmware"))
-+ return -EINVAL;
-+
- parts = kcalloc(TRX_PARSER_MAX_PARTS, sizeof(struct mtd_partition),
- GFP_KERNEL);
- if (!parts)
diff --git a/target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch b/target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
deleted file mode 100644
index 49277ab251..0000000000
--- a/target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 1 Oct 2016 22:54:48 +0200
-Subject: [PATCH] usb: xhci: add support for performing fake doorbell
-
-Broadcom's Northstar XHCI controllers seem to need a special start
-procedure to work correctly. There isn't any official documentation of
-this, the problem is that controller doesn't detect any connected
-devices with default setup. Moreover connecting USB device to controller
-that doesn't run properly can cause SoC's watchdog issues.
-
-A workaround that was successfully tested on multiple devices is to
-perform a fake doorbell. This patch adds code for doing this and enables
-it on BCM4708 family.
----
- drivers/usb/host/xhci-plat.c | 6 +++++
- drivers/usb/host/xhci.c | 63 +++++++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h | 1 +
- 3 files changed, 67 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci-plat.c
-+++ b/drivers/usb/host/xhci-plat.c
-@@ -77,6 +77,8 @@ static int xhci_priv_resume_quirk(struct
- static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
- {
- struct xhci_plat_priv *priv = xhci_to_priv(xhci);
-+ struct platform_device*pdev = to_platform_device(dev);
-+ struct device_node *node = pdev->dev.of_node;
-
- /*
- * As of now platform drivers don't provide MSI support so we ensure
-@@ -84,6 +86,9 @@ static void xhci_plat_quirks(struct devi
- * dev struct in order to setup MSI
- */
- xhci->quirks |= XHCI_PLAT | priv->quirks;
-+
-+ if (node && of_machine_is_compatible("brcm,bcm4708"))
-+ xhci->quirks |= XHCI_FAKE_DOORBELL;
- }
-
- /* called during probe() after chip reset completes */
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -158,6 +158,49 @@ int xhci_start(struct xhci_hcd *xhci)
- return ret;
- }
-
-+/**
-+ * xhci_fake_doorbell - Perform a fake doorbell on a specified slot
-+ *
-+ * Some controllers require a fake doorbell to start correctly. Without that
-+ * they simply don't detect any devices.
-+ */
-+static int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
-+{
-+ u32 temp;
-+
-+ /* Alloc a virt device for that slot */
-+ if (!xhci_alloc_virt_device(xhci, slot_id, NULL, GFP_NOIO)) {
-+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Ring fake doorbell for slot_id ep 0 */
-+ xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
-+ usleep_range(1000, 1500);
-+
-+ /* Read the status to check if HSE is set or not */
-+ temp = readl(&xhci->op_regs->status);
-+
-+ /* Clear HSE if set */
-+ if (temp & STS_FATAL) {
-+ xhci_dbg(xhci, "HSE problem detected, status: 0x%08x\n", temp);
-+ temp &= ~0x1fff;
-+ temp |= STS_FATAL;
-+ writel(temp, &xhci->op_regs->status);
-+ usleep_range(1000, 1500);
-+ readl(&xhci->op_regs->status);
-+ }
-+
-+ /* Free virt device */
-+ xhci_free_virt_device(xhci, slot_id);
-+
-+ /* We're done if controller is already running */
-+ if (readl(&xhci->op_regs->command) & CMD_RUN)
-+ return 0;
-+
-+ return xhci_start(xhci);
-+}
-+
- /*
- * Reset a halted HC.
- *
-@@ -634,6 +677,16 @@ static int xhci_run_finished(struct xhci
- spin_unlock_irqrestore(&xhci->lock, flags);
- return -ENODEV;
- }
-+
-+ if (xhci->quirks & XHCI_FAKE_DOORBELL) {
-+ int err = xhci_fake_doorbell(xhci, 1);
-+ if (err) {
-+ xhci_halt(xhci);
-+ spin_unlock_irqrestore(&xhci->lock, flags);
-+ return err;
-+ }
-+ }
-+
- xhci->shared_hcd->state = HC_STATE_RUNNING;
- xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
-
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1908,6 +1908,7 @@ struct xhci_hcd {
- #define XHCI_RESET_TO_DEFAULT BIT_ULL(44)
- #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
- #define XHCI_ZHAOXIN_HOST BIT_ULL(46)
-+#define XHCI_FAKE_DOORBELL BIT_ULL(47)
-
- unsigned int num_active_eps;
- unsigned int limit_active_eps;
diff --git a/target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch b/target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
deleted file mode 100644
index 0247a66ccc..0000000000
--- a/target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 24 Sep 2014 22:14:07 +0200
-Subject: [PATCH] ARM: BCM5301X: Disable MMU and Dcache during decompression
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom devices have broken CFE (bootloader) that leaves hardware in an
-invalid state. It causes problems with booting Linux. On Northstar
-devices kernel was randomly hanging in ~25% of tries during early init.
-Hangs used to happen at random places in the start_kernel. On BCM53573
-kernel doesn't even seem to start booting.
-
-To workaround this problem we need to do following very early:
-1) Clear 2 following bits in the SCTLR register:
-#define CR_M (1 << 0) /* MMU enable */
-#define CR_C (1 << 2) /* Dcache enable */
-2) Flush the whole D-cache
-3) Disable L2 cache
-
-Unfortunately this patch is not upstreamable as it does above things
-unconditionally. We can't check if we are running on Broadcom platform
-in any safe way and doing such hacks with ARCH_MULTI_V7 is unacceptable
-as it could break other devices support.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/compressed/Makefile
-+++ b/arch/arm/boot/compressed/Makefile
-@@ -36,6 +36,11 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
- OBJS += ll_char_wr.o font.o
- endif
-
-+ifeq ($(CONFIG_ARCH_BCM_5301X),y)
-+OBJS += head-bcm_5301x-mpcore.o
-+OBJS += cache-v7-min.o
-+endif
-+
- ifeq ($(CONFIG_ARCH_SA1100),y)
- OBJS += head-sa1100.o
- endif
---- /dev/null
-+++ b/arch/arm/boot/compressed/head-bcm_5301x-mpcore.S
-@@ -0,0 +1,37 @@
-+/*
-+ *
-+ * Platform specific tweaks. This is merged into head.S by the linker.
-+ *
-+ */
-+
-+#include <linux/linkage.h>
-+#include <asm/assembler.h>
-+#include <asm/cp15.h>
-+
-+ .section ".start", "ax"
-+
-+/*
-+ * This code section is spliced into the head code by the linker
-+ */
-+
-+__plat_uncompress_start:
-+
-+ @ Preserve r8/r7 i.e. kernel entry values
-+ mov r12, r8
-+
-+ @ Clear MMU enable and Dcache enable bits
-+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
-+ bic r0, #CR_C|CR_M
-+ mcr p15, 0, r0, c1, c0, 0 @ Write SCTLR
-+ nop
-+
-+ @ Call the cache invalidation routine
-+ bl v7_flush_dcache_all
-+ nop
-+ mov r0,#0
-+ ldr r3, =0x19022000 @ L2 cache controller, control reg
-+ str r0, [r3, #0x100] @ Disable L2 cache
-+ nop
-+
-+ @ Restore
-+ mov r8, r12
---- a/arch/arm/boot/compressed/cache-v7-min.S
-+++ b/arch/arm/boot/compressed/cache-v7-min.S
-@@ -12,6 +12,7 @@
-
- #include <linux/linkage.h>
- #include <linux/init.h>
-+#include <asm/assembler.h>
-
- __INIT
-
-@@ -63,7 +64,7 @@ loop2:
- ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
- THUMB( lsl r6, r9, r2 )
- THUMB( orr r11, r11, r6 ) @ factor index number into r11
-- mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
-+ mcr p15, 0, r11, c7, c6, 2 @ clean & invalidate by set/way
- subs r9, r9, #1 @ decrement the index
- bge loop2
- subs r4, r4, #1 @ decrement the way
diff --git a/target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch b/target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
deleted file mode 100644
index 8039831a78..0000000000
--- a/target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
+++ /dev/null
@@ -1,675 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] ARM: dts: BCM5301X: Specify switch ports for remaining
- devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -92,3 +92,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -83,3 +83,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -149,3 +149,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-@@ -46,3 +46,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-@@ -43,3 +43,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -86,3 +86,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -77,3 +77,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -77,6 +77,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -130,3 +130,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -104,3 +104,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -94,3 +94,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -38,6 +38,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -91,6 +91,44 @@
- };
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -100,6 +100,44 @@
- vcc-gpio = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -107,3 +107,42 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
diff --git a/target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch b/target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
deleted file mode 100644
index bc04cbd2d6..0000000000
--- a/target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: [PATCH] ARM: BCM5301X: Add DT for Netgear R7900
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -117,6 +117,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-buffalo-wxr-1900dhp.dtb \
- bcm4709-linksys-ea9200.dtb \
- bcm4709-netgear-r7000.dtb \
-+ bcm4709-netgear-r7900.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac3100.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7900.dts
-@@ -0,0 +1,42 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * DTS for Netgear R7900
-+ *
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ compatible = "netgear,r7900", "brcm,bcm4709", "brcm,bcm4708";
-+ model = "Netgear R7900";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory {
-+ reg = <0x00000000 0x08000000
-+ 0x88000000 0x08000000>;
-+ };
-+
-+ axi@18000000 {
-+ usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch b/target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
deleted file mode 100644
index 209c57ca0b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 2a2af518266a29323cf30c3f9ba9ef2ceb1dd84b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 16 Oct 2014 20:52:16 +0200
-Subject: [PATCH] UBI: Detect EOF mark and erase all remaining blocks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/ubi/attach.c | 5 +++++
- drivers/mtd/ubi/io.c | 4 ++++
- drivers/mtd/ubi/ubi.h | 1 +
- 3 files changed, 10 insertions(+)
-
---- a/drivers/mtd/ubi/attach.c
-+++ b/drivers/mtd/ubi/attach.c
-@@ -82,6 +82,9 @@ static int self_check_ai(struct ubi_devi
- #define AV_ADD BIT(1)
- #define AV_FIND_OR_ADD (AV_FIND | AV_ADD)
-
-+/* Set on finding block with 0xdeadc0de, indicates erasing all blocks behind */
-+bool erase_all_next;
-+
- /**
- * find_or_add_av - internal function to find a volume, add a volume or do
- * both (find and add if missing).
-@@ -1580,6 +1583,8 @@ int ubi_attach(struct ubi_device *ubi, i
- if (!ai)
- return -ENOMEM;
-
-+ erase_all_next = false;
-+
- #ifdef CONFIG_MTD_UBI_FASTMAP
- /* On small flash devices we disable fastmap in any case. */
- if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
---- a/drivers/mtd/ubi/io.c
-+++ b/drivers/mtd/ubi/io.c
-@@ -717,6 +717,10 @@ int ubi_io_read_ec_hdr(struct ubi_device
- }
-
- magic = be32_to_cpu(ec_hdr->magic);
-+ if (magic == 0xdeadc0de)
-+ erase_all_next = true;
-+ if (erase_all_next)
-+ return read_err ? UBI_IO_FF_BITFLIPS : UBI_IO_FF;
- if (magic != UBI_EC_HDR_MAGIC) {
- if (mtd_is_eccerr(read_err))
- return UBI_IO_BAD_HDR_EBADMSG;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -820,6 +820,7 @@ extern struct mutex ubi_devices_mutex;
- extern struct blocking_notifier_head ubi_notifiers;
-
- /* attach.c */
-+extern bool erase_all_next;
- struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
- int ec);
- void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb);
diff --git a/target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch b/target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch
deleted file mode 100644
index 9f6343c791..0000000000
--- a/target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 20 Jun 2022 10:01:18 +0200
-Subject: [PATCH] net: disable GRO by default
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In many cases GRO improves network performance however it comes at a
-cost of chacksums calculations. In case of slow CPU and missing hardware
-csum calculation support GRO can actually decrease network speed.
-
-On BCM4708 *disabling* GRO results in following NAT masquarade speed
-changes:
-1. 364 Mb/s → 396 Mb/s (packet steering disabled)
-2. 341 Mb/s → 566 Mb/s (packet steering enabled)
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- include/linux/netdev_features.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdev_features.h
-+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
- #define NETIF_F_UPPER_DISABLES NETIF_F_LRO
-
- /* changeable features with no special hardware requirements */
--#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)
-+#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO)
-
- /* Changeable features with no special hardware requirements that defaults to off. */
--#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD)
-+#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD | NETIF_F_GRO)
-
- #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
- NETIF_F_HW_VLAN_CTAG_RX | \
diff --git a/target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch b/target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
deleted file mode 100644
index 3a2f4b06ed..0000000000
--- a/target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 10 Jun 2022 13:10:47 +0200
-Subject: [PATCH] bgmac: reduce max frame size to support just MTU 1500
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-bgmac allocates new replacement buffer before handling each received
-frame. Allocating & DMA-preparing 9724 B each time consumes a lot of CPU
-time. Ideally bgmac should just respect currently set MTU but it isn't
-the case right now. For now just revert back to the old limited frame
-size.
-
-This change bumps NAT masquarade speed by ~95%.
-
-Ref: 8c7da63978f1 ("bgmac: configure MTU and add support for frames beyond 8192 byte size")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/ethernet/broadcom/bgmac.h | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -328,8 +328,7 @@
- #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
- #define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \
- BGMAC_RX_FRAME_OFFSET)
--/* Jumbo frame size with FCS */
--#define BGMAC_RX_MAX_FRAME_SIZE 9724
-+#define BGMAC_RX_MAX_FRAME_SIZE 1536
- #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
- #define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
diff --git a/target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch b/target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch
deleted file mode 100644
index e063f02aa9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 6f1c62440eb6846cb8045d7a5480ec7bbe47c96f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Aug 2016 10:30:41 +0200
-Subject: [PATCH] BCM53573 minor hacks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -54,6 +54,7 @@
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&ilp>;
- };
-
- clocks {
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -330,14 +330,6 @@ static int bcma_register_devices(struct
- }
- #endif
-
--#ifdef CONFIG_BCMA_SFLASH
-- if (bus->drv_cc.sflash.present) {
-- err = platform_device_register(&bcma_sflash_dev);
-- if (err)
-- bcma_err(bus, "Error registering serial flash\n");
-- }
--#endif
--
- #ifdef CONFIG_BCMA_NFLASH
- if (bus->drv_cc.nflash.present) {
- err = platform_device_register(&bcma_nflash_dev);
-@@ -415,6 +407,14 @@ int bcma_bus_register(struct bcma_bus *b
- bcma_register_core(bus, core);
- }
-
-+#ifdef CONFIG_BCMA_SFLASH
-+ if (bus->drv_cc.sflash.present) {
-+ err = platform_device_register(&bcma_sflash_dev);
-+ if (err)
-+ bcma_err(bus, "Error registering serial flash\n");
-+ }
-+#endif
-+
- /* Try to get SPROM */
- err = bcma_sprom_get(bus);
- if (err == -ENOENT) {
---- a/drivers/clocksource/arm_arch_timer.c
-+++ b/drivers/clocksource/arm_arch_timer.c
-@@ -14,6 +14,7 @@
- #include <linux/smp.h>
- #include <linux/cpu.h>
- #include <linux/cpu_pm.h>
-+#include <linux/clk.h>
- #include <linux/clockchips.h>
- #include <linux/clocksource.h>
- #include <linux/clocksource_ids.h>
-@@ -946,6 +947,16 @@ static void __init arch_timer_of_configu
- if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
- arch_timer_rate = rate;
-
-+ /* Get clk rate through clk driver if present */
-+ if (!arch_timer_rate) {
-+ struct clk *clk = of_clk_get(np, 0);
-+
-+ if (!IS_ERR(clk)) {
-+ if (!clk_prepare_enable(clk))
-+ arch_timer_rate = clk_get_rate(clk);
-+ }
-+ }
-+
- /* Check the timer frequency. */
- if (validate_timer_rate())
- pr_warn("frequency not available\n");
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
deleted file mode 100644
index 0439e38991..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From 9f66e1dd82e3186aee95282657512ca2aef1afe0 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 19 Oct 2022 21:34:49 +0200
-Subject: [PATCH] ARM: dts: bcm53016: Add devicetree for D-Link DWL-8610AP
-
-This adds a device tree for the BCM53016-based D-Link DWL-8610AP
-access point wireless router.
-
-The TRX-format partitions had to be named "firmware" due to
-an OpenWrt patch that only accepts parting such nodes if they
-are named "firmware".
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221019193449.3036010-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 131 ++++++++++++++++++
- 2 files changed, 132 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -139,6 +139,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm47094-netgear-r8500.dtb \
- bcm47094-phicomm-k3.dtb \
- bcm53015-meraki-mr26.dtb \
-+ bcm53016-dlink-dwl-8610ap.dtb \
- bcm53016-meraki-mr32.dtb \
- bcm94708.dtb \
- bcm94709.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -0,0 +1,131 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+ model = "D-Link DWL-8610AP";
-+ compatible = "dlink,dwl-8610ap", "brcm,bcm53016", "brcm,bcm4708";
-+
-+ memory@0 {
-+ device_type = "memory";
-+ /* 512 MB RAM in 2 x Macronix D9PSH chips */
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ power {
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ };
-+
-+ diag {
-+ /* Actually "diag" unclear what this means */
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ linux,default-trigger = "heartbeat";
-+ };
-+
-+ wlan-2g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wlan-5g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio_keys {
-+ compatible = "gpio-keys";
-+
-+ button-reset {
-+ debounce-interval = <100>;
-+ wakeup-source;
-+ linux,code = <KEY_RESTART>;
-+ label = "reset";
-+ /* This GPIO is actually stored in NVRAM, but it's not gonna change */
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * Flash memory at 0x1e000000-0x1fffffff
-+ * Macronix 32 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e080000 0x00020000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+
-+ et1macaddr: et1macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&gmac1 {
-+ nvmem-cells = <&et1macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ /* Serial SPI NOR Flash MX 25L1606E */
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /*
-+ * Spansion S34ML01G100TFI00 128 MB NAND Flash memory
-+ *
-+ * This ECC is a bit unorthodox but it is what the stock firmware
-+ * is using, so to be able to mount the original partitions
-+ * this is necessary.
-+ */
-+ nand-ecc-strength = <5>;
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /* This is named nflash1.trx in CFE */
-+ trx@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.trx2 in CFE */
-+ trx2@2800000 {
-+ label = "firmware2";
-+ reg = <0x02800000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.rwfs in CFE */
-+ free@5000000 {
-+ label = "free";
-+ reg = <0x05000000 0x03000000>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
deleted file mode 100644
index 21bb94fcc3..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From b1ba87897ceda8e49a47aa92832dd7bff8583e21 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Nov 2022 14:41:04 +0100
-Subject: [PATCH] ARM: dts: bcm47094: Add devicetree for D-Link DIR-890L
-
-This adds a device tree for the D-Link DIR-890L. This device
-is very similar to D-Link DIR-885L, the differences are detailed
-as a comment in the DTS file.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221107134104.1422169-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 211 ++++++++++++++++++
- 2 files changed, 212 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -129,6 +129,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
-+ bcm47094-dlink-dir-890l.dtb \
- bcm47094-linksys-panamera.dtb \
- bcm47094-luxul-abr-4500.dtb \
- bcm47094-luxul-xap-1610.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -0,0 +1,211 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device tree for D-Link DIR-890L
-+ * D-Link calls this board "WRGAC36"
-+ * this router has the same looks and form factor as D-Link DIR-885L.
-+ *
-+ * Some differences from DIR-885L include a separate USB2 port, separate LEDs
-+ * for USB2 and USB3, a separate VCC supply for the USB2 slot and no
-+ * router/extender switch is mounted (there is an empty mount point on the
-+ * PCB) so this device is a pure router. Also the LAN ports are in the right
-+ * order.
-+ *
-+ * Based on the device tree for DIR-885L
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ * Copyright (C) 2022 Linus Walleij
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch1.dtsi"
-+
-+/ {
-+ compatible = "dlink,dir-890l", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "D-Link DIR-890L";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200 earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ /*
-+ * LED information is derived from the boot log which
-+ * conveniently lists all the LEDs.
-+ */
-+ compatible = "gpio-leds";
-+
-+ power-white {
-+ label = "bcm53xx:white:power";
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wan-white {
-+ label = "bcm53xx:white:wan";
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ power-amber {
-+ label = "bcm53xx:amber:power";
-+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wan-amber {
-+ label = "bcm53xx:amber:wan";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ usb3-white {
-+ label = "bcm53xx:white:usb3";
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ usb2-white {
-+ label = "bcm53xx:white:usb2";
-+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ 2ghz {
-+ label = "bcm53xx:white:2ghz";
-+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ 5ghz {
-+ label = "bcm53xx:white:5ghz";
-+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Called "factory reset" in the vendor dmesg */
-+ button-restart {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * The flash memory is memory mapped at 0x1e000000-0x1fffffff
-+ * 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e1f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e1f0000 0x00010000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac2 {
-+ /*
-+ * The NVRAM curiously does not contain a MAC address
-+ * for et2 so since that is the only ethernet interface
-+ * actually in use on the platform, we use this et0 MAC
-+ * address for et2.
-+ */
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /* Spansion S34ML01G2, 128MB with 128KB erase blocks */
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /*
-+ * This is called "nflash" in the vendor kernel with
-+ * "upgrade" and "rootfs" (probably using OpenWrt
-+ * splitpart). We call it "firmware" like standard tools
-+ * assume. The CFE loader contains incorrect information
-+ * about TRX partitions, ignore this, there are no TRX
-+ * partitions: this device uses SEAMA.
-+ */
-+ firmware@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x08000000>;
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3 {
-+ vcc-gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
deleted file mode 100644
index 4c4ed036b9..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From c8ee9f119bfb4244f76c9971c341ec06b49332cd Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 8 Nov 2022 12:07:08 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: Correct description of TP-Link partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-TP-Link routers have flash space partitioned according to the partitions
-table. It may look like fixed partitioning but those partitions can be
-actually reorganized. New can be added (or some removed), offsets and
-sizes may change.
-
-Fix DT to use binding for the TP-Link SafeLoader partitioning method.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221108110708.13693-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 25 ++++---------------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 25 ++++---------------
- 2 files changed, 10 insertions(+), 40 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -95,30 +95,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -104,30 +104,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
deleted file mode 100644
index d6bf49d0cd..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
+++ /dev/null
@@ -1,1700 +0,0 @@
-From af84101e3f2258a303fa2461ebec0878ce23ea10 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Fri, 25 Nov 2022 15:41:27 +0100
-Subject: [PATCH] ARM: dts: broadcom: align LED node names with dtschema
-
-The node names should be generic and DT schema expects certain pattern:
-
- bcm4708-asus-rt-ac68u.dtb: leds: 'logo', 'power', 'usb2', 'usb3' do not match any of the regexes: '(^led-[0-9a-f]$|led)', 'pinctrl-[0-9]+'
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20221125144128.477059-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 15 +++++-----
- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 8 +++---
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 16 +++++------
- .../boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 6 ++--
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 10 +++----
- .../arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 10 +++----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 22 +++++++--------
- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 10 +++----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 14 +++++-----
- .../boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 6 ++--
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 20 ++++++-------
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 6 ++--
- .../boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 16 +++++------
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 22 +++++++--------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 18 ++++++------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 12 ++++----
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 16 +++++------
- .../boot/dts/bcm47094-linksys-panamera.dts | 28 +++++++++----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 6 ++--
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 20 ++++++-------
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 10 +++----
- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 4 +--
- arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 10 +++----
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 14 +++++-----
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 8 +++---
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 6 ++--
- arch/arm/boot/dts/bcm947189acdbmr.dts | 6 ++--
- 37 files changed, 223 insertions(+), 224 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -28,40 +28,39 @@
- leds {
- compatible = "gpio-leds";
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- all {
-+ led-all {
- label = "bcm53xx:blue:all";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
--
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -28,24 +28,24 @@
- leds {
- compatible = "gpio-leds";
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -37,7 +37,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- /* label = "bcm53xx:blue:usb"; */
- function = LED_FUNCTION_USB;
- color = <LED_COLOR_ID_BLUE>;
-@@ -48,14 +48,14 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- /* label = "bcm53xx:red:power"; */
- function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_RED>;
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- /* label = "bcm53xx:white:power"; */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_WHITE>;
-@@ -63,7 +63,7 @@
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- /* label = "bcm53xx:blue:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_BLUE>;
-@@ -71,14 +71,14 @@
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- /* label = "bcm53xx:amber:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- /* label = "bcm53xx:blue:wan"; */
- function = LED_FUNCTION_WAN;
- color = <LED_COLOR_ID_BLUE>;
-@@ -86,14 +86,14 @@
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- /* label = "bcm53xx:blue:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- /* label = "bcm53xx:amber:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_AMBER>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -49,7 +49,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -58,40 +58,40 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:white:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:blue:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:blue:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -42,7 +42,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -29,24 +29,24 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -54,7 +54,7 @@
- linux,default-trigger = "usbport";
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -28,29 +28,29 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -28,64 +28,64 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-green {
-+ led-usb3-green {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- status-red {
-+ led-status-red {
- label = "bcm53xx:red:status";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- status-green {
-+ led-status-green {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- status-blue {
-+ led-status-blue {
- label = "bcm53xx:blue:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-red {
-+ led-wan-red {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -28,30 +28,30 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -49,40 +49,40 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -49,45 +49,45 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -29,62 +29,62 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -23,50 +23,50 @@
- leds {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:green:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port1 {
-+ led-usb2-port1 {
- label = "bcm53xx:green:usb2-port1";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wan-green {
-+ led-wan-green {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:green:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port2 {
-+ led-usb2-port2 {
- label = "bcm53xx:green:usb2-port2";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -28,18 +28,18 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -28,48 +28,48 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router-amber {
-+ led-router-amber {
- label = "bcm53xx:amber:router";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- };
-
-- router-white {
-+ led-router-white {
- label = "bcm53xx:white:router";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-amber {
-+ led-wireless-amber {
- label = "bcm53xx:amber:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-white {
-+ led-wireless-white {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -28,43 +28,43 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -39,59 +39,59 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -23,27 +23,27 @@
- leds {
- compatible = "gpio-leds";
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -51,24 +51,24 @@
- linux,default-trigger = "usbport";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- wan-blue {
-+ led-wan-blue {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -33,37 +33,37 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "white:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-red {
-+ led-wan-red {
- label = "red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "white:lan";
- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "white:usb2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port1>, <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "white:wps";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -43,28 +43,28 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,12 +72,12 @@
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -41,47 +41,47 @@
- */
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb2-white {
-+ led-usb2-white {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -52,19 +52,19 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 22 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:green:usb2";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,58 +72,58 @@
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wifi-disabled {
-+ led-wifi-disabled {
- label = "bcm53xx:amber:wifi-disabled";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wifi-enabled {
-+ led-wifi-enabled {
- label = "bcm53xx:white:wifi-enabled";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar1 {
-+ led-bluebar1 {
- label = "bcm53xx:white:bluebar1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar2 {
-+ led-bluebar2 {
- label = "bcm53xx:white:bluebar2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar3 {
-+ led-bluebar3 {
- label = "bcm53xx:white:bluebar3";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- };
-
-- bluebar4 {
-+ led-bluebar4 {
- label = "bcm53xx:white:bluebar4";
- gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar5 {
-+ led-bluebar5 {
- label = "bcm53xx:white:bluebar5";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar6 {
-+ led-bluebar6 {
- label = "bcm53xx:white:bluebar6";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar7 {
-+ led-bluebar7 {
- label = "bcm53xx:white:bluebar7";
- gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar8 {
-+ led-bluebar8 {
- label = "bcm53xx:white:bluebar8";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -23,18 +23,18 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -25,7 +25,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -30,38 +30,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -69,18 +69,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -33,13 +33,13 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -47,18 +47,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -25,38 +25,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -23,13 +23,13 @@
- leds {
- compatible = "gpio-leds";
-
-- wlan {
-+ led-wlan {
- label = "bcm53xx:blue:wlan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-off";
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -20,26 +20,26 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-off";
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-off";
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -20,37 +20,37 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:blue:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -20,14 +20,14 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
-- diag {
-+ led-diag {
- /* Actually "diag" unclear what this means */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -36,13 +36,13 @@
- linux,default-trigger = "heartbeat";
- };
-
-- wlan-2g {
-+ led-wlan-2g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- wlan-5g {
-+ led-wlan-5g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -58,7 +58,7 @@
- pwm-leds {
- compatible = "pwm-leds";
-
-- red {
-+ led-0 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -66,7 +66,7 @@
- max-brightness = <255>;
- };
-
-- green {
-+ led-1 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
-@@ -74,7 +74,7 @@
- max-brightness = <255>;
- };
-
-- blue {
-+ led-2 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_BLUE>;
---- a/arch/arm/boot/dts/bcm947189acdbmr.dts
-+++ b/arch/arm/boot/dts/bcm947189acdbmr.dts
-@@ -25,17 +25,17 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
deleted file mode 100644
index 4744e6d5b1..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From 915fac07f053418d0ab9075af64da2872ca8a7f8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:10 +0200
-Subject: [PATCH] =?UTF-8?q?ARM:=20dts:=20BCM5301X:=20Relicense=20Rafa?=
- =?UTF-8?q?=C5=82's=20code=20to=20the=20GPL=202.0+=20/=20MIT?=
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-Introduce a new .dtsi file with a proper SPDX tag.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- MAINTAINERS | 1 +
- arch/arm/boot/dts/bcm-ns.dtsi | 202 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 192 +-----------------------------
- 3 files changed, 205 insertions(+), 190 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm-ns.dtsi
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -4063,6 +4063,7 @@ M: Rafał Miłecki <zajec5@gmail.com>
- R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
- L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
- S: Maintained
-+F: arch/arm/boot/dts/bcm-ns.dtsi
- F: arch/arm/boot/dts/bcm470*
- F: arch/arm/boot/dts/bcm5301*
- F: arch/arm/boot/dts/bcm953012*
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -0,0 +1,202 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+
-+#include <dt-bindings/clock/bcm-nsp.h>
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+
-+/ {
-+ axi@18000000 {
-+ compatible = "brcm,bus-axi";
-+ reg = <0x18000000 0x1000>;
-+ ranges = <0x00000000 0x18000000 0x00100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon: chipcommon@0 {
-+ reg = <0x00000000 0x1000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+
-+ pcie0: pcie@12000 {
-+ reg = <0x00012000 0x1000>;
-+ };
-+
-+ pcie1: pcie@13000 {
-+ reg = <0x00013000 0x1000>;
-+ };
-+
-+ usb2: usb2@21000 {
-+ reg = <0x00021000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ ehci: usb@21000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ehci";
-+ reg = <0x00021000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb2_phy>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ehci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ehci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+
-+ ohci: usb@22000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ohci";
-+ reg = <0x00022000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ohci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ohci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ usb3: usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ xhci: usb@23000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-xhci";
-+ reg = <0x00023000 0x1000>;
-+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb3_phy>;
-+ phy-names = "usb";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ xhci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+ };
-+
-+ mdio: mdio@18003000 {
-+ compatible = "brcm,iproc-mdio";
-+ reg = <0x18003000 0x8>;
-+ #size-cells = <0>;
-+ #address-cells = <1>;
-+ };
-+
-+ dmu-bus@1800c000 {
-+ compatible = "simple-bus";
-+ ranges = <0 0x1800c000 0x1000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ cru-bus@100 {
-+ compatible = "brcm,ns-cru", "simple-mfd";
-+ reg = <0x100 0x1a4>;
-+ ranges;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ usb2_phy: phy@164 {
-+ compatible = "brcm,ns-usb2-phy";
-+ reg = <0x164 0x4>;
-+ brcm,syscon-clkset = <&cru_clkset>;
-+ clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-+ clock-names = "phy-ref-clk";
-+ #phy-cells = <0>;
-+ };
-+
-+ cru_clkset: syscon@180 {
-+ compatible = "brcm,cru-clkset", "syscon";
-+ reg = <0x180 0x4>;
-+ };
-+
-+ pinctrl: pinctrl@1c0 {
-+ compatible = "brcm,bcm4708-pinmux";
-+ reg = <0x1c0 0x24>;
-+ reg-names = "cru_gpio_control";
-+
-+ spi-pins {
-+ groups = "spi_grp";
-+ function = "spi";
-+ };
-+
-+ pinmux_i2c: i2c-pins {
-+ groups = "i2c_grp";
-+ function = "i2c";
-+ };
-+
-+ pinmux_pwm: pwm-pins {
-+ groups = "pwm0_grp", "pwm1_grp",
-+ "pwm2_grp", "pwm3_grp";
-+ function = "pwm";
-+ };
-+
-+ pinmux_uart1: uart1-pins {
-+ groups = "uart1_grp";
-+ function = "uart1";
-+ };
-+ };
-+
-+ thermal: thermal@2c0 {
-+ compatible = "brcm,ns-thermal";
-+ reg = <0x2c0 0x10>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ thermal-zones {
-+ cpu_thermal: cpu-thermal {
-+ polling-delay-passive = <0>;
-+ polling-delay = <1000>;
-+ coefficients = <(-556) 418000>;
-+ thermal-sensors = <&thermal>;
-+
-+ trips {
-+ cpu-crit {
-+ temperature = <125000>;
-+ hysteresis = <0>;
-+ type = "critical";
-+ };
-+ };
-+
-+ cooling-maps {
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -8,11 +8,7 @@
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
--#include <dt-bindings/clock/bcm-nsp.h>
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/input/input.h>
--#include <dt-bindings/interrupt-controller/irq.h>
--#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include "bcm-ns.dtsi"
-
- / {
- #address-cells = <1>;
-@@ -149,12 +145,6 @@
- };
-
- axi@18000000 {
-- compatible = "brcm,bus-axi";
-- reg = <0x18000000 0x1000>;
-- ranges = <0x00000000 0x18000000 0x00100000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- #interrupt-cells = <1>;
- interrupt-map-mask = <0x000fffff 0xffff>;
- interrupt-map =
-@@ -228,108 +218,15 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon: chipcommon@0 {
-- reg = <0x00000000 0x1000>;
--
-- gpio-controller;
-- #gpio-cells = <2>;
-+ chipcommon@0 {
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
-- pcie0: pcie@12000 {
-- reg = <0x00012000 0x1000>;
-- };
--
-- pcie1: pcie@13000 {
-- reg = <0x00013000 0x1000>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
-
-- usb2: usb2@21000 {
-- reg = <0x00021000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- ehci: usb@21000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ehci";
-- reg = <0x00021000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb2_phy>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ehci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ehci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
--
-- ohci: usb@22000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ohci";
-- reg = <0x00022000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ohci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ohci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
-- usb3: usb3@23000 {
-- reg = <0x00023000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- xhci: usb@23000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-xhci";
-- reg = <0x00023000 0x1000>;
-- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb3_phy>;
-- phy-names = "usb";
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- xhci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
- };
-@@ -355,13 +252,6 @@
- status = "disabled";
- };
-
-- mdio: mdio@18003000 {
-- compatible = "brcm,iproc-mdio";
-- reg = <0x18003000 0x8>;
-- #size-cells = <0>;
-- #address-cells = <1>;
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -409,18 +299,7 @@
- };
-
- dmu-bus@1800c000 {
-- compatible = "simple-bus";
-- ranges = <0 0x1800c000 0x1000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- cru-bus@100 {
-- compatible = "brcm,ns-cru", "simple-mfd";
-- reg = <0x100 0x1a4>;
-- ranges;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- lcpll0: clock-controller@100 {
- #clock-cells = <1>;
- compatible = "brcm,nsp-lcpll0";
-@@ -440,53 +319,6 @@
- "usbclk", "iprocfast",
- "sata1", "sata2";
- };
--
-- usb2_phy: phy@164 {
-- compatible = "brcm,ns-usb2-phy";
-- reg = <0x164 0x4>;
-- brcm,syscon-clkset = <&cru_clkset>;
-- clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-- clock-names = "phy-ref-clk";
-- #phy-cells = <0>;
-- };
--
-- cru_clkset: syscon@180 {
-- compatible = "brcm,cru-clkset", "syscon";
-- reg = <0x180 0x4>;
-- };
--
-- pinctrl: pinctrl@1c0 {
-- compatible = "brcm,bcm4708-pinmux";
-- reg = <0x1c0 0x24>;
-- reg-names = "cru_gpio_control";
--
-- spi-pins {
-- groups = "spi_grp";
-- function = "spi";
-- };
--
-- pinmux_i2c: i2c-pins {
-- groups = "i2c_grp";
-- function = "i2c";
-- };
--
-- pinmux_pwm: pwm-pins {
-- groups = "pwm0_grp", "pwm1_grp",
-- "pwm2_grp", "pwm3_grp";
-- function = "pwm";
-- };
--
-- pinmux_uart1: uart1-pins {
-- groups = "uart1_grp";
-- function = "uart1";
-- };
-- };
--
-- thermal: thermal@2c0 {
-- compatible = "brcm,ns-thermal";
-- reg = <0x2c0 0x10>;
-- #thermal-sensor-cells = <0>;
-- };
- };
- };
-
-@@ -557,24 +389,4 @@
- };
- };
- };
--
-- thermal-zones {
-- cpu_thermal: cpu-thermal {
-- polling-delay-passive = <0>;
-- polling-delay = <1000>;
-- coefficients = <(-556) 418000>;
-- thermal-sensors = <&thermal>;
--
-- trips {
-- cpu-crit {
-- temperature = <125000>;
-- hysteresis = <0>;
-- type = "critical";
-- };
-- };
--
-- cooling-maps {
-- };
-- };
-- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
deleted file mode 100644
index b98f2daa67..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 916553449561c4f0b61c71b751b7bb583f5dddd4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Florian's code to the GPL 2.0+
- / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 36 ++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 39 ---------------------------------
- 2 files changed, 36 insertions(+), 39 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -19,6 +19,8 @@
-
- gpio-controller;
- #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
- };
-
- pcie0: pcie@12000 {
-@@ -109,6 +111,22 @@
- };
- };
- };
-+
-+ gmac0: ethernet@24000 {
-+ reg = <0x24000 0x800>;
-+ };
-+
-+ gmac1: ethernet@25000 {
-+ reg = <0x25000 0x800>;
-+ };
-+
-+ gmac2: ethernet@26000 {
-+ reg = <0x26000 0x800>;
-+ };
-+
-+ gmac3: ethernet@27000 {
-+ reg = <0x27000 0x800>;
-+ };
- };
-
- mdio: mdio@18003000 {
-@@ -118,6 +136,24 @@
- #address-cells = <1>;
- };
-
-+ rng: rng@18004000 {
-+ compatible = "brcm,bcm5301x-rng";
-+ reg = <0x18004000 0x14>;
-+ };
-+
-+ srab: ethernet-switch@18007000 {
-+ compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-+ reg = <0x18007000 0x1000>;
-+
-+ status = "disabled";
-+
-+ /* ports are defined in board DTS */
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -218,30 +218,9 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon@0 {
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
--
-- gmac0: ethernet@24000 {
-- reg = <0x24000 0x800>;
-- };
--
-- gmac1: ethernet@25000 {
-- reg = <0x25000 0x800>;
-- };
--
-- gmac2: ethernet@26000 {
-- reg = <0x26000 0x800>;
-- };
--
-- gmac3: ethernet@27000 {
-- reg = <0x27000 0x800>;
-- };
- };
-
- pwm: pwm@18002000 {
-@@ -322,24 +301,6 @@
- };
- };
-
-- srab: ethernet-switch@18007000 {
-- compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-- reg = <0x18007000 0x1000>;
--
-- status = "disabled";
--
-- /* ports are defined in board DTS */
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
-- };
-- };
--
-- rng: rng@18004000 {
-- compatible = "brcm,bcm5301x-rng";
-- reg = <0x18004000 0x14>;
-- };
--
- nand_controller: nand-controller@18028000 {
- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 328748c8e0..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From b3b3cd885ed39cb4b38319a1c4fa4e41db6fee72 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:20 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Hauke's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Hauke to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 90 +++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 85 -------------------------------
- 2 files changed, 90 insertions(+), 85 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -1,4 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ */
-
- #include <dt-bindings/clock/bcm-nsp.h>
- #include <dt-bindings/gpio/gpio.h>
-@@ -7,6 +10,81 @@
- #include <dt-bindings/interrupt-controller/arm-gic.h>
-
- / {
-+ interrupt-parent = <&gic>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon-a-bus@18000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x18000000 0x00001000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ uart0: serial@300 {
-+ compatible = "ns16550";
-+ reg = <0x0300 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@400 {
-+ compatible = "ns16550";
-+ reg = <0x0400 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinmux_uart1>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ mpcore-bus@19000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x19000000 0x00023000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ scu@20000 {
-+ compatible = "arm,cortex-a9-scu";
-+ reg = <0x20000 0x100>;
-+ };
-+
-+ timer@20200 {
-+ compatible = "arm,cortex-a9-global-timer";
-+ reg = <0x20200 0x100>;
-+ interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ timer@20600 {
-+ compatible = "arm,cortex-a9-twd-timer";
-+ reg = <0x20600 0x20>;
-+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-+ IRQ_TYPE_EDGE_RISING)>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ gic: interrupt-controller@21000 {
-+ compatible = "arm,cortex-a9-gic";
-+ #interrupt-cells = <3>;
-+ #address-cells = <0>;
-+ interrupt-controller;
-+ reg = <0x21000 0x1000>,
-+ <0x20100 0x100>;
-+ };
-+
-+ L2: cache-controller@22000 {
-+ compatible = "arm,pl310-cache";
-+ reg = <0x22000 0x1000>;
-+ cache-unified;
-+ arm,shared-override;
-+ prefetch-data = <1>;
-+ prefetch-instr = <1>;
-+ cache-level = <2>;
-+ };
-+ };
-+
- axi@18000000 {
- compatible = "brcm,bus-axi";
- reg = <0x18000000 0x1000>;
-@@ -216,6 +294,18 @@
- };
- };
-
-+ nand_controller: nand-controller@18028000 {
-+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-+ reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-+ reg-names = "nand", "iproc-idm", "iproc-ext";
-+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcm,nand-has-wp;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -11,41 +11,7 @@
- #include "bcm-ns.dtsi"
-
- / {
-- #address-cells = <1>;
-- #size-cells = <1>;
-- interrupt-parent = <&gic>;
--
-- chipcommon-a-bus@18000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x18000000 0x00001000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- uart0: serial@300 {
-- compatible = "ns16550";
-- reg = <0x0300 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- status = "disabled";
-- };
--
-- uart1: serial@400 {
-- compatible = "ns16550";
-- reg = <0x0400 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&pinmux_uart1>;
-- status = "disabled";
-- };
-- };
--
- mpcore-bus@19000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x19000000 0x00023000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- a9pll: arm_clk@0 {
- #clock-cells = <0>;
- compatible = "brcm,nsp-armpll";
-@@ -53,26 +19,6 @@
- reg = <0x00000 0x1000>;
- };
-
-- scu@20000 {
-- compatible = "arm,cortex-a9-scu";
-- reg = <0x20000 0x100>;
-- };
--
-- timer@20200 {
-- compatible = "arm,cortex-a9-global-timer";
-- reg = <0x20200 0x100>;
-- interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-- clocks = <&periph_clk>;
-- };
--
-- timer@20600 {
-- compatible = "arm,cortex-a9-twd-timer";
-- reg = <0x20600 0x20>;
-- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-- IRQ_TYPE_EDGE_RISING)>;
-- clocks = <&periph_clk>;
-- };
--
- watchdog@20620 {
- compatible = "arm,cortex-a9-twd-wdt";
- reg = <0x20620 0x20>;
-@@ -80,25 +26,6 @@
- IRQ_TYPE_EDGE_RISING)>;
- clocks = <&periph_clk>;
- };
--
-- gic: interrupt-controller@21000 {
-- compatible = "arm,cortex-a9-gic";
-- #interrupt-cells = <3>;
-- #address-cells = <0>;
-- interrupt-controller;
-- reg = <0x21000 0x1000>,
-- <0x20100 0x100>;
-- };
--
-- L2: cache-controller@22000 {
-- compatible = "arm,pl310-cache";
-- reg = <0x22000 0x1000>;
-- cache-unified;
-- arm,shared-override;
-- prefetch-data = <1>;
-- prefetch-instr = <1>;
-- cache-level = <2>;
-- };
- };
-
- pmu {
-@@ -301,18 +228,6 @@
- };
- };
-
-- nand_controller: nand-controller@18028000 {
-- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-- reg-names = "nand", "iproc-idm", "iproc-ext";
-- interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- brcm,nand-has-wp;
-- };
--
- spi@18029200 {
- compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi";
- reg = <0x18029200 0x184>,
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
deleted file mode 100644
index ef29266d0b..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 3b3e35b279bee5e51580c648399e20323467f58c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:21 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense AXI interrupts code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Those entries were added by:
-1. Hauke in commits dec378827c4a ("ARM: BCM5301X: Add IRQs to Broadcom's
- bus-axi in DTS file") and 1f80de6863ca ("ARM: BCM5301X: add IRQ
- numbers for PCIe controller")
-2. Florian in the commit 2cd0c0202f13 ("ARM: dts: BCM5301X: Add SRAB
- interrupts")
-
-Move them to the bcm-ns.dtsi which uses dual licensing. That syncs more
-Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 73 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 75 ---------------------------------
- 2 files changed, 73 insertions(+), 75 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -92,6 +92,79 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ #interrupt-cells = <1>;
-+ interrupt-map-mask = <0x000fffff 0xffff>;
-+ interrupt-map =
-+ /* ChipCommon */
-+ <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Switch Register Access Block */
-+ <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 0 */
-+ <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 1 */
-+ <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 2 */
-+ <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 2.0 Controller */
-+ <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 3.0 Controller */
-+ <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 0 */
-+ <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 1 */
-+ <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 2 */
-+ <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 3 */
-+ <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* NAND Controller */
-+ <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-+
- chipcommon: chipcommon@0 {
- reg = <0x00000000 0x1000>;
-
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -3,8 +3,6 @@
- * Generic DTS part for all BCM53010, BCM53011, BCM53012, BCM53014, BCM53015,
- * BCM53016, BCM53017, BCM53018, BCM4707, BCM4708 and BCM4709 SoCs
- *
-- * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-- *
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
-@@ -72,79 +70,6 @@
- };
-
- axi@18000000 {
-- #interrupt-cells = <1>;
-- interrupt-map-mask = <0x000fffff 0xffff>;
-- interrupt-map =
-- /* ChipCommon */
-- <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Switch Register Access Block */
-- <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 0 */
-- <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 1 */
-- <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 2 */
-- <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 2.0 Controller */
-- <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 3.0 Controller */
-- <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 0 */
-- <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 1 */
-- <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 2 */
-- <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 3 */
-- <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* NAND Controller */
-- <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
deleted file mode 100644
index 7d9b297191..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
+++ /dev/null
@@ -1,336 +0,0 @@
-From dfa6570eb5ce2f24059caadbe2ed70034b5337bc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 10:33:08 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Specify MAC addresses on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use NRAM (NVMEM device) and its "et0macaddr" variable (NVMEM cell) to
-point Ethernet devices to their MAC addresses.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230515083308.7612-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 5 ++++-
- 10 files changed, 113 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -24,6 +24,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -60,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -24,6 +24,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -106,6 +110,11 @@
- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -137,6 +146,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -51,6 +59,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -22,6 +22,14 @@
- <0x88000000 0x18000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -47,6 +55,11 @@
- status = "okay";
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -101,6 +105,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -136,6 +145,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -27,6 +27,7 @@
- reg = <0x1eff0000 0x10000>;
-
- et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
- };
- };
-
-@@ -76,7 +77,7 @@
- };
-
- &gmac0 {
-- nvmem-cells = <&et0macaddr>;
-+ nvmem-cells = <&et0macaddr 0>;
- nvmem-cell-names = "mac-address";
- };
-
-@@ -119,6 +120,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
deleted file mode 100644
index 5f5890e291..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 9d7121f1d2faa0b50bf5b462adcd2dd91970c45e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 20 May 2023 13:26:01 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated device "compatible" strings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar binding was updated to use minus/hyphen char between model and
-version for all devices.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230520112601.11821-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 2 +-
- 6 files changed, 6 insertions(+), 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -8,7 +8,7 @@
- #include "bcm4708.dtsi"
-
- / {
-- compatible = "luxul,xap-1510v1", "brcm,bcm4708";
-+ compatible = "luxul,xap-1510-v1", "brcm,bcm4708";
- model = "Luxul XAP-1510 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -13,7 +13,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6250v1", "brcm,bcm4708";
-+ compatible = "netgear,r6250-v1", "brcm,bcm4708";
- model = "Netgear R6250 V1 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -12,7 +12,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6300v2", "brcm,bcm4708";
-+ compatible = "netgear,r6300-v2", "brcm,bcm4708";
- model = "Netgear R6300 V2 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -8,7 +8,7 @@
- #include "bcm47081.dtsi"
-
- / {
-- compatible = "luxul,xap-1410v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xap-1410-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XAP-1410 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-1200v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xwr-1200-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XWR-1200 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-3100v1", "brcm,bcm47094", "brcm,bcm4708";
-+ compatible = "luxul,xwr-3100-v1", "brcm,bcm47094", "brcm,bcm4708";
- model = "Luxul XWR-3100 V1";
-
- chosen {
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
deleted file mode 100644
index c16587f684..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 04afb51c1dce90051487d3c7b70a1b1b246ce29a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 17:10:23 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated "spi-gpio" binding properties
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Switch away from deprecated properties.
-
-This fixes:
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-sck: False schema does not allow [[6, 7, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-mosi: False schema does not allow [[6, 4, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: 'sck-gpios' is a required property
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: Unevaluated properties are not allowed ('gpio-mosi', 'gpio-sck' were unexpected)
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602151023.8607-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 4 ++--
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 4 ++--
- 4 files changed, 8 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -16,8 +16,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
deleted file mode 100644
index 59fa457aee..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From c3acdd4901192bc69dc577012663d5abae21661e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:54 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid #usb-cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Such property simply doesn't exist (is not documented or used anywhere).
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@21000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ehci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@22000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ohci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@23000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-xhci.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -192,8 +192,6 @@
- interrupt-parent = <&gic>;
-
- ehci: usb@21000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ehci";
- reg = <0x00021000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -214,8 +212,6 @@
- };
-
- ohci: usb@22000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ohci";
- reg = <0x00022000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -245,8 +241,6 @@
- interrupt-parent = <&gic>;
-
- xhci: usb@23000 {
-- #usb-cells = <0>;
--
- compatible = "generic-xhci";
- reg = <0x00023000 0x1000>;
- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
deleted file mode 100644
index b8411fc719..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 676bf7d062c14191c3fc12f1e36e1f3809041483 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid properties from Meraki MR32
- keys
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm53015-meraki-mr26.dtb: keys: '#address-cells', '#size-cells' do not match any of the regexes: '^(button|event|key|switch|(button|event|key|switch)-[a-z0-9-]+|[a-z0-9-]+-(button|event|key|switch))$', 'pinctrl-[0-9]+'
- From schema: Documentation/devicetree/bindings/input/gpio-keys.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -39,8 +39,6 @@
-
- keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- key-restart {
- label = "Reset";
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
deleted file mode 100644
index 7496321269..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 1d5682ccc7d6088179b6cfd50a3e3bb6d2b0527e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 08:10:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Christian's code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Christian to the bcm-ns.dtsi which uses dual
-licensing. That syncs more Northstar code to be based on the same
-licensing schema.
-
-Cc: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/20230605061049.16136-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 21 +++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 23 -----------------------
- 2 files changed, 21 insertions(+), 23 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -182,6 +182,10 @@
- reg = <0x00013000 0x1000>;
- };
-
-+ pcie2: pcie@14000 {
-+ reg = <0x00014000 0x1000>;
-+ };
-+
- usb2: usb2@21000 {
- reg = <0x00021000 0x1000>;
-
-@@ -274,6 +278,14 @@
- };
- };
-
-+ pwm: pwm@18002000 {
-+ compatible = "brcm,iproc-pwm";
-+ reg = <0x18002000 0x28>;
-+ clocks = <&osc>;
-+ #pwm-cells = <3>;
-+ status = "disabled";
-+ };
-+
- mdio: mdio@18003000 {
- compatible = "brcm,iproc-mdio";
- reg = <0x18003000 0x8>;
-@@ -299,6 +311,15 @@
- };
- };
-
-+ uart2: serial@18008000 {
-+ compatible = "ns16550a";
-+ reg = <0x18008000 0x20>;
-+ clocks = <&iprocslow>;
-+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -69,20 +69,6 @@
- };
- };
-
-- axi@18000000 {
-- pcie2: pcie@14000 {
-- reg = <0x00014000 0x1000>;
-- };
-- };
--
-- pwm: pwm@18002000 {
-- compatible = "brcm,iproc-pwm";
-- reg = <0x18002000 0x28>;
-- clocks = <&osc>;
-- #pwm-cells = <3>;
-- status = "disabled";
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -110,15 +96,6 @@
- reg = <0x18105000 0x1000>;
- };
-
-- uart2: serial@18008000 {
-- compatible = "ns16550a";
-- reg = <0x18008000 0x20>;
-- clocks = <&iprocslow>;
-- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-- reg-shift = <2>;
-- status = "disabled";
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
deleted file mode 100644
index fa2f21af53..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
+++ /dev/null
@@ -1,838 +0,0 @@
-From ba4aebce23b2affb810b8a60eae853674d2cded2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 15:21:09 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Describe switch ports in the main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All Northstar SoCs have BCM5301x switches (BCM53011, BCM53012) with 8
-ports (0-8 without 6). By design 3 switch ports (5, 7 and 8) are
-hardwired to 3 on-SoC Ethernet interfaces. Switch port 8 requires
-forcing link state.
-
-It seems that global Northstar .dtsi file is the best place to describe
-those hw details. Only device specific bits (like labels) should go to
-device .dts files.
-
-This seems to fit well with a tiny exception of Asus RT-AC88U which
-somehow was designed to have switch 5 connected to an extra switch. This
-case was simply handled with a /delete-property/.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Christian Lamparter <chunkeey@gmail.com> (MR32+MR26)
-Link: https://lore.kernel.org/r/20230605132109.7933-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 41 ++++++++++++++++++-
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 7 ----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 4 --
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 3 --
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 7 ----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 7 ----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 7 ----
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 3 --
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 7 ----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 12 ------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 17 +-------
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 12 ------
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 12 ------
- .../boot/dts/bcm47094-linksys-panamera.dts | 34 ++++-----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 4 --
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 3 --
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 7 ----
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 7 ----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 3 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 3 --
- 22 files changed, 51 insertions(+), 163 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -304,10 +304,49 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac0>;
-+ };
-+
-+ port@7 {
-+ reg = <7>;
-+ ethernet = <&gmac1>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -159,34 +159,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -75,19 +75,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -82,14 +82,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -100,34 +100,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -75,14 +75,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -124,36 +124,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -191,39 +191,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -181,32 +181,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- sw0_p5: port@5 {
-- reg = <5>;
-+ /delete-property/ethernet;
-+
- label = "extsw";
- phy-mode = "rgmii";
-
-@@ -218,8 +214,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
-
- fixed-link {
-@@ -229,14 +223,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -124,39 +124,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -172,40 +172,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
- phy-mode = "rgmii";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -207,29 +207,32 @@
- dsa,member = <0 0>;
-
- ports {
-+ sw0_p0: port@0 {
-+ label = "extsw";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@1 {
-- reg = <1>;
- label = "lan7";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan4";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan8";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
-- ethernet = <&gmac0>;
- label = "cpu";
- status = "disabled";
-
-@@ -240,8 +243,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
- status = "disabled";
-
-@@ -252,24 +253,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- sw0_p0: port@0 {
-- reg = <0>;
-- label = "extsw";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -73,19 +73,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -69,14 +69,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -123,36 +123,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -98,36 +98,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -115,14 +115,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -176,14 +176,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
deleted file mode 100644
index ea571f459a..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From a6a1a156f5debaebf9f61850d111b966e9be9ee9 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR26: MR32: remove bogus nand-ecc-algo
- property
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-| bcm53015-meraki-mr26.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-| bcm53016-meraki-mr32.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-
-original ECC values for these old Merakis are sadly not
-provided by the vendor. It looks like Meraki just stuck
-with what Broadcom's SDK was doing... which left this
-up to the proprietary nand driver.
-
-Note: The invalid setting was and is handled by brcmnand. It
-falls back to "bch" in brcmnand_setup_dev() when ecc.algo is
-set to NAND_ECC_ALGO_UNKNOWN (since "hw" is not in the list
-above).
-
-A correct nand-ecc-algo = "bch"; is already specified in the
-included "bcm5301x-nand-cs0-bch8.dtsi". So this line can be
-dropped.
-
-Reported-by: Rafał Miłecki <zajec5@gmail.com> (per Mail)
-Fixes: 935327a73553 ("ARM: dts: BCM5301X: Add DT for Meraki MR26")
-Fixes: ec88a9c344d9 ("ARM: BCM5301X: Add DT for Meraki MR32")
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/2c4d00dd40124c2ddc0b139cbce7531b108f9052.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 --
- 2 files changed, 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -72,8 +72,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <0x1>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -125,8 +125,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- /*
- * The partition autodetection does not work for this device.
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
deleted file mode 100644
index 8eb5442d17..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From d68b2f7d7d06872450d4f39d84d5926d7e7ae88c Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:28 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR32: remove partition index numbers
-
-removes the partition indexes in the node names under.
-This brings the device tree source in line with others.
-
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/627f57d568030a56499361790524b4d4f3381619.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -138,31 +138,31 @@
- #address-cells = <0x1>;
- #size-cells = <0x1>;
-
-- partition0@0 {
-+ partition@0 {
- label = "u-boot";
- reg = <0x0 0x100000>;
- read-only;
- };
-
-- partition1@100000 {
-+ partition@100000 {
- label = "bootkernel1";
- reg = <0x100000 0x300000>;
- read-only;
- };
-
-- partition2@400000 {
-+ partition@400000 {
- label = "nvram";
- reg = <0x400000 0x100000>;
- read-only;
- };
-
-- partition3@500000 {
-+ partition@500000 {
- label = "bootkernel2";
- reg = <0x500000 0x300000>;
- read-only;
- };
-
-- partition4@800000 {
-+ partition@800000 {
- label = "ubi";
- reg = <0x800000 0x7780000>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
deleted file mode 100644
index 3ffe0b2f17..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 752a63b8dbe6cc6900efd1035bea427a778a4b55 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:59:25 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Netgear R8000 WiFi regulator mappings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602135925.14143-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -137,8 +137,10 @@
- #size-cells = <2>;
-
- wifi@0,1,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5735000 5835000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
-@@ -159,6 +161,19 @@
- #address-cells = <3>;
- #size-cells = <2>;
-
-+ bridge@1,0 {
-+ reg = <0x800 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
-+ };
-+ };
-+
- bridge@1,2,2 {
- reg = <0x1000 0 0 0 0>;
-
-@@ -166,8 +181,10 @@
- #size-cells = <2>;
-
- wifi@1,4,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5170000 5730000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
deleted file mode 100644
index 454ce4c278..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From b67cad33176e472df6d16a24ee7624299bdcd5d5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Jun 2023 12:58:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add cells sizes to PCIe nodes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-
-Two properties that need to be added later are "device_type" and
-"ranges". Adding "device_type" on its own causes a new warning and the
-value of "ranges" needs to be determined yet.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230616105827.21656-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -176,14 +176,23 @@
-
- pcie0: pcie@12000 {
- reg = <0x00012000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie1: pcie@13000 {
- reg = <0x00013000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- usb2: usb2@21000 {
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
deleted file mode 100644
index 9811757ee2..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 4b8e16de053fc88eac406ad63da2693dd8279043 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Wed, 5 Jul 2023 17:01:07 +0200
-Subject: [PATCH] ARM: dts: broadcom: add missing space before {
-
-Add missing whitespace between node name/label and opening {.
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20230705150108.293999-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-linksys-panamera.dts | 2 +-
- arch/arm/boot/dts/broadcom/bcm47094-phicomm-k3.dts | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -279,7 +279,7 @@
- reg = <0x080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "devinfo";
- reg = <0x0180000 0x080000>;
- };
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -55,7 +55,7 @@
- reg = <0x0080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "phicomm";
- reg = <0x0180000 0x0280000>;
- read-only;
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
deleted file mode 100644
index e5143abf58..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 8960f095de3b80beb3639075f0c8161b6ea98c61 Mon Sep 17 00:00:00 2001
-From: Dan Haab <dan.haab@luxul.com>
-Date: Wed, 5 Jul 2023 09:32:51 -0600
-Subject: [PATCH] ARM: dts: BCM5301X: Add Wi-Fi regulatory mappings for Luxul
- devices
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Dan Haab <dan.haab@luxul.com>
-Link: https://lore.kernel.org/r/20230705153251.739236-1-riproute@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-luxul-xap-1610.dts | 37 +++++++++++++++++++
- .../broadcom/bcm47094-luxul-xwr-3150-v1.dts | 36 ++++++++++++++++++
- 2 files changed, 73 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -64,6 +64,43 @@
- nvmem-cell-names = "mac-address";
- };
-
-+
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -81,6 +81,42 @@
- nvmem-cell-names = "mac-address";
- };
-
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
- &usb3 {
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index 4b2e608ec2..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 2ce61fa62183cf994666fcc911da34075c7183b5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 7 Jul 2023 11:15:19 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar SoCs have 3 usable Ethernet interfaces each connected to one
-of switch ports. They all use fixed links.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230707091519.21673-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -272,14 +272,32 @@
-
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac1: ethernet@25000 {
- reg = <0x25000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac2: ethernet@26000 {
- reg = <0x26000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac3: ethernet@27000 {
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch
deleted file mode 100644
index 8bad76edca..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From be7e1e5b0f67c58ec4be0a54db23b6a4fa6e2116 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 7 Jul 2023 13:40:01 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Drop nonexistent "default-off" LED
- trigger
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There is no such trigger documented or implemented in Linux. It was a
-copy & paste mistake.
-
-This fixes:
-arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dtb: leds: led-wlan:linux,default-trigger: 'oneOf' conditional failed, one must be fixed:
- 'default-off' is not one of ['backlight', 'default-on', 'heartbeat', 'disk-activity', 'disk-read', 'disk-write', 'timer', 'pattern', 'audio-micmute', 'audio-mute', 'bluetooth-power', 'flash', 'kbd-capslock', 'mtd', 'nand-disk', 'none', 'torch', 'usb-gadget', 'usb-host', 'usbport']
- 'default-off' does not match '^cpu[0-9]*$'
- 'default-off' does not match '^hci[0-9]+-power$'
- 'default-off' does not match '^mmc[0-9]+$'
- 'default-off' does not match '^phy[0-9]+tx$'
- From schema: Documentation/devicetree/bindings/leds/leds-gpio.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230707114004.2740-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 1 -
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 2 --
- 2 files changed, 3 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -26,7 +26,6 @@
- led-wlan {
- label = "bcm53xx:blue:wlan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-- linux,default-trigger = "default-off";
- };
-
- led-system {
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -26,7 +26,6 @@
- led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
-- linux,default-trigger = "default-off";
- };
-
- led-system {
-@@ -42,7 +41,6 @@
- led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
-- linux,default-trigger = "default-off";
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
deleted file mode 100644
index 7930c52b16..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 44ad8207806973f4e4f7d870fff36cc01f494250 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 13 Jul 2023 13:11:45 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Fix Ethernet info for Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Both Luxul's XAP devices (XAP-810 and XAP-1440) are access points that
-use a non-default design. They don't include switch but have a single
-Ethernet port and BCM54210E PHY connected to the Ethernet controller's
-MDIO bus.
-
-Support for those devices regressed due to two changes:
-
-1. Describing MDIO bus with switch
-After commit 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125
-rev 4 switch") Linux stopped probing for MDIO devices.
-
-2. Dropping hardcoded BCM54210E delays
-In commit fea7fda7f50a ("net: phy: broadcom: Fix RGMII delays
-configuration for BCM54210E") support for other PHY modes was added but
-that requires a proper "phy-mode" value in DT.
-
-Both above changes are correct (they don't need to be reverted or
-anything) but they need this fix for DT data to be correct and for Linux
-to work properly.
-
-Fixes: 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125 rev 4 switch")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230713111145.14864-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 13 +++++++++++++
- .../boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 13 +++++++++++++
- 2 files changed, 26 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -58,3 +58,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -94,3 +94,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
deleted file mode 100644
index f23873e111..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 72ec77d74d28be7359ef77971cdee38b60af9e49 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Thu, 13 Jul 2023 00:16:42 +0200
-Subject: [PATCH] ARM: dts: bcm5301x: Add SEAMA compatibles
-
-This adds SEAMA compatibles to the firmware partition of these
-two D-Link devices.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230713-seama-partitions-v4-2-69e577453d40@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 1 +
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -33,6 +33,7 @@
- #size-cells = <1>;
-
- partition@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -149,6 +149,7 @@
- * partitions: this device uses SEAMA.
- */
- firmware@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
deleted file mode 100644
index ab27495078..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 8d6b61ecad2f1c939813c5c4517d53e04672dc48 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:15 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Describe BCM53125 switch ports in the
- main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53125 always has 5 ports with GPHYs (for LAN/WAN ports) and 2 IMP
-ports. It seems the best place to describe that in the main .dtsi.
-Device specific bits can go to device .dts files. This will help
-avoiding some code duplication.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-tenda-ac9.dts | 7 -----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 26 ++++++++++++++++++-
- 2 files changed, 25 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -111,34 +111,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan1";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan3";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan4";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -192,10 +192,34 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac0>;
-+ };
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
deleted file mode 100644
index cc9e86ac75..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From d95b1caeea194962220db1778ce7fe71cdba788b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:16 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add BCM53125 switch port 5
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's connected to the extra Ethernet interface.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -216,6 +216,16 @@
- reg = <4>;
- };
-
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac1>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@8 {
- reg = <8>;
- ethernet = <&gmac0>;
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index f97d4edd75..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From e0ae343a2c1b782a346d9b844ea65e1d49c428b2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:12:27 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53573 has 2 Ethernet interfaces each connected to one of switch ports
-in the default design. They both use fixed links.
-
-An exception are Luxul XAP devices that have switch replaced by a single
-PHY.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101227.5420-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 2 ++
- .../arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 2 ++
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 12 ++++++++++++
- 3 files changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -50,6 +50,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -86,6 +86,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -181,6 +181,12 @@
-
- gmac0: ethernet@5000 {
- reg = <0x5000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-
- mdio {
- #address-cells = <1>;
-@@ -237,6 +243,12 @@
-
- gmac1: ethernet@b000 {
- reg = <0xb000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- pmu@12000 {
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
deleted file mode 100644
index e9e347075d..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From d8835601e3c306fda78f8736f1aef688e99e892d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:11:59 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Disable second Ethernet on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-XAP-810 and XAP-1440 both have a single Ethernet port and BCM54210E PHY.
-Their second Ethernet interface is not connected to anything.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101159.5289-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 4 ++++
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 4 ++++
- 2 files changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -73,3 +73,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -109,3 +109,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
deleted file mode 100644
index 47d5b10839..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
+++ /dev/null
@@ -1,431 +0,0 @@
-From 2900083269f7c0f0ff430bffc6ced2038aed9b6b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Thu, 3 Aug 2023 10:14:54 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for ASUS RT-AC3100
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-ASUS RT-AC3100 is ASUS RT-AC88U without the external switch. Move the
-shared bindings to bcm47094-asus-rt-ac3100.dtsi.
-
-Remove the fixed-link node on port@7 as commit ba4aebce23b2 ("ARM: dts:
-BCM5301X: Describe switch ports in the main DTS") states it's not
-necessary.
-
-Replace the copyright notice with an author notice.
-
-Rename the model name from Asus to ASUS on bcm47094-asus-rt-ac88u.dts.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230803071454.5902-2-arinc.unal@arinc9.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../dts/bcm47094-asus-rt-ac3100.dts | 23 +++
- .../dts/bcm47094-asus-rt-ac3100.dtsi | 163 ++++++++++++++++++
- .../dts/bcm47094-asus-rt-ac88u.dts | 155 +----------------
- 4 files changed, 190 insertions(+), 152 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -127,6 +127,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-netgear-r7000.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
-+ bcm47094-asus-rt-ac3100.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
- bcm47094-dlink-dir-890l.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
-@@ -0,0 +1,23 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-+
-+/ {
-+ compatible = "asus,rt-ac3100", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "ASUS RT-AC3100";
-+
-+ nvram@1c080000 {
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-@@ -0,0 +1,163 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ chosen {
-+ bootargs = "earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+ nvram@1c080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1c080000 0x00180000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-power {
-+ label = "white:power";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ led-wan-red {
-+ label = "red:wan";
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-lan {
-+ label = "white:lan";
-+ gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-usb2 {
-+ label = "white:usb2";
-+ gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-usb3 {
-+ label = "white:usb3";
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port1>, <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-wps {
-+ label = "white:wps";
-+ gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-reset {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-wifi {
-+ label = "Wi-Fi";
-+ linux,code = <KEY_RFKILL>;
-+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-led {
-+ label = "Backlight";
-+ linux,code = <KEY_BRIGHTNESS_ZERO>;
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x00000000 0x00080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "nvram";
-+ reg = <0x00080000 0x00180000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x00200000 0x07e00000>;
-+ compatible = "brcm,trx";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -1,102 +1,21 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- /*
-- * Copyright (C) 2021-2022 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
- */
-
- /dts-v1/;
-
--#include "bcm47094.dtsi"
--#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-
- / {
- compatible = "asus,rt-ac88u", "brcm,bcm47094", "brcm,bcm4708";
-- model = "Asus RT-AC88U";
--
-- chosen {
-- bootargs = "earlycon";
-- };
--
-- memory@0 {
-- device_type = "memory";
-- reg = <0x00000000 0x08000000>,
-- <0x88000000 0x18000000>;
-- };
-+ model = "ASUS RT-AC88U";
-
- nvram@1c080000 {
-- compatible = "brcm,nvram";
-- reg = <0x1c080000 0x00180000>;
--
- et1macaddr: et1macaddr {
- };
- };
-
-- leds {
-- compatible = "gpio-leds";
--
-- led-power {
-- label = "white:power";
-- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-- linux,default-trigger = "default-on";
-- };
--
-- led-wan-red {
-- label = "red:wan";
-- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-- };
--
-- led-lan {
-- label = "white:lan";
-- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-- };
--
-- led-usb2 {
-- label = "white:usb2";
-- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port2>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-usb3 {
-- label = "white:usb3";
-- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port1>, <&xhci_port1>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-wps {
-- label = "white:wps";
-- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-- };
-- };
--
-- gpio-keys {
-- compatible = "gpio-keys";
--
-- button-wps {
-- label = "WPS";
-- linux,code = <KEY_WPS_BUTTON>;
-- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-- };
--
-- button-reset {
-- label = "Reset";
-- linux,code = <KEY_RESTART>;
-- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-- };
--
-- button-wifi {
-- label = "Wi-Fi";
-- linux,code = <KEY_RFKILL>;
-- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-- };
--
-- button-led {
-- label = "Backlight";
-- linux,code = <KEY_BRIGHTNESS_ZERO>;
-- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-- };
-- };
--
- switch {
- compatible = "realtek,rtl8365mb";
- /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-@@ -175,31 +94,9 @@
- };
-
- &srab {
-- compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-- status = "okay";
- dsa,member = <0 0>;
-
- ports {
-- port@0 {
-- label = "lan4";
-- };
--
-- port@1 {
-- label = "lan3";
-- };
--
-- port@2 {
-- label = "lan2";
-- };
--
-- port@3 {
-- label = "lan1";
-- };
--
-- port@4 {
-- label = "wan";
-- };
--
- sw0_p5: port@5 {
- /delete-property/ethernet;
-
-@@ -212,19 +109,6 @@
- pause;
- };
- };
--
-- port@7 {
-- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- port@8 {
-- label = "cpu";
-- };
- };
- };
-
-@@ -236,36 +120,3 @@
- nvmem-cells = <&et1macaddr>;
- nvmem-cell-names = "mac-address";
- };
--
--&usb2 {
-- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
--};
--
--&usb3_phy {
-- status = "okay";
--};
--
--&nandcs {
-- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- partition@0 {
-- label = "boot";
-- reg = <0x00000000 0x00080000>;
-- read-only;
-- };
--
-- partition@80000 {
-- label = "nvram";
-- reg = <0x00080000 0x00180000>;
-- };
--
-- partition@200000 {
-- label = "firmware";
-- reg = <0x00200000 0x07e00000>;
-- compatible = "brcm,trx";
-- };
-- };
--};
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
deleted file mode 100644
index 78b8975f1f..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 5cbee5828219c4f7b33e96b5d8ce5e467b2857c8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 12:55:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MACs for D-Link DIR-885L
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et2macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901105549.7076-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-dlink-dir-885l.dts | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -25,6 +25,15 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1e3f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e3f0000 0x10000>;
-+
-+ et2macaddr: et2macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -112,6 +121,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et2macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -142,6 +156,8 @@
-
- port@4 {
- label = "wan";
-+ nvmem-cells = <&et2macaddr 3>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
deleted file mode 100644
index 11ce7acb53..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From a9e79863b62aaaefcdf469fc331bf482ae00db0d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 14:43:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MAC address for Asus RT-AC87U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et1macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901124311.31156-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -25,6 +25,12 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1c080000 {
-+ et1macaddr: et1macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -62,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et1macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb3_phy {
- status = "okay";
- };
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 6df1e555e9..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 81ea360a16978a4df61df9db56b171909bd659c0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:30:57 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Felix's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Felix to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 1ff80363524c ("ARM: BCM5301X: Add
-profiling support").
-
-Cc: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Felix Fietkau <nbd@nbd.name>
-Link: https://lore.kernel.org/r/20230916083057.10458-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 7 +++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 7 -------
- 2 files changed, 7 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -14,6 +14,13 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ pmu {
-+ compatible = "arm,cortex-a9-pmu";
-+ interrupts =
-+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
- chipcommon-a-bus@18000000 {
- compatible = "simple-bus";
- ranges = <0x00000000 0x18000000 0x00001000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -26,13 +26,6 @@
- };
- };
-
-- pmu {
-- compatible = "arm,cortex-a9-pmu";
-- interrupts =
-- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-- };
--
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 66db4a291f..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From b8d4f7c1be04d66c37c119c501c87bccc4197694 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:58:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Vivek's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Vivek to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 37f6130ec39f ("ARM: dts: BCM5301X:
-Make USB 3.0 PHY use MDIO PHY driver").
-
-Cc: Vivek Unune <npcomplete13@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Vivek Unune <npcomplete13@gmail.com>
-Link: https://lore.kernel.org/r/20230916085855.28375-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 27 ++++++++++++++++++++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 27 ------------------------
- 2 files changed, 27 insertions(+), 27 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -327,6 +327,29 @@
- #address-cells = <1>;
- };
-
-+ mdio-mux@18003000 {
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
-+ mdio-parent-bus = <&mdio>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x18003000 0x4>;
-+ mux-mask = <0x200>;
-+
-+ mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ usb3_phy: usb3-phy@10 {
-+ compatible = "brcm,ns-ax-usb3-phy";
-+ reg = <0x10>;
-+ usb3-dmp-syscon = <&usb3_dmp>;
-+ #phy-cells = <0>;
-+ status = "disabled";
-+ };
-+ };
-+ };
-+
- rng: rng@18004000 {
- compatible = "brcm,bcm5301x-rng";
- reg = <0x18004000 0x14>;
-@@ -467,6 +490,10 @@
- brcm,nand-has-wp;
- };
-
-+ usb3_dmp: syscon@18105000 {
-+ reg = <0x18105000 0x1000>;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -62,33 +62,6 @@
- };
- };
-
-- mdio-mux@18003000 {
-- compatible = "mdio-mux-mmioreg", "mdio-mux";
-- mdio-parent-bus = <&mdio>;
-- #address-cells = <1>;
-- #size-cells = <0>;
-- reg = <0x18003000 0x4>;
-- mux-mask = <0x200>;
--
-- mdio@0 {
-- reg = <0x0>;
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- usb3_phy: usb3-phy@10 {
-- compatible = "brcm,ns-ax-usb3-phy";
-- reg = <0x10>;
-- usb3-dmp-syscon = <&usb3_dmp>;
-- #phy-cells = <0>;
-- status = "disabled";
-- };
-- };
-- };
--
-- usb3_dmp: syscon@18105000 {
-- reg = <0x18105000 0x1000>;
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
deleted file mode 100644
index 72e5c6b061..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
+++ /dev/null
@@ -1,377 +0,0 @@
-From 473baeab929444295b0530f8766e4becb6a08973 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:13 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Explicitly disable unused switch CPU
- ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When redescribing ports I assumed that missing "label" (like "cpu")
-means switch port isn't used. That was incorrect and I realized my
-change made Linux always use the first (5) CPU port (there are 3 of
-them).
-
-While above should technically be possible it often isn't correct:
-1. Non-default switch ports are often connected to Ethernet interfaces
- not fully covered by vendor setup (they may miss MACs)
-2. On some devices non-default ports require specifying fixed link
-
-This fixes network connectivity for some devices. It was reported &
-tested for Netgear R8000. It also affects Linksys EA9200 with its
-downstream DTS.
-
-Fixes: ba4aebce23b2 ("ARM: dts: BCM5301X: Describe switch ports in the main DTS")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts | 8 ++++++++
- .../boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm953012er.dts | 8 ++++++++
- 20 files changed, 160 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -181,5 +181,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -85,5 +85,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -88,5 +88,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -122,5 +122,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -145,6 +145,14 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -145,5 +145,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -81,5 +81,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -148,5 +148,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -227,6 +227,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -160,6 +160,14 @@
- nvmem-cell-names = "mac-address";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -192,6 +192,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- phy-mode = "rgmii";
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -120,5 +120,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -75,5 +75,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -147,5 +147,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -158,5 +158,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -124,6 +124,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -185,6 +185,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -84,6 +84,14 @@
- label = "cpu";
- ethernet = <&gmac0>;
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
deleted file mode 100644
index 0b2b7b36a3..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From d313b0e9070a7100ca55e64fe3b081d176d8806d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:14 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set fixed-link for extra Netgear R8000
- CPU ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Ports 5 and 7 are disabled by default because the standard use case is
-for port 8 to manage all CPU directed traffic. For experimentation
-purposes however it is desirable to provide adequate properties such
-that people can experiment with using different ports without having to
-figure out their configuration. Some of the use cases include but are
-not limited to doubling or tripling the bandwidth by leveraging the
-additional ports/Ethernet MAC combinations.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -229,10 +229,20 @@
-
- port@5 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@7 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
deleted file mode 100644
index 4528c95a5a..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 253358f373492608348136e569366d73cb969f6a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 24 Oct 2023 09:26:05 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set switch ports for Linksys EA9200
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch was developed as OpenWrt downstream change and was recently
-confirmed to work as expected.
-
-Tested-by: Rani Hod <rani.hod@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231024072605.32517-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4709-linksys-ea9200.dts | 38 +++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -47,3 +47,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch b/target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch
deleted file mode 100644
index 5ebc78ca20..0000000000
--- a/target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From b9457a04eb89645049fdf427c13e6a18d5501895 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Tue, 11 Oct 2022 14:24:40 +0200
-Subject: [PATCH] bcma: support SPROM rev 11
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Rev 11 works fine for me to set the MAC address of gmac0 and
-gmac1 in the D-Link DWL-8610AP.
-
-Cc: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/bcma/sprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/bcma/sprom.c
-+++ b/drivers/bcma/sprom.c
-@@ -170,7 +170,7 @@ static int bcma_sprom_valid(struct bcma_
- return err;
-
- revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
-- if (revision != 8 && revision != 9 && revision != 10) {
-+ if (revision < 8 || revision > 11) {
- pr_err("Unsupported SPROM revision: %d\n", revision);
- return -ENOENT;
- }
diff --git a/target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch b/target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
deleted file mode 100644
index e1933e75c7..0000000000
--- a/target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 13 Apr 2021 18:25:20 +0200
-Subject: [PATCH] mtd: parsers: trx: parse "firmware" MTD partitions only
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Parsing every partition with "compatible" set to "brcm,trx" results in
-parsing both: firmware partition and failsafe partition on devices that
-implement failsafe booting. This affects e.g. Linksys EA9500 which has:
-
-partition@200000 {
- reg = <0x0200000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-partition@1f00000 {
- reg = <0x01f00000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-Check for MTD partition name "firmware" before parsing. Recently added
-ofpart_linksys_ns.c creates "firmware" and "failsafe" depending on
-bootloader setup.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/mtd/parsers/parser_trx.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/parsers/parser_trx.c
-+++ b/drivers/mtd/parsers/parser_trx.c
-@@ -92,6 +92,10 @@ static int parser_trx_parse(struct mtd_i
- if (err != 0 && err != -EINVAL)
- pr_err("failed to parse \"brcm,trx-magic\" DT attribute, using default: %d\n", err);
-
-+ /* Don't parse any failsafe / backup partitions */
-+ if (strcmp(mtd->name, "firmware"))
-+ return -EINVAL;
-+
- parts = kcalloc(TRX_PARSER_MAX_PARTS, sizeof(struct mtd_partition),
- GFP_KERNEL);
- if (!parts)
diff --git a/target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch b/target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
deleted file mode 100644
index ac5a48283d..0000000000
--- a/target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 1 Oct 2016 22:54:48 +0200
-Subject: [PATCH] usb: xhci: add support for performing fake doorbell
-
-Broadcom's Northstar XHCI controllers seem to need a special start
-procedure to work correctly. There isn't any official documentation of
-this, the problem is that controller doesn't detect any connected
-devices with default setup. Moreover connecting USB device to controller
-that doesn't run properly can cause SoC's watchdog issues.
-
-A workaround that was successfully tested on multiple devices is to
-perform a fake doorbell. This patch adds code for doing this and enables
-it on BCM4708 family.
----
- drivers/usb/host/xhci-plat.c | 6 +++++
- drivers/usb/host/xhci.c | 63 +++++++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h | 1 +
- 3 files changed, 67 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci-plat.c
-+++ b/drivers/usb/host/xhci-plat.c
-@@ -77,6 +77,8 @@ static int xhci_priv_resume_quirk(struct
- static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
- {
- struct xhci_plat_priv *priv = xhci_to_priv(xhci);
-+ struct platform_device*pdev = to_platform_device(dev);
-+ struct device_node *node = pdev->dev.of_node;
-
- /*
- * As of now platform drivers don't provide MSI support so we ensure
-@@ -84,6 +86,9 @@ static void xhci_plat_quirks(struct devi
- * dev struct in order to setup MSI
- */
- xhci->quirks |= XHCI_PLAT | priv->quirks;
-+
-+ if (node && of_machine_is_compatible("brcm,bcm4708"))
-+ xhci->quirks |= XHCI_FAKE_DOORBELL;
- }
-
- /* called during probe() after chip reset completes */
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -161,6 +161,49 @@ int xhci_start(struct xhci_hcd *xhci)
- return ret;
- }
-
-+/**
-+ * xhci_fake_doorbell - Perform a fake doorbell on a specified slot
-+ *
-+ * Some controllers require a fake doorbell to start correctly. Without that
-+ * they simply don't detect any devices.
-+ */
-+static int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
-+{
-+ u32 temp;
-+
-+ /* Alloc a virt device for that slot */
-+ if (!xhci_alloc_virt_device(xhci, slot_id, NULL, GFP_NOIO)) {
-+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Ring fake doorbell for slot_id ep 0 */
-+ xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
-+ usleep_range(1000, 1500);
-+
-+ /* Read the status to check if HSE is set or not */
-+ temp = readl(&xhci->op_regs->status);
-+
-+ /* Clear HSE if set */
-+ if (temp & STS_FATAL) {
-+ xhci_dbg(xhci, "HSE problem detected, status: 0x%08x\n", temp);
-+ temp &= ~0x1fff;
-+ temp |= STS_FATAL;
-+ writel(temp, &xhci->op_regs->status);
-+ usleep_range(1000, 1500);
-+ readl(&xhci->op_regs->status);
-+ }
-+
-+ /* Free virt device */
-+ xhci_free_virt_device(xhci, slot_id);
-+
-+ /* We're done if controller is already running */
-+ if (readl(&xhci->op_regs->command) & CMD_RUN)
-+ return 0;
-+
-+ return xhci_start(xhci);
-+}
-+
- /*
- * Reset a halted HC.
- *
-@@ -641,6 +684,15 @@ static int xhci_run_finished(struct xhci
- return -ENODEV;
- }
-
-+ if (xhci->quirks & XHCI_FAKE_DOORBELL) {
-+ int err = xhci_fake_doorbell(xhci, 1);
-+ if (err) {
-+ xhci_halt(xhci);
-+ spin_unlock_irqrestore(&xhci->lock, flags);
-+ return err;
-+ }
-+ }
-+
- xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
-
- if (xhci->quirks & XHCI_NEC_HOST)
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1908,6 +1908,7 @@ struct xhci_hcd {
- #define XHCI_RESET_TO_DEFAULT BIT_ULL(44)
- #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
- #define XHCI_ZHAOXIN_HOST BIT_ULL(46)
-+#define XHCI_FAKE_DOORBELL BIT_ULL(47)
-
- unsigned int num_active_eps;
- unsigned int limit_active_eps;
diff --git a/target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch b/target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
deleted file mode 100644
index 034d5b52fc..0000000000
--- a/target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 24 Sep 2014 22:14:07 +0200
-Subject: [PATCH] ARM: BCM5301X: Disable MMU and Dcache during decompression
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom devices have broken CFE (bootloader) that leaves hardware in an
-invalid state. It causes problems with booting Linux. On Northstar
-devices kernel was randomly hanging in ~25% of tries during early init.
-Hangs used to happen at random places in the start_kernel. On BCM53573
-kernel doesn't even seem to start booting.
-
-To workaround this problem we need to do following very early:
-1) Clear 2 following bits in the SCTLR register:
-#define CR_M (1 << 0) /* MMU enable */
-#define CR_C (1 << 2) /* Dcache enable */
-2) Flush the whole D-cache
-3) Disable L2 cache
-
-Unfortunately this patch is not upstreamable as it does above things
-unconditionally. We can't check if we are running on Broadcom platform
-in any safe way and doing such hacks with ARCH_MULTI_V7 is unacceptable
-as it could break other devices support.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/compressed/Makefile
-+++ b/arch/arm/boot/compressed/Makefile
-@@ -35,6 +35,11 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
- OBJS += ll_char_wr.o font.o
- endif
-
-+ifeq ($(CONFIG_ARCH_BCM_5301X),y)
-+OBJS += head-bcm_5301x-mpcore.o
-+OBJS += cache-v7-min.o
-+endif
-+
- ifeq ($(CONFIG_ARCH_SA1100),y)
- OBJS += head-sa1100.o
- endif
---- /dev/null
-+++ b/arch/arm/boot/compressed/head-bcm_5301x-mpcore.S
-@@ -0,0 +1,37 @@
-+/*
-+ *
-+ * Platform specific tweaks. This is merged into head.S by the linker.
-+ *
-+ */
-+
-+#include <linux/linkage.h>
-+#include <asm/assembler.h>
-+#include <asm/cp15.h>
-+
-+ .section ".start", "ax"
-+
-+/*
-+ * This code section is spliced into the head code by the linker
-+ */
-+
-+__plat_uncompress_start:
-+
-+ @ Preserve r8/r7 i.e. kernel entry values
-+ mov r12, r8
-+
-+ @ Clear MMU enable and Dcache enable bits
-+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
-+ bic r0, #CR_C|CR_M
-+ mcr p15, 0, r0, c1, c0, 0 @ Write SCTLR
-+ nop
-+
-+ @ Call the cache invalidation routine
-+ bl v7_flush_dcache_all
-+ nop
-+ mov r0,#0
-+ ldr r3, =0x19022000 @ L2 cache controller, control reg
-+ str r0, [r3, #0x100] @ Disable L2 cache
-+ nop
-+
-+ @ Restore
-+ mov r8, r12
---- a/arch/arm/boot/compressed/cache-v7-min.S
-+++ b/arch/arm/boot/compressed/cache-v7-min.S
-@@ -12,6 +12,7 @@
-
- #include <linux/linkage.h>
- #include <linux/init.h>
-+#include <asm/assembler.h>
-
- __INIT
-
-@@ -63,7 +64,7 @@ loop2:
- ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
- THUMB( lsl r6, r9, r2 )
- THUMB( orr r11, r11, r6 ) @ factor index number into r11
-- mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
-+ mcr p15, 0, r11, c7, c6, 2 @ clean & invalidate by set/way
- subs r9, r9, #1 @ decrement the index
- bge loop2
- subs r4, r4, #1 @ decrement the way
diff --git a/target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch b/target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
deleted file mode 100644
index 8039831a78..0000000000
--- a/target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
+++ /dev/null
@@ -1,675 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] ARM: dts: BCM5301X: Specify switch ports for remaining
- devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -92,3 +92,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -83,3 +83,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -149,3 +149,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-@@ -46,3 +46,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-@@ -43,3 +43,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -86,3 +86,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -77,3 +77,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -77,6 +77,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -130,3 +130,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -104,3 +104,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -94,3 +94,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -38,6 +38,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -91,6 +91,44 @@
- };
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -100,6 +100,44 @@
- vcc-gpio = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -107,3 +107,42 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
diff --git a/target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch b/target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
deleted file mode 100644
index 773c3e9be6..0000000000
--- a/target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: [PATCH] ARM: BCM5301X: Add DT for Netgear R7900
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -125,6 +125,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-buffalo-wxr-1900dhp.dtb \
- bcm4709-linksys-ea9200.dtb \
- bcm4709-netgear-r7000.dtb \
-+ bcm4709-netgear-r7900.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac3100.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7900.dts
-@@ -0,0 +1,42 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * DTS for Netgear R7900
-+ *
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ compatible = "netgear,r7900", "brcm,bcm4709", "brcm,bcm4708";
-+ model = "Netgear R7900";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory {
-+ reg = <0x00000000 0x08000000
-+ 0x88000000 0x08000000>;
-+ };
-+
-+ axi@18000000 {
-+ usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch b/target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
deleted file mode 100644
index e6140d9a70..0000000000
--- a/target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 2a2af518266a29323cf30c3f9ba9ef2ceb1dd84b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 16 Oct 2014 20:52:16 +0200
-Subject: [PATCH] UBI: Detect EOF mark and erase all remaining blocks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/ubi/attach.c | 5 +++++
- drivers/mtd/ubi/io.c | 4 ++++
- drivers/mtd/ubi/ubi.h | 1 +
- 3 files changed, 10 insertions(+)
-
---- a/drivers/mtd/ubi/attach.c
-+++ b/drivers/mtd/ubi/attach.c
-@@ -82,6 +82,9 @@ static int self_check_ai(struct ubi_devi
- #define AV_ADD BIT(1)
- #define AV_FIND_OR_ADD (AV_FIND | AV_ADD)
-
-+/* Set on finding block with 0xdeadc0de, indicates erasing all blocks behind */
-+bool erase_all_next;
-+
- /**
- * find_or_add_av - internal function to find a volume, add a volume or do
- * both (find and add if missing).
-@@ -1580,6 +1583,8 @@ int ubi_attach(struct ubi_device *ubi, i
- if (!ai)
- return -ENOMEM;
-
-+ erase_all_next = false;
-+
- #ifdef CONFIG_MTD_UBI_FASTMAP
- /* On small flash devices we disable fastmap in any case. */
- if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
---- a/drivers/mtd/ubi/io.c
-+++ b/drivers/mtd/ubi/io.c
-@@ -717,6 +717,10 @@ int ubi_io_read_ec_hdr(struct ubi_device
- }
-
- magic = be32_to_cpu(ec_hdr->magic);
-+ if (magic == 0xdeadc0de)
-+ erase_all_next = true;
-+ if (erase_all_next)
-+ return read_err ? UBI_IO_FF_BITFLIPS : UBI_IO_FF;
- if (magic != UBI_EC_HDR_MAGIC) {
- if (mtd_is_eccerr(read_err))
- return UBI_IO_BAD_HDR_EBADMSG;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -822,6 +822,7 @@ extern struct mutex ubi_devices_mutex;
- extern struct blocking_notifier_head ubi_notifiers;
-
- /* attach.c */
-+extern bool erase_all_next;
- struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
- int ec);
- void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb);
diff --git a/target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch b/target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch
deleted file mode 100644
index 9fa41a4b7e..0000000000
--- a/target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 20 Jun 2022 10:01:18 +0200
-Subject: [PATCH] net: disable GRO by default
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In many cases GRO improves network performance however it comes at a
-cost of chacksums calculations. In case of slow CPU and missing hardware
-csum calculation support GRO can actually decrease network speed.
-
-On BCM4708 *disabling* GRO results in following NAT masquarade speed
-changes:
-1. 364 Mb/s → 396 Mb/s (packet steering disabled)
-2. 341 Mb/s → 566 Mb/s (packet steering enabled)
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- include/linux/netdev_features.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdev_features.h
-+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
- #define NETIF_F_UPPER_DISABLES NETIF_F_LRO
-
- /* changeable features with no special hardware requirements */
--#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST)
-+#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO)
-
- /* Changeable features with no special hardware requirements that defaults to off. */
--#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD)
-+#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST)
-
- #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
- NETIF_F_HW_VLAN_CTAG_RX | \
diff --git a/target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch b/target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
deleted file mode 100644
index 3a2f4b06ed..0000000000
--- a/target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 10 Jun 2022 13:10:47 +0200
-Subject: [PATCH] bgmac: reduce max frame size to support just MTU 1500
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-bgmac allocates new replacement buffer before handling each received
-frame. Allocating & DMA-preparing 9724 B each time consumes a lot of CPU
-time. Ideally bgmac should just respect currently set MTU but it isn't
-the case right now. For now just revert back to the old limited frame
-size.
-
-This change bumps NAT masquarade speed by ~95%.
-
-Ref: 8c7da63978f1 ("bgmac: configure MTU and add support for frames beyond 8192 byte size")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/ethernet/broadcom/bgmac.h | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -328,8 +328,7 @@
- #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
- #define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \
- BGMAC_RX_FRAME_OFFSET)
--/* Jumbo frame size with FCS */
--#define BGMAC_RX_MAX_FRAME_SIZE 9724
-+#define BGMAC_RX_MAX_FRAME_SIZE 1536
- #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
- #define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
diff --git a/target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch b/target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch
deleted file mode 100644
index 0a52ca98ee..0000000000
--- a/target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 6f1c62440eb6846cb8045d7a5480ec7bbe47c96f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Aug 2016 10:30:41 +0200
-Subject: [PATCH] BCM53573 minor hacks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -54,6 +54,7 @@
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&ilp>;
- };
-
- clocks {
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -330,14 +330,6 @@ static int bcma_register_devices(struct
- }
- #endif
-
--#ifdef CONFIG_BCMA_SFLASH
-- if (bus->drv_cc.sflash.present) {
-- err = platform_device_register(&bcma_sflash_dev);
-- if (err)
-- bcma_err(bus, "Error registering serial flash\n");
-- }
--#endif
--
- #ifdef CONFIG_BCMA_NFLASH
- if (bus->drv_cc.nflash.present) {
- err = platform_device_register(&bcma_nflash_dev);
-@@ -415,6 +407,14 @@ int bcma_bus_register(struct bcma_bus *b
- bcma_register_core(bus, core);
- }
-
-+#ifdef CONFIG_BCMA_SFLASH
-+ if (bus->drv_cc.sflash.present) {
-+ err = platform_device_register(&bcma_sflash_dev);
-+ if (err)
-+ bcma_err(bus, "Error registering serial flash\n");
-+ }
-+#endif
-+
- /* Try to get SPROM */
- err = bcma_sprom_get(bus);
- if (err == -ENOENT) {
---- a/drivers/clocksource/arm_arch_timer.c
-+++ b/drivers/clocksource/arm_arch_timer.c
-@@ -14,6 +14,7 @@
- #include <linux/smp.h>
- #include <linux/cpu.h>
- #include <linux/cpu_pm.h>
-+#include <linux/clk.h>
- #include <linux/clockchips.h>
- #include <linux/clocksource.h>
- #include <linux/clocksource_ids.h>
-@@ -1029,6 +1030,16 @@ static void __init arch_timer_of_configu
- if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
- arch_timer_rate = rate;
-
-+ /* Get clk rate through clk driver if present */
-+ if (!arch_timer_rate) {
-+ struct clk *clk = of_clk_get(np, 0);
-+
-+ if (!IS_ERR(clk)) {
-+ if (!clk_prepare_enable(clk))
-+ arch_timer_rate = clk_get_rate(clk);
-+ }
-+ }
-+
- /* Check the timer frequency. */
- if (validate_timer_rate())
- pr_warn("frequency not available\n");
diff --git a/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch b/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch
index 9fa41a4b7e..fd41824383 100644
--- a/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch
+++ b/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch
@@ -21,7 +21,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
+@@ -243,10 +243,10 @@ static inline int find_next_netdev_featu
#define NETIF_F_UPPER_DISABLES NETIF_F_LRO
/* changeable features with no special hardware requirements */
diff --git a/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds b/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds
index 98355460a0..059a4f415a 100644
--- a/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds
+++ b/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds
@@ -6,7 +6,8 @@
board_config_update
case "$(board_name)" in
-comtrend,ar-5315u)
+comtrend,ar-5315u |\
+tp-link,td-w8968-v3)
ucidef_set_led_usbport "usb" "USB" "green:usb" "usb1-port1" "usb2-port1"
;;
esac
diff --git a/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network
index 92b2e8f4d4..b821f6a545 100644
--- a/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network
+++ b/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network
@@ -5,7 +5,8 @@
board_config_update
case "$(board_name)" in
-comtrend,ar-5315u)
+comtrend,ar-5315u |\
+tp-link,td-w8968-v3)
ucidef_set_bridge_device switch
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
diff --git a/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc b/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc
index a52f0ecc40..df09e1d249 100644
--- a/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc
+++ b/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc
@@ -3,7 +3,8 @@
. /lib/functions.sh
case "$(board_name)" in
-comtrend,ar-5315u)
+comtrend,ar-5315u) |\
+tp-link,td-w8968-v3)
mtd fixtrx firmware
;;
esac
diff --git a/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds b/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds
index b2ccc9a60e..3b9033a4d4 100644
--- a/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds
+++ b/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds
@@ -10,6 +10,7 @@ arcadyan,ar7516)
ucidef_set_led_netdev "wan" "WAN" "green:wan" "wan"
ucidef_set_led_netdev "wlan0" "WiFi" "green:wifi" "phy0-ap0"
;;
+inteno,xg6846 |\
nucom,r5010unv2 |\
sercomm,ad1018)
ucidef_set_led_usbport "usb" "USB" "green:usb" "usb1-port1" "usb2-port1"
diff --git a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network
index 78c0794f23..e846182a9a 100644
--- a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network
+++ b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network
@@ -14,6 +14,7 @@ inteno,xg6846)
;;
comtrend,ar-5381u |\
comtrend,ar-5387un |\
+dlink,dsl-2750b-b1 |\
innacomm,w3400v6 |\
nucom,r5010unv2)
ucidef_set_bridge_device switch
diff --git a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc
index e521af36ba..e442fa662c 100644
--- a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc
+++ b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc
@@ -6,6 +6,7 @@ case "$(board_name)" in
arcadyan,ar7516 |\
comtrend,ar-5381u |\
comtrend,ar-5387un |\
+dlink,dsl-2750b-b1 |\
nucom,r5010unv2)
mtd fixtrx firmware
;;
diff --git a/target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts b/target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts
new file mode 100644
index 0000000000..59b209daed
--- /dev/null
+++ b/target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "bcm6318.dtsi"
+
+/ {
+ model = "TP-Link TD-W8968 V3";
+ compatible = "tp-link,td-w8968-v3", "brcm,bcm6318";
+
+ aliases {
+ led-boot = &led_power_green;
+ led-failsafe = &led_power_green;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_green;
+ };
+
+ keys {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+
+ wlan {
+ label = "wlan";
+ gpios = <&gpio 9 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WLAN>;
+ debounce-interval = <60>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ debounce-interval = <60>;
+ };
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 34 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+ };
+
+ bcm43217-sprom {
+ compatible = "brcm,bcma-sprom";
+
+ pci-bus = <1>;
+ pci-dev = <0>;
+
+ nvmem-cells = <&macaddr_cfe_6a0 1>;
+ nvmem-cell-names = "mac-address";
+
+ brcm,sprom = "brcm/bcm43217-sprom.bin";
+ };
+};
+
+&ehci {
+ status = "okay";
+};
+
+&ethernet {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_cfe_6a0 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&hsspi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <62500000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x000000 0x010000>;
+ label = "cfe";
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_cfe_6a0: macaddr@6a0 {
+ compatible = "mac-base";
+ reg = <0x6a0 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@10000 {
+ compatible = "brcm,bcm963xx-imagetag";
+ reg = <0x010000 0x7e0000>;
+ label = "firmware";
+ };
+
+ partition@7f0000 {
+ reg = <0x7f0000 0x010000>;
+ label = "nvram";
+ };
+ };
+ };
+};
+
+&leds {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds
+ &pinctrl_ephy0_act_led &pinctrl_ephy1_act_led
+ &pinctrl_ephy2_act_led &pinctrl_ephy3_act_led>;
+
+ led@2 {
+ reg = <2>;
+ active-low;
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led_power_green: led@3 {
+ reg = <3>;
+ active-high;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@4 {
+ /* EPHY0 Act */
+ reg = <4>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <4>;
+ };
+
+ led@5 {
+ /* EPHY1 Act */
+ reg = <5>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <5>;
+ };
+
+ led@6 {
+ /* EPHY2 Act */
+ reg = <6>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <6>;
+ };
+
+ led@7 {
+ /* EPHY3 Act */
+ reg = <7>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <7>;
+ };
+
+ led@8 {
+ reg = <8>;
+ active-low;
+ function = LED_FUNCTION_WAN_ONLINE;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@10 {
+ reg = <10>;
+ active-low;
+ label = "green:dsl";
+ };
+
+ led@13 {
+ reg = <13>;
+ active-low;
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@16 {
+ reg = <16>;
+ active-low;
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+};
+
+&ohci {
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl_leds: leds {
+ function = "led";
+ pins = "gpio2", "gpio3",
+ "gpio8", "gpio10",
+ "gpio13", "gpio16";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ reg = <0>;
+ label = "lan4";
+
+ phy-handle = <&phy1>;
+ phy-mode = "mii";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan3";
+
+ phy-handle = <&phy2>;
+ phy-mode = "mii";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+
+ phy-handle = <&phy3>;
+ phy-mode = "mii";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan1";
+
+ phy-handle = <&phy4>;
+ phy-mode = "mii";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usbh {
+ status = "okay";
+};
diff --git a/target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts b/target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts
new file mode 100644
index 0000000000..e4806c0a9a
--- /dev/null
+++ b/target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts
@@ -0,0 +1,273 @@
+#include "bcm6328.dtsi"
+
+/ {
+ model = "D-Link DSL-2750B rev B1/DSL-2740B rev F1/DSL-2741B rev F1";
+ compatible = "dlink,dsl-2750b-b1", "brcm,bcm6328";
+
+ aliases {
+ led-boot = &led_power_green;
+ led-failsafe = &led_power_red;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_green;
+ };
+
+ keys {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+
+ wifi {
+ label = "wifi";
+ gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WLAN>;
+ debounce-interval = <60>;
+ };
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-31 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+ trigger-sources = <&ehci_port1>;
+ linux,default-trigger = "usbport";
+ };
+ };
+
+ ath9k-leds {
+ compatible = "gpio-leds";
+
+ led-8 {
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&ath9k 8 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "phy0tpt";
+ };
+ };
+};
+
+&leds {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds>;
+
+ led@2 {
+ reg = <2>;
+ active-low;
+ label = "red:internet";
+ };
+
+ led@3 {
+ reg = <3>;
+ active-low;
+ label = "green:dsl";
+ };
+
+ led_power_green: led@4 {
+ reg = <4>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led_power_red: led@8 {
+ reg = <8>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_RED>;
+ panic-indicator;
+ };
+
+ led@9 {
+ reg = <9>;
+ active-low;
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+
+ led@11 {
+ reg = <11>;
+ active-low;
+ label = "green:internet";
+ };
+};
+
+&ehci {
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ehci_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+};
+
+&ethernet {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_cfe_6a0 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&hsspi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <16666667>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x000000 0x010000>;
+ label = "cfe";
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_cfe_6a0: macaddr@6a0 {
+ compatible = "mac-base";
+ reg = <0x6a0 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@10000 {
+ reg = <0x010000 0x7c0000>;
+ label = "linux";
+ compatible = "brcm,bcm963xx-imagetag";
+ };
+
+ partition@7d0000 {
+ reg = <0x7d0000 0x010000>;
+ label = "cal_data";
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_data_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+ };
+ };
+
+ partition@7e0000 {
+ reg = <0x7e0000 0x020000>;
+ label = "nvram";
+ };
+ };
+ };
+};
+
+&ohci {
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+
+ ath9k: wifi@168c,002e {
+ compatible = "pci168c,002e";
+ reg = <0 0 0 0 0>;
+
+ nvmem-cells = <&macaddr_cfe_6a0 1>, <&cal_data_1000>;
+ nvmem-cell-names = "mac-address", "calibration";
+
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+ };
+};
+
+&pinctrl {
+ pinctrl_leds: leds {
+ function = "led";
+ pins = "gpio2", "gpio3", "gpio4",
+ "gpio8", "gpio9", "gpio11";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+
+ phy-handle = <&phy1>;
+ phy-mode = "mii";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+
+ phy-handle = <&phy2>;
+ phy-mode = "mii";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+
+ phy-handle = <&phy3>;
+ phy-mode = "mii";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+
+ phy-handle = <&phy4>;
+ phy-mode = "mii";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usbh {
+ status = "okay";
+};
diff --git a/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts b/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
index 72f85a53ca..91b771a2bd 100644
--- a/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
+++ b/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-/dts-v1/;
/*
* Devicetree for the Inteno XG6846 router, mostly used as a
@@ -16,26 +15,18 @@
* Some devices have a USB type A host receptacle mounted,
* some do not.
*/
+
#include "bcm6328.dtsi"
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/gpio/gpio.h>
/ {
model = "Inteno XG6846";
compatible = "inteno,xg6846", "brcm,bcm6328";
- /* OpenWrt-specific aliases */
aliases {
- led-boot = &led_pwr_red;
- led-failsafe = &led_pwr_red;
- led-running = &led_pwr_green;
- led-upgrade = &led_pwr_red;
- led-usb = &led_usb_green;
- };
-
- chosen {
- bootargs = "rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200";
- stdout-path = "serial0:115200n8";
+ led-boot = &led_power_red;
+ led-failsafe = &led_power_red;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_red;
};
/*
@@ -49,6 +40,12 @@
scl-gpios = <&gpio 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
#address-cells = <1>;
#size-cells = <0>;
+
+ sfp_eeprom: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ read-only;
+ };
};
/* This I2C bus is used for the external CATV connector (usually unused) */
@@ -60,17 +57,9 @@
#size-cells = <0>;
};
- sfp0: sfp0 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpios = <&gpio 29 GPIO_ACTIVE_HIGH>;
- };
-
keys {
compatible = "gpio-keys-polled";
- #address-cells = <1>;
- #size-cells = <0>;
- poll-interval = <20>;
+ poll-interval = <100>;
reset {
label = "reset";
@@ -79,6 +68,12 @@
debounce-interval = <60>;
};
};
+
+ sfp0: sfp0 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpios = <&gpio 29 GPIO_ACTIVE_HIGH>;
+ };
};
&hsspi {
@@ -110,10 +105,20 @@
#address-cells = <1>;
#size-cells = <1>;
- cfe: partition@0 {
+ partition@0 {
label = "cfe";
reg = <0x0000000 0x0010000>;
read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_cfe_6a0: macaddr@6a0 {
+ reg = <0x6a0 0x6>;
+ };
+ };
};
partition@10000 {
@@ -131,14 +136,8 @@
};
};
-&cfe {
- compatible = "nvmem-cells";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_cfe_6a0: macaddr@6a0 {
- reg = <0x6a0 0x6>;
- };
+&ehci {
+ status = "okay";
};
&ethernet {
@@ -148,20 +147,33 @@
nvmem-cell-names = "mac-address";
};
-&switch0 {
- dsa,member = <0 0>;
+&leds {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds>,
+ <&pinctrl_ephy1_spd_led>,
+ <&pinctrl_ephy3_spd_led>;
- ports {
- switch0port4: port@4 {
- reg = <4>;
- label = "extsw";
+ led@16 {
+ reg = <16>;
+ active-low;
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_GREEN>;
+ };
- phy-mode = "rgmii";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
+ led_power_red: led@18 {
+ reg = <18>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_RED>;
+ panic-indicator;
+ };
+
+ led_power_green: led@20 {
+ reg = <20>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
};
};
@@ -172,8 +184,10 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
+
interrupt-controller;
#interrupt-cells = <2>;
+
dsa,member = <1 0>;
ports {
@@ -183,49 +197,165 @@
port@0 {
reg = <0>;
label = "lan1";
+
phy-handle = <&lan1phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@1 {
reg = <1>;
label = "lan2";
+
phy-handle = <&lan2phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@2 {
reg = <2>;
label = "lan3";
+
phy-handle = <&lan3phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@3 {
reg = <3>;
label = "lan4";
+
phy-handle = <&lan4phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@4 {
reg = <4>;
label = "ext1";
+
phy-handle = <&ext1phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_WAN;
+ };
+ };
};
port@5 {
reg = <5>;
- phy-mode = "rgmii-id";
label = "wan";
+
+ phy-mode = "rgmii-id";
sfp = <&sfp0>;
+
fixed-link {
speed = <1000>;
full-duplex;
};
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_WAN;
+ };
+ };
};
port@6 {
reg = <6>;
+
phy-mode = "rgmii-id";
- label = "cpu";
ethernet = <&switch0port4>;
+
fixed-link {
speed = <1000>;
full-duplex;
@@ -242,21 +372,25 @@
interrupt-parent = <&switch1>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
};
+
lan2phy: ethernet-phy@1 {
reg = <1>;
interrupt-parent = <&switch1>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
};
+
lan3phy: ethernet-phy@2 {
reg = <2>;
interrupt-parent = <&switch1>;
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
};
+
lan4phy: ethernet-phy@3 {
reg = <3>;
interrupt-parent = <&switch1>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
};
+
ext1phy: ethernet-phy@4 {
reg = <4>;
interrupt-parent = <&switch1>;
@@ -266,48 +400,39 @@
};
};
-&uart0 {
+&ohci {
status = "okay";
};
&pinctrl {
- pinctrl_xg6846_usb_spd_led: xg6846_usb_spd_led-pins {
+ pinctrl_leds: leds {
function = "led";
- pins = "gpio17";
+ pins = "gpio16", "gpio18", "gpio20";
};
};
-&leds {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_xg6846_usb_spd_led>, /* GPIO16 LED USB */
- <&pinctrl_ephy1_spd_led>, /* GPIO18 LED PWR red */
- <&pinctrl_ephy3_spd_led>; /* GPIO20 LED PWR green */
+&switch0 {
+ dsa,member = <0 0>;
- /* On board variants without USB this LED is not mounted */
- led_usb_green: led@16 {
- reg = <16>;
- active-low;
- label = "green:usb";
- default-state = "off";
- };
+ ports {
+ switch0port4: port@4 {
+ reg = <4>;
+ label = "extsw";
- /*
- * LED 18 and 20 drive the same physical LED, the PWR
- * LED that can be both red and green.
- */
- led_pwr_red: led@18 {
- reg = <18>;
- active-low;
- label = "red:pwr";
- default-state = "off";
- };
+ phy-mode = "rgmii";
- led_pwr_green: led@20 {
- reg = <20>;
- active-low;
- label = "green:pwr";
- default-state = "off";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
};
+};
+
+&uart0 {
+ status = "okay";
+};
+&usbh {
+ status = "okay";
};
diff --git a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
index 6500d54e36..999f162fe4 100644
--- a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
+++ b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
@@ -49,69 +49,69 @@
leds {
compatible = "gpio-leds";
- led@0 {
+ led-0 {
label = "red:message";
gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
};
- led@1 {
+ led-1 {
label = "red:hspa";
gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
};
- led@2 {
+ led-2 {
label = "red:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@3 {
+ led_power_red: led-3 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
};
- led@6 {
+ led-6 {
label = "all";
gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- led@12 {
+ led-12 {
label = "green:lan1";
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
};
- led@13 {
+ led-13 {
label = "red:lan1";
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
};
- led@15 {
+ led-15 {
label = "green:lan2";
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
};
- led@22 {
+ led-22 {
label = "red:lan2";
gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
};
- led@23 {
+ led-23 {
label = "green:lan3";
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led@26 {
+ led-26 {
label = "red:lan3";
gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
};
- led@27 {
+ led-27 {
label = "green:lan4";
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
};
- led@28 {
+ led-28 {
label = "red:lan4";
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
@@ -120,7 +120,7 @@
ath9k-leds {
compatible = "gpio-leds";
- wlan {
+ led-2 {
function = LED_FUNCTION_WLAN;
color = <LED_COLOR_ID_RED>;
gpios = <&ath9k 2 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/bmips/dts/bcm6358.dtsi b/target/linux/bmips/dts/bcm6358.dtsi
index d5dee7d150..fe14055ef7 100644
--- a/target/linux/bmips/dts/bcm6358.dtsi
+++ b/target/linux/bmips/dts/bcm6358.dtsi
@@ -42,7 +42,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
- mips-cbr-reg = <0xff400000>;
+ brcm,bmips-cbr-reg = <0xff400000>;
mips-hpt-frequency = <150000000>;
cpu@0 {
diff --git a/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts b/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts
index a7498815e3..596ccf998f 100644
--- a/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts
+++ b/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts
@@ -41,12 +41,12 @@
leds {
compatible = "gpio-leds";
- led_phone_green: led@28 {
+ led_phone_green: led-28 {
label = "green:phone";
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
- led@30 {
+ led-30 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
index 0259fdba6c..7c1fde3132 100644
--- a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
+++ b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
@@ -42,12 +42,12 @@
leds {
compatible = "gpio-leds";
- led@28 {
+ led-28 {
label = "green:dsl";
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@34 {
+ led_power_red: led-34 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 34 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts b/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts
index 5951ad854c..7f4a725e9a 100644
--- a/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts
+++ b/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts
@@ -35,44 +35,44 @@
leds {
compatible = "gpio-leds";
- led@5 {
+ led-5 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led@21 {
+ led-21 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led@23 {
+ led-23 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@30 {
+ led-30 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
};
- led@31 {
+ led-31 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
index 647db7afaa..0ebe26716c 100644
--- a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
+++ b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
@@ -28,30 +28,30 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@31 {
+ led-31 {
label = "red:internet";
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
};
diff --git a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts
index ba75cb3e5c..8935dfe903 100644
--- a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts
+++ b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts
@@ -28,30 +28,30 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@31 {
+ led-31 {
label = "red:internet";
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
};
diff --git a/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi
index 49c546692a..43225cdd52 100644
--- a/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi
+++ b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi
@@ -41,66 +41,66 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@4 {
+ led-4 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
- led@11 {
+ led-11 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
};
- led@13 {
+ led-13 {
/* Front USB port */
label = "green:usb2";
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
};
- led@14 {
+ led-14 {
/* Back USB port */
label = "green:usb1";
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@22 {
+ led_power_red: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
panic-indicator;
};
- led@23 {
+ led-23 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@24 {
+ led_power_green: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
};
- led@26 {
+ led-26 {
label = "green:wifi2g";
gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
};
- led@27 {
+ led-27 {
label = "blue:wifi5g";
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
};
diff --git a/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts b/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts
index 3268ff146f..a0c2f321af 100644
--- a/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts
+++ b/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts
@@ -35,45 +35,45 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "blue:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "red:dsl";
gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
- led@11 {
+ led-11 {
label = "blue:hspa";
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
};
- led@12 {
+ led-12 {
label = "red:hspa";
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
};
- led_power_blue: led@22 {
+ led_power_blue: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@25 {
+ led-25 {
label = "blue:voice";
gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
};
- led@26 {
+ led-26 {
label = "red:voice";
gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
};
diff --git a/target/linux/bmips/dts/bcm6368.dtsi b/target/linux/bmips/dts/bcm6368.dtsi
index 84300c980a..e50f7a1b0c 100644
--- a/target/linux/bmips/dts/bcm6368.dtsi
+++ b/target/linux/bmips/dts/bcm6368.dtsi
@@ -43,7 +43,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
- mips-cbr-reg = <0xff400000>;
+ brcm,bmips-cbr-reg = <0xff400000>;
mips-hpt-frequency = <200000000>;
cpu@0 {
diff --git a/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts b/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts
index 263a10bf61..5fa511816b 100644
--- a/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts
+++ b/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts
@@ -42,37 +42,37 @@
leds {
compatible = "gpio-leds";
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led@14 {
+ led-14 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led@23 {
+ led-23 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@31 {
+ led-31 {
label = "red:internet";
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
};
diff --git a/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts b/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts
index 376f5b6865..cf91c0ad23 100644
--- a/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts
+++ b/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts
@@ -35,52 +35,52 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:voip2";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@4 {
+ led-4 {
label = "red:internet";
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
- led@14 {
+ led-14 {
label = "green:voip1";
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
};
- led@15 {
+ led-15 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@23 {
+ led_power_red: led-23 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
panic-indicator;
};
- led@24 {
+ led-24 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
};
- led@27 {
+ led-27 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6348-enet.c b/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6348-enet.c
index 21eb6ea0c2..5e5259a492 100644
--- a/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6348-enet.c
+++ b/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6348-enet.c
@@ -25,7 +25,6 @@
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
-#include <linux/version.h>
/* DMA channels */
#define DMA_CHAN_WIDTH 0x10
@@ -1647,11 +1646,7 @@ static int bcm6348_emac_probe(struct platform_device *pdev)
ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
ndev->mtu = ETH_DATA_LEN - VLAN_ETH_HLEN;
ndev->max_mtu = ENET_MAX_MTU - VLAN_ETH_HLEN;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
- netif_napi_add(ndev, &emac->napi, bcm6348_emac_poll);
-#else
- netif_napi_add(ndev, &emac->napi, bcm6348_emac_poll, 16);
-#endif
+ netif_napi_add_weight(ndev, &emac->napi, bcm6348_emac_poll, 16);
SET_NETDEV_DEV(ndev, dev);
ret = devm_register_netdev(dev, ndev);
diff --git a/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c b/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c
index b72a788378..7031a74490 100644
--- a/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c
+++ b/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c
@@ -20,7 +20,6 @@
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
-#include <linux/version.h>
/* TODO: Bigger frames may work but we do not trust that they are safe on all
* platforms so more research is needed, a max frame size of 2048 has been
@@ -1077,11 +1076,7 @@ static int bcm6368_enetsw_probe(struct platform_device *pdev)
ndev->min_mtu = ETH_ZLEN;
ndev->mtu = ETH_DATA_LEN;
ndev->max_mtu = ENETSW_MAX_MTU;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
- netif_napi_add(ndev, &priv->napi, bcm6368_enetsw_poll);
-#else
- netif_napi_add(ndev, &priv->napi, bcm6368_enetsw_poll, 16);
-#endif
+ netif_napi_add_weight(ndev, &priv->napi, bcm6368_enetsw_poll, 16);
ret = devm_register_netdev(dev, ndev);
if (ret) {
diff --git a/target/linux/bmips/image/bcm6318.mk b/target/linux/bmips/image/bcm6318.mk
index bfd75cc077..286a30c2f4 100644
--- a/target/linux/bmips/image/bcm6318.mk
+++ b/target/linux/bmips/image/bcm6318.mk
@@ -12,3 +12,23 @@ define Device/comtrend_ar-5315u
kmod-leds-bcm6328
endef
TARGET_DEVICES += comtrend_ar-5315u
+
+define Device/tp-link_td-w8968-v3
+ $(Device/bcm63xx-cfe)
+ DEVICE_VENDOR := TP-Link
+ DEVICE_MODEL := TD-W8968
+ DEVICE_VARIANT := V3
+ DEVICE_ALT0_VENDOR := TP-Link
+ DEVICE_ALT0_MODEL := TD-W8968
+ DEVICE_ALT0_VARIANT := V4
+ DEVICE_ALT1_VENDOR := TP-Link
+ DEVICE_ALT1_MODEL := TD-W8960N
+ DEVICE_ALT1_VARIANT := V5
+ CHIP_ID := 6318
+ CFE_BOARD_ID := 96318REF
+ FLASH_MB := 8
+ DEVICE_PACKAGES += $(USB2_PACKAGES) \
+ $(B43_PACKAGES) broadcom-43217-sprom \
+ kmod-leds-bcm6328
+endef
+TARGET_DEVICES += tp-link_td-w8968-v3
diff --git a/target/linux/bmips/image/bcm6328.mk b/target/linux/bmips/image/bcm6328.mk
index b85b6ac7a8..0ba17cef4f 100644
--- a/target/linux/bmips/image/bcm6328.mk
+++ b/target/linux/bmips/image/bcm6328.mk
@@ -39,6 +39,27 @@ define Device/comtrend_ar-5387un
endef
TARGET_DEVICES += comtrend_ar-5387un
+define Device/dlink_dsl-2750b-b1
+ $(Device/bcm63xx-cfe)
+ DEVICE_VENDOR := D-Link
+ DEVICE_MODEL := DSL-2750B
+ DEVICE_VARIANT := B1
+ DEVICE_ALT0_VENDOR := D-Link
+ DEVICE_ALT0_MODEL := DSL-2740B
+ DEVICE_ALT0_VARIANT := F1
+ DEVICE_ALT1_VENDOR := D-Link
+ DEVICE_ALT1_MODEL := DSL-2741B
+ DEVICE_ALT1_VARIANT := F1
+ CFE_BOARD_ID := AW4339U
+ CHIP_ID := 6328
+ IMAGES := cfe-EU.bin cfe-AU.bin
+ IMAGE/cfe-AU.bin := cfe-bin --signature2 "4.06.01.AUF1" --pad 4
+ IMAGE/cfe-EU.bin := cfe-bin --signature2 "4.06.01.EUF1" --pad 4
+ DEVICE_PACKAGES += $(USB2_PACKAGES) $(ATH9K_PACKAGES) \
+ kmod-leds-gpio kmod-leds-bcm6328
+endef
+TARGET_DEVICES += dlink_dsl-2750b-b1
+
define Device/innacomm_w3400v6
$(Device/bcm63xx-cfe)
DEVICE_VENDOR := Innacomm
diff --git a/target/linux/bmips/patches-6.6/010-v6.10-mips-bmips-BCM6358-make-sure-CBR-is-correctly-set.patch b/target/linux/bmips/patches-6.6/010-v6.10-mips-bmips-BCM6358-make-sure-CBR-is-correctly-set.patch
deleted file mode 100644
index 0a5a7c2402..0000000000
--- a/target/linux/bmips/patches-6.6/010-v6.10-mips-bmips-BCM6358-make-sure-CBR-is-correctly-set.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From ce5cdd3b05216b704a704f466fb4c2dff3778caf Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 11 Jun 2024 13:35:33 +0200
-Subject: [PATCH] mips: bmips: BCM6358: make sure CBR is correctly set
-
-It was discovered that some device have CBR address set to 0 causing
-kernel panic when arch_sync_dma_for_cpu_all is called.
-
-This was notice in situation where the system is booted from TP1 and
-BMIPS_GET_CBR() returns 0 instead of a valid address and
-!!(read_c0_brcm_cmt_local() & (1 << 31)); not failing.
-
-The current check whether RAC flush should be disabled or not are not
-enough hence lets check if CBR is a valid address or not.
-
-Fixes: ab327f8acdf8 ("mips: bmips: BCM6358: disable RAC flush for TP1")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/bmips/setup.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/arch/mips/bmips/setup.c
-+++ b/arch/mips/bmips/setup.c
-@@ -110,7 +110,8 @@ static void bcm6358_quirks(void)
- * RAC flush causes kernel panics on BCM6358 when booting from TP1
- * because the bootloader is not initializing it properly.
- */
-- bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31));
-+ bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) ||
-+ !!BMIPS_GET_CBR();
- }
-
- static void bcm6368_quirks(void)
diff --git a/target/linux/gemini/config-6.6 b/target/linux/gemini/config-6.6
index 87174d292f..a93297a423 100644
--- a/target/linux/gemini/config-6.6
+++ b/target/linux/gemini/config-6.6
@@ -180,7 +180,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FTTMR010_TIMER=y
CONFIG_FTWDT010_WATCHDOG=y
CONFIG_FUNCTION_ALIGNMENT=0
@@ -431,7 +430,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
diff --git a/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch b/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch
deleted file mode 100644
index b481dd3061..0000000000
--- a/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 2fd7e7f9317d3048a14026816d081b08ba98ea8e Mon Sep 17 00:00:00 2001
-From: Mark Rutland <mark.rutland@arm.com>
-Date: Tue, 8 Mar 2022 22:56:13 +0100
-Subject: [PATCH 1/3] Kbuild: use -Wdeclaration-after-statement
-
-The kernel is moving from using `-std=gnu89` to `-std=gnu11`, permitting
-the use of additional C11 features such as for-loop initial declarations.
-
-One contentious aspect of C99 is that it permits mixed declarations and
-code, and for now at least, it seems preferable to enforce that
-declarations must come first.
-
-These warnings were already enabled in the kernel itself, but not
-for KBUILD_USERCFLAGS or the compat VDSO on arch/arm64, which uses
-a separate set of CFLAGS.
-
-This patch fixes an existing violation in modpost.c, which is not
-reported because of the missing flag in KBUILD_USERCFLAGS:
-
-| scripts/mod/modpost.c: In function ‘match’:
-| scripts/mod/modpost.c:837:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
-| 837 | const char *endp = p + strlen(p) - 1;
-| | ^~~~~
-
-Signed-off-by: Mark Rutland <mark.rutland@arm.com>
-[arnd: don't add a duplicate flag to the default set, update changelog]
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Reviewed-by: Nathan Chancellor <nathan@kernel.org>
-Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
-Tested-by: Sedat Dilek <sedat.dilek@gmail.com> # LLVM/Clang v13.0.0 (x86-64)
-Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
----
- Makefile | 3 ++-
- arch/arm64/kernel/vdso32/Makefile | 1 +
- scripts/mod/modpost.c | 4 +++-
- 3 files changed, 6 insertions(+), 2 deletions(-)
-
---- a/Makefile
-+++ b/Makefile
-@@ -440,7 +440,8 @@ endif
- HOSTPKG_CONFIG = pkg-config
-
- export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
-- -O2 -fomit-frame-pointer -std=gnu89
-+ -O2 -fomit-frame-pointer -std=gnu89 \
-+ -Wdeclaration-after-statement
- export KBUILD_USERLDFLAGS :=
-
- KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS)
---- a/arch/arm64/kernel/vdso32/Makefile
-+++ b/arch/arm64/kernel/vdso32/Makefile
-@@ -76,6 +76,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-pr
- -fno-strict-aliasing -fno-common \
- -Werror-implicit-function-declaration \
- -Wno-format-security \
-+ -Wdeclaration-after-statement \
- -std=gnu89
- VDSO_CFLAGS += -O2
- # Some useful compiler-dependent flags from top-level Makefile
---- a/scripts/mod/modpost.c
-+++ b/scripts/mod/modpost.c
-@@ -833,8 +833,10 @@ static int match(const char *sym, const
- {
- const char *p;
- while (*pat) {
-+ const char *endp;
-+
- p = *pat++;
-- const char *endp = p + strlen(p) - 1;
-+ endp = p + strlen(p) - 1;
-
- /* "*foo*" */
- if (*p == '*' && *endp == '*') {
diff --git a/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch b/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch
deleted file mode 100644
index 94fc52fd8e..0000000000
--- a/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From b810c8e719ea082e47c7a8f7cf878bc84fa2455d Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Tue, 8 Mar 2022 22:56:14 +0100
-Subject: [PATCH 2/3] Kbuild: move to -std=gnu11
-
-During a patch discussion, Linus brought up the option of changing
-the C standard version from gnu89 to gnu99, which allows using variable
-declaration inside of a for() loop. While the C99, C11 and later standards
-introduce many other features, most of these are already available in
-gnu89 as GNU extensions as well.
-
-An earlier attempt to do this when gcc-5 started defaulting to
--std=gnu11 failed because at the time that caused warnings about
-designated initializers with older compilers. Now that gcc-5.1 is
-the minimum compiler version used for building kernels, that is no
-longer a concern. Similarly, the behavior of 'inline' functions changes
-between gnu89 using gnu_inline behavior and gnu11 using standard c99+
-behavior, but this was taken care of by defining 'inline' to include
-__attribute__((gnu_inline)) in order to allow building with clang a
-while ago.
-
-Nathan Chancellor reported a new -Wdeclaration-after-statement
-warning that appears in a system header on arm, this still needs a
-workaround.
-
-The differences between gnu99, gnu11, gnu1x and gnu17 are fairly
-minimal and mainly impact warnings at the -Wpedantic level that the
-kernel never enables. Between these, gnu11 is the newest version
-that is supported by all supported compiler versions, though it is
-only the default on gcc-5, while all other supported versions of
-gcc or clang default to gnu1x/gnu17.
-
-Link: https://lore.kernel.org/lkml/CAHk-=wiyCH7xeHcmiFJ-YgXUy2Jaj7pnkdKpcovt8fYbVFW3TA@mail.gmail.com/
-Link: https://github.com/ClangBuiltLinux/linux/issues/1603
-Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
-Acked-by: Marco Elver <elver@google.com>
-Acked-by: Jani Nikula <jani.nikula@intel.com>
-Acked-by: David Sterba <dsterba@suse.com>
-Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
-Reviewed-by: Alex Shi <alexs@kernel.org>
-Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
-Reviewed-by: Miguel Ojeda <ojeda@kernel.org>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Reviewed-by: Nathan Chancellor <nathan@kernel.org>
-Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
----
- Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/Makefile
-+++ b/Makefile
-@@ -524,7 +524,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror
- -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \
- -Werror=implicit-function-declaration -Werror=implicit-int \
- -Werror=return-type -Wno-format-security \
-- -std=gnu89
-+ -std=gnu11
- KBUILD_CPPFLAGS := -D__KERNEL__
- KBUILD_AFLAGS_KERNEL :=
- KBUILD_CFLAGS_KERNEL :=
diff --git a/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch b/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch
deleted file mode 100644
index e34acbba17..0000000000
--- a/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 40337d6f3d677aee7ad3052ae662d3f53dd4d5cb Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Tue, 8 Mar 2022 22:56:15 +0100
-Subject: [PATCH 3/3] Kbuild: use -std=gnu11 for KBUILD_USERCFLAGS
-
-As we change the C language standard for the kernel from gnu89 to
-gnu11, it makes sense to also update the version for user space
-compilation.
-
-Some users have older native compilers than what they use for
-kernel builds, so I considered using gnu99 as the default version
-for wider compatibility with gcc-4.6 and earlier.
-
-However, testing with older compilers showed that we already require
-HOSTCC version 5.1 as well because a lot of host tools include
-linux/compiler.h that uses __has_attribute():
-
- CC tools/objtool/exec-cmd.o
-In file included from tools/include/linux/compiler_types.h:36:0,
- from tools/include/linux/compiler.h:5,
- from exec-cmd.c:2:
-tools/include/linux/compiler-gcc.h:19:5: error: "__has_attribute" is not defined [-Werror=undef]
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Reviewed-by: Nathan Chancellor <nathan@kernel.org>
-Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
-Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
-Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
----
- Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/Makefile
-+++ b/Makefile
-@@ -440,7 +440,7 @@ endif
- HOSTPKG_CONFIG = pkg-config
-
- export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
-- -O2 -fomit-frame-pointer -std=gnu89 \
-+ -O2 -fomit-frame-pointer -std=gnu11 \
- -Wdeclaration-after-statement
- export KBUILD_USERLDFLAGS :=
-
diff --git a/target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch b/target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch
deleted file mode 100644
index 865da6b182..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch
+++ /dev/null
@@ -1,425 +0,0 @@
-From a4103262b01a1b8704b37c01c7c813df91b7b119 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 01:59:58 -0600
-Subject: [PATCH 01/29] mm: x86, arm64: add arch_has_hw_pte_young()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Patch series "Multi-Gen LRU Framework", v14.
-
-What's new
-==========
-1. OpenWrt, in addition to Android, Arch Linux Zen, Armbian, ChromeOS,
- Liquorix, post-factum and XanMod, is now shipping MGLRU on 5.15.
-2. Fixed long-tailed direct reclaim latency seen on high-memory (TBs)
- machines. The old direct reclaim backoff, which tries to enforce a
- minimum fairness among all eligible memcgs, over-swapped by about
- (total_mem>>DEF_PRIORITY)-nr_to_reclaim. The new backoff, which
- pulls the plug on swapping once the target is met, trades some
- fairness for curtailed latency:
- https://lore.kernel.org/r/20220918080010.2920238-10-yuzhao@google.com/
-3. Fixed minior build warnings and conflicts. More comments and nits.
-
-TLDR
-====
-The current page reclaim is too expensive in terms of CPU usage and it
-often makes poor choices about what to evict. This patchset offers an
-alternative solution that is performant, versatile and
-straightforward.
-
-Patchset overview
-=================
-The design and implementation overview is in patch 14:
-https://lore.kernel.org/r/20220918080010.2920238-15-yuzhao@google.com/
-
-01. mm: x86, arm64: add arch_has_hw_pte_young()
-02. mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
-Take advantage of hardware features when trying to clear the accessed
-bit in many PTEs.
-
-03. mm/vmscan.c: refactor shrink_node()
-04. Revert "include/linux/mm_inline.h: fold __update_lru_size() into
- its sole caller"
-Minor refactors to improve readability for the following patches.
-
-05. mm: multi-gen LRU: groundwork
-Adds the basic data structure and the functions that insert pages to
-and remove pages from the multi-gen LRU (MGLRU) lists.
-
-06. mm: multi-gen LRU: minimal implementation
-A minimal implementation without optimizations.
-
-07. mm: multi-gen LRU: exploit locality in rmap
-Exploits spatial locality to improve efficiency when using the rmap.
-
-08. mm: multi-gen LRU: support page table walks
-Further exploits spatial locality by optionally scanning page tables.
-
-09. mm: multi-gen LRU: optimize multiple memcgs
-Optimizes the overall performance for multiple memcgs running mixed
-types of workloads.
-
-10. mm: multi-gen LRU: kill switch
-Adds a kill switch to enable or disable MGLRU at runtime.
-
-11. mm: multi-gen LRU: thrashing prevention
-12. mm: multi-gen LRU: debugfs interface
-Provide userspace with features like thrashing prevention, working set
-estimation and proactive reclaim.
-
-13. mm: multi-gen LRU: admin guide
-14. mm: multi-gen LRU: design doc
-Add an admin guide and a design doc.
-
-Benchmark results
-=================
-Independent lab results
------------------------
-Based on the popularity of searches [01] and the memory usage in
-Google's public cloud, the most popular open-source memory-hungry
-applications, in alphabetical order, are:
- Apache Cassandra Memcached
- Apache Hadoop MongoDB
- Apache Spark PostgreSQL
- MariaDB (MySQL) Redis
-
-An independent lab evaluated MGLRU with the most widely used benchmark
-suites for the above applications. They posted 960 data points along
-with kernel metrics and perf profiles collected over more than 500
-hours of total benchmark time. Their final reports show that, with 95%
-confidence intervals (CIs), the above applications all performed
-significantly better for at least part of their benchmark matrices.
-
-On 5.14:
-1. Apache Spark [02] took 95% CIs [9.28, 11.19]% and [12.20, 14.93]%
- less wall time to sort three billion random integers, respectively,
- under the medium- and the high-concurrency conditions, when
- overcommitting memory. There were no statistically significant
- changes in wall time for the rest of the benchmark matrix.
-2. MariaDB [03] achieved 95% CIs [5.24, 10.71]% and [20.22, 25.97]%
- more transactions per minute (TPM), respectively, under the medium-
- and the high-concurrency conditions, when overcommitting memory.
- There were no statistically significant changes in TPM for the rest
- of the benchmark matrix.
-3. Memcached [04] achieved 95% CIs [23.54, 32.25]%, [20.76, 41.61]%
- and [21.59, 30.02]% more operations per second (OPS), respectively,
- for sequential access, random access and Gaussian (distribution)
- access, when THP=always; 95% CIs [13.85, 15.97]% and
- [23.94, 29.92]% more OPS, respectively, for random access and
- Gaussian access, when THP=never. There were no statistically
- significant changes in OPS for the rest of the benchmark matrix.
-4. MongoDB [05] achieved 95% CIs [2.23, 3.44]%, [6.97, 9.73]% and
- [2.16, 3.55]% more operations per second (OPS), respectively, for
- exponential (distribution) access, random access and Zipfian
- (distribution) access, when underutilizing memory; 95% CIs
- [8.83, 10.03]%, [21.12, 23.14]% and [5.53, 6.46]% more OPS,
- respectively, for exponential access, random access and Zipfian
- access, when overcommitting memory.
-
-On 5.15:
-5. Apache Cassandra [06] achieved 95% CIs [1.06, 4.10]%, [1.94, 5.43]%
- and [4.11, 7.50]% more operations per second (OPS), respectively,
- for exponential (distribution) access, random access and Zipfian
- (distribution) access, when swap was off; 95% CIs [0.50, 2.60]%,
- [6.51, 8.77]% and [3.29, 6.75]% more OPS, respectively, for
- exponential access, random access and Zipfian access, when swap was
- on.
-6. Apache Hadoop [07] took 95% CIs [5.31, 9.69]% and [2.02, 7.86]%
- less average wall time to finish twelve parallel TeraSort jobs,
- respectively, under the medium- and the high-concurrency
- conditions, when swap was on. There were no statistically
- significant changes in average wall time for the rest of the
- benchmark matrix.
-7. PostgreSQL [08] achieved 95% CI [1.75, 6.42]% more transactions per
- minute (TPM) under the high-concurrency condition, when swap was
- off; 95% CIs [12.82, 18.69]% and [22.70, 46.86]% more TPM,
- respectively, under the medium- and the high-concurrency
- conditions, when swap was on. There were no statistically
- significant changes in TPM for the rest of the benchmark matrix.
-8. Redis [09] achieved 95% CIs [0.58, 5.94]%, [6.55, 14.58]% and
- [11.47, 19.36]% more total operations per second (OPS),
- respectively, for sequential access, random access and Gaussian
- (distribution) access, when THP=always; 95% CIs [1.27, 3.54]%,
- [10.11, 14.81]% and [8.75, 13.64]% more total OPS, respectively,
- for sequential access, random access and Gaussian access, when
- THP=never.
-
-Our lab results
----------------
-To supplement the above results, we ran the following benchmark suites
-on 5.16-rc7 and found no regressions [10].
- fs_fio_bench_hdd_mq pft
- fs_lmbench pgsql-hammerdb
- fs_parallelio redis
- fs_postmark stream
- hackbench sysbenchthread
- kernbench tpcc_spark
- memcached unixbench
- multichase vm-scalability
- mutilate will-it-scale
- nginx
-
-[01] https://trends.google.com
-[02] https://lore.kernel.org/r/20211102002002.92051-1-bot@edi.works/
-[03] https://lore.kernel.org/r/20211009054315.47073-1-bot@edi.works/
-[04] https://lore.kernel.org/r/20211021194103.65648-1-bot@edi.works/
-[05] https://lore.kernel.org/r/20211109021346.50266-1-bot@edi.works/
-[06] https://lore.kernel.org/r/20211202062806.80365-1-bot@edi.works/
-[07] https://lore.kernel.org/r/20211209072416.33606-1-bot@edi.works/
-[08] https://lore.kernel.org/r/20211218071041.24077-1-bot@edi.works/
-[09] https://lore.kernel.org/r/20211122053248.57311-1-bot@edi.works/
-[10] https://lore.kernel.org/r/20220104202247.2903702-1-yuzhao@google.com/
-
-Read-world applications
-=======================
-Third-party testimonials
-------------------------
-Konstantin reported [11]:
- I have Archlinux with 8G RAM + zswap + swap. While developing, I
- have lots of apps opened such as multiple LSP-servers for different
- langs, chats, two browsers, etc... Usually, my system gets quickly
- to a point of SWAP-storms, where I have to kill LSP-servers,
- restart browsers to free memory, etc, otherwise the system lags
- heavily and is barely usable.
-
- 1.5 day ago I migrated from 5.11.15 kernel to 5.12 + the LRU
- patchset, and I started up by opening lots of apps to create memory
- pressure, and worked for a day like this. Till now I had not a
- single SWAP-storm, and mind you I got 3.4G in SWAP. I was never
- getting to the point of 3G in SWAP before without a single
- SWAP-storm.
-
-Vaibhav from IBM reported [12]:
- In a synthetic MongoDB Benchmark, seeing an average of ~19%
- throughput improvement on POWER10(Radix MMU + 64K Page Size) with
- MGLRU patches on top of 5.16 kernel for MongoDB + YCSB across
- three different request distributions, namely, Exponential, Uniform
- and Zipfan.
-
-Shuang from U of Rochester reported [13]:
- With the MGLRU, fio achieved 95% CIs [38.95, 40.26]%, [4.12, 6.64]%
- and [9.26, 10.36]% higher throughput, respectively, for random
- access, Zipfian (distribution) access and Gaussian (distribution)
- access, when the average number of jobs per CPU is 1; 95% CIs
- [42.32, 49.15]%, [9.44, 9.89]% and [20.99, 22.86]% higher
- throughput, respectively, for random access, Zipfian access and
- Gaussian access, when the average number of jobs per CPU is 2.
-
-Daniel from Michigan Tech reported [14]:
- With Memcached allocating ~100GB of byte-addressable Optante,
- performance improvement in terms of throughput (measured as queries
- per second) was about 10% for a series of workloads.
-
-Large-scale deployments
------------------------
-We've rolled out MGLRU to tens of millions of ChromeOS users and
-about a million Android users. Google's fleetwide profiling [15] shows
-an overall 40% decrease in kswapd CPU usage, in addition to
-improvements in other UX metrics, e.g., an 85% decrease in the number
-of low-memory kills at the 75th percentile and an 18% decrease in
-app launch time at the 50th percentile.
-
-The downstream kernels that have been using MGLRU include:
-1. Android [16]
-2. Arch Linux Zen [17]
-3. Armbian [18]
-4. ChromeOS [19]
-5. Liquorix [20]
-6. OpenWrt [21]
-7. post-factum [22]
-8. XanMod [23]
-
-[11] https://lore.kernel.org/r/140226722f2032c86301fbd326d91baefe3d7d23.camel@yandex.ru/
-[12] https://lore.kernel.org/r/87czj3mux0.fsf@vajain21.in.ibm.com/
-[13] https://lore.kernel.org/r/20220105024423.26409-1-szhai2@cs.rochester.edu/
-[14] https://lore.kernel.org/r/CA+4-3vksGvKd18FgRinxhqHetBS1hQekJE2gwco8Ja-bJWKtFw@mail.gmail.com/
-[15] https://dl.acm.org/doi/10.1145/2749469.2750392
-[16] https://android.com
-[17] https://archlinux.org
-[18] https://armbian.com
-[19] https://chromium.org
-[20] https://liquorix.net
-[21] https://openwrt.org
-[22] https://codeberg.org/pf-kernel
-[23] https://xanmod.org
-
-Summary
-=======
-The facts are:
-1. The independent lab results and the real-world applications
- indicate substantial improvements; there are no known regressions.
-2. Thrashing prevention, working set estimation and proactive reclaim
- work out of the box; there are no equivalent solutions.
-3. There is a lot of new code; no smaller changes have been
- demonstrated similar effects.
-
-Our options, accordingly, are:
-1. Given the amount of evidence, the reported improvements will likely
- materialize for a wide range of workloads.
-2. Gauging the interest from the past discussions, the new features
- will likely be put to use for both personal computers and data
- centers.
-3. Based on Google's track record, the new code will likely be well
- maintained in the long term. It'd be more difficult if not
- impossible to achieve similar effects with other approaches.
-
-This patch (of 14):
-
-Some architectures automatically set the accessed bit in PTEs, e.g., x86
-and arm64 v8.2. On architectures that do not have this capability,
-clearing the accessed bit in a PTE usually triggers a page fault following
-the TLB miss of this PTE (to emulate the accessed bit).
-
-Being aware of this capability can help make better decisions, e.g.,
-whether to spread the work out over a period of time to reduce bursty page
-faults when trying to clear the accessed bit in many PTEs.
-
-Note that theoretically this capability can be unreliable, e.g.,
-hotplugged CPUs might be different from builtin ones. Therefore it should
-not be used in architecture-independent code that involves correctness,
-e.g., to determine whether TLB flushes are required (in combination with
-the accessed bit).
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-1-yuzhao@google.com
-Link: https://lkml.kernel.org/r/20220918080010.2920238-2-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reviewed-by: Barry Song <baohua@kernel.org>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Acked-by: Will Deacon <will@kernel.org>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: linux-arm-kernel@lists.infradead.org
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- arch/arm64/include/asm/pgtable.h | 14 ++------------
- arch/x86/include/asm/pgtable.h | 6 +++---
- include/linux/pgtable.h | 13 +++++++++++++
- mm/memory.c | 14 +-------------
- 4 files changed, 19 insertions(+), 28 deletions(-)
-
---- a/arch/arm64/include/asm/pgtable.h
-+++ b/arch/arm64/include/asm/pgtable.h
-@@ -1005,23 +1005,13 @@ static inline void update_mmu_cache(stru
- * page after fork() + CoW for pfn mappings. We don't always have a
- * hardware-managed access flag on arm64.
- */
--static inline bool arch_faults_on_old_pte(void)
--{
-- WARN_ON(preemptible());
--
-- return !cpu_has_hw_af();
--}
--#define arch_faults_on_old_pte arch_faults_on_old_pte
-+#define arch_has_hw_pte_young cpu_has_hw_af
-
- /*
- * Experimentally, it's cheap to set the access flag in hardware and we
- * benefit from prefaulting mappings as 'old' to start with.
- */
--static inline bool arch_wants_old_prefaulted_pte(void)
--{
-- return !arch_faults_on_old_pte();
--}
--#define arch_wants_old_prefaulted_pte arch_wants_old_prefaulted_pte
-+#define arch_wants_old_prefaulted_pte cpu_has_hw_af
-
- #endif /* !__ASSEMBLY__ */
-
---- a/arch/x86/include/asm/pgtable.h
-+++ b/arch/x86/include/asm/pgtable.h
-@@ -1397,10 +1397,10 @@ static inline bool arch_has_pfn_modify_c
- return boot_cpu_has_bug(X86_BUG_L1TF);
- }
-
--#define arch_faults_on_old_pte arch_faults_on_old_pte
--static inline bool arch_faults_on_old_pte(void)
-+#define arch_has_hw_pte_young arch_has_hw_pte_young
-+static inline bool arch_has_hw_pte_young(void)
- {
-- return false;
-+ return true;
- }
-
- #endif /* __ASSEMBLY__ */
---- a/include/linux/pgtable.h
-+++ b/include/linux/pgtable.h
-@@ -259,6 +259,19 @@ static inline int pmdp_clear_flush_young
- #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
- #endif
-
-+#ifndef arch_has_hw_pte_young
-+/*
-+ * Return whether the accessed bit is supported on the local CPU.
-+ *
-+ * This stub assumes accessing through an old PTE triggers a page fault.
-+ * Architectures that automatically set the access bit should overwrite it.
-+ */
-+static inline bool arch_has_hw_pte_young(void)
-+{
-+ return false;
-+}
-+#endif
-+
- #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
- static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
- unsigned long address,
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -121,18 +121,6 @@ int randomize_va_space __read_mostly =
- 2;
- #endif
-
--#ifndef arch_faults_on_old_pte
--static inline bool arch_faults_on_old_pte(void)
--{
-- /*
-- * Those arches which don't have hw access flag feature need to
-- * implement their own helper. By default, "true" means pagefault
-- * will be hit on old pte.
-- */
-- return true;
--}
--#endif
--
- #ifndef arch_wants_old_prefaulted_pte
- static inline bool arch_wants_old_prefaulted_pte(void)
- {
-@@ -2791,7 +2779,7 @@ static inline int cow_user_page(struct p
- * On architectures with software "accessed" bits, we would
- * take a double page fault, so mark it accessed here.
- */
-- if (arch_faults_on_old_pte() && !pte_young(vmf->orig_pte)) {
-+ if (!arch_has_hw_pte_young() && !pte_young(vmf->orig_pte)) {
- pte_t entry;
-
- vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
diff --git a/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch b/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch
deleted file mode 100644
index 8e4de36db0..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 493de1c4b0f2cd909169401da8c445f6c8a7e29d Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 01:59:59 -0600
-Subject: [PATCH 02/29] mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some architectures support the accessed bit in non-leaf PMD entries, e.g.,
-x86 sets the accessed bit in a non-leaf PMD entry when using it as part of
-linear address translation [1]. Page table walkers that clear the
-accessed bit may use this capability to reduce their search space.
-
-Note that:
-1. Although an inline function is preferable, this capability is added
- as a configuration option for consistency with the existing macros.
-2. Due to the little interest in other varieties, this capability was
- only tested on Intel and AMD CPUs.
-
-Thanks to the following developers for their efforts [2][3].
- Randy Dunlap <rdunlap@infradead.org>
- Stephen Rothwell <sfr@canb.auug.org.au>
-
-[1]: Intel 64 and IA-32 Architectures Software Developer's Manual
- Volume 3 (June 2021), section 4.8
-[2] https://lore.kernel.org/r/bfdcc7c8-922f-61a9-aa15-7e7250f04af7@infradead.org/
-[3] https://lore.kernel.org/r/20220413151513.5a0d7a7e@canb.auug.org.au/
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-3-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reviewed-by: Barry Song <baohua@kernel.org>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- arch/Kconfig | 8 ++++++++
- arch/x86/Kconfig | 1 +
- arch/x86/include/asm/pgtable.h | 3 ++-
- arch/x86/mm/pgtable.c | 5 ++++-
- include/linux/pgtable.h | 4 ++--
- 5 files changed, 17 insertions(+), 4 deletions(-)
-
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -1307,6 +1307,14 @@ config ARCH_HAS_ELFCORE_COMPAT
- config ARCH_HAS_PARANOID_L1D_FLUSH
- bool
-
-+config ARCH_HAS_NONLEAF_PMD_YOUNG
-+ bool
-+ help
-+ Architectures that select this option are capable of setting the
-+ accessed bit in non-leaf PMD entries when using them as part of linear
-+ address translations. Page table walkers that clear the accessed bit
-+ may use this capability to reduce their search space.
-+
- source "kernel/gcov/Kconfig"
-
- source "scripts/gcc-plugins/Kconfig"
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
-@@ -86,6 +86,7 @@ config X86
- select ARCH_HAS_PMEM_API if X86_64
- select ARCH_HAS_PTE_DEVMAP if X86_64
- select ARCH_HAS_PTE_SPECIAL
-+ select ARCH_HAS_NONLEAF_PMD_YOUNG if PGTABLE_LEVELS > 2
- select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64
- select ARCH_HAS_COPY_MC if X86_64
- select ARCH_HAS_SET_MEMORY
---- a/arch/x86/include/asm/pgtable.h
-+++ b/arch/x86/include/asm/pgtable.h
-@@ -817,7 +817,8 @@ static inline unsigned long pmd_page_vad
-
- static inline int pmd_bad(pmd_t pmd)
- {
-- return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;
-+ return (pmd_flags(pmd) & ~(_PAGE_USER | _PAGE_ACCESSED)) !=
-+ (_KERNPG_TABLE & ~_PAGE_ACCESSED);
- }
-
- static inline unsigned long pages_to_mb(unsigned long npg)
---- a/arch/x86/mm/pgtable.c
-+++ b/arch/x86/mm/pgtable.c
-@@ -550,7 +550,7 @@ int ptep_test_and_clear_young(struct vm_
- return ret;
- }
-
--#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
- int pmdp_test_and_clear_young(struct vm_area_struct *vma,
- unsigned long addr, pmd_t *pmdp)
- {
-@@ -562,6 +562,9 @@ int pmdp_test_and_clear_young(struct vm_
-
- return ret;
- }
-+#endif
-+
-+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
- int pudp_test_and_clear_young(struct vm_area_struct *vma,
- unsigned long addr, pud_t *pudp)
- {
---- a/include/linux/pgtable.h
-+++ b/include/linux/pgtable.h
-@@ -212,7 +212,7 @@ static inline int ptep_test_and_clear_yo
- #endif
-
- #ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
--#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
- static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
- unsigned long address,
- pmd_t *pmdp)
-@@ -233,7 +233,7 @@ static inline int pmdp_test_and_clear_yo
- BUILD_BUG();
- return 0;
- }
--#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-+#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG */
- #endif
-
- #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
diff --git a/target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch b/target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch
deleted file mode 100644
index b8d2917d26..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch
+++ /dev/null
@@ -1,275 +0,0 @@
-From 9e17efd11450d3d2069adaa3c58db9ac8ebd1c66 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:00 -0600
-Subject: [PATCH 03/29] mm/vmscan.c: refactor shrink_node()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch refactors shrink_node() to improve readability for the upcoming
-changes to mm/vmscan.c.
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-4-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reviewed-by: Barry Song <baohua@kernel.org>
-Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 198 +++++++++++++++++++++++++++-------------------------
- 1 file changed, 104 insertions(+), 94 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -2497,6 +2497,109 @@ enum scan_balance {
- SCAN_FILE,
- };
-
-+static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc)
-+{
-+ unsigned long file;
-+ struct lruvec *target_lruvec;
-+
-+ target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
-+
-+ /*
-+ * Flush the memory cgroup stats, so that we read accurate per-memcg
-+ * lruvec stats for heuristics.
-+ */
-+ mem_cgroup_flush_stats();
-+
-+ /*
-+ * Determine the scan balance between anon and file LRUs.
-+ */
-+ spin_lock_irq(&target_lruvec->lru_lock);
-+ sc->anon_cost = target_lruvec->anon_cost;
-+ sc->file_cost = target_lruvec->file_cost;
-+ spin_unlock_irq(&target_lruvec->lru_lock);
-+
-+ /*
-+ * Target desirable inactive:active list ratios for the anon
-+ * and file LRU lists.
-+ */
-+ if (!sc->force_deactivate) {
-+ unsigned long refaults;
-+
-+ refaults = lruvec_page_state(target_lruvec,
-+ WORKINGSET_ACTIVATE_ANON);
-+ if (refaults != target_lruvec->refaults[0] ||
-+ inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
-+ sc->may_deactivate |= DEACTIVATE_ANON;
-+ else
-+ sc->may_deactivate &= ~DEACTIVATE_ANON;
-+
-+ /*
-+ * When refaults are being observed, it means a new
-+ * workingset is being established. Deactivate to get
-+ * rid of any stale active pages quickly.
-+ */
-+ refaults = lruvec_page_state(target_lruvec,
-+ WORKINGSET_ACTIVATE_FILE);
-+ if (refaults != target_lruvec->refaults[1] ||
-+ inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
-+ sc->may_deactivate |= DEACTIVATE_FILE;
-+ else
-+ sc->may_deactivate &= ~DEACTIVATE_FILE;
-+ } else
-+ sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE;
-+
-+ /*
-+ * If we have plenty of inactive file pages that aren't
-+ * thrashing, try to reclaim those first before touching
-+ * anonymous pages.
-+ */
-+ file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE);
-+ if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE))
-+ sc->cache_trim_mode = 1;
-+ else
-+ sc->cache_trim_mode = 0;
-+
-+ /*
-+ * Prevent the reclaimer from falling into the cache trap: as
-+ * cache pages start out inactive, every cache fault will tip
-+ * the scan balance towards the file LRU. And as the file LRU
-+ * shrinks, so does the window for rotation from references.
-+ * This means we have a runaway feedback loop where a tiny
-+ * thrashing file LRU becomes infinitely more attractive than
-+ * anon pages. Try to detect this based on file LRU size.
-+ */
-+ if (!cgroup_reclaim(sc)) {
-+ unsigned long total_high_wmark = 0;
-+ unsigned long free, anon;
-+ int z;
-+
-+ free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);
-+ file = node_page_state(pgdat, NR_ACTIVE_FILE) +
-+ node_page_state(pgdat, NR_INACTIVE_FILE);
-+
-+ for (z = 0; z < MAX_NR_ZONES; z++) {
-+ struct zone *zone = &pgdat->node_zones[z];
-+
-+ if (!managed_zone(zone))
-+ continue;
-+
-+ total_high_wmark += high_wmark_pages(zone);
-+ }
-+
-+ /*
-+ * Consider anon: if that's low too, this isn't a
-+ * runaway file reclaim problem, but rather just
-+ * extreme pressure. Reclaim as per usual then.
-+ */
-+ anon = node_page_state(pgdat, NR_INACTIVE_ANON);
-+
-+ sc->file_is_tiny =
-+ file + free <= total_high_wmark &&
-+ !(sc->may_deactivate & DEACTIVATE_ANON) &&
-+ anon >> sc->priority;
-+ }
-+}
-+
- /*
- * Determine how aggressively the anon and file LRU lists should be
- * scanned. The relative value of each set of LRU lists is determined
-@@ -2965,109 +3068,16 @@ static void shrink_node(pg_data_t *pgdat
- unsigned long nr_reclaimed, nr_scanned;
- struct lruvec *target_lruvec;
- bool reclaimable = false;
-- unsigned long file;
-
- target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
-
- again:
-- /*
-- * Flush the memory cgroup stats, so that we read accurate per-memcg
-- * lruvec stats for heuristics.
-- */
-- mem_cgroup_flush_stats();
--
- memset(&sc->nr, 0, sizeof(sc->nr));
-
- nr_reclaimed = sc->nr_reclaimed;
- nr_scanned = sc->nr_scanned;
-
-- /*
-- * Determine the scan balance between anon and file LRUs.
-- */
-- spin_lock_irq(&target_lruvec->lru_lock);
-- sc->anon_cost = target_lruvec->anon_cost;
-- sc->file_cost = target_lruvec->file_cost;
-- spin_unlock_irq(&target_lruvec->lru_lock);
--
-- /*
-- * Target desirable inactive:active list ratios for the anon
-- * and file LRU lists.
-- */
-- if (!sc->force_deactivate) {
-- unsigned long refaults;
--
-- refaults = lruvec_page_state(target_lruvec,
-- WORKINGSET_ACTIVATE_ANON);
-- if (refaults != target_lruvec->refaults[0] ||
-- inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
-- sc->may_deactivate |= DEACTIVATE_ANON;
-- else
-- sc->may_deactivate &= ~DEACTIVATE_ANON;
--
-- /*
-- * When refaults are being observed, it means a new
-- * workingset is being established. Deactivate to get
-- * rid of any stale active pages quickly.
-- */
-- refaults = lruvec_page_state(target_lruvec,
-- WORKINGSET_ACTIVATE_FILE);
-- if (refaults != target_lruvec->refaults[1] ||
-- inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
-- sc->may_deactivate |= DEACTIVATE_FILE;
-- else
-- sc->may_deactivate &= ~DEACTIVATE_FILE;
-- } else
-- sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE;
--
-- /*
-- * If we have plenty of inactive file pages that aren't
-- * thrashing, try to reclaim those first before touching
-- * anonymous pages.
-- */
-- file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE);
-- if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE))
-- sc->cache_trim_mode = 1;
-- else
-- sc->cache_trim_mode = 0;
--
-- /*
-- * Prevent the reclaimer from falling into the cache trap: as
-- * cache pages start out inactive, every cache fault will tip
-- * the scan balance towards the file LRU. And as the file LRU
-- * shrinks, so does the window for rotation from references.
-- * This means we have a runaway feedback loop where a tiny
-- * thrashing file LRU becomes infinitely more attractive than
-- * anon pages. Try to detect this based on file LRU size.
-- */
-- if (!cgroup_reclaim(sc)) {
-- unsigned long total_high_wmark = 0;
-- unsigned long free, anon;
-- int z;
--
-- free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);
-- file = node_page_state(pgdat, NR_ACTIVE_FILE) +
-- node_page_state(pgdat, NR_INACTIVE_FILE);
--
-- for (z = 0; z < MAX_NR_ZONES; z++) {
-- struct zone *zone = &pgdat->node_zones[z];
-- if (!managed_zone(zone))
-- continue;
--
-- total_high_wmark += high_wmark_pages(zone);
-- }
--
-- /*
-- * Consider anon: if that's low too, this isn't a
-- * runaway file reclaim problem, but rather just
-- * extreme pressure. Reclaim as per usual then.
-- */
-- anon = node_page_state(pgdat, NR_INACTIVE_ANON);
--
-- sc->file_is_tiny =
-- file + free <= total_high_wmark &&
-- !(sc->may_deactivate & DEACTIVATE_ANON) &&
-- anon >> sc->priority;
-- }
-+ prepare_scan_count(pgdat, sc);
-
- shrink_node_memcgs(pgdat, sc);
-
diff --git a/target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch b/target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch
deleted file mode 100644
index 2f277a56e1..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 03705be42114db7cc5bd6eb7bf7e8703c94d4880 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:01 -0600
-Subject: [PATCH 04/29] Revert "include/linux/mm_inline.h: fold
- __update_lru_size() into its sole caller"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch undoes the following refactor: commit 289ccba18af4
-("include/linux/mm_inline.h: fold __update_lru_size() into its sole
-caller")
-
-The upcoming changes to include/linux/mm_inline.h will reuse
-__update_lru_size().
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-5-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mm_inline.h | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -24,7 +24,7 @@ static inline int page_is_file_lru(struc
- return !PageSwapBacked(page);
- }
-
--static __always_inline void update_lru_size(struct lruvec *lruvec,
-+static __always_inline void __update_lru_size(struct lruvec *lruvec,
- enum lru_list lru, enum zone_type zid,
- int nr_pages)
- {
-@@ -33,6 +33,13 @@ static __always_inline void update_lru_s
- __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);
- __mod_zone_page_state(&pgdat->node_zones[zid],
- NR_ZONE_LRU_BASE + lru, nr_pages);
-+}
-+
-+static __always_inline void update_lru_size(struct lruvec *lruvec,
-+ enum lru_list lru, enum zone_type zid,
-+ long nr_pages)
-+{
-+ __update_lru_size(lruvec, lru, zid, nr_pages);
- #ifdef CONFIG_MEMCG
- mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages);
- #endif
diff --git a/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch b/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch
deleted file mode 100644
index ff4bb4df3e..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch
+++ /dev/null
@@ -1,807 +0,0 @@
-From a9b328add8422921a0dbbef162730800e16e8cfd Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:02 -0600
-Subject: [PATCH 05/29] mm: multi-gen LRU: groundwork
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Evictable pages are divided into multiple generations for each lruvec.
-The youngest generation number is stored in lrugen->max_seq for both
-anon and file types as they are aged on an equal footing. The oldest
-generation numbers are stored in lrugen->min_seq[] separately for anon
-and file types as clean file pages can be evicted regardless of swap
-constraints. These three variables are monotonically increasing.
-
-Generation numbers are truncated into order_base_2(MAX_NR_GENS+1) bits
-in order to fit into the gen counter in page->flags. Each truncated
-generation number is an index to lrugen->lists[]. The sliding window
-technique is used to track at least MIN_NR_GENS and at most
-MAX_NR_GENS generations. The gen counter stores a value within [1,
-MAX_NR_GENS] while a page is on one of lrugen->lists[]. Otherwise it
-stores 0.
-
-There are two conceptually independent procedures: "the aging", which
-produces young generations, and "the eviction", which consumes old
-generations. They form a closed-loop system, i.e., "the page reclaim".
-Both procedures can be invoked from userspace for the purposes of working
-set estimation and proactive reclaim. These techniques are commonly used
-to optimize job scheduling (bin packing) in data centers [1][2].
-
-To avoid confusion, the terms "hot" and "cold" will be applied to the
-multi-gen LRU, as a new convention; the terms "active" and "inactive" will
-be applied to the active/inactive LRU, as usual.
-
-The protection of hot pages and the selection of cold pages are based
-on page access channels and patterns. There are two access channels:
-one through page tables and the other through file descriptors. The
-protection of the former channel is by design stronger because:
-1. The uncertainty in determining the access patterns of the former
- channel is higher due to the approximation of the accessed bit.
-2. The cost of evicting the former channel is higher due to the TLB
- flushes required and the likelihood of encountering the dirty bit.
-3. The penalty of underprotecting the former channel is higher because
- applications usually do not prepare themselves for major page
- faults like they do for blocked I/O. E.g., GUI applications
- commonly use dedicated I/O threads to avoid blocking rendering
- threads.
-
-There are also two access patterns: one with temporal locality and the
-other without. For the reasons listed above, the former channel is
-assumed to follow the former pattern unless VM_SEQ_READ or VM_RAND_READ is
-present; the latter channel is assumed to follow the latter pattern unless
-outlying refaults have been observed [3][4].
-
-The next patch will address the "outlying refaults". Three macros, i.e.,
-LRU_REFS_WIDTH, LRU_REFS_PGOFF and LRU_REFS_MASK, used later are added in
-this patch to make the entire patchset less diffy.
-
-A page is added to the youngest generation on faulting. The aging needs
-to check the accessed bit at least twice before handing this page over to
-the eviction. The first check takes care of the accessed bit set on the
-initial fault; the second check makes sure this page has not been used
-since then. This protocol, AKA second chance, requires a minimum of two
-generations, hence MIN_NR_GENS.
-
-[1] https://dl.acm.org/doi/10.1145/3297858.3304053
-[2] https://dl.acm.org/doi/10.1145/3503222.3507731
-[3] https://lwn.net/Articles/495543/
-[4] https://lwn.net/Articles/815342/
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-6-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- fs/fuse/dev.c | 3 +-
- include/linux/mm.h | 2 +
- include/linux/mm_inline.h | 177 +++++++++++++++++++++++++++++-
- include/linux/mmzone.h | 100 +++++++++++++++++
- include/linux/page-flags-layout.h | 13 ++-
- include/linux/page-flags.h | 4 +-
- include/linux/sched.h | 4 +
- kernel/bounds.c | 5 +
- mm/Kconfig | 8 ++
- mm/huge_memory.c | 3 +-
- mm/memcontrol.c | 2 +
- mm/memory.c | 25 +++++
- mm/mm_init.c | 6 +-
- mm/mmzone.c | 2 +
- mm/swap.c | 10 +-
- mm/vmscan.c | 75 +++++++++++++
- 16 files changed, 425 insertions(+), 14 deletions(-)
-
---- a/fs/fuse/dev.c
-+++ b/fs/fuse/dev.c
-@@ -785,7 +785,8 @@ static int fuse_check_page(struct page *
- 1 << PG_active |
- 1 << PG_workingset |
- 1 << PG_reclaim |
-- 1 << PG_waiters))) {
-+ 1 << PG_waiters |
-+ LRU_GEN_MASK | LRU_REFS_MASK))) {
- dump_page(page, "fuse: trying to steal weird page");
- return 1;
- }
---- a/include/linux/mm.h
-+++ b/include/linux/mm.h
-@@ -1093,6 +1093,8 @@ vm_fault_t finish_mkwrite_fault(struct v
- #define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH)
- #define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH)
- #define KASAN_TAG_PGOFF (LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH)
-+#define LRU_GEN_PGOFF (KASAN_TAG_PGOFF - LRU_GEN_WIDTH)
-+#define LRU_REFS_PGOFF (LRU_GEN_PGOFF - LRU_REFS_WIDTH)
-
- /*
- * Define the bit shifts to access each section. For non-existent
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -26,10 +26,13 @@ static inline int page_is_file_lru(struc
-
- static __always_inline void __update_lru_size(struct lruvec *lruvec,
- enum lru_list lru, enum zone_type zid,
-- int nr_pages)
-+ long nr_pages)
- {
- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-
-+ lockdep_assert_held(&lruvec->lru_lock);
-+ WARN_ON_ONCE(nr_pages != (int)nr_pages);
-+
- __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);
- __mod_zone_page_state(&pgdat->node_zones[zid],
- NR_ZONE_LRU_BASE + lru, nr_pages);
-@@ -86,11 +89,177 @@ static __always_inline enum lru_list pag
- return lru;
- }
-
-+#ifdef CONFIG_LRU_GEN
-+
-+static inline bool lru_gen_enabled(void)
-+{
-+ return true;
-+}
-+
-+static inline bool lru_gen_in_fault(void)
-+{
-+ return current->in_lru_fault;
-+}
-+
-+static inline int lru_gen_from_seq(unsigned long seq)
-+{
-+ return seq % MAX_NR_GENS;
-+}
-+
-+static inline int page_lru_gen(struct page *page)
-+{
-+ unsigned long flags = READ_ONCE(page->flags);
-+
-+ return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
-+}
-+
-+static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen)
-+{
-+ unsigned long max_seq = lruvec->lrugen.max_seq;
-+
-+ VM_WARN_ON_ONCE(gen >= MAX_NR_GENS);
-+
-+ /* see the comment on MIN_NR_GENS */
-+ return gen == lru_gen_from_seq(max_seq) || gen == lru_gen_from_seq(max_seq - 1);
-+}
-+
-+static inline void lru_gen_update_size(struct lruvec *lruvec, struct page *page,
-+ int old_gen, int new_gen)
-+{
-+ int type = page_is_file_lru(page);
-+ int zone = page_zonenum(page);
-+ int delta = thp_nr_pages(page);
-+ enum lru_list lru = type * LRU_INACTIVE_FILE;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
-+ VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
-+ VM_WARN_ON_ONCE(old_gen == -1 && new_gen == -1);
-+
-+ if (old_gen >= 0)
-+ WRITE_ONCE(lrugen->nr_pages[old_gen][type][zone],
-+ lrugen->nr_pages[old_gen][type][zone] - delta);
-+ if (new_gen >= 0)
-+ WRITE_ONCE(lrugen->nr_pages[new_gen][type][zone],
-+ lrugen->nr_pages[new_gen][type][zone] + delta);
-+
-+ /* addition */
-+ if (old_gen < 0) {
-+ if (lru_gen_is_active(lruvec, new_gen))
-+ lru += LRU_ACTIVE;
-+ __update_lru_size(lruvec, lru, zone, delta);
-+ return;
-+ }
-+
-+ /* deletion */
-+ if (new_gen < 0) {
-+ if (lru_gen_is_active(lruvec, old_gen))
-+ lru += LRU_ACTIVE;
-+ __update_lru_size(lruvec, lru, zone, -delta);
-+ return;
-+ }
-+}
-+
-+static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
-+{
-+ unsigned long seq;
-+ unsigned long flags;
-+ int gen = page_lru_gen(page);
-+ int type = page_is_file_lru(page);
-+ int zone = page_zonenum(page);
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ VM_WARN_ON_ONCE_PAGE(gen != -1, page);
-+
-+ if (PageUnevictable(page))
-+ return false;
-+ /*
-+ * There are three common cases for this page:
-+ * 1. If it's hot, e.g., freshly faulted in or previously hot and
-+ * migrated, add it to the youngest generation.
-+ * 2. If it's cold but can't be evicted immediately, i.e., an anon page
-+ * not in swapcache or a dirty page pending writeback, add it to the
-+ * second oldest generation.
-+ * 3. Everything else (clean, cold) is added to the oldest generation.
-+ */
-+ if (PageActive(page))
-+ seq = lrugen->max_seq;
-+ else if ((type == LRU_GEN_ANON && !PageSwapCache(page)) ||
-+ (PageReclaim(page) &&
-+ (PageDirty(page) || PageWriteback(page))))
-+ seq = lrugen->min_seq[type] + 1;
-+ else
-+ seq = lrugen->min_seq[type];
-+
-+ gen = lru_gen_from_seq(seq);
-+ flags = (gen + 1UL) << LRU_GEN_PGOFF;
-+ /* see the comment on MIN_NR_GENS about PG_active */
-+ set_mask_bits(&page->flags, LRU_GEN_MASK | BIT(PG_active), flags);
-+
-+ lru_gen_update_size(lruvec, page, -1, gen);
-+ /* for rotate_reclaimable_page() */
-+ if (reclaiming)
-+ list_add_tail(&page->lru, &lrugen->lists[gen][type][zone]);
-+ else
-+ list_add(&page->lru, &lrugen->lists[gen][type][zone]);
-+
-+ return true;
-+}
-+
-+static inline bool lru_gen_del_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
-+{
-+ unsigned long flags;
-+ int gen = page_lru_gen(page);
-+
-+ if (gen < 0)
-+ return false;
-+
-+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page);
-+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page);
-+
-+ /* for migrate_page_states() */
-+ flags = !reclaiming && lru_gen_is_active(lruvec, gen) ? BIT(PG_active) : 0;
-+ flags = set_mask_bits(&page->flags, LRU_GEN_MASK, flags);
-+ gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
-+
-+ lru_gen_update_size(lruvec, page, gen, -1);
-+ list_del(&page->lru);
-+
-+ return true;
-+}
-+
-+#else /* !CONFIG_LRU_GEN */
-+
-+static inline bool lru_gen_enabled(void)
-+{
-+ return false;
-+}
-+
-+static inline bool lru_gen_in_fault(void)
-+{
-+ return false;
-+}
-+
-+static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
-+{
-+ return false;
-+}
-+
-+static inline bool lru_gen_del_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
-+{
-+ return false;
-+}
-+
-+#endif /* CONFIG_LRU_GEN */
-+
- static __always_inline void add_page_to_lru_list(struct page *page,
- struct lruvec *lruvec)
- {
- enum lru_list lru = page_lru(page);
-
-+ if (lru_gen_add_page(lruvec, page, false))
-+ return;
-+
- update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
- list_add(&page->lru, &lruvec->lists[lru]);
- }
-@@ -100,6 +269,9 @@ static __always_inline void add_page_to_
- {
- enum lru_list lru = page_lru(page);
-
-+ if (lru_gen_add_page(lruvec, page, true))
-+ return;
-+
- update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
- list_add_tail(&page->lru, &lruvec->lists[lru]);
- }
-@@ -107,6 +279,9 @@ static __always_inline void add_page_to_
- static __always_inline void del_page_from_lru_list(struct page *page,
- struct lruvec *lruvec)
- {
-+ if (lru_gen_del_page(lruvec, page, false))
-+ return;
-+
- list_del(&page->lru);
- update_lru_size(lruvec, page_lru(page), page_zonenum(page),
- -thp_nr_pages(page));
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -294,6 +294,102 @@ enum lruvec_flags {
- */
- };
-
-+#endif /* !__GENERATING_BOUNDS_H */
-+
-+/*
-+ * Evictable pages are divided into multiple generations. The youngest and the
-+ * oldest generation numbers, max_seq and min_seq, are monotonically increasing.
-+ * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An
-+ * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the
-+ * corresponding generation. The gen counter in page->flags stores gen+1 while
-+ * a page is on one of lrugen->lists[]. Otherwise it stores 0.
-+ *
-+ * A page is added to the youngest generation on faulting. The aging needs to
-+ * check the accessed bit at least twice before handing this page over to the
-+ * eviction. The first check takes care of the accessed bit set on the initial
-+ * fault; the second check makes sure this page hasn't been used since then.
-+ * This process, AKA second chance, requires a minimum of two generations,
-+ * hence MIN_NR_GENS. And to maintain ABI compatibility with the active/inactive
-+ * LRU, e.g., /proc/vmstat, these two generations are considered active; the
-+ * rest of generations, if they exist, are considered inactive. See
-+ * lru_gen_is_active().
-+ *
-+ * PG_active is always cleared while a page is on one of lrugen->lists[] so that
-+ * the aging needs not to worry about it. And it's set again when a page
-+ * considered active is isolated for non-reclaiming purposes, e.g., migration.
-+ * See lru_gen_add_page() and lru_gen_del_page().
-+ *
-+ * MAX_NR_GENS is set to 4 so that the multi-gen LRU can support twice the
-+ * number of categories of the active/inactive LRU when keeping track of
-+ * accesses through page tables. This requires order_base_2(MAX_NR_GENS+1) bits
-+ * in page->flags.
-+ */
-+#define MIN_NR_GENS 2U
-+#define MAX_NR_GENS 4U
-+
-+#ifndef __GENERATING_BOUNDS_H
-+
-+struct lruvec;
-+
-+#define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
-+#define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
-+
-+#ifdef CONFIG_LRU_GEN
-+
-+enum {
-+ LRU_GEN_ANON,
-+ LRU_GEN_FILE,
-+};
-+
-+/*
-+ * The youngest generation number is stored in max_seq for both anon and file
-+ * types as they are aged on an equal footing. The oldest generation numbers are
-+ * stored in min_seq[] separately for anon and file types as clean file pages
-+ * can be evicted regardless of swap constraints.
-+ *
-+ * Normally anon and file min_seq are in sync. But if swapping is constrained,
-+ * e.g., out of swap space, file min_seq is allowed to advance and leave anon
-+ * min_seq behind.
-+ *
-+ * The number of pages in each generation is eventually consistent and therefore
-+ * can be transiently negative.
-+ */
-+struct lru_gen_struct {
-+ /* the aging increments the youngest generation number */
-+ unsigned long max_seq;
-+ /* the eviction increments the oldest generation numbers */
-+ unsigned long min_seq[ANON_AND_FILE];
-+ /* the multi-gen LRU lists, lazily sorted on eviction */
-+ struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
-+ /* the multi-gen LRU sizes, eventually consistent */
-+ long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
-+};
-+
-+void lru_gen_init_lruvec(struct lruvec *lruvec);
-+
-+#ifdef CONFIG_MEMCG
-+void lru_gen_init_memcg(struct mem_cgroup *memcg);
-+void lru_gen_exit_memcg(struct mem_cgroup *memcg);
-+#endif
-+
-+#else /* !CONFIG_LRU_GEN */
-+
-+static inline void lru_gen_init_lruvec(struct lruvec *lruvec)
-+{
-+}
-+
-+#ifdef CONFIG_MEMCG
-+static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+#endif
-+
-+#endif /* CONFIG_LRU_GEN */
-+
- struct lruvec {
- struct list_head lists[NR_LRU_LISTS];
- /* per lruvec lru_lock for memcg */
-@@ -311,6 +407,10 @@ struct lruvec {
- unsigned long refaults[ANON_AND_FILE];
- /* Various lruvec state flags (enum lruvec_flags) */
- unsigned long flags;
-+#ifdef CONFIG_LRU_GEN
-+ /* evictable pages divided into generations */
-+ struct lru_gen_struct lrugen;
-+#endif
- #ifdef CONFIG_MEMCG
- struct pglist_data *pgdat;
- #endif
---- a/include/linux/page-flags-layout.h
-+++ b/include/linux/page-flags-layout.h
-@@ -55,7 +55,8 @@
- #define SECTIONS_WIDTH 0
- #endif
-
--#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
-+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_SHIFT \
-+ <= BITS_PER_LONG - NR_PAGEFLAGS
- #define NODES_WIDTH NODES_SHIFT
- #elif defined(CONFIG_SPARSEMEM_VMEMMAP)
- #error "Vmemmap: No space for nodes field in page flags"
-@@ -89,8 +90,8 @@
- #define LAST_CPUPID_SHIFT 0
- #endif
-
--#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT \
-- <= BITS_PER_LONG - NR_PAGEFLAGS
-+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \
-+ KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
- #define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT
- #else
- #define LAST_CPUPID_WIDTH 0
-@@ -100,10 +101,12 @@
- #define LAST_CPUPID_NOT_IN_PAGE_FLAGS
- #endif
-
--#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH \
-- > BITS_PER_LONG - NR_PAGEFLAGS
-+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \
-+ KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS
- #error "Not enough bits in page flags"
- #endif
-
-+#define LRU_REFS_WIDTH 0
-+
- #endif
- #endif /* _LINUX_PAGE_FLAGS_LAYOUT */
---- a/include/linux/page-flags.h
-+++ b/include/linux/page-flags.h
-@@ -845,7 +845,7 @@ static inline void ClearPageSlabPfmemall
- 1UL << PG_private | 1UL << PG_private_2 | \
- 1UL << PG_writeback | 1UL << PG_reserved | \
- 1UL << PG_slab | 1UL << PG_active | \
-- 1UL << PG_unevictable | __PG_MLOCKED)
-+ 1UL << PG_unevictable | __PG_MLOCKED | LRU_GEN_MASK)
-
- /*
- * Flags checked when a page is prepped for return by the page allocator.
-@@ -856,7 +856,7 @@ static inline void ClearPageSlabPfmemall
- * alloc-free cycle to prevent from reusing the page.
- */
- #define PAGE_FLAGS_CHECK_AT_PREP \
-- (PAGEFLAGS_MASK & ~__PG_HWPOISON)
-+ ((PAGEFLAGS_MASK & ~__PG_HWPOISON) | LRU_GEN_MASK | LRU_REFS_MASK)
-
- #define PAGE_FLAGS_PRIVATE \
- (1UL << PG_private | 1UL << PG_private_2)
---- a/include/linux/sched.h
-+++ b/include/linux/sched.h
-@@ -907,6 +907,10 @@ struct task_struct {
- #ifdef CONFIG_MEMCG
- unsigned in_user_fault:1;
- #endif
-+#ifdef CONFIG_LRU_GEN
-+ /* whether the LRU algorithm may apply to this access */
-+ unsigned in_lru_fault:1;
-+#endif
- #ifdef CONFIG_COMPAT_BRK
- unsigned brk_randomized:1;
- #endif
---- a/kernel/bounds.c
-+++ b/kernel/bounds.c
-@@ -22,6 +22,11 @@ int main(void)
- DEFINE(NR_CPUS_BITS, order_base_2(CONFIG_NR_CPUS));
- #endif
- DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
-+#ifdef CONFIG_LRU_GEN
-+ DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1));
-+#else
-+ DEFINE(LRU_GEN_WIDTH, 0);
-+#endif
- /* End of constants */
-
- return 0;
---- a/mm/Kconfig
-+++ b/mm/Kconfig
-@@ -897,6 +897,14 @@ config IO_MAPPING
- config SECRETMEM
- def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED
-
-+config LRU_GEN
-+ bool "Multi-Gen LRU"
-+ depends on MMU
-+ # make sure page->flags has enough spare bits
-+ depends on 64BIT || !SPARSEMEM || SPARSEMEM_VMEMMAP
-+ help
-+ A high performance LRU implementation to overcommit memory.
-+
- source "mm/damon/Kconfig"
-
- endmenu
---- a/mm/huge_memory.c
-+++ b/mm/huge_memory.c
-@@ -2366,7 +2366,8 @@ static void __split_huge_page_tail(struc
- #ifdef CONFIG_64BIT
- (1L << PG_arch_2) |
- #endif
-- (1L << PG_dirty)));
-+ (1L << PG_dirty) |
-+ LRU_GEN_MASK | LRU_REFS_MASK));
-
- /* ->mapping in first tail page is compound_mapcount */
- VM_BUG_ON_PAGE(tail > 2 && page_tail->mapping != TAIL_MAPPING,
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -5179,6 +5179,7 @@ static void __mem_cgroup_free(struct mem
-
- static void mem_cgroup_free(struct mem_cgroup *memcg)
- {
-+ lru_gen_exit_memcg(memcg);
- memcg_wb_domain_exit(memcg);
- __mem_cgroup_free(memcg);
- }
-@@ -5242,6 +5243,7 @@ static struct mem_cgroup *mem_cgroup_all
- memcg->deferred_split_queue.split_queue_len = 0;
- #endif
- idr_replace(&mem_cgroup_idr, memcg, memcg->id.id);
-+ lru_gen_init_memcg(memcg);
- return memcg;
- fail:
- mem_cgroup_id_remove(memcg);
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -4805,6 +4805,27 @@ static inline void mm_account_fault(stru
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
- }
-
-+#ifdef CONFIG_LRU_GEN
-+static void lru_gen_enter_fault(struct vm_area_struct *vma)
-+{
-+ /* the LRU algorithm doesn't apply to sequential or random reads */
-+ current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ));
-+}
-+
-+static void lru_gen_exit_fault(void)
-+{
-+ current->in_lru_fault = false;
-+}
-+#else
-+static void lru_gen_enter_fault(struct vm_area_struct *vma)
-+{
-+}
-+
-+static void lru_gen_exit_fault(void)
-+{
-+}
-+#endif /* CONFIG_LRU_GEN */
-+
- /*
- * By the time we get here, we already hold the mm semaphore
- *
-@@ -4836,11 +4857,15 @@ vm_fault_t handle_mm_fault(struct vm_are
- if (flags & FAULT_FLAG_USER)
- mem_cgroup_enter_user_fault();
-
-+ lru_gen_enter_fault(vma);
-+
- if (unlikely(is_vm_hugetlb_page(vma)))
- ret = hugetlb_fault(vma->vm_mm, vma, address, flags);
- else
- ret = __handle_mm_fault(vma, address, flags);
-
-+ lru_gen_exit_fault();
-+
- if (flags & FAULT_FLAG_USER) {
- mem_cgroup_exit_user_fault();
- /*
---- a/mm/mm_init.c
-+++ b/mm/mm_init.c
-@@ -65,14 +65,16 @@ void __init mminit_verify_pageflags_layo
-
- shift = 8 * sizeof(unsigned long);
- width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH
-- - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH;
-+ - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH - LRU_GEN_WIDTH - LRU_REFS_WIDTH;
- mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths",
-- "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Flags %d\n",
-+ "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Gen %d Tier %d Flags %d\n",
- SECTIONS_WIDTH,
- NODES_WIDTH,
- ZONES_WIDTH,
- LAST_CPUPID_WIDTH,
- KASAN_TAG_WIDTH,
-+ LRU_GEN_WIDTH,
-+ LRU_REFS_WIDTH,
- NR_PAGEFLAGS);
- mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts",
- "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d\n",
---- a/mm/mmzone.c
-+++ b/mm/mmzone.c
-@@ -81,6 +81,8 @@ void lruvec_init(struct lruvec *lruvec)
-
- for_each_lru(lru)
- INIT_LIST_HEAD(&lruvec->lists[lru]);
-+
-+ lru_gen_init_lruvec(lruvec);
- }
-
- #if defined(CONFIG_NUMA_BALANCING) && !defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS)
---- a/mm/swap.c
-+++ b/mm/swap.c
-@@ -446,6 +446,11 @@ void lru_cache_add(struct page *page)
- VM_BUG_ON_PAGE(PageActive(page) && PageUnevictable(page), page);
- VM_BUG_ON_PAGE(PageLRU(page), page);
-
-+ /* see the comment in lru_gen_add_page() */
-+ if (lru_gen_enabled() && !PageUnevictable(page) &&
-+ lru_gen_in_fault() && !(current->flags & PF_MEMALLOC))
-+ SetPageActive(page);
-+
- get_page(page);
- local_lock(&lru_pvecs.lock);
- pvec = this_cpu_ptr(&lru_pvecs.lru_add);
-@@ -547,7 +552,7 @@ static void lru_deactivate_file_fn(struc
-
- static void lru_deactivate_fn(struct page *page, struct lruvec *lruvec)
- {
-- if (PageActive(page) && !PageUnevictable(page)) {
-+ if (!PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) {
- int nr_pages = thp_nr_pages(page);
-
- del_page_from_lru_list(page, lruvec);
-@@ -661,7 +666,8 @@ void deactivate_file_page(struct page *p
- */
- void deactivate_page(struct page *page)
- {
-- if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) {
-+ if (PageLRU(page) && !PageUnevictable(page) &&
-+ (PageActive(page) || lru_gen_enabled())) {
- struct pagevec *pvec;
-
- local_lock(&lru_pvecs.lock);
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -2821,6 +2821,81 @@ static bool can_age_anon_pages(struct pg
- return can_demote(pgdat->node_id, sc);
- }
-
-+#ifdef CONFIG_LRU_GEN
-+
-+/******************************************************************************
-+ * shorthand helpers
-+ ******************************************************************************/
-+
-+#define for_each_gen_type_zone(gen, type, zone) \
-+ for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++) \
-+ for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
-+ for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
-+
-+static struct lruvec __maybe_unused *get_lruvec(struct mem_cgroup *memcg, int nid)
-+{
-+ struct pglist_data *pgdat = NODE_DATA(nid);
-+
-+#ifdef CONFIG_MEMCG
-+ if (memcg) {
-+ struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec;
-+
-+ /* for hotadd_new_pgdat() */
-+ if (!lruvec->pgdat)
-+ lruvec->pgdat = pgdat;
-+
-+ return lruvec;
-+ }
-+#endif
-+ VM_WARN_ON_ONCE(!mem_cgroup_disabled());
-+
-+ return pgdat ? &pgdat->__lruvec : NULL;
-+}
-+
-+/******************************************************************************
-+ * initialization
-+ ******************************************************************************/
-+
-+void lru_gen_init_lruvec(struct lruvec *lruvec)
-+{
-+ int gen, type, zone;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ lrugen->max_seq = MIN_NR_GENS + 1;
-+
-+ for_each_gen_type_zone(gen, type, zone)
-+ INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]);
-+}
-+
-+#ifdef CONFIG_MEMCG
-+void lru_gen_init_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+void lru_gen_exit_memcg(struct mem_cgroup *memcg)
-+{
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
-+ sizeof(lruvec->lrugen.nr_pages)));
-+ }
-+}
-+#endif
-+
-+static int __init init_lru_gen(void)
-+{
-+ BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS);
-+ BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS);
-+
-+ return 0;
-+};
-+late_initcall(init_lru_gen);
-+
-+#endif /* CONFIG_LRU_GEN */
-+
- static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
- unsigned long nr[NR_LRU_LISTS];
diff --git a/target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch b/target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch
deleted file mode 100644
index 14fc73f84d..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch
+++ /dev/null
@@ -1,1447 +0,0 @@
-From b564b9471cd60ef1ee3961a224898ce4a9620d84 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:03 -0600
-Subject: [PATCH 06/29] mm: multi-gen LRU: minimal implementation
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-To avoid confusion, the terms "promotion" and "demotion" will be applied
-to the multi-gen LRU, as a new convention; the terms "activation" and
-"deactivation" will be applied to the active/inactive LRU, as usual.
-
-The aging produces young generations. Given an lruvec, it increments
-max_seq when max_seq-min_seq+1 approaches MIN_NR_GENS. The aging promotes
-hot pages to the youngest generation when it finds them accessed through
-page tables; the demotion of cold pages happens consequently when it
-increments max_seq. Promotion in the aging path does not involve any LRU
-list operations, only the updates of the gen counter and
-lrugen->nr_pages[]; demotion, unless as the result of the increment of
-max_seq, requires LRU list operations, e.g., lru_deactivate_fn(). The
-aging has the complexity O(nr_hot_pages), since it is only interested in
-hot pages.
-
-The eviction consumes old generations. Given an lruvec, it increments
-min_seq when lrugen->lists[] indexed by min_seq%MAX_NR_GENS becomes empty.
-A feedback loop modeled after the PID controller monitors refaults over
-anon and file types and decides which type to evict when both types are
-available from the same generation.
-
-The protection of pages accessed multiple times through file descriptors
-takes place in the eviction path. Each generation is divided into
-multiple tiers. A page accessed N times through file descriptors is in
-tier order_base_2(N). Tiers do not have dedicated lrugen->lists[], only
-bits in page->flags. The aforementioned feedback loop also monitors
-refaults over all tiers and decides when to protect pages in which tiers
-(N>1), using the first tier (N=0,1) as a baseline. The first tier
-contains single-use unmapped clean pages, which are most likely the best
-choices. In contrast to promotion in the aging path, the protection of a
-page in the eviction path is achieved by moving this page to the next
-generation, i.e., min_seq+1, if the feedback loop decides so. This
-approach has the following advantages:
-
-1. It removes the cost of activation in the buffered access path by
- inferring whether pages accessed multiple times through file
- descriptors are statistically hot and thus worth protecting in the
- eviction path.
-2. It takes pages accessed through page tables into account and avoids
- overprotecting pages accessed multiple times through file
- descriptors. (Pages accessed through page tables are in the first
- tier, since N=0.)
-3. More tiers provide better protection for pages accessed more than
- twice through file descriptors, when under heavy buffered I/O
- workloads.
-
-Server benchmark results:
- Single workload:
- fio (buffered I/O): +[30, 32]%
- IOPS BW
- 5.19-rc1: 2673k 10.2GiB/s
- patch1-6: 3491k 13.3GiB/s
-
- Single workload:
- memcached (anon): -[4, 6]%
- Ops/sec KB/sec
- 5.19-rc1: 1161501.04 45177.25
- patch1-6: 1106168.46 43025.04
-
- Configurations:
- CPU: two Xeon 6154
- Mem: total 256G
-
- Node 1 was only used as a ram disk to reduce the variance in the
- results.
-
- patch drivers/block/brd.c <<EOF
- 99,100c99,100
- < gfp_flags = GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM;
- < page = alloc_page(gfp_flags);
- ---
- > gfp_flags = GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM | __GFP_THISNODE;
- > page = alloc_pages_node(1, gfp_flags, 0);
- EOF
-
- cat >>/etc/systemd/system.conf <<EOF
- CPUAffinity=numa
- NUMAPolicy=bind
- NUMAMask=0
- EOF
-
- cat >>/etc/memcached.conf <<EOF
- -m 184320
- -s /var/run/memcached/memcached.sock
- -a 0766
- -t 36
- -B binary
- EOF
-
- cat fio.sh
- modprobe brd rd_nr=1 rd_size=113246208
- swapoff -a
- mkfs.ext4 /dev/ram0
- mount -t ext4 /dev/ram0 /mnt
-
- mkdir /sys/fs/cgroup/user.slice/test
- echo 38654705664 >/sys/fs/cgroup/user.slice/test/memory.max
- echo $$ >/sys/fs/cgroup/user.slice/test/cgroup.procs
- fio -name=mglru --numjobs=72 --directory=/mnt --size=1408m \
- --buffered=1 --ioengine=io_uring --iodepth=128 \
- --iodepth_batch_submit=32 --iodepth_batch_complete=32 \
- --rw=randread --random_distribution=random --norandommap \
- --time_based --ramp_time=10m --runtime=5m --group_reporting
-
- cat memcached.sh
- modprobe brd rd_nr=1 rd_size=113246208
- swapoff -a
- mkswap /dev/ram0
- swapon /dev/ram0
-
- memtier_benchmark -S /var/run/memcached/memcached.sock \
- -P memcache_binary -n allkeys --key-minimum=1 \
- --key-maximum=65000000 --key-pattern=P:P -c 1 -t 36 \
- --ratio 1:0 --pipeline 8 -d 2000
-
- memtier_benchmark -S /var/run/memcached/memcached.sock \
- -P memcache_binary -n allkeys --key-minimum=1 \
- --key-maximum=65000000 --key-pattern=R:R -c 1 -t 36 \
- --ratio 0:1 --pipeline 8 --randomize --distinct-client-seed
-
-Client benchmark results:
- kswapd profiles:
- 5.19-rc1
- 40.33% page_vma_mapped_walk (overhead)
- 21.80% lzo1x_1_do_compress (real work)
- 7.53% do_raw_spin_lock
- 3.95% _raw_spin_unlock_irq
- 2.52% vma_interval_tree_iter_next
- 2.37% page_referenced_one
- 2.28% vma_interval_tree_subtree_search
- 1.97% anon_vma_interval_tree_iter_first
- 1.60% ptep_clear_flush
- 1.06% __zram_bvec_write
-
- patch1-6
- 39.03% lzo1x_1_do_compress (real work)
- 18.47% page_vma_mapped_walk (overhead)
- 6.74% _raw_spin_unlock_irq
- 3.97% do_raw_spin_lock
- 2.49% ptep_clear_flush
- 2.48% anon_vma_interval_tree_iter_first
- 1.92% page_referenced_one
- 1.88% __zram_bvec_write
- 1.48% memmove
- 1.31% vma_interval_tree_iter_next
-
- Configurations:
- CPU: single Snapdragon 7c
- Mem: total 4G
-
- ChromeOS MemoryPressure [1]
-
-[1] https://chromium.googlesource.com/chromiumos/platform/tast-tests/
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-7-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mm_inline.h | 36 ++
- include/linux/mmzone.h | 41 ++
- include/linux/page-flags-layout.h | 5 +-
- kernel/bounds.c | 2 +
- mm/Kconfig | 11 +
- mm/swap.c | 39 ++
- mm/vmscan.c | 792 +++++++++++++++++++++++++++++-
- mm/workingset.c | 110 ++++-
- 8 files changed, 1025 insertions(+), 11 deletions(-)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -106,6 +106,33 @@ static inline int lru_gen_from_seq(unsig
- return seq % MAX_NR_GENS;
- }
-
-+static inline int lru_hist_from_seq(unsigned long seq)
-+{
-+ return seq % NR_HIST_GENS;
-+}
-+
-+static inline int lru_tier_from_refs(int refs)
-+{
-+ VM_WARN_ON_ONCE(refs > BIT(LRU_REFS_WIDTH));
-+
-+ /* see the comment in page_lru_refs() */
-+ return order_base_2(refs + 1);
-+}
-+
-+static inline int page_lru_refs(struct page *page)
-+{
-+ unsigned long flags = READ_ONCE(page->flags);
-+ bool workingset = flags & BIT(PG_workingset);
-+
-+ /*
-+ * Return the number of accesses beyond PG_referenced, i.e., N-1 if the
-+ * total number of accesses is N>1, since N=0,1 both map to the first
-+ * tier. lru_tier_from_refs() will account for this off-by-one. Also see
-+ * the comment on MAX_NR_TIERS.
-+ */
-+ return ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + workingset;
-+}
-+
- static inline int page_lru_gen(struct page *page)
- {
- unsigned long flags = READ_ONCE(page->flags);
-@@ -158,6 +185,15 @@ static inline void lru_gen_update_size(s
- __update_lru_size(lruvec, lru, zone, -delta);
- return;
- }
-+
-+ /* promotion */
-+ if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) {
-+ __update_lru_size(lruvec, lru, zone, -delta);
-+ __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, delta);
-+ }
-+
-+ /* demotion requires isolation, e.g., lru_deactivate_fn() */
-+ VM_WARN_ON_ONCE(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_active(lruvec, new_gen));
- }
-
- static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -327,6 +327,28 @@ enum lruvec_flags {
- #define MIN_NR_GENS 2U
- #define MAX_NR_GENS 4U
-
-+/*
-+ * Each generation is divided into multiple tiers. A page accessed N times
-+ * through file descriptors is in tier order_base_2(N). A page in the first tier
-+ * (N=0,1) is marked by PG_referenced unless it was faulted in through page
-+ * tables or read ahead. A page in any other tier (N>1) is marked by
-+ * PG_referenced and PG_workingset. This implies a minimum of two tiers is
-+ * supported without using additional bits in page->flags.
-+ *
-+ * In contrast to moving across generations which requires the LRU lock, moving
-+ * across tiers only involves atomic operations on page->flags and therefore
-+ * has a negligible cost in the buffered access path. In the eviction path,
-+ * comparisons of refaulted/(evicted+protected) from the first tier and the
-+ * rest infer whether pages accessed multiple times through file descriptors
-+ * are statistically hot and thus worth protecting.
-+ *
-+ * MAX_NR_TIERS is set to 4 so that the multi-gen LRU can support twice the
-+ * number of categories of the active/inactive LRU when keeping track of
-+ * accesses through file descriptors. This uses MAX_NR_TIERS-2 spare bits in
-+ * page->flags.
-+ */
-+#define MAX_NR_TIERS 4U
-+
- #ifndef __GENERATING_BOUNDS_H
-
- struct lruvec;
-@@ -341,6 +363,16 @@ enum {
- LRU_GEN_FILE,
- };
-
-+#define MIN_LRU_BATCH BITS_PER_LONG
-+#define MAX_LRU_BATCH (MIN_LRU_BATCH * 64)
-+
-+/* whether to keep historical stats from evicted generations */
-+#ifdef CONFIG_LRU_GEN_STATS
-+#define NR_HIST_GENS MAX_NR_GENS
-+#else
-+#define NR_HIST_GENS 1U
-+#endif
-+
- /*
- * The youngest generation number is stored in max_seq for both anon and file
- * types as they are aged on an equal footing. The oldest generation numbers are
-@@ -363,6 +395,15 @@ struct lru_gen_struct {
- struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
- /* the multi-gen LRU sizes, eventually consistent */
- long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
-+ /* the exponential moving average of refaulted */
-+ unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS];
-+ /* the exponential moving average of evicted+protected */
-+ unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS];
-+ /* the first tier doesn't need protection, hence the minus one */
-+ unsigned long protected[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS - 1];
-+ /* can be modified without holding the LRU lock */
-+ atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
-+ atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
- };
-
- void lru_gen_init_lruvec(struct lruvec *lruvec);
---- a/include/linux/page-flags-layout.h
-+++ b/include/linux/page-flags-layout.h
-@@ -106,7 +106,10 @@
- #error "Not enough bits in page flags"
- #endif
-
--#define LRU_REFS_WIDTH 0
-+/* see the comment on MAX_NR_TIERS */
-+#define LRU_REFS_WIDTH min(__LRU_REFS_WIDTH, BITS_PER_LONG - NR_PAGEFLAGS - \
-+ ZONES_WIDTH - LRU_GEN_WIDTH - SECTIONS_WIDTH - \
-+ NODES_WIDTH - KASAN_TAG_WIDTH - LAST_CPUPID_WIDTH)
-
- #endif
- #endif /* _LINUX_PAGE_FLAGS_LAYOUT */
---- a/kernel/bounds.c
-+++ b/kernel/bounds.c
-@@ -24,8 +24,10 @@ int main(void)
- DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
- #ifdef CONFIG_LRU_GEN
- DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1));
-+ DEFINE(__LRU_REFS_WIDTH, MAX_NR_TIERS - 2);
- #else
- DEFINE(LRU_GEN_WIDTH, 0);
-+ DEFINE(__LRU_REFS_WIDTH, 0);
- #endif
- /* End of constants */
-
---- a/mm/Kconfig
-+++ b/mm/Kconfig
-@@ -897,6 +897,7 @@ config IO_MAPPING
- config SECRETMEM
- def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED
-
-+# multi-gen LRU {
- config LRU_GEN
- bool "Multi-Gen LRU"
- depends on MMU
-@@ -905,6 +906,16 @@ config LRU_GEN
- help
- A high performance LRU implementation to overcommit memory.
-
-+config LRU_GEN_STATS
-+ bool "Full stats for debugging"
-+ depends on LRU_GEN
-+ help
-+ Do not enable this option unless you plan to look at historical stats
-+ from evicted generations for debugging purpose.
-+
-+ This option has a per-memcg and per-node memory overhead.
-+# }
-+
- source "mm/damon/Kconfig"
-
- endmenu
---- a/mm/swap.c
-+++ b/mm/swap.c
-@@ -389,6 +389,40 @@ static void __lru_cache_activate_page(st
- local_unlock(&lru_pvecs.lock);
- }
-
-+#ifdef CONFIG_LRU_GEN
-+static void page_inc_refs(struct page *page)
-+{
-+ unsigned long new_flags, old_flags = READ_ONCE(page->flags);
-+
-+ if (PageUnevictable(page))
-+ return;
-+
-+ if (!PageReferenced(page)) {
-+ SetPageReferenced(page);
-+ return;
-+ }
-+
-+ if (!PageWorkingset(page)) {
-+ SetPageWorkingset(page);
-+ return;
-+ }
-+
-+ /* see the comment on MAX_NR_TIERS */
-+ do {
-+ new_flags = old_flags & LRU_REFS_MASK;
-+ if (new_flags == LRU_REFS_MASK)
-+ break;
-+
-+ new_flags += BIT(LRU_REFS_PGOFF);
-+ new_flags |= old_flags & ~LRU_REFS_MASK;
-+ } while (!try_cmpxchg(&page->flags, &old_flags, new_flags));
-+}
-+#else
-+static void page_inc_refs(struct page *page)
-+{
-+}
-+#endif /* CONFIG_LRU_GEN */
-+
- /*
- * Mark a page as having seen activity.
- *
-@@ -403,6 +437,11 @@ void mark_page_accessed(struct page *pag
- {
- page = compound_head(page);
-
-+ if (lru_gen_enabled()) {
-+ page_inc_refs(page);
-+ return;
-+ }
-+
- if (!PageReferenced(page)) {
- SetPageReferenced(page);
- } else if (PageUnevictable(page)) {
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -1142,9 +1142,11 @@ static int __remove_mapping(struct addre
-
- if (PageSwapCache(page)) {
- swp_entry_t swap = { .val = page_private(page) };
-- mem_cgroup_swapout(page, swap);
-+
-+ /* get a shadow entry before mem_cgroup_swapout() clears page_memcg() */
- if (reclaimed && !mapping_exiting(mapping))
- shadow = workingset_eviction(page, target_memcg);
-+ mem_cgroup_swapout(page, swap);
- __delete_from_swap_cache(page, swap, shadow);
- xa_unlock_irq(&mapping->i_pages);
- put_swap_page(page, swap);
-@@ -2502,6 +2504,9 @@ static void prepare_scan_count(pg_data_t
- unsigned long file;
- struct lruvec *target_lruvec;
-
-+ if (lru_gen_enabled())
-+ return;
-+
- target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
-
- /*
-@@ -2827,6 +2832,17 @@ static bool can_age_anon_pages(struct pg
- * shorthand helpers
- ******************************************************************************/
-
-+#define LRU_REFS_FLAGS (BIT(PG_referenced) | BIT(PG_workingset))
-+
-+#define DEFINE_MAX_SEQ(lruvec) \
-+ unsigned long max_seq = READ_ONCE((lruvec)->lrugen.max_seq)
-+
-+#define DEFINE_MIN_SEQ(lruvec) \
-+ unsigned long min_seq[ANON_AND_FILE] = { \
-+ READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_ANON]), \
-+ READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_FILE]), \
-+ }
-+
- #define for_each_gen_type_zone(gen, type, zone) \
- for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++) \
- for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
-@@ -2852,6 +2868,745 @@ static struct lruvec __maybe_unused *get
- return pgdat ? &pgdat->__lruvec : NULL;
- }
-
-+static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-+
-+ if (!can_demote(pgdat->node_id, sc) &&
-+ mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
-+ return 0;
-+
-+ return mem_cgroup_swappiness(memcg);
-+}
-+
-+static int get_nr_gens(struct lruvec *lruvec, int type)
-+{
-+ return lruvec->lrugen.max_seq - lruvec->lrugen.min_seq[type] + 1;
-+}
-+
-+static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
-+{
-+ /* see the comment on lru_gen_struct */
-+ return get_nr_gens(lruvec, LRU_GEN_FILE) >= MIN_NR_GENS &&
-+ get_nr_gens(lruvec, LRU_GEN_FILE) <= get_nr_gens(lruvec, LRU_GEN_ANON) &&
-+ get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS;
-+}
-+
-+/******************************************************************************
-+ * refault feedback loop
-+ ******************************************************************************/
-+
-+/*
-+ * A feedback loop based on Proportional-Integral-Derivative (PID) controller.
-+ *
-+ * The P term is refaulted/(evicted+protected) from a tier in the generation
-+ * currently being evicted; the I term is the exponential moving average of the
-+ * P term over the generations previously evicted, using the smoothing factor
-+ * 1/2; the D term isn't supported.
-+ *
-+ * The setpoint (SP) is always the first tier of one type; the process variable
-+ * (PV) is either any tier of the other type or any other tier of the same
-+ * type.
-+ *
-+ * The error is the difference between the SP and the PV; the correction is to
-+ * turn off protection when SP>PV or turn on protection when SP<PV.
-+ *
-+ * For future optimizations:
-+ * 1. The D term may discount the other two terms over time so that long-lived
-+ * generations can resist stale information.
-+ */
-+struct ctrl_pos {
-+ unsigned long refaulted;
-+ unsigned long total;
-+ int gain;
-+};
-+
-+static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
-+ struct ctrl_pos *pos)
-+{
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ int hist = lru_hist_from_seq(lrugen->min_seq[type]);
-+
-+ pos->refaulted = lrugen->avg_refaulted[type][tier] +
-+ atomic_long_read(&lrugen->refaulted[hist][type][tier]);
-+ pos->total = lrugen->avg_total[type][tier] +
-+ atomic_long_read(&lrugen->evicted[hist][type][tier]);
-+ if (tier)
-+ pos->total += lrugen->protected[hist][type][tier - 1];
-+ pos->gain = gain;
-+}
-+
-+static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover)
-+{
-+ int hist, tier;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1;
-+ unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1;
-+
-+ lockdep_assert_held(&lruvec->lru_lock);
-+
-+ if (!carryover && !clear)
-+ return;
-+
-+ hist = lru_hist_from_seq(seq);
-+
-+ for (tier = 0; tier < MAX_NR_TIERS; tier++) {
-+ if (carryover) {
-+ unsigned long sum;
-+
-+ sum = lrugen->avg_refaulted[type][tier] +
-+ atomic_long_read(&lrugen->refaulted[hist][type][tier]);
-+ WRITE_ONCE(lrugen->avg_refaulted[type][tier], sum / 2);
-+
-+ sum = lrugen->avg_total[type][tier] +
-+ atomic_long_read(&lrugen->evicted[hist][type][tier]);
-+ if (tier)
-+ sum += lrugen->protected[hist][type][tier - 1];
-+ WRITE_ONCE(lrugen->avg_total[type][tier], sum / 2);
-+ }
-+
-+ if (clear) {
-+ atomic_long_set(&lrugen->refaulted[hist][type][tier], 0);
-+ atomic_long_set(&lrugen->evicted[hist][type][tier], 0);
-+ if (tier)
-+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1], 0);
-+ }
-+ }
-+}
-+
-+static bool positive_ctrl_err(struct ctrl_pos *sp, struct ctrl_pos *pv)
-+{
-+ /*
-+ * Return true if the PV has a limited number of refaults or a lower
-+ * refaulted/total than the SP.
-+ */
-+ return pv->refaulted < MIN_LRU_BATCH ||
-+ pv->refaulted * (sp->total + MIN_LRU_BATCH) * sp->gain <=
-+ (sp->refaulted + 1) * pv->total * pv->gain;
-+}
-+
-+/******************************************************************************
-+ * the aging
-+ ******************************************************************************/
-+
-+/* protect pages accessed multiple times through file descriptors */
-+static int page_inc_gen(struct lruvec *lruvec, struct page *page, bool reclaiming)
-+{
-+ int type = page_is_file_lru(page);
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
-+ unsigned long new_flags, old_flags = READ_ONCE(page->flags);
-+
-+ VM_WARN_ON_ONCE_PAGE(!(old_flags & LRU_GEN_MASK), page);
-+
-+ do {
-+ new_gen = (old_gen + 1) % MAX_NR_GENS;
-+
-+ new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS);
-+ new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF;
-+ /* for end_page_writeback() */
-+ if (reclaiming)
-+ new_flags |= BIT(PG_reclaim);
-+ } while (!try_cmpxchg(&page->flags, &old_flags, new_flags));
-+
-+ lru_gen_update_size(lruvec, page, old_gen, new_gen);
-+
-+ return new_gen;
-+}
-+
-+static void inc_min_seq(struct lruvec *lruvec, int type)
-+{
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ reset_ctrl_pos(lruvec, type, true);
-+ WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1);
-+}
-+
-+static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
-+{
-+ int gen, type, zone;
-+ bool success = false;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
-+
-+ /* find the oldest populated generation */
-+ for (type = !can_swap; type < ANON_AND_FILE; type++) {
-+ while (min_seq[type] + MIN_NR_GENS <= lrugen->max_seq) {
-+ gen = lru_gen_from_seq(min_seq[type]);
-+
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++) {
-+ if (!list_empty(&lrugen->lists[gen][type][zone]))
-+ goto next;
-+ }
-+
-+ min_seq[type]++;
-+ }
-+next:
-+ ;
-+ }
-+
-+ /* see the comment on lru_gen_struct */
-+ if (can_swap) {
-+ min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
-+ min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
-+ }
-+
-+ for (type = !can_swap; type < ANON_AND_FILE; type++) {
-+ if (min_seq[type] == lrugen->min_seq[type])
-+ continue;
-+
-+ reset_ctrl_pos(lruvec, type, true);
-+ WRITE_ONCE(lrugen->min_seq[type], min_seq[type]);
-+ success = true;
-+ }
-+
-+ return success;
-+}
-+
-+static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, bool can_swap)
-+{
-+ int prev, next;
-+ int type, zone;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ spin_lock_irq(&lruvec->lru_lock);
-+
-+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
-+
-+ if (max_seq != lrugen->max_seq)
-+ goto unlock;
-+
-+ for (type = ANON_AND_FILE - 1; type >= 0; type--) {
-+ if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
-+ continue;
-+
-+ VM_WARN_ON_ONCE(type == LRU_GEN_FILE || can_swap);
-+
-+ inc_min_seq(lruvec, type);
-+ }
-+
-+ /*
-+ * Update the active/inactive LRU sizes for compatibility. Both sides of
-+ * the current max_seq need to be covered, since max_seq+1 can overlap
-+ * with min_seq[LRU_GEN_ANON] if swapping is constrained. And if they do
-+ * overlap, cold/hot inversion happens.
-+ */
-+ prev = lru_gen_from_seq(lrugen->max_seq - 1);
-+ next = lru_gen_from_seq(lrugen->max_seq + 1);
-+
-+ for (type = 0; type < ANON_AND_FILE; type++) {
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++) {
-+ enum lru_list lru = type * LRU_INACTIVE_FILE;
-+ long delta = lrugen->nr_pages[prev][type][zone] -
-+ lrugen->nr_pages[next][type][zone];
-+
-+ if (!delta)
-+ continue;
-+
-+ __update_lru_size(lruvec, lru, zone, delta);
-+ __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, -delta);
-+ }
-+ }
-+
-+ for (type = 0; type < ANON_AND_FILE; type++)
-+ reset_ctrl_pos(lruvec, type, false);
-+
-+ /* make sure preceding modifications appear */
-+ smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
-+unlock:
-+ spin_unlock_irq(&lruvec->lru_lock);
-+}
-+
-+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq,
-+ struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
-+{
-+ int gen, type, zone;
-+ unsigned long old = 0;
-+ unsigned long young = 0;
-+ unsigned long total = 0;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+
-+ for (type = !can_swap; type < ANON_AND_FILE; type++) {
-+ unsigned long seq;
-+
-+ for (seq = min_seq[type]; seq <= max_seq; seq++) {
-+ unsigned long size = 0;
-+
-+ gen = lru_gen_from_seq(seq);
-+
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++)
-+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
-+
-+ total += size;
-+ if (seq == max_seq)
-+ young += size;
-+ else if (seq + MIN_NR_GENS == max_seq)
-+ old += size;
-+ }
-+ }
-+
-+ /* try to scrape all its memory if this memcg was deleted */
-+ *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
-+
-+ /*
-+ * The aging tries to be lazy to reduce the overhead, while the eviction
-+ * stalls when the number of generations reaches MIN_NR_GENS. Hence, the
-+ * ideal number of generations is MIN_NR_GENS+1.
-+ */
-+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq)
-+ return true;
-+ if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
-+ return false;
-+
-+ /*
-+ * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1)
-+ * of the total number of pages for each generation. A reasonable range
-+ * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The
-+ * aging cares about the upper bound of hot pages, while the eviction
-+ * cares about the lower bound of cold pages.
-+ */
-+ if (young * MIN_NR_GENS > total)
-+ return true;
-+ if (old * (MIN_NR_GENS + 2) < total)
-+ return true;
-+
-+ return false;
-+}
-+
-+static void age_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ bool need_aging;
-+ unsigned long nr_to_scan;
-+ int swappiness = get_swappiness(lruvec, sc);
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MAX_SEQ(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
-+
-+ mem_cgroup_calculate_protection(NULL, memcg);
-+
-+ if (mem_cgroup_below_min(memcg))
-+ return;
-+
-+ need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan);
-+ if (need_aging)
-+ inc_max_seq(lruvec, max_seq, swappiness);
-+}
-+
-+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ struct mem_cgroup *memcg;
-+
-+ VM_WARN_ON_ONCE(!current_is_kswapd());
-+
-+ memcg = mem_cgroup_iter(NULL, NULL, NULL);
-+ do {
-+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
-+
-+ age_lruvec(lruvec, sc);
-+
-+ cond_resched();
-+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
-+}
-+
-+/******************************************************************************
-+ * the eviction
-+ ******************************************************************************/
-+
-+static bool sort_page(struct lruvec *lruvec, struct page *page, int tier_idx)
-+{
-+ bool success;
-+ int gen = page_lru_gen(page);
-+ int type = page_is_file_lru(page);
-+ int zone = page_zonenum(page);
-+ int delta = thp_nr_pages(page);
-+ int refs = page_lru_refs(page);
-+ int tier = lru_tier_from_refs(refs);
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ VM_WARN_ON_ONCE_PAGE(gen >= MAX_NR_GENS, page);
-+
-+ /* unevictable */
-+ if (!page_evictable(page)) {
-+ success = lru_gen_del_page(lruvec, page, true);
-+ VM_WARN_ON_ONCE_PAGE(!success, page);
-+ SetPageUnevictable(page);
-+ add_page_to_lru_list(page, lruvec);
-+ __count_vm_events(UNEVICTABLE_PGCULLED, delta);
-+ return true;
-+ }
-+
-+ /* dirty lazyfree */
-+ if (type == LRU_GEN_FILE && PageAnon(page) && PageDirty(page)) {
-+ success = lru_gen_del_page(lruvec, page, true);
-+ VM_WARN_ON_ONCE_PAGE(!success, page);
-+ SetPageSwapBacked(page);
-+ add_page_to_lru_list_tail(page, lruvec);
-+ return true;
-+ }
-+
-+ /* protected */
-+ if (tier > tier_idx) {
-+ int hist = lru_hist_from_seq(lrugen->min_seq[type]);
-+
-+ gen = page_inc_gen(lruvec, page, false);
-+ list_move_tail(&page->lru, &lrugen->lists[gen][type][zone]);
-+
-+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1],
-+ lrugen->protected[hist][type][tier - 1] + delta);
-+ __mod_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + type, delta);
-+ return true;
-+ }
-+
-+ /* waiting for writeback */
-+ if (PageLocked(page) || PageWriteback(page) ||
-+ (type == LRU_GEN_FILE && PageDirty(page))) {
-+ gen = page_inc_gen(lruvec, page, true);
-+ list_move(&page->lru, &lrugen->lists[gen][type][zone]);
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static bool isolate_page(struct lruvec *lruvec, struct page *page, struct scan_control *sc)
-+{
-+ bool success;
-+
-+ /* unmapping inhibited */
-+ if (!sc->may_unmap && page_mapped(page))
-+ return false;
-+
-+ /* swapping inhibited */
-+ if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) &&
-+ (PageDirty(page) ||
-+ (PageAnon(page) && !PageSwapCache(page))))
-+ return false;
-+
-+ /* raced with release_pages() */
-+ if (!get_page_unless_zero(page))
-+ return false;
-+
-+ /* raced with another isolation */
-+ if (!TestClearPageLRU(page)) {
-+ put_page(page);
-+ return false;
-+ }
-+
-+ /* see the comment on MAX_NR_TIERS */
-+ if (!PageReferenced(page))
-+ set_mask_bits(&page->flags, LRU_REFS_MASK | LRU_REFS_FLAGS, 0);
-+
-+ /* for shrink_page_list() */
-+ ClearPageReclaim(page);
-+ ClearPageReferenced(page);
-+
-+ success = lru_gen_del_page(lruvec, page, true);
-+ VM_WARN_ON_ONCE_PAGE(!success, page);
-+
-+ return true;
-+}
-+
-+static int scan_pages(struct lruvec *lruvec, struct scan_control *sc,
-+ int type, int tier, struct list_head *list)
-+{
-+ int gen, zone;
-+ enum vm_event_item item;
-+ int sorted = 0;
-+ int scanned = 0;
-+ int isolated = 0;
-+ int remaining = MAX_LRU_BATCH;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+
-+ VM_WARN_ON_ONCE(!list_empty(list));
-+
-+ if (get_nr_gens(lruvec, type) == MIN_NR_GENS)
-+ return 0;
-+
-+ gen = lru_gen_from_seq(lrugen->min_seq[type]);
-+
-+ for (zone = sc->reclaim_idx; zone >= 0; zone--) {
-+ LIST_HEAD(moved);
-+ int skipped = 0;
-+ struct list_head *head = &lrugen->lists[gen][type][zone];
-+
-+ while (!list_empty(head)) {
-+ struct page *page = lru_to_page(head);
-+ int delta = thp_nr_pages(page);
-+
-+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page);
-+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page);
-+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page);
-+ VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page);
-+
-+ scanned += delta;
-+
-+ if (sort_page(lruvec, page, tier))
-+ sorted += delta;
-+ else if (isolate_page(lruvec, page, sc)) {
-+ list_add(&page->lru, list);
-+ isolated += delta;
-+ } else {
-+ list_move(&page->lru, &moved);
-+ skipped += delta;
-+ }
-+
-+ if (!--remaining || max(isolated, skipped) >= MIN_LRU_BATCH)
-+ break;
-+ }
-+
-+ if (skipped) {
-+ list_splice(&moved, head);
-+ __count_zid_vm_events(PGSCAN_SKIP, zone, skipped);
-+ }
-+
-+ if (!remaining || isolated >= MIN_LRU_BATCH)
-+ break;
-+ }
-+
-+ item = current_is_kswapd() ? PGSCAN_KSWAPD : PGSCAN_DIRECT;
-+ if (!cgroup_reclaim(sc)) {
-+ __count_vm_events(item, isolated);
-+ __count_vm_events(PGREFILL, sorted);
-+ }
-+ __count_memcg_events(memcg, item, isolated);
-+ __count_memcg_events(memcg, PGREFILL, sorted);
-+ __count_vm_events(PGSCAN_ANON + type, isolated);
-+
-+ /*
-+ * There might not be eligible pages due to reclaim_idx, may_unmap and
-+ * may_writepage. Check the remaining to prevent livelock if it's not
-+ * making progress.
-+ */
-+ return isolated || !remaining ? scanned : 0;
-+}
-+
-+static int get_tier_idx(struct lruvec *lruvec, int type)
-+{
-+ int tier;
-+ struct ctrl_pos sp, pv;
-+
-+ /*
-+ * To leave a margin for fluctuations, use a larger gain factor (1:2).
-+ * This value is chosen because any other tier would have at least twice
-+ * as many refaults as the first tier.
-+ */
-+ read_ctrl_pos(lruvec, type, 0, 1, &sp);
-+ for (tier = 1; tier < MAX_NR_TIERS; tier++) {
-+ read_ctrl_pos(lruvec, type, tier, 2, &pv);
-+ if (!positive_ctrl_err(&sp, &pv))
-+ break;
-+ }
-+
-+ return tier - 1;
-+}
-+
-+static int get_type_to_scan(struct lruvec *lruvec, int swappiness, int *tier_idx)
-+{
-+ int type, tier;
-+ struct ctrl_pos sp, pv;
-+ int gain[ANON_AND_FILE] = { swappiness, 200 - swappiness };
-+
-+ /*
-+ * Compare the first tier of anon with that of file to determine which
-+ * type to scan. Also need to compare other tiers of the selected type
-+ * with the first tier of the other type to determine the last tier (of
-+ * the selected type) to evict.
-+ */
-+ read_ctrl_pos(lruvec, LRU_GEN_ANON, 0, gain[LRU_GEN_ANON], &sp);
-+ read_ctrl_pos(lruvec, LRU_GEN_FILE, 0, gain[LRU_GEN_FILE], &pv);
-+ type = positive_ctrl_err(&sp, &pv);
-+
-+ read_ctrl_pos(lruvec, !type, 0, gain[!type], &sp);
-+ for (tier = 1; tier < MAX_NR_TIERS; tier++) {
-+ read_ctrl_pos(lruvec, type, tier, gain[type], &pv);
-+ if (!positive_ctrl_err(&sp, &pv))
-+ break;
-+ }
-+
-+ *tier_idx = tier - 1;
-+
-+ return type;
-+}
-+
-+static int isolate_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
-+ int *type_scanned, struct list_head *list)
-+{
-+ int i;
-+ int type;
-+ int scanned;
-+ int tier = -1;
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ /*
-+ * Try to make the obvious choice first. When anon and file are both
-+ * available from the same generation, interpret swappiness 1 as file
-+ * first and 200 as anon first.
-+ */
-+ if (!swappiness)
-+ type = LRU_GEN_FILE;
-+ else if (min_seq[LRU_GEN_ANON] < min_seq[LRU_GEN_FILE])
-+ type = LRU_GEN_ANON;
-+ else if (swappiness == 1)
-+ type = LRU_GEN_FILE;
-+ else if (swappiness == 200)
-+ type = LRU_GEN_ANON;
-+ else
-+ type = get_type_to_scan(lruvec, swappiness, &tier);
-+
-+ for (i = !swappiness; i < ANON_AND_FILE; i++) {
-+ if (tier < 0)
-+ tier = get_tier_idx(lruvec, type);
-+
-+ scanned = scan_pages(lruvec, sc, type, tier, list);
-+ if (scanned)
-+ break;
-+
-+ type = !type;
-+ tier = -1;
-+ }
-+
-+ *type_scanned = type;
-+
-+ return scanned;
-+}
-+
-+static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness)
-+{
-+ int type;
-+ int scanned;
-+ int reclaimed;
-+ LIST_HEAD(list);
-+ struct page *page;
-+ enum vm_event_item item;
-+ struct reclaim_stat stat;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-+
-+ spin_lock_irq(&lruvec->lru_lock);
-+
-+ scanned = isolate_pages(lruvec, sc, swappiness, &type, &list);
-+
-+ scanned += try_to_inc_min_seq(lruvec, swappiness);
-+
-+ if (get_nr_gens(lruvec, !swappiness) == MIN_NR_GENS)
-+ scanned = 0;
-+
-+ spin_unlock_irq(&lruvec->lru_lock);
-+
-+ if (list_empty(&list))
-+ return scanned;
-+
-+ reclaimed = shrink_page_list(&list, pgdat, sc, &stat, false);
-+
-+ list_for_each_entry(page, &list, lru) {
-+ /* restore LRU_REFS_FLAGS cleared by isolate_page() */
-+ if (PageWorkingset(page))
-+ SetPageReferenced(page);
-+
-+ /* don't add rejected pages to the oldest generation */
-+ if (PageReclaim(page) &&
-+ (PageDirty(page) || PageWriteback(page)))
-+ ClearPageActive(page);
-+ else
-+ SetPageActive(page);
-+ }
-+
-+ spin_lock_irq(&lruvec->lru_lock);
-+
-+ move_pages_to_lru(lruvec, &list);
-+
-+ item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT;
-+ if (!cgroup_reclaim(sc))
-+ __count_vm_events(item, reclaimed);
-+ __count_memcg_events(memcg, item, reclaimed);
-+ __count_vm_events(PGSTEAL_ANON + type, reclaimed);
-+
-+ spin_unlock_irq(&lruvec->lru_lock);
-+
-+ mem_cgroup_uncharge_list(&list);
-+ free_unref_page_list(&list);
-+
-+ sc->nr_reclaimed += reclaimed;
-+
-+ return scanned;
-+}
-+
-+static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
-+ bool can_swap)
-+{
-+ bool need_aging;
-+ unsigned long nr_to_scan;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MAX_SEQ(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ if (mem_cgroup_below_min(memcg) ||
-+ (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
-+ return 0;
-+
-+ need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan);
-+ if (!need_aging)
-+ return nr_to_scan;
-+
-+ /* skip the aging path at the default priority */
-+ if (sc->priority == DEF_PRIORITY)
-+ goto done;
-+
-+ /* leave the work to lru_gen_age_node() */
-+ if (current_is_kswapd())
-+ return 0;
-+
-+ inc_max_seq(lruvec, max_seq, can_swap);
-+done:
-+ return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
-+}
-+
-+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ struct blk_plug plug;
-+ unsigned long scanned = 0;
-+
-+ lru_add_drain();
-+
-+ blk_start_plug(&plug);
-+
-+ while (true) {
-+ int delta;
-+ int swappiness;
-+ unsigned long nr_to_scan;
-+
-+ if (sc->may_swap)
-+ swappiness = get_swappiness(lruvec, sc);
-+ else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc))
-+ swappiness = 1;
-+ else
-+ swappiness = 0;
-+
-+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
-+ if (!nr_to_scan)
-+ break;
-+
-+ delta = evict_pages(lruvec, sc, swappiness);
-+ if (!delta)
-+ break;
-+
-+ scanned += delta;
-+ if (scanned >= nr_to_scan)
-+ break;
-+
-+ cond_resched();
-+ }
-+
-+ blk_finish_plug(&plug);
-+}
-+
- /******************************************************************************
- * initialization
- ******************************************************************************/
-@@ -2894,6 +3649,16 @@ static int __init init_lru_gen(void)
- };
- late_initcall(init_lru_gen);
-
-+#else /* !CONFIG_LRU_GEN */
-+
-+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+}
-+
-+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+}
-+
- #endif /* CONFIG_LRU_GEN */
-
- static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-@@ -2907,6 +3672,11 @@ static void shrink_lruvec(struct lruvec
- bool proportional_reclaim;
- struct blk_plug plug;
-
-+ if (lru_gen_enabled()) {
-+ lru_gen_shrink_lruvec(lruvec, sc);
-+ return;
-+ }
-+
- get_scan_count(lruvec, sc, nr);
-
- /* Record the original scan target for proportional adjustments later */
-@@ -3375,6 +4145,9 @@ static void snapshot_refaults(struct mem
- struct lruvec *target_lruvec;
- unsigned long refaults;
-
-+ if (lru_gen_enabled())
-+ return;
-+
- target_lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
- refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_ANON);
- target_lruvec->refaults[0] = refaults;
-@@ -3739,12 +4512,16 @@ unsigned long try_to_free_mem_cgroup_pag
- }
- #endif
-
--static void age_active_anon(struct pglist_data *pgdat,
-- struct scan_control *sc)
-+static void kswapd_age_node(struct pglist_data *pgdat, struct scan_control *sc)
- {
- struct mem_cgroup *memcg;
- struct lruvec *lruvec;
-
-+ if (lru_gen_enabled()) {
-+ lru_gen_age_node(pgdat, sc);
-+ return;
-+ }
-+
- if (!can_age_anon_pages(pgdat, sc))
- return;
-
-@@ -4061,12 +4838,11 @@ restart:
- sc.may_swap = !nr_boost_reclaim;
-
- /*
-- * Do some background aging of the anon list, to give
-- * pages a chance to be referenced before reclaiming. All
-- * pages are rotated regardless of classzone as this is
-- * about consistent aging.
-+ * Do some background aging, to give pages a chance to be
-+ * referenced before reclaiming. All pages are rotated
-+ * regardless of classzone as this is about consistent aging.
- */
-- age_active_anon(pgdat, &sc);
-+ kswapd_age_node(pgdat, &sc);
-
- /*
- * If we're getting trouble reclaiming, start doing writepage
---- a/mm/workingset.c
-+++ b/mm/workingset.c
-@@ -187,7 +187,6 @@ static unsigned int bucket_order __read_
- static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction,
- bool workingset)
- {
-- eviction >>= bucket_order;
- eviction &= EVICTION_MASK;
- eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid;
- eviction = (eviction << NODES_SHIFT) | pgdat->node_id;
-@@ -212,10 +211,107 @@ static void unpack_shadow(void *shadow,
-
- *memcgidp = memcgid;
- *pgdat = NODE_DATA(nid);
-- *evictionp = entry << bucket_order;
-+ *evictionp = entry;
- *workingsetp = workingset;
- }
-
-+#ifdef CONFIG_LRU_GEN
-+
-+static void *lru_gen_eviction(struct page *page)
-+{
-+ int hist;
-+ unsigned long token;
-+ unsigned long min_seq;
-+ struct lruvec *lruvec;
-+ struct lru_gen_struct *lrugen;
-+ int type = page_is_file_lru(page);
-+ int delta = thp_nr_pages(page);
-+ int refs = page_lru_refs(page);
-+ int tier = lru_tier_from_refs(refs);
-+ struct mem_cgroup *memcg = page_memcg(page);
-+ struct pglist_data *pgdat = page_pgdat(page);
-+
-+ BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_REFS_WIDTH > BITS_PER_LONG - EVICTION_SHIFT);
-+
-+ lruvec = mem_cgroup_lruvec(memcg, pgdat);
-+ lrugen = &lruvec->lrugen;
-+ min_seq = READ_ONCE(lrugen->min_seq[type]);
-+ token = (min_seq << LRU_REFS_WIDTH) | max(refs - 1, 0);
-+
-+ hist = lru_hist_from_seq(min_seq);
-+ atomic_long_add(delta, &lrugen->evicted[hist][type][tier]);
-+
-+ return pack_shadow(mem_cgroup_id(memcg), pgdat, token, refs);
-+}
-+
-+static void lru_gen_refault(struct page *page, void *shadow)
-+{
-+ int hist, tier, refs;
-+ int memcg_id;
-+ bool workingset;
-+ unsigned long token;
-+ unsigned long min_seq;
-+ struct lruvec *lruvec;
-+ struct lru_gen_struct *lrugen;
-+ struct mem_cgroup *memcg;
-+ struct pglist_data *pgdat;
-+ int type = page_is_file_lru(page);
-+ int delta = thp_nr_pages(page);
-+
-+ unpack_shadow(shadow, &memcg_id, &pgdat, &token, &workingset);
-+
-+ if (pgdat != page_pgdat(page))
-+ return;
-+
-+ rcu_read_lock();
-+
-+ memcg = page_memcg_rcu(page);
-+ if (memcg_id != mem_cgroup_id(memcg))
-+ goto unlock;
-+
-+ lruvec = mem_cgroup_lruvec(memcg, pgdat);
-+ lrugen = &lruvec->lrugen;
-+
-+ min_seq = READ_ONCE(lrugen->min_seq[type]);
-+ if ((token >> LRU_REFS_WIDTH) != (min_seq & (EVICTION_MASK >> LRU_REFS_WIDTH)))
-+ goto unlock;
-+
-+ hist = lru_hist_from_seq(min_seq);
-+ /* see the comment in page_lru_refs() */
-+ refs = (token & (BIT(LRU_REFS_WIDTH) - 1)) + workingset;
-+ tier = lru_tier_from_refs(refs);
-+
-+ atomic_long_add(delta, &lrugen->refaulted[hist][type][tier]);
-+ mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + type, delta);
-+
-+ /*
-+ * Count the following two cases as stalls:
-+ * 1. For pages accessed through page tables, hotter pages pushed out
-+ * hot pages which refaulted immediately.
-+ * 2. For pages accessed multiple times through file descriptors,
-+ * numbers of accesses might have been out of the range.
-+ */
-+ if (lru_gen_in_fault() || refs == BIT(LRU_REFS_WIDTH)) {
-+ SetPageWorkingset(page);
-+ mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta);
-+ }
-+unlock:
-+ rcu_read_unlock();
-+}
-+
-+#else /* !CONFIG_LRU_GEN */
-+
-+static void *lru_gen_eviction(struct page *page)
-+{
-+ return NULL;
-+}
-+
-+static void lru_gen_refault(struct page *page, void *shadow)
-+{
-+}
-+
-+#endif /* CONFIG_LRU_GEN */
-+
- /**
- * workingset_age_nonresident - age non-resident entries as LRU ages
- * @lruvec: the lruvec that was aged
-@@ -264,10 +360,14 @@ void *workingset_eviction(struct page *p
- VM_BUG_ON_PAGE(page_count(page), page);
- VM_BUG_ON_PAGE(!PageLocked(page), page);
-
-+ if (lru_gen_enabled())
-+ return lru_gen_eviction(page);
-+
- lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
- /* XXX: target_memcg can be NULL, go through lruvec */
- memcgid = mem_cgroup_id(lruvec_memcg(lruvec));
- eviction = atomic_long_read(&lruvec->nonresident_age);
-+ eviction >>= bucket_order;
- workingset_age_nonresident(lruvec, thp_nr_pages(page));
- return pack_shadow(memcgid, pgdat, eviction, PageWorkingset(page));
- }
-@@ -296,7 +396,13 @@ void workingset_refault(struct page *pag
- bool workingset;
- int memcgid;
-
-+ if (lru_gen_enabled()) {
-+ lru_gen_refault(page, shadow);
-+ return;
-+ }
-+
- unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset);
-+ eviction <<= bucket_order;
-
- rcu_read_lock();
- /*
diff --git a/target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch b/target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch
deleted file mode 100644
index 40e51b4294..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch
+++ /dev/null
@@ -1,491 +0,0 @@
-From e4277535f6d6708bb19b88c4bad155832671d69b Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:04 -0600
-Subject: [PATCH 07/29] mm: multi-gen LRU: exploit locality in rmap
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Searching the rmap for PTEs mapping each page on an LRU list (to test and
-clear the accessed bit) can be expensive because pages from different VMAs
-(PA space) are not cache friendly to the rmap (VA space). For workloads
-mostly using mapped pages, searching the rmap can incur the highest CPU
-cost in the reclaim path.
-
-This patch exploits spatial locality to reduce the trips into the rmap.
-When shrink_page_list() walks the rmap and finds a young PTE, a new
-function lru_gen_look_around() scans at most BITS_PER_LONG-1 adjacent
-PTEs. On finding another young PTE, it clears the accessed bit and
-updates the gen counter of the page mapped by this PTE to
-(max_seq%MAX_NR_GENS)+1.
-
-Server benchmark results:
- Single workload:
- fio (buffered I/O): no change
-
- Single workload:
- memcached (anon): +[3, 5]%
- Ops/sec KB/sec
- patch1-6: 1106168.46 43025.04
- patch1-7: 1147696.57 44640.29
-
- Configurations:
- no change
-
-Client benchmark results:
- kswapd profiles:
- patch1-6
- 39.03% lzo1x_1_do_compress (real work)
- 18.47% page_vma_mapped_walk (overhead)
- 6.74% _raw_spin_unlock_irq
- 3.97% do_raw_spin_lock
- 2.49% ptep_clear_flush
- 2.48% anon_vma_interval_tree_iter_first
- 1.92% page_referenced_one
- 1.88% __zram_bvec_write
- 1.48% memmove
- 1.31% vma_interval_tree_iter_next
-
- patch1-7
- 48.16% lzo1x_1_do_compress (real work)
- 8.20% page_vma_mapped_walk (overhead)
- 7.06% _raw_spin_unlock_irq
- 2.92% ptep_clear_flush
- 2.53% __zram_bvec_write
- 2.11% do_raw_spin_lock
- 2.02% memmove
- 1.93% lru_gen_look_around
- 1.56% free_unref_page_list
- 1.40% memset
-
- Configurations:
- no change
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-8-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Acked-by: Barry Song <baohua@kernel.org>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/memcontrol.h | 31 +++++++
- include/linux/mmzone.h | 6 ++
- mm/internal.h | 1 +
- mm/memcontrol.c | 1 +
- mm/rmap.c | 7 ++
- mm/swap.c | 4 +-
- mm/vmscan.c | 184 +++++++++++++++++++++++++++++++++++++
- 7 files changed, 232 insertions(+), 2 deletions(-)
-
---- a/include/linux/memcontrol.h
-+++ b/include/linux/memcontrol.h
-@@ -447,6 +447,7 @@ static inline struct obj_cgroup *__page_
- * - LRU isolation
- * - lock_page_memcg()
- * - exclusive reference
-+ * - mem_cgroup_trylock_pages()
- *
- * For a kmem page a caller should hold an rcu read lock to protect memcg
- * associated with a kmem page from being released.
-@@ -502,6 +503,7 @@ static inline struct mem_cgroup *page_me
- * - LRU isolation
- * - lock_page_memcg()
- * - exclusive reference
-+ * - mem_cgroup_trylock_pages()
- *
- * For a kmem page a caller should hold an rcu read lock to protect memcg
- * associated with a kmem page from being released.
-@@ -958,6 +960,23 @@ void unlock_page_memcg(struct page *page
-
- void __mod_memcg_state(struct mem_cgroup *memcg, int idx, int val);
-
-+/* try to stablize page_memcg() for all the pages in a memcg */
-+static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg)
-+{
-+ rcu_read_lock();
-+
-+ if (mem_cgroup_disabled() || !atomic_read(&memcg->moving_account))
-+ return true;
-+
-+ rcu_read_unlock();
-+ return false;
-+}
-+
-+static inline void mem_cgroup_unlock_pages(void)
-+{
-+ rcu_read_unlock();
-+}
-+
- /* idx can be of type enum memcg_stat_item or node_stat_item */
- static inline void mod_memcg_state(struct mem_cgroup *memcg,
- int idx, int val)
-@@ -1374,6 +1393,18 @@ static inline void unlock_page_memcg(str
- {
- }
-
-+static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg)
-+{
-+ /* to match page_memcg_rcu() */
-+ rcu_read_lock();
-+ return true;
-+}
-+
-+static inline void mem_cgroup_unlock_pages(void)
-+{
-+ rcu_read_unlock();
-+}
-+
- static inline void mem_cgroup_handle_over_high(void)
- {
- }
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -352,6 +352,7 @@ enum lruvec_flags {
- #ifndef __GENERATING_BOUNDS_H
-
- struct lruvec;
-+struct page_vma_mapped_walk;
-
- #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
- #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
-@@ -407,6 +408,7 @@ struct lru_gen_struct {
- };
-
- void lru_gen_init_lruvec(struct lruvec *lruvec);
-+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
-
- #ifdef CONFIG_MEMCG
- void lru_gen_init_memcg(struct mem_cgroup *memcg);
-@@ -419,6 +421,10 @@ static inline void lru_gen_init_lruvec(s
- {
- }
-
-+static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
-+{
-+}
-+
- #ifdef CONFIG_MEMCG
- static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
- {
---- a/mm/internal.h
-+++ b/mm/internal.h
-@@ -35,6 +35,7 @@
- void page_writeback_init(void);
-
- vm_fault_t do_swap_page(struct vm_fault *vmf);
-+void activate_page(struct page *page);
-
- void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
- unsigned long floor, unsigned long ceiling);
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -2798,6 +2798,7 @@ static void commit_charge(struct page *p
- * - LRU isolation
- * - lock_page_memcg()
- * - exclusive reference
-+ * - mem_cgroup_trylock_pages()
- */
- page->memcg_data = (unsigned long)memcg;
- }
---- a/mm/rmap.c
-+++ b/mm/rmap.c
-@@ -73,6 +73,7 @@
- #include <linux/page_idle.h>
- #include <linux/memremap.h>
- #include <linux/userfaultfd_k.h>
-+#include <linux/mm_inline.h>
-
- #include <asm/tlbflush.h>
-
-@@ -793,6 +794,12 @@ static bool page_referenced_one(struct p
- }
-
- if (pvmw.pte) {
-+ if (lru_gen_enabled() && pte_young(*pvmw.pte) &&
-+ !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) {
-+ lru_gen_look_around(&pvmw);
-+ referenced++;
-+ }
-+
- if (ptep_clear_flush_young_notify(vma, address,
- pvmw.pte)) {
- /*
---- a/mm/swap.c
-+++ b/mm/swap.c
-@@ -325,7 +325,7 @@ static bool need_activate_page_drain(int
- return pagevec_count(&per_cpu(lru_pvecs.activate_page, cpu)) != 0;
- }
-
--static void activate_page(struct page *page)
-+void activate_page(struct page *page)
- {
- page = compound_head(page);
- if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
-@@ -345,7 +345,7 @@ static inline void activate_page_drain(i
- {
- }
-
--static void activate_page(struct page *page)
-+void activate_page(struct page *page)
- {
- struct lruvec *lruvec;
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -1409,6 +1409,11 @@ retry:
- if (!sc->may_unmap && page_mapped(page))
- goto keep_locked;
-
-+ /* page_update_gen() tried to promote this page? */
-+ if (lru_gen_enabled() && !ignore_references &&
-+ page_mapped(page) && PageReferenced(page))
-+ goto keep_locked;
-+
- may_enter_fs = (sc->gfp_mask & __GFP_FS) ||
- (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO));
-
-@@ -2990,6 +2995,29 @@ static bool positive_ctrl_err(struct ctr
- * the aging
- ******************************************************************************/
-
-+/* promote pages accessed through page tables */
-+static int page_update_gen(struct page *page, int gen)
-+{
-+ unsigned long new_flags, old_flags = READ_ONCE(page->flags);
-+
-+ VM_WARN_ON_ONCE(gen >= MAX_NR_GENS);
-+ VM_WARN_ON_ONCE(!rcu_read_lock_held());
-+
-+ do {
-+ /* lru_gen_del_page() has isolated this page? */
-+ if (!(old_flags & LRU_GEN_MASK)) {
-+ /* for shrink_page_list() */
-+ new_flags = old_flags | BIT(PG_referenced);
-+ continue;
-+ }
-+
-+ new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS);
-+ new_flags |= (gen + 1UL) << LRU_GEN_PGOFF;
-+ } while (!try_cmpxchg(&page->flags, &old_flags, new_flags));
-+
-+ return ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
-+}
-+
- /* protect pages accessed multiple times through file descriptors */
- static int page_inc_gen(struct lruvec *lruvec, struct page *page, bool reclaiming)
- {
-@@ -3001,6 +3029,11 @@ static int page_inc_gen(struct lruvec *l
- VM_WARN_ON_ONCE_PAGE(!(old_flags & LRU_GEN_MASK), page);
-
- do {
-+ new_gen = ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
-+ /* page_update_gen() has promoted this page? */
-+ if (new_gen >= 0 && new_gen != old_gen)
-+ return new_gen;
-+
- new_gen = (old_gen + 1) % MAX_NR_GENS;
-
- new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS);
-@@ -3015,6 +3048,43 @@ static int page_inc_gen(struct lruvec *l
- return new_gen;
- }
-
-+static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr)
-+{
-+ unsigned long pfn = pte_pfn(pte);
-+
-+ VM_WARN_ON_ONCE(addr < vma->vm_start || addr >= vma->vm_end);
-+
-+ if (!pte_present(pte) || is_zero_pfn(pfn))
-+ return -1;
-+
-+ if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte)))
-+ return -1;
-+
-+ if (WARN_ON_ONCE(!pfn_valid(pfn)))
-+ return -1;
-+
-+ return pfn;
-+}
-+
-+static struct page *get_pfn_page(unsigned long pfn, struct mem_cgroup *memcg,
-+ struct pglist_data *pgdat)
-+{
-+ struct page *page;
-+
-+ /* try to avoid unnecessary memory loads */
-+ if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
-+ return NULL;
-+
-+ page = compound_head(pfn_to_page(pfn));
-+ if (page_to_nid(page) != pgdat->node_id)
-+ return NULL;
-+
-+ if (page_memcg_rcu(page) != memcg)
-+ return NULL;
-+
-+ return page;
-+}
-+
- static void inc_min_seq(struct lruvec *lruvec, int type)
- {
- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-@@ -3214,6 +3284,114 @@ static void lru_gen_age_node(struct pgli
- } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
- }
-
-+/*
-+ * This function exploits spatial locality when shrink_page_list() walks the
-+ * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages.
-+ */
-+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
-+{
-+ int i;
-+ pte_t *pte;
-+ unsigned long start;
-+ unsigned long end;
-+ unsigned long addr;
-+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {};
-+ struct page *page = pvmw->page;
-+ struct mem_cgroup *memcg = page_memcg(page);
-+ struct pglist_data *pgdat = page_pgdat(page);
-+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
-+ DEFINE_MAX_SEQ(lruvec);
-+ int old_gen, new_gen = lru_gen_from_seq(max_seq);
-+
-+ lockdep_assert_held(pvmw->ptl);
-+ VM_WARN_ON_ONCE_PAGE(PageLRU(page), page);
-+
-+ if (spin_is_contended(pvmw->ptl))
-+ return;
-+
-+ start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start);
-+ end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1;
-+
-+ if (end - start > MIN_LRU_BATCH * PAGE_SIZE) {
-+ if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2)
-+ end = start + MIN_LRU_BATCH * PAGE_SIZE;
-+ else if (end - pvmw->address < MIN_LRU_BATCH * PAGE_SIZE / 2)
-+ start = end - MIN_LRU_BATCH * PAGE_SIZE;
-+ else {
-+ start = pvmw->address - MIN_LRU_BATCH * PAGE_SIZE / 2;
-+ end = pvmw->address + MIN_LRU_BATCH * PAGE_SIZE / 2;
-+ }
-+ }
-+
-+ pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE;
-+
-+ rcu_read_lock();
-+ arch_enter_lazy_mmu_mode();
-+
-+ for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
-+ unsigned long pfn;
-+
-+ pfn = get_pte_pfn(pte[i], pvmw->vma, addr);
-+ if (pfn == -1)
-+ continue;
-+
-+ if (!pte_young(pte[i]))
-+ continue;
-+
-+ page = get_pfn_page(pfn, memcg, pgdat);
-+ if (!page)
-+ continue;
-+
-+ if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i))
-+ VM_WARN_ON_ONCE(true);
-+
-+ if (pte_dirty(pte[i]) && !PageDirty(page) &&
-+ !(PageAnon(page) && PageSwapBacked(page) &&
-+ !PageSwapCache(page)))
-+ set_page_dirty(page);
-+
-+ old_gen = page_lru_gen(page);
-+ if (old_gen < 0)
-+ SetPageReferenced(page);
-+ else if (old_gen != new_gen)
-+ __set_bit(i, bitmap);
-+ }
-+
-+ arch_leave_lazy_mmu_mode();
-+ rcu_read_unlock();
-+
-+ if (bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) {
-+ for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
-+ page = pte_page(pte[i]);
-+ activate_page(page);
-+ }
-+ return;
-+ }
-+
-+ /* page_update_gen() requires stable page_memcg() */
-+ if (!mem_cgroup_trylock_pages(memcg))
-+ return;
-+
-+ spin_lock_irq(&lruvec->lru_lock);
-+ new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq);
-+
-+ for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
-+ page = compound_head(pte_page(pte[i]));
-+ if (page_memcg_rcu(page) != memcg)
-+ continue;
-+
-+ old_gen = page_update_gen(page, new_gen);
-+ if (old_gen < 0 || old_gen == new_gen)
-+ continue;
-+
-+ lru_gen_update_size(lruvec, page, old_gen, new_gen);
-+ }
-+
-+ spin_unlock_irq(&lruvec->lru_lock);
-+
-+ mem_cgroup_unlock_pages();
-+}
-+
- /******************************************************************************
- * the eviction
- ******************************************************************************/
-@@ -3250,6 +3428,12 @@ static bool sort_page(struct lruvec *lru
- return true;
- }
-
-+ /* promoted */
-+ if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {
-+ list_move(&page->lru, &lrugen->lists[gen][type][zone]);
-+ return true;
-+ }
-+
- /* protected */
- if (tier > tier_idx) {
- int hist = lru_hist_from_seq(lrugen->min_seq[type]);
diff --git a/target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch b/target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch
deleted file mode 100644
index 4cfd247178..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch
+++ /dev/null
@@ -1,1687 +0,0 @@
-From 05223c4e80b34e29f2255c04ffebc2c4475e7593 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:05 -0600
-Subject: [PATCH 08/29] mm: multi-gen LRU: support page table walks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-To further exploit spatial locality, the aging prefers to walk page tables
-to search for young PTEs and promote hot pages. A kill switch will be
-added in the next patch to disable this behavior. When disabled, the
-aging relies on the rmap only.
-
-NB: this behavior has nothing similar with the page table scanning in the
-2.4 kernel [1], which searches page tables for old PTEs, adds cold pages
-to swapcache and unmaps them.
-
-To avoid confusion, the term "iteration" specifically means the traversal
-of an entire mm_struct list; the term "walk" will be applied to page
-tables and the rmap, as usual.
-
-An mm_struct list is maintained for each memcg, and an mm_struct follows
-its owner task to the new memcg when this task is migrated. Given an
-lruvec, the aging iterates lruvec_memcg()->mm_list and calls
-walk_page_range() with each mm_struct on this list to promote hot pages
-before it increments max_seq.
-
-When multiple page table walkers iterate the same list, each of them gets
-a unique mm_struct; therefore they can run concurrently. Page table
-walkers ignore any misplaced pages, e.g., if an mm_struct was migrated,
-pages it left in the previous memcg will not be promoted when its current
-memcg is under reclaim. Similarly, page table walkers will not promote
-pages from nodes other than the one under reclaim.
-
-This patch uses the following optimizations when walking page tables:
-1. It tracks the usage of mm_struct's between context switches so that
- page table walkers can skip processes that have been sleeping since
- the last iteration.
-2. It uses generational Bloom filters to record populated branches so
- that page table walkers can reduce their search space based on the
- query results, e.g., to skip page tables containing mostly holes or
- misplaced pages.
-3. It takes advantage of the accessed bit in non-leaf PMD entries when
- CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y.
-4. It does not zigzag between a PGD table and the same PMD table
- spanning multiple VMAs. IOW, it finishes all the VMAs within the
- range of the same PMD table before it returns to a PGD table. This
- improves the cache performance for workloads that have large
- numbers of tiny VMAs [2], especially when CONFIG_PGTABLE_LEVELS=5.
-
-Server benchmark results:
- Single workload:
- fio (buffered I/O): no change
-
- Single workload:
- memcached (anon): +[8, 10]%
- Ops/sec KB/sec
- patch1-7: 1147696.57 44640.29
- patch1-8: 1245274.91 48435.66
-
- Configurations:
- no change
-
-Client benchmark results:
- kswapd profiles:
- patch1-7
- 48.16% lzo1x_1_do_compress (real work)
- 8.20% page_vma_mapped_walk (overhead)
- 7.06% _raw_spin_unlock_irq
- 2.92% ptep_clear_flush
- 2.53% __zram_bvec_write
- 2.11% do_raw_spin_lock
- 2.02% memmove
- 1.93% lru_gen_look_around
- 1.56% free_unref_page_list
- 1.40% memset
-
- patch1-8
- 49.44% lzo1x_1_do_compress (real work)
- 6.19% page_vma_mapped_walk (overhead)
- 5.97% _raw_spin_unlock_irq
- 3.13% get_pfn_page
- 2.85% ptep_clear_flush
- 2.42% __zram_bvec_write
- 2.08% do_raw_spin_lock
- 1.92% memmove
- 1.44% alloc_zspage
- 1.36% memset
-
- Configurations:
- no change
-
-Thanks to the following developers for their efforts [3].
- kernel test robot <lkp@intel.com>
-
-[1] https://lwn.net/Articles/23732/
-[2] https://llvm.org/docs/ScudoHardenedAllocator.html
-[3] https://lore.kernel.org/r/202204160827.ekEARWQo-lkp@intel.com/
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-9-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- fs/exec.c | 2 +
- include/linux/memcontrol.h | 5 +
- include/linux/mm_types.h | 76 +++
- include/linux/mmzone.h | 56 +-
- include/linux/swap.h | 4 +
- kernel/exit.c | 1 +
- kernel/fork.c | 9 +
- kernel/sched/core.c | 1 +
- mm/memcontrol.c | 25 +
- mm/vmscan.c | 1010 +++++++++++++++++++++++++++++++++++-
- 10 files changed, 1172 insertions(+), 17 deletions(-)
-
---- a/fs/exec.c
-+++ b/fs/exec.c
-@@ -1014,6 +1014,7 @@ static int exec_mmap(struct mm_struct *m
- active_mm = tsk->active_mm;
- tsk->active_mm = mm;
- tsk->mm = mm;
-+ lru_gen_add_mm(mm);
- /*
- * This prevents preemption while active_mm is being loaded and
- * it and mm are being updated, which could cause problems for
-@@ -1029,6 +1030,7 @@ static int exec_mmap(struct mm_struct *m
- tsk->mm->vmacache_seqnum = 0;
- vmacache_flush(tsk);
- task_unlock(tsk);
-+ lru_gen_use_mm(mm);
- if (old_mm) {
- mmap_read_unlock(old_mm);
- BUG_ON(active_mm != old_mm);
---- a/include/linux/memcontrol.h
-+++ b/include/linux/memcontrol.h
-@@ -353,6 +353,11 @@ struct mem_cgroup {
- struct deferred_split deferred_split_queue;
- #endif
-
-+#ifdef CONFIG_LRU_GEN
-+ /* per-memcg mm_struct list */
-+ struct lru_gen_mm_list mm_list;
-+#endif
-+
- struct mem_cgroup_per_node *nodeinfo[];
- };
-
---- a/include/linux/mm_types.h
-+++ b/include/linux/mm_types.h
-@@ -580,6 +580,22 @@ struct mm_struct {
- #ifdef CONFIG_IOMMU_SUPPORT
- u32 pasid;
- #endif
-+#ifdef CONFIG_LRU_GEN
-+ struct {
-+ /* this mm_struct is on lru_gen_mm_list */
-+ struct list_head list;
-+ /*
-+ * Set when switching to this mm_struct, as a hint of
-+ * whether it has been used since the last time per-node
-+ * page table walkers cleared the corresponding bits.
-+ */
-+ unsigned long bitmap;
-+#ifdef CONFIG_MEMCG
-+ /* points to the memcg of "owner" above */
-+ struct mem_cgroup *memcg;
-+#endif
-+ } lru_gen;
-+#endif /* CONFIG_LRU_GEN */
- } __randomize_layout;
-
- /*
-@@ -606,6 +622,66 @@ static inline cpumask_t *mm_cpumask(stru
- return (struct cpumask *)&mm->cpu_bitmap;
- }
-
-+#ifdef CONFIG_LRU_GEN
-+
-+struct lru_gen_mm_list {
-+ /* mm_struct list for page table walkers */
-+ struct list_head fifo;
-+ /* protects the list above */
-+ spinlock_t lock;
-+};
-+
-+void lru_gen_add_mm(struct mm_struct *mm);
-+void lru_gen_del_mm(struct mm_struct *mm);
-+#ifdef CONFIG_MEMCG
-+void lru_gen_migrate_mm(struct mm_struct *mm);
-+#endif
-+
-+static inline void lru_gen_init_mm(struct mm_struct *mm)
-+{
-+ INIT_LIST_HEAD(&mm->lru_gen.list);
-+ mm->lru_gen.bitmap = 0;
-+#ifdef CONFIG_MEMCG
-+ mm->lru_gen.memcg = NULL;
-+#endif
-+}
-+
-+static inline void lru_gen_use_mm(struct mm_struct *mm)
-+{
-+ /*
-+ * When the bitmap is set, page reclaim knows this mm_struct has been
-+ * used since the last time it cleared the bitmap. So it might be worth
-+ * walking the page tables of this mm_struct to clear the accessed bit.
-+ */
-+ WRITE_ONCE(mm->lru_gen.bitmap, -1);
-+}
-+
-+#else /* !CONFIG_LRU_GEN */
-+
-+static inline void lru_gen_add_mm(struct mm_struct *mm)
-+{
-+}
-+
-+static inline void lru_gen_del_mm(struct mm_struct *mm)
-+{
-+}
-+
-+#ifdef CONFIG_MEMCG
-+static inline void lru_gen_migrate_mm(struct mm_struct *mm)
-+{
-+}
-+#endif
-+
-+static inline void lru_gen_init_mm(struct mm_struct *mm)
-+{
-+}
-+
-+static inline void lru_gen_use_mm(struct mm_struct *mm)
-+{
-+}
-+
-+#endif /* CONFIG_LRU_GEN */
-+
- struct mmu_gather;
- extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm);
- extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm);
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -385,7 +385,7 @@ enum {
- * min_seq behind.
- *
- * The number of pages in each generation is eventually consistent and therefore
-- * can be transiently negative.
-+ * can be transiently negative when reset_batch_size() is pending.
- */
- struct lru_gen_struct {
- /* the aging increments the youngest generation number */
-@@ -407,6 +407,53 @@ struct lru_gen_struct {
- atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
- };
-
-+enum {
-+ MM_LEAF_TOTAL, /* total leaf entries */
-+ MM_LEAF_OLD, /* old leaf entries */
-+ MM_LEAF_YOUNG, /* young leaf entries */
-+ MM_NONLEAF_TOTAL, /* total non-leaf entries */
-+ MM_NONLEAF_FOUND, /* non-leaf entries found in Bloom filters */
-+ MM_NONLEAF_ADDED, /* non-leaf entries added to Bloom filters */
-+ NR_MM_STATS
-+};
-+
-+/* double-buffering Bloom filters */
-+#define NR_BLOOM_FILTERS 2
-+
-+struct lru_gen_mm_state {
-+ /* set to max_seq after each iteration */
-+ unsigned long seq;
-+ /* where the current iteration continues (inclusive) */
-+ struct list_head *head;
-+ /* where the last iteration ended (exclusive) */
-+ struct list_head *tail;
-+ /* to wait for the last page table walker to finish */
-+ struct wait_queue_head wait;
-+ /* Bloom filters flip after each iteration */
-+ unsigned long *filters[NR_BLOOM_FILTERS];
-+ /* the mm stats for debugging */
-+ unsigned long stats[NR_HIST_GENS][NR_MM_STATS];
-+ /* the number of concurrent page table walkers */
-+ int nr_walkers;
-+};
-+
-+struct lru_gen_mm_walk {
-+ /* the lruvec under reclaim */
-+ struct lruvec *lruvec;
-+ /* unstable max_seq from lru_gen_struct */
-+ unsigned long max_seq;
-+ /* the next address within an mm to scan */
-+ unsigned long next_addr;
-+ /* to batch promoted pages */
-+ int nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
-+ /* to batch the mm stats */
-+ int mm_stats[NR_MM_STATS];
-+ /* total batched items */
-+ int batched;
-+ bool can_swap;
-+ bool force_scan;
-+};
-+
- void lru_gen_init_lruvec(struct lruvec *lruvec);
- void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
-
-@@ -457,6 +504,8 @@ struct lruvec {
- #ifdef CONFIG_LRU_GEN
- /* evictable pages divided into generations */
- struct lru_gen_struct lrugen;
-+ /* to concurrently iterate lru_gen_mm_list */
-+ struct lru_gen_mm_state mm_state;
- #endif
- #ifdef CONFIG_MEMCG
- struct pglist_data *pgdat;
-@@ -1042,6 +1091,11 @@ typedef struct pglist_data {
-
- unsigned long flags;
-
-+#ifdef CONFIG_LRU_GEN
-+ /* kswap mm walk data */
-+ struct lru_gen_mm_walk mm_walk;
-+#endif
-+
- ZONE_PADDING(_pad2_)
-
- /* Per-node vmstats */
---- a/include/linux/swap.h
-+++ b/include/linux/swap.h
-@@ -137,6 +137,10 @@ union swap_header {
- */
- struct reclaim_state {
- unsigned long reclaimed_slab;
-+#ifdef CONFIG_LRU_GEN
-+ /* per-thread mm walk data */
-+ struct lru_gen_mm_walk *mm_walk;
-+#endif
- };
-
- #ifdef __KERNEL__
---- a/kernel/exit.c
-+++ b/kernel/exit.c
-@@ -469,6 +469,7 @@ assign_new_owner:
- goto retry;
- }
- WRITE_ONCE(mm->owner, c);
-+ lru_gen_migrate_mm(mm);
- task_unlock(c);
- put_task_struct(c);
- }
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -1091,6 +1091,7 @@ static struct mm_struct *mm_init(struct
- goto fail_nocontext;
-
- mm->user_ns = get_user_ns(user_ns);
-+ lru_gen_init_mm(mm);
- return mm;
-
- fail_nocontext:
-@@ -1133,6 +1134,7 @@ static inline void __mmput(struct mm_str
- }
- if (mm->binfmt)
- module_put(mm->binfmt->module);
-+ lru_gen_del_mm(mm);
- mmdrop(mm);
- }
-
-@@ -2625,6 +2627,13 @@ pid_t kernel_clone(struct kernel_clone_a
- get_task_struct(p);
- }
-
-+ if (IS_ENABLED(CONFIG_LRU_GEN) && !(clone_flags & CLONE_VM)) {
-+ /* lock the task to synchronize with memcg migration */
-+ task_lock(p);
-+ lru_gen_add_mm(p->mm);
-+ task_unlock(p);
-+ }
-+
- wake_up_new_task(p);
-
- /* forking complete and child started to run, tell ptracer */
---- a/kernel/sched/core.c
-+++ b/kernel/sched/core.c
-@@ -5014,6 +5014,7 @@ context_switch(struct rq *rq, struct tas
- * finish_task_switch()'s mmdrop().
- */
- switch_mm_irqs_off(prev->active_mm, next->mm, next);
-+ lru_gen_use_mm(next->mm);
-
- if (!prev->mm) { // from kernel
- /* will mmdrop() in finish_task_switch(). */
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -6213,6 +6213,30 @@ static void mem_cgroup_move_task(void)
- }
- #endif
-
-+#ifdef CONFIG_LRU_GEN
-+static void mem_cgroup_attach(struct cgroup_taskset *tset)
-+{
-+ struct task_struct *task;
-+ struct cgroup_subsys_state *css;
-+
-+ /* find the first leader if there is any */
-+ cgroup_taskset_for_each_leader(task, css, tset)
-+ break;
-+
-+ if (!task)
-+ return;
-+
-+ task_lock(task);
-+ if (task->mm && READ_ONCE(task->mm->owner) == task)
-+ lru_gen_migrate_mm(task->mm);
-+ task_unlock(task);
-+}
-+#else
-+static void mem_cgroup_attach(struct cgroup_taskset *tset)
-+{
-+}
-+#endif /* CONFIG_LRU_GEN */
-+
- static int seq_puts_memcg_tunable(struct seq_file *m, unsigned long value)
- {
- if (value == PAGE_COUNTER_MAX)
-@@ -6556,6 +6580,7 @@ struct cgroup_subsys memory_cgrp_subsys
- .css_reset = mem_cgroup_css_reset,
- .css_rstat_flush = mem_cgroup_css_rstat_flush,
- .can_attach = mem_cgroup_can_attach,
-+ .attach = mem_cgroup_attach,
- .cancel_attach = mem_cgroup_cancel_attach,
- .post_attach = mem_cgroup_move_task,
- .dfl_cftypes = memory_files,
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -50,6 +50,8 @@
- #include <linux/printk.h>
- #include <linux/dax.h>
- #include <linux/psi.h>
-+#include <linux/pagewalk.h>
-+#include <linux/shmem_fs.h>
-
- #include <asm/tlbflush.h>
- #include <asm/div64.h>
-@@ -2853,7 +2855,7 @@ static bool can_age_anon_pages(struct pg
- for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
- for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
-
--static struct lruvec __maybe_unused *get_lruvec(struct mem_cgroup *memcg, int nid)
-+static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
- {
- struct pglist_data *pgdat = NODE_DATA(nid);
-
-@@ -2899,6 +2901,371 @@ static bool __maybe_unused seq_is_valid(
- }
-
- /******************************************************************************
-+ * mm_struct list
-+ ******************************************************************************/
-+
-+static struct lru_gen_mm_list *get_mm_list(struct mem_cgroup *memcg)
-+{
-+ static struct lru_gen_mm_list mm_list = {
-+ .fifo = LIST_HEAD_INIT(mm_list.fifo),
-+ .lock = __SPIN_LOCK_UNLOCKED(mm_list.lock),
-+ };
-+
-+#ifdef CONFIG_MEMCG
-+ if (memcg)
-+ return &memcg->mm_list;
-+#endif
-+ VM_WARN_ON_ONCE(!mem_cgroup_disabled());
-+
-+ return &mm_list;
-+}
-+
-+void lru_gen_add_mm(struct mm_struct *mm)
-+{
-+ int nid;
-+ struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm);
-+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
-+
-+ VM_WARN_ON_ONCE(!list_empty(&mm->lru_gen.list));
-+#ifdef CONFIG_MEMCG
-+ VM_WARN_ON_ONCE(mm->lru_gen.memcg);
-+ mm->lru_gen.memcg = memcg;
-+#endif
-+ spin_lock(&mm_list->lock);
-+
-+ for_each_node_state(nid, N_MEMORY) {
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ if (!lruvec)
-+ continue;
-+
-+ /* the first addition since the last iteration */
-+ if (lruvec->mm_state.tail == &mm_list->fifo)
-+ lruvec->mm_state.tail = &mm->lru_gen.list;
-+ }
-+
-+ list_add_tail(&mm->lru_gen.list, &mm_list->fifo);
-+
-+ spin_unlock(&mm_list->lock);
-+}
-+
-+void lru_gen_del_mm(struct mm_struct *mm)
-+{
-+ int nid;
-+ struct lru_gen_mm_list *mm_list;
-+ struct mem_cgroup *memcg = NULL;
-+
-+ if (list_empty(&mm->lru_gen.list))
-+ return;
-+
-+#ifdef CONFIG_MEMCG
-+ memcg = mm->lru_gen.memcg;
-+#endif
-+ mm_list = get_mm_list(memcg);
-+
-+ spin_lock(&mm_list->lock);
-+
-+ for_each_node(nid) {
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ if (!lruvec)
-+ continue;
-+
-+ /* where the last iteration ended (exclusive) */
-+ if (lruvec->mm_state.tail == &mm->lru_gen.list)
-+ lruvec->mm_state.tail = lruvec->mm_state.tail->next;
-+
-+ /* where the current iteration continues (inclusive) */
-+ if (lruvec->mm_state.head != &mm->lru_gen.list)
-+ continue;
-+
-+ lruvec->mm_state.head = lruvec->mm_state.head->next;
-+ /* the deletion ends the current iteration */
-+ if (lruvec->mm_state.head == &mm_list->fifo)
-+ WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1);
-+ }
-+
-+ list_del_init(&mm->lru_gen.list);
-+
-+ spin_unlock(&mm_list->lock);
-+
-+#ifdef CONFIG_MEMCG
-+ mem_cgroup_put(mm->lru_gen.memcg);
-+ mm->lru_gen.memcg = NULL;
-+#endif
-+}
-+
-+#ifdef CONFIG_MEMCG
-+void lru_gen_migrate_mm(struct mm_struct *mm)
-+{
-+ struct mem_cgroup *memcg;
-+ struct task_struct *task = rcu_dereference_protected(mm->owner, true);
-+
-+ VM_WARN_ON_ONCE(task->mm != mm);
-+ lockdep_assert_held(&task->alloc_lock);
-+
-+ /* for mm_update_next_owner() */
-+ if (mem_cgroup_disabled())
-+ return;
-+
-+ rcu_read_lock();
-+ memcg = mem_cgroup_from_task(task);
-+ rcu_read_unlock();
-+ if (memcg == mm->lru_gen.memcg)
-+ return;
-+
-+ VM_WARN_ON_ONCE(!mm->lru_gen.memcg);
-+ VM_WARN_ON_ONCE(list_empty(&mm->lru_gen.list));
-+
-+ lru_gen_del_mm(mm);
-+ lru_gen_add_mm(mm);
-+}
-+#endif
-+
-+/*
-+ * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when
-+ * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of
-+ * bits in a bitmap, k is the number of hash functions and n is the number of
-+ * inserted items.
-+ *
-+ * Page table walkers use one of the two filters to reduce their search space.
-+ * To get rid of non-leaf entries that no longer have enough leaf entries, the
-+ * aging uses the double-buffering technique to flip to the other filter each
-+ * time it produces a new generation. For non-leaf entries that have enough
-+ * leaf entries, the aging carries them over to the next generation in
-+ * walk_pmd_range(); the eviction also report them when walking the rmap
-+ * in lru_gen_look_around().
-+ *
-+ * For future optimizations:
-+ * 1. It's not necessary to keep both filters all the time. The spare one can be
-+ * freed after the RCU grace period and reallocated if needed again.
-+ * 2. And when reallocating, it's worth scaling its size according to the number
-+ * of inserted entries in the other filter, to reduce the memory overhead on
-+ * small systems and false positives on large systems.
-+ * 3. Jenkins' hash function is an alternative to Knuth's.
-+ */
-+#define BLOOM_FILTER_SHIFT 15
-+
-+static inline int filter_gen_from_seq(unsigned long seq)
-+{
-+ return seq % NR_BLOOM_FILTERS;
-+}
-+
-+static void get_item_key(void *item, int *key)
-+{
-+ u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2);
-+
-+ BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32));
-+
-+ key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1);
-+ key[1] = hash >> BLOOM_FILTER_SHIFT;
-+}
-+
-+static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq)
-+{
-+ unsigned long *filter;
-+ int gen = filter_gen_from_seq(seq);
-+
-+ filter = lruvec->mm_state.filters[gen];
-+ if (filter) {
-+ bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT));
-+ return;
-+ }
-+
-+ filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT),
-+ __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
-+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
-+}
-+
-+static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
-+{
-+ int key[2];
-+ unsigned long *filter;
-+ int gen = filter_gen_from_seq(seq);
-+
-+ filter = READ_ONCE(lruvec->mm_state.filters[gen]);
-+ if (!filter)
-+ return;
-+
-+ get_item_key(item, key);
-+
-+ if (!test_bit(key[0], filter))
-+ set_bit(key[0], filter);
-+ if (!test_bit(key[1], filter))
-+ set_bit(key[1], filter);
-+}
-+
-+static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
-+{
-+ int key[2];
-+ unsigned long *filter;
-+ int gen = filter_gen_from_seq(seq);
-+
-+ filter = READ_ONCE(lruvec->mm_state.filters[gen]);
-+ if (!filter)
-+ return true;
-+
-+ get_item_key(item, key);
-+
-+ return test_bit(key[0], filter) && test_bit(key[1], filter);
-+}
-+
-+static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last)
-+{
-+ int i;
-+ int hist;
-+
-+ lockdep_assert_held(&get_mm_list(lruvec_memcg(lruvec))->lock);
-+
-+ if (walk) {
-+ hist = lru_hist_from_seq(walk->max_seq);
-+
-+ for (i = 0; i < NR_MM_STATS; i++) {
-+ WRITE_ONCE(lruvec->mm_state.stats[hist][i],
-+ lruvec->mm_state.stats[hist][i] + walk->mm_stats[i]);
-+ walk->mm_stats[i] = 0;
-+ }
-+ }
-+
-+ if (NR_HIST_GENS > 1 && last) {
-+ hist = lru_hist_from_seq(lruvec->mm_state.seq + 1);
-+
-+ for (i = 0; i < NR_MM_STATS; i++)
-+ WRITE_ONCE(lruvec->mm_state.stats[hist][i], 0);
-+ }
-+}
-+
-+static bool should_skip_mm(struct mm_struct *mm, struct lru_gen_mm_walk *walk)
-+{
-+ int type;
-+ unsigned long size = 0;
-+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec);
-+ int key = pgdat->node_id % BITS_PER_TYPE(mm->lru_gen.bitmap);
-+
-+ if (!walk->force_scan && !test_bit(key, &mm->lru_gen.bitmap))
-+ return true;
-+
-+ clear_bit(key, &mm->lru_gen.bitmap);
-+
-+ for (type = !walk->can_swap; type < ANON_AND_FILE; type++) {
-+ size += type ? get_mm_counter(mm, MM_FILEPAGES) :
-+ get_mm_counter(mm, MM_ANONPAGES) +
-+ get_mm_counter(mm, MM_SHMEMPAGES);
-+ }
-+
-+ if (size < MIN_LRU_BATCH)
-+ return true;
-+
-+ return !mmget_not_zero(mm);
-+}
-+
-+static bool iterate_mm_list(struct lruvec *lruvec, struct lru_gen_mm_walk *walk,
-+ struct mm_struct **iter)
-+{
-+ bool first = false;
-+ bool last = true;
-+ struct mm_struct *mm = NULL;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
-+ struct lru_gen_mm_state *mm_state = &lruvec->mm_state;
-+
-+ /*
-+ * There are four interesting cases for this page table walker:
-+ * 1. It tries to start a new iteration of mm_list with a stale max_seq;
-+ * there is nothing left to do.
-+ * 2. It's the first of the current generation, and it needs to reset
-+ * the Bloom filter for the next generation.
-+ * 3. It reaches the end of mm_list, and it needs to increment
-+ * mm_state->seq; the iteration is done.
-+ * 4. It's the last of the current generation, and it needs to reset the
-+ * mm stats counters for the next generation.
-+ */
-+ spin_lock(&mm_list->lock);
-+
-+ VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq);
-+ VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq);
-+ VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers);
-+
-+ if (walk->max_seq <= mm_state->seq) {
-+ if (!*iter)
-+ last = false;
-+ goto done;
-+ }
-+
-+ if (!mm_state->nr_walkers) {
-+ VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
-+
-+ mm_state->head = mm_list->fifo.next;
-+ first = true;
-+ }
-+
-+ while (!mm && mm_state->head != &mm_list->fifo) {
-+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
-+
-+ mm_state->head = mm_state->head->next;
-+
-+ /* force scan for those added after the last iteration */
-+ if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) {
-+ mm_state->tail = mm_state->head;
-+ walk->force_scan = true;
-+ }
-+
-+ if (should_skip_mm(mm, walk))
-+ mm = NULL;
-+ }
-+
-+ if (mm_state->head == &mm_list->fifo)
-+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
-+done:
-+ if (*iter && !mm)
-+ mm_state->nr_walkers--;
-+ if (!*iter && mm)
-+ mm_state->nr_walkers++;
-+
-+ if (mm_state->nr_walkers)
-+ last = false;
-+
-+ if (*iter || last)
-+ reset_mm_stats(lruvec, walk, last);
-+
-+ spin_unlock(&mm_list->lock);
-+
-+ if (mm && first)
-+ reset_bloom_filter(lruvec, walk->max_seq + 1);
-+
-+ if (*iter)
-+ mmput_async(*iter);
-+
-+ *iter = mm;
-+
-+ return last;
-+}
-+
-+static bool iterate_mm_list_nowalk(struct lruvec *lruvec, unsigned long max_seq)
-+{
-+ bool success = false;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
-+ struct lru_gen_mm_state *mm_state = &lruvec->mm_state;
-+
-+ spin_lock(&mm_list->lock);
-+
-+ VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq);
-+
-+ if (max_seq > mm_state->seq && !mm_state->nr_walkers) {
-+ VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
-+
-+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
-+ reset_mm_stats(lruvec, NULL, true);
-+ success = true;
-+ }
-+
-+ spin_unlock(&mm_list->lock);
-+
-+ return success;
-+}
-+
-+/******************************************************************************
- * refault feedback loop
- ******************************************************************************/
-
-@@ -3048,6 +3415,118 @@ static int page_inc_gen(struct lruvec *l
- return new_gen;
- }
-
-+static void update_batch_size(struct lru_gen_mm_walk *walk, struct page *page,
-+ int old_gen, int new_gen)
-+{
-+ int type = page_is_file_lru(page);
-+ int zone = page_zonenum(page);
-+ int delta = thp_nr_pages(page);
-+
-+ VM_WARN_ON_ONCE(old_gen >= MAX_NR_GENS);
-+ VM_WARN_ON_ONCE(new_gen >= MAX_NR_GENS);
-+
-+ walk->batched++;
-+
-+ walk->nr_pages[old_gen][type][zone] -= delta;
-+ walk->nr_pages[new_gen][type][zone] += delta;
-+}
-+
-+static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk)
-+{
-+ int gen, type, zone;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ walk->batched = 0;
-+
-+ for_each_gen_type_zone(gen, type, zone) {
-+ enum lru_list lru = type * LRU_INACTIVE_FILE;
-+ int delta = walk->nr_pages[gen][type][zone];
-+
-+ if (!delta)
-+ continue;
-+
-+ walk->nr_pages[gen][type][zone] = 0;
-+ WRITE_ONCE(lrugen->nr_pages[gen][type][zone],
-+ lrugen->nr_pages[gen][type][zone] + delta);
-+
-+ if (lru_gen_is_active(lruvec, gen))
-+ lru += LRU_ACTIVE;
-+ __update_lru_size(lruvec, lru, zone, delta);
-+ }
-+}
-+
-+static int should_skip_vma(unsigned long start, unsigned long end, struct mm_walk *args)
-+{
-+ struct address_space *mapping;
-+ struct vm_area_struct *vma = args->vma;
-+ struct lru_gen_mm_walk *walk = args->private;
-+
-+ if (!vma_is_accessible(vma))
-+ return true;
-+
-+ if (is_vm_hugetlb_page(vma))
-+ return true;
-+
-+ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ))
-+ return true;
-+
-+ if (vma == get_gate_vma(vma->vm_mm))
-+ return true;
-+
-+ if (vma_is_anonymous(vma))
-+ return !walk->can_swap;
-+
-+ if (WARN_ON_ONCE(!vma->vm_file || !vma->vm_file->f_mapping))
-+ return true;
-+
-+ mapping = vma->vm_file->f_mapping;
-+ if (mapping_unevictable(mapping))
-+ return true;
-+
-+ if (shmem_mapping(mapping))
-+ return !walk->can_swap;
-+
-+ /* to exclude special mappings like dax, etc. */
-+ return !mapping->a_ops->readpage;
-+}
-+
-+/*
-+ * Some userspace memory allocators map many single-page VMAs. Instead of
-+ * returning back to the PGD table for each of such VMAs, finish an entire PMD
-+ * table to reduce zigzags and improve cache performance.
-+ */
-+static bool get_next_vma(unsigned long mask, unsigned long size, struct mm_walk *args,
-+ unsigned long *vm_start, unsigned long *vm_end)
-+{
-+ unsigned long start = round_up(*vm_end, size);
-+ unsigned long end = (start | ~mask) + 1;
-+
-+ VM_WARN_ON_ONCE(mask & size);
-+ VM_WARN_ON_ONCE((start & mask) != (*vm_start & mask));
-+
-+ while (args->vma) {
-+ if (start >= args->vma->vm_end) {
-+ args->vma = args->vma->vm_next;
-+ continue;
-+ }
-+
-+ if (end && end <= args->vma->vm_start)
-+ return false;
-+
-+ if (should_skip_vma(args->vma->vm_start, args->vma->vm_end, args)) {
-+ args->vma = args->vma->vm_next;
-+ continue;
-+ }
-+
-+ *vm_start = max(start, args->vma->vm_start);
-+ *vm_end = min(end - 1, args->vma->vm_end - 1) + 1;
-+
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
- static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr)
- {
- unsigned long pfn = pte_pfn(pte);
-@@ -3066,8 +3545,28 @@ static unsigned long get_pte_pfn(pte_t p
- return pfn;
- }
-
-+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
-+static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned long addr)
-+{
-+ unsigned long pfn = pmd_pfn(pmd);
-+
-+ VM_WARN_ON_ONCE(addr < vma->vm_start || addr >= vma->vm_end);
-+
-+ if (!pmd_present(pmd) || is_huge_zero_pmd(pmd))
-+ return -1;
-+
-+ if (WARN_ON_ONCE(pmd_devmap(pmd)))
-+ return -1;
-+
-+ if (WARN_ON_ONCE(!pfn_valid(pfn)))
-+ return -1;
-+
-+ return pfn;
-+}
-+#endif
-+
- static struct page *get_pfn_page(unsigned long pfn, struct mem_cgroup *memcg,
-- struct pglist_data *pgdat)
-+ struct pglist_data *pgdat, bool can_swap)
- {
- struct page *page;
-
-@@ -3082,9 +3581,375 @@ static struct page *get_pfn_page(unsigne
- if (page_memcg_rcu(page) != memcg)
- return NULL;
-
-+ /* file VMAs can contain anon pages from COW */
-+ if (!page_is_file_lru(page) && !can_swap)
-+ return NULL;
-+
- return page;
- }
-
-+static bool suitable_to_scan(int total, int young)
-+{
-+ int n = clamp_t(int, cache_line_size() / sizeof(pte_t), 2, 8);
-+
-+ /* suitable if the average number of young PTEs per cacheline is >=1 */
-+ return young * n >= total;
-+}
-+
-+static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
-+ struct mm_walk *args)
-+{
-+ int i;
-+ pte_t *pte;
-+ spinlock_t *ptl;
-+ unsigned long addr;
-+ int total = 0;
-+ int young = 0;
-+ struct lru_gen_mm_walk *walk = args->private;
-+ struct mem_cgroup *memcg = lruvec_memcg(walk->lruvec);
-+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec);
-+ int old_gen, new_gen = lru_gen_from_seq(walk->max_seq);
-+
-+ VM_WARN_ON_ONCE(pmd_leaf(*pmd));
-+
-+ ptl = pte_lockptr(args->mm, pmd);
-+ if (!spin_trylock(ptl))
-+ return false;
-+
-+ arch_enter_lazy_mmu_mode();
-+
-+ pte = pte_offset_map(pmd, start & PMD_MASK);
-+restart:
-+ for (i = pte_index(start), addr = start; addr != end; i++, addr += PAGE_SIZE) {
-+ unsigned long pfn;
-+ struct page *page;
-+
-+ total++;
-+ walk->mm_stats[MM_LEAF_TOTAL]++;
-+
-+ pfn = get_pte_pfn(pte[i], args->vma, addr);
-+ if (pfn == -1)
-+ continue;
-+
-+ if (!pte_young(pte[i])) {
-+ walk->mm_stats[MM_LEAF_OLD]++;
-+ continue;
-+ }
-+
-+ page = get_pfn_page(pfn, memcg, pgdat, walk->can_swap);
-+ if (!page)
-+ continue;
-+
-+ if (!ptep_test_and_clear_young(args->vma, addr, pte + i))
-+ VM_WARN_ON_ONCE(true);
-+
-+ young++;
-+ walk->mm_stats[MM_LEAF_YOUNG]++;
-+
-+ if (pte_dirty(pte[i]) && !PageDirty(page) &&
-+ !(PageAnon(page) && PageSwapBacked(page) &&
-+ !PageSwapCache(page)))
-+ set_page_dirty(page);
-+
-+ old_gen = page_update_gen(page, new_gen);
-+ if (old_gen >= 0 && old_gen != new_gen)
-+ update_batch_size(walk, page, old_gen, new_gen);
-+ }
-+
-+ if (i < PTRS_PER_PTE && get_next_vma(PMD_MASK, PAGE_SIZE, args, &start, &end))
-+ goto restart;
-+
-+ pte_unmap(pte);
-+
-+ arch_leave_lazy_mmu_mode();
-+ spin_unlock(ptl);
-+
-+ return suitable_to_scan(total, young);
-+}
-+
-+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
-+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
-+ struct mm_walk *args, unsigned long *bitmap, unsigned long *start)
-+{
-+ int i;
-+ pmd_t *pmd;
-+ spinlock_t *ptl;
-+ struct lru_gen_mm_walk *walk = args->private;
-+ struct mem_cgroup *memcg = lruvec_memcg(walk->lruvec);
-+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec);
-+ int old_gen, new_gen = lru_gen_from_seq(walk->max_seq);
-+
-+ VM_WARN_ON_ONCE(pud_leaf(*pud));
-+
-+ /* try to batch at most 1+MIN_LRU_BATCH+1 entries */
-+ if (*start == -1) {
-+ *start = next;
-+ return;
-+ }
-+
-+ i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start);
-+ if (i && i <= MIN_LRU_BATCH) {
-+ __set_bit(i - 1, bitmap);
-+ return;
-+ }
-+
-+ pmd = pmd_offset(pud, *start);
-+
-+ ptl = pmd_lockptr(args->mm, pmd);
-+ if (!spin_trylock(ptl))
-+ goto done;
-+
-+ arch_enter_lazy_mmu_mode();
-+
-+ do {
-+ unsigned long pfn;
-+ struct page *page;
-+ unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start;
-+
-+ pfn = get_pmd_pfn(pmd[i], vma, addr);
-+ if (pfn == -1)
-+ goto next;
-+
-+ if (!pmd_trans_huge(pmd[i])) {
-+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG))
-+ pmdp_test_and_clear_young(vma, addr, pmd + i);
-+ goto next;
-+ }
-+
-+ page = get_pfn_page(pfn, memcg, pgdat, walk->can_swap);
-+ if (!page)
-+ goto next;
-+
-+ if (!pmdp_test_and_clear_young(vma, addr, pmd + i))
-+ goto next;
-+
-+ walk->mm_stats[MM_LEAF_YOUNG]++;
-+
-+ if (pmd_dirty(pmd[i]) && !PageDirty(page) &&
-+ !(PageAnon(page) && PageSwapBacked(page) &&
-+ !PageSwapCache(page)))
-+ set_page_dirty(page);
-+
-+ old_gen = page_update_gen(page, new_gen);
-+ if (old_gen >= 0 && old_gen != new_gen)
-+ update_batch_size(walk, page, old_gen, new_gen);
-+next:
-+ i = i > MIN_LRU_BATCH ? 0 : find_next_bit(bitmap, MIN_LRU_BATCH, i) + 1;
-+ } while (i <= MIN_LRU_BATCH);
-+
-+ arch_leave_lazy_mmu_mode();
-+ spin_unlock(ptl);
-+done:
-+ *start = -1;
-+ bitmap_zero(bitmap, MIN_LRU_BATCH);
-+}
-+#else
-+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
-+ struct mm_walk *args, unsigned long *bitmap, unsigned long *start)
-+{
-+}
-+#endif
-+
-+static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
-+ struct mm_walk *args)
-+{
-+ int i;
-+ pmd_t *pmd;
-+ unsigned long next;
-+ unsigned long addr;
-+ struct vm_area_struct *vma;
-+ unsigned long pos = -1;
-+ struct lru_gen_mm_walk *walk = args->private;
-+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {};
-+
-+ VM_WARN_ON_ONCE(pud_leaf(*pud));
-+
-+ /*
-+ * Finish an entire PMD in two passes: the first only reaches to PTE
-+ * tables to avoid taking the PMD lock; the second, if necessary, takes
-+ * the PMD lock to clear the accessed bit in PMD entries.
-+ */
-+ pmd = pmd_offset(pud, start & PUD_MASK);
-+restart:
-+ /* walk_pte_range() may call get_next_vma() */
-+ vma = args->vma;
-+ for (i = pmd_index(start), addr = start; addr != end; i++, addr = next) {
-+ pmd_t val = pmd_read_atomic(pmd + i);
-+
-+ /* for pmd_read_atomic() */
-+ barrier();
-+
-+ next = pmd_addr_end(addr, end);
-+
-+ if (!pmd_present(val) || is_huge_zero_pmd(val)) {
-+ walk->mm_stats[MM_LEAF_TOTAL]++;
-+ continue;
-+ }
-+
-+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-+ if (pmd_trans_huge(val)) {
-+ unsigned long pfn = pmd_pfn(val);
-+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec);
-+
-+ walk->mm_stats[MM_LEAF_TOTAL]++;
-+
-+ if (!pmd_young(val)) {
-+ walk->mm_stats[MM_LEAF_OLD]++;
-+ continue;
-+ }
-+
-+ /* try to avoid unnecessary memory loads */
-+ if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
-+ continue;
-+
-+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
-+ continue;
-+ }
-+#endif
-+ walk->mm_stats[MM_NONLEAF_TOTAL]++;
-+
-+#ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
-+ if (!pmd_young(val))
-+ continue;
-+
-+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
-+#endif
-+ if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i))
-+ continue;
-+
-+ walk->mm_stats[MM_NONLEAF_FOUND]++;
-+
-+ if (!walk_pte_range(&val, addr, next, args))
-+ continue;
-+
-+ walk->mm_stats[MM_NONLEAF_ADDED]++;
-+
-+ /* carry over to the next generation */
-+ update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i);
-+ }
-+
-+ walk_pmd_range_locked(pud, -1, vma, args, bitmap, &pos);
-+
-+ if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end))
-+ goto restart;
-+}
-+
-+static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
-+ struct mm_walk *args)
-+{
-+ int i;
-+ pud_t *pud;
-+ unsigned long addr;
-+ unsigned long next;
-+ struct lru_gen_mm_walk *walk = args->private;
-+
-+ VM_WARN_ON_ONCE(p4d_leaf(*p4d));
-+
-+ pud = pud_offset(p4d, start & P4D_MASK);
-+restart:
-+ for (i = pud_index(start), addr = start; addr != end; i++, addr = next) {
-+ pud_t val = READ_ONCE(pud[i]);
-+
-+ next = pud_addr_end(addr, end);
-+
-+ if (!pud_present(val) || WARN_ON_ONCE(pud_leaf(val)))
-+ continue;
-+
-+ walk_pmd_range(&val, addr, next, args);
-+
-+ /* a racy check to curtail the waiting time */
-+ if (wq_has_sleeper(&walk->lruvec->mm_state.wait))
-+ return 1;
-+
-+ if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
-+ end = (addr | ~PUD_MASK) + 1;
-+ goto done;
-+ }
-+ }
-+
-+ if (i < PTRS_PER_PUD && get_next_vma(P4D_MASK, PUD_SIZE, args, &start, &end))
-+ goto restart;
-+
-+ end = round_up(end, P4D_SIZE);
-+done:
-+ if (!end || !args->vma)
-+ return 1;
-+
-+ walk->next_addr = max(end, args->vma->vm_start);
-+
-+ return -EAGAIN;
-+}
-+
-+static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
-+{
-+ static const struct mm_walk_ops mm_walk_ops = {
-+ .test_walk = should_skip_vma,
-+ .p4d_entry = walk_pud_range,
-+ };
-+
-+ int err;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+
-+ walk->next_addr = FIRST_USER_ADDRESS;
-+
-+ do {
-+ err = -EBUSY;
-+
-+ /* page_update_gen() requires stable page_memcg() */
-+ if (!mem_cgroup_trylock_pages(memcg))
-+ break;
-+
-+ /* the caller might be holding the lock for write */
-+ if (mmap_read_trylock(mm)) {
-+ err = walk_page_range(mm, walk->next_addr, ULONG_MAX, &mm_walk_ops, walk);
-+
-+ mmap_read_unlock(mm);
-+ }
-+
-+ mem_cgroup_unlock_pages();
-+
-+ if (walk->batched) {
-+ spin_lock_irq(&lruvec->lru_lock);
-+ reset_batch_size(lruvec, walk);
-+ spin_unlock_irq(&lruvec->lru_lock);
-+ }
-+
-+ cond_resched();
-+ } while (err == -EAGAIN);
-+}
-+
-+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat)
-+{
-+ struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
-+
-+ if (pgdat && current_is_kswapd()) {
-+ VM_WARN_ON_ONCE(walk);
-+
-+ walk = &pgdat->mm_walk;
-+ } else if (!pgdat && !walk) {
-+ VM_WARN_ON_ONCE(current_is_kswapd());
-+
-+ walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
-+ }
-+
-+ current->reclaim_state->mm_walk = walk;
-+
-+ return walk;
-+}
-+
-+static void clear_mm_walk(void)
-+{
-+ struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
-+
-+ VM_WARN_ON_ONCE(walk && memchr_inv(walk->nr_pages, 0, sizeof(walk->nr_pages)));
-+ VM_WARN_ON_ONCE(walk && memchr_inv(walk->mm_stats, 0, sizeof(walk->mm_stats)));
-+
-+ current->reclaim_state->mm_walk = NULL;
-+
-+ if (!current_is_kswapd())
-+ kfree(walk);
-+}
-+
- static void inc_min_seq(struct lruvec *lruvec, int type)
- {
- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-@@ -3136,7 +4001,7 @@ next:
- return success;
- }
-
--static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, bool can_swap)
-+static void inc_max_seq(struct lruvec *lruvec, bool can_swap)
- {
- int prev, next;
- int type, zone;
-@@ -3146,9 +4011,6 @@ static void inc_max_seq(struct lruvec *l
-
- VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
-
-- if (max_seq != lrugen->max_seq)
-- goto unlock;
--
- for (type = ANON_AND_FILE - 1; type >= 0; type--) {
- if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
- continue;
-@@ -3186,10 +4048,76 @@ static void inc_max_seq(struct lruvec *l
-
- /* make sure preceding modifications appear */
- smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
--unlock:
-+
- spin_unlock_irq(&lruvec->lru_lock);
- }
-
-+static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
-+ struct scan_control *sc, bool can_swap)
-+{
-+ bool success;
-+ struct lru_gen_mm_walk *walk;
-+ struct mm_struct *mm = NULL;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq));
-+
-+ /* see the comment in iterate_mm_list() */
-+ if (max_seq <= READ_ONCE(lruvec->mm_state.seq)) {
-+ success = false;
-+ goto done;
-+ }
-+
-+ /*
-+ * If the hardware doesn't automatically set the accessed bit, fallback
-+ * to lru_gen_look_around(), which only clears the accessed bit in a
-+ * handful of PTEs. Spreading the work out over a period of time usually
-+ * is less efficient, but it avoids bursty page faults.
-+ */
-+ if (!arch_has_hw_pte_young()) {
-+ success = iterate_mm_list_nowalk(lruvec, max_seq);
-+ goto done;
-+ }
-+
-+ walk = set_mm_walk(NULL);
-+ if (!walk) {
-+ success = iterate_mm_list_nowalk(lruvec, max_seq);
-+ goto done;
-+ }
-+
-+ walk->lruvec = lruvec;
-+ walk->max_seq = max_seq;
-+ walk->can_swap = can_swap;
-+ walk->force_scan = false;
-+
-+ do {
-+ success = iterate_mm_list(lruvec, walk, &mm);
-+ if (mm)
-+ walk_mm(lruvec, mm, walk);
-+
-+ cond_resched();
-+ } while (mm);
-+done:
-+ if (!success) {
-+ if (sc->priority <= DEF_PRIORITY - 2)
-+ wait_event_killable(lruvec->mm_state.wait,
-+ max_seq < READ_ONCE(lrugen->max_seq));
-+
-+ return max_seq < READ_ONCE(lrugen->max_seq);
-+ }
-+
-+ VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
-+
-+ inc_max_seq(lruvec, can_swap);
-+ /* either this sees any waiters or they will see updated max_seq */
-+ if (wq_has_sleeper(&lruvec->mm_state.wait))
-+ wake_up_all(&lruvec->mm_state.wait);
-+
-+ wakeup_flusher_threads(WB_REASON_VMSCAN);
-+
-+ return true;
-+}
-+
- static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq,
- struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
- {
-@@ -3265,7 +4193,7 @@ static void age_lruvec(struct lruvec *lr
-
- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan);
- if (need_aging)
-- inc_max_seq(lruvec, max_seq, swappiness);
-+ try_to_inc_max_seq(lruvec, max_seq, sc, swappiness);
- }
-
- static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
-@@ -3274,6 +4202,8 @@ static void lru_gen_age_node(struct pgli
-
- VM_WARN_ON_ONCE(!current_is_kswapd());
-
-+ set_mm_walk(pgdat);
-+
- memcg = mem_cgroup_iter(NULL, NULL, NULL);
- do {
- struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
-@@ -3282,11 +4212,16 @@ static void lru_gen_age_node(struct pgli
-
- cond_resched();
- } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
-+
-+ clear_mm_walk();
- }
-
- /*
- * This function exploits spatial locality when shrink_page_list() walks the
-- * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages.
-+ * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If
-+ * the scan was done cacheline efficiently, it adds the PMD entry pointing to
-+ * the PTE table to the Bloom filter. This forms a feedback loop between the
-+ * eviction and the aging.
- */
- void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
- {
-@@ -3295,6 +4230,8 @@ void lru_gen_look_around(struct page_vma
- unsigned long start;
- unsigned long end;
- unsigned long addr;
-+ struct lru_gen_mm_walk *walk;
-+ int young = 0;
- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {};
- struct page *page = pvmw->page;
- struct mem_cgroup *memcg = page_memcg(page);
-@@ -3309,6 +4246,9 @@ void lru_gen_look_around(struct page_vma
- if (spin_is_contended(pvmw->ptl))
- return;
-
-+ /* avoid taking the LRU lock under the PTL when possible */
-+ walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
-+
- start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start);
- end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1;
-
-@@ -3338,13 +4278,15 @@ void lru_gen_look_around(struct page_vma
- if (!pte_young(pte[i]))
- continue;
-
-- page = get_pfn_page(pfn, memcg, pgdat);
-+ page = get_pfn_page(pfn, memcg, pgdat, !walk || walk->can_swap);
- if (!page)
- continue;
-
- if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i))
- VM_WARN_ON_ONCE(true);
-
-+ young++;
-+
- if (pte_dirty(pte[i]) && !PageDirty(page) &&
- !(PageAnon(page) && PageSwapBacked(page) &&
- !PageSwapCache(page)))
-@@ -3360,7 +4302,11 @@ void lru_gen_look_around(struct page_vma
- arch_leave_lazy_mmu_mode();
- rcu_read_unlock();
-
-- if (bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) {
-+ /* feedback from rmap walkers to page table walkers */
-+ if (suitable_to_scan(i, young))
-+ update_bloom_filter(lruvec, max_seq, pvmw->pmd);
-+
-+ if (!walk && bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) {
- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
- page = pte_page(pte[i]);
- activate_page(page);
-@@ -3372,8 +4318,10 @@ void lru_gen_look_around(struct page_vma
- if (!mem_cgroup_trylock_pages(memcg))
- return;
-
-- spin_lock_irq(&lruvec->lru_lock);
-- new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq);
-+ if (!walk) {
-+ spin_lock_irq(&lruvec->lru_lock);
-+ new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq);
-+ }
-
- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
- page = compound_head(pte_page(pte[i]));
-@@ -3384,10 +4332,14 @@ void lru_gen_look_around(struct page_vma
- if (old_gen < 0 || old_gen == new_gen)
- continue;
-
-- lru_gen_update_size(lruvec, page, old_gen, new_gen);
-+ if (walk)
-+ update_batch_size(walk, page, old_gen, new_gen);
-+ else
-+ lru_gen_update_size(lruvec, page, old_gen, new_gen);
- }
-
-- spin_unlock_irq(&lruvec->lru_lock);
-+ if (!walk)
-+ spin_unlock_irq(&lruvec->lru_lock);
-
- mem_cgroup_unlock_pages();
- }
-@@ -3670,6 +4622,7 @@ static int evict_pages(struct lruvec *lr
- struct page *page;
- enum vm_event_item item;
- struct reclaim_stat stat;
-+ struct lru_gen_mm_walk *walk;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-
-@@ -3706,6 +4659,10 @@ static int evict_pages(struct lruvec *lr
-
- move_pages_to_lru(lruvec, &list);
-
-+ walk = current->reclaim_state->mm_walk;
-+ if (walk && walk->batched)
-+ reset_batch_size(lruvec, walk);
-+
- item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT;
- if (!cgroup_reclaim(sc))
- __count_vm_events(item, reclaimed);
-@@ -3722,6 +4679,11 @@ static int evict_pages(struct lruvec *lr
- return scanned;
- }
-
-+/*
-+ * For future optimizations:
-+ * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
-+ * reclaim.
-+ */
- static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
- bool can_swap)
- {
-@@ -3747,7 +4709,8 @@ static unsigned long get_nr_to_scan(stru
- if (current_is_kswapd())
- return 0;
-
-- inc_max_seq(lruvec, max_seq, can_swap);
-+ if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap))
-+ return nr_to_scan;
- done:
- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
- }
-@@ -3761,6 +4724,8 @@ static void lru_gen_shrink_lruvec(struct
-
- blk_start_plug(&plug);
-
-+ set_mm_walk(lruvec_pgdat(lruvec));
-+
- while (true) {
- int delta;
- int swappiness;
-@@ -3788,6 +4753,8 @@ static void lru_gen_shrink_lruvec(struct
- cond_resched();
- }
-
-+ clear_mm_walk();
-+
- blk_finish_plug(&plug);
- }
-
-@@ -3804,15 +4771,21 @@ void lru_gen_init_lruvec(struct lruvec *
-
- for_each_gen_type_zone(gen, type, zone)
- INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]);
-+
-+ lruvec->mm_state.seq = MIN_NR_GENS;
-+ init_waitqueue_head(&lruvec->mm_state.wait);
- }
-
- #ifdef CONFIG_MEMCG
- void lru_gen_init_memcg(struct mem_cgroup *memcg)
- {
-+ INIT_LIST_HEAD(&memcg->mm_list.fifo);
-+ spin_lock_init(&memcg->mm_list.lock);
- }
-
- void lru_gen_exit_memcg(struct mem_cgroup *memcg)
- {
-+ int i;
- int nid;
-
- for_each_node(nid) {
-@@ -3820,6 +4793,11 @@ void lru_gen_exit_memcg(struct mem_cgrou
-
- VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
- sizeof(lruvec->lrugen.nr_pages)));
-+
-+ for (i = 0; i < NR_BLOOM_FILTERS; i++) {
-+ bitmap_free(lruvec->mm_state.filters[i]);
-+ lruvec->mm_state.filters[i] = NULL;
-+ }
- }
- }
- #endif
diff --git a/target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch b/target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch
deleted file mode 100644
index b5fb195151..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch
+++ /dev/null
@@ -1,315 +0,0 @@
-From 36a18a68ea458e8f4db2ca86b00091daf32c6c74 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:06 -0600
-Subject: [PATCH 09/29] mm: multi-gen LRU: optimize multiple memcgs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When multiple memcgs are available, it is possible to use generations as a
-frame of reference to make better choices and improve overall performance
-under global memory pressure. This patch adds a basic optimization to
-select memcgs that can drop single-use unmapped clean pages first. Doing
-so reduces the chance of going into the aging path or swapping, which can
-be costly.
-
-A typical example that benefits from this optimization is a server running
-mixed types of workloads, e.g., heavy anon workload in one memcg and heavy
-buffered I/O workload in the other.
-
-Though this optimization can be applied to both kswapd and direct reclaim,
-it is only added to kswapd to keep the patchset manageable. Later
-improvements may cover the direct reclaim path.
-
-While ensuring certain fairness to all eligible memcgs, proportional scans
-of individual memcgs also require proper backoff to avoid overshooting
-their aggregate reclaim target by too much. Otherwise it can cause high
-direct reclaim latency. The conditions for backoff are:
-
-1. At low priorities, for direct reclaim, if aging fairness or direct
- reclaim latency is at risk, i.e., aging one memcg multiple times or
- swapping after the target is met.
-2. At high priorities, for global reclaim, if per-zone free pages are
- above respective watermarks.
-
-Server benchmark results:
- Mixed workloads:
- fio (buffered I/O): +[19, 21]%
- IOPS BW
- patch1-8: 1880k 7343MiB/s
- patch1-9: 2252k 8796MiB/s
-
- memcached (anon): +[119, 123]%
- Ops/sec KB/sec
- patch1-8: 862768.65 33514.68
- patch1-9: 1911022.12 74234.54
-
- Mixed workloads:
- fio (buffered I/O): +[75, 77]%
- IOPS BW
- 5.19-rc1: 1279k 4996MiB/s
- patch1-9: 2252k 8796MiB/s
-
- memcached (anon): +[13, 15]%
- Ops/sec KB/sec
- 5.19-rc1: 1673524.04 65008.87
- patch1-9: 1911022.12 74234.54
-
- Configurations:
- (changes since patch 6)
-
- cat mixed.sh
- modprobe brd rd_nr=2 rd_size=56623104
-
- swapoff -a
- mkswap /dev/ram0
- swapon /dev/ram0
-
- mkfs.ext4 /dev/ram1
- mount -t ext4 /dev/ram1 /mnt
-
- memtier_benchmark -S /var/run/memcached/memcached.sock \
- -P memcache_binary -n allkeys --key-minimum=1 \
- --key-maximum=50000000 --key-pattern=P:P -c 1 -t 36 \
- --ratio 1:0 --pipeline 8 -d 2000
-
- fio -name=mglru --numjobs=36 --directory=/mnt --size=1408m \
- --buffered=1 --ioengine=io_uring --iodepth=128 \
- --iodepth_batch_submit=32 --iodepth_batch_complete=32 \
- --rw=randread --random_distribution=random --norandommap \
- --time_based --ramp_time=10m --runtime=90m --group_reporting &
- pid=$!
-
- sleep 200
-
- memtier_benchmark -S /var/run/memcached/memcached.sock \
- -P memcache_binary -n allkeys --key-minimum=1 \
- --key-maximum=50000000 --key-pattern=R:R -c 1 -t 36 \
- --ratio 0:1 --pipeline 8 --randomize --distinct-client-seed
-
- kill -INT $pid
- wait
-
-Client benchmark results:
- no change (CONFIG_MEMCG=n)
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-10-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 96 insertions(+), 9 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -127,6 +127,12 @@ struct scan_control {
- /* Always discard instead of demoting to lower tier memory */
- unsigned int no_demotion:1;
-
-+#ifdef CONFIG_LRU_GEN
-+ /* help kswapd make better choices among multiple memcgs */
-+ unsigned int memcgs_need_aging:1;
-+ unsigned long last_reclaimed;
-+#endif
-+
- /* Allocation order */
- s8 order;
-
-@@ -4202,6 +4208,19 @@ static void lru_gen_age_node(struct pgli
-
- VM_WARN_ON_ONCE(!current_is_kswapd());
-
-+ sc->last_reclaimed = sc->nr_reclaimed;
-+
-+ /*
-+ * To reduce the chance of going into the aging path, which can be
-+ * costly, optimistically skip it if the flag below was cleared in the
-+ * eviction path. This improves the overall performance when multiple
-+ * memcgs are available.
-+ */
-+ if (!sc->memcgs_need_aging) {
-+ sc->memcgs_need_aging = true;
-+ return;
-+ }
-+
- set_mm_walk(pgdat);
-
- memcg = mem_cgroup_iter(NULL, NULL, NULL);
-@@ -4613,7 +4632,8 @@ static int isolate_pages(struct lruvec *
- return scanned;
- }
-
--static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness)
-+static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
-+ bool *need_swapping)
- {
- int type;
- int scanned;
-@@ -4676,6 +4696,9 @@ static int evict_pages(struct lruvec *lr
-
- sc->nr_reclaimed += reclaimed;
-
-+ if (need_swapping && type == LRU_GEN_ANON)
-+ *need_swapping = true;
-+
- return scanned;
- }
-
-@@ -4685,9 +4708,8 @@ static int evict_pages(struct lruvec *lr
- * reclaim.
- */
- static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
-- bool can_swap)
-+ bool can_swap, bool *need_aging)
- {
-- bool need_aging;
- unsigned long nr_to_scan;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
-@@ -4697,8 +4719,8 @@ static unsigned long get_nr_to_scan(stru
- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
- return 0;
-
-- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan);
-- if (!need_aging)
-+ *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan);
-+ if (!*need_aging)
- return nr_to_scan;
-
- /* skip the aging path at the default priority */
-@@ -4715,10 +4737,68 @@ done:
- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
- }
-
-+static bool should_abort_scan(struct lruvec *lruvec, unsigned long seq,
-+ struct scan_control *sc, bool need_swapping)
-+{
-+ int i;
-+ DEFINE_MAX_SEQ(lruvec);
-+
-+ if (!current_is_kswapd()) {
-+ /* age each memcg once to ensure fairness */
-+ if (max_seq - seq > 1)
-+ return true;
-+
-+ /* over-swapping can increase allocation latency */
-+ if (sc->nr_reclaimed >= sc->nr_to_reclaim && need_swapping)
-+ return true;
-+
-+ /* give this thread a chance to exit and free its memory */
-+ if (fatal_signal_pending(current)) {
-+ sc->nr_reclaimed += MIN_LRU_BATCH;
-+ return true;
-+ }
-+
-+ if (cgroup_reclaim(sc))
-+ return false;
-+ } else if (sc->nr_reclaimed - sc->last_reclaimed < sc->nr_to_reclaim)
-+ return false;
-+
-+ /* keep scanning at low priorities to ensure fairness */
-+ if (sc->priority > DEF_PRIORITY - 2)
-+ return false;
-+
-+ /*
-+ * A minimum amount of work was done under global memory pressure. For
-+ * kswapd, it may be overshooting. For direct reclaim, the target isn't
-+ * met, and yet the allocation may still succeed, since kswapd may have
-+ * caught up. In either case, it's better to stop now, and restart if
-+ * necessary.
-+ */
-+ for (i = 0; i <= sc->reclaim_idx; i++) {
-+ unsigned long wmark;
-+ struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i;
-+
-+ if (!managed_zone(zone))
-+ continue;
-+
-+ wmark = current_is_kswapd() ? high_wmark_pages(zone) : low_wmark_pages(zone);
-+ if (wmark > zone_page_state(zone, NR_FREE_PAGES))
-+ return false;
-+ }
-+
-+ sc->nr_reclaimed += MIN_LRU_BATCH;
-+
-+ return true;
-+}
-+
- static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
- struct blk_plug plug;
-+ bool need_aging = false;
-+ bool need_swapping = false;
- unsigned long scanned = 0;
-+ unsigned long reclaimed = sc->nr_reclaimed;
-+ DEFINE_MAX_SEQ(lruvec);
-
- lru_add_drain();
-
-@@ -4738,21 +4818,28 @@ static void lru_gen_shrink_lruvec(struct
- else
- swappiness = 0;
-
-- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
-+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging);
- if (!nr_to_scan)
-- break;
-+ goto done;
-
-- delta = evict_pages(lruvec, sc, swappiness);
-+ delta = evict_pages(lruvec, sc, swappiness, &need_swapping);
- if (!delta)
-- break;
-+ goto done;
-
- scanned += delta;
- if (scanned >= nr_to_scan)
- break;
-
-+ if (should_abort_scan(lruvec, max_seq, sc, need_swapping))
-+ break;
-+
- cond_resched();
- }
-
-+ /* see the comment in lru_gen_age_node() */
-+ if (sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH && !need_aging)
-+ sc->memcgs_need_aging = false;
-+done:
- clear_mm_walk();
-
- blk_finish_plug(&plug);
diff --git a/target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch b/target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch
deleted file mode 100644
index 8ee032fb0f..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch
+++ /dev/null
@@ -1,498 +0,0 @@
-From 640db3a029dca909af47157ca18f52b29d34a1b9 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:07 -0600
-Subject: [PATCH 10/29] mm: multi-gen LRU: kill switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add /sys/kernel/mm/lru_gen/enabled as a kill switch. Components that
-can be disabled include:
- 0x0001: the multi-gen LRU core
- 0x0002: walking page table, when arch_has_hw_pte_young() returns
- true
- 0x0004: clearing the accessed bit in non-leaf PMD entries, when
- CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y
- [yYnN]: apply to all the components above
-E.g.,
- echo y >/sys/kernel/mm/lru_gen/enabled
- cat /sys/kernel/mm/lru_gen/enabled
- 0x0007
- echo 5 >/sys/kernel/mm/lru_gen/enabled
- cat /sys/kernel/mm/lru_gen/enabled
- 0x0005
-
-NB: the page table walks happen on the scale of seconds under heavy memory
-pressure, in which case the mmap_lock contention is a lesser concern,
-compared with the LRU lock contention and the I/O congestion. So far the
-only well-known case of the mmap_lock contention happens on Android, due
-to Scudo [1] which allocates several thousand VMAs for merely a few
-hundred MBs. The SPF and the Maple Tree also have provided their own
-assessments [2][3]. However, if walking page tables does worsen the
-mmap_lock contention, the kill switch can be used to disable it. In this
-case the multi-gen LRU will suffer a minor performance degradation, as
-shown previously.
-
-Clearing the accessed bit in non-leaf PMD entries can also be disabled,
-since this behavior was not tested on x86 varieties other than Intel and
-AMD.
-
-[1] https://source.android.com/devices/tech/debug/scudo
-[2] https://lore.kernel.org/r/20220128131006.67712-1-michel@lespinasse.org/
-[3] https://lore.kernel.org/r/20220426150616.3937571-1-Liam.Howlett@oracle.com/
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-11-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/cgroup.h | 15 ++-
- include/linux/mm_inline.h | 15 ++-
- include/linux/mmzone.h | 9 ++
- kernel/cgroup/cgroup-internal.h | 1 -
- mm/Kconfig | 6 +
- mm/vmscan.c | 228 +++++++++++++++++++++++++++++++-
- 6 files changed, 265 insertions(+), 9 deletions(-)
-
---- a/include/linux/cgroup.h
-+++ b/include/linux/cgroup.h
-@@ -433,6 +433,18 @@ static inline void cgroup_put(struct cgr
- css_put(&cgrp->self);
- }
-
-+extern struct mutex cgroup_mutex;
-+
-+static inline void cgroup_lock(void)
-+{
-+ mutex_lock(&cgroup_mutex);
-+}
-+
-+static inline void cgroup_unlock(void)
-+{
-+ mutex_unlock(&cgroup_mutex);
-+}
-+
- /**
- * task_css_set_check - obtain a task's css_set with extra access conditions
- * @task: the task to obtain css_set for
-@@ -447,7 +459,6 @@ static inline void cgroup_put(struct cgr
- * as locks used during the cgroup_subsys::attach() methods.
- */
- #ifdef CONFIG_PROVE_RCU
--extern struct mutex cgroup_mutex;
- extern spinlock_t css_set_lock;
- #define task_css_set_check(task, __c) \
- rcu_dereference_check((task)->cgroups, \
-@@ -709,6 +720,8 @@ struct cgroup;
- static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; }
- static inline void css_get(struct cgroup_subsys_state *css) {}
- static inline void css_put(struct cgroup_subsys_state *css) {}
-+static inline void cgroup_lock(void) {}
-+static inline void cgroup_unlock(void) {}
- static inline int cgroup_attach_task_all(struct task_struct *from,
- struct task_struct *t) { return 0; }
- static inline int cgroupstats_build(struct cgroupstats *stats,
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -91,10 +91,21 @@ static __always_inline enum lru_list pag
-
- #ifdef CONFIG_LRU_GEN
-
-+#ifdef CONFIG_LRU_GEN_ENABLED
- static inline bool lru_gen_enabled(void)
- {
-- return true;
-+ DECLARE_STATIC_KEY_TRUE(lru_gen_caps[NR_LRU_GEN_CAPS]);
-+
-+ return static_branch_likely(&lru_gen_caps[LRU_GEN_CORE]);
-+}
-+#else
-+static inline bool lru_gen_enabled(void)
-+{
-+ DECLARE_STATIC_KEY_FALSE(lru_gen_caps[NR_LRU_GEN_CAPS]);
-+
-+ return static_branch_unlikely(&lru_gen_caps[LRU_GEN_CORE]);
- }
-+#endif
-
- static inline bool lru_gen_in_fault(void)
- {
-@@ -207,7 +218,7 @@ static inline bool lru_gen_add_page(stru
-
- VM_WARN_ON_ONCE_PAGE(gen != -1, page);
-
-- if (PageUnevictable(page))
-+ if (PageUnevictable(page) || !lrugen->enabled)
- return false;
- /*
- * There are three common cases for this page:
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -364,6 +364,13 @@ enum {
- LRU_GEN_FILE,
- };
-
-+enum {
-+ LRU_GEN_CORE,
-+ LRU_GEN_MM_WALK,
-+ LRU_GEN_NONLEAF_YOUNG,
-+ NR_LRU_GEN_CAPS
-+};
-+
- #define MIN_LRU_BATCH BITS_PER_LONG
- #define MAX_LRU_BATCH (MIN_LRU_BATCH * 64)
-
-@@ -405,6 +412,8 @@ struct lru_gen_struct {
- /* can be modified without holding the LRU lock */
- atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
- atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
-+ /* whether the multi-gen LRU is enabled */
-+ bool enabled;
- };
-
- enum {
---- a/kernel/cgroup/cgroup-internal.h
-+++ b/kernel/cgroup/cgroup-internal.h
-@@ -165,7 +165,6 @@ struct cgroup_mgctx {
- #define DEFINE_CGROUP_MGCTX(name) \
- struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name)
-
--extern struct mutex cgroup_mutex;
- extern spinlock_t css_set_lock;
- extern struct cgroup_subsys *cgroup_subsys[];
- extern struct list_head cgroup_roots;
---- a/mm/Kconfig
-+++ b/mm/Kconfig
-@@ -906,6 +906,12 @@ config LRU_GEN
- help
- A high performance LRU implementation to overcommit memory.
-
-+config LRU_GEN_ENABLED
-+ bool "Enable by default"
-+ depends on LRU_GEN
-+ help
-+ This option enables the multi-gen LRU by default.
-+
- config LRU_GEN_STATS
- bool "Full stats for debugging"
- depends on LRU_GEN
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -52,6 +52,7 @@
- #include <linux/psi.h>
- #include <linux/pagewalk.h>
- #include <linux/shmem_fs.h>
-+#include <linux/ctype.h>
-
- #include <asm/tlbflush.h>
- #include <asm/div64.h>
-@@ -2841,6 +2842,14 @@ static bool can_age_anon_pages(struct pg
-
- #ifdef CONFIG_LRU_GEN
-
-+#ifdef CONFIG_LRU_GEN_ENABLED
-+DEFINE_STATIC_KEY_ARRAY_TRUE(lru_gen_caps, NR_LRU_GEN_CAPS);
-+#define get_cap(cap) static_branch_likely(&lru_gen_caps[cap])
-+#else
-+DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_caps, NR_LRU_GEN_CAPS);
-+#define get_cap(cap) static_branch_unlikely(&lru_gen_caps[cap])
-+#endif
-+
- /******************************************************************************
- * shorthand helpers
- ******************************************************************************/
-@@ -3717,7 +3726,8 @@ static void walk_pmd_range_locked(pud_t
- goto next;
-
- if (!pmd_trans_huge(pmd[i])) {
-- if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG))
-+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) &&
-+ get_cap(LRU_GEN_NONLEAF_YOUNG))
- pmdp_test_and_clear_young(vma, addr, pmd + i);
- goto next;
- }
-@@ -3815,10 +3825,12 @@ restart:
- walk->mm_stats[MM_NONLEAF_TOTAL]++;
-
- #ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
-- if (!pmd_young(val))
-- continue;
-+ if (get_cap(LRU_GEN_NONLEAF_YOUNG)) {
-+ if (!pmd_young(val))
-+ continue;
-
-- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
-+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
-+ }
- #endif
- if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i))
- continue;
-@@ -4080,7 +4092,7 @@ static bool try_to_inc_max_seq(struct lr
- * handful of PTEs. Spreading the work out over a period of time usually
- * is less efficient, but it avoids bursty page faults.
- */
-- if (!arch_has_hw_pte_young()) {
-+ if (!(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) {
- success = iterate_mm_list_nowalk(lruvec, max_seq);
- goto done;
- }
-@@ -4846,6 +4858,208 @@ done:
- }
-
- /******************************************************************************
-+ * state change
-+ ******************************************************************************/
-+
-+static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
-+{
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ if (lrugen->enabled) {
-+ enum lru_list lru;
-+
-+ for_each_evictable_lru(lru) {
-+ if (!list_empty(&lruvec->lists[lru]))
-+ return false;
-+ }
-+ } else {
-+ int gen, type, zone;
-+
-+ for_each_gen_type_zone(gen, type, zone) {
-+ if (!list_empty(&lrugen->lists[gen][type][zone]))
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+static bool fill_evictable(struct lruvec *lruvec)
-+{
-+ enum lru_list lru;
-+ int remaining = MAX_LRU_BATCH;
-+
-+ for_each_evictable_lru(lru) {
-+ int type = is_file_lru(lru);
-+ bool active = is_active_lru(lru);
-+ struct list_head *head = &lruvec->lists[lru];
-+
-+ while (!list_empty(head)) {
-+ bool success;
-+ struct page *page = lru_to_page(head);
-+
-+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page);
-+ VM_WARN_ON_ONCE_PAGE(PageActive(page) != active, page);
-+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page);
-+ VM_WARN_ON_ONCE_PAGE(page_lru_gen(page) != -1, page);
-+
-+ del_page_from_lru_list(page, lruvec);
-+ success = lru_gen_add_page(lruvec, page, false);
-+ VM_WARN_ON_ONCE(!success);
-+
-+ if (!--remaining)
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+static bool drain_evictable(struct lruvec *lruvec)
-+{
-+ int gen, type, zone;
-+ int remaining = MAX_LRU_BATCH;
-+
-+ for_each_gen_type_zone(gen, type, zone) {
-+ struct list_head *head = &lruvec->lrugen.lists[gen][type][zone];
-+
-+ while (!list_empty(head)) {
-+ bool success;
-+ struct page *page = lru_to_page(head);
-+
-+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page);
-+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page);
-+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page);
-+ VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page);
-+
-+ success = lru_gen_del_page(lruvec, page, false);
-+ VM_WARN_ON_ONCE(!success);
-+ add_page_to_lru_list(page, lruvec);
-+
-+ if (!--remaining)
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+static void lru_gen_change_state(bool enabled)
-+{
-+ static DEFINE_MUTEX(state_mutex);
-+
-+ struct mem_cgroup *memcg;
-+
-+ cgroup_lock();
-+ cpus_read_lock();
-+ get_online_mems();
-+ mutex_lock(&state_mutex);
-+
-+ if (enabled == lru_gen_enabled())
-+ goto unlock;
-+
-+ if (enabled)
-+ static_branch_enable_cpuslocked(&lru_gen_caps[LRU_GEN_CORE]);
-+ else
-+ static_branch_disable_cpuslocked(&lru_gen_caps[LRU_GEN_CORE]);
-+
-+ memcg = mem_cgroup_iter(NULL, NULL, NULL);
-+ do {
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ if (!lruvec)
-+ continue;
-+
-+ spin_lock_irq(&lruvec->lru_lock);
-+
-+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
-+ VM_WARN_ON_ONCE(!state_is_valid(lruvec));
-+
-+ lruvec->lrugen.enabled = enabled;
-+
-+ while (!(enabled ? fill_evictable(lruvec) : drain_evictable(lruvec))) {
-+ spin_unlock_irq(&lruvec->lru_lock);
-+ cond_resched();
-+ spin_lock_irq(&lruvec->lru_lock);
-+ }
-+
-+ spin_unlock_irq(&lruvec->lru_lock);
-+ }
-+
-+ cond_resched();
-+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
-+unlock:
-+ mutex_unlock(&state_mutex);
-+ put_online_mems();
-+ cpus_read_unlock();
-+ cgroup_unlock();
-+}
-+
-+/******************************************************************************
-+ * sysfs interface
-+ ******************************************************************************/
-+
-+static ssize_t show_enabled(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
-+{
-+ unsigned int caps = 0;
-+
-+ if (get_cap(LRU_GEN_CORE))
-+ caps |= BIT(LRU_GEN_CORE);
-+
-+ if (arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))
-+ caps |= BIT(LRU_GEN_MM_WALK);
-+
-+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && get_cap(LRU_GEN_NONLEAF_YOUNG))
-+ caps |= BIT(LRU_GEN_NONLEAF_YOUNG);
-+
-+ return snprintf(buf, PAGE_SIZE, "0x%04x\n", caps);
-+}
-+
-+static ssize_t store_enabled(struct kobject *kobj, struct kobj_attribute *attr,
-+ const char *buf, size_t len)
-+{
-+ int i;
-+ unsigned int caps;
-+
-+ if (tolower(*buf) == 'n')
-+ caps = 0;
-+ else if (tolower(*buf) == 'y')
-+ caps = -1;
-+ else if (kstrtouint(buf, 0, &caps))
-+ return -EINVAL;
-+
-+ for (i = 0; i < NR_LRU_GEN_CAPS; i++) {
-+ bool enabled = caps & BIT(i);
-+
-+ if (i == LRU_GEN_CORE)
-+ lru_gen_change_state(enabled);
-+ else if (enabled)
-+ static_branch_enable(&lru_gen_caps[i]);
-+ else
-+ static_branch_disable(&lru_gen_caps[i]);
-+ }
-+
-+ return len;
-+}
-+
-+static struct kobj_attribute lru_gen_enabled_attr = __ATTR(
-+ enabled, 0644, show_enabled, store_enabled
-+);
-+
-+static struct attribute *lru_gen_attrs[] = {
-+ &lru_gen_enabled_attr.attr,
-+ NULL
-+};
-+
-+static struct attribute_group lru_gen_attr_group = {
-+ .name = "lru_gen",
-+ .attrs = lru_gen_attrs,
-+};
-+
-+/******************************************************************************
- * initialization
- ******************************************************************************/
-
-@@ -4855,6 +5069,7 @@ void lru_gen_init_lruvec(struct lruvec *
- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-
- lrugen->max_seq = MIN_NR_GENS + 1;
-+ lrugen->enabled = lru_gen_enabled();
-
- for_each_gen_type_zone(gen, type, zone)
- INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]);
-@@ -4894,6 +5109,9 @@ static int __init init_lru_gen(void)
- BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS);
- BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS);
-
-+ if (sysfs_create_group(mm_kobj, &lru_gen_attr_group))
-+ pr_err("lru_gen: failed to create sysfs group\n");
-+
- return 0;
- };
- late_initcall(init_lru_gen);
diff --git a/target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch b/target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch
deleted file mode 100644
index 30e20aff6e..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch
+++ /dev/null
@@ -1,226 +0,0 @@
-From 73d1ff551760f0c79c47ab70faa4c2ca91413f5c Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:08 -0600
-Subject: [PATCH 11/29] mm: multi-gen LRU: thrashing prevention
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention, as
-requested by many desktop users [1].
-
-When set to value N, it prevents the working set of N milliseconds from
-getting evicted. The OOM killer is triggered if this working set cannot
-be kept in memory. Based on the average human detectable lag (~100ms),
-N=1000 usually eliminates intolerable lags due to thrashing. Larger
-values like N=3000 make lags less noticeable at the risk of premature OOM
-kills.
-
-Compared with the size-based approach [2], this time-based approach
-has the following advantages:
-
-1. It is easier to configure because it is agnostic to applications
- and memory sizes.
-2. It is more reliable because it is directly wired to the OOM killer.
-
-[1] https://lore.kernel.org/r/Ydza%2FzXKY9ATRoh6@google.com/
-[2] https://lore.kernel.org/r/20101028191523.GA14972@google.com/
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-12-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Qi Zheng <zhengqi.arch@bytedance.com>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mmzone.h | 2 ++
- mm/vmscan.c | 74 ++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 73 insertions(+), 3 deletions(-)
-
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -399,6 +399,8 @@ struct lru_gen_struct {
- unsigned long max_seq;
- /* the eviction increments the oldest generation numbers */
- unsigned long min_seq[ANON_AND_FILE];
-+ /* the birth time of each generation in jiffies */
-+ unsigned long timestamps[MAX_NR_GENS];
- /* the multi-gen LRU lists, lazily sorted on eviction */
- struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
- /* the multi-gen LRU sizes, eventually consistent */
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4064,6 +4064,7 @@ static void inc_max_seq(struct lruvec *l
- for (type = 0; type < ANON_AND_FILE; type++)
- reset_ctrl_pos(lruvec, type, false);
-
-+ WRITE_ONCE(lrugen->timestamps[next], jiffies);
- /* make sure preceding modifications appear */
- smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
-
-@@ -4193,7 +4194,7 @@ static bool should_run_aging(struct lruv
- return false;
- }
-
--static void age_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl)
- {
- bool need_aging;
- unsigned long nr_to_scan;
-@@ -4207,16 +4208,36 @@ static void age_lruvec(struct lruvec *lr
- mem_cgroup_calculate_protection(NULL, memcg);
-
- if (mem_cgroup_below_min(memcg))
-- return;
-+ return false;
-
- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan);
-+
-+ if (min_ttl) {
-+ int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
-+ unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-+
-+ if (time_is_after_jiffies(birth + min_ttl))
-+ return false;
-+
-+ /* the size is likely too small to be helpful */
-+ if (!nr_to_scan && sc->priority != DEF_PRIORITY)
-+ return false;
-+ }
-+
- if (need_aging)
- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness);
-+
-+ return true;
- }
-
-+/* to protect the working set of the last N jiffies */
-+static unsigned long lru_gen_min_ttl __read_mostly;
-+
- static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
- {
- struct mem_cgroup *memcg;
-+ bool success = false;
-+ unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
-
- VM_WARN_ON_ONCE(!current_is_kswapd());
-
-@@ -4239,12 +4260,32 @@ static void lru_gen_age_node(struct pgli
- do {
- struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
-
-- age_lruvec(lruvec, sc);
-+ if (age_lruvec(lruvec, sc, min_ttl))
-+ success = true;
-
- cond_resched();
- } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
-
- clear_mm_walk();
-+
-+ /* check the order to exclude compaction-induced reclaim */
-+ if (success || !min_ttl || sc->order)
-+ return;
-+
-+ /*
-+ * The main goal is to OOM kill if every generation from all memcgs is
-+ * younger than min_ttl. However, another possibility is all memcgs are
-+ * either below min or empty.
-+ */
-+ if (mutex_trylock(&oom_lock)) {
-+ struct oom_control oc = {
-+ .gfp_mask = sc->gfp_mask,
-+ };
-+
-+ out_of_memory(&oc);
-+
-+ mutex_unlock(&oom_lock);
-+ }
- }
-
- /*
-@@ -5002,6 +5043,28 @@ unlock:
- * sysfs interface
- ******************************************************************************/
-
-+static ssize_t show_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
-+{
-+ return sprintf(buf, "%u\n", jiffies_to_msecs(READ_ONCE(lru_gen_min_ttl)));
-+}
-+
-+static ssize_t store_min_ttl(struct kobject *kobj, struct kobj_attribute *attr,
-+ const char *buf, size_t len)
-+{
-+ unsigned int msecs;
-+
-+ if (kstrtouint(buf, 0, &msecs))
-+ return -EINVAL;
-+
-+ WRITE_ONCE(lru_gen_min_ttl, msecs_to_jiffies(msecs));
-+
-+ return len;
-+}
-+
-+static struct kobj_attribute lru_gen_min_ttl_attr = __ATTR(
-+ min_ttl_ms, 0644, show_min_ttl, store_min_ttl
-+);
-+
- static ssize_t show_enabled(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
- {
- unsigned int caps = 0;
-@@ -5050,6 +5113,7 @@ static struct kobj_attribute lru_gen_ena
- );
-
- static struct attribute *lru_gen_attrs[] = {
-+ &lru_gen_min_ttl_attr.attr,
- &lru_gen_enabled_attr.attr,
- NULL
- };
-@@ -5065,12 +5129,16 @@ static struct attribute_group lru_gen_at
-
- void lru_gen_init_lruvec(struct lruvec *lruvec)
- {
-+ int i;
- int gen, type, zone;
- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-
- lrugen->max_seq = MIN_NR_GENS + 1;
- lrugen->enabled = lru_gen_enabled();
-
-+ for (i = 0; i <= MIN_NR_GENS + 1; i++)
-+ lrugen->timestamps[i] = jiffies;
-+
- for_each_gen_type_zone(gen, type, zone)
- INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]);
-
diff --git a/target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch b/target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch
deleted file mode 100644
index 482e714bb6..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch
+++ /dev/null
@@ -1,579 +0,0 @@
-From 530716d008ca26315f246cd70dc1cefc636beaa4 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 18 Sep 2022 02:00:09 -0600
-Subject: [PATCH 12/29] mm: multi-gen LRU: debugfs interface
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add /sys/kernel/debug/lru_gen for working set estimation and proactive
-reclaim. These techniques are commonly used to optimize job scheduling
-(bin packing) in data centers [1][2].
-
-Compared with the page table-based approach and the PFN-based
-approach, this lruvec-based approach has the following advantages:
-1. It offers better choices because it is aware of memcgs, NUMA nodes,
- shared mappings and unmapped page cache.
-2. It is more scalable because it is O(nr_hot_pages), whereas the
- PFN-based approach is O(nr_total_pages).
-
-Add /sys/kernel/debug/lru_gen_full for debugging.
-
-[1] https://dl.acm.org/doi/10.1145/3297858.3304053
-[2] https://dl.acm.org/doi/10.1145/3503222.3507731
-
-Link: https://lkml.kernel.org/r/20220918080010.2920238-13-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reviewed-by: Qi Zheng <zhengqi.arch@bytedance.com>
-Acked-by: Brian Geffon <bgeffon@google.com>
-Acked-by: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Acked-by: Oleksandr Natalenko <oleksandr@natalenko.name>
-Acked-by: Steven Barrett <steven@liquorix.net>
-Acked-by: Suleiman Souhlal <suleiman@google.com>
-Tested-by: Daniel Byrne <djbyrne@mtu.edu>
-Tested-by: Donald Carr <d@chaos-reins.com>
-Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
-Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
-Tested-by: Shuang Zhai <szhai2@cs.rochester.edu>
-Tested-by: Sofia Trinh <sofia.trinh@edi.works>
-Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
-Cc: Barry Song <baohua@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Hillf Danton <hdanton@sina.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Matthew Wilcox <willy@infradead.org>
-Cc: Mel Gorman <mgorman@suse.de>
-Cc: Miaohe Lin <linmiaohe@huawei.com>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Mike Rapoport <rppt@linux.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Will Deacon <will@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/nodemask.h | 1 +
- mm/vmscan.c | 411 ++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 402 insertions(+), 10 deletions(-)
-
---- a/include/linux/nodemask.h
-+++ b/include/linux/nodemask.h
-@@ -485,6 +485,7 @@ static inline int num_node_state(enum no
- #define first_online_node 0
- #define first_memory_node 0
- #define next_online_node(nid) (MAX_NUMNODES)
-+#define next_memory_node(nid) (MAX_NUMNODES)
- #define nr_node_ids 1U
- #define nr_online_nodes 1U
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -53,6 +53,7 @@
- #include <linux/pagewalk.h>
- #include <linux/shmem_fs.h>
- #include <linux/ctype.h>
-+#include <linux/debugfs.h>
-
- #include <asm/tlbflush.h>
- #include <asm/div64.h>
-@@ -3968,12 +3969,40 @@ static void clear_mm_walk(void)
- kfree(walk);
- }
-
--static void inc_min_seq(struct lruvec *lruvec, int type)
-+static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
- {
-+ int zone;
-+ int remaining = MAX_LRU_BATCH;
- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
-+
-+ if (type == LRU_GEN_ANON && !can_swap)
-+ goto done;
-+
-+ /* prevent cold/hot inversion if force_scan is true */
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++) {
-+ struct list_head *head = &lrugen->lists[old_gen][type][zone];
-+
-+ while (!list_empty(head)) {
-+ struct page *page = lru_to_page(head);
-+
-+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page);
-+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page);
-+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page);
-+ VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page);
-
-+ new_gen = page_inc_gen(lruvec, page, false);
-+ list_move_tail(&page->lru, &lrugen->lists[new_gen][type][zone]);
-+
-+ if (!--remaining)
-+ return false;
-+ }
-+ }
-+done:
- reset_ctrl_pos(lruvec, type, true);
- WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1);
-+
-+ return true;
- }
-
- static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
-@@ -4019,7 +4048,7 @@ next:
- return success;
- }
-
--static void inc_max_seq(struct lruvec *lruvec, bool can_swap)
-+static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan)
- {
- int prev, next;
- int type, zone;
-@@ -4033,9 +4062,13 @@ static void inc_max_seq(struct lruvec *l
- if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
- continue;
-
-- VM_WARN_ON_ONCE(type == LRU_GEN_FILE || can_swap);
-+ VM_WARN_ON_ONCE(!force_scan && (type == LRU_GEN_FILE || can_swap));
-
-- inc_min_seq(lruvec, type);
-+ while (!inc_min_seq(lruvec, type, can_swap)) {
-+ spin_unlock_irq(&lruvec->lru_lock);
-+ cond_resched();
-+ spin_lock_irq(&lruvec->lru_lock);
-+ }
- }
-
- /*
-@@ -4072,7 +4105,7 @@ static void inc_max_seq(struct lruvec *l
- }
-
- static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
-- struct scan_control *sc, bool can_swap)
-+ struct scan_control *sc, bool can_swap, bool force_scan)
- {
- bool success;
- struct lru_gen_mm_walk *walk;
-@@ -4093,7 +4126,7 @@ static bool try_to_inc_max_seq(struct lr
- * handful of PTEs. Spreading the work out over a period of time usually
- * is less efficient, but it avoids bursty page faults.
- */
-- if (!(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) {
-+ if (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) {
- success = iterate_mm_list_nowalk(lruvec, max_seq);
- goto done;
- }
-@@ -4107,7 +4140,7 @@ static bool try_to_inc_max_seq(struct lr
- walk->lruvec = lruvec;
- walk->max_seq = max_seq;
- walk->can_swap = can_swap;
-- walk->force_scan = false;
-+ walk->force_scan = force_scan;
-
- do {
- success = iterate_mm_list(lruvec, walk, &mm);
-@@ -4127,7 +4160,7 @@ done:
-
- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
-
-- inc_max_seq(lruvec, can_swap);
-+ inc_max_seq(lruvec, can_swap, force_scan);
- /* either this sees any waiters or they will see updated max_seq */
- if (wq_has_sleeper(&lruvec->mm_state.wait))
- wake_up_all(&lruvec->mm_state.wait);
-@@ -4225,7 +4258,7 @@ static bool age_lruvec(struct lruvec *lr
- }
-
- if (need_aging)
-- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness);
-+ try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false);
-
- return true;
- }
-@@ -4784,7 +4817,7 @@ static unsigned long get_nr_to_scan(stru
- if (current_is_kswapd())
- return 0;
-
-- if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap))
-+ if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false))
- return nr_to_scan;
- done:
- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
-@@ -5124,6 +5157,361 @@ static struct attribute_group lru_gen_at
- };
-
- /******************************************************************************
-+ * debugfs interface
-+ ******************************************************************************/
-+
-+static void *lru_gen_seq_start(struct seq_file *m, loff_t *pos)
-+{
-+ struct mem_cgroup *memcg;
-+ loff_t nr_to_skip = *pos;
-+
-+ m->private = kvmalloc(PATH_MAX, GFP_KERNEL);
-+ if (!m->private)
-+ return ERR_PTR(-ENOMEM);
-+
-+ memcg = mem_cgroup_iter(NULL, NULL, NULL);
-+ do {
-+ int nid;
-+
-+ for_each_node_state(nid, N_MEMORY) {
-+ if (!nr_to_skip--)
-+ return get_lruvec(memcg, nid);
-+ }
-+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
-+
-+ return NULL;
-+}
-+
-+static void lru_gen_seq_stop(struct seq_file *m, void *v)
-+{
-+ if (!IS_ERR_OR_NULL(v))
-+ mem_cgroup_iter_break(NULL, lruvec_memcg(v));
-+
-+ kvfree(m->private);
-+ m->private = NULL;
-+}
-+
-+static void *lru_gen_seq_next(struct seq_file *m, void *v, loff_t *pos)
-+{
-+ int nid = lruvec_pgdat(v)->node_id;
-+ struct mem_cgroup *memcg = lruvec_memcg(v);
-+
-+ ++*pos;
-+
-+ nid = next_memory_node(nid);
-+ if (nid == MAX_NUMNODES) {
-+ memcg = mem_cgroup_iter(NULL, memcg, NULL);
-+ if (!memcg)
-+ return NULL;
-+
-+ nid = first_memory_node;
-+ }
-+
-+ return get_lruvec(memcg, nid);
-+}
-+
-+static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec,
-+ unsigned long max_seq, unsigned long *min_seq,
-+ unsigned long seq)
-+{
-+ int i;
-+ int type, tier;
-+ int hist = lru_hist_from_seq(seq);
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+
-+ for (tier = 0; tier < MAX_NR_TIERS; tier++) {
-+ seq_printf(m, " %10d", tier);
-+ for (type = 0; type < ANON_AND_FILE; type++) {
-+ const char *s = " ";
-+ unsigned long n[3] = {};
-+
-+ if (seq == max_seq) {
-+ s = "RT ";
-+ n[0] = READ_ONCE(lrugen->avg_refaulted[type][tier]);
-+ n[1] = READ_ONCE(lrugen->avg_total[type][tier]);
-+ } else if (seq == min_seq[type] || NR_HIST_GENS > 1) {
-+ s = "rep";
-+ n[0] = atomic_long_read(&lrugen->refaulted[hist][type][tier]);
-+ n[1] = atomic_long_read(&lrugen->evicted[hist][type][tier]);
-+ if (tier)
-+ n[2] = READ_ONCE(lrugen->protected[hist][type][tier - 1]);
-+ }
-+
-+ for (i = 0; i < 3; i++)
-+ seq_printf(m, " %10lu%c", n[i], s[i]);
-+ }
-+ seq_putc(m, '\n');
-+ }
-+
-+ seq_puts(m, " ");
-+ for (i = 0; i < NR_MM_STATS; i++) {
-+ const char *s = " ";
-+ unsigned long n = 0;
-+
-+ if (seq == max_seq && NR_HIST_GENS == 1) {
-+ s = "LOYNFA";
-+ n = READ_ONCE(lruvec->mm_state.stats[hist][i]);
-+ } else if (seq != max_seq && NR_HIST_GENS > 1) {
-+ s = "loynfa";
-+ n = READ_ONCE(lruvec->mm_state.stats[hist][i]);
-+ }
-+
-+ seq_printf(m, " %10lu%c", n, s[i]);
-+ }
-+ seq_putc(m, '\n');
-+}
-+
-+static int lru_gen_seq_show(struct seq_file *m, void *v)
-+{
-+ unsigned long seq;
-+ bool full = !debugfs_real_fops(m->file)->write;
-+ struct lruvec *lruvec = v;
-+ struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ int nid = lruvec_pgdat(lruvec)->node_id;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MAX_SEQ(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ if (nid == first_memory_node) {
-+ const char *path = memcg ? m->private : "";
-+
-+#ifdef CONFIG_MEMCG
-+ if (memcg)
-+ cgroup_path(memcg->css.cgroup, m->private, PATH_MAX);
-+#endif
-+ seq_printf(m, "memcg %5hu %s\n", mem_cgroup_id(memcg), path);
-+ }
-+
-+ seq_printf(m, " node %5d\n", nid);
-+
-+ if (!full)
-+ seq = min_seq[LRU_GEN_ANON];
-+ else if (max_seq >= MAX_NR_GENS)
-+ seq = max_seq - MAX_NR_GENS + 1;
-+ else
-+ seq = 0;
-+
-+ for (; seq <= max_seq; seq++) {
-+ int type, zone;
-+ int gen = lru_gen_from_seq(seq);
-+ unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-+
-+ seq_printf(m, " %10lu %10u", seq, jiffies_to_msecs(jiffies - birth));
-+
-+ for (type = 0; type < ANON_AND_FILE; type++) {
-+ unsigned long size = 0;
-+ char mark = full && seq < min_seq[type] ? 'x' : ' ';
-+
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++)
-+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
-+
-+ seq_printf(m, " %10lu%c", size, mark);
-+ }
-+
-+ seq_putc(m, '\n');
-+
-+ if (full)
-+ lru_gen_seq_show_full(m, lruvec, max_seq, min_seq, seq);
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct seq_operations lru_gen_seq_ops = {
-+ .start = lru_gen_seq_start,
-+ .stop = lru_gen_seq_stop,
-+ .next = lru_gen_seq_next,
-+ .show = lru_gen_seq_show,
-+};
-+
-+static int run_aging(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc,
-+ bool can_swap, bool force_scan)
-+{
-+ DEFINE_MAX_SEQ(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ if (seq < max_seq)
-+ return 0;
-+
-+ if (seq > max_seq)
-+ return -EINVAL;
-+
-+ if (!force_scan && min_seq[!can_swap] + MAX_NR_GENS - 1 <= max_seq)
-+ return -ERANGE;
-+
-+ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, force_scan);
-+
-+ return 0;
-+}
-+
-+static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc,
-+ int swappiness, unsigned long nr_to_reclaim)
-+{
-+ DEFINE_MAX_SEQ(lruvec);
-+
-+ if (seq + MIN_NR_GENS > max_seq)
-+ return -EINVAL;
-+
-+ sc->nr_reclaimed = 0;
-+
-+ while (!signal_pending(current)) {
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ if (seq < min_seq[!swappiness])
-+ return 0;
-+
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
-+ return 0;
-+
-+ if (!evict_pages(lruvec, sc, swappiness, NULL))
-+ return 0;
-+
-+ cond_resched();
-+ }
-+
-+ return -EINTR;
-+}
-+
-+static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq,
-+ struct scan_control *sc, int swappiness, unsigned long opt)
-+{
-+ struct lruvec *lruvec;
-+ int err = -EINVAL;
-+ struct mem_cgroup *memcg = NULL;
-+
-+ if (nid < 0 || nid >= MAX_NUMNODES || !node_state(nid, N_MEMORY))
-+ return -EINVAL;
-+
-+ if (!mem_cgroup_disabled()) {
-+ rcu_read_lock();
-+ memcg = mem_cgroup_from_id(memcg_id);
-+#ifdef CONFIG_MEMCG
-+ if (memcg && !css_tryget(&memcg->css))
-+ memcg = NULL;
-+#endif
-+ rcu_read_unlock();
-+
-+ if (!memcg)
-+ return -EINVAL;
-+ }
-+
-+ if (memcg_id != mem_cgroup_id(memcg))
-+ goto done;
-+
-+ lruvec = get_lruvec(memcg, nid);
-+
-+ if (swappiness < 0)
-+ swappiness = get_swappiness(lruvec, sc);
-+ else if (swappiness > 200)
-+ goto done;
-+
-+ switch (cmd) {
-+ case '+':
-+ err = run_aging(lruvec, seq, sc, swappiness, opt);
-+ break;
-+ case '-':
-+ err = run_eviction(lruvec, seq, sc, swappiness, opt);
-+ break;
-+ }
-+done:
-+ mem_cgroup_put(memcg);
-+
-+ return err;
-+}
-+
-+static ssize_t lru_gen_seq_write(struct file *file, const char __user *src,
-+ size_t len, loff_t *pos)
-+{
-+ void *buf;
-+ char *cur, *next;
-+ unsigned int flags;
-+ struct blk_plug plug;
-+ int err = -EINVAL;
-+ struct scan_control sc = {
-+ .may_writepage = true,
-+ .may_unmap = true,
-+ .may_swap = true,
-+ .reclaim_idx = MAX_NR_ZONES - 1,
-+ .gfp_mask = GFP_KERNEL,
-+ };
-+
-+ buf = kvmalloc(len + 1, GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(buf, src, len)) {
-+ kvfree(buf);
-+ return -EFAULT;
-+ }
-+
-+ set_task_reclaim_state(current, &sc.reclaim_state);
-+ flags = memalloc_noreclaim_save();
-+ blk_start_plug(&plug);
-+ if (!set_mm_walk(NULL)) {
-+ err = -ENOMEM;
-+ goto done;
-+ }
-+
-+ next = buf;
-+ next[len] = '\0';
-+
-+ while ((cur = strsep(&next, ",;\n"))) {
-+ int n;
-+ int end;
-+ char cmd;
-+ unsigned int memcg_id;
-+ unsigned int nid;
-+ unsigned long seq;
-+ unsigned int swappiness = -1;
-+ unsigned long opt = -1;
-+
-+ cur = skip_spaces(cur);
-+ if (!*cur)
-+ continue;
-+
-+ n = sscanf(cur, "%c %u %u %lu %n %u %n %lu %n", &cmd, &memcg_id, &nid,
-+ &seq, &end, &swappiness, &end, &opt, &end);
-+ if (n < 4 || cur[end]) {
-+ err = -EINVAL;
-+ break;
-+ }
-+
-+ err = run_cmd(cmd, memcg_id, nid, seq, &sc, swappiness, opt);
-+ if (err)
-+ break;
-+ }
-+done:
-+ clear_mm_walk();
-+ blk_finish_plug(&plug);
-+ memalloc_noreclaim_restore(flags);
-+ set_task_reclaim_state(current, NULL);
-+
-+ kvfree(buf);
-+
-+ return err ? : len;
-+}
-+
-+static int lru_gen_seq_open(struct inode *inode, struct file *file)
-+{
-+ return seq_open(file, &lru_gen_seq_ops);
-+}
-+
-+static const struct file_operations lru_gen_rw_fops = {
-+ .open = lru_gen_seq_open,
-+ .read = seq_read,
-+ .write = lru_gen_seq_write,
-+ .llseek = seq_lseek,
-+ .release = seq_release,
-+};
-+
-+static const struct file_operations lru_gen_ro_fops = {
-+ .open = lru_gen_seq_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = seq_release,
-+};
-+
-+/******************************************************************************
- * initialization
- ******************************************************************************/
-
-@@ -5180,6 +5568,9 @@ static int __init init_lru_gen(void)
- if (sysfs_create_group(mm_kobj, &lru_gen_attr_group))
- pr_err("lru_gen: failed to create sysfs group\n");
-
-+ debugfs_create_file("lru_gen", 0644, NULL, NULL, &lru_gen_rw_fops);
-+ debugfs_create_file("lru_gen_full", 0444, NULL, NULL, &lru_gen_ro_fops);
-+
- return 0;
- };
- late_initcall(init_lru_gen);
diff --git a/target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch b/target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch
deleted file mode 100644
index fd4aa72747..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 92d430e8955c976eacb7cc91d7ff849c0dd009af Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 28 Sep 2022 13:36:58 -0600
-Subject: [PATCH 13/29] mm/mglru: don't sync disk for each aging cycle
-
-wakeup_flusher_threads() was added under the assumption that if a system
-runs out of clean cold pages, it might want to write back dirty pages more
-aggressively so that they can become clean and be dropped.
-
-However, doing so can breach the rate limit a system wants to impose on
-writeback, resulting in early SSD wearout.
-
-Link: https://lkml.kernel.org/r/YzSiWq9UEER5LKup@google.com
-Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reported-by: Axel Rasmussen <axelrasmussen@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4165,8 +4165,6 @@ done:
- if (wq_has_sleeper(&lruvec->mm_state.wait))
- wake_up_all(&lruvec->mm_state.wait);
-
-- wakeup_flusher_threads(WB_REASON_VMSCAN);
--
- return true;
- }
-
diff --git a/target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch b/target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch
deleted file mode 100644
index 31b35cbc4b..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 6f315879ad750391a0b1fab8c9170bc054a5f5d7 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Tue, 15 Nov 2022 18:38:07 -0700
-Subject: [PATCH 14/29] mm: multi-gen LRU: retry pages written back while
- isolated
-
-The page reclaim isolates a batch of pages from the tail of one of the
-LRU lists and works on those pages one by one. For a suitable
-swap-backed page, if the swap device is async, it queues that page for
-writeback. After the page reclaim finishes an entire batch, it puts back
-the pages it queued for writeback to the head of the original LRU list.
-
-In the meantime, the page writeback flushes the queued pages also by
-batches. Its batching logic is independent from that of the page reclaim.
-For each of the pages it writes back, the page writeback calls
-rotate_reclaimable_page() which tries to rotate a page to the tail.
-
-rotate_reclaimable_page() only works for a page after the page reclaim
-has put it back. If an async swap device is fast enough, the page
-writeback can finish with that page while the page reclaim is still
-working on the rest of the batch containing it. In this case, that page
-will remain at the head and the page reclaim will not retry it before
-reaching there.
-
-This patch adds a retry to evict_pages(). After evict_pages() has
-finished an entire batch and before it puts back pages it cannot free
-immediately, it retries those that may have missed the rotation.
-
-Before this patch, ~60% of pages swapped to an Intel Optane missed
-rotate_reclaimable_page(). After this patch, ~99% of missed pages were
-reclaimed upon retry.
-
-This problem affects relatively slow async swap devices like Samsung 980
-Pro much less and does not affect sync swap devices like zram or zswap at
-all.
-
-Link: https://lkml.kernel.org/r/20221116013808.3995280-1-yuzhao@google.com
-Fixes: ac35a4902374 ("mm: multi-gen LRU: minimal implementation")
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: "Yin, Fengwei" <fengwei.yin@intel.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 48 +++++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 37 insertions(+), 11 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4723,10 +4723,13 @@ static int evict_pages(struct lruvec *lr
- int scanned;
- int reclaimed;
- LIST_HEAD(list);
-+ LIST_HEAD(clean);
- struct page *page;
-+ struct page *next;
- enum vm_event_item item;
- struct reclaim_stat stat;
- struct lru_gen_mm_walk *walk;
-+ bool skip_retry = false;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-
-@@ -4743,20 +4746,37 @@ static int evict_pages(struct lruvec *lr
-
- if (list_empty(&list))
- return scanned;
--
-+retry:
- reclaimed = shrink_page_list(&list, pgdat, sc, &stat, false);
-+ sc->nr_reclaimed += reclaimed;
-
-- list_for_each_entry(page, &list, lru) {
-- /* restore LRU_REFS_FLAGS cleared by isolate_page() */
-- if (PageWorkingset(page))
-- SetPageReferenced(page);
-+ list_for_each_entry_safe_reverse(page, next, &list, lru) {
-+ if (!page_evictable(page)) {
-+ list_del(&page->lru);
-+ putback_lru_page(page);
-+ continue;
-+ }
-
-- /* don't add rejected pages to the oldest generation */
- if (PageReclaim(page) &&
-- (PageDirty(page) || PageWriteback(page)))
-- ClearPageActive(page);
-- else
-- SetPageActive(page);
-+ (PageDirty(page) || PageWriteback(page))) {
-+ /* restore LRU_REFS_FLAGS cleared by isolate_page() */
-+ if (PageWorkingset(page))
-+ SetPageReferenced(page);
-+ continue;
-+ }
-+
-+ if (skip_retry || PageActive(page) || PageReferenced(page) ||
-+ page_mapped(page) || PageLocked(page) ||
-+ PageDirty(page) || PageWriteback(page)) {
-+ /* don't add rejected pages to the oldest generation */
-+ set_mask_bits(&page->flags, LRU_REFS_MASK | LRU_REFS_FLAGS,
-+ BIT(PG_active));
-+ continue;
-+ }
-+
-+ /* retry pages that may have missed rotate_reclaimable_page() */
-+ list_move(&page->lru, &clean);
-+ sc->nr_scanned -= thp_nr_pages(page);
- }
-
- spin_lock_irq(&lruvec->lru_lock);
-@@ -4778,7 +4798,13 @@ static int evict_pages(struct lruvec *lr
- mem_cgroup_uncharge_list(&list);
- free_unref_page_list(&list);
-
-- sc->nr_reclaimed += reclaimed;
-+ INIT_LIST_HEAD(&list);
-+ list_splice_init(&clean, &list);
-+
-+ if (!list_empty(&list)) {
-+ skip_retry = true;
-+ goto retry;
-+ }
-
- if (need_swapping && type == LRU_GEN_ANON)
- *need_swapping = true;
diff --git a/target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch b/target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch
deleted file mode 100644
index b1319d98a3..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 255bb0ac393f1c2818cd75af45a9226300ab3daf Mon Sep 17 00:00:00 2001
-From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Date: Wed, 26 Oct 2022 15:48:30 +0200
-Subject: [PATCH 15/29] mm: multi-gen LRU: move lru_gen_add_mm() out of IRQ-off
- region
-
-lru_gen_add_mm() has been added within an IRQ-off region in the commit
-mentioned below. The other invocations of lru_gen_add_mm() are not within
-an IRQ-off region.
-
-The invocation within IRQ-off region is problematic on PREEMPT_RT because
-the function is using a spin_lock_t which must not be used within
-IRQ-disabled regions.
-
-The other invocations of lru_gen_add_mm() occur while
-task_struct::alloc_lock is acquired. Move lru_gen_add_mm() after
-interrupts are enabled and before task_unlock().
-
-Link: https://lkml.kernel.org/r/20221026134830.711887-1-bigeasy@linutronix.de
-Fixes: bd74fdaea1460 ("mm: multi-gen LRU: support page table walks")
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Acked-by: Yu Zhao <yuzhao@google.com>
-Cc: Al Viro <viro@zeniv.linux.org.uk>
-Cc: "Eric W . Biederman" <ebiederm@xmission.com>
-Cc: Kees Cook <keescook@chromium.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- fs/exec.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/fs/exec.c
-+++ b/fs/exec.c
-@@ -1014,7 +1014,6 @@ static int exec_mmap(struct mm_struct *m
- active_mm = tsk->active_mm;
- tsk->active_mm = mm;
- tsk->mm = mm;
-- lru_gen_add_mm(mm);
- /*
- * This prevents preemption while active_mm is being loaded and
- * it and mm are being updated, which could cause problems for
-@@ -1029,6 +1028,7 @@ static int exec_mmap(struct mm_struct *m
- local_irq_enable();
- tsk->mm->vmacache_seqnum = 0;
- vmacache_flush(tsk);
-+ lru_gen_add_mm(mm);
- task_unlock(tsk);
- lru_gen_use_mm(mm);
- if (old_mm) {
diff --git a/target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch b/target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch
deleted file mode 100644
index 1c10c168a5..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From c5ec455ebd2b488d91de9d8915a0c8036a2a04dd Mon Sep 17 00:00:00 2001
-From: Juergen Gross <jgross@suse.com>
-Date: Wed, 30 Nov 2022 14:49:41 -0800
-Subject: [PATCH 17/29] mm: add dummy pmd_young() for architectures not having
- it
-
-In order to avoid #ifdeffery add a dummy pmd_young() implementation as a
-fallback. This is required for the later patch "mm: introduce
-arch_has_hw_nonleaf_pmd_young()".
-
-Link: https://lkml.kernel.org/r/fd3ac3cd-7349-6bbd-890a-71a9454ca0b3@suse.com
-Signed-off-by: Juergen Gross <jgross@suse.com>
-Acked-by: Yu Zhao <yuzhao@google.com>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Cc: "H. Peter Anvin" <hpa@zytor.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: Sander Eikelenboom <linux@eikelenboom.it>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- arch/mips/include/asm/pgtable.h | 1 +
- arch/riscv/include/asm/pgtable.h | 1 +
- arch/s390/include/asm/pgtable.h | 1 +
- arch/sparc/include/asm/pgtable_64.h | 1 +
- arch/x86/include/asm/pgtable.h | 1 +
- include/linux/pgtable.h | 7 +++++++
- 6 files changed, 12 insertions(+)
-
---- a/arch/mips/include/asm/pgtable.h
-+++ b/arch/mips/include/asm/pgtable.h
-@@ -632,6 +632,7 @@ static inline pmd_t pmd_mkdirty(pmd_t pm
- return pmd;
- }
-
-+#define pmd_young pmd_young
- static inline int pmd_young(pmd_t pmd)
- {
- return !!(pmd_val(pmd) & _PAGE_ACCESSED);
---- a/arch/riscv/include/asm/pgtable.h
-+++ b/arch/riscv/include/asm/pgtable.h
-@@ -535,6 +535,7 @@ static inline int pmd_dirty(pmd_t pmd)
- return pte_dirty(pmd_pte(pmd));
- }
-
-+#define pmd_young pmd_young
- static inline int pmd_young(pmd_t pmd)
- {
- return pte_young(pmd_pte(pmd));
---- a/arch/s390/include/asm/pgtable.h
-+++ b/arch/s390/include/asm/pgtable.h
-@@ -748,6 +748,7 @@ static inline int pmd_dirty(pmd_t pmd)
- return (pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY) != 0;
- }
-
-+#define pmd_young pmd_young
- static inline int pmd_young(pmd_t pmd)
- {
- return (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) != 0;
---- a/arch/sparc/include/asm/pgtable_64.h
-+++ b/arch/sparc/include/asm/pgtable_64.h
-@@ -712,6 +712,7 @@ static inline unsigned long pmd_dirty(pm
- return pte_dirty(pte);
- }
-
-+#define pmd_young pmd_young
- static inline unsigned long pmd_young(pmd_t pmd)
- {
- pte_t pte = __pte(pmd_val(pmd));
---- a/arch/x86/include/asm/pgtable.h
-+++ b/arch/x86/include/asm/pgtable.h
-@@ -136,6 +136,7 @@ static inline int pmd_dirty(pmd_t pmd)
- return pmd_flags(pmd) & _PAGE_DIRTY;
- }
-
-+#define pmd_young pmd_young
- static inline int pmd_young(pmd_t pmd)
- {
- return pmd_flags(pmd) & _PAGE_ACCESSED;
---- a/include/linux/pgtable.h
-+++ b/include/linux/pgtable.h
-@@ -164,6 +164,13 @@ static inline pte_t *virt_to_kpte(unsign
- return pmd_none(*pmd) ? NULL : pte_offset_kernel(pmd, vaddr);
- }
-
-+#ifndef pmd_young
-+static inline int pmd_young(pmd_t pmd)
-+{
-+ return 0;
-+}
-+#endif
-+
- #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
- extern int ptep_set_access_flags(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep,
diff --git a/target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch b/target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch
deleted file mode 100644
index 9a1f9bead6..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 46cbda7b65998a5af4493f745d94417af697bd68 Mon Sep 17 00:00:00 2001
-From: Juergen Gross <jgross@suse.com>
-Date: Wed, 23 Nov 2022 07:45:10 +0100
-Subject: [PATCH 18/29] mm: introduce arch_has_hw_nonleaf_pmd_young()
-
-When running as a Xen PV guests commit eed9a328aa1a ("mm: x86: add
-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG") can cause a protection violation in
-pmdp_test_and_clear_young():
-
- BUG: unable to handle page fault for address: ffff8880083374d0
- #PF: supervisor write access in kernel mode
- #PF: error_code(0x0003) - permissions violation
- PGD 3026067 P4D 3026067 PUD 3027067 PMD 7fee5067 PTE 8010000008337065
- Oops: 0003 [#1] PREEMPT SMP NOPTI
- CPU: 7 PID: 158 Comm: kswapd0 Not tainted 6.1.0-rc5-20221118-doflr+ #1
- RIP: e030:pmdp_test_and_clear_young+0x25/0x40
-
-This happens because the Xen hypervisor can't emulate direct writes to
-page table entries other than PTEs.
-
-This can easily be fixed by introducing arch_has_hw_nonleaf_pmd_young()
-similar to arch_has_hw_pte_young() and test that instead of
-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.
-
-Link: https://lkml.kernel.org/r/20221123064510.16225-1-jgross@suse.com
-Fixes: eed9a328aa1a ("mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG")
-Signed-off-by: Juergen Gross <jgross@suse.com>
-Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
-Acked-by: Yu Zhao <yuzhao@google.com>
-Tested-by: Sander Eikelenboom <linux@eikelenboom.it>
-Acked-by: David Hildenbrand <david@redhat.com> [core changes]
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- arch/x86/include/asm/pgtable.h | 8 ++++++++
- include/linux/pgtable.h | 11 +++++++++++
- mm/vmscan.c | 10 +++++-----
- 3 files changed, 24 insertions(+), 5 deletions(-)
-
---- a/arch/x86/include/asm/pgtable.h
-+++ b/arch/x86/include/asm/pgtable.h
-@@ -1405,6 +1405,14 @@ static inline bool arch_has_hw_pte_young
- return true;
- }
-
-+#ifdef CONFIG_XEN_PV
-+#define arch_has_hw_nonleaf_pmd_young arch_has_hw_nonleaf_pmd_young
-+static inline bool arch_has_hw_nonleaf_pmd_young(void)
-+{
-+ return !cpu_feature_enabled(X86_FEATURE_XENPV);
-+}
-+#endif
-+
- #endif /* __ASSEMBLY__ */
-
- #endif /* _ASM_X86_PGTABLE_H */
---- a/include/linux/pgtable.h
-+++ b/include/linux/pgtable.h
-@@ -266,6 +266,17 @@ static inline int pmdp_clear_flush_young
- #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
- #endif
-
-+#ifndef arch_has_hw_nonleaf_pmd_young
-+/*
-+ * Return whether the accessed bit in non-leaf PMD entries is supported on the
-+ * local CPU.
-+ */
-+static inline bool arch_has_hw_nonleaf_pmd_young(void)
-+{
-+ return IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG);
-+}
-+#endif
-+
- #ifndef arch_has_hw_pte_young
- /*
- * Return whether the accessed bit is supported on the local CPU.
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3727,7 +3727,7 @@ static void walk_pmd_range_locked(pud_t
- goto next;
-
- if (!pmd_trans_huge(pmd[i])) {
-- if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) &&
-+ if (arch_has_hw_nonleaf_pmd_young() &&
- get_cap(LRU_GEN_NONLEAF_YOUNG))
- pmdp_test_and_clear_young(vma, addr, pmd + i);
- goto next;
-@@ -3825,14 +3825,14 @@ restart:
- #endif
- walk->mm_stats[MM_NONLEAF_TOTAL]++;
-
--#ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
-- if (get_cap(LRU_GEN_NONLEAF_YOUNG)) {
-+ if (arch_has_hw_nonleaf_pmd_young() &&
-+ get_cap(LRU_GEN_NONLEAF_YOUNG)) {
- if (!pmd_young(val))
- continue;
-
- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
- }
--#endif
-+
- if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i))
- continue;
-
-@@ -5132,7 +5132,7 @@ static ssize_t show_enabled(struct kobje
- if (arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))
- caps |= BIT(LRU_GEN_MM_WALK);
-
-- if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && get_cap(LRU_GEN_NONLEAF_YOUNG))
-+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG))
- caps |= BIT(LRU_GEN_NONLEAF_YOUNG);
-
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", caps);
diff --git a/target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch b/target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch
deleted file mode 100644
index e37386abdf..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From c7dfefd4bdfba3d5171038d1cc2d4160288e6ee4 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Sun, 15 Jan 2023 20:44:05 -0700
-Subject: [PATCH 16/29] mm: multi-gen LRU: fix crash during cgroup migration
-
-lru_gen_migrate_mm() assumes lru_gen_add_mm() runs prior to itself. This
-isn't true for the following scenario:
-
- CPU 1 CPU 2
-
- clone()
- cgroup_can_fork()
- cgroup_procs_write()
- cgroup_post_fork()
- task_lock()
- lru_gen_migrate_mm()
- task_unlock()
- task_lock()
- lru_gen_add_mm()
- task_unlock()
-
-And when the above happens, kernel crashes because of linked list
-corruption (mm_struct->lru_gen.list).
-
-Link: https://lore.kernel.org/r/20230115134651.30028-1-msizanoen@qtmlabs.xyz/
-Link: https://lkml.kernel.org/r/20230116034405.2960276-1-yuzhao@google.com
-Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reported-by: msizanoen <msizanoen@qtmlabs.xyz>
-Tested-by: msizanoen <msizanoen@qtmlabs.xyz>
-Cc: <stable@vger.kernel.org> [6.1+]
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3024,13 +3024,16 @@ void lru_gen_migrate_mm(struct mm_struct
- if (mem_cgroup_disabled())
- return;
-
-+ /* migration can happen before addition */
-+ if (!mm->lru_gen.memcg)
-+ return;
-+
- rcu_read_lock();
- memcg = mem_cgroup_from_task(task);
- rcu_read_unlock();
- if (memcg == mm->lru_gen.memcg)
- return;
-
-- VM_WARN_ON_ONCE(!mm->lru_gen.memcg);
- VM_WARN_ON_ONCE(list_empty(&mm->lru_gen.list));
-
- lru_gen_del_mm(mm);
diff --git a/target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch b/target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch
deleted file mode 100644
index 0e9ed9a7eb..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-From 6c7f552a48b49a8612786a28a2239fbc24fac289 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Fri, 30 Dec 2022 14:52:51 -0700
-Subject: [PATCH 19/29] mm: add vma_has_recency()
-
-Add vma_has_recency() to indicate whether a VMA may exhibit temporal
-locality that the LRU algorithm relies on.
-
-This function returns false for VMAs marked by VM_SEQ_READ or
-VM_RAND_READ. While the former flag indicates linear access, i.e., a
-special case of spatial locality, both flags indicate a lack of temporal
-locality, i.e., the reuse of an area within a relatively small duration.
-
-"Recency" is chosen over "locality" to avoid confusion between temporal
-and spatial localities.
-
-Before this patch, the active/inactive LRU only ignored the accessed bit
-from VMAs marked by VM_SEQ_READ. After this patch, the active/inactive
-LRU and MGLRU share the same logic: they both ignore the accessed bit if
-vma_has_recency() returns false.
-
-For the active/inactive LRU, the following fio test showed a [6, 8]%
-increase in IOPS when randomly accessing mapped files under memory
-pressure.
-
- kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo)
- kb=$((kb - 8*1024*1024))
-
- modprobe brd rd_nr=1 rd_size=$kb
- dd if=/dev/zero of=/dev/ram0 bs=1M
-
- mkfs.ext4 /dev/ram0
- mount /dev/ram0 /mnt/
- swapoff -a
-
- fio --name=test --directory=/mnt/ --ioengine=mmap --numjobs=8 \
- --size=8G --rw=randrw --time_based --runtime=10m \
- --group_reporting
-
-The discussion that led to this patch is here [1]. Additional test
-results are available in that thread.
-
-[1] https://lore.kernel.org/r/Y31s%2FK8T85jh05wH@google.com/
-
-Link: https://lkml.kernel.org/r/20221230215252.2628425-1-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Alexander Viro <viro@zeniv.linux.org.uk>
-Cc: Andrea Righi <andrea.righi@canonical.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mm_inline.h | 9 +++++++++
- mm/memory.c | 8 ++++----
- mm/rmap.c | 42 +++++++++++++++++----------------------
- mm/vmscan.c | 5 ++++-
- 4 files changed, 35 insertions(+), 29 deletions(-)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -333,4 +333,13 @@ static __always_inline void del_page_fro
- update_lru_size(lruvec, page_lru(page), page_zonenum(page),
- -thp_nr_pages(page));
- }
-+
-+static inline bool vma_has_recency(struct vm_area_struct *vma)
-+{
-+ if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
-+ return false;
-+
-+ return true;
-+}
-+
- #endif
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -41,6 +41,7 @@
-
- #include <linux/kernel_stat.h>
- #include <linux/mm.h>
-+#include <linux/mm_inline.h>
- #include <linux/sched/mm.h>
- #include <linux/sched/coredump.h>
- #include <linux/sched/numa_balancing.h>
-@@ -1353,8 +1354,7 @@ again:
- force_flush = 1;
- set_page_dirty(page);
- }
-- if (pte_young(ptent) &&
-- likely(!(vma->vm_flags & VM_SEQ_READ)))
-+ if (pte_young(ptent) && likely(vma_has_recency(vma)))
- mark_page_accessed(page);
- }
- rss[mm_counter(page)]--;
-@@ -4808,8 +4808,8 @@ static inline void mm_account_fault(stru
- #ifdef CONFIG_LRU_GEN
- static void lru_gen_enter_fault(struct vm_area_struct *vma)
- {
-- /* the LRU algorithm doesn't apply to sequential or random reads */
-- current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ));
-+ /* the LRU algorithm only applies to accesses with recency */
-+ current->in_lru_fault = vma_has_recency(vma);
- }
-
- static void lru_gen_exit_fault(void)
---- a/mm/rmap.c
-+++ b/mm/rmap.c
-@@ -794,25 +794,14 @@ static bool page_referenced_one(struct p
- }
-
- if (pvmw.pte) {
-- if (lru_gen_enabled() && pte_young(*pvmw.pte) &&
-- !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) {
-+ if (lru_gen_enabled() && pte_young(*pvmw.pte)) {
- lru_gen_look_around(&pvmw);
- referenced++;
- }
-
- if (ptep_clear_flush_young_notify(vma, address,
-- pvmw.pte)) {
-- /*
-- * Don't treat a reference through
-- * a sequentially read mapping as such.
-- * If the page has been used in another mapping,
-- * we will catch it; if this other mapping is
-- * already gone, the unmap path will have set
-- * PG_referenced or activated the page.
-- */
-- if (likely(!(vma->vm_flags & VM_SEQ_READ)))
-- referenced++;
-- }
-+ pvmw.pte))
-+ referenced++;
- } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
- if (pmdp_clear_flush_young_notify(vma, address,
- pvmw.pmd))
-@@ -846,7 +835,20 @@ static bool invalid_page_referenced_vma(
- struct page_referenced_arg *pra = arg;
- struct mem_cgroup *memcg = pra->memcg;
-
-- if (!mm_match_cgroup(vma->vm_mm, memcg))
-+ /*
-+ * Ignore references from this mapping if it has no recency. If the
-+ * page has been used in another mapping, we will catch it; if this
-+ * other mapping is already gone, the unmap path will have set the
-+ * referenced flag or activated the page in zap_pte_range().
-+ */
-+ if (!vma_has_recency(vma))
-+ return true;
-+
-+ /*
-+ * If we are reclaiming on behalf of a cgroup, skip counting on behalf
-+ * of references from different cgroups.
-+ */
-+ if (memcg && !mm_match_cgroup(vma->vm_mm, memcg))
- return true;
-
- return false;
-@@ -876,6 +878,7 @@ int page_referenced(struct page *page,
- .rmap_one = page_referenced_one,
- .arg = (void *)&pra,
- .anon_lock = page_lock_anon_vma_read,
-+ .invalid_vma = invalid_page_referenced_vma,
- };
-
- *vm_flags = 0;
-@@ -891,15 +894,6 @@ int page_referenced(struct page *page,
- return 1;
- }
-
-- /*
-- * If we are reclaiming on behalf of a cgroup, skip
-- * counting on behalf of references from different
-- * cgroups
-- */
-- if (memcg) {
-- rwc.invalid_vma = invalid_page_referenced_vma;
-- }
--
- rmap_walk(page, &rwc);
- *vm_flags = pra.vm_flags;
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3486,7 +3486,10 @@ static int should_skip_vma(unsigned long
- if (is_vm_hugetlb_page(vma))
- return true;
-
-- if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ))
-+ if (!vma_has_recency(vma))
-+ return true;
-+
-+ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL))
- return true;
-
- if (vma == get_gate_vma(vma->vm_mm))
diff --git a/target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch b/target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch
deleted file mode 100644
index 3bb075bf36..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 686c3d4f71de9e0e7a27f03a5617a712385f90cd Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Fri, 30 Dec 2022 14:52:52 -0700
-Subject: [PATCH 20/29] mm: support POSIX_FADV_NOREUSE
-
-This patch adds POSIX_FADV_NOREUSE to vma_has_recency() so that the LRU
-algorithm can ignore access to mapped files marked by this flag.
-
-The advantages of POSIX_FADV_NOREUSE are:
-1. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not alter the
- default readahead behavior.
-2. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not split VMAs and
- therefore does not take mmap_lock.
-3. Unlike MADV_COLD, setting it has a negligible cost, regardless of
- how many pages it affects.
-
-Its limitations are:
-1. Like POSIX_FADV_RANDOM and POSIX_FADV_SEQUENTIAL, it currently does
- not support range. IOW, its scope is the entire file.
-2. It currently does not ignore access through file descriptors.
- Specifically, for the active/inactive LRU, given a file page shared
- by two users and one of them having set POSIX_FADV_NOREUSE on the
- file, this page will be activated upon the second user accessing
- it. This corner case can be covered by checking POSIX_FADV_NOREUSE
- before calling mark_page_accessed() on the read path. But it is
- considered not worth the effort.
-
-There have been a few attempts to support POSIX_FADV_NOREUSE, e.g., [1].
-This time the goal is to fill a niche: a few desktop applications, e.g.,
-large file transferring and video encoding/decoding, want fast file
-streaming with mmap() rather than direct IO. Among those applications, an
-SVT-AV1 regression was reported when running with MGLRU [2]. The
-following test can reproduce that regression.
-
- kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo)
- kb=$((kb - 8*1024*1024))
-
- modprobe brd rd_nr=1 rd_size=$kb
- dd if=/dev/zero of=/dev/ram0 bs=1M
-
- mkfs.ext4 /dev/ram0
- mount /dev/ram0 /mnt/
- swapoff -a
-
- fallocate -l 8G /mnt/swapfile
- mkswap /mnt/swapfile
- swapon /mnt/swapfile
-
- wget http://ultravideo.cs.tut.fi/video/Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z
- 7z e -o/mnt/ Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z
- SvtAv1EncApp --preset 12 -w 3840 -h 2160 \
- -i /mnt/Bosphorus_3840x2160.y4m
-
-For MGLRU, the following change showed a [9-11]% increase in FPS,
-which makes it on par with the active/inactive LRU.
-
- patch Source/App/EncApp/EbAppMain.c <<EOF
- 31a32
- > #include <fcntl.h>
- 35d35
- < #include <fcntl.h> /* _O_BINARY */
- 117a118
- > posix_fadvise(config->mmap.fd, 0, 0, POSIX_FADV_NOREUSE);
- EOF
-
-[1] https://lore.kernel.org/r/1308923350-7932-1-git-send-email-andrea@betterlinux.com/
-[2] https://openbenchmarking.org/result/2209259-PTS-MGLRU8GB57
-
-Link: https://lkml.kernel.org/r/20221230215252.2628425-2-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Alexander Viro <viro@zeniv.linux.org.uk>
-Cc: Andrea Righi <andrea.righi@canonical.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/fs.h | 2 ++
- include/linux/mm_inline.h | 3 +++
- mm/fadvise.c | 5 ++++-
- 3 files changed, 9 insertions(+), 1 deletion(-)
-
---- a/include/linux/fs.h
-+++ b/include/linux/fs.h
-@@ -167,6 +167,8 @@ typedef int (dio_iodone_t)(struct kiocb
- /* File is stream-like */
- #define FMODE_STREAM ((__force fmode_t)0x200000)
-
-+#define FMODE_NOREUSE ((__force fmode_t)0x400000)
-+
- /* File was opened by fanotify and shouldn't generate fanotify events */
- #define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -339,6 +339,9 @@ static inline bool vma_has_recency(struc
- if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
- return false;
-
-+ if (vma->vm_file && (vma->vm_file->f_mode & FMODE_NOREUSE))
-+ return false;
-+
- return true;
- }
-
---- a/mm/fadvise.c
-+++ b/mm/fadvise.c
-@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l
- case POSIX_FADV_NORMAL:
- file->f_ra.ra_pages = bdi->ra_pages;
- spin_lock(&file->f_lock);
-- file->f_mode &= ~FMODE_RANDOM;
-+ file->f_mode &= ~(FMODE_RANDOM | FMODE_NOREUSE);
- spin_unlock(&file->f_lock);
- break;
- case POSIX_FADV_RANDOM:
-@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l
- force_page_cache_readahead(mapping, file, start_index, nrpages);
- break;
- case POSIX_FADV_NOREUSE:
-+ spin_lock(&file->f_lock);
-+ file->f_mode |= FMODE_NOREUSE;
-+ spin_unlock(&file->f_lock);
- break;
- case POSIX_FADV_DONTNEED:
- if (!inode_write_congested(mapping->host))
diff --git a/target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch b/target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch
deleted file mode 100644
index 4e09173681..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch
+++ /dev/null
@@ -1,348 +0,0 @@
-From 348fdbada9fb3f0bf1a53651be46319105af187f Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:18:59 -0700
-Subject: [PATCH 21/29] mm: multi-gen LRU: rename lru_gen_struct to
- lru_gen_page
-
-Patch series "mm: multi-gen LRU: memcg LRU", v3.
-
-Overview
-========
-
-An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs,
-since each node and memcg combination has an LRU of pages (see
-mem_cgroup_lruvec()).
-
-Its goal is to improve the scalability of global reclaim, which is
-critical to system-wide memory overcommit in data centers. Note that
-memcg reclaim is currently out of scope.
-
-Its memory bloat is a pointer to each lruvec and negligible to each
-pglist_data. In terms of traversing memcgs during global reclaim, it
-improves the best-case complexity from O(n) to O(1) and does not affect
-the worst-case complexity O(n). Therefore, on average, it has a sublinear
-complexity in contrast to the current linear complexity.
-
-The basic structure of an memcg LRU can be understood by an analogy to
-the active/inactive LRU (of pages):
-1. It has the young and the old (generations), i.e., the counterparts
- to the active and the inactive;
-2. The increment of max_seq triggers promotion, i.e., the counterpart
- to activation;
-3. Other events trigger similar operations, e.g., offlining an memcg
- triggers demotion, i.e., the counterpart to deactivation.
-
-In terms of global reclaim, it has two distinct features:
-1. Sharding, which allows each thread to start at a random memcg (in
- the old generation) and improves parallelism;
-2. Eventual fairness, which allows direct reclaim to bail out at will
- and reduces latency without affecting fairness over some time.
-
-The commit message in patch 6 details the workflow:
-https://lore.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com/
-
-The following is a simple test to quickly verify its effectiveness.
-
- Test design:
- 1. Create multiple memcgs.
- 2. Each memcg contains a job (fio).
- 3. All jobs access the same amount of memory randomly.
- 4. The system does not experience global memory pressure.
- 5. Periodically write to the root memory.reclaim.
-
- Desired outcome:
- 1. All memcgs have similar pgsteal counts, i.e., stddev(pgsteal)
- over mean(pgsteal) is close to 0%.
- 2. The total pgsteal is close to the total requested through
- memory.reclaim, i.e., sum(pgsteal) over sum(requested) is close
- to 100%.
-
- Actual outcome [1]:
- MGLRU off MGLRU on
- stddev(pgsteal) / mean(pgsteal) 75% 20%
- sum(pgsteal) / sum(requested) 425% 95%
-
- ####################################################################
- MEMCGS=128
-
- for ((memcg = 0; memcg < $MEMCGS; memcg++)); do
- mkdir /sys/fs/cgroup/memcg$memcg
- done
-
- start() {
- echo $BASHPID > /sys/fs/cgroup/memcg$memcg/cgroup.procs
-
- fio -name=memcg$memcg --numjobs=1 --ioengine=mmap \
- --filename=/dev/zero --size=1920M --rw=randrw \
- --rate=64m,64m --random_distribution=random \
- --fadvise_hint=0 --time_based --runtime=10h \
- --group_reporting --minimal
- }
-
- for ((memcg = 0; memcg < $MEMCGS; memcg++)); do
- start &
- done
-
- sleep 600
-
- for ((i = 0; i < 600; i++)); do
- echo 256m >/sys/fs/cgroup/memory.reclaim
- sleep 6
- done
-
- for ((memcg = 0; memcg < $MEMCGS; memcg++)); do
- grep "pgsteal " /sys/fs/cgroup/memcg$memcg/memory.stat
- done
- ####################################################################
-
-[1]: This was obtained from running the above script (touches less
- than 256GB memory) on an EPYC 7B13 with 512GB DRAM for over an
- hour.
-
-This patch (of 8):
-
-The new name lru_gen_page will be more distinct from the coming
-lru_gen_memcg.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-1-yuzhao@google.com
-Link: https://lkml.kernel.org/r/20221222041905.2431096-2-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mm_inline.h | 4 ++--
- include/linux/mmzone.h | 6 +++---
- mm/vmscan.c | 34 +++++++++++++++++-----------------
- mm/workingset.c | 4 ++--
- 4 files changed, 24 insertions(+), 24 deletions(-)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -168,7 +168,7 @@ static inline void lru_gen_update_size(s
- int zone = page_zonenum(page);
- int delta = thp_nr_pages(page);
- enum lru_list lru = type * LRU_INACTIVE_FILE;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
- VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
-@@ -214,7 +214,7 @@ static inline bool lru_gen_add_page(stru
- int gen = page_lru_gen(page);
- int type = page_is_file_lru(page);
- int zone = page_zonenum(page);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE_PAGE(gen != -1, page);
-
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -394,7 +394,7 @@ enum {
- * The number of pages in each generation is eventually consistent and therefore
- * can be transiently negative when reset_batch_size() is pending.
- */
--struct lru_gen_struct {
-+struct lru_gen_page {
- /* the aging increments the youngest generation number */
- unsigned long max_seq;
- /* the eviction increments the oldest generation numbers */
-@@ -451,7 +451,7 @@ struct lru_gen_mm_state {
- struct lru_gen_mm_walk {
- /* the lruvec under reclaim */
- struct lruvec *lruvec;
-- /* unstable max_seq from lru_gen_struct */
-+ /* unstable max_seq from lru_gen_page */
- unsigned long max_seq;
- /* the next address within an mm to scan */
- unsigned long next_addr;
-@@ -514,7 +514,7 @@ struct lruvec {
- unsigned long flags;
- #ifdef CONFIG_LRU_GEN
- /* evictable pages divided into generations */
-- struct lru_gen_struct lrugen;
-+ struct lru_gen_page lrugen;
- /* to concurrently iterate lru_gen_mm_list */
- struct lru_gen_mm_state mm_state;
- #endif
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -2910,7 +2910,7 @@ static int get_nr_gens(struct lruvec *lr
-
- static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
- {
-- /* see the comment on lru_gen_struct */
-+ /* see the comment on lru_gen_page */
- return get_nr_gens(lruvec, LRU_GEN_FILE) >= MIN_NR_GENS &&
- get_nr_gens(lruvec, LRU_GEN_FILE) <= get_nr_gens(lruvec, LRU_GEN_ANON) &&
- get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS;
-@@ -3316,7 +3316,7 @@ struct ctrl_pos {
- static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
- struct ctrl_pos *pos)
- {
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- int hist = lru_hist_from_seq(lrugen->min_seq[type]);
-
- pos->refaulted = lrugen->avg_refaulted[type][tier] +
-@@ -3331,7 +3331,7 @@ static void read_ctrl_pos(struct lruvec
- static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover)
- {
- int hist, tier;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1;
- unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1;
-
-@@ -3408,7 +3408,7 @@ static int page_update_gen(struct page *
- static int page_inc_gen(struct lruvec *lruvec, struct page *page, bool reclaiming)
- {
- int type = page_is_file_lru(page);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
- unsigned long new_flags, old_flags = READ_ONCE(page->flags);
-
-@@ -3453,7 +3453,7 @@ static void update_batch_size(struct lru
- static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk)
- {
- int gen, type, zone;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- walk->batched = 0;
-
-@@ -3979,7 +3979,7 @@ static bool inc_min_seq(struct lruvec *l
- {
- int zone;
- int remaining = MAX_LRU_BATCH;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
-
- if (type == LRU_GEN_ANON && !can_swap)
-@@ -4015,7 +4015,7 @@ static bool try_to_inc_min_seq(struct lr
- {
- int gen, type, zone;
- bool success = false;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- DEFINE_MIN_SEQ(lruvec);
-
- VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
-@@ -4036,7 +4036,7 @@ next:
- ;
- }
-
-- /* see the comment on lru_gen_struct */
-+ /* see the comment on lru_gen_page */
- if (can_swap) {
- min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
- min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
-@@ -4058,7 +4058,7 @@ static void inc_max_seq(struct lruvec *l
- {
- int prev, next;
- int type, zone;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- spin_lock_irq(&lruvec->lru_lock);
-
-@@ -4116,7 +4116,7 @@ static bool try_to_inc_max_seq(struct lr
- bool success;
- struct lru_gen_mm_walk *walk;
- struct mm_struct *mm = NULL;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq));
-
-@@ -4181,7 +4181,7 @@ static bool should_run_aging(struct lruv
- unsigned long old = 0;
- unsigned long young = 0;
- unsigned long total = 0;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-
- for (type = !can_swap; type < ANON_AND_FILE; type++) {
-@@ -4466,7 +4466,7 @@ static bool sort_page(struct lruvec *lru
- int delta = thp_nr_pages(page);
- int refs = page_lru_refs(page);
- int tier = lru_tier_from_refs(refs);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE_PAGE(gen >= MAX_NR_GENS, page);
-
-@@ -4566,7 +4566,7 @@ static int scan_pages(struct lruvec *lru
- int scanned = 0;
- int isolated = 0;
- int remaining = MAX_LRU_BATCH;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-
- VM_WARN_ON_ONCE(!list_empty(list));
-@@ -4967,7 +4967,7 @@ done:
-
- static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
- {
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- if (lrugen->enabled) {
- enum lru_list lru;
-@@ -5247,7 +5247,7 @@ static void lru_gen_seq_show_full(struct
- int i;
- int type, tier;
- int hist = lru_hist_from_seq(seq);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- for (tier = 0; tier < MAX_NR_TIERS; tier++) {
- seq_printf(m, " %10d", tier);
-@@ -5296,7 +5296,7 @@ static int lru_gen_seq_show(struct seq_f
- unsigned long seq;
- bool full = !debugfs_real_fops(m->file)->write;
- struct lruvec *lruvec = v;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- int nid = lruvec_pgdat(lruvec)->node_id;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
-@@ -5549,7 +5549,7 @@ void lru_gen_init_lruvec(struct lruvec *
- {
- int i;
- int gen, type, zone;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-
- lrugen->max_seq = MIN_NR_GENS + 1;
- lrugen->enabled = lru_gen_enabled();
---- a/mm/workingset.c
-+++ b/mm/workingset.c
-@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct pag
- unsigned long token;
- unsigned long min_seq;
- struct lruvec *lruvec;
-- struct lru_gen_struct *lrugen;
-+ struct lru_gen_page *lrugen;
- int type = page_is_file_lru(page);
- int delta = thp_nr_pages(page);
- int refs = page_lru_refs(page);
-@@ -252,7 +252,7 @@ static void lru_gen_refault(struct page
- unsigned long token;
- unsigned long min_seq;
- struct lruvec *lruvec;
-- struct lru_gen_struct *lrugen;
-+ struct lru_gen_page *lrugen;
- struct mem_cgroup *memcg;
- struct pglist_data *pgdat;
- int type = page_is_file_lru(page);
diff --git a/target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch b/target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch
deleted file mode 100644
index b548c1c8b3..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From afd37e73db04c7e6b47411120ac5f6a7eca51fec Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:00 -0700
-Subject: [PATCH 22/29] mm: multi-gen LRU: rename lrugen->lists[] to
- lrugen->pages[]
-
-lru_gen_page will be chained into per-node lists by the coming
-lrugen->list.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-3-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mm_inline.h | 4 ++--
- include/linux/mmzone.h | 8 ++++----
- mm/vmscan.c | 20 ++++++++++----------
- 3 files changed, 16 insertions(+), 16 deletions(-)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -246,9 +246,9 @@ static inline bool lru_gen_add_page(stru
- lru_gen_update_size(lruvec, page, -1, gen);
- /* for rotate_reclaimable_page() */
- if (reclaiming)
-- list_add_tail(&page->lru, &lrugen->lists[gen][type][zone]);
-+ list_add_tail(&page->lru, &lrugen->pages[gen][type][zone]);
- else
-- list_add(&page->lru, &lrugen->lists[gen][type][zone]);
-+ list_add(&page->lru, &lrugen->pages[gen][type][zone]);
-
- return true;
- }
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -302,7 +302,7 @@ enum lruvec_flags {
- * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An
- * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the
- * corresponding generation. The gen counter in page->flags stores gen+1 while
-- * a page is on one of lrugen->lists[]. Otherwise it stores 0.
-+ * a page is on one of lrugen->pages[]. Otherwise it stores 0.
- *
- * A page is added to the youngest generation on faulting. The aging needs to
- * check the accessed bit at least twice before handing this page over to the
-@@ -314,8 +314,8 @@ enum lruvec_flags {
- * rest of generations, if they exist, are considered inactive. See
- * lru_gen_is_active().
- *
-- * PG_active is always cleared while a page is on one of lrugen->lists[] so that
-- * the aging needs not to worry about it. And it's set again when a page
-+ * PG_active is always cleared while a page is on one of lrugen->pages[] so
-+ * that the aging needs not to worry about it. And it's set again when a page
- * considered active is isolated for non-reclaiming purposes, e.g., migration.
- * See lru_gen_add_page() and lru_gen_del_page().
- *
-@@ -402,7 +402,7 @@ struct lru_gen_page {
- /* the birth time of each generation in jiffies */
- unsigned long timestamps[MAX_NR_GENS];
- /* the multi-gen LRU lists, lazily sorted on eviction */
-- struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
-+ struct list_head pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
- /* the multi-gen LRU sizes, eventually consistent */
- long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
- /* the exponential moving average of refaulted */
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3987,7 +3987,7 @@ static bool inc_min_seq(struct lruvec *l
-
- /* prevent cold/hot inversion if force_scan is true */
- for (zone = 0; zone < MAX_NR_ZONES; zone++) {
-- struct list_head *head = &lrugen->lists[old_gen][type][zone];
-+ struct list_head *head = &lrugen->pages[old_gen][type][zone];
-
- while (!list_empty(head)) {
- struct page *page = lru_to_page(head);
-@@ -3998,7 +3998,7 @@ static bool inc_min_seq(struct lruvec *l
- VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page);
-
- new_gen = page_inc_gen(lruvec, page, false);
-- list_move_tail(&page->lru, &lrugen->lists[new_gen][type][zone]);
-+ list_move_tail(&page->lru, &lrugen->pages[new_gen][type][zone]);
-
- if (!--remaining)
- return false;
-@@ -4026,7 +4026,7 @@ static bool try_to_inc_min_seq(struct lr
- gen = lru_gen_from_seq(min_seq[type]);
-
- for (zone = 0; zone < MAX_NR_ZONES; zone++) {
-- if (!list_empty(&lrugen->lists[gen][type][zone]))
-+ if (!list_empty(&lrugen->pages[gen][type][zone]))
- goto next;
- }
-
-@@ -4491,7 +4491,7 @@ static bool sort_page(struct lruvec *lru
-
- /* promoted */
- if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {
-- list_move(&page->lru, &lrugen->lists[gen][type][zone]);
-+ list_move(&page->lru, &lrugen->pages[gen][type][zone]);
- return true;
- }
-
-@@ -4500,7 +4500,7 @@ static bool sort_page(struct lruvec *lru
- int hist = lru_hist_from_seq(lrugen->min_seq[type]);
-
- gen = page_inc_gen(lruvec, page, false);
-- list_move_tail(&page->lru, &lrugen->lists[gen][type][zone]);
-+ list_move_tail(&page->lru, &lrugen->pages[gen][type][zone]);
-
- WRITE_ONCE(lrugen->protected[hist][type][tier - 1],
- lrugen->protected[hist][type][tier - 1] + delta);
-@@ -4512,7 +4512,7 @@ static bool sort_page(struct lruvec *lru
- if (PageLocked(page) || PageWriteback(page) ||
- (type == LRU_GEN_FILE && PageDirty(page))) {
- gen = page_inc_gen(lruvec, page, true);
-- list_move(&page->lru, &lrugen->lists[gen][type][zone]);
-+ list_move(&page->lru, &lrugen->pages[gen][type][zone]);
- return true;
- }
-
-@@ -4579,7 +4579,7 @@ static int scan_pages(struct lruvec *lru
- for (zone = sc->reclaim_idx; zone >= 0; zone--) {
- LIST_HEAD(moved);
- int skipped = 0;
-- struct list_head *head = &lrugen->lists[gen][type][zone];
-+ struct list_head *head = &lrugen->pages[gen][type][zone];
-
- while (!list_empty(head)) {
- struct page *page = lru_to_page(head);
-@@ -4980,7 +4980,7 @@ static bool __maybe_unused state_is_vali
- int gen, type, zone;
-
- for_each_gen_type_zone(gen, type, zone) {
-- if (!list_empty(&lrugen->lists[gen][type][zone]))
-+ if (!list_empty(&lrugen->pages[gen][type][zone]))
- return false;
- }
- }
-@@ -5025,7 +5025,7 @@ static bool drain_evictable(struct lruve
- int remaining = MAX_LRU_BATCH;
-
- for_each_gen_type_zone(gen, type, zone) {
-- struct list_head *head = &lruvec->lrugen.lists[gen][type][zone];
-+ struct list_head *head = &lruvec->lrugen.pages[gen][type][zone];
-
- while (!list_empty(head)) {
- bool success;
-@@ -5558,7 +5558,7 @@ void lru_gen_init_lruvec(struct lruvec *
- lrugen->timestamps[i] = jiffies;
-
- for_each_gen_type_zone(gen, type, zone)
-- INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]);
-+ INIT_LIST_HEAD(&lrugen->pages[gen][type][zone]);
-
- lruvec->mm_state.seq = MIN_NR_GENS;
- init_waitqueue_head(&lruvec->mm_state.wait);
diff --git a/target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch b/target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch
deleted file mode 100644
index 2bb6e12a5a..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-From ce45f1c4b32cf69b166f56ef5bc6c761e06ed4e5 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:01 -0700
-Subject: [PATCH 23/29] mm: multi-gen LRU: remove eviction fairness safeguard
-
-Recall that the eviction consumes the oldest generation: first it
-bucket-sorts pages whose gen counters were updated by the aging and
-reclaims the rest; then it increments lrugen->min_seq.
-
-The current eviction fairness safeguard for global reclaim has a
-dilemma: when there are multiple eligible memcgs, should it continue
-or stop upon meeting the reclaim goal? If it continues, it overshoots
-and increases direct reclaim latency; if it stops, it loses fairness
-between memcgs it has taken memory away from and those it has yet to.
-
-With memcg LRU, the eviction, while ensuring eventual fairness, will
-stop upon meeting its goal. Therefore the current eviction fairness
-safeguard for global reclaim will not be needed.
-
-Note that memcg LRU only applies to global reclaim. For memcg reclaim,
-the eviction will continue, even if it is overshooting. This becomes
-unconditional due to code simplification.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-4-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 82 +++++++++++++++--------------------------------------
- 1 file changed, 23 insertions(+), 59 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -443,6 +443,11 @@ static bool cgroup_reclaim(struct scan_c
- return sc->target_mem_cgroup;
- }
-
-+static bool global_reclaim(struct scan_control *sc)
-+{
-+ return !sc->target_mem_cgroup || mem_cgroup_is_root(sc->target_mem_cgroup);
-+}
-+
- /**
- * writeback_throttling_sane - is the usual dirty throttling mechanism available?
- * @sc: scan_control in question
-@@ -493,6 +498,11 @@ static bool cgroup_reclaim(struct scan_c
- return false;
- }
-
-+static bool global_reclaim(struct scan_control *sc)
-+{
-+ return true;
-+}
-+
- static bool writeback_throttling_sane(struct scan_control *sc)
- {
- return true;
-@@ -4722,8 +4732,7 @@ static int isolate_pages(struct lruvec *
- return scanned;
- }
-
--static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
-- bool *need_swapping)
-+static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness)
- {
- int type;
- int scanned;
-@@ -4812,9 +4821,6 @@ retry:
- goto retry;
- }
-
-- if (need_swapping && type == LRU_GEN_ANON)
-- *need_swapping = true;
--
- return scanned;
- }
-
-@@ -4853,68 +4859,26 @@ done:
- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
- }
-
--static bool should_abort_scan(struct lruvec *lruvec, unsigned long seq,
-- struct scan_control *sc, bool need_swapping)
-+static unsigned long get_nr_to_reclaim(struct scan_control *sc)
- {
-- int i;
-- DEFINE_MAX_SEQ(lruvec);
--
-- if (!current_is_kswapd()) {
-- /* age each memcg once to ensure fairness */
-- if (max_seq - seq > 1)
-- return true;
--
-- /* over-swapping can increase allocation latency */
-- if (sc->nr_reclaimed >= sc->nr_to_reclaim && need_swapping)
-- return true;
--
-- /* give this thread a chance to exit and free its memory */
-- if (fatal_signal_pending(current)) {
-- sc->nr_reclaimed += MIN_LRU_BATCH;
-- return true;
-- }
--
-- if (cgroup_reclaim(sc))
-- return false;
-- } else if (sc->nr_reclaimed - sc->last_reclaimed < sc->nr_to_reclaim)
-- return false;
--
-- /* keep scanning at low priorities to ensure fairness */
-- if (sc->priority > DEF_PRIORITY - 2)
-- return false;
--
-- /*
-- * A minimum amount of work was done under global memory pressure. For
-- * kswapd, it may be overshooting. For direct reclaim, the target isn't
-- * met, and yet the allocation may still succeed, since kswapd may have
-- * caught up. In either case, it's better to stop now, and restart if
-- * necessary.
-- */
-- for (i = 0; i <= sc->reclaim_idx; i++) {
-- unsigned long wmark;
-- struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i;
--
-- if (!managed_zone(zone))
-- continue;
--
-- wmark = current_is_kswapd() ? high_wmark_pages(zone) : low_wmark_pages(zone);
-- if (wmark > zone_page_state(zone, NR_FREE_PAGES))
-- return false;
-- }
-+ /* don't abort memcg reclaim to ensure fairness */
-+ if (!global_reclaim(sc))
-+ return -1;
-
-- sc->nr_reclaimed += MIN_LRU_BATCH;
-+ /* discount the previous progress for kswapd */
-+ if (current_is_kswapd())
-+ return sc->nr_to_reclaim + sc->last_reclaimed;
-
-- return true;
-+ return max(sc->nr_to_reclaim, compact_gap(sc->order));
- }
-
- static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
- struct blk_plug plug;
- bool need_aging = false;
-- bool need_swapping = false;
- unsigned long scanned = 0;
- unsigned long reclaimed = sc->nr_reclaimed;
-- DEFINE_MAX_SEQ(lruvec);
-+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
- lru_add_drain();
-
-@@ -4938,7 +4902,7 @@ static void lru_gen_shrink_lruvec(struct
- if (!nr_to_scan)
- goto done;
-
-- delta = evict_pages(lruvec, sc, swappiness, &need_swapping);
-+ delta = evict_pages(lruvec, sc, swappiness);
- if (!delta)
- goto done;
-
-@@ -4946,7 +4910,7 @@ static void lru_gen_shrink_lruvec(struct
- if (scanned >= nr_to_scan)
- break;
-
-- if (should_abort_scan(lruvec, max_seq, sc, need_swapping))
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
- break;
-
- cond_resched();
-@@ -5393,7 +5357,7 @@ static int run_eviction(struct lruvec *l
- if (sc->nr_reclaimed >= nr_to_reclaim)
- return 0;
-
-- if (!evict_pages(lruvec, sc, swappiness, NULL))
-+ if (!evict_pages(lruvec, sc, swappiness))
- return 0;
-
- cond_resched();
diff --git a/target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch b/target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch
deleted file mode 100644
index 316217ed02..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-From e20b7386fccc18c791796eb1dc1a91eee3ccf801 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:02 -0700
-Subject: [PATCH 24/29] mm: multi-gen LRU: remove aging fairness safeguard
-
-Recall that the aging produces the youngest generation: first it scans
-for accessed pages and updates their gen counters; then it increments
-lrugen->max_seq.
-
-The current aging fairness safeguard for kswapd uses two passes to
-ensure the fairness to multiple eligible memcgs. On the first pass,
-which is shared with the eviction, it checks whether all eligible
-memcgs are low on cold pages. If so, it requires a second pass, on
-which it ages all those memcgs at the same time.
-
-With memcg LRU, the aging, while ensuring eventual fairness, will run
-when necessary. Therefore the current aging fairness safeguard for
-kswapd will not be needed.
-
-Note that memcg LRU only applies to global reclaim. For memcg reclaim,
-the aging can be unfair to different memcgs, i.e., their
-lrugen->max_seq can be incremented at different paces.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-5-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 126 ++++++++++++++++++++++++----------------------------
- 1 file changed, 59 insertions(+), 67 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -131,7 +131,6 @@ struct scan_control {
-
- #ifdef CONFIG_LRU_GEN
- /* help kswapd make better choices among multiple memcgs */
-- unsigned int memcgs_need_aging:1;
- unsigned long last_reclaimed;
- #endif
-
-@@ -4184,7 +4183,7 @@ done:
- return true;
- }
-
--static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq,
-+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
- struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
- {
- int gen, type, zone;
-@@ -4193,6 +4192,13 @@ static bool should_run_aging(struct lruv
- unsigned long total = 0;
- struct lru_gen_page *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ /* whether this lruvec is completely out of cold pages */
-+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) {
-+ *nr_to_scan = 0;
-+ return true;
-+ }
-
- for (type = !can_swap; type < ANON_AND_FILE; type++) {
- unsigned long seq;
-@@ -4221,8 +4227,6 @@ static bool should_run_aging(struct lruv
- * stalls when the number of generations reaches MIN_NR_GENS. Hence, the
- * ideal number of generations is MIN_NR_GENS+1.
- */
-- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq)
-- return true;
- if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
- return false;
-
-@@ -4241,40 +4245,54 @@ static bool should_run_aging(struct lruv
- return false;
- }
-
--static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl)
-+static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
- {
-- bool need_aging;
-- unsigned long nr_to_scan;
-- int swappiness = get_swappiness(lruvec, sc);
-+ int gen, type, zone;
-+ unsigned long total = 0;
-+ bool can_swap = get_swappiness(lruvec, sc);
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
- DEFINE_MIN_SEQ(lruvec);
-
-- VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
-+ for (type = !can_swap; type < ANON_AND_FILE; type++) {
-+ unsigned long seq;
-
-- mem_cgroup_calculate_protection(NULL, memcg);
-+ for (seq = min_seq[type]; seq <= max_seq; seq++) {
-+ gen = lru_gen_from_seq(seq);
-
-- if (mem_cgroup_below_min(memcg))
-- return false;
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++)
-+ total += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
-+ }
-+ }
-
-- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan);
-+ /* whether the size is big enough to be helpful */
-+ return mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
-+}
-
-- if (min_ttl) {
-- int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
-- unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-+static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc,
-+ unsigned long min_ttl)
-+{
-+ int gen;
-+ unsigned long birth;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-
-- if (time_is_after_jiffies(birth + min_ttl))
-- return false;
-+ VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
-
-- /* the size is likely too small to be helpful */
-- if (!nr_to_scan && sc->priority != DEF_PRIORITY)
-- return false;
-- }
-+ /* see the comment on lru_gen_page */
-+ gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
-+ birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-
-- if (need_aging)
-- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false);
-+ if (time_is_after_jiffies(birth + min_ttl))
-+ return false;
-
-- return true;
-+ if (!lruvec_is_sizable(lruvec, sc))
-+ return false;
-+
-+ mem_cgroup_calculate_protection(NULL, memcg);
-+
-+ return !mem_cgroup_below_min(memcg);
- }
-
- /* to protect the working set of the last N jiffies */
-@@ -4283,46 +4301,32 @@ static unsigned long lru_gen_min_ttl __r
- static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
- {
- struct mem_cgroup *memcg;
-- bool success = false;
- unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
-
- VM_WARN_ON_ONCE(!current_is_kswapd());
-
- sc->last_reclaimed = sc->nr_reclaimed;
-
-- /*
-- * To reduce the chance of going into the aging path, which can be
-- * costly, optimistically skip it if the flag below was cleared in the
-- * eviction path. This improves the overall performance when multiple
-- * memcgs are available.
-- */
-- if (!sc->memcgs_need_aging) {
-- sc->memcgs_need_aging = true;
-+ /* check the order to exclude compaction-induced reclaim */
-+ if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
- return;
-- }
--
-- set_mm_walk(pgdat);
-
- memcg = mem_cgroup_iter(NULL, NULL, NULL);
- do {
- struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
-
-- if (age_lruvec(lruvec, sc, min_ttl))
-- success = true;
-+ if (lruvec_is_reclaimable(lruvec, sc, min_ttl)) {
-+ mem_cgroup_iter_break(NULL, memcg);
-+ return;
-+ }
-
- cond_resched();
- } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
-
-- clear_mm_walk();
--
-- /* check the order to exclude compaction-induced reclaim */
-- if (success || !min_ttl || sc->order)
-- return;
--
- /*
- * The main goal is to OOM kill if every generation from all memcgs is
- * younger than min_ttl. However, another possibility is all memcgs are
-- * either below min or empty.
-+ * either too small or below min.
- */
- if (mutex_trylock(&oom_lock)) {
- struct oom_control oc = {
-@@ -4830,33 +4834,27 @@ retry:
- * reclaim.
- */
- static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
-- bool can_swap, bool *need_aging)
-+ bool can_swap)
- {
- unsigned long nr_to_scan;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
-- DEFINE_MIN_SEQ(lruvec);
-
- if (mem_cgroup_below_min(memcg) ||
- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
- return 0;
-
-- *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan);
-- if (!*need_aging)
-+ if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
- return nr_to_scan;
-
- /* skip the aging path at the default priority */
- if (sc->priority == DEF_PRIORITY)
-- goto done;
-+ return nr_to_scan;
-
-- /* leave the work to lru_gen_age_node() */
-- if (current_is_kswapd())
-- return 0;
-+ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false);
-
-- if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false))
-- return nr_to_scan;
--done:
-- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
-+ /* skip this lruvec as it's low on cold pages */
-+ return 0;
- }
-
- static unsigned long get_nr_to_reclaim(struct scan_control *sc)
-@@ -4875,9 +4873,7 @@ static unsigned long get_nr_to_reclaim(s
- static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
- struct blk_plug plug;
-- bool need_aging = false;
- unsigned long scanned = 0;
-- unsigned long reclaimed = sc->nr_reclaimed;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
- lru_add_drain();
-@@ -4898,13 +4894,13 @@ static void lru_gen_shrink_lruvec(struct
- else
- swappiness = 0;
-
-- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging);
-+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
- if (!nr_to_scan)
-- goto done;
-+ break;
-
- delta = evict_pages(lruvec, sc, swappiness);
- if (!delta)
-- goto done;
-+ break;
-
- scanned += delta;
- if (scanned >= nr_to_scan)
-@@ -4916,10 +4912,6 @@ static void lru_gen_shrink_lruvec(struct
- cond_resched();
- }
-
-- /* see the comment in lru_gen_age_node() */
-- if (sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH && !need_aging)
-- sc->memcgs_need_aging = false;
--done:
- clear_mm_walk();
-
- blk_finish_plug(&plug);
diff --git a/target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch b/target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch
deleted file mode 100644
index 391ee6e67c..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From 107d54931df3c28d81648122e219bf0034ef4e99 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:03 -0700
-Subject: [PATCH 25/29] mm: multi-gen LRU: shuffle should_run_aging()
-
-Move should_run_aging() next to its only caller left.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-6-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 124 ++++++++++++++++++++++++++--------------------------
- 1 file changed, 62 insertions(+), 62 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4183,68 +4183,6 @@ done:
- return true;
- }
-
--static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
-- struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
--{
-- int gen, type, zone;
-- unsigned long old = 0;
-- unsigned long young = 0;
-- unsigned long total = 0;
-- struct lru_gen_page *lrugen = &lruvec->lrugen;
-- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-- DEFINE_MIN_SEQ(lruvec);
--
-- /* whether this lruvec is completely out of cold pages */
-- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) {
-- *nr_to_scan = 0;
-- return true;
-- }
--
-- for (type = !can_swap; type < ANON_AND_FILE; type++) {
-- unsigned long seq;
--
-- for (seq = min_seq[type]; seq <= max_seq; seq++) {
-- unsigned long size = 0;
--
-- gen = lru_gen_from_seq(seq);
--
-- for (zone = 0; zone < MAX_NR_ZONES; zone++)
-- size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
--
-- total += size;
-- if (seq == max_seq)
-- young += size;
-- else if (seq + MIN_NR_GENS == max_seq)
-- old += size;
-- }
-- }
--
-- /* try to scrape all its memory if this memcg was deleted */
-- *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
--
-- /*
-- * The aging tries to be lazy to reduce the overhead, while the eviction
-- * stalls when the number of generations reaches MIN_NR_GENS. Hence, the
-- * ideal number of generations is MIN_NR_GENS+1.
-- */
-- if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
-- return false;
--
-- /*
-- * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1)
-- * of the total number of pages for each generation. A reasonable range
-- * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The
-- * aging cares about the upper bound of hot pages, while the eviction
-- * cares about the lower bound of cold pages.
-- */
-- if (young * MIN_NR_GENS > total)
-- return true;
-- if (old * (MIN_NR_GENS + 2) < total)
-- return true;
--
-- return false;
--}
--
- static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
- {
- int gen, type, zone;
-@@ -4828,6 +4766,68 @@ retry:
- return scanned;
- }
-
-+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
-+ struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
-+{
-+ int gen, type, zone;
-+ unsigned long old = 0;
-+ unsigned long young = 0;
-+ unsigned long total = 0;
-+ struct lru_gen_page *lrugen = &lruvec->lrugen;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ /* whether this lruvec is completely out of cold pages */
-+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) {
-+ *nr_to_scan = 0;
-+ return true;
-+ }
-+
-+ for (type = !can_swap; type < ANON_AND_FILE; type++) {
-+ unsigned long seq;
-+
-+ for (seq = min_seq[type]; seq <= max_seq; seq++) {
-+ unsigned long size = 0;
-+
-+ gen = lru_gen_from_seq(seq);
-+
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++)
-+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
-+
-+ total += size;
-+ if (seq == max_seq)
-+ young += size;
-+ else if (seq + MIN_NR_GENS == max_seq)
-+ old += size;
-+ }
-+ }
-+
-+ /* try to scrape all its memory if this memcg was deleted */
-+ *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
-+
-+ /*
-+ * The aging tries to be lazy to reduce the overhead, while the eviction
-+ * stalls when the number of generations reaches MIN_NR_GENS. Hence, the
-+ * ideal number of generations is MIN_NR_GENS+1.
-+ */
-+ if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
-+ return false;
-+
-+ /*
-+ * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1)
-+ * of the total number of pages for each generation. A reasonable range
-+ * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The
-+ * aging cares about the upper bound of hot pages, while the eviction
-+ * cares about the lower bound of cold pages.
-+ */
-+ if (young * MIN_NR_GENS > total)
-+ return true;
-+ if (old * (MIN_NR_GENS + 2) < total)
-+ return true;
-+
-+ return false;
-+}
-+
- /*
- * For future optimizations:
- * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
diff --git a/target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch b/target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch
deleted file mode 100644
index cfeeaa662a..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch
+++ /dev/null
@@ -1,868 +0,0 @@
-From fa6363828d314e837c5f79e97ea5e8c0d2f7f062 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:04 -0700
-Subject: [PATCH 26/29] mm: multi-gen LRU: per-node lru_gen_page lists
-
-For each node, memcgs are divided into two generations: the old and
-the young. For each generation, memcgs are randomly sharded into
-multiple bins to improve scalability. For each bin, an RCU hlist_nulls
-is virtually divided into three segments: the head, the tail and the
-default.
-
-An onlining memcg is added to the tail of a random bin in the old
-generation. The eviction starts at the head of a random bin in the old
-generation. The per-node memcg generation counter, whose reminder (mod
-2) indexes the old generation, is incremented when all its bins become
-empty.
-
-There are four operations:
-1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in
- its current generation (old or young) and updates its "seg" to
- "head";
-2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in
- its current generation (old or young) and updates its "seg" to
- "tail";
-3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in
- the old generation, updates its "gen" to "old" and resets its "seg"
- to "default";
-4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin
- in the young generation, updates its "gen" to "young" and resets
- its "seg" to "default".
-
-The events that trigger the above operations are:
-1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD;
-2. The first attempt to reclaim an memcg below low, which triggers
- MEMCG_LRU_TAIL;
-3. The first attempt to reclaim an memcg below reclaimable size
- threshold, which triggers MEMCG_LRU_TAIL;
-4. The second attempt to reclaim an memcg below reclaimable size
- threshold, which triggers MEMCG_LRU_YOUNG;
-5. Attempting to reclaim an memcg below min, which triggers
- MEMCG_LRU_YOUNG;
-6. Finishing the aging on the eviction path, which triggers
- MEMCG_LRU_YOUNG;
-7. Offlining an memcg, which triggers MEMCG_LRU_OLD.
-
-Note that memcg LRU only applies to global reclaim, and the
-round-robin incrementing of their max_seq counters ensures the
-eventual fairness to all eligible memcgs. For memcg reclaim, it still
-relies on mem_cgroup_iter().
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/memcontrol.h | 10 +
- include/linux/mm_inline.h | 17 ++
- include/linux/mmzone.h | 117 +++++++++++-
- mm/memcontrol.c | 16 ++
- mm/page_alloc.c | 1 +
- mm/vmscan.c | 373 +++++++++++++++++++++++++++++++++----
- 6 files changed, 499 insertions(+), 35 deletions(-)
-
---- a/include/linux/memcontrol.h
-+++ b/include/linux/memcontrol.h
-@@ -823,6 +823,11 @@ static inline void obj_cgroup_put(struct
- percpu_ref_put(&objcg->refcnt);
- }
-
-+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg)
-+{
-+ return !memcg || css_tryget(&memcg->css);
-+}
-+
- static inline void mem_cgroup_put(struct mem_cgroup *memcg)
- {
- if (memcg)
-@@ -1288,6 +1293,11 @@ struct mem_cgroup *mem_cgroup_from_css(s
- return NULL;
- }
-
-+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg)
-+{
-+ return true;
-+}
-+
- static inline void mem_cgroup_put(struct mem_cgroup *memcg)
- {
- }
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -112,6 +112,18 @@ static inline bool lru_gen_in_fault(void
- return current->in_lru_fault;
- }
-
-+#ifdef CONFIG_MEMCG
-+static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return READ_ONCE(lruvec->lrugen.seg);
-+}
-+#else
-+static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return 0;
-+}
-+#endif
-+
- static inline int lru_gen_from_seq(unsigned long seq)
- {
- return seq % MAX_NR_GENS;
-@@ -287,6 +299,11 @@ static inline bool lru_gen_in_fault(void
- return false;
- }
-
-+static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return 0;
-+}
-+
- static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
- {
- return false;
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -7,6 +7,7 @@
-
- #include <linux/spinlock.h>
- #include <linux/list.h>
-+#include <linux/list_nulls.h>
- #include <linux/wait.h>
- #include <linux/bitops.h>
- #include <linux/cache.h>
-@@ -357,6 +358,15 @@ struct page_vma_mapped_walk;
- #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
- #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
-
-+/* see the comment on MEMCG_NR_GENS */
-+enum {
-+ MEMCG_LRU_NOP,
-+ MEMCG_LRU_HEAD,
-+ MEMCG_LRU_TAIL,
-+ MEMCG_LRU_OLD,
-+ MEMCG_LRU_YOUNG,
-+};
-+
- #ifdef CONFIG_LRU_GEN
-
- enum {
-@@ -416,6 +426,14 @@ struct lru_gen_page {
- atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
- /* whether the multi-gen LRU is enabled */
- bool enabled;
-+#ifdef CONFIG_MEMCG
-+ /* the memcg generation this lru_gen_page belongs to */
-+ u8 gen;
-+ /* the list segment this lru_gen_page belongs to */
-+ u8 seg;
-+ /* per-node lru_gen_page list for global reclaim */
-+ struct hlist_nulls_node list;
-+#endif
- };
-
- enum {
-@@ -469,12 +487,87 @@ void lru_gen_init_lruvec(struct lruvec *
- void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
-
- #ifdef CONFIG_MEMCG
-+
-+/*
-+ * For each node, memcgs are divided into two generations: the old and the
-+ * young. For each generation, memcgs are randomly sharded into multiple bins
-+ * to improve scalability. For each bin, the hlist_nulls is virtually divided
-+ * into three segments: the head, the tail and the default.
-+ *
-+ * An onlining memcg is added to the tail of a random bin in the old generation.
-+ * The eviction starts at the head of a random bin in the old generation. The
-+ * per-node memcg generation counter, whose reminder (mod MEMCG_NR_GENS) indexes
-+ * the old generation, is incremented when all its bins become empty.
-+ *
-+ * There are four operations:
-+ * 1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in its
-+ * current generation (old or young) and updates its "seg" to "head";
-+ * 2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in its
-+ * current generation (old or young) and updates its "seg" to "tail";
-+ * 3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in the old
-+ * generation, updates its "gen" to "old" and resets its "seg" to "default";
-+ * 4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin in the
-+ * young generation, updates its "gen" to "young" and resets its "seg" to
-+ * "default".
-+ *
-+ * The events that trigger the above operations are:
-+ * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD;
-+ * 2. The first attempt to reclaim an memcg below low, which triggers
-+ * MEMCG_LRU_TAIL;
-+ * 3. The first attempt to reclaim an memcg below reclaimable size threshold,
-+ * which triggers MEMCG_LRU_TAIL;
-+ * 4. The second attempt to reclaim an memcg below reclaimable size threshold,
-+ * which triggers MEMCG_LRU_YOUNG;
-+ * 5. Attempting to reclaim an memcg below min, which triggers MEMCG_LRU_YOUNG;
-+ * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG;
-+ * 7. Offlining an memcg, which triggers MEMCG_LRU_OLD.
-+ *
-+ * Note that memcg LRU only applies to global reclaim, and the round-robin
-+ * incrementing of their max_seq counters ensures the eventual fairness to all
-+ * eligible memcgs. For memcg reclaim, it still relies on mem_cgroup_iter().
-+ */
-+#define MEMCG_NR_GENS 2
-+#define MEMCG_NR_BINS 8
-+
-+struct lru_gen_memcg {
-+ /* the per-node memcg generation counter */
-+ unsigned long seq;
-+ /* each memcg has one lru_gen_page per node */
-+ unsigned long nr_memcgs[MEMCG_NR_GENS];
-+ /* per-node lru_gen_page list for global reclaim */
-+ struct hlist_nulls_head fifo[MEMCG_NR_GENS][MEMCG_NR_BINS];
-+ /* protects the above */
-+ spinlock_t lock;
-+};
-+
-+void lru_gen_init_pgdat(struct pglist_data *pgdat);
-+
- void lru_gen_init_memcg(struct mem_cgroup *memcg);
- void lru_gen_exit_memcg(struct mem_cgroup *memcg);
--#endif
-+void lru_gen_online_memcg(struct mem_cgroup *memcg);
-+void lru_gen_offline_memcg(struct mem_cgroup *memcg);
-+void lru_gen_release_memcg(struct mem_cgroup *memcg);
-+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op);
-+
-+#else /* !CONFIG_MEMCG */
-+
-+#define MEMCG_NR_GENS 1
-+
-+struct lru_gen_memcg {
-+};
-+
-+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat)
-+{
-+}
-+
-+#endif /* CONFIG_MEMCG */
-
- #else /* !CONFIG_LRU_GEN */
-
-+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat)
-+{
-+}
-+
- static inline void lru_gen_init_lruvec(struct lruvec *lruvec)
- {
- }
-@@ -484,6 +577,7 @@ static inline void lru_gen_look_around(s
- }
-
- #ifdef CONFIG_MEMCG
-+
- static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
- {
- }
-@@ -491,7 +585,24 @@ static inline void lru_gen_init_memcg(st
- static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg)
- {
- }
--#endif
-+
-+static inline void lru_gen_online_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+static inline void lru_gen_offline_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+static inline void lru_gen_release_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
-+{
-+}
-+
-+#endif /* CONFIG_MEMCG */
-
- #endif /* CONFIG_LRU_GEN */
-
-@@ -1105,6 +1216,8 @@ typedef struct pglist_data {
- #ifdef CONFIG_LRU_GEN
- /* kswap mm walk data */
- struct lru_gen_mm_walk mm_walk;
-+ /* lru_gen_page list */
-+ struct lru_gen_memcg memcg_lru;
- #endif
-
- ZONE_PADDING(_pad2_)
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -549,6 +549,16 @@ static void mem_cgroup_update_tree(struc
- struct mem_cgroup_per_node *mz;
- struct mem_cgroup_tree_per_node *mctz;
-
-+ if (lru_gen_enabled()) {
-+ struct lruvec *lruvec = &mem_cgroup_page_nodeinfo(memcg, page)->lruvec;
-+
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD)
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD);
-+
-+ return;
-+ }
-+
- mctz = soft_limit_tree_from_page(page);
- if (!mctz)
- return;
-@@ -3434,6 +3444,9 @@ unsigned long mem_cgroup_soft_limit_recl
- unsigned long excess;
- unsigned long nr_scanned;
-
-+ if (lru_gen_enabled())
-+ return 0;
-+
- if (order > 0)
- return 0;
-
-@@ -5322,6 +5335,7 @@ static int mem_cgroup_css_online(struct
- if (unlikely(mem_cgroup_is_root(memcg)))
- queue_delayed_work(system_unbound_wq, &stats_flush_dwork,
- 2UL*HZ);
-+ lru_gen_online_memcg(memcg);
- return 0;
- }
-
-@@ -5348,6 +5362,7 @@ static void mem_cgroup_css_offline(struc
- memcg_offline_kmem(memcg);
- reparent_shrinker_deferred(memcg);
- wb_memcg_offline(memcg);
-+ lru_gen_offline_memcg(memcg);
-
- drain_all_stock(memcg);
-
-@@ -5359,6 +5374,7 @@ static void mem_cgroup_css_released(stru
- struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-
- invalidate_reclaim_iterators(memcg);
-+ lru_gen_release_memcg(memcg);
- }
-
- static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -7663,6 +7663,7 @@ static void __init free_area_init_node(i
- pgdat_set_deferred_range(pgdat);
-
- free_area_init_core(pgdat);
-+ lru_gen_init_pgdat(pgdat);
- }
-
- void __init free_area_init_memoryless_node(int nid)
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -54,6 +54,8 @@
- #include <linux/shmem_fs.h>
- #include <linux/ctype.h>
- #include <linux/debugfs.h>
-+#include <linux/rculist_nulls.h>
-+#include <linux/random.h>
-
- #include <asm/tlbflush.h>
- #include <asm/div64.h>
-@@ -129,11 +131,6 @@ struct scan_control {
- /* Always discard instead of demoting to lower tier memory */
- unsigned int no_demotion:1;
-
--#ifdef CONFIG_LRU_GEN
-- /* help kswapd make better choices among multiple memcgs */
-- unsigned long last_reclaimed;
--#endif
--
- /* Allocation order */
- s8 order;
-
-@@ -2880,6 +2877,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca
- for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
- for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
-
-+#define get_memcg_gen(seq) ((seq) % MEMCG_NR_GENS)
-+#define get_memcg_bin(bin) ((bin) % MEMCG_NR_BINS)
-+
- static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
- {
- struct pglist_data *pgdat = NODE_DATA(nid);
-@@ -4169,8 +4169,7 @@ done:
- if (sc->priority <= DEF_PRIORITY - 2)
- wait_event_killable(lruvec->mm_state.wait,
- max_seq < READ_ONCE(lrugen->max_seq));
--
-- return max_seq < READ_ONCE(lrugen->max_seq);
-+ return false;
- }
-
- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
-@@ -4243,8 +4242,6 @@ static void lru_gen_age_node(struct pgli
-
- VM_WARN_ON_ONCE(!current_is_kswapd());
-
-- sc->last_reclaimed = sc->nr_reclaimed;
--
- /* check the order to exclude compaction-induced reclaim */
- if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
- return;
-@@ -4833,8 +4830,7 @@ static bool should_run_aging(struct lruv
- * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
- * reclaim.
- */
--static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
-- bool can_swap)
-+static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool can_swap)
- {
- unsigned long nr_to_scan;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-@@ -4851,10 +4847,8 @@ static unsigned long get_nr_to_scan(stru
- if (sc->priority == DEF_PRIORITY)
- return nr_to_scan;
-
-- try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false);
--
- /* skip this lruvec as it's low on cold pages */
-- return 0;
-+ return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? -1 : 0;
- }
-
- static unsigned long get_nr_to_reclaim(struct scan_control *sc)
-@@ -4863,29 +4857,18 @@ static unsigned long get_nr_to_reclaim(s
- if (!global_reclaim(sc))
- return -1;
-
-- /* discount the previous progress for kswapd */
-- if (current_is_kswapd())
-- return sc->nr_to_reclaim + sc->last_reclaimed;
--
- return max(sc->nr_to_reclaim, compact_gap(sc->order));
- }
-
--static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
-- struct blk_plug plug;
-+ long nr_to_scan;
- unsigned long scanned = 0;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
-- lru_add_drain();
--
-- blk_start_plug(&plug);
--
-- set_mm_walk(lruvec_pgdat(lruvec));
--
- while (true) {
- int delta;
- int swappiness;
-- unsigned long nr_to_scan;
-
- if (sc->may_swap)
- swappiness = get_swappiness(lruvec, sc);
-@@ -4895,7 +4878,7 @@ static void lru_gen_shrink_lruvec(struct
- swappiness = 0;
-
- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
-- if (!nr_to_scan)
-+ if (nr_to_scan <= 0)
- break;
-
- delta = evict_pages(lruvec, sc, swappiness);
-@@ -4912,10 +4895,250 @@ static void lru_gen_shrink_lruvec(struct
- cond_resched();
- }
-
-+ /* whether try_to_inc_max_seq() was successful */
-+ return nr_to_scan < 0;
-+}
-+
-+static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ bool success;
-+ unsigned long scanned = sc->nr_scanned;
-+ unsigned long reclaimed = sc->nr_reclaimed;
-+ int seg = lru_gen_memcg_seg(lruvec);
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-+
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (!lruvec_is_sizable(lruvec, sc))
-+ return seg != MEMCG_LRU_TAIL ? MEMCG_LRU_TAIL : MEMCG_LRU_YOUNG;
-+
-+ mem_cgroup_calculate_protection(NULL, memcg);
-+
-+ if (mem_cgroup_below_min(memcg))
-+ return MEMCG_LRU_YOUNG;
-+
-+ if (mem_cgroup_below_low(memcg)) {
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (seg != MEMCG_LRU_TAIL)
-+ return MEMCG_LRU_TAIL;
-+
-+ memcg_memory_event(memcg, MEMCG_LOW);
-+ }
-+
-+ success = try_to_shrink_lruvec(lruvec, sc);
-+
-+ shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, sc->priority);
-+
-+ vmpressure(sc->gfp_mask, memcg, false, sc->nr_scanned - scanned,
-+ sc->nr_reclaimed - reclaimed);
-+
-+ sc->nr_reclaimed += current->reclaim_state->reclaimed_slab;
-+ current->reclaim_state->reclaimed_slab = 0;
-+
-+ return success ? MEMCG_LRU_YOUNG : 0;
-+}
-+
-+#ifdef CONFIG_MEMCG
-+
-+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ int gen;
-+ int bin;
-+ int first_bin;
-+ struct lruvec *lruvec;
-+ struct lru_gen_page *lrugen;
-+ const struct hlist_nulls_node *pos;
-+ int op = 0;
-+ struct mem_cgroup *memcg = NULL;
-+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-+
-+ bin = first_bin = prandom_u32_max(MEMCG_NR_BINS);
-+restart:
-+ gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
-+
-+ rcu_read_lock();
-+
-+ hlist_nulls_for_each_entry_rcu(lrugen, pos, &pgdat->memcg_lru.fifo[gen][bin], list) {
-+ if (op)
-+ lru_gen_rotate_memcg(lruvec, op);
-+
-+ mem_cgroup_put(memcg);
-+
-+ lruvec = container_of(lrugen, struct lruvec, lrugen);
-+ memcg = lruvec_memcg(lruvec);
-+
-+ if (!mem_cgroup_tryget(memcg)) {
-+ op = 0;
-+ memcg = NULL;
-+ continue;
-+ }
-+
-+ rcu_read_unlock();
-+
-+ op = shrink_one(lruvec, sc);
-+
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
-+ goto success;
-+
-+ rcu_read_lock();
-+ }
-+
-+ rcu_read_unlock();
-+
-+ /* restart if raced with lru_gen_rotate_memcg() */
-+ if (gen != get_nulls_value(pos))
-+ goto restart;
-+
-+ /* try the rest of the bins of the current generation */
-+ bin = get_memcg_bin(bin + 1);
-+ if (bin != first_bin)
-+ goto restart;
-+success:
-+ if (op)
-+ lru_gen_rotate_memcg(lruvec, op);
-+
-+ mem_cgroup_put(memcg);
-+}
-+
-+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ struct blk_plug plug;
-+
-+ VM_WARN_ON_ONCE(global_reclaim(sc));
-+
-+ lru_add_drain();
-+
-+ blk_start_plug(&plug);
-+
-+ set_mm_walk(lruvec_pgdat(lruvec));
-+
-+ if (try_to_shrink_lruvec(lruvec, sc))
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
-+
-+ clear_mm_walk();
-+
-+ blk_finish_plug(&plug);
-+}
-+
-+#else /* !CONFIG_MEMCG */
-+
-+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ BUILD_BUG();
-+}
-+
-+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ BUILD_BUG();
-+}
-+
-+#endif
-+
-+static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ int priority;
-+ unsigned long reclaimable;
-+ struct lruvec *lruvec = mem_cgroup_lruvec(NULL, pgdat);
-+
-+ if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH)
-+ return;
-+ /*
-+ * Determine the initial priority based on ((total / MEMCG_NR_GENS) >>
-+ * priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, where the
-+ * estimated reclaimed_to_scanned_ratio = inactive / total.
-+ */
-+ reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE);
-+ if (get_swappiness(lruvec, sc))
-+ reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON);
-+
-+ reclaimable /= MEMCG_NR_GENS;
-+
-+ /* round down reclaimable and round up sc->nr_to_reclaim */
-+ priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1);
-+
-+ sc->priority = clamp(priority, 0, DEF_PRIORITY);
-+}
-+
-+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ struct blk_plug plug;
-+ unsigned long reclaimed = sc->nr_reclaimed;
-+
-+ VM_WARN_ON_ONCE(!global_reclaim(sc));
-+
-+ lru_add_drain();
-+
-+ blk_start_plug(&plug);
-+
-+ set_mm_walk(pgdat);
-+
-+ set_initial_priority(pgdat, sc);
-+
-+ if (current_is_kswapd())
-+ sc->nr_reclaimed = 0;
-+
-+ if (mem_cgroup_disabled())
-+ shrink_one(&pgdat->__lruvec, sc);
-+ else
-+ shrink_many(pgdat, sc);
-+
-+ if (current_is_kswapd())
-+ sc->nr_reclaimed += reclaimed;
-+
- clear_mm_walk();
-
- blk_finish_plug(&plug);
-+
-+ /* kswapd should never fail */
-+ pgdat->kswapd_failures = 0;
-+}
-+
-+#ifdef CONFIG_MEMCG
-+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
-+{
-+ int seg;
-+ int old, new;
-+ int bin = prandom_u32_max(MEMCG_NR_BINS);
-+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ seg = 0;
-+ new = old = lruvec->lrugen.gen;
-+
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (op == MEMCG_LRU_HEAD)
-+ seg = MEMCG_LRU_HEAD;
-+ else if (op == MEMCG_LRU_TAIL)
-+ seg = MEMCG_LRU_TAIL;
-+ else if (op == MEMCG_LRU_OLD)
-+ new = get_memcg_gen(pgdat->memcg_lru.seq);
-+ else if (op == MEMCG_LRU_YOUNG)
-+ new = get_memcg_gen(pgdat->memcg_lru.seq + 1);
-+ else
-+ VM_WARN_ON_ONCE(true);
-+
-+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
-+
-+ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
-+ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
-+ else
-+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
-+
-+ pgdat->memcg_lru.nr_memcgs[old]--;
-+ pgdat->memcg_lru.nr_memcgs[new]++;
-+
-+ lruvec->lrugen.gen = new;
-+ WRITE_ONCE(lruvec->lrugen.seg, seg);
-+
-+ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq))
-+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
- }
-+#endif
-
- /******************************************************************************
- * state change
-@@ -5370,11 +5593,11 @@ static int run_cmd(char cmd, int memcg_i
-
- if (!mem_cgroup_disabled()) {
- rcu_read_lock();
-+
- memcg = mem_cgroup_from_id(memcg_id);
--#ifdef CONFIG_MEMCG
-- if (memcg && !css_tryget(&memcg->css))
-+ if (!mem_cgroup_tryget(memcg))
- memcg = NULL;
--#endif
-+
- rcu_read_unlock();
-
- if (!memcg)
-@@ -5521,6 +5744,19 @@ void lru_gen_init_lruvec(struct lruvec *
- }
-
- #ifdef CONFIG_MEMCG
-+
-+void lru_gen_init_pgdat(struct pglist_data *pgdat)
-+{
-+ int i, j;
-+
-+ spin_lock_init(&pgdat->memcg_lru.lock);
-+
-+ for (i = 0; i < MEMCG_NR_GENS; i++) {
-+ for (j = 0; j < MEMCG_NR_BINS; j++)
-+ INIT_HLIST_NULLS_HEAD(&pgdat->memcg_lru.fifo[i][j], i);
-+ }
-+}
-+
- void lru_gen_init_memcg(struct mem_cgroup *memcg)
- {
- INIT_LIST_HEAD(&memcg->mm_list.fifo);
-@@ -5544,7 +5780,69 @@ void lru_gen_exit_memcg(struct mem_cgrou
- }
- }
- }
--#endif
-+
-+void lru_gen_online_memcg(struct mem_cgroup *memcg)
-+{
-+ int gen;
-+ int nid;
-+ int bin = prandom_u32_max(MEMCG_NR_BINS);
-+
-+ for_each_node(nid) {
-+ struct pglist_data *pgdat = NODE_DATA(nid);
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ gen = get_memcg_gen(pgdat->memcg_lru.seq);
-+
-+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]);
-+ pgdat->memcg_lru.nr_memcgs[gen]++;
-+
-+ lruvec->lrugen.gen = gen;
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
-+ }
-+}
-+
-+void lru_gen_offline_memcg(struct mem_cgroup *memcg)
-+{
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD);
-+ }
-+}
-+
-+void lru_gen_release_memcg(struct mem_cgroup *memcg)
-+{
-+ int gen;
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct pglist_data *pgdat = NODE_DATA(nid);
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ gen = lruvec->lrugen.gen;
-+
-+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
-+ pgdat->memcg_lru.nr_memcgs[gen]--;
-+
-+ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq))
-+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
-+ }
-+}
-+
-+#endif /* CONFIG_MEMCG */
-
- static int __init init_lru_gen(void)
- {
-@@ -5571,6 +5869,10 @@ static void lru_gen_shrink_lruvec(struct
- {
- }
-
-+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+}
-+
- #endif /* CONFIG_LRU_GEN */
-
- static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-@@ -5584,7 +5886,7 @@ static void shrink_lruvec(struct lruvec
- bool proportional_reclaim;
- struct blk_plug plug;
-
-- if (lru_gen_enabled()) {
-+ if (lru_gen_enabled() && !global_reclaim(sc)) {
- lru_gen_shrink_lruvec(lruvec, sc);
- return;
- }
-@@ -5826,6 +6128,11 @@ static void shrink_node(pg_data_t *pgdat
- struct lruvec *target_lruvec;
- bool reclaimable = false;
-
-+ if (lru_gen_enabled() && global_reclaim(sc)) {
-+ lru_gen_shrink_node(pgdat, sc);
-+ return;
-+ }
-+
- target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
-
- again:
diff --git a/target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch b/target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch
deleted file mode 100644
index 882f29e989..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-From 93147736b5b3a21bea24313bfc7a696829932009 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:05 -0700
-Subject: [PATCH 27/29] mm: multi-gen LRU: clarify scan_control flags
-
-Among the flags in scan_control:
-1. sc->may_swap, which indicates swap constraint due to memsw.max, is
- supported as usual.
-2. sc->proactive, which indicates reclaim by memory.reclaim, may not
- opportunistically skip the aging path, since it is considered less
- latency sensitive.
-3. !(sc->gfp_mask & __GFP_IO), which indicates IO constraint, lowers
- swappiness to prioritize file LRU, since clean file pages are more
- likely to exist.
-4. sc->may_writepage and sc->may_unmap, which indicates opportunistic
- reclaim, are rejected, since unmapped clean pages are already
- prioritized. Scanning for more of them is likely futile and can
- cause high reclaim latency when there is a large number of memcgs.
-
-The rest are handled by the existing code.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-8-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 55 +++++++++++++++++++++++++++--------------------------
- 1 file changed, 28 insertions(+), 27 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -2905,6 +2905,9 @@ static int get_swappiness(struct lruvec
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-
-+ if (!sc->may_swap)
-+ return 0;
-+
- if (!can_demote(pgdat->node_id, sc) &&
- mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
- return 0;
-@@ -3952,7 +3955,7 @@ static void walk_mm(struct lruvec *lruve
- } while (err == -EAGAIN);
- }
-
--static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat)
-+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat, bool force_alloc)
- {
- struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
-
-@@ -3960,7 +3963,7 @@ static struct lru_gen_mm_walk *set_mm_wa
- VM_WARN_ON_ONCE(walk);
-
- walk = &pgdat->mm_walk;
-- } else if (!pgdat && !walk) {
-+ } else if (!walk && force_alloc) {
- VM_WARN_ON_ONCE(current_is_kswapd());
-
- walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
-@@ -4146,7 +4149,7 @@ static bool try_to_inc_max_seq(struct lr
- goto done;
- }
-
-- walk = set_mm_walk(NULL);
-+ walk = set_mm_walk(NULL, true);
- if (!walk) {
- success = iterate_mm_list_nowalk(lruvec, max_seq);
- goto done;
-@@ -4215,8 +4218,6 @@ static bool lruvec_is_reclaimable(struct
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MIN_SEQ(lruvec);
-
-- VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
--
- /* see the comment on lru_gen_page */
- gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
- birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-@@ -4472,12 +4473,8 @@ static bool isolate_page(struct lruvec *
- {
- bool success;
-
-- /* unmapping inhibited */
-- if (!sc->may_unmap && page_mapped(page))
-- return false;
--
- /* swapping inhibited */
-- if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) &&
-+ if (!(sc->gfp_mask & __GFP_IO) &&
- (PageDirty(page) ||
- (PageAnon(page) && !PageSwapCache(page))))
- return false;
-@@ -4574,9 +4571,8 @@ static int scan_pages(struct lruvec *lru
- __count_vm_events(PGSCAN_ANON + type, isolated);
-
- /*
-- * There might not be eligible pages due to reclaim_idx, may_unmap and
-- * may_writepage. Check the remaining to prevent livelock if it's not
-- * making progress.
-+ * There might not be eligible pages due to reclaim_idx. Check the
-+ * remaining to prevent livelock if it's not making progress.
- */
- return isolated || !remaining ? scanned : 0;
- }
-@@ -4836,8 +4832,7 @@ static long get_nr_to_scan(struct lruvec
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
-
-- if (mem_cgroup_below_min(memcg) ||
-- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
-+ if (mem_cgroup_below_min(memcg))
- return 0;
-
- if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
-@@ -4865,17 +4860,14 @@ static bool try_to_shrink_lruvec(struct
- long nr_to_scan;
- unsigned long scanned = 0;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-+ int swappiness = get_swappiness(lruvec, sc);
-+
-+ /* clean file pages are more likely to exist */
-+ if (swappiness && !(sc->gfp_mask & __GFP_IO))
-+ swappiness = 1;
-
- while (true) {
- int delta;
-- int swappiness;
--
-- if (sc->may_swap)
-- swappiness = get_swappiness(lruvec, sc);
-- else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc))
-- swappiness = 1;
-- else
-- swappiness = 0;
-
- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
- if (nr_to_scan <= 0)
-@@ -5005,12 +4997,13 @@ static void lru_gen_shrink_lruvec(struct
- struct blk_plug plug;
-
- VM_WARN_ON_ONCE(global_reclaim(sc));
-+ VM_WARN_ON_ONCE(!sc->may_writepage || !sc->may_unmap);
-
- lru_add_drain();
-
- blk_start_plug(&plug);
-
-- set_mm_walk(lruvec_pgdat(lruvec));
-+ set_mm_walk(NULL, false);
-
- if (try_to_shrink_lruvec(lruvec, sc))
- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
-@@ -5066,11 +5059,19 @@ static void lru_gen_shrink_node(struct p
-
- VM_WARN_ON_ONCE(!global_reclaim(sc));
-
-+ /*
-+ * Unmapped clean pages are already prioritized. Scanning for more of
-+ * them is likely futile and can cause high reclaim latency when there
-+ * is a large number of memcgs.
-+ */
-+ if (!sc->may_writepage || !sc->may_unmap)
-+ goto done;
-+
- lru_add_drain();
-
- blk_start_plug(&plug);
-
-- set_mm_walk(pgdat);
-+ set_mm_walk(pgdat, false);
-
- set_initial_priority(pgdat, sc);
-
-@@ -5088,7 +5089,7 @@ static void lru_gen_shrink_node(struct p
- clear_mm_walk();
-
- blk_finish_plug(&plug);
--
-+done:
- /* kswapd should never fail */
- pgdat->kswapd_failures = 0;
- }
-@@ -5656,7 +5657,7 @@ static ssize_t lru_gen_seq_write(struct
- set_task_reclaim_state(current, &sc.reclaim_state);
- flags = memalloc_noreclaim_save();
- blk_start_plug(&plug);
-- if (!set_mm_walk(NULL)) {
-+ if (!set_mm_walk(NULL, true)) {
- err = -ENOMEM;
- goto done;
- }
diff --git a/target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch b/target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch
deleted file mode 100644
index 38d0e5496c..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From cf3297e4c7a928da8b2b2f0baff2f9c69ea57952 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:06 -0700
-Subject: [PATCH 28/29] mm: multi-gen LRU: simplify arch_has_hw_pte_young()
- check
-
-Scanning page tables when hardware does not set the accessed bit has
-no real use cases.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-9-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4144,7 +4144,7 @@ static bool try_to_inc_max_seq(struct lr
- * handful of PTEs. Spreading the work out over a period of time usually
- * is less efficient, but it avoids bursty page faults.
- */
-- if (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) {
-+ if (!arch_has_hw_pte_young() || !get_cap(LRU_GEN_MM_WALK)) {
- success = iterate_mm_list_nowalk(lruvec, max_seq);
- goto done;
- }
diff --git a/target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch b/target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch
deleted file mode 100644
index 2d19d0d7da..0000000000
--- a/target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From cc67f962cc53f6e1dfa92eb85b7b26fe83a3c66f Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Mon, 13 Feb 2023 00:53:22 -0700
-Subject: [PATCH 29/29] mm: multi-gen LRU: avoid futile retries
-
-Recall that the per-node memcg LRU has two generations and they alternate
-when the last memcg (of a given node) is moved from one to the other.
-Each generation is also sharded into multiple bins to improve scalability.
-A reclaimer starts with a random bin (in the old generation) and, if it
-fails, it will retry, i.e., to try the rest of the bins.
-
-If a reclaimer fails with the last memcg, it should move this memcg to the
-young generation first, which causes the generations to alternate, and
-then retry. Otherwise, the retries will be futile because all other bins
-are empty.
-
-Link: https://lkml.kernel.org/r/20230213075322.1416966-1-yuzhao@google.com
-Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists")
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reported-by: T.J. Mercier <tjmercier@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- mm/vmscan.c | 25 +++++++++++++++----------
- 1 file changed, 15 insertions(+), 10 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4934,18 +4934,20 @@ static int shrink_one(struct lruvec *lru
-
- static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
- {
-+ int op;
- int gen;
- int bin;
- int first_bin;
- struct lruvec *lruvec;
- struct lru_gen_page *lrugen;
-+ struct mem_cgroup *memcg;
- const struct hlist_nulls_node *pos;
-- int op = 0;
-- struct mem_cgroup *memcg = NULL;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
- bin = first_bin = prandom_u32_max(MEMCG_NR_BINS);
- restart:
-+ op = 0;
-+ memcg = NULL;
- gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
-
- rcu_read_lock();
-@@ -4969,14 +4971,22 @@ restart:
-
- op = shrink_one(lruvec, sc);
-
-- if (sc->nr_reclaimed >= nr_to_reclaim)
-- goto success;
--
- rcu_read_lock();
-+
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
-+ break;
- }
-
- rcu_read_unlock();
-
-+ if (op)
-+ lru_gen_rotate_memcg(lruvec, op);
-+
-+ mem_cgroup_put(memcg);
-+
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
-+ return;
-+
- /* restart if raced with lru_gen_rotate_memcg() */
- if (gen != get_nulls_value(pos))
- goto restart;
-@@ -4985,11 +4995,6 @@ restart:
- bin = get_memcg_bin(bin + 1);
- if (bin != first_bin)
- goto restart;
--success:
-- if (op)
-- lru_gen_rotate_memcg(lruvec, op);
--
-- mem_cgroup_put(memcg);
- }
-
- static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
diff --git a/target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch b/target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch
deleted file mode 100644
index e154494a51..0000000000
--- a/target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch
+++ /dev/null
@@ -1,266 +0,0 @@
-From 087ed25eaf5a78a678508e893f80addab9b1c103 Mon Sep 17 00:00:00 2001
-From: Kalesh Singh <kaleshsingh@google.com>
-Date: Thu, 13 Apr 2023 14:43:26 -0700
-Subject: [PATCH] mm: Multi-gen LRU: remove wait_event_killable()
-
-Android 14 and later default to MGLRU [1] and field telemetry showed
-occasional long tail latency (>100ms) in the reclaim path.
-
-Tracing revealed priority inversion in the reclaim path. In
-try_to_inc_max_seq(), when high priority tasks were blocked on
-wait_event_killable(), the preemption of the low priority task to call
-wake_up_all() caused those high priority tasks to wait longer than
-necessary. In general, this problem is not different from others of its
-kind, e.g., one caused by mutex_lock(). However, it is specific to MGLRU
-because it introduced the new wait queue lruvec->mm_state.wait.
-
-The purpose of this new wait queue is to avoid the thundering herd
-problem. If many direct reclaimers rush into try_to_inc_max_seq(), only
-one can succeed, i.e., the one to wake up the rest, and the rest who
-failed might cause premature OOM kills if they do not wait. So far there
-is no evidence supporting this scenario, based on how often the wait has
-been hit. And this begs the question how useful the wait queue is in
-practice.
-
-Based on Minchan's recommendation, which is in line with his commit
-6d4675e60135 ("mm: don't be stuck to rmap lock on reclaim path") and the
-rest of the MGLRU code which also uses trylock when possible, remove the
-wait queue.
-
-[1] https://android-review.googlesource.com/q/I7ed7fbfd6ef9ce10053347528125dd98c39e50bf
-
-Link: https://lkml.kernel.org/r/20230413214326.2147568-1-kaleshsingh@google.com
-Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
-Change-Id: I911f3968fd1adb25171279cc5b6f48ccb7efc8de
-Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
-Suggested-by: Minchan Kim <minchan@kernel.org>
-Reported-by: Wei Wang <wvw@google.com>
-Acked-by: Yu Zhao <yuzhao@google.com>
-Cc: Minchan Kim <minchan@kernel.org>
-Cc: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
-Cc: Suleiman Souhlal <suleiman@google.com>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mmzone.h | 8 +--
- mm/vmscan.c | 111 +++++++++++++++--------------------------
- 2 files changed, 42 insertions(+), 77 deletions(-)
-
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -452,18 +452,14 @@ enum {
- struct lru_gen_mm_state {
- /* set to max_seq after each iteration */
- unsigned long seq;
-- /* where the current iteration continues (inclusive) */
-+ /* where the current iteration continues after */
- struct list_head *head;
-- /* where the last iteration ended (exclusive) */
-+ /* where the last iteration ended before */
- struct list_head *tail;
-- /* to wait for the last page table walker to finish */
-- struct wait_queue_head wait;
- /* Bloom filters flip after each iteration */
- unsigned long *filters[NR_BLOOM_FILTERS];
- /* the mm stats for debugging */
- unsigned long stats[NR_HIST_GENS][NR_MM_STATS];
-- /* the number of concurrent page table walkers */
-- int nr_walkers;
- };
-
- struct lru_gen_mm_walk {
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -2999,18 +2999,13 @@ void lru_gen_del_mm(struct mm_struct *mm
- if (!lruvec)
- continue;
-
-- /* where the last iteration ended (exclusive) */
-+ /* where the current iteration continues after */
-+ if (lruvec->mm_state.head == &mm->lru_gen.list)
-+ lruvec->mm_state.head = lruvec->mm_state.head->prev;
-+
-+ /* where the last iteration ended before */
- if (lruvec->mm_state.tail == &mm->lru_gen.list)
- lruvec->mm_state.tail = lruvec->mm_state.tail->next;
--
-- /* where the current iteration continues (inclusive) */
-- if (lruvec->mm_state.head != &mm->lru_gen.list)
-- continue;
--
-- lruvec->mm_state.head = lruvec->mm_state.head->next;
-- /* the deletion ends the current iteration */
-- if (lruvec->mm_state.head == &mm_list->fifo)
-- WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1);
- }
-
- list_del_init(&mm->lru_gen.list);
-@@ -3194,68 +3189,54 @@ static bool iterate_mm_list(struct lruve
- struct mm_struct **iter)
- {
- bool first = false;
-- bool last = true;
-+ bool last = false;
- struct mm_struct *mm = NULL;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
- struct lru_gen_mm_state *mm_state = &lruvec->mm_state;
-
- /*
-- * There are four interesting cases for this page table walker:
-- * 1. It tries to start a new iteration of mm_list with a stale max_seq;
-- * there is nothing left to do.
-- * 2. It's the first of the current generation, and it needs to reset
-- * the Bloom filter for the next generation.
-- * 3. It reaches the end of mm_list, and it needs to increment
-- * mm_state->seq; the iteration is done.
-- * 4. It's the last of the current generation, and it needs to reset the
-- * mm stats counters for the next generation.
-+ * mm_state->seq is incremented after each iteration of mm_list. There
-+ * are three interesting cases for this page table walker:
-+ * 1. It tries to start a new iteration with a stale max_seq: there is
-+ * nothing left to do.
-+ * 2. It started the next iteration: it needs to reset the Bloom filter
-+ * so that a fresh set of PTE tables can be recorded.
-+ * 3. It ended the current iteration: it needs to reset the mm stats
-+ * counters and tell its caller to increment max_seq.
- */
- spin_lock(&mm_list->lock);
-
- VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq);
-- VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq);
-- VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers);
-
-- if (walk->max_seq <= mm_state->seq) {
-- if (!*iter)
-- last = false;
-+ if (walk->max_seq <= mm_state->seq)
- goto done;
-- }
-
-- if (!mm_state->nr_walkers) {
-- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
-+ if (!mm_state->head)
-+ mm_state->head = &mm_list->fifo;
-
-- mm_state->head = mm_list->fifo.next;
-+ if (mm_state->head == &mm_list->fifo)
- first = true;
-- }
--
-- while (!mm && mm_state->head != &mm_list->fifo) {
-- mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
-
-+ do {
- mm_state->head = mm_state->head->next;
-+ if (mm_state->head == &mm_list->fifo) {
-+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
-+ last = true;
-+ break;
-+ }
-
- /* force scan for those added after the last iteration */
-- if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) {
-- mm_state->tail = mm_state->head;
-+ if (!mm_state->tail || mm_state->tail == mm_state->head) {
-+ mm_state->tail = mm_state->head->next;
- walk->force_scan = true;
- }
-
-+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
- if (should_skip_mm(mm, walk))
- mm = NULL;
-- }
--
-- if (mm_state->head == &mm_list->fifo)
-- WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
-+ } while (!mm);
- done:
-- if (*iter && !mm)
-- mm_state->nr_walkers--;
-- if (!*iter && mm)
-- mm_state->nr_walkers++;
--
-- if (mm_state->nr_walkers)
-- last = false;
--
- if (*iter || last)
- reset_mm_stats(lruvec, walk, last);
-
-@@ -3283,9 +3264,9 @@ static bool iterate_mm_list_nowalk(struc
-
- VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq);
-
-- if (max_seq > mm_state->seq && !mm_state->nr_walkers) {
-- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
--
-+ if (max_seq > mm_state->seq) {
-+ mm_state->head = NULL;
-+ mm_state->tail = NULL;
- WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
- reset_mm_stats(lruvec, NULL, true);
- success = true;
-@@ -3894,10 +3875,6 @@ restart:
-
- walk_pmd_range(&val, addr, next, args);
-
-- /* a racy check to curtail the waiting time */
-- if (wq_has_sleeper(&walk->lruvec->mm_state.wait))
-- return 1;
--
- if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
- end = (addr | ~PUD_MASK) + 1;
- goto done;
-@@ -3930,8 +3907,14 @@ static void walk_mm(struct lruvec *lruve
- walk->next_addr = FIRST_USER_ADDRESS;
-
- do {
-+ DEFINE_MAX_SEQ(lruvec);
-+
- err = -EBUSY;
-
-+ /* another thread might have called inc_max_seq() */
-+ if (walk->max_seq != max_seq)
-+ break;
-+
- /* page_update_gen() requires stable page_memcg() */
- if (!mem_cgroup_trylock_pages(memcg))
- break;
-@@ -4164,25 +4147,12 @@ static bool try_to_inc_max_seq(struct lr
- success = iterate_mm_list(lruvec, walk, &mm);
- if (mm)
- walk_mm(lruvec, mm, walk);
--
-- cond_resched();
- } while (mm);
- done:
-- if (!success) {
-- if (sc->priority <= DEF_PRIORITY - 2)
-- wait_event_killable(lruvec->mm_state.wait,
-- max_seq < READ_ONCE(lrugen->max_seq));
-- return false;
-- }
-+ if (success)
-+ inc_max_seq(lruvec, can_swap, force_scan);
-
-- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
--
-- inc_max_seq(lruvec, can_swap, force_scan);
-- /* either this sees any waiters or they will see updated max_seq */
-- if (wq_has_sleeper(&lruvec->mm_state.wait))
-- wake_up_all(&lruvec->mm_state.wait);
--
-- return true;
-+ return success;
- }
-
- static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
-@@ -5746,7 +5716,6 @@ void lru_gen_init_lruvec(struct lruvec *
- INIT_LIST_HEAD(&lrugen->pages[gen][type][zone]);
-
- lruvec->mm_state.seq = MIN_NR_GENS;
-- init_waitqueue_head(&lruvec->mm_state.wait);
- }
-
- #ifdef CONFIG_MEMCG
diff --git a/target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch b/target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch
deleted file mode 100644
index 82feb7421d..0000000000
--- a/target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Date: Tue, 5 Oct 2021 18:54:02 +0200
-Subject: [PATCH] MIPS: uasm: Enable muhu opcode for MIPS R6
-
-Enable the 'muhu' instruction, complementing the existing 'mulu', needed
-to implement a MIPS32 BPF JIT.
-
-Also fix a typo in the existing definition of 'dmulu'.
-
-Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
-
-This patch is a dependency for my 32-bit MIPS eBPF JIT.
-
-Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
----
-
---- a/arch/mips/include/asm/uasm.h
-+++ b/arch/mips/include/asm/uasm.h
-@@ -145,6 +145,7 @@ Ip_u1(_mtlo);
- Ip_u3u1u2(_mul);
- Ip_u1u2(_multu);
- Ip_u3u1u2(_mulu);
-+Ip_u3u1u2(_muhu);
- Ip_u3u1u2(_nor);
- Ip_u3u1u2(_or);
- Ip_u2u1u3(_ori);
---- a/arch/mips/mm/uasm-mips.c
-+++ b/arch/mips/mm/uasm-mips.c
-@@ -90,7 +90,7 @@ static const struct insn insn_table[insn
- RS | RT | RD},
- [insn_dmtc0] = {M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
- [insn_dmultu] = {M(spec_op, 0, 0, 0, 0, dmultu_op), RS | RT},
-- [insn_dmulu] = {M(spec_op, 0, 0, 0, dmult_dmul_op, dmultu_op),
-+ [insn_dmulu] = {M(spec_op, 0, 0, 0, dmultu_dmulu_op, dmultu_op),
- RS | RT | RD},
- [insn_drotr] = {M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE},
- [insn_drotr32] = {M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE},
-@@ -150,6 +150,8 @@ static const struct insn insn_table[insn
- [insn_mtlo] = {M(spec_op, 0, 0, 0, 0, mtlo_op), RS},
- [insn_mulu] = {M(spec_op, 0, 0, 0, multu_mulu_op, multu_op),
- RS | RT | RD},
-+ [insn_muhu] = {M(spec_op, 0, 0, 0, multu_muhu_op, multu_op),
-+ RS | RT | RD},
- #ifndef CONFIG_CPU_MIPSR6
- [insn_mul] = {M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD},
- #else
---- a/arch/mips/mm/uasm.c
-+++ b/arch/mips/mm/uasm.c
-@@ -59,7 +59,7 @@ enum opcode {
- insn_lddir, insn_ldpte, insn_ldx, insn_lh, insn_lhu, insn_ll, insn_lld,
- insn_lui, insn_lw, insn_lwu, insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi,
- insn_mflo, insn_modu, insn_movn, insn_movz, insn_mtc0, insn_mthc0,
-- insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu, insn_nor,
-+ insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu, insn_muhu, insn_nor,
- insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sb, insn_sc,
- insn_scd, insn_seleqz, insn_selnez, insn_sd, insn_sh, insn_sll,
- insn_sllv, insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra,
-@@ -344,6 +344,7 @@ I_u1(_mtlo)
- I_u3u1u2(_mul)
- I_u1u2(_multu)
- I_u3u1u2(_mulu)
-+I_u3u1u2(_muhu)
- I_u3u1u2(_nor)
- I_u3u1u2(_or)
- I_u2u1u3(_ori)
diff --git a/target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch b/target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch
deleted file mode 100644
index 3a4d573f80..0000000000
--- a/target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Date: Tue, 5 Oct 2021 18:54:03 +0200
-Subject: [PATCH] mips: uasm: Add workaround for Loongson-2F nop CPU errata
-
-This patch implements a workaround for the Loongson-2F nop in generated,
-code, if the existing option CONFIG_CPU_NOP_WORKAROUND is set. Before,
-the binutils option -mfix-loongson2f-nop was enabled, but no workaround
-was done when emitting MIPS code. Now, the nop pseudo instruction is
-emitted as "or ax,ax,zero" instead of the default "sll zero,zero,0". This
-is consistent with the workaround implemented by binutils.
-
-Link: https://sourceware.org/legacy-ml/binutils/2009-11/msg00387.html
-
-Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
----
-
---- a/arch/mips/include/asm/uasm.h
-+++ b/arch/mips/include/asm/uasm.h
-@@ -249,7 +249,11 @@ static inline void uasm_l##lb(struct uas
- #define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off)
- #define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
- #define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b)
-+#ifdef CONFIG_CPU_NOP_WORKAROUNDS
-+#define uasm_i_nop(buf) uasm_i_or(buf, 1, 1, 0)
-+#else
- #define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0)
-+#endif
- #define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
-
- static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1,
diff --git a/target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch b/target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch
deleted file mode 100644
index 7980659961..0000000000
--- a/target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch
+++ /dev/null
@@ -1,3078 +0,0 @@
-From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Date: Tue, 5 Oct 2021 18:54:04 +0200
-Subject: [PATCH] mips: bpf: Add eBPF JIT for 32-bit MIPS
-
-This is an implementation of an eBPF JIT for 32-bit MIPS I-V and MIPS32.
-The implementation supports all 32-bit and 64-bit ALU and JMP operations,
-including the recently-added atomics. 64-bit div/mod and 64-bit atomics
-are implemented using function calls to math64 and atomic64 functions,
-respectively. All 32-bit operations are implemented natively by the JIT,
-except if the CPU lacks ll/sc instructions.
-
-Register mapping
-================
-All 64-bit eBPF registers are mapped to native 32-bit MIPS register pairs,
-and does not use any stack scratch space for register swapping. This means
-that all eBPF register data is kept in CPU registers all the time, and
-this simplifies the register management a lot. It also reduces the JIT's
-pressure on temporary registers since we do not have to move data around.
-
-Native register pairs are ordered according to CPU endiannes, following
-the O32 calling convention for passing 64-bit arguments and return values.
-The eBPF return value, arguments and callee-saved registers are mapped to
-their native MIPS equivalents.
-
-Since the 32 highest bits in the eBPF FP (frame pointer) register are
-always zero, only one general-purpose register is actually needed for the
-mapping. The MIPS fp register is used for this purpose. The high bits are
-mapped to MIPS register r0. This saves us one CPU register, which is much
-needed for temporaries, while still allowing us to treat the R10 (FP)
-register just like any other eBPF register in the JIT.
-
-The MIPS gp (global pointer) and at (assembler temporary) registers are
-used as internal temporary registers for constant blinding. CPU registers
-t6-t9 are used internally by the JIT when constructing more complex 64-bit
-operations. This is precisely what is needed - two registers to store an
-operand value, and two more as scratch registers when performing the
-operation.
-
-The register mapping is shown below.
-
- R0 - $v1, $v0 return value
- R1 - $a1, $a0 argument 1, passed in registers
- R2 - $a3, $a2 argument 2, passed in registers
- R3 - $t1, $t0 argument 3, passed on stack
- R4 - $t3, $t2 argument 4, passed on stack
- R5 - $t4, $t3 argument 5, passed on stack
- R6 - $s1, $s0 callee-saved
- R7 - $s3, $s2 callee-saved
- R8 - $s5, $s4 callee-saved
- R9 - $s7, $s6 callee-saved
- FP - $r0, $fp 32-bit frame pointer
- AX - $gp, $at constant-blinding
- $t6 - $t9 unallocated, JIT temporaries
-
-Jump offsets
-============
-The JIT tries to map all conditional JMP operations to MIPS conditional
-PC-relative branches. The MIPS branch offset field is 18 bits, in bytes,
-which is equivalent to the eBPF 16-bit instruction offset. However, since
-the JIT may emit more than one CPU instruction per eBPF instruction, the
-field width may overflow. If that happens, the JIT converts the long
-conditional jump to a short PC-relative branch with the condition
-inverted, jumping over a long unconditional absolute jmp (j).
-
-This conversion will change the instruction offset mapping used for jumps,
-and may in turn result in more branch offset overflows. The JIT therefore
-dry-runs the translation until no more branches are converted and the
-offsets do not change anymore. There is an upper bound on this of course,
-and if the JIT hits that limit, the last two iterations are run with all
-branches being converted.
-
-Tail call count
-===============
-The current tail call count is stored in the 16-byte area of the caller's
-stack frame that is reserved for the callee in the o32 ABI. The value is
-initialized in the prologue, and propagated to the tail-callee by skipping
-the initialization instructions when emitting the tail call.
-
-Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
----
- create mode 100644 arch/mips/net/bpf_jit_comp.c
- create mode 100644 arch/mips/net/bpf_jit_comp.h
- create mode 100644 arch/mips/net/bpf_jit_comp32.c
-
---- a/arch/mips/net/Makefile
-+++ b/arch/mips/net/Makefile
-@@ -2,4 +2,9 @@
- # MIPS networking code
-
- obj-$(CONFIG_MIPS_CBPF_JIT) += bpf_jit.o bpf_jit_asm.o
--obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o
-+
-+ifeq ($(CONFIG_32BIT),y)
-+ obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp.o bpf_jit_comp32.o
-+else
-+ obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o
-+endif
---- /dev/null
-+++ b/arch/mips/net/bpf_jit_comp.c
-@@ -0,0 +1,1020 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Just-In-Time compiler for eBPF bytecode on MIPS.
-+ * Implementation of JIT functions common to 32-bit and 64-bit CPUs.
-+ *
-+ * Copyright (c) 2021 Anyfi Networks AB.
-+ * Author: Johan Almbladh <johan.almbladh@gmail.com>
-+ *
-+ * Based on code and ideas from
-+ * Copyright (c) 2017 Cavium, Inc.
-+ * Copyright (c) 2017 Shubham Bansal <illusionist.neo@gmail.com>
-+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
-+ */
-+
-+/*
-+ * Code overview
-+ * =============
-+ *
-+ * - bpf_jit_comp.h
-+ * Common definitions and utilities.
-+ *
-+ * - bpf_jit_comp.c
-+ * Implementation of JIT top-level logic and exported JIT API functions.
-+ * Implementation of internal operations shared by 32-bit and 64-bit code.
-+ * JMP and ALU JIT control code, register control code, shared ALU and
-+ * JMP/JMP32 JIT operations.
-+ *
-+ * - bpf_jit_comp32.c
-+ * Implementation of functions to JIT prologue, epilogue and a single eBPF
-+ * instruction for 32-bit MIPS CPUs. The functions use shared operations
-+ * where possible, and implement the rest for 32-bit MIPS such as ALU64
-+ * operations.
-+ *
-+ * - bpf_jit_comp64.c
-+ * Ditto, for 64-bit MIPS CPUs.
-+ *
-+ * Zero and sign extension
-+ * ========================
-+ * 32-bit MIPS instructions on 64-bit MIPS registers use sign extension,
-+ * but the eBPF instruction set mandates zero extension. We let the verifier
-+ * insert explicit zero-extensions after 32-bit ALU operations, both for
-+ * 32-bit and 64-bit MIPS JITs. Conditional JMP32 operations on 64-bit MIPs
-+ * are JITed with sign extensions inserted when so expected.
-+ *
-+ * ALU operations
-+ * ==============
-+ * ALU operations on 32/64-bit MIPS and ALU64 operations on 64-bit MIPS are
-+ * JITed in the following steps. ALU64 operations on 32-bit MIPS are more
-+ * complicated and therefore only processed by special implementations in
-+ * step (3).
-+ *
-+ * 1) valid_alu_i:
-+ * Determine if an immediate operation can be emitted as such, or if
-+ * we must fall back to the register version.
-+ *
-+ * 2) rewrite_alu_i:
-+ * Convert BPF operation and immediate value to a canonical form for
-+ * JITing. In some degenerate cases this form may be a no-op.
-+ *
-+ * 3) emit_alu_{i,i64,r,64}:
-+ * Emit instructions for an ALU or ALU64 immediate or register operation.
-+ *
-+ * JMP operations
-+ * ==============
-+ * JMP and JMP32 operations require an JIT instruction offset table for
-+ * translating the jump offset. This table is computed by dry-running the
-+ * JIT without actually emitting anything. However, the computed PC-relative
-+ * offset may overflow the 18-bit offset field width of the native MIPS
-+ * branch instruction. In such cases, the long jump is converted into the
-+ * following sequence.
-+ *
-+ * <branch> !<cond> +2 Inverted PC-relative branch
-+ * nop Delay slot
-+ * j <offset> Unconditional absolute long jump
-+ * nop Delay slot
-+ *
-+ * Since this converted sequence alters the offset table, all offsets must
-+ * be re-calculated. This may in turn trigger new branch conversions, so
-+ * the process is repeated until no further changes are made. Normally it
-+ * completes in 1-2 iterations. If JIT_MAX_ITERATIONS should reached, we
-+ * fall back to converting every remaining jump operation. The branch
-+ * conversion is independent of how the JMP or JMP32 condition is JITed.
-+ *
-+ * JMP32 and JMP operations are JITed as follows.
-+ *
-+ * 1) setup_jmp_{i,r}:
-+ * Convert jump conditional and offset into a form that can be JITed.
-+ * This form may be a no-op, a canonical form, or an inverted PC-relative
-+ * jump if branch conversion is necessary.
-+ *
-+ * 2) valid_jmp_i:
-+ * Determine if an immediate operations can be emitted as such, or if
-+ * we must fall back to the register version. Applies to JMP32 for 32-bit
-+ * MIPS, and both JMP and JMP32 for 64-bit MIPS.
-+ *
-+ * 3) emit_jmp_{i,i64,r,r64}:
-+ * Emit instructions for an JMP or JMP32 immediate or register operation.
-+ *
-+ * 4) finish_jmp_{i,r}:
-+ * Emit any instructions needed to finish the jump. This includes a nop
-+ * for the delay slot if a branch was emitted, and a long absolute jump
-+ * if the branch was converted.
-+ */
-+
-+#include <linux/limits.h>
-+#include <linux/bitops.h>
-+#include <linux/errno.h>
-+#include <linux/filter.h>
-+#include <linux/bpf.h>
-+#include <linux/slab.h>
-+#include <asm/bitops.h>
-+#include <asm/cacheflush.h>
-+#include <asm/cpu-features.h>
-+#include <asm/isa-rev.h>
-+#include <asm/uasm.h>
-+
-+#include "bpf_jit_comp.h"
-+
-+/* Convenience macros for descriptor access */
-+#define CONVERTED(desc) ((desc) & JIT_DESC_CONVERT)
-+#define INDEX(desc) ((desc) & ~JIT_DESC_CONVERT)
-+
-+/*
-+ * Push registers on the stack, starting at a given depth from the stack
-+ * pointer and increasing. The next depth to be written is returned.
-+ */
-+int push_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth)
-+{
-+ int reg;
-+
-+ for (reg = 0; reg < BITS_PER_BYTE * sizeof(mask); reg++)
-+ if (mask & BIT(reg)) {
-+ if ((excl & BIT(reg)) == 0) {
-+ if (sizeof(long) == 4)
-+ emit(ctx, sw, reg, depth, MIPS_R_SP);
-+ else /* sizeof(long) == 8 */
-+ emit(ctx, sd, reg, depth, MIPS_R_SP);
-+ }
-+ depth += sizeof(long);
-+ }
-+
-+ ctx->stack_used = max((int)ctx->stack_used, depth);
-+ return depth;
-+}
-+
-+/*
-+ * Pop registers from the stack, starting at a given depth from the stack
-+ * pointer and increasing. The next depth to be read is returned.
-+ */
-+int pop_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth)
-+{
-+ int reg;
-+
-+ for (reg = 0; reg < BITS_PER_BYTE * sizeof(mask); reg++)
-+ if (mask & BIT(reg)) {
-+ if ((excl & BIT(reg)) == 0) {
-+ if (sizeof(long) == 4)
-+ emit(ctx, lw, reg, depth, MIPS_R_SP);
-+ else /* sizeof(long) == 8 */
-+ emit(ctx, ld, reg, depth, MIPS_R_SP);
-+ }
-+ depth += sizeof(long);
-+ }
-+
-+ return depth;
-+}
-+
-+/* Compute the 28-bit jump target address from a BPF program location */
-+int get_target(struct jit_context *ctx, u32 loc)
-+{
-+ u32 index = INDEX(ctx->descriptors[loc]);
-+ unsigned long pc = (unsigned long)&ctx->target[ctx->jit_index];
-+ unsigned long addr = (unsigned long)&ctx->target[index];
-+
-+ if (!ctx->target)
-+ return 0;
-+
-+ if ((addr ^ pc) & ~MIPS_JMP_MASK)
-+ return -1;
-+
-+ return addr & MIPS_JMP_MASK;
-+}
-+
-+/* Compute the PC-relative offset to relative BPF program offset */
-+int get_offset(const struct jit_context *ctx, int off)
-+{
-+ return (INDEX(ctx->descriptors[ctx->bpf_index + off]) -
-+ ctx->jit_index - 1) * sizeof(u32);
-+}
-+
-+/* dst = imm (register width) */
-+void emit_mov_i(struct jit_context *ctx, u8 dst, s32 imm)
-+{
-+ if (imm >= -0x8000 && imm <= 0x7fff) {
-+ emit(ctx, addiu, dst, MIPS_R_ZERO, imm);
-+ } else {
-+ emit(ctx, lui, dst, (s16)((u32)imm >> 16));
-+ emit(ctx, ori, dst, dst, (u16)(imm & 0xffff));
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* dst = src (register width) */
-+void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src)
-+{
-+ emit(ctx, ori, dst, src, 0);
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Validate ALU immediate range */
-+bool valid_alu_i(u8 op, s32 imm)
-+{
-+ switch (BPF_OP(op)) {
-+ case BPF_NEG:
-+ case BPF_LSH:
-+ case BPF_RSH:
-+ case BPF_ARSH:
-+ /* All legal eBPF values are valid */
-+ return true;
-+ case BPF_ADD:
-+ /* imm must be 16 bits */
-+ return imm >= -0x8000 && imm <= 0x7fff;
-+ case BPF_SUB:
-+ /* -imm must be 16 bits */
-+ return imm >= -0x7fff && imm <= 0x8000;
-+ case BPF_AND:
-+ case BPF_OR:
-+ case BPF_XOR:
-+ /* imm must be 16 bits unsigned */
-+ return imm >= 0 && imm <= 0xffff;
-+ case BPF_MUL:
-+ /* imm must be zero or a positive power of two */
-+ return imm == 0 || (imm > 0 && is_power_of_2(imm));
-+ case BPF_DIV:
-+ case BPF_MOD:
-+ /* imm must be an 17-bit power of two */
-+ return (u32)imm <= 0x10000 && is_power_of_2((u32)imm);
-+ }
-+ return false;
-+}
-+
-+/* Rewrite ALU immediate operation */
-+bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val)
-+{
-+ bool act = true;
-+
-+ switch (BPF_OP(op)) {
-+ case BPF_LSH:
-+ case BPF_RSH:
-+ case BPF_ARSH:
-+ case BPF_ADD:
-+ case BPF_SUB:
-+ case BPF_OR:
-+ case BPF_XOR:
-+ /* imm == 0 is a no-op */
-+ act = imm != 0;
-+ break;
-+ case BPF_MUL:
-+ if (imm == 1) {
-+ /* dst * 1 is a no-op */
-+ act = false;
-+ } else if (imm == 0) {
-+ /* dst * 0 is dst & 0 */
-+ op = BPF_AND;
-+ } else {
-+ /* dst * (1 << n) is dst << n */
-+ op = BPF_LSH;
-+ imm = ilog2(abs(imm));
-+ }
-+ break;
-+ case BPF_DIV:
-+ if (imm == 1) {
-+ /* dst / 1 is a no-op */
-+ act = false;
-+ } else {
-+ /* dst / (1 << n) is dst >> n */
-+ op = BPF_RSH;
-+ imm = ilog2(imm);
-+ }
-+ break;
-+ case BPF_MOD:
-+ /* dst % (1 << n) is dst & ((1 << n) - 1) */
-+ op = BPF_AND;
-+ imm--;
-+ break;
-+ }
-+
-+ *alu = op;
-+ *val = imm;
-+ return act;
-+}
-+
-+/* ALU immediate operation (32-bit) */
-+void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op)
-+{
-+ switch (BPF_OP(op)) {
-+ /* dst = -dst */
-+ case BPF_NEG:
-+ emit(ctx, subu, dst, MIPS_R_ZERO, dst);
-+ break;
-+ /* dst = dst & imm */
-+ case BPF_AND:
-+ emit(ctx, andi, dst, dst, (u16)imm);
-+ break;
-+ /* dst = dst | imm */
-+ case BPF_OR:
-+ emit(ctx, ori, dst, dst, (u16)imm);
-+ break;
-+ /* dst = dst ^ imm */
-+ case BPF_XOR:
-+ emit(ctx, xori, dst, dst, (u16)imm);
-+ break;
-+ /* dst = dst << imm */
-+ case BPF_LSH:
-+ emit(ctx, sll, dst, dst, imm);
-+ break;
-+ /* dst = dst >> imm */
-+ case BPF_RSH:
-+ emit(ctx, srl, dst, dst, imm);
-+ break;
-+ /* dst = dst >> imm (arithmetic) */
-+ case BPF_ARSH:
-+ emit(ctx, sra, dst, dst, imm);
-+ break;
-+ /* dst = dst + imm */
-+ case BPF_ADD:
-+ emit(ctx, addiu, dst, dst, imm);
-+ break;
-+ /* dst = dst - imm */
-+ case BPF_SUB:
-+ emit(ctx, addiu, dst, dst, -imm);
-+ break;
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* ALU register operation (32-bit) */
-+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op)
-+{
-+ switch (BPF_OP(op)) {
-+ /* dst = dst & src */
-+ case BPF_AND:
-+ emit(ctx, and, dst, dst, src);
-+ break;
-+ /* dst = dst | src */
-+ case BPF_OR:
-+ emit(ctx, or, dst, dst, src);
-+ break;
-+ /* dst = dst ^ src */
-+ case BPF_XOR:
-+ emit(ctx, xor, dst, dst, src);
-+ break;
-+ /* dst = dst << src */
-+ case BPF_LSH:
-+ emit(ctx, sllv, dst, dst, src);
-+ break;
-+ /* dst = dst >> src */
-+ case BPF_RSH:
-+ emit(ctx, srlv, dst, dst, src);
-+ break;
-+ /* dst = dst >> src (arithmetic) */
-+ case BPF_ARSH:
-+ emit(ctx, srav, dst, dst, src);
-+ break;
-+ /* dst = dst + src */
-+ case BPF_ADD:
-+ emit(ctx, addu, dst, dst, src);
-+ break;
-+ /* dst = dst - src */
-+ case BPF_SUB:
-+ emit(ctx, subu, dst, dst, src);
-+ break;
-+ /* dst = dst * src */
-+ case BPF_MUL:
-+ if (cpu_has_mips32r1 || cpu_has_mips32r6) {
-+ emit(ctx, mul, dst, dst, src);
-+ } else {
-+ emit(ctx, multu, dst, src);
-+ emit(ctx, mflo, dst);
-+ }
-+ break;
-+ /* dst = dst / src */
-+ case BPF_DIV:
-+ if (cpu_has_mips32r6) {
-+ emit(ctx, divu_r6, dst, dst, src);
-+ } else {
-+ emit(ctx, divu, dst, src);
-+ emit(ctx, mflo, dst);
-+ }
-+ break;
-+ /* dst = dst % src */
-+ case BPF_MOD:
-+ if (cpu_has_mips32r6) {
-+ emit(ctx, modu, dst, dst, src);
-+ } else {
-+ emit(ctx, divu, dst, src);
-+ emit(ctx, mfhi, dst);
-+ }
-+ break;
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Atomic read-modify-write (32-bit) */
-+void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code)
-+{
-+ emit(ctx, ll, MIPS_R_T9, off, dst);
-+ switch (code) {
-+ case BPF_ADD:
-+ emit(ctx, addu, MIPS_R_T8, MIPS_R_T9, src);
-+ break;
-+ case BPF_AND:
-+ emit(ctx, and, MIPS_R_T8, MIPS_R_T9, src);
-+ break;
-+ case BPF_OR:
-+ emit(ctx, or, MIPS_R_T8, MIPS_R_T9, src);
-+ break;
-+ case BPF_XOR:
-+ emit(ctx, xor, MIPS_R_T8, MIPS_R_T9, src);
-+ break;
-+ }
-+ emit(ctx, sc, MIPS_R_T8, off, dst);
-+ emit(ctx, beqz, MIPS_R_T8, -16);
-+ emit(ctx, nop); /* Delay slot */
-+}
-+
-+/* Atomic compare-and-exchange (32-bit) */
-+void emit_cmpxchg_r(struct jit_context *ctx, u8 dst, u8 src, u8 res, s16 off)
-+{
-+ emit(ctx, ll, MIPS_R_T9, off, dst);
-+ emit(ctx, bne, MIPS_R_T9, res, 12);
-+ emit(ctx, move, MIPS_R_T8, src); /* Delay slot */
-+ emit(ctx, sc, MIPS_R_T8, off, dst);
-+ emit(ctx, beqz, MIPS_R_T8, -20);
-+ emit(ctx, move, res, MIPS_R_T9); /* Delay slot */
-+ clobber_reg(ctx, res);
-+}
-+
-+/* Swap bytes and truncate a register word or half word */
-+void emit_bswap_r(struct jit_context *ctx, u8 dst, u32 width)
-+{
-+ u8 tmp = MIPS_R_T8;
-+ u8 msk = MIPS_R_T9;
-+
-+ switch (width) {
-+ /* Swap bytes in a word */
-+ case 32:
-+ if (cpu_has_mips32r2 || cpu_has_mips32r6) {
-+ emit(ctx, wsbh, dst, dst);
-+ emit(ctx, rotr, dst, dst, 16);
-+ } else {
-+ emit(ctx, sll, tmp, dst, 16); /* tmp = dst << 16 */
-+ emit(ctx, srl, dst, dst, 16); /* dst = dst >> 16 */
-+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */
-+
-+ emit(ctx, lui, msk, 0xff); /* msk = 0x00ff0000 */
-+ emit(ctx, ori, msk, msk, 0xff); /* msk = msk | 0xff */
-+
-+ emit(ctx, and, tmp, dst, msk); /* tmp = dst & msk */
-+ emit(ctx, sll, tmp, tmp, 8); /* tmp = tmp << 8 */
-+ emit(ctx, srl, dst, dst, 8); /* dst = dst >> 8 */
-+ emit(ctx, and, dst, dst, msk); /* dst = dst & msk */
-+ emit(ctx, or, dst, dst, tmp); /* reg = dst | tmp */
-+ }
-+ break;
-+ /* Swap bytes in a half word */
-+ case 16:
-+ if (cpu_has_mips32r2 || cpu_has_mips32r6) {
-+ emit(ctx, wsbh, dst, dst);
-+ emit(ctx, andi, dst, dst, 0xffff);
-+ } else {
-+ emit(ctx, andi, tmp, dst, 0xff00); /* t = d & 0xff00 */
-+ emit(ctx, srl, tmp, tmp, 8); /* t = t >> 8 */
-+ emit(ctx, andi, dst, dst, 0x00ff); /* d = d & 0x00ff */
-+ emit(ctx, sll, dst, dst, 8); /* d = d << 8 */
-+ emit(ctx, or, dst, dst, tmp); /* d = d | t */
-+ }
-+ break;
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Validate jump immediate range */
-+bool valid_jmp_i(u8 op, s32 imm)
-+{
-+ switch (op) {
-+ case JIT_JNOP:
-+ /* Immediate value not used */
-+ return true;
-+ case BPF_JEQ:
-+ case BPF_JNE:
-+ /* No immediate operation */
-+ return false;
-+ case BPF_JSET:
-+ case JIT_JNSET:
-+ /* imm must be 16 bits unsigned */
-+ return imm >= 0 && imm <= 0xffff;
-+ case BPF_JGE:
-+ case BPF_JLT:
-+ case BPF_JSGE:
-+ case BPF_JSLT:
-+ /* imm must be 16 bits */
-+ return imm >= -0x8000 && imm <= 0x7fff;
-+ case BPF_JGT:
-+ case BPF_JLE:
-+ case BPF_JSGT:
-+ case BPF_JSLE:
-+ /* imm + 1 must be 16 bits */
-+ return imm >= -0x8001 && imm <= 0x7ffe;
-+ }
-+ return false;
-+}
-+
-+/* Invert a conditional jump operation */
-+static u8 invert_jmp(u8 op)
-+{
-+ switch (op) {
-+ case BPF_JA: return JIT_JNOP;
-+ case BPF_JEQ: return BPF_JNE;
-+ case BPF_JNE: return BPF_JEQ;
-+ case BPF_JSET: return JIT_JNSET;
-+ case BPF_JGT: return BPF_JLE;
-+ case BPF_JGE: return BPF_JLT;
-+ case BPF_JLT: return BPF_JGE;
-+ case BPF_JLE: return BPF_JGT;
-+ case BPF_JSGT: return BPF_JSLE;
-+ case BPF_JSGE: return BPF_JSLT;
-+ case BPF_JSLT: return BPF_JSGE;
-+ case BPF_JSLE: return BPF_JSGT;
-+ }
-+ return 0;
-+}
-+
-+/* Prepare a PC-relative jump operation */
-+static void setup_jmp(struct jit_context *ctx, u8 bpf_op,
-+ s16 bpf_off, u8 *jit_op, s32 *jit_off)
-+{
-+ u32 *descp = &ctx->descriptors[ctx->bpf_index];
-+ int op = bpf_op;
-+ int offset = 0;
-+
-+ /* Do not compute offsets on the first pass */
-+ if (INDEX(*descp) == 0)
-+ goto done;
-+
-+ /* Skip jumps never taken */
-+ if (bpf_op == JIT_JNOP)
-+ goto done;
-+
-+ /* Convert jumps always taken */
-+ if (bpf_op == BPF_JA)
-+ *descp |= JIT_DESC_CONVERT;
-+
-+ /*
-+ * Current ctx->jit_index points to the start of the branch preamble.
-+ * Since the preamble differs among different branch conditionals,
-+ * the current index cannot be used to compute the branch offset.
-+ * Instead, we use the offset table value for the next instruction,
-+ * which gives the index immediately after the branch delay slot.
-+ */
-+ if (!CONVERTED(*descp)) {
-+ int target = ctx->bpf_index + bpf_off + 1;
-+ int origin = ctx->bpf_index + 1;
-+
-+ offset = (INDEX(ctx->descriptors[target]) -
-+ INDEX(ctx->descriptors[origin]) + 1) * sizeof(u32);
-+ }
-+
-+ /*
-+ * The PC-relative branch offset field on MIPS is 18 bits signed,
-+ * so if the computed offset is larger than this we generate a an
-+ * absolute jump that we skip with an inverted conditional branch.
-+ */
-+ if (CONVERTED(*descp) || offset < -0x20000 || offset > 0x1ffff) {
-+ offset = 3 * sizeof(u32);
-+ op = invert_jmp(bpf_op);
-+ ctx->changes += !CONVERTED(*descp);
-+ *descp |= JIT_DESC_CONVERT;
-+ }
-+
-+done:
-+ *jit_off = offset;
-+ *jit_op = op;
-+}
-+
-+/* Prepare a PC-relative jump operation with immediate conditional */
-+void setup_jmp_i(struct jit_context *ctx, s32 imm, u8 width,
-+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off)
-+{
-+ bool always = false;
-+ bool never = false;
-+
-+ switch (bpf_op) {
-+ case BPF_JEQ:
-+ case BPF_JNE:
-+ break;
-+ case BPF_JSET:
-+ case BPF_JLT:
-+ never = imm == 0;
-+ break;
-+ case BPF_JGE:
-+ always = imm == 0;
-+ break;
-+ case BPF_JGT:
-+ never = (u32)imm == U32_MAX;
-+ break;
-+ case BPF_JLE:
-+ always = (u32)imm == U32_MAX;
-+ break;
-+ case BPF_JSGT:
-+ never = imm == S32_MAX && width == 32;
-+ break;
-+ case BPF_JSGE:
-+ always = imm == S32_MIN && width == 32;
-+ break;
-+ case BPF_JSLT:
-+ never = imm == S32_MIN && width == 32;
-+ break;
-+ case BPF_JSLE:
-+ always = imm == S32_MAX && width == 32;
-+ break;
-+ }
-+
-+ if (never)
-+ bpf_op = JIT_JNOP;
-+ if (always)
-+ bpf_op = BPF_JA;
-+ setup_jmp(ctx, bpf_op, bpf_off, jit_op, jit_off);
-+}
-+
-+/* Prepare a PC-relative jump operation with register conditional */
-+void setup_jmp_r(struct jit_context *ctx, bool same_reg,
-+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off)
-+{
-+ switch (bpf_op) {
-+ case BPF_JSET:
-+ break;
-+ case BPF_JEQ:
-+ case BPF_JGE:
-+ case BPF_JLE:
-+ case BPF_JSGE:
-+ case BPF_JSLE:
-+ if (same_reg)
-+ bpf_op = BPF_JA;
-+ break;
-+ case BPF_JNE:
-+ case BPF_JLT:
-+ case BPF_JGT:
-+ case BPF_JSGT:
-+ case BPF_JSLT:
-+ if (same_reg)
-+ bpf_op = JIT_JNOP;
-+ break;
-+ }
-+ setup_jmp(ctx, bpf_op, bpf_off, jit_op, jit_off);
-+}
-+
-+/* Finish a PC-relative jump operation */
-+int finish_jmp(struct jit_context *ctx, u8 jit_op, s16 bpf_off)
-+{
-+ /* Emit conditional branch delay slot */
-+ if (jit_op != JIT_JNOP)
-+ emit(ctx, nop);
-+ /*
-+ * Emit an absolute long jump with delay slot,
-+ * if the PC-relative branch was converted.
-+ */
-+ if (CONVERTED(ctx->descriptors[ctx->bpf_index])) {
-+ int target = get_target(ctx, ctx->bpf_index + bpf_off + 1);
-+
-+ if (target < 0)
-+ return -1;
-+ emit(ctx, j, target);
-+ emit(ctx, nop);
-+ }
-+ return 0;
-+}
-+
-+/* Jump immediate (32-bit) */
-+void emit_jmp_i(struct jit_context *ctx, u8 dst, s32 imm, s32 off, u8 op)
-+{
-+ switch (op) {
-+ /* No-op, used internally for branch optimization */
-+ case JIT_JNOP:
-+ break;
-+ /* PC += off if dst & imm */
-+ case BPF_JSET:
-+ emit(ctx, andi, MIPS_R_T9, dst, (u16)imm);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */
-+ case JIT_JNSET:
-+ emit(ctx, andi, MIPS_R_T9, dst, (u16)imm);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst > imm */
-+ case BPF_JGT:
-+ emit(ctx, sltiu, MIPS_R_T9, dst, imm + 1);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst >= imm */
-+ case BPF_JGE:
-+ emit(ctx, sltiu, MIPS_R_T9, dst, imm);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst < imm */
-+ case BPF_JLT:
-+ emit(ctx, sltiu, MIPS_R_T9, dst, imm);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst <= imm */
-+ case BPF_JLE:
-+ emit(ctx, sltiu, MIPS_R_T9, dst, imm + 1);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst > imm (signed) */
-+ case BPF_JSGT:
-+ emit(ctx, slti, MIPS_R_T9, dst, imm + 1);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst >= imm (signed) */
-+ case BPF_JSGE:
-+ emit(ctx, slti, MIPS_R_T9, dst, imm);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst < imm (signed) */
-+ case BPF_JSLT:
-+ emit(ctx, slti, MIPS_R_T9, dst, imm);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst <= imm (signed) */
-+ case BPF_JSLE:
-+ emit(ctx, slti, MIPS_R_T9, dst, imm + 1);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ }
-+}
-+
-+/* Jump register (32-bit) */
-+void emit_jmp_r(struct jit_context *ctx, u8 dst, u8 src, s32 off, u8 op)
-+{
-+ switch (op) {
-+ /* No-op, used internally for branch optimization */
-+ case JIT_JNOP:
-+ break;
-+ /* PC += off if dst == src */
-+ case BPF_JEQ:
-+ emit(ctx, beq, dst, src, off);
-+ break;
-+ /* PC += off if dst != src */
-+ case BPF_JNE:
-+ emit(ctx, bne, dst, src, off);
-+ break;
-+ /* PC += off if dst & src */
-+ case BPF_JSET:
-+ emit(ctx, and, MIPS_R_T9, dst, src);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */
-+ case JIT_JNSET:
-+ emit(ctx, and, MIPS_R_T9, dst, src);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst > src */
-+ case BPF_JGT:
-+ emit(ctx, sltu, MIPS_R_T9, src, dst);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst >= src */
-+ case BPF_JGE:
-+ emit(ctx, sltu, MIPS_R_T9, dst, src);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst < src */
-+ case BPF_JLT:
-+ emit(ctx, sltu, MIPS_R_T9, dst, src);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst <= src */
-+ case BPF_JLE:
-+ emit(ctx, sltu, MIPS_R_T9, src, dst);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst > src (signed) */
-+ case BPF_JSGT:
-+ emit(ctx, slt, MIPS_R_T9, src, dst);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst >= src (signed) */
-+ case BPF_JSGE:
-+ emit(ctx, slt, MIPS_R_T9, dst, src);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst < src (signed) */
-+ case BPF_JSLT:
-+ emit(ctx, slt, MIPS_R_T9, dst, src);
-+ emit(ctx, bnez, MIPS_R_T9, off);
-+ break;
-+ /* PC += off if dst <= src (signed) */
-+ case BPF_JSLE:
-+ emit(ctx, slt, MIPS_R_T9, src, dst);
-+ emit(ctx, beqz, MIPS_R_T9, off);
-+ break;
-+ }
-+}
-+
-+/* Jump always */
-+int emit_ja(struct jit_context *ctx, s16 off)
-+{
-+ int target = get_target(ctx, ctx->bpf_index + off + 1);
-+
-+ if (target < 0)
-+ return -1;
-+ emit(ctx, j, target);
-+ emit(ctx, nop);
-+ return 0;
-+}
-+
-+/* Jump to epilogue */
-+int emit_exit(struct jit_context *ctx)
-+{
-+ int target = get_target(ctx, ctx->program->len);
-+
-+ if (target < 0)
-+ return -1;
-+ emit(ctx, j, target);
-+ emit(ctx, nop);
-+ return 0;
-+}
-+
-+/* Build the program body from eBPF bytecode */
-+static int build_body(struct jit_context *ctx)
-+{
-+ const struct bpf_prog *prog = ctx->program;
-+ unsigned int i;
-+
-+ ctx->stack_used = 0;
-+ for (i = 0; i < prog->len; i++) {
-+ const struct bpf_insn *insn = &prog->insnsi[i];
-+ u32 *descp = &ctx->descriptors[i];
-+ int ret;
-+
-+ access_reg(ctx, insn->src_reg);
-+ access_reg(ctx, insn->dst_reg);
-+
-+ ctx->bpf_index = i;
-+ if (ctx->target == NULL) {
-+ ctx->changes += INDEX(*descp) != ctx->jit_index;
-+ *descp &= JIT_DESC_CONVERT;
-+ *descp |= ctx->jit_index;
-+ }
-+
-+ ret = build_insn(insn, ctx);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (ret > 0) {
-+ i++;
-+ if (ctx->target == NULL)
-+ descp[1] = ctx->jit_index;
-+ }
-+ }
-+
-+ /* Store the end offset, where the epilogue begins */
-+ ctx->descriptors[prog->len] = ctx->jit_index;
-+ return 0;
-+}
-+
-+/* Set the branch conversion flag on all instructions */
-+static void set_convert_flag(struct jit_context *ctx, bool enable)
-+{
-+ const struct bpf_prog *prog = ctx->program;
-+ u32 flag = enable ? JIT_DESC_CONVERT : 0;
-+ unsigned int i;
-+
-+ for (i = 0; i <= prog->len; i++)
-+ ctx->descriptors[i] = INDEX(ctx->descriptors[i]) | flag;
-+}
-+
-+static void jit_fill_hole(void *area, unsigned int size)
-+{
-+ u32 *p;
-+
-+ /* We are guaranteed to have aligned memory. */
-+ for (p = area; size >= sizeof(u32); size -= sizeof(u32))
-+ uasm_i_break(&p, BRK_BUG); /* Increments p */
-+}
-+
-+bool bpf_jit_needs_zext(void)
-+{
-+ return true;
-+}
-+
-+struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
-+{
-+ struct bpf_prog *tmp, *orig_prog = prog;
-+ struct bpf_binary_header *header = NULL;
-+ struct jit_context ctx;
-+ bool tmp_blinded = false;
-+ unsigned int tmp_idx;
-+ unsigned int image_size;
-+ u8 *image_ptr;
-+ int tries;
-+
-+ /*
-+ * If BPF JIT was not enabled then we must fall back to
-+ * the interpreter.
-+ */
-+ if (!prog->jit_requested)
-+ return orig_prog;
-+ /*
-+ * If constant blinding was enabled and we failed during blinding
-+ * then we must fall back to the interpreter. Otherwise, we save
-+ * the new JITed code.
-+ */
-+ tmp = bpf_jit_blind_constants(prog);
-+ if (IS_ERR(tmp))
-+ return orig_prog;
-+ if (tmp != prog) {
-+ tmp_blinded = true;
-+ prog = tmp;
-+ }
-+
-+ memset(&ctx, 0, sizeof(ctx));
-+ ctx.program = prog;
-+
-+ /*
-+ * Not able to allocate memory for descriptors[], then
-+ * we must fall back to the interpreter
-+ */
-+ ctx.descriptors = kcalloc(prog->len + 1, sizeof(*ctx.descriptors),
-+ GFP_KERNEL);
-+ if (ctx.descriptors == NULL)
-+ goto out_err;
-+
-+ /* First pass discovers used resources */
-+ if (build_body(&ctx) < 0)
-+ goto out_err;
-+ /*
-+ * Second pass computes instruction offsets.
-+ * If any PC-relative branches are out of range, a sequence of
-+ * a PC-relative branch + a jump is generated, and we have to
-+ * try again from the beginning to generate the new offsets.
-+ * This is done until no additional conversions are necessary.
-+ * The last two iterations are done with all branches being
-+ * converted, to guarantee offset table convergence within a
-+ * fixed number of iterations.
-+ */
-+ ctx.jit_index = 0;
-+ build_prologue(&ctx);
-+ tmp_idx = ctx.jit_index;
-+
-+ tries = JIT_MAX_ITERATIONS;
-+ do {
-+ ctx.jit_index = tmp_idx;
-+ ctx.changes = 0;
-+ if (tries == 2)
-+ set_convert_flag(&ctx, true);
-+ if (build_body(&ctx) < 0)
-+ goto out_err;
-+ } while (ctx.changes > 0 && --tries > 0);
-+
-+ if (WARN_ONCE(ctx.changes > 0, "JIT offsets failed to converge"))
-+ goto out_err;
-+
-+ build_epilogue(&ctx, MIPS_R_RA);
-+
-+ /* Now we know the size of the structure to make */
-+ image_size = sizeof(u32) * ctx.jit_index;
-+ header = bpf_jit_binary_alloc(image_size, &image_ptr,
-+ sizeof(u32), jit_fill_hole);
-+ /*
-+ * Not able to allocate memory for the structure then
-+ * we must fall back to the interpretation
-+ */
-+ if (header == NULL)
-+ goto out_err;
-+
-+ /* Actual pass to generate final JIT code */
-+ ctx.target = (u32 *)image_ptr;
-+ ctx.jit_index = 0;
-+
-+ /*
-+ * If building the JITed code fails somehow,
-+ * we fall back to the interpretation.
-+ */
-+ build_prologue(&ctx);
-+ if (build_body(&ctx) < 0)
-+ goto out_err;
-+ build_epilogue(&ctx, MIPS_R_RA);
-+
-+ /* Populate line info meta data */
-+ set_convert_flag(&ctx, false);
-+ bpf_prog_fill_jited_linfo(prog, &ctx.descriptors[1]);
-+
-+ /* Set as read-only exec and flush instruction cache */
-+ bpf_jit_binary_lock_ro(header);
-+ flush_icache_range((unsigned long)header,
-+ (unsigned long)&ctx.target[ctx.jit_index]);
-+
-+ if (bpf_jit_enable > 1)
-+ bpf_jit_dump(prog->len, image_size, 2, ctx.target);
-+
-+ prog->bpf_func = (void *)ctx.target;
-+ prog->jited = 1;
-+ prog->jited_len = image_size;
-+
-+out:
-+ if (tmp_blinded)
-+ bpf_jit_prog_release_other(prog, prog == orig_prog ?
-+ tmp : orig_prog);
-+ kfree(ctx.descriptors);
-+ return prog;
-+
-+out_err:
-+ prog = orig_prog;
-+ if (header)
-+ bpf_jit_binary_free(header);
-+ goto out;
-+}
---- /dev/null
-+++ b/arch/mips/net/bpf_jit_comp.h
-@@ -0,0 +1,211 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Just-In-Time compiler for eBPF bytecode on 32-bit and 64-bit MIPS.
-+ *
-+ * Copyright (c) 2021 Anyfi Networks AB.
-+ * Author: Johan Almbladh <johan.almbladh@gmail.com>
-+ *
-+ * Based on code and ideas from
-+ * Copyright (c) 2017 Cavium, Inc.
-+ * Copyright (c) 2017 Shubham Bansal <illusionist.neo@gmail.com>
-+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
-+ */
-+
-+#ifndef _BPF_JIT_COMP_H
-+#define _BPF_JIT_COMP_H
-+
-+/* MIPS registers */
-+#define MIPS_R_ZERO 0 /* Const zero */
-+#define MIPS_R_AT 1 /* Asm temp */
-+#define MIPS_R_V0 2 /* Result */
-+#define MIPS_R_V1 3 /* Result */
-+#define MIPS_R_A0 4 /* Argument */
-+#define MIPS_R_A1 5 /* Argument */
-+#define MIPS_R_A2 6 /* Argument */
-+#define MIPS_R_A3 7 /* Argument */
-+#define MIPS_R_A4 8 /* Arg (n64) */
-+#define MIPS_R_A5 9 /* Arg (n64) */
-+#define MIPS_R_A6 10 /* Arg (n64) */
-+#define MIPS_R_A7 11 /* Arg (n64) */
-+#define MIPS_R_T0 8 /* Temp (o32) */
-+#define MIPS_R_T1 9 /* Temp (o32) */
-+#define MIPS_R_T2 10 /* Temp (o32) */
-+#define MIPS_R_T3 11 /* Temp (o32) */
-+#define MIPS_R_T4 12 /* Temporary */
-+#define MIPS_R_T5 13 /* Temporary */
-+#define MIPS_R_T6 14 /* Temporary */
-+#define MIPS_R_T7 15 /* Temporary */
-+#define MIPS_R_S0 16 /* Saved */
-+#define MIPS_R_S1 17 /* Saved */
-+#define MIPS_R_S2 18 /* Saved */
-+#define MIPS_R_S3 19 /* Saved */
-+#define MIPS_R_S4 20 /* Saved */
-+#define MIPS_R_S5 21 /* Saved */
-+#define MIPS_R_S6 22 /* Saved */
-+#define MIPS_R_S7 23 /* Saved */
-+#define MIPS_R_T8 24 /* Temporary */
-+#define MIPS_R_T9 25 /* Temporary */
-+/* MIPS_R_K0 26 Reserved */
-+/* MIPS_R_K1 27 Reserved */
-+#define MIPS_R_GP 28 /* Global ptr */
-+#define MIPS_R_SP 29 /* Stack ptr */
-+#define MIPS_R_FP 30 /* Frame ptr */
-+#define MIPS_R_RA 31 /* Return */
-+
-+/*
-+ * Jump address mask for immediate jumps. The four most significant bits
-+ * must be equal to PC.
-+ */
-+#define MIPS_JMP_MASK 0x0fffffffUL
-+
-+/* Maximum number of iterations in offset table computation */
-+#define JIT_MAX_ITERATIONS 8
-+
-+/*
-+ * Jump pseudo-instructions used internally
-+ * for branch conversion and branch optimization.
-+ */
-+#define JIT_JNSET 0xe0
-+#define JIT_JNOP 0xf0
-+
-+/* Descriptor flag for PC-relative branch conversion */
-+#define JIT_DESC_CONVERT BIT(31)
-+
-+/* JIT context for an eBPF program */
-+struct jit_context {
-+ struct bpf_prog *program; /* The eBPF program being JITed */
-+ u32 *descriptors; /* eBPF to JITed CPU insn descriptors */
-+ u32 *target; /* JITed code buffer */
-+ u32 bpf_index; /* Index of current BPF program insn */
-+ u32 jit_index; /* Index of current JIT target insn */
-+ u32 changes; /* Number of PC-relative branch conv */
-+ u32 accessed; /* Bit mask of read eBPF registers */
-+ u32 clobbered; /* Bit mask of modified CPU registers */
-+ u32 stack_size; /* Total allocated stack size in bytes */
-+ u32 saved_size; /* Size of callee-saved registers */
-+ u32 stack_used; /* Stack size used for function calls */
-+};
-+
-+/* Emit the instruction if the JIT memory space has been allocated */
-+#define emit(ctx, func, ...) \
-+do { \
-+ if ((ctx)->target != NULL) { \
-+ u32 *p = &(ctx)->target[ctx->jit_index]; \
-+ uasm_i_##func(&p, ##__VA_ARGS__); \
-+ } \
-+ (ctx)->jit_index++; \
-+} while (0)
-+
-+/*
-+ * Mark a BPF register as accessed, it needs to be
-+ * initialized by the program if expected, e.g. FP.
-+ */
-+static inline void access_reg(struct jit_context *ctx, u8 reg)
-+{
-+ ctx->accessed |= BIT(reg);
-+}
-+
-+/*
-+ * Mark a CPU register as clobbered, it needs to be
-+ * saved/restored by the program if callee-saved.
-+ */
-+static inline void clobber_reg(struct jit_context *ctx, u8 reg)
-+{
-+ ctx->clobbered |= BIT(reg);
-+}
-+
-+/*
-+ * Push registers on the stack, starting at a given depth from the stack
-+ * pointer and increasing. The next depth to be written is returned.
-+ */
-+int push_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth);
-+
-+/*
-+ * Pop registers from the stack, starting at a given depth from the stack
-+ * pointer and increasing. The next depth to be read is returned.
-+ */
-+int pop_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth);
-+
-+/* Compute the 28-bit jump target address from a BPF program location */
-+int get_target(struct jit_context *ctx, u32 loc);
-+
-+/* Compute the PC-relative offset to relative BPF program offset */
-+int get_offset(const struct jit_context *ctx, int off);
-+
-+/* dst = imm (32-bit) */
-+void emit_mov_i(struct jit_context *ctx, u8 dst, s32 imm);
-+
-+/* dst = src (32-bit) */
-+void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src);
-+
-+/* Validate ALU/ALU64 immediate range */
-+bool valid_alu_i(u8 op, s32 imm);
-+
-+/* Rewrite ALU/ALU64 immediate operation */
-+bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val);
-+
-+/* ALU immediate operation (32-bit) */
-+void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op);
-+
-+/* ALU register operation (32-bit) */
-+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op);
-+
-+/* Atomic read-modify-write (32-bit) */
-+void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code);
-+
-+/* Atomic compare-and-exchange (32-bit) */
-+void emit_cmpxchg_r(struct jit_context *ctx, u8 dst, u8 src, u8 res, s16 off);
-+
-+/* Swap bytes and truncate a register word or half word */
-+void emit_bswap_r(struct jit_context *ctx, u8 dst, u32 width);
-+
-+/* Validate JMP/JMP32 immediate range */
-+bool valid_jmp_i(u8 op, s32 imm);
-+
-+/* Prepare a PC-relative jump operation with immediate conditional */
-+void setup_jmp_i(struct jit_context *ctx, s32 imm, u8 width,
-+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off);
-+
-+/* Prepare a PC-relative jump operation with register conditional */
-+void setup_jmp_r(struct jit_context *ctx, bool same_reg,
-+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off);
-+
-+/* Finish a PC-relative jump operation */
-+int finish_jmp(struct jit_context *ctx, u8 jit_op, s16 bpf_off);
-+
-+/* Conditional JMP/JMP32 immediate */
-+void emit_jmp_i(struct jit_context *ctx, u8 dst, s32 imm, s32 off, u8 op);
-+
-+/* Conditional JMP/JMP32 register */
-+void emit_jmp_r(struct jit_context *ctx, u8 dst, u8 src, s32 off, u8 op);
-+
-+/* Jump always */
-+int emit_ja(struct jit_context *ctx, s16 off);
-+
-+/* Jump to epilogue */
-+int emit_exit(struct jit_context *ctx);
-+
-+/*
-+ * Build program prologue to set up the stack and registers.
-+ * This function is implemented separately for 32-bit and 64-bit JITs.
-+ */
-+void build_prologue(struct jit_context *ctx);
-+
-+/*
-+ * Build the program epilogue to restore the stack and registers.
-+ * This function is implemented separately for 32-bit and 64-bit JITs.
-+ */
-+void build_epilogue(struct jit_context *ctx, int dest_reg);
-+
-+/*
-+ * Convert an eBPF instruction to native instruction, i.e
-+ * JITs an eBPF instruction.
-+ * Returns :
-+ * 0 - Successfully JITed an 8-byte eBPF instruction
-+ * >0 - Successfully JITed a 16-byte eBPF instruction
-+ * <0 - Failed to JIT.
-+ * This function is implemented separately for 32-bit and 64-bit JITs.
-+ */
-+int build_insn(const struct bpf_insn *insn, struct jit_context *ctx);
-+
-+#endif /* _BPF_JIT_COMP_H */
---- /dev/null
-+++ b/arch/mips/net/bpf_jit_comp32.c
-@@ -0,0 +1,1741 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Just-In-Time compiler for eBPF bytecode on MIPS.
-+ * Implementation of JIT functions for 32-bit CPUs.
-+ *
-+ * Copyright (c) 2021 Anyfi Networks AB.
-+ * Author: Johan Almbladh <johan.almbladh@gmail.com>
-+ *
-+ * Based on code and ideas from
-+ * Copyright (c) 2017 Cavium, Inc.
-+ * Copyright (c) 2017 Shubham Bansal <illusionist.neo@gmail.com>
-+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
-+ */
-+
-+#include <linux/math64.h>
-+#include <linux/errno.h>
-+#include <linux/filter.h>
-+#include <linux/bpf.h>
-+#include <asm/cpu-features.h>
-+#include <asm/isa-rev.h>
-+#include <asm/uasm.h>
-+
-+#include "bpf_jit_comp.h"
-+
-+/* MIPS a4-a7 are not available in the o32 ABI */
-+#undef MIPS_R_A4
-+#undef MIPS_R_A5
-+#undef MIPS_R_A6
-+#undef MIPS_R_A7
-+
-+/* Stack is 8-byte aligned in o32 ABI */
-+#define MIPS_STACK_ALIGNMENT 8
-+
-+/*
-+ * The top 16 bytes of a stack frame is reserved for the callee in O32 ABI.
-+ * This corresponds to stack space for register arguments a0-a3.
-+ */
-+#define JIT_RESERVED_STACK 16
-+
-+/* Temporary 64-bit register used by JIT */
-+#define JIT_REG_TMP MAX_BPF_JIT_REG
-+
-+/*
-+ * Number of prologue bytes to skip when doing a tail call.
-+ * Tail call count (TCC) initialization (8 bytes) always, plus
-+ * R0-to-v0 assignment (4 bytes) if big endian.
-+ */
-+#ifdef __BIG_ENDIAN
-+#define JIT_TCALL_SKIP 12
-+#else
-+#define JIT_TCALL_SKIP 8
-+#endif
-+
-+/* CPU registers holding the callee return value */
-+#define JIT_RETURN_REGS \
-+ (BIT(MIPS_R_V0) | \
-+ BIT(MIPS_R_V1))
-+
-+/* CPU registers arguments passed to callee directly */
-+#define JIT_ARG_REGS \
-+ (BIT(MIPS_R_A0) | \
-+ BIT(MIPS_R_A1) | \
-+ BIT(MIPS_R_A2) | \
-+ BIT(MIPS_R_A3))
-+
-+/* CPU register arguments passed to callee on stack */
-+#define JIT_STACK_REGS \
-+ (BIT(MIPS_R_T0) | \
-+ BIT(MIPS_R_T1) | \
-+ BIT(MIPS_R_T2) | \
-+ BIT(MIPS_R_T3) | \
-+ BIT(MIPS_R_T4) | \
-+ BIT(MIPS_R_T5))
-+
-+/* Caller-saved CPU registers */
-+#define JIT_CALLER_REGS \
-+ (JIT_RETURN_REGS | \
-+ JIT_ARG_REGS | \
-+ JIT_STACK_REGS)
-+
-+/* Callee-saved CPU registers */
-+#define JIT_CALLEE_REGS \
-+ (BIT(MIPS_R_S0) | \
-+ BIT(MIPS_R_S1) | \
-+ BIT(MIPS_R_S2) | \
-+ BIT(MIPS_R_S3) | \
-+ BIT(MIPS_R_S4) | \
-+ BIT(MIPS_R_S5) | \
-+ BIT(MIPS_R_S6) | \
-+ BIT(MIPS_R_S7) | \
-+ BIT(MIPS_R_GP) | \
-+ BIT(MIPS_R_FP) | \
-+ BIT(MIPS_R_RA))
-+
-+/*
-+ * Mapping of 64-bit eBPF registers to 32-bit native MIPS registers.
-+ *
-+ * 1) Native register pairs are ordered according to CPU endiannes, following
-+ * the MIPS convention for passing 64-bit arguments and return values.
-+ * 2) The eBPF return value, arguments and callee-saved registers are mapped
-+ * to their native MIPS equivalents.
-+ * 3) Since the 32 highest bits in the eBPF FP register are always zero,
-+ * only one general-purpose register is actually needed for the mapping.
-+ * We use the fp register for this purpose, and map the highest bits to
-+ * the MIPS register r0 (zero).
-+ * 4) We use the MIPS gp and at registers as internal temporary registers
-+ * for constant blinding. The gp register is callee-saved.
-+ * 5) One 64-bit temporary register is mapped for use when sign-extending
-+ * immediate operands. MIPS registers t6-t9 are available to the JIT
-+ * for as temporaries when implementing complex 64-bit operations.
-+ *
-+ * With this scheme all eBPF registers are being mapped to native MIPS
-+ * registers without having to use any stack scratch space. The direct
-+ * register mapping (2) simplifies the handling of function calls.
-+ */
-+static const u8 bpf2mips32[][2] = {
-+ /* Return value from in-kernel function, and exit value from eBPF */
-+ [BPF_REG_0] = {MIPS_R_V1, MIPS_R_V0},
-+ /* Arguments from eBPF program to in-kernel function */
-+ [BPF_REG_1] = {MIPS_R_A1, MIPS_R_A0},
-+ [BPF_REG_2] = {MIPS_R_A3, MIPS_R_A2},
-+ /* Remaining arguments, to be passed on the stack per O32 ABI */
-+ [BPF_REG_3] = {MIPS_R_T1, MIPS_R_T0},
-+ [BPF_REG_4] = {MIPS_R_T3, MIPS_R_T2},
-+ [BPF_REG_5] = {MIPS_R_T5, MIPS_R_T4},
-+ /* Callee-saved registers that in-kernel function will preserve */
-+ [BPF_REG_6] = {MIPS_R_S1, MIPS_R_S0},
-+ [BPF_REG_7] = {MIPS_R_S3, MIPS_R_S2},
-+ [BPF_REG_8] = {MIPS_R_S5, MIPS_R_S4},
-+ [BPF_REG_9] = {MIPS_R_S7, MIPS_R_S6},
-+ /* Read-only frame pointer to access the eBPF stack */
-+#ifdef __BIG_ENDIAN
-+ [BPF_REG_FP] = {MIPS_R_FP, MIPS_R_ZERO},
-+#else
-+ [BPF_REG_FP] = {MIPS_R_ZERO, MIPS_R_FP},
-+#endif
-+ /* Temporary register for blinding constants */
-+ [BPF_REG_AX] = {MIPS_R_GP, MIPS_R_AT},
-+ /* Temporary register for internal JIT use */
-+ [JIT_REG_TMP] = {MIPS_R_T7, MIPS_R_T6},
-+};
-+
-+/* Get low CPU register for a 64-bit eBPF register mapping */
-+static inline u8 lo(const u8 reg[])
-+{
-+#ifdef __BIG_ENDIAN
-+ return reg[0];
-+#else
-+ return reg[1];
-+#endif
-+}
-+
-+/* Get high CPU register for a 64-bit eBPF register mapping */
-+static inline u8 hi(const u8 reg[])
-+{
-+#ifdef __BIG_ENDIAN
-+ return reg[1];
-+#else
-+ return reg[0];
-+#endif
-+}
-+
-+/*
-+ * Mark a 64-bit CPU register pair as clobbered, it needs to be
-+ * saved/restored by the program if callee-saved.
-+ */
-+static void clobber_reg64(struct jit_context *ctx, const u8 reg[])
-+{
-+ clobber_reg(ctx, reg[0]);
-+ clobber_reg(ctx, reg[1]);
-+}
-+
-+/* dst = imm (sign-extended) */
-+static void emit_mov_se_i64(struct jit_context *ctx, const u8 dst[], s32 imm)
-+{
-+ emit_mov_i(ctx, lo(dst), imm);
-+ if (imm < 0)
-+ emit(ctx, addiu, hi(dst), MIPS_R_ZERO, -1);
-+ else
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* Zero extension, if verifier does not do it for us */
-+static void emit_zext_ver(struct jit_context *ctx, const u8 dst[])
-+{
-+ if (!ctx->program->aux->verifier_zext) {
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ clobber_reg(ctx, hi(dst));
-+ }
-+}
-+
-+/* Load delay slot, if ISA mandates it */
-+static void emit_load_delay(struct jit_context *ctx)
-+{
-+ if (!cpu_has_mips_2_3_4_5_r)
-+ emit(ctx, nop);
-+}
-+
-+/* ALU immediate operation (64-bit) */
-+static void emit_alu_i64(struct jit_context *ctx,
-+ const u8 dst[], s32 imm, u8 op)
-+{
-+ u8 src = MIPS_R_T6;
-+
-+ /*
-+ * ADD/SUB with all but the max negative imm can be handled by
-+ * inverting the operation and the imm value, saving one insn.
-+ */
-+ if (imm > S32_MIN && imm < 0)
-+ switch (op) {
-+ case BPF_ADD:
-+ op = BPF_SUB;
-+ imm = -imm;
-+ break;
-+ case BPF_SUB:
-+ op = BPF_ADD;
-+ imm = -imm;
-+ break;
-+ }
-+
-+ /* Move immediate to temporary register */
-+ emit_mov_i(ctx, src, imm);
-+
-+ switch (op) {
-+ /* dst = dst + imm */
-+ case BPF_ADD:
-+ emit(ctx, addu, lo(dst), lo(dst), src);
-+ emit(ctx, sltu, MIPS_R_T9, lo(dst), src);
-+ emit(ctx, addu, hi(dst), hi(dst), MIPS_R_T9);
-+ if (imm < 0)
-+ emit(ctx, addiu, hi(dst), hi(dst), -1);
-+ break;
-+ /* dst = dst - imm */
-+ case BPF_SUB:
-+ emit(ctx, sltu, MIPS_R_T9, lo(dst), src);
-+ emit(ctx, subu, lo(dst), lo(dst), src);
-+ emit(ctx, subu, hi(dst), hi(dst), MIPS_R_T9);
-+ if (imm < 0)
-+ emit(ctx, addiu, hi(dst), hi(dst), 1);
-+ break;
-+ /* dst = dst | imm */
-+ case BPF_OR:
-+ emit(ctx, or, lo(dst), lo(dst), src);
-+ if (imm < 0)
-+ emit(ctx, addiu, hi(dst), MIPS_R_ZERO, -1);
-+ break;
-+ /* dst = dst & imm */
-+ case BPF_AND:
-+ emit(ctx, and, lo(dst), lo(dst), src);
-+ if (imm >= 0)
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ break;
-+ /* dst = dst ^ imm */
-+ case BPF_XOR:
-+ emit(ctx, xor, lo(dst), lo(dst), src);
-+ if (imm < 0) {
-+ emit(ctx, subu, hi(dst), MIPS_R_ZERO, hi(dst));
-+ emit(ctx, addiu, hi(dst), hi(dst), -1);
-+ }
-+ break;
-+ }
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* ALU register operation (64-bit) */
-+static void emit_alu_r64(struct jit_context *ctx,
-+ const u8 dst[], const u8 src[], u8 op)
-+{
-+ switch (BPF_OP(op)) {
-+ /* dst = dst + src */
-+ case BPF_ADD:
-+ if (src == dst) {
-+ emit(ctx, srl, MIPS_R_T9, lo(dst), 31);
-+ emit(ctx, addu, lo(dst), lo(dst), lo(dst));
-+ } else {
-+ emit(ctx, addu, lo(dst), lo(dst), lo(src));
-+ emit(ctx, sltu, MIPS_R_T9, lo(dst), lo(src));
-+ }
-+ emit(ctx, addu, hi(dst), hi(dst), hi(src));
-+ emit(ctx, addu, hi(dst), hi(dst), MIPS_R_T9);
-+ break;
-+ /* dst = dst - src */
-+ case BPF_SUB:
-+ emit(ctx, sltu, MIPS_R_T9, lo(dst), lo(src));
-+ emit(ctx, subu, lo(dst), lo(dst), lo(src));
-+ emit(ctx, subu, hi(dst), hi(dst), hi(src));
-+ emit(ctx, subu, hi(dst), hi(dst), MIPS_R_T9);
-+ break;
-+ /* dst = dst | src */
-+ case BPF_OR:
-+ emit(ctx, or, lo(dst), lo(dst), lo(src));
-+ emit(ctx, or, hi(dst), hi(dst), hi(src));
-+ break;
-+ /* dst = dst & src */
-+ case BPF_AND:
-+ emit(ctx, and, lo(dst), lo(dst), lo(src));
-+ emit(ctx, and, hi(dst), hi(dst), hi(src));
-+ break;
-+ /* dst = dst ^ src */
-+ case BPF_XOR:
-+ emit(ctx, xor, lo(dst), lo(dst), lo(src));
-+ emit(ctx, xor, hi(dst), hi(dst), hi(src));
-+ break;
-+ }
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* ALU invert (64-bit) */
-+static void emit_neg_i64(struct jit_context *ctx, const u8 dst[])
-+{
-+ emit(ctx, sltu, MIPS_R_T9, MIPS_R_ZERO, lo(dst));
-+ emit(ctx, subu, lo(dst), MIPS_R_ZERO, lo(dst));
-+ emit(ctx, subu, hi(dst), MIPS_R_ZERO, hi(dst));
-+ emit(ctx, subu, hi(dst), hi(dst), MIPS_R_T9);
-+
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* ALU shift immediate (64-bit) */
-+static void emit_shift_i64(struct jit_context *ctx,
-+ const u8 dst[], u32 imm, u8 op)
-+{
-+ switch (BPF_OP(op)) {
-+ /* dst = dst << imm */
-+ case BPF_LSH:
-+ if (imm < 32) {
-+ emit(ctx, srl, MIPS_R_T9, lo(dst), 32 - imm);
-+ emit(ctx, sll, lo(dst), lo(dst), imm);
-+ emit(ctx, sll, hi(dst), hi(dst), imm);
-+ emit(ctx, or, hi(dst), hi(dst), MIPS_R_T9);
-+ } else {
-+ emit(ctx, sll, hi(dst), lo(dst), imm - 32);
-+ emit(ctx, move, lo(dst), MIPS_R_ZERO);
-+ }
-+ break;
-+ /* dst = dst >> imm */
-+ case BPF_RSH:
-+ if (imm < 32) {
-+ emit(ctx, sll, MIPS_R_T9, hi(dst), 32 - imm);
-+ emit(ctx, srl, lo(dst), lo(dst), imm);
-+ emit(ctx, srl, hi(dst), hi(dst), imm);
-+ emit(ctx, or, lo(dst), lo(dst), MIPS_R_T9);
-+ } else {
-+ emit(ctx, srl, lo(dst), hi(dst), imm - 32);
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ }
-+ break;
-+ /* dst = dst >> imm (arithmetic) */
-+ case BPF_ARSH:
-+ if (imm < 32) {
-+ emit(ctx, sll, MIPS_R_T9, hi(dst), 32 - imm);
-+ emit(ctx, srl, lo(dst), lo(dst), imm);
-+ emit(ctx, sra, hi(dst), hi(dst), imm);
-+ emit(ctx, or, lo(dst), lo(dst), MIPS_R_T9);
-+ } else {
-+ emit(ctx, sra, lo(dst), hi(dst), imm - 32);
-+ emit(ctx, sra, hi(dst), hi(dst), 31);
-+ }
-+ break;
-+ }
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* ALU shift register (64-bit) */
-+static void emit_shift_r64(struct jit_context *ctx,
-+ const u8 dst[], u8 src, u8 op)
-+{
-+ u8 t1 = MIPS_R_T8;
-+ u8 t2 = MIPS_R_T9;
-+
-+ emit(ctx, andi, t1, src, 32); /* t1 = src & 32 */
-+ emit(ctx, beqz, t1, 16); /* PC += 16 if t1 == 0 */
-+ emit(ctx, nor, t2, src, MIPS_R_ZERO); /* t2 = ~src (delay slot) */
-+
-+ switch (BPF_OP(op)) {
-+ /* dst = dst << src */
-+ case BPF_LSH:
-+ /* Next: shift >= 32 */
-+ emit(ctx, sllv, hi(dst), lo(dst), src); /* dh = dl << src */
-+ emit(ctx, move, lo(dst), MIPS_R_ZERO); /* dl = 0 */
-+ emit(ctx, b, 20); /* PC += 20 */
-+ /* +16: shift < 32 */
-+ emit(ctx, srl, t1, lo(dst), 1); /* t1 = dl >> 1 */
-+ emit(ctx, srlv, t1, t1, t2); /* t1 = t1 >> t2 */
-+ emit(ctx, sllv, lo(dst), lo(dst), src); /* dl = dl << src */
-+ emit(ctx, sllv, hi(dst), hi(dst), src); /* dh = dh << src */
-+ emit(ctx, or, hi(dst), hi(dst), t1); /* dh = dh | t1 */
-+ break;
-+ /* dst = dst >> src */
-+ case BPF_RSH:
-+ /* Next: shift >= 32 */
-+ emit(ctx, srlv, lo(dst), hi(dst), src); /* dl = dh >> src */
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO); /* dh = 0 */
-+ emit(ctx, b, 20); /* PC += 20 */
-+ /* +16: shift < 32 */
-+ emit(ctx, sll, t1, hi(dst), 1); /* t1 = dl << 1 */
-+ emit(ctx, sllv, t1, t1, t2); /* t1 = t1 << t2 */
-+ emit(ctx, srlv, lo(dst), lo(dst), src); /* dl = dl >> src */
-+ emit(ctx, srlv, hi(dst), hi(dst), src); /* dh = dh >> src */
-+ emit(ctx, or, lo(dst), lo(dst), t1); /* dl = dl | t1 */
-+ break;
-+ /* dst = dst >> src (arithmetic) */
-+ case BPF_ARSH:
-+ /* Next: shift >= 32 */
-+ emit(ctx, srav, lo(dst), hi(dst), src); /* dl = dh >>a src */
-+ emit(ctx, sra, hi(dst), hi(dst), 31); /* dh = dh >>a 31 */
-+ emit(ctx, b, 20); /* PC += 20 */
-+ /* +16: shift < 32 */
-+ emit(ctx, sll, t1, hi(dst), 1); /* t1 = dl << 1 */
-+ emit(ctx, sllv, t1, t1, t2); /* t1 = t1 << t2 */
-+ emit(ctx, srlv, lo(dst), lo(dst), src); /* dl = dl >>a src */
-+ emit(ctx, srav, hi(dst), hi(dst), src); /* dh = dh >> src */
-+ emit(ctx, or, lo(dst), lo(dst), t1); /* dl = dl | t1 */
-+ break;
-+ }
-+
-+ /* +20: Done */
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* ALU mul immediate (64x32-bit) */
-+static void emit_mul_i64(struct jit_context *ctx, const u8 dst[], s32 imm)
-+{
-+ u8 src = MIPS_R_T6;
-+ u8 tmp = MIPS_R_T9;
-+
-+ switch (imm) {
-+ /* dst = dst * 1 is a no-op */
-+ case 1:
-+ break;
-+ /* dst = dst * -1 */
-+ case -1:
-+ emit_neg_i64(ctx, dst);
-+ break;
-+ case 0:
-+ emit_mov_r(ctx, lo(dst), MIPS_R_ZERO);
-+ emit_mov_r(ctx, hi(dst), MIPS_R_ZERO);
-+ break;
-+ /* Full 64x32 multiply */
-+ default:
-+ /* hi(dst) = hi(dst) * src(imm) */
-+ emit_mov_i(ctx, src, imm);
-+ if (cpu_has_mips32r1 || cpu_has_mips32r6) {
-+ emit(ctx, mul, hi(dst), hi(dst), src);
-+ } else {
-+ emit(ctx, multu, hi(dst), src);
-+ emit(ctx, mflo, hi(dst));
-+ }
-+
-+ /* hi(dst) = hi(dst) - lo(dst) */
-+ if (imm < 0)
-+ emit(ctx, subu, hi(dst), hi(dst), lo(dst));
-+
-+ /* tmp = lo(dst) * src(imm) >> 32 */
-+ /* lo(dst) = lo(dst) * src(imm) */
-+ if (cpu_has_mips32r6) {
-+ emit(ctx, muhu, tmp, lo(dst), src);
-+ emit(ctx, mulu, lo(dst), lo(dst), src);
-+ } else {
-+ emit(ctx, multu, lo(dst), src);
-+ emit(ctx, mflo, lo(dst));
-+ emit(ctx, mfhi, tmp);
-+ }
-+
-+ /* hi(dst) += tmp */
-+ emit(ctx, addu, hi(dst), hi(dst), tmp);
-+ clobber_reg64(ctx, dst);
-+ break;
-+ }
-+}
-+
-+/* ALU mul register (64x64-bit) */
-+static void emit_mul_r64(struct jit_context *ctx,
-+ const u8 dst[], const u8 src[])
-+{
-+ u8 acc = MIPS_R_T8;
-+ u8 tmp = MIPS_R_T9;
-+
-+ /* acc = hi(dst) * lo(src) */
-+ if (cpu_has_mips32r1 || cpu_has_mips32r6) {
-+ emit(ctx, mul, acc, hi(dst), lo(src));
-+ } else {
-+ emit(ctx, multu, hi(dst), lo(src));
-+ emit(ctx, mflo, acc);
-+ }
-+
-+ /* tmp = lo(dst) * hi(src) */
-+ if (cpu_has_mips32r1 || cpu_has_mips32r6) {
-+ emit(ctx, mul, tmp, lo(dst), hi(src));
-+ } else {
-+ emit(ctx, multu, lo(dst), hi(src));
-+ emit(ctx, mflo, tmp);
-+ }
-+
-+ /* acc += tmp */
-+ emit(ctx, addu, acc, acc, tmp);
-+
-+ /* tmp = lo(dst) * lo(src) >> 32 */
-+ /* lo(dst) = lo(dst) * lo(src) */
-+ if (cpu_has_mips32r6) {
-+ emit(ctx, muhu, tmp, lo(dst), lo(src));
-+ emit(ctx, mulu, lo(dst), lo(dst), lo(src));
-+ } else {
-+ emit(ctx, multu, lo(dst), lo(src));
-+ emit(ctx, mflo, lo(dst));
-+ emit(ctx, mfhi, tmp);
-+ }
-+
-+ /* hi(dst) = acc + tmp */
-+ emit(ctx, addu, hi(dst), acc, tmp);
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* Helper function for 64-bit modulo */
-+static u64 jit_mod64(u64 a, u64 b)
-+{
-+ u64 rem;
-+
-+ div64_u64_rem(a, b, &rem);
-+ return rem;
-+}
-+
-+/* ALU div/mod register (64-bit) */
-+static void emit_divmod_r64(struct jit_context *ctx,
-+ const u8 dst[], const u8 src[], u8 op)
-+{
-+ const u8 *r0 = bpf2mips32[BPF_REG_0]; /* Mapped to v0-v1 */
-+ const u8 *r1 = bpf2mips32[BPF_REG_1]; /* Mapped to a0-a1 */
-+ const u8 *r2 = bpf2mips32[BPF_REG_2]; /* Mapped to a2-a3 */
-+ int exclude, k;
-+ u32 addr = 0;
-+
-+ /* Push caller-saved registers on stack */
-+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS,
-+ 0, JIT_RESERVED_STACK);
-+
-+ /* Put 64-bit arguments 1 and 2 in registers a0-a3 */
-+ for (k = 0; k < 2; k++) {
-+ emit(ctx, move, MIPS_R_T9, src[k]);
-+ emit(ctx, move, r1[k], dst[k]);
-+ emit(ctx, move, r2[k], MIPS_R_T9);
-+ }
-+
-+ /* Emit function call */
-+ switch (BPF_OP(op)) {
-+ /* dst = dst / src */
-+ case BPF_DIV:
-+ addr = (u32)&div64_u64;
-+ break;
-+ /* dst = dst % src */
-+ case BPF_MOD:
-+ addr = (u32)&jit_mod64;
-+ break;
-+ }
-+ emit_mov_i(ctx, MIPS_R_T9, addr);
-+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
-+ emit(ctx, nop); /* Delay slot */
-+
-+ /* Store the 64-bit result in dst */
-+ emit(ctx, move, dst[0], r0[0]);
-+ emit(ctx, move, dst[1], r0[1]);
-+
-+ /* Restore caller-saved registers, excluding the computed result */
-+ exclude = BIT(lo(dst)) | BIT(hi(dst));
-+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS,
-+ exclude, JIT_RESERVED_STACK);
-+ emit_load_delay(ctx);
-+
-+ clobber_reg64(ctx, dst);
-+ clobber_reg(ctx, MIPS_R_V0);
-+ clobber_reg(ctx, MIPS_R_V1);
-+ clobber_reg(ctx, MIPS_R_RA);
-+}
-+
-+/* Swap bytes in a register word */
-+static void emit_swap8_r(struct jit_context *ctx, u8 dst, u8 src, u8 mask)
-+{
-+ u8 tmp = MIPS_R_T9;
-+
-+ emit(ctx, and, tmp, src, mask); /* tmp = src & 0x00ff00ff */
-+ emit(ctx, sll, tmp, tmp, 8); /* tmp = tmp << 8 */
-+ emit(ctx, srl, dst, src, 8); /* dst = src >> 8 */
-+ emit(ctx, and, dst, dst, mask); /* dst = dst & 0x00ff00ff */
-+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */
-+}
-+
-+/* Swap half words in a register word */
-+static void emit_swap16_r(struct jit_context *ctx, u8 dst, u8 src)
-+{
-+ u8 tmp = MIPS_R_T9;
-+
-+ emit(ctx, sll, tmp, src, 16); /* tmp = src << 16 */
-+ emit(ctx, srl, dst, src, 16); /* dst = src >> 16 */
-+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */
-+}
-+
-+/* Swap bytes and truncate a register double word, word or half word */
-+static void emit_bswap_r64(struct jit_context *ctx, const u8 dst[], u32 width)
-+{
-+ u8 tmp = MIPS_R_T8;
-+
-+ switch (width) {
-+ /* Swap bytes in a double word */
-+ case 64:
-+ if (cpu_has_mips32r2 || cpu_has_mips32r6) {
-+ emit(ctx, rotr, tmp, hi(dst), 16);
-+ emit(ctx, rotr, hi(dst), lo(dst), 16);
-+ emit(ctx, wsbh, lo(dst), tmp);
-+ emit(ctx, wsbh, hi(dst), hi(dst));
-+ } else {
-+ emit_swap16_r(ctx, tmp, lo(dst));
-+ emit_swap16_r(ctx, lo(dst), hi(dst));
-+ emit(ctx, move, hi(dst), tmp);
-+
-+ emit(ctx, lui, tmp, 0xff); /* tmp = 0x00ff0000 */
-+ emit(ctx, ori, tmp, tmp, 0xff); /* tmp = 0x00ff00ff */
-+ emit_swap8_r(ctx, lo(dst), lo(dst), tmp);
-+ emit_swap8_r(ctx, hi(dst), hi(dst), tmp);
-+ }
-+ break;
-+ /* Swap bytes in a word */
-+ /* Swap bytes in a half word */
-+ case 32:
-+ case 16:
-+ emit_bswap_r(ctx, lo(dst), width);
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ break;
-+ }
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* Truncate a register double word, word or half word */
-+static void emit_trunc_r64(struct jit_context *ctx, const u8 dst[], u32 width)
-+{
-+ switch (width) {
-+ case 64:
-+ break;
-+ /* Zero-extend a word */
-+ case 32:
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ clobber_reg(ctx, hi(dst));
-+ break;
-+ /* Zero-extend a half word */
-+ case 16:
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ emit(ctx, andi, lo(dst), lo(dst), 0xffff);
-+ clobber_reg64(ctx, dst);
-+ break;
-+ }
-+}
-+
-+/* Load operation: dst = *(size*)(src + off) */
-+static void emit_ldx(struct jit_context *ctx,
-+ const u8 dst[], u8 src, s16 off, u8 size)
-+{
-+ switch (size) {
-+ /* Load a byte */
-+ case BPF_B:
-+ emit(ctx, lbu, lo(dst), off, src);
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ break;
-+ /* Load a half word */
-+ case BPF_H:
-+ emit(ctx, lhu, lo(dst), off, src);
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ break;
-+ /* Load a word */
-+ case BPF_W:
-+ emit(ctx, lw, lo(dst), off, src);
-+ emit(ctx, move, hi(dst), MIPS_R_ZERO);
-+ break;
-+ /* Load a double word */
-+ case BPF_DW:
-+ if (dst[1] == src) {
-+ emit(ctx, lw, dst[0], off + 4, src);
-+ emit(ctx, lw, dst[1], off, src);
-+ } else {
-+ emit(ctx, lw, dst[1], off, src);
-+ emit(ctx, lw, dst[0], off + 4, src);
-+ }
-+ emit_load_delay(ctx);
-+ break;
-+ }
-+ clobber_reg64(ctx, dst);
-+}
-+
-+/* Store operation: *(size *)(dst + off) = src */
-+static void emit_stx(struct jit_context *ctx,
-+ const u8 dst, const u8 src[], s16 off, u8 size)
-+{
-+ switch (size) {
-+ /* Store a byte */
-+ case BPF_B:
-+ emit(ctx, sb, lo(src), off, dst);
-+ break;
-+ /* Store a half word */
-+ case BPF_H:
-+ emit(ctx, sh, lo(src), off, dst);
-+ break;
-+ /* Store a word */
-+ case BPF_W:
-+ emit(ctx, sw, lo(src), off, dst);
-+ break;
-+ /* Store a double word */
-+ case BPF_DW:
-+ emit(ctx, sw, src[1], off, dst);
-+ emit(ctx, sw, src[0], off + 4, dst);
-+ break;
-+ }
-+}
-+
-+/* Atomic read-modify-write (32-bit, non-ll/sc fallback) */
-+static void emit_atomic_r32(struct jit_context *ctx,
-+ u8 dst, u8 src, s16 off, u8 code)
-+{
-+ u32 exclude = 0;
-+ u32 addr = 0;
-+
-+ /* Push caller-saved registers on stack */
-+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS,
-+ 0, JIT_RESERVED_STACK);
-+ /*
-+ * Argument 1: dst+off if xchg, otherwise src, passed in register a0
-+ * Argument 2: src if xchg, othersize dst+off, passed in register a1
-+ */
-+ emit(ctx, move, MIPS_R_T9, dst);
-+ emit(ctx, move, MIPS_R_A0, src);
-+ emit(ctx, addiu, MIPS_R_A1, MIPS_R_T9, off);
-+
-+ /* Emit function call */
-+ switch (code) {
-+ case BPF_ADD:
-+ addr = (u32)&atomic_add;
-+ break;
-+ case BPF_SUB:
-+ addr = (u32)&atomic_sub;
-+ break;
-+ case BPF_OR:
-+ addr = (u32)&atomic_or;
-+ break;
-+ case BPF_AND:
-+ addr = (u32)&atomic_and;
-+ break;
-+ case BPF_XOR:
-+ addr = (u32)&atomic_xor;
-+ break;
-+ }
-+ emit_mov_i(ctx, MIPS_R_T9, addr);
-+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
-+ emit(ctx, nop); /* Delay slot */
-+
-+ /* Restore caller-saved registers, except any fetched value */
-+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS,
-+ exclude, JIT_RESERVED_STACK);
-+ emit_load_delay(ctx);
-+ clobber_reg(ctx, MIPS_R_RA);
-+}
-+
-+/* Atomic read-modify-write (64-bit) */
-+static void emit_atomic_r64(struct jit_context *ctx,
-+ u8 dst, const u8 src[], s16 off, u8 code)
-+{
-+ const u8 *r1 = bpf2mips32[BPF_REG_1]; /* Mapped to a0-a1 */
-+ u32 exclude = 0;
-+ u32 addr = 0;
-+
-+ /* Push caller-saved registers on stack */
-+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS,
-+ 0, JIT_RESERVED_STACK);
-+ /*
-+ * Argument 1: 64-bit src, passed in registers a0-a1
-+ * Argument 2: 32-bit dst+off, passed in register a2
-+ */
-+ emit(ctx, move, MIPS_R_T9, dst);
-+ emit(ctx, move, r1[0], src[0]);
-+ emit(ctx, move, r1[1], src[1]);
-+ emit(ctx, addiu, MIPS_R_A2, MIPS_R_T9, off);
-+
-+ /* Emit function call */
-+ switch (code) {
-+ case BPF_ADD:
-+ addr = (u32)&atomic64_add;
-+ break;
-+ case BPF_SUB:
-+ addr = (u32)&atomic64_sub;
-+ break;
-+ case BPF_OR:
-+ addr = (u32)&atomic64_or;
-+ break;
-+ case BPF_AND:
-+ addr = (u32)&atomic64_and;
-+ break;
-+ case BPF_XOR:
-+ addr = (u32)&atomic64_xor;
-+ break;
-+ }
-+ emit_mov_i(ctx, MIPS_R_T9, addr);
-+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
-+ emit(ctx, nop); /* Delay slot */
-+
-+ /* Restore caller-saved registers, except any fetched value */
-+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS,
-+ exclude, JIT_RESERVED_STACK);
-+ emit_load_delay(ctx);
-+ clobber_reg(ctx, MIPS_R_RA);
-+}
-+
-+/*
-+ * Conditional movz or an emulated equivalent.
-+ * Note that the rs register may be modified.
-+ */
-+static void emit_movz_r(struct jit_context *ctx, u8 rd, u8 rs, u8 rt)
-+{
-+ if (cpu_has_mips_2) {
-+ emit(ctx, movz, rd, rs, rt); /* rd = rt ? rd : rs */
-+ } else if (cpu_has_mips32r6) {
-+ if (rs != MIPS_R_ZERO)
-+ emit(ctx, seleqz, rs, rs, rt); /* rs = 0 if rt == 0 */
-+ emit(ctx, selnez, rd, rd, rt); /* rd = 0 if rt != 0 */
-+ if (rs != MIPS_R_ZERO)
-+ emit(ctx, or, rd, rd, rs); /* rd = rd | rs */
-+ } else {
-+ emit(ctx, bnez, rt, 8); /* PC += 8 if rd != 0 */
-+ emit(ctx, nop); /* +0: delay slot */
-+ emit(ctx, or, rd, rs, MIPS_R_ZERO); /* +4: rd = rs */
-+ }
-+ clobber_reg(ctx, rd);
-+ clobber_reg(ctx, rs);
-+}
-+
-+/*
-+ * Conditional movn or an emulated equivalent.
-+ * Note that the rs register may be modified.
-+ */
-+static void emit_movn_r(struct jit_context *ctx, u8 rd, u8 rs, u8 rt)
-+{
-+ if (cpu_has_mips_2) {
-+ emit(ctx, movn, rd, rs, rt); /* rd = rt ? rs : rd */
-+ } else if (cpu_has_mips32r6) {
-+ if (rs != MIPS_R_ZERO)
-+ emit(ctx, selnez, rs, rs, rt); /* rs = 0 if rt == 0 */
-+ emit(ctx, seleqz, rd, rd, rt); /* rd = 0 if rt != 0 */
-+ if (rs != MIPS_R_ZERO)
-+ emit(ctx, or, rd, rd, rs); /* rd = rd | rs */
-+ } else {
-+ emit(ctx, beqz, rt, 8); /* PC += 8 if rd == 0 */
-+ emit(ctx, nop); /* +0: delay slot */
-+ emit(ctx, or, rd, rs, MIPS_R_ZERO); /* +4: rd = rs */
-+ }
-+ clobber_reg(ctx, rd);
-+ clobber_reg(ctx, rs);
-+}
-+
-+/* Emulation of 64-bit sltiu rd, rs, imm, where imm may be S32_MAX + 1 */
-+static void emit_sltiu_r64(struct jit_context *ctx, u8 rd,
-+ const u8 rs[], s64 imm)
-+{
-+ u8 tmp = MIPS_R_T9;
-+
-+ if (imm < 0) {
-+ emit_mov_i(ctx, rd, imm); /* rd = imm */
-+ emit(ctx, sltu, rd, lo(rs), rd); /* rd = rsl < rd */
-+ emit(ctx, sltiu, tmp, hi(rs), -1); /* tmp = rsh < ~0U */
-+ emit(ctx, or, rd, rd, tmp); /* rd = rd | tmp */
-+ } else { /* imm >= 0 */
-+ if (imm > 0x7fff) {
-+ emit_mov_i(ctx, rd, (s32)imm); /* rd = imm */
-+ emit(ctx, sltu, rd, lo(rs), rd); /* rd = rsl < rd */
-+ } else {
-+ emit(ctx, sltiu, rd, lo(rs), imm); /* rd = rsl < imm */
-+ }
-+ emit_movn_r(ctx, rd, MIPS_R_ZERO, hi(rs)); /* rd = 0 if rsh */
-+ }
-+}
-+
-+/* Emulation of 64-bit sltu rd, rs, rt */
-+static void emit_sltu_r64(struct jit_context *ctx, u8 rd,
-+ const u8 rs[], const u8 rt[])
-+{
-+ u8 tmp = MIPS_R_T9;
-+
-+ emit(ctx, sltu, rd, lo(rs), lo(rt)); /* rd = rsl < rtl */
-+ emit(ctx, subu, tmp, hi(rs), hi(rt)); /* tmp = rsh - rth */
-+ emit_movn_r(ctx, rd, MIPS_R_ZERO, tmp); /* rd = 0 if tmp != 0 */
-+ emit(ctx, sltu, tmp, hi(rs), hi(rt)); /* tmp = rsh < rth */
-+ emit(ctx, or, rd, rd, tmp); /* rd = rd | tmp */
-+}
-+
-+/* Emulation of 64-bit slti rd, rs, imm, where imm may be S32_MAX + 1 */
-+static void emit_slti_r64(struct jit_context *ctx, u8 rd,
-+ const u8 rs[], s64 imm)
-+{
-+ u8 t1 = MIPS_R_T8;
-+ u8 t2 = MIPS_R_T9;
-+ u8 cmp;
-+
-+ /*
-+ * if ((rs < 0) ^ (imm < 0)) t1 = imm >u rsl
-+ * else t1 = rsl <u imm
-+ */
-+ emit_mov_i(ctx, rd, (s32)imm);
-+ emit(ctx, sltu, t1, lo(rs), rd); /* t1 = rsl <u imm */
-+ emit(ctx, sltu, t2, rd, lo(rs)); /* t2 = imm <u rsl */
-+ emit(ctx, srl, rd, hi(rs), 31); /* rd = rsh >> 31 */
-+ if (imm < 0)
-+ emit_movz_r(ctx, t1, t2, rd); /* t1 = rd ? t1 : t2 */
-+ else
-+ emit_movn_r(ctx, t1, t2, rd); /* t1 = rd ? t2 : t1 */
-+ /*
-+ * if ((imm < 0 && rsh != 0xffffffff) ||
-+ * (imm >= 0 && rsh != 0))
-+ * t1 = 0
-+ */
-+ if (imm < 0) {
-+ emit(ctx, addiu, rd, hi(rs), 1); /* rd = rsh + 1 */
-+ cmp = rd;
-+ } else { /* imm >= 0 */
-+ cmp = hi(rs);
-+ }
-+ emit_movn_r(ctx, t1, MIPS_R_ZERO, cmp); /* t1 = 0 if cmp != 0 */
-+
-+ /*
-+ * if (imm < 0) rd = rsh < -1
-+ * else rd = rsh != 0
-+ * rd = rd | t1
-+ */
-+ emit(ctx, slti, rd, hi(rs), imm < 0 ? -1 : 0); /* rd = rsh < hi(imm) */
-+ emit(ctx, or, rd, rd, t1); /* rd = rd | t1 */
-+}
-+
-+/* Emulation of 64-bit(slt rd, rs, rt) */
-+static void emit_slt_r64(struct jit_context *ctx, u8 rd,
-+ const u8 rs[], const u8 rt[])
-+{
-+ u8 t1 = MIPS_R_T7;
-+ u8 t2 = MIPS_R_T8;
-+ u8 t3 = MIPS_R_T9;
-+
-+ /*
-+ * if ((rs < 0) ^ (rt < 0)) t1 = rtl <u rsl
-+ * else t1 = rsl <u rtl
-+ * if (rsh == rth) t1 = 0
-+ */
-+ emit(ctx, sltu, t1, lo(rs), lo(rt)); /* t1 = rsl <u rtl */
-+ emit(ctx, sltu, t2, lo(rt), lo(rs)); /* t2 = rtl <u rsl */
-+ emit(ctx, xor, t3, hi(rs), hi(rt)); /* t3 = rlh ^ rth */
-+ emit(ctx, srl, rd, t3, 31); /* rd = t3 >> 31 */
-+ emit_movn_r(ctx, t1, t2, rd); /* t1 = rd ? t2 : t1 */
-+ emit_movn_r(ctx, t1, MIPS_R_ZERO, t3); /* t1 = 0 if t3 != 0 */
-+
-+ /* rd = (rsh < rth) | t1 */
-+ emit(ctx, slt, rd, hi(rs), hi(rt)); /* rd = rsh <s rth */
-+ emit(ctx, or, rd, rd, t1); /* rd = rd | t1 */
-+}
-+
-+/* Jump immediate (64-bit) */
-+static void emit_jmp_i64(struct jit_context *ctx,
-+ const u8 dst[], s32 imm, s32 off, u8 op)
-+{
-+ u8 tmp = MIPS_R_T6;
-+
-+ switch (op) {
-+ /* No-op, used internally for branch optimization */
-+ case JIT_JNOP:
-+ break;
-+ /* PC += off if dst == imm */
-+ /* PC += off if dst != imm */
-+ case BPF_JEQ:
-+ case BPF_JNE:
-+ if (imm >= -0x7fff && imm <= 0x8000) {
-+ emit(ctx, addiu, tmp, lo(dst), -imm);
-+ } else if ((u32)imm <= 0xffff) {
-+ emit(ctx, xori, tmp, lo(dst), imm);
-+ } else { /* Register fallback */
-+ emit_mov_i(ctx, tmp, imm);
-+ emit(ctx, xor, tmp, lo(dst), tmp);
-+ }
-+ if (imm < 0) { /* Compare sign extension */
-+ emit(ctx, addu, MIPS_R_T9, hi(dst), 1);
-+ emit(ctx, or, tmp, tmp, MIPS_R_T9);
-+ } else { /* Compare zero extension */
-+ emit(ctx, or, tmp, tmp, hi(dst));
-+ }
-+ if (op == BPF_JEQ)
-+ emit(ctx, beqz, tmp, off);
-+ else /* BPF_JNE */
-+ emit(ctx, bnez, tmp, off);
-+ break;
-+ /* PC += off if dst & imm */
-+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */
-+ case BPF_JSET:
-+ case JIT_JNSET:
-+ if ((u32)imm <= 0xffff) {
-+ emit(ctx, andi, tmp, lo(dst), imm);
-+ } else { /* Register fallback */
-+ emit_mov_i(ctx, tmp, imm);
-+ emit(ctx, and, tmp, lo(dst), tmp);
-+ }
-+ if (imm < 0) /* Sign-extension pulls in high word */
-+ emit(ctx, or, tmp, tmp, hi(dst));
-+ if (op == BPF_JSET)
-+ emit(ctx, bnez, tmp, off);
-+ else /* JIT_JNSET */
-+ emit(ctx, beqz, tmp, off);
-+ break;
-+ /* PC += off if dst > imm */
-+ case BPF_JGT:
-+ emit_sltiu_r64(ctx, tmp, dst, (s64)imm + 1);
-+ emit(ctx, beqz, tmp, off);
-+ break;
-+ /* PC += off if dst >= imm */
-+ case BPF_JGE:
-+ emit_sltiu_r64(ctx, tmp, dst, imm);
-+ emit(ctx, beqz, tmp, off);
-+ break;
-+ /* PC += off if dst < imm */
-+ case BPF_JLT:
-+ emit_sltiu_r64(ctx, tmp, dst, imm);
-+ emit(ctx, bnez, tmp, off);
-+ break;
-+ /* PC += off if dst <= imm */
-+ case BPF_JLE:
-+ emit_sltiu_r64(ctx, tmp, dst, (s64)imm + 1);
-+ emit(ctx, bnez, tmp, off);
-+ break;
-+ /* PC += off if dst > imm (signed) */
-+ case BPF_JSGT:
-+ emit_slti_r64(ctx, tmp, dst, (s64)imm + 1);
-+ emit(ctx, beqz, tmp, off);
-+ break;
-+ /* PC += off if dst >= imm (signed) */
-+ case BPF_JSGE:
-+ emit_slti_r64(ctx, tmp, dst, imm);
-+ emit(ctx, beqz, tmp, off);
-+ break;
-+ /* PC += off if dst < imm (signed) */
-+ case BPF_JSLT:
-+ emit_slti_r64(ctx, tmp, dst, imm);
-+ emit(ctx, bnez, tmp, off);
-+ break;
-+ /* PC += off if dst <= imm (signed) */
-+ case BPF_JSLE:
-+ emit_slti_r64(ctx, tmp, dst, (s64)imm + 1);
-+ emit(ctx, bnez, tmp, off);
-+ break;
-+ }
-+}
-+
-+/* Jump register (64-bit) */
-+static void emit_jmp_r64(struct jit_context *ctx,
-+ const u8 dst[], const u8 src[], s32 off, u8 op)
-+{
-+ u8 t1 = MIPS_R_T6;
-+ u8 t2 = MIPS_R_T7;
-+
-+ switch (op) {
-+ /* No-op, used internally for branch optimization */
-+ case JIT_JNOP:
-+ break;
-+ /* PC += off if dst == src */
-+ /* PC += off if dst != src */
-+ case BPF_JEQ:
-+ case BPF_JNE:
-+ emit(ctx, subu, t1, lo(dst), lo(src));
-+ emit(ctx, subu, t2, hi(dst), hi(src));
-+ emit(ctx, or, t1, t1, t2);
-+ if (op == BPF_JEQ)
-+ emit(ctx, beqz, t1, off);
-+ else /* BPF_JNE */
-+ emit(ctx, bnez, t1, off);
-+ break;
-+ /* PC += off if dst & src */
-+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */
-+ case BPF_JSET:
-+ case JIT_JNSET:
-+ emit(ctx, and, t1, lo(dst), lo(src));
-+ emit(ctx, and, t2, hi(dst), hi(src));
-+ emit(ctx, or, t1, t1, t2);
-+ if (op == BPF_JSET)
-+ emit(ctx, bnez, t1, off);
-+ else /* JIT_JNSET */
-+ emit(ctx, beqz, t1, off);
-+ break;
-+ /* PC += off if dst > src */
-+ case BPF_JGT:
-+ emit_sltu_r64(ctx, t1, src, dst);
-+ emit(ctx, bnez, t1, off);
-+ break;
-+ /* PC += off if dst >= src */
-+ case BPF_JGE:
-+ emit_sltu_r64(ctx, t1, dst, src);
-+ emit(ctx, beqz, t1, off);
-+ break;
-+ /* PC += off if dst < src */
-+ case BPF_JLT:
-+ emit_sltu_r64(ctx, t1, dst, src);
-+ emit(ctx, bnez, t1, off);
-+ break;
-+ /* PC += off if dst <= src */
-+ case BPF_JLE:
-+ emit_sltu_r64(ctx, t1, src, dst);
-+ emit(ctx, beqz, t1, off);
-+ break;
-+ /* PC += off if dst > src (signed) */
-+ case BPF_JSGT:
-+ emit_slt_r64(ctx, t1, src, dst);
-+ emit(ctx, bnez, t1, off);
-+ break;
-+ /* PC += off if dst >= src (signed) */
-+ case BPF_JSGE:
-+ emit_slt_r64(ctx, t1, dst, src);
-+ emit(ctx, beqz, t1, off);
-+ break;
-+ /* PC += off if dst < src (signed) */
-+ case BPF_JSLT:
-+ emit_slt_r64(ctx, t1, dst, src);
-+ emit(ctx, bnez, t1, off);
-+ break;
-+ /* PC += off if dst <= src (signed) */
-+ case BPF_JSLE:
-+ emit_slt_r64(ctx, t1, src, dst);
-+ emit(ctx, beqz, t1, off);
-+ break;
-+ }
-+}
-+
-+/* Function call */
-+static int emit_call(struct jit_context *ctx, const struct bpf_insn *insn)
-+{
-+ bool fixed;
-+ u64 addr;
-+
-+ /* Decode the call address */
-+ if (bpf_jit_get_func_addr(ctx->program, insn, false,
-+ &addr, &fixed) < 0)
-+ return -1;
-+ if (!fixed)
-+ return -1;
-+
-+ /* Push stack arguments */
-+ push_regs(ctx, JIT_STACK_REGS, 0, JIT_RESERVED_STACK);
-+
-+ /* Emit function call */
-+ emit_mov_i(ctx, MIPS_R_T9, addr);
-+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
-+ emit(ctx, nop); /* Delay slot */
-+
-+ clobber_reg(ctx, MIPS_R_RA);
-+ clobber_reg(ctx, MIPS_R_V0);
-+ clobber_reg(ctx, MIPS_R_V1);
-+ return 0;
-+}
-+
-+/* Function tail call */
-+static int emit_tail_call(struct jit_context *ctx)
-+{
-+ u8 ary = lo(bpf2mips32[BPF_REG_2]);
-+ u8 ind = lo(bpf2mips32[BPF_REG_3]);
-+ u8 t1 = MIPS_R_T8;
-+ u8 t2 = MIPS_R_T9;
-+ int off;
-+
-+ /*
-+ * Tail call:
-+ * eBPF R1 - function argument (context ptr), passed in a0-a1
-+ * eBPF R2 - ptr to object with array of function entry points
-+ * eBPF R3 - array index of function to be called
-+ * stack[sz] - remaining tail call count, initialized in prologue
-+ */
-+
-+ /* if (ind >= ary->map.max_entries) goto out */
-+ off = offsetof(struct bpf_array, map.max_entries);
-+ if (off > 0x7fff)
-+ return -1;
-+ emit(ctx, lw, t1, off, ary); /* t1 = ary->map.max_entries*/
-+ emit_load_delay(ctx); /* Load delay slot */
-+ emit(ctx, sltu, t1, ind, t1); /* t1 = ind < t1 */
-+ emit(ctx, beqz, t1, get_offset(ctx, 1)); /* PC += off(1) if t1 == 0 */
-+ /* (next insn delay slot) */
-+ /* if (TCC-- <= 0) goto out */
-+ emit(ctx, lw, t2, ctx->stack_size, MIPS_R_SP); /* t2 = *(SP + size) */
-+ emit_load_delay(ctx); /* Load delay slot */
-+ emit(ctx, blez, t2, get_offset(ctx, 1)); /* PC += off(1) if t2 < 0 */
-+ emit(ctx, addiu, t2, t2, -1); /* t2-- (delay slot) */
-+ emit(ctx, sw, t2, ctx->stack_size, MIPS_R_SP); /* *(SP + size) = t2 */
-+
-+ /* prog = ary->ptrs[ind] */
-+ off = offsetof(struct bpf_array, ptrs);
-+ if (off > 0x7fff)
-+ return -1;
-+ emit(ctx, sll, t1, ind, 2); /* t1 = ind << 2 */
-+ emit(ctx, addu, t1, t1, ary); /* t1 += ary */
-+ emit(ctx, lw, t2, off, t1); /* t2 = *(t1 + off) */
-+ emit_load_delay(ctx); /* Load delay slot */
-+
-+ /* if (prog == 0) goto out */
-+ emit(ctx, beqz, t2, get_offset(ctx, 1)); /* PC += off(1) if t2 == 0 */
-+ emit(ctx, nop); /* Delay slot */
-+
-+ /* func = prog->bpf_func + 8 (prologue skip offset) */
-+ off = offsetof(struct bpf_prog, bpf_func);
-+ if (off > 0x7fff)
-+ return -1;
-+ emit(ctx, lw, t1, off, t2); /* t1 = *(t2 + off) */
-+ emit_load_delay(ctx); /* Load delay slot */
-+ emit(ctx, addiu, t1, t1, JIT_TCALL_SKIP); /* t1 += skip (8 or 12) */
-+
-+ /* goto func */
-+ build_epilogue(ctx, t1);
-+ return 0;
-+}
-+
-+/*
-+ * Stack frame layout for a JITed program (stack grows down).
-+ *
-+ * Higher address : Caller's stack frame :
-+ * :----------------------------:
-+ * : 64-bit eBPF args r3-r5 :
-+ * :----------------------------:
-+ * : Reserved / tail call count :
-+ * +============================+ <--- MIPS sp before call
-+ * | Callee-saved registers, |
-+ * | including RA and FP |
-+ * +----------------------------+ <--- eBPF FP (MIPS zero,fp)
-+ * | Local eBPF variables |
-+ * | allocated by program |
-+ * +----------------------------+
-+ * | Reserved for caller-saved |
-+ * | registers |
-+ * +----------------------------+
-+ * | Reserved for 64-bit eBPF |
-+ * | args r3-r5 & args passed |
-+ * | on stack in kernel calls |
-+ * Lower address +============================+ <--- MIPS sp
-+ */
-+
-+/* Build program prologue to set up the stack and registers */
-+void build_prologue(struct jit_context *ctx)
-+{
-+ const u8 *r1 = bpf2mips32[BPF_REG_1];
-+ const u8 *fp = bpf2mips32[BPF_REG_FP];
-+ int stack, saved, locals, reserved;
-+
-+ /*
-+ * The first two instructions initialize TCC in the reserved (for us)
-+ * 16-byte area in the parent's stack frame. On a tail call, the
-+ * calling function jumps into the prologue after these instructions.
-+ */
-+ emit(ctx, ori, MIPS_R_T9, MIPS_R_ZERO,
-+ min(MAX_TAIL_CALL_CNT + 1, 0xffff));
-+ emit(ctx, sw, MIPS_R_T9, 0, MIPS_R_SP);
-+
-+ /*
-+ * Register eBPF R1 contains the 32-bit context pointer argument.
-+ * A 32-bit argument is always passed in MIPS register a0, regardless
-+ * of CPU endianness. Initialize R1 accordingly and zero-extend.
-+ */
-+#ifdef __BIG_ENDIAN
-+ emit(ctx, move, lo(r1), MIPS_R_A0);
-+#endif
-+
-+ /* === Entry-point for tail calls === */
-+
-+ /* Zero-extend the 32-bit argument */
-+ emit(ctx, move, hi(r1), MIPS_R_ZERO);
-+
-+ /* If the eBPF frame pointer was accessed it must be saved */
-+ if (ctx->accessed & BIT(BPF_REG_FP))
-+ clobber_reg64(ctx, fp);
-+
-+ /* Compute the stack space needed for callee-saved registers */
-+ saved = hweight32(ctx->clobbered & JIT_CALLEE_REGS) * sizeof(u32);
-+ saved = ALIGN(saved, MIPS_STACK_ALIGNMENT);
-+
-+ /* Stack space used by eBPF program local data */
-+ locals = ALIGN(ctx->program->aux->stack_depth, MIPS_STACK_ALIGNMENT);
-+
-+ /*
-+ * If we are emitting function calls, reserve extra stack space for
-+ * caller-saved registers and function arguments passed on the stack.
-+ * The required space is computed automatically during resource
-+ * usage discovery (pass 1).
-+ */
-+ reserved = ctx->stack_used;
-+
-+ /* Allocate the stack frame */
-+ stack = ALIGN(saved + locals + reserved, MIPS_STACK_ALIGNMENT);
-+ emit(ctx, addiu, MIPS_R_SP, MIPS_R_SP, -stack);
-+
-+ /* Store callee-saved registers on stack */
-+ push_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0, stack - saved);
-+
-+ /* Initialize the eBPF frame pointer if accessed */
-+ if (ctx->accessed & BIT(BPF_REG_FP))
-+ emit(ctx, addiu, lo(fp), MIPS_R_SP, stack - saved);
-+
-+ ctx->saved_size = saved;
-+ ctx->stack_size = stack;
-+}
-+
-+/* Build the program epilogue to restore the stack and registers */
-+void build_epilogue(struct jit_context *ctx, int dest_reg)
-+{
-+ /* Restore callee-saved registers from stack */
-+ pop_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0,
-+ ctx->stack_size - ctx->saved_size);
-+ /*
-+ * A 32-bit return value is always passed in MIPS register v0,
-+ * but on big-endian targets the low part of R0 is mapped to v1.
-+ */
-+#ifdef __BIG_ENDIAN
-+ emit(ctx, move, MIPS_R_V0, MIPS_R_V1);
-+#endif
-+
-+ /* Jump to the return address and adjust the stack pointer */
-+ emit(ctx, jr, dest_reg);
-+ emit(ctx, addiu, MIPS_R_SP, MIPS_R_SP, ctx->stack_size);
-+}
-+
-+/* Build one eBPF instruction */
-+int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
-+{
-+ const u8 *dst = bpf2mips32[insn->dst_reg];
-+ const u8 *src = bpf2mips32[insn->src_reg];
-+ const u8 *tmp = bpf2mips32[JIT_REG_TMP];
-+ u8 code = insn->code;
-+ s16 off = insn->off;
-+ s32 imm = insn->imm;
-+ s32 val, rel;
-+ u8 alu, jmp;
-+
-+ switch (code) {
-+ /* ALU operations */
-+ /* dst = imm */
-+ case BPF_ALU | BPF_MOV | BPF_K:
-+ emit_mov_i(ctx, lo(dst), imm);
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = src */
-+ case BPF_ALU | BPF_MOV | BPF_X:
-+ if (imm == 1) {
-+ /* Special mov32 for zext */
-+ emit_mov_i(ctx, hi(dst), 0);
-+ } else {
-+ emit_mov_r(ctx, lo(dst), lo(src));
-+ emit_zext_ver(ctx, dst);
-+ }
-+ break;
-+ /* dst = -dst */
-+ case BPF_ALU | BPF_NEG:
-+ emit_alu_i(ctx, lo(dst), 0, BPF_NEG);
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = dst & imm */
-+ /* dst = dst | imm */
-+ /* dst = dst ^ imm */
-+ /* dst = dst << imm */
-+ /* dst = dst >> imm */
-+ /* dst = dst >> imm (arithmetic) */
-+ /* dst = dst + imm */
-+ /* dst = dst - imm */
-+ /* dst = dst * imm */
-+ /* dst = dst / imm */
-+ /* dst = dst % imm */
-+ case BPF_ALU | BPF_OR | BPF_K:
-+ case BPF_ALU | BPF_AND | BPF_K:
-+ case BPF_ALU | BPF_XOR | BPF_K:
-+ case BPF_ALU | BPF_LSH | BPF_K:
-+ case BPF_ALU | BPF_RSH | BPF_K:
-+ case BPF_ALU | BPF_ARSH | BPF_K:
-+ case BPF_ALU | BPF_ADD | BPF_K:
-+ case BPF_ALU | BPF_SUB | BPF_K:
-+ case BPF_ALU | BPF_MUL | BPF_K:
-+ case BPF_ALU | BPF_DIV | BPF_K:
-+ case BPF_ALU | BPF_MOD | BPF_K:
-+ if (!valid_alu_i(BPF_OP(code), imm)) {
-+ emit_mov_i(ctx, MIPS_R_T6, imm);
-+ emit_alu_r(ctx, lo(dst), MIPS_R_T6, BPF_OP(code));
-+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
-+ emit_alu_i(ctx, lo(dst), val, alu);
-+ }
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = dst & src */
-+ /* dst = dst | src */
-+ /* dst = dst ^ src */
-+ /* dst = dst << src */
-+ /* dst = dst >> src */
-+ /* dst = dst >> src (arithmetic) */
-+ /* dst = dst + src */
-+ /* dst = dst - src */
-+ /* dst = dst * src */
-+ /* dst = dst / src */
-+ /* dst = dst % src */
-+ case BPF_ALU | BPF_AND | BPF_X:
-+ case BPF_ALU | BPF_OR | BPF_X:
-+ case BPF_ALU | BPF_XOR | BPF_X:
-+ case BPF_ALU | BPF_LSH | BPF_X:
-+ case BPF_ALU | BPF_RSH | BPF_X:
-+ case BPF_ALU | BPF_ARSH | BPF_X:
-+ case BPF_ALU | BPF_ADD | BPF_X:
-+ case BPF_ALU | BPF_SUB | BPF_X:
-+ case BPF_ALU | BPF_MUL | BPF_X:
-+ case BPF_ALU | BPF_DIV | BPF_X:
-+ case BPF_ALU | BPF_MOD | BPF_X:
-+ emit_alu_r(ctx, lo(dst), lo(src), BPF_OP(code));
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = imm (64-bit) */
-+ case BPF_ALU64 | BPF_MOV | BPF_K:
-+ emit_mov_se_i64(ctx, dst, imm);
-+ break;
-+ /* dst = src (64-bit) */
-+ case BPF_ALU64 | BPF_MOV | BPF_X:
-+ emit_mov_r(ctx, lo(dst), lo(src));
-+ emit_mov_r(ctx, hi(dst), hi(src));
-+ break;
-+ /* dst = -dst (64-bit) */
-+ case BPF_ALU64 | BPF_NEG:
-+ emit_neg_i64(ctx, dst);
-+ break;
-+ /* dst = dst & imm (64-bit) */
-+ case BPF_ALU64 | BPF_AND | BPF_K:
-+ emit_alu_i64(ctx, dst, imm, BPF_OP(code));
-+ break;
-+ /* dst = dst | imm (64-bit) */
-+ /* dst = dst ^ imm (64-bit) */
-+ /* dst = dst + imm (64-bit) */
-+ /* dst = dst - imm (64-bit) */
-+ case BPF_ALU64 | BPF_OR | BPF_K:
-+ case BPF_ALU64 | BPF_XOR | BPF_K:
-+ case BPF_ALU64 | BPF_ADD | BPF_K:
-+ case BPF_ALU64 | BPF_SUB | BPF_K:
-+ if (imm)
-+ emit_alu_i64(ctx, dst, imm, BPF_OP(code));
-+ break;
-+ /* dst = dst << imm (64-bit) */
-+ /* dst = dst >> imm (64-bit) */
-+ /* dst = dst >> imm (64-bit, arithmetic) */
-+ case BPF_ALU64 | BPF_LSH | BPF_K:
-+ case BPF_ALU64 | BPF_RSH | BPF_K:
-+ case BPF_ALU64 | BPF_ARSH | BPF_K:
-+ if (imm)
-+ emit_shift_i64(ctx, dst, imm, BPF_OP(code));
-+ break;
-+ /* dst = dst * imm (64-bit) */
-+ case BPF_ALU64 | BPF_MUL | BPF_K:
-+ emit_mul_i64(ctx, dst, imm);
-+ break;
-+ /* dst = dst / imm (64-bit) */
-+ /* dst = dst % imm (64-bit) */
-+ case BPF_ALU64 | BPF_DIV | BPF_K:
-+ case BPF_ALU64 | BPF_MOD | BPF_K:
-+ /*
-+ * Sign-extend the immediate value into a temporary register,
-+ * and then do the operation on this register.
-+ */
-+ emit_mov_se_i64(ctx, tmp, imm);
-+ emit_divmod_r64(ctx, dst, tmp, BPF_OP(code));
-+ break;
-+ /* dst = dst & src (64-bit) */
-+ /* dst = dst | src (64-bit) */
-+ /* dst = dst ^ src (64-bit) */
-+ /* dst = dst + src (64-bit) */
-+ /* dst = dst - src (64-bit) */
-+ case BPF_ALU64 | BPF_AND | BPF_X:
-+ case BPF_ALU64 | BPF_OR | BPF_X:
-+ case BPF_ALU64 | BPF_XOR | BPF_X:
-+ case BPF_ALU64 | BPF_ADD | BPF_X:
-+ case BPF_ALU64 | BPF_SUB | BPF_X:
-+ emit_alu_r64(ctx, dst, src, BPF_OP(code));
-+ break;
-+ /* dst = dst << src (64-bit) */
-+ /* dst = dst >> src (64-bit) */
-+ /* dst = dst >> src (64-bit, arithmetic) */
-+ case BPF_ALU64 | BPF_LSH | BPF_X:
-+ case BPF_ALU64 | BPF_RSH | BPF_X:
-+ case BPF_ALU64 | BPF_ARSH | BPF_X:
-+ emit_shift_r64(ctx, dst, lo(src), BPF_OP(code));
-+ break;
-+ /* dst = dst * src (64-bit) */
-+ case BPF_ALU64 | BPF_MUL | BPF_X:
-+ emit_mul_r64(ctx, dst, src);
-+ break;
-+ /* dst = dst / src (64-bit) */
-+ /* dst = dst % src (64-bit) */
-+ case BPF_ALU64 | BPF_DIV | BPF_X:
-+ case BPF_ALU64 | BPF_MOD | BPF_X:
-+ emit_divmod_r64(ctx, dst, src, BPF_OP(code));
-+ break;
-+ /* dst = htole(dst) */
-+ /* dst = htobe(dst) */
-+ case BPF_ALU | BPF_END | BPF_FROM_LE:
-+ case BPF_ALU | BPF_END | BPF_FROM_BE:
-+ if (BPF_SRC(code) ==
-+#ifdef __BIG_ENDIAN
-+ BPF_FROM_LE
-+#else
-+ BPF_FROM_BE
-+#endif
-+ )
-+ emit_bswap_r64(ctx, dst, imm);
-+ else
-+ emit_trunc_r64(ctx, dst, imm);
-+ break;
-+ /* dst = imm64 */
-+ case BPF_LD | BPF_IMM | BPF_DW:
-+ emit_mov_i(ctx, lo(dst), imm);
-+ emit_mov_i(ctx, hi(dst), insn[1].imm);
-+ return 1;
-+ /* LDX: dst = *(size *)(src + off) */
-+ case BPF_LDX | BPF_MEM | BPF_W:
-+ case BPF_LDX | BPF_MEM | BPF_H:
-+ case BPF_LDX | BPF_MEM | BPF_B:
-+ case BPF_LDX | BPF_MEM | BPF_DW:
-+ emit_ldx(ctx, dst, lo(src), off, BPF_SIZE(code));
-+ break;
-+ /* ST: *(size *)(dst + off) = imm */
-+ case BPF_ST | BPF_MEM | BPF_W:
-+ case BPF_ST | BPF_MEM | BPF_H:
-+ case BPF_ST | BPF_MEM | BPF_B:
-+ case BPF_ST | BPF_MEM | BPF_DW:
-+ switch (BPF_SIZE(code)) {
-+ case BPF_DW:
-+ /* Sign-extend immediate value into temporary reg */
-+ emit_mov_se_i64(ctx, tmp, imm);
-+ break;
-+ case BPF_W:
-+ case BPF_H:
-+ case BPF_B:
-+ emit_mov_i(ctx, lo(tmp), imm);
-+ break;
-+ }
-+ emit_stx(ctx, lo(dst), tmp, off, BPF_SIZE(code));
-+ break;
-+ /* STX: *(size *)(dst + off) = src */
-+ case BPF_STX | BPF_MEM | BPF_W:
-+ case BPF_STX | BPF_MEM | BPF_H:
-+ case BPF_STX | BPF_MEM | BPF_B:
-+ case BPF_STX | BPF_MEM | BPF_DW:
-+ emit_stx(ctx, lo(dst), src, off, BPF_SIZE(code));
-+ break;
-+ /* Speculation barrier */
-+ case BPF_ST | BPF_NOSPEC:
-+ break;
-+ /* Atomics */
-+ case BPF_STX | BPF_XADD | BPF_W:
-+ switch (imm) {
-+ case BPF_ADD:
-+ case BPF_AND:
-+ case BPF_OR:
-+ case BPF_XOR:
-+ if (cpu_has_llsc)
-+ emit_atomic_r(ctx, lo(dst), lo(src), off, imm);
-+ else /* Non-ll/sc fallback */
-+ emit_atomic_r32(ctx, lo(dst), lo(src),
-+ off, imm);
-+ break;
-+ default:
-+ goto notyet;
-+ }
-+ break;
-+ /* Atomics (64-bit) */
-+ case BPF_STX | BPF_XADD | BPF_DW:
-+ switch (imm) {
-+ case BPF_ADD:
-+ case BPF_AND:
-+ case BPF_OR:
-+ case BPF_XOR:
-+ emit_atomic_r64(ctx, lo(dst), src, off, imm);
-+ break;
-+ default:
-+ goto notyet;
-+ }
-+ break;
-+ /* PC += off if dst == src */
-+ /* PC += off if dst != src */
-+ /* PC += off if dst & src */
-+ /* PC += off if dst > src */
-+ /* PC += off if dst >= src */
-+ /* PC += off if dst < src */
-+ /* PC += off if dst <= src */
-+ /* PC += off if dst > src (signed) */
-+ /* PC += off if dst >= src (signed) */
-+ /* PC += off if dst < src (signed) */
-+ /* PC += off if dst <= src (signed) */
-+ case BPF_JMP32 | BPF_JEQ | BPF_X:
-+ case BPF_JMP32 | BPF_JNE | BPF_X:
-+ case BPF_JMP32 | BPF_JSET | BPF_X:
-+ case BPF_JMP32 | BPF_JGT | BPF_X:
-+ case BPF_JMP32 | BPF_JGE | BPF_X:
-+ case BPF_JMP32 | BPF_JLT | BPF_X:
-+ case BPF_JMP32 | BPF_JLE | BPF_X:
-+ case BPF_JMP32 | BPF_JSGT | BPF_X:
-+ case BPF_JMP32 | BPF_JSGE | BPF_X:
-+ case BPF_JMP32 | BPF_JSLT | BPF_X:
-+ case BPF_JMP32 | BPF_JSLE | BPF_X:
-+ if (off == 0)
-+ break;
-+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel);
-+ emit_jmp_r(ctx, lo(dst), lo(src), rel, jmp);
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off if dst == imm */
-+ /* PC += off if dst != imm */
-+ /* PC += off if dst & imm */
-+ /* PC += off if dst > imm */
-+ /* PC += off if dst >= imm */
-+ /* PC += off if dst < imm */
-+ /* PC += off if dst <= imm */
-+ /* PC += off if dst > imm (signed) */
-+ /* PC += off if dst >= imm (signed) */
-+ /* PC += off if dst < imm (signed) */
-+ /* PC += off if dst <= imm (signed) */
-+ case BPF_JMP32 | BPF_JEQ | BPF_K:
-+ case BPF_JMP32 | BPF_JNE | BPF_K:
-+ case BPF_JMP32 | BPF_JSET | BPF_K:
-+ case BPF_JMP32 | BPF_JGT | BPF_K:
-+ case BPF_JMP32 | BPF_JGE | BPF_K:
-+ case BPF_JMP32 | BPF_JLT | BPF_K:
-+ case BPF_JMP32 | BPF_JLE | BPF_K:
-+ case BPF_JMP32 | BPF_JSGT | BPF_K:
-+ case BPF_JMP32 | BPF_JSGE | BPF_K:
-+ case BPF_JMP32 | BPF_JSLT | BPF_K:
-+ case BPF_JMP32 | BPF_JSLE | BPF_K:
-+ if (off == 0)
-+ break;
-+ setup_jmp_i(ctx, imm, 32, BPF_OP(code), off, &jmp, &rel);
-+ if (valid_jmp_i(jmp, imm)) {
-+ emit_jmp_i(ctx, lo(dst), imm, rel, jmp);
-+ } else {
-+ /* Move large immediate to register */
-+ emit_mov_i(ctx, MIPS_R_T6, imm);
-+ emit_jmp_r(ctx, lo(dst), MIPS_R_T6, rel, jmp);
-+ }
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off if dst == src */
-+ /* PC += off if dst != src */
-+ /* PC += off if dst & src */
-+ /* PC += off if dst > src */
-+ /* PC += off if dst >= src */
-+ /* PC += off if dst < src */
-+ /* PC += off if dst <= src */
-+ /* PC += off if dst > src (signed) */
-+ /* PC += off if dst >= src (signed) */
-+ /* PC += off if dst < src (signed) */
-+ /* PC += off if dst <= src (signed) */
-+ case BPF_JMP | BPF_JEQ | BPF_X:
-+ case BPF_JMP | BPF_JNE | BPF_X:
-+ case BPF_JMP | BPF_JSET | BPF_X:
-+ case BPF_JMP | BPF_JGT | BPF_X:
-+ case BPF_JMP | BPF_JGE | BPF_X:
-+ case BPF_JMP | BPF_JLT | BPF_X:
-+ case BPF_JMP | BPF_JLE | BPF_X:
-+ case BPF_JMP | BPF_JSGT | BPF_X:
-+ case BPF_JMP | BPF_JSGE | BPF_X:
-+ case BPF_JMP | BPF_JSLT | BPF_X:
-+ case BPF_JMP | BPF_JSLE | BPF_X:
-+ if (off == 0)
-+ break;
-+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel);
-+ emit_jmp_r64(ctx, dst, src, rel, jmp);
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off if dst == imm */
-+ /* PC += off if dst != imm */
-+ /* PC += off if dst & imm */
-+ /* PC += off if dst > imm */
-+ /* PC += off if dst >= imm */
-+ /* PC += off if dst < imm */
-+ /* PC += off if dst <= imm */
-+ /* PC += off if dst > imm (signed) */
-+ /* PC += off if dst >= imm (signed) */
-+ /* PC += off if dst < imm (signed) */
-+ /* PC += off if dst <= imm (signed) */
-+ case BPF_JMP | BPF_JEQ | BPF_K:
-+ case BPF_JMP | BPF_JNE | BPF_K:
-+ case BPF_JMP | BPF_JSET | BPF_K:
-+ case BPF_JMP | BPF_JGT | BPF_K:
-+ case BPF_JMP | BPF_JGE | BPF_K:
-+ case BPF_JMP | BPF_JLT | BPF_K:
-+ case BPF_JMP | BPF_JLE | BPF_K:
-+ case BPF_JMP | BPF_JSGT | BPF_K:
-+ case BPF_JMP | BPF_JSGE | BPF_K:
-+ case BPF_JMP | BPF_JSLT | BPF_K:
-+ case BPF_JMP | BPF_JSLE | BPF_K:
-+ if (off == 0)
-+ break;
-+ setup_jmp_i(ctx, imm, 64, BPF_OP(code), off, &jmp, &rel);
-+ emit_jmp_i64(ctx, dst, imm, rel, jmp);
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off */
-+ case BPF_JMP | BPF_JA:
-+ if (off == 0)
-+ break;
-+ if (emit_ja(ctx, off) < 0)
-+ goto toofar;
-+ break;
-+ /* Tail call */
-+ case BPF_JMP | BPF_TAIL_CALL:
-+ if (emit_tail_call(ctx) < 0)
-+ goto invalid;
-+ break;
-+ /* Function call */
-+ case BPF_JMP | BPF_CALL:
-+ if (emit_call(ctx, insn) < 0)
-+ goto invalid;
-+ break;
-+ /* Function return */
-+ case BPF_JMP | BPF_EXIT:
-+ /*
-+ * Optimization: when last instruction is EXIT
-+ * simply continue to epilogue.
-+ */
-+ if (ctx->bpf_index == ctx->program->len - 1)
-+ break;
-+ if (emit_exit(ctx) < 0)
-+ goto toofar;
-+ break;
-+
-+ default:
-+invalid:
-+ pr_err_once("unknown opcode %02x\n", code);
-+ return -EINVAL;
-+notyet:
-+ pr_info_once("*** NOT YET: opcode %02x ***\n", code);
-+ return -EFAULT;
-+toofar:
-+ pr_info_once("*** TOO FAR: jump at %u opcode %02x ***\n",
-+ ctx->bpf_index, code);
-+ return -E2BIG;
-+ }
-+ return 0;
-+}
diff --git a/target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch b/target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch
deleted file mode 100644
index 38b46c0b76..0000000000
--- a/target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch
+++ /dev/null
@@ -1,1005 +0,0 @@
-From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Date: Tue, 5 Oct 2021 18:54:05 +0200
-Subject: [PATCH] mips: bpf: Add new eBPF JIT for 64-bit MIPS
-
-This is an implementation on of an eBPF JIT for 64-bit MIPS III-V and
-MIPS64r1-r6. It uses the same framework introduced by the 32-bit JIT.
-
-Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
----
- create mode 100644 arch/mips/net/bpf_jit_comp64.c
-
---- /dev/null
-+++ b/arch/mips/net/bpf_jit_comp64.c
-@@ -0,0 +1,991 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Just-In-Time compiler for eBPF bytecode on MIPS.
-+ * Implementation of JIT functions for 64-bit CPUs.
-+ *
-+ * Copyright (c) 2021 Anyfi Networks AB.
-+ * Author: Johan Almbladh <johan.almbladh@gmail.com>
-+ *
-+ * Based on code and ideas from
-+ * Copyright (c) 2017 Cavium, Inc.
-+ * Copyright (c) 2017 Shubham Bansal <illusionist.neo@gmail.com>
-+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/filter.h>
-+#include <linux/bpf.h>
-+#include <asm/cpu-features.h>
-+#include <asm/isa-rev.h>
-+#include <asm/uasm.h>
-+
-+#include "bpf_jit_comp.h"
-+
-+/* MIPS t0-t3 are not available in the n64 ABI */
-+#undef MIPS_R_T0
-+#undef MIPS_R_T1
-+#undef MIPS_R_T2
-+#undef MIPS_R_T3
-+
-+/* Stack is 16-byte aligned in n64 ABI */
-+#define MIPS_STACK_ALIGNMENT 16
-+
-+/* Extra 64-bit eBPF registers used by JIT */
-+#define JIT_REG_TC (MAX_BPF_JIT_REG + 0)
-+#define JIT_REG_ZX (MAX_BPF_JIT_REG + 1)
-+
-+/* Number of prologue bytes to skip when doing a tail call */
-+#define JIT_TCALL_SKIP 4
-+
-+/* Callee-saved CPU registers that the JIT must preserve */
-+#define JIT_CALLEE_REGS \
-+ (BIT(MIPS_R_S0) | \
-+ BIT(MIPS_R_S1) | \
-+ BIT(MIPS_R_S2) | \
-+ BIT(MIPS_R_S3) | \
-+ BIT(MIPS_R_S4) | \
-+ BIT(MIPS_R_S5) | \
-+ BIT(MIPS_R_S6) | \
-+ BIT(MIPS_R_S7) | \
-+ BIT(MIPS_R_GP) | \
-+ BIT(MIPS_R_FP) | \
-+ BIT(MIPS_R_RA))
-+
-+/* Caller-saved CPU registers available for JIT use */
-+#define JIT_CALLER_REGS \
-+ (BIT(MIPS_R_A5) | \
-+ BIT(MIPS_R_A6) | \
-+ BIT(MIPS_R_A7))
-+/*
-+ * Mapping of 64-bit eBPF registers to 64-bit native MIPS registers.
-+ * MIPS registers t4 - t7 may be used by the JIT as temporary registers.
-+ * MIPS registers t8 - t9 are reserved for single-register common functions.
-+ */
-+static const u8 bpf2mips64[] = {
-+ /* Return value from in-kernel function, and exit value from eBPF */
-+ [BPF_REG_0] = MIPS_R_V0,
-+ /* Arguments from eBPF program to in-kernel function */
-+ [BPF_REG_1] = MIPS_R_A0,
-+ [BPF_REG_2] = MIPS_R_A1,
-+ [BPF_REG_3] = MIPS_R_A2,
-+ [BPF_REG_4] = MIPS_R_A3,
-+ [BPF_REG_5] = MIPS_R_A4,
-+ /* Callee-saved registers that in-kernel function will preserve */
-+ [BPF_REG_6] = MIPS_R_S0,
-+ [BPF_REG_7] = MIPS_R_S1,
-+ [BPF_REG_8] = MIPS_R_S2,
-+ [BPF_REG_9] = MIPS_R_S3,
-+ /* Read-only frame pointer to access the eBPF stack */
-+ [BPF_REG_FP] = MIPS_R_FP,
-+ /* Temporary register for blinding constants */
-+ [BPF_REG_AX] = MIPS_R_AT,
-+ /* Tail call count register, caller-saved */
-+ [JIT_REG_TC] = MIPS_R_A5,
-+ /* Constant for register zero-extension */
-+ [JIT_REG_ZX] = MIPS_R_V1,
-+};
-+
-+/*
-+ * MIPS 32-bit operations on 64-bit registers generate a sign-extended
-+ * result. However, the eBPF ISA mandates zero-extension, so we rely on the
-+ * verifier to add that for us (emit_zext_ver). In addition, ALU arithmetic
-+ * operations, right shift and byte swap require properly sign-extended
-+ * operands or the result is unpredictable. We emit explicit sign-extensions
-+ * in those cases.
-+ */
-+
-+/* Sign extension */
-+static void emit_sext(struct jit_context *ctx, u8 dst, u8 src)
-+{
-+ emit(ctx, sll, dst, src, 0);
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Zero extension */
-+static void emit_zext(struct jit_context *ctx, u8 dst)
-+{
-+ if (cpu_has_mips64r2 || cpu_has_mips64r6) {
-+ emit(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
-+ } else {
-+ emit(ctx, and, dst, dst, bpf2mips64[JIT_REG_ZX]);
-+ access_reg(ctx, JIT_REG_ZX); /* We need the ZX register */
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Zero extension, if verifier does not do it for us */
-+static void emit_zext_ver(struct jit_context *ctx, u8 dst)
-+{
-+ if (!ctx->program->aux->verifier_zext)
-+ emit_zext(ctx, dst);
-+}
-+
-+/* dst = imm (64-bit) */
-+static void emit_mov_i64(struct jit_context *ctx, u8 dst, u64 imm64)
-+{
-+ if (imm64 >= 0xffffffffffff8000ULL || imm64 < 0x8000ULL) {
-+ emit(ctx, daddiu, dst, MIPS_R_ZERO, (s16)imm64);
-+ } else if (imm64 >= 0xffffffff80000000ULL ||
-+ (imm64 < 0x80000000 && imm64 > 0xffff)) {
-+ emit(ctx, lui, dst, (s16)(imm64 >> 16));
-+ emit(ctx, ori, dst, dst, (u16)imm64 & 0xffff);
-+ } else {
-+ u8 acc = MIPS_R_ZERO;
-+ int k;
-+
-+ for (k = 0; k < 4; k++) {
-+ u16 half = imm64 >> (48 - 16 * k);
-+
-+ if (acc == dst)
-+ emit(ctx, dsll, dst, dst, 16);
-+
-+ if (half) {
-+ emit(ctx, ori, dst, acc, half);
-+ acc = dst;
-+ }
-+ }
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* ALU immediate operation (64-bit) */
-+static void emit_alu_i64(struct jit_context *ctx, u8 dst, s32 imm, u8 op)
-+{
-+ switch (BPF_OP(op)) {
-+ /* dst = dst | imm */
-+ case BPF_OR:
-+ emit(ctx, ori, dst, dst, (u16)imm);
-+ break;
-+ /* dst = dst ^ imm */
-+ case BPF_XOR:
-+ emit(ctx, xori, dst, dst, (u16)imm);
-+ break;
-+ /* dst = -dst */
-+ case BPF_NEG:
-+ emit(ctx, dsubu, dst, MIPS_R_ZERO, dst);
-+ break;
-+ /* dst = dst << imm */
-+ case BPF_LSH:
-+ emit(ctx, dsll_safe, dst, dst, imm);
-+ break;
-+ /* dst = dst >> imm */
-+ case BPF_RSH:
-+ emit(ctx, dsrl_safe, dst, dst, imm);
-+ break;
-+ /* dst = dst >> imm (arithmetic) */
-+ case BPF_ARSH:
-+ emit(ctx, dsra_safe, dst, dst, imm);
-+ break;
-+ /* dst = dst + imm */
-+ case BPF_ADD:
-+ emit(ctx, daddiu, dst, dst, imm);
-+ break;
-+ /* dst = dst - imm */
-+ case BPF_SUB:
-+ emit(ctx, daddiu, dst, dst, -imm);
-+ break;
-+ default:
-+ /* Width-generic operations */
-+ emit_alu_i(ctx, dst, imm, op);
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* ALU register operation (64-bit) */
-+static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)
-+{
-+ switch (BPF_OP(op)) {
-+ /* dst = dst << src */
-+ case BPF_LSH:
-+ emit(ctx, dsllv, dst, dst, src);
-+ break;
-+ /* dst = dst >> src */
-+ case BPF_RSH:
-+ emit(ctx, dsrlv, dst, dst, src);
-+ break;
-+ /* dst = dst >> src (arithmetic) */
-+ case BPF_ARSH:
-+ emit(ctx, dsrav, dst, dst, src);
-+ break;
-+ /* dst = dst + src */
-+ case BPF_ADD:
-+ emit(ctx, daddu, dst, dst, src);
-+ break;
-+ /* dst = dst - src */
-+ case BPF_SUB:
-+ emit(ctx, dsubu, dst, dst, src);
-+ break;
-+ /* dst = dst * src */
-+ case BPF_MUL:
-+ if (cpu_has_mips64r6) {
-+ emit(ctx, dmulu, dst, dst, src);
-+ } else {
-+ emit(ctx, dmultu, dst, src);
-+ emit(ctx, mflo, dst);
-+ }
-+ break;
-+ /* dst = dst / src */
-+ case BPF_DIV:
-+ if (cpu_has_mips64r6) {
-+ emit(ctx, ddivu_r6, dst, dst, src);
-+ } else {
-+ emit(ctx, ddivu, dst, src);
-+ emit(ctx, mflo, dst);
-+ }
-+ break;
-+ /* dst = dst % src */
-+ case BPF_MOD:
-+ if (cpu_has_mips64r6) {
-+ emit(ctx, dmodu, dst, dst, src);
-+ } else {
-+ emit(ctx, ddivu, dst, src);
-+ emit(ctx, mfhi, dst);
-+ }
-+ break;
-+ default:
-+ /* Width-generic operations */
-+ emit_alu_r(ctx, dst, src, op);
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Swap sub words in a register double word */
-+static void emit_swap_r64(struct jit_context *ctx, u8 dst, u8 mask, u32 bits)
-+{
-+ u8 tmp = MIPS_R_T9;
-+
-+ emit(ctx, and, tmp, dst, mask); /* tmp = dst & mask */
-+ emit(ctx, dsll, tmp, tmp, bits); /* tmp = tmp << bits */
-+ emit(ctx, dsrl, dst, dst, bits); /* dst = dst >> bits */
-+ emit(ctx, and, dst, dst, mask); /* dst = dst & mask */
-+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */
-+}
-+
-+/* Swap bytes and truncate a register double word, word or half word */
-+static void emit_bswap_r64(struct jit_context *ctx, u8 dst, u32 width)
-+{
-+ switch (width) {
-+ /* Swap bytes in a double word */
-+ case 64:
-+ if (cpu_has_mips64r2 || cpu_has_mips64r6) {
-+ emit(ctx, dsbh, dst, dst);
-+ emit(ctx, dshd, dst, dst);
-+ } else {
-+ u8 t1 = MIPS_R_T6;
-+ u8 t2 = MIPS_R_T7;
-+
-+ emit(ctx, dsll32, t2, dst, 0); /* t2 = dst << 32 */
-+ emit(ctx, dsrl32, dst, dst, 0); /* dst = dst >> 32 */
-+ emit(ctx, or, dst, dst, t2); /* dst = dst | t2 */
-+
-+ emit(ctx, ori, t2, MIPS_R_ZERO, 0xffff);
-+ emit(ctx, dsll32, t1, t2, 0); /* t1 = t2 << 32 */
-+ emit(ctx, or, t1, t1, t2); /* t1 = t1 | t2 */
-+ emit_swap_r64(ctx, dst, t1, 16);/* dst = swap16(dst) */
-+
-+ emit(ctx, lui, t2, 0xff); /* t2 = 0x00ff0000 */
-+ emit(ctx, ori, t2, t2, 0xff); /* t2 = t2 | 0x00ff */
-+ emit(ctx, dsll32, t1, t2, 0); /* t1 = t2 << 32 */
-+ emit(ctx, or, t1, t1, t2); /* t1 = t1 | t2 */
-+ emit_swap_r64(ctx, dst, t1, 8); /* dst = swap8(dst) */
-+ }
-+ break;
-+ /* Swap bytes in a half word */
-+ /* Swap bytes in a word */
-+ case 32:
-+ case 16:
-+ emit_sext(ctx, dst, dst);
-+ emit_bswap_r(ctx, dst, width);
-+ if (cpu_has_mips64r2 || cpu_has_mips64r6)
-+ emit_zext(ctx, dst);
-+ break;
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Truncate a register double word, word or half word */
-+static void emit_trunc_r64(struct jit_context *ctx, u8 dst, u32 width)
-+{
-+ switch (width) {
-+ case 64:
-+ break;
-+ /* Zero-extend a word */
-+ case 32:
-+ emit_zext(ctx, dst);
-+ break;
-+ /* Zero-extend a half word */
-+ case 16:
-+ emit(ctx, andi, dst, dst, 0xffff);
-+ break;
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Load operation: dst = *(size*)(src + off) */
-+static void emit_ldx(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 size)
-+{
-+ switch (size) {
-+ /* Load a byte */
-+ case BPF_B:
-+ emit(ctx, lbu, dst, off, src);
-+ break;
-+ /* Load a half word */
-+ case BPF_H:
-+ emit(ctx, lhu, dst, off, src);
-+ break;
-+ /* Load a word */
-+ case BPF_W:
-+ emit(ctx, lwu, dst, off, src);
-+ break;
-+ /* Load a double word */
-+ case BPF_DW:
-+ emit(ctx, ld, dst, off, src);
-+ break;
-+ }
-+ clobber_reg(ctx, dst);
-+}
-+
-+/* Store operation: *(size *)(dst + off) = src */
-+static void emit_stx(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 size)
-+{
-+ switch (size) {
-+ /* Store a byte */
-+ case BPF_B:
-+ emit(ctx, sb, src, off, dst);
-+ break;
-+ /* Store a half word */
-+ case BPF_H:
-+ emit(ctx, sh, src, off, dst);
-+ break;
-+ /* Store a word */
-+ case BPF_W:
-+ emit(ctx, sw, src, off, dst);
-+ break;
-+ /* Store a double word */
-+ case BPF_DW:
-+ emit(ctx, sd, src, off, dst);
-+ break;
-+ }
-+}
-+
-+/* Atomic read-modify-write */
-+static void emit_atomic_r64(struct jit_context *ctx,
-+ u8 dst, u8 src, s16 off, u8 code)
-+{
-+ u8 t1 = MIPS_R_T6;
-+ u8 t2 = MIPS_R_T7;
-+
-+ emit(ctx, lld, t1, off, dst);
-+ switch (code) {
-+ case BPF_ADD:
-+ emit(ctx, daddu, t2, t1, src);
-+ break;
-+ case BPF_AND:
-+ emit(ctx, and, t2, t1, src);
-+ break;
-+ case BPF_OR:
-+ emit(ctx, or, t2, t1, src);
-+ break;
-+ case BPF_XOR:
-+ emit(ctx, xor, t2, t1, src);
-+ break;
-+ }
-+ emit(ctx, scd, t2, off, dst);
-+ emit(ctx, beqz, t2, -16);
-+ emit(ctx, nop); /* Delay slot */
-+}
-+
-+/* Function call */
-+static int emit_call(struct jit_context *ctx, const struct bpf_insn *insn)
-+{
-+ u8 zx = bpf2mips64[JIT_REG_ZX];
-+ u8 tmp = MIPS_R_T6;
-+ bool fixed;
-+ u64 addr;
-+
-+ /* Decode the call address */
-+ if (bpf_jit_get_func_addr(ctx->program, insn, false,
-+ &addr, &fixed) < 0)
-+ return -1;
-+ if (!fixed)
-+ return -1;
-+
-+ /* Push caller-saved registers on stack */
-+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, 0, 0);
-+
-+ /* Emit function call */
-+ emit_mov_i64(ctx, tmp, addr);
-+ emit(ctx, jalr, MIPS_R_RA, tmp);
-+ emit(ctx, nop); /* Delay slot */
-+
-+ /* Restore caller-saved registers */
-+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, 0, 0);
-+
-+ /* Re-initialize the JIT zero-extension register if accessed */
-+ if (ctx->accessed & BIT(JIT_REG_ZX)) {
-+ emit(ctx, daddiu, zx, MIPS_R_ZERO, -1);
-+ emit(ctx, dsrl32, zx, zx, 0);
-+ }
-+
-+ clobber_reg(ctx, MIPS_R_RA);
-+ clobber_reg(ctx, MIPS_R_V0);
-+ clobber_reg(ctx, MIPS_R_V1);
-+ return 0;
-+}
-+
-+/* Function tail call */
-+static int emit_tail_call(struct jit_context *ctx)
-+{
-+ u8 ary = bpf2mips64[BPF_REG_2];
-+ u8 ind = bpf2mips64[BPF_REG_3];
-+ u8 tcc = bpf2mips64[JIT_REG_TC];
-+ u8 tmp = MIPS_R_T6;
-+ int off;
-+
-+ /*
-+ * Tail call:
-+ * eBPF R1 - function argument (context ptr), passed in a0-a1
-+ * eBPF R2 - ptr to object with array of function entry points
-+ * eBPF R3 - array index of function to be called
-+ */
-+
-+ /* if (ind >= ary->map.max_entries) goto out */
-+ off = offsetof(struct bpf_array, map.max_entries);
-+ if (off > 0x7fff)
-+ return -1;
-+ emit(ctx, lwu, tmp, off, ary); /* tmp = ary->map.max_entrs*/
-+ emit(ctx, sltu, tmp, ind, tmp); /* tmp = ind < t1 */
-+ emit(ctx, beqz, tmp, get_offset(ctx, 1)); /* PC += off(1) if tmp == 0*/
-+
-+ /* if (--TCC < 0) goto out */
-+ emit(ctx, daddiu, tcc, tcc, -1); /* tcc-- (delay slot) */
-+ emit(ctx, bltz, tcc, get_offset(ctx, 1)); /* PC += off(1) if tcc < 0 */
-+ /* (next insn delay slot) */
-+ /* prog = ary->ptrs[ind] */
-+ off = offsetof(struct bpf_array, ptrs);
-+ if (off > 0x7fff)
-+ return -1;
-+ emit(ctx, dsll, tmp, ind, 3); /* tmp = ind << 3 */
-+ emit(ctx, daddu, tmp, tmp, ary); /* tmp += ary */
-+ emit(ctx, ld, tmp, off, tmp); /* tmp = *(tmp + off) */
-+
-+ /* if (prog == 0) goto out */
-+ emit(ctx, beqz, tmp, get_offset(ctx, 1)); /* PC += off(1) if tmp == 0*/
-+ emit(ctx, nop); /* Delay slot */
-+
-+ /* func = prog->bpf_func + 8 (prologue skip offset) */
-+ off = offsetof(struct bpf_prog, bpf_func);
-+ if (off > 0x7fff)
-+ return -1;
-+ emit(ctx, ld, tmp, off, tmp); /* tmp = *(tmp + off) */
-+ emit(ctx, daddiu, tmp, tmp, JIT_TCALL_SKIP); /* tmp += skip (4) */
-+
-+ /* goto func */
-+ build_epilogue(ctx, tmp);
-+ access_reg(ctx, JIT_REG_TC);
-+ return 0;
-+}
-+
-+/*
-+ * Stack frame layout for a JITed program (stack grows down).
-+ *
-+ * Higher address : Previous stack frame :
-+ * +===========================+ <--- MIPS sp before call
-+ * | Callee-saved registers, |
-+ * | including RA and FP |
-+ * +---------------------------+ <--- eBPF FP (MIPS fp)
-+ * | Local eBPF variables |
-+ * | allocated by program |
-+ * +---------------------------+
-+ * | Reserved for caller-saved |
-+ * | registers |
-+ * Lower address +===========================+ <--- MIPS sp
-+ */
-+
-+/* Build program prologue to set up the stack and registers */
-+void build_prologue(struct jit_context *ctx)
-+{
-+ u8 fp = bpf2mips64[BPF_REG_FP];
-+ u8 tc = bpf2mips64[JIT_REG_TC];
-+ u8 zx = bpf2mips64[JIT_REG_ZX];
-+ int stack, saved, locals, reserved;
-+
-+ /*
-+ * The first instruction initializes the tail call count register.
-+ * On a tail call, the calling function jumps into the prologue
-+ * after this instruction.
-+ */
-+ emit(ctx, addiu, tc, MIPS_R_ZERO, min(MAX_TAIL_CALL_CNT + 1, 0xffff));
-+
-+ /* === Entry-point for tail calls === */
-+
-+ /*
-+ * If the eBPF frame pointer and tail call count registers were
-+ * accessed they must be preserved. Mark them as clobbered here
-+ * to save and restore them on the stack as needed.
-+ */
-+ if (ctx->accessed & BIT(BPF_REG_FP))
-+ clobber_reg(ctx, fp);
-+ if (ctx->accessed & BIT(JIT_REG_TC))
-+ clobber_reg(ctx, tc);
-+ if (ctx->accessed & BIT(JIT_REG_ZX))
-+ clobber_reg(ctx, zx);
-+
-+ /* Compute the stack space needed for callee-saved registers */
-+ saved = hweight32(ctx->clobbered & JIT_CALLEE_REGS) * sizeof(u64);
-+ saved = ALIGN(saved, MIPS_STACK_ALIGNMENT);
-+
-+ /* Stack space used by eBPF program local data */
-+ locals = ALIGN(ctx->program->aux->stack_depth, MIPS_STACK_ALIGNMENT);
-+
-+ /*
-+ * If we are emitting function calls, reserve extra stack space for
-+ * caller-saved registers needed by the JIT. The required space is
-+ * computed automatically during resource usage discovery (pass 1).
-+ */
-+ reserved = ctx->stack_used;
-+
-+ /* Allocate the stack frame */
-+ stack = ALIGN(saved + locals + reserved, MIPS_STACK_ALIGNMENT);
-+ if (stack)
-+ emit(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, -stack);
-+
-+ /* Store callee-saved registers on stack */
-+ push_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0, stack - saved);
-+
-+ /* Initialize the eBPF frame pointer if accessed */
-+ if (ctx->accessed & BIT(BPF_REG_FP))
-+ emit(ctx, daddiu, fp, MIPS_R_SP, stack - saved);
-+
-+ /* Initialize the ePF JIT zero-extension register if accessed */
-+ if (ctx->accessed & BIT(JIT_REG_ZX)) {
-+ emit(ctx, daddiu, zx, MIPS_R_ZERO, -1);
-+ emit(ctx, dsrl32, zx, zx, 0);
-+ }
-+
-+ ctx->saved_size = saved;
-+ ctx->stack_size = stack;
-+}
-+
-+/* Build the program epilogue to restore the stack and registers */
-+void build_epilogue(struct jit_context *ctx, int dest_reg)
-+{
-+ /* Restore callee-saved registers from stack */
-+ pop_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0,
-+ ctx->stack_size - ctx->saved_size);
-+
-+ /* Release the stack frame */
-+ if (ctx->stack_size)
-+ emit(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, ctx->stack_size);
-+
-+ /* Jump to return address and sign-extend the 32-bit return value */
-+ emit(ctx, jr, dest_reg);
-+ emit(ctx, sll, MIPS_R_V0, MIPS_R_V0, 0); /* Delay slot */
-+}
-+
-+/* Build one eBPF instruction */
-+int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
-+{
-+ u8 dst = bpf2mips64[insn->dst_reg];
-+ u8 src = bpf2mips64[insn->src_reg];
-+ u8 code = insn->code;
-+ s16 off = insn->off;
-+ s32 imm = insn->imm;
-+ s32 val, rel;
-+ u8 alu, jmp;
-+
-+ switch (code) {
-+ /* ALU operations */
-+ /* dst = imm */
-+ case BPF_ALU | BPF_MOV | BPF_K:
-+ emit_mov_i(ctx, dst, imm);
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = src */
-+ case BPF_ALU | BPF_MOV | BPF_X:
-+ if (imm == 1) {
-+ /* Special mov32 for zext */
-+ emit_zext(ctx, dst);
-+ } else {
-+ emit_mov_r(ctx, dst, src);
-+ emit_zext_ver(ctx, dst);
-+ }
-+ break;
-+ /* dst = -dst */
-+ case BPF_ALU | BPF_NEG:
-+ emit_sext(ctx, dst, dst);
-+ emit_alu_i(ctx, dst, 0, BPF_NEG);
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = dst & imm */
-+ /* dst = dst | imm */
-+ /* dst = dst ^ imm */
-+ /* dst = dst << imm */
-+ case BPF_ALU | BPF_OR | BPF_K:
-+ case BPF_ALU | BPF_AND | BPF_K:
-+ case BPF_ALU | BPF_XOR | BPF_K:
-+ case BPF_ALU | BPF_LSH | BPF_K:
-+ if (!valid_alu_i(BPF_OP(code), imm)) {
-+ emit_mov_i(ctx, MIPS_R_T4, imm);
-+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));
-+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
-+ emit_alu_i(ctx, dst, val, alu);
-+ }
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = dst >> imm */
-+ /* dst = dst >> imm (arithmetic) */
-+ /* dst = dst + imm */
-+ /* dst = dst - imm */
-+ /* dst = dst * imm */
-+ /* dst = dst / imm */
-+ /* dst = dst % imm */
-+ case BPF_ALU | BPF_RSH | BPF_K:
-+ case BPF_ALU | BPF_ARSH | BPF_K:
-+ case BPF_ALU | BPF_ADD | BPF_K:
-+ case BPF_ALU | BPF_SUB | BPF_K:
-+ case BPF_ALU | BPF_MUL | BPF_K:
-+ case BPF_ALU | BPF_DIV | BPF_K:
-+ case BPF_ALU | BPF_MOD | BPF_K:
-+ if (!valid_alu_i(BPF_OP(code), imm)) {
-+ emit_sext(ctx, dst, dst);
-+ emit_mov_i(ctx, MIPS_R_T4, imm);
-+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));
-+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
-+ emit_sext(ctx, dst, dst);
-+ emit_alu_i(ctx, dst, val, alu);
-+ }
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = dst & src */
-+ /* dst = dst | src */
-+ /* dst = dst ^ src */
-+ /* dst = dst << src */
-+ case BPF_ALU | BPF_AND | BPF_X:
-+ case BPF_ALU | BPF_OR | BPF_X:
-+ case BPF_ALU | BPF_XOR | BPF_X:
-+ case BPF_ALU | BPF_LSH | BPF_X:
-+ emit_alu_r(ctx, dst, src, BPF_OP(code));
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = dst >> src */
-+ /* dst = dst >> src (arithmetic) */
-+ /* dst = dst + src */
-+ /* dst = dst - src */
-+ /* dst = dst * src */
-+ /* dst = dst / src */
-+ /* dst = dst % src */
-+ case BPF_ALU | BPF_RSH | BPF_X:
-+ case BPF_ALU | BPF_ARSH | BPF_X:
-+ case BPF_ALU | BPF_ADD | BPF_X:
-+ case BPF_ALU | BPF_SUB | BPF_X:
-+ case BPF_ALU | BPF_MUL | BPF_X:
-+ case BPF_ALU | BPF_DIV | BPF_X:
-+ case BPF_ALU | BPF_MOD | BPF_X:
-+ emit_sext(ctx, dst, dst);
-+ emit_sext(ctx, MIPS_R_T4, src);
-+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));
-+ emit_zext_ver(ctx, dst);
-+ break;
-+ /* dst = imm (64-bit) */
-+ case BPF_ALU64 | BPF_MOV | BPF_K:
-+ emit_mov_i(ctx, dst, imm);
-+ break;
-+ /* dst = src (64-bit) */
-+ case BPF_ALU64 | BPF_MOV | BPF_X:
-+ emit_mov_r(ctx, dst, src);
-+ break;
-+ /* dst = -dst (64-bit) */
-+ case BPF_ALU64 | BPF_NEG:
-+ emit_alu_i64(ctx, dst, 0, BPF_NEG);
-+ break;
-+ /* dst = dst & imm (64-bit) */
-+ /* dst = dst | imm (64-bit) */
-+ /* dst = dst ^ imm (64-bit) */
-+ /* dst = dst << imm (64-bit) */
-+ /* dst = dst >> imm (64-bit) */
-+ /* dst = dst >> imm ((64-bit, arithmetic) */
-+ /* dst = dst + imm (64-bit) */
-+ /* dst = dst - imm (64-bit) */
-+ /* dst = dst * imm (64-bit) */
-+ /* dst = dst / imm (64-bit) */
-+ /* dst = dst % imm (64-bit) */
-+ case BPF_ALU64 | BPF_AND | BPF_K:
-+ case BPF_ALU64 | BPF_OR | BPF_K:
-+ case BPF_ALU64 | BPF_XOR | BPF_K:
-+ case BPF_ALU64 | BPF_LSH | BPF_K:
-+ case BPF_ALU64 | BPF_RSH | BPF_K:
-+ case BPF_ALU64 | BPF_ARSH | BPF_K:
-+ case BPF_ALU64 | BPF_ADD | BPF_K:
-+ case BPF_ALU64 | BPF_SUB | BPF_K:
-+ case BPF_ALU64 | BPF_MUL | BPF_K:
-+ case BPF_ALU64 | BPF_DIV | BPF_K:
-+ case BPF_ALU64 | BPF_MOD | BPF_K:
-+ if (!valid_alu_i(BPF_OP(code), imm)) {
-+ emit_mov_i(ctx, MIPS_R_T4, imm);
-+ emit_alu_r64(ctx, dst, MIPS_R_T4, BPF_OP(code));
-+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
-+ emit_alu_i64(ctx, dst, val, alu);
-+ }
-+ break;
-+ /* dst = dst & src (64-bit) */
-+ /* dst = dst | src (64-bit) */
-+ /* dst = dst ^ src (64-bit) */
-+ /* dst = dst << src (64-bit) */
-+ /* dst = dst >> src (64-bit) */
-+ /* dst = dst >> src (64-bit, arithmetic) */
-+ /* dst = dst + src (64-bit) */
-+ /* dst = dst - src (64-bit) */
-+ /* dst = dst * src (64-bit) */
-+ /* dst = dst / src (64-bit) */
-+ /* dst = dst % src (64-bit) */
-+ case BPF_ALU64 | BPF_AND | BPF_X:
-+ case BPF_ALU64 | BPF_OR | BPF_X:
-+ case BPF_ALU64 | BPF_XOR | BPF_X:
-+ case BPF_ALU64 | BPF_LSH | BPF_X:
-+ case BPF_ALU64 | BPF_RSH | BPF_X:
-+ case BPF_ALU64 | BPF_ARSH | BPF_X:
-+ case BPF_ALU64 | BPF_ADD | BPF_X:
-+ case BPF_ALU64 | BPF_SUB | BPF_X:
-+ case BPF_ALU64 | BPF_MUL | BPF_X:
-+ case BPF_ALU64 | BPF_DIV | BPF_X:
-+ case BPF_ALU64 | BPF_MOD | BPF_X:
-+ emit_alu_r64(ctx, dst, src, BPF_OP(code));
-+ break;
-+ /* dst = htole(dst) */
-+ /* dst = htobe(dst) */
-+ case BPF_ALU | BPF_END | BPF_FROM_LE:
-+ case BPF_ALU | BPF_END | BPF_FROM_BE:
-+ if (BPF_SRC(code) ==
-+#ifdef __BIG_ENDIAN
-+ BPF_FROM_LE
-+#else
-+ BPF_FROM_BE
-+#endif
-+ )
-+ emit_bswap_r64(ctx, dst, imm);
-+ else
-+ emit_trunc_r64(ctx, dst, imm);
-+ break;
-+ /* dst = imm64 */
-+ case BPF_LD | BPF_IMM | BPF_DW:
-+ emit_mov_i64(ctx, dst, (u32)imm | ((u64)insn[1].imm << 32));
-+ return 1;
-+ /* LDX: dst = *(size *)(src + off) */
-+ case BPF_LDX | BPF_MEM | BPF_W:
-+ case BPF_LDX | BPF_MEM | BPF_H:
-+ case BPF_LDX | BPF_MEM | BPF_B:
-+ case BPF_LDX | BPF_MEM | BPF_DW:
-+ emit_ldx(ctx, dst, src, off, BPF_SIZE(code));
-+ break;
-+ /* ST: *(size *)(dst + off) = imm */
-+ case BPF_ST | BPF_MEM | BPF_W:
-+ case BPF_ST | BPF_MEM | BPF_H:
-+ case BPF_ST | BPF_MEM | BPF_B:
-+ case BPF_ST | BPF_MEM | BPF_DW:
-+ emit_mov_i(ctx, MIPS_R_T4, imm);
-+ emit_stx(ctx, dst, MIPS_R_T4, off, BPF_SIZE(code));
-+ break;
-+ /* STX: *(size *)(dst + off) = src */
-+ case BPF_STX | BPF_MEM | BPF_W:
-+ case BPF_STX | BPF_MEM | BPF_H:
-+ case BPF_STX | BPF_MEM | BPF_B:
-+ case BPF_STX | BPF_MEM | BPF_DW:
-+ emit_stx(ctx, dst, src, off, BPF_SIZE(code));
-+ break;
-+ /* Speculation barrier */
-+ case BPF_ST | BPF_NOSPEC:
-+ break;
-+ /* Atomics */
-+ case BPF_STX | BPF_XADD | BPF_W:
-+ case BPF_STX | BPF_XADD | BPF_DW:
-+ switch (imm) {
-+ case BPF_ADD:
-+ case BPF_AND:
-+ case BPF_OR:
-+ case BPF_XOR:
-+ if (BPF_SIZE(code) == BPF_DW) {
-+ emit_atomic_r64(ctx, dst, src, off, imm);
-+ } else { /* 32-bit, no fetch */
-+ emit_sext(ctx, MIPS_R_T4, src);
-+ emit_atomic_r(ctx, dst, MIPS_R_T4, off, imm);
-+ }
-+ break;
-+ default:
-+ goto notyet;
-+ }
-+ break;
-+ /* PC += off if dst == src */
-+ /* PC += off if dst != src */
-+ /* PC += off if dst & src */
-+ /* PC += off if dst > src */
-+ /* PC += off if dst >= src */
-+ /* PC += off if dst < src */
-+ /* PC += off if dst <= src */
-+ /* PC += off if dst > src (signed) */
-+ /* PC += off if dst >= src (signed) */
-+ /* PC += off if dst < src (signed) */
-+ /* PC += off if dst <= src (signed) */
-+ case BPF_JMP32 | BPF_JEQ | BPF_X:
-+ case BPF_JMP32 | BPF_JNE | BPF_X:
-+ case BPF_JMP32 | BPF_JSET | BPF_X:
-+ case BPF_JMP32 | BPF_JGT | BPF_X:
-+ case BPF_JMP32 | BPF_JGE | BPF_X:
-+ case BPF_JMP32 | BPF_JLT | BPF_X:
-+ case BPF_JMP32 | BPF_JLE | BPF_X:
-+ case BPF_JMP32 | BPF_JSGT | BPF_X:
-+ case BPF_JMP32 | BPF_JSGE | BPF_X:
-+ case BPF_JMP32 | BPF_JSLT | BPF_X:
-+ case BPF_JMP32 | BPF_JSLE | BPF_X:
-+ if (off == 0)
-+ break;
-+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel);
-+ emit_sext(ctx, MIPS_R_T4, dst); /* Sign-extended dst */
-+ emit_sext(ctx, MIPS_R_T5, src); /* Sign-extended src */
-+ emit_jmp_r(ctx, MIPS_R_T4, MIPS_R_T5, rel, jmp);
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off if dst == imm */
-+ /* PC += off if dst != imm */
-+ /* PC += off if dst & imm */
-+ /* PC += off if dst > imm */
-+ /* PC += off if dst >= imm */
-+ /* PC += off if dst < imm */
-+ /* PC += off if dst <= imm */
-+ /* PC += off if dst > imm (signed) */
-+ /* PC += off if dst >= imm (signed) */
-+ /* PC += off if dst < imm (signed) */
-+ /* PC += off if dst <= imm (signed) */
-+ case BPF_JMP32 | BPF_JEQ | BPF_K:
-+ case BPF_JMP32 | BPF_JNE | BPF_K:
-+ case BPF_JMP32 | BPF_JSET | BPF_K:
-+ case BPF_JMP32 | BPF_JGT | BPF_K:
-+ case BPF_JMP32 | BPF_JGE | BPF_K:
-+ case BPF_JMP32 | BPF_JLT | BPF_K:
-+ case BPF_JMP32 | BPF_JLE | BPF_K:
-+ case BPF_JMP32 | BPF_JSGT | BPF_K:
-+ case BPF_JMP32 | BPF_JSGE | BPF_K:
-+ case BPF_JMP32 | BPF_JSLT | BPF_K:
-+ case BPF_JMP32 | BPF_JSLE | BPF_K:
-+ if (off == 0)
-+ break;
-+ setup_jmp_i(ctx, imm, 32, BPF_OP(code), off, &jmp, &rel);
-+ emit_sext(ctx, MIPS_R_T4, dst); /* Sign-extended dst */
-+ if (valid_jmp_i(jmp, imm)) {
-+ emit_jmp_i(ctx, MIPS_R_T4, imm, rel, jmp);
-+ } else {
-+ /* Move large immediate to register, sign-extended */
-+ emit_mov_i(ctx, MIPS_R_T5, imm);
-+ emit_jmp_r(ctx, MIPS_R_T4, MIPS_R_T5, rel, jmp);
-+ }
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off if dst == src */
-+ /* PC += off if dst != src */
-+ /* PC += off if dst & src */
-+ /* PC += off if dst > src */
-+ /* PC += off if dst >= src */
-+ /* PC += off if dst < src */
-+ /* PC += off if dst <= src */
-+ /* PC += off if dst > src (signed) */
-+ /* PC += off if dst >= src (signed) */
-+ /* PC += off if dst < src (signed) */
-+ /* PC += off if dst <= src (signed) */
-+ case BPF_JMP | BPF_JEQ | BPF_X:
-+ case BPF_JMP | BPF_JNE | BPF_X:
-+ case BPF_JMP | BPF_JSET | BPF_X:
-+ case BPF_JMP | BPF_JGT | BPF_X:
-+ case BPF_JMP | BPF_JGE | BPF_X:
-+ case BPF_JMP | BPF_JLT | BPF_X:
-+ case BPF_JMP | BPF_JLE | BPF_X:
-+ case BPF_JMP | BPF_JSGT | BPF_X:
-+ case BPF_JMP | BPF_JSGE | BPF_X:
-+ case BPF_JMP | BPF_JSLT | BPF_X:
-+ case BPF_JMP | BPF_JSLE | BPF_X:
-+ if (off == 0)
-+ break;
-+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel);
-+ emit_jmp_r(ctx, dst, src, rel, jmp);
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off if dst == imm */
-+ /* PC += off if dst != imm */
-+ /* PC += off if dst & imm */
-+ /* PC += off if dst > imm */
-+ /* PC += off if dst >= imm */
-+ /* PC += off if dst < imm */
-+ /* PC += off if dst <= imm */
-+ /* PC += off if dst > imm (signed) */
-+ /* PC += off if dst >= imm (signed) */
-+ /* PC += off if dst < imm (signed) */
-+ /* PC += off if dst <= imm (signed) */
-+ case BPF_JMP | BPF_JEQ | BPF_K:
-+ case BPF_JMP | BPF_JNE | BPF_K:
-+ case BPF_JMP | BPF_JSET | BPF_K:
-+ case BPF_JMP | BPF_JGT | BPF_K:
-+ case BPF_JMP | BPF_JGE | BPF_K:
-+ case BPF_JMP | BPF_JLT | BPF_K:
-+ case BPF_JMP | BPF_JLE | BPF_K:
-+ case BPF_JMP | BPF_JSGT | BPF_K:
-+ case BPF_JMP | BPF_JSGE | BPF_K:
-+ case BPF_JMP | BPF_JSLT | BPF_K:
-+ case BPF_JMP | BPF_JSLE | BPF_K:
-+ if (off == 0)
-+ break;
-+ setup_jmp_i(ctx, imm, 64, BPF_OP(code), off, &jmp, &rel);
-+ if (valid_jmp_i(jmp, imm)) {
-+ emit_jmp_i(ctx, dst, imm, rel, jmp);
-+ } else {
-+ /* Move large immediate to register */
-+ emit_mov_i(ctx, MIPS_R_T4, imm);
-+ emit_jmp_r(ctx, dst, MIPS_R_T4, rel, jmp);
-+ }
-+ if (finish_jmp(ctx, jmp, off) < 0)
-+ goto toofar;
-+ break;
-+ /* PC += off */
-+ case BPF_JMP | BPF_JA:
-+ if (off == 0)
-+ break;
-+ if (emit_ja(ctx, off) < 0)
-+ goto toofar;
-+ break;
-+ /* Tail call */
-+ case BPF_JMP | BPF_TAIL_CALL:
-+ if (emit_tail_call(ctx) < 0)
-+ goto invalid;
-+ break;
-+ /* Function call */
-+ case BPF_JMP | BPF_CALL:
-+ if (emit_call(ctx, insn) < 0)
-+ goto invalid;
-+ break;
-+ /* Function return */
-+ case BPF_JMP | BPF_EXIT:
-+ /*
-+ * Optimization: when last instruction is EXIT
-+ * simply continue to epilogue.
-+ */
-+ if (ctx->bpf_index == ctx->program->len - 1)
-+ break;
-+ if (emit_exit(ctx) < 0)
-+ goto toofar;
-+ break;
-+
-+ default:
-+invalid:
-+ pr_err_once("unknown opcode %02x\n", code);
-+ return -EINVAL;
-+notyet:
-+ pr_info_once("*** NOT YET: opcode %02x ***\n", code);
-+ return -EFAULT;
-+toofar:
-+ pr_info_once("*** TOO FAR: jump at %u opcode %02x ***\n",
-+ ctx->bpf_index, code);
-+ return -E2BIG;
-+ }
-+ return 0;
-+}
diff --git a/target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch b/target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch
deleted file mode 100644
index 63553ebe58..0000000000
--- a/target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Date: Tue, 5 Oct 2021 18:54:06 +0200
-Subject: [PATCH] mips: bpf: Add JIT workarounds for CPU errata
-
-This patch adds workarounds for the following CPU errata to the MIPS
-eBPF JIT, if enabled in the kernel configuration.
-
- - R10000 ll/sc weak ordering
- - Loongson-3 ll/sc weak ordering
- - Loongson-2F jump hang
-
-The Loongson-2F nop errata is implemented in uasm, which the JIT uses,
-so no additional mitigations are needed for that.
-
-Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
----
-
---- a/arch/mips/net/bpf_jit_comp.c
-+++ b/arch/mips/net/bpf_jit_comp.c
-@@ -404,6 +404,7 @@ void emit_alu_r(struct jit_context *ctx,
- /* Atomic read-modify-write (32-bit) */
- void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code)
- {
-+ LLSC_sync(ctx);
- emit(ctx, ll, MIPS_R_T9, off, dst);
- switch (code) {
- case BPF_ADD:
-@@ -420,18 +421,19 @@ void emit_atomic_r(struct jit_context *c
- break;
- }
- emit(ctx, sc, MIPS_R_T8, off, dst);
-- emit(ctx, beqz, MIPS_R_T8, -16);
-+ emit(ctx, LLSC_beqz, MIPS_R_T8, -16 - LLSC_offset);
- emit(ctx, nop); /* Delay slot */
- }
-
- /* Atomic compare-and-exchange (32-bit) */
- void emit_cmpxchg_r(struct jit_context *ctx, u8 dst, u8 src, u8 res, s16 off)
- {
-+ LLSC_sync(ctx);
- emit(ctx, ll, MIPS_R_T9, off, dst);
- emit(ctx, bne, MIPS_R_T9, res, 12);
- emit(ctx, move, MIPS_R_T8, src); /* Delay slot */
- emit(ctx, sc, MIPS_R_T8, off, dst);
-- emit(ctx, beqz, MIPS_R_T8, -20);
-+ emit(ctx, LLSC_beqz, MIPS_R_T8, -20 - LLSC_offset);
- emit(ctx, move, res, MIPS_R_T9); /* Delay slot */
- clobber_reg(ctx, res);
- }
---- a/arch/mips/net/bpf_jit_comp.h
-+++ b/arch/mips/net/bpf_jit_comp.h
-@@ -87,7 +87,7 @@ struct jit_context {
- };
-
- /* Emit the instruction if the JIT memory space has been allocated */
--#define emit(ctx, func, ...) \
-+#define __emit(ctx, func, ...) \
- do { \
- if ((ctx)->target != NULL) { \
- u32 *p = &(ctx)->target[ctx->jit_index]; \
-@@ -95,6 +95,30 @@ do { \
- } \
- (ctx)->jit_index++; \
- } while (0)
-+#define emit(...) __emit(__VA_ARGS__)
-+
-+/* Workaround for R10000 ll/sc errata */
-+#ifdef CONFIG_WAR_R10000
-+#define LLSC_beqz beqzl
-+#else
-+#define LLSC_beqz beqz
-+#endif
-+
-+/* Workaround for Loongson-3 ll/sc errata */
-+#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS
-+#define LLSC_sync(ctx) emit(ctx, sync, 0)
-+#define LLSC_offset 4
-+#else
-+#define LLSC_sync(ctx)
-+#define LLSC_offset 0
-+#endif
-+
-+/* Workaround for Loongson-2F jump errata */
-+#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
-+#define JALR_MASK 0xffffffffcfffffffULL
-+#else
-+#define JALR_MASK (~0ULL)
-+#endif
-
- /*
- * Mark a BPF register as accessed, it needs to be
---- a/arch/mips/net/bpf_jit_comp64.c
-+++ b/arch/mips/net/bpf_jit_comp64.c
-@@ -375,6 +375,7 @@ static void emit_atomic_r64(struct jit_c
- u8 t1 = MIPS_R_T6;
- u8 t2 = MIPS_R_T7;
-
-+ LLSC_sync(ctx);
- emit(ctx, lld, t1, off, dst);
- switch (code) {
- case BPF_ADD:
-@@ -391,7 +392,7 @@ static void emit_atomic_r64(struct jit_c
- break;
- }
- emit(ctx, scd, t2, off, dst);
-- emit(ctx, beqz, t2, -16);
-+ emit(ctx, LLSC_beqz, t2, -16 - LLSC_offset);
- emit(ctx, nop); /* Delay slot */
- }
-
-@@ -414,7 +415,7 @@ static int emit_call(struct jit_context
- push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, 0, 0);
-
- /* Emit function call */
-- emit_mov_i64(ctx, tmp, addr);
-+ emit_mov_i64(ctx, tmp, addr & JALR_MASK);
- emit(ctx, jalr, MIPS_R_RA, tmp);
- emit(ctx, nop); /* Delay slot */
-
diff --git a/target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch b/target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch
deleted file mode 100644
index 24e4e9052b..0000000000
--- a/target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Date: Tue, 5 Oct 2021 18:54:07 +0200
-Subject: [PATCH] mips: bpf: Enable eBPF JITs
-
-This patch enables the new eBPF JITs for 32-bit and 64-bit MIPS. It also
-disables the old cBPF JIT to so cBPF programs are converted to use the
-new JIT.
-
-Workarounds for R4000 CPU errata are not implemented by the JIT, so the
-JIT is disabled if any of those workarounds are configured.
-
-Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
----
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -3431,6 +3431,7 @@ S: Supported
- F: arch/arm64/net/
-
- BPF JIT for MIPS (32-BIT AND 64-BIT)
-+M: Johan Almbladh <johan.almbladh@anyfinetworks.com>
- M: Paul Burton <paulburton@kernel.org>
- L: netdev@vger.kernel.org
- L: bpf@vger.kernel.org
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -58,7 +58,6 @@ config MIPS
- select HAVE_ARCH_TRACEHOOK
- select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES
- select HAVE_ASM_MODVERSIONS
-- select HAVE_CBPF_JIT if !64BIT && !CPU_MICROMIPS
- select HAVE_CONTEXT_TRACKING
- select HAVE_TIF_NOHZ
- select HAVE_C_RECORDMCOUNT
-@@ -66,7 +65,10 @@ config MIPS
- select HAVE_DEBUG_STACKOVERFLOW
- select HAVE_DMA_CONTIGUOUS
- select HAVE_DYNAMIC_FTRACE
-- select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2
-+ select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
-+ !CPU_DADDI_WORKAROUNDS && \
-+ !CPU_R4000_WORKAROUNDS && \
-+ !CPU_R4400_WORKAROUNDS
- select HAVE_EXIT_THREAD
- select HAVE_FAST_GUP
- select HAVE_FTRACE_MCOUNT_RECORD
---- a/arch/mips/net/Makefile
-+++ b/arch/mips/net/Makefile
-@@ -2,9 +2,10 @@
- # MIPS networking code
-
- obj-$(CONFIG_MIPS_CBPF_JIT) += bpf_jit.o bpf_jit_asm.o
-+obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp.o
-
- ifeq ($(CONFIG_32BIT),y)
-- obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp.o bpf_jit_comp32.o
-+ obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp32.o
- else
-- obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o
-+ obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp64.o
- endif
diff --git a/target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch b/target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch
deleted file mode 100644
index e25c336831..0000000000
--- a/target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch
+++ /dev/null
@@ -1,387 +0,0 @@
-From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
-Date: Tue, 5 Oct 2021 18:54:08 +0200
-Subject: [PATCH] mips: bpf: Remove old BPF JIT implementations
-
-This patch removes the old 32-bit cBPF and 64-bit eBPF JIT implementations.
-They are replaced by a new eBPF implementation that supports both 32-bit
-and 64-bit MIPS CPUs.
-
-Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
----
- delete mode 100644 arch/mips/net/bpf_jit.c
- delete mode 100644 arch/mips/net/bpf_jit.h
- delete mode 100644 arch/mips/net/bpf_jit_asm.S
- delete mode 100644 arch/mips/net/ebpf_jit.c
-
---- a/arch/mips/net/bpf_jit.h
-+++ /dev/null
-@@ -1,81 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0-only */
--/*
-- * Just-In-Time compiler for BPF filters on MIPS
-- *
-- * Copyright (c) 2014 Imagination Technologies Ltd.
-- * Author: Markos Chandras <markos.chandras@imgtec.com>
-- */
--
--#ifndef BPF_JIT_MIPS_OP_H
--#define BPF_JIT_MIPS_OP_H
--
--/* Registers used by JIT */
--#define MIPS_R_ZERO 0
--#define MIPS_R_V0 2
--#define MIPS_R_A0 4
--#define MIPS_R_A1 5
--#define MIPS_R_T4 12
--#define MIPS_R_T5 13
--#define MIPS_R_T6 14
--#define MIPS_R_T7 15
--#define MIPS_R_S0 16
--#define MIPS_R_S1 17
--#define MIPS_R_S2 18
--#define MIPS_R_S3 19
--#define MIPS_R_S4 20
--#define MIPS_R_S5 21
--#define MIPS_R_S6 22
--#define MIPS_R_S7 23
--#define MIPS_R_SP 29
--#define MIPS_R_RA 31
--
--/* Conditional codes */
--#define MIPS_COND_EQ 0x1
--#define MIPS_COND_GE (0x1 << 1)
--#define MIPS_COND_GT (0x1 << 2)
--#define MIPS_COND_NE (0x1 << 3)
--#define MIPS_COND_ALL (0x1 << 4)
--/* Conditionals on X register or K immediate */
--#define MIPS_COND_X (0x1 << 5)
--#define MIPS_COND_K (0x1 << 6)
--
--#define r_ret MIPS_R_V0
--
--/*
-- * Use 2 scratch registers to avoid pipeline interlocks.
-- * There is no overhead during epilogue and prologue since
-- * any of the $s0-$s6 registers will only be preserved if
-- * they are going to actually be used.
-- */
--#define r_skb_hl MIPS_R_S0 /* skb header length */
--#define r_skb_data MIPS_R_S1 /* skb actual data */
--#define r_off MIPS_R_S2
--#define r_A MIPS_R_S3
--#define r_X MIPS_R_S4
--#define r_skb MIPS_R_S5
--#define r_M MIPS_R_S6
--#define r_skb_len MIPS_R_S7
--#define r_s0 MIPS_R_T4 /* scratch reg 1 */
--#define r_s1 MIPS_R_T5 /* scratch reg 2 */
--#define r_tmp_imm MIPS_R_T6 /* No need to preserve this */
--#define r_tmp MIPS_R_T7 /* No need to preserve this */
--#define r_zero MIPS_R_ZERO
--#define r_sp MIPS_R_SP
--#define r_ra MIPS_R_RA
--
--#ifndef __ASSEMBLY__
--
--/* Declare ASM helpers */
--
--#define DECLARE_LOAD_FUNC(func) \
-- extern u8 func(unsigned long *skb, int offset); \
-- extern u8 func##_negative(unsigned long *skb, int offset); \
-- extern u8 func##_positive(unsigned long *skb, int offset)
--
--DECLARE_LOAD_FUNC(sk_load_word);
--DECLARE_LOAD_FUNC(sk_load_half);
--DECLARE_LOAD_FUNC(sk_load_byte);
--
--#endif
--
--#endif /* BPF_JIT_MIPS_OP_H */
---- a/arch/mips/net/bpf_jit_asm.S
-+++ /dev/null
-@@ -1,285 +0,0 @@
--/*
-- * bpf_jib_asm.S: Packet/header access helper functions for MIPS/MIPS64 BPF
-- * compiler.
-- *
-- * Copyright (C) 2015 Imagination Technologies Ltd.
-- * Author: Markos Chandras <markos.chandras@imgtec.com>
-- *
-- * This program is free software; you can redistribute it and/or modify it
-- * under the terms of the GNU General Public License as published by the
-- * Free Software Foundation; version 2 of the License.
-- */
--
--#include <asm/asm.h>
--#include <asm/isa-rev.h>
--#include <asm/regdef.h>
--#include "bpf_jit.h"
--
--/* ABI
-- *
-- * r_skb_hl skb header length
-- * r_skb_data skb data
-- * r_off(a1) offset register
-- * r_A BPF register A
-- * r_X PF register X
-- * r_skb(a0) *skb
-- * r_M *scratch memory
-- * r_skb_le skb length
-- * r_s0 Scratch register 0
-- * r_s1 Scratch register 1
-- *
-- * On entry:
-- * a0: *skb
-- * a1: offset (imm or imm + X)
-- *
-- * All non-BPF-ABI registers are free for use. On return, we only
-- * care about r_ret. The BPF-ABI registers are assumed to remain
-- * unmodified during the entire filter operation.
-- */
--
--#define skb a0
--#define offset a1
--#define SKF_LL_OFF (-0x200000) /* Can't include linux/filter.h in assembly */
--
-- /* We know better :) so prevent assembler reordering etc */
-- .set noreorder
--
--#define is_offset_negative(TYPE) \
-- /* If offset is negative we have more work to do */ \
-- slti t0, offset, 0; \
-- bgtz t0, bpf_slow_path_##TYPE##_neg; \
-- /* Be careful what follows in DS. */
--
--#define is_offset_in_header(SIZE, TYPE) \
-- /* Reading from header? */ \
-- addiu $r_s0, $r_skb_hl, -SIZE; \
-- slt t0, $r_s0, offset; \
-- bgtz t0, bpf_slow_path_##TYPE; \
--
--LEAF(sk_load_word)
-- is_offset_negative(word)
--FEXPORT(sk_load_word_positive)
-- is_offset_in_header(4, word)
-- /* Offset within header boundaries */
-- PTR_ADDU t1, $r_skb_data, offset
-- .set reorder
-- lw $r_A, 0(t1)
-- .set noreorder
--#ifdef CONFIG_CPU_LITTLE_ENDIAN
--# if MIPS_ISA_REV >= 2
-- wsbh t0, $r_A
-- rotr $r_A, t0, 16
--# else
-- sll t0, $r_A, 24
-- srl t1, $r_A, 24
-- srl t2, $r_A, 8
-- or t0, t0, t1
-- andi t2, t2, 0xff00
-- andi t1, $r_A, 0xff00
-- or t0, t0, t2
-- sll t1, t1, 8
-- or $r_A, t0, t1
--# endif
--#endif
-- jr $r_ra
-- move $r_ret, zero
-- END(sk_load_word)
--
--LEAF(sk_load_half)
-- is_offset_negative(half)
--FEXPORT(sk_load_half_positive)
-- is_offset_in_header(2, half)
-- /* Offset within header boundaries */
-- PTR_ADDU t1, $r_skb_data, offset
-- lhu $r_A, 0(t1)
--#ifdef CONFIG_CPU_LITTLE_ENDIAN
--# if MIPS_ISA_REV >= 2
-- wsbh $r_A, $r_A
--# else
-- sll t0, $r_A, 8
-- srl t1, $r_A, 8
-- andi t0, t0, 0xff00
-- or $r_A, t0, t1
--# endif
--#endif
-- jr $r_ra
-- move $r_ret, zero
-- END(sk_load_half)
--
--LEAF(sk_load_byte)
-- is_offset_negative(byte)
--FEXPORT(sk_load_byte_positive)
-- is_offset_in_header(1, byte)
-- /* Offset within header boundaries */
-- PTR_ADDU t1, $r_skb_data, offset
-- lbu $r_A, 0(t1)
-- jr $r_ra
-- move $r_ret, zero
-- END(sk_load_byte)
--
--/*
-- * call skb_copy_bits:
-- * (prototype in linux/skbuff.h)
-- *
-- * int skb_copy_bits(sk_buff *skb, int offset, void *to, int len)
-- *
-- * o32 mandates we leave 4 spaces for argument registers in case
-- * the callee needs to use them. Even though we don't care about
-- * the argument registers ourselves, we need to allocate that space
-- * to remain ABI compliant since the callee may want to use that space.
-- * We also allocate 2 more spaces for $r_ra and our return register (*to).
-- *
-- * n64 is a bit different. The *caller* will allocate the space to preserve
-- * the arguments. So in 64-bit kernels, we allocate the 4-arg space for no
-- * good reason but it does not matter that much really.
-- *
-- * (void *to) is returned in r_s0
-- *
-- */
--#ifdef CONFIG_CPU_LITTLE_ENDIAN
--#define DS_OFFSET(SIZE) (4 * SZREG)
--#else
--#define DS_OFFSET(SIZE) ((4 * SZREG) + (4 - SIZE))
--#endif
--#define bpf_slow_path_common(SIZE) \
-- /* Quick check. Are we within reasonable boundaries? */ \
-- LONG_ADDIU $r_s1, $r_skb_len, -SIZE; \
-- sltu $r_s0, offset, $r_s1; \
-- beqz $r_s0, fault; \
-- /* Load 4th argument in DS */ \
-- LONG_ADDIU a3, zero, SIZE; \
-- PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
-- PTR_LA t0, skb_copy_bits; \
-- PTR_S $r_ra, (5 * SZREG)($r_sp); \
-- /* Assign low slot to a2 */ \
-- PTR_ADDIU a2, $r_sp, DS_OFFSET(SIZE); \
-- jalr t0; \
-- /* Reset our destination slot (DS but it's ok) */ \
-- INT_S zero, (4 * SZREG)($r_sp); \
-- /* \
-- * skb_copy_bits returns 0 on success and -EFAULT \
-- * on error. Our data live in a2. Do not bother with \
-- * our data if an error has been returned. \
-- */ \
-- /* Restore our frame */ \
-- PTR_L $r_ra, (5 * SZREG)($r_sp); \
-- INT_L $r_s0, (4 * SZREG)($r_sp); \
-- bltz v0, fault; \
-- PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
-- move $r_ret, zero; \
--
--NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp)
-- bpf_slow_path_common(4)
--#ifdef CONFIG_CPU_LITTLE_ENDIAN
--# if MIPS_ISA_REV >= 2
-- wsbh t0, $r_s0
-- jr $r_ra
-- rotr $r_A, t0, 16
--# else
-- sll t0, $r_s0, 24
-- srl t1, $r_s0, 24
-- srl t2, $r_s0, 8
-- or t0, t0, t1
-- andi t2, t2, 0xff00
-- andi t1, $r_s0, 0xff00
-- or t0, t0, t2
-- sll t1, t1, 8
-- jr $r_ra
-- or $r_A, t0, t1
--# endif
--#else
-- jr $r_ra
-- move $r_A, $r_s0
--#endif
--
-- END(bpf_slow_path_word)
--
--NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp)
-- bpf_slow_path_common(2)
--#ifdef CONFIG_CPU_LITTLE_ENDIAN
--# if MIPS_ISA_REV >= 2
-- jr $r_ra
-- wsbh $r_A, $r_s0
--# else
-- sll t0, $r_s0, 8
-- andi t1, $r_s0, 0xff00
-- andi t0, t0, 0xff00
-- srl t1, t1, 8
-- jr $r_ra
-- or $r_A, t0, t1
--# endif
--#else
-- jr $r_ra
-- move $r_A, $r_s0
--#endif
--
-- END(bpf_slow_path_half)
--
--NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp)
-- bpf_slow_path_common(1)
-- jr $r_ra
-- move $r_A, $r_s0
--
-- END(bpf_slow_path_byte)
--
--/*
-- * Negative entry points
-- */
-- .macro bpf_is_end_of_data
-- li t0, SKF_LL_OFF
-- /* Reading link layer data? */
-- slt t1, offset, t0
-- bgtz t1, fault
-- /* Be careful what follows in DS. */
-- .endm
--/*
-- * call skb_copy_bits:
-- * (prototype in linux/filter.h)
-- *
-- * void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb,
-- * int k, unsigned int size)
-- *
-- * see above (bpf_slow_path_common) for ABI restrictions
-- */
--#define bpf_negative_common(SIZE) \
-- PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
-- PTR_LA t0, bpf_internal_load_pointer_neg_helper; \
-- PTR_S $r_ra, (5 * SZREG)($r_sp); \
-- jalr t0; \
-- li a2, SIZE; \
-- PTR_L $r_ra, (5 * SZREG)($r_sp); \
-- /* Check return pointer */ \
-- beqz v0, fault; \
-- PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
-- /* Preserve our pointer */ \
-- move $r_s0, v0; \
-- /* Set return value */ \
-- move $r_ret, zero; \
--
--bpf_slow_path_word_neg:
-- bpf_is_end_of_data
--NESTED(sk_load_word_negative, (6 * SZREG), $r_sp)
-- bpf_negative_common(4)
-- jr $r_ra
-- lw $r_A, 0($r_s0)
-- END(sk_load_word_negative)
--
--bpf_slow_path_half_neg:
-- bpf_is_end_of_data
--NESTED(sk_load_half_negative, (6 * SZREG), $r_sp)
-- bpf_negative_common(2)
-- jr $r_ra
-- lhu $r_A, 0($r_s0)
-- END(sk_load_half_negative)
--
--bpf_slow_path_byte_neg:
-- bpf_is_end_of_data
--NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp)
-- bpf_negative_common(1)
-- jr $r_ra
-- lbu $r_A, 0($r_s0)
-- END(sk_load_byte_negative)
--
--fault:
-- jr $r_ra
-- addiu $r_ret, zero, 1
diff --git a/target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch b/target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch
deleted file mode 100644
index 4d544a30f5..0000000000
--- a/target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From 5287acc6f097c0c18e54401b611a877a3083b68c Mon Sep 17 00:00:00 2001
-From: Martin KaFai Lau <kafai@fb.com>
-Date: Wed, 16 Mar 2022 10:38:23 -0700
-Subject: [PATCH 1/3] bpf: selftests: Add helpers to directly use the capget
- and capset syscall
-
-After upgrading to the newer libcap (>= 2.60),
-the libcap commit aca076443591 ("Make cap_t operations thread safe.")
-added a "__u8 mutex;" to the "struct _cap_struct". It caused a few byte
-shift that breaks the assumption made in the "struct libcap" definition
-in test_verifier.c.
-
-The bpf selftest usage only needs to enable and disable the effective
-caps of the running task. It is easier to directly syscall the
-capget and capset instead. It can also remove the libcap
-library dependency.
-
-The cap_helpers.{c,h} is added. One __u64 is used for all CAP_*
-bits instead of two __u32.
-
-Signed-off-by: Martin KaFai Lau <kafai@fb.com>
-Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/20220316173823.2036955-1-kafai@fb.com
----
- tools/testing/selftests/bpf/cap_helpers.c | 67 +++++++++++++++++++++++
- tools/testing/selftests/bpf/cap_helpers.h | 19 +++++++
- 2 files changed, 86 insertions(+)
- create mode 100644 tools/testing/selftests/bpf/cap_helpers.c
- create mode 100644 tools/testing/selftests/bpf/cap_helpers.h
-
---- /dev/null
-+++ b/tools/testing/selftests/bpf/cap_helpers.c
-@@ -0,0 +1,67 @@
-+// SPDX-License-Identifier: GPL-2.0
-+#include "cap_helpers.h"
-+
-+/* Avoid including <sys/capability.h> from the libcap-devel package,
-+ * so directly declare them here and use them from glibc.
-+ */
-+int capget(cap_user_header_t header, cap_user_data_t data);
-+int capset(cap_user_header_t header, const cap_user_data_t data);
-+
-+int cap_enable_effective(__u64 caps, __u64 *old_caps)
-+{
-+ struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
-+ struct __user_cap_header_struct hdr = {
-+ .version = _LINUX_CAPABILITY_VERSION_3,
-+ };
-+ __u32 cap0 = caps;
-+ __u32 cap1 = caps >> 32;
-+ int err;
-+
-+ err = capget(&hdr, data);
-+ if (err)
-+ return err;
-+
-+ if (old_caps)
-+ *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;
-+
-+ if ((data[0].effective & cap0) == cap0 &&
-+ (data[1].effective & cap1) == cap1)
-+ return 0;
-+
-+ data[0].effective |= cap0;
-+ data[1].effective |= cap1;
-+ err = capset(&hdr, data);
-+ if (err)
-+ return err;
-+
-+ return 0;
-+}
-+
-+int cap_disable_effective(__u64 caps, __u64 *old_caps)
-+{
-+ struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
-+ struct __user_cap_header_struct hdr = {
-+ .version = _LINUX_CAPABILITY_VERSION_3,
-+ };
-+ __u32 cap0 = caps;
-+ __u32 cap1 = caps >> 32;
-+ int err;
-+
-+ err = capget(&hdr, data);
-+ if (err)
-+ return err;
-+
-+ if (old_caps)
-+ *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;
-+
-+ if (!(data[0].effective & cap0) && !(data[1].effective & cap1))
-+ return 0;
-+
-+ data[0].effective &= ~cap0;
-+ data[1].effective &= ~cap1;
-+ err = capset(&hdr, data);
-+ if (err)
-+ return err;
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/tools/testing/selftests/bpf/cap_helpers.h
-@@ -0,0 +1,19 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __CAP_HELPERS_H
-+#define __CAP_HELPERS_H
-+
-+#include <linux/types.h>
-+#include <linux/capability.h>
-+
-+#ifndef CAP_PERFMON
-+#define CAP_PERFMON 38
-+#endif
-+
-+#ifndef CAP_BPF
-+#define CAP_BPF 39
-+#endif
-+
-+int cap_enable_effective(__u64 caps, __u64 *old_caps);
-+int cap_disable_effective(__u64 caps, __u64 *old_caps);
-+
-+#endif
diff --git a/target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch b/target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch
deleted file mode 100644
index cc60b54340..0000000000
--- a/target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-From 847a6b7ee906be874f0cae279c8de902a7d3f092 Mon Sep 17 00:00:00 2001
-From: Martin KaFai Lau <kafai@fb.com>
-Date: Wed, 16 Mar 2022 10:38:29 -0700
-Subject: [PATCH 2/3] bpf: selftests: Remove libcap usage from test_verifier
-
-This patch removes the libcap usage from test_verifier.
-The cap_*_effective() helpers added in the earlier patch are
-used instead.
-
-Signed-off-by: Martin KaFai Lau <kafai@fb.com>
-Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/20220316173829.2038682-1-kafai@fb.com
----
- tools/testing/selftests/bpf/Makefile | 31 +++++---
- tools/testing/selftests/bpf/test_verifier.c | 88 ++++++---------------
- 2 files changed, 46 insertions(+), 73 deletions(-)
-
---- a/tools/testing/selftests/bpf/Makefile
-+++ b/tools/testing/selftests/bpf/Makefile
-@@ -189,16 +189,27 @@ TEST_GEN_PROGS_EXTENDED += $(DEFAULT_BPF
-
- $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/test_stub.o $(BPFOBJ)
-
--$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
--$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
--$(OUTPUT)/test_sock: cgroup_helpers.c
--$(OUTPUT)/test_sock_addr: cgroup_helpers.c
--$(OUTPUT)/test_sockmap: cgroup_helpers.c
--$(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c
--$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c
--$(OUTPUT)/test_cgroup_storage: cgroup_helpers.c
--$(OUTPUT)/test_sock_fields: cgroup_helpers.c
--$(OUTPUT)/test_sysctl: cgroup_helpers.c
-+CGROUP_HELPERS := $(OUTPUT)/cgroup_helpers.o
-+TESTING_HELPERS := $(OUTPUT)/testing_helpers.o
-+TRACE_HELPERS := $(OUTPUT)/trace_helpers.o
-+CAP_HELPERS := $(OUTPUT)/cap_helpers.o
-+
-+$(OUTPUT)/test_dev_cgroup: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_skb_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_sock: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_sock_addr: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_sockmap: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_tcpnotify_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) $(TRACE_HELPERS)
-+$(OUTPUT)/get_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_cgroup_storage: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_sock_fields: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_sysctl: $(CGROUP_HELPERS) $(TESTING_HELPERS)
-+$(OUTPUT)/test_tag: $(TESTING_HELPERS)
-+$(OUTPUT)/test_lirc_mode2_user: $(TESTING_HELPERS)
-+$(OUTPUT)/xdping: $(TESTING_HELPERS)
-+$(OUTPUT)/flow_dissector_load: $(TESTING_HELPERS)
-+$(OUTPUT)/test_maps: $(TESTING_HELPERS)
-+$(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS)
-
- BPFTOOL ?= $(DEFAULT_BPFTOOL)
- $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \
---- a/tools/testing/selftests/bpf/test_verifier.c
-+++ b/tools/testing/selftests/bpf/test_verifier.c
-@@ -22,8 +22,6 @@
- #include <limits.h>
- #include <assert.h>
-
--#include <sys/capability.h>
--
- #include <linux/unistd.h>
- #include <linux/filter.h>
- #include <linux/bpf_perf_event.h>
-@@ -43,6 +41,7 @@
- # endif
- #endif
- #include "bpf_rlimit.h"
-+#include "cap_helpers.h"
- #include "bpf_rand.h"
- #include "bpf_util.h"
- #include "test_btf.h"
-@@ -59,6 +58,10 @@
- #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
- #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
-
-+/* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */
-+#define ADMIN_CAPS (1ULL << CAP_NET_ADMIN | \
-+ 1ULL << CAP_PERFMON | \
-+ 1ULL << CAP_BPF)
- #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
- static bool unpriv_disabled = false;
- static int skips;
-@@ -940,47 +943,19 @@ struct libcap {
-
- static int set_admin(bool admin)
- {
-- cap_t caps;
-- /* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */
-- const cap_value_t cap_net_admin = CAP_NET_ADMIN;
-- const cap_value_t cap_sys_admin = CAP_SYS_ADMIN;
-- struct libcap *cap;
-- int ret = -1;
--
-- caps = cap_get_proc();
-- if (!caps) {
-- perror("cap_get_proc");
-- return -1;
-- }
-- cap = (struct libcap *)caps;
-- if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_sys_admin, CAP_CLEAR)) {
-- perror("cap_set_flag clear admin");
-- goto out;
-- }
-- if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_admin,
-- admin ? CAP_SET : CAP_CLEAR)) {
-- perror("cap_set_flag set_or_clear net");
-- goto out;
-- }
-- /* libcap is likely old and simply ignores CAP_BPF and CAP_PERFMON,
-- * so update effective bits manually
-- */
-+ int err;
-+
- if (admin) {
-- cap->data[1].effective |= 1 << (38 /* CAP_PERFMON */ - 32);
-- cap->data[1].effective |= 1 << (39 /* CAP_BPF */ - 32);
-+ err = cap_enable_effective(ADMIN_CAPS, NULL);
-+ if (err)
-+ perror("cap_enable_effective(ADMIN_CAPS)");
- } else {
-- cap->data[1].effective &= ~(1 << (38 - 32));
-- cap->data[1].effective &= ~(1 << (39 - 32));
-+ err = cap_disable_effective(ADMIN_CAPS, NULL);
-+ if (err)
-+ perror("cap_disable_effective(ADMIN_CAPS)");
- }
-- if (cap_set_proc(caps)) {
-- perror("cap_set_proc");
-- goto out;
-- }
-- ret = 0;
--out:
-- if (cap_free(caps))
-- perror("cap_free");
-- return ret;
-+
-+ return err;
- }
-
- static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val,
-@@ -1246,31 +1221,18 @@ fail_log:
-
- static bool is_admin(void)
- {
-- cap_flag_value_t net_priv = CAP_CLEAR;
-- bool perfmon_priv = false;
-- bool bpf_priv = false;
-- struct libcap *cap;
-- cap_t caps;
--
--#ifdef CAP_IS_SUPPORTED
-- if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
-- perror("cap_get_flag");
-- return false;
-- }
--#endif
-- caps = cap_get_proc();
-- if (!caps) {
-- perror("cap_get_proc");
-+ __u64 caps;
-+
-+ /* The test checks for finer cap as CAP_NET_ADMIN,
-+ * CAP_PERFMON, and CAP_BPF instead of CAP_SYS_ADMIN.
-+ * Thus, disable CAP_SYS_ADMIN at the beginning.
-+ */
-+ if (cap_disable_effective(1ULL << CAP_SYS_ADMIN, &caps)) {
-+ perror("cap_disable_effective(CAP_SYS_ADMIN)");
- return false;
- }
-- cap = (struct libcap *)caps;
-- bpf_priv = cap->data[1].effective & (1 << (39/* CAP_BPF */ - 32));
-- perfmon_priv = cap->data[1].effective & (1 << (38/* CAP_PERFMON */ - 32));
-- if (cap_get_flag(caps, CAP_NET_ADMIN, CAP_EFFECTIVE, &net_priv))
-- perror("cap_get_flag NET");
-- if (cap_free(caps))
-- perror("cap_free");
-- return bpf_priv && perfmon_priv && net_priv == CAP_SET;
-+
-+ return (caps & ADMIN_CAPS) == ADMIN_CAPS;
- }
-
- static void get_unpriv_disabled()
diff --git a/target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch b/target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch
deleted file mode 100644
index 9badba7f8e..0000000000
--- a/target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 1ac00fea13c576e2b13dabf9a72ad3034e3bb804 Mon Sep 17 00:00:00 2001
-From: Martin KaFai Lau <kafai@fb.com>
-Date: Wed, 16 Mar 2022 10:38:35 -0700
-Subject: [PATCH 3/3] bpf: selftests: Remove libcap usage from test_progs
-
-This patch removes the libcap usage from test_progs.
-bind_perm.c is the only user. cap_*_effective() helpers added in the
-earlier patch are directly used instead.
-
-No other selftest binary is using libcap, so '-lcap' is also removed
-from the Makefile.
-
-Signed-off-by: Martin KaFai Lau <kafai@fb.com>
-Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-Reviewed-by: Stanislav Fomichev <sdf@google.com>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/20220316173835.2039334-1-kafai@fb.com
----
- tools/testing/selftests/bpf/Makefile | 5 ++-
- .../selftests/bpf/prog_tests/bind_perm.c | 44 ++++---------------
- 2 files changed, 11 insertions(+), 38 deletions(-)
-
---- a/tools/testing/selftests/bpf/Makefile
-+++ b/tools/testing/selftests/bpf/Makefile
-@@ -26,7 +26,7 @@ CFLAGS += -g -O0 -rdynamic -Wall $(GENFL
- -I$(TOOLSINCDIR) -I$(APIDIR) -I$(OUTPUT) \
- -Dbpf_prog_load=bpf_prog_test_load \
- -Dbpf_load_program=bpf_test_load_program
--LDLIBS += -lcap -lelf -lz -lrt -lpthread
-+LDLIBS += -lelf -lz -lrt -lpthread
-
- # Silence some warnings when compiled with clang
- ifneq ($(LLVM),)
-@@ -471,7 +471,8 @@ TRUNNER_TESTS_DIR := prog_tests
- TRUNNER_BPF_PROGS_DIR := progs
- TRUNNER_EXTRA_SOURCES := test_progs.c cgroup_helpers.c trace_helpers.c \
- network_helpers.c testing_helpers.c \
-- btf_helpers.c flow_dissector_load.h
-+ btf_helpers.c flow_dissector_load.h \
-+ cap_helpers.c
- TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \
- ima_setup.sh \
- $(wildcard progs/btf_dump_test_case_*.c)
---- a/tools/testing/selftests/bpf/prog_tests/bind_perm.c
-+++ b/tools/testing/selftests/bpf/prog_tests/bind_perm.c
-@@ -4,9 +4,9 @@
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
--#include <sys/capability.h>
-
- #include "test_progs.h"
-+#include "cap_helpers.h"
- #include "bind_perm.skel.h"
-
- static int duration;
-@@ -49,41 +49,11 @@ close_socket:
- close(fd);
- }
-
--bool cap_net_bind_service(cap_flag_value_t flag)
--{
-- const cap_value_t cap_net_bind_service = CAP_NET_BIND_SERVICE;
-- cap_flag_value_t original_value;
-- bool was_effective = false;
-- cap_t caps;
--
-- caps = cap_get_proc();
-- if (CHECK(!caps, "cap_get_proc", "errno %d", errno))
-- goto free_caps;
--
-- if (CHECK(cap_get_flag(caps, CAP_NET_BIND_SERVICE, CAP_EFFECTIVE,
-- &original_value),
-- "cap_get_flag", "errno %d", errno))
-- goto free_caps;
--
-- was_effective = (original_value == CAP_SET);
--
-- if (CHECK(cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_bind_service,
-- flag),
-- "cap_set_flag", "errno %d", errno))
-- goto free_caps;
--
-- if (CHECK(cap_set_proc(caps), "cap_set_proc", "errno %d", errno))
-- goto free_caps;
--
--free_caps:
-- CHECK(cap_free(caps), "cap_free", "errno %d", errno);
-- return was_effective;
--}
--
- void test_bind_perm(void)
- {
-- bool cap_was_effective;
-+ const __u64 net_bind_svc_cap = 1ULL << CAP_NET_BIND_SERVICE;
- struct bind_perm *skel;
-+ __u64 old_caps = 0;
- int cgroup_fd;
-
- if (create_netns())
-@@ -105,7 +75,8 @@ void test_bind_perm(void)
- if (!ASSERT_OK_PTR(skel, "bind_v6_prog"))
- goto close_skeleton;
-
-- cap_was_effective = cap_net_bind_service(CAP_CLEAR);
-+ ASSERT_OK(cap_disable_effective(net_bind_svc_cap, &old_caps),
-+ "cap_disable_effective");
-
- try_bind(AF_INET, 110, EACCES);
- try_bind(AF_INET6, 110, EACCES);
-@@ -113,8 +84,9 @@ void test_bind_perm(void)
- try_bind(AF_INET, 111, 0);
- try_bind(AF_INET6, 111, 0);
-
-- if (cap_was_effective)
-- cap_net_bind_service(CAP_SET);
-+ if (old_caps & net_bind_svc_cap)
-+ ASSERT_OK(cap_enable_effective(net_bind_svc_cap, NULL),
-+ "cap_enable_effective");
-
- close_skeleton:
- bind_perm__destroy(skel);
diff --git a/target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch b/target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch
deleted file mode 100644
index 819cc292e8..0000000000
--- a/target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 815f0e738a8d5663a02350e2580706829144a722 Mon Sep 17 00:00:00 2001
-From: Horatiu Vultur <horatiu.vultur@microchip.com>
-Date: Wed, 3 Nov 2021 09:50:59 +0100
-Subject: [PATCH] clk: gate: Add devm_clk_hw_register_gate()
-
-Add devm_clk_hw_register_gate() - devres-managed version of
-clk_hw_register_gate()
-
-Suggested-by: Stephen Boyd <sboyd@kernel.org>
-Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
-Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
-Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
-Link: https://lore.kernel.org/r/20211103085102.1656081-2-horatiu.vultur@microchip.com
----
- drivers/clk/clk-gate.c | 35 +++++++++++++++++++++++++++++++++++
- include/linux/clk-provider.h | 23 +++++++++++++++++++++++
- 2 files changed, 58 insertions(+)
-
---- a/drivers/clk/clk-gate.c
-+++ b/drivers/clk/clk-gate.c
-@@ -7,6 +7,7 @@
- */
-
- #include <linux/clk-provider.h>
-+#include <linux/device.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/io.h>
-@@ -222,3 +223,37 @@ void clk_hw_unregister_gate(struct clk_h
- kfree(gate);
- }
- EXPORT_SYMBOL_GPL(clk_hw_unregister_gate);
-+
-+static void devm_clk_hw_release_gate(struct device *dev, void *res)
-+{
-+ clk_hw_unregister_gate(*(struct clk_hw **)res);
-+}
-+
-+struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
-+ struct device_node *np, const char *name,
-+ const char *parent_name, const struct clk_hw *parent_hw,
-+ const struct clk_parent_data *parent_data,
-+ unsigned long flags,
-+ void __iomem *reg, u8 bit_idx,
-+ u8 clk_gate_flags, spinlock_t *lock)
-+{
-+ struct clk_hw **ptr, *hw;
-+
-+ ptr = devres_alloc(devm_clk_hw_release_gate, sizeof(*ptr), GFP_KERNEL);
-+ if (!ptr)
-+ return ERR_PTR(-ENOMEM);
-+
-+ hw = __clk_hw_register_gate(dev, np, name, parent_name, parent_hw,
-+ parent_data, flags, reg, bit_idx,
-+ clk_gate_flags, lock);
-+
-+ if (!IS_ERR(hw)) {
-+ *ptr = hw;
-+ devres_add(dev, ptr);
-+ } else {
-+ devres_free(ptr);
-+ }
-+
-+ return hw;
-+}
-+EXPORT_SYMBOL_GPL(__devm_clk_hw_register_gate);
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -517,6 +517,13 @@ struct clk_hw *__clk_hw_register_gate(st
- unsigned long flags,
- void __iomem *reg, u8 bit_idx,
- u8 clk_gate_flags, spinlock_t *lock);
-+struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
-+ struct device_node *np, const char *name,
-+ const char *parent_name, const struct clk_hw *parent_hw,
-+ const struct clk_parent_data *parent_data,
-+ unsigned long flags,
-+ void __iomem *reg, u8 bit_idx,
-+ u8 clk_gate_flags, spinlock_t *lock);
- struct clk *clk_register_gate(struct device *dev, const char *name,
- const char *parent_name, unsigned long flags,
- void __iomem *reg, u8 bit_idx,
-@@ -571,6 +578,22 @@ struct clk *clk_register_gate(struct dev
- __clk_hw_register_gate((dev), NULL, (name), NULL, NULL, (parent_data), \
- (flags), (reg), (bit_idx), \
- (clk_gate_flags), (lock))
-+/**
-+ * devm_clk_hw_register_gate - register a gate clock with the clock framework
-+ * @dev: device that is registering this clock
-+ * @name: name of this clock
-+ * @parent_name: name of this clock's parent
-+ * @flags: framework-specific flags for this clock
-+ * @reg: register address to control gating of this clock
-+ * @bit_idx: which bit in the register controls gating of this clock
-+ * @clk_gate_flags: gate-specific flags for this clock
-+ * @lock: shared register lock for this clock
-+ */
-+#define devm_clk_hw_register_gate(dev, name, parent_name, flags, reg, bit_idx,\
-+ clk_gate_flags, lock) \
-+ __devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
-+ NULL, (flags), (reg), (bit_idx), \
-+ (clk_gate_flags), (lock))
- void clk_unregister_gate(struct clk *clk);
- void clk_hw_unregister_gate(struct clk_hw *hw);
- int clk_gate_is_enabled(struct clk_hw *hw);
diff --git a/target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch b/target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch
deleted file mode 100644
index 7de3cbbda0..0000000000
--- a/target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0dc0da881b4574d1e04a079ab2ea75da61f5ad2e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 11 Mar 2022 10:32:33 +0100
-Subject: [PATCH] tty: serial: bcm63xx: use more precise Kconfig symbol
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Patches lowering SERIAL_BCM63XX dependencies led to a discussion and
-documentation change regarding "depends" usage. Adjust Kconfig entry to
-match current guidelines. Make this symbol available for relevant
-architectures only.
-
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Ref: f35a07f92616 ("tty: serial: bcm63xx: lower driver dependencies")
-Ref: 18084e435ff6 ("Documentation/kbuild: Document platform dependency practises")
-Link: https://lore.kernel.org/r/20220311093233.10012-1-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/tty/serial/Kconfig | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/tty/serial/Kconfig
-+++ b/drivers/tty/serial/Kconfig
-@@ -1098,7 +1098,8 @@ config SERIAL_TIMBERDALE
- config SERIAL_BCM63XX
- tristate "Broadcom BCM63xx/BCM33xx UART support"
- select SERIAL_CORE
-- depends on COMMON_CLK
-+ depends on ARCH_BCM4908 || ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC || COMPILE_TEST
-+ default ARCH_BCM4908 || ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC
- help
- This enables the driver for the onchip UART core found on
- the following chipsets:
diff --git a/target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch b/target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch
deleted file mode 100644
index caec8db5d6..0000000000
--- a/target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From cdbc4e3399ed8cdcf234a85f7a2482b622379e82 Mon Sep 17 00:00:00 2001
-From: Connor O'Brien <connoro@google.com>
-Date: Wed, 12 Jan 2022 00:25:03 +0000
-Subject: [PATCH] tools/resolve_btfids: Build with host flags
-
-resolve_btfids is built using $(HOSTCC) and $(HOSTLD) but does not
-pick up the corresponding flags. As a result, host-specific settings
-(such as a sysroot specified via HOSTCFLAGS=--sysroot=..., or a linker
-specified via HOSTLDFLAGS=-fuse-ld=...) will not be respected.
-
-Fix this by setting CFLAGS to KBUILD_HOSTCFLAGS and LDFLAGS to
-KBUILD_HOSTLDFLAGS.
-
-Also pass the cflags through to libbpf via EXTRA_CFLAGS to ensure that
-the host libbpf is built with flags consistent with resolve_btfids.
-
-Signed-off-by: Connor O'Brien <connoro@google.com>
-Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
-Acked-by: Song Liu <songliubraving@fb.com>
-Link: https://lore.kernel.org/bpf/20220112002503.115968-1-connoro@google.com
-(cherry picked from commit 0e3a1c902ffb56e9fe4416f0cd382c97b09ecbf6)
-Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
----
- tools/bpf/resolve_btfids/Makefile | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/tools/bpf/resolve_btfids/Makefile
-+++ b/tools/bpf/resolve_btfids/Makefile
-@@ -23,6 +23,8 @@ CC = $(HOSTCC)
- LD = $(HOSTLD)
- ARCH = $(HOSTARCH)
- RM ?= rm
-+CFLAGS := $(KBUILD_HOSTCFLAGS)
-+LDFLAGS := $(KBUILD_HOSTLDFLAGS)
-
- OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/
-
-@@ -45,9 +47,9 @@ $(SUBCMDOBJ): fixdep FORCE | $(OUTPUT)/l
- $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@)
-
- $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf
-- $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@)
-+ $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(abspath $(dir $@))/ EXTRA_CFLAGS="$(CFLAGS)" $(abspath $@)
-
--CFLAGS := -g \
-+CFLAGS += -g \
- -I$(srctree)/tools/include \
- -I$(srctree)/tools/include/uapi \
- -I$(LIBBPF_SRC) \
diff --git a/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch b/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch
deleted file mode 100644
index d1bef74f32..0000000000
--- a/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch
+++ /dev/null
@@ -1,997 +0,0 @@
-From a77725a9a3c5924e2fd4cd5b3557dd92a8e46f87 Mon Sep 17 00:00:00 2001
-From: Rob Herring <robh@kernel.org>
-Date: Mon, 25 Oct 2021 11:05:45 -0500
-Subject: [PATCH 1/1] scripts/dtc: Update to upstream version
- v1.6.1-19-g0a3a9d3449c8
-
-This adds the following commits from upstream:
-
-0a3a9d3449c8 checks: Add an interrupt-map check
-8fd24744e361 checks: Ensure '#interrupt-cells' only exists in interrupt providers
-d8d1a9a77863 checks: Drop interrupt provider '#address-cells' check
-52a16fd72824 checks: Make interrupt_provider check dependent on interrupts_extended_is_cell
-37fd700685da treesource: Maintain phandle label/path on output
-e33ce1d6a8c7 flattree: Use '\n', not ';' to separate asm pseudo-ops
-d24cc189dca6 asm: Use assembler macros instead of cpp macros
-ff3a30c115ad asm: Use .asciz and .ascii instead of .string
-5eb5927d81ee fdtdump: fix -Werror=int-to-pointer-cast
-0869f8269161 libfdt: Add ALIGNMENT error string
-69595a167f06 checks: Fix bus-range check
-72d09e2682a4 Makefile: add -Wsign-compare to warning options
-b587787ef388 checks: Fix signedness comparisons warnings
-69bed6c2418f dtc: Wrap phandle validity check
-910221185560 fdtget: Fix signedness comparisons warnings
-d966f08fcd21 tests: Fix signedness comparisons warnings
-ecfb438c07fa dtc: Fix signedness comparisons warnings: pointer diff
-5bec74a6d135 dtc: Fix signedness comparisons warnings: reservednum
-24e7f511fd4a fdtdump: Fix signedness comparisons warnings
-b6910bec1161 Bump version to v1.6.1
-21d61d18f968 Fix CID 1461557
-4c2ef8f4d14c checks: Introduce is_multiple_of()
-e59ca36fb70e Make handling of cpp line information more tolerant
-0c3fd9b6aceb checks: Drop interrupt_cells_is_cell check
-6b3081abc4ac checks: Add check_is_cell() for all phandle+arg properties
-2dffc192a77f yamltree: Remove marker ordering dependency
-61e513439e40 pylibfdt: Rework "avoid unused variable warning" lines
-c8bddd106095 tests: add a positive gpio test case
-ad4abfadb687 checks: replace strstr and strrchr with strends
-09c6a6e88718 dtc.h: add strends for suffix matching
-9bb9b8d0b4a0 checks: tigthen up nr-gpios prop exception
-b07b62ee3342 libfdt: Add FDT alignment check to fdt_check_header()
-a2def5479950 libfdt: Check that the root-node name is empty
-4ca61f84dc21 libfdt: Check that there is only one root node
-34d708249a91 dtc: Remove -O dtbo support
-8e7ff260f755 libfdt: Fix a possible "unchecked return value" warning
-88875268c05c checks: Warn on node-name and property name being the same
-9d2279e7e6ee checks: Change node-name check to match devicetree spec
-f527c867a8c6 util: limit gnu_printf format attribute to gcc >= 4.4.0
-
-Reviewed-by: Frank Rowand <frank.rowand@sony.com>
-Tested-by: Frank Rowand <frank.rowand@sony.com>
-Signed-off-by: Rob Herring <robh@kernel.org>
----
- scripts/dtc/checks.c | 222 ++++++++++++++++++++++--------
- scripts/dtc/dtc-lexer.l | 2 +-
- scripts/dtc/dtc.c | 6 +-
- scripts/dtc/dtc.h | 40 +++++-
- scripts/dtc/flattree.c | 11 +-
- scripts/dtc/libfdt/fdt.c | 4 +
- scripts/dtc/libfdt/fdt_rw.c | 18 ++-
- scripts/dtc/libfdt/fdt_strerror.c | 1 +
- scripts/dtc/libfdt/libfdt.h | 7 +
- scripts/dtc/livetree.c | 6 +-
- scripts/dtc/treesource.c | 48 +++----
- scripts/dtc/util.h | 6 +-
- scripts/dtc/version_gen.h | 2 +-
- scripts/dtc/yamltree.c | 16 ++-
- 14 files changed, 275 insertions(+), 114 deletions(-)
-
---- a/scripts/dtc/checks.c
-+++ b/scripts/dtc/checks.c
-@@ -143,6 +143,14 @@ static void check_nodes_props(struct che
- check_nodes_props(c, dti, child);
- }
-
-+static bool is_multiple_of(int multiple, int divisor)
-+{
-+ if (divisor == 0)
-+ return multiple == 0;
-+ else
-+ return (multiple % divisor) == 0;
-+}
-+
- static bool run_check(struct check *c, struct dt_info *dti)
- {
- struct node *dt = dti->dt;
-@@ -297,19 +305,20 @@ ERROR(duplicate_property_names, check_du
- #define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
- #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- #define DIGITS "0123456789"
--#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
-+#define NODECHARS LOWERCASE UPPERCASE DIGITS ",._+-@"
-+#define PROPCHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
- #define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-"
-
- static void check_node_name_chars(struct check *c, struct dt_info *dti,
- struct node *node)
- {
-- int n = strspn(node->name, c->data);
-+ size_t n = strspn(node->name, c->data);
-
- if (n < strlen(node->name))
- FAIL(c, dti, node, "Bad character '%c' in node name",
- node->name[n]);
- }
--ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
-+ERROR(node_name_chars, check_node_name_chars, NODECHARS);
-
- static void check_node_name_chars_strict(struct check *c, struct dt_info *dti,
- struct node *node)
-@@ -330,6 +339,20 @@ static void check_node_name_format(struc
- }
- ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
-
-+static void check_node_name_vs_property_name(struct check *c,
-+ struct dt_info *dti,
-+ struct node *node)
-+{
-+ if (!node->parent)
-+ return;
-+
-+ if (get_property(node->parent, node->name)) {
-+ FAIL(c, dti, node, "node name and property name conflict");
-+ }
-+}
-+WARNING(node_name_vs_property_name, check_node_name_vs_property_name,
-+ NULL, &node_name_chars);
-+
- static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
- struct node *node)
- {
-@@ -363,14 +386,14 @@ static void check_property_name_chars(st
- struct property *prop;
-
- for_each_property(node, prop) {
-- int n = strspn(prop->name, c->data);
-+ size_t n = strspn(prop->name, c->data);
-
- if (n < strlen(prop->name))
- FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name",
- prop->name[n]);
- }
- }
--ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
-+ERROR(property_name_chars, check_property_name_chars, PROPCHARS);
-
- static void check_property_name_chars_strict(struct check *c,
- struct dt_info *dti,
-@@ -380,7 +403,7 @@ static void check_property_name_chars_st
-
- for_each_property(node, prop) {
- const char *name = prop->name;
-- int n = strspn(name, c->data);
-+ size_t n = strspn(name, c->data);
-
- if (n == strlen(prop->name))
- continue;
-@@ -497,7 +520,7 @@ static cell_t check_phandle_prop(struct
-
- phandle = propval_cell(prop);
-
-- if ((phandle == 0) || (phandle == -1)) {
-+ if (!phandle_is_valid(phandle)) {
- FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property",
- phandle, prop->name);
- return 0;
-@@ -556,7 +579,7 @@ static void check_name_properties(struct
- if (!prop)
- return; /* No name property, that's fine */
-
-- if ((prop->val.len != node->basenamelen+1)
-+ if ((prop->val.len != node->basenamelen + 1U)
- || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
- FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead"
- " of base node name)", prop->val.val);
-@@ -657,7 +680,6 @@ ERROR(omit_unused_nodes, fixup_omit_unus
- */
- WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells");
- WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells");
--WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
-
- WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
- WARNING_IF_NOT_STRING(model_is_string, "model");
-@@ -672,8 +694,7 @@ static void check_names_is_string_list(s
- struct property *prop;
-
- for_each_property(node, prop) {
-- const char *s = strrchr(prop->name, '-');
-- if (!s || !streq(s, "-names"))
-+ if (!strends(prop->name, "-names"))
- continue;
-
- c->data = prop->name;
-@@ -753,7 +774,7 @@ static void check_reg_format(struct chec
- size_cells = node_size_cells(node->parent);
- entrylen = (addr_cells + size_cells) * sizeof(cell_t);
-
-- if (!entrylen || (prop->val.len % entrylen) != 0)
-+ if (!is_multiple_of(prop->val.len, entrylen))
- FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) "
- "(#address-cells == %d, #size-cells == %d)",
- prop->val.len, addr_cells, size_cells);
-@@ -794,7 +815,7 @@ static void check_ranges_format(struct c
- "#size-cells (%d) differs from %s (%d)",
- ranges, c_size_cells, node->parent->fullpath,
- p_size_cells);
-- } else if ((prop->val.len % entrylen) != 0) {
-+ } else if (!is_multiple_of(prop->val.len, entrylen)) {
- FAIL_PROP(c, dti, node, prop, "\"%s\" property has invalid length (%d bytes) "
- "(parent #address-cells == %d, child #address-cells == %d, "
- "#size-cells == %d)", ranges, prop->val.len,
-@@ -871,7 +892,7 @@ static void check_pci_device_bus_num(str
- } else {
- cells = (cell_t *)prop->val.val;
- min_bus = fdt32_to_cpu(cells[0]);
-- max_bus = fdt32_to_cpu(cells[0]);
-+ max_bus = fdt32_to_cpu(cells[1]);
- }
- if ((bus_num < min_bus) || (bus_num > max_bus))
- FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)",
-@@ -1367,9 +1388,9 @@ static void check_property_phandle_args(
- const struct provider *provider)
- {
- struct node *root = dti->dt;
-- int cell, cellsize = 0;
-+ unsigned int cell, cellsize = 0;
-
-- if (prop->val.len % sizeof(cell_t)) {
-+ if (!is_multiple_of(prop->val.len, sizeof(cell_t))) {
- FAIL_PROP(c, dti, node, prop,
- "property size (%d) is invalid, expected multiple of %zu",
- prop->val.len, sizeof(cell_t));
-@@ -1379,14 +1400,14 @@ static void check_property_phandle_args(
- for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
- struct node *provider_node;
- struct property *cellprop;
-- int phandle;
-+ cell_t phandle;
-
- phandle = propval_cell_n(prop, cell);
- /*
- * Some bindings use a cell value 0 or -1 to skip over optional
- * entries when each index position has a specific definition.
- */
-- if (phandle == 0 || phandle == -1) {
-+ if (!phandle_is_valid(phandle)) {
- /* Give up if this is an overlay with external references */
- if (dti->dtsflags & DTSF_PLUGIN)
- break;
-@@ -1452,7 +1473,8 @@ static void check_provider_cells_propert
- }
- #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
- static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
-- WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
-+ WARNING_IF_NOT_CELL(nm##_is_cell, cells_name); \
-+ WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &nm##_is_cell, &phandle_references);
-
- WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
- WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
-@@ -1473,24 +1495,17 @@ WARNING_PROPERTY_PHANDLE_CELLS(thermal_s
-
- static bool prop_is_gpio(struct property *prop)
- {
-- char *str;
--
- /*
- * *-gpios and *-gpio can appear in property names,
- * so skip over any false matches (only one known ATM)
- */
-- if (strstr(prop->name, "nr-gpio"))
-+ if (strends(prop->name, ",nr-gpios"))
- return false;
-
-- str = strrchr(prop->name, '-');
-- if (str)
-- str++;
-- else
-- str = prop->name;
-- if (!(streq(str, "gpios") || streq(str, "gpio")))
-- return false;
--
-- return true;
-+ return strends(prop->name, "-gpios") ||
-+ streq(prop->name, "gpios") ||
-+ strends(prop->name, "-gpio") ||
-+ streq(prop->name, "gpio");
- }
-
- static void check_gpios_property(struct check *c,
-@@ -1525,13 +1540,10 @@ static void check_deprecated_gpio_proper
- struct property *prop;
-
- for_each_property(node, prop) {
-- char *str;
--
- if (!prop_is_gpio(prop))
- continue;
-
-- str = strstr(prop->name, "gpio");
-- if (!streq(str, "gpio"))
-+ if (!strends(prop->name, "gpio"))
- continue;
-
- FAIL_PROP(c, dti, node, prop,
-@@ -1561,21 +1573,106 @@ static void check_interrupt_provider(str
- struct node *node)
- {
- struct property *prop;
-+ bool irq_provider = node_is_interrupt_provider(node);
-
-- if (!node_is_interrupt_provider(node))
-+ prop = get_property(node, "#interrupt-cells");
-+ if (irq_provider && !prop) {
-+ FAIL(c, dti, node,
-+ "Missing '#interrupt-cells' in interrupt provider");
- return;
-+ }
-
-- prop = get_property(node, "#interrupt-cells");
-- if (!prop)
-+ if (!irq_provider && prop) {
- FAIL(c, dti, node,
-- "Missing #interrupt-cells in interrupt provider");
-+ "'#interrupt-cells' found, but node is not an interrupt provider");
-+ return;
-+ }
-+}
-+WARNING(interrupt_provider, check_interrupt_provider, NULL, &interrupts_extended_is_cell);
-
-- prop = get_property(node, "#address-cells");
-- if (!prop)
-+static void check_interrupt_map(struct check *c,
-+ struct dt_info *dti,
-+ struct node *node)
-+{
-+ struct node *root = dti->dt;
-+ struct property *prop, *irq_map_prop;
-+ size_t cellsize, cell, map_cells;
-+
-+ irq_map_prop = get_property(node, "interrupt-map");
-+ if (!irq_map_prop)
-+ return;
-+
-+ if (node->addr_cells < 0) {
- FAIL(c, dti, node,
-- "Missing #address-cells in interrupt provider");
-+ "Missing '#address-cells' in interrupt-map provider");
-+ return;
-+ }
-+ cellsize = node_addr_cells(node);
-+ cellsize += propval_cell(get_property(node, "#interrupt-cells"));
-+
-+ prop = get_property(node, "interrupt-map-mask");
-+ if (prop && (prop->val.len != (cellsize * sizeof(cell_t))))
-+ FAIL_PROP(c, dti, node, prop,
-+ "property size (%d) is invalid, expected %zu",
-+ prop->val.len, cellsize * sizeof(cell_t));
-+
-+ if (!is_multiple_of(irq_map_prop->val.len, sizeof(cell_t))) {
-+ FAIL_PROP(c, dti, node, irq_map_prop,
-+ "property size (%d) is invalid, expected multiple of %zu",
-+ irq_map_prop->val.len, sizeof(cell_t));
-+ return;
-+ }
-+
-+ map_cells = irq_map_prop->val.len / sizeof(cell_t);
-+ for (cell = 0; cell < map_cells; ) {
-+ struct node *provider_node;
-+ struct property *cellprop;
-+ int phandle;
-+ size_t parent_cellsize;
-+
-+ if ((cell + cellsize) >= map_cells) {
-+ FAIL_PROP(c, dti, node, irq_map_prop,
-+ "property size (%d) too small, expected > %zu",
-+ irq_map_prop->val.len, (cell + cellsize) * sizeof(cell_t));
-+ break;
-+ }
-+ cell += cellsize;
-+
-+ phandle = propval_cell_n(irq_map_prop, cell);
-+ if (!phandle_is_valid(phandle)) {
-+ /* Give up if this is an overlay with external references */
-+ if (!(dti->dtsflags & DTSF_PLUGIN))
-+ FAIL_PROP(c, dti, node, irq_map_prop,
-+ "Cell %zu is not a phandle(%d)",
-+ cell, phandle);
-+ break;
-+ }
-+
-+ provider_node = get_node_by_phandle(root, phandle);
-+ if (!provider_node) {
-+ FAIL_PROP(c, dti, node, irq_map_prop,
-+ "Could not get phandle(%d) node for (cell %zu)",
-+ phandle, cell);
-+ break;
-+ }
-+
-+ cellprop = get_property(provider_node, "#interrupt-cells");
-+ if (cellprop) {
-+ parent_cellsize = propval_cell(cellprop);
-+ } else {
-+ FAIL(c, dti, node, "Missing property '#interrupt-cells' in node %s or bad phandle (referred from interrupt-map[%zu])",
-+ provider_node->fullpath, cell);
-+ break;
-+ }
-+
-+ cellprop = get_property(provider_node, "#address-cells");
-+ if (cellprop)
-+ parent_cellsize += propval_cell(cellprop);
-+
-+ cell += 1 + parent_cellsize;
-+ }
- }
--WARNING(interrupt_provider, check_interrupt_provider, NULL);
-+WARNING(interrupt_map, check_interrupt_map, NULL, &phandle_references, &addr_size_cells, &interrupt_provider);
-
- static void check_interrupts_property(struct check *c,
- struct dt_info *dti,
-@@ -1584,13 +1681,13 @@ static void check_interrupts_property(st
- struct node *root = dti->dt;
- struct node *irq_node = NULL, *parent = node;
- struct property *irq_prop, *prop = NULL;
-- int irq_cells, phandle;
-+ cell_t irq_cells, phandle;
-
- irq_prop = get_property(node, "interrupts");
- if (!irq_prop)
- return;
-
-- if (irq_prop->val.len % sizeof(cell_t))
-+ if (!is_multiple_of(irq_prop->val.len, sizeof(cell_t)))
- FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu",
- irq_prop->val.len, sizeof(cell_t));
-
-@@ -1603,7 +1700,7 @@ static void check_interrupts_property(st
- prop = get_property(parent, "interrupt-parent");
- if (prop) {
- phandle = propval_cell(prop);
-- if ((phandle == 0) || (phandle == -1)) {
-+ if (!phandle_is_valid(phandle)) {
- /* Give up if this is an overlay with
- * external references */
- if (dti->dtsflags & DTSF_PLUGIN)
-@@ -1639,7 +1736,7 @@ static void check_interrupts_property(st
- }
-
- irq_cells = propval_cell(prop);
-- if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
-+ if (!is_multiple_of(irq_prop->val.len, irq_cells * sizeof(cell_t))) {
- FAIL_PROP(c, dti, node, prop,
- "size is (%d), expected multiple of %d",
- irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)));
-@@ -1750,7 +1847,7 @@ WARNING(graph_port, check_graph_port, NU
- static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti,
- struct node *endpoint)
- {
-- int phandle;
-+ cell_t phandle;
- struct node *node;
- struct property *prop;
-
-@@ -1760,7 +1857,7 @@ static struct node *get_remote_endpoint(
-
- phandle = propval_cell(prop);
- /* Give up if this is an overlay with external references */
-- if (phandle == 0 || phandle == -1)
-+ if (!phandle_is_valid(phandle))
- return NULL;
-
- node = get_node_by_phandle(dti->dt, phandle);
-@@ -1796,7 +1893,7 @@ WARNING(graph_endpoint, check_graph_endp
- static struct check *check_table[] = {
- &duplicate_node_names, &duplicate_property_names,
- &node_name_chars, &node_name_format, &property_name_chars,
-- &name_is_string, &name_properties,
-+ &name_is_string, &name_properties, &node_name_vs_property_name,
-
- &duplicate_label,
-
-@@ -1804,7 +1901,7 @@ static struct check *check_table[] = {
- &phandle_references, &path_references,
- &omit_unused_nodes,
-
-- &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
-+ &address_cells_is_cell, &size_cells_is_cell,
- &device_type_is_string, &model_is_string, &status_is_string,
- &label_is_string,
-
-@@ -1839,26 +1936,43 @@ static struct check *check_table[] = {
- &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
-
- &clocks_property,
-+ &clocks_is_cell,
- &cooling_device_property,
-+ &cooling_device_is_cell,
- &dmas_property,
-+ &dmas_is_cell,
- &hwlocks_property,
-+ &hwlocks_is_cell,
- &interrupts_extended_property,
-+ &interrupts_extended_is_cell,
- &io_channels_property,
-+ &io_channels_is_cell,
- &iommus_property,
-+ &iommus_is_cell,
- &mboxes_property,
-+ &mboxes_is_cell,
- &msi_parent_property,
-+ &msi_parent_is_cell,
- &mux_controls_property,
-+ &mux_controls_is_cell,
- &phys_property,
-+ &phys_is_cell,
- &power_domains_property,
-+ &power_domains_is_cell,
- &pwms_property,
-+ &pwms_is_cell,
- &resets_property,
-+ &resets_is_cell,
- &sound_dai_property,
-+ &sound_dai_is_cell,
- &thermal_sensors_property,
-+ &thermal_sensors_is_cell,
-
- &deprecated_gpio_property,
- &gpios_property,
- &interrupts_property,
- &interrupt_provider,
-+ &interrupt_map,
-
- &alias_paths,
-
-@@ -1882,7 +1996,7 @@ static void enable_warning_error(struct
-
- static void disable_warning_error(struct check *c, bool warn, bool error)
- {
-- int i;
-+ unsigned int i;
-
- /* Lowering level, also lower it for things this is the prereq
- * for */
-@@ -1903,7 +2017,7 @@ static void disable_warning_error(struct
-
- void parse_checks_option(bool warn, bool error, const char *arg)
- {
-- int i;
-+ unsigned int i;
- const char *name = arg;
- bool enable = true;
-
-@@ -1930,7 +2044,7 @@ void parse_checks_option(bool warn, bool
-
- void process_checks(bool force, struct dt_info *dti)
- {
-- int i;
-+ unsigned int i;
- int error = 0;
-
- for (i = 0; i < ARRAY_SIZE(check_table); i++) {
---- a/scripts/dtc/dtc-lexer.l
-+++ b/scripts/dtc/dtc-lexer.l
-@@ -57,7 +57,7 @@ static void PRINTF(1, 2) lexical_error(c
- push_input_file(name);
- }
-
--<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
-+<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)* {
- char *line, *fnstart, *fnend;
- struct data fn;
- /* skip text before line # */
---- a/scripts/dtc/dtc.c
-+++ b/scripts/dtc/dtc.c
-@@ -12,7 +12,7 @@
- * Command line options
- */
- int quiet; /* Level of quietness */
--int reservenum; /* Number of memory reservation slots */
-+unsigned int reservenum;/* Number of memory reservation slots */
- int minsize; /* Minimum blob size */
- int padsize; /* Additional padding to blob */
- int alignsize; /* Additional padding to blob accroding to the alignsize */
-@@ -197,7 +197,7 @@ int main(int argc, char *argv[])
- depname = optarg;
- break;
- case 'R':
-- reservenum = strtol(optarg, NULL, 0);
-+ reservenum = strtoul(optarg, NULL, 0);
- break;
- case 'S':
- minsize = strtol(optarg, NULL, 0);
-@@ -359,8 +359,6 @@ int main(int argc, char *argv[])
- #endif
- } else if (streq(outform, "dtb")) {
- dt_to_blob(outf, dti, outversion);
-- } else if (streq(outform, "dtbo")) {
-- dt_to_blob(outf, dti, outversion);
- } else if (streq(outform, "asm")) {
- dt_to_asm(outf, dti, outversion);
- } else if (streq(outform, "null")) {
---- a/scripts/dtc/dtc.h
-+++ b/scripts/dtc/dtc.h
-@@ -35,7 +35,7 @@
- * Command line options
- */
- extern int quiet; /* Level of quietness */
--extern int reservenum; /* Number of memory reservation slots */
-+extern unsigned int reservenum; /* Number of memory reservation slots */
- extern int minsize; /* Minimum blob size */
- extern int padsize; /* Additional padding to blob */
- extern int alignsize; /* Additional padding to blob accroding to the alignsize */
-@@ -51,6 +51,11 @@ extern int annotate; /* annotate .dts w
-
- typedef uint32_t cell_t;
-
-+static inline bool phandle_is_valid(cell_t phandle)
-+{
-+ return phandle != 0 && phandle != ~0U;
-+}
-+
- static inline uint16_t dtb_ld16(const void *p)
- {
- const uint8_t *bp = (const uint8_t *)p;
-@@ -86,6 +91,16 @@ static inline uint64_t dtb_ld64(const vo
- #define streq(a, b) (strcmp((a), (b)) == 0)
- #define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0)
- #define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0))
-+static inline bool strends(const char *str, const char *suffix)
-+{
-+ unsigned int len, suffix_len;
-+
-+ len = strlen(str);
-+ suffix_len = strlen(suffix);
-+ if (len < suffix_len)
-+ return false;
-+ return streq(str + len - suffix_len, suffix);
-+}
-
- #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
-
-@@ -101,6 +116,12 @@ enum markertype {
- TYPE_UINT64,
- TYPE_STRING,
- };
-+
-+static inline bool is_type_marker(enum markertype type)
-+{
-+ return type >= TYPE_UINT8;
-+}
-+
- extern const char *markername(enum markertype markertype);
-
- struct marker {
-@@ -125,7 +146,22 @@ struct data {
- for_each_marker(m) \
- if ((m)->type == (t))
-
--size_t type_marker_length(struct marker *m);
-+static inline struct marker *next_type_marker(struct marker *m)
-+{
-+ for_each_marker(m)
-+ if (is_type_marker(m->type))
-+ break;
-+ return m;
-+}
-+
-+static inline size_t type_marker_length(struct marker *m)
-+{
-+ struct marker *next = next_type_marker(m->next);
-+
-+ if (next)
-+ return next->offset - m->offset;
-+ return 0;
-+}
-
- void data_free(struct data d);
-
---- a/scripts/dtc/flattree.c
-+++ b/scripts/dtc/flattree.c
-@@ -124,7 +124,8 @@ static void asm_emit_cell(void *e, cell_
- {
- FILE *f = e;
-
-- fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n",
-+ fprintf(f, "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n"
-+ "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n",
- (val >> 24) & 0xff, (val >> 16) & 0xff,
- (val >> 8) & 0xff, val & 0xff);
- }
-@@ -134,9 +135,9 @@ static void asm_emit_string(void *e, con
- FILE *f = e;
-
- if (len != 0)
-- fprintf(f, "\t.string\t\"%.*s\"\n", len, str);
-+ fprintf(f, "\t.asciz\t\"%.*s\"\n", len, str);
- else
-- fprintf(f, "\t.string\t\"%s\"\n", str);
-+ fprintf(f, "\t.asciz\t\"%s\"\n", str);
- }
-
- static void asm_emit_align(void *e, int a)
-@@ -295,7 +296,7 @@ static struct data flatten_reserve_list(
- {
- struct reserve_info *re;
- struct data d = empty_data;
-- int j;
-+ unsigned int j;
-
- for (re = reservelist; re; re = re->next) {
- d = data_append_re(d, re->address, re->size);
-@@ -438,7 +439,7 @@ static void dump_stringtable_asm(FILE *f
-
- while (p < (strbuf.val + strbuf.len)) {
- len = strlen(p);
-- fprintf(f, "\t.string \"%s\"\n", p);
-+ fprintf(f, "\t.asciz \"%s\"\n", p);
- p += len+1;
- }
- }
---- a/scripts/dtc/libfdt/fdt.c
-+++ b/scripts/dtc/libfdt/fdt.c
-@@ -90,6 +90,10 @@ int fdt_check_header(const void *fdt)
- {
- size_t hdrsize;
-
-+ /* The device tree must be at an 8-byte aligned address */
-+ if ((uintptr_t)fdt & 7)
-+ return -FDT_ERR_ALIGNMENT;
-+
- if (fdt_magic(fdt) != FDT_MAGIC)
- return -FDT_ERR_BADMAGIC;
- if (!can_assume(LATEST)) {
---- a/scripts/dtc/libfdt/fdt_rw.c
-+++ b/scripts/dtc/libfdt/fdt_rw.c
-@@ -349,7 +349,10 @@ int fdt_add_subnode_namelen(void *fdt, i
- return offset;
-
- /* Try to place the new node after the parent's properties */
-- fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
-+ tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
-+ /* the fdt_subnode_offset_namelen() should ensure this never hits */
-+ if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE))
-+ return -FDT_ERR_INTERNAL;
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-@@ -391,7 +394,9 @@ int fdt_del_node(void *fdt, int nodeoffs
- }
-
- static void fdt_packblocks_(const char *old, char *new,
-- int mem_rsv_size, int struct_size)
-+ int mem_rsv_size,
-+ int struct_size,
-+ int strings_size)
- {
- int mem_rsv_off, struct_off, strings_off;
-
-@@ -406,8 +411,7 @@ static void fdt_packblocks_(const char *
- fdt_set_off_dt_struct(new, struct_off);
- fdt_set_size_dt_struct(new, struct_size);
-
-- memmove(new + strings_off, old + fdt_off_dt_strings(old),
-- fdt_size_dt_strings(old));
-+ memmove(new + strings_off, old + fdt_off_dt_strings(old), strings_size);
- fdt_set_off_dt_strings(new, strings_off);
- fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
- }
-@@ -467,7 +471,8 @@ int fdt_open_into(const void *fdt, void
- return -FDT_ERR_NOSPACE;
- }
-
-- fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
-+ fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size,
-+ fdt_size_dt_strings(fdt));
- memmove(buf, tmp, newsize);
-
- fdt_set_magic(buf, FDT_MAGIC);
-@@ -487,7 +492,8 @@ int fdt_pack(void *fdt)
-
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
-- fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
-+ fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt),
-+ fdt_size_dt_strings(fdt));
- fdt_set_totalsize(fdt, fdt_data_size_(fdt));
-
- return 0;
---- a/scripts/dtc/libfdt/fdt_strerror.c
-+++ b/scripts/dtc/libfdt/fdt_strerror.c
-@@ -39,6 +39,7 @@ static struct fdt_errtabent fdt_errtable
- FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
- FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
- FDT_ERRTABENT(FDT_ERR_BADFLAGS),
-+ FDT_ERRTABENT(FDT_ERR_ALIGNMENT),
- };
- #define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0])))
-
---- a/scripts/dtc/libfdt/libfdt.h
-+++ b/scripts/dtc/libfdt/libfdt.h
-@@ -131,6 +131,13 @@ uint32_t fdt_next_tag(const void *fdt, i
- * to work even with unaligned pointers on platforms (such as ARMv5) that don't
- * like unaligned loads and stores.
- */
-+static inline uint16_t fdt16_ld(const fdt16_t *p)
-+{
-+ const uint8_t *bp = (const uint8_t *)p;
-+
-+ return ((uint16_t)bp[0] << 8) | bp[1];
-+}
-+
- static inline uint32_t fdt32_ld(const fdt32_t *p)
- {
- const uint8_t *bp = (const uint8_t *)p;
---- a/scripts/dtc/livetree.c
-+++ b/scripts/dtc/livetree.c
-@@ -526,7 +526,7 @@ struct node *get_node_by_path(struct nod
- p = strchr(path, '/');
-
- for_each_child(tree, child) {
-- if (p && strprefixeq(path, p - path, child->name))
-+ if (p && strprefixeq(path, (size_t)(p - path), child->name))
- return get_node_by_path(child, p+1);
- else if (!p && streq(path, child->name))
- return child;
-@@ -559,7 +559,7 @@ struct node *get_node_by_phandle(struct
- {
- struct node *child, *node;
-
-- if ((phandle == 0) || (phandle == -1)) {
-+ if (!phandle_is_valid(phandle)) {
- assert(generate_fixups);
- return NULL;
- }
-@@ -594,7 +594,7 @@ cell_t get_node_phandle(struct node *roo
- static cell_t phandle = 1; /* FIXME: ick, static local */
- struct data d = empty_data;
-
-- if ((node->phandle != 0) && (node->phandle != -1))
-+ if (phandle_is_valid(node->phandle))
- return node->phandle;
-
- while (get_node_by_phandle(root, phandle))
---- a/scripts/dtc/treesource.c
-+++ b/scripts/dtc/treesource.c
-@@ -124,27 +124,6 @@ static void write_propval_int(FILE *f, c
- }
- }
-
--static bool has_data_type_information(struct marker *m)
--{
-- return m->type >= TYPE_UINT8;
--}
--
--static struct marker *next_type_marker(struct marker *m)
--{
-- while (m && !has_data_type_information(m))
-- m = m->next;
-- return m;
--}
--
--size_t type_marker_length(struct marker *m)
--{
-- struct marker *next = next_type_marker(m->next);
--
-- if (next)
-- return next->offset - m->offset;
-- return 0;
--}
--
- static const char *delim_start[] = {
- [TYPE_UINT8] = "[",
- [TYPE_UINT16] = "/bits/ 16 <",
-@@ -229,26 +208,39 @@ static void write_propval(FILE *f, struc
- size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
- size_t data_len = type_marker_length(m) ? : len - m->offset;
- const char *p = &prop->val.val[m->offset];
-+ struct marker *m_phandle;
-
-- if (has_data_type_information(m)) {
-+ if (is_type_marker(m->type)) {
- emit_type = m->type;
- fprintf(f, " %s", delim_start[emit_type]);
- } else if (m->type == LABEL)
- fprintf(f, " %s:", m->ref);
-- else if (m->offset)
-- fputc(' ', f);
-
-- if (emit_type == TYPE_NONE) {
-- assert(chunk_len == 0);
-+ if (emit_type == TYPE_NONE || chunk_len == 0)
- continue;
-- }
-
- switch(emit_type) {
- case TYPE_UINT16:
- write_propval_int(f, p, chunk_len, 2);
- break;
- case TYPE_UINT32:
-- write_propval_int(f, p, chunk_len, 4);
-+ m_phandle = prop->val.markers;
-+ for_each_marker_of_type(m_phandle, REF_PHANDLE)
-+ if (m->offset == m_phandle->offset)
-+ break;
-+
-+ if (m_phandle) {
-+ if (m_phandle->ref[0] == '/')
-+ fprintf(f, "&{%s}", m_phandle->ref);
-+ else
-+ fprintf(f, "&%s", m_phandle->ref);
-+ if (chunk_len > 4) {
-+ fputc(' ', f);
-+ write_propval_int(f, p + 4, chunk_len - 4, 4);
-+ }
-+ } else {
-+ write_propval_int(f, p, chunk_len, 4);
-+ }
- break;
- case TYPE_UINT64:
- write_propval_int(f, p, chunk_len, 8);
---- a/scripts/dtc/util.h
-+++ b/scripts/dtc/util.h
-@@ -13,10 +13,10 @@
- */
-
- #ifdef __GNUC__
--#ifdef __clang__
--#define PRINTF(i, j) __attribute__((format (printf, i, j)))
--#else
-+#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
- #define PRINTF(i, j) __attribute__((format (gnu_printf, i, j)))
-+#else
-+#define PRINTF(i, j) __attribute__((format (printf, i, j)))
- #endif
- #define NORETURN __attribute__((noreturn))
- #else
---- a/scripts/dtc/version_gen.h
-+++ b/scripts/dtc/version_gen.h
-@@ -1 +1 @@
--#define DTC_VERSION "DTC 1.6.0-g183df9e9"
-+#define DTC_VERSION "DTC 1.6.1-g0a3a9d34"
---- a/scripts/dtc/yamltree.c
-+++ b/scripts/dtc/yamltree.c
-@@ -29,11 +29,12 @@ char *yaml_error_name[] = {
- (emitter)->problem, __func__, __LINE__); \
- })
-
--static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, char *data, unsigned int len, int width)
-+static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers,
-+ char *data, unsigned int seq_offset, unsigned int len, int width)
- {
- yaml_event_t event;
- void *tag;
-- unsigned int off, start_offset = markers->offset;
-+ unsigned int off;
-
- switch(width) {
- case 1: tag = "!u8"; break;
-@@ -66,7 +67,7 @@ static void yaml_propval_int(yaml_emitte
- m = markers;
- is_phandle = false;
- for_each_marker_of_type(m, REF_PHANDLE) {
-- if (m->offset == (start_offset + off)) {
-+ if (m->offset == (seq_offset + off)) {
- is_phandle = true;
- break;
- }
-@@ -114,6 +115,7 @@ static void yaml_propval(yaml_emitter_t
- yaml_event_t event;
- unsigned int len = prop->val.len;
- struct marker *m = prop->val.markers;
-+ struct marker *markers = prop->val.markers;
-
- /* Emit the property name */
- yaml_scalar_event_initialize(&event, NULL,
-@@ -151,19 +153,19 @@ static void yaml_propval(yaml_emitter_t
-
- switch(m->type) {
- case TYPE_UINT16:
-- yaml_propval_int(emitter, m, data, chunk_len, 2);
-+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 2);
- break;
- case TYPE_UINT32:
-- yaml_propval_int(emitter, m, data, chunk_len, 4);
-+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 4);
- break;
- case TYPE_UINT64:
-- yaml_propval_int(emitter, m, data, chunk_len, 8);
-+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 8);
- break;
- case TYPE_STRING:
- yaml_propval_string(emitter, data, chunk_len);
- break;
- default:
-- yaml_propval_int(emitter, m, data, chunk_len, 1);
-+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 1);
- break;
- }
- }
diff --git a/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch b/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch
deleted file mode 100644
index 786a2d93b5..0000000000
--- a/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 73bbb94466fd3f8b313eeb0b0467314a262dddb3 Mon Sep 17 00:00:00 2001
-From: Miguel Ojeda <ojeda@kernel.org>
-Date: Mon, 5 Apr 2021 04:58:39 +0200
-Subject: [PATCH] kallsyms: support "big" kernel symbols
-
-Rust symbols can become quite long due to namespacing introduced
-by modules, types, traits, generics, etc.
-
-Increasing to 255 is not enough in some cases, therefore
-introduce longer lengths to the symbol table.
-
-In order to avoid increasing all lengths to 2 bytes (since most
-of them are small, including many Rust ones), use ULEB128 to
-keep smaller symbols in 1 byte, with the rest in 2 bytes.
-
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
-Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
-Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
-Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
-Co-developed-by: Gary Guo <gary@garyguo.net>
-Signed-off-by: Gary Guo <gary@garyguo.net>
-Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
-Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
-Co-developed-by: Matthew Wilcox <willy@infradead.org>
-Signed-off-by: Matthew Wilcox <willy@infradead.org>
-Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
----
- kernel/kallsyms.c | 26 ++++++++++++++++++++++----
- scripts/kallsyms.c | 29 ++++++++++++++++++++++++++---
- 2 files changed, 48 insertions(+), 7 deletions(-)
-
---- a/kernel/kallsyms.c
-+++ b/kernel/kallsyms.c
-@@ -69,12 +69,20 @@ static unsigned int kallsyms_expand_symb
- data = &kallsyms_names[off];
- len = *data;
- data++;
-+ off++;
-+
-+ /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */
-+ if ((len & 0x80) != 0) {
-+ len = (len & 0x7F) | (*data << 7);
-+ data++;
-+ off++;
-+ }
-
- /*
- * Update the offset to return the offset for the next symbol on
- * the compressed stream.
- */
-- off += len + 1;
-+ off += len;
-
- /*
- * For every byte on the compressed symbol data, copy the table
-@@ -127,7 +135,7 @@ static char kallsyms_get_symbol_type(uns
- static unsigned int get_symbol_offset(unsigned long pos)
- {
- const u8 *name;
-- int i;
-+ int i, len;
-
- /*
- * Use the closest marker we have. We have markers every 256 positions,
-@@ -141,8 +149,18 @@ static unsigned int get_symbol_offset(un
- * so we just need to add the len to the current pointer for every
- * symbol we wish to skip.
- */
-- for (i = 0; i < (pos & 0xFF); i++)
-- name = name + (*name) + 1;
-+ for (i = 0; i < (pos & 0xFF); i++) {
-+ len = *name;
-+
-+ /*
-+ * If MSB is 1, it is a "big" symbol, so we need to look into
-+ * the next byte (and skip it, too).
-+ */
-+ if ((len & 0x80) != 0)
-+ len = ((len & 0x7F) | (name[1] << 7)) + 1;
-+
-+ name = name + len + 1;
-+ }
-
- return name - kallsyms_names;
- }
---- a/scripts/kallsyms.c
-+++ b/scripts/kallsyms.c
-@@ -470,12 +470,35 @@ static void write_src(void)
- if ((i & 0xFF) == 0)
- markers[i >> 8] = off;
-
-- printf("\t.byte 0x%02x", table[i]->len);
-+ /* There cannot be any symbol of length zero. */
-+ if (table[i]->len == 0) {
-+ fprintf(stderr, "kallsyms failure: "
-+ "unexpected zero symbol length\n");
-+ exit(EXIT_FAILURE);
-+ }
-+
-+ /* Only lengths that fit in up-to-two-byte ULEB128 are supported. */
-+ if (table[i]->len > 0x3FFF) {
-+ fprintf(stderr, "kallsyms failure: "
-+ "unexpected huge symbol length\n");
-+ exit(EXIT_FAILURE);
-+ }
-+
-+ /* Encode length with ULEB128. */
-+ if (table[i]->len <= 0x7F) {
-+ /* Most symbols use a single byte for the length. */
-+ printf("\t.byte 0x%02x", table[i]->len);
-+ off += table[i]->len + 1;
-+ } else {
-+ /* "Big" symbols use two bytes. */
-+ printf("\t.byte 0x%02x, 0x%02x",
-+ (table[i]->len & 0x7F) | 0x80,
-+ (table[i]->len >> 7) & 0x7F);
-+ off += table[i]->len + 2;
-+ }
- for (k = 0; k < table[i]->len; k++)
- printf(", 0x%02x", table[i]->sym[k]);
- printf("\n");
--
-- off += table[i]->len + 1;
- }
- printf("\n");
-
diff --git a/target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch b/target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch
deleted file mode 100644
index 18a8752a18..0000000000
--- a/target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-To: linus.walleij@linaro.org
-Cc: bjorn.andersson@linaro.org, dianders@chromium.org,
- linux-arm-msm@vger.kernel.org, linux-gpio@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Subject: [PATCH] pinctrl: qcom: Return -EINVAL for setting affinity if no IRQ
- parent
-Date: Thu, 13 Jan 2022 21:56:17 +0530
-Message-Id: <20220113162617.131697-1-manivannan.sadhasivam@linaro.org>
-
-The MSM GPIO IRQ controller relies on the parent IRQ controller to set the
-CPU affinity for the IRQ. And this is only valid if there is any wakeup
-parent available and defined in DT.
-
-For the case of no parent IRQ controller defined in DT,
-msm_gpio_irq_set_affinity() and msm_gpio_irq_set_vcpu_affinity() should
-return -EINVAL instead of 0 as the affinity can't be set.
-
-Otherwise, below warning will be printed by genirq:
-
-genirq: irq_chip msmgpio did not update eff. affinity mask of irq 70
-
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/pinctrl/qcom/pinctrl-msm.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/pinctrl/qcom/pinctrl-msm.c
-+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
-@@ -1157,7 +1157,7 @@ static int msm_gpio_irq_set_affinity(str
- if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
- return irq_chip_set_affinity_parent(d, dest, force);
-
-- return 0;
-+ return -EINVAL;
- }
-
- static int msm_gpio_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
-@@ -1168,7 +1168,7 @@ static int msm_gpio_irq_set_vcpu_affinit
- if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
- return irq_chip_set_vcpu_affinity_parent(d, vcpu_info);
-
-- return 0;
-+ return -EINVAL;
- }
-
- static void msm_gpio_irq_handler(struct irq_desc *desc)
diff --git a/target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch b/target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch
deleted file mode 100644
index ee0bf9309f..0000000000
--- a/target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From b5af64fceb04dc298c5e69c517b4d83893ff060b Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@linaro.org>
-Date: Thu, 30 Sep 2021 11:21:10 -0700
-Subject: [PATCH 1/1] soc: qcom: smem: Support reserved-memory description
-
-Practically all modern Qualcomm platforms has a single reserved-memory
-region for SMEM. So rather than having to describe SMEM in the form of a
-node with a reference to a reserved-memory node, allow the SMEM device
-to be instantiated directly from the reserved-memory node.
-
-The current means of falling back to dereferencing the "memory-region"
-is kept as a fallback, if it's determined that the SMEM node is a
-reserved-memory node.
-
-The "qcom,smem" compatible is added to the reserved_mem_matches list, to
-allow the reserved-memory device to be probed.
-
-In order to retain the readability of the code, the resolution of
-resources is split from the actual ioremapping.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-Acked-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
-Link: https://lore.kernel.org/r/20210930182111.57353-4-bjorn.andersson@linaro.org
----
- drivers/of/platform.c | 1 +
- drivers/soc/qcom/smem.c | 57 ++++++++++++++++++++++++++++-------------
- 2 files changed, 40 insertions(+), 18 deletions(-)
-
---- a/drivers/of/platform.c
-+++ b/drivers/of/platform.c
-@@ -509,6 +509,7 @@ EXPORT_SYMBOL_GPL(of_platform_default_po
- static const struct of_device_id reserved_mem_matches[] = {
- { .compatible = "qcom,rmtfs-mem" },
- { .compatible = "qcom,cmd-db" },
-+ { .compatible = "qcom,smem" },
- { .compatible = "ramoops" },
- { .compatible = "nvmem-rmem" },
- {}
---- a/drivers/soc/qcom/smem.c
-+++ b/drivers/soc/qcom/smem.c
-@@ -9,6 +9,7 @@
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/of_address.h>
-+#include <linux/of_reserved_mem.h>
- #include <linux/platform_device.h>
- #include <linux/sizes.h>
- #include <linux/slab.h>
-@@ -240,7 +241,7 @@ static const u8 SMEM_INFO_MAGIC[] = { 0x
- * @size: size of the memory region
- */
- struct smem_region {
-- u32 aux_base;
-+ phys_addr_t aux_base;
- void __iomem *virt_base;
- size_t size;
- };
-@@ -499,7 +500,7 @@ static void *qcom_smem_get_global(struct
- for (i = 0; i < smem->num_regions; i++) {
- region = &smem->regions[i];
-
-- if (region->aux_base == aux_base || !aux_base) {
-+ if ((u32)region->aux_base == aux_base || !aux_base) {
- if (size != NULL)
- *size = le32_to_cpu(entry->size);
- return region->virt_base + le32_to_cpu(entry->offset);
-@@ -664,7 +665,7 @@ phys_addr_t qcom_smem_virt_to_phys(void
- if (p < region->virt_base + region->size) {
- u64 offset = p - region->virt_base;
-
-- return (phys_addr_t)region->aux_base + offset;
-+ return region->aux_base + offset;
- }
- }
-
-@@ -863,12 +864,12 @@ qcom_smem_enumerate_partitions(struct qc
- return 0;
- }
-
--static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
-- const char *name, int i)
-+static int qcom_smem_resolve_mem(struct qcom_smem *smem, const char *name,
-+ struct smem_region *region)
- {
-+ struct device *dev = smem->dev;
- struct device_node *np;
- struct resource r;
-- resource_size_t size;
- int ret;
-
- np = of_parse_phandle(dev->of_node, name, 0);
-@@ -881,13 +882,9 @@ static int qcom_smem_map_memory(struct q
- of_node_put(np);
- if (ret)
- return ret;
-- size = resource_size(&r);
-
-- smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, size);
-- if (!smem->regions[i].virt_base)
-- return -ENOMEM;
-- smem->regions[i].aux_base = (u32)r.start;
-- smem->regions[i].size = size;
-+ region->aux_base = r.start;
-+ region->size = resource_size(&r);
-
- return 0;
- }
-@@ -895,12 +892,14 @@ static int qcom_smem_map_memory(struct q
- static int qcom_smem_probe(struct platform_device *pdev)
- {
- struct smem_header *header;
-+ struct reserved_mem *rmem;
- struct qcom_smem *smem;
- size_t array_size;
- int num_regions;
- int hwlock_id;
- u32 version;
- int ret;
-+ int i;
-
- num_regions = 1;
- if (of_find_property(pdev->dev.of_node, "qcom,rpm-msg-ram", NULL))
-@@ -914,13 +913,35 @@ static int qcom_smem_probe(struct platfo
- smem->dev = &pdev->dev;
- smem->num_regions = num_regions;
-
-- ret = qcom_smem_map_memory(smem, &pdev->dev, "memory-region", 0);
-- if (ret)
-- return ret;
--
-- if (num_regions > 1 && (ret = qcom_smem_map_memory(smem, &pdev->dev,
-- "qcom,rpm-msg-ram", 1)))
-- return ret;
-+ rmem = of_reserved_mem_lookup(pdev->dev.of_node);
-+ if (rmem) {
-+ smem->regions[0].aux_base = rmem->base;
-+ smem->regions[0].size = rmem->size;
-+ } else {
-+ /*
-+ * Fall back to the memory-region reference, if we're not a
-+ * reserved-memory node.
-+ */
-+ ret = qcom_smem_resolve_mem(smem, "memory-region", &smem->regions[0]);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ if (num_regions > 1) {
-+ ret = qcom_smem_resolve_mem(smem, "qcom,rpm-msg-ram", &smem->regions[1]);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ for (i = 0; i < num_regions; i++) {
-+ smem->regions[i].virt_base = devm_ioremap_wc(&pdev->dev,
-+ smem->regions[i].aux_base,
-+ smem->regions[i].size);
-+ if (!smem->regions[i].virt_base) {
-+ dev_err(&pdev->dev, "failed to remap %pa\n", &smem->regions[i].aux_base);
-+ return -ENOMEM;
-+ }
-+ }
-
- header = smem->regions[0].virt_base;
- if (le32_to_cpu(header->initialized) != 1 ||
diff --git a/target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch b/target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch
deleted file mode 100644
index 84ae5a7fc7..0000000000
--- a/target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From ee1a0696934a8b77a6a2098f92832c46d34ec5da Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 27 Oct 2021 14:31:35 +0200
-Subject: [PATCH] watchdog: bcm63xx_wdt: fix fallthrough warning
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-drivers/watchdog/bcm63xx_wdt.c: In function 'bcm63xx_wdt_ioctl':
-drivers/watchdog/bcm63xx_wdt.c:208:17: warning: this statement may fall through [-Wimplicit-fallthrough=]
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
-Link: https://lore.kernel.org/r/20211027123135.27458-1-zajec5@gmail.com
-Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
----
- drivers/watchdog/bcm63xx_wdt.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/watchdog/bcm63xx_wdt.c
-+++ b/drivers/watchdog/bcm63xx_wdt.c
-@@ -207,6 +207,8 @@ static long bcm63xx_wdt_ioctl(struct fil
-
- bcm63xx_wdt_pet();
-
-+ fallthrough;
-+
- case WDIOC_GETTIMEOUT:
- return put_user(wdt_time, p);
-
diff --git a/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch b/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch
deleted file mode 100644
index 7c1507bba7..0000000000
--- a/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 579aee9fc594af94c242068c011b0233563d4bbf Mon Sep 17 00:00:00 2001
-From: Stephen Rothwell <sfr@canb.auug.org.au>
-Date: Mon, 10 Oct 2022 16:57:21 +1100
-Subject: [PATCH] powerpc: suppress some linker warnings in recent linker
- versions
-
-This is a follow on from commit
-
- 0d362be5b142 ("Makefile: link with -z noexecstack --no-warn-rwx-segments")
-
-for arch/powerpc/boot to address wanrings like:
-
- ld: warning: opal-calls.o: missing .note.GNU-stack section implies executable stack
- ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
- ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions
-
-This fixes issue https://github.com/linuxppc/issues/issues/417
-
-Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/20221010165721.106267e6@canb.auug.org.au
----
- arch/powerpc/boot/wrapper | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -213,6 +213,11 @@ ld_version()
- }'
- }
-
-+ld_is_lld()
-+{
-+ ${CROSS}ld -V 2>&1 | grep -q LLD
-+}
-+
- # Do not include PT_INTERP segment when linking pie. Non-pie linking
- # just ignores this option.
- LD_VERSION=$(${CROSS}ld --version | ld_version)
-@@ -221,6 +226,14 @@ if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VE
- nodl="--no-dynamic-linker"
- fi
-
-+# suppress some warnings in recent ld versions
-+nowarn="-z noexecstack"
-+if ! ld_is_lld; then
-+ if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then
-+ nowarn="$nowarn --no-warn-rwx-segments"
-+ fi
-+fi
-+
- platformo=$object/"$platform".o
- lds=$object/zImage.lds
- ext=strip
-@@ -502,7 +515,7 @@ if [ "$platform" != "miboot" ]; then
- text_start="-Ttext $link_address"
- fi
- #link everything
-- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \
-+ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $nowarn $rodynamic $notext -o "$ofile" $map \
- $platformo $tmp $object/wrapper.a
- rm $tmp
- fi
diff --git a/target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch b/target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch
deleted file mode 100644
index c66a3f11b4..0000000000
--- a/target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From 626bfa03729959ea9917181fb3d8ffaa1594d02a Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Wed, 13 Oct 2021 22:40:18 -0700
-Subject: [PATCH 1/1] MIPS: kernel: proc: add CPU option reporting
-
-Many MIPS CPUs have optional CPU features which are not activated for
-all CPU cores. Print the CPU options, which are implemented in the core,
-in /proc/cpuinfo. This makes it possible to see which features are
-supported and which are not supported. This should cover all standard
-MIPS extensions. Before, it only printed information about the main MIPS
-ASEs.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-
-Changes from original patch[0]:
-- Remove cpu_has_6k_cache and cpu_has_8k_cache due to commit 6ce91ba8589a
- ("MIPS: Remove cpu_has_6k_cache and cpu_has_8k_cache in cpu_cache_init()")
-- Add new options: mac2008_only, ftlbparex, gsexcex, mmid, mm_sysad,
- mm_full
-- Use seq_puts instead of seq_printf as suggested by checkpatch
-- Minor commit message reword
-
-[0]: https://lore.kernel.org/linux-mips/20181223225224.23042-1-hauke@hauke-m.de/
-
-Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/kernel/proc.c | 122 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 122 insertions(+)
-
---- a/arch/mips/kernel/proc.c
-+++ b/arch/mips/kernel/proc.c
-@@ -138,6 +138,128 @@ static int show_cpuinfo(struct seq_file
- seq_printf(m, "micromips kernel\t: %s\n",
- (read_c0_config3() & MIPS_CONF3_ISA_OE) ? "yes" : "no");
- }
-+
-+ seq_puts(m, "Options implemented\t:");
-+ if (cpu_has_tlb)
-+ seq_puts(m, " tlb");
-+ if (cpu_has_ftlb)
-+ seq_puts(m, " ftlb");
-+ if (cpu_has_tlbinv)
-+ seq_puts(m, " tlbinv");
-+ if (cpu_has_segments)
-+ seq_puts(m, " segments");
-+ if (cpu_has_rixiex)
-+ seq_puts(m, " rixiex");
-+ if (cpu_has_ldpte)
-+ seq_puts(m, " ldpte");
-+ if (cpu_has_maar)
-+ seq_puts(m, " maar");
-+ if (cpu_has_rw_llb)
-+ seq_puts(m, " rw_llb");
-+ if (cpu_has_4kex)
-+ seq_puts(m, " 4kex");
-+ if (cpu_has_3k_cache)
-+ seq_puts(m, " 3k_cache");
-+ if (cpu_has_4k_cache)
-+ seq_puts(m, " 4k_cache");
-+ if (cpu_has_tx39_cache)
-+ seq_puts(m, " tx39_cache");
-+ if (cpu_has_octeon_cache)
-+ seq_puts(m, " octeon_cache");
-+ if (cpu_has_fpu)
-+ seq_puts(m, " fpu");
-+ if (cpu_has_32fpr)
-+ seq_puts(m, " 32fpr");
-+ if (cpu_has_cache_cdex_p)
-+ seq_puts(m, " cache_cdex_p");
-+ if (cpu_has_cache_cdex_s)
-+ seq_puts(m, " cache_cdex_s");
-+ if (cpu_has_prefetch)
-+ seq_puts(m, " prefetch");
-+ if (cpu_has_mcheck)
-+ seq_puts(m, " mcheck");
-+ if (cpu_has_ejtag)
-+ seq_puts(m, " ejtag");
-+ if (cpu_has_llsc)
-+ seq_puts(m, " llsc");
-+ if (cpu_has_guestctl0ext)
-+ seq_puts(m, " guestctl0ext");
-+ if (cpu_has_guestctl1)
-+ seq_puts(m, " guestctl1");
-+ if (cpu_has_guestctl2)
-+ seq_puts(m, " guestctl2");
-+ if (cpu_has_guestid)
-+ seq_puts(m, " guestid");
-+ if (cpu_has_drg)
-+ seq_puts(m, " drg");
-+ if (cpu_has_rixi)
-+ seq_puts(m, " rixi");
-+ if (cpu_has_lpa)
-+ seq_puts(m, " lpa");
-+ if (cpu_has_mvh)
-+ seq_puts(m, " mvh");
-+ if (cpu_has_vtag_icache)
-+ seq_puts(m, " vtag_icache");
-+ if (cpu_has_dc_aliases)
-+ seq_puts(m, " dc_aliases");
-+ if (cpu_has_ic_fills_f_dc)
-+ seq_puts(m, " ic_fills_f_dc");
-+ if (cpu_has_pindexed_dcache)
-+ seq_puts(m, " pindexed_dcache");
-+ if (cpu_has_userlocal)
-+ seq_puts(m, " userlocal");
-+ if (cpu_has_nofpuex)
-+ seq_puts(m, " nofpuex");
-+ if (cpu_has_vint)
-+ seq_puts(m, " vint");
-+ if (cpu_has_veic)
-+ seq_puts(m, " veic");
-+ if (cpu_has_inclusive_pcaches)
-+ seq_puts(m, " inclusive_pcaches");
-+ if (cpu_has_perf_cntr_intr_bit)
-+ seq_puts(m, " perf_cntr_intr_bit");
-+ if (cpu_has_ufr)
-+ seq_puts(m, " ufr");
-+ if (cpu_has_fre)
-+ seq_puts(m, " fre");
-+ if (cpu_has_cdmm)
-+ seq_puts(m, " cdmm");
-+ if (cpu_has_small_pages)
-+ seq_puts(m, " small_pages");
-+ if (cpu_has_nan_legacy)
-+ seq_puts(m, " nan_legacy");
-+ if (cpu_has_nan_2008)
-+ seq_puts(m, " nan_2008");
-+ if (cpu_has_ebase_wg)
-+ seq_puts(m, " ebase_wg");
-+ if (cpu_has_badinstr)
-+ seq_puts(m, " badinstr");
-+ if (cpu_has_badinstrp)
-+ seq_puts(m, " badinstrp");
-+ if (cpu_has_contextconfig)
-+ seq_puts(m, " contextconfig");
-+ if (cpu_has_perf)
-+ seq_puts(m, " perf");
-+ if (cpu_has_mac2008_only)
-+ seq_puts(m, " mac2008_only");
-+ if (cpu_has_ftlbparex)
-+ seq_puts(m, " ftlbparex");
-+ if (cpu_has_gsexcex)
-+ seq_puts(m, " gsexcex");
-+ if (cpu_has_shared_ftlb_ram)
-+ seq_puts(m, " shared_ftlb_ram");
-+ if (cpu_has_shared_ftlb_entries)
-+ seq_puts(m, " shared_ftlb_entries");
-+ if (cpu_has_mipsmt_pertccounters)
-+ seq_puts(m, " mipsmt_pertccounters");
-+ if (cpu_has_mmid)
-+ seq_puts(m, " mmid");
-+ if (cpu_has_mm_sysad)
-+ seq_puts(m, " mm_sysad");
-+ if (cpu_has_mm_full)
-+ seq_puts(m, " mm_full");
-+ seq_puts(m, "\n");
-+
- seq_printf(m, "shadow register sets\t: %d\n",
- cpu_data[n].srsets);
- seq_printf(m, "kscratch registers\t: %d\n",
diff --git a/target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch b/target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch
deleted file mode 100644
index 6caf7d06d4..0000000000
--- a/target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 1cab5bd69eb1f995ced2d7576cb15f8a8941fd85 Mon Sep 17 00:00:00 2001
-From: Tiezhu Yang <yangtiezhu@loongson.cn>
-Date: Thu, 25 Nov 2021 19:39:32 +0800
-Subject: [PATCH 1/1] MIPS: Fix using smp_processor_id() in preemptible in
- show_cpuinfo()
-
-There exists the following issue under DEBUG_PREEMPT:
-
- BUG: using smp_processor_id() in preemptible [00000000] code: systemd/1
- caller is show_cpuinfo+0x460/0xea0
- ...
- Call Trace:
- [<ffffffff8020f0dc>] show_stack+0x94/0x128
- [<ffffffff80e6cab4>] dump_stack_lvl+0x94/0xd8
- [<ffffffff80e74c5c>] check_preemption_disabled+0x104/0x110
- [<ffffffff802209c8>] show_cpuinfo+0x460/0xea0
- [<ffffffff80539d54>] seq_read_iter+0xfc/0x4f8
- [<ffffffff804fcc10>] new_sync_read+0x110/0x1b8
- [<ffffffff804ff57c>] vfs_read+0x1b4/0x1d0
- [<ffffffff804ffb18>] ksys_read+0xd0/0x110
- [<ffffffff8021c090>] syscall_common+0x34/0x58
-
-We can see the following call trace:
- show_cpuinfo()
- cpu_has_fpu
- current_cpu_data
- smp_processor_id()
-
- $ addr2line -f -e vmlinux 0xffffffff802209c8
- show_cpuinfo
- arch/mips/kernel/proc.c:188
-
- $ head -188 arch/mips/kernel/proc.c | tail -1
- if (cpu_has_fpu)
-
- arch/mips/include/asm/cpu-features.h
- # define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU)
-
- arch/mips/include/asm/cpu-info.h
- #define current_cpu_data cpu_data[smp_processor_id()]
-
-Based on the above analysis, fix the issue by using raw_cpu_has_fpu
-which calls raw_smp_processor_id() in show_cpuinfo().
-
-Fixes: 626bfa037299 ("MIPS: kernel: proc: add CPU option reporting")
-Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/kernel/proc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/kernel/proc.c
-+++ b/arch/mips/kernel/proc.c
-@@ -166,7 +166,7 @@ static int show_cpuinfo(struct seq_file
- seq_puts(m, " tx39_cache");
- if (cpu_has_octeon_cache)
- seq_puts(m, " octeon_cache");
-- if (cpu_has_fpu)
-+ if (raw_cpu_has_fpu)
- seq_puts(m, " fpu");
- if (cpu_has_32fpr)
- seq_puts(m, " 32fpr");
diff --git a/target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch b/target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch
deleted file mode 100644
index 541d247542..0000000000
--- a/target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-From f4c5c7f9d2e5ab005d57826b740b694b042a737c Mon Sep 17 00:00:00 2001
-From: Felix Matouschek <felix@matouschek.org>
-Date: Mon, 18 Apr 2022 15:28:03 +0200
-Subject: [PATCH 1/1] mtd: spinand: Add support for XTX XT26G0xA
-
-Add support for XTX Technology XT26G01AXXXXX, XTX26G02AXXXXX and
-XTX26G04AXXXXX SPI NAND.
-
-These are 3V, 1G/2G/4Gbit serial SLC NAND flash devices with on-die ECC
-(8bit strength per 512bytes).
-
-Tested on Teltonika RUTX10 flashed with OpenWrt.
-
-Links:
- - http://www.xtxtech.com/download/?AId=225
- - https://datasheet.lcsc.com/szlcsc/2005251034_XTX-XT26G01AWSEGA_C558841.pdf
-Signed-off-by: Felix Matouschek <felix@matouschek.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220418132803.664103-1-felix@matouschek.org
----
- drivers/mtd/nand/spi/Makefile | 2 +-
- drivers/mtd/nand/spi/core.c | 1 +
- drivers/mtd/nand/spi/xtx.c | 129 ++++++++++++++++++++++++++++++++++
- include/linux/mtd/spinand.h | 1 +
- 4 files changed, 132 insertions(+), 1 deletion(-)
- create mode 100644 drivers/mtd/nand/spi/xtx.c
-
---- a/drivers/mtd/nand/spi/Makefile
-+++ b/drivers/mtd/nand/spi/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
-+spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
- obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -902,6 +902,7 @@ static const struct spinand_manufacturer
- &paragon_spinand_manufacturer,
- &toshiba_spinand_manufacturer,
- &winbond_spinand_manufacturer,
-+ &xtx_spinand_manufacturer,
- };
-
- static int spinand_manufacturer_match(struct spinand_device *spinand,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/xtx.c
-@@ -0,0 +1,129 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Author:
-+ * Felix Matouschek <felix@matouschek.org>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+#define SPINAND_MFR_XTX 0x0B
-+
-+#define XT26G0XA_STATUS_ECC_MASK GENMASK(5, 2)
-+#define XT26G0XA_STATUS_ECC_NO_DETECTED (0 << 2)
-+#define XT26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
-+#define XT26G0XA_STATUS_ECC_UNCOR_ERROR (2 << 4)
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(write_cache_variants,
-+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(update_cache_variants,
-+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
-+
-+static int xt26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section)
-+ return -ERANGE;
-+
-+ region->offset = 48;
-+ region->length = 16;
-+
-+ return 0;
-+}
-+
-+static int xt26g0xa_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section)
-+ return -ERANGE;
-+
-+ region->offset = 1;
-+ region->length = 47;
-+
-+ return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops xt26g0xa_ooblayout = {
-+ .ecc = xt26g0xa_ooblayout_ecc,
-+ .free = xt26g0xa_ooblayout_free,
-+};
-+
-+static int xt26g0xa_ecc_get_status(struct spinand_device *spinand,
-+ u8 status)
-+{
-+ status = status & XT26G0XA_STATUS_ECC_MASK;
-+
-+ switch (status) {
-+ case XT26G0XA_STATUS_ECC_NO_DETECTED:
-+ return 0;
-+ case XT26G0XA_STATUS_ECC_8_CORRECTED:
-+ return 8;
-+ case XT26G0XA_STATUS_ECC_UNCOR_ERROR:
-+ return -EBADMSG;
-+ default:
-+ break;
-+ }
-+
-+ /* At this point values greater than (2 << 4) are invalid */
-+ if (status > XT26G0XA_STATUS_ECC_UNCOR_ERROR)
-+ return -EINVAL;
-+
-+ /* (1 << 2) through (7 << 2) are 1-7 corrected errors */
-+ return status >> 2;
-+}
-+
-+static const struct spinand_info xtx_spinand_table[] = {
-+ SPINAND_INFO("XT26G01A",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&xt26g0xa_ooblayout,
-+ xt26g0xa_ecc_get_status)),
-+ SPINAND_INFO("XT26G02A",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE2),
-+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&xt26g0xa_ooblayout,
-+ xt26g0xa_ecc_get_status)),
-+ SPINAND_INFO("XT26G04A",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE3),
-+ NAND_MEMORG(1, 2048, 64, 128, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&xt26g0xa_ooblayout,
-+ xt26g0xa_ecc_get_status)),
-+};
-+
-+static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
-+};
-+
-+const struct spinand_manufacturer xtx_spinand_manufacturer = {
-+ .id = SPINAND_MFR_XTX,
-+ .name = "XTX",
-+ .chips = xtx_spinand_table,
-+ .nchips = ARRAY_SIZE(xtx_spinand_table),
-+ .ops = &xtx_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -266,6 +266,7 @@ extern const struct spinand_manufacturer
- extern const struct spinand_manufacturer paragon_spinand_manufacturer;
- extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
- extern const struct spinand_manufacturer winbond_spinand_manufacturer;
-+extern const struct spinand_manufacturer xtx_spinand_manufacturer;
-
- /**
- * struct spinand_op_variants - SPI NAND operation variants
diff --git a/target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch b/target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch
deleted file mode 100644
index d6c4b4fd1e..0000000000
--- a/target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch
+++ /dev/null
@@ -1,219 +0,0 @@
-From 4bf18d5a2dd02db8c5b16a2cfae513510506df5b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Thu, 3 Feb 2022 22:44:40 +0100
-Subject: [PATCH 1/2] phy: marvell: phy-mvebu-a3700-comphy: Remove port from
- driver configuration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Port number is encoded into argument for SMC call. It is zero for SATA,
-PCIe and also both USB 3.0 PHYs. It is non-zero only for Ethernet PHY
-(incorrectly called SGMII) on lane 0. Ethernet PHY on lane 1 also uses zero
-port number.
-
-So construct "port" bits for SMC call argument can be constructed directly
-from PHY type and lane number.
-
-Change driver code to always pass zero port number for non-ethernet PHYs
-and for ethernet PHYs determinate port number from lane number. This
-simplifies the driver.
-
-As port number from DT PHY configuration is not used anymore, remove whole
-driver code which parses it. This also simplifies the driver.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20220203214444.1508-2-kabel@kernel.org
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 62 +++++++++-----------
- 1 file changed, 29 insertions(+), 33 deletions(-)
-
---- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
-+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
-@@ -20,7 +20,6 @@
- #include <linux/platform_device.h>
-
- #define MVEBU_A3700_COMPHY_LANES 3
--#define MVEBU_A3700_COMPHY_PORTS 2
-
- /* COMPHY Fast SMC function identifiers */
- #define COMPHY_SIP_POWER_ON 0x82000001
-@@ -45,51 +44,47 @@
- #define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \
- ((idx) << 8) | \
- ((speed) << 2))
--#define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \
-+#define COMPHY_FW_PCIE(mode, speed, width) (COMPHY_FW_NET(mode, 0, speed) | \
- ((width) << 18))
-
- struct mvebu_a3700_comphy_conf {
- unsigned int lane;
- enum phy_mode mode;
- int submode;
-- unsigned int port;
- u32 fw_mode;
- };
-
--#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _port, _fw) \
-+#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _fw) \
- { \
- .lane = _lane, \
- .mode = _mode, \
- .submode = _smode, \
-- .port = _port, \
- .fw_mode = _fw, \
- }
-
--#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _port, _fw) \
-- MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _port, _fw)
-+#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _fw) \
-+ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _fw)
-
--#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _port, _fw) \
-- MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _port, _fw)
-+#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _fw) \
-+ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _fw)
-
- static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = {
- /* lane 0 */
-- MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0,
-+ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS,
- COMPHY_FW_MODE_USB3H),
-- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1,
-+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII,
- COMPHY_FW_MODE_SGMII),
-- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1,
-+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX,
- COMPHY_FW_MODE_2500BASEX),
- /* lane 1 */
-- MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0,
-- COMPHY_FW_MODE_PCIE),
-- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0,
-+ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
-+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII,
- COMPHY_FW_MODE_SGMII),
-- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0,
-+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX,
- COMPHY_FW_MODE_2500BASEX),
- /* lane 2 */
-- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0,
-- COMPHY_FW_MODE_SATA),
-- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, 0,
-+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
-+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS,
- COMPHY_FW_MODE_USB3H),
- };
-
-@@ -98,7 +93,6 @@ struct mvebu_a3700_comphy_lane {
- unsigned int id;
- enum phy_mode mode;
- int submode;
-- int port;
- };
-
- static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane,
-@@ -120,7 +114,7 @@ static int mvebu_a3700_comphy_smc(unsign
- }
- }
-
--static int mvebu_a3700_comphy_get_fw_mode(int lane, int port,
-+static int mvebu_a3700_comphy_get_fw_mode(int lane,
- enum phy_mode mode,
- int submode)
- {
-@@ -132,7 +126,6 @@ static int mvebu_a3700_comphy_get_fw_mod
-
- for (i = 0; i < n; i++) {
- if (mvebu_a3700_comphy_modes[i].lane == lane &&
-- mvebu_a3700_comphy_modes[i].port == port &&
- mvebu_a3700_comphy_modes[i].mode == mode &&
- mvebu_a3700_comphy_modes[i].submode == submode)
- break;
-@@ -153,7 +146,7 @@ static int mvebu_a3700_comphy_set_mode(s
- if (submode == PHY_INTERFACE_MODE_1000BASEX)
- submode = PHY_INTERFACE_MODE_SGMII;
-
-- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode,
-+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, mode,
- submode);
- if (fw_mode < 0) {
- dev_err(lane->dev, "invalid COMPHY mode\n");
-@@ -172,9 +165,10 @@ static int mvebu_a3700_comphy_power_on(s
- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
- u32 fw_param;
- int fw_mode;
-+ int fw_port;
- int ret;
-
-- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port,
-+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id,
- lane->mode, lane->submode);
- if (fw_mode < 0) {
- dev_err(lane->dev, "invalid COMPHY mode\n");
-@@ -191,17 +185,18 @@ static int mvebu_a3700_comphy_power_on(s
- fw_param = COMPHY_FW_MODE(fw_mode);
- break;
- case PHY_MODE_ETHERNET:
-+ fw_port = (lane->id == 0) ? 1 : 0;
- switch (lane->submode) {
- case PHY_INTERFACE_MODE_SGMII:
- dev_dbg(lane->dev, "set lane %d to SGMII mode\n",
- lane->id);
-- fw_param = COMPHY_FW_NET(fw_mode, lane->port,
-+ fw_param = COMPHY_FW_NET(fw_mode, fw_port,
- COMPHY_FW_SPEED_1_25G);
- break;
- case PHY_INTERFACE_MODE_2500BASEX:
- dev_dbg(lane->dev, "set lane %d to 2500BASEX mode\n",
- lane->id);
-- fw_param = COMPHY_FW_NET(fw_mode, lane->port,
-+ fw_param = COMPHY_FW_NET(fw_mode, fw_port,
- COMPHY_FW_SPEED_3_125G);
- break;
- default:
-@@ -212,8 +207,7 @@ static int mvebu_a3700_comphy_power_on(s
- break;
- case PHY_MODE_PCIE:
- dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id);
-- fw_param = COMPHY_FW_PCIE(fw_mode, lane->port,
-- COMPHY_FW_SPEED_5G,
-+ fw_param = COMPHY_FW_PCIE(fw_mode, COMPHY_FW_SPEED_5G,
- phy->attrs.bus_width);
- break;
- default:
-@@ -247,17 +241,20 @@ static struct phy *mvebu_a3700_comphy_xl
- struct of_phandle_args *args)
- {
- struct mvebu_a3700_comphy_lane *lane;
-+ unsigned int port;
- struct phy *phy;
-
-- if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS))
-- return ERR_PTR(-EINVAL);
--
- phy = of_phy_simple_xlate(dev, args);
- if (IS_ERR(phy))
- return phy;
-
- lane = phy_get_drvdata(phy);
-- lane->port = args->args[0];
-+
-+ port = args->args[0];
-+ if (port != 0 && (port != 1 || lane->id != 0)) {
-+ dev_err(lane->dev, "invalid port number %u\n", port);
-+ return ERR_PTR(-EINVAL);
-+ }
-
- return phy;
- }
-@@ -302,7 +299,6 @@ static int mvebu_a3700_comphy_probe(stru
- lane->mode = PHY_MODE_INVALID;
- lane->submode = PHY_INTERFACE_MODE_NA;
- lane->id = lane_id;
-- lane->port = -1;
- phy_set_drvdata(phy, lane);
- }
-
diff --git a/target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch b/target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch
deleted file mode 100644
index 4593d14bfe..0000000000
--- a/target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch
+++ /dev/null
@@ -1,1552 +0,0 @@
-From 934337080c6c59b75db76b180b509f218640ad48 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Thu, 3 Feb 2022 22:44:41 +0100
-Subject: [PATCH 2/2] phy: marvell: phy-mvebu-a3700-comphy: Add native kernel
- implementation
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove old RPC implementation and add a new native kernel implementation.
-
-The old implementation uses ARM SMC API to issue RPC calls to ARM Trusted
-Firmware which provides real implementation of PHY configuration.
-
-But older versions of ARM Trusted Firmware do not provide this PHY
-configuration functionality, simply returning: operation not supported; or
-worse, some versions provide the configuration functionality incorrectly.
-
-For example the firmware shipped in ESPRESSObin board has this older
-version of ARM Trusted Firmware and therefore SATA, USB 3.0 and PCIe
-functionality do not work with newer versions of Linux kernel.
-
-Due to the above reasons, the following commits were introduced into Linux,
-to workaround these issues by ignoring -EOPNOTSUPP error code from
-phy-mvebu-a3700-comphy driver function phy_power_on():
-
-commit 45aefe3d2251 ("ata: ahci: mvebu: Make SATA PHY optional for Armada
-3720")
-commit 3241929b67d2 ("usb: host: xhci: mvebu: make USB 3.0 PHY optional for
-Armada 3720")
-commit b0c6ae0f8948 ("PCI: aardvark: Fix initialization with old Marvell's
-Arm Trusted Firmware")
-
-Replace this RPC implementation with proper native kernel implementation,
-which is independent on the firmware. Never return -EOPNOTSUPP for proper
-arguments.
-
-This should solve multiple issues with real-world boards, where it is not
-possible or really inconvenient to change the firmware. Let's eliminate
-these issues.
-
-This implementation is ported directly from Armada 3720 comphy driver found
-in newest version of ARM Trusted Firmware source code, but with various
-fixes of register names, some added comments, some refactoring due to the
-original code not conforming to kernel standards. Also PCIe mode poweroff
-support was added here, and PHY reset support. These changes are also going
-to be sent to ARM Trusted Firmware.
-
-[ Pali did the porting from ATF.
- I (Marek) then fixed some register names, some various other things,
- added some comments and refactored the code to kernel standards. Also
- fixed PHY poweroff and added PHY reset. ]
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20220203214444.1508-3-kabel@kernel.org
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 1332 ++++++++++++++++--
- 1 file changed, 1215 insertions(+), 117 deletions(-)
-
---- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
-+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
-@@ -5,12 +5,16 @@
- * Authors:
- * Evan Wang <xswang@marvell.com>
- * Miquèl Raynal <miquel.raynal@bootlin.com>
-+ * Pali Rohár <pali@kernel.org>
-+ * Marek Behún <kabel@kernel.org>
- *
- * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart.
-- * SMC call initial support done by Grzegorz Jaszczyk.
-+ * Comphy code from ARM Trusted Firmware ported by Pali Rohár <pali@kernel.org>
-+ * and Marek Behún <kabel@kernel.org>.
- */
-
--#include <linux/arm-smccc.h>
-+#include <linux/bitfield.h>
-+#include <linux/clk.h>
- #include <linux/io.h>
- #include <linux/iopoll.h>
- #include <linux/mfd/syscon.h>
-@@ -18,103 +22,1118 @@
- #include <linux/phy.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-
--#define MVEBU_A3700_COMPHY_LANES 3
-+#define PLL_SET_DELAY_US 600
-+#define COMPHY_PLL_SLEEP 1000
-+#define COMPHY_PLL_TIMEOUT 150000
-+
-+/* Comphy lane2 indirect access register offset */
-+#define COMPHY_LANE2_INDIR_ADDR 0x0
-+#define COMPHY_LANE2_INDIR_DATA 0x4
-+
-+/* SATA and USB3 PHY offset compared to SATA PHY */
-+#define COMPHY_LANE2_REGS_BASE 0x200
-+
-+/*
-+ * When accessing common PHY lane registers directly, we need to shift by 1,
-+ * since the registers are 16-bit.
-+ */
-+#define COMPHY_LANE_REG_DIRECT(reg) (((reg) & 0x7FF) << 1)
-+
-+/* COMPHY registers */
-+#define COMPHY_POWER_PLL_CTRL 0x01
-+#define PU_IVREF_BIT BIT(15)
-+#define PU_PLL_BIT BIT(14)
-+#define PU_RX_BIT BIT(13)
-+#define PU_TX_BIT BIT(12)
-+#define PU_TX_INTP_BIT BIT(11)
-+#define PU_DFE_BIT BIT(10)
-+#define RESET_DTL_RX_BIT BIT(9)
-+#define PLL_LOCK_BIT BIT(8)
-+#define REF_FREF_SEL_MASK GENMASK(4, 0)
-+#define REF_FREF_SEL_SERDES_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x1)
-+#define REF_FREF_SEL_SERDES_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)
-+#define REF_FREF_SEL_SERDES_50MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x4)
-+#define REF_FREF_SEL_PCIE_USB3_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x2)
-+#define REF_FREF_SEL_PCIE_USB3_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)
-+#define COMPHY_MODE_MASK GENMASK(7, 5)
-+#define COMPHY_MODE_SATA FIELD_PREP(COMPHY_MODE_MASK, 0x0)
-+#define COMPHY_MODE_PCIE FIELD_PREP(COMPHY_MODE_MASK, 0x3)
-+#define COMPHY_MODE_SERDES FIELD_PREP(COMPHY_MODE_MASK, 0x4)
-+#define COMPHY_MODE_USB3 FIELD_PREP(COMPHY_MODE_MASK, 0x5)
-+
-+#define COMPHY_KVCO_CAL_CTRL 0x02
-+#define USE_MAX_PLL_RATE_BIT BIT(12)
-+#define SPEED_PLL_MASK GENMASK(7, 2)
-+#define SPEED_PLL_VALUE_16 FIELD_PREP(SPEED_PLL_MASK, 0x10)
-+
-+#define COMPHY_DIG_LOOPBACK_EN 0x23
-+#define SEL_DATA_WIDTH_MASK GENMASK(11, 10)
-+#define DATA_WIDTH_10BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x0)
-+#define DATA_WIDTH_20BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x1)
-+#define DATA_WIDTH_40BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x2)
-+#define PLL_READY_TX_BIT BIT(4)
-+
-+#define COMPHY_SYNC_PATTERN 0x24
-+#define TXD_INVERT_BIT BIT(10)
-+#define RXD_INVERT_BIT BIT(11)
-+
-+#define COMPHY_SYNC_MASK_GEN 0x25
-+#define PHY_GEN_MAX_MASK GENMASK(11, 10)
-+#define PHY_GEN_MAX_USB3_5G FIELD_PREP(PHY_GEN_MAX_MASK, 0x1)
-+
-+#define COMPHY_ISOLATION_CTRL 0x26
-+#define PHY_ISOLATE_MODE BIT(15)
-+
-+#define COMPHY_GEN2_SET2 0x3e
-+#define GS2_TX_SSC_AMP_MASK GENMASK(15, 9)
-+#define GS2_TX_SSC_AMP_4128 FIELD_PREP(GS2_TX_SSC_AMP_MASK, 0x20)
-+#define GS2_VREG_RXTX_MAS_ISET_MASK GENMASK(8, 7)
-+#define GS2_VREG_RXTX_MAS_ISET_60U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
-+ 0x0)
-+#define GS2_VREG_RXTX_MAS_ISET_80U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
-+ 0x1)
-+#define GS2_VREG_RXTX_MAS_ISET_100U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
-+ 0x2)
-+#define GS2_VREG_RXTX_MAS_ISET_120U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
-+ 0x3)
-+#define GS2_RSVD_6_0_MASK GENMASK(6, 0)
-+
-+#define COMPHY_GEN3_SET2 0x3f
-+
-+#define COMPHY_IDLE_SYNC_EN 0x48
-+#define IDLE_SYNC_EN BIT(12)
-+
-+#define COMPHY_MISC_CTRL0 0x4F
-+#define CLK100M_125M_EN BIT(4)
-+#define TXDCLK_2X_SEL BIT(6)
-+#define CLK500M_EN BIT(7)
-+#define PHY_REF_CLK_SEL BIT(10)
-+
-+#define COMPHY_SFT_RESET 0x52
-+#define SFT_RST BIT(9)
-+#define SFT_RST_NO_REG BIT(10)
-+
-+#define COMPHY_MISC_CTRL1 0x73
-+#define SEL_BITS_PCIE_FORCE BIT(15)
-+
-+#define COMPHY_GEN2_SET3 0x112
-+#define GS3_FFE_CAP_SEL_MASK GENMASK(3, 0)
-+#define GS3_FFE_CAP_SEL_VALUE FIELD_PREP(GS3_FFE_CAP_SEL_MASK, 0xF)
-+
-+/* PIPE registers */
-+#define COMPHY_PIPE_LANE_CFG0 0x180
-+#define PRD_TXDEEMPH0_MASK BIT(0)
-+#define PRD_TXMARGIN_MASK GENMASK(3, 1)
-+#define PRD_TXSWING_MASK BIT(4)
-+#define CFG_TX_ALIGN_POS_MASK GENMASK(8, 5)
-+
-+#define COMPHY_PIPE_LANE_CFG1 0x181
-+#define PRD_TXDEEMPH1_MASK BIT(15)
-+#define USE_MAX_PLL_RATE_EN BIT(9)
-+#define TX_DET_RX_MODE BIT(6)
-+#define GEN2_TX_DATA_DLY_MASK GENMASK(4, 3)
-+#define GEN2_TX_DATA_DLY_DEFT FIELD_PREP(GEN2_TX_DATA_DLY_MASK, 2)
-+#define TX_ELEC_IDLE_MODE_EN BIT(0)
-+
-+#define COMPHY_PIPE_LANE_STAT1 0x183
-+#define TXDCLK_PCLK_EN BIT(0)
-+
-+#define COMPHY_PIPE_LANE_CFG4 0x188
-+#define SPREAD_SPECTRUM_CLK_EN BIT(7)
-+
-+#define COMPHY_PIPE_RST_CLK_CTRL 0x1C1
-+#define PIPE_SOFT_RESET BIT(0)
-+#define PIPE_REG_RESET BIT(1)
-+#define MODE_CORE_CLK_FREQ_SEL BIT(9)
-+#define MODE_PIPE_WIDTH_32 BIT(3)
-+#define MODE_REFDIV_MASK GENMASK(5, 4)
-+#define MODE_REFDIV_BY_4 FIELD_PREP(MODE_REFDIV_MASK, 0x2)
-+
-+#define COMPHY_PIPE_TEST_MODE_CTRL 0x1C2
-+#define MODE_MARGIN_OVERRIDE BIT(2)
-+
-+#define COMPHY_PIPE_CLK_SRC_LO 0x1C3
-+#define MODE_CLK_SRC BIT(0)
-+#define BUNDLE_PERIOD_SEL BIT(1)
-+#define BUNDLE_PERIOD_SCALE_MASK GENMASK(3, 2)
-+#define BUNDLE_SAMPLE_CTRL BIT(4)
-+#define PLL_READY_DLY_MASK GENMASK(7, 5)
-+#define CFG_SEL_20B BIT(15)
-+
-+#define COMPHY_PIPE_PWR_MGM_TIM1 0x1D0
-+#define CFG_PM_OSCCLK_WAIT_MASK GENMASK(15, 12)
-+#define CFG_PM_RXDEN_WAIT_MASK GENMASK(11, 8)
-+#define CFG_PM_RXDEN_WAIT_1_UNIT FIELD_PREP(CFG_PM_RXDEN_WAIT_MASK, 0x1)
-+#define CFG_PM_RXDLOZ_WAIT_MASK GENMASK(7, 0)
-+#define CFG_PM_RXDLOZ_WAIT_7_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0x7)
-+#define CFG_PM_RXDLOZ_WAIT_12_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0xC)
-+
-+/*
-+ * This register is not from PHY lane register space. It only exists in the
-+ * indirect register space, before the actual PHY lane 2 registers. So the
-+ * offset is absolute, not relative to COMPHY_LANE2_REGS_BASE.
-+ * It is used only for SATA PHY initialization.
-+ */
-+#define COMPHY_RESERVED_REG 0x0E
-+#define PHYCTRL_FRM_PIN_BIT BIT(13)
-
--/* COMPHY Fast SMC function identifiers */
--#define COMPHY_SIP_POWER_ON 0x82000001
--#define COMPHY_SIP_POWER_OFF 0x82000002
--#define COMPHY_SIP_PLL_LOCK 0x82000003
--
--#define COMPHY_FW_MODE_SATA 0x1
--#define COMPHY_FW_MODE_SGMII 0x2
--#define COMPHY_FW_MODE_2500BASEX 0x3
--#define COMPHY_FW_MODE_USB3H 0x4
--#define COMPHY_FW_MODE_USB3D 0x5
--#define COMPHY_FW_MODE_PCIE 0x6
--#define COMPHY_FW_MODE_USB3 0xa
--
--#define COMPHY_FW_SPEED_1_25G 0 /* SGMII 1G */
--#define COMPHY_FW_SPEED_2_5G 1
--#define COMPHY_FW_SPEED_3_125G 2 /* 2500BASE-X */
--#define COMPHY_FW_SPEED_5G 3
--#define COMPHY_FW_SPEED_MAX 0x3F
--
--#define COMPHY_FW_MODE(mode) ((mode) << 12)
--#define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \
-- ((idx) << 8) | \
-- ((speed) << 2))
--#define COMPHY_FW_PCIE(mode, speed, width) (COMPHY_FW_NET(mode, 0, speed) | \
-- ((width) << 18))
-+/* South Bridge PHY Configuration Registers */
-+#define COMPHY_PHY_REG(lane, reg) (((1 - (lane)) * 0x28) + ((reg) & 0x3f))
-+
-+/*
-+ * lane0: USB3/GbE1 PHY Configuration 1
-+ * lane1: PCIe/GbE0 PHY Configuration 1
-+ * (used only by SGMII code)
-+ */
-+#define COMPHY_PHY_CFG1 0x0
-+#define PIN_PU_IVREF_BIT BIT(1)
-+#define PIN_RESET_CORE_BIT BIT(11)
-+#define PIN_RESET_COMPHY_BIT BIT(12)
-+#define PIN_PU_PLL_BIT BIT(16)
-+#define PIN_PU_RX_BIT BIT(17)
-+#define PIN_PU_TX_BIT BIT(18)
-+#define PIN_TX_IDLE_BIT BIT(19)
-+#define GEN_RX_SEL_MASK GENMASK(25, 22)
-+#define GEN_RX_SEL_VALUE(val) FIELD_PREP(GEN_RX_SEL_MASK, (val))
-+#define GEN_TX_SEL_MASK GENMASK(29, 26)
-+#define GEN_TX_SEL_VALUE(val) FIELD_PREP(GEN_TX_SEL_MASK, (val))
-+#define SERDES_SPEED_1_25_G 0x6
-+#define SERDES_SPEED_3_125_G 0x8
-+#define PHY_RX_INIT_BIT BIT(30)
-+
-+/*
-+ * lane0: USB3/GbE1 PHY Status 1
-+ * lane1: PCIe/GbE0 PHY Status 1
-+ * (used only by SGMII code)
-+ */
-+#define COMPHY_PHY_STAT1 0x18
-+#define PHY_RX_INIT_DONE_BIT BIT(0)
-+#define PHY_PLL_READY_RX_BIT BIT(2)
-+#define PHY_PLL_READY_TX_BIT BIT(3)
-+
-+/* PHY Selector */
-+#define COMPHY_SELECTOR_PHY_REG 0xFC
-+/* bit0: 0: Lane1 is GbE0; 1: Lane1 is PCIe */
-+#define COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT BIT(0)
-+/* bit4: 0: Lane0 is GbE1; 1: Lane0 is USB3 */
-+#define COMPHY_SELECTOR_USB3_GBE1_SEL_BIT BIT(4)
-+/* bit8: 0: Lane0 is USB3 instead of GbE1, Lane2 is SATA; 1: Lane2 is USB3 */
-+#define COMPHY_SELECTOR_USB3_PHY_SEL_BIT BIT(8)
-
- struct mvebu_a3700_comphy_conf {
- unsigned int lane;
- enum phy_mode mode;
- int submode;
-- u32 fw_mode;
- };
-
--#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _fw) \
-+#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode) \
- { \
- .lane = _lane, \
- .mode = _mode, \
- .submode = _smode, \
-- .fw_mode = _fw, \
- }
-
--#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _fw) \
-- MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _fw)
-+#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode) \
-+ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA)
-
--#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _fw) \
-- MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _fw)
-+#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode) \
-+ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode)
-
- static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = {
- /* lane 0 */
-- MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS,
-- COMPHY_FW_MODE_USB3H),
-- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII,
-- COMPHY_FW_MODE_SGMII),
-- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX,
-- COMPHY_FW_MODE_2500BASEX),
-+ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS),
-+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII),
-+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_1000BASEX),
-+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX),
- /* lane 1 */
-- MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
-- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII,
-- COMPHY_FW_MODE_SGMII),
-- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX,
-- COMPHY_FW_MODE_2500BASEX),
-+ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE),
-+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII),
-+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_1000BASEX),
-+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX),
- /* lane 2 */
-- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
-- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS,
-- COMPHY_FW_MODE_USB3H),
-+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA),
-+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS),
-+};
-+
-+struct mvebu_a3700_comphy_priv {
-+ void __iomem *comphy_regs;
-+ void __iomem *lane0_phy_regs; /* USB3 and GbE1 */
-+ void __iomem *lane1_phy_regs; /* PCIe and GbE0 */
-+ void __iomem *lane2_phy_indirect; /* SATA and USB3 */
-+ spinlock_t lock; /* for PHY selector access */
-+ bool xtal_is_40m;
- };
-
- struct mvebu_a3700_comphy_lane {
-+ struct mvebu_a3700_comphy_priv *priv;
- struct device *dev;
- unsigned int id;
- enum phy_mode mode;
- int submode;
-+ bool invert_tx;
-+ bool invert_rx;
-+ bool needs_reset;
-+};
-+
-+struct gbe_phy_init_data_fix {
-+ u16 addr;
-+ u16 value;
-+};
-+
-+/* Changes to 40M1G25 mode data required for running 40M3G125 init mode */
-+static struct gbe_phy_init_data_fix gbe_phy_init_fix[] = {
-+ { 0x005, 0x07CC }, { 0x015, 0x0000 }, { 0x01B, 0x0000 },
-+ { 0x01D, 0x0000 }, { 0x01E, 0x0000 }, { 0x01F, 0x0000 },
-+ { 0x020, 0x0000 }, { 0x021, 0x0030 }, { 0x026, 0x0888 },
-+ { 0x04D, 0x0152 }, { 0x04F, 0xA020 }, { 0x050, 0x07CC },
-+ { 0x053, 0xE9CA }, { 0x055, 0xBD97 }, { 0x071, 0x3015 },
-+ { 0x076, 0x03AA }, { 0x07C, 0x0FDF }, { 0x0C2, 0x3030 },
-+ { 0x0C3, 0x8000 }, { 0x0E2, 0x5550 }, { 0x0E3, 0x12A4 },
-+ { 0x0E4, 0x7D00 }, { 0x0E6, 0x0C83 }, { 0x101, 0xFCC0 },
-+ { 0x104, 0x0C10 }
- };
-
--static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane,
-- unsigned long mode)
-+/* 40M1G25 mode init data */
-+static u16 gbe_phy_init[512] = {
-+ /* 0 1 2 3 4 5 6 7 */
-+ /*-----------------------------------------------------------*/
-+ /* 8 9 A B C D E F */
-+ 0x3110, 0xFD83, 0x6430, 0x412F, 0x82C0, 0x06FA, 0x4500, 0x6D26, /* 00 */
-+ 0xAFC0, 0x8000, 0xC000, 0x0000, 0x2000, 0x49CC, 0x0BC9, 0x2A52, /* 08 */
-+ 0x0BD2, 0x0CDE, 0x13D2, 0x0CE8, 0x1149, 0x10E0, 0x0000, 0x0000, /* 10 */
-+ 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x4134, 0x0D2D, 0xFFFF, /* 18 */
-+ 0xFFE0, 0x4030, 0x1016, 0x0030, 0x0000, 0x0800, 0x0866, 0x0000, /* 20 */
-+ 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, /* 28 */
-+ 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */
-+ 0x0000, 0x0000, 0x000F, 0x6A62, 0x1988, 0x3100, 0x3100, 0x3100, /* 38 */
-+ 0x3100, 0xA708, 0x2430, 0x0830, 0x1030, 0x4610, 0xFF00, 0xFF00, /* 40 */
-+ 0x0060, 0x1000, 0x0400, 0x0040, 0x00F0, 0x0155, 0x1100, 0xA02A, /* 48 */
-+ 0x06FA, 0x0080, 0xB008, 0xE3ED, 0x5002, 0xB592, 0x7A80, 0x0001, /* 50 */
-+ 0x020A, 0x8820, 0x6014, 0x8054, 0xACAA, 0xFC88, 0x2A02, 0x45CF, /* 58 */
-+ 0x000F, 0x1817, 0x2860, 0x064F, 0x0000, 0x0204, 0x1800, 0x6000, /* 60 */
-+ 0x810F, 0x4F23, 0x4000, 0x4498, 0x0850, 0x0000, 0x000E, 0x1002, /* 68 */
-+ 0x9D3A, 0x3009, 0xD066, 0x0491, 0x0001, 0x6AB0, 0x0399, 0x3780, /* 70 */
-+ 0x0040, 0x5AC0, 0x4A80, 0x0000, 0x01DF, 0x0000, 0x0007, 0x0000, /* 78 */
-+ 0x2D54, 0x00A1, 0x4000, 0x0100, 0xA20A, 0x0000, 0x0000, 0x0000, /* 80 */
-+ 0x0000, 0x0000, 0x0000, 0x7400, 0x0E81, 0x1000, 0x1242, 0x0210, /* 88 */
-+ 0x80DF, 0x0F1F, 0x2F3F, 0x4F5F, 0x6F7F, 0x0F1F, 0x2F3F, 0x4F5F, /* 90 */
-+ 0x6F7F, 0x4BAD, 0x0000, 0x0000, 0x0800, 0x0000, 0x2400, 0xB651, /* 98 */
-+ 0xC9E0, 0x4247, 0x0A24, 0x0000, 0xAF19, 0x1004, 0x0000, 0x0000, /* A0 */
-+ 0x0000, 0x0013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* A8 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* B0 */
-+ 0x0000, 0x0000, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, /* B8 */
-+ 0x0000, 0x0000, 0x3010, 0xFA00, 0x0000, 0x0000, 0x0000, 0x0003, /* C0 */
-+ 0x1618, 0x8200, 0x8000, 0x0400, 0x050F, 0x0000, 0x0000, 0x0000, /* C8 */
-+ 0x4C93, 0x0000, 0x1000, 0x1120, 0x0010, 0x1242, 0x1242, 0x1E00, /* D0 */
-+ 0x0000, 0x0000, 0x0000, 0x00F8, 0x0000, 0x0041, 0x0800, 0x0000, /* D8 */
-+ 0x82A0, 0x572E, 0x2490, 0x14A9, 0x4E00, 0x0000, 0x0803, 0x0541, /* E0 */
-+ 0x0C15, 0x0000, 0x0000, 0x0400, 0x2626, 0x0000, 0x0000, 0x4200, /* E8 */
-+ 0x0000, 0xAA55, 0x1020, 0x0000, 0x0000, 0x5010, 0x0000, 0x0000, /* F0 */
-+ 0x0000, 0x0000, 0x5000, 0x0000, 0x0000, 0x0000, 0x02F2, 0x0000, /* F8 */
-+ 0x101F, 0xFDC0, 0x4000, 0x8010, 0x0110, 0x0006, 0x0000, 0x0000, /*100 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*108 */
-+ 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04C6, 0x0000, /*110 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*118 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*120 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*128 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*130 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*138 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*140 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*148 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*150 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*158 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*160 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*168 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*170 */
-+ 0x0000, 0x0000, 0x0000, 0x00F0, 0x08A2, 0x3112, 0x0A14, 0x0000, /*178 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*180 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*188 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*190 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*198 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A0 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A8 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B0 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B8 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C0 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C8 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D0 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D8 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E0 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E8 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1F0 */
-+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /*1F8 */
-+};
-+
-+static inline void comphy_reg_set(void __iomem *addr, u32 data, u32 mask)
- {
-- struct arm_smccc_res res;
-- s32 ret;
-+ u32 val;
-+
-+ val = readl(addr);
-+ val = (val & ~mask) | (data & mask);
-+ writel(val, addr);
-+}
-
-- arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res);
-- ret = res.a0;
-+static inline void comphy_reg_set16(void __iomem *addr, u16 data, u16 mask)
-+{
-+ u16 val;
-
-- switch (ret) {
-- case SMCCC_RET_SUCCESS:
-- return 0;
-- case SMCCC_RET_NOT_SUPPORTED:
-- return -EOPNOTSUPP;
-+ val = readw(addr);
-+ val = (val & ~mask) | (data & mask);
-+ writew(val, addr);
-+}
-+
-+/* Used for accessing lane 2 registers (SATA/USB3 PHY) */
-+static void comphy_set_indirect(struct mvebu_a3700_comphy_priv *priv,
-+ u32 offset, u16 data, u16 mask)
-+{
-+ writel(offset,
-+ priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_ADDR);
-+ comphy_reg_set(priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_DATA,
-+ data, mask);
-+}
-+
-+static void comphy_lane_reg_set(struct mvebu_a3700_comphy_lane *lane,
-+ u16 reg, u16 data, u16 mask)
-+{
-+ if (lane->id == 2) {
-+ /* lane 2 PHY registers are accessed indirectly */
-+ comphy_set_indirect(lane->priv,
-+ reg + COMPHY_LANE2_REGS_BASE,
-+ data, mask);
-+ } else {
-+ void __iomem *base = lane->id == 1 ?
-+ lane->priv->lane1_phy_regs :
-+ lane->priv->lane0_phy_regs;
-+
-+ comphy_reg_set16(base + COMPHY_LANE_REG_DIRECT(reg),
-+ data, mask);
-+ }
-+}
-+
-+static int comphy_lane_reg_poll(struct mvebu_a3700_comphy_lane *lane,
-+ u16 reg, u16 bits,
-+ ulong sleep_us, ulong timeout_us)
-+{
-+ int ret;
-+
-+ if (lane->id == 2) {
-+ u32 data;
-+
-+ /* lane 2 PHY registers are accessed indirectly */
-+ writel(reg + COMPHY_LANE2_REGS_BASE,
-+ lane->priv->lane2_phy_indirect +
-+ COMPHY_LANE2_INDIR_ADDR);
-+
-+ ret = readl_poll_timeout(lane->priv->lane2_phy_indirect +
-+ COMPHY_LANE2_INDIR_DATA,
-+ data, (data & bits) == bits,
-+ sleep_us, timeout_us);
-+ } else {
-+ void __iomem *base = lane->id == 1 ?
-+ lane->priv->lane1_phy_regs :
-+ lane->priv->lane0_phy_regs;
-+ u16 data;
-+
-+ ret = readw_poll_timeout(base + COMPHY_LANE_REG_DIRECT(reg),
-+ data, (data & bits) == bits,
-+ sleep_us, timeout_us);
-+ }
-+
-+ return ret;
-+}
-+
-+static void comphy_periph_reg_set(struct mvebu_a3700_comphy_lane *lane,
-+ u8 reg, u32 data, u32 mask)
-+{
-+ comphy_reg_set(lane->priv->comphy_regs + COMPHY_PHY_REG(lane->id, reg),
-+ data, mask);
-+}
-+
-+static int comphy_periph_reg_poll(struct mvebu_a3700_comphy_lane *lane,
-+ u8 reg, u32 bits,
-+ ulong sleep_us, ulong timeout_us)
-+{
-+ u32 data;
-+
-+ return readl_poll_timeout(lane->priv->comphy_regs +
-+ COMPHY_PHY_REG(lane->id, reg),
-+ data, (data & bits) == bits,
-+ sleep_us, timeout_us);
-+}
-+
-+/* PHY selector configures with corresponding modes */
-+static int
-+mvebu_a3700_comphy_set_phy_selector(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ u32 old, new, clr = 0, set = 0;
-+ unsigned long flags;
-+
-+ switch (lane->mode) {
-+ case PHY_MODE_SATA:
-+ /* SATA must be in Lane2 */
-+ if (lane->id == 2)
-+ clr = COMPHY_SELECTOR_USB3_PHY_SEL_BIT;
-+ else
-+ goto error;
-+ break;
-+
-+ case PHY_MODE_ETHERNET:
-+ if (lane->id == 0)
-+ clr = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;
-+ else if (lane->id == 1)
-+ clr = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT;
-+ else
-+ goto error;
-+ break;
-+
-+ case PHY_MODE_USB_HOST_SS:
-+ if (lane->id == 2)
-+ set = COMPHY_SELECTOR_USB3_PHY_SEL_BIT;
-+ else if (lane->id == 0)
-+ set = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;
-+ else
-+ goto error;
-+ break;
-+
-+ case PHY_MODE_PCIE:
-+ /* PCIE must be in Lane1 */
-+ if (lane->id == 1)
-+ set = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT;
-+ else
-+ goto error;
-+ break;
-+
-+ default:
-+ goto error;
-+ }
-+
-+ spin_lock_irqsave(&lane->priv->lock, flags);
-+
-+ old = readl(lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG);
-+ new = (old & ~clr) | set;
-+ writel(new, lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG);
-+
-+ spin_unlock_irqrestore(&lane->priv->lock, flags);
-+
-+ dev_dbg(lane->dev,
-+ "COMPHY[%d] mode[%d] changed PHY selector 0x%08x -> 0x%08x\n",
-+ lane->id, lane->mode, old, new);
-+
-+ return 0;
-+error:
-+ dev_err(lane->dev, "COMPHY[%d] mode[%d] is invalid\n", lane->id,
-+ lane->mode);
-+ return -EINVAL;
-+}
-+
-+static int
-+mvebu_a3700_comphy_sata_power_on(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ u32 mask, data, ref_clk;
-+ int ret;
-+
-+ /* Configure phy selector for SATA */
-+ ret = mvebu_a3700_comphy_set_phy_selector(lane);
-+ if (ret)
-+ return ret;
-+
-+ /* Clear phy isolation mode to make it work in normal mode */
-+ comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL,
-+ 0x0, PHY_ISOLATE_MODE);
-+
-+ /* 0. Check the Polarity invert bits */
-+ data = 0x0;
-+ if (lane->invert_tx)
-+ data |= TXD_INVERT_BIT;
-+ if (lane->invert_rx)
-+ data |= RXD_INVERT_BIT;
-+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
-+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
-+
-+ /* 1. Select 40-bit data width */
-+ comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN,
-+ DATA_WIDTH_40BIT, SEL_DATA_WIDTH_MASK);
-+
-+ /* 2. Select reference clock(25M) and PHY mode (SATA) */
-+ if (lane->priv->xtal_is_40m)
-+ ref_clk = REF_FREF_SEL_SERDES_40MHZ;
-+ else
-+ ref_clk = REF_FREF_SEL_SERDES_25MHZ;
-+
-+ data = ref_clk | COMPHY_MODE_SATA;
-+ mask = REF_FREF_SEL_MASK | COMPHY_MODE_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
-+
-+ /* 3. Use maximum PLL rate (no power save) */
-+ comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL,
-+ USE_MAX_PLL_RATE_BIT, USE_MAX_PLL_RATE_BIT);
-+
-+ /* 4. Reset reserved bit */
-+ comphy_set_indirect(lane->priv, COMPHY_RESERVED_REG,
-+ 0x0, PHYCTRL_FRM_PIN_BIT);
-+
-+ /* 5. Set vendor-specific configuration (It is done in sata driver) */
-+ /* XXX: in U-Boot below sequence was executed in this place, in Linux
-+ * not. Now it is done only in U-Boot before this comphy
-+ * initialization - tests shows that it works ok, but in case of any
-+ * future problem it is left for reference.
-+ * reg_set(MVEBU_REGS_BASE + 0xe00a0, 0, 0xffffffff);
-+ * reg_set(MVEBU_REGS_BASE + 0xe00a4, BIT(6), BIT(6));
-+ */
-+
-+ /* Wait for > 55 us to allow PLL be enabled */
-+ udelay(PLL_SET_DELAY_US);
-+
-+ /* Polling status */
-+ ret = comphy_lane_reg_poll(lane, COMPHY_DIG_LOOPBACK_EN,
-+ PLL_READY_TX_BIT, COMPHY_PLL_SLEEP,
-+ COMPHY_PLL_TIMEOUT);
-+ if (ret)
-+ dev_err(lane->dev, "Failed to lock SATA PLL\n");
-+
-+ return ret;
-+}
-+
-+static void comphy_gbe_phy_init(struct mvebu_a3700_comphy_lane *lane,
-+ bool is_1gbps)
-+{
-+ int addr, fix_idx;
-+ u16 val;
-+
-+ fix_idx = 0;
-+ for (addr = 0; addr < 512; addr++) {
-+ /*
-+ * All PHY register values are defined in full for 3.125Gbps
-+ * SERDES speed. The values required for 1.25 Gbps are almost
-+ * the same and only few registers should be "fixed" in
-+ * comparison to 3.125 Gbps values. These register values are
-+ * stored in "gbe_phy_init_fix" array.
-+ */
-+ if (!is_1gbps && gbe_phy_init_fix[fix_idx].addr == addr) {
-+ /* Use new value */
-+ val = gbe_phy_init_fix[fix_idx].value;
-+ if (fix_idx < ARRAY_SIZE(gbe_phy_init_fix))
-+ fix_idx++;
-+ } else {
-+ val = gbe_phy_init[addr];
-+ }
-+
-+ comphy_lane_reg_set(lane, addr, val, 0xFFFF);
-+ }
-+}
-+
-+static int
-+mvebu_a3700_comphy_ethernet_power_on(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ u32 mask, data, speed_sel;
-+ int ret;
-+
-+ /* Set selector */
-+ ret = mvebu_a3700_comphy_set_phy_selector(lane);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * 1. Reset PHY by setting PHY input port PIN_RESET=1.
-+ * 2. Set PHY input port PIN_TX_IDLE=1, PIN_PU_IVREF=1 to keep
-+ * PHY TXP/TXN output to idle state during PHY initialization
-+ * 3. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0.
-+ */
-+ data = PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT | PIN_RESET_COMPHY_BIT;
-+ mask = data | PIN_RESET_CORE_BIT | PIN_PU_PLL_BIT | PIN_PU_RX_BIT |
-+ PIN_PU_TX_BIT | PHY_RX_INIT_BIT;
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
-+
-+ /* 4. Release reset to the PHY by setting PIN_RESET=0. */
-+ data = 0x0;
-+ mask = PIN_RESET_COMPHY_BIT;
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
-+
-+ /*
-+ * 5. Set PIN_PHY_GEN_TX[3:0] and PIN_PHY_GEN_RX[3:0] to decide COMPHY
-+ * bit rate
-+ */
-+ switch (lane->submode) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ /* SGMII 1G, SerDes speed 1.25G */
-+ speed_sel = SERDES_SPEED_1_25_G;
-+ break;
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ /* 2500Base-X, SerDes speed 3.125G */
-+ speed_sel = SERDES_SPEED_3_125_G;
-+ break;
- default:
-+ /* Other rates are not supported */
-+ dev_err(lane->dev,
-+ "unsupported phy speed %d on comphy lane%d\n",
-+ lane->submode, lane->id);
- return -EINVAL;
- }
-+ data = GEN_RX_SEL_VALUE(speed_sel) | GEN_TX_SEL_VALUE(speed_sel);
-+ mask = GEN_RX_SEL_MASK | GEN_TX_SEL_MASK;
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
-+
-+ /*
-+ * 6. Wait 10mS for bandgap and reference clocks to stabilize; then
-+ * start SW programming.
-+ */
-+ mdelay(10);
-+
-+ /* 7. Program COMPHY register PHY_MODE */
-+ data = COMPHY_MODE_SERDES;
-+ mask = COMPHY_MODE_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
-+
-+ /*
-+ * 8. Set COMPHY register REFCLK_SEL to select the correct REFCLK
-+ * source
-+ */
-+ data = 0x0;
-+ mask = PHY_REF_CLK_SEL;
-+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask);
-+
-+ /*
-+ * 9. Set correct reference clock frequency in COMPHY register
-+ * REF_FREF_SEL.
-+ */
-+ if (lane->priv->xtal_is_40m)
-+ data = REF_FREF_SEL_SERDES_50MHZ;
-+ else
-+ data = REF_FREF_SEL_SERDES_25MHZ;
-+
-+ mask = REF_FREF_SEL_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
-+
-+ /*
-+ * 10. Program COMPHY register PHY_GEN_MAX[1:0]
-+ * This step is mentioned in the flow received from verification team.
-+ * However the PHY_GEN_MAX value is only meaningful for other interfaces
-+ * (not SERDES). For instance, it selects SATA speed 1.5/3/6 Gbps or
-+ * PCIe speed 2.5/5 Gbps
-+ */
-+
-+ /*
-+ * 11. Program COMPHY register SEL_BITS to set correct parallel data
-+ * bus width
-+ */
-+ data = DATA_WIDTH_10BIT;
-+ mask = SEL_DATA_WIDTH_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, data, mask);
-+
-+ /*
-+ * 12. As long as DFE function needs to be enabled in any mode,
-+ * COMPHY register DFE_UPDATE_EN[5:0] shall be programmed to 0x3F
-+ * for real chip during COMPHY power on.
-+ * The value of the DFE_UPDATE_EN already is 0x3F, because it is the
-+ * default value after reset of the PHY.
-+ */
-+
-+ /*
-+ * 13. Program COMPHY GEN registers.
-+ * These registers should be programmed based on the lab testing result
-+ * to achieve optimal performance. Please contact the CEA group to get
-+ * the related GEN table during real chip bring-up. We only required to
-+ * run though the entire registers programming flow defined by
-+ * "comphy_gbe_phy_init" when the REF clock is 40 MHz. For REF clock
-+ * 25 MHz the default values stored in PHY registers are OK.
-+ */
-+ dev_dbg(lane->dev, "Running C-DPI phy init %s mode\n",
-+ lane->submode == PHY_INTERFACE_MODE_2500BASEX ? "2G5" : "1G");
-+ if (lane->priv->xtal_is_40m)
-+ comphy_gbe_phy_init(lane,
-+ lane->submode != PHY_INTERFACE_MODE_2500BASEX);
-+
-+ /*
-+ * 14. Check the PHY Polarity invert bit
-+ */
-+ data = 0x0;
-+ if (lane->invert_tx)
-+ data |= TXD_INVERT_BIT;
-+ if (lane->invert_rx)
-+ data |= RXD_INVERT_BIT;
-+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
-+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
-+
-+ /*
-+ * 15. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1 to
-+ * start PHY power up sequence. All the PHY register programming should
-+ * be done before PIN_PU_PLL=1. There should be no register programming
-+ * for normal PHY operation from this point.
-+ */
-+ data = PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT;
-+ mask = data;
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
-+
-+ /*
-+ * 16. Wait for PHY power up sequence to finish by checking output ports
-+ * PIN_PLL_READY_TX=1 and PIN_PLL_READY_RX=1.
-+ */
-+ ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,
-+ PHY_PLL_READY_TX_BIT |
-+ PHY_PLL_READY_RX_BIT,
-+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
-+ if (ret) {
-+ dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n",
-+ lane->id);
-+ return ret;
-+ }
-+
-+ /*
-+ * 17. Set COMPHY input port PIN_TX_IDLE=0
-+ */
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, 0x0, PIN_TX_IDLE_BIT);
-+
-+ /*
-+ * 18. After valid data appear on PIN_RXDATA bus, set PIN_RX_INIT=1. To
-+ * start RX initialization. PIN_RX_INIT_DONE will be cleared to 0 by the
-+ * PHY After RX initialization is done, PIN_RX_INIT_DONE will be set to
-+ * 1 by COMPHY Set PIN_RX_INIT=0 after PIN_RX_INIT_DONE= 1. Please
-+ * refer to RX initialization part for details.
-+ */
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1,
-+ PHY_RX_INIT_BIT, PHY_RX_INIT_BIT);
-+
-+ ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,
-+ PHY_PLL_READY_TX_BIT |
-+ PHY_PLL_READY_RX_BIT,
-+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
-+ if (ret) {
-+ dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n",
-+ lane->id);
-+ return ret;
-+ }
-+
-+ ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,
-+ PHY_RX_INIT_DONE_BIT,
-+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
-+ if (ret)
-+ dev_err(lane->dev, "Failed to init RX of SERDES PHY %d\n",
-+ lane->id);
-+
-+ return ret;
- }
-
--static int mvebu_a3700_comphy_get_fw_mode(int lane,
-+static int
-+mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ u32 mask, data, cfg, ref_clk;
-+ int ret;
-+
-+ /* Set phy seclector */
-+ ret = mvebu_a3700_comphy_set_phy_selector(lane);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The
-+ * register belong to UTMI module, so it is set in UTMI phy driver.
-+ */
-+
-+ /*
-+ * 1. Set PRD_TXDEEMPH (3.5db de-emph)
-+ */
-+ data = PRD_TXDEEMPH0_MASK;
-+ mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK |
-+ CFG_TX_ALIGN_POS_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG0, data, mask);
-+
-+ /*
-+ * 2. Set BIT0: enable transmitter in high impedance mode
-+ * Set BIT[3:4]: delay 2 clock cycles for HiZ off latency
-+ * Set BIT6: Tx detect Rx at HiZ mode
-+ * Unset BIT15: set to 0 to set USB3 De-emphasize level to -3.5db
-+ * together with bit 0 of COMPHY_PIPE_LANE_CFG0 register
-+ */
-+ data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN;
-+ mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK |
-+ TX_ELEC_IDLE_MODE_EN;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, data, mask);
-+
-+ /*
-+ * 3. Set Spread Spectrum Clock Enabled
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG4,
-+ SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN);
-+
-+ /*
-+ * 4. Set Override Margining Controls From the MAC:
-+ * Use margining signals from lane configuration
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_TEST_MODE_CTRL,
-+ MODE_MARGIN_OVERRIDE, 0xFFFF);
-+
-+ /*
-+ * 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles
-+ * set Mode Clock Source = PCLK is generated from REFCLK
-+ */
-+ data = 0x0;
-+ mask = MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE_MASK |
-+ BUNDLE_SAMPLE_CTRL | PLL_READY_DLY_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, data, mask);
-+
-+ /*
-+ * 6. Set G2 Spread Spectrum Clock Amplitude at 4K
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_GEN2_SET2,
-+ GS2_TX_SSC_AMP_4128, GS2_TX_SSC_AMP_MASK);
-+
-+ /*
-+ * 7. Unset G3 Spread Spectrum Clock Amplitude
-+ * set G3 TX and RX Register Master Current Select
-+ */
-+ data = GS2_VREG_RXTX_MAS_ISET_60U;
-+ mask = GS2_TX_SSC_AMP_MASK | GS2_VREG_RXTX_MAS_ISET_MASK |
-+ GS2_RSVD_6_0_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_GEN3_SET2, data, mask);
-+
-+ /*
-+ * 8. Check crystal jumper setting and program the Power and PLL Control
-+ * accordingly Change RX wait
-+ */
-+ if (lane->priv->xtal_is_40m) {
-+ ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ;
-+ cfg = CFG_PM_RXDLOZ_WAIT_12_UNIT;
-+ } else {
-+ ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ;
-+ cfg = CFG_PM_RXDLOZ_WAIT_7_UNIT;
-+ }
-+
-+ data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
-+ PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_USB3 | ref_clk;
-+ mask = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
-+ PU_TX_INTP_BIT | PU_DFE_BIT | PLL_LOCK_BIT | COMPHY_MODE_MASK |
-+ REF_FREF_SEL_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
-+
-+ data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg;
-+ mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |
-+ CFG_PM_RXDLOZ_WAIT_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask);
-+
-+ /*
-+ * 9. Enable idle sync
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN,
-+ IDLE_SYNC_EN, IDLE_SYNC_EN);
-+
-+ /*
-+ * 10. Enable the output of 500M clock
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, CLK500M_EN, CLK500M_EN);
-+
-+ /*
-+ * 11. Set 20-bit data width
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN,
-+ DATA_WIDTH_20BIT, 0xFFFF);
-+
-+ /*
-+ * 12. Override Speed_PLL value and use MAC PLL
-+ */
-+ data = SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT;
-+ mask = 0xFFFF;
-+ comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, data, mask);
-+
-+ /*
-+ * 13. Check the Polarity invert bit
-+ */
-+ data = 0x0;
-+ if (lane->invert_tx)
-+ data |= TXD_INVERT_BIT;
-+ if (lane->invert_rx)
-+ data |= RXD_INVERT_BIT;
-+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
-+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
-+
-+ /*
-+ * 14. Set max speed generation to USB3.0 5Gbps
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_SYNC_MASK_GEN,
-+ PHY_GEN_MAX_USB3_5G, PHY_GEN_MAX_MASK);
-+
-+ /*
-+ * 15. Set capacitor value for FFE gain peaking to 0xF
-+ */
-+ comphy_lane_reg_set(lane, COMPHY_GEN2_SET3,
-+ GS3_FFE_CAP_SEL_VALUE, GS3_FFE_CAP_SEL_MASK);
-+
-+ /*
-+ * 16. Release SW reset
-+ */
-+ data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4;
-+ mask = 0xFFFF;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);
-+
-+ /* Wait for > 55 us to allow PCLK be enabled */
-+ udelay(PLL_SET_DELAY_US);
-+
-+ ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN,
-+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
-+ if (ret)
-+ dev_err(lane->dev, "Failed to lock USB3 PLL\n");
-+
-+ return ret;
-+}
-+
-+static int
-+mvebu_a3700_comphy_pcie_power_on(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ u32 mask, data, ref_clk;
-+ int ret;
-+
-+ /* Configure phy selector for PCIe */
-+ ret = mvebu_a3700_comphy_set_phy_selector(lane);
-+ if (ret)
-+ return ret;
-+
-+ /* 1. Enable max PLL. */
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1,
-+ USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN);
-+
-+ /* 2. Select 20 bit SERDES interface. */
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO,
-+ CFG_SEL_20B, CFG_SEL_20B);
-+
-+ /* 3. Force to use reg setting for PCIe mode */
-+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL1,
-+ SEL_BITS_PCIE_FORCE, SEL_BITS_PCIE_FORCE);
-+
-+ /* 4. Change RX wait */
-+ data = CFG_PM_RXDEN_WAIT_1_UNIT | CFG_PM_RXDLOZ_WAIT_12_UNIT;
-+ mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |
-+ CFG_PM_RXDLOZ_WAIT_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask);
-+
-+ /* 5. Enable idle sync */
-+ comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN,
-+ IDLE_SYNC_EN, IDLE_SYNC_EN);
-+
-+ /* 6. Enable the output of 100M/125M/500M clock */
-+ data = CLK500M_EN | TXDCLK_2X_SEL | CLK100M_125M_EN;
-+ mask = data;
-+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask);
-+
-+ /*
-+ * 7. Enable TX, PCIE global register, 0xd0074814, it is done in
-+ * PCI-E driver
-+ */
-+
-+ /*
-+ * 8. Check crystal jumper setting and program the Power and PLL
-+ * Control accordingly
-+ */
-+
-+ if (lane->priv->xtal_is_40m)
-+ ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ;
-+ else
-+ ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ;
-+
-+ data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
-+ PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_PCIE | ref_clk;
-+ mask = 0xFFFF;
-+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
-+
-+ /* 9. Override Speed_PLL value and use MAC PLL */
-+ comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL,
-+ SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT,
-+ 0xFFFF);
-+
-+ /* 10. Check the Polarity invert bit */
-+ data = 0x0;
-+ if (lane->invert_tx)
-+ data |= TXD_INVERT_BIT;
-+ if (lane->invert_rx)
-+ data |= RXD_INVERT_BIT;
-+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
-+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
-+
-+ /* 11. Release SW reset */
-+ data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32;
-+ mask = data | PIPE_SOFT_RESET | MODE_REFDIV_MASK;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);
-+
-+ /* Wait for > 55 us to allow PCLK be enabled */
-+ udelay(PLL_SET_DELAY_US);
-+
-+ ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN,
-+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
-+ if (ret)
-+ dev_err(lane->dev, "Failed to lock PCIE PLL\n");
-+
-+ return ret;
-+}
-+
-+static void
-+mvebu_a3700_comphy_sata_power_off(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ /* Set phy isolation mode */
-+ comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL,
-+ PHY_ISOLATE_MODE, PHY_ISOLATE_MODE);
-+
-+ /* Power off PLL, Tx, Rx */
-+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL,
-+ 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);
-+}
-+
-+static void
-+mvebu_a3700_comphy_ethernet_power_off(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ u32 mask, data;
-+
-+ data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | PIN_PU_IVREF_BIT |
-+ PHY_RX_INIT_BIT;
-+ mask = data;
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
-+}
-+
-+static void
-+mvebu_a3700_comphy_pcie_power_off(struct mvebu_a3700_comphy_lane *lane)
-+{
-+ /* Power off PLL, Tx, Rx */
-+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL,
-+ 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);
-+}
-+
-+static int mvebu_a3700_comphy_reset(struct phy *phy)
-+{
-+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
-+ u16 mask, data;
-+
-+ dev_dbg(lane->dev, "resetting lane %d\n", lane->id);
-+
-+ /* COMPHY reset for internal logic */
-+ comphy_lane_reg_set(lane, COMPHY_SFT_RESET,
-+ SFT_RST_NO_REG, SFT_RST_NO_REG);
-+
-+ /* COMPHY register reset (cleared automatically) */
-+ comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST);
-+
-+ /* PIPE soft and register reset */
-+ data = PIPE_SOFT_RESET | PIPE_REG_RESET;
-+ mask = data;
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);
-+
-+ /* Release PIPE register reset */
-+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL,
-+ 0x0, PIPE_REG_RESET);
-+
-+ /* Reset SB configuration register (only for lanes 0 and 1) */
-+ if (lane->id == 0 || lane->id == 1) {
-+ u32 mask, data;
-+
-+ data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT |
-+ PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT;
-+ mask = data | PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT;
-+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
-+ }
-+
-+ return 0;
-+}
-+
-+static bool mvebu_a3700_comphy_check_mode(int lane,
- enum phy_mode mode,
- int submode)
- {
-@@ -122,7 +1141,7 @@ static int mvebu_a3700_comphy_get_fw_mod
-
- /* Unused PHY mux value is 0x0 */
- if (mode == PHY_MODE_INVALID)
-- return -EINVAL;
-+ return false;
-
- for (i = 0; i < n; i++) {
- if (mvebu_a3700_comphy_modes[i].lane == lane &&
-@@ -132,27 +1151,30 @@ static int mvebu_a3700_comphy_get_fw_mod
- }
-
- if (i == n)
-- return -EINVAL;
-+ return false;
-
-- return mvebu_a3700_comphy_modes[i].fw_mode;
-+ return true;
- }
-
- static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode,
- int submode)
- {
- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
-- int fw_mode;
-
-- if (submode == PHY_INTERFACE_MODE_1000BASEX)
-- submode = PHY_INTERFACE_MODE_SGMII;
--
-- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, mode,
-- submode);
-- if (fw_mode < 0) {
-+ if (!mvebu_a3700_comphy_check_mode(lane->id, mode, submode)) {
- dev_err(lane->dev, "invalid COMPHY mode\n");
-- return fw_mode;
-+ return -EINVAL;
- }
-
-+ /* Mode cannot be changed while the PHY is powered on */
-+ if (phy->power_count &&
-+ (lane->mode != mode || lane->submode != submode))
-+ return -EBUSY;
-+
-+ /* If changing mode, ensure reset is called */
-+ if (lane->mode != PHY_MODE_INVALID && lane->mode != mode)
-+ lane->needs_reset = true;
-+
- /* Just remember the mode, ->power_on() will do the real setup */
- lane->mode = mode;
- lane->submode = submode;
-@@ -163,76 +1185,77 @@ static int mvebu_a3700_comphy_set_mode(s
- static int mvebu_a3700_comphy_power_on(struct phy *phy)
- {
- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
-- u32 fw_param;
-- int fw_mode;
-- int fw_port;
- int ret;
-
-- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id,
-- lane->mode, lane->submode);
-- if (fw_mode < 0) {
-+ if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode,
-+ lane->submode)) {
- dev_err(lane->dev, "invalid COMPHY mode\n");
-- return fw_mode;
-+ return -EINVAL;
-+ }
-+
-+ if (lane->needs_reset) {
-+ ret = mvebu_a3700_comphy_reset(phy);
-+ if (ret)
-+ return ret;
-+
-+ lane->needs_reset = false;
- }
-
- switch (lane->mode) {
- case PHY_MODE_USB_HOST_SS:
- dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id);
-- fw_param = COMPHY_FW_MODE(fw_mode);
-- break;
-+ return mvebu_a3700_comphy_usb3_power_on(lane);
- case PHY_MODE_SATA:
- dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id);
-- fw_param = COMPHY_FW_MODE(fw_mode);
-- break;
-+ return mvebu_a3700_comphy_sata_power_on(lane);
- case PHY_MODE_ETHERNET:
-- fw_port = (lane->id == 0) ? 1 : 0;
-- switch (lane->submode) {
-- case PHY_INTERFACE_MODE_SGMII:
-- dev_dbg(lane->dev, "set lane %d to SGMII mode\n",
-- lane->id);
-- fw_param = COMPHY_FW_NET(fw_mode, fw_port,
-- COMPHY_FW_SPEED_1_25G);
-- break;
-- case PHY_INTERFACE_MODE_2500BASEX:
-- dev_dbg(lane->dev, "set lane %d to 2500BASEX mode\n",
-- lane->id);
-- fw_param = COMPHY_FW_NET(fw_mode, fw_port,
-- COMPHY_FW_SPEED_3_125G);
-- break;
-- default:
-- dev_err(lane->dev, "unsupported PHY submode (%d)\n",
-- lane->submode);
-- return -ENOTSUPP;
-- }
-- break;
-+ dev_dbg(lane->dev, "set lane %d to Ethernet mode\n", lane->id);
-+ return mvebu_a3700_comphy_ethernet_power_on(lane);
- case PHY_MODE_PCIE:
- dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id);
-- fw_param = COMPHY_FW_PCIE(fw_mode, COMPHY_FW_SPEED_5G,
-- phy->attrs.bus_width);
-- break;
-+ return mvebu_a3700_comphy_pcie_power_on(lane);
- default:
- dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode);
-- return -ENOTSUPP;
-+ return -EOPNOTSUPP;
- }
--
-- ret = mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param);
-- if (ret == -EOPNOTSUPP)
-- dev_err(lane->dev,
-- "unsupported SMC call, try updating your firmware\n");
--
-- return ret;
- }
-
- static int mvebu_a3700_comphy_power_off(struct phy *phy)
- {
- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
-
-- return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0);
-+ switch (lane->mode) {
-+ case PHY_MODE_USB_HOST_SS:
-+ /*
-+ * The USB3 MAC sets the USB3 PHY to low state, so we do not
-+ * need to power off USB3 PHY again.
-+ */
-+ break;
-+
-+ case PHY_MODE_SATA:
-+ mvebu_a3700_comphy_sata_power_off(lane);
-+ break;
-+
-+ case PHY_MODE_ETHERNET:
-+ mvebu_a3700_comphy_ethernet_power_off(lane);
-+ break;
-+
-+ case PHY_MODE_PCIE:
-+ mvebu_a3700_comphy_pcie_power_off(lane);
-+ break;
-+
-+ default:
-+ dev_err(lane->dev, "invalid COMPHY mode\n");
-+ return -EINVAL;
-+ }
-+
-+ return 0;
- }
-
- static const struct phy_ops mvebu_a3700_comphy_ops = {
- .power_on = mvebu_a3700_comphy_power_on,
- .power_off = mvebu_a3700_comphy_power_off,
-+ .reset = mvebu_a3700_comphy_reset,
- .set_mode = mvebu_a3700_comphy_set_mode,
- .owner = THIS_MODULE,
- };
-@@ -256,13 +1279,75 @@ static struct phy *mvebu_a3700_comphy_xl
- return ERR_PTR(-EINVAL);
- }
-
-+ lane->invert_tx = args->args[1] & BIT(0);
-+ lane->invert_rx = args->args[1] & BIT(1);
-+
- return phy;
- }
-
- static int mvebu_a3700_comphy_probe(struct platform_device *pdev)
- {
-+ struct mvebu_a3700_comphy_priv *priv;
- struct phy_provider *provider;
- struct device_node *child;
-+ struct resource *res;
-+ struct clk *clk;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->lock);
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "comphy");
-+ priv->comphy_regs = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(priv->comphy_regs))
-+ return PTR_ERR(priv->comphy_regs);
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-+ "lane1_pcie_gbe");
-+ priv->lane1_phy_regs = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(priv->lane1_phy_regs))
-+ return PTR_ERR(priv->lane1_phy_regs);
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-+ "lane0_usb3_gbe");
-+ priv->lane0_phy_regs = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(priv->lane0_phy_regs))
-+ return PTR_ERR(priv->lane0_phy_regs);
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-+ "lane2_sata_usb3");
-+ priv->lane2_phy_indirect = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(priv->lane2_phy_indirect))
-+ return PTR_ERR(priv->lane2_phy_indirect);
-+
-+ /*
-+ * Driver needs to know if reference xtal clock is 40MHz or 25MHz.
-+ * Old DT bindings do not have xtal clk present. So do not fail here
-+ * and expects that default 25MHz reference clock is used.
-+ */
-+ clk = clk_get(&pdev->dev, "xtal");
-+ if (IS_ERR(clk)) {
-+ if (PTR_ERR(clk) == -EPROBE_DEFER)
-+ return -EPROBE_DEFER;
-+ dev_warn(&pdev->dev, "missing 'xtal' clk (%ld)\n",
-+ PTR_ERR(clk));
-+ } else {
-+ ret = clk_prepare_enable(clk);
-+ if (ret) {
-+ dev_warn(&pdev->dev, "enabling xtal clk failed (%d)\n",
-+ ret);
-+ } else {
-+ if (clk_get_rate(clk) == 40000000)
-+ priv->xtal_is_40m = true;
-+ clk_disable_unprepare(clk);
-+ }
-+ clk_put(clk);
-+ }
-+
-+ dev_set_drvdata(&pdev->dev, priv);
-
- for_each_available_child_of_node(pdev->dev.of_node, child) {
- struct mvebu_a3700_comphy_lane *lane;
-@@ -277,7 +1362,7 @@ static int mvebu_a3700_comphy_probe(stru
- continue;
- }
-
-- if (lane_id >= MVEBU_A3700_COMPHY_LANES) {
-+ if (lane_id >= 3) {
- dev_err(&pdev->dev, "invalid 'reg' property\n");
- continue;
- }
-@@ -295,15 +1380,26 @@ static int mvebu_a3700_comphy_probe(stru
- return PTR_ERR(phy);
- }
-
-+ lane->priv = priv;
- lane->dev = &pdev->dev;
- lane->mode = PHY_MODE_INVALID;
- lane->submode = PHY_INTERFACE_MODE_NA;
- lane->id = lane_id;
-+ lane->invert_tx = false;
-+ lane->invert_rx = false;
- phy_set_drvdata(phy, lane);
-+
-+ /*
-+ * To avoid relying on the bootloader/firmware configuration,
-+ * power off all comphys.
-+ */
-+ mvebu_a3700_comphy_reset(phy);
-+ lane->needs_reset = false;
- }
-
- provider = devm_of_phy_provider_register(&pdev->dev,
- mvebu_a3700_comphy_xlate);
-+
- return PTR_ERR_OR_ZERO(provider);
- }
-
-@@ -323,5 +1419,7 @@ static struct platform_driver mvebu_a370
- module_platform_driver(mvebu_a3700_comphy_driver);
-
- MODULE_AUTHOR("Miquèl Raynal <miquel.raynal@bootlin.com>");
-+MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
-+MODULE_AUTHOR("Marek Behún <kabel@kernel.org>");
- MODULE_DESCRIPTION("Common PHY driver for A3700");
- MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch b/target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch
deleted file mode 100644
index 03b6a5754d..0000000000
--- a/target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 73a78b6130d9e13daca22b86ad52f063b9403e03 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Wed, 8 Dec 2021 03:40:35 +0100
-Subject: [PATCH 1/1] arm64: dts: marvell: armada-37xx: Add xtal clock to
- comphy node
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Kernel driver phy-mvebu-a3700-comphy.c needs to know the rate of the
-reference xtal clock. So add missing xtal clock source into comphy device
-tree node. If the property is not present, the driver defaults to 25 MHz
-xtal rate (which, as far as we know, is used by all the existing boards).
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
----
- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
-+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
-@@ -265,6 +265,8 @@
- "lane2_sata_usb3";
- #address-cells = <1>;
- #size-cells = <0>;
-+ clocks = <&xtalclk>;
-+ clock-names = "xtal";
-
- comphy0: phy@0 {
- reg = <0>;
diff --git a/target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch b/target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch
deleted file mode 100644
index 35bc19c1ef..0000000000
--- a/target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From ee995101fde67f85a3cd4c74f4f92fc4592e726b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Thu, 3 Feb 2022 22:44:42 +0100
-Subject: [PATCH 1/3] Revert "ata: ahci: mvebu: Make SATA PHY optional for
- Armada 3720"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit 45aefe3d2251e4e229d7662052739f96ad1d08d9.
-
-Armada 3720 PHY driver (phy-mvebu-a3700-comphy.c) does not return
--EOPNOTSUPP from phy_power_on() callback anymore.
-
-So remove AHCI_HFLAG_IGN_NOTSUPP_POWER_ON flag from Armada 3720 plat data.
-
-AHCI_HFLAG_IGN_NOTSUPP_POWER_ON is not used by any other ahci driver, so
-remove this flag completely.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Acked-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
-Link: https://lore.kernel.org/r/20220203214444.1508-4-kabel@kernel.org
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/ata/ahci.h | 2 --
- drivers/ata/ahci_mvebu.c | 2 +-
- drivers/ata/libahci_platform.c | 2 +-
- 3 files changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -240,8 +240,6 @@ enum {
- as default lpm_policy */
- AHCI_HFLAG_SUSPEND_PHYS = BIT(26), /* handle PHYs during
- suspend/resume */
-- AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = BIT(27), /* ignore -EOPNOTSUPP
-- from phy_power_on() */
- AHCI_HFLAG_NO_SXS = BIT(28), /* SXS not supported */
- AHCI_HFLAG_43BIT_ONLY = BIT(29), /* 43bit DMA addr limit */
-
---- a/drivers/ata/ahci_mvebu.c
-+++ b/drivers/ata/ahci_mvebu.c
-@@ -227,7 +227,7 @@ static const struct ahci_mvebu_plat_data
-
- static const struct ahci_mvebu_plat_data ahci_mvebu_armada_3700_plat_data = {
- .plat_config = ahci_mvebu_armada_3700_config,
-- .flags = AHCI_HFLAG_SUSPEND_PHYS | AHCI_HFLAG_IGN_NOTSUPP_POWER_ON,
-+ .flags = AHCI_HFLAG_SUSPEND_PHYS,
- };
-
- static const struct of_device_id ahci_mvebu_of_match[] = {
---- a/drivers/ata/libahci_platform.c
-+++ b/drivers/ata/libahci_platform.c
-@@ -59,7 +59,7 @@ int ahci_platform_enable_phys(struct ahc
- }
-
- rc = phy_power_on(hpriv->phys[i]);
-- if (rc && !(rc == -EOPNOTSUPP && (hpriv->flags & AHCI_HFLAG_IGN_NOTSUPP_POWER_ON))) {
-+ if (rc) {
- phy_exit(hpriv->phys[i]);
- goto disable_phys;
- }
diff --git a/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch b/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch
deleted file mode 100644
index 8cd86e0fcb..0000000000
--- a/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 8e10548f7f4814e530857d2049d6af6bc78add53 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Thu, 3 Feb 2022 22:44:43 +0100
-Subject: [PATCH 2/3] Revert "usb: host: xhci: mvebu: make USB 3.0 PHY optional
- for Armada 3720"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit 3241929b67d28c83945d3191c6816a3271fd6b85.
-
-Armada 3720 phy driver (phy-mvebu-a3700-comphy.c) does not return
--EOPNOTSUPP from phy_power_on() callback anymore.
-
-So remove XHCI_SKIP_PHY_INIT flag from xhci_mvebu_a3700_plat_setup() and
-then also whole xhci_mvebu_a3700_plat_setup() function which is there just
-to handle -EOPNOTSUPP for XHCI_SKIP_PHY_INIT.
-
-xhci plat_setup callback is not used by any other xhci plat driver, so
-remove this callback completely.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Link: https://lore.kernel.org/r/20220203214444.1508-5-kabel@kernel.org
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/usb/host/xhci-mvebu.c | 42 -----------------------------------
- drivers/usb/host/xhci-mvebu.h | 6 -----
- drivers/usb/host/xhci-plat.c | 20 +----------------
- drivers/usb/host/xhci-plat.h | 1 -
- 4 files changed, 1 insertion(+), 68 deletions(-)
-
---- a/drivers/usb/host/xhci-mvebu.c
-+++ b/drivers/usb/host/xhci-mvebu.c
-@@ -8,7 +8,6 @@
- #include <linux/mbus.h>
- #include <linux/of.h>
- #include <linux/platform_device.h>
--#include <linux/phy/phy.h>
-
- #include <linux/usb.h>
- #include <linux/usb/hcd.h>
-@@ -74,47 +73,6 @@ int xhci_mvebu_mbus_init_quirk(struct us
-
- return 0;
- }
--
--int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd)
--{
-- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-- struct device *dev = hcd->self.controller;
-- struct phy *phy;
-- int ret;
--
-- /* Old bindings miss the PHY handle */
-- phy = of_phy_get(dev->of_node, "usb3-phy");
-- if (IS_ERR(phy) && PTR_ERR(phy) == -EPROBE_DEFER)
-- return -EPROBE_DEFER;
-- else if (IS_ERR(phy))
-- goto phy_out;
--
-- ret = phy_init(phy);
-- if (ret)
-- goto phy_put;
--
-- ret = phy_set_mode(phy, PHY_MODE_USB_HOST_SS);
-- if (ret)
-- goto phy_exit;
--
-- ret = phy_power_on(phy);
-- if (ret == -EOPNOTSUPP) {
-- /* Skip initializatin of XHCI PHY when it is unsupported by firmware */
-- dev_warn(dev, "PHY unsupported by firmware\n");
-- xhci->quirks |= XHCI_SKIP_PHY_INIT;
-- }
-- if (ret)
-- goto phy_exit;
--
-- phy_power_off(phy);
--phy_exit:
-- phy_exit(phy);
--phy_put:
-- of_phy_put(phy);
--phy_out:
--
-- return 0;
--}
-
- int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
- {
---- a/drivers/usb/host/xhci-mvebu.h
-+++ b/drivers/usb/host/xhci-mvebu.h
-@@ -12,18 +12,12 @@ struct usb_hcd;
-
- #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
- int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
--int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd);
- int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd);
- #else
- static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
- {
- return 0;
- }
--
--static inline int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd)
--{
-- return 0;
--}
-
- static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
- {
---- a/drivers/usb/host/xhci-plat.c
-+++ b/drivers/usb/host/xhci-plat.c
-@@ -44,16 +44,6 @@ static void xhci_priv_plat_start(struct
- priv->plat_start(hcd);
- }
-
--static int xhci_priv_plat_setup(struct usb_hcd *hcd)
--{
-- struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
--
-- if (!priv->plat_setup)
-- return 0;
--
-- return priv->plat_setup(hcd);
--}
--
- static int xhci_priv_init_quirk(struct usb_hcd *hcd)
- {
- struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
-@@ -121,7 +111,6 @@ static const struct xhci_plat_priv xhci_
- };
-
- static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
-- .plat_setup = xhci_mvebu_a3700_plat_setup,
- .init_quirk = xhci_mvebu_a3700_init_quirk,
- };
-
-@@ -344,14 +333,7 @@ static int xhci_plat_probe(struct platfo
-
- hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
- xhci->shared_hcd->tpl_support = hcd->tpl_support;
--
-- if (priv) {
-- ret = xhci_priv_plat_setup(hcd);
-- if (ret)
-- goto disable_usb_phy;
-- }
--
-- if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)))
-+ if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))
- hcd->skip_phy_initialization = 1;
-
- if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK))
---- a/drivers/usb/host/xhci-plat.h
-+++ b/drivers/usb/host/xhci-plat.h
-@@ -13,7 +13,6 @@
- struct xhci_plat_priv {
- const char *firmware_name;
- unsigned long long quirks;
-- int (*plat_setup)(struct usb_hcd *);
- void (*plat_start)(struct usb_hcd *);
- int (*init_quirk)(struct usb_hcd *);
- int (*suspend_quirk)(struct usb_hcd *);
diff --git a/target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch b/target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch
deleted file mode 100644
index fcfb02d35a..0000000000
--- a/target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 9a4556dad7bd0a6b8339cb72e169f5c76f2af6f1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Thu, 3 Feb 2022 22:44:44 +0100
-Subject: [PATCH 3/3] Revert "PCI: aardvark: Fix initialization with old
- Marvell's Arm Trusted Firmware"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit b0c6ae0f8948a2be6bf4e8b4bbab9ca1343289b6.
-
-Armada 3720 phy driver (phy-mvebu-a3700-comphy.c) does not return
--EOPNOTSUPP from phy_power_on() callback anymore.
-
-So remove dead code which handles -EOPNOTSUPP return value.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-Link: https://lore.kernel.org/r/20220203214444.1508-6-kabel@kernel.org
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/pci/controller/pci-aardvark.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/pci/controller/pci-aardvark.c
-+++ b/drivers/pci/controller/pci-aardvark.c
-@@ -1642,9 +1642,7 @@ static int advk_pcie_enable_phy(struct a
- }
-
- ret = phy_power_on(pcie->phy);
-- if (ret == -EOPNOTSUPP) {
-- dev_warn(&pcie->pdev->dev, "PHY unsupported by firmware\n");
-- } else if (ret) {
-+ if (ret) {
- phy_exit(pcie->phy);
- return ret;
- }
diff --git a/target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch b/target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch
deleted file mode 100644
index a2c897b7a9..0000000000
--- a/target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch
+++ /dev/null
@@ -1,194 +0,0 @@
-From 0a6fc70d76bddf98278af2ac000379c82aec8f11 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Mon, 29 Aug 2022 10:30:46 +0200
-Subject: [PATCH] phy: marvell: phy-mvebu-a3700-comphy: Remove broken reset
- support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Reset support for SATA PHY is somehow broken and after calling it, kernel
-is not able to detect and initialize SATA disk Samsung SSD 850 EMT0 [1].
-
-Reset support was introduced in commit 934337080c6c ("phy: marvell:
-phy-mvebu-a3700-comphy: Add native kernel implementation") as part of
-complete rewrite of this driver. v1 patch series of that commit [2] did
-not contain reset support and was tested that is working fine with
-Ethernet, SATA and USB PHYs without issues too.
-
-So for now remove broken reset support and change implementation of
-power_off callback to power off all functions on specified lane (and not
-only selected function) because during startup kernel does not know which
-function was selected and configured by bootloader. Same logic was used
-also in v1 patch series of that commit.
-
-This change fixes issues with initialization of SATA disk Samsung SSD 850
-and disk is working again, like before mentioned commit.
-
-Once problem with PHY reset callback is solved its functionality could be
-re-introduced. But for now it is unknown why it does not work.
-
-[1] - https://lore.kernel.org/r/20220531124159.3e4lgn2v462irbtz@shindev/
-[2] - https://lore.kernel.org/r/20211028184242.22105-1-kabel@kernel.org/
-
-Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
-Fixes: 934337080c6c ("phy: marvell: phy-mvebu-a3700-comphy: Add native kernel implementation")
-Cc: stable@vger.kernel.org # v5.18+
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Tested-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
-Link: https://lore.kernel.org/r/20220829083046.15082-1-pali@kernel.org
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 87 ++++----------------
- 1 file changed, 17 insertions(+), 70 deletions(-)
-
---- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
-+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
-@@ -274,7 +274,6 @@ struct mvebu_a3700_comphy_lane {
- int submode;
- bool invert_tx;
- bool invert_rx;
-- bool needs_reset;
- };
-
- struct gbe_phy_init_data_fix {
-@@ -1097,40 +1096,12 @@ mvebu_a3700_comphy_pcie_power_off(struct
- 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);
- }
-
--static int mvebu_a3700_comphy_reset(struct phy *phy)
-+static void mvebu_a3700_comphy_usb3_power_off(struct mvebu_a3700_comphy_lane *lane)
- {
-- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
-- u16 mask, data;
--
-- dev_dbg(lane->dev, "resetting lane %d\n", lane->id);
--
-- /* COMPHY reset for internal logic */
-- comphy_lane_reg_set(lane, COMPHY_SFT_RESET,
-- SFT_RST_NO_REG, SFT_RST_NO_REG);
--
-- /* COMPHY register reset (cleared automatically) */
-- comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST);
--
-- /* PIPE soft and register reset */
-- data = PIPE_SOFT_RESET | PIPE_REG_RESET;
-- mask = data;
-- comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);
--
-- /* Release PIPE register reset */
-- comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL,
-- 0x0, PIPE_REG_RESET);
--
-- /* Reset SB configuration register (only for lanes 0 and 1) */
-- if (lane->id == 0 || lane->id == 1) {
-- u32 mask, data;
--
-- data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT |
-- PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT;
-- mask = data | PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT;
-- comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
-- }
--
-- return 0;
-+ /*
-+ * The USB3 MAC sets the USB3 PHY to low state, so we do not
-+ * need to power off USB3 PHY again.
-+ */
- }
-
- static bool mvebu_a3700_comphy_check_mode(int lane,
-@@ -1171,10 +1142,6 @@ static int mvebu_a3700_comphy_set_mode(s
- (lane->mode != mode || lane->submode != submode))
- return -EBUSY;
-
-- /* If changing mode, ensure reset is called */
-- if (lane->mode != PHY_MODE_INVALID && lane->mode != mode)
-- lane->needs_reset = true;
--
- /* Just remember the mode, ->power_on() will do the real setup */
- lane->mode = mode;
- lane->submode = submode;
-@@ -1185,7 +1152,6 @@ static int mvebu_a3700_comphy_set_mode(s
- static int mvebu_a3700_comphy_power_on(struct phy *phy)
- {
- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
-- int ret;
-
- if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode,
- lane->submode)) {
-@@ -1193,14 +1159,6 @@ static int mvebu_a3700_comphy_power_on(s
- return -EINVAL;
- }
-
-- if (lane->needs_reset) {
-- ret = mvebu_a3700_comphy_reset(phy);
-- if (ret)
-- return ret;
--
-- lane->needs_reset = false;
-- }
--
- switch (lane->mode) {
- case PHY_MODE_USB_HOST_SS:
- dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id);
-@@ -1224,38 +1182,28 @@ static int mvebu_a3700_comphy_power_off(
- {
- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
-
-- switch (lane->mode) {
-- case PHY_MODE_USB_HOST_SS:
-- /*
-- * The USB3 MAC sets the USB3 PHY to low state, so we do not
-- * need to power off USB3 PHY again.
-- */
-- break;
--
-- case PHY_MODE_SATA:
-- mvebu_a3700_comphy_sata_power_off(lane);
-- break;
--
-- case PHY_MODE_ETHERNET:
-+ switch (lane->id) {
-+ case 0:
-+ mvebu_a3700_comphy_usb3_power_off(lane);
- mvebu_a3700_comphy_ethernet_power_off(lane);
-- break;
--
-- case PHY_MODE_PCIE:
-+ return 0;
-+ case 1:
- mvebu_a3700_comphy_pcie_power_off(lane);
-- break;
--
-+ mvebu_a3700_comphy_ethernet_power_off(lane);
-+ return 0;
-+ case 2:
-+ mvebu_a3700_comphy_usb3_power_off(lane);
-+ mvebu_a3700_comphy_sata_power_off(lane);
-+ return 0;
- default:
- dev_err(lane->dev, "invalid COMPHY mode\n");
- return -EINVAL;
- }
--
-- return 0;
- }
-
- static const struct phy_ops mvebu_a3700_comphy_ops = {
- .power_on = mvebu_a3700_comphy_power_on,
- .power_off = mvebu_a3700_comphy_power_off,
-- .reset = mvebu_a3700_comphy_reset,
- .set_mode = mvebu_a3700_comphy_set_mode,
- .owner = THIS_MODULE,
- };
-@@ -1393,8 +1341,7 @@ static int mvebu_a3700_comphy_probe(stru
- * To avoid relying on the bootloader/firmware configuration,
- * power off all comphys.
- */
-- mvebu_a3700_comphy_reset(phy);
-- lane->needs_reset = false;
-+ mvebu_a3700_comphy_power_off(phy);
- }
-
- provider = devm_of_phy_provider_register(&pdev->dev,
diff --git a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch b/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch
deleted file mode 100644
index 175df150cc..0000000000
--- a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 86fc59ef818beb0e1945d17f8e734898baba7e4e Mon Sep 17 00:00:00 2001
-From: Colin Foster <colin.foster@in-advantage.com>
-Date: Sun, 13 Mar 2022 15:45:23 -0700
-Subject: [PATCH 1/2] regmap: add configurable downshift for addresses
-
-Add an additional reg_downshift to be applied to register addresses before
-any register accesses. An example of a device that uses this is a VSC7514
-chip, which require each register address to be downshifted by two if the
-access is performed over a SPI bus.
-
-Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
-Link: https://lore.kernel.org/r/20220313224524.399947-2-colin.foster@in-advantage.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/base/regmap/internal.h | 1 +
- drivers/base/regmap/regmap.c | 5 +++++
- include/linux/regmap.h | 3 +++
- 3 files changed, 9 insertions(+)
-
---- a/drivers/base/regmap/internal.h
-+++ b/drivers/base/regmap/internal.h
-@@ -31,6 +31,7 @@ struct regmap_format {
- size_t buf_size;
- size_t reg_bytes;
- size_t pad_bytes;
-+ size_t reg_downshift;
- size_t val_bytes;
- void (*format_write)(struct regmap *map,
- unsigned int reg, unsigned int val);
---- a/drivers/base/regmap/regmap.c
-+++ b/drivers/base/regmap/regmap.c
-@@ -823,6 +823,7 @@ struct regmap *__regmap_init(struct devi
-
- map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
- map->format.pad_bytes = config->pad_bits / 8;
-+ map->format.reg_downshift = config->reg_downshift;
- map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
- map->format.buf_size = DIV_ROUND_UP(config->reg_bits +
- config->val_bits + config->pad_bits, 8);
-@@ -1750,6 +1751,7 @@ static int _regmap_raw_write_impl(struct
- return ret;
- }
-
-+ reg >>= map->format.reg_downshift;
- map->format.format_reg(map->work_buf, reg, map->reg_shift);
- regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
- map->write_flag_mask);
-@@ -1920,6 +1922,7 @@ static int _regmap_bus_formatted_write(v
- return ret;
- }
-
-+ reg >>= map->format.reg_downshift;
- map->format.format_write(map, reg, val);
-
- trace_regmap_hw_write_start(map, reg, 1);
-@@ -2360,6 +2363,7 @@ static int _regmap_raw_multi_reg_write(s
- unsigned int reg = regs[i].reg;
- unsigned int val = regs[i].def;
- trace_regmap_hw_write_start(map, reg, 1);
-+ reg >>= map->format.reg_downshift;
- map->format.format_reg(u8, reg, map->reg_shift);
- u8 += reg_bytes + pad_bytes;
- map->format.format_val(u8, val, 0);
-@@ -2685,6 +2689,7 @@ static int _regmap_raw_read(struct regma
- return ret;
- }
-
-+ reg >>= map->format.reg_downshift;
- map->format.format_reg(map->work_buf, reg, map->reg_shift);
- regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
- map->read_flag_mask);
---- a/include/linux/regmap.h
-+++ b/include/linux/regmap.h
-@@ -237,6 +237,8 @@ typedef void (*regmap_unlock)(void *);
- * @reg_stride: The register address stride. Valid register addresses are a
- * multiple of this value. If set to 0, a value of 1 will be
- * used.
-+ * @reg_downshift: The number of bits to downshift the register before
-+ * performing any operations.
- * @pad_bits: Number of bits of padding between register and value.
- * @val_bits: Number of bits in a register value, mandatory.
- *
-@@ -366,6 +368,7 @@ struct regmap_config {
-
- int reg_bits;
- int reg_stride;
-+ int reg_downshift;
- int pad_bits;
- int val_bits;
-
diff --git a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch b/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch
deleted file mode 100644
index df716c4b65..0000000000
--- a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 0074f3f2b1e43d3cedd97e47fb6980db6d2ba79e Mon Sep 17 00:00:00 2001
-From: Colin Foster <colin.foster@in-advantage.com>
-Date: Sun, 13 Mar 2022 15:45:24 -0700
-Subject: [PATCH 2/2] regmap: allow a defined reg_base to be added to every
- address
-
-There's an inconsistency that arises when a register set can be accessed
-internally via MMIO, or externally via SPI. The VSC7514 chip allows both
-modes of operation. When internally accessed, the system utilizes __iomem,
-devm_ioremap_resource, and devm_regmap_init_mmio.
-
-For SPI it isn't possible to utilize memory-mapped IO. To properly operate,
-the resource base must be added to the register before every operation.
-
-Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
-Link: https://lore.kernel.org/r/20220313224524.399947-3-colin.foster@in-advantage.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/base/regmap/internal.h | 1 +
- drivers/base/regmap/regmap.c | 6 ++++++
- include/linux/regmap.h | 3 +++
- 3 files changed, 10 insertions(+)
-
---- a/drivers/base/regmap/internal.h
-+++ b/drivers/base/regmap/internal.h
-@@ -63,6 +63,7 @@ struct regmap {
- regmap_unlock unlock;
- void *lock_arg; /* This is passed to lock/unlock functions */
- gfp_t alloc_flags;
-+ unsigned int reg_base;
-
- struct device *dev; /* Device we do I/O on */
- void *work_buf; /* Scratch buffer used to format I/O */
---- a/drivers/base/regmap/regmap.c
-+++ b/drivers/base/regmap/regmap.c
-@@ -821,6 +821,8 @@ struct regmap *__regmap_init(struct devi
- else
- map->alloc_flags = GFP_KERNEL;
-
-+ map->reg_base = config->reg_base;
-+
- map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
- map->format.pad_bytes = config->pad_bits / 8;
- map->format.reg_downshift = config->reg_downshift;
-@@ -1751,6 +1753,7 @@ static int _regmap_raw_write_impl(struct
- return ret;
- }
-
-+ reg += map->reg_base;
- reg >>= map->format.reg_downshift;
- map->format.format_reg(map->work_buf, reg, map->reg_shift);
- regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
-@@ -1922,6 +1925,7 @@ static int _regmap_bus_formatted_write(v
- return ret;
- }
-
-+ reg += map->reg_base;
- reg >>= map->format.reg_downshift;
- map->format.format_write(map, reg, val);
-
-@@ -2363,6 +2367,7 @@ static int _regmap_raw_multi_reg_write(s
- unsigned int reg = regs[i].reg;
- unsigned int val = regs[i].def;
- trace_regmap_hw_write_start(map, reg, 1);
-+ reg += map->reg_base;
- reg >>= map->format.reg_downshift;
- map->format.format_reg(u8, reg, map->reg_shift);
- u8 += reg_bytes + pad_bytes;
-@@ -2689,6 +2694,7 @@ static int _regmap_raw_read(struct regma
- return ret;
- }
-
-+ reg += map->reg_base;
- reg >>= map->format.reg_downshift;
- map->format.format_reg(map->work_buf, reg, map->reg_shift);
- regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
---- a/include/linux/regmap.h
-+++ b/include/linux/regmap.h
-@@ -239,6 +239,8 @@ typedef void (*regmap_unlock)(void *);
- * used.
- * @reg_downshift: The number of bits to downshift the register before
- * performing any operations.
-+ * @reg_base: Value to be added to every register address before performing any
-+ * operation.
- * @pad_bits: Number of bits of padding between register and value.
- * @val_bits: Number of bits in a register value, mandatory.
- *
-@@ -369,6 +371,7 @@ struct regmap_config {
- int reg_bits;
- int reg_stride;
- int reg_downshift;
-+ unsigned int reg_base;
- int pad_bits;
- int val_bits;
-
diff --git a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch b/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch
deleted file mode 100644
index 33de94cb17..0000000000
--- a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 697c3892d825fb78f42ec8e53bed065dd728db3e Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 30 Jan 2023 02:04:57 +0000
-Subject: [PATCH] regmap: apply reg_base and reg_downshift for single register
- ops
-
-reg_base and reg_downshift currently don't have any effect if used with
-a regmap_bus or regmap_config which only offers single register
-operations (ie. reg_read, reg_write and optionally reg_update_bits).
-
-Fix that and take them into account also for regmap_bus with only
-reg_read and read_write operations by applying reg_base and
-reg_downshift in _regmap_bus_reg_write, _regmap_bus_reg_read.
-
-Also apply reg_base and reg_downshift in _regmap_update_bits, but only
-in case the operation is carried out with a reg_update_bits call
-defined in either regmap_bus or regmap_config.
-
-Fixes: 0074f3f2b1e43d ("regmap: allow a defined reg_base to be added to every address")
-Fixes: 86fc59ef818beb ("regmap: add configurable downshift for addresses")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Colin Foster <colin.foster@in-advantage.com>
-Link: https://lore.kernel.org/r/Y9clyVS3tQEHlUhA@makrotopia.org
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/base/regmap/regmap.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/base/regmap/regmap.c
-+++ b/drivers/base/regmap/regmap.c
-@@ -1943,6 +1943,8 @@ static int _regmap_bus_reg_write(void *c
- {
- struct regmap *map = context;
-
-+ reg += map->reg_base;
-+ reg >>= map->format.reg_downshift;
- return map->bus->reg_write(map->bus_context, reg, val);
- }
-
-@@ -2715,6 +2717,8 @@ static int _regmap_bus_reg_read(void *co
- {
- struct regmap *map = context;
-
-+ reg += map->reg_base;
-+ reg >>= map->format.reg_downshift;
- return map->bus->reg_read(map->bus_context, reg, val);
- }
-
-@@ -3084,6 +3088,8 @@ static int _regmap_update_bits(struct re
- *change = false;
-
- if (regmap_volatile(map, reg) && map->reg_update_bits) {
-+ reg += map->reg_base;
-+ reg >>= map->format.reg_downshift;
- ret = map->reg_update_bits(map->bus_context, reg, mask, val);
- if (ret == 0 && change)
- *change = true;
diff --git a/target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch b/target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch
deleted file mode 100644
index 82e712e20a..0000000000
--- a/target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 78391fb5b1b5318900725c72f1db25b2ae92894f Mon Sep 17 00:00:00 2001
-From: Christophe Leroy <christophe.leroy@csgroup.eu>
-Date: Wed, 7 Jun 2023 09:50:52 +0200
-Subject: [PATCH] powerpc/vdso: link with -z noexecstack
-
-With recent binutils, the following warning appears:
-
- VDSO32L arch/powerpc/kernel/vdso/vdso32.so.dbg
-/opt/gcc-12.2.0-nolibc/powerpc64-linux/bin/../lib/gcc/powerpc64-linux/12.2.0/../../../../powerpc64-linux/bin/ld: warning: arch/powerpc/kernel/vdso/getcpu-32.o: missing .note.GNU-stack section implies executable stack
-/opt/gcc-12.2.0-nolibc/powerpc64-linux/bin/../lib/gcc/powerpc64-linux/12.2.0/../../../../powerpc64-linux/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
-
-To avoid that, explicitly tell the linker we don't want executable
-stack.
-
-For more explanations, see commit ffcf9c5700e4 ("x86: link vdso
-and boot with -z noexecstack --no-warn-rwx-segments")
-
-Commit was adapted for 5.15 as VDSO32 and VDSO64 were merged later so it
-does not directly apply.
-
-Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/b95f2e3216a574837dd61208444e9515c3423da4.1662132312.git.christophe.leroy@csgroup.eu
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-[Adapt to 5.15 as it has VDSO split for 32 and 64bit]
----
- arch/powerpc/kernel/vdso32/Makefile | 2 +-
- arch/powerpc/kernel/vdso64/Makefile | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/powerpc/kernel/vdso32/Makefile
-+++ b/arch/powerpc/kernel/vdso32/Makefile
-@@ -66,7 +66,7 @@ include/generated/vdso32-offsets.h: $(ob
-
- # actual build commands
- quiet_cmd_vdso32ld_and_check = VDSO32L $@
-- cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) ; $(cmd_vdso_check)
-+ cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) -z noexecstack ; $(cmd_vdso_check)
- quiet_cmd_vdso32as = VDSO32A $@
- cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) -c -o $@ $<
- quiet_cmd_vdso32cc = VDSO32C $@
---- a/arch/powerpc/kernel/vdso64/Makefile
-+++ b/arch/powerpc/kernel/vdso64/Makefile
-@@ -53,4 +53,4 @@ include/generated/vdso64-offsets.h: $(ob
-
- # actual build commands
- quiet_cmd_vdso64ld_and_check = VDSO64L $@
-- cmd_vdso64ld_and_check = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^); $(cmd_vdso_check)
-+ cmd_vdso64ld_and_check = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) -z noexecstack ; $(cmd_vdso_check)
diff --git a/target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch b/target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch
deleted file mode 100644
index 1f3aae13b4..0000000000
--- a/target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From bcdf0315a61a29eb753a607d3a85a4032de72d94 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 10 May 2022 15:12:59 +0200
-Subject: [PATCH] mtd: call of_platform_populate() for MTD partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Until this change MTD subsystem supported handling partitions only with
-MTD partitions parsers. That's a specific / limited API designed around
-partitions.
-
-Some MTD partitions may however require different handling. They may
-contain specific data that needs to be parsed and somehow extracted. For
-that purpose MTD subsystem should allow binding of standard platform
-drivers.
-
-An example can be U-Boot (sub)partition with environment variables.
-There exist a "u-boot,env" DT binding for MTD (sub)partition that
-requires an NVMEM driver.
-
-Ref: 5db1c2dbc04c ("dt-bindings: nvmem: add U-Boot environment variables binding")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220510131259.555-1-zajec5@gmail.com
----
- drivers/mtd/mtdpart.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -17,6 +17,7 @@
- #include <linux/mtd/partitions.h>
- #include <linux/err.h>
- #include <linux/of.h>
-+#include <linux/of_platform.h>
-
- #include "mtdcore.h"
-
-@@ -577,10 +578,16 @@ static int mtd_part_of_parse(struct mtd_
- struct mtd_part_parser *parser;
- struct device_node *np;
- struct property *prop;
-+ struct device *dev;
- const char *compat;
- const char *fixed = "fixed-partitions";
- int ret, err = 0;
-
-+ dev = &master->dev;
-+ /* Use parent device (controller) if the top level MTD is not registered */
-+ if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) && !mtd_is_partition(master))
-+ dev = master->dev.parent;
-+
- np = mtd_get_of_node(master);
- if (mtd_is_partition(master))
- of_node_get(np);
-@@ -593,6 +600,7 @@ static int mtd_part_of_parse(struct mtd_
- continue;
- ret = mtd_part_do_parse(parser, master, pparts, NULL);
- if (ret > 0) {
-+ of_platform_populate(np, NULL, NULL, dev);
- of_node_put(np);
- return ret;
- }
-@@ -600,6 +608,7 @@ static int mtd_part_of_parse(struct mtd_
- if (ret < 0 && !err)
- err = ret;
- }
-+ of_platform_populate(np, NULL, NULL, dev);
- of_node_put(np);
-
- /*
diff --git a/target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch b/target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch
deleted file mode 100644
index 113a96ad42..0000000000
--- a/target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch
+++ /dev/null
@@ -1,302 +0,0 @@
-From 9b78ef0c7997052e9eaa0f7a4513d546fa17358c Mon Sep 17 00:00:00 2001
-From: Mikhail Zhilkin <csharper2005@gmail.com>
-Date: Sun, 29 May 2022 11:07:14 +0000
-Subject: [PATCH] mtd: parsers: add support for Sercomm partitions
-
-This adds an MTD partition parser for the Sercomm partition table that
-is used in some Beeline, Netgear and Sercomm routers.
-
-The Sercomm partition map table contains real partition offsets, which
-may differ from device to device depending on the number and location of
-bad blocks on NAND.
-
-Original patch (proposed by NOGUCHI Hiroshi):
-Link: https://github.com/openwrt/openwrt/pull/1318#issuecomment-420607394
-
-Signed-off-by: NOGUCHI Hiroshi <drvlabo@gmail.com>
-Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220529110714.189732-1-csharper2005@gmail.com
----
- drivers/mtd/parsers/Kconfig | 9 ++
- drivers/mtd/parsers/Makefile | 1 +
- drivers/mtd/parsers/scpart.c | 248 +++++++++++++++++++++++++++++++++++
- 3 files changed, 258 insertions(+)
- create mode 100644 drivers/mtd/parsers/scpart.c
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -186,3 +186,12 @@ config MTD_QCOMSMEM_PARTS
- help
- This provides support for parsing partitions from Shared Memory (SMEM)
- for NAND and SPI flash on Qualcomm platforms.
-+
-+config MTD_SERCOMM_PARTS
-+ tristate "Sercomm partition table parser"
-+ depends on MTD && RALINK
-+ help
-+ This provides partitions table parser for devices with Sercomm
-+ partition map. This partition table contains real partition
-+ offsets, which may differ from device to device depending on the
-+ number and location of bad blocks on NAND.
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -10,6 +10,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)
- obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
- obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
- obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
-+obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o
- obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
- obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
- obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o
---- /dev/null
-+++ b/drivers/mtd/parsers/scpart.c
-@@ -0,0 +1,248 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * drivers/mtd/scpart.c: Sercomm Partition Parser
-+ *
-+ * Copyright (C) 2018 NOGUCHI Hiroshi
-+ * Copyright (C) 2022 Mikhail Zhilkin
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/module.h>
-+
-+#define MOD_NAME "scpart"
-+
-+#ifdef pr_fmt
-+#undef pr_fmt
-+#endif
-+
-+#define pr_fmt(fmt) MOD_NAME ": " fmt
-+
-+#define ID_ALREADY_FOUND 0xffffffffUL
-+
-+#define MAP_OFFS_IN_BLK 0x800
-+#define MAP_MIRROR_NUM 2
-+
-+static const char sc_part_magic[] = {
-+ 'S', 'C', 'F', 'L', 'M', 'A', 'P', 'O', 'K', '\0',
-+};
-+#define PART_MAGIC_LEN sizeof(sc_part_magic)
-+
-+/* assumes that all fields are set by CPU native endian */
-+struct sc_part_desc {
-+ uint32_t part_id;
-+ uint32_t part_offs;
-+ uint32_t part_bytes;
-+};
-+
-+static uint32_t scpart_desc_is_valid(struct sc_part_desc *pdesc)
-+{
-+ return ((pdesc->part_id != 0xffffffffUL) &&
-+ (pdesc->part_offs != 0xffffffffUL) &&
-+ (pdesc->part_bytes != 0xffffffffUL));
-+}
-+
-+static int scpart_scan_partmap(struct mtd_info *master, loff_t partmap_offs,
-+ struct sc_part_desc **ppdesc)
-+{
-+ int cnt = 0;
-+ int res = 0;
-+ int res2;
-+ loff_t offs;
-+ size_t retlen;
-+ struct sc_part_desc *pdesc = NULL;
-+ struct sc_part_desc *tmpdesc;
-+ uint8_t *buf;
-+
-+ buf = kzalloc(master->erasesize, GFP_KERNEL);
-+ if (!buf) {
-+ res = -ENOMEM;
-+ goto out;
-+ }
-+
-+ res2 = mtd_read(master, partmap_offs, master->erasesize, &retlen, buf);
-+ if (res2 || retlen != master->erasesize) {
-+ res = -EIO;
-+ goto free;
-+ }
-+
-+ for (offs = MAP_OFFS_IN_BLK;
-+ offs < master->erasesize - sizeof(*tmpdesc);
-+ offs += sizeof(*tmpdesc)) {
-+ tmpdesc = (struct sc_part_desc *)&buf[offs];
-+ if (!scpart_desc_is_valid(tmpdesc))
-+ break;
-+ cnt++;
-+ }
-+
-+ if (cnt > 0) {
-+ int bytes = cnt * sizeof(*pdesc);
-+
-+ pdesc = kcalloc(cnt, sizeof(*pdesc), GFP_KERNEL);
-+ if (!pdesc) {
-+ res = -ENOMEM;
-+ goto free;
-+ }
-+ memcpy(pdesc, &(buf[MAP_OFFS_IN_BLK]), bytes);
-+
-+ *ppdesc = pdesc;
-+ res = cnt;
-+ }
-+
-+free:
-+ kfree(buf);
-+
-+out:
-+ return res;
-+}
-+
-+static int scpart_find_partmap(struct mtd_info *master,
-+ struct sc_part_desc **ppdesc)
-+{
-+ int magic_found = 0;
-+ int res = 0;
-+ int res2;
-+ loff_t offs = 0;
-+ size_t retlen;
-+ uint8_t rdbuf[PART_MAGIC_LEN];
-+
-+ while ((magic_found < MAP_MIRROR_NUM) &&
-+ (offs < master->size) &&
-+ !mtd_block_isbad(master, offs)) {
-+ res2 = mtd_read(master, offs, PART_MAGIC_LEN, &retlen, rdbuf);
-+ if (res2 || retlen != PART_MAGIC_LEN) {
-+ res = -EIO;
-+ goto out;
-+ }
-+ if (!memcmp(rdbuf, sc_part_magic, PART_MAGIC_LEN)) {
-+ pr_debug("Signature found at 0x%llx\n", offs);
-+ magic_found++;
-+ res = scpart_scan_partmap(master, offs, ppdesc);
-+ if (res > 0)
-+ goto out;
-+ }
-+ offs += master->erasesize;
-+ }
-+
-+out:
-+ if (res > 0)
-+ pr_info("Valid 'SC PART MAP' (%d partitions) found at 0x%llx\n", res, offs);
-+ else
-+ pr_info("No valid 'SC PART MAP' was found\n");
-+
-+ return res;
-+}
-+
-+static int scpart_parse(struct mtd_info *master,
-+ const struct mtd_partition **pparts,
-+ struct mtd_part_parser_data *data)
-+{
-+ const char *partname;
-+ int n;
-+ int nr_scparts;
-+ int nr_parts = 0;
-+ int res = 0;
-+ struct sc_part_desc *scpart_map = NULL;
-+ struct mtd_partition *parts = NULL;
-+ struct device_node *mtd_node;
-+ struct device_node *ofpart_node;
-+ struct device_node *pp;
-+
-+ mtd_node = mtd_get_of_node(master);
-+ if (!mtd_node) {
-+ res = -ENOENT;
-+ goto out;
-+ }
-+
-+ ofpart_node = of_get_child_by_name(mtd_node, "partitions");
-+ if (!ofpart_node) {
-+ pr_info("%s: 'partitions' subnode not found on %pOF.\n",
-+ master->name, mtd_node);
-+ res = -ENOENT;
-+ goto out;
-+ }
-+
-+ nr_scparts = scpart_find_partmap(master, &scpart_map);
-+ if (nr_scparts <= 0) {
-+ pr_info("No any partitions was found in 'SC PART MAP'.\n");
-+ res = -ENOENT;
-+ goto free;
-+ }
-+
-+ parts = kcalloc(of_get_child_count(ofpart_node), sizeof(*parts),
-+ GFP_KERNEL);
-+ if (!parts) {
-+ res = -ENOMEM;
-+ goto free;
-+ }
-+
-+ for_each_child_of_node(ofpart_node, pp) {
-+ u32 scpart_id;
-+
-+ if (of_property_read_u32(pp, "sercomm,scpart-id", &scpart_id))
-+ continue;
-+
-+ for (n = 0 ; n < nr_scparts ; n++)
-+ if ((scpart_map[n].part_id != ID_ALREADY_FOUND) &&
-+ (scpart_id == scpart_map[n].part_id))
-+ break;
-+ if (n >= nr_scparts)
-+ /* not match */
-+ continue;
-+
-+ /* add the partition found in OF into MTD partition array */
-+ parts[nr_parts].offset = scpart_map[n].part_offs;
-+ parts[nr_parts].size = scpart_map[n].part_bytes;
-+ parts[nr_parts].of_node = pp;
-+
-+ if (!of_property_read_string(pp, "label", &partname))
-+ parts[nr_parts].name = partname;
-+ if (of_property_read_bool(pp, "read-only"))
-+ parts[nr_parts].mask_flags |= MTD_WRITEABLE;
-+ if (of_property_read_bool(pp, "lock"))
-+ parts[nr_parts].mask_flags |= MTD_POWERUP_LOCK;
-+
-+ /* mark as 'done' */
-+ scpart_map[n].part_id = ID_ALREADY_FOUND;
-+
-+ nr_parts++;
-+ }
-+
-+ if (nr_parts > 0) {
-+ *pparts = parts;
-+ res = nr_parts;
-+ } else
-+ pr_info("No partition in OF matches partition ID with 'SC PART MAP'.\n");
-+
-+ of_node_put(pp);
-+
-+free:
-+ kfree(scpart_map);
-+ if (res <= 0)
-+ kfree(parts);
-+
-+out:
-+ return res;
-+}
-+
-+static const struct of_device_id scpart_parser_of_match_table[] = {
-+ { .compatible = "sercomm,sc-partitions" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, scpart_parser_of_match_table);
-+
-+static struct mtd_part_parser scpart_parser = {
-+ .parse_fn = scpart_parse,
-+ .name = "scpart",
-+ .of_match_table = scpart_parser_of_match_table,
-+};
-+module_mtd_part_parser(scpart_parser);
-+
-+/* mtd parsers will request the module by parser name */
-+MODULE_ALIAS("scpart");
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("NOGUCHI Hiroshi <drvlabo@gmail.com>");
-+MODULE_AUTHOR("Mikhail Zhilkin <csharper2005@gmail.com>");
-+MODULE_DESCRIPTION("Sercomm partition parser");
diff --git a/target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch b/target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch
deleted file mode 100644
index ee385416d1..0000000000
--- a/target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From ad9b10d1eaada169bd764abcab58f08538877e26 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 22 Jun 2022 03:06:28 +0200
-Subject: mtd: core: introduce of support for dynamic partitions
-
-We have many parser that register mtd partitions at runtime. One example
-is the cmdlinepart or the smem-part parser where the compatible is defined
-in the dts and the partitions gets detected and registered by the
-parser. This is problematic for the NVMEM subsystem that requires an OF
-node to detect NVMEM cells.
-
-To fix this problem, introduce an additional logic that will try to
-assign an OF node to the MTD if declared.
-
-On MTD addition, it will be checked if the MTD has an OF node and if
-not declared will check if a partition with the same label / node name is
-declared in DTS. If an exact match is found, the partition dynamically
-allocated by the parser will have a connected OF node.
-
-The NVMEM subsystem will detect the OF node and register any NVMEM cells
-declared statically in the DTS.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220622010628.30414-4-ansuelsmth@gmail.com
----
- drivers/mtd/mtdcore.c | 61 +++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 61 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -564,6 +564,66 @@ static int mtd_nvmem_add(struct mtd_info
- return 0;
- }
-
-+static void mtd_check_of_node(struct mtd_info *mtd)
-+{
-+ struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
-+ const char *pname, *prefix = "partition-";
-+ int plen, mtd_name_len, offset, prefix_len;
-+ struct mtd_info *parent;
-+ bool found = false;
-+
-+ /* Check if MTD already has a device node */
-+ if (dev_of_node(&mtd->dev))
-+ return;
-+
-+ /* Check if a partitions node exist */
-+ parent = mtd->parent;
-+ parent_dn = dev_of_node(&parent->dev);
-+ if (!parent_dn)
-+ return;
-+
-+ partitions = of_get_child_by_name(parent_dn, "partitions");
-+ if (!partitions)
-+ goto exit_parent;
-+
-+ prefix_len = strlen(prefix);
-+ mtd_name_len = strlen(mtd->name);
-+
-+ /* Search if a partition is defined with the same name */
-+ for_each_child_of_node(partitions, mtd_dn) {
-+ offset = 0;
-+
-+ /* Skip partition with no/wrong prefix */
-+ if (!of_node_name_prefix(mtd_dn, "partition-"))
-+ continue;
-+
-+ /* Label have priority. Check that first */
-+ if (of_property_read_string(mtd_dn, "label", &pname)) {
-+ of_property_read_string(mtd_dn, "name", &pname);
-+ offset = prefix_len;
-+ }
-+
-+ plen = strlen(pname) - offset;
-+ if (plen == mtd_name_len &&
-+ !strncmp(mtd->name, pname + offset, plen)) {
-+ found = true;
-+ break;
-+ }
-+ }
-+
-+ if (!found)
-+ goto exit_partitions;
-+
-+ /* Set of_node only for nvmem */
-+ if (of_device_is_compatible(mtd_dn, "nvmem-cells"))
-+ mtd_set_of_node(mtd, mtd_dn);
-+
-+exit_partitions:
-+ of_node_put(partitions);
-+exit_parent:
-+ of_node_put(parent_dn);
-+}
-+
- /**
- * add_mtd_device - register an MTD device
- * @mtd: pointer to new MTD device info structure
-@@ -669,6 +729,7 @@ int add_mtd_device(struct mtd_info *mtd)
- mtd->dev.devt = MTD_DEVT(i);
- dev_set_name(&mtd->dev, "mtd%d", i);
- dev_set_drvdata(&mtd->dev, mtd);
-+ mtd_check_of_node(mtd);
- of_node_get(mtd_get_of_node(mtd));
- error = device_register(&mtd->dev);
- if (error) {
diff --git a/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch b/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch
deleted file mode 100644
index 3039eabea5..0000000000
--- a/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From b0321721be50b80c03a51866a94fde4f94690e18 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 15 Jun 2022 21:42:59 +0200
-Subject: [PATCH] mtd: allow getting MTD device associated with a specific DT
- node
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-MTD subsystem API allows interacting with MTD devices (e.g. reading,
-writing, handling bad blocks). So far a random driver could get MTD
-device only by its name (get_mtd_device_nm()). This change allows
-getting them also by a DT node.
-
-This API is required for drivers handling DT defined MTD partitions in a
-specific way (e.g. U-Boot (sub)partition with environment variables).
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/mtd/mtdcore.c | 28 ++++++++++++++++++++++++++++
- include/linux/mtd/mtd.h | 1 +
- 2 files changed, 29 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -1236,6 +1236,34 @@ int __get_mtd_device(struct mtd_info *mt
- EXPORT_SYMBOL_GPL(__get_mtd_device);
-
- /**
-+ * of_get_mtd_device_by_node - obtain an MTD device associated with a given node
-+ *
-+ * @np: device tree node
-+ */
-+struct mtd_info *of_get_mtd_device_by_node(struct device_node *np)
-+{
-+ struct mtd_info *mtd = NULL;
-+ struct mtd_info *tmp;
-+ int err;
-+
-+ mutex_lock(&mtd_table_mutex);
-+
-+ err = -EPROBE_DEFER;
-+ mtd_for_each_device(tmp) {
-+ if (mtd_get_of_node(tmp) == np) {
-+ mtd = tmp;
-+ err = __get_mtd_device(mtd);
-+ break;
-+ }
-+ }
-+
-+ mutex_unlock(&mtd_table_mutex);
-+
-+ return err ? ERR_PTR(err) : mtd;
-+}
-+EXPORT_SYMBOL_GPL(of_get_mtd_device_by_node);
-+
-+/**
- * get_mtd_device_nm - obtain a validated handle for an MTD device by
- * device name
- * @name: MTD device name to open
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -682,6 +682,7 @@ extern int mtd_device_unregister(struct
- extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
- extern int __get_mtd_device(struct mtd_info *mtd);
- extern void __put_mtd_device(struct mtd_info *mtd);
-+extern struct mtd_info *of_get_mtd_device_by_node(struct device_node *np);
- extern struct mtd_info *get_mtd_device_nm(const char *name);
- extern void put_mtd_device(struct mtd_info *mtd);
-
diff --git a/target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch b/target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch
deleted file mode 100644
index e45e2ab48e..0000000000
--- a/target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 7ec4cdb321738d44ae5d405e7b6ac73dfbf99caa Mon Sep 17 00:00:00 2001
-From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
-Date: Mon, 25 Jul 2022 22:49:25 +0900
-Subject: [PATCH] mtd: core: check partition before dereference
-
-syzbot is reporting NULL pointer dereference at mtd_check_of_node() [1],
-for mtdram test device (CONFIG_MTD_MTDRAM) is not partition.
-
-Link: https://syzkaller.appspot.com/bug?extid=fe013f55a2814a9e8cfd [1]
-Reported-by: syzbot <syzbot+fe013f55a2814a9e8cfd@syzkaller.appspotmail.com>
-Reported-by: kernel test robot <oliver.sang@intel.com>
-Fixes: ad9b10d1eaada169 ("mtd: core: introduce of support for dynamic partitions")
-Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
-CC: stable@vger.kernel.org
-Signed-off-by: Richard Weinberger <richard@nod.at>
----
- drivers/mtd/mtdcore.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -577,6 +577,8 @@ static void mtd_check_of_node(struct mtd
- return;
-
- /* Check if a partitions node exist */
-+ if (!mtd_is_partition(mtd))
-+ return;
- parent = mtd->parent;
- parent_dn = dev_of_node(&parent->dev);
- if (!parent_dn)
diff --git a/target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch b/target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch
deleted file mode 100644
index 9399a00aa1..0000000000
--- a/target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 12b58961de0bd88b3c7dfa5d21f6d67f4678b780 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 18 Oct 2022 07:18:22 +0200
-Subject: [PATCH] mtd: core: add missing of_node_get() in dynamic partitions
- code
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes unbalanced of_node_put():
-[ 1.078910] 6 cmdlinepart partitions found on MTD device gpmi-nand
-[ 1.085116] Creating 6 MTD partitions on "gpmi-nand":
-[ 1.090181] 0x000000000000-0x000008000000 : "nandboot"
-[ 1.096952] 0x000008000000-0x000009000000 : "nandfit"
-[ 1.103547] 0x000009000000-0x00000b000000 : "nandkernel"
-[ 1.110317] 0x00000b000000-0x00000c000000 : "nanddtb"
-[ 1.115525] ------------[ cut here ]------------
-[ 1.120141] refcount_t: addition on 0; use-after-free.
-[ 1.125328] WARNING: CPU: 0 PID: 1 at lib/refcount.c:25 refcount_warn_saturate+0xdc/0x148
-[ 1.133528] Modules linked in:
-[ 1.136589] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc7-next-20220930-04543-g8cf3f7
-[ 1.146342] Hardware name: Freescale i.MX8DXL DDR3L EVK (DT)
-[ 1.151999] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
-[ 1.158965] pc : refcount_warn_saturate+0xdc/0x148
-[ 1.163760] lr : refcount_warn_saturate+0xdc/0x148
-[ 1.168556] sp : ffff800009ddb080
-[ 1.171866] x29: ffff800009ddb080 x28: ffff800009ddb35a x27: 0000000000000002
-[ 1.179015] x26: ffff8000098b06ad x25: ffffffffffffffff x24: ffff0a00ffffff05
-[ 1.186165] x23: ffff00001fdf6470 x22: ffff800009ddb367 x21: 0000000000000000
-[ 1.193314] x20: ffff00001fdfebe8 x19: ffff00001fdfec50 x18: ffffffffffffffff
-[ 1.200464] x17: 0000000000000000 x16: 0000000000000118 x15: 0000000000000004
-[ 1.207614] x14: 0000000000000fff x13: ffff800009bca248 x12: 0000000000000003
-[ 1.214764] x11: 00000000ffffefff x10: c0000000ffffefff x9 : 4762cb2ccb52de00
-[ 1.221914] x8 : 4762cb2ccb52de00 x7 : 205d313431303231 x6 : 312e31202020205b
-[ 1.229063] x5 : ffff800009d55c1f x4 : 0000000000000001 x3 : 0000000000000000
-[ 1.236213] x2 : 0000000000000000 x1 : ffff800009954be6 x0 : 000000000000002a
-[ 1.243365] Call trace:
-[ 1.245806] refcount_warn_saturate+0xdc/0x148
-[ 1.250253] kobject_get+0x98/0x9c
-[ 1.253658] of_node_get+0x20/0x34
-[ 1.257072] of_fwnode_get+0x3c/0x54
-[ 1.260652] fwnode_get_nth_parent+0xd8/0xf4
-[ 1.264926] fwnode_full_name_string+0x3c/0xb4
-[ 1.269373] device_node_string+0x498/0x5b4
-[ 1.273561] pointer+0x41c/0x5d0
-[ 1.276793] vsnprintf+0x4d8/0x694
-[ 1.280198] vprintk_store+0x164/0x528
-[ 1.283951] vprintk_emit+0x98/0x164
-[ 1.287530] vprintk_default+0x44/0x6c
-[ 1.291284] vprintk+0xf0/0x134
-[ 1.294428] _printk+0x54/0x7c
-[ 1.297486] of_node_release+0xe8/0x128
-[ 1.301326] kobject_put+0x98/0xfc
-[ 1.304732] of_node_put+0x1c/0x28
-[ 1.308137] add_mtd_device+0x484/0x6d4
-[ 1.311977] add_mtd_partitions+0xf0/0x1d0
-[ 1.316078] parse_mtd_partitions+0x45c/0x518
-[ 1.320439] mtd_device_parse_register+0xb0/0x274
-[ 1.325147] gpmi_nand_probe+0x51c/0x650
-[ 1.329074] platform_probe+0xa8/0xd0
-[ 1.332740] really_probe+0x130/0x334
-[ 1.336406] __driver_probe_device+0xb4/0xe0
-[ 1.340681] driver_probe_device+0x3c/0x1f8
-[ 1.344869] __driver_attach+0xdc/0x1a4
-[ 1.348708] bus_for_each_dev+0x80/0xcc
-[ 1.352548] driver_attach+0x24/0x30
-[ 1.356127] bus_add_driver+0x108/0x1f4
-[ 1.359967] driver_register+0x78/0x114
-[ 1.363807] __platform_driver_register+0x24/0x30
-[ 1.368515] gpmi_nand_driver_init+0x1c/0x28
-[ 1.372798] do_one_initcall+0xbc/0x238
-[ 1.376638] do_initcall_level+0x94/0xb4
-[ 1.380565] do_initcalls+0x54/0x94
-[ 1.384058] do_basic_setup+0x1c/0x28
-[ 1.387724] kernel_init_freeable+0x110/0x188
-[ 1.392084] kernel_init+0x20/0x1a0
-[ 1.395578] ret_from_fork+0x10/0x20
-[ 1.399157] ---[ end trace 0000000000000000 ]---
-[ 1.403782] ------------[ cut here ]------------
-
-Reported-by: Han Xu <han.xu@nxp.com>
-Fixes: ad9b10d1eaada169 ("mtd: core: introduce of support for dynamic partitions")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Tested-by: Han Xu <han.xu@nxp.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221018051822.28685-1-zajec5@gmail.com
----
- drivers/mtd/mtdcore.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -580,7 +580,7 @@ static void mtd_check_of_node(struct mtd
- if (!mtd_is_partition(mtd))
- return;
- parent = mtd->parent;
-- parent_dn = dev_of_node(&parent->dev);
-+ parent_dn = of_node_get(dev_of_node(&parent->dev));
- if (!parent_dn)
- return;
-
diff --git a/target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch b/target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch
deleted file mode 100644
index 7e9645ea98..0000000000
--- a/target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 63db0cb35e1cb3b3c134906d1062f65513fdda2d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Oct 2022 10:37:09 +0200
-Subject: [PATCH] mtd: core: simplify (a bit) code find partition-matching
- dynamic OF node
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Don't hardcode "partition-" string twice
-2. Use simpler logic & use ->name to avoid of_property_read_string()
-3. Use mtd_get_of_node() helper
-
-Cc: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-1-zajec5@gmail.com
----
- drivers/mtd/mtdcore.c | 16 +++++++---------
- 1 file changed, 7 insertions(+), 9 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -569,18 +569,16 @@ static void mtd_check_of_node(struct mtd
- struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
- const char *pname, *prefix = "partition-";
- int plen, mtd_name_len, offset, prefix_len;
-- struct mtd_info *parent;
- bool found = false;
-
- /* Check if MTD already has a device node */
-- if (dev_of_node(&mtd->dev))
-+ if (mtd_get_of_node(mtd))
- return;
-
- /* Check if a partitions node exist */
- if (!mtd_is_partition(mtd))
- return;
-- parent = mtd->parent;
-- parent_dn = of_node_get(dev_of_node(&parent->dev));
-+ parent_dn = of_node_get(mtd_get_of_node(mtd->parent));
- if (!parent_dn)
- return;
-
-@@ -593,15 +591,15 @@ static void mtd_check_of_node(struct mtd
-
- /* Search if a partition is defined with the same name */
- for_each_child_of_node(partitions, mtd_dn) {
-- offset = 0;
--
- /* Skip partition with no/wrong prefix */
-- if (!of_node_name_prefix(mtd_dn, "partition-"))
-+ if (!of_node_name_prefix(mtd_dn, prefix))
- continue;
-
- /* Label have priority. Check that first */
-- if (of_property_read_string(mtd_dn, "label", &pname)) {
-- of_property_read_string(mtd_dn, "name", &pname);
-+ if (!of_property_read_string(mtd_dn, "label", &pname)) {
-+ offset = 0;
-+ } else {
-+ pname = mtd_dn->name;
- offset = prefix_len;
- }
-
diff --git a/target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch b/target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch
deleted file mode 100644
index 48a7c13cd0..0000000000
--- a/target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From ddb8cefb7af288950447ca6eeeafb09977dab56f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Oct 2022 10:37:10 +0200
-Subject: [PATCH] mtd: core: try to find OF node for every MTD partition
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-So far this feature was limited to the top-level "nvmem-cells" node.
-There are multiple parsers creating partitions and subpartitions
-dynamically. Extend that code to handle them too.
-
-This allows finding partition-* node for every MTD (sub)partition.
-
-Random example:
-
-partitions {
- compatible = "brcm,bcm947xx-cfe-partitions";
-
- partition-firmware {
- compatible = "brcm,trx";
-
- partition-loader {
- };
- };
-};
-
-Cc: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-2-zajec5@gmail.com
----
- drivers/mtd/mtdcore.c | 18 ++++++------------
- 1 file changed, 6 insertions(+), 12 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -569,20 +569,22 @@ static void mtd_check_of_node(struct mtd
- struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
- const char *pname, *prefix = "partition-";
- int plen, mtd_name_len, offset, prefix_len;
-- bool found = false;
-
- /* Check if MTD already has a device node */
- if (mtd_get_of_node(mtd))
- return;
-
-- /* Check if a partitions node exist */
- if (!mtd_is_partition(mtd))
- return;
-+
- parent_dn = of_node_get(mtd_get_of_node(mtd->parent));
- if (!parent_dn)
- return;
-
-- partitions = of_get_child_by_name(parent_dn, "partitions");
-+ if (mtd_is_partition(mtd->parent))
-+ partitions = of_node_get(parent_dn);
-+ else
-+ partitions = of_get_child_by_name(parent_dn, "partitions");
- if (!partitions)
- goto exit_parent;
-
-@@ -606,19 +608,11 @@ static void mtd_check_of_node(struct mtd
- plen = strlen(pname) - offset;
- if (plen == mtd_name_len &&
- !strncmp(mtd->name, pname + offset, plen)) {
-- found = true;
-+ mtd_set_of_node(mtd, mtd_dn);
- break;
- }
- }
-
-- if (!found)
-- goto exit_partitions;
--
-- /* Set of_node only for nvmem */
-- if (of_device_is_compatible(mtd_dn, "nvmem-cells"))
-- mtd_set_of_node(mtd, mtd_dn);
--
--exit_partitions:
- of_node_put(partitions);
- exit_parent:
- of_node_put(parent_dn);
diff --git a/target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch b/target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch
deleted file mode 100644
index 0efad99157..0000000000
--- a/target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 26bccc9671ba5e01f7153addbe94e7dc3f677375 Mon Sep 17 00:00:00 2001
-From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
-Date: Mon, 3 Jan 2022 03:03:16 +0000
-Subject: [PATCH 13/14] mtd: parsers: qcom: Don't print error message on
- -EPROBE_DEFER
-
-Its possible for the main smem driver to not be loaded by the time we come
-along to parse the smem partition description but, this is a perfectly
-normal thing.
-
-No need to print out an error message in this case.
-
-Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220103030316.58301-3-bryan.odonoghue@linaro.org
----
- drivers/mtd/parsers/qcomsmempart.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/parsers/qcomsmempart.c
-+++ b/drivers/mtd/parsers/qcomsmempart.c
-@@ -75,7 +75,8 @@ static int parse_qcomsmem_part(struct mt
- pr_debug("Parsing partition table info from SMEM\n");
- ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len);
- if (IS_ERR(ptable)) {
-- pr_err("Error reading partition table header\n");
-+ if (PTR_ERR(ptable) != -EPROBE_DEFER)
-+ pr_err("Error reading partition table header\n");
- return PTR_ERR(ptable);
- }
-
diff --git a/target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch b/target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch
deleted file mode 100644
index 505e347e40..0000000000
--- a/target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 26422ac78e9d8767bd4aabfbae616b15edbf6a1b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 22 Oct 2022 23:13:18 +0200
-Subject: [PATCH] mtd: core: set ROOT_DEV for partitions marked as rootfs in DT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds support for "linux,rootfs" binding that is used to mark flash
-partition containing rootfs. It's useful for devices using device tree
-that don't have bootloader passing root info in cmdline.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221022211318.32009-2-zajec5@gmail.com
----
- drivers/mtd/mtdcore.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -28,6 +28,7 @@
- #include <linux/leds.h>
- #include <linux/debugfs.h>
- #include <linux/nvmem-provider.h>
-+#include <linux/root_dev.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-@@ -748,6 +749,17 @@ int add_mtd_device(struct mtd_info *mtd)
- not->add(mtd);
-
- mutex_unlock(&mtd_table_mutex);
-+
-+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) {
-+ if (IS_BUILTIN(CONFIG_MTD)) {
-+ pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name);
-+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
-+ } else {
-+ pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n",
-+ mtd->index, mtd->name);
-+ }
-+ }
-+
- /* We _know_ we aren't being removed, because
- our caller is still holding us here. So none
- of this try_ nonsense, and no bitching about it
diff --git a/target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch b/target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch
deleted file mode 100644
index ba14ae0178..0000000000
--- a/target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From fb42378dcc7f247df56f0ecddfdae85487495fbc Mon Sep 17 00:00:00 2001
-From: Saravana Kannan <saravanak@google.com>
-Date: Mon, 6 Feb 2023 17:42:04 -0800
-Subject: [PATCH] mtd: mtdpart: Don't create platform device that'll never
- probe
-
-These "nvmem-cells" platform devices never get probed because there's no
-platform driver for it and it's never used anywhere else. So it's a
-waste of memory. These devices also cause fw_devlink to block nvmem
-consumers of "nvmem-cells" partition from probing because the supplier
-device never probes.
-
-So stop creating platform devices for nvmem-cells partitions to avoid
-wasting memory and to avoid blocking probing of consumers.
-
-Reported-by: Maxim Kiselev <bigunclemax@gmail.com>
-Fixes: bcdf0315a61a ("mtd: call of_platform_populate() for MTD partitions")
-Signed-off-by: Saravana Kannan <saravanak@google.com>
-Tested-by: Maksim Kiselev <bigunclemax@gmail.com>
-Tested-by: Douglas Anderson <dianders@chromium.org>
-Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Tested-by: Luca Weiss <luca.weiss@fairphone.com> # qcom/sm7225-fairphone-fp4
-Link: https://lore.kernel.org/r/20230207014207.1678715-13-saravanak@google.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/mtd/mtdpart.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -577,6 +577,7 @@ static int mtd_part_of_parse(struct mtd_
- {
- struct mtd_part_parser *parser;
- struct device_node *np;
-+ struct device_node *child;
- struct property *prop;
- struct device *dev;
- const char *compat;
-@@ -594,6 +595,15 @@ static int mtd_part_of_parse(struct mtd_
- else
- np = of_get_child_by_name(np, "partitions");
-
-+ /*
-+ * Don't create devices that are added to a bus but will never get
-+ * probed. That'll cause fw_devlink to block probing of consumers of
-+ * this partition until the partition device is probed.
-+ */
-+ for_each_child_of_node(np, child)
-+ if (of_device_is_compatible(child, "nvmem-cells"))
-+ of_node_set_flag(child, OF_POPULATED);
-+
- of_property_for_each_string(np, "compatible", prop, compat) {
- parser = mtd_part_get_compatible_parser(compat);
- if (!parser)
diff --git a/target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch b/target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch
deleted file mode 100644
index 5c49841760..0000000000
--- a/target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 2365f91c861cbfeef7141c69842848c7b2d3c2db Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Sun, 13 Feb 2022 15:40:44 +0900
-Subject: [PATCH] mtd: parsers: trx: allow to use on MediaTek MIPS SoCs
-
-Buffalo sells some router devices which have trx-formatted firmware,
-based on MediaTek MIPS SoCs. To use parser_trx on those devices, add
-"RALINK" to dependency and allow to compile for MediaTek MIPS SoCs.
-
-examples:
-
-- WCR-1166DS (MT7628)
-- WSR-1166DHP (MT7621)
-- WSR-2533DHP (MT7621)
-
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220213064045.1781-1-musashino.open@gmail.com
----
- drivers/mtd/parsers/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -115,7 +115,7 @@ config MTD_AFS_PARTS
-
- config MTD_PARSER_TRX
- tristate "Parser for TRX format partitions"
-- depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || COMPILE_TEST)
-+ depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST)
- help
- TRX is a firmware format used by Broadcom on their devices. It
- may contain up to 3/4 partitions (depending on the version).
diff --git a/target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch b/target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch
deleted file mode 100644
index dce2c91fd3..0000000000
--- a/target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 8e7daa85641c9559c113f6b217bdc923397de77c Mon Sep 17 00:00:00 2001
-From: William Zhang <william.zhang@broadcom.com>
-Date: Thu, 22 Feb 2024 19:47:58 -0800
-Subject: [PATCH] mtd: rawnand: brcmnand: Support write protection setting from
- dts
-
-The write protection feature is controlled by the module parameter wp_on
-with default set to enabled. But not all the board use this feature
-especially in BCMBCA broadband board. And module parameter is not
-sufficient as different board can have different option. Add a device
-tree property and allow this feature to be configured through the board
-dts on per board basis.
-
-Signed-off-by: William Zhang <william.zhang@broadcom.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Reviewed-by: Kamal Dasu <kamal.dasu@broadcom.com>
-Reviewed-by: David Regan <dregan@broadcom.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-william.zhang@broadcom.com
----
- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-@@ -3184,6 +3184,10 @@ int brcmnand_probe(struct platform_devic
- /* Disable XOR addressing */
- brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
-
-+ /* Check if the board connects the WP pin */
-+ if (of_property_read_bool(dn, "brcm,wp-not-connected"))
-+ wp_on = 0;
-+
- if (ctrl->features & BRCMNAND_HAS_WP) {
- /* Permanently disable write protection */
- if (wp_on == 2)
diff --git a/target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch b/target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch
deleted file mode 100644
index 153191529c..0000000000
--- a/target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From c67d90e058550403a3e6f9b05bfcdcfa12b1815c Mon Sep 17 00:00:00 2001
-From: Vincent Tremblay <vincent@vtremblay.dev>
-Date: Mon, 26 Dec 2022 21:35:48 -0500
-Subject: [PATCH] spidev: Add Silicon Labs EM3581 device compatible
-
-Add compatible string for Silicon Labs EM3581 device.
-
-Signed-off-by: Vincent Tremblay <vincent@vtremblay.dev>
-Link: https://lore.kernel.org/r/20221227023550.569547-2-vincent@vtremblay.dev
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spidev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/spi/spidev.c
-+++ b/drivers/spi/spidev.c
-@@ -691,6 +691,7 @@ static const struct spi_device_id spidev
- { .name = "m53cpld" },
- { .name = "spi-petra" },
- { .name = "spi-authenta" },
-+ { .name = "em3581" },
- {},
- };
- MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
-@@ -705,6 +706,7 @@ static const struct of_device_id spidev_
- { .compatible = "menlo,m53cpld" },
- { .compatible = "cisco,spi-petra" },
- { .compatible = "micron,spi-authenta" },
-+ { .compatible = "silabs,em3581" },
- {},
- };
- MODULE_DEVICE_TABLE(of, spidev_dt_ids);
diff --git a/target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch b/target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch
deleted file mode 100644
index ef36c82a6c..0000000000
--- a/target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 6c9d1fd52956c3148e847a214bae9102b1811de5 Mon Sep 17 00:00:00 2001
-From: Vincent Tremblay <vincent@vtremblay.dev>
-Date: Tue, 27 Dec 2022 09:10:08 -0500
-Subject: [PATCH] spidev: Add Silicon Labs SI3210 device compatible
-
-Add compatible string for Silicon Labs SI3210 device.
-
-Signed-off-by: Vincent Tremblay <vincent@vtremblay.dev>
-Link: https://lore.kernel.org/r/20221227141011.111410-2-vincent@vtremblay.dev
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spidev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/spi/spidev.c
-+++ b/drivers/spi/spidev.c
-@@ -692,6 +692,7 @@ static const struct spi_device_id spidev
- { .name = "spi-petra" },
- { .name = "spi-authenta" },
- { .name = "em3581" },
-+ { .name = "si3210" },
- {},
- };
- MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
-@@ -707,6 +708,7 @@ static const struct of_device_id spidev_
- { .compatible = "cisco,spi-petra" },
- { .compatible = "micron,spi-authenta" },
- { .compatible = "silabs,em3581" },
-+ { .compatible = "silabs,si3210" },
- {},
- };
- MODULE_DEVICE_TABLE(of, spidev_dt_ids);
diff --git a/target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch b/target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch
deleted file mode 100644
index 94863b891c..0000000000
--- a/target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 573eec222bc82fb5e724586267fbbb1aed9ffd03 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Sun, 20 Mar 2022 17:59:58 +0800
-Subject: [PATCH 2/5] mtd: spinand: gigadevice: add support for GD5FxGQ4xExxG
-
-Add support for:
- GD5F1GQ4RExxG
- GD5F2GQ4{U,R}ExxG
-
-These chips differ from GD5F1GQ4UExxG only in chip ID, voltage
-and capacity.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-3-gch981213@gmail.com
----
- drivers/mtd/nand/spi/gigadevice.c | 30 ++++++++++++++++++++++++++++++
- 1 file changed, 30 insertions(+)
-
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -335,6 +335,36 @@ static const struct spinand_info gigadev
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
- gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F1GQ4RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
-+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GQ4UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GQ4RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
- SPINAND_INFO("GD5F1GQ4UFxxG",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
- NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
diff --git a/target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch b/target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch
deleted file mode 100644
index 287a062aac..0000000000
--- a/target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 620a988813403318023296b61228ee8f3fcdb8e0 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Sun, 20 Mar 2022 17:59:59 +0800
-Subject: [PATCH 3/5] mtd: spinand: gigadevice: add support for GD5F1GQ5RExxG
-
-This chip is the 1.8v version of GD5F1GQ5UExxG.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-4-gch981213@gmail.com
----
- drivers/mtd/nand/spi/gigadevice.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -385,6 +385,16 @@ static const struct spinand_info gigadev
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
- gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F1GQ5RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
-+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
- };
-
- static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
diff --git a/target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch b/target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch
deleted file mode 100644
index b1cf47678e..0000000000
--- a/target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 194ec04b3a9e7fa97d1fbef296410631bc3cf1c8 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Sun, 20 Mar 2022 18:00:00 +0800
-Subject: [PATCH 4/5] mtd: spinand: gigadevice: add support for GD5F{2,
- 4}GQ5xExxG
-
-Add support for:
- GD5F2GQ5{U,R}ExxG
- GD5F4GQ6{U,R}ExxG
-
-These chips uses 4 dummy bytes for quad io and 2 dummy bytes for dual io.
-Besides that and memory layout, they are identical to their 1G variant.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-5-gch981213@gmail.com
----
- drivers/mtd/nand/spi/gigadevice.c | 48 +++++++++++++++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -47,6 +47,14 @@ static SPINAND_OP_VARIANTS(read_cache_va
- SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
- SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-
-+static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
-+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
- static SPINAND_OP_VARIANTS(write_cache_variants,
- SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
- SPINAND_PROG_LOAD(true, 0, NULL, 0));
-@@ -393,6 +401,46 @@ static const struct spinand_info gigadev
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GQ5UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GQ5RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F4GQ6UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F4GQ6RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
- gd5fxgq5xexxg_ecc_get_status)),
- };
diff --git a/target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch b/target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch
deleted file mode 100644
index 5e342a29fb..0000000000
--- a/target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 54647cd003c08b714474a5b599a147ec6a160486 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Sun, 20 Mar 2022 18:00:01 +0800
-Subject: [PATCH 5/5] mtd: spinand: gigadevice: add support for GD5FxGM7xExxG
-
-Add support for:
- GD5F{1,2}GM7{U,R}ExxG
- GD5F4GM8{U,R}ExxG
-
-These are new 27nm counterparts for the GD5FxGQ4 chips from GigaDevice
-with 8b/512b on-die ECC capability.
-These chips (and currently supported GD5FxGQ5 chips) have QIO DTR
-instruction for reading page cache. It isn't added in this patch because
-I don't have a DTR spi controller for testing.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-6-gch981213@gmail.com
----
- drivers/mtd/nand/spi/gigadevice.c | 60 +++++++++++++++++++++++++++++++
- 1 file changed, 60 insertions(+)
-
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -443,6 +443,66 @@ static const struct spinand_info gigadev
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
- gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F1GM7UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
-+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F1GM7RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
-+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GM7UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GM7RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F4GM8UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
-+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F4GM8RExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
-+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
- };
-
- static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
diff --git a/target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch b/target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch
deleted file mode 100644
index 9f543365a5..0000000000
--- a/target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch
+++ /dev/null
@@ -1,229 +0,0 @@
-From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 15 Oct 2022 11:29:50 +0200
-Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This parser deals with most TP-Link home routers. It reads info about
-partitions and registers them in the MTD subsystem.
-
-Example from TP-Link Archer C5 V2:
-
-spi-nor spi0.0: s25fl128s1 (16384 Kbytes)
-15 tplink-safeloader partitions found on MTD device spi0.0
-Creating 15 MTD partitions on "spi0.0":
-0x000000000000-0x000000040000 : "fs-uboot"
-0x000000040000-0x000000440000 : "os-image"
-0x000000440000-0x000000e40000 : "rootfs"
-0x000000e40000-0x000000e40200 : "default-mac"
-0x000000e40200-0x000000e40400 : "pin"
-0x000000e40400-0x000000e40600 : "product-info"
-0x000000e50000-0x000000e60000 : "partition-table"
-0x000000e60000-0x000000e60200 : "soft-version"
-0x000000e61000-0x000000e70000 : "support-list"
-0x000000e70000-0x000000e80000 : "profile"
-0x000000e80000-0x000000e90000 : "default-config"
-0x000000e90000-0x000000ee0000 : "user-config"
-0x000000ee0000-0x000000fe0000 : "log"
-0x000000fe0000-0x000000ff0000 : "radio_bk"
-0x000000ff0000-0x000001000000 : "radio"
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com
----
- drivers/mtd/parsers/Kconfig | 15 +++
- drivers/mtd/parsers/Makefile | 1 +
- drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++
- 3 files changed, 166 insertions(+)
- create mode 100644 drivers/mtd/parsers/tplink_safeloader.c
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -113,6 +113,21 @@ config MTD_AFS_PARTS
- for your particular device. It won't happen automatically. The
- 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example.
-
-+config MTD_PARSER_TPLINK_SAFELOADER
-+ tristate "TP-Link Safeloader partitions parser"
-+ depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST)
-+ help
-+ TP-Link home routers use flash partitions to store various data. Info
-+ about flash space layout is stored in a partitions table using a
-+ custom ASCII-based format.
-+
-+ That format was first found in devices with SafeLoader bootloader and
-+ was named after it. Later it was adapted to CFE and U-Boot
-+ bootloaders.
-+
-+ This driver reads partitions table, parses it and creates MTD
-+ partitions.
-+
- config MTD_PARSER_TRX
- tristate "Parser for TRX format partitions"
- depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST)
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -9,6 +9,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) +=
- ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o
- obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
- obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
-+obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o
- obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
- obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o
- obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
---- /dev/null
-+++ b/drivers/mtd/parsers/tplink_safeloader.c
-@@ -0,0 +1,150 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright © 2022 Rafał Miłecki <rafal@milecki.pl>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/of.h>
-+#include <linux/slab.h>
-+
-+#define TPLINK_SAFELOADER_DATA_OFFSET 4
-+#define TPLINK_SAFELOADER_MAX_PARTS 32
-+
-+struct safeloader_cmn_header {
-+ __be32 size;
-+ uint32_t unused;
-+} __packed;
-+
-+static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd)
-+{
-+ struct safeloader_cmn_header hdr;
-+ struct device_node *np;
-+ size_t bytes_read;
-+ size_t offset;
-+ size_t size;
-+ char *buf;
-+ int err;
-+
-+ np = mtd_get_of_node(mtd);
-+ if (mtd_is_partition(mtd))
-+ of_node_get(np);
-+ else
-+ np = of_get_child_by_name(np, "partitions");
-+
-+ if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) {
-+ pr_err("Failed to get partitions table offset\n");
-+ goto err_put;
-+ }
-+
-+ err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset);
-+ goto err_put;
-+ }
-+
-+ size = be32_to_cpu(hdr.size);
-+
-+ buf = kmalloc(size + 1, GFP_KERNEL);
-+ if (!buf)
-+ goto err_put;
-+
-+ err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr));
-+ goto err_kfree;
-+ }
-+
-+ buf[size] = '\0';
-+
-+ of_node_put(np);
-+
-+ return buf;
-+
-+err_kfree:
-+ kfree(buf);
-+err_put:
-+ of_node_put(np);
-+ return NULL;
-+}
-+
-+static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd,
-+ const struct mtd_partition **pparts,
-+ struct mtd_part_parser_data *data)
-+{
-+ struct mtd_partition *parts;
-+ char name[65];
-+ size_t offset;
-+ size_t bytes;
-+ char *buf;
-+ int idx;
-+ int err;
-+
-+ parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL);
-+ if (!parts) {
-+ err = -ENOMEM;
-+ goto err_out;
-+ }
-+
-+ buf = mtd_parser_tplink_safeloader_read_table(mtd);
-+ if (!buf) {
-+ err = -ENOENT;
-+ goto err_out;
-+ }
-+
-+ for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET;
-+ idx < TPLINK_SAFELOADER_MAX_PARTS &&
-+ sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n",
-+ name, &parts[idx].offset, &parts[idx].size, &bytes) == 3;
-+ idx++, offset += bytes + 1) {
-+ parts[idx].name = kstrdup(name, GFP_KERNEL);
-+ if (!parts[idx].name) {
-+ err = -ENOMEM;
-+ goto err_free;
-+ }
-+ }
-+
-+ if (idx == TPLINK_SAFELOADER_MAX_PARTS)
-+ pr_warn("Reached maximum number of partitions!\n");
-+
-+ kfree(buf);
-+
-+ *pparts = parts;
-+
-+ return idx;
-+
-+err_free:
-+ for (idx -= 1; idx >= 0; idx--)
-+ kfree(parts[idx].name);
-+err_out:
-+ return err;
-+};
-+
-+static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts,
-+ int nr_parts)
-+{
-+ int i;
-+
-+ for (i = 0; i < nr_parts; i++)
-+ kfree(pparts[i].name);
-+
-+ kfree(pparts);
-+}
-+
-+static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = {
-+ { .compatible = "tplink,safeloader-partitions" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table);
-+
-+static struct mtd_part_parser mtd_parser_tplink_safeloader = {
-+ .parse_fn = mtd_parser_tplink_safeloader_parse,
-+ .cleanup = mtd_parser_tplink_safeloader_cleanup,
-+ .name = "tplink-safeloader",
-+ .of_match_table = mtd_parser_tplink_safeloader_of_match_table,
-+};
-+module_mtd_part_parser(mtd_parser_tplink_safeloader);
-+
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch b/target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch
deleted file mode 100644
index 2358352e93..0000000000
--- a/target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 6abef37d16d0c570ef5a149e63762fba2a30804b Mon Sep 17 00:00:00 2001
-From: "Leon M. George" <leon@georgemail.eu>
-Date: Wed, 30 Mar 2022 16:16:56 +0200
-Subject: [PATCH] mtd: spi-nor: support eon en25qh256a variant
-
-The EN25QH256A variant of the EN25QH256 doesn't initialize correctly from SFDP
-alone and only accesses memory below 8m (addr_width is 4 but read_opcode takes
-only 3 bytes).
-
-Set SNOR_F_4B_OPCODES if the flash chip variant was detected using hwcaps.
-
-The fix submitted upstream uses the PARSE_SFDP initializer that is not
-available in the kernel used with Openwrt.
-
-Signed-off-by: Leon M. George <leon@georgemail.eu>
----
- drivers/mtd/spi-nor/eon.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/mtd/spi-nor/eon.c
-+++ b/drivers/mtd/spi-nor/eon.c
-@@ -8,6 +8,16 @@
-
- #include "core.h"
-
-+static void en25qh256_post_sfdp_fixups(struct spi_nor *nor)
-+{
-+ if (nor->params->hwcaps.mask & SNOR_HWCAPS_READ_1_1_4)
-+ nor->flags |= SNOR_F_4B_OPCODES;
-+}
-+
-+static const struct spi_nor_fixups en25qh256_fixups = {
-+ .post_sfdp = en25qh256_post_sfdp_fixups,
-+};
-+
- static const struct flash_info eon_parts[] = {
- /* EON -- en25xxx */
- { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) },
-@@ -23,7 +33,9 @@ static const struct flash_info eon_parts
- { "en25qh64", INFO(0x1c7017, 0, 64 * 1024, 128,
- SECT_4K | SPI_NOR_DUAL_READ) },
- { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) },
-- { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
-+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512,
-+ SPI_NOR_DUAL_READ)
-+ .fixups = &en25qh256_fixups },
- { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) },
- };
-
diff --git a/target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch b/target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch
deleted file mode 100644
index 9f1757caa7..0000000000
--- a/target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From e237285113963bd1dd2e925770aa8b3aa8a1894c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <kernel@kempniu.pl>
-Date: Wed, 29 Jun 2022 14:57:34 +0200
-Subject: [PATCH 1/4] mtd: track maximum number of bitflips for each read
- request
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-mtd_read_oob() callers are currently oblivious to the details of ECC
-errors detected during the read operation - they only learn (through the
-return value) whether any corrected bitflips or uncorrectable errors
-occurred. More detailed ECC information can be useful to user-space
-applications for making better-informed choices about moving data
-around.
-
-Extend struct mtd_oob_ops with a pointer to a newly-introduced struct
-mtd_req_stats and set its 'max_bitflips' field to the maximum number of
-bitflips found in a single ECC step during the read operation performed
-by mtd_read_oob(). This is a prerequisite for ultimately passing that
-value back to user space.
-
-Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Michał Kępień <kernel@kempniu.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-2-kernel@kempniu.pl
----
- drivers/mtd/mtdcore.c | 5 +++++
- include/linux/mtd/mtd.h | 5 +++++
- 2 files changed, 10 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -1676,6 +1676,9 @@ int mtd_read_oob(struct mtd_info *mtd, l
- if (!master->_read_oob && (!master->_read || ops->oobbuf))
- return -EOPNOTSUPP;
-
-+ if (ops->stats)
-+ memset(ops->stats, 0, sizeof(*ops->stats));
-+
- if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
- ret_code = mtd_io_emulated_slc(mtd, from, true, ops);
- else
-@@ -1693,6 +1696,8 @@ int mtd_read_oob(struct mtd_info *mtd, l
- return ret_code;
- if (mtd->ecc_strength == 0)
- return 0; /* device lacks ecc */
-+ if (ops->stats)
-+ ops->stats->max_bitflips = ret_code;
- return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
- }
- EXPORT_SYMBOL_GPL(mtd_read_oob);
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -40,6 +40,10 @@ struct mtd_erase_region_info {
- unsigned long *lockmap; /* If keeping bitmap of locks */
- };
-
-+struct mtd_req_stats {
-+ unsigned int max_bitflips;
-+};
-+
- /**
- * struct mtd_oob_ops - oob operation operands
- * @mode: operation mode
-@@ -70,6 +74,7 @@ struct mtd_oob_ops {
- uint32_t ooboffs;
- uint8_t *datbuf;
- uint8_t *oobbuf;
-+ struct mtd_req_stats *stats;
- };
-
- #define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
diff --git a/target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch b/target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch
deleted file mode 100644
index 1484624e4e..0000000000
--- a/target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch
+++ /dev/null
@@ -1,325 +0,0 @@
-From e97709c9d18903f5acd5fbe2985dd054da0432b1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <kernel@kempniu.pl>
-Date: Wed, 29 Jun 2022 14:57:35 +0200
-Subject: [PATCH 2/4] mtd: always initialize 'stats' in struct mtd_oob_ops
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-As the 'stats' field in struct mtd_oob_ops is used in conditional
-expressions, ensure it is always zero-initialized in all such structures
-to prevent random stack garbage from being interpreted as a pointer.
-
-Strictly speaking, this problem currently only needs to be fixed for
-struct mtd_oob_ops structures subsequently passed to mtd_read_oob().
-However, this commit goes a step further and makes all instances of
-struct mtd_oob_ops in the tree zero-initialized, in hope of preventing
-future problems, e.g. if struct mtd_req_stats gets extended with write
-statistics at some point.
-
-Signed-off-by: Michał Kępień <kernel@kempniu.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-3-kernel@kempniu.pl
----
- drivers/mtd/inftlcore.c | 6 +++---
- drivers/mtd/mtdswap.c | 6 +++---
- drivers/mtd/nand/onenand/onenand_base.c | 4 ++--
- drivers/mtd/nand/onenand/onenand_bbt.c | 2 +-
- drivers/mtd/nand/raw/nand_bbt.c | 8 ++++----
- drivers/mtd/nand/raw/sm_common.c | 2 +-
- drivers/mtd/nftlcore.c | 6 +++---
- drivers/mtd/sm_ftl.c | 4 ++--
- drivers/mtd/ssfdc.c | 2 +-
- drivers/mtd/tests/nandbiterrs.c | 2 +-
- drivers/mtd/tests/oobtest.c | 8 ++++----
- drivers/mtd/tests/readtest.c | 2 +-
- fs/jffs2/wbuf.c | 6 +++---
- 13 files changed, 29 insertions(+), 29 deletions(-)
-
---- a/drivers/mtd/inftlcore.c
-+++ b/drivers/mtd/inftlcore.c
-@@ -136,7 +136,7 @@ static void inftl_remove_dev(struct mtd_
- int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
- size_t *retlen, uint8_t *buf)
- {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int res;
-
- ops.mode = MTD_OPS_PLACE_OOB;
-@@ -156,7 +156,7 @@ int inftl_read_oob(struct mtd_info *mtd,
- int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
- size_t *retlen, uint8_t *buf)
- {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int res;
-
- ops.mode = MTD_OPS_PLACE_OOB;
-@@ -176,7 +176,7 @@ int inftl_write_oob(struct mtd_info *mtd
- static int inftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
- size_t *retlen, uint8_t *buf, uint8_t *oob)
- {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int res;
-
- ops.mode = MTD_OPS_PLACE_OOB;
---- a/drivers/mtd/mtdswap.c
-+++ b/drivers/mtd/mtdswap.c
-@@ -323,7 +323,7 @@ static int mtdswap_read_markers(struct m
- struct mtdswap_oobdata *data, *data2;
- int ret;
- loff_t offset;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- offset = mtdswap_eb_offset(d, eb);
-
-@@ -370,7 +370,7 @@ static int mtdswap_write_marker(struct m
- struct mtdswap_oobdata n;
- int ret;
- loff_t offset;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- ops.ooboffs = 0;
- ops.oobbuf = (uint8_t *)&n;
-@@ -879,7 +879,7 @@ static unsigned int mtdswap_eblk_passes(
- loff_t base, pos;
- unsigned int *p1 = (unsigned int *)d->page_buf;
- unsigned char *p2 = (unsigned char *)d->oob_buf;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int ret;
-
- ops.mode = MTD_OPS_AUTO_OOB;
---- a/drivers/mtd/nand/onenand/onenand_base.c
-+++ b/drivers/mtd/nand/onenand/onenand_base.c
-@@ -2935,7 +2935,7 @@ static int do_otp_write(struct mtd_info
- struct onenand_chip *this = mtd->priv;
- unsigned char *pbuf = buf;
- int ret;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- /* Force buffer page aligned */
- if (len < mtd->writesize) {
-@@ -2977,7 +2977,7 @@ static int do_otp_lock(struct mtd_info *
- size_t *retlen, u_char *buf)
- {
- struct onenand_chip *this = mtd->priv;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int ret;
-
- if (FLEXONENAND(this)) {
---- a/drivers/mtd/nand/onenand/onenand_bbt.c
-+++ b/drivers/mtd/nand/onenand/onenand_bbt.c
-@@ -61,7 +61,7 @@ static int create_bbt(struct mtd_info *m
- int startblock;
- loff_t from;
- size_t readlen, ooblen;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int rgn;
-
- printk(KERN_INFO "Scanning device for bad blocks\n");
---- a/drivers/mtd/nand/raw/nand_bbt.c
-+++ b/drivers/mtd/nand/raw/nand_bbt.c
-@@ -313,7 +313,7 @@ static int scan_read_oob(struct nand_chi
- size_t len)
- {
- struct mtd_info *mtd = nand_to_mtd(this);
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int res, ret = 0;
-
- ops.mode = MTD_OPS_PLACE_OOB;
-@@ -354,7 +354,7 @@ static int scan_write_bbt(struct nand_ch
- uint8_t *buf, uint8_t *oob)
- {
- struct mtd_info *mtd = nand_to_mtd(this);
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- ops.mode = MTD_OPS_PLACE_OOB;
- ops.ooboffs = 0;
-@@ -416,7 +416,7 @@ static int scan_block_fast(struct nand_c
- {
- struct mtd_info *mtd = nand_to_mtd(this);
-
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int ret, page_offset;
-
- ops.ooblen = mtd->oobsize;
-@@ -756,7 +756,7 @@ static int write_bbt(struct nand_chip *t
- uint8_t rcode = td->reserved_block_code;
- size_t retlen, len = 0;
- loff_t to;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- ops.ooblen = mtd->oobsize;
- ops.ooboffs = 0;
---- a/drivers/mtd/nand/raw/sm_common.c
-+++ b/drivers/mtd/nand/raw/sm_common.c
-@@ -99,7 +99,7 @@ static const struct mtd_ooblayout_ops oo
- static int sm_block_markbad(struct nand_chip *chip, loff_t ofs)
- {
- struct mtd_info *mtd = nand_to_mtd(chip);
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- struct sm_oob oob;
- int ret;
-
---- a/drivers/mtd/nftlcore.c
-+++ b/drivers/mtd/nftlcore.c
-@@ -124,7 +124,7 @@ int nftl_read_oob(struct mtd_info *mtd,
- size_t *retlen, uint8_t *buf)
- {
- loff_t mask = mtd->writesize - 1;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int res;
-
- ops.mode = MTD_OPS_PLACE_OOB;
-@@ -145,7 +145,7 @@ int nftl_write_oob(struct mtd_info *mtd,
- size_t *retlen, uint8_t *buf)
- {
- loff_t mask = mtd->writesize - 1;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int res;
-
- ops.mode = MTD_OPS_PLACE_OOB;
-@@ -168,7 +168,7 @@ static int nftl_write(struct mtd_info *m
- size_t *retlen, uint8_t *buf, uint8_t *oob)
- {
- loff_t mask = mtd->writesize - 1;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int res;
-
- ops.mode = MTD_OPS_PLACE_OOB;
---- a/drivers/mtd/sm_ftl.c
-+++ b/drivers/mtd/sm_ftl.c
-@@ -239,7 +239,7 @@ static int sm_read_sector(struct sm_ftl
- uint8_t *buffer, struct sm_oob *oob)
- {
- struct mtd_info *mtd = ftl->trans->mtd;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- struct sm_oob tmp_oob;
- int ret = -EIO;
- int try = 0;
-@@ -323,7 +323,7 @@ static int sm_write_sector(struct sm_ftl
- int zone, int block, int boffset,
- uint8_t *buffer, struct sm_oob *oob)
- {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- struct mtd_info *mtd = ftl->trans->mtd;
- int ret;
-
---- a/drivers/mtd/ssfdc.c
-+++ b/drivers/mtd/ssfdc.c
-@@ -163,7 +163,7 @@ static int read_physical_sector(struct m
- /* Read redundancy area (wrapper to MTD_READ_OOB */
- static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
- {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int ret;
-
- ops.mode = MTD_OPS_RAW;
---- a/drivers/mtd/tests/nandbiterrs.c
-+++ b/drivers/mtd/tests/nandbiterrs.c
-@@ -99,7 +99,7 @@ static int write_page(int log)
- static int rewrite_page(int log)
- {
- int err = 0;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- if (log)
- pr_info("rewrite page\n");
---- a/drivers/mtd/tests/oobtest.c
-+++ b/drivers/mtd/tests/oobtest.c
-@@ -56,7 +56,7 @@ static void do_vary_offset(void)
- static int write_eraseblock(int ebnum)
- {
- int i;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int err = 0;
- loff_t addr = (loff_t)ebnum * mtd->erasesize;
-
-@@ -165,7 +165,7 @@ static size_t memffshow(loff_t addr, lof
- static int verify_eraseblock(int ebnum)
- {
- int i;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int err = 0;
- loff_t addr = (loff_t)ebnum * mtd->erasesize;
- size_t bitflips;
-@@ -260,7 +260,7 @@ static int verify_eraseblock(int ebnum)
-
- static int verify_eraseblock_in_one_go(int ebnum)
- {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int err = 0;
- loff_t addr = (loff_t)ebnum * mtd->erasesize;
- size_t len = mtd->oobavail * pgcnt;
-@@ -338,7 +338,7 @@ static int __init mtd_oobtest_init(void)
- int err = 0;
- unsigned int i;
- uint64_t tmp;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- loff_t addr = 0, addr0;
-
- printk(KERN_INFO "\n");
---- a/drivers/mtd/tests/readtest.c
-+++ b/drivers/mtd/tests/readtest.c
-@@ -47,7 +47,7 @@ static int read_eraseblock_by_page(int e
- err = ret;
- }
- if (mtd->oobsize) {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- ops.mode = MTD_OPS_PLACE_OOB;
- ops.len = 0;
---- a/fs/jffs2/wbuf.c
-+++ b/fs/jffs2/wbuf.c
-@@ -1035,7 +1035,7 @@ int jffs2_check_oob_empty(struct jffs2_s
- {
- int i, ret;
- int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
-
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail;
-@@ -1076,7 +1076,7 @@ int jffs2_check_oob_empty(struct jffs2_s
- int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
- struct jffs2_eraseblock *jeb)
- {
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
-
- ops.mode = MTD_OPS_AUTO_OOB;
-@@ -1101,7 +1101,7 @@ int jffs2_write_nand_cleanmarker(struct
- struct jffs2_eraseblock *jeb)
- {
- int ret;
-- struct mtd_oob_ops ops;
-+ struct mtd_oob_ops ops = { };
- int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
-
- ops.mode = MTD_OPS_AUTO_OOB;
diff --git a/target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch b/target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch
deleted file mode 100644
index f2f45eb7bc..0000000000
--- a/target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 2ed18d818d1f7492172f8dd5904344c7d367e8ed Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <kernel@kempniu.pl>
-Date: Wed, 29 Jun 2022 14:57:36 +0200
-Subject: [PATCH 3/4] mtd: add ECC error accounting for each read request
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Extend struct mtd_req_stats with two new fields holding the number of
-corrected bitflips and uncorrectable errors detected during a read
-operation. This is a prerequisite for ultimately passing those counters
-to user space, where they can be useful to applications for making
-better-informed choices about moving data around.
-
-Unlike 'max_bitflips' (which is set - in a common code path - to the
-return value of a function called while the MTD device's mutex is held),
-these counters have to be maintained in each MTD driver which defines
-the '_read_oob' callback because the statistics need to be calculated
-while the MTD device's mutex is held.
-
-Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Michał Kępień <kernel@kempniu.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-4-kernel@kempniu.pl
----
- drivers/mtd/devices/docg3.c | 8 ++++++++
- drivers/mtd/nand/onenand/onenand_base.c | 12 ++++++++++++
- drivers/mtd/nand/raw/nand_base.c | 10 ++++++++++
- drivers/mtd/nand/spi/core.c | 10 ++++++++++
- include/linux/mtd/mtd.h | 2 ++
- 5 files changed, 42 insertions(+)
-
---- a/drivers/mtd/devices/docg3.c
-+++ b/drivers/mtd/devices/docg3.c
-@@ -871,6 +871,7 @@ static int doc_read_oob(struct mtd_info
- u8 *buf = ops->datbuf;
- size_t len, ooblen, nbdata, nboob;
- u8 hwecc[DOC_ECC_BCH_SIZE], eccconf1;
-+ struct mtd_ecc_stats old_stats;
- int max_bitflips = 0;
-
- if (buf)
-@@ -895,6 +896,7 @@ static int doc_read_oob(struct mtd_info
- ret = 0;
- skip = from % DOC_LAYOUT_PAGE_SIZE;
- mutex_lock(&docg3->cascade->lock);
-+ old_stats = mtd->ecc_stats;
- while (ret >= 0 && (len > 0 || ooblen > 0)) {
- calc_block_sector(from - skip, &block0, &block1, &page, &ofs,
- docg3->reliable);
-@@ -966,6 +968,12 @@ static int doc_read_oob(struct mtd_info
- }
-
- out:
-+ if (ops->stats) {
-+ ops->stats->uncorrectable_errors +=
-+ mtd->ecc_stats.failed - old_stats.failed;
-+ ops->stats->corrected_bitflips +=
-+ mtd->ecc_stats.corrected - old_stats.corrected;
-+ }
- mutex_unlock(&docg3->cascade->lock);
- return ret;
- err_in_read:
---- a/drivers/mtd/nand/onenand/onenand_base.c
-+++ b/drivers/mtd/nand/onenand/onenand_base.c
-@@ -1440,6 +1440,7 @@ static int onenand_read_oob(struct mtd_i
- struct mtd_oob_ops *ops)
- {
- struct onenand_chip *this = mtd->priv;
-+ struct mtd_ecc_stats old_stats;
- int ret;
-
- switch (ops->mode) {
-@@ -1453,12 +1454,23 @@ static int onenand_read_oob(struct mtd_i
- }
-
- onenand_get_device(mtd, FL_READING);
-+
-+ old_stats = mtd->ecc_stats;
-+
- if (ops->datbuf)
- ret = ONENAND_IS_4KB_PAGE(this) ?
- onenand_mlc_read_ops_nolock(mtd, from, ops) :
- onenand_read_ops_nolock(mtd, from, ops);
- else
- ret = onenand_read_oob_nolock(mtd, from, ops);
-+
-+ if (ops->stats) {
-+ ops->stats->uncorrectable_errors +=
-+ mtd->ecc_stats.failed - old_stats.failed;
-+ ops->stats->corrected_bitflips +=
-+ mtd->ecc_stats.corrected - old_stats.corrected;
-+ }
-+
- onenand_release_device(mtd);
-
- return ret;
---- a/drivers/mtd/nand/raw/nand_base.c
-+++ b/drivers/mtd/nand/raw/nand_base.c
-@@ -3815,6 +3815,7 @@ static int nand_read_oob(struct mtd_info
- struct mtd_oob_ops *ops)
- {
- struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtd_ecc_stats old_stats;
- int ret;
-
- ops->retlen = 0;
-@@ -3826,11 +3827,20 @@ static int nand_read_oob(struct mtd_info
-
- nand_get_device(chip);
-
-+ old_stats = mtd->ecc_stats;
-+
- if (!ops->datbuf)
- ret = nand_do_read_oob(chip, from, ops);
- else
- ret = nand_do_read_ops(chip, from, ops);
-
-+ if (ops->stats) {
-+ ops->stats->uncorrectable_errors +=
-+ mtd->ecc_stats.failed - old_stats.failed;
-+ ops->stats->corrected_bitflips +=
-+ mtd->ecc_stats.corrected - old_stats.corrected;
-+ }
-+
- nand_release_device(chip);
- return ret;
- }
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -629,6 +629,7 @@ static int spinand_mtd_read(struct mtd_i
- {
- struct spinand_device *spinand = mtd_to_spinand(mtd);
- struct nand_device *nand = mtd_to_nanddev(mtd);
-+ struct mtd_ecc_stats old_stats;
- unsigned int max_bitflips = 0;
- struct nand_io_iter iter;
- bool disable_ecc = false;
-@@ -640,6 +641,8 @@ static int spinand_mtd_read(struct mtd_i
-
- mutex_lock(&spinand->lock);
-
-+ old_stats = mtd->ecc_stats;
-+
- nanddev_io_for_each_page(nand, NAND_PAGE_READ, from, ops, &iter) {
- if (disable_ecc)
- iter.req.mode = MTD_OPS_RAW;
-@@ -662,6 +665,13 @@ static int spinand_mtd_read(struct mtd_i
- ops->oobretlen += iter.req.ooblen;
- }
-
-+ if (ops->stats) {
-+ ops->stats->uncorrectable_errors +=
-+ mtd->ecc_stats.failed - old_stats.failed;
-+ ops->stats->corrected_bitflips +=
-+ mtd->ecc_stats.corrected - old_stats.corrected;
-+ }
-+
- mutex_unlock(&spinand->lock);
-
- if (ecc_failed && !ret)
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -41,6 +41,8 @@ struct mtd_erase_region_info {
- };
-
- struct mtd_req_stats {
-+ unsigned int uncorrectable_errors;
-+ unsigned int corrected_bitflips;
- unsigned int max_bitflips;
- };
-
diff --git a/target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch b/target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch
deleted file mode 100644
index 182e4f6ab5..0000000000
--- a/target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch
+++ /dev/null
@@ -1,321 +0,0 @@
-From 2c9745d36e04ac27161acd78514f647b9b587ad4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <kernel@kempniu.pl>
-Date: Wed, 29 Jun 2022 14:57:37 +0200
-Subject: [PATCH 4/4] mtdchar: add MEMREAD ioctl
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-User-space applications making use of MTD devices via /dev/mtd*
-character devices currently have limited capabilities for reading data:
-
- - only deprecated methods of accessing OOB layout information exist,
-
- - there is no way to explicitly specify MTD operation mode to use; it
- is auto-selected based on the MTD file mode (MTD_FILE_MODE_*) set
- for the character device; in particular, this prevents using
- MTD_OPS_AUTO_OOB for reads,
-
- - all existing user-space interfaces which cause mtd_read() or
- mtd_read_oob() to be called (via mtdchar_read() and
- mtdchar_read_oob(), respectively) return success even when those
- functions return -EUCLEAN or -EBADMSG; this renders user-space
- applications using these interfaces unaware of any corrected
- bitflips or uncorrectable ECC errors detected during reads.
-
-Note that the existing MEMWRITE ioctl allows the MTD operation mode to
-be explicitly set, allowing user-space applications to write page data
-and OOB data without requiring them to know anything about the OOB
-layout of the MTD device they are writing to (MTD_OPS_AUTO_OOB). Also,
-the MEMWRITE ioctl does not mangle the return value of mtd_write_oob().
-
-Add a new ioctl, MEMREAD, which addresses the above issues. It is
-intended to be a read-side counterpart of the existing MEMWRITE ioctl.
-Similarly to the latter, the read operation is performed in a loop which
-processes at most mtd->erasesize bytes in each iteration. This is done
-to prevent unbounded memory allocations caused by calling kmalloc() with
-the 'size' argument taken directly from the struct mtd_read_req provided
-by user space. However, the new ioctl is implemented so that the values
-it returns match those that would have been returned if just a single
-mtd_read_oob() call was issued to handle the entire read operation in
-one go.
-
-Note that while just returning -EUCLEAN or -EBADMSG to user space would
-already be a valid and useful indication of the ECC algorithm detecting
-errors during a read operation, that signal would not be granular enough
-to cover all use cases. For example, knowing the maximum number of
-bitflips detected in a single ECC step during a read operation performed
-on a given page may be useful when dealing with an MTD partition whose
-ECC layout varies across pages (e.g. a partition consisting of a
-bootloader area using a "custom" ECC layout followed by data pages using
-a "standard" ECC layout). To address that, include ECC statistics in
-the structure returned to user space by the new MEMREAD ioctl.
-
-Link: https://www.infradead.org/pipermail/linux-mtd/2016-April/067085.html
-
-Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Michał Kępień <kernel@kempniu.pl>
-Acked-by: Richard Weinberger <richard@nod.at>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-5-kernel@kempniu.pl
----
- drivers/mtd/mtdchar.c | 139 +++++++++++++++++++++++++++++++++++++
- include/uapi/mtd/mtd-abi.h | 64 +++++++++++++++--
- 2 files changed, 198 insertions(+), 5 deletions(-)
-
---- a/drivers/mtd/mtdchar.c
-+++ b/drivers/mtd/mtdchar.c
-@@ -621,6 +621,137 @@ static int mtdchar_write_ioctl(struct mt
- return ret;
- }
-
-+static int mtdchar_read_ioctl(struct mtd_info *mtd,
-+ struct mtd_read_req __user *argp)
-+{
-+ struct mtd_info *master = mtd_get_master(mtd);
-+ struct mtd_read_req req;
-+ void __user *usr_data, *usr_oob;
-+ uint8_t *datbuf = NULL, *oobbuf = NULL;
-+ size_t datbuf_len, oobbuf_len;
-+ size_t orig_len, orig_ooblen;
-+ int ret = 0;
-+
-+ if (copy_from_user(&req, argp, sizeof(req)))
-+ return -EFAULT;
-+
-+ orig_len = req.len;
-+ orig_ooblen = req.ooblen;
-+
-+ usr_data = (void __user *)(uintptr_t)req.usr_data;
-+ usr_oob = (void __user *)(uintptr_t)req.usr_oob;
-+
-+ if (!master->_read_oob)
-+ return -EOPNOTSUPP;
-+
-+ if (!usr_data)
-+ req.len = 0;
-+
-+ if (!usr_oob)
-+ req.ooblen = 0;
-+
-+ req.ecc_stats.uncorrectable_errors = 0;
-+ req.ecc_stats.corrected_bitflips = 0;
-+ req.ecc_stats.max_bitflips = 0;
-+
-+ req.len &= 0xffffffff;
-+ req.ooblen &= 0xffffffff;
-+
-+ if (req.start + req.len > mtd->size) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ datbuf_len = min_t(size_t, req.len, mtd->erasesize);
-+ if (datbuf_len > 0) {
-+ datbuf = kvmalloc(datbuf_len, GFP_KERNEL);
-+ if (!datbuf) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+ }
-+
-+ oobbuf_len = min_t(size_t, req.ooblen, mtd->erasesize);
-+ if (oobbuf_len > 0) {
-+ oobbuf = kvmalloc(oobbuf_len, GFP_KERNEL);
-+ if (!oobbuf) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+ }
-+
-+ while (req.len > 0 || (!usr_data && req.ooblen > 0)) {
-+ struct mtd_req_stats stats;
-+ struct mtd_oob_ops ops = {
-+ .mode = req.mode,
-+ .len = min_t(size_t, req.len, datbuf_len),
-+ .ooblen = min_t(size_t, req.ooblen, oobbuf_len),
-+ .datbuf = datbuf,
-+ .oobbuf = oobbuf,
-+ .stats = &stats,
-+ };
-+
-+ /*
-+ * Shorten non-page-aligned, eraseblock-sized reads so that the
-+ * read ends on an eraseblock boundary. This is necessary in
-+ * order to prevent OOB data for some pages from being
-+ * duplicated in the output of non-page-aligned reads requiring
-+ * multiple mtd_read_oob() calls to be completed.
-+ */
-+ if (ops.len == mtd->erasesize)
-+ ops.len -= mtd_mod_by_ws(req.start + ops.len, mtd);
-+
-+ ret = mtd_read_oob(mtd, (loff_t)req.start, &ops);
-+
-+ req.ecc_stats.uncorrectable_errors +=
-+ stats.uncorrectable_errors;
-+ req.ecc_stats.corrected_bitflips += stats.corrected_bitflips;
-+ req.ecc_stats.max_bitflips =
-+ max(req.ecc_stats.max_bitflips, stats.max_bitflips);
-+
-+ if (ret && !mtd_is_bitflip_or_eccerr(ret))
-+ break;
-+
-+ if (copy_to_user(usr_data, ops.datbuf, ops.retlen) ||
-+ copy_to_user(usr_oob, ops.oobbuf, ops.oobretlen)) {
-+ ret = -EFAULT;
-+ break;
-+ }
-+
-+ req.start += ops.retlen;
-+ req.len -= ops.retlen;
-+ usr_data += ops.retlen;
-+
-+ req.ooblen -= ops.oobretlen;
-+ usr_oob += ops.oobretlen;
-+ }
-+
-+ /*
-+ * As multiple iterations of the above loop (and therefore multiple
-+ * mtd_read_oob() calls) may be necessary to complete the read request,
-+ * adjust the final return code to ensure it accounts for all detected
-+ * ECC errors.
-+ */
-+ if (!ret || mtd_is_bitflip(ret)) {
-+ if (req.ecc_stats.uncorrectable_errors > 0)
-+ ret = -EBADMSG;
-+ else if (req.ecc_stats.corrected_bitflips > 0)
-+ ret = -EUCLEAN;
-+ }
-+
-+out:
-+ req.len = orig_len - req.len;
-+ req.ooblen = orig_ooblen - req.ooblen;
-+
-+ if (copy_to_user(argp, &req, sizeof(req)))
-+ ret = -EFAULT;
-+
-+ kvfree(datbuf);
-+ kvfree(oobbuf);
-+
-+ return ret;
-+}
-+
- static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
- {
- struct mtd_file_info *mfi = file->private_data;
-@@ -643,6 +774,7 @@ static int mtdchar_ioctl(struct file *fi
- case MEMGETINFO:
- case MEMREADOOB:
- case MEMREADOOB64:
-+ case MEMREAD:
- case MEMISLOCKED:
- case MEMGETOOBSEL:
- case MEMGETBADBLOCK:
-@@ -817,6 +949,13 @@ static int mtdchar_ioctl(struct file *fi
- break;
- }
-
-+ case MEMREAD:
-+ {
-+ ret = mtdchar_read_ioctl(mtd,
-+ (struct mtd_read_req __user *)arg);
-+ break;
-+ }
-+
- case MEMLOCK:
- {
- struct erase_info_user einfo;
---- a/include/uapi/mtd/mtd-abi.h
-+++ b/include/uapi/mtd/mtd-abi.h
-@@ -55,9 +55,9 @@ struct mtd_oob_buf64 {
- * @MTD_OPS_RAW: data are transferred as-is, with no error correction;
- * this mode implies %MTD_OPS_PLACE_OOB
- *
-- * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
-- * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
-- * %MTD_FILE_MODE_RAW.
-+ * These modes can be passed to ioctl(MEMWRITE) and ioctl(MEMREAD); they are
-+ * also used internally. See notes on "MTD file modes" for discussion on
-+ * %MTD_OPS_RAW vs. %MTD_FILE_MODE_RAW.
- */
- enum {
- MTD_OPS_PLACE_OOB = 0,
-@@ -91,6 +91,53 @@ struct mtd_write_req {
- __u8 padding[7];
- };
-
-+/**
-+ * struct mtd_read_req_ecc_stats - ECC statistics for a read operation
-+ *
-+ * @uncorrectable_errors: the number of uncorrectable errors that happened
-+ * during the read operation
-+ * @corrected_bitflips: the number of bitflips corrected during the read
-+ * operation
-+ * @max_bitflips: the maximum number of bitflips detected in any single ECC
-+ * step for the data read during the operation; this information
-+ * can be used to decide whether the data stored in a specific
-+ * region of the MTD device should be moved somewhere else to
-+ * avoid data loss.
-+ */
-+struct mtd_read_req_ecc_stats {
-+ __u32 uncorrectable_errors;
-+ __u32 corrected_bitflips;
-+ __u32 max_bitflips;
-+};
-+
-+/**
-+ * struct mtd_read_req - data structure for requesting a read operation
-+ *
-+ * @start: start address
-+ * @len: length of data buffer (only lower 32 bits are used)
-+ * @ooblen: length of OOB buffer (only lower 32 bits are used)
-+ * @usr_data: user-provided data buffer
-+ * @usr_oob: user-provided OOB buffer
-+ * @mode: MTD mode (see "MTD operation modes")
-+ * @padding: reserved, must be set to 0
-+ * @ecc_stats: ECC statistics for the read operation
-+ *
-+ * This structure supports ioctl(MEMREAD) operations, allowing data and/or OOB
-+ * reads in various modes. To read from OOB-only, set @usr_data == NULL, and to
-+ * read data-only, set @usr_oob == NULL. However, setting both @usr_data and
-+ * @usr_oob to NULL is not allowed.
-+ */
-+struct mtd_read_req {
-+ __u64 start;
-+ __u64 len;
-+ __u64 ooblen;
-+ __u64 usr_data;
-+ __u64 usr_oob;
-+ __u8 mode;
-+ __u8 padding[7];
-+ struct mtd_read_req_ecc_stats ecc_stats;
-+};
-+
- #define MTD_ABSENT 0
- #define MTD_RAM 1
- #define MTD_ROM 2
-@@ -207,6 +254,12 @@ struct otp_info {
- #define MEMWRITE _IOWR('M', 24, struct mtd_write_req)
- /* Erase a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */
- #define OTPERASE _IOW('M', 25, struct otp_info)
-+/*
-+ * Most generic read interface; can read in-band and/or out-of-band in various
-+ * modes (see "struct mtd_read_req"). This ioctl is not supported for flashes
-+ * without OOB, e.g., NOR flash.
-+ */
-+#define MEMREAD _IOWR('M', 26, struct mtd_read_req)
-
- /*
- * Obsolete legacy interface. Keep it in order not to break userspace
-@@ -270,8 +323,9 @@ struct mtd_ecc_stats {
- * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW -
- * raw access to the flash, without error correction or autoplacement schemes.
- * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode
-- * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is
-- * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)).
-+ * (e.g., when using ioctl(MEMWRITE) or ioctl(MEMREAD)), but in some cases, the
-+ * MTD_FILE_MODE is used out of necessity (e.g., `write()',
-+ * ioctl(MEMWRITEOOB64)).
- */
- enum mtd_file_modes {
- MTD_FILE_MODE_NORMAL = MTD_OTP_OFF,
diff --git a/target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch b/target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch
deleted file mode 100644
index 7dbc271725..0000000000
--- a/target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From ebed787a0becb9354f0a23620a5130cccd6c730c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 19 Jan 2023 03:45:43 +0000
-Subject: [PATCH] mtd: spinand: macronix: use scratch buffer for DMA operation
-
-The mx35lf1ge4ab_get_eccsr() function uses an SPI DMA operation to
-read the eccsr, hence the buffer should not be on stack. Since commit
-380583227c0c7f ("spi: spi-mem: Add extra sanity checks on the op param")
-the kernel emmits a warning and blocks such operations.
-
-Use the scratch buffer to get eccsr instead of trying to directly read
-into a stack-allocated variable.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Dhruva Gole <d-gole@ti.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/Y8i85zM0u4XdM46z@makrotopia.org
----
- drivers/mtd/nand/spi/macronix.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/spi/macronix.c
-+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -83,9 +83,10 @@ static int mx35lf1ge4ab_ecc_get_status(s
- * in order to avoid forcing the wear-leveling layer to move
- * data around if it's not necessary.
- */
-- if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
-+ if (mx35lf1ge4ab_get_eccsr(spinand, spinand->scratchbuf))
- return nanddev_get_ecc_conf(nand)->strength;
-
-+ eccsr = *spinand->scratchbuf;
- if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength ||
- !eccsr))
- return nanddev_get_ecc_conf(nand)->strength;
diff --git a/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch b/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch
deleted file mode 100644
index 2d89a5db12..0000000000
--- a/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 281f7a6c1a33fffcde32001bacbb4f672140fbf9 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Wed, 8 Mar 2023 09:20:21 +0100
-Subject: [PATCH] mtd: core: prepare mtd_otp_nvmem_add() to handle
- -EPROBE_DEFER
-
-NVMEM soon will get the ability for nvmem layouts and these might
-not be ready when nvmem_register() is called and thus it might
-return -EPROBE_DEFER. Don't print the error message in this case.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
----
- drivers/mtd/mtdcore.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -960,8 +960,8 @@ static int mtd_otp_nvmem_add(struct mtd_
- nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size,
- mtd_nvmem_user_otp_reg_read);
- if (IS_ERR(nvmem)) {
-- dev_err(dev, "Failed to register OTP NVMEM device\n");
-- return PTR_ERR(nvmem);
-+ err = PTR_ERR(nvmem);
-+ goto err;
- }
- mtd->otp_user_nvmem = nvmem;
- }
-@@ -978,7 +978,6 @@ static int mtd_otp_nvmem_add(struct mtd_
- nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size,
- mtd_nvmem_fact_otp_reg_read);
- if (IS_ERR(nvmem)) {
-- dev_err(dev, "Failed to register OTP NVMEM device\n");
- err = PTR_ERR(nvmem);
- goto err;
- }
-@@ -991,7 +990,7 @@ static int mtd_otp_nvmem_add(struct mtd_
- err:
- if (mtd->otp_user_nvmem)
- nvmem_unregister(mtd->otp_user_nvmem);
-- return err;
-+ return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n");
- }
-
- /**
diff --git a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch
deleted file mode 100644
index dca1062be9..0000000000
--- a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From 8610037e8106b48c79cfe0afb92b2b2466e51c3d Mon Sep 17 00:00:00 2001
-From: Joe Damato <jdamato@fastly.com>
-Date: Tue, 1 Mar 2022 23:55:47 -0800
-Subject: [PATCH] page_pool: Add allocation stats
-
-Add per-pool statistics counters for the allocation path of a page pool.
-These stats are incremented in softirq context, so no locking or per-cpu
-variables are needed.
-
-This code is disabled by default and a kernel config option is provided for
-users who wish to enable them.
-
-The statistics added are:
- - fast: successful fast path allocations
- - slow: slow path order-0 allocations
- - slow_high_order: slow path high order allocations
- - empty: ptr ring is empty, so a slow path allocation was forced.
- - refill: an allocation which triggered a refill of the cache
- - waive: pages obtained from the ptr ring that cannot be added to
- the cache due to a NUMA mismatch.
-
-Signed-off-by: Joe Damato <jdamato@fastly.com>
-Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
-Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/page_pool.h | 18 ++++++++++++++++++
- net/Kconfig | 13 +++++++++++++
- net/core/page_pool.c | 24 ++++++++++++++++++++----
- 3 files changed, 51 insertions(+), 4 deletions(-)
-
---- a/include/net/page_pool.h
-+++ b/include/net/page_pool.h
-@@ -82,6 +82,19 @@ struct page_pool_params {
- unsigned int offset; /* DMA addr offset */
- };
-
-+#ifdef CONFIG_PAGE_POOL_STATS
-+struct page_pool_alloc_stats {
-+ u64 fast; /* fast path allocations */
-+ u64 slow; /* slow-path order 0 allocations */
-+ u64 slow_high_order; /* slow-path high order allocations */
-+ u64 empty; /* failed refills due to empty ptr ring, forcing
-+ * slow path allocation
-+ */
-+ u64 refill; /* allocations via successful refill */
-+ u64 waive; /* failed refills due to numa zone mismatch */
-+};
-+#endif
-+
- struct page_pool {
- struct page_pool_params p;
-
-@@ -132,6 +145,11 @@ struct page_pool {
- refcount_t user_cnt;
-
- u64 destroy_cnt;
-+
-+#ifdef CONFIG_PAGE_POOL_STATS
-+ /* these stats are incremented while in softirq context */
-+ struct page_pool_alloc_stats alloc_stats;
-+#endif
- };
-
- struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp);
---- a/net/Kconfig
-+++ b/net/Kconfig
-@@ -432,6 +432,19 @@ config NET_DEVLINK
- config PAGE_POOL
- bool
-
-+config PAGE_POOL_STATS
-+ default n
-+ bool "Page pool stats"
-+ depends on PAGE_POOL
-+ help
-+ Enable page pool statistics to track page allocation and recycling
-+ in page pools. This option incurs additional CPU cost in allocation
-+ and recycle paths and additional memory cost to store the statistics.
-+ These statistics are only available if this option is enabled and if
-+ the driver using the page pool supports exporting this data.
-+
-+ If unsure, say N.
-+
- config FAILOVER
- tristate "Generic failover module"
- help
---- a/net/core/page_pool.c
-+++ b/net/core/page_pool.c
-@@ -49,6 +49,13 @@ static void page_pool_producer_unlock(st
- spin_unlock_bh(&pool->ring.producer_lock);
- }
-
-+#ifdef CONFIG_PAGE_POOL_STATS
-+/* alloc_stat_inc is intended to be used in softirq context */
-+#define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++)
-+#else
-+#define alloc_stat_inc(pool, __stat)
-+#endif
-+
- static int page_pool_init(struct page_pool *pool,
- const struct page_pool_params *params)
- {
-@@ -140,8 +147,10 @@ static struct page *page_pool_refill_all
- int pref_nid; /* preferred NUMA node */
-
- /* Quicker fallback, avoid locks when ring is empty */
-- if (__ptr_ring_empty(r))
-+ if (__ptr_ring_empty(r)) {
-+ alloc_stat_inc(pool, empty);
- return NULL;
-+ }
-
- /* Softirq guarantee CPU and thus NUMA node is stable. This,
- * assumes CPU refilling driver RX-ring will also run RX-NAPI.
-@@ -171,14 +180,17 @@ static struct page *page_pool_refill_all
- * This limit stress on page buddy alloactor.
- */
- page_pool_return_page(pool, page);
-+ alloc_stat_inc(pool, waive);
- page = NULL;
- break;
- }
- } while (pool->alloc.count < PP_ALLOC_CACHE_REFILL);
-
- /* Return last page */
-- if (likely(pool->alloc.count > 0))
-+ if (likely(pool->alloc.count > 0)) {
- page = pool->alloc.cache[--pool->alloc.count];
-+ alloc_stat_inc(pool, refill);
-+ }
-
- spin_unlock(&r->consumer_lock);
- return page;
-@@ -193,6 +205,7 @@ static struct page *__page_pool_get_cach
- if (likely(pool->alloc.count)) {
- /* Fast-path */
- page = pool->alloc.cache[--pool->alloc.count];
-+ alloc_stat_inc(pool, fast);
- } else {
- page = page_pool_refill_alloc_cache(pool);
- }
-@@ -264,6 +277,7 @@ static struct page *__page_pool_alloc_pa
- return NULL;
- }
-
-+ alloc_stat_inc(pool, slow_high_order);
- page_pool_set_pp_info(pool, page);
-
- /* Track how many pages are held 'in-flight' */
-@@ -318,10 +332,12 @@ static struct page *__page_pool_alloc_pa
- }
-
- /* Return last page */
-- if (likely(pool->alloc.count > 0))
-+ if (likely(pool->alloc.count > 0)) {
- page = pool->alloc.cache[--pool->alloc.count];
-- else
-+ alloc_stat_inc(pool, slow);
-+ } else {
- page = NULL;
-+ }
-
- /* When page just alloc'ed is should/must have refcnt 1. */
- return page;
diff --git a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch
deleted file mode 100644
index b425b78c75..0000000000
--- a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-From ad6fa1e1ab1b8164f1ba296b1b4dc556a483bcad Mon Sep 17 00:00:00 2001
-From: Joe Damato <jdamato@fastly.com>
-Date: Tue, 1 Mar 2022 23:55:48 -0800
-Subject: [PATCH 2/3] page_pool: Add recycle stats
-
-Add per-cpu stats tracking page pool recycling events:
- - cached: recycling placed page in the page pool cache
- - cache_full: page pool cache was full
- - ring: page placed into the ptr ring
- - ring_full: page released from page pool because the ptr ring was full
- - released_refcnt: page released (and not recycled) because refcnt > 1
-
-Signed-off-by: Joe Damato <jdamato@fastly.com>
-Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
-Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/page_pool.h | 16 ++++++++++++++++
- net/core/page_pool.c | 30 ++++++++++++++++++++++++++++--
- 2 files changed, 44 insertions(+), 2 deletions(-)
-
---- a/include/net/page_pool.h
-+++ b/include/net/page_pool.h
-@@ -93,6 +93,18 @@ struct page_pool_alloc_stats {
- u64 refill; /* allocations via successful refill */
- u64 waive; /* failed refills due to numa zone mismatch */
- };
-+
-+struct page_pool_recycle_stats {
-+ u64 cached; /* recycling placed page in the cache. */
-+ u64 cache_full; /* cache was full */
-+ u64 ring; /* recycling placed page back into ptr ring */
-+ u64 ring_full; /* page was released from page-pool because
-+ * PTR ring was full.
-+ */
-+ u64 released_refcnt; /* page released because of elevated
-+ * refcnt
-+ */
-+};
- #endif
-
- struct page_pool {
-@@ -136,6 +148,10 @@ struct page_pool {
- */
- struct ptr_ring ring;
-
-+#ifdef CONFIG_PAGE_POOL_STATS
-+ /* recycle stats are per-cpu to avoid locking */
-+ struct page_pool_recycle_stats __percpu *recycle_stats;
-+#endif
- atomic_t pages_state_release_cnt;
-
- /* A page_pool is strictly tied to a single RX-queue being
---- a/net/core/page_pool.c
-+++ b/net/core/page_pool.c
-@@ -52,8 +52,15 @@ static void page_pool_producer_unlock(st
- #ifdef CONFIG_PAGE_POOL_STATS
- /* alloc_stat_inc is intended to be used in softirq context */
- #define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++)
-+/* recycle_stat_inc is safe to use when preemption is possible. */
-+#define recycle_stat_inc(pool, __stat) \
-+ do { \
-+ struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \
-+ this_cpu_inc(s->__stat); \
-+ } while (0)
- #else
- #define alloc_stat_inc(pool, __stat)
-+#define recycle_stat_inc(pool, __stat)
- #endif
-
- static int page_pool_init(struct page_pool *pool,
-@@ -103,6 +110,12 @@ static int page_pool_init(struct page_po
- pool->p.flags & PP_FLAG_PAGE_FRAG)
- return -EINVAL;
-
-+#ifdef CONFIG_PAGE_POOL_STATS
-+ pool->recycle_stats = alloc_percpu(struct page_pool_recycle_stats);
-+ if (!pool->recycle_stats)
-+ return -ENOMEM;
-+#endif
-+
- if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0)
- return -ENOMEM;
-
-@@ -435,7 +448,12 @@ static bool page_pool_recycle_in_ring(st
- else
- ret = ptr_ring_produce_bh(&pool->ring, page);
-
-- return (ret == 0) ? true : false;
-+ if (!ret) {
-+ recycle_stat_inc(pool, ring);
-+ return true;
-+ }
-+
-+ return false;
- }
-
- /* Only allow direct recycling in special circumstances, into the
-@@ -446,11 +464,14 @@ static bool page_pool_recycle_in_ring(st
- static bool page_pool_recycle_in_cache(struct page *page,
- struct page_pool *pool)
- {
-- if (unlikely(pool->alloc.count == PP_ALLOC_CACHE_SIZE))
-+ if (unlikely(pool->alloc.count == PP_ALLOC_CACHE_SIZE)) {
-+ recycle_stat_inc(pool, cache_full);
- return false;
-+ }
-
- /* Caller MUST have verified/know (page_ref_count(page) == 1) */
- pool->alloc.cache[pool->alloc.count++] = page;
-+ recycle_stat_inc(pool, cached);
- return true;
- }
-
-@@ -505,6 +526,7 @@ __page_pool_put_page(struct page_pool *p
- * doing refcnt based recycle tricks, meaning another process
- * will be invoking put_page.
- */
-+ recycle_stat_inc(pool, released_refcnt);
- /* Do not replace this with page_pool_return_page() */
- page_pool_release_page(pool, page);
- put_page(page);
-@@ -518,6 +540,7 @@ void page_pool_put_page(struct page_pool
- page = __page_pool_put_page(pool, page, dma_sync_size, allow_direct);
- if (page && !page_pool_recycle_in_ring(pool, page)) {
- /* Cache full, fallback to free pages */
-+ recycle_stat_inc(pool, ring_full);
- page_pool_return_page(pool, page);
- }
- }
-@@ -665,6 +688,9 @@ static void page_pool_free(struct page_p
- if (pool->p.flags & PP_FLAG_DMA_MAP)
- put_device(pool->p.dev);
-
-+#ifdef CONFIG_PAGE_POOL_STATS
-+ free_percpu(pool->recycle_stats);
-+#endif
- kfree(pool);
- }
-
diff --git a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch
deleted file mode 100644
index e1a7635133..0000000000
--- a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 6b95e3388b1ea0ca63500c5a6e39162dbf828433 Mon Sep 17 00:00:00 2001
-From: Joe Damato <jdamato@fastly.com>
-Date: Tue, 1 Mar 2022 23:55:49 -0800
-Subject: [PATCH 3/3] page_pool: Add function to batch and return stats
-
-Adds a function page_pool_get_stats which can be used by drivers to obtain
-stats for a specified page_pool.
-
-Signed-off-by: Joe Damato <jdamato@fastly.com>
-Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
-Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/page_pool.h | 17 +++++++++++++++++
- net/core/page_pool.c | 25 +++++++++++++++++++++++++
- 2 files changed, 42 insertions(+)
-
---- a/include/net/page_pool.h
-+++ b/include/net/page_pool.h
-@@ -105,6 +105,23 @@ struct page_pool_recycle_stats {
- * refcnt
- */
- };
-+
-+/* This struct wraps the above stats structs so users of the
-+ * page_pool_get_stats API can pass a single argument when requesting the
-+ * stats for the page pool.
-+ */
-+struct page_pool_stats {
-+ struct page_pool_alloc_stats alloc_stats;
-+ struct page_pool_recycle_stats recycle_stats;
-+};
-+
-+/*
-+ * Drivers that wish to harvest page pool stats and report them to users
-+ * (perhaps via ethtool, debugfs, or another mechanism) can allocate a
-+ * struct page_pool_stats call page_pool_get_stats to get stats for the specified pool.
-+ */
-+bool page_pool_get_stats(struct page_pool *pool,
-+ struct page_pool_stats *stats);
- #endif
-
- struct page_pool {
---- a/net/core/page_pool.c
-+++ b/net/core/page_pool.c
-@@ -58,6 +58,31 @@ static void page_pool_producer_unlock(st
- struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \
- this_cpu_inc(s->__stat); \
- } while (0)
-+
-+bool page_pool_get_stats(struct page_pool *pool,
-+ struct page_pool_stats *stats)
-+{
-+ int cpu = 0;
-+
-+ if (!stats)
-+ return false;
-+
-+ memcpy(&stats->alloc_stats, &pool->alloc_stats, sizeof(pool->alloc_stats));
-+
-+ for_each_possible_cpu(cpu) {
-+ const struct page_pool_recycle_stats *pcpu =
-+ per_cpu_ptr(pool->recycle_stats, cpu);
-+
-+ stats->recycle_stats.cached += pcpu->cached;
-+ stats->recycle_stats.cache_full += pcpu->cache_full;
-+ stats->recycle_stats.ring += pcpu->ring;
-+ stats->recycle_stats.ring_full += pcpu->ring_full;
-+ stats->recycle_stats.released_refcnt += pcpu->released_refcnt;
-+ }
-+
-+ return true;
-+}
-+EXPORT_SYMBOL(page_pool_get_stats);
- #else
- #define alloc_stat_inc(pool, __stat)
- #define recycle_stat_inc(pool, __stat)
diff --git a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch
deleted file mode 100644
index f438ef3a59..0000000000
--- a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 590032a4d2133ecc10d3078a8db1d85a4842f12c Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 11 Apr 2022 16:05:26 +0200
-Subject: [PATCH] page_pool: Add recycle stats to page_pool_put_page_bulk
-
-Add missing recycle stats to page_pool_put_page_bulk routine.
-
-Reviewed-by: Joe Damato <jdamato@fastly.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-Link: https://lore.kernel.org/r/3712178b51c007cfaed910ea80e68f00c916b1fa.1649685634.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- net/core/page_pool.c | 15 +++++++++++++--
- 1 file changed, 13 insertions(+), 2 deletions(-)
-
---- a/net/core/page_pool.c
-+++ b/net/core/page_pool.c
-@@ -59,6 +59,12 @@ static void page_pool_producer_unlock(st
- this_cpu_inc(s->__stat); \
- } while (0)
-
-+#define recycle_stat_add(pool, __stat, val) \
-+ do { \
-+ struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \
-+ this_cpu_add(s->__stat, val); \
-+ } while (0)
-+
- bool page_pool_get_stats(struct page_pool *pool,
- struct page_pool_stats *stats)
- {
-@@ -86,6 +92,7 @@ EXPORT_SYMBOL(page_pool_get_stats);
- #else
- #define alloc_stat_inc(pool, __stat)
- #define recycle_stat_inc(pool, __stat)
-+#define recycle_stat_add(pool, __stat, val)
- #endif
-
- static int page_pool_init(struct page_pool *pool,
-@@ -593,9 +600,13 @@ void page_pool_put_page_bulk(struct page
- /* Bulk producer into ptr_ring page_pool cache */
- in_softirq = page_pool_producer_lock(pool);
- for (i = 0; i < bulk_len; i++) {
-- if (__ptr_ring_produce(&pool->ring, data[i]))
-- break; /* ring full */
-+ if (__ptr_ring_produce(&pool->ring, data[i])) {
-+ /* ring full */
-+ recycle_stat_inc(pool, ring_full);
-+ break;
-+ }
- }
-+ recycle_stat_add(pool, ring, i);
- page_pool_producer_unlock(pool, in_softirq);
-
- /* Hopefully all pages was return into ptr_ring */
diff --git a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch
deleted file mode 100644
index 3ff136b084..0000000000
--- a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From f3c5264f452a5b0ac1de1f2f657efbabdea3c76a Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Apr 2022 18:31:58 +0200
-Subject: [PATCH] net: page_pool: introduce ethtool stats
-
-Introduce page_pool APIs to report stats through ethtool and reduce
-duplicated code in each driver.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Jakub Kicinski <kuba@kernel.org>
-Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/page_pool.h | 21 ++++++++++++++
- net/core/page_pool.c | 63 ++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 83 insertions(+), 1 deletion(-)
-
---- a/include/net/page_pool.h
-+++ b/include/net/page_pool.h
-@@ -115,6 +115,10 @@ struct page_pool_stats {
- struct page_pool_recycle_stats recycle_stats;
- };
-
-+int page_pool_ethtool_stats_get_count(void);
-+u8 *page_pool_ethtool_stats_get_strings(u8 *data);
-+u64 *page_pool_ethtool_stats_get(u64 *data, void *stats);
-+
- /*
- * Drivers that wish to harvest page pool stats and report them to users
- * (perhaps via ethtool, debugfs, or another mechanism) can allocate a
-@@ -122,6 +126,23 @@ struct page_pool_stats {
- */
- bool page_pool_get_stats(struct page_pool *pool,
- struct page_pool_stats *stats);
-+#else
-+
-+static inline int page_pool_ethtool_stats_get_count(void)
-+{
-+ return 0;
-+}
-+
-+static inline u8 *page_pool_ethtool_stats_get_strings(u8 *data)
-+{
-+ return data;
-+}
-+
-+static inline u64 *page_pool_ethtool_stats_get(u64 *data, void *stats)
-+{
-+ return data;
-+}
-+
- #endif
-
- struct page_pool {
---- a/net/core/page_pool.c
-+++ b/net/core/page_pool.c
-@@ -18,6 +18,7 @@
- #include <linux/page-flags.h>
- #include <linux/mm.h> /* for __put_page() */
- #include <linux/poison.h>
-+#include <linux/ethtool.h>
-
- #include <trace/events/page_pool.h>
-
-@@ -65,6 +66,20 @@ static void page_pool_producer_unlock(st
- this_cpu_add(s->__stat, val); \
- } while (0)
-
-+static const char pp_stats[][ETH_GSTRING_LEN] = {
-+ "rx_pp_alloc_fast",
-+ "rx_pp_alloc_slow",
-+ "rx_pp_alloc_slow_ho",
-+ "rx_pp_alloc_empty",
-+ "rx_pp_alloc_refill",
-+ "rx_pp_alloc_waive",
-+ "rx_pp_recycle_cached",
-+ "rx_pp_recycle_cache_full",
-+ "rx_pp_recycle_ring",
-+ "rx_pp_recycle_ring_full",
-+ "rx_pp_recycle_released_ref",
-+};
-+
- bool page_pool_get_stats(struct page_pool *pool,
- struct page_pool_stats *stats)
- {
-@@ -73,7 +88,13 @@ bool page_pool_get_stats(struct page_poo
- if (!stats)
- return false;
-
-- memcpy(&stats->alloc_stats, &pool->alloc_stats, sizeof(pool->alloc_stats));
-+ /* The caller is responsible to initialize stats. */
-+ stats->alloc_stats.fast += pool->alloc_stats.fast;
-+ stats->alloc_stats.slow += pool->alloc_stats.slow;
-+ stats->alloc_stats.slow_high_order += pool->alloc_stats.slow_high_order;
-+ stats->alloc_stats.empty += pool->alloc_stats.empty;
-+ stats->alloc_stats.refill += pool->alloc_stats.refill;
-+ stats->alloc_stats.waive += pool->alloc_stats.waive;
-
- for_each_possible_cpu(cpu) {
- const struct page_pool_recycle_stats *pcpu =
-@@ -89,6 +110,46 @@ bool page_pool_get_stats(struct page_poo
- return true;
- }
- EXPORT_SYMBOL(page_pool_get_stats);
-+
-+u8 *page_pool_ethtool_stats_get_strings(u8 *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(pp_stats); i++) {
-+ memcpy(data, pp_stats[i], ETH_GSTRING_LEN);
-+ data += ETH_GSTRING_LEN;
-+ }
-+
-+ return data;
-+}
-+EXPORT_SYMBOL(page_pool_ethtool_stats_get_strings);
-+
-+int page_pool_ethtool_stats_get_count(void)
-+{
-+ return ARRAY_SIZE(pp_stats);
-+}
-+EXPORT_SYMBOL(page_pool_ethtool_stats_get_count);
-+
-+u64 *page_pool_ethtool_stats_get(u64 *data, void *stats)
-+{
-+ struct page_pool_stats *pool_stats = stats;
-+
-+ *data++ = pool_stats->alloc_stats.fast;
-+ *data++ = pool_stats->alloc_stats.slow;
-+ *data++ = pool_stats->alloc_stats.slow_high_order;
-+ *data++ = pool_stats->alloc_stats.empty;
-+ *data++ = pool_stats->alloc_stats.refill;
-+ *data++ = pool_stats->alloc_stats.waive;
-+ *data++ = pool_stats->recycle_stats.cached;
-+ *data++ = pool_stats->recycle_stats.cache_full;
-+ *data++ = pool_stats->recycle_stats.ring;
-+ *data++ = pool_stats->recycle_stats.ring_full;
-+ *data++ = pool_stats->recycle_stats.released_refcnt;
-+
-+ return data;
-+}
-+EXPORT_SYMBOL(page_pool_ethtool_stats_get);
-+
- #else
- #define alloc_stat_inc(pool, __stat)
- #define recycle_stat_inc(pool, __stat)
diff --git a/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch b/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch
deleted file mode 100644
index 4a914404a2..0000000000
--- a/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 2e88d4ff03013937028f5397268b21e10cf68713 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 21 Jan 2022 11:09:45 +0100
-Subject: [PATCH] xdp: introduce flags field in xdp_buff/xdp_frame
-
-Introduce flags field in xdp_frame and xdp_buffer data structures
-to define additional buffer features. At the moment the only
-supported buffer feature is frags bit (XDP_FLAGS_HAS_FRAGS).
-frags bit is used to specify if this is a linear buffer
-(XDP_FLAGS_HAS_FRAGS not set) or a frags frame (XDP_FLAGS_HAS_FRAGS
-set). In the latter case the driver is expected to initialize the
-skb_shared_info structure at the end of the first buffer to link together
-subsequent buffers belonging to the same frame.
-
-Acked-by: Toke Hoiland-Jorgensen <toke@redhat.com>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/e389f14f3a162c0a5bc6a2e1aa8dd01a90be117d.1642758637.git.lorenzo@kernel.org
-Signed-off-by: Alexei Starovoitov <ast@kernel.org>
----
- include/net/xdp.h | 29 +++++++++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
---- a/include/net/xdp.h
-+++ b/include/net/xdp.h
-@@ -66,6 +66,10 @@ struct xdp_txq_info {
- struct net_device *dev;
- };
-
-+enum xdp_buff_flags {
-+ XDP_FLAGS_HAS_FRAGS = BIT(0), /* non-linear xdp buff */
-+};
-+
- struct xdp_buff {
- void *data;
- void *data_end;
-@@ -74,13 +78,30 @@ struct xdp_buff {
- struct xdp_rxq_info *rxq;
- struct xdp_txq_info *txq;
- u32 frame_sz; /* frame size to deduce data_hard_end/reserved tailroom*/
-+ u32 flags; /* supported values defined in xdp_buff_flags */
- };
-
-+static __always_inline bool xdp_buff_has_frags(struct xdp_buff *xdp)
-+{
-+ return !!(xdp->flags & XDP_FLAGS_HAS_FRAGS);
-+}
-+
-+static __always_inline void xdp_buff_set_frags_flag(struct xdp_buff *xdp)
-+{
-+ xdp->flags |= XDP_FLAGS_HAS_FRAGS;
-+}
-+
-+static __always_inline void xdp_buff_clear_frags_flag(struct xdp_buff *xdp)
-+{
-+ xdp->flags &= ~XDP_FLAGS_HAS_FRAGS;
-+}
-+
- static __always_inline void
- xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq)
- {
- xdp->frame_sz = frame_sz;
- xdp->rxq = rxq;
-+ xdp->flags = 0;
- }
-
- static __always_inline void
-@@ -122,8 +143,14 @@ struct xdp_frame {
- */
- struct xdp_mem_info mem;
- struct net_device *dev_rx; /* used by cpumap */
-+ u32 flags; /* supported values defined in xdp_buff_flags */
- };
-
-+static __always_inline bool xdp_frame_has_frags(struct xdp_frame *frame)
-+{
-+ return !!(frame->flags & XDP_FLAGS_HAS_FRAGS);
-+}
-+
- #define XDP_BULK_QUEUE_SIZE 16
- struct xdp_frame_bulk {
- int count;
-@@ -180,6 +207,7 @@ void xdp_convert_frame_to_buff(struct xd
- xdp->data_end = frame->data + frame->len;
- xdp->data_meta = frame->data - frame->metasize;
- xdp->frame_sz = frame->frame_sz;
-+ xdp->flags = frame->flags;
- }
-
- static inline
-@@ -206,6 +234,7 @@ int xdp_update_frame_from_buff(struct xd
- xdp_frame->headroom = headroom - sizeof(*xdp_frame);
- xdp_frame->metasize = metasize;
- xdp_frame->frame_sz = xdp->frame_sz;
-+ xdp_frame->flags = xdp->flags;
-
- return 0;
- }
diff --git a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch
deleted file mode 100644
index e126b21417..0000000000
--- a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch
+++ /dev/null
@@ -1,137 +0,0 @@
-From 7c48cb0176c6d6d3b55029f7ff4ffa05faee6446 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 21 Jan 2022 11:09:50 +0100
-Subject: [PATCH] xdp: add frags support to xdp_return_{buff/frame}
-
-Take into account if the received xdp_buff/xdp_frame is non-linear
-recycling/returning the frame memory to the allocator or into
-xdp_frame_bulk.
-
-Acked-by: Toke Hoiland-Jorgensen <toke@redhat.com>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/a961069febc868508ce1bdf5e53a343eb4e57cb2.1642758637.git.lorenzo@kernel.org
-Signed-off-by: Alexei Starovoitov <ast@kernel.org>
----
- include/net/xdp.h | 18 ++++++++++++++--
- net/core/xdp.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 69 insertions(+), 3 deletions(-)
-
---- a/include/net/xdp.h
-+++ b/include/net/xdp.h
-@@ -275,10 +275,24 @@ void __xdp_release_frame(void *data, str
- static inline void xdp_release_frame(struct xdp_frame *xdpf)
- {
- struct xdp_mem_info *mem = &xdpf->mem;
-+ struct skb_shared_info *sinfo;
-+ int i;
-
- /* Curr only page_pool needs this */
-- if (mem->type == MEM_TYPE_PAGE_POOL)
-- __xdp_release_frame(xdpf->data, mem);
-+ if (mem->type != MEM_TYPE_PAGE_POOL)
-+ return;
-+
-+ if (likely(!xdp_frame_has_frags(xdpf)))
-+ goto out;
-+
-+ sinfo = xdp_get_shared_info_from_frame(xdpf);
-+ for (i = 0; i < sinfo->nr_frags; i++) {
-+ struct page *page = skb_frag_page(&sinfo->frags[i]);
-+
-+ __xdp_release_frame(page_address(page), mem);
-+ }
-+out:
-+ __xdp_release_frame(xdpf->data, mem);
- }
-
- int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq,
---- a/net/core/xdp.c
-+++ b/net/core/xdp.c
-@@ -409,12 +409,38 @@ static void __xdp_return(void *data, str
-
- void xdp_return_frame(struct xdp_frame *xdpf)
- {
-+ struct skb_shared_info *sinfo;
-+ int i;
-+
-+ if (likely(!xdp_frame_has_frags(xdpf)))
-+ goto out;
-+
-+ sinfo = xdp_get_shared_info_from_frame(xdpf);
-+ for (i = 0; i < sinfo->nr_frags; i++) {
-+ struct page *page = skb_frag_page(&sinfo->frags[i]);
-+
-+ __xdp_return(page_address(page), &xdpf->mem, false, NULL);
-+ }
-+out:
- __xdp_return(xdpf->data, &xdpf->mem, false, NULL);
- }
- EXPORT_SYMBOL_GPL(xdp_return_frame);
-
- void xdp_return_frame_rx_napi(struct xdp_frame *xdpf)
- {
-+ struct skb_shared_info *sinfo;
-+ int i;
-+
-+ if (likely(!xdp_frame_has_frags(xdpf)))
-+ goto out;
-+
-+ sinfo = xdp_get_shared_info_from_frame(xdpf);
-+ for (i = 0; i < sinfo->nr_frags; i++) {
-+ struct page *page = skb_frag_page(&sinfo->frags[i]);
-+
-+ __xdp_return(page_address(page), &xdpf->mem, true, NULL);
-+ }
-+out:
- __xdp_return(xdpf->data, &xdpf->mem, true, NULL);
- }
- EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi);
-@@ -450,7 +476,7 @@ void xdp_return_frame_bulk(struct xdp_fr
- struct xdp_mem_allocator *xa;
-
- if (mem->type != MEM_TYPE_PAGE_POOL) {
-- __xdp_return(xdpf->data, &xdpf->mem, false, NULL);
-+ xdp_return_frame(xdpf);
- return;
- }
-
-@@ -469,12 +495,38 @@ void xdp_return_frame_bulk(struct xdp_fr
- bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
- }
-
-+ if (unlikely(xdp_frame_has_frags(xdpf))) {
-+ struct skb_shared_info *sinfo;
-+ int i;
-+
-+ sinfo = xdp_get_shared_info_from_frame(xdpf);
-+ for (i = 0; i < sinfo->nr_frags; i++) {
-+ skb_frag_t *frag = &sinfo->frags[i];
-+
-+ bq->q[bq->count++] = skb_frag_address(frag);
-+ if (bq->count == XDP_BULK_QUEUE_SIZE)
-+ xdp_flush_frame_bulk(bq);
-+ }
-+ }
- bq->q[bq->count++] = xdpf->data;
- }
- EXPORT_SYMBOL_GPL(xdp_return_frame_bulk);
-
- void xdp_return_buff(struct xdp_buff *xdp)
- {
-+ struct skb_shared_info *sinfo;
-+ int i;
-+
-+ if (likely(!xdp_buff_has_frags(xdp)))
-+ goto out;
-+
-+ sinfo = xdp_get_shared_info_from_buff(xdp);
-+ for (i = 0; i < sinfo->nr_frags; i++) {
-+ struct page *page = skb_frag_page(&sinfo->frags[i]);
-+
-+ __xdp_return(page_address(page), &xdp->rxq->mem, true, xdp);
-+ }
-+out:
- __xdp_return(xdp->data, &xdp->rxq->mem, true, xdp);
- }
-
diff --git a/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch b/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch
deleted file mode 100644
index 36f55d511a..0000000000
--- a/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From d16697cb6261d4cc23422e6b1cb2759df8aa76d0 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 21 Jan 2022 11:09:44 +0100
-Subject: [PATCH] net: skbuff: add size metadata to skb_shared_info for xdp
-
-Introduce xdp_frags_size field in skb_shared_info data structure
-to store xdp_buff/xdp_frame frame paged size (xdp_frags_size will
-be used in xdp frags support). In order to not increase
-skb_shared_info size we will use a hole due to skb_shared_info
-alignment.
-
-Acked-by: Toke Hoiland-Jorgensen <toke@redhat.com>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/8a849819a3e0a143d540f78a3a5add76e17e980d.1642758637.git.lorenzo@kernel.org
-Signed-off-by: Alexei Starovoitov <ast@kernel.org>
----
- include/linux/skbuff.h | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -568,6 +568,7 @@ struct skb_shared_info {
- * Warning : all fields before dataref are cleared in __alloc_skb()
- */
- atomic_t dataref;
-+ unsigned int xdp_frags_size;
-
- /* Intermediate layers must ensure that destructor_arg
- * remains valid until skb destructor */
diff --git a/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch b/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch
deleted file mode 100644
index 1ec260a2e6..0000000000
--- a/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 5142239a22219921a7863cf00c9ab853c00689d8 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 11 Mar 2022 10:14:18 +0100
-Subject: [PATCH] net: veth: Account total xdp_frame len running ndo_xdp_xmit
-
-Even if this is a theoretical issue since it is not possible to perform
-XDP_REDIRECT on a non-linear xdp_frame, veth driver does not account
-paged area in ndo_xdp_xmit function pointer.
-Introduce xdp_get_frame_len utility routine to get the xdp_frame full
-length and account total frame size running XDP_REDIRECT of a
-non-linear xdp frame into a veth device.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-Acked-by: Toke Hoiland-Jorgensen <toke@redhat.com>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/54f9fd3bb65d190daf2c0bbae2f852ff16cfbaa0.1646989407.git.lorenzo@kernel.org
----
- drivers/net/veth.c | 4 ++--
- include/net/xdp.h | 14 ++++++++++++++
- 2 files changed, 16 insertions(+), 2 deletions(-)
-
---- a/drivers/net/veth.c
-+++ b/drivers/net/veth.c
-@@ -503,7 +503,7 @@ static int veth_xdp_xmit(struct net_devi
- struct xdp_frame *frame = frames[i];
- void *ptr = veth_xdp_to_ptr(frame);
-
-- if (unlikely(frame->len > max_len ||
-+ if (unlikely(xdp_get_frame_len(frame) > max_len ||
- __ptr_ring_produce(&rq->xdp_ring, ptr)))
- break;
- nxmit++;
-@@ -864,7 +864,7 @@ static int veth_xdp_rcv(struct veth_rq *
- /* ndo_xdp_xmit */
- struct xdp_frame *frame = veth_ptr_to_xdp(ptr);
-
-- stats->xdp_bytes += frame->len;
-+ stats->xdp_bytes += xdp_get_frame_len(frame);
- frame = veth_xdp_rcv_one(rq, frame, bq, stats);
- if (frame) {
- /* XDP_PASS */
---- a/include/net/xdp.h
-+++ b/include/net/xdp.h
-@@ -295,6 +295,20 @@ out:
- __xdp_release_frame(xdpf->data, mem);
- }
-
-+static __always_inline unsigned int xdp_get_frame_len(struct xdp_frame *xdpf)
-+{
-+ struct skb_shared_info *sinfo;
-+ unsigned int len = xdpf->len;
-+
-+ if (likely(!xdp_frame_has_frags(xdpf)))
-+ goto out;
-+
-+ sinfo = xdp_get_shared_info_from_frame(xdpf);
-+ len += sinfo->xdp_frags_size;
-+out:
-+ return len;
-+}
-+
- int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq,
- struct net_device *dev, u32 queue_index, unsigned int napi_id);
- void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq);
diff --git a/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch b/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch
deleted file mode 100644
index fd583e80f4..0000000000
--- a/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 7cda76d858a4e71ac4a04066c093679a12e1312c Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 11 Mar 2022 10:14:20 +0100
-Subject: [PATCH] veth: Allow jumbo frames in xdp mode
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Allow increasing the MTU over page boundaries on veth devices
-if the attached xdp program declares to support xdp fragments.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/d5dc039c3d4123426e7023a488c449181a7bc57f.1646989407.git.lorenzo@kernel.org
----
- drivers/net/veth.c | 11 ++++++++---
- 1 file changed, 8 insertions(+), 3 deletions(-)
-
---- a/drivers/net/veth.c
-+++ b/drivers/net/veth.c
-@@ -1455,9 +1455,14 @@ static int veth_xdp_set(struct net_devic
- goto err;
- }
-
-- max_mtu = PAGE_SIZE - VETH_XDP_HEADROOM -
-- peer->hard_header_len -
-- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+ max_mtu = SKB_WITH_OVERHEAD(PAGE_SIZE - VETH_XDP_HEADROOM) -
-+ peer->hard_header_len;
-+ /* Allow increasing the max_mtu if the program supports
-+ * XDP fragments.
-+ */
-+ //if (prog->aux->xdp_has_frags)
-+ max_mtu += PAGE_SIZE * MAX_SKB_FRAGS;
-+
- if (peer->mtu > max_mtu) {
- NL_SET_ERR_MSG_MOD(extack, "Peer MTU is too large to set XDP");
- err = -ERANGE;
diff --git a/target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch b/target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch
deleted file mode 100644
index c5d5d2c3a9..0000000000
--- a/target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 7390609b0121a1b982c5ecdfcd72dc328e5784ee Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:42 +0000
-Subject: [PATCH] net: add helper eth_addr_add()
-
-Add a helper to add an offset to a ethernet address. This comes in handy
-if you have a base ethernet address for multiple interfaces.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/etherdevice.h | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/include/linux/etherdevice.h
-+++ b/include/linux/etherdevice.h
-@@ -478,6 +478,20 @@ static inline void eth_addr_inc(u8 *addr
- }
-
- /**
-+ * eth_addr_add() - Add (or subtract) an offset to/from the given MAC address.
-+ *
-+ * @offset: Offset to add.
-+ * @addr: Pointer to a six-byte array containing Ethernet address to increment.
-+ */
-+static inline void eth_addr_add(u8 *addr, long offset)
-+{
-+ u64 u = ether_addr_to_u64(addr);
-+
-+ u += offset;
-+ u64_to_ether_addr(u, addr);
-+}
-+
-+/**
- * is_etherdev_addr - Tell if given Ethernet address belongs to the device.
- * @dev: Pointer to a device structure
- * @addr: Pointer to a six-byte array containing the Ethernet address
diff --git a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch
deleted file mode 100644
index 8e5c718042..0000000000
--- a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch
+++ /dev/null
@@ -1,279 +0,0 @@
-From dc452a471dbae8aca8257c565174212620880093 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Fri, 10 Dec 2021 01:34:37 +0200
-Subject: net: dsa: introduce tagger-owned storage for private and shared data
-
-Ansuel is working on register access over Ethernet for the qca8k switch
-family. This requires the qca8k tagging protocol driver to receive
-frames which aren't intended for the network stack, but instead for the
-qca8k switch driver itself.
-
-The dp->priv is currently the prevailing method for passing data back
-and forth between the tagging protocol driver and the switch driver.
-However, this method is riddled with caveats.
-
-The DSA design allows in principle for any switch driver to return any
-protocol it desires in ->get_tag_protocol(). The dsa_loop driver can be
-modified to do just that. But in the current design, the memory behind
-dp->priv has to be allocated by the switch driver, so if the tagging
-protocol is paired to an unexpected switch driver, we may end up in NULL
-pointer dereferences inside the kernel, or worse (a switch driver may
-allocate dp->priv according to the expectations of a different tagger).
-
-The latter possibility is even more plausible considering that DSA
-switches can dynamically change tagging protocols in certain cases
-(dsa <-> edsa, ocelot <-> ocelot-8021q), and the current design lends
-itself to mistakes that are all too easy to make.
-
-This patch proposes that the tagging protocol driver should manage its
-own memory, instead of relying on the switch driver to do so.
-After analyzing the different in-tree needs, it can be observed that the
-required tagger storage is per switch, therefore a ds->tagger_data
-pointer is introduced. In principle, per-port storage could also be
-introduced, although there is no need for it at the moment. Future
-changes will replace the current usage of dp->priv with ds->tagger_data.
-
-We define a "binding" event between the DSA switch tree and the tagging
-protocol. During this binding event, the tagging protocol's ->connect()
-method is called first, and this may allocate some memory for each
-switch of the tree. Then a cross-chip notifier is emitted for the
-switches within that tree, and they are given the opportunity to fix up
-the tagger's memory (for example, they might set up some function
-pointers that represent virtual methods for consuming packets).
-Because the memory is owned by the tagger, there exists a ->disconnect()
-method for the tagger (which is the place to free the resources), but
-there doesn't exist a ->disconnect() method for the switch driver.
-This is part of the design. The switch driver should make minimal use of
-the public part of the tagger data, and only after type-checking it
-using the supplied "proto" argument.
-
-In the code there are in fact two binding events, one is the initial
-event in dsa_switch_setup_tag_protocol(). At this stage, the cross chip
-notifier chains aren't initialized, so we call each switch's connect()
-method by hand. Then there is dsa_tree_bind_tag_proto() during
-dsa_tree_change_tag_proto(), and here we have an old protocol and a new
-one. We first connect to the new one before disconnecting from the old
-one, to simplify error handling a bit and to ensure we remain in a valid
-state at all times.
-
-Co-developed-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/dsa.h | 12 +++++++++
- net/dsa/dsa2.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++---
- net/dsa/dsa_priv.h | 1 +
- net/dsa/switch.c | 14 +++++++++++
- 4 files changed, 96 insertions(+), 4 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -80,12 +80,15 @@ enum dsa_tag_protocol {
- };
-
- struct dsa_switch;
-+struct dsa_switch_tree;
-
- struct dsa_device_ops {
- struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
- struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev);
- void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
- int *offset);
-+ int (*connect)(struct dsa_switch_tree *dst);
-+ void (*disconnect)(struct dsa_switch_tree *dst);
- unsigned int needed_headroom;
- unsigned int needed_tailroom;
- const char *name;
-@@ -329,6 +332,8 @@ struct dsa_switch {
- */
- void *priv;
-
-+ void *tagger_data;
-+
- /*
- * Configuration data for this switch.
- */
-@@ -612,6 +617,13 @@ struct dsa_switch_ops {
- enum dsa_tag_protocol mprot);
- int (*change_tag_protocol)(struct dsa_switch *ds, int port,
- enum dsa_tag_protocol proto);
-+ /*
-+ * Method for switch drivers to connect to the tagging protocol driver
-+ * in current use. The switch driver can provide handlers for certain
-+ * types of packets for switch management.
-+ */
-+ int (*connect_tag_protocol)(struct dsa_switch *ds,
-+ enum dsa_tag_protocol proto);
-
- /* Optional switch-wide initialization and destruction methods */
- int (*setup)(struct dsa_switch *ds);
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -230,8 +230,12 @@ static struct dsa_switch_tree *dsa_tree_
-
- static void dsa_tree_free(struct dsa_switch_tree *dst)
- {
-- if (dst->tag_ops)
-+ if (dst->tag_ops) {
-+ if (dst->tag_ops->disconnect)
-+ dst->tag_ops->disconnect(dst);
-+
- dsa_tag_driver_put(dst->tag_ops);
-+ }
- list_del(&dst->list);
- kfree(dst);
- }
-@@ -827,7 +831,7 @@ static int dsa_switch_setup_tag_protocol
- int port, err;
-
- if (tag_ops->proto == dst->default_proto)
-- return 0;
-+ goto connect;
-
- for (port = 0; port < ds->num_ports; port++) {
- if (!dsa_is_cpu_port(ds, port))
-@@ -843,6 +847,17 @@ static int dsa_switch_setup_tag_protocol
- }
- }
-
-+connect:
-+ if (ds->ops->connect_tag_protocol) {
-+ err = ds->ops->connect_tag_protocol(ds, tag_ops->proto);
-+ if (err) {
-+ dev_err(ds->dev,
-+ "Unable to connect to tag protocol \"%s\": %pe\n",
-+ tag_ops->name, ERR_PTR(err));
-+ return err;
-+ }
-+ }
-+
- return 0;
- }
-
-@@ -1154,6 +1169,46 @@ static void dsa_tree_teardown(struct dsa
- dst->setup = false;
- }
-
-+static int dsa_tree_bind_tag_proto(struct dsa_switch_tree *dst,
-+ const struct dsa_device_ops *tag_ops)
-+{
-+ const struct dsa_device_ops *old_tag_ops = dst->tag_ops;
-+ struct dsa_notifier_tag_proto_info info;
-+ int err;
-+
-+ dst->tag_ops = tag_ops;
-+
-+ /* Notify the new tagger about the connection to this tree */
-+ if (tag_ops->connect) {
-+ err = tag_ops->connect(dst);
-+ if (err)
-+ goto out_revert;
-+ }
-+
-+ /* Notify the switches from this tree about the connection
-+ * to the new tagger
-+ */
-+ info.tag_ops = tag_ops;
-+ err = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO_CONNECT, &info);
-+ if (err && err != -EOPNOTSUPP)
-+ goto out_disconnect;
-+
-+ /* Notify the old tagger about the disconnection from this tree */
-+ if (old_tag_ops->disconnect)
-+ old_tag_ops->disconnect(dst);
-+
-+ return 0;
-+
-+out_disconnect:
-+ /* Revert the new tagger's connection to this tree */
-+ if (tag_ops->disconnect)
-+ tag_ops->disconnect(dst);
-+out_revert:
-+ dst->tag_ops = old_tag_ops;
-+
-+ return err;
-+}
-+
- /* Since the dsa/tagging sysfs device attribute is per master, the assumption
- * is that all DSA switches within a tree share the same tagger, otherwise
- * they would have formed disjoint trees (different "dsa,member" values).
-@@ -1186,12 +1241,15 @@ int dsa_tree_change_tag_proto(struct dsa
- goto out_unlock;
- }
-
-+ /* Notify the tag protocol change */
- info.tag_ops = tag_ops;
- err = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, &info);
- if (err)
-- goto out_unwind_tagger;
-+ return err;
-
-- dst->tag_ops = tag_ops;
-+ err = dsa_tree_bind_tag_proto(dst, tag_ops);
-+ if (err)
-+ goto out_unwind_tagger;
-
- rtnl_unlock();
-
-@@ -1279,6 +1337,7 @@ static int dsa_port_parse_cpu(struct dsa
- struct dsa_switch *ds = dp->ds;
- struct dsa_switch_tree *dst = ds->dst;
- enum dsa_tag_protocol default_proto;
-+ int err;
-
- /* Find out which protocol the switch would prefer. */
- default_proto = dsa_get_tag_protocol(dp, master);
-@@ -1333,6 +1392,12 @@ static int dsa_port_parse_cpu(struct dsa
- */
- dsa_tag_driver_put(tag_ops);
- } else {
-+ if (tag_ops->connect) {
-+ err = tag_ops->connect(dst);
-+ if (err)
-+ return err;
-+ }
-+
- dst->tag_ops = tag_ops;
- }
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -37,6 +37,7 @@ enum {
- DSA_NOTIFIER_VLAN_DEL,
- DSA_NOTIFIER_MTU,
- DSA_NOTIFIER_TAG_PROTO,
-+ DSA_NOTIFIER_TAG_PROTO_CONNECT,
- DSA_NOTIFIER_MRP_ADD,
- DSA_NOTIFIER_MRP_DEL,
- DSA_NOTIFIER_MRP_ADD_RING_ROLE,
---- a/net/dsa/switch.c
-+++ b/net/dsa/switch.c
-@@ -616,6 +616,17 @@ static int dsa_switch_change_tag_proto(s
- return 0;
- }
-
-+static int dsa_switch_connect_tag_proto(struct dsa_switch *ds,
-+ struct dsa_notifier_tag_proto_info *info)
-+{
-+ const struct dsa_device_ops *tag_ops = info->tag_ops;
-+
-+ if (!ds->ops->connect_tag_protocol)
-+ return -EOPNOTSUPP;
-+
-+ return ds->ops->connect_tag_protocol(ds, tag_ops->proto);
-+}
-+
- static int dsa_switch_mrp_add(struct dsa_switch *ds,
- struct dsa_notifier_mrp_info *info)
- {
-@@ -735,6 +746,9 @@ static int dsa_switch_event(struct notif
- case DSA_NOTIFIER_TAG_PROTO:
- err = dsa_switch_change_tag_proto(ds, info);
- break;
-+ case DSA_NOTIFIER_TAG_PROTO_CONNECT:
-+ err = dsa_switch_connect_tag_proto(ds, info);
-+ break;
- case DSA_NOTIFIER_MRP_ADD:
- err = dsa_switch_mrp_add(ds, info);
- break;
diff --git a/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch b/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch
deleted file mode 100644
index 8c81ebc7f5..0000000000
--- a/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch
+++ /dev/null
@@ -1,274 +0,0 @@
-From 7f2973149c22e7a6fee4c0c9fa6b8e4108e9c208 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 14 Dec 2021 03:45:36 +0200
-Subject: net: dsa: make tagging protocols connect to individual switches from
- a tree
-
-On the NXP Bluebox 3 board which uses a multi-switch setup with sja1105,
-the mechanism through which the tagger connects to the switch tree is
-broken, due to improper DSA code design. At the time when tag_ops->connect()
-is called in dsa_port_parse_cpu(), DSA hasn't finished "touching" all
-the ports, so it doesn't know how large the tree is and how many ports
-it has. It has just seen the first CPU port by this time. As a result,
-this function will call the tagger's ->connect method too early, and the
-tagger will connect only to the first switch from the tree.
-
-This could be perhaps addressed a bit more simply by just moving the
-tag_ops->connect(dst) call a bit later (for example in dsa_tree_setup),
-but there is already a design inconsistency at present: on the switch
-side, the notification is on a per-switch basis, but on the tagger side,
-it is on a per-tree basis. Furthermore, the persistent storage itself is
-per switch (ds->tagger_data). And the tagger connect and disconnect
-procedures (at least the ones that exist currently) could see a fair bit
-of simplification if they didn't have to iterate through the switches of
-a tree.
-
-To fix the issue, this change transforms tag_ops->connect(dst) into
-tag_ops->connect(ds) and moves it somewhere where we already iterate
-over all switches of a tree. That is in dsa_switch_setup_tag_protocol(),
-which is a good placement because we already have there the connection
-call to the switch side of things.
-
-As for the dsa_tree_bind_tag_proto() method (called from the code path
-that changes the tag protocol), things are a bit more complicated
-because we receive the tree as argument, yet when we unwind on errors,
-it would be nice to not call tag_ops->disconnect(ds) where we didn't
-previously call tag_ops->connect(ds). We didn't have this problem before
-because the tag_ops connection operations passed the entire dst before,
-and this is more fine grained now. To solve the error rewind case using
-the new API, we have to create yet one more cross-chip notifier for
-disconnection, and stay connected with the old tag protocol to all the
-switches in the tree until we've succeeded to connect with the new one
-as well. So if something fails half way, the whole tree is still
-connected to the old tagger. But there may still be leaks if the tagger
-fails to connect to the 2nd out of 3 switches in a tree: somebody needs
-to tell the tagger to disconnect from the first switch. Nothing comes
-for free, and this was previously handled privately by the tagging
-protocol driver before, but now we need to emit a disconnect cross-chip
-notifier for that, because DSA has to take care of the unwind path. We
-assume that the tagging protocol has connected to a switch if it has set
-ds->tagger_data to something, otherwise we avoid calling its
-disconnection method in the error rewind path.
-
-The rest of the changes are in the tagging protocol drivers, and have to
-do with the replacement of dst with ds. The iteration is removed and the
-error unwind path is simplified, as mentioned above.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/dsa.h | 5 ++--
- net/dsa/dsa2.c | 44 +++++++++++++-----------------
- net/dsa/dsa_priv.h | 1 +
- net/dsa/switch.c | 52 ++++++++++++++++++++++++++++++++---
- net/dsa/tag_ocelot_8021q.c | 53 +++++++++++-------------------------
- net/dsa/tag_sja1105.c | 67 ++++++++++++++++------------------------------
- 6 files changed, 109 insertions(+), 113 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -80,15 +80,14 @@ enum dsa_tag_protocol {
- };
-
- struct dsa_switch;
--struct dsa_switch_tree;
-
- struct dsa_device_ops {
- struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
- struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev);
- void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
- int *offset);
-- int (*connect)(struct dsa_switch_tree *dst);
-- void (*disconnect)(struct dsa_switch_tree *dst);
-+ int (*connect)(struct dsa_switch *ds);
-+ void (*disconnect)(struct dsa_switch *ds);
- unsigned int needed_headroom;
- unsigned int needed_tailroom;
- const char *name;
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -230,12 +230,8 @@ static struct dsa_switch_tree *dsa_tree_
-
- static void dsa_tree_free(struct dsa_switch_tree *dst)
- {
-- if (dst->tag_ops) {
-- if (dst->tag_ops->disconnect)
-- dst->tag_ops->disconnect(dst);
--
-+ if (dst->tag_ops)
- dsa_tag_driver_put(dst->tag_ops);
-- }
- list_del(&dst->list);
- kfree(dst);
- }
-@@ -848,17 +844,29 @@ static int dsa_switch_setup_tag_protocol
- }
-
- connect:
-+ if (tag_ops->connect) {
-+ err = tag_ops->connect(ds);
-+ if (err)
-+ return err;
-+ }
-+
- if (ds->ops->connect_tag_protocol) {
- err = ds->ops->connect_tag_protocol(ds, tag_ops->proto);
- if (err) {
- dev_err(ds->dev,
- "Unable to connect to tag protocol \"%s\": %pe\n",
- tag_ops->name, ERR_PTR(err));
-- return err;
-+ goto disconnect;
- }
- }
-
- return 0;
-+
-+disconnect:
-+ if (tag_ops->disconnect)
-+ tag_ops->disconnect(ds);
-+
-+ return err;
- }
-
- static int dsa_switch_setup(struct dsa_switch *ds)
-@@ -1178,13 +1186,6 @@ static int dsa_tree_bind_tag_proto(struc
-
- dst->tag_ops = tag_ops;
-
-- /* Notify the new tagger about the connection to this tree */
-- if (tag_ops->connect) {
-- err = tag_ops->connect(dst);
-- if (err)
-- goto out_revert;
-- }
--
- /* Notify the switches from this tree about the connection
- * to the new tagger
- */
-@@ -1194,16 +1195,14 @@ static int dsa_tree_bind_tag_proto(struc
- goto out_disconnect;
-
- /* Notify the old tagger about the disconnection from this tree */
-- if (old_tag_ops->disconnect)
-- old_tag_ops->disconnect(dst);
-+ info.tag_ops = old_tag_ops;
-+ dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO_DISCONNECT, &info);
-
- return 0;
-
- out_disconnect:
-- /* Revert the new tagger's connection to this tree */
-- if (tag_ops->disconnect)
-- tag_ops->disconnect(dst);
--out_revert:
-+ info.tag_ops = tag_ops;
-+ dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO_DISCONNECT, &info);
- dst->tag_ops = old_tag_ops;
-
- return err;
-@@ -1337,7 +1336,6 @@ static int dsa_port_parse_cpu(struct dsa
- struct dsa_switch *ds = dp->ds;
- struct dsa_switch_tree *dst = ds->dst;
- enum dsa_tag_protocol default_proto;
-- int err;
-
- /* Find out which protocol the switch would prefer. */
- default_proto = dsa_get_tag_protocol(dp, master);
-@@ -1392,12 +1390,6 @@ static int dsa_port_parse_cpu(struct dsa
- */
- dsa_tag_driver_put(tag_ops);
- } else {
-- if (tag_ops->connect) {
-- err = tag_ops->connect(dst);
-- if (err)
-- return err;
-- }
--
- dst->tag_ops = tag_ops;
- }
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -38,6 +38,7 @@ enum {
- DSA_NOTIFIER_MTU,
- DSA_NOTIFIER_TAG_PROTO,
- DSA_NOTIFIER_TAG_PROTO_CONNECT,
-+ DSA_NOTIFIER_TAG_PROTO_DISCONNECT,
- DSA_NOTIFIER_MRP_ADD,
- DSA_NOTIFIER_MRP_DEL,
- DSA_NOTIFIER_MRP_ADD_RING_ROLE,
---- a/net/dsa/switch.c
-+++ b/net/dsa/switch.c
-@@ -616,15 +616,58 @@ static int dsa_switch_change_tag_proto(s
- return 0;
- }
-
--static int dsa_switch_connect_tag_proto(struct dsa_switch *ds,
-- struct dsa_notifier_tag_proto_info *info)
-+/* We use the same cross-chip notifiers to inform both the tagger side, as well
-+ * as the switch side, of connection and disconnection events.
-+ * Since ds->tagger_data is owned by the tagger, it isn't a hard error if the
-+ * switch side doesn't support connecting to this tagger, and therefore, the
-+ * fact that we don't disconnect the tagger side doesn't constitute a memory
-+ * leak: the tagger will still operate with persistent per-switch memory, just
-+ * with the switch side unconnected to it. What does constitute a hard error is
-+ * when the switch side supports connecting but fails.
-+ */
-+static int
-+dsa_switch_connect_tag_proto(struct dsa_switch *ds,
-+ struct dsa_notifier_tag_proto_info *info)
- {
- const struct dsa_device_ops *tag_ops = info->tag_ops;
-+ int err;
-+
-+ /* Notify the new tagger about the connection to this switch */
-+ if (tag_ops->connect) {
-+ err = tag_ops->connect(ds);
-+ if (err)
-+ return err;
-+ }
-
- if (!ds->ops->connect_tag_protocol)
- return -EOPNOTSUPP;
-
-- return ds->ops->connect_tag_protocol(ds, tag_ops->proto);
-+ /* Notify the switch about the connection to the new tagger */
-+ err = ds->ops->connect_tag_protocol(ds, tag_ops->proto);
-+ if (err) {
-+ /* Revert the new tagger's connection to this tree */
-+ if (tag_ops->disconnect)
-+ tag_ops->disconnect(ds);
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+dsa_switch_disconnect_tag_proto(struct dsa_switch *ds,
-+ struct dsa_notifier_tag_proto_info *info)
-+{
-+ const struct dsa_device_ops *tag_ops = info->tag_ops;
-+
-+ /* Notify the tagger about the disconnection from this switch */
-+ if (tag_ops->disconnect && ds->tagger_data)
-+ tag_ops->disconnect(ds);
-+
-+ /* No need to notify the switch, since it shouldn't have any
-+ * resources to tear down
-+ */
-+ return 0;
- }
-
- static int dsa_switch_mrp_add(struct dsa_switch *ds,
-@@ -749,6 +792,9 @@ static int dsa_switch_event(struct notif
- case DSA_NOTIFIER_TAG_PROTO_CONNECT:
- err = dsa_switch_connect_tag_proto(ds, info);
- break;
-+ case DSA_NOTIFIER_TAG_PROTO_DISCONNECT:
-+ err = dsa_switch_disconnect_tag_proto(ds, info);
-+ break;
- case DSA_NOTIFIER_MRP_ADD:
- err = dsa_switch_mrp_add(ds, info);
- break;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch b/target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch
deleted file mode 100644
index 2bace3baac..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch
+++ /dev/null
@@ -1,327 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 5 Feb 2022 17:59:07 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for coherent
- DMA
-
-It improves performance by eliminating the need for a cache flush on rx and tx
-In preparation for supporting WED (Wireless Ethernet Dispatch), also add a
-function for disabling coherent DMA at runtime.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -9,6 +9,7 @@
- #include <linux/of_device.h>
- #include <linux/of_mdio.h>
- #include <linux/of_net.h>
-+#include <linux/of_address.h>
- #include <linux/mfd/syscon.h>
- #include <linux/regmap.h>
- #include <linux/clk.h>
-@@ -850,7 +851,7 @@ static int mtk_init_fq_dma(struct mtk_et
- dma_addr_t dma_addr;
- int i;
-
-- eth->scratch_ring = dma_alloc_coherent(eth->dev,
-+ eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
- cnt * sizeof(struct mtk_tx_dma),
- &eth->phy_scratch_ring,
- GFP_ATOMIC);
-@@ -862,10 +863,10 @@ static int mtk_init_fq_dma(struct mtk_et
- if (unlikely(!eth->scratch_head))
- return -ENOMEM;
-
-- dma_addr = dma_map_single(eth->dev,
-+ dma_addr = dma_map_single(eth->dma_dev,
- eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
- DMA_FROM_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
-+ if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
- return -ENOMEM;
-
- phy_ring_tail = eth->phy_scratch_ring +
-@@ -919,26 +920,26 @@ static void mtk_tx_unmap(struct mtk_eth
- {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
- if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) {
-- dma_unmap_single(eth->dev,
-+ dma_unmap_single(eth->dma_dev,
- dma_unmap_addr(tx_buf, dma_addr0),
- dma_unmap_len(tx_buf, dma_len0),
- DMA_TO_DEVICE);
- } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) {
-- dma_unmap_page(eth->dev,
-+ dma_unmap_page(eth->dma_dev,
- dma_unmap_addr(tx_buf, dma_addr0),
- dma_unmap_len(tx_buf, dma_len0),
- DMA_TO_DEVICE);
- }
- } else {
- if (dma_unmap_len(tx_buf, dma_len0)) {
-- dma_unmap_page(eth->dev,
-+ dma_unmap_page(eth->dma_dev,
- dma_unmap_addr(tx_buf, dma_addr0),
- dma_unmap_len(tx_buf, dma_len0),
- DMA_TO_DEVICE);
- }
-
- if (dma_unmap_len(tx_buf, dma_len1)) {
-- dma_unmap_page(eth->dev,
-+ dma_unmap_page(eth->dma_dev,
- dma_unmap_addr(tx_buf, dma_addr1),
- dma_unmap_len(tx_buf, dma_len1),
- DMA_TO_DEVICE);
-@@ -1016,9 +1017,9 @@ static int mtk_tx_map(struct sk_buff *sk
- if (skb_vlan_tag_present(skb))
- txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
-
-- mapped_addr = dma_map_single(eth->dev, skb->data,
-+ mapped_addr = dma_map_single(eth->dma_dev, skb->data,
- skb_headlen(skb), DMA_TO_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dev, mapped_addr)))
-+ if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr)))
- return -ENOMEM;
-
- WRITE_ONCE(itxd->txd1, mapped_addr);
-@@ -1057,10 +1058,10 @@ static int mtk_tx_map(struct sk_buff *sk
-
-
- frag_map_size = min(frag_size, MTK_TX_DMA_BUF_LEN);
-- mapped_addr = skb_frag_dma_map(eth->dev, frag, offset,
-+ mapped_addr = skb_frag_dma_map(eth->dma_dev, frag, offset,
- frag_map_size,
- DMA_TO_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dev, mapped_addr)))
-+ if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr)))
- goto err_dma;
-
- if (i == nr_frags - 1 &&
-@@ -1341,18 +1342,18 @@ static int mtk_poll_rx(struct napi_struc
- netdev->stats.rx_dropped++;
- goto release_desc;
- }
-- dma_addr = dma_map_single(eth->dev,
-+ dma_addr = dma_map_single(eth->dma_dev,
- new_data + NET_SKB_PAD +
- eth->ip_align,
- ring->buf_size,
- DMA_FROM_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dev, dma_addr))) {
-+ if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) {
- skb_free_frag(new_data);
- netdev->stats.rx_dropped++;
- goto release_desc;
- }
-
-- dma_unmap_single(eth->dev, trxd.rxd1,
-+ dma_unmap_single(eth->dma_dev, trxd.rxd1,
- ring->buf_size, DMA_FROM_DEVICE);
-
- /* receive data */
-@@ -1625,7 +1626,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- if (!ring->buf)
- goto no_tx_mem;
-
-- ring->dma = dma_alloc_coherent(eth->dev, MTK_DMA_SIZE * sz,
-+ ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
- &ring->phys, GFP_ATOMIC);
- if (!ring->dma)
- goto no_tx_mem;
-@@ -1643,7 +1644,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- * descriptors in ring->dma_pdma.
- */
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-- ring->dma_pdma = dma_alloc_coherent(eth->dev, MTK_DMA_SIZE * sz,
-+ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
- &ring->phys_pdma,
- GFP_ATOMIC);
- if (!ring->dma_pdma)
-@@ -1702,7 +1703,7 @@ static void mtk_tx_clean(struct mtk_eth
- }
-
- if (ring->dma) {
-- dma_free_coherent(eth->dev,
-+ dma_free_coherent(eth->dma_dev,
- MTK_DMA_SIZE * sizeof(*ring->dma),
- ring->dma,
- ring->phys);
-@@ -1710,7 +1711,7 @@ static void mtk_tx_clean(struct mtk_eth
- }
-
- if (ring->dma_pdma) {
-- dma_free_coherent(eth->dev,
-+ dma_free_coherent(eth->dma_dev,
- MTK_DMA_SIZE * sizeof(*ring->dma_pdma),
- ring->dma_pdma,
- ring->phys_pdma);
-@@ -1758,18 +1759,18 @@ static int mtk_rx_alloc(struct mtk_eth *
- return -ENOMEM;
- }
-
-- ring->dma = dma_alloc_coherent(eth->dev,
-+ ring->dma = dma_alloc_coherent(eth->dma_dev,
- rx_dma_size * sizeof(*ring->dma),
- &ring->phys, GFP_ATOMIC);
- if (!ring->dma)
- return -ENOMEM;
-
- for (i = 0; i < rx_dma_size; i++) {
-- dma_addr_t dma_addr = dma_map_single(eth->dev,
-+ dma_addr_t dma_addr = dma_map_single(eth->dma_dev,
- ring->data[i] + NET_SKB_PAD + eth->ip_align,
- ring->buf_size,
- DMA_FROM_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
-+ if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
- return -ENOMEM;
- ring->dma[i].rxd1 = (unsigned int)dma_addr;
-
-@@ -1805,7 +1806,7 @@ static void mtk_rx_clean(struct mtk_eth
- continue;
- if (!ring->dma[i].rxd1)
- continue;
-- dma_unmap_single(eth->dev,
-+ dma_unmap_single(eth->dma_dev,
- ring->dma[i].rxd1,
- ring->buf_size,
- DMA_FROM_DEVICE);
-@@ -1816,7 +1817,7 @@ static void mtk_rx_clean(struct mtk_eth
- }
-
- if (ring->dma) {
-- dma_free_coherent(eth->dev,
-+ dma_free_coherent(eth->dma_dev,
- ring->dma_size * sizeof(*ring->dma),
- ring->dma,
- ring->phys);
-@@ -2175,7 +2176,7 @@ static void mtk_dma_free(struct mtk_eth
- if (eth->netdev[i])
- netdev_reset_queue(eth->netdev[i]);
- if (eth->scratch_ring) {
-- dma_free_coherent(eth->dev,
-+ dma_free_coherent(eth->dma_dev,
- MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
- eth->scratch_ring,
- eth->phy_scratch_ring);
-@@ -2527,6 +2528,8 @@ static void mtk_dim_tx(struct work_struc
-
- static int mtk_hw_init(struct mtk_eth *eth)
- {
-+ u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-+ ETHSYS_DMA_AG_MAP_PPE;
- int i, val, ret;
-
- if (test_and_set_bit(MTK_HW_INIT, &eth->state))
-@@ -2539,6 +2542,10 @@ static int mtk_hw_init(struct mtk_eth *e
- if (ret)
- goto err_disable_pm;
-
-+ if (eth->ethsys)
-+ regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask,
-+ of_dma_is_coherent(eth->dma_dev->of_node) * dma_mask);
-+
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
- ret = device_reset(eth->dev);
- if (ret) {
-@@ -3085,6 +3092,35 @@ free_netdev:
- return err;
- }
-
-+void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
-+{
-+ struct net_device *dev, *tmp;
-+ LIST_HEAD(dev_list);
-+ int i;
-+
-+ rtnl_lock();
-+
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ dev = eth->netdev[i];
-+
-+ if (!dev || !(dev->flags & IFF_UP))
-+ continue;
-+
-+ list_add_tail(&dev->close_list, &dev_list);
-+ }
-+
-+ dev_close_many(&dev_list, false);
-+
-+ eth->dma_dev = dma_dev;
-+
-+ list_for_each_entry_safe(dev, tmp, &dev_list, close_list) {
-+ list_del_init(&dev->close_list);
-+ dev_open(dev, NULL);
-+ }
-+
-+ rtnl_unlock();
-+}
-+
- static int mtk_probe(struct platform_device *pdev)
- {
- struct device_node *mac_np;
-@@ -3098,6 +3134,7 @@ static int mtk_probe(struct platform_dev
- eth->soc = of_device_get_match_data(&pdev->dev);
-
- eth->dev = &pdev->dev;
-+ eth->dma_dev = &pdev->dev;
- eth->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(eth->base))
- return PTR_ERR(eth->base);
-@@ -3146,6 +3183,16 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-+ if (of_dma_is_coherent(pdev->dev.of_node)) {
-+ struct regmap *cci;
-+
-+ cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+ "mediatek,cci-control");
-+ /* enable CPU/bus coherency */
-+ if (!IS_ERR(cci))
-+ regmap_write(cci, 0, 3);
-+ }
-+
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii),
- GFP_KERNEL);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -463,6 +463,12 @@
- #define RSTCTRL_FE BIT(6)
- #define RSTCTRL_PPE BIT(31)
-
-+/* ethernet dma channel agent map */
-+#define ETHSYS_DMA_AG_MAP 0x408
-+#define ETHSYS_DMA_AG_MAP_PDMA BIT(0)
-+#define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
-+#define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-+
- /* SGMII subsystem config registers */
- /* Register to auto-negotiation restart */
- #define SGMSYS_PCS_CONTROL_1 0x0
-@@ -880,6 +886,7 @@ struct mtk_sgmii {
- /* 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
- * @base: The mapped register i/o base
- * @page_lock: Make sure that register operations are atomic
- * @tx_irq__lock: Make sure that IRQ register operations are atomic
-@@ -923,6 +930,7 @@ struct mtk_sgmii {
-
- struct mtk_eth {
- struct device *dev;
-+ struct device *dma_dev;
- void __iomem *base;
- spinlock_t page_lock;
- spinlock_t tx_irq_lock;
-@@ -1021,6 +1029,7 @@ int mtk_gmac_rgmii_path_setup(struct mtk
- int mtk_eth_offload_init(struct mtk_eth *eth);
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
- void *type_data);
-+void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
-
-
- #endif /* MTK_ETH_H */
diff --git a/target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch b/target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch
deleted file mode 100644
index 85dc9ad6fc..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch
+++ /dev/null
@@ -1,1679 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 5 Feb 2022 17:56:08 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for Wireless
- Ethernet Dispatch (WED)
-
-The Wireless Ethernet Dispatch subsystem on the MT7622 SoC can be
-configured to intercept and handle access to the DMA queues and
-PCIe interrupts for a MT7615/MT7915 wireless card.
-It can manage the internal WDMA (Wireless DMA) controller, which allows
-ethernet packets to be passed from the packet switch engine (PSE) to the
-wireless card, bypassing the CPU entirely.
-This can be used to implement hardware flow offloading from ethernet to
-WLAN.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed.h
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ops.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_regs.h
- create mode 100644 include/linux/soc/mediatek/mtk_wed.h
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -7,6 +7,10 @@ config NET_VENDOR_MEDIATEK
-
- if NET_VENDOR_MEDIATEK
-
-+config NET_MEDIATEK_SOC_WED
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ def_bool NET_MEDIATEK_SOC != n
-+
- config NET_MEDIATEK_SOC
- tristate "MediaTek SoC Gigabit Ethernet support"
- depends on NET_DSA || !NET_DSA
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,4 +5,9 @@
-
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
- mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
-+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o
-+ifdef CONFIG_DEBUG_FS
-+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
-+endif
-+obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o
- obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -24,6 +24,7 @@
- #include <net/dsa.h>
-
- #include "mtk_eth_soc.h"
-+#include "mtk_wed.h"
-
- static int mtk_msg_level = -1;
- module_param_named(msg_level, mtk_msg_level, int, 0);
-@@ -3215,6 +3216,22 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-+ for (i = 0;; i++) {
-+ struct device_node *np = of_parse_phandle(pdev->dev.of_node,
-+ "mediatek,wed", i);
-+ static const u32 wdma_regs[] = {
-+ MTK_WDMA0_BASE,
-+ MTK_WDMA1_BASE
-+ };
-+ void __iomem *wdma;
-+
-+ if (!np || i >= ARRAY_SIZE(wdma_regs))
-+ break;
-+
-+ wdma = eth->base + wdma_regs[i];
-+ mtk_wed_add_hw(np, eth, wdma, i);
-+ }
-+
- for (i = 0; i < 3; i++) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
- eth->irq[i] = eth->irq[0];
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -295,6 +295,9 @@
- #define MTK_GDM1_TX_GPCNT 0x2438
- #define MTK_STAT_OFFSET 0x40
-
-+#define MTK_WDMA0_BASE 0x2800
-+#define MTK_WDMA1_BASE 0x2c00
-+
- /* QDMA descriptor txd4 */
- #define TX_DMA_CHKSUM (0x7 << 29)
- #define TX_DMA_TSO BIT(28)
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -0,0 +1,875 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/bitfield.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/skbuff.h>
-+#include <linux/of_platform.h>
-+#include <linux/of_address.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/debugfs.h>
-+#include <linux/soc/mediatek/mtk_wed.h>
-+#include "mtk_eth_soc.h"
-+#include "mtk_wed_regs.h"
-+#include "mtk_wed.h"
-+#include "mtk_ppe.h"
-+
-+#define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
-+
-+#define MTK_WED_PKT_SIZE 1900
-+#define MTK_WED_BUF_SIZE 2048
-+#define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
-+
-+#define MTK_WED_TX_RING_SIZE 2048
-+#define MTK_WED_WDMA_RING_SIZE 1024
-+
-+static struct mtk_wed_hw *hw_list[2];
-+static DEFINE_MUTEX(hw_lock);
-+
-+static void
-+wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
-+{
-+ regmap_update_bits(dev->hw->regs, reg, mask | val, val);
-+}
-+
-+static void
-+wed_set(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ return wed_m32(dev, reg, 0, mask);
-+}
-+
-+static void
-+wed_clr(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ return wed_m32(dev, reg, mask, 0);
-+}
-+
-+static void
-+wdma_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
-+{
-+ wdma_w32(dev, reg, (wdma_r32(dev, reg) & ~mask) | val);
-+}
-+
-+static void
-+wdma_set(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ wdma_m32(dev, reg, 0, mask);
-+}
-+
-+static u32
-+mtk_wed_read_reset(struct mtk_wed_device *dev)
-+{
-+ return wed_r32(dev, MTK_WED_RESET);
-+}
-+
-+static void
-+mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
-+{
-+ u32 status;
-+
-+ wed_w32(dev, MTK_WED_RESET, mask);
-+ if (readx_poll_timeout(mtk_wed_read_reset, dev, status,
-+ !(status & mask), 0, 1000))
-+ WARN_ON_ONCE(1);
-+}
-+
-+static struct mtk_wed_hw *
-+mtk_wed_assign(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_hw *hw;
-+
-+ hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)];
-+ if (!hw || hw->wed_dev)
-+ return NULL;
-+
-+ hw->wed_dev = dev;
-+ return hw;
-+}
-+
-+static int
-+mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wdma_desc *desc;
-+ dma_addr_t desc_phys;
-+ void **page_list;
-+ int token = dev->wlan.token_start;
-+ int ring_size;
-+ int n_pages;
-+ int i, page_idx;
-+
-+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-+ n_pages = ring_size / MTK_WED_BUF_PER_PAGE;
-+
-+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
-+ if (!page_list)
-+ return -ENOMEM;
-+
-+ dev->buf_ring.size = ring_size;
-+ dev->buf_ring.pages = page_list;
-+
-+ desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc)
-+ return -ENOMEM;
-+
-+ dev->buf_ring.desc = desc;
-+ dev->buf_ring.desc_phys = desc_phys;
-+
-+ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
-+ dma_addr_t page_phys, buf_phys;
-+ struct page *page;
-+ void *buf;
-+ int s;
-+
-+ page = __dev_alloc_pages(GFP_KERNEL, 0);
-+ if (!page)
-+ return -ENOMEM;
-+
-+ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ if (dma_mapping_error(dev->hw->dev, page_phys)) {
-+ __free_page(page);
-+ return -ENOMEM;
-+ }
-+
-+ page_list[page_idx++] = page;
-+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+
-+ buf = page_to_virt(page);
-+ buf_phys = page_phys;
-+
-+ for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
-+ u32 txd_size;
-+
-+ txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
-+
-+ desc->buf0 = buf_phys;
-+ desc->buf1 = buf_phys + txd_size;
-+ desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0,
-+ txd_size) |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-+ MTK_WED_BUF_SIZE - txd_size) |
-+ MTK_WDMA_DESC_CTRL_LAST_SEG1;
-+ desc->info = 0;
-+ desc++;
-+
-+ buf += MTK_WED_BUF_SIZE;
-+ buf_phys += MTK_WED_BUF_SIZE;
-+ }
-+
-+ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_free_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wdma_desc *desc = dev->buf_ring.desc;
-+ void **page_list = dev->buf_ring.pages;
-+ int page_idx;
-+ int i;
-+
-+ if (!page_list)
-+ return;
-+
-+ if (!desc)
-+ goto free_pagelist;
-+
-+ for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
-+ void *page = page_list[page_idx++];
-+
-+ if (!page)
-+ break;
-+
-+ dma_unmap_page(dev->hw->dev, desc[i].buf0,
-+ PAGE_SIZE, DMA_BIDIRECTIONAL);
-+ __free_page(page);
-+ }
-+
-+ dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc),
-+ desc, dev->buf_ring.desc_phys);
-+
-+free_pagelist:
-+ kfree(page_list);
-+}
-+
-+static void
-+mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
-+{
-+ if (!ring->desc)
-+ return;
-+
-+ dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc),
-+ ring->desc, ring->desc_phys);
-+}
-+
-+static void
-+mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
-+ mtk_wed_free_ring(dev, &dev->tx_ring[i]);
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-+ mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
-+}
-+
-+static void
-+mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
-+{
-+ u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-+
-+ if (!dev->hw->num_flows)
-+ mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-+
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK, en ? mask : 0);
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK);
-+}
-+
-+static void
-+mtk_wed_stop(struct mtk_wed_device *dev)
-+{
-+ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
-+ mtk_wed_set_ext_int(dev, false);
-+
-+ wed_clr(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WED_TX_BM_EN |
-+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
-+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
-+ wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
-+ wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
-+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-+
-+ wed_clr(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_TX_DMA_EN |
-+ MTK_WED_GLO_CFG_RX_DMA_EN);
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+}
-+
-+static void
-+mtk_wed_detach(struct mtk_wed_device *dev)
-+{
-+ struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node;
-+ struct mtk_wed_hw *hw = dev->hw;
-+
-+ mutex_lock(&hw_lock);
-+
-+ mtk_wed_stop(dev);
-+
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-+
-+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+
-+ mtk_wed_free_buffer(dev);
-+ mtk_wed_free_tx_rings(dev);
-+
-+ if (of_dma_is_coherent(wlan_node))
-+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
-+ BIT(hw->index), BIT(hw->index));
-+
-+ if (!hw_list[!hw->index]->wed_dev &&
-+ hw->eth->dma_dev != hw->eth->dev)
-+ mtk_eth_set_dma_device(hw->eth, hw->eth->dev);
-+
-+ memset(dev, 0, sizeof(*dev));
-+ module_put(THIS_MODULE);
-+
-+ hw->wed_dev = NULL;
-+ mutex_unlock(&hw_lock);
-+}
-+
-+static void
-+mtk_wed_hw_init_early(struct mtk_wed_device *dev)
-+{
-+ u32 mask, set;
-+ u32 offset;
-+
-+ mtk_wed_stop(dev);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+
-+ mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
-+ MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-+ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-+ set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
-+ MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
-+ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
-+ wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-+
-+ wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES);
-+
-+ offset = dev->hw->index ? 0x04000400 : 0;
-+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
-+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset);
-+
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, MTK_PCIE_BASE(dev->hw->index));
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
-+}
-+
-+static void
-+mtk_wed_hw_init(struct mtk_wed_device *dev)
-+{
-+ if (dev->init_done)
-+ return;
-+
-+ dev->init_done = true;
-+ mtk_wed_set_ext_int(dev, false);
-+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-+ dev->buf_ring.size / 128) |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
-+ MTK_WED_TX_RING_SIZE / 256));
-+
-+ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
-+
-+ wed_w32(dev, MTK_WED_TX_BM_TKID,
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-+ dev->wlan.token_start) |
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-+ dev->wlan.token_start + dev->wlan.nbuf - 1));
-+
-+ wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-+
-+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
-+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
-+ MTK_WED_TX_BM_DYN_THR_HI);
-+
-+ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-+
-+ wed_set(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_TX_BM_EN |
-+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+
-+ wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
-+}
-+
-+static void
-+mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size)
-+{
-+ int i;
-+
-+ for (i = 0; i < size; i++) {
-+ desc[i].buf0 = 0;
-+ desc[i].ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ desc[i].buf1 = 0;
-+ desc[i].info = 0;
-+ }
-+}
-+
-+static u32
-+mtk_wed_check_busy(struct mtk_wed_device *dev)
-+{
-+ if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY)
-+ return true;
-+
-+ if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) &
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY)
-+ return true;
-+
-+ if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY)
-+ return true;
-+
-+ if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) &
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
-+ return true;
-+
-+ if (wdma_r32(dev, MTK_WDMA_GLO_CFG) &
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
-+ return true;
-+
-+ if (wed_r32(dev, MTK_WED_CTRL) &
-+ (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY))
-+ return true;
-+
-+ return false;
-+}
-+
-+static int
-+mtk_wed_poll_busy(struct mtk_wed_device *dev)
-+{
-+ int sleep = 15000;
-+ int timeout = 100 * sleep;
-+ u32 val;
-+
-+ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-+ timeout, false, dev);
-+}
-+
-+static void
-+mtk_wed_reset_dma(struct mtk_wed_device *dev)
-+{
-+ bool busy = false;
-+ u32 val;
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) {
-+ struct mtk_wdma_desc *desc = dev->tx_ring[i].desc;
-+
-+ if (!desc)
-+ continue;
-+
-+ mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE);
-+ }
-+
-+ if (mtk_wed_poll_busy(dev))
-+ busy = mtk_wed_check_busy(dev);
-+
-+ if (busy) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
-+ } else {
-+ wed_w32(dev, MTK_WED_RESET_IDX,
-+ MTK_WED_RESET_IDX_TX |
-+ MTK_WED_RESET_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
-+ }
-+
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-+
-+ if (busy) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
-+ } else {
-+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
-+ MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV);
-+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0);
-+
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE);
-+
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE);
-+ }
-+
-+ for (i = 0; i < 100; i++) {
-+ val = wed_r32(dev, MTK_WED_TX_BM_INTF);
-+ if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
-+ break;
-+ }
-+
-+ mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
-+ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-+
-+ if (busy) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV);
-+ } else {
-+ wed_w32(dev, MTK_WED_WPDMA_RESET_IDX,
-+ MTK_WED_WPDMA_RESET_IDX_TX |
-+ MTK_WED_WPDMA_RESET_IDX_RX);
-+ wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
-+ }
-+
-+}
-+
-+static int
-+mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-+ int size)
-+{
-+ ring->desc = dma_alloc_coherent(dev->hw->dev,
-+ size * sizeof(*ring->desc),
-+ &ring->desc_phys, GFP_KERNEL);
-+ if (!ring->desc)
-+ return -ENOMEM;
-+
-+ ring->size = size;
-+ mtk_wed_ring_reset(ring->desc, size);
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+{
-+ struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
-+
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE))
-+ return -ENOMEM;
-+
-+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-+ wdma->desc_phys);
-+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT,
-+ size);
-+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+
-+ wed_w32(dev, MTK_WED_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-+ wdma->desc_phys);
-+ wed_w32(dev, MTK_WED_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT,
-+ size);
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
-+{
-+ u32 wdma_mask;
-+ u32 val;
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-+ if (!dev->tx_wdma[i].desc)
-+ mtk_wed_wdma_ring_setup(dev, i, 16);
-+
-+ wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
-+
-+ mtk_wed_hw_init(dev);
-+
-+ wed_set(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WED_TX_BM_EN |
-+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER,
-+ MTK_WED_WPDMA_INT_TRIGGER_RX_DONE |
-+ MTK_WED_WPDMA_INT_TRIGGER_TX_DONE);
-+
-+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
-+ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-+
-+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
-+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
-+
-+ wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask);
-+ wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
-+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
-+
-+ wed_set(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_TX_DMA_EN |
-+ MTK_WED_GLO_CFG_RX_DMA_EN);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+
-+ mtk_wed_set_ext_int(dev, true);
-+ val = dev->wlan.wpdma_phys |
-+ MTK_PCIE_MIRROR_MAP_EN |
-+ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index);
-+
-+ if (dev->hw->index)
-+ val |= BIT(1);
-+ val |= BIT(0);
-+ regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
-+
-+ dev->running = true;
-+}
-+
-+static int
-+mtk_wed_attach(struct mtk_wed_device *dev)
-+ __releases(RCU)
-+{
-+ struct mtk_wed_hw *hw;
-+ int ret = 0;
-+
-+ RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
-+ "mtk_wed_attach without holding the RCU read lock");
-+
-+ if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 ||
-+ !try_module_get(THIS_MODULE))
-+ ret = -ENODEV;
-+
-+ rcu_read_unlock();
-+
-+ if (ret)
-+ return ret;
-+
-+ mutex_lock(&hw_lock);
-+
-+ hw = mtk_wed_assign(dev);
-+ if (!hw) {
-+ module_put(THIS_MODULE);
-+ ret = -ENODEV;
-+ goto out;
-+ }
-+
-+ dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index);
-+
-+ dev->hw = hw;
-+ dev->dev = hw->dev;
-+ dev->irq = hw->irq;
-+ dev->wdma_idx = hw->index;
-+
-+ if (hw->eth->dma_dev == hw->eth->dev &&
-+ of_dma_is_coherent(hw->eth->dev->of_node))
-+ mtk_eth_set_dma_device(hw->eth, hw->dev);
-+
-+ ret = mtk_wed_buffer_alloc(dev);
-+ if (ret) {
-+ mtk_wed_detach(dev);
-+ goto out;
-+ }
-+
-+ mtk_wed_hw_init_early(dev);
-+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0);
-+
-+out:
-+ mutex_unlock(&hw_lock);
-+
-+ return ret;
-+}
-+
-+static int
-+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->tx_ring[idx];
-+
-+ /*
-+ * Tx ring redirection:
-+ * Instead of configuring the WLAN PDMA TX ring directly, the WLAN
-+ * driver allocated DMA ring gets configured into WED MTK_WED_RING_TX(n)
-+ * registers.
-+ *
-+ * WED driver posts its own DMA ring as WLAN PDMA TX and configures it
-+ * into MTK_WED_WPDMA_RING_TX(n) registers.
-+ * It gets filled with packets picked up from WED TX ring and from
-+ * WDMA RX.
-+ */
-+
-+ BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
-+
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE))
-+ return -ENOMEM;
-+
-+ if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ return -ENOMEM;
-+
-+ ring->reg_base = MTK_WED_RING_TX(idx);
-+ ring->wpdma = regs;
-+
-+ /* WED -> WPDMA */
-+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
-+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_TX_RING_SIZE);
-+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_CPU_IDX, 0);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-+ ring->desc_phys);
-+ wed_w32(dev, MTK_WED_WPDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
-+ MTK_WED_TX_RING_SIZE);
-+ wed_w32(dev, MTK_WED_WPDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->txfree_ring;
-+ int i;
-+
-+ /*
-+ * For txfree event handling, the same DMA ring is shared between WED
-+ * and WLAN. The WLAN driver accesses the ring index registers through
-+ * WED
-+ */
-+ ring->reg_base = MTK_WED_RING_RX(1);
-+ ring->wpdma = regs;
-+
-+ for (i = 0; i < 12; i += 4) {
-+ u32 val = readl(regs + i);
-+
-+ wed_w32(dev, MTK_WED_RING_RX(1) + i, val);
-+ wed_w32(dev, MTK_WED_WPDMA_RING_RX(1) + i, val);
-+ }
-+
-+ return 0;
-+}
-+
-+static u32
-+mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
-+{
-+ u32 val;
-+
-+ val = wed_r32(dev, MTK_WED_EXT_INT_STATUS);
-+ wed_w32(dev, MTK_WED_EXT_INT_STATUS, val);
-+ val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-+ if (!dev->hw->num_flows)
-+ val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-+ if (val && net_ratelimit())
-+ pr_err("mtk_wed%d: error status=%08x\n", dev->hw->index, val);
-+
-+ val = wed_r32(dev, MTK_WED_INT_STATUS);
-+ val &= mask;
-+ wed_w32(dev, MTK_WED_INT_STATUS, val); /* ACK */
-+
-+ return val;
-+}
-+
-+static void
-+mtk_wed_irq_set_mask(struct mtk_wed_device *dev, u32 mask)
-+{
-+ if (!dev->running)
-+ return;
-+
-+ mtk_wed_set_ext_int(dev, !!mask);
-+ wed_w32(dev, MTK_WED_INT_MASK, mask);
-+}
-+
-+int mtk_wed_flow_add(int index)
-+{
-+ struct mtk_wed_hw *hw = hw_list[index];
-+ int ret;
-+
-+ if (!hw || !hw->wed_dev)
-+ return -ENODEV;
-+
-+ if (hw->num_flows) {
-+ hw->num_flows++;
-+ return 0;
-+ }
-+
-+ mutex_lock(&hw_lock);
-+ if (!hw->wed_dev) {
-+ ret = -ENODEV;
-+ goto out;
-+ }
-+
-+ ret = hw->wed_dev->wlan.offload_enable(hw->wed_dev);
-+ if (!ret)
-+ hw->num_flows++;
-+ mtk_wed_set_ext_int(hw->wed_dev, true);
-+
-+out:
-+ mutex_unlock(&hw_lock);
-+
-+ return ret;
-+}
-+
-+void mtk_wed_flow_remove(int index)
-+{
-+ struct mtk_wed_hw *hw = hw_list[index];
-+
-+ if (!hw)
-+ return;
-+
-+ if (--hw->num_flows)
-+ return;
-+
-+ mutex_lock(&hw_lock);
-+ if (!hw->wed_dev)
-+ goto out;
-+
-+ hw->wed_dev->wlan.offload_disable(hw->wed_dev);
-+ mtk_wed_set_ext_int(hw->wed_dev, true);
-+
-+out:
-+ mutex_unlock(&hw_lock);
-+}
-+
-+void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-+ void __iomem *wdma, int index)
-+{
-+ static const struct mtk_wed_ops wed_ops = {
-+ .attach = mtk_wed_attach,
-+ .tx_ring_setup = mtk_wed_tx_ring_setup,
-+ .txfree_ring_setup = mtk_wed_txfree_ring_setup,
-+ .start = mtk_wed_start,
-+ .stop = mtk_wed_stop,
-+ .reset_dma = mtk_wed_reset_dma,
-+ .reg_read = wed_r32,
-+ .reg_write = wed_w32,
-+ .irq_get = mtk_wed_irq_get,
-+ .irq_set_mask = mtk_wed_irq_set_mask,
-+ .detach = mtk_wed_detach,
-+ };
-+ struct device_node *eth_np = eth->dev->of_node;
-+ struct platform_device *pdev;
-+ struct mtk_wed_hw *hw;
-+ struct regmap *regs;
-+ int irq;
-+
-+ if (!np)
-+ return;
-+
-+ pdev = of_find_device_by_node(np);
-+ if (!pdev)
-+ return;
-+
-+ get_device(&pdev->dev);
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0)
-+ return;
-+
-+ regs = syscon_regmap_lookup_by_phandle(np, NULL);
-+ if (!regs)
-+ return;
-+
-+ rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
-+
-+ mutex_lock(&hw_lock);
-+
-+ if (WARN_ON(hw_list[index]))
-+ goto unlock;
-+
-+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
-+ hw->node = np;
-+ hw->regs = regs;
-+ hw->eth = eth;
-+ hw->dev = &pdev->dev;
-+ hw->wdma = wdma;
-+ hw->index = index;
-+ hw->irq = irq;
-+ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
-+ "mediatek,pcie-mirror");
-+ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
-+ "mediatek,hifsys");
-+ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) {
-+ kfree(hw);
-+ goto unlock;
-+ }
-+
-+ if (!index) {
-+ regmap_write(hw->mirror, 0, 0);
-+ regmap_write(hw->mirror, 4, 0);
-+ }
-+ mtk_wed_hw_add_debugfs(hw);
-+
-+ hw_list[index] = hw;
-+
-+unlock:
-+ mutex_unlock(&hw_lock);
-+}
-+
-+void mtk_wed_exit(void)
-+{
-+ int i;
-+
-+ rcu_assign_pointer(mtk_soc_wed_ops, NULL);
-+
-+ synchronize_rcu();
-+
-+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
-+ struct mtk_wed_hw *hw;
-+
-+ hw = hw_list[i];
-+ if (!hw)
-+ continue;
-+
-+ hw_list[i] = NULL;
-+ debugfs_remove(hw->debugfs_dir);
-+ put_device(hw->dev);
-+ kfree(hw);
-+ }
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -0,0 +1,128 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
-+
-+#ifndef __MTK_WED_PRIV_H
-+#define __MTK_WED_PRIV_H
-+
-+#include <linux/soc/mediatek/mtk_wed.h>
-+#include <linux/debugfs.h>
-+#include <linux/regmap.h>
-+
-+struct mtk_eth;
-+
-+struct mtk_wed_hw {
-+ struct device_node *node;
-+ struct mtk_eth *eth;
-+ struct regmap *regs;
-+ struct regmap *hifsys;
-+ struct device *dev;
-+ void __iomem *wdma;
-+ struct regmap *mirror;
-+ struct dentry *debugfs_dir;
-+ struct mtk_wed_device *wed_dev;
-+ u32 debugfs_reg;
-+ u32 num_flows;
-+ char dirname[5];
-+ int irq;
-+ int index;
-+};
-+
-+
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static inline void
-+wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
-+{
-+ regmap_write(dev->hw->regs, reg, val);
-+}
-+
-+static inline u32
-+wed_r32(struct mtk_wed_device *dev, u32 reg)
-+{
-+ unsigned int val;
-+
-+ regmap_read(dev->hw->regs, reg, &val);
-+
-+ return val;
-+}
-+
-+static inline void
-+wdma_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
-+{
-+ writel(val, dev->hw->wdma + reg);
-+}
-+
-+static inline u32
-+wdma_r32(struct mtk_wed_device *dev, u32 reg)
-+{
-+ return readl(dev->hw->wdma + reg);
-+}
-+
-+static inline u32
-+wpdma_tx_r32(struct mtk_wed_device *dev, int ring, u32 reg)
-+{
-+ if (!dev->tx_ring[ring].wpdma)
-+ return 0;
-+
-+ return readl(dev->tx_ring[ring].wpdma + reg);
-+}
-+
-+static inline void
-+wpdma_tx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val)
-+{
-+ if (!dev->tx_ring[ring].wpdma)
-+ return;
-+
-+ writel(val, dev->tx_ring[ring].wpdma + reg);
-+}
-+
-+static inline u32
-+wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg)
-+{
-+ if (!dev->txfree_ring.wpdma)
-+ return 0;
-+
-+ return readl(dev->txfree_ring.wpdma + reg);
-+}
-+
-+static inline void
-+wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
-+{
-+ if (!dev->txfree_ring.wpdma)
-+ return;
-+
-+ writel(val, dev->txfree_ring.wpdma + reg);
-+}
-+
-+void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-+ void __iomem *wdma, int index);
-+void mtk_wed_exit(void);
-+int mtk_wed_flow_add(int index);
-+void mtk_wed_flow_remove(int index);
-+#else
-+static inline void
-+mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-+ void __iomem *wdma, int index)
-+{
-+}
-+static inline void
-+mtk_wed_exit(void)
-+{
-+}
-+static inline int mtk_wed_flow_add(int index)
-+{
-+ return -EINVAL;
-+}
-+static inline void mtk_wed_flow_remove(int index)
-+{
-+}
-+#endif
-+
-+#ifdef CONFIG_DEBUG_FS
-+void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw);
-+#else
-+static inline void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
-+{
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -0,0 +1,175 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
-+
-+#include <linux/seq_file.h>
-+#include "mtk_wed.h"
-+#include "mtk_wed_regs.h"
-+
-+struct reg_dump {
-+ const char *name;
-+ u16 offset;
-+ u8 type;
-+ u8 base;
-+};
-+
-+enum {
-+ DUMP_TYPE_STRING,
-+ DUMP_TYPE_WED,
-+ DUMP_TYPE_WDMA,
-+ DUMP_TYPE_WPDMA_TX,
-+ DUMP_TYPE_WPDMA_TXFREE,
-+};
-+
-+#define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
-+#define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
-+#define DUMP_RING(_prefix, _base, ...) \
-+ { _prefix " BASE", _base, __VA_ARGS__ }, \
-+ { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \
-+ { _prefix " CIDX", _base + 0x8, __VA_ARGS__ }, \
-+ { _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
-+
-+#define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
-+#define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
-+
-+#define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
-+#define DUMP_WDMA_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WDMA)
-+
-+#define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n)
-+#define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE)
-+
-+static void
-+print_reg_val(struct seq_file *s, const char *name, u32 val)
-+{
-+ seq_printf(s, "%-32s %08x\n", name, val);
-+}
-+
-+static void
-+dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
-+ const struct reg_dump *regs, int n_regs)
-+{
-+ const struct reg_dump *cur;
-+ u32 val;
-+
-+ for (cur = regs; cur < &regs[n_regs]; cur++) {
-+ switch (cur->type) {
-+ case DUMP_TYPE_STRING:
-+ seq_printf(s, "%s======== %s:\n",
-+ cur > regs ? "\n" : "",
-+ cur->name);
-+ continue;
-+ case DUMP_TYPE_WED:
-+ val = wed_r32(dev, cur->offset);
-+ break;
-+ case DUMP_TYPE_WDMA:
-+ val = wdma_r32(dev, cur->offset);
-+ break;
-+ case DUMP_TYPE_WPDMA_TX:
-+ val = wpdma_tx_r32(dev, cur->base, cur->offset);
-+ break;
-+ case DUMP_TYPE_WPDMA_TXFREE:
-+ val = wpdma_txfree_r32(dev, cur->offset);
-+ break;
-+ }
-+ print_reg_val(s, cur->name, val);
-+ }
-+}
-+
-+
-+static int
-+wed_txinfo_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("WED TX"),
-+ DUMP_WED(WED_TX_MIB(0)),
-+ DUMP_WED_RING(WED_RING_TX(0)),
-+
-+ DUMP_WED(WED_TX_MIB(1)),
-+ DUMP_WED_RING(WED_RING_TX(1)),
-+
-+ DUMP_STR("WPDMA TX"),
-+ DUMP_WED(WED_WPDMA_TX_MIB(0)),
-+ DUMP_WED_RING(WED_WPDMA_RING_TX(0)),
-+ DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(0)),
-+
-+ DUMP_WED(WED_WPDMA_TX_MIB(1)),
-+ DUMP_WED_RING(WED_WPDMA_RING_TX(1)),
-+ DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(1)),
-+
-+ DUMP_STR("WPDMA TX"),
-+ DUMP_WPDMA_TX_RING(0),
-+ DUMP_WPDMA_TX_RING(1),
-+
-+ DUMP_STR("WED WDMA RX"),
-+ DUMP_WED(WED_WDMA_RX_MIB(0)),
-+ DUMP_WED_RING(WED_WDMA_RING_RX(0)),
-+ DUMP_WED(WED_WDMA_RX_THRES(0)),
-+ DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(0)),
-+ DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(0)),
-+
-+ DUMP_WED(WED_WDMA_RX_MIB(1)),
-+ DUMP_WED_RING(WED_WDMA_RING_RX(1)),
-+ DUMP_WED(WED_WDMA_RX_THRES(1)),
-+ DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(1)),
-+ DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(1)),
-+
-+ DUMP_STR("WDMA RX"),
-+ DUMP_WDMA(WDMA_GLO_CFG),
-+ DUMP_WDMA_RING(WDMA_RING_RX(0)),
-+ DUMP_WDMA_RING(WDMA_RING_RX(1)),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev)
-+ return 0;
-+
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
-+
-+
-+static int
-+mtk_wed_reg_set(void *data, u64 val)
-+{
-+ struct mtk_wed_hw *hw = data;
-+
-+ regmap_write(hw->regs, hw->debugfs_reg, val);
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_reg_get(void *data, u64 *val)
-+{
-+ struct mtk_wed_hw *hw = data;
-+ unsigned int regval;
-+ int ret;
-+
-+ ret = regmap_read(hw->regs, hw->debugfs_reg, &regval);
-+ if (ret)
-+ return ret;
-+
-+ *val = regval;
-+
-+ return 0;
-+}
-+
-+DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set,
-+ "0x%08llx\n");
-+
-+void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
-+{
-+ struct dentry *dir;
-+
-+ snprintf(hw->dirname, sizeof(hw->dirname), "wed%d", hw->index);
-+ dir = debugfs_create_dir(hw->dirname, NULL);
-+ if (!dir)
-+ return;
-+
-+ hw->debugfs_dir = dir;
-+ debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
-+ debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
-+ debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_ops.c
-@@ -0,0 +1,8 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
-+
-+#include <linux/kernel.h>
-+#include <linux/soc/mediatek/mtk_wed.h>
-+
-+const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-+EXPORT_SYMBOL_GPL(mtk_soc_wed_ops);
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -0,0 +1,251 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
-+
-+#ifndef __MTK_WED_REGS_H
-+#define __MTK_WED_REGS_H
-+
-+#define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0)
-+#define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15)
-+#define MTK_WDMA_DESC_CTRL_BURST BIT(16)
-+#define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16)
-+#define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30)
-+#define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
-+
-+struct mtk_wdma_desc {
-+ __le32 buf0;
-+ __le32 ctrl;
-+ __le32 buf1;
-+ __le32 info;
-+} __packed __aligned(4);
-+
-+#define MTK_WED_RESET 0x008
-+#define MTK_WED_RESET_TX_BM BIT(0)
-+#define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
-+#define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
-+#define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
-+#define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11)
-+#define MTK_WED_RESET_WED_TX_DMA BIT(12)
-+#define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
-+#define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
-+#define MTK_WED_RESET_WED BIT(31)
-+
-+#define MTK_WED_CTRL 0x00c
-+#define MTK_WED_CTRL_WPDMA_INT_AGENT_EN BIT(0)
-+#define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1)
-+#define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2)
-+#define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
-+#define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
-+#define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
-+#define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
-+#define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11)
-+#define MTK_WED_CTRL_RESERVE_EN BIT(12)
-+#define MTK_WED_CTRL_RESERVE_BUSY BIT(13)
-+#define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
-+#define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
-+
-+#define MTK_WED_EXT_INT_STATUS 0x020
-+#define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0)
-+#define MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD BIT(1)
-+#define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4)
-+#define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8)
-+#define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9)
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12)
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN BIT(19)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_BM_DMAD_COHERENT BIT(20)
-+#define MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR BIT(21)
-+#define MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR BIT(22)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24)
-+#define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
-+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
-+ MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
-+ MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \
-+ MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \
-+ MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \
-+ MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR | \
-+ MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR)
-+
-+#define MTK_WED_EXT_INT_MASK 0x028
-+
-+#define MTK_WED_STATUS 0x060
-+#define MTK_WED_STATUS_TX GENMASK(15, 8)
-+
-+#define MTK_WED_TX_BM_CTRL 0x080
-+#define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
-+#define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-+#define MTK_WED_TX_BM_CTRL_PAUSE BIT(28)
-+
-+#define MTK_WED_TX_BM_BASE 0x084
-+
-+#define MTK_WED_TX_BM_TKID 0x088
-+#define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
-+#define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-+
-+#define MTK_WED_TX_BM_BUF_LEN 0x08c
-+
-+#define MTK_WED_TX_BM_INTF 0x09c
-+#define MTK_WED_TX_BM_INTF_TKID GENMASK(15, 0)
-+#define MTK_WED_TX_BM_INTF_TKFIFO_FDEP GENMASK(23, 16)
-+#define MTK_WED_TX_BM_INTF_TKID_VALID BIT(28)
-+#define MTK_WED_TX_BM_INTF_TKID_READ BIT(29)
-+
-+#define MTK_WED_TX_BM_DYN_THR 0x0a0
-+#define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0)
-+#define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16)
-+
-+#define MTK_WED_INT_STATUS 0x200
-+#define MTK_WED_INT_MASK 0x204
-+
-+#define MTK_WED_GLO_CFG 0x208
-+#define MTK_WED_GLO_CFG_TX_DMA_EN BIT(0)
-+#define MTK_WED_GLO_CFG_TX_DMA_BUSY BIT(1)
-+#define MTK_WED_GLO_CFG_RX_DMA_EN BIT(2)
-+#define MTK_WED_GLO_CFG_RX_DMA_BUSY BIT(3)
-+#define MTK_WED_GLO_CFG_RX_BT_SIZE GENMASK(5, 4)
-+#define MTK_WED_GLO_CFG_TX_WB_DDONE BIT(6)
-+#define MTK_WED_GLO_CFG_BIG_ENDIAN BIT(7)
-+#define MTK_WED_GLO_CFG_DIS_BT_SIZE_ALIGN BIT(8)
-+#define MTK_WED_GLO_CFG_TX_BT_SIZE_LO BIT(9)
-+#define MTK_WED_GLO_CFG_MULTI_DMA_EN GENMASK(11, 10)
-+#define MTK_WED_GLO_CFG_FIFO_LITTLE_ENDIAN BIT(12)
-+#define MTK_WED_GLO_CFG_MI_DEPTH_RD GENMASK(21, 13)
-+#define MTK_WED_GLO_CFG_TX_BT_SIZE_HI GENMASK(23, 22)
-+#define MTK_WED_GLO_CFG_SW_RESET BIT(24)
-+#define MTK_WED_GLO_CFG_FIRST_TOKEN_ONLY BIT(26)
-+#define MTK_WED_GLO_CFG_OMIT_RX_INFO BIT(27)
-+#define MTK_WED_GLO_CFG_OMIT_TX_INFO BIT(28)
-+#define MTK_WED_GLO_CFG_BYTE_SWAP BIT(29)
-+#define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31)
-+
-+#define MTK_WED_RESET_IDX 0x20c
-+#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
-+#define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
-+
-+#define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
-+
-+#define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10)
-+
-+#define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10)
-+
-+#define MTK_WED_WPDMA_INT_TRIGGER 0x504
-+#define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
-+#define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
-+
-+#define MTK_WED_WPDMA_GLO_CFG 0x508
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN BIT(0)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY BIT(1)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN BIT(2)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY BIT(3)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_BT_SIZE GENMASK(5, 4)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_WB_DDONE BIT(6)
-+#define MTK_WED_WPDMA_GLO_CFG_BIG_ENDIAN BIT(7)
-+#define MTK_WED_WPDMA_GLO_CFG_DIS_BT_SIZE_ALIGN BIT(8)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_BT_SIZE_LO BIT(9)
-+#define MTK_WED_WPDMA_GLO_CFG_MULTI_DMA_EN GENMASK(11, 10)
-+#define MTK_WED_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN BIT(12)
-+#define MTK_WED_WPDMA_GLO_CFG_MI_DEPTH_RD GENMASK(21, 13)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_BT_SIZE_HI GENMASK(23, 22)
-+#define MTK_WED_WPDMA_GLO_CFG_SW_RESET BIT(24)
-+#define MTK_WED_WPDMA_GLO_CFG_FIRST_TOKEN_ONLY BIT(26)
-+#define MTK_WED_WPDMA_GLO_CFG_OMIT_RX_INFO BIT(27)
-+#define MTK_WED_WPDMA_GLO_CFG_OMIT_TX_INFO BIT(28)
-+#define MTK_WED_WPDMA_GLO_CFG_BYTE_SWAP BIT(29)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31)
-+
-+#define MTK_WED_WPDMA_RESET_IDX 0x50c
-+#define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0)
-+#define MTK_WED_WPDMA_RESET_IDX_RX GENMASK(17, 16)
-+
-+#define MTK_WED_WPDMA_INT_CTRL 0x520
-+#define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21)
-+
-+#define MTK_WED_WPDMA_INT_MASK 0x524
-+
-+#define MTK_WED_PCIE_CFG_BASE 0x560
-+
-+#define MTK_WED_PCIE_INT_TRIGGER 0x570
-+#define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16)
-+
-+#define MTK_WED_WPDMA_CFG_BASE 0x580
-+
-+#define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4)
-+#define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4)
-+
-+#define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10)
-+#define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10)
-+#define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
-+#define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
-+
-+#define MTK_WED_WDMA_GLO_CFG 0xa04
-+#define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
-+#define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2)
-+#define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3)
-+#define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4)
-+#define MTK_WED_WDMA_GLO_CFG_TX_WB_DDONE BIT(6)
-+#define MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE BIT(13)
-+#define MTK_WED_WDMA_GLO_CFG_WCOMPLETE_SEL BIT(16)
-+#define MTK_WED_WDMA_GLO_CFG_INIT_PHASE_RXDMA_BYPASS BIT(17)
-+#define MTK_WED_WDMA_GLO_CFG_INIT_PHASE_BYPASS BIT(18)
-+#define MTK_WED_WDMA_GLO_CFG_FSM_RETURN_IDLE BIT(19)
-+#define MTK_WED_WDMA_GLO_CFG_WAIT_COHERENT BIT(20)
-+#define MTK_WED_WDMA_GLO_CFG_AXI_W_AFTER_AW BIT(21)
-+#define MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY_SINGLE_W BIT(22)
-+#define MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY BIT(23)
-+#define MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP BIT(24)
-+#define MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE BIT(25)
-+#define MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE BIT(26)
-+#define MTK_WED_WDMA_GLO_CFG_RXDRV_CLKGATE_BYPASS BIT(30)
-+
-+#define MTK_WED_WDMA_RESET_IDX 0xa08
-+#define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
-+#define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
-+
-+#define MTK_WED_WDMA_INT_TRIGGER 0xa28
-+#define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16)
-+
-+#define MTK_WED_WDMA_INT_CTRL 0xa2c
-+#define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16)
-+
-+#define MTK_WED_WDMA_OFFSET0 0xaa4
-+#define MTK_WED_WDMA_OFFSET1 0xaa8
-+
-+#define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4)
-+#define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4)
-+#define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4)
-+
-+#define MTK_WED_RING_OFS_BASE 0x00
-+#define MTK_WED_RING_OFS_COUNT 0x04
-+#define MTK_WED_RING_OFS_CPU_IDX 0x08
-+#define MTK_WED_RING_OFS_DMA_IDX 0x0c
-+
-+#define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10)
-+
-+#define MTK_WDMA_GLO_CFG 0x204
-+#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES GENMASK(28, 26)
-+
-+#define MTK_WDMA_RESET_IDX 0x208
-+#define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0)
-+#define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16)
-+
-+#define MTK_WDMA_INT_MASK 0x228
-+#define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0)
-+#define MTK_WDMA_INT_MASK_RX_DONE GENMASK(17, 16)
-+#define MTK_WDMA_INT_MASK_TX_DELAY BIT(28)
-+#define MTK_WDMA_INT_MASK_TX_COHERENT BIT(29)
-+#define MTK_WDMA_INT_MASK_RX_DELAY BIT(30)
-+#define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31)
-+
-+#define MTK_WDMA_INT_GRP1 0x250
-+#define MTK_WDMA_INT_GRP2 0x254
-+
-+#define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
-+#define MTK_PCIE_MIRROR_MAP_EN BIT(0)
-+#define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
-+
-+/* DMA channel mapping */
-+#define HIFSYS_DMA_AG_MAP 0x008
-+
-+#endif
---- /dev/null
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -0,0 +1,131 @@
-+#ifndef __MTK_WED_H
-+#define __MTK_WED_H
-+
-+#include <linux/kernel.h>
-+#include <linux/rcupdate.h>
-+#include <linux/regmap.h>
-+#include <linux/pci.h>
-+
-+#define MTK_WED_TX_QUEUES 2
-+
-+struct mtk_wed_hw;
-+struct mtk_wdma_desc;
-+
-+struct mtk_wed_ring {
-+ struct mtk_wdma_desc *desc;
-+ dma_addr_t desc_phys;
-+ int size;
-+
-+ u32 reg_base;
-+ void __iomem *wpdma;
-+};
-+
-+struct mtk_wed_device {
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ const struct mtk_wed_ops *ops;
-+ struct device *dev;
-+ struct mtk_wed_hw *hw;
-+ bool init_done, running;
-+ int wdma_idx;
-+ int irq;
-+
-+ struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
-+ struct mtk_wed_ring txfree_ring;
-+ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
-+
-+ struct {
-+ int size;
-+ void **pages;
-+ struct mtk_wdma_desc *desc;
-+ dma_addr_t desc_phys;
-+ } buf_ring;
-+
-+ /* filled by driver: */
-+ struct {
-+ struct pci_dev *pci_dev;
-+
-+ u32 wpdma_phys;
-+
-+ u16 token_start;
-+ unsigned int nbuf;
-+
-+ u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
-+ int (*offload_enable)(struct mtk_wed_device *wed);
-+ void (*offload_disable)(struct mtk_wed_device *wed);
-+ } wlan;
-+#endif
-+};
-+
-+struct mtk_wed_ops {
-+ int (*attach)(struct mtk_wed_device *dev);
-+ int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
-+ int (*txfree_ring_setup)(struct mtk_wed_device *dev,
-+ void __iomem *regs);
-+ void (*detach)(struct mtk_wed_device *dev);
-+
-+ void (*stop)(struct mtk_wed_device *dev);
-+ void (*start)(struct mtk_wed_device *dev, u32 irq_mask);
-+ void (*reset_dma)(struct mtk_wed_device *dev);
-+
-+ u32 (*reg_read)(struct mtk_wed_device *dev, u32 reg);
-+ void (*reg_write)(struct mtk_wed_device *dev, u32 reg, u32 val);
-+
-+ u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
-+ void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
-+};
-+
-+extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-+
-+static inline int
-+mtk_wed_device_attach(struct mtk_wed_device *dev)
-+{
-+ int ret = -ENODEV;
-+
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ rcu_read_lock();
-+ dev->ops = rcu_dereference(mtk_soc_wed_ops);
-+ if (dev->ops)
-+ ret = dev->ops->attach(dev);
-+ else
-+ rcu_read_unlock();
-+
-+ if (ret)
-+ dev->ops = NULL;
-+#endif
-+
-+ return ret;
-+}
-+
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+#define mtk_wed_device_active(_dev) !!(_dev)->ops
-+#define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
-+#define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
-+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
-+ (_dev)->ops->txfree_ring_setup(_dev, _regs)
-+#define mtk_wed_device_reg_read(_dev, _reg) \
-+ (_dev)->ops->reg_read(_dev, _reg)
-+#define mtk_wed_device_reg_write(_dev, _reg, _val) \
-+ (_dev)->ops->reg_write(_dev, _reg, _val)
-+#define mtk_wed_device_irq_get(_dev, _mask) \
-+ (_dev)->ops->irq_get(_dev, _mask)
-+#define mtk_wed_device_irq_set_mask(_dev, _mask) \
-+ (_dev)->ops->irq_set_mask(_dev, _mask)
-+#else
-+static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
-+{
-+ return false;
-+}
-+#define mtk_wed_device_detach(_dev) do {} while (0)
-+#define mtk_wed_device_start(_dev, _mask) do {} while (0)
-+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_reg_read(_dev, _reg) 0
-+#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
-+#define mtk_wed_device_irq_get(_dev, _mask) 0
-+#define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
-+#endif
-+
-+#endif
diff --git a/target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch b/target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch
deleted file mode 100644
index 69113c2ffa..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch
+++ /dev/null
@@ -1,269 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 5 Feb 2022 18:29:22 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: implement flow offloading
- to WED devices
-
-This allows hardware flow offloading from Ethernet to WLAN on MT7622 SoC
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -329,6 +329,24 @@ int mtk_foe_entry_set_pppoe(struct mtk_f
- return 0;
- }
-
-+int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
-+ int bss, int wcid)
-+{
-+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
-+ u32 *ib2 = mtk_foe_entry_ib2(entry);
-+
-+ *ib2 &= ~MTK_FOE_IB2_PORT_MG;
-+ *ib2 |= MTK_FOE_IB2_WDMA_WINFO;
-+ if (wdma_idx)
-+ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX;
-+
-+ l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
-+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
-+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
-+
-+ return 0;
-+}
-+
- static inline bool mtk_foe_entry_usable(struct mtk_foe_entry *entry)
- {
- return !(entry->ib1 & MTK_FOE_IB1_STATIC) &&
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -48,9 +48,9 @@ enum {
- #define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5)
- #define MTK_FOE_IB2_MULTICAST BIT(8)
-
--#define MTK_FOE_IB2_WHNAT_QID2 GENMASK(13, 12)
--#define MTK_FOE_IB2_WHNAT_DEVIDX BIT(16)
--#define MTK_FOE_IB2_WHNAT_NAT BIT(17)
-+#define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12)
-+#define MTK_FOE_IB2_WDMA_DEVIDX BIT(16)
-+#define MTK_FOE_IB2_WDMA_WINFO BIT(17)
-
- #define MTK_FOE_IB2_PORT_MG GENMASK(17, 12)
-
-@@ -58,9 +58,9 @@ enum {
-
- #define MTK_FOE_IB2_DSCP GENMASK(31, 24)
-
--#define MTK_FOE_VLAN2_WHNAT_BSS GEMMASK(5, 0)
--#define MTK_FOE_VLAN2_WHNAT_WCID GENMASK(13, 6)
--#define MTK_FOE_VLAN2_WHNAT_RING GENMASK(15, 14)
-+#define MTK_FOE_VLAN2_WINFO_BSS GENMASK(5, 0)
-+#define MTK_FOE_VLAN2_WINFO_WCID GENMASK(13, 6)
-+#define MTK_FOE_VLAN2_WINFO_RING GENMASK(15, 14)
-
- enum {
- MTK_FOE_STATE_INVALID,
-@@ -281,6 +281,8 @@ int mtk_foe_entry_set_ipv6_tuple(struct
- int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port);
- int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
- int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
-+int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
-+ int bss, int wcid);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
- u16 timestamp);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -10,6 +10,7 @@
- #include <net/pkt_cls.h>
- #include <net/dsa.h>
- #include "mtk_eth_soc.h"
-+#include "mtk_wed.h"
-
- struct mtk_flow_data {
- struct ethhdr eth;
-@@ -39,6 +40,7 @@ struct mtk_flow_entry {
- struct rhash_head node;
- unsigned long cookie;
- u16 hash;
-+ s8 wed_index;
- };
-
- static const struct rhashtable_params mtk_flow_ht_params = {
-@@ -80,6 +82,35 @@ mtk_flow_offload_mangle_eth(const struct
- memcpy(dest, src, act->mangle.mask ? 2 : 4);
- }
-
-+static int
-+mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_info *info)
-+{
-+ struct net_device_path_ctx ctx = {
-+ .dev = dev,
-+ .daddr = addr,
-+ };
-+ struct net_device_path path = {};
-+
-+ if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED))
-+ return -1;
-+
-+ if (!dev->netdev_ops->ndo_fill_forward_path)
-+ return -1;
-+
-+ if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path))
-+ return -1;
-+
-+ if (path.type != DEV_PATH_MTK_WDMA)
-+ return -1;
-+
-+ info->wdma_idx = path.mtk_wdma.wdma_idx;
-+ info->queue = path.mtk_wdma.queue;
-+ info->bss = path.mtk_wdma.bss;
-+ info->wcid = path.mtk_wdma.wcid;
-+
-+ return 0;
-+}
-+
-
- static int
- mtk_flow_mangle_ports(const struct flow_action_entry *act,
-@@ -149,10 +180,20 @@ mtk_flow_get_dsa_port(struct net_device
-
- static int
- mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
-- struct net_device *dev)
-+ struct net_device *dev, const u8 *dest_mac,
-+ int *wed_index)
- {
-+ struct mtk_wdma_info info = {};
- int pse_port, dsa_port;
-
-+ if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
-+ mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss,
-+ info.wcid);
-+ pse_port = 3;
-+ *wed_index = info.wdma_idx;
-+ goto out;
-+ }
-+
- dsa_port = mtk_flow_get_dsa_port(&dev);
- if (dsa_port >= 0)
- mtk_foe_entry_set_dsa(foe, dsa_port);
-@@ -164,6 +205,7 @@ mtk_flow_set_output_device(struct mtk_et
- else
- return -EOPNOTSUPP;
-
-+out:
- mtk_foe_entry_set_pse_port(foe, pse_port);
-
- return 0;
-@@ -179,6 +221,7 @@ mtk_flow_offload_replace(struct mtk_eth
- struct net_device *odev = NULL;
- struct mtk_flow_entry *entry;
- int offload_type = 0;
-+ int wed_index = -1;
- u16 addr_type = 0;
- u32 timestamp;
- u8 l4proto = 0;
-@@ -326,10 +369,14 @@ mtk_flow_offload_replace(struct mtk_eth
- if (data.pppoe.num == 1)
- mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid);
-
-- err = mtk_flow_set_output_device(eth, &foe, odev);
-+ err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest,
-+ &wed_index);
- if (err)
- return err;
-
-+ if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
-+ return err;
-+
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return -ENOMEM;
-@@ -343,6 +390,7 @@ mtk_flow_offload_replace(struct mtk_eth
- }
-
- entry->hash = hash;
-+ entry->wed_index = wed_index;
- err = rhashtable_insert_fast(&eth->flow_table, &entry->node,
- mtk_flow_ht_params);
- if (err < 0)
-@@ -353,6 +401,8 @@ clear_flow:
- mtk_foe_entry_clear(&eth->ppe, hash);
- free:
- kfree(entry);
-+ if (wed_index >= 0)
-+ mtk_wed_flow_remove(wed_index);
- return err;
- }
-
-@@ -369,6 +419,8 @@ mtk_flow_offload_destroy(struct mtk_eth
- mtk_foe_entry_clear(&eth->ppe, entry->hash);
- rhashtable_remove_fast(&eth->flow_table, &entry->node,
- mtk_flow_ht_params);
-+ if (entry->wed_index >= 0)
-+ mtk_wed_flow_remove(entry->wed_index);
- kfree(entry);
-
- return 0;
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -7,6 +7,7 @@
- #include <linux/soc/mediatek/mtk_wed.h>
- #include <linux/debugfs.h>
- #include <linux/regmap.h>
-+#include <linux/netdevice.h>
-
- struct mtk_eth;
-
-@@ -27,6 +28,12 @@ struct mtk_wed_hw {
- int index;
- };
-
-+struct mtk_wdma_info {
-+ u8 wdma_idx;
-+ u8 queue;
-+ u16 wcid;
-+ u8 bss;
-+};
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- static inline void
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -875,6 +875,7 @@ enum net_device_path_type {
- DEV_PATH_BRIDGE,
- DEV_PATH_PPPOE,
- DEV_PATH_DSA,
-+ DEV_PATH_MTK_WDMA,
- };
-
- struct net_device_path {
-@@ -900,6 +901,12 @@ struct net_device_path {
- int port;
- u16 proto;
- } dsa;
-+ struct {
-+ u8 wdma_idx;
-+ u8 queue;
-+ u16 wcid;
-+ u8 bss;
-+ } mtk_wdma;
- };
- };
-
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -769,6 +769,10 @@ int dev_fill_forward_path(const struct n
- if (WARN_ON_ONCE(last_dev == ctx.dev))
- return -1;
- }
-+
-+ if (!ctx.dev)
-+ return ret;
-+
- path = dev_fwd_path(stack);
- if (!path)
- return -1;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch b/target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch
deleted file mode 100644
index 9adb067015..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From: David Bentham <db260179@gmail.com>
-Date: Mon, 21 Feb 2022 15:36:16 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add ipv6 flow offload
- support
-
-Add the missing IPv6 flow offloading support for routing only.
-Hardware flow offloading is done by the packet processing engine (PPE)
-of the Ethernet MAC and as it doesn't support mangling of IPv6 packets,
-IPv6 NAT cannot be supported.
-
-Signed-off-by: David Bentham <db260179@gmail.com>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -6,6 +6,7 @@
- #include <linux/if_ether.h>
- #include <linux/rhashtable.h>
- #include <linux/ip.h>
-+#include <linux/ipv6.h>
- #include <net/flow_offload.h>
- #include <net/pkt_cls.h>
- #include <net/dsa.h>
-@@ -20,6 +21,11 @@ struct mtk_flow_data {
- __be32 src_addr;
- __be32 dst_addr;
- } v4;
-+
-+ struct {
-+ struct in6_addr src_addr;
-+ struct in6_addr dst_addr;
-+ } v6;
- };
-
- __be16 src_port;
-@@ -65,6 +71,14 @@ mtk_flow_set_ipv4_addr(struct mtk_foe_en
- data->v4.dst_addr, data->dst_port);
- }
-
-+static int
-+mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data)
-+{
-+ return mtk_foe_entry_set_ipv6_tuple(foe,
-+ data->v6.src_addr.s6_addr32, data->src_port,
-+ data->v6.dst_addr.s6_addr32, data->dst_port);
-+}
-+
- static void
- mtk_flow_offload_mangle_eth(const struct flow_action_entry *act, void *eth)
- {
-@@ -296,6 +310,9 @@ mtk_flow_offload_replace(struct mtk_eth
- case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
- offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT;
- break;
-+ case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
-+ offload_type = MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T;
-+ break;
- default:
- return -EOPNOTSUPP;
- }
-@@ -331,6 +348,17 @@ mtk_flow_offload_replace(struct mtk_eth
- mtk_flow_set_ipv4_addr(&foe, &data, false);
- }
-
-+ if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
-+ struct flow_match_ipv6_addrs addrs;
-+
-+ flow_rule_match_ipv6_addrs(rule, &addrs);
-+
-+ data.v6.src_addr = addrs.key->src;
-+ data.v6.dst_addr = addrs.key->dst;
-+
-+ mtk_flow_set_ipv6_addr(&foe, &data);
-+ }
-+
- flow_action_for_each(i, act, &rule->action) {
- if (act->id != FLOW_ACTION_MANGLE)
- continue;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch b/target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch
deleted file mode 100644
index 1950d81ebb..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 21 Feb 2022 15:37:21 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: support TC_SETUP_BLOCK for
- PPE offload
-
-This allows offload entries to be created from user space
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -564,10 +564,13 @@ mtk_eth_setup_tc_block(struct net_device
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
- void *type_data)
- {
-- if (type == TC_SETUP_FT)
-+ switch (type) {
-+ case TC_SETUP_BLOCK:
-+ case TC_SETUP_FT:
- return mtk_eth_setup_tc_block(dev, type_data);
--
-- return -EOPNOTSUPP;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
- }
-
- int mtk_eth_offload_init(struct mtk_eth *eth)
diff --git a/target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch b/target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch
deleted file mode 100644
index 488a79924f..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch
+++ /dev/null
@@ -1,159 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 21 Feb 2022 15:38:20 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: allocate struct mtk_ppe
- separately
-
-Preparation for adding more data to it, which will increase its size.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2348,7 +2348,7 @@ static int mtk_open(struct net_device *d
- return err;
- }
-
-- if (eth->soc->offload_version && mtk_ppe_start(&eth->ppe) == 0)
-+ if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
- gdm_config = MTK_GDMA_TO_PPE;
-
- mtk_gdm_config(eth, gdm_config);
-@@ -2422,7 +2422,7 @@ static int mtk_stop(struct net_device *d
- mtk_dma_free(eth);
-
- if (eth->soc->offload_version)
-- mtk_ppe_stop(&eth->ppe);
-+ mtk_ppe_stop(eth->ppe);
-
- return 0;
- }
-@@ -3307,10 +3307,11 @@ static int mtk_probe(struct platform_dev
- }
-
- if (eth->soc->offload_version) {
-- err = mtk_ppe_init(&eth->ppe, eth->dev,
-- eth->base + MTK_ETH_PPE_BASE, 2);
-- if (err)
-+ eth->ppe = mtk_ppe_init(eth->dev, eth->base + MTK_ETH_PPE_BASE, 2);
-+ if (!eth->ppe) {
-+ err = -ENOMEM;
- goto err_free_dev;
-+ }
-
- err = mtk_eth_offload_init(eth);
- if (err)
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -983,7 +983,7 @@ struct mtk_eth {
- u32 rx_dma_l4_valid;
- int ip_align;
-
-- struct mtk_ppe ppe;
-+ struct mtk_ppe *ppe;
- struct rhashtable flow_table;
- };
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -384,10 +384,15 @@ int mtk_foe_entry_commit(struct mtk_ppe
- return hash;
- }
-
--int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
-+struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base,
- int version)
- {
- struct mtk_foe_entry *foe;
-+ struct mtk_ppe *ppe;
-+
-+ ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL);
-+ if (!ppe)
-+ return NULL;
-
- /* need to allocate a separate device, since it PPE DMA access is
- * not coherent.
-@@ -399,13 +404,13 @@ int mtk_ppe_init(struct mtk_ppe *ppe, st
- foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
- &ppe->foe_phys, GFP_KERNEL);
- if (!foe)
-- return -ENOMEM;
-+ return NULL;
-
- ppe->foe_table = foe;
-
- mtk_ppe_debugfs_init(ppe);
-
-- return 0;
-+ return ppe;
- }
-
- static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -246,8 +246,7 @@ struct mtk_ppe {
- void *acct_table;
- };
-
--int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
-- int version);
-+struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base, int version);
- int mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -411,7 +411,7 @@ mtk_flow_offload_replace(struct mtk_eth
-
- entry->cookie = f->cookie;
- timestamp = mtk_eth_timestamp(eth);
-- hash = mtk_foe_entry_commit(&eth->ppe, &foe, timestamp);
-+ hash = mtk_foe_entry_commit(eth->ppe, &foe, timestamp);
- if (hash < 0) {
- err = hash;
- goto free;
-@@ -426,7 +426,7 @@ mtk_flow_offload_replace(struct mtk_eth
-
- return 0;
- clear_flow:
-- mtk_foe_entry_clear(&eth->ppe, hash);
-+ mtk_foe_entry_clear(eth->ppe, hash);
- free:
- kfree(entry);
- if (wed_index >= 0)
-@@ -444,7 +444,7 @@ mtk_flow_offload_destroy(struct mtk_eth
- if (!entry)
- return -ENOENT;
-
-- mtk_foe_entry_clear(&eth->ppe, entry->hash);
-+ mtk_foe_entry_clear(eth->ppe, entry->hash);
- rhashtable_remove_fast(&eth->flow_table, &entry->node,
- mtk_flow_ht_params);
- if (entry->wed_index >= 0)
-@@ -466,7 +466,7 @@ mtk_flow_offload_stats(struct mtk_eth *e
- if (!entry)
- return -ENOENT;
-
-- timestamp = mtk_foe_entry_timestamp(&eth->ppe, entry->hash);
-+ timestamp = mtk_foe_entry_timestamp(eth->ppe, entry->hash);
- if (timestamp < 0)
- return -ETIMEDOUT;
-
-@@ -522,7 +522,7 @@ mtk_eth_setup_tc_block(struct net_device
- struct flow_block_cb *block_cb;
- flow_setup_cb_t *cb;
-
-- if (!eth->ppe.foe_table)
-+ if (!eth->ppe || !eth->ppe->foe_table)
- return -EOPNOTSUPP;
-
- if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
-@@ -575,7 +575,7 @@ int mtk_eth_setup_tc(struct net_device *
-
- int mtk_eth_offload_init(struct mtk_eth *eth)
- {
-- if (!eth->ppe.foe_table)
-+ if (!eth->ppe || !eth->ppe->foe_table)
- return 0;
-
- return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
diff --git a/target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch b/target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch
deleted file mode 100644
index 182c6afb78..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch
+++ /dev/null
@@ -1,424 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 21 Feb 2022 15:39:18 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rework hardware flow table
- management
-
-The hardware was designed to handle flow detection and creation of flow entries
-by itself, relying on the software primarily for filling in egress routing
-information.
-When there is a hash collision between multiple flows, this allows the hardware
-to maintain the entry for the most active flow.
-Additionally, the hardware only keeps offloading active for entries with at
-least 30 packets per second.
-
-With this rework, the code no longer creates a hardware entries directly.
-Instead, the hardware entry is only created when the PPE reports a matching
-unbound flow with the minimum target rate.
-In order to reduce CPU overhead, looking for flows belonging to a hash entry
-is rate limited to once every 100ms.
-
-This rework is also used as preparation for emulating bridge offload by
-managing L4 offload entries on demand.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -21,6 +21,7 @@
- #include <linux/pinctrl/devinfo.h>
- #include <linux/phylink.h>
- #include <linux/jhash.h>
-+#include <linux/bitfield.h>
- #include <net/dsa.h>
-
- #include "mtk_eth_soc.h"
-@@ -1303,7 +1304,7 @@ static int mtk_poll_rx(struct napi_struc
- struct net_device *netdev;
- unsigned int pktlen;
- dma_addr_t dma_addr;
-- u32 hash;
-+ u32 hash, reason;
- int mac;
-
- ring = mtk_get_rx_ring(eth);
-@@ -1382,6 +1383,11 @@ static int mtk_poll_rx(struct napi_struc
- skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
- }
-
-+ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
-+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-+ mtk_ppe_check_skb(eth->ppe, skb,
-+ trxd.rxd4 & MTK_RXD4_FOE_ENTRY);
-+
- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
- (trxd.rxd2 & RX_DMA_VTAG))
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-@@ -3307,7 +3313,7 @@ static int mtk_probe(struct platform_dev
- }
-
- if (eth->soc->offload_version) {
-- eth->ppe = mtk_ppe_init(eth->dev, eth->base + MTK_ETH_PPE_BASE, 2);
-+ eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
- if (!eth->ppe) {
- err = -ENOMEM;
- goto err_free_dev;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -6,9 +6,12 @@
- #include <linux/iopoll.h>
- #include <linux/etherdevice.h>
- #include <linux/platform_device.h>
-+#include "mtk_eth_soc.h"
- #include "mtk_ppe.h"
- #include "mtk_ppe_regs.h"
-
-+static DEFINE_SPINLOCK(ppe_lock);
-+
- static void ppe_w32(struct mtk_ppe *ppe, u32 reg, u32 val)
- {
- writel(val, ppe->base + reg);
-@@ -41,6 +44,11 @@ static u32 ppe_clear(struct mtk_ppe *ppe
- return ppe_m32(ppe, reg, val, 0);
- }
-
-+static u32 mtk_eth_timestamp(struct mtk_eth *eth)
-+{
-+ return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP;
-+}
-+
- static int mtk_ppe_wait_busy(struct mtk_ppe *ppe)
- {
- int ret;
-@@ -353,26 +361,59 @@ static inline bool mtk_foe_entry_usable(
- FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND;
- }
-
--int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
-- u16 timestamp)
-+static bool
-+mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data)
-+{
-+ int type, len;
-+
-+ if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP)
-+ return false;
-+
-+ type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1);
-+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE)
-+ len = offsetof(struct mtk_foe_entry, ipv6._rsv);
-+ else
-+ len = offsetof(struct mtk_foe_entry, ipv4.ib2);
-+
-+ return !memcmp(&entry->data.data, &data->data, len - 4);
-+}
-+
-+static void
-+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- struct mtk_foe_entry *hwe;
-- u32 hash;
-+ struct mtk_foe_entry foe;
-
-+ spin_lock_bh(&ppe_lock);
-+ if (entry->hash == 0xffff)
-+ goto out;
-+
-+ hwe = &ppe->foe_table[entry->hash];
-+ memcpy(&foe, hwe, sizeof(foe));
-+ if (!mtk_flow_entry_match(entry, &foe)) {
-+ entry->hash = 0xffff;
-+ goto out;
-+ }
-+
-+ entry->data.ib1 = foe.ib1;
-+
-+out:
-+ spin_unlock_bh(&ppe_lock);
-+}
-+
-+static void
-+__mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
-+ u16 hash)
-+{
-+ struct mtk_foe_entry *hwe;
-+ u16 timestamp;
-+
-+ timestamp = mtk_eth_timestamp(ppe->eth);
- timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP;
- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp);
-
-- hash = mtk_ppe_hash_entry(entry);
- hwe = &ppe->foe_table[hash];
-- if (!mtk_foe_entry_usable(hwe)) {
-- hwe++;
-- hash++;
--
-- if (!mtk_foe_entry_usable(hwe))
-- return -ENOSPC;
-- }
--
- memcpy(&hwe->data, &entry->data, sizeof(hwe->data));
- wmb();
- hwe->ib1 = entry->ib1;
-@@ -380,13 +421,77 @@ int mtk_foe_entry_commit(struct mtk_ppe
- dma_wmb();
-
- mtk_ppe_cache_clear(ppe);
-+}
-
-- return hash;
-+void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ spin_lock_bh(&ppe_lock);
-+ hlist_del_init(&entry->list);
-+ if (entry->hash != 0xffff) {
-+ ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE;
-+ ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
-+ MTK_FOE_STATE_BIND);
-+ dma_wmb();
-+ }
-+ entry->hash = 0xffff;
-+ spin_unlock_bh(&ppe_lock);
-+}
-+
-+int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ u32 hash = mtk_ppe_hash_entry(&entry->data);
-+
-+ entry->hash = 0xffff;
-+ spin_lock_bh(&ppe_lock);
-+ hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]);
-+ spin_unlock_bh(&ppe_lock);
-+
-+ return 0;
-+}
-+
-+void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
-+{
-+ struct hlist_head *head = &ppe->foe_flow[hash / 2];
-+ struct mtk_flow_entry *entry;
-+ struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
-+ bool found = false;
-+
-+ if (hlist_empty(head))
-+ return;
-+
-+ spin_lock_bh(&ppe_lock);
-+ hlist_for_each_entry(entry, head, list) {
-+ if (found || !mtk_flow_entry_match(entry, hwe)) {
-+ if (entry->hash != 0xffff)
-+ entry->hash = 0xffff;
-+ continue;
-+ }
-+
-+ entry->hash = hash;
-+ __mtk_foe_entry_commit(ppe, &entry->data, hash);
-+ found = true;
-+ }
-+ spin_unlock_bh(&ppe_lock);
-+}
-+
-+int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ u16 now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP;
-+ u16 timestamp;
-+
-+ mtk_flow_entry_update(ppe, entry);
-+ timestamp = entry->data.ib1 & MTK_FOE_IB1_BIND_TIMESTAMP;
-+
-+ if (timestamp > now)
-+ return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now;
-+ else
-+ return now - timestamp;
- }
-
--struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base,
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version)
- {
-+ struct device *dev = eth->dev;
- struct mtk_foe_entry *foe;
- struct mtk_ppe *ppe;
-
-@@ -398,6 +503,7 @@ struct mtk_ppe *mtk_ppe_init(struct devi
- * not coherent.
- */
- ppe->base = base;
-+ ppe->eth = eth;
- ppe->dev = dev;
- ppe->version = version;
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -235,7 +235,17 @@ enum {
- MTK_PPE_CPU_REASON_INVALID = 0x1f,
- };
-
-+struct mtk_flow_entry {
-+ struct rhash_head node;
-+ struct hlist_node list;
-+ unsigned long cookie;
-+ struct mtk_foe_entry data;
-+ u16 hash;
-+ s8 wed_index;
-+};
-+
- struct mtk_ppe {
-+ struct mtk_eth *eth;
- struct device *dev;
- void __iomem *base;
- int version;
-@@ -243,18 +253,33 @@ struct mtk_ppe {
- struct mtk_foe_entry *foe_table;
- dma_addr_t foe_phys;
-
-+ u16 foe_check_time[MTK_PPE_ENTRIES];
-+ struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2];
-+
- void *acct_table;
- };
-
--struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base, int version);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
- int mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-
-+void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
-+
- static inline void
--mtk_foe_entry_clear(struct mtk_ppe *ppe, u16 hash)
-+mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
- {
-- ppe->foe_table[hash].ib1 = 0;
-- dma_wmb();
-+ u16 now, diff;
-+
-+ if (!ppe)
-+ return;
-+
-+ now = (u16)jiffies;
-+ diff = now - ppe->foe_check_time[hash];
-+ if (diff < HZ / 10)
-+ return;
-+
-+ ppe->foe_check_time[hash] = now;
-+ __mtk_ppe_check_skb(ppe, skb, hash);
- }
-
- static inline int
-@@ -282,8 +307,9 @@ int mtk_foe_entry_set_vlan(struct mtk_fo
- int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
- int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
- int bss, int wcid);
--int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
-- u16 timestamp);
-+int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
-+void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
-+int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
-
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -42,13 +42,6 @@ struct mtk_flow_data {
- } pppoe;
- };
-
--struct mtk_flow_entry {
-- struct rhash_head node;
-- unsigned long cookie;
-- u16 hash;
-- s8 wed_index;
--};
--
- static const struct rhashtable_params mtk_flow_ht_params = {
- .head_offset = offsetof(struct mtk_flow_entry, node),
- .key_offset = offsetof(struct mtk_flow_entry, cookie),
-@@ -56,12 +49,6 @@ static const struct rhashtable_params mt
- .automatic_shrinking = true,
- };
-
--static u32
--mtk_eth_timestamp(struct mtk_eth *eth)
--{
-- return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP;
--}
--
- static int
- mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data,
- bool egress)
-@@ -237,10 +224,8 @@ mtk_flow_offload_replace(struct mtk_eth
- int offload_type = 0;
- int wed_index = -1;
- u16 addr_type = 0;
-- u32 timestamp;
- u8 l4proto = 0;
- int err = 0;
-- int hash;
- int i;
-
- if (rhashtable_lookup(&eth->flow_table, &f->cookie, mtk_flow_ht_params))
-@@ -410,23 +395,21 @@ mtk_flow_offload_replace(struct mtk_eth
- return -ENOMEM;
-
- entry->cookie = f->cookie;
-- timestamp = mtk_eth_timestamp(eth);
-- hash = mtk_foe_entry_commit(eth->ppe, &foe, timestamp);
-- if (hash < 0) {
-- err = hash;
-+ memcpy(&entry->data, &foe, sizeof(entry->data));
-+ entry->wed_index = wed_index;
-+
-+ if (mtk_foe_entry_commit(eth->ppe, entry) < 0)
- goto free;
-- }
-
-- entry->hash = hash;
-- entry->wed_index = wed_index;
- err = rhashtable_insert_fast(&eth->flow_table, &entry->node,
- mtk_flow_ht_params);
- if (err < 0)
-- goto clear_flow;
-+ goto clear;
-
- return 0;
--clear_flow:
-- mtk_foe_entry_clear(eth->ppe, hash);
-+
-+clear:
-+ mtk_foe_entry_clear(eth->ppe, entry);
- free:
- kfree(entry);
- if (wed_index >= 0)
-@@ -444,7 +427,7 @@ mtk_flow_offload_destroy(struct mtk_eth
- if (!entry)
- return -ENOENT;
-
-- mtk_foe_entry_clear(eth->ppe, entry->hash);
-+ mtk_foe_entry_clear(eth->ppe, entry);
- rhashtable_remove_fast(&eth->flow_table, &entry->node,
- mtk_flow_ht_params);
- if (entry->wed_index >= 0)
-@@ -458,7 +441,6 @@ static int
- mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
- {
- struct mtk_flow_entry *entry;
-- int timestamp;
- u32 idle;
-
- entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
-@@ -466,11 +448,7 @@ mtk_flow_offload_stats(struct mtk_eth *e
- if (!entry)
- return -ENOENT;
-
-- timestamp = mtk_foe_entry_timestamp(eth->ppe, entry->hash);
-- if (timestamp < 0)
-- return -ETIMEDOUT;
--
-- idle = mtk_eth_timestamp(eth) - timestamp;
-+ idle = mtk_foe_entry_idle_time(eth->ppe, entry);
- f->stats.lastused = jiffies - idle * HZ;
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch b/target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch
deleted file mode 100644
index 2ff0b341f9..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 21 Feb 2022 15:55:19 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: remove bridge flow offload
- type entry support
-
-According to MediaTek, this feature is not supported in current hardware
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -84,13 +84,6 @@ static u32 mtk_ppe_hash_entry(struct mtk
- u32 hash;
-
- switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) {
-- case MTK_PPE_PKT_TYPE_BRIDGE:
-- hv1 = e->bridge.src_mac_lo;
-- hv1 ^= ((e->bridge.src_mac_hi & 0xffff) << 16);
-- hv2 = e->bridge.src_mac_hi >> 16;
-- hv2 ^= e->bridge.dest_mac_lo;
-- hv3 = e->bridge.dest_mac_hi;
-- break;
- case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
- case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
- hv1 = e->ipv4.orig.ports;
-@@ -572,7 +565,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_FLOW_CFG_IP4_NAT |
- MTK_PPE_FLOW_CFG_IP4_NAPT |
- MTK_PPE_FLOW_CFG_IP4_DSLITE |
-- MTK_PPE_FLOW_CFG_L2_BRIDGE |
- MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
- ppe_w32(ppe, MTK_PPE_FLOW_CFG, val);
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -32,7 +32,6 @@ static const char *mtk_foe_pkt_type_str(
- static const char * const type_str[] = {
- [MTK_PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T",
- [MTK_PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T",
-- [MTK_PPE_PKT_TYPE_BRIDGE] = "L2",
- [MTK_PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE",
- [MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T",
- [MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T",
diff --git a/target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch b/target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch
deleted file mode 100644
index 209c65e66a..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch
+++ /dev/null
@@ -1,553 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 23 Feb 2022 10:56:34 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: support creating mac
- address based offload entries
-
-This will be used to implement a limited form of bridge offloading.
-Since the hardware does not support flow table entries with just source
-and destination MAC address, the driver has to emulate it.
-
-The hardware automatically creates entries entries for incoming flows, even
-when they are bridged instead of routed, and reports when packets for these
-flows have reached the minimum PPS rate for offloading.
-
-After this happens, we look up the L2 flow offload entry based on the MAC
-header and fill in the output routing information in the flow table.
-The dynamically created per-flow entries are automatically removed when
-either the hardware flowtable entry expires, is replaced, or if the offload
-rule they belong to is removed
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -6,12 +6,22 @@
- #include <linux/iopoll.h>
- #include <linux/etherdevice.h>
- #include <linux/platform_device.h>
-+#include <linux/if_ether.h>
-+#include <linux/if_vlan.h>
-+#include <net/dsa.h>
- #include "mtk_eth_soc.h"
- #include "mtk_ppe.h"
- #include "mtk_ppe_regs.h"
-
- static DEFINE_SPINLOCK(ppe_lock);
-
-+static const struct rhashtable_params mtk_flow_l2_ht_params = {
-+ .head_offset = offsetof(struct mtk_flow_entry, l2_node),
-+ .key_offset = offsetof(struct mtk_flow_entry, data.bridge),
-+ .key_len = offsetof(struct mtk_foe_bridge, key_end),
-+ .automatic_shrinking = true,
-+};
-+
- static void ppe_w32(struct mtk_ppe *ppe, u32 reg, u32 val)
- {
- writel(val, ppe->base + reg);
-@@ -123,6 +133,9 @@ mtk_foe_entry_l2(struct mtk_foe_entry *e
- {
- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-
-+ if (type == MTK_PPE_PKT_TYPE_BRIDGE)
-+ return &entry->bridge.l2;
-+
- if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE)
- return &entry->ipv6.l2;
-
-@@ -134,6 +147,9 @@ mtk_foe_entry_ib2(struct mtk_foe_entry *
- {
- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-
-+ if (type == MTK_PPE_PKT_TYPE_BRIDGE)
-+ return &entry->bridge.ib2;
-+
- if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE)
- return &entry->ipv6.ib2;
-
-@@ -168,7 +184,12 @@ int mtk_foe_entry_prepare(struct mtk_foe
- if (type == MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T)
- entry->ipv6.ports = ports_pad;
-
-- if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) {
-+ if (type == MTK_PPE_PKT_TYPE_BRIDGE) {
-+ ether_addr_copy(entry->bridge.src_mac, src_mac);
-+ ether_addr_copy(entry->bridge.dest_mac, dest_mac);
-+ entry->bridge.ib2 = val;
-+ l2 = &entry->bridge.l2;
-+ } else if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) {
- entry->ipv6.ib2 = val;
- l2 = &entry->ipv6.l2;
- } else {
-@@ -372,12 +393,96 @@ mtk_flow_entry_match(struct mtk_flow_ent
- }
-
- static void
-+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ struct hlist_head *head;
-+ struct hlist_node *tmp;
-+
-+ if (entry->type == MTK_FLOW_TYPE_L2) {
-+ rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node,
-+ mtk_flow_l2_ht_params);
-+
-+ head = &entry->l2_flows;
-+ hlist_for_each_entry_safe(entry, tmp, head, l2_data.list)
-+ __mtk_foe_entry_clear(ppe, entry);
-+ return;
-+ }
-+
-+ hlist_del_init(&entry->list);
-+ if (entry->hash != 0xffff) {
-+ ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE;
-+ ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
-+ MTK_FOE_STATE_BIND);
-+ dma_wmb();
-+ }
-+ entry->hash = 0xffff;
-+
-+ if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW)
-+ return;
-+
-+ hlist_del_init(&entry->l2_data.list);
-+ kfree(entry);
-+}
-+
-+static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1)
-+{
-+ u16 timestamp;
-+ u16 now;
-+
-+ now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP;
-+ timestamp = ib1 & MTK_FOE_IB1_BIND_TIMESTAMP;
-+
-+ if (timestamp > now)
-+ return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now;
-+ else
-+ return now - timestamp;
-+}
-+
-+static void
-+mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ struct mtk_flow_entry *cur;
-+ struct mtk_foe_entry *hwe;
-+ struct hlist_node *tmp;
-+ int idle;
-+
-+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) {
-+ int cur_idle;
-+ u32 ib1;
-+
-+ hwe = &ppe->foe_table[cur->hash];
-+ ib1 = READ_ONCE(hwe->ib1);
-+
-+ if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) {
-+ cur->hash = 0xffff;
-+ __mtk_foe_entry_clear(ppe, cur);
-+ continue;
-+ }
-+
-+ cur_idle = __mtk_foe_entry_idle_time(ppe, ib1);
-+ if (cur_idle >= idle)
-+ continue;
-+
-+ idle = cur_idle;
-+ entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
-+ entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP;
-+ }
-+}
-+
-+static void
- mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- struct mtk_foe_entry *hwe;
- struct mtk_foe_entry foe;
-
- spin_lock_bh(&ppe_lock);
-+
-+ if (entry->type == MTK_FLOW_TYPE_L2) {
-+ mtk_flow_entry_update_l2(ppe, entry);
-+ goto out;
-+ }
-+
- if (entry->hash == 0xffff)
- goto out;
-
-@@ -419,21 +524,28 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- spin_lock_bh(&ppe_lock);
-- hlist_del_init(&entry->list);
-- if (entry->hash != 0xffff) {
-- ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE;
-- ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
-- MTK_FOE_STATE_BIND);
-- dma_wmb();
-- }
-- entry->hash = 0xffff;
-+ __mtk_foe_entry_clear(ppe, entry);
- spin_unlock_bh(&ppe_lock);
- }
-
-+static int
-+mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ entry->type = MTK_FLOW_TYPE_L2;
-+
-+ return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node,
-+ mtk_flow_l2_ht_params);
-+}
-+
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-- u32 hash = mtk_ppe_hash_entry(&entry->data);
-+ int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1);
-+ u32 hash;
-+
-+ if (type == MTK_PPE_PKT_TYPE_BRIDGE)
-+ return mtk_foe_entry_commit_l2(ppe, entry);
-
-+ hash = mtk_ppe_hash_entry(&entry->data);
- entry->hash = 0xffff;
- spin_lock_bh(&ppe_lock);
- hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]);
-@@ -442,18 +554,72 @@ int mtk_foe_entry_commit(struct mtk_ppe
- return 0;
- }
-
-+static void
-+mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ u16 hash)
-+{
-+ struct mtk_flow_entry *flow_info;
-+ struct mtk_foe_entry foe, *hwe;
-+ struct mtk_foe_mac_info *l2;
-+ u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP;
-+ int type;
-+
-+ flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end),
-+ GFP_ATOMIC);
-+ if (!flow_info)
-+ return;
-+
-+ flow_info->l2_data.base_flow = entry;
-+ flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW;
-+ flow_info->hash = hash;
-+ hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 2]);
-+ hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
-+
-+ hwe = &ppe->foe_table[hash];
-+ memcpy(&foe, hwe, sizeof(foe));
-+ foe.ib1 &= ib1_mask;
-+ foe.ib1 |= entry->data.ib1 & ~ib1_mask;
-+
-+ l2 = mtk_foe_entry_l2(&foe);
-+ memcpy(l2, &entry->data.bridge.l2, sizeof(*l2));
-+
-+ type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, foe.ib1);
-+ if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT)
-+ memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new));
-+ else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP)
-+ l2->etype = ETH_P_IPV6;
-+
-+ *mtk_foe_entry_ib2(&foe) = entry->data.bridge.ib2;
-+
-+ __mtk_foe_entry_commit(ppe, &foe, hash);
-+}
-+
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
- {
- struct hlist_head *head = &ppe->foe_flow[hash / 2];
-- struct mtk_flow_entry *entry;
- struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
-+ struct mtk_flow_entry *entry;
-+ struct mtk_foe_bridge key = {};
-+ struct ethhdr *eh;
- bool found = false;
--
-- if (hlist_empty(head))
-- return;
-+ u8 *tag;
-
- spin_lock_bh(&ppe_lock);
-+
-+ if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND)
-+ goto out;
-+
- hlist_for_each_entry(entry, head, list) {
-+ if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) {
-+ if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) ==
-+ MTK_FOE_STATE_BIND))
-+ continue;
-+
-+ entry->hash = 0xffff;
-+ __mtk_foe_entry_clear(ppe, entry);
-+ continue;
-+ }
-+
- if (found || !mtk_flow_entry_match(entry, hwe)) {
- if (entry->hash != 0xffff)
- entry->hash = 0xffff;
-@@ -464,21 +630,50 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- __mtk_foe_entry_commit(ppe, &entry->data, hash);
- found = true;
- }
-+
-+ if (found)
-+ goto out;
-+
-+ eh = eth_hdr(skb);
-+ ether_addr_copy(key.dest_mac, eh->h_dest);
-+ ether_addr_copy(key.src_mac, eh->h_source);
-+ tag = skb->data - 2;
-+ key.vlan = 0;
-+ switch (skb->protocol) {
-+#if IS_ENABLED(CONFIG_NET_DSA)
-+ case htons(ETH_P_XDSA):
-+ if (!netdev_uses_dsa(skb->dev) ||
-+ skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK)
-+ goto out;
-+
-+ tag += 4;
-+ if (get_unaligned_be16(tag) != ETH_P_8021Q)
-+ break;
-+
-+ fallthrough;
-+#endif
-+ case htons(ETH_P_8021Q):
-+ key.vlan = get_unaligned_be16(tag + 2) & VLAN_VID_MASK;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ entry = rhashtable_lookup_fast(&ppe->l2_flows, &key, mtk_flow_l2_ht_params);
-+ if (!entry)
-+ goto out;
-+
-+ mtk_foe_entry_commit_subflow(ppe, entry, hash);
-+
-+out:
- spin_unlock_bh(&ppe_lock);
- }
-
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-- u16 now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP;
-- u16 timestamp;
--
- mtk_flow_entry_update(ppe, entry);
-- timestamp = entry->data.ib1 & MTK_FOE_IB1_BIND_TIMESTAMP;
-
-- if (timestamp > now)
-- return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now;
-- else
-- return now - timestamp;
-+ return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
- }
-
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-@@ -492,6 +687,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- if (!ppe)
- return NULL;
-
-+ rhashtable_init(&ppe->l2_flows, &mtk_flow_l2_ht_params);
-+
- /* need to allocate a separate device, since it PPE DMA access is
- * not coherent.
- */
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -6,6 +6,7 @@
-
- #include <linux/kernel.h>
- #include <linux/bitfield.h>
-+#include <linux/rhashtable.h>
-
- #define MTK_ETH_PPE_BASE 0xc00
-
-@@ -84,19 +85,16 @@ struct mtk_foe_mac_info {
- u16 src_mac_lo;
- };
-
-+/* software-only entry type */
- struct mtk_foe_bridge {
-- u32 dest_mac_hi;
--
-- u16 src_mac_lo;
-- u16 dest_mac_lo;
-+ u8 dest_mac[ETH_ALEN];
-+ u8 src_mac[ETH_ALEN];
-+ u16 vlan;
-
-- u32 src_mac_hi;
-+ struct {} key_end;
-
- u32 ib2;
-
-- u32 _rsv[5];
--
-- u32 udf_tsid;
- struct mtk_foe_mac_info l2;
- };
-
-@@ -235,13 +233,33 @@ enum {
- MTK_PPE_CPU_REASON_INVALID = 0x1f,
- };
-
-+enum {
-+ MTK_FLOW_TYPE_L4,
-+ MTK_FLOW_TYPE_L2,
-+ MTK_FLOW_TYPE_L2_SUBFLOW,
-+};
-+
- struct mtk_flow_entry {
-+ union {
-+ struct hlist_node list;
-+ struct {
-+ struct rhash_head l2_node;
-+ struct hlist_head l2_flows;
-+ };
-+ };
-+ u8 type;
-+ s8 wed_index;
-+ u16 hash;
-+ union {
-+ struct mtk_foe_entry data;
-+ struct {
-+ struct mtk_flow_entry *base_flow;
-+ struct hlist_node list;
-+ struct {} end;
-+ } l2_data;
-+ };
- struct rhash_head node;
-- struct hlist_node list;
- unsigned long cookie;
-- struct mtk_foe_entry data;
-- u16 hash;
-- s8 wed_index;
- };
-
- struct mtk_ppe {
-@@ -256,6 +274,8 @@ struct mtk_ppe {
- u16 foe_check_time[MTK_PPE_ENTRIES];
- struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2];
-
-+ struct rhashtable l2_flows;
-+
- void *acct_table;
- };
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -31,6 +31,8 @@ struct mtk_flow_data {
- __be16 src_port;
- __be16 dst_port;
-
-+ u16 vlan_in;
-+
- struct {
- u16 id;
- __be16 proto;
-@@ -257,9 +259,45 @@ mtk_flow_offload_replace(struct mtk_eth
- return -EOPNOTSUPP;
- }
-
-+ switch (addr_type) {
-+ case 0:
-+ offload_type = MTK_PPE_PKT_TYPE_BRIDGE;
-+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
-+ struct flow_match_eth_addrs match;
-+
-+ flow_rule_match_eth_addrs(rule, &match);
-+ memcpy(data.eth.h_dest, match.key->dst, ETH_ALEN);
-+ memcpy(data.eth.h_source, match.key->src, ETH_ALEN);
-+ } else {
-+ return -EOPNOTSUPP;
-+ }
-+
-+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
-+ struct flow_match_vlan match;
-+
-+ flow_rule_match_vlan(rule, &match);
-+
-+ if (match.key->vlan_tpid != cpu_to_be16(ETH_P_8021Q))
-+ return -EOPNOTSUPP;
-+
-+ data.vlan_in = match.key->vlan_id;
-+ }
-+ break;
-+ case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
-+ offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT;
-+ break;
-+ case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
-+ offload_type = MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T;
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
- flow_action_for_each(i, act, &rule->action) {
- switch (act->id) {
- case FLOW_ACTION_MANGLE:
-+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE)
-+ return -EOPNOTSUPP;
- if (act->mangle.htype == FLOW_ACT_MANGLE_HDR_TYPE_ETH)
- mtk_flow_offload_mangle_eth(act, &data.eth);
- break;
-@@ -291,17 +329,6 @@ mtk_flow_offload_replace(struct mtk_eth
- }
- }
-
-- switch (addr_type) {
-- case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
-- offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT;
-- break;
-- case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
-- offload_type = MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T;
-- break;
-- default:
-- return -EOPNOTSUPP;
-- }
--
- if (!is_valid_ether_addr(data.eth.h_source) ||
- !is_valid_ether_addr(data.eth.h_dest))
- return -EINVAL;
-@@ -315,10 +342,13 @@ mtk_flow_offload_replace(struct mtk_eth
- if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
- struct flow_match_ports ports;
-
-+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE)
-+ return -EOPNOTSUPP;
-+
- flow_rule_match_ports(rule, &ports);
- data.src_port = ports.key->src;
- data.dst_port = ports.key->dst;
-- } else {
-+ } else if (offload_type != MTK_PPE_PKT_TYPE_BRIDGE) {
- return -EOPNOTSUPP;
- }
-
-@@ -348,6 +378,9 @@ mtk_flow_offload_replace(struct mtk_eth
- if (act->id != FLOW_ACTION_MANGLE)
- continue;
-
-+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE)
-+ return -EOPNOTSUPP;
-+
- switch (act->mangle.htype) {
- case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
- case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
-@@ -373,6 +406,9 @@ mtk_flow_offload_replace(struct mtk_eth
- return err;
- }
-
-+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE)
-+ foe.bridge.vlan = data.vlan_in;
-+
- if (data.vlan.num == 1) {
- if (data.vlan.proto != htons(ETH_P_8021Q))
- return -EOPNOTSUPP;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch b/target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch
deleted file mode 100644
index 8f3dfe8239..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 8 Apr 2022 10:59:45 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc/wed: fix sparse endian warnings
-
-Descriptor fields are little-endian
-
-Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -144,16 +144,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi
-
- for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
- u32 txd_size;
-+ u32 ctrl;
-
- txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
-
-- desc->buf0 = buf_phys;
-- desc->buf1 = buf_phys + txd_size;
-- desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0,
-- txd_size) |
-- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-- MTK_WED_BUF_SIZE - txd_size) |
-- MTK_WDMA_DESC_CTRL_LAST_SEG1;
-+ desc->buf0 = cpu_to_le32(buf_phys);
-+ desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-+ MTK_WED_BUF_SIZE - txd_size) |
-+ MTK_WDMA_DESC_CTRL_LAST_SEG1;
-+ desc->ctrl = cpu_to_le32(ctrl);
- desc->info = 0;
- desc++;
-
-@@ -184,12 +185,14 @@ mtk_wed_free_buffer(struct mtk_wed_devic
-
- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
- void *page = page_list[page_idx++];
-+ dma_addr_t buf_addr;
-
- if (!page)
- break;
-
-- dma_unmap_page(dev->hw->dev, desc[i].buf0,
-- PAGE_SIZE, DMA_BIDIRECTIONAL);
-+ buf_addr = le32_to_cpu(desc[i].buf0);
-+ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
- __free_page(page);
- }
-
diff --git a/target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch b/target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch
deleted file mode 100644
index 4ec8fe74bc..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Yang Yingliang <yangyingliang@huawei.com>
-Date: Fri, 8 Apr 2022 11:22:46 +0800
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix return value check in
- mtk_wed_add_hw()
-
-If syscon_regmap_lookup_by_phandle() fails, it never return NULL pointer,
-change the check to IS_ERR().
-
-Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Reported-by: Hulk Robot <hulkci@huawei.com>
-Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -816,7 +816,7 @@ void mtk_wed_add_hw(struct device_node *
- return;
-
- regs = syscon_regmap_lookup_by_phandle(np, NULL);
-- if (!regs)
-+ if (IS_ERR(regs))
- return;
-
- rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
diff --git a/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch b/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch
deleted file mode 100644
index 22125a4546..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 11 Apr 2022 12:13:25 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: use standard property for
- cci-control-port
-
-Rely on standard cci-control-port property to identify CCI port
-reference.
-Update mt7622 dts binding.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -957,7 +957,7 @@
- power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
- mediatek,ethsys = <&ethsys>;
- mediatek,sgmiisys = <&sgmiisys>;
-- mediatek,cci-control = <&cci_control2>;
-+ cci-control-port = <&cci_control2>;
- mediatek,wed = <&wed0>, <&wed1>;
- mediatek,pcie-mirror = <&pcie_mirror>;
- mediatek,hifsys = <&hifsys>;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3194,7 +3194,7 @@ static int mtk_probe(struct platform_dev
- struct regmap *cci;
-
- cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-- "mediatek,cci-control");
-+ "cci-control-port");
- /* enable CPU/bus coherency */
- if (!IS_ERR(cci))
- regmap_write(cci, 0, 3);
diff --git a/target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch b/target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch
deleted file mode 100644
index 656b3a159e..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Tue, 12 Apr 2022 12:24:19 +0300
-Subject: [PATCH] net: ethernet: mtk_eth_soc: use after free in
- __mtk_ppe_check_skb()
-
-The __mtk_foe_entry_clear() function frees "entry" so we have to use
-the _safe() version of hlist_for_each_entry() to prevent a use after
-free.
-
-Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries")
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -600,6 +600,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
- struct mtk_flow_entry *entry;
- struct mtk_foe_bridge key = {};
-+ struct hlist_node *n;
- struct ethhdr *eh;
- bool found = false;
- u8 *tag;
-@@ -609,7 +610,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND)
- goto out;
-
-- hlist_for_each_entry(entry, head, list) {
-+ hlist_for_each_entry_safe(entry, n, head, list) {
- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) {
- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) ==
- MTK_FOE_STATE_BIND))
diff --git a/target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch b/target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch
deleted file mode 100644
index 714163c86b..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Thu, 21 Apr 2022 18:49:02 +0300
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add check for allocation failure
-
-Check if the kzalloc() failed.
-
-Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -827,6 +827,8 @@ void mtk_wed_add_hw(struct device_node *
- goto unlock;
-
- hw = kzalloc(sizeof(*hw), GFP_KERNEL);
-+ if (!hw)
-+ goto unlock;
- hw->node = np;
- hw->regs = regs;
- hw->eth = eth;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch b/target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch
deleted file mode 100644
index aa98745ac6..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Jakub Kicinski <kuba@kernel.org>
-Date: Fri, 20 May 2022 12:56:03 -0700
-Subject: [PATCH] eth: mtk_eth_soc: silence the GCC 12 array-bounds warning
-
-GCC 12 gets upset because in mtk_foe_entry_commit_subflow()
-this driver allocates a partial structure. The writes are
-within bounds.
-
-Silence these warnings for now, our build bot runs GCC 12
-so we won't allow any new instances.
-
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -11,3 +11,8 @@ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) +
- endif
- obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o
- obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o
-+
-+# FIXME: temporarily silence -Warray-bounds on non W=1+ builds
-+ifndef KBUILD_EXTRA_WARN
-+CFLAGS_mtk_ppe.o += -Wno-array-bounds
-+endif
diff --git a/target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch b/target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch
deleted file mode 100644
index 268b372388..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:26 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on GFP_KERNEL for
- dma_alloc_coherent whenever possible
-
-Rely on GFP_KERNEL for dma descriptors mappings in mtk_tx_alloc(),
-mtk_rx_alloc() and mtk_init_fq_dma() since they are run in non-irq
-context.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -856,7 +856,7 @@ static int mtk_init_fq_dma(struct mtk_et
- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
- cnt * sizeof(struct mtk_tx_dma),
- &eth->phy_scratch_ring,
-- GFP_ATOMIC);
-+ GFP_KERNEL);
- if (unlikely(!eth->scratch_ring))
- return -ENOMEM;
-
-@@ -1634,7 +1634,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- goto no_tx_mem;
-
- ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
-- &ring->phys, GFP_ATOMIC);
-+ &ring->phys, GFP_KERNEL);
- if (!ring->dma)
- goto no_tx_mem;
-
-@@ -1652,8 +1652,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- */
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
-- &ring->phys_pdma,
-- GFP_ATOMIC);
-+ &ring->phys_pdma, GFP_KERNEL);
- if (!ring->dma_pdma)
- goto no_tx_mem;
-
-@@ -1768,7 +1767,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-
- ring->dma = dma_alloc_coherent(eth->dma_dev,
- rx_dma_size * sizeof(*ring->dma),
-- &ring->phys, GFP_ATOMIC);
-+ &ring->phys, GFP_KERNEL);
- if (!ring->dma)
- return -ENOMEM;
-
diff --git a/target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch b/target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch
deleted file mode 100644
index dc85786be2..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:27 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: move tx dma desc configuration in
- mtk_tx_set_dma_desc
-
-Move tx dma descriptor configuration in mtk_tx_set_dma_desc routine.
-This is a preliminary patch to introduce mt7986 ethernet support since
-it relies on a different tx dma descriptor layout.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -982,18 +982,51 @@ static void setup_tx_buf(struct mtk_eth
- }
- }
-
-+static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc,
-+ struct mtk_tx_dma_desc_info *info)
-+{
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ u32 data;
-+
-+ WRITE_ONCE(desc->txd1, info->addr);
-+
-+ data = TX_DMA_SWC | TX_DMA_PLEN0(info->size);
-+ if (info->last)
-+ data |= TX_DMA_LS0;
-+ WRITE_ONCE(desc->txd3, data);
-+
-+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT; /* forward port */
-+ if (info->first) {
-+ if (info->gso)
-+ data |= TX_DMA_TSO;
-+ /* tx checksum offload */
-+ if (info->csum)
-+ data |= TX_DMA_CHKSUM;
-+ /* vlan header offload */
-+ if (info->vlan)
-+ data |= TX_DMA_INS_VLAN | info->vlan_tci;
-+ }
-+ WRITE_ONCE(desc->txd4, data);
-+}
-+
- static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
- int tx_num, struct mtk_tx_ring *ring, bool gso)
- {
-+ struct mtk_tx_dma_desc_info txd_info = {
-+ .size = skb_headlen(skb),
-+ .gso = gso,
-+ .csum = skb->ip_summed == CHECKSUM_PARTIAL,
-+ .vlan = skb_vlan_tag_present(skb),
-+ .vlan_tci = skb_vlan_tag_get(skb),
-+ .first = true,
-+ .last = !skb_is_nonlinear(skb),
-+ };
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
- struct mtk_tx_dma *itxd, *txd;
- struct mtk_tx_dma *itxd_pdma, *txd_pdma;
- struct mtk_tx_buf *itx_buf, *tx_buf;
-- dma_addr_t mapped_addr;
-- unsigned int nr_frags;
- int i, n_desc = 1;
-- u32 txd4 = 0, fport;
- int k = 0;
-
- itxd = ring->next_free;
-@@ -1001,49 +1034,32 @@ static int mtk_tx_map(struct sk_buff *sk
- if (itxd == ring->last_free)
- return -ENOMEM;
-
-- /* set the forward port */
-- fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT;
-- txd4 |= fport;
--
- itx_buf = mtk_desc_to_tx_buf(ring, itxd);
- memset(itx_buf, 0, sizeof(*itx_buf));
-
-- if (gso)
-- txd4 |= TX_DMA_TSO;
--
-- /* TX Checksum offload */
-- if (skb->ip_summed == CHECKSUM_PARTIAL)
-- txd4 |= TX_DMA_CHKSUM;
--
-- /* VLAN header offload */
-- if (skb_vlan_tag_present(skb))
-- txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
--
-- mapped_addr = dma_map_single(eth->dma_dev, skb->data,
-- skb_headlen(skb), DMA_TO_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr)))
-+ txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
-+ DMA_TO_DEVICE);
-+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
- return -ENOMEM;
-
-- WRITE_ONCE(itxd->txd1, mapped_addr);
-+ mtk_tx_set_dma_desc(dev, itxd, &txd_info);
-+
- itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
-- setup_tx_buf(eth, itx_buf, itxd_pdma, mapped_addr, skb_headlen(skb),
-+ setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
- k++);
-
- /* TX SG offload */
- txd = itxd;
- txd_pdma = qdma_to_pdma(ring, txd);
-- nr_frags = skb_shinfo(skb)->nr_frags;
-
-- for (i = 0; i < nr_frags; i++) {
-+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- unsigned int offset = 0;
- int frag_size = skb_frag_size(frag);
-
- while (frag_size) {
-- bool last_frag = false;
-- unsigned int frag_map_size;
- bool new_desc = true;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) ||
-@@ -1058,23 +1074,17 @@ static int mtk_tx_map(struct sk_buff *sk
- new_desc = false;
- }
-
--
-- frag_map_size = min(frag_size, MTK_TX_DMA_BUF_LEN);
-- mapped_addr = skb_frag_dma_map(eth->dma_dev, frag, offset,
-- frag_map_size,
-- DMA_TO_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr)))
-+ memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
-+ txd_info.size = min(frag_size, MTK_TX_DMA_BUF_LEN);
-+ txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
-+ !(frag_size - txd_info.size);
-+ txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
-+ offset, txd_info.size,
-+ DMA_TO_DEVICE);
-+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
- goto err_dma;
-
-- if (i == nr_frags - 1 &&
-- (frag_size - frag_map_size) == 0)
-- last_frag = true;
--
-- WRITE_ONCE(txd->txd1, mapped_addr);
-- WRITE_ONCE(txd->txd3, (TX_DMA_SWC |
-- TX_DMA_PLEN0(frag_map_size) |
-- last_frag * TX_DMA_LS0));
-- WRITE_ONCE(txd->txd4, fport);
-+ mtk_tx_set_dma_desc(dev, txd, &txd_info);
-
- tx_buf = mtk_desc_to_tx_buf(ring, txd);
- if (new_desc)
-@@ -1084,20 +1094,17 @@ static int mtk_tx_map(struct sk_buff *sk
- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
-
-- setup_tx_buf(eth, tx_buf, txd_pdma, mapped_addr,
-- frag_map_size, k++);
-+ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
-+ txd_info.size, k++);
-
-- frag_size -= frag_map_size;
-- offset += frag_map_size;
-+ frag_size -= txd_info.size;
-+ offset += txd_info.size;
- }
- }
-
- /* store skb to cleanup */
- itx_buf->skb = skb;
-
-- WRITE_ONCE(itxd->txd4, txd4);
-- WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
-- (!nr_frags * TX_DMA_LS0)));
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
- if (k & 0x1)
- txd_pdma->txd2 |= TX_DMA_LS0;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -843,6 +843,17 @@ enum mkt_eth_capabilities {
- MTK_MUX_U3_GMAC2_TO_QPHY | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
-
-+struct mtk_tx_dma_desc_info {
-+ dma_addr_t addr;
-+ u32 size;
-+ u16 vlan_tci;
-+ u8 gso:1;
-+ u8 csum:1;
-+ u8 vlan:1;
-+ u8 first:1;
-+ u8 last:1;
-+};
-+
- /* struct mtk_eth_data - This is the structure holding all differences
- * among various plaforms
- * @ana_rgc3: The offset for register ANA_RGC3 related to
diff --git a/target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch
deleted file mode 100644
index 7e05181b5e..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:28 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add txd_size to mtk_soc_data
-
-In order to remove mtk_tx_dma size dependency, introduce txd_size in
-mtk_soc_data data structure. Rely on txd_size in mtk_init_fq_dma() and
-mtk_dma_free() routines.
-This is a preliminary patch to add mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -848,20 +848,20 @@ static void *mtk_max_lro_buf_alloc(gfp_t
- /* the qdma core needs scratch memory to be setup */
- static int mtk_init_fq_dma(struct mtk_eth *eth)
- {
-+ const struct mtk_soc_data *soc = eth->soc;
- dma_addr_t phy_ring_tail;
- int cnt = MTK_DMA_SIZE;
- dma_addr_t dma_addr;
- int i;
-
- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
-- cnt * sizeof(struct mtk_tx_dma),
-+ cnt * soc->txrx.txd_size,
- &eth->phy_scratch_ring,
- GFP_KERNEL);
- if (unlikely(!eth->scratch_ring))
- return -ENOMEM;
-
-- eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE,
-- GFP_KERNEL);
-+ eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
- if (unlikely(!eth->scratch_head))
- return -ENOMEM;
-
-@@ -871,16 +871,19 @@ static int mtk_init_fq_dma(struct mtk_et
- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
- return -ENOMEM;
-
-- phy_ring_tail = eth->phy_scratch_ring +
-- (sizeof(struct mtk_tx_dma) * (cnt - 1));
-+ phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1);
-
- for (i = 0; i < cnt; i++) {
-- eth->scratch_ring[i].txd1 =
-- (dma_addr + (i * MTK_QDMA_PAGE_SIZE));
-+ struct mtk_tx_dma *txd;
-+
-+ txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size;
-+ txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
- if (i < cnt - 1)
-- eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
-- ((i + 1) * sizeof(struct mtk_tx_dma)));
-- eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
-+ txd->txd2 = eth->phy_scratch_ring +
-+ (i + 1) * soc->txrx.txd_size;
-+
-+ txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
-+ txd->txd4 = 0;
- }
-
- mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
-@@ -2183,6 +2186,7 @@ static int mtk_dma_init(struct mtk_eth *
-
- static void mtk_dma_free(struct mtk_eth *eth)
- {
-+ const struct mtk_soc_data *soc = eth->soc;
- int i;
-
- for (i = 0; i < MTK_MAC_COUNT; i++)
-@@ -2190,9 +2194,8 @@ static void mtk_dma_free(struct mtk_eth
- netdev_reset_queue(eth->netdev[i]);
- if (eth->scratch_ring) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
-- eth->scratch_ring,
-- eth->phy_scratch_ring);
-+ MTK_DMA_SIZE * soc->txrx.txd_size,
-+ eth->scratch_ring, eth->phy_scratch_ring);
- eth->scratch_ring = NULL;
- eth->phy_scratch_ring = 0;
- }
-@@ -3397,6 +3400,9 @@ static const struct mtk_soc_data mt2701_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ },
- };
-
- static const struct mtk_soc_data mt7621_data = {
-@@ -3405,6 +3411,9 @@ static const struct mtk_soc_data mt7621_
- .required_clks = MT7621_CLKS_BITMAP,
- .required_pctl = false,
- .offload_version = 2,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ },
- };
-
- static const struct mtk_soc_data mt7622_data = {
-@@ -3414,6 +3423,9 @@ static const struct mtk_soc_data mt7622_
- .required_clks = MT7622_CLKS_BITMAP,
- .required_pctl = false,
- .offload_version = 2,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ },
- };
-
- static const struct mtk_soc_data mt7623_data = {
-@@ -3422,6 +3434,9 @@ static const struct mtk_soc_data mt7623_
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
- .offload_version = 2,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ },
- };
-
- static const struct mtk_soc_data mt7629_data = {
-@@ -3430,6 +3445,9 @@ static const struct mtk_soc_data mt7629_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7629_CLKS_BITMAP,
- .required_pctl = false,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ },
- };
-
- static const struct mtk_soc_data rt5350_data = {
-@@ -3437,6 +3455,9 @@ static const struct mtk_soc_data rt5350_
- .hw_features = MTK_HW_FEATURES_MT7628,
- .required_clks = MT7628_CLKS_BITMAP,
- .required_pctl = false,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ },
- };
-
- const struct of_device_id of_mtk_match[] = {
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -864,6 +864,7 @@ struct mtk_tx_dma_desc_info {
- * the target SoC
- * @required_pctl A bool value to show whether the SoC requires
- * the extra setup for those pins used by GMAC.
-+ * @txd_size Tx DMA descriptor size.
- */
- struct mtk_soc_data {
- u32 ana_rgc3;
-@@ -872,6 +873,9 @@ struct mtk_soc_data {
- bool required_pctl;
- u8 offload_version;
- netdev_features_t hw_features;
-+ struct {
-+ u32 txd_size;
-+ } txrx;
- };
-
- /* currently no SoC has more than 2 macs */
diff --git a/target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch b/target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch
deleted file mode 100644
index 0547d7874f..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:29 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size in
- mtk_tx_alloc/mtk_tx_clean
-
-This is a preliminary patch to add mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1635,8 +1635,10 @@ static int mtk_napi_rx(struct napi_struc
-
- static int mtk_tx_alloc(struct mtk_eth *eth)
- {
-+ const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_ring *ring = &eth->tx_ring;
-- int i, sz = sizeof(*ring->dma);
-+ int i, sz = soc->txrx.txd_size;
-+ struct mtk_tx_dma *txd;
-
- ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf),
- GFP_KERNEL);
-@@ -1652,8 +1654,10 @@ static int mtk_tx_alloc(struct mtk_eth *
- int next = (i + 1) % MTK_DMA_SIZE;
- u32 next_ptr = ring->phys + next * sz;
-
-- ring->dma[i].txd2 = next_ptr;
-- ring->dma[i].txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-+ txd = (void *)ring->dma + i * sz;
-+ txd->txd2 = next_ptr;
-+ txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-+ txd->txd4 = 0;
- }
-
- /* On MT7688 (PDMA only) this driver uses the ring->dma structs
-@@ -1675,7 +1679,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- ring->dma_size = MTK_DMA_SIZE;
- atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
- ring->next_free = &ring->dma[0];
-- ring->last_free = &ring->dma[MTK_DMA_SIZE - 1];
-+ ring->last_free = (void *)txd;
- ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz));
- ring->thresh = MAX_SKB_FRAGS;
-
-@@ -1708,6 +1712,7 @@ no_tx_mem:
-
- static void mtk_tx_clean(struct mtk_eth *eth)
- {
-+ const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_ring *ring = &eth->tx_ring;
- int i;
-
-@@ -1720,17 +1725,15 @@ static void mtk_tx_clean(struct mtk_eth
-
- if (ring->dma) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * sizeof(*ring->dma),
-- ring->dma,
-- ring->phys);
-+ MTK_DMA_SIZE * soc->txrx.txd_size,
-+ ring->dma, ring->phys);
- ring->dma = NULL;
- }
-
- if (ring->dma_pdma) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * sizeof(*ring->dma_pdma),
-- ring->dma_pdma,
-- ring->phys_pdma);
-+ MTK_DMA_SIZE * soc->txrx.txd_size,
-+ ring->dma_pdma, ring->phys_pdma);
- ring->dma_pdma = NULL;
- }
- }
diff --git a/target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch b/target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch
deleted file mode 100644
index b76d69c50e..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:30 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size in
- mtk_desc_to_tx_buf
-
-This is a preliminary patch to add mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -901,10 +901,11 @@ static inline void *mtk_qdma_phys_to_vir
- return ret + (desc - ring->phys);
- }
-
--static inline struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,
-- struct mtk_tx_dma *txd)
-+static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,
-+ struct mtk_tx_dma *txd,
-+ u32 txd_size)
- {
-- int idx = txd - ring->dma;
-+ int idx = ((void *)txd - (void *)ring->dma) / txd_size;
-
- return &ring->buf[idx];
- }
-@@ -1026,6 +1027,7 @@ static int mtk_tx_map(struct sk_buff *sk
- };
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-+ const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_dma *itxd, *txd;
- struct mtk_tx_dma *itxd_pdma, *txd_pdma;
- struct mtk_tx_buf *itx_buf, *tx_buf;
-@@ -1037,7 +1039,7 @@ static int mtk_tx_map(struct sk_buff *sk
- if (itxd == ring->last_free)
- return -ENOMEM;
-
-- itx_buf = mtk_desc_to_tx_buf(ring, itxd);
-+ itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
- memset(itx_buf, 0, sizeof(*itx_buf));
-
- txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
-@@ -1065,7 +1067,7 @@ static int mtk_tx_map(struct sk_buff *sk
- while (frag_size) {
- bool new_desc = true;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) ||
-+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) ||
- (i & 0x1)) {
- txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
- txd_pdma = qdma_to_pdma(ring, txd);
-@@ -1089,7 +1091,8 @@ static int mtk_tx_map(struct sk_buff *sk
-
- mtk_tx_set_dma_desc(dev, txd, &txd_info);
-
-- tx_buf = mtk_desc_to_tx_buf(ring, txd);
-+ tx_buf = mtk_desc_to_tx_buf(ring, txd,
-+ soc->txrx.txd_size);
- if (new_desc)
- memset(tx_buf, 0, sizeof(*tx_buf));
- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
-@@ -1108,7 +1111,7 @@ static int mtk_tx_map(struct sk_buff *sk
- /* store skb to cleanup */
- itx_buf->skb = skb;
-
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- if (k & 0x1)
- txd_pdma->txd2 |= TX_DMA_LS0;
- else
-@@ -1126,7 +1129,7 @@ static int mtk_tx_map(struct sk_buff *sk
- */
- wmb();
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) ||
- !netdev_xmit_more())
- mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR);
-@@ -1140,13 +1143,13 @@ static int mtk_tx_map(struct sk_buff *sk
-
- err_dma:
- do {
-- tx_buf = mtk_desc_to_tx_buf(ring, itxd);
-+ tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
-
- /* unmap dma */
- mtk_tx_unmap(eth, tx_buf, false);
-
- itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA))
- itxd_pdma->txd2 = TX_DMA_DESP2_DEF;
-
- itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
-@@ -1460,7 +1463,8 @@ static int mtk_poll_tx_qdma(struct mtk_e
- if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
- break;
-
-- tx_buf = mtk_desc_to_tx_buf(ring, desc);
-+ tx_buf = mtk_desc_to_tx_buf(ring, desc,
-+ eth->soc->txrx.txd_size);
- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
- mac = 1;
-
diff --git a/target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch b/target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch
deleted file mode 100644
index 99ee2c5cf9..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:31 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size in txd_to_idx
-
-This is a preliminary patch to add mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -916,9 +916,10 @@ static struct mtk_tx_dma *qdma_to_pdma(s
- return ring->dma_pdma - ring->dma + dma;
- }
-
--static int txd_to_idx(struct mtk_tx_ring *ring, struct mtk_tx_dma *dma)
-+static int txd_to_idx(struct mtk_tx_ring *ring, struct mtk_tx_dma *dma,
-+ u32 txd_size)
- {
-- return ((void *)dma - (void *)ring->dma) / sizeof(*dma);
-+ return ((void *)dma - (void *)ring->dma) / txd_size;
- }
-
- static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
-@@ -1134,8 +1135,10 @@ static int mtk_tx_map(struct sk_buff *sk
- !netdev_xmit_more())
- mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR);
- } else {
-- int next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd),
-- ring->dma_size);
-+ int next_idx;
-+
-+ next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->txrx.txd_size),
-+ ring->dma_size);
- mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
- }
-
diff --git a/target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch
deleted file mode 100644
index 27bf69b58c..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:32 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add rxd_size to mtk_soc_data
-
-Similar to tx counterpart, introduce rxd_size in mtk_soc_data data
-structure.
-This is a preliminary patch to add mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1786,7 +1786,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- }
-
- ring->dma = dma_alloc_coherent(eth->dma_dev,
-- rx_dma_size * sizeof(*ring->dma),
-+ rx_dma_size * eth->soc->txrx.rxd_size,
- &ring->phys, GFP_KERNEL);
- if (!ring->dma)
- return -ENOMEM;
-@@ -1844,9 +1844,8 @@ static void mtk_rx_clean(struct mtk_eth
-
- if (ring->dma) {
- dma_free_coherent(eth->dma_dev,
-- ring->dma_size * sizeof(*ring->dma),
-- ring->dma,
-- ring->phys);
-+ ring->dma_size * eth->soc->txrx.rxd_size,
-+ ring->dma, ring->phys);
- ring->dma = NULL;
- }
- }
-@@ -3412,6 +3411,7 @@ static const struct mtk_soc_data mt2701_
- .required_pctl = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
- },
- };
-
-@@ -3423,6 +3423,7 @@ static const struct mtk_soc_data mt7621_
- .offload_version = 2,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
- },
- };
-
-@@ -3435,6 +3436,7 @@ static const struct mtk_soc_data mt7622_
- .offload_version = 2,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
- },
- };
-
-@@ -3446,6 +3448,7 @@ static const struct mtk_soc_data mt7623_
- .offload_version = 2,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
- },
- };
-
-@@ -3457,6 +3460,7 @@ static const struct mtk_soc_data mt7629_
- .required_pctl = false,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
- },
- };
-
-@@ -3467,6 +3471,7 @@ static const struct mtk_soc_data rt5350_
- .required_pctl = false,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
- },
- };
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -865,6 +865,7 @@ struct mtk_tx_dma_desc_info {
- * @required_pctl A bool value to show whether the SoC requires
- * the extra setup for those pins used by GMAC.
- * @txd_size Tx DMA descriptor size.
-+ * @rxd_size Rx DMA descriptor size.
- */
- struct mtk_soc_data {
- u32 ana_rgc3;
-@@ -875,6 +876,7 @@ struct mtk_soc_data {
- netdev_features_t hw_features;
- struct {
- u32 txd_size;
-+ u32 rxd_size;
- } txrx;
- };
-
diff --git a/target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch b/target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch
deleted file mode 100644
index 393faf6553..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:33 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size field in
- mtk_poll_tx/mtk_poll_rx
-
-This is a preliminary to ad mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1275,9 +1275,12 @@ static struct mtk_rx_ring *mtk_get_rx_ri
- return &eth->rx_ring[0];
-
- for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) {
-+ struct mtk_rx_dma *rxd;
-+
- ring = &eth->rx_ring[i];
- idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-- if (ring->dma[idx].rxd2 & RX_DMA_DONE) {
-+ rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size;
-+ if (rxd->rxd2 & RX_DMA_DONE) {
- ring->calc_idx_update = true;
- return ring;
- }
-@@ -1328,7 +1331,7 @@ static int mtk_poll_rx(struct napi_struc
- goto rx_done;
-
- idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-- rxd = &ring->dma[idx];
-+ rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size;
- data = ring->data[idx];
-
- if (!mtk_rx_get_desc(&trxd, rxd))
-@@ -1520,7 +1523,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
-
- mtk_tx_unmap(eth, tx_buf, true);
-
-- desc = &ring->dma[cpu];
-+ desc = (void *)ring->dma + cpu * eth->soc->txrx.txd_size;
- ring->last_free = desc;
- atomic_inc(&ring->free_count);
-
diff --git a/target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch b/target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch
deleted file mode 100644
index fdfa8b99c0..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:34 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on rxd_size field in
- mtk_rx_alloc/mtk_rx_clean
-
-Remove mtk_rx_dma structure layout dependency in mtk_rx_alloc/mtk_rx_clean.
-Initialize to 0 rxd3 and rxd4 in mtk_rx_alloc.
-This is a preliminary patch to add mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1795,18 +1795,25 @@ static int mtk_rx_alloc(struct mtk_eth *
- return -ENOMEM;
-
- for (i = 0; i < rx_dma_size; i++) {
-+ struct mtk_rx_dma *rxd;
-+
- dma_addr_t dma_addr = dma_map_single(eth->dma_dev,
- ring->data[i] + NET_SKB_PAD + eth->ip_align,
- ring->buf_size,
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
- return -ENOMEM;
-- ring->dma[i].rxd1 = (unsigned int)dma_addr;
-+
-+ rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size;
-+ rxd->rxd1 = (unsigned int)dma_addr;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-- ring->dma[i].rxd2 = RX_DMA_LSO;
-+ rxd->rxd2 = RX_DMA_LSO;
- else
-- ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size);
-+ rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size);
-+
-+ rxd->rxd3 = 0;
-+ rxd->rxd4 = 0;
- }
- ring->dma_size = rx_dma_size;
- ring->calc_idx_update = false;
-@@ -1831,14 +1838,17 @@ static void mtk_rx_clean(struct mtk_eth
-
- if (ring->data && ring->dma) {
- for (i = 0; i < ring->dma_size; i++) {
-+ struct mtk_rx_dma *rxd;
-+
- if (!ring->data[i])
- continue;
-- if (!ring->dma[i].rxd1)
-+
-+ rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size;
-+ if (!rxd->rxd1)
- continue;
-- dma_unmap_single(eth->dma_dev,
-- ring->dma[i].rxd1,
-- ring->buf_size,
-- DMA_FROM_DEVICE);
-+
-+ dma_unmap_single(eth->dma_dev, rxd->rxd1,
-+ ring->buf_size, DMA_FROM_DEVICE);
- skb_free_frag(ring->data[i]);
- }
- kfree(ring->data);
diff --git a/target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch b/target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch
deleted file mode 100644
index c4c337a3ce..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch
+++ /dev/null
@@ -1,814 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:35 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce device register map
-
-Introduce reg_map structure to add the capability to support different
-register definitions. Move register definitions in mtk_regmap structure.
-This is a preliminary patch to introduce mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -34,6 +34,59 @@ MODULE_PARM_DESC(msg_level, "Message lev
- #define MTK_ETHTOOL_STAT(x) { #x, \
- offsetof(struct mtk_hw_stats, x) / sizeof(u64) }
-
-+static const struct mtk_reg_map mtk_reg_map = {
-+ .tx_irq_mask = 0x1a1c,
-+ .tx_irq_status = 0x1a18,
-+ .pdma = {
-+ .rx_ptr = 0x0900,
-+ .rx_cnt_cfg = 0x0904,
-+ .pcrx_ptr = 0x0908,
-+ .glo_cfg = 0x0a04,
-+ .rst_idx = 0x0a08,
-+ .delay_irq = 0x0a0c,
-+ .irq_status = 0x0a20,
-+ .irq_mask = 0x0a28,
-+ .int_grp = 0x0a50,
-+ },
-+ .qdma = {
-+ .qtx_cfg = 0x1800,
-+ .rx_ptr = 0x1900,
-+ .rx_cnt_cfg = 0x1904,
-+ .qcrx_ptr = 0x1908,
-+ .glo_cfg = 0x1a04,
-+ .rst_idx = 0x1a08,
-+ .delay_irq = 0x1a0c,
-+ .fc_th = 0x1a10,
-+ .int_grp = 0x1a20,
-+ .hred = 0x1a44,
-+ .ctx_ptr = 0x1b00,
-+ .dtx_ptr = 0x1b04,
-+ .crx_ptr = 0x1b10,
-+ .drx_ptr = 0x1b14,
-+ .fq_head = 0x1b20,
-+ .fq_tail = 0x1b24,
-+ .fq_count = 0x1b28,
-+ .fq_blen = 0x1b2c,
-+ },
-+ .gdm1_cnt = 0x2400,
-+};
-+
-+static const struct mtk_reg_map mt7628_reg_map = {
-+ .tx_irq_mask = 0x0a28,
-+ .tx_irq_status = 0x0a20,
-+ .pdma = {
-+ .rx_ptr = 0x0900,
-+ .rx_cnt_cfg = 0x0904,
-+ .pcrx_ptr = 0x0908,
-+ .glo_cfg = 0x0a04,
-+ .rst_idx = 0x0a08,
-+ .delay_irq = 0x0a0c,
-+ .irq_status = 0x0a20,
-+ .irq_mask = 0x0a28,
-+ .int_grp = 0x0a50,
-+ },
-+};
-+
- /* strings used by ethtool */
- static const struct mtk_ethtool_stats {
- char str[ETH_GSTRING_LEN];
-@@ -629,8 +682,8 @@ static inline void mtk_tx_irq_disable(st
- u32 val;
-
- spin_lock_irqsave(&eth->tx_irq_lock, flags);
-- val = mtk_r32(eth, eth->tx_int_mask_reg);
-- mtk_w32(eth, val & ~mask, eth->tx_int_mask_reg);
-+ val = mtk_r32(eth, eth->soc->reg_map->tx_irq_mask);
-+ mtk_w32(eth, val & ~mask, eth->soc->reg_map->tx_irq_mask);
- spin_unlock_irqrestore(&eth->tx_irq_lock, flags);
- }
-
-@@ -640,8 +693,8 @@ static inline void mtk_tx_irq_enable(str
- u32 val;
-
- spin_lock_irqsave(&eth->tx_irq_lock, flags);
-- val = mtk_r32(eth, eth->tx_int_mask_reg);
-- mtk_w32(eth, val | mask, eth->tx_int_mask_reg);
-+ val = mtk_r32(eth, eth->soc->reg_map->tx_irq_mask);
-+ mtk_w32(eth, val | mask, eth->soc->reg_map->tx_irq_mask);
- spin_unlock_irqrestore(&eth->tx_irq_lock, flags);
- }
-
-@@ -651,8 +704,8 @@ static inline void mtk_rx_irq_disable(st
- u32 val;
-
- spin_lock_irqsave(&eth->rx_irq_lock, flags);
-- val = mtk_r32(eth, MTK_PDMA_INT_MASK);
-- mtk_w32(eth, val & ~mask, MTK_PDMA_INT_MASK);
-+ val = mtk_r32(eth, eth->soc->reg_map->pdma.irq_mask);
-+ mtk_w32(eth, val & ~mask, eth->soc->reg_map->pdma.irq_mask);
- spin_unlock_irqrestore(&eth->rx_irq_lock, flags);
- }
-
-@@ -662,8 +715,8 @@ static inline void mtk_rx_irq_enable(str
- u32 val;
-
- spin_lock_irqsave(&eth->rx_irq_lock, flags);
-- val = mtk_r32(eth, MTK_PDMA_INT_MASK);
-- mtk_w32(eth, val | mask, MTK_PDMA_INT_MASK);
-+ val = mtk_r32(eth, eth->soc->reg_map->pdma.irq_mask);
-+ mtk_w32(eth, val | mask, eth->soc->reg_map->pdma.irq_mask);
- spin_unlock_irqrestore(&eth->rx_irq_lock, flags);
- }
-
-@@ -714,39 +767,39 @@ void mtk_stats_update_mac(struct mtk_mac
- hw_stats->rx_checksum_errors +=
- mtk_r32(mac->hw, MT7628_SDM_CS_ERR);
- } else {
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- unsigned int offs = hw_stats->reg_offset;
- u64 stats;
-
-- hw_stats->rx_bytes += mtk_r32(mac->hw,
-- MTK_GDM1_RX_GBCNT_L + offs);
-- stats = mtk_r32(mac->hw, MTK_GDM1_RX_GBCNT_H + offs);
-+ hw_stats->rx_bytes += mtk_r32(mac->hw, reg_map->gdm1_cnt + offs);
-+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x4 + offs);
- if (stats)
- hw_stats->rx_bytes += (stats << 32);
- hw_stats->rx_packets +=
-- mtk_r32(mac->hw, MTK_GDM1_RX_GPCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x8 + offs);
- hw_stats->rx_overflow +=
-- mtk_r32(mac->hw, MTK_GDM1_RX_OERCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x10 + offs);
- hw_stats->rx_fcs_errors +=
-- mtk_r32(mac->hw, MTK_GDM1_RX_FERCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x14 + offs);
- hw_stats->rx_short_errors +=
-- mtk_r32(mac->hw, MTK_GDM1_RX_SERCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x18 + offs);
- hw_stats->rx_long_errors +=
-- mtk_r32(mac->hw, MTK_GDM1_RX_LENCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x1c + offs);
- hw_stats->rx_checksum_errors +=
-- mtk_r32(mac->hw, MTK_GDM1_RX_CERCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
- hw_stats->rx_flow_control_packets +=
-- mtk_r32(mac->hw, MTK_GDM1_RX_FCCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
- hw_stats->tx_skip +=
-- mtk_r32(mac->hw, MTK_GDM1_TX_SKIPCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
- hw_stats->tx_collisions +=
-- mtk_r32(mac->hw, MTK_GDM1_TX_COLCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
- hw_stats->tx_bytes +=
-- mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_L + offs);
-- stats = mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_H + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
- if (stats)
- hw_stats->tx_bytes += (stats << 32);
- hw_stats->tx_packets +=
-- mtk_r32(mac->hw, MTK_GDM1_TX_GPCNT + offs);
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
- }
-
- u64_stats_update_end(&hw_stats->syncp);
-@@ -886,10 +939,10 @@ static int mtk_init_fq_dma(struct mtk_et
- txd->txd4 = 0;
- }
-
-- mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
-- mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
-- mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
-- mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
-+ mtk_w32(eth, eth->phy_scratch_ring, soc->reg_map->qdma.fq_head);
-+ mtk_w32(eth, phy_ring_tail, soc->reg_map->qdma.fq_tail);
-+ mtk_w32(eth, (cnt << 16) | cnt, soc->reg_map->qdma.fq_count);
-+ mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, soc->reg_map->qdma.fq_blen);
-
- return 0;
- }
-@@ -1133,7 +1186,7 @@ static int mtk_tx_map(struct sk_buff *sk
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) ||
- !netdev_xmit_more())
-- mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR);
-+ mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr);
- } else {
- int next_idx;
-
-@@ -1450,6 +1503,7 @@ rx_done:
- static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
- unsigned int *done, unsigned int *bytes)
- {
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct mtk_tx_dma *desc;
- struct sk_buff *skb;
-@@ -1457,7 +1511,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
- u32 cpu, dma;
-
- cpu = ring->last_free_ptr;
-- dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
-+ dma = mtk_r32(eth, reg_map->qdma.drx_ptr);
-
- desc = mtk_qdma_phys_to_virt(ring, cpu);
-
-@@ -1492,7 +1546,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
- }
-
- ring->last_free_ptr = cpu;
-- mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
-+ mtk_w32(eth, cpu, reg_map->qdma.crx_ptr);
-
- return budget;
- }
-@@ -1585,24 +1639,25 @@ static void mtk_handle_status_irq(struct
- static int mtk_napi_tx(struct napi_struct *napi, int budget)
- {
- struct mtk_eth *eth = container_of(napi, struct mtk_eth, tx_napi);
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- int tx_done = 0;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
- mtk_handle_status_irq(eth);
-- mtk_w32(eth, MTK_TX_DONE_INT, eth->tx_int_status_reg);
-+ mtk_w32(eth, MTK_TX_DONE_INT, reg_map->tx_irq_status);
- tx_done = mtk_poll_tx(eth, budget);
-
- if (unlikely(netif_msg_intr(eth))) {
- dev_info(eth->dev,
- "done tx %d, intr 0x%08x/0x%x\n", tx_done,
-- mtk_r32(eth, eth->tx_int_status_reg),
-- mtk_r32(eth, eth->tx_int_mask_reg));
-+ mtk_r32(eth, reg_map->tx_irq_status),
-+ mtk_r32(eth, reg_map->tx_irq_mask));
- }
-
- if (tx_done == budget)
- return budget;
-
-- if (mtk_r32(eth, eth->tx_int_status_reg) & MTK_TX_DONE_INT)
-+ if (mtk_r32(eth, reg_map->tx_irq_status) & MTK_TX_DONE_INT)
- return budget;
-
- if (napi_complete_done(napi, tx_done))
-@@ -1614,6 +1669,7 @@ static int mtk_napi_tx(struct napi_struc
- static int mtk_napi_rx(struct napi_struct *napi, int budget)
- {
- struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- int rx_done_total = 0;
-
- mtk_handle_status_irq(eth);
-@@ -1621,21 +1677,21 @@ static int mtk_napi_rx(struct napi_struc
- do {
- int rx_done;
-
-- mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_STATUS);
-+ mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.irq_status);
- rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth);
- rx_done_total += rx_done;
-
- if (unlikely(netif_msg_intr(eth))) {
- dev_info(eth->dev,
- "done rx %d, intr 0x%08x/0x%x\n", rx_done,
-- mtk_r32(eth, MTK_PDMA_INT_STATUS),
-- mtk_r32(eth, MTK_PDMA_INT_MASK));
-+ mtk_r32(eth, reg_map->pdma.irq_status),
-+ mtk_r32(eth, reg_map->pdma.irq_mask));
- }
-
- if (rx_done_total == budget)
- return budget;
-
-- } while (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT);
-+ } while (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT);
-
- if (napi_complete_done(napi, rx_done_total))
- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
-@@ -1698,20 +1754,20 @@ static int mtk_tx_alloc(struct mtk_eth *
- */
- wmb();
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-- mtk_w32(eth, ring->phys, MTK_QTX_CTX_PTR);
-- mtk_w32(eth, ring->phys, MTK_QTX_DTX_PTR);
-+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-+ mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr);
-+ mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr);
- mtk_w32(eth,
- ring->phys + ((MTK_DMA_SIZE - 1) * sz),
-- MTK_QTX_CRX_PTR);
-- mtk_w32(eth, ring->last_free_ptr, MTK_QTX_DRX_PTR);
-+ soc->reg_map->qdma.crx_ptr);
-+ mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
-- MTK_QTX_CFG(0));
-+ soc->reg_map->qdma.qtx_cfg);
- } else {
- mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
- mtk_w32(eth, MTK_DMA_SIZE, MT7628_TX_MAX_CNT0);
- mtk_w32(eth, 0, MT7628_TX_CTX_IDX0);
-- mtk_w32(eth, MT7628_PST_DTX_IDX0, MTK_PDMA_RST_IDX);
-+ mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx);
- }
-
- return 0;
-@@ -1750,6 +1806,7 @@ static void mtk_tx_clean(struct mtk_eth
-
- 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;
- struct mtk_rx_ring *ring;
- int rx_data_len, rx_dma_size;
- int i;
-@@ -1818,16 +1875,18 @@ static int mtk_rx_alloc(struct mtk_eth *
- ring->dma_size = rx_dma_size;
- ring->calc_idx_update = false;
- ring->calc_idx = rx_dma_size - 1;
-- ring->crx_idx_reg = MTK_PRX_CRX_IDX_CFG(ring_no);
-+ ring->crx_idx_reg = reg_map->pdma.pcrx_ptr + ring_no * MTK_QRX_OFFSET;
- /* make sure that all changes to the dma ring are flushed before we
- * continue
- */
- wmb();
-
-- mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset);
-- mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset);
-+ mtk_w32(eth, ring->phys,
-+ reg_map->pdma.rx_ptr + ring_no * MTK_QRX_OFFSET + offset);
-+ mtk_w32(eth, rx_dma_size,
-+ reg_map->pdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET + offset);
- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset);
-- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset);
-+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), reg_map->pdma.rst_idx + offset);
-
- return 0;
- }
-@@ -2139,9 +2198,9 @@ static int mtk_dma_busy_wait(struct mtk_
- u32 val;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-- reg = MTK_QDMA_GLO_CFG;
-+ reg = eth->soc->reg_map->qdma.glo_cfg;
- else
-- reg = MTK_PDMA_GLO_CFG;
-+ reg = eth->soc->reg_map->pdma.glo_cfg;
-
- ret = readx_poll_timeout_atomic(__raw_readl, eth->base + reg, val,
- !(val & (MTK_RX_DMA_BUSY | MTK_TX_DMA_BUSY)),
-@@ -2199,8 +2258,8 @@ static int mtk_dma_init(struct mtk_eth *
- * automatically
- */
- mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN |
-- FC_THRES_MIN, MTK_QDMA_FC_THRES);
-- mtk_w32(eth, 0x0, MTK_QDMA_HRED2);
-+ FC_THRES_MIN, eth->soc->reg_map->qdma.fc_th);
-+ mtk_w32(eth, 0x0, eth->soc->reg_map->qdma.hred);
- }
-
- return 0;
-@@ -2274,13 +2333,14 @@ static irqreturn_t mtk_handle_irq_tx(int
- static irqreturn_t mtk_handle_irq(int irq, void *_eth)
- {
- struct mtk_eth *eth = _eth;
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
-
-- if (mtk_r32(eth, MTK_PDMA_INT_MASK) & MTK_RX_DONE_INT) {
-- if (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT)
-+ if (mtk_r32(eth, reg_map->pdma.irq_mask) & MTK_RX_DONE_INT) {
-+ if (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT)
- mtk_handle_irq_rx(irq, _eth);
- }
-- if (mtk_r32(eth, eth->tx_int_mask_reg) & MTK_TX_DONE_INT) {
-- if (mtk_r32(eth, eth->tx_int_status_reg) & MTK_TX_DONE_INT)
-+ 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)
- mtk_handle_irq_tx(irq, _eth);
- }
-
-@@ -2304,6 +2364,7 @@ static void mtk_poll_controller(struct n
- static int mtk_start_dma(struct mtk_eth *eth)
- {
- u32 rx_2b_offset = (NET_IP_ALIGN == 2) ? MTK_RX_2B_OFFSET : 0;
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- int err;
-
- err = mtk_dma_init(eth);
-@@ -2318,16 +2379,15 @@ static int mtk_start_dma(struct mtk_eth
- MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
- MTK_RX_DMA_EN | MTK_RX_2B_OFFSET |
- MTK_RX_BT_32DWORDS,
-- MTK_QDMA_GLO_CFG);
--
-+ reg_map->qdma.glo_cfg);
- mtk_w32(eth,
- MTK_RX_DMA_EN | rx_2b_offset |
- MTK_RX_BT_32DWORDS | MTK_MULTI_EN,
-- MTK_PDMA_GLO_CFG);
-+ 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,
-- MTK_PDMA_GLO_CFG);
-+ reg_map->pdma.glo_cfg);
- }
-
- return 0;
-@@ -2453,8 +2513,8 @@ static int mtk_stop(struct net_device *d
- cancel_work_sync(&eth->tx_dim.work);
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-- mtk_stop_dma(eth, MTK_QDMA_GLO_CFG);
-- mtk_stop_dma(eth, MTK_PDMA_GLO_CFG);
-+ mtk_stop_dma(eth, eth->soc->reg_map->qdma.glo_cfg);
-+ mtk_stop_dma(eth, eth->soc->reg_map->pdma.glo_cfg);
-
- mtk_dma_free(eth);
-
-@@ -2508,6 +2568,7 @@ static void mtk_dim_rx(struct work_struc
- {
- struct dim *dim = container_of(work, struct dim, work);
- struct mtk_eth *eth = container_of(dim, struct mtk_eth, rx_dim);
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct dim_cq_moder cur_profile;
- u32 val, cur;
-
-@@ -2515,7 +2576,7 @@ static void mtk_dim_rx(struct work_struc
- dim->profile_ix);
- spin_lock_bh(&eth->dim_lock);
-
-- val = mtk_r32(eth, MTK_PDMA_DELAY_INT);
-+ val = mtk_r32(eth, reg_map->pdma.delay_irq);
- val &= MTK_PDMA_DELAY_TX_MASK;
- val |= MTK_PDMA_DELAY_RX_EN;
-
-@@ -2525,9 +2586,9 @@ static void mtk_dim_rx(struct work_struc
- cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK);
- val |= cur << MTK_PDMA_DELAY_RX_PINT_SHIFT;
-
-- mtk_w32(eth, val, MTK_PDMA_DELAY_INT);
-+ mtk_w32(eth, val, reg_map->pdma.delay_irq);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-- mtk_w32(eth, val, MTK_QDMA_DELAY_INT);
-+ mtk_w32(eth, val, reg_map->qdma.delay_irq);
-
- spin_unlock_bh(&eth->dim_lock);
-
-@@ -2538,6 +2599,7 @@ static void mtk_dim_tx(struct work_struc
- {
- struct dim *dim = container_of(work, struct dim, work);
- struct mtk_eth *eth = container_of(dim, struct mtk_eth, tx_dim);
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct dim_cq_moder cur_profile;
- u32 val, cur;
-
-@@ -2545,7 +2607,7 @@ static void mtk_dim_tx(struct work_struc
- dim->profile_ix);
- spin_lock_bh(&eth->dim_lock);
-
-- val = mtk_r32(eth, MTK_PDMA_DELAY_INT);
-+ val = mtk_r32(eth, reg_map->pdma.delay_irq);
- val &= MTK_PDMA_DELAY_RX_MASK;
- val |= MTK_PDMA_DELAY_TX_EN;
-
-@@ -2555,9 +2617,9 @@ static void mtk_dim_tx(struct work_struc
- cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK);
- val |= cur << MTK_PDMA_DELAY_TX_PINT_SHIFT;
-
-- mtk_w32(eth, val, MTK_PDMA_DELAY_INT);
-+ mtk_w32(eth, val, reg_map->pdma.delay_irq);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-- mtk_w32(eth, val, MTK_QDMA_DELAY_INT);
-+ mtk_w32(eth, val, reg_map->qdma.delay_irq);
-
- spin_unlock_bh(&eth->dim_lock);
-
-@@ -2568,6 +2630,7 @@ static int mtk_hw_init(struct mtk_eth *e
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
- ETHSYS_DMA_AG_MAP_PPE;
-+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- int i, val, ret;
-
- if (test_and_set_bit(MTK_HW_INIT, &eth->state))
-@@ -2642,10 +2705,10 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_rx_irq_disable(eth, ~0);
-
- /* FE int grouping */
-- mtk_w32(eth, MTK_TX_DONE_INT, MTK_PDMA_INT_GRP1);
-- mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_GRP2);
-- mtk_w32(eth, MTK_TX_DONE_INT, MTK_QDMA_INT_GRP1);
-- mtk_w32(eth, MTK_RX_DONE_INT, MTK_QDMA_INT_GRP2);
-+ mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
-+ mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.int_grp + 4);
-+ mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
-+ mtk_w32(eth, MTK_RX_DONE_INT, reg_map->qdma.int_grp + 4);
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
- return 0;
-@@ -3177,14 +3240,6 @@ static int mtk_probe(struct platform_dev
- if (IS_ERR(eth->base))
- return PTR_ERR(eth->base);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-- eth->tx_int_mask_reg = MTK_QDMA_INT_MASK;
-- eth->tx_int_status_reg = MTK_QDMA_INT_STATUS;
-- } else {
-- eth->tx_int_mask_reg = MTK_PDMA_INT_MASK;
-- eth->tx_int_status_reg = MTK_PDMA_INT_STATUS;
-- }
--
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
- eth->rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA;
- eth->ip_align = NET_IP_ALIGN;
-@@ -3418,6 +3473,7 @@ static int mtk_remove(struct platform_de
- }
-
- static const struct mtk_soc_data mt2701_data = {
-+ .reg_map = &mtk_reg_map,
- .caps = MT7623_CAPS | MTK_HWLRO,
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
-@@ -3429,6 +3485,7 @@ static const struct mtk_soc_data mt2701_
- };
-
- static const struct mtk_soc_data mt7621_data = {
-+ .reg_map = &mtk_reg_map,
- .caps = MT7621_CAPS,
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7621_CLKS_BITMAP,
-@@ -3441,6 +3498,7 @@ static const struct mtk_soc_data mt7621_
- };
-
- static const struct mtk_soc_data mt7622_data = {
-+ .reg_map = &mtk_reg_map,
- .ana_rgc3 = 0x2028,
- .caps = MT7622_CAPS | MTK_HWLRO,
- .hw_features = MTK_HW_FEATURES,
-@@ -3454,6 +3512,7 @@ static const struct mtk_soc_data mt7622_
- };
-
- static const struct mtk_soc_data mt7623_data = {
-+ .reg_map = &mtk_reg_map,
- .caps = MT7623_CAPS | MTK_HWLRO,
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
-@@ -3466,6 +3525,7 @@ static const struct mtk_soc_data mt7623_
- };
-
- static const struct mtk_soc_data mt7629_data = {
-+ .reg_map = &mtk_reg_map,
- .ana_rgc3 = 0x128,
- .caps = MT7629_CAPS | MTK_HWLRO,
- .hw_features = MTK_HW_FEATURES,
-@@ -3478,6 +3538,7 @@ static const struct mtk_soc_data mt7629_
- };
-
- static const struct mtk_soc_data rt5350_data = {
-+ .reg_map = &mt7628_reg_map,
- .caps = MT7628_CAPS,
- .hw_features = MTK_HW_FEATURES_MT7628,
- .required_clks = MT7628_CLKS_BITMAP,
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -48,6 +48,8 @@
- #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM)
- #define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1))
-
-+#define MTK_QRX_OFFSET 0x10
-+
- #define MTK_MAX_RX_RING_NUM 4
- #define MTK_HW_LRO_DMA_SIZE 8
-
-@@ -100,18 +102,6 @@
- /* Unicast Filter MAC Address Register - High */
- #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
-
--/* PDMA RX Base Pointer Register */
--#define MTK_PRX_BASE_PTR0 0x900
--#define MTK_PRX_BASE_PTR_CFG(x) (MTK_PRX_BASE_PTR0 + (x * 0x10))
--
--/* PDMA RX Maximum Count Register */
--#define MTK_PRX_MAX_CNT0 0x904
--#define MTK_PRX_MAX_CNT_CFG(x) (MTK_PRX_MAX_CNT0 + (x * 0x10))
--
--/* PDMA RX CPU Pointer Register */
--#define MTK_PRX_CRX_IDX0 0x908
--#define MTK_PRX_CRX_IDX_CFG(x) (MTK_PRX_CRX_IDX0 + (x * 0x10))
--
- /* PDMA HW LRO Control Registers */
- #define MTK_PDMA_LRO_CTRL_DW0 0x980
- #define MTK_LRO_EN BIT(0)
-@@ -126,18 +116,19 @@
- #define MTK_ADMA_MODE BIT(15)
- #define MTK_LRO_MIN_RXD_SDL (MTK_HW_LRO_SDL_REMAIN_ROOM << 16)
-
--/* PDMA Global Configuration Register */
--#define MTK_PDMA_GLO_CFG 0xa04
-+#define MTK_RX_DMA_LRO_EN BIT(8)
- #define MTK_MULTI_EN BIT(10)
- #define MTK_PDMA_SIZE_8DWORDS (1 << 4)
-
-+/* PDMA Global Configuration Register */
-+#define MTK_PDMA_LRO_SDL 0x3000
-+#define MTK_RX_CFG_SDL_OFFSET 16
-+
- /* PDMA Reset Index Register */
--#define MTK_PDMA_RST_IDX 0xa08
- #define MTK_PST_DRX_IDX0 BIT(16)
- #define MTK_PST_DRX_IDX_CFG(x) (MTK_PST_DRX_IDX0 << (x))
-
- /* PDMA Delay Interrupt Register */
--#define MTK_PDMA_DELAY_INT 0xa0c
- #define MTK_PDMA_DELAY_RX_MASK GENMASK(15, 0)
- #define MTK_PDMA_DELAY_RX_EN BIT(15)
- #define MTK_PDMA_DELAY_RX_PINT_SHIFT 8
-@@ -151,19 +142,9 @@
- #define MTK_PDMA_DELAY_PINT_MASK 0x7f
- #define MTK_PDMA_DELAY_PTIME_MASK 0xff
-
--/* PDMA Interrupt Status Register */
--#define MTK_PDMA_INT_STATUS 0xa20
--
--/* PDMA Interrupt Mask Register */
--#define MTK_PDMA_INT_MASK 0xa28
--
- /* PDMA HW LRO Alter Flow Delta Register */
- #define MTK_PDMA_LRO_ALT_SCORE_DELTA 0xa4c
-
--/* PDMA Interrupt grouping registers */
--#define MTK_PDMA_INT_GRP1 0xa50
--#define MTK_PDMA_INT_GRP2 0xa54
--
- /* 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))
-@@ -185,26 +166,9 @@
- #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3)
-
- /* QDMA TX Queue Configuration Registers */
--#define MTK_QTX_CFG(x) (0x1800 + (x * 0x10))
- #define QDMA_RES_THRES 4
-
--/* QDMA TX Queue Scheduler Registers */
--#define MTK_QTX_SCH(x) (0x1804 + (x * 0x10))
--
--/* QDMA RX Base Pointer Register */
--#define MTK_QRX_BASE_PTR0 0x1900
--
--/* QDMA RX Maximum Count Register */
--#define MTK_QRX_MAX_CNT0 0x1904
--
--/* QDMA RX CPU Pointer Register */
--#define MTK_QRX_CRX_IDX0 0x1908
--
--/* QDMA RX DMA Pointer Register */
--#define MTK_QRX_DRX_IDX0 0x190C
--
- /* QDMA Global Configuration Register */
--#define MTK_QDMA_GLO_CFG 0x1A04
- #define MTK_RX_2B_OFFSET BIT(31)
- #define MTK_RX_BT_32DWORDS (3 << 11)
- #define MTK_NDP_CO_PRO BIT(10)
-@@ -216,20 +180,12 @@
- #define MTK_TX_DMA_EN BIT(0)
- #define MTK_DMA_BUSY_TIMEOUT_US 1000000
-
--/* QDMA Reset Index Register */
--#define MTK_QDMA_RST_IDX 0x1A08
--
--/* QDMA Delay Interrupt Register */
--#define MTK_QDMA_DELAY_INT 0x1A0C
--
- /* QDMA Flow Control Register */
--#define MTK_QDMA_FC_THRES 0x1A10
- #define FC_THRES_DROP_MODE BIT(20)
- #define FC_THRES_DROP_EN (7 << 16)
- #define FC_THRES_MIN 0x4444
-
- /* QDMA Interrupt Status Register */
--#define MTK_QDMA_INT_STATUS 0x1A18
- #define MTK_RX_DONE_DLY BIT(30)
- #define MTK_TX_DONE_DLY BIT(28)
- #define MTK_RX_DONE_INT3 BIT(19)
-@@ -244,55 +200,8 @@
- #define MTK_TX_DONE_INT MTK_TX_DONE_DLY
-
- /* QDMA Interrupt grouping registers */
--#define MTK_QDMA_INT_GRP1 0x1a20
--#define MTK_QDMA_INT_GRP2 0x1a24
- #define MTK_RLS_DONE_INT BIT(0)
-
--/* QDMA Interrupt Status Register */
--#define MTK_QDMA_INT_MASK 0x1A1C
--
--/* QDMA Interrupt Mask Register */
--#define MTK_QDMA_HRED2 0x1A44
--
--/* QDMA TX Forward CPU Pointer Register */
--#define MTK_QTX_CTX_PTR 0x1B00
--
--/* QDMA TX Forward DMA Pointer Register */
--#define MTK_QTX_DTX_PTR 0x1B04
--
--/* QDMA TX Release CPU Pointer Register */
--#define MTK_QTX_CRX_PTR 0x1B10
--
--/* QDMA TX Release DMA Pointer Register */
--#define MTK_QTX_DRX_PTR 0x1B14
--
--/* QDMA FQ Head Pointer Register */
--#define MTK_QDMA_FQ_HEAD 0x1B20
--
--/* QDMA FQ Head Pointer Register */
--#define MTK_QDMA_FQ_TAIL 0x1B24
--
--/* QDMA FQ Free Page Counter Register */
--#define MTK_QDMA_FQ_CNT 0x1B28
--
--/* QDMA FQ Free Page Buffer Length Register */
--#define MTK_QDMA_FQ_BLEN 0x1B2C
--
--/* GMA1 counter / statics register */
--#define MTK_GDM1_RX_GBCNT_L 0x2400
--#define MTK_GDM1_RX_GBCNT_H 0x2404
--#define MTK_GDM1_RX_GPCNT 0x2408
--#define MTK_GDM1_RX_OERCNT 0x2410
--#define MTK_GDM1_RX_FERCNT 0x2414
--#define MTK_GDM1_RX_SERCNT 0x2418
--#define MTK_GDM1_RX_LENCNT 0x241c
--#define MTK_GDM1_RX_CERCNT 0x2420
--#define MTK_GDM1_RX_FCCNT 0x2424
--#define MTK_GDM1_TX_SKIPCNT 0x2428
--#define MTK_GDM1_TX_COLCNT 0x242c
--#define MTK_GDM1_TX_GBCNT_L 0x2430
--#define MTK_GDM1_TX_GBCNT_H 0x2434
--#define MTK_GDM1_TX_GPCNT 0x2438
- #define MTK_STAT_OFFSET 0x40
-
- #define MTK_WDMA0_BASE 0x2800
-@@ -854,8 +763,46 @@ struct mtk_tx_dma_desc_info {
- u8 last:1;
- };
-
-+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 int_grp;
-+ } pdma;
-+ struct {
-+ u32 qtx_cfg; /* tx queue configuration */
-+ u32 rx_ptr; /* rx base pointer */
-+ u32 rx_cnt_cfg; /* rx max count configuration */
-+ u32 qcrx_ptr; /* rx cpu pointer */
-+ u32 glo_cfg; /* global configuration */
-+ u32 rst_idx; /* reset index */
-+ u32 delay_irq; /* delay interrupt */
-+ u32 fc_th; /* flow control */
-+ u32 int_grp;
-+ u32 hred; /* interrupt mask */
-+ u32 ctx_ptr; /* tx acquire cpu pointer */
-+ u32 dtx_ptr; /* tx acquire dma pointer */
-+ u32 crx_ptr; /* tx release cpu pointer */
-+ u32 drx_ptr; /* tx release dma pointer */
-+ u32 fq_head; /* fq head pointer */
-+ u32 fq_tail; /* fq tail pointer */
-+ u32 fq_count; /* fq free page count */
-+ u32 fq_blen; /* fq free page buffer length */
-+ } qdma;
-+ u32 gdm1_cnt;
-+};
-+
- /* struct mtk_eth_data - This is the structure holding all differences
- * among various plaforms
-+ * @reg_map Soc register map.
- * @ana_rgc3: The offset for register ANA_RGC3 related to
- * sgmiisys syscon
- * @caps Flags shown the extra capability for the SoC
-@@ -868,6 +815,7 @@ struct mtk_tx_dma_desc_info {
- * @rxd_size Rx DMA descriptor size.
- */
- struct mtk_soc_data {
-+ const struct mtk_reg_map *reg_map;
- u32 ana_rgc3;
- u32 caps;
- u32 required_clks;
-@@ -995,8 +943,6 @@ struct mtk_eth {
- u32 tx_bytes;
- struct dim tx_dim;
-
-- u32 tx_int_mask_reg;
-- u32 tx_int_status_reg;
- u32 rx_dma_l4_valid;
- int ip_align;
-
diff --git a/target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch b/target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch
deleted file mode 100644
index d55ab77211..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch
+++ /dev/null
@@ -1,917 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:36 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
-
-Introduce MTK_NETSYS_V2 support. MTK_NETSYS_V2 defines 32B TX/RX DMA
-descriptors.
-This is a preliminary patch to add mt7986 ethernet support.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -873,8 +873,8 @@ static inline int mtk_max_buf_size(int f
- return buf_size;
- }
-
--static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd,
-- struct mtk_rx_dma *dma_rxd)
-+static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd,
-+ struct mtk_rx_dma_v2 *dma_rxd)
- {
- rxd->rxd2 = READ_ONCE(dma_rxd->rxd2);
- if (!(rxd->rxd2 & RX_DMA_DONE))
-@@ -883,6 +883,10 @@ static inline bool mtk_rx_get_desc(struc
- rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
- rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
- rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
-+ rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
-+ }
-
- return true;
- }
-@@ -927,7 +931,7 @@ static int mtk_init_fq_dma(struct mtk_et
- phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1);
-
- for (i = 0; i < cnt; i++) {
-- struct mtk_tx_dma *txd;
-+ struct mtk_tx_dma_v2 *txd;
-
- txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size;
- txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
-@@ -937,6 +941,12 @@ static int mtk_init_fq_dma(struct mtk_et
-
- txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
- txd->txd4 = 0;
-+ if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+ txd->txd5 = 0;
-+ txd->txd6 = 0;
-+ txd->txd7 = 0;
-+ txd->txd8 = 0;
-+ }
- }
-
- mtk_w32(eth, eth->phy_scratch_ring, soc->reg_map->qdma.fq_head);
-@@ -1040,10 +1050,12 @@ static void setup_tx_buf(struct mtk_eth
- }
- }
-
--static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc,
-- struct mtk_tx_dma_desc_info *info)
-+static void mtk_tx_set_dma_desc_v1(struct net_device *dev, void *txd,
-+ struct mtk_tx_dma_desc_info *info)
- {
- struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+ struct mtk_tx_dma *desc = txd;
- u32 data;
-
- WRITE_ONCE(desc->txd1, info->addr);
-@@ -1067,6 +1079,59 @@ static void mtk_tx_set_dma_desc(struct n
- WRITE_ONCE(desc->txd4, data);
- }
-
-+static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd,
-+ struct mtk_tx_dma_desc_info *info)
-+{
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_tx_dma_v2 *desc = txd;
-+ struct mtk_eth *eth = mac->hw;
-+ u32 data;
-+
-+ WRITE_ONCE(desc->txd1, info->addr);
-+
-+ data = TX_DMA_PLEN0(info->size);
-+ if (info->last)
-+ data |= TX_DMA_LS0;
-+ WRITE_ONCE(desc->txd3, data);
-+
-+ if (!info->qid && mac->id)
-+ info->qid = MTK_QDMA_GMAC2_QID;
-+
-+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+ data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
-+ WRITE_ONCE(desc->txd4, data);
-+
-+ data = 0;
-+ if (info->first) {
-+ if (info->gso)
-+ data |= TX_DMA_TSO_V2;
-+ /* tx checksum offload */
-+ if (info->csum)
-+ data |= TX_DMA_CHKSUM_V2;
-+ }
-+ WRITE_ONCE(desc->txd5, data);
-+
-+ data = 0;
-+ if (info->first && info->vlan)
-+ data |= TX_DMA_INS_VLAN_V2 | info->vlan_tci;
-+ WRITE_ONCE(desc->txd6, data);
-+
-+ WRITE_ONCE(desc->txd7, 0);
-+ WRITE_ONCE(desc->txd8, 0);
-+}
-+
-+static void mtk_tx_set_dma_desc(struct net_device *dev, void *txd,
-+ struct mtk_tx_dma_desc_info *info)
-+{
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ mtk_tx_set_dma_desc_v2(dev, txd, info);
-+ else
-+ mtk_tx_set_dma_desc_v1(dev, txd, info);
-+}
-+
- static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
- int tx_num, struct mtk_tx_ring *ring, bool gso)
- {
-@@ -1075,6 +1140,7 @@ static int mtk_tx_map(struct sk_buff *sk
- .gso = gso,
- .csum = skb->ip_summed == CHECKSUM_PARTIAL,
- .vlan = skb_vlan_tag_present(skb),
-+ .qid = skb->mark & MTK_QDMA_TX_MASK,
- .vlan_tci = skb_vlan_tag_get(skb),
- .first = true,
- .last = !skb_is_nonlinear(skb),
-@@ -1134,7 +1200,9 @@ static int mtk_tx_map(struct sk_buff *sk
- }
-
- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
-- txd_info.size = min(frag_size, MTK_TX_DMA_BUF_LEN);
-+ txd_info.size = min_t(unsigned int, frag_size,
-+ soc->txrx.dma_max_len);
-+ txd_info.qid = skb->mark & MTK_QDMA_TX_MASK;
- txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
- !(frag_size - txd_info.size);
- txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
-@@ -1215,17 +1283,16 @@ err_dma:
- return -ENOMEM;
- }
-
--static inline int mtk_cal_txd_req(struct sk_buff *skb)
-+static int mtk_cal_txd_req(struct mtk_eth *eth, struct sk_buff *skb)
- {
-- int i, nfrags;
-+ int i, nfrags = 1;
- skb_frag_t *frag;
-
-- nfrags = 1;
- if (skb_is_gso(skb)) {
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- frag = &skb_shinfo(skb)->frags[i];
- nfrags += DIV_ROUND_UP(skb_frag_size(frag),
-- MTK_TX_DMA_BUF_LEN);
-+ eth->soc->txrx.dma_max_len);
- }
- } else {
- nfrags += skb_shinfo(skb)->nr_frags;
-@@ -1277,7 +1344,7 @@ static netdev_tx_t mtk_start_xmit(struct
- if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
- goto drop;
-
-- tx_num = mtk_cal_txd_req(skb);
-+ tx_num = mtk_cal_txd_req(eth, skb);
- if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
- netif_stop_queue(dev);
- netif_err(eth, tx_queued, dev,
-@@ -1369,7 +1436,7 @@ static int mtk_poll_rx(struct napi_struc
- int idx;
- struct sk_buff *skb;
- u8 *data, *new_data;
-- struct mtk_rx_dma *rxd, trxd;
-+ struct mtk_rx_dma_v2 *rxd, trxd;
- int done = 0, bytes = 0;
-
- while (done < budget) {
-@@ -1377,7 +1444,7 @@ static int mtk_poll_rx(struct napi_struc
- unsigned int pktlen;
- dma_addr_t dma_addr;
- u32 hash, reason;
-- int mac;
-+ int mac = 0;
-
- ring = mtk_get_rx_ring(eth);
- if (unlikely(!ring))
-@@ -1387,16 +1454,15 @@ static int mtk_poll_rx(struct napi_struc
- rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size;
- data = ring->data[idx];
-
-- if (!mtk_rx_get_desc(&trxd, rxd))
-+ if (!mtk_rx_get_desc(eth, &trxd, rxd))
- break;
-
- /* find out which mac the packet come from. values start at 1 */
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) ||
-- (trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-- mac = 0;
-- else
-- mac = ((trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
-- RX_DMA_FPORT_MASK) - 1;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
-+ else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-+ mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
-
- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
- !eth->netdev[mac]))
-@@ -1442,7 +1508,7 @@ static int mtk_poll_rx(struct napi_struc
- pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
- skb->dev = netdev;
- skb_put(skb, pktlen);
-- if (trxd.rxd4 & eth->rx_dma_l4_valid)
-+ if (trxd.rxd4 & eth->soc->txrx.rx_dma_l4_valid)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb_checksum_none_assert(skb);
-@@ -1460,10 +1526,25 @@ static int mtk_poll_rx(struct napi_struc
- mtk_ppe_check_skb(eth->ppe, skb,
- trxd.rxd4 & MTK_RXD4_FOE_ENTRY);
-
-- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
-- (trxd.rxd2 & RX_DMA_VTAG))
-- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-- RX_DMA_VID(trxd.rxd3));
-+ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (trxd.rxd3 & RX_DMA_VTAG_V2)
-+ __vlan_hwaccel_put_tag(skb,
-+ htons(RX_DMA_VPID(trxd.rxd4)),
-+ RX_DMA_VID(trxd.rxd4));
-+ } else if (trxd.rxd2 & RX_DMA_VTAG) {
-+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-+ RX_DMA_VID(trxd.rxd3));
-+ }
-+
-+ /* If the device is attached to a dsa switch, the special
-+ * tag inserted in VLAN field by hw switch can * be offloaded
-+ * by RX HW VLAN offload. Clear vlan info.
-+ */
-+ if (netdev_uses_dsa(netdev))
-+ __vlan_hwaccel_clear_tag(skb);
-+ }
-+
- skb_record_rx_queue(skb, 0);
- napi_gro_receive(napi, skb);
-
-@@ -1475,7 +1556,7 @@ release_desc:
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
- rxd->rxd2 = RX_DMA_LSO;
- else
-- rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size);
-+ rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
- ring->calc_idx = idx;
-
-@@ -1677,7 +1758,8 @@ static int mtk_napi_rx(struct napi_struc
- do {
- int rx_done;
-
-- mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.irq_status);
-+ mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask,
-+ reg_map->pdma.irq_status);
- rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth);
- rx_done_total += rx_done;
-
-@@ -1691,10 +1773,11 @@ static int mtk_napi_rx(struct napi_struc
- if (rx_done_total == budget)
- return budget;
-
-- } while (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT);
-+ } while (mtk_r32(eth, reg_map->pdma.irq_status) &
-+ eth->soc->txrx.rx_irq_done_mask);
-
- if (napi_complete_done(napi, rx_done_total))
-- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
-+ mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
-
- return rx_done_total;
- }
-@@ -1704,7 +1787,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_ring *ring = &eth->tx_ring;
- int i, sz = soc->txrx.txd_size;
-- struct mtk_tx_dma *txd;
-+ struct mtk_tx_dma_v2 *txd;
-
- ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf),
- GFP_KERNEL);
-@@ -1724,13 +1807,19 @@ static int mtk_tx_alloc(struct mtk_eth *
- txd->txd2 = next_ptr;
- txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
- txd->txd4 = 0;
-+ if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+ txd->txd5 = 0;
-+ txd->txd6 = 0;
-+ txd->txd7 = 0;
-+ txd->txd8 = 0;
-+ }
- }
-
- /* On MT7688 (PDMA only) this driver uses the ring->dma structs
- * only as the framework. The real HW descriptors are the PDMA
- * descriptors in ring->dma_pdma.
- */
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
- &ring->phys_pdma, GFP_KERNEL);
- if (!ring->dma_pdma)
-@@ -1810,13 +1899,11 @@ static int mtk_rx_alloc(struct mtk_eth *
- struct mtk_rx_ring *ring;
- int rx_data_len, rx_dma_size;
- int i;
-- u32 offset = 0;
-
- if (rx_flag == MTK_RX_FLAGS_QDMA) {
- if (ring_no)
- return -EINVAL;
- ring = &eth->rx_ring_qdma;
-- offset = 0x1000;
- } else {
- ring = &eth->rx_ring[ring_no];
- }
-@@ -1852,7 +1939,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- return -ENOMEM;
-
- for (i = 0; i < rx_dma_size; i++) {
-- struct mtk_rx_dma *rxd;
-+ struct mtk_rx_dma_v2 *rxd;
-
- dma_addr_t dma_addr = dma_map_single(eth->dma_dev,
- ring->data[i] + NET_SKB_PAD + eth->ip_align,
-@@ -1867,26 +1954,47 @@ static int mtk_rx_alloc(struct mtk_eth *
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
- rxd->rxd2 = RX_DMA_LSO;
- else
-- rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size);
-+ rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
- rxd->rxd3 = 0;
- rxd->rxd4 = 0;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ rxd->rxd5 = 0;
-+ rxd->rxd6 = 0;
-+ rxd->rxd7 = 0;
-+ rxd->rxd8 = 0;
-+ }
- }
- ring->dma_size = rx_dma_size;
- ring->calc_idx_update = false;
- ring->calc_idx = rx_dma_size - 1;
-- ring->crx_idx_reg = reg_map->pdma.pcrx_ptr + ring_no * MTK_QRX_OFFSET;
-+ if (rx_flag == MTK_RX_FLAGS_QDMA)
-+ ring->crx_idx_reg = reg_map->qdma.qcrx_ptr +
-+ ring_no * MTK_QRX_OFFSET;
-+ else
-+ ring->crx_idx_reg = reg_map->pdma.pcrx_ptr +
-+ ring_no * MTK_QRX_OFFSET;
- /* make sure that all changes to the dma ring are flushed before we
- * continue
- */
- wmb();
-
-- mtk_w32(eth, ring->phys,
-- reg_map->pdma.rx_ptr + ring_no * MTK_QRX_OFFSET + offset);
-- mtk_w32(eth, rx_dma_size,
-- reg_map->pdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET + offset);
-- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset);
-- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), reg_map->pdma.rst_idx + offset);
-+ if (rx_flag == MTK_RX_FLAGS_QDMA) {
-+ mtk_w32(eth, ring->phys,
-+ reg_map->qdma.rx_ptr + ring_no * MTK_QRX_OFFSET);
-+ mtk_w32(eth, rx_dma_size,
-+ reg_map->qdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET);
-+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no),
-+ reg_map->qdma.rst_idx);
-+ } else {
-+ mtk_w32(eth, ring->phys,
-+ reg_map->pdma.rx_ptr + ring_no * MTK_QRX_OFFSET);
-+ mtk_w32(eth, rx_dma_size,
-+ reg_map->pdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET);
-+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no),
-+ reg_map->pdma.rst_idx);
-+ }
-+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
-
- return 0;
- }
-@@ -2311,7 +2419,7 @@ static irqreturn_t mtk_handle_irq_rx(int
- eth->rx_events++;
- if (likely(napi_schedule_prep(&eth->rx_napi))) {
- __napi_schedule(&eth->rx_napi);
-- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
-+ mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
- }
-
- return IRQ_HANDLED;
-@@ -2335,8 +2443,10 @@ static irqreturn_t mtk_handle_irq(int ir
- struct mtk_eth *eth = _eth;
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
-
-- if (mtk_r32(eth, reg_map->pdma.irq_mask) & MTK_RX_DONE_INT) {
-- if (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT)
-+ if (mtk_r32(eth, reg_map->pdma.irq_mask) &
-+ eth->soc->txrx.rx_irq_done_mask) {
-+ if (mtk_r32(eth, reg_map->pdma.irq_status) &
-+ eth->soc->txrx.rx_irq_done_mask)
- mtk_handle_irq_rx(irq, _eth);
- }
- if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) {
-@@ -2354,16 +2464,16 @@ static void mtk_poll_controller(struct n
- struct mtk_eth *eth = mac->hw;
-
- mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
-- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
-+ mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
- mtk_handle_irq_rx(eth->irq[2], dev);
- mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
-+ mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
- }
- #endif
-
- static int mtk_start_dma(struct mtk_eth *eth)
- {
-- u32 rx_2b_offset = (NET_IP_ALIGN == 2) ? MTK_RX_2B_OFFSET : 0;
-+ u32 val, rx_2b_offset = (NET_IP_ALIGN == 2) ? MTK_RX_2B_OFFSET : 0;
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- int err;
-
-@@ -2374,12 +2484,19 @@ static int mtk_start_dma(struct mtk_eth
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-- mtk_w32(eth,
-- MTK_TX_WB_DDONE | MTK_TX_DMA_EN |
-- MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
-- MTK_RX_DMA_EN | MTK_RX_2B_OFFSET |
-- MTK_RX_BT_32DWORDS,
-- reg_map->qdma.glo_cfg);
-+ val = mtk_r32(eth, reg_map->qdma.glo_cfg);
-+ val |= MTK_TX_DMA_EN | MTK_RX_DMA_EN |
-+ MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
-+ MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
-+ MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
-+ MTK_CHK_DDONE_EN;
-+ else
-+ 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,
-@@ -2453,7 +2570,7 @@ static int mtk_open(struct net_device *d
- napi_enable(&eth->tx_napi);
- napi_enable(&eth->rx_napi);
- mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
-+ mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
- refcount_set(&eth->dma_refcnt, 1);
- }
- else
-@@ -2505,7 +2622,7 @@ static int mtk_stop(struct net_device *d
- mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
-
- mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
-- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
-+ mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
- napi_disable(&eth->tx_napi);
- napi_disable(&eth->rx_napi);
-
-@@ -2665,9 +2782,25 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
- }
-
-- /* Non-MT7628 handling... */
-- ethsys_reset(eth, RSTCTRL_FE);
-- ethsys_reset(eth, RSTCTRL_PPE);
-+ val = RSTCTRL_FE | RSTCTRL_PPE;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-+
-+ val |= RSTCTRL_ETH;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1;
-+ }
-+
-+ ethsys_reset(eth, val);
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-+ 0x3ffffff);
-+
-+ /* Set FE to PDMAv2 if necessary */
-+ val = mtk_r32(eth, MTK_FE_GLO_MISC);
-+ mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
-+ }
-
- if (eth->pctl) {
- /* Set GE2 driving and slew rate */
-@@ -2706,11 +2839,47 @@ static int mtk_hw_init(struct mtk_eth *e
-
- /* FE int grouping */
- mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
-- mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.int_grp + 4);
-+ mtk_w32(eth, eth->soc->txrx.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, MTK_RX_DONE_INT, reg_map->qdma.int_grp + 4);
-+ mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ /* PSE should not drop port8 and port9 packets */
-+ mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-+
-+ /* PSE Free Queue Flow Control */
-+ mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2);
-+
-+ /* PSE config input queue threshold */
-+ mtk_w32(eth, 0x001a000e, PSE_IQ_REV(1));
-+ mtk_w32(eth, 0x01ff001a, PSE_IQ_REV(2));
-+ mtk_w32(eth, 0x000e01ff, PSE_IQ_REV(3));
-+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(4));
-+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(5));
-+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(6));
-+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(7));
-+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(8));
-+
-+ /* PSE config output queue threshold */
-+ mtk_w32(eth, 0x000f000a, PSE_OQ_TH(1));
-+ mtk_w32(eth, 0x001a000f, PSE_OQ_TH(2));
-+ mtk_w32(eth, 0x000f001a, PSE_OQ_TH(3));
-+ mtk_w32(eth, 0x01ff000f, PSE_OQ_TH(4));
-+ mtk_w32(eth, 0x000f000f, PSE_OQ_TH(5));
-+ mtk_w32(eth, 0x0006000f, PSE_OQ_TH(6));
-+ mtk_w32(eth, 0x00060006, PSE_OQ_TH(7));
-+ mtk_w32(eth, 0x00060006, PSE_OQ_TH(8));
-+
-+ /* GDM and CDM Threshold */
-+ mtk_w32(eth, 0x00000004, MTK_GDM2_THRES);
-+ mtk_w32(eth, 0x00000004, MTK_CDMW0_THRES);
-+ mtk_w32(eth, 0x00000004, MTK_CDMW1_THRES);
-+ mtk_w32(eth, 0x00000004, MTK_CDME0_THRES);
-+ mtk_w32(eth, 0x00000004, MTK_CDME1_THRES);
-+ mtk_w32(eth, 0x00000004, MTK_CDMM_THRES);
-+ }
-+
- return 0;
-
- err_disable_pm:
-@@ -3240,12 +3409,8 @@ static int mtk_probe(struct platform_dev
- if (IS_ERR(eth->base))
- return PTR_ERR(eth->base);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
-- eth->rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
- eth->ip_align = NET_IP_ALIGN;
-- } else {
-- eth->rx_dma_l4_valid = RX_DMA_L4_VALID;
-- }
-
- spin_lock_init(&eth->page_lock);
- spin_lock_init(&eth->tx_irq_lock);
-@@ -3481,6 +3646,10 @@ static const struct mtk_soc_data mt2701_
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
-@@ -3494,6 +3663,10 @@ static const struct mtk_soc_data mt7621_
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
-@@ -3508,6 +3681,10 @@ static const struct mtk_soc_data mt7622_
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
-@@ -3521,6 +3698,10 @@ static const struct mtk_soc_data mt7623_
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
-@@ -3534,6 +3715,10 @@ static const struct mtk_soc_data mt7629_
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
-@@ -3546,6 +3731,10 @@ static const struct mtk_soc_data rt5350_
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -23,6 +23,7 @@
- #define MTK_MAX_RX_LENGTH 1536
- #define MTK_MAX_RX_LENGTH_2K 2048
- #define MTK_TX_DMA_BUF_LEN 0x3fff
-+#define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_DMA_SIZE 512
- #define MTK_NAPI_WEIGHT 64
- #define MTK_MAC_COUNT 2
-@@ -83,6 +84,10 @@
- #define MTK_CDMQ_IG_CTRL 0x1400
- #define MTK_CDMQ_STAG_EN BIT(0)
-
-+/* CDMP Ingress Control Register */
-+#define MTK_CDMP_IG_CTRL 0x400
-+#define MTK_CDMP_STAG_EN BIT(0)
-+
- /* CDMP Exgress Control Register */
- #define MTK_CDMP_EG_CTRL 0x404
-
-@@ -102,13 +107,38 @@
- /* Unicast Filter MAC Address Register - High */
- #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
-
-+/* FE global misc reg*/
-+#define MTK_FE_GLO_MISC 0x124
-+
-+/* PSE Free Queue Flow Control */
-+#define PSE_FQFC_CFG1 0x100
-+#define PSE_FQFC_CFG2 0x104
-+#define PSE_DROP_CFG 0x108
-+
-+/* PSE Input Queue Reservation Register*/
-+#define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2))
-+
-+/* PSE Output Queue Threshold Register*/
-+#define PSE_OQ_TH(x) (0x160 + (((x) - 1) << 2))
-+
-+/* GDM and CDM Threshold */
-+#define MTK_GDM2_THRES 0x1530
-+#define MTK_CDMW0_THRES 0x164c
-+#define MTK_CDMW1_THRES 0x1650
-+#define MTK_CDME0_THRES 0x1654
-+#define MTK_CDME1_THRES 0x1658
-+#define MTK_CDMM_THRES 0x165c
-+
- /* PDMA HW LRO Control Registers */
- #define MTK_PDMA_LRO_CTRL_DW0 0x980
- #define MTK_LRO_EN BIT(0)
- #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)
- #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
-@@ -180,6 +210,13 @@
- #define MTK_TX_DMA_EN BIT(0)
- #define MTK_DMA_BUSY_TIMEOUT_US 1000000
-
-+/* QDMA V2 Global Configuration Register */
-+#define MTK_CHK_DDONE_EN BIT(28)
-+#define MTK_DMAD_WR_WDONE BIT(26)
-+#define MTK_WCOMP_EN BIT(24)
-+#define MTK_RESV_BUF (0x40 << 16)
-+#define MTK_MUTLI_CNT (0x4 << 12)
-+
- /* QDMA Flow Control Register */
- #define FC_THRES_DROP_MODE BIT(20)
- #define FC_THRES_DROP_EN (7 << 16)
-@@ -199,11 +236,32 @@
- #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)
-+
- /* QDMA Interrupt grouping registers */
- #define MTK_RLS_DONE_INT BIT(0)
-
- #define MTK_STAT_OFFSET 0x40
-
-+/* QDMA TX NUM */
-+#define MTK_QDMA_TX_NUM 16
-+#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1)
-+#define QID_BITS_V2(x) (((x) & 0x3f) << 16)
-+#define MTK_QDMA_GMAC2_QID 8
-+
-+#define MTK_TX_DMA_BUF_SHIFT 8
-+
-+/* QDMA V2 descriptor txd6 */
-+#define TX_DMA_INS_VLAN_V2 BIT(16)
-+/* QDMA V2 descriptor txd5 */
-+#define TX_DMA_CHKSUM_V2 (0x7 << 28)
-+#define TX_DMA_TSO_V2 BIT(31)
-+
-+/* QDMA V2 descriptor txd4 */
-+#define TX_DMA_FPORT_SHIFT_V2 8
-+#define TX_DMA_FPORT_MASK_V2 0xf
-+#define TX_DMA_SWC_V2 BIT(30)
-+
- #define MTK_WDMA0_BASE 0x2800
- #define MTK_WDMA1_BASE 0x2c00
-
-@@ -217,10 +275,9 @@
- /* QDMA descriptor txd3 */
- #define TX_DMA_OWNER_CPU BIT(31)
- #define TX_DMA_LS0 BIT(30)
--#define TX_DMA_PLEN0(_x) (((_x) & MTK_TX_DMA_BUF_LEN) << 16)
--#define TX_DMA_PLEN1(_x) ((_x) & MTK_TX_DMA_BUF_LEN)
-+#define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
-+#define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len)
- #define TX_DMA_SWC BIT(14)
--#define TX_DMA_SDL(_x) (((_x) & 0x3fff) << 16)
-
- /* PDMA on MT7628 */
- #define TX_DMA_DONE BIT(31)
-@@ -230,12 +287,14 @@
- /* QDMA descriptor rxd2 */
- #define RX_DMA_DONE BIT(31)
- #define RX_DMA_LSO BIT(30)
--#define RX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16)
--#define RX_DMA_GET_PLEN0(_x) (((_x) >> 16) & 0x3fff)
-+#define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
-+#define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
- #define RX_DMA_VTAG BIT(15)
-
- /* QDMA descriptor rxd3 */
--#define RX_DMA_VID(_x) ((_x) & 0xfff)
-+#define RX_DMA_VID(x) ((x) & VLAN_VID_MASK)
-+#define RX_DMA_TCI(x) ((x) & (VLAN_PRIO_MASK | VLAN_VID_MASK))
-+#define RX_DMA_VPID(x) (((x) >> 16) & 0xffff)
-
- /* QDMA descriptor rxd4 */
- #define MTK_RXD4_FOE_ENTRY GENMASK(13, 0)
-@@ -246,10 +305,15 @@
- /* QDMA descriptor rxd4 */
- #define RX_DMA_L4_VALID BIT(24)
- #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */
--#define RX_DMA_FPORT_SHIFT 19
--#define RX_DMA_FPORT_MASK 0x7
- #define RX_DMA_SPECIAL_TAG BIT(22)
-
-+#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf)
-+#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7)
-+
-+/* PDMA V2 descriptor rxd3 */
-+#define RX_DMA_VTAG_V2 BIT(0)
-+#define RX_DMA_L4_VALID_V2 BIT(2)
-+
- /* PHY Indirect Access Control registers */
- #define MTK_PHY_IAC 0x10004
- #define PHY_IAC_ACCESS BIT(31)
-@@ -371,6 +435,16 @@
- #define ETHSYS_TRGMII_MT7621_DDR_PLL BIT(5)
-
- /* ethernet reset control register */
-+#define ETHSYS_RSTCTRL 0x34
-+#define RSTCTRL_FE BIT(6)
-+#define RSTCTRL_PPE BIT(31)
-+#define RSTCTRL_PPE1 BIT(30)
-+#define RSTCTRL_ETH BIT(23)
-+
-+/* ethernet reset check idle register */
-+#define ETHSYS_FE_RST_CHK_IDLE_EN 0x28
-+
-+/* ethernet reset control register */
- #define ETHSYS_RSTCTRL 0x34
- #define RSTCTRL_FE BIT(6)
- #define RSTCTRL_PPE BIT(31)
-@@ -454,6 +528,17 @@ struct mtk_rx_dma {
- unsigned int rxd4;
- } __packed __aligned(4);
-
-+struct mtk_rx_dma_v2 {
-+ unsigned int rxd1;
-+ unsigned int rxd2;
-+ unsigned int rxd3;
-+ unsigned int rxd4;
-+ unsigned int rxd5;
-+ unsigned int rxd6;
-+ unsigned int rxd7;
-+ unsigned int rxd8;
-+} __packed __aligned(4);
-+
- struct mtk_tx_dma {
- unsigned int txd1;
- unsigned int txd2;
-@@ -461,6 +546,17 @@ struct mtk_tx_dma {
- unsigned int txd4;
- } __packed __aligned(4);
-
-+struct mtk_tx_dma_v2 {
-+ unsigned int txd1;
-+ unsigned int txd2;
-+ unsigned int txd3;
-+ unsigned int txd4;
-+ unsigned int txd5;
-+ unsigned int txd6;
-+ unsigned int txd7;
-+ unsigned int txd8;
-+} __packed __aligned(4);
-+
- struct mtk_eth;
- struct mtk_mac;
-
-@@ -647,7 +743,9 @@ enum mkt_eth_capabilities {
- MTK_SHARED_INT_BIT,
- MTK_TRGMII_MT7621_CLK_BIT,
- MTK_QDMA_BIT,
-+ MTK_NETSYS_V2_BIT,
- MTK_SOC_MT7628_BIT,
-+ MTK_RSTCTRL_PPE1_BIT,
-
- /* MUX BITS*/
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-@@ -679,7 +777,9 @@ enum mkt_eth_capabilities {
- #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
- #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
- #define MTK_QDMA BIT(MTK_QDMA_BIT)
-+#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
- #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
-+#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -756,6 +856,7 @@ struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
- u32 size;
- u16 vlan_tci;
-+ u16 qid;
- u8 gso:1;
- u8 csum:1;
- u8 vlan:1;
-@@ -813,6 +914,10 @@ struct mtk_reg_map {
- * the extra setup for those pins used by GMAC.
- * @txd_size Tx DMA descriptor size.
- * @rxd_size Rx DMA descriptor size.
-+ * @rx_irq_done_mask Rx irq done register mask.
-+ * @rx_dma_l4_valid Rx DMA valid register mask.
-+ * @dma_max_len Max DMA tx/rx buffer length.
-+ * @dma_len_offset Tx/Rx DMA length field offset.
- */
- struct mtk_soc_data {
- const struct mtk_reg_map *reg_map;
-@@ -825,6 +930,10 @@ struct mtk_soc_data {
- struct {
- u32 txd_size;
- u32 rxd_size;
-+ u32 rx_irq_done_mask;
-+ u32 rx_dma_l4_valid;
-+ u32 dma_max_len;
-+ u32 dma_len_offset;
- } txrx;
- };
-
-@@ -943,7 +1052,6 @@ struct mtk_eth {
- u32 tx_bytes;
- struct dim tx_dim;
-
-- u32 rx_dma_l4_valid;
- int ip_align;
-
- struct mtk_ppe *ppe;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch b/target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch
deleted file mode 100644
index 1ee9bb52a7..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:37 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: convert ring dma pointer to void
-
-Simplify the code converting {tx,rx} ring dma pointer to void
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -957,18 +957,15 @@ static int mtk_init_fq_dma(struct mtk_et
- return 0;
- }
-
--static inline void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc)
-+static void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc)
- {
-- void *ret = ring->dma;
--
-- return ret + (desc - ring->phys);
-+ return ring->dma + (desc - ring->phys);
- }
-
- static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,
-- struct mtk_tx_dma *txd,
-- u32 txd_size)
-+ void *txd, u32 txd_size)
- {
-- int idx = ((void *)txd - (void *)ring->dma) / txd_size;
-+ int idx = (txd - ring->dma) / txd_size;
-
- return &ring->buf[idx];
- }
-@@ -976,13 +973,12 @@ static struct mtk_tx_buf *mtk_desc_to_tx
- static struct mtk_tx_dma *qdma_to_pdma(struct mtk_tx_ring *ring,
- struct mtk_tx_dma *dma)
- {
-- return ring->dma_pdma - ring->dma + dma;
-+ return ring->dma_pdma - (struct mtk_tx_dma *)ring->dma + dma;
- }
-
--static int txd_to_idx(struct mtk_tx_ring *ring, struct mtk_tx_dma *dma,
-- u32 txd_size)
-+static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_size)
- {
-- return ((void *)dma - (void *)ring->dma) / txd_size;
-+ return (dma - ring->dma) / txd_size;
- }
-
- static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
-@@ -1399,7 +1395,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
-
- ring = &eth->rx_ring[i];
- idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-- rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
- if (rxd->rxd2 & RX_DMA_DONE) {
- ring->calc_idx_update = true;
- return ring;
-@@ -1451,7 +1447,7 @@ static int mtk_poll_rx(struct napi_struc
- goto rx_done;
-
- idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-- rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
- data = ring->data[idx];
-
- if (!mtk_rx_get_desc(eth, &trxd, rxd))
-@@ -1658,7 +1654,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
-
- mtk_tx_unmap(eth, tx_buf, true);
-
-- desc = (void *)ring->dma + cpu * eth->soc->txrx.txd_size;
-+ desc = ring->dma + cpu * eth->soc->txrx.txd_size;
- ring->last_free = desc;
- atomic_inc(&ring->free_count);
-
-@@ -1803,7 +1799,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- int next = (i + 1) % MTK_DMA_SIZE;
- u32 next_ptr = ring->phys + next * sz;
-
-- txd = (void *)ring->dma + i * sz;
-+ txd = ring->dma + i * sz;
- txd->txd2 = next_ptr;
- txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
- txd->txd4 = 0;
-@@ -1833,7 +1829,7 @@ static int mtk_tx_alloc(struct mtk_eth *
-
- ring->dma_size = MTK_DMA_SIZE;
- atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
-- ring->next_free = &ring->dma[0];
-+ ring->next_free = ring->dma;
- ring->last_free = (void *)txd;
- ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz));
- ring->thresh = MAX_SKB_FRAGS;
-@@ -1948,7 +1944,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
- return -ENOMEM;
-
-- rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + i * eth->soc->txrx.rxd_size;
- rxd->rxd1 = (unsigned int)dma_addr;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-@@ -2010,7 +2006,7 @@ static void mtk_rx_clean(struct mtk_eth
- if (!ring->data[i])
- continue;
-
-- rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + i * eth->soc->txrx.rxd_size;
- if (!rxd->rxd1)
- continue;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -689,7 +689,7 @@ struct mtk_tx_buf {
- * are present
- */
- struct mtk_tx_ring {
-- struct mtk_tx_dma *dma;
-+ void *dma;
- struct mtk_tx_buf *buf;
- dma_addr_t phys;
- struct mtk_tx_dma *next_free;
-@@ -719,7 +719,7 @@ enum mtk_rx_flags {
- * @calc_idx: The current head of ring
- */
- struct mtk_rx_ring {
-- struct mtk_rx_dma *dma;
-+ void *dma;
- u8 **data;
- dma_addr_t phys;
- u16 frag_size;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch b/target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch
deleted file mode 100644
index af77ee39e1..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:38 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: convert scratch_ring pointer to
- void
-
-Simplify the code converting scratch_ring pointer to void
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -933,7 +933,7 @@ static int mtk_init_fq_dma(struct mtk_et
- for (i = 0; i < cnt; i++) {
- struct mtk_tx_dma_v2 *txd;
-
-- txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size;
-+ txd = eth->scratch_ring + i * soc->txrx.txd_size;
- txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
- if (i < cnt - 1)
- txd->txd2 = eth->phy_scratch_ring +
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1029,7 +1029,7 @@ struct mtk_eth {
- struct mtk_rx_ring rx_ring_qdma;
- struct napi_struct tx_napi;
- struct napi_struct rx_napi;
-- struct mtk_tx_dma *scratch_ring;
-+ void *scratch_ring;
- dma_addr_t phy_scratch_ring;
- void *scratch_head;
- struct clk *clks[MTK_CLK_MAX];
diff --git a/target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch b/target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch
deleted file mode 100644
index cceb79ba27..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 May 2022 20:11:39 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce support for mt7986
- chipset
-
-Add support for mt7986-eth driver available on mt7986 soc.
-
-Tested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -87,6 +87,43 @@ static const struct mtk_reg_map mt7628_r
- },
- };
-
-+static const struct mtk_reg_map mt7986_reg_map = {
-+ .tx_irq_mask = 0x461c,
-+ .tx_irq_status = 0x4618,
-+ .pdma = {
-+ .rx_ptr = 0x6100,
-+ .rx_cnt_cfg = 0x6104,
-+ .pcrx_ptr = 0x6108,
-+ .glo_cfg = 0x6204,
-+ .rst_idx = 0x6208,
-+ .delay_irq = 0x620c,
-+ .irq_status = 0x6220,
-+ .irq_mask = 0x6228,
-+ .int_grp = 0x6250,
-+ },
-+ .qdma = {
-+ .qtx_cfg = 0x4400,
-+ .rx_ptr = 0x4500,
-+ .rx_cnt_cfg = 0x4504,
-+ .qcrx_ptr = 0x4508,
-+ .glo_cfg = 0x4604,
-+ .rst_idx = 0x4608,
-+ .delay_irq = 0x460c,
-+ .fc_th = 0x4610,
-+ .int_grp = 0x4620,
-+ .hred = 0x4644,
-+ .ctx_ptr = 0x4700,
-+ .dtx_ptr = 0x4704,
-+ .crx_ptr = 0x4710,
-+ .drx_ptr = 0x4714,
-+ .fq_head = 0x4720,
-+ .fq_tail = 0x4724,
-+ .fq_count = 0x4728,
-+ .fq_blen = 0x472c,
-+ },
-+ .gdm1_cnt = 0x1c00,
-+};
-+
- /* strings used by ethtool */
- static const struct mtk_ethtool_stats {
- char str[ETH_GSTRING_LEN];
-@@ -110,7 +147,7 @@ static const char * const mtk_clks_sourc
- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
-- "sgmii_ck", "eth2pll",
-+ "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
- };
-
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
-@@ -3718,6 +3755,21 @@ static const struct mtk_soc_data mt7629_
- },
- };
-
-+static const struct mtk_soc_data mt7986_data = {
-+ .reg_map = &mt7986_reg_map,
-+ .ana_rgc3 = 0x128,
-+ .caps = MT7986_CAPS,
-+ .required_clks = MT7986_CLKS_BITMAP,
-+ .required_pctl = false,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+};
-+
- static const struct mtk_soc_data rt5350_data = {
- .reg_map = &mt7628_reg_map,
- .caps = MT7628_CAPS,
-@@ -3740,6 +3792,7 @@ const struct of_device_id of_mtk_match[]
- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
-+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
- {},
- };
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -624,6 +624,10 @@ enum mtk_clks_map {
- MTK_CLK_SGMII2_CDR_FB,
- MTK_CLK_SGMII_CK,
- MTK_CLK_ETH2PLL,
-+ MTK_CLK_WOCPU0,
-+ MTK_CLK_WOCPU1,
-+ MTK_CLK_NETSYS0,
-+ MTK_CLK_NETSYS1,
- MTK_CLK_MAX
- };
-
-@@ -654,6 +658,16 @@ enum mtk_clks_map {
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK) | \
- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
-+#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
-+ BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
-+ BIT(MTK_CLK_SGMII_TX_250M) | \
-+ BIT(MTK_CLK_SGMII_RX_250M) | \
-+ BIT(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT(MTK_CLK_SGMII2_CDR_FB))
-
- enum mtk_dev_state {
- MTK_HW_INIT,
-@@ -852,6 +866,10 @@ enum mkt_eth_capabilities {
- MTK_MUX_U3_GMAC2_TO_QPHY | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
-
-+#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
-+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
-+ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
- u32 size;
diff --git a/target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch b/target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch
deleted file mode 100644
index e490333a9b..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Thu, 19 May 2022 17:08:00 +0300
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix error code in
- mtk_flow_offload_replace()
-
-Preserve the error code from mtk_foe_entry_commit(). Do not return
-success.
-
-Fixes: c4f033d9e03e ("net: ethernet: mtk_eth_soc: rework hardware flow table management")
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -434,7 +434,8 @@ mtk_flow_offload_replace(struct mtk_eth
- memcpy(&entry->data, &foe, sizeof(entry->data));
- entry->wed_index = wed_index;
-
-- if (mtk_foe_entry_commit(eth->ppe, entry) < 0)
-+ err = mtk_foe_entry_commit(eth->ppe, entry);
-+ if (err < 0)
- goto free;
-
- err = rhashtable_insert_fast(&eth->flow_table, &entry->node,
diff --git a/target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch b/target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch
deleted file mode 100644
index cfb6ca4866..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 6 Jun 2022 21:49:00 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: enable rx cksum offload for
- MTK_NETSYS_V2
-
-Enable rx checksum offload for mt7986 chipset.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/c8699805c18f7fd38315fcb8da2787676d83a32c.1654544585.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1473,8 +1473,8 @@ static int mtk_poll_rx(struct napi_struc
- int done = 0, bytes = 0;
-
- while (done < budget) {
-+ unsigned int pktlen, *rxdcsum;
- struct net_device *netdev;
-- unsigned int pktlen;
- dma_addr_t dma_addr;
- u32 hash, reason;
- int mac = 0;
-@@ -1541,7 +1541,13 @@ static int mtk_poll_rx(struct napi_struc
- pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
- skb->dev = netdev;
- skb_put(skb, pktlen);
-- if (trxd.rxd4 & eth->soc->txrx.rx_dma_l4_valid)
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ rxdcsum = &trxd.rxd3;
-+ else
-+ rxdcsum = &trxd.rxd4;
-+
-+ if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb_checksum_none_assert(skb);
-@@ -3765,6 +3771,7 @@ static const struct mtk_soc_data mt7986_
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
- .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
- .dma_len_offset = 8,
- },
diff --git a/target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch b/target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch
deleted file mode 100644
index 5303ca48a7..0000000000
--- a/target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Jakub Kicinski <kuba@kernel.org>
-Date: Thu, 19 May 2022 18:25:55 -0700
-Subject: [PATCH] eth: mtk_ppe: fix up after merge
-
-I missed this in the barrage of GCC 12 warnings. Commit cf2df74e202d
-("net: fix dev_fill_forward_path with pppoe + bridge") changed
-the pointer into an array.
-
-Fixes: d7e6f5836038 ("Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net")
-Link: https://lore.kernel.org/r/20220520012555.2262461-1-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -90,10 +90,11 @@ mtk_flow_get_wdma_info(struct net_device
- {
- struct net_device_path_ctx ctx = {
- .dev = dev,
-- .daddr = addr,
- };
- struct net_device_path path = {};
-
-+ memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
-+
- if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED))
- return -1;
-
diff --git a/target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch b/target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch
deleted file mode 100644
index 5737da6e10..0000000000
--- a/target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch
+++ /dev/null
@@ -1,948 +0,0 @@
-From 4973056cceacc70966396039fae99867dfafd796 Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Fri, 22 Oct 2021 18:41:04 -0400
-Subject: [PATCH] net: convert users of bitmap_foo() to linkmode_foo()
-
-This converts instances of
- bitmap_foo(args..., __ETHTOOL_LINK_MODE_MASK_NBITS)
-to
- linkmode_foo(args...)
-
-I manually fixed up some lines to prevent them from being excessively
-long. Otherwise, this change was generated with the following semantic
-patch:
-
-// Generated with
-// echo linux/linkmode.h > includes
-// git grep -Flf includes include/ | cut -f 2- -d / | cat includes - \
-// | sort | uniq | tee new_includes | wc -l && mv new_includes includes
-// and repeating until the number stopped going up
-@i@
-@@
-
-(
- #include <linux/acpi_mdio.h>
-|
- #include <linux/brcmphy.h>
-|
- #include <linux/dsa/loop.h>
-|
- #include <linux/dsa/sja1105.h>
-|
- #include <linux/ethtool.h>
-|
- #include <linux/ethtool_netlink.h>
-|
- #include <linux/fec.h>
-|
- #include <linux/fs_enet_pd.h>
-|
- #include <linux/fsl/enetc_mdio.h>
-|
- #include <linux/fwnode_mdio.h>
-|
- #include <linux/linkmode.h>
-|
- #include <linux/lsm_audit.h>
-|
- #include <linux/mdio-bitbang.h>
-|
- #include <linux/mdio.h>
-|
- #include <linux/mdio-mux.h>
-|
- #include <linux/mii.h>
-|
- #include <linux/mii_timestamper.h>
-|
- #include <linux/mlx5/accel.h>
-|
- #include <linux/mlx5/cq.h>
-|
- #include <linux/mlx5/device.h>
-|
- #include <linux/mlx5/driver.h>
-|
- #include <linux/mlx5/eswitch.h>
-|
- #include <linux/mlx5/fs.h>
-|
- #include <linux/mlx5/port.h>
-|
- #include <linux/mlx5/qp.h>
-|
- #include <linux/mlx5/rsc_dump.h>
-|
- #include <linux/mlx5/transobj.h>
-|
- #include <linux/mlx5/vport.h>
-|
- #include <linux/of_mdio.h>
-|
- #include <linux/of_net.h>
-|
- #include <linux/pcs-lynx.h>
-|
- #include <linux/pcs/pcs-xpcs.h>
-|
- #include <linux/phy.h>
-|
- #include <linux/phy_led_triggers.h>
-|
- #include <linux/phylink.h>
-|
- #include <linux/platform_data/bcmgenet.h>
-|
- #include <linux/platform_data/xilinx-ll-temac.h>
-|
- #include <linux/pxa168_eth.h>
-|
- #include <linux/qed/qed_eth_if.h>
-|
- #include <linux/qed/qed_fcoe_if.h>
-|
- #include <linux/qed/qed_if.h>
-|
- #include <linux/qed/qed_iov_if.h>
-|
- #include <linux/qed/qed_iscsi_if.h>
-|
- #include <linux/qed/qed_ll2_if.h>
-|
- #include <linux/qed/qed_nvmetcp_if.h>
-|
- #include <linux/qed/qed_rdma_if.h>
-|
- #include <linux/sfp.h>
-|
- #include <linux/sh_eth.h>
-|
- #include <linux/smsc911x.h>
-|
- #include <linux/soc/nxp/lpc32xx-misc.h>
-|
- #include <linux/stmmac.h>
-|
- #include <linux/sunrpc/svc_rdma.h>
-|
- #include <linux/sxgbe_platform.h>
-|
- #include <net/cfg80211.h>
-|
- #include <net/dsa.h>
-|
- #include <net/mac80211.h>
-|
- #include <net/selftests.h>
-|
- #include <rdma/ib_addr.h>
-|
- #include <rdma/ib_cache.h>
-|
- #include <rdma/ib_cm.h>
-|
- #include <rdma/ib_hdrs.h>
-|
- #include <rdma/ib_mad.h>
-|
- #include <rdma/ib_marshall.h>
-|
- #include <rdma/ib_pack.h>
-|
- #include <rdma/ib_pma.h>
-|
- #include <rdma/ib_sa.h>
-|
- #include <rdma/ib_smi.h>
-|
- #include <rdma/ib_umem.h>
-|
- #include <rdma/ib_umem_odp.h>
-|
- #include <rdma/ib_verbs.h>
-|
- #include <rdma/iw_cm.h>
-|
- #include <rdma/mr_pool.h>
-|
- #include <rdma/opa_addr.h>
-|
- #include <rdma/opa_port_info.h>
-|
- #include <rdma/opa_smi.h>
-|
- #include <rdma/opa_vnic.h>
-|
- #include <rdma/rdma_cm.h>
-|
- #include <rdma/rdma_cm_ib.h>
-|
- #include <rdma/rdmavt_cq.h>
-|
- #include <rdma/rdma_vt.h>
-|
- #include <rdma/rdmavt_qp.h>
-|
- #include <rdma/rw.h>
-|
- #include <rdma/tid_rdma_defs.h>
-|
- #include <rdma/uverbs_ioctl.h>
-|
- #include <rdma/uverbs_named_ioctl.h>
-|
- #include <rdma/uverbs_std_types.h>
-|
- #include <rdma/uverbs_types.h>
-|
- #include <soc/mscc/ocelot.h>
-|
- #include <soc/mscc/ocelot_ptp.h>
-|
- #include <soc/mscc/ocelot_vcap.h>
-|
- #include <trace/events/ib_mad.h>
-|
- #include <trace/events/rdma_core.h>
-|
- #include <trace/events/rdma.h>
-|
- #include <trace/events/rpcrdma.h>
-|
- #include <uapi/linux/ethtool.h>
-|
- #include <uapi/linux/ethtool_netlink.h>
-|
- #include <uapi/linux/mdio.h>
-|
- #include <uapi/linux/mii.h>
-)
-
-@depends on i@
-expression list args;
-@@
-
-(
-- bitmap_zero(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_zero(args)
-|
-- bitmap_copy(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_copy(args)
-|
-- bitmap_and(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_and(args)
-|
-- bitmap_or(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_or(args)
-|
-- bitmap_empty(args, ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_empty(args)
-|
-- bitmap_andnot(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_andnot(args)
-|
-- bitmap_equal(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_equal(args)
-|
-- bitmap_intersects(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_intersects(args)
-|
-- bitmap_subset(args, __ETHTOOL_LINK_MODE_MASK_NBITS)
-+ linkmode_subset(args)
-)
-
-Add missing linux/mii.h include to mellanox. -DaveM
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_common.c | 6 ++----
- drivers/net/dsa/bcm_sf2.c | 8 +++----
- drivers/net/dsa/hirschmann/hellcreek.c | 6 ++----
- drivers/net/dsa/lantiq_gswip.c | 14 ++++++-------
- drivers/net/dsa/microchip/ksz8795.c | 8 +++----
- drivers/net/dsa/mv88e6xxx/chip.c | 5 ++---
- drivers/net/dsa/ocelot/felix_vsc9959.c | 8 +++----
- drivers/net/dsa/ocelot/seville_vsc9953.c | 8 +++----
- drivers/net/dsa/qca/ar9331.c | 10 ++++-----
- drivers/net/dsa/sja1105/sja1105_main.c | 7 +++----
- drivers/net/dsa/xrs700x/xrs700x.c | 8 +++----
- drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 8 +++----
- drivers/net/ethernet/atheros/ag71xx.c | 8 +++----
- drivers/net/ethernet/cadence/macb_main.c | 11 +++++-----
- .../net/ethernet/freescale/enetc/enetc_pf.c | 8 +++----
- .../net/ethernet/huawei/hinic/hinic_ethtool.c | 10 ++++-----
- .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 5 ++---
- drivers/net/ethernet/marvell/mvneta.c | 10 ++++-----
- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 +++----
- .../marvell/octeontx2/nic/otx2_ethtool.c | 5 ++---
- drivers/net/ethernet/marvell/pxa168_eth.c | 3 +--
- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 21 +++++++------------
- .../microchip/sparx5/sparx5_phylink.c | 7 +++----
- drivers/net/ethernet/mscc/ocelot_net.c | 7 +++----
- .../ethernet/pensando/ionic/ionic_ethtool.c | 3 +--
- .../net/ethernet/xilinx/xilinx_axienet_main.c | 8 +++----
- drivers/net/pcs/pcs-xpcs.c | 2 +-
- drivers/net/phy/sfp-bus.c | 2 +-
- net/ethtool/ioctl.c | 7 +++----
- 29 files changed, 87 insertions(+), 133 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1349,10 +1349,8 @@ void b53_phylink_validate(struct dsa_swi
- phylink_set(mask, 100baseT_Full);
- }
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-
- phylink_helper_basex_speed(state);
- }
---- a/drivers/net/dsa/bcm_sf2.c
-+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -692,7 +692,7 @@ static void bcm_sf2_sw_validate(struct d
- state->interface != PHY_INTERFACE_MODE_GMII &&
- state->interface != PHY_INTERFACE_MODE_INTERNAL &&
- state->interface != PHY_INTERFACE_MODE_MOCA) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- if (port != core_readl(priv, CORE_IMP0_PRT_ID))
- dev_err(ds->dev,
- "Unsupported interface: %d for port %d\n",
-@@ -720,10 +720,8 @@ static void bcm_sf2_sw_validate(struct d
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
---- a/drivers/net/dsa/hirschmann/hellcreek.c
-+++ b/drivers/net/dsa/hirschmann/hellcreek.c
-@@ -1476,10 +1476,8 @@ static void hellcreek_phylink_validate(s
- else
- phylink_set(mask, 1000baseT_Full);
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static int
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1452,10 +1452,8 @@ static void gswip_phylink_set_capab(unsi
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
-@@ -1483,7 +1481,7 @@ static void gswip_xrx200_phylink_validat
- goto unsupported;
- break;
- default:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported port: %i\n", port);
- return;
- }
-@@ -1493,7 +1491,7 @@ static void gswip_xrx200_phylink_validat
- return;
-
- unsupported:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
- phy_modes(state->interface), port);
- }
-@@ -1523,7 +1521,7 @@ static void gswip_xrx300_phylink_validat
- goto unsupported;
- break;
- default:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported port: %i\n", port);
- return;
- }
-@@ -1533,7 +1531,7 @@ static void gswip_xrx300_phylink_validat
- return;
-
- unsupported:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
- phy_modes(state->interface), port);
- }
---- a/drivers/net/dsa/microchip/ksz8795.c
-+++ b/drivers/net/dsa/microchip/ksz8795.c
-@@ -1542,15 +1542,13 @@ static void ksz8_validate(struct dsa_swi
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-
- return;
-
- unsupported:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported interface: %s, port: %d\n",
- phy_modes(state->interface), port);
- }
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -683,9 +683,8 @@ static void mv88e6xxx_validate(struct ds
- if (chip->info->ops->phylink_validate)
- chip->info->ops->phylink_validate(chip, port, mask, state);
-
-- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-
- /* We can only operate at 2500BaseX or 1000BaseX. If requested
- * to advertise both, only report advertising at 2500BaseX.
---- a/drivers/net/dsa/ocelot/felix_vsc9959.c
-+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
-@@ -944,7 +944,7 @@ static void vsc9959_phylink_validate(str
-
- if (state->interface != PHY_INTERFACE_MODE_NA &&
- state->interface != ocelot_port->phy_mode) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
-@@ -966,10 +966,8 @@ static void vsc9959_phylink_validate(str
- phylink_set(mask, 2500baseX_Full);
- }
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
---- a/drivers/net/dsa/ocelot/seville_vsc9953.c
-+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
-@@ -1000,7 +1000,7 @@ static void vsc9953_phylink_validate(str
-
- if (state->interface != PHY_INTERFACE_MODE_NA &&
- state->interface != ocelot_port->phy_mode) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
-@@ -1019,10 +1019,8 @@ static void vsc9953_phylink_validate(str
- phylink_set(mask, 2500baseX_Full);
- }
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port,
---- a/drivers/net/dsa/qca/ar9331.c
-+++ b/drivers/net/dsa/qca/ar9331.c
-@@ -522,7 +522,7 @@ static void ar9331_sw_phylink_validate(s
- goto unsupported;
- break;
- default:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported port: %i\n", port);
- return;
- }
-@@ -536,15 +536,13 @@ static void ar9331_sw_phylink_validate(s
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-
- return;
-
- unsupported:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported interface: %d, port: %d\n",
- state->interface, port);
- }
---- a/drivers/net/dsa/sja1105/sja1105_main.c
-+++ b/drivers/net/dsa/sja1105/sja1105_main.c
-@@ -1360,7 +1360,7 @@ static void sja1105_phylink_validate(str
- */
- if (state->interface != PHY_INTERFACE_MODE_NA &&
- sja1105_phy_mode_mismatch(priv, port, state->interface)) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
-@@ -1380,9 +1380,8 @@ static void sja1105_phylink_validate(str
- phylink_set(mask, 2500baseX_Full);
- }
-
-- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static int
---- a/drivers/net/dsa/xrs700x/xrs700x.c
-+++ b/drivers/net/dsa/xrs700x/xrs700x.c
-@@ -457,7 +457,7 @@ static void xrs700x_phylink_validate(str
- phylink_set(mask, 1000baseT_Full);
- break;
- default:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- dev_err(ds->dev, "Unsupported port: %i\n", port);
- return;
- }
-@@ -468,10 +468,8 @@ static void xrs700x_phylink_validate(str
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Full);
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void xrs700x_mac_link_up(struct dsa_switch *ds, int port,
---- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
-+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
-@@ -374,9 +374,8 @@ static int xgbe_set_link_ksettings(struc
- __ETHTOOL_LINK_MODE_MASK_NBITS, cmd->link_modes.advertising,
- __ETHTOOL_LINK_MODE_MASK_NBITS, lks->link_modes.supported);
-
-- bitmap_and(advertising,
-- cmd->link_modes.advertising, lks->link_modes.supported,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(advertising, cmd->link_modes.advertising,
-+ lks->link_modes.supported);
-
- if ((cmd->base.autoneg == AUTONEG_ENABLE) &&
- bitmap_empty(advertising, __ETHTOOL_LINK_MODE_MASK_NBITS)) {
-@@ -389,8 +388,7 @@ static int xgbe_set_link_ksettings(struc
- pdata->phy.autoneg = cmd->base.autoneg;
- pdata->phy.speed = speed;
- pdata->phy.duplex = cmd->base.duplex;
-- bitmap_copy(lks->link_modes.advertising, advertising,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_copy(lks->link_modes.advertising, advertising);
-
- if (cmd->base.autoneg == AUTONEG_ENABLE)
- XGBE_SET_ADV(lks, Autoneg);
---- a/drivers/net/ethernet/atheros/ag71xx.c
-+++ b/drivers/net/ethernet/atheros/ag71xx.c
-@@ -1082,14 +1082,12 @@ static void ag71xx_mac_validate(struct p
- phylink_set(mask, 1000baseX_Full);
- }
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-
- return;
- unsupported:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- }
-
- static void ag71xx_mac_pcs_get_state(struct phylink_config *config,
---- a/drivers/net/ethernet/cadence/macb_main.c
-+++ b/drivers/net/ethernet/cadence/macb_main.c
-@@ -523,21 +523,21 @@ static void macb_validate(struct phylink
- state->interface != PHY_INTERFACE_MODE_SGMII &&
- state->interface != PHY_INTERFACE_MODE_10GBASER &&
- !phy_interface_mode_is_rgmii(state->interface)) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
- if (!macb_is_gem(bp) &&
- (state->interface == PHY_INTERFACE_MODE_GMII ||
- phy_interface_mode_is_rgmii(state->interface))) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
- if (state->interface == PHY_INTERFACE_MODE_10GBASER &&
- !(bp->caps & MACB_CAPS_HIGH_SPEED &&
- bp->caps & MACB_CAPS_PCS)) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
-@@ -576,9 +576,8 @@ static void macb_validate(struct phylink
- phylink_set(mask, 1000baseT_Half);
- }
- out:
-- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
-+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
-@@ -965,7 +965,7 @@ static void enetc_pl_mac_validate(struct
- state->interface != PHY_INTERFACE_MODE_2500BASEX &&
- state->interface != PHY_INTERFACE_MODE_USXGMII &&
- !phy_interface_mode_is_rgmii(state->interface)) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
-@@ -988,10 +988,8 @@ static void enetc_pl_mac_validate(struct
- phylink_set(mask, 2500baseX_Full);
- }
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void enetc_pl_mac_config(struct phylink_config *config,
---- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
-+++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
-@@ -322,12 +322,10 @@ static int hinic_get_link_ksettings(stru
- }
- }
-
-- bitmap_copy(link_ksettings->link_modes.supported,
-- (unsigned long *)&settings.supported,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_copy(link_ksettings->link_modes.advertising,
-- (unsigned long *)&settings.advertising,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_copy(link_ksettings->link_modes.supported,
-+ (unsigned long *)&settings.supported);
-+ linkmode_copy(link_ksettings->link_modes.advertising,
-+ (unsigned long *)&settings.advertising);
-
- return 0;
- }
---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
-+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
-@@ -467,9 +467,8 @@ static int ixgbe_set_link_ksettings(stru
- * this function does not support duplex forcing, but can
- * limit the advertising of the adapter to the specified speed
- */
-- if (!bitmap_subset(cmd->link_modes.advertising,
-- cmd->link_modes.supported,
-- __ETHTOOL_LINK_MODE_MASK_NBITS))
-+ if (!linkmode_subset(cmd->link_modes.advertising,
-+ cmd->link_modes.supported))
- return -EINVAL;
-
- /* only allow one speed at a time if no autoneg */
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -3835,14 +3835,14 @@ static void mvneta_validate(struct phyli
- */
- if (phy_interface_mode_is_8023z(state->interface)) {
- if (!phylink_test(state->advertising, Autoneg)) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
- } else if (state->interface != PHY_INTERFACE_MODE_NA &&
- state->interface != PHY_INTERFACE_MODE_QSGMII &&
- state->interface != PHY_INTERFACE_MODE_SGMII &&
- !phy_interface_mode_is_rgmii(state->interface)) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
-@@ -3871,10 +3871,8 @@ static void mvneta_validate(struct phyli
- phylink_set(mask, 100baseT_Full);
- }
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-
- /* We can only operate at 2500BaseX or 1000BaseX. If requested
- * to advertise both, only report advertising at 2500BaseX.
---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-@@ -6377,15 +6377,14 @@ static void mvpp2_phylink_validate(struc
- goto empty_set;
- }
-
-- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-
- phylink_helper_basex_speed(state);
- return;
-
- empty_set:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- }
-
- static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode,
---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
-+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
-@@ -1172,9 +1172,8 @@ static int otx2_set_link_ksettings(struc
- otx2_get_link_ksettings(netdev, &cur_ks);
-
- /* Check requested modes against supported modes by hardware */
-- if (!bitmap_subset(cmd->link_modes.advertising,
-- cur_ks.link_modes.supported,
-- __ETHTOOL_LINK_MODE_MASK_NBITS))
-+ if (!linkmode_subset(cmd->link_modes.advertising,
-+ cur_ks.link_modes.supported))
- return -EINVAL;
-
- mutex_lock(&mbox->lock);
---- a/drivers/net/ethernet/marvell/pxa168_eth.c
-+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
-@@ -977,8 +977,7 @@ static int pxa168_init_phy(struct net_de
- cmd.base.phy_address = pep->phy_addr;
- cmd.base.speed = pep->phy_speed;
- cmd.base.duplex = pep->phy_duplex;
-- bitmap_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES);
- cmd.base.autoneg = AUTONEG_ENABLE;
-
- if (cmd.base.speed != 0)
---- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
-+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
-@@ -39,6 +39,7 @@
- #include <linux/in.h>
- #include <net/ip.h>
- #include <linux/bitmap.h>
-+#include <linux/mii.h>
-
- #include "mlx4_en.h"
- #include "en_port.h"
-@@ -643,10 +644,8 @@ static unsigned long *ptys2ethtool_link_
- unsigned int i; \
- cfg = &ptys2ethtool_map[reg_]; \
- cfg->speed = speed_; \
-- bitmap_zero(cfg->supported, \
-- __ETHTOOL_LINK_MODE_MASK_NBITS); \
-- bitmap_zero(cfg->advertised, \
-- __ETHTOOL_LINK_MODE_MASK_NBITS); \
-+ linkmode_zero(cfg->supported); \
-+ linkmode_zero(cfg->advertised); \
- for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) { \
- __set_bit(modes[i], cfg->supported); \
- __set_bit(modes[i], cfg->advertised); \
-@@ -702,10 +701,8 @@ static void ptys2ethtool_update_link_mod
- int i;
- for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {
- if (eth_proto & MLX4_PROT_MASK(i))
-- bitmap_or(link_modes, link_modes,
-- ptys2ethtool_link_mode(&ptys2ethtool_map[i],
-- report),
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_or(link_modes, link_modes,
-+ ptys2ethtool_link_mode(&ptys2ethtool_map[i], report));
- }
- }
-
-@@ -716,11 +713,9 @@ static u32 ethtool2ptys_link_modes(const
- u32 ptys_modes = 0;
-
- for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {
-- if (bitmap_intersects(
-- ptys2ethtool_link_mode(&ptys2ethtool_map[i],
-- report),
-- link_modes,
-- __ETHTOOL_LINK_MODE_MASK_NBITS))
-+ ulong *map_mode = ptys2ethtool_link_mode(&ptys2ethtool_map[i],
-+ report);
-+ if (linkmode_intersects(map_mode, link_modes))
- ptys_modes |= 1 << i;
- }
- return ptys_modes;
---- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
-+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
-@@ -92,12 +92,11 @@ static void sparx5_phylink_validate(stru
- }
- break;
- default:
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void sparx5_phylink_mac_config(struct phylink_config *config,
---- a/drivers/net/ethernet/mscc/ocelot_net.c
-+++ b/drivers/net/ethernet/mscc/ocelot_net.c
-@@ -1509,7 +1509,7 @@ static void vsc7514_phylink_validate(str
-
- if (state->interface != PHY_INTERFACE_MODE_NA &&
- state->interface != ocelot_port->phy_mode) {
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
-
-@@ -1528,9 +1528,8 @@ static void vsc7514_phylink_validate(str
- phylink_set(mask, 2500baseT_Full);
- phylink_set(mask, 2500baseX_Full);
-
-- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void vsc7514_phylink_mac_config(struct phylink_config *config,
---- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
-+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
-@@ -228,8 +228,7 @@ static int ionic_get_link_ksettings(stru
- break;
- }
-
-- bitmap_copy(ks->link_modes.advertising, ks->link_modes.supported,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_copy(ks->link_modes.advertising, ks->link_modes.supported);
-
- ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
- ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-@@ -1565,7 +1565,7 @@ static void axienet_validate(struct phyl
- netdev_warn(ndev, "Cannot use PHY mode %s, supported: %s\n",
- phy_modes(state->interface),
- phy_modes(lp->phy_mode));
-- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(supported);
- return;
- }
- }
-@@ -1598,10 +1598,8 @@ static void axienet_validate(struct phyl
- break;
- }
-
-- bitmap_and(supported, supported, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-- bitmap_and(state->advertising, state->advertising, mask,
-- __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
-
- static void axienet_mac_pcs_get_state(struct phylink_config *config,
---- a/drivers/net/pcs/pcs-xpcs.c
-+++ b/drivers/net/pcs/pcs-xpcs.c
-@@ -637,7 +637,7 @@ void xpcs_validate(struct dw_xpcs *xpcs,
- if (state->interface == PHY_INTERFACE_MODE_NA)
- return;
-
-- bitmap_zero(xpcs_supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(xpcs_supported);
-
- compat = xpcs_find_compat(xpcs->id, state->interface);
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -379,7 +379,7 @@ void sfp_parse_support(struct sfp_bus *b
- if (bus->sfp_quirk)
- bus->sfp_quirk->modes(id, modes);
-
-- bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_or(support, support, modes);
-
- phylink_set(support, Autoneg);
- phylink_set(support, Pause);
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -335,7 +335,7 @@ EXPORT_SYMBOL(ethtool_intersect_link_mas
- void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst,
- u32 legacy_u32)
- {
-- bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(dst);
- dst[0] = legacy_u32;
- }
- EXPORT_SYMBOL(ethtool_convert_legacy_u32_to_link_mode);
-@@ -350,11 +350,10 @@ bool ethtool_convert_link_mode_to_legacy
- if (__ETHTOOL_LINK_MODE_MASK_NBITS > 32) {
- __ETHTOOL_DECLARE_LINK_MODE_MASK(ext);
-
-- bitmap_zero(ext, __ETHTOOL_LINK_MODE_MASK_NBITS);
-+ linkmode_zero(ext);
- bitmap_fill(ext, 32);
- bitmap_complement(ext, ext, __ETHTOOL_LINK_MODE_MASK_NBITS);
-- if (bitmap_intersects(ext, src,
-- __ETHTOOL_LINK_MODE_MASK_NBITS)) {
-+ if (linkmode_intersects(ext, src)) {
- /* src mask goes beyond bit 31 */
- retval = false;
- }
diff --git a/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch b/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch
deleted file mode 100644
index 885c2fcf25..0000000000
--- a/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 38c310eb46f5f80213a92093af11af270c209a76 Mon Sep 17 00:00:00 2001
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Tue, 26 Oct 2021 11:06:06 +0100
-Subject: [PATCH] net: phylink: add MAC phy_interface_t bitmap
-
-Add a phy_interface_t bitmap so the MAC driver can specifiy which PHY
-interface modes it supports.
-
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/phylink.h | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -78,6 +78,7 @@ struct phylink_config {
- bool ovr_an_inband;
- void (*get_fixed_state)(struct phylink_config *config,
- struct phylink_link_state *state);
-+ DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
- };
-
- /**
diff --git a/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch b/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch
deleted file mode 100644
index 9800884f6e..0000000000
--- a/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From d25f3a74f30aace819163dfa54f2a4b8ca1dc932 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 26 Oct 2021 11:06:11 +0100
-Subject: [PATCH] net: phylink: use supported_interfaces for phylink
- validation
-
-If the network device supplies a supported interface bitmap, we can use
-that during phylink's validation to simplify MAC drivers in two ways by
-using the supported_interfaces bitmap to:
-
-1. reject unsupported interfaces before calling into the MAC driver.
-2. generate the set of all supported link modes across all supported
- interfaces (used mainly for SFP, but also some 10G PHYs.)
-
-Suggested-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 36 ++++++++++++++++++++++++++++++++++++
- include/linux/phylink.h | 12 ++++++++++--
- 2 files changed, 46 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -155,9 +155,45 @@ static const char *phylink_an_mode_str(u
- return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
- }
-
-+static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(all_adv) = { 0, };
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, };
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(s);
-+ struct phylink_link_state t;
-+ int intf;
-+
-+ for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) {
-+ if (test_bit(intf, pl->config->supported_interfaces)) {
-+ linkmode_copy(s, supported);
-+
-+ t = *state;
-+ t.interface = intf;
-+ pl->mac_ops->validate(pl->config, s, &t);
-+ linkmode_or(all_s, all_s, s);
-+ linkmode_or(all_adv, all_adv, t.advertising);
-+ }
-+ }
-+
-+ linkmode_copy(supported, all_s);
-+ linkmode_copy(state->advertising, all_adv);
-+
-+ return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
-+}
-+
- static int phylink_validate(struct phylink *pl, unsigned long *supported,
- struct phylink_link_state *state)
- {
-+ if (!phy_interface_empty(pl->config->supported_interfaces)) {
-+ if (state->interface == PHY_INTERFACE_MODE_NA)
-+ return phylink_validate_any(pl, supported, state);
-+
-+ if (!test_bit(state->interface,
-+ pl->config->supported_interfaces))
-+ return -EINVAL;
-+ }
-+
- pl->mac_ops->validate(pl->config, supported, state);
-
- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -68,6 +68,8 @@ enum phylink_op_type {
- * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
- * @get_fixed_state: callback to execute to determine the fixed link state,
- * if MAC link is at %MLO_AN_FIXED mode.
-+ * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx
-+ * are supported by the MAC/PCS.
- */
- struct phylink_config {
- struct device *dev;
-@@ -136,8 +138,14 @@ struct phylink_mac_ops {
- * based on @state->advertising and/or @state->speed and update
- * @state->interface accordingly. See phylink_helper_basex_speed().
- *
-- * When @state->interface is %PHY_INTERFACE_MODE_NA, phylink expects the
-- * MAC driver to return all supported link modes.
-+ * When @config->supported_interfaces has been set, phylink will iterate
-+ * over the supported interfaces to determine the full capability of the
-+ * MAC. The validation function must not print errors if @state->interface
-+ * is set to an unexpected value.
-+ *
-+ * When @config->supported_interfaces is empty, phylink will call this
-+ * function with @state->interface set to %PHY_INTERFACE_MODE_NA, and
-+ * expects the MAC driver to return all supported link modes.
- *
- * If the @state->interface mode is not supported, then the @supported
- * mask must be cleared.
diff --git a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch
deleted file mode 100644
index b438786536..0000000000
--- a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From c07c6e8eb4b38bae921f9e2f108d1e7f8e14226e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Thu, 28 Oct 2021 18:00:14 +0100
-Subject: [PATCH] net: dsa: populate supported_interfaces member
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add a new DSA switch operation, phylink_get_interfaces, which should
-fill in which PHY_INTERFACE_MODE_* are supported by given port.
-
-Use this before phylink_create() to fill phylinks supported_interfaces
-member, allowing phylink to determine which PHY_INTERFACE_MODEs are
-supported.
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-[tweaked patch and description to add more complete support -- rmk]
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/dsa.h | 2 ++
- net/dsa/port.c | 4 ++++
- net/dsa/slave.c | 4 ++++
- 3 files changed, 10 insertions(+)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -654,6 +654,8 @@ struct dsa_switch_ops {
- /*
- * PHYLINK integration
- */
-+ void (*phylink_get_interfaces)(struct dsa_switch *ds, int port,
-+ unsigned long *supported_interfaces);
- void (*phylink_validate)(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state);
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1188,6 +1188,10 @@ static int dsa_port_phylink_register(str
- dp->pl_config.type = PHYLINK_DEV;
- dp->pl_config.pcs_poll = ds->pcs_poll;
-
-+ if (ds->ops->phylink_get_interfaces)
-+ ds->ops->phylink_get_interfaces(ds, dp->index,
-+ dp->pl_config.supported_interfaces);
-+
- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
- mode, &dsa_port_phylink_mac_ops);
- if (IS_ERR(dp->pl)) {
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -1837,6 +1837,10 @@ static int dsa_slave_phy_setup(struct ne
- dp->pl_config.poll_fixed_state = true;
- }
-
-+ if (ds->ops->phylink_get_interfaces)
-+ ds->ops->phylink_get_interfaces(ds, dp->index,
-+ dp->pl_config.supported_interfaces);
-+
- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode,
- &dsa_port_phylink_mac_ops);
- if (IS_ERR(dp->pl)) {
diff --git a/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch b/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch
deleted file mode 100644
index 9b67a8a518..0000000000
--- a/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From 21bd64bd717dedac96f53b668144cbe37d3c12d4 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 30 Nov 2021 13:09:55 +0000
-Subject: [PATCH] net: dsa: consolidate phylink creation
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The code in port.c and slave.c creating the phylink instance is very
-similar - let's consolidate this into a single function.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Marek Behún <kabel@kernel.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/dsa/dsa_priv.h | 2 +-
- net/dsa/port.c | 44 ++++++++++++++++++++++++++++----------------
- net/dsa/slave.c | 19 +++----------------
- 3 files changed, 32 insertions(+), 33 deletions(-)
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -261,13 +261,13 @@ int dsa_port_mrp_add_ring_role(const str
- const struct switchdev_obj_ring_role_mrp *mrp);
- int dsa_port_mrp_del_ring_role(const struct dsa_port *dp,
- const struct switchdev_obj_ring_role_mrp *mrp);
-+int dsa_port_phylink_create(struct dsa_port *dp);
- int dsa_port_link_register_of(struct dsa_port *dp);
- void dsa_port_link_unregister_of(struct dsa_port *dp);
- int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
- void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr);
- int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast);
- void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast);
--extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;
-
- static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
- const struct net_device *dev)
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1092,7 +1092,7 @@ static void dsa_port_phylink_mac_link_up
- speed, duplex, tx_pause, rx_pause);
- }
-
--const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
-+static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
- .validate = dsa_port_phylink_validate,
- .mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state,
- .mac_config = dsa_port_phylink_mac_config,
-@@ -1101,6 +1101,30 @@ const struct phylink_mac_ops dsa_port_ph
- .mac_link_up = dsa_port_phylink_mac_link_up,
- };
-
-+int dsa_port_phylink_create(struct dsa_port *dp)
-+{
-+ struct dsa_switch *ds = dp->ds;
-+ phy_interface_t mode;
-+ int err;
-+
-+ err = of_get_phy_mode(dp->dn, &mode);
-+ if (err)
-+ mode = PHY_INTERFACE_MODE_NA;
-+
-+ if (ds->ops->phylink_get_interfaces)
-+ ds->ops->phylink_get_interfaces(ds, dp->index,
-+ dp->pl_config.supported_interfaces);
-+
-+ dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
-+ mode, &dsa_port_phylink_mac_ops);
-+ if (IS_ERR(dp->pl)) {
-+ pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
-+ return PTR_ERR(dp->pl);
-+ }
-+
-+ return 0;
-+}
-+
- static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
- {
- struct dsa_switch *ds = dp->ds;
-@@ -1177,27 +1201,15 @@ static int dsa_port_phylink_register(str
- {
- struct dsa_switch *ds = dp->ds;
- struct device_node *port_dn = dp->dn;
-- phy_interface_t mode;
- int err;
-
-- err = of_get_phy_mode(port_dn, &mode);
-- if (err)
-- mode = PHY_INTERFACE_MODE_NA;
--
- dp->pl_config.dev = ds->dev;
- dp->pl_config.type = PHYLINK_DEV;
- dp->pl_config.pcs_poll = ds->pcs_poll;
-
-- if (ds->ops->phylink_get_interfaces)
-- ds->ops->phylink_get_interfaces(ds, dp->index,
-- dp->pl_config.supported_interfaces);
--
-- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
-- mode, &dsa_port_phylink_mac_ops);
-- if (IS_ERR(dp->pl)) {
-- pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
-- return PTR_ERR(dp->pl);
-- }
-+ err = dsa_port_phylink_create(dp);
-+ if (err)
-+ return err;
-
- err = phylink_of_phy_connect(dp->pl, port_dn, 0);
- if (err && err != -ENODEV) {
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -1817,14 +1817,9 @@ static int dsa_slave_phy_setup(struct ne
- struct dsa_port *dp = dsa_slave_to_port(slave_dev);
- struct device_node *port_dn = dp->dn;
- struct dsa_switch *ds = dp->ds;
-- phy_interface_t mode;
- u32 phy_flags = 0;
- int ret;
-
-- ret = of_get_phy_mode(port_dn, &mode);
-- if (ret)
-- mode = PHY_INTERFACE_MODE_NA;
--
- dp->pl_config.dev = &slave_dev->dev;
- dp->pl_config.type = PHYLINK_NETDEV;
-
-@@ -1837,17 +1832,9 @@ static int dsa_slave_phy_setup(struct ne
- dp->pl_config.poll_fixed_state = true;
- }
-
-- if (ds->ops->phylink_get_interfaces)
-- ds->ops->phylink_get_interfaces(ds, dp->index,
-- dp->pl_config.supported_interfaces);
--
-- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode,
-- &dsa_port_phylink_mac_ops);
-- if (IS_ERR(dp->pl)) {
-- netdev_err(slave_dev,
-- "error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
-- return PTR_ERR(dp->pl);
-- }
-+ ret = dsa_port_phylink_create(dp);
-+ if (ret)
-+ return ret;
-
- if (ds->ops->get_phy_flags)
- phy_flags = ds->ops->get_phy_flags(ds, dp->index);
diff --git a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch b/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch
deleted file mode 100644
index 1d9616c0db..0000000000
--- a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 072eea6c22b2af680c3949e64f9adde278c71e68 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 30 Nov 2021 13:10:01 +0000
-Subject: [PATCH] net: dsa: replace phylink_get_interfaces() with
- phylink_get_caps()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Phylink needs slightly more information than phylink_get_interfaces()
-allows us to get from the DSA drivers - we need the MAC capabilities.
-Replace the phylink_get_interfaces() method with phylink_get_caps() to
-allow DSA drivers to fill in the phylink_config MAC capabilities field
-as well.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Marek Behún <kabel@kernel.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/net/dsa.h | 4 ++--
- net/dsa/port.c | 5 ++---
- 2 files changed, 4 insertions(+), 5 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -654,8 +654,8 @@ struct dsa_switch_ops {
- /*
- * PHYLINK integration
- */
-- void (*phylink_get_interfaces)(struct dsa_switch *ds, int port,
-- unsigned long *supported_interfaces);
-+ void (*phylink_get_caps)(struct dsa_switch *ds, int port,
-+ struct phylink_config *config);
- void (*phylink_validate)(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state);
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1111,9 +1111,8 @@ int dsa_port_phylink_create(struct dsa_p
- if (err)
- mode = PHY_INTERFACE_MODE_NA;
-
-- if (ds->ops->phylink_get_interfaces)
-- ds->ops->phylink_get_interfaces(ds, dp->index,
-- dp->pl_config.supported_interfaces);
-+ if (ds->ops->phylink_get_caps)
-+ ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
-
- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
- mode, &dsa_port_phylink_mac_ops);
diff --git a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch b/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch
deleted file mode 100644
index 9791ad2ac9..0000000000
--- a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From bde018222c6b084ac32933a9f933581dd83da18e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 17 Feb 2022 18:30:35 +0000
-Subject: [PATCH] net: dsa: add support for phylink mac_select_pcs()
-
-Add DSA support for the phylink mac_select_pcs() method so DSA drivers
-can return provide phylink with the appropriate PCS for the PHY
-interface mode.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/dsa.h | 3 +++
- net/dsa/port.c | 15 +++++++++++++++
- 2 files changed, 18 insertions(+)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -659,6 +659,9 @@ struct dsa_switch_ops {
- void (*phylink_validate)(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state);
-+ struct phylink_pcs *(*phylink_mac_select_pcs)(struct dsa_switch *ds,
-+ int port,
-+ phy_interface_t iface);
- int (*phylink_mac_link_state)(struct dsa_switch *ds, int port,
- struct phylink_link_state *state);
- void (*phylink_mac_config)(struct dsa_switch *ds, int port,
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1028,6 +1028,20 @@ static void dsa_port_phylink_mac_pcs_get
- }
- }
-
-+static struct phylink_pcs *
-+dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
-+ phy_interface_t interface)
-+{
-+ struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_switch *ds = dp->ds;
-+ struct phylink_pcs *pcs = NULL;
-+
-+ if (ds->ops->phylink_mac_select_pcs)
-+ pcs = ds->ops->phylink_mac_select_pcs(ds, dp->index, interface);
-+
-+ return pcs;
-+}
-+
- static void dsa_port_phylink_mac_config(struct phylink_config *config,
- unsigned int mode,
- const struct phylink_link_state *state)
-@@ -1094,6 +1108,7 @@ static void dsa_port_phylink_mac_link_up
-
- static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
- .validate = dsa_port_phylink_validate,
-+ .mac_select_pcs = dsa_port_phylink_mac_select_pcs,
- .mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state,
- .mac_config = dsa_port_phylink_mac_config,
- .mac_an_restart = dsa_port_phylink_mac_an_restart,
diff --git a/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch b/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch
deleted file mode 100644
index 1a7817b0f9..0000000000
--- a/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 8e20f591f204f8db7f1182918f8e2285d3f589e0 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 26 Oct 2021 11:06:01 +0100
-Subject: [PATCH] net: phy: add phy_interface_t bitmap support
-
-Add support for a bitmap for phy interface modes, which includes:
-- a macro to declare the interface bitmap
-- an inline helper to zero the interface bitmap
-- an inline helper to detect an empty interface bitmap
-- inline helpers to do a bitwise AND and OR operations on two interface
- bitmaps
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/phy.h | 34 ++++++++++++++++++++++++++++++++++
- 1 file changed, 34 insertions(+)
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -155,6 +155,40 @@ typedef enum {
- PHY_INTERFACE_MODE_MAX,
- } phy_interface_t;
-
-+/* PHY interface mode bitmap handling */
-+#define DECLARE_PHY_INTERFACE_MASK(name) \
-+ DECLARE_BITMAP(name, PHY_INTERFACE_MODE_MAX)
-+
-+static inline void phy_interface_zero(unsigned long *intf)
-+{
-+ bitmap_zero(intf, PHY_INTERFACE_MODE_MAX);
-+}
-+
-+static inline bool phy_interface_empty(const unsigned long *intf)
-+{
-+ return bitmap_empty(intf, PHY_INTERFACE_MODE_MAX);
-+}
-+
-+static inline void phy_interface_and(unsigned long *dst, const unsigned long *a,
-+ const unsigned long *b)
-+{
-+ bitmap_and(dst, a, b, PHY_INTERFACE_MODE_MAX);
-+}
-+
-+static inline void phy_interface_or(unsigned long *dst, const unsigned long *a,
-+ const unsigned long *b)
-+{
-+ bitmap_or(dst, a, b, PHY_INTERFACE_MODE_MAX);
-+}
-+
-+static inline void phy_interface_set_rgmii(unsigned long *intf)
-+{
-+ __set_bit(PHY_INTERFACE_MODE_RGMII, intf);
-+ __set_bit(PHY_INTERFACE_MODE_RGMII_ID, intf);
-+ __set_bit(PHY_INTERFACE_MODE_RGMII_RXID, intf);
-+ __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, intf);
-+}
-+
- /*
- * phy_supported_speeds - return all speeds currently supported by a PHY device
- */
diff --git a/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch b/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch
deleted file mode 100644
index 5d5ac4b009..0000000000
--- a/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch
+++ /dev/null
@@ -1,197 +0,0 @@
-From d1e86325af377129adb7fc6f34eb044ca6068b47 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 15 Dec 2021 15:34:15 +0000
-Subject: [PATCH] net: phylink: add mac_select_pcs() method to phylink_mac_ops
-
-mac_select_pcs() allows us to have an explicit point to query which
-PCS the MAC wishes to use for a particular PHY interface mode, thereby
-allowing us to add support to validate the link settings with the PCS.
-
-Phylink will also use this to select the PCS to be used during a major
-configuration event without the MAC driver needing to call
-phylink_set_pcs().
-
-Note that if mac_select_pcs() is present, the supported_interfaces
-bitmap must be filled in; this avoids mac_select_pcs() being called
-with PHY_INTERFACE_MODE_NA when we want to get support for all
-interface types. Phylink will return an error in phylink_create()
-unless this condition is satisfied.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 68 +++++++++++++++++++++++++++++++++------
- include/linux/phylink.h | 18 +++++++++++
- 2 files changed, 77 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -155,6 +155,23 @@ static const char *phylink_an_mode_str(u
- return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
- }
-
-+static int phylink_validate_mac_and_pcs(struct phylink *pl,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ struct phylink_pcs *pcs;
-+
-+ if (pl->mac_ops->mac_select_pcs) {
-+ pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
-+ if (IS_ERR(pcs))
-+ return PTR_ERR(pcs);
-+ }
-+
-+ pl->mac_ops->validate(pl->config, supported, state);
-+
-+ return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
-+}
-+
- static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
- struct phylink_link_state *state)
- {
-@@ -170,9 +187,10 @@ static int phylink_validate_any(struct p
-
- t = *state;
- t.interface = intf;
-- pl->mac_ops->validate(pl->config, s, &t);
-- linkmode_or(all_s, all_s, s);
-- linkmode_or(all_adv, all_adv, t.advertising);
-+ if (!phylink_validate_mac_and_pcs(pl, s, &t)) {
-+ linkmode_or(all_s, all_s, s);
-+ linkmode_or(all_adv, all_adv, t.advertising);
-+ }
- }
- }
-
-@@ -194,9 +212,7 @@ static int phylink_validate(struct phyli
- return -EINVAL;
- }
-
-- pl->mac_ops->validate(pl->config, supported, state);
--
-- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
-+ return phylink_validate_mac_and_pcs(pl, supported, state);
- }
-
- static int phylink_parse_fixedlink(struct phylink *pl,
-@@ -486,10 +502,21 @@ static void phylink_mac_pcs_an_restart(s
- static void phylink_major_config(struct phylink *pl, bool restart,
- const struct phylink_link_state *state)
- {
-+ struct phylink_pcs *pcs = NULL;
- int err;
-
- phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
-
-+ if (pl->mac_ops->mac_select_pcs) {
-+ pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
-+ if (IS_ERR(pcs)) {
-+ phylink_err(pl,
-+ "mac_select_pcs unexpectedly failed: %pe\n",
-+ pcs);
-+ return;
-+ }
-+ }
-+
- if (pl->mac_ops->mac_prepare) {
- err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
- state->interface);
-@@ -500,6 +527,12 @@ static void phylink_major_config(struct
- }
- }
-
-+ /* If we have a new PCS, switch to the new PCS after preparing the MAC
-+ * for the change.
-+ */
-+ if (pcs)
-+ phylink_set_pcs(pl, pcs);
-+
- phylink_mac_config(pl, state);
-
- if (pl->pcs_ops) {
-@@ -879,6 +912,14 @@ struct phylink *phylink_create(struct ph
- struct phylink *pl;
- int ret;
-
-+ /* Validate the supplied configuration */
-+ if (mac_ops->mac_select_pcs &&
-+ phy_interface_empty(config->supported_interfaces)) {
-+ dev_err(config->dev,
-+ "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n");
-+ return ERR_PTR(-EINVAL);
-+ }
-+
- pl = kzalloc(sizeof(*pl), GFP_KERNEL);
- if (!pl)
- return ERR_PTR(-ENOMEM);
-@@ -947,9 +988,10 @@ EXPORT_SYMBOL_GPL(phylink_create);
- * @pl: a pointer to a &struct phylink returned from phylink_create()
- * @pcs: a pointer to the &struct phylink_pcs
- *
-- * Bind the MAC PCS to phylink. This may be called after phylink_create(),
-- * in mac_prepare() or mac_config() methods if it is desired to dynamically
-- * change the PCS.
-+ * Bind the MAC PCS to phylink. This may be called after phylink_create().
-+ * If it is desired to dynamically change the PCS, then the preferred method
-+ * is to use mac_select_pcs(), but it may also be called in mac_prepare()
-+ * or mac_config().
- *
- * Please note that there are behavioural changes with the mac_config()
- * callback if a PCS is present (denoting a newer setup) so removing a PCS
-@@ -960,6 +1002,14 @@ void phylink_set_pcs(struct phylink *pl,
- {
- pl->pcs = pcs;
- pl->pcs_ops = pcs->ops;
-+
-+ if (!pl->phylink_disable_state &&
-+ pl->cfg_link_an_mode == MLO_AN_INBAND) {
-+ if (pl->config->pcs_poll || pcs->poll)
-+ mod_timer(&pl->link_poll, jiffies + HZ);
-+ else
-+ del_timer(&pl->link_poll);
-+ }
- }
- EXPORT_SYMBOL_GPL(phylink_set_pcs);
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -86,6 +86,7 @@ struct phylink_config {
- /**
- * struct phylink_mac_ops - MAC operations structure.
- * @validate: Validate and update the link configuration.
-+ * @mac_select_pcs: Select a PCS for the interface mode.
- * @mac_pcs_get_state: Read the current link state from the hardware.
- * @mac_prepare: prepare for a major reconfiguration of the interface.
- * @mac_config: configure the MAC for the selected mode and state.
-@@ -100,6 +101,8 @@ struct phylink_mac_ops {
- void (*validate)(struct phylink_config *config,
- unsigned long *supported,
- struct phylink_link_state *state);
-+ struct phylink_pcs *(*mac_select_pcs)(struct phylink_config *config,
-+ phy_interface_t interface);
- void (*mac_pcs_get_state)(struct phylink_config *config,
- struct phylink_link_state *state);
- int (*mac_prepare)(struct phylink_config *config, unsigned int mode,
-@@ -152,6 +155,21 @@ struct phylink_mac_ops {
- */
- void validate(struct phylink_config *config, unsigned long *supported,
- struct phylink_link_state *state);
-+/**
-+ * mac_select_pcs: Select a PCS for the interface mode.
-+ * @config: a pointer to a &struct phylink_config.
-+ * @interface: PHY interface mode for PCS
-+ *
-+ * Return the &struct phylink_pcs for the specified interface mode, or
-+ * NULL if none is required, or an error pointer on error.
-+ *
-+ * This must not modify any state. It is used to query which PCS should
-+ * be used. Phylink will use this during validation to ensure that the
-+ * configuration is valid, and when setting a configuration to internally
-+ * set the PCS that will be used.
-+ */
-+struct phylink_pcs *mac_select_pcs(struct phylink_config *config,
-+ phy_interface_t interface);
-
- /**
- * mac_pcs_get_state() - Read the current inband link state from the hardware
diff --git a/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch b/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch
deleted file mode 100644
index f30a566c81..0000000000
--- a/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch
+++ /dev/null
@@ -1,341 +0,0 @@
-From 34ae2c09d46a2d0abd907e139b466f798e4095a8 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 15 Nov 2021 10:00:27 +0000
-Subject: [PATCH] net: phylink: add generic validate implementation
-
-Add a generic validate() implementation using the supported_interfaces
-and a bitmask of MAC pause/speed/duplex capabilities. This allows us
-to entirely eliminate many driver private validate() implementations.
-
-We expose the underlying phylink_get_linkmodes() function so that
-drivers which have special needs can still benefit from conversion.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 252 ++++++++++++++++++++++++++++++++++++++
- include/linux/phylink.h | 31 +++++
- 2 files changed, 283 insertions(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -172,6 +172,258 @@ static int phylink_validate_mac_and_pcs(
- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
- }
-
-+static void phylink_caps_to_linkmodes(unsigned long *linkmodes,
-+ unsigned long caps)
-+{
-+ if (caps & MAC_SYM_PAUSE)
-+ __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes);
-+
-+ if (caps & MAC_ASYM_PAUSE)
-+ __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes);
-+
-+ if (caps & MAC_10HD)
-+ __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, linkmodes);
-+
-+ if (caps & MAC_10FD)
-+ __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, linkmodes);
-+
-+ if (caps & MAC_100HD) {
-+ __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_100FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_1000HD)
-+ __set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, linkmodes);
-+
-+ if (caps & MAC_1000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_2500FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_5000FD)
-+ __set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, linkmodes);
-+
-+ if (caps & MAC_10000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_25000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_40000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_50000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_56000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_100000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_200000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, linkmodes);
-+ }
-+
-+ if (caps & MAC_400000FD) {
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
-+ linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, linkmodes);
-+ __set_bit(ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, linkmodes);
-+ }
-+}
-+
-+/**
-+ * phylink_get_linkmodes() - get acceptable link modes
-+ * @linkmodes: ethtool linkmode mask (must be already initialised)
-+ * @interface: phy interface mode defined by &typedef phy_interface_t
-+ * @mac_capabilities: bitmask of MAC capabilities
-+ *
-+ * Set all possible pause, speed and duplex linkmodes in @linkmodes that
-+ * are supported by the @interface mode and @mac_capabilities. @linkmodes
-+ * must have been initialised previously.
-+ */
-+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
-+ unsigned long mac_capabilities)
-+{
-+ unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
-+
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
-+ fallthrough;
-+
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_GMII:
-+ caps |= MAC_1000HD | MAC_1000FD;
-+ fallthrough;
-+
-+ case PHY_INTERFACE_MODE_REVRMII:
-+ case PHY_INTERFACE_MODE_RMII:
-+ case PHY_INTERFACE_MODE_REVMII:
-+ case PHY_INTERFACE_MODE_MII:
-+ caps |= MAC_10HD | MAC_10FD;
-+ fallthrough;
-+
-+ case PHY_INTERFACE_MODE_100BASEX:
-+ caps |= MAC_100HD | MAC_100FD;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_TBI:
-+ case PHY_INTERFACE_MODE_MOCA:
-+ case PHY_INTERFACE_MODE_RTBI:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ caps |= MAC_1000HD;
-+ fallthrough;
-+ case PHY_INTERFACE_MODE_TRGMII:
-+ caps |= MAC_1000FD;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ caps |= MAC_2500FD;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_5GBASER:
-+ caps |= MAC_5000FD;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_XGMII:
-+ case PHY_INTERFACE_MODE_RXAUI:
-+ case PHY_INTERFACE_MODE_XAUI:
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ case PHY_INTERFACE_MODE_10GKR:
-+ caps |= MAC_10000FD;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_25GBASER:
-+ caps |= MAC_25000FD;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_XLGMII:
-+ caps |= MAC_40000FD;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_INTERNAL:
-+ caps |= ~0;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_NA:
-+ case PHY_INTERFACE_MODE_MAX:
-+ case PHY_INTERFACE_MODE_SMII:
-+ break;
-+ }
-+
-+ phylink_caps_to_linkmodes(linkmodes, caps & mac_capabilities);
-+}
-+EXPORT_SYMBOL_GPL(phylink_get_linkmodes);
-+
-+/**
-+ * phylink_generic_validate() - generic validate() callback implementation
-+ * @config: a pointer to a &struct phylink_config.
-+ * @supported: ethtool bitmask for supported link modes.
-+ * @state: a pointer to a &struct phylink_link_state.
-+ *
-+ * Generic implementation of the validate() callback that MAC drivers can
-+ * use when they pass the range of supported interfaces and MAC capabilities.
-+ * This makes use of phylink_get_linkmodes().
-+ */
-+void phylink_generic_validate(struct phylink_config *config,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-+
-+ phylink_set_port_modes(mask);
-+ phylink_set(mask, Autoneg);
-+ phylink_get_linkmodes(mask, state->interface, config->mac_capabilities);
-+
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-+}
-+EXPORT_SYMBOL_GPL(phylink_generic_validate);
-+
- static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
- struct phylink_link_state *state)
- {
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -20,6 +20,29 @@ enum {
- MLO_AN_PHY = 0, /* Conventional PHY */
- MLO_AN_FIXED, /* Fixed-link mode */
- MLO_AN_INBAND, /* In-band protocol */
-+
-+ MAC_SYM_PAUSE = BIT(0),
-+ MAC_ASYM_PAUSE = BIT(1),
-+ MAC_10HD = BIT(2),
-+ MAC_10FD = BIT(3),
-+ MAC_10 = MAC_10HD | MAC_10FD,
-+ MAC_100HD = BIT(4),
-+ MAC_100FD = BIT(5),
-+ MAC_100 = MAC_100HD | MAC_100FD,
-+ MAC_1000HD = BIT(6),
-+ MAC_1000FD = BIT(7),
-+ MAC_1000 = MAC_1000HD | MAC_1000FD,
-+ MAC_2500FD = BIT(8),
-+ MAC_5000FD = BIT(9),
-+ MAC_10000FD = BIT(10),
-+ MAC_20000FD = BIT(11),
-+ MAC_25000FD = BIT(12),
-+ MAC_40000FD = BIT(13),
-+ MAC_50000FD = BIT(14),
-+ MAC_56000FD = BIT(15),
-+ MAC_100000FD = BIT(16),
-+ MAC_200000FD = BIT(17),
-+ MAC_400000FD = BIT(18),
- };
-
- static inline bool phylink_autoneg_inband(unsigned int mode)
-@@ -70,6 +93,7 @@ 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.
-+ * @mac_capabilities: MAC pause/speed/duplex capabilities.
- */
- struct phylink_config {
- struct device *dev;
-@@ -81,6 +105,7 @@ struct phylink_config {
- void (*get_fixed_state)(struct phylink_config *config,
- struct phylink_link_state *state);
- DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
-+ unsigned long mac_capabilities;
- };
-
- /**
-@@ -462,6 +487,12 @@ void pcs_link_up(struct phylink_pcs *pcs
- phy_interface_t interface, int speed, int duplex);
- #endif
-
-+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
-+ unsigned long mac_capabilities);
-+void phylink_generic_validate(struct phylink_config *config,
-+ unsigned long *supported,
-+ struct phylink_link_state *state);
-+
- struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
- phy_interface_t iface,
- const struct phylink_mac_ops *mac_ops);
diff --git a/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch b/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch
deleted file mode 100644
index 524ce9bd92..0000000000
--- a/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 0d22d4b626a4eaa3196019092eb6c1919e9f8caa Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 15 Dec 2021 15:34:20 +0000
-Subject: [PATCH] net: phylink: add pcs_validate() method
-
-Add a hook for PCS to validate the link parameters. This avoids MAC
-drivers having to have knowledge of their PCS in their validate()
-method, thereby allowing several MAC drivers to be simplfied.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 31 +++++++++++++++++++++++++++++++
- include/linux/phylink.h | 20 ++++++++++++++++++++
- 2 files changed, 51 insertions(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -160,13 +160,44 @@ static int phylink_validate_mac_and_pcs(
- struct phylink_link_state *state)
- {
- struct phylink_pcs *pcs;
-+ int ret;
-
-+ /* Get the PCS for this interface mode */
- if (pl->mac_ops->mac_select_pcs) {
- pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
- if (IS_ERR(pcs))
- return PTR_ERR(pcs);
-+ } else {
-+ pcs = pl->pcs;
- }
-
-+ if (pcs) {
-+ /* 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.
-+ */
-+ if (!pcs->ops) {
-+ phylink_err(pl, "interface %s: uninitialised PCS\n",
-+ phy_modes(state->interface));
-+ dump_stack();
-+ return -EINVAL;
-+ }
-+
-+ /* Validate the link parameters with the PCS */
-+ if (pcs->ops->pcs_validate) {
-+ ret = pcs->ops->pcs_validate(pcs, supported, state);
-+ if (ret < 0 || phylink_is_empty_linkmode(supported))
-+ return -EINVAL;
-+
-+ /* Ensure the advertising mask is a subset of the
-+ * supported mask.
-+ */
-+ linkmode_and(state->advertising, state->advertising,
-+ supported);
-+ }
-+ }
-+
-+ /* Then validate the link parameters with the MAC */
- pl->mac_ops->validate(pl->config, supported, state);
-
- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -398,6 +398,7 @@ struct phylink_pcs {
-
- /**
- * struct phylink_pcs_ops - MAC PCS operations structure.
-+ * @pcs_validate: validate the link configuration.
- * @pcs_get_state: read the current MAC PCS link state from the hardware.
- * @pcs_config: configure the MAC PCS for the selected mode and state.
- * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
-@@ -405,6 +406,8 @@ struct phylink_pcs {
- * (where necessary).
- */
- struct phylink_pcs_ops {
-+ int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
-+ const struct phylink_link_state *state);
- void (*pcs_get_state)(struct phylink_pcs *pcs,
- struct phylink_link_state *state);
- int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
-@@ -418,6 +421,23 @@ struct phylink_pcs_ops {
-
- #if 0 /* For kernel-doc purposes only. */
- /**
-+ * pcs_validate() - validate the link configuration.
-+ * @pcs: a pointer to a &struct phylink_pcs.
-+ * @supported: ethtool bitmask for supported link modes.
-+ * @state: a const pointer to a &struct phylink_link_state.
-+ *
-+ * Validate the interface mode, and advertising's autoneg bit, removing any
-+ * media ethtool link modes that would not be supportable from the supported
-+ * mask. Phylink will propagate the changes to the advertising mask. See the
-+ * &struct phylink_mac_ops validate() method.
-+ *
-+ * Returns -EINVAL if the interface mode/autoneg mode is not supported.
-+ * Returns non-zero positive if the link state can be supported.
-+ */
-+int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
-+ const struct phylink_link_state *state);
-+
-+/**
- * pcs_get_state() - Read the current inband link state from the hardware
- * @pcs: a pointer to a &struct phylink_pcs.
- * @state: a pointer to a &struct phylink_link_state.
diff --git a/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch b/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch
deleted file mode 100644
index 16d5da9c70..0000000000
--- a/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 3e5b1feccea7db576353ffc302f78d522e4116e6 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 9 Dec 2021 13:11:32 +0000
-Subject: [PATCH] net: phylink: add legacy_pre_march2020 indicator
-
-Add a boolean to phylink_config to indicate whether a driver has not
-been updated for the changes in commit 7cceb599d15d ("net: phylink:
-avoid mac_config calls"), and thus are reliant on the old behaviour.
-
-We were currently keying the phylink behaviour on the presence of a
-PCS, but this is sub-optimal for modern drivers that may not have a
-PCS.
-
-This commit merely introduces the new flag, but does not add any use,
-since we need all legacy drivers to set this flag before it can be
-used. Once these legacy drivers have been updated, we can remove this
-flag.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/linux/phylink.h | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -84,6 +84,8 @@ enum phylink_op_type {
- * struct phylink_config - PHYLINK configuration structure
- * @dev: a pointer to a struct device associated with the MAC
- * @type: operation type of PHYLINK instance
-+ * @legacy_pre_march2020: driver has not been updated for March 2020 updates
-+ * (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls")
- * @pcs_poll: MAC PCS cannot provide link change interrupt
- * @poll_fixed_state: if true, starts link_poll,
- * if MAC link is at %MLO_AN_FIXED mode.
-@@ -98,6 +100,7 @@ enum phylink_op_type {
- struct phylink_config {
- struct device *dev;
- enum phylink_op_type type;
-+ bool legacy_pre_march2020;
- bool pcs_poll;
- bool poll_fixed_state;
- bool mac_managed_pm;
diff --git a/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch b/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch
deleted file mode 100644
index 849881942e..0000000000
--- a/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0a9f0794d9bd67e590a9488afe87fbb0419d9539 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 9 Dec 2021 13:11:38 +0000
-Subject: [PATCH] net: dsa: mark DSA phylink as legacy_pre_march2020
-
-The majority of DSA drivers do not make use of the PCS support, and
-thus operate in legacy mode. In order to preserve this behaviour in
-future, we need to set the legacy_pre_march2020 flag so phylink knows
-this may require the legacy calls.
-
-There are some DSA drivers that do make use of PCS support, and these
-will continue operating as before - legacy_pre_march2020 will not
-prevent split-PCS support enabling the newer phylink behaviour.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/dsa/port.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1126,6 +1126,13 @@ int dsa_port_phylink_create(struct dsa_p
- if (err)
- mode = PHY_INTERFACE_MODE_NA;
-
-+ /* Presence of phylink_mac_link_state or phylink_mac_an_restart is
-+ * an indicator of a legacy phylink driver.
-+ */
-+ if (ds->ops->phylink_mac_link_state ||
-+ ds->ops->phylink_mac_an_restart)
-+ dp->pl_config.legacy_pre_march2020 = true;
-+
- if (ds->ops->phylink_get_caps)
- ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
-
diff --git a/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch b/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch
deleted file mode 100644
index 73e53068b8..0000000000
--- a/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 001f4261fe4d5ae710cf1f445b6cae6d9d3ae26e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 9 Dec 2021 13:11:48 +0000
-Subject: [PATCH] net: phylink: use legacy_pre_march2020
-
-Use the legacy flag to indicate whether we should operate in legacy
-mode. This allows us to stop using the presence of a PCS as an
-indicator to the age of the phylink user, and make PCS presence
-optional.
-
-Legacy mode involves:
-1) calling mac_config() whenever the link comes up
-2) calling mac_config() whenever the inband advertisement changes,
- possibly followed by a call to mac_an_restart()
-3) making use of mac_an_restart()
-4) making use of mac_pcs_get_state()
-
-All the above functionality was moved to a seperate "PCS" block of
-operations in March 2020.
-
-Update the documents to indicate that the differences that this flag
-makes.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 12 ++++++------
- include/linux/phylink.h | 17 +++++++++++++++++
- 2 files changed, 23 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -777,7 +777,7 @@ static void phylink_mac_pcs_an_restart(s
- phylink_autoneg_inband(pl->cur_link_an_mode)) {
- if (pl->pcs_ops)
- pl->pcs_ops->pcs_an_restart(pl->pcs);
-- else
-+ else if (pl->config->legacy_pre_march2020)
- pl->mac_ops->mac_an_restart(pl->config);
- }
- }
-@@ -855,7 +855,7 @@ static int phylink_change_inband_advert(
- if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
- return 0;
-
-- if (!pl->pcs_ops) {
-+ if (!pl->pcs_ops && pl->config->legacy_pre_march2020) {
- /* Legacy method */
- phylink_mac_config(pl, &pl->link_config);
- phylink_mac_pcs_an_restart(pl);
-@@ -900,7 +900,8 @@ static void phylink_mac_pcs_get_state(st
-
- if (pl->pcs_ops)
- pl->pcs_ops->pcs_get_state(pl->pcs, state);
-- else if (pl->mac_ops->mac_pcs_get_state)
-+ else if (pl->mac_ops->mac_pcs_get_state &&
-+ pl->config->legacy_pre_march2020)
- pl->mac_ops->mac_pcs_get_state(pl->config, state);
- else
- state->link = 0;
-@@ -1094,12 +1095,11 @@ static void phylink_resolve(struct work_
- }
- phylink_major_config(pl, false, &link_state);
- pl->link_config.interface = link_state.interface;
-- } else if (!pl->pcs_ops) {
-+ } else if (!pl->pcs_ops && pl->config->legacy_pre_march2020) {
- /* The interface remains unchanged, only the speed,
- * duplex or pause settings have changed. Call the
- * old mac_config() method to configure the MAC/PCS
-- * only if we do not have a PCS installed (an
-- * unconverted user.)
-+ * only if we do not have a legacy MAC driver.
- */
- phylink_mac_config(pl, &link_state);
- }
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -210,6 +210,10 @@ struct phylink_pcs *mac_select_pcs(struc
- * negotiation completion state in @state->an_complete, and link up state
- * in @state->link. If possible, @state->lp_advertising should also be
- * populated.
-+ *
-+ * Note: This is a legacy method. This function will not be called unless
-+ * legacy_pre_march2020 is set in &struct phylink_config and there is no
-+ * PCS attached.
- */
- void mac_pcs_get_state(struct phylink_config *config,
- struct phylink_link_state *state);
-@@ -250,6 +254,15 @@ int mac_prepare(struct phylink_config *c
- * guaranteed to be correct, and so any mac_config() implementation must
- * never reference these fields.
- *
-+ * Note: For legacy March 2020 drivers (drivers with legacy_pre_march2020 set
-+ * in their &phylnk_config and which don't have a PCS), this function will be
-+ * called on each link up event, and to also change the in-band advert. For
-+ * non-legacy drivers, it will only be called to reconfigure the MAC for a
-+ * "major" change in e.g. interface mode. It will not be called for changes
-+ * in speed, duplex or pause modes or to change the in-band advertisement.
-+ * In any case, it is strongly preferred that speed, duplex and pause settings
-+ * are handled in the mac_link_up() method and not in this method.
-+ *
- * (this requires a rewrite - please refer to mac_link_up() for situations
- * where the PCS and MAC are not tightly integrated.)
- *
-@@ -334,6 +347,10 @@ int mac_finish(struct phylink_config *co
- /**
- * mac_an_restart() - restart 802.3z BaseX autonegotiation
- * @config: a pointer to a &struct phylink_config.
-+ *
-+ * Note: This is a legacy method. This function will not be called unless
-+ * legacy_pre_march2020 is set in &struct phylink_config and there is no
-+ * PCS attached.
- */
- void mac_an_restart(struct phylink_config *config);
-
diff --git a/target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch b/target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch
deleted file mode 100644
index 924d0e954a..0000000000
--- a/target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 1054457006d4a14de4ae4132030e33d7eedaeba1 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 21 Feb 2022 17:10:52 +0000
-Subject: [PATCH] net: phy: phylink: fix DSA mac_select_pcs() introduction
-
-Vladimir Oltean reports that probing on DSA drivers that aren't yet
-populating supported_interfaces now fails. Fix this by allowing
-phylink to detect whether DSA actually provides an underlying
-mac_select_pcs() implementation.
-
-Reported-by: Vladimir Oltean <olteanv@gmail.com>
-Fixes: bde018222c6b ("net: dsa: add support for phylink mac_select_pcs()")
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/E1nMCD6-00A0wC-FG@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 14 +++++++++++---
- net/dsa/port.c | 2 +-
- 2 files changed, 12 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -74,6 +74,7 @@ struct phylink {
- struct work_struct resolve;
-
- bool mac_link_dropped;
-+ bool using_mac_select_pcs;
-
- struct sfp_bus *sfp_bus;
- bool sfp_may_have_phy;
-@@ -163,7 +164,7 @@ static int phylink_validate_mac_and_pcs(
- int ret;
-
- /* Get the PCS for this interface mode */
-- if (pl->mac_ops->mac_select_pcs) {
-+ if (pl->using_mac_select_pcs) {
- pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
- if (IS_ERR(pcs))
- return PTR_ERR(pcs);
-@@ -790,7 +791,7 @@ static void phylink_major_config(struct
-
- phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
-
-- if (pl->mac_ops->mac_select_pcs) {
-+ if (pl->using_mac_select_pcs) {
- pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
- if (IS_ERR(pcs)) {
- phylink_err(pl,
-@@ -1192,11 +1193,17 @@ struct phylink *phylink_create(struct ph
- phy_interface_t iface,
- const struct phylink_mac_ops *mac_ops)
- {
-+ bool using_mac_select_pcs = false;
- struct phylink *pl;
- int ret;
-
-- /* Validate the supplied configuration */
- if (mac_ops->mac_select_pcs &&
-+ mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) !=
-+ ERR_PTR(-EOPNOTSUPP))
-+ using_mac_select_pcs = true;
-+
-+ /* Validate the supplied configuration */
-+ if (using_mac_select_pcs &&
- phy_interface_empty(config->supported_interfaces)) {
- dev_err(config->dev,
- "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n");
-@@ -1221,6 +1228,7 @@ struct phylink *phylink_create(struct ph
- return ERR_PTR(-EINVAL);
- }
-
-+ pl->using_mac_select_pcs = using_mac_select_pcs;
- pl->phy_state.interface = iface;
- pl->link_interface = iface;
- if (iface == PHY_INTERFACE_MODE_MOCA)
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1033,8 +1033,8 @@ dsa_port_phylink_mac_select_pcs(struct p
- phy_interface_t interface)
- {
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
- struct dsa_switch *ds = dp->ds;
-- struct phylink_pcs *pcs = NULL;
-
- if (ds->ops->phylink_mac_select_pcs)
- pcs = ds->ops->phylink_mac_select_pcs(ds, dp->index, interface);
diff --git a/target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch
deleted file mode 100644
index f21fa4b277..0000000000
--- a/target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From fdedb695e6a8657302341cda81d519ef04f9acaa Mon Sep 17 00:00:00 2001
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Wed, 27 Oct 2021 10:03:43 +0100
-Subject: [PATCH] net: mvneta: populate supported_interfaces member
-
-Populate the phy_interface_t bitmap for the Marvell mvneta driver with
-interfaces modes supported by the MAC.
-
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/marvell/mvneta.c | 25 +++++++++++++++++++++++++
- 1 file changed, 25 insertions(+)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -5180,6 +5180,31 @@ static int mvneta_probe(struct platform_
-
- pp->phylink_config.dev = &dev->dev;
- pp->phylink_config.type = PHYLINK_NETDEV;
-+ phy_interface_set_rgmii(pp->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_QSGMII,
-+ pp->phylink_config.supported_interfaces);
-+ if (comphy) {
-+ /* If a COMPHY is present, we can support any of the serdes
-+ * modes and switch between them.
-+ */
-+ __set_bit(PHY_INTERFACE_MODE_SGMII,
-+ pp->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-+ pp->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-+ pp->phylink_config.supported_interfaces);
-+ } else if (phy_mode == PHY_INTERFACE_MODE_2500BASEX) {
-+ /* No COMPHY, with only 2500BASE-X mode supported */
-+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-+ pp->phylink_config.supported_interfaces);
-+ } else if (phy_mode == PHY_INTERFACE_MODE_1000BASEX ||
-+ phy_mode == PHY_INTERFACE_MODE_SGMII) {
-+ /* No COMPHY, we can switch between 1000BASE-X and SGMII */
-+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-+ pp->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_SGMII,
-+ pp->phylink_config.supported_interfaces);
-+ }
-
- phylink = phylink_create(&pp->phylink_config, pdev->dev.fwnode,
- phy_mode, &mvneta_phylink_ops);
diff --git a/target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch b/target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch
deleted file mode 100644
index e287e39d6a..0000000000
--- a/target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From d9ca72807ecb236f679b960c70ef5b7d4a5f0222 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 27 Oct 2021 10:03:48 +0100
-Subject: [PATCH] net: mvneta: remove interface checks in mvneta_validate()
-
-As phylink checks the interface mode against the supported_interfaces
-bitmap, we no longer need to validate the interface mode in the
-validation function. Remove this to simplify it.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/marvell/mvneta.c | 11 ++---------
- 1 file changed, 2 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -3833,15 +3833,8 @@ static void mvneta_validate(struct phyli
- * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ...
- * When <PortType> = 1 (1000BASE-X) this field must be set to 1."
- */
-- if (phy_interface_mode_is_8023z(state->interface)) {
-- if (!phylink_test(state->advertising, Autoneg)) {
-- linkmode_zero(supported);
-- return;
-- }
-- } else if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_QSGMII &&
-- state->interface != PHY_INTERFACE_MODE_SGMII &&
-- !phy_interface_mode_is_rgmii(state->interface)) {
-+ if (phy_interface_mode_is_8023z(state->interface) &&
-+ !phylink_test(state->advertising, Autoneg)) {
- linkmode_zero(supported);
- return;
- }
diff --git a/target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch b/target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch
deleted file mode 100644
index 9121612bf8..0000000000
--- a/target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 099cbfa286ab937d8213c2dc5c0b401969b78042 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 27 Oct 2021 10:03:53 +0100
-Subject: [PATCH] net: mvneta: drop use of phylink_helper_basex_speed()
-
-Now that we have a better method to select SFP interface modes, we
-no longer need to use phylink_helper_basex_speed() in a driver's
-validation function, and we can also get rid of our hack to indicate
-both 1000base-X and 2500base-X if the comphy is present to make that
-work. Remove this hack and use of phylink_helper_basex_speed().
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/marvell/mvneta.c | 12 +++---------
- 1 file changed, 3 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -3824,8 +3824,6 @@ static void mvneta_validate(struct phyli
- unsigned long *supported,
- struct phylink_link_state *state)
- {
-- struct net_device *ndev = to_net_dev(config->dev);
-- struct mvneta_port *pp = netdev_priv(ndev);
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
- /* We only support QSGMII, SGMII, 802.3z and RGMII modes.
-@@ -3847,11 +3845,12 @@ static void mvneta_validate(struct phyli
- phylink_set(mask, Pause);
-
- /* Half-duplex at speeds higher than 100Mbit is unsupported */
-- if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) {
-+ if (state->interface != PHY_INTERFACE_MODE_2500BASEX) {
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 1000baseX_Full);
- }
-- if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) {
-+
-+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
- phylink_set(mask, 2500baseT_Full);
- phylink_set(mask, 2500baseX_Full);
- }
-@@ -3866,11 +3865,6 @@ static void mvneta_validate(struct phyli
-
- linkmode_and(supported, supported, mask);
- linkmode_and(state->advertising, state->advertising, mask);
--
-- /* We can only operate at 2500BaseX or 1000BaseX. If requested
-- * to advertise both, only report advertising at 2500BaseX.
-- */
-- phylink_helper_basex_speed(state);
- }
-
- static void mvneta_mac_pcs_get_state(struct phylink_config *config,
diff --git a/target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch b/target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch
deleted file mode 100644
index 209dfbc0de..0000000000
--- a/target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 02a0988b98930491db95966fb8086072e47dabb6 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 15 Nov 2021 10:00:32 +0000
-Subject: [PATCH] net: mvneta: use phylink_generic_validate()
-
-Convert mvneta to use phylink_generic_validate() for the bulk of its
-validate() implementation. This network adapter has a restriction
-that for 802.3z links, autonegotiation must be enabled.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/marvell/mvneta.c | 34 ++++-----------------------
- 1 file changed, 4 insertions(+), 30 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -3824,8 +3824,6 @@ static void mvneta_validate(struct phyli
- unsigned long *supported,
- struct phylink_link_state *state)
- {
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
--
- /* We only support QSGMII, SGMII, 802.3z and RGMII modes.
- * When in 802.3z mode, we must have AN enabled:
- * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ...
-@@ -3837,34 +3835,7 @@ static void mvneta_validate(struct phyli
- return;
- }
-
-- /* Allow all the expected bits */
-- phylink_set(mask, Autoneg);
-- phylink_set_port_modes(mask);
--
-- /* Asymmetric pause is unsupported */
-- phylink_set(mask, Pause);
--
-- /* Half-duplex at speeds higher than 100Mbit is unsupported */
-- if (state->interface != PHY_INTERFACE_MODE_2500BASEX) {
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 1000baseX_Full);
-- }
--
-- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
-- phylink_set(mask, 2500baseT_Full);
-- phylink_set(mask, 2500baseX_Full);
-- }
--
-- if (!phy_interface_mode_is_8023z(state->interface)) {
-- /* 10M and 100M are only supported in non-802.3z mode */
-- phylink_set(mask, 10baseT_Half);
-- phylink_set(mask, 10baseT_Full);
-- phylink_set(mask, 100baseT_Half);
-- phylink_set(mask, 100baseT_Full);
-- }
--
-- linkmode_and(supported, supported, mask);
-- linkmode_and(state->advertising, state->advertising, mask);
-+ phylink_generic_validate(config, supported, state);
- }
-
- static void mvneta_mac_pcs_get_state(struct phylink_config *config,
-@@ -5167,6 +5138,9 @@ static int mvneta_probe(struct platform_
-
- pp->phylink_config.dev = &dev->dev;
- pp->phylink_config.type = PHYLINK_NETDEV;
-+ pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 |
-+ MAC_100 | MAC_1000FD | MAC_2500FD;
-+
- phy_interface_set_rgmii(pp->phylink_config.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_QSGMII,
- pp->phylink_config.supported_interfaces);
diff --git a/target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch b/target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch
deleted file mode 100644
index 31717565bf..0000000000
--- a/target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 2106be4fdf3223d9c5bd485e6ef094139e3197ba Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sun, 12 Dec 2021 13:01:21 +0000
-Subject: [PATCH] net: mvneta: mark as a legacy_pre_march2020 driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-mvneta provides mac_an_restart and mac_pcs_get_state methods, so needs
-to be marked as a legacy driver. Marek spotted that mvneta had stopped
-working in 2500base-X mode - thanks for reporting.
-
-Reported-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/marvell/mvneta.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -5138,6 +5138,7 @@ static int mvneta_probe(struct platform_
-
- pp->phylink_config.dev = &dev->dev;
- pp->phylink_config.type = PHYLINK_NETDEV;
-+ pp->phylink_config.legacy_pre_march2020 = true;
- pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 |
- MAC_100 | MAC_1000FD | MAC_2500FD;
-
diff --git a/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch
deleted file mode 100644
index affb87b47b..0000000000
--- a/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 83800d29f0c578e82554e7d4c6bfdbdf9b6cf428 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 16 Nov 2021 10:06:43 +0000
-Subject: [PATCH] net: mtk_eth_soc: populate supported_interfaces member
-
-Populate the phy interface mode bitmap for the Mediatek driver with
-interfaces modes supported by the MAC.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3361,6 +3361,26 @@ static int mtk_add_mac(struct mtk_eth *e
-
- mac->phylink_config.dev = &eth->netdev[id]->dev;
- mac->phylink_config.type = PHYLINK_NETDEV;
-+ __set_bit(PHY_INTERFACE_MODE_MII,
-+ mac->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_GMII,
-+ mac->phylink_config.supported_interfaces);
-+
-+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
-+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
-+
-+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
-+ __set_bit(PHY_INTERFACE_MODE_TRGMII,
-+ mac->phylink_config.supported_interfaces);
-+
-+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
-+ __set_bit(PHY_INTERFACE_MODE_SGMII,
-+ mac->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-+ mac->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-+ mac->phylink_config.supported_interfaces);
-+ }
-
- phylink = phylink_create(&mac->phylink_config,
- of_fwnode_handle(mac->of_node),
diff --git a/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch b/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch
deleted file mode 100644
index 432e23d0a0..0000000000
--- a/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From db81ca153814475d7e07365d46a4d1134bd122e2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 16 Nov 2021 10:06:48 +0000
-Subject: [PATCH] net: mtk_eth_soc: remove interface checks in mtk_validate()
-
-As phylink checks the interface mode against the supported_interfaces
-bitmap, we no longer need to validate the interface mode, nor handle
-PHY_INTERFACE_MODE_NA in the validation function. Remove these to
-simplify the implementation.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 ---------------------
- 1 file changed, 34 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -577,24 +577,8 @@ static void mtk_validate(struct phylink_
- unsigned long *supported,
- struct phylink_link_state *state)
- {
-- struct mtk_mac *mac = container_of(config, struct mtk_mac,
-- phylink_config);
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_MII &&
-- state->interface != PHY_INTERFACE_MODE_GMII &&
-- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII) &&
-- phy_interface_mode_is_rgmii(state->interface)) &&
-- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) &&
-- !mac->id && state->interface == PHY_INTERFACE_MODE_TRGMII) &&
-- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII) &&
-- (state->interface == PHY_INTERFACE_MODE_SGMII ||
-- phy_interface_mode_is_8023z(state->interface)))) {
-- linkmode_zero(supported);
-- return;
-- }
--
- phylink_set_port_modes(mask);
- phylink_set(mask, Autoneg);
-
-@@ -621,7 +605,6 @@ static void mtk_validate(struct phylink_
- case PHY_INTERFACE_MODE_MII:
- case PHY_INTERFACE_MODE_RMII:
- case PHY_INTERFACE_MODE_REVMII:
-- case PHY_INTERFACE_MODE_NA:
- default:
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
-@@ -630,23 +613,6 @@ static void mtk_validate(struct phylink_
- break;
- }
-
-- if (state->interface == PHY_INTERFACE_MODE_NA) {
-- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 1000baseX_Full);
-- phylink_set(mask, 2500baseX_Full);
-- }
-- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) {
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 1000baseT_Half);
-- phylink_set(mask, 1000baseX_Full);
-- }
-- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_GEPHY)) {
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 1000baseT_Half);
-- }
-- }
--
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
-
diff --git a/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch b/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch
deleted file mode 100644
index 7585f7c1eb..0000000000
--- a/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 71d927494463c4f016d828e1134da26b7e961af5 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 16 Nov 2021 10:06:53 +0000
-Subject: [PATCH] net: mtk_eth_soc: drop use of phylink_helper_basex_speed()
-
-Now that we have a better method to select SFP interface modes, we
-no longer need to use phylink_helper_basex_speed() in a driver's
-validation function, and we can also get rid of our hack to indicate
-both 1000base-X and 2500base-X if the comphy is present to make that
-work. Remove this hack and use of phylink_helper_basex_speed().
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++------
- 1 file changed, 2 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -587,8 +587,9 @@ static void mtk_validate(struct phylink_
- phylink_set(mask, 1000baseT_Full);
- break;
- case PHY_INTERFACE_MODE_1000BASEX:
-- case PHY_INTERFACE_MODE_2500BASEX:
- phylink_set(mask, 1000baseX_Full);
-+ break;
-+ case PHY_INTERFACE_MODE_2500BASEX:
- phylink_set(mask, 2500baseX_Full);
- break;
- case PHY_INTERFACE_MODE_GMII:
-@@ -618,11 +619,6 @@ static void mtk_validate(struct phylink_
-
- linkmode_and(supported, supported, mask);
- linkmode_and(state->advertising, state->advertising, mask);
--
-- /* We can only operate at 2500BaseX or 1000BaseX. If requested
-- * to advertise both, only report advertising at 2500BaseX.
-- */
-- phylink_helper_basex_speed(state);
- }
-
- static const struct phylink_mac_ops mtk_phylink_ops = {
diff --git a/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch b/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch
deleted file mode 100644
index 69b6906b7a..0000000000
--- a/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From a4238f6ce151afa331375d74a5033b76da637644 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 16 Nov 2021 10:06:58 +0000
-Subject: [PATCH] net: mtk_eth_soc: use phylink_generic_validate()
-
-mtk_eth_soc has no special behaviour in its validation implementation,
-so can be switched to phylink_generic_validate().
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++-------------------
- 1 file changed, 4 insertions(+), 49 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -573,56 +573,8 @@ static void mtk_mac_link_up(struct phyli
- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-
--static void mtk_validate(struct phylink_config *config,
-- unsigned long *supported,
-- struct phylink_link_state *state)
--{
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
--
-- phylink_set_port_modes(mask);
-- phylink_set(mask, Autoneg);
--
-- switch (state->interface) {
-- case PHY_INTERFACE_MODE_TRGMII:
-- phylink_set(mask, 1000baseT_Full);
-- break;
-- case PHY_INTERFACE_MODE_1000BASEX:
-- phylink_set(mask, 1000baseX_Full);
-- break;
-- case PHY_INTERFACE_MODE_2500BASEX:
-- phylink_set(mask, 2500baseX_Full);
-- break;
-- case PHY_INTERFACE_MODE_GMII:
-- case PHY_INTERFACE_MODE_RGMII:
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- phylink_set(mask, 1000baseT_Half);
-- fallthrough;
-- case PHY_INTERFACE_MODE_SGMII:
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 1000baseX_Full);
-- fallthrough;
-- case PHY_INTERFACE_MODE_MII:
-- case PHY_INTERFACE_MODE_RMII:
-- case PHY_INTERFACE_MODE_REVMII:
-- default:
-- phylink_set(mask, 10baseT_Half);
-- phylink_set(mask, 10baseT_Full);
-- phylink_set(mask, 100baseT_Half);
-- phylink_set(mask, 100baseT_Full);
-- break;
-- }
--
-- phylink_set(mask, Pause);
-- phylink_set(mask, Asym_Pause);
--
-- linkmode_and(supported, supported, mask);
-- linkmode_and(state->advertising, state->advertising, mask);
--}
--
- static const struct phylink_mac_ops mtk_phylink_ops = {
-- .validate = mtk_validate,
-+ .validate = phylink_generic_validate,
- .mac_pcs_get_state = mtk_mac_pcs_get_state,
- .mac_an_restart = mtk_mac_an_restart,
- .mac_config = mtk_mac_config,
-@@ -3323,6 +3275,9 @@ static int mtk_add_mac(struct mtk_eth *e
-
- mac->phylink_config.dev = &eth->netdev[id]->dev;
- mac->phylink_config.type = PHYLINK_NETDEV;
-+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-+ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
-+
- __set_bit(PHY_INTERFACE_MODE_MII,
- mac->phylink_config.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_GMII,
diff --git a/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch b/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch
deleted file mode 100644
index 680d20b943..0000000000
--- a/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From b06515367facfadcf5e70cf6f39db749cf4eb5e3 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 9 Dec 2021 13:11:43 +0000
-Subject: [PATCH] net: mtk_eth_soc: mark as a legacy_pre_march2020 driver
-
-mtk_eth_soc has not been updated for commit 7cceb599d15d ("net: phylink:
-avoid mac_config calls"), and makes use of state->speed and
-state->duplex in contravention of the phylink documentation. This makes
-reliant on the legacy behaviours, so mark it as a legacy driver.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3275,6 +3275,10 @@ static int mtk_add_mac(struct mtk_eth *e
-
- mac->phylink_config.dev = &eth->netdev[id]->dev;
- mac->phylink_config.type = PHYLINK_NETDEV;
-+ /* This driver makes use of state->speed/state->duplex in
-+ * mac_config
-+ */
-+ mac->phylink_config.legacy_pre_march2020 = true;
- mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
-
diff --git a/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch b/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch
deleted file mode 100644
index 4cdd03aa05..0000000000
--- a/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 889e3691b9d6573de133da1f5e78f590e52152cd Mon Sep 17 00:00:00 2001
-From: Jakub Kicinski <kuba@kernel.org>
-Date: Thu, 28 Apr 2022 14:23:13 -0700
-Subject: [PATCH] eth: mtk_eth_soc: remove a copy of the NAPI_POLL_WEIGHT
- define
-
-Defining local versions of NAPI_POLL_WEIGHT with the same
-values in the drivers just makes refactoring harder.
-
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
- 2 files changed, 2 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3574,9 +3574,9 @@ static int mtk_probe(struct platform_dev
- */
- init_dummy_netdev(&eth->dummy_dev);
- netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx,
-- MTK_NAPI_WEIGHT);
-+ NAPI_POLL_WEIGHT);
- netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx,
-- MTK_NAPI_WEIGHT);
-+ NAPI_POLL_WEIGHT);
-
- platform_set_drvdata(pdev, eth);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -25,7 +25,6 @@
- #define MTK_TX_DMA_BUF_LEN 0x3fff
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_DMA_SIZE 512
--#define MTK_NAPI_WEIGHT 64
- #define MTK_MAC_COUNT 2
- #define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
- #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
diff --git a/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch b/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch
deleted file mode 100644
index fd6bd1b87d..0000000000
--- a/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 0600bdde1fae75fb9bad72033d28edddc72b44b2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:54:31 +0100
-Subject: [PATCH 01/12] net: mtk_eth_soc: remove unused mac->mode
-
-mac->mode is only ever written to in one location, and is thus
-superflous. Remove it.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 -
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
- 2 files changed, 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3270,7 +3270,6 @@ static int mtk_add_mac(struct mtk_eth *e
-
- /* mac config is not set */
- mac->interface = PHY_INTERFACE_MODE_NA;
-- mac->mode = MLO_AN_PHY;
- mac->speed = SPEED_UNKNOWN;
-
- mac->phylink_config.dev = &eth->netdev[id]->dev;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1086,7 +1086,6 @@ struct mtk_eth {
- struct mtk_mac {
- int id;
- phy_interface_t interface;
-- unsigned int mode;
- int speed;
- struct device_node *of_node;
- struct phylink *phylink;
diff --git a/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch b/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch
deleted file mode 100644
index a15914bd55..0000000000
--- a/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 5a7a2f4b29d7546244da7d8bbc1962fce5b230f2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:54:36 +0100
-Subject: [PATCH 02/12] net: mtk_eth_soc: remove unused sgmii flags
-
-The "flags" member of struct mtk_sgmii appears to be unused, as are
-the MTK_SGMII_PHYSPEED_* and MTK_HAS_FLAGS() macros. Remove them.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 --------
- 1 file changed, 8 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -957,23 +957,15 @@ struct mtk_soc_data {
- /* currently no SoC has more than 2 macs */
- #define MTK_MAX_DEVS 2
-
--#define MTK_SGMII_PHYSPEED_AN BIT(31)
--#define MTK_SGMII_PHYSPEED_MASK GENMASK(2, 0)
--#define MTK_SGMII_PHYSPEED_1000 BIT(0)
--#define MTK_SGMII_PHYSPEED_2500 BIT(1)
--#define MTK_HAS_FLAGS(flags, _x) (((flags) & (_x)) == (_x))
--
- /* struct mtk_sgmii - This is the structure holding sgmii regmap and its
- * characteristics
- * @regmap: The register map pointing at the range used to setup
- * SGMII modes
-- * @flags: The enum refers to which mode the sgmii wants to run on
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
- */
-
- struct mtk_sgmii {
- struct regmap *regmap[MTK_MAX_DEVS];
-- u32 flags[MTK_MAX_DEVS];
- u32 ana_rgc3;
- };
-
diff --git a/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch b/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch
deleted file mode 100644
index e16bc875e5..0000000000
--- a/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From bc5e93e0cd22e360eda23859b939280205567580 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:54:42 +0100
-Subject: [PATCH 03/12] net: mtk_eth_soc: add mask and update PCS speed
- definitions
-
-The PCS speed setting is a two bit field, but it is defined as two
-separate bits. Add a bitfield mask for the speed definitions, an
- use the FIELD_PREP() macro to define each PCS speed.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -17,6 +17,7 @@
- #include <linux/phylink.h>
- #include <linux/rhashtable.h>
- #include <linux/dim.h>
-+#include <linux/bitfield.h>
- #include "mtk_ppe.h"
-
- #define MTK_QDMA_PAGE_SIZE 2048
-@@ -474,9 +475,10 @@
- #define SGMSYS_SGMII_MODE 0x20
- #define SGMII_IF_MODE_BIT0 BIT(0)
- #define SGMII_SPEED_DUPLEX_AN BIT(1)
--#define SGMII_SPEED_10 0x0
--#define SGMII_SPEED_100 BIT(2)
--#define SGMII_SPEED_1000 BIT(3)
-+#define SGMII_SPEED_MASK GENMASK(3, 2)
-+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
-+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
-+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
- #define SGMII_DUPLEX_FULL BIT(4)
- #define SGMII_IF_MODE_BIT5 BIT(5)
- #define SGMII_REMOTE_FAULT_DIS BIT(8)
diff --git a/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch b/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch
deleted file mode 100644
index fb1ee4e310..0000000000
--- a/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 7da3f901f8ecb425105fad39a0f5de73306abe52 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:54:47 +0100
-Subject: [PATCH 04/12] net: mtk_eth_soc: correct 802.3z speed setting
-
-Phylink does not guarantee that state->speed will be set correctly in
-the mac_config() call, so it's a bug that the driver makes use of it.
-Moreover, it is making use of it in a function that is only ever called
-for 1000BASE-X and 2500BASE-X which operate at a fixed speed which
-happens to be the same setting irrespective of the interface mode. We
-can simply remove the switch statement and just set the SGMII interface
-speed.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 +++++-------------
- 1 file changed, 5 insertions(+), 13 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -34,6 +34,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- return 0;
- }
-
-+/* For SGMII interface mode */
- int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
- {
- unsigned int val;
-@@ -60,6 +61,9 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
- return 0;
- }
-
-+/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
-+ * fixed speed.
-+ */
- int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
- const struct phylink_link_state *state)
- {
-@@ -82,19 +86,7 @@ int mtk_sgmii_setup_mode_force(struct mt
- /* SGMII force mode setting */
- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
- val &= ~SGMII_IF_MODE_MASK;
--
-- switch (state->speed) {
-- case SPEED_10:
-- val |= SGMII_SPEED_10;
-- break;
-- case SPEED_100:
-- val |= SGMII_SPEED_100;
-- break;
-- case SPEED_2500:
-- case SPEED_1000:
-- val |= SGMII_SPEED_1000;
-- break;
-- }
-+ val |= SGMII_SPEED_1000;
-
- if (state->duplex == DUPLEX_FULL)
- val |= SGMII_DUPLEX_FULL;
diff --git a/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch b/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch
deleted file mode 100644
index 93743ad3ff..0000000000
--- a/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From a459187390bb221827f9c07866c3a5ffbdf9622b Mon Sep 17 00:00:00 2001
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:54:52 +0100
-Subject: [PATCH 05/12] net: mtk_eth_soc: correct 802.3z duplex setting
-
-Phylink does not guarantee that state->duplex will be set correctly in
-the mac_config() call, so it's a bug that the driver makes use of it.
-
-Move the 802.3z PCS duplex configuration to mac_link_up().
-
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 +++++++++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 22 +++++++++++++++------
- 3 files changed, 29 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -542,8 +542,18 @@ static void mtk_mac_link_up(struct phyli
- {
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
- phylink_config);
-- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-+ u32 mcr;
-
-+ if (phy_interface_mode_is_8023z(interface)) {
-+ struct mtk_eth *eth = mac->hw;
-+
-+ /* Decide how GMAC and SGMIISYS be mapped */
-+ int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
-+ 0 : mac->id;
-+ mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex);
-+ }
-+
-+ mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
- mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
- MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
- MAC_MCR_FORCE_RX_FC);
-@@ -3274,9 +3284,7 @@ static int mtk_add_mac(struct mtk_eth *e
-
- mac->phylink_config.dev = &eth->netdev[id]->dev;
- mac->phylink_config.type = PHYLINK_NETDEV;
-- /* This driver makes use of state->speed/state->duplex in
-- * mac_config
-- */
-+ /* This driver makes use of state->speed in mac_config */
- mac->phylink_config.legacy_pre_march2020 = true;
- mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1104,6 +1104,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
- int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
- const struct phylink_link_state *state);
-+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
- void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
-
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -83,14 +83,10 @@ int mtk_sgmii_setup_mode_force(struct mt
- val &= ~SGMII_AN_ENABLE;
- regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
-
-- /* SGMII force mode setting */
-+ /* Set the speed etc but leave the duplex unchanged */
- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
-- val &= ~SGMII_IF_MODE_MASK;
-+ val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
- val |= SGMII_SPEED_1000;
--
-- if (state->duplex == DUPLEX_FULL)
-- val |= SGMII_DUPLEX_FULL;
--
- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
-
- /* Release PHYA power down state */
-@@ -101,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt
- return 0;
- }
-
-+/* For 1000BASE-X and 2500BASE-X interface modes */
-+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
-+{
-+ unsigned int val;
-+
-+ /* SGMII force duplex setting */
-+ regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
-+ val &= ~SGMII_DUPLEX_FULL;
-+ if (duplex == DUPLEX_FULL)
-+ val |= SGMII_DUPLEX_FULL;
-+
-+ regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
-+}
-+
- void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
- {
- struct mtk_sgmii *ss = eth->sgmii;
diff --git a/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch b/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch
deleted file mode 100644
index 6556bb7d07..0000000000
--- a/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 4ce5a0bd3958ed248f0325bfcb95339f7c74feb2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:54:57 +0100
-Subject: [PATCH 06/12] net: mtk_eth_soc: stop passing phylink state to sgmii
- setup
-
-Now that mtk_sgmii_setup_mode_force() only uses the interface mode
-from the phylink state, pass just the interface mode into this
-function.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++--
- 3 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -437,7 +437,7 @@ static void mtk_mac_config(struct phylin
- /* Setup SGMIISYS with the determined property */
- if (state->interface != PHY_INTERFACE_MODE_SGMII)
- err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
-- state);
-+ state->interface);
- else if (phylink_autoneg_inband(mode))
- err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1103,7 +1103,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- u32 ana_rgc3);
- int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
- int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-- const struct phylink_link_state *state);
-+ phy_interface_t interface);
- void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
- void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -65,7 +65,7 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
- * fixed speed.
- */
- int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-- const struct phylink_link_state *state)
-+ phy_interface_t interface)
- {
- unsigned int val;
-
-@@ -74,7 +74,7 @@ int mtk_sgmii_setup_mode_force(struct mt
-
- regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
- val &= ~RG_PHY_SPEED_MASK;
-- if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
- val |= RG_PHY_SPEED_3_125G;
- regmap_write(ss->regmap[id], ss->ana_rgc3, val);
-
diff --git a/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch b/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch
deleted file mode 100644
index 0e22c7fd67..0000000000
--- a/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From 1ec619ee4a052fb9ac48b57554ac2722a0bfe73c Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:55:02 +0100
-Subject: [PATCH 07/12] net: mtk_eth_soc: provide mtk_sgmii_config()
-
-Provide mtk_sgmii_config() to wrap up the decisions about which SGMII
-configuration will be called.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 ++---
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 20 +++++++++++++++++---
- 3 files changed, 20 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -435,12 +435,7 @@ static void mtk_mac_config(struct phylin
- 0 : mac->id;
-
- /* Setup SGMIISYS with the determined property */
-- if (state->interface != PHY_INTERFACE_MODE_SGMII)
-- err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
-- state->interface);
-- else if (phylink_autoneg_inband(mode))
-- err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
--
-+ err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface);
- if (err)
- goto init_err;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1101,9 +1101,8 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
-
- int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
- u32 ana_rgc3);
--int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
--int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-- phy_interface_t interface);
-+int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
-+ phy_interface_t interface);
- void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
- void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -35,7 +35,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- }
-
- /* For SGMII interface mode */
--int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
-+static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
- {
- unsigned int val;
-
-@@ -64,8 +64,8 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
- * fixed speed.
- */
--int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-- phy_interface_t interface)
-+static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-+ phy_interface_t interface)
- {
- unsigned int val;
-
-@@ -97,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt
- return 0;
- }
-
-+int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ int err = 0;
-+
-+ /* Setup SGMIISYS with the determined property */
-+ if (interface != PHY_INTERFACE_MODE_SGMII)
-+ err = mtk_sgmii_setup_mode_force(ss, id, interface);
-+ else if (phylink_autoneg_inband(mode))
-+ err = mtk_sgmii_setup_mode_an(ss, id);
-+
-+ return err;
-+}
-+
- /* For 1000BASE-X and 2500BASE-X interface modes */
- void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
- {
diff --git a/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch b/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch
deleted file mode 100644
index 8080a2ca44..0000000000
--- a/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 650a49bc65df6b0e0051a8f62d7c22d95a8f350d Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:55:07 +0100
-Subject: [PATCH 08/12] net: mtk_eth_soc: add fixme comment for state->speed
- use
-
-Add a fixme comment for the last remaining incorrect usage of
-state->speed in the mac_config() method, which is strangely in a code
-path which is only run when the PHY interface mode changes.
-
-This means if we are in RGMII mode, changes in state->speed will not
-cause the INTF_MODE, TRGMII_RCK_CTRL and TRGMII_TCK_CTRL registers to
-be set according to the speed, nor will the TRGPLL clock be set to the
-correct value.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -374,6 +374,14 @@ static void mtk_mac_config(struct phylin
- state->interface))
- goto err_phy;
- } else {
-+ /* FIXME: this is incorrect. Not only does it
-+ * use state->speed (which is not guaranteed
-+ * to be correct) but it also makes use of it
-+ * in a code path that will only be reachable
-+ * when the PHY interface mode changes, not
-+ * when the speed changes. Consequently, RGMII
-+ * is probably broken.
-+ */
- mtk_gmac0_rgmii_adjust(mac->hw,
- state->interface,
- state->speed);
diff --git a/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch b/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch
deleted file mode 100644
index b03ef436bd..0000000000
--- a/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 21089867278deb2a110b685e3cd33f64f9ce41e2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:55:17 +0100
-Subject: [PATCH 10/12] net: mtk_eth_soc: move restoration of SYSCFG0 to
- mac_finish()
-
-The SGMIISYS configuration is performed while ETHSYS_SYSCFG0 is in a
-disabled state. In order to preserve this when we switch to phylink_pcs
-we need to move the restoration of this register to the mac_finish()
-callback.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- 2 files changed, 10 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -447,8 +447,8 @@ static void mtk_mac_config(struct phylin
- if (err)
- goto init_err;
-
-- regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
-- SYSCFG0_SGMII_MASK, val);
-+ /* Save the syscfg0 value for mac_finish */
-+ mac->syscfg0 = val;
- } else if (phylink_autoneg_inband(mode)) {
- dev_err(eth->dev,
- "In-band mode not supported in non SGMII mode!\n");
-@@ -472,8 +472,15 @@ static int mtk_mac_finish(struct phylink
- {
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
- phylink_config);
-+ struct mtk_eth *eth = mac->hw;
- u32 mcr_cur, mcr_new;
-
-+ /* Enable SGMII */
-+ if (interface == PHY_INTERFACE_MODE_SGMII ||
-+ phy_interface_mode_is_8023z(interface))
-+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
-+ SYSCFG0_SGMII_MASK, mac->syscfg0);
-+
- /* Setup gmac */
- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
- mcr_new = mcr_cur;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1088,6 +1088,7 @@ struct mtk_mac {
- struct mtk_hw_stats *hw_stats;
- __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
- int hwlro_ip_cnt;
-+ unsigned int syscfg0;
- };
-
- /* the struct describing the SoC. these are declared in the soc_xyz.c files */
diff --git a/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch b/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch
deleted file mode 100644
index 4c84703cd9..0000000000
--- a/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From 901f3fbe13c3e56f0742e02717ccbfabbc95c463 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:55:22 +0100
-Subject: [PATCH 11/12] net: mtk_eth_soc: convert code structure to suit split
- PCS support
-
-Provide a mtk_pcs structure which encapsulates everything that the PCS
-functions need (the regmap and ana_rgc3 offset), and use this in the
-PCS functions. Provide shim functions to convert from the existing
-"mtk_sgmii_*" interface to the converted PCS functions.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 15 ++-
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 123 +++++++++++---------
- 2 files changed, 79 insertions(+), 59 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -959,16 +959,23 @@ struct mtk_soc_data {
- /* currently no SoC has more than 2 macs */
- #define MTK_MAX_DEVS 2
-
--/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
-- * characteristics
-+/* struct mtk_pcs - This structure holds each sgmii regmap and associated
-+ * data
- * @regmap: The register map pointing at the range used to setup
- * SGMII modes
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
- */
-+struct mtk_pcs {
-+ struct regmap *regmap;
-+ u32 ana_rgc3;
-+};
-
-+/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
-+ * characteristics
-+ * @pcs Array of individual PCS structures
-+ */
- struct mtk_sgmii {
-- struct regmap *regmap[MTK_MAX_DEVS];
-- u32 ana_rgc3;
-+ struct mtk_pcs pcs[MTK_MAX_DEVS];
- };
-
- /* struct mtk_eth - This is the main datasructure for holding the state
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -9,90 +9,71 @@
-
- #include <linux/mfd/syscon.h>
- #include <linux/of.h>
-+#include <linux/phylink.h>
- #include <linux/regmap.h>
-
- #include "mtk_eth_soc.h"
-
--int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
--{
-- struct device_node *np;
-- int i;
--
-- ss->ana_rgc3 = ana_rgc3;
--
-- for (i = 0; i < MTK_MAX_DEVS; i++) {
-- np = of_parse_phandle(r, "mediatek,sgmiisys", i);
-- if (!np)
-- break;
--
-- ss->regmap[i] = syscon_node_to_regmap(np);
-- of_node_put(np);
-- if (IS_ERR(ss->regmap[i]))
-- return PTR_ERR(ss->regmap[i]);
-- }
--
-- return 0;
--}
--
- /* For SGMII interface mode */
--static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
-+static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
- unsigned int val;
-
-- if (!ss->regmap[id])
-+ if (!mpcs->regmap)
- return -EINVAL;
-
- /* Setup the link timer and QPHY power up inside SGMIISYS */
-- regmap_write(ss->regmap[id], SGMSYS_PCS_LINK_TIMER,
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
- SGMII_LINK_TIMER_DEFAULT);
-
-- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
-+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
- val |= SGMII_REMOTE_FAULT_DIS;
-- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
-+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-
-- regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val);
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
- val |= SGMII_AN_RESTART;
-- regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
-
-- regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
- val &= ~SGMII_PHYA_PWD;
-- regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
-+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
-
- return 0;
-+
- }
-
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
- * fixed speed.
- */
--static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-- phy_interface_t interface)
-+static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
-+ phy_interface_t interface)
- {
- unsigned int val;
-
-- if (!ss->regmap[id])
-+ if (!mpcs->regmap)
- return -EINVAL;
-
-- regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
-+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
- val &= ~RG_PHY_SPEED_MASK;
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- val |= RG_PHY_SPEED_3_125G;
-- regmap_write(ss->regmap[id], ss->ana_rgc3, val);
-+ regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
-
- /* Disable SGMII AN */
-- regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val);
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
- val &= ~SGMII_AN_ENABLE;
-- regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
-
- /* Set the speed etc but leave the duplex unchanged */
-- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
-+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
- val |= SGMII_SPEED_1000;
-- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
-+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-
- /* Release PHYA power down state */
-- regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
- val &= ~SGMII_PHYA_PWD;
-- regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
-+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
-
- return 0;
- }
-@@ -100,44 +81,76 @@ static int mtk_sgmii_setup_mode_force(st
- int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
- phy_interface_t interface)
- {
-+ struct mtk_pcs *mpcs = &ss->pcs[id];
- int err = 0;
-
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
-- err = mtk_sgmii_setup_mode_force(ss, id, interface);
-+ err = mtk_pcs_setup_mode_force(mpcs, interface);
- else if (phylink_autoneg_inband(mode))
-- err = mtk_sgmii_setup_mode_an(ss, id);
-+ err = mtk_pcs_setup_mode_an(mpcs);
-
- return err;
- }
-
--/* For 1000BASE-X and 2500BASE-X interface modes */
--void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
-+static void mtk_pcs_restart_an(struct mtk_pcs *mpcs)
-+{
-+ unsigned int val;
-+
-+ if (!mpcs->regmap)
-+ return;
-+
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
-+ val |= SGMII_AN_RESTART;
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
-+}
-+
-+static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex)
- {
- unsigned int val;
-
- /* SGMII force duplex setting */
-- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
-+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
- val &= ~SGMII_DUPLEX_FULL;
- if (duplex == DUPLEX_FULL)
- val |= SGMII_DUPLEX_FULL;
-
-- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
-+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-+}
-+
-+/* For 1000BASE-X and 2500BASE-X interface modes */
-+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
-+{
-+ mtk_pcs_link_up(&ss->pcs[id], speed, duplex);
-+}
-+
-+int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
-+{
-+ struct device_node *np;
-+ int i;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ np = of_parse_phandle(r, "mediatek,sgmiisys", i);
-+ if (!np)
-+ break;
-+
-+ ss->pcs[i].ana_rgc3 = ana_rgc3;
-+ ss->pcs[i].regmap = syscon_node_to_regmap(np);
-+ of_node_put(np);
-+ if (IS_ERR(ss->pcs[i].regmap))
-+ return PTR_ERR(ss->pcs[i].regmap);
-+ }
-+
-+ return 0;
- }
-
- void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
- {
-- struct mtk_sgmii *ss = eth->sgmii;
-- unsigned int val, sid;
-+ unsigned int sid;
-
- /* Decide how GMAC and SGMIISYS be mapped */
- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
- 0 : mac_id;
-
-- if (!ss->regmap[sid])
-- return;
--
-- regmap_read(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, &val);
-- val |= SGMII_AN_RESTART;
-- regmap_write(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, val);
-+ mtk_pcs_restart_an(&eth->sgmii->pcs[sid]);
- }
diff --git a/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch
deleted file mode 100644
index 0f7e451245..0000000000
--- a/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch
+++ /dev/null
@@ -1,262 +0,0 @@
-From 14a44ab0330d290fade1403a920e299cc56d7300 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 18 May 2022 15:55:28 +0100
-Subject: [PATCH 12/12] net: mtk_eth_soc: partially convert to phylink_pcs
-
-Partially convert mtk_eth_soc to phylink_pcs, moving the configuration,
-link up and AN restart over. However, it seems mac_pcs_get_state()
-doesn't actually get the state from the PCS, so we can't convert that
-over without a better understanding of the hardware.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++----------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 ++-
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 55 +++++++++++----------
- 3 files changed, 53 insertions(+), 58 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -310,6 +310,25 @@ static void mtk_gmac0_rgmii_adjust(struc
- mtk_w32(eth, val, TRGMII_TCK_CTRL);
- }
-
-+static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
-+ phy_interface_t interface)
-+{
-+ struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+ phylink_config);
-+ struct mtk_eth *eth = mac->hw;
-+ unsigned int sid;
-+
-+ 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;
-+
-+ return mtk_sgmii_select_pcs(eth->sgmii, sid);
-+ }
-+
-+ return NULL;
-+}
-+
- static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
- const struct phylink_link_state *state)
- {
-@@ -317,7 +336,7 @@ static void mtk_mac_config(struct phylin
- phylink_config);
- struct mtk_eth *eth = mac->hw;
- int val, ge_mode, err = 0;
-- u32 sid, i;
-+ u32 i;
-
- /* MT76x8 has no hardware settings between for the MAC */
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-@@ -438,15 +457,6 @@ static void mtk_mac_config(struct phylin
- SYSCFG0_SGMII_MASK,
- ~(u32)SYSCFG0_SGMII_MASK);
-
-- /* Decide how GMAC and SGMIISYS be mapped */
-- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
-- 0 : mac->id;
--
-- /* Setup SGMIISYS with the determined property */
-- err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface);
-- if (err)
-- goto init_err;
--
- /* Save the syscfg0 value for mac_finish */
- mac->syscfg0 = val;
- } else if (phylink_autoneg_inband(mode)) {
-@@ -526,14 +536,6 @@ static void mtk_mac_pcs_get_state(struct
- state->pause |= MLO_PAUSE_TX;
- }
-
--static void mtk_mac_an_restart(struct phylink_config *config)
--{
-- struct mtk_mac *mac = container_of(config, struct mtk_mac,
-- phylink_config);
--
-- mtk_sgmii_restart_an(mac->hw, mac->id);
--}
--
- static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -554,15 +556,6 @@ static void mtk_mac_link_up(struct phyli
- phylink_config);
- u32 mcr;
-
-- if (phy_interface_mode_is_8023z(interface)) {
-- struct mtk_eth *eth = mac->hw;
--
-- /* Decide how GMAC and SGMIISYS be mapped */
-- int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
-- 0 : mac->id;
-- mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex);
-- }
--
- mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
- mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
- MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
-@@ -595,8 +588,8 @@ static void mtk_mac_link_up(struct phyli
-
- static const struct phylink_mac_ops mtk_phylink_ops = {
- .validate = phylink_generic_validate,
-+ .mac_select_pcs = mtk_mac_select_pcs,
- .mac_pcs_get_state = mtk_mac_pcs_get_state,
-- .mac_an_restart = mtk_mac_an_restart,
- .mac_config = mtk_mac_config,
- .mac_finish = mtk_mac_finish,
- .mac_link_down = mtk_mac_link_down,
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -964,10 +964,12 @@ struct mtk_soc_data {
- * @regmap: The register map pointing at the range used to setup
- * SGMII modes
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
-+ * @pcs: Phylink PCS structure
- */
- struct mtk_pcs {
- struct regmap *regmap;
- u32 ana_rgc3;
-+ struct phylink_pcs pcs;
- };
-
- /* struct mtk_sgmii - This is the structure holding sgmii regmap and its
-@@ -1107,12 +1109,9 @@ void mtk_stats_update_mac(struct mtk_mac
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
- u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
-
-+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
- int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
- u32 ana_rgc3);
--int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
-- phy_interface_t interface);
--void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
--void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
-
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -14,14 +14,16 @@
-
- #include "mtk_eth_soc.h"
-
-+static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
-+{
-+ return container_of(pcs, struct mtk_pcs, pcs);
-+}
-+
- /* For SGMII interface mode */
- static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
- unsigned int val;
-
-- if (!mpcs->regmap)
-- return -EINVAL;
--
- /* Setup the link timer and QPHY power up inside SGMIISYS */
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
- SGMII_LINK_TIMER_DEFAULT);
-@@ -50,9 +52,6 @@ static int mtk_pcs_setup_mode_force(stru
- {
- unsigned int val;
-
-- if (!mpcs->regmap)
-- return -EINVAL;
--
- regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
- val &= ~RG_PHY_SPEED_MASK;
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-@@ -78,10 +77,12 @@ static int mtk_pcs_setup_mode_force(stru
- return 0;
- }
-
--int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
-- phy_interface_t interface)
-+static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface,
-+ const unsigned long *advertising,
-+ bool permit_pause_to_mac)
- {
-- struct mtk_pcs *mpcs = &ss->pcs[id];
-+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- int err = 0;
-
- /* Setup SGMIISYS with the determined property */
-@@ -93,22 +94,25 @@ int mtk_sgmii_config(struct mtk_sgmii *s
- return err;
- }
-
--static void mtk_pcs_restart_an(struct mtk_pcs *mpcs)
-+static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
- {
-+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int val;
-
-- if (!mpcs->regmap)
-- return;
--
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
- val |= SGMII_AN_RESTART;
- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
- }
-
--static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex)
-+static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface, int speed, int duplex)
- {
-+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int val;
-
-+ if (!phy_interface_mode_is_8023z(interface))
-+ return;
-+
- /* SGMII force duplex setting */
- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
- val &= ~SGMII_DUPLEX_FULL;
-@@ -118,11 +122,11 @@ static void mtk_pcs_link_up(struct mtk_p
- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
- }
-
--/* For 1000BASE-X and 2500BASE-X interface modes */
--void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
--{
-- mtk_pcs_link_up(&ss->pcs[id], speed, duplex);
--}
-+static const struct phylink_pcs_ops mtk_pcs_ops = {
-+ .pcs_config = mtk_pcs_config,
-+ .pcs_an_restart = mtk_pcs_restart_an,
-+ .pcs_link_up = mtk_pcs_link_up,
-+};
-
- int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
- {
-@@ -139,18 +143,17 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- of_node_put(np);
- if (IS_ERR(ss->pcs[i].regmap))
- return PTR_ERR(ss->pcs[i].regmap);
-+
-+ ss->pcs[i].pcs.ops = &mtk_pcs_ops;
- }
-
- return 0;
- }
-
--void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
-+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
- {
-- unsigned int sid;
--
-- /* Decide how GMAC and SGMIISYS be mapped */
-- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
-- 0 : mac_id;
-+ if (!ss->pcs[id].regmap)
-+ return NULL;
-
-- mtk_pcs_restart_an(&eth->sgmii->pcs[sid]);
-+ return &ss->pcs[id].pcs;
- }
diff --git a/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch b/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch
deleted file mode 100644
index f65b0cafa8..0000000000
--- a/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 505560028b6deb9b4385cf6100f05ca6f4aacaf8 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Mon, 6 Dec 2021 18:57:49 +0200
-Subject: [PATCH 01/13] net: dsa: mt7530: iterate using
- dsa_switch_for_each_user_port in bridging ops
-
-Avoid repeated calls to dsa_to_port() (some hidden behind dsa_is_user_port
-and some in plain sight) by keeping two struct dsa_port references: one
-to the port passed as argument, and another to the other ports of the
-switch that we're iterating over.
-
-dsa_to_port(ds, i) gets replaced by other_dp, i gets replaced by
-other_port which is derived from other_dp->index, dsa_is_user_port is
-handled by the DSA iterator.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 52 +++++++++++++++++++++++-----------------
- 1 file changed, 30 insertions(+), 22 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1425,27 +1425,31 @@ static int
- mt7530_port_bridge_join(struct dsa_switch *ds, int port,
- struct net_device *bridge)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
- u32 port_bitmap = BIT(MT7530_CPU_PORT);
-- int i;
-+ struct mt7530_priv *priv = ds->priv;
-
- mutex_lock(&priv->reg_mutex);
-
-- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ dsa_switch_for_each_user_port(other_dp, ds) {
-+ int other_port = other_dp->index;
-+
-+ if (dp == other_dp)
-+ continue;
-+
- /* Add this port to the port matrix of the other ports in the
- * same bridge. If the port is disabled, port matrix is kept
- * and not being setup until the port becomes enabled.
- */
-- if (dsa_is_user_port(ds, i) && i != port) {
-- if (dsa_to_port(ds, i)->bridge_dev != bridge)
-- continue;
-- if (priv->ports[i].enable)
-- mt7530_set(priv, MT7530_PCR_P(i),
-- PCR_MATRIX(BIT(port)));
-- priv->ports[i].pm |= PCR_MATRIX(BIT(port));
-+ if (other_dp->bridge_dev != bridge)
-+ continue;
-
-- port_bitmap |= BIT(i);
-- }
-+ if (priv->ports[other_port].enable)
-+ mt7530_set(priv, MT7530_PCR_P(other_port),
-+ PCR_MATRIX(BIT(port)));
-+ priv->ports[other_port].pm |= PCR_MATRIX(BIT(port));
-+
-+ port_bitmap |= BIT(other_port);
- }
-
- /* Add the all other ports to this port matrix. */
-@@ -1550,24 +1554,28 @@ static void
- mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
- struct net_device *bridge)
- {
-+ struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
- struct mt7530_priv *priv = ds->priv;
-- int i;
-
- mutex_lock(&priv->reg_mutex);
-
-- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ dsa_switch_for_each_user_port(other_dp, ds) {
-+ int other_port = other_dp->index;
-+
-+ if (dp == other_dp)
-+ continue;
-+
- /* Remove this port from the port matrix of the other ports
- * in the same bridge. If the port is disabled, port matrix
- * is kept and not being setup until the port becomes enabled.
- */
-- if (dsa_is_user_port(ds, i) && i != port) {
-- if (dsa_to_port(ds, i)->bridge_dev != bridge)
-- continue;
-- if (priv->ports[i].enable)
-- mt7530_clear(priv, MT7530_PCR_P(i),
-- PCR_MATRIX(BIT(port)));
-- priv->ports[i].pm &= ~PCR_MATRIX(BIT(port));
-- }
-+ if (other_dp->bridge_dev != bridge)
-+ continue;
-+
-+ if (priv->ports[other_port].enable)
-+ mt7530_clear(priv, MT7530_PCR_P(other_port),
-+ PCR_MATRIX(BIT(port)));
-+ priv->ports[other_port].pm &= ~PCR_MATRIX(BIT(port));
- }
-
- /* Set the cpu port to be the only one in the port matrix of
diff --git a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch
deleted file mode 100644
index e04bb11e80..0000000000
--- a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From a1da54bcd664fc27169386db966575675ac3ccb0 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:01 +0100
-Subject: [PATCH 02/13] net: dsa: mt7530: populate supported_interfaces and
- mac_capabilities
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Populate the supported interfaces and MAC capabilities for mt7530,
-mt7531 and mt7621 DSA switches. Filling this in will enable phylink
-to pre-check the PHY interface mode against the the supported
-interfaces bitmap prior to calling the validate function, and will
-eventually allow us to convert to using the generic validation.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 74 ++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.h | 2 ++
- 2 files changed, 76 insertions(+)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2687,6 +2687,32 @@ mt7531_setup(struct dsa_switch *ds)
- return 0;
- }
-
-+static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port,
-+ struct phylink_config *config)
-+{
-+ switch (port) {
-+ case 0 ... 4: /* Internal phy */
-+ __set_bit(PHY_INTERFACE_MODE_GMII,
-+ config->supported_interfaces);
-+ break;
-+
-+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-+ phy_interface_set_rgmii(config->supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_MII,
-+ config->supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_GMII,
-+ config->supported_interfaces);
-+ break;
-+
-+ case 6: /* 1st cpu port */
-+ __set_bit(PHY_INTERFACE_MODE_RGMII,
-+ config->supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_TRGMII,
-+ config->supported_interfaces);
-+ break;
-+ }
-+}
-+
- static bool
- mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
- const struct phylink_link_state *state)
-@@ -2723,6 +2749,37 @@ static bool mt7531_is_rgmii_port(struct
- return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
- }
-
-+static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
-+ struct phylink_config *config)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ switch (port) {
-+ case 0 ... 4: /* Internal phy */
-+ __set_bit(PHY_INTERFACE_MODE_GMII,
-+ config->supported_interfaces);
-+ break;
-+
-+ case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
-+ if (mt7531_is_rgmii_port(priv, port)) {
-+ phy_interface_set_rgmii(config->supported_interfaces);
-+ break;
-+ }
-+ fallthrough;
-+
-+ case 6: /* 1st cpu port supports sgmii/8023z only */
-+ __set_bit(PHY_INTERFACE_MODE_SGMII,
-+ config->supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-+ config->supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-+ config->supported_interfaces);
-+
-+ config->mac_capabilities |= MAC_2500FD;
-+ break;
-+ }
-+}
-+
- static bool
- mt7531_phy_mode_supported(struct dsa_switch *ds, int port,
- const struct phylink_link_state *state)
-@@ -3199,6 +3256,18 @@ mt7531_cpu_port_config(struct dsa_switch
- return 0;
- }
-
-+static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
-+ struct phylink_config *config)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ /* This switch only supports full-duplex at 1Gbps */
-+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-+ MAC_10 | MAC_100 | MAC_1000FD;
-+
-+ priv->info->mac_port_get_caps(ds, port, config);
-+}
-+
- static void
- mt7530_mac_port_validate(struct dsa_switch *ds, int port,
- unsigned long *supported)
-@@ -3435,6 +3504,7 @@ static const struct dsa_switch_ops mt753
- .port_vlan_del = mt7530_port_vlan_del,
- .port_mirror_add = mt753x_port_mirror_add,
- .port_mirror_del = mt753x_port_mirror_del,
-+ .phylink_get_caps = mt753x_phylink_get_caps,
- .phylink_validate = mt753x_phylink_validate,
- .phylink_mac_link_state = mt753x_phylink_mac_link_state,
- .phylink_mac_config = mt753x_phylink_mac_config,
-@@ -3452,6 +3522,7 @@ static const struct mt753x_info mt753x_t
- .phy_read = mt7530_phy_read,
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
-+ .mac_port_get_caps = mt7530_mac_port_get_caps,
- .phy_mode_supported = mt7530_phy_mode_supported,
- .mac_port_validate = mt7530_mac_port_validate,
- .mac_port_get_state = mt7530_phylink_mac_link_state,
-@@ -3463,6 +3534,7 @@ static const struct mt753x_info mt753x_t
- .phy_read = mt7530_phy_read,
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
-+ .mac_port_get_caps = mt7530_mac_port_get_caps,
- .phy_mode_supported = mt7530_phy_mode_supported,
- .mac_port_validate = mt7530_mac_port_validate,
- .mac_port_get_state = mt7530_phylink_mac_link_state,
-@@ -3475,6 +3547,7 @@ static const struct mt753x_info mt753x_t
- .phy_write = mt7531_ind_phy_write,
- .pad_setup = mt7531_pad_setup,
- .cpu_port_config = mt7531_cpu_port_config,
-+ .mac_port_get_caps = mt7531_mac_port_get_caps,
- .phy_mode_supported = mt7531_phy_mode_supported,
- .mac_port_validate = mt7531_mac_port_validate,
- .mac_port_get_state = mt7531_phylink_mac_link_state,
-@@ -3537,6 +3610,7 @@ mt7530_probe(struct mdio_device *mdiodev
- */
- if (!priv->info->sw_setup || !priv->info->pad_setup ||
- !priv->info->phy_read || !priv->info->phy_write ||
-+ !priv->info->mac_port_get_caps ||
- !priv->info->phy_mode_supported ||
- !priv->info->mac_port_validate ||
- !priv->info->mac_port_get_state || !priv->info->mac_port_config)
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -807,6 +807,8 @@ struct mt753x_info {
- int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
- int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
- int (*cpu_port_config)(struct dsa_switch *ds, int port);
-+ void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
-+ struct phylink_config *config);
- bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
- const struct phylink_link_state *state);
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
diff --git a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch
deleted file mode 100644
index 31be0e7be3..0000000000
--- a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From e3f6719e2269868ca129b05da50cd55786848954 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:06 +0100
-Subject: [PATCH 03/13] net: dsa: mt7530: remove interface checks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-As phylink checks the interface mode against the supported_interfaces
-bitmap, we no longer need to validate the interface mode, nor handle
-PHY_INTERFACE_MODE_NA in the validation function. Remove these to
-simplify the implementation.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 82 ----------------------------------------
- drivers/net/dsa/mt7530.h | 2 -
- 2 files changed, 84 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2713,37 +2713,6 @@ static void mt7530_mac_port_get_caps(str
- }
- }
-
--static bool
--mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
-- const struct phylink_link_state *state)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- switch (port) {
-- case 0 ... 4: /* Internal phy */
-- if (state->interface != PHY_INTERFACE_MODE_GMII)
-- return false;
-- break;
-- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-- if (!phy_interface_mode_is_rgmii(state->interface) &&
-- state->interface != PHY_INTERFACE_MODE_MII &&
-- state->interface != PHY_INTERFACE_MODE_GMII)
-- return false;
-- break;
-- case 6: /* 1st cpu port */
-- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_TRGMII)
-- return false;
-- break;
-- default:
-- dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
-- port);
-- return false;
-- }
--
-- return true;
--}
--
- static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port)
- {
- return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
-@@ -2780,44 +2749,6 @@ static void mt7531_mac_port_get_caps(str
- }
- }
-
--static bool
--mt7531_phy_mode_supported(struct dsa_switch *ds, int port,
-- const struct phylink_link_state *state)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- switch (port) {
-- case 0 ... 4: /* Internal phy */
-- if (state->interface != PHY_INTERFACE_MODE_GMII)
-- return false;
-- break;
-- case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
-- if (mt7531_is_rgmii_port(priv, port))
-- return phy_interface_mode_is_rgmii(state->interface);
-- fallthrough;
-- case 6: /* 1st cpu port supports sgmii/8023z only */
-- if (state->interface != PHY_INTERFACE_MODE_SGMII &&
-- !phy_interface_mode_is_8023z(state->interface))
-- return false;
-- break;
-- default:
-- dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
-- port);
-- return false;
-- }
--
-- return true;
--}
--
--static bool
--mt753x_phy_mode_supported(struct dsa_switch *ds, int port,
-- const struct phylink_link_state *state)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- return priv->info->phy_mode_supported(ds, port, state);
--}
--
- static int
- mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
- {
-@@ -3072,9 +3003,6 @@ mt753x_phylink_mac_config(struct dsa_swi
- struct mt7530_priv *priv = ds->priv;
- u32 mcr_cur, mcr_new;
-
-- if (!mt753x_phy_mode_supported(ds, port, state))
-- goto unsupported;
--
- switch (port) {
- case 0 ... 4: /* Internal phy */
- if (state->interface != PHY_INTERFACE_MODE_GMII)
-@@ -3290,12 +3218,6 @@ mt753x_phylink_validate(struct dsa_switc
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
- struct mt7530_priv *priv = ds->priv;
-
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- !mt753x_phy_mode_supported(ds, port, state)) {
-- linkmode_zero(supported);
-- return;
-- }
--
- phylink_set_port_modes(mask);
-
- if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
-@@ -3523,7 +3445,6 @@ static const struct mt753x_info mt753x_t
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
-- .phy_mode_supported = mt7530_phy_mode_supported,
- .mac_port_validate = mt7530_mac_port_validate,
- .mac_port_get_state = mt7530_phylink_mac_link_state,
- .mac_port_config = mt7530_mac_config,
-@@ -3535,7 +3456,6 @@ static const struct mt753x_info mt753x_t
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
-- .phy_mode_supported = mt7530_phy_mode_supported,
- .mac_port_validate = mt7530_mac_port_validate,
- .mac_port_get_state = mt7530_phylink_mac_link_state,
- .mac_port_config = mt7530_mac_config,
-@@ -3548,7 +3468,6 @@ static const struct mt753x_info mt753x_t
- .pad_setup = mt7531_pad_setup,
- .cpu_port_config = mt7531_cpu_port_config,
- .mac_port_get_caps = mt7531_mac_port_get_caps,
-- .phy_mode_supported = mt7531_phy_mode_supported,
- .mac_port_validate = mt7531_mac_port_validate,
- .mac_port_get_state = mt7531_phylink_mac_link_state,
- .mac_port_config = mt7531_mac_config,
-@@ -3611,7 +3530,6 @@ mt7530_probe(struct mdio_device *mdiodev
- if (!priv->info->sw_setup || !priv->info->pad_setup ||
- !priv->info->phy_read || !priv->info->phy_write ||
- !priv->info->mac_port_get_caps ||
-- !priv->info->phy_mode_supported ||
- !priv->info->mac_port_validate ||
- !priv->info->mac_port_get_state || !priv->info->mac_port_config)
- return -EINVAL;
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -809,8 +809,6 @@ struct mt753x_info {
- int (*cpu_port_config)(struct dsa_switch *ds, int port);
- void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
- struct phylink_config *config);
-- bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
-- const struct phylink_link_state *state);
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
- unsigned long *supported);
- int (*mac_port_get_state)(struct dsa_switch *ds, int port,
diff --git a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch
deleted file mode 100644
index 2a5d5ae9d9..0000000000
--- a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 58344a3b85f1bd5ffddfc2c11f6f2bf688b5f990 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:12 +0100
-Subject: [PATCH 04/13] net: dsa: mt7530: drop use of
- phylink_helper_basex_speed()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Now that we have a better method to select SFP interface modes, we
-no longer need to use phylink_helper_basex_speed() in a driver's
-validation function.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 5 -----
- 1 file changed, 5 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3242,11 +3242,6 @@ mt753x_phylink_validate(struct dsa_switc
-
- linkmode_and(supported, supported, mask);
- linkmode_and(state->advertising, state->advertising, mask);
--
-- /* We can only operate at 2500BaseX or 1000BaseX. If requested
-- * to advertise both, only report advertising at 2500BaseX.
-- */
-- phylink_helper_basex_speed(state);
- }
-
- static int
diff --git a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch
deleted file mode 100644
index ad672312e4..0000000000
--- a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 3c1d788a62dc648d1846049b66119ebb69dedd52 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:17 +0100
-Subject: [PATCH 05/13] net: dsa: mt7530: only indicate linkmodes that can be
- supported
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Now that mt7530 is not using the basex helper, it becomes unnecessary to
-indicate support for both 1000baseX and 2500baseX when one of the 803.3z
-PHY interface modes is being selected. Ensure that the driver indicates
-only those linkmodes that can actually be supported by the PHY interface
-mode.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 12 ++++++++----
- drivers/net/dsa/mt7530.h | 1 +
- 2 files changed, 9 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2820,12 +2820,13 @@ static int mt7531_rgmii_setup(struct mt7
- }
-
- static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
-+ phy_interface_t interface,
- unsigned long *supported)
- {
- /* Port5 supports ethier RGMII or SGMII.
- * Port6 supports SGMII only.
- */
-- if (port == 6) {
-+ if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) {
- phylink_set(supported, 2500baseX_Full);
- phylink_set(supported, 2500baseT_Full);
- }
-@@ -3198,16 +3199,18 @@ static void mt753x_phylink_get_caps(stru
-
- static void
- mt7530_mac_port_validate(struct dsa_switch *ds, int port,
-+ phy_interface_t interface,
- unsigned long *supported)
- {
- }
-
- static void mt7531_mac_port_validate(struct dsa_switch *ds, int port,
-+ phy_interface_t interface,
- unsigned long *supported)
- {
- struct mt7530_priv *priv = ds->priv;
-
-- mt7531_sgmii_validate(priv, port, supported);
-+ mt7531_sgmii_validate(priv, port, interface, supported);
- }
-
- static void
-@@ -3230,12 +3233,13 @@ mt753x_phylink_validate(struct dsa_switc
- }
-
- /* This switch only supports 1G full-duplex. */
-- if (state->interface != PHY_INTERFACE_MODE_MII) {
-+ if (state->interface != PHY_INTERFACE_MODE_MII &&
-+ state->interface != PHY_INTERFACE_MODE_2500BASEX) {
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 1000baseX_Full);
- }
-
-- priv->info->mac_port_validate(ds, port, mask);
-+ priv->info->mac_port_validate(ds, port, state->interface, mask);
-
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -810,6 +810,7 @@ struct mt753x_info {
- void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
- struct phylink_config *config);
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
-+ phy_interface_t interface,
- unsigned long *supported);
- int (*mac_port_get_state)(struct dsa_switch *ds, int port,
- struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch
deleted file mode 100644
index 8d9802f1ee..0000000000
--- a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From 1c2211cb15dd3957fb26c0e1615eceb5db851ad6 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:22 +0100
-Subject: [PATCH 06/13] net: dsa: mt7530: switch to use phylink_get_linkmodes()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Switch mt7530 to use phylink_get_linkmodes() to generate the ethtool
-linkmodes that can be supported. We are unable to use the generic
-helper for this as pause modes are dependent on the interface as
-the Autoneg bit depends on the interface mode.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 57 ++++------------------------------------
- 1 file changed, 5 insertions(+), 52 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2819,19 +2819,6 @@ static int mt7531_rgmii_setup(struct mt7
- return 0;
- }
-
--static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
-- phy_interface_t interface,
-- unsigned long *supported)
--{
-- /* Port5 supports ethier RGMII or SGMII.
-- * Port6 supports SGMII only.
-- */
-- if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) {
-- phylink_set(supported, 2500baseX_Full);
-- phylink_set(supported, 2500baseT_Full);
-- }
--}
--
- static void
- mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
- unsigned int mode, phy_interface_t interface,
-@@ -3198,51 +3185,21 @@ static void mt753x_phylink_get_caps(stru
- }
-
- static void
--mt7530_mac_port_validate(struct dsa_switch *ds, int port,
-- phy_interface_t interface,
-- unsigned long *supported)
--{
--}
--
--static void mt7531_mac_port_validate(struct dsa_switch *ds, int port,
-- phy_interface_t interface,
-- unsigned long *supported)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- mt7531_sgmii_validate(priv, port, interface, supported);
--}
--
--static void
- mt753x_phylink_validate(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state)
- {
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-- struct mt7530_priv *priv = ds->priv;
-+ u32 caps;
-+
-+ caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
-
- phylink_set_port_modes(mask);
-+ phylink_get_linkmodes(mask, state->interface, caps);
-
- if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
-- !phy_interface_mode_is_8023z(state->interface)) {
-- phylink_set(mask, 10baseT_Half);
-- phylink_set(mask, 10baseT_Full);
-- phylink_set(mask, 100baseT_Half);
-- phylink_set(mask, 100baseT_Full);
-+ !phy_interface_mode_is_8023z(state->interface))
- phylink_set(mask, Autoneg);
-- }
--
-- /* This switch only supports 1G full-duplex. */
-- if (state->interface != PHY_INTERFACE_MODE_MII &&
-- state->interface != PHY_INTERFACE_MODE_2500BASEX) {
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 1000baseX_Full);
-- }
--
-- priv->info->mac_port_validate(ds, port, state->interface, mask);
--
-- phylink_set(mask, Pause);
-- phylink_set(mask, Asym_Pause);
-
- linkmode_and(supported, supported, mask);
- linkmode_and(state->advertising, state->advertising, mask);
-@@ -3444,7 +3401,6 @@ static const struct mt753x_info mt753x_t
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
-- .mac_port_validate = mt7530_mac_port_validate,
- .mac_port_get_state = mt7530_phylink_mac_link_state,
- .mac_port_config = mt7530_mac_config,
- },
-@@ -3455,7 +3411,6 @@ static const struct mt753x_info mt753x_t
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
-- .mac_port_validate = mt7530_mac_port_validate,
- .mac_port_get_state = mt7530_phylink_mac_link_state,
- .mac_port_config = mt7530_mac_config,
- },
-@@ -3467,7 +3422,6 @@ static const struct mt753x_info mt753x_t
- .pad_setup = mt7531_pad_setup,
- .cpu_port_config = mt7531_cpu_port_config,
- .mac_port_get_caps = mt7531_mac_port_get_caps,
-- .mac_port_validate = mt7531_mac_port_validate,
- .mac_port_get_state = mt7531_phylink_mac_link_state,
- .mac_port_config = mt7531_mac_config,
- .mac_pcs_an_restart = mt7531_sgmii_restart_an,
-@@ -3529,7 +3483,6 @@ mt7530_probe(struct mdio_device *mdiodev
- if (!priv->info->sw_setup || !priv->info->pad_setup ||
- !priv->info->phy_read || !priv->info->phy_write ||
- !priv->info->mac_port_get_caps ||
-- !priv->info->mac_port_validate ||
- !priv->info->mac_port_get_state || !priv->info->mac_port_config)
- return -EINVAL;
-
diff --git a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch
deleted file mode 100644
index 149c12c1fb..0000000000
--- a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch
+++ /dev/null
@@ -1,385 +0,0 @@
-From fd993fd59d96d5e2d5972ec4ca1f9651025c987b Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:27 +0100
-Subject: [PATCH 07/13] net: dsa: mt7530: partially convert to phylink_pcs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Partially convert the mt7530 driver to use phylink's PCS support. This
-is a partial implementation as we don't move anything into the
-pcs_config method yet - this driver supports SGMII or 1000BASE-X
-without in-band.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 144 +++++++++++++++++++++++----------------
- drivers/net/dsa/mt7530.h | 21 +++---
- 2 files changed, 95 insertions(+), 70 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -25,6 +25,11 @@
-
- #include "mt7530.h"
-
-+static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)
-+{
-+ return container_of(pcs, struct mt753x_pcs, pcs);
-+}
-+
- /* String, offset, and register size in bytes if different from 4 bytes */
- static const struct mt7530_mib_desc mt7530_mib[] = {
- MIB_DESC(1, 0x00, "TxDrop"),
-@@ -2819,12 +2824,11 @@ static int mt7531_rgmii_setup(struct mt7
- return 0;
- }
-
--static void
--mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
-- unsigned int mode, phy_interface_t interface,
-- int speed, int duplex)
-+static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface, int speed, int duplex)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-+ int port = pcs_to_mt753x_pcs(pcs)->port;
- unsigned int val;
-
- /* For adjusting speed and duplex of SGMII force mode. */
-@@ -2850,6 +2854,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw
-
- /* MT7531 SGMII 1G force mode can only work in full duplex mode,
- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
-+ *
-+ * The speed check is unnecessary as the MAC capabilities apply
-+ * this restriction. --rmk
- */
- if ((speed == SPEED_10 || speed == SPEED_100) &&
- duplex != DUPLEX_FULL)
-@@ -2925,9 +2932,10 @@ static int mt7531_sgmii_setup_mode_an(st
- return 0;
- }
-
--static void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port)
-+static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-+ int port = pcs_to_mt753x_pcs(pcs)->port;
- u32 val;
-
- /* Only restart AN when AN is enabled */
-@@ -2984,6 +2992,24 @@ mt753x_mac_config(struct dsa_switch *ds,
- return priv->info->mac_port_config(ds, port, mode, state->interface);
- }
-
-+static struct phylink_pcs *
-+mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
-+ phy_interface_t interface)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_TRGMII:
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ return &priv->pcs[port].pcs;
-+
-+ default:
-+ return NULL;
-+ }
-+}
-+
- static void
- mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- const struct phylink_link_state *state)
-@@ -3045,17 +3071,6 @@ unsupported:
- mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
- }
-
--static void
--mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- if (!priv->info->mac_pcs_an_restart)
-- return;
--
-- priv->info->mac_pcs_an_restart(ds, port);
--}
--
- static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface)
-@@ -3065,16 +3080,13 @@ static void mt753x_phylink_mac_link_down
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
- }
-
--static void mt753x_mac_pcs_link_up(struct dsa_switch *ds, int port,
-- unsigned int mode, phy_interface_t interface,
-- int speed, int duplex)
-+static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs,
-+ unsigned int mode,
-+ phy_interface_t interface,
-+ int speed, int duplex)
- {
-- struct mt7530_priv *priv = ds->priv;
--
-- if (!priv->info->mac_pcs_link_up)
-- return;
--
-- priv->info->mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
-+ if (pcs->ops->pcs_link_up)
-+ pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
- }
-
- static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
-@@ -3087,8 +3099,6 @@ static void mt753x_phylink_mac_link_up(s
- struct mt7530_priv *priv = ds->priv;
- u32 mcr;
-
-- mt753x_mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
--
- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
-
- /* MT753x MAC works in 1G full duplex mode for all up-clocked
-@@ -3166,6 +3176,8 @@ mt7531_cpu_port_config(struct dsa_switch
- return ret;
- mt7530_write(priv, MT7530_PMCR_P(port),
- PMCR_CPU_PORT_SETTING(priv->id));
-+ mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED,
-+ interface, speed, DUPLEX_FULL);
- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
- speed, DUPLEX_FULL, true, true);
-
-@@ -3205,16 +3217,13 @@ mt753x_phylink_validate(struct dsa_switc
- linkmode_and(state->advertising, state->advertising, mask);
- }
-
--static int
--mt7530_phylink_mac_link_state(struct dsa_switch *ds, int port,
-- struct phylink_link_state *state)
-+static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-+ int port = pcs_to_mt753x_pcs(pcs)->port;
- u32 pmsr;
-
-- if (port < 0 || port >= MT7530_NUM_PORTS)
-- return -EINVAL;
--
- pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
-
- state->link = (pmsr & PMSR_LINK);
-@@ -3241,8 +3250,6 @@ mt7530_phylink_mac_link_state(struct dsa
- state->pause |= MLO_PAUSE_RX;
- if (pmsr & PMSR_TX_FC)
- state->pause |= MLO_PAUSE_TX;
--
-- return 1;
- }
-
- static int
-@@ -3284,32 +3291,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
- return 0;
- }
-
--static int
--mt7531_phylink_mac_link_state(struct dsa_switch *ds, int port,
-- struct phylink_link_state *state)
-+static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-+ int port = pcs_to_mt753x_pcs(pcs)->port;
-
- if (state->interface == PHY_INTERFACE_MODE_SGMII)
-- return mt7531_sgmii_pcs_get_state_an(priv, port, state);
--
-- return -EOPNOTSUPP;
-+ mt7531_sgmii_pcs_get_state_an(priv, port, state);
-+ else
-+ state->link = false;
- }
-
--static int
--mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
-- struct phylink_link_state *state)
-+static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface,
-+ const unsigned long *advertising,
-+ bool permit_pause_to_mac)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ return 0;
-+}
-
-- return priv->info->mac_port_get_state(ds, port, state);
-+static void mt7530_pcs_an_restart(struct phylink_pcs *pcs)
-+{
- }
-
-+static const struct phylink_pcs_ops mt7530_pcs_ops = {
-+ .pcs_get_state = mt7530_pcs_get_state,
-+ .pcs_config = mt753x_pcs_config,
-+ .pcs_an_restart = mt7530_pcs_an_restart,
-+};
-+
-+static const struct phylink_pcs_ops mt7531_pcs_ops = {
-+ .pcs_get_state = mt7531_pcs_get_state,
-+ .pcs_config = mt753x_pcs_config,
-+ .pcs_an_restart = mt7531_pcs_an_restart,
-+ .pcs_link_up = mt7531_pcs_link_up,
-+};
-+
- static int
- mt753x_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
- int ret = priv->info->sw_setup(ds);
-+ int i;
-
- if (ret)
- return ret;
-@@ -3322,6 +3346,13 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-+ /* Initialise the PCS devices */
-+ for (i = 0; i < priv->ds->num_ports; i++) {
-+ priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-+ priv->pcs[i].priv = priv;
-+ priv->pcs[i].port = i;
-+ }
-+
- return ret;
- }
-
-@@ -3384,9 +3415,8 @@ static const struct dsa_switch_ops mt753
- .port_mirror_del = mt753x_port_mirror_del,
- .phylink_get_caps = mt753x_phylink_get_caps,
- .phylink_validate = mt753x_phylink_validate,
-- .phylink_mac_link_state = mt753x_phylink_mac_link_state,
-+ .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
- .phylink_mac_config = mt753x_phylink_mac_config,
-- .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
- .phylink_mac_link_down = mt753x_phylink_mac_link_down,
- .phylink_mac_link_up = mt753x_phylink_mac_link_up,
- .get_mac_eee = mt753x_get_mac_eee,
-@@ -3396,36 +3426,34 @@ static const struct dsa_switch_ops mt753
- static const struct mt753x_info mt753x_table[] = {
- [ID_MT7621] = {
- .id = ID_MT7621,
-+ .pcs_ops = &mt7530_pcs_ops,
- .sw_setup = mt7530_setup,
- .phy_read = mt7530_phy_read,
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
-- .mac_port_get_state = mt7530_phylink_mac_link_state,
- .mac_port_config = mt7530_mac_config,
- },
- [ID_MT7530] = {
- .id = ID_MT7530,
-+ .pcs_ops = &mt7530_pcs_ops,
- .sw_setup = mt7530_setup,
- .phy_read = mt7530_phy_read,
- .phy_write = mt7530_phy_write,
- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
-- .mac_port_get_state = mt7530_phylink_mac_link_state,
- .mac_port_config = mt7530_mac_config,
- },
- [ID_MT7531] = {
- .id = ID_MT7531,
-+ .pcs_ops = &mt7531_pcs_ops,
- .sw_setup = mt7531_setup,
- .phy_read = mt7531_ind_phy_read,
- .phy_write = mt7531_ind_phy_write,
- .pad_setup = mt7531_pad_setup,
- .cpu_port_config = mt7531_cpu_port_config,
- .mac_port_get_caps = mt7531_mac_port_get_caps,
-- .mac_port_get_state = mt7531_phylink_mac_link_state,
- .mac_port_config = mt7531_mac_config,
-- .mac_pcs_an_restart = mt7531_sgmii_restart_an,
-- .mac_pcs_link_up = mt7531_sgmii_link_up_force,
- },
- };
-
-@@ -3483,7 +3511,7 @@ mt7530_probe(struct mdio_device *mdiodev
- if (!priv->info->sw_setup || !priv->info->pad_setup ||
- !priv->info->phy_read || !priv->info->phy_write ||
- !priv->info->mac_port_get_caps ||
-- !priv->info->mac_port_get_state || !priv->info->mac_port_config)
-+ !priv->info->mac_port_config)
- return -EINVAL;
-
- priv->id = priv->info->id;
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -779,6 +779,12 @@ static const char *p5_intf_modes(unsigne
-
- struct mt7530_priv;
-
-+struct mt753x_pcs {
-+ struct phylink_pcs pcs;
-+ struct mt7530_priv *priv;
-+ int port;
-+};
-+
- /* struct mt753x_info - This is the main data structure for holding the specific
- * part for each supported device
- * @sw_setup: Holding the handler to a device initialization
-@@ -790,18 +796,14 @@ struct mt7530_priv;
- * port
- * @mac_port_validate: Holding the way to set addition validate type for a
- * certan MAC port
-- * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain
-- * MAC port
- * @mac_port_config: Holding the way setting up the PHY attribute to a
- * certain MAC port
-- * @mac_pcs_an_restart Holding the way restarting PCS autonegotiation for a
-- * certain MAC port
-- * @mac_pcs_link_up: Holding the way setting up the PHY attribute to the pcs
-- * of the certain MAC port
- */
- struct mt753x_info {
- enum mt753x_id id;
-
-+ const struct phylink_pcs_ops *pcs_ops;
-+
- int (*sw_setup)(struct dsa_switch *ds);
- int (*phy_read)(struct mt7530_priv *priv, int port, int regnum);
- int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
-@@ -812,15 +814,9 @@ struct mt753x_info {
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
- phy_interface_t interface,
- unsigned long *supported);
-- int (*mac_port_get_state)(struct dsa_switch *ds, int port,
-- struct phylink_link_state *state);
- int (*mac_port_config)(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface);
-- void (*mac_pcs_an_restart)(struct dsa_switch *ds, int port);
-- void (*mac_pcs_link_up)(struct dsa_switch *ds, int port,
-- unsigned int mode, phy_interface_t interface,
-- int speed, int duplex);
- };
-
- /* struct mt7530_priv - This is the main data structure for holding the state
-@@ -862,6 +858,7 @@ struct mt7530_priv {
- u8 mirror_tx;
-
- struct mt7530_port ports[MT7530_NUM_PORTS];
-+ struct mt753x_pcs pcs[MT7530_NUM_PORTS];
- /* protect among processes for registers access*/
- struct mutex reg_mutex;
- int irq;
diff --git a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch
deleted file mode 100644
index 6e406ace0d..0000000000
--- a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 2b0ee6768f3ac09072e5fd60b36580924e1cfa1c Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:32 +0100
-Subject: [PATCH 08/13] net: dsa: mt7530: move autoneg handling to PCS
- validation
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move the autoneg bit handling to the PCS validation, which allows us to
-get rid of mt753x_phylink_validate() and rely on the default
-phylink_generic_validate() implementation for the MAC side.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 28 ++++++++++------------------
- 1 file changed, 10 insertions(+), 18 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3196,25 +3196,16 @@ static void mt753x_phylink_get_caps(stru
- priv->info->mac_port_get_caps(ds, port, config);
- }
-
--static void
--mt753x_phylink_validate(struct dsa_switch *ds, int port,
-- unsigned long *supported,
-- struct phylink_link_state *state)
--{
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-- u32 caps;
--
-- caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
--
-- phylink_set_port_modes(mask);
-- phylink_get_linkmodes(mask, state->interface, caps);
-+static int mt753x_pcs_validate(struct phylink_pcs *pcs,
-+ unsigned long *supported,
-+ const struct phylink_link_state *state)
-+{
-+ /* Autonegotiation is not supported in TRGMII nor 802.3z modes */
-+ if (state->interface == PHY_INTERFACE_MODE_TRGMII ||
-+ phy_interface_mode_is_8023z(state->interface))
-+ phylink_clear(supported, Autoneg);
-
-- if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
-- !phy_interface_mode_is_8023z(state->interface))
-- phylink_set(mask, Autoneg);
--
-- linkmode_and(supported, supported, mask);
-- linkmode_and(state->advertising, state->advertising, mask);
-+ return 0;
- }
-
- static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
-@@ -3316,12 +3307,14 @@ static void mt7530_pcs_an_restart(struct
- }
-
- static const struct phylink_pcs_ops mt7530_pcs_ops = {
-+ .pcs_validate = mt753x_pcs_validate,
- .pcs_get_state = mt7530_pcs_get_state,
- .pcs_config = mt753x_pcs_config,
- .pcs_an_restart = mt7530_pcs_an_restart,
- };
-
- static const struct phylink_pcs_ops mt7531_pcs_ops = {
-+ .pcs_validate = mt753x_pcs_validate,
- .pcs_get_state = mt7531_pcs_get_state,
- .pcs_config = mt753x_pcs_config,
- .pcs_an_restart = mt7531_pcs_an_restart,
-@@ -3414,7 +3407,6 @@ static const struct dsa_switch_ops mt753
- .port_mirror_add = mt753x_port_mirror_add,
- .port_mirror_del = mt753x_port_mirror_del,
- .phylink_get_caps = mt753x_phylink_get_caps,
-- .phylink_validate = mt753x_phylink_validate,
- .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
- .phylink_mac_config = mt753x_phylink_mac_config,
- .phylink_mac_link_down = mt753x_phylink_mac_link_down,
diff --git a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch
deleted file mode 100644
index afcfcaba34..0000000000
--- a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 5bc26de9bfaa6bb5539c09d4435dced98f429cfc Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 11 Apr 2022 10:46:37 +0100
-Subject: [PATCH 09/13] net: dsa: mt7530: mark as non-legacy
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The mt7530 driver does not make use of the speed, duplex, pause or
-advertisement in its phylink_mac_config() implementation, so it can be
-marked as a non-legacy driver.
-
-Tested-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3193,6 +3193,12 @@ static void mt753x_phylink_get_caps(stru
- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000FD;
-
-+ /* This driver does not make use of the speed, duplex, pause or the
-+ * advertisement in its mac_config, so it is safe to mark this driver
-+ * as non-legacy.
-+ */
-+ config->legacy_pre_march2020 = false;
-+
- priv->info->mac_port_get_caps(ds, port, config);
- }
-
diff --git a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch
deleted file mode 100644
index bf2938d03b..0000000000
--- a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 1f15b5e8733115cee65342bcaafeaf0368809fae Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 25 Apr 2022 22:28:02 +0100
-Subject: [PATCH 10/13] net: dsa: mt753x: fix pcs conversion regression
-
-Daniel Golle reports that the conversion of mt753x to phylink PCS caused
-an oops as below.
-
-The problem is with the placement of the PCS initialisation, which
-occurs after mt7531_setup() has been called. However, burited in this
-function is a call to setup the CPU port, which requires the PCS
-structure to be already setup.
-
-Fix this by changing the initialisation order.
-
-Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020
-Mem abort info:
- ESR = 0x96000005
- EC = 0x25: DABT (current EL), IL = 32 bits
- SET = 0, FnV = 0
- EA = 0, S1PTW = 0
- FSC = 0x05: level 1 translation fault
-Data abort info:
- ISV = 0, ISS = 0x00000005
- CM = 0, WnR = 0
-user pgtable: 4k pages, 39-bit VAs, pgdp=0000000046057000
-[0000000000000020] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
-Internal error: Oops: 96000005 [#1] SMP
-Modules linked in:
-CPU: 0 PID: 32 Comm: kworker/u4:1 Tainted: G S 5.18.0-rc3-next-20220422+ #0
-Hardware name: Bananapi BPI-R64 (DT)
-Workqueue: events_unbound deferred_probe_work_func
-pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
-pc : mt7531_cpu_port_config+0xcc/0x1b0
-lr : mt7531_cpu_port_config+0xc0/0x1b0
-sp : ffffffc008d5b980
-x29: ffffffc008d5b990 x28: ffffff80060562c8 x27: 00000000f805633b
-x26: ffffff80001a8880 x25: 00000000000009c4 x24: 0000000000000016
-x23: ffffff8005eb6470 x22: 0000000000003600 x21: ffffff8006948080
-x20: 0000000000000000 x19: 0000000000000006 x18: 0000000000000000
-x17: 0000000000000001 x16: 0000000000000001 x15: 02963607fcee069e
-x14: 0000000000000000 x13: 0000000000000030 x12: 0101010101010101
-x11: ffffffc037302000 x10: 0000000000000870 x9 : ffffffc008d5b800
-x8 : ffffff800028f950 x7 : 0000000000000001 x6 : 00000000662b3000
-x5 : 00000000000002f0 x4 : 0000000000000000 x3 : ffffff800028f080
-x2 : 0000000000000000 x1 : ffffff800028f080 x0 : 0000000000000000
-Call trace:
- mt7531_cpu_port_config+0xcc/0x1b0
- mt753x_cpu_port_enable+0x24/0x1f0
- mt7531_setup+0x49c/0x5c0
- mt753x_setup+0x20/0x31c
- dsa_register_switch+0x8bc/0x1020
- mt7530_probe+0x118/0x200
- mdio_probe+0x30/0x64
- really_probe.part.0+0x98/0x280
- __driver_probe_device+0x94/0x140
- driver_probe_device+0x40/0x114
- __device_attach_driver+0xb0/0x10c
- bus_for_each_drv+0x64/0xa0
- __device_attach+0xa8/0x16c
- device_initial_probe+0x10/0x20
- bus_probe_device+0x94/0x9c
- deferred_probe_work_func+0x80/0xb4
- process_one_work+0x200/0x3a0
- worker_thread+0x260/0x4c0
- kthread+0xd4/0xe0
- ret_from_fork+0x10/0x20
-Code: 9409e911 937b7e60 8b0002a0 f9405800 (f9401005)
----[ end trace 0000000000000000 ]---
-
-Reported-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Fixes: cbd1f243bc41 ("net: dsa: mt7530: partially convert to phylink_pcs")
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Link: https://lore.kernel.org/r/E1nj6FW-007WZB-5Y@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3331,9 +3331,16 @@ static int
- mt753x_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-- int ret = priv->info->sw_setup(ds);
-- int i;
-+ int i, ret;
-
-+ /* Initialise the PCS devices */
-+ for (i = 0; i < priv->ds->num_ports; i++) {
-+ priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-+ priv->pcs[i].priv = priv;
-+ priv->pcs[i].port = i;
-+ }
-+
-+ ret = priv->info->sw_setup(ds);
- if (ret)
- return ret;
-
-@@ -3345,13 +3352,6 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-- /* Initialise the PCS devices */
-- for (i = 0; i < priv->ds->num_ports; i++) {
-- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-- priv->pcs[i].priv = priv;
-- priv->pcs[i].port = i;
-- }
--
- return ret;
- }
-
diff --git a/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch b/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch
deleted file mode 100644
index 320b5c1ef9..0000000000
--- a/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From e26be16262e1fc1e9f1798c12762663bd9c265c6 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Fri, 10 Jun 2022 19:05:37 +0200
-Subject: [PATCH 11/13] net: dsa: mt7530: rework mt7530_hw_vlan_{add,del}
-
-Rework vlan_add/vlan_del functions in preparation for dynamic cpu port.
-
-Currently BIT(MT7530_CPU_PORT) is added to new_members, even though
-mt7530_port_vlan_add() will be called on the CPU port too.
-
-Let DSA core decide when to call port_vlan_add for the CPU port, rather
-than doing it implicitly.
-
-We can do autonomous forwarding in a certain VLAN, but not add br0 to that
-VLAN and avoid flooding the CPU with those packets, if software knows it
-doesn't need to process them.
-
-Suggested-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 30 ++++++++++++------------------
- 1 file changed, 12 insertions(+), 18 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1771,11 +1771,11 @@ static void
- mt7530_hw_vlan_add(struct mt7530_priv *priv,
- struct mt7530_hw_vlan_entry *entry)
- {
-+ struct dsa_port *dp = dsa_to_port(priv->ds, entry->port);
- u8 new_members;
- u32 val;
-
-- new_members = entry->old_members | BIT(entry->port) |
-- BIT(MT7530_CPU_PORT);
-+ new_members = entry->old_members | BIT(entry->port);
-
- /* Validate the entry with independent learning, create egress tag per
- * VLAN and joining the port as one of the port members.
-@@ -1786,22 +1786,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *p
-
- /* Decide whether adding tag or not for those outgoing packets from the
- * port inside the VLAN.
-- */
-- val = entry->untagged ? MT7530_VLAN_EGRESS_UNTAG :
-- MT7530_VLAN_EGRESS_TAG;
-- mt7530_rmw(priv, MT7530_VAWD2,
-- ETAG_CTRL_P_MASK(entry->port),
-- ETAG_CTRL_P(entry->port, val));
--
-- /* CPU port is always taken as a tagged port for serving more than one
-+ * CPU port is always taken as a tagged port for serving more than one
- * VLANs across and also being applied with egress type stack mode for
- * that VLAN tags would be appended after hardware special tag used as
- * DSA tag.
- */
-+ if (dsa_port_is_cpu(dp))
-+ val = MT7530_VLAN_EGRESS_STACK;
-+ else if (entry->untagged)
-+ val = MT7530_VLAN_EGRESS_UNTAG;
-+ else
-+ val = MT7530_VLAN_EGRESS_TAG;
- mt7530_rmw(priv, MT7530_VAWD2,
-- ETAG_CTRL_P_MASK(MT7530_CPU_PORT),
-- ETAG_CTRL_P(MT7530_CPU_PORT,
-- MT7530_VLAN_EGRESS_STACK));
-+ ETAG_CTRL_P_MASK(entry->port),
-+ ETAG_CTRL_P(entry->port, val));
- }
-
- static void
-@@ -1820,11 +1818,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p
- return;
- }
-
-- /* If certain member apart from CPU port is still alive in the VLAN,
-- * the entry would be kept valid. Otherwise, the entry is got to be
-- * disabled.
-- */
-- if (new_members && new_members != BIT(MT7530_CPU_PORT)) {
-+ if (new_members) {
- val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) |
- VLAN_VALID;
- mt7530_write(priv, MT7530_VAWD1, val);
diff --git a/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch b/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch
deleted file mode 100644
index eef19b4cb5..0000000000
--- a/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From ad2606f6fafae3a7d41c4f2af5554c8f6adecbc7 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Fri, 10 Jun 2022 19:05:39 +0200
-Subject: [PATCH 13/13] net: dsa: mt7530: get cpu-port via dp->cpu_dp instead
- of constant
-
-Replace last occurences of hardcoded cpu-port by cpu_dp member of
-dsa_port struct.
-
-Now the constant can be dropped.
-
-Suggested-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 27 ++++++++++++++++++++-------
- drivers/net/dsa/mt7530.h | 1 -
- 2 files changed, 20 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1275,6 +1275,7 @@ static int
- mt7530_port_enable(struct dsa_switch *ds, int port,
- struct phy_device *phy)
- {
-+ struct dsa_port *dp = dsa_to_port(ds, port);
- struct mt7530_priv *priv = ds->priv;
-
- mutex_lock(&priv->reg_mutex);
-@@ -1283,7 +1284,11 @@ mt7530_port_enable(struct dsa_switch *ds
- * restore the port matrix if the port is the member of a certain
- * bridge.
- */
-- priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
-+ if (dsa_port_is_user(dp)) {
-+ struct dsa_port *cpu_dp = dp->cpu_dp;
-+
-+ priv->ports[port].pm |= PCR_MATRIX(BIT(cpu_dp->index));
-+ }
- priv->ports[port].enable = true;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- priv->ports[port].pm);
-@@ -1431,7 +1436,8 @@ mt7530_port_bridge_join(struct dsa_switc
- struct net_device *bridge)
- {
- struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
-- u32 port_bitmap = BIT(MT7530_CPU_PORT);
-+ struct dsa_port *cpu_dp = dp->cpu_dp;
-+ u32 port_bitmap = BIT(cpu_dp->index);
- struct mt7530_priv *priv = ds->priv;
-
- mutex_lock(&priv->reg_mutex);
-@@ -1508,9 +1514,12 @@ mt7530_port_set_vlan_unaware(struct dsa_
- * the CPU port get out of VLAN filtering mode.
- */
- if (all_user_ports_removed) {
-- mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT),
-+ struct dsa_port *dp = dsa_to_port(ds, port);
-+ struct dsa_port *cpu_dp = dp->cpu_dp;
-+
-+ mt7530_write(priv, MT7530_PCR_P(cpu_dp->index),
- PCR_MATRIX(dsa_user_ports(priv->ds)));
-- mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), PORT_SPEC_TAG
-+ mt7530_write(priv, MT7530_PVC_P(cpu_dp->index), PORT_SPEC_TAG
- | PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
- }
- }
-@@ -1560,6 +1569,7 @@ mt7530_port_bridge_leave(struct dsa_swit
- struct net_device *bridge)
- {
- struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
-+ struct dsa_port *cpu_dp = dp->cpu_dp;
- struct mt7530_priv *priv = ds->priv;
-
- mutex_lock(&priv->reg_mutex);
-@@ -1588,8 +1598,8 @@ mt7530_port_bridge_leave(struct dsa_swit
- */
- if (priv->ports[port].enable)
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
-- PCR_MATRIX(BIT(MT7530_CPU_PORT)));
-- priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
-+ PCR_MATRIX(BIT(cpu_dp->index)));
-+ priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index));
-
- /* When a port is removed from the bridge, the port would be set up
- * back to the default as is at initial boot which is a VLAN-unaware
-@@ -1752,6 +1762,9 @@ static int
- mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
- struct netlink_ext_ack *extack)
- {
-+ struct dsa_port *dp = dsa_to_port(ds, port);
-+ struct dsa_port *cpu_dp = dp->cpu_dp;
-+
- if (vlan_filtering) {
- /* The port is being kept as VLAN-unaware port when bridge is
- * set up with vlan_filtering not being set, Otherwise, the
-@@ -1759,7 +1772,7 @@ mt7530_port_vlan_filtering(struct dsa_sw
- * for becoming a VLAN-aware port.
- */
- mt7530_port_set_vlan_aware(ds, port);
-- mt7530_port_set_vlan_aware(ds, MT7530_CPU_PORT);
-+ mt7530_port_set_vlan_aware(ds, cpu_dp->index);
- } else {
- mt7530_port_set_vlan_unaware(ds, port);
- }
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -8,7 +8,6 @@
-
- #define MT7530_NUM_PORTS 7
- #define MT7530_NUM_PHYS 5
--#define MT7530_CPU_PORT 6
- #define MT7530_NUM_FDB_RECORDS 2048
- #define MT7530_ALL_MEMBERS 0xff
-
diff --git a/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch b/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch
deleted file mode 100644
index f022f7bf54..0000000000
--- a/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch
+++ /dev/null
@@ -1,330 +0,0 @@
-From 23233e577ef973c2c5d0dd757a0a4605e34ecb57 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 22 Jul 2022 09:19:36 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on page_pool for single page
- buffers
-
-Rely on page_pool allocator for single page buffers in order to keep
-them dma mapped and add skb recycling support.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/Kconfig | 1 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 185 +++++++++++++++-----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++
- 3 files changed, 156 insertions(+), 40 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -16,6 +16,7 @@ config NET_MEDIATEK_SOC
- depends on NET_DSA || !NET_DSA
- select PHYLINK
- select DIMLIB
-+ select PAGE_POOL
- help
- This driver supports the gigabit ethernet MACs in the
- MediaTek SoC family.
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1388,6 +1388,68 @@ static void mtk_update_rx_cpu_idx(struct
- }
- }
-
-+static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
-+ struct xdp_rxq_info *xdp_q,
-+ int id, int size)
-+{
-+ struct page_pool_params pp_params = {
-+ .order = 0,
-+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
-+ .pool_size = size,
-+ .nid = NUMA_NO_NODE,
-+ .dev = eth->dma_dev,
-+ .dma_dir = DMA_FROM_DEVICE,
-+ .offset = MTK_PP_HEADROOM,
-+ .max_len = MTK_PP_MAX_BUF_SIZE,
-+ };
-+ struct page_pool *pp;
-+ int err;
-+
-+ pp = page_pool_create(&pp_params);
-+ if (IS_ERR(pp))
-+ return pp;
-+
-+ err = xdp_rxq_info_reg(xdp_q, &eth->dummy_dev, id,
-+ eth->rx_napi.napi_id);
-+ if (err < 0)
-+ goto err_free_pp;
-+
-+ err = xdp_rxq_info_reg_mem_model(xdp_q, MEM_TYPE_PAGE_POOL, pp);
-+ if (err)
-+ goto err_unregister_rxq;
-+
-+ return pp;
-+
-+err_unregister_rxq:
-+ xdp_rxq_info_unreg(xdp_q);
-+err_free_pp:
-+ page_pool_destroy(pp);
-+
-+ return ERR_PTR(err);
-+}
-+
-+static void *mtk_page_pool_get_buff(struct page_pool *pp, dma_addr_t *dma_addr,
-+ gfp_t gfp_mask)
-+{
-+ struct page *page;
-+
-+ page = page_pool_alloc_pages(pp, gfp_mask | __GFP_NOWARN);
-+ if (!page)
-+ return NULL;
-+
-+ *dma_addr = page_pool_get_dma_addr(page) + MTK_PP_HEADROOM;
-+ return page_address(page);
-+}
-+
-+static void mtk_rx_put_buff(struct mtk_rx_ring *ring, void *data, bool napi)
-+{
-+ if (ring->page_pool)
-+ page_pool_put_full_page(ring->page_pool,
-+ virt_to_head_page(data), napi);
-+ else
-+ skb_free_frag(data);
-+}
-+
- static int mtk_poll_rx(struct napi_struct *napi, int budget,
- struct mtk_eth *eth)
- {
-@@ -1401,9 +1463,9 @@ static int mtk_poll_rx(struct napi_struc
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
-+ u32 hash, reason, reserve_len;
- struct net_device *netdev;
- dma_addr_t dma_addr;
-- u32 hash, reason;
- int mac = 0;
-
- ring = mtk_get_rx_ring(eth);
-@@ -1434,36 +1496,54 @@ static int mtk_poll_rx(struct napi_struc
- goto release_desc;
-
- /* alloc new buffer */
-- if (ring->frag_size <= PAGE_SIZE)
-- new_data = napi_alloc_frag(ring->frag_size);
-- else
-- new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC);
-- if (unlikely(!new_data)) {
-- netdev->stats.rx_dropped++;
-- goto release_desc;
-- }
-- dma_addr = dma_map_single(eth->dma_dev,
-- new_data + NET_SKB_PAD +
-- eth->ip_align,
-- ring->buf_size,
-- DMA_FROM_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) {
-- skb_free_frag(new_data);
-- netdev->stats.rx_dropped++;
-- goto release_desc;
-- }
-+ if (ring->page_pool) {
-+ new_data = mtk_page_pool_get_buff(ring->page_pool,
-+ &dma_addr,
-+ GFP_ATOMIC);
-+ if (unlikely(!new_data)) {
-+ netdev->stats.rx_dropped++;
-+ goto release_desc;
-+ }
-+ } else {
-+ if (ring->frag_size <= PAGE_SIZE)
-+ new_data = napi_alloc_frag(ring->frag_size);
-+ else
-+ new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC);
-+
-+ if (unlikely(!new_data)) {
-+ netdev->stats.rx_dropped++;
-+ goto release_desc;
-+ }
-
-- dma_unmap_single(eth->dma_dev, trxd.rxd1,
-- ring->buf_size, DMA_FROM_DEVICE);
-+ dma_addr = dma_map_single(eth->dma_dev,
-+ new_data + NET_SKB_PAD + eth->ip_align,
-+ ring->buf_size, DMA_FROM_DEVICE);
-+ if (unlikely(dma_mapping_error(eth->dma_dev,
-+ dma_addr))) {
-+ skb_free_frag(new_data);
-+ netdev->stats.rx_dropped++;
-+ goto release_desc;
-+ }
-+
-+ dma_unmap_single(eth->dma_dev, trxd.rxd1,
-+ ring->buf_size, DMA_FROM_DEVICE);
-+ }
-
- /* receive data */
- skb = build_skb(data, ring->frag_size);
- if (unlikely(!skb)) {
-- skb_free_frag(data);
-+ mtk_rx_put_buff(ring, data, true);
- netdev->stats.rx_dropped++;
- goto skip_rx;
- }
-- skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
-+
-+ if (ring->page_pool) {
-+ reserve_len = MTK_PP_HEADROOM;
-+ skb_mark_for_recycle(skb);
-+ } else {
-+ reserve_len = NET_SKB_PAD + NET_IP_ALIGN;
-+ }
-+ skb_reserve(skb, reserve_len);
-
- pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
- skb->dev = netdev;
-@@ -1517,7 +1597,6 @@ static int mtk_poll_rx(struct napi_struc
- skip_rx:
- ring->data[idx] = new_data;
- rxd->rxd1 = (unsigned int)dma_addr;
--
- release_desc:
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
- rxd->rxd2 = RX_DMA_LSO;
-@@ -1525,7 +1604,6 @@ release_desc:
- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
- ring->calc_idx = idx;
--
- done++;
- }
-
-@@ -1889,13 +1967,15 @@ static int mtk_rx_alloc(struct mtk_eth *
- if (!ring->data)
- return -ENOMEM;
-
-- for (i = 0; i < rx_dma_size; i++) {
-- if (ring->frag_size <= PAGE_SIZE)
-- ring->data[i] = netdev_alloc_frag(ring->frag_size);
-- else
-- ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL);
-- if (!ring->data[i])
-- return -ENOMEM;
-+ if (!eth->hwlro) {
-+ struct page_pool *pp;
-+
-+ pp = mtk_create_page_pool(eth, &ring->xdp_q, ring_no,
-+ rx_dma_size);
-+ if (IS_ERR(pp))
-+ return PTR_ERR(pp);
-+
-+ ring->page_pool = pp;
- }
-
- ring->dma = dma_alloc_coherent(eth->dma_dev,
-@@ -1906,16 +1986,33 @@ static int mtk_rx_alloc(struct mtk_eth *
-
- for (i = 0; i < rx_dma_size; i++) {
- struct mtk_rx_dma_v2 *rxd;
--
-- dma_addr_t dma_addr = dma_map_single(eth->dma_dev,
-- ring->data[i] + NET_SKB_PAD + eth->ip_align,
-- ring->buf_size,
-- DMA_FROM_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
-- return -ENOMEM;
-+ dma_addr_t dma_addr;
-+ void *data;
-
- rxd = ring->dma + i * eth->soc->txrx.rxd_size;
-+ if (ring->page_pool) {
-+ data = mtk_page_pool_get_buff(ring->page_pool,
-+ &dma_addr, GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+ } else {
-+ if (ring->frag_size <= PAGE_SIZE)
-+ data = netdev_alloc_frag(ring->frag_size);
-+ else
-+ data = mtk_max_lro_buf_alloc(GFP_KERNEL);
-+
-+ if (!data)
-+ return -ENOMEM;
-+
-+ dma_addr = dma_map_single(eth->dma_dev,
-+ data + NET_SKB_PAD + eth->ip_align,
-+ ring->buf_size, DMA_FROM_DEVICE);
-+ if (unlikely(dma_mapping_error(eth->dma_dev,
-+ dma_addr)))
-+ return -ENOMEM;
-+ }
- rxd->rxd1 = (unsigned int)dma_addr;
-+ ring->data[i] = data;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
- rxd->rxd2 = RX_DMA_LSO;
-@@ -1931,6 +2028,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- rxd->rxd8 = 0;
- }
- }
-+
- ring->dma_size = rx_dma_size;
- ring->calc_idx_update = false;
- ring->calc_idx = rx_dma_size - 1;
-@@ -1982,7 +2080,7 @@ static void mtk_rx_clean(struct mtk_eth
-
- dma_unmap_single(eth->dma_dev, rxd->rxd1,
- ring->buf_size, DMA_FROM_DEVICE);
-- skb_free_frag(ring->data[i]);
-+ mtk_rx_put_buff(ring, ring->data[i], false);
- }
- kfree(ring->data);
- ring->data = NULL;
-@@ -1994,6 +2092,13 @@ static void mtk_rx_clean(struct mtk_eth
- ring->dma, ring->phys);
- ring->dma = NULL;
- }
-+
-+ if (ring->page_pool) {
-+ if (xdp_rxq_info_is_reg(&ring->xdp_q))
-+ xdp_rxq_info_unreg(&ring->xdp_q);
-+ page_pool_destroy(ring->page_pool);
-+ ring->page_pool = NULL;
-+ }
- }
-
- static int mtk_hwlro_rx_init(struct mtk_eth *eth)
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -18,6 +18,8 @@
- #include <linux/rhashtable.h>
- #include <linux/dim.h>
- #include <linux/bitfield.h>
-+#include <net/page_pool.h>
-+#include <linux/bpf_trace.h>
- #include "mtk_ppe.h"
-
- #define MTK_QDMA_PAGE_SIZE 2048
-@@ -49,6 +51,11 @@
- #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM)
- #define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1))
-
-+#define MTK_PP_HEADROOM XDP_PACKET_HEADROOM
-+#define MTK_PP_PAD (MTK_PP_HEADROOM + \
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-+#define MTK_PP_MAX_BUF_SIZE (PAGE_SIZE - MTK_PP_PAD)
-+
- #define MTK_QRX_OFFSET 0x10
-
- #define MTK_MAX_RX_RING_NUM 4
-@@ -743,6 +750,9 @@ struct mtk_rx_ring {
- bool calc_idx_update;
- u16 calc_idx;
- u32 crx_idx_reg;
-+ /* page_pool */
-+ struct page_pool *page_pool;
-+ struct xdp_rxq_info xdp_q;
- };
-
- enum mkt_eth_capabilities {
diff --git a/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch b/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch
deleted file mode 100644
index 94efa92986..0000000000
--- a/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch
+++ /dev/null
@@ -1,291 +0,0 @@
-From 7c26c20da5d420cde55618263be4aa2f6de53056 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 22 Jul 2022 09:19:37 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add basic XDP support
-
-Introduce basic XDP support to mtk_eth_soc driver.
-Supported XDP verdicts:
-- XDP_PASS
-- XDP_DROP
-- XDP_REDIRECT
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 162 +++++++++++++++++---
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +
- 2 files changed, 145 insertions(+), 19 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1388,6 +1388,11 @@ static void mtk_update_rx_cpu_idx(struct
- }
- }
-
-+static bool mtk_page_pool_enabled(struct mtk_eth *eth)
-+{
-+ return !eth->hwlro;
-+}
-+
- static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
- struct xdp_rxq_info *xdp_q,
- int id, int size)
-@@ -1450,11 +1455,52 @@ static void mtk_rx_put_buff(struct mtk_r
- skb_free_frag(data);
- }
-
-+static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring,
-+ struct xdp_buff *xdp, struct net_device *dev)
-+{
-+ struct bpf_prog *prog;
-+ u32 act = XDP_PASS;
-+
-+ rcu_read_lock();
-+
-+ prog = rcu_dereference(eth->prog);
-+ if (!prog)
-+ goto out;
-+
-+ act = bpf_prog_run_xdp(prog, xdp);
-+ switch (act) {
-+ case XDP_PASS:
-+ goto out;
-+ case XDP_REDIRECT:
-+ if (unlikely(xdp_do_redirect(dev, xdp, prog))) {
-+ act = XDP_DROP;
-+ break;
-+ }
-+ goto out;
-+ default:
-+ bpf_warn_invalid_xdp_action(act);
-+ fallthrough;
-+ case XDP_ABORTED:
-+ trace_xdp_exception(dev, prog, act);
-+ fallthrough;
-+ case XDP_DROP:
-+ break;
-+ }
-+
-+ page_pool_put_full_page(ring->page_pool,
-+ virt_to_head_page(xdp->data), true);
-+out:
-+ rcu_read_unlock();
-+
-+ return act;
-+}
-+
- 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;
-+ bool xdp_flush = false;
- int idx;
- struct sk_buff *skb;
- u8 *data, *new_data;
-@@ -1463,9 +1509,9 @@ static int mtk_poll_rx(struct napi_struc
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
-- u32 hash, reason, reserve_len;
- struct net_device *netdev;
- dma_addr_t dma_addr;
-+ u32 hash, reason;
- int mac = 0;
-
- ring = mtk_get_rx_ring(eth);
-@@ -1495,8 +1541,14 @@ static int mtk_poll_rx(struct napi_struc
- if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
- goto release_desc;
-
-+ pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
-+
- /* alloc new buffer */
- if (ring->page_pool) {
-+ struct page *page = virt_to_head_page(data);
-+ struct xdp_buff xdp;
-+ u32 ret;
-+
- new_data = mtk_page_pool_get_buff(ring->page_pool,
- &dma_addr,
- GFP_ATOMIC);
-@@ -1504,6 +1556,34 @@ static int mtk_poll_rx(struct napi_struc
- netdev->stats.rx_dropped++;
- goto release_desc;
- }
-+
-+ dma_sync_single_for_cpu(eth->dma_dev,
-+ page_pool_get_dma_addr(page) + MTK_PP_HEADROOM,
-+ pktlen, page_pool_get_dma_dir(ring->page_pool));
-+
-+ xdp_init_buff(&xdp, PAGE_SIZE, &ring->xdp_q);
-+ xdp_prepare_buff(&xdp, data, MTK_PP_HEADROOM, pktlen,
-+ false);
-+ xdp_buff_clear_frags_flag(&xdp);
-+
-+ ret = mtk_xdp_run(eth, ring, &xdp, netdev);
-+ if (ret == XDP_REDIRECT)
-+ xdp_flush = true;
-+
-+ if (ret != XDP_PASS)
-+ goto skip_rx;
-+
-+ skb = build_skb(data, PAGE_SIZE);
-+ if (unlikely(!skb)) {
-+ page_pool_put_full_page(ring->page_pool,
-+ page, true);
-+ netdev->stats.rx_dropped++;
-+ goto skip_rx;
-+ }
-+
-+ skb_reserve(skb, xdp.data - xdp.data_hard_start);
-+ skb_put(skb, xdp.data_end - xdp.data);
-+ skb_mark_for_recycle(skb);
- } else {
- if (ring->frag_size <= PAGE_SIZE)
- new_data = napi_alloc_frag(ring->frag_size);
-@@ -1527,27 +1607,20 @@ static int mtk_poll_rx(struct napi_struc
-
- dma_unmap_single(eth->dma_dev, trxd.rxd1,
- ring->buf_size, DMA_FROM_DEVICE);
-- }
-
-- /* receive data */
-- skb = build_skb(data, ring->frag_size);
-- if (unlikely(!skb)) {
-- mtk_rx_put_buff(ring, data, true);
-- netdev->stats.rx_dropped++;
-- goto skip_rx;
-- }
-+ skb = build_skb(data, ring->frag_size);
-+ if (unlikely(!skb)) {
-+ netdev->stats.rx_dropped++;
-+ skb_free_frag(data);
-+ goto skip_rx;
-+ }
-
-- if (ring->page_pool) {
-- reserve_len = MTK_PP_HEADROOM;
-- skb_mark_for_recycle(skb);
-- } else {
-- reserve_len = NET_SKB_PAD + NET_IP_ALIGN;
-+ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
-+ skb_put(skb, pktlen);
- }
-- skb_reserve(skb, reserve_len);
-
-- pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
- skb->dev = netdev;
-- skb_put(skb, pktlen);
-+ bytes += skb->len;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
- rxdcsum = &trxd.rxd3;
-@@ -1559,7 +1632,6 @@ static int mtk_poll_rx(struct napi_struc
- else
- skb_checksum_none_assert(skb);
- skb->protocol = eth_type_trans(skb, netdev);
-- bytes += pktlen;
-
- hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY;
- if (hash != MTK_RXD4_FOE_ENTRY) {
-@@ -1622,6 +1694,9 @@ rx_done:
- &dim_sample);
- net_dim(&eth->rx_dim, dim_sample);
-
-+ if (xdp_flush)
-+ xdp_do_flush_map();
-+
- return done;
- }
-
-@@ -1967,7 +2042,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- if (!ring->data)
- return -ENOMEM;
-
-- if (!eth->hwlro) {
-+ if (mtk_page_pool_enabled(eth)) {
- struct page_pool *pp;
-
- pp = mtk_create_page_pool(eth, &ring->xdp_q, ring_no,
-@@ -2712,6 +2787,48 @@ static int mtk_stop(struct net_device *d
- return 0;
- }
-
-+static int mtk_xdp_setup(struct net_device *dev, struct bpf_prog *prog,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+ struct bpf_prog *old_prog;
-+ bool need_update;
-+
-+ if (eth->hwlro) {
-+ NL_SET_ERR_MSG_MOD(extack, "XDP not supported with HWLRO");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ if (dev->mtu > MTK_PP_MAX_BUF_SIZE) {
-+ NL_SET_ERR_MSG_MOD(extack, "MTU too large for XDP");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ need_update = !!eth->prog != !!prog;
-+ if (netif_running(dev) && need_update)
-+ mtk_stop(dev);
-+
-+ old_prog = rcu_replace_pointer(eth->prog, prog, lockdep_rtnl_is_held());
-+ if (old_prog)
-+ bpf_prog_put(old_prog);
-+
-+ if (netif_running(dev) && need_update)
-+ return mtk_open(dev);
-+
-+ return 0;
-+}
-+
-+static int mtk_xdp(struct net_device *dev, struct netdev_bpf *xdp)
-+{
-+ switch (xdp->command) {
-+ case XDP_SETUP_PROG:
-+ return mtk_xdp_setup(dev, xdp->prog, xdp->extack);
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
- static void ethsys_reset(struct mtk_eth *eth, u32 reset_bits)
- {
- regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL,
-@@ -2990,6 +3107,12 @@ static int mtk_change_mtu(struct net_dev
- struct mtk_eth *eth = mac->hw;
- u32 mcr_cur, mcr_new;
-
-+ if (rcu_access_pointer(eth->prog) &&
-+ length > MTK_PP_MAX_BUF_SIZE) {
-+ netdev_err(dev, "Invalid MTU for XDP mode\n");
-+ return -EINVAL;
-+ }
-+
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
- mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
-@@ -3316,6 +3439,7 @@ static const struct net_device_ops mtk_n
- .ndo_poll_controller = mtk_poll_controller,
- #endif
- .ndo_setup_tc = mtk_eth_setup_tc,
-+ .ndo_bpf = mtk_xdp,
- };
-
- static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1086,6 +1086,8 @@ struct mtk_eth {
-
- struct mtk_ppe *ppe;
- struct rhashtable flow_table;
-+
-+ struct bpf_prog __rcu *prog;
- };
-
- /* struct mtk_mac - the structure that holds the info about the MACs of the
diff --git a/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch b/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch
deleted file mode 100644
index 7bb4222fef..0000000000
--- a/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 916a6ee836d6b7b8ef1ed5f0515e256ca60e9968 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 22 Jul 2022 09:19:38 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce xdp ethtool counters
-
-Report xdp stats through ethtool
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 26 +++++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++++++++++
- 2 files changed, 36 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -34,6 +34,10 @@ MODULE_PARM_DESC(msg_level, "Message lev
- #define MTK_ETHTOOL_STAT(x) { #x, \
- offsetof(struct mtk_hw_stats, x) / sizeof(u64) }
-
-+#define MTK_ETHTOOL_XDP_STAT(x) { #x, \
-+ offsetof(struct mtk_hw_stats, xdp_stats.x) / \
-+ sizeof(u64) }
-+
- static const struct mtk_reg_map mtk_reg_map = {
- .tx_irq_mask = 0x1a1c,
- .tx_irq_status = 0x1a18,
-@@ -141,6 +145,13 @@ static const struct mtk_ethtool_stats {
- MTK_ETHTOOL_STAT(rx_long_errors),
- MTK_ETHTOOL_STAT(rx_checksum_errors),
- MTK_ETHTOOL_STAT(rx_flow_control_packets),
-+ MTK_ETHTOOL_XDP_STAT(rx_xdp_redirect),
-+ MTK_ETHTOOL_XDP_STAT(rx_xdp_pass),
-+ MTK_ETHTOOL_XDP_STAT(rx_xdp_drop),
-+ MTK_ETHTOOL_XDP_STAT(rx_xdp_tx),
-+ MTK_ETHTOOL_XDP_STAT(rx_xdp_tx_errors),
-+ MTK_ETHTOOL_XDP_STAT(tx_xdp_xmit),
-+ MTK_ETHTOOL_XDP_STAT(tx_xdp_xmit_errors),
- };
-
- static const char * const mtk_clks_source_name[] = {
-@@ -1458,6 +1469,9 @@ static void mtk_rx_put_buff(struct mtk_r
- static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring,
- struct xdp_buff *xdp, struct net_device *dev)
- {
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_hw_stats *hw_stats = mac->hw_stats;
-+ u64 *count = &hw_stats->xdp_stats.rx_xdp_drop;
- struct bpf_prog *prog;
- u32 act = XDP_PASS;
-
-@@ -1470,13 +1484,16 @@ static u32 mtk_xdp_run(struct mtk_eth *e
- act = bpf_prog_run_xdp(prog, xdp);
- switch (act) {
- case XDP_PASS:
-- goto out;
-+ count = &hw_stats->xdp_stats.rx_xdp_pass;
-+ goto update_stats;
- case XDP_REDIRECT:
- if (unlikely(xdp_do_redirect(dev, xdp, prog))) {
- act = XDP_DROP;
- break;
- }
-- goto out;
-+
-+ count = &hw_stats->xdp_stats.rx_xdp_redirect;
-+ goto update_stats;
- default:
- bpf_warn_invalid_xdp_action(act);
- fallthrough;
-@@ -1489,6 +1506,11 @@ static u32 mtk_xdp_run(struct mtk_eth *e
-
- page_pool_put_full_page(ring->page_pool,
- virt_to_head_page(xdp->data), true);
-+
-+update_stats:
-+ u64_stats_update_begin(&hw_stats->syncp);
-+ *count = *count + 1;
-+ u64_stats_update_end(&hw_stats->syncp);
- out:
- rcu_read_unlock();
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -568,6 +568,16 @@ struct mtk_tx_dma_v2 {
- struct mtk_eth;
- struct mtk_mac;
-
-+struct mtk_xdp_stats {
-+ u64 rx_xdp_redirect;
-+ u64 rx_xdp_pass;
-+ u64 rx_xdp_drop;
-+ u64 rx_xdp_tx;
-+ u64 rx_xdp_tx_errors;
-+ u64 tx_xdp_xmit;
-+ u64 tx_xdp_xmit_errors;
-+};
-+
- /* struct mtk_hw_stats - the structure that holds the traffic statistics.
- * @stats_lock: make sure that stats operations are atomic
- * @reg_offset: the status register offset of the SoC
-@@ -591,6 +601,8 @@ struct mtk_hw_stats {
- u64 rx_checksum_errors;
- u64 rx_flow_control_packets;
-
-+ struct mtk_xdp_stats xdp_stats;
-+
- spinlock_t stats_lock;
- u32 reg_offset;
- struct u64_stats_sync syncp;
diff --git a/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch b/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch
deleted file mode 100644
index deb06d4892..0000000000
--- a/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch
+++ /dev/null
@@ -1,340 +0,0 @@
-From 5886d26fd25bbe26130e3e5f7474b9b3e98a3469 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 22 Jul 2022 09:19:39 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add xmit XDP support
-
-Introduce XDP support for XDP_TX verdict and ndo_xdp_xmit function
-pointer.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 192 +++++++++++++++++---
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 +-
- 2 files changed, 180 insertions(+), 22 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -987,15 +987,26 @@ static void mtk_tx_unmap(struct mtk_eth
- }
- }
-
-- tx_buf->flags = 0;
-- if (tx_buf->skb &&
-- (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC)) {
-- if (napi)
-- napi_consume_skb(tx_buf->skb, napi);
-+ if (tx_buf->type == MTK_TYPE_SKB) {
-+ if (tx_buf->data &&
-+ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-+ struct sk_buff *skb = tx_buf->data;
-+
-+ if (napi)
-+ napi_consume_skb(skb, napi);
-+ else
-+ dev_kfree_skb_any(skb);
-+ }
-+ } else if (tx_buf->data) {
-+ struct xdp_frame *xdpf = tx_buf->data;
-+
-+ if (napi && tx_buf->type == MTK_TYPE_XDP_TX)
-+ xdp_return_frame_rx_napi(xdpf);
- else
-- dev_kfree_skb_any(tx_buf->skb);
-+ xdp_return_frame(xdpf);
- }
-- tx_buf->skb = NULL;
-+ tx_buf->flags = 0;
-+ tx_buf->data = NULL;
- }
-
- static void setup_tx_buf(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
-@@ -1012,7 +1023,7 @@ static void setup_tx_buf(struct mtk_eth
- dma_unmap_addr_set(tx_buf, dma_addr1, mapped_addr);
- dma_unmap_len_set(tx_buf, dma_len1, size);
- } else {
-- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
-+ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
- txd->txd1 = mapped_addr;
- txd->txd2 = TX_DMA_PLEN0(size);
- dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
-@@ -1188,7 +1199,7 @@ static int mtk_tx_map(struct sk_buff *sk
- soc->txrx.txd_size);
- if (new_desc)
- memset(tx_buf, 0, sizeof(*tx_buf));
-- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
-+ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
- tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
-@@ -1202,7 +1213,8 @@ static int mtk_tx_map(struct sk_buff *sk
- }
-
- /* store skb to cleanup */
-- itx_buf->skb = skb;
-+ itx_buf->type = MTK_TYPE_SKB;
-+ itx_buf->data = skb;
-
- if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- if (k & 0x1)
-@@ -1414,13 +1426,14 @@ static struct page_pool *mtk_create_page
- .pool_size = size,
- .nid = NUMA_NO_NODE,
- .dev = eth->dma_dev,
-- .dma_dir = DMA_FROM_DEVICE,
- .offset = MTK_PP_HEADROOM,
- .max_len = MTK_PP_MAX_BUF_SIZE,
- };
- struct page_pool *pp;
- int err;
-
-+ pp_params.dma_dir = rcu_access_pointer(eth->prog) ? DMA_BIDIRECTIONAL
-+ : DMA_FROM_DEVICE;
- pp = page_pool_create(&pp_params);
- if (IS_ERR(pp))
- return pp;
-@@ -1466,6 +1479,122 @@ static void mtk_rx_put_buff(struct mtk_r
- skb_free_frag(data);
- }
-
-+static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf,
-+ struct net_device *dev, bool dma_map)
-+{
-+ const struct mtk_soc_data *soc = eth->soc;
-+ struct mtk_tx_ring *ring = &eth->tx_ring;
-+ struct mtk_tx_dma_desc_info txd_info = {
-+ .size = xdpf->len,
-+ .first = true,
-+ .last = true,
-+ };
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_tx_dma *txd, *txd_pdma;
-+ int err = 0, index = 0, n_desc = 1;
-+ struct mtk_tx_buf *tx_buf;
-+
-+ if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
-+ return -EBUSY;
-+
-+ if (unlikely(atomic_read(&ring->free_count) <= 1))
-+ return -EBUSY;
-+
-+ spin_lock(&eth->page_lock);
-+
-+ txd = ring->next_free;
-+ if (txd == ring->last_free) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size);
-+ memset(tx_buf, 0, sizeof(*tx_buf));
-+
-+ if (dma_map) { /* ndo_xdp_xmit */
-+ txd_info.addr = dma_map_single(eth->dma_dev, xdpf->data,
-+ txd_info.size, DMA_TO_DEVICE);
-+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-+ } else {
-+ struct page *page = virt_to_head_page(xdpf->data);
-+
-+ txd_info.addr = page_pool_get_dma_addr(page) +
-+ sizeof(*xdpf) + xdpf->headroom;
-+ dma_sync_single_for_device(eth->dma_dev, txd_info.addr,
-+ txd_info.size,
-+ DMA_BIDIRECTIONAL);
-+ }
-+ mtk_tx_set_dma_desc(dev, txd, &txd_info);
-+
-+ tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
-+
-+ txd_pdma = qdma_to_pdma(ring, txd);
-+ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size,
-+ index++);
-+
-+ /* store xdpf for cleanup */
-+ tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
-+ tx_buf->data = xdpf;
-+
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-+ if (index & 1)
-+ txd_pdma->txd2 |= TX_DMA_LS0;
-+ else
-+ txd_pdma->txd2 |= TX_DMA_LS1;
-+ }
-+
-+ ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-+ atomic_sub(n_desc, &ring->free_count);
-+
-+ /* make sure that all changes to the dma ring are flushed before we
-+ * continue
-+ */
-+ wmb();
-+
-+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-+ mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr);
-+ } else {
-+ int idx;
-+
-+ idx = txd_to_idx(ring, txd, soc->txrx.txd_size);
-+ mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
-+ MT7628_TX_CTX_IDX0);
-+ }
-+out:
-+ spin_unlock(&eth->page_lock);
-+
-+ return err;
-+}
-+
-+static int mtk_xdp_xmit(struct net_device *dev, int num_frame,
-+ struct xdp_frame **frames, u32 flags)
-+{
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_hw_stats *hw_stats = mac->hw_stats;
-+ struct mtk_eth *eth = mac->hw;
-+ int i, nxmit = 0;
-+
-+ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
-+ return -EINVAL;
-+
-+ for (i = 0; i < num_frame; i++) {
-+ if (mtk_xdp_submit_frame(eth, frames[i], dev, true))
-+ break;
-+ nxmit++;
-+ }
-+
-+ u64_stats_update_begin(&hw_stats->syncp);
-+ hw_stats->xdp_stats.tx_xdp_xmit += nxmit;
-+ hw_stats->xdp_stats.tx_xdp_xmit_errors += num_frame - nxmit;
-+ u64_stats_update_end(&hw_stats->syncp);
-+
-+ return nxmit;
-+}
-+
- static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring,
- struct xdp_buff *xdp, struct net_device *dev)
- {
-@@ -1494,6 +1623,18 @@ static u32 mtk_xdp_run(struct mtk_eth *e
-
- count = &hw_stats->xdp_stats.rx_xdp_redirect;
- goto update_stats;
-+ case XDP_TX: {
-+ struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp);
-+
-+ if (mtk_xdp_submit_frame(eth, xdpf, dev, false)) {
-+ count = &hw_stats->xdp_stats.rx_xdp_tx_errors;
-+ act = XDP_DROP;
-+ break;
-+ }
-+
-+ count = &hw_stats->xdp_stats.rx_xdp_tx;
-+ goto update_stats;
-+ }
- default:
- bpf_warn_invalid_xdp_action(act);
- fallthrough;
-@@ -1727,9 +1868,8 @@ static int mtk_poll_tx_qdma(struct mtk_e
- {
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct mtk_tx_ring *ring = &eth->tx_ring;
-- struct mtk_tx_dma *desc;
-- struct sk_buff *skb;
- struct mtk_tx_buf *tx_buf;
-+ struct mtk_tx_dma *desc;
- u32 cpu, dma;
-
- cpu = ring->last_free_ptr;
-@@ -1750,15 +1890,21 @@ static int mtk_poll_tx_qdma(struct mtk_e
- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
- mac = 1;
-
-- skb = tx_buf->skb;
-- if (!skb)
-+ if (!tx_buf->data)
- break;
-
-- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
-+ if (tx_buf->type == MTK_TYPE_SKB &&
-+ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-+ struct sk_buff *skb = tx_buf->data;
-+
- bytes[mac] += skb->len;
- done[mac]++;
- budget--;
-+ } else if (tx_buf->type == MTK_TYPE_XDP_TX ||
-+ tx_buf->type == MTK_TYPE_XDP_NDO) {
-+ budget--;
- }
-+
- mtk_tx_unmap(eth, tx_buf, true);
-
- ring->last_free = desc;
-@@ -1777,9 +1923,8 @@ static int mtk_poll_tx_pdma(struct mtk_e
- unsigned int *done, unsigned int *bytes)
- {
- struct mtk_tx_ring *ring = &eth->tx_ring;
-- struct mtk_tx_dma *desc;
-- struct sk_buff *skb;
- struct mtk_tx_buf *tx_buf;
-+ struct mtk_tx_dma *desc;
- u32 cpu, dma;
-
- cpu = ring->cpu_idx;
-@@ -1787,14 +1932,18 @@ static int mtk_poll_tx_pdma(struct mtk_e
-
- while ((cpu != dma) && budget) {
- tx_buf = &ring->buf[cpu];
-- skb = tx_buf->skb;
-- if (!skb)
-+ if (!tx_buf->data)
- break;
-
-- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
-+ if (tx_buf->type == MTK_TYPE_SKB &&
-+ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-+ struct sk_buff *skb = tx_buf->data;
- bytes[0] += skb->len;
- done[0]++;
- budget--;
-+ } else if (tx_buf->type == MTK_TYPE_XDP_TX ||
-+ tx_buf->type == MTK_TYPE_XDP_NDO) {
-+ budget--;
- }
-
- mtk_tx_unmap(eth, tx_buf, true);
-@@ -3462,6 +3611,7 @@ static const struct net_device_ops mtk_n
- #endif
- .ndo_setup_tc = mtk_eth_setup_tc,
- .ndo_bpf = mtk_xdp,
-+ .ndo_xdp_xmit = mtk_xdp_xmit,
- };
-
- static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -694,6 +694,12 @@ enum mtk_dev_state {
- MTK_RESETTING
- };
-
-+enum mtk_tx_buf_type {
-+ MTK_TYPE_SKB,
-+ MTK_TYPE_XDP_TX,
-+ MTK_TYPE_XDP_NDO,
-+};
-+
- /* struct mtk_tx_buf - This struct holds the pointers to the memory pointed at
- * by the TX descriptor s
- * @skb: The SKB pointer of the packet being sent
-@@ -703,7 +709,9 @@ enum mtk_dev_state {
- * @dma_len1: The length of the second segment
- */
- struct mtk_tx_buf {
-- struct sk_buff *skb;
-+ enum mtk_tx_buf_type type;
-+ void *data;
-+
- u32 flags;
- DEFINE_DMA_UNMAP_ADDR(dma_addr0);
- DEFINE_DMA_UNMAP_LEN(dma_len0);
diff --git a/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch b/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch
deleted file mode 100644
index 4707aacd9d..0000000000
--- a/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 84b9cd389036d4a262d8cee794d56c04095358a7 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 22 Jul 2022 09:19:40 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for
- page_pool_get_stats
-
-Introduce support for the page_pool stats API into mtk_eth_soc driver.
-Report page_pool stats through ethtool.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/Kconfig | 1 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 37 +++++++++++++++++++--
- 2 files changed, 35 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -17,6 +17,7 @@ config NET_MEDIATEK_SOC
- select PHYLINK
- select DIMLIB
- select PAGE_POOL
-+ select PAGE_POOL_STATS
- help
- This driver supports the gigabit ethernet MACs in the
- MediaTek SoC family.
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3473,11 +3473,18 @@ static void mtk_get_strings(struct net_d
- int i;
-
- switch (stringset) {
-- case ETH_SS_STATS:
-+ case ETH_SS_STATS: {
-+ struct mtk_mac *mac = netdev_priv(dev);
-+
- for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) {
- memcpy(data, mtk_ethtool_stats[i].str, ETH_GSTRING_LEN);
- data += ETH_GSTRING_LEN;
- }
-+ if (mtk_page_pool_enabled(mac->hw))
-+ page_pool_ethtool_stats_get_strings(data);
-+ break;
-+ }
-+ default:
- break;
- }
- }
-@@ -3485,13 +3492,35 @@ static void mtk_get_strings(struct net_d
- static int mtk_get_sset_count(struct net_device *dev, int sset)
- {
- switch (sset) {
-- case ETH_SS_STATS:
-- return ARRAY_SIZE(mtk_ethtool_stats);
-+ case ETH_SS_STATS: {
-+ int count = ARRAY_SIZE(mtk_ethtool_stats);
-+ struct mtk_mac *mac = netdev_priv(dev);
-+
-+ if (mtk_page_pool_enabled(mac->hw))
-+ count += page_pool_ethtool_stats_get_count();
-+ return count;
-+ }
- default:
- return -EOPNOTSUPP;
- }
- }
-
-+static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data)
-+{
-+ struct page_pool_stats stats = {};
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(eth->rx_ring); i++) {
-+ struct mtk_rx_ring *ring = &eth->rx_ring[i];
-+
-+ if (!ring->page_pool)
-+ continue;
-+
-+ page_pool_get_stats(ring->page_pool, &stats);
-+ }
-+ page_pool_ethtool_stats_get(data, &stats);
-+}
-+
- static void mtk_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
- {
-@@ -3519,6 +3548,8 @@ static void mtk_get_ethtool_stats(struct
-
- for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++)
- *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset);
-+ if (mtk_page_pool_enabled(mac->hw))
-+ mtk_ethtool_pp_stats(mac->hw, data_dst);
- } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
- }
-
diff --git a/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch b/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch
deleted file mode 100644
index 33a7616652..0000000000
--- a/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From b16fe6d82b71fa0dd5c957bc22d66a694976d6eb Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 27 Jul 2022 23:20:50 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_xdp_frame_map
- utility routine
-
-This is a preliminary patch to add xdp multi-frag support to mtk_eth_soc
-driver
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 68 +++++++++++++--------
- 1 file changed, 42 insertions(+), 26 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1479,6 +1479,41 @@ static void mtk_rx_put_buff(struct mtk_r
- skb_free_frag(data);
- }
-
-+static int mtk_xdp_frame_map(struct mtk_eth *eth, struct net_device *dev,
-+ struct mtk_tx_dma_desc_info *txd_info,
-+ struct mtk_tx_dma *txd, struct mtk_tx_buf *tx_buf,
-+ void *data, u16 headroom, int index, bool dma_map)
-+{
-+ struct mtk_tx_ring *ring = &eth->tx_ring;
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_tx_dma *txd_pdma;
-+
-+ if (dma_map) { /* ndo_xdp_xmit */
-+ txd_info->addr = dma_map_single(eth->dma_dev, data,
-+ txd_info->size, DMA_TO_DEVICE);
-+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info->addr)))
-+ return -ENOMEM;
-+
-+ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-+ } else {
-+ struct page *page = virt_to_head_page(data);
-+
-+ txd_info->addr = page_pool_get_dma_addr(page) +
-+ sizeof(struct xdp_frame) + headroom;
-+ dma_sync_single_for_device(eth->dma_dev, txd_info->addr,
-+ txd_info->size, DMA_BIDIRECTIONAL);
-+ }
-+ mtk_tx_set_dma_desc(dev, txd, txd_info);
-+
-+ tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
-+
-+ txd_pdma = qdma_to_pdma(ring, txd);
-+ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info->addr, txd_info->size,
-+ index);
-+
-+ return 0;
-+}
-+
- static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf,
- struct net_device *dev, bool dma_map)
- {
-@@ -1489,9 +1524,8 @@ static int mtk_xdp_submit_frame(struct m
- .first = true,
- .last = true,
- };
-- struct mtk_mac *mac = netdev_priv(dev);
-- struct mtk_tx_dma *txd, *txd_pdma;
- int err = 0, index = 0, n_desc = 1;
-+ struct mtk_tx_dma *txd, *txd_pdma;
- struct mtk_tx_buf *tx_buf;
-
- if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
-@@ -1511,36 +1545,18 @@ static int mtk_xdp_submit_frame(struct m
- tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size);
- memset(tx_buf, 0, sizeof(*tx_buf));
-
-- if (dma_map) { /* ndo_xdp_xmit */
-- txd_info.addr = dma_map_single(eth->dma_dev, xdpf->data,
-- txd_info.size, DMA_TO_DEVICE);
-- if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) {
-- err = -ENOMEM;
-- goto out;
-- }
-- tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-- } else {
-- struct page *page = virt_to_head_page(xdpf->data);
--
-- txd_info.addr = page_pool_get_dma_addr(page) +
-- sizeof(*xdpf) + xdpf->headroom;
-- dma_sync_single_for_device(eth->dma_dev, txd_info.addr,
-- txd_info.size,
-- DMA_BIDIRECTIONAL);
-- }
-- mtk_tx_set_dma_desc(dev, txd, &txd_info);
--
-- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
--
-- txd_pdma = qdma_to_pdma(ring, txd);
-- setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size,
-- index++);
-+ err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf,
-+ xdpf->data, xdpf->headroom, index,
-+ dma_map);
-+ if (err < 0)
-+ goto out;
-
- /* store xdpf for cleanup */
- tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
- tx_buf->data = xdpf;
-
- if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-+ txd_pdma = qdma_to_pdma(ring, txd);
- if (index & 1)
- txd_pdma->txd2 |= TX_DMA_LS0;
- else
diff --git a/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch b/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch
deleted file mode 100644
index e75861bc82..0000000000
--- a/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch
+++ /dev/null
@@ -1,218 +0,0 @@
-From 155738a4f319538a09f734ce1f5a2eac3ada1de2 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 27 Jul 2022 23:20:51 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce xdp multi-frag support
-
-Add the capability to map non-linear xdp frames in XDP_TX and
-ndo_xdp_xmit callback.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 125 +++++++++++++-------
- 1 file changed, 82 insertions(+), 43 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -987,23 +987,22 @@ static void mtk_tx_unmap(struct mtk_eth
- }
- }
-
-- if (tx_buf->type == MTK_TYPE_SKB) {
-- if (tx_buf->data &&
-- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-+ if (tx_buf->data && tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-+ if (tx_buf->type == MTK_TYPE_SKB) {
- struct sk_buff *skb = tx_buf->data;
-
- if (napi)
- napi_consume_skb(skb, napi);
- else
- dev_kfree_skb_any(skb);
-- }
-- } else if (tx_buf->data) {
-- struct xdp_frame *xdpf = tx_buf->data;
-+ } else {
-+ struct xdp_frame *xdpf = tx_buf->data;
-
-- if (napi && tx_buf->type == MTK_TYPE_XDP_TX)
-- xdp_return_frame_rx_napi(xdpf);
-- else
-- xdp_return_frame(xdpf);
-+ if (napi && tx_buf->type == MTK_TYPE_XDP_TX)
-+ xdp_return_frame_rx_napi(xdpf);
-+ else
-+ xdp_return_frame(xdpf);
-+ }
- }
- tx_buf->flags = 0;
- tx_buf->data = NULL;
-@@ -1506,6 +1505,8 @@ static int mtk_xdp_frame_map(struct mtk_
- mtk_tx_set_dma_desc(dev, txd, txd_info);
-
- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
-+ tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
-+ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
-
- txd_pdma = qdma_to_pdma(ring, txd);
- setup_tx_buf(eth, tx_buf, txd_pdma, txd_info->addr, txd_info->size,
-@@ -1517,43 +1518,69 @@ static int mtk_xdp_frame_map(struct mtk_
- static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf,
- struct net_device *dev, bool dma_map)
- {
-+ struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf);
- const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct mtk_tx_dma_desc_info txd_info = {
- .size = xdpf->len,
- .first = true,
-- .last = true,
-+ .last = !xdp_frame_has_frags(xdpf),
- };
-- int err = 0, index = 0, n_desc = 1;
-- struct mtk_tx_dma *txd, *txd_pdma;
-- struct mtk_tx_buf *tx_buf;
-+ int err, index = 0, n_desc = 1, nr_frags;
-+ struct mtk_tx_dma *htxd, *txd, *txd_pdma;
-+ struct mtk_tx_buf *htx_buf, *tx_buf;
-+ void *data = xdpf->data;
-
- if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
- return -EBUSY;
-
-- if (unlikely(atomic_read(&ring->free_count) <= 1))
-+ nr_frags = unlikely(xdp_frame_has_frags(xdpf)) ? sinfo->nr_frags : 0;
-+ if (unlikely(atomic_read(&ring->free_count) <= 1 + nr_frags))
- return -EBUSY;
-
- spin_lock(&eth->page_lock);
-
- txd = ring->next_free;
- if (txd == ring->last_free) {
-- err = -ENOMEM;
-- goto out;
-+ spin_unlock(&eth->page_lock);
-+ return -ENOMEM;
- }
-+ htxd = txd;
-
- tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size);
- memset(tx_buf, 0, sizeof(*tx_buf));
-+ htx_buf = tx_buf;
-
-- err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf,
-- xdpf->data, xdpf->headroom, index,
-- dma_map);
-- if (err < 0)
-- goto out;
-+ for (;;) {
-+ err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf,
-+ data, xdpf->headroom, index, dma_map);
-+ if (err < 0)
-+ goto unmap;
-+
-+ if (txd_info.last)
-+ break;
-
-+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || (index & 0x1)) {
-+ txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
-+ txd_pdma = qdma_to_pdma(ring, txd);
-+ if (txd == ring->last_free)
-+ goto unmap;
-+
-+ tx_buf = mtk_desc_to_tx_buf(ring, txd,
-+ soc->txrx.txd_size);
-+ memset(tx_buf, 0, sizeof(*tx_buf));
-+ n_desc++;
-+ }
-+
-+ memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
-+ txd_info.size = skb_frag_size(&sinfo->frags[index]);
-+ txd_info.last = index + 1 == nr_frags;
-+ data = skb_frag_address(&sinfo->frags[index]);
-+
-+ index++;
-+ }
- /* store xdpf for cleanup */
-- tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
-- tx_buf->data = xdpf;
-+ htx_buf->data = xdpf;
-
- if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- txd_pdma = qdma_to_pdma(ring, txd);
-@@ -1580,7 +1607,24 @@ static int mtk_xdp_submit_frame(struct m
- mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
- MT7628_TX_CTX_IDX0);
- }
--out:
-+
-+ spin_unlock(&eth->page_lock);
-+
-+ return 0;
-+
-+unmap:
-+ while (htxd != txd) {
-+ txd_pdma = qdma_to_pdma(ring, htxd);
-+ tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size);
-+ mtk_tx_unmap(eth, tx_buf, false);
-+
-+ htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA))
-+ txd_pdma->txd2 = TX_DMA_DESP2_DEF;
-+
-+ htxd = mtk_qdma_phys_to_virt(ring, htxd->txd2);
-+ }
-+
- spin_unlock(&eth->page_lock);
-
- return err;
-@@ -1909,18 +1953,15 @@ static int mtk_poll_tx_qdma(struct mtk_e
- if (!tx_buf->data)
- break;
-
-- if (tx_buf->type == MTK_TYPE_SKB &&
-- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-- struct sk_buff *skb = tx_buf->data;
-+ if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-+ if (tx_buf->type == MTK_TYPE_SKB) {
-+ struct sk_buff *skb = tx_buf->data;
-
-- bytes[mac] += skb->len;
-- done[mac]++;
-- budget--;
-- } else if (tx_buf->type == MTK_TYPE_XDP_TX ||
-- tx_buf->type == MTK_TYPE_XDP_NDO) {
-+ bytes[mac] += skb->len;
-+ done[mac]++;
-+ }
- budget--;
- }
--
- mtk_tx_unmap(eth, tx_buf, true);
-
- ring->last_free = desc;
-@@ -1951,17 +1992,15 @@ static int mtk_poll_tx_pdma(struct mtk_e
- if (!tx_buf->data)
- break;
-
-- if (tx_buf->type == MTK_TYPE_SKB &&
-- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-- struct sk_buff *skb = tx_buf->data;
-- bytes[0] += skb->len;
-- done[0]++;
-- budget--;
-- } else if (tx_buf->type == MTK_TYPE_XDP_TX ||
-- tx_buf->type == MTK_TYPE_XDP_NDO) {
-+ if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-+ if (tx_buf->type == MTK_TYPE_SKB) {
-+ struct sk_buff *skb = tx_buf->data;
-+
-+ bytes[0] += skb->len;
-+ done[0]++;
-+ }
- budget--;
- }
--
- mtk_tx_unmap(eth, tx_buf, true);
-
- desc = ring->dma + cpu * eth->soc->txrx.txd_size;
diff --git a/target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch b/target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch
deleted file mode 100644
index 1f2a3ee140..0000000000
--- a/target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch
+++ /dev/null
@@ -1,394 +0,0 @@
-From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:57:50 +0000
-Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS
-
-The SGMII core found in several MediaTek SoCs is identical to what can
-also be found in MediaTek's MT7531 Ethernet switch IC.
-As this has not always been clear, both drivers developed different
-implementations to deal with the PCS.
-Recently Alexander Couzens pointed out this fact which lead to the
-development of this shared driver.
-
-Add a dedicated driver, mostly by copying the code now found in the
-Ethernet driver. The now redundant code will be removed by a follow-up
-commit.
-
-Suggested-by: Alexander Couzens <lynxis@fe80.eu>
-Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- MAINTAINERS | 8 +
- drivers/net/pcs/Kconfig | 7 +
- drivers/net/pcs/Makefile | 1 +
- drivers/net/pcs/pcs-mtk-lynxi.c | 305 ++++++++++++++++++++++++++++++
- include/linux/pcs/pcs-mtk-lynxi.h | 13 ++
- 5 files changed, 334 insertions(+)
- create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
- create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -11790,6 +11790,14 @@ L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/ethernet/mediatek/
-
-+MEDIATEK ETHERNET PCS DRIVER
-+M: Alexander Couzens <lynxis@fe80.eu>
-+M: Daniel Golle <daniel@makrotopia.org>
-+L: netdev@vger.kernel.org
-+S: Maintained
-+F: drivers/net/pcs/pcs-mtk-lynxi.c
-+F: include/linux/pcs/pcs-mtk-lynxi.h
-+
- MEDIATEK I2C CONTROLLER DRIVER
- M: Qii Wang <qii.wang@mediatek.com>
- L: linux-i2c@vger.kernel.org
---- a/drivers/net/pcs/Kconfig
-+++ b/drivers/net/pcs/Kconfig
-@@ -18,4 +18,11 @@ config PCS_LYNX
- 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.
-+
- endmenu
---- a/drivers/net/pcs/Makefile
-+++ b/drivers/net/pcs/Makefile
-@@ -5,3 +5,4 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.
-
- obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
- obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
-+obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
---- /dev/null
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -0,0 +1,305 @@
-+// SPDX-License-Identifier: GPL-2.0
-+// Copyright (c) 2018-2019 MediaTek Inc.
-+/* A library for MediaTek SGMII circuit
-+ *
-+ * Author: Sean Wang <sean.wang@mediatek.com>
-+ * Author: Alexander Couzens <lynxis@fe80.eu>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ *
-+ */
-+
-+#include <linux/mdio.h>
-+#include <linux/of.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
-+#include <linux/phylink.h>
-+#include <linux/regmap.h>
-+
-+/* SGMII subsystem config registers */
-+/* BMCR (low 16) BMSR (high 16) */
-+#define SGMSYS_PCS_CONTROL_1 0x0
-+#define SGMII_BMCR GENMASK(15, 0)
-+#define SGMII_BMSR GENMASK(31, 16)
-+
-+#define SGMSYS_PCS_DEVICE_ID 0x4
-+#define SGMII_LYNXI_DEV_ID 0x4d544950
-+
-+#define SGMSYS_PCS_ADVERTISE 0x8
-+#define SGMII_ADVERTISE GENMASK(15, 0)
-+#define SGMII_LPA GENMASK(31, 16)
-+
-+#define SGMSYS_PCS_SCRATCH 0x14
-+#define SGMII_DEV_VERSION GENMASK(31, 16)
-+
-+/* Register to programmable link timer, the unit in 2 * 8ns */
-+#define SGMSYS_PCS_LINK_TIMER 0x18
-+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
-+#define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \
-+ ((ns) / 2 / 8))
-+
-+/* Register to control remote fault */
-+#define SGMSYS_SGMII_MODE 0x20
-+#define SGMII_IF_MODE_SGMII BIT(0)
-+#define SGMII_SPEED_DUPLEX_AN BIT(1)
-+#define SGMII_SPEED_MASK GENMASK(3, 2)
-+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
-+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
-+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
-+#define SGMII_DUPLEX_HALF BIT(4)
-+#define SGMII_REMOTE_FAULT_DIS BIT(8)
-+
-+/* Register to reset SGMII design */
-+#define SGMSYS_RESERVED_0 0x34
-+#define SGMII_SW_RESET BIT(0)
-+
-+/* Register to set SGMII speed, ANA RG_ Control Signals III */
-+#define SGMII_PHY_SPEED_MASK GENMASK(3, 2)
-+#define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0)
-+#define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1)
-+
-+/* Register to power up QPHY */
-+#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
-+#define SGMII_PHYA_PWD BIT(4)
-+
-+/* Register to QPHY wrapper control */
-+#define SGMSYS_QPHY_WRAP_CTRL 0xec
-+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
-+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
-+
-+/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated
-+ * data
-+ * @regmap: The register map pointing at the range used to setup
-+ * SGMII modes
-+ * @dev: Pointer to device owning the PCS
-+ * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap
-+ * @interface: Currently configured interface mode
-+ * @pcs: Phylink PCS structure
-+ * @flags: Flags indicating hardware properties
-+ */
-+struct mtk_pcs_lynxi {
-+ struct regmap *regmap;
-+ u32 ana_rgc3;
-+ phy_interface_t interface;
-+ struct phylink_pcs pcs;
-+ u32 flags;
-+};
-+
-+static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
-+{
-+ return container_of(pcs, struct mtk_pcs_lynxi, pcs);
-+}
-+
-+static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+ unsigned int bm, adv;
-+
-+ /* Read the BMSR and LPA */
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+
-+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-+ FIELD_GET(SGMII_LPA, adv));
-+}
-+
-+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface,
-+ const unsigned long *advertising,
-+ bool permit_pause_to_mac)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+ bool mode_changed = false, changed, use_an;
-+ unsigned int rgc3, sgm_mode, bmcr;
-+ int advertise, link_timer;
-+
-+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-+ advertising);
-+ if (advertise < 0)
-+ return 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
-+ * other words, 1000Mbps or 2500Mbps).
-+ */
-+ if (interface == PHY_INTERFACE_MODE_SGMII) {
-+ sgm_mode = SGMII_IF_MODE_SGMII;
-+ if (phylink_autoneg_inband(mode)) {
-+ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-+ SGMII_SPEED_DUPLEX_AN;
-+ use_an = true;
-+ } else {
-+ use_an = false;
-+ }
-+ } else if (phylink_autoneg_inband(mode)) {
-+ /* 1000base-X or 2500base-X autoneg */
-+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
-+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ advertising);
-+ } else {
-+ /* 1000base-X or 2500base-X without autoneg */
-+ sgm_mode = 0;
-+ use_an = false;
-+ }
-+
-+ if (use_an)
-+ bmcr = BMCR_ANENABLE;
-+ else
-+ bmcr = 0;
-+
-+ if (mpcs->interface != interface) {
-+ link_timer = phylink_get_link_timer_ns(interface);
-+ if (link_timer < 0)
-+ return link_timer;
-+
-+ /* PHYA power down */
-+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD);
-+
-+ /* Reset SGMII PCS state */
-+ regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
-+ SGMII_SW_RESET);
-+
-+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-+ SGMII_PN_SWAP_MASK,
-+ SGMII_PN_SWAP_TX_RX);
-+
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+ rgc3 = SGMII_PHY_SPEED_3_125G;
-+ else
-+ rgc3 = SGMII_PHY_SPEED_1_25G;
-+
-+ /* Configure the underlying interface speed */
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ SGMII_PHY_SPEED_MASK, rgc3);
-+
-+ /* Setup the link timer */
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
-+ SGMII_LINK_TIMER_VAL(link_timer));
-+
-+ mpcs->interface = interface;
-+ mode_changed = true;
-+ }
-+
-+ /* Update the advertisement, noting whether it has changed */
-+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-+ SGMII_ADVERTISE, advertise, &changed);
-+
-+ /* Update the sgmsys mode register */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-+ SGMII_IF_MODE_SGMII, sgm_mode);
-+
-+ /* Update the BMCR */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ BMCR_ANENABLE, bmcr);
-+
-+ /* Release PHYA power down state
-+ * Only removing bit SGMII_PHYA_PWD isn't enough.
-+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-+ * prevents SGMII from working. The SGMII still shows link but no traffic
-+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-+ * taken from a good working state of the SGMII interface.
-+ * Unknown how much the QPHY needs but it is racy without a sleep.
-+ * Tested on mt7622 & mt7986.
-+ */
-+ usleep_range(50, 100);
-+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-+
-+ return changed || mode_changed;
-+}
-+
-+static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+
-+ regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
-+}
-+
-+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface, int speed,
-+ int duplex)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+ unsigned int sgm_mode;
-+
-+ if (!phylink_autoneg_inband(mode)) {
-+ /* Force the speed and duplex setting */
-+ if (speed == SPEED_10)
-+ sgm_mode = SGMII_SPEED_10;
-+ else if (speed == SPEED_100)
-+ sgm_mode = SGMII_SPEED_100;
-+ else
-+ sgm_mode = SGMII_SPEED_1000;
-+
-+ if (duplex != DUPLEX_FULL)
-+ sgm_mode |= SGMII_DUPLEX_HALF;
-+
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
-+ sgm_mode);
-+ }
-+}
-+
-+static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
-+ .pcs_get_state = mtk_pcs_lynxi_get_state,
-+ .pcs_config = mtk_pcs_lynxi_config,
-+ .pcs_an_restart = mtk_pcs_lynxi_restart_an,
-+ .pcs_link_up = mtk_pcs_lynxi_link_up,
-+};
-+
-+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
-+ struct regmap *regmap, u32 ana_rgc3,
-+ u32 flags)
-+{
-+ struct mtk_pcs_lynxi *mpcs;
-+ u32 id, ver;
-+ int ret;
-+
-+ ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id);
-+ if (ret < 0)
-+ return NULL;
-+
-+ if (id != SGMII_LYNXI_DEV_ID) {
-+ dev_err(dev, "unknown PCS device id %08x\n", id);
-+ return NULL;
-+ }
-+
-+ ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver);
-+ if (ret < 0)
-+ return NULL;
-+
-+ ver = FIELD_GET(SGMII_DEV_VERSION, ver);
-+ if (ver != 0x1) {
-+ dev_err(dev, "unknown PCS device version %04x\n", ver);
-+ return NULL;
-+ }
-+
-+ 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;
-+
-+ mpcs->ana_rgc3 = ana_rgc3;
-+ mpcs->regmap = regmap;
-+ mpcs->flags = flags;
-+ mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
-+ mpcs->pcs.poll = true;
-+ mpcs->interface = PHY_INTERFACE_MODE_NA;
-+
-+ return &mpcs->pcs;
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_create);
-+
-+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs)
-+{
-+ if (!pcs)
-+ return;
-+
-+ kfree(pcs_to_mtk_pcs_lynxi(pcs));
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_destroy);
-+
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/include/linux/pcs/pcs-mtk-lynxi.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __LINUX_PCS_MTK_LYNXI_H
-+#define __LINUX_PCS_MTK_LYNXI_H
-+
-+#include <linux/phylink.h>
-+#include <linux/regmap.h>
-+
-+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
-+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
-+ struct regmap *regmap,
-+ u32 ana_rgc3, u32 flags);
-+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
-+#endif
diff --git a/target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch b/target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch
deleted file mode 100644
index 421563ef08..0000000000
--- a/target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 43ed6fff01333868a1d0e19876f67c22d9939952 Mon Sep 17 00:00:00 2001
-From: Yuval Shaia <yshaia@marvell.com>
-Date: Wed, 13 Oct 2021 09:49:21 +0300
-Subject: [PATCH] net: mvneta: Delete unused variable
-
-The variable pp is not in use - delete it.
-
-Signed-off-by: Yuval Shaia <yshaia@marvell.com>
-Link: https://lore.kernel.org/r/20211013064921.26346-1-yshaia@marvell.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/marvell/mvneta.c | 11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -1914,7 +1914,7 @@ static int mvneta_rx_refill(struct mvnet
- }
-
- /* Handle tx checksum */
--static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb)
-+static u32 mvneta_skb_tx_csum(struct sk_buff *skb)
- {
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- int ip_hdr_len = 0;
-@@ -2595,8 +2595,7 @@ err_drop_frame:
- }
-
- static inline void
--mvneta_tso_put_hdr(struct sk_buff *skb,
-- struct mvneta_port *pp, struct mvneta_tx_queue *txq)
-+mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq)
- {
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
-@@ -2604,7 +2603,7 @@ mvneta_tso_put_hdr(struct sk_buff *skb,
-
- tx_desc = mvneta_txq_next_desc_get(txq);
- tx_desc->data_size = hdr_len;
-- tx_desc->command = mvneta_skb_tx_csum(pp, skb);
-+ tx_desc->command = mvneta_skb_tx_csum(skb);
- tx_desc->command |= MVNETA_TXD_F_DESC;
- tx_desc->buf_phys_addr = txq->tso_hdrs_phys +
- txq->txq_put_index * TSO_HEADER_SIZE;
-@@ -2681,7 +2680,7 @@ static int mvneta_tx_tso(struct sk_buff
- hdr = txq->tso_hdrs + txq->txq_put_index * TSO_HEADER_SIZE;
- tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0);
-
-- mvneta_tso_put_hdr(skb, pp, txq);
-+ mvneta_tso_put_hdr(skb, txq);
-
- while (data_left > 0) {
- int size;
-@@ -2799,7 +2798,7 @@ static netdev_tx_t mvneta_tx(struct sk_b
- /* Get a descriptor for the first part of the packet */
- tx_desc = mvneta_txq_next_desc_get(txq);
-
-- tx_cmd = mvneta_skb_tx_csum(pp, skb);
-+ tx_cmd = mvneta_skb_tx_csum(skb);
-
- tx_desc->data_size = skb_headlen(skb);
-
diff --git a/target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch b/target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch
deleted file mode 100644
index a16e68ee4f..0000000000
--- a/target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0cf39c6543469aae4a30cba354243125514ed568 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 29 Mar 2023 13:11:17 +0100
-Subject: [PATCH] net: mvneta: fix potential double-frees in
- mvneta_txq_sw_deinit()
-
-Reported on the Turris forum, mvneta provokes kernel warnings in the
-architecture DMA mapping code when mvneta_setup_txqs() fails to
-allocate memory. This happens because when mvneta_cleanup_txqs() is
-called in the mvneta_stop() path, we leave pointers in the structure
-that have been freed.
-
-Then on mvneta_open(), we call mvneta_setup_txqs(), which starts
-allocating memory. On memory allocation failure, mvneta_cleanup_txqs()
-will walk all the queues freeing any non-NULL pointers - which includes
-pointers that were previously freed in mvneta_stop().
-
-Fix this by setting these pointers to NULL to prevent double-freeing
-of the same memory.
-
-Link: https://forum.turris.cz/t/random-kernel-exceptions-on-hbl-tos-7-0/18865/8
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/ethernet/marvell/mvneta.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -3481,6 +3481,8 @@ static void mvneta_txq_sw_deinit(struct
-
- netdev_tx_reset_queue(nq);
-
-+ txq->buf = NULL;
-+ txq->tso_hdrs = NULL;
- txq->descs = NULL;
- txq->last_desc = 0;
- txq->next_desc_to_proc = 0;
diff --git a/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch b/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch
deleted file mode 100644
index a3842d35f5..0000000000
--- a/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 0cf731f9ebb5bf6f252055bebf4463a5c0bd490b Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 23 Aug 2022 14:24:07 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix hw hash reporting for
- MTK_NETSYS_V2
-
-Properly report hw rx hash for mt7986 chipset accroding to the new dma
-descriptor layout.
-
-Fixes: 197c9e9b17b11 ("net: ethernet: mtk_eth_soc: introduce support for mt7986 chipset")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/091394ea4e705fbb35f828011d98d0ba33808f69.1661257293.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 +++++++++++----------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +++++
- 2 files changed, 17 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1845,10 +1845,19 @@ static int mtk_poll_rx(struct napi_struc
- skb->dev = netdev;
- bytes += skb->len;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
-+ if (hash != MTK_RXD5_FOE_ENTRY)
-+ skb_set_hash(skb, jhash_1word(hash, 0),
-+ PKT_HASH_TYPE_L4);
- rxdcsum = &trxd.rxd3;
-- else
-+ } else {
-+ hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY;
-+ if (hash != MTK_RXD4_FOE_ENTRY)
-+ skb_set_hash(skb, jhash_1word(hash, 0),
-+ PKT_HASH_TYPE_L4);
- rxdcsum = &trxd.rxd4;
-+ }
-
- if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-@@ -1856,16 +1865,9 @@ static int mtk_poll_rx(struct napi_struc
- skb_checksum_none_assert(skb);
- skb->protocol = eth_type_trans(skb, netdev);
-
-- hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY;
-- if (hash != MTK_RXD4_FOE_ENTRY) {
-- hash = jhash_1word(hash, 0);
-- skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
-- }
--
- reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-- mtk_ppe_check_skb(eth->ppe, skb,
-- trxd.rxd4 & MTK_RXD4_FOE_ENTRY);
-+ mtk_ppe_check_skb(eth->ppe, skb, hash);
-
- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -314,6 +314,11 @@
- #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */
- #define RX_DMA_SPECIAL_TAG BIT(22)
-
-+/* PDMA descriptor rxd5 */
-+#define MTK_RXD5_FOE_ENTRY GENMASK(14, 0)
-+#define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18)
-+#define MTK_RXD5_SRC_PORT GENMASK(29, 26)
-+
- #define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf)
- #define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7)
-
diff --git a/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch b/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch
deleted file mode 100644
index 0de8ab4376..0000000000
--- a/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Tom Rix <trix@redhat.com>
-Date: Sat, 16 Jul 2022 17:46:54 -0400
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix off by one check of
- ARRAY_SIZE
-
-In mtk_wed_tx_ring_setup(.., int idx, ..), idx is used as an index here
- struct mtk_wed_ring *ring = &dev->tx_ring[idx];
-
-The bounds of idx are checked here
- BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
-
-If idx is the size of the array, it will pass this check and overflow.
-So change the check to >= .
-
-Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Signed-off-by: Tom Rix <trix@redhat.com>
-Link: https://lore.kernel.org/r/20220716214654.1540240-1-trix@redhat.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -651,7 +651,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- * WDMA RX.
- */
-
-- BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
-+ BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring));
-
- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE))
- return -ENOMEM;
diff --git a/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch b/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch
deleted file mode 100644
index fc6e246468..0000000000
--- a/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Jul 2022 11:51:53 +0200
-Subject: [PATCH] net: ethernet: mtk_ppe: fix possible NULL pointer dereference
- in mtk_flow_get_wdma_info
-
-odev pointer can be NULL in mtk_flow_offload_replace routine according
-to the flower action rules. Fix possible NULL pointer dereference in
-mtk_flow_get_wdma_info.
-
-Fixes: a333215e10cb5 ("net: ethernet: mtk_eth_soc: implement flow offloading to WED devices")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/4e1685bc4976e21e364055f6bee86261f8f9ee93.1658137753.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -93,6 +93,9 @@ mtk_flow_get_wdma_info(struct net_device
- };
- struct net_device_path path = {};
-
-+ if (!ctx.dev)
-+ return -ENODEV;
-+
- memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
-
- if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED))
diff --git a/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch b/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch
deleted file mode 100644
index c0720152d6..0000000000
--- a/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 22 Jul 2022 09:06:19 +0200
-Subject: [PATCH] net: ethernet: mtk-ppe: fix traffic offload with bridged wlan
-
-A typical flow offload scenario for OpenWrt users is routed traffic
-received by the wan interface that is redirected to a wlan device
-belonging to the lan bridge. Current implementation fails to
-fill wdma offload info in mtk_flow_get_wdma_info() since odev device is
-the local bridge. Fix the issue running dev_fill_forward_path routine in
-mtk_flow_get_wdma_info in order to identify the wlan device.
-
-Tested-by: Paolo Valerio <pvalerio@redhat.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -88,32 +88,28 @@ mtk_flow_offload_mangle_eth(const struct
- static int
- mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_info *info)
- {
-- struct net_device_path_ctx ctx = {
-- .dev = dev,
-- };
-- struct net_device_path path = {};
-+ struct net_device_path_stack stack;
-+ struct net_device_path *path;
-+ int err;
-
-- if (!ctx.dev)
-+ if (!dev)
- return -ENODEV;
-
-- memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
--
- if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED))
- return -1;
-
-- if (!dev->netdev_ops->ndo_fill_forward_path)
-- return -1;
--
-- if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path))
-- return -1;
-+ err = dev_fill_forward_path(dev, addr, &stack);
-+ if (err)
-+ return err;
-
-- if (path.type != DEV_PATH_MTK_WDMA)
-+ path = &stack.path[stack.num_paths - 1];
-+ if (path->type != DEV_PATH_MTK_WDMA)
- return -1;
-
-- info->wdma_idx = path.mtk_wdma.wdma_idx;
-- info->queue = path.mtk_wdma.queue;
-- info->bss = path.mtk_wdma.bss;
-- info->wcid = path.mtk_wdma.wcid;
-+ info->wdma_idx = path->mtk_wdma.wdma_idx;
-+ info->queue = path->mtk_wdma.queue;
-+ info->bss = path->mtk_wdma.bss;
-+ info->wcid = path->mtk_wdma.wcid;
-
- return 0;
- }
diff --git a/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch b/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch
deleted file mode 100644
index 3c28e83551..0000000000
--- a/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c9daab322313087afde8c46f41df3c628410ae20 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 5 Sep 2022 14:46:01 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: remove mtk_foe_entry_timestamp
-
-Get rid of mtk_foe_entry_timestamp routine since it is no longer used.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_ppe.h | 11 -----------
- 1 file changed, 11 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -302,17 +302,6 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s
- __mtk_ppe_check_skb(ppe, skb, hash);
- }
-
--static inline int
--mtk_foe_entry_timestamp(struct mtk_ppe *ppe, u16 hash)
--{
-- u32 ib1 = READ_ONCE(ppe->foe_table[hash].ib1);
--
-- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND)
-- return -1;
--
-- return FIELD_GET(MTK_FOE_IB1_BIND_TIMESTAMP, ib1);
--}
--
- int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto,
- u8 pse_port, u8 *src_mac, u8 *dest_mac);
- int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port);
diff --git a/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch b/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch
deleted file mode 100644
index f4eb030ef6..0000000000
--- a/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 5e69163d3b9931098922b3fc2f8e786af8c1f37e Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 13 Sep 2022 15:03:05 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: enable XDP support just for
- MT7986 SoC
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Disable page_pool/XDP support for MT7621 SoC in order fix a regression
-introduce adding XDP for MT7986 SoC. There is no a real use case for XDP
-on MT7621 since it is a low-end cpu. Moreover this patch reduces the
-memory footprint.
-
-Tested-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Fixes: 23233e577ef9 ("net: ethernet: mtk_eth_soc: rely on page_pool for single page buffers")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/2bf31e27b888c43228b0d84dd2ef5033338269e2.1663074002.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1412,7 +1412,7 @@ static void mtk_update_rx_cpu_idx(struct
-
- static bool mtk_page_pool_enabled(struct mtk_eth *eth)
- {
-- return !eth->hwlro;
-+ return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);
- }
-
- static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
diff --git a/target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch b/target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch
deleted file mode 100644
index be6da9b4af..0000000000
--- a/target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From patchwork Thu Sep 8 19:33:38 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Lorenzo Bianconi <lorenzo@kernel.org>
-X-Patchwork-Id: 12970556
-X-Patchwork-Delegate: kuba@kernel.org
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-To: netdev@vger.kernel.org
-Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com,
- Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com,
- linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com,
- Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com,
- ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com,
- devicetree@vger.kernel.org, robh@kernel.org
-Subject: [PATCH net-next 03/12] net: ethernet: mtk_eth_soc: move gdma_to_ppe
- and ppe_base definitions in mtk register map
-Date: Thu, 8 Sep 2022 21:33:37 +0200
-Message-Id:
- <95938fc9cbe0223714be2658a49ca58e9baace00.1662661555.git.lorenzo@kernel.org>
-X-Mailer: git-send-email 2.37.3
-In-Reply-To: <cover.1662661555.git.lorenzo@kernel.org>
-References: <cover.1662661555.git.lorenzo@kernel.org>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-This is a preliminary patch to introduce mt7986 hw packet engine.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 +++++++++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 ++-
- drivers/net/ethernet/mediatek/mtk_ppe.h | 2 --
- 3 files changed, 13 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -73,6 +73,8 @@ static const struct mtk_reg_map mtk_reg_
- .fq_blen = 0x1b2c,
- },
- .gdm1_cnt = 0x2400,
-+ .gdma_to_ppe0 = 0x4444,
-+ .ppe_base = 0x0c00,
- };
-
- static const struct mtk_reg_map mt7628_reg_map = {
-@@ -126,6 +128,8 @@ static const struct mtk_reg_map mt7986_r
- .fq_blen = 0x472c,
- },
- .gdm1_cnt = 0x1c00,
-+ .gdma_to_ppe0 = 0x3333,
-+ .ppe_base = 0x2000,
- };
-
- /* strings used by ethtool */
-@@ -2927,6 +2931,7 @@ static int mtk_open(struct net_device *d
-
- /* we run 2 netdevs on the same dma ring so we only bring it up once */
- if (!refcount_read(&eth->dma_refcnt)) {
-+ const struct mtk_soc_data *soc = eth->soc;
- u32 gdm_config = MTK_GDMA_TO_PDMA;
- int err;
-
-@@ -2936,15 +2941,15 @@ static int mtk_open(struct net_device *d
- return err;
- }
-
-- if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
-- gdm_config = MTK_GDMA_TO_PPE;
-+ if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
-+ gdm_config = soc->reg_map->gdma_to_ppe0;
-
- mtk_gdm_config(eth, gdm_config);
-
- napi_enable(&eth->tx_napi);
- napi_enable(&eth->rx_napi);
- mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-- mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
-+ mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
- refcount_set(&eth->dma_refcnt, 1);
- }
- else
-@@ -4043,7 +4048,9 @@ static int mtk_probe(struct platform_dev
- }
-
- if (eth->soc->offload_version) {
-- eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
-+ u32 ppe_addr = eth->soc->reg_map->ppe_base;
-+
-+ eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2);
- if (!eth->ppe) {
- err = -ENOMEM;
- goto err_free_dev;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -105,7 +105,6 @@
- #define MTK_GDMA_TCS_EN BIT(21)
- #define MTK_GDMA_UCS_EN BIT(20)
- #define MTK_GDMA_TO_PDMA 0x0
--#define MTK_GDMA_TO_PPE 0x4444
- #define MTK_GDMA_DROP_ALL 0x7777
-
- /* Unicast Filter MAC Address Register - Low */
-@@ -953,6 +952,8 @@ struct mtk_reg_map {
- u32 fq_blen; /* fq free page buffer length */
- } qdma;
- u32 gdm1_cnt;
-+ u32 gdma_to_ppe0;
-+ u32 ppe_base;
- };
-
- /* struct mtk_eth_data - This is the structure holding all differences
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -8,8 +8,6 @@
- #include <linux/bitfield.h>
- #include <linux/rhashtable.h>
-
--#define MTK_ETH_PPE_BASE 0xc00
--
- #define MTK_PPE_ENTRIES_SHIFT 3
- #define MTK_PPE_ENTRIES (1024 << MTK_PPE_ENTRIES_SHIFT)
- #define MTK_PPE_HASH_MASK (MTK_PPE_ENTRIES - 1)
diff --git a/target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch b/target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch
deleted file mode 100644
index 76f954f626..0000000000
--- a/target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch
+++ /dev/null
@@ -1,199 +0,0 @@
-From patchwork Thu Sep 8 19:33:38 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Lorenzo Bianconi <lorenzo@kernel.org>
-X-Patchwork-Id: 12970557
-X-Patchwork-Delegate: kuba@kernel.org
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-To: netdev@vger.kernel.org
-Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com,
- Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com,
- linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com,
- Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com,
- ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com,
- devicetree@vger.kernel.org, robh@kernel.org
-Subject: [PATCH net-next 04/12] net: ethernet: mtk_eth_soc: move ppe table
- hash offset to mtk_soc_data structure
-Date: Thu, 8 Sep 2022 21:33:38 +0200
-Message-Id:
- <cc263ffeaa3e1d7314e36a4f941e96d38e41a6bf.1662661555.git.lorenzo@kernel.org>
-X-Mailer: git-send-email 2.37.3
-In-Reply-To: <cover.1662661555.git.lorenzo@kernel.org>
-References: <cover.1662661555.git.lorenzo@kernel.org>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-This is a preliminary patch to introduce mt7986 hw packet engine.
-
-Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
- drivers/net/ethernet/mediatek/mtk_ppe.c | 24 +++++++++++++++------
- drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +-
- 4 files changed, 25 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4146,6 +4146,7 @@ static const struct mtk_soc_data mt7621_
- .required_clks = MT7621_CLKS_BITMAP,
- .required_pctl = false,
- .offload_version = 2,
-+ .hash_offset = 2,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4164,6 +4165,7 @@ static const struct mtk_soc_data mt7622_
- .required_clks = MT7622_CLKS_BITMAP,
- .required_pctl = false,
- .offload_version = 2,
-+ .hash_offset = 2,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4181,6 +4183,7 @@ static const struct mtk_soc_data mt7623_
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
- .offload_version = 2,
-+ .hash_offset = 2,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4214,6 +4217,7 @@ static const struct mtk_soc_data mt7986_
- .caps = MT7986_CAPS,
- .required_clks = MT7986_CLKS_BITMAP,
- .required_pctl = false,
-+ .hash_offset = 4,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -967,6 +967,7 @@ struct mtk_reg_map {
- * the target SoC
- * @required_pctl A bool value to show whether the SoC requires
- * the extra setup for those pins used by GMAC.
-+ * @hash_offset Flow table hash offset.
- * @txd_size Tx DMA descriptor size.
- * @rxd_size Rx DMA descriptor size.
- * @rx_irq_done_mask Rx irq done register mask.
-@@ -981,6 +982,7 @@ struct mtk_soc_data {
- u32 required_clks;
- bool required_pctl;
- u8 offload_version;
-+ u8 hash_offset;
- netdev_features_t hw_features;
- struct {
- u32 txd_size;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -88,7 +88,7 @@ static void mtk_ppe_cache_enable(struct
- enable * MTK_PPE_CACHE_CTL_EN);
- }
-
--static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
-+static u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e)
- {
- u32 hv1, hv2, hv3;
- u32 hash;
-@@ -122,7 +122,7 @@ static u32 mtk_ppe_hash_entry(struct mtk
- hash = (hash >> 24) | ((hash & 0xffffff) << 8);
- hash ^= hv1 ^ hv2 ^ hv3;
- hash ^= hash >> 16;
-- hash <<= 1;
-+ hash <<= (ffs(eth->soc->hash_offset) - 1);
- hash &= MTK_PPE_ENTRIES - 1;
-
- return hash;
-@@ -540,15 +540,16 @@ mtk_foe_entry_commit_l2(struct mtk_ppe *
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1);
-+ const struct mtk_soc_data *soc = ppe->eth->soc;
- u32 hash;
-
- if (type == MTK_PPE_PKT_TYPE_BRIDGE)
- return mtk_foe_entry_commit_l2(ppe, entry);
-
-- hash = mtk_ppe_hash_entry(&entry->data);
-+ hash = mtk_ppe_hash_entry(ppe->eth, &entry->data);
- entry->hash = 0xffff;
- spin_lock_bh(&ppe_lock);
-- hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]);
-+ hlist_add_head(&entry->list, &ppe->foe_flow[hash / soc->hash_offset]);
- spin_unlock_bh(&ppe_lock);
-
- return 0;
-@@ -558,6 +559,7 @@ static void
- mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
- u16 hash)
- {
-+ const struct mtk_soc_data *soc = ppe->eth->soc;
- struct mtk_flow_entry *flow_info;
- struct mtk_foe_entry foe, *hwe;
- struct mtk_foe_mac_info *l2;
-@@ -572,7 +574,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
- flow_info->l2_data.base_flow = entry;
- flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW;
- flow_info->hash = hash;
-- hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 2]);
-+ hlist_add_head(&flow_info->list,
-+ &ppe->foe_flow[hash / soc->hash_offset]);
- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
-
- hwe = &ppe->foe_table[hash];
-@@ -596,7 +599,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
- {
-- struct hlist_head *head = &ppe->foe_flow[hash / 2];
-+ const struct mtk_soc_data *soc = ppe->eth->soc;
-+ struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset];
- struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
- struct mtk_flow_entry *entry;
- struct mtk_foe_bridge key = {};
-@@ -680,9 +684,11 @@ int mtk_foe_entry_idle_time(struct mtk_p
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version)
- {
-+ const struct mtk_soc_data *soc = eth->soc;
- struct device *dev = eth->dev;
- struct mtk_foe_entry *foe;
- struct mtk_ppe *ppe;
-+ u32 foe_flow_size;
-
- ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL);
- if (!ppe)
-@@ -705,6 +711,12 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
-
- ppe->foe_table = foe;
-
-+ foe_flow_size = (MTK_PPE_ENTRIES / soc->hash_offset) *
-+ sizeof(*ppe->foe_flow);
-+ ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
-+ if (!ppe->foe_flow)
-+ return NULL;
-+
- mtk_ppe_debugfs_init(ppe);
-
- return ppe;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -270,7 +270,7 @@ struct mtk_ppe {
- dma_addr_t foe_phys;
-
- u16 foe_check_time[MTK_PPE_ENTRIES];
-- struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2];
-+ struct hlist_head *foe_flow;
-
- struct rhashtable l2_flows;
-
diff --git a/target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch b/target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch
deleted file mode 100644
index fb64da3d7a..0000000000
--- a/target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch
+++ /dev/null
@@ -1,318 +0,0 @@
-From patchwork Thu Sep 8 19:33:39 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Lorenzo Bianconi <lorenzo@kernel.org>
-X-Patchwork-Id: 12970559
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-To: netdev@vger.kernel.org
-Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com,
- Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com,
- linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com,
- Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com,
- ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com,
- devicetree@vger.kernel.org, robh@kernel.org
-Subject: [PATCH net-next 05/12] net: ethernet: mtk_eth_soc: add the capability
- to run multiple ppe
-Date: Thu, 8 Sep 2022 21:33:39 +0200
-Message-Id:
- <dd0254775390eb031c67c448df8b19e87df58558.1662661555.git.lorenzo@kernel.org>
-X-Mailer: git-send-email 2.37.3
-In-Reply-To: <cover.1662661555.git.lorenzo@kernel.org>
-References: <cover.1662661555.git.lorenzo@kernel.org>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-mt7986 chipset support multiple packet engines for wlan <-> eth
-packet forwarding.
-
-Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ++++++++++++-------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
- drivers/net/ethernet/mediatek/mtk_ppe.c | 14 +++++---
- drivers/net/ethernet/mediatek/mtk_ppe.h | 9 +++--
- .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 8 ++---
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 13 +++----
- 6 files changed, 48 insertions(+), 33 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1871,7 +1871,7 @@ static int mtk_poll_rx(struct napi_struc
-
- reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-- mtk_ppe_check_skb(eth->ppe, skb, hash);
-+ mtk_ppe_check_skb(eth->ppe[0], skb, hash);
-
- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-@@ -2932,7 +2932,8 @@ static int mtk_open(struct net_device *d
- /* we run 2 netdevs on the same dma ring so we only bring it up once */
- if (!refcount_read(&eth->dma_refcnt)) {
- const struct mtk_soc_data *soc = eth->soc;
-- u32 gdm_config = MTK_GDMA_TO_PDMA;
-+ u32 gdm_config;
-+ int i;
- int err;
-
- err = mtk_start_dma(eth);
-@@ -2941,8 +2942,11 @@ static int mtk_open(struct net_device *d
- return err;
- }
-
-- if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
-- gdm_config = soc->reg_map->gdma_to_ppe0;
-+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
-+ mtk_ppe_start(eth->ppe[i]);
-+
-+ gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe0
-+ : MTK_GDMA_TO_PDMA;
-
- mtk_gdm_config(eth, gdm_config);
-
-@@ -2987,6 +2991,7 @@ static int mtk_stop(struct net_device *d
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-+ int i;
-
- phylink_stop(mac->phylink);
-
-@@ -3014,8 +3019,8 @@ static int mtk_stop(struct net_device *d
-
- mtk_dma_free(eth);
-
-- if (eth->soc->offload_version)
-- mtk_ppe_stop(eth->ppe);
-+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
-+ mtk_ppe_stop(eth->ppe[i]);
-
- return 0;
- }
-@@ -4048,12 +4053,19 @@ static int mtk_probe(struct platform_dev
- }
-
- if (eth->soc->offload_version) {
-- u32 ppe_addr = eth->soc->reg_map->ppe_base;
-+ u32 num_ppe;
-
-- eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2);
-- if (!eth->ppe) {
-- err = -ENOMEM;
-- goto err_free_dev;
-+ num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
-+ num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
-+ for (i = 0; i < num_ppe; i++) {
-+ u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
-+
-+ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
-+ eth->soc->offload_version, i);
-+ if (!eth->ppe[i]) {
-+ err = -ENOMEM;
-+ goto err_free_dev;
-+ }
- }
-
- err = mtk_eth_offload_init(eth);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1112,7 +1112,7 @@ struct mtk_eth {
-
- int ip_align;
-
-- struct mtk_ppe *ppe;
-+ struct mtk_ppe *ppe[2];
- struct rhashtable flow_table;
-
- struct bpf_prog __rcu *prog;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -682,7 +682,7 @@ int mtk_foe_entry_idle_time(struct mtk_p
- }
-
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-- int version)
-+ int version, int index)
- {
- const struct mtk_soc_data *soc = eth->soc;
- struct device *dev = eth->dev;
-@@ -717,7 +717,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- if (!ppe->foe_flow)
- return NULL;
-
-- mtk_ppe_debugfs_init(ppe);
-+ mtk_ppe_debugfs_init(ppe, index);
-
- return ppe;
- }
-@@ -738,10 +738,13 @@ static void mtk_ppe_init_foe_table(struc
- ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC;
- }
-
--int mtk_ppe_start(struct mtk_ppe *ppe)
-+void mtk_ppe_start(struct mtk_ppe *ppe)
- {
- u32 val;
-
-+ if (!ppe)
-+ return;
-+
- mtk_ppe_init_foe_table(ppe);
- ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
-
-@@ -809,8 +812,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
- ppe_w32(ppe, MTK_PPE_GLO_CFG, val);
-
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
--
-- return 0;
- }
-
- int mtk_ppe_stop(struct mtk_ppe *ppe)
-@@ -818,6 +819,9 @@ int mtk_ppe_stop(struct mtk_ppe *ppe)
- u32 val;
- int i;
-
-+ if (!ppe)
-+ return 0;
-+
- for (i = 0; i < MTK_PPE_ENTRIES; i++)
- ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
- MTK_FOE_STATE_INVALID);
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -247,6 +247,7 @@ struct mtk_flow_entry {
- };
- u8 type;
- s8 wed_index;
-+ u8 ppe_index;
- u16 hash;
- union {
- struct mtk_foe_entry data;
-@@ -265,6 +266,7 @@ struct mtk_ppe {
- struct device *dev;
- void __iomem *base;
- int version;
-+ char dirname[5];
-
- struct mtk_foe_entry *foe_table;
- dma_addr_t foe_phys;
-@@ -277,8 +279,9 @@ struct mtk_ppe {
- void *acct_table;
- };
-
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
--int mtk_ppe_start(struct mtk_ppe *ppe);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-+ int version, int index);
-+void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
-@@ -317,6 +320,6 @@ int mtk_foe_entry_set_wdma(struct mtk_fo
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
--int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
-+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
-
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -187,7 +187,7 @@ mtk_ppe_debugfs_foe_open_bind(struct ino
- inode->i_private);
- }
-
--int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
-+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index)
- {
- static const struct file_operations fops_all = {
- .open = mtk_ppe_debugfs_foe_open_all,
-@@ -195,17 +195,17 @@ int mtk_ppe_debugfs_init(struct mtk_ppe
- .llseek = seq_lseek,
- .release = single_release,
- };
--
- static const struct file_operations fops_bind = {
- .open = mtk_ppe_debugfs_foe_open_bind,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- };
--
- struct dentry *root;
-
-- root = debugfs_create_dir("mtk_ppe", NULL);
-+ snprintf(ppe->dirname, sizeof(ppe->dirname), "ppe%d", index);
-+
-+ root = debugfs_create_dir(ppe->dirname, NULL);
- if (!root)
- return -ENOMEM;
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -434,7 +434,7 @@ mtk_flow_offload_replace(struct mtk_eth
- memcpy(&entry->data, &foe, sizeof(entry->data));
- entry->wed_index = wed_index;
-
-- err = mtk_foe_entry_commit(eth->ppe, entry);
-+ err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry);
- if (err < 0)
- goto free;
-
-@@ -446,7 +446,7 @@ mtk_flow_offload_replace(struct mtk_eth
- return 0;
-
- clear:
-- mtk_foe_entry_clear(eth->ppe, entry);
-+ mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
- free:
- kfree(entry);
- if (wed_index >= 0)
-@@ -464,7 +464,7 @@ mtk_flow_offload_destroy(struct mtk_eth
- if (!entry)
- return -ENOENT;
-
-- mtk_foe_entry_clear(eth->ppe, entry);
-+ mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
- rhashtable_remove_fast(&eth->flow_table, &entry->node,
- mtk_flow_ht_params);
- if (entry->wed_index >= 0)
-@@ -485,7 +485,7 @@ mtk_flow_offload_stats(struct mtk_eth *e
- if (!entry)
- return -ENOENT;
-
-- idle = mtk_foe_entry_idle_time(eth->ppe, entry);
-+ idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
- f->stats.lastused = jiffies - idle * HZ;
-
- return 0;
-@@ -537,7 +537,7 @@ mtk_eth_setup_tc_block(struct net_device
- struct flow_block_cb *block_cb;
- flow_setup_cb_t *cb;
-
-- if (!eth->ppe || !eth->ppe->foe_table)
-+ if (!eth->soc->offload_version)
- return -EOPNOTSUPP;
-
- if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
-@@ -590,8 +590,5 @@ int mtk_eth_setup_tc(struct net_device *
-
- int mtk_eth_offload_init(struct mtk_eth *eth)
- {
-- if (!eth->ppe || !eth->ppe->foe_table)
-- return 0;
--
- return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
- }
diff --git a/target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch b/target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch
deleted file mode 100644
index 6a58334c32..0000000000
--- a/target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 0dcbe607cec32ccae23b02a641b8bd6191a328ae Mon Sep 17 00:00:00 2001
-Message-Id: <0dcbe607cec32ccae23b02a641b8bd6191a328ae.1662243796.git.lorenzo@kernel.org>
-In-Reply-To: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org>
-References: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 23 Aug 2022 23:09:05 +0200
-Subject: [PATCH net-next 2/4] net: ethernet: mtk_eth_soc: move wdma_base
- definitions in mtk register map
-
-This is a preliminary patch to introduce mt7986 wed support.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++++------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 +---
- 2 files changed, 11 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -75,6 +75,10 @@ static const struct mtk_reg_map mtk_reg_
- .gdm1_cnt = 0x2400,
- .gdma_to_ppe0 = 0x4444,
- .ppe_base = 0x0c00,
-+ .wdma_base = {
-+ [0] = 0x2800,
-+ [1] = 0x2c00,
-+ },
- };
-
- static const struct mtk_reg_map mt7628_reg_map = {
-@@ -130,6 +134,10 @@ static const struct mtk_reg_map mt7986_r
- .gdm1_cnt = 0x1c00,
- .gdma_to_ppe0 = 0x3333,
- .ppe_base = 0x2000,
-+ .wdma_base = {
-+ [0] = 0x4800,
-+ [1] = 0x4c00,
-+ },
- };
-
- /* strings used by ethtool */
-@@ -3965,16 +3973,12 @@ static int mtk_probe(struct platform_dev
- for (i = 0;; i++) {
- struct device_node *np = of_parse_phandle(pdev->dev.of_node,
- "mediatek,wed", i);
-- static const u32 wdma_regs[] = {
-- MTK_WDMA0_BASE,
-- MTK_WDMA1_BASE
-- };
- void __iomem *wdma;
-
-- if (!np || i >= ARRAY_SIZE(wdma_regs))
-+ if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base))
- break;
-
-- wdma = eth->base + wdma_regs[i];
-+ wdma = eth->base + eth->soc->reg_map->wdma_base[i];
- mtk_wed_add_hw(np, eth, wdma, i);
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -268,9 +268,6 @@
- #define TX_DMA_FPORT_MASK_V2 0xf
- #define TX_DMA_SWC_V2 BIT(30)
-
--#define MTK_WDMA0_BASE 0x2800
--#define MTK_WDMA1_BASE 0x2c00
--
- /* QDMA descriptor txd4 */
- #define TX_DMA_CHKSUM (0x7 << 29)
- #define TX_DMA_TSO BIT(28)
-@@ -954,6 +951,7 @@ struct mtk_reg_map {
- u32 gdm1_cnt;
- u32 gdma_to_ppe0;
- u32 ppe_base;
-+ u32 wdma_base[2];
- };
-
- /* struct mtk_eth_data - This is the structure holding all differences
diff --git a/target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch b/target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch
deleted file mode 100644
index de1f217272..0000000000
--- a/target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch
+++ /dev/null
@@ -1,251 +0,0 @@
-From e3c27d869fccc1f2b8d0b4cde4763ab223874e8c Mon Sep 17 00:00:00 2001
-Message-Id: <e3c27d869fccc1f2b8d0b4cde4763ab223874e8c.1662243796.git.lorenzo@kernel.org>
-In-Reply-To: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org>
-References: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sun, 21 Aug 2022 17:51:17 +0200
-Subject: [PATCH net-next 3/4] net: ethernet: mtk_eth_soc: add foe_entry_size
- to mtk_eth_soc
-
-Introduce foe_entry_size to mtk_eth_soc data structure since mt7986
-relies on a bigger mtk_foe_entry data structure.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++++
- drivers/net/ethernet/mediatek/mtk_ppe.c | 55 +++++++++++--------
- drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +-
- .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +-
- 5 files changed, 48 insertions(+), 24 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4163,6 +4163,7 @@ static const struct mtk_soc_data mt7621_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 2,
-+ .foe_entry_size = sizeof(struct mtk_foe_entry),
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4182,6 +4183,7 @@ static const struct mtk_soc_data mt7622_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 2,
-+ .foe_entry_size = sizeof(struct mtk_foe_entry),
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4200,6 +4202,7 @@ static const struct mtk_soc_data mt7623_
- .required_pctl = true,
- .offload_version = 2,
- .hash_offset = 2,
-+ .foe_entry_size = sizeof(struct mtk_foe_entry),
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -966,6 +966,7 @@ struct mtk_reg_map {
- * @required_pctl A bool value to show whether the SoC requires
- * the extra setup for those pins used by GMAC.
- * @hash_offset Flow table hash offset.
-+ * @foe_entry_size Foe table entry size.
- * @txd_size Tx DMA descriptor size.
- * @rxd_size Rx DMA descriptor size.
- * @rx_irq_done_mask Rx irq done register mask.
-@@ -981,6 +982,7 @@ struct mtk_soc_data {
- bool required_pctl;
- u8 offload_version;
- u8 hash_offset;
-+ u16 foe_entry_size;
- netdev_features_t hw_features;
- struct {
- u32 txd_size;
-@@ -1141,6 +1143,14 @@ 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[];
-
-+static inline struct mtk_foe_entry *
-+mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
-+{
-+ const struct mtk_soc_data *soc = ppe->eth->soc;
-+
-+ return ppe->foe_table + hash * soc->foe_entry_size;
-+}
-+
- /* read the hardware status register */
- void mtk_stats_update_mac(struct mtk_mac *mac);
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -410,9 +410,10 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
-
- hlist_del_init(&entry->list);
- if (entry->hash != 0xffff) {
-- ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE;
-- ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
-- MTK_FOE_STATE_BIND);
-+ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
-+
-+ hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-+ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND);
- dma_wmb();
- }
- entry->hash = 0xffff;
-@@ -451,7 +452,7 @@ mtk_flow_entry_update_l2(struct mtk_ppe
- int cur_idle;
- u32 ib1;
-
-- hwe = &ppe->foe_table[cur->hash];
-+ hwe = mtk_foe_get_entry(ppe, cur->hash);
- ib1 = READ_ONCE(hwe->ib1);
-
- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) {
-@@ -473,8 +474,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe
- static void
- mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-+ struct mtk_foe_entry foe = {};
- struct mtk_foe_entry *hwe;
-- struct mtk_foe_entry foe;
-
- spin_lock_bh(&ppe_lock);
-
-@@ -486,8 +487,8 @@ mtk_flow_entry_update(struct mtk_ppe *pp
- if (entry->hash == 0xffff)
- goto out;
-
-- hwe = &ppe->foe_table[entry->hash];
-- memcpy(&foe, hwe, sizeof(foe));
-+ hwe = mtk_foe_get_entry(ppe, entry->hash);
-+ memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size);
- if (!mtk_flow_entry_match(entry, &foe)) {
- entry->hash = 0xffff;
- goto out;
-@@ -511,8 +512,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp);
-
-- hwe = &ppe->foe_table[hash];
-- memcpy(&hwe->data, &entry->data, sizeof(hwe->data));
-+ hwe = mtk_foe_get_entry(ppe, hash);
-+ memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size);
- wmb();
- hwe->ib1 = entry->ib1;
-
-@@ -561,7 +562,7 @@ mtk_foe_entry_commit_subflow(struct mtk_
- {
- const struct mtk_soc_data *soc = ppe->eth->soc;
- struct mtk_flow_entry *flow_info;
-- struct mtk_foe_entry foe, *hwe;
-+ struct mtk_foe_entry foe = {}, *hwe;
- struct mtk_foe_mac_info *l2;
- u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP;
- int type;
-@@ -578,8 +579,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
- &ppe->foe_flow[hash / soc->hash_offset]);
- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
-
-- hwe = &ppe->foe_table[hash];
-- memcpy(&foe, hwe, sizeof(foe));
-+ hwe = mtk_foe_get_entry(ppe, hash);
-+ memcpy(&foe, hwe, soc->foe_entry_size);
- foe.ib1 &= ib1_mask;
- foe.ib1 |= entry->data.ib1 & ~ib1_mask;
-
-@@ -601,7 +602,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- {
- const struct mtk_soc_data *soc = ppe->eth->soc;
- struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset];
-- struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
-+ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash);
- struct mtk_flow_entry *entry;
- struct mtk_foe_bridge key = {};
- struct hlist_node *n;
-@@ -686,9 +687,9 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- {
- const struct mtk_soc_data *soc = eth->soc;
- struct device *dev = eth->dev;
-- struct mtk_foe_entry *foe;
- struct mtk_ppe *ppe;
- u32 foe_flow_size;
-+ void *foe;
-
- ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL);
- if (!ppe)
-@@ -704,7 +705,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- ppe->dev = dev;
- ppe->version = version;
-
-- foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
-+ foe = dmam_alloc_coherent(ppe->dev,
-+ MTK_PPE_ENTRIES * soc->foe_entry_size,
- &ppe->foe_phys, GFP_KERNEL);
- if (!foe)
- return NULL;
-@@ -727,15 +729,21 @@ static void mtk_ppe_init_foe_table(struc
- static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 };
- int i, k;
-
-- memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(*ppe->foe_table));
-+ memset(ppe->foe_table, 0,
-+ MTK_PPE_ENTRIES * ppe->eth->soc->foe_entry_size);
-
- if (!IS_ENABLED(CONFIG_SOC_MT7621))
- return;
-
- /* skip all entries that cross the 1024 byte boundary */
-- for (i = 0; i < MTK_PPE_ENTRIES; i += 128)
-- for (k = 0; k < ARRAY_SIZE(skip); k++)
-- ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC;
-+ for (i = 0; i < MTK_PPE_ENTRIES; i += 128) {
-+ for (k = 0; k < ARRAY_SIZE(skip); k++) {
-+ struct mtk_foe_entry *hwe;
-+
-+ hwe = mtk_foe_get_entry(ppe, i + skip[k]);
-+ hwe->ib1 |= MTK_FOE_IB1_STATIC;
-+ }
-+ }
- }
-
- void mtk_ppe_start(struct mtk_ppe *ppe)
-@@ -822,9 +830,12 @@ int mtk_ppe_stop(struct mtk_ppe *ppe)
- if (!ppe)
- return 0;
-
-- for (i = 0; i < MTK_PPE_ENTRIES; i++)
-- ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
-- MTK_FOE_STATE_INVALID);
-+ for (i = 0; i < MTK_PPE_ENTRIES; i++) {
-+ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, i);
-+
-+ hwe->ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
-+ MTK_FOE_STATE_INVALID);
-+ }
-
- mtk_ppe_cache_enable(ppe, false);
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -268,7 +268,7 @@ struct mtk_ppe {
- int version;
- char dirname[5];
-
-- struct mtk_foe_entry *foe_table;
-+ void *foe_table;
- dma_addr_t foe_phys;
-
- u16 foe_check_time[MTK_PPE_ENTRIES];
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -79,7 +79,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- int i;
-
- for (i = 0; i < MTK_PPE_ENTRIES; i++) {
-- struct mtk_foe_entry *entry = &ppe->foe_table[i];
-+ struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
- struct mtk_foe_mac_info *l2;
- struct mtk_flow_addr_info ai = {};
- unsigned char h_source[ETH_ALEN];
diff --git a/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch b/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch
deleted file mode 100644
index 77daf6c8bf..0000000000
--- a/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 12ff69304c83c679ca01ef3db963ab0db9de19fb Mon Sep 17 00:00:00 2001
-Message-Id: <12ff69304c83c679ca01ef3db963ab0db9de19fb.1662332102.git.lorenzo@kernel.org>
-In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org>
-References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 5 Sep 2022 00:43:43 +0200
-Subject: [PATCH net-next 2/6] net: ethernet: mtk_eth_soc: fix typo in
- __mtk_foe_entry_clear
-
-Set ib1 state to MTK_FOE_STATE_UNBIND in __mtk_foe_entry_clear routine.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -413,7 +413,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
-
- hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND);
-+ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_UNBIND);
- dma_wmb();
- }
- entry->hash = 0xffff;
diff --git a/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch b/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch
deleted file mode 100644
index 7ab6d486b2..0000000000
--- a/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 4253e6e2b795a18ab534adcd5c313d3fc4150975 Mon Sep 17 00:00:00 2001
-Message-Id: <4253e6e2b795a18ab534adcd5c313d3fc4150975.1662332102.git.lorenzo@kernel.org>
-In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org>
-References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 5 Sep 2022 00:48:52 +0200
-Subject: [PATCH net-next 3/6] net: ethernet: mtk_eth_soc: check max allowed
- value in mtk_ppe_check_skb
-
-Check theoretical OOB accesses in mtk_ppe_check_skb routine
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -294,6 +294,9 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s
- if (!ppe)
- return;
-
-+ if (hash > MTK_PPE_HASH_MASK)
-+ return;
-+
- now = (u16)jiffies;
- diff = now - ppe->foe_check_time[hash];
- if (diff < HZ / 10)
diff --git a/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch b/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch
deleted file mode 100644
index a8c88daf1f..0000000000
--- a/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-From e5ecb4f619197b93fa682d722452dc8412864cdb Mon Sep 17 00:00:00 2001
-Message-Id: <e5ecb4f619197b93fa682d722452dc8412864cdb.1662886033.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 26 Aug 2022 01:12:57 +0200
-Subject: [PATCH net-next 1/5] net: ethernet: mtk_eth_wed: add
- mtk_wed_configure_irq and mtk_wed_dma_{enable/disable}
-
-Introduce mtk_wed_configure_irq, mtk_wed_dma_enable and mtk_wed_dma_disable
-utility routines.
-This is a preliminary patch to introduce mt7986 wed support.
-
-Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 87 +++++++++++++-------
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 6 +-
- 2 files changed, 64 insertions(+), 29 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -237,9 +237,30 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- }
-
- static void
--mtk_wed_stop(struct mtk_wed_device *dev)
-+mtk_wed_dma_disable(struct mtk_wed_device *dev)
- {
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+
-+ wed_clr(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_TX_DMA_EN |
-+ MTK_WED_GLO_CFG_RX_DMA_EN);
-+
- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
-+ wdma_m32(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_TX_DMA_EN |
-+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0);
-+}
-+
-+static void
-+mtk_wed_stop(struct mtk_wed_device *dev)
-+{
-+ mtk_wed_dma_disable(dev);
- mtk_wed_set_ext_int(dev, false);
-
- wed_clr(dev, MTK_WED_CTRL,
-@@ -252,15 +273,6 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
- wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
--
-- wed_clr(dev, MTK_WED_GLO_CFG,
-- MTK_WED_GLO_CFG_TX_DMA_EN |
-- MTK_WED_GLO_CFG_RX_DMA_EN);
-- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-- wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
- }
-
- static void
-@@ -313,7 +325,10 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
- wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-
-- wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES);
-+ wdma_set(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-
- offset = dev->hw->index ? 0x04000400 : 0;
- wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
-@@ -520,43 +535,38 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_d
- }
-
- static void
--mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
-+mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
- {
-- u32 wdma_mask;
-- u32 val;
-- int i;
--
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- if (!dev->tx_wdma[i].desc)
-- mtk_wed_wdma_ring_setup(dev, i, 16);
--
-- wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
--
-- mtk_wed_hw_init(dev);
-+ u32 wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
-
-+ /* wed control cr set */
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WDMA_INT_AGENT_EN |
- MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS);
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
-+ MTK_WED_PCIE_INT_TRIGGER_STATUS);
-
- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER,
- MTK_WED_WPDMA_INT_TRIGGER_RX_DONE |
- MTK_WED_WPDMA_INT_TRIGGER_TX_DONE);
-
-- wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
-- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
--
-+ /* initail wdma interrupt agent */
- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
-
- wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask);
- wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask);
--
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
- wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
-+}
-+
-+static void
-+mtk_wed_dma_enable(struct mtk_wed_device *dev)
-+{
-+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-
- wed_set(dev, MTK_WED_GLO_CFG,
- MTK_WED_GLO_CFG_TX_DMA_EN |
-@@ -567,6 +577,26 @@ mtk_wed_start(struct mtk_wed_device *dev
- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-
-+ wdma_set(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_TX_DMA_EN |
-+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-+}
-+
-+static void
-+mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
-+{
-+ u32 val;
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-+ if (!dev->tx_wdma[i].desc)
-+ mtk_wed_wdma_ring_setup(dev, i, 16);
-+
-+ mtk_wed_hw_init(dev);
-+ mtk_wed_configure_irq(dev, irq_mask);
-+
- mtk_wed_set_ext_int(dev, true);
- val = dev->wlan.wpdma_phys |
- MTK_PCIE_MIRROR_MAP_EN |
-@@ -577,6 +607,7 @@ mtk_wed_start(struct mtk_wed_device *dev
- val |= BIT(0);
- regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
-
-+ mtk_wed_dma_enable(dev);
- dev->running = true;
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -224,7 +224,11 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10)
-
- #define MTK_WDMA_GLO_CFG 0x204
--#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES GENMASK(28, 26)
-+#define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0)
-+#define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2)
-+#define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26)
-+#define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27)
-+#define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28)
-
- #define MTK_WDMA_RESET_IDX 0x208
- #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0)
diff --git a/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch b/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch
deleted file mode 100644
index 00255cdcf6..0000000000
--- a/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch
+++ /dev/null
@@ -1,942 +0,0 @@
-From 463a71af080fbc77339bee2037fb1e081e3824f7 Mon Sep 17 00:00:00 2001
-Message-Id: <463a71af080fbc77339bee2037fb1e081e3824f7.1662886034.git.lorenzo@kernel.org>
-In-Reply-To: <e5ecb4f619197b93fa682d722452dc8412864cdb.1662886033.git.lorenzo@kernel.org>
-References: <e5ecb4f619197b93fa682d722452dc8412864cdb.1662886033.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 27 Aug 2022 16:15:14 +0200
-Subject: [PATCH net-next 2/5] net: ethernet: mtk_eth_wed: add wed support for
- mt7986 chipset
-
-Introduce Wireless Etherne Dispatcher support on transmission side
-for mt7986 chipset
-
-Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +-
- drivers/net/ethernet/mediatek/mtk_wed.c | 371 ++++++++++++++----
- drivers/net/ethernet/mediatek/mtk_wed.h | 8 +-
- .../net/ethernet/mediatek/mtk_wed_debugfs.c | 3 +
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 81 +++-
- include/linux/soc/mediatek/mtk_wed.h | 8 +
- 6 files changed, 408 insertions(+), 97 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3890,6 +3890,7 @@ void mtk_eth_set_dma_device(struct mtk_e
-
- static int mtk_probe(struct platform_device *pdev)
- {
-+ struct resource *res = NULL;
- struct device_node *mac_np;
- struct mtk_eth *eth;
- int err, i;
-@@ -3970,16 +3971,31 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-- for (i = 0;; i++) {
-- struct device_node *np = of_parse_phandle(pdev->dev.of_node,
-- "mediatek,wed", i);
-- void __iomem *wdma;
--
-- if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base))
-- break;
--
-- wdma = eth->base + eth->soc->reg_map->wdma_base[i];
-- mtk_wed_add_hw(np, eth, wdma, i);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res)
-+ return -EINVAL;
-+ }
-+
-+ if (eth->soc->offload_version) {
-+ for (i = 0;; i++) {
-+ struct device_node *np;
-+ phys_addr_t wdma_phy;
-+ u32 wdma_base;
-+
-+ if (i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base))
-+ break;
-+
-+ np = of_parse_phandle(pdev->dev.of_node,
-+ "mediatek,wed", i);
-+ if (!np)
-+ break;
-+
-+ wdma_base = eth->soc->reg_map->wdma_base[i];
-+ wdma_phy = res ? res->start + wdma_base : 0;
-+ mtk_wed_add_hw(np, eth, eth->base + wdma_base,
-+ wdma_phy, i);
-+ }
- }
-
- for (i = 0; i < 3; i++) {
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -25,6 +25,11 @@
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 1024
-+#define MTK_WED_MAX_GROUP_SIZE 0x100
-+#define MTK_WED_VLD_GROUP_SIZE 0x40
-+#define MTK_WED_PER_GROUP_PKT 128
-+
-+#define MTK_WED_FBUF_SIZE 128
-
- static struct mtk_wed_hw *hw_list[2];
- static DEFINE_MUTEX(hw_lock);
-@@ -150,10 +155,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi
-
- desc->buf0 = cpu_to_le32(buf_phys);
- desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-- MTK_WED_BUF_SIZE - txd_size) |
-- MTK_WDMA_DESC_CTRL_LAST_SEG1;
-+
-+ if (dev->hw->version == 1)
-+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-+ MTK_WED_BUF_SIZE - txd_size) |
-+ MTK_WDMA_DESC_CTRL_LAST_SEG1;
-+ else
-+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2,
-+ MTK_WED_BUF_SIZE - txd_size) |
-+ MTK_WDMA_DESC_CTRL_LAST_SEG0;
- desc->ctrl = cpu_to_le32(ctrl);
- desc->info = 0;
- desc++;
-@@ -209,7 +221,7 @@ mtk_wed_free_ring(struct mtk_wed_device
- if (!ring->desc)
- return;
-
-- dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc),
-+ dma_free_coherent(dev->hw->dev, ring->size * ring->desc_size,
- ring->desc, ring->desc_phys);
- }
-
-@@ -229,6 +241,14 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- {
- u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-+ if (dev->hw->version == 1)
-+ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
-+ else
-+ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-+ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH |
-+ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-+ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
-+
- if (!dev->hw->num_flows)
- mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-
-@@ -237,6 +257,20 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- }
-
- static void
-+mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable)
-+{
-+ if (enable) {
-+ wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
-+ wed_w32(dev, MTK_WED_TXP_DW1,
-+ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0103));
-+ } else {
-+ wed_w32(dev, MTK_WED_TXP_DW1,
-+ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0100));
-+ wed_clr(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
-+ }
-+}
-+
-+static void
- mtk_wed_dma_disable(struct mtk_wed_device *dev)
- {
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-@@ -249,12 +283,22 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WED_GLO_CFG_TX_DMA_EN |
- MTK_WED_GLO_CFG_RX_DMA_EN);
-
-- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
- wdma_m32(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_TX_DMA_EN |
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0);
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0);
-+
-+ if (dev->hw->version == 1) {
-+ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
-+ wdma_m32(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0);
-+ } else {
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-+
-+ mtk_wed_set_512_support(dev, false);
-+ }
- }
-
- static void
-@@ -293,7 +337,7 @@ mtk_wed_detach(struct mtk_wed_device *de
- mtk_wed_free_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-
-- if (of_dma_is_coherent(wlan_node))
-+ if (of_dma_is_coherent(wlan_node) && hw->hifsys)
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), BIT(hw->index));
-
-@@ -308,14 +352,69 @@ mtk_wed_detach(struct mtk_wed_device *de
- mutex_unlock(&hw_lock);
- }
-
-+#define PCIE_BASE_ADDR0 0x11280000
-+static void
-+mtk_wed_bus_init(struct mtk_wed_device *dev)
-+{
-+ struct device_node *np = dev->hw->eth->dev->of_node;
-+ struct regmap *regs;
-+ u32 val;
-+
-+ regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie");
-+ if (IS_ERR(regs))
-+ return;
-+
-+ regmap_update_bits(regs, 0, BIT(0), BIT(0));
-+
-+ wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
-+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
-+
-+ /* pcie interrupt control: pola/source selection */
-+ wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
-+ wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
-+
-+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
-+
-+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
-+
-+ /* pcie interrupt status trigger register */
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-+ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
-+
-+ /* pola setting */
-+ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
-+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-+}
-+
-+static void
-+mtk_wed_set_wpdma(struct mtk_wed_device *dev)
-+{
-+ if (dev->hw->version == 1) {
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
-+ } else {
-+ mtk_wed_bus_init(dev);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-+ }
-+}
-+
- static void
- mtk_wed_hw_init_early(struct mtk_wed_device *dev)
- {
- u32 mask, set;
-- u32 offset;
-
- mtk_wed_stop(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+ mtk_wed_set_wpdma(dev);
-
- mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
- MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-@@ -325,17 +424,33 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
- wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-
-- wdma_set(dev, MTK_WDMA_GLO_CFG,
-- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
--
-- offset = dev->hw->index ? 0x04000400 : 0;
-- wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
-- wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset);
-+ if (dev->hw->version == 1) {
-+ u32 offset = dev->hw->index ? 0x04000400 : 0;
-
-- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, MTK_PCIE_BASE(dev->hw->index));
-- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
-+ wdma_set(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-+
-+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
-+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE,
-+ MTK_PCIE_BASE(dev->hw->index));
-+ } else {
-+ wed_w32(dev, MTK_WED_WDMA_CFG_BASE, dev->hw->wdma_phy);
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_ETH_DMAD_FMT);
-+ wed_w32(dev, MTK_WED_WDMA_OFFSET0,
-+ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_INTS,
-+ MTK_WDMA_INT_STATUS) |
-+ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_CFG,
-+ MTK_WDMA_GLO_CFG));
-+
-+ wed_w32(dev, MTK_WED_WDMA_OFFSET1,
-+ FIELD_PREP(MTK_WED_WDMA_OFST1_TX_CTRL,
-+ MTK_WDMA_RING_TX(0)) |
-+ FIELD_PREP(MTK_WED_WDMA_OFST1_RX_CTRL,
-+ MTK_WDMA_RING_RX(0)));
-+ }
- }
-
- static void
-@@ -355,37 +470,65 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
-
-- wed_w32(dev, MTK_WED_TX_BM_TKID,
-- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-- dev->wlan.token_start) |
-- FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-- dev->wlan.token_start + dev->wlan.nbuf - 1));
--
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
-- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
-- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
-- MTK_WED_TX_BM_DYN_THR_HI);
-+ if (dev->hw->version == 1) {
-+ wed_w32(dev, MTK_WED_TX_BM_TKID,
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-+ dev->wlan.token_start) |
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-+ dev->wlan.token_start +
-+ dev->wlan.nbuf - 1));
-+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
-+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
-+ MTK_WED_TX_BM_DYN_THR_HI);
-+ } else {
-+ wed_w32(dev, MTK_WED_TX_BM_TKID_V2,
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-+ dev->wlan.token_start) |
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-+ dev->wlan.token_start +
-+ dev->wlan.nbuf - 1));
-+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
-+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) |
-+ MTK_WED_TX_BM_DYN_THR_HI_V2);
-+ wed_w32(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM,
-+ dev->buf_ring.size / 128) |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
-+ dev->buf_ring.size / 128));
-+ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
-+ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
-+ MTK_WED_TX_TKID_DYN_THR_HI);
-+ }
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-- wed_set(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WED_TX_BM_EN |
-- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+ if (dev->hw->version == 1)
-+ wed_set(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_TX_BM_EN |
-+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+ else
-+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
-
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
- }
-
- static void
--mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size)
-+mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size)
- {
-+ void *head = (void *)ring->desc;
- int i;
-
- for (i = 0; i < size; i++) {
-- desc[i].buf0 = 0;
-- desc[i].ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-- desc[i].buf1 = 0;
-- desc[i].info = 0;
-+ struct mtk_wdma_desc *desc;
-+
-+ desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size);
-+ desc->buf0 = 0;
-+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ desc->buf1 = 0;
-+ desc->info = 0;
- }
- }
-
-@@ -436,12 +579,10 @@ mtk_wed_reset_dma(struct mtk_wed_device
- int i;
-
- for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) {
-- struct mtk_wdma_desc *desc = dev->tx_ring[i].desc;
--
-- if (!desc)
-+ if (!dev->tx_ring[i].desc)
- continue;
-
-- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE);
-+ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE);
- }
-
- if (mtk_wed_poll_busy(dev))
-@@ -498,16 +639,16 @@ mtk_wed_reset_dma(struct mtk_wed_device
-
- static int
- mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-- int size)
-+ int size, u32 desc_size)
- {
-- ring->desc = dma_alloc_coherent(dev->hw->dev,
-- size * sizeof(*ring->desc),
-+ ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size,
- &ring->desc_phys, GFP_KERNEL);
- if (!ring->desc)
- return -ENOMEM;
-
-+ ring->desc_size = desc_size;
- ring->size = size;
-- mtk_wed_ring_reset(ring->desc, size);
-+ mtk_wed_ring_reset(ring, size);
-
- return 0;
- }
-@@ -515,9 +656,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device
- static int
- mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
- {
-+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
-
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -546,16 +688,41 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
-- MTK_WED_PCIE_INT_TRIGGER_STATUS);
-+ if (dev->hw->version == 1) {
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
-+ MTK_WED_PCIE_INT_TRIGGER_STATUS);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER,
-+ MTK_WED_WPDMA_INT_TRIGGER_RX_DONE |
-+ MTK_WED_WPDMA_INT_TRIGGER_TX_DONE);
-
-- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER,
-- MTK_WED_WPDMA_INT_TRIGGER_RX_DONE |
-- MTK_WED_WPDMA_INT_TRIGGER_TX_DONE);
-+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
-+ } else {
-+ /* initail tx interrupt trigger */
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
-+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN |
-+ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG,
-+ dev->wlan.tx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG,
-+ dev->wlan.tx_tbit[1]));
-+
-+ /* initail txfree interrupt trigger */
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX_FREE,
-+ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN |
-+ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
-+ dev->wlan.txfree_tbit));
-+
-+ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
-+ wed_set(dev, MTK_WED_WDMA_INT_CTRL,
-+ FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL,
-+ dev->wdma_idx));
-+ }
-
-- /* initail wdma interrupt agent */
- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
-- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
-
- wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask);
- wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask);
-@@ -580,14 +747,28 @@ mtk_wed_dma_enable(struct mtk_wed_device
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_TX_DMA_EN |
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-+
-+ if (dev->hw->version == 1) {
-+ wdma_set(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-+ } else {
-+ wed_set(dev, MTK_WED_WPDMA_CTRL,
-+ MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-+
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-+
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
-+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-+ }
- }
-
- static void
- mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
- {
-- u32 val;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-@@ -598,14 +779,17 @@ mtk_wed_start(struct mtk_wed_device *dev
- mtk_wed_configure_irq(dev, irq_mask);
-
- mtk_wed_set_ext_int(dev, true);
-- val = dev->wlan.wpdma_phys |
-- MTK_PCIE_MIRROR_MAP_EN |
-- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index);
--
-- if (dev->hw->index)
-- val |= BIT(1);
-- val |= BIT(0);
-- regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
-+
-+ if (dev->hw->version == 1) {
-+ u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN |
-+ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID,
-+ dev->hw->index);
-+
-+ val |= BIT(0) | (BIT(1) * !!dev->hw->index);
-+ regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
-+ } else {
-+ mtk_wed_set_512_support(dev, true);
-+ }
-
- mtk_wed_dma_enable(dev);
- dev->running = true;
-@@ -639,7 +823,9 @@ mtk_wed_attach(struct mtk_wed_device *de
- goto out;
- }
-
-- dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index);
-+ dev_info(&dev->wlan.pci_dev->dev,
-+ "attaching wed device %d version %d\n",
-+ hw->index, hw->version);
-
- dev->hw = hw;
- dev->dev = hw->dev;
-@@ -657,7 +843,9 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0);
-+ if (hw->hifsys)
-+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
-+ BIT(hw->index), 0);
-
- out:
- mutex_unlock(&hw_lock);
-@@ -684,7 +872,8 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
-
- BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring));
-
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE))
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-+ sizeof(*ring->desc)))
- return -ENOMEM;
-
- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-@@ -711,21 +900,21 @@ static int
- mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
- {
- struct mtk_wed_ring *ring = &dev->txfree_ring;
-- int i;
-+ int i, index = dev->hw->version == 1;
-
- /*
- * For txfree event handling, the same DMA ring is shared between WED
- * and WLAN. The WLAN driver accesses the ring index registers through
- * WED
- */
-- ring->reg_base = MTK_WED_RING_RX(1);
-+ ring->reg_base = MTK_WED_RING_RX(index);
- ring->wpdma = regs;
-
- for (i = 0; i < 12; i += 4) {
- u32 val = readl(regs + i);
-
-- wed_w32(dev, MTK_WED_RING_RX(1) + i, val);
-- wed_w32(dev, MTK_WED_WPDMA_RING_RX(1) + i, val);
-+ wed_w32(dev, MTK_WED_RING_RX(index) + i, val);
-+ wed_w32(dev, MTK_WED_WPDMA_RING_RX(index) + i, val);
- }
-
- return 0;
-@@ -734,11 +923,19 @@ mtk_wed_txfree_ring_setup(struct mtk_wed
- static u32
- mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
- {
-- u32 val;
-+ u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-+
-+ if (dev->hw->version == 1)
-+ ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
-+ else
-+ ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-+ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH |
-+ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-+ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
-
- val = wed_r32(dev, MTK_WED_EXT_INT_STATUS);
- wed_w32(dev, MTK_WED_EXT_INT_STATUS, val);
-- val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-+ val &= ext_mask;
- if (!dev->hw->num_flows)
- val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
- if (val && net_ratelimit())
-@@ -813,7 +1010,8 @@ out:
- }
-
- void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-- void __iomem *wdma, int index)
-+ void __iomem *wdma, phys_addr_t wdma_phy,
-+ int index)
- {
- static const struct mtk_wed_ops wed_ops = {
- .attach = mtk_wed_attach,
-@@ -860,26 +1058,33 @@ void mtk_wed_add_hw(struct device_node *
- hw = kzalloc(sizeof(*hw), GFP_KERNEL);
- if (!hw)
- goto unlock;
-+
- hw->node = np;
- hw->regs = regs;
- hw->eth = eth;
- hw->dev = &pdev->dev;
-+ hw->wdma_phy = wdma_phy;
- hw->wdma = wdma;
- hw->index = index;
- hw->irq = irq;
-- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
-- "mediatek,pcie-mirror");
-- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
-- "mediatek,hifsys");
-- if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) {
-- kfree(hw);
-- goto unlock;
-- }
-+ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
-
-- if (!index) {
-- regmap_write(hw->mirror, 0, 0);
-- regmap_write(hw->mirror, 4, 0);
-+ if (hw->version == 1) {
-+ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
-+ "mediatek,pcie-mirror");
-+ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
-+ "mediatek,hifsys");
-+ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) {
-+ kfree(hw);
-+ goto unlock;
-+ }
-+
-+ if (!index) {
-+ regmap_write(hw->mirror, 0, 0);
-+ regmap_write(hw->mirror, 4, 0);
-+ }
- }
-+
- mtk_wed_hw_add_debugfs(hw);
-
- hw_list[index] = hw;
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -18,11 +18,13 @@ struct mtk_wed_hw {
- struct regmap *hifsys;
- struct device *dev;
- void __iomem *wdma;
-+ phys_addr_t wdma_phy;
- struct regmap *mirror;
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
- u32 debugfs_reg;
- u32 num_flows;
-+ u8 version;
- char dirname[5];
- int irq;
- int index;
-@@ -101,14 +103,16 @@ wpdma_txfree_w32(struct mtk_wed_device *
- }
-
- void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-- void __iomem *wdma, int index);
-+ void __iomem *wdma, phys_addr_t wdma_phy,
-+ int index);
- void mtk_wed_exit(void);
- int mtk_wed_flow_add(int index);
- void mtk_wed_flow_remove(int index);
- #else
- static inline void
- mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-- void __iomem *wdma, int index)
-+ void __iomem *wdma, phys_addr_t wdma_phy,
-+ int index)
- {
- }
- static inline void
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -116,6 +116,9 @@ wed_txinfo_show(struct seq_file *s, void
- DUMP_WDMA(WDMA_GLO_CFG),
- DUMP_WDMA_RING(WDMA_RING_RX(0)),
- DUMP_WDMA_RING(WDMA_RING_RX(1)),
-+
-+ DUMP_STR("TX FREE"),
-+ DUMP_WED(WED_RX_MIB(0)),
- };
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -5,6 +5,7 @@
- #define __MTK_WED_REGS_H
-
- #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0)
-+#define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0)
- #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15)
- #define MTK_WDMA_DESC_CTRL_BURST BIT(16)
- #define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16)
-@@ -41,6 +42,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_RESERVE_EN BIT(12)
- #define MTK_WED_CTRL_RESERVE_BUSY BIT(13)
- #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
-+#define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25)
- #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
-
- #define MTK_WED_EXT_INT_STATUS 0x020
-@@ -57,7 +59,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN BIT(19)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_BM_DMAD_COHERENT BIT(20)
- #define MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR BIT(21)
--#define MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR BIT(22)
-+#define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22)
-+#define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24)
- #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
- MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
-@@ -65,8 +68,7 @@ struct mtk_wdma_desc {
- MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \
- MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \
- MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \
-- MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR | \
-- MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR)
-+ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR)
-
- #define MTK_WED_EXT_INT_MASK 0x028
-
-@@ -81,6 +83,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_BM_BASE 0x084
-
- #define MTK_WED_TX_BM_TKID 0x088
-+#define MTK_WED_TX_BM_TKID_V2 0x0c8
- #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
- #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-
-@@ -94,7 +97,25 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_TX_BM_DYN_THR 0x0a0
- #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0)
-+#define MTK_WED_TX_BM_DYN_THR_LO_V2 GENMASK(8, 0)
- #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16)
-+#define MTK_WED_TX_BM_DYN_THR_HI_V2 GENMASK(24, 16)
-+
-+#define MTK_WED_TX_TKID_CTRL 0x0c0
-+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(6, 0)
-+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-+#define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
-+
-+#define MTK_WED_TX_TKID_DYN_THR 0x0e0
-+#define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0)
-+#define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16)
-+
-+#define MTK_WED_TXP_DW0 0x120
-+#define MTK_WED_TXP_DW1 0x124
-+#define MTK_WED_WPDMA_WRITE_TXP GENMASK(31, 16)
-+#define MTK_WED_TXDP_CTRL 0x130
-+#define MTK_WED_TXDP_DW9_OVERWR BIT(9)
-+#define MTK_WED_RX_BM_TKID_MIB 0x1cc
-
- #define MTK_WED_INT_STATUS 0x200
- #define MTK_WED_INT_MASK 0x204
-@@ -125,6 +146,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
-
- #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
-+#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4)
-
- #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10)
-
-@@ -155,21 +177,62 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_GLO_CFG_BYTE_SWAP BIT(29)
- #define MTK_WED_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31)
-
-+/* CONFIG_MEDIATEK_NETSYS_V2 */
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC BIT(4)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28)
-+
- #define MTK_WED_WPDMA_RESET_IDX 0x50c
- #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0)
- #define MTK_WED_WPDMA_RESET_IDX_RX GENMASK(17, 16)
-
-+#define MTK_WED_WPDMA_CTRL 0x518
-+#define MTK_WED_WPDMA_CTRL_SDL1_FIXED BIT(31)
-+
- #define MTK_WED_WPDMA_INT_CTRL 0x520
- #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21)
-
- #define MTK_WED_WPDMA_INT_MASK 0x524
-
-+#define MTK_WED_WPDMA_INT_CTRL_TX 0x530
-+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10)
-+
-+#define MTK_WED_WPDMA_INT_CTRL_RX 0x534
-+
-+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538
-+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG GENMASK(6, 2)
-+
- #define MTK_WED_PCIE_CFG_BASE 0x560
-
-+#define MTK_WED_PCIE_CFG_BASE 0x560
-+#define MTK_WED_PCIE_CFG_INTM 0x564
-+#define MTK_WED_PCIE_CFG_MSIS 0x568
- #define MTK_WED_PCIE_INT_TRIGGER 0x570
- #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16)
-
-+#define MTK_WED_PCIE_INT_CTRL 0x57c
-+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
-+#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
-+#define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12)
-+
- #define MTK_WED_WPDMA_CFG_BASE 0x580
-+#define MTK_WED_WPDMA_CFG_INT_MASK 0x584
-+#define MTK_WED_WPDMA_CFG_TX 0x588
-+#define MTK_WED_WPDMA_CFG_TX_FREE 0x58c
-
- #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4)
- #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4)
-@@ -203,15 +266,24 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
- #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
-
-+#define MTK_WED_WDMA_INT_CLR 0xa24
-+#define MTK_WED_WDMA_INT_CLR_RX_DONE GENMASK(17, 16)
-+
- #define MTK_WED_WDMA_INT_TRIGGER 0xa28
- #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16)
-
- #define MTK_WED_WDMA_INT_CTRL 0xa2c
- #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16)
-
-+#define MTK_WED_WDMA_CFG_BASE 0xaa0
- #define MTK_WED_WDMA_OFFSET0 0xaa4
- #define MTK_WED_WDMA_OFFSET1 0xaa8
-
-+#define MTK_WED_WDMA_OFST0_GLO_INTS GENMASK(15, 0)
-+#define MTK_WED_WDMA_OFST0_GLO_CFG GENMASK(31, 16)
-+#define MTK_WED_WDMA_OFST1_TX_CTRL GENMASK(15, 0)
-+#define MTK_WED_WDMA_OFST1_RX_CTRL GENMASK(31, 16)
-+
- #define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4)
- #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4)
- #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4)
-@@ -221,6 +293,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RING_OFS_CPU_IDX 0x08
- #define MTK_WED_RING_OFS_DMA_IDX 0x0c
-
-+#define MTK_WDMA_RING_TX(_n) (0x000 + (_n) * 0x10)
- #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10)
-
- #define MTK_WDMA_GLO_CFG 0x204
-@@ -234,6 +307,8 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0)
- #define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16)
-
-+#define MTK_WDMA_INT_STATUS 0x220
-+
- #define MTK_WDMA_INT_MASK 0x228
- #define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0)
- #define MTK_WDMA_INT_MASK_RX_DONE GENMASK(17, 16)
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -14,6 +14,7 @@ struct mtk_wdma_desc;
- struct mtk_wed_ring {
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-+ u32 desc_size;
- int size;
-
- u32 reg_base;
-@@ -45,10 +46,17 @@ struct mtk_wed_device {
- struct pci_dev *pci_dev;
-
- u32 wpdma_phys;
-+ u32 wpdma_int;
-+ u32 wpdma_mask;
-+ u32 wpdma_tx;
-+ u32 wpdma_txfree;
-
- u16 token_start;
- unsigned int nbuf;
-
-+ u8 tx_tbit[MTK_WED_TX_QUEUES];
-+ u8 txfree_tbit;
-+
- u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
- int (*offload_enable)(struct mtk_wed_device *wed);
- void (*offload_disable)(struct mtk_wed_device *wed);
diff --git a/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch b/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch
deleted file mode 100644
index f4b78a2798..0000000000
--- a/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-From 6e1df49f330dce7c58a39d6772f1385b6887bb03 Mon Sep 17 00:00:00 2001
-Message-Id: <6e1df49f330dce7c58a39d6772f1385b6887bb03.1662990860.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 8 Sep 2022 11:26:10 +0200
-Subject: [PATCH net-next] net: ethernet: mtk_eth_wed: add axi bus support
-
-Other than pcie bus, introduce support for axi bus to mtk wed driver.
-Axi bus is used to connect mt7986-wmac soc chip available on mt7986
-device.
-
-Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 116 +++++++++++++------
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 2 +
- include/linux/soc/mediatek/mtk_wed.h | 11 +-
- 3 files changed, 91 insertions(+), 38 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -85,11 +85,31 @@ static struct mtk_wed_hw *
- mtk_wed_assign(struct mtk_wed_device *dev)
- {
- struct mtk_wed_hw *hw;
-+ int i;
-+
-+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
-+ hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)];
-+ if (!hw)
-+ return NULL;
-+
-+ if (!hw->wed_dev)
-+ goto out;
-+
-+ if (hw->version == 1)
-+ return NULL;
-+
-+ /* MT7986 WED devices do not have any pcie slot restrictions */
-+ }
-+ /* MT7986 PCIE or AXI */
-+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
-+ hw = hw_list[i];
-+ if (hw && !hw->wed_dev)
-+ goto out;
-+ }
-
-- hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)];
-- if (!hw || hw->wed_dev)
-- return NULL;
-+ return NULL;
-
-+out:
- hw->wed_dev = dev;
- return hw;
- }
-@@ -322,7 +342,6 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- static void
- mtk_wed_detach(struct mtk_wed_device *dev)
- {
-- struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node;
- struct mtk_wed_hw *hw = dev->hw;
-
- mutex_lock(&hw_lock);
-@@ -337,9 +356,14 @@ mtk_wed_detach(struct mtk_wed_device *de
- mtk_wed_free_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-
-- if (of_dma_is_coherent(wlan_node) && hw->hifsys)
-- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
-- BIT(hw->index), BIT(hw->index));
-+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
-+ struct device_node *wlan_node;
-+
-+ wlan_node = dev->wlan.pci_dev->dev.of_node;
-+ if (of_dma_is_coherent(wlan_node) && hw->hifsys)
-+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
-+ BIT(hw->index), BIT(hw->index));
-+ }
-
- if (!hw_list[!hw->index]->wed_dev &&
- hw->eth->dma_dev != hw->eth->dev)
-@@ -356,40 +380,47 @@ mtk_wed_detach(struct mtk_wed_device *de
- static void
- mtk_wed_bus_init(struct mtk_wed_device *dev)
- {
-- struct device_node *np = dev->hw->eth->dev->of_node;
-- struct regmap *regs;
-- u32 val;
--
-- regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie");
-- if (IS_ERR(regs))
-- return;
-+ switch (dev->wlan.bus_type) {
-+ case MTK_WED_BUS_PCIE: {
-+ struct device_node *np = dev->hw->eth->dev->of_node;
-+ struct regmap *regs;
-+
-+ regs = syscon_regmap_lookup_by_phandle(np,
-+ "mediatek,wed-pcie");
-+ if (IS_ERR(regs))
-+ break;
-
-- regmap_update_bits(regs, 0, BIT(0), BIT(0));
-+ regmap_update_bits(regs, 0, BIT(0), BIT(0));
-
-- wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
-- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
-+ wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
-+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
-
-- /* pcie interrupt control: pola/source selection */
-- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
-- wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
--
-- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
-- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
-- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
--
-- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
--
-- /* pcie interrupt status trigger register */
-- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
--
-- /* pola setting */
-- val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
-- wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-+ /* pcie interrupt control: pola/source selection */
-+ wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
-+ wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
-+
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
-+
-+ /* pcie interrupt status trigger register */
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-+ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
-+
-+ /* pola setting */
-+ wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-+ break;
-+ }
-+ case MTK_WED_BUS_AXI:
-+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
-+ MTK_WED_WPDMA_INT_CTRL_SIG_SRC |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0));
-+ break;
-+ default:
-+ break;
-+ }
- }
-
- static void
-@@ -800,12 +831,14 @@ mtk_wed_attach(struct mtk_wed_device *de
- __releases(RCU)
- {
- struct mtk_wed_hw *hw;
-+ struct device *device;
- int ret = 0;
-
- RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
- "mtk_wed_attach without holding the RCU read lock");
-
-- if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 ||
-+ if ((dev->wlan.bus_type == MTK_WED_BUS_PCIE &&
-+ pci_domain_nr(dev->wlan.pci_dev->bus) > 1) ||
- !try_module_get(THIS_MODULE))
- ret = -ENODEV;
-
-@@ -823,8 +856,10 @@ mtk_wed_attach(struct mtk_wed_device *de
- goto out;
- }
-
-- dev_info(&dev->wlan.pci_dev->dev,
-- "attaching wed device %d version %d\n",
-+ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE
-+ ? &dev->wlan.pci_dev->dev
-+ : &dev->wlan.platform_dev->dev;
-+ dev_info(device, "attaching wed device %d version %d\n",
- hw->index, hw->version);
-
- dev->hw = hw;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -198,6 +198,8 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_INT_CTRL 0x520
- #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21)
-+#define MTK_WED_WPDMA_INT_CTRL_SIG_SRC BIT(22)
-+#define MTK_WED_WPDMA_INT_CTRL_SRC_SEL GENMASK(17, 16)
-
- #define MTK_WED_WPDMA_INT_MASK 0x524
-
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -11,6 +11,11 @@
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-
-+enum mtk_wed_bus_tye {
-+ MTK_WED_BUS_PCIE,
-+ MTK_WED_BUS_AXI,
-+};
-+
- struct mtk_wed_ring {
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-@@ -43,7 +48,11 @@ struct mtk_wed_device {
-
- /* filled by driver: */
- struct {
-- struct pci_dev *pci_dev;
-+ union {
-+ struct platform_device *platform_dev;
-+ struct pci_dev *pci_dev;
-+ };
-+ enum mtk_wed_bus_tye bus_type;
-
- u32 wpdma_phys;
- u32 wpdma_int;
diff --git a/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch b/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch
deleted file mode 100644
index 56d63b1e35..0000000000
--- a/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch
+++ /dev/null
@@ -1,882 +0,0 @@
-From 93408c858e5dc01d97c55efa721268f63fde2ae5 Mon Sep 17 00:00:00 2001
-Message-Id: <93408c858e5dc01d97c55efa721268f63fde2ae5.1662886034.git.lorenzo@kernel.org>
-In-Reply-To: <e5ecb4f619197b93fa682d722452dc8412864cdb.1662886033.git.lorenzo@kernel.org>
-References: <e5ecb4f619197b93fa682d722452dc8412864cdb.1662886033.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 3 Sep 2022 18:34:09 +0200
-Subject: [PATCH net-next 4/5] net: ethernet: mtk_eth_soc: introduce flow
- offloading support for mt7986
-
-Introduce hw flow offload support for mt7986 chipset. PPE is not enabled
-yet in mt7986 since mt76 support is not available yet.
-
-Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 72 ++++++
- drivers/net/ethernet/mediatek/mtk_ppe.c | 213 +++++++++++-------
- drivers/net/ethernet/mediatek/mtk_ppe.h | 52 ++++-
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 49 ++--
- drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 8 +
- 6 files changed, 289 insertions(+), 116 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1858,12 +1858,14 @@ static int mtk_poll_rx(struct napi_struc
- bytes += skb->len;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
- hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
- if (hash != MTK_RXD5_FOE_ENTRY)
- skb_set_hash(skb, jhash_1word(hash, 0),
- PKT_HASH_TYPE_L4);
- rxdcsum = &trxd.rxd3;
- } else {
-+ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
- hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY;
- if (hash != MTK_RXD4_FOE_ENTRY)
- skb_set_hash(skb, jhash_1word(hash, 0),
-@@ -1877,7 +1879,6 @@ static int mtk_poll_rx(struct napi_struc
- skb_checksum_none_assert(skb);
- skb->protocol = eth_type_trans(skb, netdev);
-
-- reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
- mtk_ppe_check_skb(eth->ppe[0], skb, hash);
-
-@@ -4179,7 +4180,7 @@ static const struct mtk_soc_data mt7621_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 2,
-- .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4199,7 +4200,7 @@ static const struct mtk_soc_data mt7622_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 2,
-- .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4218,7 +4219,7 @@ static const struct mtk_soc_data mt7623_
- .required_pctl = true,
- .offload_version = 2,
- .hash_offset = 2,
-- .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4250,9 +4251,11 @@ static const struct mtk_soc_data mt7986_
- .reg_map = &mt7986_reg_map,
- .ana_rgc3 = 0x128,
- .caps = MT7986_CAPS,
-+ .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7986_CLKS_BITMAP,
- .required_pctl = false,
- .hash_offset = 4,
-+ .foe_entry_size = sizeof(struct mtk_foe_entry),
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1151,6 +1151,78 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u
- return ppe->foe_table + hash * soc->foe_entry_size;
- }
-
-+static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-+
-+ return MTK_FOE_IB1_BIND_TIMESTAMP;
-+}
-+
-+static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return MTK_FOE_IB1_BIND_PPPOE_V2;
-+
-+ return MTK_FOE_IB1_BIND_PPPOE;
-+}
-+
-+static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return MTK_FOE_IB1_BIND_VLAN_TAG_V2;
-+
-+ return MTK_FOE_IB1_BIND_VLAN_TAG;
-+}
-+
-+static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return MTK_FOE_IB1_BIND_VLAN_LAYER_V2;
-+
-+ return MTK_FOE_IB1_BIND_VLAN_LAYER;
-+}
-+
-+static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
-+
-+ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
-+}
-+
-+static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
-+
-+ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
-+}
-+
-+static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return MTK_FOE_IB1_PACKET_TYPE_V2;
-+
-+ return MTK_FOE_IB1_PACKET_TYPE;
-+}
-+
-+static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val);
-+
-+ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val);
-+}
-+
-+static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
-+{
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return MTK_FOE_IB2_MULTICAST_V2;
-+
-+ return MTK_FOE_IB2_MULTICAST;
-+}
-+
- /* read the hardware status register */
- void mtk_stats_update_mac(struct mtk_mac *mac);
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -56,7 +56,7 @@ static u32 ppe_clear(struct mtk_ppe *ppe
-
- static u32 mtk_eth_timestamp(struct mtk_eth *eth)
- {
-- return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP;
-+ return mtk_r32(eth, 0x0010) & mtk_get_ib1_ts_mask(eth);
- }
-
- static int mtk_ppe_wait_busy(struct mtk_ppe *ppe)
-@@ -93,7 +93,7 @@ static u32 mtk_ppe_hash_entry(struct mtk
- u32 hv1, hv2, hv3;
- u32 hash;
-
-- switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) {
-+ switch (mtk_get_ib1_pkt_type(eth, e->ib1)) {
- case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
- case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
- hv1 = e->ipv4.orig.ports;
-@@ -129,9 +129,9 @@ static u32 mtk_ppe_hash_entry(struct mtk
- }
-
- static inline struct mtk_foe_mac_info *
--mtk_foe_entry_l2(struct mtk_foe_entry *entry)
-+mtk_foe_entry_l2(struct mtk_eth *eth, struct mtk_foe_entry *entry)
- {
-- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1);
-
- if (type == MTK_PPE_PKT_TYPE_BRIDGE)
- return &entry->bridge.l2;
-@@ -143,9 +143,9 @@ mtk_foe_entry_l2(struct mtk_foe_entry *e
- }
-
- static inline u32 *
--mtk_foe_entry_ib2(struct mtk_foe_entry *entry)
-+mtk_foe_entry_ib2(struct mtk_eth *eth, struct mtk_foe_entry *entry)
- {
-- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1);
-
- if (type == MTK_PPE_PKT_TYPE_BRIDGE)
- return &entry->bridge.ib2;
-@@ -156,27 +156,38 @@ mtk_foe_entry_ib2(struct mtk_foe_entry *
- return &entry->ipv4.ib2;
- }
-
--int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto,
-- u8 pse_port, u8 *src_mac, u8 *dest_mac)
-+int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int type, int l4proto, u8 pse_port, u8 *src_mac,
-+ u8 *dest_mac)
- {
- struct mtk_foe_mac_info *l2;
- u32 ports_pad, val;
-
- memset(entry, 0, sizeof(*entry));
-
-- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
-- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) |
-- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
-- MTK_FOE_IB1_BIND_TTL |
-- MTK_FOE_IB1_BIND_CACHE;
-- entry->ib1 = val;
--
-- val = FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) |
-- FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f) |
-- FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
-+ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) |
-+ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
-+ MTK_FOE_IB1_BIND_CACHE_V2 | MTK_FOE_IB1_BIND_TTL_V2;
-+ entry->ib1 = val;
-+
-+ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) |
-+ FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf);
-+ } else {
-+ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
-+ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) |
-+ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
-+ MTK_FOE_IB1_BIND_CACHE | MTK_FOE_IB1_BIND_TTL;
-+ entry->ib1 = val;
-+
-+ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) |
-+ FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) |
-+ FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f);
-+ }
-
- if (is_multicast_ether_addr(dest_mac))
-- val |= MTK_FOE_IB2_MULTICAST;
-+ val |= mtk_get_ib2_multicast_mask(eth);
-
- ports_pad = 0xa5a5a500 | (l4proto & 0xff);
- if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE)
-@@ -210,24 +221,30 @@ int mtk_foe_entry_prepare(struct mtk_foe
- return 0;
- }
-
--int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port)
-+int mtk_foe_entry_set_pse_port(struct mtk_eth *eth,
-+ struct mtk_foe_entry *entry, u8 port)
- {
-- u32 *ib2 = mtk_foe_entry_ib2(entry);
-- u32 val;
-+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-+ u32 val = *ib2;
-
-- val = *ib2;
-- val &= ~MTK_FOE_IB2_DEST_PORT;
-- val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ val &= ~MTK_FOE_IB2_DEST_PORT_V2;
-+ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port);
-+ } else {
-+ val &= ~MTK_FOE_IB2_DEST_PORT;
-+ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port);
-+ }
- *ib2 = val;
-
- return 0;
- }
-
--int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool egress,
-+int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth,
-+ struct mtk_foe_entry *entry, bool egress,
- __be32 src_addr, __be16 src_port,
- __be32 dest_addr, __be16 dest_port)
- {
-- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1);
- struct mtk_ipv4_tuple *t;
-
- switch (type) {
-@@ -262,11 +279,12 @@ int mtk_foe_entry_set_ipv4_tuple(struct
- return 0;
- }
-
--int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry,
-+int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth,
-+ struct mtk_foe_entry *entry,
- __be32 *src_addr, __be16 src_port,
- __be32 *dest_addr, __be16 dest_port)
- {
-- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1);
- u32 *src, *dest;
- int i;
-
-@@ -297,39 +315,41 @@ int mtk_foe_entry_set_ipv6_tuple(struct
- return 0;
- }
-
--int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port)
-+int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int port)
- {
-- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
-+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
-
- l2->etype = BIT(port);
-
-- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER))
-- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1);
-+ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth)))
-+ entry->ib1 |= mtk_prep_ib1_vlan_layer(eth, 1);
- else
- l2->etype |= BIT(8);
-
-- entry->ib1 &= ~MTK_FOE_IB1_BIND_VLAN_TAG;
-+ entry->ib1 &= ~mtk_get_ib1_vlan_tag_mask(eth);
-
- return 0;
- }
-
--int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid)
-+int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int vid)
- {
-- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
-+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
-
-- switch (FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)) {
-+ switch (mtk_prep_ib1_vlan_layer(eth, entry->ib1)) {
- case 0:
-- entry->ib1 |= MTK_FOE_IB1_BIND_VLAN_TAG |
-- FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1);
-+ entry->ib1 |= mtk_get_ib1_vlan_tag_mask(eth) |
-+ mtk_prep_ib1_vlan_layer(eth, 1);
- l2->vlan1 = vid;
- return 0;
- case 1:
-- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) {
-+ if (!(entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) {
- l2->vlan1 = vid;
- l2->etype |= BIT(8);
- } else {
- l2->vlan2 = vid;
-- entry->ib1 += FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1);
-+ entry->ib1 += mtk_prep_ib1_vlan_layer(eth, 1);
- }
- return 0;
- default:
-@@ -337,34 +357,42 @@ int mtk_foe_entry_set_vlan(struct mtk_fo
- }
- }
-
--int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid)
-+int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int sid)
- {
-- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
-+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
-
-- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER) ||
-- (entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG))
-+ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth)) ||
-+ (entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth)))
- l2->etype = ETH_P_PPP_SES;
-
-- entry->ib1 |= MTK_FOE_IB1_BIND_PPPOE;
-+ entry->ib1 |= mtk_get_ib1_ppoe_mask(eth);
- l2->pppoe_id = sid;
-
- return 0;
- }
-
--int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
-- int bss, int wcid)
-+int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int wdma_idx, int txq, int bss, int wcid)
- {
-- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
-- u32 *ib2 = mtk_foe_entry_ib2(entry);
-+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
-+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-
-- *ib2 &= ~MTK_FOE_IB2_PORT_MG;
-- *ib2 |= MTK_FOE_IB2_WDMA_WINFO;
-- if (wdma_idx)
-- *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX;
--
-- l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
-- FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
-- FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
-+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
-+ MTK_FOE_IB2_WDMA_WINFO_V2;
-+ l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
-+ FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
-+ } else {
-+ *ib2 &= ~MTK_FOE_IB2_PORT_MG;
-+ *ib2 |= MTK_FOE_IB2_WDMA_WINFO;
-+ if (wdma_idx)
-+ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX;
-+ l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
-+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
-+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
-+ }
-
- return 0;
- }
-@@ -376,14 +404,15 @@ static inline bool mtk_foe_entry_usable(
- }
-
- static bool
--mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data)
-+mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry,
-+ struct mtk_foe_entry *data)
- {
- int type, len;
-
- if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP)
- return false;
-
-- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1);
-+ type = mtk_get_ib1_pkt_type(eth, entry->data.ib1);
- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE)
- len = offsetof(struct mtk_foe_entry, ipv6._rsv);
- else
-@@ -427,14 +456,12 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
-
- static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1)
- {
-- u16 timestamp;
-- u16 now;
--
-- now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP;
-- timestamp = ib1 & MTK_FOE_IB1_BIND_TIMESTAMP;
-+ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth);
-+ u16 now = mtk_eth_timestamp(ppe->eth);
-+ u16 timestamp = ib1 & ib1_ts_mask;
-
- if (timestamp > now)
-- return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now;
-+ return ib1_ts_mask + 1 - timestamp + now;
- else
- return now - timestamp;
- }
-@@ -442,6 +469,7 @@ static int __mtk_foe_entry_idle_time(str
- static void
- mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-+ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth);
- struct mtk_flow_entry *cur;
- struct mtk_foe_entry *hwe;
- struct hlist_node *tmp;
-@@ -466,8 +494,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe
- continue;
-
- idle = cur_idle;
-- entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
-- entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP;
-+ entry->data.ib1 &= ~ib1_ts_mask;
-+ entry->data.ib1 |= hwe->ib1 & ib1_ts_mask;
- }
- }
-
-@@ -489,7 +517,7 @@ mtk_flow_entry_update(struct mtk_ppe *pp
-
- hwe = mtk_foe_get_entry(ppe, entry->hash);
- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size);
-- if (!mtk_flow_entry_match(entry, &foe)) {
-+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) {
- entry->hash = 0xffff;
- goto out;
- }
-@@ -504,16 +532,22 @@ static void
- __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
- u16 hash)
- {
-+ struct mtk_eth *eth = ppe->eth;
-+ u16 timestamp = mtk_eth_timestamp(eth);
- struct mtk_foe_entry *hwe;
-- u16 timestamp;
-
-- timestamp = mtk_eth_timestamp(ppe->eth);
-- timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP;
-- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
-- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-+ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2,
-+ timestamp);
-+ } else {
-+ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
-+ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP,
-+ timestamp);
-+ }
-
- hwe = mtk_foe_get_entry(ppe, hash);
-- memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size);
-+ memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size);
- wmb();
- hwe->ib1 = entry->ib1;
-
-@@ -540,8 +574,8 @@ mtk_foe_entry_commit_l2(struct mtk_ppe *
-
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1);
- const struct mtk_soc_data *soc = ppe->eth->soc;
-+ int type = mtk_get_ib1_pkt_type(ppe->eth, entry->data.ib1);
- u32 hash;
-
- if (type == MTK_PPE_PKT_TYPE_BRIDGE)
-@@ -564,7 +598,7 @@ mtk_foe_entry_commit_subflow(struct mtk_
- struct mtk_flow_entry *flow_info;
- struct mtk_foe_entry foe = {}, *hwe;
- struct mtk_foe_mac_info *l2;
-- u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP;
-+ u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP;
- int type;
-
- flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end),
-@@ -584,16 +618,16 @@ mtk_foe_entry_commit_subflow(struct mtk_
- foe.ib1 &= ib1_mask;
- foe.ib1 |= entry->data.ib1 & ~ib1_mask;
-
-- l2 = mtk_foe_entry_l2(&foe);
-+ l2 = mtk_foe_entry_l2(ppe->eth, &foe);
- memcpy(l2, &entry->data.bridge.l2, sizeof(*l2));
-
-- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, foe.ib1);
-+ type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1);
- if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT)
- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new));
- else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP)
- l2->etype = ETH_P_IPV6;
-
-- *mtk_foe_entry_ib2(&foe) = entry->data.bridge.ib2;
-+ *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2;
-
- __mtk_foe_entry_commit(ppe, &foe, hash);
- }
-@@ -626,7 +660,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- continue;
- }
-
-- if (found || !mtk_flow_entry_match(entry, hwe)) {
-+ if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) {
- if (entry->hash != 0xffff)
- entry->hash = 0xffff;
- continue;
-@@ -771,6 +805,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_SCAN_MODE_CHECK_AGE) |
- FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
- MTK_PPE_ENTRIES_SHIFT);
-+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
-+ val |= MTK_PPE_TB_CFG_INFO_SEL;
- ppe_w32(ppe, MTK_PPE_TB_CFG, val);
-
- ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK,
-@@ -778,15 +814,21 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
-
- mtk_ppe_cache_enable(ppe, true);
-
-- val = MTK_PPE_FLOW_CFG_IP4_TCP_FRAG |
-- MTK_PPE_FLOW_CFG_IP4_UDP_FRAG |
-- MTK_PPE_FLOW_CFG_IP6_3T_ROUTE |
-+ val = MTK_PPE_FLOW_CFG_IP6_3T_ROUTE |
- MTK_PPE_FLOW_CFG_IP6_5T_ROUTE |
- MTK_PPE_FLOW_CFG_IP6_6RD |
- MTK_PPE_FLOW_CFG_IP4_NAT |
- MTK_PPE_FLOW_CFG_IP4_NAPT |
- MTK_PPE_FLOW_CFG_IP4_DSLITE |
- MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
-+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
-+ val |= MTK_PPE_MD_TOAP_BYP_CRSN0 |
-+ MTK_PPE_MD_TOAP_BYP_CRSN1 |
-+ MTK_PPE_MD_TOAP_BYP_CRSN2 |
-+ MTK_PPE_FLOW_CFG_IP4_HASH_GRE_KEY;
-+ else
-+ val |= MTK_PPE_FLOW_CFG_IP4_TCP_FRAG |
-+ MTK_PPE_FLOW_CFG_IP4_UDP_FRAG;
- ppe_w32(ppe, MTK_PPE_FLOW_CFG, val);
-
- val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) |
-@@ -820,6 +862,11 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- ppe_w32(ppe, MTK_PPE_GLO_CFG, val);
-
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
-+
-+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) {
-+ ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
-+ ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
-+ }
- }
-
- int mtk_ppe_stop(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -32,6 +32,15 @@
- #define MTK_FOE_IB1_UDP BIT(30)
- #define MTK_FOE_IB1_STATIC BIT(31)
-
-+/* CONFIG_MEDIATEK_NETSYS_V2 */
-+#define MTK_FOE_IB1_BIND_TIMESTAMP_V2 GENMASK(7, 0)
-+#define MTK_FOE_IB1_BIND_VLAN_LAYER_V2 GENMASK(16, 14)
-+#define MTK_FOE_IB1_BIND_PPPOE_V2 BIT(17)
-+#define MTK_FOE_IB1_BIND_VLAN_TAG_V2 BIT(18)
-+#define MTK_FOE_IB1_BIND_CACHE_V2 BIT(20)
-+#define MTK_FOE_IB1_BIND_TTL_V2 BIT(22)
-+#define MTK_FOE_IB1_PACKET_TYPE_V2 GENMASK(27, 23)
-+
- enum {
- MTK_PPE_PKT_TYPE_IPV4_HNAPT = 0,
- MTK_PPE_PKT_TYPE_IPV4_ROUTE = 1,
-@@ -53,14 +62,25 @@ enum {
-
- #define MTK_FOE_IB2_PORT_MG GENMASK(17, 12)
-
-+#define MTK_FOE_IB2_RX_IDX GENMASK(18, 17)
- #define MTK_FOE_IB2_PORT_AG GENMASK(23, 18)
-
- #define MTK_FOE_IB2_DSCP GENMASK(31, 24)
-
-+/* CONFIG_MEDIATEK_NETSYS_V2 */
-+#define MTK_FOE_IB2_PORT_MG_V2 BIT(7)
-+#define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9)
-+#define MTK_FOE_IB2_MULTICAST_V2 BIT(13)
-+#define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19)
-+#define MTK_FOE_IB2_PORT_AG_V2 GENMASK(23, 20)
-+
- #define MTK_FOE_VLAN2_WINFO_BSS GENMASK(5, 0)
- #define MTK_FOE_VLAN2_WINFO_WCID GENMASK(13, 6)
- #define MTK_FOE_VLAN2_WINFO_RING GENMASK(15, 14)
-
-+#define MTK_FOE_WINFO_BSS GENMASK(5, 0)
-+#define MTK_FOE_WINFO_WCID GENMASK(15, 6)
-+
- enum {
- MTK_FOE_STATE_INVALID,
- MTK_FOE_STATE_UNBIND,
-@@ -81,6 +101,9 @@ struct mtk_foe_mac_info {
-
- u16 pppoe_id;
- u16 src_mac_lo;
-+
-+ u16 minfo;
-+ u16 winfo;
- };
-
- /* software-only entry type */
-@@ -198,7 +221,7 @@ struct mtk_foe_entry {
- struct mtk_foe_ipv4_dslite dslite;
- struct mtk_foe_ipv6 ipv6;
- struct mtk_foe_ipv6_6rd ipv6_6rd;
-- u32 data[19];
-+ u32 data[23];
- };
- };
-
-@@ -306,20 +329,27 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s
- __mtk_ppe_check_skb(ppe, skb, hash);
- }
-
--int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto,
-- u8 pse_port, u8 *src_mac, u8 *dest_mac);
--int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port);
--int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig,
-+int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int type, int l4proto, u8 pse_port, u8 *src_mac,
-+ u8 *dest_mac);
-+int mtk_foe_entry_set_pse_port(struct mtk_eth *eth,
-+ struct mtk_foe_entry *entry, u8 port);
-+int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth,
-+ struct mtk_foe_entry *entry, bool orig,
- __be32 src_addr, __be16 src_port,
- __be32 dest_addr, __be16 dest_port);
--int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry,
-+int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth,
-+ struct mtk_foe_entry *entry,
- __be32 *src_addr, __be16 src_port,
- __be32 *dest_addr, __be16 dest_port);
--int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port);
--int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
--int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
--int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
-- int bss, int wcid);
-+int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int port);
-+int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int vid);
-+int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int sid);
-+int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ int wdma_idx, int txq, int bss, int wcid);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -52,18 +52,19 @@ static const struct rhashtable_params mt
- };
-
- static int
--mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data,
-- bool egress)
-+mtk_flow_set_ipv4_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe,
-+ struct mtk_flow_data *data, bool egress)
- {
-- return mtk_foe_entry_set_ipv4_tuple(foe, egress,
-+ return mtk_foe_entry_set_ipv4_tuple(eth, foe, egress,
- data->v4.src_addr, data->src_port,
- data->v4.dst_addr, data->dst_port);
- }
-
- static int
--mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data)
-+mtk_flow_set_ipv6_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe,
-+ struct mtk_flow_data *data)
- {
-- return mtk_foe_entry_set_ipv6_tuple(foe,
-+ return mtk_foe_entry_set_ipv6_tuple(eth, foe,
- data->v6.src_addr.s6_addr32, data->src_port,
- data->v6.dst_addr.s6_addr32, data->dst_port);
- }
-@@ -190,16 +191,29 @@ mtk_flow_set_output_device(struct mtk_et
- int pse_port, dsa_port;
-
- if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
-- mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss,
-- info.wcid);
-- pse_port = 3;
-+ mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
-+ info.bss, info.wcid);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ switch (info.wdma_idx) {
-+ case 0:
-+ pse_port = 8;
-+ break;
-+ case 1:
-+ pse_port = 9;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ } else {
-+ pse_port = 3;
-+ }
- *wed_index = info.wdma_idx;
- goto out;
- }
-
- dsa_port = mtk_flow_get_dsa_port(&dev);
- if (dsa_port >= 0)
-- mtk_foe_entry_set_dsa(foe, dsa_port);
-+ mtk_foe_entry_set_dsa(eth, foe, dsa_port);
-
- if (dev == eth->netdev[0])
- pse_port = 1;
-@@ -209,7 +223,7 @@ mtk_flow_set_output_device(struct mtk_et
- return -EOPNOTSUPP;
-
- out:
-- mtk_foe_entry_set_pse_port(foe, pse_port);
-+ mtk_foe_entry_set_pse_port(eth, foe, pse_port);
-
- return 0;
- }
-@@ -333,9 +347,8 @@ mtk_flow_offload_replace(struct mtk_eth
- !is_valid_ether_addr(data.eth.h_dest))
- return -EINVAL;
-
-- err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0,
-- data.eth.h_source,
-- data.eth.h_dest);
-+ err = mtk_foe_entry_prepare(eth, &foe, offload_type, l4proto, 0,
-+ data.eth.h_source, data.eth.h_dest);
- if (err)
- return err;
-
-@@ -360,7 +373,7 @@ mtk_flow_offload_replace(struct mtk_eth
- data.v4.src_addr = addrs.key->src;
- data.v4.dst_addr = addrs.key->dst;
-
-- mtk_flow_set_ipv4_addr(&foe, &data, false);
-+ mtk_flow_set_ipv4_addr(eth, &foe, &data, false);
- }
-
- if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
-@@ -371,7 +384,7 @@ mtk_flow_offload_replace(struct mtk_eth
- data.v6.src_addr = addrs.key->src;
- data.v6.dst_addr = addrs.key->dst;
-
-- mtk_flow_set_ipv6_addr(&foe, &data);
-+ mtk_flow_set_ipv6_addr(eth, &foe, &data);
- }
-
- flow_action_for_each(i, act, &rule->action) {
-@@ -401,7 +414,7 @@ mtk_flow_offload_replace(struct mtk_eth
- }
-
- if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
-- err = mtk_flow_set_ipv4_addr(&foe, &data, true);
-+ err = mtk_flow_set_ipv4_addr(eth, &foe, &data, true);
- if (err)
- return err;
- }
-@@ -413,10 +426,10 @@ mtk_flow_offload_replace(struct mtk_eth
- if (data.vlan.proto != htons(ETH_P_8021Q))
- return -EOPNOTSUPP;
-
-- mtk_foe_entry_set_vlan(&foe, data.vlan.id);
-+ mtk_foe_entry_set_vlan(eth, &foe, data.vlan.id);
- }
- if (data.pppoe.num == 1)
-- mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid);
-+ mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid);
-
- err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest,
- &wed_index);
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -21,6 +21,9 @@
- #define MTK_PPE_GLO_CFG_BUSY BIT(31)
-
- #define MTK_PPE_FLOW_CFG 0x204
-+#define MTK_PPE_MD_TOAP_BYP_CRSN0 BIT(1)
-+#define MTK_PPE_MD_TOAP_BYP_CRSN1 BIT(2)
-+#define MTK_PPE_MD_TOAP_BYP_CRSN2 BIT(3)
- #define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG BIT(6)
- #define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG BIT(7)
- #define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE BIT(8)
-@@ -54,6 +57,7 @@
- #define MTK_PPE_TB_CFG_HASH_MODE GENMASK(15, 14)
- #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16)
- #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18)
-+#define MTK_PPE_TB_CFG_INFO_SEL BIT(20)
-
- enum {
- MTK_PPE_SCAN_MODE_DISABLED,
-@@ -112,6 +116,8 @@ enum {
- #define MTK_PPE_DEFAULT_CPU_PORT 0x248
- #define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n) (GENMASK(2, 0) << ((_n) * 4))
-
-+#define MTK_PPE_DEFAULT_CPU_PORT1 0x24c
-+
- #define MTK_PPE_MTU_DROP 0x308
-
- #define MTK_PPE_VLAN_MTU0 0x30c
-@@ -141,4 +147,6 @@ enum {
- #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
- #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)
-
-+#define MTK_PPE_SBW_CTRL 0x374
-+
- #endif
diff --git a/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch b/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch
deleted file mode 100644
index c4bd29365c..0000000000
--- a/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 40350ce3ae8701146aafd79c5f7b5582d9955e58 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 25 Sep 2022 15:12:35 +0100
-Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: fix wrong use of new helper
- function
-To: linux-mediatek@lists.infradead.org,
- netdev@vger.kernel.org,
- Lorenzo Bianconi <lorenzo@kernel.org>
-Cc: Sujuan Chen <sujuan.chen@mediatek.com>,
- Bo Jiao <Bo.Jiao@mediatek.com>,
- Felix Fietkau <nbd@nbd.name>,
- John Crispin <john@phrozen.org>,
- Sean Wang <sean.wang@mediatek.com>,
- Mark Lee <Mark-MC.Lee@mediatek.com>,
- David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- Chen Minqiang <ptpt52@gmail.com>
-
-In function mtk_foe_entry_set_vlan() the call to field accessor macro
-FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)
-has been wrongly replaced by
-mtk_prep_ib1_vlan_layer(eth, entry->ib1)
-
-Use correct helper function mtk_get_ib1_vlan_layer instead.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Fixes: 03a3180e5c09e1 ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -337,7 +337,7 @@ int mtk_foe_entry_set_vlan(struct mtk_et
- {
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
-
-- switch (mtk_prep_ib1_vlan_layer(eth, entry->ib1)) {
-+ switch (mtk_get_ib1_vlan_layer(eth, entry->ib1)) {
- case 0:
- entry->ib1 |= mtk_get_ib1_vlan_tag_mask(eth) |
- mtk_prep_ib1_vlan_layer(eth, 1);
diff --git a/target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch b/target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch
deleted file mode 100644
index 58314a8fc0..0000000000
--- a/target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From b94b02a270471337bef73c44fa3493a521e31a61 Mon Sep 17 00:00:00 2001
-Message-Id: <b94b02a270471337bef73c44fa3493a521e31a61.1662886034.git.lorenzo@kernel.org>
-In-Reply-To: <e5ecb4f619197b93fa682d722452dc8412864cdb.1662886033.git.lorenzo@kernel.org>
-References: <e5ecb4f619197b93fa682d722452dc8412864cdb.1662886033.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 5 Sep 2022 13:56:13 +0200
-Subject: [PATCH net-next 5/5] net: ethernet: mtk_eth_soc: enable flow
- offloading support for mt7986
-
-Enable hw packet engine and wireless packet dispatcher for mt7986
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4254,6 +4254,7 @@ static const struct mtk_soc_data mt7986_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7986_CLKS_BITMAP,
- .required_pctl = false,
-+ .offload_version = 2,
- .hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
- .txrx = {
diff --git a/target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch b/target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch
deleted file mode 100644
index bb02f401a2..0000000000
--- a/target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From fcf14c2c5deae8f8c3d25530bab10856f63f8a63 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 25 Sep 2022 15:18:54 +0100
-Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: fix usage of foe_entry_size
-To: linux-mediatek@lists.infradead.org,
- netdev@vger.kernel.org,
- Lorenzo Bianconi <lorenzo@kernel.org>
-Cc: Sujuan Chen <sujuan.chen@mediatek.com>,
- Bo Jiao <Bo.Jiao@mediatek.com>,
- Felix Fietkau <nbd@nbd.name>,
- John Crispin <john@phrozen.org>,
- Sean Wang <sean.wang@mediatek.com>,
- Mark Lee <Mark-MC.Lee@mediatek.com>,
- David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- Chen Minqiang <ptpt52@gmail.com>
-
-As sizeof(hwe->data) can now longer be used as the actual size depends
-on foe_entry_size, in commit 9d8cb4c096ab02
-("net: ethernet: mtk_eth_soc: add foe_entry_size to mtk_eth_soc") the
-use of sizeof(hwe->data) is hence replaced.
-However, replacing it with ppe->eth->soc->foe_entry_size is wrong as
-foe_entry_size represents the size of the whole descriptor and not just
-the 'data' field.
-Fix this by subtracing the size of the only other field in the struct
-'ib1', so we actually end up with the correct size to be copied to the
-data field.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Fixes: 9d8cb4c096ab02 ("net: ethernet: mtk_eth_soc: add foe_entry_size to mtk_eth_soc")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -547,7 +547,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- }
-
- hwe = mtk_foe_get_entry(ppe, hash);
-- memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size);
-+ memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size - sizeof(hwe->ib1));
- wmb();
- hwe->ib1 = entry->ib1;
-
diff --git a/target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch b/target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch
deleted file mode 100644
index 27c719b663..0000000000
--- a/target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From c9da02bfb1112461e048d3b736afb1873f6f4ccf Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 27 Sep 2022 16:30:02 +0100
-Subject: [PATCH 1/1] net: ethernet: mtk_eth_soc: fix mask of
- RX_DMA_GET_SPORT{,_V2}
-
-The bitmasks applied in RX_DMA_GET_SPORT and RX_DMA_GET_SPORT_V2 macros
-were swapped. Fix that.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Fixes: 160d3a9b192985 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support")
-Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/YzMW+mg9UsaCdKRQ@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -315,8 +315,8 @@
- #define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18)
- #define MTK_RXD5_SRC_PORT GENMASK(29, 26)
-
--#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf)
--#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7)
-+#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0x7)
-+#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0xf)
-
- /* PDMA V2 descriptor rxd3 */
- #define RX_DMA_VTAG_V2 BIT(0)
diff --git a/target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch b/target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch
deleted file mode 100644
index 11465c1c5b..0000000000
--- a/target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From ae3ed15da5889263de372ff9df2e83e16acca4cb Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 30 Sep 2022 01:56:53 +0100
-Subject: [PATCH 1/1] net: ethernet: mtk_eth_soc: fix state in
- __mtk_foe_entry_clear
-
-Setting ib1 state to MTK_FOE_STATE_UNBIND in __mtk_foe_entry_clear
-routine as done by commit 0e80707d94e4c8 ("net: ethernet: mtk_eth_soc:
-fix typo in __mtk_foe_entry_clear") breaks flow offloading, at least
-on older MTK_NETSYS_V1 SoCs, OpenWrt users have confirmed the bug on
-MT7622 and MT7621 systems.
-Felix Fietkau suggested to use MTK_FOE_STATE_INVALID instead which
-works well on both, MTK_NETSYS_V1 and MTK_NETSYS_V2.
-
-Tested on MT7622 (Linksys E8450) and MT7986 (BananaPi BPI-R3).
-
-Suggested-by: Felix Fietkau <nbd@nbd.name>
-Fixes: 0e80707d94e4c8 ("net: ethernet: mtk_eth_soc: fix typo in __mtk_foe_entry_clear")
-Fixes: 33fc42de33278b ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/YzY+1Yg0FBXcnrtc@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -442,7 +442,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
-
- hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_UNBIND);
-+ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
- dma_wmb();
- }
- entry->hash = 0xffff;
diff --git a/target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch b/target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch
deleted file mode 100644
index cad3204354..0000000000
--- a/target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From b3d0d98179d62f9d55635a600679c4fa362baf8d Mon Sep 17 00:00:00 2001
-From: Yang Yingliang <yangyingliang@huawei.com>
-Date: Mon, 17 Oct 2022 11:51:54 +0800
-Subject: [PATCH 1/3] net: ethernet: mtk_eth_soc: fix possible memory leak in
- mtk_probe()
-
-If mtk_wed_add_hw() has been called, mtk_wed_exit() needs be called
-in error path or removing module to free the memory allocated in
-mtk_wed_add_hw().
-
-Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4006,19 +4006,23 @@ static int mtk_probe(struct platform_dev
- 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;
-+ err = -ENXIO;
-+ 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]);
- if (IS_ERR(eth->clks[i])) {
-- if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER)
-- return -EPROBE_DEFER;
-+ if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) {
-+ err = -EPROBE_DEFER;
-+ goto err_wed_exit;
-+ }
- if (eth->soc->required_clks & BIT(i)) {
- dev_err(&pdev->dev, "clock %s not found\n",
- mtk_clks_source_name[i]);
-- return -EINVAL;
-+ err = -EINVAL;
-+ goto err_wed_exit;
- }
- eth->clks[i] = NULL;
- }
-@@ -4029,7 +4033,7 @@ static int mtk_probe(struct platform_dev
-
- err = mtk_hw_init(eth);
- if (err)
-- return err;
-+ goto err_wed_exit;
-
- eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO);
-
-@@ -4127,6 +4131,8 @@ err_free_dev:
- mtk_free_dev(eth);
- err_deinit_hw:
- mtk_hw_deinit(eth);
-+err_wed_exit:
-+ mtk_wed_exit();
-
- return err;
- }
-@@ -4146,6 +4152,7 @@ static int mtk_remove(struct platform_de
- phylink_disconnect_phy(mac->phylink);
- }
-
-+ mtk_wed_exit();
- mtk_hw_deinit(eth);
-
- netif_napi_del(&eth->tx_napi);
diff --git a/target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch b/target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch
deleted file mode 100644
index 4f0b78f110..0000000000
--- a/target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 9d4f20a476ca57e4c9246eb1fa2a61bea2354720 Mon Sep 17 00:00:00 2001
-From: Yang Yingliang <yangyingliang@huawei.com>
-Date: Mon, 17 Oct 2022 11:51:55 +0800
-Subject: [PATCH 2/3] net: ethernet: mtk_eth_wed: add missing put_device() in
- mtk_wed_add_hw()
-
-After calling get_device() in mtk_wed_add_hw(), in error path, put_device()
-needs be called.
-
-Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1077,11 +1077,11 @@ void mtk_wed_add_hw(struct device_node *
- get_device(&pdev->dev);
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
-- return;
-+ goto err_put_device;
-
- regs = syscon_regmap_lookup_by_phandle(np, NULL);
- if (IS_ERR(regs))
-- return;
-+ goto err_put_device;
-
- rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
-
-@@ -1124,8 +1124,14 @@ void mtk_wed_add_hw(struct device_node *
-
- hw_list[index] = hw;
-
-+ mutex_unlock(&hw_lock);
-+
-+ return;
-+
- unlock:
- mutex_unlock(&hw_lock);
-+err_put_device:
-+ put_device(&pdev->dev);
- }
-
- void mtk_wed_exit(void)
diff --git a/target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch b/target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch
deleted file mode 100644
index 32f62aaed2..0000000000
--- a/target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From e0bb4659e235770e6f53b3692e958591f49448f5 Mon Sep 17 00:00:00 2001
-From: Yang Yingliang <yangyingliang@huawei.com>
-Date: Mon, 17 Oct 2022 11:51:56 +0800
-Subject: [PATCH 3/3] net: ethernet: mtk_eth_wed: add missing of_node_put()
-
-The device_node pointer returned by of_parse_phandle() with refcount
-incremented, when finish using it, the refcount need be decreased.
-
-Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1072,7 +1072,7 @@ void mtk_wed_add_hw(struct device_node *
-
- pdev = of_find_device_by_node(np);
- if (!pdev)
-- return;
-+ goto err_of_node_put;
-
- get_device(&pdev->dev);
- irq = platform_get_irq(pdev, 0);
-@@ -1132,6 +1132,8 @@ unlock:
- mutex_unlock(&hw_lock);
- err_put_device:
- put_device(&pdev->dev);
-+err_of_node_put:
-+ of_node_put(np);
- }
-
- void mtk_wed_exit(void)
-@@ -1152,6 +1154,7 @@ void mtk_wed_exit(void)
- hw_list[i] = NULL;
- debugfs_remove(hw->debugfs_dir);
- put_device(hw->dev);
-+ of_node_put(hw->node);
- kfree(hw);
- }
- }
diff --git a/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch b/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch
deleted file mode 100644
index e2a2046442..0000000000
--- a/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 8110437e59616293228cd781c486d8495a61e36a Mon Sep 17 00:00:00 2001
-From: Yan Cangang <nalanzeyu@gmail.com>
-Date: Sun, 20 Nov 2022 13:52:58 +0800
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix resource leak in error path
-
-In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() failed,
-mtk_mdio_cleanup() isn't called. Fix it.
-
-Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
-Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support")
-Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4089,13 +4089,13 @@ static int mtk_probe(struct platform_dev
- eth->soc->offload_version, i);
- if (!eth->ppe[i]) {
- err = -ENOMEM;
-- goto err_free_dev;
-+ goto err_deinit_mdio;
- }
- }
-
- err = mtk_eth_offload_init(eth);
- if (err)
-- goto err_free_dev;
-+ goto err_deinit_mdio;
- }
-
- for (i = 0; i < MTK_MAX_DEVS; i++) {
diff --git a/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch b/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch
deleted file mode 100644
index 13f0ed5a5d..0000000000
--- a/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 603ea5e7ffa73c7fac07d8713d97285990695213 Mon Sep 17 00:00:00 2001
-From: Yan Cangang <nalanzeyu@gmail.com>
-Date: Sun, 20 Nov 2022 13:52:59 +0800
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory leak in error path
-
-In mtk_ppe_init(), when dmam_alloc_coherent() or devm_kzalloc() failed,
-the rhashtable ppe->l2_flows isn't destroyed. Fix it.
-
-In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() or
-register_netdev() failed, have the same problem. Fix it.
-
-Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries")
-Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 +++++----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_ppe.h | 1 +
- 3 files changed, 23 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4089,13 +4089,13 @@ static int mtk_probe(struct platform_dev
- eth->soc->offload_version, i);
- if (!eth->ppe[i]) {
- err = -ENOMEM;
-- goto err_deinit_mdio;
-+ goto err_deinit_ppe;
- }
- }
-
- err = mtk_eth_offload_init(eth);
- if (err)
-- goto err_deinit_mdio;
-+ goto err_deinit_ppe;
- }
-
- for (i = 0; i < MTK_MAX_DEVS; i++) {
-@@ -4105,7 +4105,7 @@ static int mtk_probe(struct platform_dev
- err = register_netdev(eth->netdev[i]);
- if (err) {
- dev_err(eth->dev, "error bringing up device\n");
-- goto err_deinit_mdio;
-+ goto err_deinit_ppe;
- } else
- netif_info(eth, probe, eth->netdev[i],
- "mediatek frame engine at 0x%08lx, irq %d\n",
-@@ -4125,7 +4125,8 @@ static int mtk_probe(struct platform_dev
-
- return 0;
-
--err_deinit_mdio:
-+err_deinit_ppe:
-+ mtk_ppe_deinit(eth);
- mtk_mdio_cleanup(eth);
- err_free_dev:
- mtk_free_dev(eth);
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -743,7 +743,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- MTK_PPE_ENTRIES * soc->foe_entry_size,
- &ppe->foe_phys, GFP_KERNEL);
- if (!foe)
-- return NULL;
-+ goto err_free_l2_flows;
-
- ppe->foe_table = foe;
-
-@@ -751,11 +751,26 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- sizeof(*ppe->foe_flow);
- ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
- if (!ppe->foe_flow)
-- return NULL;
-+ goto err_free_l2_flows;
-
- mtk_ppe_debugfs_init(ppe, index);
-
- return ppe;
-+
-+err_free_l2_flows:
-+ rhashtable_destroy(&ppe->l2_flows);
-+ return NULL;
-+}
-+
-+void mtk_ppe_deinit(struct mtk_eth *eth)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) {
-+ if (!eth->ppe[i])
-+ return;
-+ rhashtable_destroy(&eth->ppe[i]->l2_flows);
-+ }
- }
-
- static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -304,6 +304,7 @@ struct mtk_ppe {
-
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version, int index);
-+void mtk_ppe_deinit(struct mtk_eth *eth);
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-
diff --git a/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch b/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch
deleted file mode 100644
index c48613929d..0000000000
--- a/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch
+++ /dev/null
@@ -1,591 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Sat, 5 Nov 2022 23:36:18 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: introduce wed mcu support
-
-Introduce WED mcu support used to configure WED WO chip.
-This is a preliminary patch in order to add RX Wireless
-Ethernet Dispatch available on MT7986 SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.h
-
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,7 +5,7 @@
-
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
- mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
--mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o
-+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o
- ifdef CONFIG_DEBUG_FS
- mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
- endif
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -0,0 +1,359 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2022 MediaTek Inc.
-+ *
-+ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
-+ * Sujuan Chen <sujuan.chen@mediatek.com>
-+ */
-+
-+#include <linux/firmware.h>
-+#include <linux/of_address.h>
-+#include <linux/of_reserved_mem.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/soc/mediatek/mtk_wed.h>
-+
-+#include "mtk_wed_regs.h"
-+#include "mtk_wed_wo.h"
-+#include "mtk_wed.h"
-+
-+static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
-+{
-+ return readl(wo->boot.addr + reg);
-+}
-+
-+static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
-+{
-+ writel(val, wo->boot.addr + reg);
-+}
-+
-+static struct sk_buff *
-+mtk_wed_mcu_msg_alloc(const void *data, int data_len)
-+{
-+ int length = sizeof(struct mtk_wed_mcu_hdr) + data_len;
-+ struct sk_buff *skb;
-+
-+ skb = alloc_skb(length, GFP_KERNEL);
-+ if (!skb)
-+ return NULL;
-+
-+ memset(skb->head, 0, length);
-+ skb_reserve(skb, sizeof(struct mtk_wed_mcu_hdr));
-+ if (data && data_len)
-+ skb_put_data(skb, data, data_len);
-+
-+ return skb;
-+}
-+
-+static struct sk_buff *
-+mtk_wed_mcu_get_response(struct mtk_wed_wo *wo, unsigned long expires)
-+{
-+ if (!time_is_after_jiffies(expires))
-+ return NULL;
-+
-+ wait_event_timeout(wo->mcu.wait, !skb_queue_empty(&wo->mcu.res_q),
-+ expires - jiffies);
-+ return skb_dequeue(&wo->mcu.res_q);
-+}
-+
-+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb)
-+{
-+ skb_queue_tail(&wo->mcu.res_q, skb);
-+ wake_up(&wo->mcu.wait);
-+}
-+
-+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo,
-+ struct sk_buff *skb)
-+{
-+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+
-+ switch (hdr->cmd) {
-+ case MTK_WED_WO_EVT_LOG_DUMP: {
-+ const char *msg = (const char *)(skb->data + sizeof(*hdr));
-+
-+ dev_notice(wo->hw->dev, "%s\n", msg);
-+ break;
-+ }
-+ case MTK_WED_WO_EVT_PROFILING: {
-+ struct mtk_wed_wo_log_info *info;
-+ u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info);
-+ int i;
-+
-+ info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr));
-+ for (i = 0 ; i < count ; i++)
-+ dev_notice(wo->hw->dev,
-+ "SN:%u latency: total=%u, rro:%u, mod:%u\n",
-+ le32_to_cpu(info[i].sn),
-+ le32_to_cpu(info[i].total),
-+ le32_to_cpu(info[i].rro),
-+ le32_to_cpu(info[i].mod));
-+ break;
-+ }
-+ case MTK_WED_WO_EVT_RXCNT_INFO:
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dev_kfree_skb(skb);
-+}
-+
-+static int
-+mtk_wed_mcu_skb_send_msg(struct mtk_wed_wo *wo, struct sk_buff *skb,
-+ int id, int cmd, u16 *wait_seq, bool wait_resp)
-+{
-+ struct mtk_wed_mcu_hdr *hdr;
-+
-+ /* TODO: make it dynamic based on cmd */
-+ wo->mcu.timeout = 20 * HZ;
-+
-+ hdr = (struct mtk_wed_mcu_hdr *)skb_push(skb, sizeof(*hdr));
-+ hdr->cmd = cmd;
-+ hdr->length = cpu_to_le16(skb->len);
-+
-+ if (wait_resp && wait_seq) {
-+ u16 seq = ++wo->mcu.seq;
-+
-+ if (!seq)
-+ seq = ++wo->mcu.seq;
-+ *wait_seq = seq;
-+
-+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_NEED_RSP);
-+ hdr->seq = cpu_to_le16(seq);
-+ }
-+ if (id == MTK_WED_MODULE_ID_WO)
-+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO);
-+
-+ dev_kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_mcu_parse_response(struct mtk_wed_wo *wo, struct sk_buff *skb,
-+ int cmd, int seq)
-+{
-+ struct mtk_wed_mcu_hdr *hdr;
-+
-+ if (!skb) {
-+ dev_err(wo->hw->dev, "Message %08x (seq %d) timeout\n",
-+ cmd, seq);
-+ return -ETIMEDOUT;
-+ }
-+
-+ hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+ if (le16_to_cpu(hdr->seq) != seq)
-+ return -EAGAIN;
-+
-+ skb_pull(skb, sizeof(*hdr));
-+ switch (cmd) {
-+ case MTK_WED_WO_CMD_RXCNT_INFO:
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
-+ const void *data, int len, bool wait_resp)
-+{
-+ unsigned long expires;
-+ struct sk_buff *skb;
-+ u16 seq;
-+ int ret;
-+
-+ skb = mtk_wed_mcu_msg_alloc(data, len);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&wo->mcu.mutex);
-+
-+ ret = mtk_wed_mcu_skb_send_msg(wo, skb, id, cmd, &seq, wait_resp);
-+ if (ret || !wait_resp)
-+ goto unlock;
-+
-+ expires = jiffies + wo->mcu.timeout;
-+ do {
-+ skb = mtk_wed_mcu_get_response(wo, expires);
-+ ret = mtk_wed_mcu_parse_response(wo, skb, cmd, seq);
-+ dev_kfree_skb(skb);
-+ } while (ret == -EAGAIN);
-+
-+unlock:
-+ mutex_unlock(&wo->mcu.mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+mtk_wed_get_memory_region(struct mtk_wed_wo *wo,
-+ struct mtk_wed_wo_memory_region *region)
-+{
-+ struct reserved_mem *rmem;
-+ struct device_node *np;
-+ int index;
-+
-+ index = of_property_match_string(wo->hw->node, "memory-region-names",
-+ region->name);
-+ if (index < 0)
-+ return index;
-+
-+ np = of_parse_phandle(wo->hw->node, "memory-region", index);
-+ if (!np)
-+ return -ENODEV;
-+
-+ rmem = of_reserved_mem_lookup(np);
-+ of_node_put(np);
-+
-+ if (!rmem)
-+ return -ENODEV;
-+
-+ region->phy_addr = rmem->base;
-+ region->size = rmem->size;
-+ region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size);
-+
-+ return !region->addr ? -EINVAL : 0;
-+}
-+
-+static int
-+mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw,
-+ struct mtk_wed_wo_memory_region *region)
-+{
-+ const u8 *first_region_ptr, *region_ptr, *trailer_ptr, *ptr = fw->data;
-+ const struct mtk_wed_fw_trailer *trailer;
-+ const struct mtk_wed_fw_region *fw_region;
-+
-+ trailer_ptr = fw->data + fw->size - sizeof(*trailer);
-+ trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr;
-+ region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region);
-+ first_region_ptr = region_ptr;
-+
-+ while (region_ptr < trailer_ptr) {
-+ u32 length;
-+
-+ fw_region = (const struct mtk_wed_fw_region *)region_ptr;
-+ length = le32_to_cpu(fw_region->len);
-+
-+ if (region->phy_addr != le32_to_cpu(fw_region->addr))
-+ goto next;
-+
-+ if (region->size < length)
-+ goto next;
-+
-+ if (first_region_ptr < ptr + length)
-+ goto next;
-+
-+ if (region->shared && region->consumed)
-+ return 0;
-+
-+ if (!region->shared || !region->consumed) {
-+ memcpy_toio(region->addr, ptr, length);
-+ region->consumed = true;
-+ return 0;
-+ }
-+next:
-+ region_ptr += sizeof(*fw_region);
-+ ptr += length;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int
-+mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
-+{
-+ static struct mtk_wed_wo_memory_region mem_region[] = {
-+ [MTK_WED_WO_REGION_EMI] = {
-+ .name = "wo-emi",
-+ },
-+ [MTK_WED_WO_REGION_ILM] = {
-+ .name = "wo-ilm",
-+ },
-+ [MTK_WED_WO_REGION_DATA] = {
-+ .name = "wo-data",
-+ .shared = true,
-+ },
-+ };
-+ const struct mtk_wed_fw_trailer *trailer;
-+ const struct firmware *fw;
-+ const char *fw_name;
-+ u32 val, boot_cr;
-+ int ret, i;
-+
-+ /* load firmware region metadata */
-+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
-+ ret = mtk_wed_get_memory_region(wo, &mem_region[i]);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ wo->boot.name = "wo-boot";
-+ ret = mtk_wed_get_memory_region(wo, &wo->boot);
-+ if (ret)
-+ return ret;
-+
-+ /* set dummy cr */
-+ wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL,
-+ wo->hw->index + 1);
-+
-+ /* load firmware */
-+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+ ret = request_firmware(&fw, fw_name, wo->hw->dev);
-+ if (ret)
-+ return ret;
-+
-+ trailer = (void *)(fw->data + fw->size -
-+ sizeof(struct mtk_wed_fw_trailer));
-+ dev_info(wo->hw->dev,
-+ "MTK WED WO Firmware Version: %.10s, Build Time: %.15s\n",
-+ trailer->fw_ver, trailer->build_date);
-+ dev_info(wo->hw->dev, "MTK WED WO Chip ID %02x Region %d\n",
-+ trailer->chip_id, trailer->num_region);
-+
-+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
-+ ret = mtk_wed_mcu_run_firmware(wo, fw, &mem_region[i]);
-+ if (ret)
-+ goto out;
-+ }
-+
-+ /* set the start address */
-+ boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR
-+ : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
-+ wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
-+ /* wo firmware reset */
-+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
-+
-+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
-+ val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK
-+ : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
-+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
-+out:
-+ release_firmware(fw);
-+
-+ return ret;
-+}
-+
-+static u32
-+mtk_wed_mcu_read_fw_dl(struct mtk_wed_wo *wo)
-+{
-+ return wed_r32(wo->hw->wed_dev,
-+ MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL);
-+}
-+
-+int mtk_wed_mcu_init(struct mtk_wed_wo *wo)
-+{
-+ u32 val;
-+ int ret;
-+
-+ skb_queue_head_init(&wo->mcu.res_q);
-+ init_waitqueue_head(&wo->mcu.wait);
-+ mutex_init(&wo->mcu.mutex);
-+
-+ ret = mtk_wed_mcu_load_firmware(wo);
-+ if (ret)
-+ return ret;
-+
-+ return readx_poll_timeout(mtk_wed_mcu_read_fw_dl, wo, val, !val,
-+ 100, MTK_FW_DL_TIMEOUT);
-+}
-+
-+MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
-+MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -152,6 +152,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10)
-
-+#define MTK_WED_SCR0 0x3c0
- #define MTK_WED_WPDMA_INT_TRIGGER 0x504
- #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
- #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -0,0 +1,150 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/* Copyright (C) 2022 Lorenzo Bianconi <lorenzo@kernel.org> */
-+
-+#ifndef __MTK_WED_WO_H
-+#define __MTK_WED_WO_H
-+
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+
-+struct mtk_wed_hw;
-+
-+struct mtk_wed_mcu_hdr {
-+ /* DW0 */
-+ u8 version;
-+ u8 cmd;
-+ __le16 length;
-+
-+ /* DW1 */
-+ __le16 seq;
-+ __le16 flag;
-+
-+ /* DW2 */
-+ __le32 status;
-+
-+ /* DW3 */
-+ u8 rsv[20];
-+};
-+
-+struct mtk_wed_wo_log_info {
-+ __le32 sn;
-+ __le32 total;
-+ __le32 rro;
-+ __le32 mod;
-+};
-+
-+enum mtk_wed_wo_event {
-+ MTK_WED_WO_EVT_LOG_DUMP = 0x1,
-+ MTK_WED_WO_EVT_PROFILING = 0x2,
-+ MTK_WED_WO_EVT_RXCNT_INFO = 0x3,
-+};
-+
-+#define MTK_WED_MODULE_ID_WO 1
-+#define MTK_FW_DL_TIMEOUT 4000000 /* us */
-+#define MTK_WOCPU_TIMEOUT 2000000 /* us */
-+
-+enum {
-+ MTK_WED_WARP_CMD_FLAG_RSP = BIT(0),
-+ MTK_WED_WARP_CMD_FLAG_NEED_RSP = BIT(1),
-+ MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2),
-+};
-+
-+enum {
-+ MTK_WED_WO_REGION_EMI,
-+ MTK_WED_WO_REGION_ILM,
-+ MTK_WED_WO_REGION_DATA,
-+ MTK_WED_WO_REGION_BOOT,
-+ __MTK_WED_WO_REGION_MAX,
-+};
-+
-+enum mtk_wed_dummy_cr_idx {
-+ MTK_WED_DUMMY_CR_FWDL,
-+ MTK_WED_DUMMY_CR_WO_STATUS,
-+};
-+
-+#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
-+#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
-+
-+#define MTK_WO_MCU_CFG_LS_BASE 0
-+#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
-+#define MTK_WO_MCU_CFG_LS_FW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x004)
-+#define MTK_WO_MCU_CFG_LS_CFG_DBG1_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x00c)
-+#define MTK_WO_MCU_CFG_LS_CFG_DBG2_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x010)
-+#define MTK_WO_MCU_CFG_LS_WF_MCCR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x014)
-+#define MTK_WO_MCU_CFG_LS_WF_MCCR_SET_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x018)
-+#define MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x01c)
-+#define MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x050)
-+#define MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x060)
-+#define MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x064)
-+
-+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5)
-+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0)
-+
-+struct mtk_wed_wo_memory_region {
-+ const char *name;
-+ void __iomem *addr;
-+ phys_addr_t phy_addr;
-+ u32 size;
-+ bool shared:1;
-+ bool consumed:1;
-+};
-+
-+struct mtk_wed_fw_region {
-+ __le32 decomp_crc;
-+ __le32 decomp_len;
-+ __le32 decomp_blk_sz;
-+ u8 rsv0[4];
-+ __le32 addr;
-+ __le32 len;
-+ u8 feature_set;
-+ u8 rsv1[15];
-+} __packed;
-+
-+struct mtk_wed_fw_trailer {
-+ u8 chip_id;
-+ u8 eco_code;
-+ u8 num_region;
-+ u8 format_ver;
-+ u8 format_flag;
-+ u8 rsv[2];
-+ char fw_ver[10];
-+ char build_date[15];
-+ u32 crc;
-+};
-+
-+struct mtk_wed_wo {
-+ struct mtk_wed_hw *hw;
-+ struct mtk_wed_wo_memory_region boot;
-+
-+ struct {
-+ struct mutex mutex;
-+ int timeout;
-+ u16 seq;
-+
-+ struct sk_buff_head res_q;
-+ wait_queue_head_t wait;
-+ } mcu;
-+};
-+
-+static inline int
-+mtk_wed_mcu_check_msg(struct mtk_wed_wo *wo, struct sk_buff *skb)
-+{
-+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+
-+ if (hdr->version)
-+ return -EINVAL;
-+
-+ if (skb->len < sizeof(*hdr) || skb->len != le16_to_cpu(hdr->length))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb);
-+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo,
-+ struct sk_buff *skb);
-+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
-+ const void *data, int len, bool wait_resp);
-+int mtk_wed_mcu_init(struct mtk_wed_wo *wo);
-+
-+#endif /* __MTK_WED_WO_H */
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -11,6 +11,35 @@
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-
-+enum mtk_wed_wo_cmd {
-+ MTK_WED_WO_CMD_WED_CFG,
-+ MTK_WED_WO_CMD_WED_RX_STAT,
-+ MTK_WED_WO_CMD_RRO_SER,
-+ MTK_WED_WO_CMD_DBG_INFO,
-+ MTK_WED_WO_CMD_DEV_INFO,
-+ MTK_WED_WO_CMD_BSS_INFO,
-+ MTK_WED_WO_CMD_STA_REC,
-+ MTK_WED_WO_CMD_DEV_INFO_DUMP,
-+ MTK_WED_WO_CMD_BSS_INFO_DUMP,
-+ MTK_WED_WO_CMD_STA_REC_DUMP,
-+ MTK_WED_WO_CMD_BA_INFO_DUMP,
-+ MTK_WED_WO_CMD_FBCMD_Q_DUMP,
-+ MTK_WED_WO_CMD_FW_LOG_CTRL,
-+ MTK_WED_WO_CMD_LOG_FLUSH,
-+ MTK_WED_WO_CMD_CHANGE_STATE,
-+ MTK_WED_WO_CMD_CPU_STATS_ENABLE,
-+ MTK_WED_WO_CMD_CPU_STATS_DUMP,
-+ MTK_WED_WO_CMD_EXCEPTION_INIT,
-+ MTK_WED_WO_CMD_PROF_CTRL,
-+ MTK_WED_WO_CMD_STA_BA_DUMP,
-+ MTK_WED_WO_CMD_BA_CTRL_DUMP,
-+ MTK_WED_WO_CMD_RXCNT_CTRL,
-+ MTK_WED_WO_CMD_RXCNT_INFO,
-+ MTK_WED_WO_CMD_SET_CAP,
-+ MTK_WED_WO_CMD_CCIF_RING_DUMP,
-+ MTK_WED_WO_CMD_WED_END
-+};
-+
- enum mtk_wed_bus_tye {
- MTK_WED_BUS_PCIE,
- MTK_WED_BUS_AXI,
diff --git a/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch b/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch
deleted file mode 100644
index fd5f45df2a..0000000000
--- a/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch
+++ /dev/null
@@ -1,737 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:19 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: introduce wed wo support
-
-Introduce WO chip support to mtk wed driver. MTK WED WO is used to
-implement RX Wireless Ethernet Dispatch and offload traffic received by
-wlan nic to the wired interface.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.c
-
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,7 +5,7 @@
-
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
- mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.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_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
- endif
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -16,6 +16,7 @@
- #include "mtk_wed_regs.h"
- #include "mtk_wed.h"
- #include "mtk_ppe.h"
-+#include "mtk_wed_wo.h"
-
- #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
-
-@@ -355,6 +356,8 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mtk_wed_free_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-+ if (hw->version != 1)
-+ mtk_wed_wo_deinit(hw);
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
- struct device_node *wlan_node;
-@@ -878,9 +881,11 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (hw->hifsys)
-+ if (hw->version == 1)
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
-+ else
-+ ret = mtk_wed_wo_init(hw);
-
- out:
- mutex_unlock(&hw_lock);
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -10,6 +10,7 @@
- #include <linux/netdevice.h>
-
- struct mtk_eth;
-+struct mtk_wed_wo;
-
- struct mtk_wed_hw {
- struct device_node *node;
-@@ -22,6 +23,7 @@ struct mtk_wed_hw {
- struct regmap *mirror;
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
-+ struct mtk_wed_wo *wed_wo;
- u32 debugfs_reg;
- u32 num_flows;
- u8 version;
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -122,8 +122,7 @@ mtk_wed_mcu_skb_send_msg(struct mtk_wed_
- if (id == MTK_WED_MODULE_ID_WO)
- hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO);
-
-- dev_kfree_skb(skb);
-- return 0;
-+ return mtk_wed_wo_queue_tx_skb(wo, &wo->q_tx, skb);
- }
-
- static int
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -0,0 +1,508 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2022 MediaTek Inc.
-+ *
-+ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
-+ * Sujuan Chen <sujuan.chen@mediatek.com>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/of_platform.h>
-+#include <linux/interrupt.h>
-+#include <linux/of_address.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/of_irq.h>
-+#include <linux/bitfield.h>
-+
-+#include "mtk_wed.h"
-+#include "mtk_wed_regs.h"
-+#include "mtk_wed_wo.h"
-+
-+static u32
-+mtk_wed_mmio_r32(struct mtk_wed_wo *wo, u32 reg)
-+{
-+ u32 val;
-+
-+ if (regmap_read(wo->mmio.regs, reg, &val))
-+ val = ~0;
-+
-+ return val;
-+}
-+
-+static void
-+mtk_wed_mmio_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
-+{
-+ regmap_write(wo->mmio.regs, reg, val);
-+}
-+
-+static u32
-+mtk_wed_wo_get_isr(struct mtk_wed_wo *wo)
-+{
-+ u32 val = mtk_wed_mmio_r32(wo, MTK_WED_WO_CCIF_RCHNUM);
-+
-+ return val & MTK_WED_WO_CCIF_RCHNUM_MASK;
-+}
-+
-+static void
-+mtk_wed_wo_set_isr(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_IRQ0_MASK, mask);
-+}
-+
-+static void
-+mtk_wed_wo_set_ack(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_ACK, mask);
-+}
-+
-+static void
-+mtk_wed_wo_set_isr_mask(struct mtk_wed_wo *wo, u32 mask, u32 val, bool set)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&wo->mmio.lock, flags);
-+ wo->mmio.irq_mask &= ~mask;
-+ wo->mmio.irq_mask |= val;
-+ if (set)
-+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask);
-+ spin_unlock_irqrestore(&wo->mmio.lock, flags);
-+}
-+
-+static void
-+mtk_wed_wo_irq_enable(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_wo_set_isr_mask(wo, 0, mask, false);
-+ tasklet_schedule(&wo->mmio.irq_tasklet);
-+}
-+
-+static void
-+mtk_wed_wo_irq_disable(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_wo_set_isr_mask(wo, mask, 0, true);
-+}
-+
-+static void
-+mtk_wed_wo_kickout(struct mtk_wed_wo *wo)
-+{
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_BUSY, 1 << MTK_WED_WO_TXCH_NUM);
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_TCHNUM, MTK_WED_WO_TXCH_NUM);
-+}
-+
-+static void
-+mtk_wed_wo_queue_kick(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ u32 val)
-+{
-+ wmb();
-+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, val);
-+}
-+
-+static void *
-+mtk_wed_wo_dequeue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, u32 *len,
-+ bool flush)
-+{
-+ int buf_len = SKB_WITH_OVERHEAD(q->buf_size);
-+ int index = (q->tail + 1) % q->n_desc;
-+ struct mtk_wed_wo_queue_entry *entry;
-+ struct mtk_wed_wo_queue_desc *desc;
-+ void *buf;
-+
-+ if (!q->queued)
-+ return NULL;
-+
-+ if (flush)
-+ q->desc[index].ctrl |= cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE);
-+ else if (!(q->desc[index].ctrl & cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE)))
-+ return NULL;
-+
-+ q->tail = index;
-+ q->queued--;
-+
-+ desc = &q->desc[index];
-+ entry = &q->entry[index];
-+ buf = entry->buf;
-+ if (len)
-+ *len = FIELD_GET(MTK_WED_WO_CTL_SD_LEN0,
-+ le32_to_cpu(READ_ONCE(desc->ctrl)));
-+ if (buf)
-+ dma_unmap_single(wo->hw->dev, entry->addr, buf_len,
-+ DMA_FROM_DEVICE);
-+ entry->buf = NULL;
-+
-+ return buf;
-+}
-+
-+static int
-+mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ gfp_t gfp, bool rx)
-+{
-+ enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-+ int n_buf = 0;
-+
-+ spin_lock_bh(&q->lock);
-+ while (q->queued < q->n_desc) {
-+ void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp);
-+ struct mtk_wed_wo_queue_entry *entry;
-+ dma_addr_t addr;
-+
-+ if (!buf)
-+ break;
-+
-+ addr = dma_map_single(wo->hw->dev, buf, q->buf_size, dir);
-+ if (unlikely(dma_mapping_error(wo->hw->dev, addr))) {
-+ skb_free_frag(buf);
-+ break;
-+ }
-+
-+ q->head = (q->head + 1) % q->n_desc;
-+ entry = &q->entry[q->head];
-+ entry->addr = addr;
-+ entry->len = q->buf_size;
-+ q->entry[q->head].buf = buf;
-+
-+ if (rx) {
-+ struct mtk_wed_wo_queue_desc *desc = &q->desc[q->head];
-+ u32 ctrl = MTK_WED_WO_CTL_LAST_SEC0 |
-+ FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0,
-+ entry->len);
-+
-+ WRITE_ONCE(desc->buf0, cpu_to_le32(addr));
-+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
-+ }
-+ q->queued++;
-+ n_buf++;
-+ }
-+ spin_unlock_bh(&q->lock);
-+
-+ return n_buf;
-+}
-+
-+static void
-+mtk_wed_wo_rx_complete(struct mtk_wed_wo *wo)
-+{
-+ mtk_wed_wo_set_ack(wo, MTK_WED_WO_RXCH_INT_MASK);
-+ mtk_wed_wo_irq_enable(wo, MTK_WED_WO_RXCH_INT_MASK);
-+}
-+
-+static void
-+mtk_wed_wo_rx_run_queue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ for (;;) {
-+ struct mtk_wed_mcu_hdr *hdr;
-+ struct sk_buff *skb;
-+ void *data;
-+ u32 len;
-+
-+ data = mtk_wed_wo_dequeue(wo, q, &len, false);
-+ if (!data)
-+ break;
-+
-+ skb = build_skb(data, q->buf_size);
-+ if (!skb) {
-+ skb_free_frag(data);
-+ continue;
-+ }
-+
-+ __skb_put(skb, len);
-+ if (mtk_wed_mcu_check_msg(wo, skb)) {
-+ dev_kfree_skb(skb);
-+ continue;
-+ }
-+
-+ hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+ if (hdr->flag & cpu_to_le16(MTK_WED_WARP_CMD_FLAG_RSP))
-+ mtk_wed_mcu_rx_event(wo, skb);
-+ else
-+ mtk_wed_mcu_rx_unsolicited_event(wo, skb);
-+ }
-+
-+ if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) {
-+ u32 index = (q->head - 1) % q->n_desc;
-+
-+ mtk_wed_wo_queue_kick(wo, q, index);
-+ }
-+}
-+
-+static irqreturn_t
-+mtk_wed_wo_irq_handler(int irq, void *data)
-+{
-+ struct mtk_wed_wo *wo = data;
-+
-+ mtk_wed_wo_set_isr(wo, 0);
-+ tasklet_schedule(&wo->mmio.irq_tasklet);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void mtk_wed_wo_irq_tasklet(struct tasklet_struct *t)
-+{
-+ struct mtk_wed_wo *wo = from_tasklet(wo, t, mmio.irq_tasklet);
-+ u32 intr, mask;
-+
-+ /* disable interrupts */
-+ mtk_wed_wo_set_isr(wo, 0);
-+
-+ intr = mtk_wed_wo_get_isr(wo);
-+ intr &= wo->mmio.irq_mask;
-+ mask = intr & (MTK_WED_WO_RXCH_INT_MASK | MTK_WED_WO_EXCEPTION_INT_MASK);
-+ mtk_wed_wo_irq_disable(wo, mask);
-+
-+ if (intr & MTK_WED_WO_RXCH_INT_MASK) {
-+ mtk_wed_wo_rx_run_queue(wo, &wo->q_rx);
-+ mtk_wed_wo_rx_complete(wo);
-+ }
-+}
-+
-+/* mtk wed wo hw queues */
-+
-+static int
-+mtk_wed_wo_queue_alloc(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ int n_desc, int buf_size, int index,
-+ struct mtk_wed_wo_queue_regs *regs)
-+{
-+ spin_lock_init(&q->lock);
-+ q->regs = *regs;
-+ q->n_desc = n_desc;
-+ q->buf_size = buf_size;
-+
-+ q->desc = dmam_alloc_coherent(wo->hw->dev, n_desc * sizeof(*q->desc),
-+ &q->desc_dma, GFP_KERNEL);
-+ if (!q->desc)
-+ return -ENOMEM;
-+
-+ q->entry = devm_kzalloc(wo->hw->dev, n_desc * sizeof(*q->entry),
-+ GFP_KERNEL);
-+ if (!q->entry)
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_wo_queue_free(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0);
-+ dma_free_coherent(wo->hw->dev, q->n_desc * sizeof(*q->desc), q->desc,
-+ q->desc_dma);
-+}
-+
-+static void
-+mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ struct page *page;
-+ int i;
-+
-+ spin_lock_bh(&q->lock);
-+ for (i = 0; i < q->n_desc; i++) {
-+ struct mtk_wed_wo_queue_entry *entry = &q->entry[i];
-+
-+ dma_unmap_single(wo->hw->dev, entry->addr, entry->len,
-+ DMA_TO_DEVICE);
-+ skb_free_frag(entry->buf);
-+ entry->buf = NULL;
-+ }
-+ spin_unlock_bh(&q->lock);
-+
-+ if (!q->cache.va)
-+ return;
-+
-+ page = virt_to_page(q->cache.va);
-+ __page_frag_cache_drain(page, q->cache.pagecnt_bias);
-+ memset(&q->cache, 0, sizeof(q->cache));
-+}
-+
-+static void
-+mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ struct page *page;
-+
-+ spin_lock_bh(&q->lock);
-+ for (;;) {
-+ void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
-+
-+ if (!buf)
-+ break;
-+
-+ skb_free_frag(buf);
-+ }
-+ spin_unlock_bh(&q->lock);
-+
-+ if (!q->cache.va)
-+ return;
-+
-+ page = virt_to_page(q->cache.va);
-+ __page_frag_cache_drain(page, q->cache.pagecnt_bias);
-+ memset(&q->cache, 0, sizeof(q->cache));
-+}
-+
-+static void
-+mtk_wed_wo_queue_reset(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0);
-+ mtk_wed_mmio_w32(wo, q->regs.desc_base, q->desc_dma);
-+ mtk_wed_mmio_w32(wo, q->regs.ring_size, q->n_desc);
-+}
-+
-+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ struct sk_buff *skb)
-+{
-+ struct mtk_wed_wo_queue_entry *entry;
-+ struct mtk_wed_wo_queue_desc *desc;
-+ int ret = 0, index;
-+ u32 ctrl;
-+
-+ spin_lock_bh(&q->lock);
-+
-+ q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx);
-+ index = (q->head + 1) % q->n_desc;
-+ if (q->tail == index) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ entry = &q->entry[index];
-+ if (skb->len > entry->len) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ desc = &q->desc[index];
-+ q->head = index;
-+
-+ dma_sync_single_for_cpu(wo->hw->dev, entry->addr, skb->len,
-+ DMA_TO_DEVICE);
-+ memcpy(entry->buf, skb->data, skb->len);
-+ dma_sync_single_for_device(wo->hw->dev, entry->addr, skb->len,
-+ DMA_TO_DEVICE);
-+
-+ ctrl = FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, skb->len) |
-+ MTK_WED_WO_CTL_LAST_SEC0 | MTK_WED_WO_CTL_DMA_DONE;
-+ WRITE_ONCE(desc->buf0, cpu_to_le32(entry->addr));
-+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
-+
-+ mtk_wed_wo_queue_kick(wo, q, q->head);
-+ mtk_wed_wo_kickout(wo);
-+out:
-+ spin_unlock_bh(&q->lock);
-+
-+ dev_kfree_skb(skb);
-+
-+ return ret;
-+}
-+
-+static int
-+mtk_wed_wo_exception_init(struct mtk_wed_wo *wo)
-+{
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_wo_hardware_init(struct mtk_wed_wo *wo)
-+{
-+ struct mtk_wed_wo_queue_regs regs;
-+ struct device_node *np;
-+ int ret;
-+
-+ np = of_parse_phandle(wo->hw->node, "mediatek,wo-ccif", 0);
-+ if (!np)
-+ return -ENODEV;
-+
-+ wo->mmio.regs = syscon_regmap_lookup_by_phandle(np, NULL);
-+ if (IS_ERR_OR_NULL(wo->mmio.regs))
-+ return PTR_ERR(wo->mmio.regs);
-+
-+ wo->mmio.irq = irq_of_parse_and_map(np, 0);
-+ wo->mmio.irq_mask = MTK_WED_WO_ALL_INT_MASK;
-+ spin_lock_init(&wo->mmio.lock);
-+ tasklet_setup(&wo->mmio.irq_tasklet, mtk_wed_wo_irq_tasklet);
-+
-+ ret = devm_request_irq(wo->hw->dev, wo->mmio.irq,
-+ mtk_wed_wo_irq_handler, IRQF_TRIGGER_HIGH,
-+ KBUILD_MODNAME, wo);
-+ if (ret)
-+ goto error;
-+
-+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY1;
-+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY2;
-+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW4;
-+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY3;
-+
-+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_tx, MTK_WED_WO_RING_SIZE,
-+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_TXCH_NUM,
-+ &regs);
-+ if (ret)
-+ goto error;
-+
-+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false);
-+ mtk_wed_wo_queue_reset(wo, &wo->q_tx);
-+
-+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY5;
-+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY6;
-+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW8;
-+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY7;
-+
-+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_rx, MTK_WED_WO_RING_SIZE,
-+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_RXCH_NUM,
-+ &regs);
-+ if (ret)
-+ goto error;
-+
-+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true);
-+ mtk_wed_wo_queue_reset(wo, &wo->q_rx);
-+
-+ /* rx queue irqmask */
-+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask);
-+
-+ return 0;
-+
-+error:
-+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo);
-+
-+ return ret;
-+}
-+
-+static void
-+mtk_wed_wo_hw_deinit(struct mtk_wed_wo *wo)
-+{
-+ /* disable interrupts */
-+ mtk_wed_wo_set_isr(wo, 0);
-+
-+ tasklet_disable(&wo->mmio.irq_tasklet);
-+
-+ disable_irq(wo->mmio.irq);
-+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo);
-+
-+ mtk_wed_wo_queue_tx_clean(wo, &wo->q_tx);
-+ mtk_wed_wo_queue_rx_clean(wo, &wo->q_rx);
-+ mtk_wed_wo_queue_free(wo, &wo->q_tx);
-+ mtk_wed_wo_queue_free(wo, &wo->q_rx);
-+}
-+
-+int mtk_wed_wo_init(struct mtk_wed_hw *hw)
-+{
-+ struct mtk_wed_wo *wo;
-+ int ret;
-+
-+ wo = devm_kzalloc(hw->dev, sizeof(*wo), GFP_KERNEL);
-+ if (!wo)
-+ return -ENOMEM;
-+
-+ hw->wed_wo = wo;
-+ wo->hw = hw;
-+
-+ ret = mtk_wed_wo_hardware_init(wo);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_wed_mcu_init(wo);
-+ if (ret)
-+ return ret;
-+
-+ return mtk_wed_wo_exception_init(wo);
-+}
-+
-+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw)
-+{
-+ struct mtk_wed_wo *wo = hw->wed_wo;
-+
-+ mtk_wed_wo_hw_deinit(wo);
-+}
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -80,6 +80,54 @@ enum mtk_wed_dummy_cr_idx {
- #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5)
- #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0)
-
-+#define MTK_WED_WO_RING_SIZE 256
-+#define MTK_WED_WO_CMD_LEN 1504
-+
-+#define MTK_WED_WO_TXCH_NUM 0
-+#define MTK_WED_WO_RXCH_NUM 1
-+#define MTK_WED_WO_RXCH_WO_EXCEPTION 7
-+
-+#define MTK_WED_WO_TXCH_INT_MASK BIT(0)
-+#define MTK_WED_WO_RXCH_INT_MASK BIT(1)
-+#define MTK_WED_WO_EXCEPTION_INT_MASK BIT(7)
-+#define MTK_WED_WO_ALL_INT_MASK (MTK_WED_WO_RXCH_INT_MASK | \
-+ MTK_WED_WO_EXCEPTION_INT_MASK)
-+
-+#define MTK_WED_WO_CCIF_BUSY 0x004
-+#define MTK_WED_WO_CCIF_START 0x008
-+#define MTK_WED_WO_CCIF_TCHNUM 0x00c
-+#define MTK_WED_WO_CCIF_RCHNUM 0x010
-+#define MTK_WED_WO_CCIF_RCHNUM_MASK GENMASK(7, 0)
-+
-+#define MTK_WED_WO_CCIF_ACK 0x014
-+#define MTK_WED_WO_CCIF_IRQ0_MASK 0x018
-+#define MTK_WED_WO_CCIF_IRQ1_MASK 0x01c
-+#define MTK_WED_WO_CCIF_DUMMY1 0x020
-+#define MTK_WED_WO_CCIF_DUMMY2 0x024
-+#define MTK_WED_WO_CCIF_DUMMY3 0x028
-+#define MTK_WED_WO_CCIF_DUMMY4 0x02c
-+#define MTK_WED_WO_CCIF_SHADOW1 0x030
-+#define MTK_WED_WO_CCIF_SHADOW2 0x034
-+#define MTK_WED_WO_CCIF_SHADOW3 0x038
-+#define MTK_WED_WO_CCIF_SHADOW4 0x03c
-+#define MTK_WED_WO_CCIF_DUMMY5 0x050
-+#define MTK_WED_WO_CCIF_DUMMY6 0x054
-+#define MTK_WED_WO_CCIF_DUMMY7 0x058
-+#define MTK_WED_WO_CCIF_DUMMY8 0x05c
-+#define MTK_WED_WO_CCIF_SHADOW5 0x060
-+#define MTK_WED_WO_CCIF_SHADOW6 0x064
-+#define MTK_WED_WO_CCIF_SHADOW7 0x068
-+#define MTK_WED_WO_CCIF_SHADOW8 0x06c
-+
-+#define MTK_WED_WO_CTL_SD_LEN1 GENMASK(13, 0)
-+#define MTK_WED_WO_CTL_LAST_SEC1 BIT(14)
-+#define MTK_WED_WO_CTL_BURST BIT(15)
-+#define MTK_WED_WO_CTL_SD_LEN0_SHIFT 16
-+#define MTK_WED_WO_CTL_SD_LEN0 GENMASK(29, 16)
-+#define MTK_WED_WO_CTL_LAST_SEC0 BIT(30)
-+#define MTK_WED_WO_CTL_DMA_DONE BIT(31)
-+#define MTK_WED_WO_INFO_WINFO GENMASK(15, 0)
-+
- struct mtk_wed_wo_memory_region {
- const char *name;
- void __iomem *addr;
-@@ -112,10 +160,53 @@ struct mtk_wed_fw_trailer {
- u32 crc;
- };
-
-+struct mtk_wed_wo_queue_regs {
-+ u32 desc_base;
-+ u32 ring_size;
-+ u32 cpu_idx;
-+ u32 dma_idx;
-+};
-+
-+struct mtk_wed_wo_queue_desc {
-+ __le32 buf0;
-+ __le32 ctrl;
-+ __le32 buf1;
-+ __le32 info;
-+ __le32 reserved[4];
-+} __packed __aligned(32);
-+
-+struct mtk_wed_wo_queue_entry {
-+ dma_addr_t addr;
-+ void *buf;
-+ u32 len;
-+};
-+
-+struct mtk_wed_wo_queue {
-+ struct mtk_wed_wo_queue_regs regs;
-+
-+ struct page_frag_cache cache;
-+ spinlock_t lock;
-+
-+ struct mtk_wed_wo_queue_desc *desc;
-+ dma_addr_t desc_dma;
-+
-+ struct mtk_wed_wo_queue_entry *entry;
-+
-+ u16 head;
-+ u16 tail;
-+ int n_desc;
-+ int queued;
-+ int buf_size;
-+
-+};
-+
- struct mtk_wed_wo {
- struct mtk_wed_hw *hw;
- struct mtk_wed_wo_memory_region boot;
-
-+ struct mtk_wed_wo_queue q_tx;
-+ struct mtk_wed_wo_queue q_rx;
-+
- struct {
- struct mutex mutex;
- int timeout;
-@@ -124,6 +215,15 @@ struct mtk_wed_wo {
- struct sk_buff_head res_q;
- wait_queue_head_t wait;
- } mcu;
-+
-+ struct {
-+ struct regmap *regs;
-+
-+ spinlock_t lock;
-+ struct tasklet_struct irq_tasklet;
-+ int irq;
-+ u32 irq_mask;
-+ } mmio;
- };
-
- static inline int
-@@ -146,5 +246,9 @@ void mtk_wed_mcu_rx_unsolicited_event(st
- int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
- const void *data, int len, bool wait_resp);
- int mtk_wed_mcu_init(struct mtk_wed_wo *wo);
-+int mtk_wed_wo_init(struct mtk_wed_hw *hw);
-+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw);
-+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *dev, struct mtk_wed_wo_queue *q,
-+ struct sk_buff *skb);
-
- #endif /* __MTK_WED_WO_H */
diff --git a/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch b/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch
deleted file mode 100644
index a002a5f851..0000000000
--- a/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:20 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: rename tx_wdma array in rx_wdma
-
-Rename tx_wdma queue array in rx_wdma since this is rx side of wdma soc.
-Moreover rename mtk_wed_wdma_ring_setup routine in
-mtk_wed_wdma_rx_ring_setup()
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -253,8 +253,8 @@ mtk_wed_free_tx_rings(struct mtk_wed_dev
-
- for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
- mtk_wed_free_ring(dev, &dev->tx_ring[i]);
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
-+ mtk_wed_free_ring(dev, &dev->rx_wdma[i]);
- }
-
- static void
-@@ -688,10 +688,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device
- }
-
- static int
--mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
-- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
-+ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
-
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size))
- return -ENOMEM;
-@@ -805,9 +805,9 @@ mtk_wed_start(struct mtk_wed_device *dev
- {
- int i;
-
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- if (!dev->tx_wdma[i].desc)
-- mtk_wed_wdma_ring_setup(dev, i, 16);
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
-+ if (!dev->rx_wdma[i].desc)
-+ mtk_wed_wdma_rx_ring_setup(dev, i, 16);
-
- mtk_wed_hw_init(dev);
- mtk_wed_configure_irq(dev, irq_mask);
-@@ -916,7 +916,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- sizeof(*ring->desc)))
- return -ENOMEM;
-
-- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
- return -ENOMEM;
-
- ring->reg_base = MTK_WED_RING_TX(idx);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -7,6 +7,7 @@
- #include <linux/pci.h>
-
- #define MTK_WED_TX_QUEUES 2
-+#define MTK_WED_RX_QUEUES 2
-
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-@@ -66,7 +67,7 @@ struct mtk_wed_device {
-
- struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring txfree_ring;
-- struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
-+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-
- struct {
- int size;
diff --git a/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch b/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch
deleted file mode 100644
index eca29739b4..0000000000
--- a/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch
+++ /dev/null
@@ -1,1521 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:21 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add configure wed wo support
-
-Enable RX Wireless Ethernet Dispatch available on MT7986 Soc.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -9,6 +9,7 @@
- #include <linux/skbuff.h>
- #include <linux/of_platform.h>
- #include <linux/of_address.h>
-+#include <linux/of_reserved_mem.h>
- #include <linux/mfd/syscon.h>
- #include <linux/debugfs.h>
- #include <linux/soc/mediatek/mtk_wed.h>
-@@ -23,6 +24,7 @@
- #define MTK_WED_PKT_SIZE 1900
- #define MTK_WED_BUF_SIZE 2048
- #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
-+#define MTK_WED_RX_RING_SIZE 1536
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 1024
-@@ -31,6 +33,10 @@
- #define MTK_WED_PER_GROUP_PKT 128
-
- #define MTK_WED_FBUF_SIZE 128
-+#define MTK_WED_MIOD_CNT 16
-+#define MTK_WED_FB_CMD_CNT 1024
-+#define MTK_WED_RRO_QUE_CNT 8192
-+#define MTK_WED_MIOD_ENTRY_CNT 128
-
- static struct mtk_wed_hw *hw_list[2];
- static DEFINE_MUTEX(hw_lock);
-@@ -65,12 +71,76 @@ wdma_set(struct mtk_wed_device *dev, u32
- wdma_m32(dev, reg, 0, mask);
- }
-
-+static void
-+wdma_clr(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ wdma_m32(dev, reg, mask, 0);
-+}
-+
-+static u32
-+wifi_r32(struct mtk_wed_device *dev, u32 reg)
-+{
-+ return readl(dev->wlan.base + reg);
-+}
-+
-+static void
-+wifi_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
-+{
-+ writel(val, dev->wlan.base + reg);
-+}
-+
- static u32
- mtk_wed_read_reset(struct mtk_wed_device *dev)
- {
- return wed_r32(dev, MTK_WED_RESET);
- }
-
-+static u32
-+mtk_wdma_read_reset(struct mtk_wed_device *dev)
-+{
-+ return wdma_r32(dev, MTK_WDMA_GLO_CFG);
-+}
-+
-+static void
-+mtk_wdma_rx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
-+ int i;
-+
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
-+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 1000))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
-+ if (dev->rx_wdma[i].desc)
-+ continue;
-+
-+ wdma_w32(dev,
-+ MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+ }
-+}
-+
-+static void
-+mtk_wdma_tx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
-+ int i;
-+
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 1000))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
-+ if (dev->tx_wdma[i].desc)
-+ continue;
-+
-+ wdma_w32(dev,
-+ MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+ }
-+}
-+
- static void
- mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
- {
-@@ -82,6 +152,54 @@ mtk_wed_reset(struct mtk_wed_device *dev
- WARN_ON_ONCE(1);
- }
-
-+static u32
-+mtk_wed_wo_read_status(struct mtk_wed_device *dev)
-+{
-+ return wed_r32(dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_WO_STATUS);
-+}
-+
-+static void
-+mtk_wed_wo_reset(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ u8 state = MTK_WED_WO_STATE_DISABLE;
-+ void __iomem *reg;
-+ u32 val;
-+
-+ mtk_wdma_tx_reset(dev);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+
-+ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &state,
-+ sizeof(state), false);
-+
-+ if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val,
-+ val == MTK_WED_WOIF_DISABLE_DONE,
-+ 100, MTK_WOCPU_TIMEOUT))
-+ dev_err(dev->hw->dev, "failed to disable wed-wo\n");
-+
-+ reg = ioremap(MTK_WED_WO_CPU_MCUSYS_RESET_ADDR, 4);
-+
-+ val = readl(reg);
-+ switch (dev->hw->index) {
-+ case 0:
-+ val |= MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ val &= ~MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ break;
-+ case 1:
-+ val |= MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ val &= ~MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ break;
-+ default:
-+ break;
-+ }
-+ iounmap(reg);
-+}
-+
- static struct mtk_wed_hw *
- mtk_wed_assign(struct mtk_wed_device *dev)
- {
-@@ -116,7 +234,7 @@ out:
- }
-
- static int
--mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
-+mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-@@ -133,16 +251,16 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi
- if (!page_list)
- return -ENOMEM;
-
-- dev->buf_ring.size = ring_size;
-- dev->buf_ring.pages = page_list;
-+ dev->tx_buf_ring.size = ring_size;
-+ dev->tx_buf_ring.pages = page_list;
-
- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
- &desc_phys, GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
-- dev->buf_ring.desc = desc;
-- dev->buf_ring.desc_phys = desc_phys;
-+ dev->tx_buf_ring.desc = desc;
-+ dev->tx_buf_ring.desc_phys = desc_phys;
-
- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
- dma_addr_t page_phys, buf_phys;
-@@ -203,10 +321,10 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi
- }
-
- static void
--mtk_wed_free_buffer(struct mtk_wed_device *dev)
-+mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
- {
-- struct mtk_wdma_desc *desc = dev->buf_ring.desc;
-- void **page_list = dev->buf_ring.pages;
-+ struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
-+ void **page_list = dev->tx_buf_ring.pages;
- int page_idx;
- int i;
-
-@@ -216,7 +334,8 @@ mtk_wed_free_buffer(struct mtk_wed_devic
- if (!desc)
- goto free_pagelist;
-
-- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
-+ for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size;
-+ i += MTK_WED_BUF_PER_PAGE) {
- void *page = page_list[page_idx++];
- dma_addr_t buf_addr;
-
-@@ -229,13 +348,59 @@ mtk_wed_free_buffer(struct mtk_wed_devic
- __free_page(page);
- }
-
-- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc),
-- desc, dev->buf_ring.desc_phys);
-+ dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc),
-+ desc, dev->tx_buf_ring.desc_phys);
-
- free_pagelist:
- kfree(page_list);
- }
-
-+static int
-+mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ struct mtk_rxbm_desc *desc;
-+ dma_addr_t desc_phys;
-+
-+ dev->rx_buf_ring.size = dev->wlan.rx_nbuf;
-+ desc = dma_alloc_coherent(dev->hw->dev,
-+ dev->wlan.rx_nbuf * sizeof(*desc),
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc)
-+ return -ENOMEM;
-+
-+ dev->rx_buf_ring.desc = desc;
-+ dev->rx_buf_ring.desc_phys = desc_phys;
-+ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
-+
-+ if (!desc)
-+ return;
-+
-+ dev->wlan.release_rx_buf(dev);
-+ dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc),
-+ desc, dev->rx_buf_ring.desc_phys);
-+}
-+
-+static void
-+mtk_wed_rx_buffer_hw_init(struct mtk_wed_device *dev)
-+{
-+ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD,
-+ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size));
-+ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys);
-+ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL |
-+ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt));
-+ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
-+ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+}
-+
- static void
- mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
- {
-@@ -247,6 +412,13 @@ mtk_wed_free_ring(struct mtk_wed_device
- }
-
- static void
-+mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
-+{
-+ mtk_wed_free_rx_buffer(dev);
-+ mtk_wed_free_ring(dev, &dev->rro.ring);
-+}
-+
-+static void
- mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
- {
- int i;
-@@ -291,6 +463,38 @@ mtk_wed_set_512_support(struct mtk_wed_d
- }
- }
-
-+#define MTK_WFMDA_RX_DMA_EN BIT(2)
-+static void
-+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
-+{
-+ u32 val;
-+ int i;
-+
-+ if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED))
-+ return; /* queue is not configured by mt76 */
-+
-+ for (i = 0; i < 3; i++) {
-+ u32 cur_idx;
-+
-+ cur_idx = wed_r32(dev,
-+ MTK_WED_WPDMA_RING_RX_DATA(idx) +
-+ MTK_WED_RING_OFS_CPU_IDX);
-+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
-+ break;
-+
-+ usleep_range(100000, 200000);
-+ }
-+
-+ if (i == 3) {
-+ dev_err(dev->hw->dev, "rx dma enable failed\n");
-+ return;
-+ }
-+
-+ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) |
-+ MTK_WFMDA_RX_DMA_EN;
-+ wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val);
-+}
-+
- static void
- mtk_wed_dma_disable(struct mtk_wed_device *dev)
- {
-@@ -304,20 +508,25 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WED_GLO_CFG_TX_DMA_EN |
- MTK_WED_GLO_CFG_RX_DMA_EN);
-
-- wdma_m32(dev, MTK_WDMA_GLO_CFG,
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_TX_DMA_EN |
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0);
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-
- if (dev->hw->version == 1) {
- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
-- wdma_m32(dev, MTK_WDMA_GLO_CFG,
-- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0);
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_EN);
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+
- mtk_wed_set_512_support(dev, false);
- }
- }
-@@ -338,6 +547,13 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
- wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-+
-+ if (dev->hw->version == 1)
-+ return;
-+
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
- }
-
- static void
-@@ -353,11 +569,21 @@ mtk_wed_detach(struct mtk_wed_device *de
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-+ }
-
-- mtk_wed_free_buffer(dev);
-+ mtk_wed_free_tx_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-- if (hw->version != 1)
-+
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ mtk_wed_wo_reset(dev);
-+ mtk_wed_free_rx_rings(dev);
- mtk_wed_wo_deinit(hw);
-+ mtk_wdma_rx_reset(dev);
-+ }
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
- struct device_node *wlan_node;
-@@ -434,10 +660,12 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- } else {
- mtk_wed_bus_init(dev);
-
-- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
- }
- }
-
-@@ -487,6 +715,132 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- }
- }
-
-+static int
-+mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-+ int size)
-+{
-+ ring->desc = dma_alloc_coherent(dev->hw->dev,
-+ size * sizeof(*ring->desc),
-+ &ring->desc_phys, GFP_KERNEL);
-+ if (!ring->desc)
-+ return -ENOMEM;
-+
-+ ring->desc_size = sizeof(*ring->desc);
-+ ring->size = size;
-+ memset(ring->desc, 0, size);
-+
-+ return 0;
-+}
-+
-+#define MTK_WED_MIOD_COUNT (MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT)
-+static int
-+mtk_wed_rro_alloc(struct mtk_wed_device *dev)
-+{
-+ struct reserved_mem *rmem;
-+ struct device_node *np;
-+ int index;
-+
-+ index = of_property_match_string(dev->hw->node, "memory-region-names",
-+ "wo-dlm");
-+ if (index < 0)
-+ return index;
-+
-+ np = of_parse_phandle(dev->hw->node, "memory-region", index);
-+ if (!np)
-+ return -ENODEV;
-+
-+ rmem = of_reserved_mem_lookup(np);
-+ of_node_put(np);
-+
-+ if (!rmem)
-+ return -ENODEV;
-+
-+ dev->rro.miod_phys = rmem->base;
-+ dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys;
-+
-+ return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring,
-+ MTK_WED_RRO_QUE_CNT);
-+}
-+
-+static int
-+mtk_wed_rro_cfg(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ struct {
-+ struct {
-+ __le32 base;
-+ __le32 cnt;
-+ __le32 unit;
-+ } ring[2];
-+ __le32 wed;
-+ u8 version;
-+ } req = {
-+ .ring[0] = {
-+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE),
-+ .cnt = cpu_to_le32(MTK_WED_MIOD_CNT),
-+ .unit = cpu_to_le32(MTK_WED_MIOD_ENTRY_CNT),
-+ },
-+ .ring[1] = {
-+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE +
-+ MTK_WED_MIOD_COUNT),
-+ .cnt = cpu_to_le32(MTK_WED_FB_CMD_CNT),
-+ .unit = cpu_to_le32(4),
-+ },
-+ };
-+
-+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_WED_CFG,
-+ &req, sizeof(req), true);
-+}
-+
-+static void
-+mtk_wed_rro_hw_init(struct mtk_wed_device *dev)
-+{
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CFG,
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_MID_DW, 0x70 >> 2) |
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_MOD_DW, 0x10 >> 2) |
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_ENTRY_DW,
-+ MTK_WED_MIOD_ENTRY_CNT >> 2));
-+
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_phys);
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL1,
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_CNT, MTK_WED_MIOD_CNT));
-+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_phys);
-+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL1,
-+ FIELD_PREP(MTK_WED_RROQM_FDBK_CNT, MTK_WED_FB_CMD_CNT));
-+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL2, 0);
-+ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.ring.desc_phys);
-+
-+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
-+ MTK_WED_RROQM_RST_IDX_MIOD |
-+ MTK_WED_RROQM_RST_IDX_FDBK);
-+
-+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL2, MTK_WED_MIOD_CNT - 1);
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
-+}
-+
-+static void
-+mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
-+{
-+ wed_w32(dev, MTK_WED_RESET, MTK_WED_RESET_RX_ROUTE_QM);
-+
-+ for (;;) {
-+ usleep_range(100, 200);
-+ if (!(wed_r32(dev, MTK_WED_RESET) & MTK_WED_RESET_RX_ROUTE_QM))
-+ break;
-+ }
-+
-+ /* configure RX_ROUTE_QM */
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ /* enable RX_ROUTE_QM */
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
-+}
-+
- static void
- mtk_wed_hw_init(struct mtk_wed_device *dev)
- {
-@@ -498,11 +852,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- wed_w32(dev, MTK_WED_TX_BM_CTRL,
- MTK_WED_TX_BM_CTRL_PAUSE |
- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-- dev->buf_ring.size / 128) |
-+ dev->tx_buf_ring.size / 128) |
- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
- MTK_WED_TX_RING_SIZE / 256));
-
-- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
-+ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys);
-
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
-@@ -529,9 +883,9 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- wed_w32(dev, MTK_WED_TX_TKID_CTRL,
- MTK_WED_TX_TKID_CTRL_PAUSE |
- FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM,
-- dev->buf_ring.size / 128) |
-+ dev->tx_buf_ring.size / 128) |
- FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
-- dev->buf_ring.size / 128));
-+ dev->tx_buf_ring.size / 128));
- wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
- FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
- MTK_WED_TX_TKID_DYN_THR_HI);
-@@ -539,18 +893,28 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-- if (dev->hw->version == 1)
-+ if (dev->hw->version == 1) {
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-- else
-+ } else {
- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
-+ /* rx hw init */
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+
-+ mtk_wed_rx_buffer_hw_init(dev);
-+ mtk_wed_rro_hw_init(dev);
-+ mtk_wed_route_qm_hw_init(dev);
-+ }
-
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
- }
-
- static void
--mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size)
-+mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx)
- {
- void *head = (void *)ring->desc;
- int i;
-@@ -560,7 +924,10 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
-
- desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size);
- desc->buf0 = 0;
-- desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ if (tx)
-+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ else
-+ desc->ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST);
- desc->buf1 = 0;
- desc->info = 0;
- }
-@@ -616,7 +983,8 @@ mtk_wed_reset_dma(struct mtk_wed_device
- if (!dev->tx_ring[i].desc)
- continue;
-
-- mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE);
-+ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE,
-+ true);
- }
-
- if (mtk_wed_poll_busy(dev))
-@@ -634,6 +1002,9 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-+ if (mtk_wed_get_rx_capa(dev))
-+ mtk_wdma_rx_reset(dev);
-+
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
-@@ -668,12 +1039,11 @@ mtk_wed_reset_dma(struct mtk_wed_device
- MTK_WED_WPDMA_RESET_IDX_RX);
- wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
- }
--
- }
-
- static int
- mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-- int size, u32 desc_size)
-+ int size, u32 desc_size, bool tx)
- {
- ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size,
- &ring->desc_phys, GFP_KERNEL);
-@@ -682,7 +1052,7 @@ mtk_wed_ring_alloc(struct mtk_wed_device
-
- ring->desc_size = desc_size;
- ring->size = size;
-- mtk_wed_ring_reset(ring, size);
-+ mtk_wed_ring_reset(ring, size, tx);
-
- return 0;
- }
-@@ -691,9 +1061,14 @@ static int
- mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
-- struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
-+ struct mtk_wed_ring *wdma;
-
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size))
-+ if (idx >= ARRAY_SIZE(dev->rx_wdma))
-+ return -EINVAL;
-+
-+ wdma = &dev->rx_wdma[idx];
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-+ true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -710,6 +1085,60 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
- return 0;
- }
-
-+static int
-+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+{
-+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
-+ struct mtk_wed_ring *wdma;
-+
-+ if (idx >= ARRAY_SIZE(dev->tx_wdma))
-+ return -EINVAL;
-+
-+ wdma = &dev->tx_wdma[idx];
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-+ true))
-+ return -ENOMEM;
-+
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-+ wdma->desc_phys);
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
-+ size);
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
-+
-+ if (!idx) {
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
-+ wdma->desc_phys);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_COUNT,
-+ size);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_CPU_IDX,
-+ 0);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_DMA_IDX,
-+ 0);
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
-+ u32 reason, u32 hash)
-+{
-+ struct mtk_eth *eth = dev->hw->eth;
-+ struct ethhdr *eh;
-+
-+ if (!skb)
-+ return;
-+
-+ if (reason != MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-+ return;
-+
-+ skb_set_mac_header(skb, 0);
-+ eh = eth_hdr(skb);
-+ skb->protocol = eh->h_proto;
-+ mtk_ppe_check_skb(eth->ppe[dev->hw->index], skb, hash);
-+}
-+
- static void
- mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
- {
-@@ -732,6 +1161,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev
-
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
-+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
-+ GENMASK(1, 0));
- /* initail tx interrupt trigger */
- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
- MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-@@ -750,6 +1181,16 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
- dev->wlan.txfree_tbit));
-
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-+ dev->wlan.rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-+ dev->wlan.rx_tbit[1]));
-+
- wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
- wed_set(dev, MTK_WED_WDMA_INT_CTRL,
- FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL,
-@@ -787,9 +1228,15 @@ mtk_wed_dma_enable(struct mtk_wed_device
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
-+ int i;
-+
- wed_set(dev, MTK_WED_WPDMA_CTRL,
- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+
- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-@@ -797,6 +1244,15 @@ mtk_wed_dma_enable(struct mtk_wed_device
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-+ 0x2));
-+
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-+ mtk_wed_check_wfdma_rx_fill(dev, i);
- }
- }
-
-@@ -822,7 +1278,19 @@ mtk_wed_start(struct mtk_wed_device *dev
- val |= BIT(0) | (BIT(1) * !!dev->hw->index);
- regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
- } else {
-- mtk_wed_set_512_support(dev, true);
-+ /* driver set mid ready and only once */
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK1,
-+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK2,
-+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-+
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK1);
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK2);
-+
-+ if (mtk_wed_rro_cfg(dev))
-+ return;
-+
-+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
- }
-
- mtk_wed_dma_enable(dev);
-@@ -856,7 +1324,7 @@ mtk_wed_attach(struct mtk_wed_device *de
- if (!hw) {
- module_put(THIS_MODULE);
- ret = -ENODEV;
-- goto out;
-+ goto unlock;
- }
-
- device = dev->wlan.bus_type == MTK_WED_BUS_PCIE
-@@ -869,15 +1337,24 @@ mtk_wed_attach(struct mtk_wed_device *de
- dev->dev = hw->dev;
- dev->irq = hw->irq;
- dev->wdma_idx = hw->index;
-+ dev->version = hw->version;
-
- if (hw->eth->dma_dev == hw->eth->dev &&
- of_dma_is_coherent(hw->eth->dev->of_node))
- mtk_eth_set_dma_device(hw->eth, hw->dev);
-
-- ret = mtk_wed_buffer_alloc(dev);
-- if (ret) {
-- mtk_wed_detach(dev);
-+ ret = mtk_wed_tx_buffer_alloc(dev);
-+ if (ret)
- goto out;
-+
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ ret = mtk_wed_rx_buffer_alloc(dev);
-+ if (ret)
-+ goto out;
-+
-+ ret = mtk_wed_rro_alloc(dev);
-+ if (ret)
-+ goto out;
- }
-
- mtk_wed_hw_init_early(dev);
-@@ -886,8 +1363,10 @@ mtk_wed_attach(struct mtk_wed_device *de
- BIT(hw->index), 0);
- else
- ret = mtk_wed_wo_init(hw);
--
- out:
-+ if (ret)
-+ mtk_wed_detach(dev);
-+unlock:
- mutex_unlock(&hw_lock);
-
- return ret;
-@@ -910,10 +1389,11 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- * WDMA RX.
- */
-
-- BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring));
-+ if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
-+ return -EINVAL;
-
- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-- sizeof(*ring->desc)))
-+ sizeof(*ring->desc), true))
- return -ENOMEM;
-
- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-@@ -960,6 +1440,37 @@ mtk_wed_txfree_ring_setup(struct mtk_wed
- return 0;
- }
-
-+static int
-+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_ring[idx];
-+
-+ if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
-+ return -EINVAL;
-+
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
-+ sizeof(*ring->desc), false))
-+ return -ENOMEM;
-+
-+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ return -ENOMEM;
-+
-+ ring->reg_base = MTK_WED_RING_RX_DATA(idx);
-+ ring->wpdma = regs;
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+
-+ /* WPDMA -> WED */
-+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
-+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_RX_RING_SIZE);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_BASE,
-+ ring->desc_phys);
-+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_COUNT,
-+ MTK_WED_RX_RING_SIZE);
-+
-+ return 0;
-+}
-+
- static u32
- mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
- {
-@@ -1056,7 +1567,9 @@ void mtk_wed_add_hw(struct device_node *
- static const struct mtk_wed_ops wed_ops = {
- .attach = mtk_wed_attach,
- .tx_ring_setup = mtk_wed_tx_ring_setup,
-+ .rx_ring_setup = mtk_wed_rx_ring_setup,
- .txfree_ring_setup = mtk_wed_txfree_ring_setup,
-+ .msg_update = mtk_wed_mcu_msg_update,
- .start = mtk_wed_start,
- .stop = mtk_wed_stop,
- .reset_dma = mtk_wed_reset_dma,
-@@ -1065,6 +1578,7 @@ void mtk_wed_add_hw(struct device_node *
- .irq_get = mtk_wed_irq_get,
- .irq_set_mask = mtk_wed_irq_set_mask,
- .detach = mtk_wed_detach,
-+ .ppe_check = mtk_wed_ppe_check,
- };
- struct device_node *eth_np = eth->dev->of_node;
- struct platform_device *pdev;
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -87,6 +87,24 @@ wpdma_tx_w32(struct mtk_wed_device *dev,
- }
-
- static inline u32
-+wpdma_rx_r32(struct mtk_wed_device *dev, int ring, u32 reg)
-+{
-+ if (!dev->rx_ring[ring].wpdma)
-+ return 0;
-+
-+ return readl(dev->rx_ring[ring].wpdma + reg);
-+}
-+
-+static inline void
-+wpdma_rx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val)
-+{
-+ if (!dev->rx_ring[ring].wpdma)
-+ return;
-+
-+ writel(val, dev->rx_ring[ring].wpdma + reg);
-+}
-+
-+static inline u32
- wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg)
- {
- if (!dev->txfree_ring.wpdma)
-@@ -128,6 +146,7 @@ static inline int mtk_wed_flow_add(int i
- static inline void mtk_wed_flow_remove(int index)
- {
- }
-+
- #endif
-
- #ifdef CONFIG_DEBUG_FS
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -10,6 +10,7 @@
- #include <linux/of_reserved_mem.h>
- #include <linux/mfd/syscon.h>
- #include <linux/soc/mediatek/mtk_wed.h>
-+#include <asm/unaligned.h>
-
- #include "mtk_wed_regs.h"
- #include "mtk_wed_wo.h"
-@@ -60,24 +61,37 @@ void mtk_wed_mcu_rx_event(struct mtk_wed
- wake_up(&wo->mcu.wait);
- }
-
-+static void
-+mtk_wed_update_rx_stats(struct mtk_wed_device *wed, struct sk_buff *skb)
-+{
-+ u32 count = get_unaligned_le32(skb->data);
-+ struct mtk_wed_wo_rx_stats *stats;
-+ int i;
-+
-+ if (count * sizeof(*stats) > skb->len - sizeof(u32))
-+ return;
-+
-+ stats = (struct mtk_wed_wo_rx_stats *)(skb->data + sizeof(u32));
-+ for (i = 0 ; i < count ; i++)
-+ wed->wlan.update_wo_rx_stats(wed, &stats[i]);
-+}
-+
- void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo,
- struct sk_buff *skb)
- {
- struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-
-- switch (hdr->cmd) {
-- case MTK_WED_WO_EVT_LOG_DUMP: {
-- const char *msg = (const char *)(skb->data + sizeof(*hdr));
-+ skb_pull(skb, sizeof(*hdr));
-
-- dev_notice(wo->hw->dev, "%s\n", msg);
-+ switch (hdr->cmd) {
-+ case MTK_WED_WO_EVT_LOG_DUMP:
-+ dev_notice(wo->hw->dev, "%s\n", skb->data);
- break;
-- }
- case MTK_WED_WO_EVT_PROFILING: {
-- struct mtk_wed_wo_log_info *info;
-- u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info);
-+ struct mtk_wed_wo_log_info *info = (void *)skb->data;
-+ u32 count = skb->len / sizeof(*info);
- int i;
-
-- info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr));
- for (i = 0 ; i < count ; i++)
- dev_notice(wo->hw->dev,
- "SN:%u latency: total=%u, rro:%u, mod:%u\n",
-@@ -88,6 +102,7 @@ void mtk_wed_mcu_rx_unsolicited_event(st
- break;
- }
- case MTK_WED_WO_EVT_RXCNT_INFO:
-+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb);
- break;
- default:
- break;
-@@ -144,6 +159,8 @@ mtk_wed_mcu_parse_response(struct mtk_we
- skb_pull(skb, sizeof(*hdr));
- switch (cmd) {
- case MTK_WED_WO_CMD_RXCNT_INFO:
-+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb);
-+ break;
- default:
- break;
- }
-@@ -182,6 +199,18 @@ unlock:
- return ret;
- }
-
-+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data,
-+ int len)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+
-+ if (dev->hw->version == 1)
-+ return 0;
-+
-+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len,
-+ true);
-+}
-+
- static int
- mtk_wed_get_memory_region(struct mtk_wed_wo *wo,
- struct mtk_wed_wo_memory_region *region)
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -4,6 +4,7 @@
- #ifndef __MTK_WED_REGS_H
- #define __MTK_WED_REGS_H
-
-+#define MTK_WFDMA_DESC_CTRL_TO_HOST BIT(8)
- #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0)
- #define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0)
- #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15)
-@@ -28,6 +29,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_WED_TX_DMA BIT(12)
- #define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
- #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
-+#define MTK_WED_RESET_RX_RRO_QM BIT(20)
-+#define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
- #define MTK_WED_RESET_WED BIT(31)
-
- #define MTK_WED_CTRL 0x00c
-@@ -39,8 +42,12 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11)
--#define MTK_WED_CTRL_RESERVE_EN BIT(12)
--#define MTK_WED_CTRL_RESERVE_BUSY BIT(13)
-+#define MTK_WED_CTRL_WED_RX_BM_EN BIT(12)
-+#define MTK_WED_CTRL_WED_RX_BM_BUSY BIT(13)
-+#define MTK_WED_CTRL_RX_RRO_QM_EN BIT(14)
-+#define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
-+#define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
-+#define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
- #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
- #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25)
- #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
-@@ -62,6 +69,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22)
- #define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_GET_BM_DMAD_SKIP BIT(25)
-+#define MTK_WED_EXT_INT_STATUS_WPDMA_RX_D_DRV_ERR BIT(26)
-+#define MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY BIT(27)
- #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
- MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
- MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
-@@ -71,6 +81,8 @@ struct mtk_wdma_desc {
- MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR)
-
- #define MTK_WED_EXT_INT_MASK 0x028
-+#define MTK_WED_EXT_INT_MASK1 0x02c
-+#define MTK_WED_EXT_INT_MASK2 0x030
-
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-@@ -151,6 +163,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10)
-
- #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10)
-+#define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
-
- #define MTK_WED_SCR0 0x3c0
- #define MTK_WED_WPDMA_INT_TRIGGER 0x504
-@@ -213,6 +226,12 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10)
-
- #define MTK_WED_WPDMA_INT_CTRL_RX 0x534
-+#define MTK_WED_WPDMA_INT_CTRL_RX0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RX0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RX1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RX1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG GENMASK(14, 10)
-
- #define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538
- #define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0)
-@@ -242,11 +261,34 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10)
- #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10)
-+#define MTK_WED_WPDMA_RING_RX_DATA(_n) (0x730 + (_n) * 0x10)
-+
-+#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
-+#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)
-+#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)
-+
-+#define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
-+#define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
-+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-+
-+#define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
-+#define MTK_WED_WPDMA_RX_RING 0x770
-+
-+#define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
-+
-+#define MTK_WED_WDMA_RING_TX 0x800
-+
-+#define MTK_WED_WDMA_TX_MIB 0x810
-+
- #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
- #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
-
- #define MTK_WED_WDMA_GLO_CFG 0xa04
- #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
-+#define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
- #define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2)
- #define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3)
- #define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4)
-@@ -291,6 +333,20 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4)
- #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4)
-
-+#define MTK_WED_RX_BM_RX_DMAD 0xd80
-+#define MTK_WED_RX_BM_RX_DMAD_SDL0 GENMASK(13, 0)
-+
-+#define MTK_WED_RX_BM_BASE 0xd84
-+#define MTK_WED_RX_BM_INIT_PTR 0xd88
-+#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0)
-+#define MTK_WED_RX_BM_INIT_SW_TAIL BIT(16)
-+
-+#define MTK_WED_RX_PTR 0xd8c
-+
-+#define MTK_WED_RX_BM_DYN_ALLOC_TH 0xdb4
-+#define MTK_WED_RX_BM_DYN_ALLOC_TH_H GENMASK(31, 16)
-+#define MTK_WED_RX_BM_DYN_ALLOC_TH_L GENMASK(15, 0)
-+
- #define MTK_WED_RING_OFS_BASE 0x00
- #define MTK_WED_RING_OFS_COUNT 0x04
- #define MTK_WED_RING_OFS_CPU_IDX 0x08
-@@ -301,7 +357,9 @@ struct mtk_wdma_desc {
-
- #define MTK_WDMA_GLO_CFG 0x204
- #define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0)
-+#define MTK_WDMA_GLO_CFG_TX_DMA_BUSY BIT(1)
- #define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2)
-+#define MTK_WDMA_GLO_CFG_RX_DMA_BUSY BIT(3)
- #define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26)
- #define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27)
- #define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28)
-@@ -330,4 +388,70 @@ struct mtk_wdma_desc {
- /* DMA channel mapping */
- #define HIFSYS_DMA_AG_MAP 0x008
-
-+#define MTK_WED_RTQM_GLO_CFG 0xb00
-+#define MTK_WED_RTQM_BUSY BIT(1)
-+#define MTK_WED_RTQM_Q_RST BIT(2)
-+#define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
-+#define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-+
-+#define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
-+#define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
-+#define MTK_WED_RTQM_Q2N_MIB 0xb80
-+#define MTK_WED_RTQM_Q2H_MIB(_n) (0xb84 + (_n) * 0x4)
-+
-+#define MTK_WED_RTQM_Q2B_MIB 0xb8c
-+#define MTK_WED_RTQM_PFDBK_MIB 0xb90
-+
-+#define MTK_WED_RROQM_GLO_CFG 0xc04
-+#define MTK_WED_RROQM_RST_IDX 0xc08
-+#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
-+#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4)
-+
-+#define MTK_WED_RROQM_MIOD_CTRL0 0xc40
-+#define MTK_WED_RROQM_MIOD_CTRL1 0xc44
-+#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0)
-+
-+#define MTK_WED_RROQM_MIOD_CTRL2 0xc48
-+#define MTK_WED_RROQM_MIOD_CTRL3 0xc4c
-+
-+#define MTK_WED_RROQM_FDBK_CTRL0 0xc50
-+#define MTK_WED_RROQM_FDBK_CTRL1 0xc54
-+#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0)
-+
-+#define MTK_WED_RROQM_FDBK_CTRL2 0xc58
-+
-+#define MTK_WED_RROQ_BASE_L 0xc80
-+#define MTK_WED_RROQ_BASE_H 0xc84
-+
-+#define MTK_WED_RROQM_MIOD_CFG 0xc8c
-+#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0)
-+#define MTK_WED_RROQM_MIOD_MOD_DW GENMASK(13, 8)
-+#define MTK_WED_RROQM_MIOD_ENTRY_DW GENMASK(22, 16)
-+
-+#define MTK_WED_RROQM_MID_MIB 0xcc0
-+#define MTK_WED_RROQM_MOD_MIB 0xcc4
-+#define MTK_WED_RROQM_MOD_COHERENT_MIB 0xcc8
-+#define MTK_WED_RROQM_FDBK_MIB 0xcd0
-+#define MTK_WED_RROQM_FDBK_COHERENT_MIB 0xcd4
-+#define MTK_WED_RROQM_FDBK_IND_MIB 0xce0
-+#define MTK_WED_RROQM_FDBK_ENQ_MIB 0xce4
-+#define MTK_WED_RROQM_FDBK_ANC_MIB 0xce8
-+#define MTK_WED_RROQM_FDBK_ANC2H_MIB 0xcec
-+
-+#define MTK_WED_RX_BM_RX_DMAD 0xd80
-+#define MTK_WED_RX_BM_BASE 0xd84
-+#define MTK_WED_RX_BM_INIT_PTR 0xd88
-+#define MTK_WED_RX_BM_PTR 0xd8c
-+#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
-+#define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0)
-+
-+#define MTK_WED_RX_BM_BLEN 0xd90
-+#define MTK_WED_RX_BM_STS 0xd94
-+#define MTK_WED_RX_BM_INTF2 0xd98
-+#define MTK_WED_RX_BM_INTF 0xd9c
-+#define MTK_WED_RX_BM_ERR_STS 0xda8
-+
-+#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
-+#define MTK_WED_PCIE_INT_MASK 0x0
-+
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -49,6 +49,10 @@ enum {
- MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2),
- };
-
-+#define MTK_WED_WO_CPU_MCUSYS_RESET_ADDR 0x15194050
-+#define MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK 0x20
-+#define MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK 0x1
-+
- enum {
- MTK_WED_WO_REGION_EMI,
- MTK_WED_WO_REGION_ILM,
-@@ -57,6 +61,28 @@ enum {
- __MTK_WED_WO_REGION_MAX,
- };
-
-+enum mtk_wed_wo_state {
-+ MTK_WED_WO_STATE_UNDEFINED,
-+ MTK_WED_WO_STATE_INIT,
-+ MTK_WED_WO_STATE_ENABLE,
-+ MTK_WED_WO_STATE_DISABLE,
-+ MTK_WED_WO_STATE_HALT,
-+ MTK_WED_WO_STATE_GATING,
-+ MTK_WED_WO_STATE_SER_RESET,
-+ MTK_WED_WO_STATE_WF_RESET,
-+};
-+
-+enum mtk_wed_wo_done_state {
-+ MTK_WED_WOIF_UNDEFINED,
-+ MTK_WED_WOIF_DISABLE_DONE,
-+ MTK_WED_WOIF_TRIGGER_ENABLE,
-+ MTK_WED_WOIF_ENABLE_DONE,
-+ MTK_WED_WOIF_TRIGGER_GATING,
-+ MTK_WED_WOIF_GATING_DONE,
-+ MTK_WED_WOIF_TRIGGER_HALT,
-+ MTK_WED_WOIF_HALT_DONE,
-+};
-+
- enum mtk_wed_dummy_cr_idx {
- MTK_WED_DUMMY_CR_FWDL,
- MTK_WED_DUMMY_CR_WO_STATUS,
-@@ -245,6 +271,8 @@ void mtk_wed_mcu_rx_unsolicited_event(st
- struct sk_buff *skb);
- int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
- const void *data, int len, bool wait_resp);
-+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data,
-+ int len);
- int mtk_wed_mcu_init(struct mtk_wed_wo *wo);
- int mtk_wed_wo_init(struct mtk_wed_hw *hw);
- void mtk_wed_wo_deinit(struct mtk_wed_hw *hw);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -5,10 +5,13 @@
- #include <linux/rcupdate.h>
- #include <linux/regmap.h>
- #include <linux/pci.h>
-+#include <linux/skbuff.h>
-
- #define MTK_WED_TX_QUEUES 2
- #define MTK_WED_RX_QUEUES 2
-
-+#define WED_WO_STA_REC 0x6
-+
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-
-@@ -41,21 +44,37 @@ enum mtk_wed_wo_cmd {
- MTK_WED_WO_CMD_WED_END
- };
-
-+struct mtk_rxbm_desc {
-+ __le32 buf0;
-+ __le32 token;
-+} __packed __aligned(4);
-+
- enum mtk_wed_bus_tye {
- MTK_WED_BUS_PCIE,
- MTK_WED_BUS_AXI,
- };
-
-+#define MTK_WED_RING_CONFIGURED BIT(0)
- struct mtk_wed_ring {
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
- u32 desc_size;
- int size;
-+ u32 flags;
-
- u32 reg_base;
- void __iomem *wpdma;
- };
-
-+struct mtk_wed_wo_rx_stats {
-+ __le16 wlan_idx;
-+ __le16 tid;
-+ __le32 rx_pkt_cnt;
-+ __le32 rx_byte_cnt;
-+ __le32 rx_err_cnt;
-+ __le32 rx_drop_cnt;
-+};
-+
- struct mtk_wed_device {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- const struct mtk_wed_ops *ops;
-@@ -64,9 +83,12 @@ struct mtk_wed_device {
- bool init_done, running;
- int wdma_idx;
- int irq;
-+ u8 version;
-
- struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
-+ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
- struct mtk_wed_ring txfree_ring;
-+ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-
- struct {
-@@ -74,7 +96,20 @@ struct mtk_wed_device {
- void **pages;
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-- } buf_ring;
-+ } tx_buf_ring;
-+
-+ struct {
-+ int size;
-+ struct page_frag_cache rx_page;
-+ struct mtk_rxbm_desc *desc;
-+ dma_addr_t desc_phys;
-+ } rx_buf_ring;
-+
-+ struct {
-+ struct mtk_wed_ring ring;
-+ dma_addr_t miod_phys;
-+ dma_addr_t fdbk_phys;
-+ } rro;
-
- /* filled by driver: */
- struct {
-@@ -83,22 +118,36 @@ struct mtk_wed_device {
- struct pci_dev *pci_dev;
- };
- enum mtk_wed_bus_tye bus_type;
-+ void __iomem *base;
-+ u32 phy_base;
-
- u32 wpdma_phys;
- u32 wpdma_int;
- u32 wpdma_mask;
- u32 wpdma_tx;
- u32 wpdma_txfree;
-+ u32 wpdma_rx_glo;
-+ u32 wpdma_rx;
-+
-+ bool wcid_512;
-
- u16 token_start;
- unsigned int nbuf;
-+ unsigned int rx_nbuf;
-+ unsigned int rx_npkt;
-+ unsigned int rx_size;
-
- u8 tx_tbit[MTK_WED_TX_QUEUES];
-+ u8 rx_tbit[MTK_WED_RX_QUEUES];
- u8 txfree_tbit;
-
- u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
- int (*offload_enable)(struct mtk_wed_device *wed);
- void (*offload_disable)(struct mtk_wed_device *wed);
-+ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size);
-+ void (*release_rx_buf)(struct mtk_wed_device *wed);
-+ void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
-+ struct mtk_wed_wo_rx_stats *stats);
- } wlan;
- #endif
- };
-@@ -107,9 +156,15 @@ struct mtk_wed_ops {
- int (*attach)(struct mtk_wed_device *dev);
- int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
-+ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
- int (*txfree_ring_setup)(struct mtk_wed_device *dev,
- void __iomem *regs);
-+ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
-+ void *data, int len);
- void (*detach)(struct mtk_wed_device *dev);
-+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
-+ u32 reason, u32 hash);
-
- void (*stop)(struct mtk_wed_device *dev);
- void (*start)(struct mtk_wed_device *dev, u32 irq_mask);
-@@ -144,6 +199,16 @@ mtk_wed_device_attach(struct mtk_wed_dev
- return ret;
- }
-
-+static inline bool
-+mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
-+{
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ return dev->version != 1;
-+#else
-+ return false;
-+#endif
-+}
-+
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- #define mtk_wed_device_active(_dev) !!(_dev)->ops
- #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
-@@ -160,6 +225,12 @@ mtk_wed_device_attach(struct mtk_wed_dev
- (_dev)->ops->irq_get(_dev, _mask)
- #define mtk_wed_device_irq_set_mask(_dev, _mask) \
- (_dev)->ops->irq_set_mask(_dev, _mask)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
-+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
-+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
-+ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -173,6 +244,9 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
- #define mtk_wed_device_irq_get(_dev, _mask) 0
- #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
-+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch b/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch
deleted file mode 100644
index bb1066dece..0000000000
--- a/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:22 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add rx mib counters
-
-Introduce WED RX MIB counters support available on MT7986a SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -2,6 +2,7 @@
- /* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
-
- #include <linux/seq_file.h>
-+#include <linux/soc/mediatek/mtk_wed.h>
- #include "mtk_wed.h"
- #include "mtk_wed_regs.h"
-
-@@ -18,6 +19,8 @@ enum {
- DUMP_TYPE_WDMA,
- DUMP_TYPE_WPDMA_TX,
- DUMP_TYPE_WPDMA_TXFREE,
-+ DUMP_TYPE_WPDMA_RX,
-+ DUMP_TYPE_WED_RRO,
- };
-
- #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
-@@ -36,6 +39,9 @@ enum {
-
- #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n)
- #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE)
-+#define DUMP_WPDMA_RX_RING(_n) DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n)
-+#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO)
-+#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO)
-
- static void
- print_reg_val(struct seq_file *s, const char *name, u32 val)
-@@ -57,6 +63,7 @@ dump_wed_regs(struct seq_file *s, struct
- cur > regs ? "\n" : "",
- cur->name);
- continue;
-+ case DUMP_TYPE_WED_RRO:
- case DUMP_TYPE_WED:
- val = wed_r32(dev, cur->offset);
- break;
-@@ -69,6 +76,9 @@ dump_wed_regs(struct seq_file *s, struct
- case DUMP_TYPE_WPDMA_TXFREE:
- val = wpdma_txfree_r32(dev, cur->offset);
- break;
-+ case DUMP_TYPE_WPDMA_RX:
-+ val = wpdma_rx_r32(dev, cur->base, cur->offset);
-+ break;
- }
- print_reg_val(s, cur->name, val);
- }
-@@ -132,6 +142,80 @@ wed_txinfo_show(struct seq_file *s, void
- }
- DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
-
-+static int
-+wed_rxinfo_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("WPDMA RX"),
-+ DUMP_WPDMA_RX_RING(0),
-+ DUMP_WPDMA_RX_RING(1),
-+
-+ DUMP_STR("WPDMA RX"),
-+ DUMP_WED(WED_WPDMA_RX_D_MIB(0)),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)),
-+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)),
-+ DUMP_WED(WED_WPDMA_RX_D_MIB(1)),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)),
-+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)),
-+ DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB),
-+
-+ DUMP_STR("WED RX"),
-+ DUMP_WED_RING(WED_RING_RX_DATA(0)),
-+ DUMP_WED_RING(WED_RING_RX_DATA(1)),
-+
-+ DUMP_STR("WED RRO"),
-+ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
-+ DUMP_WED(WED_RROQM_MID_MIB),
-+ DUMP_WED(WED_RROQM_MOD_MIB),
-+ DUMP_WED(WED_RROQM_MOD_COHERENT_MIB),
-+ DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0),
-+ DUMP_WED(WED_RROQM_FDBK_IND_MIB),
-+ DUMP_WED(WED_RROQM_FDBK_ENQ_MIB),
-+ DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
-+ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
-+
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_R2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2N_MIB),
-+ DUMP_WED(WED_RTQM_Q2B_MIB),
-+ DUMP_WED(WED_RTQM_PFDBK_MIB),
-+
-+ DUMP_STR("WED WDMA TX"),
-+ DUMP_WED(WED_WDMA_TX_MIB),
-+ DUMP_WED_RING(WED_WDMA_RING_TX),
-+
-+ DUMP_STR("WDMA TX"),
-+ DUMP_WDMA(WDMA_GLO_CFG),
-+ DUMP_WDMA_RING(WDMA_RING_TX(0)),
-+ DUMP_WDMA_RING(WDMA_RING_TX(1)),
-+
-+ DUMP_STR("WED RX BM"),
-+ DUMP_WED(WED_RX_BM_BASE),
-+ DUMP_WED(WED_RX_BM_RX_DMAD),
-+ DUMP_WED(WED_RX_BM_PTR),
-+ DUMP_WED(WED_RX_BM_TKID_MIB),
-+ DUMP_WED(WED_RX_BM_BLEN),
-+ DUMP_WED(WED_RX_BM_STS),
-+ DUMP_WED(WED_RX_BM_INTF2),
-+ DUMP_WED(WED_RX_BM_INTF),
-+ DUMP_WED(WED_RX_BM_ERR_STS),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev)
-+ return 0;
-+
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rxinfo);
-
- static int
- mtk_wed_reg_set(void *data, u64 val)
-@@ -175,4 +259,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w
- debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
- debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
- debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-+ if (hw->version != 1)
-+ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
-+ &wed_rxinfo_fops);
- }
diff --git a/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch b/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch
deleted file mode 100644
index 7f76e9b497..0000000000
--- a/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 17 Nov 2022 00:35:04 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: do not overwrite mtu
- configuration running reset routine
-
-Restore user configured MTU running mtk_hw_init() during tx timeout routine
-since it will be overwritten after a hw reset.
-
-Reported-by: Felix Fietkau <nbd@nbd.name>
-Fixes: 9ea4d311509f ("net: ethernet: mediatek: add the whole ethernet reset into the reset process")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3178,6 +3178,30 @@ static void mtk_dim_tx(struct work_struc
- dim->state = DIM_START_MEASURE;
- }
-
-+static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val)
-+{
-+ struct mtk_eth *eth = mac->hw;
-+ u32 mcr_cur, mcr_new;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-+ return;
-+
-+ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-+ mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
-+
-+ if (val <= 1518)
-+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
-+ else if (val <= 1536)
-+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
-+ else if (val <= 1552)
-+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
-+ else
-+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
-+
-+ if (mcr_new != mcr_cur)
-+ mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
-+}
-+
- static int mtk_hw_init(struct mtk_eth *eth)
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-@@ -3252,8 +3276,16 @@ static int mtk_hw_init(struct mtk_eth *e
- * up with the more appropriate value when mtk_mac_config call is being
- * invoked.
- */
-- for (i = 0; i < MTK_MAC_COUNT; i++)
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ struct net_device *dev = eth->netdev[i];
-+
- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
-+ if (dev) {
-+ struct mtk_mac *mac = netdev_priv(dev);
-+
-+ mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
-+ }
-+ }
-
- /* Indicates CDM to parse the MTK special tag from CPU
- * which also is working out for untag packets.
-@@ -3352,7 +3384,6 @@ static int mtk_change_mtu(struct net_dev
- int length = new_mtu + MTK_RX_ETH_HLEN;
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-- u32 mcr_cur, mcr_new;
-
- if (rcu_access_pointer(eth->prog) &&
- length > MTK_PP_MAX_BUF_SIZE) {
-@@ -3360,23 +3391,7 @@ static int mtk_change_mtu(struct net_dev
- return -EINVAL;
- }
-
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
-- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-- mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
--
-- if (length <= 1518)
-- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
-- else if (length <= 1536)
-- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
-- else if (length <= 1552)
-- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
-- else
-- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
--
-- if (mcr_new != mcr_cur)
-- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
-- }
--
-+ mtk_set_mcr_max_rx(mac, length);
- dev->mtu = new_mtu;
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch b/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch
deleted file mode 100644
index 65d9621e2f..0000000000
--- a/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 17 Nov 2022 00:58:46 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in
- mtk_pending_work
-
-Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is
-set only in mtk_pending_work() and it runs holding rtnl lock
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3422,11 +3422,8 @@ static void mtk_pending_work(struct work
- rtnl_lock();
-
- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
-+ set_bit(MTK_RESETTING, &eth->state);
-
-- while (test_and_set_bit_lock(MTK_RESETTING, &eth->state))
-- cpu_relax();
--
-- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__);
- /* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!eth->netdev[i])
-@@ -3460,7 +3457,7 @@ static void mtk_pending_work(struct work
-
- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
-
-- clear_bit_unlock(MTK_RESETTING, &eth->state);
-+ clear_bit(MTK_RESETTING, &eth->state);
-
- rtnl_unlock();
- }
diff --git a/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch b/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch
deleted file mode 100644
index 4eca30dbfd..0000000000
--- a/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 17 Nov 2022 15:29:53 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix RSTCTRL_PPE{0,1} definitions
-
-Fix RSTCTRL_PPE0 and RSTCTRL_PPE1 register mask definitions for
-MTK_NETSYS_V2.
-Remove duplicated definitions.
-
-Fixes: 160d3a9b1929 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3241,16 +3241,17 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
- }
-
-- val = RSTCTRL_FE | RSTCTRL_PPE;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
--
-- val |= RSTCTRL_ETH;
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val |= RSTCTRL_PPE1;
-+ val = RSTCTRL_PPE0_V2;
-+ } else {
-+ val = RSTCTRL_PPE0;
- }
-
-- ethsys_reset(eth, val);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1;
-+
-+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -445,18 +445,14 @@
- /* ethernet reset control register */
- #define ETHSYS_RSTCTRL 0x34
- #define RSTCTRL_FE BIT(6)
--#define RSTCTRL_PPE BIT(31)
--#define RSTCTRL_PPE1 BIT(30)
-+#define RSTCTRL_PPE0 BIT(31)
-+#define RSTCTRL_PPE0_V2 BIT(30)
-+#define RSTCTRL_PPE1 BIT(31)
- #define RSTCTRL_ETH BIT(23)
-
- /* ethernet reset check idle register */
- #define ETHSYS_FE_RST_CHK_IDLE_EN 0x28
-
--/* ethernet reset control register */
--#define ETHSYS_RSTCTRL 0x34
--#define RSTCTRL_FE BIT(6)
--#define RSTCTRL_PPE BIT(31)
--
- /* ethernet dma channel agent map */
- #define ETHSYS_DMA_AG_MAP 0x408
- #define ETHSYS_DMA_AG_MAP_PDMA BIT(0)
diff --git a/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch b/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch
deleted file mode 100644
index 117ccc0902..0000000000
--- a/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Thu, 24 Nov 2022 11:18:14 +0800
-Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed
- v1
-
-All wed versions should enable the wcid overwritten feature,
-since the wcid size is controlled by the wlan driver.
-
-Tested-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Co-developed-by: Bo Jiao <bo.jiao@mediatek.com>
-Signed-off-by: Bo Jiao <bo.jiao@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
--
-- mtk_wed_set_512_support(dev, false);
- }
-+
-+ mtk_wed_set_512_support(dev, false);
- }
-
- static void
-@@ -1290,9 +1290,10 @@ mtk_wed_start(struct mtk_wed_device *dev
- if (mtk_wed_rro_cfg(dev))
- return;
-
-- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
- }
-
-+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-+
- mtk_wed_dma_enable(dev);
- dev->running = true;
- }
-@@ -1358,11 +1359,13 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (hw->version == 1)
-+ if (hw->version == 1) {
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
-- else
-+ } else {
-+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
- ret = mtk_wed_wo_init(hw);
-+ }
- out:
- if (ret)
- mtk_wed_detach(dev);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -20,6 +20,8 @@ struct mtk_wdma_desc {
- __le32 info;
- } __packed __aligned(4);
-
-+#define MTK_WED_REV_ID 0x004
-+
- #define MTK_WED_RESET 0x008
- #define MTK_WED_RESET_TX_BM BIT(0)
- #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -85,6 +85,9 @@ struct mtk_wed_device {
- int irq;
- u8 version;
-
-+ /* used by wlan driver */
-+ u32 rev_id;
-+
- struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
- struct mtk_wed_ring txfree_ring;
diff --git a/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch b/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch
deleted file mode 100644
index ec58c3fc57..0000000000
--- a/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:51 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: return status value in
- mtk_wdma_rx_reset
-
-Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine.
-Increase poll timeout to 10ms in order to be aligned with vendor sdk.
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic
- return wdma_r32(dev, MTK_WDMA_GLO_CFG);
- }
-
--static void
-+static int
- mtk_wdma_rx_reset(struct mtk_wed_device *dev)
- {
- u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
-- int i;
-+ int i, ret;
-
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
-- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-- !(status & mask), 0, 1000))
-+ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 10000);
-+ if (ret)
- dev_err(dev->hw->dev, "rx reset failed\n");
-
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-+
- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
- if (dev->rx_wdma[i].desc)
- continue;
-@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device
- wdma_w32(dev,
- MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
- }
-+
-+ return ret;
- }
-
- static void
-@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mtk_wed_stop(dev);
-
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
--
-+ mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
- if (mtk_wed_get_rx_capa(dev)) {
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de
- mtk_wed_wo_reset(dev);
- mtk_wed_free_rx_rings(dev);
- mtk_wed_wo_deinit(hw);
-- mtk_wdma_rx_reset(dev);
- }
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
-@@ -999,11 +1002,7 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
--
-- if (mtk_wed_get_rx_capa(dev))
-- mtk_wdma_rx_reset(dev);
-+ mtk_wdma_rx_reset(dev);
-
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
diff --git a/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch b/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch
deleted file mode 100644
index 10c1732c96..0000000000
--- a/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:52 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX
- configuration in mtk_wdma_tx_reset
-
-Remove duplicated code. Increase poll timeout to 10ms in order to be
-aligned with vendor sdk.
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device
-
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-- !(status & mask), 0, 1000))
-+ !(status & mask), 0, 10000))
- dev_err(dev->hw->dev, "tx reset failed\n");
-
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
-- if (dev->tx_wdma[i].desc)
-- continue;
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
- wdma_w32(dev,
- MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
-- }
- }
-
- static void
-@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-- if (mtk_wed_get_rx_capa(dev)) {
-- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-- }
--
- mtk_wed_free_tx_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-
diff --git a/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch b/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch
deleted file mode 100644
index f4e842d515..0000000000
--- a/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:53 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop
-
-Update mtk_wed_stop routine and rename old mtk_wed_stop() to
-mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet
-Dispatcher reset support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- static void
- mtk_wed_stop(struct mtk_wed_device *dev)
- {
-- mtk_wed_dma_disable(dev);
- mtk_wed_set_ext_int(dev, false);
-
-- wed_clr(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WDMA_INT_AGENT_EN |
-- MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
-- MTK_WED_CTRL_WED_TX_BM_EN |
-- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
- wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
-@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev)
-
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
- wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
-- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+}
-+
-+static void
-+mtk_wed_deinit(struct mtk_wed_device *dev)
-+{
-+ mtk_wed_stop(dev);
-+ mtk_wed_dma_disable(dev);
-+
-+ wed_clr(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WED_TX_BM_EN |
-+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+
-+ if (dev->hw->version == 1)
-+ return;
-+
-+ wed_clr(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_ROUTE_QM_EN |
-+ MTK_WED_CTRL_WED_RX_BM_EN |
-+ MTK_WED_CTRL_RX_RRO_QM_EN);
- }
-
- static void
-@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mutex_lock(&hw_lock);
-
-- mtk_wed_stop(dev);
-+ mtk_wed_deinit(dev);
-
- mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-@@ -670,7 +684,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- {
- u32 mask, set;
-
-- mtk_wed_stop(dev);
-+ mtk_wed_deinit(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
- mtk_wed_set_wpdma(dev);
-
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
- (_dev)->ops->msg_update(_dev, _id, _msg, _len)
-+#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
-+#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
-+#define mtk_wed_device_stop(_dev) do {} while (0)
-+#define mtk_wed_device_dma_reset(_dev) do {} while (0)
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch b/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch
deleted file mode 100644
index a0fc9da99e..0000000000
--- a/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch
+++ /dev/null
@@ -1,309 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:54 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine
-
-Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless
-Ethernet Dispatcher available on MT7986 SoC.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -944,42 +944,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
- }
-
- static u32
--mtk_wed_check_busy(struct mtk_wed_device *dev)
-+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
- {
-- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) &
-- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) &
-- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
-- return true;
--
-- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) &
-- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_CTRL) &
-- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY))
-- return true;
--
-- return false;
-+ return !!(wed_r32(dev, reg) & mask);
- }
-
- static int
--mtk_wed_poll_busy(struct mtk_wed_device *dev)
-+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
- {
- int sleep = 15000;
- int timeout = 100 * sleep;
- u32 val;
-
- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-- timeout, false, dev);
-+ timeout, false, dev, reg, mask);
-+}
-+
-+static int
-+mtk_wed_rx_reset(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ u8 val = MTK_WED_WO_STATE_SER_RESET;
-+ int i, ret;
-+
-+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
-+ sizeof(val), true);
-+ if (ret)
-+ return ret;
-+
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
-+ if (ret) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
-+ } else {
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
-+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
-+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+ }
-+
-+ /* reset rro qm */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_RRO_QM_BUSY);
-+ if (ret) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM);
-+ } else {
-+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
-+ MTK_WED_RROQM_RST_IDX_MIOD |
-+ MTK_WED_RROQM_RST_IDX_FDBK);
-+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
-+ }
-+
-+ /* reset route qm */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
-+ if (ret)
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
-+ else
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ MTK_WED_RTQM_Q_RST);
-+
-+ /* reset tx wdma */
-+ mtk_wdma_tx_reset(dev);
-+
-+ /* reset tx wdma drv */
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
-+
-+ /* reset wed rx dma */
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_RX_DMA_BUSY);
-+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN);
-+ if (ret) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
-+ } else {
-+ struct mtk_eth *eth = dev->hw->eth;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ wed_set(dev, MTK_WED_RESET_IDX,
-+ MTK_WED_RESET_IDX_RX_V2);
-+ else
-+ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
-+ }
-+
-+ /* reset rx bm */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_RX_BM_BUSY);
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
-+
-+ /* wo change to enable state */
-+ val = MTK_WED_WO_STATE_ENABLE;
-+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
-+ sizeof(val), true);
-+ if (ret)
-+ return ret;
-+
-+ /* wed_rx_ring_reset */
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) {
-+ if (!dev->rx_ring[i].desc)
-+ continue;
-+
-+ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE,
-+ false);
-+ }
-+ mtk_wed_free_rx_buffer(dev);
-+
-+ return 0;
- }
-
- static void
-@@ -997,19 +1085,23 @@ mtk_wed_reset_dma(struct mtk_wed_device
- true);
- }
-
-- if (mtk_wed_poll_busy(dev))
-- busy = mtk_wed_check_busy(dev);
--
-+ /* 1. reset WED tx DMA */
-+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN);
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_TX_DMA_BUSY);
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
- } else {
-- wed_w32(dev, MTK_WED_RESET_IDX,
-- MTK_WED_RESET_IDX_TX |
-- MTK_WED_RESET_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-- mtk_wdma_rx_reset(dev);
-+ /* 2. reset WDMA rx DMA */
-+ busy = !!mtk_wdma_rx_reset(dev);
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ if (!busy)
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
-
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
-@@ -1026,6 +1118,9 @@ mtk_wed_reset_dma(struct mtk_wed_device
- MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE);
- }
-
-+ /* 3. reset WED WPDMA tx */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+
- for (i = 0; i < 100; i++) {
- val = wed_r32(dev, MTK_WED_TX_BM_INTF);
- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
-@@ -1033,8 +1128,19 @@ mtk_wed_reset_dma(struct mtk_wed_device
- }
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN);
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-+ /* 4. reset WED WPDMA tx */
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ if (!busy)
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY);
-+
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
-@@ -1045,6 +1151,17 @@ mtk_wed_reset_dma(struct mtk_wed_device
- MTK_WED_WPDMA_RESET_IDX_RX);
- wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
- }
-+
-+ dev->init_done = false;
-+ if (dev->hw->version == 1)
-+ return;
-+
-+ if (!busy) {
-+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
-+ }
-+
-+ mtk_wed_rx_reset(dev);
- }
-
- static int
-@@ -1267,6 +1384,9 @@ mtk_wed_start(struct mtk_wed_device *dev
- {
- int i;
-
-+ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev))
-+ return;
-+
- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
- if (!dev->rx_wdma[i].desc)
- mtk_wed_wdma_rx_ring_setup(dev, i, 16);
-@@ -1355,10 +1475,6 @@ mtk_wed_attach(struct mtk_wed_device *de
- goto out;
-
- if (mtk_wed_get_rx_capa(dev)) {
-- ret = mtk_wed_rx_buffer_alloc(dev);
-- if (ret)
-- goto out;
--
- ret = mtk_wed_rro_alloc(dev);
- if (ret)
- goto out;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -24,11 +24,15 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_RESET 0x008
- #define MTK_WED_RESET_TX_BM BIT(0)
-+#define MTK_WED_RESET_RX_BM BIT(1)
- #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
- #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
- #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
-+#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10)
- #define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11)
- #define MTK_WED_RESET_WED_TX_DMA BIT(12)
-+#define MTK_WED_RESET_WED_RX_DMA BIT(13)
-+#define MTK_WED_RESET_WDMA_TX_DRV BIT(16)
- #define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
- #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
- #define MTK_WED_RESET_RX_RRO_QM BIT(20)
-@@ -158,6 +162,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_IDX 0x20c
- #define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
- #define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
-+#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6)
-+#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
-
- #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
- #define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4)
-@@ -267,6 +273,9 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
- #define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1)
-+#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3)
-+#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4)
- #define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)
- #define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)
-
diff --git a/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch b/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch
deleted file mode 100644
index 4404971cc7..0000000000
--- a/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:55 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
-
-Introduce reset parameter to mtk_wed_tx_ring_setup signature.
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1181,7 +1181,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device
- }
-
- static int
--mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
-+ bool reset)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-@@ -1190,8 +1191,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
- return -EINVAL;
-
- wdma = &dev->rx_wdma[idx];
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-- true))
-+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1389,7 +1390,7 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
- if (!dev->rx_wdma[i].desc)
-- mtk_wed_wdma_rx_ring_setup(dev, i, 16);
-+ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
-
- mtk_wed_hw_init(dev);
- mtk_wed_configure_irq(dev, irq_mask);
-@@ -1498,7 +1499,8 @@ unlock:
- }
-
- static int
--mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
-+ bool reset)
- {
- struct mtk_wed_ring *ring = &dev->tx_ring[idx];
-
-@@ -1517,11 +1519,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
- return -EINVAL;
-
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-- sizeof(*ring->desc), true))
-+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-+ sizeof(*ring->desc), true))
- return -ENOMEM;
-
-- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
-+ reset))
- return -ENOMEM;
-
- ring->reg_base = MTK_WED_RING_TX(idx);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -158,7 +158,7 @@ struct mtk_wed_device {
- struct mtk_wed_ops {
- int (*attach)(struct mtk_wed_device *dev);
- int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
-- void __iomem *regs);
-+ void __iomem *regs, bool reset);
- int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
- int (*txfree_ring_setup)(struct mtk_wed_device *dev,
-@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- #define mtk_wed_device_active(_dev) !!(_dev)->ops
- #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
- #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
--#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \
-- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \
-+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)
- #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
- (_dev)->ops->txfree_ring_setup(_dev, _regs)
- #define mtk_wed_device_reg_read(_dev, _reg) \
-@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active
- }
- #define mtk_wed_device_detach(_dev) do {} while (0)
- #define mtk_wed_device_start(_dev, _mask) do {} while (0)
--#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
- #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
- #define mtk_wed_device_reg_read(_dev, _reg) 0
- #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
diff --git a/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch b/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch
deleted file mode 100644
index f9b11326b1..0000000000
--- a/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 1 Dec 2022 16:26:53 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in
- mtk_wed_wo_queue_refill
-
-In order to fix the following sleep while atomic bug always alloc pages
-with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in
-spin_lock critical section.
-
-[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT)
-[ 9.054665] Call trace:
-[ 9.057096] dump_backtrace+0x0/0x154
-[ 9.060751] show_stack+0x14/0x1c
-[ 9.064052] dump_stack_lvl+0x64/0x7c
-[ 9.067702] dump_stack+0x14/0x2c
-[ 9.071001] ___might_sleep+0xec/0x120
-[ 9.074736] __might_sleep+0x4c/0x9c
-[ 9.078296] __alloc_pages+0x184/0x2e4
-[ 9.082030] page_frag_alloc_align+0x98/0x1ac
-[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234
-[ 9.090974] mtk_wed_wo_init+0x174/0x2c0
-[ 9.094881] mtk_wed_attach+0x7c8/0x7e0
-[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e]
-[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e]
-[ 9.108727] pci_device_probe+0xac/0x13c
-[ 9.112638] really_probe.part.0+0x98/0x2f4
-[ 9.116807] __driver_probe_device+0x94/0x13c
-[ 9.121147] driver_probe_device+0x40/0x114
-[ 9.125314] __driver_attach+0x7c/0x180
-[ 9.129133] bus_for_each_dev+0x5c/0x90
-[ 9.132953] driver_attach+0x20/0x2c
-[ 9.136513] bus_add_driver+0x104/0x1fc
-[ 9.140333] driver_register+0x74/0x120
-[ 9.144153] __pci_register_driver+0x40/0x50
-[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e]
-[ 9.152848] do_one_initcall+0x40/0x25c
-[ 9.156669] do_init_module+0x44/0x230
-[ 9.160403] load_module+0x1f30/0x2750
-[ 9.164135] __do_sys_init_module+0x150/0x200
-[ 9.168475] __arm64_sys_init_module+0x18/0x20
-[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0
-[ 9.177589] do_el0_svc+0x48/0xe0
-[ 9.180889] el0_svc+0x14/0x50
-[ 9.183929] el0t_64_sync_handler+0x9c/0x120
-[ 9.188183] el0t_64_sync+0x158/0x15c
-
-Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
-Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo
-
- static int
- mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-- gfp_t gfp, bool rx)
-+ bool rx)
- {
- enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
- int n_buf = 0;
-
- spin_lock_bh(&q->lock);
- while (q->queued < q->n_desc) {
-- void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp);
- struct mtk_wed_wo_queue_entry *entry;
- dma_addr_t addr;
-+ void *buf;
-
-+ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC);
- if (!buf)
- break;
-
-@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w
- mtk_wed_mcu_rx_unsolicited_event(wo, skb);
- }
-
-- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) {
-+ if (mtk_wed_wo_queue_refill(wo, q, true)) {
- u32 index = (q->head - 1) % q->n_desc;
-
- mtk_wed_wo_queue_kick(wo, q, index);
-@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
- if (ret)
- goto error;
-
-- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false);
-+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false);
- mtk_wed_wo_queue_reset(wo, &wo->q_tx);
-
- regs.desc_base = MTK_WED_WO_CCIF_DUMMY5;
-@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
- if (ret)
- goto error;
-
-- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true);
-+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true);
- mtk_wed_wo_queue_reset(wo, &wo->q_rx);
-
- /* rx queue irqmask */
diff --git a/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch b/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch
deleted file mode 100644
index fa6f56dbe7..0000000000
--- a/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 10 Jan 2023 10:31:26 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue
-
-Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and
-mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher
-MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization
-and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in
-mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been
-disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill
-routines can't run concurrently get rid of spinlock for mcu rx queue.
-
-Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
- enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
- int n_buf = 0;
-
-- spin_lock_bh(&q->lock);
- while (q->queued < q->n_desc) {
- struct mtk_wed_wo_queue_entry *entry;
- dma_addr_t addr;
-@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
- q->queued++;
- n_buf++;
- }
-- spin_unlock_bh(&q->lock);
-
- return n_buf;
- }
-@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
- {
- struct page *page;
-
-- spin_lock_bh(&q->lock);
- for (;;) {
- void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
-
-@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
-
- skb_free_frag(buf);
- }
-- spin_unlock_bh(&q->lock);
-
- if (!q->cache.va)
- return;
diff --git a/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch b/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch
deleted file mode 100644
index 9b1e4c3250..0000000000
--- a/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 12 Jan 2023 10:21:29 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue
-
-Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue,
-we do not need to protect WED MCU tx queue with a spin lock since
-the tx queue is accessed in the two following routines:
-- mtk_wed_wo_queue_tx_skb():
- it is run at initialization and during mt7915 normal operation.
- Moreover MCU messages are serialized through MCU mutex.
-- mtk_wed_wo_queue_tx_clean():
- it runs just at mt7915 driver module unload when no more messages
- are sent to the MCU.
-
-Remove tx queue spinlock.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo
- int n_desc, int buf_size, int index,
- struct mtk_wed_wo_queue_regs *regs)
- {
-- spin_lock_init(&q->lock);
- q->regs = *regs;
- q->n_desc = n_desc;
- q->buf_size = buf_size;
-@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
- struct page *page;
- int i;
-
-- spin_lock_bh(&q->lock);
- for (i = 0; i < q->n_desc; i++) {
- struct mtk_wed_wo_queue_entry *entry = &q->entry[i];
-
-@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
- skb_free_frag(entry->buf);
- entry->buf = NULL;
- }
-- spin_unlock_bh(&q->lock);
-
- if (!q->cache.va)
- return;
-@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
- int ret = 0, index;
- u32 ctrl;
-
-- spin_lock_bh(&q->lock);
--
- q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx);
- index = (q->head + 1) % q->n_desc;
- if (q->tail == index) {
-@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
- mtk_wed_wo_queue_kick(wo, q, q->head);
- mtk_wed_wo_kickout(wo);
- out:
-- spin_unlock_bh(&q->lock);
--
- dev_kfree_skb(skb);
-
- return ret;
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -211,7 +211,6 @@ struct mtk_wed_wo_queue {
- struct mtk_wed_wo_queue_regs regs;
-
- struct page_frag_cache cache;
-- spinlock_t lock;
-
- struct mtk_wed_wo_queue_desc *desc;
- dma_addr_t desc_dma;
diff --git a/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch b/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch
deleted file mode 100644
index 33f2b5b0a5..0000000000
--- a/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:28 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility
- routine
-
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3202,6 +3202,27 @@ static void mtk_set_mcr_max_rx(struct mt
- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
- }
-
-+static void mtk_hw_reset(struct mtk_eth *eth)
-+{
-+ u32 val;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-+ val = RSTCTRL_PPE0_V2;
-+ } else {
-+ val = RSTCTRL_PPE0;
-+ }
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1;
-+
-+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-+ 0x3ffffff);
-+}
-+
- static int mtk_hw_init(struct mtk_eth *eth)
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-@@ -3241,22 +3262,9 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-- val = RSTCTRL_PPE0_V2;
-- } else {
-- val = RSTCTRL_PPE0;
-- }
--
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val |= RSTCTRL_PPE1;
--
-- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-+ mtk_hw_reset(eth);
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-- 0x3ffffff);
--
- /* Set FE to PDMAv2 if necessary */
- val = mtk_r32(eth, MTK_FE_GLO_MISC);
- mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
diff --git a/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch b/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch
deleted file mode 100644
index 84209fccd5..0000000000
--- a/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:29 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset
- support
-
-Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch
-to align reset procedure to vendor sdk and avoid to power down the chip
-during hw reset.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3223,7 +3223,54 @@ static void mtk_hw_reset(struct mtk_eth
- 0x3ffffff);
- }
-
--static int mtk_hw_init(struct mtk_eth *eth)
-+static u32 mtk_hw_reset_read(struct mtk_eth *eth)
-+{
-+ u32 val;
-+
-+ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val);
-+ return val;
-+}
-+
-+static void mtk_hw_warm_reset(struct mtk_eth *eth)
-+{
-+ u32 rst_mask, val;
-+
-+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE,
-+ RSTCTRL_FE);
-+ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val,
-+ val & RSTCTRL_FE, 1, 1000)) {
-+ dev_err(eth->dev, "warm reset failed\n");
-+ mtk_hw_reset(eth);
-+ return;
-+ }
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
-+ else
-+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ rst_mask |= RSTCTRL_PPE1;
-+
-+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
-+
-+ udelay(1);
-+ val = mtk_hw_reset_read(eth);
-+ if (!(val & rst_mask))
-+ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n",
-+ val, rst_mask);
-+
-+ rst_mask |= RSTCTRL_FE;
-+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask);
-+
-+ udelay(1);
-+ val = mtk_hw_reset_read(eth);
-+ if (val & rst_mask)
-+ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n",
-+ val, rst_mask);
-+}
-+
-+static int mtk_hw_init(struct mtk_eth *eth, bool reset)
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
- ETHSYS_DMA_AG_MAP_PPE;
-@@ -3262,7 +3309,12 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
- }
-
-- mtk_hw_reset(eth);
-+ msleep(100);
-+
-+ if (reset)
-+ mtk_hw_warm_reset(eth);
-+ else
-+ mtk_hw_reset(eth);
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- /* Set FE to PDMAv2 if necessary */
-@@ -3450,7 +3502,7 @@ static void mtk_pending_work(struct work
- if (eth->dev->pins)
- pinctrl_select_state(eth->dev->pins->p,
- eth->dev->pins->default_state);
-- mtk_hw_init(eth);
-+ mtk_hw_init(eth, true);
-
- /* restart DMA and enable IRQs */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-@@ -4052,7 +4104,7 @@ static int mtk_probe(struct platform_dev
- eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
- INIT_WORK(&eth->pending_work, mtk_pending_work);
-
-- err = mtk_hw_init(eth);
-+ err = mtk_hw_init(eth, false);
- if (err)
- goto err_wed_exit;
-
diff --git a/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch b/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch
deleted file mode 100644
index e75a4cc0d0..0000000000
--- a/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch
+++ /dev/null
@@ -1,262 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:30 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor
- sdk
-
-Avoid to power-down the ethernet chip during hw reset and align reset
-procedure to vendor sdk.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2788,14 +2788,29 @@ static void mtk_dma_free(struct mtk_eth
- kfree(eth->scratch_head);
- }
-
-+static bool mtk_hw_reset_check(struct mtk_eth *eth)
-+{
-+ u32 val = mtk_r32(eth, MTK_INT_STATUS2);
-+
-+ 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) ||
-+ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL);
-+}
-+
- static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue)
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-
-+ if (test_bit(MTK_RESETTING, &eth->state))
-+ return;
-+
-+ if (!mtk_hw_reset_check(eth))
-+ return;
-+
- eth->netdev[mac->id]->stats.tx_errors++;
-- netif_err(eth, tx_err, dev,
-- "transmit timed out\n");
-+ netif_err(eth, tx_err, dev, "transmit timed out\n");
-+
- schedule_work(&eth->pending_work);
- }
-
-@@ -3277,15 +3292,17 @@ static int mtk_hw_init(struct mtk_eth *e
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- int i, val, ret;
-
-- if (test_and_set_bit(MTK_HW_INIT, &eth->state))
-+ if (!reset && test_and_set_bit(MTK_HW_INIT, &eth->state))
- return 0;
-
-- pm_runtime_enable(eth->dev);
-- pm_runtime_get_sync(eth->dev);
-+ if (!reset) {
-+ pm_runtime_enable(eth->dev);
-+ pm_runtime_get_sync(eth->dev);
-
-- ret = mtk_clk_enable(eth);
-- if (ret)
-- goto err_disable_pm;
-+ ret = mtk_clk_enable(eth);
-+ if (ret)
-+ goto err_disable_pm;
-+ }
-
- if (eth->ethsys)
- regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask,
-@@ -3411,8 +3428,10 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
-
- err_disable_pm:
-- pm_runtime_put_sync(eth->dev);
-- pm_runtime_disable(eth->dev);
-+ if (!reset) {
-+ pm_runtime_put_sync(eth->dev);
-+ pm_runtime_disable(eth->dev);
-+ }
-
- return ret;
- }
-@@ -3474,30 +3493,53 @@ static int mtk_do_ioctl(struct net_devic
- return -EOPNOTSUPP;
- }
-
-+static void mtk_prepare_for_reset(struct mtk_eth *eth)
-+{
-+ u32 val;
-+ int i;
-+
-+ /* disabe FE P3 and P4 */
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= MTK_FE_LINK_DOWN_P4;
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
-+
-+ /* adjust PPE configurations to prepare for reset */
-+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
-+ mtk_ppe_prepare_reset(eth->ppe[i]);
-+
-+ /* disable NETSYS interrupts */
-+ mtk_w32(eth, 0, MTK_FE_INT_ENABLE);
-+
-+ /* force link down GMAC */
-+ for (i = 0; i < 2; i++) {
-+ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK;
-+ mtk_w32(eth, val, MTK_MAC_MCR(i));
-+ }
-+}
-+
- static void mtk_pending_work(struct work_struct *work)
- {
- struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
-- int err, i;
- unsigned long restart = 0;
-+ u32 val;
-+ int i;
-
- rtnl_lock();
--
-- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
- set_bit(MTK_RESETTING, &eth->state);
-
-+ mtk_prepare_for_reset(eth);
-+
- /* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i])
-+ if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
- continue;
-+
- mtk_stop(eth->netdev[i]);
- __set_bit(i, &restart);
- }
-- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__);
-
-- /* restart underlying hardware such as power, clock, pin mux
-- * and the connected phy
-- */
-- mtk_hw_deinit(eth);
-+ usleep_range(15000, 16000);
-
- if (eth->dev->pins)
- pinctrl_select_state(eth->dev->pins->p,
-@@ -3508,15 +3550,19 @@ static void mtk_pending_work(struct work
- for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!test_bit(i, &restart))
- continue;
-- err = mtk_open(eth->netdev[i]);
-- if (err) {
-+
-+ if (mtk_open(eth->netdev[i])) {
- netif_alert(eth, ifup, eth->netdev[i],
-- "Driver up/down cycle failed, closing device.\n");
-+ "Driver up/down cycle failed\n");
- dev_close(eth->netdev[i]);
- }
- }
-
-- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
-+ /* enabe FE P3 and P4 */
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val &= ~MTK_FE_LINK_DOWN_P4;
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
-
- clear_bit(MTK_RESETTING, &eth->state);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -72,12 +72,24 @@
- #define MTK_HW_LRO_REPLACE_DELTA 1000
- #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522
-
-+/* Frame Engine Global Configuration */
-+#define MTK_FE_GLO_CFG 0x00
-+#define MTK_FE_LINK_DOWN_P3 BIT(11)
-+#define MTK_FE_LINK_DOWN_P4 BIT(12)
-+
- /* Frame Engine Global Reset Register */
- #define MTK_RST_GL 0x04
- #define RST_GL_PSE BIT(0)
-
- /* Frame Engine Interrupt Status Register */
- #define MTK_INT_STATUS2 0x08
-+#define MTK_FE_INT_ENABLE 0x0c
-+#define MTK_FE_INT_FQ_EMPTY BIT(8)
-+#define MTK_FE_INT_TSO_FAIL BIT(12)
-+#define MTK_FE_INT_TSO_ILLEGAL BIT(13)
-+#define MTK_FE_INT_TSO_ALIGN BIT(14)
-+#define MTK_FE_INT_RFIFO_OV BIT(18)
-+#define MTK_FE_INT_RFIFO_UF BIT(19)
- #define MTK_GDM1_AF BIT(28)
- #define MTK_GDM2_AF BIT(29)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -716,6 +716,33 @@ int mtk_foe_entry_idle_time(struct mtk_p
- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
- }
-
-+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
-+{
-+ if (!ppe)
-+ return -EINVAL;
-+
-+ /* disable KA */
-+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
-+ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
-+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0);
-+ usleep_range(10000, 11000);
-+
-+ /* set KA timer to maximum */
-+ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
-+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff);
-+
-+ /* set KA tick select */
-+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL);
-+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
-+ usleep_range(10000, 11000);
-+
-+ /* disable scan mode */
-+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE);
-+ usleep_range(10000, 11000);
-+
-+ return mtk_ppe_wait_busy(ppe);
-+}
-+
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version, int index)
- {
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -307,6 +307,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- void mtk_ppe_deinit(struct mtk_eth *eth);
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -58,6 +58,12 @@
- #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16)
- #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18)
- #define MTK_PPE_TB_CFG_INFO_SEL BIT(20)
-+#define MTK_PPE_TB_TICK_SEL BIT(24)
-+
-+#define MTK_PPE_BIND_LMT1 0x230
-+#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16)
-+
-+#define MTK_PPE_KEEPALIVE 0x234
-
- enum {
- MTK_PPE_SCAN_MODE_DISABLED,
diff --git a/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch b/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch
deleted file mode 100644
index 898785ece2..0000000000
--- a/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:31 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to
- mtk_hw_reset_check
-
-Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -50,6 +50,7 @@ static const struct mtk_reg_map mtk_reg_
- .delay_irq = 0x0a0c,
- .irq_status = 0x0a20,
- .irq_mask = 0x0a28,
-+ .adma_rx_dbg0 = 0x0a38,
- .int_grp = 0x0a50,
- },
- .qdma = {
-@@ -79,6 +80,8 @@ static const struct mtk_reg_map mtk_reg_
- [0] = 0x2800,
- [1] = 0x2c00,
- },
-+ .pse_iq_sta = 0x0110,
-+ .pse_oq_sta = 0x0118,
- };
-
- static const struct mtk_reg_map mt7628_reg_map = {
-@@ -109,6 +112,7 @@ static const struct mtk_reg_map mt7986_r
- .delay_irq = 0x620c,
- .irq_status = 0x6220,
- .irq_mask = 0x6228,
-+ .adma_rx_dbg0 = 0x6238,
- .int_grp = 0x6250,
- },
- .qdma = {
-@@ -138,6 +142,8 @@ static const struct mtk_reg_map mt7986_r
- [0] = 0x4800,
- [1] = 0x4c00,
- },
-+ .pse_iq_sta = 0x0180,
-+ .pse_oq_sta = 0x01a0,
- };
-
- /* strings used by ethtool */
-@@ -3285,6 +3291,102 @@ static void mtk_hw_warm_reset(struct mtk
- val, rst_mask);
- }
-
-+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 oq_hang, cdm1_busy, adma_busy;
-+ bool wtx_busy, cdm_full, oq_free;
-+ u32 wdidx, val, gdm1_fc, gdm2_fc;
-+ bool qfsm_hang, qfwd_hang;
-+ bool ret = false;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-+ return false;
-+
-+ /* WDMA sanity checks */
-+ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc);
-+
-+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204);
-+ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val);
-+
-+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230);
-+ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val);
-+
-+ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) &&
-+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) &&
-+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16)));
-+
-+ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) {
-+ if (++eth->reset.wdma_hang_count > 2) {
-+ eth->reset.wdma_hang_count = 0;
-+ ret = true;
-+ }
-+ goto out;
-+ }
-+
-+ /* QDMA sanity checks */
-+ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234);
-+ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308);
-+
-+ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0;
-+ 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);
-+
-+ if (qfsm_hang && qfwd_hang &&
-+ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) ||
-+ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) {
-+ if (++eth->reset.qdma_hang_count > 2) {
-+ eth->reset.qdma_hang_count = 0;
-+ ret = true;
-+ }
-+ goto out;
-+ }
-+
-+ /* ADMA sanity checks */
-+ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0));
-+ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16));
-+ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) &&
-+ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6));
-+
-+ if (oq_hang && cdm1_busy && adma_busy) {
-+ if (++eth->reset.adma_hang_count > 2) {
-+ eth->reset.adma_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;
-+out:
-+ eth->reset.wdidx = wdidx;
-+
-+ return ret;
-+}
-+
-+static void mtk_hw_reset_monitor_work(struct work_struct *work)
-+{
-+ struct delayed_work *del_work = to_delayed_work(work);
-+ struct mtk_eth *eth = container_of(del_work, struct mtk_eth,
-+ reset.monitor_work);
-+
-+ if (test_bit(MTK_RESETTING, &eth->state))
-+ goto out;
-+
-+ /* DMA stuck checks */
-+ if (mtk_hw_check_dma_hang(eth))
-+ schedule_work(&eth->pending_work);
-+
-+out:
-+ schedule_delayed_work(&eth->reset.monitor_work,
-+ MTK_DMA_MONITOR_TIMEOUT);
-+}
-+
- static int mtk_hw_init(struct mtk_eth *eth, bool reset)
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-@@ -3600,6 +3702,7 @@ static int mtk_cleanup(struct mtk_eth *e
- mtk_unreg_dev(eth);
- mtk_free_dev(eth);
- cancel_work_sync(&eth->pending_work);
-+ cancel_delayed_work_sync(&eth->reset.monitor_work);
-
- return 0;
- }
-@@ -4037,6 +4140,7 @@ static int mtk_probe(struct platform_dev
-
- eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
- INIT_WORK(&eth->rx_dim.work, mtk_dim_rx);
-+ INIT_DELAYED_WORK(&eth->reset.monitor_work, mtk_hw_reset_monitor_work);
-
- eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
- INIT_WORK(&eth->tx_dim.work, mtk_dim_tx);
-@@ -4241,6 +4345,8 @@ static int mtk_probe(struct platform_dev
- NAPI_POLL_WEIGHT);
-
- platform_set_drvdata(pdev, eth);
-+ schedule_delayed_work(&eth->reset.monitor_work,
-+ MTK_DMA_MONITOR_TIMEOUT);
-
- return 0;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -256,6 +256,8 @@
-
- #define MTK_RX_DONE_INT_V2 BIT(14)
-
-+#define MTK_CDM_TXFIFO_RDY BIT(7)
-+
- /* QDMA Interrupt grouping registers */
- #define MTK_RLS_DONE_INT BIT(0)
-
-@@ -538,6 +540,17 @@
- #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c)
- #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110)
-
-+#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_MAC_FSM(x) (0x1010C + ((x) * 0x100))
-+
- struct mtk_rx_dma {
- unsigned int rxd1;
- unsigned int rxd2;
-@@ -934,6 +947,7 @@ struct mtk_reg_map {
- u32 delay_irq; /* delay interrupt */
- u32 irq_status; /* interrupt status */
- u32 irq_mask; /* interrupt mask */
-+ u32 adma_rx_dbg0;
- u32 int_grp;
- } pdma;
- struct {
-@@ -960,6 +974,8 @@ struct mtk_reg_map {
- u32 gdma_to_ppe0;
- u32 ppe_base;
- u32 wdma_base[2];
-+ u32 pse_iq_sta;
-+ u32 pse_oq_sta;
- };
-
- /* struct mtk_eth_data - This is the structure holding all differences
-@@ -1002,6 +1018,8 @@ struct mtk_soc_data {
- } txrx;
- };
-
-+#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
-+
- /* currently no SoC has more than 2 macs */
- #define MTK_MAX_DEVS 2
-
-@@ -1124,6 +1142,14 @@ struct mtk_eth {
- struct rhashtable flow_table;
-
- struct bpf_prog __rcu *prog;
-+
-+ struct {
-+ struct delayed_work monitor_work;
-+ u32 wdidx;
-+ u8 wdma_hang_count;
-+ u8 qdma_hang_count;
-+ u8 adma_hang_count;
-+ } reset;
- };
-
- /* struct mtk_mac - the structure that holds the info about the MACs of the
diff --git a/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch b/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch
deleted file mode 100644
index cc9aaaf0b8..0000000000
--- a/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:32 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks
-
-Introduce reset and reset_complete wlan callback to schedule WLAN driver
-reset when ethernet/wed driver is resetting.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3631,6 +3631,11 @@ static void mtk_pending_work(struct work
- set_bit(MTK_RESETTING, &eth->state);
-
- mtk_prepare_for_reset(eth);
-+ mtk_wed_fe_reset();
-+ /* Run again reset preliminary configuration in order to avoid any
-+ * possible race during FE reset since it can run releasing RTNL lock.
-+ */
-+ mtk_prepare_for_reset(eth);
-
- /* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-@@ -3668,6 +3673,8 @@ static void mtk_pending_work(struct work
-
- clear_bit(MTK_RESETTING, &eth->state);
-
-+ mtk_wed_fe_reset_complete();
-+
- rtnl_unlock();
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device *
- iounmap(reg);
- }
-
-+void mtk_wed_fe_reset(void)
-+{
-+ int i;
-+
-+ mutex_lock(&hw_lock);
-+
-+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
-+ struct mtk_wed_hw *hw = hw_list[i];
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+ int err;
-+
-+ if (!dev || !dev->wlan.reset)
-+ continue;
-+
-+ /* reset callback blocks until WLAN reset is completed */
-+ err = dev->wlan.reset(dev);
-+ if (err)
-+ dev_err(dev->dev, "wlan reset failed: %d\n", err);
-+ }
-+
-+ mutex_unlock(&hw_lock);
-+}
-+
-+void mtk_wed_fe_reset_complete(void)
-+{
-+ int i;
-+
-+ mutex_lock(&hw_lock);
-+
-+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
-+ struct mtk_wed_hw *hw = hw_list[i];
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev || !dev->wlan.reset_complete)
-+ continue;
-+
-+ dev->wlan.reset_complete(dev);
-+ }
-+
-+ mutex_unlock(&hw_lock);
-+}
-+
- static struct mtk_wed_hw *
- mtk_wed_assign(struct mtk_wed_device *dev)
- {
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node *
- void mtk_wed_exit(void);
- int mtk_wed_flow_add(int index);
- void mtk_wed_flow_remove(int index);
-+void mtk_wed_fe_reset(void);
-+void mtk_wed_fe_reset_complete(void);
- #else
- static inline void
- mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i
- {
- }
-
-+static inline void mtk_wed_fe_reset(void)
-+{
-+}
-+
-+static inline void mtk_wed_fe_reset_complete(void)
-+{
-+}
- #endif
-
- #ifdef CONFIG_DEBUG_FS
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -151,6 +151,8 @@ struct mtk_wed_device {
- void (*release_rx_buf)(struct mtk_wed_device *wed);
- void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
- struct mtk_wed_wo_rx_stats *stats);
-+ int (*reset)(struct mtk_wed_device *wed);
-+ void (*reset_complete)(struct mtk_wed_device *wed);
- } wlan;
- #endif
- };
diff --git a/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch b/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch
deleted file mode 100644
index c63628da99..0000000000
--- a/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 5 Dec 2022 12:34:42 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback
-
-This patch adds reset parameter to mtk_wed_rx_ring_setup signature
-in order to align rx_ring_setup callback to tx_ring_setup one introduced
-in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to
-tx_ring_setup callback")'
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1252,7 +1252,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
- }
-
- static int
--mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
-+ bool reset)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-@@ -1261,8 +1262,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
- return -EINVAL;
-
- wdma = &dev->tx_wdma[idx];
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-- true))
-+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1272,6 +1273,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
-
-+ if (reset)
-+ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true);
-+
- if (!idx) {
- wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
-@@ -1611,18 +1615,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed
- }
-
- static int
--mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
-+ bool reset)
- {
- struct mtk_wed_ring *ring = &dev->rx_ring[idx];
-
- if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
- return -EINVAL;
-
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
-- sizeof(*ring->desc), false))
-+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
-+ sizeof(*ring->desc), false))
- return -ENOMEM;
-
-- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
-+ reset))
- return -ENOMEM;
-
- ring->reg_base = MTK_WED_RING_RX_DATA(idx);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -162,7 +162,7 @@ struct mtk_wed_ops {
- int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs, bool reset);
- int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-- void __iomem *regs);
-+ void __iomem *regs, bool reset);
- int (*txfree_ring_setup)(struct mtk_wed_device *dev,
- void __iomem *regs);
- int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
-@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- (_dev)->ops->irq_get(_dev, _mask)
- #define mtk_wed_device_irq_set_mask(_dev, _mask) \
- (_dev)->ops->irq_set_mask(_dev, _mask)
--#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
-- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
-+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset)
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
- (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
-@@ -251,7 +251,7 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
- #define mtk_wed_device_irq_get(_dev, _mask) 0
- #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
--#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
- #define mtk_wed_device_stop(_dev) do {} while (0)
diff --git a/target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch b/target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch
deleted file mode 100644
index 45af898cf0..0000000000
--- a/target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 19:50:31 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: account for vlan in rx
- header length
-
-The network stack assumes that devices can handle an extra VLAN tag without
-increasing the MTU
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -29,7 +29,7 @@
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_DMA_SIZE 512
- #define MTK_MAC_COUNT 2
--#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
-+#define MTK_RX_ETH_HLEN (VLAN_ETH_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 | \
diff --git a/target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch b/target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch
deleted file mode 100644
index 908b2d88f3..0000000000
--- a/target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 19:53:57 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: increase tx ring side for
- QDMA devices
-
-In order to use the hardware traffic shaper feature, a larger tx ring is
-needed, especially for the scratch ring, which the hardware shaper uses to
-reorder packets.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -900,7 +900,7 @@ static int mtk_init_fq_dma(struct mtk_et
- {
- const struct mtk_soc_data *soc = eth->soc;
- dma_addr_t phy_ring_tail;
-- int cnt = MTK_DMA_SIZE;
-+ int cnt = MTK_QDMA_RING_SIZE;
- dma_addr_t dma_addr;
- int i;
-
-@@ -2154,19 +2154,25 @@ static int mtk_tx_alloc(struct mtk_eth *
- struct mtk_tx_ring *ring = &eth->tx_ring;
- int i, sz = soc->txrx.txd_size;
- struct mtk_tx_dma_v2 *txd;
-+ int ring_size;
-
-- ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf),
-+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
-+ ring_size = MTK_QDMA_RING_SIZE;
-+ else
-+ ring_size = MTK_DMA_SIZE;
-+
-+ ring->buf = kcalloc(ring_size, sizeof(*ring->buf),
- GFP_KERNEL);
- if (!ring->buf)
- goto no_tx_mem;
-
-- ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
-+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
- &ring->phys, GFP_KERNEL);
- if (!ring->dma)
- goto no_tx_mem;
-
-- for (i = 0; i < MTK_DMA_SIZE; i++) {
-- int next = (i + 1) % MTK_DMA_SIZE;
-+ for (i = 0; i < ring_size; i++) {
-+ int next = (i + 1) % ring_size;
- u32 next_ptr = ring->phys + next * sz;
-
- txd = ring->dma + i * sz;
-@@ -2186,22 +2192,22 @@ static int mtk_tx_alloc(struct mtk_eth *
- * descriptors in ring->dma_pdma.
- */
- if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
-+ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
- &ring->phys_pdma, GFP_KERNEL);
- if (!ring->dma_pdma)
- goto no_tx_mem;
-
-- for (i = 0; i < MTK_DMA_SIZE; i++) {
-+ for (i = 0; i < ring_size; i++) {
- ring->dma_pdma[i].txd2 = TX_DMA_DESP2_DEF;
- ring->dma_pdma[i].txd4 = 0;
- }
- }
-
-- ring->dma_size = MTK_DMA_SIZE;
-- atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
-+ ring->dma_size = ring_size;
-+ atomic_set(&ring->free_count, ring_size - 2);
- ring->next_free = ring->dma;
- ring->last_free = (void *)txd;
-- ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz));
-+ ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz));
- ring->thresh = MAX_SKB_FRAGS;
-
- /* make sure that all changes to the dma ring are flushed before we
-@@ -2213,14 +2219,14 @@ static int mtk_tx_alloc(struct mtk_eth *
- mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr);
- mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr);
- mtk_w32(eth,
-- ring->phys + ((MTK_DMA_SIZE - 1) * sz),
-+ ring->phys + ((ring_size - 1) * sz),
- soc->reg_map->qdma.crx_ptr);
- mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
- soc->reg_map->qdma.qtx_cfg);
- } else {
- mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
-- mtk_w32(eth, MTK_DMA_SIZE, MT7628_TX_MAX_CNT0);
-+ mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0);
- mtk_w32(eth, 0, MT7628_TX_CTX_IDX0);
- mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx);
- }
-@@ -2238,7 +2244,7 @@ static void mtk_tx_clean(struct mtk_eth
- int i;
-
- if (ring->buf) {
-- for (i = 0; i < MTK_DMA_SIZE; i++)
-+ for (i = 0; i < ring->dma_size; i++)
- mtk_tx_unmap(eth, &ring->buf[i], false);
- kfree(ring->buf);
- ring->buf = NULL;
-@@ -2246,14 +2252,14 @@ static void mtk_tx_clean(struct mtk_eth
-
- if (ring->dma) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * soc->txrx.txd_size,
-+ ring->dma_size * soc->txrx.txd_size,
- ring->dma, ring->phys);
- ring->dma = NULL;
- }
-
- if (ring->dma_pdma) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * soc->txrx.txd_size,
-+ ring->dma_size * soc->txrx.txd_size,
- ring->dma_pdma, ring->phys_pdma);
- ring->dma_pdma = NULL;
- }
-@@ -2776,7 +2782,7 @@ static void mtk_dma_free(struct mtk_eth
- netdev_reset_queue(eth->netdev[i]);
- if (eth->scratch_ring) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * soc->txrx.txd_size,
-+ MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
- eth->scratch_ring, eth->phy_scratch_ring);
- eth->scratch_ring = NULL;
- eth->phy_scratch_ring = 0;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -27,6 +27,7 @@
- #define MTK_MAX_RX_LENGTH_2K 2048
- #define MTK_TX_DMA_BUF_LEN 0x3fff
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
-+#define MTK_QDMA_RING_SIZE 2048
- #define MTK_DMA_SIZE 512
- #define MTK_MAC_COUNT 2
- #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN)
diff --git a/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch b/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch
deleted file mode 100644
index 34aa7b14cd..0000000000
--- a/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Nov 2022 19:49:08 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid port_mg assignment on
- MT7622 and newer
-
-On newer chips, this field is unused and contains some bits related to queue
-assignment. Initialize it to 0 in those cases.
-Fix offload_version on MT7621 and MT7623, which still need the previous value.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4424,7 +4424,7 @@ static const struct mtk_soc_data mt7621_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7621_CLKS_BITMAP,
- .required_pctl = false,
-- .offload_version = 2,
-+ .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
-@@ -4463,7 +4463,7 @@ static const struct mtk_soc_data mt7623_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
-- .offload_version = 2,
-+ .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -175,6 +175,8 @@ int mtk_foe_entry_prepare(struct mtk_eth
- val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) |
- FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf);
- } else {
-+ int port_mg = eth->soc->offload_version > 1 ? 0 : 0x3f;
-+
- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) |
- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
-@@ -182,7 +184,7 @@ int mtk_foe_entry_prepare(struct mtk_eth
- entry->ib1 = val;
-
- val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) |
-- FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) |
-+ FIELD_PREP(MTK_FOE_IB2_PORT_MG, port_mg) |
- FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f);
- }
-
diff --git a/target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch b/target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch
deleted file mode 100644
index 765666602e..0000000000
--- a/target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch
+++ /dev/null
@@ -1,654 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 20:17:27 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: implement multi-queue
- support for per-port queues
-
-When sending traffic to multiple ports with different link speeds, queued
-packets to one port can drown out tx to other ports.
-In order to better handle transmission to multiple ports, use the hardware
-shaper feature to implement weighted fair queueing between ports.
-Weight and maximum rate are automatically adjusted based on the link speed
-of the port.
-The first 3 queues are unrestricted and reserved for non-DSA direct tx on
-GMAC ports. The following queues are automatically assigned by the MTK DSA
-tag driver based on the target port number.
-The PPE offload code configures the queues for offloaded traffic in the same
-way.
-This feature is only supported on devices supporting QDMA. All queues still
-share the same DMA ring and descriptor pool.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -55,6 +55,7 @@ static const struct mtk_reg_map mtk_reg_
- },
- .qdma = {
- .qtx_cfg = 0x1800,
-+ .qtx_sch = 0x1804,
- .rx_ptr = 0x1900,
- .rx_cnt_cfg = 0x1904,
- .qcrx_ptr = 0x1908,
-@@ -62,6 +63,7 @@ static const struct mtk_reg_map mtk_reg_
- .rst_idx = 0x1a08,
- .delay_irq = 0x1a0c,
- .fc_th = 0x1a10,
-+ .tx_sch_rate = 0x1a14,
- .int_grp = 0x1a20,
- .hred = 0x1a44,
- .ctx_ptr = 0x1b00,
-@@ -117,6 +119,7 @@ static const struct mtk_reg_map mt7986_r
- },
- .qdma = {
- .qtx_cfg = 0x4400,
-+ .qtx_sch = 0x4404,
- .rx_ptr = 0x4500,
- .rx_cnt_cfg = 0x4504,
- .qcrx_ptr = 0x4508,
-@@ -134,6 +137,7 @@ static const struct mtk_reg_map mt7986_r
- .fq_tail = 0x4724,
- .fq_count = 0x4728,
- .fq_blen = 0x472c,
-+ .tx_sch_rate = 0x4798,
- },
- .gdm1_cnt = 0x1c00,
- .gdma_to_ppe0 = 0x3333,
-@@ -576,6 +580,75 @@ static void mtk_mac_link_down(struct phy
- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-
-+static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-+ int speed)
-+{
-+ const struct mtk_soc_data *soc = eth->soc;
-+ u32 ofs, val;
-+
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA))
-+ return;
-+
-+ val = MTK_QTX_SCH_MIN_RATE_EN |
-+ /* minimum: 10 Mbps */
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-+
-+ if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-+ switch (speed) {
-+ case SPEED_10:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 2) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_100:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3);
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_1000:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 105) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10);
-+ break;
-+ default:
-+ break;
-+ }
-+ } else {
-+ switch (speed) {
-+ case SPEED_10:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_100:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5);
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_1000:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ ofs = MTK_QTX_OFFSET * idx;
-+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
-+}
-+
- static void mtk_mac_link_up(struct phylink_config *config,
- struct phy_device *phy,
- unsigned int mode, phy_interface_t interface,
-@@ -601,6 +674,8 @@ static void mtk_mac_link_up(struct phyli
- break;
- }
-
-+ mtk_set_queue_speed(mac->hw, mac->id, speed);
-+
- /* Configure duplex */
- if (duplex == DUPLEX_FULL)
- mcr |= MAC_MCR_FORCE_DPX;
-@@ -1059,7 +1134,8 @@ static void mtk_tx_set_dma_desc_v1(struc
-
- WRITE_ONCE(desc->txd1, info->addr);
-
-- data = TX_DMA_SWC | TX_DMA_PLEN0(info->size);
-+ data = TX_DMA_SWC | TX_DMA_PLEN0(info->size) |
-+ FIELD_PREP(TX_DMA_PQID, info->qid);
- if (info->last)
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-@@ -1093,9 +1169,6 @@ static void mtk_tx_set_dma_desc_v2(struc
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-
-- if (!info->qid && mac->id)
-- info->qid = MTK_QDMA_GMAC2_QID;
--
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
- data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
- WRITE_ONCE(desc->txd4, data);
-@@ -1139,11 +1212,12 @@ static int mtk_tx_map(struct sk_buff *sk
- .gso = gso,
- .csum = skb->ip_summed == CHECKSUM_PARTIAL,
- .vlan = skb_vlan_tag_present(skb),
-- .qid = skb->mark & MTK_QDMA_TX_MASK,
-+ .qid = skb_get_queue_mapping(skb),
- .vlan_tci = skb_vlan_tag_get(skb),
- .first = true,
- .last = !skb_is_nonlinear(skb),
- };
-+ struct netdev_queue *txq;
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
- const struct mtk_soc_data *soc = eth->soc;
-@@ -1151,8 +1225,10 @@ static int mtk_tx_map(struct sk_buff *sk
- struct mtk_tx_dma *itxd_pdma, *txd_pdma;
- struct mtk_tx_buf *itx_buf, *tx_buf;
- int i, n_desc = 1;
-+ int queue = skb_get_queue_mapping(skb);
- int k = 0;
-
-+ txq = netdev_get_tx_queue(dev, queue);
- itxd = ring->next_free;
- itxd_pdma = qdma_to_pdma(ring, itxd);
- if (itxd == ring->last_free)
-@@ -1201,7 +1277,7 @@ static int mtk_tx_map(struct sk_buff *sk
- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
- txd_info.size = min_t(unsigned int, frag_size,
- soc->txrx.dma_max_len);
-- txd_info.qid = skb->mark & MTK_QDMA_TX_MASK;
-+ txd_info.qid = queue;
- txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
- !(frag_size - txd_info.size);
- txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
-@@ -1240,7 +1316,7 @@ static int mtk_tx_map(struct sk_buff *sk
- txd_pdma->txd2 |= TX_DMA_LS1;
- }
-
-- netdev_sent_queue(dev, skb->len);
-+ netdev_tx_sent_queue(txq, skb->len);
- skb_tx_timestamp(skb);
-
- ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-@@ -1252,8 +1328,7 @@ static int mtk_tx_map(struct sk_buff *sk
- wmb();
-
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-- if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) ||
-- !netdev_xmit_more())
-+ if (netif_xmit_stopped(txq) || !netdev_xmit_more())
- mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr);
- } else {
- int next_idx;
-@@ -1322,7 +1397,7 @@ static void mtk_wake_queue(struct mtk_et
- for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!eth->netdev[i])
- continue;
-- netif_wake_queue(eth->netdev[i]);
-+ netif_tx_wake_all_queues(eth->netdev[i]);
- }
- }
-
-@@ -1346,7 +1421,7 @@ static netdev_tx_t mtk_start_xmit(struct
-
- tx_num = mtk_cal_txd_req(eth, skb);
- if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
-- netif_stop_queue(dev);
-+ netif_tx_stop_all_queues(dev);
- netif_err(eth, tx_queued, dev,
- "Tx Ring full when queue awake!\n");
- spin_unlock(&eth->page_lock);
-@@ -1372,7 +1447,7 @@ static netdev_tx_t mtk_start_xmit(struct
- goto drop;
-
- if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
-- netif_stop_queue(dev);
-+ netif_tx_stop_all_queues(dev);
-
- spin_unlock(&eth->page_lock);
-
-@@ -1539,10 +1614,12 @@ static int mtk_xdp_submit_frame(struct m
- struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf);
- const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_ring *ring = &eth->tx_ring;
-+ struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_tx_dma_desc_info txd_info = {
- .size = xdpf->len,
- .first = true,
- .last = !xdp_frame_has_frags(xdpf),
-+ .qid = mac->id,
- };
- int err, index = 0, n_desc = 1, nr_frags;
- struct mtk_tx_dma *htxd, *txd, *txd_pdma;
-@@ -1593,6 +1670,7 @@ static int mtk_xdp_submit_frame(struct m
- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
- txd_info.size = skb_frag_size(&sinfo->frags[index]);
- txd_info.last = index + 1 == nr_frags;
-+ txd_info.qid = mac->id;
- data = skb_frag_address(&sinfo->frags[index]);
-
- index++;
-@@ -1944,8 +2022,46 @@ rx_done:
- return done;
- }
-
-+struct mtk_poll_state {
-+ struct netdev_queue *txq;
-+ unsigned int total;
-+ unsigned int done;
-+ unsigned int bytes;
-+};
-+
-+static void
-+mtk_poll_tx_done(struct mtk_eth *eth, struct mtk_poll_state *state, u8 mac,
-+ struct sk_buff *skb)
-+{
-+ struct netdev_queue *txq;
-+ struct net_device *dev;
-+ unsigned int bytes = skb->len;
-+
-+ state->total++;
-+ eth->tx_packets++;
-+ eth->tx_bytes += bytes;
-+
-+ dev = eth->netdev[mac];
-+ if (!dev)
-+ return;
-+
-+ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
-+ if (state->txq == txq) {
-+ state->done++;
-+ state->bytes += bytes;
-+ return;
-+ }
-+
-+ if (state->txq)
-+ netdev_tx_completed_queue(state->txq, state->done, state->bytes);
-+
-+ state->txq = txq;
-+ state->done = 1;
-+ state->bytes = bytes;
-+}
-+
- static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
-- unsigned int *done, unsigned int *bytes)
-+ struct mtk_poll_state *state)
- {
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct mtk_tx_ring *ring = &eth->tx_ring;
-@@ -1975,12 +2091,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
- break;
-
- if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-- if (tx_buf->type == MTK_TYPE_SKB) {
-- struct sk_buff *skb = tx_buf->data;
-+ if (tx_buf->type == MTK_TYPE_SKB)
-+ mtk_poll_tx_done(eth, state, mac, tx_buf->data);
-
-- bytes[mac] += skb->len;
-- done[mac]++;
-- }
- budget--;
- }
- mtk_tx_unmap(eth, tx_buf, true);
-@@ -1998,7 +2111,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
- }
-
- static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget,
-- unsigned int *done, unsigned int *bytes)
-+ struct mtk_poll_state *state)
- {
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct mtk_tx_buf *tx_buf;
-@@ -2014,12 +2127,8 @@ static int mtk_poll_tx_pdma(struct mtk_e
- break;
-
- if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-- if (tx_buf->type == MTK_TYPE_SKB) {
-- struct sk_buff *skb = tx_buf->data;
--
-- bytes[0] += skb->len;
-- done[0]++;
-- }
-+ if (tx_buf->type == MTK_TYPE_SKB)
-+ mtk_poll_tx_done(eth, state, 0, tx_buf->data);
- budget--;
- }
- mtk_tx_unmap(eth, tx_buf, true);
-@@ -2040,26 +2149,15 @@ static int mtk_poll_tx(struct mtk_eth *e
- {
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct dim_sample dim_sample = {};
-- unsigned int done[MTK_MAX_DEVS];
-- unsigned int bytes[MTK_MAX_DEVS];
-- int total = 0, i;
--
-- memset(done, 0, sizeof(done));
-- memset(bytes, 0, sizeof(bytes));
-+ struct mtk_poll_state state = {};
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-- budget = mtk_poll_tx_qdma(eth, budget, done, bytes);
-+ budget = mtk_poll_tx_qdma(eth, budget, &state);
- else
-- budget = mtk_poll_tx_pdma(eth, budget, done, bytes);
-+ budget = mtk_poll_tx_pdma(eth, budget, &state);
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i] || !done[i])
-- continue;
-- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
-- total += done[i];
-- eth->tx_packets += done[i];
-- eth->tx_bytes += bytes[i];
-- }
-+ if (state.txq)
-+ netdev_tx_completed_queue(state.txq, state.done, state.bytes);
-
- dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes,
- &dim_sample);
-@@ -2069,7 +2167,7 @@ static int mtk_poll_tx(struct mtk_eth *e
- (atomic_read(&ring->free_count) > ring->thresh))
- mtk_wake_queue(eth);
-
-- return total;
-+ return state.total;
- }
-
- static void mtk_handle_status_irq(struct mtk_eth *eth)
-@@ -2155,6 +2253,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- int i, sz = soc->txrx.txd_size;
- struct mtk_tx_dma_v2 *txd;
- int ring_size;
-+ u32 ofs, val;
-
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
- ring_size = MTK_QDMA_RING_SIZE;
-@@ -2222,8 +2321,25 @@ static int mtk_tx_alloc(struct mtk_eth *
- ring->phys + ((ring_size - 1) * sz),
- soc->reg_map->qdma.crx_ptr);
- mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
-- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
-- soc->reg_map->qdma.qtx_cfg);
-+
-+ for (i = 0, ofs = 0; i < MTK_QDMA_NUM_QUEUES; i++) {
-+ val = (QDMA_RES_THRES << 8) | QDMA_RES_THRES;
-+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs);
-+
-+ val = MTK_QTX_SCH_MIN_RATE_EN |
-+ /* minimum: 10 Mbps */
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
-+ ofs += MTK_QTX_OFFSET;
-+ }
-+ val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16);
-+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
- } else {
- mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
- mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0);
-@@ -2906,7 +3022,7 @@ static int mtk_start_dma(struct mtk_eth
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
- val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
- MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
-- MTK_CHK_DDONE_EN;
-+ MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
- else
- val |= MTK_RX_BT_32DWORDS;
- mtk_w32(eth, val, reg_map->qdma.glo_cfg);
-@@ -2952,6 +3068,45 @@ static void mtk_gdm_config(struct mtk_et
- mtk_w32(eth, 0, MTK_RST_GL);
- }
-
-+static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr)
-+{
-+ struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier);
-+ struct mtk_eth *eth = mac->hw;
-+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-+ struct ethtool_link_ksettings s;
-+ struct net_device *ldev;
-+ struct list_head *iter;
-+ struct dsa_port *dp;
-+
-+ if (event != NETDEV_CHANGE)
-+ return NOTIFY_DONE;
-+
-+ netdev_for_each_lower_dev(dev, ldev, iter) {
-+ if (netdev_priv(ldev) == mac)
-+ goto found;
-+ }
-+
-+ return NOTIFY_DONE;
-+
-+found:
-+ if (!dsa_slave_dev_check(dev))
-+ return NOTIFY_DONE;
-+
-+ if (__ethtool_get_link_ksettings(dev, &s))
-+ return NOTIFY_DONE;
-+
-+ if (s.base.speed == 0 || s.base.speed == ((__u32)-1))
-+ return NOTIFY_DONE;
-+
-+ dp = dsa_port_from_netdev(dev);
-+ if (dp->index >= MTK_QDMA_NUM_QUEUES)
-+ return NOTIFY_DONE;
-+
-+ mtk_set_queue_speed(eth, dp->index + 3, s.base.speed);
-+
-+ return NOTIFY_DONE;
-+}
-+
- static int mtk_open(struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
-@@ -2996,7 +3151,8 @@ static int mtk_open(struct net_device *d
- refcount_inc(&eth->dma_refcnt);
-
- phylink_start(mac->phylink);
-- netif_start_queue(dev);
-+ netif_tx_start_all_queues(dev);
-+
- return 0;
- }
-
-@@ -3702,8 +3858,12 @@ static int mtk_unreg_dev(struct mtk_eth
- int i;
-
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ struct mtk_mac *mac;
- if (!eth->netdev[i])
- continue;
-+ mac = netdev_priv(eth->netdev[i]);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-+ unregister_netdevice_notifier(&mac->device_notifier);
- unregister_netdev(eth->netdev[i]);
- }
-
-@@ -3920,6 +4080,23 @@ static int mtk_set_rxnfc(struct net_devi
- return ret;
- }
-
-+static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb,
-+ struct net_device *sb_dev)
-+{
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ unsigned int queue = 0;
-+
-+ if (netdev_uses_dsa(dev))
-+ queue = skb_get_queue_mapping(skb) + 3;
-+ else
-+ queue = mac->id;
-+
-+ if (queue >= dev->num_tx_queues)
-+ queue = 0;
-+
-+ return queue;
-+}
-+
- static const struct ethtool_ops mtk_ethtool_ops = {
- .get_link_ksettings = mtk_get_link_ksettings,
- .set_link_ksettings = mtk_set_link_ksettings,
-@@ -3954,6 +4131,7 @@ static const struct net_device_ops mtk_n
- .ndo_setup_tc = mtk_eth_setup_tc,
- .ndo_bpf = mtk_xdp,
- .ndo_xdp_xmit = mtk_xdp_xmit,
-+ .ndo_select_queue = mtk_select_queue,
- };
-
- static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
-@@ -3963,6 +4141,7 @@ static int mtk_add_mac(struct mtk_eth *e
- struct phylink *phylink;
- struct mtk_mac *mac;
- int id, err;
-+ int txqs = 1;
-
- if (!_id) {
- dev_err(eth->dev, "missing mac id\n");
-@@ -3980,7 +4159,10 @@ static int mtk_add_mac(struct mtk_eth *e
- return -EINVAL;
- }
-
-- eth->netdev[id] = alloc_etherdev(sizeof(*mac));
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-+ txqs = MTK_QDMA_NUM_QUEUES;
-+
-+ eth->netdev[id] = alloc_etherdev_mqs(sizeof(*mac), txqs, 1);
- if (!eth->netdev[id]) {
- dev_err(eth->dev, "alloc_etherdev failed\n");
- return -ENOMEM;
-@@ -4088,6 +4270,11 @@ static int mtk_add_mac(struct mtk_eth *e
- else
- eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN;
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-+ mac->device_notifier.notifier_call = mtk_device_event;
-+ register_netdevice_notifier(&mac->device_notifier);
-+ }
-+
- return 0;
-
- free_netdev:
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -22,6 +22,7 @@
- #include <linux/bpf_trace.h>
- #include "mtk_ppe.h"
-
-+#define MTK_QDMA_NUM_QUEUES 16
- #define MTK_QDMA_PAGE_SIZE 2048
- #define MTK_MAX_RX_LENGTH 1536
- #define MTK_MAX_RX_LENGTH_2K 2048
-@@ -215,8 +216,26 @@
- #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3)
-
- /* QDMA TX Queue Configuration Registers */
-+#define MTK_QTX_OFFSET 0x10
- #define QDMA_RES_THRES 4
-
-+/* QDMA Tx Queue Scheduler Configuration Registers */
-+#define MTK_QTX_SCH_TX_SEL BIT(31)
-+#define MTK_QTX_SCH_TX_SEL_V2 GENMASK(31, 30)
-+
-+#define MTK_QTX_SCH_LEAKY_BUCKET_EN BIT(30)
-+#define MTK_QTX_SCH_LEAKY_BUCKET_SIZE GENMASK(29, 28)
-+#define MTK_QTX_SCH_MIN_RATE_EN BIT(27)
-+#define MTK_QTX_SCH_MIN_RATE_MAN GENMASK(26, 20)
-+#define MTK_QTX_SCH_MIN_RATE_EXP GENMASK(19, 16)
-+#define MTK_QTX_SCH_MAX_RATE_WEIGHT GENMASK(15, 12)
-+#define MTK_QTX_SCH_MAX_RATE_EN BIT(11)
-+#define MTK_QTX_SCH_MAX_RATE_MAN GENMASK(10, 4)
-+#define MTK_QTX_SCH_MAX_RATE_EXP GENMASK(3, 0)
-+
-+/* QDMA TX Scheduler Rate Control Register */
-+#define MTK_QDMA_TX_SCH_MAX_WFQ BIT(15)
-+
- /* QDMA Global Configuration Register */
- #define MTK_RX_2B_OFFSET BIT(31)
- #define MTK_RX_BT_32DWORDS (3 << 11)
-@@ -235,6 +254,7 @@
- #define MTK_WCOMP_EN BIT(24)
- #define MTK_RESV_BUF (0x40 << 16)
- #define MTK_MUTLI_CNT (0x4 << 12)
-+#define MTK_LEAKY_BUCKET_EN BIT(11)
-
- /* QDMA Flow Control Register */
- #define FC_THRES_DROP_MODE BIT(20)
-@@ -265,8 +285,6 @@
- #define MTK_STAT_OFFSET 0x40
-
- /* QDMA TX NUM */
--#define MTK_QDMA_TX_NUM 16
--#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1)
- #define QID_BITS_V2(x) (((x) & 0x3f) << 16)
- #define MTK_QDMA_GMAC2_QID 8
-
-@@ -296,6 +314,7 @@
- #define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
- #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len)
- #define TX_DMA_SWC BIT(14)
-+#define TX_DMA_PQID GENMASK(3, 0)
-
- /* PDMA on MT7628 */
- #define TX_DMA_DONE BIT(31)
-@@ -953,6 +972,7 @@ struct mtk_reg_map {
- } pdma;
- struct {
- u32 qtx_cfg; /* tx queue configuration */
-+ u32 qtx_sch; /* tx queue scheduler configuration */
- u32 rx_ptr; /* rx base pointer */
- u32 rx_cnt_cfg; /* rx max count configuration */
- u32 qcrx_ptr; /* rx cpu pointer */
-@@ -970,6 +990,7 @@ struct mtk_reg_map {
- u32 fq_tail; /* fq tail pointer */
- u32 fq_count; /* fq free page count */
- u32 fq_blen; /* fq free page buffer length */
-+ u32 tx_sch_rate; /* tx scheduler rate control registers */
- } qdma;
- u32 gdm1_cnt;
- u32 gdma_to_ppe0;
-@@ -1173,6 +1194,7 @@ struct mtk_mac {
- __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
- int hwlro_ip_cnt;
- unsigned int syscfg0;
-+ struct notifier_block device_notifier;
- };
-
- /* the struct describing the SoC. these are declared in the soc_xyz.c files */
diff --git a/target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch b/target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch
deleted file mode 100644
index 186df4bdc9..0000000000
--- a/target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 18:16:03 +0200
-Subject: [PATCH] net: dsa: tag_mtk: assign per-port queues
-
-Keeps traffic sent to the switch within link speed limits
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/dsa/tag_mtk.c
-+++ b/net/dsa/tag_mtk.c
-@@ -25,6 +25,8 @@ static struct sk_buff *mtk_tag_xmit(stru
- u8 xmit_tpid;
- u8 *mtk_tag;
-
-+ skb_set_queue_mapping(skb, dp->index);
-+
- /* Build the special tag after the MAC Source Address. If VLAN header
- * is present, it's required that VLAN header and special tag is
- * being combined. Only in this way we can allow the switch can parse
diff --git a/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch b/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch
deleted file mode 100644
index e05042c204..0000000000
--- a/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 3 Nov 2022 17:49:44 +0100
-Subject: [PATCH] net: ethernet: mediatek: ppe: assign per-port queues
- for offloaded traffic
-
-Keeps traffic sent to the switch within link speed limits
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -405,6 +405,24 @@ static inline bool mtk_foe_entry_usable(
- FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND;
- }
-
-+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ unsigned int queue)
-+{
-+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ *ib2 &= ~MTK_FOE_IB2_QID_V2;
-+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue);
-+ *ib2 |= MTK_FOE_IB2_PSE_QOS_V2;
-+ } else {
-+ *ib2 &= ~MTK_FOE_IB2_QID;
-+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID, queue);
-+ *ib2 |= MTK_FOE_IB2_PSE_QOS;
-+ }
-+
-+ return 0;
-+}
-+
- static bool
- mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry,
- struct mtk_foe_entry *data)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -68,7 +68,9 @@ enum {
- #define MTK_FOE_IB2_DSCP GENMASK(31, 24)
-
- /* CONFIG_MEDIATEK_NETSYS_V2 */
-+#define MTK_FOE_IB2_QID_V2 GENMASK(6, 0)
- #define MTK_FOE_IB2_PORT_MG_V2 BIT(7)
-+#define MTK_FOE_IB2_PSE_QOS_V2 BIT(8)
- #define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9)
- #define MTK_FOE_IB2_MULTICAST_V2 BIT(13)
- #define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19)
-@@ -352,6 +354,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
- int sid);
- int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
- int wdma_idx, int txq, int bss, int wcid);
-+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ unsigned int queue);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -188,7 +188,7 @@ mtk_flow_set_output_device(struct mtk_et
- int *wed_index)
- {
- struct mtk_wdma_info info = {};
-- int pse_port, dsa_port;
-+ int pse_port, dsa_port, queue;
-
- if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
- mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
-@@ -212,8 +212,6 @@ mtk_flow_set_output_device(struct mtk_et
- }
-
- dsa_port = mtk_flow_get_dsa_port(&dev);
-- if (dsa_port >= 0)
-- mtk_foe_entry_set_dsa(eth, foe, dsa_port);
-
- if (dev == eth->netdev[0])
- pse_port = 1;
-@@ -222,6 +220,14 @@ mtk_flow_set_output_device(struct mtk_et
- else
- return -EOPNOTSUPP;
-
-+ if (dsa_port >= 0) {
-+ mtk_foe_entry_set_dsa(eth, foe, dsa_port);
-+ queue = 3 + dsa_port;
-+ } else {
-+ queue = pse_port - 1;
-+ }
-+ mtk_foe_entry_set_queue(eth, foe, queue);
-+
- out:
- mtk_foe_entry_set_pse_port(eth, foe, pse_port);
-
diff --git a/target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch b/target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch
deleted file mode 100644
index 0478cb528e..0000000000
--- a/target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 8 Nov 2022 15:03:15 +0100
-Subject: [PATCH] net: dsa: add support for DSA rx offloading via
- metadata dst
-
-If a metadata dst is present with the type METADATA_HW_PORT_MUX on a dsa cpu
-port netdev, assume that it carries the port number and that there is no DSA
-tag present in the skb data.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/core/flow_dissector.c
-+++ b/net/core/flow_dissector.c
-@@ -940,12 +940,14 @@ bool __skb_flow_dissect(const struct net
- #if IS_ENABLED(CONFIG_NET_DSA)
- if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
- proto == htons(ETH_P_XDSA))) {
-+ struct metadata_dst *md_dst = skb_metadata_dst(skb);
- const struct dsa_device_ops *ops;
- int offset = 0;
-
- ops = skb->dev->dsa_ptr->tag_ops;
- /* Only DSA header taggers break flow dissection */
-- if (ops->needed_headroom) {
-+ if (ops->needed_headroom &&
-+ (!md_dst || md_dst->type != METADATA_HW_PORT_MUX)) {
- if (ops->flow_dissect)
- ops->flow_dissect(skb, &proto, &offset);
- else
---- a/net/dsa/dsa.c
-+++ b/net/dsa/dsa.c
-@@ -20,6 +20,7 @@
- #include <linux/phy_fixed.h>
- #include <linux/ptp_classify.h>
- #include <linux/etherdevice.h>
-+#include <net/dst_metadata.h>
-
- #include "dsa_priv.h"
-
-@@ -225,6 +226,7 @@ static bool dsa_skb_defer_rx_timestamp(s
- static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *pt, struct net_device *unused)
- {
-+ struct metadata_dst *md_dst = skb_metadata_dst(skb);
- struct dsa_port *cpu_dp = dev->dsa_ptr;
- struct sk_buff *nskb = NULL;
- struct dsa_slave_priv *p;
-@@ -238,7 +240,22 @@ static int dsa_switch_rcv(struct sk_buff
- if (!skb)
- return 0;
-
-- nskb = cpu_dp->rcv(skb, dev);
-+ if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) {
-+ unsigned int port = md_dst->u.port_info.port_id;
-+
-+ skb_dst_drop(skb);
-+ if (!skb_has_extensions(skb))
-+ skb->slow_gro = 0;
-+
-+ skb->dev = dsa_master_find_slave(dev, 0, port);
-+ if (likely(skb->dev)) {
-+ dsa_default_offload_fwd_mark(skb);
-+ nskb = skb;
-+ }
-+ } else {
-+ nskb = cpu_dp->rcv(skb, dev);
-+ }
-+
- if (!nskb) {
- kfree_skb(skb);
- return 0;
diff --git a/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch
deleted file mode 100644
index b64f434365..0000000000
--- a/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 11:01:12 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix VLAN rx hardware
- acceleration
-
-- enable VLAN untagging for PDMA rx
-- make it possible to disable the feature via ethtool
-- pass VLAN tag to the DSA driver
-- untag special tag on PDMA only if no non-DSA devices are in use
-- disable special tag untagging on 7986 for now, since it's not working yet
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -23,6 +23,7 @@
- #include <linux/jhash.h>
- #include <linux/bitfield.h>
- #include <net/dsa.h>
-+#include <net/dst_metadata.h>
-
- #include "mtk_eth_soc.h"
- #include "mtk_wed.h"
-@@ -1973,16 +1974,22 @@ static int mtk_poll_rx(struct napi_struc
- htons(RX_DMA_VPID(trxd.rxd4)),
- RX_DMA_VID(trxd.rxd4));
- } else if (trxd.rxd2 & RX_DMA_VTAG) {
-- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-+ __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)),
- RX_DMA_VID(trxd.rxd3));
- }
-+ }
-+
-+ /* When using VLAN untagging in combination with DSA, the
-+ * hardware treats the MTK special tag as a VLAN and untags it.
-+ */
-+ if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) {
-+ unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0);
-
-- /* If the device is attached to a dsa switch, the special
-- * tag inserted in VLAN field by hw switch can * be offloaded
-- * by RX HW VLAN offload. Clear vlan info.
-- */
-- if (netdev_uses_dsa(netdev))
-- __vlan_hwaccel_clear_tag(skb);
-+ if (port < ARRAY_SIZE(eth->dsa_meta) &&
-+ eth->dsa_meta[port])
-+ skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
-+
-+ __vlan_hwaccel_clear_tag(skb);
- }
-
- skb_record_rx_queue(skb, 0);
-@@ -2802,15 +2809,30 @@ static netdev_features_t mtk_fix_feature
-
- static int mtk_set_features(struct net_device *dev, netdev_features_t features)
- {
-- int err = 0;
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+ netdev_features_t diff = dev->features ^ features;
-+ int i;
-+
-+ if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
-+ mtk_hwlro_netdev_disable(dev);
-
-- if (!((dev->features ^ features) & NETIF_F_LRO))
-+ /* Set RX VLAN offloading */
-+ if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
- return 0;
-
-- if (!(features & NETIF_F_LRO))
-- mtk_hwlro_netdev_disable(dev);
-+ mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
-+ MTK_CDMP_EG_CTRL);
-
-- return err;
-+ /* sync features with other MAC */
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i] || eth->netdev[i] == dev)
-+ continue;
-+ eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
-+ eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
-+ }
-+
-+ return 0;
- }
-
- /* wait for DMA to finish whatever it is doing before we start using it again */
-@@ -3107,11 +3129,45 @@ found:
- return NOTIFY_DONE;
- }
-
-+static bool mtk_uses_dsa(struct net_device *dev)
-+{
-+#if IS_ENABLED(CONFIG_NET_DSA)
-+ return netdev_uses_dsa(dev) &&
-+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK;
-+#else
-+ return false;
-+#endif
-+}
-+
- static int mtk_open(struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-- int err;
-+ int i, err;
-+
-+ if (mtk_uses_dsa(dev) && !eth->prog) {
-+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+ struct metadata_dst *md_dst = eth->dsa_meta[i];
-+
-+ if (md_dst)
-+ continue;
-+
-+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-+ GFP_KERNEL);
-+ if (!md_dst)
-+ return -ENOMEM;
-+
-+ md_dst->u.port_info.port_id = i;
-+ eth->dsa_meta[i] = md_dst;
-+ }
-+ } else {
-+ /* Hardware special tag parsing needs to be disabled if at least
-+ * one MAC does not use DSA.
-+ */
-+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+ val &= ~MTK_CDMP_STAG_EN;
-+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-+ }
-
- err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
- if (err) {
-@@ -3634,6 +3690,10 @@ static int mtk_hw_init(struct mtk_eth *e
- */
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
-+ }
-
- /* Enable RX VLan Offloading */
- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-@@ -3850,6 +3910,12 @@ static int mtk_free_dev(struct mtk_eth *
- free_netdev(eth->netdev[i]);
- }
-
-+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+ if (!eth->dsa_meta[i])
-+ break;
-+ metadata_dst_free(eth->dsa_meta[i]);
-+ }
-+
- return 0;
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -22,6 +22,9 @@
- #include <linux/bpf_trace.h>
- #include "mtk_ppe.h"
-
-+#define MTK_MAX_DSA_PORTS 7
-+#define MTK_DSA_PORT_MASK GENMASK(2, 0)
-+
- #define MTK_QDMA_NUM_QUEUES 16
- #define MTK_QDMA_PAGE_SIZE 2048
- #define MTK_MAX_RX_LENGTH 1536
-@@ -105,6 +108,9 @@
- #define MTK_CDMQ_IG_CTRL 0x1400
- #define MTK_CDMQ_STAG_EN BIT(0)
-
-+/* CDMQ Exgress Control Register */
-+#define MTK_CDMQ_EG_CTRL 0x1404
-+
- /* CDMP Ingress Control Register */
- #define MTK_CDMP_IG_CTRL 0x400
- #define MTK_CDMP_STAG_EN BIT(0)
-@@ -1160,6 +1166,8 @@ struct mtk_eth {
-
- int ip_align;
-
-+ struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS];
-+
- struct mtk_ppe *ppe[2];
- struct rhashtable flow_table;
-
diff --git a/target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch b/target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch
deleted file mode 100644
index b8c786505f..0000000000
--- a/target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 3 Nov 2022 17:46:25 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: drop packets to WDMA if the
- ring is full
-
-Improves handling of DMA ring overflow.
-Clarify other WDMA drop related comment.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3714,9 +3714,12 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- /* PSE should not drop port8 and port9 packets */
-+ /* PSE should not drop port8 and port9 packets from WDMA Tx */
- mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-
-+ /* PSE should drop packets to port 8/9 on WDMA Rx ring full */
-+ mtk_w32(eth, 0x00000300, PSE_PPE0_DROP);
-+
- /* PSE Free Queue Flow Control */
- mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -140,6 +140,7 @@
- #define PSE_FQFC_CFG1 0x100
- #define PSE_FQFC_CFG2 0x104
- #define PSE_DROP_CFG 0x108
-+#define PSE_PPE0_DROP 0x110
-
- /* PSE Input Queue Reservation Register*/
- #define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2))
diff --git a/target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch b/target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch
deleted file mode 100644
index 346db89911..0000000000
--- a/target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sat, 28 Jan 2023 12:42:32 +0300
-Subject: [PATCH] net: ethernet: mtk_eth_soc: disable hardware DSA untagging
- for second MAC
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-According to my tests on MT7621AT and MT7623NI SoCs, hardware DSA untagging
-won't work on the second MAC. Therefore, disable this feature when the
-second MAC of the MT7621 and MT7623 SoCs is being used.
-
-Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging")
-Link: https://lore.kernel.org/netdev/6249fc14-b38a-c770-36b4-5af6d41c21d3@arinc9.com/
-Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20230128094232.2451947-1-arinc.unal@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3145,7 +3145,8 @@ static int mtk_open(struct net_device *d
- struct mtk_eth *eth = mac->hw;
- int i, err;
-
-- if (mtk_uses_dsa(dev) && !eth->prog) {
-+ if ((mtk_uses_dsa(dev) && !eth->prog) &&
-+ !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) {
- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
- struct metadata_dst *md_dst = eth->dsa_meta[i];
-
-@@ -3162,7 +3163,8 @@ static int mtk_open(struct net_device *d
- }
- } else {
- /* Hardware special tag parsing needs to be disabled if at least
-- * one MAC does not use DSA.
-+ * one MAC does not use DSA, or the second MAC of the MT7621 and
-+ * MT7623 SoCs is being used.
- */
- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
- val &= ~MTK_CDMP_STAG_EN;
diff --git a/target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch b/target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch
deleted file mode 100644
index ec5dc49f5e..0000000000
--- a/target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sun, 5 Feb 2023 20:53:31 +0300
-Subject: [PATCH] net: ethernet: mtk_eth_soc: enable special tag when any MAC
- uses DSA
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The special tag is only enabled when the first MAC uses DSA. However, it
-must be enabled when any MAC uses DSA. Change the check accordingly.
-
-This fixes hardware DSA untagging not working on the second MAC of the
-MT7621 and MT7623 SoCs, and likely other SoCs too. Therefore, remove the
-check that disables hardware DSA untagging for the second MAC of the MT7621
-and MT7623 SoCs.
-
-Fixes: a1f47752fd62 ("net: ethernet: mtk_eth_soc: disable hardware DSA untagging for second MAC")
-Co-developed-by: Richard van Schagen <richard@routerhints.com>
-Signed-off-by: Richard van Schagen <richard@routerhints.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3080,7 +3080,7 @@ static void mtk_gdm_config(struct mtk_et
-
- val |= config;
-
-- if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0]))
-+ if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i]))
- val |= MTK_GDMA_SPECIAL_TAG;
-
- mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-@@ -3145,8 +3145,7 @@ static int mtk_open(struct net_device *d
- struct mtk_eth *eth = mac->hw;
- int i, err;
-
-- if ((mtk_uses_dsa(dev) && !eth->prog) &&
-- !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) {
-+ if (mtk_uses_dsa(dev) && !eth->prog) {
- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
- struct metadata_dst *md_dst = eth->dsa_meta[i];
-
-@@ -3163,8 +3162,7 @@ static int mtk_open(struct net_device *d
- }
- } else {
- /* Hardware special tag parsing needs to be disabled if at least
-- * one MAC does not use DSA, or the second MAC of the MT7621 and
-- * MT7623 SoCs is being used.
-+ * one MAC does not use DSA.
- */
- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
- val &= ~MTK_CDMP_STAG_EN;
diff --git a/target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch b/target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch
deleted file mode 100644
index e75459696b..0000000000
--- a/target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 7 Feb 2023 12:30:27 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix DSA TX tag hwaccel for switch
- port 0
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Arınç reports that on his MT7621AT Unielec U7621-06 board and MT7623NI
-Bananapi BPI-R2, packets received by the CPU over mt7530 switch port 0
-(of which this driver acts as the DSA master) are not processed
-correctly by software. More precisely, they arrive without a DSA tag
-(in packet or in the hwaccel area - skb_metadata_dst()), so DSA cannot
-demux them towards the switch's interface for port 0. Traffic from other
-ports receives a skb_metadata_dst() with the correct port and is demuxed
-properly.
-
-Looking at mtk_poll_rx(), it becomes apparent that this driver uses the
-skb vlan hwaccel area:
-
- union {
- u32 vlan_all;
- struct {
- __be16 vlan_proto;
- __u16 vlan_tci;
- };
- };
-
-as a temporary storage for the VLAN hwaccel tag, or the DSA hwaccel tag.
-If this is a DSA master it's a DSA hwaccel tag, and finally clears up
-the skb VLAN hwaccel header.
-
-I'm guessing that the problem is the (mis)use of API.
-skb_vlan_tag_present() looks like this:
-
- #define skb_vlan_tag_present(__skb) (!!(__skb)->vlan_all)
-
-So if both vlan_proto and vlan_tci are zeroes, skb_vlan_tag_present()
-returns precisely false. I don't know for sure what is the format of the
-DSA hwaccel tag, but I surely know that lowermost 3 bits of vlan_proto
-are 0 when receiving from port 0:
-
- unsigned int port = vlan_proto & GENMASK(2, 0);
-
-If the RX descriptor has no other bits set to non-zero values in
-RX_DMA_VTAG, then the call to __vlan_hwaccel_put_tag() will not, in
-fact, make the subsequent skb_vlan_tag_present() return true, because
-it's implemented like this:
-
-static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb,
- __be16 vlan_proto, u16 vlan_tci)
-{
- skb->vlan_proto = vlan_proto;
- skb->vlan_tci = vlan_tci;
-}
-
-What we need to do to fix this problem (assuming this is the problem) is
-to stop using skb->vlan_all as temporary storage for driver affairs, and
-just create some local variables that serve the same purpose, but
-hopefully better. Instead of calling skb_vlan_tag_present(), let's look
-at a boolean has_hwaccel_tag which we set to true when the RX DMA
-descriptors have something. Disambiguate based on netdev_uses_dsa()
-whether this is a VLAN or DSA hwaccel tag, and only call
-__vlan_hwaccel_put_tag() if we're certain it's a VLAN tag.
-
-Arınç confirms that the treatment works, so this validates the
-assumption.
-
-Link: https://lore.kernel.org/netdev/704f3a72-fc9e-714a-db54-272e17612637@arinc9.com/
-Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging")
-Reported-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1829,7 +1829,9 @@ static int mtk_poll_rx(struct napi_struc
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
-+ bool has_hwaccel_tag = false;
- struct net_device *netdev;
-+ u16 vlan_proto, vlan_tci;
- dma_addr_t dma_addr;
- u32 hash, reason;
- int mac = 0;
-@@ -1969,27 +1971,29 @@ static int mtk_poll_rx(struct napi_struc
-
- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- if (trxd.rxd3 & RX_DMA_VTAG_V2)
-- __vlan_hwaccel_put_tag(skb,
-- htons(RX_DMA_VPID(trxd.rxd4)),
-- RX_DMA_VID(trxd.rxd4));
-+ if (trxd.rxd3 & RX_DMA_VTAG_V2) {
-+ vlan_proto = RX_DMA_VPID(trxd.rxd4);
-+ vlan_tci = RX_DMA_VID(trxd.rxd4);
-+ has_hwaccel_tag = true;
-+ }
- } else if (trxd.rxd2 & RX_DMA_VTAG) {
-- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)),
-- RX_DMA_VID(trxd.rxd3));
-+ vlan_proto = RX_DMA_VPID(trxd.rxd3);
-+ vlan_tci = RX_DMA_VID(trxd.rxd3);
-+ has_hwaccel_tag = true;
- }
- }
-
- /* When using VLAN untagging in combination with DSA, the
- * hardware treats the MTK special tag as a VLAN and untags it.
- */
-- if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) {
-- unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0);
-+ if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
-+ unsigned int port = vlan_proto & GENMASK(2, 0);
-
- if (port < ARRAY_SIZE(eth->dsa_meta) &&
- eth->dsa_meta[port])
- skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
--
-- __vlan_hwaccel_clear_tag(skb);
-+ } else if (has_hwaccel_tag) {
-+ __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
- }
-
- skb_record_rx_queue(skb, 0);
diff --git a/target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch b/target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch
deleted file mode 100644
index a3bb1c5db7..0000000000
--- a/target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Date: Sun, 12 Feb 2023 07:51:51 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: No need to clear memory after a
- dma_alloc_coherent() call
-
-dma_alloc_coherent() already clears the allocated memory, there is no need
-to explicitly call memset().
-
-Moreover, it is likely that the size in the memset() is incorrect and
-should be "size * sizeof(*ring->desc)".
-
-Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Link: https://lore.kernel.org/r/d5acce7dd108887832c9719f62c7201b4c83b3fb.1676184599.git.christophe.jaillet@wanadoo.fr
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -779,7 +779,6 @@ mtk_wed_rro_ring_alloc(struct mtk_wed_de
-
- ring->desc_size = sizeof(*ring->desc);
- ring->size = size;
-- memset(ring->desc, 0, size);
-
- return 0;
- }
diff --git a/target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch b/target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch
deleted file mode 100644
index e043a681da..0000000000
--- a/target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 7 Dec 2022 15:04:54 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: fix some possible NULL pointer
- dereferences
-
-Fix possible NULL pointer dereference in mtk_wed_detach routine checking
-wo pointer is properly allocated before running mtk_wed_wo_reset() and
-mtk_wed_wo_deinit().
-Even if it is just a theoretical issue at the moment check wo pointer is
-not NULL in mtk_wed_mcu_msg_update.
-Moreover, honor mtk_wed_mcu_send_msg return value in mtk_wed_wo_reset()
-
-Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support")
-Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -174,9 +174,10 @@ mtk_wed_wo_reset(struct mtk_wed_device *
- mtk_wdma_tx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-
-- mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-- MTK_WED_WO_CMD_CHANGE_STATE, &state,
-- sizeof(state), false);
-+ if (mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &state,
-+ sizeof(state), false))
-+ return;
-
- if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val,
- val == MTK_WED_WOIF_DISABLE_DONE,
-@@ -632,9 +633,11 @@ mtk_wed_detach(struct mtk_wed_device *de
- mtk_wed_free_tx_rings(dev);
-
- if (mtk_wed_get_rx_capa(dev)) {
-- mtk_wed_wo_reset(dev);
-+ if (hw->wed_wo)
-+ mtk_wed_wo_reset(dev);
- mtk_wed_free_rx_rings(dev);
-- mtk_wed_wo_deinit(hw);
-+ if (hw->wed_wo)
-+ mtk_wed_wo_deinit(hw);
- }
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -207,6 +207,9 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- if (dev->hw->version == 1)
- return 0;
-
-+ if (WARN_ON(!wo))
-+ return -ENODEV;
-+
- return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len,
- true);
- }
diff --git a/target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch b/target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch
deleted file mode 100644
index 0afe7106e5..0000000000
--- a/target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 7 Dec 2022 15:04:55 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: fix possible deadlock if
- mtk_wed_wo_init fails
-
-Introduce __mtk_wed_detach() in order to avoid a deadlock in
-mtk_wed_attach routine if mtk_wed_wo_init fails since both
-mtk_wed_attach and mtk_wed_detach run holding hw_lock mutex.
-
-Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -619,12 +619,10 @@ mtk_wed_deinit(struct mtk_wed_device *de
- }
-
- static void
--mtk_wed_detach(struct mtk_wed_device *dev)
-+__mtk_wed_detach(struct mtk_wed_device *dev)
- {
- struct mtk_wed_hw *hw = dev->hw;
-
-- mutex_lock(&hw_lock);
--
- mtk_wed_deinit(dev);
-
- mtk_wdma_rx_reset(dev);
-@@ -657,6 +655,13 @@ mtk_wed_detach(struct mtk_wed_device *de
- module_put(THIS_MODULE);
-
- hw->wed_dev = NULL;
-+}
-+
-+static void
-+mtk_wed_detach(struct mtk_wed_device *dev)
-+{
-+ mutex_lock(&hw_lock);
-+ __mtk_wed_detach(dev);
- mutex_unlock(&hw_lock);
- }
-
-@@ -1538,8 +1543,10 @@ mtk_wed_attach(struct mtk_wed_device *de
- ret = mtk_wed_wo_init(hw);
- }
- out:
-- if (ret)
-- mtk_wed_detach(dev);
-+ if (ret) {
-+ dev_err(dev->hw->dev, "failed to attach wed device\n");
-+ __mtk_wed_detach(dev);
-+ }
- unlock:
- mutex_unlock(&hw_lock);
-
diff --git a/target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch b/target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch
deleted file mode 100644
index 4ba492014a..0000000000
--- a/target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 24 Mar 2023 14:56:58 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix tx throughput regression with
- direct 1G links
-
-Using the QDMA tx scheduler to throttle tx to line speed works fine for
-switch ports, but apparently caused a regression on non-switch ports.
-
-Based on a number of tests, it seems that this throttling can be safely
-dropped without re-introducing the issues on switch ports that the
-tx scheduling changes resolved.
-
-Link: https://lore.kernel.org/netdev/trinity-92c3826f-c2c8-40af-8339-bc6d0d3ffea4-1678213958520@3c-app-gmx-bs16/
-Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues")
-Reported-by: Frank Wunderlich <frank-w@public-files.de>
-Reported-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -675,8 +675,6 @@ static void mtk_mac_link_up(struct phyli
- break;
- }
-
-- mtk_set_queue_speed(mac->hw, mac->id, speed);
--
- /* Configure duplex */
- if (duplex == DUPLEX_FULL)
- mcr |= MAC_MCR_FORCE_DPX;
diff --git a/target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch b/target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch
deleted file mode 100644
index 40b14fc36a..0000000000
--- a/target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 5e61fe157a27afc7c0d4f7bcbceefdca536c015f Mon Sep 17 00:00:00 2001
-From: Maxime Chevallier <maxime.chevallier@bootlin.com>
-Date: Wed, 17 Aug 2022 14:32:52 +0200
-Subject: [PATCH] net: phy: Introduce QUSGMII PHY mode
-
-The QUSGMII mode is a derivative of Cisco's USXGMII standard. This
-standard is pretty similar to SGMII, but allows for faster speeds, and
-has the build-in bits for Quad and Octa variants (like QSGMII).
-
-The main difference with SGMII/QSGMII is that USXGMII/QUSGMII re-uses
-the preamble to carry various information, named 'Extensions'.
-
-As of today, the USXGMII standard only mentions the "PCH" extension,
-which is used to convey timestamps, allowing in-band signaling of PTP
-timestamps without having to modify the frame itself.
-
-This commit adds support for that mode. When no extension is in use, it
-behaves exactly like QSGMII, although it's not compatible with QSGMII.
-
-Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/networking/phy.rst | 9 +++++++++
- drivers/net/phy/phylink.c | 3 +++
- include/linux/phy.h | 4 ++++
- 3 files changed, 16 insertions(+)
-
---- a/Documentation/networking/phy.rst
-+++ b/Documentation/networking/phy.rst
-@@ -303,6 +303,15 @@ Some of the interface modes are describe
- rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying
- data rate of 100Mpbs.
-
-+``PHY_INTERFACE_MODE_QUSGMII``
-+ This defines the Cisco the Quad USGMII mode, which is the Quad variant of
-+ the USGMII (Universal SGMII) link. It's very similar to QSGMII, but uses
-+ a Packet Control Header (PCH) instead of the 7 bytes preamble to carry not
-+ only the port id, but also so-called "extensions". The only documented
-+ extension so-far in the specification is the inclusion of timestamps, for
-+ PTP-enabled PHYs. This mode isn't compatible with QSGMII, but offers the
-+ same capabilities in terms of link speed and negociation.
-+
- Pause frames / flow control
- ===========================
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -367,6 +367,7 @@ void phylink_get_linkmodes(unsigned long
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII:
- case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_QUSGMII:
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_GMII:
- caps |= MAC_1000HD | MAC_1000FD;
-@@ -630,6 +631,7 @@ static int phylink_parse_mode(struct phy
- switch (pl->link_config.interface) {
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_QUSGMII:
- phylink_set(pl->supported, 10baseT_Half);
- phylink_set(pl->supported, 10baseT_Full);
- phylink_set(pl->supported, 100baseT_Half);
-@@ -2956,6 +2958,7 @@ void phylink_mii_c22_pcs_get_state(struc
-
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_QUSGMII:
- phylink_decode_sgmii_word(state, lpa);
- break;
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -115,6 +115,7 @@ extern const int phy_10gbit_features_arr
- * @PHY_INTERFACE_MODE_25GBASER: 25G BaseR
- * @PHY_INTERFACE_MODE_USXGMII: Universal Serial 10GE MII
- * @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN
-+ * @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII
- * @PHY_INTERFACE_MODE_MAX: Book keeping
- *
- * Describes the interface between the MAC and PHY.
-@@ -152,6 +153,7 @@ typedef enum {
- PHY_INTERFACE_MODE_USXGMII,
- /* 10GBASE-KR - with Clause 73 AN */
- PHY_INTERFACE_MODE_10GKR,
-+ PHY_INTERFACE_MODE_QUSGMII,
- PHY_INTERFACE_MODE_MAX,
- } phy_interface_t;
-
-@@ -267,6 +269,8 @@ static inline const char *phy_modes(phy_
- return "10gbase-kr";
- case PHY_INTERFACE_MODE_100BASEX:
- return "100base-x";
-+ case PHY_INTERFACE_MODE_QUSGMII:
-+ return "qusgmii";
- default:
- return "unknown";
- }
diff --git a/target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch b/target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch
deleted file mode 100644
index a9706af893..0000000000
--- a/target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From c04ade27cb7b952b6b9b9a0efa0a6129cc63f2ae Mon Sep 17 00:00:00 2001
-From: Maxime Chevallier <maxime.chevallier@bootlin.com>
-Date: Wed, 17 Aug 2022 14:32:54 +0200
-Subject: [PATCH] net: phy: Add helper to derive the number of ports from a phy
- mode
-
-Some phy modes such as QSGMII multiplex several MAC<->PHY links on one
-single physical interface. QSGMII used to be the only one supported, but
-other modes such as QUSGMII also carry multiple links.
-
-This helper allows getting the number of links that are multiplexed
-on a given interface.
-
-Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy-core.c | 52 ++++++++++++++++++++++++++++++++++++++
- include/linux/phy.h | 2 ++
- 2 files changed, 54 insertions(+)
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -74,6 +74,58 @@ const char *phy_duplex_to_str(unsigned i
- }
- EXPORT_SYMBOL_GPL(phy_duplex_to_str);
-
-+/**
-+ * phy_interface_num_ports - Return the number of links that can be carried by
-+ * a given MAC-PHY physical link. Returns 0 if this is
-+ * unknown, the number of links else.
-+ *
-+ * @interface: The interface mode we want to get the number of ports
-+ */
-+int phy_interface_num_ports(phy_interface_t interface)
-+{
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_NA:
-+ return 0;
-+ case PHY_INTERFACE_MODE_INTERNAL:
-+ case PHY_INTERFACE_MODE_MII:
-+ case PHY_INTERFACE_MODE_GMII:
-+ case PHY_INTERFACE_MODE_TBI:
-+ case PHY_INTERFACE_MODE_REVMII:
-+ case PHY_INTERFACE_MODE_RMII:
-+ case PHY_INTERFACE_MODE_REVRMII:
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RTBI:
-+ case PHY_INTERFACE_MODE_XGMII:
-+ case PHY_INTERFACE_MODE_XLGMII:
-+ case PHY_INTERFACE_MODE_MOCA:
-+ case PHY_INTERFACE_MODE_TRGMII:
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_SMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ case PHY_INTERFACE_MODE_5GBASER:
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ case PHY_INTERFACE_MODE_25GBASER:
-+ case PHY_INTERFACE_MODE_10GKR:
-+ case PHY_INTERFACE_MODE_100BASEX:
-+ case PHY_INTERFACE_MODE_RXAUI:
-+ case PHY_INTERFACE_MODE_XAUI:
-+ return 1;
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_QUSGMII:
-+ return 4;
-+ case PHY_INTERFACE_MODE_MAX:
-+ WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode");
-+ return 0;
-+ }
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(phy_interface_num_ports);
-+
- /* A mapping of all SUPPORTED settings to speed/duplex. This table
- * must be grouped by speed and sorted in descending match priority
- * - iow, descending speed.
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -964,6 +964,8 @@ struct phy_fixup {
- const char *phy_speed_to_str(int speed);
- const char *phy_duplex_to_str(unsigned int duplex);
-
-+int phy_interface_num_ports(phy_interface_t interface);
-+
- /* A structure for mapping a particular speed and duplex
- * combination to a particular SUPPORTED and ADVERTISED value
- */
diff --git a/target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch b/target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch
deleted file mode 100644
index 70669dde3a..0000000000
--- a/target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 05ad5d4581c3c1cc724fe50d4652833fb9f3037b Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Fri, 2 Sep 2022 18:02:39 -0400
-Subject: [PATCH] net: phy: Add 1000BASE-KX interface mode
-
-Add 1000BASE-KX interface mode. This 1G backplane ethernet as described in
-clause 70. Clause 73 autonegotiation is mandatory, and only full duplex
-operation is supported.
-
-Although at the PMA level this interface mode is identical to
-1000BASE-X, it uses a different form of in-band autonegation. This
-justifies a separate interface mode, since the interface mode (along
-with the MLO_AN_* autonegotiation mode) sets the type of autonegotiation
-which will be used on a link. This results in more than just electrical
-differences between the link modes.
-
-With regard to 1000BASE-X, 1000BASE-KX holds a similar position to
-SGMII: same signaling, but different autonegotiation. PCS drivers
-(which typically handle in-band autonegotiation) may only support
-1000BASE-X, and not 1000BASE-KX. Similarly, the phy mode is used to
-configure serdes phys with phy_set_mode_ext. Due to the different
-electrical standards (SFI or XFI vs Clause 70), they will likely want to
-use different configuration. Adding a phy interface mode for
-1000BASE-KX helps simplify configuration in these areas.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/networking/phy.rst | 6 ++++++
- drivers/net/phy/phy-core.c | 1 +
- drivers/net/phy/phylink.c | 1 +
- include/linux/phy.h | 4 ++++
- 4 files changed, 12 insertions(+)
-
---- a/Documentation/networking/phy.rst
-+++ b/Documentation/networking/phy.rst
-@@ -312,6 +312,12 @@ Some of the interface modes are describe
- PTP-enabled PHYs. This mode isn't compatible with QSGMII, but offers the
- same capabilities in terms of link speed and negociation.
-
-+``PHY_INTERFACE_MODE_1000BASEKX``
-+ This is 1000BASE-X as defined by IEEE 802.3 Clause 36 with Clause 73
-+ autonegotiation. Generally, it will be used with a Clause 70 PMD. To
-+ contrast with the 1000BASE-X phy mode used for Clause 38 and 39 PMDs, this
-+ interface mode has different autonegotiation and only supports full duplex.
-+
- Pause frames / flow control
- ===========================
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -114,6 +114,7 @@ int phy_interface_num_ports(phy_interfac
- case PHY_INTERFACE_MODE_100BASEX:
- case PHY_INTERFACE_MODE_RXAUI:
- case PHY_INTERFACE_MODE_XAUI:
-+ case PHY_INTERFACE_MODE_1000BASEKX:
- return 1;
- case PHY_INTERFACE_MODE_QSGMII:
- case PHY_INTERFACE_MODE_QUSGMII:
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -390,6 +390,7 @@ void phylink_get_linkmodes(unsigned long
- case PHY_INTERFACE_MODE_1000BASEX:
- caps |= MAC_1000HD;
- fallthrough;
-+ case PHY_INTERFACE_MODE_1000BASEKX:
- case PHY_INTERFACE_MODE_TRGMII:
- caps |= MAC_1000FD;
- break;
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -116,6 +116,7 @@ extern const int phy_10gbit_features_arr
- * @PHY_INTERFACE_MODE_USXGMII: Universal Serial 10GE MII
- * @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN
- * @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII
-+ * @PHY_INTERFACE_MODE_1000BASEKX: 1000Base-KX - with Clause 73 AN
- * @PHY_INTERFACE_MODE_MAX: Book keeping
- *
- * Describes the interface between the MAC and PHY.
-@@ -154,6 +155,7 @@ typedef enum {
- /* 10GBASE-KR - with Clause 73 AN */
- PHY_INTERFACE_MODE_10GKR,
- PHY_INTERFACE_MODE_QUSGMII,
-+ PHY_INTERFACE_MODE_1000BASEKX,
- PHY_INTERFACE_MODE_MAX,
- } phy_interface_t;
-
-@@ -251,6 +253,8 @@ static inline const char *phy_modes(phy_
- return "trgmii";
- case PHY_INTERFACE_MODE_1000BASEX:
- return "1000base-x";
-+ case PHY_INTERFACE_MODE_1000BASEKX:
-+ return "1000base-kx";
- case PHY_INTERFACE_MODE_2500BASEX:
- return "2500base-x";
- case PHY_INTERFACE_MODE_5GBASER:
diff --git a/target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch b/target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch
deleted file mode 100644
index fc02d7a4ea..0000000000
--- a/target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From 0c3e10cb44232833a50cb8e3e784c432906a60c1 Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Tue, 20 Sep 2022 18:12:31 -0400
-Subject: [PATCH] net: phy: Add support for rate matching
-
-This adds support for rate matching (also known as rate adaptation) to
-the phy subsystem. The general idea is that the phy interface runs at
-one speed, and the MAC throttles the rate at which it sends packets to
-the link speed. There's a good overview of several techniques for
-achieving this at [1]. This patch adds support for three: pause-frame
-based (such as in Aquantia phys), CRS-based (such as in 10PASS-TS and
-2BASE-TL), and open-loop-based (such as in 10GBASE-W).
-
-This patch makes a few assumptions and a few non assumptions about the
-types of rate matching available. First, it assumes that different phys
-may use different forms of rate matching. Second, it assumes that phys
-can use rate matching for any of their supported link speeds (e.g. if a
-phy supports 10BASE-T and XGMII, then it can adapt XGMII to 10BASE-T).
-Third, it does not assume that all interface modes will use the same
-form of rate matching. Fourth, it does not assume that all phy devices
-will support rate matching (even if some do). Relaxing or strengthening
-these (non-)assumptions could result in a different API. For example, if
-all interface modes were assumed to use the same form of rate matching,
-then a bitmask of interface modes supportting rate matching would
-suffice.
-
-For some better visibility into the process, the current rate matching
-mode is exposed as part of the ethtool ksettings. For the moment, only
-read access is supported. I'm not sure what userspace might want to
-configure yet (disable it altogether, disable just one mode, specify the
-mode to use, etc.). For the moment, since only pause-based rate
-adaptation support is added in the next few commits, rate matching can
-be disabled altogether by adjusting the advertisement.
-
-802.3 calls this feature "rate adaptation" in clause 49 (10GBASE-R) and
-"rate matching" in clause 61 (10PASS-TL and 2BASE-TS). Aquantia also calls
-this feature "rate adaptation". I chose "rate matching" because it is
-shorter, and because Russell doesn't think "adaptation" is correct in this
-context.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/networking/ethtool-netlink.rst | 2 ++
- drivers/net/phy/phy-core.c | 21 +++++++++++++++
- drivers/net/phy/phy.c | 28 ++++++++++++++++++++
- include/linux/phy.h | 22 ++++++++++++++-
- include/uapi/linux/ethtool.h | 18 +++++++++++--
- include/uapi/linux/ethtool_netlink.h | 1 +
- net/ethtool/ioctl.c | 1 +
- net/ethtool/linkmodes.c | 5 ++++
- 8 files changed, 95 insertions(+), 3 deletions(-)
-
---- a/Documentation/networking/ethtool-netlink.rst
-+++ b/Documentation/networking/ethtool-netlink.rst
-@@ -418,6 +418,7 @@ Kernel response contents:
- ``ETHTOOL_A_LINKMODES_DUPLEX`` u8 duplex mode
- ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG`` u8 Master/slave port mode
- ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE`` u8 Master/slave port state
-+ ``ETHTOOL_A_LINKMODES_RATE_MATCHING`` u8 PHY rate matching
- ========================================== ====== ==========================
-
- For ``ETHTOOL_A_LINKMODES_OURS``, value represents advertised modes and mask
-@@ -441,6 +442,7 @@ Request contents:
- ``ETHTOOL_A_LINKMODES_SPEED`` u32 link speed (Mb/s)
- ``ETHTOOL_A_LINKMODES_DUPLEX`` u8 duplex mode
- ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG`` u8 Master/slave port mode
-+ ``ETHTOOL_A_LINKMODES_RATE_MATCHING`` u8 PHY rate matching
- ``ETHTOOL_A_LINKMODES_LANES`` u32 lanes
- ========================================== ====== ==========================
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -75,6 +75,27 @@ const char *phy_duplex_to_str(unsigned i
- EXPORT_SYMBOL_GPL(phy_duplex_to_str);
-
- /**
-+ * phy_rate_matching_to_str - Return a string describing the rate matching
-+ *
-+ * @rate_matching: Type of rate matching to describe
-+ */
-+const char *phy_rate_matching_to_str(int rate_matching)
-+{
-+ switch (rate_matching) {
-+ case RATE_MATCH_NONE:
-+ return "none";
-+ case RATE_MATCH_PAUSE:
-+ return "pause";
-+ case RATE_MATCH_CRS:
-+ return "crs";
-+ case RATE_MATCH_OPEN_LOOP:
-+ return "open-loop";
-+ }
-+ return "Unsupported (update phy-core.c)";
-+}
-+EXPORT_SYMBOL_GPL(phy_rate_matching_to_str);
-+
-+/**
- * phy_interface_num_ports - Return the number of links that can be carried by
- * a given MAC-PHY physical link. Returns 0 if this is
- * unknown, the number of links else.
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -127,6 +127,33 @@ void phy_print_status(struct phy_device
- EXPORT_SYMBOL(phy_print_status);
-
- /**
-+ * phy_get_rate_matching - determine if rate matching is supported
-+ * @phydev: The phy device to return rate matching for
-+ * @iface: The interface mode to use
-+ *
-+ * This determines the type of rate matching (if any) that @phy supports
-+ * using @iface. @iface may be %PHY_INTERFACE_MODE_NA to determine if any
-+ * interface supports rate matching.
-+ *
-+ * Return: The type of rate matching @phy supports for @iface, or
-+ * %RATE_MATCH_NONE.
-+ */
-+int phy_get_rate_matching(struct phy_device *phydev,
-+ phy_interface_t iface)
-+{
-+ int ret = RATE_MATCH_NONE;
-+
-+ if (phydev->drv->get_rate_matching) {
-+ mutex_lock(&phydev->lock);
-+ ret = phydev->drv->get_rate_matching(phydev, iface);
-+ mutex_unlock(&phydev->lock);
-+ }
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(phy_get_rate_matching);
-+
-+/**
- * phy_config_interrupt - configure the PHY device for the requested interrupts
- * @phydev: the phy_device struct
- * @interrupts: interrupt flags to configure for this @phydev
-@@ -268,6 +295,7 @@ void phy_ethtool_ksettings_get(struct ph
- cmd->base.duplex = phydev->duplex;
- cmd->base.master_slave_cfg = phydev->master_slave_get;
- cmd->base.master_slave_state = phydev->master_slave_state;
-+ cmd->base.rate_matching = phydev->rate_matching;
- if (phydev->interface == PHY_INTERFACE_MODE_MOCA)
- cmd->base.port = PORT_BNC;
- else
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -280,7 +280,6 @@ static inline const char *phy_modes(phy_
- }
- }
-
--
- #define PHY_INIT_TIMEOUT 100000
- #define PHY_FORCE_TIMEOUT 10
-
-@@ -573,6 +572,7 @@ struct macsec_ops;
- * @lp_advertising: Current link partner advertised linkmodes
- * @eee_broken_modes: Energy efficient ethernet modes which should be prohibited
- * @autoneg: Flag autoneg being used
-+ * @rate_matching: Current rate matching mode
- * @link: Current link state
- * @autoneg_complete: Flag auto negotiation of the link has completed
- * @mdix: Current crossover
-@@ -639,6 +639,8 @@ struct phy_device {
- unsigned irq_suspended:1;
- unsigned irq_rerun:1;
-
-+ int rate_matching;
-+
- enum phy_state state;
-
- u32 dev_flags;
-@@ -801,6 +803,21 @@ struct phy_driver {
- */
- int (*get_features)(struct phy_device *phydev);
-
-+ /**
-+ * @get_rate_matching: Get the supported type of rate matching for a
-+ * particular phy interface. This is used by phy consumers to determine
-+ * whether to advertise lower-speed modes for that interface. It is
-+ * assumed that if a rate matching mode is supported on an interface,
-+ * then that interface's rate can be adapted to all slower link speeds
-+ * supported by the phy. If iface is %PHY_INTERFACE_MODE_NA, and the phy
-+ * supports any kind of rate matching for any interface, then it must
-+ * return that rate matching mode (preferring %RATE_MATCH_PAUSE to
-+ * %RATE_MATCH_CRS). If the interface is not supported, this should
-+ * return %RATE_MATCH_NONE.
-+ */
-+ int (*get_rate_matching)(struct phy_device *phydev,
-+ phy_interface_t iface);
-+
- /* PHY Power Management */
- /** @suspend: Suspend the hardware, saving state if needed */
- int (*suspend)(struct phy_device *phydev);
-@@ -967,6 +984,7 @@ struct phy_fixup {
-
- const char *phy_speed_to_str(int speed);
- const char *phy_duplex_to_str(unsigned int duplex);
-+const char *phy_rate_matching_to_str(int rate_matching);
-
- int phy_interface_num_ports(phy_interface_t interface);
-
-@@ -1675,6 +1693,8 @@ int phy_disable_interrupts(struct phy_de
- void phy_request_interrupt(struct phy_device *phydev);
- void phy_free_interrupt(struct phy_device *phydev);
- void phy_print_status(struct phy_device *phydev);
-+int phy_get_rate_matching(struct phy_device *phydev,
-+ phy_interface_t iface);
- int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
- void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode);
- void phy_advertise_supported(struct phy_device *phydev);
---- a/include/uapi/linux/ethtool.h
-+++ b/include/uapi/linux/ethtool.h
-@@ -1809,6 +1809,20 @@ static inline int ethtool_validate_duple
- #define MASTER_SLAVE_STATE_SLAVE 3
- #define MASTER_SLAVE_STATE_ERR 4
-
-+/* These are used to throttle the rate of data on the phy interface when the
-+ * native speed of the interface is higher than the link speed. These should
-+ * not be used for phy interfaces which natively support multiple speeds (e.g.
-+ * MII or SGMII).
-+ */
-+/* No rate matching performed. */
-+#define RATE_MATCH_NONE 0
-+/* The phy sends pause frames to throttle the MAC. */
-+#define RATE_MATCH_PAUSE 1
-+/* The phy asserts CRS to prevent the MAC from transmitting. */
-+#define RATE_MATCH_CRS 2
-+/* The MAC is programmed with a sufficiently-large IPG. */
-+#define RATE_MATCH_OPEN_LOOP 3
-+
- /* Which connector port. */
- #define PORT_TP 0x00
- #define PORT_AUI 0x01
-@@ -2002,8 +2016,8 @@ enum ethtool_reset_flags {
- * reported consistently by PHYLIB. Read-only.
- * @master_slave_cfg: Master/slave port mode.
- * @master_slave_state: Master/slave port state.
-+ * @rate_matching: Rate adaptation performed by the PHY
- * @reserved: Reserved for future use; see the note on reserved space.
-- * @reserved1: Reserved for future use; see the note on reserved space.
- * @link_mode_masks: Variable length bitmaps.
- *
- * If autonegotiation is disabled, the speed and @duplex represent the
-@@ -2054,7 +2068,7 @@ struct ethtool_link_settings {
- __u8 transceiver;
- __u8 master_slave_cfg;
- __u8 master_slave_state;
-- __u8 reserved1[1];
-+ __u8 rate_matching;
- __u32 reserved[7];
- __u32 link_mode_masks[0];
- /* layout of link_mode_masks fields:
---- a/include/uapi/linux/ethtool_netlink.h
-+++ b/include/uapi/linux/ethtool_netlink.h
-@@ -238,6 +238,7 @@ enum {
- ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, /* u8 */
- ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, /* u8 */
- ETHTOOL_A_LINKMODES_LANES, /* u32 */
-+ ETHTOOL_A_LINKMODES_RATE_MATCHING, /* u8 */
-
- /* add new constants above here */
- __ETHTOOL_A_LINKMODES_CNT,
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -559,6 +559,7 @@ static int ethtool_get_link_ksettings(st
- = __ETHTOOL_LINK_MODE_MASK_NU32;
- link_ksettings.base.master_slave_cfg = MASTER_SLAVE_CFG_UNSUPPORTED;
- link_ksettings.base.master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
-+ link_ksettings.base.rate_matching = RATE_MATCH_NONE;
-
- return store_link_ksettings_for_user(useraddr, &link_ksettings);
- }
---- a/net/ethtool/linkmodes.c
-+++ b/net/ethtool/linkmodes.c
-@@ -70,6 +70,7 @@ static int linkmodes_reply_size(const st
- + nla_total_size(sizeof(u32)) /* LINKMODES_SPEED */
- + nla_total_size(sizeof(u32)) /* LINKMODES_LANES */
- + nla_total_size(sizeof(u8)) /* LINKMODES_DUPLEX */
-+ + nla_total_size(sizeof(u8)) /* LINKMODES_RATE_MATCHING */
- + 0;
- ret = ethnl_bitset_size(ksettings->link_modes.advertising,
- ksettings->link_modes.supported,
-@@ -143,6 +144,10 @@ static int linkmodes_fill_reply(struct s
- lsettings->master_slave_state))
- return -EMSGSIZE;
-
-+ if (nla_put_u8(skb, ETHTOOL_A_LINKMODES_RATE_MATCHING,
-+ lsettings->rate_matching))
-+ return -EMSGSIZE;
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch b/target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch
deleted file mode 100644
index 460c5c2317..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From f3eceaed9edd7c0e0d9fb057613131f92973626f Mon Sep 17 00:00:00 2001
-From: Kees Cook <keescook@chromium.org>
-Date: Fri, 27 Jan 2023 14:38:54 -0800
-Subject: [PATCH] net: ethernet: mtk_eth_soc: Avoid truncating allocation
-
-There doesn't appear to be a reason to truncate the allocation used for
-flow_info, so do a full allocation and remove the unused empty struct.
-GCC does not like having a reference to an object that has been
-partially allocated, as bounds checking may become impossible when
-such an object is passed to other code. Seen with GCC 13:
-
-../drivers/net/ethernet/mediatek/mtk_ppe.c: In function 'mtk_foe_entry_commit_subflow':
-../drivers/net/ethernet/mediatek/mtk_ppe.c:623:18: warning: array subscript 'struct mtk_flow_entry[0]' is partly outside array bounds of 'unsigned char[48]' [-Warray-bounds=]
- 623 | flow_info->l2_data.base_flow = entry;
- | ^~
-
-Cc: Felix Fietkau <nbd@nbd.name>
-Cc: John Crispin <john@phrozen.org>
-Cc: Sean Wang <sean.wang@mediatek.com>
-Cc: Mark Lee <Mark-MC.Lee@mediatek.com>
-Cc: Lorenzo Bianconi <lorenzo@kernel.org>
-Cc: "David S. Miller" <davem@davemloft.net>
-Cc: Eric Dumazet <edumazet@google.com>
-Cc: Jakub Kicinski <kuba@kernel.org>
-Cc: Paolo Abeni <pabeni@redhat.com>
-Cc: Matthias Brugger <matthias.bgg@gmail.com>
-Cc: netdev@vger.kernel.org
-Cc: linux-arm-kernel@lists.infradead.org
-Cc: linux-mediatek@lists.infradead.org
-Signed-off-by: Kees Cook <keescook@chromium.org>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Link: https://lore.kernel.org/r/20230127223853.never.014-kees@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 3 +--
- drivers/net/ethernet/mediatek/mtk_ppe.h | 1 -
- 2 files changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -621,8 +621,7 @@ mtk_foe_entry_commit_subflow(struct mtk_
- u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP;
- int type;
-
-- flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end),
-- GFP_ATOMIC);
-+ flow_info = kzalloc(sizeof(*flow_info), GFP_ATOMIC);
- if (!flow_info)
- return;
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -279,7 +279,6 @@ struct mtk_flow_entry {
- struct {
- struct mtk_flow_entry *base_flow;
- struct hlist_node list;
-- struct {} end;
- } l2_data;
- };
- struct rhash_head node;
diff --git a/target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch b/target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch
deleted file mode 100644
index 68f3659367..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From b6a709cb51f7bdc55c01cec886098a9753ce8c28 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:42 +0100
-Subject: [PATCH 01/10] net: mtk_eth_soc: add definitions for PCS
-
-As a result of help from Frank Wunderlich to investigate and test, we
-know a bit more about the PCS on the Mediatek platforms. Update the
-definitions from this investigation.
-
-This PCS appears similar, but not identical to the Lynx PCS.
-
-Although not included in this patch, but for future reference, the PHY
-ID registers at offset 4 read as 0x4d544950 'MTIP'.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++++++++---
- 1 file changed, 10 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -501,8 +501,10 @@
- #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-
- /* SGMII subsystem config registers */
--/* Register to auto-negotiation restart */
-+/* BMCR (low 16) BMSR (high 16) */
- #define SGMSYS_PCS_CONTROL_1 0x0
-+#define SGMII_BMCR GENMASK(15, 0)
-+#define SGMII_BMSR GENMASK(31, 16)
- #define SGMII_AN_RESTART BIT(9)
- #define SGMII_ISOLATE BIT(10)
- #define SGMII_AN_ENABLE BIT(12)
-@@ -512,13 +514,18 @@
- #define SGMII_PCS_FAULT BIT(23)
- #define SGMII_AN_EXPANSION_CLR BIT(30)
-
-+#define SGMSYS_PCS_ADVERTISE 0x8
-+#define SGMII_ADVERTISE GENMASK(15, 0)
-+#define SGMII_LPA GENMASK(31, 16)
-+
- /* Register to programmable link timer, the unit in 2 * 8ns */
- #define SGMSYS_PCS_LINK_TIMER 0x18
--#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & GENMASK(19, 0))
-+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
-+#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
-
- /* Register to control remote fault */
- #define SGMSYS_SGMII_MODE 0x20
--#define SGMII_IF_MODE_BIT0 BIT(0)
-+#define SGMII_IF_MODE_SGMII BIT(0)
- #define SGMII_SPEED_DUPLEX_AN BIT(1)
- #define SGMII_SPEED_MASK GENMASK(3, 2)
- #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
diff --git a/target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch b/target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch
deleted file mode 100644
index 4ea428c9d6..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 5cf7797526ee81bea0f627bccaa3d887f48f53e0 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:47 +0100
-Subject: [PATCH 02/10] net: mtk_eth_soc: eliminate unnecessary error handling
-
-The functions called by the pcs_config() method always return zero, so
-there is no point trying to handle an error from these functions. Make
-these functions void, eliminate the "err" variable and simply return
-zero from the pcs_config() function itself.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++------------
- 1 file changed, 6 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -20,7 +20,7 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
- }
-
- /* For SGMII interface mode */
--static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
-+static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
- unsigned int val;
-
-@@ -39,16 +39,13 @@ static int mtk_pcs_setup_mode_an(struct
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
- val &= ~SGMII_PHYA_PWD;
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
--
-- return 0;
--
- }
-
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
- * fixed speed.
- */
--static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
-- phy_interface_t interface)
-+static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
-+ phy_interface_t interface)
- {
- unsigned int val;
-
-@@ -73,8 +70,6 @@ static int mtk_pcs_setup_mode_force(stru
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
- val &= ~SGMII_PHYA_PWD;
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
--
-- return 0;
- }
-
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -83,15 +78,14 @@ static int mtk_pcs_config(struct phylink
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- int err = 0;
-
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
-- err = mtk_pcs_setup_mode_force(mpcs, interface);
-+ mtk_pcs_setup_mode_force(mpcs, interface);
- else if (phylink_autoneg_inband(mode))
-- err = mtk_pcs_setup_mode_an(mpcs);
-+ mtk_pcs_setup_mode_an(mpcs);
-
-- return err;
-+ return 0;
- }
-
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
diff --git a/target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch b/target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch
deleted file mode 100644
index 64a4a72fa6..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From c000dca098002da193b98099df051c9ead0cacb4 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:52 +0100
-Subject: [PATCH 03/10] net: mtk_eth_soc: add pcs_get_state() implementation
-
-Add a pcs_get_state() implementation which uses the advertisements
-to compute the resulting link modes, and BMSR contents to determine
-negotiation and link status.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -19,6 +19,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
- return container_of(pcs, struct mtk_pcs, pcs);
- }
-
-+static void mtk_pcs_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
-+{
-+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ unsigned int bm, adv;
-+
-+ /* Read the BMSR and LPA */
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+
-+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-+ FIELD_GET(SGMII_LPA, adv));
-+}
-+
- /* For SGMII interface mode */
- static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
-@@ -117,6 +131,7 @@ static void mtk_pcs_link_up(struct phyli
- }
-
- static const struct phylink_pcs_ops mtk_pcs_ops = {
-+ .pcs_get_state = mtk_pcs_get_state,
- .pcs_config = mtk_pcs_config,
- .pcs_an_restart = mtk_pcs_restart_an,
- .pcs_link_up = mtk_pcs_link_up,
diff --git a/target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch b/target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch
deleted file mode 100644
index 24610fe11e..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From 0d2351dc2768061689abd4de1529fa206bbd574e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:58 +0100
-Subject: [PATCH 04/10] net: mtk_eth_soc: convert mtk_sgmii to use
- regmap_update_bits()
-
-mtk_sgmii does a lot of read-modify-write operations, for which there
-is a specific regmap function. Use this function instead of open-coding
-the operations.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 61 ++++++++++-------------
- 1 file changed, 26 insertions(+), 35 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -36,23 +36,18 @@ static void mtk_pcs_get_state(struct phy
- /* For SGMII interface mode */
- static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
-- unsigned int val;
--
- /* Setup the link timer and QPHY power up inside SGMIISYS */
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
- SGMII_LINK_TIMER_DEFAULT);
-
-- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val |= SGMII_REMOTE_FAULT_DIS;
-- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
--
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
-- val |= SGMII_AN_RESTART;
-- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
--
-- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-- val &= ~SGMII_PHYA_PWD;
-- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
-+
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_RESTART, SGMII_AN_RESTART);
-+
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
- }
-
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
-@@ -61,29 +56,26 @@ static void mtk_pcs_setup_mode_an(struct
- static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
- phy_interface_t interface)
- {
-- unsigned int val;
-+ unsigned int rgc3;
-
-- regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
-- val &= ~RG_PHY_SPEED_MASK;
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- val |= RG_PHY_SPEED_3_125G;
-- regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
-+ rgc3 = RG_PHY_SPEED_3_125G;
-+
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ RG_PHY_SPEED_3_125G, rgc3);
-
- /* Disable SGMII AN */
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
-- val &= ~SGMII_AN_ENABLE;
-- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_ENABLE, 0);
-
- /* Set the speed etc but leave the duplex unchanged */
-- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
-- val |= SGMII_SPEED_1000;
-- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
-+ SGMII_SPEED_1000);
-
- /* Release PHYA power down state */
-- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-- val &= ~SGMII_PHYA_PWD;
-- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
- }
-
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -105,29 +97,28 @@ static int mtk_pcs_config(struct phylink
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int val;
-
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
-- val |= SGMII_AN_RESTART;
-- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_RESTART, SGMII_AN_RESTART);
- }
-
- static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface, int speed, int duplex)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int val;
-+ unsigned int sgm_mode;
-
- if (!phy_interface_mode_is_8023z(interface))
- return;
-
- /* SGMII force duplex setting */
-- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val &= ~SGMII_DUPLEX_FULL;
- if (duplex == DUPLEX_FULL)
-- val |= SGMII_DUPLEX_FULL;
-+ sgm_mode = SGMII_DUPLEX_FULL;
-+ else
-+ sgm_mode = 0;
-
-- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_DUPLEX_FULL, sgm_mode);
- }
-
- static const struct phylink_pcs_ops mtk_pcs_ops = {
diff --git a/target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch b/target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch
deleted file mode 100644
index ba76ca40ff..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 12198c3a410fe69843e335c1bbf6d4c2a4d48e4e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:03 +0100
-Subject: [PATCH 05/10] net: mtk_eth_soc: add out of band forcing of speed and
- duplex in pcs_link_up
-
-Add support for forcing the link speed and duplex setting in the
-pcs_link_up() method for out of band modes, which will be useful when
-we finish converting the pcs_config() method. Until then, we still have
-to force duplex for 802.3z modes to work correctly.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 28 ++++++++++++++---------
- 1 file changed, 17 insertions(+), 11 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -108,17 +108,23 @@ static void mtk_pcs_link_up(struct phyli
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int sgm_mode;
-
-- if (!phy_interface_mode_is_8023z(interface))
-- return;
-+ if (!phylink_autoneg_inband(mode) ||
-+ phy_interface_mode_is_8023z(interface)) {
-+ /* Force the speed and duplex setting */
-+ if (speed == SPEED_10)
-+ sgm_mode = SGMII_SPEED_10;
-+ else if (speed == SPEED_100)
-+ sgm_mode = SGMII_SPEED_100;
-+ else
-+ sgm_mode = SGMII_SPEED_1000;
-
-- /* SGMII force duplex setting */
-- if (duplex == DUPLEX_FULL)
-- sgm_mode = SGMII_DUPLEX_FULL;
-- else
-- sgm_mode = 0;
-+ if (duplex == DUPLEX_FULL)
-+ sgm_mode |= SGMII_DUPLEX_FULL;
-
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_DUPLEX_FULL, sgm_mode);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
-+ sgm_mode);
-+ }
- }
-
- static const struct phylink_pcs_ops mtk_pcs_ops = {
diff --git a/target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch b/target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch
deleted file mode 100644
index b76e159275..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 6f38fffe2179dd29612aea2c67c46ed6682b4e46 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:08 +0100
-Subject: [PATCH 06/10] net: mtk_eth_soc: move PHY power up
-
-The PHY power up is common to both configuration paths, so move it into
-the parent function. We need to do this for all serdes modes.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -45,9 +45,6 @@ static void mtk_pcs_setup_mode_an(struct
-
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_RESTART, SGMII_AN_RESTART);
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
- }
-
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
-@@ -72,10 +69,6 @@ static void mtk_pcs_setup_mode_force(str
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
- SGMII_SPEED_1000);
--
-- /* Release PHYA power down state */
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
- }
-
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -91,6 +84,10 @@ static int mtk_pcs_config(struct phylink
- else if (phylink_autoneg_inband(mode))
- mtk_pcs_setup_mode_an(mpcs);
-
-+ /* Release PHYA power down state */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch b/target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch
deleted file mode 100644
index cd9f0699b3..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f752c0df13dfeb721c11d3debb79f08cf437344f Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:13 +0100
-Subject: [PATCH 07/10] net: mtk_eth_soc: move interface speed selection
-
-Move the selection of the underlying interface speed to the pcs_config
-function, so we always program the interface speed.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++++++--------
- 1 file changed, 10 insertions(+), 8 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -53,14 +53,6 @@ static void mtk_pcs_setup_mode_an(struct
- static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
- phy_interface_t interface)
- {
-- unsigned int rgc3;
--
-- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- rgc3 = RG_PHY_SPEED_3_125G;
--
-- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-- RG_PHY_SPEED_3_125G, rgc3);
--
- /* Disable SGMII AN */
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_ENABLE, 0);
-@@ -77,6 +69,16 @@ static int mtk_pcs_config(struct phylink
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ unsigned int rgc3;
-+
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+ rgc3 = RG_PHY_SPEED_3_125G;
-+ else
-+ rgc3 = 0;
-+
-+ /* Configure the underlying interface speed */
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ RG_PHY_SPEED_3_125G, rgc3);
-
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
diff --git a/target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch b/target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch
deleted file mode 100644
index f08358e963..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From c125c66ea71b9377ae2478c4f1b87b180cc5c6ef Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:18 +0100
-Subject: [PATCH 08/10] net: mtk_eth_soc: add advertisement programming
-
-Program the advertisement into the mtk PCS block.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -70,16 +70,27 @@ static int mtk_pcs_config(struct phylink
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int rgc3;
-+ int advertise;
-+ bool changed;
-
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- rgc3 = RG_PHY_SPEED_3_125G;
- else
- rgc3 = 0;
-
-+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-+ advertising);
-+ if (advertise < 0)
-+ return advertise;
-+
- /* Configure the underlying interface speed */
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-
-+ /* Update the advertisement, noting whether it has changed */
-+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-+ SGMII_ADVERTISE, advertise, &changed);
-+
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
- mtk_pcs_setup_mode_force(mpcs, interface);
-@@ -90,7 +101,7 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, 0);
-
-- return 0;
-+ return changed;
- }
-
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
diff --git a/target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch b/target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch
deleted file mode 100644
index 602d52c6f4..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 3027d89f87707e7f3e5b683e0d37a32afb5bde96 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:23 +0100
-Subject: [PATCH 09/10] net: mtk_eth_soc: move and correct link timer
- programming
-
-Program the link timer appropriately for the interface mode being
-used, using the newly introduced phylink helper that provides the
-nanosecond link timer interval.
-
-The intervals are 1.6ms for SGMII based protocols and 10ms for
-802.3z based protocols.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++-----
- 1 file changed, 8 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -36,10 +36,6 @@ static void mtk_pcs_get_state(struct phy
- /* For SGMII interface mode */
- static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
-- /* Setup the link timer and QPHY power up inside SGMIISYS */
-- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
-- SGMII_LINK_TIMER_DEFAULT);
--
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
-
-@@ -69,8 +65,8 @@ static int mtk_pcs_config(struct phylink
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ int advertise, link_timer;
- unsigned int rgc3;
-- int advertise;
- bool changed;
-
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-@@ -83,6 +79,10 @@ static int mtk_pcs_config(struct phylink
- if (advertise < 0)
- return advertise;
-
-+ link_timer = phylink_get_link_timer_ns(interface);
-+ if (link_timer < 0)
-+ return link_timer;
-+
- /* Configure the underlying interface speed */
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-@@ -91,6 +91,9 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
- SGMII_ADVERTISE, advertise, &changed);
-
-+ /* Setup the link timer and QPHY power up inside SGMIISYS */
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-+
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
- mtk_pcs_setup_mode_force(mpcs, interface);
diff --git a/target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch b/target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch
deleted file mode 100644
index 0e9a0535a7..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From 81b0f12a2a8a1699a7d49c3995e5f71e4ec018e6 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:28 +0100
-Subject: [PATCH 10/10] net: mtk_eth_soc: add support for in-band 802.3z
- negotiation
-
-As a result of help from Frank Wunderlich to investigate and test, we
-now know how to program this PCS for in-band 802.3z negotiation. Add
-support for this by moving the contents of the two functions into the
-common mtk_pcs_config() function and adding the register settings for
-802.3z negotiation.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 77 ++++++++++++-----------
- 1 file changed, 42 insertions(+), 35 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -33,41 +33,15 @@ static void mtk_pcs_get_state(struct phy
- FIELD_GET(SGMII_LPA, adv));
- }
-
--/* For SGMII interface mode */
--static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
--{
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_RESTART, SGMII_AN_RESTART);
--}
--
--/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
-- * fixed speed.
-- */
--static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
-- phy_interface_t interface)
--{
-- /* Disable SGMII AN */
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_ENABLE, 0);
--
-- /* Set the speed etc but leave the duplex unchanged */
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
-- SGMII_SPEED_1000);
--}
--
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ unsigned int rgc3, sgm_mode, bmcr;
- int advertise, link_timer;
-- unsigned int rgc3;
-- bool changed;
-+ bool changed, use_an;
-
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- rgc3 = RG_PHY_SPEED_3_125G;
-@@ -83,6 +57,37 @@ static int mtk_pcs_config(struct phylink
- if (link_timer < 0)
- return link_timer;
-
-+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
-+ * we assume that fixes it's speed at bitrate = line rate (in
-+ * other words, 1000Mbps or 2500Mbps).
-+ */
-+ if (interface == PHY_INTERFACE_MODE_SGMII) {
-+ sgm_mode = SGMII_IF_MODE_SGMII;
-+ if (phylink_autoneg_inband(mode)) {
-+ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-+ SGMII_SPEED_DUPLEX_AN;
-+ use_an = true;
-+ } else {
-+ use_an = false;
-+ }
-+ } else if (phylink_autoneg_inband(mode)) {
-+ /* 1000base-X or 2500base-X autoneg */
-+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
-+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ advertising);
-+ } else {
-+ /* 1000base-X or 2500base-X without autoneg */
-+ sgm_mode = 0;
-+ use_an = false;
-+ }
-+
-+ if (use_an) {
-+ /* FIXME: Do we need to set AN_RESTART here? */
-+ bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
-+ } else {
-+ bmcr = 0;
-+ }
-+
- /* Configure the underlying interface speed */
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-@@ -94,11 +99,14 @@ static int mtk_pcs_config(struct phylink
- /* Setup the link timer and QPHY power up inside SGMIISYS */
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-
-- /* Setup SGMIISYS with the determined property */
-- if (interface != PHY_INTERFACE_MODE_SGMII)
-- mtk_pcs_setup_mode_force(mpcs, interface);
-- else if (phylink_autoneg_inband(mode))
-- mtk_pcs_setup_mode_an(mpcs);
-+ /* Update the sgmsys mode register */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-+ SGMII_IF_MODE_SGMII, sgm_mode);
-+
-+ /* Update the BMCR */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
-
- /* Release PHYA power down state */
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-@@ -121,8 +129,7 @@ static void mtk_pcs_link_up(struct phyli
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int sgm_mode;
-
-- if (!phylink_autoneg_inband(mode) ||
-- phy_interface_mode_is_8023z(interface)) {
-+ if (!phylink_autoneg_inband(mode)) {
- /* Force the speed and duplex setting */
- if (speed == SPEED_10)
- sgm_mode = SGMII_SPEED_10;
diff --git a/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch b/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch
deleted file mode 100644
index 598788d998..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Wed, 1 Feb 2023 19:23:29 +0100
-Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered
- down on configuration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The code expect the PHY to be in power down which is only true after reset.
-Allow changes of the SGMII parameters more than once.
-
-Only power down when reconfiguring to avoid bouncing the link when there's
-no reason to - based on code from Russell King.
-
-There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-prevents SGMII from working. The SGMII still shows link but no traffic
-can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-taken from a good working state of the SGMII interface.
-
-Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC")
-Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
-[ bmork: rebased and squashed into one patch ]
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------
- 2 files changed, 30 insertions(+), 11 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1064,11 +1064,13 @@ struct mtk_soc_data {
- * @regmap: The register map pointing at the range used to setup
- * SGMII modes
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
-+ * @interface: Currently configured interface mode
- * @pcs: Phylink PCS structure
- */
- struct mtk_pcs {
- struct regmap *regmap;
- u32 ana_rgc3;
-+ phy_interface_t interface;
- struct phylink_pcs pcs;
- };
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink
- int advertise, link_timer;
- bool changed, use_an;
-
-- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- rgc3 = RG_PHY_SPEED_3_125G;
-- else
-- rgc3 = 0;
--
- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
- advertising);
- if (advertise < 0)
-@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink
- bmcr = 0;
- }
-
-- /* Configure the underlying interface speed */
-- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-- RG_PHY_SPEED_3_125G, rgc3);
-+ if (mpcs->interface != interface) {
-+ /* PHYA power down */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-+
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+ rgc3 = RG_PHY_SPEED_3_125G;
-+ else
-+ rgc3 = 0;
-+
-+ /* Configure the underlying interface speed */
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ RG_PHY_SPEED_3_125G, rgc3);
-+
-+ mpcs->interface = interface;
-+ }
-
- /* Update the advertisement, noting whether it has changed */
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
-
-- /* Release PHYA power down state */
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
-+ /* Release PHYA power down state
-+ * Only removing bit SGMII_PHYA_PWD isn't enough.
-+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-+ * prevents SGMII from working. The SGMII still shows link but no traffic
-+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-+ * taken from a good working state of the SGMII interface.
-+ * Unknown how much the QPHY needs but it is racy without a sleep.
-+ * Tested on mt7622 & mt7986.
-+ */
-+ usleep_range(50, 100);
-+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-
- return changed;
- }
-@@ -171,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- return PTR_ERR(ss->pcs[i].regmap);
-
- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
-+ ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
- }
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch b/target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch
deleted file mode 100644
index 79e5ad147c..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
-Date: Wed, 1 Feb 2023 19:23:30 +0100
-Subject: [PATCH 12/13] net: mediatek: sgmii: fix duplex configuration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The logic of the duplex bit is inverted. Setting it means half
-duplex, not full duplex.
-
-Fix and rename macro to avoid confusion.
-
-Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -531,7 +531,7 @@
- #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
- #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
- #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
--#define SGMII_DUPLEX_FULL BIT(4)
-+#define SGMII_DUPLEX_HALF BIT(4)
- #define SGMII_IF_MODE_BIT5 BIT(5)
- #define SGMII_REMOTE_FAULT_DIS BIT(8)
- #define SGMII_CODE_SYNC_SET_VAL BIT(9)
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -154,11 +154,11 @@ static void mtk_pcs_link_up(struct phyli
- else
- sgm_mode = SGMII_SPEED_1000;
-
-- if (duplex == DUPLEX_FULL)
-- sgm_mode |= SGMII_DUPLEX_FULL;
-+ if (duplex != DUPLEX_FULL)
-+ sgm_mode |= SGMII_DUPLEX_HALF;
-
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
-+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
- sgm_mode);
- }
- }
diff --git a/target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch b/target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch
deleted file mode 100644
index 56d7a1348f..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Wed, 1 Feb 2023 19:23:31 +0100
-Subject: [PATCH 13/13] mtk_sgmii: enable PCS polling to allow SFP work
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently there is no IRQ handling (even the SGMII supports it).
-Enable polling to support SFP ports.
-
-Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
-[ bmork: changed "1" => "true" ]
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -187,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- return PTR_ERR(ss->pcs[i].regmap);
-
- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
-+ ss->pcs[i].pcs.poll = true;
- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
- }
-
diff --git a/target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch b/target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch
deleted file mode 100644
index a63b110914..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 611e2dabb4b3243d176739fd6a5a34d007fa3f86 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 14 Mar 2023 00:34:26 +0000
-Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: reset PCS state
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Reset the internal PCS state machine when changing interface mode.
-This prevents confusing the state machine when changing interface
-modes, e.g. from SGMII to 2500Base-X or vice-versa.
-
-Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -539,6 +539,10 @@
- #define SGMII_SEND_AN_ERROR_EN BIT(11)
- #define SGMII_IF_MODE_MASK GENMASK(5, 1)
-
-+/* Register to reset SGMII design */
-+#define SGMII_RESERVED_0 0x34
-+#define SGMII_SW_RESET BIT(0)
-+
- /* Register to set SGMII speed, ANA RG_ Control Signals III*/
- #define SGMSYS_ANA_RG_CS3 0x2028
- #define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-
-+ /* Reset SGMII PCS state */
-+ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
-+ SGMII_SW_RESET, SGMII_SW_RESET);
-+
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- rgc3 = RG_PHY_SPEED_3_125G;
- else
diff --git a/target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch b/target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch
deleted file mode 100644
index 0fabeea20c..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 14 Mar 2023 00:34:45 +0000
-Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Only restart auto-negotiation and write link timer if actually
-necessary. This prevents losing the link in case of minor
-changes.
-
-Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink
- const unsigned long *advertising,
- bool permit_pause_to_mac)
- {
-+ bool mode_changed = false, changed, use_an;
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int rgc3, sgm_mode, bmcr;
- int advertise, link_timer;
-- bool changed, use_an;
-
- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
- advertising);
- if (advertise < 0)
- return advertise;
-
-- link_timer = phylink_get_link_timer_ns(interface);
-- if (link_timer < 0)
-- return link_timer;
--
- /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
- * we assume that fixes it's speed at bitrate = line rate (in
- * other words, 1000Mbps or 2500Mbps).
-@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink
- }
-
- if (use_an) {
-- /* FIXME: Do we need to set AN_RESTART here? */
-- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
-+ bmcr = SGMII_AN_ENABLE;
- } else {
- bmcr = 0;
- }
-
- if (mpcs->interface != interface) {
-+ link_timer = phylink_get_link_timer_ns(interface);
-+ if (link_timer < 0)
-+ return link_timer;
-+
- /* PHYA power down */
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-
-+ /* Setup the link timer */
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-+
- mpcs->interface = interface;
-+ mode_changed = true;
- }
-
- /* Update the advertisement, noting whether it has changed */
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
- SGMII_ADVERTISE, advertise, &changed);
-
-- /* Setup the link timer and QPHY power up inside SGMIISYS */
-- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
--
- /* Update the sgmsys mode register */
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink
-
- /* Update the BMCR */
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
-+ SGMII_AN_ENABLE, bmcr);
-
- /* Release PHYA power down state
- * Only removing bit SGMII_PHYA_PWD isn't enough.
-@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink
- usleep_range(50, 100);
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-
-- return changed;
-+ return changed || mode_changed;
- }
-
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
diff --git a/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch
deleted file mode 100644
index 741831f696..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch
+++ /dev/null
@@ -1,200 +0,0 @@
-From f5d43ddd334b7c32fcaed9ba46afbd85cb467f1f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:56:28 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for MT7981 SoC
-
-The MediaTek MT7981 SoC comes with two 1G/2.5G SGMII ports, just like
-MT7986.
-
-In addition MT7981 is equipped with a built-in 1000Base-T PHY which can
-be used with GMAC1.
-
-As many MT7981 boards make use of inverting SGMII signal polarity, add
-new device-tree attribute 'mediatek,pn_swap' to support them.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy(
-
- static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
- {
-- unsigned int val = 0;
-+ unsigned int val = 0, mask = 0, reg = 0;
- bool updated = true;
-
- switch (path) {
- case MTK_ETH_PATH_GMAC2_SGMII:
-- val = CO_QPHY_SEL;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) {
-+ reg = USB_PHY_SWITCH_REG;
-+ val = SGMII_QPHY_SEL;
-+ mask = QPHY_SEL_MASK;
-+ } else {
-+ reg = INFRA_MISC2;
-+ val = CO_QPHY_SEL;
-+ mask = val;
-+ }
- break;
- default:
- updated = false;
-@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
- }
-
- if (updated)
-- regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
-+ regmap_update_bits(eth->infra, reg, mask, val);
-
- dev_dbg(eth->dev, "path %s in %s updated = %d\n",
- mtk_eth_path_name(path), __func__, updated);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4751,6 +4751,26 @@ static const struct mtk_soc_data mt7629_
- },
- };
-
-+static const struct mtk_soc_data mt7981_data = {
-+ .reg_map = &mt7986_reg_map,
-+ .ana_rgc3 = 0x128,
-+ .caps = MT7981_CAPS,
-+ .hw_features = MTK_HW_FEATURES,
-+ .required_clks = MT7981_CLKS_BITMAP,
-+ .required_pctl = false,
-+ .offload_version = 2,
-+ .hash_offset = 4,
-+ .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+};
-+
- static const struct mtk_soc_data mt7986_data = {
- .reg_map = &mt7986_reg_map,
- .ana_rgc3 = 0x128,
-@@ -4793,6 +4813,7 @@ const struct of_device_id of_mtk_match[]
- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
-+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
- {},
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -553,11 +553,22 @@
- #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
- #define SGMII_PHYA_PWD BIT(4)
-
-+/* Register to QPHY wrapper control */
-+#define SGMSYS_QPHY_WRAP_CTRL 0xec
-+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
-+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
-+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
-+
- /* Infrasys subsystem config registers */
- #define INFRA_MISC2 0x70c
- #define CO_QPHY_SEL BIT(0)
- #define GEPHY_MAC_SEL BIT(1)
-
-+/* Top misc registers */
-+#define USB_PHY_SWITCH_REG 0x218
-+#define QPHY_SEL_MASK GENMASK(1, 0)
-+#define SGMII_QPHY_SEL 0x2
-+
- /* MT7628/88 specific stuff */
- #define MT7628_PDMA_OFFSET 0x0800
- #define MT7628_SDM_OFFSET 0x0c00
-@@ -738,6 +749,17 @@ enum mtk_clks_map {
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK) | \
- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
-+#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
-+ BIT(MTK_CLK_WOCPU0) | \
-+ BIT(MTK_CLK_SGMII_TX_250M) | \
-+ BIT(MTK_CLK_SGMII_RX_250M) | \
-+ BIT(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT(MTK_CLK_SGMII2_CDR_FB) | \
-+ BIT(MTK_CLK_SGMII_CK))
- #define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
-@@ -851,6 +873,7 @@ enum mkt_eth_capabilities {
- MTK_NETSYS_V2_BIT,
- MTK_SOC_MT7628_BIT,
- MTK_RSTCTRL_PPE1_BIT,
-+ MTK_U3_COPHY_V2_BIT,
-
- /* MUX BITS*/
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-@@ -885,6 +908,7 @@ enum mkt_eth_capabilities {
- #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
- #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -957,6 +981,11 @@ enum mkt_eth_capabilities {
- MTK_MUX_U3_GMAC2_TO_QPHY | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
-
-+#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_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+
- #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-@@ -1070,12 +1099,14 @@ struct mtk_soc_data {
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
- * @interface: Currently configured interface mode
- * @pcs: Phylink PCS structure
-+ * @flags: Flags indicating hardware properties
- */
- struct mtk_pcs {
- struct regmap *regmap;
- u32 ana_rgc3;
- phy_interface_t interface;
- struct phylink_pcs pcs;
-+ u32 flags;
- };
-
- /* struct mtk_sgmii - This is the structure holding sgmii regmap and its
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -87,6 +87,11 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-
-+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-+ SGMII_PN_SWAP_MASK,
-+ SGMII_PN_SWAP_TX_RX);
-+
- /* Reset SGMII PCS state */
- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
- SGMII_SW_RESET, SGMII_SW_RESET);
-@@ -186,6 +191,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
-
- ss->pcs[i].ana_rgc3 = ana_rgc3;
- ss->pcs[i].regmap = syscon_node_to_regmap(np);
-+
-+ ss->pcs[i].flags = 0;
-+ if (of_property_read_bool(np, "mediatek,pnswap"))
-+ ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
-+
- of_node_put(np);
- if (IS_ERR(ss->pcs[i].regmap))
- return PTR_ERR(ss->pcs[i].regmap);
diff --git a/target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch b/target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch
deleted file mode 100644
index d4c1ecf22c..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From c0a440031d4314d1023c1b87f43a4233634eebdb Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:57:15 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: set MDIO bus clock frequency
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Set MDIO bus clock frequency and allow setting a custom maximum
-frequency from device tree.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 +++++++
- 2 files changed, 28 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -701,8 +701,10 @@ static const struct phylink_mac_ops mtk_
-
- static int mtk_mdio_init(struct mtk_eth *eth)
- {
-+ unsigned int max_clk = 2500000, divider;
- struct device_node *mii_np;
- int ret;
-+ u32 val;
-
- mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
- if (!mii_np) {
-@@ -728,6 +730,25 @@ static int mtk_mdio_init(struct mtk_eth
- eth->mii_bus->parent = eth->dev;
-
- snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
-+
-+ if (!of_property_read_u32(mii_np, "clock-frequency", &val)) {
-+ if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
-+ dev_err(eth->dev, "MDIO clock frequency out of range");
-+ ret = -EINVAL;
-+ goto err_put_node;
-+ }
-+ max_clk = val;
-+ }
-+ divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
-+
-+ /* Configure MDC Divider */
-+ val = mtk_r32(eth, MTK_PPSC);
-+ val &= ~PPSC_MDC_CFG;
-+ val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
-+ mtk_w32(eth, val, MTK_PPSC);
-+
-+ dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
-+
- ret = of_mdiobus_register(eth->mii_bus, mii_np);
-
- err_put_node:
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -363,6 +363,13 @@
- #define RX_DMA_VTAG_V2 BIT(0)
- #define RX_DMA_L4_VALID_V2 BIT(2)
-
-+/* PHY Polling and SMI Master Control registers */
-+#define MTK_PPSC 0x10000
-+#define PPSC_MDC_CFG GENMASK(29, 24)
-+#define PPSC_MDC_TURBO BIT(20)
-+#define MDC_MAX_FREQ 25000000
-+#define MDC_MAX_DIVIDER 63
-+
- /* PHY Indirect Access Control registers */
- #define MTK_PHY_IAC 0x10004
- #define PHY_IAC_ACCESS BIT(31)
diff --git a/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch b/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch
deleted file mode 100644
index 8f76206167..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch
+++ /dev/null
@@ -1,512 +0,0 @@
-From 2a3ec7ae313310c1092e4256208cc04d1958e469 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:58:02 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: switch to external PCS driver
-
-Now that we got a PCS driver, use it and remove the now redundant
-PCS code and it's header macros from the Ethernet driver.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/Kconfig | 2 +
- drivers/net/ethernet/mediatek/Makefile | 2 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +--------
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 217 --------------------
- 5 files changed, 56 insertions(+), 319 deletions(-)
- delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -18,6 +18,8 @@ config NET_MEDIATEK_SOC
- select DIMLIB
- select PAGE_POOL
- select PAGE_POOL_STATS
-+ select PCS_MTK_LYNXI
-+ select REGMAP_MMIO
- help
- This driver supports the gigabit ethernet MACs in the
- MediaTek SoC family.
---- 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_sgmii.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_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
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -20,6 +20,7 @@
- #include <linux/interrupt.h>
- #include <linux/pinctrl/devinfo.h>
- #include <linux/phylink.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
- #include <linux/jhash.h>
- #include <linux/bitfield.h>
- #include <net/dsa.h>
-@@ -357,7 +358,7 @@ static struct phylink_pcs *mtk_mac_selec
- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
- 0 : mac->id;
-
-- return mtk_sgmii_select_pcs(eth->sgmii, sid);
-+ return eth->sgmii_pcs[sid];
- }
-
- return NULL;
-@@ -3962,8 +3963,17 @@ static int mtk_unreg_dev(struct mtk_eth
- return 0;
- }
-
-+static void mtk_sgmii_destroy(struct mtk_eth *eth)
-+{
-+ int i;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++)
-+ mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
-+}
-+
- static int mtk_cleanup(struct mtk_eth *eth)
- {
-+ mtk_sgmii_destroy(eth);
- mtk_unreg_dev(eth);
- mtk_free_dev(eth);
- cancel_work_sync(&eth->pending_work);
-@@ -4403,6 +4413,36 @@ void mtk_eth_set_dma_device(struct mtk_e
- rtnl_unlock();
- }
-
-+static int mtk_sgmii_init(struct mtk_eth *eth)
-+{
-+ struct device_node *np;
-+ struct regmap *regmap;
-+ u32 flags;
-+ int i;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
-+ if (!np)
-+ break;
-+
-+ regmap = syscon_node_to_regmap(np);
-+ flags = 0;
-+ if (of_property_read_bool(np, "mediatek,pnswap"))
-+ flags |= MTK_SGMII_FLAG_PN_SWAP;
-+
-+ of_node_put(np);
-+
-+ if (IS_ERR(regmap))
-+ return PTR_ERR(regmap);
-+
-+ eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap,
-+ eth->soc->ana_rgc3,
-+ flags);
-+ }
-+
-+ return 0;
-+}
-+
- static int mtk_probe(struct platform_device *pdev)
- {
- struct resource *res = NULL;
-@@ -4466,13 +4506,7 @@ static int mtk_probe(struct platform_dev
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
-- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii),
-- GFP_KERNEL);
-- if (!eth->sgmii)
-- return -ENOMEM;
--
-- err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node,
-- eth->soc->ana_rgc3);
-+ err = mtk_sgmii_init(eth);
-
- if (err)
- return err;
-@@ -4483,14 +4517,17 @@ static int mtk_probe(struct platform_dev
- "mediatek,pctl");
- if (IS_ERR(eth->pctl)) {
- dev_err(&pdev->dev, "no pctl regmap found\n");
-- return PTR_ERR(eth->pctl);
-+ err = PTR_ERR(eth->pctl);
-+ goto err_destroy_sgmii;
- }
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!res)
-- return -EINVAL;
-+ if (!res) {
-+ err = -EINVAL;
-+ goto err_destroy_sgmii;
-+ }
- }
-
- if (eth->soc->offload_version) {
-@@ -4651,6 +4688,8 @@ err_deinit_hw:
- mtk_hw_deinit(eth);
- err_wed_exit:
- mtk_wed_exit();
-+err_destroy_sgmii:
-+ mtk_sgmii_destroy(eth);
-
- return err;
- }
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -507,65 +507,6 @@
- #define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
- #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-
--/* SGMII subsystem config registers */
--/* BMCR (low 16) BMSR (high 16) */
--#define SGMSYS_PCS_CONTROL_1 0x0
--#define SGMII_BMCR GENMASK(15, 0)
--#define SGMII_BMSR GENMASK(31, 16)
--#define SGMII_AN_RESTART BIT(9)
--#define SGMII_ISOLATE BIT(10)
--#define SGMII_AN_ENABLE BIT(12)
--#define SGMII_LINK_STATYS BIT(18)
--#define SGMII_AN_ABILITY BIT(19)
--#define SGMII_AN_COMPLETE BIT(21)
--#define SGMII_PCS_FAULT BIT(23)
--#define SGMII_AN_EXPANSION_CLR BIT(30)
--
--#define SGMSYS_PCS_ADVERTISE 0x8
--#define SGMII_ADVERTISE GENMASK(15, 0)
--#define SGMII_LPA GENMASK(31, 16)
--
--/* Register to programmable link timer, the unit in 2 * 8ns */
--#define SGMSYS_PCS_LINK_TIMER 0x18
--#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
--#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
--
--/* Register to control remote fault */
--#define SGMSYS_SGMII_MODE 0x20
--#define SGMII_IF_MODE_SGMII BIT(0)
--#define SGMII_SPEED_DUPLEX_AN BIT(1)
--#define SGMII_SPEED_MASK GENMASK(3, 2)
--#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
--#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
--#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
--#define SGMII_DUPLEX_HALF BIT(4)
--#define SGMII_IF_MODE_BIT5 BIT(5)
--#define SGMII_REMOTE_FAULT_DIS BIT(8)
--#define SGMII_CODE_SYNC_SET_VAL BIT(9)
--#define SGMII_CODE_SYNC_SET_EN BIT(10)
--#define SGMII_SEND_AN_ERROR_EN BIT(11)
--#define SGMII_IF_MODE_MASK GENMASK(5, 1)
--
--/* Register to reset SGMII design */
--#define SGMII_RESERVED_0 0x34
--#define SGMII_SW_RESET BIT(0)
--
--/* Register to set SGMII speed, ANA RG_ Control Signals III*/
--#define SGMSYS_ANA_RG_CS3 0x2028
--#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
--#define RG_PHY_SPEED_1_25G 0x0
--#define RG_PHY_SPEED_3_125G BIT(2)
--
--/* Register to power up QPHY */
--#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
--#define SGMII_PHYA_PWD BIT(4)
--
--/* Register to QPHY wrapper control */
--#define SGMSYS_QPHY_WRAP_CTRL 0xec
--#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
--#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
--#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
--
- /* Infrasys subsystem config registers */
- #define INFRA_MISC2 0x70c
- #define CO_QPHY_SEL BIT(0)
-@@ -1099,31 +1040,6 @@ struct mtk_soc_data {
- /* currently no SoC has more than 2 macs */
- #define MTK_MAX_DEVS 2
-
--/* struct mtk_pcs - This structure holds each sgmii regmap and associated
-- * data
-- * @regmap: The register map pointing at the range used to setup
-- * SGMII modes
-- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
-- * @interface: Currently configured interface mode
-- * @pcs: Phylink PCS structure
-- * @flags: Flags indicating hardware properties
-- */
--struct mtk_pcs {
-- struct regmap *regmap;
-- u32 ana_rgc3;
-- phy_interface_t interface;
-- struct phylink_pcs pcs;
-- u32 flags;
--};
--
--/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
-- * characteristics
-- * @pcs Array of individual PCS structures
-- */
--struct mtk_sgmii {
-- struct mtk_pcs pcs[MTK_MAX_DEVS];
--};
--
- /* struct mtk_eth - This is the main datasructure for holding the state
- * of the driver
- * @dev: The device pointer
-@@ -1143,6 +1059,7 @@ struct mtk_sgmii {
- * MII modes
- * @infra: The register map pointing at the range used to setup
- * SGMII and GePHY path
-+ * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances
- * @pctl: The register map pointing at the range used to setup
- * GMAC port drive/slew values
- * @dma_refcnt: track how many netdevs are using the DMA engine
-@@ -1183,8 +1100,8 @@ struct mtk_eth {
- u32 msg_enable;
- unsigned long sysclk;
- struct regmap *ethsys;
-- struct regmap *infra;
-- struct mtk_sgmii *sgmii;
-+ struct regmap *infra;
-+ struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
- struct regmap *pctl;
- bool hwlro;
- refcount_t dma_refcnt;
-@@ -1346,10 +1263,6 @@ void mtk_stats_update_mac(struct mtk_mac
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
- u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
-
--struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
--int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
-- u32 ana_rgc3);
--
- int mtk_gmac_sgmii_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);
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ /dev/null
-@@ -1,217 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--// Copyright (c) 2018-2019 MediaTek Inc.
--
--/* A library for MediaTek SGMII circuit
-- *
-- * Author: Sean Wang <sean.wang@mediatek.com>
-- *
-- */
--
--#include <linux/mfd/syscon.h>
--#include <linux/of.h>
--#include <linux/phylink.h>
--#include <linux/regmap.h>
--
--#include "mtk_eth_soc.h"
--
--static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
--{
-- return container_of(pcs, struct mtk_pcs, pcs);
--}
--
--static void mtk_pcs_get_state(struct phylink_pcs *pcs,
-- struct phylink_link_state *state)
--{
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int bm, adv;
--
-- /* Read the BMSR and LPA */
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
--
-- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-- FIELD_GET(SGMII_LPA, adv));
--}
--
--static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-- phy_interface_t interface,
-- const unsigned long *advertising,
-- bool permit_pause_to_mac)
--{
-- bool mode_changed = false, changed, use_an;
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int rgc3, sgm_mode, bmcr;
-- int advertise, link_timer;
--
-- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-- advertising);
-- if (advertise < 0)
-- return 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
-- * other words, 1000Mbps or 2500Mbps).
-- */
-- if (interface == PHY_INTERFACE_MODE_SGMII) {
-- sgm_mode = SGMII_IF_MODE_SGMII;
-- if (phylink_autoneg_inband(mode)) {
-- sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-- SGMII_SPEED_DUPLEX_AN;
-- use_an = true;
-- } else {
-- use_an = false;
-- }
-- } else if (phylink_autoneg_inband(mode)) {
-- /* 1000base-X or 2500base-X autoneg */
-- sgm_mode = SGMII_REMOTE_FAULT_DIS;
-- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-- advertising);
-- } else {
-- /* 1000base-X or 2500base-X without autoneg */
-- sgm_mode = 0;
-- use_an = false;
-- }
--
-- if (use_an) {
-- bmcr = SGMII_AN_ENABLE;
-- } else {
-- bmcr = 0;
-- }
--
-- if (mpcs->interface != interface) {
-- link_timer = phylink_get_link_timer_ns(interface);
-- if (link_timer < 0)
-- return link_timer;
--
-- /* PHYA power down */
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
--
-- if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-- SGMII_PN_SWAP_MASK,
-- SGMII_PN_SWAP_TX_RX);
--
-- /* Reset SGMII PCS state */
-- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
-- SGMII_SW_RESET, SGMII_SW_RESET);
--
-- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- rgc3 = RG_PHY_SPEED_3_125G;
-- else
-- rgc3 = 0;
--
-- /* Configure the underlying interface speed */
-- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-- RG_PHY_SPEED_3_125G, rgc3);
--
-- /* Setup the link timer */
-- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
--
-- mpcs->interface = interface;
-- mode_changed = true;
-- }
--
-- /* Update the advertisement, noting whether it has changed */
-- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-- SGMII_ADVERTISE, advertise, &changed);
--
-- /* Update the sgmsys mode register */
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-- SGMII_IF_MODE_SGMII, sgm_mode);
--
-- /* Update the BMCR */
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_ENABLE, bmcr);
--
-- /* Release PHYA power down state
-- * Only removing bit SGMII_PHYA_PWD isn't enough.
-- * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-- * prevents SGMII from working. The SGMII still shows link but no traffic
-- * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-- * taken from a good working state of the SGMII interface.
-- * Unknown how much the QPHY needs but it is racy without a sleep.
-- * Tested on mt7622 & mt7986.
-- */
-- usleep_range(50, 100);
-- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
--
-- return changed || mode_changed;
--}
--
--static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
--{
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_RESTART, SGMII_AN_RESTART);
--}
--
--static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-- phy_interface_t interface, int speed, int duplex)
--{
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int sgm_mode;
--
-- if (!phylink_autoneg_inband(mode)) {
-- /* Force the speed and duplex setting */
-- if (speed == SPEED_10)
-- sgm_mode = SGMII_SPEED_10;
-- else if (speed == SPEED_100)
-- sgm_mode = SGMII_SPEED_100;
-- else
-- sgm_mode = SGMII_SPEED_1000;
--
-- if (duplex != DUPLEX_FULL)
-- sgm_mode |= SGMII_DUPLEX_HALF;
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
-- sgm_mode);
-- }
--}
--
--static const struct phylink_pcs_ops mtk_pcs_ops = {
-- .pcs_get_state = mtk_pcs_get_state,
-- .pcs_config = mtk_pcs_config,
-- .pcs_an_restart = mtk_pcs_restart_an,
-- .pcs_link_up = mtk_pcs_link_up,
--};
--
--int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
--{
-- struct device_node *np;
-- int i;
--
-- for (i = 0; i < MTK_MAX_DEVS; i++) {
-- np = of_parse_phandle(r, "mediatek,sgmiisys", i);
-- if (!np)
-- break;
--
-- ss->pcs[i].ana_rgc3 = ana_rgc3;
-- ss->pcs[i].regmap = syscon_node_to_regmap(np);
--
-- ss->pcs[i].flags = 0;
-- if (of_property_read_bool(np, "mediatek,pnswap"))
-- ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
--
-- of_node_put(np);
-- if (IS_ERR(ss->pcs[i].regmap))
-- return PTR_ERR(ss->pcs[i].regmap);
--
-- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
-- ss->pcs[i].pcs.poll = true;
-- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
-- }
--
-- return 0;
--}
--
--struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
--{
-- if (!ss->pcs[id].regmap)
-- return NULL;
--
-- return &ss->pcs[id].pcs;
--}
diff --git a/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch b/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch
deleted file mode 100644
index 7742b0925b..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 11:19:14 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add missing ppe cache flush when
- deleting a flow
-
-The cache needs to be flushed to ensure that the hardware stops offloading
-the flow immediately.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -464,6 +464,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- hwe->ib1 &= ~MTK_FOE_IB1_STATE;
- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
- dma_wmb();
-+ mtk_ppe_cache_clear(ppe);
- }
- entry->hash = 0xffff;
-
diff --git a/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch
deleted file mode 100644
index 9ce2735951..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From f5af7931d2a2cae66d0f9dad4ba517b1b00620b3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 19 Apr 2023 19:07:23 +0100
-Subject: [PATCH] net: mtk_eth_soc: use WO firmware for MT7981
-
-In order to support wireless offloading on MT7981 we need to load the
-appropriate firmware. Recognize MT7981 and load mt7981_wo.bin.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 7 ++++++-
- drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 +
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- wo->hw->index + 1);
-
- /* load firmware */
-- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+ if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
-+ fw_name = MT7981_FIRMWARE_WO;
-+ else
-+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+
- ret = request_firmware(&fw, fw_name, wo->hw->dev);
- if (ret)
- return ret;
-@@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *
- 100, MTK_FW_DL_TIMEOUT);
- }
-
-+MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx {
- MTK_WED_DUMMY_CR_WO_STATUS,
- };
-
-+#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
- #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
- #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
-
diff --git a/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch
deleted file mode 100644
index d715c4aa68..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 7c83e28f10830aa5105c25eaabe890e3adac36aa Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 9 May 2023 03:20:06 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix NULL pointer dereference
-
-Check for NULL pointer to avoid kernel crashing in case of missing WO
-firmware in case only a single WEDv2 device has been initialized, e.g. on
-MT7981 which can connect just one wireless frontend.
-
-Fixes: 86ce0d09e424 ("net: ethernet: mtk_eth_soc: use WO firmware for MT7981")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -647,7 +647,7 @@ __mtk_wed_detach(struct mtk_wed_device *
- BIT(hw->index), BIT(hw->index));
- }
-
-- if (!hw_list[!hw->index]->wed_dev &&
-+ if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) &&
- hw->eth->dma_dev != hw->eth->dev)
- mtk_eth_set_dma_device(hw->eth, hw->eth->dev);
-
diff --git a/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch b/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch
deleted file mode 100644
index e4022ffbdf..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch
+++ /dev/null
@@ -1,428 +0,0 @@
-From patchwork Wed Nov 2 00:58:01 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 13027653
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@kernel.org>
-Date: Wed, 2 Nov 2022 00:58:01 +0000
-From: Daniel Golle <daniel@makrotopia.org>
-To: Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
- Sean Wang <sean.wang@mediatek.com>,
- Mark Lee <Mark-MC.Lee@mediatek.com>,
- "David S. Miller" <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org
-Subject: [PATCH v4] net: ethernet: mediatek: ppe: add support for flow
- accounting
-Message-ID: <Y2HAmYYPd77dz+K5@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-The PPE units found in MT7622 and newer support packet and byte
-accounting of hw-offloaded flows. Add support for reading those
-counters as found in MediaTek's SDK[1].
-
-[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-v4: declare function mtk_mib_entry_read as static
-v3: don't bother to set 'false' values in any zero-initialized struct
- use mtk_foe_entry_ib2
- both changes were requested by Felix Fietkau
-
-v2: fix wrong variable name in return value check spotted by Denis Kirjanov
-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- drivers/net/ethernet/mediatek/mtk_ppe.c | 110 +++++++++++++++++-
- drivers/net/ethernet/mediatek/mtk_ppe.h | 23 +++-
- .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +-
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 7 ++
- drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +++
- 7 files changed, 166 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4637,8 +4637,8 @@ static int mtk_probe(struct platform_dev
- for (i = 0; i < num_ppe; i++) {
- u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
-
-- eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
-- eth->soc->offload_version, i);
-+ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
-+
- if (!eth->ppe[i]) {
- err = -ENOMEM;
- goto err_deinit_ppe;
-@@ -4764,6 +4764,7 @@ static const struct mtk_soc_data mt7622_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 2,
-+ .has_accounting = true,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4801,6 +4802,7 @@ static const struct mtk_soc_data mt7629_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7629_CLKS_BITMAP,
- .required_pctl = false,
-+ .has_accounting = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4821,6 +4823,7 @@ static const struct mtk_soc_data mt7981_
- .offload_version = 2,
- .hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .has_accounting = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4841,6 +4844,7 @@ static const struct mtk_soc_data mt7986_
- .offload_version = 2,
- .hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .has_accounting = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1008,6 +1008,8 @@ struct mtk_reg_map {
- * the extra setup for those pins used by GMAC.
- * @hash_offset Flow table hash offset.
- * @foe_entry_size Foe table entry size.
-+ * @has_accounting Bool indicating support for accounting of
-+ * offloaded flows.
- * @txd_size Tx DMA descriptor size.
- * @rxd_size Rx DMA descriptor size.
- * @rx_irq_done_mask Rx irq done register mask.
-@@ -1025,6 +1027,7 @@ struct mtk_soc_data {
- u8 hash_offset;
- u16 foe_entry_size;
- netdev_features_t hw_features;
-+ bool has_accounting;
- struct {
- u32 txd_size;
- u32 rxd_size;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_
- return ret;
- }
-
-+static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
-+{
-+ int ret;
-+ u32 val;
-+
-+ ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
-+ !(val & MTK_PPE_MIB_SER_CR_ST),
-+ 20, MTK_PPE_WAIT_TIMEOUT_US);
-+
-+ if (ret)
-+ dev_err(ppe->dev, "MIB table busy");
-+
-+ return ret;
-+}
-+
-+static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
-+{
-+ u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
-+ u32 val, cnt_r0, cnt_r1, cnt_r2;
-+ int ret;
-+
-+ val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
-+ ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
-+
-+ ret = mtk_ppe_mib_wait_busy(ppe);
-+ if (ret)
-+ return ret;
-+
-+ cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
-+ cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-+ cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
-+
-+ byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-+ byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-+ pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-+ pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+
-+ return 0;
-+}
-+
- static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
- {
- ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
-@@ -465,6 +507,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
- dma_wmb();
- mtk_ppe_cache_clear(ppe);
-+ if (ppe->accounting) {
-+ struct mtk_foe_accounting *acct;
-+
-+ acct = ppe->acct_table + entry->hash * sizeof(*acct);
-+ acct->packets = 0;
-+ acct->bytes = 0;
-+ }
- }
- entry->hash = 0xffff;
-
-@@ -572,6 +621,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- wmb();
- hwe->ib1 = entry->ib1;
-
-+ if (ppe->accounting)
-+ *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+
- dma_wmb();
-
- mtk_ppe_cache_clear(ppe);
-@@ -763,11 +815,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
- return mtk_ppe_wait_busy(ppe);
- }
-
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-- int version, int index)
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+ struct mtk_foe_accounting *diff)
-+{
-+ struct mtk_foe_accounting *acct;
-+ int size = sizeof(struct mtk_foe_accounting);
-+ u64 bytes, packets;
-+
-+ if (!ppe->accounting)
-+ return NULL;
-+
-+ if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
-+ return NULL;
-+
-+ acct = ppe->acct_table + index * size;
-+
-+ acct->bytes += bytes;
-+ acct->packets += packets;
-+
-+ if (diff) {
-+ diff->bytes = bytes;
-+ diff->packets = packets;
-+ }
-+
-+ return acct;
-+}
-+
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
- {
-+ bool accounting = eth->soc->has_accounting;
- const struct mtk_soc_data *soc = eth->soc;
-+ struct mtk_foe_accounting *acct;
- struct device *dev = eth->dev;
-+ struct mtk_mib_entry *mib;
- struct mtk_ppe *ppe;
- u32 foe_flow_size;
- void *foe;
-@@ -784,7 +864,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- ppe->base = base;
- ppe->eth = eth;
- ppe->dev = dev;
-- ppe->version = version;
-+ ppe->version = eth->soc->offload_version;
-+ ppe->accounting = accounting;
-
- foe = dmam_alloc_coherent(ppe->dev,
- MTK_PPE_ENTRIES * soc->foe_entry_size,
-@@ -800,6 +881,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- if (!ppe->foe_flow)
- goto err_free_l2_flows;
-
-+ if (accounting) {
-+ mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
-+ &ppe->mib_phys, GFP_KERNEL);
-+ if (!mib)
-+ return NULL;
-+
-+ ppe->mib_table = mib;
-+
-+ acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
-+ GFP_KERNEL);
-+
-+ if (!acct)
-+ return NULL;
-+
-+ ppe->acct_table = acct;
-+ }
-+
- mtk_ppe_debugfs_init(ppe, index);
-
- return ppe;
-@@ -929,6 +1027,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
- ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
- }
-+
-+ if (ppe->accounting && ppe->mib_phys) {
-+ ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
-+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
-+ MTK_PPE_MIB_CFG_EN);
-+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
-+ MTK_PPE_MIB_CFG_RD_CLR);
-+ ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
-+ MTK_PPE_MIB_CFG_RD_CLR);
-+ }
- }
-
- int mtk_ppe_stop(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -57,6 +57,7 @@ enum {
- #define MTK_FOE_IB2_MULTICAST BIT(8)
-
- #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12)
-+#define MTK_FOE_IB2_MIB_CNT BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO BIT(17)
-
-@@ -285,16 +286,34 @@ struct mtk_flow_entry {
- unsigned long cookie;
- };
-
-+struct mtk_mib_entry {
-+ u32 byt_cnt_l;
-+ u16 byt_cnt_h;
-+ u32 pkt_cnt_l;
-+ u8 pkt_cnt_h;
-+ u8 _rsv0;
-+ u32 _rsv1;
-+} __packed;
-+
-+struct mtk_foe_accounting {
-+ u64 bytes;
-+ u64 packets;
-+};
-+
- struct mtk_ppe {
- struct mtk_eth *eth;
- struct device *dev;
- void __iomem *base;
- int version;
- char dirname[5];
-+ bool accounting;
-
- void *foe_table;
- dma_addr_t foe_phys;
-
-+ struct mtk_mib_entry *mib_table;
-+ dma_addr_t mib_phys;
-+
- u16 foe_check_time[MTK_PPE_ENTRIES];
- struct hlist_head *foe_flow;
-
-@@ -303,8 +322,7 @@ struct mtk_ppe {
- void *acct_table;
- };
-
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-- int version, int index);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
- void mtk_ppe_deinit(struct mtk_eth *eth);
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-@@ -359,5 +377,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+ struct mtk_foe_accounting *diff);
-
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
- struct mtk_foe_mac_info *l2;
- struct mtk_flow_addr_info ai = {};
-+ struct mtk_foe_accounting *acct;
- unsigned char h_source[ETH_ALEN];
- unsigned char h_dest[ETH_ALEN];
- int type, state;
-@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- if (bind && state != MTK_FOE_STATE_BIND)
- continue;
-
-+ acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-+
- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
- seq_printf(m, "%05x %s %7s", i,
- mtk_foe_entry_state_str(state),
-@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
-
- seq_printf(m, " eth=%pM->%pM etype=%04x"
-- " vlan=%d,%d ib1=%08x ib2=%08x\n",
-+ " vlan=%d,%d ib1=%08x ib2=%08x"
-+ " packets=%llu bytes=%llu\n",
- h_source, h_dest, ntohs(l2->etype),
-- l2->vlan1, l2->vlan2, entry->ib1, ib2);
-+ l2->vlan1, l2->vlan2, entry->ib1, ib2,
-+ acct ? acct->packets : 0, acct ? acct->bytes : 0);
- }
-
- return 0;
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -497,6 +497,7 @@ static int
- mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
- {
- struct mtk_flow_entry *entry;
-+ struct mtk_foe_accounting diff;
- u32 idle;
-
- entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
-@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e
- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
- f->stats.lastused = jiffies - idle * HZ;
-
-+ if (entry->hash != 0xFFFF &&
-+ mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
-+ &diff)) {
-+ f->stats.pkts += diff.packets;
-+ f->stats.bytes += diff.bytes;
-+ }
-+
- return 0;
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -149,6 +149,20 @@ enum {
-
- #define MTK_PPE_MIB_TB_BASE 0x338
-
-+#define MTK_PPE_MIB_SER_CR 0x33C
-+#define MTK_PPE_MIB_SER_CR_ST BIT(16)
-+#define MTK_PPE_MIB_SER_CR_ADDR GENMASK(13, 0)
-+
-+#define MTK_PPE_MIB_SER_R0 0x340
-+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW GENMASK(31, 0)
-+
-+#define MTK_PPE_MIB_SER_R1 0x344
-+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW GENMASK(31, 16)
-+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH GENMASK(15, 0)
-+
-+#define MTK_PPE_MIB_SER_R2 0x348
-+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0)
-+
- #define MTK_PPE_MIB_CACHE_CTL 0x350
- #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
- #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)
diff --git a/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
deleted file mode 100644
index 3a02c3a718..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 21:45:43 +0100
-Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for v1
- hardware
-
-Older chips (like MT7622) use a different bit in ib2 to enable hardware
-counter support.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -605,6 +605,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- struct mtk_eth *eth = ppe->eth;
- u16 timestamp = mtk_eth_timestamp(eth);
- struct mtk_foe_entry *hwe;
-+ u32 val;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-@@ -621,8 +622,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- wmb();
- hwe->ib1 = entry->ib1;
-
-- if (ppe->accounting)
-- *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+ if (ppe->accounting) {
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ val = MTK_FOE_IB2_MIB_CNT_V2;
-+ else
-+ val = MTK_FOE_IB2_MIB_CNT;
-+ *mtk_foe_entry_ib2(eth, hwe) |= val;
-+ }
-
- dma_wmb();
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -55,9 +55,10 @@ enum {
- #define MTK_FOE_IB2_PSE_QOS BIT(4)
- #define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5)
- #define MTK_FOE_IB2_MULTICAST BIT(8)
-+#define MTK_FOE_IB2_MIB_CNT BIT(10)
-
- #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12)
--#define MTK_FOE_IB2_MIB_CNT BIT(15)
-+#define MTK_FOE_IB2_MIB_CNT_V2 BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO BIT(17)
-
diff --git a/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
deleted file mode 100644
index 8be6a69921..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 20 Nov 2022 23:01:00 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload,
- only use DSA untagging
-
-Through testing I found out that hardware vlan rx offload support seems to
-have some hardware issues. At least when using multiple MACs and when receiving
-tagged packets on the secondary MAC, the hardware can sometimes start to emit
-wrong tags on the first MAC as well.
-
-In order to avoid such issues, drop the feature configuration and use the
-offload feature only for DSA hardware untagging on MT7621/MT7622 devices which
-only use one MAC.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1849,9 +1849,7 @@ static int mtk_poll_rx(struct napi_struc
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
-- bool has_hwaccel_tag = false;
- struct net_device *netdev;
-- u16 vlan_proto, vlan_tci;
- dma_addr_t dma_addr;
- u32 hash, reason;
- int mac = 0;
-@@ -1986,36 +1984,21 @@ static int mtk_poll_rx(struct napi_struc
- skb_checksum_none_assert(skb);
- skb->protocol = eth_type_trans(skb, netdev);
-
-- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-- mtk_ppe_check_skb(eth->ppe[0], skb, hash);
--
-- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- if (trxd.rxd3 & RX_DMA_VTAG_V2) {
-- vlan_proto = RX_DMA_VPID(trxd.rxd4);
-- vlan_tci = RX_DMA_VID(trxd.rxd4);
-- has_hwaccel_tag = true;
-- }
-- } else if (trxd.rxd2 & RX_DMA_VTAG) {
-- vlan_proto = RX_DMA_VPID(trxd.rxd3);
-- vlan_tci = RX_DMA_VID(trxd.rxd3);
-- has_hwaccel_tag = true;
-- }
-- }
--
- /* When using VLAN untagging in combination with DSA, the
- * hardware treats the MTK special tag as a VLAN and untags it.
- */
-- if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
-- unsigned int port = vlan_proto & GENMASK(2, 0);
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-+ (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-+ unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-
- if (port < ARRAY_SIZE(eth->dsa_meta) &&
- eth->dsa_meta[port])
- skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
-- } else if (has_hwaccel_tag) {
-- __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
- }
-
-+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-+ mtk_ppe_check_skb(eth->ppe[0], skb, hash);
-+
- skb_record_rx_queue(skb, 0);
- napi_gro_receive(napi, skb);
-
-@@ -2833,29 +2816,11 @@ static netdev_features_t mtk_fix_feature
-
- static int mtk_set_features(struct net_device *dev, netdev_features_t features)
- {
-- struct mtk_mac *mac = netdev_priv(dev);
-- struct mtk_eth *eth = mac->hw;
- netdev_features_t diff = dev->features ^ features;
-- int i;
-
- if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
- mtk_hwlro_netdev_disable(dev);
-
-- /* Set RX VLAN offloading */
-- if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
-- return 0;
--
-- mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
-- MTK_CDMP_EG_CTRL);
--
-- /* sync features with other MAC */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i] || eth->netdev[i] == dev)
-- continue;
-- eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
-- eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
-- }
--
- return 0;
- }
-
-@@ -3169,30 +3134,6 @@ static int mtk_open(struct net_device *d
- struct mtk_eth *eth = mac->hw;
- int i, err;
-
-- if (mtk_uses_dsa(dev) && !eth->prog) {
-- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-- struct metadata_dst *md_dst = eth->dsa_meta[i];
--
-- if (md_dst)
-- continue;
--
-- md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-- GFP_KERNEL);
-- if (!md_dst)
-- return -ENOMEM;
--
-- md_dst->u.port_info.port_id = i;
-- eth->dsa_meta[i] = md_dst;
-- }
-- } else {
-- /* Hardware special tag parsing needs to be disabled if at least
-- * one MAC does not use DSA.
-- */
-- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-- val &= ~MTK_CDMP_STAG_EN;
-- mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-- }
--
- err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
- if (err) {
- netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3233,6 +3174,35 @@ static int mtk_open(struct net_device *d
- phylink_start(mac->phylink);
- netif_tx_start_all_queues(dev);
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return 0;
-+
-+ if (mtk_uses_dsa(dev) && !eth->prog) {
-+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+ struct metadata_dst *md_dst = eth->dsa_meta[i];
-+
-+ if (md_dst)
-+ continue;
-+
-+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-+ GFP_KERNEL);
-+ if (!md_dst)
-+ return -ENOMEM;
-+
-+ md_dst->u.port_info.port_id = i;
-+ eth->dsa_meta[i] = md_dst;
-+ }
-+ } else {
-+ /* Hardware special tag parsing needs to be disabled if at least
-+ * one MAC does not use DSA.
-+ */
-+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+ val &= ~MTK_CDMP_STAG_EN;
-+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-+
-+ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
-+ }
-+
- return 0;
- }
-
-@@ -3717,10 +3687,9 @@ static int mtk_hw_init(struct mtk_eth *e
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
-- }
-
-- /* Enable RX VLan Offloading */
-- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+ }
-
- /* set interrupt delays based on current Net DIM sample */
- mtk_dim_rx(&eth->rx_dim.work);
-@@ -4360,7 +4329,7 @@ static int mtk_add_mac(struct mtk_eth *e
- eth->netdev[id]->hw_features |= NETIF_F_LRO;
-
- eth->netdev[id]->vlan_features = eth->soc->hw_features &
-- ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
-+ ~NETIF_F_HW_VLAN_CTAG_TX;
- eth->netdev[id]->features |= eth->soc->hw_features;
- eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -48,7 +48,6 @@
- #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
- NETIF_F_RXCSUM | \
- NETIF_F_HW_VLAN_CTAG_TX | \
-- NETIF_F_HW_VLAN_CTAG_RX | \
- NETIF_F_SG | NETIF_F_TSO | \
- NETIF_F_TSO6 | \
- NETIF_F_IPV6_CSUM |\
diff --git a/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch
deleted file mode 100644
index 2704faec12..0000000000
--- a/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 19 Jul 2023 01:39:36 +0100
-Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always
- mtk_get_ib1_pkt_type
-
-entries and bind debugfs files would display wrong data on NETSYS_V2 and
-later because instead of using mtk_get_ib1_pkt_type the driver would use
-MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs.
-Use mtk_get_ib1_pkt_type so entries and bind records display correctly.
-
-Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-
- acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-
-- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-+ type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
- seq_printf(m, "%05x %s %7s", i,
- mtk_foe_entry_state_str(state),
- mtk_foe_pkt_type_str(type));
diff --git a/target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch b/target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch
deleted file mode 100644
index 6788a2ec35..0000000000
--- a/target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From b5375509184dc23d2b7fa0c5ed8763899ccc9674 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 2 Oct 2021 19:58:11 +0200
-Subject: [PATCH] net: bgmac: improve handling PHY
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Use info from DT if available
-
-It allows describing for example a fixed link. It's more accurate than
-just guessing there may be one (depending on a chipset).
-
-2. Verify PHY ID before trying to connect PHY
-
-PHY addr 0x1e (30) is special in Broadcom routers and means a switch
-connected as MDIO devices instead of a real PHY. Don't try connecting to
-it.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac-bcma.c | 33 ++++++++++++++--------
- 1 file changed, 21 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -11,6 +11,7 @@
- #include <linux/bcma/bcma.h>
- #include <linux/brcmphy.h>
- #include <linux/etherdevice.h>
-+#include <linux/of_mdio.h>
- #include <linux/of_net.h>
- #include "bgmac.h"
-
-@@ -86,17 +87,28 @@ static int bcma_phy_connect(struct bgmac
- struct phy_device *phy_dev;
- char bus_id[MII_BUS_ID_SIZE + 3];
-
-+ /* DT info should be the most accurate */
-+ phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
-+ bgmac_adjust_link);
-+ if (phy_dev)
-+ return 0;
-+
- /* Connect to the PHY */
-- snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
-- bgmac->phyaddr);
-- phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
-- PHY_INTERFACE_MODE_MII);
-- if (IS_ERR(phy_dev)) {
-- dev_err(bgmac->dev, "PHY connection failed\n");
-- return PTR_ERR(phy_dev);
-+ if (bgmac->mii_bus && bgmac->phyaddr != BGMAC_PHY_NOREGS) {
-+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
-+ bgmac->phyaddr);
-+ phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
-+ PHY_INTERFACE_MODE_MII);
-+ if (IS_ERR(phy_dev)) {
-+ dev_err(bgmac->dev, "PHY connection failed\n");
-+ return PTR_ERR(phy_dev);
-+ }
-+
-+ return 0;
- }
-
-- return 0;
-+ /* Assume a fixed link to the switch port */
-+ return bgmac_phy_connect_direct(bgmac);
- }
-
- static const struct bcma_device_id bgmac_bcma_tbl[] = {
-@@ -297,10 +309,7 @@ static int bgmac_probe(struct bcma_devic
- bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
- bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
- bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
-- if (bgmac->mii_bus)
-- bgmac->phy_connect = bcma_phy_connect;
-- else
-- bgmac->phy_connect = bgmac_phy_connect_direct;
-+ bgmac->phy_connect = bcma_phy_connect;
-
- err = bgmac_enet_probe(bgmac);
- if (err)
diff --git a/target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch b/target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch
deleted file mode 100644
index f134828273..0000000000
--- a/target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 45c9d966688e7fad7f24bfc450547d91e4304d0b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 2 Oct 2021 19:58:12 +0200
-Subject: [PATCH] net: bgmac: support MDIO described in DT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Check ethernet controller DT node for "mdio" subnode and use it with
-of_mdiobus_register() when present. That allows specifying MDIO and its
-PHY devices in a standard DT based way.
-
-This is required for BCM53573 SoC support. That family is sometimes
-called Northstar (by marketing?) but is quite different from it. It uses
-different CPU(s) and many different hw blocks.
-
-One of shared blocks in BCM53573 is Ethernet controller. Switch however
-is not SRAB accessible (as it Northstar) but is MDIO attached.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
-@@ -10,6 +10,7 @@
-
- #include <linux/bcma/bcma.h>
- #include <linux/brcmphy.h>
-+#include <linux/of_mdio.h>
- #include "bgmac.h"
-
- static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask,
-@@ -211,6 +212,7 @@ struct mii_bus *bcma_mdio_mii_register(s
- {
- struct bcma_device *core = bgmac->bcma.core;
- struct mii_bus *mii_bus;
-+ struct device_node *np;
- int err;
-
- mii_bus = mdiobus_alloc();
-@@ -229,7 +231,9 @@ struct mii_bus *bcma_mdio_mii_register(s
- mii_bus->parent = &core->dev;
- mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
-
-- err = mdiobus_register(mii_bus);
-+ np = of_get_child_by_name(core->dev.of_node, "mdio");
-+
-+ err = of_mdiobus_register(mii_bus, np);
- if (err) {
- dev_err(&core->dev, "Registration of mii bus failed\n");
- goto err_free_bus;
diff --git a/target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch b/target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch
deleted file mode 100644
index 6090a40eae..0000000000
--- a/target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 12cf1b89a66828719b2135891b65bd5d03eedea9 Mon Sep 17 00:00:00 2001
-From: Bhadram Varka <vbhadram@nvidia.com>
-Date: Tue, 21 Jun 2022 09:10:27 +0530
-Subject: [PATCH] net: phy: Add support for AQR113C EPHY
-
-Add support multi-gigabit and single-port Ethernet
-PHY transceiver (AQR113C).
-
-Signed-off-by: Bhadram Varka <vbhadram@nvidia.com>
-Link: https://lore.kernel.org/r/20220621034027.56508-1-vbhadram@nvidia.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/aquantia_main.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/drivers/net/phy/aquantia_main.c
-+++ b/drivers/net/phy/aquantia_main.c
-@@ -22,6 +22,7 @@
- #define PHY_ID_AQR107 0x03a1b4e0
- #define PHY_ID_AQCS109 0x03a1b5c2
- #define PHY_ID_AQR405 0x03a1b4b0
-+#define PHY_ID_AQR113C 0x31c31c12
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -744,6 +745,24 @@ static struct phy_driver aqr_driver[] =
- .handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr_read_status,
- },
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
-+ .name = "Aquantia AQR113C",
-+ .probe = aqr107_probe,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
- };
-
- module_phy_driver(aqr_driver);
-@@ -756,6 +775,7 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
- { }
- };
-
diff --git a/target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch b/target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch
deleted file mode 100644
index ec8485e0a7..0000000000
--- a/target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 7de26bf144f6a72858ab60afb2bd2b43265ee0ad Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Tue, 20 Sep 2022 18:12:34 -0400
-Subject: [PATCH] net: phy: aquantia: Add some additional phy interfaces
-
-These are documented in the AQR115 register reference. I haven't tested
-them, but perhaps they'll be useful to someone.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia_main.c | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/aquantia_main.c
-+++ b/drivers/net/phy/aquantia_main.c
-@@ -27,9 +27,12 @@
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
-
- #define MDIO_AN_VEND_PROV 0xc400
-@@ -401,15 +404,24 @@ static int aqr107_read_status(struct phy
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
- phydev->interface = PHY_INTERFACE_MODE_10GKR;
- break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:
-+ phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;
-+ break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
- phydev->interface = PHY_INTERFACE_MODE_10GBASER;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
- phydev->interface = PHY_INTERFACE_MODE_USXGMII;
- break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:
-+ phydev->interface = PHY_INTERFACE_MODE_XAUI;
-+ break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
- phydev->interface = PHY_INTERFACE_MODE_SGMII;
- break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:
-+ phydev->interface = PHY_INTERFACE_MODE_RXAUI;
-+ break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
- break;
-@@ -522,11 +534,14 @@ static int aqr107_config_init(struct phy
-
- /* Check that the PHY interface type is compatible */
- if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_1000BASEKX &&
- phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
- phydev->interface != PHY_INTERFACE_MODE_XGMII &&
- phydev->interface != PHY_INTERFACE_MODE_USXGMII &&
- phydev->interface != PHY_INTERFACE_MODE_10GKR &&
-- phydev->interface != PHY_INTERFACE_MODE_10GBASER)
-+ phydev->interface != PHY_INTERFACE_MODE_10GBASER &&
-+ phydev->interface != PHY_INTERFACE_MODE_XAUI &&
-+ phydev->interface != PHY_INTERFACE_MODE_RXAUI)
- return -ENODEV;
-
- WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
diff --git a/target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch b/target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch
deleted file mode 100644
index d5d58762ce..0000000000
--- a/target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 3c42563b30417afc8855a3b4c1b38c2f36f78657 Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Tue, 20 Sep 2022 18:12:35 -0400
-Subject: [PATCH] net: phy: aquantia: Add support for rate matching
-
-This adds support for rate matching for phys similar to the AQR107. We
-assume that all phys using aqr107_read_status support rate matching.
-However, it could be possible to determine support based on the firmware
-revision if there are phys discovered which do not support rate
-matching. However, as rate matching is advertised in the datasheets for
-these phys, I suspect it is supported most boards.
-
-Despite the name, the "config" registers are updated with the current
-rate matching method (if any). Because they appear to be updated
-automatically, I don't know if these registers can be used to disable
-rate matching.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia_main.c | 51 ++++++++++++++++++++++++++++++---
- 1 file changed, 47 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/aquantia_main.c
-+++ b/drivers/net/phy/aquantia_main.c
-@@ -97,6 +97,19 @@
- #define VEND1_GLOBAL_GEN_STAT2 0xc831
- #define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
-
-+/* The following registers all have similar layouts; first the registers... */
-+#define VEND1_GLOBAL_CFG_10M 0x0310
-+#define VEND1_GLOBAL_CFG_100M 0x031b
-+#define VEND1_GLOBAL_CFG_1G 0x031c
-+#define VEND1_GLOBAL_CFG_2_5G 0x031d
-+#define VEND1_GLOBAL_CFG_5G 0x031e
-+#define VEND1_GLOBAL_CFG_10G 0x031f
-+/* ...and now the fields */
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-+
- #define VEND1_GLOBAL_RSVD_STAT1 0xc885
- #define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
- #define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
-@@ -347,40 +360,57 @@ static int aqr_read_status(struct phy_de
-
- static int aqr107_read_rate(struct phy_device *phydev)
- {
-+ u32 config_reg;
- int val;
-
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
- if (val < 0)
- return val;
-
-+ if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
-+ phydev->duplex = DUPLEX_FULL;
-+ else
-+ phydev->duplex = DUPLEX_HALF;
-+
- switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
- case MDIO_AN_TX_VEND_STATUS1_10BASET:
- phydev->speed = SPEED_10;
-+ config_reg = VEND1_GLOBAL_CFG_10M;
- break;
- case MDIO_AN_TX_VEND_STATUS1_100BASETX:
- phydev->speed = SPEED_100;
-+ config_reg = VEND1_GLOBAL_CFG_100M;
- break;
- case MDIO_AN_TX_VEND_STATUS1_1000BASET:
- phydev->speed = SPEED_1000;
-+ config_reg = VEND1_GLOBAL_CFG_1G;
- break;
- case MDIO_AN_TX_VEND_STATUS1_2500BASET:
- phydev->speed = SPEED_2500;
-+ config_reg = VEND1_GLOBAL_CFG_2_5G;
- break;
- case MDIO_AN_TX_VEND_STATUS1_5000BASET:
- phydev->speed = SPEED_5000;
-+ config_reg = VEND1_GLOBAL_CFG_5G;
- break;
- case MDIO_AN_TX_VEND_STATUS1_10GBASET:
- phydev->speed = SPEED_10000;
-+ config_reg = VEND1_GLOBAL_CFG_10G;
- break;
- default:
- phydev->speed = SPEED_UNKNOWN;
-- break;
-+ return 0;
- }
-
-- if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
-- phydev->duplex = DUPLEX_FULL;
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);
-+ if (val < 0)
-+ return val;
-+
-+ if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==
-+ VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)
-+ phydev->rate_matching = RATE_MATCH_PAUSE;
- else
-- phydev->duplex = DUPLEX_HALF;
-+ phydev->rate_matching = RATE_MATCH_NONE;
-
- return 0;
- }
-@@ -647,6 +677,16 @@ static int aqr107_wait_processor_intensi
- return 0;
- }
-
-+static int aqr107_get_rate_matching(struct phy_device *phydev,
-+ phy_interface_t iface)
-+{
-+ if (iface == PHY_INTERFACE_MODE_10GBASER ||
-+ iface == PHY_INTERFACE_MODE_2500BASEX ||
-+ iface == PHY_INTERFACE_MODE_NA)
-+ return RATE_MATCH_PAUSE;
-+ return RATE_MATCH_NONE;
-+}
-+
- static int aqr107_suspend(struct phy_device *phydev)
- {
- int err;
-@@ -720,6 +760,7 @@ static struct phy_driver aqr_driver[] =
- PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
- .name = "Aquantia AQR107",
- .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqr107_config_init,
- .config_aneg = aqr_config_aneg,
- .config_intr = aqr_config_intr,
-@@ -738,6 +779,7 @@ static struct phy_driver aqr_driver[] =
- PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
- .name = "Aquantia AQCS109",
- .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqcs109_config_init,
- .config_aneg = aqr_config_aneg,
- .config_intr = aqr_config_intr,
-@@ -764,6 +806,7 @@ static struct phy_driver aqr_driver[] =
- PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
- .name = "Aquantia AQR113C",
- .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqr107_config_init,
- .config_aneg = aqr_config_aneg,
- .config_intr = aqr_config_intr,
diff --git a/target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch b/target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch
deleted file mode 100644
index 4bb786e790..0000000000
--- a/target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch
+++ /dev/null
@@ -1,2310 +0,0 @@
-From d2213db3f49bce8e7a87c8de05b9a091f78f654e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 14 Nov 2023 15:08:41 +0100
-Subject: [PATCH 1/3] net: phy: aquantia: move to separate directory
-
-Move aquantia PHY driver to separate driectory in preparation for
-firmware loading support to keep things tidy.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 5 +----
- drivers/net/phy/Makefile | 6 +-----
- drivers/net/phy/aquantia/Kconfig | 5 +++++
- drivers/net/phy/aquantia/Makefile | 6 ++++++
- drivers/net/phy/{ => aquantia}/aquantia.h | 0
- drivers/net/phy/{ => aquantia}/aquantia_hwmon.c | 0
- drivers/net/phy/{ => aquantia}/aquantia_main.c | 0
- 7 files changed, 13 insertions(+), 9 deletions(-)
- create mode 100644 drivers/net/phy/aquantia/Kconfig
- create mode 100644 drivers/net/phy/aquantia/Makefile
- rename drivers/net/phy/{ => aquantia}/aquantia.h (100%)
- rename drivers/net/phy/{ => aquantia}/aquantia_hwmon.c (100%)
- rename drivers/net/phy/{ => aquantia}/aquantia_main.c (100%)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -83,10 +83,7 @@ config ADIN_PHY
- - ADIN1300 - Robust,Industrial, Low Latency 10/100/1000 Gigabit
- Ethernet PHY
-
--config AQUANTIA_PHY
-- tristate "Aquantia PHYs"
-- help
-- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
-+source "drivers/net/phy/aquantia/Kconfig"
-
- config AX88796B_PHY
- tristate "Asix PHYs"
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -32,11 +32,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
-
- obj-$(CONFIG_ADIN_PHY) += adin.o
- obj-$(CONFIG_AMD_PHY) += amd.o
--aquantia-objs += aquantia_main.o
--ifdef CONFIG_HWMON
--aquantia-objs += aquantia_hwmon.o
--endif
--obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
-+obj-$(CONFIG_AQUANTIA_PHY) += aquantia/
- obj-$(CONFIG_AT803X_PHY) += at803x.o
- obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
- obj-$(CONFIG_BCM54140_PHY) += bcm54140.o
---- /dev/null
-+++ b/drivers/net/phy/aquantia/Kconfig
-@@ -0,0 +1,5 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+config AQUANTIA_PHY
-+ tristate "Aquantia PHYs"
-+ help
-+ Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
---- /dev/null
-+++ b/drivers/net/phy/aquantia/Makefile
-@@ -0,0 +1,6 @@
-+# SPDX-License-Identifier: GPL-2.0
-+aquantia-objs += aquantia_main.o
-+ifdef CONFIG_HWMON
-+aquantia-objs += aquantia_hwmon.o
-+endif
-+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
---- a/drivers/net/phy/aquantia.h
-+++ /dev/null
-@@ -1,16 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 */
--/* HWMON driver for Aquantia PHY
-- *
-- * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-- * Author: Andrew Lunn <andrew@lunn.ch>
-- * Author: Heiner Kallweit <hkallweit1@gmail.com>
-- */
--
--#include <linux/device.h>
--#include <linux/phy.h>
--
--#if IS_REACHABLE(CONFIG_HWMON)
--int aqr_hwmon_probe(struct phy_device *phydev);
--#else
--static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
--#endif
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia.h
-@@ -0,0 +1,16 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/* HWMON driver for Aquantia PHY
-+ *
-+ * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-+ * Author: Andrew Lunn <andrew@lunn.ch>
-+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/phy.h>
-+
-+#if IS_REACHABLE(CONFIG_HWMON)
-+int aqr_hwmon_probe(struct phy_device *phydev);
-+#else
-+static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
-+#endif
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c
-@@ -0,0 +1,250 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/* HWMON driver for Aquantia PHY
-+ *
-+ * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-+ * Author: Andrew Lunn <andrew@lunn.ch>
-+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
-+ */
-+
-+#include <linux/phy.h>
-+#include <linux/device.h>
-+#include <linux/ctype.h>
-+#include <linux/hwmon.h>
-+
-+#include "aquantia.h"
-+
-+/* Vendor specific 1, MDIO_MMD_VEND2 */
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
-+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
-+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
-+#define VEND1_THERMAL_STAT1 0xc820
-+#define VEND1_THERMAL_STAT2 0xc821
-+#define VEND1_THERMAL_STAT2_VALID BIT(0)
-+#define VEND1_GENERAL_STAT1 0xc830
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
-+
-+#if IS_REACHABLE(CONFIG_HWMON)
-+
-+static umode_t aqr_hwmon_is_visible(const void *data,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel)
-+{
-+ if (type != hwmon_temp)
-+ return 0;
-+
-+ switch (attr) {
-+ case hwmon_temp_input:
-+ case hwmon_temp_min_alarm:
-+ case hwmon_temp_max_alarm:
-+ case hwmon_temp_lcrit_alarm:
-+ case hwmon_temp_crit_alarm:
-+ return 0444;
-+ case hwmon_temp_min:
-+ case hwmon_temp_max:
-+ case hwmon_temp_lcrit:
-+ case hwmon_temp_crit:
-+ return 0644;
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
-+{
-+ int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
-+
-+ if (temp < 0)
-+ return temp;
-+
-+ /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */
-+ *value = (s16)temp * 1000 / 256;
-+
-+ return 0;
-+}
-+
-+static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
-+{
-+ int temp;
-+
-+ if (value >= 128000 || value < -128000)
-+ return -ERANGE;
-+
-+ temp = value * 256 / 1000;
-+
-+ /* temp is in s16 range and we're interested in lower 16 bits only */
-+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp);
-+}
-+
-+static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit)
-+{
-+ int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
-+
-+ if (val < 0)
-+ return val;
-+
-+ return !!(val & bit);
-+}
-+
-+static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
-+{
-+ int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit);
-+
-+ if (val < 0)
-+ return val;
-+
-+ *value = val;
-+
-+ return 0;
-+}
-+
-+static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *value)
-+{
-+ struct phy_device *phydev = dev_get_drvdata(dev);
-+ int reg;
-+
-+ if (type != hwmon_temp)
-+ return -EOPNOTSUPP;
-+
-+ switch (attr) {
-+ case hwmon_temp_input:
-+ reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2,
-+ VEND1_THERMAL_STAT2_VALID);
-+ if (reg < 0)
-+ return reg;
-+ if (!reg)
-+ return -EBUSY;
-+
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
-+
-+ case hwmon_temp_lcrit:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_min:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-+ value);
-+ case hwmon_temp_max:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-+ value);
-+ case hwmon_temp_crit:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_lcrit_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_LOW_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_min_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_LOW_TEMP_WARN,
-+ value);
-+ case hwmon_temp_max_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_HIGH_TEMP_WARN,
-+ value);
-+ case hwmon_temp_crit_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL,
-+ value);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long value)
-+{
-+ struct phy_device *phydev = dev_get_drvdata(dev);
-+
-+ if (type != hwmon_temp)
-+ return -EOPNOTSUPP;
-+
-+ switch (attr) {
-+ case hwmon_temp_lcrit:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_min:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-+ value);
-+ case hwmon_temp_max:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-+ value);
-+ case hwmon_temp_crit:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-+ value);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static const struct hwmon_ops aqr_hwmon_ops = {
-+ .is_visible = aqr_hwmon_is_visible,
-+ .read = aqr_hwmon_read,
-+ .write = aqr_hwmon_write,
-+};
-+
-+static u32 aqr_hwmon_chip_config[] = {
-+ HWMON_C_REGISTER_TZ,
-+ 0,
-+};
-+
-+static const struct hwmon_channel_info aqr_hwmon_chip = {
-+ .type = hwmon_chip,
-+ .config = aqr_hwmon_chip_config,
-+};
-+
-+static u32 aqr_hwmon_temp_config[] = {
-+ HWMON_T_INPUT |
-+ HWMON_T_MAX | HWMON_T_MIN |
-+ HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM |
-+ HWMON_T_CRIT | HWMON_T_LCRIT |
-+ HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM,
-+ 0,
-+};
-+
-+static const struct hwmon_channel_info aqr_hwmon_temp = {
-+ .type = hwmon_temp,
-+ .config = aqr_hwmon_temp_config,
-+};
-+
-+static const struct hwmon_channel_info *aqr_hwmon_info[] = {
-+ &aqr_hwmon_chip,
-+ &aqr_hwmon_temp,
-+ NULL,
-+};
-+
-+static const struct hwmon_chip_info aqr_hwmon_chip_info = {
-+ .ops = &aqr_hwmon_ops,
-+ .info = aqr_hwmon_info,
-+};
-+
-+int aqr_hwmon_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct device *hwmon_dev;
-+ char *hwmon_name;
-+ int i, j;
-+
-+ hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
-+ if (!hwmon_name)
-+ return -ENOMEM;
-+
-+ for (i = j = 0; hwmon_name[i]; i++) {
-+ if (isalnum(hwmon_name[i])) {
-+ if (i != j)
-+ hwmon_name[j] = hwmon_name[i];
-+ j++;
-+ }
-+ }
-+ hwmon_name[j] = '\0';
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name,
-+ phydev, &aqr_hwmon_chip_info, NULL);
-+
-+ return PTR_ERR_OR_ZERO(hwmon_dev);
-+}
-+
-+#endif
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -0,0 +1,844 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Driver for Aquantia PHY
-+ *
-+ * Author: Shaohui Xie <Shaohui.Xie@freescale.com>
-+ *
-+ * Copyright 2015 Freescale Semiconductor, Inc.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/bitfield.h>
-+#include <linux/phy.h>
-+
-+#include "aquantia.h"
-+
-+#define PHY_ID_AQ1202 0x03a1b445
-+#define PHY_ID_AQ2104 0x03a1b460
-+#define PHY_ID_AQR105 0x03a1b4a2
-+#define PHY_ID_AQR106 0x03a1b4d0
-+#define PHY_ID_AQR107 0x03a1b4e0
-+#define PHY_ID_AQCS109 0x03a1b5c2
-+#define PHY_ID_AQR405 0x03a1b4b0
-+#define PHY_ID_AQR113C 0x31c31c12
-+
-+#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
-+
-+#define MDIO_AN_VEND_PROV 0xc400
-+#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15)
-+#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)
-+#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11)
-+#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
-+#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
-+#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
-+#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
-+
-+#define MDIO_AN_TX_VEND_STATUS1 0xc800
-+#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1)
-+#define MDIO_AN_TX_VEND_STATUS1_10BASET 0
-+#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1
-+#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2
-+#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3
-+#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4
-+#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5
-+#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0)
-+
-+#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00
-+#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1)
-+
-+#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01
-+#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0)
-+
-+#define MDIO_AN_TX_VEND_INT_MASK2 0xd401
-+#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0)
-+
-+#define MDIO_AN_RX_LP_STAT1 0xe820
-+#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15)
-+#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14)
-+#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13)
-+#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12)
-+#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2)
-+
-+#define MDIO_AN_RX_LP_STAT4 0xe823
-+#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8)
-+#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0)
-+
-+#define MDIO_AN_RX_VEND_STAT3 0xe832
-+#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
-+
-+/* MDIO_MMD_C22EXT */
-+#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292
-+#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294
-+#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297
-+#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313
-+#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315
-+#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317
-+#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318
-+#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319
-+#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
-+#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
-+
-+/* Vendor specific 1, MDIO_MMD_VEND1 */
-+#define VEND1_GLOBAL_FW_ID 0x0020
-+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
-+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
-+
-+#define VEND1_GLOBAL_GEN_STAT2 0xc831
-+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
-+
-+/* The following registers all have similar layouts; first the registers... */
-+#define VEND1_GLOBAL_CFG_10M 0x0310
-+#define VEND1_GLOBAL_CFG_100M 0x031b
-+#define VEND1_GLOBAL_CFG_1G 0x031c
-+#define VEND1_GLOBAL_CFG_2_5G 0x031d
-+#define VEND1_GLOBAL_CFG_5G 0x031e
-+#define VEND1_GLOBAL_CFG_10G 0x031f
-+/* ...and now the fields */
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-+
-+#define VEND1_GLOBAL_RSVD_STAT1 0xc885
-+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
-+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
-+
-+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
-+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
-+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
-+
-+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
-+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
-+
-+#define VEND1_GLOBAL_INT_STD_MASK 0xff00
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
-+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
-+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
-+
-+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
-+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
-+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
-+
-+/* Sleep and timeout for checking if the Processor-Intensive
-+ * MDIO operation is finished
-+ */
-+#define AQR107_OP_IN_PROG_SLEEP 1000
-+#define AQR107_OP_IN_PROG_TIMEOUT 100000
-+
-+struct aqr107_hw_stat {
-+ const char *name;
-+ int reg;
-+ int size;
-+};
-+
-+#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
-+static const struct aqr107_hw_stat aqr107_hw_stats[] = {
-+ SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26),
-+ SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26),
-+ SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8),
-+ SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26),
-+ SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26),
-+ SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8),
-+ SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8),
-+ SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8),
-+ SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16),
-+ SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22),
-+};
-+#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
-+
-+struct aqr107_priv {
-+ u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
-+};
-+
-+static int aqr107_get_sset_count(struct phy_device *phydev)
-+{
-+ return AQR107_SGMII_STAT_SZ;
-+}
-+
-+static void aqr107_get_strings(struct phy_device *phydev, u8 *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++)
-+ strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name,
-+ ETH_GSTRING_LEN);
-+}
-+
-+static u64 aqr107_get_stat(struct phy_device *phydev, int index)
-+{
-+ const struct aqr107_hw_stat *stat = aqr107_hw_stats + index;
-+ int len_l = min(stat->size, 16);
-+ int len_h = stat->size - len_l;
-+ u64 ret;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg);
-+ if (val < 0)
-+ return U64_MAX;
-+
-+ ret = val & GENMASK(len_l - 1, 0);
-+ if (len_h) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1);
-+ if (val < 0)
-+ return U64_MAX;
-+
-+ ret += (val & GENMASK(len_h - 1, 0)) << 16;
-+ }
-+
-+ return ret;
-+}
-+
-+static void aqr107_get_stats(struct phy_device *phydev,
-+ struct ethtool_stats *stats, u64 *data)
-+{
-+ struct aqr107_priv *priv = phydev->priv;
-+ u64 val;
-+ int i;
-+
-+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) {
-+ val = aqr107_get_stat(phydev, i);
-+ if (val == U64_MAX)
-+ phydev_err(phydev, "Reading HW Statistics failed for %s\n",
-+ aqr107_hw_stats[i].name);
-+ else
-+ priv->sgmii_stats[i] += val;
-+
-+ data[i] = priv->sgmii_stats[i];
-+ }
-+}
-+
-+static int aqr_config_aneg(struct phy_device *phydev)
-+{
-+ bool changed = false;
-+ u16 reg;
-+ int ret;
-+
-+ if (phydev->autoneg == AUTONEG_DISABLE)
-+ return genphy_c45_pma_setup_forced(phydev);
-+
-+ ret = genphy_c45_an_config_aneg(phydev);
-+ if (ret < 0)
-+ return ret;
-+ if (ret > 0)
-+ changed = true;
-+
-+ /* Clause 45 has no standardized support for 1000BaseT, therefore
-+ * use vendor registers for this mode.
-+ */
-+ reg = 0;
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
-+
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
-+
-+ /* Handle the case when the 2.5G and 5G speeds are not advertised */
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;
-+
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;
-+
-+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-+ MDIO_AN_VEND_PROV_1000BASET_HALF |
-+ MDIO_AN_VEND_PROV_1000BASET_FULL |
-+ MDIO_AN_VEND_PROV_2500BASET_FULL |
-+ MDIO_AN_VEND_PROV_5000BASET_FULL, reg);
-+ if (ret < 0)
-+ return ret;
-+ if (ret > 0)
-+ changed = true;
-+
-+ return genphy_c45_check_and_restart_aneg(phydev, changed);
-+}
-+
-+static int aqr_config_intr(struct phy_device *phydev)
-+{
-+ bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
-+ int err;
-+
-+ if (en) {
-+ /* Clear any pending interrupts before enabling them */
-+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-+ if (err < 0)
-+ return err;
-+ }
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,
-+ en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);
-+ if (err < 0)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,
-+ en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);
-+ if (err < 0)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
-+ en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
-+ VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
-+ if (err < 0)
-+ return err;
-+
-+ if (!en) {
-+ /* Clear any pending interrupts after we have disabled them */
-+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-+ if (err < 0)
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
-+{
-+ int irq_status;
-+
-+ irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,
-+ MDIO_AN_TX_VEND_INT_STATUS2);
-+ if (irq_status < 0) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))
-+ return IRQ_NONE;
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int aqr_read_status(struct phy_device *phydev)
-+{
-+ int val;
-+
-+ if (phydev->autoneg == AUTONEG_ENABLE) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-+ if (val < 0)
-+ return val;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-+ phydev->lp_advertising,
-+ val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-+ phydev->lp_advertising,
-+ val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);
-+ }
-+
-+ return genphy_c45_read_status(phydev);
-+}
-+
-+static int aqr107_read_rate(struct phy_device *phydev)
-+{
-+ u32 config_reg;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
-+ if (val < 0)
-+ return val;
-+
-+ if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
-+ phydev->duplex = DUPLEX_FULL;
-+ else
-+ phydev->duplex = DUPLEX_HALF;
-+
-+ switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
-+ case MDIO_AN_TX_VEND_STATUS1_10BASET:
-+ phydev->speed = SPEED_10;
-+ config_reg = VEND1_GLOBAL_CFG_10M;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_100BASETX:
-+ phydev->speed = SPEED_100;
-+ config_reg = VEND1_GLOBAL_CFG_100M;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_1000BASET:
-+ phydev->speed = SPEED_1000;
-+ config_reg = VEND1_GLOBAL_CFG_1G;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_2500BASET:
-+ phydev->speed = SPEED_2500;
-+ config_reg = VEND1_GLOBAL_CFG_2_5G;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_5000BASET:
-+ phydev->speed = SPEED_5000;
-+ config_reg = VEND1_GLOBAL_CFG_5G;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_10GBASET:
-+ phydev->speed = SPEED_10000;
-+ config_reg = VEND1_GLOBAL_CFG_10G;
-+ break;
-+ default:
-+ phydev->speed = SPEED_UNKNOWN;
-+ return 0;
-+ }
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);
-+ if (val < 0)
-+ return val;
-+
-+ if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==
-+ VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)
-+ phydev->rate_matching = RATE_MATCH_PAUSE;
-+ else
-+ phydev->rate_matching = RATE_MATCH_NONE;
-+
-+ return 0;
-+}
-+
-+static int aqr107_read_status(struct phy_device *phydev)
-+{
-+ int val, ret;
-+
-+ ret = aqr_read_status(phydev);
-+ if (ret)
-+ return ret;
-+
-+ if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
-+ return 0;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
-+ if (val < 0)
-+ return val;
-+
-+ switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
-+ phydev->interface = PHY_INTERFACE_MODE_10GKR;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:
-+ phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
-+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
-+ phydev->interface = PHY_INTERFACE_MODE_USXGMII;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:
-+ phydev->interface = PHY_INTERFACE_MODE_XAUI;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:
-+ phydev->interface = PHY_INTERFACE_MODE_RXAUI;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ break;
-+ default:
-+ phydev->interface = PHY_INTERFACE_MODE_NA;
-+ break;
-+ }
-+
-+ /* Read possibly downshifted rate from vendor register */
-+ return aqr107_read_rate(phydev);
-+}
-+
-+static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
-+{
-+ int val, cnt, enable;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);
-+ if (val < 0)
-+ return val;
-+
-+ enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);
-+ cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
-+
-+ *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;
-+
-+ return 0;
-+}
-+
-+static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
-+{
-+ int val = 0;
-+
-+ if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))
-+ return -E2BIG;
-+
-+ if (cnt != DOWNSHIFT_DEV_DISABLE) {
-+ val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;
-+ val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);
-+ }
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-+ MDIO_AN_VEND_PROV_DOWNSHIFT_EN |
-+ MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
-+}
-+
-+static int aqr107_get_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return aqr107_get_downshift(phydev, data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int aqr107_set_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, const void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return aqr107_set_downshift(phydev, *(const u8 *)data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+/* If we configure settings whilst firmware is still initializing the chip,
-+ * then these settings may be overwritten. Therefore make sure chip
-+ * initialization has completed. Use presence of the firmware ID as
-+ * indicator for initialization having completed.
-+ * The chip also provides a "reset completed" bit, but it's cleared after
-+ * read. Therefore function would time out if called again.
-+ */
-+static int aqr107_wait_reset_complete(struct phy_device *phydev)
-+{
-+ int val;
-+
-+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_FW_ID, val, val != 0,
-+ 20000, 2000000, false);
-+}
-+
-+static void aqr107_chip_info(struct phy_device *phydev)
-+{
-+ u8 fw_major, fw_minor, build_id, prov_id;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
-+ if (val < 0)
-+ return;
-+
-+ fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val);
-+ fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1);
-+ if (val < 0)
-+ return;
-+
-+ build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
-+ prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
-+
-+ phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
-+ fw_major, fw_minor, build_id, prov_id);
-+}
-+
-+static int aqr107_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Check that the PHY interface type is compatible */
-+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_1000BASEKX &&
-+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
-+ phydev->interface != PHY_INTERFACE_MODE_XGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_USXGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_10GKR &&
-+ phydev->interface != PHY_INTERFACE_MODE_10GBASER &&
-+ phydev->interface != PHY_INTERFACE_MODE_XAUI &&
-+ phydev->interface != PHY_INTERFACE_MODE_RXAUI)
-+ return -ENODEV;
-+
-+ WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
-+ "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");
-+
-+ ret = aqr107_wait_reset_complete(phydev);
-+ if (!ret)
-+ aqr107_chip_info(phydev);
-+
-+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
-+}
-+
-+static int aqcs109_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Check that the PHY interface type is compatible */
-+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
-+ return -ENODEV;
-+
-+ ret = aqr107_wait_reset_complete(phydev);
-+ if (!ret)
-+ aqr107_chip_info(phydev);
-+
-+ /* AQCS109 belongs to a chip family partially supporting 10G and 5G.
-+ * PMA speed ability bits are the same for all members of the family,
-+ * AQCS109 however supports speeds up to 2.5G only.
-+ */
-+ ret = phy_set_max_speed(phydev, SPEED_2500);
-+ if (ret)
-+ return ret;
-+
-+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
-+}
-+
-+static void aqr107_link_change_notify(struct phy_device *phydev)
-+{
-+ u8 fw_major, fw_minor;
-+ bool downshift, short_reach, afr;
-+ int mode, val;
-+
-+ if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE)
-+ return;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-+ /* call failed or link partner is no Aquantia PHY */
-+ if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY))
-+ return;
-+
-+ short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH;
-+ downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4);
-+ if (val < 0)
-+ return;
-+
-+ fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val);
-+ fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3);
-+ if (val < 0)
-+ return;
-+
-+ afr = val & MDIO_AN_RX_VEND_STAT3_AFR;
-+
-+ phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n",
-+ fw_major, fw_minor,
-+ short_reach ? ", short reach mode" : "",
-+ downshift ? ", fast-retrain downshift advertised" : "",
-+ afr ? ", fast reframe advertised" : "");
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9);
-+ if (val < 0)
-+ return;
-+
-+ mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val);
-+ if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2)
-+ phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
-+}
-+
-+static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
-+{
-+ int val, err;
-+
-+ /* The datasheet notes to wait at least 1ms after issuing a
-+ * processor intensive operation before checking.
-+ * We cannot use the 'sleep_before_read' parameter of read_poll_timeout
-+ * because that just determines the maximum time slept, not the minimum.
-+ */
-+ usleep_range(1000, 5000);
-+
-+ err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_GEN_STAT2, val,
-+ !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
-+ AQR107_OP_IN_PROG_SLEEP,
-+ AQR107_OP_IN_PROG_TIMEOUT, false);
-+ if (err) {
-+ phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+static int aqr107_get_rate_matching(struct phy_device *phydev,
-+ phy_interface_t iface)
-+{
-+ if (iface == PHY_INTERFACE_MODE_10GBASER ||
-+ iface == PHY_INTERFACE_MODE_2500BASEX ||
-+ iface == PHY_INTERFACE_MODE_NA)
-+ return RATE_MATCH_PAUSE;
-+ return RATE_MATCH_NONE;
-+}
-+
-+static int aqr107_suspend(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-+ MDIO_CTRL1_LPOWER);
-+ if (err)
-+ return err;
-+
-+ return aqr107_wait_processor_intensive_op(phydev);
-+}
-+
-+static int aqr107_resume(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-+ MDIO_CTRL1_LPOWER);
-+ if (err)
-+ return err;
-+
-+ return aqr107_wait_processor_intensive_op(phydev);
-+}
-+
-+static int aqr107_probe(struct phy_device *phydev)
-+{
-+ phydev->priv = devm_kzalloc(&phydev->mdio.dev,
-+ sizeof(struct aqr107_priv), GFP_KERNEL);
-+ if (!phydev->priv)
-+ return -ENOMEM;
-+
-+ return aqr_hwmon_probe(phydev);
-+}
-+
-+static struct phy_driver aqr_driver[] = {
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
-+ .name = "Aquantia AQ1202",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),
-+ .name = "Aquantia AQ2104",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
-+ .name = "Aquantia AQR105",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
-+ .name = "Aquantia AQR106",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
-+ .name = "Aquantia AQR107",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
-+ .name = "Aquantia AQCS109",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqcs109_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
-+ .name = "Aquantia AQR405",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
-+ .name = "Aquantia AQR113C",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+};
-+
-+module_phy_driver(aqr_driver);
-+
-+static struct mdio_device_id __maybe_unused aqr_tbl[] = {
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, aqr_tbl);
-+
-+MODULE_DESCRIPTION("Aquantia PHY driver");
-+MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/phy/aquantia_hwmon.c
-+++ /dev/null
-@@ -1,250 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/* HWMON driver for Aquantia PHY
-- *
-- * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-- * Author: Andrew Lunn <andrew@lunn.ch>
-- * Author: Heiner Kallweit <hkallweit1@gmail.com>
-- */
--
--#include <linux/phy.h>
--#include <linux/device.h>
--#include <linux/ctype.h>
--#include <linux/hwmon.h>
--
--#include "aquantia.h"
--
--/* Vendor specific 1, MDIO_MMD_VEND2 */
--#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
--#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
--#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
--#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
--#define VEND1_THERMAL_STAT1 0xc820
--#define VEND1_THERMAL_STAT2 0xc821
--#define VEND1_THERMAL_STAT2_VALID BIT(0)
--#define VEND1_GENERAL_STAT1 0xc830
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
--
--#if IS_REACHABLE(CONFIG_HWMON)
--
--static umode_t aqr_hwmon_is_visible(const void *data,
-- enum hwmon_sensor_types type,
-- u32 attr, int channel)
--{
-- if (type != hwmon_temp)
-- return 0;
--
-- switch (attr) {
-- case hwmon_temp_input:
-- case hwmon_temp_min_alarm:
-- case hwmon_temp_max_alarm:
-- case hwmon_temp_lcrit_alarm:
-- case hwmon_temp_crit_alarm:
-- return 0444;
-- case hwmon_temp_min:
-- case hwmon_temp_max:
-- case hwmon_temp_lcrit:
-- case hwmon_temp_crit:
-- return 0644;
-- default:
-- return 0;
-- }
--}
--
--static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
--{
-- int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
--
-- if (temp < 0)
-- return temp;
--
-- /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */
-- *value = (s16)temp * 1000 / 256;
--
-- return 0;
--}
--
--static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
--{
-- int temp;
--
-- if (value >= 128000 || value < -128000)
-- return -ERANGE;
--
-- temp = value * 256 / 1000;
--
-- /* temp is in s16 range and we're interested in lower 16 bits only */
-- return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp);
--}
--
--static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit)
--{
-- int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
--
-- if (val < 0)
-- return val;
--
-- return !!(val & bit);
--}
--
--static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
--{
-- int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit);
--
-- if (val < 0)
-- return val;
--
-- *value = val;
--
-- return 0;
--}
--
--static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
-- u32 attr, int channel, long *value)
--{
-- struct phy_device *phydev = dev_get_drvdata(dev);
-- int reg;
--
-- if (type != hwmon_temp)
-- return -EOPNOTSUPP;
--
-- switch (attr) {
-- case hwmon_temp_input:
-- reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2,
-- VEND1_THERMAL_STAT2_VALID);
-- if (reg < 0)
-- return reg;
-- if (!reg)
-- return -EBUSY;
--
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
--
-- case hwmon_temp_lcrit:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-- value);
-- case hwmon_temp_min:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-- value);
-- case hwmon_temp_max:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-- value);
-- case hwmon_temp_crit:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-- value);
-- case hwmon_temp_lcrit_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_LOW_TEMP_FAIL,
-- value);
-- case hwmon_temp_min_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_LOW_TEMP_WARN,
-- value);
-- case hwmon_temp_max_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_HIGH_TEMP_WARN,
-- value);
-- case hwmon_temp_crit_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL,
-- value);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
-- u32 attr, int channel, long value)
--{
-- struct phy_device *phydev = dev_get_drvdata(dev);
--
-- if (type != hwmon_temp)
-- return -EOPNOTSUPP;
--
-- switch (attr) {
-- case hwmon_temp_lcrit:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-- value);
-- case hwmon_temp_min:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-- value);
-- case hwmon_temp_max:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-- value);
-- case hwmon_temp_crit:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-- value);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static const struct hwmon_ops aqr_hwmon_ops = {
-- .is_visible = aqr_hwmon_is_visible,
-- .read = aqr_hwmon_read,
-- .write = aqr_hwmon_write,
--};
--
--static u32 aqr_hwmon_chip_config[] = {
-- HWMON_C_REGISTER_TZ,
-- 0,
--};
--
--static const struct hwmon_channel_info aqr_hwmon_chip = {
-- .type = hwmon_chip,
-- .config = aqr_hwmon_chip_config,
--};
--
--static u32 aqr_hwmon_temp_config[] = {
-- HWMON_T_INPUT |
-- HWMON_T_MAX | HWMON_T_MIN |
-- HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM |
-- HWMON_T_CRIT | HWMON_T_LCRIT |
-- HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM,
-- 0,
--};
--
--static const struct hwmon_channel_info aqr_hwmon_temp = {
-- .type = hwmon_temp,
-- .config = aqr_hwmon_temp_config,
--};
--
--static const struct hwmon_channel_info *aqr_hwmon_info[] = {
-- &aqr_hwmon_chip,
-- &aqr_hwmon_temp,
-- NULL,
--};
--
--static const struct hwmon_chip_info aqr_hwmon_chip_info = {
-- .ops = &aqr_hwmon_ops,
-- .info = aqr_hwmon_info,
--};
--
--int aqr_hwmon_probe(struct phy_device *phydev)
--{
-- struct device *dev = &phydev->mdio.dev;
-- struct device *hwmon_dev;
-- char *hwmon_name;
-- int i, j;
--
-- hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
-- if (!hwmon_name)
-- return -ENOMEM;
--
-- for (i = j = 0; hwmon_name[i]; i++) {
-- if (isalnum(hwmon_name[i])) {
-- if (i != j)
-- hwmon_name[j] = hwmon_name[i];
-- j++;
-- }
-- }
-- hwmon_name[j] = '\0';
--
-- hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name,
-- phydev, &aqr_hwmon_chip_info, NULL);
--
-- return PTR_ERR_OR_ZERO(hwmon_dev);
--}
--
--#endif
---- a/drivers/net/phy/aquantia_main.c
-+++ /dev/null
-@@ -1,844 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/*
-- * Driver for Aquantia PHY
-- *
-- * Author: Shaohui Xie <Shaohui.Xie@freescale.com>
-- *
-- * Copyright 2015 Freescale Semiconductor, Inc.
-- */
--
--#include <linux/kernel.h>
--#include <linux/module.h>
--#include <linux/delay.h>
--#include <linux/bitfield.h>
--#include <linux/phy.h>
--
--#include "aquantia.h"
--
--#define PHY_ID_AQ1202 0x03a1b445
--#define PHY_ID_AQ2104 0x03a1b460
--#define PHY_ID_AQR105 0x03a1b4a2
--#define PHY_ID_AQR106 0x03a1b4d0
--#define PHY_ID_AQR107 0x03a1b4e0
--#define PHY_ID_AQCS109 0x03a1b5c2
--#define PHY_ID_AQR405 0x03a1b4b0
--#define PHY_ID_AQR113C 0x31c31c12
--
--#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
--
--#define MDIO_AN_VEND_PROV 0xc400
--#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15)
--#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)
--#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11)
--#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
--#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
--#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
--#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
--
--#define MDIO_AN_TX_VEND_STATUS1 0xc800
--#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1)
--#define MDIO_AN_TX_VEND_STATUS1_10BASET 0
--#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1
--#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2
--#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3
--#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4
--#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5
--#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0)
--
--#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00
--#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1)
--
--#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01
--#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0)
--
--#define MDIO_AN_TX_VEND_INT_MASK2 0xd401
--#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0)
--
--#define MDIO_AN_RX_LP_STAT1 0xe820
--#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15)
--#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14)
--#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13)
--#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12)
--#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2)
--
--#define MDIO_AN_RX_LP_STAT4 0xe823
--#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8)
--#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0)
--
--#define MDIO_AN_RX_VEND_STAT3 0xe832
--#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
--
--/* MDIO_MMD_C22EXT */
--#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292
--#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294
--#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297
--#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313
--#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315
--#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317
--#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318
--#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319
--#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
--#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
--
--/* Vendor specific 1, MDIO_MMD_VEND1 */
--#define VEND1_GLOBAL_FW_ID 0x0020
--#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
--#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
--
--#define VEND1_GLOBAL_GEN_STAT2 0xc831
--#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
--
--/* The following registers all have similar layouts; first the registers... */
--#define VEND1_GLOBAL_CFG_10M 0x0310
--#define VEND1_GLOBAL_CFG_100M 0x031b
--#define VEND1_GLOBAL_CFG_1G 0x031c
--#define VEND1_GLOBAL_CFG_2_5G 0x031d
--#define VEND1_GLOBAL_CFG_5G 0x031e
--#define VEND1_GLOBAL_CFG_10G 0x031f
--/* ...and now the fields */
--#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
--
--#define VEND1_GLOBAL_RSVD_STAT1 0xc885
--#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
--#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
--
--#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
--#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
--#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
--
--#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
--#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
--
--#define VEND1_GLOBAL_INT_STD_MASK 0xff00
--#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
--#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
--#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
--#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
--#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
--#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
--
--#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
--#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
--#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
--#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
--#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
--#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
--
--/* Sleep and timeout for checking if the Processor-Intensive
-- * MDIO operation is finished
-- */
--#define AQR107_OP_IN_PROG_SLEEP 1000
--#define AQR107_OP_IN_PROG_TIMEOUT 100000
--
--struct aqr107_hw_stat {
-- const char *name;
-- int reg;
-- int size;
--};
--
--#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
--static const struct aqr107_hw_stat aqr107_hw_stats[] = {
-- SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26),
-- SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26),
-- SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8),
-- SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26),
-- SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26),
-- SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8),
-- SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8),
-- SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8),
-- SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16),
-- SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22),
--};
--#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
--
--struct aqr107_priv {
-- u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
--};
--
--static int aqr107_get_sset_count(struct phy_device *phydev)
--{
-- return AQR107_SGMII_STAT_SZ;
--}
--
--static void aqr107_get_strings(struct phy_device *phydev, u8 *data)
--{
-- int i;
--
-- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++)
-- strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name,
-- ETH_GSTRING_LEN);
--}
--
--static u64 aqr107_get_stat(struct phy_device *phydev, int index)
--{
-- const struct aqr107_hw_stat *stat = aqr107_hw_stats + index;
-- int len_l = min(stat->size, 16);
-- int len_h = stat->size - len_l;
-- u64 ret;
-- int val;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg);
-- if (val < 0)
-- return U64_MAX;
--
-- ret = val & GENMASK(len_l - 1, 0);
-- if (len_h) {
-- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1);
-- if (val < 0)
-- return U64_MAX;
--
-- ret += (val & GENMASK(len_h - 1, 0)) << 16;
-- }
--
-- return ret;
--}
--
--static void aqr107_get_stats(struct phy_device *phydev,
-- struct ethtool_stats *stats, u64 *data)
--{
-- struct aqr107_priv *priv = phydev->priv;
-- u64 val;
-- int i;
--
-- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) {
-- val = aqr107_get_stat(phydev, i);
-- if (val == U64_MAX)
-- phydev_err(phydev, "Reading HW Statistics failed for %s\n",
-- aqr107_hw_stats[i].name);
-- else
-- priv->sgmii_stats[i] += val;
--
-- data[i] = priv->sgmii_stats[i];
-- }
--}
--
--static int aqr_config_aneg(struct phy_device *phydev)
--{
-- bool changed = false;
-- u16 reg;
-- int ret;
--
-- if (phydev->autoneg == AUTONEG_DISABLE)
-- return genphy_c45_pma_setup_forced(phydev);
--
-- ret = genphy_c45_an_config_aneg(phydev);
-- if (ret < 0)
-- return ret;
-- if (ret > 0)
-- changed = true;
--
-- /* Clause 45 has no standardized support for 1000BaseT, therefore
-- * use vendor registers for this mode.
-- */
-- reg = 0;
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
--
-- /* Handle the case when the 2.5G and 5G speeds are not advertised */
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;
--
-- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-- MDIO_AN_VEND_PROV_1000BASET_HALF |
-- MDIO_AN_VEND_PROV_1000BASET_FULL |
-- MDIO_AN_VEND_PROV_2500BASET_FULL |
-- MDIO_AN_VEND_PROV_5000BASET_FULL, reg);
-- if (ret < 0)
-- return ret;
-- if (ret > 0)
-- changed = true;
--
-- return genphy_c45_check_and_restart_aneg(phydev, changed);
--}
--
--static int aqr_config_intr(struct phy_device *phydev)
--{
-- bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
-- int err;
--
-- if (en) {
-- /* Clear any pending interrupts before enabling them */
-- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-- if (err < 0)
-- return err;
-- }
--
-- err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,
-- en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);
-- if (err < 0)
-- return err;
--
-- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,
-- en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);
-- if (err < 0)
-- return err;
--
-- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
-- en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
-- VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
-- if (err < 0)
-- return err;
--
-- if (!en) {
-- /* Clear any pending interrupts after we have disabled them */
-- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-- if (err < 0)
-- return err;
-- }
--
-- return 0;
--}
--
--static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
--{
-- int irq_status;
--
-- irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,
-- MDIO_AN_TX_VEND_INT_STATUS2);
-- if (irq_status < 0) {
-- phy_error(phydev);
-- return IRQ_NONE;
-- }
--
-- if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))
-- return IRQ_NONE;
--
-- phy_trigger_machine(phydev);
--
-- return IRQ_HANDLED;
--}
--
--static int aqr_read_status(struct phy_device *phydev)
--{
-- int val;
--
-- if (phydev->autoneg == AUTONEG_ENABLE) {
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-- if (val < 0)
-- return val;
--
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-- phydev->lp_advertising,
-- val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-- phydev->lp_advertising,
-- val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);
-- }
--
-- return genphy_c45_read_status(phydev);
--}
--
--static int aqr107_read_rate(struct phy_device *phydev)
--{
-- u32 config_reg;
-- int val;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
-- if (val < 0)
-- return val;
--
-- if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
-- phydev->duplex = DUPLEX_FULL;
-- else
-- phydev->duplex = DUPLEX_HALF;
--
-- switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
-- case MDIO_AN_TX_VEND_STATUS1_10BASET:
-- phydev->speed = SPEED_10;
-- config_reg = VEND1_GLOBAL_CFG_10M;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_100BASETX:
-- phydev->speed = SPEED_100;
-- config_reg = VEND1_GLOBAL_CFG_100M;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_1000BASET:
-- phydev->speed = SPEED_1000;
-- config_reg = VEND1_GLOBAL_CFG_1G;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_2500BASET:
-- phydev->speed = SPEED_2500;
-- config_reg = VEND1_GLOBAL_CFG_2_5G;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_5000BASET:
-- phydev->speed = SPEED_5000;
-- config_reg = VEND1_GLOBAL_CFG_5G;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_10GBASET:
-- phydev->speed = SPEED_10000;
-- config_reg = VEND1_GLOBAL_CFG_10G;
-- break;
-- default:
-- phydev->speed = SPEED_UNKNOWN;
-- return 0;
-- }
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);
-- if (val < 0)
-- return val;
--
-- if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==
-- VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)
-- phydev->rate_matching = RATE_MATCH_PAUSE;
-- else
-- phydev->rate_matching = RATE_MATCH_NONE;
--
-- return 0;
--}
--
--static int aqr107_read_status(struct phy_device *phydev)
--{
-- int val, ret;
--
-- ret = aqr_read_status(phydev);
-- if (ret)
-- return ret;
--
-- if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
-- return 0;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
-- if (val < 0)
-- return val;
--
-- switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
-- phydev->interface = PHY_INTERFACE_MODE_10GKR;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:
-- phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
-- phydev->interface = PHY_INTERFACE_MODE_10GBASER;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
-- phydev->interface = PHY_INTERFACE_MODE_USXGMII;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:
-- phydev->interface = PHY_INTERFACE_MODE_XAUI;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
-- phydev->interface = PHY_INTERFACE_MODE_SGMII;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:
-- phydev->interface = PHY_INTERFACE_MODE_RXAUI;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
-- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-- break;
-- default:
-- phydev->interface = PHY_INTERFACE_MODE_NA;
-- break;
-- }
--
-- /* Read possibly downshifted rate from vendor register */
-- return aqr107_read_rate(phydev);
--}
--
--static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
--{
-- int val, cnt, enable;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);
-- if (val < 0)
-- return val;
--
-- enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);
-- cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
--
-- *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;
--
-- return 0;
--}
--
--static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
--{
-- int val = 0;
--
-- if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))
-- return -E2BIG;
--
-- if (cnt != DOWNSHIFT_DEV_DISABLE) {
-- val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;
-- val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);
-- }
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-- MDIO_AN_VEND_PROV_DOWNSHIFT_EN |
-- MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
--}
--
--static int aqr107_get_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return aqr107_get_downshift(phydev, data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static int aqr107_set_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, const void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return aqr107_set_downshift(phydev, *(const u8 *)data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--/* If we configure settings whilst firmware is still initializing the chip,
-- * then these settings may be overwritten. Therefore make sure chip
-- * initialization has completed. Use presence of the firmware ID as
-- * indicator for initialization having completed.
-- * The chip also provides a "reset completed" bit, but it's cleared after
-- * read. Therefore function would time out if called again.
-- */
--static int aqr107_wait_reset_complete(struct phy_device *phydev)
--{
-- int val;
--
-- return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-- VEND1_GLOBAL_FW_ID, val, val != 0,
-- 20000, 2000000, false);
--}
--
--static void aqr107_chip_info(struct phy_device *phydev)
--{
-- u8 fw_major, fw_minor, build_id, prov_id;
-- int val;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
-- if (val < 0)
-- return;
--
-- fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val);
-- fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1);
-- if (val < 0)
-- return;
--
-- build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
-- prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
--
-- phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
-- fw_major, fw_minor, build_id, prov_id);
--}
--
--static int aqr107_config_init(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Check that the PHY interface type is compatible */
-- if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_1000BASEKX &&
-- phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
-- phydev->interface != PHY_INTERFACE_MODE_XGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_USXGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_10GKR &&
-- phydev->interface != PHY_INTERFACE_MODE_10GBASER &&
-- phydev->interface != PHY_INTERFACE_MODE_XAUI &&
-- phydev->interface != PHY_INTERFACE_MODE_RXAUI)
-- return -ENODEV;
--
-- WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
-- "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");
--
-- ret = aqr107_wait_reset_complete(phydev);
-- if (!ret)
-- aqr107_chip_info(phydev);
--
-- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
--}
--
--static int aqcs109_config_init(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Check that the PHY interface type is compatible */
-- if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
-- return -ENODEV;
--
-- ret = aqr107_wait_reset_complete(phydev);
-- if (!ret)
-- aqr107_chip_info(phydev);
--
-- /* AQCS109 belongs to a chip family partially supporting 10G and 5G.
-- * PMA speed ability bits are the same for all members of the family,
-- * AQCS109 however supports speeds up to 2.5G only.
-- */
-- ret = phy_set_max_speed(phydev, SPEED_2500);
-- if (ret)
-- return ret;
--
-- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
--}
--
--static void aqr107_link_change_notify(struct phy_device *phydev)
--{
-- u8 fw_major, fw_minor;
-- bool downshift, short_reach, afr;
-- int mode, val;
--
-- if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE)
-- return;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-- /* call failed or link partner is no Aquantia PHY */
-- if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY))
-- return;
--
-- short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH;
-- downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4);
-- if (val < 0)
-- return;
--
-- fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val);
-- fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3);
-- if (val < 0)
-- return;
--
-- afr = val & MDIO_AN_RX_VEND_STAT3_AFR;
--
-- phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n",
-- fw_major, fw_minor,
-- short_reach ? ", short reach mode" : "",
-- downshift ? ", fast-retrain downshift advertised" : "",
-- afr ? ", fast reframe advertised" : "");
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9);
-- if (val < 0)
-- return;
--
-- mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val);
-- if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2)
-- phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
--}
--
--static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
--{
-- int val, err;
--
-- /* The datasheet notes to wait at least 1ms after issuing a
-- * processor intensive operation before checking.
-- * We cannot use the 'sleep_before_read' parameter of read_poll_timeout
-- * because that just determines the maximum time slept, not the minimum.
-- */
-- usleep_range(1000, 5000);
--
-- err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-- VEND1_GLOBAL_GEN_STAT2, val,
-- !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
-- AQR107_OP_IN_PROG_SLEEP,
-- AQR107_OP_IN_PROG_TIMEOUT, false);
-- if (err) {
-- phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
-- return err;
-- }
--
-- return 0;
--}
--
--static int aqr107_get_rate_matching(struct phy_device *phydev,
-- phy_interface_t iface)
--{
-- if (iface == PHY_INTERFACE_MODE_10GBASER ||
-- iface == PHY_INTERFACE_MODE_2500BASEX ||
-- iface == PHY_INTERFACE_MODE_NA)
-- return RATE_MATCH_PAUSE;
-- return RATE_MATCH_NONE;
--}
--
--static int aqr107_suspend(struct phy_device *phydev)
--{
-- int err;
--
-- err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-- MDIO_CTRL1_LPOWER);
-- if (err)
-- return err;
--
-- return aqr107_wait_processor_intensive_op(phydev);
--}
--
--static int aqr107_resume(struct phy_device *phydev)
--{
-- int err;
--
-- err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-- MDIO_CTRL1_LPOWER);
-- if (err)
-- return err;
--
-- return aqr107_wait_processor_intensive_op(phydev);
--}
--
--static int aqr107_probe(struct phy_device *phydev)
--{
-- phydev->priv = devm_kzalloc(&phydev->mdio.dev,
-- sizeof(struct aqr107_priv), GFP_KERNEL);
-- if (!phydev->priv)
-- return -ENOMEM;
--
-- return aqr_hwmon_probe(phydev);
--}
--
--static struct phy_driver aqr_driver[] = {
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
-- .name = "Aquantia AQ1202",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),
-- .name = "Aquantia AQ2104",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
-- .name = "Aquantia AQR105",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
-- .name = "Aquantia AQR106",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
-- .name = "Aquantia AQR107",
-- .probe = aqr107_probe,
-- .get_rate_matching = aqr107_get_rate_matching,
-- .config_init = aqr107_config_init,
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr107_read_status,
-- .get_tunable = aqr107_get_tunable,
-- .set_tunable = aqr107_set_tunable,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
-- .get_sset_count = aqr107_get_sset_count,
-- .get_strings = aqr107_get_strings,
-- .get_stats = aqr107_get_stats,
-- .link_change_notify = aqr107_link_change_notify,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
-- .name = "Aquantia AQCS109",
-- .probe = aqr107_probe,
-- .get_rate_matching = aqr107_get_rate_matching,
-- .config_init = aqcs109_config_init,
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr107_read_status,
-- .get_tunable = aqr107_get_tunable,
-- .set_tunable = aqr107_set_tunable,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
-- .get_sset_count = aqr107_get_sset_count,
-- .get_strings = aqr107_get_strings,
-- .get_stats = aqr107_get_stats,
-- .link_change_notify = aqr107_link_change_notify,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
-- .name = "Aquantia AQR405",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
-- .name = "Aquantia AQR113C",
-- .probe = aqr107_probe,
-- .get_rate_matching = aqr107_get_rate_matching,
-- .config_init = aqr107_config_init,
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr107_read_status,
-- .get_tunable = aqr107_get_tunable,
-- .set_tunable = aqr107_set_tunable,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
-- .get_sset_count = aqr107_get_sset_count,
-- .get_strings = aqr107_get_strings,
-- .get_stats = aqr107_get_stats,
-- .link_change_notify = aqr107_link_change_notify,
--},
--};
--
--module_phy_driver(aqr_driver);
--
--static struct mdio_device_id __maybe_unused aqr_tbl[] = {
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
-- { }
--};
--
--MODULE_DEVICE_TABLE(mdio, aqr_tbl);
--
--MODULE_DESCRIPTION("Aquantia PHY driver");
--MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");
--MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch b/target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch
deleted file mode 100644
index 2b94522723..0000000000
--- a/target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From e1fbfa4a995d42e02e22b0dff2f8b4fdee1504b3 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 14 Nov 2023 15:08:42 +0100
-Subject: [PATCH 2/3] net: phy: aquantia: move MMD_VEND define to header
-
-Move MMD_VEND define to header to clean things up and in preparation for
-firmware loading support that require some define placed in
-aquantia_main.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/aquantia.h | 69 +++++++++++++++++++++++
- drivers/net/phy/aquantia/aquantia_hwmon.c | 14 -----
- drivers/net/phy/aquantia/aquantia_main.c | 55 ------------------
- 3 files changed, 69 insertions(+), 69 deletions(-)
-
---- a/drivers/net/phy/aquantia/aquantia.h
-+++ b/drivers/net/phy/aquantia/aquantia.h
-@@ -9,6 +9,75 @@
- #include <linux/device.h>
- #include <linux/phy.h>
-
-+/* Vendor specific 1, MDIO_MMD_VEND1 */
-+#define VEND1_GLOBAL_FW_ID 0x0020
-+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
-+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
-+
-+/* The following registers all have similar layouts; first the registers... */
-+#define VEND1_GLOBAL_CFG_10M 0x0310
-+#define VEND1_GLOBAL_CFG_100M 0x031b
-+#define VEND1_GLOBAL_CFG_1G 0x031c
-+#define VEND1_GLOBAL_CFG_2_5G 0x031d
-+#define VEND1_GLOBAL_CFG_5G 0x031e
-+#define VEND1_GLOBAL_CFG_10G 0x031f
-+/* ...and now the fields */
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-+
-+/* Vendor specific 1, MDIO_MMD_VEND2 */
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
-+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
-+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
-+#define VEND1_THERMAL_STAT1 0xc820
-+#define VEND1_THERMAL_STAT2 0xc821
-+#define VEND1_THERMAL_STAT2_VALID BIT(0)
-+#define VEND1_GENERAL_STAT1 0xc830
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
-+
-+#define VEND1_GLOBAL_GEN_STAT2 0xc831
-+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
-+
-+#define VEND1_GLOBAL_RSVD_STAT1 0xc885
-+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
-+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
-+
-+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
-+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
-+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
-+
-+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
-+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
-+
-+#define VEND1_GLOBAL_INT_STD_MASK 0xff00
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
-+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
-+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
-+
-+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
-+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
-+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
-+
- #if IS_REACHABLE(CONFIG_HWMON)
- int aqr_hwmon_probe(struct phy_device *phydev);
- #else
---- a/drivers/net/phy/aquantia/aquantia_hwmon.c
-+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c
-@@ -13,20 +13,6 @@
-
- #include "aquantia.h"
-
--/* Vendor specific 1, MDIO_MMD_VEND2 */
--#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
--#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
--#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
--#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
--#define VEND1_THERMAL_STAT1 0xc820
--#define VEND1_THERMAL_STAT2 0xc821
--#define VEND1_THERMAL_STAT2_VALID BIT(0)
--#define VEND1_GENERAL_STAT1 0xc830
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
--
- #if IS_REACHABLE(CONFIG_HWMON)
-
- static umode_t aqr_hwmon_is_visible(const void *data,
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -89,61 +89,6 @@
- #define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
- #define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
-
--/* Vendor specific 1, MDIO_MMD_VEND1 */
--#define VEND1_GLOBAL_FW_ID 0x0020
--#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
--#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
--
--#define VEND1_GLOBAL_GEN_STAT2 0xc831
--#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
--
--/* The following registers all have similar layouts; first the registers... */
--#define VEND1_GLOBAL_CFG_10M 0x0310
--#define VEND1_GLOBAL_CFG_100M 0x031b
--#define VEND1_GLOBAL_CFG_1G 0x031c
--#define VEND1_GLOBAL_CFG_2_5G 0x031d
--#define VEND1_GLOBAL_CFG_5G 0x031e
--#define VEND1_GLOBAL_CFG_10G 0x031f
--/* ...and now the fields */
--#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
--
--#define VEND1_GLOBAL_RSVD_STAT1 0xc885
--#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
--#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
--
--#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
--#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
--#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
--
--#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
--#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
--
--#define VEND1_GLOBAL_INT_STD_MASK 0xff00
--#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
--#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
--#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
--#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
--#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
--#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
--
--#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
--#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
--#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
--#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
--#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
--#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
--
- /* Sleep and timeout for checking if the Processor-Intensive
- * MDIO operation is finished
- */
diff --git a/target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch b/target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch
deleted file mode 100644
index 1ae5966df6..0000000000
--- a/target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch
+++ /dev/null
@@ -1,504 +0,0 @@
-From e93984ebc1c82bd34f7a1b3391efaceee0a8ae96 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Tue, 14 Nov 2023 15:08:43 +0100
-Subject: [PATCH 3/3] net: phy: aquantia: add firmware load support
-
-Aquantia PHY-s require firmware to be loaded before they start operating.
-It can be automatically loaded in case when there is a SPI-NOR connected
-to Aquantia PHY-s or can be loaded from the host via MDIO.
-
-This patch adds support for loading the firmware via MDIO as in most cases
-there is no SPI-NOR being used to save on cost.
-Firmware loading code itself is ported from mainline U-boot with cleanups.
-
-The firmware has mixed values both in big and little endian.
-PHY core itself is big-endian but it expects values to be in little-endian.
-The firmware is little-endian but CRC-16 value for it is stored at the end
-of firmware in big-endian.
-
-It seems the PHY does the conversion internally from firmware that is
-little-endian to the PHY that is big-endian on using the mailbox
-but mailbox returns a big-endian CRC-16 to verify the written data
-integrity.
-
-Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/Kconfig | 1 +
- drivers/net/phy/aquantia/Makefile | 2 +-
- drivers/net/phy/aquantia/aquantia.h | 32 ++
- drivers/net/phy/aquantia/aquantia_firmware.c | 370 +++++++++++++++++++
- drivers/net/phy/aquantia/aquantia_main.c | 6 +
- 5 files changed, 410 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/phy/aquantia/aquantia_firmware.c
-
---- a/drivers/net/phy/aquantia/Kconfig
-+++ b/drivers/net/phy/aquantia/Kconfig
-@@ -1,5 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0-only
- config AQUANTIA_PHY
- tristate "Aquantia PHYs"
-+ select CRC_CCITT
- help
- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
---- a/drivers/net/phy/aquantia/Makefile
-+++ b/drivers/net/phy/aquantia/Makefile
-@@ -1,5 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
--aquantia-objs += aquantia_main.o
-+aquantia-objs += aquantia_main.o aquantia_firmware.o
- ifdef CONFIG_HWMON
- aquantia-objs += aquantia_hwmon.o
- endif
---- a/drivers/net/phy/aquantia/aquantia.h
-+++ b/drivers/net/phy/aquantia/aquantia.h
-@@ -10,10 +10,35 @@
- #include <linux/phy.h>
-
- /* Vendor specific 1, MDIO_MMD_VEND1 */
-+#define VEND1_GLOBAL_SC 0x0
-+#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15)
-+#define VEND1_GLOBAL_SC_LOW_POWER BIT(11)
-+
- #define VEND1_GLOBAL_FW_ID 0x0020
- #define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
- #define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
-
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8)
-+
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16))
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x))
-+
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16))
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x))
-+
- /* The following registers all have similar layouts; first the registers... */
- #define VEND1_GLOBAL_CFG_10M 0x0310
- #define VEND1_GLOBAL_CFG_100M 0x031b
-@@ -28,6 +53,11 @@
- #define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-
- /* Vendor specific 1, MDIO_MMD_VEND2 */
-+#define VEND1_GLOBAL_CONTROL2 0xc001
-+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15)
-+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6)
-+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0)
-+
- #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
- #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
- #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
-@@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *p
- #else
- static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
- #endif
-+
-+int aqr_firmware_load(struct phy_device *phydev);
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia_firmware.c
-@@ -0,0 +1,370 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/bitfield.h>
-+#include <linux/of.h>
-+#include <linux/firmware.h>
-+#include <linux/crc-ccitt.h>
-+#include <linux/nvmem-consumer.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include "aquantia.h"
-+
-+#define UP_RESET_SLEEP 100
-+
-+/* addresses of memory segments in the phy */
-+#define DRAM_BASE_ADDR 0x3FFE0000
-+#define IRAM_BASE_ADDR 0x40000000
-+
-+/* firmware image format constants */
-+#define VERSION_STRING_SIZE 0x40
-+#define VERSION_STRING_OFFSET 0x0200
-+/* primary offset is written at an offset from the start of the fw blob */
-+#define PRIMARY_OFFSET_OFFSET 0x8
-+/* primary offset needs to be then added to a base offset */
-+#define PRIMARY_OFFSET_SHIFT 12
-+#define PRIMARY_OFFSET(x) ((x) << PRIMARY_OFFSET_SHIFT)
-+#define HEADER_OFFSET 0x300
-+
-+struct aqr_fw_header {
-+ u32 padding;
-+ u8 iram_offset[3];
-+ u8 iram_size[3];
-+ u8 dram_offset[3];
-+ u8 dram_size[3];
-+} __packed;
-+
-+enum aqr_fw_src {
-+ AQR_FW_SRC_NVMEM = 0,
-+ AQR_FW_SRC_FS,
-+};
-+
-+static const char * const aqr_fw_src_string[] = {
-+ [AQR_FW_SRC_NVMEM] = "NVMEM",
-+ [AQR_FW_SRC_FS] = "FS",
-+};
-+
-+/* AQR firmware doesn't have fixed offsets for iram and dram section
-+ * but instead provide an header with the offset to use on reading
-+ * and parsing the firmware.
-+ *
-+ * AQR firmware can't be trusted and each offset is validated to be
-+ * not negative and be in the size of the firmware itself.
-+ */
-+static bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
-+{
-+ return offset + get_size <= size;
-+}
-+
-+static int aqr_fw_get_be16(const u8 *data, size_t offset, size_t size, u16 *value)
-+{
-+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
-+ return -EINVAL;
-+
-+ *value = get_unaligned_be16(data + offset);
-+
-+ return 0;
-+}
-+
-+static int aqr_fw_get_le16(const u8 *data, size_t offset, size_t size, u16 *value)
-+{
-+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
-+ return -EINVAL;
-+
-+ *value = get_unaligned_le16(data + offset);
-+
-+ return 0;
-+}
-+
-+static int aqr_fw_get_le24(const u8 *data, size_t offset, size_t size, u32 *value)
-+{
-+ if (!aqr_fw_validate_get(size, offset, sizeof(u8) * 3))
-+ return -EINVAL;
-+
-+ *value = get_unaligned_le24(data + offset);
-+
-+ return 0;
-+}
-+
-+/* load data into the phy's memory */
-+static int aqr_fw_load_memory(struct phy_device *phydev, u32 addr,
-+ const u8 *data, size_t len)
-+{
-+ u16 crc = 0, up_crc;
-+ size_t pos;
-+
-+ /* PHY expect addr in LE */
-+ addr = (__force u32)cpu_to_le32(addr);
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET);
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE3,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(addr));
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE4,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(addr));
-+
-+ /* We assume and enforce the size to be word aligned.
-+ * If a firmware that is not word aligned is found, please report upstream.
-+ */
-+ for (pos = 0; pos < len; pos += sizeof(u32)) {
-+ u32 word;
-+
-+ /* FW data is always stored in little-endian */
-+ word = get_unaligned((const u32 *)(data + pos));
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word));
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE6,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(word));
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE |
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE);
-+
-+ /* calculate CRC as we load data to the mailbox.
-+ * We convert word to big-endian as PHY is BE and mailbox will
-+ * return a BE CRC.
-+ */
-+ word = (__force u32)cpu_to_be32(word);
-+ crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word));
-+ }
-+
-+ up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2);
-+ if (crc != up_crc) {
-+ phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n",
-+ crc, up_crc);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
-+ enum aqr_fw_src fw_src)
-+{
-+ u16 calculated_crc, read_crc, read_primary_offset;
-+ u32 iram_offset = 0, iram_size = 0;
-+ u32 dram_offset = 0, dram_size = 0;
-+ char version[VERSION_STRING_SIZE];
-+ u32 primary_offset = 0;
-+ int ret;
-+
-+ /* extract saved CRC at the end of the fw
-+ * CRC is saved in big-endian as PHY is BE
-+ */
-+ ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
-+ if (ret) {
-+ phydev_err(phydev, "bad firmware CRC in firmware\n");
-+ return ret;
-+ }
-+ calculated_crc = crc_ccitt_false(0, data, size - sizeof(u16));
-+ if (read_crc != calculated_crc) {
-+ phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n",
-+ read_crc, calculated_crc);
-+ return -EINVAL;
-+ }
-+
-+ /* Get the primary offset to extract DRAM and IRAM sections. */
-+ ret = aqr_fw_get_le16(data, PRIMARY_OFFSET_OFFSET, size, &read_primary_offset);
-+ if (ret) {
-+ phydev_err(phydev, "bad primary offset in firmware\n");
-+ return ret;
-+ }
-+ primary_offset = PRIMARY_OFFSET(read_primary_offset);
-+
-+ /* Find the DRAM and IRAM sections within the firmware file.
-+ * Make sure the fw_header is correctly in the firmware.
-+ */
-+ if (!aqr_fw_validate_get(size, primary_offset + HEADER_OFFSET,
-+ sizeof(struct aqr_fw_header))) {
-+ phydev_err(phydev, "bad fw_header in firmware\n");
-+ return -EINVAL;
-+ }
-+
-+ /* offset are in LE and values needs to be converted to cpu endian */
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, iram_offset),
-+ size, &iram_offset);
-+ if (ret) {
-+ phydev_err(phydev, "bad iram offset in firmware\n");
-+ return ret;
-+ }
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, iram_size),
-+ size, &iram_size);
-+ if (ret) {
-+ phydev_err(phydev, "invalid iram size in firmware\n");
-+ return ret;
-+ }
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, dram_offset),
-+ size, &dram_offset);
-+ if (ret) {
-+ phydev_err(phydev, "bad dram offset in firmware\n");
-+ return ret;
-+ }
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, dram_size),
-+ size, &dram_size);
-+ if (ret) {
-+ phydev_err(phydev, "invalid dram size in firmware\n");
-+ return ret;
-+ }
-+
-+ /* Increment the offset with the primary offset.
-+ * Validate iram/dram offset and size.
-+ */
-+ iram_offset += primary_offset;
-+ if (iram_size % sizeof(u32)) {
-+ phydev_err(phydev, "iram size if not aligned to word size. Please report this upstream!\n");
-+ return -EINVAL;
-+ }
-+ if (!aqr_fw_validate_get(size, iram_offset, iram_size)) {
-+ phydev_err(phydev, "invalid iram offset for iram size\n");
-+ return -EINVAL;
-+ }
-+
-+ dram_offset += primary_offset;
-+ if (dram_size % sizeof(u32)) {
-+ phydev_err(phydev, "dram size if not aligned to word size. Please report this upstream!\n");
-+ return -EINVAL;
-+ }
-+ if (!aqr_fw_validate_get(size, dram_offset, dram_size)) {
-+ phydev_err(phydev, "invalid iram offset for iram size\n");
-+ return -EINVAL;
-+ }
-+
-+ phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n",
-+ primary_offset, iram_offset, iram_size, dram_offset, dram_size);
-+
-+ if (!aqr_fw_validate_get(size, dram_offset + VERSION_STRING_OFFSET,
-+ VERSION_STRING_SIZE)) {
-+ phydev_err(phydev, "invalid version in firmware\n");
-+ return -EINVAL;
-+ }
-+ strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET,
-+ VERSION_STRING_SIZE);
-+ if (version[0] == '\0') {
-+ phydev_err(phydev, "invalid version in firmware\n");
-+ return -EINVAL;
-+ }
-+ phydev_info(phydev, "loading firmware version '%s' from '%s'\n", version,
-+ aqr_fw_src_string[fw_src]);
-+
-+ /* stall the microcprocessor */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
-+
-+ phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n",
-+ DRAM_BASE_ADDR, dram_offset, dram_size);
-+ ret = aqr_fw_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset,
-+ dram_size);
-+ if (ret)
-+ return ret;
-+
-+ phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n",
-+ IRAM_BASE_ADDR, iram_offset, iram_size);
-+ ret = aqr_fw_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset,
-+ iram_size);
-+ if (ret)
-+ return ret;
-+
-+ /* make sure soft reset and low power mode are clear */
-+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC,
-+ VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER);
-+
-+ /* Release the microprocessor. UP_RESET must be held for 100 usec. */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL |
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD |
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST);
-+ usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2);
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
-+
-+ return 0;
-+}
-+
-+static int aqr_firmware_load_nvmem(struct phy_device *phydev)
-+{
-+ struct nvmem_cell *cell;
-+ size_t size;
-+ u8 *buf;
-+ int ret;
-+
-+ cell = nvmem_cell_get(&phydev->mdio.dev, "firmware");
-+ if (IS_ERR(cell))
-+ return PTR_ERR(cell);
-+
-+ buf = nvmem_cell_read(cell, &size);
-+ if (IS_ERR(buf)) {
-+ ret = PTR_ERR(buf);
-+ goto exit;
-+ }
-+
-+ ret = aqr_fw_boot(phydev, buf, size, AQR_FW_SRC_NVMEM);
-+ if (ret)
-+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
-+
-+ kfree(buf);
-+exit:
-+ nvmem_cell_put(cell);
-+
-+ return ret;
-+}
-+
-+static int aqr_firmware_load_fs(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ const struct firmware *fw;
-+ const char *fw_name;
-+ int ret;
-+
-+ ret = of_property_read_string(dev->of_node, "firmware-name",
-+ &fw_name);
-+ if (ret)
-+ return ret;
-+
-+ ret = request_firmware(&fw, fw_name, dev);
-+ if (ret) {
-+ phydev_err(phydev, "failed to find FW file %s (%d)\n",
-+ fw_name, ret);
-+ return ret;
-+ }
-+
-+ ret = aqr_fw_boot(phydev, fw->data, fw->size, AQR_FW_SRC_FS);
-+ if (ret)
-+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
-+
-+ release_firmware(fw);
-+
-+ return ret;
-+}
-+
-+int aqr_firmware_load(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Check if the firmware is not already loaded by pooling
-+ * the current version returned by the PHY. If 0 is returned,
-+ * no firmware is loaded.
-+ */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
-+ if (ret > 0)
-+ goto exit;
-+
-+ ret = aqr_firmware_load_nvmem(phydev);
-+ if (!ret)
-+ goto exit;
-+
-+ ret = aqr_firmware_load_fs(phydev);
-+ if (ret)
-+ return ret;
-+
-+exit:
-+ return 0;
-+}
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -658,11 +658,17 @@ static int aqr107_resume(struct phy_devi
-
- static int aqr107_probe(struct phy_device *phydev)
- {
-+ int ret;
-+
- phydev->priv = devm_kzalloc(&phydev->mdio.dev,
- sizeof(struct aqr107_priv), GFP_KERNEL);
- if (!phydev->priv)
- return -ENOMEM;
-
-+ ret = aqr_firmware_load(phydev);
-+ if (ret)
-+ return ret;
-+
- return aqr_hwmon_probe(phydev);
- }
-
diff --git a/target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch b/target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch
deleted file mode 100644
index d130794c08..0000000000
--- a/target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 038ba1dc4e54d51d953f5618d8eb5dd39bd9de25 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 13 Feb 2024 14:35:51 +0100
-Subject: [PATCH] net: phy: aquantia: add AQR111 and AQR111B0 PHY ID
-
-Add Aquantia AQR111 and AQR111B0 PHY ID. These PHY advertise 10G speed
-but actually supports up to 5G speed, hence some manual fixup is needed.
-
-The Aquantia AQR111B0 PHY is just a variant of the AQR111 with smaller
-chip size.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240213133558.1836-1-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/aquantia/aquantia_main.c | 52 ++++++++++++++++++++++++
- 1 file changed, 52 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -22,6 +22,8 @@
- #define PHY_ID_AQR107 0x03a1b4e0
- #define PHY_ID_AQCS109 0x03a1b5c2
- #define PHY_ID_AQR405 0x03a1b4b0
-+#define PHY_ID_AQR111 0x03a1b610
-+#define PHY_ID_AQR111B0 0x03a1b612
- #define PHY_ID_AQR113C 0x31c31c12
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
-@@ -672,6 +674,16 @@ static int aqr107_probe(struct phy_devic
- return aqr_hwmon_probe(phydev);
- }
-
-+static int aqr111_config_init(struct phy_device *phydev)
-+{
-+ /* AQR111 reports supporting speed up to 10G,
-+ * however only speeds up to 5G are supported.
-+ */
-+ phy_set_max_speed(phydev, SPEED_5000);
-+
-+ return aqr107_config_init(phydev);
-+}
-+
- static struct phy_driver aqr_driver[] = {
- {
- PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
-@@ -746,6 +758,42 @@ static struct phy_driver aqr_driver[] =
- .link_change_notify = aqr107_link_change_notify,
- },
- {
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111),
-+ .name = "Aquantia AQR111",
-+ .probe = aqr107_probe,
-+ .config_init = aqr111_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),
-+ .name = "Aquantia AQR111B0",
-+ .probe = aqr107_probe,
-+ .config_init = aqr111_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
- PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
- .name = "Aquantia AQR405",
- .config_aneg = aqr_config_aneg,
-@@ -784,6 +832,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
- { }
- };
diff --git a/target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch b/target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch
deleted file mode 100644
index 5a46ab39cf..0000000000
--- a/target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 71b605d32017e5b8d257db7344bc2f8e8fcc973e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 15 Feb 2024 16:30:05 +0100
-Subject: [PATCH] net: phy: aquantia: add AQR113 PHY ID
-
-Add Aquantia AQR113 PHY ID. Aquantia AQR113 is just a chip size variant of
-the already supported AQR133C where the only difference is the PHY ID
-and the hw chip size.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -24,6 +24,7 @@
- #define PHY_ID_AQR405 0x03a1b4b0
- #define PHY_ID_AQR111 0x03a1b610
- #define PHY_ID_AQR111B0 0x03a1b612
-+#define PHY_ID_AQR113 0x31c31c40
- #define PHY_ID_AQR113C 0x31c31c12
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
-@@ -802,6 +803,24 @@ static struct phy_driver aqr_driver[] =
- .read_status = aqr_read_status,
- },
- {
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113),
-+ .name = "Aquantia AQR113",
-+ .probe = aqr107_probe,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
- PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
- .name = "Aquantia AQR113C",
- .probe = aqr107_probe,
-@@ -834,6 +853,7 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
- { }
- };
diff --git a/target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch b/target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch
deleted file mode 100644
index 49651a5e4f..0000000000
--- a/target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 6d47302a3f0ba31445478d518d98bd55918bc8ab Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 15 Feb 2024 22:43:30 +0100
-Subject: [PATCH] net: phy: aquantia: add AQR813 PHY ID
-
-Aquantia AQR813 is the Octal Port variant of the AQR113. Add PHY ID for
-it to provide support for it.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -26,6 +26,7 @@
- #define PHY_ID_AQR111B0 0x03a1b612
- #define PHY_ID_AQR113 0x31c31c40
- #define PHY_ID_AQR113C 0x31c31c12
-+#define PHY_ID_AQR813 0x31c31cb2
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -839,6 +840,24 @@ static struct phy_driver aqr_driver[] =
- .get_stats = aqr107_get_stats,
- .link_change_notify = aqr107_link_change_notify,
- },
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
-+ .name = "Aquantia AQR813",
-+ .probe = aqr107_probe,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
- };
-
- module_phy_driver(aqr_driver);
-@@ -855,6 +874,7 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
- { }
- };
-
diff --git a/target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch b/target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch
deleted file mode 100644
index 03171d72cc..0000000000
--- a/target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0ccf8511182436183c031e8a2f740ae91a02c625 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 14 Sep 2021 14:33:45 +0200
-Subject: net: phy: at803x: add support for qca 8327 internal phy
-
-Add support for qca8327 internal phy needed for correct init of the
-switch port. It does use the same qca8337 function and reg just with a
-different id.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Tested-by: Rosen Penev <rosenp@gmail.com>
-Tested-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1410,6 +1410,19 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = at803x_get_sset_count,
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
-+}, {
-+ /* QCA8327 */
-+ .phy_id = QCA8327_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "QCA PHY 8327",
-+ /* PHY_GBIT_FEATURES */
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca83xx_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = at803x_get_sset_count,
-+ .get_strings = at803x_get_strings,
-+ .get_stats = at803x_get_stats,
- }, };
-
- module_phy_driver(at803x_driver);
-@@ -1420,6 +1433,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
- { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
- { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) },
- { }
- };
-
diff --git a/target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch b/target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch
deleted file mode 100644
index dc149a742b..0000000000
--- a/target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From 983d96a9116a328668601555d96736261d33170c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:51 +0200
-Subject: [PATCH] net: dsa: b53: Include all ports in "enabled_ports"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Make "enabled_ports" bitfield contain all available switch ports
-including a CPU port. This way there is no need for fixup during
-initialization.
-
-For BCM53010, BCM53018 and BCM53019 include also other available ports.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 23 +++++++++++------------
- 1 file changed, 11 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2300,7 +2300,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM5325_DEVICE_ID,
- .dev_name = "BCM5325",
- .vlans = 16,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x3f,
- .arl_bins = 2,
- .arl_buckets = 1024,
- .imp_port = 5,
-@@ -2311,7 +2311,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM5365_DEVICE_ID,
- .dev_name = "BCM5365",
- .vlans = 256,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x3f,
- .arl_bins = 2,
- .arl_buckets = 1024,
- .imp_port = 5,
-@@ -2322,7 +2322,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM5389_DEVICE_ID,
- .dev_name = "BCM5389",
- .vlans = 4096,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x11f,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2336,7 +2336,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM5395_DEVICE_ID,
- .dev_name = "BCM5395",
- .vlans = 4096,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x11f,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2350,7 +2350,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM5397_DEVICE_ID,
- .dev_name = "BCM5397",
- .vlans = 4096,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x11f,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2364,7 +2364,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM5398_DEVICE_ID,
- .dev_name = "BCM5398",
- .vlans = 4096,
-- .enabled_ports = 0x7f,
-+ .enabled_ports = 0x17f,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2378,7 +2378,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM53115_DEVICE_ID,
- .dev_name = "BCM53115",
- .vlans = 4096,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x11f,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .vta_regs = B53_VTA_REGS,
-@@ -2392,7 +2392,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM53125_DEVICE_ID,
- .dev_name = "BCM53125",
- .vlans = 4096,
-- .enabled_ports = 0xff,
-+ .enabled_ports = 0x1ff,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2434,7 +2434,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM53010_DEVICE_ID,
- .dev_name = "BCM53010",
- .vlans = 4096,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x1bf,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2476,7 +2476,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM53018_DEVICE_ID,
- .dev_name = "BCM53018",
- .vlans = 4096,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x1bf,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2490,7 +2490,7 @@ static const struct b53_chip_data b53_sw
- .chip_id = BCM53019_DEVICE_ID,
- .dev_name = "BCM53019",
- .vlans = 4096,
-- .enabled_ports = 0x1f,
-+ .enabled_ports = 0x1bf,
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-@@ -2632,7 +2632,6 @@ static int b53_switch_init(struct b53_de
- dev->cpu_port = 5;
- }
-
-- dev->enabled_ports |= BIT(dev->cpu_port);
- dev->num_ports = fls(dev->enabled_ports);
-
- dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS);
diff --git a/target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch b/target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch
deleted file mode 100644
index 23805a9027..0000000000
--- a/target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From b290c6384afabbca5ae6e2af72fb1b2bc37922be Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:52 +0200
-Subject: [PATCH] net: dsa: b53: Drop BCM5301x workaround for a wrong CPU/IMP
- port
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-On BCM5301x port 8 requires a fixed link when used.
-
-Years ago when b53 was an OpenWrt downstream driver (with configuration
-based on sometimes bugged NVRAM) there was a need for a fixup. In case
-of forcing fixed link for (incorrectly specified) port 5 the code had to
-actually setup port 8 link.
-
-For upstream b53 driver with setup based on DT there is no need for that
-workaround. In DT we have and require correct ports setup.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1291,12 +1291,6 @@ static void b53_adjust_link(struct dsa_s
- return;
- }
- }
-- } else if (is5301x(dev)) {
-- if (port != dev->cpu_port) {
-- b53_force_port_config(dev, dev->cpu_port, 2000,
-- DUPLEX_FULL, true, true);
-- b53_force_link(dev, dev->cpu_port, 1);
-- }
- }
-
- /* Re-negotiate EEE if it was enabled already */
diff --git a/target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch b/target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch
deleted file mode 100644
index 941fa23eb4..0000000000
--- a/target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3ff26b29230c54fea2353b63124c589b61953e14 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:53 +0200
-Subject: [PATCH] net: dsa: b53: Improve flow control setup on BCM5301x
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-According to the Broadcom's reference driver flow control needs to be
-enabled for any CPU switch port (5, 7 or 8 - depending on which one is
-used). Current code makes it work only for the port 5. Use
-dsa_is_cpu_port() which solved that problem.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1222,7 +1222,7 @@ static void b53_adjust_link(struct dsa_s
- return;
-
- /* Enable flow control on BCM5301x's CPU port */
-- if (is5301x(dev) && port == dev->cpu_port)
-+ if (is5301x(dev) && dsa_is_cpu_port(ds, port))
- tx_pause = rx_pause = true;
-
- if (phydev->pause) {
diff --git a/target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch b/target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch
deleted file mode 100644
index 07d0ec03cf..0000000000
--- a/target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From 7d5af56418d7d01e43247a33b6fe6492ea871923 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:54 +0200
-Subject: [PATCH] net: dsa: b53: Drop unused "cpu_port" field
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's set but never used anymore.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 28 ----------------------------
- drivers/net/dsa/b53/b53_priv.h | 1 -
- 2 files changed, 29 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2298,7 +2298,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 2,
- .arl_buckets = 1024,
- .imp_port = 5,
-- .cpu_port = B53_CPU_PORT_25,
- .duplex_reg = B53_DUPLEX_STAT_FE,
- },
- {
-@@ -2309,7 +2308,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 2,
- .arl_buckets = 1024,
- .imp_port = 5,
-- .cpu_port = B53_CPU_PORT_25,
- .duplex_reg = B53_DUPLEX_STAT_FE,
- },
- {
-@@ -2320,7 +2318,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2334,7 +2331,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2348,7 +2344,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS_9798,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2362,7 +2357,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS_9798,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2377,7 +2371,6 @@ static const struct b53_chip_data b53_sw
- .arl_buckets = 1024,
- .vta_regs = B53_VTA_REGS,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
- .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-@@ -2390,7 +2383,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2404,7 +2396,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2418,7 +2409,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS_63XX,
- .duplex_reg = B53_DUPLEX_STAT_63XX,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
-@@ -2432,7 +2422,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2446,7 +2435,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2460,7 +2448,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2474,7 +2461,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2488,7 +2474,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2502,7 +2487,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2516,7 +2500,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2545,7 +2528,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 1024,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2559,7 +2541,6 @@ static const struct b53_chip_data b53_sw
- .arl_bins = 4,
- .arl_buckets = 256,
- .imp_port = 8,
-- .cpu_port = B53_CPU_PORT,
- .vta_regs = B53_VTA_REGS,
- .duplex_reg = B53_DUPLEX_STAT_GE,
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2585,7 +2566,6 @@ static int b53_switch_init(struct b53_de
- dev->vta_regs[2] = chip->vta_regs[2];
- dev->jumbo_pm_reg = chip->jumbo_pm_reg;
- dev->imp_port = chip->imp_port;
-- dev->cpu_port = chip->cpu_port;
- dev->num_vlans = chip->vlans;
- dev->num_arl_bins = chip->arl_bins;
- dev->num_arl_buckets = chip->arl_buckets;
-@@ -2617,13 +2597,6 @@ static int b53_switch_init(struct b53_de
- break;
- #endif
- }
-- } else if (dev->chip_id == BCM53115_DEVICE_ID) {
-- u64 strap_value;
--
-- b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value);
-- /* use second IMP port if GMII is enabled */
-- if (strap_value & SV_GMII_CTRL_115)
-- dev->cpu_port = 5;
- }
-
- dev->num_ports = fls(dev->enabled_ports);
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -124,7 +124,6 @@ struct b53_device {
- /* used ports mask */
- u16 enabled_ports;
- unsigned int imp_port;
-- unsigned int cpu_port;
-
- /* connect specific data */
- u8 current_page;
diff --git a/target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch b/target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch
deleted file mode 100644
index 7e4e9462e8..0000000000
--- a/target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From b4df02b562f4aa14ff6811f30e1b4d2159585c59 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 19 Sep 2021 18:28:15 +0200
-Subject: net: phy: at803x: add support for qca 8327 A variant internal phy
-
-For qca8327 internal phy there are 2 different switch variant with 2
-different phy id. Add this missing variant so the internal phy can be
-correctly identified and fixed.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 25 ++++++++++++++++++++-----
- 1 file changed, 20 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -150,7 +150,8 @@
- #define ATH8035_PHY_ID 0x004dd072
- #define AT8030_PHY_ID_MASK 0xffffffef
-
--#define QCA8327_PHY_ID 0x004dd034
-+#define QCA8327_A_PHY_ID 0x004dd033
-+#define QCA8327_B_PHY_ID 0x004dd034
- #define QCA8337_PHY_ID 0x004dd036
- #define QCA8K_PHY_ID_MASK 0xffffffff
-
-@@ -1411,10 +1412,23 @@ static struct phy_driver at803x_driver[]
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
- }, {
-- /* QCA8327 */
-- .phy_id = QCA8327_PHY_ID,
-+ /* QCA8327-A from switch QCA8327-AL1A */
-+ .phy_id = QCA8327_A_PHY_ID,
- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "QCA PHY 8327",
-+ .name = "QCA PHY 8327-A",
-+ /* PHY_GBIT_FEATURES */
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca83xx_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = at803x_get_sset_count,
-+ .get_strings = at803x_get_strings,
-+ .get_stats = at803x_get_stats,
-+}, {
-+ /* QCA8327-B from switch QCA8327-BL1A */
-+ .phy_id = QCA8327_B_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "QCA PHY 8327-B",
- /* PHY_GBIT_FEATURES */
- .probe = at803x_probe,
- .flags = PHY_IS_INTERNAL,
-@@ -1434,7 +1448,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
- { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
- { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
- { }
- };
-
diff --git a/target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch b/target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch
deleted file mode 100644
index 89aca23194..0000000000
--- a/target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 15b9df4ece17d084f14eb0ca1cf05f2ad497e425 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 19 Sep 2021 18:28:16 +0200
-Subject: net: phy: at803x: add resume/suspend function to qca83xx phy
-
-Add resume/suspend function to qca83xx internal phy.
-We can't use the at803x generic function as the documentation lacks of
-any support for WoL regs.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1411,6 +1411,8 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = at803x_get_sset_count,
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
- }, {
- /* QCA8327-A from switch QCA8327-AL1A */
- .phy_id = QCA8327_A_PHY_ID,
-@@ -1424,6 +1426,8 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = at803x_get_sset_count,
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
- }, {
- /* QCA8327-B from switch QCA8327-BL1A */
- .phy_id = QCA8327_B_PHY_ID,
-@@ -1437,6 +1441,8 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = at803x_get_sset_count,
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
- }, };
-
- module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch b/target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch
deleted file mode 100644
index 920bef24fd..0000000000
--- a/target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From d44fd8604a4ab92119adb35f05fd87612af722b5 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 19 Sep 2021 18:28:17 +0200
-Subject: net: phy: at803x: fix spacing and improve name for 83xx phy
-
-Fix spacing and improve name for 83xx phy following other phy in the
-same driver.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 60 ++++++++++++++++++++++++------------------------
- 1 file changed, 30 insertions(+), 30 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1400,47 +1400,47 @@ static struct phy_driver at803x_driver[]
- .config_aneg = at803x_config_aneg,
- }, {
- /* QCA8337 */
-- .phy_id = QCA8337_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "QCA PHY 8337",
-+ .phy_id = QCA8337_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8337 internal PHY",
- /* PHY_GBIT_FEATURES */
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca83xx_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = at803x_get_sset_count,
-- .get_strings = at803x_get_strings,
-- .get_stats = at803x_get_stats,
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca83xx_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = at803x_get_sset_count,
-+ .get_strings = at803x_get_strings,
-+ .get_stats = at803x_get_stats,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- }, {
- /* QCA8327-A from switch QCA8327-AL1A */
-- .phy_id = QCA8327_A_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "QCA PHY 8327-A",
-+ .phy_id = QCA8327_A_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8327-A internal PHY",
- /* PHY_GBIT_FEATURES */
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca83xx_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = at803x_get_sset_count,
-- .get_strings = at803x_get_strings,
-- .get_stats = at803x_get_stats,
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca83xx_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = at803x_get_sset_count,
-+ .get_strings = at803x_get_strings,
-+ .get_stats = at803x_get_stats,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- }, {
- /* QCA8327-B from switch QCA8327-BL1A */
-- .phy_id = QCA8327_B_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "QCA PHY 8327-B",
-+ .phy_id = QCA8327_B_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8327-B internal PHY",
- /* PHY_GBIT_FEATURES */
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca83xx_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = at803x_get_sset_count,
-- .get_strings = at803x_get_strings,
-- .get_stats = at803x_get_stats,
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca83xx_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = at803x_get_sset_count,
-+ .get_strings = at803x_get_strings,
-+ .get_stats = at803x_get_stats,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- }, };
diff --git a/target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch b/target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch
deleted file mode 100644
index 1029420ea9..0000000000
--- a/target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From ba3c01ee02ed0d821c9f241f179bbc9457542b8f Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:15 +0200
-Subject: net: phy: at803x: fix resume for QCA8327 phy
-
-From Documentation phy resume triggers phy reset and restart
-auto-negotiation. Add a dedicated function to wait reset to finish as
-it was notice a regression where port sometime are not reliable after a
-suspend/resume session. The reset wait logic is copied from phy_poll_reset.
-Add dedicated suspend function to use genphy_suspend only with QCA8337
-phy and set only additional debug settings for QCA8327. With more test
-it was reported that QCA8327 doesn't proprely support this mode and
-using this cause the unreliability of the switch ports, especially the
-malfunction of the port0.
-
-Fixes: 15b9df4ece17 ("net: phy: at803x: add resume/suspend function to qca83xx phy")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 69 +++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 63 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -92,9 +92,14 @@
- #define AT803X_DEBUG_REG_5 0x05
- #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
-
-+#define AT803X_DEBUG_REG_HIB_CTRL 0x0b
-+#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10)
-+#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
-+
- #define AT803X_DEBUG_REG_3C 0x3C
-
- #define AT803X_DEBUG_REG_3D 0x3D
-+#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
-
- #define AT803X_DEBUG_REG_1F 0x1F
- #define AT803X_DEBUG_PLL_ON BIT(2)
-@@ -1304,6 +1309,58 @@ static int qca83xx_config_init(struct ph
- return 0;
- }
-
-+static int qca83xx_resume(struct phy_device *phydev)
-+{
-+ int ret, val;
-+
-+ /* Skip reset if not suspended */
-+ if (!phydev->suspended)
-+ return 0;
-+
-+ /* Reinit the port, reset values set by suspend */
-+ qca83xx_config_init(phydev);
-+
-+ /* Reset the port on port resume */
-+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-+
-+ /* On resume from suspend the switch execute a reset and
-+ * restart auto-negotiation. Wait for reset to complete.
-+ */
-+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
-+ 50000, 600000, true);
-+ if (ret)
-+ return ret;
-+
-+ msleep(1);
-+
-+ return 0;
-+}
-+
-+static int qca83xx_suspend(struct phy_device *phydev)
-+{
-+ u16 mask = 0;
-+
-+ /* Only QCA8337 support actual suspend.
-+ * QCA8327 cause port unreliability when phy suspend
-+ * is set.
-+ */
-+ if (phydev->drv->phy_id == QCA8337_PHY_ID) {
-+ genphy_suspend(phydev);
-+ } else {
-+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-+ phy_modify(phydev, MII_BMCR, mask, 0);
-+ }
-+
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
-+ AT803X_DEBUG_GATE_CLK_IN1000, 0);
-+
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-+ AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
-+ AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
-+
-+ return 0;
-+}
-+
- static struct phy_driver at803x_driver[] = {
- {
- /* Qualcomm Atheros AR8035 */
-@@ -1411,8 +1468,8 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = at803x_get_sset_count,
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
-- .suspend = genphy_suspend,
-- .resume = genphy_resume,
-+ .suspend = qca83xx_suspend,
-+ .resume = qca83xx_resume,
- }, {
- /* QCA8327-A from switch QCA8327-AL1A */
- .phy_id = QCA8327_A_PHY_ID,
-@@ -1426,8 +1483,8 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = at803x_get_sset_count,
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
-- .suspend = genphy_suspend,
-- .resume = genphy_resume,
-+ .suspend = qca83xx_suspend,
-+ .resume = qca83xx_resume,
- }, {
- /* QCA8327-B from switch QCA8327-BL1A */
- .phy_id = QCA8327_B_PHY_ID,
-@@ -1441,8 +1498,8 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = at803x_get_sset_count,
- .get_strings = at803x_get_strings,
- .get_stats = at803x_get_stats,
-- .suspend = genphy_suspend,
-- .resume = genphy_resume,
-+ .suspend = qca83xx_suspend,
-+ .resume = qca83xx_resume,
- }, };
-
- module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch b/target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch
deleted file mode 100644
index 5813619c5c..0000000000
--- a/target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 1ca8311949aec5c9447645731ef1c6bc5bd71350 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:16 +0200
-Subject: net: phy: at803x: add DAC amplitude fix for 8327 phy
-
-QCA8327 internal phy require DAC amplitude adjustement set to +6% with
-100m speed. Also add additional define to report a change of the same
-reg in QCA8337. (different scope it does set 1000m voltage)
-Add link_change_notify function to set the proper amplitude adjustement
-on PHY_RUNNING state and disable on any other state.
-
-Fixes: b4df02b562f4 ("net: phy: at803x: add support for qca 8327 A variant internal phy")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 33 +++++++++++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -87,6 +87,8 @@
- #define AT803X_PSSR_MR_AN_COMPLETE 0x0200
-
- #define AT803X_DEBUG_REG_0 0x00
-+#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
-+#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
- #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
-
- #define AT803X_DEBUG_REG_5 0x05
-@@ -1306,9 +1308,37 @@ static int qca83xx_config_init(struct ph
- break;
- }
-
-+ /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
-+ * Disable on init and enable only with 100m speed following
-+ * qca original source code.
-+ */
-+ if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
-+ phydev->drv->phy_id == QCA8327_B_PHY_ID)
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+
- return 0;
- }
-
-+static void qca83xx_link_change_notify(struct phy_device *phydev)
-+{
-+ /* QCA8337 doesn't require DAC Amplitude adjustement */
-+ if (phydev->drv->phy_id == QCA8337_PHY_ID)
-+ return;
-+
-+ /* Set DAC Amplitude adjustment to +6% for 100m on link running */
-+ if (phydev->state == PHY_RUNNING) {
-+ if (phydev->speed == SPEED_100)
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+ QCA8327_DEBUG_MANU_CTRL_EN,
-+ QCA8327_DEBUG_MANU_CTRL_EN);
-+ } else {
-+ /* Reset DAC Amplitude adjustment */
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+ }
-+}
-+
- static int qca83xx_resume(struct phy_device *phydev)
- {
- int ret, val;
-@@ -1461,6 +1491,7 @@ static struct phy_driver at803x_driver[]
- .phy_id_mask = QCA8K_PHY_ID_MASK,
- .name = "Qualcomm Atheros 8337 internal PHY",
- /* PHY_GBIT_FEATURES */
-+ .link_change_notify = qca83xx_link_change_notify,
- .probe = at803x_probe,
- .flags = PHY_IS_INTERNAL,
- .config_init = qca83xx_config_init,
-@@ -1476,6 +1507,7 @@ static struct phy_driver at803x_driver[]
- .phy_id_mask = QCA8K_PHY_ID_MASK,
- .name = "Qualcomm Atheros 8327-A internal PHY",
- /* PHY_GBIT_FEATURES */
-+ .link_change_notify = qca83xx_link_change_notify,
- .probe = at803x_probe,
- .flags = PHY_IS_INTERNAL,
- .config_init = qca83xx_config_init,
-@@ -1491,6 +1523,7 @@ static struct phy_driver at803x_driver[]
- .phy_id_mask = QCA8K_PHY_ID_MASK,
- .name = "Qualcomm Atheros 8327-B internal PHY",
- /* PHY_GBIT_FEATURES */
-+ .link_change_notify = qca83xx_link_change_notify,
- .probe = at803x_probe,
- .flags = PHY_IS_INTERNAL,
- .config_init = qca83xx_config_init,
diff --git a/target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch b/target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch
deleted file mode 100644
index 9f880593f1..0000000000
--- a/target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 9d1c29b4028557a496be9c5eb2b4b86063700636 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:17 +0200
-Subject: net: phy: at803x: enable prefer master for 83xx internal phy
-
-From original QCA source code the port was set to prefer master as port
-type in 1000BASE-T mode. Apply the same settings also here.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1317,6 +1317,9 @@ static int qca83xx_config_init(struct ph
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
- QCA8327_DEBUG_MANU_CTRL_EN, 0);
-
-+ /* Following original QCA sourcecode set port to prefer master */
-+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch b/target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch
deleted file mode 100644
index 89e9b3f662..0000000000
--- a/target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 67999555ff42e91de7654488d9a7735bd9e84555 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:18 +0200
-Subject: net: phy: at803x: better describe debug regs
-
-Give a name to known debug regs from Documentation instead of using
-unknown hex values.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 30 +++++++++++++++---------------
- 1 file changed, 15 insertions(+), 15 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -86,12 +86,12 @@
- #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
- #define AT803X_PSSR_MR_AN_COMPLETE 0x0200
-
--#define AT803X_DEBUG_REG_0 0x00
-+#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00
- #define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
- #define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
- #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
-
--#define AT803X_DEBUG_REG_5 0x05
-+#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05
- #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
-
- #define AT803X_DEBUG_REG_HIB_CTRL 0x0b
-@@ -100,7 +100,7 @@
-
- #define AT803X_DEBUG_REG_3C 0x3C
-
--#define AT803X_DEBUG_REG_3D 0x3D
-+#define AT803X_DEBUG_REG_GREEN 0x3D
- #define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
-
- #define AT803X_DEBUG_REG_1F 0x1F
-@@ -284,25 +284,25 @@ static int at803x_read_page(struct phy_d
-
- static int at803x_enable_rx_delay(struct phy_device *phydev)
- {
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0,
- AT803X_DEBUG_RX_CLK_DLY_EN);
- }
-
- static int at803x_enable_tx_delay(struct phy_device *phydev)
- {
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0,
- AT803X_DEBUG_TX_CLK_DLY_EN);
- }
-
- static int at803x_disable_rx_delay(struct phy_device *phydev)
- {
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
- AT803X_DEBUG_RX_CLK_DLY_EN, 0);
- }
-
- static int at803x_disable_tx_delay(struct phy_device *phydev)
- {
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE,
- AT803X_DEBUG_TX_CLK_DLY_EN, 0);
- }
-
-@@ -1292,9 +1292,9 @@ static int qca83xx_config_init(struct ph
- switch (switch_revision) {
- case 1:
- /* For 100M waveform */
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
- /* Turn on Gigabit clock */
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
- break;
-
- case 2:
-@@ -1302,8 +1302,8 @@ static int qca83xx_config_init(struct ph
- fallthrough;
- case 4:
- phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
- break;
- }
-@@ -1314,7 +1314,7 @@ static int qca83xx_config_init(struct ph
- */
- if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
- phydev->drv->phy_id == QCA8327_B_PHY_ID)
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
- QCA8327_DEBUG_MANU_CTRL_EN, 0);
-
- /* Following original QCA sourcecode set port to prefer master */
-@@ -1332,12 +1332,12 @@ static void qca83xx_link_change_notify(s
- /* Set DAC Amplitude adjustment to +6% for 100m on link running */
- if (phydev->state == PHY_RUNNING) {
- if (phydev->speed == SPEED_100)
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
- QCA8327_DEBUG_MANU_CTRL_EN,
- QCA8327_DEBUG_MANU_CTRL_EN);
- } else {
- /* Reset DAC Amplitude adjustment */
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
- QCA8327_DEBUG_MANU_CTRL_EN, 0);
- }
- }
-@@ -1384,7 +1384,7 @@ static int qca83xx_suspend(struct phy_de
- phy_modify(phydev, MII_BMCR, mask, 0);
- }
-
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
- AT803X_DEBUG_GATE_CLK_IN1000, 0);
-
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
diff --git a/target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch b/target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch
deleted file mode 100644
index c8d424de38..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From d8b6f5bae6d3b648a67b6958cb98e4e97256d652 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:06 +0200
-Subject: dsa: qca8k: add mac_power_sel support
-
-Add missing mac power sel support needed for ipq8064/5 SoC that require
-1.8v for the internal regulator port instead of the default 1.5v.
-If other device needs this, consider adding a dedicated binding to
-support this.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 31 +++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 5 +++++
- 2 files changed, 36 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -951,6 +951,33 @@ qca8k_setup_of_rgmii_delay(struct qca8k_
- }
-
- static int
-+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
-+{
-+ u32 mask = 0;
-+ int ret = 0;
-+
-+ /* SoC specific settings for ipq8064.
-+ * If more device require this consider adding
-+ * a dedicated binding.
-+ */
-+ if (of_machine_is_compatible("qcom,ipq8064"))
-+ mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
-+
-+ /* SoC specific settings for ipq8065 */
-+ if (of_machine_is_compatible("qcom,ipq8065"))
-+ mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
-+
-+ if (mask) {
-+ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
-+ QCA8K_MAC_PWR_RGMII0_1_8V |
-+ QCA8K_MAC_PWR_RGMII1_1_8V,
-+ mask);
-+ }
-+
-+ return ret;
-+}
-+
-+static int
- qca8k_setup(struct dsa_switch *ds)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-@@ -979,6 +1006,10 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-+ ret = qca8k_setup_mac_pwr_sel(priv);
-+ if (ret)
-+ return ret;
-+
- /* Enable CPU Port */
- ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -100,6 +100,11 @@
- #define QCA8K_SGMII_MODE_CTRL_PHY (1 << 22)
- #define QCA8K_SGMII_MODE_CTRL_MAC (2 << 22)
-
-+/* MAC_PWR_SEL registers */
-+#define QCA8K_REG_MAC_PWR_SEL 0x0e4
-+#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18)
-+#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19)
-+
- /* EEE control registers */
- #define QCA8K_REG_EEE_CTRL 0x100
- #define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2)
diff --git a/target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch b/target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch
deleted file mode 100644
index bd768ec27d..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From fdbf35df9c091db9c46e57e9938e3f7a4f603a7c Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:07 +0200
-Subject: dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties
-
-Add names and descriptions of additional PORT0_PAD_CTRL properties.
-qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock
-phase to failling edge.
-
-Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -37,6 +37,10 @@ A CPU port node has the following option
- managed entity. See
- Documentation/devicetree/bindings/net/fixed-link.txt
- for details.
-+- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
-+ Mostly used in qca8327 with CPU port 0 set to
-+ sgmii.
-+- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
-
- For QCA8K the 'fixed-link' sub-node supports only the following properties:
-
diff --git a/target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch b/target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch
deleted file mode 100644
index e464452d82..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 6c43809bf1bee76c434e365a26546a92a5fbec14 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:08 +0200
-Subject: net: dsa: qca8k: add support for sgmii falling edge
-
-Add support for this in the qca8k driver. Also add support for SGMII
-rx/tx clock falling edge. This is only present for pad0, pad5 and
-pad6 have these bit reserved from Documentation. Add a comment that this
-is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and
-setting falling in port0 applies to both configuration with sgmii used
-for port0 or port6.
-
-Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 4 ++++
- 2 files changed, 67 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -978,6 +978,42 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
- }
-
- static int
-+qca8k_parse_port_config(struct qca8k_priv *priv)
-+{
-+ struct device_node *port_dn;
-+ phy_interface_t mode;
-+ struct dsa_port *dp;
-+ int port, ret;
-+
-+ /* We have 2 CPU port. Check them */
-+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+ /* Skip every other port */
-+ if (port != 0 && port != 6)
-+ continue;
-+
-+ dp = dsa_to_port(priv->ds, port);
-+ port_dn = dp->dn;
-+
-+ if (!of_device_is_available(port_dn))
-+ continue;
-+
-+ ret = of_get_phy_mode(port_dn, &mode);
-+ if (ret)
-+ continue;
-+
-+ if (mode == PHY_INTERFACE_MODE_SGMII) {
-+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-+ priv->sgmii_tx_clk_falling_edge = true;
-+
-+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-+ priv->sgmii_rx_clk_falling_edge = true;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_setup(struct dsa_switch *ds)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-@@ -990,6 +1026,11 @@ qca8k_setup(struct dsa_switch *ds)
- return -EINVAL;
- }
-
-+ /* Parse CPU port config to be later used in phy_link mac_config */
-+ ret = qca8k_parse_port_config(priv);
-+ if (ret)
-+ return ret;
-+
- mutex_init(&priv->reg_mutex);
-
- /* Start by setting up the register mapping */
-@@ -1274,6 +1315,28 @@ qca8k_phylink_mac_config(struct dsa_swit
- }
-
- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
-+
-+ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
-+ * falling edge is set writing in the PORT0 PAD reg
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8327 ||
-+ priv->switch_id == QCA8K_ID_QCA8337)
-+ reg = QCA8K_REG_PORT0_PAD_CTRL;
-+
-+ val = 0;
-+
-+ /* SGMII Clock phase configuration */
-+ if (priv->sgmii_rx_clk_falling_edge)
-+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
-+
-+ if (priv->sgmii_tx_clk_falling_edge)
-+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
-+
-+ if (val)
-+ ret = qca8k_rmw(priv, reg,
-+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
-+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
-+ val);
- break;
- default:
- dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -35,6 +35,8 @@
- #define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8)
- #define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8)
- #define QCA8K_REG_PORT0_PAD_CTRL 0x004
-+#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19)
-+#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18)
- #define QCA8K_REG_PORT5_PAD_CTRL 0x008
- #define QCA8K_REG_PORT6_PAD_CTRL 0x00c
- #define QCA8K_PORT_PAD_RGMII_EN BIT(26)
-@@ -260,6 +262,8 @@ struct qca8k_priv {
- u8 switch_revision;
- u8 rgmii_tx_delay;
- u8 rgmii_rx_delay;
-+ bool sgmii_rx_clk_falling_edge;
-+ bool sgmii_tx_clk_falling_edge;
- bool legacy_phy_port_mapping;
- struct regmap *regmap;
- struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch b/target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch
deleted file mode 100644
index 606ac0af3d..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 731d613338ec6de482053ffa3f71be2325b0f8eb Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:09 +0200
-Subject: dt-bindings: net: dsa: qca8k: Document support for CPU port 6
-
-The switch now support CPU port to be set 6 instead of be hardcoded to
-0. Document support for it and describe logic selection.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -29,7 +29,11 @@ the mdio MASTER is used as communication
- Don't use mixed external and internal mdio-bus configurations, as this is
- not supported by the hardware.
-
--The CPU port of this switch is always port 0.
-+This switch support 2 CPU port. Normally and advised configuration is with
-+CPU port set to port 0. It is also possible to set the CPU port to port 6
-+if the device requires it. The driver will configure the switch to the defined
-+port. With both CPU port declared the first CPU port is selected as primary
-+and the secondary CPU ignored.
-
- A CPU port node has the following optional node:
-
diff --git a/target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch b/target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch
deleted file mode 100644
index 320db8fa9f..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 3fcf734aa482487df83cf8f18608438fcf59127f Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:10 +0200
-Subject: net: dsa: qca8k: add support for cpu port 6
-
-Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
-ports. The original intention of this driver seems to be use the
-mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
-where device have connected only the CPU port 6. To skip the
-introduction of a new binding, rework the driver to address the
-secondary CPU port as primary and drop any reference of hardcoded port.
-With configuration of mac06 exchange, just skip the definition of port0
-and define the CPU port as a secondary. The driver will autoconfigure
-the switch to use that as the primary CPU port.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 51 ++++++++++++++++++++++++++++++++++---------------
- drivers/net/dsa/qca8k.h | 2 --
- 2 files changed, 36 insertions(+), 17 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
- return ret;
- }
-
-+static int qca8k_find_cpu_port(struct dsa_switch *ds)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Find the connected cpu port. Valid port are 0 or 6 */
-+ if (dsa_is_cpu_port(ds, 0))
-+ return 0;
-+
-+ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
-+
-+ if (dsa_is_cpu_port(ds, 6))
-+ return 6;
-+
-+ return -EINVAL;
-+}
-+
- static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
-@@ -1017,13 +1033,13 @@ static int
- qca8k_setup(struct dsa_switch *ds)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int ret, i;
-+ int cpu_port, ret, i;
- u32 mask;
-
-- /* Make sure that port 0 is the cpu port */
-- if (!dsa_is_cpu_port(ds, 0)) {
-- dev_err(priv->dev, "port 0 is not the CPU port");
-- return -EINVAL;
-+ cpu_port = qca8k_find_cpu_port(ds);
-+ if (cpu_port < 0) {
-+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
-+ return cpu_port;
- }
-
- /* Parse CPU port config to be later used in phy_link mac_config */
-@@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds)
- dev_warn(priv->dev, "mib init failed");
-
- /* Enable QCA header mode on the cpu port */
-- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
- if (ret) {
-@@ -1087,10 +1103,10 @@ qca8k_setup(struct dsa_switch *ds)
-
- /* Forward all unknown frames to CPU port for Linux processing */
- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
-- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
-- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
-- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
-+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
-+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
-+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
-+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
- if (ret)
- return ret;
-
-@@ -1098,7 +1114,7 @@ qca8k_setup(struct dsa_switch *ds)
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
- /* CPU port gets connected to all user ports of the switch */
- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
- if (ret)
- return ret;
-@@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds)
-
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
- QCA8K_PORT_LOOKUP_MEMBER,
-- BIT(QCA8K_CPU_PORT));
-+ BIT(cpu_port));
- if (ret)
- return ret;
-
-@@ -1616,9 +1632,12 @@ static int
- qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int port_mask = BIT(QCA8K_CPU_PORT);
-+ int port_mask, cpu_port;
- int i, ret;
-
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+ port_mask = BIT(cpu_port);
-+
- for (i = 1; i < QCA8K_NUM_PORTS; i++) {
- if (dsa_to_port(ds, i)->bridge_dev != br)
- continue;
-@@ -1645,7 +1664,9 @@ static void
- qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int i;
-+ int cpu_port, i;
-+
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-
- for (i = 1; i < QCA8K_NUM_PORTS; i++) {
- if (dsa_to_port(ds, i)->bridge_dev != br)
-@@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switc
- * this port
- */
- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT));
-+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
- }
-
- static int
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -24,8 +24,6 @@
-
- #define QCA8K_NUM_FDB_RECORDS 2048
-
--#define QCA8K_CPU_PORT 0
--
- #define QCA8K_PORT_VID_DEF 1
-
- /* Global control registers */
diff --git a/target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch b/target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch
deleted file mode 100644
index de201764f9..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch
+++ /dev/null
@@ -1,295 +0,0 @@
-From 5654ec78dd7e64b1e04777b24007344329e6a63b Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:11 +0200
-Subject: net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6
-
-Future proof commit. This switch have 2 CPU ports and one valid
-configuration is first CPU port set to sgmii and second CPU port set to
-rgmii-id. The current implementation detects delay only for CPU port
-zero set to rgmii and doesn't count any delay set in a secondary CPU
-port. Drop the current delay scan function and move it to the sgmii
-parser function to generalize and implicitly add support for secondary
-CPU port set to rgmii-id. Introduce new logic where delay is enabled
-also with internal delay binding declared and rgmii set as PHY mode.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 165 ++++++++++++++++++++++++------------------------
- drivers/net/dsa/qca8k.h | 10 ++-
- 2 files changed, 89 insertions(+), 86 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -889,68 +889,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
- }
-
- static int
--qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)
--{
-- struct device_node *port_dn;
-- phy_interface_t mode;
-- struct dsa_port *dp;
-- u32 val;
--
-- /* CPU port is already checked */
-- dp = dsa_to_port(priv->ds, 0);
--
-- port_dn = dp->dn;
--
-- /* Check if port 0 is set to the correct type */
-- of_get_phy_mode(port_dn, &mode);
-- if (mode != PHY_INTERFACE_MODE_RGMII_ID &&
-- mode != PHY_INTERFACE_MODE_RGMII_RXID &&
-- mode != PHY_INTERFACE_MODE_RGMII_TXID) {
-- return 0;
-- }
--
-- switch (mode) {
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val))
-- val = 2;
-- else
-- /* Switch regs accept value in ns, convert ps to ns */
-- val = val / 1000;
--
-- if (val > QCA8K_MAX_DELAY) {
-- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-- val = 3;
-- }
--
-- priv->rgmii_rx_delay = val;
-- /* Stop here if we need to check only for rx delay */
-- if (mode != PHY_INTERFACE_MODE_RGMII_ID)
-- break;
--
-- fallthrough;
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val))
-- val = 1;
-- else
-- /* Switch regs accept value in ns, convert ps to ns */
-- val = val / 1000;
--
-- if (val > QCA8K_MAX_DELAY) {
-- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-- val = 3;
-- }
--
-- priv->rgmii_tx_delay = val;
-- break;
-- default:
-- return 0;
-- }
--
-- return 0;
--}
--
--static int
- qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
- {
- u32 mask = 0;
-@@ -996,19 +934,21 @@ static int qca8k_find_cpu_port(struct ds
- static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
-+ int port, cpu_port_index = 0, ret;
- struct device_node *port_dn;
- phy_interface_t mode;
- struct dsa_port *dp;
-- int port, ret;
-+ u32 delay;
-
- /* We have 2 CPU port. Check them */
-- for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+ for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) {
- /* Skip every other port */
- if (port != 0 && port != 6)
- continue;
-
- dp = dsa_to_port(priv->ds, port);
- port_dn = dp->dn;
-+ cpu_port_index++;
-
- if (!of_device_is_available(port_dn))
- continue;
-@@ -1017,12 +957,54 @@ qca8k_parse_port_config(struct qca8k_pri
- if (ret)
- continue;
-
-- if (mode == PHY_INTERFACE_MODE_SGMII) {
-+ switch (mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ delay = 0;
-+
-+ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-+ /* Switch regs accept value in ns, convert ps to ns */
-+ delay = delay / 1000;
-+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_TXID)
-+ delay = 1;
-+
-+ if (delay > QCA8K_MAX_DELAY) {
-+ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-+ delay = 3;
-+ }
-+
-+ priv->rgmii_tx_delay[cpu_port_index] = delay;
-+
-+ delay = 0;
-+
-+ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
-+ /* Switch regs accept value in ns, convert ps to ns */
-+ delay = delay / 1000;
-+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+ delay = 2;
-+
-+ if (delay > QCA8K_MAX_DELAY) {
-+ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-+ delay = 3;
-+ }
-+
-+ priv->rgmii_rx_delay[cpu_port_index] = delay;
-+
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
- priv->sgmii_tx_clk_falling_edge = true;
-
- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
- priv->sgmii_rx_clk_falling_edge = true;
-+
-+ break;
-+ default:
-+ continue;
- }
- }
-
-@@ -1059,10 +1041,6 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-- ret = qca8k_setup_of_rgmii_delay(priv);
-- if (ret)
-- return ret;
--
- ret = qca8k_setup_mac_pwr_sel(priv);
- if (ret)
- return ret;
-@@ -1229,8 +1207,8 @@ qca8k_phylink_mac_config(struct dsa_swit
- const struct phylink_link_state *state)
- {
- struct qca8k_priv *priv = ds->priv;
-- u32 reg, val;
-- int ret;
-+ int cpu_port_index, ret;
-+ u32 reg, val, delay;
-
- switch (port) {
- case 0: /* 1st CPU port */
-@@ -1242,6 +1220,7 @@ qca8k_phylink_mac_config(struct dsa_swit
- return;
-
- reg = QCA8K_REG_PORT0_PAD_CTRL;
-+ cpu_port_index = QCA8K_CPU_PORT0;
- break;
- case 1:
- case 2:
-@@ -1260,6 +1239,7 @@ qca8k_phylink_mac_config(struct dsa_swit
- return;
-
- reg = QCA8K_REG_PORT6_PAD_CTRL;
-+ cpu_port_index = QCA8K_CPU_PORT6;
- break;
- default:
- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
-@@ -1274,23 +1254,40 @@ qca8k_phylink_mac_config(struct dsa_swit
-
- switch (state->interface) {
- case PHY_INTERFACE_MODE_RGMII:
-- /* RGMII mode means no delay so don't enable the delay */
-- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
-- break;
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_TXID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
-- /* RGMII_ID needs internal delay. This is enabled through
-- * PORT5_PAD_CTRL for all ports, rather than individual port
-- * registers
-+ val = QCA8K_PORT_PAD_RGMII_EN;
-+
-+ /* Delay can be declared in 3 different way.
-+ * Mode to rgmii and internal-delay standard binding defined
-+ * rgmii-id or rgmii-tx/rx phy mode set.
-+ * The parse logic set a delay different than 0 only when one
-+ * of the 3 different way is used. In all other case delay is
-+ * not enabled. With ID or TX/RXID delay is enabled and set
-+ * to the default and recommended value.
-+ */
-+ if (priv->rgmii_tx_delay[cpu_port_index]) {
-+ delay = priv->rgmii_tx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-+ }
-+
-+ if (priv->rgmii_rx_delay[cpu_port_index]) {
-+ delay = priv->rgmii_rx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-+ }
-+
-+ /* Set RGMII delay based on the selected values */
-+ qca8k_write(priv, reg, val);
-+
-+ /* QCA8337 requires to set rgmii rx delay for all ports.
-+ * This is enabled through PORT5_PAD_CTRL for all ports,
-+ * rather than individual port registers.
- */
-- qca8k_write(priv, reg,
-- QCA8K_PORT_PAD_RGMII_EN |
-- QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) |
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-- /* QCA8337 requires to set rgmii rx delay */
- if (priv->switch_id == QCA8K_ID_QCA8337)
- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -13,6 +13,7 @@
- #include <linux/gpio.h>
-
- #define QCA8K_NUM_PORTS 7
-+#define QCA8K_NUM_CPU_PORTS 2
- #define QCA8K_MAX_MTU 9000
-
- #define PHY_ID_QCA8327 0x004dd034
-@@ -255,13 +256,18 @@ struct qca8k_match_data {
- u8 id;
- };
-
-+enum {
-+ QCA8K_CPU_PORT0,
-+ QCA8K_CPU_PORT6,
-+};
-+
- struct qca8k_priv {
- u8 switch_id;
- u8 switch_revision;
-- u8 rgmii_tx_delay;
-- u8 rgmii_rx_delay;
- bool sgmii_rx_clk_falling_edge;
- bool sgmii_tx_clk_falling_edge;
-+ u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-+ u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
- bool legacy_phy_port_mapping;
- struct regmap *regmap;
- struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch b/target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch
deleted file mode 100644
index 8abd264e79..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 13ad5ccc093ff448b99ac7e138e91e78796adb48 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:12 +0200
-Subject: dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll
-
-Document qca,sgmii-enable-pll binding used in the CPU nodes to
-enable SGMII PLL on MAC config.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -45,6 +45,16 @@ A CPU port node has the following option
- Mostly used in qca8327 with CPU port 0 set to
- sgmii.
- - qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
-+- qca,sgmii-enable-pll : For SGMII CPU port, explicitly enable PLL, TX and RX
-+ chain along with Signal Detection.
-+ This should NOT be enabled for qca8327. If enabled with
-+ qca8327 the sgmii port won't correctly init and an err
-+ is printed.
-+ This can be required for qca8337 switch with revision 2.
-+ A warning is displayed when used with revision greater
-+ 2.
-+ With CPU port set to sgmii and qca8337 it is advised
-+ to set this unless a communication problem is observed.
-
- For QCA8K the 'fixed-link' sub-node supports only the following properties:
-
diff --git a/target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch b/target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch
deleted file mode 100644
index 2b5a84a1b0..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From bbc4799e8bb6c397e3b3fec13de68e179f5db9ff Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:13 +0200
-Subject: net: dsa: qca8k: add explicit SGMII PLL enable
-
-Support enabling PLL on the SGMII CPU port. Some device require this
-special configuration or no traffic is transmitted and the switch
-doesn't work at all. A dedicated binding is added to the CPU node
-port to apply the correct reg on mac config.
-Fail to correctly configure sgmii with qca8327 switch and warn if pll is
-used on qca8337 with a revision greater than 1.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 19 +++++++++++++++++--
- drivers/net/dsa/qca8k.h | 1 +
- 2 files changed, 18 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1002,6 +1002,18 @@ qca8k_parse_port_config(struct qca8k_pri
- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
- priv->sgmii_rx_clk_falling_edge = true;
-
-+ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
-+ priv->sgmii_enable_pll = true;
-+
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
-+ priv->sgmii_enable_pll = false;
-+ }
-+
-+ if (priv->switch_revision < 2)
-+ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
-+ }
-+
- break;
- default:
- continue;
-@@ -1312,8 +1324,11 @@ qca8k_phylink_mac_config(struct dsa_swit
- if (ret)
- return;
-
-- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-- QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
-+ val |= QCA8K_SGMII_EN_SD;
-+
-+ if (priv->sgmii_enable_pll)
-+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-+ QCA8K_SGMII_EN_TX;
-
- if (dsa_is_cpu_port(ds, port)) {
- /* CPU port, we're talking to the CPU MAC, be a PHY */
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -266,6 +266,7 @@ struct qca8k_priv {
- u8 switch_revision;
- bool sgmii_rx_clk_falling_edge;
- bool sgmii_tx_clk_falling_edge;
-+ bool sgmii_enable_pll;
- u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
- u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
- bool legacy_phy_port_mapping;
diff --git a/target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch b/target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch
deleted file mode 100644
index 38dc954e8c..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 924087c5c3d41553700b0eb83ca2a53b91643dca Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:14 +0200
-Subject: dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding
-
-Document new binding qca,ignore-power-on-sel used to ignore
-power on strapping and use sw regs instead.
-Document qca,led-open.drain to set led to open drain mode, the
-qca,ignore-power-on-sel is mandatory with this enabled or an error will
-be reported.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -13,6 +13,17 @@ Required properties:
- Optional properties:
-
- - reset-gpios: GPIO to be used to reset the whole device
-+- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
-+ drain or eeprom presence. This is needed for broken
-+ devices that have wrong configuration or when the oem
-+ decided to not use pin strapping and fallback to sw
-+ regs.
-+- qca,led-open-drain: Set leds to open-drain mode. This requires the
-+ qca,ignore-power-on-sel to be set or the driver will fail
-+ to probe. This is needed if the oem doesn't use pin
-+ strapping to set this mode and prefers to set it using sw
-+ regs. The pin strapping related to led open drain mode is
-+ the pin B68 for QCA832x and B49 for QCA833x
-
- Subnodes:
-
diff --git a/target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch b/target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch
deleted file mode 100644
index aa5d92a4fd..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 362bb238d8bf1470424214a8a5968d9c6cce68fa Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:15 +0200
-Subject: net: dsa: qca8k: add support for pws config reg
-
-Some qca8327 switch require to force the ignore of power on sel
-strapping. Some switch require to set the led open drain mode in regs
-instead of using strapping. While most of the device implements this
-using the correct way using pin strapping, there are still some broken
-device that require to be set using sw regs.
-Introduce a new binding and support these special configuration.
-As led open drain require to ignore pin strapping to work, the probe
-fails with EINVAL error with incorrect configuration.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 39 +++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 6 ++++++
- 2 files changed, 45 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -932,6 +932,41 @@ static int qca8k_find_cpu_port(struct ds
- }
-
- static int
-+qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
-+{
-+ struct device_node *node = priv->dev->of_node;
-+ u32 val = 0;
-+ int ret;
-+
-+ /* QCA8327 require to set to the correct mode.
-+ * His bigger brother QCA8328 have the 172 pin layout.
-+ * Should be applied by default but we set this just to make sure.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
-+ QCA8327_PWS_PACKAGE148_EN);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
-+ val |= QCA8K_PWS_POWER_ON_SEL;
-+
-+ if (of_property_read_bool(node, "qca,led-open-drain")) {
-+ if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
-+ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
-+ return -EINVAL;
-+ }
-+
-+ val |= QCA8K_PWS_LED_OPEN_EN_CSR;
-+ }
-+
-+ return qca8k_rmw(priv, QCA8K_REG_PWS,
-+ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
-+ val);
-+}
-+
-+static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
- int port, cpu_port_index = 0, ret;
-@@ -1053,6 +1088,10 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-+ ret = qca8k_setup_of_pws_reg(priv);
-+ if (ret)
-+ return ret;
-+
- ret = qca8k_setup_mac_pwr_sel(priv);
- if (ret)
- return ret;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -46,6 +46,12 @@
- #define QCA8K_MAX_DELAY 3
- #define QCA8K_PORT_PAD_SGMII_EN BIT(7)
- #define QCA8K_REG_PWS 0x010
-+#define QCA8K_PWS_POWER_ON_SEL BIT(31)
-+/* This reg is only valid for QCA832x and toggle the package
-+ * type from 176 pin (by default) to 148 pin used on QCA8327
-+ */
-+#define QCA8327_PWS_PACKAGE148_EN BIT(30)
-+#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24)
- #define QCA8K_PWS_SERDES_AEN_DIS BIT(7)
- #define QCA8K_REG_MODULE_EN 0x030
- #define QCA8K_MODULE_EN_MIB BIT(0)
diff --git a/target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch b/target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch
deleted file mode 100644
index 1bfb00c5b2..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From ed7988d77fbfb79366b68f9e7fa60a6080da23d4 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:16 +0200
-Subject: dt-bindings: net: dsa: qca8k: document support for qca8328
-
-QCA8328 is the bigger brother of qca8327. Document the new compatible
-binding and add some information to understand the various switch
-compatible.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -3,9 +3,10 @@
- Required properties:
-
- - compatible: should be one of:
-- "qca,qca8327"
-- "qca,qca8334"
-- "qca,qca8337"
-+ "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
-+ "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
-+ "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
-+ "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
-
- - #size-cells: must be 0
- - #address-cells: must be 1
diff --git a/target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch b/target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch
deleted file mode 100644
index b300621e63..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From f477d1c8bdbef4f400718238e350f16f521d2a3e Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:17 +0200
-Subject: net: dsa: qca8k: add support for QCA8328
-
-QCA8328 switch is the bigger brother of the qca8327. Same regs different
-chip. Change the function to set the correct pin layout and introduce a
-new match_data to differentiate the 2 switch as they have the same ID
-and their internal PHY have the same ID.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 19 ++++++++++++++++---
- drivers/net/dsa/qca8k.h | 1 +
- 2 files changed, 17 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -935,6 +935,7 @@ static int
- qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
- {
- struct device_node *node = priv->dev->of_node;
-+ const struct qca8k_match_data *data;
- u32 val = 0;
- int ret;
-
-@@ -943,8 +944,14 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
- * Should be applied by default but we set this just to make sure.
- */
- if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ data = of_device_get_match_data(priv->dev);
-+
-+ /* Set the correct package of 148 pin for QCA8327 */
-+ if (data->reduced_package)
-+ val |= QCA8327_PWS_PACKAGE148_EN;
-+
- ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
-- QCA8327_PWS_PACKAGE148_EN);
-+ val);
- if (ret)
- return ret;
- }
-@@ -2124,7 +2131,12 @@ static int qca8k_resume(struct device *d
- static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
- qca8k_suspend, qca8k_resume);
-
--static const struct qca8k_match_data qca832x = {
-+static const struct qca8k_match_data qca8327 = {
-+ .id = QCA8K_ID_QCA8327,
-+ .reduced_package = true,
-+};
-+
-+static const struct qca8k_match_data qca8328 = {
- .id = QCA8K_ID_QCA8327,
- };
-
-@@ -2133,7 +2145,8 @@ static const struct qca8k_match_data qca
- };
-
- static const struct of_device_id qca8k_of_match[] = {
-- { .compatible = "qca,qca8327", .data = &qca832x },
-+ { .compatible = "qca,qca8327", .data = &qca8327 },
-+ { .compatible = "qca,qca8328", .data = &qca8328 },
- { .compatible = "qca,qca8334", .data = &qca833x },
- { .compatible = "qca,qca8337", .data = &qca833x },
- { /* sentinel */ },
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -260,6 +260,7 @@ struct ar8xxx_port_status {
-
- struct qca8k_match_data {
- u8 id;
-+ bool reduced_package;
- };
-
- enum {
diff --git a/target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch b/target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch
deleted file mode 100644
index 27f94dca02..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch
+++ /dev/null
@@ -1,159 +0,0 @@
-From cef08115846e581f80ff99abf7bf218da1840616 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:18 +0200
-Subject: net: dsa: qca8k: set internal delay also for sgmii
-
-QCA original code report port instability and sa that SGMII also require
-to set internal delay. Generalize the rgmii delay function and apply the
-advised value if they are not defined in DT.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 88 +++++++++++++++++++++++++++++++++----------------
- drivers/net/dsa/qca8k.h | 2 ++
- 2 files changed, 62 insertions(+), 28 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1004,6 +1004,7 @@ qca8k_parse_port_config(struct qca8k_pri
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_TXID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_SGMII:
- delay = 0;
-
- if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-@@ -1036,8 +1037,13 @@ qca8k_parse_port_config(struct qca8k_pri
-
- priv->rgmii_rx_delay[cpu_port_index] = delay;
-
-- break;
-- case PHY_INTERFACE_MODE_SGMII:
-+ /* Skip sgmii parsing for rgmii* mode */
-+ if (mode == PHY_INTERFACE_MODE_RGMII ||
-+ mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_TXID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+ break;
-+
- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
- priv->sgmii_tx_clk_falling_edge = true;
-
-@@ -1261,12 +1267,53 @@ qca8k_setup(struct dsa_switch *ds)
- }
-
- static void
-+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
-+ u32 reg)
-+{
-+ u32 delay, val = 0;
-+ int ret;
-+
-+ /* Delay can be declared in 3 different way.
-+ * Mode to rgmii and internal-delay standard binding defined
-+ * rgmii-id or rgmii-tx/rx phy mode set.
-+ * The parse logic set a delay different than 0 only when one
-+ * of the 3 different way is used. In all other case delay is
-+ * not enabled. With ID or TX/RXID delay is enabled and set
-+ * to the default and recommended value.
-+ */
-+ if (priv->rgmii_tx_delay[cpu_port_index]) {
-+ delay = priv->rgmii_tx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-+ }
-+
-+ if (priv->rgmii_rx_delay[cpu_port_index]) {
-+ delay = priv->rgmii_rx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-+ }
-+
-+ /* Set RGMII delay based on the selected values */
-+ ret = qca8k_rmw(priv, reg,
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
-+ val);
-+ if (ret)
-+ dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
-+ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
-+}
-+
-+static void
- qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- const struct phylink_link_state *state)
- {
- struct qca8k_priv *priv = ds->priv;
- int cpu_port_index, ret;
-- u32 reg, val, delay;
-+ u32 reg, val;
-
- switch (port) {
- case 0: /* 1st CPU port */
-@@ -1315,32 +1362,10 @@ qca8k_phylink_mac_config(struct dsa_swit
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_TXID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
-- val = QCA8K_PORT_PAD_RGMII_EN;
--
-- /* Delay can be declared in 3 different way.
-- * Mode to rgmii and internal-delay standard binding defined
-- * rgmii-id or rgmii-tx/rx phy mode set.
-- * The parse logic set a delay different than 0 only when one
-- * of the 3 different way is used. In all other case delay is
-- * not enabled. With ID or TX/RXID delay is enabled and set
-- * to the default and recommended value.
-- */
-- if (priv->rgmii_tx_delay[cpu_port_index]) {
-- delay = priv->rgmii_tx_delay[cpu_port_index];
--
-- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-- }
--
-- if (priv->rgmii_rx_delay[cpu_port_index]) {
-- delay = priv->rgmii_rx_delay[cpu_port_index];
--
-- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-- }
-+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
-
-- /* Set RGMII delay based on the selected values */
-- qca8k_write(priv, reg, val);
-+ /* Configure rgmii delay */
-+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-
- /* QCA8337 requires to set rgmii rx delay for all ports.
- * This is enabled through PORT5_PAD_CTRL for all ports,
-@@ -1411,6 +1436,13 @@ qca8k_phylink_mac_config(struct dsa_swit
- QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
- val);
-+
-+ /* From original code is reported port instability as SGMII also
-+ * require delay set. Apply advised values here or take them from DT.
-+ */
-+ if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-+
- break;
- default:
- dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -39,7 +39,9 @@
- #define QCA8K_REG_PORT5_PAD_CTRL 0x008
- #define QCA8K_REG_PORT6_PAD_CTRL 0x00c
- #define QCA8K_PORT_PAD_RGMII_EN BIT(26)
-+#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22)
- #define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) ((x) << 22)
-+#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20)
- #define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) ((x) << 20)
- #define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25)
- #define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
diff --git a/target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch b/target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch
deleted file mode 100644
index b991798c87..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From fd0bb28c547f7c8affb1691128cece38f5b626a1 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:19 +0200
-Subject: net: dsa: qca8k: move port config to dedicated struct
-
-Move ports related config to dedicated struct to keep things organized.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 26 +++++++++++++-------------
- drivers/net/dsa/qca8k.h | 10 +++++++---
- 2 files changed, 20 insertions(+), 16 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1019,7 +1019,7 @@ qca8k_parse_port_config(struct qca8k_pri
- delay = 3;
- }
-
-- priv->rgmii_tx_delay[cpu_port_index] = delay;
-+ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
-
- delay = 0;
-
-@@ -1035,7 +1035,7 @@ qca8k_parse_port_config(struct qca8k_pri
- delay = 3;
- }
-
-- priv->rgmii_rx_delay[cpu_port_index] = delay;
-+ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
-
- /* Skip sgmii parsing for rgmii* mode */
- if (mode == PHY_INTERFACE_MODE_RGMII ||
-@@ -1045,17 +1045,17 @@ qca8k_parse_port_config(struct qca8k_pri
- break;
-
- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-- priv->sgmii_tx_clk_falling_edge = true;
-+ priv->ports_config.sgmii_tx_clk_falling_edge = true;
-
- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-- priv->sgmii_rx_clk_falling_edge = true;
-+ priv->ports_config.sgmii_rx_clk_falling_edge = true;
-
- if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
-- priv->sgmii_enable_pll = true;
-+ priv->ports_config.sgmii_enable_pll = true;
-
- if (priv->switch_id == QCA8K_ID_QCA8327) {
- dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
-- priv->sgmii_enable_pll = false;
-+ priv->ports_config.sgmii_enable_pll = false;
- }
-
- if (priv->switch_revision < 2)
-@@ -1281,15 +1281,15 @@ qca8k_mac_config_setup_internal_delay(st
- * not enabled. With ID or TX/RXID delay is enabled and set
- * to the default and recommended value.
- */
-- if (priv->rgmii_tx_delay[cpu_port_index]) {
-- delay = priv->rgmii_tx_delay[cpu_port_index];
-+ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
-+ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
-
- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
- }
-
-- if (priv->rgmii_rx_delay[cpu_port_index]) {
-- delay = priv->rgmii_rx_delay[cpu_port_index];
-+ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
-+ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
-
- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-@@ -1397,7 +1397,7 @@ qca8k_phylink_mac_config(struct dsa_swit
-
- val |= QCA8K_SGMII_EN_SD;
-
-- if (priv->sgmii_enable_pll)
-+ if (priv->ports_config.sgmii_enable_pll)
- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
- QCA8K_SGMII_EN_TX;
-
-@@ -1425,10 +1425,10 @@ qca8k_phylink_mac_config(struct dsa_swit
- val = 0;
-
- /* SGMII Clock phase configuration */
-- if (priv->sgmii_rx_clk_falling_edge)
-+ if (priv->ports_config.sgmii_rx_clk_falling_edge)
- val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
-
-- if (priv->sgmii_tx_clk_falling_edge)
-+ if (priv->ports_config.sgmii_tx_clk_falling_edge)
- val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
-
- if (val)
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -270,15 +270,19 @@ enum {
- QCA8K_CPU_PORT6,
- };
-
--struct qca8k_priv {
-- u8 switch_id;
-- u8 switch_revision;
-+struct qca8k_ports_config {
- bool sgmii_rx_clk_falling_edge;
- bool sgmii_tx_clk_falling_edge;
- bool sgmii_enable_pll;
- u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
- u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-+};
-+
-+struct qca8k_priv {
-+ u8 switch_id;
-+ u8 switch_revision;
- bool legacy_phy_port_mapping;
-+ struct qca8k_ports_config ports_config;
- struct regmap *regmap;
- struct mii_bus *bus;
- struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch b/target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch
deleted file mode 100644
index f7cb514176..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From e52073a8e3086046a098b8a7cbeb282ff0cdb424 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:20 +0200
-Subject: dt-bindings: net: ipq8064-mdio: fix warning with new qca8k switch
-
-Fix warning now that we have qca8k switch Documentation using yaml.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
-+++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
-@@ -51,6 +51,9 @@ examples:
- switch@10 {
- compatible = "qca,qca8337";
- reg = <0x10>;
-- /* ... */
-+
-+ ports {
-+ /* ... */
-+ };
- };
- };
diff --git a/target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch b/target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch
deleted file mode 100644
index b9bce97dd3..0000000000
--- a/target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch
+++ /dev/null
@@ -1,631 +0,0 @@
-From d291fbb8245d5ba04979fed85575860a5cea7196 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:21 +0200
-Subject: dt-bindings: net: dsa: qca8k: convert to YAML schema
-
-Convert the qca8k bindings to YAML format.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Co-developed-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../devicetree/bindings/net/dsa/qca8k.txt | 245 --------------
- .../devicetree/bindings/net/dsa/qca8k.yaml | 362 +++++++++++++++++++++
- 2 files changed, 362 insertions(+), 245 deletions(-)
- delete mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.txt
- create mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.yaml
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ /dev/null
-@@ -1,245 +0,0 @@
--* Qualcomm Atheros QCA8xxx switch family
--
--Required properties:
--
--- compatible: should be one of:
-- "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
-- "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
-- "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
-- "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
--
--- #size-cells: must be 0
--- #address-cells: must be 1
--
--Optional properties:
--
--- reset-gpios: GPIO to be used to reset the whole device
--- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
-- drain or eeprom presence. This is needed for broken
-- devices that have wrong configuration or when the oem
-- decided to not use pin strapping and fallback to sw
-- regs.
--- qca,led-open-drain: Set leds to open-drain mode. This requires the
-- qca,ignore-power-on-sel to be set or the driver will fail
-- to probe. This is needed if the oem doesn't use pin
-- strapping to set this mode and prefers to set it using sw
-- regs. The pin strapping related to led open drain mode is
-- the pin B68 for QCA832x and B49 for QCA833x
--
--Subnodes:
--
--The integrated switch subnode should be specified according to the binding
--described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
--mdio-bus each subnode describing a port needs to have a valid phandle
--referencing the internal PHY it is connected to. This is because there's no
--N:N mapping of port and PHY id.
--To declare the internal mdio-bus configuration, declare a mdio node in the
--switch node and declare the phandle for the port referencing the internal
--PHY is connected to. In this config a internal mdio-bus is registered and
--the mdio MASTER is used as communication.
--
--Don't use mixed external and internal mdio-bus configurations, as this is
--not supported by the hardware.
--
--This switch support 2 CPU port. Normally and advised configuration is with
--CPU port set to port 0. It is also possible to set the CPU port to port 6
--if the device requires it. The driver will configure the switch to the defined
--port. With both CPU port declared the first CPU port is selected as primary
--and the secondary CPU ignored.
--
--A CPU port node has the following optional node:
--
--- fixed-link : Fixed-link subnode describing a link to a non-MDIO
-- managed entity. See
-- Documentation/devicetree/bindings/net/fixed-link.txt
-- for details.
--- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
-- Mostly used in qca8327 with CPU port 0 set to
-- sgmii.
--- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
--- qca,sgmii-enable-pll : For SGMII CPU port, explicitly enable PLL, TX and RX
-- chain along with Signal Detection.
-- This should NOT be enabled for qca8327. If enabled with
-- qca8327 the sgmii port won't correctly init and an err
-- is printed.
-- This can be required for qca8337 switch with revision 2.
-- A warning is displayed when used with revision greater
-- 2.
-- With CPU port set to sgmii and qca8337 it is advised
-- to set this unless a communication problem is observed.
--
--For QCA8K the 'fixed-link' sub-node supports only the following properties:
--
--- 'speed' (integer, mandatory), to indicate the link speed. Accepted
-- values are 10, 100 and 1000
--- 'full-duplex' (boolean, optional), to indicate that full duplex is
-- used. When absent, half duplex is assumed.
--
--Examples:
--
--for the external mdio-bus configuration:
--
-- &mdio0 {
-- phy_port1: phy@0 {
-- reg = <0>;
-- };
--
-- phy_port2: phy@1 {
-- reg = <1>;
-- };
--
-- phy_port3: phy@2 {
-- reg = <2>;
-- };
--
-- phy_port4: phy@3 {
-- reg = <3>;
-- };
--
-- phy_port5: phy@4 {
-- reg = <4>;
-- };
--
-- switch@10 {
-- compatible = "qca,qca8337";
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
-- reg = <0x10>;
--
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
-- port@0 {
-- reg = <0>;
-- label = "cpu";
-- ethernet = <&gmac1>;
-- phy-mode = "rgmii";
-- fixed-link {
-- speed = 1000;
-- full-duplex;
-- };
-- };
--
-- port@1 {
-- reg = <1>;
-- label = "lan1";
-- phy-handle = <&phy_port1>;
-- };
--
-- port@2 {
-- reg = <2>;
-- label = "lan2";
-- phy-handle = <&phy_port2>;
-- };
--
-- port@3 {
-- reg = <3>;
-- label = "lan3";
-- phy-handle = <&phy_port3>;
-- };
--
-- port@4 {
-- reg = <4>;
-- label = "lan4";
-- phy-handle = <&phy_port4>;
-- };
--
-- port@5 {
-- reg = <5>;
-- label = "wan";
-- phy-handle = <&phy_port5>;
-- };
-- };
-- };
-- };
--
--for the internal master mdio-bus configuration:
--
-- &mdio0 {
-- switch@10 {
-- compatible = "qca,qca8337";
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
-- reg = <0x10>;
--
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- port@0 {
-- reg = <0>;
-- label = "cpu";
-- ethernet = <&gmac1>;
-- phy-mode = "rgmii";
-- fixed-link {
-- speed = 1000;
-- full-duplex;
-- };
-- };
--
-- port@1 {
-- reg = <1>;
-- label = "lan1";
-- phy-mode = "internal";
-- phy-handle = <&phy_port1>;
-- };
--
-- port@2 {
-- reg = <2>;
-- label = "lan2";
-- phy-mode = "internal";
-- phy-handle = <&phy_port2>;
-- };
--
-- port@3 {
-- reg = <3>;
-- label = "lan3";
-- phy-mode = "internal";
-- phy-handle = <&phy_port3>;
-- };
--
-- port@4 {
-- reg = <4>;
-- label = "lan4";
-- phy-mode = "internal";
-- phy-handle = <&phy_port4>;
-- };
--
-- port@5 {
-- reg = <5>;
-- label = "wan";
-- phy-mode = "internal";
-- phy-handle = <&phy_port5>;
-- };
-- };
--
-- mdio {
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- phy_port1: phy@0 {
-- reg = <0>;
-- };
--
-- phy_port2: phy@1 {
-- reg = <1>;
-- };
--
-- phy_port3: phy@2 {
-- reg = <2>;
-- };
--
-- phy_port4: phy@3 {
-- reg = <3>;
-- };
--
-- phy_port5: phy@4 {
-- reg = <4>;
-- };
-- };
-- };
-- };
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml
-@@ -0,0 +1,362 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/dsa/qca8k.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm Atheros QCA83xx switch family
-+
-+maintainers:
-+ - John Crispin <john@phrozen.org>
-+
-+description:
-+ If the QCA8K switch is connect to an SoC's external mdio-bus, each subnode
-+ describing a port needs to have a valid phandle referencing the internal PHY
-+ it is connected to. This is because there is no N:N mapping of port and PHY
-+ ID. To declare the internal mdio-bus configuration, declare an MDIO node in
-+ the switch node and declare the phandle for the port, referencing the internal
-+ PHY it is connected to. In this config, an internal mdio-bus is registered and
-+ the MDIO master is used for communication. Mixed external and internal
-+ mdio-bus configurations are not supported by the hardware.
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - enum:
-+ - qca,qca8327
-+ - qca,qca8328
-+ - qca,qca8334
-+ - qca,qca8337
-+ description: |
-+ qca,qca8328: referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
-+ qca,qca8327: referenced as AR8327(N)-AL1A DR-QFN 148 pin package
-+ qca,qca8334: referenced as QCA8334-AL3C QFN 88 pin package
-+ qca,qca8337: referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
-+
-+ reg:
-+ maxItems: 1
-+
-+ reset-gpios:
-+ description:
-+ GPIO to be used to reset the whole device
-+ maxItems: 1
-+
-+ qca,ignore-power-on-sel:
-+ $ref: /schemas/types.yaml#/definitions/flag
-+ description:
-+ Ignore power-on pin strapping to configure LED open-drain or EEPROM
-+ presence. This is needed for devices with incorrect configuration or when
-+ the OEM has decided not to use pin strapping and falls back to SW regs.
-+
-+ qca,led-open-drain:
-+ $ref: /schemas/types.yaml#/definitions/flag
-+ description:
-+ Set LEDs to open-drain mode. This requires the qca,ignore-power-on-sel to
-+ be set, otherwise the driver will fail at probe. This is required if the
-+ OEM does not use pin strapping to set this mode and prefers to set it
-+ using SW regs. The pin strappings related to LED open-drain mode are
-+ B68 on the QCA832x and B49 on the QCA833x.
-+
-+ mdio:
-+ type: object
-+ description: Qca8k switch have an internal mdio to access switch port.
-+ If this is not present, the legacy mapping is used and the
-+ internal mdio access is used.
-+ With the legacy mapping the reg corresponding to the internal
-+ mdio is the switch reg with an offset of -1.
-+
-+ properties:
-+ '#address-cells':
-+ const: 1
-+ '#size-cells':
-+ const: 0
-+
-+ patternProperties:
-+ "^(ethernet-)?phy@[0-4]$":
-+ type: object
-+
-+ allOf:
-+ - $ref: "http://devicetree.org/schemas/net/mdio.yaml#"
-+
-+ properties:
-+ reg:
-+ maxItems: 1
-+
-+ required:
-+ - reg
-+
-+patternProperties:
-+ "^(ethernet-)?ports$":
-+ type: object
-+ properties:
-+ '#address-cells':
-+ const: 1
-+ '#size-cells':
-+ const: 0
-+
-+ patternProperties:
-+ "^(ethernet-)?port@[0-6]$":
-+ type: object
-+ description: Ethernet switch ports
-+
-+ properties:
-+ reg:
-+ description: Port number
-+
-+ label:
-+ description:
-+ Describes the label associated with this port, which will become
-+ the netdev name
-+ $ref: /schemas/types.yaml#/definitions/string
-+
-+ link:
-+ description:
-+ Should be a list of phandles to other switch's DSA port. This
-+ port is used as the outgoing port towards the phandle ports. The
-+ full routing information must be given, not just the one hop
-+ routes to neighbouring switches
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+
-+ ethernet:
-+ description:
-+ Should be a phandle to a valid Ethernet device node. This host
-+ device is what the switch port is connected to
-+ $ref: /schemas/types.yaml#/definitions/phandle
-+
-+ phy-handle: true
-+
-+ phy-mode: true
-+
-+ fixed-link: true
-+
-+ mac-address: true
-+
-+ sfp: true
-+
-+ qca,sgmii-rxclk-falling-edge:
-+ $ref: /schemas/types.yaml#/definitions/flag
-+ description:
-+ Set the receive clock phase to falling edge. Mostly commonly used on
-+ the QCA8327 with CPU port 0 set to SGMII.
-+
-+ qca,sgmii-txclk-falling-edge:
-+ $ref: /schemas/types.yaml#/definitions/flag
-+ description:
-+ Set the transmit clock phase to falling edge.
-+
-+ qca,sgmii-enable-pll:
-+ $ref: /schemas/types.yaml#/definitions/flag
-+ description:
-+ For SGMII CPU port, explicitly enable PLL, TX and RX chain along with
-+ Signal Detection. On the QCA8327 this should not be enabled, otherwise
-+ the SGMII port will not initialize. When used on the QCA8337, revision 3
-+ or greater, a warning will be displayed. When the CPU port is set to
-+ SGMII on the QCA8337, it is advised to set this unless a communication
-+ issue is observed.
-+
-+ required:
-+ - reg
-+
-+ additionalProperties: false
-+
-+oneOf:
-+ - required:
-+ - ports
-+ - required:
-+ - ethernet-ports
-+
-+required:
-+ - compatible
-+ - reg
-+
-+additionalProperties: true
-+
-+examples:
-+ - |
-+ #include <dt-bindings/gpio/gpio.h>
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ external_phy_port1: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+
-+ external_phy_port2: ethernet-phy@1 {
-+ reg = <1>;
-+ };
-+
-+ external_phy_port3: ethernet-phy@2 {
-+ reg = <2>;
-+ };
-+
-+ external_phy_port4: ethernet-phy@3 {
-+ reg = <3>;
-+ };
-+
-+ external_phy_port5: ethernet-phy@4 {
-+ reg = <4>;
-+ };
-+
-+ switch@10 {
-+ compatible = "qca,qca8337";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
-+ reg = <0x10>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "cpu";
-+ ethernet = <&gmac1>;
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan1";
-+ phy-handle = <&external_phy_port1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ phy-handle = <&external_phy_port2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan3";
-+ phy-handle = <&external_phy_port3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan4";
-+ phy-handle = <&external_phy_port4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "wan";
-+ phy-handle = <&external_phy_port5>;
-+ };
-+ };
-+ };
-+ };
-+ - |
-+ #include <dt-bindings/gpio/gpio.h>
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ switch@10 {
-+ compatible = "qca,qca8337";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
-+ reg = <0x10>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "cpu";
-+ ethernet = <&gmac1>;
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan1";
-+ phy-mode = "internal";
-+ phy-handle = <&internal_phy_port1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ phy-mode = "internal";
-+ phy-handle = <&internal_phy_port2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan3";
-+ phy-mode = "internal";
-+ phy-handle = <&internal_phy_port3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan4";
-+ phy-mode = "internal";
-+ phy-handle = <&internal_phy_port4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "wan";
-+ phy-mode = "internal";
-+ phy-handle = <&internal_phy_port5>;
-+ };
-+
-+ port@6 {
-+ reg = <0>;
-+ label = "cpu";
-+ ethernet = <&gmac1>;
-+ phy-mode = "sgmii";
-+
-+ qca,sgmii-rxclk-falling-edge;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ internal_phy_port1: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+
-+ internal_phy_port2: ethernet-phy@1 {
-+ reg = <1>;
-+ };
-+
-+ internal_phy_port3: ethernet-phy@2 {
-+ reg = <2>;
-+ };
-+
-+ internal_phy_port4: ethernet-phy@3 {
-+ reg = <3>;
-+ };
-+
-+ internal_phy_port5: ethernet-phy@4 {
-+ reg = <4>;
-+ };
-+ };
-+ };
-+ };
diff --git a/target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch b/target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch
deleted file mode 100644
index a510cfdc18..0000000000
--- a/target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 06dd34a628ae5b6a839b757e746de165d6789ca8 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 17 Oct 2021 16:56:46 +0200
-Subject: net: dsa: qca8k: fix delay applied to wrong cpu in parse_port_config
-
-Fix delay settings applied to wrong cpu in parse_port_config. The delay
-values is set to the wrong index as the cpu_port_index is incremented
-too early. Start the cpu_port_index to -1 so the correct value is
-applied to address also the case with invalid phy mode and not available
-port.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -976,7 +976,7 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
- static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
-- int port, cpu_port_index = 0, ret;
-+ int port, cpu_port_index = -1, ret;
- struct device_node *port_dn;
- phy_interface_t mode;
- struct dsa_port *dp;
diff --git a/target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch b/target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch
deleted file mode 100644
index 71fa3022d5..0000000000
--- a/target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch
+++ /dev/null
@@ -1,151 +0,0 @@
-From 040e926f5813a5f4cc18dbff7c942d1e52f368f2 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 19 Oct 2021 02:08:50 +0200
-Subject: net: dsa: qca8k: tidy for loop in setup and add cpu port check
-
-Tidy and organize qca8k setup function from multiple for loop.
-Change for loop in bridge leave/join to scan all port and skip cpu port.
-No functional change intended.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 74 +++++++++++++++++++++++++++++--------------------
- 1 file changed, 44 insertions(+), 30 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1122,28 +1122,34 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- dev_warn(priv->dev, "mib init failed");
-
-- /* Enable QCA header mode on the cpu port */
-- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
-- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
-- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
-- if (ret) {
-- dev_err(priv->dev, "failed enabling QCA header mode");
-- return ret;
-- }
--
-- /* Disable forwarding by default on all ports */
-+ /* Initial setup of all ports */
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ /* Disable forwarding by default on all ports */
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
- QCA8K_PORT_LOOKUP_MEMBER, 0);
- if (ret)
- return ret;
-- }
-
-- /* Disable MAC by default on all ports */
-- for (i = 1; i < QCA8K_NUM_PORTS; i++)
-- qca8k_port_set_status(priv, i, 0);
-+ /* Enable QCA header mode on all cpu ports */
-+ if (dsa_is_cpu_port(ds, i)) {
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-+ QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
-+ QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
-+ if (ret) {
-+ dev_err(priv->dev, "failed enabling QCA header mode");
-+ return ret;
-+ }
-+ }
-+
-+ /* Disable MAC by default on all user ports */
-+ if (dsa_is_user_port(ds, i))
-+ qca8k_port_set_status(priv, i, 0);
-+ }
-
-- /* Forward all unknown frames to CPU port for Linux processing */
-+ /* Forward all unknown frames to CPU port for Linux processing
-+ * Notice that in multi-cpu config only one port should be set
-+ * for igmp, unknown, multicast and broadcast packet
-+ */
- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
-@@ -1152,11 +1158,13 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-- /* Setup connection between CPU port & user ports */
-+ /* Setup connection between CPU port & user ports
-+ * Configure specific switch configuration for ports
-+ */
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
- /* CPU port gets connected to all user ports of the switch */
- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
- if (ret)
- return ret;
-@@ -1193,16 +1201,14 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
- }
-- }
-
-- /* The port 5 of the qca8337 have some problem in flood condition. The
-- * original legacy driver had some specific buffer and priority settings
-- * for the different port suggested by the QCA switch team. Add this
-- * missing settings to improve switch stability under load condition.
-- * This problem is limited to qca8337 and other qca8k switch are not affected.
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8337) {
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ /* The port 5 of the qca8337 have some problem in flood condition. The
-+ * original legacy driver had some specific buffer and priority settings
-+ * for the different port suggested by the QCA switch team. Add this
-+ * missing settings to improve switch stability under load condition.
-+ * This problem is limited to qca8337 and other qca8k switch are not affected.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8337) {
- switch (i) {
- /* The 2 CPU port and port 5 requires some different
- * priority than any other ports.
-@@ -1238,6 +1244,12 @@ qca8k_setup(struct dsa_switch *ds)
- QCA8K_PORT_HOL_CTRL1_WRED_EN,
- mask);
- }
-+
-+ /* Set initial MTU for every port.
-+ * We have only have a general MTU setting. So track
-+ * every port and set the max across all port.
-+ */
-+ priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
- }
-
- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-@@ -1251,8 +1263,6 @@ qca8k_setup(struct dsa_switch *ds)
- }
-
- /* Setup our port MTUs to match power on defaults */
-- for (i = 0; i < QCA8K_NUM_PORTS; i++)
-- priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
- if (ret)
- dev_warn(priv->dev, "failed setting MTU settings");
-@@ -1728,7 +1738,9 @@ qca8k_port_bridge_join(struct dsa_switch
- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
- port_mask = BIT(cpu_port);
-
-- for (i = 1; i < QCA8K_NUM_PORTS; i++) {
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
- if (dsa_to_port(ds, i)->bridge_dev != br)
- continue;
- /* Add this port to the portvlan mask of the other ports
-@@ -1758,7 +1770,9 @@ qca8k_port_bridge_leave(struct dsa_switc
-
- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-
-- for (i = 1; i < QCA8K_NUM_PORTS; i++) {
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
- if (dsa_to_port(ds, i)->bridge_dev != br)
- continue;
- /* Remove this port to the portvlan mask of the other ports
diff --git a/target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch b/target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch
deleted file mode 100644
index 4a61703c52..0000000000
--- a/target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 5f15d392dcb4aa250a63d6f2c5adfc26c0aedc78 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 2 Nov 2021 19:30:41 +0100
-Subject: net: dsa: qca8k: make sure PAD0 MAC06 exchange is disabled
-
-Some device set MAC06 exchange in the bootloader. This cause some
-problem as we don't support this strange mode and we just set the port6
-as the primary CPU port. With MAC06 exchange, PAD0 reg configure port6
-instead of port0. Add an extra check and explicitly disable MAC06 exchange
-to correctly configure the port PAD config.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Fixes: 3fcf734aa482 ("net: dsa: qca8k: add support for cpu port 6")
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 8 ++++++++
- drivers/net/dsa/qca8k.h | 1 +
- 2 files changed, 9 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1109,6 +1109,14 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-+ /* Make sure MAC06 is disabled */
-+ ret = qca8k_reg_clear(priv, QCA8K_REG_PORT0_PAD_CTRL,
-+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
-+ if (ret) {
-+ dev_err(priv->dev, "failed disabling MAC06 exchange");
-+ return ret;
-+ }
-+
- /* Enable CPU Port */
- ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -34,6 +34,7 @@
- #define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8)
- #define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8)
- #define QCA8K_REG_PORT0_PAD_CTRL 0x004
-+#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31)
- #define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19)
- #define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18)
- #define QCA8K_REG_PORT5_PAD_CTRL 0x008
diff --git a/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch
deleted file mode 100644
index 25ac8db912..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 19 Jul 2023 12:29:49 +0200
-Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE
- macros
-
-Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more
-explicit foe_entry size for different chipset revisions.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++-----
- drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++
- 2 files changed, 8 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4713,7 +4713,7 @@ static const struct mtk_soc_data mt7621_
- .required_pctl = false,
- .offload_version = 1,
- .hash_offset = 2,
-- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4734,7 +4734,7 @@ static const struct mtk_soc_data mt7622_
- .offload_version = 2,
- .hash_offset = 2,
- .has_accounting = true,
-- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4753,7 +4753,7 @@ static const struct mtk_soc_data mt7623_
- .required_pctl = true,
- .offload_version = 1,
- .hash_offset = 2,
-- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4791,8 +4791,8 @@ static const struct mtk_soc_data mt7981_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 4,
-- .foe_entry_size = sizeof(struct mtk_foe_entry),
- .has_accounting = true,
-+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4812,8 +4812,8 @@ static const struct mtk_soc_data mt7986_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 4,
-- .foe_entry_size = sizeof(struct mtk_foe_entry),
- .has_accounting = true,
-+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd {
- struct mtk_foe_mac_info l2;
- };
-
-+#define MTK_FOE_ENTRY_V1_SIZE 80
-+#define MTK_FOE_ENTRY_V2_SIZE 96
-+
- struct mtk_foe_entry {
- u32 ib1;
-
diff --git a/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch
deleted file mode 100644
index 97209958af..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sat, 22 Jul 2023 21:32:49 +0100
-Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL
- configuration
-
-MT7623 GMAC0 attempts to configure the system clocking according to the
-required speed in the .mac_config callback for non-SGMII, non-baseX and
-non-TRGMII modes.
-
-state->speed setting has never been reliable in the .mac_config
-callback - there are cases where this is not the link speed,
-particularly via ethtool paths, so this has always been unreliable (as
-detailed in phylink's documentation.)
-
-There is the additional issue that mtk_gmac0_rgmii_adjust() will only
-be called if state->interface changes, which means it only configures
-the system clocking on the very first .mac_config call, which will be
-made when the network device is first brought up before any link is
-established.
-
-Essentially, this code is incredibly buggy, and probably never worked.
-
-Moreover, checking the in-kernel DT files, it seems no platform makes
-use of this code path.
-
-Therefore, let's remove it, and disable interface modes for port 0 that
-are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623.
-
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++---------------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- 2 files changed, 17 insertions(+), 38 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -309,7 +309,7 @@ static int mt7621_gmac0_rgmii_adjust(str
- }
-
- static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth,
-- phy_interface_t interface, int speed)
-+ phy_interface_t interface)
- {
- u32 val;
- int ret;
-@@ -323,26 +323,7 @@ static void mtk_gmac0_rgmii_adjust(struc
- return;
- }
-
-- val = (speed == SPEED_1000) ?
-- INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100;
-- mtk_w32(eth, val, INTF_MODE);
--
-- regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0,
-- ETHSYS_TRGMII_CLK_SEL362_5,
-- ETHSYS_TRGMII_CLK_SEL362_5);
--
-- val = (speed == SPEED_1000) ? 250000000 : 500000000;
-- ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val);
-- if (ret)
-- dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret);
--
-- val = (speed == SPEED_1000) ?
-- RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100;
-- mtk_w32(eth, val, TRGMII_RCK_CTRL);
--
-- val = (speed == SPEED_1000) ?
-- TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100;
-- mtk_w32(eth, val, TRGMII_TCK_CTRL);
-+ dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
- }
-
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
-@@ -428,17 +409,8 @@ static void mtk_mac_config(struct phylin
- state->interface))
- goto err_phy;
- } else {
-- /* FIXME: this is incorrect. Not only does it
-- * use state->speed (which is not guaranteed
-- * to be correct) but it also makes use of it
-- * in a code path that will only be reachable
-- * when the PHY interface mode changes, not
-- * when the speed changes. Consequently, RGMII
-- * is probably broken.
-- */
- mtk_gmac0_rgmii_adjust(mac->hw,
-- state->interface,
-- state->speed);
-+ state->interface);
-
- /* mt7623_pad_clk_setup */
- for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-@@ -4288,13 +4260,19 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
-
-- __set_bit(PHY_INTERFACE_MODE_MII,
-- mac->phylink_config.supported_interfaces);
-- __set_bit(PHY_INTERFACE_MODE_GMII,
-- mac->phylink_config.supported_interfaces);
-+ /* MT7623 gmac0 is now missing its speed-specific PLL configuration
-+ * in its .mac_config method (since state->speed is not valid there.
-+ * Disable support for MII, GMII and RGMII.
-+ */
-+ if (!mac->hw->soc->disable_pll_modes || mac->id != 0) {
-+ __set_bit(PHY_INTERFACE_MODE_MII,
-+ mac->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_GMII,
-+ mac->phylink_config.supported_interfaces);
-
-- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
-- phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
-+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
-+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
-+ }
-
- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
- __set_bit(PHY_INTERFACE_MODE_TRGMII,
-@@ -4754,6 +4732,7 @@ static const struct mtk_soc_data mt7623_
- .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-+ .disable_pll_modes = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1027,6 +1027,7 @@ struct mtk_soc_data {
- u16 foe_entry_size;
- netdev_features_t hw_features;
- bool has_accounting;
-+ bool disable_pll_modes;
- struct {
- u32 txd_size;
- u32 rxd_size;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch
deleted file mode 100644
index e1b12725b5..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sat, 22 Jul 2023 21:32:54 +0100
-Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state
- and modernise
-
-Remove the .mac_pcs_get_state function, since as far as I can tell is
-never called - no DT appears to specify an in-band-status management
-nor SFP support for this driver.
-
-Removal of this, along with the previous patch to remove the incorrect
-clocking configuration, means that the driver becomes non-legacy, so
-we can remove the "legacy_pre_march2020" status from this driver.
-
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ---------------------
- 1 file changed, 35 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -511,38 +511,6 @@ static int mtk_mac_finish(struct phylink
- return 0;
- }
-
--static void mtk_mac_pcs_get_state(struct phylink_config *config,
-- struct phylink_link_state *state)
--{
-- struct mtk_mac *mac = container_of(config, struct mtk_mac,
-- phylink_config);
-- u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id));
--
-- state->link = (pmsr & MAC_MSR_LINK);
-- state->duplex = (pmsr & MAC_MSR_DPX) >> 1;
--
-- switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) {
-- case 0:
-- state->speed = SPEED_10;
-- break;
-- case MAC_MSR_SPEED_100:
-- state->speed = SPEED_100;
-- break;
-- case MAC_MSR_SPEED_1000:
-- state->speed = SPEED_1000;
-- break;
-- default:
-- state->speed = SPEED_UNKNOWN;
-- break;
-- }
--
-- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
-- if (pmsr & MAC_MSR_RX_FC)
-- state->pause |= MLO_PAUSE_RX;
-- if (pmsr & MAC_MSR_TX_FC)
-- state->pause |= MLO_PAUSE_TX;
--}
--
- static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -665,7 +633,6 @@ static void mtk_mac_link_up(struct phyli
- static const struct phylink_mac_ops mtk_phylink_ops = {
- .validate = phylink_generic_validate,
- .mac_select_pcs = mtk_mac_select_pcs,
-- .mac_pcs_get_state = mtk_mac_pcs_get_state,
- .mac_config = mtk_mac_config,
- .mac_finish = mtk_mac_finish,
- .mac_link_down = mtk_mac_link_down,
-@@ -4255,8 +4222,6 @@ static int mtk_add_mac(struct mtk_eth *e
-
- mac->phylink_config.dev = &eth->netdev[id]->dev;
- mac->phylink_config.type = PHYLINK_NETDEV;
-- /* This driver makes use of state->speed in mac_config */
-- mac->phylink_config.legacy_pre_march2020 = true;
- mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
-
diff --git a/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch
deleted file mode 100644
index e4be17c9cb..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch
+++ /dev/null
@@ -1,550 +0,0 @@
-From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:02 +0100
-Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in
- mtk_soc_data
-
-Introduce version field in mtk_soc_data data structure in order to
-make mtk_eth driver easier to maintain for chipset configuration
-codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++--------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 36 +++++++-----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++---
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 2 +-
- drivers/net/ethernet/mediatek/mtk_wed.c | 4 +-
- 5 files changed, 66 insertions(+), 49 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -536,7 +536,7 @@ static void mtk_set_queue_speed(struct m
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
- MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v1(eth))
- val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-
- if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-@@ -911,7 +911,7 @@ static bool mtk_rx_get_desc(struct mtk_e
- rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
- rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
- rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
- rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
- }
-@@ -969,7 +969,7 @@ static int mtk_init_fq_dma(struct mtk_et
-
- txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
- txd->txd4 = 0;
-- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- txd->txd5 = 0;
- txd->txd6 = 0;
- txd->txd7 = 0;
-@@ -1158,7 +1158,7 @@ static void mtk_tx_set_dma_desc(struct n
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- mtk_tx_set_dma_desc_v2(dev, txd, info);
- else
- mtk_tx_set_dma_desc_v1(dev, txd, info);
-@@ -1465,7 +1465,7 @@ static void mtk_update_rx_cpu_idx(struct
-
- static bool mtk_page_pool_enabled(struct mtk_eth *eth)
- {
-- return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);
-+ return eth->soc->version == 2;
- }
-
- static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
-@@ -1805,7 +1805,7 @@ static int mtk_poll_rx(struct napi_struc
- break;
-
- /* find out which mac the packet come from. values start at 1 */
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-@@ -1901,7 +1901,7 @@ static int mtk_poll_rx(struct napi_struc
- skb->dev = netdev;
- bytes += skb->len;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
- hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
- if (hash != MTK_RXD5_FOE_ENTRY)
-@@ -1926,8 +1926,8 @@ static int mtk_poll_rx(struct napi_struc
- /* When using VLAN untagging in combination with DSA, the
- * hardware treats the MTK special tag as a VLAN and untags it.
- */
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-- (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-+ if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) &&
-+ netdev_uses_dsa(netdev)) {
- unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-
- if (port < ARRAY_SIZE(eth->dsa_meta) &&
-@@ -2231,7 +2231,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- txd->txd2 = next_ptr;
- txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
- txd->txd4 = 0;
-- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- txd->txd5 = 0;
- txd->txd6 = 0;
- txd->txd7 = 0;
-@@ -2284,14 +2284,14 @@ static int mtk_tx_alloc(struct mtk_eth *
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
- MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v1(eth))
- val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
- mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
- ofs += MTK_QTX_OFFSET;
- }
- val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16);
- mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate);
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
- } else {
- mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
-@@ -2418,7 +2418,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-
- rxd->rxd3 = 0;
- rxd->rxd4 = 0;
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- rxd->rxd5 = 0;
- rxd->rxd6 = 0;
- rxd->rxd7 = 0;
-@@ -2969,7 +2969,7 @@ static int mtk_start_dma(struct mtk_eth
- MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
- MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
- MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
- MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
-@@ -3113,7 +3113,7 @@ static int mtk_open(struct net_device *d
- phylink_start(mac->phylink);
- netif_tx_start_all_queues(dev);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return 0;
-
- if (mtk_uses_dsa(dev) && !eth->prog) {
-@@ -3378,7 +3378,7 @@ static void mtk_hw_reset(struct mtk_eth
- {
- u32 val;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
- val = RSTCTRL_PPE0_V2;
- } else {
-@@ -3390,7 +3390,7 @@ static void mtk_hw_reset(struct mtk_eth
-
- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
- 0x3ffffff);
- }
-@@ -3416,7 +3416,7 @@ static void mtk_hw_warm_reset(struct mtk
- return;
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
- else
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
-@@ -3586,7 +3586,7 @@ static int mtk_hw_init(struct mtk_eth *e
- else
- mtk_hw_reset(eth);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- /* Set FE to PDMAv2 if necessary */
- val = mtk_r32(eth, MTK_FE_GLO_MISC);
- mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
-@@ -3623,7 +3623,7 @@ static int mtk_hw_init(struct mtk_eth *e
- */
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ 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);
-
-@@ -3645,7 +3645,7 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- /* PSE should not drop port8 and port9 packets from WDMA Tx */
- mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-
-@@ -4434,7 +4434,7 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- err = -EINVAL;
-@@ -4542,9 +4542,8 @@ static int mtk_probe(struct platform_dev
- }
-
- if (eth->soc->offload_version) {
-- u32 num_ppe;
-+ u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
-
-- num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
- num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
- for (i = 0; i < num_ppe; i++) {
- u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
-@@ -4638,6 +4637,7 @@ static const struct mtk_soc_data mt2701_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
-+ .version = 1,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4654,6 +4654,7 @@ static const struct mtk_soc_data mt7621_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7621_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 1,
- .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-@@ -4674,6 +4675,7 @@ static const struct mtk_soc_data mt7622_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7622_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 1,
- .offload_version = 2,
- .hash_offset = 2,
- .has_accounting = true,
-@@ -4694,6 +4696,7 @@ static const struct mtk_soc_data mt7623_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
-+ .version = 1,
- .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-@@ -4716,6 +4719,7 @@ static const struct mtk_soc_data mt7629_
- .required_clks = MT7629_CLKS_BITMAP,
- .required_pctl = false,
- .has_accounting = true,
-+ .version = 1,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4733,6 +4737,7 @@ static const struct mtk_soc_data mt7981_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7981_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 2,
- .offload_version = 2,
- .hash_offset = 4,
- .has_accounting = true,
-@@ -4754,6 +4759,7 @@ static const struct mtk_soc_data mt7986_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7986_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 2,
- .offload_version = 2,
- .hash_offset = 4,
- .has_accounting = true,
-@@ -4774,6 +4780,7 @@ static const struct mtk_soc_data rt5350_
- .hw_features = MTK_HW_FEATURES_MT7628,
- .required_clks = MT7628_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 1,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -817,7 +817,6 @@ enum mkt_eth_capabilities {
- MTK_SHARED_INT_BIT,
- MTK_TRGMII_MT7621_CLK_BIT,
- MTK_QDMA_BIT,
-- MTK_NETSYS_V2_BIT,
- MTK_SOC_MT7628_BIT,
- MTK_RSTCTRL_PPE1_BIT,
- MTK_U3_COPHY_V2_BIT,
-@@ -852,7 +851,6 @@ enum mkt_eth_capabilities {
- #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
- #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
- #define MTK_QDMA BIT(MTK_QDMA_BIT)
--#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
- #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
- #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
-@@ -931,11 +929,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_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+ MTK_RSTCTRL_PPE1)
-
- #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
-- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+ MTK_RSTCTRL_PPE1)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
-@@ -1006,6 +1004,7 @@ struct mtk_reg_map {
- * @required_pctl A bool value to show whether the SoC requires
- * the extra setup for those pins used by GMAC.
- * @hash_offset Flow table hash offset.
-+ * @version SoC version.
- * @foe_entry_size Foe table entry size.
- * @has_accounting Bool indicating support for accounting of
- * offloaded flows.
-@@ -1024,6 +1023,7 @@ struct mtk_soc_data {
- bool required_pctl;
- u8 offload_version;
- u8 hash_offset;
-+ u8 version;
- u16 foe_entry_size;
- netdev_features_t hw_features;
- bool has_accounting;
-@@ -1180,6 +1180,16 @@ 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[];
-
-+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
-+{
-+ return eth->soc->version == 1;
-+}
-+
-+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
-+{
-+ return eth->soc->version > 1;
-+}
-+
- static inline struct mtk_foe_entry *
- mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
- {
-@@ -1190,7 +1200,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u
-
- static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-
- return MTK_FOE_IB1_BIND_TIMESTAMP;
-@@ -1198,7 +1208,7 @@ static inline u32 mtk_get_ib1_ts_mask(st
-
- static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_PPPOE_V2;
-
- return MTK_FOE_IB1_BIND_PPPOE;
-@@ -1206,7 +1216,7 @@ static inline u32 mtk_get_ib1_ppoe_mask(
-
- static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_VLAN_TAG_V2;
-
- return MTK_FOE_IB1_BIND_VLAN_TAG;
-@@ -1214,7 +1224,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m
-
- static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_VLAN_LAYER_V2;
-
- return MTK_FOE_IB1_BIND_VLAN_LAYER;
-@@ -1222,7 +1232,7 @@ static inline u32 mtk_get_ib1_vlan_layer
-
- static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
-
- return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
-@@ -1230,7 +1240,7 @@ static inline u32 mtk_prep_ib1_vlan_laye
-
- static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
-
- return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
-@@ -1238,7 +1248,7 @@ static inline u32 mtk_get_ib1_vlan_layer
-
- static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_PACKET_TYPE_V2;
-
- return MTK_FOE_IB1_PACKET_TYPE;
-@@ -1246,7 +1256,7 @@ static inline u32 mtk_get_ib1_pkt_type_m
-
- static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val);
-
- return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val);
-@@ -1254,7 +1264,7 @@ static inline u32 mtk_get_ib1_pkt_type(s
-
- static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB2_MULTICAST_V2;
-
- return MTK_FOE_IB2_MULTICAST;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth
-
- memset(entry, 0, sizeof(*entry));
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) |
- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
-@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
- u32 val = *ib2;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- val &= ~MTK_FOE_IB2_DEST_PORT_V2;
- val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port);
- } else {
-@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
- *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
- MTK_FOE_IB2_WDMA_WINFO_V2;
-@@ -452,7 +452,7 @@ int mtk_foe_entry_set_queue(struct mtk_e
- {
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- *ib2 &= ~MTK_FOE_IB2_QID_V2;
- *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue);
- *ib2 |= MTK_FOE_IB2_PSE_QOS_V2;
-@@ -607,7 +607,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- struct mtk_foe_entry *hwe;
- u32 val;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2,
- timestamp);
-@@ -623,7 +623,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- hwe->ib1 = entry->ib1;
-
- if (ppe->accounting) {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- val = MTK_FOE_IB2_MIB_CNT_V2;
- else
- val = MTK_FOE_IB2_MIB_CNT;
-@@ -971,7 +971,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_SCAN_MODE_CHECK_AGE) |
- FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
- MTK_PPE_ENTRIES_SHIFT);
-- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(ppe->eth))
- val |= MTK_PPE_TB_CFG_INFO_SEL;
- ppe_w32(ppe, MTK_PPE_TB_CFG, val);
-
-@@ -987,7 +987,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_FLOW_CFG_IP4_NAPT |
- MTK_PPE_FLOW_CFG_IP4_DSLITE |
- MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
-- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(ppe->eth))
- val |= MTK_PPE_MD_TOAP_BYP_CRSN0 |
- MTK_PPE_MD_TOAP_BYP_CRSN1 |
- MTK_PPE_MD_TOAP_BYP_CRSN2 |
-@@ -1029,7 +1029,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
-
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
-
-- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) {
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
- ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
- }
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
- if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
- mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
- info.bss, info.wcid);
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- switch (info.wdma_idx) {
- case 0:
- pse_port = 8;
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1084,7 +1084,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- } else {
- struct mtk_eth *eth = dev->hw->eth;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- wed_set(dev, MTK_WED_RESET_IDX,
- MTK_WED_RESET_IDX_RX_V2);
- else
-@@ -1806,7 +1806,7 @@ void mtk_wed_add_hw(struct device_node *
- hw->wdma = wdma;
- hw->index = index;
- hw->irq = irq;
-- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
-+ hw->version = mtk_is_netsys_v1(eth) ? 1 : 2;
-
- if (hw->version == 1) {
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
diff --git a/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch
deleted file mode 100644
index 5a08b9dddf..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:27 +0100
-Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3
-
-This is a preliminary patch to add MT7988 SoC support since it runs 3
-macs instead of 2.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1040,8 +1040,8 @@ struct mtk_soc_data {
-
- #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
-
--/* currently no SoC has more than 2 macs */
--#define MTK_MAX_DEVS 2
-+/* currently no SoC has more than 3 macs */
-+#define MTK_MAX_DEVS 3
-
- /* struct mtk_eth - This is the main datasructure for holding the state
- * of the driver
diff --git a/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch b/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch
deleted file mode 100644
index faa8734c24..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:44 +0100
-Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and
- remove MTK_MAC_COUNT
-
-Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++---------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
- 2 files changed, 27 insertions(+), 23 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -837,7 +837,7 @@ static void mtk_stats_update(struct mtk_
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->mac[i] || !eth->mac[i]->hw_stats)
- continue;
- if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
-@@ -1340,7 +1340,7 @@ static int mtk_queue_stopped(struct mtk_
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- if (netif_queue_stopped(eth->netdev[i]))
-@@ -1354,7 +1354,7 @@ static void mtk_wake_queue(struct mtk_et
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- netif_tx_wake_all_queues(eth->netdev[i]);
-@@ -1811,7 +1811,7 @@ static int mtk_poll_rx(struct napi_struc
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
- mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
-
-- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
-+ if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
- !eth->netdev[mac]))
- goto release_desc;
-
-@@ -2843,7 +2843,7 @@ static void mtk_dma_free(struct mtk_eth
- const struct mtk_soc_data *soc = eth->soc;
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++)
-+ for (i = 0; i < MTK_MAX_DEVS; i++)
- if (eth->netdev[i])
- netdev_reset_queue(eth->netdev[i]);
- if (eth->scratch_ring) {
-@@ -2997,8 +2997,13 @@ static void mtk_gdm_config(struct mtk_et
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
- return;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ u32 val;
-+
-+ if (!eth->netdev[i])
-+ continue;
-+
-+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-
- /* default setup the forward port to send frame to PDMA */
- val &= ~0xffff;
-@@ -3008,7 +3013,7 @@ static void mtk_gdm_config(struct mtk_et
-
- val |= config;
-
-- if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i]))
-+ if (netdev_uses_dsa(eth->netdev[i]))
- val |= MTK_GDMA_SPECIAL_TAG;
-
- mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-@@ -3607,15 +3612,15 @@ static int mtk_hw_init(struct mtk_eth *e
- * up with the more appropriate value when mtk_mac_config call is being
- * invoked.
- */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- struct net_device *dev = eth->netdev[i];
-
-- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
-- if (dev) {
-- struct mtk_mac *mac = netdev_priv(dev);
-+ if (!dev)
-+ continue;
-
-- mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
-- }
-+ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
-+ mtk_set_mcr_max_rx(netdev_priv(dev),
-+ dev->mtu + MTK_RX_ETH_HLEN);
- }
-
- /* Indicates CDM to parse the MTK special tag from CPU
-@@ -3795,7 +3800,7 @@ static void mtk_pending_work(struct work
- mtk_prepare_for_reset(eth);
-
- /* stop all devices to make sure that dma is properly shut down */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
- continue;
-
-@@ -3811,8 +3816,8 @@ static void mtk_pending_work(struct work
- mtk_hw_init(eth, true);
-
- /* restart DMA and enable IRQs */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!test_bit(i, &restart))
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ if (!eth->netdev[i] || !test_bit(i, &restart))
- continue;
-
- if (mtk_open(eth->netdev[i])) {
-@@ -3839,7 +3844,7 @@ static int mtk_free_dev(struct mtk_eth *
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- free_netdev(eth->netdev[i]);
-@@ -3858,7 +3863,7 @@ static int mtk_unreg_dev(struct mtk_eth
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- struct mtk_mac *mac;
- if (!eth->netdev[i])
- continue;
-@@ -4159,7 +4164,7 @@ static int mtk_add_mac(struct mtk_eth *e
- }
-
- id = be32_to_cpup(_id);
-- if (id >= MTK_MAC_COUNT) {
-+ if (id >= MTK_MAX_DEVS) {
- dev_err(eth->dev, "%d is not a valid mac id\n", id);
- return -EINVAL;
- }
-@@ -4304,7 +4309,7 @@ void mtk_eth_set_dma_device(struct mtk_e
-
- rtnl_lock();
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- dev = eth->netdev[i];
-
- if (!dev || !(dev->flags & IFF_UP))
-@@ -4612,7 +4617,7 @@ static int mtk_remove(struct platform_de
- int i;
-
- /* stop all devices to make sure that dma is properly shut down */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- mtk_stop(eth->netdev[i]);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -33,7 +33,6 @@
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_QDMA_RING_SIZE 2048
- #define MTK_DMA_SIZE 512
--#define MTK_MAC_COUNT 2
- #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN)
- #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
- #define MTK_DMA_DUMMY_DESC 0xffffffff
diff --git a/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch b/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch
deleted file mode 100644
index c22b55c6f1..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch
+++ /dev/null
@@ -1,307 +0,0 @@
-From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:59 +0100
-Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version
- support
-
-Introduce NETSYS_V3 chipset version support.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++--
- 2 files changed, 116 insertions(+), 37 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -817,17 +817,32 @@ void mtk_stats_update_mac(struct mtk_mac
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
- hw_stats->rx_flow_control_packets +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
-- hw_stats->tx_skip +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
-- hw_stats->tx_collisions +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
-- hw_stats->tx_bytes +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
-- if (stats)
-- hw_stats->tx_bytes += (stats << 32);
-- hw_stats->tx_packets +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ hw_stats->tx_skip +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
-+ hw_stats->tx_collisions +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
-+ hw_stats->tx_bytes +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
-+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
-+ if (stats)
-+ hw_stats->tx_bytes += (stats << 32);
-+ hw_stats->tx_packets +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
-+ } else {
-+ hw_stats->tx_skip +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
-+ hw_stats->tx_collisions +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
-+ hw_stats->tx_bytes +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
-+ if (stats)
-+ hw_stats->tx_bytes += (stats << 32);
-+ hw_stats->tx_packets +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+ }
- }
-
- u64_stats_update_end(&hw_stats->syncp);
-@@ -1129,7 +1144,10 @@ static void mtk_tx_set_dma_desc_v2(struc
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-
-- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+ if (mac->id == MTK_GMAC3_ID)
-+ data = PSE_GDM3_PORT;
-+ else
-+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
- data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
- WRITE_ONCE(desc->txd4, data);
-
-@@ -1140,6 +1158,8 @@ static void mtk_tx_set_dma_desc_v2(struc
- /* tx checksum offload */
- if (info->csum)
- data |= TX_DMA_CHKSUM_V2;
-+ if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev))
-+ data |= TX_DMA_SPTAG_V3;
- }
- WRITE_ONCE(desc->txd5, data);
-
-@@ -1205,8 +1225,7 @@ static int mtk_tx_map(struct sk_buff *sk
- mtk_tx_set_dma_desc(dev, itxd, &txd_info);
-
- itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-- MTK_TX_FLAGS_FPORT1;
-+ itx_buf->mac_id = mac->id;
- setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
- k++);
-
-@@ -1254,8 +1273,7 @@ static int mtk_tx_map(struct sk_buff *sk
- memset(tx_buf, 0, sizeof(*tx_buf));
- tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
- tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
-- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-- MTK_TX_FLAGS_FPORT1;
-+ tx_buf->mac_id = mac->id;
-
- setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
- txd_info.size, k++);
-@@ -1557,7 +1575,7 @@ static int mtk_xdp_frame_map(struct mtk_
- }
- mtk_tx_set_dma_desc(dev, txd, txd_info);
-
-- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
-+ tx_buf->mac_id = mac->id;
- tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
- tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
-
-@@ -1805,11 +1823,24 @@ static int mtk_poll_rx(struct napi_struc
- break;
-
- /* find out which mac the packet come from. values start at 1 */
-- if (mtk_is_netsys_v2_or_greater(eth))
-- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
-- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
-+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
-+
-+ switch (val) {
-+ case PSE_GDM1_PORT:
-+ case PSE_GDM2_PORT:
-+ mac = val - 1;
-+ break;
-+ case PSE_GDM3_PORT:
-+ mac = MTK_GMAC3_ID;
-+ break;
-+ default:
-+ break;
-+ }
-+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
- mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
-+ }
-
- if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
- !eth->netdev[mac]))
-@@ -2029,7 +2060,6 @@ static int mtk_poll_tx_qdma(struct mtk_e
-
- while ((cpu != dma) && budget) {
- u32 next_cpu = desc->txd2;
-- int mac = 0;
-
- desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
- if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
-@@ -2037,15 +2067,13 @@ static int mtk_poll_tx_qdma(struct mtk_e
-
- tx_buf = mtk_desc_to_tx_buf(ring, desc,
- eth->soc->txrx.txd_size);
-- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
-- mac = 1;
--
- if (!tx_buf->data)
- break;
-
- if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
- if (tx_buf->type == MTK_TYPE_SKB)
-- mtk_poll_tx_done(eth, state, mac, tx_buf->data);
-+ mtk_poll_tx_done(eth, state, tx_buf->mac_id,
-+ tx_buf->data);
-
- budget--;
- }
-@@ -3650,7 +3678,24 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ /* PSE should not drop port1, port8 and port9 packets */
-+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
-+
-+ /* GDM and CDM Threshold */
-+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
-+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
-+
-+ /* Disable GDM1 RX CRC stripping */
-+ mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0));
-+
-+ /* PSE GDM3 MIB counter has incorrect hw default values,
-+ * so the driver ought to read clear the values beforehand
-+ * in case ethtool retrieve wrong mib values.
-+ */
-+ for (i = 0; i < 0x80; i += 0x4)
-+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
-+ } else if (!mtk_is_netsys_v1(eth)) {
- /* PSE should not drop port8 and port9 packets from WDMA Tx */
- mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-
-@@ -4212,7 +4257,11 @@ static int mtk_add_mac(struct mtk_eth *e
- }
- spin_lock_init(&mac->hw_stats->stats_lock);
- u64_stats_init(&mac->hw_stats->syncp);
-- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-+
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ mac->hw_stats->reg_offset = id * 0x80;
-+ else
-+ mac->hw_stats->reg_offset = id * 0x40;
-
- /* phylink create */
- err = of_get_phy_mode(np, &phy_mode);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -122,6 +122,7 @@
- #define MTK_GDMA_ICS_EN BIT(22)
- #define MTK_GDMA_TCS_EN BIT(21)
- #define MTK_GDMA_UCS_EN BIT(20)
-+#define MTK_GDMA_STRP_CRC BIT(16)
- #define MTK_GDMA_TO_PDMA 0x0
- #define MTK_GDMA_DROP_ALL 0x7777
-
-@@ -287,8 +288,6 @@
- /* QDMA Interrupt grouping registers */
- #define MTK_RLS_DONE_INT BIT(0)
-
--#define MTK_STAT_OFFSET 0x40
--
- /* QDMA TX NUM */
- #define QID_BITS_V2(x) (((x) & 0x3f) << 16)
- #define MTK_QDMA_GMAC2_QID 8
-@@ -301,6 +300,8 @@
- #define TX_DMA_CHKSUM_V2 (0x7 << 28)
- #define TX_DMA_TSO_V2 BIT(31)
-
-+#define TX_DMA_SPTAG_V3 BIT(27)
-+
- /* QDMA V2 descriptor txd4 */
- #define TX_DMA_FPORT_SHIFT_V2 8
- #define TX_DMA_FPORT_MASK_V2 0xf
-@@ -631,12 +632,6 @@ enum mtk_tx_flags {
- */
- MTK_TX_FLAGS_SINGLE0 = 0x01,
- MTK_TX_FLAGS_PAGE0 = 0x02,
--
-- /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted
-- * SKB out instead of looking up through hardware TX descriptor.
-- */
-- MTK_TX_FLAGS_FPORT0 = 0x04,
-- MTK_TX_FLAGS_FPORT1 = 0x08,
- };
-
- /* This enum allows us to identify how the clock is defined on the array of the
-@@ -722,6 +717,35 @@ enum mtk_dev_state {
- MTK_RESETTING
- };
-
-+/* PSE Port Definition */
-+enum mtk_pse_port {
-+ PSE_ADMA_PORT = 0,
-+ PSE_GDM1_PORT,
-+ PSE_GDM2_PORT,
-+ PSE_PPE0_PORT,
-+ PSE_PPE1_PORT,
-+ PSE_QDMA_TX_PORT,
-+ PSE_QDMA_RX_PORT,
-+ PSE_DROP_PORT,
-+ PSE_WDMA0_PORT,
-+ PSE_WDMA1_PORT,
-+ PSE_TDMA_PORT,
-+ PSE_NONE_PORT,
-+ PSE_PPE2_PORT,
-+ PSE_WDMA2_PORT,
-+ PSE_EIP197_PORT,
-+ PSE_GDM3_PORT,
-+ PSE_PORT_MAX
-+};
-+
-+/* GMAC Identifier */
-+enum mtk_gmac_id {
-+ MTK_GMAC1_ID = 0,
-+ MTK_GMAC2_ID,
-+ MTK_GMAC3_ID,
-+ MTK_GMAC_ID_MAX
-+};
-+
- enum mtk_tx_buf_type {
- MTK_TYPE_SKB,
- MTK_TYPE_XDP_TX,
-@@ -740,7 +764,8 @@ struct mtk_tx_buf {
- enum mtk_tx_buf_type type;
- void *data;
-
-- u32 flags;
-+ u16 mac_id;
-+ u16 flags;
- DEFINE_DMA_UNMAP_ADDR(dma_addr0);
- DEFINE_DMA_UNMAP_LEN(dma_len0);
- DEFINE_DMA_UNMAP_ADDR(dma_addr1);
-@@ -1189,6 +1214,11 @@ static inline bool mtk_is_netsys_v2_or_g
- return eth->soc->version > 1;
- }
-
-+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
-+{
-+ return eth->soc->version > 2;
-+}
-+
- static inline struct mtk_foe_entry *
- mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
- {
diff --git a/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
deleted file mode 100644
index 0a72eec2fc..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:53:13 +0100
-Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in
- mtk_soc_data struct to u64
-
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 56 ++++++++++----------
- 2 files changed, 39 insertions(+), 39 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -15,10 +15,10 @@
- struct mtk_eth_muxc {
- const char *name;
- int cap_bit;
-- int (*set_path)(struct mtk_eth *eth, int path);
-+ int (*set_path)(struct mtk_eth *eth, u64 path);
- };
-
--static const char *mtk_eth_path_name(int path)
-+static const char *mtk_eth_path_name(u64 path)
- {
- switch (path) {
- case MTK_ETH_PATH_GMAC1_RGMII:
-@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
- }
- }
-
--static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
-+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
- bool updated = true;
- u32 val, mask, set;
-@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
- return 0;
- }
-
--static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
-+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
- bool updated = true;
-@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
- return 0;
- }
-
--static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
-+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0, mask = 0, reg = 0;
- bool updated = true;
-@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
- return 0;
- }
-
--static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
- bool updated = true;
-@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
- return 0;
- }
-
--static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
- bool updated = true;
-@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
- },
- };
-
--static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
-+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
- {
- int i, err = 0;
-
-@@ -249,7 +249,7 @@ out:
-
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
-- int path;
-+ u64 path;
-
- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
- MTK_ETH_PATH_GMAC2_SGMII;
-@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
-
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
- {
-- int path = 0;
-+ u64 path = 0;
-
- if (mac_id == 1)
- path = MTK_ETH_PATH_GMAC2_GEPHY;
-@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
-
- int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
-- int path;
-+ u64 path;
-
- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII :
- MTK_ETH_PATH_GMAC2_RGMII;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -863,41 +863,41 @@ enum mkt_eth_capabilities {
- };
-
- /* Supported hardware group on SoCs */
--#define MTK_RGMII BIT(MTK_RGMII_BIT)
--#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
--#define MTK_SGMII BIT(MTK_SGMII_BIT)
--#define MTK_ESW BIT(MTK_ESW_BIT)
--#define MTK_GEPHY BIT(MTK_GEPHY_BIT)
--#define MTK_MUX BIT(MTK_MUX_BIT)
--#define MTK_INFRA BIT(MTK_INFRA_BIT)
--#define MTK_SHARED_SGMII BIT(MTK_SHARED_SGMII_BIT)
--#define MTK_HWLRO BIT(MTK_HWLRO_BIT)
--#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
--#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
--#define MTK_QDMA BIT(MTK_QDMA_BIT)
--#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
--#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
--#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
-+#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_ESW BIT_ULL(MTK_ESW_BIT)
-+#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
-+#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
-+#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_SHARED_INT BIT_ULL(MTK_SHARED_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)
-+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
-- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
- #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY \
-- BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
-- BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
-- BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
-- BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-
- /* Supported path present on SoCs */
--#define MTK_ETH_PATH_GMAC1_RGMII BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_SGMII BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_RGMII BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_GEPHY BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
--#define MTK_ETH_PATH_GDM1_ESW BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
-+#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_TRGMII BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
-+#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
-
- #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
- #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -1042,7 +1042,7 @@ struct mtk_reg_map {
- struct mtk_soc_data {
- const struct mtk_reg_map *reg_map;
- u32 ana_rgc3;
-- u32 caps;
-+ u64 caps;
- u32 required_clks;
- bool required_pctl;
- u8 offload_version;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch
deleted file mode 100644
index 4e5b857d48..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 25 Jul 2023 01:53:28 +0100
-Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to
- u64
-
-The to-be-added MT7988 SoC adds many new clocks which need to be
-controlled by the Ethernet driver, which will result in their total
-number exceeding 32.
-Prepare by converting clock bitmaps into 64-bit types.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++----------
- 1 file changed, 49 insertions(+), 47 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -663,54 +663,56 @@ enum mtk_clks_map {
- MTK_CLK_MAX
- };
-
--#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
-- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
-- BIT(MTK_CLK_TRGPLL))
--#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
-- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_GP2) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII_CK) | \
-- BIT(MTK_CLK_ETH2PLL))
-+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_TRGPLL))
-+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII_CK) | \
-+ BIT_ULL(MTK_CLK_ETH2PLL))
- #define MT7621_CLKS_BITMAP (0)
- #define MT7628_CLKS_BITMAP (0)
--#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
-- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII2_TX_250M) | \
-- BIT(MTK_CLK_SGMII2_RX_250M) | \
-- BIT(MTK_CLK_SGMII2_CDR_REF) | \
-- BIT(MTK_CLK_SGMII2_CDR_FB) | \
-- BIT(MTK_CLK_SGMII_CK) | \
-- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
--#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_WOCPU0) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII2_TX_250M) | \
-- BIT(MTK_CLK_SGMII2_RX_250M) | \
-- BIT(MTK_CLK_SGMII2_CDR_REF) | \
-- BIT(MTK_CLK_SGMII2_CDR_FB) | \
-- BIT(MTK_CLK_SGMII_CK))
--#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII2_TX_250M) | \
-- BIT(MTK_CLK_SGMII2_RX_250M) | \
-- BIT(MTK_CLK_SGMII2_CDR_REF) | \
-- BIT(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII_CK) | \
-+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
-+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_WOCPU0) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII_CK))
-+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
-
- enum mtk_dev_state {
- MTK_HW_INIT,
-@@ -1043,7 +1045,7 @@ struct mtk_soc_data {
- const struct mtk_reg_map *reg_map;
- u32 ana_rgc3;
- u64 caps;
-- u32 required_clks;
-+ u64 required_clks;
- bool required_pctl;
- u8 offload_version;
- u8 hash_offset;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch
deleted file mode 100644
index 58b9cec626..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch
+++ /dev/null
@@ -1,477 +0,0 @@
-From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:57:42 +0100
-Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for
- MT7988 SoC
-
-Introduce support for ethernet chip available in MT7988 SoC to
-mtk_eth_soc driver. As a first step support only the first GMAC which
-is hard-wired to the internal DSA switch having 4 built-in gigabit
-Ethernet PHYs.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 201 +++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 86 +++++++-
- 3 files changed, 273 insertions(+), 28 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64
- static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
- bool updated = true;
-- u32 val, mask, set;
-+ u32 mask, set, reg;
-
- switch (path) {
- case MTK_ETH_PATH_GMAC1_SGMII:
-@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str
- break;
- }
-
-- if (updated) {
-- val = mtk_r32(eth, MTK_MAC_MISC);
-- val = (val & mask) | set;
-- mtk_w32(eth, val, MTK_MAC_MISC);
-- }
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ reg = MTK_MAC_MISC_V3;
-+ else
-+ reg = MTK_MAC_MISC;
-+
-+ if (updated)
-+ mtk_m32(eth, mask, set, reg);
-
- dev_dbg(eth->dev, "path %s in %s updated = %d\n",
- mtk_eth_path_name(path), __func__, updated);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
- .pse_oq_sta = 0x01a0,
- };
-
-+static const struct mtk_reg_map mt7988_reg_map = {
-+ .tx_irq_mask = 0x461c,
-+ .tx_irq_status = 0x4618,
-+ .pdma = {
-+ .rx_ptr = 0x6900,
-+ .rx_cnt_cfg = 0x6904,
-+ .pcrx_ptr = 0x6908,
-+ .glo_cfg = 0x6a04,
-+ .rst_idx = 0x6a08,
-+ .delay_irq = 0x6a0c,
-+ .irq_status = 0x6a20,
-+ .irq_mask = 0x6a28,
-+ .adma_rx_dbg0 = 0x6a38,
-+ .int_grp = 0x6a50,
-+ },
-+ .qdma = {
-+ .qtx_cfg = 0x4400,
-+ .qtx_sch = 0x4404,
-+ .rx_ptr = 0x4500,
-+ .rx_cnt_cfg = 0x4504,
-+ .qcrx_ptr = 0x4508,
-+ .glo_cfg = 0x4604,
-+ .rst_idx = 0x4608,
-+ .delay_irq = 0x460c,
-+ .fc_th = 0x4610,
-+ .int_grp = 0x4620,
-+ .hred = 0x4644,
-+ .ctx_ptr = 0x4700,
-+ .dtx_ptr = 0x4704,
-+ .crx_ptr = 0x4710,
-+ .drx_ptr = 0x4714,
-+ .fq_head = 0x4720,
-+ .fq_tail = 0x4724,
-+ .fq_count = 0x4728,
-+ .fq_blen = 0x472c,
-+ .tx_sch_rate = 0x4798,
-+ },
-+ .gdm1_cnt = 0x1c00,
-+ .gdma_to_ppe0 = 0x3333,
-+ .ppe_base = 0x2000,
-+ .wdma_base = {
-+ [0] = 0x4800,
-+ [1] = 0x4c00,
-+ },
-+ .pse_iq_sta = 0x0180,
-+ .pse_oq_sta = 0x01a0,
-+};
-+
- /* strings used by ethtool */
- static const struct mtk_ethtool_stats {
- char str[ETH_GSTRING_LEN];
-@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
- };
-
- static const char * const mtk_clks_source_name[] = {
-- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
-- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
-- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
-- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
-+ "ethif",
-+ "sgmiitop",
-+ "esw",
-+ "gp0",
-+ "gp1",
-+ "gp2",
-+ "gp3",
-+ "xgp1",
-+ "xgp2",
-+ "xgp3",
-+ "crypto",
-+ "fe",
-+ "trgpll",
-+ "sgmii_tx250m",
-+ "sgmii_rx250m",
-+ "sgmii_cdr_ref",
-+ "sgmii_cdr_fb",
-+ "sgmii2_tx250m",
-+ "sgmii2_rx250m",
-+ "sgmii2_cdr_ref",
-+ "sgmii2_cdr_fb",
-+ "sgmii_ck",
-+ "eth2pll",
-+ "wocpu0",
-+ "wocpu1",
-+ "netsys0",
-+ "netsys1",
-+ "ethwarp_wocpu2",
-+ "ethwarp_wocpu1",
-+ "ethwarp_wocpu0",
-+ "top_usxgmii0_sel",
-+ "top_usxgmii1_sel",
-+ "top_sgm0_sel",
-+ "top_sgm1_sel",
-+ "top_xfi_phy0_xtal_sel",
-+ "top_xfi_phy1_xtal_sel",
-+ "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",
- };
-
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
-@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
- return __raw_readl(eth->base + reg);
- }
-
--static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg)
-+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg)
- {
- u32 val;
-
-@@ -326,6 +418,19 @@ static void mtk_gmac0_rgmii_adjust(struc
- dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
- }
-
-+static void mtk_setup_bridge_switch(struct mtk_eth *eth)
-+{
-+ /* Force Port1 XGMAC Link Up */
-+ mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID),
-+ MTK_XGMAC_STS(MTK_GMAC1_ID));
-+
-+ /* Adjust GSW bridge IPG to 11 */
-+ mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK,
-+ (GSW_IPG_11 << GSWTX_IPG_SHIFT) |
-+ (GSW_IPG_11 << GSWRX_IPG_SHIFT),
-+ MTK_GSW_CFG);
-+}
-+
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
- phy_interface_t interface)
- {
-@@ -395,6 +500,8 @@ static void mtk_mac_config(struct phylin
- goto init_err;
- }
- break;
-+ case PHY_INTERFACE_MODE_INTERNAL:
-+ break;
- default:
- goto err_phy;
- }
-@@ -472,6 +579,15 @@ static void mtk_mac_config(struct phylin
- return;
- }
-
-+ /* Setup gmac */
-+ if (mtk_is_netsys_v3_or_greater(eth) &&
-+ mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
-+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+
-+ mtk_setup_bridge_switch(eth);
-+ }
-+
- return;
-
- err_phy:
-@@ -681,11 +797,15 @@ static int mtk_mdio_init(struct mtk_eth
- }
- divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
-
-+ /* Configure MDC Turbo Mode */
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3);
-+
- /* Configure MDC Divider */
-- val = mtk_r32(eth, MTK_PPSC);
-- val &= ~PPSC_MDC_CFG;
-- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
-- mtk_w32(eth, val, MTK_PPSC);
-+ val = FIELD_PREP(PPSC_MDC_CFG, divider);
-+ if (!mtk_is_netsys_v3_or_greater(eth))
-+ val |= PPSC_MDC_TURBO;
-+ mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC);
-
- dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
-
-@@ -1144,10 +1264,19 @@ static void mtk_tx_set_dma_desc_v2(struc
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-
-- if (mac->id == MTK_GMAC3_ID)
-- data = PSE_GDM3_PORT;
-- else
-- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+ /* set forward port */
-+ switch (mac->id) {
-+ case MTK_GMAC1_ID:
-+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
-+ break;
-+ case MTK_GMAC2_ID:
-+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
-+ break;
-+ case MTK_GMAC3_ID:
-+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
-+ break;
-+ }
-+
- data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
- WRITE_ONCE(desc->txd4, data);
-
-@@ -4306,6 +4435,17 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->phylink_config.supported_interfaces);
- }
-
-+ if (mtk_is_netsys_v3_or_greater(mac->hw) &&
-+ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) &&
-+ id == MTK_GMAC1_ID) {
-+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
-+ MAC_SYM_PAUSE |
-+ MAC_10000FD;
-+ phy_interface_zero(mac->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ mac->phylink_config.supported_interfaces);
-+ }
-+
- phylink = phylink_create(&mac->phylink_config,
- of_fwnode_handle(mac->of_node),
- phy_mode, &mtk_phylink_ops);
-@@ -4828,6 +4968,24 @@ static const struct mtk_soc_data mt7986_
- },
- };
-
-+static const struct mtk_soc_data mt7988_data = {
-+ .reg_map = &mt7988_reg_map,
-+ .ana_rgc3 = 0x128,
-+ .caps = MT7988_CAPS,
-+ .hw_features = MTK_HW_FEATURES,
-+ .required_clks = MT7988_CLKS_BITMAP,
-+ .required_pctl = false,
-+ .version = 3,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+};
-+
- static const struct mtk_soc_data rt5350_data = {
- .reg_map = &mt7628_reg_map,
- .caps = MT7628_CAPS,
-@@ -4846,14 +5004,15 @@ static const struct mtk_soc_data rt5350_
- };
-
- const struct of_device_id of_mtk_match[] = {
-- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
-- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
-- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
-- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
-- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
-- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
-- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
-- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
-+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
-+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
-+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
-+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
-+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
-+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
-+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
-+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
-+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
- {},
- };
- MODULE_DEVICE_TABLE(of, of_mtk_match);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -117,7 +117,8 @@
- #define MTK_CDMP_EG_CTRL 0x404
-
- /* GDM Exgress Control Register */
--#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
-+#define MTK_GDMA_FWD_CFG(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x540 : 0x500 + (_x * 0x1000); })
- #define MTK_GDMA_SPECIAL_TAG BIT(24)
- #define MTK_GDMA_ICS_EN BIT(22)
- #define MTK_GDMA_TCS_EN BIT(21)
-@@ -126,6 +127,11 @@
- #define MTK_GDMA_TO_PDMA 0x0
- #define MTK_GDMA_DROP_ALL 0x7777
-
-+/* GDM Egress Control Register */
-+#define MTK_GDMA_EG_CTRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x544 : 0x504 + (_x * 0x1000); })
-+#define MTK_GDMA_XGDM_SEL BIT(31)
-+
- /* Unicast Filter MAC Address Register - Low */
- #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
-
-@@ -386,7 +392,26 @@
- #define PHY_IAC_TIMEOUT HZ
-
- #define MTK_MAC_MISC 0x1000c
-+#define MTK_MAC_MISC_V3 0x10010
- #define MTK_MUX_TO_ESW BIT(0)
-+#define MISC_MDC_TURBO BIT(4)
-+
-+/* XMAC status registers */
-+#define MTK_XGMAC_STS(x) (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C)
-+#define MTK_XGMAC_FORCE_LINK(x) (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15))
-+#define MTK_USXGMII_PCS_LINK BIT(8)
-+#define MTK_XGMAC_RX_FC BIT(5)
-+#define MTK_XGMAC_TX_FC BIT(4)
-+#define MTK_USXGMII_PCS_MODE GENMASK(3, 1)
-+#define MTK_XGMAC_LINK_STS BIT(0)
-+
-+/* GSW bridge registers */
-+#define MTK_GSW_CFG (0x10080)
-+#define GSWTX_IPG_MASK GENMASK(19, 16)
-+#define GSWTX_IPG_SHIFT 16
-+#define GSWRX_IPG_MASK GENMASK(3, 0)
-+#define GSWRX_IPG_SHIFT 0
-+#define GSW_IPG_11 11
-
- /* Mac control registers */
- #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100))
-@@ -644,6 +669,11 @@ enum mtk_clks_map {
- MTK_CLK_GP0,
- MTK_CLK_GP1,
- MTK_CLK_GP2,
-+ MTK_CLK_GP3,
-+ MTK_CLK_XGP1,
-+ MTK_CLK_XGP2,
-+ MTK_CLK_XGP3,
-+ MTK_CLK_CRYPTO,
- MTK_CLK_FE,
- MTK_CLK_TRGPLL,
- MTK_CLK_SGMII_TX_250M,
-@@ -660,6 +690,27 @@ enum mtk_clks_map {
- MTK_CLK_WOCPU1,
- MTK_CLK_NETSYS0,
- MTK_CLK_NETSYS1,
-+ MTK_CLK_ETHWARP_WOCPU2,
-+ MTK_CLK_ETHWARP_WOCPU1,
-+ MTK_CLK_ETHWARP_WOCPU0,
-+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
-+ MTK_CLK_TOP_SGM_0_SEL,
-+ MTK_CLK_TOP_SGM_1_SEL,
-+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
-+ MTK_CLK_TOP_ETH_GMII_SEL,
-+ MTK_CLK_TOP_ETH_REFCK_50M_SEL,
-+ MTK_CLK_TOP_ETH_SYS_200M_SEL,
-+ MTK_CLK_TOP_ETH_SYS_SEL,
-+ MTK_CLK_TOP_ETH_XGMII_SEL,
-+ MTK_CLK_TOP_ETH_MII_SEL,
-+ MTK_CLK_TOP_NETSYS_SEL,
-+ MTK_CLK_TOP_NETSYS_500M_SEL,
-+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
-+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
-+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
-+ MTK_CLK_TOP_NETSYS_WARP_SEL,
- MTK_CLK_MAX
- };
-
-@@ -713,6 +764,36 @@ enum mtk_clks_map {
- BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
- BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
- BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
-+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
-+ BIT_ULL(MTK_CLK_CRYPTO) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
-+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
-+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
-
- enum mtk_dev_state {
- MTK_HW_INIT,
-@@ -961,6 +1042,8 @@ enum mkt_eth_capabilities {
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_RSTCTRL_PPE1)
-
-+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
-+
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
- u32 size;
-@@ -1306,6 +1389,7 @@ void mtk_stats_update_mac(struct mtk_mac
-
- 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_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
diff --git a/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch
deleted file mode 100644
index 95bf60da80..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 27 Jul 2023 09:02:26 +0200
-Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support
- for MT7988 SoC
-
-In order to recycle pages, enable page_pool allocator for MT7988 SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1612,7 +1612,7 @@ static void mtk_update_rx_cpu_idx(struct
-
- static bool mtk_page_pool_enabled(struct mtk_eth *eth)
- {
-- return eth->soc->version == 2;
-+ return mtk_is_netsys_v2_or_greater(eth);
- }
-
- static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
diff --git a/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch
deleted file mode 100644
index 5205914c4f..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 27 Jul 2023 09:07:28 +0200
-Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw
- flowtable_offload for MT7988 SoC
-
-Enable hw Packet Process Engine (PPE) for MT7988 SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
- drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++----
- drivers/net/ethernet/mediatek/mtk_ppe.h | 19 ++++++++++++++++++-
- 3 files changed, 36 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4976,6 +4976,9 @@ static const struct mtk_soc_data mt7988_
- .required_clks = MT7988_CLKS_BITMAP,
- .required_pctl = false,
- .version = 3,
-+ .offload_version = 2,
-+ .hash_offset = 4,
-+ .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ switch (eth->soc->version) {
-+ case 3:
-+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
-+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
-+ MTK_FOE_IB2_WDMA_WINFO_V2;
-+ l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
-+ FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
-+ break;
-+ case 2:
- *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
- *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
- MTK_FOE_IB2_WDMA_WINFO_V2;
- l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
- FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
-- } else {
-+ break;
-+ default:
- *ib2 &= ~MTK_FOE_IB2_PORT_MG;
- *ib2 |= MTK_FOE_IB2_WDMA_WINFO;
- if (wdma_idx)
-@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
- FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
- FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
-+ break;
- }
-
- return 0;
-@@ -956,8 +966,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- mtk_ppe_init_foe_table(ppe);
- ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
-
-- val = MTK_PPE_TB_CFG_ENTRY_80B |
-- MTK_PPE_TB_CFG_AGE_NON_L4 |
-+ val = MTK_PPE_TB_CFG_AGE_NON_L4 |
- MTK_PPE_TB_CFG_AGE_UNBIND |
- MTK_PPE_TB_CFG_AGE_TCP |
- MTK_PPE_TB_CFG_AGE_UDP |
-@@ -973,6 +982,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_ENTRIES_SHIFT);
- if (mtk_is_netsys_v2_or_greater(ppe->eth))
- val |= MTK_PPE_TB_CFG_INFO_SEL;
-+ if (!mtk_is_netsys_v3_or_greater(ppe->eth))
-+ val |= MTK_PPE_TB_CFG_ENTRY_80B;
- ppe_w32(ppe, MTK_PPE_TB_CFG, val);
-
- ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK,
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -85,6 +85,17 @@ enum {
- #define MTK_FOE_WINFO_BSS GENMASK(5, 0)
- #define MTK_FOE_WINFO_WCID GENMASK(15, 6)
-
-+#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16)
-+#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0)
-+
-+#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0)
-+#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16)
-+#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20)
-+#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21)
-+#define MTK_FOE_WINFO_PAO_IS_SP BIT(22)
-+#define MTK_FOE_WINFO_PAO_HF BIT(23)
-+#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24)
-+
- enum {
- MTK_FOE_STATE_INVALID,
- MTK_FOE_STATE_UNBIND,
-@@ -106,8 +117,13 @@ struct mtk_foe_mac_info {
- u16 pppoe_id;
- u16 src_mac_lo;
-
-+ /* netsys_v2 */
- u16 minfo;
- u16 winfo;
-+
-+ /* netsys_v3 */
-+ u32 w3info;
-+ u32 wpao;
- };
-
- /* software-only entry type */
-@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd {
-
- #define MTK_FOE_ENTRY_V1_SIZE 80
- #define MTK_FOE_ENTRY_V2_SIZE 96
-+#define MTK_FOE_ENTRY_V3_SIZE 128
-
- struct mtk_foe_entry {
- u32 ib1;
-@@ -228,7 +245,7 @@ struct mtk_foe_entry {
- struct mtk_foe_ipv4_dslite dslite;
- struct mtk_foe_ipv6 ipv6;
- struct mtk_foe_ipv6_6rd ipv6_6rd;
-- u32 data[23];
-+ u32 data[31];
- };
- };
-
diff --git a/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch
deleted file mode 100644
index 8a48976126..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 2 Aug 2023 04:31:09 +0100
-Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow
- accounting on MT7988
-
-NETSYS_V3 uses 64 bits for each counters while older SoCs are using
-48/40 bits for each counter.
-Support reading per-flow byte and package counters on NETSYS_V3.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
- drivers/net/ethernet/mediatek/mtk_ppe.c | 21 +++++++++++++-------
- drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 2 ++
- 3 files changed, 17 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4978,6 +4978,7 @@ static const struct mtk_soc_data mt7988_
- .version = 3,
- .offload_version = 2,
- .hash_offset = 4,
-+ .has_accounting = true,
- .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct
-
- static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
- {
-- u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
- u32 val, cnt_r0, cnt_r1, cnt_r2;
- int ret;
-
-@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk
- cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
- cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
-
-- byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-- byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-- pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-- pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-- *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+ if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
-+ /* 64 bit for each counter */
-+ u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
-+ *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
-+ *packets = ((u64)cnt_r3 << 32) | cnt_r2;
-+ } else {
-+ /* 48 bit byte counter, 40 bit packet counter */
-+ u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-+ u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-+ u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-+ u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+ }
-
- return 0;
- }
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -163,6 +163,8 @@ enum {
- #define MTK_PPE_MIB_SER_R2 0x348
- #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0)
-
-+#define MTK_PPE_MIB_SER_R3 0x34c
-+
- #define MTK_PPE_MIB_CACHE_CTL 0x350
- #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
- #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)
diff --git a/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch
deleted file mode 100644
index 6f1639a572..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 21 Aug 2023 17:12:44 +0100
-Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw
- reset
-
-When a hardware reset is triggered on devices not initializing WED the
-calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a
-pointer on uninitialized stack memory.
-Break out of both functions in case a hw_list entry is 0.
-
-Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void)
-
- for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
- struct mtk_wed_hw *hw = hw_list[i];
-- struct mtk_wed_device *dev = hw->wed_dev;
-+ struct mtk_wed_device *dev;
- int err;
-
-+ if (!hw)
-+ break;
-+
-+ dev = hw->wed_dev;
- if (!dev || !dev->wlan.reset)
- continue;
-
-@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void)
-
- for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
- struct mtk_wed_hw *hw = hw_list[i];
-- struct mtk_wed_device *dev = hw->wed_dev;
-+ struct mtk_wed_device *dev;
-+
-+ if (!hw)
-+ break;
-
-+ dev = hw->wed_dev;
- if (!dev || !dev->wlan.reset_complete)
- continue;
-
diff --git a/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch
deleted file mode 100644
index 35977946d3..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:31:24 +0100
-Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions
- for MT7988
-
-More register macros need to be adjusted for the 3rd GMAC on MT7988.
-Account for added bit in SYSCFG0_SGMII_MASK.
-
-Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -133,10 +133,12 @@
- #define MTK_GDMA_XGDM_SEL BIT(31)
-
- /* Unicast Filter MAC Address Register - Low */
--#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
-+#define MTK_GDMA_MAC_ADRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x548 : 0x508 + (_x * 0x1000); })
-
- /* Unicast Filter MAC Address Register - High */
--#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
-+#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x54C : 0x50C + (_x * 0x1000); })
-
- /* FE global misc reg*/
- #define MTK_FE_GLO_MISC 0x124
-@@ -500,7 +502,7 @@
- #define ETHSYS_SYSCFG0 0x14
- #define SYSCFG0_GE_MASK 0x3
- #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2)))
--#define SYSCFG0_SGMII_MASK GENMASK(9, 8)
-+#define SYSCFG0_SGMII_MASK GENMASK(9, 7)
- #define SYSCFG0_SGMII_GMAC1 ((2 << 8) & SYSCFG0_SGMII_MASK)
- #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK)
- #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
diff --git a/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch
deleted file mode 100644
index 963807aa45..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:32:03 +0100
-Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988
-
-Add bits needed to reset the frame engine on MT7988.
-
-Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++--
- 2 files changed, 68 insertions(+), 24 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3540,19 +3540,34 @@ static void mtk_hw_reset(struct mtk_eth
- {
- u32 val;
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v2_or_greater(eth))
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-+
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ val = RSTCTRL_PPE0_V3;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1_V3;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ val |= RSTCTRL_PPE2;
-+
-+ val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
-+ } else if (mtk_is_netsys_v2_or_greater(eth)) {
- val = RSTCTRL_PPE0_V2;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1;
- } else {
- val = RSTCTRL_PPE0;
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val |= RSTCTRL_PPE1;
--
- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-
-- if (mtk_is_netsys_v2_or_greater(eth))
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-+ 0x6f8ff);
-+ else if (mtk_is_netsys_v2_or_greater(eth))
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
- 0x3ffffff);
- }
-@@ -3578,13 +3593,21 @@ static void mtk_hw_warm_reset(struct mtk
- return;
- }
-
-- if (mtk_is_netsys_v2_or_greater(eth))
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ rst_mask |= RSTCTRL_PPE1_V3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ rst_mask |= RSTCTRL_PPE2;
-+
-+ rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
-+ } else if (mtk_is_netsys_v2_or_greater(eth)) {
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
-- else
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ rst_mask |= RSTCTRL_PPE1;
-+ } else {
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
--
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- rst_mask |= RSTCTRL_PPE1;
-+ }
-
- regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
-
-@@ -3936,11 +3959,17 @@ static void mtk_prepare_for_reset(struct
- u32 val;
- int i;
-
-- /* disabe FE P3 and P4 */
-- val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val |= MTK_FE_LINK_DOWN_P4;
-- mtk_w32(eth, val, MTK_FE_GLO_CFG);
-+ /* set FE PPE ports link down */
-+ for (i = MTK_GMAC1_ID;
-+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
-+ i += 2) {
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
-+ }
-
- /* adjust PPE configurations to prepare for reset */
- for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
-@@ -4001,11 +4030,18 @@ static void mtk_pending_work(struct work
- }
- }
-
-- /* enabe FE P3 and P4 */
-- val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val &= ~MTK_FE_LINK_DOWN_P4;
-- mtk_w32(eth, val, MTK_FE_GLO_CFG);
-+ /* set FE PPE ports link up */
-+ for (i = MTK_GMAC1_ID;
-+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
-+ i += 2) {
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
-+
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
-+ }
-
- clear_bit(MTK_RESETTING, &eth->state);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -76,9 +76,8 @@
- #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522
-
- /* Frame Engine Global Configuration */
--#define MTK_FE_GLO_CFG 0x00
--#define MTK_FE_LINK_DOWN_P3 BIT(11)
--#define MTK_FE_LINK_DOWN_P4 BIT(12)
-+#define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00)
-+#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16)
-
- /* Frame Engine Global Reset Register */
- #define MTK_RST_GL 0x04
-@@ -519,9 +518,15 @@
- /* ethernet reset control register */
- #define ETHSYS_RSTCTRL 0x34
- #define RSTCTRL_FE BIT(6)
-+#define RSTCTRL_WDMA0 BIT(24)
-+#define RSTCTRL_WDMA1 BIT(25)
-+#define RSTCTRL_WDMA2 BIT(26)
- #define RSTCTRL_PPE0 BIT(31)
- #define RSTCTRL_PPE0_V2 BIT(30)
- #define RSTCTRL_PPE1 BIT(31)
-+#define RSTCTRL_PPE0_V3 BIT(29)
-+#define RSTCTRL_PPE1_V3 BIT(30)
-+#define RSTCTRL_PPE2 BIT(31)
- #define RSTCTRL_ETH BIT(23)
-
- /* ethernet reset check idle register */
-@@ -928,6 +933,7 @@ enum mkt_eth_capabilities {
- MTK_QDMA_BIT,
- MTK_SOC_MT7628_BIT,
- MTK_RSTCTRL_PPE1_BIT,
-+ MTK_RSTCTRL_PPE2_BIT,
- MTK_U3_COPHY_V2_BIT,
-
- /* MUX BITS*/
-@@ -962,6 +968,7 @@ enum mkt_eth_capabilities {
- #define MTK_QDMA BIT_ULL(MTK_QDMA_BIT)
- #define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
- #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
-@@ -1044,7 +1051,8 @@ enum mkt_eth_capabilities {
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_RSTCTRL_PPE1)
-
--#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
-+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
-+ MTK_RSTCTRL_PPE2)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch
deleted file mode 100644
index e224443e43..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:32:54 +0100
-Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC
- SRAM
-
-MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet
-DMA rings. Support using the SRAM without breaking existing device tree
-bindings, ie. only new SoC starting from MT7988 will have the SRAM
-declared as additional resource in device tree. For MT7981 and MT7986
-an offset on top of the main I/O base is used.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++-----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++-
- 2 files changed, 78 insertions(+), 22 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1074,10 +1074,13 @@ static int mtk_init_fq_dma(struct mtk_et
- dma_addr_t dma_addr;
- int i;
-
-- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
-- cnt * soc->txrx.txd_size,
-- &eth->phy_scratch_ring,
-- GFP_KERNEL);
-+ 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->txrx.txd_size,
-+ &eth->phy_scratch_ring,
-+ GFP_KERNEL);
- if (unlikely(!eth->scratch_ring))
- return -ENOMEM;
-
-@@ -2375,8 +2378,14 @@ static int mtk_tx_alloc(struct mtk_eth *
- if (!ring->buf)
- goto no_tx_mem;
-
-- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
-- &ring->phys, GFP_KERNEL);
-+ if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
-+ ring->dma = eth->sram_base + ring_size * sz;
-+ ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
-+ } else {
-+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
-+ &ring->phys, GFP_KERNEL);
-+ }
-+
- if (!ring->dma)
- goto no_tx_mem;
-
-@@ -2475,8 +2484,7 @@ static void mtk_tx_clean(struct mtk_eth
- kfree(ring->buf);
- ring->buf = NULL;
- }
--
-- if (ring->dma) {
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
- dma_free_coherent(eth->dma_dev,
- ring->dma_size * soc->txrx.txd_size,
- ring->dma, ring->phys);
-@@ -2495,9 +2503,14 @@ static int mtk_rx_alloc(struct mtk_eth *
- {
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct mtk_rx_ring *ring;
-- int rx_data_len, rx_dma_size;
-+ int rx_data_len, rx_dma_size, tx_ring_size;
- int i;
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-+ tx_ring_size = MTK_QDMA_RING_SIZE;
-+ else
-+ tx_ring_size = MTK_DMA_SIZE;
-+
- if (rx_flag == MTK_RX_FLAGS_QDMA) {
- if (ring_no)
- return -EINVAL;
-@@ -2532,9 +2545,20 @@ static int mtk_rx_alloc(struct mtk_eth *
- ring->page_pool = pp;
- }
-
-- ring->dma = dma_alloc_coherent(eth->dma_dev,
-- rx_dma_size * eth->soc->txrx.rxd_size,
-- &ring->phys, GFP_KERNEL);
-+ 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->txrx.rxd_size,
-+ &ring->phys, GFP_KERNEL);
-+ } else {
-+ struct mtk_tx_ring *tx_ring = &eth->tx_ring;
-+
-+ ring->dma = tx_ring->dma + tx_ring_size *
-+ eth->soc->txrx.txd_size * (ring_no + 1);
-+ ring->phys = tx_ring->phys + tx_ring_size *
-+ eth->soc->txrx.txd_size * (ring_no + 1);
-+ }
-+
- if (!ring->dma)
- return -ENOMEM;
-
-@@ -2617,7 +2641,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- return 0;
- }
-
--static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
-+static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
- {
- int i;
-
-@@ -2640,7 +2664,7 @@ static void mtk_rx_clean(struct mtk_eth
- ring->data = NULL;
- }
-
-- if (ring->dma) {
-+ if (!in_sram && ring->dma) {
- dma_free_coherent(eth->dma_dev,
- ring->dma_size * eth->soc->txrx.rxd_size,
- ring->dma, ring->phys);
-@@ -3003,7 +3027,7 @@ static void mtk_dma_free(struct mtk_eth
- for (i = 0; i < MTK_MAX_DEVS; i++)
- if (eth->netdev[i])
- netdev_reset_queue(eth->netdev[i]);
-- if (eth->scratch_ring) {
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
- dma_free_coherent(eth->dma_dev,
- MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
- eth->scratch_ring, eth->phy_scratch_ring);
-@@ -3011,13 +3035,13 @@ static void mtk_dma_free(struct mtk_eth
- eth->phy_scratch_ring = 0;
- }
- mtk_tx_clean(eth);
-- mtk_rx_clean(eth, &eth->rx_ring[0]);
-- mtk_rx_clean(eth, &eth->rx_ring_qdma);
-+ mtk_rx_clean(eth, &eth->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM));
-+ mtk_rx_clean(eth, &eth->rx_ring_qdma, false);
-
- if (eth->hwlro) {
- mtk_hwlro_rx_uninit(eth);
- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
-- mtk_rx_clean(eth, &eth->rx_ring[i]);
-+ mtk_rx_clean(eth, &eth->rx_ring[i], false);
- }
-
- kfree(eth->scratch_head);
-@@ -4587,7 +4611,7 @@ static int mtk_sgmii_init(struct mtk_eth
-
- static int mtk_probe(struct platform_device *pdev)
- {
-- struct resource *res = NULL;
-+ struct resource *res = NULL, *res_sram;
- struct device_node *mac_np;
- struct mtk_eth *eth;
- int err, i;
-@@ -4607,6 +4631,20 @@ static int mtk_probe(struct platform_dev
- 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;
-+ }
-+ }
-+
- spin_lock_init(&eth->page_lock);
- spin_lock_init(&eth->tx_irq_lock);
- spin_lock_init(&eth->rx_irq_lock);
-@@ -4670,6 +4708,18 @@ static int mtk_probe(struct platform_dev
- 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) {
-+ err = -EINVAL;
-+ goto err_destroy_sgmii;
-+ }
-+ eth->phy_scratch_ring = res_sram->start;
-+ } else {
-+ eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET;
-+ }
-+ }
- }
-
- if (eth->soc->offload_version) {
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -139,6 +139,9 @@
- #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
-+
- /* FE global misc reg*/
- #define MTK_FE_GLO_MISC 0x124
-
-@@ -935,6 +938,7 @@ enum mkt_eth_capabilities {
- MTK_RSTCTRL_PPE1_BIT,
- MTK_RSTCTRL_PPE2_BIT,
- MTK_U3_COPHY_V2_BIT,
-+ MTK_SRAM_BIT,
-
- /* MUX BITS*/
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-@@ -970,6 +974,7 @@ enum mkt_eth_capabilities {
- #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
- #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
- #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
-+#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -1045,14 +1050,14 @@ 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_RSTCTRL_PPE1 | MTK_SRAM)
-
- #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
-- MTK_RSTCTRL_PPE1)
-+ MTK_RSTCTRL_PPE1 | MTK_SRAM)
-
- #define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
-- MTK_RSTCTRL_PPE2)
-+ MTK_RSTCTRL_PPE2 | MTK_SRAM)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
-@@ -1212,6 +1217,7 @@ struct mtk_eth {
- struct device *dev;
- struct device *dma_dev;
- void __iomem *base;
-+ void *sram_base;
- spinlock_t page_lock;
- spinlock_t tx_irq_lock;
- spinlock_t rx_irq_lock;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch
deleted file mode 100644
index 528f9a3e5c..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:33:12 +0100
-Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA
- addressing on MT7988
-
-Systems having 4 GiB of RAM and more require DMA addressing beyond the
-current 32-bit limit. Starting from MT7988 the hardware now supports
-36-bit DMA addressing, let's use that new capability in the driver to
-avoid running into swiotlb on systems with 4 GiB of RAM or more.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++--
- 2 files changed, 48 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1265,6 +1265,10 @@ static void mtk_tx_set_dma_desc_v2(struc
- data = TX_DMA_PLEN0(info->size);
- if (info->last)
- data |= TX_DMA_LS0;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ data |= TX_DMA_PREP_ADDR64(info->addr);
-+
- WRITE_ONCE(desc->txd3, data);
-
- /* set forward port */
-@@ -1932,6 +1936,7 @@ static int mtk_poll_rx(struct napi_struc
- bool xdp_flush = false;
- int idx;
- struct sk_buff *skb;
-+ u64 addr64 = 0;
- u8 *data, *new_data;
- struct mtk_rx_dma_v2 *rxd, trxd;
- int done = 0, bytes = 0;
-@@ -2047,7 +2052,10 @@ static int mtk_poll_rx(struct napi_struc
- goto release_desc;
- }
-
-- dma_unmap_single(eth->dma_dev, trxd.rxd1,
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ addr64 = RX_DMA_GET_ADDR64(trxd.rxd2);
-+
-+ dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
- ring->buf_size, DMA_FROM_DEVICE);
-
- skb = build_skb(data, ring->frag_size);
-@@ -2113,6 +2121,9 @@ release_desc:
- else
- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
-+
- ring->calc_idx = idx;
- done++;
- }
-@@ -2597,6 +2608,9 @@ static int mtk_rx_alloc(struct mtk_eth *
- else
- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
-+
- rxd->rxd3 = 0;
- rxd->rxd4 = 0;
- if (mtk_is_netsys_v2_or_greater(eth)) {
-@@ -2643,6 +2657,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-
- static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
- {
-+ u64 addr64 = 0;
- int i;
-
- if (ring->data && ring->dma) {
-@@ -2656,7 +2671,10 @@ static void mtk_rx_clean(struct mtk_eth
- if (!rxd->rxd1)
- continue;
-
-- dma_unmap_single(eth->dma_dev, rxd->rxd1,
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ addr64 = RX_DMA_GET_ADDR64(rxd->rxd2);
-+
-+ dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64),
- ring->buf_size, DMA_FROM_DEVICE);
- mtk_rx_put_buff(ring, ring->data[i], false);
- }
-@@ -4645,6 +4663,14 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
-+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
-+ if (err) {
-+ dev_err(&pdev->dev, "Wrong DMA config\n");
-+ return -EINVAL;
-+ }
-+ }
-+
- spin_lock_init(&eth->page_lock);
- spin_lock_init(&eth->tx_irq_lock);
- spin_lock_init(&eth->rx_irq_lock);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -331,6 +331,14 @@
- #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len)
- #define TX_DMA_SWC BIT(14)
- #define TX_DMA_PQID GENMASK(3, 0)
-+#define TX_DMA_ADDR64_MASK GENMASK(3, 0)
-+#if IS_ENABLED(CONFIG_64BIT)
-+# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32)
-+# define TX_DMA_PREP_ADDR64(x) FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32))
-+#else
-+# define TX_DMA_GET_ADDR64(x) (0)
-+# define TX_DMA_PREP_ADDR64(x) (0)
-+#endif
-
- /* PDMA on MT7628 */
- #define TX_DMA_DONE BIT(31)
-@@ -343,6 +351,14 @@
- #define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
- #define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
- #define RX_DMA_VTAG BIT(15)
-+#define RX_DMA_ADDR64_MASK GENMASK(3, 0)
-+#if IS_ENABLED(CONFIG_64BIT)
-+# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32)
-+# define RX_DMA_PREP_ADDR64(x) FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32))
-+#else
-+# define RX_DMA_GET_ADDR64(x) (0)
-+# define RX_DMA_PREP_ADDR64(x) (0)
-+#endif
-
- /* QDMA descriptor rxd3 */
- #define RX_DMA_VID(x) ((x) & VLAN_VID_MASK)
-@@ -939,6 +955,7 @@ enum mkt_eth_capabilities {
- MTK_RSTCTRL_PPE2_BIT,
- MTK_U3_COPHY_V2_BIT,
- MTK_SRAM_BIT,
-+ MTK_36BIT_DMA_BIT,
-
- /* MUX BITS*/
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-@@ -975,6 +992,7 @@ enum mkt_eth_capabilities {
- #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
- #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
- #define MTK_SRAM BIT_ULL(MTK_SRAM_BIT)
-+#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -1056,8 +1074,8 @@ enum mkt_eth_capabilities {
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_RSTCTRL_PPE1 | MTK_SRAM)
-
--#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
-- MTK_RSTCTRL_PPE2 | MTK_SRAM)
-+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
-+ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch b/target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch
deleted file mode 100644
index 959add1954..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From e10a35abb3da12b812cfb6fc6137926a0c81e39a Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 10 Sep 2023 22:40:30 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix uninitialized variable
-
-Variable dma_addr in function mtk_poll_rx can be uninitialized on
-some of the error paths. In practise this doesn't matter, even random
-data present in uninitialized stack memory can safely be used in the
-way it happens in the error path.
-
-However, in order to make Smatch happy make sure the variable is
-always initialized.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1940,11 +1940,11 @@ static int mtk_poll_rx(struct napi_struc
- u8 *data, *new_data;
- struct mtk_rx_dma_v2 *rxd, trxd;
- int done = 0, bytes = 0;
-+ dma_addr_t dma_addr = DMA_MAPPING_ERROR;
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
- struct net_device *netdev;
-- dma_addr_t dma_addr;
- u32 hash, reason;
- int mac = 0;
-
-@@ -2121,7 +2121,8 @@ release_desc:
- else
- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) &&
-+ likely(dma_addr != DMA_MAPPING_ERROR))
- rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
-
- ring->calc_idx = idx;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch b/target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch
deleted file mode 100644
index ac3e3a3e67..0000000000
--- a/target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 5a124b1fd3e6cb15a943f0cdfe96aa8f6d3d2f39 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 9 Sep 2023 20:41:56 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix pse_port configuration for
- MT7988
-
-MT7988 SoC support 3 NICs. Fix pse_port configuration in
-mtk_flow_set_output_device routine if the traffic is offloaded to eth2.
-Rely on mtk_pse_port definitions.
-
-Fixes: 88efedf517e6 ("net: ethernet: mtk_eth_soc: enable nft hw flowtable_offload for MT7988 SoC")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -214,9 +214,11 @@ mtk_flow_set_output_device(struct mtk_et
- dsa_port = mtk_flow_get_dsa_port(&dev);
-
- if (dev == eth->netdev[0])
-- pse_port = 1;
-+ pse_port = PSE_GDM1_PORT;
- else if (dev == eth->netdev[1])
-- pse_port = 2;
-+ pse_port = PSE_GDM2_PORT;
-+ else if (dev == eth->netdev[2])
-+ pse_port = PSE_GDM3_PORT;
- else
- return -EOPNOTSUPP;
-
diff --git a/target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch
deleted file mode 100644
index 21d0f045d9..0000000000
--- a/target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch
+++ /dev/null
@@ -1,271 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 20 Mar 2023 11:44:30 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add code for offloading flows
- from wlan devices
-
-WED version 2 (on MT7986 and later) can offload flows originating from wireless
-devices. In order to make that work, ndo_setup_tc needs to be implemented on
-the netdevs. This adds the required code to offload flows coming in from WED,
-while keeping track of the incoming wed index used for selecting the correct
-PPE device.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 37 ++++---
- drivers/net/ethernet/mediatek/mtk_wed.c | 101 ++++++++++++++++++
- include/linux/soc/mediatek/mtk_wed.h | 6 ++
- 4 files changed, 133 insertions(+), 14 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1432,6 +1432,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
- int mtk_eth_offload_init(struct mtk_eth *eth);
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
- void *type_data);
-+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
-+ int ppe_index);
-+void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
- void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
-
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -237,7 +237,8 @@ out:
- }
-
- static int
--mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
-+mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f,
-+ int ppe_index)
- {
- struct flow_rule *rule = flow_cls_offload_flow_rule(f);
- struct flow_action_entry *act;
-@@ -454,6 +455,7 @@ mtk_flow_offload_replace(struct mtk_eth
- entry->cookie = f->cookie;
- memcpy(&entry->data, &foe, sizeof(entry->data));
- entry->wed_index = wed_index;
-+ entry->ppe_index = ppe_index;
-
- err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry);
- if (err < 0)
-@@ -522,25 +524,15 @@ mtk_flow_offload_stats(struct mtk_eth *e
-
- static DEFINE_MUTEX(mtk_flow_offload_mutex);
-
--static int
--mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
-+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
-+ int ppe_index)
- {
-- struct flow_cls_offload *cls = type_data;
-- struct net_device *dev = cb_priv;
-- struct mtk_mac *mac = netdev_priv(dev);
-- struct mtk_eth *eth = mac->hw;
- int err;
-
-- if (!tc_can_offload(dev))
-- return -EOPNOTSUPP;
--
-- if (type != TC_SETUP_CLSFLOWER)
-- return -EOPNOTSUPP;
--
- mutex_lock(&mtk_flow_offload_mutex);
- switch (cls->command) {
- case FLOW_CLS_REPLACE:
-- err = mtk_flow_offload_replace(eth, cls);
-+ err = mtk_flow_offload_replace(eth, cls, ppe_index);
- break;
- case FLOW_CLS_DESTROY:
- err = mtk_flow_offload_destroy(eth, cls);
-@@ -558,6 +550,23 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_
- }
-
- static int
-+mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
-+{
-+ struct flow_cls_offload *cls = type_data;
-+ struct net_device *dev = cb_priv;
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+
-+ if (!tc_can_offload(dev))
-+ return -EOPNOTSUPP;
-+
-+ if (type != TC_SETUP_CLSFLOWER)
-+ return -EOPNOTSUPP;
-+
-+ return mtk_flow_offload_cmd(eth, cls, 0);
-+}
-+
-+static int
- mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
- {
- struct mtk_mac *mac = netdev_priv(dev);
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -13,6 +13,8 @@
- #include <linux/mfd/syscon.h>
- #include <linux/debugfs.h>
- #include <linux/soc/mediatek/mtk_wed.h>
-+#include <net/flow_offload.h>
-+#include <net/pkt_cls.h>
- #include "mtk_eth_soc.h"
- #include "mtk_wed_regs.h"
- #include "mtk_wed.h"
-@@ -41,6 +43,11 @@
- static struct mtk_wed_hw *hw_list[2];
- static DEFINE_MUTEX(hw_lock);
-
-+struct mtk_wed_flow_block_priv {
-+ struct mtk_wed_hw *hw;
-+ struct net_device *dev;
-+};
-+
- static void
- wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
- {
-@@ -1753,6 +1760,99 @@ out:
- mutex_unlock(&hw_lock);
- }
-
-+static int
-+mtk_wed_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
-+{
-+ struct mtk_wed_flow_block_priv *priv = cb_priv;
-+ struct flow_cls_offload *cls = type_data;
-+ struct mtk_wed_hw *hw = priv->hw;
-+
-+ if (!tc_can_offload(priv->dev))
-+ return -EOPNOTSUPP;
-+
-+ if (type != TC_SETUP_CLSFLOWER)
-+ return -EOPNOTSUPP;
-+
-+ return mtk_flow_offload_cmd(hw->eth, cls, hw->index);
-+}
-+
-+static int
-+mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev,
-+ struct flow_block_offload *f)
-+{
-+ struct mtk_wed_flow_block_priv *priv;
-+ static LIST_HEAD(block_cb_list);
-+ struct flow_block_cb *block_cb;
-+ struct mtk_eth *eth = hw->eth;
-+ flow_setup_cb_t *cb;
-+
-+ if (!eth->soc->offload_version)
-+ return -EOPNOTSUPP;
-+
-+ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
-+ return -EOPNOTSUPP;
-+
-+ cb = mtk_wed_setup_tc_block_cb;
-+ f->driver_block_list = &block_cb_list;
-+
-+ switch (f->command) {
-+ case FLOW_BLOCK_BIND:
-+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
-+ if (block_cb) {
-+ flow_block_cb_incref(block_cb);
-+ return 0;
-+ }
-+
-+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->hw = hw;
-+ priv->dev = dev;
-+ block_cb = flow_block_cb_alloc(cb, dev, priv, NULL);
-+ if (IS_ERR(block_cb)) {
-+ kfree(priv);
-+ return PTR_ERR(block_cb);
-+ }
-+
-+ flow_block_cb_incref(block_cb);
-+ flow_block_cb_add(block_cb, f);
-+ list_add_tail(&block_cb->driver_list, &block_cb_list);
-+ return 0;
-+ case FLOW_BLOCK_UNBIND:
-+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
-+ if (!block_cb)
-+ return -ENOENT;
-+
-+ if (!flow_block_cb_decref(block_cb)) {
-+ flow_block_cb_remove(block_cb, f);
-+ list_del(&block_cb->driver_list);
-+ kfree(block_cb->cb_priv);
-+ }
-+ return 0;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int
-+mtk_wed_setup_tc(struct mtk_wed_device *wed, struct net_device *dev,
-+ enum tc_setup_type type, void *type_data)
-+{
-+ struct mtk_wed_hw *hw = wed->hw;
-+
-+ if (hw->version < 2)
-+ return -EOPNOTSUPP;
-+
-+ switch (type) {
-+ case TC_SETUP_BLOCK:
-+ case TC_SETUP_FT:
-+ return mtk_wed_setup_tc_block(hw, dev, type_data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
- void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, phys_addr_t wdma_phy,
- int index)
-@@ -1772,6 +1872,7 @@ void mtk_wed_add_hw(struct device_node *
- .irq_set_mask = mtk_wed_irq_set_mask,
- .detach = mtk_wed_detach,
- .ppe_check = mtk_wed_ppe_check,
-+ .setup_tc = mtk_wed_setup_tc,
- };
- struct device_node *eth_np = eth->dev->of_node;
- struct platform_device *pdev;
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -6,6 +6,7 @@
- #include <linux/regmap.h>
- #include <linux/pci.h>
- #include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-
- #define MTK_WED_TX_QUEUES 2
- #define MTK_WED_RX_QUEUES 2
-@@ -180,6 +181,8 @@ struct mtk_wed_ops {
-
- u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
- void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
-+ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev,
-+ enum tc_setup_type type, void *type_data);
- };
-
- extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -238,6 +241,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- (_dev)->ops->msg_update(_dev, _id, _msg, _len)
- #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
- #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
-+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \
-+ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data)
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -256,6 +261,7 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
- #define mtk_wed_device_stop(_dev) do {} while (0)
- #define mtk_wed_device_dma_reset(_dev) do {} while (0)
-+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch
deleted file mode 100644
index 84b768bd79..0000000000
--- a/target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 20 Mar 2023 15:37:55 +0100
-Subject: [PATCH] net: ethernet: mediatek: mtk_ppe: prefer newly added l2
- flows over existing ones
-
-When a device is roaming between interfaces and a new flow entry is created,
-we should assume that its output device is more up to date than whatever
-entry existed already.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -662,10 +662,20 @@ void mtk_foe_entry_clear(struct mtk_ppe
- static int
- mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-+ struct mtk_flow_entry *prev;
-+
- entry->type = MTK_FLOW_TYPE_L2;
-
-- return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node,
-- mtk_flow_l2_ht_params);
-+ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &entry->l2_node,
-+ mtk_flow_l2_ht_params);
-+ if (likely(!prev))
-+ return 0;
-+
-+ if (IS_ERR(prev))
-+ return PTR_ERR(prev);
-+
-+ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node,
-+ &entry->l2_node, mtk_flow_l2_ht_params);
- }
-
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
diff --git a/target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch b/target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch
deleted file mode 100644
index a9f82ca3cb..0000000000
--- a/target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch
+++ /dev/null
@@ -1,334 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 10:24:11 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: improve keeping track of
- offloaded flows
-
-Unify tracking of L2 and L3 flows. Use the generic list field in struct
-mtk_foe_entry for tracking L2 subflows. Preparation for improving
-flow accounting support.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------
- drivers/net/ethernet/mediatek/mtk_ppe.h | 15 +--
- 2 files changed, 86 insertions(+), 91 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -482,42 +482,43 @@ int mtk_foe_entry_set_queue(struct mtk_e
- return 0;
- }
-
-+static int
-+mtk_flow_entry_match_len(struct mtk_eth *eth, struct mtk_foe_entry *entry)
-+{
-+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1);
-+
-+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE)
-+ return offsetof(struct mtk_foe_entry, ipv6._rsv);
-+ else
-+ return offsetof(struct mtk_foe_entry, ipv4.ib2);
-+}
-+
- static bool
- mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry,
-- struct mtk_foe_entry *data)
-+ struct mtk_foe_entry *data, int len)
- {
-- int type, len;
--
- if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP)
- return false;
-
-- type = mtk_get_ib1_pkt_type(eth, entry->data.ib1);
-- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE)
-- len = offsetof(struct mtk_foe_entry, ipv6._rsv);
-- else
-- len = offsetof(struct mtk_foe_entry, ipv4.ib2);
--
- return !memcmp(&entry->data.data, &data->data, len - 4);
- }
-
- static void
--__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ bool set_state)
- {
-- struct hlist_head *head;
- struct hlist_node *tmp;
-
- if (entry->type == MTK_FLOW_TYPE_L2) {
- rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node,
- mtk_flow_l2_ht_params);
-
-- head = &entry->l2_flows;
-- hlist_for_each_entry_safe(entry, tmp, head, l2_data.list)
-- __mtk_foe_entry_clear(ppe, entry);
-+ hlist_for_each_entry_safe(entry, tmp, &entry->l2_flows, l2_list)
-+ __mtk_foe_entry_clear(ppe, entry, set_state);
- return;
- }
-
-- hlist_del_init(&entry->list);
-- if (entry->hash != 0xffff) {
-+ if (entry->hash != 0xffff && set_state) {
- struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
-
- hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-@@ -537,7 +538,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW)
- return;
-
-- hlist_del_init(&entry->l2_data.list);
-+ hlist_del_init(&entry->l2_list);
-+ hlist_del_init(&entry->list);
- kfree(entry);
- }
-
-@@ -553,66 +555,55 @@ static int __mtk_foe_entry_idle_time(str
- return now - timestamp;
- }
-
-+static bool
-+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ struct mtk_foe_entry foe = {};
-+ struct mtk_foe_entry *hwe;
-+ u16 hash = entry->hash;
-+ int len;
-+
-+ if (hash == 0xffff)
-+ return false;
-+
-+ hwe = mtk_foe_get_entry(ppe, hash);
-+ len = mtk_flow_entry_match_len(ppe->eth, &entry->data);
-+ memcpy(&foe, hwe, len);
-+
-+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) ||
-+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND)
-+ return false;
-+
-+ entry->data.ib1 = foe.ib1;
-+
-+ return true;
-+}
-+
- static void
- mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth);
- struct mtk_flow_entry *cur;
-- struct mtk_foe_entry *hwe;
- struct hlist_node *tmp;
- int idle;
-
- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) {
-+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) {
- int cur_idle;
-- u32 ib1;
--
-- hwe = mtk_foe_get_entry(ppe, cur->hash);
-- ib1 = READ_ONCE(hwe->ib1);
-
-- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) {
-- cur->hash = 0xffff;
-- __mtk_foe_entry_clear(ppe, cur);
-+ if (!mtk_flow_entry_update(ppe, cur)) {
-+ __mtk_foe_entry_clear(ppe, entry, false);
- continue;
- }
-
-- cur_idle = __mtk_foe_entry_idle_time(ppe, ib1);
-+ cur_idle = __mtk_foe_entry_idle_time(ppe, cur->data.ib1);
- if (cur_idle >= idle)
- continue;
-
- idle = cur_idle;
- entry->data.ib1 &= ~ib1_ts_mask;
-- entry->data.ib1 |= hwe->ib1 & ib1_ts_mask;
-- }
--}
--
--static void
--mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
--{
-- struct mtk_foe_entry foe = {};
-- struct mtk_foe_entry *hwe;
--
-- spin_lock_bh(&ppe_lock);
--
-- if (entry->type == MTK_FLOW_TYPE_L2) {
-- mtk_flow_entry_update_l2(ppe, entry);
-- goto out;
-+ entry->data.ib1 |= cur->data.ib1 & ib1_ts_mask;
- }
--
-- if (entry->hash == 0xffff)
-- goto out;
--
-- hwe = mtk_foe_get_entry(ppe, entry->hash);
-- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size);
-- if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) {
-- entry->hash = 0xffff;
-- goto out;
-- }
--
-- entry->data.ib1 = foe.ib1;
--
--out:
-- spin_unlock_bh(&ppe_lock);
- }
-
- static void
-@@ -655,7 +646,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- spin_lock_bh(&ppe_lock);
-- __mtk_foe_entry_clear(ppe, entry);
-+ __mtk_foe_entry_clear(ppe, entry, true);
-+ hlist_del_init(&entry->list);
- spin_unlock_bh(&ppe_lock);
- }
-
-@@ -702,8 +694,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
- {
- const struct mtk_soc_data *soc = ppe->eth->soc;
- struct mtk_flow_entry *flow_info;
-- struct mtk_foe_entry foe = {}, *hwe;
- struct mtk_foe_mac_info *l2;
-+ struct mtk_foe_entry *hwe;
- u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP;
- int type;
-
-@@ -711,30 +703,30 @@ mtk_foe_entry_commit_subflow(struct mtk_
- if (!flow_info)
- return;
-
-- flow_info->l2_data.base_flow = entry;
- flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW;
- flow_info->hash = hash;
- hlist_add_head(&flow_info->list,
- &ppe->foe_flow[hash / soc->hash_offset]);
-- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
-+ hlist_add_head(&flow_info->l2_list, &entry->l2_flows);
-
- hwe = mtk_foe_get_entry(ppe, hash);
-- memcpy(&foe, hwe, soc->foe_entry_size);
-- foe.ib1 &= ib1_mask;
-- foe.ib1 |= entry->data.ib1 & ~ib1_mask;
-+ memcpy(&flow_info->data, hwe, soc->foe_entry_size);
-+ flow_info->data.ib1 &= ib1_mask;
-+ flow_info->data.ib1 |= entry->data.ib1 & ~ib1_mask;
-
-- l2 = mtk_foe_entry_l2(ppe->eth, &foe);
-+ l2 = mtk_foe_entry_l2(ppe->eth, &flow_info->data);
- memcpy(l2, &entry->data.bridge.l2, sizeof(*l2));
-
-- type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1);
-+ type = mtk_get_ib1_pkt_type(ppe->eth, flow_info->data.ib1);
- if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT)
-- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new));
-+ memcpy(&flow_info->data.ipv4.new, &flow_info->data.ipv4.orig,
-+ sizeof(flow_info->data.ipv4.new));
- else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP)
- l2->etype = ETH_P_IPV6;
-
-- *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2;
-+ *mtk_foe_entry_ib2(ppe->eth, &flow_info->data) = entry->data.bridge.ib2;
-
-- __mtk_foe_entry_commit(ppe, &foe, hash);
-+ __mtk_foe_entry_commit(ppe, &flow_info->data, hash);
- }
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
-@@ -744,9 +736,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash);
- struct mtk_flow_entry *entry;
- struct mtk_foe_bridge key = {};
-+ struct mtk_foe_entry foe = {};
- struct hlist_node *n;
- struct ethhdr *eh;
- bool found = false;
-+ int entry_len;
- u8 *tag;
-
- spin_lock_bh(&ppe_lock);
-@@ -754,20 +748,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND)
- goto out;
-
-- hlist_for_each_entry_safe(entry, n, head, list) {
-- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) {
-- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) ==
-- MTK_FOE_STATE_BIND))
-- continue;
--
-- entry->hash = 0xffff;
-- __mtk_foe_entry_clear(ppe, entry);
-- continue;
-- }
-+ entry_len = mtk_flow_entry_match_len(ppe->eth, hwe);
-+ memcpy(&foe, hwe, entry_len);
-
-- if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) {
-+ hlist_for_each_entry_safe(entry, n, head, list) {
-+ if (found ||
-+ !mtk_flow_entry_match(ppe->eth, entry, &foe, entry_len)) {
- if (entry->hash != 0xffff)
-- entry->hash = 0xffff;
-+ __mtk_foe_entry_clear(ppe, entry, false);
- continue;
- }
-
-@@ -816,9 +804,17 @@ out:
-
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-- mtk_flow_entry_update(ppe, entry);
-+ int idle;
-+
-+ spin_lock_bh(&ppe_lock);
-+ if (entry->type == MTK_FLOW_TYPE_L2)
-+ mtk_flow_entry_update_l2(ppe, entry);
-+ else
-+ mtk_flow_entry_update(ppe, entry);
-+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-+ spin_unlock_bh(&ppe_lock);
-
-- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-+ return idle;
- }
-
- int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -286,7 +286,12 @@ enum {
-
- struct mtk_flow_entry {
- union {
-- struct hlist_node list;
-+ /* regular flows + L2 subflows */
-+ struct {
-+ struct hlist_node list;
-+ struct hlist_node l2_list;
-+ };
-+ /* L2 flows */
- struct {
- struct rhash_head l2_node;
- struct hlist_head l2_flows;
-@@ -296,13 +301,7 @@ struct mtk_flow_entry {
- s8 wed_index;
- u8 ppe_index;
- u16 hash;
-- union {
-- struct mtk_foe_entry data;
-- struct {
-- struct mtk_flow_entry *base_flow;
-- struct hlist_node list;
-- } l2_data;
-- };
-+ struct mtk_foe_entry data;
- struct rhash_head node;
- unsigned long cookie;
- };
diff --git a/target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch b/target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch
deleted file mode 100644
index 2ea6d341b0..0000000000
--- a/target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch
+++ /dev/null
@@ -1,342 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 11:05:22 +0100
-Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for L2
- flows
-
-For L2 flows, the packet/byte counters should report the sum of the
-counters of their subflows, both current and expired.
-In order to make this work, change the way that accounting data is tracked.
-Reset counters when a flow enters bind. Once it expires (or enters unbind),
-store the last counter value in struct mtk_flow_entry.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -79,9 +79,9 @@ static int mtk_ppe_mib_wait_busy(struct
- int ret;
- u32 val;
-
-- ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
-- !(val & MTK_PPE_MIB_SER_CR_ST),
-- 20, MTK_PPE_WAIT_TIMEOUT_US);
-+ ret = readl_poll_timeout_atomic(ppe->base + MTK_PPE_MIB_SER_CR, val,
-+ !(val & MTK_PPE_MIB_SER_CR_ST),
-+ 20, MTK_PPE_WAIT_TIMEOUT_US);
-
- if (ret)
- dev_err(ppe->dev, "MIB table busy");
-@@ -89,17 +89,31 @@ static int mtk_ppe_mib_wait_busy(struct
- return ret;
- }
-
--static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
-+static inline struct mtk_foe_accounting *
-+mtk_ppe_acct_data(struct mtk_ppe *ppe, u16 index)
-+{
-+ if (!ppe->acct_table)
-+ return NULL;
-+
-+ return ppe->acct_table + index * sizeof(struct mtk_foe_accounting);
-+}
-+
-+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index)
- {
- u32 val, cnt_r0, cnt_r1, cnt_r2;
-+ struct mtk_foe_accounting *acct;
- int ret;
-
- val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
- ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
-
-+ acct = mtk_ppe_acct_data(ppe, index);
-+ if (!acct)
-+ return NULL;
-+
- ret = mtk_ppe_mib_wait_busy(ppe);
- if (ret)
-- return ret;
-+ return acct;
-
- cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
- cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-@@ -108,19 +122,19 @@ static int mtk_mib_entry_read(struct mtk
- if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
- /* 64 bit for each counter */
- u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
-- *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
-- *packets = ((u64)cnt_r3 << 32) | cnt_r2;
-+ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0;
-+ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2;
- } else {
- /* 48 bit byte counter, 40 bit packet counter */
- u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
- u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
- u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
- u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-- *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low;
- }
-
-- return 0;
-+ return acct;
- }
-
- static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
-@@ -525,13 +539,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
- dma_wmb();
- mtk_ppe_cache_clear(ppe);
-- if (ppe->accounting) {
-- struct mtk_foe_accounting *acct;
--
-- acct = ppe->acct_table + entry->hash * sizeof(*acct);
-- acct->packets = 0;
-- acct->bytes = 0;
-- }
- }
- entry->hash = 0xffff;
-
-@@ -556,11 +563,14 @@ static int __mtk_foe_entry_idle_time(str
- }
-
- static bool
--mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ u64 *packets, u64 *bytes)
- {
-+ struct mtk_foe_accounting *acct;
- struct mtk_foe_entry foe = {};
- struct mtk_foe_entry *hwe;
- u16 hash = entry->hash;
-+ bool ret = false;
- int len;
-
- if (hash == 0xffff)
-@@ -571,18 +581,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp
- memcpy(&foe, hwe, len);
-
- if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) ||
-- FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND)
-- return false;
-+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) {
-+ acct = mtk_ppe_acct_data(ppe, hash);
-+ if (acct) {
-+ entry->prev_packets += acct->packets;
-+ entry->prev_bytes += acct->bytes;
-+ }
-+
-+ goto out;
-+ }
-
- entry->data.ib1 = foe.ib1;
-+ acct = mtk_ppe_mib_entry_read(ppe, hash);
-+ ret = true;
-+
-+out:
-+ if (acct) {
-+ *packets += acct->packets;
-+ *bytes += acct->bytes;
-+ }
-
-- return true;
-+ return ret;
- }
-
- static void
- mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth);
-+ u64 *packets = &entry->packets;
-+ u64 *bytes = &entry->bytes;
- struct mtk_flow_entry *cur;
- struct hlist_node *tmp;
- int idle;
-@@ -591,7 +618,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe
- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) {
- int cur_idle;
-
-- if (!mtk_flow_entry_update(ppe, cur)) {
-+ if (!mtk_flow_entry_update(ppe, cur, packets, bytes)) {
-+ entry->prev_packets += cur->prev_packets;
-+ entry->prev_bytes += cur->prev_bytes;
- __mtk_foe_entry_clear(ppe, entry, false);
- continue;
- }
-@@ -606,10 +635,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe
- }
- }
-
-+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ int *idle)
-+{
-+ entry->packets = entry->prev_packets;
-+ entry->bytes = entry->prev_bytes;
-+
-+ spin_lock_bh(&ppe_lock);
-+
-+ if (entry->type == MTK_FLOW_TYPE_L2)
-+ mtk_flow_entry_update_l2(ppe, entry);
-+ else
-+ mtk_flow_entry_update(ppe, entry, &entry->packets, &entry->bytes);
-+
-+ *idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-+
-+ spin_unlock_bh(&ppe_lock);
-+}
-+
- static void
- __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
- u16 hash)
- {
-+ struct mtk_foe_accounting *acct;
- struct mtk_eth *eth = ppe->eth;
- u16 timestamp = mtk_eth_timestamp(eth);
- struct mtk_foe_entry *hwe;
-@@ -640,6 +688,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-
- dma_wmb();
-
-+ acct = mtk_ppe_mib_entry_read(ppe, hash);
-+ if (acct) {
-+ acct->packets = 0;
-+ acct->bytes = 0;
-+ }
-+
- mtk_ppe_cache_clear(ppe);
- }
-
-@@ -802,21 +856,6 @@ out:
- spin_unlock_bh(&ppe_lock);
- }
-
--int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
--{
-- int idle;
--
-- spin_lock_bh(&ppe_lock);
-- if (entry->type == MTK_FLOW_TYPE_L2)
-- mtk_flow_entry_update_l2(ppe, entry);
-- else
-- mtk_flow_entry_update(ppe, entry);
-- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-- spin_unlock_bh(&ppe_lock);
--
-- return idle;
--}
--
- int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
- {
- if (!ppe)
-@@ -844,32 +883,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
- return mtk_ppe_wait_busy(ppe);
- }
-
--struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-- struct mtk_foe_accounting *diff)
--{
-- struct mtk_foe_accounting *acct;
-- int size = sizeof(struct mtk_foe_accounting);
-- u64 bytes, packets;
--
-- if (!ppe->accounting)
-- return NULL;
--
-- if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
-- return NULL;
--
-- acct = ppe->acct_table + index * size;
--
-- acct->bytes += bytes;
-- acct->packets += packets;
--
-- if (diff) {
-- diff->bytes = bytes;
-- diff->packets = packets;
-- }
--
-- return acct;
--}
--
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
- {
- bool accounting = eth->soc->has_accounting;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -304,6 +304,8 @@ struct mtk_flow_entry {
- struct mtk_foe_entry data;
- struct rhash_head node;
- unsigned long cookie;
-+ u64 prev_packets, prev_bytes;
-+ u64 packets, bytes;
- };
-
- struct mtk_mib_entry {
-@@ -347,6 +349,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth)
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
- int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
-+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index);
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
-
-@@ -395,9 +398,8 @@ int mtk_foe_entry_set_queue(struct mtk_e
- unsigned int queue);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
--int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
--struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-- struct mtk_foe_accounting *diff);
-+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ int *idle);
-
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -96,7 +96,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- if (bind && state != MTK_FOE_STATE_BIND)
- continue;
-
-- acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-+ acct = mtk_ppe_mib_entry_read(ppe, i);
-
- type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
- seq_printf(m, "%05x %s %7s", i,
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -501,24 +501,21 @@ static int
- mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
- {
- struct mtk_flow_entry *entry;
-- struct mtk_foe_accounting diff;
-- u32 idle;
-+ u64 packets, bytes;
-+ int idle;
-
- entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
- mtk_flow_ht_params);
- if (!entry)
- return -ENOENT;
-
-- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
-+ packets = entry->packets;
-+ bytes = entry->bytes;
-+ mtk_foe_entry_get_stats(eth->ppe[entry->ppe_index], entry, &idle);
-+ f->stats.pkts += entry->packets - packets;
-+ f->stats.bytes += entry->bytes - bytes;
- f->stats.lastused = jiffies - idle * HZ;
-
-- if (entry->hash != 0xFFFF &&
-- mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
-- &diff)) {
-- f->stats.pkts += diff.packets;
-- f->stats.bytes += diff.bytes;
-- }
--
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch b/target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch
deleted file mode 100644
index a224b62624..0000000000
--- a/target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sun, 27 Aug 2023 19:31:41 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: add some more info in wed_txinfo_show
- handler
-
-Add some new info in Wireless Ethernet Dispatcher wed_txinfo_show
-debugfs handler useful during debugging.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/3390292655d568180b73d2a25576f61aa63310e5.1693157377.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -127,8 +127,17 @@ wed_txinfo_show(struct seq_file *s, void
- DUMP_WDMA_RING(WDMA_RING_RX(0)),
- DUMP_WDMA_RING(WDMA_RING_RX(1)),
-
-- DUMP_STR("TX FREE"),
-+ DUMP_STR("WED TX FREE"),
- DUMP_WED(WED_RX_MIB(0)),
-+ DUMP_WED_RING(WED_RING_RX(0)),
-+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)),
-+ DUMP_WED(WED_RX_MIB(1)),
-+ DUMP_WED_RING(WED_RING_RX(1)),
-+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)),
-+
-+ DUMP_STR("WED WPDMA TX FREE"),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX(0)),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX(1)),
- };
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -266,6 +266,8 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4)
- #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_MIB(_n) (0x5e0 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_COHERENT_MIB(_n) (0x5f0 + (_n) * 4)
-
- #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10)
- #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10)
diff --git a/target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch b/target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch
deleted file mode 100644
index df6edfdf94..0000000000
--- a/target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sun, 27 Aug 2023 19:33:47 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: minor change in wed_{tx,rx}info_show
-
-No functional changes, just cosmetic ones.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/71e046c72a978745f0435af265dda610aa9bfbcf.1693157578.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -84,7 +84,6 @@ dump_wed_regs(struct seq_file *s, struct
- }
- }
-
--
- static int
- wed_txinfo_show(struct seq_file *s, void *data)
- {
-@@ -142,10 +141,8 @@ wed_txinfo_show(struct seq_file *s, void
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
-- if (!dev)
-- return 0;
--
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-
- return 0;
- }
-@@ -217,10 +214,8 @@ wed_rxinfo_show(struct seq_file *s, void
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
-- if (!dev)
-- return 0;
--
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-
- return 0;
- }
diff --git a/target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch b/target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch
deleted file mode 100644
index 0bf9dea24f..0000000000
--- a/target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Sep 2023 10:22:56 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on mtk_pse_port definitions
- in mtk_flow_set_output_device
-
-Similar to ethernet ports, rely on mtk_pse_port definitions for
-pse wdma ports as well.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/b86bdb717e963e3246c1dec5f736c810703cf056.1694506814.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -196,10 +196,10 @@ mtk_flow_set_output_device(struct mtk_et
- if (mtk_is_netsys_v2_or_greater(eth)) {
- switch (info.wdma_idx) {
- case 0:
-- pse_port = 8;
-+ pse_port = PSE_WDMA0_PORT;
- break;
- case 1:
-- pse_port = 9;
-+ pse_port = PSE_WDMA1_PORT;
- break;
- default:
- return -EINVAL;
diff --git a/target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch b/target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
deleted file mode 100644
index c99e1334d4..0000000000
--- a/target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Sep 2023 10:28:00 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: check update_wo_rx_stats in
- mtk_wed_update_rx_stats()
-
-Check if update_wo_rx_stats function pointer is properly set in
-mtk_wed_update_rx_stats routine before accessing it.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/b0d233386e059bccb59f18f69afb79a7806e5ded.1694507226.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -68,6 +68,9 @@ mtk_wed_update_rx_stats(struct mtk_wed_d
- struct mtk_wed_wo_rx_stats *stats;
- int i;
-
-+ if (!wed->wlan.update_wo_rx_stats)
-+ return;
-+
- if (count * sizeof(*stats) > skb->len - sizeof(u32))
- return;
-
diff --git a/target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch b/target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch
deleted file mode 100644
index cd7fb92e20..0000000000
--- a/target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 13 Sep 2023 20:42:47 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: do not assume offload callbacks are
- always set
-
-Check if wlan.offload_enable and wlan.offload_disable callbacks are set
-in mtk_wed_flow_add/mtk_wed_flow_remove since mt7996 will not rely
-on them.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1712,19 +1712,20 @@ mtk_wed_irq_set_mask(struct mtk_wed_devi
- int mtk_wed_flow_add(int index)
- {
- struct mtk_wed_hw *hw = hw_list[index];
-- int ret;
-+ int ret = 0;
-
-- if (!hw || !hw->wed_dev)
-- return -ENODEV;
-+ mutex_lock(&hw_lock);
-
-- if (hw->num_flows) {
-- hw->num_flows++;
-- return 0;
-+ if (!hw || !hw->wed_dev) {
-+ ret = -ENODEV;
-+ goto out;
- }
-
-- mutex_lock(&hw_lock);
-- if (!hw->wed_dev) {
-- ret = -ENODEV;
-+ if (!hw->wed_dev->wlan.offload_enable)
-+ goto out;
-+
-+ if (hw->num_flows) {
-+ hw->num_flows++;
- goto out;
- }
-
-@@ -1743,14 +1744,15 @@ void mtk_wed_flow_remove(int index)
- {
- struct mtk_wed_hw *hw = hw_list[index];
-
-- if (!hw)
-- return;
-+ mutex_lock(&hw_lock);
-
-- if (--hw->num_flows)
-- return;
-+ if (!hw || !hw->wed_dev)
-+ goto out;
-
-- mutex_lock(&hw_lock);
-- if (!hw->wed_dev)
-+ if (!hw->wed_dev->wlan.offload_disable)
-+ goto out;
-+
-+ if (--hw->num_flows)
- goto out;
-
- hw->wed_dev->wlan.offload_disable(hw->wed_dev);
diff --git a/target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch b/target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
deleted file mode 100644
index 2948188650..0000000000
--- a/target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
+++ /dev/null
@@ -1,232 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:05 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce versioning utility routines
-
-Similar to mtk_eth_soc, introduce the following wed versioning
-utility routines:
-- mtk_wed_is_v1
-- mtk_wed_is_v2
-
-This is a preliminary patch to introduce WED support for MT7988 SoC
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -277,7 +277,7 @@ mtk_wed_assign(struct mtk_wed_device *de
- if (!hw->wed_dev)
- goto out;
-
-- if (hw->version == 1)
-+ if (mtk_wed_is_v1(hw))
- return NULL;
-
- /* MT7986 WED devices do not have any pcie slot restrictions */
-@@ -358,7 +358,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- desc->buf0 = cpu_to_le32(buf_phys);
- desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
- MTK_WED_BUF_SIZE - txd_size) |
-@@ -497,7 +497,7 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- {
- u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
- else
- mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-@@ -576,7 +576,7 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
- wdma_clr(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return;
-
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
-@@ -624,7 +624,7 @@ mtk_wed_deinit(struct mtk_wed_device *de
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return;
-
- wed_clr(dev, MTK_WED_CTRL,
-@@ -730,7 +730,7 @@ mtk_wed_bus_init(struct mtk_wed_device *
- static void
- mtk_wed_set_wpdma(struct mtk_wed_device *dev)
- {
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
- } else {
- mtk_wed_bus_init(dev);
-@@ -761,7 +761,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
- wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- u32 offset = dev->hw->index ? 0x04000400 : 0;
-
- wdma_set(dev, MTK_WDMA_GLO_CFG,
-@@ -934,7 +934,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_TX_BM_TKID,
- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
- dev->wlan.token_start) |
-@@ -967,7 +967,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-@@ -1217,7 +1217,7 @@ mtk_wed_reset_dma(struct mtk_wed_device
- }
-
- dev->init_done = false;
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return;
-
- if (!busy) {
-@@ -1343,7 +1343,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
- MTK_WED_PCIE_INT_TRIGGER_STATUS);
-
-@@ -1416,7 +1416,7 @@ mtk_wed_dma_enable(struct mtk_wed_device
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
-@@ -1465,7 +1465,7 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- mtk_wed_set_ext_int(dev, true);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN |
- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID,
- dev->hw->index);
-@@ -1550,7 +1550,7 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (hw->version == 1) {
-+ if (mtk_wed_is_v1(hw)) {
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
- } else {
-@@ -1618,7 +1618,7 @@ static int
- mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
- {
- struct mtk_wed_ring *ring = &dev->txfree_ring;
-- int i, index = dev->hw->version == 1;
-+ int i, index = mtk_wed_is_v1(dev->hw);
-
- /*
- * For txfree event handling, the same DMA ring is shared between WED
-@@ -1676,7 +1676,7 @@ mtk_wed_irq_get(struct mtk_wed_device *d
- {
- u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
- else
- ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-@@ -1843,7 +1843,7 @@ mtk_wed_setup_tc(struct mtk_wed_device *
- {
- struct mtk_wed_hw *hw = wed->hw;
-
-- if (hw->version < 2)
-+ if (mtk_wed_is_v1(hw))
- return -EOPNOTSUPP;
-
- switch (type) {
-@@ -1917,9 +1917,9 @@ void mtk_wed_add_hw(struct device_node *
- hw->wdma = wdma;
- hw->index = index;
- hw->irq = irq;
-- hw->version = mtk_is_netsys_v1(eth) ? 1 : 2;
-+ hw->version = eth->soc->version;
-
-- if (hw->version == 1) {
-+ if (mtk_wed_is_v1(hw)) {
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
- "mediatek,pcie-mirror");
- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -40,6 +40,16 @@ struct mtk_wdma_info {
- };
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static inline bool mtk_wed_is_v1(struct mtk_wed_hw *hw)
-+{
-+ return hw->version == 1;
-+}
-+
-+static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw)
-+{
-+ return hw->version == 2;
-+}
-+
- static inline void
- wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
- {
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -263,7 +263,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w
- debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
- debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
- debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-- if (hw->version != 1)
-+ if (!mtk_wed_is_v1(hw))
- debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
- &wed_rxinfo_fops);
- }
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- {
- struct mtk_wed_wo *wo = dev->hw->wed_wo;
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return 0;
-
- if (WARN_ON(!wo))
diff --git a/target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch b/target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch
deleted file mode 100644
index bc34aa33a9..0000000000
--- a/target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:06 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: do not configure rx offload if not
- supported
-
-Check if rx offload is supported running mtk_wed_get_rx_capa routine
-before configuring it. This is a preliminary patch to introduce Wireless
-Ethernet Dispatcher (WED) support for MT7988 SoC.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-
-- if (mtk_wed_is_v1(dev->hw))
-+ if (!mtk_wed_get_rx_capa(dev))
- return;
-
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
-@@ -732,16 +732,21 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- {
- if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
-- } else {
-- mtk_wed_bus_init(dev);
--
-- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
-+ return;
- }
-+
-+ mtk_wed_bus_init(dev);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-+
-+ if (!mtk_wed_get_rx_capa(dev))
-+ return;
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
- }
-
- static void
-@@ -973,15 +978,17 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
- } else {
- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
-- /* rx hw init */
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-- MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-- MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
--
-- mtk_wed_rx_buffer_hw_init(dev);
-- mtk_wed_rro_hw_init(dev);
-- mtk_wed_route_qm_hw_init(dev);
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ /* rx hw init */
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+
-+ mtk_wed_rx_buffer_hw_init(dev);
-+ mtk_wed_rro_hw_init(dev);
-+ mtk_wed_route_qm_hw_init(dev);
-+ }
- }
-
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
-@@ -1353,8 +1360,6 @@ mtk_wed_configure_irq(struct mtk_wed_dev
-
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
-- wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
-- GENMASK(1, 0));
- /* initail tx interrupt trigger */
- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
- MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-@@ -1373,15 +1378,20 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
- dev->wlan.txfree_tbit));
-
-- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-- MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-- MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-- MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-- MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-- dev->wlan.rx_tbit[0]) |
-- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-- dev->wlan.rx_tbit[1]));
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-+ dev->wlan.rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-+ dev->wlan.rx_tbit[1]));
-+
-+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
-+ GENMASK(1, 0));
-+ }
-
- wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
- wed_set(dev, MTK_WED_WDMA_INT_CTRL,
-@@ -1400,6 +1410,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- static void
- mtk_wed_dma_enable(struct mtk_wed_device *dev)
- {
-+ int i;
-+
- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-
- wed_set(dev, MTK_WED_GLO_CFG,
-@@ -1419,33 +1431,33 @@ mtk_wed_dma_enable(struct mtk_wed_device
- if (mtk_wed_is_v1(dev->hw)) {
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-- } else {
-- int i;
-+ return;
-+ }
-
-- wed_set(dev, MTK_WED_WPDMA_CTRL,
-- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-+ wed_set(dev, MTK_WED_WPDMA_CTRL,
-+ MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
-+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-
-- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+ if (!mtk_wed_get_rx_capa(dev))
-+ return;
-
-- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
--
-- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
-- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-
-- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-- MTK_WED_WPDMA_RX_D_RX_DRV_EN |
-- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-- 0x2));
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-+ 0x2));
-
-- for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-- mtk_wed_check_wfdma_rx_fill(dev, i);
-- }
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-+ mtk_wed_check_wfdma_rx_fill(dev, i);
- }
-
- static void
-@@ -1472,7 +1484,7 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- val |= BIT(0) | (BIT(1) * !!dev->hw->index);
- regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
-- } else {
-+ } else if (mtk_wed_get_rx_capa(dev)) {
- /* driver set mid ready and only once */
- wed_w32(dev, MTK_WED_EXT_INT_MASK1,
- MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-@@ -1484,7 +1496,6 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- if (mtk_wed_rro_cfg(dev))
- return;
--
- }
-
- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-@@ -1550,13 +1561,14 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (mtk_wed_is_v1(hw)) {
-+ if (mtk_wed_is_v1(hw))
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
-- } else {
-+ else
- dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
-+
-+ if (mtk_wed_get_rx_capa(dev))
- ret = mtk_wed_wo_init(hw);
-- }
- out:
- if (ret) {
- dev_err(dev->hw->dev, "failed to attach wed device\n");
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- {
- struct mtk_wed_wo *wo = dev->hw->wed_wo;
-
-- if (mtk_wed_is_v1(dev->hw))
-+ if (!mtk_wed_get_rx_capa(dev))
- return 0;
-
- if (WARN_ON(!wo))
diff --git a/target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch b/target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch
deleted file mode 100644
index d83434fb2c..0000000000
--- a/target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:07 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: rename mtk_rxbm_desc in
- mtk_wed_bm_desc
-
-Rename mtk_rxbm_desc structure in mtk_wed_bm_desc since it will be used
-even on tx side by MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -421,7 +421,7 @@ free_pagelist:
- static int
- mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
- {
-- struct mtk_rxbm_desc *desc;
-+ struct mtk_wed_bm_desc *desc;
- dma_addr_t desc_phys;
-
- dev->rx_buf_ring.size = dev->wlan.rx_nbuf;
-@@ -441,7 +441,7 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d
- static void
- mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
- {
-- struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
-+ struct mtk_wed_bm_desc *desc = dev->rx_buf_ring.desc;
-
- if (!desc)
- return;
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -45,7 +45,7 @@ enum mtk_wed_wo_cmd {
- MTK_WED_WO_CMD_WED_END
- };
-
--struct mtk_rxbm_desc {
-+struct mtk_wed_bm_desc {
- __le32 buf0;
- __le32 token;
- } __packed __aligned(4);
-@@ -105,7 +105,7 @@ struct mtk_wed_device {
- struct {
- int size;
- struct page_frag_cache rx_page;
-- struct mtk_rxbm_desc *desc;
-+ struct mtk_wed_bm_desc *desc;
- dma_addr_t desc_phys;
- } rx_buf_ring;
-
diff --git a/target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch b/target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch
deleted file mode 100644
index 8000a8759e..0000000000
--- a/target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:08 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce mtk_wed_buf structure
-
-Introduce mtk_wed_buf structure to store both virtual and physical
-addresses allocated in mtk_wed_tx_buffer_alloc() routine. This is a
-preliminary patch to add WED support for MT7988 SoC since it relies on a
-different dma descriptor layout not storing page dma addresses.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -299,9 +299,9 @@ out:
- static int
- mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
-+ struct mtk_wed_buf *page_list;
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-- void **page_list;
- int token = dev->wlan.token_start;
- int ring_size;
- int n_pages;
-@@ -342,7 +342,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- return -ENOMEM;
- }
-
-- page_list[page_idx++] = page;
-+ page_list[page_idx].p = page;
-+ page_list[page_idx++].phy_addr = page_phys;
- dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
-
-@@ -386,8 +387,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- static void
- mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
- {
-+ struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages;
- struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
-- void **page_list = dev->tx_buf_ring.pages;
- int page_idx;
- int i;
-
-@@ -399,13 +400,12 @@ mtk_wed_free_tx_buffer(struct mtk_wed_de
-
- for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size;
- i += MTK_WED_BUF_PER_PAGE) {
-- void *page = page_list[page_idx++];
-- dma_addr_t buf_addr;
-+ dma_addr_t buf_addr = page_list[page_idx].phy_addr;
-+ void *page = page_list[page_idx++].p;
-
- if (!page)
- break;
-
-- buf_addr = le32_to_cpu(desc[i].buf0);
- dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- __free_page(page);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -76,6 +76,11 @@ struct mtk_wed_wo_rx_stats {
- __le32 rx_drop_cnt;
- };
-
-+struct mtk_wed_buf {
-+ void *p;
-+ dma_addr_t phy_addr;
-+};
-+
- struct mtk_wed_device {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- const struct mtk_wed_ops *ops;
-@@ -97,7 +102,7 @@ struct mtk_wed_device {
-
- struct {
- int size;
-- void **pages;
-+ struct mtk_wed_buf *pages;
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
- } tx_buf_ring;
diff --git a/target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch b/target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch
deleted file mode 100644
index 98d782b1d0..0000000000
--- a/target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:09 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: move mem_region array out of
- mtk_wed_mcu_load_firmware
-
-Remove mtk_wed_wo_memory_region boot structure in mtk_wed_wo.
-This is a preliminary patch to introduce WED support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -16,14 +16,30 @@
- #include "mtk_wed_wo.h"
- #include "mtk_wed.h"
-
-+static struct mtk_wed_wo_memory_region mem_region[] = {
-+ [MTK_WED_WO_REGION_EMI] = {
-+ .name = "wo-emi",
-+ },
-+ [MTK_WED_WO_REGION_ILM] = {
-+ .name = "wo-ilm",
-+ },
-+ [MTK_WED_WO_REGION_DATA] = {
-+ .name = "wo-data",
-+ .shared = true,
-+ },
-+ [MTK_WED_WO_REGION_BOOT] = {
-+ .name = "wo-boot",
-+ },
-+};
-+
- static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
- {
-- return readl(wo->boot.addr + reg);
-+ return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
- }
-
- static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
- {
-- writel(val, wo->boot.addr + reg);
-+ writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
- }
-
- static struct sk_buff *
-@@ -294,18 +310,6 @@ next:
- static int
- mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
- {
-- static struct mtk_wed_wo_memory_region mem_region[] = {
-- [MTK_WED_WO_REGION_EMI] = {
-- .name = "wo-emi",
-- },
-- [MTK_WED_WO_REGION_ILM] = {
-- .name = "wo-ilm",
-- },
-- [MTK_WED_WO_REGION_DATA] = {
-- .name = "wo-data",
-- .shared = true,
-- },
-- };
- const struct mtk_wed_fw_trailer *trailer;
- const struct firmware *fw;
- const char *fw_name;
-@@ -319,11 +323,6 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- return ret;
- }
-
-- wo->boot.name = "wo-boot";
-- ret = mtk_wed_get_memory_region(wo, &wo->boot);
-- if (ret)
-- return ret;
--
- /* set dummy cr */
- wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL,
- wo->hw->index + 1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -228,7 +228,6 @@ struct mtk_wed_wo_queue {
-
- struct mtk_wed_wo {
- struct mtk_wed_hw *hw;
-- struct mtk_wed_wo_memory_region boot;
-
- struct mtk_wed_wo_queue q_tx;
- struct mtk_wed_wo_queue q_rx;
diff --git a/target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch b/target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch
deleted file mode 100644
index 48b0d02049..0000000000
--- a/target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:10 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: make memory region optional
-
-Make mtk_wed_wo_memory_region optionals.
-This is a preliminary patch to introduce Wireless Ethernet Dispatcher
-support for MT7988 SoC since MT7988 WED fw image will have a different
-layout.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -234,19 +234,13 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- }
-
- static int
--mtk_wed_get_memory_region(struct mtk_wed_wo *wo,
-+mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index,
- struct mtk_wed_wo_memory_region *region)
- {
- struct reserved_mem *rmem;
- struct device_node *np;
-- int index;
-
-- index = of_property_match_string(wo->hw->node, "memory-region-names",
-- region->name);
-- if (index < 0)
-- return index;
--
-- np = of_parse_phandle(wo->hw->node, "memory-region", index);
-+ np = of_parse_phandle(hw->node, "memory-region", index);
- if (!np)
- return -ENODEV;
-
-@@ -258,7 +252,7 @@ mtk_wed_get_memory_region(struct mtk_wed
-
- region->phy_addr = rmem->base;
- region->size = rmem->size;
-- region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size);
-+ region->addr = devm_ioremap(hw->dev, region->phy_addr, region->size);
-
- return !region->addr ? -EINVAL : 0;
- }
-@@ -271,6 +265,9 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_
- const struct mtk_wed_fw_trailer *trailer;
- const struct mtk_wed_fw_region *fw_region;
-
-+ if (!region->phy_addr || !region->size)
-+ return 0;
-+
- trailer_ptr = fw->data + fw->size - sizeof(*trailer);
- trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr;
- region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region);
-@@ -318,7 +315,13 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
-
- /* load firmware region metadata */
- for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
-- ret = mtk_wed_get_memory_region(wo, &mem_region[i]);
-+ int index = of_property_match_string(wo->hw->node,
-+ "memory-region-names",
-+ mem_region[i].name);
-+ if (index < 0)
-+ continue;
-+
-+ ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]);
- if (ret)
- return ret;
- }
diff --git a/target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch b/target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch
deleted file mode 100644
index 878e8fe996..0000000000
--- a/target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:11 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: fix EXT_INT_STATUS_RX_FBUF
- definitions for MT7986 SoC
-
-Fix MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH and
-MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH definitions for MT7986 (MT7986 is
-the only SoC to use them).
-
-Fixes: de84a090d99a ("net: ethernet: mtk_eth_wed: add wed support for mt7986 chipset")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -64,8 +64,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4)
- #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8)
- #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9)
--#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12)
--#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13)
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(10) /* wed v2 */
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(11) /* wed v2 */
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18)
diff --git a/target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch b/target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
deleted file mode 100644
index c43114fb5b..0000000000
--- a/target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:12 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_soc_data structure
-
-Introduce mtk_wed_soc_data utility structure to contain per-SoC
-definitions.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -48,6 +48,26 @@ struct mtk_wed_flow_block_priv {
- struct net_device *dev;
- };
-
-+static const struct mtk_wed_soc_data mt7622_data = {
-+ .regmap = {
-+ .tx_bm_tkid = 0x088,
-+ .wpdma_rx_ring0 = 0x770,
-+ .reset_idx_tx_mask = GENMASK(3, 0),
-+ .reset_idx_rx_mask = GENMASK(17, 16),
-+ },
-+ .wdma_desc_size = sizeof(struct mtk_wdma_desc),
-+};
-+
-+static const struct mtk_wed_soc_data mt7986_data = {
-+ .regmap = {
-+ .tx_bm_tkid = 0x0c8,
-+ .wpdma_rx_ring0 = 0x770,
-+ .reset_idx_tx_mask = GENMASK(1, 0),
-+ .reset_idx_rx_mask = GENMASK(7, 6),
-+ },
-+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
-+};
-+
- static void
- wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
- {
-@@ -746,7 +766,7 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- return;
-
- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
-+ wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx);
- }
-
- static void
-@@ -940,22 +960,10 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
- if (mtk_wed_is_v1(dev->hw)) {
-- wed_w32(dev, MTK_WED_TX_BM_TKID,
-- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-- dev->wlan.token_start) |
-- FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-- dev->wlan.token_start +
-- dev->wlan.nbuf - 1));
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
- MTK_WED_TX_BM_DYN_THR_HI);
- } else {
-- wed_w32(dev, MTK_WED_TX_BM_TKID_V2,
-- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-- dev->wlan.token_start) |
-- FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-- dev->wlan.token_start +
-- dev->wlan.nbuf - 1));
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) |
- MTK_WED_TX_BM_DYN_THR_HI_V2);
-@@ -970,6 +978,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- MTK_WED_TX_TKID_DYN_THR_HI);
- }
-
-+ wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid,
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, dev->wlan.token_start) |
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-+ dev->wlan.token_start + dev->wlan.nbuf - 1));
-+
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
- if (mtk_wed_is_v1(dev->hw)) {
-@@ -1104,13 +1117,8 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- if (ret) {
- mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
- } else {
-- struct mtk_eth *eth = dev->hw->eth;
--
-- if (mtk_is_netsys_v2_or_greater(eth))
-- wed_set(dev, MTK_WED_RESET_IDX,
-- MTK_WED_RESET_IDX_RX_V2);
-- else
-- wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
-+ wed_set(dev, MTK_WED_RESET_IDX,
-+ dev->hw->soc->regmap.reset_idx_rx_mask);
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-@@ -1163,7 +1171,8 @@ mtk_wed_reset_dma(struct mtk_wed_device
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
- } else {
-- wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
-+ wed_w32(dev, MTK_WED_RESET_IDX,
-+ dev->hw->soc->regmap.reset_idx_tx_mask);
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-@@ -1255,7 +1264,6 @@ static int
- mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
- bool reset)
- {
-- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-
- if (idx >= ARRAY_SIZE(dev->rx_wdma))
-@@ -1263,7 +1271,7 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
-
- wdma = &dev->rx_wdma[idx];
- if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- desc_size, true))
-+ dev->hw->soc->wdma_desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1284,7 +1292,6 @@ static int
- mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
- bool reset)
- {
-- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-
- if (idx >= ARRAY_SIZE(dev->tx_wdma))
-@@ -1292,7 +1299,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
-
- wdma = &dev->tx_wdma[idx];
- if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- desc_size, true))
-+ dev->hw->soc->wdma_desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1931,7 +1938,12 @@ void mtk_wed_add_hw(struct device_node *
- hw->irq = irq;
- hw->version = eth->soc->version;
-
-- if (mtk_wed_is_v1(hw)) {
-+ switch (hw->version) {
-+ case 2:
-+ hw->soc = &mt7986_data;
-+ break;
-+ default:
-+ case 1:
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
- "mediatek,pcie-mirror");
- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
-@@ -1945,6 +1957,8 @@ void mtk_wed_add_hw(struct device_node *
- regmap_write(hw->mirror, 0, 0);
- regmap_write(hw->mirror, 4, 0);
- }
-+ hw->soc = &mt7622_data;
-+ break;
- }
-
- mtk_wed_hw_add_debugfs(hw);
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -12,7 +12,18 @@
- struct mtk_eth;
- struct mtk_wed_wo;
-
-+struct mtk_wed_soc_data {
-+ struct {
-+ u32 tx_bm_tkid;
-+ u32 wpdma_rx_ring0;
-+ u32 reset_idx_tx_mask;
-+ u32 reset_idx_rx_mask;
-+ } regmap;
-+ u32 wdma_desc_size;
-+};
-+
- struct mtk_wed_hw {
-+ const struct mtk_wed_soc_data *soc;
- struct device_node *node;
- struct mtk_eth *eth;
- struct regmap *regs;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -100,8 +100,6 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_TX_BM_BASE 0x084
-
--#define MTK_WED_TX_BM_TKID 0x088
--#define MTK_WED_TX_BM_TKID_V2 0x0c8
- #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
- #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-
-@@ -160,9 +158,6 @@ struct mtk_wdma_desc {
- #define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31)
-
- #define MTK_WED_RESET_IDX 0x20c
--#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
--#define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
--#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6)
- #define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
-
- #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
-@@ -286,7 +281,6 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-
- #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
--#define MTK_WED_WPDMA_RX_RING 0x770
-
- #define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
- #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
diff --git a/target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch b/target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
deleted file mode 100644
index f53b822224..0000000000
--- a/target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
+++ /dev/null
@@ -1,1280 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:13 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce WED support for MT7988
-
-Similar to MT7986 and MT7622, enable Wireless Ethernet Ditpatcher for
-MT7988 in order to offload traffic forwarded from LAN/WLAN to WLAN/LAN
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -195,6 +195,7 @@ static const struct mtk_reg_map mt7988_r
- .wdma_base = {
- [0] = 0x4800,
- [1] = 0x4c00,
-+ [2] = 0x5000,
- },
- .pse_iq_sta = 0x0180,
- .pse_oq_sta = 0x01a0,
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1129,7 +1129,7 @@ struct mtk_reg_map {
- u32 gdm1_cnt;
- u32 gdma_to_ppe0;
- u32 ppe_base;
-- u32 wdma_base[2];
-+ u32 wdma_base[3];
- u32 pse_iq_sta;
- u32 pse_oq_sta;
- };
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -201,6 +201,9 @@ mtk_flow_set_output_device(struct mtk_et
- case 1:
- pse_port = PSE_WDMA1_PORT;
- break;
-+ case 2:
-+ pse_port = PSE_WDMA2_PORT;
-+ break;
- default:
- return -EINVAL;
- }
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -16,17 +16,19 @@
- #include <net/flow_offload.h>
- #include <net/pkt_cls.h>
- #include "mtk_eth_soc.h"
--#include "mtk_wed_regs.h"
- #include "mtk_wed.h"
- #include "mtk_ppe.h"
- #include "mtk_wed_wo.h"
-
- #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
-
--#define MTK_WED_PKT_SIZE 1900
-+#define MTK_WED_PKT_SIZE 1920
- #define MTK_WED_BUF_SIZE 2048
-+#define MTK_WED_PAGE_BUF_SIZE 128
- #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
-+#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
- #define MTK_WED_RX_RING_SIZE 1536
-+#define MTK_WED_RX_PG_BM_CNT 8192
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 1024
-@@ -40,7 +42,10 @@
- #define MTK_WED_RRO_QUE_CNT 8192
- #define MTK_WED_MIOD_ENTRY_CNT 128
-
--static struct mtk_wed_hw *hw_list[2];
-+#define MTK_WED_TX_BM_DMA_SIZE 65536
-+#define MTK_WED_TX_BM_PKT_CNT 32768
-+
-+static struct mtk_wed_hw *hw_list[3];
- static DEFINE_MUTEX(hw_lock);
-
- struct mtk_wed_flow_block_priv {
-@@ -55,6 +60,7 @@ static const struct mtk_wed_soc_data mt7
- .reset_idx_tx_mask = GENMASK(3, 0),
- .reset_idx_rx_mask = GENMASK(17, 16),
- },
-+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc),
- .wdma_desc_size = sizeof(struct mtk_wdma_desc),
- };
-
-@@ -65,6 +71,18 @@ static const struct mtk_wed_soc_data mt7
- .reset_idx_tx_mask = GENMASK(1, 0),
- .reset_idx_rx_mask = GENMASK(7, 6),
- },
-+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc),
-+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
-+};
-+
-+static const struct mtk_wed_soc_data mt7988_data = {
-+ .regmap = {
-+ .tx_bm_tkid = 0x0c8,
-+ .wpdma_rx_ring0 = 0x7d0,
-+ .reset_idx_tx_mask = GENMASK(1, 0),
-+ .reset_idx_rx_mask = GENMASK(7, 6),
-+ },
-+ .tx_ring_desc_size = sizeof(struct mtk_wed_bm_desc),
- .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
- };
-
-@@ -319,33 +337,38 @@ out:
- static int
- mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
-+ u32 desc_size = dev->hw->soc->tx_ring_desc_size;
-+ int i, page_idx = 0, n_pages, ring_size;
-+ int token = dev->wlan.token_start;
- struct mtk_wed_buf *page_list;
-- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-- int token = dev->wlan.token_start;
-- int ring_size;
-- int n_pages;
-- int i, page_idx;
-+ void *desc_ptr;
-
-- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-- n_pages = ring_size / MTK_WED_BUF_PER_PAGE;
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-+ dev->tx_buf_ring.size = ring_size;
-+ } else {
-+ dev->tx_buf_ring.size = MTK_WED_TX_BM_DMA_SIZE;
-+ ring_size = MTK_WED_TX_BM_PKT_CNT;
-+ }
-+ n_pages = dev->tx_buf_ring.size / MTK_WED_BUF_PER_PAGE;
-
- page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
- if (!page_list)
- return -ENOMEM;
-
-- dev->tx_buf_ring.size = ring_size;
- dev->tx_buf_ring.pages = page_list;
-
-- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
-- &desc_phys, GFP_KERNEL);
-- if (!desc)
-+ desc_ptr = dma_alloc_coherent(dev->hw->dev,
-+ dev->tx_buf_ring.size * desc_size,
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc_ptr)
- return -ENOMEM;
-
-- dev->tx_buf_ring.desc = desc;
-+ dev->tx_buf_ring.desc = desc_ptr;
- dev->tx_buf_ring.desc_phys = desc_phys;
-
-- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
-+ for (i = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
- dma_addr_t page_phys, buf_phys;
- struct page *page;
- void *buf;
-@@ -371,28 +394,31 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- buf_phys = page_phys;
-
- for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
-- u32 txd_size;
-- u32 ctrl;
--
-- txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
-+ struct mtk_wdma_desc *desc = desc_ptr;
-
- desc->buf0 = cpu_to_le32(buf_phys);
-- desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ u32 txd_size, ctrl;
-
-- if (mtk_wed_is_v1(dev->hw))
-- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-- MTK_WED_BUF_SIZE - txd_size) |
-- MTK_WDMA_DESC_CTRL_LAST_SEG1;
-- else
-- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2,
-- MTK_WED_BUF_SIZE - txd_size) |
-- MTK_WDMA_DESC_CTRL_LAST_SEG0;
-- desc->ctrl = cpu_to_le32(ctrl);
-- desc->info = 0;
-- desc++;
-+ txd_size = dev->wlan.init_buf(buf, buf_phys,
-+ token++);
-+ desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size);
-+ if (mtk_wed_is_v1(dev->hw))
-+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG1 |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-+ MTK_WED_BUF_SIZE - txd_size);
-+ else
-+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG0 |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2,
-+ MTK_WED_BUF_SIZE - txd_size);
-+ desc->ctrl = cpu_to_le32(ctrl);
-+ desc->info = 0;
-+ } else {
-+ desc->ctrl = cpu_to_le32(token << 16);
-+ }
-
-+ desc_ptr += desc_size;
- buf += MTK_WED_BUF_SIZE;
- buf_phys += MTK_WED_BUF_SIZE;
- }
-@@ -408,31 +434,31 @@ static void
- mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
- {
- struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages;
-- struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
-- int page_idx;
-- int i;
-+ struct mtk_wed_hw *hw = dev->hw;
-+ int i, page_idx = 0;
-
- if (!page_list)
- return;
-
-- if (!desc)
-+ if (!dev->tx_buf_ring.desc)
- goto free_pagelist;
-
-- for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size;
-- i += MTK_WED_BUF_PER_PAGE) {
-- dma_addr_t buf_addr = page_list[page_idx].phy_addr;
-+ for (i = 0; i < dev->tx_buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
-+ dma_addr_t page_phy = page_list[page_idx].phy_addr;
- void *page = page_list[page_idx++].p;
-
- if (!page)
- break;
-
-- dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
-+ dma_unmap_page(dev->hw->dev, page_phy, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- __free_page(page);
- }
-
-- dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc),
-- desc, dev->tx_buf_ring.desc_phys);
-+ dma_free_coherent(dev->hw->dev,
-+ dev->tx_buf_ring.size * hw->soc->tx_ring_desc_size,
-+ dev->tx_buf_ring.desc,
-+ dev->tx_buf_ring.desc_phys);
-
- free_pagelist:
- kfree(page_list);
-@@ -517,13 +543,23 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- {
- u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-- if (mtk_wed_is_v1(dev->hw))
-+ switch (dev->hw->version) {
-+ case 1:
- mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
-- else
-+ break;
-+ case 2:
- mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
- MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH |
- MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
-+ break;
-+ case 3:
-+ mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-+ break;
-+ default:
-+ break;
-+ }
-
- if (!dev->hw->num_flows)
- mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-@@ -535,6 +571,9 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- static void
- mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable)
- {
-+ if (!mtk_wed_is_v2(dev->hw))
-+ return;
-+
- if (enable) {
- wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
- wed_w32(dev, MTK_WED_TXP_DW1,
-@@ -609,6 +648,14 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw) &&
-+ mtk_wed_get_rx_capa(dev)) {
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG,
-+ MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG,
-+ MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ }
- }
-
- mtk_wed_set_512_support(dev, false);
-@@ -651,6 +698,14 @@ mtk_wed_deinit(struct mtk_wed_device *de
- MTK_WED_CTRL_RX_ROUTE_QM_EN |
- MTK_WED_CTRL_WED_RX_BM_EN |
- MTK_WED_CTRL_RX_RRO_QM_EN);
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
-+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_TX_AMSDU);
-+ wed_clr(dev, MTK_WED_PCIE_INT_CTRL,
-+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER);
-+ }
- }
-
- static void
-@@ -700,21 +755,37 @@ mtk_wed_detach(struct mtk_wed_device *de
- mutex_unlock(&hw_lock);
- }
-
--#define PCIE_BASE_ADDR0 0x11280000
- static void
- mtk_wed_bus_init(struct mtk_wed_device *dev)
- {
- switch (dev->wlan.bus_type) {
- case MTK_WED_BUS_PCIE: {
- struct device_node *np = dev->hw->eth->dev->of_node;
-- struct regmap *regs;
-
-- regs = syscon_regmap_lookup_by_phandle(np,
-- "mediatek,wed-pcie");
-- if (IS_ERR(regs))
-- break;
-+ if (mtk_wed_is_v2(dev->hw)) {
-+ struct regmap *regs;
-+
-+ regs = syscon_regmap_lookup_by_phandle(np,
-+ "mediatek,wed-pcie");
-+ if (IS_ERR(regs))
-+ break;
-
-- regmap_update_bits(regs, 0, BIT(0), BIT(0));
-+ regmap_update_bits(regs, 0, BIT(0), BIT(0));
-+ }
-+
-+ if (dev->wlan.msi) {
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM,
-+ dev->hw->pcie_base | 0xc08);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE,
-+ dev->hw->pcie_base | 0xc04);
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(8));
-+ } else {
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM,
-+ dev->hw->pcie_base | 0x180);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE,
-+ dev->hw->pcie_base | 0x184);
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-+ }
-
- wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
-@@ -722,19 +793,9 @@ mtk_wed_bus_init(struct mtk_wed_device *
- /* pcie interrupt control: pola/source selection */
- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
-- wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
--
-- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
-- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
--
-- /* pcie interrupt status trigger register */
-- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
--
-- /* pola setting */
-- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER |
-+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL,
-+ dev->hw->index));
- break;
- }
- case MTK_WED_BUS_AXI:
-@@ -772,18 +833,19 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- static void
- mtk_wed_hw_init_early(struct mtk_wed_device *dev)
- {
-- u32 mask, set;
-+ u32 set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2);
-+ u32 mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE;
-
- mtk_wed_deinit(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
- mtk_wed_set_wpdma(dev);
-
-- mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
-- MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-- set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
-- MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
-- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ mask |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-+ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-+ set |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
-+ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
-+ }
- wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-
- if (mtk_wed_is_v1(dev->hw)) {
-@@ -931,11 +993,18 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_
- }
-
- /* configure RX_ROUTE_QM */
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-- FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ if (mtk_wed_is_v2(dev->hw)) {
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT,
-+ 0x3 + dev->hw->index));
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ } else {
-+ wed_set(dev, MTK_WED_RTQM_ENQ_CFG0,
-+ FIELD_PREP(MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT,
-+ 0x3 + dev->hw->index));
-+ }
- /* enable RX_ROUTE_QM */
- wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
- }
-@@ -948,22 +1017,30 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- dev->init_done = true;
- mtk_wed_set_ext_int(dev, false);
-- wed_w32(dev, MTK_WED_TX_BM_CTRL,
-- MTK_WED_TX_BM_CTRL_PAUSE |
-- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-- dev->tx_buf_ring.size / 128) |
-- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
-- MTK_WED_TX_RING_SIZE / 256));
-
- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys);
--
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
- if (mtk_wed_is_v1(dev->hw)) {
-+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-+ dev->tx_buf_ring.size / 128) |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
-+ MTK_WED_TX_RING_SIZE / 256));
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
- MTK_WED_TX_BM_DYN_THR_HI);
-- } else {
-+ } else if (mtk_wed_is_v2(dev->hw)) {
-+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-+ dev->tx_buf_ring.size / 128) |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
-+ MTK_WED_TX_RING_SIZE / 256));
-+ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
-+ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
-+ MTK_WED_TX_TKID_DYN_THR_HI);
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) |
- MTK_WED_TX_BM_DYN_THR_HI_V2);
-@@ -973,9 +1050,6 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- dev->tx_buf_ring.size / 128) |
- FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
- dev->tx_buf_ring.size / 128));
-- wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
-- FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
-- MTK_WED_TX_TKID_DYN_THR_HI);
- }
-
- wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid,
-@@ -985,26 +1059,62 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* switch to new bm architecture */
-+ wed_clr(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_LEGACY_EN);
-+
-+ wed_w32(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3,
-+ dev->wlan.nbuf / 128) |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3,
-+ dev->wlan.nbuf / 128));
-+ /* return SKBID + SDP back to bm */
-+ wed_set(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_FREE_FORMAT);
-+
-+ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR,
-+ MTK_WED_TX_BM_PKT_CNT |
-+ MTK_WED_TX_BM_INIT_SW_TAIL_IDX);
-+ }
-+
- if (mtk_wed_is_v1(dev->hw)) {
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-- } else {
-- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
-- if (mtk_wed_get_rx_capa(dev)) {
-- /* rx hw init */
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-- MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-- MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
--
-- mtk_wed_rx_buffer_hw_init(dev);
-- mtk_wed_rro_hw_init(dev);
-- mtk_wed_route_qm_hw_init(dev);
-- }
-+ } else if (mtk_wed_get_rx_capa(dev)) {
-+ /* rx hw init */
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+
-+ /* reset prefetch index of ring */
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+
-+ /* reset prefetch FIFO of ring */
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR |
-+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, 0);
-+
-+ mtk_wed_rx_buffer_hw_init(dev);
-+ mtk_wed_rro_hw_init(dev);
-+ mtk_wed_route_qm_hw_init(dev);
- }
-
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
-+ if (!mtk_wed_is_v1(dev->hw))
-+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
- }
-
- static void
-@@ -1302,6 +1412,24 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
- dev->hw->soc->wdma_desc_size, true))
- return -ENOMEM;
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ struct mtk_wdma_desc *desc = wdma->desc;
-+ int i;
-+
-+ for (i = 0; i < MTK_WED_WDMA_RING_SIZE; i++) {
-+ desc->buf0 = 0;
-+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ desc->buf1 = 0;
-+ desc->info = cpu_to_le32(MTK_WDMA_TXD0_DESC_INFO_DMA_DONE);
-+ desc++;
-+ desc->buf0 = 0;
-+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ desc->buf1 = 0;
-+ desc->info = cpu_to_le32(MTK_WDMA_TXD1_DESC_INFO_DMA_DONE);
-+ desc++;
-+ }
-+ }
-+
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
-@@ -1367,6 +1495,9 @@ mtk_wed_configure_irq(struct mtk_wed_dev
-
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_TKID_ALI_EN);
-+
- /* initail tx interrupt trigger */
- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
- MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-@@ -1419,33 +1550,60 @@ mtk_wed_dma_enable(struct mtk_wed_device
- {
- int i;
-
-- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
-+ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ wdma_set(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_TX_DMA_EN |
-+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-+ wed_set(dev, MTK_WED_WPDMA_CTRL, MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-+ } else {
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR);
-+ wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-+ }
-
- wed_set(dev, MTK_WED_GLO_CFG,
- MTK_WED_GLO_CFG_TX_DMA_EN |
- MTK_WED_GLO_CFG_RX_DMA_EN);
-- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+
- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-
-- wdma_set(dev, MTK_WDMA_GLO_CFG,
-- MTK_WDMA_GLO_CFG_TX_DMA_EN |
-- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
--
- if (mtk_wed_is_v1(dev->hw)) {
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- return;
- }
-
-- wed_set(dev, MTK_WED_WPDMA_CTRL,
-- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_BURST_SIZE, 0x10) |
-+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_LOW_THRES, 0x8));
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN);
-+
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
-+
-+ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ }
-+
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-@@ -1457,11 +1615,22 @@ mtk_wed_dma_enable(struct mtk_wed_device
- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RXD_READ_LEN);
- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
- MTK_WED_WPDMA_RX_D_RX_DRV_EN |
- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-- 0x2));
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, 0x2));
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE, 0x10) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_LOW_THRES, 0x8));
-+
-+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
-+ wdma_set(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ }
-
- for (i = 0; i < MTK_WED_RX_QUEUES; i++)
- mtk_wed_check_wfdma_rx_fill(dev, i);
-@@ -1501,6 +1670,12 @@ mtk_wed_start(struct mtk_wed_device *dev
- wed_r32(dev, MTK_WED_EXT_INT_MASK1);
- wed_r32(dev, MTK_WED_EXT_INT_MASK2);
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK3,
-+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK3);
-+ }
-+
- if (mtk_wed_rro_cfg(dev))
- return;
- }
-@@ -1552,6 +1727,7 @@ mtk_wed_attach(struct mtk_wed_device *de
- dev->irq = hw->irq;
- dev->wdma_idx = hw->index;
- dev->version = hw->version;
-+ dev->hw->pcie_base = mtk_wed_get_pcie_base(dev);
-
- if (hw->eth->dma_dev == hw->eth->dev &&
- of_dma_is_coherent(hw->eth->dev->of_node))
-@@ -1619,6 +1795,23 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- ring->reg_base = MTK_WED_RING_TX(idx);
- ring->wpdma = regs;
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw) && idx == 1) {
-+ /* reset prefetch index */
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ /* reset prefetch FIFO */
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG,
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR |
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR);
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0);
-+ }
-+
- /* WED -> WPDMA */
- wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
- wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_TX_RING_SIZE);
-@@ -1693,15 +1886,13 @@ mtk_wed_rx_ring_setup(struct mtk_wed_dev
- static u32
- mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
- {
-- u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-+ u32 val, ext_mask;
-
-- if (mtk_wed_is_v1(dev->hw))
-- ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ ext_mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
- else
-- ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-- MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH |
-- MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
-+ ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
- val = wed_r32(dev, MTK_WED_EXT_INT_STATUS);
- wed_w32(dev, MTK_WED_EXT_INT_STATUS, val);
-@@ -1942,6 +2133,9 @@ void mtk_wed_add_hw(struct device_node *
- case 2:
- hw->soc = &mt7986_data;
- break;
-+ case 3:
-+ hw->soc = &mt7988_data;
-+ break;
- default:
- case 1:
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -9,6 +9,8 @@
- #include <linux/regmap.h>
- #include <linux/netdevice.h>
-
-+#include "mtk_wed_regs.h"
-+
- struct mtk_eth;
- struct mtk_wed_wo;
-
-@@ -19,6 +21,7 @@ struct mtk_wed_soc_data {
- u32 reset_idx_tx_mask;
- u32 reset_idx_rx_mask;
- } regmap;
-+ u32 tx_ring_desc_size;
- u32 wdma_desc_size;
- };
-
-@@ -35,6 +38,7 @@ struct mtk_wed_hw {
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
- struct mtk_wed_wo *wed_wo;
-+ u32 pcie_base;
- u32 debugfs_reg;
- u32 num_flows;
- u8 version;
-@@ -61,6 +65,16 @@ static inline bool mtk_wed_is_v2(struct
- return hw->version == 2;
- }
-
-+static inline bool mtk_wed_is_v3(struct mtk_wed_hw *hw)
-+{
-+ return hw->version == 3;
-+}
-+
-+static inline bool mtk_wed_is_v3_or_greater(struct mtk_wed_hw *hw)
-+{
-+ return hw->version > 2;
-+}
-+
- static inline void
- wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
- {
-@@ -143,6 +157,21 @@ wpdma_txfree_w32(struct mtk_wed_device *
- writel(val, dev->txfree_ring.wpdma + reg);
- }
-
-+static inline u32 mtk_wed_get_pcie_base(struct mtk_wed_device *dev)
-+{
-+ if (!mtk_wed_is_v3_or_greater(dev->hw))
-+ return MTK_WED_PCIE_BASE;
-+
-+ switch (dev->hw->index) {
-+ case 1:
-+ return MTK_WED_PCIE_BASE1;
-+ case 2:
-+ return MTK_WED_PCIE_BASE2;
-+ default:
-+ return MTK_WED_PCIE_BASE0;
-+ }
-+}
-+
- void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, phys_addr_t wdma_phy,
- int index);
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -331,10 +331,22 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- wo->hw->index + 1);
-
- /* load firmware */
-- if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
-- fw_name = MT7981_FIRMWARE_WO;
-- else
-- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+ switch (wo->hw->version) {
-+ case 2:
-+ if (of_device_is_compatible(wo->hw->node,
-+ "mediatek,mt7981-wed"))
-+ fw_name = MT7981_FIRMWARE_WO;
-+ else
-+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1
-+ : MT7986_FIRMWARE_WO0;
-+ break;
-+ case 3:
-+ fw_name = wo->hw->index ? MT7988_FIRMWARE_WO1
-+ : MT7988_FIRMWARE_WO0;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-
- ret = request_firmware(&fw, fw_name, wo->hw->dev);
- if (ret)
-@@ -355,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- }
-
- /* set the start address */
-- boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR
-- : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
-+ if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
-+ boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR;
-+ else
-+ boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
- wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
- /* wo firmware reset */
- wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
-
-- val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
-- val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK
-- : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
-+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
-+ MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
- wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
- out:
- release_firmware(fw);
-@@ -398,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *
- MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
-+MODULE_FIRMWARE(MT7988_FIRMWARE_WO0);
-+MODULE_FIRMWARE(MT7988_FIRMWARE_WO1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -13,6 +13,9 @@
- #define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30)
- #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
-
-+#define MTK_WDMA_TXD0_DESC_INFO_DMA_DONE BIT(29)
-+#define MTK_WDMA_TXD1_DESC_INFO_DMA_DONE BIT(31)
-+
- struct mtk_wdma_desc {
- __le32 buf0;
- __le32 ctrl;
-@@ -37,6 +40,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
- #define MTK_WED_RESET_RX_RRO_QM BIT(20)
- #define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
-+#define MTK_WED_RESET_TX_AMSDU BIT(22)
- #define MTK_WED_RESET_WED BIT(31)
-
- #define MTK_WED_CTRL 0x00c
-@@ -44,6 +48,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1)
- #define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2)
- #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
-+#define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
-+#define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
-+#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7)
- #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
- #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
-@@ -54,9 +61,14 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
- #define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
- #define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
-+#define MTK_WED_CTRL_TX_TKID_ALI_EN BIT(20)
-+#define MTK_WED_CTRL_TX_TKID_ALI_BUSY BIT(21)
-+#define MTK_WED_CTRL_TX_AMSDU_EN BIT(22)
-+#define MTK_WED_CTRL_TX_AMSDU_BUSY BIT(23)
- #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
- #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25)
- #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
-+#define MTK_WED_CTRL_FLD_MIB_RD_CLR BIT(28)
-
- #define MTK_WED_EXT_INT_STATUS 0x020
- #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0)
-@@ -89,6 +101,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_MASK 0x028
- #define MTK_WED_EXT_INT_MASK1 0x02c
- #define MTK_WED_EXT_INT_MASK2 0x030
-+#define MTK_WED_EXT_INT_MASK3 0x034
-
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-@@ -96,9 +109,14 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_BM_CTRL 0x080
- #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
- #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-+#define MTK_WED_TX_BM_CTRL_LEGACY_EN BIT(26)
-+#define MTK_WED_TX_TKID_CTRL_FREE_FORMAT BIT(27)
- #define MTK_WED_TX_BM_CTRL_PAUSE BIT(28)
-
- #define MTK_WED_TX_BM_BASE 0x084
-+#define MTK_WED_TX_BM_INIT_PTR 0x088
-+#define MTK_WED_TX_BM_SW_TAIL_IDX GENMASK(16, 0)
-+#define MTK_WED_TX_BM_INIT_SW_TAIL_IDX BIT(16)
-
- #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
- #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-@@ -122,6 +140,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16)
- #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
-
-+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0)
-+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16)
-+
- #define MTK_WED_TX_TKID_DYN_THR 0x0e0
- #define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0)
- #define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16)
-@@ -199,12 +220,15 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7)
--#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(15, 12)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4 BIT(18)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19)
--#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK BIT(20)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21)
- #define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST BIT(25)
- #define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK BIT(30)
-
- #define MTK_WED_WPDMA_RESET_IDX 0x50c
- #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0)
-@@ -250,9 +274,10 @@ struct mtk_wdma_desc {
- #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16)
-
- #define MTK_WED_PCIE_INT_CTRL 0x57c
--#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
--#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
- #define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12)
-+#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
-+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
-+#define MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER BIT(21)
-
- #define MTK_WED_WPDMA_CFG_BASE 0x580
- #define MTK_WED_WPDMA_CFG_INT_MASK 0x584
-@@ -286,6 +311,20 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
- #define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
-
-+#define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
-+#define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
-+#define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX 0x7b8
-+#define MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR BIT(15)
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX 0x7bc
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG 0x7c0
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR BIT(16)
-+
- #define MTK_WED_WDMA_RING_TX 0x800
-
- #define MTK_WED_WDMA_TX_MIB 0x810
-@@ -293,6 +332,18 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
- #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
-
-+#define MTK_WED_WDMA_RX_PREF_CFG 0x950
-+#define MTK_WED_WDMA_RX_PREF_EN BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
-+#define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
-+#define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
-+#define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
-+#define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
-+
-+#define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
-+#define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR BIT(16)
-+
- #define MTK_WED_WDMA_GLO_CFG 0xa04
- #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
- #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
-@@ -325,6 +376,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16)
-
- #define MTK_WED_WDMA_INT_CTRL 0xa2c
-+#define MTK_WED_WDMA_INT_POLL_PRD GENMASK(7, 0)
- #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16)
-
- #define MTK_WED_WDMA_CFG_BASE 0xaa0
-@@ -388,6 +440,18 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_INT_GRP1 0x250
- #define MTK_WDMA_INT_GRP2 0x254
-
-+#define MTK_WDMA_PREF_TX_CFG 0x2d0
-+#define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
-+
-+#define MTK_WDMA_PREF_RX_CFG 0x2dc
-+#define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
-+
-+#define MTK_WDMA_WRBK_TX_CFG 0x300
-+#define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
-+
-+#define MTK_WDMA_WRBK_RX_CFG 0x344
-+#define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
-+
- #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
- #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
- #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
-@@ -401,6 +465,30 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
- #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-
-+#define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
-+#define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
-+#define MTK_WED_RTQM_IGRS0_I2H_PKT_CNT(_n) (0xb2c + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS0_FDROP_CNT 0xb34
-+
-+#define MTK_WED_RTQM_IGRS1_I2HW_DMAD_CNT 0xb44
-+#define MTK_WED_RTQM_IGRS1_I2H_DMAD_CNT(_n) (0xb48 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS1_I2HW_PKT_CNT 0xb50
-+#define MTK_WED_RTQM_IGRS1_I2H_PKT_CNT(_n) (0xb54 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS1_FDROP_CNT 0xb5c
-+
-+#define MTK_WED_RTQM_IGRS2_I2HW_DMAD_CNT 0xb6c
-+#define MTK_WED_RTQM_IGRS2_I2H_DMAD_CNT(_n) (0xb70 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS2_I2HW_PKT_CNT 0xb78
-+#define MTK_WED_RTQM_IGRS2_I2H_PKT_CNT(_n) (0xb7c + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS2_FDROP_CNT 0xb84
-+
-+#define MTK_WED_RTQM_IGRS3_I2HW_DMAD_CNT 0xb94
-+#define MTK_WED_RTQM_IGRS3_I2H_DMAD_CNT(_n) (0xb98 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS3_I2HW_PKT_CNT 0xba0
-+#define MTK_WED_RTQM_IGRS3_I2H_PKT_CNT(_n) (0xba4 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS3_FDROP_CNT 0xbac
-+
- #define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
- #define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
- #define MTK_WED_RTQM_Q2N_MIB 0xb80
-@@ -409,6 +497,24 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q2B_MIB 0xb8c
- #define MTK_WED_RTQM_PFDBK_MIB 0xb90
-
-+#define MTK_WED_RTQM_ENQ_CFG0 0xbb8
-+#define MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT GENMASK(15, 12)
-+
-+#define MTK_WED_RTQM_FDROP_MIB 0xb84
-+#define MTK_WED_RTQM_ENQ_I2Q_DMAD_CNT 0xbbc
-+#define MTK_WED_RTQM_ENQ_I2N_DMAD_CNT 0xbc0
-+#define MTK_WED_RTQM_ENQ_I2Q_PKT_CNT 0xbc4
-+#define MTK_WED_RTQM_ENQ_I2N_PKT_CNT 0xbc8
-+#define MTK_WED_RTQM_ENQ_USED_ENTRY_CNT 0xbcc
-+#define MTK_WED_RTQM_ENQ_ERR_CNT 0xbd0
-+
-+#define MTK_WED_RTQM_DEQ_DMAD_CNT 0xbd8
-+#define MTK_WED_RTQM_DEQ_Q2I_DMAD_CNT 0xbdc
-+#define MTK_WED_RTQM_DEQ_PKT_CNT 0xbe0
-+#define MTK_WED_RTQM_DEQ_Q2I_PKT_CNT 0xbe4
-+#define MTK_WED_RTQM_DEQ_USED_PFDBK_CNT 0xbe8
-+#define MTK_WED_RTQM_DEQ_ERR_CNT 0xbec
-+
- #define MTK_WED_RROQM_GLO_CFG 0xc04
- #define MTK_WED_RROQM_RST_IDX 0xc08
- #define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
-@@ -458,7 +564,116 @@ struct mtk_wdma_desc {
- #define MTK_WED_RX_BM_INTF 0xd9c
- #define MTK_WED_RX_BM_ERR_STS 0xda8
-
-+#define MTK_RRO_IND_CMD_SIGNATURE 0xe00
-+#define MTK_RRO_IND_CMD_DMA_IDX GENMASK(11, 0)
-+#define MTK_RRO_IND_CMD_MAGIC_CNT GENMASK(30, 28)
-+
-+#define MTK_WED_IND_CMD_RX_CTRL0 0xe04
-+#define MTK_WED_IND_CMD_PROC_IDX GENMASK(11, 0)
-+#define MTK_WED_IND_CMD_PREFETCH_FREE_CNT GENMASK(19, 16)
-+#define MTK_WED_IND_CMD_MAGIC_CNT GENMASK(30, 28)
-+
-+#define MTK_WED_IND_CMD_RX_CTRL1 0xe08
-+#define MTK_WED_IND_CMD_RX_CTRL2 0xe0c
-+#define MTK_WED_IND_CMD_MAX_CNT GENMASK(11, 0)
-+#define MTK_WED_IND_CMD_BASE_M GENMASK(19, 16)
-+
-+#define MTK_WED_RRO_CFG0 0xe10
-+#define MTK_WED_RRO_CFG1 0xe14
-+#define MTK_WED_RRO_CFG1_MAX_WIN_SZ GENMASK(31, 29)
-+#define MTK_WED_RRO_CFG1_ACK_SN_BASE_M GENMASK(19, 16)
-+#define MTK_WED_RRO_CFG1_PARTICL_SE_ID GENMASK(11, 0)
-+
-+#define MTK_WED_ADDR_ELEM_CFG0 0xe18
-+#define MTK_WED_ADDR_ELEM_CFG1 0xe1c
-+#define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT GENMASK(19, 16)
-+
-+#define MTK_WED_ADDR_ELEM_TBL_CFG 0xe20
-+#define MTK_WED_ADDR_ELEM_TBL_OFFSET GENMASK(6, 0)
-+#define MTK_WED_ADDR_ELEM_TBL_RD_RDY BIT(28)
-+#define MTK_WED_ADDR_ELEM_TBL_WR_RDY BIT(29)
-+#define MTK_WED_ADDR_ELEM_TBL_RD BIT(30)
-+#define MTK_WED_ADDR_ELEM_TBL_WR BIT(31)
-+
-+#define MTK_WED_RADDR_ELEM_TBL_WDATA 0xe24
-+#define MTK_WED_RADDR_ELEM_TBL_RDATA 0xe28
-+
-+#define MTK_WED_PN_CHECK_CFG 0xe30
-+#define MTK_WED_PN_CHECK_SE_ID GENMASK(11, 0)
-+#define MTK_WED_PN_CHECK_RD_RDY BIT(28)
-+#define MTK_WED_PN_CHECK_WR_RDY BIT(29)
-+#define MTK_WED_PN_CHECK_RD BIT(30)
-+#define MTK_WED_PN_CHECK_WR BIT(31)
-+
-+#define MTK_WED_PN_CHECK_WDATA_M 0xe38
-+#define MTK_WED_PN_CHECK_IS_FIRST BIT(17)
-+
-+#define MTK_WED_RRO_MSDU_PG_RING_CFG(_n) (0xe44 + (_n) * 0x8)
-+
-+#define MTK_WED_RRO_MSDU_PG_RING2_CFG 0xe58
-+#define MTK_WED_RRO_MSDU_PG_DRV_CLR BIT(26)
-+#define MTK_WED_RRO_MSDU_PG_DRV_EN BIT(31)
-+
-+#define MTK_WED_RRO_MSDU_PG_CTRL0(_n) (0xe5c + (_n) * 0xc)
-+#define MTK_WED_RRO_MSDU_PG_CTRL1(_n) (0xe60 + (_n) * 0xc)
-+#define MTK_WED_RRO_MSDU_PG_CTRL2(_n) (0xe64 + (_n) * 0xc)
-+
-+#define MTK_WED_RRO_RX_D_RX(_n) (0xe80 + (_n) * 0x10)
-+
-+#define MTK_WED_RRO_RX_MAGIC_CNT BIT(13)
-+
-+#define MTK_WED_RRO_RX_D_CFG(_n) (0xea0 + (_n) * 0x4)
-+#define MTK_WED_RRO_RX_D_DRV_CLR BIT(26)
-+#define MTK_WED_RRO_RX_D_DRV_EN BIT(31)
-+
-+#define MTK_WED_RRO_PG_BM_RX_DMAM 0xeb0
-+#define MTK_WED_RRO_PG_BM_RX_SDL0 GENMASK(13, 0)
-+
-+#define MTK_WED_RRO_PG_BM_BASE 0xeb4
-+#define MTK_WED_RRO_PG_BM_INIT_PTR 0xeb8
-+#define MTK_WED_RRO_PG_BM_SW_TAIL_IDX GENMASK(15, 0)
-+#define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX BIT(16)
-+
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX 0xeec
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG GENMASK(14, 10)
-+
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG 0xef4
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG GENMASK(14, 10)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN BIT(16)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
-+
-+#define MTK_WED_RX_IND_CMD_CNT0 0xf20
-+#define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
-+
-+#define MTK_WED_RX_IND_CMD_CNT(_n) (0xf20 + (_n) * 0x4)
-+#define MTK_WED_IND_CMD_MAGIC_CNT_FAIL_CNT GENMASK(15, 0)
-+
-+#define MTK_WED_RX_ADDR_ELEM_CNT(_n) (0xf48 + (_n) * 0x4)
-+#define MTK_WED_ADDR_ELEM_SIG_FAIL_CNT GENMASK(15, 0)
-+#define MTK_WED_ADDR_ELEM_FIRST_SIG_FAIL_CNT GENMASK(31, 16)
-+#define MTK_WED_ADDR_ELEM_ACKSN_CNT GENMASK(27, 0)
-+
-+#define MTK_WED_RX_MSDU_PG_CNT(_n) (0xf5c + (_n) * 0x4)
-+
-+#define MTK_WED_RX_PN_CHK_CNT 0xf70
-+#define MTK_WED_PN_CHK_FAIL_CNT GENMASK(15, 0)
-+
- #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
- #define MTK_WED_PCIE_INT_MASK 0x0
-
-+#define MTK_WED_PCIE_BASE 0x11280000
-+#define MTK_WED_PCIE_BASE0 0x11300000
-+#define MTK_WED_PCIE_BASE1 0x11310000
-+#define MTK_WED_PCIE_BASE2 0x11290000
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -91,6 +91,8 @@ enum mtk_wed_dummy_cr_idx {
- #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
- #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
- #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
-+#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin"
-+#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin"
-
- #define MTK_WO_MCU_CFG_LS_BASE 0
- #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -139,6 +139,8 @@ struct mtk_wed_device {
- u32 wpdma_rx;
-
- bool wcid_512;
-+ bool hw_rro;
-+ bool msi;
-
- u16 token_start;
- unsigned int nbuf;
-@@ -212,10 +214,12 @@ mtk_wed_device_attach(struct mtk_wed_dev
- return ret;
- }
-
--static inline bool
--mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
-+static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
- {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ if (dev->version == 3)
-+ return dev->wlan.hw_rro;
-+
- return dev->version != 1;
- #else
- return false;
diff --git a/target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch b/target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch
deleted file mode 100644
index e91ae69d08..0000000000
--- a/target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:14 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: refactor mtk_wed_check_wfdma_rx_fill
- routine
-
-Refactor mtk_wed_check_wfdma_rx_fill() in order to be reused adding HW
-receive offload support for MT7988 SoC.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -585,22 +585,15 @@ mtk_wed_set_512_support(struct mtk_wed_d
- }
- }
-
--#define MTK_WFMDA_RX_DMA_EN BIT(2)
--static void
--mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
-+static int
-+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev,
-+ struct mtk_wed_ring *ring)
- {
-- u32 val;
- int i;
-
-- if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED))
-- return; /* queue is not configured by mt76 */
--
- for (i = 0; i < 3; i++) {
-- u32 cur_idx;
-+ u32 cur_idx = readl(ring->wpdma + MTK_WED_RING_OFS_CPU_IDX);
-
-- cur_idx = wed_r32(dev,
-- MTK_WED_WPDMA_RING_RX_DATA(idx) +
-- MTK_WED_RING_OFS_CPU_IDX);
- if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
- break;
-
-@@ -609,12 +602,10 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_w
-
- if (i == 3) {
- dev_err(dev->hw->dev, "rx dma enable failed\n");
-- return;
-+ return -ETIMEDOUT;
- }
-
-- val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) |
-- MTK_WFMDA_RX_DMA_EN;
-- wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val);
-+ return 0;
- }
-
- static void
-@@ -1545,6 +1536,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
- }
-
-+#define MTK_WFMDA_RX_DMA_EN BIT(2)
- static void
- mtk_wed_dma_enable(struct mtk_wed_device *dev)
- {
-@@ -1632,8 +1624,26 @@ mtk_wed_dma_enable(struct mtk_wed_device
- wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
- }
-
-- for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-- mtk_wed_check_wfdma_rx_fill(dev, i);
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) {
-+ struct mtk_wed_ring *ring = &dev->rx_ring[i];
-+ u32 val;
-+
-+ if (!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue; /* queue is not configured by mt76 */
-+
-+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) {
-+ dev_err(dev->hw->dev,
-+ "rx_ring(%d) dma enable failed\n", i);
-+ continue;
-+ }
-+
-+ val = wifi_r32(dev,
-+ dev->wlan.wpdma_rx_glo -
-+ dev->wlan.phy_base) | MTK_WFMDA_RX_DMA_EN;
-+ wifi_w32(dev,
-+ dev->wlan.wpdma_rx_glo - dev->wlan.phy_base,
-+ val);
-+ }
- }
-
- static void
diff --git a/target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch b/target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch
deleted file mode 100644
index 21a4e0759f..0000000000
--- a/target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch
+++ /dev/null
@@ -1,465 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:15 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce partial AMSDU offload
- support for MT7988
-
-Introduce partial AMSDU offload support for MT7988 SoC in order to merge
-in hw packets belonging to the same AMSDU before passing them to the
-WLAN nic.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -438,7 +438,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
- }
-
- int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-- int wdma_idx, int txq, int bss, int wcid)
-+ int wdma_idx, int txq, int bss, int wcid,
-+ bool amsdu_en)
- {
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-@@ -450,6 +451,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- MTK_FOE_IB2_WDMA_WINFO_V2;
- l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
- FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
-+ l2->amsdu = FIELD_PREP(MTK_FOE_WINFO_AMSDU_EN, amsdu_en);
- break;
- case 2:
- *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -88,13 +88,13 @@ enum {
- #define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16)
- #define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0)
-
--#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0)
--#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16)
--#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20)
--#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21)
--#define MTK_FOE_WINFO_PAO_IS_SP BIT(22)
--#define MTK_FOE_WINFO_PAO_HF BIT(23)
--#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24)
-+#define MTK_FOE_WINFO_AMSDU_USR_INFO GENMASK(15, 0)
-+#define MTK_FOE_WINFO_AMSDU_TID GENMASK(19, 16)
-+#define MTK_FOE_WINFO_AMSDU_IS_FIXEDRATE BIT(20)
-+#define MTK_FOE_WINFO_AMSDU_IS_PRIOR BIT(21)
-+#define MTK_FOE_WINFO_AMSDU_IS_SP BIT(22)
-+#define MTK_FOE_WINFO_AMSDU_HF BIT(23)
-+#define MTK_FOE_WINFO_AMSDU_EN BIT(24)
-
- enum {
- MTK_FOE_STATE_INVALID,
-@@ -123,7 +123,7 @@ struct mtk_foe_mac_info {
-
- /* netsys_v3 */
- u32 w3info;
-- u32 wpao;
-+ u32 amsdu;
- };
-
- /* software-only entry type */
-@@ -393,7 +393,8 @@ int mtk_foe_entry_set_vlan(struct mtk_et
- int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
- int sid);
- int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-- int wdma_idx, int txq, int bss, int wcid);
-+ int wdma_idx, int txq, int bss, int wcid,
-+ bool amsdu_en);
- int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
- unsigned int queue);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -111,6 +111,7 @@ mtk_flow_get_wdma_info(struct net_device
- info->queue = path->mtk_wdma.queue;
- info->bss = path->mtk_wdma.bss;
- info->wcid = path->mtk_wdma.wcid;
-+ info->amsdu = path->mtk_wdma.amsdu;
-
- return 0;
- }
-@@ -192,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
-
- if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
- mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
-- info.bss, info.wcid);
-+ info.bss, info.wcid, info.amsdu);
- if (mtk_is_netsys_v2_or_greater(eth)) {
- switch (info.wdma_idx) {
- case 0:
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -29,6 +29,8 @@
- #define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
- #define MTK_WED_RX_RING_SIZE 1536
- #define MTK_WED_RX_PG_BM_CNT 8192
-+#define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4)
-+#define MTK_WED_AMSDU_NPAGES 32
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 1024
-@@ -172,6 +174,23 @@ mtk_wdma_rx_reset(struct mtk_wed_device
- return ret;
- }
-
-+static u32
-+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ return !!(wed_r32(dev, reg) & mask);
-+}
-+
-+static int
-+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ int sleep = 15000;
-+ int timeout = 100 * sleep;
-+ u32 val;
-+
-+ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-+ timeout, false, dev, reg, mask);
-+}
-+
- static void
- mtk_wdma_tx_reset(struct mtk_wed_device *dev)
- {
-@@ -335,6 +354,118 @@ out:
- }
-
- static int
-+mtk_wed_amsdu_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_hw *hw = dev->hw;
-+ struct mtk_wed_amsdu *wed_amsdu;
-+ int i;
-+
-+ if (!mtk_wed_is_v3_or_greater(hw))
-+ return 0;
-+
-+ wed_amsdu = devm_kcalloc(hw->dev, MTK_WED_AMSDU_NPAGES,
-+ sizeof(*wed_amsdu), GFP_KERNEL);
-+ if (!wed_amsdu)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
-+ void *ptr;
-+
-+ /* each segment is 64K */
-+ ptr = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN |
-+ __GFP_ZERO | __GFP_COMP |
-+ GFP_DMA32,
-+ get_order(MTK_WED_AMSDU_BUF_SIZE));
-+ if (!ptr)
-+ goto error;
-+
-+ wed_amsdu[i].txd = ptr;
-+ wed_amsdu[i].txd_phy = dma_map_single(hw->dev, ptr,
-+ MTK_WED_AMSDU_BUF_SIZE,
-+ DMA_TO_DEVICE);
-+ if (dma_mapping_error(hw->dev, wed_amsdu[i].txd_phy))
-+ goto error;
-+ }
-+ dev->hw->wed_amsdu = wed_amsdu;
-+
-+ return 0;
-+
-+error:
-+ for (i--; i >= 0; i--)
-+ dma_unmap_single(hw->dev, wed_amsdu[i].txd_phy,
-+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
-+ return -ENOMEM;
-+}
-+
-+static void
-+mtk_wed_amsdu_free_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
-+ int i;
-+
-+ if (!wed_amsdu)
-+ return;
-+
-+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
-+ dma_unmap_single(dev->hw->dev, wed_amsdu[i].txd_phy,
-+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
-+ free_pages((unsigned long)wed_amsdu[i].txd,
-+ get_order(MTK_WED_AMSDU_BUF_SIZE));
-+ }
-+}
-+
-+static int
-+mtk_wed_amsdu_init(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
-+ int i, ret;
-+
-+ if (!wed_amsdu)
-+ return 0;
-+
-+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++)
-+ wed_w32(dev, MTK_WED_AMSDU_HIFTXD_BASE_L(i),
-+ wed_amsdu[i].txd_phy);
-+
-+ /* init all sta parameter */
-+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO_INIT, MTK_WED_AMSDU_STA_RMVL |
-+ MTK_WED_AMSDU_STA_WTBL_HDRT_MODE |
-+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_LEN,
-+ dev->wlan.amsdu_max_len >> 8) |
-+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_NUM,
-+ dev->wlan.amsdu_max_subframes));
-+
-+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO, MTK_WED_AMSDU_STA_INFO_DO_INIT);
-+
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_AMSDU_STA_INFO,
-+ MTK_WED_AMSDU_STA_INFO_DO_INIT);
-+ if (ret) {
-+ dev_err(dev->hw->dev, "amsdu initialization failed\n");
-+ return ret;
-+ }
-+
-+ /* init partial amsdu offload txd src */
-+ wed_set(dev, MTK_WED_AMSDU_HIFTXD_CFG,
-+ FIELD_PREP(MTK_WED_AMSDU_HIFTXD_SRC, dev->hw->index));
-+
-+ /* init qmem */
-+ wed_set(dev, MTK_WED_AMSDU_PSE, MTK_WED_AMSDU_PSE_RESET);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_MON_AMSDU_QMEM_STS1, BIT(29));
-+ if (ret) {
-+ pr_info("%s: amsdu qmem initialization failed\n", __func__);
-+ return ret;
-+ }
-+
-+ /* eagle E1 PCIE1 tx ring 22 flow control issue */
-+ if (dev->wlan.id == 0x7991)
-+ wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING);
-+
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
-+
-+ return 0;
-+}
-+
-+static int
- mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
- u32 desc_size = dev->hw->soc->tx_ring_desc_size;
-@@ -708,6 +839,7 @@ __mtk_wed_detach(struct mtk_wed_device *
-
- mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+ mtk_wed_amsdu_free_buffer(dev);
- mtk_wed_free_tx_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-
-@@ -1128,23 +1260,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
- }
- }
-
--static u32
--mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
--{
-- return !!(wed_r32(dev, reg) & mask);
--}
--
--static int
--mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
--{
-- int sleep = 15000;
-- int timeout = 100 * sleep;
-- u32 val;
--
-- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-- timeout, false, dev, reg, mask);
--}
--
- static int
- mtk_wed_rx_reset(struct mtk_wed_device *dev)
- {
-@@ -1691,6 +1806,7 @@ mtk_wed_start(struct mtk_wed_device *dev
- }
-
- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-+ mtk_wed_amsdu_init(dev);
-
- mtk_wed_dma_enable(dev);
- dev->running = true;
-@@ -1747,6 +1863,10 @@ mtk_wed_attach(struct mtk_wed_device *de
- if (ret)
- goto out;
-
-+ ret = mtk_wed_amsdu_buffer_alloc(dev);
-+ if (ret)
-+ goto out;
-+
- if (mtk_wed_get_rx_capa(dev)) {
- ret = mtk_wed_rro_alloc(dev);
- if (ret)
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -25,6 +25,11 @@ struct mtk_wed_soc_data {
- u32 wdma_desc_size;
- };
-
-+struct mtk_wed_amsdu {
-+ void *txd;
-+ dma_addr_t txd_phy;
-+};
-+
- struct mtk_wed_hw {
- const struct mtk_wed_soc_data *soc;
- struct device_node *node;
-@@ -38,6 +43,7 @@ struct mtk_wed_hw {
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
- struct mtk_wed_wo *wed_wo;
-+ struct mtk_wed_amsdu *wed_amsdu;
- u32 pcie_base;
- u32 debugfs_reg;
- u32 num_flows;
-@@ -52,6 +58,7 @@ struct mtk_wdma_info {
- u8 queue;
- u16 wcid;
- u8 bss;
-+ u8 amsdu;
- };
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -672,6 +672,82 @@ struct mtk_wdma_desc {
- #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
- #define MTK_WED_PCIE_INT_MASK 0x0
-
-+#define MTK_WED_AMSDU_FIFO 0x1800
-+#define MTK_WED_AMSDU_IS_PRIOR0_RING BIT(10)
-+
-+#define MTK_WED_AMSDU_STA_INFO 0x01810
-+#define MTK_WED_AMSDU_STA_INFO_DO_INIT BIT(0)
-+#define MTK_WED_AMSDU_STA_INFO_SET_INIT BIT(1)
-+
-+#define MTK_WED_AMSDU_STA_INFO_INIT 0x01814
-+#define MTK_WED_AMSDU_STA_WTBL_HDRT_MODE BIT(0)
-+#define MTK_WED_AMSDU_STA_RMVL BIT(1)
-+#define MTK_WED_AMSDU_STA_MAX_AMSDU_LEN GENMASK(7, 2)
-+#define MTK_WED_AMSDU_STA_MAX_AMSDU_NUM GENMASK(11, 8)
-+
-+#define MTK_WED_AMSDU_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4)
-+
-+#define MTK_WED_AMSDU_PSE 0x1910
-+#define MTK_WED_AMSDU_PSE_RESET BIT(16)
-+
-+#define MTK_WED_AMSDU_HIFTXD_CFG 0x1968
-+#define MTK_WED_AMSDU_HIFTXD_SRC GENMASK(16, 15)
-+
-+#define MTK_WED_MON_AMSDU_FIFO_DMAD 0x1a34
-+
-+#define MTK_WED_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50)
-+
-+#define MTK_WED_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50)
-+#define MTK_WED_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0)
-+#define MTK_WED_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16)
-+
-+#define MTK_WED_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50)
-+#define MTK_WED_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0)
-+#define MTK_WED_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16)
-+#define MTK_WED_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24)
-+
-+#define MTK_WED_MON_AMSDU_QMEM_STS1 0x1e04
-+
-+#define MTK_WED_MON_AMSDU_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4)
-+#define MTK_WED_AMSDU_QMEM_FQ_CNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_SP_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID0_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID1_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID2_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID3_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID4_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID5_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID6_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID7_QCNT GENMASK(11, 0)
-+
-+#define MTK_WED_MON_AMSDU_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4)
-+#define MTK_WED_AMSDU_QMEM_FQ_HEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_SP_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID0_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID1_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID2_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID3_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID4_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID5_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID6_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID7_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_FQ_TAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_SP_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID0_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID1_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID2_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID3_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID4_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID5_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID6_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID7_QTAIL GENMASK(11, 0)
-+
-+#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4)
-+
- #define MTK_WED_PCIE_BASE 0x11280000
- #define MTK_WED_PCIE_BASE0 0x11300000
- #define MTK_WED_PCIE_BASE1 0x11310000
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -906,6 +906,7 @@ struct net_device_path {
- u8 queue;
- u16 wcid;
- u8 bss;
-+ u8 amsdu;
- } mtk_wdma;
- };
- };
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -129,6 +129,7 @@ struct mtk_wed_device {
- enum mtk_wed_bus_tye bus_type;
- void __iomem *base;
- u32 phy_base;
-+ u32 id;
-
- u32 wpdma_phys;
- u32 wpdma_int;
-@@ -147,10 +148,12 @@ struct mtk_wed_device {
- unsigned int rx_nbuf;
- unsigned int rx_npkt;
- unsigned int rx_size;
-+ unsigned int amsdu_max_len;
-
- u8 tx_tbit[MTK_WED_TX_QUEUES];
- u8 rx_tbit[MTK_WED_RX_QUEUES];
- u8 txfree_tbit;
-+ u8 amsdu_max_subframes;
-
- u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
- int (*offload_enable)(struct mtk_wed_device *wed);
-@@ -224,6 +227,15 @@ static inline bool mtk_wed_get_rx_capa(s
- #else
- return false;
- #endif
-+}
-+
-+static inline bool mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev)
-+{
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ return dev->version == 3;
-+#else
-+ return false;
-+#endif
- }
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
diff --git a/target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch b/target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
deleted file mode 100644
index 0cf4c18875..0000000000
--- a/target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
+++ /dev/null
@@ -1,483 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:16 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce hw_rro support for MT7988
-
-MT7988 SoC support 802.11 receive reordering offload in hw while
-MT7986 SoC implements it through the firmware running on the mcu.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -26,7 +26,7 @@
- #define MTK_WED_BUF_SIZE 2048
- #define MTK_WED_PAGE_BUF_SIZE 128
- #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
--#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
-+#define MTK_WED_RX_BUF_PER_PAGE (PAGE_SIZE / MTK_WED_PAGE_BUF_SIZE)
- #define MTK_WED_RX_RING_SIZE 1536
- #define MTK_WED_RX_PG_BM_CNT 8192
- #define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4)
-@@ -596,6 +596,68 @@ free_pagelist:
- }
-
- static int
-+mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ int n_pages = MTK_WED_RX_PG_BM_CNT / MTK_WED_RX_BUF_PER_PAGE;
-+ struct mtk_wed_buf *page_list;
-+ struct mtk_wed_bm_desc *desc;
-+ dma_addr_t desc_phys;
-+ int i, page_idx = 0;
-+
-+ if (!dev->wlan.hw_rro)
-+ return 0;
-+
-+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
-+ if (!page_list)
-+ return -ENOMEM;
-+
-+ dev->hw_rro.size = dev->wlan.rx_nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-+ dev->hw_rro.pages = page_list;
-+ desc = dma_alloc_coherent(dev->hw->dev,
-+ dev->wlan.rx_nbuf * sizeof(*desc),
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc)
-+ return -ENOMEM;
-+
-+ dev->hw_rro.desc = desc;
-+ dev->hw_rro.desc_phys = desc_phys;
-+
-+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) {
-+ dma_addr_t page_phys, buf_phys;
-+ struct page *page;
-+ int s;
-+
-+ page = __dev_alloc_page(GFP_KERNEL);
-+ if (!page)
-+ return -ENOMEM;
-+
-+ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ if (dma_mapping_error(dev->hw->dev, page_phys)) {
-+ __free_page(page);
-+ return -ENOMEM;
-+ }
-+
-+ page_list[page_idx].p = page;
-+ page_list[page_idx++].phy_addr = page_phys;
-+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+
-+ buf_phys = page_phys;
-+ for (s = 0; s < MTK_WED_RX_BUF_PER_PAGE; s++) {
-+ desc->buf0 = cpu_to_le32(buf_phys);
-+ buf_phys += MTK_WED_PAGE_BUF_SIZE;
-+ desc++;
-+ }
-+
-+ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ }
-+
-+ return 0;
-+}
-+
-+static int
- mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
- {
- struct mtk_wed_bm_desc *desc;
-@@ -612,7 +674,42 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d
- dev->rx_buf_ring.desc_phys = desc_phys;
- dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
-
-- return 0;
-+ return mtk_wed_hwrro_buffer_alloc(dev);
-+}
-+
-+static void
-+mtk_wed_hwrro_free_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_buf *page_list = dev->hw_rro.pages;
-+ struct mtk_wed_bm_desc *desc = dev->hw_rro.desc;
-+ int i, page_idx = 0;
-+
-+ if (!dev->wlan.hw_rro)
-+ return;
-+
-+ if (!page_list)
-+ return;
-+
-+ if (!desc)
-+ goto free_pagelist;
-+
-+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) {
-+ dma_addr_t buf_addr = page_list[page_idx].phy_addr;
-+ void *page = page_list[page_idx++].p;
-+
-+ if (!page)
-+ break;
-+
-+ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ __free_page(page);
-+ }
-+
-+ dma_free_coherent(dev->hw->dev, dev->hw_rro.size * sizeof(*desc),
-+ desc, dev->hw_rro.desc_phys);
-+
-+free_pagelist:
-+ kfree(page_list);
- }
-
- static void
-@@ -626,6 +723,28 @@ mtk_wed_free_rx_buffer(struct mtk_wed_de
- dev->wlan.release_rx_buf(dev);
- dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc),
- desc, dev->rx_buf_ring.desc_phys);
-+
-+ mtk_wed_hwrro_free_buffer(dev);
-+}
-+
-+static void
-+mtk_wed_hwrro_init(struct mtk_wed_device *dev)
-+{
-+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
-+ return;
-+
-+ wed_set(dev, MTK_WED_RRO_PG_BM_RX_DMAM,
-+ FIELD_PREP(MTK_WED_RRO_PG_BM_RX_SDL0, 128));
-+
-+ wed_w32(dev, MTK_WED_RRO_PG_BM_BASE, dev->hw_rro.desc_phys);
-+
-+ wed_w32(dev, MTK_WED_RRO_PG_BM_INIT_PTR,
-+ MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX |
-+ FIELD_PREP(MTK_WED_RRO_PG_BM_SW_TAIL_IDX,
-+ MTK_WED_RX_PG_BM_CNT));
-+
-+ /* enable rx_page_bm to fetch dmad */
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
- }
-
- static void
-@@ -639,6 +758,8 @@ mtk_wed_rx_buffer_hw_init(struct mtk_wed
- wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
- FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
- wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+
-+ mtk_wed_hwrro_init(dev);
- }
-
- static void
-@@ -934,6 +1055,8 @@ mtk_wed_bus_init(struct mtk_wed_device *
- static void
- mtk_wed_set_wpdma(struct mtk_wed_device *dev)
- {
-+ int i;
-+
- if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
- return;
-@@ -951,6 +1074,15 @@ mtk_wed_set_wpdma(struct mtk_wed_device
-
- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
- wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx);
-+
-+ if (!dev->wlan.hw_rro)
-+ return;
-+
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(0), dev->wlan.wpdma_rx_rro[0]);
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(1), dev->wlan.wpdma_rx_rro[1]);
-+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++)
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING_CFG(i),
-+ dev->wlan.wpdma_rx_pg + i * 0x10);
- }
-
- static void
-@@ -1762,6 +1894,165 @@ mtk_wed_dma_enable(struct mtk_wed_device
- }
-
- static void
-+mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask, bool reset)
-+{
-+ int i;
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
-+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
-+
-+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
-+ return;
-+
-+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG,
-+ dev->wlan.rro_rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG,
-+ dev->wlan.rro_rx_tbit[1]));
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG,
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[1]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[2]));
-+
-+ /* RRO_MSDU_PG_RING2_CFG1_FLD_DRV_EN should be enabled after
-+ * WM FWDL completed, otherwise RRO_MSDU_PG ring may broken
-+ */
-+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_EN);
-+
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) {
-+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[i];
-+
-+ if (!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue;
-+
-+ if (mtk_wed_check_wfdma_rx_fill(dev, ring))
-+ dev_err(dev->hw->dev,
-+ "rx_rro_ring(%d) initialization failed\n", i);
-+ }
-+
-+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) {
-+ struct mtk_wed_ring *ring = &dev->rx_page_ring[i];
-+
-+ if (!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue;
-+
-+ if (mtk_wed_check_wfdma_rx_fill(dev, ring))
-+ dev_err(dev->hw->dev,
-+ "rx_page_ring(%d) initialization failed\n", i);
-+ }
-+}
-+
-+static void
-+mtk_wed_rro_rx_ring_setup(struct mtk_wed_device *dev, int idx,
-+ void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx];
-+
-+ ring->wpdma = regs;
-+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_BASE,
-+ readl(regs));
-+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+}
-+
-+static void
-+mtk_wed_msdu_pg_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx];
-+
-+ ring->wpdma = regs;
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_BASE,
-+ readl(regs));
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+}
-+
-+static int
-+mtk_wed_ind_rx_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->ind_cmd_ring;
-+ u32 val = readl(regs + MTK_WED_RING_OFS_COUNT);
-+ int i, count = 0;
-+
-+ ring->wpdma = regs;
-+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_BASE,
-+ readl(regs) & 0xfffffff0);
-+
-+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+
-+ /* ack sn cr */
-+ wed_w32(dev, MTK_WED_RRO_CFG0, dev->wlan.phy_base +
-+ dev->wlan.ind_cmd.ack_sn_addr);
-+ wed_w32(dev, MTK_WED_RRO_CFG1,
-+ FIELD_PREP(MTK_WED_RRO_CFG1_MAX_WIN_SZ,
-+ dev->wlan.ind_cmd.win_size) |
-+ FIELD_PREP(MTK_WED_RRO_CFG1_PARTICL_SE_ID,
-+ dev->wlan.ind_cmd.particular_sid));
-+
-+ /* particular session addr element */
-+ wed_w32(dev, MTK_WED_ADDR_ELEM_CFG0,
-+ dev->wlan.ind_cmd.particular_se_phys);
-+
-+ for (i = 0; i < dev->wlan.ind_cmd.se_group_nums; i++) {
-+ wed_w32(dev, MTK_WED_RADDR_ELEM_TBL_WDATA,
-+ dev->wlan.ind_cmd.addr_elem_phys[i] >> 4);
-+ wed_w32(dev, MTK_WED_ADDR_ELEM_TBL_CFG,
-+ MTK_WED_ADDR_ELEM_TBL_WR | (i & 0x7f));
-+
-+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
-+ while (!(val & MTK_WED_ADDR_ELEM_TBL_WR_RDY) && count++ < 100)
-+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
-+ if (count >= 100)
-+ dev_err(dev->hw->dev,
-+ "write ba session base failed\n");
-+ }
-+
-+ /* pn check init */
-+ for (i = 0; i < dev->wlan.ind_cmd.particular_sid; i++) {
-+ wed_w32(dev, MTK_WED_PN_CHECK_WDATA_M,
-+ MTK_WED_PN_CHECK_IS_FIRST);
-+
-+ wed_w32(dev, MTK_WED_PN_CHECK_CFG, MTK_WED_PN_CHECK_WR |
-+ FIELD_PREP(MTK_WED_PN_CHECK_SE_ID, i));
-+
-+ count = 0;
-+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
-+ while (!(val & MTK_WED_PN_CHECK_WR_RDY) && count++ < 100)
-+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
-+ if (count >= 100)
-+ dev_err(dev->hw->dev,
-+ "session(%d) initialization failed\n", i);
-+ }
-+
-+ wed_w32(dev, MTK_WED_RX_IND_CMD_CNT0, MTK_WED_RX_IND_CMD_DBG_CNT_EN);
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
-+
-+ return 0;
-+}
-+
-+static void
- mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
- {
- int i;
-@@ -2215,6 +2506,10 @@ void mtk_wed_add_hw(struct device_node *
- .detach = mtk_wed_detach,
- .ppe_check = mtk_wed_ppe_check,
- .setup_tc = mtk_wed_setup_tc,
-+ .start_hw_rro = mtk_wed_start_hw_rro,
-+ .rro_rx_ring_setup = mtk_wed_rro_rx_ring_setup,
-+ .msdu_pg_rx_ring_setup = mtk_wed_msdu_pg_rx_ring_setup,
-+ .ind_rx_ring_setup = mtk_wed_ind_rx_ring_setup,
- };
- struct device_node *eth_np = eth->dev->of_node;
- struct platform_device *pdev;
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -10,6 +10,7 @@
-
- #define MTK_WED_TX_QUEUES 2
- #define MTK_WED_RX_QUEUES 2
-+#define MTK_WED_RX_PAGE_QUEUES 3
-
- #define WED_WO_STA_REC 0x6
-
-@@ -99,6 +100,9 @@ struct mtk_wed_device {
- struct mtk_wed_ring txfree_ring;
- struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-+ struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES];
-+ struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES];
-+ struct mtk_wed_ring ind_cmd_ring;
-
- struct {
- int size;
-@@ -120,6 +124,13 @@ struct mtk_wed_device {
- dma_addr_t fdbk_phys;
- } rro;
-
-+ struct {
-+ int size;
-+ struct mtk_wed_buf *pages;
-+ struct mtk_wed_bm_desc *desc;
-+ dma_addr_t desc_phys;
-+ } hw_rro;
-+
- /* filled by driver: */
- struct {
- union {
-@@ -138,6 +149,8 @@ struct mtk_wed_device {
- u32 wpdma_txfree;
- u32 wpdma_rx_glo;
- u32 wpdma_rx;
-+ u32 wpdma_rx_rro[MTK_WED_RX_QUEUES];
-+ u32 wpdma_rx_pg;
-
- bool wcid_512;
- bool hw_rro;
-@@ -152,9 +165,20 @@ struct mtk_wed_device {
-
- u8 tx_tbit[MTK_WED_TX_QUEUES];
- u8 rx_tbit[MTK_WED_RX_QUEUES];
-+ u8 rro_rx_tbit[MTK_WED_RX_QUEUES];
-+ u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES];
- u8 txfree_tbit;
- u8 amsdu_max_subframes;
-
-+ struct {
-+ u8 se_group_nums;
-+ u16 win_size;
-+ u16 particular_sid;
-+ u32 ack_sn_addr;
-+ dma_addr_t particular_se_phys;
-+ dma_addr_t addr_elem_phys[1024];
-+ } ind_cmd;
-+
- u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
- int (*offload_enable)(struct mtk_wed_device *wed);
- void (*offload_disable)(struct mtk_wed_device *wed);
-@@ -193,6 +217,14 @@ struct mtk_wed_ops {
- void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
- int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev,
- enum tc_setup_type type, void *type_data);
-+ void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask,
-+ bool reset);
-+ void (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
-+ void (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
-+ int (*ind_rx_ring_setup)(struct mtk_wed_device *dev,
-+ void __iomem *regs);
- };
-
- extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -264,6 +296,15 @@ static inline bool mtk_wed_is_amsdu_supp
- #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
- #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \
- (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data)
-+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) \
-+ (_dev)->ops->start_hw_rro(_dev, _mask, _reset)
-+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \
-+ (_dev)->ops->ind_rx_ring_setup(_dev, _regs)
-+
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -283,6 +324,10 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_stop(_dev) do {} while (0)
- #define mtk_wed_device_dma_reset(_dev) do {} while (0)
- #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP
-+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) do {} while (0)
-+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch b/target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch
deleted file mode 100644
index 5ea43a4445..0000000000
--- a/target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:17 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: debugfs: move wed_v2 specific regs
- out of regs array
-
-Move specific WED2.0 debugfs entries out of regs array. This is a
-preliminary patch to introduce WED 3.0 debugfs info.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -151,7 +151,7 @@ DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
- static int
- wed_rxinfo_show(struct seq_file *s, void *data)
- {
-- static const struct reg_dump regs[] = {
-+ static const struct reg_dump regs_common[] = {
- DUMP_STR("WPDMA RX"),
- DUMP_WPDMA_RX_RING(0),
- DUMP_WPDMA_RX_RING(1),
-@@ -169,7 +169,7 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED_RING(WED_RING_RX_DATA(0)),
- DUMP_WED_RING(WED_RING_RX_DATA(1)),
-
-- DUMP_STR("WED RRO"),
-+ DUMP_STR("WED WO RRO"),
- DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
- DUMP_WED(WED_RROQM_MID_MIB),
- DUMP_WED(WED_RROQM_MOD_MIB),
-@@ -180,17 +180,6 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
- DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
-
-- DUMP_STR("WED Route QM"),
-- DUMP_WED(WED_RTQM_R2H_MIB(0)),
-- DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-- DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-- DUMP_WED(WED_RTQM_R2H_MIB(1)),
-- DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-- DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-- DUMP_WED(WED_RTQM_Q2N_MIB),
-- DUMP_WED(WED_RTQM_Q2B_MIB),
-- DUMP_WED(WED_RTQM_PFDBK_MIB),
--
- DUMP_STR("WED WDMA TX"),
- DUMP_WED(WED_WDMA_TX_MIB),
- DUMP_WED_RING(WED_WDMA_RING_TX),
-@@ -211,11 +200,25 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED(WED_RX_BM_INTF),
- DUMP_WED(WED_RX_BM_ERR_STS),
- };
-+ static const struct reg_dump regs_wed_v2[] = {
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_R2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2N_MIB),
-+ DUMP_WED(WED_RTQM_Q2B_MIB),
-+ DUMP_WED(WED_RTQM_PFDBK_MIB),
-+ };
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
-- if (dev)
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ if (dev) {
-+ dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common));
-+ dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
-+ }
-
- return 0;
- }
diff --git a/target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch b/target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch
deleted file mode 100644
index f491d2fd80..0000000000
--- a/target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch
+++ /dev/null
@@ -1,432 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:18 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: debugfs: add WED 3.0 debugfs entries
-
-Introduce WED3.0 debugfs entries useful for debugging.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -11,6 +11,7 @@ struct reg_dump {
- u16 offset;
- u8 type;
- u8 base;
-+ u32 mask;
- };
-
- enum {
-@@ -25,6 +26,8 @@ enum {
-
- #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
- #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
-+#define DUMP_REG_MASK(_reg, _mask) \
-+ { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask }
- #define DUMP_RING(_prefix, _base, ...) \
- { _prefix " BASE", _base, __VA_ARGS__ }, \
- { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \
-@@ -32,6 +35,7 @@ enum {
- { _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
-
- #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
-+#define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask)
- #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
-
- #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
-@@ -212,12 +216,58 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED(WED_RTQM_Q2B_MIB),
- DUMP_WED(WED_RTQM_PFDBK_MIB),
- };
-+ static const struct reg_dump regs_wed_v3[] = {
-+ DUMP_STR("WED RX RRO DATA"),
-+ DUMP_WED_RING(WED_RRO_RX_D_RX(0)),
-+ DUMP_WED_RING(WED_RRO_RX_D_RX(1)),
-+
-+ DUMP_STR("WED RX MSDU PAGE"),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)),
-+
-+ DUMP_STR("WED RX IND CMD"),
-+ DUMP_WED(WED_IND_CMD_RX_CTRL1),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
-+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT),
-+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
-+ WED_IND_CMD_PREFETCH_FREE_CNT),
-+ DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID),
-+
-+ DUMP_STR("WED ADDR ELEM"),
-+ DUMP_WED(WED_ADDR_ELEM_CFG0),
-+ DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
-+ WED_ADDR_ELEM_PREFETCH_FREE_CNT),
-+
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_ERR_CNT),
-+
-+ DUMP_WED(WED_RTQM_DEQ_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_PKT_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_ERR_CNT),
-+ };
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
- if (dev) {
- dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common));
-- dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
-+ if (mtk_wed_is_v2(hw))
-+ dump_wed_regs(s, dev,
-+ regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
-+ else
-+ dump_wed_regs(s, dev,
-+ regs_wed_v3, ARRAY_SIZE(regs_wed_v3));
- }
-
- return 0;
-@@ -225,6 +275,314 @@ wed_rxinfo_show(struct seq_file *s, void
- DEFINE_SHOW_ATTRIBUTE(wed_rxinfo);
-
- static int
-+wed_amsdu_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("WED AMDSU INFO"),
-+ DUMP_WED(WED_MON_AMSDU_FIFO_DMAD),
-+
-+ DUMP_STR("WED AMDSU ENG0 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(0)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG1 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(1)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG2 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(2)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG3 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(3)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG4 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(4)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG5 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(5)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG6 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(6)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG7 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(7)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG8 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(8)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED QMEM INFO"),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_FQ_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_SP_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID0_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID1_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID2_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID3_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID4_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID5_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID6_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID7_QCNT),
-+
-+ DUMP_STR("WED QMEM HEAD INFO"),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_FQ_HEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_SP_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID0_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID1_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID2_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID3_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID4_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID5_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID6_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID7_QHEAD),
-+
-+ DUMP_STR("WED QMEM TAIL INFO"),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_FQ_TAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_SP_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID0_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID1_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID2_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID3_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID4_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID5_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID6_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID7_QTAIL),
-+
-+ DUMP_STR("WED HIFTXD MSDU INFO"),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(1)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(2)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(3)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(4)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(5)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(6)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(7)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(8)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(9)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(10)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(11)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(12)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(13)),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_amsdu);
-+
-+static int
-+wed_rtqm_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"),
-+ DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS1(Legacy)"),
-+ DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS2(RRO3.0)"),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS3(DEBUG)"),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rtqm);
-+
-+static int
-+wed_rro_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("RRO/IND CMD CNT"),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(1)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(2)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(3)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(4)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(5)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(6)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(7)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(8)),
-+ DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9),
-+ WED_IND_CMD_MAGIC_CNT_FAIL_CNT),
-+
-+ DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)),
-+ DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1),
-+ WED_ADDR_ELEM_SIG_FAIL_CNT),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(1)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(2)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(3)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(4)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(5)),
-+ DUMP_WED_MASK(WED_RX_PN_CHK_CNT,
-+ WED_PN_CHK_FAIL_CNT),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rro);
-+
-+static int
- mtk_wed_reg_set(void *data, u64 val)
- {
- struct mtk_wed_hw *hw = data;
-@@ -266,7 +624,16 @@ void mtk_wed_hw_add_debugfs(struct mtk_w
- debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
- debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
- debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-- if (!mtk_wed_is_v1(hw))
-+ if (!mtk_wed_is_v1(hw)) {
- debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
- &wed_rxinfo_fops);
-+ if (mtk_wed_is_v3_or_greater(hw)) {
-+ debugfs_create_file_unsafe("amsdu", 0400, dir, hw,
-+ &wed_amsdu_fops);
-+ debugfs_create_file_unsafe("rtqm", 0400, dir, hw,
-+ &wed_rtqm_fops);
-+ debugfs_create_file_unsafe("rro", 0400, dir, hw,
-+ &wed_rro_fops);
-+ }
-+ }
- }
diff --git a/target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch b/target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch
deleted file mode 100644
index aaaabf05e8..0000000000
--- a/target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch
+++ /dev/null
@@ -1,587 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:19 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: add wed 3.0 reset support
-
-Introduce support for resetting Wireless Ethernet Dispatcher 3.0
-available on MT988 SoC.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -148,6 +148,90 @@ mtk_wdma_read_reset(struct mtk_wed_devic
- return wdma_r32(dev, MTK_WDMA_GLO_CFG);
- }
-
-+static void
-+mtk_wdma_v3_rx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status;
-+
-+ if (!mtk_wed_is_v3_or_greater(dev->hw))
-+ return;
-+
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ /* prefetch FIFO */
-+ wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
-+
-+ /* core FIFO */
-+ wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG,
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG,
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
-+
-+ /* writeback FIFO */
-+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+
-+ /* prefetch ring status */
-+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
-+
-+ /* writeback ring status */
-+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
-+}
-+
- static int
- mtk_wdma_rx_reset(struct mtk_wed_device *dev)
- {
-@@ -160,6 +244,7 @@ mtk_wdma_rx_reset(struct mtk_wed_device
- if (ret)
- dev_err(dev->hw->dev, "rx reset failed\n");
-
-+ mtk_wdma_v3_rx_reset(dev);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-@@ -192,6 +277,84 @@ mtk_wed_poll_busy(struct mtk_wed_device
- }
-
- static void
-+mtk_wdma_v3_tx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status;
-+
-+ if (!mtk_wed_is_v3_or_greater(dev->hw))
-+ return;
-+
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ /* prefetch FIFO */
-+ wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
-+
-+ /* core FIFO */
-+ wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG,
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG,
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
-+
-+ /* writeback FIFO */
-+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+
-+ /* prefetch ring status */
-+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
-+
-+ /* writeback ring status */
-+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
-+}
-+
-+static void
- mtk_wdma_tx_reset(struct mtk_wed_device *dev)
- {
- u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
-@@ -202,6 +365,7 @@ mtk_wdma_tx_reset(struct mtk_wed_device
- !(status & mask), 0, 10000))
- dev_err(dev->hw->dev, "tx reset failed\n");
-
-+ mtk_wdma_v3_tx_reset(dev);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-@@ -1405,13 +1569,33 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- if (ret)
- return ret;
-
-+ if (dev->wlan.hw_rro) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS,
-+ MTK_WED_RX_IND_CMD_BUSY);
-+ mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG);
-+ }
-+
- wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
- MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
-+ if (!ret && mtk_wed_is_v3_or_greater(dev->hw))
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_BUSY);
- if (ret) {
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
- } else {
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* 1.a. disable prefetch HW */
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_BUSY);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL);
-+ }
-+
- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
- MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
- MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-@@ -1439,23 +1623,52 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
- }
-
-+ if (dev->wlan.hw_rro) {
-+ /* disable rro msdu page drv */
-+ wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_EN);
-+
-+ /* disable rro data drv */
-+ wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
-+
-+ /* rro msdu page drv reset */
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+
-+ /* rro data drv reset */
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2),
-+ MTK_WED_RRO_RX_D_DRV_CLR);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2),
-+ MTK_WED_RRO_RX_D_DRV_CLR);
-+ }
-+
- /* reset route qm */
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
- ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
-- if (ret)
-+ if (ret) {
- mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
-- else
-- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-- MTK_WED_RTQM_Q_RST);
-+ } else if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_RTQM_RST, BIT(0));
-+ wed_clr(dev, MTK_WED_RTQM_RST, BIT(0));
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
-+ } else {
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ }
-
- /* reset tx wdma */
- mtk_wdma_tx_reset(dev);
-
- /* reset tx wdma drv */
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
-- mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS,
-+ MTK_WED_WPDMA_STATUS_TX_DRV);
-+ else
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
-
- /* reset wed rx dma */
-@@ -1476,6 +1689,14 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- MTK_WED_CTRL_WED_RX_BM_BUSY);
- mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
-
-+ if (dev->wlan.hw_rro) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_RX_PG_BM_BUSY);
-+ wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
-+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
-+ }
-+
- /* wo change to enable state */
- val = MTK_WED_WO_STATE_ENABLE;
- ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-@@ -1493,6 +1714,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- false);
- }
- mtk_wed_free_rx_buffer(dev);
-+ mtk_wed_hwrro_free_buffer(dev);
-
- return 0;
- }
-@@ -1526,15 +1748,41 @@ mtk_wed_reset_dma(struct mtk_wed_device
-
- /* 2. reset WDMA rx DMA */
- busy = !!mtk_wdma_rx_reset(dev);
-- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ val = MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE |
-+ wed_r32(dev, MTK_WED_WDMA_GLO_CFG);
-+ val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN;
-+ wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val);
-+ } else {
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ }
-+
- if (!busy)
- busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
-+ if (!busy && mtk_wed_is_v3_or_greater(dev->hw))
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_BUSY);
-
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
- } else {
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* 1.a. disable prefetch HW */
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_BUSY);
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
-+
-+ /* 2. Reset dma index */
-+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
-+ MTK_WED_WDMA_RESET_IDX_RX_ALL);
-+ }
-+
- wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
- MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV);
- wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0);
-@@ -1550,8 +1798,13 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
- for (i = 0; i < 100; i++) {
-- val = wed_r32(dev, MTK_WED_TX_BM_INTF);
-- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
-+ if (mtk_wed_is_v1(dev->hw))
-+ val = FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP,
-+ wed_r32(dev, MTK_WED_TX_BM_INTF));
-+ else
-+ val = FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP,
-+ wed_r32(dev, MTK_WED_TX_TKID_INTF));
-+ if (val == 0x40)
- break;
- }
-
-@@ -1573,6 +1826,8 @@ mtk_wed_reset_dma(struct mtk_wed_device
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV);
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ wed_w32(dev, MTK_WED_RX1_CTRL2, 0);
- } else {
- wed_w32(dev, MTK_WED_WPDMA_RESET_IDX,
- MTK_WED_WPDMA_RESET_IDX_TX |
-@@ -1589,7 +1844,14 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-- mtk_wed_rx_reset(dev);
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* reset amsdu engine */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
-+ mtk_wed_reset(dev, MTK_WED_RESET_TX_AMSDU);
-+ }
-+
-+ if (mtk_wed_get_rx_capa(dev))
-+ mtk_wed_rx_reset(dev);
- }
-
- static int
-@@ -1841,6 +2103,7 @@ mtk_wed_dma_enable(struct mtk_wed_device
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
-
- wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
- }
-
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-@@ -1904,6 +2167,12 @@ mtk_wed_start_hw_rro(struct mtk_wed_devi
- if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
- return;
-
-+ if (reset) {
-+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_EN);
-+ return;
-+ }
-+
- wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
- wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
- MTK_WED_RRO_MSDU_PG_DRV_CLR);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -28,6 +28,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET 0x008
- #define MTK_WED_RESET_TX_BM BIT(0)
- #define MTK_WED_RESET_RX_BM BIT(1)
-+#define MTK_WED_RESET_RX_PG_BM BIT(2)
-+#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3)
- #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
- #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
- #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
-@@ -106,6 +108,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-
-+#define MTK_WED_WPDMA_STATUS 0x068
-+#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8)
-+
- #define MTK_WED_TX_BM_CTRL 0x080
- #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
- #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-@@ -140,6 +145,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16)
- #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
-
-+#define MTK_WED_TX_TKID_INTF 0x0dc
-+#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16)
-+
- #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0)
- #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16)
-
-@@ -190,6 +198,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
-
- #define MTK_WED_SCR0 0x3c0
-+#define MTK_WED_RX1_CTRL2 0x418
- #define MTK_WED_WPDMA_INT_TRIGGER 0x504
- #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
- #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
-@@ -303,6 +312,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
- #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
-+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20)
- #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-
- #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
-@@ -313,6 +323,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
- #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1)
- #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
- #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
-
-@@ -334,11 +345,13 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WDMA_RX_PREF_CFG 0x950
- #define MTK_WED_WDMA_RX_PREF_EN BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1)
- #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
- #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
- #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
- #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
- #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
-+#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27)
-
- #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
- #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
-@@ -367,6 +380,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WDMA_RESET_IDX 0xa08
- #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
-+#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20)
- #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
-
- #define MTK_WED_WDMA_INT_CLR 0xa24
-@@ -437,21 +451,62 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30)
- #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31)
-
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12)
-+
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21)
-+
- #define MTK_WDMA_INT_GRP1 0x250
- #define MTK_WDMA_INT_GRP2 0x254
-
- #define MTK_WDMA_PREF_TX_CFG 0x2d0
- #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
-+#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1)
-
- #define MTK_WDMA_PREF_RX_CFG 0x2dc
- #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
-+#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1)
-+
-+#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0
-+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0)
-+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16)
-+
-+#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4
-+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0)
-+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16)
-+
-+#define MTK_WDMA_PREF_SIDX_CFG 0x2e4
-+#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
-+#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
-
- #define MTK_WDMA_WRBK_TX_CFG 0x300
-+#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0)
- #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
-
-+#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4)
-+#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0)
-+
- #define MTK_WDMA_WRBK_RX_CFG 0x344
-+#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0)
- #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
-
-+#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4)
-+#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0)
-+
-+#define MTK_WDMA_WRBK_SIDX_CFG 0x388
-+#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
-+#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
-+
- #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
- #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
- #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
-@@ -465,6 +520,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
- #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-
-+#define MTK_WED_RTQM_RST 0xb04
-+
- #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
- #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
- #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
-@@ -653,6 +710,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
- #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
-
-+#define MTK_WED_RRO_RX_HW_STS 0xf00
-+#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0)
-+
- #define MTK_WED_RX_IND_CMD_CNT0 0xf20
- #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
-
diff --git a/target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch b/target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch
deleted file mode 100644
index df9518d86c..0000000000
--- a/target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 3b00a07c2443745d62babfe08dbb2ad8e649526e Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 19 Nov 2021 03:03:49 +0100
-Subject: [PATCH] net: dsa: qca8k: fix internal delay applied to the wrong PAD
- config
-
-With SGMII phy the internal delay is always applied to the PAD0 config.
-This is caused by the falling edge configuration that hardcode the reg
-to PAD0 (as the falling edge bits are present only in PAD0 reg)
-Move the delay configuration before the reg overwrite to correctly apply
-the delay.
-
-Fixes: cef08115846e ("net: dsa: qca8k: set internal delay also for sgmii")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1433,6 +1433,12 @@ qca8k_phylink_mac_config(struct dsa_swit
-
- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
-
-+ /* From original code is reported port instability as SGMII also
-+ * require delay set. Apply advised values here or take them from DT.
-+ */
-+ if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-+
- /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
- * falling edge is set writing in the PORT0 PAD reg
- */
-@@ -1455,12 +1461,6 @@ qca8k_phylink_mac_config(struct dsa_swit
- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
- val);
-
-- /* From original code is reported port instability as SGMII also
-- * require delay set. Apply advised values here or take them from DT.
-- */
-- if (state->interface == PHY_INTERFACE_MODE_SGMII)
-- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
--
- break;
- default:
- dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
diff --git a/target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch b/target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch
deleted file mode 100644
index 7348d93ec4..0000000000
--- a/target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 65258b9d8cde45689bdc86ca39b50f01f983733b Mon Sep 17 00:00:00 2001
-From: Robert Marko <robert.marko@sartura.hr>
-Date: Fri, 19 Nov 2021 03:03:50 +0100
-Subject: [PATCH] net: dsa: qca8k: fix MTU calculation
-
-qca8k has a global MTU, so its tracking the MTU per port to make sure
-that the largest MTU gets applied.
-Since it uses the frame size instead of MTU the driver MTU change function
-will then add the size of Ethernet header and checksum on top of MTU.
-
-The driver currently populates the per port MTU size as Ethernet frame
-length + checksum which equals 1518.
-
-The issue is that then MTU change function will go through all of the
-ports, find the largest MTU and apply the Ethernet header + checksum on
-top of it again, so for a desired MTU of 1500 you will end up with 1536.
-
-This is obviously incorrect, so to correct it populate the per port struct
-MTU with just the MTU and not include the Ethernet header + checksum size
-as those will be added by the MTU change function.
-
-Fixes: f58d2598cf70 ("net: dsa: qca8k: implement the port MTU callbacks")
-Signed-off-by: Robert Marko <robert.marko@sartura.hr>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1256,8 +1256,12 @@ qca8k_setup(struct dsa_switch *ds)
- /* Set initial MTU for every port.
- * We have only have a general MTU setting. So track
- * every port and set the max across all port.
-+ * Set per port MTU to 1500 as the MTU change function
-+ * will add the overhead and if its set to 1518 then it
-+ * will apply the overhead again and we will end up with
-+ * MTU of 1536 instead of 1518
- */
-- priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
-+ priv->port_mtu[i] = ETH_DATA_LEN;
- }
-
- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
diff --git a/target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch b/target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch
deleted file mode 100644
index f477b1b929..0000000000
--- a/target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From b9133f3ef5a2659730cf47a74bd0a9259f1cf8ff Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:40 +0100
-Subject: net: dsa: qca8k: remove redundant check in parse_port_config
-
-The very next check for port 0 and 6 already makes sure we don't go out
-of bounds with the ports_config delay table.
-Remove the redundant check.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -983,7 +983,7 @@ qca8k_parse_port_config(struct qca8k_pri
- u32 delay;
-
- /* We have 2 CPU port. Check them */
-- for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) {
-+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
- /* Skip every other port */
- if (port != 0 && port != 6)
- continue;
diff --git a/target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch b/target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch
deleted file mode 100644
index 2cea88089d..0000000000
--- a/target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch
+++ /dev/null
@@ -1,507 +0,0 @@
-From 90ae68bfc2ffcb54a4ba4f64edbeb84a80cbb57c Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:41 +0100
-Subject: net: dsa: qca8k: convert to GENMASK/FIELD_PREP/FIELD_GET
-
-Convert and try to standardize bit fields using
-GENMASK/FIELD_PREP/FIELD_GET macros. Rework some logic to support the
-standard macro and tidy things up. No functional change intended.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 98 +++++++++++++++----------------
- drivers/net/dsa/qca8k.h | 153 ++++++++++++++++++++++++++----------------------
- 2 files changed, 130 insertions(+), 121 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -9,6 +9,7 @@
- #include <linux/module.h>
- #include <linux/phy.h>
- #include <linux/netdevice.h>
-+#include <linux/bitfield.h>
- #include <net/dsa.h>
- #include <linux/of_net.h>
- #include <linux/of_mdio.h>
-@@ -319,18 +320,18 @@ qca8k_fdb_read(struct qca8k_priv *priv,
- }
-
- /* vid - 83:72 */
-- fdb->vid = (reg[2] >> QCA8K_ATU_VID_S) & QCA8K_ATU_VID_M;
-+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
- /* aging - 67:64 */
-- fdb->aging = reg[2] & QCA8K_ATU_STATUS_M;
-+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
- /* portmask - 54:48 */
-- fdb->port_mask = (reg[1] >> QCA8K_ATU_PORT_S) & QCA8K_ATU_PORT_M;
-+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
- /* mac - 47:0 */
-- fdb->mac[0] = (reg[1] >> QCA8K_ATU_ADDR0_S) & 0xff;
-- fdb->mac[1] = reg[1] & 0xff;
-- fdb->mac[2] = (reg[0] >> QCA8K_ATU_ADDR2_S) & 0xff;
-- fdb->mac[3] = (reg[0] >> QCA8K_ATU_ADDR3_S) & 0xff;
-- fdb->mac[4] = (reg[0] >> QCA8K_ATU_ADDR4_S) & 0xff;
-- fdb->mac[5] = reg[0] & 0xff;
-+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
-+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
-+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
-+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
-+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
-+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
-
- return 0;
- }
-@@ -343,18 +344,18 @@ qca8k_fdb_write(struct qca8k_priv *priv,
- int i;
-
- /* vid - 83:72 */
-- reg[2] = (vid & QCA8K_ATU_VID_M) << QCA8K_ATU_VID_S;
-+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
- /* aging - 67:64 */
-- reg[2] |= aging & QCA8K_ATU_STATUS_M;
-+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
- /* portmask - 54:48 */
-- reg[1] = (port_mask & QCA8K_ATU_PORT_M) << QCA8K_ATU_PORT_S;
-+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
- /* mac - 47:0 */
-- reg[1] |= mac[0] << QCA8K_ATU_ADDR0_S;
-- reg[1] |= mac[1];
-- reg[0] |= mac[2] << QCA8K_ATU_ADDR2_S;
-- reg[0] |= mac[3] << QCA8K_ATU_ADDR3_S;
-- reg[0] |= mac[4] << QCA8K_ATU_ADDR4_S;
-- reg[0] |= mac[5];
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
-
- /* load the array into the ARL table */
- for (i = 0; i < 3; i++)
-@@ -372,7 +373,7 @@ qca8k_fdb_access(struct qca8k_priv *priv
- reg |= cmd;
- if (port >= 0) {
- reg |= QCA8K_ATU_FUNC_PORT_EN;
-- reg |= (port & QCA8K_ATU_FUNC_PORT_M) << QCA8K_ATU_FUNC_PORT_S;
-+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
- }
-
- /* Write the function register triggering the table access */
-@@ -454,7 +455,7 @@ qca8k_vlan_access(struct qca8k_priv *pri
- /* Set the command and VLAN index */
- reg = QCA8K_VTU_FUNC1_BUSY;
- reg |= cmd;
-- reg |= vid << QCA8K_VTU_FUNC1_VID_S;
-+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
-
- /* Write the function register triggering the table access */
- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-@@ -500,13 +501,11 @@ qca8k_vlan_add(struct qca8k_priv *priv,
- if (ret < 0)
- goto out;
- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-- reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
- if (untagged)
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
-- QCA8K_VTU_FUNC0_EG_MODE_S(port);
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
- else
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
-- QCA8K_VTU_FUNC0_EG_MODE_S(port);
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
-
- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
- if (ret)
-@@ -534,15 +533,13 @@ qca8k_vlan_del(struct qca8k_priv *priv,
- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
- if (ret < 0)
- goto out;
-- reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
-- QCA8K_VTU_FUNC0_EG_MODE_S(port);
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
-
- /* Check if we're the last member to be removed */
- del = true;
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- mask = QCA8K_VTU_FUNC0_EG_MODE_NOT;
-- mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i);
-+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
-
- if ((reg & mask) != mask) {
- del = false;
-@@ -1014,7 +1011,7 @@ qca8k_parse_port_config(struct qca8k_pri
- mode == PHY_INTERFACE_MODE_RGMII_TXID)
- delay = 1;
-
-- if (delay > QCA8K_MAX_DELAY) {
-+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) {
- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
- delay = 3;
- }
-@@ -1030,7 +1027,7 @@ qca8k_parse_port_config(struct qca8k_pri
- mode == PHY_INTERFACE_MODE_RGMII_RXID)
- delay = 2;
-
-- if (delay > QCA8K_MAX_DELAY) {
-+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) {
- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
- delay = 3;
- }
-@@ -1141,8 +1138,8 @@ qca8k_setup(struct dsa_switch *ds)
- /* Enable QCA header mode on all cpu ports */
- if (dsa_is_cpu_port(ds, i)) {
- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
-- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
- if (ret) {
- dev_err(priv->dev, "failed enabling QCA header mode");
- return ret;
-@@ -1159,10 +1156,10 @@ qca8k_setup(struct dsa_switch *ds)
- * for igmp, unknown, multicast and broadcast packet
- */
- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
-- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
-- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
-- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
- if (ret)
- return ret;
-
-@@ -1180,8 +1177,6 @@ qca8k_setup(struct dsa_switch *ds)
-
- /* Individual user ports get connected to CPU port only */
- if (dsa_is_user_port(ds, i)) {
-- int shift = 16 * (i % 2);
--
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
- QCA8K_PORT_LOOKUP_MEMBER,
- BIT(cpu_port));
-@@ -1198,8 +1193,8 @@ qca8k_setup(struct dsa_switch *ds)
- * default egress vid
- */
- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-- 0xfff << shift,
-- QCA8K_PORT_VID_DEF << shift);
-+ QCA8K_EGREES_VLAN_PORT_MASK(i),
-+ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF));
- if (ret)
- return ret;
-
-@@ -1246,7 +1241,7 @@ qca8k_setup(struct dsa_switch *ds)
- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
- QCA8K_PORT_HOL_CTRL1_WRED_EN;
- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
-- QCA8K_PORT_HOL_CTRL1_ING_BUF |
-+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
- QCA8K_PORT_HOL_CTRL1_WRED_EN,
-@@ -1269,8 +1264,8 @@ qca8k_setup(struct dsa_switch *ds)
- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
- QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
- qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
-- QCA8K_GLOBAL_FC_GOL_XON_THRES_S |
-- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S,
-+ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK |
-+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK,
- mask);
- }
-
-@@ -1935,11 +1930,11 @@ qca8k_port_vlan_filtering(struct dsa_swi
-
- if (vlan_filtering) {
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
- } else {
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
- }
-
-@@ -1963,10 +1958,9 @@ qca8k_port_vlan_add(struct dsa_switch *d
- }
-
- if (pvid) {
-- int shift = 16 * (port % 2);
--
- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-- 0xfff << shift, vlan->vid << shift);
-+ QCA8K_EGREES_VLAN_PORT_MASK(port),
-+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
- if (ret)
- return ret;
-
-@@ -2060,7 +2054,7 @@ static int qca8k_read_switch_id(struct q
- if (ret < 0)
- return -ENODEV;
-
-- id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK);
-+ id = QCA8K_MASK_CTRL_DEVICE_ID(val);
- if (id != data->id) {
- dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id);
- return -ENODEV;
-@@ -2069,7 +2063,7 @@ static int qca8k_read_switch_id(struct q
- priv->switch_id = id;
-
- /* Save revision to communicate to the internal PHY driver */
-- priv->switch_revision = (val & QCA8K_MASK_CTRL_REV_ID_MASK);
-+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
-
- return 0;
- }
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -30,9 +30,9 @@
- /* Global control registers */
- #define QCA8K_REG_MASK_CTRL 0x000
- #define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0)
--#define QCA8K_MASK_CTRL_REV_ID(x) ((x) >> 0)
-+#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x)
- #define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8)
--#define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8)
-+#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x)
- #define QCA8K_REG_PORT0_PAD_CTRL 0x004
- #define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31)
- #define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19)
-@@ -41,12 +41,11 @@
- #define QCA8K_REG_PORT6_PAD_CTRL 0x00c
- #define QCA8K_PORT_PAD_RGMII_EN BIT(26)
- #define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22)
--#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) ((x) << 22)
-+#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x)
- #define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20)
--#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) ((x) << 20)
-+#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x)
- #define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25)
- #define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
--#define QCA8K_MAX_DELAY 3
- #define QCA8K_PORT_PAD_SGMII_EN BIT(7)
- #define QCA8K_REG_PWS 0x010
- #define QCA8K_PWS_POWER_ON_SEL BIT(31)
-@@ -68,10 +67,12 @@
- #define QCA8K_MDIO_MASTER_READ BIT(27)
- #define QCA8K_MDIO_MASTER_WRITE 0
- #define QCA8K_MDIO_MASTER_SUP_PRE BIT(26)
--#define QCA8K_MDIO_MASTER_PHY_ADDR(x) ((x) << 21)
--#define QCA8K_MDIO_MASTER_REG_ADDR(x) ((x) << 16)
--#define QCA8K_MDIO_MASTER_DATA(x) (x)
-+#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21)
-+#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x)
-+#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16)
-+#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x)
- #define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0)
-+#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x)
- #define QCA8K_MDIO_MASTER_MAX_PORTS 5
- #define QCA8K_MDIO_MASTER_MAX_REG 32
- #define QCA8K_GOL_MAC_ADDR0 0x60
-@@ -93,9 +94,7 @@
- #define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12)
- #define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4))
- #define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2)
--#define QCA8K_PORT_HDR_CTRL_RX_S 2
- #define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0)
--#define QCA8K_PORT_HDR_CTRL_TX_S 0
- #define QCA8K_PORT_HDR_CTRL_ALL 2
- #define QCA8K_PORT_HDR_CTRL_MGMT 1
- #define QCA8K_PORT_HDR_CTRL_NONE 0
-@@ -105,10 +104,11 @@
- #define QCA8K_SGMII_EN_TX BIT(3)
- #define QCA8K_SGMII_EN_SD BIT(4)
- #define QCA8K_SGMII_CLK125M_DELAY BIT(7)
--#define QCA8K_SGMII_MODE_CTRL_MASK (BIT(22) | BIT(23))
--#define QCA8K_SGMII_MODE_CTRL_BASEX (0 << 22)
--#define QCA8K_SGMII_MODE_CTRL_PHY (1 << 22)
--#define QCA8K_SGMII_MODE_CTRL_MAC (2 << 22)
-+#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22)
-+#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x)
-+#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0)
-+#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1)
-+#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2)
-
- /* MAC_PWR_SEL registers */
- #define QCA8K_REG_MAC_PWR_SEL 0x0e4
-@@ -121,100 +121,115 @@
-
- /* ACL registers */
- #define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8))
--#define QCA8K_PORT_VLAN_CVID(x) (x << 16)
--#define QCA8K_PORT_VLAN_SVID(x) x
-+#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16)
-+#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x)
-+#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0)
-+#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x)
- #define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8))
- #define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470
- #define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474
-
- /* Lookup registers */
- #define QCA8K_REG_ATU_DATA0 0x600
--#define QCA8K_ATU_ADDR2_S 24
--#define QCA8K_ATU_ADDR3_S 16
--#define QCA8K_ATU_ADDR4_S 8
-+#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24)
-+#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16)
-+#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8)
-+#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0)
- #define QCA8K_REG_ATU_DATA1 0x604
--#define QCA8K_ATU_PORT_M 0x7f
--#define QCA8K_ATU_PORT_S 16
--#define QCA8K_ATU_ADDR0_S 8
-+#define QCA8K_ATU_PORT_MASK GENMASK(22, 16)
-+#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8)
-+#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0)
- #define QCA8K_REG_ATU_DATA2 0x608
--#define QCA8K_ATU_VID_M 0xfff
--#define QCA8K_ATU_VID_S 8
--#define QCA8K_ATU_STATUS_M 0xf
-+#define QCA8K_ATU_VID_MASK GENMASK(19, 8)
-+#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0)
- #define QCA8K_ATU_STATUS_STATIC 0xf
- #define QCA8K_REG_ATU_FUNC 0x60c
- #define QCA8K_ATU_FUNC_BUSY BIT(31)
- #define QCA8K_ATU_FUNC_PORT_EN BIT(14)
- #define QCA8K_ATU_FUNC_MULTI_EN BIT(13)
- #define QCA8K_ATU_FUNC_FULL BIT(12)
--#define QCA8K_ATU_FUNC_PORT_M 0xf
--#define QCA8K_ATU_FUNC_PORT_S 8
-+#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8)
- #define QCA8K_REG_VTU_FUNC0 0x610
- #define QCA8K_VTU_FUNC0_VALID BIT(20)
- #define QCA8K_VTU_FUNC0_IVL_EN BIT(19)
--#define QCA8K_VTU_FUNC0_EG_MODE_S(_i) (4 + (_i) * 2)
--#define QCA8K_VTU_FUNC0_EG_MODE_MASK 3
--#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD 0
--#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG 1
--#define QCA8K_VTU_FUNC0_EG_MODE_TAG 2
--#define QCA8K_VTU_FUNC0_EG_MODE_NOT 3
-+/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4)
-+ * It does contain VLAN_MODE for each port [5:4] for port0,
-+ * [7:6] for port1 ... [17:16] for port6. Use virtual port
-+ * define to handle this.
-+ */
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2)
-+#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
- #define QCA8K_REG_VTU_FUNC1 0x614
- #define QCA8K_VTU_FUNC1_BUSY BIT(31)
--#define QCA8K_VTU_FUNC1_VID_S 16
-+#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16)
- #define QCA8K_VTU_FUNC1_FULL BIT(4)
- #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620
- #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
- #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624
--#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S 24
--#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_S 16
--#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_S 8
--#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_S 0
-+#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24)
-+#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16)
-+#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8)
-+#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0)
- #define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc)
- #define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE GENMASK(9, 8)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE (0 << 8)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK (1 << 8)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK (2 << 8)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE (3 << 8)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3)
- #define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16)
--#define QCA8K_PORT_LOOKUP_STATE_DISABLED (0 << 16)
--#define QCA8K_PORT_LOOKUP_STATE_BLOCKING (1 << 16)
--#define QCA8K_PORT_LOOKUP_STATE_LISTENING (2 << 16)
--#define QCA8K_PORT_LOOKUP_STATE_LEARNING (3 << 16)
--#define QCA8K_PORT_LOOKUP_STATE_FORWARD (4 << 16)
--#define QCA8K_PORT_LOOKUP_STATE GENMASK(18, 16)
-+#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x)
-+#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0)
-+#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1)
-+#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2)
-+#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3)
-+#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4)
- #define QCA8K_PORT_LOOKUP_LEARN BIT(20)
-
- #define QCA8K_REG_GLOBAL_FC_THRESH 0x800
--#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) ((x) << 16)
--#define QCA8K_GLOBAL_FC_GOL_XON_THRES_S GENMASK(24, 16)
--#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) ((x) << 0)
--#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S GENMASK(8, 0)
-+#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16)
-+#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x)
-+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0)
-+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x)
-
- #define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF GENMASK(3, 0)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) ((x) << 0)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF GENMASK(7, 4)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) ((x) << 4)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF GENMASK(11, 8)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) ((x) << 8)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF GENMASK(15, 12)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) ((x) << 12)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF GENMASK(19, 16)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) ((x) << 16)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF GENMASK(23, 20)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) ((x) << 20)
--#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF GENMASK(29, 24)
--#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) ((x) << 24)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x)
-
- #define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8)
--#define QCA8K_PORT_HOL_CTRL1_ING_BUF GENMASK(3, 0)
--#define QCA8K_PORT_HOL_CTRL1_ING(x) ((x) << 0)
-+#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0)
-+#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x)
- #define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6)
- #define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7)
- #define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8)
- #define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16)
-
- /* Pkt edit registers */
-+#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2))
-+#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i))
-+#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i))
- #define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2)))
-
- /* L3 registers */
diff --git a/target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch b/target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch
deleted file mode 100644
index 8c39b8ea29..0000000000
--- a/target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 994c28b6f971fa5db8ae977daea37eee87d93d51 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:42 +0100
-Subject: net: dsa: qca8k: remove extra mutex_init in qca8k_setup
-
-Mutex is already init in sw_probe. Remove the extra init in qca8k_setup.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1086,8 +1086,6 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-- mutex_init(&priv->reg_mutex);
--
- /* Start by setting up the register mapping */
- priv->regmap = devm_regmap_init(ds->dev, NULL, priv,
- &qca8k_regmap_config);
diff --git a/target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch b/target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch
deleted file mode 100644
index 44d938c53e..0000000000
--- a/target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 36b8af12f424e7a7f60a935c60a0fd4aa0822378 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:43 +0100
-Subject: net: dsa: qca8k: move regmap init in probe and set it mandatory
-
-In preparation for regmap conversion, move regmap init in the probe
-function and make it mandatory as any read/write/rmw operation will be
-converted to regmap API.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1086,12 +1086,6 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-- /* Start by setting up the register mapping */
-- priv->regmap = devm_regmap_init(ds->dev, NULL, priv,
-- &qca8k_regmap_config);
-- if (IS_ERR(priv->regmap))
-- dev_warn(priv->dev, "regmap initialization failed");
--
- ret = qca8k_setup_mdio_bus(priv);
- if (ret)
- return ret;
-@@ -2096,6 +2090,14 @@ qca8k_sw_probe(struct mdio_device *mdiod
- gpiod_set_value_cansleep(priv->reset_gpio, 0);
- }
-
-+ /* Start by setting up the register mapping */
-+ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv,
-+ &qca8k_regmap_config);
-+ if (IS_ERR(priv->regmap)) {
-+ dev_err(priv->dev, "regmap initialization failed");
-+ return PTR_ERR(priv->regmap);
-+ }
-+
- /* Check the detected switch id */
- ret = qca8k_read_switch_id(priv);
- if (ret)
diff --git a/target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch b/target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch
deleted file mode 100644
index 4ca9c8ba41..0000000000
--- a/target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From 8b5f3f29a81a71934d004e21a1292c1148b05926 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:44 +0100
-Subject: net: dsa: qca8k: initial conversion to regmap helper
-
-Convert any qca8k set/clear/pool to regmap helper and add
-missing config to regmap_config struct.
-Read/write/rmw operation are reworked to use the regmap helper
-internally to keep the delta of this patch low. These additional
-function will then be dropped when the code split will be proposed.
-
-Ipq40xx SoC have the internal switch based on the qca8k regmap but use
-mmio for read/write/rmw operation instead of mdio.
-In preparation for the support of this internal switch, convert the
-driver to regmap API to later split the driver to common and specific
-code. The overhead introduced by the use of regamp API is marginal as the
-internal mdio will bypass it by using its direct access and regmap will be
-used only by configuration functions or fdb access.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 107 +++++++++++++++++++++---------------------------
- 1 file changed, 47 insertions(+), 60 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -10,6 +10,7 @@
- #include <linux/phy.h>
- #include <linux/netdevice.h>
- #include <linux/bitfield.h>
-+#include <linux/regmap.h>
- #include <net/dsa.h>
- #include <linux/of_net.h>
- #include <linux/of_mdio.h>
-@@ -152,6 +153,25 @@ qca8k_set_page(struct mii_bus *bus, u16
- static int
- qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
- {
-+ return regmap_read(priv->regmap, reg, val);
-+}
-+
-+static int
-+qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
-+{
-+ return regmap_write(priv->regmap, reg, val);
-+}
-+
-+static int
-+qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+{
-+ return regmap_update_bits(priv->regmap, reg, mask, write_val);
-+}
-+
-+static int
-+qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
- struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- int ret;
-@@ -172,8 +192,9 @@ exit:
- }
-
- static int
--qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
-+qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
- {
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
- struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- int ret;
-@@ -194,8 +215,9 @@ exit:
- }
-
- static int
--qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
- {
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
- struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- u32 val;
-@@ -223,34 +245,6 @@ exit:
- return ret;
- }
-
--static int
--qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val)
--{
-- return qca8k_rmw(priv, reg, 0, val);
--}
--
--static int
--qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val)
--{
-- return qca8k_rmw(priv, reg, val, 0);
--}
--
--static int
--qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
--
-- return qca8k_read(priv, reg, val);
--}
--
--static int
--qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
--
-- return qca8k_write(priv, reg, val);
--}
--
- static const struct regmap_range qca8k_readable_ranges[] = {
- regmap_reg_range(0x0000, 0x00e4), /* Global control */
- regmap_reg_range(0x0100, 0x0168), /* EEE control */
-@@ -282,26 +276,19 @@ static struct regmap_config qca8k_regmap
- .max_register = 0x16ac, /* end MIB - Port6 range */
- .reg_read = qca8k_regmap_read,
- .reg_write = qca8k_regmap_write,
-+ .reg_update_bits = qca8k_regmap_update_bits,
- .rd_table = &qca8k_readable_table,
-+ .disable_locking = true, /* Locking is handled by qca8k read/write */
-+ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
- };
-
- static int
- qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
- {
-- int ret, ret1;
- u32 val;
-
-- ret = read_poll_timeout(qca8k_read, ret1, !(val & mask),
-- 0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-- priv, reg, &val);
--
-- /* Check if qca8k_read has failed for a different reason
-- * before returning -ETIMEDOUT
-- */
-- if (ret < 0 && ret1 < 0)
-- return ret1;
--
-- return ret;
-+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
- }
-
- static int
-@@ -568,7 +555,7 @@ qca8k_mib_init(struct qca8k_priv *priv)
- int ret;
-
- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
- if (ret)
- goto exit;
-
-@@ -576,7 +563,7 @@ qca8k_mib_init(struct qca8k_priv *priv)
- if (ret)
- goto exit;
-
-- ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
- if (ret)
- goto exit;
-
-@@ -597,9 +584,9 @@ qca8k_port_set_status(struct qca8k_priv
- mask |= QCA8K_PORT_STATUS_LINK_AUTO;
-
- if (enable)
-- qca8k_reg_set(priv, QCA8K_REG_PORT_STATUS(port), mask);
-+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
- else
-- qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask);
-+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
- }
-
- static u32
-@@ -861,8 +848,8 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
- * a dt-overlay and driver reload changed the configuration
- */
-
-- return qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
-- QCA8K_MDIO_MASTER_EN);
-+ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL,
-+ QCA8K_MDIO_MASTER_EN);
- }
-
- /* Check if the devicetree declare the port:phy mapping */
-@@ -1099,16 +1086,16 @@ qca8k_setup(struct dsa_switch *ds)
- return ret;
-
- /* Make sure MAC06 is disabled */
-- ret = qca8k_reg_clear(priv, QCA8K_REG_PORT0_PAD_CTRL,
-- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
-+ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
-+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
- if (ret) {
- dev_err(priv->dev, "failed disabling MAC06 exchange");
- return ret;
- }
-
- /* Enable CPU Port */
-- ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
- if (ret) {
- dev_err(priv->dev, "failed enabling CPU port");
- return ret;
-@@ -1176,8 +1163,8 @@ qca8k_setup(struct dsa_switch *ds)
- return ret;
-
- /* Enable ARP Auto-learning by default */
-- ret = qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_LEARN);
-+ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_LEARN);
- if (ret)
- return ret;
-
-@@ -1745,9 +1732,9 @@ qca8k_port_bridge_join(struct dsa_switch
- /* Add this port to the portvlan mask of the other ports
- * in the bridge
- */
-- ret = qca8k_reg_set(priv,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-+ ret = regmap_set_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
- if (ret)
- return ret;
- if (i != port)
-@@ -1777,9 +1764,9 @@ qca8k_port_bridge_leave(struct dsa_switc
- /* Remove this port to the portvlan mask of the other ports
- * in the bridge
- */
-- qca8k_reg_clear(priv,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-+ regmap_clear_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
- }
-
- /* Set the cpu port to be the only one in the portvlan mask of
diff --git a/target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch b/target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch
deleted file mode 100644
index c8c050933b..0000000000
--- a/target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From c126f118b330ccf0db0dda4a4bd6c729865a205f Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:45 +0100
-Subject: net: dsa: qca8k: add additional MIB counter and make it dynamic
-
-We are currently missing 2 additionals MIB counter present in QCA833x
-switch.
-QC832x switch have 39 MIB counter and QCA833X have 41 MIB counter.
-Add the additional MIB counter and rework the MIB function to print the
-correct supported counter from the match_data struct.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 23 ++++++++++++++++++++---
- drivers/net/dsa/qca8k.h | 4 ++++
- 2 files changed, 24 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -70,6 +70,8 @@ static const struct qca8k_mib_desc ar832
- MIB_DESC(1, 0x9c, "TxExcDefer"),
- MIB_DESC(1, 0xa0, "TxDefer"),
- MIB_DESC(1, 0xa4, "TxLateCol"),
-+ MIB_DESC(1, 0xa8, "RXUnicast"),
-+ MIB_DESC(1, 0xac, "TXUnicast"),
- };
-
- /* The 32bit switch registers are accessed indirectly. To achieve this we need
-@@ -1605,12 +1607,16 @@ qca8k_phylink_mac_link_up(struct dsa_swi
- static void
- qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
- {
-+ const struct qca8k_match_data *match_data;
-+ struct qca8k_priv *priv = ds->priv;
- int i;
-
- if (stringset != ETH_SS_STATS)
- return;
-
-- for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++)
-+ match_data = of_device_get_match_data(priv->dev);
-+
-+ for (i = 0; i < match_data->mib_count; i++)
- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
- ETH_GSTRING_LEN);
- }
-@@ -1620,12 +1626,15 @@ qca8k_get_ethtool_stats(struct dsa_switc
- uint64_t *data)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ const struct qca8k_match_data *match_data;
- const struct qca8k_mib_desc *mib;
- u32 reg, i, val;
- u32 hi = 0;
- int ret;
-
-- for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-+ match_data = of_device_get_match_data(priv->dev);
-+
-+ for (i = 0; i < match_data->mib_count; i++) {
- mib = &ar8327_mib[i];
- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
-
-@@ -1648,10 +1657,15 @@ qca8k_get_ethtool_stats(struct dsa_switc
- static int
- qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
- {
-+ const struct qca8k_match_data *match_data;
-+ struct qca8k_priv *priv = ds->priv;
-+
- if (sset != ETH_SS_STATS)
- return 0;
-
-- return ARRAY_SIZE(ar8327_mib);
-+ match_data = of_device_get_match_data(priv->dev);
-+
-+ return match_data->mib_count;
- }
-
- static int
-@@ -2173,14 +2187,17 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
- static const struct qca8k_match_data qca8327 = {
- .id = QCA8K_ID_QCA8327,
- .reduced_package = true,
-+ .mib_count = QCA8K_QCA832X_MIB_COUNT,
- };
-
- static const struct qca8k_match_data qca8328 = {
- .id = QCA8K_ID_QCA8327,
-+ .mib_count = QCA8K_QCA832X_MIB_COUNT,
- };
-
- static const struct qca8k_match_data qca833x = {
- .id = QCA8K_ID_QCA8337,
-+ .mib_count = QCA8K_QCA833X_MIB_COUNT,
- };
-
- static const struct of_device_id qca8k_of_match[] = {
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -21,6 +21,9 @@
- #define PHY_ID_QCA8337 0x004dd036
- #define QCA8K_ID_QCA8337 0x13
-
-+#define QCA8K_QCA832X_MIB_COUNT 39
-+#define QCA8K_QCA833X_MIB_COUNT 41
-+
- #define QCA8K_BUSY_WAIT_TIMEOUT 2000
-
- #define QCA8K_NUM_FDB_RECORDS 2048
-@@ -279,6 +282,7 @@ struct ar8xxx_port_status {
- struct qca8k_match_data {
- u8 id;
- bool reduced_package;
-+ u8 mib_count;
- };
-
- enum {
diff --git a/target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch b/target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch
deleted file mode 100644
index 8ad7ab472d..0000000000
--- a/target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 4592538bfb0d5d3c3c8a1d7071724d081412ac91 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:46 +0100
-Subject: net: dsa: qca8k: add support for port fast aging
-
-The switch supports fast aging by flushing any rule in the ARL
-table for a specific port.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 11 +++++++++++
- drivers/net/dsa/qca8k.h | 1 +
- 2 files changed, 12 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1790,6 +1790,16 @@ qca8k_port_bridge_leave(struct dsa_switc
- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
- }
-
-+static void
-+qca8k_port_fast_age(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
- static int
- qca8k_port_enable(struct dsa_switch *ds, int port,
- struct phy_device *phy)
-@@ -2017,6 +2027,7 @@ static const struct dsa_switch_ops qca8k
- .port_stp_state_set = qca8k_port_stp_state_set,
- .port_bridge_join = qca8k_port_bridge_join,
- .port_bridge_leave = qca8k_port_bridge_leave,
-+ .port_fast_age = qca8k_port_fast_age,
- .port_fdb_add = qca8k_port_fdb_add,
- .port_fdb_del = qca8k_port_fdb_del,
- .port_fdb_dump = qca8k_port_fdb_dump,
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -262,6 +262,7 @@ enum qca8k_fdb_cmd {
- QCA8K_FDB_FLUSH = 1,
- QCA8K_FDB_LOAD = 2,
- QCA8K_FDB_PURGE = 3,
-+ QCA8K_FDB_FLUSH_PORT = 5,
- QCA8K_FDB_NEXT = 6,
- QCA8K_FDB_SEARCH = 7,
- };
diff --git a/target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch b/target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch
deleted file mode 100644
index 659e482405..0000000000
--- a/target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 6a3bdc5209f45d2af83aa92433ab6e5cf2297aa4 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:47 +0100
-Subject: net: dsa: qca8k: add set_ageing_time support
-
-qca8k support setting ageing time in step of 7s. Add support for it and
-set the max value accepted of 7645m.
-Documentation talks about support for 10000m but that values doesn't
-make sense as the value doesn't match the max value in the reg.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 25 +++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 3 +++
- 2 files changed, 28 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1261,6 +1261,10 @@ qca8k_setup(struct dsa_switch *ds)
- /* We don't have interrupts for link changes, so we need to poll */
- ds->pcs_poll = true;
-
-+ /* Set min a max ageing value supported */
-+ ds->ageing_time_min = 7000;
-+ ds->ageing_time_max = 458745000;
-+
- return 0;
- }
-
-@@ -1801,6 +1805,26 @@ qca8k_port_fast_age(struct dsa_switch *d
- }
-
- static int
-+qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ unsigned int secs = msecs / 1000;
-+ u32 val;
-+
-+ /* AGE_TIME reg is set in 7s step */
-+ val = secs / 7;
-+
-+ /* Handle case with 0 as val to NOT disable
-+ * learning
-+ */
-+ if (!val)
-+ val = 1;
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
-+ QCA8K_ATU_AGE_TIME(val));
-+}
-+
-+static int
- qca8k_port_enable(struct dsa_switch *ds, int port,
- struct phy_device *phy)
- {
-@@ -2018,6 +2042,7 @@ static const struct dsa_switch_ops qca8k
- .get_strings = qca8k_get_strings,
- .get_ethtool_stats = qca8k_get_ethtool_stats,
- .get_sset_count = qca8k_get_sset_count,
-+ .set_ageing_time = qca8k_set_ageing_time,
- .get_mac_eee = qca8k_get_mac_eee,
- .set_mac_eee = qca8k_set_mac_eee,
- .port_enable = qca8k_port_enable,
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -175,6 +175,9 @@
- #define QCA8K_VTU_FUNC1_BUSY BIT(31)
- #define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16)
- #define QCA8K_VTU_FUNC1_FULL BIT(4)
-+#define QCA8K_REG_ATU_CTRL 0x618
-+#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0)
-+#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x))
- #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620
- #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
- #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624
diff --git a/target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch b/target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch
deleted file mode 100644
index 8b97939ecb..0000000000
--- a/target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From ba8f870dfa635113ce6e8095a5eb1835ecde2e9e Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 22 Nov 2021 16:23:48 +0100
-Subject: net: dsa: qca8k: add support for mdb_add/del
-
-Add support for mdb add/del function. The ARL table is used to insert
-the rule. The rule will be searched, deleted and reinserted with the
-port mask updated. The function will check if the rule has to be updated
-or insert directly with no deletion of the old rule.
-If every port is removed from the port mask, the rule is removed.
-The rule is set STATIC in the ARL table (aka it doesn't age) to not be
-flushed by fast age function.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 99 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -436,6 +436,81 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
- }
-
- static int
-+qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_fdb_read(priv, &fdb);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule exist. Delete first */
-+ if (!fdb.aging) {
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+ }
-+
-+ /* Add port to fdb portmask */
-+ fdb.port_mask |= port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
-+qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule doesn't exist. Why delete? */
-+ if (!fdb.aging) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+
-+ /* Only port in the rule is this port. Don't re insert */
-+ if (fdb.port_mask == port_mask)
-+ goto exit;
-+
-+ /* Remove port from port mask */
-+ fdb.port_mask &= ~port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
- qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
- {
- u32 reg;
-@@ -1949,6 +2024,28 @@ qca8k_port_fdb_dump(struct dsa_switch *d
- }
-
- static int
-+qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
-+}
-+
-+static int
-+qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
-+}
-+
-+static int
- qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
- struct netlink_ext_ack *extack)
- {
-@@ -2056,6 +2153,8 @@ static const struct dsa_switch_ops qca8k
- .port_fdb_add = qca8k_port_fdb_add,
- .port_fdb_del = qca8k_port_fdb_del,
- .port_fdb_dump = qca8k_port_fdb_dump,
-+ .port_mdb_add = qca8k_port_mdb_add,
-+ .port_mdb_del = qca8k_port_mdb_del,
- .port_vlan_filtering = qca8k_port_vlan_filtering,
- .port_vlan_add = qca8k_port_vlan_add,
- .port_vlan_del = qca8k_port_vlan_del,
diff --git a/target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch b/target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch
deleted file mode 100644
index dc5a22935f..0000000000
--- a/target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 2c1bdbc7e7560d7de754cad277d968d56bb1899e Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 23 Nov 2021 03:59:10 +0100
-Subject: net: dsa: qca8k: add support for mirror mode
-
-The switch supports mirror mode. Only one port can set as mirror port and
-every other port can set to both ingress and egress mode. The mirror
-port is disabled and reverted to normal operation once every port is
-removed from sending packet to it.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 4 +++
- 2 files changed, 99 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -2046,6 +2046,99 @@ qca8k_port_mdb_del(struct dsa_switch *ds
- }
-
- static int
-+qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror,
-+ bool ingress)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int monitor_port, ret;
-+ u32 reg, val;
-+
-+ /* Check for existent entry */
-+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
-+ return -EEXIST;
-+
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* QCA83xx can have only one port set to mirror mode.
-+ * Check that the correct port is requested and return error otherwise.
-+ * When no mirror port is set, the values is set to 0xF
-+ */
-+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
-+ return -EEXIST;
-+
-+ /* Set the monitor port */
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
-+ mirror->to_local_port);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ return ret;
-+
-+ if (ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_update_bits(priv->regmap, reg, val, val);
-+ if (ret)
-+ return ret;
-+
-+ /* Track mirror port for tx and rx to decide when the
-+ * mirror port has to be disabled.
-+ */
-+ if (ingress)
-+ priv->mirror_rx |= BIT(port);
-+ else
-+ priv->mirror_tx |= BIT(port);
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg, val;
-+ int ret;
-+
-+ if (mirror->ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_clear_bits(priv->regmap, reg, val);
-+ if (ret)
-+ goto err;
-+
-+ if (mirror->ingress)
-+ priv->mirror_rx &= ~BIT(port);
-+ else
-+ priv->mirror_tx &= ~BIT(port);
-+
-+ /* No port set to send packet to mirror port. Disable mirror port */
-+ if (!priv->mirror_rx && !priv->mirror_tx) {
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ goto err;
-+ }
-+err:
-+ dev_err(priv->dev, "Failed to del mirror port from %d", port);
-+}
-+
-+static int
- qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
- struct netlink_ext_ack *extack)
- {
-@@ -2155,6 +2248,8 @@ static const struct dsa_switch_ops qca8k
- .port_fdb_dump = qca8k_port_fdb_dump,
- .port_mdb_add = qca8k_port_mdb_add,
- .port_mdb_del = qca8k_port_mdb_del,
-+ .port_mirror_add = qca8k_port_mirror_add,
-+ .port_mirror_del = qca8k_port_mirror_del,
- .port_vlan_filtering = qca8k_port_vlan_filtering,
- .port_vlan_add = qca8k_port_vlan_add,
- .port_vlan_del = qca8k_port_vlan_del,
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -180,6 +180,7 @@
- #define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x))
- #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620
- #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
-+#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4)
- #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624
- #define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24)
- #define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16)
-@@ -201,6 +202,7 @@
- #define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3)
- #define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4)
- #define QCA8K_PORT_LOOKUP_LEARN BIT(20)
-+#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
-
- #define QCA8K_REG_GLOBAL_FC_THRESH 0x800
- #define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16)
-@@ -305,6 +307,8 @@ struct qca8k_ports_config {
- struct qca8k_priv {
- u8 switch_id;
- u8 switch_revision;
-+ u8 mirror_rx;
-+ u8 mirror_tx;
- bool legacy_phy_port_mapping;
- struct qca8k_ports_config ports_config;
- struct regmap *regmap;
diff --git a/target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch b/target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch
deleted file mode 100644
index b53f1288d5..0000000000
--- a/target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch
+++ /dev/null
@@ -1,288 +0,0 @@
-From def975307c01191b6f0170048c3724b0ed3348af Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 23 Nov 2021 03:59:11 +0100
-Subject: net: dsa: qca8k: add LAG support
-
-Add LAG support to this switch. In Documentation this is described as
-trunk mode. A max of 4 LAGs are supported and each can support up to 4
-port. The current tx mode supported is Hash mode with both L2 and L2+3
-mode.
-When no port are present in the trunk, the trunk is disabled in the
-switch.
-When a port is disconnected, the traffic is redirected to the other
-available port.
-The hash mode is global and each LAG require to have the same hash mode
-set. To change the hash mode when multiple LAG are configured, it's
-required to remove each LAG and set the desired hash mode to the last.
-An error is printed when it's asked to set a not supported hadh mode.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 33 +++++++++
- 2 files changed, 210 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1340,6 +1340,9 @@ qca8k_setup(struct dsa_switch *ds)
- ds->ageing_time_min = 7000;
- ds->ageing_time_max = 458745000;
-
-+ /* Set max number of LAGs supported */
-+ ds->num_lag_ids = QCA8K_NUM_LAGS;
-+
- return 0;
- }
-
-@@ -2226,6 +2229,178 @@ qca8k_get_tag_protocol(struct dsa_switch
- return DSA_TAG_PROTO_QCA;
- }
-
-+static bool
-+qca8k_lag_can_offload(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct dsa_port *dp;
-+ int id, members = 0;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+ if (id < 0 || id >= ds->num_lag_ids)
-+ return false;
-+
-+ dsa_lag_foreach_port(dp, ds->dst, lag)
-+ /* Includes the port joining the LAG */
-+ members++;
-+
-+ if (members > QCA8K_NUM_PORTS_FOR_LAG)
-+ return false;
-+
-+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
-+ return false;
-+
-+ if (info->hash_type != NETDEV_LAG_HASH_L2 ||
-+ info->hash_type != NETDEV_LAG_HASH_L23)
-+ return false;
-+
-+ return true;
-+}
-+
-+static int
-+qca8k_lag_setup_hash(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ bool unique_lag = true;
-+ int i, id;
-+ u32 hash;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ switch (info->hash_type) {
-+ case NETDEV_LAG_HASH_L23:
-+ hash |= QCA8K_TRUNK_HASH_SIP_EN;
-+ hash |= QCA8K_TRUNK_HASH_DIP_EN;
-+ fallthrough;
-+ case NETDEV_LAG_HASH_L2:
-+ hash |= QCA8K_TRUNK_HASH_SA_EN;
-+ hash |= QCA8K_TRUNK_HASH_DA_EN;
-+ break;
-+ default: /* We should NEVER reach this */
-+ return -EOPNOTSUPP;
-+ }
-+
-+ /* Check if we are the unique configured LAG */
-+ dsa_lags_foreach_id(i, ds->dst)
-+ if (i != id && dsa_lag_dev(ds->dst, i)) {
-+ unique_lag = false;
-+ break;
-+ }
-+
-+ /* Hash Mode is global. Make sure the same Hash Mode
-+ * is set to all the 4 possible lag.
-+ * If we are the unique LAG we can set whatever hash
-+ * mode we want.
-+ * To change hash mode it's needed to remove all LAG
-+ * and change the mode with the latest.
-+ */
-+ if (unique_lag) {
-+ priv->lag_hash_mode = hash;
-+ } else if (priv->lag_hash_mode != hash) {
-+ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
-+ QCA8K_TRUNK_HASH_MASK, hash);
-+}
-+
-+static int
-+qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
-+ struct net_device *lag, bool delete)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret, id, i;
-+ u32 val;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ /* Read current port member */
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* Shift val to the correct trunk */
-+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
-+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
-+ if (delete)
-+ val &= ~BIT(port);
-+ else
-+ val |= BIT(port);
-+
-+ /* Update port member. With empty portmap disable trunk */
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
-+ QCA8K_REG_GOL_TRUNK_MEMBER(id) |
-+ QCA8K_REG_GOL_TRUNK_EN(id),
-+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
-+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
-+
-+ /* Search empty member if adding or port on deleting */
-+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
-+ if (ret)
-+ return ret;
-+
-+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
-+
-+ if (delete) {
-+ /* If port flagged to be disabled assume this member is
-+ * empty
-+ */
-+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
-+ if (val != port)
-+ continue;
-+ } else {
-+ /* If port flagged to be enabled assume this member is
-+ * already set
-+ */
-+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+ }
-+
-+ /* We have found the member to add/remove */
-+ break;
-+ }
-+
-+ /* Set port in the correct port mask or disable port if in delete mode */
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
-+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
-+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
-+}
-+
-+static int
-+qca8k_port_lag_join(struct dsa_switch *ds, int port,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ int ret;
-+
-+ if (!qca8k_lag_can_offload(ds, lag, info))
-+ return -EOPNOTSUPP;
-+
-+ ret = qca8k_lag_setup_hash(ds, lag, info);
-+ if (ret)
-+ return ret;
-+
-+ return qca8k_lag_refresh_portmap(ds, port, lag, false);
-+}
-+
-+static int
-+qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-+ struct net_device *lag)
-+{
-+ return qca8k_lag_refresh_portmap(ds, port, lag, true);
-+}
-+
- static const struct dsa_switch_ops qca8k_switch_ops = {
- .get_tag_protocol = qca8k_get_tag_protocol,
- .setup = qca8k_setup,
-@@ -2259,6 +2434,8 @@ static const struct dsa_switch_ops qca8k
- .phylink_mac_link_down = qca8k_phylink_mac_link_down,
- .phylink_mac_link_up = qca8k_phylink_mac_link_up,
- .get_phy_flags = qca8k_get_phy_flags,
-+ .port_lag_join = qca8k_port_lag_join,
-+ .port_lag_leave = qca8k_port_lag_leave,
- };
-
- static int qca8k_read_switch_id(struct qca8k_priv *priv)
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -15,6 +15,8 @@
- #define QCA8K_NUM_PORTS 7
- #define QCA8K_NUM_CPU_PORTS 2
- #define QCA8K_MAX_MTU 9000
-+#define QCA8K_NUM_LAGS 4
-+#define QCA8K_NUM_PORTS_FOR_LAG 4
-
- #define PHY_ID_QCA8327 0x004dd034
- #define QCA8K_ID_QCA8327 0x12
-@@ -122,6 +124,14 @@
- #define QCA8K_REG_EEE_CTRL 0x100
- #define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2)
-
-+/* TRUNK_HASH_EN registers */
-+#define QCA8K_TRUNK_HASH_EN_CTRL 0x270
-+#define QCA8K_TRUNK_HASH_SIP_EN BIT(3)
-+#define QCA8K_TRUNK_HASH_DIP_EN BIT(2)
-+#define QCA8K_TRUNK_HASH_SA_EN BIT(1)
-+#define QCA8K_TRUNK_HASH_DA_EN BIT(0)
-+#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0)
-+
- /* ACL registers */
- #define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8))
- #define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16)
-@@ -204,6 +214,28 @@
- #define QCA8K_PORT_LOOKUP_LEARN BIT(20)
- #define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
-
-+#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700
-+/* 4 max trunk first
-+ * first 6 bit for member bitmap
-+ * 7th bit is to enable trunk port
-+ */
-+#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8)
-+#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7)
-+#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i))
-+#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0)
-+#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i))
-+/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */
-+#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4))
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0)
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3)
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0)
-+#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16)
-+#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4)
-+/* Complex shift: FIRST shift for port THEN shift for trunk */
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i))
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j))
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j))
-+
- #define QCA8K_REG_GLOBAL_FC_THRESH 0x800
- #define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16)
- #define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x)
-@@ -309,6 +341,7 @@ struct qca8k_priv {
- u8 switch_revision;
- u8 mirror_rx;
- u8 mirror_tx;
-+ u8 lag_hash_mode;
- bool legacy_phy_port_mapping;
- struct qca8k_ports_config ports_config;
- struct regmap *regmap;
diff --git a/target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch b/target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch
deleted file mode 100644
index 7d811be11c..0000000000
--- a/target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 0898ca67b86e14207d4feb3f3fea8b87cec5aab1 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 23 Nov 2021 16:44:46 +0100
-Subject: net: dsa: qca8k: fix warning in LAG feature
-
-Fix warning reported by bot.
-Make sure hash is init to 0 and fix wrong logic for hash_type in
-qca8k_lag_can_offload.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Fixes: def975307c01 ("net: dsa: qca8k: add LAG support")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Link: https://lore.kernel.org/r/20211123154446.31019-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca8k.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -2251,7 +2251,7 @@ qca8k_lag_can_offload(struct dsa_switch
- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
- return false;
-
-- if (info->hash_type != NETDEV_LAG_HASH_L2 ||
-+ if (info->hash_type != NETDEV_LAG_HASH_L2 &&
- info->hash_type != NETDEV_LAG_HASH_L23)
- return false;
-
-@@ -2265,8 +2265,8 @@ qca8k_lag_setup_hash(struct dsa_switch *
- {
- struct qca8k_priv *priv = ds->priv;
- bool unique_lag = true;
-+ u32 hash = 0;
- int i, id;
-- u32 hash;
-
- id = dsa_lag_id(ds->dst, lag);
-
diff --git a/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch b/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch
deleted file mode 100644
index 77cf63b809..0000000000
--- a/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 904e112ad431492b34f235f59738e8312802bbf9 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Thu, 6 Jan 2022 01:11:12 +0200
-Subject: [PATCH 1/6] net: dsa: reorder PHY initialization with MTU setup in
- slave.c
-
-In dsa_slave_create() there are 2 sections that take rtnl_lock():
-MTU change and netdev registration. They are separated by PHY
-initialization.
-
-There isn't any strict ordering requirement except for the fact that
-netdev registration should be last. Therefore, we can perform the MTU
-change a bit later, after the PHY setup. A future change will then be
-able to merge the two rtnl_lock sections into one.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/slave.c | 14 +++++++-------
- 1 file changed, 7 insertions(+), 7 deletions(-)
-
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -1977,13 +1977,6 @@ int dsa_slave_create(struct dsa_port *po
- port->slave = slave_dev;
- dsa_slave_setup_tagger(slave_dev);
-
-- rtnl_lock();
-- ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN);
-- rtnl_unlock();
-- if (ret && ret != -EOPNOTSUPP)
-- dev_warn(ds->dev, "nonfatal error %d setting MTU to %d on port %d\n",
-- ret, ETH_DATA_LEN, port->index);
--
- netif_carrier_off(slave_dev);
-
- ret = dsa_slave_phy_setup(slave_dev);
-@@ -1995,6 +1988,13 @@ int dsa_slave_create(struct dsa_port *po
- }
-
- rtnl_lock();
-+ ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN);
-+ rtnl_unlock();
-+ if (ret && ret != -EOPNOTSUPP)
-+ dev_warn(ds->dev, "nonfatal error %d setting MTU to %d on port %d\n",
-+ ret, ETH_DATA_LEN, port->index);
-+
-+ rtnl_lock();
-
- ret = register_netdevice(slave_dev);
- if (ret) {
diff --git a/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch b/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch
deleted file mode 100644
index 50aa5d8f0d..0000000000
--- a/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From e31dbd3b6aba585231cd84a87adeb22e7c6a8c19 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Thu, 6 Jan 2022 01:11:13 +0200
-Subject: [PATCH 2/6] net: dsa: merge rtnl_lock sections in dsa_slave_create
-
-Currently dsa_slave_create() has two sequences of rtnl_lock/rtnl_unlock
-in a row. Remove the rtnl_unlock() and rtnl_lock() in between, such that
-the operation can execute slighly faster.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/slave.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -1988,14 +1988,12 @@ int dsa_slave_create(struct dsa_port *po
- }
-
- rtnl_lock();
-+
- ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN);
-- rtnl_unlock();
- if (ret && ret != -EOPNOTSUPP)
- dev_warn(ds->dev, "nonfatal error %d setting MTU to %d on port %d\n",
- ret, ETH_DATA_LEN, port->index);
-
-- rtnl_lock();
--
- ret = register_netdevice(slave_dev);
- if (ret) {
- netdev_err(master, "error %d registering interface %s\n",
diff --git a/target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch b/target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch
deleted file mode 100644
index 6c7aad6928..0000000000
--- a/target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From a1ff94c2973c43bc1e2677ac63ebb15b1d1ff846 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Thu, 6 Jan 2022 01:11:14 +0200
-Subject: [PATCH 3/6] net: dsa: stop updating master MTU from master.c
-
-At present there are two paths for changing the MTU of the DSA master.
-
-The first is:
-
-dsa_tree_setup
--> dsa_tree_setup_ports
- -> dsa_port_setup
- -> dsa_slave_create
- -> dsa_slave_change_mtu
- -> dev_set_mtu(master)
-
-The second is:
-
-dsa_tree_setup
--> dsa_tree_setup_master
- -> dsa_master_setup
- -> dev_set_mtu(dev)
-
-So the dev_set_mtu() call from dsa_master_setup() has been effectively
-superseded by the dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN) that is
-done from dsa_slave_create() for each user port. The later function also
-updates the master MTU according to the largest user port MTU from the
-tree. Therefore, updating the master MTU through a separate code path
-isn't needed.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/master.c | 25 +------------------------
- 1 file changed, 1 insertion(+), 24 deletions(-)
-
---- a/net/dsa/master.c
-+++ b/net/dsa/master.c
-@@ -329,28 +329,13 @@ static const struct attribute_group dsa_
- .attrs = dsa_slave_attrs,
- };
-
--static void dsa_master_reset_mtu(struct net_device *dev)
--{
-- int err;
--
-- rtnl_lock();
-- err = dev_set_mtu(dev, ETH_DATA_LEN);
-- if (err)
-- netdev_dbg(dev,
-- "Unable to reset MTU to exclude DSA overheads\n");
-- rtnl_unlock();
--}
--
- static struct lock_class_key dsa_master_addr_list_lock_key;
-
- int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp)
- {
-- const struct dsa_device_ops *tag_ops = cpu_dp->tag_ops;
- struct dsa_switch *ds = cpu_dp->ds;
- struct device_link *consumer_link;
-- int mtu, ret;
--
-- mtu = ETH_DATA_LEN + dsa_tag_protocol_overhead(tag_ops);
-+ int ret;
-
- /* The DSA master must use SET_NETDEV_DEV for this to work. */
- consumer_link = device_link_add(ds->dev, dev->dev.parent,
-@@ -360,13 +345,6 @@ int dsa_master_setup(struct net_device *
- "Failed to create a device link to DSA switch %s\n",
- dev_name(ds->dev));
-
-- rtnl_lock();
-- ret = dev_set_mtu(dev, mtu);
-- rtnl_unlock();
-- if (ret)
-- netdev_warn(dev, "error %d setting MTU to %d to include DSA overhead\n",
-- ret, mtu);
--
- /* If we use a tagging format that doesn't have an ethertype
- * field, make sure that all packets from this point on get
- * sent to the tag format's receive function.
-@@ -404,7 +382,6 @@ void dsa_master_teardown(struct net_devi
- sysfs_remove_group(&dev->dev.kobj, &dsa_group);
- dsa_netdev_ops_set(dev, NULL);
- dsa_master_ethtool_teardown(dev);
-- dsa_master_reset_mtu(dev);
- dsa_master_set_promiscuity(dev, -1);
-
- dev->dsa_ptr = NULL;
diff --git a/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch b/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch
deleted file mode 100644
index dbc28efc94..0000000000
--- a/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From c146f9bc195a9dc3ad7fd000a14540e7c9df952d Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Thu, 6 Jan 2022 01:11:15 +0200
-Subject: [PATCH 4/6] net: dsa: hold rtnl_mutex when calling
- dsa_master_{setup,teardown}
-
-DSA needs to simulate master tracking events when a binding is first
-with a DSA master established and torn down, in order to give drivers
-the simplifying guarantee that ->master_state_change calls are made
-only when the master's readiness state to pass traffic changes.
-master_state_change() provide a operational bool that DSA driver can use
-to understand if DSA master is operational or not.
-To avoid races, we need to block the reception of
-NETDEV_UP/NETDEV_CHANGE/NETDEV_GOING_DOWN events in the netdev notifier
-chain while we are changing the master's dev->dsa_ptr (this changes what
-netdev_uses_dsa(dev) reports).
-
-The dsa_master_setup() and dsa_master_teardown() functions optionally
-require the rtnl_mutex to be held, if the tagger needs the master to be
-promiscuous, these functions call dev_set_promiscuity(). Move the
-rtnl_lock() from that function and make it top-level.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/dsa2.c | 8 ++++++++
- net/dsa/master.c | 4 ++--
- 2 files changed, 10 insertions(+), 2 deletions(-)
-
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -1056,6 +1056,8 @@ static int dsa_tree_setup_master(struct
- struct dsa_port *dp;
- int err;
-
-+ rtnl_lock();
-+
- list_for_each_entry(dp, &dst->ports, list) {
- if (dsa_port_is_cpu(dp)) {
- err = dsa_master_setup(dp->master, dp);
-@@ -1064,6 +1066,8 @@ static int dsa_tree_setup_master(struct
- }
- }
-
-+ rtnl_unlock();
-+
- return 0;
- }
-
-@@ -1071,9 +1075,13 @@ static void dsa_tree_teardown_master(str
- {
- struct dsa_port *dp;
-
-+ rtnl_lock();
-+
- list_for_each_entry(dp, &dst->ports, list)
- if (dsa_port_is_cpu(dp))
- dsa_master_teardown(dp->master);
-+
-+ rtnl_unlock();
- }
-
- static int dsa_tree_setup_lags(struct dsa_switch_tree *dst)
---- a/net/dsa/master.c
-+++ b/net/dsa/master.c
-@@ -266,9 +266,9 @@ static void dsa_master_set_promiscuity(s
- if (!ops->promisc_on_master)
- return;
-
-- rtnl_lock();
-+ ASSERT_RTNL();
-+
- dev_set_promiscuity(dev, inc);
-- rtnl_unlock();
- }
-
- static ssize_t tagging_show(struct device *d, struct device_attribute *attr,
diff --git a/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch b/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch
deleted file mode 100644
index fbb9c94ec1..0000000000
--- a/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 1e3f407f3cacc5dcfe27166c412ed9bc263d82bf Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Thu, 6 Jan 2022 01:11:16 +0200
-Subject: [PATCH 5/6] net: dsa: first set up shared ports, then non-shared
- ports
-
-After commit a57d8c217aad ("net: dsa: flush switchdev workqueue before
-tearing down CPU/DSA ports"), the port setup and teardown procedure
-became asymmetric.
-
-The fact of the matter is that user ports need the shared ports to be up
-before they can be used for CPU-initiated termination. And since we
-register net devices for the user ports, those won't be functional until
-we also call the setup for the shared (CPU, DSA) ports. But we may do
-that later, depending on the port numbering scheme of the hardware we
-are dealing with.
-
-It just makes sense that all shared ports are brought up before any user
-port is. I can't pinpoint any issue due to the current behavior, but
-let's change it nonetheless, for consistency's sake.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/dsa2.c | 50 +++++++++++++++++++++++++++++++++++++-------------
- 1 file changed, 37 insertions(+), 13 deletions(-)
-
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -1021,23 +1021,28 @@ static void dsa_tree_teardown_switches(s
- dsa_switch_teardown(dp->ds);
- }
-
--static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
-+/* Bring shared ports up first, then non-shared ports */
-+static int dsa_tree_setup_ports(struct dsa_switch_tree *dst)
- {
- struct dsa_port *dp;
-- int err;
-+ int err = 0;
-
- list_for_each_entry(dp, &dst->ports, list) {
-- err = dsa_switch_setup(dp->ds);
-- if (err)
-- goto teardown;
-+ if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp)) {
-+ err = dsa_port_setup(dp);
-+ if (err)
-+ goto teardown;
-+ }
- }
-
- list_for_each_entry(dp, &dst->ports, list) {
-- err = dsa_port_setup(dp);
-- if (err) {
-- err = dsa_port_reinit_as_unused(dp);
-- if (err)
-- goto teardown;
-+ if (dsa_port_is_user(dp) || dsa_port_is_unused(dp)) {
-+ err = dsa_port_setup(dp);
-+ if (err) {
-+ err = dsa_port_reinit_as_unused(dp);
-+ if (err)
-+ goto teardown;
-+ }
- }
- }
-
-@@ -1046,7 +1051,21 @@ static int dsa_tree_setup_switches(struc
- teardown:
- dsa_tree_teardown_ports(dst);
-
-- dsa_tree_teardown_switches(dst);
-+ return err;
-+}
-+
-+static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
-+{
-+ struct dsa_port *dp;
-+ int err = 0;
-+
-+ list_for_each_entry(dp, &dst->ports, list) {
-+ err = dsa_switch_setup(dp->ds);
-+ if (err) {
-+ dsa_tree_teardown_switches(dst);
-+ break;
-+ }
-+ }
-
- return err;
- }
-@@ -1133,10 +1152,14 @@ static int dsa_tree_setup(struct dsa_swi
- if (err)
- goto teardown_cpu_ports;
-
-- err = dsa_tree_setup_master(dst);
-+ err = dsa_tree_setup_ports(dst);
- if (err)
- goto teardown_switches;
-
-+ err = dsa_tree_setup_master(dst);
-+ if (err)
-+ goto teardown_ports;
-+
- err = dsa_tree_setup_lags(dst);
- if (err)
- goto teardown_master;
-@@ -1149,8 +1172,9 @@ static int dsa_tree_setup(struct dsa_swi
-
- teardown_master:
- dsa_tree_teardown_master(dst);
--teardown_switches:
-+teardown_ports:
- dsa_tree_teardown_ports(dst);
-+teardown_switches:
- dsa_tree_teardown_switches(dst);
- teardown_cpu_ports:
- dsa_tree_teardown_cpu_ports(dst);
diff --git a/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch b/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch
deleted file mode 100644
index a46e06ef8b..0000000000
--- a/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 11fd667dac315ea3f2469961f6d2869271a46cae Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Thu, 6 Jan 2022 01:11:17 +0200
-Subject: [PATCH 6/6] net: dsa: setup master before ports
-
-It is said that as soon as a network interface is registered, all its
-resources should have already been prepared, so that it is available for
-sending and receiving traffic. One of the resources needed by a DSA
-slave interface is the master.
-
-dsa_tree_setup
--> dsa_tree_setup_ports
- -> dsa_port_setup
- -> dsa_slave_create
- -> register_netdevice
--> dsa_tree_setup_master
- -> dsa_master_setup
- -> sets up master->dsa_ptr, which enables reception
-
-Therefore, there is a short period of time after register_netdevice()
-during which the master isn't prepared to pass traffic to the DSA layer
-(master->dsa_ptr is checked by eth_type_trans). Same thing during
-unregistration, there is a time frame in which packets might be missed.
-
-Note that this change opens us to another race: dsa_master_find_slave()
-will get invoked potentially earlier than the slave creation, and later
-than the slave deletion. Since dp->slave starts off as a NULL pointer,
-the earlier calls aren't a problem, but the later calls are. To avoid
-use-after-free, we should zeroize dp->slave before calling
-dsa_slave_destroy().
-
-In practice I cannot really test real life improvements brought by this
-change, since in my systems, netdevice creation races with PHY autoneg
-which takes a few seconds to complete, and that masks quite a few races.
-Effects might be noticeable in a setup with fixed links all the way to
-an external system.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/dsa2.c | 23 +++++++++++++----------
- 1 file changed, 13 insertions(+), 10 deletions(-)
-
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -567,6 +567,7 @@ static void dsa_port_teardown(struct dsa
- struct devlink_port *dlp = &dp->devlink_port;
- struct dsa_switch *ds = dp->ds;
- struct dsa_mac_addr *a, *tmp;
-+ struct net_device *slave;
-
- if (!dp->setup)
- return;
-@@ -588,9 +589,11 @@ static void dsa_port_teardown(struct dsa
- dsa_port_link_unregister_of(dp);
- break;
- case DSA_PORT_TYPE_USER:
-- if (dp->slave) {
-- dsa_slave_destroy(dp->slave);
-+ slave = dp->slave;
-+
-+ if (slave) {
- dp->slave = NULL;
-+ dsa_slave_destroy(slave);
- }
- break;
- }
-@@ -1152,17 +1155,17 @@ static int dsa_tree_setup(struct dsa_swi
- if (err)
- goto teardown_cpu_ports;
-
-- err = dsa_tree_setup_ports(dst);
-+ err = dsa_tree_setup_master(dst);
- if (err)
- goto teardown_switches;
-
-- err = dsa_tree_setup_master(dst);
-+ err = dsa_tree_setup_ports(dst);
- if (err)
-- goto teardown_ports;
-+ goto teardown_master;
-
- err = dsa_tree_setup_lags(dst);
- if (err)
-- goto teardown_master;
-+ goto teardown_ports;
-
- dst->setup = true;
-
-@@ -1170,10 +1173,10 @@ static int dsa_tree_setup(struct dsa_swi
-
- return 0;
-
--teardown_master:
-- dsa_tree_teardown_master(dst);
- teardown_ports:
- dsa_tree_teardown_ports(dst);
-+teardown_master:
-+ dsa_tree_teardown_master(dst);
- teardown_switches:
- dsa_tree_teardown_switches(dst);
- teardown_cpu_ports:
-@@ -1191,10 +1194,10 @@ static void dsa_tree_teardown(struct dsa
-
- dsa_tree_teardown_lags(dst);
-
-- dsa_tree_teardown_master(dst);
--
- dsa_tree_teardown_ports(dst);
-
-+ dsa_tree_teardown_master(dst);
-+
- dsa_tree_teardown_switches(dst);
-
- dsa_tree_teardown_cpu_ports(dst);
diff --git a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch
deleted file mode 100644
index 15122950ce..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From 295ab96f478d0fa56393e85406f19a867e26ce22 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 2 Feb 2022 01:03:20 +0100
-Subject: [PATCH 01/16] net: dsa: provide switch operations for tracking the
- master state
-
-Certain drivers may need to send management traffic to the switch for
-things like register access, FDB dump, etc, to accelerate what their
-slow bus (SPI, I2C, MDIO) can already do.
-
-Ethernet is faster (especially in bulk transactions) but is also more
-unreliable, since the user may decide to bring the DSA master down (or
-not bring it up), therefore severing the link between the host and the
-attached switch.
-
-Drivers needing Ethernet-based register access already should have
-fallback logic to the slow bus if the Ethernet method fails, but that
-fallback may be based on a timeout, and the I/O to the switch may slow
-down to a halt if the master is down, because every Ethernet packet will
-have to time out. The driver also doesn't have the option to turn off
-Ethernet-based I/O momentarily, because it wouldn't know when to turn it
-back on.
-
-Which is where this change comes in. By tracking NETDEV_CHANGE,
-NETDEV_UP and NETDEV_GOING_DOWN events on the DSA master, we should know
-the exact interval of time during which this interface is reliably
-available for traffic. Provide this information to switches so they can
-use it as they wish.
-
-An helper is added dsa_port_master_is_operational() to check if a master
-port is operational.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/dsa.h | 17 +++++++++++++++++
- net/dsa/dsa2.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
- net/dsa/dsa_priv.h | 13 +++++++++++++
- net/dsa/slave.c | 32 ++++++++++++++++++++++++++++++++
- net/dsa/switch.c | 15 +++++++++++++++
- 5 files changed, 123 insertions(+)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -291,6 +291,10 @@ struct dsa_port {
- struct list_head mdbs;
-
- bool setup;
-+ /* Master state bits, valid only on CPU ports */
-+ u8 master_admin_up:1;
-+ u8 master_oper_up:1;
-+
- };
-
- /* TODO: ideally DSA ports would have a single dp->link_dp member,
-@@ -456,6 +460,12 @@ static inline bool dsa_port_is_unused(st
- return dp->type == DSA_PORT_TYPE_UNUSED;
- }
-
-+static inline bool dsa_port_master_is_operational(struct dsa_port *dp)
-+{
-+ return dsa_port_is_cpu(dp) && dp->master_admin_up &&
-+ dp->master_oper_up;
-+}
-+
- static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
- {
- return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
-@@ -957,6 +967,13 @@ struct dsa_switch_ops {
- int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid,
- u16 flags);
- int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid);
-+
-+ /*
-+ * DSA master tracking operations
-+ */
-+ void (*master_state_change)(struct dsa_switch *ds,
-+ const struct net_device *master,
-+ bool operational);
- };
-
- #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -1297,6 +1297,52 @@ out_unlock:
- return err;
- }
-
-+static void dsa_tree_master_state_change(struct dsa_switch_tree *dst,
-+ struct net_device *master)
-+{
-+ struct dsa_notifier_master_state_info info;
-+ struct dsa_port *cpu_dp = master->dsa_ptr;
-+
-+ info.master = master;
-+ info.operational = dsa_port_master_is_operational(cpu_dp);
-+
-+ dsa_tree_notify(dst, DSA_NOTIFIER_MASTER_STATE_CHANGE, &info);
-+}
-+
-+void dsa_tree_master_admin_state_change(struct dsa_switch_tree *dst,
-+ struct net_device *master,
-+ bool up)
-+{
-+ struct dsa_port *cpu_dp = master->dsa_ptr;
-+ bool notify = false;
-+
-+ if ((dsa_port_master_is_operational(cpu_dp)) !=
-+ (up && cpu_dp->master_oper_up))
-+ notify = true;
-+
-+ cpu_dp->master_admin_up = up;
-+
-+ if (notify)
-+ dsa_tree_master_state_change(dst, master);
-+}
-+
-+void dsa_tree_master_oper_state_change(struct dsa_switch_tree *dst,
-+ struct net_device *master,
-+ bool up)
-+{
-+ struct dsa_port *cpu_dp = master->dsa_ptr;
-+ bool notify = false;
-+
-+ if ((dsa_port_master_is_operational(cpu_dp)) !=
-+ (cpu_dp->master_admin_up && up))
-+ notify = true;
-+
-+ cpu_dp->master_oper_up = up;
-+
-+ if (notify)
-+ dsa_tree_master_state_change(dst, master);
-+}
-+
- static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index)
- {
- struct dsa_switch_tree *dst = ds->dst;
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -45,6 +45,7 @@ enum {
- DSA_NOTIFIER_MRP_DEL_RING_ROLE,
- DSA_NOTIFIER_TAG_8021Q_VLAN_ADD,
- DSA_NOTIFIER_TAG_8021Q_VLAN_DEL,
-+ DSA_NOTIFIER_MASTER_STATE_CHANGE,
- };
-
- /* DSA_NOTIFIER_AGEING_TIME */
-@@ -127,6 +128,12 @@ struct dsa_notifier_tag_8021q_vlan_info
- u16 vid;
- };
-
-+/* DSA_NOTIFIER_MASTER_STATE_CHANGE */
-+struct dsa_notifier_master_state_info {
-+ const struct net_device *master;
-+ bool operational;
-+};
-+
- struct dsa_switchdev_event_work {
- struct dsa_switch *ds;
- int port;
-@@ -549,6 +556,12 @@ int dsa_tree_change_tag_proto(struct dsa
- struct net_device *master,
- const struct dsa_device_ops *tag_ops,
- const struct dsa_device_ops *old_tag_ops);
-+void dsa_tree_master_admin_state_change(struct dsa_switch_tree *dst,
-+ struct net_device *master,
-+ bool up);
-+void dsa_tree_master_oper_state_change(struct dsa_switch_tree *dst,
-+ struct net_device *master,
-+ bool up);
- int dsa_bridge_num_get(const struct net_device *bridge_dev, int max);
- void dsa_bridge_num_put(const struct net_device *bridge_dev, int bridge_num);
-
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -2311,6 +2311,36 @@ static int dsa_slave_netdevice_event(str
- err = dsa_port_lag_change(dp, info->lower_state_info);
- return notifier_from_errno(err);
- }
-+ case NETDEV_CHANGE:
-+ case NETDEV_UP: {
-+ /* Track state of master port.
-+ * DSA driver may require the master port (and indirectly
-+ * the tagger) to be available for some special operation.
-+ */
-+ if (netdev_uses_dsa(dev)) {
-+ struct dsa_port *cpu_dp = dev->dsa_ptr;
-+ struct dsa_switch_tree *dst = cpu_dp->ds->dst;
-+
-+ /* Track when the master port is UP */
-+ dsa_tree_master_oper_state_change(dst, dev,
-+ netif_oper_up(dev));
-+
-+ /* Track when the master port is ready and can accept
-+ * packet.
-+ * NETDEV_UP event is not enough to flag a port as ready.
-+ * We also have to wait for linkwatch_do_dev to dev_activate
-+ * and emit a NETDEV_CHANGE event.
-+ * We check if a master port is ready by checking if the dev
-+ * have a qdisc assigned and is not noop.
-+ */
-+ dsa_tree_master_admin_state_change(dst, dev,
-+ !qdisc_tx_is_noop(dev));
-+
-+ return NOTIFY_OK;
-+ }
-+
-+ return NOTIFY_DONE;
-+ }
- case NETDEV_GOING_DOWN: {
- struct dsa_port *dp, *cpu_dp;
- struct dsa_switch_tree *dst;
-@@ -2322,6 +2352,8 @@ static int dsa_slave_netdevice_event(str
- cpu_dp = dev->dsa_ptr;
- dst = cpu_dp->ds->dst;
-
-+ dsa_tree_master_admin_state_change(dst, dev, false);
-+
- list_for_each_entry(dp, &dst->ports, list) {
- if (!dsa_is_user_port(dp->ds, dp->index))
- continue;
---- a/net/dsa/switch.c
-+++ b/net/dsa/switch.c
-@@ -722,6 +722,18 @@ dsa_switch_mrp_del_ring_role(struct dsa_
- return 0;
- }
-
-+static int
-+dsa_switch_master_state_change(struct dsa_switch *ds,
-+ struct dsa_notifier_master_state_info *info)
-+{
-+ if (!ds->ops->master_state_change)
-+ return 0;
-+
-+ ds->ops->master_state_change(ds, info->master, info->operational);
-+
-+ return 0;
-+}
-+
- static int dsa_switch_event(struct notifier_block *nb,
- unsigned long event, void *info)
- {
-@@ -813,6 +825,9 @@ static int dsa_switch_event(struct notif
- case DSA_NOTIFIER_TAG_8021Q_VLAN_DEL:
- err = dsa_switch_tag_8021q_vlan_del(ds, info);
- break;
-+ case DSA_NOTIFIER_MASTER_STATE_CHANGE:
-+ err = dsa_switch_master_state_change(ds, info);
-+ break;
- default:
- err = -EOPNOTSUPP;
- break;
diff --git a/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch b/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch
deleted file mode 100644
index c55c5271d4..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From e83d56537859849f2223b90749e554831b1f3c27 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 2 Feb 2022 01:03:21 +0100
-Subject: [PATCH 02/16] net: dsa: replay master state events in
- dsa_tree_{setup,teardown}_master
-
-In order for switch driver to be able to make simple and reliable use of
-the master tracking operations, they must also be notified of the
-initial state of the DSA master, not just of the changes. This is
-because they might enable certain features only during the time when
-they know that the DSA master is up and running.
-
-Therefore, this change explicitly checks the state of the DSA master
-under the same rtnl_mutex as we were holding during the
-dsa_master_setup() and dsa_master_teardown() call. The idea being that
-if the DSA master became operational in between the moment in which it
-became a DSA master (dsa_master_setup set dev->dsa_ptr) and the moment
-when we checked for the master being up, there is a chance that we
-would emit a ->master_state_change() call with no actual state change.
-We need to avoid that by serializing the concurrent netdevice event with
-us. If the netdevice event started before, we force it to finish before
-we begin, because we take rtnl_lock before making netdev_uses_dsa()
-return true. So we also handle that early event and do nothing on it.
-Similarly, if the dev_open() attempt is concurrent with us, it will
-attempt to take the rtnl_mutex, but we're holding it. We'll see that
-the master flag IFF_UP isn't set, then when we release the rtnl_mutex
-we'll process the NETDEV_UP notifier.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/dsa2.c | 28 ++++++++++++++++++++++++----
- 1 file changed, 24 insertions(+), 4 deletions(-)
-
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -15,6 +15,7 @@
- #include <linux/of.h>
- #include <linux/of_net.h>
- #include <net/devlink.h>
-+#include <net/sch_generic.h>
-
- #include "dsa_priv.h"
-
-@@ -1082,9 +1083,18 @@ static int dsa_tree_setup_master(struct
-
- list_for_each_entry(dp, &dst->ports, list) {
- if (dsa_port_is_cpu(dp)) {
-- err = dsa_master_setup(dp->master, dp);
-+ struct net_device *master = dp->master;
-+ bool admin_up = (master->flags & IFF_UP) &&
-+ !qdisc_tx_is_noop(master);
-+
-+ err = dsa_master_setup(master, dp);
- if (err)
- return err;
-+
-+ /* Replay master state event */
-+ dsa_tree_master_admin_state_change(dst, master, admin_up);
-+ dsa_tree_master_oper_state_change(dst, master,
-+ netif_oper_up(master));
- }
- }
-
-@@ -1099,9 +1109,19 @@ static void dsa_tree_teardown_master(str
-
- rtnl_lock();
-
-- list_for_each_entry(dp, &dst->ports, list)
-- if (dsa_port_is_cpu(dp))
-- dsa_master_teardown(dp->master);
-+ list_for_each_entry(dp, &dst->ports, list) {
-+ if (dsa_port_is_cpu(dp)) {
-+ struct net_device *master = dp->master;
-+
-+ /* Synthesizing an "admin down" state is sufficient for
-+ * the switches to get a notification if the master is
-+ * currently up and running.
-+ */
-+ dsa_tree_master_admin_state_change(dst, master, false);
-+
-+ dsa_master_teardown(master);
-+ }
-+ }
-
- rtnl_unlock();
- }
diff --git a/target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch b/target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch
deleted file mode 100644
index 82c94b385b..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 6b0458299297ca4ab6fb295800e29a4e501d50c1 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:22 +0100
-Subject: [PATCH 03/16] net: dsa: tag_qca: convert to FIELD macro
-
-Convert driver to FIELD macro to drop redundant define.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/tag_qca.c | 34 +++++++++++++++-------------------
- 1 file changed, 15 insertions(+), 19 deletions(-)
-
---- a/net/dsa/tag_qca.c
-+++ b/net/dsa/tag_qca.c
-@@ -4,29 +4,24 @@
- */
-
- #include <linux/etherdevice.h>
-+#include <linux/bitfield.h>
-
- #include "dsa_priv.h"
-
- #define QCA_HDR_LEN 2
- #define QCA_HDR_VERSION 0x2
-
--#define QCA_HDR_RECV_VERSION_MASK GENMASK(15, 14)
--#define QCA_HDR_RECV_VERSION_S 14
--#define QCA_HDR_RECV_PRIORITY_MASK GENMASK(13, 11)
--#define QCA_HDR_RECV_PRIORITY_S 11
--#define QCA_HDR_RECV_TYPE_MASK GENMASK(10, 6)
--#define QCA_HDR_RECV_TYPE_S 6
-+#define QCA_HDR_RECV_VERSION GENMASK(15, 14)
-+#define QCA_HDR_RECV_PRIORITY GENMASK(13, 11)
-+#define QCA_HDR_RECV_TYPE GENMASK(10, 6)
- #define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3)
--#define QCA_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0)
-+#define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0)
-
--#define QCA_HDR_XMIT_VERSION_MASK GENMASK(15, 14)
--#define QCA_HDR_XMIT_VERSION_S 14
--#define QCA_HDR_XMIT_PRIORITY_MASK GENMASK(13, 11)
--#define QCA_HDR_XMIT_PRIORITY_S 11
--#define QCA_HDR_XMIT_CONTROL_MASK GENMASK(10, 8)
--#define QCA_HDR_XMIT_CONTROL_S 8
-+#define QCA_HDR_XMIT_VERSION GENMASK(15, 14)
-+#define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11)
-+#define QCA_HDR_XMIT_CONTROL GENMASK(10, 8)
- #define QCA_HDR_XMIT_FROM_CPU BIT(7)
--#define QCA_HDR_XMIT_DP_BIT_MASK GENMASK(6, 0)
-+#define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0)
-
- static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
- {
-@@ -40,8 +35,9 @@ static struct sk_buff *qca_tag_xmit(stru
- phdr = dsa_etype_header_pos_tx(skb);
-
- /* Set the version field, and set destination port information */
-- hdr = QCA_HDR_VERSION << QCA_HDR_XMIT_VERSION_S |
-- QCA_HDR_XMIT_FROM_CPU | BIT(dp->index);
-+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
-+ hdr |= QCA_HDR_XMIT_FROM_CPU;
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(dp->index));
-
- *phdr = htons(hdr);
-
-@@ -62,7 +58,7 @@ static struct sk_buff *qca_tag_rcv(struc
- hdr = ntohs(*phdr);
-
- /* Make sure the version is correct */
-- ver = (hdr & QCA_HDR_RECV_VERSION_MASK) >> QCA_HDR_RECV_VERSION_S;
-+ ver = FIELD_GET(QCA_HDR_RECV_VERSION, hdr);
- if (unlikely(ver != QCA_HDR_VERSION))
- return NULL;
-
-@@ -71,7 +67,7 @@ static struct sk_buff *qca_tag_rcv(struc
- dsa_strip_etype_header(skb, QCA_HDR_LEN);
-
- /* Get source port information */
-- port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK);
-+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, hdr);
-
- skb->dev = dsa_master_find_slave(dev, 0, port);
- if (!skb->dev)
diff --git a/target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch b/target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch
deleted file mode 100644
index c1e74ceeeb..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 3ec762fb13c7e7273800b94c80db1c2cc37590d1 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:23 +0100
-Subject: [PATCH 04/16] net: dsa: tag_qca: move define to include linux/dsa
-
-Move tag_qca define to include dir linux/dsa as the qca8k require access
-to the tagger define to support in-band mdio read/write using ethernet
-packet.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/dsa/tag_qca.h | 21 +++++++++++++++++++++
- net/dsa/tag_qca.c | 16 +---------------
- 2 files changed, 22 insertions(+), 15 deletions(-)
- create mode 100644 include/linux/dsa/tag_qca.h
-
---- /dev/null
-+++ b/include/linux/dsa/tag_qca.h
-@@ -0,0 +1,21 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+
-+#ifndef __TAG_QCA_H
-+#define __TAG_QCA_H
-+
-+#define QCA_HDR_LEN 2
-+#define QCA_HDR_VERSION 0x2
-+
-+#define QCA_HDR_RECV_VERSION GENMASK(15, 14)
-+#define QCA_HDR_RECV_PRIORITY GENMASK(13, 11)
-+#define QCA_HDR_RECV_TYPE GENMASK(10, 6)
-+#define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3)
-+#define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0)
-+
-+#define QCA_HDR_XMIT_VERSION GENMASK(15, 14)
-+#define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11)
-+#define QCA_HDR_XMIT_CONTROL GENMASK(10, 8)
-+#define QCA_HDR_XMIT_FROM_CPU BIT(7)
-+#define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0)
-+
-+#endif /* __TAG_QCA_H */
---- a/net/dsa/tag_qca.c
-+++ b/net/dsa/tag_qca.c
-@@ -5,24 +5,10 @@
-
- #include <linux/etherdevice.h>
- #include <linux/bitfield.h>
-+#include <linux/dsa/tag_qca.h>
-
- #include "dsa_priv.h"
-
--#define QCA_HDR_LEN 2
--#define QCA_HDR_VERSION 0x2
--
--#define QCA_HDR_RECV_VERSION GENMASK(15, 14)
--#define QCA_HDR_RECV_PRIORITY GENMASK(13, 11)
--#define QCA_HDR_RECV_TYPE GENMASK(10, 6)
--#define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3)
--#define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0)
--
--#define QCA_HDR_XMIT_VERSION GENMASK(15, 14)
--#define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11)
--#define QCA_HDR_XMIT_CONTROL GENMASK(10, 8)
--#define QCA_HDR_XMIT_FROM_CPU BIT(7)
--#define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0)
--
- static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct dsa_port *dp = dsa_slave_to_port(dev);
diff --git a/target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch b/target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch
deleted file mode 100644
index 9394a0dabb..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 101c04c3463b87061e6a3d4f72c1bc57670685a6 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:24 +0100
-Subject: [PATCH 05/16] net: dsa: tag_qca: enable promisc_on_master flag
-
-Ethernet MDIO packets are non-standard and DSA master expects the first
-6 octets to be the MAC DA. To address these kind of packet, enable
-promisc_on_master flag for the tagger.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/tag_qca.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/net/dsa/tag_qca.c
-+++ b/net/dsa/tag_qca.c
-@@ -68,6 +68,7 @@ static const struct dsa_device_ops qca_n
- .xmit = qca_tag_xmit,
- .rcv = qca_tag_rcv,
- .needed_headroom = QCA_HDR_LEN,
-+ .promisc_on_master = true,
- };
-
- MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch b/target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch
deleted file mode 100644
index 459454e03b..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From c2ee8181fddb293d296477f60b3eb4fa3ce4e1a6 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:25 +0100
-Subject: [PATCH 06/16] net: dsa: tag_qca: add define for handling mgmt
- Ethernet packet
-
-Add all the required define to prepare support for mgmt read/write in
-Ethernet packet. Any packet of this type has to be dropped as the only
-use of these special packet is receive ack for an mgmt write request or
-receive data for an mgmt read request.
-A struct is used that emulates the Ethernet header but is used for a
-different purpose.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/dsa/tag_qca.h | 44 +++++++++++++++++++++++++++++++++++++
- net/dsa/tag_qca.c | 15 ++++++++++---
- 2 files changed, 56 insertions(+), 3 deletions(-)
-
---- a/include/linux/dsa/tag_qca.h
-+++ b/include/linux/dsa/tag_qca.h
-@@ -12,10 +12,54 @@
- #define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3)
- #define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0)
-
-+/* Packet type for recv */
-+#define QCA_HDR_RECV_TYPE_NORMAL 0x0
-+#define QCA_HDR_RECV_TYPE_MIB 0x1
-+#define QCA_HDR_RECV_TYPE_RW_REG_ACK 0x2
-+
- #define QCA_HDR_XMIT_VERSION GENMASK(15, 14)
- #define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11)
- #define QCA_HDR_XMIT_CONTROL GENMASK(10, 8)
- #define QCA_HDR_XMIT_FROM_CPU BIT(7)
- #define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0)
-
-+/* Packet type for xmit */
-+#define QCA_HDR_XMIT_TYPE_NORMAL 0x0
-+#define QCA_HDR_XMIT_TYPE_RW_REG 0x1
-+
-+/* Check code for a valid mgmt packet. Switch will ignore the packet
-+ * with this wrong.
-+ */
-+#define QCA_HDR_MGMT_CHECK_CODE_VAL 0x5
-+
-+/* Specific define for in-band MDIO read/write with Ethernet packet */
-+#define QCA_HDR_MGMT_SEQ_LEN 4 /* 4 byte for the seq */
-+#define QCA_HDR_MGMT_COMMAND_LEN 4 /* 4 byte for the command */
-+#define QCA_HDR_MGMT_DATA1_LEN 4 /* First 4 byte for the mdio data */
-+#define QCA_HDR_MGMT_HEADER_LEN (QCA_HDR_MGMT_SEQ_LEN + \
-+ QCA_HDR_MGMT_COMMAND_LEN + \
-+ QCA_HDR_MGMT_DATA1_LEN)
-+
-+#define QCA_HDR_MGMT_DATA2_LEN 12 /* Other 12 byte for the mdio data */
-+#define QCA_HDR_MGMT_PADDING_LEN 34 /* Padding to reach the min Ethernet packet */
-+
-+#define QCA_HDR_MGMT_PKT_LEN (QCA_HDR_MGMT_HEADER_LEN + \
-+ QCA_HDR_LEN + \
-+ QCA_HDR_MGMT_DATA2_LEN + \
-+ QCA_HDR_MGMT_PADDING_LEN)
-+
-+#define QCA_HDR_MGMT_SEQ_NUM GENMASK(31, 0) /* 63, 32 */
-+#define QCA_HDR_MGMT_CHECK_CODE GENMASK(31, 29) /* 31, 29 */
-+#define QCA_HDR_MGMT_CMD BIT(28) /* 28 */
-+#define QCA_HDR_MGMT_LENGTH GENMASK(23, 20) /* 23, 20 */
-+#define QCA_HDR_MGMT_ADDR GENMASK(18, 0) /* 18, 0 */
-+
-+/* Special struct emulating a Ethernet header */
-+struct qca_mgmt_ethhdr {
-+ u32 command; /* command bit 31:0 */
-+ u32 seq; /* seq 63:32 */
-+ u32 mdio_data; /* first 4byte mdio */
-+ __be16 hdr; /* qca hdr */
-+} __packed;
-+
- #endif /* __TAG_QCA_H */
---- a/net/dsa/tag_qca.c
-+++ b/net/dsa/tag_qca.c
-@@ -32,10 +32,12 @@ static struct sk_buff *qca_tag_xmit(stru
-
- static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev)
- {
-- u8 ver;
-- u16 hdr;
-- int port;
-+ u8 ver, pk_type;
- __be16 *phdr;
-+ int port;
-+ u16 hdr;
-+
-+ BUILD_BUG_ON(sizeof(struct qca_mgmt_ethhdr) != QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);
-
- if (unlikely(!pskb_may_pull(skb, QCA_HDR_LEN)))
- return NULL;
-@@ -48,6 +50,13 @@ static struct sk_buff *qca_tag_rcv(struc
- if (unlikely(ver != QCA_HDR_VERSION))
- return NULL;
-
-+ /* Get pk type */
-+ pk_type = FIELD_GET(QCA_HDR_RECV_TYPE, hdr);
-+
-+ /* Ethernet MDIO read/write packet */
-+ if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK)
-+ return NULL;
-+
- /* Remove QCA tag and recalculate checksum */
- skb_pull_rcsum(skb, QCA_HDR_LEN);
- dsa_strip_etype_header(skb, QCA_HDR_LEN);
diff --git a/target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch b/target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch
deleted file mode 100644
index 7e5dc65730..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 18be654a4345f7d937b4bfbad74bea8093e3a93c Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:26 +0100
-Subject: [PATCH 07/16] net: dsa: tag_qca: add define for handling MIB packet
-
-Add struct to correctly parse a mib Ethernet packet.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/dsa/tag_qca.h | 10 ++++++++++
- net/dsa/tag_qca.c | 4 ++++
- 2 files changed, 14 insertions(+)
-
---- a/include/linux/dsa/tag_qca.h
-+++ b/include/linux/dsa/tag_qca.h
-@@ -62,4 +62,14 @@ struct qca_mgmt_ethhdr {
- __be16 hdr; /* qca hdr */
- } __packed;
-
-+enum mdio_cmd {
-+ MDIO_WRITE = 0x0,
-+ MDIO_READ
-+};
-+
-+struct mib_ethhdr {
-+ u32 data[3]; /* first 3 mib counter */
-+ __be16 hdr; /* qca hdr */
-+} __packed;
-+
- #endif /* __TAG_QCA_H */
---- a/net/dsa/tag_qca.c
-+++ b/net/dsa/tag_qca.c
-@@ -57,6 +57,10 @@ static struct sk_buff *qca_tag_rcv(struc
- if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK)
- return NULL;
-
-+ /* Ethernet MIB counter packet */
-+ if (pk_type == QCA_HDR_RECV_TYPE_MIB)
-+ return NULL;
-+
- /* Remove QCA tag and recalculate checksum */
- skb_pull_rcsum(skb, QCA_HDR_LEN);
- dsa_strip_etype_header(skb, QCA_HDR_LEN);
diff --git a/target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch b/target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch
deleted file mode 100644
index ad25da30e6..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 31eb6b4386ad91930417e3f5c8157a4b5e31cbd5 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:27 +0100
-Subject: [PATCH 08/16] net: dsa: tag_qca: add support for handling mgmt and
- MIB Ethernet packet
-
-Add connect/disconnect helper to assign private struct to the DSA switch.
-Add support for Ethernet mgmt and MIB if the DSA driver provide an handler
-to correctly parse and elaborate the data.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/dsa/tag_qca.h | 7 +++++++
- net/dsa/tag_qca.c | 39 ++++++++++++++++++++++++++++++++++---
- 2 files changed, 43 insertions(+), 3 deletions(-)
-
---- a/include/linux/dsa/tag_qca.h
-+++ b/include/linux/dsa/tag_qca.h
-@@ -72,4 +72,11 @@ struct mib_ethhdr {
- __be16 hdr; /* qca hdr */
- } __packed;
-
-+struct qca_tagger_data {
-+ void (*rw_reg_ack_handler)(struct dsa_switch *ds,
-+ struct sk_buff *skb);
-+ void (*mib_autocast_handler)(struct dsa_switch *ds,
-+ struct sk_buff *skb);
-+};
-+
- #endif /* __TAG_QCA_H */
---- a/net/dsa/tag_qca.c
-+++ b/net/dsa/tag_qca.c
-@@ -5,6 +5,7 @@
-
- #include <linux/etherdevice.h>
- #include <linux/bitfield.h>
-+#include <net/dsa.h>
- #include <linux/dsa/tag_qca.h>
-
- #include "dsa_priv.h"
-@@ -32,6 +33,9 @@ static struct sk_buff *qca_tag_xmit(stru
-
- static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev)
- {
-+ struct qca_tagger_data *tagger_data;
-+ struct dsa_port *dp = dev->dsa_ptr;
-+ struct dsa_switch *ds = dp->ds;
- u8 ver, pk_type;
- __be16 *phdr;
- int port;
-@@ -39,6 +43,8 @@ static struct sk_buff *qca_tag_rcv(struc
-
- BUILD_BUG_ON(sizeof(struct qca_mgmt_ethhdr) != QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);
-
-+ tagger_data = ds->tagger_data;
-+
- if (unlikely(!pskb_may_pull(skb, QCA_HDR_LEN)))
- return NULL;
-
-@@ -53,13 +59,19 @@ static struct sk_buff *qca_tag_rcv(struc
- /* Get pk type */
- pk_type = FIELD_GET(QCA_HDR_RECV_TYPE, hdr);
-
-- /* Ethernet MDIO read/write packet */
-- if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK)
-+ /* Ethernet mgmt read/write packet */
-+ if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK) {
-+ if (likely(tagger_data->rw_reg_ack_handler))
-+ tagger_data->rw_reg_ack_handler(ds, skb);
- return NULL;
-+ }
-
- /* Ethernet MIB counter packet */
-- if (pk_type == QCA_HDR_RECV_TYPE_MIB)
-+ if (pk_type == QCA_HDR_RECV_TYPE_MIB) {
-+ if (likely(tagger_data->mib_autocast_handler))
-+ tagger_data->mib_autocast_handler(ds, skb);
- return NULL;
-+ }
-
- /* Remove QCA tag and recalculate checksum */
- skb_pull_rcsum(skb, QCA_HDR_LEN);
-@@ -75,9 +87,30 @@ static struct sk_buff *qca_tag_rcv(struc
- return skb;
- }
-
-+static int qca_tag_connect(struct dsa_switch *ds)
-+{
-+ struct qca_tagger_data *tagger_data;
-+
-+ tagger_data = kzalloc(sizeof(*tagger_data), GFP_KERNEL);
-+ if (!tagger_data)
-+ return -ENOMEM;
-+
-+ ds->tagger_data = tagger_data;
-+
-+ return 0;
-+}
-+
-+static void qca_tag_disconnect(struct dsa_switch *ds)
-+{
-+ kfree(ds->tagger_data);
-+ ds->tagger_data = NULL;
-+}
-+
- static const struct dsa_device_ops qca_netdev_ops = {
- .name = "qca",
- .proto = DSA_TAG_PROTO_QCA,
-+ .connect = qca_tag_connect,
-+ .disconnect = qca_tag_disconnect,
- .xmit = qca_tag_xmit,
- .rcv = qca_tag_rcv,
- .needed_headroom = QCA_HDR_LEN,
diff --git a/target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch b/target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch
deleted file mode 100644
index eb21cc3912..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From cddbec19466a1dfb4d45ddd507d9f09f991d54ae Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:28 +0100
-Subject: [PATCH 09/16] net: dsa: qca8k: add tracking state of master port
-
-MDIO/MIB Ethernet require the master port and the tagger availabale to
-correctly work. Use the new api master_state_change to track when master
-is operational or not and set a bool in qca8k_priv.
-We cache the first cached master available and we check if other cpu
-port are operational when the cached one goes down.
-This cached master will later be used by mdio read/write and mib request to
-correctly use the working function.
-
-qca8k implementation for MDIO/MIB Ethernet is bad. CPU port0 is the only
-one that answers with the ack packet or sends MIB Ethernet packets. For
-this reason the master_state_change ignore CPU port6 and only checks
-CPU port0 if it's operational and enables this mode.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 15 +++++++++++++++
- drivers/net/dsa/qca8k.h | 1 +
- 2 files changed, 16 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -2401,6 +2401,20 @@ qca8k_port_lag_leave(struct dsa_switch *
- return qca8k_lag_refresh_portmap(ds, port, lag, true);
- }
-
-+static void
-+qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
-+ bool operational)
-+{
-+ struct dsa_port *dp = master->dsa_ptr;
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Ethernet MIB/MDIO is only supported for CPU port 0 */
-+ if (dp->index != 0)
-+ return;
-+
-+ priv->mgmt_master = operational ? (struct net_device *)master : NULL;
-+}
-+
- static const struct dsa_switch_ops qca8k_switch_ops = {
- .get_tag_protocol = qca8k_get_tag_protocol,
- .setup = qca8k_setup,
-@@ -2436,6 +2450,7 @@ static const struct dsa_switch_ops qca8k
- .get_phy_flags = qca8k_get_phy_flags,
- .port_lag_join = qca8k_port_lag_join,
- .port_lag_leave = qca8k_port_lag_leave,
-+ .master_state_change = qca8k_master_change,
- };
-
- static int qca8k_read_switch_id(struct qca8k_priv *priv)
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -353,6 +353,7 @@ struct qca8k_priv {
- struct dsa_switch_ops ops;
- struct gpio_desc *reset_gpio;
- unsigned int port_mtu[QCA8K_NUM_PORTS];
-+ struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
- };
-
- struct qca8k_mib_desc {
diff --git a/target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch b/target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch
deleted file mode 100644
index 07c5ba4621..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch
+++ /dev/null
@@ -1,363 +0,0 @@
-From 5950c7c0a68c915b336c70f79388626e2d576ab7 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:29 +0100
-Subject: [PATCH 10/16] net: dsa: qca8k: add support for mgmt read/write in
- Ethernet packet
-
-Add qca8k side support for mgmt read/write in Ethernet packet.
-qca8k supports some specially crafted Ethernet packet that can be used
-for mgmt read/write instead of the legacy method uart/internal mdio.
-This add support for the qca8k side to craft the packet and enqueue it.
-Each port and the qca8k_priv have a special struct to put data in it.
-The completion API is used to wait for the packet to be received back
-with the requested data.
-
-The various steps are:
-1. Craft the special packet with the qca hdr set to mgmt read/write
- mode.
-2. Set the lock in the dedicated mgmt struct.
-3. Increment the seq number and set it in the mgmt pkt
-4. Reinit the completion.
-5. Enqueue the packet.
-6. Wait the packet to be received.
-7. Use the data set by the tagger to complete the mdio operation.
-
-If the completion timeouts or the ack value is not true, the legacy
-mdio way is used.
-
-It has to be considered that in the initial setup mdio is still used and
-mdio is still used until DSA is ready to accept and tag packet.
-
-tag_proto_connect() is used to fill the required handler for the tagger
-to correctly parse and elaborate the special Ethernet mdio packet.
-
-Locking is added to qca8k_master_change() to make sure no mgmt Ethernet
-are in progress.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 225 ++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 13 +++
- 2 files changed, 238 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -20,6 +20,7 @@
- #include <linux/phylink.h>
- #include <linux/gpio/consumer.h>
- #include <linux/etherdevice.h>
-+#include <linux/dsa/tag_qca.h>
-
- #include "qca8k.h"
-
-@@ -170,6 +171,194 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r
- return regmap_update_bits(priv->regmap, reg, mask, write_val);
- }
-
-+static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ u8 len, cmd;
-+
-+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
-+ mgmt_eth_data = &priv->mgmt_eth_data;
-+
-+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
-+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
-+
-+ /* Make sure the seq match the requested packet */
-+ if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
-+ mgmt_eth_data->ack = true;
-+
-+ if (cmd == MDIO_READ) {
-+ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
-+
-+ /* Get the rest of the 12 byte of data */
-+ if (len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(mgmt_eth_data->data + 1, skb->data,
-+ QCA_HDR_MGMT_DATA2_LEN);
-+ }
-+
-+ complete(&mgmt_eth_data->rw_done);
-+}
-+
-+static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,
-+ int priority)
-+{
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ struct sk_buff *skb;
-+ u16 hdr;
-+
-+ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
-+ if (!skb)
-+ return NULL;
-+
-+ skb_reset_mac_header(skb);
-+ skb_set_network_header(skb, skb->len);
-+
-+ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);
-+
-+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority);
-+ hdr |= QCA_HDR_XMIT_FROM_CPU;
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
-+
-+ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, 4);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
-+ QCA_HDR_MGMT_CHECK_CODE_VAL);
-+
-+ if (cmd == MDIO_WRITE)
-+ mgmt_ethhdr->mdio_data = *val;
-+
-+ mgmt_ethhdr->hdr = htons(hdr);
-+
-+ skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-+
-+ return skb;
-+}
-+
-+static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
-+{
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+
-+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
-+ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
-+}
-+
-+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-+ struct sk_buff *skb;
-+ bool ack;
-+ int ret;
-+
-+ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,
-+ QCA8K_ETHERNET_MDIO_PRIORITY);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check mgmt_master if is operational */
-+ if (!priv->mgmt_master) {
-+ kfree_skb(skb);
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ return -EINVAL;
-+ }
-+
-+ skb->dev = priv->mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the mdio pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
-+
-+ *val = mgmt_eth_data->data[0];
-+ ack = mgmt_eth_data->ack;
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 val)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-+ struct sk_buff *skb;
-+ bool ack;
-+ int ret;
-+
-+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, &val,
-+ QCA8K_ETHERNET_MDIO_PRIORITY);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check mgmt_master if is operational */
-+ if (!priv->mgmt_master) {
-+ kfree_skb(skb);
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ return -EINVAL;
-+ }
-+
-+ skb->dev = priv->mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the mdio pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+{
-+ u32 val = 0;
-+ int ret;
-+
-+ ret = qca8k_read_eth(priv, reg, &val);
-+ if (ret)
-+ return ret;
-+
-+ val &= ~mask;
-+ val |= write_val;
-+
-+ return qca8k_write_eth(priv, reg, val);
-+}
-+
- static int
- qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
- {
-@@ -178,6 +367,9 @@ qca8k_regmap_read(void *ctx, uint32_t re
- u16 r1, r2, page;
- int ret;
-
-+ if (!qca8k_read_eth(priv, reg, val))
-+ return 0;
-+
- qca8k_split_addr(reg, &r1, &r2, &page);
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-@@ -201,6 +393,9 @@ qca8k_regmap_write(void *ctx, uint32_t r
- u16 r1, r2, page;
- int ret;
-
-+ if (!qca8k_write_eth(priv, reg, val))
-+ return 0;
-+
- qca8k_split_addr(reg, &r1, &r2, &page);
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-@@ -225,6 +420,9 @@ qca8k_regmap_update_bits(void *ctx, uint
- u32 val;
- int ret;
-
-+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
-+ return 0;
-+
- qca8k_split_addr(reg, &r1, &r2, &page);
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-@@ -2412,7 +2610,30 @@ qca8k_master_change(struct dsa_switch *d
- if (dp->index != 0)
- return;
-
-+ mutex_lock(&priv->mgmt_eth_data.mutex);
-+
- priv->mgmt_master = operational ? (struct net_device *)master : NULL;
-+
-+ mutex_unlock(&priv->mgmt_eth_data.mutex);
-+}
-+
-+static int qca8k_connect_tag_protocol(struct dsa_switch *ds,
-+ enum dsa_tag_protocol proto)
-+{
-+ struct qca_tagger_data *tagger_data;
-+
-+ switch (proto) {
-+ case DSA_TAG_PROTO_QCA:
-+ tagger_data = ds->tagger_data;
-+
-+ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler;
-+
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return 0;
- }
-
- static const struct dsa_switch_ops qca8k_switch_ops = {
-@@ -2451,6 +2672,7 @@ static const struct dsa_switch_ops qca8k
- .port_lag_join = qca8k_port_lag_join,
- .port_lag_leave = qca8k_port_lag_leave,
- .master_state_change = qca8k_master_change,
-+ .connect_tag_protocol = qca8k_connect_tag_protocol,
- };
-
- static int qca8k_read_switch_id(struct qca8k_priv *priv)
-@@ -2530,6 +2752,9 @@ qca8k_sw_probe(struct mdio_device *mdiod
- if (!priv->ds)
- return -ENOMEM;
-
-+ mutex_init(&priv->mgmt_eth_data.mutex);
-+ init_completion(&priv->mgmt_eth_data.rw_done);
-+
- priv->ds->dev = &mdiodev->dev;
- priv->ds->num_ports = QCA8K_NUM_PORTS;
- priv->ds->priv = priv;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -11,6 +11,10 @@
- #include <linux/delay.h>
- #include <linux/regmap.h>
- #include <linux/gpio.h>
-+#include <linux/dsa/tag_qca.h>
-+
-+#define QCA8K_ETHERNET_MDIO_PRIORITY 7
-+#define QCA8K_ETHERNET_TIMEOUT 100
-
- #define QCA8K_NUM_PORTS 7
- #define QCA8K_NUM_CPU_PORTS 2
-@@ -328,6 +332,14 @@ enum {
- QCA8K_CPU_PORT6,
- };
-
-+struct qca8k_mgmt_eth_data {
-+ struct completion rw_done;
-+ struct mutex mutex; /* Enforce one mdio read/write at time */
-+ bool ack;
-+ u32 seq;
-+ u32 data[4];
-+};
-+
- struct qca8k_ports_config {
- bool sgmii_rx_clk_falling_edge;
- bool sgmii_tx_clk_falling_edge;
-@@ -354,6 +366,7 @@ struct qca8k_priv {
- struct gpio_desc *reset_gpio;
- unsigned int port_mtu[QCA8K_NUM_PORTS];
- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
-+ struct qca8k_mgmt_eth_data mgmt_eth_data;
- };
-
- struct qca8k_mib_desc {
diff --git a/target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch b/target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch
deleted file mode 100644
index 0dcf279433..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch
+++ /dev/null
@@ -1,226 +0,0 @@
-From 5c957c7ca78cce5e4b96866722b0115bd758d945 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:30 +0100
-Subject: [PATCH 11/16] net: dsa: qca8k: add support for mib autocast in
- Ethernet packet
-
-The switch can autocast MIB counter using Ethernet packet.
-Add support for this and provide a handler for the tagger.
-The switch will send packet with MIB counter for each port, the switch
-will use completion API to wait for the correct packet to be received
-and will complete the task only when each packet is received.
-Although the handler will drop all the other packet, we still have to
-consume each MIB packet to complete the request. This is done to prevent
-mixed data with concurrent ethtool request.
-
-connect_tag_protocol() is used to add the handler to the tag_qca tagger,
-master_state_change() use the MIB lock to make sure no MIB Ethernet is
-in progress.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 106 +++++++++++++++++++++++++++++++++++++++-
- drivers/net/dsa/qca8k.h | 17 ++++++-
- 2 files changed, 121 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -830,7 +830,10 @@ qca8k_mib_init(struct qca8k_priv *priv)
- int ret;
-
- mutex_lock(&priv->reg_mutex);
-- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
-+ QCA8K_MIB_BUSY);
- if (ret)
- goto exit;
-
-@@ -1901,6 +1904,97 @@ qca8k_get_strings(struct dsa_switch *ds,
- ETH_GSTRING_LEN);
- }
-
-+static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
-+{
-+ const struct qca8k_match_data *match_data;
-+ struct qca8k_mib_eth_data *mib_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ const struct qca8k_mib_desc *mib;
-+ struct mib_ethhdr *mib_ethhdr;
-+ int i, mib_len, offset = 0;
-+ u64 *data;
-+ u8 port;
-+
-+ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
-+ mib_eth_data = &priv->mib_eth_data;
-+
-+ /* The switch autocast every port. Ignore other packet and
-+ * parse only the requested one.
-+ */
-+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr));
-+ if (port != mib_eth_data->req_port)
-+ goto exit;
-+
-+ match_data = device_get_match_data(priv->dev);
-+ data = mib_eth_data->data;
-+
-+ for (i = 0; i < match_data->mib_count; i++) {
-+ mib = &ar8327_mib[i];
-+
-+ /* First 3 mib are present in the skb head */
-+ if (i < 3) {
-+ data[i] = mib_ethhdr->data[i];
-+ continue;
-+ }
-+
-+ mib_len = sizeof(uint32_t);
-+
-+ /* Some mib are 64 bit wide */
-+ if (mib->size == 2)
-+ mib_len = sizeof(uint64_t);
-+
-+ /* Copy the mib value from packet to the */
-+ memcpy(data + i, skb->data + offset, mib_len);
-+
-+ /* Set the offset for the next mib */
-+ offset += mib_len;
-+ }
-+
-+exit:
-+ /* Complete on receiving all the mib packet */
-+ if (refcount_dec_and_test(&mib_eth_data->port_parsed))
-+ complete(&mib_eth_data->rw_done);
-+}
-+
-+static int
-+qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
-+{
-+ struct dsa_port *dp = dsa_to_port(ds, port);
-+ struct qca8k_mib_eth_data *mib_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ mib_eth_data = &priv->mib_eth_data;
-+
-+ mutex_lock(&mib_eth_data->mutex);
-+
-+ reinit_completion(&mib_eth_data->rw_done);
-+
-+ mib_eth_data->req_port = dp->index;
-+ mib_eth_data->data = data;
-+ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS);
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ /* Send mib autocast request */
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) |
-+ QCA8K_MIB_BUSY);
-+
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ if (ret)
-+ goto exit;
-+
-+ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT);
-+
-+exit:
-+ mutex_unlock(&mib_eth_data->mutex);
-+
-+ return ret;
-+}
-+
- static void
- qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *data)
-@@ -1912,6 +2006,10 @@ qca8k_get_ethtool_stats(struct dsa_switc
- u32 hi = 0;
- int ret;
-
-+ if (priv->mgmt_master &&
-+ qca8k_get_ethtool_stats_eth(ds, port, data) > 0)
-+ return;
-+
- match_data = of_device_get_match_data(priv->dev);
-
- for (i = 0; i < match_data->mib_count; i++) {
-@@ -2611,9 +2709,11 @@ qca8k_master_change(struct dsa_switch *d
- return;
-
- mutex_lock(&priv->mgmt_eth_data.mutex);
-+ mutex_lock(&priv->mib_eth_data.mutex);
-
- priv->mgmt_master = operational ? (struct net_device *)master : NULL;
-
-+ mutex_unlock(&priv->mib_eth_data.mutex);
- mutex_unlock(&priv->mgmt_eth_data.mutex);
- }
-
-@@ -2627,6 +2727,7 @@ static int qca8k_connect_tag_protocol(st
- tagger_data = ds->tagger_data;
-
- tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler;
-+ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler;
-
- break;
- default:
-@@ -2755,6 +2856,9 @@ qca8k_sw_probe(struct mdio_device *mdiod
- mutex_init(&priv->mgmt_eth_data.mutex);
- init_completion(&priv->mgmt_eth_data.rw_done);
-
-+ mutex_init(&priv->mib_eth_data.mutex);
-+ init_completion(&priv->mib_eth_data.rw_done);
-+
- priv->ds->dev = &mdiodev->dev;
- priv->ds->num_ports = QCA8K_NUM_PORTS;
- priv->ds->priv = priv;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -67,7 +67,7 @@
- #define QCA8K_REG_MODULE_EN 0x030
- #define QCA8K_MODULE_EN_MIB BIT(0)
- #define QCA8K_REG_MIB 0x034
--#define QCA8K_MIB_FLUSH BIT(24)
-+#define QCA8K_MIB_FUNC GENMASK(26, 24)
- #define QCA8K_MIB_CPU_KEEP BIT(20)
- #define QCA8K_MIB_BUSY BIT(17)
- #define QCA8K_MDIO_MASTER_CTRL 0x3c
-@@ -317,6 +317,12 @@ enum qca8k_vlan_cmd {
- QCA8K_VLAN_READ = 6,
- };
-
-+enum qca8k_mid_cmd {
-+ QCA8K_MIB_FLUSH = 1,
-+ QCA8K_MIB_FLUSH_PORT = 2,
-+ QCA8K_MIB_CAST = 3,
-+};
-+
- struct ar8xxx_port_status {
- int enabled;
- };
-@@ -340,6 +346,14 @@ struct qca8k_mgmt_eth_data {
- u32 data[4];
- };
-
-+struct qca8k_mib_eth_data {
-+ struct completion rw_done;
-+ struct mutex mutex; /* Process one command at time */
-+ refcount_t port_parsed; /* Counter to track parsed port */
-+ u8 req_port;
-+ u64 *data; /* pointer to ethtool data */
-+};
-+
- struct qca8k_ports_config {
- bool sgmii_rx_clk_falling_edge;
- bool sgmii_tx_clk_falling_edge;
-@@ -367,6 +381,7 @@ struct qca8k_priv {
- unsigned int port_mtu[QCA8K_NUM_PORTS];
- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
- struct qca8k_mgmt_eth_data mgmt_eth_data;
-+ struct qca8k_mib_eth_data mib_eth_data;
- };
-
- struct qca8k_mib_desc {
diff --git a/target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch b/target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch
deleted file mode 100644
index f5899eb590..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-From 2cd5485663847d468dc207b3ff85fb1fab44d97f Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:31 +0100
-Subject: [PATCH 12/16] net: dsa: qca8k: add support for phy read/write with
- mgmt Ethernet
-
-Use mgmt Ethernet also for phy read/write if availabale. Use a different
-seq number to make sure we receive the correct packet.
-On any error, we fallback to the legacy mdio read/write.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 216 ++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 1 +
- 2 files changed, 217 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -867,6 +867,199 @@ qca8k_port_set_status(struct qca8k_priv
- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
- }
-
-+static int
-+qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
-+ struct sk_buff *read_skb, u32 *val)
-+{
-+ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL);
-+ bool ack;
-+ int ret;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the copy pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ *val = mgmt_eth_data->data[0];
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,
-+ int regnum, u16 data)
-+{
-+ struct sk_buff *write_skb, *clear_skb, *read_skb;
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data;
-+ u32 write_val, clear_val = 0, val;
-+ struct net_device *mgmt_master;
-+ int ret, ret1;
-+ bool ack;
-+
-+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-+ return -EINVAL;
-+
-+ mgmt_eth_data = &priv->mgmt_eth_data;
-+
-+ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-+ QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
-+
-+ if (read) {
-+ write_val |= QCA8K_MDIO_MASTER_READ;
-+ } else {
-+ write_val |= QCA8K_MDIO_MASTER_WRITE;
-+ write_val |= QCA8K_MDIO_MASTER_DATA(data);
-+ }
-+
-+ /* Prealloc all the needed skb before the lock */
-+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL,
-+ &write_val, QCA8K_ETHERNET_PHY_PRIORITY);
-+ if (!write_skb)
-+ return -ENOMEM;
-+
-+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL,
-+ &clear_val, QCA8K_ETHERNET_PHY_PRIORITY);
-+ if (!write_skb) {
-+ ret = -ENOMEM;
-+ goto err_clear_skb;
-+ }
-+
-+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL,
-+ &clear_val, QCA8K_ETHERNET_PHY_PRIORITY);
-+ if (!write_skb) {
-+ ret = -ENOMEM;
-+ goto err_read_skb;
-+ }
-+
-+ /* Actually start the request:
-+ * 1. Send mdio master packet
-+ * 2. Busy Wait for mdio master command
-+ * 3. Get the data if we are reading
-+ * 4. Reset the mdio master (even with error)
-+ */
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check if mgmt_master is operational */
-+ mgmt_master = priv->mgmt_master;
-+ if (!mgmt_master) {
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ ret = -EINVAL;
-+ goto err_mgmt_master;
-+ }
-+
-+ read_skb->dev = mgmt_master;
-+ clear_skb->dev = mgmt_master;
-+ write_skb->dev = mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the write pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(write_skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0) {
-+ ret = -ETIMEDOUT;
-+ kfree_skb(read_skb);
-+ goto exit;
-+ }
-+
-+ if (!ack) {
-+ ret = -EINVAL;
-+ kfree_skb(read_skb);
-+ goto exit;
-+ }
-+
-+ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1,
-+ !(val & QCA8K_MDIO_MASTER_BUSY), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-+ mgmt_eth_data, read_skb, &val);
-+
-+ if (ret < 0 && ret1 < 0) {
-+ ret = ret1;
-+ goto exit;
-+ }
-+
-+ if (read) {
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the read pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(read_skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0) {
-+ ret = -ETIMEDOUT;
-+ goto exit;
-+ }
-+
-+ if (!ack) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK;
-+ } else {
-+ kfree_skb(read_skb);
-+ }
-+exit:
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the clear pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(clear_skb);
-+
-+ wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ return ret;
-+
-+ /* Error handling before lock */
-+err_mgmt_master:
-+ kfree_skb(read_skb);
-+err_read_skb:
-+ kfree_skb(clear_skb);
-+err_clear_skb:
-+ kfree_skb(write_skb);
-+
-+ return ret;
-+}
-+
- static u32
- qca8k_port_to_phy(int port)
- {
-@@ -989,6 +1182,12 @@ qca8k_internal_mdio_write(struct mii_bus
- {
- struct qca8k_priv *priv = slave_bus->priv;
- struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data);
-+ if (!ret)
-+ return 0;
-
- return qca8k_mdio_write(bus, phy, regnum, data);
- }
-@@ -998,6 +1197,12 @@ qca8k_internal_mdio_read(struct mii_bus
- {
- struct qca8k_priv *priv = slave_bus->priv;
- struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0);
-+ if (ret >= 0)
-+ return ret;
-
- return qca8k_mdio_read(bus, phy, regnum);
- }
-@@ -1006,6 +1211,7 @@ static int
- qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
- {
- struct qca8k_priv *priv = ds->priv;
-+ int ret;
-
- /* Check if the legacy mapping should be used and the
- * port is not correctly mapped to the right PHY in the
-@@ -1014,6 +1220,11 @@ qca8k_phy_write(struct dsa_switch *ds, i
- if (priv->legacy_phy_port_mapping)
- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, false, port, regnum, 0);
-+ if (!ret)
-+ return ret;
-+
- return qca8k_mdio_write(priv->bus, port, regnum, data);
- }
-
-@@ -1030,6 +1241,11 @@ qca8k_phy_read(struct dsa_switch *ds, in
- if (priv->legacy_phy_port_mapping)
- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, true, port, regnum, 0);
-+ if (ret >= 0)
-+ return ret;
-+
- ret = qca8k_mdio_read(priv->bus, port, regnum);
-
- if (ret < 0)
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -14,6 +14,7 @@
- #include <linux/dsa/tag_qca.h>
-
- #define QCA8K_ETHERNET_MDIO_PRIORITY 7
-+#define QCA8K_ETHERNET_PHY_PRIORITY 6
- #define QCA8K_ETHERNET_TIMEOUT 100
-
- #define QCA8K_NUM_PORTS 7
diff --git a/target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch b/target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch
deleted file mode 100644
index 4ac0bc32fd..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch
+++ /dev/null
@@ -1,208 +0,0 @@
-From 4264350acb75430d5021a1d7de56a33faf69a097 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:32 +0100
-Subject: [PATCH 13/16] net: dsa: qca8k: move page cache to driver priv
-
-There can be multiple qca8k switch on the same system. Move the static
-qca8k_current_page to qca8k_priv and make it specific for each switch.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 42 ++++++++++++++++++++---------------------
- drivers/net/dsa/qca8k.h | 9 +++++++++
- 2 files changed, 29 insertions(+), 22 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -75,12 +75,6 @@ static const struct qca8k_mib_desc ar832
- MIB_DESC(1, 0xac, "TXUnicast"),
- };
-
--/* The 32bit switch registers are accessed indirectly. To achieve this we need
-- * to set the page of the register. Track the last page that was set to reduce
-- * mdio writes
-- */
--static u16 qca8k_current_page = 0xffff;
--
- static void
- qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
- {
-@@ -134,11 +128,13 @@ qca8k_mii_write32(struct mii_bus *bus, i
- }
-
- static int
--qca8k_set_page(struct mii_bus *bus, u16 page)
-+qca8k_set_page(struct qca8k_priv *priv, u16 page)
- {
-+ u16 *cached_page = &priv->mdio_cache.page;
-+ struct mii_bus *bus = priv->bus;
- int ret;
-
-- if (page == qca8k_current_page)
-+ if (page == *cached_page)
- return 0;
-
- ret = bus->write(bus, 0x18, 0, page);
-@@ -148,7 +144,7 @@ qca8k_set_page(struct mii_bus *bus, u16
- return ret;
- }
-
-- qca8k_current_page = page;
-+ *cached_page = page;
- usleep_range(1000, 2000);
- return 0;
- }
-@@ -374,7 +370,7 @@ qca8k_regmap_read(void *ctx, uint32_t re
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-
-- ret = qca8k_set_page(bus, page);
-+ ret = qca8k_set_page(priv, page);
- if (ret < 0)
- goto exit;
-
-@@ -400,7 +396,7 @@ qca8k_regmap_write(void *ctx, uint32_t r
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-
-- ret = qca8k_set_page(bus, page);
-+ ret = qca8k_set_page(priv, page);
- if (ret < 0)
- goto exit;
-
-@@ -427,7 +423,7 @@ qca8k_regmap_update_bits(void *ctx, uint
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-
-- ret = qca8k_set_page(bus, page);
-+ ret = qca8k_set_page(priv, page);
- if (ret < 0)
- goto exit;
-
-@@ -1098,8 +1094,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
- }
-
- static int
--qca8k_mdio_write(struct mii_bus *bus, int phy, int regnum, u16 data)
-+qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
- {
-+ struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- u32 val;
- int ret;
-@@ -1116,7 +1113,7 @@ qca8k_mdio_write(struct mii_bus *bus, in
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-
-- ret = qca8k_set_page(bus, page);
-+ ret = qca8k_set_page(priv, page);
- if (ret)
- goto exit;
-
-@@ -1135,8 +1132,9 @@ exit:
- }
-
- static int
--qca8k_mdio_read(struct mii_bus *bus, int phy, int regnum)
-+qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
- {
-+ struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- u32 val;
- int ret;
-@@ -1152,7 +1150,7 @@ qca8k_mdio_read(struct mii_bus *bus, int
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-
-- ret = qca8k_set_page(bus, page);
-+ ret = qca8k_set_page(priv, page);
- if (ret)
- goto exit;
-
-@@ -1181,7 +1179,6 @@ static int
- qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
- {
- struct qca8k_priv *priv = slave_bus->priv;
-- struct mii_bus *bus = priv->bus;
- int ret;
-
- /* Use mdio Ethernet when available, fallback to legacy one on error */
-@@ -1189,14 +1186,13 @@ qca8k_internal_mdio_write(struct mii_bus
- if (!ret)
- return 0;
-
-- return qca8k_mdio_write(bus, phy, regnum, data);
-+ return qca8k_mdio_write(priv, phy, regnum, data);
- }
-
- static int
- qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
- {
- struct qca8k_priv *priv = slave_bus->priv;
-- struct mii_bus *bus = priv->bus;
- int ret;
-
- /* Use mdio Ethernet when available, fallback to legacy one on error */
-@@ -1204,7 +1200,7 @@ qca8k_internal_mdio_read(struct mii_bus
- if (ret >= 0)
- return ret;
-
-- return qca8k_mdio_read(bus, phy, regnum);
-+ return qca8k_mdio_read(priv, phy, regnum);
- }
-
- static int
-@@ -1225,7 +1221,7 @@ qca8k_phy_write(struct dsa_switch *ds, i
- if (!ret)
- return ret;
-
-- return qca8k_mdio_write(priv->bus, port, regnum, data);
-+ return qca8k_mdio_write(priv, port, regnum, data);
- }
-
- static int
-@@ -1246,7 +1242,7 @@ qca8k_phy_read(struct dsa_switch *ds, in
- if (ret >= 0)
- return ret;
-
-- ret = qca8k_mdio_read(priv->bus, port, regnum);
-+ ret = qca8k_mdio_read(priv, port, regnum);
-
- if (ret < 0)
- return 0xffff;
-@@ -3060,6 +3056,8 @@ qca8k_sw_probe(struct mdio_device *mdiod
- return PTR_ERR(priv->regmap);
- }
-
-+ priv->mdio_cache.page = 0xffff;
-+
- /* Check the detected switch id */
- ret = qca8k_read_switch_id(priv);
- if (ret)
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -363,6 +363,14 @@ struct qca8k_ports_config {
- u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
- };
-
-+struct qca8k_mdio_cache {
-+/* The 32bit switch registers are accessed indirectly. To achieve this we need
-+ * to set the page of the register. Track the last page that was set to reduce
-+ * mdio writes
-+ */
-+ u16 page;
-+};
-+
- struct qca8k_priv {
- u8 switch_id;
- u8 switch_revision;
-@@ -383,6 +391,7 @@ struct qca8k_priv {
- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
- struct qca8k_mgmt_eth_data mgmt_eth_data;
- struct qca8k_mib_eth_data mib_eth_data;
-+ struct qca8k_mdio_cache mdio_cache;
- };
-
- struct qca8k_mib_desc {
diff --git a/target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch b/target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch
deleted file mode 100644
index e2cb2721ce..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-From 2481d206fae7884cd07014fd1318e63af35e99eb Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:33 +0100
-Subject: [PATCH 14/16] net: dsa: qca8k: cache lo and hi for mdio write
-
-From Documentation, we can cache lo and hi the same way we do with the
-page. This massively reduce the mdio write as 3/4 of the time as we only
-require to write the lo or hi part for a mdio write.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 61 +++++++++++++++++++++++++++++++++--------
- drivers/net/dsa/qca8k.h | 5 ++++
- 2 files changed, 54 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -89,6 +89,44 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u
- }
-
- static int
-+qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
-+{
-+ u16 *cached_lo = &priv->mdio_cache.lo;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (lo == *cached_lo)
-+ return 0;
-+
-+ ret = bus->write(bus, phy_id, regnum, lo);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit lo register\n");
-+
-+ *cached_lo = lo;
-+ return 0;
-+}
-+
-+static int
-+qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
-+{
-+ u16 *cached_hi = &priv->mdio_cache.hi;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (hi == *cached_hi)
-+ return 0;
-+
-+ ret = bus->write(bus, phy_id, regnum, hi);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit hi register\n");
-+
-+ *cached_hi = hi;
-+ return 0;
-+}
-+
-+static int
- qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
- {
- int ret;
-@@ -111,7 +149,7 @@ qca8k_mii_read32(struct mii_bus *bus, in
- }
-
- static void
--qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
-+qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
- {
- u16 lo, hi;
- int ret;
-@@ -119,12 +157,9 @@ qca8k_mii_write32(struct mii_bus *bus, i
- lo = val & 0xffff;
- hi = (u16)(val >> 16);
-
-- ret = bus->write(bus, phy_id, regnum, lo);
-+ ret = qca8k_set_lo(priv, phy_id, regnum, lo);
- if (ret >= 0)
-- ret = bus->write(bus, phy_id, regnum + 1, hi);
-- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit register\n");
-+ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
- }
-
- static int
-@@ -400,7 +435,7 @@ qca8k_regmap_write(void *ctx, uint32_t r
- if (ret < 0)
- goto exit;
-
-- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-
- exit:
- mutex_unlock(&bus->mdio_lock);
-@@ -433,7 +468,7 @@ qca8k_regmap_update_bits(void *ctx, uint
-
- val &= ~mask;
- val |= write_val;
-- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-
- exit:
- mutex_unlock(&bus->mdio_lock);
-@@ -1117,14 +1152,14 @@ qca8k_mdio_write(struct qca8k_priv *priv
- if (ret)
- goto exit;
-
-- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-
- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
- QCA8K_MDIO_MASTER_BUSY);
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
-@@ -1154,7 +1189,7 @@ qca8k_mdio_read(struct qca8k_priv *priv,
- if (ret)
- goto exit;
-
-- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-
- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
- QCA8K_MDIO_MASTER_BUSY);
-@@ -1165,7 +1200,7 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
-@@ -3057,6 +3092,8 @@ qca8k_sw_probe(struct mdio_device *mdiod
- }
-
- priv->mdio_cache.page = 0xffff;
-+ priv->mdio_cache.lo = 0xffff;
-+ priv->mdio_cache.hi = 0xffff;
-
- /* Check the detected switch id */
- ret = qca8k_read_switch_id(priv);
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -369,6 +369,11 @@ struct qca8k_mdio_cache {
- * mdio writes
- */
- u16 page;
-+/* lo and hi can also be cached and from Documentation we can skip one
-+ * extra mdio write if lo or hi is didn't change.
-+ */
-+ u16 lo;
-+ u16 hi;
- };
-
- struct qca8k_priv {
diff --git a/target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch b/target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch
deleted file mode 100644
index 5acd13dbad..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From 90386223f44e2a751d7e9e9ac8f78ea33358a891 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:34 +0100
-Subject: [PATCH 15/16] net: dsa: qca8k: add support for larger read/write size
- with mgmt Ethernet
-
-mgmt Ethernet packet can read/write up to 16byte at times. The len reg
-is limited to 15 (0xf). The switch actually sends and accepts data in 4
-different steps of len values.
-Len steps:
-- 0: nothing
-- 1-4: first 4 byte
-- 5-6: first 12 byte
-- 7-15: all 16 byte
-
-In the alloc skb function we check if the len is 16 and we fix it to a
-len of 15. It the read/write function interest to extract the real asked
-data. The tagger handler will always copy the fully 16byte with a READ
-command. This is useful for some big regs like the fdb reg that are
-more than 4byte of data. This permits to introduce a bulk function that
-will send and request the entire entry in one go.
-Write function is changed and it does now require to pass the pointer to
-val to also handle array val.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 61 +++++++++++++++++++++++++++--------------
- 1 file changed, 41 insertions(+), 20 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -222,7 +222,9 @@ static void qca8k_rw_reg_ack_handler(str
- if (cmd == MDIO_READ) {
- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
-
-- /* Get the rest of the 12 byte of data */
-+ /* Get the rest of the 12 byte of data.
-+ * The read/write function will extract the requested data.
-+ */
- if (len > QCA_HDR_MGMT_DATA1_LEN)
- memcpy(mgmt_eth_data->data + 1, skb->data,
- QCA_HDR_MGMT_DATA2_LEN);
-@@ -232,16 +234,30 @@ static void qca8k_rw_reg_ack_handler(str
- }
-
- static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,
-- int priority)
-+ int priority, unsigned int len)
- {
- struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ unsigned int real_len;
- struct sk_buff *skb;
-+ u32 *data2;
- u16 hdr;
-
- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
- if (!skb)
- return NULL;
-
-+ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
-+ * Actually for some reason the steps are:
-+ * 0: nothing
-+ * 1-4: first 4 byte
-+ * 5-6: first 12 byte
-+ * 7-15: all 16 byte
-+ */
-+ if (len == 16)
-+ real_len = 15;
-+ else
-+ real_len = len;
-+
- skb_reset_mac_header(skb);
- skb_set_network_header(skb, skb->len);
-
-@@ -254,7 +270,7 @@ static struct sk_buff *qca8k_alloc_mdio_
- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
-
- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, 4);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
- QCA_HDR_MGMT_CHECK_CODE_VAL);
-@@ -264,7 +280,9 @@ static struct sk_buff *qca8k_alloc_mdio_
-
- mgmt_ethhdr->hdr = htons(hdr);
-
-- skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-+ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
-
- return skb;
- }
-@@ -277,7 +295,7 @@ static void qca8k_mdio_header_fill_seq_n
- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
- }
-
--static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val)
-+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
- {
- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
- struct sk_buff *skb;
-@@ -285,7 +303,7 @@ static int qca8k_read_eth(struct qca8k_p
- int ret;
-
- skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,
-- QCA8K_ETHERNET_MDIO_PRIORITY);
-+ QCA8K_ETHERNET_MDIO_PRIORITY, len);
- if (!skb)
- return -ENOMEM;
-
-@@ -313,6 +331,9 @@ static int qca8k_read_eth(struct qca8k_p
- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
-
- *val = mgmt_eth_data->data[0];
-+ if (len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN);
-+
- ack = mgmt_eth_data->ack;
-
- mutex_unlock(&mgmt_eth_data->mutex);
-@@ -326,15 +347,15 @@ static int qca8k_read_eth(struct qca8k_p
- return 0;
- }
-
--static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 val)
-+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
- {
- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
- struct sk_buff *skb;
- bool ack;
- int ret;
-
-- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, &val,
-- QCA8K_ETHERNET_MDIO_PRIORITY);
-+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val,
-+ QCA8K_ETHERNET_MDIO_PRIORITY, len);
- if (!skb)
- return -ENOMEM;
-
-@@ -380,14 +401,14 @@ qca8k_regmap_update_bits_eth(struct qca8
- u32 val = 0;
- int ret;
-
-- ret = qca8k_read_eth(priv, reg, &val);
-+ ret = qca8k_read_eth(priv, reg, &val, sizeof(val));
- if (ret)
- return ret;
-
- val &= ~mask;
- val |= write_val;
-
-- return qca8k_write_eth(priv, reg, val);
-+ return qca8k_write_eth(priv, reg, &val, sizeof(val));
- }
-
- static int
-@@ -398,7 +419,7 @@ qca8k_regmap_read(void *ctx, uint32_t re
- u16 r1, r2, page;
- int ret;
-
-- if (!qca8k_read_eth(priv, reg, val))
-+ if (!qca8k_read_eth(priv, reg, val, sizeof(val)))
- return 0;
-
- qca8k_split_addr(reg, &r1, &r2, &page);
-@@ -424,7 +445,7 @@ qca8k_regmap_write(void *ctx, uint32_t r
- u16 r1, r2, page;
- int ret;
-
-- if (!qca8k_write_eth(priv, reg, val))
-+ if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
- return 0;
-
- qca8k_split_addr(reg, &r1, &r2, &page);
-@@ -959,21 +980,21 @@ qca8k_phy_eth_command(struct qca8k_priv
- }
-
- /* Prealloc all the needed skb before the lock */
-- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL,
-- &write_val, QCA8K_ETHERNET_PHY_PRIORITY);
-+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val));
- if (!write_skb)
- return -ENOMEM;
-
-- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL,
-- &clear_val, QCA8K_ETHERNET_PHY_PRIORITY);
-+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
- if (!write_skb) {
- ret = -ENOMEM;
- goto err_clear_skb;
- }
-
-- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL,
-- &clear_val, QCA8K_ETHERNET_PHY_PRIORITY);
-- if (!write_skb) {
-+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-+ if (!read_skb) {
- ret = -ENOMEM;
- goto err_read_skb;
- }
diff --git a/target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch b/target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch
deleted file mode 100644
index f26c6b91ac..0000000000
--- a/target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From 4f3701fc599820568ba4395070d34e4248800fc0 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Wed, 2 Feb 2022 01:03:35 +0100
-Subject: [PATCH 16/16] net: dsa: qca8k: introduce qca8k_bulk_read/write
- function
-
-Introduce qca8k_bulk_read/write() function to use mgmt Ethernet way to
-read/write packet in bulk. Make use of this new function in the fdb
-function and while at it reduce the reg for fdb_read from 4 to 3 as the
-max bit for the ARL(fdb) table is 83 bits.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 55 ++++++++++++++++++++++++++++++++---------
- 1 file changed, 43 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -412,6 +412,43 @@ qca8k_regmap_update_bits_eth(struct qca8
- }
-
- static int
-+qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+
-+ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+ u32 tmp;
-+
-+ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ tmp = val[i];
-+
-+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-@@ -546,17 +583,13 @@ qca8k_busy_wait(struct qca8k_priv *priv,
- static int
- qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
- {
-- u32 reg[4], val;
-- int i, ret;
-+ u32 reg[3];
-+ int ret;
-
- /* load the ARL table into an array */
-- for (i = 0; i < 4; i++) {
-- ret = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4), &val);
-- if (ret < 0)
-- return ret;
--
-- reg[i] = val;
-- }
-+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+ if (ret)
-+ return ret;
-
- /* vid - 83:72 */
- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
-@@ -580,7 +613,6 @@ qca8k_fdb_write(struct qca8k_priv *priv,
- u8 aging)
- {
- u32 reg[3] = { 0 };
-- int i;
-
- /* vid - 83:72 */
- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-@@ -597,8 +629,7 @@ qca8k_fdb_write(struct qca8k_priv *priv,
- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
-
- /* load the array into the ARL table */
-- for (i = 0; i < 3; i++)
-- qca8k_write(priv, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]);
-+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
- }
-
- static int
diff --git a/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch b/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch
deleted file mode 100644
index 34607c223c..0000000000
--- a/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From c3664d913dc115cab4a5fdb5634df4887048000e Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Fri, 4 Feb 2022 13:03:36 +0300
-Subject: [PATCH 1/1] net: dsa: qca8k: check correct variable in
- qca8k_phy_eth_command()
-
-This is a copy and paste bug. It was supposed to check "clear_skb"
-instead of "write_skb".
-
-Fixes: 2cd548566384 ("net: dsa: qca8k: add support for phy read/write with mgmt Ethernet")
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1018,7 +1018,7 @@ qca8k_phy_eth_command(struct qca8k_priv
-
- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val,
- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-- if (!write_skb) {
-+ if (!clear_skb) {
- ret = -ENOMEM;
- goto err_clear_skb;
- }
diff --git a/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch b/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch
deleted file mode 100644
index d8cf266309..0000000000
--- a/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 4f5e483b8c7a644733db941a1ae00173baa7b463 Mon Sep 17 00:00:00 2001
-From: kernel test robot <lkp@intel.com>
-Date: Thu, 10 Feb 2022 06:13:04 +0800
-Subject: [PATCH 1/1] net: dsa: qca8k: fix noderef.cocci warnings
-
-drivers/net/dsa/qca8k.c:422:37-43: ERROR: application of sizeof to pointer
-
- sizeof when applied to a pointer typed expression gives the size of
- the pointer
-
-Generated by: scripts/coccinelle/misc/noderef.cocci
-
-Fixes: 90386223f44e ("net: dsa: qca8k: add support for larger read/write size with mgmt Ethernet")
-CC: Ansuel Smith <ansuelsmth@gmail.com>
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: kernel test robot <lkp@intel.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Link: https://lore.kernel.org/r/20220209221304.GA17529@d2214a582157
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca8k.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -456,7 +456,7 @@ qca8k_regmap_read(void *ctx, uint32_t re
- u16 r1, r2, page;
- int ret;
-
-- if (!qca8k_read_eth(priv, reg, val, sizeof(val)))
-+ if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
- return 0;
-
- qca8k_split_addr(reg, &r1, &r2, &page);
diff --git a/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch
deleted file mode 100644
index 57df4c126e..0000000000
--- a/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 69fd055957a02309ffdc23d887a01988b6e5bab1 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sat, 16 Apr 2022 01:30:12 +0200
-Subject: [PATCH 1/6] net: dsa: qca8k: drop MTU tracking from qca8k_priv
-
-DSA set the CPU port based on the largest MTU of all the slave ports.
-Based on this we can drop the MTU array from qca8k_priv and set the
-port_change_mtu logic on DSA changing MTU of the CPU port as the switch
-have a global MTU settingfor each port.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 26 +++++++++-----------------
- drivers/net/dsa/qca8k.h | 1 -
- 2 files changed, 9 insertions(+), 18 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1803,16 +1803,6 @@ qca8k_setup(struct dsa_switch *ds)
- QCA8K_PORT_HOL_CTRL1_WRED_EN,
- mask);
- }
--
-- /* Set initial MTU for every port.
-- * We have only have a general MTU setting. So track
-- * every port and set the max across all port.
-- * Set per port MTU to 1500 as the MTU change function
-- * will add the overhead and if its set to 1518 then it
-- * will apply the overhead again and we will end up with
-- * MTU of 1536 instead of 1518
-- */
-- priv->port_mtu[i] = ETH_DATA_LEN;
- }
-
- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-@@ -2525,13 +2515,16 @@ static int
- qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct qca8k_priv *priv = ds->priv;
-- int ret, i, mtu = 0;
--
-- priv->port_mtu[port] = new_mtu;
-+ int ret;
-
-- for (i = 0; i < QCA8K_NUM_PORTS; i++)
-- if (priv->port_mtu[i] > mtu)
-- mtu = priv->port_mtu[i];
-+ /* We have only have a general MTU setting.
-+ * DSA always set the CPU port's MTU to the largest MTU of the slave
-+ * ports.
-+ * Setting MTU just for the CPU port is sufficient to correctly set a
-+ * value for every port.
-+ */
-+ if (!dsa_is_cpu_port(ds, port))
-+ return 0;
-
- /* To change the MAX_FRAME_SIZE the cpu ports must be off or
- * the switch panics.
-@@ -2545,7 +2538,7 @@ qca8k_port_change_mtu(struct dsa_switch
- qca8k_port_set_status(priv, 6, 0);
-
- /* Include L2 header / FCS length */
-- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
-+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
-
- if (priv->port_sts[0].enabled)
- qca8k_port_set_status(priv, 0, 1);
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -392,7 +392,6 @@ struct qca8k_priv {
- struct device *dev;
- struct dsa_switch_ops ops;
- struct gpio_desc *reset_gpio;
-- unsigned int port_mtu[QCA8K_NUM_PORTS];
- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
- struct qca8k_mgmt_eth_data mgmt_eth_data;
- struct qca8k_mib_eth_data mib_eth_data;
diff --git a/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch
deleted file mode 100644
index 3cacd7e4fd..0000000000
--- a/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 2b8fd87af7f156942971789abac8ee2bb60c03bc Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sat, 16 Apr 2022 01:30:13 +0200
-Subject: [PATCH 2/6] net: dsa: qca8k: drop port_sts from qca8k_priv
-
-Port_sts is a thing of the past for this driver. It was something
-present on the initial implementation of this driver and parts of the
-original struct were dropped over time. Using an array of int to store if
-a port is enabled or not to handle PM operation seems overkill. Switch
-and use a simple u8 to store the port status where each bit correspond
-to a port. (bit is set port is enabled, bit is not set, port is disabled)
-Also add some comments to better describe why we need to track port
-status.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 15 +++++++++------
- drivers/net/dsa/qca8k.h | 9 ++++-----
- 2 files changed, 13 insertions(+), 11 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -2494,7 +2494,7 @@ qca8k_port_enable(struct dsa_switch *ds,
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-
- qca8k_port_set_status(priv, port, 1);
-- priv->port_sts[port].enabled = 1;
-+ priv->port_enabled_map |= BIT(port);
-
- if (dsa_is_user_port(ds, port))
- phy_support_asym_pause(phy);
-@@ -2508,7 +2508,7 @@ qca8k_port_disable(struct dsa_switch *ds
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-
- qca8k_port_set_status(priv, port, 0);
-- priv->port_sts[port].enabled = 0;
-+ priv->port_enabled_map &= ~BIT(port);
- }
-
- static int
-@@ -2531,19 +2531,19 @@ qca8k_port_change_mtu(struct dsa_switch
- * Turn off both cpu ports before applying the new value to prevent
- * this.
- */
-- if (priv->port_sts[0].enabled)
-+ if (priv->port_enabled_map & BIT(0))
- qca8k_port_set_status(priv, 0, 0);
-
-- if (priv->port_sts[6].enabled)
-+ if (priv->port_enabled_map & BIT(6))
- qca8k_port_set_status(priv, 6, 0);
-
- /* Include L2 header / FCS length */
- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
-
-- if (priv->port_sts[0].enabled)
-+ if (priv->port_enabled_map & BIT(0))
- qca8k_port_set_status(priv, 0, 1);
-
-- if (priv->port_sts[6].enabled)
-+ if (priv->port_enabled_map & BIT(6))
- qca8k_port_set_status(priv, 6, 1);
-
- return ret;
-@@ -3199,13 +3199,16 @@ static void qca8k_sw_shutdown(struct mdi
- static void
- qca8k_set_pm(struct qca8k_priv *priv, int enable)
- {
-- int i;
-+ int port;
-
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- if (!priv->port_sts[i].enabled)
-+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+ /* Do not enable on resume if the port was
-+ * disabled before.
-+ */
-+ if (!(priv->port_enabled_map & BIT(port)))
- continue;
-
-- qca8k_port_set_status(priv, i, enable);
-+ qca8k_port_set_status(priv, port, enable);
- }
- }
-
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -324,10 +324,6 @@ enum qca8k_mid_cmd {
- QCA8K_MIB_CAST = 3,
- };
-
--struct ar8xxx_port_status {
-- int enabled;
--};
--
- struct qca8k_match_data {
- u8 id;
- bool reduced_package;
-@@ -382,11 +378,14 @@ struct qca8k_priv {
- u8 mirror_rx;
- u8 mirror_tx;
- u8 lag_hash_mode;
-+ /* Each bit correspond to a port. This switch can support a max of 7 port.
-+ * Bit 1: port enabled. Bit 0: port disabled.
-+ */
-+ u8 port_enabled_map;
- bool legacy_phy_port_mapping;
- struct qca8k_ports_config ports_config;
- struct regmap *regmap;
- struct mii_bus *bus;
-- struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
- struct dsa_switch *ds;
- struct mutex reg_mutex;
- struct device *dev;
diff --git a/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch b/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch
deleted file mode 100644
index 12c3221077..0000000000
--- a/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 8255212e4130bd2dc1463286a3dddb74797bbdc1 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sat, 16 Apr 2022 01:30:14 +0200
-Subject: [PATCH 3/6] net: dsa: qca8k: rework and simplify mdiobus logic
-
-In an attempt to reduce qca8k_priv space, rework and simplify mdiobus
-logic.
-We now declare a mdiobus instead of relying on DSA phy_read/write even
-if a mdio node is not present. This is all to make the qca8k ops static
-and not switch specific. With a legacy implementation where port doesn't
-have a phy map declared in the dts with a mdio node, we declare a
-'qca8k-legacy' mdiobus. The conversion logic is used as legacy read and
-write ops are used instead of the internal one.
-Also drop the legacy_phy_port_mapping as we now declare mdiobus with ops
-that already address the workaround.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 95 +++++++++++++----------------------------
- drivers/net/dsa/qca8k.h | 1 -
- 2 files changed, 29 insertions(+), 67 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1291,83 +1291,63 @@ qca8k_internal_mdio_read(struct mii_bus
- }
-
- static int
--qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
-+qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data)
- {
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
-+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-
-- /* Check if the legacy mapping should be used and the
-- * port is not correctly mapped to the right PHY in the
-- * devicetree
-- */
-- if (priv->legacy_phy_port_mapping)
-- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
--
-- /* Use mdio Ethernet when available, fallback to legacy one on error */
-- ret = qca8k_phy_eth_command(priv, false, port, regnum, 0);
-- if (!ret)
-- return ret;
--
-- return qca8k_mdio_write(priv, port, regnum, data);
-+ return qca8k_internal_mdio_write(slave_bus, port, regnum, data);
- }
-
- static int
--qca8k_phy_read(struct dsa_switch *ds, int port, int regnum)
-+qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum)
- {
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- /* Check if the legacy mapping should be used and the
-- * port is not correctly mapped to the right PHY in the
-- * devicetree
-- */
-- if (priv->legacy_phy_port_mapping)
-- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
--
-- /* Use mdio Ethernet when available, fallback to legacy one on error */
-- ret = qca8k_phy_eth_command(priv, true, port, regnum, 0);
-- if (ret >= 0)
-- return ret;
--
-- ret = qca8k_mdio_read(priv, port, regnum);
--
-- if (ret < 0)
-- return 0xffff;
-+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-
-- return ret;
-+ return qca8k_internal_mdio_read(slave_bus, port, regnum);
- }
-
- static int
--qca8k_mdio_register(struct qca8k_priv *priv, struct device_node *mdio)
-+qca8k_mdio_register(struct qca8k_priv *priv)
- {
- struct dsa_switch *ds = priv->ds;
-+ struct device_node *mdio;
- struct mii_bus *bus;
-
- bus = devm_mdiobus_alloc(ds->dev);
--
- if (!bus)
- return -ENOMEM;
-
- bus->priv = (void *)priv;
-- bus->name = "qca8k slave mii";
-- bus->read = qca8k_internal_mdio_read;
-- bus->write = qca8k_internal_mdio_write;
-- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d",
-- ds->index);
--
- bus->parent = ds->dev;
- bus->phy_mask = ~ds->phys_mii_mask;
--
- ds->slave_mii_bus = bus;
-
-- return devm_of_mdiobus_register(priv->dev, bus, mdio);
-+ /* Check if the devicetree declare the port:phy mapping */
-+ mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
-+ if (of_device_is_available(mdio)) {
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", ds->index);
-+ bus->name = "qca8k slave mii";
-+ bus->read = qca8k_internal_mdio_read;
-+ bus->write = qca8k_internal_mdio_write;
-+ return devm_of_mdiobus_register(priv->dev, bus, mdio);
-+ }
-+
-+ /* If a mapping can't be found the legacy mapping is used,
-+ * using the qca8k_port_to_phy function
-+ */
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
-+ ds->dst->index, ds->index);
-+ bus->name = "qca8k-legacy slave mii";
-+ bus->read = qca8k_legacy_mdio_read;
-+ bus->write = qca8k_legacy_mdio_write;
-+ return devm_mdiobus_register(priv->dev, bus);
- }
-
- static int
- qca8k_setup_mdio_bus(struct qca8k_priv *priv)
- {
- u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
-- struct device_node *ports, *port, *mdio;
-+ struct device_node *ports, *port;
- phy_interface_t mode;
- int err;
-
-@@ -1429,24 +1409,7 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
- QCA8K_MDIO_MASTER_EN);
- }
-
-- /* Check if the devicetree declare the port:phy mapping */
-- mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
-- if (of_device_is_available(mdio)) {
-- err = qca8k_mdio_register(priv, mdio);
-- if (err)
-- of_node_put(mdio);
--
-- return err;
-- }
--
-- /* If a mapping can't be found the legacy mapping is used,
-- * using the qca8k_port_to_phy function
-- */
-- priv->legacy_phy_port_mapping = true;
-- priv->ops.phy_read = qca8k_phy_read;
-- priv->ops.phy_write = qca8k_phy_write;
--
-- return 0;
-+ return qca8k_mdio_register(priv);
- }
-
- static int
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -382,7 +382,6 @@ struct qca8k_priv {
- * Bit 1: port enabled. Bit 0: port disabled.
- */
- u8 port_enabled_map;
-- bool legacy_phy_port_mapping;
- struct qca8k_ports_config ports_config;
- struct regmap *regmap;
- struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch
deleted file mode 100644
index 8641000abb..0000000000
--- a/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 2349b83a2486c55b9dd225326f0172a84a43c5e4 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sat, 16 Apr 2022 01:30:15 +0200
-Subject: [PATCH 4/6] net: dsa: qca8k: drop dsa_switch_ops from qca8k_priv
-
-Now that dsa_switch_ops is not switch specific anymore, we can drop it
-from qca8k_priv and use the static ops directly for the dsa_switch
-pointer.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 3 +--
- drivers/net/dsa/qca8k.h | 1 -
- 2 files changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -3121,8 +3121,7 @@ qca8k_sw_probe(struct mdio_device *mdiod
- priv->ds->dev = &mdiodev->dev;
- priv->ds->num_ports = QCA8K_NUM_PORTS;
- priv->ds->priv = priv;
-- priv->ops = qca8k_switch_ops;
-- priv->ds->ops = &priv->ops;
-+ priv->ds->ops = &qca8k_switch_ops;
- mutex_init(&priv->reg_mutex);
- dev_set_drvdata(&mdiodev->dev, priv);
-
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -388,7 +388,6 @@ struct qca8k_priv {
- struct dsa_switch *ds;
- struct mutex reg_mutex;
- struct device *dev;
-- struct dsa_switch_ops ops;
- struct gpio_desc *reset_gpio;
- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
- struct qca8k_mgmt_eth_data mgmt_eth_data;
diff --git a/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch b/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch
deleted file mode 100644
index b14b22091b..0000000000
--- a/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 6cfc03b602200c5cbbd8d906fd905547814e83df Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sat, 16 Apr 2022 01:30:16 +0200
-Subject: [PATCH 5/6] net: dsa: qca8k: correctly handle mdio read error
-
-Restore original way to handle mdio read error by returning 0xffff.
-This was wrongly changed when the internal_mdio_read was introduced,
-now that both legacy and internal use the same function, make sure that
-they behave the same way.
-
-Fixes: ce062a0adbfe ("net: dsa: qca8k: fix kernel panic with legacy mdio mapping")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1287,7 +1287,12 @@ qca8k_internal_mdio_read(struct mii_bus
- if (ret >= 0)
- return ret;
-
-- return qca8k_mdio_read(priv, phy, regnum);
-+ ret = qca8k_mdio_read(priv, phy, regnum);
-+
-+ if (ret < 0)
-+ return 0xffff;
-+
-+ return ret;
- }
-
- static int
diff --git a/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch b/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch
deleted file mode 100644
index 094686f11b..0000000000
--- a/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 8d1af50842bf2774f4edc57054206e909117469b Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sat, 16 Apr 2022 01:30:17 +0200
-Subject: [PATCH 6/6] net: dsa: qca8k: unify bus id naming with legacy and OF
- mdio bus
-
-Add support for multiple switch with OF mdio bus declaration.
-Unify the bus id naming and use the same logic for both legacy and OF
-mdio bus.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1323,6 +1323,8 @@ qca8k_mdio_register(struct qca8k_priv *p
- return -ENOMEM;
-
- bus->priv = (void *)priv;
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
-+ ds->dst->index, ds->index);
- bus->parent = ds->dev;
- bus->phy_mask = ~ds->phys_mii_mask;
- ds->slave_mii_bus = bus;
-@@ -1330,7 +1332,6 @@ qca8k_mdio_register(struct qca8k_priv *p
- /* Check if the devicetree declare the port:phy mapping */
- mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
- if (of_device_is_available(mdio)) {
-- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", ds->index);
- bus->name = "qca8k slave mii";
- bus->read = qca8k_internal_mdio_read;
- bus->write = qca8k_internal_mdio_write;
-@@ -1340,8 +1341,6 @@ qca8k_mdio_register(struct qca8k_priv *p
- /* If a mapping can't be found the legacy mapping is used,
- * using the qca8k_port_to_phy function
- */
-- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
-- ds->dst->index, ds->index);
- bus->name = "qca8k-legacy slave mii";
- bus->read = qca8k_legacy_mdio_read;
- bus->write = qca8k_legacy_mdio_write;
diff --git a/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch b/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch
deleted file mode 100644
index 1534113f1d..0000000000
--- a/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch
+++ /dev/null
@@ -1,7389 +0,0 @@
-From 4bbaf764e1e1786eb937fdb62172f656f512e116 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 13 Jul 2022 22:53:50 +0200
-Subject: [PATCH 1/1] net: dsa: qca8k: move driver to qca dir
-
-Move qca8k driver to qca dir in preparation for code split and
-introduction of ipq4019 switch based on qca8k.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/Kconfig | 8 --------
- drivers/net/dsa/Makefile | 1 -
- drivers/net/dsa/qca/Kconfig | 8 ++++++++
- drivers/net/dsa/qca/Makefile | 1 +
- drivers/net/dsa/{ => qca}/qca8k.c | 0
- drivers/net/dsa/{ => qca}/qca8k.h | 0
- 6 files changed, 9 insertions(+), 9 deletions(-)
- rename drivers/net/dsa/{ => qca}/qca8k.c (100%)
- rename drivers/net/dsa/{ => qca}/qca8k.h (100%)
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -60,14 +60,6 @@ source "drivers/net/dsa/sja1105/Kconfig"
-
- source "drivers/net/dsa/xrs700x/Kconfig"
-
--config NET_DSA_QCA8K
-- tristate "Qualcomm Atheros QCA8K Ethernet switch family support"
-- select NET_DSA_TAG_QCA
-- select REGMAP
-- help
-- This enables support for the Qualcomm Atheros QCA8K Ethernet
-- switch chips.
--
- config NET_DSA_REALTEK_SMI
- tristate "Realtek SMI Ethernet switch family support"
- select NET_DSA_TAG_RTL4_A
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -8,7 +8,6 @@ endif
- obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
- obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
- obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
--obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
- obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
- realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
- obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
---- a/drivers/net/dsa/qca/Kconfig
-+++ b/drivers/net/dsa/qca/Kconfig
-@@ -7,3 +7,11 @@ config NET_DSA_AR9331
- help
- This enables support for the Qualcomm Atheros AR9331 built-in Ethernet
- switch.
-+
-+config NET_DSA_QCA8K
-+ tristate "Qualcomm Atheros QCA8K Ethernet switch family support"
-+ select NET_DSA_TAG_QCA
-+ select REGMAP
-+ help
-+ This enables support for the Qualcomm Atheros QCA8K Ethernet
-+ switch chips.
---- a/drivers/net/dsa/qca/Makefile
-+++ b/drivers/net/dsa/qca/Makefile
-@@ -1,2 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0-only
- obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o
-+obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k.c
-@@ -0,0 +1,3243 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
-+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2016 John Crispin <john@phrozen.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/phy.h>
-+#include <linux/netdevice.h>
-+#include <linux/bitfield.h>
-+#include <linux/regmap.h>
-+#include <net/dsa.h>
-+#include <linux/of_net.h>
-+#include <linux/of_mdio.h>
-+#include <linux/of_platform.h>
-+#include <linux/if_bridge.h>
-+#include <linux/mdio.h>
-+#include <linux/phylink.h>
-+#include <linux/gpio/consumer.h>
-+#include <linux/etherdevice.h>
-+#include <linux/dsa/tag_qca.h>
-+
-+#include "qca8k.h"
-+
-+#define MIB_DESC(_s, _o, _n) \
-+ { \
-+ .size = (_s), \
-+ .offset = (_o), \
-+ .name = (_n), \
-+ }
-+
-+static const struct qca8k_mib_desc ar8327_mib[] = {
-+ MIB_DESC(1, 0x00, "RxBroad"),
-+ MIB_DESC(1, 0x04, "RxPause"),
-+ MIB_DESC(1, 0x08, "RxMulti"),
-+ MIB_DESC(1, 0x0c, "RxFcsErr"),
-+ MIB_DESC(1, 0x10, "RxAlignErr"),
-+ MIB_DESC(1, 0x14, "RxRunt"),
-+ MIB_DESC(1, 0x18, "RxFragment"),
-+ MIB_DESC(1, 0x1c, "Rx64Byte"),
-+ MIB_DESC(1, 0x20, "Rx128Byte"),
-+ MIB_DESC(1, 0x24, "Rx256Byte"),
-+ MIB_DESC(1, 0x28, "Rx512Byte"),
-+ MIB_DESC(1, 0x2c, "Rx1024Byte"),
-+ MIB_DESC(1, 0x30, "Rx1518Byte"),
-+ MIB_DESC(1, 0x34, "RxMaxByte"),
-+ MIB_DESC(1, 0x38, "RxTooLong"),
-+ MIB_DESC(2, 0x3c, "RxGoodByte"),
-+ MIB_DESC(2, 0x44, "RxBadByte"),
-+ MIB_DESC(1, 0x4c, "RxOverFlow"),
-+ MIB_DESC(1, 0x50, "Filtered"),
-+ MIB_DESC(1, 0x54, "TxBroad"),
-+ MIB_DESC(1, 0x58, "TxPause"),
-+ MIB_DESC(1, 0x5c, "TxMulti"),
-+ MIB_DESC(1, 0x60, "TxUnderRun"),
-+ MIB_DESC(1, 0x64, "Tx64Byte"),
-+ MIB_DESC(1, 0x68, "Tx128Byte"),
-+ MIB_DESC(1, 0x6c, "Tx256Byte"),
-+ MIB_DESC(1, 0x70, "Tx512Byte"),
-+ MIB_DESC(1, 0x74, "Tx1024Byte"),
-+ MIB_DESC(1, 0x78, "Tx1518Byte"),
-+ MIB_DESC(1, 0x7c, "TxMaxByte"),
-+ MIB_DESC(1, 0x80, "TxOverSize"),
-+ MIB_DESC(2, 0x84, "TxByte"),
-+ MIB_DESC(1, 0x8c, "TxCollision"),
-+ MIB_DESC(1, 0x90, "TxAbortCol"),
-+ MIB_DESC(1, 0x94, "TxMultiCol"),
-+ MIB_DESC(1, 0x98, "TxSingleCol"),
-+ MIB_DESC(1, 0x9c, "TxExcDefer"),
-+ MIB_DESC(1, 0xa0, "TxDefer"),
-+ MIB_DESC(1, 0xa4, "TxLateCol"),
-+ MIB_DESC(1, 0xa8, "RXUnicast"),
-+ MIB_DESC(1, 0xac, "TXUnicast"),
-+};
-+
-+static void
-+qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
-+{
-+ regaddr >>= 1;
-+ *r1 = regaddr & 0x1e;
-+
-+ regaddr >>= 5;
-+ *r2 = regaddr & 0x7;
-+
-+ regaddr >>= 3;
-+ *page = regaddr & 0x3ff;
-+}
-+
-+static int
-+qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
-+{
-+ u16 *cached_lo = &priv->mdio_cache.lo;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (lo == *cached_lo)
-+ return 0;
-+
-+ ret = bus->write(bus, phy_id, regnum, lo);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit lo register\n");
-+
-+ *cached_lo = lo;
-+ return 0;
-+}
-+
-+static int
-+qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
-+{
-+ u16 *cached_hi = &priv->mdio_cache.hi;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (hi == *cached_hi)
-+ return 0;
-+
-+ ret = bus->write(bus, phy_id, regnum, hi);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit hi register\n");
-+
-+ *cached_hi = hi;
-+ return 0;
-+}
-+
-+static int
-+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+{
-+ int ret;
-+
-+ ret = bus->read(bus, phy_id, regnum);
-+ if (ret >= 0) {
-+ *val = ret;
-+ ret = bus->read(bus, phy_id, regnum + 1);
-+ *val |= ret << 16;
-+ }
-+
-+ if (ret < 0) {
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to read qca8k 32bit register\n");
-+ *val = 0;
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
-+{
-+ u16 lo, hi;
-+ int ret;
-+
-+ lo = val & 0xffff;
-+ hi = (u16)(val >> 16);
-+
-+ ret = qca8k_set_lo(priv, phy_id, regnum, lo);
-+ if (ret >= 0)
-+ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
-+}
-+
-+static int
-+qca8k_set_page(struct qca8k_priv *priv, u16 page)
-+{
-+ u16 *cached_page = &priv->mdio_cache.page;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (page == *cached_page)
-+ return 0;
-+
-+ ret = bus->write(bus, 0x18, 0, page);
-+ if (ret < 0) {
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to set qca8k page\n");
-+ return ret;
-+ }
-+
-+ *cached_page = page;
-+ usleep_range(1000, 2000);
-+ return 0;
-+}
-+
-+static int
-+qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
-+{
-+ return regmap_read(priv->regmap, reg, val);
-+}
-+
-+static int
-+qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
-+{
-+ return regmap_write(priv->regmap, reg, val);
-+}
-+
-+static int
-+qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+{
-+ return regmap_update_bits(priv->regmap, reg, mask, write_val);
-+}
-+
-+static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ u8 len, cmd;
-+
-+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
-+ mgmt_eth_data = &priv->mgmt_eth_data;
-+
-+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
-+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
-+
-+ /* Make sure the seq match the requested packet */
-+ if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
-+ mgmt_eth_data->ack = true;
-+
-+ if (cmd == MDIO_READ) {
-+ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
-+
-+ /* Get the rest of the 12 byte of data.
-+ * The read/write function will extract the requested data.
-+ */
-+ if (len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(mgmt_eth_data->data + 1, skb->data,
-+ QCA_HDR_MGMT_DATA2_LEN);
-+ }
-+
-+ complete(&mgmt_eth_data->rw_done);
-+}
-+
-+static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,
-+ int priority, unsigned int len)
-+{
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ unsigned int real_len;
-+ struct sk_buff *skb;
-+ u32 *data2;
-+ u16 hdr;
-+
-+ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
-+ if (!skb)
-+ return NULL;
-+
-+ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
-+ * Actually for some reason the steps are:
-+ * 0: nothing
-+ * 1-4: first 4 byte
-+ * 5-6: first 12 byte
-+ * 7-15: all 16 byte
-+ */
-+ if (len == 16)
-+ real_len = 15;
-+ else
-+ real_len = len;
-+
-+ skb_reset_mac_header(skb);
-+ skb_set_network_header(skb, skb->len);
-+
-+ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);
-+
-+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority);
-+ hdr |= QCA_HDR_XMIT_FROM_CPU;
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
-+
-+ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
-+ QCA_HDR_MGMT_CHECK_CODE_VAL);
-+
-+ if (cmd == MDIO_WRITE)
-+ mgmt_ethhdr->mdio_data = *val;
-+
-+ mgmt_ethhdr->hdr = htons(hdr);
-+
-+ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
-+
-+ return skb;
-+}
-+
-+static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
-+{
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+
-+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
-+ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
-+}
-+
-+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-+ struct sk_buff *skb;
-+ bool ack;
-+ int ret;
-+
-+ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,
-+ QCA8K_ETHERNET_MDIO_PRIORITY, len);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check mgmt_master if is operational */
-+ if (!priv->mgmt_master) {
-+ kfree_skb(skb);
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ return -EINVAL;
-+ }
-+
-+ skb->dev = priv->mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the mdio pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
-+
-+ *val = mgmt_eth_data->data[0];
-+ if (len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-+ struct sk_buff *skb;
-+ bool ack;
-+ int ret;
-+
-+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val,
-+ QCA8K_ETHERNET_MDIO_PRIORITY, len);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check mgmt_master if is operational */
-+ if (!priv->mgmt_master) {
-+ kfree_skb(skb);
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ return -EINVAL;
-+ }
-+
-+ skb->dev = priv->mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the mdio pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+{
-+ u32 val = 0;
-+ int ret;
-+
-+ ret = qca8k_read_eth(priv, reg, &val, sizeof(val));
-+ if (ret)
-+ return ret;
-+
-+ val &= ~mask;
-+ val |= write_val;
-+
-+ return qca8k_write_eth(priv, reg, &val, sizeof(val));
-+}
-+
-+static int
-+qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+
-+ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+ u32 tmp;
-+
-+ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ tmp = val[i];
-+
-+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ int ret;
-+
-+ if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
-+ return 0;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);
-+
-+exit:
-+ mutex_unlock(&bus->mdio_lock);
-+ return ret;
-+}
-+
-+static int
-+qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ int ret;
-+
-+ if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
-+ return 0;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret < 0)
-+ goto exit;
-+
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+exit:
-+ mutex_unlock(&bus->mdio_lock);
-+ return ret;
-+}
-+
-+static int
-+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret;
-+
-+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
-+ return 0;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-+ if (ret < 0)
-+ goto exit;
-+
-+ val &= ~mask;
-+ val |= write_val;
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+exit:
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static const struct regmap_range qca8k_readable_ranges[] = {
-+ regmap_reg_range(0x0000, 0x00e4), /* Global control */
-+ regmap_reg_range(0x0100, 0x0168), /* EEE control */
-+ regmap_reg_range(0x0200, 0x0270), /* Parser control */
-+ regmap_reg_range(0x0400, 0x0454), /* ACL */
-+ regmap_reg_range(0x0600, 0x0718), /* Lookup */
-+ regmap_reg_range(0x0800, 0x0b70), /* QM */
-+ regmap_reg_range(0x0c00, 0x0c80), /* PKT */
-+ regmap_reg_range(0x0e00, 0x0e98), /* L3 */
-+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
-+
-+};
-+
-+static const struct regmap_access_table qca8k_readable_table = {
-+ .yes_ranges = qca8k_readable_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
-+};
-+
-+static struct regmap_config qca8k_regmap_config = {
-+ .reg_bits = 16,
-+ .val_bits = 32,
-+ .reg_stride = 4,
-+ .max_register = 0x16ac, /* end MIB - Port6 range */
-+ .reg_read = qca8k_regmap_read,
-+ .reg_write = qca8k_regmap_write,
-+ .reg_update_bits = qca8k_regmap_update_bits,
-+ .rd_table = &qca8k_readable_table,
-+ .disable_locking = true, /* Locking is handled by qca8k read/write */
-+ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
-+};
-+
-+static int
-+qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
-+{
-+ u32 val;
-+
-+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
-+}
-+
-+static int
-+qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
-+{
-+ u32 reg[3];
-+ int ret;
-+
-+ /* load the ARL table into an array */
-+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+ if (ret)
-+ return ret;
-+
-+ /* vid - 83:72 */
-+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
-+ /* aging - 67:64 */
-+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
-+ /* portmask - 54:48 */
-+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
-+ /* mac - 47:0 */
-+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
-+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
-+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
-+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
-+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
-+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac,
-+ u8 aging)
-+{
-+ u32 reg[3] = { 0 };
-+
-+ /* vid - 83:72 */
-+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-+ /* aging - 67:64 */
-+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
-+ /* portmask - 54:48 */
-+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
-+ /* mac - 47:0 */
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
-+
-+ /* load the array into the ARL table */
-+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+}
-+
-+static int
-+qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /* Set the command and FDB index */
-+ reg = QCA8K_ATU_FUNC_BUSY;
-+ reg |= cmd;
-+ if (port >= 0) {
-+ reg |= QCA8K_ATU_FUNC_PORT_EN;
-+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
-+ }
-+
-+ /* Write the function register triggering the table access */
-+ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-+ if (ret)
-+ return ret;
-+
-+ /* wait for completion */
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
-+ if (ret)
-+ return ret;
-+
-+ /* Check for table full violation when adding an entry */
-+ if (cmd == QCA8K_FDB_LOAD) {
-+ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
-+ if (ret < 0)
-+ return ret;
-+ if (reg & QCA8K_ATU_FUNC_FULL)
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port)
-+{
-+ int ret;
-+
-+ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
-+ if (ret < 0)
-+ return ret;
-+
-+ return qca8k_fdb_read(priv, fdb);
-+}
-+
-+static int
-+qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask,
-+ u16 vid, u8 aging)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_write(priv, vid, port_mask, mac, aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_write(priv, vid, port_mask, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static void
-+qca8k_fdb_flush(struct qca8k_priv *priv)
-+{
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static int
-+qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_fdb_read(priv, &fdb);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule exist. Delete first */
-+ if (!fdb.aging) {
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+ }
-+
-+ /* Add port to fdb portmask */
-+ fdb.port_mask |= port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
-+qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule doesn't exist. Why delete? */
-+ if (!fdb.aging) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+
-+ /* Only port in the rule is this port. Don't re insert */
-+ if (fdb.port_mask == port_mask)
-+ goto exit;
-+
-+ /* Remove port from port mask */
-+ fdb.port_mask &= ~port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
-+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /* Set the command and VLAN index */
-+ reg = QCA8K_VTU_FUNC1_BUSY;
-+ reg |= cmd;
-+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
-+
-+ /* Write the function register triggering the table access */
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-+ if (ret)
-+ return ret;
-+
-+ /* wait for completion */
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
-+ if (ret)
-+ return ret;
-+
-+ /* Check for table full violation when adding an entry */
-+ if (cmd == QCA8K_VLAN_LOAD) {
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
-+ if (ret < 0)
-+ return ret;
-+ if (reg & QCA8K_VTU_FUNC1_FULL)
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /*
-+ We do the right thing with VLAN 0 and treat it as untagged while
-+ preserving the tag on egress.
-+ */
-+ if (vid == 0)
-+ return 0;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-+ if (ret < 0)
-+ goto out;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+ if (ret < 0)
-+ goto out;
-+ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-+ if (untagged)
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
-+ else
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
-+
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+ if (ret)
-+ goto out;
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-+
-+out:
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
-+{
-+ u32 reg, mask;
-+ int ret, i;
-+ bool del;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-+ if (ret < 0)
-+ goto out;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+ if (ret < 0)
-+ goto out;
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
-+
-+ /* Check if we're the last member to be removed */
-+ del = true;
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
-+
-+ if ((reg & mask) != mask) {
-+ del = false;
-+ break;
-+ }
-+ }
-+
-+ if (del) {
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
-+ } else {
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+ if (ret)
-+ goto out;
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-+ }
-+
-+out:
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mib_init(struct qca8k_priv *priv)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
-+ QCA8K_MIB_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static void
-+qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
-+{
-+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
-+
-+ /* Port 0 and 6 have no internal PHY */
-+ if (port > 0 && port < 6)
-+ mask |= QCA8K_PORT_STATUS_LINK_AUTO;
-+
-+ if (enable)
-+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-+ else
-+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-+}
-+
-+static int
-+qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
-+ struct sk_buff *read_skb, u32 *val)
-+{
-+ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL);
-+ bool ack;
-+ int ret;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the copy pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ *val = mgmt_eth_data->data[0];
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,
-+ int regnum, u16 data)
-+{
-+ struct sk_buff *write_skb, *clear_skb, *read_skb;
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data;
-+ u32 write_val, clear_val = 0, val;
-+ struct net_device *mgmt_master;
-+ int ret, ret1;
-+ bool ack;
-+
-+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-+ return -EINVAL;
-+
-+ mgmt_eth_data = &priv->mgmt_eth_data;
-+
-+ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-+ QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
-+
-+ if (read) {
-+ write_val |= QCA8K_MDIO_MASTER_READ;
-+ } else {
-+ write_val |= QCA8K_MDIO_MASTER_WRITE;
-+ write_val |= QCA8K_MDIO_MASTER_DATA(data);
-+ }
-+
-+ /* Prealloc all the needed skb before the lock */
-+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val));
-+ if (!write_skb)
-+ return -ENOMEM;
-+
-+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-+ if (!clear_skb) {
-+ ret = -ENOMEM;
-+ goto err_clear_skb;
-+ }
-+
-+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-+ if (!read_skb) {
-+ ret = -ENOMEM;
-+ goto err_read_skb;
-+ }
-+
-+ /* Actually start the request:
-+ * 1. Send mdio master packet
-+ * 2. Busy Wait for mdio master command
-+ * 3. Get the data if we are reading
-+ * 4. Reset the mdio master (even with error)
-+ */
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check if mgmt_master is operational */
-+ mgmt_master = priv->mgmt_master;
-+ if (!mgmt_master) {
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ ret = -EINVAL;
-+ goto err_mgmt_master;
-+ }
-+
-+ read_skb->dev = mgmt_master;
-+ clear_skb->dev = mgmt_master;
-+ write_skb->dev = mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the write pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(write_skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0) {
-+ ret = -ETIMEDOUT;
-+ kfree_skb(read_skb);
-+ goto exit;
-+ }
-+
-+ if (!ack) {
-+ ret = -EINVAL;
-+ kfree_skb(read_skb);
-+ goto exit;
-+ }
-+
-+ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1,
-+ !(val & QCA8K_MDIO_MASTER_BUSY), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-+ mgmt_eth_data, read_skb, &val);
-+
-+ if (ret < 0 && ret1 < 0) {
-+ ret = ret1;
-+ goto exit;
-+ }
-+
-+ if (read) {
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the read pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(read_skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0) {
-+ ret = -ETIMEDOUT;
-+ goto exit;
-+ }
-+
-+ if (!ack) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK;
-+ } else {
-+ kfree_skb(read_skb);
-+ }
-+exit:
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the clear pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(clear_skb);
-+
-+ wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ return ret;
-+
-+ /* Error handling before lock */
-+err_mgmt_master:
-+ kfree_skb(read_skb);
-+err_read_skb:
-+ kfree_skb(clear_skb);
-+err_clear_skb:
-+ kfree_skb(write_skb);
-+
-+ return ret;
-+}
-+
-+static u32
-+qca8k_port_to_phy(int port)
-+{
-+ /* From Andrew Lunn:
-+ * Port 0 has no internal phy.
-+ * Port 1 has an internal PHY at MDIO address 0.
-+ * Port 2 has an internal PHY at MDIO address 1.
-+ * ...
-+ * Port 5 has an internal PHY at MDIO address 4.
-+ * Port 6 has no internal PHY.
-+ */
-+
-+ return port - 1;
-+}
-+
-+static int
-+qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
-+{
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret, ret1;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-+ bus, 0x10 | r2, r1, &val);
-+
-+ /* Check if qca8k_read has failed for a different reason
-+ * before returnting -ETIMEDOUT
-+ */
-+ if (ret < 0 && ret1 < 0)
-+ return ret1;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret;
-+
-+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-+ return -EINVAL;
-+
-+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
-+ QCA8K_MDIO_MASTER_DATA(data);
-+
-+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret)
-+ goto exit;
-+
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-+ QCA8K_MDIO_MASTER_BUSY);
-+
-+exit:
-+ /* even if the busy_wait timeouts try to clear the MASTER_EN */
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret;
-+
-+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-+ return -EINVAL;
-+
-+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-+ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
-+
-+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret)
-+ goto exit;
-+
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-+ QCA8K_MDIO_MASTER_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-+
-+exit:
-+ /* even if the busy_wait timeouts try to clear the MASTER_EN */
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ if (ret >= 0)
-+ ret = val & QCA8K_MDIO_MASTER_DATA_MASK;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
-+{
-+ struct qca8k_priv *priv = slave_bus->priv;
-+ int ret;
-+
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data);
-+ if (!ret)
-+ return 0;
-+
-+ return qca8k_mdio_write(priv, phy, regnum, data);
-+}
-+
-+static int
-+qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
-+{
-+ struct qca8k_priv *priv = slave_bus->priv;
-+ int ret;
-+
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0);
-+ if (ret >= 0)
-+ return ret;
-+
-+ ret = qca8k_mdio_read(priv, phy, regnum);
-+
-+ if (ret < 0)
-+ return 0xffff;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data)
-+{
-+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-+
-+ return qca8k_internal_mdio_write(slave_bus, port, regnum, data);
-+}
-+
-+static int
-+qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum)
-+{
-+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-+
-+ return qca8k_internal_mdio_read(slave_bus, port, regnum);
-+}
-+
-+static int
-+qca8k_mdio_register(struct qca8k_priv *priv)
-+{
-+ struct dsa_switch *ds = priv->ds;
-+ struct device_node *mdio;
-+ struct mii_bus *bus;
-+
-+ bus = devm_mdiobus_alloc(ds->dev);
-+ if (!bus)
-+ return -ENOMEM;
-+
-+ bus->priv = (void *)priv;
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
-+ ds->dst->index, ds->index);
-+ bus->parent = ds->dev;
-+ bus->phy_mask = ~ds->phys_mii_mask;
-+ ds->slave_mii_bus = bus;
-+
-+ /* Check if the devicetree declare the port:phy mapping */
-+ mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
-+ if (of_device_is_available(mdio)) {
-+ bus->name = "qca8k slave mii";
-+ bus->read = qca8k_internal_mdio_read;
-+ bus->write = qca8k_internal_mdio_write;
-+ return devm_of_mdiobus_register(priv->dev, bus, mdio);
-+ }
-+
-+ /* If a mapping can't be found the legacy mapping is used,
-+ * using the qca8k_port_to_phy function
-+ */
-+ bus->name = "qca8k-legacy slave mii";
-+ bus->read = qca8k_legacy_mdio_read;
-+ bus->write = qca8k_legacy_mdio_write;
-+ return devm_mdiobus_register(priv->dev, bus);
-+}
-+
-+static int
-+qca8k_setup_mdio_bus(struct qca8k_priv *priv)
-+{
-+ u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
-+ struct device_node *ports, *port;
-+ phy_interface_t mode;
-+ int err;
-+
-+ ports = of_get_child_by_name(priv->dev->of_node, "ports");
-+ if (!ports)
-+ ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports");
-+
-+ if (!ports)
-+ return -EINVAL;
-+
-+ for_each_available_child_of_node(ports, port) {
-+ err = of_property_read_u32(port, "reg", &reg);
-+ if (err) {
-+ of_node_put(port);
-+ of_node_put(ports);
-+ return err;
-+ }
-+
-+ if (!dsa_is_user_port(priv->ds, reg))
-+ continue;
-+
-+ of_get_phy_mode(port, &mode);
-+
-+ if (of_property_read_bool(port, "phy-handle") &&
-+ mode != PHY_INTERFACE_MODE_INTERNAL)
-+ external_mdio_mask |= BIT(reg);
-+ else
-+ internal_mdio_mask |= BIT(reg);
-+ }
-+
-+ of_node_put(ports);
-+ if (!external_mdio_mask && !internal_mdio_mask) {
-+ dev_err(priv->dev, "no PHYs are defined.\n");
-+ return -EINVAL;
-+ }
-+
-+ /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through
-+ * the MDIO_MASTER register also _disconnects_ the external MDC
-+ * passthrough to the internal PHYs. It's not possible to use both
-+ * configurations at the same time!
-+ *
-+ * Because this came up during the review process:
-+ * If the external mdio-bus driver is capable magically disabling
-+ * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's
-+ * accessors for the time being, it would be possible to pull this
-+ * off.
-+ */
-+ if (!!external_mdio_mask && !!internal_mdio_mask) {
-+ dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n");
-+ return -EINVAL;
-+ }
-+
-+ if (external_mdio_mask) {
-+ /* Make sure to disable the internal mdio bus in cases
-+ * a dt-overlay and driver reload changed the configuration
-+ */
-+
-+ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL,
-+ QCA8K_MDIO_MASTER_EN);
-+ }
-+
-+ return qca8k_mdio_register(priv);
-+}
-+
-+static int
-+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
-+{
-+ u32 mask = 0;
-+ int ret = 0;
-+
-+ /* SoC specific settings for ipq8064.
-+ * If more device require this consider adding
-+ * a dedicated binding.
-+ */
-+ if (of_machine_is_compatible("qcom,ipq8064"))
-+ mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
-+
-+ /* SoC specific settings for ipq8065 */
-+ if (of_machine_is_compatible("qcom,ipq8065"))
-+ mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
-+
-+ if (mask) {
-+ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
-+ QCA8K_MAC_PWR_RGMII0_1_8V |
-+ QCA8K_MAC_PWR_RGMII1_1_8V,
-+ mask);
-+ }
-+
-+ return ret;
-+}
-+
-+static int qca8k_find_cpu_port(struct dsa_switch *ds)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Find the connected cpu port. Valid port are 0 or 6 */
-+ if (dsa_is_cpu_port(ds, 0))
-+ return 0;
-+
-+ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
-+
-+ if (dsa_is_cpu_port(ds, 6))
-+ return 6;
-+
-+ return -EINVAL;
-+}
-+
-+static int
-+qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
-+{
-+ struct device_node *node = priv->dev->of_node;
-+ const struct qca8k_match_data *data;
-+ u32 val = 0;
-+ int ret;
-+
-+ /* QCA8327 require to set to the correct mode.
-+ * His bigger brother QCA8328 have the 172 pin layout.
-+ * Should be applied by default but we set this just to make sure.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ data = of_device_get_match_data(priv->dev);
-+
-+ /* Set the correct package of 148 pin for QCA8327 */
-+ if (data->reduced_package)
-+ val |= QCA8327_PWS_PACKAGE148_EN;
-+
-+ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
-+ val);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
-+ val |= QCA8K_PWS_POWER_ON_SEL;
-+
-+ if (of_property_read_bool(node, "qca,led-open-drain")) {
-+ if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
-+ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
-+ return -EINVAL;
-+ }
-+
-+ val |= QCA8K_PWS_LED_OPEN_EN_CSR;
-+ }
-+
-+ return qca8k_rmw(priv, QCA8K_REG_PWS,
-+ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
-+ val);
-+}
-+
-+static int
-+qca8k_parse_port_config(struct qca8k_priv *priv)
-+{
-+ int port, cpu_port_index = -1, ret;
-+ struct device_node *port_dn;
-+ phy_interface_t mode;
-+ struct dsa_port *dp;
-+ u32 delay;
-+
-+ /* We have 2 CPU port. Check them */
-+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+ /* Skip every other port */
-+ if (port != 0 && port != 6)
-+ continue;
-+
-+ dp = dsa_to_port(priv->ds, port);
-+ port_dn = dp->dn;
-+ cpu_port_index++;
-+
-+ if (!of_device_is_available(port_dn))
-+ continue;
-+
-+ ret = of_get_phy_mode(port_dn, &mode);
-+ if (ret)
-+ continue;
-+
-+ switch (mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_SGMII:
-+ delay = 0;
-+
-+ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-+ /* Switch regs accept value in ns, convert ps to ns */
-+ delay = delay / 1000;
-+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_TXID)
-+ delay = 1;
-+
-+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) {
-+ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-+ delay = 3;
-+ }
-+
-+ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
-+
-+ delay = 0;
-+
-+ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
-+ /* Switch regs accept value in ns, convert ps to ns */
-+ delay = delay / 1000;
-+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+ delay = 2;
-+
-+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) {
-+ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-+ delay = 3;
-+ }
-+
-+ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
-+
-+ /* Skip sgmii parsing for rgmii* mode */
-+ if (mode == PHY_INTERFACE_MODE_RGMII ||
-+ mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_TXID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+ break;
-+
-+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-+ priv->ports_config.sgmii_tx_clk_falling_edge = true;
-+
-+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-+ priv->ports_config.sgmii_rx_clk_falling_edge = true;
-+
-+ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
-+ priv->ports_config.sgmii_enable_pll = true;
-+
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
-+ priv->ports_config.sgmii_enable_pll = false;
-+ }
-+
-+ if (priv->switch_revision < 2)
-+ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
-+ }
-+
-+ break;
-+ default:
-+ continue;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_setup(struct dsa_switch *ds)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ int cpu_port, ret, i;
-+ u32 mask;
-+
-+ cpu_port = qca8k_find_cpu_port(ds);
-+ if (cpu_port < 0) {
-+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
-+ return cpu_port;
-+ }
-+
-+ /* Parse CPU port config to be later used in phy_link mac_config */
-+ ret = qca8k_parse_port_config(priv);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_setup_mdio_bus(priv);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_setup_of_pws_reg(priv);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_setup_mac_pwr_sel(priv);
-+ if (ret)
-+ return ret;
-+
-+ /* Make sure MAC06 is disabled */
-+ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
-+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
-+ if (ret) {
-+ dev_err(priv->dev, "failed disabling MAC06 exchange");
-+ return ret;
-+ }
-+
-+ /* Enable CPU Port */
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-+ if (ret) {
-+ dev_err(priv->dev, "failed enabling CPU port");
-+ return ret;
-+ }
-+
-+ /* Enable MIB counters */
-+ ret = qca8k_mib_init(priv);
-+ if (ret)
-+ dev_warn(priv->dev, "mib init failed");
-+
-+ /* Initial setup of all ports */
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ /* Disable forwarding by default on all ports */
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_MEMBER, 0);
-+ if (ret)
-+ return ret;
-+
-+ /* Enable QCA header mode on all cpu ports */
-+ if (dsa_is_cpu_port(ds, i)) {
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
-+ if (ret) {
-+ dev_err(priv->dev, "failed enabling QCA header mode");
-+ return ret;
-+ }
-+ }
-+
-+ /* Disable MAC by default on all user ports */
-+ if (dsa_is_user_port(ds, i))
-+ qca8k_port_set_status(priv, i, 0);
-+ }
-+
-+ /* Forward all unknown frames to CPU port for Linux processing
-+ * Notice that in multi-cpu config only one port should be set
-+ * for igmp, unknown, multicast and broadcast packet
-+ */
-+ ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
-+ if (ret)
-+ return ret;
-+
-+ /* Setup connection between CPU port & user ports
-+ * Configure specific switch configuration for ports
-+ */
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ /* CPU port gets connected to all user ports of the switch */
-+ if (dsa_is_cpu_port(ds, i)) {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-+ if (ret)
-+ return ret;
-+ }
-+
-+ /* Individual user ports get connected to CPU port only */
-+ if (dsa_is_user_port(ds, i)) {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_MEMBER,
-+ BIT(cpu_port));
-+ if (ret)
-+ return ret;
-+
-+ /* Enable ARP Auto-learning by default */
-+ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_LEARN);
-+ if (ret)
-+ return ret;
-+
-+ /* For port based vlans to work we need to set the
-+ * default egress vid
-+ */
-+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-+ QCA8K_EGREES_VLAN_PORT_MASK(i),
-+ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF));
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-+ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-+ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-+ if (ret)
-+ return ret;
-+ }
-+
-+ /* The port 5 of the qca8337 have some problem in flood condition. The
-+ * original legacy driver had some specific buffer and priority settings
-+ * for the different port suggested by the QCA switch team. Add this
-+ * missing settings to improve switch stability under load condition.
-+ * This problem is limited to qca8337 and other qca8k switch are not affected.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8337) {
-+ switch (i) {
-+ /* The 2 CPU port and port 5 requires some different
-+ * priority than any other ports.
-+ */
-+ case 0:
-+ case 5:
-+ case 6:
-+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
-+ break;
-+ default:
-+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
-+ }
-+ qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
-+
-+ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
-+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_WRED_EN;
-+ qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
-+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
-+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_WRED_EN,
-+ mask);
-+ }
-+ }
-+
-+ /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
-+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
-+ qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
-+ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK |
-+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK,
-+ mask);
-+ }
-+
-+ /* Setup our port MTUs to match power on defaults */
-+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
-+ if (ret)
-+ dev_warn(priv->dev, "failed setting MTU settings");
-+
-+ /* Flush the FDB table */
-+ qca8k_fdb_flush(priv);
-+
-+ /* We don't have interrupts for link changes, so we need to poll */
-+ ds->pcs_poll = true;
-+
-+ /* Set min a max ageing value supported */
-+ ds->ageing_time_min = 7000;
-+ ds->ageing_time_max = 458745000;
-+
-+ /* Set max number of LAGs supported */
-+ ds->num_lag_ids = QCA8K_NUM_LAGS;
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
-+ u32 reg)
-+{
-+ u32 delay, val = 0;
-+ int ret;
-+
-+ /* Delay can be declared in 3 different way.
-+ * Mode to rgmii and internal-delay standard binding defined
-+ * rgmii-id or rgmii-tx/rx phy mode set.
-+ * The parse logic set a delay different than 0 only when one
-+ * of the 3 different way is used. In all other case delay is
-+ * not enabled. With ID or TX/RXID delay is enabled and set
-+ * to the default and recommended value.
-+ */
-+ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
-+ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-+ }
-+
-+ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
-+ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-+ }
-+
-+ /* Set RGMII delay based on the selected values */
-+ ret = qca8k_rmw(priv, reg,
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
-+ val);
-+ if (ret)
-+ dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
-+ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
-+}
-+
-+static void
-+qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ const struct phylink_link_state *state)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int cpu_port_index, ret;
-+ u32 reg, val;
-+
-+ switch (port) {
-+ case 0: /* 1st CPU port */
-+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII)
-+ return;
-+
-+ reg = QCA8K_REG_PORT0_PAD_CTRL;
-+ cpu_port_index = QCA8K_CPU_PORT0;
-+ break;
-+ case 1:
-+ case 2:
-+ case 3:
-+ case 4:
-+ case 5:
-+ /* Internal PHY, nothing to do */
-+ return;
-+ case 6: /* 2nd CPU port / external PHY */
-+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII &&
-+ state->interface != PHY_INTERFACE_MODE_1000BASEX)
-+ return;
-+
-+ reg = QCA8K_REG_PORT6_PAD_CTRL;
-+ cpu_port_index = QCA8K_CPU_PORT6;
-+ break;
-+ default:
-+ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
-+ return;
-+ }
-+
-+ if (port != 6 && phylink_autoneg_inband(mode)) {
-+ dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
-+ __func__);
-+ return;
-+ }
-+
-+ switch (state->interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
-+
-+ /* Configure rgmii delay */
-+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-+
-+ /* QCA8337 requires to set rgmii rx delay for all ports.
-+ * This is enabled through PORT5_PAD_CTRL for all ports,
-+ * rather than individual port registers.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8337)
-+ qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ /* Enable SGMII on the port */
-+ qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-+
-+ /* Enable/disable SerDes auto-negotiation as necessary */
-+ ret = qca8k_read(priv, QCA8K_REG_PWS, &val);
-+ if (ret)
-+ return;
-+ if (phylink_autoneg_inband(mode))
-+ val &= ~QCA8K_PWS_SERDES_AEN_DIS;
-+ else
-+ val |= QCA8K_PWS_SERDES_AEN_DIS;
-+ qca8k_write(priv, QCA8K_REG_PWS, val);
-+
-+ /* Configure the SGMII parameters */
-+ ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
-+ if (ret)
-+ return;
-+
-+ val |= QCA8K_SGMII_EN_SD;
-+
-+ if (priv->ports_config.sgmii_enable_pll)
-+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-+ QCA8K_SGMII_EN_TX;
-+
-+ if (dsa_is_cpu_port(ds, port)) {
-+ /* CPU port, we're talking to the CPU MAC, be a PHY */
-+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-+ val |= QCA8K_SGMII_MODE_CTRL_PHY;
-+ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
-+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-+ val |= QCA8K_SGMII_MODE_CTRL_MAC;
-+ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
-+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-+ val |= QCA8K_SGMII_MODE_CTRL_BASEX;
-+ }
-+
-+ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
-+
-+ /* From original code is reported port instability as SGMII also
-+ * require delay set. Apply advised values here or take them from DT.
-+ */
-+ if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-+
-+ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
-+ * falling edge is set writing in the PORT0 PAD reg
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8327 ||
-+ priv->switch_id == QCA8K_ID_QCA8337)
-+ reg = QCA8K_REG_PORT0_PAD_CTRL;
-+
-+ val = 0;
-+
-+ /* SGMII Clock phase configuration */
-+ if (priv->ports_config.sgmii_rx_clk_falling_edge)
-+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
-+
-+ if (priv->ports_config.sgmii_tx_clk_falling_edge)
-+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
-+
-+ if (val)
-+ ret = qca8k_rmw(priv, reg,
-+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
-+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
-+ val);
-+
-+ break;
-+ default:
-+ dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
-+ phy_modes(state->interface), port);
-+ return;
-+ }
-+}
-+
-+static void
-+qca8k_phylink_validate(struct dsa_switch *ds, int port,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-+
-+ switch (port) {
-+ case 0: /* 1st CPU port */
-+ if (state->interface != PHY_INTERFACE_MODE_NA &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII)
-+ goto unsupported;
-+ break;
-+ case 1:
-+ case 2:
-+ case 3:
-+ case 4:
-+ case 5:
-+ /* Internal PHY */
-+ if (state->interface != PHY_INTERFACE_MODE_NA &&
-+ state->interface != PHY_INTERFACE_MODE_GMII &&
-+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
-+ goto unsupported;
-+ break;
-+ case 6: /* 2nd CPU port / external PHY */
-+ if (state->interface != PHY_INTERFACE_MODE_NA &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII &&
-+ state->interface != PHY_INTERFACE_MODE_1000BASEX)
-+ goto unsupported;
-+ break;
-+ default:
-+unsupported:
-+ linkmode_zero(supported);
-+ return;
-+ }
-+
-+ phylink_set_port_modes(mask);
-+ phylink_set(mask, Autoneg);
-+
-+ phylink_set(mask, 1000baseT_Full);
-+ phylink_set(mask, 10baseT_Half);
-+ phylink_set(mask, 10baseT_Full);
-+ phylink_set(mask, 100baseT_Half);
-+ phylink_set(mask, 100baseT_Full);
-+
-+ if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
-+ phylink_set(mask, 1000baseX_Full);
-+
-+ phylink_set(mask, Pause);
-+ phylink_set(mask, Asym_Pause);
-+
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-+}
-+
-+static int
-+qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port,
-+ struct phylink_link_state *state)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg;
-+ int ret;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
-+ state->an_complete = state->link;
-+ state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
-+ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
-+ DUPLEX_HALF;
-+
-+ switch (reg & QCA8K_PORT_STATUS_SPEED) {
-+ case QCA8K_PORT_STATUS_SPEED_10:
-+ state->speed = SPEED_10;
-+ break;
-+ case QCA8K_PORT_STATUS_SPEED_100:
-+ state->speed = SPEED_100;
-+ break;
-+ case QCA8K_PORT_STATUS_SPEED_1000:
-+ state->speed = SPEED_1000;
-+ break;
-+ default:
-+ state->speed = SPEED_UNKNOWN;
-+ break;
-+ }
-+
-+ state->pause = MLO_PAUSE_NONE;
-+ if (reg & QCA8K_PORT_STATUS_RXFLOW)
-+ state->pause |= MLO_PAUSE_RX;
-+ if (reg & QCA8K_PORT_STATUS_TXFLOW)
-+ state->pause |= MLO_PAUSE_TX;
-+
-+ return 1;
-+}
-+
-+static void
-+qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 0);
-+}
-+
-+static void
-+qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface, struct phy_device *phydev,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg;
-+
-+ if (phylink_autoneg_inband(mode)) {
-+ reg = QCA8K_PORT_STATUS_LINK_AUTO;
-+ } else {
-+ switch (speed) {
-+ case SPEED_10:
-+ reg = QCA8K_PORT_STATUS_SPEED_10;
-+ break;
-+ case SPEED_100:
-+ reg = QCA8K_PORT_STATUS_SPEED_100;
-+ break;
-+ case SPEED_1000:
-+ reg = QCA8K_PORT_STATUS_SPEED_1000;
-+ break;
-+ default:
-+ reg = QCA8K_PORT_STATUS_LINK_AUTO;
-+ break;
-+ }
-+
-+ if (duplex == DUPLEX_FULL)
-+ reg |= QCA8K_PORT_STATUS_DUPLEX;
-+
-+ if (rx_pause || dsa_is_cpu_port(ds, port))
-+ reg |= QCA8K_PORT_STATUS_RXFLOW;
-+
-+ if (tx_pause || dsa_is_cpu_port(ds, port))
-+ reg |= QCA8K_PORT_STATUS_TXFLOW;
-+ }
-+
-+ reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
-+
-+ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
-+}
-+
-+static void
-+qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
-+{
-+ const struct qca8k_match_data *match_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ int i;
-+
-+ if (stringset != ETH_SS_STATS)
-+ return;
-+
-+ match_data = of_device_get_match_data(priv->dev);
-+
-+ for (i = 0; i < match_data->mib_count; i++)
-+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-+ ETH_GSTRING_LEN);
-+}
-+
-+static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
-+{
-+ const struct qca8k_match_data *match_data;
-+ struct qca8k_mib_eth_data *mib_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ const struct qca8k_mib_desc *mib;
-+ struct mib_ethhdr *mib_ethhdr;
-+ int i, mib_len, offset = 0;
-+ u64 *data;
-+ u8 port;
-+
-+ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
-+ mib_eth_data = &priv->mib_eth_data;
-+
-+ /* The switch autocast every port. Ignore other packet and
-+ * parse only the requested one.
-+ */
-+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr));
-+ if (port != mib_eth_data->req_port)
-+ goto exit;
-+
-+ match_data = device_get_match_data(priv->dev);
-+ data = mib_eth_data->data;
-+
-+ for (i = 0; i < match_data->mib_count; i++) {
-+ mib = &ar8327_mib[i];
-+
-+ /* First 3 mib are present in the skb head */
-+ if (i < 3) {
-+ data[i] = mib_ethhdr->data[i];
-+ continue;
-+ }
-+
-+ mib_len = sizeof(uint32_t);
-+
-+ /* Some mib are 64 bit wide */
-+ if (mib->size == 2)
-+ mib_len = sizeof(uint64_t);
-+
-+ /* Copy the mib value from packet to the */
-+ memcpy(data + i, skb->data + offset, mib_len);
-+
-+ /* Set the offset for the next mib */
-+ offset += mib_len;
-+ }
-+
-+exit:
-+ /* Complete on receiving all the mib packet */
-+ if (refcount_dec_and_test(&mib_eth_data->port_parsed))
-+ complete(&mib_eth_data->rw_done);
-+}
-+
-+static int
-+qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
-+{
-+ struct dsa_port *dp = dsa_to_port(ds, port);
-+ struct qca8k_mib_eth_data *mib_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ mib_eth_data = &priv->mib_eth_data;
-+
-+ mutex_lock(&mib_eth_data->mutex);
-+
-+ reinit_completion(&mib_eth_data->rw_done);
-+
-+ mib_eth_data->req_port = dp->index;
-+ mib_eth_data->data = data;
-+ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS);
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ /* Send mib autocast request */
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) |
-+ QCA8K_MIB_BUSY);
-+
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ if (ret)
-+ goto exit;
-+
-+ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT);
-+
-+exit:
-+ mutex_unlock(&mib_eth_data->mutex);
-+
-+ return ret;
-+}
-+
-+static void
-+qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
-+ uint64_t *data)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ const struct qca8k_match_data *match_data;
-+ const struct qca8k_mib_desc *mib;
-+ u32 reg, i, val;
-+ u32 hi = 0;
-+ int ret;
-+
-+ if (priv->mgmt_master &&
-+ qca8k_get_ethtool_stats_eth(ds, port, data) > 0)
-+ return;
-+
-+ match_data = of_device_get_match_data(priv->dev);
-+
-+ for (i = 0; i < match_data->mib_count; i++) {
-+ mib = &ar8327_mib[i];
-+ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
-+
-+ ret = qca8k_read(priv, reg, &val);
-+ if (ret < 0)
-+ continue;
-+
-+ if (mib->size == 2) {
-+ ret = qca8k_read(priv, reg + 4, &hi);
-+ if (ret < 0)
-+ continue;
-+ }
-+
-+ data[i] = val;
-+ if (mib->size == 2)
-+ data[i] |= (u64)hi << 32;
-+ }
-+}
-+
-+static int
-+qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
-+{
-+ const struct qca8k_match_data *match_data;
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ if (sset != ETH_SS_STATS)
-+ return 0;
-+
-+ match_data = of_device_get_match_data(priv->dev);
-+
-+ return match_data->mib_count;
-+}
-+
-+static int
-+qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
-+ u32 reg;
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
-+ if (ret < 0)
-+ goto exit;
-+
-+ if (eee->eee_enabled)
-+ reg |= lpi_en;
-+ else
-+ reg &= ~lpi_en;
-+ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
-+qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
-+{
-+ /* Nothing to do on the port's MAC */
-+ return 0;
-+}
-+
-+static void
-+qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u32 stp_state;
-+
-+ switch (state) {
-+ case BR_STATE_DISABLED:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
-+ break;
-+ case BR_STATE_BLOCKING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
-+ break;
-+ case BR_STATE_LISTENING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
-+ break;
-+ case BR_STATE_LEARNING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
-+ break;
-+ case BR_STATE_FORWARDING:
-+ default:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
-+ break;
-+ }
-+
-+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
-+}
-+
-+static int
-+qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ int port_mask, cpu_port;
-+ int i, ret;
-+
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+ port_mask = BIT(cpu_port);
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
-+ if (dsa_to_port(ds, i)->bridge_dev != br)
-+ continue;
-+ /* Add this port to the portvlan mask of the other ports
-+ * in the bridge
-+ */
-+ ret = regmap_set_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
-+ if (ret)
-+ return ret;
-+ if (i != port)
-+ port_mask |= BIT(i);
-+ }
-+
-+ /* Add all other ports to this ports portvlan mask */
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER, port_mask);
-+
-+ return ret;
-+}
-+
-+static void
-+qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ int cpu_port, i;
-+
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
-+ if (dsa_to_port(ds, i)->bridge_dev != br)
-+ continue;
-+ /* Remove this port to the portvlan mask of the other ports
-+ * in the bridge
-+ */
-+ regmap_clear_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
-+ }
-+
-+ /* Set the cpu port to be the only one in the portvlan mask of
-+ * this port
-+ */
-+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
-+}
-+
-+static void
-+qca8k_port_fast_age(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static int
-+qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ unsigned int secs = msecs / 1000;
-+ u32 val;
-+
-+ /* AGE_TIME reg is set in 7s step */
-+ val = secs / 7;
-+
-+ /* Handle case with 0 as val to NOT disable
-+ * learning
-+ */
-+ if (!val)
-+ val = 1;
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
-+ QCA8K_ATU_AGE_TIME(val));
-+}
-+
-+static int
-+qca8k_port_enable(struct dsa_switch *ds, int port,
-+ struct phy_device *phy)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 1);
-+ priv->port_enabled_map |= BIT(port);
-+
-+ if (dsa_is_user_port(ds, port))
-+ phy_support_asym_pause(phy);
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_port_disable(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 0);
-+ priv->port_enabled_map &= ~BIT(port);
-+}
-+
-+static int
-+qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ /* We have only have a general MTU setting.
-+ * DSA always set the CPU port's MTU to the largest MTU of the slave
-+ * ports.
-+ * Setting MTU just for the CPU port is sufficient to correctly set a
-+ * value for every port.
-+ */
-+ if (!dsa_is_cpu_port(ds, port))
-+ return 0;
-+
-+ /* To change the MAX_FRAME_SIZE the cpu ports must be off or
-+ * the switch panics.
-+ * Turn off both cpu ports before applying the new value to prevent
-+ * this.
-+ */
-+ if (priv->port_enabled_map & BIT(0))
-+ qca8k_port_set_status(priv, 0, 0);
-+
-+ if (priv->port_enabled_map & BIT(6))
-+ qca8k_port_set_status(priv, 6, 0);
-+
-+ /* Include L2 header / FCS length */
-+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
-+
-+ if (priv->port_enabled_map & BIT(0))
-+ qca8k_port_set_status(priv, 0, 1);
-+
-+ if (priv->port_enabled_map & BIT(6))
-+ qca8k_port_set_status(priv, 6, 1);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_port_max_mtu(struct dsa_switch *ds, int port)
-+{
-+ return QCA8K_MAX_MTU;
-+}
-+
-+static int
-+qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
-+ u16 port_mask, u16 vid)
-+{
-+ /* Set the vid to the port vlan id if no vid is set */
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ return qca8k_fdb_add(priv, addr, port_mask, vid,
-+ QCA8K_ATU_STATUS_STATIC);
-+}
-+
-+static int
-+qca8k_port_fdb_add(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u16 port_mask = BIT(port);
-+
-+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
-+}
-+
-+static int
-+qca8k_port_fdb_del(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u16 port_mask = BIT(port);
-+
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ return qca8k_fdb_del(priv, addr, port_mask, vid);
-+}
-+
-+static int
-+qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
-+ dsa_fdb_dump_cb_t *cb, void *data)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ struct qca8k_fdb _fdb = { 0 };
-+ int cnt = QCA8K_NUM_FDB_RECORDS;
-+ bool is_static;
-+ int ret = 0;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
-+ if (!_fdb.aging)
-+ break;
-+ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
-+ ret = cb(_fdb.mac, _fdb.vid, is_static, data);
-+ if (ret)
-+ break;
-+ }
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
-+}
-+
-+static int
-+qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
-+}
-+
-+static int
-+qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror,
-+ bool ingress)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int monitor_port, ret;
-+ u32 reg, val;
-+
-+ /* Check for existent entry */
-+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
-+ return -EEXIST;
-+
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* QCA83xx can have only one port set to mirror mode.
-+ * Check that the correct port is requested and return error otherwise.
-+ * When no mirror port is set, the values is set to 0xF
-+ */
-+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
-+ return -EEXIST;
-+
-+ /* Set the monitor port */
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
-+ mirror->to_local_port);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ return ret;
-+
-+ if (ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_update_bits(priv->regmap, reg, val, val);
-+ if (ret)
-+ return ret;
-+
-+ /* Track mirror port for tx and rx to decide when the
-+ * mirror port has to be disabled.
-+ */
-+ if (ingress)
-+ priv->mirror_rx |= BIT(port);
-+ else
-+ priv->mirror_tx |= BIT(port);
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg, val;
-+ int ret;
-+
-+ if (mirror->ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_clear_bits(priv->regmap, reg, val);
-+ if (ret)
-+ goto err;
-+
-+ if (mirror->ingress)
-+ priv->mirror_rx &= ~BIT(port);
-+ else
-+ priv->mirror_tx &= ~BIT(port);
-+
-+ /* No port set to send packet to mirror port. Disable mirror port */
-+ if (!priv->mirror_rx && !priv->mirror_tx) {
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ goto err;
-+ }
-+err:
-+ dev_err(priv->dev, "Failed to del mirror port from %d", port);
-+}
-+
-+static int
-+qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ if (vlan_filtering) {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
-+ } else {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_port_vlan_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan,
-+ struct netlink_ext_ack *extack)
-+{
-+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
-+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
-+ if (ret) {
-+ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
-+ return ret;
-+ }
-+
-+ if (pvid) {
-+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-+ QCA8K_EGREES_VLAN_PORT_MASK(port),
-+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
-+ QCA8K_PORT_VLAN_CVID(vlan->vid) |
-+ QCA8K_PORT_VLAN_SVID(vlan->vid));
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_port_vlan_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ ret = qca8k_vlan_del(priv, port, vlan->vid);
-+ if (ret)
-+ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
-+
-+ return ret;
-+}
-+
-+static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Communicate to the phy internal driver the switch revision.
-+ * Based on the switch revision different values needs to be
-+ * set to the dbg and mmd reg on the phy.
-+ * The first 2 bit are used to communicate the switch revision
-+ * to the phy driver.
-+ */
-+ if (port > 0 && port < 6)
-+ return priv->switch_revision;
-+
-+ return 0;
-+}
-+
-+static enum dsa_tag_protocol
-+qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
-+ enum dsa_tag_protocol mp)
-+{
-+ return DSA_TAG_PROTO_QCA;
-+}
-+
-+static bool
-+qca8k_lag_can_offload(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct dsa_port *dp;
-+ int id, members = 0;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+ if (id < 0 || id >= ds->num_lag_ids)
-+ return false;
-+
-+ dsa_lag_foreach_port(dp, ds->dst, lag)
-+ /* Includes the port joining the LAG */
-+ members++;
-+
-+ if (members > QCA8K_NUM_PORTS_FOR_LAG)
-+ return false;
-+
-+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
-+ return false;
-+
-+ if (info->hash_type != NETDEV_LAG_HASH_L2 &&
-+ info->hash_type != NETDEV_LAG_HASH_L23)
-+ return false;
-+
-+ return true;
-+}
-+
-+static int
-+qca8k_lag_setup_hash(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ bool unique_lag = true;
-+ u32 hash = 0;
-+ int i, id;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ switch (info->hash_type) {
-+ case NETDEV_LAG_HASH_L23:
-+ hash |= QCA8K_TRUNK_HASH_SIP_EN;
-+ hash |= QCA8K_TRUNK_HASH_DIP_EN;
-+ fallthrough;
-+ case NETDEV_LAG_HASH_L2:
-+ hash |= QCA8K_TRUNK_HASH_SA_EN;
-+ hash |= QCA8K_TRUNK_HASH_DA_EN;
-+ break;
-+ default: /* We should NEVER reach this */
-+ return -EOPNOTSUPP;
-+ }
-+
-+ /* Check if we are the unique configured LAG */
-+ dsa_lags_foreach_id(i, ds->dst)
-+ if (i != id && dsa_lag_dev(ds->dst, i)) {
-+ unique_lag = false;
-+ break;
-+ }
-+
-+ /* Hash Mode is global. Make sure the same Hash Mode
-+ * is set to all the 4 possible lag.
-+ * If we are the unique LAG we can set whatever hash
-+ * mode we want.
-+ * To change hash mode it's needed to remove all LAG
-+ * and change the mode with the latest.
-+ */
-+ if (unique_lag) {
-+ priv->lag_hash_mode = hash;
-+ } else if (priv->lag_hash_mode != hash) {
-+ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
-+ QCA8K_TRUNK_HASH_MASK, hash);
-+}
-+
-+static int
-+qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
-+ struct net_device *lag, bool delete)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret, id, i;
-+ u32 val;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ /* Read current port member */
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* Shift val to the correct trunk */
-+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
-+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
-+ if (delete)
-+ val &= ~BIT(port);
-+ else
-+ val |= BIT(port);
-+
-+ /* Update port member. With empty portmap disable trunk */
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
-+ QCA8K_REG_GOL_TRUNK_MEMBER(id) |
-+ QCA8K_REG_GOL_TRUNK_EN(id),
-+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
-+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
-+
-+ /* Search empty member if adding or port on deleting */
-+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
-+ if (ret)
-+ return ret;
-+
-+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
-+
-+ if (delete) {
-+ /* If port flagged to be disabled assume this member is
-+ * empty
-+ */
-+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
-+ if (val != port)
-+ continue;
-+ } else {
-+ /* If port flagged to be enabled assume this member is
-+ * already set
-+ */
-+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+ }
-+
-+ /* We have found the member to add/remove */
-+ break;
-+ }
-+
-+ /* Set port in the correct port mask or disable port if in delete mode */
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
-+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
-+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
-+}
-+
-+static int
-+qca8k_port_lag_join(struct dsa_switch *ds, int port,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ int ret;
-+
-+ if (!qca8k_lag_can_offload(ds, lag, info))
-+ return -EOPNOTSUPP;
-+
-+ ret = qca8k_lag_setup_hash(ds, lag, info);
-+ if (ret)
-+ return ret;
-+
-+ return qca8k_lag_refresh_portmap(ds, port, lag, false);
-+}
-+
-+static int
-+qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-+ struct net_device *lag)
-+{
-+ return qca8k_lag_refresh_portmap(ds, port, lag, true);
-+}
-+
-+static void
-+qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
-+ bool operational)
-+{
-+ struct dsa_port *dp = master->dsa_ptr;
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Ethernet MIB/MDIO is only supported for CPU port 0 */
-+ if (dp->index != 0)
-+ return;
-+
-+ mutex_lock(&priv->mgmt_eth_data.mutex);
-+ mutex_lock(&priv->mib_eth_data.mutex);
-+
-+ priv->mgmt_master = operational ? (struct net_device *)master : NULL;
-+
-+ mutex_unlock(&priv->mib_eth_data.mutex);
-+ mutex_unlock(&priv->mgmt_eth_data.mutex);
-+}
-+
-+static int qca8k_connect_tag_protocol(struct dsa_switch *ds,
-+ enum dsa_tag_protocol proto)
-+{
-+ struct qca_tagger_data *tagger_data;
-+
-+ switch (proto) {
-+ case DSA_TAG_PROTO_QCA:
-+ tagger_data = ds->tagger_data;
-+
-+ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler;
-+ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler;
-+
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct dsa_switch_ops qca8k_switch_ops = {
-+ .get_tag_protocol = qca8k_get_tag_protocol,
-+ .setup = qca8k_setup,
-+ .get_strings = qca8k_get_strings,
-+ .get_ethtool_stats = qca8k_get_ethtool_stats,
-+ .get_sset_count = qca8k_get_sset_count,
-+ .set_ageing_time = qca8k_set_ageing_time,
-+ .get_mac_eee = qca8k_get_mac_eee,
-+ .set_mac_eee = qca8k_set_mac_eee,
-+ .port_enable = qca8k_port_enable,
-+ .port_disable = qca8k_port_disable,
-+ .port_change_mtu = qca8k_port_change_mtu,
-+ .port_max_mtu = qca8k_port_max_mtu,
-+ .port_stp_state_set = qca8k_port_stp_state_set,
-+ .port_bridge_join = qca8k_port_bridge_join,
-+ .port_bridge_leave = qca8k_port_bridge_leave,
-+ .port_fast_age = qca8k_port_fast_age,
-+ .port_fdb_add = qca8k_port_fdb_add,
-+ .port_fdb_del = qca8k_port_fdb_del,
-+ .port_fdb_dump = qca8k_port_fdb_dump,
-+ .port_mdb_add = qca8k_port_mdb_add,
-+ .port_mdb_del = qca8k_port_mdb_del,
-+ .port_mirror_add = qca8k_port_mirror_add,
-+ .port_mirror_del = qca8k_port_mirror_del,
-+ .port_vlan_filtering = qca8k_port_vlan_filtering,
-+ .port_vlan_add = qca8k_port_vlan_add,
-+ .port_vlan_del = qca8k_port_vlan_del,
-+ .phylink_validate = qca8k_phylink_validate,
-+ .phylink_mac_link_state = qca8k_phylink_mac_link_state,
-+ .phylink_mac_config = qca8k_phylink_mac_config,
-+ .phylink_mac_link_down = qca8k_phylink_mac_link_down,
-+ .phylink_mac_link_up = qca8k_phylink_mac_link_up,
-+ .get_phy_flags = qca8k_get_phy_flags,
-+ .port_lag_join = qca8k_port_lag_join,
-+ .port_lag_leave = qca8k_port_lag_leave,
-+ .master_state_change = qca8k_master_change,
-+ .connect_tag_protocol = qca8k_connect_tag_protocol,
-+};
-+
-+static int qca8k_read_switch_id(struct qca8k_priv *priv)
-+{
-+ const struct qca8k_match_data *data;
-+ u32 val;
-+ u8 id;
-+ int ret;
-+
-+ /* get the switches ID from the compatible */
-+ data = of_device_get_match_data(priv->dev);
-+ if (!data)
-+ return -ENODEV;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-+ if (ret < 0)
-+ return -ENODEV;
-+
-+ id = QCA8K_MASK_CTRL_DEVICE_ID(val);
-+ if (id != data->id) {
-+ dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id);
-+ return -ENODEV;
-+ }
-+
-+ priv->switch_id = id;
-+
-+ /* Save revision to communicate to the internal PHY driver */
-+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_sw_probe(struct mdio_device *mdiodev)
-+{
-+ struct qca8k_priv *priv;
-+ int ret;
-+
-+ /* allocate the private data struct so that we can probe the switches
-+ * ID register
-+ */
-+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->bus = mdiodev->bus;
-+ priv->dev = &mdiodev->dev;
-+
-+ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
-+ GPIOD_ASIS);
-+ if (IS_ERR(priv->reset_gpio))
-+ return PTR_ERR(priv->reset_gpio);
-+
-+ if (priv->reset_gpio) {
-+ gpiod_set_value_cansleep(priv->reset_gpio, 1);
-+ /* The active low duration must be greater than 10 ms
-+ * and checkpatch.pl wants 20 ms.
-+ */
-+ msleep(20);
-+ gpiod_set_value_cansleep(priv->reset_gpio, 0);
-+ }
-+
-+ /* Start by setting up the register mapping */
-+ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv,
-+ &qca8k_regmap_config);
-+ if (IS_ERR(priv->regmap)) {
-+ dev_err(priv->dev, "regmap initialization failed");
-+ return PTR_ERR(priv->regmap);
-+ }
-+
-+ priv->mdio_cache.page = 0xffff;
-+ priv->mdio_cache.lo = 0xffff;
-+ priv->mdio_cache.hi = 0xffff;
-+
-+ /* Check the detected switch id */
-+ ret = qca8k_read_switch_id(priv);
-+ if (ret)
-+ return ret;
-+
-+ priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-+ if (!priv->ds)
-+ return -ENOMEM;
-+
-+ mutex_init(&priv->mgmt_eth_data.mutex);
-+ init_completion(&priv->mgmt_eth_data.rw_done);
-+
-+ mutex_init(&priv->mib_eth_data.mutex);
-+ init_completion(&priv->mib_eth_data.rw_done);
-+
-+ priv->ds->dev = &mdiodev->dev;
-+ priv->ds->num_ports = QCA8K_NUM_PORTS;
-+ priv->ds->priv = priv;
-+ priv->ds->ops = &qca8k_switch_ops;
-+ mutex_init(&priv->reg_mutex);
-+ dev_set_drvdata(&mdiodev->dev, priv);
-+
-+ return dsa_register_switch(priv->ds);
-+}
-+
-+static void
-+qca8k_sw_remove(struct mdio_device *mdiodev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+ int i;
-+
-+ if (!priv)
-+ return;
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++)
-+ qca8k_port_set_status(priv, i, 0);
-+
-+ dsa_unregister_switch(priv->ds);
-+
-+ dev_set_drvdata(&mdiodev->dev, NULL);
-+}
-+
-+static void qca8k_sw_shutdown(struct mdio_device *mdiodev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+
-+ if (!priv)
-+ return;
-+
-+ dsa_switch_shutdown(priv->ds);
-+
-+ dev_set_drvdata(&mdiodev->dev, NULL);
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static void
-+qca8k_set_pm(struct qca8k_priv *priv, int enable)
-+{
-+ int port;
-+
-+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+ /* Do not enable on resume if the port was
-+ * disabled before.
-+ */
-+ if (!(priv->port_enabled_map & BIT(port)))
-+ continue;
-+
-+ qca8k_port_set_status(priv, port, enable);
-+ }
-+}
-+
-+static int qca8k_suspend(struct device *dev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(dev);
-+
-+ qca8k_set_pm(priv, 0);
-+
-+ return dsa_switch_suspend(priv->ds);
-+}
-+
-+static int qca8k_resume(struct device *dev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(dev);
-+
-+ qca8k_set_pm(priv, 1);
-+
-+ return dsa_switch_resume(priv->ds);
-+}
-+#endif /* CONFIG_PM_SLEEP */
-+
-+static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-+ qca8k_suspend, qca8k_resume);
-+
-+static const struct qca8k_match_data qca8327 = {
-+ .id = QCA8K_ID_QCA8327,
-+ .reduced_package = true,
-+ .mib_count = QCA8K_QCA832X_MIB_COUNT,
-+};
-+
-+static const struct qca8k_match_data qca8328 = {
-+ .id = QCA8K_ID_QCA8327,
-+ .mib_count = QCA8K_QCA832X_MIB_COUNT,
-+};
-+
-+static const struct qca8k_match_data qca833x = {
-+ .id = QCA8K_ID_QCA8337,
-+ .mib_count = QCA8K_QCA833X_MIB_COUNT,
-+};
-+
-+static const struct of_device_id qca8k_of_match[] = {
-+ { .compatible = "qca,qca8327", .data = &qca8327 },
-+ { .compatible = "qca,qca8328", .data = &qca8328 },
-+ { .compatible = "qca,qca8334", .data = &qca833x },
-+ { .compatible = "qca,qca8337", .data = &qca833x },
-+ { /* sentinel */ },
-+};
-+
-+static struct mdio_driver qca8kmdio_driver = {
-+ .probe = qca8k_sw_probe,
-+ .remove = qca8k_sw_remove,
-+ .shutdown = qca8k_sw_shutdown,
-+ .mdiodrv.driver = {
-+ .name = "qca8k",
-+ .of_match_table = qca8k_of_match,
-+ .pm = &qca8k_pm_ops,
-+ },
-+};
-+
-+mdio_module_driver(qca8kmdio_driver);
-+
-+MODULE_AUTHOR("Mathieu Olivari, John Crispin <john@phrozen.org>");
-+MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:qca8k");
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -0,0 +1,411 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
-+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
-+ */
-+
-+#ifndef __QCA8K_H
-+#define __QCA8K_H
-+
-+#include <linux/delay.h>
-+#include <linux/regmap.h>
-+#include <linux/gpio.h>
-+#include <linux/dsa/tag_qca.h>
-+
-+#define QCA8K_ETHERNET_MDIO_PRIORITY 7
-+#define QCA8K_ETHERNET_PHY_PRIORITY 6
-+#define QCA8K_ETHERNET_TIMEOUT 100
-+
-+#define QCA8K_NUM_PORTS 7
-+#define QCA8K_NUM_CPU_PORTS 2
-+#define QCA8K_MAX_MTU 9000
-+#define QCA8K_NUM_LAGS 4
-+#define QCA8K_NUM_PORTS_FOR_LAG 4
-+
-+#define PHY_ID_QCA8327 0x004dd034
-+#define QCA8K_ID_QCA8327 0x12
-+#define PHY_ID_QCA8337 0x004dd036
-+#define QCA8K_ID_QCA8337 0x13
-+
-+#define QCA8K_QCA832X_MIB_COUNT 39
-+#define QCA8K_QCA833X_MIB_COUNT 41
-+
-+#define QCA8K_BUSY_WAIT_TIMEOUT 2000
-+
-+#define QCA8K_NUM_FDB_RECORDS 2048
-+
-+#define QCA8K_PORT_VID_DEF 1
-+
-+/* Global control registers */
-+#define QCA8K_REG_MASK_CTRL 0x000
-+#define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0)
-+#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x)
-+#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8)
-+#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x)
-+#define QCA8K_REG_PORT0_PAD_CTRL 0x004
-+#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31)
-+#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19)
-+#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18)
-+#define QCA8K_REG_PORT5_PAD_CTRL 0x008
-+#define QCA8K_REG_PORT6_PAD_CTRL 0x00c
-+#define QCA8K_PORT_PAD_RGMII_EN BIT(26)
-+#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22)
-+#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x)
-+#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20)
-+#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x)
-+#define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25)
-+#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
-+#define QCA8K_PORT_PAD_SGMII_EN BIT(7)
-+#define QCA8K_REG_PWS 0x010
-+#define QCA8K_PWS_POWER_ON_SEL BIT(31)
-+/* This reg is only valid for QCA832x and toggle the package
-+ * type from 176 pin (by default) to 148 pin used on QCA8327
-+ */
-+#define QCA8327_PWS_PACKAGE148_EN BIT(30)
-+#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24)
-+#define QCA8K_PWS_SERDES_AEN_DIS BIT(7)
-+#define QCA8K_REG_MODULE_EN 0x030
-+#define QCA8K_MODULE_EN_MIB BIT(0)
-+#define QCA8K_REG_MIB 0x034
-+#define QCA8K_MIB_FUNC GENMASK(26, 24)
-+#define QCA8K_MIB_CPU_KEEP BIT(20)
-+#define QCA8K_MIB_BUSY BIT(17)
-+#define QCA8K_MDIO_MASTER_CTRL 0x3c
-+#define QCA8K_MDIO_MASTER_BUSY BIT(31)
-+#define QCA8K_MDIO_MASTER_EN BIT(30)
-+#define QCA8K_MDIO_MASTER_READ BIT(27)
-+#define QCA8K_MDIO_MASTER_WRITE 0
-+#define QCA8K_MDIO_MASTER_SUP_PRE BIT(26)
-+#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21)
-+#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x)
-+#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16)
-+#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x)
-+#define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0)
-+#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x)
-+#define QCA8K_MDIO_MASTER_MAX_PORTS 5
-+#define QCA8K_MDIO_MASTER_MAX_REG 32
-+#define QCA8K_GOL_MAC_ADDR0 0x60
-+#define QCA8K_GOL_MAC_ADDR1 0x64
-+#define QCA8K_MAX_FRAME_SIZE 0x78
-+#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
-+#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0)
-+#define QCA8K_PORT_STATUS_SPEED_10 0
-+#define QCA8K_PORT_STATUS_SPEED_100 0x1
-+#define QCA8K_PORT_STATUS_SPEED_1000 0x2
-+#define QCA8K_PORT_STATUS_TXMAC BIT(2)
-+#define QCA8K_PORT_STATUS_RXMAC BIT(3)
-+#define QCA8K_PORT_STATUS_TXFLOW BIT(4)
-+#define QCA8K_PORT_STATUS_RXFLOW BIT(5)
-+#define QCA8K_PORT_STATUS_DUPLEX BIT(6)
-+#define QCA8K_PORT_STATUS_LINK_UP BIT(8)
-+#define QCA8K_PORT_STATUS_LINK_AUTO BIT(9)
-+#define QCA8K_PORT_STATUS_LINK_PAUSE BIT(10)
-+#define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12)
-+#define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4))
-+#define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2)
-+#define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0)
-+#define QCA8K_PORT_HDR_CTRL_ALL 2
-+#define QCA8K_PORT_HDR_CTRL_MGMT 1
-+#define QCA8K_PORT_HDR_CTRL_NONE 0
-+#define QCA8K_REG_SGMII_CTRL 0x0e0
-+#define QCA8K_SGMII_EN_PLL BIT(1)
-+#define QCA8K_SGMII_EN_RX BIT(2)
-+#define QCA8K_SGMII_EN_TX BIT(3)
-+#define QCA8K_SGMII_EN_SD BIT(4)
-+#define QCA8K_SGMII_CLK125M_DELAY BIT(7)
-+#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22)
-+#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x)
-+#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0)
-+#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1)
-+#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2)
-+
-+/* MAC_PWR_SEL registers */
-+#define QCA8K_REG_MAC_PWR_SEL 0x0e4
-+#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18)
-+#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19)
-+
-+/* EEE control registers */
-+#define QCA8K_REG_EEE_CTRL 0x100
-+#define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2)
-+
-+/* TRUNK_HASH_EN registers */
-+#define QCA8K_TRUNK_HASH_EN_CTRL 0x270
-+#define QCA8K_TRUNK_HASH_SIP_EN BIT(3)
-+#define QCA8K_TRUNK_HASH_DIP_EN BIT(2)
-+#define QCA8K_TRUNK_HASH_SA_EN BIT(1)
-+#define QCA8K_TRUNK_HASH_DA_EN BIT(0)
-+#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0)
-+
-+/* ACL registers */
-+#define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8))
-+#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16)
-+#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x)
-+#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0)
-+#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x)
-+#define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8))
-+#define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470
-+#define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474
-+
-+/* Lookup registers */
-+#define QCA8K_REG_ATU_DATA0 0x600
-+#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24)
-+#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16)
-+#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8)
-+#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0)
-+#define QCA8K_REG_ATU_DATA1 0x604
-+#define QCA8K_ATU_PORT_MASK GENMASK(22, 16)
-+#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8)
-+#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0)
-+#define QCA8K_REG_ATU_DATA2 0x608
-+#define QCA8K_ATU_VID_MASK GENMASK(19, 8)
-+#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0)
-+#define QCA8K_ATU_STATUS_STATIC 0xf
-+#define QCA8K_REG_ATU_FUNC 0x60c
-+#define QCA8K_ATU_FUNC_BUSY BIT(31)
-+#define QCA8K_ATU_FUNC_PORT_EN BIT(14)
-+#define QCA8K_ATU_FUNC_MULTI_EN BIT(13)
-+#define QCA8K_ATU_FUNC_FULL BIT(12)
-+#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8)
-+#define QCA8K_REG_VTU_FUNC0 0x610
-+#define QCA8K_VTU_FUNC0_VALID BIT(20)
-+#define QCA8K_VTU_FUNC0_IVL_EN BIT(19)
-+/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4)
-+ * It does contain VLAN_MODE for each port [5:4] for port0,
-+ * [7:6] for port1 ... [17:16] for port6. Use virtual port
-+ * define to handle this.
-+ */
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2)
-+#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3)
-+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
-+#define QCA8K_REG_VTU_FUNC1 0x614
-+#define QCA8K_VTU_FUNC1_BUSY BIT(31)
-+#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16)
-+#define QCA8K_VTU_FUNC1_FULL BIT(4)
-+#define QCA8K_REG_ATU_CTRL 0x618
-+#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0)
-+#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x))
-+#define QCA8K_REG_GLOBAL_FW_CTRL0 0x620
-+#define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
-+#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4)
-+#define QCA8K_REG_GLOBAL_FW_CTRL1 0x624
-+#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24)
-+#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16)
-+#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8)
-+#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0)
-+#define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc)
-+#define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2)
-+#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3)
-+#define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16)
-+#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x)
-+#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0)
-+#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1)
-+#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2)
-+#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3)
-+#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4)
-+#define QCA8K_PORT_LOOKUP_LEARN BIT(20)
-+#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
-+
-+#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700
-+/* 4 max trunk first
-+ * first 6 bit for member bitmap
-+ * 7th bit is to enable trunk port
-+ */
-+#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8)
-+#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7)
-+#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i))
-+#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0)
-+#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i))
-+/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */
-+#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4))
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0)
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3)
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0)
-+#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16)
-+#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4)
-+/* Complex shift: FIRST shift for port THEN shift for trunk */
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i))
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j))
-+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j))
-+
-+#define QCA8K_REG_GLOBAL_FC_THRESH 0x800
-+#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16)
-+#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x)
-+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0)
-+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x)
-+
-+#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24)
-+#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x)
-+
-+#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8)
-+#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0)
-+#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x)
-+#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6)
-+#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7)
-+#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8)
-+#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16)
-+
-+/* Pkt edit registers */
-+#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2))
-+#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i))
-+#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i))
-+#define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2)))
-+
-+/* L3 registers */
-+#define QCA8K_HROUTER_CONTROL 0xe00
-+#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_M GENMASK(17, 16)
-+#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_S 16
-+#define QCA8K_HROUTER_CONTROL_ARP_AGE_MODE 1
-+#define QCA8K_HROUTER_PBASED_CONTROL1 0xe08
-+#define QCA8K_HROUTER_PBASED_CONTROL2 0xe0c
-+#define QCA8K_HNAT_CONTROL 0xe38
-+
-+/* MIB registers */
-+#define QCA8K_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100)
-+
-+/* QCA specific MII registers */
-+#define MII_ATH_MMD_ADDR 0x0d
-+#define MII_ATH_MMD_DATA 0x0e
-+
-+enum {
-+ QCA8K_PORT_SPEED_10M = 0,
-+ QCA8K_PORT_SPEED_100M = 1,
-+ QCA8K_PORT_SPEED_1000M = 2,
-+ QCA8K_PORT_SPEED_ERR = 3,
-+};
-+
-+enum qca8k_fdb_cmd {
-+ QCA8K_FDB_FLUSH = 1,
-+ QCA8K_FDB_LOAD = 2,
-+ QCA8K_FDB_PURGE = 3,
-+ QCA8K_FDB_FLUSH_PORT = 5,
-+ QCA8K_FDB_NEXT = 6,
-+ QCA8K_FDB_SEARCH = 7,
-+};
-+
-+enum qca8k_vlan_cmd {
-+ QCA8K_VLAN_FLUSH = 1,
-+ QCA8K_VLAN_LOAD = 2,
-+ QCA8K_VLAN_PURGE = 3,
-+ QCA8K_VLAN_REMOVE_PORT = 4,
-+ QCA8K_VLAN_NEXT = 5,
-+ QCA8K_VLAN_READ = 6,
-+};
-+
-+enum qca8k_mid_cmd {
-+ QCA8K_MIB_FLUSH = 1,
-+ QCA8K_MIB_FLUSH_PORT = 2,
-+ QCA8K_MIB_CAST = 3,
-+};
-+
-+struct qca8k_match_data {
-+ u8 id;
-+ bool reduced_package;
-+ u8 mib_count;
-+};
-+
-+enum {
-+ QCA8K_CPU_PORT0,
-+ QCA8K_CPU_PORT6,
-+};
-+
-+struct qca8k_mgmt_eth_data {
-+ struct completion rw_done;
-+ struct mutex mutex; /* Enforce one mdio read/write at time */
-+ bool ack;
-+ u32 seq;
-+ u32 data[4];
-+};
-+
-+struct qca8k_mib_eth_data {
-+ struct completion rw_done;
-+ struct mutex mutex; /* Process one command at time */
-+ refcount_t port_parsed; /* Counter to track parsed port */
-+ u8 req_port;
-+ u64 *data; /* pointer to ethtool data */
-+};
-+
-+struct qca8k_ports_config {
-+ bool sgmii_rx_clk_falling_edge;
-+ bool sgmii_tx_clk_falling_edge;
-+ bool sgmii_enable_pll;
-+ u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-+ u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-+};
-+
-+struct qca8k_mdio_cache {
-+/* The 32bit switch registers are accessed indirectly. To achieve this we need
-+ * to set the page of the register. Track the last page that was set to reduce
-+ * mdio writes
-+ */
-+ u16 page;
-+/* lo and hi can also be cached and from Documentation we can skip one
-+ * extra mdio write if lo or hi is didn't change.
-+ */
-+ u16 lo;
-+ u16 hi;
-+};
-+
-+struct qca8k_priv {
-+ u8 switch_id;
-+ u8 switch_revision;
-+ u8 mirror_rx;
-+ u8 mirror_tx;
-+ u8 lag_hash_mode;
-+ /* Each bit correspond to a port. This switch can support a max of 7 port.
-+ * Bit 1: port enabled. Bit 0: port disabled.
-+ */
-+ u8 port_enabled_map;
-+ struct qca8k_ports_config ports_config;
-+ struct regmap *regmap;
-+ struct mii_bus *bus;
-+ struct dsa_switch *ds;
-+ struct mutex reg_mutex;
-+ struct device *dev;
-+ struct gpio_desc *reset_gpio;
-+ struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
-+ struct qca8k_mgmt_eth_data mgmt_eth_data;
-+ struct qca8k_mib_eth_data mib_eth_data;
-+ struct qca8k_mdio_cache mdio_cache;
-+};
-+
-+struct qca8k_mib_desc {
-+ unsigned int size;
-+ unsigned int offset;
-+ const char *name;
-+};
-+
-+struct qca8k_fdb {
-+ u16 vid;
-+ u8 port_mask;
-+ u8 aging;
-+ u8 mac[6];
-+};
-+
-+#endif /* __QCA8K_H */
---- a/drivers/net/dsa/qca8k.c
-+++ /dev/null
-@@ -1,3243 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/*
-- * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
-- * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
-- * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
-- * Copyright (c) 2016 John Crispin <john@phrozen.org>
-- */
--
--#include <linux/module.h>
--#include <linux/phy.h>
--#include <linux/netdevice.h>
--#include <linux/bitfield.h>
--#include <linux/regmap.h>
--#include <net/dsa.h>
--#include <linux/of_net.h>
--#include <linux/of_mdio.h>
--#include <linux/of_platform.h>
--#include <linux/if_bridge.h>
--#include <linux/mdio.h>
--#include <linux/phylink.h>
--#include <linux/gpio/consumer.h>
--#include <linux/etherdevice.h>
--#include <linux/dsa/tag_qca.h>
--
--#include "qca8k.h"
--
--#define MIB_DESC(_s, _o, _n) \
-- { \
-- .size = (_s), \
-- .offset = (_o), \
-- .name = (_n), \
-- }
--
--static const struct qca8k_mib_desc ar8327_mib[] = {
-- MIB_DESC(1, 0x00, "RxBroad"),
-- MIB_DESC(1, 0x04, "RxPause"),
-- MIB_DESC(1, 0x08, "RxMulti"),
-- MIB_DESC(1, 0x0c, "RxFcsErr"),
-- MIB_DESC(1, 0x10, "RxAlignErr"),
-- MIB_DESC(1, 0x14, "RxRunt"),
-- MIB_DESC(1, 0x18, "RxFragment"),
-- MIB_DESC(1, 0x1c, "Rx64Byte"),
-- MIB_DESC(1, 0x20, "Rx128Byte"),
-- MIB_DESC(1, 0x24, "Rx256Byte"),
-- MIB_DESC(1, 0x28, "Rx512Byte"),
-- MIB_DESC(1, 0x2c, "Rx1024Byte"),
-- MIB_DESC(1, 0x30, "Rx1518Byte"),
-- MIB_DESC(1, 0x34, "RxMaxByte"),
-- MIB_DESC(1, 0x38, "RxTooLong"),
-- MIB_DESC(2, 0x3c, "RxGoodByte"),
-- MIB_DESC(2, 0x44, "RxBadByte"),
-- MIB_DESC(1, 0x4c, "RxOverFlow"),
-- MIB_DESC(1, 0x50, "Filtered"),
-- MIB_DESC(1, 0x54, "TxBroad"),
-- MIB_DESC(1, 0x58, "TxPause"),
-- MIB_DESC(1, 0x5c, "TxMulti"),
-- MIB_DESC(1, 0x60, "TxUnderRun"),
-- MIB_DESC(1, 0x64, "Tx64Byte"),
-- MIB_DESC(1, 0x68, "Tx128Byte"),
-- MIB_DESC(1, 0x6c, "Tx256Byte"),
-- MIB_DESC(1, 0x70, "Tx512Byte"),
-- MIB_DESC(1, 0x74, "Tx1024Byte"),
-- MIB_DESC(1, 0x78, "Tx1518Byte"),
-- MIB_DESC(1, 0x7c, "TxMaxByte"),
-- MIB_DESC(1, 0x80, "TxOverSize"),
-- MIB_DESC(2, 0x84, "TxByte"),
-- MIB_DESC(1, 0x8c, "TxCollision"),
-- MIB_DESC(1, 0x90, "TxAbortCol"),
-- MIB_DESC(1, 0x94, "TxMultiCol"),
-- MIB_DESC(1, 0x98, "TxSingleCol"),
-- MIB_DESC(1, 0x9c, "TxExcDefer"),
-- MIB_DESC(1, 0xa0, "TxDefer"),
-- MIB_DESC(1, 0xa4, "TxLateCol"),
-- MIB_DESC(1, 0xa8, "RXUnicast"),
-- MIB_DESC(1, 0xac, "TXUnicast"),
--};
--
--static void
--qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
--{
-- regaddr >>= 1;
-- *r1 = regaddr & 0x1e;
--
-- regaddr >>= 5;
-- *r2 = regaddr & 0x7;
--
-- regaddr >>= 3;
-- *page = regaddr & 0x3ff;
--}
--
--static int
--qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
--{
-- u16 *cached_lo = &priv->mdio_cache.lo;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (lo == *cached_lo)
-- return 0;
--
-- ret = bus->write(bus, phy_id, regnum, lo);
-- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit lo register\n");
--
-- *cached_lo = lo;
-- return 0;
--}
--
--static int
--qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
--{
-- u16 *cached_hi = &priv->mdio_cache.hi;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (hi == *cached_hi)
-- return 0;
--
-- ret = bus->write(bus, phy_id, regnum, hi);
-- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit hi register\n");
--
-- *cached_hi = hi;
-- return 0;
--}
--
--static int
--qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
--{
-- int ret;
--
-- ret = bus->read(bus, phy_id, regnum);
-- if (ret >= 0) {
-- *val = ret;
-- ret = bus->read(bus, phy_id, regnum + 1);
-- *val |= ret << 16;
-- }
--
-- if (ret < 0) {
-- dev_err_ratelimited(&bus->dev,
-- "failed to read qca8k 32bit register\n");
-- *val = 0;
-- return ret;
-- }
--
-- return 0;
--}
--
--static void
--qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
--{
-- u16 lo, hi;
-- int ret;
--
-- lo = val & 0xffff;
-- hi = (u16)(val >> 16);
--
-- ret = qca8k_set_lo(priv, phy_id, regnum, lo);
-- if (ret >= 0)
-- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
--}
--
--static int
--qca8k_set_page(struct qca8k_priv *priv, u16 page)
--{
-- u16 *cached_page = &priv->mdio_cache.page;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (page == *cached_page)
-- return 0;
--
-- ret = bus->write(bus, 0x18, 0, page);
-- if (ret < 0) {
-- dev_err_ratelimited(&bus->dev,
-- "failed to set qca8k page\n");
-- return ret;
-- }
--
-- *cached_page = page;
-- usleep_range(1000, 2000);
-- return 0;
--}
--
--static int
--qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
--{
-- return regmap_read(priv->regmap, reg, val);
--}
--
--static int
--qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
--{
-- return regmap_write(priv->regmap, reg, val);
--}
--
--static int
--qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
--{
-- return regmap_update_bits(priv->regmap, reg, mask, write_val);
--}
--
--static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
--{
-- struct qca8k_mgmt_eth_data *mgmt_eth_data;
-- struct qca8k_priv *priv = ds->priv;
-- struct qca_mgmt_ethhdr *mgmt_ethhdr;
-- u8 len, cmd;
--
-- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
-- mgmt_eth_data = &priv->mgmt_eth_data;
--
-- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
-- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
--
-- /* Make sure the seq match the requested packet */
-- if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
-- mgmt_eth_data->ack = true;
--
-- if (cmd == MDIO_READ) {
-- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
--
-- /* Get the rest of the 12 byte of data.
-- * The read/write function will extract the requested data.
-- */
-- if (len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(mgmt_eth_data->data + 1, skb->data,
-- QCA_HDR_MGMT_DATA2_LEN);
-- }
--
-- complete(&mgmt_eth_data->rw_done);
--}
--
--static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,
-- int priority, unsigned int len)
--{
-- struct qca_mgmt_ethhdr *mgmt_ethhdr;
-- unsigned int real_len;
-- struct sk_buff *skb;
-- u32 *data2;
-- u16 hdr;
--
-- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
-- if (!skb)
-- return NULL;
--
-- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
-- * Actually for some reason the steps are:
-- * 0: nothing
-- * 1-4: first 4 byte
-- * 5-6: first 12 byte
-- * 7-15: all 16 byte
-- */
-- if (len == 16)
-- real_len = 15;
-- else
-- real_len = len;
--
-- skb_reset_mac_header(skb);
-- skb_set_network_header(skb, skb->len);
--
-- mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);
--
-- hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
-- hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority);
-- hdr |= QCA_HDR_XMIT_FROM_CPU;
-- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
-- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
--
-- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
-- QCA_HDR_MGMT_CHECK_CODE_VAL);
--
-- if (cmd == MDIO_WRITE)
-- mgmt_ethhdr->mdio_data = *val;
--
-- mgmt_ethhdr->hdr = htons(hdr);
--
-- data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
--
-- return skb;
--}
--
--static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
--{
-- struct qca_mgmt_ethhdr *mgmt_ethhdr;
--
-- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
-- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
--}
--
--static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-- struct sk_buff *skb;
-- bool ack;
-- int ret;
--
-- skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,
-- QCA8K_ETHERNET_MDIO_PRIORITY, len);
-- if (!skb)
-- return -ENOMEM;
--
-- mutex_lock(&mgmt_eth_data->mutex);
--
-- /* Check mgmt_master if is operational */
-- if (!priv->mgmt_master) {
-- kfree_skb(skb);
-- mutex_unlock(&mgmt_eth_data->mutex);
-- return -EINVAL;
-- }
--
-- skb->dev = priv->mgmt_master;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the mdio pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
--
-- *val = mgmt_eth_data->data[0];
-- if (len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN);
--
-- ack = mgmt_eth_data->ack;
--
-- mutex_unlock(&mgmt_eth_data->mutex);
--
-- if (ret <= 0)
-- return -ETIMEDOUT;
--
-- if (!ack)
-- return -EINVAL;
--
-- return 0;
--}
--
--static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-- struct sk_buff *skb;
-- bool ack;
-- int ret;
--
-- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val,
-- QCA8K_ETHERNET_MDIO_PRIORITY, len);
-- if (!skb)
-- return -ENOMEM;
--
-- mutex_lock(&mgmt_eth_data->mutex);
--
-- /* Check mgmt_master if is operational */
-- if (!priv->mgmt_master) {
-- kfree_skb(skb);
-- mutex_unlock(&mgmt_eth_data->mutex);
-- return -EINVAL;
-- }
--
-- skb->dev = priv->mgmt_master;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the mdio pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
--
-- ack = mgmt_eth_data->ack;
--
-- mutex_unlock(&mgmt_eth_data->mutex);
--
-- if (ret <= 0)
-- return -ETIMEDOUT;
--
-- if (!ack)
-- return -EINVAL;
--
-- return 0;
--}
--
--static int
--qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
--{
-- u32 val = 0;
-- int ret;
--
-- ret = qca8k_read_eth(priv, reg, &val, sizeof(val));
-- if (ret)
-- return ret;
--
-- val &= ~mask;
-- val |= write_val;
--
-- return qca8k_write_eth(priv, reg, &val, sizeof(val));
--}
--
--static int
--qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
--
-- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
-- u32 tmp;
--
-- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- tmp = val[i];
--
-- ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- int ret;
--
-- if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
-- return 0;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret < 0)
-- goto exit;
--
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);
--
--exit:
-- mutex_unlock(&bus->mdio_lock);
-- return ret;
--}
--
--static int
--qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- int ret;
--
-- if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
-- return 0;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret < 0)
-- goto exit;
--
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
--exit:
-- mutex_unlock(&bus->mdio_lock);
-- return ret;
--}
--
--static int
--qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- u32 val;
-- int ret;
--
-- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
-- return 0;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret < 0)
-- goto exit;
--
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-- if (ret < 0)
-- goto exit;
--
-- val &= ~mask;
-- val |= write_val;
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
--exit:
-- mutex_unlock(&bus->mdio_lock);
--
-- return ret;
--}
--
--static const struct regmap_range qca8k_readable_ranges[] = {
-- regmap_reg_range(0x0000, 0x00e4), /* Global control */
-- regmap_reg_range(0x0100, 0x0168), /* EEE control */
-- regmap_reg_range(0x0200, 0x0270), /* Parser control */
-- regmap_reg_range(0x0400, 0x0454), /* ACL */
-- regmap_reg_range(0x0600, 0x0718), /* Lookup */
-- regmap_reg_range(0x0800, 0x0b70), /* QM */
-- regmap_reg_range(0x0c00, 0x0c80), /* PKT */
-- regmap_reg_range(0x0e00, 0x0e98), /* L3 */
-- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
--
--};
--
--static const struct regmap_access_table qca8k_readable_table = {
-- .yes_ranges = qca8k_readable_ranges,
-- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
--};
--
--static struct regmap_config qca8k_regmap_config = {
-- .reg_bits = 16,
-- .val_bits = 32,
-- .reg_stride = 4,
-- .max_register = 0x16ac, /* end MIB - Port6 range */
-- .reg_read = qca8k_regmap_read,
-- .reg_write = qca8k_regmap_write,
-- .reg_update_bits = qca8k_regmap_update_bits,
-- .rd_table = &qca8k_readable_table,
-- .disable_locking = true, /* Locking is handled by qca8k read/write */
-- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
--};
--
--static int
--qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
--{
-- u32 val;
--
-- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
-- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
--}
--
--static int
--qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
--{
-- u32 reg[3];
-- int ret;
--
-- /* load the ARL table into an array */
-- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-- if (ret)
-- return ret;
--
-- /* vid - 83:72 */
-- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
-- /* aging - 67:64 */
-- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
-- /* portmask - 54:48 */
-- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
-- /* mac - 47:0 */
-- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
-- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
-- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
-- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
-- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
-- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
--
-- return 0;
--}
--
--static void
--qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac,
-- u8 aging)
--{
-- u32 reg[3] = { 0 };
--
-- /* vid - 83:72 */
-- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-- /* aging - 67:64 */
-- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
-- /* portmask - 54:48 */
-- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
-- /* mac - 47:0 */
-- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
-- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
--
-- /* load the array into the ARL table */
-- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
--}
--
--static int
--qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
--{
-- u32 reg;
-- int ret;
--
-- /* Set the command and FDB index */
-- reg = QCA8K_ATU_FUNC_BUSY;
-- reg |= cmd;
-- if (port >= 0) {
-- reg |= QCA8K_ATU_FUNC_PORT_EN;
-- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
-- }
--
-- /* Write the function register triggering the table access */
-- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-- if (ret)
-- return ret;
--
-- /* wait for completion */
-- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
-- if (ret)
-- return ret;
--
-- /* Check for table full violation when adding an entry */
-- if (cmd == QCA8K_FDB_LOAD) {
-- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
-- if (ret < 0)
-- return ret;
-- if (reg & QCA8K_ATU_FUNC_FULL)
-- return -1;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port)
--{
-- int ret;
--
-- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
-- if (ret < 0)
-- return ret;
--
-- return qca8k_fdb_read(priv, fdb);
--}
--
--static int
--qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask,
-- u16 vid, u8 aging)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_write(priv, vid, port_mask, mac, aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_write(priv, vid, port_mask, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static void
--qca8k_fdb_flush(struct qca8k_priv *priv)
--{
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
-- mutex_unlock(&priv->reg_mutex);
--}
--
--static int
--qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
-- const u8 *mac, u16 vid)
--{
-- struct qca8k_fdb fdb = { 0 };
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
--
-- qca8k_fdb_write(priv, vid, 0, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-- if (ret < 0)
-- goto exit;
--
-- ret = qca8k_fdb_read(priv, &fdb);
-- if (ret < 0)
-- goto exit;
--
-- /* Rule exist. Delete first */
-- if (!fdb.aging) {
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- if (ret)
-- goto exit;
-- }
--
-- /* Add port to fdb portmask */
-- fdb.port_mask |= port_mask;
--
-- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
-- const u8 *mac, u16 vid)
--{
-- struct qca8k_fdb fdb = { 0 };
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
--
-- qca8k_fdb_write(priv, vid, 0, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-- if (ret < 0)
-- goto exit;
--
-- /* Rule doesn't exist. Why delete? */
-- if (!fdb.aging) {
-- ret = -EINVAL;
-- goto exit;
-- }
--
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- if (ret)
-- goto exit;
--
-- /* Only port in the rule is this port. Don't re insert */
-- if (fdb.port_mask == port_mask)
-- goto exit;
--
-- /* Remove port from port mask */
-- fdb.port_mask &= ~port_mask;
--
-- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
--{
-- u32 reg;
-- int ret;
--
-- /* Set the command and VLAN index */
-- reg = QCA8K_VTU_FUNC1_BUSY;
-- reg |= cmd;
-- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
--
-- /* Write the function register triggering the table access */
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-- if (ret)
-- return ret;
--
-- /* wait for completion */
-- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
-- if (ret)
-- return ret;
--
-- /* Check for table full violation when adding an entry */
-- if (cmd == QCA8K_VLAN_LOAD) {
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
-- if (ret < 0)
-- return ret;
-- if (reg & QCA8K_VTU_FUNC1_FULL)
-- return -ENOMEM;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
--{
-- u32 reg;
-- int ret;
--
-- /*
-- We do the right thing with VLAN 0 and treat it as untagged while
-- preserving the tag on egress.
-- */
-- if (vid == 0)
-- return 0;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-- if (ret < 0)
-- goto out;
--
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-- if (ret < 0)
-- goto out;
-- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-- if (untagged)
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
-- else
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
--
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-- if (ret)
-- goto out;
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
--
--out:
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
--{
-- u32 reg, mask;
-- int ret, i;
-- bool del;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-- if (ret < 0)
-- goto out;
--
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-- if (ret < 0)
-- goto out;
-- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
--
-- /* Check if we're the last member to be removed */
-- del = true;
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
--
-- if ((reg & mask) != mask) {
-- del = false;
-- break;
-- }
-- }
--
-- if (del) {
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
-- } else {
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-- if (ret)
-- goto out;
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-- }
--
--out:
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_mib_init(struct qca8k_priv *priv)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
-- QCA8K_MIB_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static void
--qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
--{
-- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
--
-- /* Port 0 and 6 have no internal PHY */
-- if (port > 0 && port < 6)
-- mask |= QCA8K_PORT_STATUS_LINK_AUTO;
--
-- if (enable)
-- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-- else
-- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
--}
--
--static int
--qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
-- struct sk_buff *read_skb, u32 *val)
--{
-- struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL);
-- bool ack;
-- int ret;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the copy pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- ack = mgmt_eth_data->ack;
--
-- if (ret <= 0)
-- return -ETIMEDOUT;
--
-- if (!ack)
-- return -EINVAL;
--
-- *val = mgmt_eth_data->data[0];
--
-- return 0;
--}
--
--static int
--qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,
-- int regnum, u16 data)
--{
-- struct sk_buff *write_skb, *clear_skb, *read_skb;
-- struct qca8k_mgmt_eth_data *mgmt_eth_data;
-- u32 write_val, clear_val = 0, val;
-- struct net_device *mgmt_master;
-- int ret, ret1;
-- bool ack;
--
-- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-- return -EINVAL;
--
-- mgmt_eth_data = &priv->mgmt_eth_data;
--
-- write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-- QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-- QCA8K_MDIO_MASTER_REG_ADDR(regnum);
--
-- if (read) {
-- write_val |= QCA8K_MDIO_MASTER_READ;
-- } else {
-- write_val |= QCA8K_MDIO_MASTER_WRITE;
-- write_val |= QCA8K_MDIO_MASTER_DATA(data);
-- }
--
-- /* Prealloc all the needed skb before the lock */
-- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val,
-- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val));
-- if (!write_skb)
-- return -ENOMEM;
--
-- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-- if (!clear_skb) {
-- ret = -ENOMEM;
-- goto err_clear_skb;
-- }
--
-- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-- if (!read_skb) {
-- ret = -ENOMEM;
-- goto err_read_skb;
-- }
--
-- /* Actually start the request:
-- * 1. Send mdio master packet
-- * 2. Busy Wait for mdio master command
-- * 3. Get the data if we are reading
-- * 4. Reset the mdio master (even with error)
-- */
-- mutex_lock(&mgmt_eth_data->mutex);
--
-- /* Check if mgmt_master is operational */
-- mgmt_master = priv->mgmt_master;
-- if (!mgmt_master) {
-- mutex_unlock(&mgmt_eth_data->mutex);
-- ret = -EINVAL;
-- goto err_mgmt_master;
-- }
--
-- read_skb->dev = mgmt_master;
-- clear_skb->dev = mgmt_master;
-- write_skb->dev = mgmt_master;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the write pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(write_skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- ack = mgmt_eth_data->ack;
--
-- if (ret <= 0) {
-- ret = -ETIMEDOUT;
-- kfree_skb(read_skb);
-- goto exit;
-- }
--
-- if (!ack) {
-- ret = -EINVAL;
-- kfree_skb(read_skb);
-- goto exit;
-- }
--
-- ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1,
-- !(val & QCA8K_MDIO_MASTER_BUSY), 0,
-- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-- mgmt_eth_data, read_skb, &val);
--
-- if (ret < 0 && ret1 < 0) {
-- ret = ret1;
-- goto exit;
-- }
--
-- if (read) {
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the read pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(read_skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- ack = mgmt_eth_data->ack;
--
-- if (ret <= 0) {
-- ret = -ETIMEDOUT;
-- goto exit;
-- }
--
-- if (!ack) {
-- ret = -EINVAL;
-- goto exit;
-- }
--
-- ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK;
-- } else {
-- kfree_skb(read_skb);
-- }
--exit:
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the clear pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(clear_skb);
--
-- wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- mutex_unlock(&mgmt_eth_data->mutex);
--
-- return ret;
--
-- /* Error handling before lock */
--err_mgmt_master:
-- kfree_skb(read_skb);
--err_read_skb:
-- kfree_skb(clear_skb);
--err_clear_skb:
-- kfree_skb(write_skb);
--
-- return ret;
--}
--
--static u32
--qca8k_port_to_phy(int port)
--{
-- /* From Andrew Lunn:
-- * Port 0 has no internal phy.
-- * Port 1 has an internal PHY at MDIO address 0.
-- * Port 2 has an internal PHY at MDIO address 1.
-- * ...
-- * Port 5 has an internal PHY at MDIO address 4.
-- * Port 6 has no internal PHY.
-- */
--
-- return port - 1;
--}
--
--static int
--qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
--{
-- u16 r1, r2, page;
-- u32 val;
-- int ret, ret1;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
-- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-- bus, 0x10 | r2, r1, &val);
--
-- /* Check if qca8k_read has failed for a different reason
-- * before returnting -ETIMEDOUT
-- */
-- if (ret < 0 && ret1 < 0)
-- return ret1;
--
-- return ret;
--}
--
--static int
--qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
--{
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- u32 val;
-- int ret;
--
-- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-- return -EINVAL;
--
-- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-- QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-- QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
-- QCA8K_MDIO_MASTER_DATA(data);
--
-- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret)
-- goto exit;
--
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
-- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-- QCA8K_MDIO_MASTER_BUSY);
--
--exit:
-- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
--
-- mutex_unlock(&bus->mdio_lock);
--
-- return ret;
--}
--
--static int
--qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
--{
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- u32 val;
-- int ret;
--
-- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-- return -EINVAL;
--
-- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-- QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-- QCA8K_MDIO_MASTER_REG_ADDR(regnum);
--
-- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret)
-- goto exit;
--
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
-- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-- QCA8K_MDIO_MASTER_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
--
--exit:
-- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
--
-- mutex_unlock(&bus->mdio_lock);
--
-- if (ret >= 0)
-- ret = val & QCA8K_MDIO_MASTER_DATA_MASK;
--
-- return ret;
--}
--
--static int
--qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
--{
-- struct qca8k_priv *priv = slave_bus->priv;
-- int ret;
--
-- /* Use mdio Ethernet when available, fallback to legacy one on error */
-- ret = qca8k_phy_eth_command(priv, false, phy, regnum, data);
-- if (!ret)
-- return 0;
--
-- return qca8k_mdio_write(priv, phy, regnum, data);
--}
--
--static int
--qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
--{
-- struct qca8k_priv *priv = slave_bus->priv;
-- int ret;
--
-- /* Use mdio Ethernet when available, fallback to legacy one on error */
-- ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0);
-- if (ret >= 0)
-- return ret;
--
-- ret = qca8k_mdio_read(priv, phy, regnum);
--
-- if (ret < 0)
-- return 0xffff;
--
-- return ret;
--}
--
--static int
--qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data)
--{
-- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
--
-- return qca8k_internal_mdio_write(slave_bus, port, regnum, data);
--}
--
--static int
--qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum)
--{
-- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
--
-- return qca8k_internal_mdio_read(slave_bus, port, regnum);
--}
--
--static int
--qca8k_mdio_register(struct qca8k_priv *priv)
--{
-- struct dsa_switch *ds = priv->ds;
-- struct device_node *mdio;
-- struct mii_bus *bus;
--
-- bus = devm_mdiobus_alloc(ds->dev);
-- if (!bus)
-- return -ENOMEM;
--
-- bus->priv = (void *)priv;
-- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
-- ds->dst->index, ds->index);
-- bus->parent = ds->dev;
-- bus->phy_mask = ~ds->phys_mii_mask;
-- ds->slave_mii_bus = bus;
--
-- /* Check if the devicetree declare the port:phy mapping */
-- mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
-- if (of_device_is_available(mdio)) {
-- bus->name = "qca8k slave mii";
-- bus->read = qca8k_internal_mdio_read;
-- bus->write = qca8k_internal_mdio_write;
-- return devm_of_mdiobus_register(priv->dev, bus, mdio);
-- }
--
-- /* If a mapping can't be found the legacy mapping is used,
-- * using the qca8k_port_to_phy function
-- */
-- bus->name = "qca8k-legacy slave mii";
-- bus->read = qca8k_legacy_mdio_read;
-- bus->write = qca8k_legacy_mdio_write;
-- return devm_mdiobus_register(priv->dev, bus);
--}
--
--static int
--qca8k_setup_mdio_bus(struct qca8k_priv *priv)
--{
-- u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
-- struct device_node *ports, *port;
-- phy_interface_t mode;
-- int err;
--
-- ports = of_get_child_by_name(priv->dev->of_node, "ports");
-- if (!ports)
-- ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports");
--
-- if (!ports)
-- return -EINVAL;
--
-- for_each_available_child_of_node(ports, port) {
-- err = of_property_read_u32(port, "reg", &reg);
-- if (err) {
-- of_node_put(port);
-- of_node_put(ports);
-- return err;
-- }
--
-- if (!dsa_is_user_port(priv->ds, reg))
-- continue;
--
-- of_get_phy_mode(port, &mode);
--
-- if (of_property_read_bool(port, "phy-handle") &&
-- mode != PHY_INTERFACE_MODE_INTERNAL)
-- external_mdio_mask |= BIT(reg);
-- else
-- internal_mdio_mask |= BIT(reg);
-- }
--
-- of_node_put(ports);
-- if (!external_mdio_mask && !internal_mdio_mask) {
-- dev_err(priv->dev, "no PHYs are defined.\n");
-- return -EINVAL;
-- }
--
-- /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through
-- * the MDIO_MASTER register also _disconnects_ the external MDC
-- * passthrough to the internal PHYs. It's not possible to use both
-- * configurations at the same time!
-- *
-- * Because this came up during the review process:
-- * If the external mdio-bus driver is capable magically disabling
-- * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's
-- * accessors for the time being, it would be possible to pull this
-- * off.
-- */
-- if (!!external_mdio_mask && !!internal_mdio_mask) {
-- dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n");
-- return -EINVAL;
-- }
--
-- if (external_mdio_mask) {
-- /* Make sure to disable the internal mdio bus in cases
-- * a dt-overlay and driver reload changed the configuration
-- */
--
-- return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL,
-- QCA8K_MDIO_MASTER_EN);
-- }
--
-- return qca8k_mdio_register(priv);
--}
--
--static int
--qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
--{
-- u32 mask = 0;
-- int ret = 0;
--
-- /* SoC specific settings for ipq8064.
-- * If more device require this consider adding
-- * a dedicated binding.
-- */
-- if (of_machine_is_compatible("qcom,ipq8064"))
-- mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
--
-- /* SoC specific settings for ipq8065 */
-- if (of_machine_is_compatible("qcom,ipq8065"))
-- mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
--
-- if (mask) {
-- ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
-- QCA8K_MAC_PWR_RGMII0_1_8V |
-- QCA8K_MAC_PWR_RGMII1_1_8V,
-- mask);
-- }
--
-- return ret;
--}
--
--static int qca8k_find_cpu_port(struct dsa_switch *ds)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- /* Find the connected cpu port. Valid port are 0 or 6 */
-- if (dsa_is_cpu_port(ds, 0))
-- return 0;
--
-- dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
--
-- if (dsa_is_cpu_port(ds, 6))
-- return 6;
--
-- return -EINVAL;
--}
--
--static int
--qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
--{
-- struct device_node *node = priv->dev->of_node;
-- const struct qca8k_match_data *data;
-- u32 val = 0;
-- int ret;
--
-- /* QCA8327 require to set to the correct mode.
-- * His bigger brother QCA8328 have the 172 pin layout.
-- * Should be applied by default but we set this just to make sure.
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8327) {
-- data = of_device_get_match_data(priv->dev);
--
-- /* Set the correct package of 148 pin for QCA8327 */
-- if (data->reduced_package)
-- val |= QCA8327_PWS_PACKAGE148_EN;
--
-- ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
-- val);
-- if (ret)
-- return ret;
-- }
--
-- if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
-- val |= QCA8K_PWS_POWER_ON_SEL;
--
-- if (of_property_read_bool(node, "qca,led-open-drain")) {
-- if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
-- dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
-- return -EINVAL;
-- }
--
-- val |= QCA8K_PWS_LED_OPEN_EN_CSR;
-- }
--
-- return qca8k_rmw(priv, QCA8K_REG_PWS,
-- QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
-- val);
--}
--
--static int
--qca8k_parse_port_config(struct qca8k_priv *priv)
--{
-- int port, cpu_port_index = -1, ret;
-- struct device_node *port_dn;
-- phy_interface_t mode;
-- struct dsa_port *dp;
-- u32 delay;
--
-- /* We have 2 CPU port. Check them */
-- for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-- /* Skip every other port */
-- if (port != 0 && port != 6)
-- continue;
--
-- dp = dsa_to_port(priv->ds, port);
-- port_dn = dp->dn;
-- cpu_port_index++;
--
-- if (!of_device_is_available(port_dn))
-- continue;
--
-- ret = of_get_phy_mode(port_dn, &mode);
-- if (ret)
-- continue;
--
-- switch (mode) {
-- case PHY_INTERFACE_MODE_RGMII:
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- case PHY_INTERFACE_MODE_SGMII:
-- delay = 0;
--
-- if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-- /* Switch regs accept value in ns, convert ps to ns */
-- delay = delay / 1000;
-- else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-- mode == PHY_INTERFACE_MODE_RGMII_TXID)
-- delay = 1;
--
-- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) {
-- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-- delay = 3;
-- }
--
-- priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
--
-- delay = 0;
--
-- if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
-- /* Switch regs accept value in ns, convert ps to ns */
-- delay = delay / 1000;
-- else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-- mode == PHY_INTERFACE_MODE_RGMII_RXID)
-- delay = 2;
--
-- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) {
-- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-- delay = 3;
-- }
--
-- priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
--
-- /* Skip sgmii parsing for rgmii* mode */
-- if (mode == PHY_INTERFACE_MODE_RGMII ||
-- mode == PHY_INTERFACE_MODE_RGMII_ID ||
-- mode == PHY_INTERFACE_MODE_RGMII_TXID ||
-- mode == PHY_INTERFACE_MODE_RGMII_RXID)
-- break;
--
-- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-- priv->ports_config.sgmii_tx_clk_falling_edge = true;
--
-- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-- priv->ports_config.sgmii_rx_clk_falling_edge = true;
--
-- if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
-- priv->ports_config.sgmii_enable_pll = true;
--
-- if (priv->switch_id == QCA8K_ID_QCA8327) {
-- dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
-- priv->ports_config.sgmii_enable_pll = false;
-- }
--
-- if (priv->switch_revision < 2)
-- dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
-- }
--
-- break;
-- default:
-- continue;
-- }
-- }
--
-- return 0;
--}
--
--static int
--qca8k_setup(struct dsa_switch *ds)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int cpu_port, ret, i;
-- u32 mask;
--
-- cpu_port = qca8k_find_cpu_port(ds);
-- if (cpu_port < 0) {
-- dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
-- return cpu_port;
-- }
--
-- /* Parse CPU port config to be later used in phy_link mac_config */
-- ret = qca8k_parse_port_config(priv);
-- if (ret)
-- return ret;
--
-- ret = qca8k_setup_mdio_bus(priv);
-- if (ret)
-- return ret;
--
-- ret = qca8k_setup_of_pws_reg(priv);
-- if (ret)
-- return ret;
--
-- ret = qca8k_setup_mac_pwr_sel(priv);
-- if (ret)
-- return ret;
--
-- /* Make sure MAC06 is disabled */
-- ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
-- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
-- if (ret) {
-- dev_err(priv->dev, "failed disabling MAC06 exchange");
-- return ret;
-- }
--
-- /* Enable CPU Port */
-- ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-- if (ret) {
-- dev_err(priv->dev, "failed enabling CPU port");
-- return ret;
-- }
--
-- /* Enable MIB counters */
-- ret = qca8k_mib_init(priv);
-- if (ret)
-- dev_warn(priv->dev, "mib init failed");
--
-- /* Initial setup of all ports */
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- /* Disable forwarding by default on all ports */
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER, 0);
-- if (ret)
-- return ret;
--
-- /* Enable QCA header mode on all cpu ports */
-- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
-- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
-- if (ret) {
-- dev_err(priv->dev, "failed enabling QCA header mode");
-- return ret;
-- }
-- }
--
-- /* Disable MAC by default on all user ports */
-- if (dsa_is_user_port(ds, i))
-- qca8k_port_set_status(priv, i, 0);
-- }
--
-- /* Forward all unknown frames to CPU port for Linux processing
-- * Notice that in multi-cpu config only one port should be set
-- * for igmp, unknown, multicast and broadcast packet
-- */
-- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
-- if (ret)
-- return ret;
--
-- /* Setup connection between CPU port & user ports
-- * Configure specific switch configuration for ports
-- */
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- /* CPU port gets connected to all user ports of the switch */
-- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-- if (ret)
-- return ret;
-- }
--
-- /* Individual user ports get connected to CPU port only */
-- if (dsa_is_user_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER,
-- BIT(cpu_port));
-- if (ret)
-- return ret;
--
-- /* Enable ARP Auto-learning by default */
-- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_LEARN);
-- if (ret)
-- return ret;
--
-- /* For port based vlans to work we need to set the
-- * default egress vid
-- */
-- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-- QCA8K_EGREES_VLAN_PORT_MASK(i),
-- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF));
-- if (ret)
-- return ret;
--
-- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-- if (ret)
-- return ret;
-- }
--
-- /* The port 5 of the qca8337 have some problem in flood condition. The
-- * original legacy driver had some specific buffer and priority settings
-- * for the different port suggested by the QCA switch team. Add this
-- * missing settings to improve switch stability under load condition.
-- * This problem is limited to qca8337 and other qca8k switch are not affected.
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8337) {
-- switch (i) {
-- /* The 2 CPU port and port 5 requires some different
-- * priority than any other ports.
-- */
-- case 0:
-- case 5:
-- case 6:
-- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
-- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
-- break;
-- default:
-- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
-- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
-- }
-- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
--
-- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
-- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_WRED_EN;
-- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
-- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
-- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_WRED_EN,
-- mask);
-- }
-- }
--
-- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-- if (priv->switch_id == QCA8K_ID_QCA8327) {
-- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
-- QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
-- qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
-- QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK |
-- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK,
-- mask);
-- }
--
-- /* Setup our port MTUs to match power on defaults */
-- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
-- if (ret)
-- dev_warn(priv->dev, "failed setting MTU settings");
--
-- /* Flush the FDB table */
-- qca8k_fdb_flush(priv);
--
-- /* We don't have interrupts for link changes, so we need to poll */
-- ds->pcs_poll = true;
--
-- /* Set min a max ageing value supported */
-- ds->ageing_time_min = 7000;
-- ds->ageing_time_max = 458745000;
--
-- /* Set max number of LAGs supported */
-- ds->num_lag_ids = QCA8K_NUM_LAGS;
--
-- return 0;
--}
--
--static void
--qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
-- u32 reg)
--{
-- u32 delay, val = 0;
-- int ret;
--
-- /* Delay can be declared in 3 different way.
-- * Mode to rgmii and internal-delay standard binding defined
-- * rgmii-id or rgmii-tx/rx phy mode set.
-- * The parse logic set a delay different than 0 only when one
-- * of the 3 different way is used. In all other case delay is
-- * not enabled. With ID or TX/RXID delay is enabled and set
-- * to the default and recommended value.
-- */
-- if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
-- delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
--
-- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-- }
--
-- if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
-- delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
--
-- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-- }
--
-- /* Set RGMII delay based on the selected values */
-- ret = qca8k_rmw(priv, reg,
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
-- val);
-- if (ret)
-- dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
-- cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
--}
--
--static void
--qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-- const struct phylink_link_state *state)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int cpu_port_index, ret;
-- u32 reg, val;
--
-- switch (port) {
-- case 0: /* 1st CPU port */
-- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII)
-- return;
--
-- reg = QCA8K_REG_PORT0_PAD_CTRL;
-- cpu_port_index = QCA8K_CPU_PORT0;
-- break;
-- case 1:
-- case 2:
-- case 3:
-- case 4:
-- case 5:
-- /* Internal PHY, nothing to do */
-- return;
-- case 6: /* 2nd CPU port / external PHY */
-- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII &&
-- state->interface != PHY_INTERFACE_MODE_1000BASEX)
-- return;
--
-- reg = QCA8K_REG_PORT6_PAD_CTRL;
-- cpu_port_index = QCA8K_CPU_PORT6;
-- break;
-- default:
-- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
-- return;
-- }
--
-- if (port != 6 && phylink_autoneg_inband(mode)) {
-- dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
-- __func__);
-- return;
-- }
--
-- switch (state->interface) {
-- case PHY_INTERFACE_MODE_RGMII:
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
--
-- /* Configure rgmii delay */
-- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
--
-- /* QCA8337 requires to set rgmii rx delay for all ports.
-- * This is enabled through PORT5_PAD_CTRL for all ports,
-- * rather than individual port registers.
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8337)
-- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-- break;
-- case PHY_INTERFACE_MODE_SGMII:
-- case PHY_INTERFACE_MODE_1000BASEX:
-- /* Enable SGMII on the port */
-- qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
--
-- /* Enable/disable SerDes auto-negotiation as necessary */
-- ret = qca8k_read(priv, QCA8K_REG_PWS, &val);
-- if (ret)
-- return;
-- if (phylink_autoneg_inband(mode))
-- val &= ~QCA8K_PWS_SERDES_AEN_DIS;
-- else
-- val |= QCA8K_PWS_SERDES_AEN_DIS;
-- qca8k_write(priv, QCA8K_REG_PWS, val);
--
-- /* Configure the SGMII parameters */
-- ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
-- if (ret)
-- return;
--
-- val |= QCA8K_SGMII_EN_SD;
--
-- if (priv->ports_config.sgmii_enable_pll)
-- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-- QCA8K_SGMII_EN_TX;
--
-- if (dsa_is_cpu_port(ds, port)) {
-- /* CPU port, we're talking to the CPU MAC, be a PHY */
-- val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-- val |= QCA8K_SGMII_MODE_CTRL_PHY;
-- } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
-- val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-- val |= QCA8K_SGMII_MODE_CTRL_MAC;
-- } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
-- val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-- val |= QCA8K_SGMII_MODE_CTRL_BASEX;
-- }
--
-- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
--
-- /* From original code is reported port instability as SGMII also
-- * require delay set. Apply advised values here or take them from DT.
-- */
-- if (state->interface == PHY_INTERFACE_MODE_SGMII)
-- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
--
-- /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
-- * falling edge is set writing in the PORT0 PAD reg
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8327 ||
-- priv->switch_id == QCA8K_ID_QCA8337)
-- reg = QCA8K_REG_PORT0_PAD_CTRL;
--
-- val = 0;
--
-- /* SGMII Clock phase configuration */
-- if (priv->ports_config.sgmii_rx_clk_falling_edge)
-- val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
--
-- if (priv->ports_config.sgmii_tx_clk_falling_edge)
-- val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
--
-- if (val)
-- ret = qca8k_rmw(priv, reg,
-- QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
-- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
-- val);
--
-- break;
-- default:
-- dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
-- phy_modes(state->interface), port);
-- return;
-- }
--}
--
--static void
--qca8k_phylink_validate(struct dsa_switch *ds, int port,
-- unsigned long *supported,
-- struct phylink_link_state *state)
--{
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
--
-- switch (port) {
-- case 0: /* 1st CPU port */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII)
-- goto unsupported;
-- break;
-- case 1:
-- case 2:
-- case 3:
-- case 4:
-- case 5:
-- /* Internal PHY */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_GMII &&
-- state->interface != PHY_INTERFACE_MODE_INTERNAL)
-- goto unsupported;
-- break;
-- case 6: /* 2nd CPU port / external PHY */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII &&
-- state->interface != PHY_INTERFACE_MODE_1000BASEX)
-- goto unsupported;
-- break;
-- default:
--unsupported:
-- linkmode_zero(supported);
-- return;
-- }
--
-- phylink_set_port_modes(mask);
-- phylink_set(mask, Autoneg);
--
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 10baseT_Half);
-- phylink_set(mask, 10baseT_Full);
-- phylink_set(mask, 100baseT_Half);
-- phylink_set(mask, 100baseT_Full);
--
-- if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
-- phylink_set(mask, 1000baseX_Full);
--
-- phylink_set(mask, Pause);
-- phylink_set(mask, Asym_Pause);
--
-- linkmode_and(supported, supported, mask);
-- linkmode_and(state->advertising, state->advertising, mask);
--}
--
--static int
--qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port,
-- struct phylink_link_state *state)
--{
-- struct qca8k_priv *priv = ds->priv;
-- u32 reg;
-- int ret;
--
-- ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
-- if (ret < 0)
-- return ret;
--
-- state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
-- state->an_complete = state->link;
-- state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
-- state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
-- DUPLEX_HALF;
--
-- switch (reg & QCA8K_PORT_STATUS_SPEED) {
-- case QCA8K_PORT_STATUS_SPEED_10:
-- state->speed = SPEED_10;
-- break;
-- case QCA8K_PORT_STATUS_SPEED_100:
-- state->speed = SPEED_100;
-- break;
-- case QCA8K_PORT_STATUS_SPEED_1000:
-- state->speed = SPEED_1000;
-- break;
-- default:
-- state->speed = SPEED_UNKNOWN;
-- break;
-- }
--
-- state->pause = MLO_PAUSE_NONE;
-- if (reg & QCA8K_PORT_STATUS_RXFLOW)
-- state->pause |= MLO_PAUSE_RX;
-- if (reg & QCA8K_PORT_STATUS_TXFLOW)
-- state->pause |= MLO_PAUSE_TX;
--
-- return 1;
--}
--
--static void
--qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
-- phy_interface_t interface)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- qca8k_port_set_status(priv, port, 0);
--}
--
--static void
--qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
-- phy_interface_t interface, struct phy_device *phydev,
-- int speed, int duplex, bool tx_pause, bool rx_pause)
--{
-- struct qca8k_priv *priv = ds->priv;
-- u32 reg;
--
-- if (phylink_autoneg_inband(mode)) {
-- reg = QCA8K_PORT_STATUS_LINK_AUTO;
-- } else {
-- switch (speed) {
-- case SPEED_10:
-- reg = QCA8K_PORT_STATUS_SPEED_10;
-- break;
-- case SPEED_100:
-- reg = QCA8K_PORT_STATUS_SPEED_100;
-- break;
-- case SPEED_1000:
-- reg = QCA8K_PORT_STATUS_SPEED_1000;
-- break;
-- default:
-- reg = QCA8K_PORT_STATUS_LINK_AUTO;
-- break;
-- }
--
-- if (duplex == DUPLEX_FULL)
-- reg |= QCA8K_PORT_STATUS_DUPLEX;
--
-- if (rx_pause || dsa_is_cpu_port(ds, port))
-- reg |= QCA8K_PORT_STATUS_RXFLOW;
--
-- if (tx_pause || dsa_is_cpu_port(ds, port))
-- reg |= QCA8K_PORT_STATUS_TXFLOW;
-- }
--
-- reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
--
-- qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
--}
--
--static void
--qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
--{
-- const struct qca8k_match_data *match_data;
-- struct qca8k_priv *priv = ds->priv;
-- int i;
--
-- if (stringset != ETH_SS_STATS)
-- return;
--
-- match_data = of_device_get_match_data(priv->dev);
--
-- for (i = 0; i < match_data->mib_count; i++)
-- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-- ETH_GSTRING_LEN);
--}
--
--static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
--{
-- const struct qca8k_match_data *match_data;
-- struct qca8k_mib_eth_data *mib_eth_data;
-- struct qca8k_priv *priv = ds->priv;
-- const struct qca8k_mib_desc *mib;
-- struct mib_ethhdr *mib_ethhdr;
-- int i, mib_len, offset = 0;
-- u64 *data;
-- u8 port;
--
-- mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
-- mib_eth_data = &priv->mib_eth_data;
--
-- /* The switch autocast every port. Ignore other packet and
-- * parse only the requested one.
-- */
-- port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr));
-- if (port != mib_eth_data->req_port)
-- goto exit;
--
-- match_data = device_get_match_data(priv->dev);
-- data = mib_eth_data->data;
--
-- for (i = 0; i < match_data->mib_count; i++) {
-- mib = &ar8327_mib[i];
--
-- /* First 3 mib are present in the skb head */
-- if (i < 3) {
-- data[i] = mib_ethhdr->data[i];
-- continue;
-- }
--
-- mib_len = sizeof(uint32_t);
--
-- /* Some mib are 64 bit wide */
-- if (mib->size == 2)
-- mib_len = sizeof(uint64_t);
--
-- /* Copy the mib value from packet to the */
-- memcpy(data + i, skb->data + offset, mib_len);
--
-- /* Set the offset for the next mib */
-- offset += mib_len;
-- }
--
--exit:
-- /* Complete on receiving all the mib packet */
-- if (refcount_dec_and_test(&mib_eth_data->port_parsed))
-- complete(&mib_eth_data->rw_done);
--}
--
--static int
--qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
--{
-- struct dsa_port *dp = dsa_to_port(ds, port);
-- struct qca8k_mib_eth_data *mib_eth_data;
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- mib_eth_data = &priv->mib_eth_data;
--
-- mutex_lock(&mib_eth_data->mutex);
--
-- reinit_completion(&mib_eth_data->rw_done);
--
-- mib_eth_data->req_port = dp->index;
-- mib_eth_data->data = data;
-- refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS);
--
-- mutex_lock(&priv->reg_mutex);
--
-- /* Send mib autocast request */
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) |
-- QCA8K_MIB_BUSY);
--
-- mutex_unlock(&priv->reg_mutex);
--
-- if (ret)
-- goto exit;
--
-- ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT);
--
--exit:
-- mutex_unlock(&mib_eth_data->mutex);
--
-- return ret;
--}
--
--static void
--qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
-- uint64_t *data)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- const struct qca8k_match_data *match_data;
-- const struct qca8k_mib_desc *mib;
-- u32 reg, i, val;
-- u32 hi = 0;
-- int ret;
--
-- if (priv->mgmt_master &&
-- qca8k_get_ethtool_stats_eth(ds, port, data) > 0)
-- return;
--
-- match_data = of_device_get_match_data(priv->dev);
--
-- for (i = 0; i < match_data->mib_count; i++) {
-- mib = &ar8327_mib[i];
-- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
--
-- ret = qca8k_read(priv, reg, &val);
-- if (ret < 0)
-- continue;
--
-- if (mib->size == 2) {
-- ret = qca8k_read(priv, reg + 4, &hi);
-- if (ret < 0)
-- continue;
-- }
--
-- data[i] = val;
-- if (mib->size == 2)
-- data[i] |= (u64)hi << 32;
-- }
--}
--
--static int
--qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
--{
-- const struct qca8k_match_data *match_data;
-- struct qca8k_priv *priv = ds->priv;
--
-- if (sset != ETH_SS_STATS)
-- return 0;
--
-- match_data = of_device_get_match_data(priv->dev);
--
-- return match_data->mib_count;
--}
--
--static int
--qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
-- u32 reg;
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
-- if (ret < 0)
-- goto exit;
--
-- if (eee->eee_enabled)
-- reg |= lpi_en;
-- else
-- reg &= ~lpi_en;
-- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
--{
-- /* Nothing to do on the port's MAC */
-- return 0;
--}
--
--static void
--qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u32 stp_state;
--
-- switch (state) {
-- case BR_STATE_DISABLED:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
-- break;
-- case BR_STATE_BLOCKING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
-- break;
-- case BR_STATE_LISTENING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
-- break;
-- case BR_STATE_LEARNING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
-- break;
-- case BR_STATE_FORWARDING:
-- default:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
-- break;
-- }
--
-- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
--}
--
--static int
--qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int port_mask, cpu_port;
-- int i, ret;
--
-- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-- port_mask = BIT(cpu_port);
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- if (dsa_is_cpu_port(ds, i))
-- continue;
-- if (dsa_to_port(ds, i)->bridge_dev != br)
-- continue;
-- /* Add this port to the portvlan mask of the other ports
-- * in the bridge
-- */
-- ret = regmap_set_bits(priv->regmap,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-- if (ret)
-- return ret;
-- if (i != port)
-- port_mask |= BIT(i);
-- }
--
-- /* Add all other ports to this ports portvlan mask */
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_MEMBER, port_mask);
--
-- return ret;
--}
--
--static void
--qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int cpu_port, i;
--
-- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- if (dsa_is_cpu_port(ds, i))
-- continue;
-- if (dsa_to_port(ds, i)->bridge_dev != br)
-- continue;
-- /* Remove this port to the portvlan mask of the other ports
-- * in the bridge
-- */
-- regmap_clear_bits(priv->regmap,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-- }
--
-- /* Set the cpu port to be the only one in the portvlan mask of
-- * this port
-- */
-- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
--}
--
--static void
--qca8k_port_fast_age(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
-- mutex_unlock(&priv->reg_mutex);
--}
--
--static int
--qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
--{
-- struct qca8k_priv *priv = ds->priv;
-- unsigned int secs = msecs / 1000;
-- u32 val;
--
-- /* AGE_TIME reg is set in 7s step */
-- val = secs / 7;
--
-- /* Handle case with 0 as val to NOT disable
-- * learning
-- */
-- if (!val)
-- val = 1;
--
-- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
-- QCA8K_ATU_AGE_TIME(val));
--}
--
--static int
--qca8k_port_enable(struct dsa_switch *ds, int port,
-- struct phy_device *phy)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--
-- qca8k_port_set_status(priv, port, 1);
-- priv->port_enabled_map |= BIT(port);
--
-- if (dsa_is_user_port(ds, port))
-- phy_support_asym_pause(phy);
--
-- return 0;
--}
--
--static void
--qca8k_port_disable(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--
-- qca8k_port_set_status(priv, port, 0);
-- priv->port_enabled_map &= ~BIT(port);
--}
--
--static int
--qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- /* We have only have a general MTU setting.
-- * DSA always set the CPU port's MTU to the largest MTU of the slave
-- * ports.
-- * Setting MTU just for the CPU port is sufficient to correctly set a
-- * value for every port.
-- */
-- if (!dsa_is_cpu_port(ds, port))
-- return 0;
--
-- /* To change the MAX_FRAME_SIZE the cpu ports must be off or
-- * the switch panics.
-- * Turn off both cpu ports before applying the new value to prevent
-- * this.
-- */
-- if (priv->port_enabled_map & BIT(0))
-- qca8k_port_set_status(priv, 0, 0);
--
-- if (priv->port_enabled_map & BIT(6))
-- qca8k_port_set_status(priv, 6, 0);
--
-- /* Include L2 header / FCS length */
-- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
--
-- if (priv->port_enabled_map & BIT(0))
-- qca8k_port_set_status(priv, 0, 1);
--
-- if (priv->port_enabled_map & BIT(6))
-- qca8k_port_set_status(priv, 6, 1);
--
-- return ret;
--}
--
--static int
--qca8k_port_max_mtu(struct dsa_switch *ds, int port)
--{
-- return QCA8K_MAX_MTU;
--}
--
--static int
--qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
-- u16 port_mask, u16 vid)
--{
-- /* Set the vid to the port vlan id if no vid is set */
-- if (!vid)
-- vid = QCA8K_PORT_VID_DEF;
--
-- return qca8k_fdb_add(priv, addr, port_mask, vid,
-- QCA8K_ATU_STATUS_STATIC);
--}
--
--static int
--qca8k_port_fdb_add(struct dsa_switch *ds, int port,
-- const unsigned char *addr, u16 vid)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u16 port_mask = BIT(port);
--
-- return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
--}
--
--static int
--qca8k_port_fdb_del(struct dsa_switch *ds, int port,
-- const unsigned char *addr, u16 vid)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u16 port_mask = BIT(port);
--
-- if (!vid)
-- vid = QCA8K_PORT_VID_DEF;
--
-- return qca8k_fdb_del(priv, addr, port_mask, vid);
--}
--
--static int
--qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
-- dsa_fdb_dump_cb_t *cb, void *data)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- struct qca8k_fdb _fdb = { 0 };
-- int cnt = QCA8K_NUM_FDB_RECORDS;
-- bool is_static;
-- int ret = 0;
--
-- mutex_lock(&priv->reg_mutex);
-- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
-- if (!_fdb.aging)
-- break;
-- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
-- ret = cb(_fdb.mac, _fdb.vid, is_static, data);
-- if (ret)
-- break;
-- }
-- mutex_unlock(&priv->reg_mutex);
--
-- return 0;
--}
--
--static int
--qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_mdb *mdb)
--{
-- struct qca8k_priv *priv = ds->priv;
-- const u8 *addr = mdb->addr;
-- u16 vid = mdb->vid;
--
-- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
--}
--
--static int
--qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_mdb *mdb)
--{
-- struct qca8k_priv *priv = ds->priv;
-- const u8 *addr = mdb->addr;
-- u16 vid = mdb->vid;
--
-- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
--}
--
--static int
--qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-- struct dsa_mall_mirror_tc_entry *mirror,
-- bool ingress)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int monitor_port, ret;
-- u32 reg, val;
--
-- /* Check for existent entry */
-- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
-- return -EEXIST;
--
-- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
-- if (ret)
-- return ret;
--
-- /* QCA83xx can have only one port set to mirror mode.
-- * Check that the correct port is requested and return error otherwise.
-- * When no mirror port is set, the values is set to 0xF
-- */
-- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
-- return -EEXIST;
--
-- /* Set the monitor port */
-- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
-- mirror->to_local_port);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (ret)
-- return ret;
--
-- if (ingress) {
-- reg = QCA8K_PORT_LOOKUP_CTRL(port);
-- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-- } else {
-- reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-- }
--
-- ret = regmap_update_bits(priv->regmap, reg, val, val);
-- if (ret)
-- return ret;
--
-- /* Track mirror port for tx and rx to decide when the
-- * mirror port has to be disabled.
-- */
-- if (ingress)
-- priv->mirror_rx |= BIT(port);
-- else
-- priv->mirror_tx |= BIT(port);
--
-- return 0;
--}
--
--static void
--qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-- struct dsa_mall_mirror_tc_entry *mirror)
--{
-- struct qca8k_priv *priv = ds->priv;
-- u32 reg, val;
-- int ret;
--
-- if (mirror->ingress) {
-- reg = QCA8K_PORT_LOOKUP_CTRL(port);
-- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-- } else {
-- reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-- }
--
-- ret = regmap_clear_bits(priv->regmap, reg, val);
-- if (ret)
-- goto err;
--
-- if (mirror->ingress)
-- priv->mirror_rx &= ~BIT(port);
-- else
-- priv->mirror_tx &= ~BIT(port);
--
-- /* No port set to send packet to mirror port. Disable mirror port */
-- if (!priv->mirror_rx && !priv->mirror_tx) {
-- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (ret)
-- goto err;
-- }
--err:
-- dev_err(priv->dev, "Failed to del mirror port from %d", port);
--}
--
--static int
--qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-- struct netlink_ext_ack *extack)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- if (vlan_filtering) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
-- } else {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
-- }
--
-- return ret;
--}
--
--static int
--qca8k_port_vlan_add(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_vlan *vlan,
-- struct netlink_ext_ack *extack)
--{
-- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
-- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
-- if (ret) {
-- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
-- return ret;
-- }
--
-- if (pvid) {
-- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-- QCA8K_EGREES_VLAN_PORT_MASK(port),
-- QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
-- if (ret)
-- return ret;
--
-- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
-- QCA8K_PORT_VLAN_CVID(vlan->vid) |
-- QCA8K_PORT_VLAN_SVID(vlan->vid));
-- }
--
-- return ret;
--}
--
--static int
--qca8k_port_vlan_del(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_vlan *vlan)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- ret = qca8k_vlan_del(priv, port, vlan->vid);
-- if (ret)
-- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
--
-- return ret;
--}
--
--static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- /* Communicate to the phy internal driver the switch revision.
-- * Based on the switch revision different values needs to be
-- * set to the dbg and mmd reg on the phy.
-- * The first 2 bit are used to communicate the switch revision
-- * to the phy driver.
-- */
-- if (port > 0 && port < 6)
-- return priv->switch_revision;
--
-- return 0;
--}
--
--static enum dsa_tag_protocol
--qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
-- enum dsa_tag_protocol mp)
--{
-- return DSA_TAG_PROTO_QCA;
--}
--
--static bool
--qca8k_lag_can_offload(struct dsa_switch *ds,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- struct dsa_port *dp;
-- int id, members = 0;
--
-- id = dsa_lag_id(ds->dst, lag);
-- if (id < 0 || id >= ds->num_lag_ids)
-- return false;
--
-- dsa_lag_foreach_port(dp, ds->dst, lag)
-- /* Includes the port joining the LAG */
-- members++;
--
-- if (members > QCA8K_NUM_PORTS_FOR_LAG)
-- return false;
--
-- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
-- return false;
--
-- if (info->hash_type != NETDEV_LAG_HASH_L2 &&
-- info->hash_type != NETDEV_LAG_HASH_L23)
-- return false;
--
-- return true;
--}
--
--static int
--qca8k_lag_setup_hash(struct dsa_switch *ds,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- struct qca8k_priv *priv = ds->priv;
-- bool unique_lag = true;
-- u32 hash = 0;
-- int i, id;
--
-- id = dsa_lag_id(ds->dst, lag);
--
-- switch (info->hash_type) {
-- case NETDEV_LAG_HASH_L23:
-- hash |= QCA8K_TRUNK_HASH_SIP_EN;
-- hash |= QCA8K_TRUNK_HASH_DIP_EN;
-- fallthrough;
-- case NETDEV_LAG_HASH_L2:
-- hash |= QCA8K_TRUNK_HASH_SA_EN;
-- hash |= QCA8K_TRUNK_HASH_DA_EN;
-- break;
-- default: /* We should NEVER reach this */
-- return -EOPNOTSUPP;
-- }
--
-- /* Check if we are the unique configured LAG */
-- dsa_lags_foreach_id(i, ds->dst)
-- if (i != id && dsa_lag_dev(ds->dst, i)) {
-- unique_lag = false;
-- break;
-- }
--
-- /* Hash Mode is global. Make sure the same Hash Mode
-- * is set to all the 4 possible lag.
-- * If we are the unique LAG we can set whatever hash
-- * mode we want.
-- * To change hash mode it's needed to remove all LAG
-- * and change the mode with the latest.
-- */
-- if (unique_lag) {
-- priv->lag_hash_mode = hash;
-- } else if (priv->lag_hash_mode != hash) {
-- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n");
-- return -EOPNOTSUPP;
-- }
--
-- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
-- QCA8K_TRUNK_HASH_MASK, hash);
--}
--
--static int
--qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
-- struct net_device *lag, bool delete)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret, id, i;
-- u32 val;
--
-- id = dsa_lag_id(ds->dst, lag);
--
-- /* Read current port member */
-- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
-- if (ret)
-- return ret;
--
-- /* Shift val to the correct trunk */
-- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
-- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
-- if (delete)
-- val &= ~BIT(port);
-- else
-- val |= BIT(port);
--
-- /* Update port member. With empty portmap disable trunk */
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
-- QCA8K_REG_GOL_TRUNK_MEMBER(id) |
-- QCA8K_REG_GOL_TRUNK_EN(id),
-- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
-- val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
--
-- /* Search empty member if adding or port on deleting */
-- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
-- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
-- if (ret)
-- return ret;
--
-- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
-- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
--
-- if (delete) {
-- /* If port flagged to be disabled assume this member is
-- * empty
-- */
-- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-- continue;
--
-- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
-- if (val != port)
-- continue;
-- } else {
-- /* If port flagged to be enabled assume this member is
-- * already set
-- */
-- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-- continue;
-- }
--
-- /* We have found the member to add/remove */
-- break;
-- }
--
-- /* Set port in the correct port mask or disable port if in delete mode */
-- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
-- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
-- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
-- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
-- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
--}
--
--static int
--qca8k_port_lag_join(struct dsa_switch *ds, int port,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- int ret;
--
-- if (!qca8k_lag_can_offload(ds, lag, info))
-- return -EOPNOTSUPP;
--
-- ret = qca8k_lag_setup_hash(ds, lag, info);
-- if (ret)
-- return ret;
--
-- return qca8k_lag_refresh_portmap(ds, port, lag, false);
--}
--
--static int
--qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-- struct net_device *lag)
--{
-- return qca8k_lag_refresh_portmap(ds, port, lag, true);
--}
--
--static void
--qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
-- bool operational)
--{
-- struct dsa_port *dp = master->dsa_ptr;
-- struct qca8k_priv *priv = ds->priv;
--
-- /* Ethernet MIB/MDIO is only supported for CPU port 0 */
-- if (dp->index != 0)
-- return;
--
-- mutex_lock(&priv->mgmt_eth_data.mutex);
-- mutex_lock(&priv->mib_eth_data.mutex);
--
-- priv->mgmt_master = operational ? (struct net_device *)master : NULL;
--
-- mutex_unlock(&priv->mib_eth_data.mutex);
-- mutex_unlock(&priv->mgmt_eth_data.mutex);
--}
--
--static int qca8k_connect_tag_protocol(struct dsa_switch *ds,
-- enum dsa_tag_protocol proto)
--{
-- struct qca_tagger_data *tagger_data;
--
-- switch (proto) {
-- case DSA_TAG_PROTO_QCA:
-- tagger_data = ds->tagger_data;
--
-- tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler;
-- tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler;
--
-- break;
-- default:
-- return -EOPNOTSUPP;
-- }
--
-- return 0;
--}
--
--static const struct dsa_switch_ops qca8k_switch_ops = {
-- .get_tag_protocol = qca8k_get_tag_protocol,
-- .setup = qca8k_setup,
-- .get_strings = qca8k_get_strings,
-- .get_ethtool_stats = qca8k_get_ethtool_stats,
-- .get_sset_count = qca8k_get_sset_count,
-- .set_ageing_time = qca8k_set_ageing_time,
-- .get_mac_eee = qca8k_get_mac_eee,
-- .set_mac_eee = qca8k_set_mac_eee,
-- .port_enable = qca8k_port_enable,
-- .port_disable = qca8k_port_disable,
-- .port_change_mtu = qca8k_port_change_mtu,
-- .port_max_mtu = qca8k_port_max_mtu,
-- .port_stp_state_set = qca8k_port_stp_state_set,
-- .port_bridge_join = qca8k_port_bridge_join,
-- .port_bridge_leave = qca8k_port_bridge_leave,
-- .port_fast_age = qca8k_port_fast_age,
-- .port_fdb_add = qca8k_port_fdb_add,
-- .port_fdb_del = qca8k_port_fdb_del,
-- .port_fdb_dump = qca8k_port_fdb_dump,
-- .port_mdb_add = qca8k_port_mdb_add,
-- .port_mdb_del = qca8k_port_mdb_del,
-- .port_mirror_add = qca8k_port_mirror_add,
-- .port_mirror_del = qca8k_port_mirror_del,
-- .port_vlan_filtering = qca8k_port_vlan_filtering,
-- .port_vlan_add = qca8k_port_vlan_add,
-- .port_vlan_del = qca8k_port_vlan_del,
-- .phylink_validate = qca8k_phylink_validate,
-- .phylink_mac_link_state = qca8k_phylink_mac_link_state,
-- .phylink_mac_config = qca8k_phylink_mac_config,
-- .phylink_mac_link_down = qca8k_phylink_mac_link_down,
-- .phylink_mac_link_up = qca8k_phylink_mac_link_up,
-- .get_phy_flags = qca8k_get_phy_flags,
-- .port_lag_join = qca8k_port_lag_join,
-- .port_lag_leave = qca8k_port_lag_leave,
-- .master_state_change = qca8k_master_change,
-- .connect_tag_protocol = qca8k_connect_tag_protocol,
--};
--
--static int qca8k_read_switch_id(struct qca8k_priv *priv)
--{
-- const struct qca8k_match_data *data;
-- u32 val;
-- u8 id;
-- int ret;
--
-- /* get the switches ID from the compatible */
-- data = of_device_get_match_data(priv->dev);
-- if (!data)
-- return -ENODEV;
--
-- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-- if (ret < 0)
-- return -ENODEV;
--
-- id = QCA8K_MASK_CTRL_DEVICE_ID(val);
-- if (id != data->id) {
-- dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id);
-- return -ENODEV;
-- }
--
-- priv->switch_id = id;
--
-- /* Save revision to communicate to the internal PHY driver */
-- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
--
-- return 0;
--}
--
--static int
--qca8k_sw_probe(struct mdio_device *mdiodev)
--{
-- struct qca8k_priv *priv;
-- int ret;
--
-- /* allocate the private data struct so that we can probe the switches
-- * ID register
-- */
-- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- priv->bus = mdiodev->bus;
-- priv->dev = &mdiodev->dev;
--
-- priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
-- GPIOD_ASIS);
-- if (IS_ERR(priv->reset_gpio))
-- return PTR_ERR(priv->reset_gpio);
--
-- if (priv->reset_gpio) {
-- gpiod_set_value_cansleep(priv->reset_gpio, 1);
-- /* The active low duration must be greater than 10 ms
-- * and checkpatch.pl wants 20 ms.
-- */
-- msleep(20);
-- gpiod_set_value_cansleep(priv->reset_gpio, 0);
-- }
--
-- /* Start by setting up the register mapping */
-- priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv,
-- &qca8k_regmap_config);
-- if (IS_ERR(priv->regmap)) {
-- dev_err(priv->dev, "regmap initialization failed");
-- return PTR_ERR(priv->regmap);
-- }
--
-- priv->mdio_cache.page = 0xffff;
-- priv->mdio_cache.lo = 0xffff;
-- priv->mdio_cache.hi = 0xffff;
--
-- /* Check the detected switch id */
-- ret = qca8k_read_switch_id(priv);
-- if (ret)
-- return ret;
--
-- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-- if (!priv->ds)
-- return -ENOMEM;
--
-- mutex_init(&priv->mgmt_eth_data.mutex);
-- init_completion(&priv->mgmt_eth_data.rw_done);
--
-- mutex_init(&priv->mib_eth_data.mutex);
-- init_completion(&priv->mib_eth_data.rw_done);
--
-- priv->ds->dev = &mdiodev->dev;
-- priv->ds->num_ports = QCA8K_NUM_PORTS;
-- priv->ds->priv = priv;
-- priv->ds->ops = &qca8k_switch_ops;
-- mutex_init(&priv->reg_mutex);
-- dev_set_drvdata(&mdiodev->dev, priv);
--
-- return dsa_register_switch(priv->ds);
--}
--
--static void
--qca8k_sw_remove(struct mdio_device *mdiodev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
-- int i;
--
-- if (!priv)
-- return;
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++)
-- qca8k_port_set_status(priv, i, 0);
--
-- dsa_unregister_switch(priv->ds);
--
-- dev_set_drvdata(&mdiodev->dev, NULL);
--}
--
--static void qca8k_sw_shutdown(struct mdio_device *mdiodev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
--
-- if (!priv)
-- return;
--
-- dsa_switch_shutdown(priv->ds);
--
-- dev_set_drvdata(&mdiodev->dev, NULL);
--}
--
--#ifdef CONFIG_PM_SLEEP
--static void
--qca8k_set_pm(struct qca8k_priv *priv, int enable)
--{
-- int port;
--
-- for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-- /* Do not enable on resume if the port was
-- * disabled before.
-- */
-- if (!(priv->port_enabled_map & BIT(port)))
-- continue;
--
-- qca8k_port_set_status(priv, port, enable);
-- }
--}
--
--static int qca8k_suspend(struct device *dev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(dev);
--
-- qca8k_set_pm(priv, 0);
--
-- return dsa_switch_suspend(priv->ds);
--}
--
--static int qca8k_resume(struct device *dev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(dev);
--
-- qca8k_set_pm(priv, 1);
--
-- return dsa_switch_resume(priv->ds);
--}
--#endif /* CONFIG_PM_SLEEP */
--
--static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-- qca8k_suspend, qca8k_resume);
--
--static const struct qca8k_match_data qca8327 = {
-- .id = QCA8K_ID_QCA8327,
-- .reduced_package = true,
-- .mib_count = QCA8K_QCA832X_MIB_COUNT,
--};
--
--static const struct qca8k_match_data qca8328 = {
-- .id = QCA8K_ID_QCA8327,
-- .mib_count = QCA8K_QCA832X_MIB_COUNT,
--};
--
--static const struct qca8k_match_data qca833x = {
-- .id = QCA8K_ID_QCA8337,
-- .mib_count = QCA8K_QCA833X_MIB_COUNT,
--};
--
--static const struct of_device_id qca8k_of_match[] = {
-- { .compatible = "qca,qca8327", .data = &qca8327 },
-- { .compatible = "qca,qca8328", .data = &qca8328 },
-- { .compatible = "qca,qca8334", .data = &qca833x },
-- { .compatible = "qca,qca8337", .data = &qca833x },
-- { /* sentinel */ },
--};
--
--static struct mdio_driver qca8kmdio_driver = {
-- .probe = qca8k_sw_probe,
-- .remove = qca8k_sw_remove,
-- .shutdown = qca8k_sw_shutdown,
-- .mdiodrv.driver = {
-- .name = "qca8k",
-- .of_match_table = qca8k_of_match,
-- .pm = &qca8k_pm_ops,
-- },
--};
--
--mdio_module_driver(qca8kmdio_driver);
--
--MODULE_AUTHOR("Mathieu Olivari, John Crispin <john@phrozen.org>");
--MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family");
--MODULE_LICENSE("GPL v2");
--MODULE_ALIAS("platform:qca8k");
---- a/drivers/net/dsa/qca8k.h
-+++ /dev/null
-@@ -1,411 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0-only */
--/*
-- * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
-- * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
-- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
-- */
--
--#ifndef __QCA8K_H
--#define __QCA8K_H
--
--#include <linux/delay.h>
--#include <linux/regmap.h>
--#include <linux/gpio.h>
--#include <linux/dsa/tag_qca.h>
--
--#define QCA8K_ETHERNET_MDIO_PRIORITY 7
--#define QCA8K_ETHERNET_PHY_PRIORITY 6
--#define QCA8K_ETHERNET_TIMEOUT 100
--
--#define QCA8K_NUM_PORTS 7
--#define QCA8K_NUM_CPU_PORTS 2
--#define QCA8K_MAX_MTU 9000
--#define QCA8K_NUM_LAGS 4
--#define QCA8K_NUM_PORTS_FOR_LAG 4
--
--#define PHY_ID_QCA8327 0x004dd034
--#define QCA8K_ID_QCA8327 0x12
--#define PHY_ID_QCA8337 0x004dd036
--#define QCA8K_ID_QCA8337 0x13
--
--#define QCA8K_QCA832X_MIB_COUNT 39
--#define QCA8K_QCA833X_MIB_COUNT 41
--
--#define QCA8K_BUSY_WAIT_TIMEOUT 2000
--
--#define QCA8K_NUM_FDB_RECORDS 2048
--
--#define QCA8K_PORT_VID_DEF 1
--
--/* Global control registers */
--#define QCA8K_REG_MASK_CTRL 0x000
--#define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0)
--#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x)
--#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8)
--#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x)
--#define QCA8K_REG_PORT0_PAD_CTRL 0x004
--#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31)
--#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19)
--#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18)
--#define QCA8K_REG_PORT5_PAD_CTRL 0x008
--#define QCA8K_REG_PORT6_PAD_CTRL 0x00c
--#define QCA8K_PORT_PAD_RGMII_EN BIT(26)
--#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22)
--#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x)
--#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20)
--#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x)
--#define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25)
--#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
--#define QCA8K_PORT_PAD_SGMII_EN BIT(7)
--#define QCA8K_REG_PWS 0x010
--#define QCA8K_PWS_POWER_ON_SEL BIT(31)
--/* This reg is only valid for QCA832x and toggle the package
-- * type from 176 pin (by default) to 148 pin used on QCA8327
-- */
--#define QCA8327_PWS_PACKAGE148_EN BIT(30)
--#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24)
--#define QCA8K_PWS_SERDES_AEN_DIS BIT(7)
--#define QCA8K_REG_MODULE_EN 0x030
--#define QCA8K_MODULE_EN_MIB BIT(0)
--#define QCA8K_REG_MIB 0x034
--#define QCA8K_MIB_FUNC GENMASK(26, 24)
--#define QCA8K_MIB_CPU_KEEP BIT(20)
--#define QCA8K_MIB_BUSY BIT(17)
--#define QCA8K_MDIO_MASTER_CTRL 0x3c
--#define QCA8K_MDIO_MASTER_BUSY BIT(31)
--#define QCA8K_MDIO_MASTER_EN BIT(30)
--#define QCA8K_MDIO_MASTER_READ BIT(27)
--#define QCA8K_MDIO_MASTER_WRITE 0
--#define QCA8K_MDIO_MASTER_SUP_PRE BIT(26)
--#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21)
--#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x)
--#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16)
--#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x)
--#define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0)
--#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x)
--#define QCA8K_MDIO_MASTER_MAX_PORTS 5
--#define QCA8K_MDIO_MASTER_MAX_REG 32
--#define QCA8K_GOL_MAC_ADDR0 0x60
--#define QCA8K_GOL_MAC_ADDR1 0x64
--#define QCA8K_MAX_FRAME_SIZE 0x78
--#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
--#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0)
--#define QCA8K_PORT_STATUS_SPEED_10 0
--#define QCA8K_PORT_STATUS_SPEED_100 0x1
--#define QCA8K_PORT_STATUS_SPEED_1000 0x2
--#define QCA8K_PORT_STATUS_TXMAC BIT(2)
--#define QCA8K_PORT_STATUS_RXMAC BIT(3)
--#define QCA8K_PORT_STATUS_TXFLOW BIT(4)
--#define QCA8K_PORT_STATUS_RXFLOW BIT(5)
--#define QCA8K_PORT_STATUS_DUPLEX BIT(6)
--#define QCA8K_PORT_STATUS_LINK_UP BIT(8)
--#define QCA8K_PORT_STATUS_LINK_AUTO BIT(9)
--#define QCA8K_PORT_STATUS_LINK_PAUSE BIT(10)
--#define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12)
--#define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4))
--#define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2)
--#define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0)
--#define QCA8K_PORT_HDR_CTRL_ALL 2
--#define QCA8K_PORT_HDR_CTRL_MGMT 1
--#define QCA8K_PORT_HDR_CTRL_NONE 0
--#define QCA8K_REG_SGMII_CTRL 0x0e0
--#define QCA8K_SGMII_EN_PLL BIT(1)
--#define QCA8K_SGMII_EN_RX BIT(2)
--#define QCA8K_SGMII_EN_TX BIT(3)
--#define QCA8K_SGMII_EN_SD BIT(4)
--#define QCA8K_SGMII_CLK125M_DELAY BIT(7)
--#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22)
--#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x)
--#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0)
--#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1)
--#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2)
--
--/* MAC_PWR_SEL registers */
--#define QCA8K_REG_MAC_PWR_SEL 0x0e4
--#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18)
--#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19)
--
--/* EEE control registers */
--#define QCA8K_REG_EEE_CTRL 0x100
--#define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2)
--
--/* TRUNK_HASH_EN registers */
--#define QCA8K_TRUNK_HASH_EN_CTRL 0x270
--#define QCA8K_TRUNK_HASH_SIP_EN BIT(3)
--#define QCA8K_TRUNK_HASH_DIP_EN BIT(2)
--#define QCA8K_TRUNK_HASH_SA_EN BIT(1)
--#define QCA8K_TRUNK_HASH_DA_EN BIT(0)
--#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0)
--
--/* ACL registers */
--#define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8))
--#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16)
--#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x)
--#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0)
--#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x)
--#define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8))
--#define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470
--#define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474
--
--/* Lookup registers */
--#define QCA8K_REG_ATU_DATA0 0x600
--#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24)
--#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16)
--#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8)
--#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0)
--#define QCA8K_REG_ATU_DATA1 0x604
--#define QCA8K_ATU_PORT_MASK GENMASK(22, 16)
--#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8)
--#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0)
--#define QCA8K_REG_ATU_DATA2 0x608
--#define QCA8K_ATU_VID_MASK GENMASK(19, 8)
--#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0)
--#define QCA8K_ATU_STATUS_STATIC 0xf
--#define QCA8K_REG_ATU_FUNC 0x60c
--#define QCA8K_ATU_FUNC_BUSY BIT(31)
--#define QCA8K_ATU_FUNC_PORT_EN BIT(14)
--#define QCA8K_ATU_FUNC_MULTI_EN BIT(13)
--#define QCA8K_ATU_FUNC_FULL BIT(12)
--#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8)
--#define QCA8K_REG_VTU_FUNC0 0x610
--#define QCA8K_VTU_FUNC0_VALID BIT(20)
--#define QCA8K_VTU_FUNC0_IVL_EN BIT(19)
--/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4)
-- * It does contain VLAN_MODE for each port [5:4] for port0,
-- * [7:6] for port1 ... [17:16] for port6. Use virtual port
-- * define to handle this.
-- */
--#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2)
--#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0)
--#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
--#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0)
--#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
--#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1)
--#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
--#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2)
--#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
--#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3)
--#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i))
--#define QCA8K_REG_VTU_FUNC1 0x614
--#define QCA8K_VTU_FUNC1_BUSY BIT(31)
--#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16)
--#define QCA8K_VTU_FUNC1_FULL BIT(4)
--#define QCA8K_REG_ATU_CTRL 0x618
--#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0)
--#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x))
--#define QCA8K_REG_GLOBAL_FW_CTRL0 0x620
--#define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
--#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4)
--#define QCA8K_REG_GLOBAL_FW_CTRL1 0x624
--#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24)
--#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16)
--#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8)
--#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0)
--#define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc)
--#define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2)
--#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3)
--#define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16)
--#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x)
--#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0)
--#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1)
--#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2)
--#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3)
--#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4)
--#define QCA8K_PORT_LOOKUP_LEARN BIT(20)
--#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
--
--#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700
--/* 4 max trunk first
-- * first 6 bit for member bitmap
-- * 7th bit is to enable trunk port
-- */
--#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8)
--#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7)
--#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i))
--#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0)
--#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i))
--/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */
--#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4))
--#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0)
--#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3)
--#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0)
--#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16)
--#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4)
--/* Complex shift: FIRST shift for port THEN shift for trunk */
--#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i))
--#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j))
--#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j))
--
--#define QCA8K_REG_GLOBAL_FC_THRESH 0x800
--#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16)
--#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x)
--#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0)
--#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x)
--
--#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20)
--#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x)
--#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24)
--#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x)
--
--#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8)
--#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0)
--#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x)
--#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6)
--#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7)
--#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8)
--#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16)
--
--/* Pkt edit registers */
--#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2))
--#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i))
--#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i))
--#define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2)))
--
--/* L3 registers */
--#define QCA8K_HROUTER_CONTROL 0xe00
--#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_M GENMASK(17, 16)
--#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_S 16
--#define QCA8K_HROUTER_CONTROL_ARP_AGE_MODE 1
--#define QCA8K_HROUTER_PBASED_CONTROL1 0xe08
--#define QCA8K_HROUTER_PBASED_CONTROL2 0xe0c
--#define QCA8K_HNAT_CONTROL 0xe38
--
--/* MIB registers */
--#define QCA8K_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100)
--
--/* QCA specific MII registers */
--#define MII_ATH_MMD_ADDR 0x0d
--#define MII_ATH_MMD_DATA 0x0e
--
--enum {
-- QCA8K_PORT_SPEED_10M = 0,
-- QCA8K_PORT_SPEED_100M = 1,
-- QCA8K_PORT_SPEED_1000M = 2,
-- QCA8K_PORT_SPEED_ERR = 3,
--};
--
--enum qca8k_fdb_cmd {
-- QCA8K_FDB_FLUSH = 1,
-- QCA8K_FDB_LOAD = 2,
-- QCA8K_FDB_PURGE = 3,
-- QCA8K_FDB_FLUSH_PORT = 5,
-- QCA8K_FDB_NEXT = 6,
-- QCA8K_FDB_SEARCH = 7,
--};
--
--enum qca8k_vlan_cmd {
-- QCA8K_VLAN_FLUSH = 1,
-- QCA8K_VLAN_LOAD = 2,
-- QCA8K_VLAN_PURGE = 3,
-- QCA8K_VLAN_REMOVE_PORT = 4,
-- QCA8K_VLAN_NEXT = 5,
-- QCA8K_VLAN_READ = 6,
--};
--
--enum qca8k_mid_cmd {
-- QCA8K_MIB_FLUSH = 1,
-- QCA8K_MIB_FLUSH_PORT = 2,
-- QCA8K_MIB_CAST = 3,
--};
--
--struct qca8k_match_data {
-- u8 id;
-- bool reduced_package;
-- u8 mib_count;
--};
--
--enum {
-- QCA8K_CPU_PORT0,
-- QCA8K_CPU_PORT6,
--};
--
--struct qca8k_mgmt_eth_data {
-- struct completion rw_done;
-- struct mutex mutex; /* Enforce one mdio read/write at time */
-- bool ack;
-- u32 seq;
-- u32 data[4];
--};
--
--struct qca8k_mib_eth_data {
-- struct completion rw_done;
-- struct mutex mutex; /* Process one command at time */
-- refcount_t port_parsed; /* Counter to track parsed port */
-- u8 req_port;
-- u64 *data; /* pointer to ethtool data */
--};
--
--struct qca8k_ports_config {
-- bool sgmii_rx_clk_falling_edge;
-- bool sgmii_tx_clk_falling_edge;
-- bool sgmii_enable_pll;
-- u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-- u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
--};
--
--struct qca8k_mdio_cache {
--/* The 32bit switch registers are accessed indirectly. To achieve this we need
-- * to set the page of the register. Track the last page that was set to reduce
-- * mdio writes
-- */
-- u16 page;
--/* lo and hi can also be cached and from Documentation we can skip one
-- * extra mdio write if lo or hi is didn't change.
-- */
-- u16 lo;
-- u16 hi;
--};
--
--struct qca8k_priv {
-- u8 switch_id;
-- u8 switch_revision;
-- u8 mirror_rx;
-- u8 mirror_tx;
-- u8 lag_hash_mode;
-- /* Each bit correspond to a port. This switch can support a max of 7 port.
-- * Bit 1: port enabled. Bit 0: port disabled.
-- */
-- u8 port_enabled_map;
-- struct qca8k_ports_config ports_config;
-- struct regmap *regmap;
-- struct mii_bus *bus;
-- struct dsa_switch *ds;
-- struct mutex reg_mutex;
-- struct device *dev;
-- struct gpio_desc *reset_gpio;
-- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */
-- struct qca8k_mgmt_eth_data mgmt_eth_data;
-- struct qca8k_mib_eth_data mib_eth_data;
-- struct qca8k_mdio_cache mdio_cache;
--};
--
--struct qca8k_mib_desc {
-- unsigned int size;
-- unsigned int offset;
-- const char *name;
--};
--
--struct qca8k_fdb {
-- u16 vid;
-- u8 port_mask;
-- u8 aging;
-- u8 mac[6];
--};
--
--#endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch b/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch
deleted file mode 100644
index 77fe64632f..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-From 3bb0844e7bcd0fb0bcfab6202b5edd349ef5250a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:10 +0200
-Subject: [PATCH 01/14] net: dsa: qca8k: cache match data to speed up access
-
-Using of_device_get_match_data is expensive. Cache match data to speed
-up access and rework user of match data to use the new cached value.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k.c | 35 +++++++++++------------------------
- drivers/net/dsa/qca/qca8k.h | 1 +
- 2 files changed, 12 insertions(+), 24 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k.c
-+++ b/drivers/net/dsa/qca/qca8k.c
-@@ -1462,8 +1462,8 @@ static int qca8k_find_cpu_port(struct ds
- static int
- qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
- {
-+ const struct qca8k_match_data *data = priv->info;
- struct device_node *node = priv->dev->of_node;
-- const struct qca8k_match_data *data;
- u32 val = 0;
- int ret;
-
-@@ -1472,8 +1472,6 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
- * Should be applied by default but we set this just to make sure.
- */
- if (priv->switch_id == QCA8K_ID_QCA8327) {
-- data = of_device_get_match_data(priv->dev);
--
- /* Set the correct package of 148 pin for QCA8327 */
- if (data->reduced_package)
- val |= QCA8327_PWS_PACKAGE148_EN;
-@@ -2146,23 +2144,19 @@ qca8k_phylink_mac_link_up(struct dsa_swi
- static void
- qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
- {
-- const struct qca8k_match_data *match_data;
- struct qca8k_priv *priv = ds->priv;
- int i;
-
- if (stringset != ETH_SS_STATS)
- return;
-
-- match_data = of_device_get_match_data(priv->dev);
--
-- for (i = 0; i < match_data->mib_count; i++)
-+ for (i = 0; i < priv->info->mib_count; i++)
- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
- ETH_GSTRING_LEN);
- }
-
- static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
- {
-- const struct qca8k_match_data *match_data;
- struct qca8k_mib_eth_data *mib_eth_data;
- struct qca8k_priv *priv = ds->priv;
- const struct qca8k_mib_desc *mib;
-@@ -2181,10 +2175,9 @@ static void qca8k_mib_autocast_handler(s
- if (port != mib_eth_data->req_port)
- goto exit;
-
-- match_data = device_get_match_data(priv->dev);
- data = mib_eth_data->data;
-
-- for (i = 0; i < match_data->mib_count; i++) {
-+ for (i = 0; i < priv->info->mib_count; i++) {
- mib = &ar8327_mib[i];
-
- /* First 3 mib are present in the skb head */
-@@ -2256,7 +2249,6 @@ qca8k_get_ethtool_stats(struct dsa_switc
- uint64_t *data)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- const struct qca8k_match_data *match_data;
- const struct qca8k_mib_desc *mib;
- u32 reg, i, val;
- u32 hi = 0;
-@@ -2266,9 +2258,7 @@ qca8k_get_ethtool_stats(struct dsa_switc
- qca8k_get_ethtool_stats_eth(ds, port, data) > 0)
- return;
-
-- match_data = of_device_get_match_data(priv->dev);
--
-- for (i = 0; i < match_data->mib_count; i++) {
-+ for (i = 0; i < priv->info->mib_count; i++) {
- mib = &ar8327_mib[i];
- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
-
-@@ -2291,15 +2281,12 @@ qca8k_get_ethtool_stats(struct dsa_switc
- static int
- qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
- {
-- const struct qca8k_match_data *match_data;
- struct qca8k_priv *priv = ds->priv;
-
- if (sset != ETH_SS_STATS)
- return 0;
-
-- match_data = of_device_get_match_data(priv->dev);
--
-- return match_data->mib_count;
-+ return priv->info->mib_count;
- }
-
- static int
-@@ -3037,14 +3024,11 @@ static const struct dsa_switch_ops qca8k
-
- static int qca8k_read_switch_id(struct qca8k_priv *priv)
- {
-- const struct qca8k_match_data *data;
- u32 val;
- u8 id;
- int ret;
-
-- /* get the switches ID from the compatible */
-- data = of_device_get_match_data(priv->dev);
-- if (!data)
-+ if (!priv->info)
- return -ENODEV;
-
- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-@@ -3052,8 +3036,10 @@ static int qca8k_read_switch_id(struct q
- return -ENODEV;
-
- id = QCA8K_MASK_CTRL_DEVICE_ID(val);
-- if (id != data->id) {
-- dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id);
-+ if (id != priv->info->id) {
-+ dev_err(priv->dev,
-+ "Switch id detected %x but expected %x",
-+ id, priv->info->id);
- return -ENODEV;
- }
-
-@@ -3078,6 +3064,7 @@ qca8k_sw_probe(struct mdio_device *mdiod
- if (!priv)
- return -ENOMEM;
-
-+ priv->info = of_device_get_match_data(priv->dev);
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
-
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -393,6 +393,7 @@ struct qca8k_priv {
- struct qca8k_mgmt_eth_data mgmt_eth_data;
- struct qca8k_mib_eth_data mib_eth_data;
- struct qca8k_mdio_cache mdio_cache;
-+ const struct qca8k_match_data *info;
- };
-
- struct qca8k_mib_desc {
diff --git a/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch b/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch
deleted file mode 100644
index 5b2dce4c55..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 533c64bca62a8654f00698bc893f639013e38c7b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:11 +0200
-Subject: [PATCH 02/14] net: dsa: qca8k: make mib autocast feature optional
-
-Some switch may not support mib autocast feature and require the legacy
-way of reading the regs directly.
-Make the mib autocast feature optional and permit to declare support for
-it using match_data struct in a dedicated qca8k_info_ops struct.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k.c | 11 +++++++++--
- drivers/net/dsa/qca/qca8k.h | 5 +++++
- 2 files changed, 14 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k.c
-+++ b/drivers/net/dsa/qca/qca8k.c
-@@ -2254,8 +2254,8 @@ qca8k_get_ethtool_stats(struct dsa_switc
- u32 hi = 0;
- int ret;
-
-- if (priv->mgmt_master &&
-- qca8k_get_ethtool_stats_eth(ds, port, data) > 0)
-+ if (priv->mgmt_master && priv->info->ops->autocast_mib &&
-+ priv->info->ops->autocast_mib(ds, port, data) > 0)
- return;
-
- for (i = 0; i < priv->info->mib_count; i++) {
-@@ -3187,20 +3187,27 @@ static int qca8k_resume(struct device *d
- static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
- qca8k_suspend, qca8k_resume);
-
-+static const struct qca8k_info_ops qca8xxx_ops = {
-+ .autocast_mib = qca8k_get_ethtool_stats_eth,
-+};
-+
- static const struct qca8k_match_data qca8327 = {
- .id = QCA8K_ID_QCA8327,
- .reduced_package = true,
- .mib_count = QCA8K_QCA832X_MIB_COUNT,
-+ .ops = &qca8xxx_ops,
- };
-
- static const struct qca8k_match_data qca8328 = {
- .id = QCA8K_ID_QCA8327,
- .mib_count = QCA8K_QCA832X_MIB_COUNT,
-+ .ops = &qca8xxx_ops,
- };
-
- static const struct qca8k_match_data qca833x = {
- .id = QCA8K_ID_QCA8337,
- .mib_count = QCA8K_QCA833X_MIB_COUNT,
-+ .ops = &qca8xxx_ops,
- };
-
- static const struct of_device_id qca8k_of_match[] = {
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -324,10 +324,15 @@ enum qca8k_mid_cmd {
- QCA8K_MIB_CAST = 3,
- };
-
-+struct qca8k_info_ops {
-+ int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data);
-+};
-+
- struct qca8k_match_data {
- u8 id;
- bool reduced_package;
- u8 mib_count;
-+ const struct qca8k_info_ops *ops;
- };
-
- enum {
diff --git a/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch
deleted file mode 100644
index afa466693a..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch
+++ /dev/null
@@ -1,6532 +0,0 @@
-From 027152b830434e3632ad5dd678cc5d4740358dbb Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:12 +0200
-Subject: [PATCH 03/14] net: dsa: qca8k: move mib struct to common code
-
-The same MIB struct is used by drivers based on qca8k family switch. Move
-it to common code to make it accessible also by other drivers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/Makefile | 1 +
- drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} | 51 ---------------
- drivers/net/dsa/qca/qca8k-common.c | 63 +++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 3 +
- 4 files changed, 67 insertions(+), 51 deletions(-)
- rename drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} (98%)
- create mode 100644 drivers/net/dsa/qca/qca8k-common.c
-
---- a/drivers/net/dsa/qca/Makefile
-+++ b/drivers/net/dsa/qca/Makefile
-@@ -1,3 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0-only
- obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o
- obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
-+qca8k-y += qca8k-common.o qca8k-8xxx.o
---- a/drivers/net/dsa/qca/qca8k.c
-+++ /dev/null
-@@ -1,3237 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/*
-- * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
-- * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
-- * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
-- * Copyright (c) 2016 John Crispin <john@phrozen.org>
-- */
--
--#include <linux/module.h>
--#include <linux/phy.h>
--#include <linux/netdevice.h>
--#include <linux/bitfield.h>
--#include <linux/regmap.h>
--#include <net/dsa.h>
--#include <linux/of_net.h>
--#include <linux/of_mdio.h>
--#include <linux/of_platform.h>
--#include <linux/if_bridge.h>
--#include <linux/mdio.h>
--#include <linux/phylink.h>
--#include <linux/gpio/consumer.h>
--#include <linux/etherdevice.h>
--#include <linux/dsa/tag_qca.h>
--
--#include "qca8k.h"
--
--#define MIB_DESC(_s, _o, _n) \
-- { \
-- .size = (_s), \
-- .offset = (_o), \
-- .name = (_n), \
-- }
--
--static const struct qca8k_mib_desc ar8327_mib[] = {
-- MIB_DESC(1, 0x00, "RxBroad"),
-- MIB_DESC(1, 0x04, "RxPause"),
-- MIB_DESC(1, 0x08, "RxMulti"),
-- MIB_DESC(1, 0x0c, "RxFcsErr"),
-- MIB_DESC(1, 0x10, "RxAlignErr"),
-- MIB_DESC(1, 0x14, "RxRunt"),
-- MIB_DESC(1, 0x18, "RxFragment"),
-- MIB_DESC(1, 0x1c, "Rx64Byte"),
-- MIB_DESC(1, 0x20, "Rx128Byte"),
-- MIB_DESC(1, 0x24, "Rx256Byte"),
-- MIB_DESC(1, 0x28, "Rx512Byte"),
-- MIB_DESC(1, 0x2c, "Rx1024Byte"),
-- MIB_DESC(1, 0x30, "Rx1518Byte"),
-- MIB_DESC(1, 0x34, "RxMaxByte"),
-- MIB_DESC(1, 0x38, "RxTooLong"),
-- MIB_DESC(2, 0x3c, "RxGoodByte"),
-- MIB_DESC(2, 0x44, "RxBadByte"),
-- MIB_DESC(1, 0x4c, "RxOverFlow"),
-- MIB_DESC(1, 0x50, "Filtered"),
-- MIB_DESC(1, 0x54, "TxBroad"),
-- MIB_DESC(1, 0x58, "TxPause"),
-- MIB_DESC(1, 0x5c, "TxMulti"),
-- MIB_DESC(1, 0x60, "TxUnderRun"),
-- MIB_DESC(1, 0x64, "Tx64Byte"),
-- MIB_DESC(1, 0x68, "Tx128Byte"),
-- MIB_DESC(1, 0x6c, "Tx256Byte"),
-- MIB_DESC(1, 0x70, "Tx512Byte"),
-- MIB_DESC(1, 0x74, "Tx1024Byte"),
-- MIB_DESC(1, 0x78, "Tx1518Byte"),
-- MIB_DESC(1, 0x7c, "TxMaxByte"),
-- MIB_DESC(1, 0x80, "TxOverSize"),
-- MIB_DESC(2, 0x84, "TxByte"),
-- MIB_DESC(1, 0x8c, "TxCollision"),
-- MIB_DESC(1, 0x90, "TxAbortCol"),
-- MIB_DESC(1, 0x94, "TxMultiCol"),
-- MIB_DESC(1, 0x98, "TxSingleCol"),
-- MIB_DESC(1, 0x9c, "TxExcDefer"),
-- MIB_DESC(1, 0xa0, "TxDefer"),
-- MIB_DESC(1, 0xa4, "TxLateCol"),
-- MIB_DESC(1, 0xa8, "RXUnicast"),
-- MIB_DESC(1, 0xac, "TXUnicast"),
--};
--
--static void
--qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
--{
-- regaddr >>= 1;
-- *r1 = regaddr & 0x1e;
--
-- regaddr >>= 5;
-- *r2 = regaddr & 0x7;
--
-- regaddr >>= 3;
-- *page = regaddr & 0x3ff;
--}
--
--static int
--qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
--{
-- u16 *cached_lo = &priv->mdio_cache.lo;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (lo == *cached_lo)
-- return 0;
--
-- ret = bus->write(bus, phy_id, regnum, lo);
-- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit lo register\n");
--
-- *cached_lo = lo;
-- return 0;
--}
--
--static int
--qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
--{
-- u16 *cached_hi = &priv->mdio_cache.hi;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (hi == *cached_hi)
-- return 0;
--
-- ret = bus->write(bus, phy_id, regnum, hi);
-- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit hi register\n");
--
-- *cached_hi = hi;
-- return 0;
--}
--
--static int
--qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
--{
-- int ret;
--
-- ret = bus->read(bus, phy_id, regnum);
-- if (ret >= 0) {
-- *val = ret;
-- ret = bus->read(bus, phy_id, regnum + 1);
-- *val |= ret << 16;
-- }
--
-- if (ret < 0) {
-- dev_err_ratelimited(&bus->dev,
-- "failed to read qca8k 32bit register\n");
-- *val = 0;
-- return ret;
-- }
--
-- return 0;
--}
--
--static void
--qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
--{
-- u16 lo, hi;
-- int ret;
--
-- lo = val & 0xffff;
-- hi = (u16)(val >> 16);
--
-- ret = qca8k_set_lo(priv, phy_id, regnum, lo);
-- if (ret >= 0)
-- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
--}
--
--static int
--qca8k_set_page(struct qca8k_priv *priv, u16 page)
--{
-- u16 *cached_page = &priv->mdio_cache.page;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (page == *cached_page)
-- return 0;
--
-- ret = bus->write(bus, 0x18, 0, page);
-- if (ret < 0) {
-- dev_err_ratelimited(&bus->dev,
-- "failed to set qca8k page\n");
-- return ret;
-- }
--
-- *cached_page = page;
-- usleep_range(1000, 2000);
-- return 0;
--}
--
--static int
--qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
--{
-- return regmap_read(priv->regmap, reg, val);
--}
--
--static int
--qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
--{
-- return regmap_write(priv->regmap, reg, val);
--}
--
--static int
--qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
--{
-- return regmap_update_bits(priv->regmap, reg, mask, write_val);
--}
--
--static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
--{
-- struct qca8k_mgmt_eth_data *mgmt_eth_data;
-- struct qca8k_priv *priv = ds->priv;
-- struct qca_mgmt_ethhdr *mgmt_ethhdr;
-- u8 len, cmd;
--
-- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
-- mgmt_eth_data = &priv->mgmt_eth_data;
--
-- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
-- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
--
-- /* Make sure the seq match the requested packet */
-- if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
-- mgmt_eth_data->ack = true;
--
-- if (cmd == MDIO_READ) {
-- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
--
-- /* Get the rest of the 12 byte of data.
-- * The read/write function will extract the requested data.
-- */
-- if (len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(mgmt_eth_data->data + 1, skb->data,
-- QCA_HDR_MGMT_DATA2_LEN);
-- }
--
-- complete(&mgmt_eth_data->rw_done);
--}
--
--static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,
-- int priority, unsigned int len)
--{
-- struct qca_mgmt_ethhdr *mgmt_ethhdr;
-- unsigned int real_len;
-- struct sk_buff *skb;
-- u32 *data2;
-- u16 hdr;
--
-- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
-- if (!skb)
-- return NULL;
--
-- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
-- * Actually for some reason the steps are:
-- * 0: nothing
-- * 1-4: first 4 byte
-- * 5-6: first 12 byte
-- * 7-15: all 16 byte
-- */
-- if (len == 16)
-- real_len = 15;
-- else
-- real_len = len;
--
-- skb_reset_mac_header(skb);
-- skb_set_network_header(skb, skb->len);
--
-- mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);
--
-- hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
-- hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority);
-- hdr |= QCA_HDR_XMIT_FROM_CPU;
-- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
-- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
--
-- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
-- QCA_HDR_MGMT_CHECK_CODE_VAL);
--
-- if (cmd == MDIO_WRITE)
-- mgmt_ethhdr->mdio_data = *val;
--
-- mgmt_ethhdr->hdr = htons(hdr);
--
-- data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
--
-- return skb;
--}
--
--static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
--{
-- struct qca_mgmt_ethhdr *mgmt_ethhdr;
--
-- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
-- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
--}
--
--static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-- struct sk_buff *skb;
-- bool ack;
-- int ret;
--
-- skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,
-- QCA8K_ETHERNET_MDIO_PRIORITY, len);
-- if (!skb)
-- return -ENOMEM;
--
-- mutex_lock(&mgmt_eth_data->mutex);
--
-- /* Check mgmt_master if is operational */
-- if (!priv->mgmt_master) {
-- kfree_skb(skb);
-- mutex_unlock(&mgmt_eth_data->mutex);
-- return -EINVAL;
-- }
--
-- skb->dev = priv->mgmt_master;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the mdio pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
--
-- *val = mgmt_eth_data->data[0];
-- if (len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN);
--
-- ack = mgmt_eth_data->ack;
--
-- mutex_unlock(&mgmt_eth_data->mutex);
--
-- if (ret <= 0)
-- return -ETIMEDOUT;
--
-- if (!ack)
-- return -EINVAL;
--
-- return 0;
--}
--
--static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-- struct sk_buff *skb;
-- bool ack;
-- int ret;
--
-- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val,
-- QCA8K_ETHERNET_MDIO_PRIORITY, len);
-- if (!skb)
-- return -ENOMEM;
--
-- mutex_lock(&mgmt_eth_data->mutex);
--
-- /* Check mgmt_master if is operational */
-- if (!priv->mgmt_master) {
-- kfree_skb(skb);
-- mutex_unlock(&mgmt_eth_data->mutex);
-- return -EINVAL;
-- }
--
-- skb->dev = priv->mgmt_master;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the mdio pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
--
-- ack = mgmt_eth_data->ack;
--
-- mutex_unlock(&mgmt_eth_data->mutex);
--
-- if (ret <= 0)
-- return -ETIMEDOUT;
--
-- if (!ack)
-- return -EINVAL;
--
-- return 0;
--}
--
--static int
--qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
--{
-- u32 val = 0;
-- int ret;
--
-- ret = qca8k_read_eth(priv, reg, &val, sizeof(val));
-- if (ret)
-- return ret;
--
-- val &= ~mask;
-- val |= write_val;
--
-- return qca8k_write_eth(priv, reg, &val, sizeof(val));
--}
--
--static int
--qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
--
-- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
-- u32 tmp;
--
-- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- tmp = val[i];
--
-- ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- int ret;
--
-- if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
-- return 0;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret < 0)
-- goto exit;
--
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);
--
--exit:
-- mutex_unlock(&bus->mdio_lock);
-- return ret;
--}
--
--static int
--qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- int ret;
--
-- if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
-- return 0;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret < 0)
-- goto exit;
--
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
--exit:
-- mutex_unlock(&bus->mdio_lock);
-- return ret;
--}
--
--static int
--qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- u32 val;
-- int ret;
--
-- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
-- return 0;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret < 0)
-- goto exit;
--
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-- if (ret < 0)
-- goto exit;
--
-- val &= ~mask;
-- val |= write_val;
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
--exit:
-- mutex_unlock(&bus->mdio_lock);
--
-- return ret;
--}
--
--static const struct regmap_range qca8k_readable_ranges[] = {
-- regmap_reg_range(0x0000, 0x00e4), /* Global control */
-- regmap_reg_range(0x0100, 0x0168), /* EEE control */
-- regmap_reg_range(0x0200, 0x0270), /* Parser control */
-- regmap_reg_range(0x0400, 0x0454), /* ACL */
-- regmap_reg_range(0x0600, 0x0718), /* Lookup */
-- regmap_reg_range(0x0800, 0x0b70), /* QM */
-- regmap_reg_range(0x0c00, 0x0c80), /* PKT */
-- regmap_reg_range(0x0e00, 0x0e98), /* L3 */
-- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
--
--};
--
--static const struct regmap_access_table qca8k_readable_table = {
-- .yes_ranges = qca8k_readable_ranges,
-- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
--};
--
--static struct regmap_config qca8k_regmap_config = {
-- .reg_bits = 16,
-- .val_bits = 32,
-- .reg_stride = 4,
-- .max_register = 0x16ac, /* end MIB - Port6 range */
-- .reg_read = qca8k_regmap_read,
-- .reg_write = qca8k_regmap_write,
-- .reg_update_bits = qca8k_regmap_update_bits,
-- .rd_table = &qca8k_readable_table,
-- .disable_locking = true, /* Locking is handled by qca8k read/write */
-- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
--};
--
--static int
--qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
--{
-- u32 val;
--
-- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
-- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
--}
--
--static int
--qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
--{
-- u32 reg[3];
-- int ret;
--
-- /* load the ARL table into an array */
-- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-- if (ret)
-- return ret;
--
-- /* vid - 83:72 */
-- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
-- /* aging - 67:64 */
-- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
-- /* portmask - 54:48 */
-- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
-- /* mac - 47:0 */
-- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
-- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
-- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
-- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
-- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
-- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
--
-- return 0;
--}
--
--static void
--qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac,
-- u8 aging)
--{
-- u32 reg[3] = { 0 };
--
-- /* vid - 83:72 */
-- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-- /* aging - 67:64 */
-- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
-- /* portmask - 54:48 */
-- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
-- /* mac - 47:0 */
-- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
-- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
--
-- /* load the array into the ARL table */
-- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
--}
--
--static int
--qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
--{
-- u32 reg;
-- int ret;
--
-- /* Set the command and FDB index */
-- reg = QCA8K_ATU_FUNC_BUSY;
-- reg |= cmd;
-- if (port >= 0) {
-- reg |= QCA8K_ATU_FUNC_PORT_EN;
-- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
-- }
--
-- /* Write the function register triggering the table access */
-- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-- if (ret)
-- return ret;
--
-- /* wait for completion */
-- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
-- if (ret)
-- return ret;
--
-- /* Check for table full violation when adding an entry */
-- if (cmd == QCA8K_FDB_LOAD) {
-- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
-- if (ret < 0)
-- return ret;
-- if (reg & QCA8K_ATU_FUNC_FULL)
-- return -1;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port)
--{
-- int ret;
--
-- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
-- if (ret < 0)
-- return ret;
--
-- return qca8k_fdb_read(priv, fdb);
--}
--
--static int
--qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask,
-- u16 vid, u8 aging)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_write(priv, vid, port_mask, mac, aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_write(priv, vid, port_mask, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static void
--qca8k_fdb_flush(struct qca8k_priv *priv)
--{
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
-- mutex_unlock(&priv->reg_mutex);
--}
--
--static int
--qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
-- const u8 *mac, u16 vid)
--{
-- struct qca8k_fdb fdb = { 0 };
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
--
-- qca8k_fdb_write(priv, vid, 0, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-- if (ret < 0)
-- goto exit;
--
-- ret = qca8k_fdb_read(priv, &fdb);
-- if (ret < 0)
-- goto exit;
--
-- /* Rule exist. Delete first */
-- if (!fdb.aging) {
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- if (ret)
-- goto exit;
-- }
--
-- /* Add port to fdb portmask */
-- fdb.port_mask |= port_mask;
--
-- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
-- const u8 *mac, u16 vid)
--{
-- struct qca8k_fdb fdb = { 0 };
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
--
-- qca8k_fdb_write(priv, vid, 0, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-- if (ret < 0)
-- goto exit;
--
-- /* Rule doesn't exist. Why delete? */
-- if (!fdb.aging) {
-- ret = -EINVAL;
-- goto exit;
-- }
--
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- if (ret)
-- goto exit;
--
-- /* Only port in the rule is this port. Don't re insert */
-- if (fdb.port_mask == port_mask)
-- goto exit;
--
-- /* Remove port from port mask */
-- fdb.port_mask &= ~port_mask;
--
-- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
--{
-- u32 reg;
-- int ret;
--
-- /* Set the command and VLAN index */
-- reg = QCA8K_VTU_FUNC1_BUSY;
-- reg |= cmd;
-- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
--
-- /* Write the function register triggering the table access */
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-- if (ret)
-- return ret;
--
-- /* wait for completion */
-- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
-- if (ret)
-- return ret;
--
-- /* Check for table full violation when adding an entry */
-- if (cmd == QCA8K_VLAN_LOAD) {
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
-- if (ret < 0)
-- return ret;
-- if (reg & QCA8K_VTU_FUNC1_FULL)
-- return -ENOMEM;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
--{
-- u32 reg;
-- int ret;
--
-- /*
-- We do the right thing with VLAN 0 and treat it as untagged while
-- preserving the tag on egress.
-- */
-- if (vid == 0)
-- return 0;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-- if (ret < 0)
-- goto out;
--
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-- if (ret < 0)
-- goto out;
-- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-- if (untagged)
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
-- else
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
--
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-- if (ret)
-- goto out;
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
--
--out:
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
--{
-- u32 reg, mask;
-- int ret, i;
-- bool del;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-- if (ret < 0)
-- goto out;
--
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-- if (ret < 0)
-- goto out;
-- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
--
-- /* Check if we're the last member to be removed */
-- del = true;
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
--
-- if ((reg & mask) != mask) {
-- del = false;
-- break;
-- }
-- }
--
-- if (del) {
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
-- } else {
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-- if (ret)
-- goto out;
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-- }
--
--out:
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_mib_init(struct qca8k_priv *priv)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
-- QCA8K_MIB_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static void
--qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
--{
-- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
--
-- /* Port 0 and 6 have no internal PHY */
-- if (port > 0 && port < 6)
-- mask |= QCA8K_PORT_STATUS_LINK_AUTO;
--
-- if (enable)
-- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-- else
-- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
--}
--
--static int
--qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
-- struct sk_buff *read_skb, u32 *val)
--{
-- struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL);
-- bool ack;
-- int ret;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the copy pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- ack = mgmt_eth_data->ack;
--
-- if (ret <= 0)
-- return -ETIMEDOUT;
--
-- if (!ack)
-- return -EINVAL;
--
-- *val = mgmt_eth_data->data[0];
--
-- return 0;
--}
--
--static int
--qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,
-- int regnum, u16 data)
--{
-- struct sk_buff *write_skb, *clear_skb, *read_skb;
-- struct qca8k_mgmt_eth_data *mgmt_eth_data;
-- u32 write_val, clear_val = 0, val;
-- struct net_device *mgmt_master;
-- int ret, ret1;
-- bool ack;
--
-- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-- return -EINVAL;
--
-- mgmt_eth_data = &priv->mgmt_eth_data;
--
-- write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-- QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-- QCA8K_MDIO_MASTER_REG_ADDR(regnum);
--
-- if (read) {
-- write_val |= QCA8K_MDIO_MASTER_READ;
-- } else {
-- write_val |= QCA8K_MDIO_MASTER_WRITE;
-- write_val |= QCA8K_MDIO_MASTER_DATA(data);
-- }
--
-- /* Prealloc all the needed skb before the lock */
-- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val,
-- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val));
-- if (!write_skb)
-- return -ENOMEM;
--
-- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-- if (!clear_skb) {
-- ret = -ENOMEM;
-- goto err_clear_skb;
-- }
--
-- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-- if (!read_skb) {
-- ret = -ENOMEM;
-- goto err_read_skb;
-- }
--
-- /* Actually start the request:
-- * 1. Send mdio master packet
-- * 2. Busy Wait for mdio master command
-- * 3. Get the data if we are reading
-- * 4. Reset the mdio master (even with error)
-- */
-- mutex_lock(&mgmt_eth_data->mutex);
--
-- /* Check if mgmt_master is operational */
-- mgmt_master = priv->mgmt_master;
-- if (!mgmt_master) {
-- mutex_unlock(&mgmt_eth_data->mutex);
-- ret = -EINVAL;
-- goto err_mgmt_master;
-- }
--
-- read_skb->dev = mgmt_master;
-- clear_skb->dev = mgmt_master;
-- write_skb->dev = mgmt_master;
--
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the write pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(write_skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- ack = mgmt_eth_data->ack;
--
-- if (ret <= 0) {
-- ret = -ETIMEDOUT;
-- kfree_skb(read_skb);
-- goto exit;
-- }
--
-- if (!ack) {
-- ret = -EINVAL;
-- kfree_skb(read_skb);
-- goto exit;
-- }
--
-- ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1,
-- !(val & QCA8K_MDIO_MASTER_BUSY), 0,
-- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-- mgmt_eth_data, read_skb, &val);
--
-- if (ret < 0 && ret1 < 0) {
-- ret = ret1;
-- goto exit;
-- }
--
-- if (read) {
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the read pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(read_skb);
--
-- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- ack = mgmt_eth_data->ack;
--
-- if (ret <= 0) {
-- ret = -ETIMEDOUT;
-- goto exit;
-- }
--
-- if (!ack) {
-- ret = -EINVAL;
-- goto exit;
-- }
--
-- ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK;
-- } else {
-- kfree_skb(read_skb);
-- }
--exit:
-- reinit_completion(&mgmt_eth_data->rw_done);
--
-- /* Increment seq_num and set it in the clear pkt */
-- mgmt_eth_data->seq++;
-- qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq);
-- mgmt_eth_data->ack = false;
--
-- dev_queue_xmit(clear_skb);
--
-- wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-- QCA8K_ETHERNET_TIMEOUT);
--
-- mutex_unlock(&mgmt_eth_data->mutex);
--
-- return ret;
--
-- /* Error handling before lock */
--err_mgmt_master:
-- kfree_skb(read_skb);
--err_read_skb:
-- kfree_skb(clear_skb);
--err_clear_skb:
-- kfree_skb(write_skb);
--
-- return ret;
--}
--
--static u32
--qca8k_port_to_phy(int port)
--{
-- /* From Andrew Lunn:
-- * Port 0 has no internal phy.
-- * Port 1 has an internal PHY at MDIO address 0.
-- * Port 2 has an internal PHY at MDIO address 1.
-- * ...
-- * Port 5 has an internal PHY at MDIO address 4.
-- * Port 6 has no internal PHY.
-- */
--
-- return port - 1;
--}
--
--static int
--qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
--{
-- u16 r1, r2, page;
-- u32 val;
-- int ret, ret1;
--
-- qca8k_split_addr(reg, &r1, &r2, &page);
--
-- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
-- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-- bus, 0x10 | r2, r1, &val);
--
-- /* Check if qca8k_read has failed for a different reason
-- * before returnting -ETIMEDOUT
-- */
-- if (ret < 0 && ret1 < 0)
-- return ret1;
--
-- return ret;
--}
--
--static int
--qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
--{
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- u32 val;
-- int ret;
--
-- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-- return -EINVAL;
--
-- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-- QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-- QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
-- QCA8K_MDIO_MASTER_DATA(data);
--
-- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret)
-- goto exit;
--
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
-- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-- QCA8K_MDIO_MASTER_BUSY);
--
--exit:
-- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
--
-- mutex_unlock(&bus->mdio_lock);
--
-- return ret;
--}
--
--static int
--qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
--{
-- struct mii_bus *bus = priv->bus;
-- u16 r1, r2, page;
-- u32 val;
-- int ret;
--
-- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-- return -EINVAL;
--
-- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-- QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-- QCA8K_MDIO_MASTER_REG_ADDR(regnum);
--
-- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--
-- ret = qca8k_set_page(priv, page);
-- if (ret)
-- goto exit;
--
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
--
-- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-- QCA8K_MDIO_MASTER_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
--
--exit:
-- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
--
-- mutex_unlock(&bus->mdio_lock);
--
-- if (ret >= 0)
-- ret = val & QCA8K_MDIO_MASTER_DATA_MASK;
--
-- return ret;
--}
--
--static int
--qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
--{
-- struct qca8k_priv *priv = slave_bus->priv;
-- int ret;
--
-- /* Use mdio Ethernet when available, fallback to legacy one on error */
-- ret = qca8k_phy_eth_command(priv, false, phy, regnum, data);
-- if (!ret)
-- return 0;
--
-- return qca8k_mdio_write(priv, phy, regnum, data);
--}
--
--static int
--qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
--{
-- struct qca8k_priv *priv = slave_bus->priv;
-- int ret;
--
-- /* Use mdio Ethernet when available, fallback to legacy one on error */
-- ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0);
-- if (ret >= 0)
-- return ret;
--
-- ret = qca8k_mdio_read(priv, phy, regnum);
--
-- if (ret < 0)
-- return 0xffff;
--
-- return ret;
--}
--
--static int
--qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data)
--{
-- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
--
-- return qca8k_internal_mdio_write(slave_bus, port, regnum, data);
--}
--
--static int
--qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum)
--{
-- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
--
-- return qca8k_internal_mdio_read(slave_bus, port, regnum);
--}
--
--static int
--qca8k_mdio_register(struct qca8k_priv *priv)
--{
-- struct dsa_switch *ds = priv->ds;
-- struct device_node *mdio;
-- struct mii_bus *bus;
--
-- bus = devm_mdiobus_alloc(ds->dev);
-- if (!bus)
-- return -ENOMEM;
--
-- bus->priv = (void *)priv;
-- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
-- ds->dst->index, ds->index);
-- bus->parent = ds->dev;
-- bus->phy_mask = ~ds->phys_mii_mask;
-- ds->slave_mii_bus = bus;
--
-- /* Check if the devicetree declare the port:phy mapping */
-- mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
-- if (of_device_is_available(mdio)) {
-- bus->name = "qca8k slave mii";
-- bus->read = qca8k_internal_mdio_read;
-- bus->write = qca8k_internal_mdio_write;
-- return devm_of_mdiobus_register(priv->dev, bus, mdio);
-- }
--
-- /* If a mapping can't be found the legacy mapping is used,
-- * using the qca8k_port_to_phy function
-- */
-- bus->name = "qca8k-legacy slave mii";
-- bus->read = qca8k_legacy_mdio_read;
-- bus->write = qca8k_legacy_mdio_write;
-- return devm_mdiobus_register(priv->dev, bus);
--}
--
--static int
--qca8k_setup_mdio_bus(struct qca8k_priv *priv)
--{
-- u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
-- struct device_node *ports, *port;
-- phy_interface_t mode;
-- int err;
--
-- ports = of_get_child_by_name(priv->dev->of_node, "ports");
-- if (!ports)
-- ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports");
--
-- if (!ports)
-- return -EINVAL;
--
-- for_each_available_child_of_node(ports, port) {
-- err = of_property_read_u32(port, "reg", &reg);
-- if (err) {
-- of_node_put(port);
-- of_node_put(ports);
-- return err;
-- }
--
-- if (!dsa_is_user_port(priv->ds, reg))
-- continue;
--
-- of_get_phy_mode(port, &mode);
--
-- if (of_property_read_bool(port, "phy-handle") &&
-- mode != PHY_INTERFACE_MODE_INTERNAL)
-- external_mdio_mask |= BIT(reg);
-- else
-- internal_mdio_mask |= BIT(reg);
-- }
--
-- of_node_put(ports);
-- if (!external_mdio_mask && !internal_mdio_mask) {
-- dev_err(priv->dev, "no PHYs are defined.\n");
-- return -EINVAL;
-- }
--
-- /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through
-- * the MDIO_MASTER register also _disconnects_ the external MDC
-- * passthrough to the internal PHYs. It's not possible to use both
-- * configurations at the same time!
-- *
-- * Because this came up during the review process:
-- * If the external mdio-bus driver is capable magically disabling
-- * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's
-- * accessors for the time being, it would be possible to pull this
-- * off.
-- */
-- if (!!external_mdio_mask && !!internal_mdio_mask) {
-- dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n");
-- return -EINVAL;
-- }
--
-- if (external_mdio_mask) {
-- /* Make sure to disable the internal mdio bus in cases
-- * a dt-overlay and driver reload changed the configuration
-- */
--
-- return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL,
-- QCA8K_MDIO_MASTER_EN);
-- }
--
-- return qca8k_mdio_register(priv);
--}
--
--static int
--qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
--{
-- u32 mask = 0;
-- int ret = 0;
--
-- /* SoC specific settings for ipq8064.
-- * If more device require this consider adding
-- * a dedicated binding.
-- */
-- if (of_machine_is_compatible("qcom,ipq8064"))
-- mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
--
-- /* SoC specific settings for ipq8065 */
-- if (of_machine_is_compatible("qcom,ipq8065"))
-- mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
--
-- if (mask) {
-- ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
-- QCA8K_MAC_PWR_RGMII0_1_8V |
-- QCA8K_MAC_PWR_RGMII1_1_8V,
-- mask);
-- }
--
-- return ret;
--}
--
--static int qca8k_find_cpu_port(struct dsa_switch *ds)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- /* Find the connected cpu port. Valid port are 0 or 6 */
-- if (dsa_is_cpu_port(ds, 0))
-- return 0;
--
-- dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
--
-- if (dsa_is_cpu_port(ds, 6))
-- return 6;
--
-- return -EINVAL;
--}
--
--static int
--qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
--{
-- const struct qca8k_match_data *data = priv->info;
-- struct device_node *node = priv->dev->of_node;
-- u32 val = 0;
-- int ret;
--
-- /* QCA8327 require to set to the correct mode.
-- * His bigger brother QCA8328 have the 172 pin layout.
-- * Should be applied by default but we set this just to make sure.
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8327) {
-- /* Set the correct package of 148 pin for QCA8327 */
-- if (data->reduced_package)
-- val |= QCA8327_PWS_PACKAGE148_EN;
--
-- ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
-- val);
-- if (ret)
-- return ret;
-- }
--
-- if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
-- val |= QCA8K_PWS_POWER_ON_SEL;
--
-- if (of_property_read_bool(node, "qca,led-open-drain")) {
-- if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
-- dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
-- return -EINVAL;
-- }
--
-- val |= QCA8K_PWS_LED_OPEN_EN_CSR;
-- }
--
-- return qca8k_rmw(priv, QCA8K_REG_PWS,
-- QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
-- val);
--}
--
--static int
--qca8k_parse_port_config(struct qca8k_priv *priv)
--{
-- int port, cpu_port_index = -1, ret;
-- struct device_node *port_dn;
-- phy_interface_t mode;
-- struct dsa_port *dp;
-- u32 delay;
--
-- /* We have 2 CPU port. Check them */
-- for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-- /* Skip every other port */
-- if (port != 0 && port != 6)
-- continue;
--
-- dp = dsa_to_port(priv->ds, port);
-- port_dn = dp->dn;
-- cpu_port_index++;
--
-- if (!of_device_is_available(port_dn))
-- continue;
--
-- ret = of_get_phy_mode(port_dn, &mode);
-- if (ret)
-- continue;
--
-- switch (mode) {
-- case PHY_INTERFACE_MODE_RGMII:
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- case PHY_INTERFACE_MODE_SGMII:
-- delay = 0;
--
-- if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-- /* Switch regs accept value in ns, convert ps to ns */
-- delay = delay / 1000;
-- else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-- mode == PHY_INTERFACE_MODE_RGMII_TXID)
-- delay = 1;
--
-- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) {
-- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-- delay = 3;
-- }
--
-- priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
--
-- delay = 0;
--
-- if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
-- /* Switch regs accept value in ns, convert ps to ns */
-- delay = delay / 1000;
-- else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-- mode == PHY_INTERFACE_MODE_RGMII_RXID)
-- delay = 2;
--
-- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) {
-- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-- delay = 3;
-- }
--
-- priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
--
-- /* Skip sgmii parsing for rgmii* mode */
-- if (mode == PHY_INTERFACE_MODE_RGMII ||
-- mode == PHY_INTERFACE_MODE_RGMII_ID ||
-- mode == PHY_INTERFACE_MODE_RGMII_TXID ||
-- mode == PHY_INTERFACE_MODE_RGMII_RXID)
-- break;
--
-- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-- priv->ports_config.sgmii_tx_clk_falling_edge = true;
--
-- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-- priv->ports_config.sgmii_rx_clk_falling_edge = true;
--
-- if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
-- priv->ports_config.sgmii_enable_pll = true;
--
-- if (priv->switch_id == QCA8K_ID_QCA8327) {
-- dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
-- priv->ports_config.sgmii_enable_pll = false;
-- }
--
-- if (priv->switch_revision < 2)
-- dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
-- }
--
-- break;
-- default:
-- continue;
-- }
-- }
--
-- return 0;
--}
--
--static int
--qca8k_setup(struct dsa_switch *ds)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int cpu_port, ret, i;
-- u32 mask;
--
-- cpu_port = qca8k_find_cpu_port(ds);
-- if (cpu_port < 0) {
-- dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
-- return cpu_port;
-- }
--
-- /* Parse CPU port config to be later used in phy_link mac_config */
-- ret = qca8k_parse_port_config(priv);
-- if (ret)
-- return ret;
--
-- ret = qca8k_setup_mdio_bus(priv);
-- if (ret)
-- return ret;
--
-- ret = qca8k_setup_of_pws_reg(priv);
-- if (ret)
-- return ret;
--
-- ret = qca8k_setup_mac_pwr_sel(priv);
-- if (ret)
-- return ret;
--
-- /* Make sure MAC06 is disabled */
-- ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
-- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
-- if (ret) {
-- dev_err(priv->dev, "failed disabling MAC06 exchange");
-- return ret;
-- }
--
-- /* Enable CPU Port */
-- ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-- if (ret) {
-- dev_err(priv->dev, "failed enabling CPU port");
-- return ret;
-- }
--
-- /* Enable MIB counters */
-- ret = qca8k_mib_init(priv);
-- if (ret)
-- dev_warn(priv->dev, "mib init failed");
--
-- /* Initial setup of all ports */
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- /* Disable forwarding by default on all ports */
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER, 0);
-- if (ret)
-- return ret;
--
-- /* Enable QCA header mode on all cpu ports */
-- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
-- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
-- if (ret) {
-- dev_err(priv->dev, "failed enabling QCA header mode");
-- return ret;
-- }
-- }
--
-- /* Disable MAC by default on all user ports */
-- if (dsa_is_user_port(ds, i))
-- qca8k_port_set_status(priv, i, 0);
-- }
--
-- /* Forward all unknown frames to CPU port for Linux processing
-- * Notice that in multi-cpu config only one port should be set
-- * for igmp, unknown, multicast and broadcast packet
-- */
-- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
-- if (ret)
-- return ret;
--
-- /* Setup connection between CPU port & user ports
-- * Configure specific switch configuration for ports
-- */
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- /* CPU port gets connected to all user ports of the switch */
-- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-- if (ret)
-- return ret;
-- }
--
-- /* Individual user ports get connected to CPU port only */
-- if (dsa_is_user_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER,
-- BIT(cpu_port));
-- if (ret)
-- return ret;
--
-- /* Enable ARP Auto-learning by default */
-- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_LEARN);
-- if (ret)
-- return ret;
--
-- /* For port based vlans to work we need to set the
-- * default egress vid
-- */
-- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-- QCA8K_EGREES_VLAN_PORT_MASK(i),
-- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF));
-- if (ret)
-- return ret;
--
-- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-- if (ret)
-- return ret;
-- }
--
-- /* The port 5 of the qca8337 have some problem in flood condition. The
-- * original legacy driver had some specific buffer and priority settings
-- * for the different port suggested by the QCA switch team. Add this
-- * missing settings to improve switch stability under load condition.
-- * This problem is limited to qca8337 and other qca8k switch are not affected.
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8337) {
-- switch (i) {
-- /* The 2 CPU port and port 5 requires some different
-- * priority than any other ports.
-- */
-- case 0:
-- case 5:
-- case 6:
-- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
-- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
-- break;
-- default:
-- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
-- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
-- }
-- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
--
-- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
-- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_WRED_EN;
-- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
-- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
-- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_WRED_EN,
-- mask);
-- }
-- }
--
-- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-- if (priv->switch_id == QCA8K_ID_QCA8327) {
-- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
-- QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
-- qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
-- QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK |
-- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK,
-- mask);
-- }
--
-- /* Setup our port MTUs to match power on defaults */
-- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
-- if (ret)
-- dev_warn(priv->dev, "failed setting MTU settings");
--
-- /* Flush the FDB table */
-- qca8k_fdb_flush(priv);
--
-- /* We don't have interrupts for link changes, so we need to poll */
-- ds->pcs_poll = true;
--
-- /* Set min a max ageing value supported */
-- ds->ageing_time_min = 7000;
-- ds->ageing_time_max = 458745000;
--
-- /* Set max number of LAGs supported */
-- ds->num_lag_ids = QCA8K_NUM_LAGS;
--
-- return 0;
--}
--
--static void
--qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
-- u32 reg)
--{
-- u32 delay, val = 0;
-- int ret;
--
-- /* Delay can be declared in 3 different way.
-- * Mode to rgmii and internal-delay standard binding defined
-- * rgmii-id or rgmii-tx/rx phy mode set.
-- * The parse logic set a delay different than 0 only when one
-- * of the 3 different way is used. In all other case delay is
-- * not enabled. With ID or TX/RXID delay is enabled and set
-- * to the default and recommended value.
-- */
-- if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
-- delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
--
-- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-- }
--
-- if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
-- delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
--
-- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-- }
--
-- /* Set RGMII delay based on the selected values */
-- ret = qca8k_rmw(priv, reg,
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
-- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
-- val);
-- if (ret)
-- dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
-- cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
--}
--
--static void
--qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-- const struct phylink_link_state *state)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int cpu_port_index, ret;
-- u32 reg, val;
--
-- switch (port) {
-- case 0: /* 1st CPU port */
-- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII)
-- return;
--
-- reg = QCA8K_REG_PORT0_PAD_CTRL;
-- cpu_port_index = QCA8K_CPU_PORT0;
-- break;
-- case 1:
-- case 2:
-- case 3:
-- case 4:
-- case 5:
-- /* Internal PHY, nothing to do */
-- return;
-- case 6: /* 2nd CPU port / external PHY */
-- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII &&
-- state->interface != PHY_INTERFACE_MODE_1000BASEX)
-- return;
--
-- reg = QCA8K_REG_PORT6_PAD_CTRL;
-- cpu_port_index = QCA8K_CPU_PORT6;
-- break;
-- default:
-- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
-- return;
-- }
--
-- if (port != 6 && phylink_autoneg_inband(mode)) {
-- dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
-- __func__);
-- return;
-- }
--
-- switch (state->interface) {
-- case PHY_INTERFACE_MODE_RGMII:
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
--
-- /* Configure rgmii delay */
-- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
--
-- /* QCA8337 requires to set rgmii rx delay for all ports.
-- * This is enabled through PORT5_PAD_CTRL for all ports,
-- * rather than individual port registers.
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8337)
-- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-- break;
-- case PHY_INTERFACE_MODE_SGMII:
-- case PHY_INTERFACE_MODE_1000BASEX:
-- /* Enable SGMII on the port */
-- qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
--
-- /* Enable/disable SerDes auto-negotiation as necessary */
-- ret = qca8k_read(priv, QCA8K_REG_PWS, &val);
-- if (ret)
-- return;
-- if (phylink_autoneg_inband(mode))
-- val &= ~QCA8K_PWS_SERDES_AEN_DIS;
-- else
-- val |= QCA8K_PWS_SERDES_AEN_DIS;
-- qca8k_write(priv, QCA8K_REG_PWS, val);
--
-- /* Configure the SGMII parameters */
-- ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
-- if (ret)
-- return;
--
-- val |= QCA8K_SGMII_EN_SD;
--
-- if (priv->ports_config.sgmii_enable_pll)
-- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-- QCA8K_SGMII_EN_TX;
--
-- if (dsa_is_cpu_port(ds, port)) {
-- /* CPU port, we're talking to the CPU MAC, be a PHY */
-- val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-- val |= QCA8K_SGMII_MODE_CTRL_PHY;
-- } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
-- val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-- val |= QCA8K_SGMII_MODE_CTRL_MAC;
-- } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
-- val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-- val |= QCA8K_SGMII_MODE_CTRL_BASEX;
-- }
--
-- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
--
-- /* From original code is reported port instability as SGMII also
-- * require delay set. Apply advised values here or take them from DT.
-- */
-- if (state->interface == PHY_INTERFACE_MODE_SGMII)
-- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
--
-- /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
-- * falling edge is set writing in the PORT0 PAD reg
-- */
-- if (priv->switch_id == QCA8K_ID_QCA8327 ||
-- priv->switch_id == QCA8K_ID_QCA8337)
-- reg = QCA8K_REG_PORT0_PAD_CTRL;
--
-- val = 0;
--
-- /* SGMII Clock phase configuration */
-- if (priv->ports_config.sgmii_rx_clk_falling_edge)
-- val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
--
-- if (priv->ports_config.sgmii_tx_clk_falling_edge)
-- val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
--
-- if (val)
-- ret = qca8k_rmw(priv, reg,
-- QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
-- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
-- val);
--
-- break;
-- default:
-- dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
-- phy_modes(state->interface), port);
-- return;
-- }
--}
--
--static void
--qca8k_phylink_validate(struct dsa_switch *ds, int port,
-- unsigned long *supported,
-- struct phylink_link_state *state)
--{
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
--
-- switch (port) {
-- case 0: /* 1st CPU port */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII)
-- goto unsupported;
-- break;
-- case 1:
-- case 2:
-- case 3:
-- case 4:
-- case 5:
-- /* Internal PHY */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_GMII &&
-- state->interface != PHY_INTERFACE_MODE_INTERNAL)
-- goto unsupported;
-- break;
-- case 6: /* 2nd CPU port / external PHY */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-- state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-- state->interface != PHY_INTERFACE_MODE_SGMII &&
-- state->interface != PHY_INTERFACE_MODE_1000BASEX)
-- goto unsupported;
-- break;
-- default:
--unsupported:
-- linkmode_zero(supported);
-- return;
-- }
--
-- phylink_set_port_modes(mask);
-- phylink_set(mask, Autoneg);
--
-- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 10baseT_Half);
-- phylink_set(mask, 10baseT_Full);
-- phylink_set(mask, 100baseT_Half);
-- phylink_set(mask, 100baseT_Full);
--
-- if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
-- phylink_set(mask, 1000baseX_Full);
--
-- phylink_set(mask, Pause);
-- phylink_set(mask, Asym_Pause);
--
-- linkmode_and(supported, supported, mask);
-- linkmode_and(state->advertising, state->advertising, mask);
--}
--
--static int
--qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port,
-- struct phylink_link_state *state)
--{
-- struct qca8k_priv *priv = ds->priv;
-- u32 reg;
-- int ret;
--
-- ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
-- if (ret < 0)
-- return ret;
--
-- state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
-- state->an_complete = state->link;
-- state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
-- state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
-- DUPLEX_HALF;
--
-- switch (reg & QCA8K_PORT_STATUS_SPEED) {
-- case QCA8K_PORT_STATUS_SPEED_10:
-- state->speed = SPEED_10;
-- break;
-- case QCA8K_PORT_STATUS_SPEED_100:
-- state->speed = SPEED_100;
-- break;
-- case QCA8K_PORT_STATUS_SPEED_1000:
-- state->speed = SPEED_1000;
-- break;
-- default:
-- state->speed = SPEED_UNKNOWN;
-- break;
-- }
--
-- state->pause = MLO_PAUSE_NONE;
-- if (reg & QCA8K_PORT_STATUS_RXFLOW)
-- state->pause |= MLO_PAUSE_RX;
-- if (reg & QCA8K_PORT_STATUS_TXFLOW)
-- state->pause |= MLO_PAUSE_TX;
--
-- return 1;
--}
--
--static void
--qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
-- phy_interface_t interface)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- qca8k_port_set_status(priv, port, 0);
--}
--
--static void
--qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
-- phy_interface_t interface, struct phy_device *phydev,
-- int speed, int duplex, bool tx_pause, bool rx_pause)
--{
-- struct qca8k_priv *priv = ds->priv;
-- u32 reg;
--
-- if (phylink_autoneg_inband(mode)) {
-- reg = QCA8K_PORT_STATUS_LINK_AUTO;
-- } else {
-- switch (speed) {
-- case SPEED_10:
-- reg = QCA8K_PORT_STATUS_SPEED_10;
-- break;
-- case SPEED_100:
-- reg = QCA8K_PORT_STATUS_SPEED_100;
-- break;
-- case SPEED_1000:
-- reg = QCA8K_PORT_STATUS_SPEED_1000;
-- break;
-- default:
-- reg = QCA8K_PORT_STATUS_LINK_AUTO;
-- break;
-- }
--
-- if (duplex == DUPLEX_FULL)
-- reg |= QCA8K_PORT_STATUS_DUPLEX;
--
-- if (rx_pause || dsa_is_cpu_port(ds, port))
-- reg |= QCA8K_PORT_STATUS_RXFLOW;
--
-- if (tx_pause || dsa_is_cpu_port(ds, port))
-- reg |= QCA8K_PORT_STATUS_TXFLOW;
-- }
--
-- reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
--
-- qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
--}
--
--static void
--qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int i;
--
-- if (stringset != ETH_SS_STATS)
-- return;
--
-- for (i = 0; i < priv->info->mib_count; i++)
-- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-- ETH_GSTRING_LEN);
--}
--
--static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
--{
-- struct qca8k_mib_eth_data *mib_eth_data;
-- struct qca8k_priv *priv = ds->priv;
-- const struct qca8k_mib_desc *mib;
-- struct mib_ethhdr *mib_ethhdr;
-- int i, mib_len, offset = 0;
-- u64 *data;
-- u8 port;
--
-- mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
-- mib_eth_data = &priv->mib_eth_data;
--
-- /* The switch autocast every port. Ignore other packet and
-- * parse only the requested one.
-- */
-- port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr));
-- if (port != mib_eth_data->req_port)
-- goto exit;
--
-- data = mib_eth_data->data;
--
-- for (i = 0; i < priv->info->mib_count; i++) {
-- mib = &ar8327_mib[i];
--
-- /* First 3 mib are present in the skb head */
-- if (i < 3) {
-- data[i] = mib_ethhdr->data[i];
-- continue;
-- }
--
-- mib_len = sizeof(uint32_t);
--
-- /* Some mib are 64 bit wide */
-- if (mib->size == 2)
-- mib_len = sizeof(uint64_t);
--
-- /* Copy the mib value from packet to the */
-- memcpy(data + i, skb->data + offset, mib_len);
--
-- /* Set the offset for the next mib */
-- offset += mib_len;
-- }
--
--exit:
-- /* Complete on receiving all the mib packet */
-- if (refcount_dec_and_test(&mib_eth_data->port_parsed))
-- complete(&mib_eth_data->rw_done);
--}
--
--static int
--qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
--{
-- struct dsa_port *dp = dsa_to_port(ds, port);
-- struct qca8k_mib_eth_data *mib_eth_data;
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- mib_eth_data = &priv->mib_eth_data;
--
-- mutex_lock(&mib_eth_data->mutex);
--
-- reinit_completion(&mib_eth_data->rw_done);
--
-- mib_eth_data->req_port = dp->index;
-- mib_eth_data->data = data;
-- refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS);
--
-- mutex_lock(&priv->reg_mutex);
--
-- /* Send mib autocast request */
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) |
-- QCA8K_MIB_BUSY);
--
-- mutex_unlock(&priv->reg_mutex);
--
-- if (ret)
-- goto exit;
--
-- ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT);
--
--exit:
-- mutex_unlock(&mib_eth_data->mutex);
--
-- return ret;
--}
--
--static void
--qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
-- uint64_t *data)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- const struct qca8k_mib_desc *mib;
-- u32 reg, i, val;
-- u32 hi = 0;
-- int ret;
--
-- if (priv->mgmt_master && priv->info->ops->autocast_mib &&
-- priv->info->ops->autocast_mib(ds, port, data) > 0)
-- return;
--
-- for (i = 0; i < priv->info->mib_count; i++) {
-- mib = &ar8327_mib[i];
-- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
--
-- ret = qca8k_read(priv, reg, &val);
-- if (ret < 0)
-- continue;
--
-- if (mib->size == 2) {
-- ret = qca8k_read(priv, reg + 4, &hi);
-- if (ret < 0)
-- continue;
-- }
--
-- data[i] = val;
-- if (mib->size == 2)
-- data[i] |= (u64)hi << 32;
-- }
--}
--
--static int
--qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- if (sset != ETH_SS_STATS)
-- return 0;
--
-- return priv->info->mib_count;
--}
--
--static int
--qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
-- u32 reg;
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
-- if (ret < 0)
-- goto exit;
--
-- if (eee->eee_enabled)
-- reg |= lpi_en;
-- else
-- reg &= ~lpi_en;
-- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
--{
-- /* Nothing to do on the port's MAC */
-- return 0;
--}
--
--static void
--qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u32 stp_state;
--
-- switch (state) {
-- case BR_STATE_DISABLED:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
-- break;
-- case BR_STATE_BLOCKING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
-- break;
-- case BR_STATE_LISTENING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
-- break;
-- case BR_STATE_LEARNING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
-- break;
-- case BR_STATE_FORWARDING:
-- default:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
-- break;
-- }
--
-- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
--}
--
--static int
--qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int port_mask, cpu_port;
-- int i, ret;
--
-- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-- port_mask = BIT(cpu_port);
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- if (dsa_is_cpu_port(ds, i))
-- continue;
-- if (dsa_to_port(ds, i)->bridge_dev != br)
-- continue;
-- /* Add this port to the portvlan mask of the other ports
-- * in the bridge
-- */
-- ret = regmap_set_bits(priv->regmap,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-- if (ret)
-- return ret;
-- if (i != port)
-- port_mask |= BIT(i);
-- }
--
-- /* Add all other ports to this ports portvlan mask */
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_MEMBER, port_mask);
--
-- return ret;
--}
--
--static void
--qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int cpu_port, i;
--
-- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- if (dsa_is_cpu_port(ds, i))
-- continue;
-- if (dsa_to_port(ds, i)->bridge_dev != br)
-- continue;
-- /* Remove this port to the portvlan mask of the other ports
-- * in the bridge
-- */
-- regmap_clear_bits(priv->regmap,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-- }
--
-- /* Set the cpu port to be the only one in the portvlan mask of
-- * this port
-- */
-- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
--}
--
--static void
--qca8k_port_fast_age(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
-- mutex_unlock(&priv->reg_mutex);
--}
--
--static int
--qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
--{
-- struct qca8k_priv *priv = ds->priv;
-- unsigned int secs = msecs / 1000;
-- u32 val;
--
-- /* AGE_TIME reg is set in 7s step */
-- val = secs / 7;
--
-- /* Handle case with 0 as val to NOT disable
-- * learning
-- */
-- if (!val)
-- val = 1;
--
-- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
-- QCA8K_ATU_AGE_TIME(val));
--}
--
--static int
--qca8k_port_enable(struct dsa_switch *ds, int port,
-- struct phy_device *phy)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--
-- qca8k_port_set_status(priv, port, 1);
-- priv->port_enabled_map |= BIT(port);
--
-- if (dsa_is_user_port(ds, port))
-- phy_support_asym_pause(phy);
--
-- return 0;
--}
--
--static void
--qca8k_port_disable(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--
-- qca8k_port_set_status(priv, port, 0);
-- priv->port_enabled_map &= ~BIT(port);
--}
--
--static int
--qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- /* We have only have a general MTU setting.
-- * DSA always set the CPU port's MTU to the largest MTU of the slave
-- * ports.
-- * Setting MTU just for the CPU port is sufficient to correctly set a
-- * value for every port.
-- */
-- if (!dsa_is_cpu_port(ds, port))
-- return 0;
--
-- /* To change the MAX_FRAME_SIZE the cpu ports must be off or
-- * the switch panics.
-- * Turn off both cpu ports before applying the new value to prevent
-- * this.
-- */
-- if (priv->port_enabled_map & BIT(0))
-- qca8k_port_set_status(priv, 0, 0);
--
-- if (priv->port_enabled_map & BIT(6))
-- qca8k_port_set_status(priv, 6, 0);
--
-- /* Include L2 header / FCS length */
-- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
--
-- if (priv->port_enabled_map & BIT(0))
-- qca8k_port_set_status(priv, 0, 1);
--
-- if (priv->port_enabled_map & BIT(6))
-- qca8k_port_set_status(priv, 6, 1);
--
-- return ret;
--}
--
--static int
--qca8k_port_max_mtu(struct dsa_switch *ds, int port)
--{
-- return QCA8K_MAX_MTU;
--}
--
--static int
--qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
-- u16 port_mask, u16 vid)
--{
-- /* Set the vid to the port vlan id if no vid is set */
-- if (!vid)
-- vid = QCA8K_PORT_VID_DEF;
--
-- return qca8k_fdb_add(priv, addr, port_mask, vid,
-- QCA8K_ATU_STATUS_STATIC);
--}
--
--static int
--qca8k_port_fdb_add(struct dsa_switch *ds, int port,
-- const unsigned char *addr, u16 vid)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u16 port_mask = BIT(port);
--
-- return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
--}
--
--static int
--qca8k_port_fdb_del(struct dsa_switch *ds, int port,
-- const unsigned char *addr, u16 vid)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u16 port_mask = BIT(port);
--
-- if (!vid)
-- vid = QCA8K_PORT_VID_DEF;
--
-- return qca8k_fdb_del(priv, addr, port_mask, vid);
--}
--
--static int
--qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
-- dsa_fdb_dump_cb_t *cb, void *data)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- struct qca8k_fdb _fdb = { 0 };
-- int cnt = QCA8K_NUM_FDB_RECORDS;
-- bool is_static;
-- int ret = 0;
--
-- mutex_lock(&priv->reg_mutex);
-- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
-- if (!_fdb.aging)
-- break;
-- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
-- ret = cb(_fdb.mac, _fdb.vid, is_static, data);
-- if (ret)
-- break;
-- }
-- mutex_unlock(&priv->reg_mutex);
--
-- return 0;
--}
--
--static int
--qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_mdb *mdb)
--{
-- struct qca8k_priv *priv = ds->priv;
-- const u8 *addr = mdb->addr;
-- u16 vid = mdb->vid;
--
-- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
--}
--
--static int
--qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_mdb *mdb)
--{
-- struct qca8k_priv *priv = ds->priv;
-- const u8 *addr = mdb->addr;
-- u16 vid = mdb->vid;
--
-- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
--}
--
--static int
--qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-- struct dsa_mall_mirror_tc_entry *mirror,
-- bool ingress)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int monitor_port, ret;
-- u32 reg, val;
--
-- /* Check for existent entry */
-- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
-- return -EEXIST;
--
-- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
-- if (ret)
-- return ret;
--
-- /* QCA83xx can have only one port set to mirror mode.
-- * Check that the correct port is requested and return error otherwise.
-- * When no mirror port is set, the values is set to 0xF
-- */
-- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
-- return -EEXIST;
--
-- /* Set the monitor port */
-- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
-- mirror->to_local_port);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (ret)
-- return ret;
--
-- if (ingress) {
-- reg = QCA8K_PORT_LOOKUP_CTRL(port);
-- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-- } else {
-- reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-- }
--
-- ret = regmap_update_bits(priv->regmap, reg, val, val);
-- if (ret)
-- return ret;
--
-- /* Track mirror port for tx and rx to decide when the
-- * mirror port has to be disabled.
-- */
-- if (ingress)
-- priv->mirror_rx |= BIT(port);
-- else
-- priv->mirror_tx |= BIT(port);
--
-- return 0;
--}
--
--static void
--qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-- struct dsa_mall_mirror_tc_entry *mirror)
--{
-- struct qca8k_priv *priv = ds->priv;
-- u32 reg, val;
-- int ret;
--
-- if (mirror->ingress) {
-- reg = QCA8K_PORT_LOOKUP_CTRL(port);
-- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-- } else {
-- reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-- }
--
-- ret = regmap_clear_bits(priv->regmap, reg, val);
-- if (ret)
-- goto err;
--
-- if (mirror->ingress)
-- priv->mirror_rx &= ~BIT(port);
-- else
-- priv->mirror_tx &= ~BIT(port);
--
-- /* No port set to send packet to mirror port. Disable mirror port */
-- if (!priv->mirror_rx && !priv->mirror_tx) {
-- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (ret)
-- goto err;
-- }
--err:
-- dev_err(priv->dev, "Failed to del mirror port from %d", port);
--}
--
--static int
--qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-- struct netlink_ext_ack *extack)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- if (vlan_filtering) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
-- } else {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
-- }
--
-- return ret;
--}
--
--static int
--qca8k_port_vlan_add(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_vlan *vlan,
-- struct netlink_ext_ack *extack)
--{
-- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
-- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
-- if (ret) {
-- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
-- return ret;
-- }
--
-- if (pvid) {
-- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-- QCA8K_EGREES_VLAN_PORT_MASK(port),
-- QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
-- if (ret)
-- return ret;
--
-- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
-- QCA8K_PORT_VLAN_CVID(vlan->vid) |
-- QCA8K_PORT_VLAN_SVID(vlan->vid));
-- }
--
-- return ret;
--}
--
--static int
--qca8k_port_vlan_del(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_vlan *vlan)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- ret = qca8k_vlan_del(priv, port, vlan->vid);
-- if (ret)
-- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
--
-- return ret;
--}
--
--static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- /* Communicate to the phy internal driver the switch revision.
-- * Based on the switch revision different values needs to be
-- * set to the dbg and mmd reg on the phy.
-- * The first 2 bit are used to communicate the switch revision
-- * to the phy driver.
-- */
-- if (port > 0 && port < 6)
-- return priv->switch_revision;
--
-- return 0;
--}
--
--static enum dsa_tag_protocol
--qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
-- enum dsa_tag_protocol mp)
--{
-- return DSA_TAG_PROTO_QCA;
--}
--
--static bool
--qca8k_lag_can_offload(struct dsa_switch *ds,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- struct dsa_port *dp;
-- int id, members = 0;
--
-- id = dsa_lag_id(ds->dst, lag);
-- if (id < 0 || id >= ds->num_lag_ids)
-- return false;
--
-- dsa_lag_foreach_port(dp, ds->dst, lag)
-- /* Includes the port joining the LAG */
-- members++;
--
-- if (members > QCA8K_NUM_PORTS_FOR_LAG)
-- return false;
--
-- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
-- return false;
--
-- if (info->hash_type != NETDEV_LAG_HASH_L2 &&
-- info->hash_type != NETDEV_LAG_HASH_L23)
-- return false;
--
-- return true;
--}
--
--static int
--qca8k_lag_setup_hash(struct dsa_switch *ds,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- struct qca8k_priv *priv = ds->priv;
-- bool unique_lag = true;
-- u32 hash = 0;
-- int i, id;
--
-- id = dsa_lag_id(ds->dst, lag);
--
-- switch (info->hash_type) {
-- case NETDEV_LAG_HASH_L23:
-- hash |= QCA8K_TRUNK_HASH_SIP_EN;
-- hash |= QCA8K_TRUNK_HASH_DIP_EN;
-- fallthrough;
-- case NETDEV_LAG_HASH_L2:
-- hash |= QCA8K_TRUNK_HASH_SA_EN;
-- hash |= QCA8K_TRUNK_HASH_DA_EN;
-- break;
-- default: /* We should NEVER reach this */
-- return -EOPNOTSUPP;
-- }
--
-- /* Check if we are the unique configured LAG */
-- dsa_lags_foreach_id(i, ds->dst)
-- if (i != id && dsa_lag_dev(ds->dst, i)) {
-- unique_lag = false;
-- break;
-- }
--
-- /* Hash Mode is global. Make sure the same Hash Mode
-- * is set to all the 4 possible lag.
-- * If we are the unique LAG we can set whatever hash
-- * mode we want.
-- * To change hash mode it's needed to remove all LAG
-- * and change the mode with the latest.
-- */
-- if (unique_lag) {
-- priv->lag_hash_mode = hash;
-- } else if (priv->lag_hash_mode != hash) {
-- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n");
-- return -EOPNOTSUPP;
-- }
--
-- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
-- QCA8K_TRUNK_HASH_MASK, hash);
--}
--
--static int
--qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
-- struct net_device *lag, bool delete)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret, id, i;
-- u32 val;
--
-- id = dsa_lag_id(ds->dst, lag);
--
-- /* Read current port member */
-- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
-- if (ret)
-- return ret;
--
-- /* Shift val to the correct trunk */
-- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
-- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
-- if (delete)
-- val &= ~BIT(port);
-- else
-- val |= BIT(port);
--
-- /* Update port member. With empty portmap disable trunk */
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
-- QCA8K_REG_GOL_TRUNK_MEMBER(id) |
-- QCA8K_REG_GOL_TRUNK_EN(id),
-- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
-- val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
--
-- /* Search empty member if adding or port on deleting */
-- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
-- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
-- if (ret)
-- return ret;
--
-- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
-- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
--
-- if (delete) {
-- /* If port flagged to be disabled assume this member is
-- * empty
-- */
-- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-- continue;
--
-- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
-- if (val != port)
-- continue;
-- } else {
-- /* If port flagged to be enabled assume this member is
-- * already set
-- */
-- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-- continue;
-- }
--
-- /* We have found the member to add/remove */
-- break;
-- }
--
-- /* Set port in the correct port mask or disable port if in delete mode */
-- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
-- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
-- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
-- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
-- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
--}
--
--static int
--qca8k_port_lag_join(struct dsa_switch *ds, int port,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- int ret;
--
-- if (!qca8k_lag_can_offload(ds, lag, info))
-- return -EOPNOTSUPP;
--
-- ret = qca8k_lag_setup_hash(ds, lag, info);
-- if (ret)
-- return ret;
--
-- return qca8k_lag_refresh_portmap(ds, port, lag, false);
--}
--
--static int
--qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-- struct net_device *lag)
--{
-- return qca8k_lag_refresh_portmap(ds, port, lag, true);
--}
--
--static void
--qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
-- bool operational)
--{
-- struct dsa_port *dp = master->dsa_ptr;
-- struct qca8k_priv *priv = ds->priv;
--
-- /* Ethernet MIB/MDIO is only supported for CPU port 0 */
-- if (dp->index != 0)
-- return;
--
-- mutex_lock(&priv->mgmt_eth_data.mutex);
-- mutex_lock(&priv->mib_eth_data.mutex);
--
-- priv->mgmt_master = operational ? (struct net_device *)master : NULL;
--
-- mutex_unlock(&priv->mib_eth_data.mutex);
-- mutex_unlock(&priv->mgmt_eth_data.mutex);
--}
--
--static int qca8k_connect_tag_protocol(struct dsa_switch *ds,
-- enum dsa_tag_protocol proto)
--{
-- struct qca_tagger_data *tagger_data;
--
-- switch (proto) {
-- case DSA_TAG_PROTO_QCA:
-- tagger_data = ds->tagger_data;
--
-- tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler;
-- tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler;
--
-- break;
-- default:
-- return -EOPNOTSUPP;
-- }
--
-- return 0;
--}
--
--static const struct dsa_switch_ops qca8k_switch_ops = {
-- .get_tag_protocol = qca8k_get_tag_protocol,
-- .setup = qca8k_setup,
-- .get_strings = qca8k_get_strings,
-- .get_ethtool_stats = qca8k_get_ethtool_stats,
-- .get_sset_count = qca8k_get_sset_count,
-- .set_ageing_time = qca8k_set_ageing_time,
-- .get_mac_eee = qca8k_get_mac_eee,
-- .set_mac_eee = qca8k_set_mac_eee,
-- .port_enable = qca8k_port_enable,
-- .port_disable = qca8k_port_disable,
-- .port_change_mtu = qca8k_port_change_mtu,
-- .port_max_mtu = qca8k_port_max_mtu,
-- .port_stp_state_set = qca8k_port_stp_state_set,
-- .port_bridge_join = qca8k_port_bridge_join,
-- .port_bridge_leave = qca8k_port_bridge_leave,
-- .port_fast_age = qca8k_port_fast_age,
-- .port_fdb_add = qca8k_port_fdb_add,
-- .port_fdb_del = qca8k_port_fdb_del,
-- .port_fdb_dump = qca8k_port_fdb_dump,
-- .port_mdb_add = qca8k_port_mdb_add,
-- .port_mdb_del = qca8k_port_mdb_del,
-- .port_mirror_add = qca8k_port_mirror_add,
-- .port_mirror_del = qca8k_port_mirror_del,
-- .port_vlan_filtering = qca8k_port_vlan_filtering,
-- .port_vlan_add = qca8k_port_vlan_add,
-- .port_vlan_del = qca8k_port_vlan_del,
-- .phylink_validate = qca8k_phylink_validate,
-- .phylink_mac_link_state = qca8k_phylink_mac_link_state,
-- .phylink_mac_config = qca8k_phylink_mac_config,
-- .phylink_mac_link_down = qca8k_phylink_mac_link_down,
-- .phylink_mac_link_up = qca8k_phylink_mac_link_up,
-- .get_phy_flags = qca8k_get_phy_flags,
-- .port_lag_join = qca8k_port_lag_join,
-- .port_lag_leave = qca8k_port_lag_leave,
-- .master_state_change = qca8k_master_change,
-- .connect_tag_protocol = qca8k_connect_tag_protocol,
--};
--
--static int qca8k_read_switch_id(struct qca8k_priv *priv)
--{
-- u32 val;
-- u8 id;
-- int ret;
--
-- if (!priv->info)
-- return -ENODEV;
--
-- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-- if (ret < 0)
-- return -ENODEV;
--
-- id = QCA8K_MASK_CTRL_DEVICE_ID(val);
-- if (id != priv->info->id) {
-- dev_err(priv->dev,
-- "Switch id detected %x but expected %x",
-- id, priv->info->id);
-- return -ENODEV;
-- }
--
-- priv->switch_id = id;
--
-- /* Save revision to communicate to the internal PHY driver */
-- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
--
-- return 0;
--}
--
--static int
--qca8k_sw_probe(struct mdio_device *mdiodev)
--{
-- struct qca8k_priv *priv;
-- int ret;
--
-- /* allocate the private data struct so that we can probe the switches
-- * ID register
-- */
-- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- priv->info = of_device_get_match_data(priv->dev);
-- priv->bus = mdiodev->bus;
-- priv->dev = &mdiodev->dev;
--
-- priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
-- GPIOD_ASIS);
-- if (IS_ERR(priv->reset_gpio))
-- return PTR_ERR(priv->reset_gpio);
--
-- if (priv->reset_gpio) {
-- gpiod_set_value_cansleep(priv->reset_gpio, 1);
-- /* The active low duration must be greater than 10 ms
-- * and checkpatch.pl wants 20 ms.
-- */
-- msleep(20);
-- gpiod_set_value_cansleep(priv->reset_gpio, 0);
-- }
--
-- /* Start by setting up the register mapping */
-- priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv,
-- &qca8k_regmap_config);
-- if (IS_ERR(priv->regmap)) {
-- dev_err(priv->dev, "regmap initialization failed");
-- return PTR_ERR(priv->regmap);
-- }
--
-- priv->mdio_cache.page = 0xffff;
-- priv->mdio_cache.lo = 0xffff;
-- priv->mdio_cache.hi = 0xffff;
--
-- /* Check the detected switch id */
-- ret = qca8k_read_switch_id(priv);
-- if (ret)
-- return ret;
--
-- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-- if (!priv->ds)
-- return -ENOMEM;
--
-- mutex_init(&priv->mgmt_eth_data.mutex);
-- init_completion(&priv->mgmt_eth_data.rw_done);
--
-- mutex_init(&priv->mib_eth_data.mutex);
-- init_completion(&priv->mib_eth_data.rw_done);
--
-- priv->ds->dev = &mdiodev->dev;
-- priv->ds->num_ports = QCA8K_NUM_PORTS;
-- priv->ds->priv = priv;
-- priv->ds->ops = &qca8k_switch_ops;
-- mutex_init(&priv->reg_mutex);
-- dev_set_drvdata(&mdiodev->dev, priv);
--
-- return dsa_register_switch(priv->ds);
--}
--
--static void
--qca8k_sw_remove(struct mdio_device *mdiodev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
-- int i;
--
-- if (!priv)
-- return;
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++)
-- qca8k_port_set_status(priv, i, 0);
--
-- dsa_unregister_switch(priv->ds);
--
-- dev_set_drvdata(&mdiodev->dev, NULL);
--}
--
--static void qca8k_sw_shutdown(struct mdio_device *mdiodev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
--
-- if (!priv)
-- return;
--
-- dsa_switch_shutdown(priv->ds);
--
-- dev_set_drvdata(&mdiodev->dev, NULL);
--}
--
--#ifdef CONFIG_PM_SLEEP
--static void
--qca8k_set_pm(struct qca8k_priv *priv, int enable)
--{
-- int port;
--
-- for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-- /* Do not enable on resume if the port was
-- * disabled before.
-- */
-- if (!(priv->port_enabled_map & BIT(port)))
-- continue;
--
-- qca8k_port_set_status(priv, port, enable);
-- }
--}
--
--static int qca8k_suspend(struct device *dev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(dev);
--
-- qca8k_set_pm(priv, 0);
--
-- return dsa_switch_suspend(priv->ds);
--}
--
--static int qca8k_resume(struct device *dev)
--{
-- struct qca8k_priv *priv = dev_get_drvdata(dev);
--
-- qca8k_set_pm(priv, 1);
--
-- return dsa_switch_resume(priv->ds);
--}
--#endif /* CONFIG_PM_SLEEP */
--
--static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-- qca8k_suspend, qca8k_resume);
--
--static const struct qca8k_info_ops qca8xxx_ops = {
-- .autocast_mib = qca8k_get_ethtool_stats_eth,
--};
--
--static const struct qca8k_match_data qca8327 = {
-- .id = QCA8K_ID_QCA8327,
-- .reduced_package = true,
-- .mib_count = QCA8K_QCA832X_MIB_COUNT,
-- .ops = &qca8xxx_ops,
--};
--
--static const struct qca8k_match_data qca8328 = {
-- .id = QCA8K_ID_QCA8327,
-- .mib_count = QCA8K_QCA832X_MIB_COUNT,
-- .ops = &qca8xxx_ops,
--};
--
--static const struct qca8k_match_data qca833x = {
-- .id = QCA8K_ID_QCA8337,
-- .mib_count = QCA8K_QCA833X_MIB_COUNT,
-- .ops = &qca8xxx_ops,
--};
--
--static const struct of_device_id qca8k_of_match[] = {
-- { .compatible = "qca,qca8327", .data = &qca8327 },
-- { .compatible = "qca,qca8328", .data = &qca8328 },
-- { .compatible = "qca,qca8334", .data = &qca833x },
-- { .compatible = "qca,qca8337", .data = &qca833x },
-- { /* sentinel */ },
--};
--
--static struct mdio_driver qca8kmdio_driver = {
-- .probe = qca8k_sw_probe,
-- .remove = qca8k_sw_remove,
-- .shutdown = qca8k_sw_shutdown,
-- .mdiodrv.driver = {
-- .name = "qca8k",
-- .of_match_table = qca8k_of_match,
-- .pm = &qca8k_pm_ops,
-- },
--};
--
--mdio_module_driver(qca8kmdio_driver);
--
--MODULE_AUTHOR("Mathieu Olivari, John Crispin <john@phrozen.org>");
--MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family");
--MODULE_LICENSE("GPL v2");
--MODULE_ALIAS("platform:qca8k");
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -0,0 +1,3186 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
-+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2016 John Crispin <john@phrozen.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/phy.h>
-+#include <linux/netdevice.h>
-+#include <linux/bitfield.h>
-+#include <linux/regmap.h>
-+#include <net/dsa.h>
-+#include <linux/of_net.h>
-+#include <linux/of_mdio.h>
-+#include <linux/of_platform.h>
-+#include <linux/if_bridge.h>
-+#include <linux/mdio.h>
-+#include <linux/phylink.h>
-+#include <linux/gpio/consumer.h>
-+#include <linux/etherdevice.h>
-+#include <linux/dsa/tag_qca.h>
-+
-+#include "qca8k.h"
-+
-+static void
-+qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
-+{
-+ regaddr >>= 1;
-+ *r1 = regaddr & 0x1e;
-+
-+ regaddr >>= 5;
-+ *r2 = regaddr & 0x7;
-+
-+ regaddr >>= 3;
-+ *page = regaddr & 0x3ff;
-+}
-+
-+static int
-+qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
-+{
-+ u16 *cached_lo = &priv->mdio_cache.lo;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (lo == *cached_lo)
-+ return 0;
-+
-+ ret = bus->write(bus, phy_id, regnum, lo);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit lo register\n");
-+
-+ *cached_lo = lo;
-+ return 0;
-+}
-+
-+static int
-+qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
-+{
-+ u16 *cached_hi = &priv->mdio_cache.hi;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (hi == *cached_hi)
-+ return 0;
-+
-+ ret = bus->write(bus, phy_id, regnum, hi);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit hi register\n");
-+
-+ *cached_hi = hi;
-+ return 0;
-+}
-+
-+static int
-+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+{
-+ int ret;
-+
-+ ret = bus->read(bus, phy_id, regnum);
-+ if (ret >= 0) {
-+ *val = ret;
-+ ret = bus->read(bus, phy_id, regnum + 1);
-+ *val |= ret << 16;
-+ }
-+
-+ if (ret < 0) {
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to read qca8k 32bit register\n");
-+ *val = 0;
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
-+{
-+ u16 lo, hi;
-+ int ret;
-+
-+ lo = val & 0xffff;
-+ hi = (u16)(val >> 16);
-+
-+ ret = qca8k_set_lo(priv, phy_id, regnum, lo);
-+ if (ret >= 0)
-+ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
-+}
-+
-+static int
-+qca8k_set_page(struct qca8k_priv *priv, u16 page)
-+{
-+ u16 *cached_page = &priv->mdio_cache.page;
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ if (page == *cached_page)
-+ return 0;
-+
-+ ret = bus->write(bus, 0x18, 0, page);
-+ if (ret < 0) {
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to set qca8k page\n");
-+ return ret;
-+ }
-+
-+ *cached_page = page;
-+ usleep_range(1000, 2000);
-+ return 0;
-+}
-+
-+static int
-+qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
-+{
-+ return regmap_read(priv->regmap, reg, val);
-+}
-+
-+static int
-+qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
-+{
-+ return regmap_write(priv->regmap, reg, val);
-+}
-+
-+static int
-+qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+{
-+ return regmap_update_bits(priv->regmap, reg, mask, write_val);
-+}
-+
-+static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ u8 len, cmd;
-+
-+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
-+ mgmt_eth_data = &priv->mgmt_eth_data;
-+
-+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
-+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
-+
-+ /* Make sure the seq match the requested packet */
-+ if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
-+ mgmt_eth_data->ack = true;
-+
-+ if (cmd == MDIO_READ) {
-+ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
-+
-+ /* Get the rest of the 12 byte of data.
-+ * The read/write function will extract the requested data.
-+ */
-+ if (len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(mgmt_eth_data->data + 1, skb->data,
-+ QCA_HDR_MGMT_DATA2_LEN);
-+ }
-+
-+ complete(&mgmt_eth_data->rw_done);
-+}
-+
-+static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,
-+ int priority, unsigned int len)
-+{
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ unsigned int real_len;
-+ struct sk_buff *skb;
-+ u32 *data2;
-+ u16 hdr;
-+
-+ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
-+ if (!skb)
-+ return NULL;
-+
-+ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
-+ * Actually for some reason the steps are:
-+ * 0: nothing
-+ * 1-4: first 4 byte
-+ * 5-6: first 12 byte
-+ * 7-15: all 16 byte
-+ */
-+ if (len == 16)
-+ real_len = 15;
-+ else
-+ real_len = len;
-+
-+ skb_reset_mac_header(skb);
-+ skb_set_network_header(skb, skb->len);
-+
-+ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);
-+
-+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority);
-+ hdr |= QCA_HDR_XMIT_FROM_CPU;
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
-+ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
-+
-+ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
-+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
-+ QCA_HDR_MGMT_CHECK_CODE_VAL);
-+
-+ if (cmd == MDIO_WRITE)
-+ mgmt_ethhdr->mdio_data = *val;
-+
-+ mgmt_ethhdr->hdr = htons(hdr);
-+
-+ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
-+
-+ return skb;
-+}
-+
-+static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
-+{
-+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+
-+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
-+ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
-+}
-+
-+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-+ struct sk_buff *skb;
-+ bool ack;
-+ int ret;
-+
-+ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,
-+ QCA8K_ETHERNET_MDIO_PRIORITY, len);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check mgmt_master if is operational */
-+ if (!priv->mgmt_master) {
-+ kfree_skb(skb);
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ return -EINVAL;
-+ }
-+
-+ skb->dev = priv->mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the mdio pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
-+
-+ *val = mgmt_eth_data->data[0];
-+ if (len > QCA_HDR_MGMT_DATA1_LEN)
-+ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
-+ struct sk_buff *skb;
-+ bool ack;
-+ int ret;
-+
-+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val,
-+ QCA8K_ETHERNET_MDIO_PRIORITY, len);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check mgmt_master if is operational */
-+ if (!priv->mgmt_master) {
-+ kfree_skb(skb);
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ return -EINVAL;
-+ }
-+
-+ skb->dev = priv->mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the mdio pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+{
-+ u32 val = 0;
-+ int ret;
-+
-+ ret = qca8k_read_eth(priv, reg, &val, sizeof(val));
-+ if (ret)
-+ return ret;
-+
-+ val &= ~mask;
-+ val |= write_val;
-+
-+ return qca8k_write_eth(priv, reg, &val, sizeof(val));
-+}
-+
-+static int
-+qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+
-+ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+ u32 tmp;
-+
-+ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ tmp = val[i];
-+
-+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ int ret;
-+
-+ if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
-+ return 0;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);
-+
-+exit:
-+ mutex_unlock(&bus->mdio_lock);
-+ return ret;
-+}
-+
-+static int
-+qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ int ret;
-+
-+ if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
-+ return 0;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret < 0)
-+ goto exit;
-+
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+exit:
-+ mutex_unlock(&bus->mdio_lock);
-+ return ret;
-+}
-+
-+static int
-+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret;
-+
-+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
-+ return 0;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-+ if (ret < 0)
-+ goto exit;
-+
-+ val &= ~mask;
-+ val |= write_val;
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+exit:
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static const struct regmap_range qca8k_readable_ranges[] = {
-+ regmap_reg_range(0x0000, 0x00e4), /* Global control */
-+ regmap_reg_range(0x0100, 0x0168), /* EEE control */
-+ regmap_reg_range(0x0200, 0x0270), /* Parser control */
-+ regmap_reg_range(0x0400, 0x0454), /* ACL */
-+ regmap_reg_range(0x0600, 0x0718), /* Lookup */
-+ regmap_reg_range(0x0800, 0x0b70), /* QM */
-+ regmap_reg_range(0x0c00, 0x0c80), /* PKT */
-+ regmap_reg_range(0x0e00, 0x0e98), /* L3 */
-+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
-+
-+};
-+
-+static const struct regmap_access_table qca8k_readable_table = {
-+ .yes_ranges = qca8k_readable_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
-+};
-+
-+static struct regmap_config qca8k_regmap_config = {
-+ .reg_bits = 16,
-+ .val_bits = 32,
-+ .reg_stride = 4,
-+ .max_register = 0x16ac, /* end MIB - Port6 range */
-+ .reg_read = qca8k_regmap_read,
-+ .reg_write = qca8k_regmap_write,
-+ .reg_update_bits = qca8k_regmap_update_bits,
-+ .rd_table = &qca8k_readable_table,
-+ .disable_locking = true, /* Locking is handled by qca8k read/write */
-+ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
-+};
-+
-+static int
-+qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
-+{
-+ u32 val;
-+
-+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
-+}
-+
-+static int
-+qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
-+{
-+ u32 reg[3];
-+ int ret;
-+
-+ /* load the ARL table into an array */
-+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+ if (ret)
-+ return ret;
-+
-+ /* vid - 83:72 */
-+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
-+ /* aging - 67:64 */
-+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
-+ /* portmask - 54:48 */
-+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
-+ /* mac - 47:0 */
-+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
-+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
-+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
-+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
-+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
-+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac,
-+ u8 aging)
-+{
-+ u32 reg[3] = { 0 };
-+
-+ /* vid - 83:72 */
-+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-+ /* aging - 67:64 */
-+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
-+ /* portmask - 54:48 */
-+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
-+ /* mac - 47:0 */
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
-+
-+ /* load the array into the ARL table */
-+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+}
-+
-+static int
-+qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /* Set the command and FDB index */
-+ reg = QCA8K_ATU_FUNC_BUSY;
-+ reg |= cmd;
-+ if (port >= 0) {
-+ reg |= QCA8K_ATU_FUNC_PORT_EN;
-+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
-+ }
-+
-+ /* Write the function register triggering the table access */
-+ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-+ if (ret)
-+ return ret;
-+
-+ /* wait for completion */
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
-+ if (ret)
-+ return ret;
-+
-+ /* Check for table full violation when adding an entry */
-+ if (cmd == QCA8K_FDB_LOAD) {
-+ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
-+ if (ret < 0)
-+ return ret;
-+ if (reg & QCA8K_ATU_FUNC_FULL)
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port)
-+{
-+ int ret;
-+
-+ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
-+ if (ret < 0)
-+ return ret;
-+
-+ return qca8k_fdb_read(priv, fdb);
-+}
-+
-+static int
-+qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask,
-+ u16 vid, u8 aging)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_write(priv, vid, port_mask, mac, aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_write(priv, vid, port_mask, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static void
-+qca8k_fdb_flush(struct qca8k_priv *priv)
-+{
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static int
-+qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_fdb_read(priv, &fdb);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule exist. Delete first */
-+ if (!fdb.aging) {
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+ }
-+
-+ /* Add port to fdb portmask */
-+ fdb.port_mask |= port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
-+qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule doesn't exist. Why delete? */
-+ if (!fdb.aging) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+
-+ /* Only port in the rule is this port. Don't re insert */
-+ if (fdb.port_mask == port_mask)
-+ goto exit;
-+
-+ /* Remove port from port mask */
-+ fdb.port_mask &= ~port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
-+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /* Set the command and VLAN index */
-+ reg = QCA8K_VTU_FUNC1_BUSY;
-+ reg |= cmd;
-+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
-+
-+ /* Write the function register triggering the table access */
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-+ if (ret)
-+ return ret;
-+
-+ /* wait for completion */
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
-+ if (ret)
-+ return ret;
-+
-+ /* Check for table full violation when adding an entry */
-+ if (cmd == QCA8K_VLAN_LOAD) {
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
-+ if (ret < 0)
-+ return ret;
-+ if (reg & QCA8K_VTU_FUNC1_FULL)
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /*
-+ We do the right thing with VLAN 0 and treat it as untagged while
-+ preserving the tag on egress.
-+ */
-+ if (vid == 0)
-+ return 0;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-+ if (ret < 0)
-+ goto out;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+ if (ret < 0)
-+ goto out;
-+ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-+ if (untagged)
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
-+ else
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
-+
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+ if (ret)
-+ goto out;
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-+
-+out:
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
-+{
-+ u32 reg, mask;
-+ int ret, i;
-+ bool del;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-+ if (ret < 0)
-+ goto out;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+ if (ret < 0)
-+ goto out;
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
-+
-+ /* Check if we're the last member to be removed */
-+ del = true;
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
-+
-+ if ((reg & mask) != mask) {
-+ del = false;
-+ break;
-+ }
-+ }
-+
-+ if (del) {
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
-+ } else {
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+ if (ret)
-+ goto out;
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-+ }
-+
-+out:
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mib_init(struct qca8k_priv *priv)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
-+ QCA8K_MIB_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static void
-+qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
-+{
-+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
-+
-+ /* Port 0 and 6 have no internal PHY */
-+ if (port > 0 && port < 6)
-+ mask |= QCA8K_PORT_STATUS_LINK_AUTO;
-+
-+ if (enable)
-+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-+ else
-+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-+}
-+
-+static int
-+qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
-+ struct sk_buff *read_skb, u32 *val)
-+{
-+ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL);
-+ bool ack;
-+ int ret;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the copy pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0)
-+ return -ETIMEDOUT;
-+
-+ if (!ack)
-+ return -EINVAL;
-+
-+ *val = mgmt_eth_data->data[0];
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,
-+ int regnum, u16 data)
-+{
-+ struct sk_buff *write_skb, *clear_skb, *read_skb;
-+ struct qca8k_mgmt_eth_data *mgmt_eth_data;
-+ u32 write_val, clear_val = 0, val;
-+ struct net_device *mgmt_master;
-+ int ret, ret1;
-+ bool ack;
-+
-+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-+ return -EINVAL;
-+
-+ mgmt_eth_data = &priv->mgmt_eth_data;
-+
-+ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-+ QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
-+
-+ if (read) {
-+ write_val |= QCA8K_MDIO_MASTER_READ;
-+ } else {
-+ write_val |= QCA8K_MDIO_MASTER_WRITE;
-+ write_val |= QCA8K_MDIO_MASTER_DATA(data);
-+ }
-+
-+ /* Prealloc all the needed skb before the lock */
-+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val));
-+ if (!write_skb)
-+ return -ENOMEM;
-+
-+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-+ if (!clear_skb) {
-+ ret = -ENOMEM;
-+ goto err_clear_skb;
-+ }
-+
-+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val,
-+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
-+ if (!read_skb) {
-+ ret = -ENOMEM;
-+ goto err_read_skb;
-+ }
-+
-+ /* Actually start the request:
-+ * 1. Send mdio master packet
-+ * 2. Busy Wait for mdio master command
-+ * 3. Get the data if we are reading
-+ * 4. Reset the mdio master (even with error)
-+ */
-+ mutex_lock(&mgmt_eth_data->mutex);
-+
-+ /* Check if mgmt_master is operational */
-+ mgmt_master = priv->mgmt_master;
-+ if (!mgmt_master) {
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+ ret = -EINVAL;
-+ goto err_mgmt_master;
-+ }
-+
-+ read_skb->dev = mgmt_master;
-+ clear_skb->dev = mgmt_master;
-+ write_skb->dev = mgmt_master;
-+
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the write pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(write_skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0) {
-+ ret = -ETIMEDOUT;
-+ kfree_skb(read_skb);
-+ goto exit;
-+ }
-+
-+ if (!ack) {
-+ ret = -EINVAL;
-+ kfree_skb(read_skb);
-+ goto exit;
-+ }
-+
-+ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1,
-+ !(val & QCA8K_MDIO_MASTER_BUSY), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-+ mgmt_eth_data, read_skb, &val);
-+
-+ if (ret < 0 && ret1 < 0) {
-+ ret = ret1;
-+ goto exit;
-+ }
-+
-+ if (read) {
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the read pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(read_skb);
-+
-+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ ack = mgmt_eth_data->ack;
-+
-+ if (ret <= 0) {
-+ ret = -ETIMEDOUT;
-+ goto exit;
-+ }
-+
-+ if (!ack) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK;
-+ } else {
-+ kfree_skb(read_skb);
-+ }
-+exit:
-+ reinit_completion(&mgmt_eth_data->rw_done);
-+
-+ /* Increment seq_num and set it in the clear pkt */
-+ mgmt_eth_data->seq++;
-+ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq);
-+ mgmt_eth_data->ack = false;
-+
-+ dev_queue_xmit(clear_skb);
-+
-+ wait_for_completion_timeout(&mgmt_eth_data->rw_done,
-+ QCA8K_ETHERNET_TIMEOUT);
-+
-+ mutex_unlock(&mgmt_eth_data->mutex);
-+
-+ return ret;
-+
-+ /* Error handling before lock */
-+err_mgmt_master:
-+ kfree_skb(read_skb);
-+err_read_skb:
-+ kfree_skb(clear_skb);
-+err_clear_skb:
-+ kfree_skb(write_skb);
-+
-+ return ret;
-+}
-+
-+static u32
-+qca8k_port_to_phy(int port)
-+{
-+ /* From Andrew Lunn:
-+ * Port 0 has no internal phy.
-+ * Port 1 has an internal PHY at MDIO address 0.
-+ * Port 2 has an internal PHY at MDIO address 1.
-+ * ...
-+ * Port 5 has an internal PHY at MDIO address 4.
-+ * Port 6 has no internal PHY.
-+ */
-+
-+ return port - 1;
-+}
-+
-+static int
-+qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
-+{
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret, ret1;
-+
-+ qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+ ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-+ bus, 0x10 | r2, r1, &val);
-+
-+ /* Check if qca8k_read has failed for a different reason
-+ * before returnting -ETIMEDOUT
-+ */
-+ if (ret < 0 && ret1 < 0)
-+ return ret1;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret;
-+
-+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-+ return -EINVAL;
-+
-+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
-+ QCA8K_MDIO_MASTER_DATA(data);
-+
-+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret)
-+ goto exit;
-+
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-+ QCA8K_MDIO_MASTER_BUSY);
-+
-+exit:
-+ /* even if the busy_wait timeouts try to clear the MASTER_EN */
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u16 r1, r2, page;
-+ u32 val;
-+ int ret;
-+
-+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-+ return -EINVAL;
-+
-+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-+ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
-+
-+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = qca8k_set_page(priv, page);
-+ if (ret)
-+ goto exit;
-+
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+
-+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-+ QCA8K_MDIO_MASTER_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-+
-+exit:
-+ /* even if the busy_wait timeouts try to clear the MASTER_EN */
-+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ if (ret >= 0)
-+ ret = val & QCA8K_MDIO_MASTER_DATA_MASK;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
-+{
-+ struct qca8k_priv *priv = slave_bus->priv;
-+ int ret;
-+
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data);
-+ if (!ret)
-+ return 0;
-+
-+ return qca8k_mdio_write(priv, phy, regnum, data);
-+}
-+
-+static int
-+qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
-+{
-+ struct qca8k_priv *priv = slave_bus->priv;
-+ int ret;
-+
-+ /* Use mdio Ethernet when available, fallback to legacy one on error */
-+ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0);
-+ if (ret >= 0)
-+ return ret;
-+
-+ ret = qca8k_mdio_read(priv, phy, regnum);
-+
-+ if (ret < 0)
-+ return 0xffff;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data)
-+{
-+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-+
-+ return qca8k_internal_mdio_write(slave_bus, port, regnum, data);
-+}
-+
-+static int
-+qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum)
-+{
-+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-+
-+ return qca8k_internal_mdio_read(slave_bus, port, regnum);
-+}
-+
-+static int
-+qca8k_mdio_register(struct qca8k_priv *priv)
-+{
-+ struct dsa_switch *ds = priv->ds;
-+ struct device_node *mdio;
-+ struct mii_bus *bus;
-+
-+ bus = devm_mdiobus_alloc(ds->dev);
-+ if (!bus)
-+ return -ENOMEM;
-+
-+ bus->priv = (void *)priv;
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
-+ ds->dst->index, ds->index);
-+ bus->parent = ds->dev;
-+ bus->phy_mask = ~ds->phys_mii_mask;
-+ ds->slave_mii_bus = bus;
-+
-+ /* Check if the devicetree declare the port:phy mapping */
-+ mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
-+ if (of_device_is_available(mdio)) {
-+ bus->name = "qca8k slave mii";
-+ bus->read = qca8k_internal_mdio_read;
-+ bus->write = qca8k_internal_mdio_write;
-+ return devm_of_mdiobus_register(priv->dev, bus, mdio);
-+ }
-+
-+ /* If a mapping can't be found the legacy mapping is used,
-+ * using the qca8k_port_to_phy function
-+ */
-+ bus->name = "qca8k-legacy slave mii";
-+ bus->read = qca8k_legacy_mdio_read;
-+ bus->write = qca8k_legacy_mdio_write;
-+ return devm_mdiobus_register(priv->dev, bus);
-+}
-+
-+static int
-+qca8k_setup_mdio_bus(struct qca8k_priv *priv)
-+{
-+ u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
-+ struct device_node *ports, *port;
-+ phy_interface_t mode;
-+ int err;
-+
-+ ports = of_get_child_by_name(priv->dev->of_node, "ports");
-+ if (!ports)
-+ ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports");
-+
-+ if (!ports)
-+ return -EINVAL;
-+
-+ for_each_available_child_of_node(ports, port) {
-+ err = of_property_read_u32(port, "reg", &reg);
-+ if (err) {
-+ of_node_put(port);
-+ of_node_put(ports);
-+ return err;
-+ }
-+
-+ if (!dsa_is_user_port(priv->ds, reg))
-+ continue;
-+
-+ of_get_phy_mode(port, &mode);
-+
-+ if (of_property_read_bool(port, "phy-handle") &&
-+ mode != PHY_INTERFACE_MODE_INTERNAL)
-+ external_mdio_mask |= BIT(reg);
-+ else
-+ internal_mdio_mask |= BIT(reg);
-+ }
-+
-+ of_node_put(ports);
-+ if (!external_mdio_mask && !internal_mdio_mask) {
-+ dev_err(priv->dev, "no PHYs are defined.\n");
-+ return -EINVAL;
-+ }
-+
-+ /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through
-+ * the MDIO_MASTER register also _disconnects_ the external MDC
-+ * passthrough to the internal PHYs. It's not possible to use both
-+ * configurations at the same time!
-+ *
-+ * Because this came up during the review process:
-+ * If the external mdio-bus driver is capable magically disabling
-+ * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's
-+ * accessors for the time being, it would be possible to pull this
-+ * off.
-+ */
-+ if (!!external_mdio_mask && !!internal_mdio_mask) {
-+ dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n");
-+ return -EINVAL;
-+ }
-+
-+ if (external_mdio_mask) {
-+ /* Make sure to disable the internal mdio bus in cases
-+ * a dt-overlay and driver reload changed the configuration
-+ */
-+
-+ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL,
-+ QCA8K_MDIO_MASTER_EN);
-+ }
-+
-+ return qca8k_mdio_register(priv);
-+}
-+
-+static int
-+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
-+{
-+ u32 mask = 0;
-+ int ret = 0;
-+
-+ /* SoC specific settings for ipq8064.
-+ * If more device require this consider adding
-+ * a dedicated binding.
-+ */
-+ if (of_machine_is_compatible("qcom,ipq8064"))
-+ mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
-+
-+ /* SoC specific settings for ipq8065 */
-+ if (of_machine_is_compatible("qcom,ipq8065"))
-+ mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
-+
-+ if (mask) {
-+ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
-+ QCA8K_MAC_PWR_RGMII0_1_8V |
-+ QCA8K_MAC_PWR_RGMII1_1_8V,
-+ mask);
-+ }
-+
-+ return ret;
-+}
-+
-+static int qca8k_find_cpu_port(struct dsa_switch *ds)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Find the connected cpu port. Valid port are 0 or 6 */
-+ if (dsa_is_cpu_port(ds, 0))
-+ return 0;
-+
-+ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
-+
-+ if (dsa_is_cpu_port(ds, 6))
-+ return 6;
-+
-+ return -EINVAL;
-+}
-+
-+static int
-+qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
-+{
-+ const struct qca8k_match_data *data = priv->info;
-+ struct device_node *node = priv->dev->of_node;
-+ u32 val = 0;
-+ int ret;
-+
-+ /* QCA8327 require to set to the correct mode.
-+ * His bigger brother QCA8328 have the 172 pin layout.
-+ * Should be applied by default but we set this just to make sure.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ /* Set the correct package of 148 pin for QCA8327 */
-+ if (data->reduced_package)
-+ val |= QCA8327_PWS_PACKAGE148_EN;
-+
-+ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
-+ val);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
-+ val |= QCA8K_PWS_POWER_ON_SEL;
-+
-+ if (of_property_read_bool(node, "qca,led-open-drain")) {
-+ if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
-+ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
-+ return -EINVAL;
-+ }
-+
-+ val |= QCA8K_PWS_LED_OPEN_EN_CSR;
-+ }
-+
-+ return qca8k_rmw(priv, QCA8K_REG_PWS,
-+ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
-+ val);
-+}
-+
-+static int
-+qca8k_parse_port_config(struct qca8k_priv *priv)
-+{
-+ int port, cpu_port_index = -1, ret;
-+ struct device_node *port_dn;
-+ phy_interface_t mode;
-+ struct dsa_port *dp;
-+ u32 delay;
-+
-+ /* We have 2 CPU port. Check them */
-+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+ /* Skip every other port */
-+ if (port != 0 && port != 6)
-+ continue;
-+
-+ dp = dsa_to_port(priv->ds, port);
-+ port_dn = dp->dn;
-+ cpu_port_index++;
-+
-+ if (!of_device_is_available(port_dn))
-+ continue;
-+
-+ ret = of_get_phy_mode(port_dn, &mode);
-+ if (ret)
-+ continue;
-+
-+ switch (mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_SGMII:
-+ delay = 0;
-+
-+ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-+ /* Switch regs accept value in ns, convert ps to ns */
-+ delay = delay / 1000;
-+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_TXID)
-+ delay = 1;
-+
-+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) {
-+ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-+ delay = 3;
-+ }
-+
-+ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
-+
-+ delay = 0;
-+
-+ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
-+ /* Switch regs accept value in ns, convert ps to ns */
-+ delay = delay / 1000;
-+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+ delay = 2;
-+
-+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) {
-+ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-+ delay = 3;
-+ }
-+
-+ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
-+
-+ /* Skip sgmii parsing for rgmii* mode */
-+ if (mode == PHY_INTERFACE_MODE_RGMII ||
-+ mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_TXID ||
-+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+ break;
-+
-+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-+ priv->ports_config.sgmii_tx_clk_falling_edge = true;
-+
-+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-+ priv->ports_config.sgmii_rx_clk_falling_edge = true;
-+
-+ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
-+ priv->ports_config.sgmii_enable_pll = true;
-+
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
-+ priv->ports_config.sgmii_enable_pll = false;
-+ }
-+
-+ if (priv->switch_revision < 2)
-+ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
-+ }
-+
-+ break;
-+ default:
-+ continue;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_setup(struct dsa_switch *ds)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ int cpu_port, ret, i;
-+ u32 mask;
-+
-+ cpu_port = qca8k_find_cpu_port(ds);
-+ if (cpu_port < 0) {
-+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
-+ return cpu_port;
-+ }
-+
-+ /* Parse CPU port config to be later used in phy_link mac_config */
-+ ret = qca8k_parse_port_config(priv);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_setup_mdio_bus(priv);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_setup_of_pws_reg(priv);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_setup_mac_pwr_sel(priv);
-+ if (ret)
-+ return ret;
-+
-+ /* Make sure MAC06 is disabled */
-+ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
-+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
-+ if (ret) {
-+ dev_err(priv->dev, "failed disabling MAC06 exchange");
-+ return ret;
-+ }
-+
-+ /* Enable CPU Port */
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-+ if (ret) {
-+ dev_err(priv->dev, "failed enabling CPU port");
-+ return ret;
-+ }
-+
-+ /* Enable MIB counters */
-+ ret = qca8k_mib_init(priv);
-+ if (ret)
-+ dev_warn(priv->dev, "mib init failed");
-+
-+ /* Initial setup of all ports */
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ /* Disable forwarding by default on all ports */
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_MEMBER, 0);
-+ if (ret)
-+ return ret;
-+
-+ /* Enable QCA header mode on all cpu ports */
-+ if (dsa_is_cpu_port(ds, i)) {
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
-+ if (ret) {
-+ dev_err(priv->dev, "failed enabling QCA header mode");
-+ return ret;
-+ }
-+ }
-+
-+ /* Disable MAC by default on all user ports */
-+ if (dsa_is_user_port(ds, i))
-+ qca8k_port_set_status(priv, i, 0);
-+ }
-+
-+ /* Forward all unknown frames to CPU port for Linux processing
-+ * Notice that in multi-cpu config only one port should be set
-+ * for igmp, unknown, multicast and broadcast packet
-+ */
-+ ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
-+ if (ret)
-+ return ret;
-+
-+ /* Setup connection between CPU port & user ports
-+ * Configure specific switch configuration for ports
-+ */
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ /* CPU port gets connected to all user ports of the switch */
-+ if (dsa_is_cpu_port(ds, i)) {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-+ if (ret)
-+ return ret;
-+ }
-+
-+ /* Individual user ports get connected to CPU port only */
-+ if (dsa_is_user_port(ds, i)) {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_MEMBER,
-+ BIT(cpu_port));
-+ if (ret)
-+ return ret;
-+
-+ /* Enable ARP Auto-learning by default */
-+ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_LEARN);
-+ if (ret)
-+ return ret;
-+
-+ /* For port based vlans to work we need to set the
-+ * default egress vid
-+ */
-+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-+ QCA8K_EGREES_VLAN_PORT_MASK(i),
-+ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF));
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-+ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-+ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-+ if (ret)
-+ return ret;
-+ }
-+
-+ /* The port 5 of the qca8337 have some problem in flood condition. The
-+ * original legacy driver had some specific buffer and priority settings
-+ * for the different port suggested by the QCA switch team. Add this
-+ * missing settings to improve switch stability under load condition.
-+ * This problem is limited to qca8337 and other qca8k switch are not affected.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8337) {
-+ switch (i) {
-+ /* The 2 CPU port and port 5 requires some different
-+ * priority than any other ports.
-+ */
-+ case 0:
-+ case 5:
-+ case 6:
-+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
-+ break;
-+ default:
-+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
-+ }
-+ qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
-+
-+ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
-+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_WRED_EN;
-+ qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
-+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
-+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_WRED_EN,
-+ mask);
-+ }
-+ }
-+
-+ /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-+ if (priv->switch_id == QCA8K_ID_QCA8327) {
-+ mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
-+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
-+ qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
-+ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK |
-+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK,
-+ mask);
-+ }
-+
-+ /* Setup our port MTUs to match power on defaults */
-+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
-+ if (ret)
-+ dev_warn(priv->dev, "failed setting MTU settings");
-+
-+ /* Flush the FDB table */
-+ qca8k_fdb_flush(priv);
-+
-+ /* We don't have interrupts for link changes, so we need to poll */
-+ ds->pcs_poll = true;
-+
-+ /* Set min a max ageing value supported */
-+ ds->ageing_time_min = 7000;
-+ ds->ageing_time_max = 458745000;
-+
-+ /* Set max number of LAGs supported */
-+ ds->num_lag_ids = QCA8K_NUM_LAGS;
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
-+ u32 reg)
-+{
-+ u32 delay, val = 0;
-+ int ret;
-+
-+ /* Delay can be declared in 3 different way.
-+ * Mode to rgmii and internal-delay standard binding defined
-+ * rgmii-id or rgmii-tx/rx phy mode set.
-+ * The parse logic set a delay different than 0 only when one
-+ * of the 3 different way is used. In all other case delay is
-+ * not enabled. With ID or TX/RXID delay is enabled and set
-+ * to the default and recommended value.
-+ */
-+ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
-+ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-+ }
-+
-+ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
-+ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
-+
-+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-+ }
-+
-+ /* Set RGMII delay based on the selected values */
-+ ret = qca8k_rmw(priv, reg,
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
-+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
-+ val);
-+ if (ret)
-+ dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
-+ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
-+}
-+
-+static void
-+qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ const struct phylink_link_state *state)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int cpu_port_index, ret;
-+ u32 reg, val;
-+
-+ switch (port) {
-+ case 0: /* 1st CPU port */
-+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII)
-+ return;
-+
-+ reg = QCA8K_REG_PORT0_PAD_CTRL;
-+ cpu_port_index = QCA8K_CPU_PORT0;
-+ break;
-+ case 1:
-+ case 2:
-+ case 3:
-+ case 4:
-+ case 5:
-+ /* Internal PHY, nothing to do */
-+ return;
-+ case 6: /* 2nd CPU port / external PHY */
-+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII &&
-+ state->interface != PHY_INTERFACE_MODE_1000BASEX)
-+ return;
-+
-+ reg = QCA8K_REG_PORT6_PAD_CTRL;
-+ cpu_port_index = QCA8K_CPU_PORT6;
-+ break;
-+ default:
-+ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
-+ return;
-+ }
-+
-+ if (port != 6 && phylink_autoneg_inband(mode)) {
-+ dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
-+ __func__);
-+ return;
-+ }
-+
-+ switch (state->interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
-+
-+ /* Configure rgmii delay */
-+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-+
-+ /* QCA8337 requires to set rgmii rx delay for all ports.
-+ * This is enabled through PORT5_PAD_CTRL for all ports,
-+ * rather than individual port registers.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8337)
-+ qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ /* Enable SGMII on the port */
-+ qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-+
-+ /* Enable/disable SerDes auto-negotiation as necessary */
-+ ret = qca8k_read(priv, QCA8K_REG_PWS, &val);
-+ if (ret)
-+ return;
-+ if (phylink_autoneg_inband(mode))
-+ val &= ~QCA8K_PWS_SERDES_AEN_DIS;
-+ else
-+ val |= QCA8K_PWS_SERDES_AEN_DIS;
-+ qca8k_write(priv, QCA8K_REG_PWS, val);
-+
-+ /* Configure the SGMII parameters */
-+ ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
-+ if (ret)
-+ return;
-+
-+ val |= QCA8K_SGMII_EN_SD;
-+
-+ if (priv->ports_config.sgmii_enable_pll)
-+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-+ QCA8K_SGMII_EN_TX;
-+
-+ if (dsa_is_cpu_port(ds, port)) {
-+ /* CPU port, we're talking to the CPU MAC, be a PHY */
-+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-+ val |= QCA8K_SGMII_MODE_CTRL_PHY;
-+ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
-+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-+ val |= QCA8K_SGMII_MODE_CTRL_MAC;
-+ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
-+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
-+ val |= QCA8K_SGMII_MODE_CTRL_BASEX;
-+ }
-+
-+ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
-+
-+ /* From original code is reported port instability as SGMII also
-+ * require delay set. Apply advised values here or take them from DT.
-+ */
-+ if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-+
-+ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
-+ * falling edge is set writing in the PORT0 PAD reg
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8327 ||
-+ priv->switch_id == QCA8K_ID_QCA8337)
-+ reg = QCA8K_REG_PORT0_PAD_CTRL;
-+
-+ val = 0;
-+
-+ /* SGMII Clock phase configuration */
-+ if (priv->ports_config.sgmii_rx_clk_falling_edge)
-+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
-+
-+ if (priv->ports_config.sgmii_tx_clk_falling_edge)
-+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
-+
-+ if (val)
-+ ret = qca8k_rmw(priv, reg,
-+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
-+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
-+ val);
-+
-+ break;
-+ default:
-+ dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
-+ phy_modes(state->interface), port);
-+ return;
-+ }
-+}
-+
-+static void
-+qca8k_phylink_validate(struct dsa_switch *ds, int port,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-+
-+ switch (port) {
-+ case 0: /* 1st CPU port */
-+ if (state->interface != PHY_INTERFACE_MODE_NA &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII)
-+ goto unsupported;
-+ break;
-+ case 1:
-+ case 2:
-+ case 3:
-+ case 4:
-+ case 5:
-+ /* Internal PHY */
-+ if (state->interface != PHY_INTERFACE_MODE_NA &&
-+ state->interface != PHY_INTERFACE_MODE_GMII &&
-+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
-+ goto unsupported;
-+ break;
-+ case 6: /* 2nd CPU port / external PHY */
-+ if (state->interface != PHY_INTERFACE_MODE_NA &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII &&
-+ state->interface != PHY_INTERFACE_MODE_1000BASEX)
-+ goto unsupported;
-+ break;
-+ default:
-+unsupported:
-+ linkmode_zero(supported);
-+ return;
-+ }
-+
-+ phylink_set_port_modes(mask);
-+ phylink_set(mask, Autoneg);
-+
-+ phylink_set(mask, 1000baseT_Full);
-+ phylink_set(mask, 10baseT_Half);
-+ phylink_set(mask, 10baseT_Full);
-+ phylink_set(mask, 100baseT_Half);
-+ phylink_set(mask, 100baseT_Full);
-+
-+ if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
-+ phylink_set(mask, 1000baseX_Full);
-+
-+ phylink_set(mask, Pause);
-+ phylink_set(mask, Asym_Pause);
-+
-+ linkmode_and(supported, supported, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
-+}
-+
-+static int
-+qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port,
-+ struct phylink_link_state *state)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg;
-+ int ret;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
-+ state->an_complete = state->link;
-+ state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
-+ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
-+ DUPLEX_HALF;
-+
-+ switch (reg & QCA8K_PORT_STATUS_SPEED) {
-+ case QCA8K_PORT_STATUS_SPEED_10:
-+ state->speed = SPEED_10;
-+ break;
-+ case QCA8K_PORT_STATUS_SPEED_100:
-+ state->speed = SPEED_100;
-+ break;
-+ case QCA8K_PORT_STATUS_SPEED_1000:
-+ state->speed = SPEED_1000;
-+ break;
-+ default:
-+ state->speed = SPEED_UNKNOWN;
-+ break;
-+ }
-+
-+ state->pause = MLO_PAUSE_NONE;
-+ if (reg & QCA8K_PORT_STATUS_RXFLOW)
-+ state->pause |= MLO_PAUSE_RX;
-+ if (reg & QCA8K_PORT_STATUS_TXFLOW)
-+ state->pause |= MLO_PAUSE_TX;
-+
-+ return 1;
-+}
-+
-+static void
-+qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 0);
-+}
-+
-+static void
-+qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface, struct phy_device *phydev,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg;
-+
-+ if (phylink_autoneg_inband(mode)) {
-+ reg = QCA8K_PORT_STATUS_LINK_AUTO;
-+ } else {
-+ switch (speed) {
-+ case SPEED_10:
-+ reg = QCA8K_PORT_STATUS_SPEED_10;
-+ break;
-+ case SPEED_100:
-+ reg = QCA8K_PORT_STATUS_SPEED_100;
-+ break;
-+ case SPEED_1000:
-+ reg = QCA8K_PORT_STATUS_SPEED_1000;
-+ break;
-+ default:
-+ reg = QCA8K_PORT_STATUS_LINK_AUTO;
-+ break;
-+ }
-+
-+ if (duplex == DUPLEX_FULL)
-+ reg |= QCA8K_PORT_STATUS_DUPLEX;
-+
-+ if (rx_pause || dsa_is_cpu_port(ds, port))
-+ reg |= QCA8K_PORT_STATUS_RXFLOW;
-+
-+ if (tx_pause || dsa_is_cpu_port(ds, port))
-+ reg |= QCA8K_PORT_STATUS_TXFLOW;
-+ }
-+
-+ reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
-+
-+ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
-+}
-+
-+static void
-+qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int i;
-+
-+ if (stringset != ETH_SS_STATS)
-+ return;
-+
-+ for (i = 0; i < priv->info->mib_count; i++)
-+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-+ ETH_GSTRING_LEN);
-+}
-+
-+static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
-+{
-+ struct qca8k_mib_eth_data *mib_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ const struct qca8k_mib_desc *mib;
-+ struct mib_ethhdr *mib_ethhdr;
-+ int i, mib_len, offset = 0;
-+ u64 *data;
-+ u8 port;
-+
-+ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
-+ mib_eth_data = &priv->mib_eth_data;
-+
-+ /* The switch autocast every port. Ignore other packet and
-+ * parse only the requested one.
-+ */
-+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr));
-+ if (port != mib_eth_data->req_port)
-+ goto exit;
-+
-+ data = mib_eth_data->data;
-+
-+ for (i = 0; i < priv->info->mib_count; i++) {
-+ mib = &ar8327_mib[i];
-+
-+ /* First 3 mib are present in the skb head */
-+ if (i < 3) {
-+ data[i] = mib_ethhdr->data[i];
-+ continue;
-+ }
-+
-+ mib_len = sizeof(uint32_t);
-+
-+ /* Some mib are 64 bit wide */
-+ if (mib->size == 2)
-+ mib_len = sizeof(uint64_t);
-+
-+ /* Copy the mib value from packet to the */
-+ memcpy(data + i, skb->data + offset, mib_len);
-+
-+ /* Set the offset for the next mib */
-+ offset += mib_len;
-+ }
-+
-+exit:
-+ /* Complete on receiving all the mib packet */
-+ if (refcount_dec_and_test(&mib_eth_data->port_parsed))
-+ complete(&mib_eth_data->rw_done);
-+}
-+
-+static int
-+qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
-+{
-+ struct dsa_port *dp = dsa_to_port(ds, port);
-+ struct qca8k_mib_eth_data *mib_eth_data;
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ mib_eth_data = &priv->mib_eth_data;
-+
-+ mutex_lock(&mib_eth_data->mutex);
-+
-+ reinit_completion(&mib_eth_data->rw_done);
-+
-+ mib_eth_data->req_port = dp->index;
-+ mib_eth_data->data = data;
-+ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS);
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ /* Send mib autocast request */
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) |
-+ QCA8K_MIB_BUSY);
-+
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ if (ret)
-+ goto exit;
-+
-+ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT);
-+
-+exit:
-+ mutex_unlock(&mib_eth_data->mutex);
-+
-+ return ret;
-+}
-+
-+static void
-+qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
-+ uint64_t *data)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ const struct qca8k_mib_desc *mib;
-+ u32 reg, i, val;
-+ u32 hi = 0;
-+ int ret;
-+
-+ if (priv->mgmt_master && priv->info->ops->autocast_mib &&
-+ priv->info->ops->autocast_mib(ds, port, data) > 0)
-+ return;
-+
-+ for (i = 0; i < priv->info->mib_count; i++) {
-+ mib = &ar8327_mib[i];
-+ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
-+
-+ ret = qca8k_read(priv, reg, &val);
-+ if (ret < 0)
-+ continue;
-+
-+ if (mib->size == 2) {
-+ ret = qca8k_read(priv, reg + 4, &hi);
-+ if (ret < 0)
-+ continue;
-+ }
-+
-+ data[i] = val;
-+ if (mib->size == 2)
-+ data[i] |= (u64)hi << 32;
-+ }
-+}
-+
-+static int
-+qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ if (sset != ETH_SS_STATS)
-+ return 0;
-+
-+ return priv->info->mib_count;
-+}
-+
-+static int
-+qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
-+ u32 reg;
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
-+ if (ret < 0)
-+ goto exit;
-+
-+ if (eee->eee_enabled)
-+ reg |= lpi_en;
-+ else
-+ reg &= ~lpi_en;
-+ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int
-+qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
-+{
-+ /* Nothing to do on the port's MAC */
-+ return 0;
-+}
-+
-+static void
-+qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u32 stp_state;
-+
-+ switch (state) {
-+ case BR_STATE_DISABLED:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
-+ break;
-+ case BR_STATE_BLOCKING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
-+ break;
-+ case BR_STATE_LISTENING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
-+ break;
-+ case BR_STATE_LEARNING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
-+ break;
-+ case BR_STATE_FORWARDING:
-+ default:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
-+ break;
-+ }
-+
-+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
-+}
-+
-+static int
-+qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ int port_mask, cpu_port;
-+ int i, ret;
-+
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+ port_mask = BIT(cpu_port);
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
-+ if (dsa_to_port(ds, i)->bridge_dev != br)
-+ continue;
-+ /* Add this port to the portvlan mask of the other ports
-+ * in the bridge
-+ */
-+ ret = regmap_set_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
-+ if (ret)
-+ return ret;
-+ if (i != port)
-+ port_mask |= BIT(i);
-+ }
-+
-+ /* Add all other ports to this ports portvlan mask */
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER, port_mask);
-+
-+ return ret;
-+}
-+
-+static void
-+qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ int cpu_port, i;
-+
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
-+ if (dsa_to_port(ds, i)->bridge_dev != br)
-+ continue;
-+ /* Remove this port to the portvlan mask of the other ports
-+ * in the bridge
-+ */
-+ regmap_clear_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
-+ }
-+
-+ /* Set the cpu port to be the only one in the portvlan mask of
-+ * this port
-+ */
-+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
-+}
-+
-+static void
-+qca8k_port_fast_age(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static int
-+qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ unsigned int secs = msecs / 1000;
-+ u32 val;
-+
-+ /* AGE_TIME reg is set in 7s step */
-+ val = secs / 7;
-+
-+ /* Handle case with 0 as val to NOT disable
-+ * learning
-+ */
-+ if (!val)
-+ val = 1;
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
-+ QCA8K_ATU_AGE_TIME(val));
-+}
-+
-+static int
-+qca8k_port_enable(struct dsa_switch *ds, int port,
-+ struct phy_device *phy)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 1);
-+ priv->port_enabled_map |= BIT(port);
-+
-+ if (dsa_is_user_port(ds, port))
-+ phy_support_asym_pause(phy);
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_port_disable(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 0);
-+ priv->port_enabled_map &= ~BIT(port);
-+}
-+
-+static int
-+qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ /* We have only have a general MTU setting.
-+ * DSA always set the CPU port's MTU to the largest MTU of the slave
-+ * ports.
-+ * Setting MTU just for the CPU port is sufficient to correctly set a
-+ * value for every port.
-+ */
-+ if (!dsa_is_cpu_port(ds, port))
-+ return 0;
-+
-+ /* To change the MAX_FRAME_SIZE the cpu ports must be off or
-+ * the switch panics.
-+ * Turn off both cpu ports before applying the new value to prevent
-+ * this.
-+ */
-+ if (priv->port_enabled_map & BIT(0))
-+ qca8k_port_set_status(priv, 0, 0);
-+
-+ if (priv->port_enabled_map & BIT(6))
-+ qca8k_port_set_status(priv, 6, 0);
-+
-+ /* Include L2 header / FCS length */
-+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
-+
-+ if (priv->port_enabled_map & BIT(0))
-+ qca8k_port_set_status(priv, 0, 1);
-+
-+ if (priv->port_enabled_map & BIT(6))
-+ qca8k_port_set_status(priv, 6, 1);
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_port_max_mtu(struct dsa_switch *ds, int port)
-+{
-+ return QCA8K_MAX_MTU;
-+}
-+
-+static int
-+qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
-+ u16 port_mask, u16 vid)
-+{
-+ /* Set the vid to the port vlan id if no vid is set */
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ return qca8k_fdb_add(priv, addr, port_mask, vid,
-+ QCA8K_ATU_STATUS_STATIC);
-+}
-+
-+static int
-+qca8k_port_fdb_add(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u16 port_mask = BIT(port);
-+
-+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
-+}
-+
-+static int
-+qca8k_port_fdb_del(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u16 port_mask = BIT(port);
-+
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ return qca8k_fdb_del(priv, addr, port_mask, vid);
-+}
-+
-+static int
-+qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
-+ dsa_fdb_dump_cb_t *cb, void *data)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ struct qca8k_fdb _fdb = { 0 };
-+ int cnt = QCA8K_NUM_FDB_RECORDS;
-+ bool is_static;
-+ int ret = 0;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
-+ if (!_fdb.aging)
-+ break;
-+ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
-+ ret = cb(_fdb.mac, _fdb.vid, is_static, data);
-+ if (ret)
-+ break;
-+ }
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
-+}
-+
-+static int
-+qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
-+}
-+
-+static int
-+qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror,
-+ bool ingress)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int monitor_port, ret;
-+ u32 reg, val;
-+
-+ /* Check for existent entry */
-+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
-+ return -EEXIST;
-+
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* QCA83xx can have only one port set to mirror mode.
-+ * Check that the correct port is requested and return error otherwise.
-+ * When no mirror port is set, the values is set to 0xF
-+ */
-+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
-+ return -EEXIST;
-+
-+ /* Set the monitor port */
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
-+ mirror->to_local_port);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ return ret;
-+
-+ if (ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_update_bits(priv->regmap, reg, val, val);
-+ if (ret)
-+ return ret;
-+
-+ /* Track mirror port for tx and rx to decide when the
-+ * mirror port has to be disabled.
-+ */
-+ if (ingress)
-+ priv->mirror_rx |= BIT(port);
-+ else
-+ priv->mirror_tx |= BIT(port);
-+
-+ return 0;
-+}
-+
-+static void
-+qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg, val;
-+ int ret;
-+
-+ if (mirror->ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_clear_bits(priv->regmap, reg, val);
-+ if (ret)
-+ goto err;
-+
-+ if (mirror->ingress)
-+ priv->mirror_rx &= ~BIT(port);
-+ else
-+ priv->mirror_tx &= ~BIT(port);
-+
-+ /* No port set to send packet to mirror port. Disable mirror port */
-+ if (!priv->mirror_rx && !priv->mirror_tx) {
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ goto err;
-+ }
-+err:
-+ dev_err(priv->dev, "Failed to del mirror port from %d", port);
-+}
-+
-+static int
-+qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ if (vlan_filtering) {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
-+ } else {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_port_vlan_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan,
-+ struct netlink_ext_ack *extack)
-+{
-+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
-+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
-+ if (ret) {
-+ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
-+ return ret;
-+ }
-+
-+ if (pvid) {
-+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-+ QCA8K_EGREES_VLAN_PORT_MASK(port),
-+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
-+ QCA8K_PORT_VLAN_CVID(vlan->vid) |
-+ QCA8K_PORT_VLAN_SVID(vlan->vid));
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_port_vlan_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ ret = qca8k_vlan_del(priv, port, vlan->vid);
-+ if (ret)
-+ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
-+
-+ return ret;
-+}
-+
-+static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Communicate to the phy internal driver the switch revision.
-+ * Based on the switch revision different values needs to be
-+ * set to the dbg and mmd reg on the phy.
-+ * The first 2 bit are used to communicate the switch revision
-+ * to the phy driver.
-+ */
-+ if (port > 0 && port < 6)
-+ return priv->switch_revision;
-+
-+ return 0;
-+}
-+
-+static enum dsa_tag_protocol
-+qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
-+ enum dsa_tag_protocol mp)
-+{
-+ return DSA_TAG_PROTO_QCA;
-+}
-+
-+static bool
-+qca8k_lag_can_offload(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct dsa_port *dp;
-+ int id, members = 0;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+ if (id < 0 || id >= ds->num_lag_ids)
-+ return false;
-+
-+ dsa_lag_foreach_port(dp, ds->dst, lag)
-+ /* Includes the port joining the LAG */
-+ members++;
-+
-+ if (members > QCA8K_NUM_PORTS_FOR_LAG)
-+ return false;
-+
-+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
-+ return false;
-+
-+ if (info->hash_type != NETDEV_LAG_HASH_L2 &&
-+ info->hash_type != NETDEV_LAG_HASH_L23)
-+ return false;
-+
-+ return true;
-+}
-+
-+static int
-+qca8k_lag_setup_hash(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ bool unique_lag = true;
-+ u32 hash = 0;
-+ int i, id;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ switch (info->hash_type) {
-+ case NETDEV_LAG_HASH_L23:
-+ hash |= QCA8K_TRUNK_HASH_SIP_EN;
-+ hash |= QCA8K_TRUNK_HASH_DIP_EN;
-+ fallthrough;
-+ case NETDEV_LAG_HASH_L2:
-+ hash |= QCA8K_TRUNK_HASH_SA_EN;
-+ hash |= QCA8K_TRUNK_HASH_DA_EN;
-+ break;
-+ default: /* We should NEVER reach this */
-+ return -EOPNOTSUPP;
-+ }
-+
-+ /* Check if we are the unique configured LAG */
-+ dsa_lags_foreach_id(i, ds->dst)
-+ if (i != id && dsa_lag_dev(ds->dst, i)) {
-+ unique_lag = false;
-+ break;
-+ }
-+
-+ /* Hash Mode is global. Make sure the same Hash Mode
-+ * is set to all the 4 possible lag.
-+ * If we are the unique LAG we can set whatever hash
-+ * mode we want.
-+ * To change hash mode it's needed to remove all LAG
-+ * and change the mode with the latest.
-+ */
-+ if (unique_lag) {
-+ priv->lag_hash_mode = hash;
-+ } else if (priv->lag_hash_mode != hash) {
-+ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
-+ QCA8K_TRUNK_HASH_MASK, hash);
-+}
-+
-+static int
-+qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
-+ struct net_device *lag, bool delete)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret, id, i;
-+ u32 val;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ /* Read current port member */
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* Shift val to the correct trunk */
-+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
-+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
-+ if (delete)
-+ val &= ~BIT(port);
-+ else
-+ val |= BIT(port);
-+
-+ /* Update port member. With empty portmap disable trunk */
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
-+ QCA8K_REG_GOL_TRUNK_MEMBER(id) |
-+ QCA8K_REG_GOL_TRUNK_EN(id),
-+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
-+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
-+
-+ /* Search empty member if adding or port on deleting */
-+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
-+ if (ret)
-+ return ret;
-+
-+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
-+
-+ if (delete) {
-+ /* If port flagged to be disabled assume this member is
-+ * empty
-+ */
-+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
-+ if (val != port)
-+ continue;
-+ } else {
-+ /* If port flagged to be enabled assume this member is
-+ * already set
-+ */
-+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+ }
-+
-+ /* We have found the member to add/remove */
-+ break;
-+ }
-+
-+ /* Set port in the correct port mask or disable port if in delete mode */
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
-+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
-+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
-+}
-+
-+static int
-+qca8k_port_lag_join(struct dsa_switch *ds, int port,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ int ret;
-+
-+ if (!qca8k_lag_can_offload(ds, lag, info))
-+ return -EOPNOTSUPP;
-+
-+ ret = qca8k_lag_setup_hash(ds, lag, info);
-+ if (ret)
-+ return ret;
-+
-+ return qca8k_lag_refresh_portmap(ds, port, lag, false);
-+}
-+
-+static int
-+qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-+ struct net_device *lag)
-+{
-+ return qca8k_lag_refresh_portmap(ds, port, lag, true);
-+}
-+
-+static void
-+qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
-+ bool operational)
-+{
-+ struct dsa_port *dp = master->dsa_ptr;
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ /* Ethernet MIB/MDIO is only supported for CPU port 0 */
-+ if (dp->index != 0)
-+ return;
-+
-+ mutex_lock(&priv->mgmt_eth_data.mutex);
-+ mutex_lock(&priv->mib_eth_data.mutex);
-+
-+ priv->mgmt_master = operational ? (struct net_device *)master : NULL;
-+
-+ mutex_unlock(&priv->mib_eth_data.mutex);
-+ mutex_unlock(&priv->mgmt_eth_data.mutex);
-+}
-+
-+static int qca8k_connect_tag_protocol(struct dsa_switch *ds,
-+ enum dsa_tag_protocol proto)
-+{
-+ struct qca_tagger_data *tagger_data;
-+
-+ switch (proto) {
-+ case DSA_TAG_PROTO_QCA:
-+ tagger_data = ds->tagger_data;
-+
-+ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler;
-+ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler;
-+
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct dsa_switch_ops qca8k_switch_ops = {
-+ .get_tag_protocol = qca8k_get_tag_protocol,
-+ .setup = qca8k_setup,
-+ .get_strings = qca8k_get_strings,
-+ .get_ethtool_stats = qca8k_get_ethtool_stats,
-+ .get_sset_count = qca8k_get_sset_count,
-+ .set_ageing_time = qca8k_set_ageing_time,
-+ .get_mac_eee = qca8k_get_mac_eee,
-+ .set_mac_eee = qca8k_set_mac_eee,
-+ .port_enable = qca8k_port_enable,
-+ .port_disable = qca8k_port_disable,
-+ .port_change_mtu = qca8k_port_change_mtu,
-+ .port_max_mtu = qca8k_port_max_mtu,
-+ .port_stp_state_set = qca8k_port_stp_state_set,
-+ .port_bridge_join = qca8k_port_bridge_join,
-+ .port_bridge_leave = qca8k_port_bridge_leave,
-+ .port_fast_age = qca8k_port_fast_age,
-+ .port_fdb_add = qca8k_port_fdb_add,
-+ .port_fdb_del = qca8k_port_fdb_del,
-+ .port_fdb_dump = qca8k_port_fdb_dump,
-+ .port_mdb_add = qca8k_port_mdb_add,
-+ .port_mdb_del = qca8k_port_mdb_del,
-+ .port_mirror_add = qca8k_port_mirror_add,
-+ .port_mirror_del = qca8k_port_mirror_del,
-+ .port_vlan_filtering = qca8k_port_vlan_filtering,
-+ .port_vlan_add = qca8k_port_vlan_add,
-+ .port_vlan_del = qca8k_port_vlan_del,
-+ .phylink_validate = qca8k_phylink_validate,
-+ .phylink_mac_link_state = qca8k_phylink_mac_link_state,
-+ .phylink_mac_config = qca8k_phylink_mac_config,
-+ .phylink_mac_link_down = qca8k_phylink_mac_link_down,
-+ .phylink_mac_link_up = qca8k_phylink_mac_link_up,
-+ .get_phy_flags = qca8k_get_phy_flags,
-+ .port_lag_join = qca8k_port_lag_join,
-+ .port_lag_leave = qca8k_port_lag_leave,
-+ .master_state_change = qca8k_master_change,
-+ .connect_tag_protocol = qca8k_connect_tag_protocol,
-+};
-+
-+static int qca8k_read_switch_id(struct qca8k_priv *priv)
-+{
-+ u32 val;
-+ u8 id;
-+ int ret;
-+
-+ if (!priv->info)
-+ return -ENODEV;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-+ if (ret < 0)
-+ return -ENODEV;
-+
-+ id = QCA8K_MASK_CTRL_DEVICE_ID(val);
-+ if (id != priv->info->id) {
-+ dev_err(priv->dev,
-+ "Switch id detected %x but expected %x",
-+ id, priv->info->id);
-+ return -ENODEV;
-+ }
-+
-+ priv->switch_id = id;
-+
-+ /* Save revision to communicate to the internal PHY driver */
-+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_sw_probe(struct mdio_device *mdiodev)
-+{
-+ struct qca8k_priv *priv;
-+ int ret;
-+
-+ /* allocate the private data struct so that we can probe the switches
-+ * ID register
-+ */
-+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->info = of_device_get_match_data(priv->dev);
-+ priv->bus = mdiodev->bus;
-+ priv->dev = &mdiodev->dev;
-+
-+ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
-+ GPIOD_ASIS);
-+ if (IS_ERR(priv->reset_gpio))
-+ return PTR_ERR(priv->reset_gpio);
-+
-+ if (priv->reset_gpio) {
-+ gpiod_set_value_cansleep(priv->reset_gpio, 1);
-+ /* The active low duration must be greater than 10 ms
-+ * and checkpatch.pl wants 20 ms.
-+ */
-+ msleep(20);
-+ gpiod_set_value_cansleep(priv->reset_gpio, 0);
-+ }
-+
-+ /* Start by setting up the register mapping */
-+ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv,
-+ &qca8k_regmap_config);
-+ if (IS_ERR(priv->regmap)) {
-+ dev_err(priv->dev, "regmap initialization failed");
-+ return PTR_ERR(priv->regmap);
-+ }
-+
-+ priv->mdio_cache.page = 0xffff;
-+ priv->mdio_cache.lo = 0xffff;
-+ priv->mdio_cache.hi = 0xffff;
-+
-+ /* Check the detected switch id */
-+ ret = qca8k_read_switch_id(priv);
-+ if (ret)
-+ return ret;
-+
-+ priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-+ if (!priv->ds)
-+ return -ENOMEM;
-+
-+ mutex_init(&priv->mgmt_eth_data.mutex);
-+ init_completion(&priv->mgmt_eth_data.rw_done);
-+
-+ mutex_init(&priv->mib_eth_data.mutex);
-+ init_completion(&priv->mib_eth_data.rw_done);
-+
-+ priv->ds->dev = &mdiodev->dev;
-+ priv->ds->num_ports = QCA8K_NUM_PORTS;
-+ priv->ds->priv = priv;
-+ priv->ds->ops = &qca8k_switch_ops;
-+ mutex_init(&priv->reg_mutex);
-+ dev_set_drvdata(&mdiodev->dev, priv);
-+
-+ return dsa_register_switch(priv->ds);
-+}
-+
-+static void
-+qca8k_sw_remove(struct mdio_device *mdiodev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+ int i;
-+
-+ if (!priv)
-+ return;
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++)
-+ qca8k_port_set_status(priv, i, 0);
-+
-+ dsa_unregister_switch(priv->ds);
-+
-+ dev_set_drvdata(&mdiodev->dev, NULL);
-+}
-+
-+static void qca8k_sw_shutdown(struct mdio_device *mdiodev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+
-+ if (!priv)
-+ return;
-+
-+ dsa_switch_shutdown(priv->ds);
-+
-+ dev_set_drvdata(&mdiodev->dev, NULL);
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static void
-+qca8k_set_pm(struct qca8k_priv *priv, int enable)
-+{
-+ int port;
-+
-+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+ /* Do not enable on resume if the port was
-+ * disabled before.
-+ */
-+ if (!(priv->port_enabled_map & BIT(port)))
-+ continue;
-+
-+ qca8k_port_set_status(priv, port, enable);
-+ }
-+}
-+
-+static int qca8k_suspend(struct device *dev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(dev);
-+
-+ qca8k_set_pm(priv, 0);
-+
-+ return dsa_switch_suspend(priv->ds);
-+}
-+
-+static int qca8k_resume(struct device *dev)
-+{
-+ struct qca8k_priv *priv = dev_get_drvdata(dev);
-+
-+ qca8k_set_pm(priv, 1);
-+
-+ return dsa_switch_resume(priv->ds);
-+}
-+#endif /* CONFIG_PM_SLEEP */
-+
-+static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-+ qca8k_suspend, qca8k_resume);
-+
-+static const struct qca8k_info_ops qca8xxx_ops = {
-+ .autocast_mib = qca8k_get_ethtool_stats_eth,
-+};
-+
-+static const struct qca8k_match_data qca8327 = {
-+ .id = QCA8K_ID_QCA8327,
-+ .reduced_package = true,
-+ .mib_count = QCA8K_QCA832X_MIB_COUNT,
-+ .ops = &qca8xxx_ops,
-+};
-+
-+static const struct qca8k_match_data qca8328 = {
-+ .id = QCA8K_ID_QCA8327,
-+ .mib_count = QCA8K_QCA832X_MIB_COUNT,
-+ .ops = &qca8xxx_ops,
-+};
-+
-+static const struct qca8k_match_data qca833x = {
-+ .id = QCA8K_ID_QCA8337,
-+ .mib_count = QCA8K_QCA833X_MIB_COUNT,
-+ .ops = &qca8xxx_ops,
-+};
-+
-+static const struct of_device_id qca8k_of_match[] = {
-+ { .compatible = "qca,qca8327", .data = &qca8327 },
-+ { .compatible = "qca,qca8328", .data = &qca8328 },
-+ { .compatible = "qca,qca8334", .data = &qca833x },
-+ { .compatible = "qca,qca8337", .data = &qca833x },
-+ { /* sentinel */ },
-+};
-+
-+static struct mdio_driver qca8kmdio_driver = {
-+ .probe = qca8k_sw_probe,
-+ .remove = qca8k_sw_remove,
-+ .shutdown = qca8k_sw_shutdown,
-+ .mdiodrv.driver = {
-+ .name = "qca8k",
-+ .of_match_table = qca8k_of_match,
-+ .pm = &qca8k_pm_ops,
-+ },
-+};
-+
-+mdio_module_driver(qca8kmdio_driver);
-+
-+MODULE_AUTHOR("Mathieu Olivari, John Crispin <john@phrozen.org>");
-+MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:qca8k");
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -0,0 +1,63 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
-+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2016 John Crispin <john@phrozen.org>
-+ */
-+
-+#include <linux/netdevice.h>
-+#include <net/dsa.h>
-+
-+#include "qca8k.h"
-+
-+#define MIB_DESC(_s, _o, _n) \
-+ { \
-+ .size = (_s), \
-+ .offset = (_o), \
-+ .name = (_n), \
-+ }
-+
-+const struct qca8k_mib_desc ar8327_mib[] = {
-+ MIB_DESC(1, 0x00, "RxBroad"),
-+ MIB_DESC(1, 0x04, "RxPause"),
-+ MIB_DESC(1, 0x08, "RxMulti"),
-+ MIB_DESC(1, 0x0c, "RxFcsErr"),
-+ MIB_DESC(1, 0x10, "RxAlignErr"),
-+ MIB_DESC(1, 0x14, "RxRunt"),
-+ MIB_DESC(1, 0x18, "RxFragment"),
-+ MIB_DESC(1, 0x1c, "Rx64Byte"),
-+ MIB_DESC(1, 0x20, "Rx128Byte"),
-+ MIB_DESC(1, 0x24, "Rx256Byte"),
-+ MIB_DESC(1, 0x28, "Rx512Byte"),
-+ MIB_DESC(1, 0x2c, "Rx1024Byte"),
-+ MIB_DESC(1, 0x30, "Rx1518Byte"),
-+ MIB_DESC(1, 0x34, "RxMaxByte"),
-+ MIB_DESC(1, 0x38, "RxTooLong"),
-+ MIB_DESC(2, 0x3c, "RxGoodByte"),
-+ MIB_DESC(2, 0x44, "RxBadByte"),
-+ MIB_DESC(1, 0x4c, "RxOverFlow"),
-+ MIB_DESC(1, 0x50, "Filtered"),
-+ MIB_DESC(1, 0x54, "TxBroad"),
-+ MIB_DESC(1, 0x58, "TxPause"),
-+ MIB_DESC(1, 0x5c, "TxMulti"),
-+ MIB_DESC(1, 0x60, "TxUnderRun"),
-+ MIB_DESC(1, 0x64, "Tx64Byte"),
-+ MIB_DESC(1, 0x68, "Tx128Byte"),
-+ MIB_DESC(1, 0x6c, "Tx256Byte"),
-+ MIB_DESC(1, 0x70, "Tx512Byte"),
-+ MIB_DESC(1, 0x74, "Tx1024Byte"),
-+ MIB_DESC(1, 0x78, "Tx1518Byte"),
-+ MIB_DESC(1, 0x7c, "TxMaxByte"),
-+ MIB_DESC(1, 0x80, "TxOverSize"),
-+ MIB_DESC(2, 0x84, "TxByte"),
-+ MIB_DESC(1, 0x8c, "TxCollision"),
-+ MIB_DESC(1, 0x90, "TxAbortCol"),
-+ MIB_DESC(1, 0x94, "TxMultiCol"),
-+ MIB_DESC(1, 0x98, "TxSingleCol"),
-+ MIB_DESC(1, 0x9c, "TxExcDefer"),
-+ MIB_DESC(1, 0xa0, "TxDefer"),
-+ MIB_DESC(1, 0xa4, "TxLateCol"),
-+ MIB_DESC(1, 0xa8, "RXUnicast"),
-+ MIB_DESC(1, 0xac, "TXUnicast"),
-+};
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -414,4 +414,7 @@ struct qca8k_fdb {
- u8 mac[6];
- };
-
-+/* Common setup function */
-+extern const struct qca8k_mib_desc ar8327_mib[];
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch b/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch
deleted file mode 100644
index 012ab85474..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From d5f901eab2e9dfed1095995dfc98f231f4fd2971 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:13 +0200
-Subject: [PATCH 04/14] net: dsa: qca8k: move qca8k read/write/rmw and reg
- table to common code
-
-The same reg table and read/write/rmw function are used by drivers
-based on qca8k family switch.
-Move them to common code to make it accessible also by other drivers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 42 ------------------------------
- drivers/net/dsa/qca/qca8k-common.c | 38 +++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 6 +++++
- 3 files changed, 44 insertions(+), 42 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -133,24 +133,6 @@ qca8k_set_page(struct qca8k_priv *priv,
- return 0;
- }
-
--static int
--qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
--{
-- return regmap_read(priv->regmap, reg, val);
--}
--
--static int
--qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
--{
-- return regmap_write(priv->regmap, reg, val);
--}
--
--static int
--qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
--{
-- return regmap_update_bits(priv->regmap, reg, mask, write_val);
--}
--
- static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
- {
- struct qca8k_mgmt_eth_data *mgmt_eth_data;
-@@ -483,30 +465,6 @@ exit:
- return ret;
- }
-
--static const struct regmap_range qca8k_readable_ranges[] = {
-- regmap_reg_range(0x0000, 0x00e4), /* Global control */
-- regmap_reg_range(0x0100, 0x0168), /* EEE control */
-- regmap_reg_range(0x0200, 0x0270), /* Parser control */
-- regmap_reg_range(0x0400, 0x0454), /* ACL */
-- regmap_reg_range(0x0600, 0x0718), /* Lookup */
-- regmap_reg_range(0x0800, 0x0b70), /* QM */
-- regmap_reg_range(0x0c00, 0x0c80), /* PKT */
-- regmap_reg_range(0x0e00, 0x0e98), /* L3 */
-- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
--
--};
--
--static const struct regmap_access_table qca8k_readable_table = {
-- .yes_ranges = qca8k_readable_ranges,
-- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
--};
--
- static struct regmap_config qca8k_regmap_config = {
- .reg_bits = 16,
- .val_bits = 32,
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -61,3 +61,41 @@ const struct qca8k_mib_desc ar8327_mib[]
- MIB_DESC(1, 0xa8, "RXUnicast"),
- MIB_DESC(1, 0xac, "TXUnicast"),
- };
-+
-+int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
-+{
-+ return regmap_read(priv->regmap, reg, val);
-+}
-+
-+int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
-+{
-+ return regmap_write(priv->regmap, reg, val);
-+}
-+
-+int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
-+{
-+ return regmap_update_bits(priv->regmap, reg, mask, write_val);
-+}
-+
-+static const struct regmap_range qca8k_readable_ranges[] = {
-+ regmap_reg_range(0x0000, 0x00e4), /* Global control */
-+ regmap_reg_range(0x0100, 0x0168), /* EEE control */
-+ regmap_reg_range(0x0200, 0x0270), /* Parser control */
-+ regmap_reg_range(0x0400, 0x0454), /* ACL */
-+ regmap_reg_range(0x0600, 0x0718), /* Lookup */
-+ regmap_reg_range(0x0800, 0x0b70), /* QM */
-+ regmap_reg_range(0x0c00, 0x0c80), /* PKT */
-+ regmap_reg_range(0x0e00, 0x0e98), /* L3 */
-+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
-+};
-+
-+const struct regmap_access_table qca8k_readable_table = {
-+ .yes_ranges = qca8k_readable_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
-+};
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -416,5 +416,11 @@ struct qca8k_fdb {
-
- /* Common setup function */
- extern const struct qca8k_mib_desc ar8327_mib[];
-+extern const struct regmap_access_table qca8k_readable_table;
-+
-+/* Common read/write/rmw function */
-+int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val);
-+int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val);
-+int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val);
-
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch b/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch
deleted file mode 100644
index 0ed7ed41fb..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 910746444313dc463396cd63024cdf54ef04ef39 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:14 +0200
-Subject: [PATCH 05/14] net: dsa: qca8k: move qca8k bulk read/write helper to
- common code
-
-The same ATU function are used by drivers based on qca8k family switch.
-Move the bulk read/write helper to common code to declare these shared
-ATU functions in common code.
-These helper will be dropped when regmap correctly support bulk
-read/write.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 39 ++----------------------------
- drivers/net/dsa/qca/qca8k-common.c | 39 ++++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 8 ++++++
- 3 files changed, 49 insertions(+), 37 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -343,43 +343,6 @@ qca8k_regmap_update_bits_eth(struct qca8
- }
-
- static int
--qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
--
-- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
-- u32 tmp;
--
-- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- tmp = val[i];
--
-- ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--static int
- qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-@@ -3096,6 +3059,8 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-
- static const struct qca8k_info_ops qca8xxx_ops = {
- .autocast_mib = qca8k_get_ethtool_stats_eth,
-+ .read_eth = qca8k_read_eth,
-+ .write_eth = qca8k_write_eth,
- };
-
- static const struct qca8k_match_data qca8327 = {
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -99,3 +99,42 @@ const struct regmap_access_table qca8k_r
- .yes_ranges = qca8k_readable_ranges,
- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
- };
-+
-+/* TODO: remove these extra ops when we can support regmap bulk read/write */
-+int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+
-+ if (priv->mgmt_master && priv->info->ops->read_eth &&
-+ !priv->info->ops->read_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* TODO: remove these extra ops when we can support regmap bulk read/write */
-+int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+{
-+ int i, count = len / sizeof(u32), ret;
-+ u32 tmp;
-+
-+ if (priv->mgmt_master && priv->info->ops->write_eth &&
-+ !priv->info->ops->write_eth(priv, reg, val, len))
-+ return 0;
-+
-+ for (i = 0; i < count; i++) {
-+ tmp = val[i];
-+
-+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -324,8 +324,13 @@ enum qca8k_mid_cmd {
- QCA8K_MIB_CAST = 3,
- };
-
-+struct qca8k_priv;
-+
- struct qca8k_info_ops {
- int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data);
-+ /* TODO: remove these extra ops when we can support regmap bulk read/write */
-+ int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
-+ int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
- };
-
- struct qca8k_match_data {
-@@ -423,4 +428,7 @@ int qca8k_read(struct qca8k_priv *priv,
- int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val);
- int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val);
-
-+int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
-+int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch
deleted file mode 100644
index a39a55b89b..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch
+++ /dev/null
@@ -1,137 +0,0 @@
-From fce1ec0c4e2d03d9c62ffc615a42bdba78eb4c14 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:15 +0200
-Subject: [PATCH 06/14] net: dsa: qca8k: move mib init function to common code
-
-The same mib function is used by drivers based on qca8k family switch.
-Move it to common code to make it accessible also by other drivers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 37 ------------------------------
- drivers/net/dsa/qca/qca8k-common.c | 35 ++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 4 ++++
- 3 files changed, 39 insertions(+), 37 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -442,15 +442,6 @@ static struct regmap_config qca8k_regmap
- };
-
- static int
--qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
--{
-- u32 val;
--
-- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
-- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
--}
--
--static int
- qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
- {
- u32 reg[3];
-@@ -777,34 +768,6 @@ out:
- return ret;
- }
-
--static int
--qca8k_mib_init(struct qca8k_priv *priv)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
-- QCA8K_MIB_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-- if (ret)
-- goto exit;
--
-- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-- if (ret)
-- goto exit;
--
-- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
- static void
- qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
- {
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -7,6 +7,7 @@
- */
-
- #include <linux/netdevice.h>
-+#include <linux/bitfield.h>
- #include <net/dsa.h>
-
- #include "qca8k.h"
-@@ -138,3 +139,38 @@ int qca8k_bulk_write(struct qca8k_priv *
-
- return 0;
- }
-+
-+int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
-+{
-+ u32 val;
-+
-+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
-+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
-+}
-+
-+int qca8k_mib_init(struct qca8k_priv *priv)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
-+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
-+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
-+ QCA8K_MIB_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-+ if (ret)
-+ goto exit;
-+
-+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-+ if (ret)
-+ goto exit;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -422,6 +422,7 @@ struct qca8k_fdb {
- /* Common setup function */
- extern const struct qca8k_mib_desc ar8327_mib[];
- extern const struct regmap_access_table qca8k_readable_table;
-+int qca8k_mib_init(struct qca8k_priv *priv);
-
- /* Common read/write/rmw function */
- int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val);
-@@ -431,4 +432,7 @@ int qca8k_rmw(struct qca8k_priv *priv, u
- int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
- int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
-
-+/* Common ops function */
-+int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch b/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch
deleted file mode 100644
index 6fd1c66b0a..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch
+++ /dev/null
@@ -1,281 +0,0 @@
-From 472fcea160f27a5d9b7526093d9d8d89ba0b6137 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:16 +0200
-Subject: [PATCH 07/14] net: dsa: qca8k: move port set status/eee/ethtool stats
- function to common code
-
-The same logic to disable/enable port, set eee and get ethtool stats is
-used by drivers based on qca8k family switch.
-Move it to common code to make it accessible also by other drivers.
-While at it also drop unnecessary qca8k_priv cast for void pointers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 105 -----------------------------
- drivers/net/dsa/qca/qca8k-common.c | 102 ++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 11 +++
- 3 files changed, 113 insertions(+), 105 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -768,21 +768,6 @@ out:
- return ret;
- }
-
--static void
--qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
--{
-- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
--
-- /* Port 0 and 6 have no internal PHY */
-- if (port > 0 && port < 6)
-- mask |= QCA8K_PORT_STATUS_LINK_AUTO;
--
-- if (enable)
-- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-- else
-- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
--}
--
- static int
- qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
- struct sk_buff *read_skb, u32 *val)
-@@ -1974,20 +1959,6 @@ qca8k_phylink_mac_link_up(struct dsa_swi
- qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
- }
-
--static void
--qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int i;
--
-- if (stringset != ETH_SS_STATS)
-- return;
--
-- for (i = 0; i < priv->info->mib_count; i++)
-- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-- ETH_GSTRING_LEN);
--}
--
- static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
- {
- struct qca8k_mib_eth_data *mib_eth_data;
-@@ -2078,82 +2049,6 @@ exit:
- }
-
- static void
--qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
-- uint64_t *data)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- const struct qca8k_mib_desc *mib;
-- u32 reg, i, val;
-- u32 hi = 0;
-- int ret;
--
-- if (priv->mgmt_master && priv->info->ops->autocast_mib &&
-- priv->info->ops->autocast_mib(ds, port, data) > 0)
-- return;
--
-- for (i = 0; i < priv->info->mib_count; i++) {
-- mib = &ar8327_mib[i];
-- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
--
-- ret = qca8k_read(priv, reg, &val);
-- if (ret < 0)
-- continue;
--
-- if (mib->size == 2) {
-- ret = qca8k_read(priv, reg + 4, &hi);
-- if (ret < 0)
-- continue;
-- }
--
-- data[i] = val;
-- if (mib->size == 2)
-- data[i] |= (u64)hi << 32;
-- }
--}
--
--static int
--qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- if (sset != ETH_SS_STATS)
-- return 0;
--
-- return priv->info->mib_count;
--}
--
--static int
--qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
-- u32 reg;
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
-- if (ret < 0)
-- goto exit;
--
-- if (eee->eee_enabled)
-- reg |= lpi_en;
-- else
-- reg &= ~lpi_en;
-- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
--{
-- /* Nothing to do on the port's MAC */
-- return 0;
--}
--
--static void
- qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -174,3 +174,105 @@ exit:
- mutex_unlock(&priv->reg_mutex);
- return ret;
- }
-+
-+void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
-+{
-+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
-+
-+ /* Port 0 and 6 have no internal PHY */
-+ if (port > 0 && port < 6)
-+ mask |= QCA8K_PORT_STATUS_LINK_AUTO;
-+
-+ if (enable)
-+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-+ else
-+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
-+}
-+
-+void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset,
-+ uint8_t *data)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int i;
-+
-+ if (stringset != ETH_SS_STATS)
-+ return;
-+
-+ for (i = 0; i < priv->info->mib_count; i++)
-+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-+ ETH_GSTRING_LEN);
-+}
-+
-+void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
-+ uint64_t *data)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const struct qca8k_mib_desc *mib;
-+ u32 reg, i, val;
-+ u32 hi = 0;
-+ int ret;
-+
-+ if (priv->mgmt_master && priv->info->ops->autocast_mib &&
-+ priv->info->ops->autocast_mib(ds, port, data) > 0)
-+ return;
-+
-+ for (i = 0; i < priv->info->mib_count; i++) {
-+ mib = &ar8327_mib[i];
-+ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
-+
-+ ret = qca8k_read(priv, reg, &val);
-+ if (ret < 0)
-+ continue;
-+
-+ if (mib->size == 2) {
-+ ret = qca8k_read(priv, reg + 4, &hi);
-+ if (ret < 0)
-+ continue;
-+ }
-+
-+ data[i] = val;
-+ if (mib->size == 2)
-+ data[i] |= (u64)hi << 32;
-+ }
-+}
-+
-+int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ if (sset != ETH_SS_STATS)
-+ return 0;
-+
-+ return priv->info->mib_count;
-+}
-+
-+int qca8k_set_mac_eee(struct dsa_switch *ds, int port,
-+ struct ethtool_eee *eee)
-+{
-+ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg;
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
-+ if (ret < 0)
-+ goto exit;
-+
-+ if (eee->eee_enabled)
-+ reg |= lpi_en;
-+ else
-+ reg &= ~lpi_en;
-+ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
-+ struct ethtool_eee *e)
-+{
-+ /* Nothing to do on the port's MAC */
-+ return 0;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -423,6 +423,7 @@ struct qca8k_fdb {
- extern const struct qca8k_mib_desc ar8327_mib[];
- extern const struct regmap_access_table qca8k_readable_table;
- int qca8k_mib_init(struct qca8k_priv *priv);
-+void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable);
-
- /* Common read/write/rmw function */
- int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val);
-@@ -435,4 +436,14 @@ int qca8k_bulk_write(struct qca8k_priv *
- /* Common ops function */
- int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
-
-+/* Common ethtool stats function */
-+void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data);
-+void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
-+ uint64_t *data);
-+int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset);
-+
-+/* Common eee function */
-+int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee);
-+int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch
deleted file mode 100644
index 3ca682d72c..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch
+++ /dev/null
@@ -1,237 +0,0 @@
-From fd3cae2f3ac190d06e48f43739237e02f9dc51ff Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:17 +0200
-Subject: [PATCH 08/14] net: dsa: qca8k: move bridge functions to common code
-
-The same bridge functions are used by drivers based on qca8k family
-switch. Move them to common code to make them accessible also by other
-drivers.
-While at it also drop unnecessary qca8k_priv cast for void pointers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------
- drivers/net/dsa/qca/qca8k-common.c | 93 ++++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 9 +++
- 3 files changed, 102 insertions(+), 93 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -2049,97 +2049,6 @@ exit:
- }
-
- static void
--qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u32 stp_state;
--
-- switch (state) {
-- case BR_STATE_DISABLED:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
-- break;
-- case BR_STATE_BLOCKING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
-- break;
-- case BR_STATE_LISTENING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
-- break;
-- case BR_STATE_LEARNING:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
-- break;
-- case BR_STATE_FORWARDING:
-- default:
-- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
-- break;
-- }
--
-- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
--}
--
--static int
--qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int port_mask, cpu_port;
-- int i, ret;
--
-- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-- port_mask = BIT(cpu_port);
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- if (dsa_is_cpu_port(ds, i))
-- continue;
-- if (dsa_to_port(ds, i)->bridge_dev != br)
-- continue;
-- /* Add this port to the portvlan mask of the other ports
-- * in the bridge
-- */
-- ret = regmap_set_bits(priv->regmap,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-- if (ret)
-- return ret;
-- if (i != port)
-- port_mask |= BIT(i);
-- }
--
-- /* Add all other ports to this ports portvlan mask */
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_MEMBER, port_mask);
--
-- return ret;
--}
--
--static void
--qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int cpu_port, i;
--
-- cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
--
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- if (dsa_is_cpu_port(ds, i))
-- continue;
-- if (dsa_to_port(ds, i)->bridge_dev != br)
-- continue;
-- /* Remove this port to the portvlan mask of the other ports
-- * in the bridge
-- */
-- regmap_clear_bits(priv->regmap,
-- QCA8K_PORT_LOOKUP_CTRL(i),
-- BIT(port));
-- }
--
-- /* Set the cpu port to be the only one in the portvlan mask of
-- * this port
-- */
-- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
--}
--
--static void
- qca8k_port_fast_age(struct dsa_switch *ds, int port)
- {
- struct qca8k_priv *priv = ds->priv;
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -9,6 +9,7 @@
- #include <linux/netdevice.h>
- #include <linux/bitfield.h>
- #include <net/dsa.h>
-+#include <linux/if_bridge.h>
-
- #include "qca8k.h"
-
-@@ -276,3 +277,93 @@ int qca8k_get_mac_eee(struct dsa_switch
- /* Nothing to do on the port's MAC */
- return 0;
- }
-+
-+void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 stp_state;
-+
-+ switch (state) {
-+ case BR_STATE_DISABLED:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
-+ break;
-+ case BR_STATE_BLOCKING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
-+ break;
-+ case BR_STATE_LISTENING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
-+ break;
-+ case BR_STATE_LEARNING:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
-+ break;
-+ case BR_STATE_FORWARDING:
-+ default:
-+ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
-+ break;
-+ }
-+
-+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
-+}
-+
-+int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
-+ struct net_device *br)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int port_mask, cpu_port;
-+ int i, ret;
-+
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+ port_mask = BIT(cpu_port);
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
-+ if (dsa_to_port(ds, i)->bridge_dev != br)
-+ continue;
-+ /* Add this port to the portvlan mask of the other ports
-+ * in the bridge
-+ */
-+ ret = regmap_set_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
-+ if (ret)
-+ return ret;
-+ if (i != port)
-+ port_mask |= BIT(i);
-+ }
-+
-+ /* Add all other ports to this ports portvlan mask */
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER, port_mask);
-+
-+ return ret;
-+}
-+
-+void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
-+ struct net_device *br)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int cpu_port, i;
-+
-+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ if (dsa_is_cpu_port(ds, i))
-+ continue;
-+ if (dsa_to_port(ds, i)->bridge_dev != br)
-+ continue;
-+ /* Remove this port to the portvlan mask of the other ports
-+ * in the bridge
-+ */
-+ regmap_clear_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(i),
-+ BIT(port));
-+ }
-+
-+ /* Set the cpu port to be the only one in the portvlan mask of
-+ * this port
-+ */
-+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -446,4 +446,11 @@ int qca8k_get_sset_count(struct dsa_swit
- int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee);
- int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
-
-+/* Common bridge function */
-+void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
-+int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
-+ struct net_device *br);
-+void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
-+ struct net_device *br);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch b/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch
deleted file mode 100644
index e3414408d6..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-From b3a302b171f73425b41de8d3357fae3fa7057322 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:18 +0200
-Subject: [PATCH 09/14] net: dsa: qca8k: move set age/MTU/port enable/disable
- functions to common code
-
-The same set age, MTU and port enable/disable function are used by
-driver based on qca8k family switch.
-Move them to common code to make them accessible also by other drivers.
-While at it also drop unnecessary qca8k_priv cast for void pointers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 88 ------------------------------
- drivers/net/dsa/qca/qca8k-common.c | 85 +++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 12 ++++
- 3 files changed, 97 insertions(+), 88 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -2059,94 +2059,6 @@ qca8k_port_fast_age(struct dsa_switch *d
- }
-
- static int
--qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
--{
-- struct qca8k_priv *priv = ds->priv;
-- unsigned int secs = msecs / 1000;
-- u32 val;
--
-- /* AGE_TIME reg is set in 7s step */
-- val = secs / 7;
--
-- /* Handle case with 0 as val to NOT disable
-- * learning
-- */
-- if (!val)
-- val = 1;
--
-- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
-- QCA8K_ATU_AGE_TIME(val));
--}
--
--static int
--qca8k_port_enable(struct dsa_switch *ds, int port,
-- struct phy_device *phy)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--
-- qca8k_port_set_status(priv, port, 1);
-- priv->port_enabled_map |= BIT(port);
--
-- if (dsa_is_user_port(ds, port))
-- phy_support_asym_pause(phy);
--
-- return 0;
--}
--
--static void
--qca8k_port_disable(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--
-- qca8k_port_set_status(priv, port, 0);
-- priv->port_enabled_map &= ~BIT(port);
--}
--
--static int
--qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- /* We have only have a general MTU setting.
-- * DSA always set the CPU port's MTU to the largest MTU of the slave
-- * ports.
-- * Setting MTU just for the CPU port is sufficient to correctly set a
-- * value for every port.
-- */
-- if (!dsa_is_cpu_port(ds, port))
-- return 0;
--
-- /* To change the MAX_FRAME_SIZE the cpu ports must be off or
-- * the switch panics.
-- * Turn off both cpu ports before applying the new value to prevent
-- * this.
-- */
-- if (priv->port_enabled_map & BIT(0))
-- qca8k_port_set_status(priv, 0, 0);
--
-- if (priv->port_enabled_map & BIT(6))
-- qca8k_port_set_status(priv, 6, 0);
--
-- /* Include L2 header / FCS length */
-- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
--
-- if (priv->port_enabled_map & BIT(0))
-- qca8k_port_set_status(priv, 0, 1);
--
-- if (priv->port_enabled_map & BIT(6))
-- qca8k_port_set_status(priv, 6, 1);
--
-- return ret;
--}
--
--static int
--qca8k_port_max_mtu(struct dsa_switch *ds, int port)
--{
-- return QCA8K_MAX_MTU;
--}
--
--static int
- qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
- u16 port_mask, u16 vid)
- {
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -367,3 +367,88 @@ void qca8k_port_bridge_leave(struct dsa_
- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
- }
-+
-+int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ unsigned int secs = msecs / 1000;
-+ u32 val;
-+
-+ /* AGE_TIME reg is set in 7s step */
-+ val = secs / 7;
-+
-+ /* Handle case with 0 as val to NOT disable
-+ * learning
-+ */
-+ if (!val)
-+ val = 1;
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL,
-+ QCA8K_ATU_AGE_TIME_MASK,
-+ QCA8K_ATU_AGE_TIME(val));
-+}
-+
-+int qca8k_port_enable(struct dsa_switch *ds, int port,
-+ struct phy_device *phy)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 1);
-+ priv->port_enabled_map |= BIT(port);
-+
-+ if (dsa_is_user_port(ds, port))
-+ phy_support_asym_pause(phy);
-+
-+ return 0;
-+}
-+
-+void qca8k_port_disable(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ qca8k_port_set_status(priv, port, 0);
-+ priv->port_enabled_map &= ~BIT(port);
-+}
-+
-+int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ /* We have only have a general MTU setting.
-+ * DSA always set the CPU port's MTU to the largest MTU of the slave
-+ * ports.
-+ * Setting MTU just for the CPU port is sufficient to correctly set a
-+ * value for every port.
-+ */
-+ if (!dsa_is_cpu_port(ds, port))
-+ return 0;
-+
-+ /* To change the MAX_FRAME_SIZE the cpu ports must be off or
-+ * the switch panics.
-+ * Turn off both cpu ports before applying the new value to prevent
-+ * this.
-+ */
-+ if (priv->port_enabled_map & BIT(0))
-+ qca8k_port_set_status(priv, 0, 0);
-+
-+ if (priv->port_enabled_map & BIT(6))
-+ qca8k_port_set_status(priv, 6, 0);
-+
-+ /* Include L2 header / FCS length */
-+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu +
-+ ETH_HLEN + ETH_FCS_LEN);
-+
-+ if (priv->port_enabled_map & BIT(0))
-+ qca8k_port_set_status(priv, 0, 1);
-+
-+ if (priv->port_enabled_map & BIT(6))
-+ qca8k_port_set_status(priv, 6, 1);
-+
-+ return ret;
-+}
-+
-+int qca8k_port_max_mtu(struct dsa_switch *ds, int port)
-+{
-+ return QCA8K_MAX_MTU;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -453,4 +453,16 @@ int qca8k_port_bridge_join(struct dsa_sw
- void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
- struct net_device *br);
-
-+/* Common port enable/disable function */
-+int qca8k_port_enable(struct dsa_switch *ds, int port,
-+ struct phy_device *phy);
-+void qca8k_port_disable(struct dsa_switch *ds, int port);
-+
-+/* Common MTU function */
-+int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu);
-+int qca8k_port_max_mtu(struct dsa_switch *ds, int port);
-+
-+/* Common fast age function */
-+int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch b/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch
deleted file mode 100644
index 96468ae74e..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch
+++ /dev/null
@@ -1,704 +0,0 @@
-From 2e5bd96eea86a246b4de3bf756f7a11b43e6187d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:19 +0200
-Subject: [PATCH 10/14] net: dsa: qca8k: move port FDB/MDB function to common
- code
-
-The same port FDB/MDB function are used by drivers based on qca8k family
-switch. Move them to common code to make them accessible also by other
-drivers.
-Also drop bulk read/write functions and make them static
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 306 -----------------------------
- drivers/net/dsa/qca/qca8k-common.c | 297 +++++++++++++++++++++++++++-
- drivers/net/dsa/qca/qca8k.h | 25 ++-
- 3 files changed, 317 insertions(+), 311 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -442,217 +442,6 @@ static struct regmap_config qca8k_regmap
- };
-
- static int
--qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
--{
-- u32 reg[3];
-- int ret;
--
-- /* load the ARL table into an array */
-- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-- if (ret)
-- return ret;
--
-- /* vid - 83:72 */
-- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
-- /* aging - 67:64 */
-- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
-- /* portmask - 54:48 */
-- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
-- /* mac - 47:0 */
-- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
-- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
-- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
-- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
-- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
-- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
--
-- return 0;
--}
--
--static void
--qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac,
-- u8 aging)
--{
-- u32 reg[3] = { 0 };
--
-- /* vid - 83:72 */
-- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-- /* aging - 67:64 */
-- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
-- /* portmask - 54:48 */
-- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
-- /* mac - 47:0 */
-- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
-- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
-- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
--
-- /* load the array into the ARL table */
-- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
--}
--
--static int
--qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
--{
-- u32 reg;
-- int ret;
--
-- /* Set the command and FDB index */
-- reg = QCA8K_ATU_FUNC_BUSY;
-- reg |= cmd;
-- if (port >= 0) {
-- reg |= QCA8K_ATU_FUNC_PORT_EN;
-- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
-- }
--
-- /* Write the function register triggering the table access */
-- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-- if (ret)
-- return ret;
--
-- /* wait for completion */
-- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
-- if (ret)
-- return ret;
--
-- /* Check for table full violation when adding an entry */
-- if (cmd == QCA8K_FDB_LOAD) {
-- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
-- if (ret < 0)
-- return ret;
-- if (reg & QCA8K_ATU_FUNC_FULL)
-- return -1;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port)
--{
-- int ret;
--
-- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
-- if (ret < 0)
-- return ret;
--
-- return qca8k_fdb_read(priv, fdb);
--}
--
--static int
--qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask,
-- u16 vid, u8 aging)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_write(priv, vid, port_mask, mac, aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid)
--{
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_write(priv, vid, port_mask, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static void
--qca8k_fdb_flush(struct qca8k_priv *priv)
--{
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
-- mutex_unlock(&priv->reg_mutex);
--}
--
--static int
--qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
-- const u8 *mac, u16 vid)
--{
-- struct qca8k_fdb fdb = { 0 };
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
--
-- qca8k_fdb_write(priv, vid, 0, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-- if (ret < 0)
-- goto exit;
--
-- ret = qca8k_fdb_read(priv, &fdb);
-- if (ret < 0)
-- goto exit;
--
-- /* Rule exist. Delete first */
-- if (!fdb.aging) {
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- if (ret)
-- goto exit;
-- }
--
-- /* Add port to fdb portmask */
-- fdb.port_mask |= port_mask;
--
-- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
--qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
-- const u8 *mac, u16 vid)
--{
-- struct qca8k_fdb fdb = { 0 };
-- int ret;
--
-- mutex_lock(&priv->reg_mutex);
--
-- qca8k_fdb_write(priv, vid, 0, mac, 0);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-- if (ret < 0)
-- goto exit;
--
-- /* Rule doesn't exist. Why delete? */
-- if (!fdb.aging) {
-- ret = -EINVAL;
-- goto exit;
-- }
--
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-- if (ret)
-- goto exit;
--
-- /* Only port in the rule is this port. Don't re insert */
-- if (fdb.port_mask == port_mask)
-- goto exit;
--
-- /* Remove port from port mask */
-- fdb.port_mask &= ~port_mask;
--
-- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
--
--exit:
-- mutex_unlock(&priv->reg_mutex);
-- return ret;
--}
--
--static int
- qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
- {
- u32 reg;
-@@ -2048,97 +1837,6 @@ exit:
- return ret;
- }
-
--static void
--qca8k_port_fast_age(struct dsa_switch *ds, int port)
--{
-- struct qca8k_priv *priv = ds->priv;
--
-- mutex_lock(&priv->reg_mutex);
-- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
-- mutex_unlock(&priv->reg_mutex);
--}
--
--static int
--qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
-- u16 port_mask, u16 vid)
--{
-- /* Set the vid to the port vlan id if no vid is set */
-- if (!vid)
-- vid = QCA8K_PORT_VID_DEF;
--
-- return qca8k_fdb_add(priv, addr, port_mask, vid,
-- QCA8K_ATU_STATUS_STATIC);
--}
--
--static int
--qca8k_port_fdb_add(struct dsa_switch *ds, int port,
-- const unsigned char *addr, u16 vid)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u16 port_mask = BIT(port);
--
-- return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
--}
--
--static int
--qca8k_port_fdb_del(struct dsa_switch *ds, int port,
-- const unsigned char *addr, u16 vid)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- u16 port_mask = BIT(port);
--
-- if (!vid)
-- vid = QCA8K_PORT_VID_DEF;
--
-- return qca8k_fdb_del(priv, addr, port_mask, vid);
--}
--
--static int
--qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
-- dsa_fdb_dump_cb_t *cb, void *data)
--{
-- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- struct qca8k_fdb _fdb = { 0 };
-- int cnt = QCA8K_NUM_FDB_RECORDS;
-- bool is_static;
-- int ret = 0;
--
-- mutex_lock(&priv->reg_mutex);
-- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
-- if (!_fdb.aging)
-- break;
-- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
-- ret = cb(_fdb.mac, _fdb.vid, is_static, data);
-- if (ret)
-- break;
-- }
-- mutex_unlock(&priv->reg_mutex);
--
-- return 0;
--}
--
--static int
--qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_mdb *mdb)
--{
-- struct qca8k_priv *priv = ds->priv;
-- const u8 *addr = mdb->addr;
-- u16 vid = mdb->vid;
--
-- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
--}
--
--static int
--qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_mdb *mdb)
--{
-- struct qca8k_priv *priv = ds->priv;
-- const u8 *addr = mdb->addr;
-- u16 vid = mdb->vid;
--
-- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
--}
--
- static int
- qca8k_port_mirror_add(struct dsa_switch *ds, int port,
- struct dsa_mall_mirror_tc_entry *mirror,
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -103,7 +103,7 @@ const struct regmap_access_table qca8k_r
- };
-
- /* TODO: remove these extra ops when we can support regmap bulk read/write */
--int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
- {
- int i, count = len / sizeof(u32), ret;
-
-@@ -121,7 +121,7 @@ int qca8k_bulk_read(struct qca8k_priv *p
- }
-
- /* TODO: remove these extra ops when we can support regmap bulk read/write */
--int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
-+static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
- {
- int i, count = len / sizeof(u32), ret;
- u32 tmp;
-@@ -149,6 +149,211 @@ int qca8k_busy_wait(struct qca8k_priv *p
- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
- }
-
-+static int qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
-+{
-+ u32 reg[3];
-+ int ret;
-+
-+ /* load the ARL table into an array */
-+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+ if (ret)
-+ return ret;
-+
-+ /* vid - 83:72 */
-+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
-+ /* aging - 67:64 */
-+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
-+ /* portmask - 54:48 */
-+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
-+ /* mac - 47:0 */
-+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
-+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
-+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
-+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
-+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
-+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
-+
-+ return 0;
-+}
-+
-+static void qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask,
-+ const u8 *mac, u8 aging)
-+{
-+ u32 reg[3] = { 0 };
-+
-+ /* vid - 83:72 */
-+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-+ /* aging - 67:64 */
-+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
-+ /* portmask - 54:48 */
-+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
-+ /* mac - 47:0 */
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
-+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
-+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
-+
-+ /* load the array into the ARL table */
-+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+}
-+
-+static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
-+ int port)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /* Set the command and FDB index */
-+ reg = QCA8K_ATU_FUNC_BUSY;
-+ reg |= cmd;
-+ if (port >= 0) {
-+ reg |= QCA8K_ATU_FUNC_PORT_EN;
-+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
-+ }
-+
-+ /* Write the function register triggering the table access */
-+ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-+ if (ret)
-+ return ret;
-+
-+ /* wait for completion */
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
-+ if (ret)
-+ return ret;
-+
-+ /* Check for table full violation when adding an entry */
-+ if (cmd == QCA8K_FDB_LOAD) {
-+ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
-+ if (ret < 0)
-+ return ret;
-+ if (reg & QCA8K_ATU_FUNC_FULL)
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb,
-+ int port)
-+{
-+ int ret;
-+
-+ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
-+ if (ret < 0)
-+ return ret;
-+
-+ return qca8k_fdb_read(priv, fdb);
-+}
-+
-+static int qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac,
-+ u16 port_mask, u16 vid, u8 aging)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_write(priv, vid, port_mask, mac, aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac,
-+ u16 port_mask, u16 vid)
-+{
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_write(priv, vid, port_mask, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+void qca8k_fdb_flush(struct qca8k_priv *priv)
-+{
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ ret = qca8k_fdb_read(priv, &fdb);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule exist. Delete first */
-+ if (!fdb.aging) {
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+ }
-+
-+ /* Add port to fdb portmask */
-+ fdb.port_mask |= port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
-+static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
-+ const u8 *mac, u16 vid)
-+{
-+ struct qca8k_fdb fdb = { 0 };
-+ int ret;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ qca8k_fdb_write(priv, vid, 0, mac, 0);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* Rule doesn't exist. Why delete? */
-+ if (!fdb.aging) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
-+ if (ret)
-+ goto exit;
-+
-+ /* Only port in the rule is this port. Don't re insert */
-+ if (fdb.port_mask == port_mask)
-+ goto exit;
-+
-+ /* Remove port from port mask */
-+ fdb.port_mask &= ~port_mask;
-+
-+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
-+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
-+
-+exit:
-+ mutex_unlock(&priv->reg_mutex);
-+ return ret;
-+}
-+
- int qca8k_mib_init(struct qca8k_priv *priv)
- {
- int ret;
-@@ -368,6 +573,15 @@ void qca8k_port_bridge_leave(struct dsa_
- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
- }
-
-+void qca8k_port_fast_age(struct dsa_switch *ds, int port)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
- int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
- {
- struct qca8k_priv *priv = ds->priv;
-@@ -452,3 +666,78 @@ int qca8k_port_max_mtu(struct dsa_switch
- {
- return QCA8K_MAX_MTU;
- }
-+
-+int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
-+ u16 port_mask, u16 vid)
-+{
-+ /* Set the vid to the port vlan id if no vid is set */
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ return qca8k_fdb_add(priv, addr, port_mask, vid,
-+ QCA8K_ATU_STATUS_STATIC);
-+}
-+
-+int qca8k_port_fdb_add(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u16 port_mask = BIT(port);
-+
-+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
-+}
-+
-+int qca8k_port_fdb_del(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ u16 port_mask = BIT(port);
-+
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ return qca8k_fdb_del(priv, addr, port_mask, vid);
-+}
-+
-+int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
-+ dsa_fdb_dump_cb_t *cb, void *data)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ struct qca8k_fdb _fdb = { 0 };
-+ int cnt = QCA8K_NUM_FDB_RECORDS;
-+ bool is_static;
-+ int ret = 0;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
-+ if (!_fdb.aging)
-+ break;
-+ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
-+ ret = cb(_fdb.mac, _fdb.vid, is_static, data);
-+ if (ret)
-+ break;
-+ }
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return 0;
-+}
-+
-+int qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
-+}
-+
-+int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ const u8 *addr = mdb->addr;
-+ u16 vid = mdb->vid;
-+
-+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -430,11 +430,9 @@ int qca8k_read(struct qca8k_priv *priv,
- int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val);
- int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val);
-
--int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
--int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
--
- /* Common ops function */
- int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
-+void qca8k_fdb_flush(struct qca8k_priv *priv);
-
- /* Common ethtool stats function */
- void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data);
-@@ -463,6 +461,23 @@ int qca8k_port_change_mtu(struct dsa_swi
- int qca8k_port_max_mtu(struct dsa_switch *ds, int port);
-
- /* Common fast age function */
-+void qca8k_port_fast_age(struct dsa_switch *ds, int port);
- int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs);
-
-+/* Common FDB function */
-+int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
-+ u16 port_mask, u16 vid);
-+int qca8k_port_fdb_add(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid);
-+int qca8k_port_fdb_del(struct dsa_switch *ds, int port,
-+ const unsigned char *addr, u16 vid);
-+int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
-+ dsa_fdb_dump_cb_t *cb, void *data);
-+
-+/* Common MDB function */
-+int qca8k_port_mdb_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb);
-+int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_mdb *mdb);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch b/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch
deleted file mode 100644
index c1336d4a92..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch
+++ /dev/null
@@ -1,232 +0,0 @@
-From 742d37a84d3f7bb60d9b2d9ada9ad4e599f65ebf Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:20 +0200
-Subject: [PATCH 11/14] net: dsa: qca8k: move port mirror functions to common
- code
-
-The same port mirror functions are used by drivers based on qca8k family
-switch. Move them to common code to make them accessible also by other
-drivers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------
- drivers/net/dsa/qca/qca8k-common.c | 91 +++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 7 +++
- 3 files changed, 98 insertions(+), 93 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1838,99 +1838,6 @@ exit:
- }
-
- static int
--qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-- struct dsa_mall_mirror_tc_entry *mirror,
-- bool ingress)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int monitor_port, ret;
-- u32 reg, val;
--
-- /* Check for existent entry */
-- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
-- return -EEXIST;
--
-- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
-- if (ret)
-- return ret;
--
-- /* QCA83xx can have only one port set to mirror mode.
-- * Check that the correct port is requested and return error otherwise.
-- * When no mirror port is set, the values is set to 0xF
-- */
-- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
-- return -EEXIST;
--
-- /* Set the monitor port */
-- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
-- mirror->to_local_port);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (ret)
-- return ret;
--
-- if (ingress) {
-- reg = QCA8K_PORT_LOOKUP_CTRL(port);
-- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-- } else {
-- reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-- }
--
-- ret = regmap_update_bits(priv->regmap, reg, val, val);
-- if (ret)
-- return ret;
--
-- /* Track mirror port for tx and rx to decide when the
-- * mirror port has to be disabled.
-- */
-- if (ingress)
-- priv->mirror_rx |= BIT(port);
-- else
-- priv->mirror_tx |= BIT(port);
--
-- return 0;
--}
--
--static void
--qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-- struct dsa_mall_mirror_tc_entry *mirror)
--{
-- struct qca8k_priv *priv = ds->priv;
-- u32 reg, val;
-- int ret;
--
-- if (mirror->ingress) {
-- reg = QCA8K_PORT_LOOKUP_CTRL(port);
-- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-- } else {
-- reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-- }
--
-- ret = regmap_clear_bits(priv->regmap, reg, val);
-- if (ret)
-- goto err;
--
-- if (mirror->ingress)
-- priv->mirror_rx &= ~BIT(port);
-- else
-- priv->mirror_tx &= ~BIT(port);
--
-- /* No port set to send packet to mirror port. Disable mirror port */
-- if (!priv->mirror_rx && !priv->mirror_tx) {
-- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-- if (ret)
-- goto err;
-- }
--err:
-- dev_err(priv->dev, "Failed to del mirror port from %d", port);
--}
--
--static int
- qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
- struct netlink_ext_ack *extack)
- {
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -741,3 +741,94 @@ int qca8k_port_mdb_del(struct dsa_switch
-
- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
- }
-+
-+int qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror,
-+ bool ingress)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int monitor_port, ret;
-+ u32 reg, val;
-+
-+ /* Check for existent entry */
-+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
-+ return -EEXIST;
-+
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* QCA83xx can have only one port set to mirror mode.
-+ * Check that the correct port is requested and return error otherwise.
-+ * When no mirror port is set, the values is set to 0xF
-+ */
-+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
-+ return -EEXIST;
-+
-+ /* Set the monitor port */
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
-+ mirror->to_local_port);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ return ret;
-+
-+ if (ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_update_bits(priv->regmap, reg, val, val);
-+ if (ret)
-+ return ret;
-+
-+ /* Track mirror port for tx and rx to decide when the
-+ * mirror port has to be disabled.
-+ */
-+ if (ingress)
-+ priv->mirror_rx |= BIT(port);
-+ else
-+ priv->mirror_tx |= BIT(port);
-+
-+ return 0;
-+}
-+
-+void qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ u32 reg, val;
-+ int ret;
-+
-+ if (mirror->ingress) {
-+ reg = QCA8K_PORT_LOOKUP_CTRL(port);
-+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
-+ } else {
-+ reg = QCA8K_REG_PORT_HOL_CTRL1(port);
-+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
-+ }
-+
-+ ret = regmap_clear_bits(priv->regmap, reg, val);
-+ if (ret)
-+ goto err;
-+
-+ if (mirror->ingress)
-+ priv->mirror_rx &= ~BIT(port);
-+ else
-+ priv->mirror_tx &= ~BIT(port);
-+
-+ /* No port set to send packet to mirror port. Disable mirror port */
-+ if (!priv->mirror_rx && !priv->mirror_tx) {
-+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
-+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
-+ if (ret)
-+ goto err;
-+ }
-+err:
-+ dev_err(priv->dev, "Failed to del mirror port from %d", port);
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -480,4 +480,11 @@ int qca8k_port_mdb_add(struct dsa_switch
- int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_mdb *mdb);
-
-+/* Common port mirror function */
-+int qca8k_port_mirror_add(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror,
-+ bool ingress);
-+void qca8k_port_mirror_del(struct dsa_switch *ds, int port,
-+ struct dsa_mall_mirror_tc_entry *mirror);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch b/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch
deleted file mode 100644
index 898010f950..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch
+++ /dev/null
@@ -1,448 +0,0 @@
-From c5290f636624b98e76a82bd63ffec0a8a9daa620 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:21 +0200
-Subject: [PATCH 12/14] net: dsa: qca8k: move port VLAN functions to common
- code
-
-The same port VLAN functions are used by drivers based on qca8k family
-switch. Move them to common code to make them accessible also by other
-drivers.
-Also drop exposing busy_wait and make it static.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 182 -----------------------------
- drivers/net/dsa/qca/qca8k-common.c | 179 +++++++++++++++++++++++++++-
- drivers/net/dsa/qca/qca8k.h | 10 +-
- 3 files changed, 187 insertions(+), 184 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -15,7 +15,6 @@
- #include <linux/of_net.h>
- #include <linux/of_mdio.h>
- #include <linux/of_platform.h>
--#include <linux/if_bridge.h>
- #include <linux/mdio.h>
- #include <linux/phylink.h>
- #include <linux/gpio/consumer.h>
-@@ -442,122 +441,6 @@ static struct regmap_config qca8k_regmap
- };
-
- static int
--qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
--{
-- u32 reg;
-- int ret;
--
-- /* Set the command and VLAN index */
-- reg = QCA8K_VTU_FUNC1_BUSY;
-- reg |= cmd;
-- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
--
-- /* Write the function register triggering the table access */
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-- if (ret)
-- return ret;
--
-- /* wait for completion */
-- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
-- if (ret)
-- return ret;
--
-- /* Check for table full violation when adding an entry */
-- if (cmd == QCA8K_VLAN_LOAD) {
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
-- if (ret < 0)
-- return ret;
-- if (reg & QCA8K_VTU_FUNC1_FULL)
-- return -ENOMEM;
-- }
--
-- return 0;
--}
--
--static int
--qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
--{
-- u32 reg;
-- int ret;
--
-- /*
-- We do the right thing with VLAN 0 and treat it as untagged while
-- preserving the tag on egress.
-- */
-- if (vid == 0)
-- return 0;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-- if (ret < 0)
-- goto out;
--
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-- if (ret < 0)
-- goto out;
-- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-- if (untagged)
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
-- else
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
--
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-- if (ret)
-- goto out;
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
--
--out:
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
--qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
--{
-- u32 reg, mask;
-- int ret, i;
-- bool del;
--
-- mutex_lock(&priv->reg_mutex);
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-- if (ret < 0)
-- goto out;
--
-- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-- if (ret < 0)
-- goto out;
-- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
--
-- /* Check if we're the last member to be removed */
-- del = true;
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
--
-- if ((reg & mask) != mask) {
-- del = false;
-- break;
-- }
-- }
--
-- if (del) {
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
-- } else {
-- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-- if (ret)
-- goto out;
-- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-- }
--
--out:
-- mutex_unlock(&priv->reg_mutex);
--
-- return ret;
--}
--
--static int
- qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
- struct sk_buff *read_skb, u32 *val)
- {
-@@ -1836,71 +1719,6 @@ exit:
-
- return ret;
- }
--
--static int
--qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-- struct netlink_ext_ack *extack)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- if (vlan_filtering) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
-- } else {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
-- }
--
-- return ret;
--}
--
--static int
--qca8k_port_vlan_add(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_vlan *vlan,
-- struct netlink_ext_ack *extack)
--{
-- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
-- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
-- if (ret) {
-- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
-- return ret;
-- }
--
-- if (pvid) {
-- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-- QCA8K_EGREES_VLAN_PORT_MASK(port),
-- QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
-- if (ret)
-- return ret;
--
-- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
-- QCA8K_PORT_VLAN_CVID(vlan->vid) |
-- QCA8K_PORT_VLAN_SVID(vlan->vid));
-- }
--
-- return ret;
--}
--
--static int
--qca8k_port_vlan_del(struct dsa_switch *ds, int port,
-- const struct switchdev_obj_port_vlan *vlan)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret;
--
-- ret = qca8k_vlan_del(priv, port, vlan->vid);
-- if (ret)
-- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
--
-- return ret;
--}
-
- static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
- {
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -141,7 +141,7 @@ static int qca8k_bulk_write(struct qca8k
- return 0;
- }
-
--int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
-+static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
- {
- u32 val;
-
-@@ -354,6 +354,120 @@ exit:
- return ret;
- }
-
-+static int qca8k_vlan_access(struct qca8k_priv *priv,
-+ enum qca8k_vlan_cmd cmd, u16 vid)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /* Set the command and VLAN index */
-+ reg = QCA8K_VTU_FUNC1_BUSY;
-+ reg |= cmd;
-+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
-+
-+ /* Write the function register triggering the table access */
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-+ if (ret)
-+ return ret;
-+
-+ /* wait for completion */
-+ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
-+ if (ret)
-+ return ret;
-+
-+ /* Check for table full violation when adding an entry */
-+ if (cmd == QCA8K_VLAN_LOAD) {
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
-+ if (ret < 0)
-+ return ret;
-+ if (reg & QCA8K_VTU_FUNC1_FULL)
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid,
-+ bool untagged)
-+{
-+ u32 reg;
-+ int ret;
-+
-+ /* We do the right thing with VLAN 0 and treat it as untagged while
-+ * preserving the tag on egress.
-+ */
-+ if (vid == 0)
-+ return 0;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-+ if (ret < 0)
-+ goto out;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+ if (ret < 0)
-+ goto out;
-+ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-+ if (untagged)
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
-+ else
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
-+
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+ if (ret)
-+ goto out;
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-+
-+out:
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
-+{
-+ u32 reg, mask;
-+ int ret, i;
-+ bool del;
-+
-+ mutex_lock(&priv->reg_mutex);
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
-+ if (ret < 0)
-+ goto out;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+ if (ret < 0)
-+ goto out;
-+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
-+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
-+
-+ /* Check if we're the last member to be removed */
-+ del = true;
-+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
-+
-+ if ((reg & mask) != mask) {
-+ del = false;
-+ break;
-+ }
-+ }
-+
-+ if (del) {
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
-+ } else {
-+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+ if (ret)
-+ goto out;
-+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-+ }
-+
-+out:
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
- int qca8k_mib_init(struct qca8k_priv *priv)
- {
- int ret;
-@@ -832,3 +946,66 @@ void qca8k_port_mirror_del(struct dsa_sw
- err:
- dev_err(priv->dev, "Failed to del mirror port from %d", port);
- }
-+
-+int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port,
-+ bool vlan_filtering,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ if (vlan_filtering) {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
-+ } else {
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
-+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
-+ }
-+
-+ return ret;
-+}
-+
-+int qca8k_port_vlan_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan,
-+ struct netlink_ext_ack *extack)
-+{
-+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
-+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
-+ if (ret) {
-+ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
-+ return ret;
-+ }
-+
-+ if (pvid) {
-+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-+ QCA8K_EGREES_VLAN_PORT_MASK(port),
-+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
-+ QCA8K_PORT_VLAN_CVID(vlan->vid) |
-+ QCA8K_PORT_VLAN_SVID(vlan->vid));
-+ }
-+
-+ return ret;
-+}
-+
-+int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret;
-+
-+ ret = qca8k_vlan_del(priv, port, vlan->vid);
-+ if (ret)
-+ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
-+
-+ return ret;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -431,7 +431,6 @@ int qca8k_write(struct qca8k_priv *priv,
- int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val);
-
- /* Common ops function */
--int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
- void qca8k_fdb_flush(struct qca8k_priv *priv);
-
- /* Common ethtool stats function */
-@@ -487,4 +486,13 @@ int qca8k_port_mirror_add(struct dsa_swi
- void qca8k_port_mirror_del(struct dsa_switch *ds, int port,
- struct dsa_mall_mirror_tc_entry *mirror);
-
-+/* Common port VLAN function */
-+int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-+ struct netlink_ext_ack *extack);
-+int qca8k_port_vlan_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan,
-+ struct netlink_ext_ack *extack);
-+int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_vlan *vlan);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch
deleted file mode 100644
index 1802b17eaa..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch
+++ /dev/null
@@ -1,384 +0,0 @@
-From e9bbf019af44b204b71ef8edf224002550aab641 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:22 +0200
-Subject: [PATCH 13/14] net: dsa: qca8k: move port LAG functions to common code
-
-The same port LAG functions are used by drivers based on qca8k family
-switch. Move them to common code to make them accessible also by other
-drivers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 168 -----------------------------
- drivers/net/dsa/qca/qca8k-common.c | 165 ++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 6 ++
- 3 files changed, 171 insertions(+), 168 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1743,178 +1743,6 @@ qca8k_get_tag_protocol(struct dsa_switch
- return DSA_TAG_PROTO_QCA;
- }
-
--static bool
--qca8k_lag_can_offload(struct dsa_switch *ds,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- struct dsa_port *dp;
-- int id, members = 0;
--
-- id = dsa_lag_id(ds->dst, lag);
-- if (id < 0 || id >= ds->num_lag_ids)
-- return false;
--
-- dsa_lag_foreach_port(dp, ds->dst, lag)
-- /* Includes the port joining the LAG */
-- members++;
--
-- if (members > QCA8K_NUM_PORTS_FOR_LAG)
-- return false;
--
-- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
-- return false;
--
-- if (info->hash_type != NETDEV_LAG_HASH_L2 &&
-- info->hash_type != NETDEV_LAG_HASH_L23)
-- return false;
--
-- return true;
--}
--
--static int
--qca8k_lag_setup_hash(struct dsa_switch *ds,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- struct qca8k_priv *priv = ds->priv;
-- bool unique_lag = true;
-- u32 hash = 0;
-- int i, id;
--
-- id = dsa_lag_id(ds->dst, lag);
--
-- switch (info->hash_type) {
-- case NETDEV_LAG_HASH_L23:
-- hash |= QCA8K_TRUNK_HASH_SIP_EN;
-- hash |= QCA8K_TRUNK_HASH_DIP_EN;
-- fallthrough;
-- case NETDEV_LAG_HASH_L2:
-- hash |= QCA8K_TRUNK_HASH_SA_EN;
-- hash |= QCA8K_TRUNK_HASH_DA_EN;
-- break;
-- default: /* We should NEVER reach this */
-- return -EOPNOTSUPP;
-- }
--
-- /* Check if we are the unique configured LAG */
-- dsa_lags_foreach_id(i, ds->dst)
-- if (i != id && dsa_lag_dev(ds->dst, i)) {
-- unique_lag = false;
-- break;
-- }
--
-- /* Hash Mode is global. Make sure the same Hash Mode
-- * is set to all the 4 possible lag.
-- * If we are the unique LAG we can set whatever hash
-- * mode we want.
-- * To change hash mode it's needed to remove all LAG
-- * and change the mode with the latest.
-- */
-- if (unique_lag) {
-- priv->lag_hash_mode = hash;
-- } else if (priv->lag_hash_mode != hash) {
-- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n");
-- return -EOPNOTSUPP;
-- }
--
-- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
-- QCA8K_TRUNK_HASH_MASK, hash);
--}
--
--static int
--qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
-- struct net_device *lag, bool delete)
--{
-- struct qca8k_priv *priv = ds->priv;
-- int ret, id, i;
-- u32 val;
--
-- id = dsa_lag_id(ds->dst, lag);
--
-- /* Read current port member */
-- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
-- if (ret)
-- return ret;
--
-- /* Shift val to the correct trunk */
-- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
-- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
-- if (delete)
-- val &= ~BIT(port);
-- else
-- val |= BIT(port);
--
-- /* Update port member. With empty portmap disable trunk */
-- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
-- QCA8K_REG_GOL_TRUNK_MEMBER(id) |
-- QCA8K_REG_GOL_TRUNK_EN(id),
-- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
-- val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
--
-- /* Search empty member if adding or port on deleting */
-- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
-- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
-- if (ret)
-- return ret;
--
-- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
-- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
--
-- if (delete) {
-- /* If port flagged to be disabled assume this member is
-- * empty
-- */
-- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-- continue;
--
-- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
-- if (val != port)
-- continue;
-- } else {
-- /* If port flagged to be enabled assume this member is
-- * already set
-- */
-- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-- continue;
-- }
--
-- /* We have found the member to add/remove */
-- break;
-- }
--
-- /* Set port in the correct port mask or disable port if in delete mode */
-- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
-- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
-- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
-- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
-- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
--}
--
--static int
--qca8k_port_lag_join(struct dsa_switch *ds, int port,
-- struct net_device *lag,
-- struct netdev_lag_upper_info *info)
--{
-- int ret;
--
-- if (!qca8k_lag_can_offload(ds, lag, info))
-- return -EOPNOTSUPP;
--
-- ret = qca8k_lag_setup_hash(ds, lag, info);
-- if (ret)
-- return ret;
--
-- return qca8k_lag_refresh_portmap(ds, port, lag, false);
--}
--
--static int
--qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-- struct net_device *lag)
--{
-- return qca8k_lag_refresh_portmap(ds, port, lag, true);
--}
--
- static void
- qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
- bool operational)
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -1009,3 +1009,169 @@ int qca8k_port_vlan_del(struct dsa_switc
-
- return ret;
- }
-+
-+static bool qca8k_lag_can_offload(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct dsa_port *dp;
-+ int id, members = 0;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+ if (id < 0 || id >= ds->num_lag_ids)
-+ return false;
-+
-+ dsa_lag_foreach_port(dp, ds->dst, lag)
-+ /* Includes the port joining the LAG */
-+ members++;
-+
-+ if (members > QCA8K_NUM_PORTS_FOR_LAG)
-+ return false;
-+
-+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
-+ return false;
-+
-+ if (info->hash_type != NETDEV_LAG_HASH_L2 &&
-+ info->hash_type != NETDEV_LAG_HASH_L23)
-+ return false;
-+
-+ return true;
-+}
-+
-+static int qca8k_lag_setup_hash(struct dsa_switch *ds,
-+ struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ bool unique_lag = true;
-+ u32 hash = 0;
-+ int i, id;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ switch (info->hash_type) {
-+ case NETDEV_LAG_HASH_L23:
-+ hash |= QCA8K_TRUNK_HASH_SIP_EN;
-+ hash |= QCA8K_TRUNK_HASH_DIP_EN;
-+ fallthrough;
-+ case NETDEV_LAG_HASH_L2:
-+ hash |= QCA8K_TRUNK_HASH_SA_EN;
-+ hash |= QCA8K_TRUNK_HASH_DA_EN;
-+ break;
-+ default: /* We should NEVER reach this */
-+ return -EOPNOTSUPP;
-+ }
-+
-+ /* Check if we are the unique configured LAG */
-+ dsa_lags_foreach_id(i, ds->dst)
-+ if (i != id && dsa_lag_dev(ds->dst, i)) {
-+ unique_lag = false;
-+ break;
-+ }
-+
-+ /* Hash Mode is global. Make sure the same Hash Mode
-+ * is set to all the 4 possible lag.
-+ * If we are the unique LAG we can set whatever hash
-+ * mode we want.
-+ * To change hash mode it's needed to remove all LAG
-+ * and change the mode with the latest.
-+ */
-+ if (unique_lag) {
-+ priv->lag_hash_mode = hash;
-+ } else if (priv->lag_hash_mode != hash) {
-+ netdev_err(lag, "Error: Mismatched Hash Mode across different lag is not supported\n");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
-+ QCA8K_TRUNK_HASH_MASK, hash);
-+}
-+
-+static int qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
-+ struct net_device *lag, bool delete)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+ int ret, id, i;
-+ u32 val;
-+
-+ id = dsa_lag_id(ds->dst, lag);
-+
-+ /* Read current port member */
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
-+ if (ret)
-+ return ret;
-+
-+ /* Shift val to the correct trunk */
-+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
-+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
-+ if (delete)
-+ val &= ~BIT(port);
-+ else
-+ val |= BIT(port);
-+
-+ /* Update port member. With empty portmap disable trunk */
-+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
-+ QCA8K_REG_GOL_TRUNK_MEMBER(id) |
-+ QCA8K_REG_GOL_TRUNK_EN(id),
-+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
-+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
-+
-+ /* Search empty member if adding or port on deleting */
-+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
-+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
-+ if (ret)
-+ return ret;
-+
-+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
-+
-+ if (delete) {
-+ /* If port flagged to be disabled assume this member is
-+ * empty
-+ */
-+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+
-+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
-+ if (val != port)
-+ continue;
-+ } else {
-+ /* If port flagged to be enabled assume this member is
-+ * already set
-+ */
-+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
-+ continue;
-+ }
-+
-+ /* We have found the member to add/remove */
-+ break;
-+ }
-+
-+ /* Set port in the correct port mask or disable port if in delete mode */
-+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
-+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
-+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
-+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
-+}
-+
-+int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct net_device *lag,
-+ struct netdev_lag_upper_info *info)
-+{
-+ int ret;
-+
-+ if (!qca8k_lag_can_offload(ds, lag, info))
-+ return -EOPNOTSUPP;
-+
-+ ret = qca8k_lag_setup_hash(ds, lag, info);
-+ if (ret)
-+ return ret;
-+
-+ return qca8k_lag_refresh_portmap(ds, port, lag, false);
-+}
-+
-+int qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-+ struct net_device *lag)
-+{
-+ return qca8k_lag_refresh_portmap(ds, port, lag, true);
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -495,4 +495,10 @@ int qca8k_port_vlan_add(struct dsa_switc
- int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan);
-
-+/* Common port LAG function */
-+int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct net_device *lag,
-+ struct netdev_lag_upper_info *info);
-+int qca8k_port_lag_leave(struct dsa_switch *ds, int port,
-+ struct net_device *lag);
-+
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch b/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch
deleted file mode 100644
index d6ec8b77e0..0000000000
--- a/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 9d1bcb1f293f1391302a109c9819c3705c804700 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 27 Jul 2022 13:35:23 +0200
-Subject: [PATCH 14/14] net: dsa: qca8k: move read_switch_id function to common
- code
-
-The same function to read the switch id is used by drivers based on
-qca8k family switch. Move them to common code to make them accessible
-also by other drivers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 29 -----------------------------
- drivers/net/dsa/qca/qca8k-common.c | 29 +++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 1 +
- 3 files changed, 30 insertions(+), 29 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1822,35 +1822,6 @@ static const struct dsa_switch_ops qca8k
- .connect_tag_protocol = qca8k_connect_tag_protocol,
- };
-
--static int qca8k_read_switch_id(struct qca8k_priv *priv)
--{
-- u32 val;
-- u8 id;
-- int ret;
--
-- if (!priv->info)
-- return -ENODEV;
--
-- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-- if (ret < 0)
-- return -ENODEV;
--
-- id = QCA8K_MASK_CTRL_DEVICE_ID(val);
-- if (id != priv->info->id) {
-- dev_err(priv->dev,
-- "Switch id detected %x but expected %x",
-- id, priv->info->id);
-- return -ENODEV;
-- }
--
-- priv->switch_id = id;
--
-- /* Save revision to communicate to the internal PHY driver */
-- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
--
-- return 0;
--}
--
- static int
- qca8k_sw_probe(struct mdio_device *mdiodev)
- {
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -1175,3 +1175,32 @@ int qca8k_port_lag_leave(struct dsa_swit
- {
- return qca8k_lag_refresh_portmap(ds, port, lag, true);
- }
-+
-+int qca8k_read_switch_id(struct qca8k_priv *priv)
-+{
-+ u32 val;
-+ u8 id;
-+ int ret;
-+
-+ if (!priv->info)
-+ return -ENODEV;
-+
-+ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-+ if (ret < 0)
-+ return -ENODEV;
-+
-+ id = QCA8K_MASK_CTRL_DEVICE_ID(val);
-+ if (id != priv->info->id) {
-+ dev_err(priv->dev,
-+ "Switch id detected %x but expected %x",
-+ id, priv->info->id);
-+ return -ENODEV;
-+ }
-+
-+ priv->switch_id = id;
-+
-+ /* Save revision to communicate to the internal PHY driver */
-+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
-+
-+ return 0;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -424,6 +424,7 @@ extern const struct qca8k_mib_desc ar832
- extern const struct regmap_access_table qca8k_readable_table;
- int qca8k_mib_init(struct qca8k_priv *priv);
- void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable);
-+int qca8k_read_switch_id(struct qca8k_priv *priv);
-
- /* Common read/write/rmw function */
- int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val);
diff --git a/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch b/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch
deleted file mode 100644
index 0cca2788f6..0000000000
--- a/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 057bcf15db8e625276ddf02b2b7c668a3cb43f81 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 4 Sep 2022 23:46:24 +0200
-Subject: [net PATCH] net: dsa: qca8k: fix NULL pointer dereference for
- of_device_get_match_data
-
-of_device_get_match_data is called on priv->dev before priv->dev is
-actually set. Move of_device_get_match_data after priv->dev is correctly
-set to fix this kernel panic.
-
-Fixes: 3bb0844e7bcd ("net: dsa: qca8k: cache match data to speed up access")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1835,9 +1835,9 @@ qca8k_sw_probe(struct mdio_device *mdiod
- if (!priv)
- return -ENOMEM;
-
-- priv->info = of_device_get_match_data(priv->dev);
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
-+ priv->info = of_device_get_match_data(priv->dev);
-
- priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
- GPIOD_ASIS);
diff --git a/target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch b/target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch
deleted file mode 100644
index 44093eab95..0000000000
--- a/target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 381a730182f1d174e1950cd4e63e885b1c302051 Mon Sep 17 00:00:00 2001
-From: Tobias Waldekranz <tobias@waldekranz.com>
-Date: Mon, 24 Jan 2022 22:09:43 +0100
-Subject: net: dsa: Move VLAN filtering syncing out of dsa_switch_bridge_leave
-
-Most of dsa_switch_bridge_leave was, in fact, dealing with the syncing
-of VLAN filtering for switches on which that is a global
-setting. Separate the two phases to prepare for the cross-chip related
-bugfix in the following commit.
-
-Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/switch.c | 38 +++++++++++++++++++++++++-------------
- 1 file changed, 25 insertions(+), 13 deletions(-)
-
---- a/net/dsa/switch.c
-+++ b/net/dsa/switch.c
-@@ -113,25 +113,14 @@ static int dsa_switch_bridge_join(struct
- return dsa_tag_8021q_bridge_join(ds, info);
- }
-
--static int dsa_switch_bridge_leave(struct dsa_switch *ds,
-- struct dsa_notifier_bridge_info *info)
-+static int dsa_switch_sync_vlan_filtering(struct dsa_switch *ds,
-+ struct dsa_notifier_bridge_info *info)
- {
-- struct dsa_switch_tree *dst = ds->dst;
- struct netlink_ext_ack extack = {0};
- bool change_vlan_filtering = false;
- bool vlan_filtering;
- int err, port;
-
-- if (dst->index == info->tree_index && ds->index == info->sw_index &&
-- ds->ops->port_bridge_leave)
-- ds->ops->port_bridge_leave(ds, info->port, info->br);
--
-- if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
-- ds->ops->crosschip_bridge_leave)
-- ds->ops->crosschip_bridge_leave(ds, info->tree_index,
-- info->sw_index, info->port,
-- info->br);
--
- if (ds->needs_standalone_vlan_filtering && !br_vlan_enabled(info->br)) {
- change_vlan_filtering = true;
- vlan_filtering = true;
-@@ -172,6 +161,29 @@ static int dsa_switch_bridge_leave(struc
- return err;
- }
-
-+ return 0;
-+}
-+
-+static int dsa_switch_bridge_leave(struct dsa_switch *ds,
-+ struct dsa_notifier_bridge_info *info)
-+{
-+ struct dsa_switch_tree *dst = ds->dst;
-+ int err;
-+
-+ if (dst->index == info->tree_index && ds->index == info->sw_index &&
-+ ds->ops->port_bridge_leave)
-+ ds->ops->port_bridge_leave(ds, info->port, info->br);
-+
-+ if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
-+ ds->ops->crosschip_bridge_leave)
-+ ds->ops->crosschip_bridge_leave(ds, info->tree_index,
-+ info->sw_index, info->port,
-+ info->br);
-+
-+ err = dsa_switch_sync_vlan_filtering(ds, info);
-+ if (err)
-+ return err;
-+
- return dsa_tag_8021q_bridge_leave(ds, info);
- }
-
diff --git a/target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch b/target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch
deleted file mode 100644
index cdddbcf14e..0000000000
--- a/target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 108dc8741c203e9d6ce4e973367f1bac20c7192b Mon Sep 17 00:00:00 2001
-From: Tobias Waldekranz <tobias@waldekranz.com>
-Date: Mon, 24 Jan 2022 22:09:44 +0100
-Subject: net: dsa: Avoid cross-chip syncing of VLAN filtering
-
-Changes to VLAN filtering are not applicable to cross-chip
-notifications.
-
-On a system like this:
-
-.-----. .-----. .-----.
-| sw1 +---+ sw2 +---+ sw3 |
-'-1-2-' '-1-2-' '-1-2-'
-
-Before this change, upon sw1p1 leaving a bridge, a call to
-dsa_port_vlan_filtering would also be made to sw2p1 and sw3p1.
-
-In this scenario:
-
-.---------. .-----. .-----.
-| sw1 +---+ sw2 +---+ sw3 |
-'-1-2-3-4-' '-1-2-' '-1-2-'
-
-When sw1p4 would leave a bridge, dsa_port_vlan_filtering would be
-called for sw2 and sw3 with a non-existing port - leading to array
-out-of-bounds accesses and crashes on mv88e6xxx.
-
-Fixes: d371b7c92d19 ("net: dsa: Unset vlan_filtering when ports leave the bridge")
-Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/switch.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/net/dsa/switch.c
-+++ b/net/dsa/switch.c
-@@ -180,9 +180,11 @@ static int dsa_switch_bridge_leave(struc
- info->sw_index, info->port,
- info->br);
-
-- err = dsa_switch_sync_vlan_filtering(ds, info);
-- if (err)
-- return err;
-+ if (ds->dst->index == info->tree_index && ds->index == info->sw_index) {
-+ err = dsa_switch_sync_vlan_filtering(ds, info);
-+ if (err)
-+ return err;
-+ }
-
- return dsa_tag_8021q_bridge_leave(ds, info);
- }
diff --git a/target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch b/target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch
deleted file mode 100644
index 78570c5e6e..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From c9111895fd38dadf125e07be627778a9950d8d77 Mon Sep 17 00:00:00 2001
-From: DENG Qingfang <dqfext@gmail.com>
-Date: Sun, 26 Sep 2021 00:59:24 +0200
-Subject: [PATCH 01/11] net: dsa: rtl8366rb: Support bridge offloading
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use port isolation registers to configure bridge offloading.
-
-Tested on the D-Link DIR-685, switching between ports and
-sniffing ports to make sure no packets leak.
-
-Cc: Vladimir Oltean <olteanv@gmail.com>
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: DENG Qingfang <dqfext@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/rtl8366rb.c | 86 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 86 insertions(+)
-
---- a/drivers/net/dsa/rtl8366rb.c
-+++ b/drivers/net/dsa/rtl8366rb.c
-@@ -300,6 +300,13 @@
- #define RTL8366RB_INTERRUPT_STATUS_REG 0x0442
- #define RTL8366RB_NUM_INTERRUPT 14 /* 0..13 */
-
-+/* Port isolation registers */
-+#define RTL8366RB_PORT_ISO_BASE 0x0F08
-+#define RTL8366RB_PORT_ISO(pnum) (RTL8366RB_PORT_ISO_BASE + (pnum))
-+#define RTL8366RB_PORT_ISO_EN BIT(0)
-+#define RTL8366RB_PORT_ISO_PORTS_MASK GENMASK(7, 1)
-+#define RTL8366RB_PORT_ISO_PORTS(pmask) ((pmask) << 1)
-+
- /* bits 0..5 enable force when cleared */
- #define RTL8366RB_MAC_FORCE_CTRL_REG 0x0F11
-
-@@ -835,6 +842,21 @@ static int rtl8366rb_setup(struct dsa_sw
- if (ret)
- return ret;
-
-+ /* Isolate all user ports so they can only send packets to itself and the CPU port */
-+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
-+ ret = regmap_write(smi->map, RTL8366RB_PORT_ISO(i),
-+ RTL8366RB_PORT_ISO_PORTS(BIT(RTL8366RB_PORT_NUM_CPU)) |
-+ RTL8366RB_PORT_ISO_EN);
-+ if (ret)
-+ return ret;
-+ }
-+ /* CPU port can send packets to all ports */
-+ ret = regmap_write(smi->map, RTL8366RB_PORT_ISO(RTL8366RB_PORT_NUM_CPU),
-+ RTL8366RB_PORT_ISO_PORTS(dsa_user_ports(ds)) |
-+ RTL8366RB_PORT_ISO_EN);
-+ if (ret)
-+ return ret;
-+
- /* Set up the "green ethernet" feature */
- ret = rtl8366rb_jam_table(rtl8366rb_green_jam,
- ARRAY_SIZE(rtl8366rb_green_jam), smi, false);
-@@ -1127,6 +1149,68 @@ rtl8366rb_port_disable(struct dsa_switch
- rb8366rb_set_port_led(smi, port, false);
- }
-
-+static int
-+rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port,
-+ struct net_device *bridge)
-+{
-+ struct realtek_smi *smi = ds->priv;
-+ unsigned int port_bitmap = 0;
-+ int ret, i;
-+
-+ /* Loop over all other ports than the current one */
-+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
-+ /* Current port handled last */
-+ if (i == port)
-+ continue;
-+ /* Not on this bridge */
-+ if (dsa_to_port(ds, i)->bridge_dev != bridge)
-+ continue;
-+ /* Join this port to each other port on the bridge */
-+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(i),
-+ RTL8366RB_PORT_ISO_PORTS(BIT(port)),
-+ RTL8366RB_PORT_ISO_PORTS(BIT(port)));
-+ if (ret)
-+ dev_err(smi->dev, "failed to join port %d\n", port);
-+
-+ port_bitmap |= BIT(i);
-+ }
-+
-+ /* Set the bits for the ports we can access */
-+ return regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(port),
-+ RTL8366RB_PORT_ISO_PORTS(port_bitmap),
-+ RTL8366RB_PORT_ISO_PORTS(port_bitmap));
-+}
-+
-+static void
-+rtl8366rb_port_bridge_leave(struct dsa_switch *ds, int port,
-+ struct net_device *bridge)
-+{
-+ struct realtek_smi *smi = ds->priv;
-+ unsigned int port_bitmap = 0;
-+ int ret, i;
-+
-+ /* Loop over all other ports than this one */
-+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
-+ /* Current port handled last */
-+ if (i == port)
-+ continue;
-+ /* Not on this bridge */
-+ if (dsa_to_port(ds, i)->bridge_dev != bridge)
-+ continue;
-+ /* Remove this port from any other port on the bridge */
-+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(i),
-+ RTL8366RB_PORT_ISO_PORTS(BIT(port)), 0);
-+ if (ret)
-+ dev_err(smi->dev, "failed to leave port %d\n", port);
-+
-+ port_bitmap |= BIT(i);
-+ }
-+
-+ /* Clear the bits for the ports we can not access, leave ourselves */
-+ regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(port),
-+ RTL8366RB_PORT_ISO_PORTS(port_bitmap), 0);
-+}
-+
- static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct realtek_smi *smi = ds->priv;
-@@ -1510,6 +1594,8 @@ static const struct dsa_switch_ops rtl83
- .get_strings = rtl8366_get_strings,
- .get_ethtool_stats = rtl8366_get_ethtool_stats,
- .get_sset_count = rtl8366_get_sset_count,
-+ .port_bridge_join = rtl8366rb_port_bridge_join,
-+ .port_bridge_leave = rtl8366rb_port_bridge_leave,
- .port_vlan_filtering = rtl8366_vlan_filtering,
- .port_vlan_add = rtl8366_vlan_add,
- .port_vlan_del = rtl8366_vlan_del,
diff --git a/target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch b/target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch
deleted file mode 100644
index e61349a32c..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 96cf10a8e7297065459473c081a6fb6432a22312 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 26 Sep 2021 00:59:25 +0200
-Subject: [PATCH 02/11] net: dsa: rtl8366: Drop custom VLAN set-up
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This hacky default VLAN setup was done in order to direct
-packets to the right ports and provide port isolation, both
-which we now support properly using custom tags and proper
-bridge port isolation.
-
-We can drop the custom VLAN code and leave all VLAN handling
-alone, as users expect things to be. We can also drop
-ds->configure_vlan_while_not_filtering = false; and let
-the core deal with any VLANs it wants.
-
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Cc: DENG Qingfang <dqfext@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/realtek-smi-core.h | 1 -
- drivers/net/dsa/rtl8366.c | 48 ------------------------------
- drivers/net/dsa/rtl8366rb.c | 4 +--
- 3 files changed, 1 insertion(+), 52 deletions(-)
-
---- a/drivers/net/dsa/realtek-smi-core.h
-+++ b/drivers/net/dsa/realtek-smi-core.h
-@@ -129,7 +129,6 @@ int rtl8366_set_pvid(struct realtek_smi
- int rtl8366_enable_vlan4k(struct realtek_smi *smi, bool enable);
- int rtl8366_enable_vlan(struct realtek_smi *smi, bool enable);
- int rtl8366_reset_vlan(struct realtek_smi *smi);
--int rtl8366_init_vlan(struct realtek_smi *smi);
- int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
- struct netlink_ext_ack *extack);
- int rtl8366_vlan_add(struct dsa_switch *ds, int port,
---- a/drivers/net/dsa/rtl8366.c
-+++ b/drivers/net/dsa/rtl8366.c
-@@ -292,54 +292,6 @@ int rtl8366_reset_vlan(struct realtek_sm
- }
- EXPORT_SYMBOL_GPL(rtl8366_reset_vlan);
-
--int rtl8366_init_vlan(struct realtek_smi *smi)
--{
-- int port;
-- int ret;
--
-- ret = rtl8366_reset_vlan(smi);
-- if (ret)
-- return ret;
--
-- /* Loop over the available ports, for each port, associate
-- * it with the VLAN (port+1)
-- */
-- for (port = 0; port < smi->num_ports; port++) {
-- u32 mask;
--
-- if (port == smi->cpu_port)
-- /* For the CPU port, make all ports members of this
-- * VLAN.
-- */
-- mask = GENMASK((int)smi->num_ports - 1, 0);
-- else
-- /* For all other ports, enable itself plus the
-- * CPU port.
-- */
-- mask = BIT(port) | BIT(smi->cpu_port);
--
-- /* For each port, set the port as member of VLAN (port+1)
-- * and untagged, except for the CPU port: the CPU port (5) is
-- * member of VLAN 6 and so are ALL the other ports as well.
-- * Use filter 0 (no filter).
-- */
-- dev_info(smi->dev, "VLAN%d port mask for port %d, %08x\n",
-- (port + 1), port, mask);
-- ret = rtl8366_set_vlan(smi, (port + 1), mask, mask, 0);
-- if (ret)
-- return ret;
--
-- dev_info(smi->dev, "VLAN%d port %d, PVID set to %d\n",
-- (port + 1), port, (port + 1));
-- ret = rtl8366_set_pvid(smi, port, (port + 1));
-- if (ret)
-- return ret;
-- }
--
-- return rtl8366_enable_vlan(smi, true);
--}
--EXPORT_SYMBOL_GPL(rtl8366_init_vlan);
--
- int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
- struct netlink_ext_ack *extack)
- {
---- a/drivers/net/dsa/rtl8366rb.c
-+++ b/drivers/net/dsa/rtl8366rb.c
-@@ -985,7 +985,7 @@ static int rtl8366rb_setup(struct dsa_sw
- return ret;
- }
-
-- ret = rtl8366_init_vlan(smi);
-+ ret = rtl8366_reset_vlan(smi);
- if (ret)
- return ret;
-
-@@ -999,8 +999,6 @@ static int rtl8366rb_setup(struct dsa_sw
- return -ENODEV;
- }
-
-- ds->configure_vlan_while_not_filtering = false;
--
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch b/target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch
deleted file mode 100644
index 2b19752399..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch
+++ /dev/null
@@ -1,270 +0,0 @@
-From 7028f54b620f8df344b18e46e4a78e266091ab45 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 26 Sep 2021 00:59:26 +0200
-Subject: [PATCH 03/11] net: dsa: rtl8366rb: Rewrite weird VLAN filering
- enablement
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-While we were defining one VLAN per port for isolating the ports
-the port_vlan_filtering() callback was implemented to enable a
-VLAN on the port + 1. This function makes no sense, not only is
-it incomplete as it only enables the VLAN, it doesn't do what
-the callback is supposed to do, which is to selectively enable
-and disable filtering on a certain port.
-
-Implement the correct callback: we have two registers dealing
-with filtering on the RTL9366RB, so we implement an ASIC-specific
-callback and implement filering using the register bit that makes
-the switch drop frames if the port is not in the VLAN member set.
-
-The DSA documentation Documentation/networking/switchdev.rst states:
-
- When the bridge has VLAN filtering enabled and a PVID is not
- configured on the ingress port, untagged and 802.1p tagged
- packets must be dropped. When the bridge has VLAN filtering
- enabled and a PVID exists on the ingress port, untagged and
- priority-tagged packets must be accepted and forwarded according
- to the bridge's port membership of the PVID VLAN. When the
- bridge has VLAN filtering disabled, the presence/lack of a
- PVID should not influence the packet forwarding decision.
-
-To comply with this, we add two arrays of bool in the RTL8366RB
-state that keeps track of if filtering and PVID is enabled or
-not for each port. We then add code such that whenever filtering
-or PVID changes, we update the filter according to the
-specification.
-
-Cc: Vladimir Oltean <olteanv@gmail.com>
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Cc: DENG Qingfang <dqfext@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/realtek-smi-core.h | 2 -
- drivers/net/dsa/rtl8366.c | 35 ----------
- drivers/net/dsa/rtl8366rb.c | 102 +++++++++++++++++++++++++++--
- 3 files changed, 95 insertions(+), 44 deletions(-)
-
---- a/drivers/net/dsa/realtek-smi-core.h
-+++ b/drivers/net/dsa/realtek-smi-core.h
-@@ -129,8 +129,6 @@ int rtl8366_set_pvid(struct realtek_smi
- int rtl8366_enable_vlan4k(struct realtek_smi *smi, bool enable);
- int rtl8366_enable_vlan(struct realtek_smi *smi, bool enable);
- int rtl8366_reset_vlan(struct realtek_smi *smi);
--int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-- struct netlink_ext_ack *extack);
- int rtl8366_vlan_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan,
- struct netlink_ext_ack *extack);
---- a/drivers/net/dsa/rtl8366.c
-+++ b/drivers/net/dsa/rtl8366.c
-@@ -292,41 +292,6 @@ int rtl8366_reset_vlan(struct realtek_sm
- }
- EXPORT_SYMBOL_GPL(rtl8366_reset_vlan);
-
--int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
-- struct netlink_ext_ack *extack)
--{
-- struct realtek_smi *smi = ds->priv;
-- struct rtl8366_vlan_4k vlan4k;
-- int ret;
--
-- /* Use VLAN nr port + 1 since VLAN0 is not valid */
-- if (!smi->ops->is_vlan_valid(smi, port + 1))
-- return -EINVAL;
--
-- dev_info(smi->dev, "%s filtering on port %d\n",
-- vlan_filtering ? "enable" : "disable",
-- port);
--
-- /* TODO:
-- * The hardware support filter ID (FID) 0..7, I have no clue how to
-- * support this in the driver when the callback only says on/off.
-- */
-- ret = smi->ops->get_vlan_4k(smi, port + 1, &vlan4k);
-- if (ret)
-- return ret;
--
-- /* Just set the filter to FID 1 for now then */
-- ret = rtl8366_set_vlan(smi, port + 1,
-- vlan4k.member,
-- vlan4k.untag,
-- 1);
-- if (ret)
-- return ret;
--
-- return 0;
--}
--EXPORT_SYMBOL_GPL(rtl8366_vlan_filtering);
--
- int rtl8366_vlan_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan,
- struct netlink_ext_ack *extack)
---- a/drivers/net/dsa/rtl8366rb.c
-+++ b/drivers/net/dsa/rtl8366rb.c
-@@ -143,6 +143,21 @@
- #define RTL8366RB_PHY_NO_OFFSET 9
- #define RTL8366RB_PHY_NO_MASK (0x1f << 9)
-
-+/* VLAN Ingress Control Register 1, one bit per port.
-+ * bit 0 .. 5 will make the switch drop ingress frames without
-+ * VID such as untagged or priority-tagged frames for respective
-+ * port.
-+ * bit 6 .. 11 will make the switch drop ingress frames carrying
-+ * a C-tag with VID != 0 for respective port.
-+ */
-+#define RTL8366RB_VLAN_INGRESS_CTRL1_REG 0x037E
-+#define RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port) (BIT((port)) | BIT((port) + 6))
-+
-+/* VLAN Ingress Control Register 2, one bit per port.
-+ * bit0 .. bit5 will make the switch drop all ingress frames with
-+ * a VLAN classification that does not include the port is in its
-+ * member set.
-+ */
- #define RTL8366RB_VLAN_INGRESS_CTRL2_REG 0x037f
-
- /* LED control registers */
-@@ -321,9 +336,13 @@
- /**
- * struct rtl8366rb - RTL8366RB-specific data
- * @max_mtu: per-port max MTU setting
-+ * @pvid_enabled: if PVID is set for respective port
-+ * @vlan_filtering: if VLAN filtering is enabled for respective port
- */
- struct rtl8366rb {
- unsigned int max_mtu[RTL8366RB_NUM_PORTS];
-+ bool pvid_enabled[RTL8366RB_NUM_PORTS];
-+ bool vlan_filtering[RTL8366RB_NUM_PORTS];
- };
-
- static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
-@@ -933,11 +952,13 @@ static int rtl8366rb_setup(struct dsa_sw
- if (ret)
- return ret;
-
-- /* Discard VLAN tagged packets if the port is not a member of
-- * the VLAN with which the packets is associated.
-- */
-+ /* Accept all packets by default, we enable filtering on-demand */
-+ ret = regmap_write(smi->map, RTL8366RB_VLAN_INGRESS_CTRL1_REG,
-+ 0);
-+ if (ret)
-+ return ret;
- ret = regmap_write(smi->map, RTL8366RB_VLAN_INGRESS_CTRL2_REG,
-- RTL8366RB_PORT_ALL);
-+ 0);
- if (ret)
- return ret;
-
-@@ -1209,6 +1230,53 @@ rtl8366rb_port_bridge_leave(struct dsa_s
- RTL8366RB_PORT_ISO_PORTS(port_bitmap), 0);
- }
-
-+/**
-+ * rtl8366rb_drop_untagged() - make the switch drop untagged and C-tagged frames
-+ * @smi: SMI state container
-+ * @port: the port to drop untagged and C-tagged frames on
-+ * @drop: whether to drop or pass untagged and C-tagged frames
-+ */
-+static int rtl8366rb_drop_untagged(struct realtek_smi *smi, int port, bool drop)
-+{
-+ return regmap_update_bits(smi->map, RTL8366RB_VLAN_INGRESS_CTRL1_REG,
-+ RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port),
-+ drop ? RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port) : 0);
-+}
-+
-+static int rtl8366rb_vlan_filtering(struct dsa_switch *ds, int port,
-+ bool vlan_filtering,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct realtek_smi *smi = ds->priv;
-+ struct rtl8366rb *rb;
-+ int ret;
-+
-+ rb = smi->chip_data;
-+
-+ dev_dbg(smi->dev, "port %d: %s VLAN filtering\n", port,
-+ vlan_filtering ? "enable" : "disable");
-+
-+ /* If the port is not in the member set, the frame will be dropped */
-+ ret = regmap_update_bits(smi->map, RTL8366RB_VLAN_INGRESS_CTRL2_REG,
-+ BIT(port), vlan_filtering ? BIT(port) : 0);
-+ if (ret)
-+ return ret;
-+
-+ /* Keep track if filtering is enabled on each port */
-+ rb->vlan_filtering[port] = vlan_filtering;
-+
-+ /* If VLAN filtering is enabled and PVID is also enabled, we must
-+ * not drop any untagged or C-tagged frames. If we turn off VLAN
-+ * filtering on a port, we need ti accept any frames.
-+ */
-+ if (vlan_filtering)
-+ ret = rtl8366rb_drop_untagged(smi, port, !rb->pvid_enabled[port]);
-+ else
-+ ret = rtl8366rb_drop_untagged(smi, port, false);
-+
-+ return ret;
-+}
-+
- static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct realtek_smi *smi = ds->priv;
-@@ -1420,14 +1488,34 @@ static int rtl8366rb_get_mc_index(struct
-
- static int rtl8366rb_set_mc_index(struct realtek_smi *smi, int port, int index)
- {
-+ struct rtl8366rb *rb;
-+ bool pvid_enabled;
-+ int ret;
-+
-+ rb = smi->chip_data;
-+ pvid_enabled = !!index;
-+
- if (port >= smi->num_ports || index >= RTL8366RB_NUM_VLANS)
- return -EINVAL;
-
-- return regmap_update_bits(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port),
-+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port),
- RTL8366RB_PORT_VLAN_CTRL_MASK <<
- RTL8366RB_PORT_VLAN_CTRL_SHIFT(port),
- (index & RTL8366RB_PORT_VLAN_CTRL_MASK) <<
- RTL8366RB_PORT_VLAN_CTRL_SHIFT(port));
-+ if (ret)
-+ return ret;
-+
-+ rb->pvid_enabled[port] = pvid_enabled;
-+
-+ /* If VLAN filtering is enabled and PVID is also enabled, we must
-+ * not drop any untagged or C-tagged frames. Make sure to update the
-+ * filtering setting.
-+ */
-+ if (rb->vlan_filtering[port])
-+ ret = rtl8366rb_drop_untagged(smi, port, !pvid_enabled);
-+
-+ return ret;
- }
-
- static bool rtl8366rb_is_vlan_valid(struct realtek_smi *smi, unsigned int vlan)
-@@ -1437,7 +1525,7 @@ static bool rtl8366rb_is_vlan_valid(stru
- if (smi->vlan4k_enabled)
- max = RTL8366RB_NUM_VIDS - 1;
-
-- if (vlan == 0 || vlan > max)
-+ if (vlan > max)
- return false;
-
- return true;
-@@ -1594,7 +1682,7 @@ static const struct dsa_switch_ops rtl83
- .get_sset_count = rtl8366_get_sset_count,
- .port_bridge_join = rtl8366rb_port_bridge_join,
- .port_bridge_leave = rtl8366rb_port_bridge_leave,
-- .port_vlan_filtering = rtl8366_vlan_filtering,
-+ .port_vlan_filtering = rtl8366rb_vlan_filtering,
- .port_vlan_add = rtl8366_vlan_add,
- .port_vlan_del = rtl8366_vlan_del,
- .port_enable = rtl8366rb_port_enable,
diff --git a/target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch b/target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch
deleted file mode 100644
index b56032c366..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From ddb59a5dc42714999c335dab4bf256125ba3120c Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 26 Sep 2021 00:59:29 +0200
-Subject: [PATCH 06/11] net: dsa: rtl8366: Drop and depromote pointless prints
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We don't need a message for every VLAN association, dbg
-is fine. The message about adding the DSA or CPU
-port to a VLAN is directly misleading, this is perfectly
-fine.
-
-Cc: Vladimir Oltean <olteanv@gmail.com>
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Cc: DENG Qingfang <dqfext@gmail.com>
-Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/rtl8366.c | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/rtl8366.c
-+++ b/drivers/net/dsa/rtl8366.c
-@@ -318,12 +318,9 @@ int rtl8366_vlan_add(struct dsa_switch *
- return ret;
- }
-
-- dev_info(smi->dev, "add VLAN %d on port %d, %s, %s\n",
-- vlan->vid, port, untagged ? "untagged" : "tagged",
-- pvid ? " PVID" : "no PVID");
--
-- if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
-- dev_err(smi->dev, "port is DSA or CPU port\n");
-+ dev_dbg(smi->dev, "add VLAN %d on port %d, %s, %s\n",
-+ vlan->vid, port, untagged ? "untagged" : "tagged",
-+ pvid ? "PVID" : "no PVID");
-
- member |= BIT(port);
-
-@@ -356,7 +353,7 @@ int rtl8366_vlan_del(struct dsa_switch *
- struct realtek_smi *smi = ds->priv;
- int ret, i;
-
-- dev_info(smi->dev, "del VLAN %04x on port %d\n", vlan->vid, port);
-+ dev_dbg(smi->dev, "del VLAN %d on port %d\n", vlan->vid, port);
-
- for (i = 0; i < smi->num_vlan_mc; i++) {
- struct rtl8366_vlan_mc vlanmc;
diff --git a/target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch b/target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch
deleted file mode 100644
index 8cd1df97f2..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 5c9b66f3c8a3f72fa2a58e89a57c6d7afd550bf0 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 29 Sep 2021 13:23:22 +0200
-Subject: [PATCH 07/11] net: dsa: rtl8366rb: Use core filtering tracking
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We added a state variable to track whether a certain port
-was VLAN filtering or not, but we can just inquire the DSA
-core about this.
-
-Cc: Vladimir Oltean <olteanv@gmail.com>
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Cc: DENG Qingfang <dqfext@gmail.com>
-Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
-Cc: Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/rtl8366rb.c | 9 ++-------
- 1 file changed, 2 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/rtl8366rb.c
-+++ b/drivers/net/dsa/rtl8366rb.c
-@@ -337,12 +337,10 @@
- * struct rtl8366rb - RTL8366RB-specific data
- * @max_mtu: per-port max MTU setting
- * @pvid_enabled: if PVID is set for respective port
-- * @vlan_filtering: if VLAN filtering is enabled for respective port
- */
- struct rtl8366rb {
- unsigned int max_mtu[RTL8366RB_NUM_PORTS];
- bool pvid_enabled[RTL8366RB_NUM_PORTS];
-- bool vlan_filtering[RTL8366RB_NUM_PORTS];
- };
-
- static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
-@@ -1262,12 +1260,9 @@ static int rtl8366rb_vlan_filtering(stru
- if (ret)
- return ret;
-
-- /* Keep track if filtering is enabled on each port */
-- rb->vlan_filtering[port] = vlan_filtering;
--
- /* If VLAN filtering is enabled and PVID is also enabled, we must
- * not drop any untagged or C-tagged frames. If we turn off VLAN
-- * filtering on a port, we need ti accept any frames.
-+ * filtering on a port, we need to accept any frames.
- */
- if (vlan_filtering)
- ret = rtl8366rb_drop_untagged(smi, port, !rb->pvid_enabled[port]);
-@@ -1512,7 +1507,7 @@ static int rtl8366rb_set_mc_index(struct
- * not drop any untagged or C-tagged frames. Make sure to update the
- * filtering setting.
- */
-- if (rb->vlan_filtering[port])
-+ if (dsa_port_is_vlan_filtering(dsa_to_port(smi->ds, port)))
- ret = rtl8366rb_drop_untagged(smi, port, !pvid_enabled);
-
- return ret;
diff --git a/target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch b/target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch
deleted file mode 100644
index 8306eb5aef..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 831a3d26bea0d14f8563eecf96def660a74a3000 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Tue, 5 Oct 2021 21:47:02 +0200
-Subject: [PATCH 08/11] net: dsa: rtl8366rb: Support disabling learning
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The RTL8366RB hardware supports disabling learning per-port
-so let's make use of this feature. Rename some unfortunately
-named registers in the process.
-
-Suggested-by: Vladimir Oltean <olteanv@gmail.com>
-Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Cc: DENG Qingfang <dqfext@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/rtl8366rb.c | 50 ++++++++++++++++++++++++++++++++-----
- 1 file changed, 44 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/rtl8366rb.c
-+++ b/drivers/net/dsa/rtl8366rb.c
-@@ -14,6 +14,7 @@
-
- #include <linux/bitops.h>
- #include <linux/etherdevice.h>
-+#include <linux/if_bridge.h>
- #include <linux/interrupt.h>
- #include <linux/irqdomain.h>
- #include <linux/irqchip/chained_irq.h>
-@@ -42,9 +43,12 @@
- /* Port Enable Control register */
- #define RTL8366RB_PECR 0x0001
-
--/* Switch Security Control registers */
--#define RTL8366RB_SSCR0 0x0002
--#define RTL8366RB_SSCR1 0x0003
-+/* Switch per-port learning disablement register */
-+#define RTL8366RB_PORT_LEARNDIS_CTRL 0x0002
-+
-+/* Security control, actually aging register */
-+#define RTL8366RB_SECURITY_CTRL 0x0003
-+
- #define RTL8366RB_SSCR2 0x0004
- #define RTL8366RB_SSCR2_DROP_UNKNOWN_DA BIT(0)
-
-@@ -927,13 +931,14 @@ static int rtl8366rb_setup(struct dsa_sw
- /* layer 2 size, see rtl8366rb_change_mtu() */
- rb->max_mtu[i] = 1532;
-
-- /* Enable learning for all ports */
-- ret = regmap_write(smi->map, RTL8366RB_SSCR0, 0);
-+ /* Disable learning for all ports */
-+ ret = regmap_write(smi->map, RTL8366RB_PORT_LEARNDIS_CTRL,
-+ RTL8366RB_PORT_ALL);
- if (ret)
- return ret;
-
- /* Enable auto ageing for all ports */
-- ret = regmap_write(smi->map, RTL8366RB_SSCR1, 0);
-+ ret = regmap_write(smi->map, RTL8366RB_SECURITY_CTRL, 0);
- if (ret)
- return ret;
-
-@@ -1272,6 +1277,37 @@ static int rtl8366rb_vlan_filtering(stru
- return ret;
- }
-
-+static int
-+rtl8366rb_port_pre_bridge_flags(struct dsa_switch *ds, int port,
-+ struct switchdev_brport_flags flags,
-+ struct netlink_ext_ack *extack)
-+{
-+ /* We support enabling/disabling learning */
-+ if (flags.mask & ~(BR_LEARNING))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int
-+rtl8366rb_port_bridge_flags(struct dsa_switch *ds, int port,
-+ struct switchdev_brport_flags flags,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct realtek_smi *smi = ds->priv;
-+ int ret;
-+
-+ if (flags.mask & BR_LEARNING) {
-+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_LEARNDIS_CTRL,
-+ BIT(port),
-+ (flags.val & BR_LEARNING) ? 0 : BIT(port));
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct realtek_smi *smi = ds->priv;
-@@ -1682,6 +1718,8 @@ static const struct dsa_switch_ops rtl83
- .port_vlan_del = rtl8366_vlan_del,
- .port_enable = rtl8366rb_port_enable,
- .port_disable = rtl8366rb_port_disable,
-+ .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
-+ .port_bridge_flags = rtl8366rb_port_bridge_flags,
- .port_change_mtu = rtl8366rb_change_mtu,
- .port_max_mtu = rtl8366rb_max_mtu,
- };
diff --git a/target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch b/target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch
deleted file mode 100644
index a74108e23d..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 8eb13420eb9ab4a4e2ebd612bf5dc9dba0039236 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Tue, 5 Oct 2021 21:47:03 +0200
-Subject: [PATCH 09/11] net: dsa: rtl8366rb: Support fast aging
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This implements fast aging per-port using the special "security"
-register, which will flush any learned L2 LUT entries on a port.
-
-The vendor API just enabled setting and clearing this bit, so
-we set it to age out any entries on the port and then we clear
-it again.
-
-Suggested-by: Vladimir Oltean <olteanv@gmail.com>
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Cc: DENG Qingfang <dqfext@gmail.com>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/rtl8366rb.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/net/dsa/rtl8366rb.c
-+++ b/drivers/net/dsa/rtl8366rb.c
-@@ -1308,6 +1308,19 @@ rtl8366rb_port_bridge_flags(struct dsa_s
- return 0;
- }
-
-+static void
-+rtl8366rb_port_fast_age(struct dsa_switch *ds, int port)
-+{
-+ struct realtek_smi *smi = ds->priv;
-+
-+ /* This will age out any learned L2 entries */
-+ regmap_update_bits(smi->map, RTL8366RB_SECURITY_CTRL,
-+ BIT(port), BIT(port));
-+ /* Restore the normal state of things */
-+ regmap_update_bits(smi->map, RTL8366RB_SECURITY_CTRL,
-+ BIT(port), 0);
-+}
-+
- static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct realtek_smi *smi = ds->priv;
-@@ -1720,6 +1733,7 @@ static const struct dsa_switch_ops rtl83
- .port_disable = rtl8366rb_port_disable,
- .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
- .port_bridge_flags = rtl8366rb_port_bridge_flags,
-+ .port_fast_age = rtl8366rb_port_fast_age,
- .port_change_mtu = rtl8366rb_change_mtu,
- .port_max_mtu = rtl8366rb_max_mtu,
- };
diff --git a/target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch b/target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch
deleted file mode 100644
index e787ce9481..0000000000
--- a/target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 90c855471a89d3e05ecf5b6464bd04abf2c83b70 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Tue, 5 Oct 2021 21:47:04 +0200
-Subject: [PATCH 10/11] net: dsa: rtl8366rb: Support setting STP state
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds support for setting the STP state to the RTL8366RB
-DSA switch. This rids the following message from the kernel on
-e.g. OpenWrt:
-
-DSA: failed to set STP state 3 (-95)
-
-Since the RTL8366RB has one STP state register per FID with
-two bit per port in each, we simply loop over all the FIDs
-and set the state on all of them.
-
-Cc: Vladimir Oltean <olteanv@gmail.com>
-Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
-Cc: Mauri Sandberg <sandberg@mailfence.com>
-Cc: DENG Qingfang <dqfext@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/rtl8366rb.c | 48 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/dsa/rtl8366rb.c
-+++ b/drivers/net/dsa/rtl8366rb.c
-@@ -110,6 +110,18 @@
-
- #define RTL8366RB_POWER_SAVING_REG 0x0021
-
-+/* Spanning tree status (STP) control, two bits per port per FID */
-+#define RTL8366RB_STP_STATE_BASE 0x0050 /* 0x0050..0x0057 */
-+#define RTL8366RB_STP_STATE_DISABLED 0x0
-+#define RTL8366RB_STP_STATE_BLOCKING 0x1
-+#define RTL8366RB_STP_STATE_LEARNING 0x2
-+#define RTL8366RB_STP_STATE_FORWARDING 0x3
-+#define RTL8366RB_STP_MASK GENMASK(1, 0)
-+#define RTL8366RB_STP_STATE(port, state) \
-+ ((state) << ((port) * 2))
-+#define RTL8366RB_STP_STATE_MASK(port) \
-+ RTL8366RB_STP_STATE((port), RTL8366RB_STP_MASK)
-+
- /* CPU port control reg */
- #define RTL8368RB_CPU_CTRL_REG 0x0061
- #define RTL8368RB_CPU_PORTS_MSK 0x00FF
-@@ -234,6 +246,7 @@
- #define RTL8366RB_NUM_LEDGROUPS 4
- #define RTL8366RB_NUM_VIDS 4096
- #define RTL8366RB_PRIORITYMAX 7
-+#define RTL8366RB_NUM_FIDS 8
- #define RTL8366RB_FIDMAX 7
-
- #define RTL8366RB_PORT_1 BIT(0) /* In userspace port 0 */
-@@ -1309,6 +1322,40 @@ rtl8366rb_port_bridge_flags(struct dsa_s
- }
-
- static void
-+rtl8366rb_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-+{
-+ struct realtek_smi *smi = ds->priv;
-+ u32 val;
-+ int i;
-+
-+ switch (state) {
-+ case BR_STATE_DISABLED:
-+ val = RTL8366RB_STP_STATE_DISABLED;
-+ break;
-+ case BR_STATE_BLOCKING:
-+ case BR_STATE_LISTENING:
-+ val = RTL8366RB_STP_STATE_BLOCKING;
-+ break;
-+ case BR_STATE_LEARNING:
-+ val = RTL8366RB_STP_STATE_LEARNING;
-+ break;
-+ case BR_STATE_FORWARDING:
-+ val = RTL8366RB_STP_STATE_FORWARDING;
-+ break;
-+ default:
-+ dev_err(smi->dev, "unknown bridge state requested\n");
-+ return;
-+ };
-+
-+ /* Set the same status for the port on all the FIDs */
-+ for (i = 0; i < RTL8366RB_NUM_FIDS; i++) {
-+ regmap_update_bits(smi->map, RTL8366RB_STP_STATE_BASE + i,
-+ RTL8366RB_STP_STATE_MASK(port),
-+ RTL8366RB_STP_STATE(port, val));
-+ }
-+}
-+
-+static void
- rtl8366rb_port_fast_age(struct dsa_switch *ds, int port)
- {
- struct realtek_smi *smi = ds->priv;
-@@ -1733,6 +1780,7 @@ static const struct dsa_switch_ops rtl83
- .port_disable = rtl8366rb_port_disable,
- .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
- .port_bridge_flags = rtl8366rb_port_bridge_flags,
-+ .port_stp_state_set = rtl8366rb_port_stp_state_set,
- .port_fast_age = rtl8366rb_port_fast_age,
- .port_change_mtu = rtl8366rb_change_mtu,
- .port_max_mtu = rtl8366rb_max_mtu,
diff --git a/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch b/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch
deleted file mode 100644
index 43fc3b1523..0000000000
--- a/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From f9ec5723c3dbfcede9c7b0dcdf85e401ce16316c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 23 Jul 2022 16:29:29 +0200
-Subject: [PATCH 1/5] net: ethernet: stmicro: stmmac: move queue reset to
- dedicated functions
-
-Move queue reset to dedicated functions. This aside from a simple
-cleanup is also required to allocate a dma conf without resetting the tx
-queue while the device is temporarily detached as now the reset is not
-part of the dma init function and can be done later in the code flow.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 59 ++++++++++---------
- 1 file changed, 31 insertions(+), 28 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -130,6 +130,9 @@ static irqreturn_t stmmac_mac_interrupt(
- static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id);
- static irqreturn_t stmmac_msi_intr_tx(int irq, void *data);
- static irqreturn_t stmmac_msi_intr_rx(int irq, void *data);
-+static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue);
-+static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue);
-+static void stmmac_reset_queues_param(struct stmmac_priv *priv);
- static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue);
- static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue);
-
-@@ -1713,9 +1716,6 @@ static int __init_dma_rx_desc_rings(stru
- return -ENOMEM;
- }
-
-- rx_q->cur_rx = 0;
-- rx_q->dirty_rx = 0;
--
- /* Setup the chained descriptor addresses */
- if (priv->mode == STMMAC_CHAIN_MODE) {
- if (priv->extend_desc)
-@@ -1821,12 +1821,6 @@ static int __init_dma_tx_desc_rings(stru
- tx_q->tx_skbuff[i] = NULL;
- }
-
-- tx_q->dirty_tx = 0;
-- tx_q->cur_tx = 0;
-- tx_q->mss = 0;
--
-- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
--
- return 0;
- }
-
-@@ -2695,10 +2689,7 @@ static void stmmac_tx_err(struct stmmac_
- stmmac_stop_tx_dma(priv, chan);
- dma_free_tx_skbufs(priv, chan);
- stmmac_clear_tx_descriptors(priv, chan);
-- tx_q->dirty_tx = 0;
-- tx_q->cur_tx = 0;
-- tx_q->mss = 0;
-- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, chan));
-+ stmmac_reset_tx_queue(priv, chan);
- stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- tx_q->dma_tx_phy, chan);
- stmmac_start_tx_dma(priv, chan);
-@@ -3783,6 +3774,8 @@ static int stmmac_open(struct net_device
- }
- }
-
-+ stmmac_reset_queues_param(priv);
-+
- ret = stmmac_hw_setup(dev, true);
- if (ret < 0) {
- netdev_err(priv->dev, "%s: Hw setup failed\n", __func__);
-@@ -6412,6 +6405,7 @@ void stmmac_enable_rx_queue(struct stmma
- return;
- }
-
-+ stmmac_reset_rx_queue(priv, queue);
- stmmac_clear_rx_descriptors(priv, queue);
-
- stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
-@@ -6473,6 +6467,7 @@ void stmmac_enable_tx_queue(struct stmma
- return;
- }
-
-+ stmmac_reset_tx_queue(priv, queue);
- stmmac_clear_tx_descriptors(priv, queue);
-
- stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
-@@ -7400,6 +7395,25 @@ int stmmac_suspend(struct device *dev)
- }
- EXPORT_SYMBOL_GPL(stmmac_suspend);
-
-+static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue)
-+{
-+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+
-+ rx_q->cur_rx = 0;
-+ rx_q->dirty_rx = 0;
-+}
-+
-+static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue)
-+{
-+ struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+
-+ tx_q->cur_tx = 0;
-+ tx_q->dirty_tx = 0;
-+ tx_q->mss = 0;
-+
-+ netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
-+}
-+
- /**
- * stmmac_reset_queues_param - reset queue parameters
- * @priv: device pointer
-@@ -7410,22 +7424,11 @@ static void stmmac_reset_queues_param(st
- u32 tx_cnt = priv->plat->tx_queues_to_use;
- u32 queue;
-
-- for (queue = 0; queue < rx_cnt; queue++) {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ for (queue = 0; queue < rx_cnt; queue++)
-+ stmmac_reset_rx_queue(priv, queue);
-
-- rx_q->cur_rx = 0;
-- rx_q->dirty_rx = 0;
-- }
--
-- for (queue = 0; queue < tx_cnt; queue++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
--
-- tx_q->cur_tx = 0;
-- tx_q->dirty_tx = 0;
-- tx_q->mss = 0;
--
-- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
-- }
-+ for (queue = 0; queue < tx_cnt; queue++)
-+ stmmac_reset_tx_queue(priv, queue);
- }
-
- /**
diff --git a/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch b/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch
deleted file mode 100644
index 0940d3d799..0000000000
--- a/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 7028471edb646bfc532fec0973e50e784cdcb7c6 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 23 Jul 2022 16:29:30 +0200
-Subject: [PATCH 2/5] net: ethernet: stmicro: stmmac: first disable all queues
- and disconnect in release
-
-Disable all queues and disconnect before tx_disable in stmmac_release to
-prevent a corner case where packet may be still queued at the same time
-tx_disable is called resulting in kernel panic if some packet still has
-to be processed.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -3837,8 +3837,6 @@ static int stmmac_release(struct net_dev
- struct stmmac_priv *priv = netdev_priv(dev);
- u32 chan;
-
-- netif_tx_disable(dev);
--
- if (device_may_wakeup(priv->device))
- phylink_speed_down(priv->phylink, false);
- /* Stop and disconnect the PHY */
-@@ -3850,6 +3848,8 @@ static int stmmac_release(struct net_dev
- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
- hrtimer_cancel(&priv->tx_queue[chan].txtimer);
-
-+ netif_tx_disable(dev);
-+
- /* Free the IRQ lines */
- stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0);
-
diff --git a/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch b/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch
deleted file mode 100644
index 1b5a8a700b..0000000000
--- a/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch
+++ /dev/null
@@ -1,1289 +0,0 @@
-From 8531c80800c10e8ef7952022326c2f983e1314bf Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 23 Jul 2022 16:29:31 +0200
-Subject: [PATCH 3/5] net: ethernet: stmicro: stmmac: move dma conf to
- dedicated struct
-
-Move dma buf conf to dedicated struct. This in preparation for code
-rework that will permit to allocate separate dma_conf without affecting
-the priv struct.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/stmicro/stmmac/chain_mode.c | 6 +-
- .../net/ethernet/stmicro/stmmac/ring_mode.c | 4 +-
- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 21 +-
- .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 4 +-
- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 286 +++++++++---------
- .../stmicro/stmmac/stmmac_selftests.c | 8 +-
- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 6 +-
- 7 files changed, 172 insertions(+), 163 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
-@@ -46,7 +46,7 @@ static int jumbo_frm(void *p, struct sk_
-
- while (len != 0) {
- tx_q->tx_skbuff[entry] = NULL;
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
- desc = tx_q->dma_tx + entry;
-
- if (len > bmax) {
-@@ -137,7 +137,7 @@ static void refill_desc3(void *priv_ptr,
- */
- p->des3 = cpu_to_le32((unsigned int)(rx_q->dma_rx_phy +
- (((rx_q->dirty_rx) + 1) %
-- priv->dma_rx_size) *
-+ priv->dma_conf.dma_rx_size) *
- sizeof(struct dma_desc)));
- }
-
-@@ -155,7 +155,7 @@ static void clean_desc3(void *priv_ptr,
- */
- p->des3 = cpu_to_le32((unsigned int)((tx_q->dma_tx_phy +
- ((tx_q->dirty_tx + 1) %
-- priv->dma_tx_size))
-+ priv->dma_conf.dma_tx_size))
- * sizeof(struct dma_desc)));
- }
-
---- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
-@@ -51,7 +51,7 @@ static int jumbo_frm(void *p, struct sk_
- stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum,
- STMMAC_RING_MODE, 0, false, skb->len);
- tx_q->tx_skbuff[entry] = NULL;
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
-
- if (priv->extend_desc)
- desc = (struct dma_desc *)(tx_q->dma_etx + entry);
-@@ -107,7 +107,7 @@ static void refill_desc3(void *priv_ptr,
- struct stmmac_priv *priv = rx_q->priv_data;
-
- /* Fill DES3 in case of RING mode */
-- if (priv->dma_buf_sz == BUF_SIZE_16KiB)
-+ if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB)
- p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB);
- }
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-@@ -185,6 +185,18 @@ struct stmmac_rfs_entry {
- int tc;
- };
-
-+struct stmmac_dma_conf {
-+ unsigned int dma_buf_sz;
-+
-+ /* RX Queue */
-+ struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES];
-+ unsigned int dma_rx_size;
-+
-+ /* TX Queue */
-+ struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
-+ unsigned int dma_tx_size;
-+};
-+
- struct stmmac_priv {
- /* Frequently used values are kept adjacent for cache effect */
- u32 tx_coal_frames[MTL_MAX_TX_QUEUES];
-@@ -199,7 +211,6 @@ struct stmmac_priv {
- int sph_cap;
- u32 sarc_type;
-
-- unsigned int dma_buf_sz;
- unsigned int rx_copybreak;
- u32 rx_riwt[MTL_MAX_TX_QUEUES];
- int hwts_rx_en;
-@@ -211,13 +222,7 @@ struct stmmac_priv {
- int (*hwif_quirks)(struct stmmac_priv *priv);
- struct mutex lock;
-
-- /* RX Queue */
-- struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES];
-- unsigned int dma_rx_size;
--
-- /* TX Queue */
-- struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
-- unsigned int dma_tx_size;
-+ struct stmmac_dma_conf dma_conf;
-
- /* Generic channel for NAPI */
- struct stmmac_channel channel[STMMAC_CH_MAX];
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
-@@ -484,8 +484,8 @@ static void stmmac_get_ringparam(struct
-
- ring->rx_max_pending = DMA_MAX_RX_SIZE;
- ring->tx_max_pending = DMA_MAX_TX_SIZE;
-- ring->rx_pending = priv->dma_rx_size;
-- ring->tx_pending = priv->dma_tx_size;
-+ ring->rx_pending = priv->dma_conf.dma_rx_size;
-+ ring->tx_pending = priv->dma_conf.dma_tx_size;
- }
-
- static int stmmac_set_ringparam(struct net_device *netdev,
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -74,8 +74,8 @@ static int phyaddr = -1;
- module_param(phyaddr, int, 0444);
- MODULE_PARM_DESC(phyaddr, "Physical device address");
-
--#define STMMAC_TX_THRESH(x) ((x)->dma_tx_size / 4)
--#define STMMAC_RX_THRESH(x) ((x)->dma_rx_size / 4)
-+#define STMMAC_TX_THRESH(x) ((x)->dma_conf.dma_tx_size / 4)
-+#define STMMAC_RX_THRESH(x) ((x)->dma_conf.dma_rx_size / 4)
-
- /* Limit to make sure XDP TX and slow path can coexist */
- #define STMMAC_XSK_TX_BUDGET_MAX 256
-@@ -232,7 +232,7 @@ static void stmmac_disable_all_queues(st
-
- /* synchronize_rcu() needed for pending XDP buffers to drain */
- for (queue = 0; queue < rx_queues_cnt; queue++) {
-- rx_q = &priv->rx_queue[queue];
-+ rx_q = &priv->dma_conf.rx_queue[queue];
- if (rx_q->xsk_pool) {
- synchronize_rcu();
- break;
-@@ -358,13 +358,13 @@ static void print_pkt(unsigned char *buf
-
- static inline u32 stmmac_tx_avail(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- u32 avail;
-
- if (tx_q->dirty_tx > tx_q->cur_tx)
- avail = tx_q->dirty_tx - tx_q->cur_tx - 1;
- else
-- avail = priv->dma_tx_size - tx_q->cur_tx + tx_q->dirty_tx - 1;
-+ avail = priv->dma_conf.dma_tx_size - tx_q->cur_tx + tx_q->dirty_tx - 1;
-
- return avail;
- }
-@@ -376,13 +376,13 @@ static inline u32 stmmac_tx_avail(struct
- */
- static inline u32 stmmac_rx_dirty(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- u32 dirty;
-
- if (rx_q->dirty_rx <= rx_q->cur_rx)
- dirty = rx_q->cur_rx - rx_q->dirty_rx;
- else
-- dirty = priv->dma_rx_size - rx_q->dirty_rx + rx_q->cur_rx;
-+ dirty = priv->dma_conf.dma_rx_size - rx_q->dirty_rx + rx_q->cur_rx;
-
- return dirty;
- }
-@@ -410,7 +410,7 @@ static int stmmac_enable_eee_mode(struct
-
- /* check if all TX queues have the work finished */
- for (queue = 0; queue < tx_cnt; queue++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-
- if (tx_q->dirty_tx != tx_q->cur_tx)
- return -EBUSY; /* still unfinished work */
-@@ -1310,7 +1310,7 @@ static void stmmac_display_rx_rings(stru
-
- /* Display RX rings */
- for (queue = 0; queue < rx_cnt; queue++) {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-
- pr_info("\tRX Queue %u rings\n", queue);
-
-@@ -1323,7 +1323,7 @@ static void stmmac_display_rx_rings(stru
- }
-
- /* Display RX ring */
-- stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true,
-+ stmmac_display_ring(priv, head_rx, priv->dma_conf.dma_rx_size, true,
- rx_q->dma_rx_phy, desc_size);
- }
- }
-@@ -1337,7 +1337,7 @@ static void stmmac_display_tx_rings(stru
-
- /* Display TX rings */
- for (queue = 0; queue < tx_cnt; queue++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-
- pr_info("\tTX Queue %d rings\n", queue);
-
-@@ -1352,7 +1352,7 @@ static void stmmac_display_tx_rings(stru
- desc_size = sizeof(struct dma_desc);
- }
-
-- stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false,
-+ stmmac_display_ring(priv, head_tx, priv->dma_conf.dma_tx_size, false,
- tx_q->dma_tx_phy, desc_size);
- }
- }
-@@ -1393,21 +1393,21 @@ static int stmmac_set_bfsize(int mtu, in
- */
- static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int i;
-
- /* Clear the RX descriptors */
-- for (i = 0; i < priv->dma_rx_size; i++)
-+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++)
- if (priv->extend_desc)
- stmmac_init_rx_desc(priv, &rx_q->dma_erx[i].basic,
- priv->use_riwt, priv->mode,
-- (i == priv->dma_rx_size - 1),
-- priv->dma_buf_sz);
-+ (i == priv->dma_conf.dma_rx_size - 1),
-+ priv->dma_conf.dma_buf_sz);
- else
- stmmac_init_rx_desc(priv, &rx_q->dma_rx[i],
- priv->use_riwt, priv->mode,
-- (i == priv->dma_rx_size - 1),
-- priv->dma_buf_sz);
-+ (i == priv->dma_conf.dma_rx_size - 1),
-+ priv->dma_conf.dma_buf_sz);
- }
-
- /**
-@@ -1419,12 +1419,12 @@ static void stmmac_clear_rx_descriptors(
- */
- static void stmmac_clear_tx_descriptors(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- int i;
-
- /* Clear the TX descriptors */
-- for (i = 0; i < priv->dma_tx_size; i++) {
-- int last = (i == (priv->dma_tx_size - 1));
-+ for (i = 0; i < priv->dma_conf.dma_tx_size; i++) {
-+ int last = (i == (priv->dma_conf.dma_tx_size - 1));
- struct dma_desc *p;
-
- if (priv->extend_desc)
-@@ -1472,7 +1472,7 @@ static void stmmac_clear_descriptors(str
- static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
- int i, gfp_t flags, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-
- if (!buf->page) {
-@@ -1497,7 +1497,7 @@ static int stmmac_init_rx_buffers(struct
- buf->addr = page_pool_get_dma_addr(buf->page) + buf->page_offset;
-
- stmmac_set_desc_addr(priv, p, buf->addr);
-- if (priv->dma_buf_sz == BUF_SIZE_16KiB)
-+ if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB)
- stmmac_init_desc3(priv, p);
-
- return 0;
-@@ -1511,7 +1511,7 @@ static int stmmac_init_rx_buffers(struct
- */
- static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-
- if (buf->page)
-@@ -1531,7 +1531,7 @@ static void stmmac_free_rx_buffer(struct
- */
- static void stmmac_free_tx_buffer(struct stmmac_priv *priv, u32 queue, int i)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-
- if (tx_q->tx_skbuff_dma[i].buf &&
- tx_q->tx_skbuff_dma[i].buf_type != STMMAC_TXBUF_T_XDP_TX) {
-@@ -1576,17 +1576,17 @@ static void dma_free_rx_skbufs(struct st
- {
- int i;
-
-- for (i = 0; i < priv->dma_rx_size; i++)
-+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++)
- stmmac_free_rx_buffer(priv, queue, i);
- }
-
- static int stmmac_alloc_rx_buffers(struct stmmac_priv *priv, u32 queue,
- gfp_t flags)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int i;
-
-- for (i = 0; i < priv->dma_rx_size; i++) {
-+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) {
- struct dma_desc *p;
- int ret;
-
-@@ -1613,10 +1613,10 @@ static int stmmac_alloc_rx_buffers(struc
- */
- static void dma_free_rx_xskbufs(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int i;
-
-- for (i = 0; i < priv->dma_rx_size; i++) {
-+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) {
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-
- if (!buf->xdp)
-@@ -1629,10 +1629,10 @@ static void dma_free_rx_xskbufs(struct s
-
- static int stmmac_alloc_rx_buffers_zc(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int i;
-
-- for (i = 0; i < priv->dma_rx_size; i++) {
-+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) {
- struct stmmac_rx_buffer *buf;
- dma_addr_t dma_addr;
- struct dma_desc *p;
-@@ -1675,7 +1675,7 @@ static struct xsk_buff_pool *stmmac_get_
- */
- static int __init_dma_rx_desc_rings(struct stmmac_priv *priv, u32 queue, gfp_t flags)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int ret;
-
- netif_dbg(priv, probe, priv->dev,
-@@ -1721,11 +1721,11 @@ static int __init_dma_rx_desc_rings(stru
- if (priv->extend_desc)
- stmmac_mode_init(priv, rx_q->dma_erx,
- rx_q->dma_rx_phy,
-- priv->dma_rx_size, 1);
-+ priv->dma_conf.dma_rx_size, 1);
- else
- stmmac_mode_init(priv, rx_q->dma_rx,
- rx_q->dma_rx_phy,
-- priv->dma_rx_size, 0);
-+ priv->dma_conf.dma_rx_size, 0);
- }
-
- return 0;
-@@ -1752,7 +1752,7 @@ static int init_dma_rx_desc_rings(struct
-
- err_init_rx_buffers:
- while (queue >= 0) {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-
- if (rx_q->xsk_pool)
- dma_free_rx_xskbufs(priv, queue);
-@@ -1781,7 +1781,7 @@ err_init_rx_buffers:
- */
- static int __init_dma_tx_desc_rings(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- int i;
-
- netif_dbg(priv, probe, priv->dev,
-@@ -1793,16 +1793,16 @@ static int __init_dma_tx_desc_rings(stru
- if (priv->extend_desc)
- stmmac_mode_init(priv, tx_q->dma_etx,
- tx_q->dma_tx_phy,
-- priv->dma_tx_size, 1);
-+ priv->dma_conf.dma_tx_size, 1);
- else if (!(tx_q->tbs & STMMAC_TBS_AVAIL))
- stmmac_mode_init(priv, tx_q->dma_tx,
- tx_q->dma_tx_phy,
-- priv->dma_tx_size, 0);
-+ priv->dma_conf.dma_tx_size, 0);
- }
-
- tx_q->xsk_pool = stmmac_get_xsk_pool(priv, queue);
-
-- for (i = 0; i < priv->dma_tx_size; i++) {
-+ for (i = 0; i < priv->dma_conf.dma_tx_size; i++) {
- struct dma_desc *p;
-
- if (priv->extend_desc)
-@@ -1872,12 +1872,12 @@ static int init_dma_desc_rings(struct ne
- */
- static void dma_free_tx_skbufs(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- int i;
-
- tx_q->xsk_frames_done = 0;
-
-- for (i = 0; i < priv->dma_tx_size; i++)
-+ for (i = 0; i < priv->dma_conf.dma_tx_size; i++)
- stmmac_free_tx_buffer(priv, queue, i);
-
- if (tx_q->xsk_pool && tx_q->xsk_frames_done) {
-@@ -1907,7 +1907,7 @@ static void stmmac_free_tx_skbufs(struct
- */
- static void __free_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-
- /* Release the DMA RX socket buffers */
- if (rx_q->xsk_pool)
-@@ -1920,11 +1920,11 @@ static void __free_dma_rx_desc_resources
-
- /* Free DMA regions of consistent memory previously allocated */
- if (!priv->extend_desc)
-- dma_free_coherent(priv->device, priv->dma_rx_size *
-+ dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size *
- sizeof(struct dma_desc),
- rx_q->dma_rx, rx_q->dma_rx_phy);
- else
-- dma_free_coherent(priv->device, priv->dma_rx_size *
-+ dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size *
- sizeof(struct dma_extended_desc),
- rx_q->dma_erx, rx_q->dma_rx_phy);
-
-@@ -1953,7 +1953,7 @@ static void free_dma_rx_desc_resources(s
- */
- static void __free_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- size_t size;
- void *addr;
-
-@@ -1971,7 +1971,7 @@ static void __free_dma_tx_desc_resources
- addr = tx_q->dma_tx;
- }
-
-- size *= priv->dma_tx_size;
-+ size *= priv->dma_conf.dma_tx_size;
-
- dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy);
-
-@@ -2000,7 +2000,7 @@ static void free_dma_tx_desc_resources(s
- */
- static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- struct stmmac_channel *ch = &priv->channel[queue];
- bool xdp_prog = stmmac_xdp_is_enabled(priv);
- struct page_pool_params pp_params = { 0 };
-@@ -2012,8 +2012,8 @@ static int __alloc_dma_rx_desc_resources
- rx_q->priv_data = priv;
-
- pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
-- pp_params.pool_size = priv->dma_rx_size;
-- num_pages = DIV_ROUND_UP(priv->dma_buf_sz, PAGE_SIZE);
-+ pp_params.pool_size = priv->dma_conf.dma_rx_size;
-+ num_pages = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE);
- pp_params.order = ilog2(num_pages);
- pp_params.nid = dev_to_node(priv->device);
- pp_params.dev = priv->device;
-@@ -2028,7 +2028,7 @@ static int __alloc_dma_rx_desc_resources
- return ret;
- }
-
-- rx_q->buf_pool = kcalloc(priv->dma_rx_size,
-+ rx_q->buf_pool = kcalloc(priv->dma_conf.dma_rx_size,
- sizeof(*rx_q->buf_pool),
- GFP_KERNEL);
- if (!rx_q->buf_pool)
-@@ -2036,7 +2036,7 @@ static int __alloc_dma_rx_desc_resources
-
- if (priv->extend_desc) {
- rx_q->dma_erx = dma_alloc_coherent(priv->device,
-- priv->dma_rx_size *
-+ priv->dma_conf.dma_rx_size *
- sizeof(struct dma_extended_desc),
- &rx_q->dma_rx_phy,
- GFP_KERNEL);
-@@ -2045,7 +2045,7 @@ static int __alloc_dma_rx_desc_resources
-
- } else {
- rx_q->dma_rx = dma_alloc_coherent(priv->device,
-- priv->dma_rx_size *
-+ priv->dma_conf.dma_rx_size *
- sizeof(struct dma_desc),
- &rx_q->dma_rx_phy,
- GFP_KERNEL);
-@@ -2102,20 +2102,20 @@ err_dma:
- */
- static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- size_t size;
- void *addr;
-
- tx_q->queue_index = queue;
- tx_q->priv_data = priv;
-
-- tx_q->tx_skbuff_dma = kcalloc(priv->dma_tx_size,
-+ tx_q->tx_skbuff_dma = kcalloc(priv->dma_conf.dma_tx_size,
- sizeof(*tx_q->tx_skbuff_dma),
- GFP_KERNEL);
- if (!tx_q->tx_skbuff_dma)
- return -ENOMEM;
-
-- tx_q->tx_skbuff = kcalloc(priv->dma_tx_size,
-+ tx_q->tx_skbuff = kcalloc(priv->dma_conf.dma_tx_size,
- sizeof(struct sk_buff *),
- GFP_KERNEL);
- if (!tx_q->tx_skbuff)
-@@ -2128,7 +2128,7 @@ static int __alloc_dma_tx_desc_resources
- else
- size = sizeof(struct dma_desc);
-
-- size *= priv->dma_tx_size;
-+ size *= priv->dma_conf.dma_tx_size;
-
- addr = dma_alloc_coherent(priv->device, size,
- &tx_q->dma_tx_phy, GFP_KERNEL);
-@@ -2372,7 +2372,7 @@ static void stmmac_dma_operation_mode(st
-
- /* configure all channels */
- for (chan = 0; chan < rx_channels_count; chan++) {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan];
- u32 buf_size;
-
- qmode = priv->plat->rx_queues_cfg[chan].mode_to_use;
-@@ -2387,7 +2387,7 @@ static void stmmac_dma_operation_mode(st
- chan);
- } else {
- stmmac_set_dma_bfsize(priv, priv->ioaddr,
-- priv->dma_buf_sz,
-+ priv->dma_conf.dma_buf_sz,
- chan);
- }
- }
-@@ -2403,7 +2403,7 @@ static void stmmac_dma_operation_mode(st
- static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
- {
- struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- struct xsk_buff_pool *pool = tx_q->xsk_pool;
- unsigned int entry = tx_q->cur_tx;
- struct dma_desc *tx_desc = NULL;
-@@ -2478,7 +2478,7 @@ static bool stmmac_xdp_xmit_zc(struct st
-
- stmmac_enable_dma_transmission(priv, priv->ioaddr);
-
-- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_tx_size);
-+ tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
- entry = tx_q->cur_tx;
- }
-
-@@ -2504,7 +2504,7 @@ static bool stmmac_xdp_xmit_zc(struct st
- */
- static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- unsigned int bytes_compl = 0, pkts_compl = 0;
- unsigned int entry, xmits = 0, count = 0;
-
-@@ -2517,7 +2517,7 @@ static int stmmac_tx_clean(struct stmmac
- entry = tx_q->dirty_tx;
-
- /* Try to clean all TX complete frame in 1 shot */
-- while ((entry != tx_q->cur_tx) && count < priv->dma_tx_size) {
-+ while ((entry != tx_q->cur_tx) && count < priv->dma_conf.dma_tx_size) {
- struct xdp_frame *xdpf;
- struct sk_buff *skb;
- struct dma_desc *p;
-@@ -2617,7 +2617,7 @@ static int stmmac_tx_clean(struct stmmac
-
- stmmac_release_tx_desc(priv, p, priv->mode);
-
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
- }
- tx_q->dirty_tx = entry;
-
-@@ -2682,7 +2682,7 @@ static int stmmac_tx_clean(struct stmmac
- */
- static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-
- netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, chan));
-
-@@ -2749,8 +2749,8 @@ static int stmmac_napi_check(struct stmm
- {
- int status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
- &priv->xstats, chan, dir);
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan];
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
- struct stmmac_channel *ch = &priv->channel[chan];
- struct napi_struct *rx_napi;
- struct napi_struct *tx_napi;
-@@ -2926,7 +2926,7 @@ static int stmmac_init_dma_engine(struct
-
- /* DMA RX Channel Configuration */
- for (chan = 0; chan < rx_channels_count; chan++) {
-- rx_q = &priv->rx_queue[chan];
-+ rx_q = &priv->dma_conf.rx_queue[chan];
-
- stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- rx_q->dma_rx_phy, chan);
-@@ -2940,7 +2940,7 @@ static int stmmac_init_dma_engine(struct
-
- /* DMA TX Channel Configuration */
- for (chan = 0; chan < tx_channels_count; chan++) {
-- tx_q = &priv->tx_queue[chan];
-+ tx_q = &priv->dma_conf.tx_queue[chan];
-
- stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- tx_q->dma_tx_phy, chan);
-@@ -2955,7 +2955,7 @@ static int stmmac_init_dma_engine(struct
-
- static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-
- hrtimer_start(&tx_q->txtimer,
- STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]),
-@@ -3005,7 +3005,7 @@ static void stmmac_init_coalesce(struct
- u32 chan;
-
- for (chan = 0; chan < tx_channel_count; chan++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-
- priv->tx_coal_frames[chan] = STMMAC_TX_FRAMES;
- priv->tx_coal_timer[chan] = STMMAC_COAL_TX_TIMER;
-@@ -3027,12 +3027,12 @@ static void stmmac_set_rings_length(stru
- /* set TX ring length */
- for (chan = 0; chan < tx_channels_count; chan++)
- stmmac_set_tx_ring_len(priv, priv->ioaddr,
-- (priv->dma_tx_size - 1), chan);
-+ (priv->dma_conf.dma_tx_size - 1), chan);
-
- /* set RX ring length */
- for (chan = 0; chan < rx_channels_count; chan++)
- stmmac_set_rx_ring_len(priv, priv->ioaddr,
-- (priv->dma_rx_size - 1), chan);
-+ (priv->dma_conf.dma_rx_size - 1), chan);
- }
-
- /**
-@@ -3367,7 +3367,7 @@ static int stmmac_hw_setup(struct net_de
- /* Enable TSO */
- if (priv->tso) {
- for (chan = 0; chan < tx_cnt; chan++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-
- /* TSO and TBS cannot co-exist */
- if (tx_q->tbs & STMMAC_TBS_AVAIL)
-@@ -3389,7 +3389,7 @@ static int stmmac_hw_setup(struct net_de
-
- /* TBS */
- for (chan = 0; chan < tx_cnt; chan++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
- int enable = tx_q->tbs & STMMAC_TBS_AVAIL;
-
- stmmac_enable_tbs(priv, priv->ioaddr, enable, chan);
-@@ -3433,7 +3433,7 @@ static void stmmac_free_irq(struct net_d
- for (j = irq_idx - 1; j >= 0; j--) {
- if (priv->tx_irq[j] > 0) {
- irq_set_affinity_hint(priv->tx_irq[j], NULL);
-- free_irq(priv->tx_irq[j], &priv->tx_queue[j]);
-+ free_irq(priv->tx_irq[j], &priv->dma_conf.tx_queue[j]);
- }
- }
- irq_idx = priv->plat->rx_queues_to_use;
-@@ -3442,7 +3442,7 @@ static void stmmac_free_irq(struct net_d
- for (j = irq_idx - 1; j >= 0; j--) {
- if (priv->rx_irq[j] > 0) {
- irq_set_affinity_hint(priv->rx_irq[j], NULL);
-- free_irq(priv->rx_irq[j], &priv->rx_queue[j]);
-+ free_irq(priv->rx_irq[j], &priv->dma_conf.rx_queue[j]);
- }
- }
-
-@@ -3576,7 +3576,7 @@ static int stmmac_request_irq_multi_msi(
- sprintf(int_name, "%s:%s-%d", dev->name, "rx", i);
- ret = request_irq(priv->rx_irq[i],
- stmmac_msi_intr_rx,
-- 0, int_name, &priv->rx_queue[i]);
-+ 0, int_name, &priv->dma_conf.rx_queue[i]);
- if (unlikely(ret < 0)) {
- netdev_err(priv->dev,
- "%s: alloc rx-%d MSI %d (error: %d)\n",
-@@ -3599,7 +3599,7 @@ static int stmmac_request_irq_multi_msi(
- sprintf(int_name, "%s:%s-%d", dev->name, "tx", i);
- ret = request_irq(priv->tx_irq[i],
- stmmac_msi_intr_tx,
-- 0, int_name, &priv->tx_queue[i]);
-+ 0, int_name, &priv->dma_conf.tx_queue[i]);
- if (unlikely(ret < 0)) {
- netdev_err(priv->dev,
- "%s: alloc tx-%d MSI %d (error: %d)\n",
-@@ -3730,21 +3730,21 @@ static int stmmac_open(struct net_device
- bfsize = 0;
-
- if (bfsize < BUF_SIZE_16KiB)
-- bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
-+ bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_conf.dma_buf_sz);
-
-- priv->dma_buf_sz = bfsize;
-+ priv->dma_conf.dma_buf_sz = bfsize;
- buf_sz = bfsize;
-
- priv->rx_copybreak = STMMAC_RX_COPYBREAK;
-
-- if (!priv->dma_tx_size)
-- priv->dma_tx_size = DMA_DEFAULT_TX_SIZE;
-- if (!priv->dma_rx_size)
-- priv->dma_rx_size = DMA_DEFAULT_RX_SIZE;
-+ if (!priv->dma_conf.dma_tx_size)
-+ priv->dma_conf.dma_tx_size = DMA_DEFAULT_TX_SIZE;
-+ if (!priv->dma_conf.dma_rx_size)
-+ priv->dma_conf.dma_rx_size = DMA_DEFAULT_RX_SIZE;
-
- /* Earlier check for TBS */
- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
- int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en;
-
- /* Setup per-TXQ tbs flag before TX descriptor alloc */
-@@ -3802,7 +3802,7 @@ irq_error:
- phylink_stop(priv->phylink);
-
- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
-- hrtimer_cancel(&priv->tx_queue[chan].txtimer);
-+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
-
- stmmac_hw_teardown(dev);
- init_error:
-@@ -3846,7 +3846,7 @@ static int stmmac_release(struct net_dev
- stmmac_disable_all_queues(priv);
-
- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
-- hrtimer_cancel(&priv->tx_queue[chan].txtimer);
-+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
-
- netif_tx_disable(dev);
-
-@@ -3910,7 +3910,7 @@ static bool stmmac_vlan_insert(struct st
- return false;
-
- stmmac_set_tx_owner(priv, p);
-- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_tx_size);
-+ tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
- return true;
- }
-
-@@ -3928,7 +3928,7 @@ static bool stmmac_vlan_insert(struct st
- static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des,
- int total_len, bool last_segment, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- struct dma_desc *desc;
- u32 buff_size;
- int tmp_len;
-@@ -3939,7 +3939,7 @@ static void stmmac_tso_allocator(struct
- dma_addr_t curr_addr;
-
- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx,
-- priv->dma_tx_size);
-+ priv->dma_conf.dma_tx_size);
- WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
-
- if (tx_q->tbs & STMMAC_TBS_AVAIL)
-@@ -3967,7 +3967,7 @@ static void stmmac_tso_allocator(struct
-
- static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- int desc_size;
-
- if (likely(priv->extend_desc))
-@@ -4029,7 +4029,7 @@ static netdev_tx_t stmmac_tso_xmit(struc
- dma_addr_t des;
- int i;
-
-- tx_q = &priv->tx_queue[queue];
-+ tx_q = &priv->dma_conf.tx_queue[queue];
- first_tx = tx_q->cur_tx;
-
- /* Compute header lengths */
-@@ -4069,7 +4069,7 @@ static netdev_tx_t stmmac_tso_xmit(struc
- stmmac_set_mss(priv, mss_desc, mss);
- tx_q->mss = mss;
- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx,
-- priv->dma_tx_size);
-+ priv->dma_conf.dma_tx_size);
- WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
- }
-
-@@ -4181,7 +4181,7 @@ static netdev_tx_t stmmac_tso_xmit(struc
- * ndo_start_xmit will fill this descriptor the next time it's
- * called and stmmac_tx_clean may clean up to this descriptor.
- */
-- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_tx_size);
-+ tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
-
- if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) {
- netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n",
-@@ -4269,7 +4269,7 @@ static netdev_tx_t stmmac_xmit(struct sk
- int entry, first_tx;
- dma_addr_t des;
-
-- tx_q = &priv->tx_queue[queue];
-+ tx_q = &priv->dma_conf.tx_queue[queue];
- first_tx = tx_q->cur_tx;
-
- if (priv->tx_path_in_lpi_mode && priv->eee_sw_timer_en)
-@@ -4332,7 +4332,7 @@ static netdev_tx_t stmmac_xmit(struct sk
- int len = skb_frag_size(frag);
- bool last_segment = (i == (nfrags - 1));
-
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
- WARN_ON(tx_q->tx_skbuff[entry]);
-
- if (likely(priv->extend_desc))
-@@ -4403,7 +4403,7 @@ static netdev_tx_t stmmac_xmit(struct sk
- * ndo_start_xmit will fill this descriptor the next time it's
- * called and stmmac_tx_clean may clean up to this descriptor.
- */
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
- tx_q->cur_tx = entry;
-
- if (netif_msg_pktdata(priv)) {
-@@ -4515,7 +4515,7 @@ static void stmmac_rx_vlan(struct net_de
- */
- static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int dirty = stmmac_rx_dirty(priv, queue);
- unsigned int entry = rx_q->dirty_rx;
-
-@@ -4565,7 +4565,7 @@ static inline void stmmac_rx_refill(stru
- dma_wmb();
- stmmac_set_rx_owner(priv, p, use_rx_wd);
-
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_rx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size);
- }
- rx_q->dirty_rx = entry;
- rx_q->rx_tail_addr = rx_q->dma_rx_phy +
-@@ -4593,12 +4593,12 @@ static unsigned int stmmac_rx_buf1_len(s
-
- /* First descriptor, not last descriptor and not split header */
- if (status & rx_not_ls)
-- return priv->dma_buf_sz;
-+ return priv->dma_conf.dma_buf_sz;
-
- plen = stmmac_get_rx_frame_len(priv, p, coe);
-
- /* First descriptor and last descriptor and not split header */
-- return min_t(unsigned int, priv->dma_buf_sz, plen);
-+ return min_t(unsigned int, priv->dma_conf.dma_buf_sz, plen);
- }
-
- static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
-@@ -4614,7 +4614,7 @@ static unsigned int stmmac_rx_buf2_len(s
-
- /* Not last descriptor */
- if (status & rx_not_ls)
-- return priv->dma_buf_sz;
-+ return priv->dma_conf.dma_buf_sz;
-
- plen = stmmac_get_rx_frame_len(priv, p, coe);
-
-@@ -4625,7 +4625,7 @@ static unsigned int stmmac_rx_buf2_len(s
- static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
- struct xdp_frame *xdpf, bool dma_map)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- unsigned int entry = tx_q->cur_tx;
- struct dma_desc *tx_desc;
- dma_addr_t dma_addr;
-@@ -4688,7 +4688,7 @@ static int stmmac_xdp_xmit_xdpf(struct s
-
- stmmac_enable_dma_transmission(priv, priv->ioaddr);
-
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
- tx_q->cur_tx = entry;
-
- return STMMAC_XDP_TX;
-@@ -4862,7 +4862,7 @@ static void stmmac_dispatch_skb_zc(struc
-
- static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- unsigned int entry = rx_q->dirty_rx;
- struct dma_desc *rx_desc = NULL;
- bool ret = true;
-@@ -4905,7 +4905,7 @@ static bool stmmac_rx_refill_zc(struct s
- dma_wmb();
- stmmac_set_rx_owner(priv, rx_desc, use_rx_wd);
-
-- entry = STMMAC_GET_ENTRY(entry, priv->dma_rx_size);
-+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size);
- }
-
- if (rx_desc) {
-@@ -4920,7 +4920,7 @@ static bool stmmac_rx_refill_zc(struct s
-
- static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- unsigned int count = 0, error = 0, len = 0;
- int dirty = stmmac_rx_dirty(priv, queue);
- unsigned int next_entry = rx_q->cur_rx;
-@@ -4942,7 +4942,7 @@ static int stmmac_rx_zc(struct stmmac_pr
- desc_size = sizeof(struct dma_desc);
- }
-
-- stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true,
-+ stmmac_display_ring(priv, rx_head, priv->dma_conf.dma_rx_size, true,
- rx_q->dma_rx_phy, desc_size);
- }
- while (count < limit) {
-@@ -4989,7 +4989,7 @@ read_again:
-
- /* Prefetch the next RX descriptor */
- rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx,
-- priv->dma_rx_size);
-+ priv->dma_conf.dma_rx_size);
- next_entry = rx_q->cur_rx;
-
- if (priv->extend_desc)
-@@ -5110,7 +5110,7 @@ read_again:
- */
- static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- struct stmmac_channel *ch = &priv->channel[queue];
- unsigned int count = 0, error = 0, len = 0;
- int status = 0, coe = priv->hw->rx_csum;
-@@ -5123,7 +5123,7 @@ static int stmmac_rx(struct stmmac_priv
- int buf_sz;
-
- dma_dir = page_pool_get_dma_dir(rx_q->page_pool);
-- buf_sz = DIV_ROUND_UP(priv->dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
-+ buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
-
- if (netif_msg_rx_status(priv)) {
- void *rx_head;
-@@ -5137,7 +5137,7 @@ static int stmmac_rx(struct stmmac_priv
- desc_size = sizeof(struct dma_desc);
- }
-
-- stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true,
-+ stmmac_display_ring(priv, rx_head, priv->dma_conf.dma_rx_size, true,
- rx_q->dma_rx_phy, desc_size);
- }
- while (count < limit) {
-@@ -5181,7 +5181,7 @@ read_again:
- break;
-
- rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx,
-- priv->dma_rx_size);
-+ priv->dma_conf.dma_rx_size);
- next_entry = rx_q->cur_rx;
-
- if (priv->extend_desc)
-@@ -5315,7 +5315,7 @@ read_again:
- buf1_len, dma_dir);
- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- buf->page, buf->page_offset, buf1_len,
-- priv->dma_buf_sz);
-+ priv->dma_conf.dma_buf_sz);
-
- /* Data payload appended into SKB */
- page_pool_release_page(rx_q->page_pool, buf->page);
-@@ -5327,7 +5327,7 @@ read_again:
- buf2_len, dma_dir);
- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- buf->sec_page, 0, buf2_len,
-- priv->dma_buf_sz);
-+ priv->dma_conf.dma_buf_sz);
-
- /* Data payload appended into SKB */
- page_pool_release_page(rx_q->page_pool, buf->sec_page);
-@@ -5760,11 +5760,13 @@ static irqreturn_t stmmac_safety_interru
- static irqreturn_t stmmac_msi_intr_tx(int irq, void *data)
- {
- struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)data;
-+ struct stmmac_dma_conf *dma_conf;
- int chan = tx_q->queue_index;
- struct stmmac_priv *priv;
- int status;
-
-- priv = container_of(tx_q, struct stmmac_priv, tx_queue[chan]);
-+ dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]);
-+ priv = container_of(dma_conf, struct stmmac_priv, dma_conf);
-
- /* Check if adapter is up */
- if (test_bit(STMMAC_DOWN, &priv->state))
-@@ -5799,10 +5801,12 @@ static irqreturn_t stmmac_msi_intr_tx(in
- static irqreturn_t stmmac_msi_intr_rx(int irq, void *data)
- {
- struct stmmac_rx_queue *rx_q = (struct stmmac_rx_queue *)data;
-+ struct stmmac_dma_conf *dma_conf;
- int chan = rx_q->queue_index;
- struct stmmac_priv *priv;
-
-- priv = container_of(rx_q, struct stmmac_priv, rx_queue[chan]);
-+ dma_conf = container_of(rx_q, struct stmmac_dma_conf, rx_queue[chan]);
-+ priv = container_of(dma_conf, struct stmmac_priv, dma_conf);
-
- /* Check if adapter is up */
- if (test_bit(STMMAC_DOWN, &priv->state))
-@@ -5828,10 +5832,10 @@ static void stmmac_poll_controller(struc
-
- if (priv->plat->multi_msi_en) {
- for (i = 0; i < priv->plat->rx_queues_to_use; i++)
-- stmmac_msi_intr_rx(0, &priv->rx_queue[i]);
-+ stmmac_msi_intr_rx(0, &priv->dma_conf.rx_queue[i]);
-
- for (i = 0; i < priv->plat->tx_queues_to_use; i++)
-- stmmac_msi_intr_tx(0, &priv->tx_queue[i]);
-+ stmmac_msi_intr_tx(0, &priv->dma_conf.tx_queue[i]);
- } else {
- disable_irq(dev->irq);
- stmmac_interrupt(dev->irq, dev);
-@@ -6012,34 +6016,34 @@ static int stmmac_rings_status_show(stru
- return 0;
-
- for (queue = 0; queue < rx_count; queue++) {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-
- seq_printf(seq, "RX Queue %d:\n", queue);
-
- if (priv->extend_desc) {
- seq_printf(seq, "Extended descriptor ring:\n");
- sysfs_display_ring((void *)rx_q->dma_erx,
-- priv->dma_rx_size, 1, seq, rx_q->dma_rx_phy);
-+ priv->dma_conf.dma_rx_size, 1, seq, rx_q->dma_rx_phy);
- } else {
- seq_printf(seq, "Descriptor ring:\n");
- sysfs_display_ring((void *)rx_q->dma_rx,
-- priv->dma_rx_size, 0, seq, rx_q->dma_rx_phy);
-+ priv->dma_conf.dma_rx_size, 0, seq, rx_q->dma_rx_phy);
- }
- }
-
- for (queue = 0; queue < tx_count; queue++) {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-
- seq_printf(seq, "TX Queue %d:\n", queue);
-
- if (priv->extend_desc) {
- seq_printf(seq, "Extended descriptor ring:\n");
- sysfs_display_ring((void *)tx_q->dma_etx,
-- priv->dma_tx_size, 1, seq, tx_q->dma_tx_phy);
-+ priv->dma_conf.dma_tx_size, 1, seq, tx_q->dma_tx_phy);
- } else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) {
- seq_printf(seq, "Descriptor ring:\n");
- sysfs_display_ring((void *)tx_q->dma_tx,
-- priv->dma_tx_size, 0, seq, tx_q->dma_tx_phy);
-+ priv->dma_conf.dma_tx_size, 0, seq, tx_q->dma_tx_phy);
- }
- }
-
-@@ -6386,7 +6390,7 @@ void stmmac_disable_rx_queue(struct stmm
-
- void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- struct stmmac_channel *ch = &priv->channel[queue];
- unsigned long flags;
- u32 buf_size;
-@@ -6423,7 +6427,7 @@ void stmmac_enable_rx_queue(struct stmma
- rx_q->queue_index);
- } else {
- stmmac_set_dma_bfsize(priv, priv->ioaddr,
-- priv->dma_buf_sz,
-+ priv->dma_conf.dma_buf_sz,
- rx_q->queue_index);
- }
-
-@@ -6449,7 +6453,7 @@ void stmmac_disable_tx_queue(struct stmm
-
- void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- struct stmmac_channel *ch = &priv->channel[queue];
- unsigned long flags;
- int ret;
-@@ -6499,7 +6503,7 @@ void stmmac_xdp_release(struct net_devic
- stmmac_disable_all_queues(priv);
-
- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
-- hrtimer_cancel(&priv->tx_queue[chan].txtimer);
-+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
-
- /* Free the IRQ lines */
- stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0);
-@@ -6558,7 +6562,7 @@ int stmmac_xdp_open(struct net_device *d
-
- /* DMA RX Channel Configuration */
- for (chan = 0; chan < rx_cnt; chan++) {
-- rx_q = &priv->rx_queue[chan];
-+ rx_q = &priv->dma_conf.rx_queue[chan];
-
- stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- rx_q->dma_rx_phy, chan);
-@@ -6576,7 +6580,7 @@ int stmmac_xdp_open(struct net_device *d
- rx_q->queue_index);
- } else {
- stmmac_set_dma_bfsize(priv, priv->ioaddr,
-- priv->dma_buf_sz,
-+ priv->dma_conf.dma_buf_sz,
- rx_q->queue_index);
- }
-
-@@ -6585,7 +6589,7 @@ int stmmac_xdp_open(struct net_device *d
-
- /* DMA TX Channel Configuration */
- for (chan = 0; chan < tx_cnt; chan++) {
-- tx_q = &priv->tx_queue[chan];
-+ tx_q = &priv->dma_conf.tx_queue[chan];
-
- stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- tx_q->dma_tx_phy, chan);
-@@ -6618,7 +6622,7 @@ int stmmac_xdp_open(struct net_device *d
-
- irq_error:
- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
-- hrtimer_cancel(&priv->tx_queue[chan].txtimer);
-+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
-
- stmmac_hw_teardown(dev);
- init_error:
-@@ -6645,8 +6649,8 @@ int stmmac_xsk_wakeup(struct net_device
- queue >= priv->plat->tx_queues_to_use)
- return -EINVAL;
-
-- rx_q = &priv->rx_queue[queue];
-- tx_q = &priv->tx_queue[queue];
-+ rx_q = &priv->dma_conf.rx_queue[queue];
-+ tx_q = &priv->dma_conf.tx_queue[queue];
- ch = &priv->channel[queue];
-
- if (!rx_q->xsk_pool && !tx_q->xsk_pool)
-@@ -6906,8 +6910,8 @@ int stmmac_reinit_ringparam(struct net_d
- if (netif_running(dev))
- stmmac_release(dev);
-
-- priv->dma_rx_size = rx_size;
-- priv->dma_tx_size = tx_size;
-+ priv->dma_conf.dma_rx_size = rx_size;
-+ priv->dma_conf.dma_tx_size = tx_size;
-
- if (netif_running(dev))
- ret = stmmac_open(dev);
-@@ -7345,7 +7349,7 @@ int stmmac_suspend(struct device *dev)
- stmmac_disable_all_queues(priv);
-
- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
-- hrtimer_cancel(&priv->tx_queue[chan].txtimer);
-+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
-
- if (priv->eee_enabled) {
- priv->tx_path_in_lpi_mode = false;
-@@ -7397,7 +7401,7 @@ EXPORT_SYMBOL_GPL(stmmac_suspend);
-
- static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-
- rx_q->cur_rx = 0;
- rx_q->dirty_rx = 0;
-@@ -7405,7 +7409,7 @@ static void stmmac_reset_rx_queue(struct
-
- static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-
- tx_q->cur_tx = 0;
- tx_q->dirty_tx = 0;
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
-@@ -795,8 +795,8 @@ static int stmmac_test_flowctrl(struct s
- struct stmmac_channel *ch = &priv->channel[i];
- u32 tail;
-
-- tail = priv->rx_queue[i].dma_rx_phy +
-- (priv->dma_rx_size * sizeof(struct dma_desc));
-+ tail = priv->dma_conf.rx_queue[i].dma_rx_phy +
-+ (priv->dma_conf.dma_rx_size * sizeof(struct dma_desc));
-
- stmmac_set_rx_tail_ptr(priv, priv->ioaddr, tail, i);
- stmmac_start_rx(priv, priv->ioaddr, i);
-@@ -1684,7 +1684,7 @@ cleanup:
- static int __stmmac_test_jumbo(struct stmmac_priv *priv, u16 queue)
- {
- struct stmmac_packet_attrs attr = { };
-- int size = priv->dma_buf_sz;
-+ int size = priv->dma_conf.dma_buf_sz;
-
- attr.dst = priv->dev->dev_addr;
- attr.max_size = size - ETH_FCS_LEN;
-@@ -1767,7 +1767,7 @@ static int stmmac_test_tbs(struct stmmac
-
- /* Find first TBS enabled Queue, if any */
- for (i = 0; i < priv->plat->tx_queues_to_use; i++)
-- if (priv->tx_queue[i].tbs & STMMAC_TBS_AVAIL)
-+ if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_AVAIL)
- break;
-
- if (i >= priv->plat->tx_queues_to_use)
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
-@@ -971,13 +971,13 @@ static int tc_setup_etf(struct stmmac_pr
- return -EOPNOTSUPP;
- if (qopt->queue >= priv->plat->tx_queues_to_use)
- return -EINVAL;
-- if (!(priv->tx_queue[qopt->queue].tbs & STMMAC_TBS_AVAIL))
-+ if (!(priv->dma_conf.tx_queue[qopt->queue].tbs & STMMAC_TBS_AVAIL))
- return -EINVAL;
-
- if (qopt->enable)
-- priv->tx_queue[qopt->queue].tbs |= STMMAC_TBS_EN;
-+ priv->dma_conf.tx_queue[qopt->queue].tbs |= STMMAC_TBS_EN;
- else
-- priv->tx_queue[qopt->queue].tbs &= ~STMMAC_TBS_EN;
-+ priv->dma_conf.tx_queue[qopt->queue].tbs &= ~STMMAC_TBS_EN;
-
- netdev_info(priv->dev, "%s ETF for Queue %d\n",
- qopt->enable ? "enabled" : "disabled", qopt->queue);
diff --git a/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch b/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch
deleted file mode 100644
index 87da2af562..0000000000
--- a/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch
+++ /dev/null
@@ -1,1161 +0,0 @@
-From ba39b344e9240a4a5fd4ab8178200b85cd1809da Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 23 Jul 2022 16:29:32 +0200
-Subject: [PATCH 4/5] net: ethernet: stmicro: stmmac: generate stmmac dma conf
- before open
-
-Rework the driver to generate the stmmac dma_conf before stmmac_open.
-This permits a function to first check if it's possible to allocate a
-new dma_config and then pass it directly to __stmmac_open and "open" the
-interface with the new configuration.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 462 +++++++++++-------
- 1 file changed, 289 insertions(+), 173 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -1301,7 +1301,8 @@ static int stmmac_phy_setup(struct stmma
- return 0;
- }
-
--static void stmmac_display_rx_rings(struct stmmac_priv *priv)
-+static void stmmac_display_rx_rings(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- u32 rx_cnt = priv->plat->rx_queues_to_use;
- unsigned int desc_size;
-@@ -1310,7 +1311,7 @@ static void stmmac_display_rx_rings(stru
-
- /* Display RX rings */
- for (queue = 0; queue < rx_cnt; queue++) {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
-
- pr_info("\tRX Queue %u rings\n", queue);
-
-@@ -1323,12 +1324,13 @@ static void stmmac_display_rx_rings(stru
- }
-
- /* Display RX ring */
-- stmmac_display_ring(priv, head_rx, priv->dma_conf.dma_rx_size, true,
-+ stmmac_display_ring(priv, head_rx, dma_conf->dma_rx_size, true,
- rx_q->dma_rx_phy, desc_size);
- }
- }
-
--static void stmmac_display_tx_rings(struct stmmac_priv *priv)
-+static void stmmac_display_tx_rings(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- u32 tx_cnt = priv->plat->tx_queues_to_use;
- unsigned int desc_size;
-@@ -1337,7 +1339,7 @@ static void stmmac_display_tx_rings(stru
-
- /* Display TX rings */
- for (queue = 0; queue < tx_cnt; queue++) {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
-
- pr_info("\tTX Queue %d rings\n", queue);
-
-@@ -1352,18 +1354,19 @@ static void stmmac_display_tx_rings(stru
- desc_size = sizeof(struct dma_desc);
- }
-
-- stmmac_display_ring(priv, head_tx, priv->dma_conf.dma_tx_size, false,
-+ stmmac_display_ring(priv, head_tx, dma_conf->dma_tx_size, false,
- tx_q->dma_tx_phy, desc_size);
- }
- }
-
--static void stmmac_display_rings(struct stmmac_priv *priv)
-+static void stmmac_display_rings(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- /* Display RX ring */
-- stmmac_display_rx_rings(priv);
-+ stmmac_display_rx_rings(priv, dma_conf);
-
- /* Display TX ring */
-- stmmac_display_tx_rings(priv);
-+ stmmac_display_tx_rings(priv, dma_conf);
- }
-
- static int stmmac_set_bfsize(int mtu, int bufsize)
-@@ -1387,44 +1390,50 @@ static int stmmac_set_bfsize(int mtu, in
- /**
- * stmmac_clear_rx_descriptors - clear RX descriptors
- * @priv: driver private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: RX queue index
- * Description: this function is called to clear the RX descriptors
- * in case of both basic and extended descriptors are used.
- */
--static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv, u32 queue)
-+static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- int i;
-
- /* Clear the RX descriptors */
-- for (i = 0; i < priv->dma_conf.dma_rx_size; i++)
-+ for (i = 0; i < dma_conf->dma_rx_size; i++)
- if (priv->extend_desc)
- stmmac_init_rx_desc(priv, &rx_q->dma_erx[i].basic,
- priv->use_riwt, priv->mode,
-- (i == priv->dma_conf.dma_rx_size - 1),
-- priv->dma_conf.dma_buf_sz);
-+ (i == dma_conf->dma_rx_size - 1),
-+ dma_conf->dma_buf_sz);
- else
- stmmac_init_rx_desc(priv, &rx_q->dma_rx[i],
- priv->use_riwt, priv->mode,
-- (i == priv->dma_conf.dma_rx_size - 1),
-- priv->dma_conf.dma_buf_sz);
-+ (i == dma_conf->dma_rx_size - 1),
-+ dma_conf->dma_buf_sz);
- }
-
- /**
- * stmmac_clear_tx_descriptors - clear tx descriptors
- * @priv: driver private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: TX queue index.
- * Description: this function is called to clear the TX descriptors
- * in case of both basic and extended descriptors are used.
- */
--static void stmmac_clear_tx_descriptors(struct stmmac_priv *priv, u32 queue)
-+static void stmmac_clear_tx_descriptors(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
- int i;
-
- /* Clear the TX descriptors */
-- for (i = 0; i < priv->dma_conf.dma_tx_size; i++) {
-- int last = (i == (priv->dma_conf.dma_tx_size - 1));
-+ for (i = 0; i < dma_conf->dma_tx_size; i++) {
-+ int last = (i == (dma_conf->dma_tx_size - 1));
- struct dma_desc *p;
-
- if (priv->extend_desc)
-@@ -1441,10 +1450,12 @@ static void stmmac_clear_tx_descriptors(
- /**
- * stmmac_clear_descriptors - clear descriptors
- * @priv: driver private structure
-+ * @dma_conf: structure to take the dma data
- * Description: this function is called to clear the TX and RX descriptors
- * in case of both basic and extended descriptors are used.
- */
--static void stmmac_clear_descriptors(struct stmmac_priv *priv)
-+static void stmmac_clear_descriptors(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- u32 rx_queue_cnt = priv->plat->rx_queues_to_use;
- u32 tx_queue_cnt = priv->plat->tx_queues_to_use;
-@@ -1452,16 +1463,17 @@ static void stmmac_clear_descriptors(str
-
- /* Clear the RX descriptors */
- for (queue = 0; queue < rx_queue_cnt; queue++)
-- stmmac_clear_rx_descriptors(priv, queue);
-+ stmmac_clear_rx_descriptors(priv, dma_conf, queue);
-
- /* Clear the TX descriptors */
- for (queue = 0; queue < tx_queue_cnt; queue++)
-- stmmac_clear_tx_descriptors(priv, queue);
-+ stmmac_clear_tx_descriptors(priv, dma_conf, queue);
- }
-
- /**
- * stmmac_init_rx_buffers - init the RX descriptor buffer.
- * @priv: driver private structure
-+ * @dma_conf: structure to take the dma data
- * @p: descriptor pointer
- * @i: descriptor index
- * @flags: gfp flag
-@@ -1469,10 +1481,12 @@ static void stmmac_clear_descriptors(str
- * Description: this function is called to allocate a receive buffer, perform
- * the DMA mapping and init the descriptor.
- */
--static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
-+static int stmmac_init_rx_buffers(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ struct dma_desc *p,
- int i, gfp_t flags, u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-
- if (!buf->page) {
-@@ -1497,7 +1511,7 @@ static int stmmac_init_rx_buffers(struct
- buf->addr = page_pool_get_dma_addr(buf->page) + buf->page_offset;
-
- stmmac_set_desc_addr(priv, p, buf->addr);
-- if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB)
-+ if (dma_conf->dma_buf_sz == BUF_SIZE_16KiB)
- stmmac_init_desc3(priv, p);
-
- return 0;
-@@ -1506,12 +1520,13 @@ static int stmmac_init_rx_buffers(struct
- /**
- * stmmac_free_rx_buffer - free RX dma buffers
- * @priv: private structure
-- * @queue: RX queue index
-+ * @rx_q: RX queue
- * @i: buffer index.
- */
--static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i)
-+static void stmmac_free_rx_buffer(struct stmmac_priv *priv,
-+ struct stmmac_rx_queue *rx_q,
-+ int i)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-
- if (buf->page)
-@@ -1526,12 +1541,15 @@ static void stmmac_free_rx_buffer(struct
- /**
- * stmmac_free_tx_buffer - free RX dma buffers
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: RX queue index
- * @i: buffer index.
- */
--static void stmmac_free_tx_buffer(struct stmmac_priv *priv, u32 queue, int i)
-+static void stmmac_free_tx_buffer(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue, int i)
- {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
-
- if (tx_q->tx_skbuff_dma[i].buf &&
- tx_q->tx_skbuff_dma[i].buf_type != STMMAC_TXBUF_T_XDP_TX) {
-@@ -1570,23 +1588,28 @@ static void stmmac_free_tx_buffer(struct
- /**
- * dma_free_rx_skbufs - free RX dma buffers
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: RX queue index
- */
--static void dma_free_rx_skbufs(struct stmmac_priv *priv, u32 queue)
-+static void dma_free_rx_skbufs(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- int i;
-
-- for (i = 0; i < priv->dma_conf.dma_rx_size; i++)
-- stmmac_free_rx_buffer(priv, queue, i);
-+ for (i = 0; i < dma_conf->dma_rx_size; i++)
-+ stmmac_free_rx_buffer(priv, rx_q, i);
- }
-
--static int stmmac_alloc_rx_buffers(struct stmmac_priv *priv, u32 queue,
-- gfp_t flags)
-+static int stmmac_alloc_rx_buffers(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue, gfp_t flags)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- int i;
-
-- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) {
-+ for (i = 0; i < dma_conf->dma_rx_size; i++) {
- struct dma_desc *p;
- int ret;
-
-@@ -1595,7 +1618,7 @@ static int stmmac_alloc_rx_buffers(struc
- else
- p = rx_q->dma_rx + i;
-
-- ret = stmmac_init_rx_buffers(priv, p, i, flags,
-+ ret = stmmac_init_rx_buffers(priv, dma_conf, p, i, flags,
- queue);
- if (ret)
- return ret;
-@@ -1609,14 +1632,17 @@ static int stmmac_alloc_rx_buffers(struc
- /**
- * dma_free_rx_xskbufs - free RX dma buffers from XSK pool
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: RX queue index
- */
--static void dma_free_rx_xskbufs(struct stmmac_priv *priv, u32 queue)
-+static void dma_free_rx_xskbufs(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- int i;
-
-- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) {
-+ for (i = 0; i < dma_conf->dma_rx_size; i++) {
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-
- if (!buf->xdp)
-@@ -1627,12 +1653,14 @@ static void dma_free_rx_xskbufs(struct s
- }
- }
-
--static int stmmac_alloc_rx_buffers_zc(struct stmmac_priv *priv, u32 queue)
-+static int stmmac_alloc_rx_buffers_zc(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- int i;
-
-- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) {
-+ for (i = 0; i < dma_conf->dma_rx_size; i++) {
- struct stmmac_rx_buffer *buf;
- dma_addr_t dma_addr;
- struct dma_desc *p;
-@@ -1667,22 +1695,25 @@ static struct xsk_buff_pool *stmmac_get_
- /**
- * __init_dma_rx_desc_rings - init the RX descriptor ring (per queue)
- * @priv: driver private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: RX queue index
- * @flags: gfp flag.
- * Description: this function initializes the DMA RX descriptors
- * and allocates the socket buffers. It supports the chained and ring
- * modes.
- */
--static int __init_dma_rx_desc_rings(struct stmmac_priv *priv, u32 queue, gfp_t flags)
-+static int __init_dma_rx_desc_rings(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue, gfp_t flags)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- int ret;
-
- netif_dbg(priv, probe, priv->dev,
- "(%s) dma_rx_phy=0x%08x\n", __func__,
- (u32)rx_q->dma_rx_phy);
-
-- stmmac_clear_rx_descriptors(priv, queue);
-+ stmmac_clear_rx_descriptors(priv, dma_conf, queue);
-
- xdp_rxq_info_unreg_mem_model(&rx_q->xdp_rxq);
-
-@@ -1709,9 +1740,9 @@ static int __init_dma_rx_desc_rings(stru
- /* RX XDP ZC buffer pool may not be populated, e.g.
- * xdpsock TX-only.
- */
-- stmmac_alloc_rx_buffers_zc(priv, queue);
-+ stmmac_alloc_rx_buffers_zc(priv, dma_conf, queue);
- } else {
-- ret = stmmac_alloc_rx_buffers(priv, queue, flags);
-+ ret = stmmac_alloc_rx_buffers(priv, dma_conf, queue, flags);
- if (ret < 0)
- return -ENOMEM;
- }
-@@ -1721,17 +1752,19 @@ static int __init_dma_rx_desc_rings(stru
- if (priv->extend_desc)
- stmmac_mode_init(priv, rx_q->dma_erx,
- rx_q->dma_rx_phy,
-- priv->dma_conf.dma_rx_size, 1);
-+ dma_conf->dma_rx_size, 1);
- else
- stmmac_mode_init(priv, rx_q->dma_rx,
- rx_q->dma_rx_phy,
-- priv->dma_conf.dma_rx_size, 0);
-+ dma_conf->dma_rx_size, 0);
- }
-
- return 0;
- }
-
--static int init_dma_rx_desc_rings(struct net_device *dev, gfp_t flags)
-+static int init_dma_rx_desc_rings(struct net_device *dev,
-+ struct stmmac_dma_conf *dma_conf,
-+ gfp_t flags)
- {
- struct stmmac_priv *priv = netdev_priv(dev);
- u32 rx_count = priv->plat->rx_queues_to_use;
-@@ -1743,7 +1776,7 @@ static int init_dma_rx_desc_rings(struct
- "SKB addresses:\nskb\t\tskb data\tdma data\n");
-
- for (queue = 0; queue < rx_count; queue++) {
-- ret = __init_dma_rx_desc_rings(priv, queue, flags);
-+ ret = __init_dma_rx_desc_rings(priv, dma_conf, queue, flags);
- if (ret)
- goto err_init_rx_buffers;
- }
-@@ -1752,12 +1785,12 @@ static int init_dma_rx_desc_rings(struct
-
- err_init_rx_buffers:
- while (queue >= 0) {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
-
- if (rx_q->xsk_pool)
-- dma_free_rx_xskbufs(priv, queue);
-+ dma_free_rx_xskbufs(priv, dma_conf, queue);
- else
-- dma_free_rx_skbufs(priv, queue);
-+ dma_free_rx_skbufs(priv, dma_conf, queue);
-
- rx_q->buf_alloc_num = 0;
- rx_q->xsk_pool = NULL;
-@@ -1774,14 +1807,17 @@ err_init_rx_buffers:
- /**
- * __init_dma_tx_desc_rings - init the TX descriptor ring (per queue)
- * @priv: driver private structure
-- * @queue : TX queue index
-+ * @dma_conf: structure to take the dma data
-+ * @queue: TX queue index
- * Description: this function initializes the DMA TX descriptors
- * and allocates the socket buffers. It supports the chained and ring
- * modes.
- */
--static int __init_dma_tx_desc_rings(struct stmmac_priv *priv, u32 queue)
-+static int __init_dma_tx_desc_rings(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
- int i;
-
- netif_dbg(priv, probe, priv->dev,
-@@ -1793,16 +1829,16 @@ static int __init_dma_tx_desc_rings(stru
- if (priv->extend_desc)
- stmmac_mode_init(priv, tx_q->dma_etx,
- tx_q->dma_tx_phy,
-- priv->dma_conf.dma_tx_size, 1);
-+ dma_conf->dma_tx_size, 1);
- else if (!(tx_q->tbs & STMMAC_TBS_AVAIL))
- stmmac_mode_init(priv, tx_q->dma_tx,
- tx_q->dma_tx_phy,
-- priv->dma_conf.dma_tx_size, 0);
-+ dma_conf->dma_tx_size, 0);
- }
-
- tx_q->xsk_pool = stmmac_get_xsk_pool(priv, queue);
-
-- for (i = 0; i < priv->dma_conf.dma_tx_size; i++) {
-+ for (i = 0; i < dma_conf->dma_tx_size; i++) {
- struct dma_desc *p;
-
- if (priv->extend_desc)
-@@ -1824,7 +1860,8 @@ static int __init_dma_tx_desc_rings(stru
- return 0;
- }
-
--static int init_dma_tx_desc_rings(struct net_device *dev)
-+static int init_dma_tx_desc_rings(struct net_device *dev,
-+ struct stmmac_dma_conf *dma_conf)
- {
- struct stmmac_priv *priv = netdev_priv(dev);
- u32 tx_queue_cnt;
-@@ -1833,7 +1870,7 @@ static int init_dma_tx_desc_rings(struct
- tx_queue_cnt = priv->plat->tx_queues_to_use;
-
- for (queue = 0; queue < tx_queue_cnt; queue++)
-- __init_dma_tx_desc_rings(priv, queue);
-+ __init_dma_tx_desc_rings(priv, dma_conf, queue);
-
- return 0;
- }
-@@ -1841,26 +1878,29 @@ static int init_dma_tx_desc_rings(struct
- /**
- * init_dma_desc_rings - init the RX/TX descriptor rings
- * @dev: net device structure
-+ * @dma_conf: structure to take the dma data
- * @flags: gfp flag.
- * Description: this function initializes the DMA RX/TX descriptors
- * and allocates the socket buffers. It supports the chained and ring
- * modes.
- */
--static int init_dma_desc_rings(struct net_device *dev, gfp_t flags)
-+static int init_dma_desc_rings(struct net_device *dev,
-+ struct stmmac_dma_conf *dma_conf,
-+ gfp_t flags)
- {
- struct stmmac_priv *priv = netdev_priv(dev);
- int ret;
-
-- ret = init_dma_rx_desc_rings(dev, flags);
-+ ret = init_dma_rx_desc_rings(dev, dma_conf, flags);
- if (ret)
- return ret;
-
-- ret = init_dma_tx_desc_rings(dev);
-+ ret = init_dma_tx_desc_rings(dev, dma_conf);
-
-- stmmac_clear_descriptors(priv);
-+ stmmac_clear_descriptors(priv, dma_conf);
-
- if (netif_msg_hw(priv))
-- stmmac_display_rings(priv);
-+ stmmac_display_rings(priv, dma_conf);
-
- return ret;
- }
-@@ -1868,17 +1908,20 @@ static int init_dma_desc_rings(struct ne
- /**
- * dma_free_tx_skbufs - free TX dma buffers
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: TX queue index
- */
--static void dma_free_tx_skbufs(struct stmmac_priv *priv, u32 queue)
-+static void dma_free_tx_skbufs(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
- int i;
-
- tx_q->xsk_frames_done = 0;
-
-- for (i = 0; i < priv->dma_conf.dma_tx_size; i++)
-- stmmac_free_tx_buffer(priv, queue, i);
-+ for (i = 0; i < dma_conf->dma_tx_size; i++)
-+ stmmac_free_tx_buffer(priv, dma_conf, queue, i);
-
- if (tx_q->xsk_pool && tx_q->xsk_frames_done) {
- xsk_tx_completed(tx_q->xsk_pool, tx_q->xsk_frames_done);
-@@ -1897,34 +1940,37 @@ static void stmmac_free_tx_skbufs(struct
- u32 queue;
-
- for (queue = 0; queue < tx_queue_cnt; queue++)
-- dma_free_tx_skbufs(priv, queue);
-+ dma_free_tx_skbufs(priv, &priv->dma_conf, queue);
- }
-
- /**
- * __free_dma_rx_desc_resources - free RX dma desc resources (per queue)
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: RX queue index
- */
--static void __free_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue)
-+static void __free_dma_rx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
-
- /* Release the DMA RX socket buffers */
- if (rx_q->xsk_pool)
-- dma_free_rx_xskbufs(priv, queue);
-+ dma_free_rx_xskbufs(priv, dma_conf, queue);
- else
-- dma_free_rx_skbufs(priv, queue);
-+ dma_free_rx_skbufs(priv, dma_conf, queue);
-
- rx_q->buf_alloc_num = 0;
- rx_q->xsk_pool = NULL;
-
- /* Free DMA regions of consistent memory previously allocated */
- if (!priv->extend_desc)
-- dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size *
-+ dma_free_coherent(priv->device, dma_conf->dma_rx_size *
- sizeof(struct dma_desc),
- rx_q->dma_rx, rx_q->dma_rx_phy);
- else
-- dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size *
-+ dma_free_coherent(priv->device, dma_conf->dma_rx_size *
- sizeof(struct dma_extended_desc),
- rx_q->dma_erx, rx_q->dma_rx_phy);
-
-@@ -1936,29 +1982,33 @@ static void __free_dma_rx_desc_resources
- page_pool_destroy(rx_q->page_pool);
- }
-
--static void free_dma_rx_desc_resources(struct stmmac_priv *priv)
-+static void free_dma_rx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- u32 rx_count = priv->plat->rx_queues_to_use;
- u32 queue;
-
- /* Free RX queue resources */
- for (queue = 0; queue < rx_count; queue++)
-- __free_dma_rx_desc_resources(priv, queue);
-+ __free_dma_rx_desc_resources(priv, dma_conf, queue);
- }
-
- /**
- * __free_dma_tx_desc_resources - free TX dma desc resources (per queue)
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: TX queue index
- */
--static void __free_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue)
-+static void __free_dma_tx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
- size_t size;
- void *addr;
-
- /* Release the DMA TX socket buffers */
-- dma_free_tx_skbufs(priv, queue);
-+ dma_free_tx_skbufs(priv, dma_conf, queue);
-
- if (priv->extend_desc) {
- size = sizeof(struct dma_extended_desc);
-@@ -1971,7 +2021,7 @@ static void __free_dma_tx_desc_resources
- addr = tx_q->dma_tx;
- }
-
-- size *= priv->dma_conf.dma_tx_size;
-+ size *= dma_conf->dma_tx_size;
-
- dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy);
-
-@@ -1979,28 +2029,32 @@ static void __free_dma_tx_desc_resources
- kfree(tx_q->tx_skbuff);
- }
-
--static void free_dma_tx_desc_resources(struct stmmac_priv *priv)
-+static void free_dma_tx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- u32 tx_count = priv->plat->tx_queues_to_use;
- u32 queue;
-
- /* Free TX queue resources */
- for (queue = 0; queue < tx_count; queue++)
-- __free_dma_tx_desc_resources(priv, queue);
-+ __free_dma_tx_desc_resources(priv, dma_conf, queue);
- }
-
- /**
- * __alloc_dma_rx_desc_resources - alloc RX resources (per queue).
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: RX queue index
- * Description: according to which descriptor can be used (extend or basic)
- * this function allocates the resources for TX and RX paths. In case of
- * reception, for example, it pre-allocated the RX socket buffer in order to
- * allow zero-copy mechanism.
- */
--static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue)
-+static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- struct stmmac_channel *ch = &priv->channel[queue];
- bool xdp_prog = stmmac_xdp_is_enabled(priv);
- struct page_pool_params pp_params = { 0 };
-@@ -2012,8 +2066,8 @@ static int __alloc_dma_rx_desc_resources
- rx_q->priv_data = priv;
-
- pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
-- pp_params.pool_size = priv->dma_conf.dma_rx_size;
-- num_pages = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE);
-+ pp_params.pool_size = dma_conf->dma_rx_size;
-+ num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE);
- pp_params.order = ilog2(num_pages);
- pp_params.nid = dev_to_node(priv->device);
- pp_params.dev = priv->device;
-@@ -2028,7 +2082,7 @@ static int __alloc_dma_rx_desc_resources
- return ret;
- }
-
-- rx_q->buf_pool = kcalloc(priv->dma_conf.dma_rx_size,
-+ rx_q->buf_pool = kcalloc(dma_conf->dma_rx_size,
- sizeof(*rx_q->buf_pool),
- GFP_KERNEL);
- if (!rx_q->buf_pool)
-@@ -2036,7 +2090,7 @@ static int __alloc_dma_rx_desc_resources
-
- if (priv->extend_desc) {
- rx_q->dma_erx = dma_alloc_coherent(priv->device,
-- priv->dma_conf.dma_rx_size *
-+ dma_conf->dma_rx_size *
- sizeof(struct dma_extended_desc),
- &rx_q->dma_rx_phy,
- GFP_KERNEL);
-@@ -2045,7 +2099,7 @@ static int __alloc_dma_rx_desc_resources
-
- } else {
- rx_q->dma_rx = dma_alloc_coherent(priv->device,
-- priv->dma_conf.dma_rx_size *
-+ dma_conf->dma_rx_size *
- sizeof(struct dma_desc),
- &rx_q->dma_rx_phy,
- GFP_KERNEL);
-@@ -2070,7 +2124,8 @@ static int __alloc_dma_rx_desc_resources
- return 0;
- }
-
--static int alloc_dma_rx_desc_resources(struct stmmac_priv *priv)
-+static int alloc_dma_rx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- u32 rx_count = priv->plat->rx_queues_to_use;
- u32 queue;
-@@ -2078,7 +2133,7 @@ static int alloc_dma_rx_desc_resources(s
-
- /* RX queues buffers and DMA */
- for (queue = 0; queue < rx_count; queue++) {
-- ret = __alloc_dma_rx_desc_resources(priv, queue);
-+ ret = __alloc_dma_rx_desc_resources(priv, dma_conf, queue);
- if (ret)
- goto err_dma;
- }
-@@ -2086,7 +2141,7 @@ static int alloc_dma_rx_desc_resources(s
- return 0;
-
- err_dma:
-- free_dma_rx_desc_resources(priv);
-+ free_dma_rx_desc_resources(priv, dma_conf);
-
- return ret;
- }
-@@ -2094,28 +2149,31 @@ err_dma:
- /**
- * __alloc_dma_tx_desc_resources - alloc TX resources (per queue).
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * @queue: TX queue index
- * Description: according to which descriptor can be used (extend or basic)
- * this function allocates the resources for TX and RX paths. In case of
- * reception, for example, it pre-allocated the RX socket buffer in order to
- * allow zero-copy mechanism.
- */
--static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue)
-+static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf,
-+ u32 queue)
- {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
- size_t size;
- void *addr;
-
- tx_q->queue_index = queue;
- tx_q->priv_data = priv;
-
-- tx_q->tx_skbuff_dma = kcalloc(priv->dma_conf.dma_tx_size,
-+ tx_q->tx_skbuff_dma = kcalloc(dma_conf->dma_tx_size,
- sizeof(*tx_q->tx_skbuff_dma),
- GFP_KERNEL);
- if (!tx_q->tx_skbuff_dma)
- return -ENOMEM;
-
-- tx_q->tx_skbuff = kcalloc(priv->dma_conf.dma_tx_size,
-+ tx_q->tx_skbuff = kcalloc(dma_conf->dma_tx_size,
- sizeof(struct sk_buff *),
- GFP_KERNEL);
- if (!tx_q->tx_skbuff)
-@@ -2128,7 +2186,7 @@ static int __alloc_dma_tx_desc_resources
- else
- size = sizeof(struct dma_desc);
-
-- size *= priv->dma_conf.dma_tx_size;
-+ size *= dma_conf->dma_tx_size;
-
- addr = dma_alloc_coherent(priv->device, size,
- &tx_q->dma_tx_phy, GFP_KERNEL);
-@@ -2145,7 +2203,8 @@ static int __alloc_dma_tx_desc_resources
- return 0;
- }
-
--static int alloc_dma_tx_desc_resources(struct stmmac_priv *priv)
-+static int alloc_dma_tx_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- u32 tx_count = priv->plat->tx_queues_to_use;
- u32 queue;
-@@ -2153,7 +2212,7 @@ static int alloc_dma_tx_desc_resources(s
-
- /* TX queues buffers and DMA */
- for (queue = 0; queue < tx_count; queue++) {
-- ret = __alloc_dma_tx_desc_resources(priv, queue);
-+ ret = __alloc_dma_tx_desc_resources(priv, dma_conf, queue);
- if (ret)
- goto err_dma;
- }
-@@ -2161,27 +2220,29 @@ static int alloc_dma_tx_desc_resources(s
- return 0;
-
- err_dma:
-- free_dma_tx_desc_resources(priv);
-+ free_dma_tx_desc_resources(priv, dma_conf);
- return ret;
- }
-
- /**
- * alloc_dma_desc_resources - alloc TX/RX resources.
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- * Description: according to which descriptor can be used (extend or basic)
- * this function allocates the resources for TX and RX paths. In case of
- * reception, for example, it pre-allocated the RX socket buffer in order to
- * allow zero-copy mechanism.
- */
--static int alloc_dma_desc_resources(struct stmmac_priv *priv)
-+static int alloc_dma_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- /* RX Allocation */
-- int ret = alloc_dma_rx_desc_resources(priv);
-+ int ret = alloc_dma_rx_desc_resources(priv, dma_conf);
-
- if (ret)
- return ret;
-
-- ret = alloc_dma_tx_desc_resources(priv);
-+ ret = alloc_dma_tx_desc_resources(priv, dma_conf);
-
- return ret;
- }
-@@ -2189,16 +2250,18 @@ static int alloc_dma_desc_resources(stru
- /**
- * free_dma_desc_resources - free dma desc resources
- * @priv: private structure
-+ * @dma_conf: structure to take the dma data
- */
--static void free_dma_desc_resources(struct stmmac_priv *priv)
-+static void free_dma_desc_resources(struct stmmac_priv *priv,
-+ struct stmmac_dma_conf *dma_conf)
- {
- /* Release the DMA TX socket buffers */
-- free_dma_tx_desc_resources(priv);
-+ free_dma_tx_desc_resources(priv, dma_conf);
-
- /* Release the DMA RX socket buffers later
- * to ensure all pending XDP_TX buffers are returned.
- */
-- free_dma_rx_desc_resources(priv);
-+ free_dma_rx_desc_resources(priv, dma_conf);
- }
-
- /**
-@@ -2687,8 +2750,8 @@ static void stmmac_tx_err(struct stmmac_
- netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, chan));
-
- stmmac_stop_tx_dma(priv, chan);
-- dma_free_tx_skbufs(priv, chan);
-- stmmac_clear_tx_descriptors(priv, chan);
-+ dma_free_tx_skbufs(priv, &priv->dma_conf, chan);
-+ stmmac_clear_tx_descriptors(priv, &priv->dma_conf, chan);
- stmmac_reset_tx_queue(priv, chan);
- stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- tx_q->dma_tx_phy, chan);
-@@ -3686,19 +3749,93 @@ static int stmmac_request_irq(struct net
- }
-
- /**
-- * stmmac_open - open entry point of the driver
-+ * stmmac_setup_dma_desc - Generate a dma_conf and allocate DMA queue
-+ * @priv: driver private structure
-+ * @mtu: MTU to setup the dma queue and buf with
-+ * Description: Allocate and generate a dma_conf based on the provided MTU.
-+ * Allocate the Tx/Rx DMA queue and init them.
-+ * Return value:
-+ * the dma_conf allocated struct on success and an appropriate ERR_PTR on failure.
-+ */
-+static struct stmmac_dma_conf *
-+stmmac_setup_dma_desc(struct stmmac_priv *priv, unsigned int mtu)
-+{
-+ struct stmmac_dma_conf *dma_conf;
-+ int chan, bfsize, ret;
-+
-+ dma_conf = kzalloc(sizeof(*dma_conf), GFP_KERNEL);
-+ if (!dma_conf) {
-+ netdev_err(priv->dev, "%s: DMA conf allocation failed\n",
-+ __func__);
-+ return ERR_PTR(-ENOMEM);
-+ }
-+
-+ bfsize = stmmac_set_16kib_bfsize(priv, mtu);
-+ if (bfsize < 0)
-+ bfsize = 0;
-+
-+ if (bfsize < BUF_SIZE_16KiB)
-+ bfsize = stmmac_set_bfsize(mtu, 0);
-+
-+ dma_conf->dma_buf_sz = bfsize;
-+ /* Chose the tx/rx size from the already defined one in the
-+ * priv struct. (if defined)
-+ */
-+ dma_conf->dma_tx_size = priv->dma_conf.dma_tx_size;
-+ dma_conf->dma_rx_size = priv->dma_conf.dma_rx_size;
-+
-+ if (!dma_conf->dma_tx_size)
-+ dma_conf->dma_tx_size = DMA_DEFAULT_TX_SIZE;
-+ if (!dma_conf->dma_rx_size)
-+ dma_conf->dma_rx_size = DMA_DEFAULT_RX_SIZE;
-+
-+ /* Earlier check for TBS */
-+ for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) {
-+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[chan];
-+ int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en;
-+
-+ /* Setup per-TXQ tbs flag before TX descriptor alloc */
-+ tx_q->tbs |= tbs_en ? STMMAC_TBS_AVAIL : 0;
-+ }
-+
-+ ret = alloc_dma_desc_resources(priv, dma_conf);
-+ if (ret < 0) {
-+ netdev_err(priv->dev, "%s: DMA descriptors allocation failed\n",
-+ __func__);
-+ goto alloc_error;
-+ }
-+
-+ ret = init_dma_desc_rings(priv->dev, dma_conf, GFP_KERNEL);
-+ if (ret < 0) {
-+ netdev_err(priv->dev, "%s: DMA descriptors initialization failed\n",
-+ __func__);
-+ goto init_error;
-+ }
-+
-+ return dma_conf;
-+
-+init_error:
-+ free_dma_desc_resources(priv, dma_conf);
-+alloc_error:
-+ kfree(dma_conf);
-+ return ERR_PTR(ret);
-+}
-+
-+/**
-+ * __stmmac_open - open entry point of the driver
- * @dev : pointer to the device structure.
-+ * @dma_conf : structure to take the dma data
- * Description:
- * This function is the open entry point of the driver.
- * Return value:
- * 0 on success and an appropriate (-)ve integer as defined in errno.h
- * file on failure.
- */
--static int stmmac_open(struct net_device *dev)
-+static int __stmmac_open(struct net_device *dev,
-+ struct stmmac_dma_conf *dma_conf)
- {
- struct stmmac_priv *priv = netdev_priv(dev);
- int mode = priv->plat->phy_interface;
-- int bfsize = 0;
- u32 chan;
- int ret;
-
-@@ -3725,45 +3862,10 @@ static int stmmac_open(struct net_device
- memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
- priv->xstats.threshold = tc;
-
-- bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu);
-- if (bfsize < 0)
-- bfsize = 0;
--
-- if (bfsize < BUF_SIZE_16KiB)
-- bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_conf.dma_buf_sz);
--
-- priv->dma_conf.dma_buf_sz = bfsize;
-- buf_sz = bfsize;
--
- priv->rx_copybreak = STMMAC_RX_COPYBREAK;
-
-- if (!priv->dma_conf.dma_tx_size)
-- priv->dma_conf.dma_tx_size = DMA_DEFAULT_TX_SIZE;
-- if (!priv->dma_conf.dma_rx_size)
-- priv->dma_conf.dma_rx_size = DMA_DEFAULT_RX_SIZE;
--
-- /* Earlier check for TBS */
-- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) {
-- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-- int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en;
--
-- /* Setup per-TXQ tbs flag before TX descriptor alloc */
-- tx_q->tbs |= tbs_en ? STMMAC_TBS_AVAIL : 0;
-- }
--
-- ret = alloc_dma_desc_resources(priv);
-- if (ret < 0) {
-- netdev_err(priv->dev, "%s: DMA descriptors allocation failed\n",
-- __func__);
-- goto dma_desc_error;
-- }
--
-- ret = init_dma_desc_rings(dev, GFP_KERNEL);
-- if (ret < 0) {
-- netdev_err(priv->dev, "%s: DMA descriptors initialization failed\n",
-- __func__);
-- goto init_error;
-- }
-+ buf_sz = dma_conf->dma_buf_sz;
-+ memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf));
-
- if (priv->plat->serdes_powerup) {
- ret = priv->plat->serdes_powerup(dev, priv->plat->bsp_priv);
-@@ -3806,14 +3908,28 @@ irq_error:
-
- stmmac_hw_teardown(dev);
- init_error:
-- free_dma_desc_resources(priv);
--dma_desc_error:
-+ free_dma_desc_resources(priv, &priv->dma_conf);
- phylink_disconnect_phy(priv->phylink);
- init_phy_error:
- pm_runtime_put(priv->device);
- return ret;
- }
-
-+static int stmmac_open(struct net_device *dev)
-+{
-+ struct stmmac_priv *priv = netdev_priv(dev);
-+ struct stmmac_dma_conf *dma_conf;
-+ int ret;
-+
-+ dma_conf = stmmac_setup_dma_desc(priv, dev->mtu);
-+ if (IS_ERR(dma_conf))
-+ return PTR_ERR(dma_conf);
-+
-+ ret = __stmmac_open(dev, dma_conf);
-+ kfree(dma_conf);
-+ return ret;
-+}
-+
- static void stmmac_fpe_stop_wq(struct stmmac_priv *priv)
- {
- set_bit(__FPE_REMOVING, &priv->fpe_task_state);
-@@ -3862,7 +3978,7 @@ static int stmmac_release(struct net_dev
- stmmac_stop_all_dma(priv);
-
- /* Release and free the Rx/Tx resources */
-- free_dma_desc_resources(priv);
-+ free_dma_desc_resources(priv, &priv->dma_conf);
-
- /* Disable the MAC Rx/Tx */
- stmmac_mac_set(priv, priv->ioaddr, false);
-@@ -6385,7 +6501,7 @@ void stmmac_disable_rx_queue(struct stmm
- spin_unlock_irqrestore(&ch->lock, flags);
-
- stmmac_stop_rx_dma(priv, queue);
-- __free_dma_rx_desc_resources(priv, queue);
-+ __free_dma_rx_desc_resources(priv, &priv->dma_conf, queue);
- }
-
- void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue)
-@@ -6396,21 +6512,21 @@ void stmmac_enable_rx_queue(struct stmma
- u32 buf_size;
- int ret;
-
-- ret = __alloc_dma_rx_desc_resources(priv, queue);
-+ ret = __alloc_dma_rx_desc_resources(priv, &priv->dma_conf, queue);
- if (ret) {
- netdev_err(priv->dev, "Failed to alloc RX desc.\n");
- return;
- }
-
-- ret = __init_dma_rx_desc_rings(priv, queue, GFP_KERNEL);
-+ ret = __init_dma_rx_desc_rings(priv, &priv->dma_conf, queue, GFP_KERNEL);
- if (ret) {
-- __free_dma_rx_desc_resources(priv, queue);
-+ __free_dma_rx_desc_resources(priv, &priv->dma_conf, queue);
- netdev_err(priv->dev, "Failed to init RX desc.\n");
- return;
- }
-
- stmmac_reset_rx_queue(priv, queue);
-- stmmac_clear_rx_descriptors(priv, queue);
-+ stmmac_clear_rx_descriptors(priv, &priv->dma_conf, queue);
-
- stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- rx_q->dma_rx_phy, rx_q->queue_index);
-@@ -6448,7 +6564,7 @@ void stmmac_disable_tx_queue(struct stmm
- spin_unlock_irqrestore(&ch->lock, flags);
-
- stmmac_stop_tx_dma(priv, queue);
-- __free_dma_tx_desc_resources(priv, queue);
-+ __free_dma_tx_desc_resources(priv, &priv->dma_conf, queue);
- }
-
- void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue)
-@@ -6458,21 +6574,21 @@ void stmmac_enable_tx_queue(struct stmma
- unsigned long flags;
- int ret;
-
-- ret = __alloc_dma_tx_desc_resources(priv, queue);
-+ ret = __alloc_dma_tx_desc_resources(priv, &priv->dma_conf, queue);
- if (ret) {
- netdev_err(priv->dev, "Failed to alloc TX desc.\n");
- return;
- }
-
-- ret = __init_dma_tx_desc_rings(priv, queue);
-+ ret = __init_dma_tx_desc_rings(priv, &priv->dma_conf, queue);
- if (ret) {
-- __free_dma_tx_desc_resources(priv, queue);
-+ __free_dma_tx_desc_resources(priv, &priv->dma_conf, queue);
- netdev_err(priv->dev, "Failed to init TX desc.\n");
- return;
- }
-
- stmmac_reset_tx_queue(priv, queue);
-- stmmac_clear_tx_descriptors(priv, queue);
-+ stmmac_clear_tx_descriptors(priv, &priv->dma_conf, queue);
-
- stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
- tx_q->dma_tx_phy, tx_q->queue_index);
-@@ -6512,7 +6628,7 @@ void stmmac_xdp_release(struct net_devic
- stmmac_stop_all_dma(priv);
-
- /* Release and free the Rx/Tx resources */
-- free_dma_desc_resources(priv);
-+ free_dma_desc_resources(priv, &priv->dma_conf);
-
- /* Disable the MAC Rx/Tx */
- stmmac_mac_set(priv, priv->ioaddr, false);
-@@ -6537,14 +6653,14 @@ int stmmac_xdp_open(struct net_device *d
- u32 chan;
- int ret;
-
-- ret = alloc_dma_desc_resources(priv);
-+ ret = alloc_dma_desc_resources(priv, &priv->dma_conf);
- if (ret < 0) {
- netdev_err(dev, "%s: DMA descriptors allocation failed\n",
- __func__);
- goto dma_desc_error;
- }
-
-- ret = init_dma_desc_rings(dev, GFP_KERNEL);
-+ ret = init_dma_desc_rings(dev, &priv->dma_conf, GFP_KERNEL);
- if (ret < 0) {
- netdev_err(dev, "%s: DMA descriptors initialization failed\n",
- __func__);
-@@ -6626,7 +6742,7 @@ irq_error:
-
- stmmac_hw_teardown(dev);
- init_error:
-- free_dma_desc_resources(priv);
-+ free_dma_desc_resources(priv, &priv->dma_conf);
- dma_desc_error:
- return ret;
- }
-@@ -7492,7 +7608,7 @@ int stmmac_resume(struct device *dev)
- stmmac_reset_queues_param(priv);
-
- stmmac_free_tx_skbufs(priv);
-- stmmac_clear_descriptors(priv);
-+ stmmac_clear_descriptors(priv, &priv->dma_conf);
-
- stmmac_hw_setup(ndev, false);
- stmmac_init_coalesce(priv);
diff --git a/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch b/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch
deleted file mode 100644
index e1d46f03a9..0000000000
--- a/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 3470079687448abac42deb62774253be1d6bdef3 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 23 Jul 2022 16:29:33 +0200
-Subject: [PATCH 5/5] net: ethernet: stmicro: stmmac: permit MTU change with
- interface up
-
-Remove the limitation where the interface needs to be down to change
-MTU by releasing and opening the stmmac driver to set the new MTU.
-Also call the set_filter function to correctly init the port.
-This permits to remove the EBUSY error while the ethernet port is
-running permitting a correct MTU change if for example a DSA request
-a MTU change for a switch CPU port.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 30 +++++++++++++++----
- 1 file changed, 24 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -5627,18 +5627,15 @@ static int stmmac_change_mtu(struct net_
- {
- struct stmmac_priv *priv = netdev_priv(dev);
- int txfifosz = priv->plat->tx_fifo_size;
-+ struct stmmac_dma_conf *dma_conf;
- const int mtu = new_mtu;
-+ int ret;
-
- if (txfifosz == 0)
- txfifosz = priv->dma_cap.tx_fifo_size;
-
- txfifosz /= priv->plat->tx_queues_to_use;
-
-- if (netif_running(dev)) {
-- netdev_err(priv->dev, "must be stopped to change its MTU\n");
-- return -EBUSY;
-- }
--
- if (stmmac_xdp_is_enabled(priv) && new_mtu > ETH_DATA_LEN) {
- netdev_dbg(priv->dev, "Jumbo frames not supported for XDP\n");
- return -EINVAL;
-@@ -5650,8 +5647,29 @@ static int stmmac_change_mtu(struct net_
- if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB))
- return -EINVAL;
-
-- dev->mtu = mtu;
-+ if (netif_running(dev)) {
-+ netdev_dbg(priv->dev, "restarting interface to change its MTU\n");
-+ /* Try to allocate the new DMA conf with the new mtu */
-+ dma_conf = stmmac_setup_dma_desc(priv, mtu);
-+ if (IS_ERR(dma_conf)) {
-+ netdev_err(priv->dev, "failed allocating new dma conf for new MTU %d\n",
-+ mtu);
-+ return PTR_ERR(dma_conf);
-+ }
-+
-+ stmmac_release(dev);
-+
-+ ret = __stmmac_open(dev, dma_conf);
-+ kfree(dma_conf);
-+ if (ret) {
-+ netdev_err(priv->dev, "failed reopening the interface after MTU change\n");
-+ return ret;
-+ }
-+
-+ stmmac_set_rx_mode(dev);
-+ }
-
-+ dev->mtu = mtu;
- netdev_update_features(dev);
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch b/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch
deleted file mode 100644
index 4f0d95f456..0000000000
--- a/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From a2550d3ce53c68f54042bc5e468c4d07491ffe0e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 12 Oct 2022 19:18:36 +0200
-Subject: [PATCH 1/2] net: dsa: qca8k: fix inband mgmt for big-endian systems
-
-The header and the data of the skb for the inband mgmt requires
-to be in little-endian. This is problematic for big-endian system
-as the mgmt header is written in the cpu byte order.
-
-Fix this by converting each value for the mgmt header and data to
-little-endian, and convert to cpu byte order the mgmt header and
-data sent by the switch.
-
-Fixes: 5950c7c0a68c ("net: dsa: qca8k: add support for mgmt read/write in Ethernet packet")
-Tested-by: Pawel Dembicki <paweldembicki@gmail.com>
-Tested-by: Lech Perczak <lech.perczak@gmail.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Lech Perczak <lech.perczak@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 63 ++++++++++++++++++++++++--------
- include/linux/dsa/tag_qca.h | 6 +--
- 2 files changed, 50 insertions(+), 19 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(str
- struct qca8k_mgmt_eth_data *mgmt_eth_data;
- struct qca8k_priv *priv = ds->priv;
- struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ u32 command;
- u8 len, cmd;
-+ int i;
-
- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
- mgmt_eth_data = &priv->mgmt_eth_data;
-
-- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
-- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
-+ command = get_unaligned_le32(&mgmt_ethhdr->command);
-+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
-+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
-
- /* Make sure the seq match the requested packet */
-- if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
-+ if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
- mgmt_eth_data->ack = true;
-
- if (cmd == MDIO_READ) {
-- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
-+ u32 *val = mgmt_eth_data->data;
-+
-+ *val = get_unaligned_le32(&mgmt_ethhdr->mdio_data);
-
- /* Get the rest of the 12 byte of data.
- * The read/write function will extract the requested data.
- */
-- if (len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(mgmt_eth_data->data + 1, skb->data,
-- QCA_HDR_MGMT_DATA2_LEN);
-+ if (len > QCA_HDR_MGMT_DATA1_LEN) {
-+ __le32 *data2 = (__le32 *)skb->data;
-+ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
-+ len - QCA_HDR_MGMT_DATA1_LEN);
-+
-+ val++;
-+
-+ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
-+ *val = get_unaligned_le32(data2);
-+ val++;
-+ data2++;
-+ }
-+ }
- }
-
- complete(&mgmt_eth_data->rw_done);
-@@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_
- struct qca_mgmt_ethhdr *mgmt_ethhdr;
- unsigned int real_len;
- struct sk_buff *skb;
-- u32 *data2;
-+ __le32 *data2;
-+ u32 command;
- u16 hdr;
-+ int i;
-
- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
- if (!skb)
-@@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_
- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
-
-- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
-- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
-+ command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
-+ command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
-+ command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
-+ command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
- QCA_HDR_MGMT_CHECK_CODE_VAL);
-
-+ put_unaligned_le32(command, &mgmt_ethhdr->command);
-+
- if (cmd == MDIO_WRITE)
-- mgmt_ethhdr->mdio_data = *val;
-+ put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data);
-
- mgmt_ethhdr->hdr = htons(hdr);
-
- data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
-- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
-- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
-+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) {
-+ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
-+ len - QCA_HDR_MGMT_DATA1_LEN);
-+
-+ val++;
-+
-+ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
-+ put_unaligned_le32(*val, data2);
-+ data2++;
-+ val++;
-+ }
-+ }
-
- return skb;
- }
-@@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_
- static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
- {
- struct qca_mgmt_ethhdr *mgmt_ethhdr;
-+ u32 seq;
-
-+ seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
-- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
-+ put_unaligned_le32(seq, &mgmt_ethhdr->seq);
- }
-
- static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
---- a/include/linux/dsa/tag_qca.h
-+++ b/include/linux/dsa/tag_qca.h
-@@ -56,9 +56,9 @@
-
- /* Special struct emulating a Ethernet header */
- struct qca_mgmt_ethhdr {
-- u32 command; /* command bit 31:0 */
-- u32 seq; /* seq 63:32 */
-- u32 mdio_data; /* first 4byte mdio */
-+ __le32 command; /* command bit 31:0 */
-+ __le32 seq; /* seq 63:32 */
-+ __le32 mdio_data; /* first 4byte mdio */
- __be16 hdr; /* qca hdr */
- } __packed;
-
diff --git a/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch b/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch
deleted file mode 100644
index d13014bf93..0000000000
--- a/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 0d4636f7d72df3179b20a2d32b647881917a5e2a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 12 Oct 2022 19:18:37 +0200
-Subject: [PATCH 2/2] net: dsa: qca8k: fix ethtool autocast mib for big-endian
- systems
-
-The switch sends autocast mib in little-endian. This is problematic for
-big-endian system as the values needs to be converted.
-
-Fix this by converting each mib value to cpu byte order.
-
-Fixes: 5c957c7ca78c ("net: dsa: qca8k: add support for mib autocast in Ethernet packet")
-Tested-by: Pawel Dembicki <paweldembicki@gmail.com>
-Tested-by: Lech Perczak <lech.perczak@gmail.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 20 ++++++++------------
- include/linux/dsa/tag_qca.h | 2 +-
- 2 files changed, 9 insertions(+), 13 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1668,9 +1668,9 @@ static void qca8k_mib_autocast_handler(s
- struct qca8k_priv *priv = ds->priv;
- const struct qca8k_mib_desc *mib;
- struct mib_ethhdr *mib_ethhdr;
-- int i, mib_len, offset = 0;
-- u64 *data;
-+ __le32 *data2;
- u8 port;
-+ int i;
-
- mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
- mib_eth_data = &priv->mib_eth_data;
-@@ -1682,28 +1682,24 @@ static void qca8k_mib_autocast_handler(s
- if (port != mib_eth_data->req_port)
- goto exit;
-
-- data = mib_eth_data->data;
-+ data2 = (__le32 *)skb->data;
-
- for (i = 0; i < priv->info->mib_count; i++) {
- mib = &ar8327_mib[i];
-
- /* First 3 mib are present in the skb head */
- if (i < 3) {
-- data[i] = mib_ethhdr->data[i];
-+ mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i);
- continue;
- }
-
-- mib_len = sizeof(uint32_t);
--
- /* Some mib are 64 bit wide */
- if (mib->size == 2)
-- mib_len = sizeof(uint64_t);
--
-- /* Copy the mib value from packet to the */
-- memcpy(data + i, skb->data + offset, mib_len);
-+ mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2);
-+ else
-+ mib_eth_data->data[i] = get_unaligned_le32(data2);
-
-- /* Set the offset for the next mib */
-- offset += mib_len;
-+ data2 += mib->size;
- }
-
- exit:
---- a/include/linux/dsa/tag_qca.h
-+++ b/include/linux/dsa/tag_qca.h
-@@ -68,7 +68,7 @@ enum mdio_cmd {
- };
-
- struct mib_ethhdr {
-- u32 data[3]; /* first 3 mib counter */
-+ __le32 data[3]; /* first 3 mib counter */
- __be16 hdr; /* qca hdr */
- } __packed;
-
diff --git a/target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch b/target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch
deleted file mode 100644
index b61e7ede49..0000000000
--- a/target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 9807ae69746196ee4bbffe7d22d22ab2b61c6ed0 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 29 Dec 2022 17:33:32 +0100
-Subject: [PATCH 1/5] net: dsa: qca8k: fix wrong length value for mgmt eth
- packet
-
-The assumption that Documentation was right about how this value work was
-wrong. It was discovered that the length value of the mgmt header is in
-step of word size.
-
-As an example to process 4 byte of data the correct length to set is 2.
-To process 8 byte 4, 12 byte 6, 16 byte 8...
-
-Odd values will always return the next size on the ack packet.
-(length of 3 (6 byte) will always return 8 bytes of data)
-
-This means that a value of 15 (0xf) actually means reading/writing 32 bytes
-of data instead of 16 bytes. This behaviour is totally absent and not
-documented in the switch Documentation.
-
-In fact from Documentation the max value that mgmt eth can process is
-16 byte of data while in reality it can process 32 bytes at once.
-
-To handle this we always round up the length after deviding it for word
-size. We check if the result is odd and we round another time to align
-to what the switch will provide in the ack packet.
-The workaround for the length limit of 15 is still needed as the length
-reg max value is 0xf(15)
-
-Reported-by: Ronald Wahl <ronald.wahl@raritan.com>
-Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
-Fixes: 90386223f44e ("net: dsa: qca8k: add support for larger read/write size with mgmt Ethernet")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Cc: stable@vger.kernel.org # v5.18+
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 45 +++++++++++++++++++++++++-------
- 1 file changed, 35 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -146,7 +146,16 @@ static void qca8k_rw_reg_ack_handler(str
-
- command = get_unaligned_le32(&mgmt_ethhdr->command);
- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
-+
- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
-+ /* Special case for len of 15 as this is the max value for len and needs to
-+ * be increased before converting it from word to dword.
-+ */
-+ if (len == 15)
-+ len++;
-+
-+ /* We can ignore odd value, we always round up them in the alloc function. */
-+ len *= sizeof(u16);
-
- /* Make sure the seq match the requested packet */
- if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
-@@ -193,17 +202,33 @@ static struct sk_buff *qca8k_alloc_mdio_
- if (!skb)
- return NULL;
-
-- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
-- * Actually for some reason the steps are:
-- * 0: nothing
-- * 1-4: first 4 byte
-- * 5-6: first 12 byte
-- * 7-15: all 16 byte
-+ /* Hdr mgmt length value is in step of word size.
-+ * As an example to process 4 byte of data the correct length to set is 2.
-+ * To process 8 byte 4, 12 byte 6, 16 byte 8...
-+ *
-+ * Odd values will always return the next size on the ack packet.
-+ * (length of 3 (6 byte) will always return 8 bytes of data)
-+ *
-+ * This means that a value of 15 (0xf) actually means reading/writing 32 bytes
-+ * of data.
-+ *
-+ * To correctly calculate the length we devide the requested len by word and
-+ * round up.
-+ * On the ack function we can skip the odd check as we already handle the
-+ * case here.
- */
-- if (len == 16)
-- real_len = 15;
-- else
-- real_len = len;
-+ real_len = DIV_ROUND_UP(len, sizeof(u16));
-+
-+ /* We check if the result len is odd and we round up another time to
-+ * the next size. (length of 3 will be increased to 4 as switch will always
-+ * return 8 bytes)
-+ */
-+ if (real_len % sizeof(u16) != 0)
-+ real_len++;
-+
-+ /* Max reg value is 0xf(15) but switch will always return the next size (32 byte) */
-+ if (real_len == 16)
-+ real_len--;
-
- skb_reset_mac_header(skb);
- skb_set_network_header(skb, skb->len);
diff --git a/target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch b/target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch
deleted file mode 100644
index 55ecb1eb42..0000000000
--- a/target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From d9dba91be71f03cc75bcf39fc0d5d99ff33f1ae0 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 29 Dec 2022 17:33:33 +0100
-Subject: [PATCH 2/5] net: dsa: tag_qca: fix wrong MGMT_DATA2 size
-
-It was discovered that MGMT_DATA2 can contain up to 28 bytes of data
-instead of the 12 bytes written in the Documentation by accounting the
-limit of 16 bytes declared in Documentation subtracting the first 4 byte
-in the packet header.
-
-Update the define with the real world value.
-
-Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
-Fixes: c2ee8181fddb ("net: dsa: tag_qca: add define for handling mgmt Ethernet packet")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Cc: stable@vger.kernel.org # v5.18+
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/dsa/tag_qca.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/include/linux/dsa/tag_qca.h
-+++ b/include/linux/dsa/tag_qca.h
-@@ -40,8 +40,8 @@
- QCA_HDR_MGMT_COMMAND_LEN + \
- QCA_HDR_MGMT_DATA1_LEN)
-
--#define QCA_HDR_MGMT_DATA2_LEN 12 /* Other 12 byte for the mdio data */
--#define QCA_HDR_MGMT_PADDING_LEN 34 /* Padding to reach the min Ethernet packet */
-+#define QCA_HDR_MGMT_DATA2_LEN 28 /* Other 28 byte for the mdio data */
-+#define QCA_HDR_MGMT_PADDING_LEN 18 /* Padding to reach the min Ethernet packet */
-
- #define QCA_HDR_MGMT_PKT_LEN (QCA_HDR_MGMT_HEADER_LEN + \
- QCA_HDR_LEN + \
diff --git a/target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch b/target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch
deleted file mode 100644
index c8e22fd1b8..0000000000
--- a/target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 03cb9e6d0b32b768e3d9d473c5c4ca1100877664 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 29 Dec 2022 17:33:34 +0100
-Subject: [PATCH 3/5] Revert "net: dsa: qca8k: cache lo and hi for mdio write"
-
-This reverts commit 2481d206fae7884cd07014fd1318e63af35e99eb.
-
-The Documentation is very confusing about the topic.
-The cache logic for hi and lo is wrong and actually miss some regs to be
-actually written.
-
-What the Documentation actually intended was that it's possible to skip
-writing hi OR lo if half of the reg is not needed to be written or read.
-
-Revert the change in favor of a better and correct implementation.
-
-Reported-by: Ronald Wahl <ronald.wahl@raritan.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Cc: stable@vger.kernel.org # v5.18+
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 61 +++++++-------------------------
- drivers/net/dsa/qca/qca8k.h | 5 ---
- 2 files changed, 12 insertions(+), 54 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -37,44 +37,6 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u
- }
-
- static int
--qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
--{
-- u16 *cached_lo = &priv->mdio_cache.lo;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (lo == *cached_lo)
-- return 0;
--
-- ret = bus->write(bus, phy_id, regnum, lo);
-- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit lo register\n");
--
-- *cached_lo = lo;
-- return 0;
--}
--
--static int
--qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
--{
-- u16 *cached_hi = &priv->mdio_cache.hi;
-- struct mii_bus *bus = priv->bus;
-- int ret;
--
-- if (hi == *cached_hi)
-- return 0;
--
-- ret = bus->write(bus, phy_id, regnum, hi);
-- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit hi register\n");
--
-- *cached_hi = hi;
-- return 0;
--}
--
--static int
- qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
- {
- int ret;
-@@ -97,7 +59,7 @@ qca8k_mii_read32(struct mii_bus *bus, in
- }
-
- static void
--qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
-+qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
- {
- u16 lo, hi;
- int ret;
-@@ -105,9 +67,12 @@ qca8k_mii_write32(struct qca8k_priv *pri
- lo = val & 0xffff;
- hi = (u16)(val >> 16);
-
-- ret = qca8k_set_lo(priv, phy_id, regnum, lo);
-+ ret = bus->write(bus, phy_id, regnum, lo);
- if (ret >= 0)
-- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
-+ ret = bus->write(bus, phy_id, regnum + 1, hi);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit register\n");
- }
-
- static int
-@@ -442,7 +407,7 @@ qca8k_regmap_write(void *ctx, uint32_t r
- if (ret < 0)
- goto exit;
-
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-
- exit:
- mutex_unlock(&bus->mdio_lock);
-@@ -475,7 +440,7 @@ qca8k_regmap_update_bits(void *ctx, uint
-
- val &= ~mask;
- val |= write_val;
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-
- exit:
- mutex_unlock(&bus->mdio_lock);
-@@ -750,14 +715,14 @@ qca8k_mdio_write(struct qca8k_priv *priv
- if (ret)
- goto exit;
-
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-
- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
- QCA8K_MDIO_MASTER_BUSY);
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-+ qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
-@@ -787,7 +752,7 @@ qca8k_mdio_read(struct qca8k_priv *priv,
- if (ret)
- goto exit;
-
-- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
-+ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-
- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
- QCA8K_MDIO_MASTER_BUSY);
-@@ -798,7 +763,7 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
-+ qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
-@@ -1914,8 +1879,6 @@ qca8k_sw_probe(struct mdio_device *mdiod
- }
-
- priv->mdio_cache.page = 0xffff;
-- priv->mdio_cache.lo = 0xffff;
-- priv->mdio_cache.hi = 0xffff;
-
- /* Check the detected switch id */
- ret = qca8k_read_switch_id(priv);
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -375,11 +375,6 @@ struct qca8k_mdio_cache {
- * mdio writes
- */
- u16 page;
--/* lo and hi can also be cached and from Documentation we can skip one
-- * extra mdio write if lo or hi is didn't change.
-- */
-- u16 lo;
-- u16 hi;
- };
-
- struct qca8k_priv {
diff --git a/target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch b/target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch
deleted file mode 100644
index c0320ad6f9..0000000000
--- a/target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From cfbd6de588ef659c198083205dc954a6d3ed2aec Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 29 Dec 2022 17:33:35 +0100
-Subject: [PATCH 4/5] net: dsa: qca8k: introduce single mii read/write lo/hi
-
-It may be useful to read/write just the lo or hi half of a reg.
-
-This is especially useful for phy poll with the use of mdio master.
-The mdio master reg is composed by the first 16 bit related to setup and
-the other half with the returned data or data to write.
-
-Refactor the mii function to permit single mii read/write of lo or hi
-half of the reg.
-
-Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 106 ++++++++++++++++++++++++-------
- 1 file changed, 84 insertions(+), 22 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -37,42 +37,104 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u
- }
-
- static int
--qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
- {
- int ret;
-+ u16 lo;
-
-- ret = bus->read(bus, phy_id, regnum);
-- if (ret >= 0) {
-- *val = ret;
-- ret = bus->read(bus, phy_id, regnum + 1);
-- *val |= ret << 16;
-- }
-+ lo = val & 0xffff;
-+ ret = bus->write(bus, phy_id, regnum, lo);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit lo register\n");
-+
-+ return ret;
-+}
-
-- if (ret < 0) {
-+static int
-+qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
-+{
-+ int ret;
-+ u16 hi;
-+
-+ hi = (u16)(val >> 16);
-+ ret = bus->write(bus, phy_id, regnum, hi);
-+ if (ret < 0)
- dev_err_ratelimited(&bus->dev,
-- "failed to read qca8k 32bit register\n");
-- *val = 0;
-- return ret;
-- }
-+ "failed to write qca8k 32bit hi register\n");
-
-+ return ret;
-+}
-+
-+static int
-+qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+{
-+ int ret;
-+
-+ ret = bus->read(bus, phy_id, regnum);
-+ if (ret < 0)
-+ goto err;
-+
-+ *val = ret & 0xffff;
- return 0;
-+
-+err:
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to read qca8k 32bit lo register\n");
-+ *val = 0;
-+
-+ return ret;
- }
-
--static void
--qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
-+static int
-+qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
- {
-- u16 lo, hi;
- int ret;
-
-- lo = val & 0xffff;
-- hi = (u16)(val >> 16);
-+ ret = bus->read(bus, phy_id, regnum);
-+ if (ret < 0)
-+ goto err;
-
-- ret = bus->write(bus, phy_id, regnum, lo);
-- if (ret >= 0)
-- ret = bus->write(bus, phy_id, regnum + 1, hi);
-+ *val = ret << 16;
-+ return 0;
-+
-+err:
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to read qca8k 32bit hi register\n");
-+ *val = 0;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+{
-+ u32 hi, lo;
-+ int ret;
-+
-+ *val = 0;
-+
-+ ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo);
- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit register\n");
-+ goto err;
-+
-+ ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi);
-+ if (ret < 0)
-+ goto err;
-+
-+ *val = lo | hi;
-+
-+err:
-+ return ret;
-+}
-+
-+static void
-+qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
-+{
-+ if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0)
-+ return;
-+
-+ qca8k_mii_write_hi(bus, phy_id, regnum + 1, val);
- }
-
- static int
diff --git a/target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch b/target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch
deleted file mode 100644
index 4cbb66cf35..0000000000
--- a/target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From a4165830ca237f2b3318faf62562bce8ce12a389 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 29 Dec 2022 17:33:36 +0100
-Subject: [PATCH 5/5] net: dsa: qca8k: improve mdio master read/write by using
- single lo/hi
-
-Improve mdio master read/write by using singe mii read/write lo/hi.
-
-In a read and write we need to poll the mdio master regs in a busy loop
-to check for a specific bit present in the upper half of the reg. We can
-ignore the other half since it won't contain useful data. This will save
-an additional useless read for each read and write operation.
-
-In a read operation the returned data is present in the mdio master reg
-lower half. We can ignore the other half since it won't contain useful
-data. This will save an additional useless read for each read operation.
-
-In a read operation it's needed to just set the hi half of the mdio
-master reg as the lo half will be replaced by the result. This will save
-an additional useless write for each read operation.
-
-Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -740,9 +740,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
-
- qca8k_split_addr(reg, &r1, &r2, &page);
-
-- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
-+ ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0,
- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-- bus, 0x10 | r2, r1, &val);
-+ bus, 0x10 | r2, r1 + 1, &val);
-
- /* Check if qca8k_read has failed for a different reason
- * before returnting -ETIMEDOUT
-@@ -784,7 +784,7 @@ qca8k_mdio_write(struct qca8k_priv *priv
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
-@@ -814,18 +814,18 @@ qca8k_mdio_read(struct qca8k_priv *priv,
- if (ret)
- goto exit;
-
-- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val);
-
- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
- QCA8K_MDIO_MASTER_BUSY);
- if (ret)
- goto exit;
-
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-+ ret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, &val);
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
diff --git a/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch b/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch
deleted file mode 100644
index 7cb21ed00d..0000000000
--- a/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-From 3265f421887847db9ae2c01a00645e33608556d8 Mon Sep 17 00:00:00 2001
-From: Robert Hancock <robert.hancock@calian.com>
-Date: Tue, 25 Jan 2022 10:54:09 -0600
-Subject: [PATCH] net: phy: at803x: add fiber support
-
-Previously this driver always forced the copper page to be selected,
-however for AR8031 in 100Base-FX or 1000Base-X modes, the fiber page
-needs to be selected. Set the appropriate mode based on the hardware
-mode_cfg strap selection.
-
-Enable the appropriate interrupt bits to detect fiber-side link up
-or down events.
-
-Update config_aneg and read_status methods to use the appropriate
-Clause 37 calls when fiber mode is in use.
-
-Signed-off-by: Robert Hancock <robert.hancock@calian.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 76 +++++++++++++++++++++++++++++++++++-----
- 1 file changed, 67 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -48,6 +48,8 @@
- #define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12)
- #define AT803X_INTR_ENABLE_LINK_FAIL BIT(11)
- #define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10)
-+#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8)
-+#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7)
- #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5)
- #define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1)
- #define AT803X_INTR_ENABLE_WOL BIT(0)
-@@ -82,6 +84,17 @@
-
- #define AT803X_MODE_CFG_MASK 0x0F
- #define AT803X_MODE_CFG_SGMII 0x01
-+#define AT803X_MODE_CFG_BASET_RGMII 0x00
-+#define AT803X_MODE_CFG_BASET_SGMII 0x01
-+#define AT803X_MODE_CFG_BX1000_RGMII_50OHM 0x02
-+#define AT803X_MODE_CFG_BX1000_RGMII_75OHM 0x03
-+#define AT803X_MODE_CFG_BX1000_CONV_50OHM 0x04
-+#define AT803X_MODE_CFG_BX1000_CONV_75OHM 0x05
-+#define AT803X_MODE_CFG_FX100_RGMII_50OHM 0x06
-+#define AT803X_MODE_CFG_FX100_CONV_50OHM 0x07
-+#define AT803X_MODE_CFG_RGMII_AUTO_MDET 0x0B
-+#define AT803X_MODE_CFG_FX100_RGMII_75OHM 0x0E
-+#define AT803X_MODE_CFG_FX100_CONV_75OHM 0x0F
-
- #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
- #define AT803X_PSSR_MR_AN_COMPLETE 0x0200
-@@ -199,6 +212,8 @@ struct at803x_priv {
- u16 clk_25m_mask;
- u8 smarteee_lpi_tw_1g;
- u8 smarteee_lpi_tw_100m;
-+ bool is_fiber;
-+ bool is_1000basex;
- struct regulator_dev *vddio_rdev;
- struct regulator_dev *vddh_rdev;
- struct regulator *vddio;
-@@ -674,7 +689,33 @@ static int at803x_probe(struct phy_devic
- return ret;
- }
-
-+ if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-+ int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
-+ int mode_cfg;
-+
-+ if (ccr < 0)
-+ goto err;
-+ mode_cfg = ccr & AT803X_MODE_CFG_MASK;
-+
-+ switch (mode_cfg) {
-+ case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
-+ case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
-+ priv->is_1000basex = true;
-+ fallthrough;
-+ case AT803X_MODE_CFG_FX100_RGMII_50OHM:
-+ case AT803X_MODE_CFG_FX100_RGMII_75OHM:
-+ priv->is_fiber = true;
-+ break;
-+ }
-+ }
-+
- return 0;
-+
-+err:
-+ if (priv->vddio)
-+ regulator_disable(priv->vddio);
-+
-+ return ret;
- }
-
- static void at803x_remove(struct phy_device *phydev)
-@@ -687,6 +728,7 @@ static void at803x_remove(struct phy_dev
-
- static int at803x_get_features(struct phy_device *phydev)
- {
-+ struct at803x_priv *priv = phydev->priv;
- int err;
-
- err = genphy_read_abilities(phydev);
-@@ -704,12 +746,13 @@ static int at803x_get_features(struct ph
- * As a result of that, ESTATUS_1000_XFULL is set
- * to 1 even when operating in copper TP mode.
- *
-- * Remove this mode from the supported link modes,
-- * as this driver currently only supports copper
-- * operation.
-+ * Remove this mode from the supported link modes
-+ * when not operating in 1000BaseX mode.
- */
-- linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-- phydev->supported);
-+ if (!priv->is_1000basex)
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-+ phydev->supported);
-+
- return 0;
- }
-
-@@ -773,15 +816,18 @@ static int at8031_pll_config(struct phy_
-
- static int at803x_config_init(struct phy_device *phydev)
- {
-+ struct at803x_priv *priv = phydev->priv;
- int ret;
-
- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
- /* Some bootloaders leave the fiber page selected.
-- * Switch to the copper page, as otherwise we read
-- * the PHY capabilities from the fiber side.
-+ * Switch to the appropriate page (fiber or copper), as otherwise we
-+ * read the PHY capabilities from the wrong page.
- */
- phy_lock_mdio_bus(phydev);
-- ret = at803x_write_page(phydev, AT803X_PAGE_COPPER);
-+ ret = at803x_write_page(phydev,
-+ priv->is_fiber ? AT803X_PAGE_FIBER :
-+ AT803X_PAGE_COPPER);
- phy_unlock_mdio_bus(phydev);
- if (ret)
- return ret;
-@@ -840,6 +886,7 @@ static int at803x_ack_interrupt(struct p
-
- static int at803x_config_intr(struct phy_device *phydev)
- {
-+ struct at803x_priv *priv = phydev->priv;
- int err;
- int value;
-
-@@ -856,6 +903,10 @@ static int at803x_config_intr(struct phy
- value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
- value |= AT803X_INTR_ENABLE_LINK_FAIL;
- value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
-+ if (priv->is_fiber) {
-+ value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
-+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
-+ }
-
- err = phy_write(phydev, AT803X_INTR_ENABLE, value);
- } else {
-@@ -923,8 +974,12 @@ static void at803x_link_change_notify(st
-
- static int at803x_read_status(struct phy_device *phydev)
- {
-+ struct at803x_priv *priv = phydev->priv;
- int ss, err, old_link = phydev->link;
-
-+ if (priv->is_1000basex)
-+ return genphy_c37_read_status(phydev);
-+
- /* Update the link, but return if there was an error */
- err = genphy_update_link(phydev);
- if (err)
-@@ -1023,6 +1078,7 @@ static int at803x_config_mdix(struct phy
-
- static int at803x_config_aneg(struct phy_device *phydev)
- {
-+ struct at803x_priv *priv = phydev->priv;
- int ret;
-
- ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
-@@ -1039,6 +1095,9 @@ static int at803x_config_aneg(struct phy
- return ret;
- }
-
-+ if (priv->is_1000basex)
-+ return genphy_c37_config_aneg(phydev);
-+
- return genphy_config_aneg(phydev);
- }
-
diff --git a/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch b/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch
deleted file mode 100644
index 8393cb32e8..0000000000
--- a/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From dc4d5fcc5d365c9f70ea3f5c09bdf70e988fad50 Mon Sep 17 00:00:00 2001
-From: Robert Hancock <robert.hancock@calian.com>
-Date: Tue, 25 Jan 2022 10:54:10 -0600
-Subject: [PATCH] net: phy: at803x: Support downstream SFP cage
-
-Add support for downstream SFP cages for AR8031 and AR8033. This is
-primarily intended for fiber modules or direct-attach cables, however
-copper modules which work in 1000Base-X mode may also function. Such
-modules are allowed with a warning.
-
-Signed-off-by: Robert Hancock <robert.hancock@calian.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 56 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 56 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -19,6 +19,8 @@
- #include <linux/regulator/of_regulator.h>
- #include <linux/regulator/driver.h>
- #include <linux/regulator/consumer.h>
-+#include <linux/phylink.h>
-+#include <linux/sfp.h>
- #include <dt-bindings/net/qca-ar803x.h>
-
- #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
-@@ -555,6 +557,55 @@ static int at8031_register_regulators(st
- return 0;
- }
-
-+static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+{
-+ struct phy_device *phydev = upstream;
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
-+ phy_interface_t iface;
-+
-+ linkmode_zero(phy_support);
-+ phylink_set(phy_support, 1000baseX_Full);
-+ phylink_set(phy_support, 1000baseT_Full);
-+ phylink_set(phy_support, Autoneg);
-+ phylink_set(phy_support, Pause);
-+ phylink_set(phy_support, Asym_Pause);
-+
-+ linkmode_zero(sfp_support);
-+ sfp_parse_support(phydev->sfp_bus, id, sfp_support);
-+ /* Some modules support 10G modes as well as others we support.
-+ * Mask out non-supported modes so the correct interface is picked.
-+ */
-+ linkmode_and(sfp_support, phy_support, sfp_support);
-+
-+ if (linkmode_empty(sfp_support)) {
-+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
-+ return -EINVAL;
-+ }
-+
-+ iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
-+
-+ /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
-+ * interface for use with SFP modules.
-+ * However, some copper modules detected as having a preferred SGMII
-+ * interface do default to and function in 1000Base-X mode, so just
-+ * print a warning and allow such modules, as they may have some chance
-+ * of working.
-+ */
-+ if (iface == PHY_INTERFACE_MODE_SGMII)
-+ dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
-+ else if (iface != PHY_INTERFACE_MODE_1000BASEX)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static const struct sfp_upstream_ops at803x_sfp_ops = {
-+ .attach = phy_sfp_attach,
-+ .detach = phy_sfp_detach,
-+ .module_insert = at803x_sfp_insert,
-+};
-+
- static int at803x_parse_dt(struct phy_device *phydev)
- {
- struct device_node *node = phydev->mdio.dev.of_node;
-@@ -662,6 +713,11 @@ static int at803x_parse_dt(struct phy_de
- phydev_err(phydev, "failed to get VDDIO regulator\n");
- return PTR_ERR(priv->vddio);
- }
-+
-+ /* Only AR8031/8033 support 1000Base-X for SFP modules */
-+ ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
-+ if (ret < 0)
-+ return ret;
- }
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch b/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch
deleted file mode 100644
index 53d6325c49..0000000000
--- a/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 9926de7315be3d606cc011a305ad9adb9e8e14c9 Mon Sep 17 00:00:00 2001
-From: Oleksij Rempel <o.rempel@pengutronix.de>
-Date: Sat, 18 Jun 2022 14:23:33 +0200
-Subject: [PATCH] net: phy: at803x: fix NULL pointer dereference on AR9331 PHY
-
-Latest kernel will explode on the PHY interrupt config, since it depends
-now on allocated priv. So, run probe to allocate priv to fix it.
-
- ar9331_switch ethernet.1:10 lan0 (uninitialized): PHY [!ahb!ethernet@1a000000!mdio!switch@10:00] driver [Qualcomm Atheros AR9331 built-in PHY] (irq=13)
- CPU 0 Unable to handle kernel paging request at virtual address 0000000a, epc == 8050e8a8, ra == 80504b34
- ...
- Call Trace:
- [<8050e8a8>] at803x_config_intr+0x5c/0xd0
- [<80504b34>] phy_request_interrupt+0xa8/0xd0
- [<8050289c>] phylink_bringup_phy+0x2d8/0x3ac
- [<80502b68>] phylink_fwnode_phy_connect+0x118/0x130
- [<8074d8ec>] dsa_slave_create+0x270/0x420
- [<80743b04>] dsa_port_setup+0x12c/0x148
- [<8074580c>] dsa_register_switch+0xaf0/0xcc0
- [<80511344>] ar9331_sw_probe+0x370/0x388
- [<8050cb78>] mdio_probe+0x44/0x70
- [<804df300>] really_probe+0x200/0x424
- [<804df7b4>] __driver_probe_device+0x290/0x298
- [<804df810>] driver_probe_device+0x54/0xe4
- [<804dfd50>] __device_attach_driver+0xe4/0x130
- [<804dcb00>] bus_for_each_drv+0xb4/0xd8
- [<804dfac4>] __device_attach+0x104/0x1a4
- [<804ddd24>] bus_probe_device+0x48/0xc4
- [<804deb44>] deferred_probe_work_func+0xf0/0x10c
- [<800a0ffc>] process_one_work+0x314/0x4d4
- [<800a17fc>] worker_thread+0x2a4/0x354
- [<800a9a54>] kthread+0x134/0x13c
- [<8006306c>] ret_from_kernel_thread+0x14/0x1c
-
-Same Issue would affect some other PHYs (QCA8081, QCA9561), so fix it
-too.
-
-Fixes: 3265f4218878 ("net: phy: at803x: add fiber support")
-Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1592,6 +1592,8 @@ static struct phy_driver at803x_driver[]
- /* ATHEROS AR9331 */
- PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
- .name = "Qualcomm Atheros AR9331 built-in PHY",
-+ .probe = at803x_probe,
-+ .remove = at803x_remove,
- .suspend = at803x_suspend,
- .resume = at803x_resume,
- .flags = PHY_POLL_CABLE_TEST,
diff --git a/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch b/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch
deleted file mode 100644
index cdae5b4ca4..0000000000
--- a/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 1f0dd412e34e177621769866bef347f0b22364df Mon Sep 17 00:00:00 2001
-From: Wei Yongjun <weiyongjun1@huawei.com>
-Date: Fri, 18 Nov 2022 10:36:35 +0000
-Subject: [PATCH] net: phy: at803x: fix error return code in at803x_probe()
-
-Fix to return a negative error code from the ccr read error handling
-case instead of 0, as done elsewhere in this function.
-
-Fixes: 3265f4218878 ("net: phy: at803x: add fiber support")
-Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20221118103635.254256-1-weiyongjun@huaweicloud.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/at803x.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -749,8 +749,10 @@ static int at803x_probe(struct phy_devic
- int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
- int mode_cfg;
-
-- if (ccr < 0)
-+ if (ccr < 0) {
-+ ret = ccr;
- goto err;
-+ }
- mode_cfg = ccr & AT803X_MODE_CFG_MASK;
-
- switch (mode_cfg) {
diff --git a/target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch b/target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch
deleted file mode 100644
index 44f0864e9a..0000000000
--- a/target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 789d3eeb2367f92193a0882f7cdab03f0f9d6930 Mon Sep 17 00:00:00 2001
-From: Thomas Perrot <thomas.perrot@bootlin.com>
-Date: Thu, 16 Dec 2021 13:42:27 +0530
-Subject: [PATCH] bus: mhi: pci_generic: Introduce Sierra EM919X support
-
-Add support for EM919X modems, this modem series is based on SDX55
-qcom chip.
-
-It is mandatory to use the same ring for control+data and diag events.
-
-Link: https://lore.kernel.org/r/20211123081541.648426-1-thomas.perrot@bootlin.com
-Tested-by: Aleksander Morgado <aleksander@aleksander.es>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Signed-off-by: Thomas Perrot <thomas.perrot@bootlin.com>
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Link: https://lore.kernel.org/r/20211216081227.237749-11-manivannan.sadhasivam@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/bus/mhi/host/pci_generic.c | 43 +++++++++++++++++++++++++++++++++++
- 1 file changed, 43 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -406,6 +406,46 @@ static const struct mhi_pci_dev_info mhi
- .mru_default = 32768,
- };
-
-+static const struct mhi_channel_config mhi_sierra_em919x_channels[] = {
-+ MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0),
-+ MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 256, 0),
-+ MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 0),
-+ MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 0),
-+ MHI_CHANNEL_CONFIG_UL(12, "MBIM", 128, 0),
-+ MHI_CHANNEL_CONFIG_DL(13, "MBIM", 128, 0),
-+ MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0),
-+ MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0),
-+ MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),
-+ MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),
-+ MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 512, 1),
-+ MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 512, 2),
-+};
-+
-+static struct mhi_event_config modem_sierra_em919x_mhi_events[] = {
-+ /* first ring is control+data and DIAG ring */
-+ MHI_EVENT_CONFIG_CTRL(0, 2048),
-+ /* Hardware channels request dedicated hardware event rings */
-+ MHI_EVENT_CONFIG_HW_DATA(1, 2048, 100),
-+ MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101)
-+};
-+
-+static const struct mhi_controller_config modem_sierra_em919x_config = {
-+ .max_channels = 128,
-+ .timeout_ms = 24000,
-+ .num_channels = ARRAY_SIZE(mhi_sierra_em919x_channels),
-+ .ch_cfg = mhi_sierra_em919x_channels,
-+ .num_events = ARRAY_SIZE(modem_sierra_em919x_mhi_events),
-+ .event_cfg = modem_sierra_em919x_mhi_events,
-+};
-+
-+static const struct mhi_pci_dev_info mhi_sierra_em919x_info = {
-+ .name = "sierra-em919x",
-+ .config = &modem_sierra_em919x_config,
-+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM,
-+ .dma_data_width = 32,
-+ .sideband_wake = false,
-+};
-+
- static const struct mhi_channel_config mhi_telit_fn980_hw_v1_channels[] = {
- MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0),
- MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0),
-@@ -480,6 +520,9 @@ static const struct mhi_pci_dev_info mhi
- };
-
- static const struct pci_device_id mhi_pci_id_table[] = {
-+ /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */
-+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200),
-+ .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info },
- /* Telit FN980 hardware revision v1 */
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x1C5D, 0x2000),
- .driver_data = (kernel_ulong_t) &mhi_telit_fn980_hw_v1_info },
diff --git a/target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch b/target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch
deleted file mode 100644
index 3c71a27b79..0000000000
--- a/target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From f369e9ad52ec9361827e21a631b7198c9fca438e Mon Sep 17 00:00:00 2001
-From: Koen Vandeputte <koen.vandeputte@citymesh.com>
-Date: Wed, 31 Aug 2022 12:03:49 +0200
-Subject: [PATCH] bus: mhi: host: always print detected modem name
-
-This harmless print provides a very easy way of knowing
-if the modem is detected properly during probing.
-
-Promote it to an informational print so no hassle is required
-enabling kernel debugging info to obtain it.
-
-The rationale here is that:
-On a lot of low-storage embedded devices, extensive kernel
-debugging info is not always present as this would
-increase it's size to much causing partition size issues.
-
-Signed-off-by: Koen Vandeputte <koen.vandeputte@citymesh.com>
-Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
-Link: https://lore.kernel.org/r/20220831100349.1488762-1-koen.vandeputte@citymesh.com
-[mani: added missing review tags]
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -806,7 +806,7 @@ static int mhi_pci_probe(struct pci_dev
- struct mhi_controller *mhi_cntrl;
- int err;
-
-- dev_dbg(&pdev->dev, "MHI PCI device found: %s\n", info->name);
-+ dev_info(&pdev->dev, "MHI PCI device found: %s\n", info->name);
-
- /* mhi_pdev.mhi_cntrl must be zero-initialized */
- mhi_pdev = devm_kzalloc(&pdev->dev, sizeof(*mhi_pdev), GFP_KERNEL);
diff --git a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch
deleted file mode 100644
index 7f16b936cd..0000000000
--- a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From e19de30d20809af3221ef8a2648b8a8a52e02d90 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 21 Sep 2022 01:23:14 +0100
-Subject: [PATCH 1/1] net: dsa: mt7530: add support for in-band link status
-
-Read link status from SGMII PCS for in-band managed 2500Base-X and
-1000Base-X connection on a MAC port of the MT7531. This is needed to
-get the SFP cage working which is connected to SGMII interface of
-port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board.
-While at it also handle an_complete for both the autoneg and the
-non-autoneg codepath.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 50 +++++++++++++++++++++++++++++-----------
- drivers/net/dsa/mt7530.h | 1 +
- 2 files changed, 38 insertions(+), 13 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2979,9 +2979,6 @@ mt7531_mac_config(struct dsa_switch *ds,
- case PHY_INTERFACE_MODE_NA:
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_2500BASEX:
-- if (phylink_autoneg_inband(mode))
-- return -EINVAL;
--
- return mt7531_sgmii_setup_mode_force(priv, port, interface);
- default:
- return -EINVAL;
-@@ -3057,13 +3054,6 @@ unsupported:
- return;
- }
-
-- if (phylink_autoneg_inband(mode) &&
-- state->interface != PHY_INTERFACE_MODE_SGMII) {
-- dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
-- __func__);
-- return;
-- }
--
- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
- mcr_new = mcr_cur;
- mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-@@ -3200,6 +3190,9 @@ static void mt753x_phylink_get_caps(stru
- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000FD;
-
-+ if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
-+ config->mac_capabilities |= MAC_2500FD;
-+
- /* This driver does not make use of the speed, duplex, pause or the
- * advertisement in its mac_config, so it is safe to mark this driver
- * as non-legacy.
-@@ -3265,6 +3258,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
-
- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
- state->link = !!(status & MT7531_SGMII_LINK_STATUS);
-+ state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
- if (state->interface == PHY_INTERFACE_MODE_SGMII &&
- (status & MT7531_SGMII_AN_ENABLE)) {
- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
-@@ -3295,16 +3289,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
- return 0;
- }
-
-+static void
-+mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
-+ struct phylink_link_state *state)
-+{
-+ unsigned int val;
-+
-+ val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-+ state->link = !!(val & MT7531_SGMII_LINK_STATUS);
-+ if (!state->link)
-+ return;
-+
-+ state->an_complete = state->link;
-+
-+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
-+ state->speed = SPEED_2500;
-+ else
-+ state->speed = SPEED_1000;
-+
-+ state->duplex = DUPLEX_FULL;
-+ state->pause = MLO_PAUSE_NONE;
-+}
-+
- static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
- struct phylink_link_state *state)
- {
- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
- int port = pcs_to_mt753x_pcs(pcs)->port;
-
-- if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+ if (state->interface == PHY_INTERFACE_MODE_SGMII) {
- mt7531_sgmii_pcs_get_state_an(priv, port, state);
-- else
-- state->link = false;
-+ return;
-+ } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
-+ (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
-+ mt7531_sgmii_pcs_get_state_inband(priv, port, state);
-+ return;
-+ }
-+
-+ state->link = false;
- }
-
- static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -3345,6 +3367,8 @@ mt753x_setup(struct dsa_switch *ds)
- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
- priv->pcs[i].priv = priv;
- priv->pcs[i].port = i;
-+ if (mt753x_is_mac_port(i))
-+ priv->pcs[i].pcs.poll = 1;
- }
-
- ret = priv->info->sw_setup(ds);
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -410,6 +410,7 @@ enum mt7530_vlan_port_acc_frm {
- #define MT7531_SGMII_LINK_STATUS BIT(18)
- #define MT7531_SGMII_AN_ENABLE BIT(12)
- #define MT7531_SGMII_AN_RESTART BIT(9)
-+#define MT7531_SGMII_AN_COMPLETE BIT(21)
-
- /* Register for SGMII PCS_SPPED_ABILITY */
- #define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
diff --git a/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch b/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch
deleted file mode 100644
index 77cd336d36..0000000000
--- a/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 8475c4b70b040f9d8cbc308100f2c4d865f810b3 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 13 Sep 2022 20:06:27 +0100
-Subject: [PATCH 1/1] net: sfp: re-implement soft state polling setup
-
-Re-implement the decision making for soft state polling. Instead of
-generating the soft state mask in sfp_soft_start_poll() by looking at
-which GPIOs are available, record their availability in
-sfp_sm_mod_probe() in sfp->state_hw_mask.
-
-This will then allow us to clear bits in sfp->state_hw_mask in module
-specific quirks when the hardware signals should not be used, thereby
-allowing us to switch to using the software state polling.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++++------------
- 1 file changed, 26 insertions(+), 12 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -240,6 +240,7 @@ struct sfp {
- bool need_poll;
-
- struct mutex st_mutex; /* Protects state */
-+ unsigned int state_hw_mask;
- unsigned int state_soft_mask;
- unsigned int state;
- struct delayed_work poll;
-@@ -505,17 +506,18 @@ static void sfp_soft_set_state(struct sf
- static void sfp_soft_start_poll(struct sfp *sfp)
- {
- const struct sfp_eeprom_id *id = &sfp->id;
-+ unsigned int mask = 0;
-
- sfp->state_soft_mask = 0;
-- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE &&
-- !sfp->gpio[GPIO_TX_DISABLE])
-- sfp->state_soft_mask |= SFP_F_TX_DISABLE;
-- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT &&
-- !sfp->gpio[GPIO_TX_FAULT])
-- sfp->state_soft_mask |= SFP_F_TX_FAULT;
-- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS &&
-- !sfp->gpio[GPIO_LOS])
-- sfp->state_soft_mask |= SFP_F_LOS;
-+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE)
-+ mask |= SFP_F_TX_DISABLE;
-+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT)
-+ mask |= SFP_F_TX_FAULT;
-+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS)
-+ mask |= SFP_F_LOS;
-+
-+ // Poll the soft state for hardware pins we want to ignore
-+ sfp->state_soft_mask = ~sfp->state_hw_mask & mask;
-
- if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
- !sfp->need_poll)
-@@ -529,10 +531,11 @@ static void sfp_soft_stop_poll(struct sf
-
- static unsigned int sfp_get_state(struct sfp *sfp)
- {
-- unsigned int state = sfp->get_state(sfp);
-+ unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT);
-+ unsigned int state;
-
-- if (state & SFP_F_PRESENT &&
-- sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT))
-+ state = sfp->get_state(sfp) & sfp->state_hw_mask;
-+ if (state & SFP_F_PRESENT && soft)
- state |= sfp_soft_get_state(sfp);
-
- return state;
-@@ -1942,6 +1945,15 @@ static int sfp_sm_mod_probe(struct sfp *
- if (ret < 0)
- return ret;
-
-+ /* Initialise state bits to use from hardware */
-+ sfp->state_hw_mask = SFP_F_PRESENT;
-+ if (sfp->gpio[GPIO_TX_DISABLE])
-+ sfp->state_hw_mask |= SFP_F_TX_DISABLE;
-+ if (sfp->gpio[GPIO_TX_FAULT])
-+ sfp->state_hw_mask |= SFP_F_TX_FAULT;
-+ if (sfp->gpio[GPIO_LOS])
-+ sfp->state_hw_mask |= SFP_F_LOS;
-+
- if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) &&
- !memcmp(id.base.vendor_pn, "3FE46541AA ", 16))
- sfp->module_t_start_up = T_START_UP_BAD_GPON;
-@@ -2568,6 +2580,8 @@ static int sfp_probe(struct platform_dev
- return PTR_ERR(sfp->gpio[i]);
- }
-
-+ sfp->state_hw_mask = SFP_F_PRESENT;
-+
- sfp->get_state = sfp_gpio_get_state;
- sfp->set_state = sfp_gpio_set_state;
-
diff --git a/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch b/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch
deleted file mode 100644
index 02fa28c5af..0000000000
--- a/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch
+++ /dev/null
@@ -1,291 +0,0 @@
-From 23571c7b96437483d28a990c906cc81f5f66374e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 13 Sep 2022 20:06:32 +0100
-Subject: [PATCH 1/1] net: sfp: move quirk handling into sfp.c
-
-We need to handle more quirks than just those which affect the link
-modes of the module. Move the quirk lookup into sfp.c, and pass the
-quirk to sfp-bus.c
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/sfp-bus.c | 98 ++-------------------------------------
- drivers/net/phy/sfp.c | 94 ++++++++++++++++++++++++++++++++++++-
- drivers/net/phy/sfp.h | 9 +++-
- 3 files changed, 104 insertions(+), 97 deletions(-)
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -10,12 +10,6 @@
-
- #include "sfp.h"
-
--struct sfp_quirk {
-- const char *vendor;
-- const char *part;
-- void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
--};
--
- /**
- * struct sfp_bus - internal representation of a sfp bus
- */
-@@ -38,93 +32,6 @@ struct sfp_bus {
- bool started;
- };
-
--static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
-- unsigned long *modes)
--{
-- phylink_set(modes, 2500baseX_Full);
--}
--
--static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
-- unsigned long *modes)
--{
-- /* Ubiquiti U-Fiber Instant module claims that support all transceiver
-- * types including 10G Ethernet which is not truth. So clear all claimed
-- * modes and set only one mode which module supports: 1000baseX_Full.
-- */
-- phylink_zero(modes);
-- phylink_set(modes, 1000baseX_Full);
--}
--
--static const struct sfp_quirk sfp_quirks[] = {
-- {
-- // Alcatel Lucent G-010S-P can operate at 2500base-X, but
-- // incorrectly report 2500MBd NRZ in their EEPROM
-- .vendor = "ALCATELLUCENT",
-- .part = "G010SP",
-- .modes = sfp_quirk_2500basex,
-- }, {
-- // Alcatel Lucent G-010S-A can operate at 2500base-X, but
-- // report 3.2GBd NRZ in their EEPROM
-- .vendor = "ALCATELLUCENT",
-- .part = "3FE46541AA",
-- .modes = sfp_quirk_2500basex,
-- }, {
-- // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
-- // NRZ in their EEPROM
-- .vendor = "HUAWEI",
-- .part = "MA5671A",
-- .modes = sfp_quirk_2500basex,
-- }, {
-- // Lantech 8330-262D-E can operate at 2500base-X, but
-- // incorrectly report 2500MBd NRZ in their EEPROM
-- .vendor = "Lantech",
-- .part = "8330-262D-E",
-- .modes = sfp_quirk_2500basex,
-- }, {
-- .vendor = "UBNT",
-- .part = "UF-INSTANT",
-- .modes = sfp_quirk_ubnt_uf_instant,
-- },
--};
--
--static size_t sfp_strlen(const char *str, size_t maxlen)
--{
-- size_t size, i;
--
-- /* Trailing characters should be filled with space chars */
-- for (i = 0, size = 0; i < maxlen; i++)
-- if (str[i] != ' ')
-- size = i + 1;
--
-- return size;
--}
--
--static bool sfp_match(const char *qs, const char *str, size_t len)
--{
-- if (!qs)
-- return true;
-- if (strlen(qs) != len)
-- return false;
-- return !strncmp(qs, str, len);
--}
--
--static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
--{
-- const struct sfp_quirk *q;
-- unsigned int i;
-- size_t vs, ps;
--
-- vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
-- ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
--
-- for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
-- if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
-- sfp_match(q->part, id->base.vendor_pn, ps))
-- return q;
--
-- return NULL;
--}
--
- /**
- * sfp_parse_port() - Parse the EEPROM base ID, setting the port type
- * @bus: a pointer to the &struct sfp_bus structure for the sfp module
-@@ -786,12 +693,13 @@ void sfp_link_down(struct sfp_bus *bus)
- }
- EXPORT_SYMBOL_GPL(sfp_link_down);
-
--int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id)
-+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
-+ const struct sfp_quirk *quirk)
- {
- const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
- int ret = 0;
-
-- bus->sfp_quirk = sfp_lookup_quirk(id);
-+ bus->sfp_quirk = quirk;
-
- if (ops && ops->module_insert)
- ret = ops->module_insert(bus->upstream, id);
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -259,6 +259,8 @@ struct sfp {
- unsigned int module_t_start_up;
- bool tx_fault_ignore;
-
-+ const struct sfp_quirk *quirk;
-+
- #if IS_ENABLED(CONFIG_HWMON)
- struct sfp_diag diag;
- struct delayed_work hwmon_probe;
-@@ -315,6 +317,93 @@ static const struct of_device_id sfp_of_
- };
- MODULE_DEVICE_TABLE(of, sfp_of_match);
-
-+static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
-+ unsigned long *modes)
-+{
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes);
-+}
-+
-+static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
-+ unsigned long *modes)
-+{
-+ /* Ubiquiti U-Fiber Instant module claims that support all transceiver
-+ * types including 10G Ethernet which is not truth. So clear all claimed
-+ * modes and set only one mode which module supports: 1000baseX_Full.
-+ */
-+ linkmode_zero(modes);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
-+}
-+
-+static const struct sfp_quirk sfp_quirks[] = {
-+ {
-+ // Alcatel Lucent G-010S-P can operate at 2500base-X, but
-+ // incorrectly report 2500MBd NRZ in their EEPROM
-+ .vendor = "ALCATELLUCENT",
-+ .part = "G010SP",
-+ .modes = sfp_quirk_2500basex,
-+ }, {
-+ // Alcatel Lucent G-010S-A can operate at 2500base-X, but
-+ // report 3.2GBd NRZ in their EEPROM
-+ .vendor = "ALCATELLUCENT",
-+ .part = "3FE46541AA",
-+ .modes = sfp_quirk_2500basex,
-+ }, {
-+ // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
-+ // NRZ in their EEPROM
-+ .vendor = "HUAWEI",
-+ .part = "MA5671A",
-+ .modes = sfp_quirk_2500basex,
-+ }, {
-+ // Lantech 8330-262D-E can operate at 2500base-X, but
-+ // incorrectly report 2500MBd NRZ in their EEPROM
-+ .vendor = "Lantech",
-+ .part = "8330-262D-E",
-+ .modes = sfp_quirk_2500basex,
-+ }, {
-+ .vendor = "UBNT",
-+ .part = "UF-INSTANT",
-+ .modes = sfp_quirk_ubnt_uf_instant,
-+ },
-+};
-+
-+static size_t sfp_strlen(const char *str, size_t maxlen)
-+{
-+ size_t size, i;
-+
-+ /* Trailing characters should be filled with space chars */
-+ for (i = 0, size = 0; i < maxlen; i++)
-+ if (str[i] != ' ')
-+ size = i + 1;
-+
-+ return size;
-+}
-+
-+static bool sfp_match(const char *qs, const char *str, size_t len)
-+{
-+ if (!qs)
-+ return true;
-+ if (strlen(qs) != len)
-+ return false;
-+ return !strncmp(qs, str, len);
-+}
-+
-+static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
-+{
-+ const struct sfp_quirk *q;
-+ unsigned int i;
-+ size_t vs, ps;
-+
-+ vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
-+ ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
-+
-+ for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
-+ if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
-+ sfp_match(q->part, id->base.vendor_pn, ps))
-+ return q;
-+
-+ return NULL;
-+}
-+
- static unsigned long poll_jiffies;
-
- static unsigned int sfp_gpio_get_state(struct sfp *sfp)
-@@ -1966,6 +2055,8 @@ static int sfp_sm_mod_probe(struct sfp *
- else
- sfp->tx_fault_ignore = false;
-
-+ sfp->quirk = sfp_lookup_quirk(&id);
-+
- return 0;
- }
-
-@@ -2077,7 +2168,8 @@ static void sfp_sm_module(struct sfp *sf
- break;
-
- /* Report the module insertion to the upstream device */
-- err = sfp_module_insert(sfp->sfp_bus, &sfp->id);
-+ err = sfp_module_insert(sfp->sfp_bus, &sfp->id,
-+ sfp->quirk);
- if (err < 0) {
- sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
- break;
---- a/drivers/net/phy/sfp.h
-+++ b/drivers/net/phy/sfp.h
-@@ -6,6 +6,12 @@
-
- struct sfp;
-
-+struct sfp_quirk {
-+ const char *vendor;
-+ const char *part;
-+ void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
-+};
-+
- struct sfp_socket_ops {
- void (*attach)(struct sfp *sfp);
- void (*detach)(struct sfp *sfp);
-@@ -23,7 +29,8 @@ int sfp_add_phy(struct sfp_bus *bus, str
- void sfp_remove_phy(struct sfp_bus *bus);
- void sfp_link_up(struct sfp_bus *bus);
- void sfp_link_down(struct sfp_bus *bus);
--int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
-+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
-+ const struct sfp_quirk *quirk);
- void sfp_module_remove(struct sfp_bus *bus);
- int sfp_module_start(struct sfp_bus *bus);
- void sfp_module_stop(struct sfp_bus *bus);
diff --git a/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch b/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch
deleted file mode 100644
index b076676cff..0000000000
--- a/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 275416754e9a262c97a1ad6f806a4bc6e0464aa2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 13 Sep 2022 20:06:37 +0100
-Subject: [PATCH 1/1] net: sfp: move Alcatel Lucent 3FE46541AA fixup
-
-Add a new fixup mechanism to the SFP quirks, and use it for this
-module.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/sfp.c | 14 +++++++++-----
- drivers/net/phy/sfp.h | 1 +
- 2 files changed, 10 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -317,6 +317,11 @@ static const struct of_device_id sfp_of_
- };
- MODULE_DEVICE_TABLE(of, sfp_of_match);
-
-+static void sfp_fixup_long_startup(struct sfp *sfp)
-+{
-+ sfp->module_t_start_up = T_START_UP_BAD_GPON;
-+}
-+
- static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
- unsigned long *modes)
- {
-@@ -347,6 +352,7 @@ static const struct sfp_quirk sfp_quirks
- .vendor = "ALCATELLUCENT",
- .part = "3FE46541AA",
- .modes = sfp_quirk_2500basex,
-+ .fixup = sfp_fixup_long_startup,
- }, {
- // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
- // NRZ in their EEPROM
-@@ -2043,11 +2049,7 @@ static int sfp_sm_mod_probe(struct sfp *
- if (sfp->gpio[GPIO_LOS])
- sfp->state_hw_mask |= SFP_F_LOS;
-
-- if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) &&
-- !memcmp(id.base.vendor_pn, "3FE46541AA ", 16))
-- sfp->module_t_start_up = T_START_UP_BAD_GPON;
-- else
-- sfp->module_t_start_up = T_START_UP;
-+ sfp->module_t_start_up = T_START_UP;
-
- if (!memcmp(id.base.vendor_name, "HUAWEI ", 16) &&
- !memcmp(id.base.vendor_pn, "MA5671A ", 16))
-@@ -2056,6 +2058,8 @@ static int sfp_sm_mod_probe(struct sfp *
- sfp->tx_fault_ignore = false;
-
- sfp->quirk = sfp_lookup_quirk(&id);
-+ if (sfp->quirk && sfp->quirk->fixup)
-+ sfp->quirk->fixup(sfp);
-
- return 0;
- }
---- a/drivers/net/phy/sfp.h
-+++ b/drivers/net/phy/sfp.h
-@@ -10,6 +10,7 @@ struct sfp_quirk {
- const char *vendor;
- const char *part;
- void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
-+ void (*fixup)(struct sfp *sfp);
- };
-
- struct sfp_socket_ops {
diff --git a/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch b/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch
deleted file mode 100644
index 7f856e5b5b..0000000000
--- a/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 5029be761161374a3624aa7b4670174c35449bf5 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 13 Sep 2022 20:06:42 +0100
-Subject: [PATCH 1/1] net: sfp: move Huawei MA5671A fixup
-
-Move this module over to the new fixup mechanism.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/sfp.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -322,6 +322,11 @@ static void sfp_fixup_long_startup(struc
- sfp->module_t_start_up = T_START_UP_BAD_GPON;
- }
-
-+static void sfp_fixup_ignore_tx_fault(struct sfp *sfp)
-+{
-+ sfp->tx_fault_ignore = true;
-+}
-+
- static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
- unsigned long *modes)
- {
-@@ -359,6 +364,7 @@ static const struct sfp_quirk sfp_quirks
- .vendor = "HUAWEI",
- .part = "MA5671A",
- .modes = sfp_quirk_2500basex,
-+ .fixup = sfp_fixup_ignore_tx_fault,
- }, {
- // Lantech 8330-262D-E can operate at 2500base-X, but
- // incorrectly report 2500MBd NRZ in their EEPROM
-@@ -2051,11 +2057,7 @@ static int sfp_sm_mod_probe(struct sfp *
-
- sfp->module_t_start_up = T_START_UP;
-
-- if (!memcmp(id.base.vendor_name, "HUAWEI ", 16) &&
-- !memcmp(id.base.vendor_pn, "MA5671A ", 16))
-- sfp->tx_fault_ignore = true;
-- else
-- sfp->tx_fault_ignore = false;
-+ sfp->tx_fault_ignore = false;
-
- sfp->quirk = sfp_lookup_quirk(&id);
- if (sfp->quirk && sfp->quirk->fixup)
diff --git a/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch b/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch
deleted file mode 100644
index 81108e19c1..0000000000
--- a/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 73472c830eae5fce2107f7f086f1e6827d215caf Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 13 Sep 2022 20:06:48 +0100
-Subject: [PATCH 1/1] net: sfp: add support for HALNy GPON SFP
-
-Add a quirk for the HALNy HL-GSFP module, which appears to have an
-inverted RX_LOS signal, and maybe uses TX_FAULT as a serial port
-transmit pin. Rather than use these hardware signals, switch to
-using software polling for these status signals.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/sfp-bus.c | 2 +-
- drivers/net/phy/sfp.c | 21 ++++++++++++++++++---
- 2 files changed, 19 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -283,7 +283,7 @@ void sfp_parse_support(struct sfp_bus *b
- phylink_set(modes, 2500baseX_Full);
- }
-
-- if (bus->sfp_quirk)
-+ if (bus->sfp_quirk && bus->sfp_quirk->modes)
- bus->sfp_quirk->modes(id, modes);
-
- linkmode_or(support, support, modes);
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -327,6 +327,15 @@ static void sfp_fixup_ignore_tx_fault(st
- sfp->tx_fault_ignore = true;
- }
-
-+static void sfp_fixup_halny_gsfp(struct sfp *sfp)
-+{
-+ /* Ignore the TX_FAULT and LOS signals on this module.
-+ * these are possibly used for other purposes on this
-+ * module, e.g. a serial port.
-+ */
-+ sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS);
-+}
-+
- static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
- unsigned long *modes)
- {
-@@ -359,6 +368,10 @@ static const struct sfp_quirk sfp_quirks
- .modes = sfp_quirk_2500basex,
- .fixup = sfp_fixup_long_startup,
- }, {
-+ .vendor = "HALNy",
-+ .part = "HL-GSFP",
-+ .fixup = sfp_fixup_halny_gsfp,
-+ }, {
- // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
- // NRZ in their EEPROM
- .vendor = "HUAWEI",
-@@ -375,16 +388,18 @@ static const struct sfp_quirk sfp_quirks
- .vendor = "UBNT",
- .part = "UF-INSTANT",
- .modes = sfp_quirk_ubnt_uf_instant,
-- },
-+ }
- };
-
- static size_t sfp_strlen(const char *str, size_t maxlen)
- {
- size_t size, i;
-
-- /* Trailing characters should be filled with space chars */
-+ /* Trailing characters should be filled with space chars, but
-+ * some manufacturers can't read SFF-8472 and use NUL.
-+ */
- for (i = 0, size = 0; i < maxlen; i++)
-- if (str[i] != ' ')
-+ if (str[i] != ' ' && str[i] != '\0')
- size = i + 1;
-
- return size;
diff --git a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch
deleted file mode 100644
index 8060ad5afc..0000000000
--- a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch
+++ /dev/null
@@ -1,514 +0,0 @@
-From patchwork Thu Mar 9 10:57:44 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 13167235
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-Date: Thu, 9 Mar 2023 10:57:44 +0000
-From: Daniel Golle <daniel@makrotopia.org>
-To: netdev@vger.kernel.org, linux-mediatek@lists.infradead.org,
- linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
- Russell King <linux@armlinux.org.uk>,
- Heiner Kallweit <hkallweit1@gmail.com>,
- Lorenzo Bianconi <lorenzo@kernel.org>,
- Mark Lee <Mark-MC.Lee@mediatek.com>,
- John Crispin <john@phrozen.org>, Felix Fietkau <nbd@nbd.name>,
- AngeloGioacchino Del Regno
- <angelogioacchino.delregno@collabora.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- DENG Qingfang <dqfext@gmail.com>,
- Landen Chao <Landen.Chao@mediatek.com>,
- Sean Wang <sean.wang@mediatek.com>,
- Paolo Abeni <pabeni@redhat.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Eric Dumazet <edumazet@google.com>,
- "David S. Miller" <davem@davemloft.net>,
- Vladimir Oltean <olteanv@gmail.com>,
- Florian Fainelli <f.fainelli@gmail.com>,
- Andrew Lunn <andrew@lunn.ch>,
- Vladimir Oltean <vladimir.oltean@nxp.com>
-Cc: =?iso-8859-1?q?Bj=F8rn?= Mork <bjorn@mork.no>,
- Frank Wunderlich <frank-w@public-files.de>,
- Alexander Couzens <lynxis@fe80.eu>
-Subject: [PATCH net-next v13 11/16] net: dsa: mt7530: use external PCS driver
-Message-ID:
- <2ac2ee40d3b0e705461b50613fda6a7edfdbc4b3.1678357225.git.daniel@makrotopia.org>
-References: <cover.1678357225.git.daniel@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-In-Reply-To: <cover.1678357225.git.daniel@makrotopia.org>
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-Implement regmap access wrappers, for now only to be used by the
-pcs-mtk driver.
-Make use of external PCS driver and drop the reduntant implementation
-in mt7530.c.
-As a nice side effect the SGMII registers can now also more easily be
-inspected for debugging via /sys/kernel/debug/regmap.
-
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
----
- drivers/net/dsa/Kconfig | 1 +
- drivers/net/dsa/mt7530.c | 277 ++++++++++-----------------------------
- drivers/net/dsa/mt7530.h | 47 +------
- 3 files changed, 71 insertions(+), 254 deletions(-)
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -37,6 +37,7 @@ config NET_DSA_MT7530
- tristate "MediaTek MT753x and MT7621 Ethernet switch support"
- select NET_DSA_TAG_MTK
- select MEDIATEK_GE_PHY
-+ select PCS_MTK_LYNXI
- help
- This enables support for the MediaTek MT7530, MT7531, and MT7621
- Ethernet switch chips.
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -14,6 +14,7 @@
- #include <linux/of_mdio.h>
- #include <linux/of_net.h>
- #include <linux/of_platform.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
- #include <linux/phylink.h>
- #include <linux/regmap.h>
- #include <linux/regulator/consumer.h>
-@@ -2831,128 +2832,11 @@ static int mt7531_rgmii_setup(struct mt7
- return 0;
- }
-
--static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-- phy_interface_t interface, int speed, int duplex)
--{
-- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-- int port = pcs_to_mt753x_pcs(pcs)->port;
-- unsigned int val;
--
-- /* For adjusting speed and duplex of SGMII force mode. */
-- if (interface != PHY_INTERFACE_MODE_SGMII ||
-- phylink_autoneg_inband(mode))
-- return;
--
-- /* SGMII force mode setting */
-- val = mt7530_read(priv, MT7531_SGMII_MODE(port));
-- val &= ~MT7531_SGMII_IF_MODE_MASK;
--
-- switch (speed) {
-- case SPEED_10:
-- val |= MT7531_SGMII_FORCE_SPEED_10;
-- break;
-- case SPEED_100:
-- val |= MT7531_SGMII_FORCE_SPEED_100;
-- break;
-- case SPEED_1000:
-- val |= MT7531_SGMII_FORCE_SPEED_1000;
-- break;
-- }
--
-- /* MT7531 SGMII 1G force mode can only work in full duplex mode,
-- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
-- *
-- * The speed check is unnecessary as the MAC capabilities apply
-- * this restriction. --rmk
-- */
-- if ((speed == SPEED_10 || speed == SPEED_100) &&
-- duplex != DUPLEX_FULL)
-- val |= MT7531_SGMII_FORCE_HALF_DUPLEX;
--
-- mt7530_write(priv, MT7531_SGMII_MODE(port), val);
--}
--
- static bool mt753x_is_mac_port(u32 port)
- {
- return (port == 5 || port == 6);
- }
-
--static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
-- phy_interface_t interface)
--{
-- u32 val;
--
-- if (!mt753x_is_mac_port(port))
-- return -EINVAL;
--
-- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-- MT7531_SGMII_PHYA_PWD);
--
-- val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
-- val &= ~MT7531_RG_TPHY_SPEED_MASK;
-- /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B
-- * encoding.
-- */
-- val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ?
-- MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G;
-- mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
--
-- mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
--
-- /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex
-- * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
-- */
-- mt7530_rmw(priv, MT7531_SGMII_MODE(port),
-- MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS,
-- MT7531_SGMII_FORCE_SPEED_1000);
--
-- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
--
-- return 0;
--}
--
--static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
-- phy_interface_t interface)
--{
-- if (!mt753x_is_mac_port(port))
-- return -EINVAL;
--
-- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-- MT7531_SGMII_PHYA_PWD);
--
-- mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
-- MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G);
--
-- mt7530_set(priv, MT7531_SGMII_MODE(port),
-- MT7531_SGMII_REMOTE_FAULT_DIS |
-- MT7531_SGMII_SPEED_DUPLEX_AN);
--
-- mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port),
-- MT7531_SGMII_TX_CONFIG_MASK, 1);
--
-- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
--
-- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART);
--
-- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
--
-- return 0;
--}
--
--static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
--{
-- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-- int port = pcs_to_mt753x_pcs(pcs)->port;
-- u32 val;
--
-- /* Only restart AN when AN is enabled */
-- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-- if (val & MT7531_SGMII_AN_ENABLE) {
-- val |= MT7531_SGMII_AN_RESTART;
-- mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
-- }
--}
--
- static int
- mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
-@@ -2975,11 +2859,11 @@ mt7531_mac_config(struct dsa_switch *ds,
- phydev = dp->slave->phydev;
- return mt7531_rgmii_setup(priv, port, interface, phydev);
- case PHY_INTERFACE_MODE_SGMII:
-- return mt7531_sgmii_setup_mode_an(priv, port, interface);
- case PHY_INTERFACE_MODE_NA:
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_2500BASEX:
-- return mt7531_sgmii_setup_mode_force(priv, port, interface);
-+ /* handled in SGMII PCS driver */
-+ return 0;
- default:
- return -EINVAL;
- }
-@@ -3004,11 +2888,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
-
- switch (interface) {
- case PHY_INTERFACE_MODE_TRGMII:
-+ return &priv->pcs[port].pcs;
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_2500BASEX:
-- return &priv->pcs[port].pcs;
--
-+ return priv->ports[port].sgmii_pcs;
- default:
- return NULL;
- }
-@@ -3249,86 +3133,6 @@ static void mt7530_pcs_get_state(struct
- state->pause |= MLO_PAUSE_TX;
- }
-
--static int
--mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
-- struct phylink_link_state *state)
--{
-- u32 status, val;
-- u16 config_reg;
--
-- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-- state->link = !!(status & MT7531_SGMII_LINK_STATUS);
-- state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
-- if (state->interface == PHY_INTERFACE_MODE_SGMII &&
-- (status & MT7531_SGMII_AN_ENABLE)) {
-- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
-- config_reg = val >> 16;
--
-- switch (config_reg & LPA_SGMII_SPD_MASK) {
-- case LPA_SGMII_1000:
-- state->speed = SPEED_1000;
-- break;
-- case LPA_SGMII_100:
-- state->speed = SPEED_100;
-- break;
-- case LPA_SGMII_10:
-- state->speed = SPEED_10;
-- break;
-- default:
-- dev_err(priv->dev, "invalid sgmii PHY speed\n");
-- state->link = false;
-- return -EINVAL;
-- }
--
-- if (config_reg & LPA_SGMII_FULL_DUPLEX)
-- state->duplex = DUPLEX_FULL;
-- else
-- state->duplex = DUPLEX_HALF;
-- }
--
-- return 0;
--}
--
--static void
--mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
-- struct phylink_link_state *state)
--{
-- unsigned int val;
--
-- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-- state->link = !!(val & MT7531_SGMII_LINK_STATUS);
-- if (!state->link)
-- return;
--
-- state->an_complete = state->link;
--
-- if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
-- state->speed = SPEED_2500;
-- else
-- state->speed = SPEED_1000;
--
-- state->duplex = DUPLEX_FULL;
-- state->pause = MLO_PAUSE_NONE;
--}
--
--static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
-- struct phylink_link_state *state)
--{
-- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-- int port = pcs_to_mt753x_pcs(pcs)->port;
--
-- if (state->interface == PHY_INTERFACE_MODE_SGMII) {
-- mt7531_sgmii_pcs_get_state_an(priv, port, state);
-- return;
-- } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
-- (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
-- mt7531_sgmii_pcs_get_state_inband(priv, port, state);
-- return;
-- }
--
-- state->link = false;
--}
--
- static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface,
- const unsigned long *advertising,
-@@ -3348,18 +3152,57 @@ static const struct phylink_pcs_ops mt75
- .pcs_an_restart = mt7530_pcs_an_restart,
- };
-
--static const struct phylink_pcs_ops mt7531_pcs_ops = {
-- .pcs_validate = mt753x_pcs_validate,
-- .pcs_get_state = mt7531_pcs_get_state,
-- .pcs_config = mt753x_pcs_config,
-- .pcs_an_restart = mt7531_pcs_an_restart,
-- .pcs_link_up = mt7531_pcs_link_up,
-+static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-+{
-+ struct mt7530_priv *priv = context;
-+
-+ *val = mt7530_read(priv, reg);
-+ return 0;
-+};
-+
-+static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-+{
-+ struct mt7530_priv *priv = context;
-+
-+ mt7530_write(priv, reg, val);
-+ return 0;
-+};
-+
-+static int mt7530_regmap_update_bits(void *context, unsigned int reg,
-+ unsigned int mask, unsigned int val)
-+{
-+ struct mt7530_priv *priv = context;
-+
-+ mt7530_rmw(priv, reg, mask, val);
-+ return 0;
-+};
-+
-+static const struct regmap_bus mt7531_regmap_bus = {
-+ .reg_write = mt7530_regmap_write,
-+ .reg_read = mt7530_regmap_read,
-+ .reg_update_bits = mt7530_regmap_update_bits,
-+};
-+
-+#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
-+ { \
-+ .name = _name, \
-+ .reg_bits = 16, \
-+ .val_bits = 32, \
-+ .reg_stride = 4, \
-+ .reg_base = _reg_base, \
-+ .max_register = 0x17c, \
-+ }
-+
-+static const struct regmap_config mt7531_pcs_config[] = {
-+ MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
-+ MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
- };
-
- static int
- mt753x_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-+ struct regmap *regmap;
- int i, ret;
-
- /* Initialise the PCS devices */
-@@ -3367,8 +3210,6 @@ mt753x_setup(struct dsa_switch *ds)
- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
- priv->pcs[i].priv = priv;
- priv->pcs[i].port = i;
-- if (mt753x_is_mac_port(i))
-- priv->pcs[i].pcs.poll = 1;
- }
-
- ret = priv->info->sw_setup(ds);
-@@ -3383,6 +3224,16 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-+ if (priv->id == ID_MT7531)
-+ for (i = 0; i < 2; i++) {
-+ regmap = devm_regmap_init(ds->dev,
-+ &mt7531_regmap_bus, priv,
-+ &mt7531_pcs_config[i]);
-+ priv->ports[5 + i].sgmii_pcs =
-+ mtk_pcs_lynxi_create(ds->dev, regmap,
-+ MT7531_PHYA_CTRL_SIGNAL3, 0);
-+ }
-+
- return ret;
- }
-
-@@ -3475,7 +3326,7 @@ static const struct mt753x_info mt753x_t
- },
- [ID_MT7531] = {
- .id = ID_MT7531,
-- .pcs_ops = &mt7531_pcs_ops,
-+ .pcs_ops = &mt7530_pcs_ops,
- .sw_setup = mt7531_setup,
- .phy_read = mt7531_ind_phy_read,
- .phy_write = mt7531_ind_phy_write,
-@@ -3583,7 +3434,7 @@ static void
- mt7530_remove(struct mdio_device *mdiodev)
- {
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-- int ret = 0;
-+ int ret = 0, i;
-
- if (!priv)
- return;
-@@ -3602,6 +3453,10 @@ mt7530_remove(struct mdio_device *mdiode
- mt7530_free_irq(priv);
-
- dsa_unregister_switch(priv->ds);
-+
-+ for (i = 0; i < 2; ++i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-+
- mutex_destroy(&priv->reg_mutex);
-
- dev_set_drvdata(&mdiodev->dev, NULL);
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm {
- CCR_TX_OCT_CNT_BAD)
-
- /* MT7531 SGMII register group */
--#define MT7531_SGMII_REG_BASE 0x5000
--#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
-- ((p) - 5) * 0x1000 + (r))
--
--/* Register forSGMII PCS_CONTROL_1 */
--#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00)
--#define MT7531_SGMII_LINK_STATUS BIT(18)
--#define MT7531_SGMII_AN_ENABLE BIT(12)
--#define MT7531_SGMII_AN_RESTART BIT(9)
--#define MT7531_SGMII_AN_COMPLETE BIT(21)
--
--/* Register for SGMII PCS_SPPED_ABILITY */
--#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
--#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0)
--#define MT7531_SGMII_TX_CONFIG BIT(0)
--
--/* Register for SGMII_MODE */
--#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20)
--#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8)
--#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1)
--#define MT7531_SGMII_FORCE_DUPLEX BIT(4)
--#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2)
--#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3)
--#define MT7531_SGMII_FORCE_SPEED_100 BIT(2)
--#define MT7531_SGMII_FORCE_SPEED_10 0
--#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1)
--
--enum mt7531_sgmii_force_duplex {
-- MT7531_SGMII_FORCE_FULL_DUPLEX = 0,
-- MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10,
--};
--
--/* Fields of QPHY_PWR_STATE_CTRL */
--#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8)
--#define MT7531_SGMII_PHYA_PWD BIT(4)
--
--/* Values of SGMII SPEED */
--#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128)
--#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3))
--#define MT7531_RG_TPHY_SPEED_1_25G 0x0
--#define MT7531_RG_TPHY_SPEED_3_125G BIT(2)
-+#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000)
-+#define MT7531_PHYA_CTRL_SIGNAL3 0x128
-
- /* Register for system reset */
- #define MT7530_SYS_CTRL 0x7000
-@@ -741,13 +702,13 @@ struct mt7530_fdb {
- * @pm: The matrix used to show all connections with the port.
- * @pvid: The VLAN specified is to be considered a PVID at ingress. Any
- * untagged frames will be assigned to the related VLAN.
-- * @vlan_filtering: The flags indicating whether the port that can recognize
-- * VLAN-tagged frames.
-+ * @sgmii_pcs: Pointer to PCS instance for SerDes ports
- */
- struct mt7530_port {
- bool enable;
- u32 pm;
- u16 pvid;
-+ struct phylink_pcs *sgmii_pcs;
- };
-
- /* Port 5 interface select definitions */
diff --git a/target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch b/target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch
deleted file mode 100644
index 413c73f547..0000000000
--- a/target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From ad651d68cee75e9ac20002254c4e5d09ee67a84b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 2 Apr 2023 12:44:37 +0100
-Subject: [PATCH] net: sfp: add quirk enabling 2500Base-x for HG MXPD-483II
-
-The HG MXPD-483II 1310nm SFP module is meant to operate with 2500Base-X,
-however, in their EEPROM they incorrectly specify:
- Transceiver type : Ethernet: 1000BASE-LX
- ...
- BR, Nominal : 2600MBd
-
-Use sfp_quirk_2500basex for this module to allow 2500Base-X mode anyway.
-
-https://forum.banana-pi.org/t/bpi-r3-sfp-module-compatibility/14573/60
-
-Reported-by: chowtom <chowtom@gmail.com>
-Tested-by: chowtom <chowtom@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/sfp.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -372,6 +372,10 @@ static const struct sfp_quirk sfp_quirks
- .part = "HL-GSFP",
- .fixup = sfp_fixup_halny_gsfp,
- }, {
-+ .vendor = "HG GENUINE",
-+ .part = "MXPD-483II",
-+ .modes = sfp_quirk_2500basex,
-+ }, {
- // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
- // NRZ in their EEPROM
- .vendor = "HUAWEI",
diff --git a/target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch b/target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch
deleted file mode 100644
index 87d7ff6154..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From bdb6cfe7512f7a214815a3092f0be50963dcacbc Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sat, 18 Jun 2022 11:28:32 +0100
-Subject: [PATCH] net: mii: add mii_bmcr_encode_fixed()
-
-Add a function to encode a fixed speed/duplex to a BMCR value.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/mii.h | 35 +++++++++++++++++++++++++++++++++++
- 1 file changed, 35 insertions(+)
-
---- a/include/linux/mii.h
-+++ b/include/linux/mii.h
-@@ -595,4 +595,39 @@ static inline u8 mii_resolve_flowctrl_fd
- return cap;
- }
-
-+/**
-+ * mii_bmcr_encode_fixed - encode fixed speed/duplex settings to a BMCR value
-+ * @speed: a SPEED_* value
-+ * @duplex: a DUPLEX_* value
-+ *
-+ * Encode the speed and duplex to a BMCR value. 2500, 1000, 100 and 10 Mbps are
-+ * supported. 2500Mbps is encoded to 1000Mbps. Other speeds are encoded as 10
-+ * Mbps. Unknown duplex values are encoded to half-duplex.
-+ */
-+static inline u16 mii_bmcr_encode_fixed(int speed, int duplex)
-+{
-+ u16 bmcr;
-+
-+ switch (speed) {
-+ case SPEED_2500:
-+ case SPEED_1000:
-+ bmcr = BMCR_SPEED1000;
-+ break;
-+
-+ case SPEED_100:
-+ bmcr = BMCR_SPEED100;
-+ break;
-+
-+ case SPEED_10:
-+ default:
-+ bmcr = BMCR_SPEED10;
-+ break;
-+ }
-+
-+ if (duplex == DUPLEX_FULL)
-+ bmcr |= BMCR_FULLDPLX;
-+
-+ return bmcr;
-+}
-+
- #endif /* __LINUX_MII_H__ */
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch b/target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch
deleted file mode 100644
index cfd0034ee6..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From b6f56cddb5f57a0b8da0ce582232a2f1933558c6 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:19 +0100
-Subject: [PATCH 04/16] net: dsa: mt7530: make some noise if register read
- fails
-
-Simply returning the negative error value instead of the read value
-doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1)
-so this kind of error will not go unnoticed.
-
-Suggested-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -225,9 +225,10 @@ mt7530_mii_read(struct mt7530_priv *priv
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0) {
-+ WARN_ON_ONCE(1);
- dev_err(&bus->dev,
- "failed to read mt7530 register\n");
-- return ret;
-+ return 0;
- }
-
- lo = bus->read(bus, 0x1f, r);
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch
deleted file mode 100644
index 62d9c78cca..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From 9ecc00164dc2300dfcd40afe549a8ee951dfea9f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:30 +0100
-Subject: [PATCH 05/16] net: dsa: mt7530: refactor SGMII PCS creation
-
-Instead of macro templates use a dedidated function and allocated
-regmap_config when creating the regmaps for the pcs-mtk-lynxi
-instances.
-This is in preparation to switching to use unlocked regmap accessors
-and have regmap's locking API handle locking for us.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++-------------
- 1 file changed, 50 insertions(+), 24 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3184,26 +3184,56 @@ static const struct regmap_bus mt7531_re
- .reg_update_bits = mt7530_regmap_update_bits,
- };
-
--#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
-- { \
-- .name = _name, \
-- .reg_bits = 16, \
-- .val_bits = 32, \
-- .reg_stride = 4, \
-- .reg_base = _reg_base, \
-- .max_register = 0x17c, \
-+static int
-+mt7531_create_sgmii(struct mt7530_priv *priv)
-+{
-+ struct regmap_config *mt7531_pcs_config[2];
-+ struct phylink_pcs *pcs;
-+ struct regmap *regmap;
-+ int i, ret = 0;
-+
-+ for (i = 0; i < 2; i++) {
-+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
-+ sizeof(struct regmap_config),
-+ GFP_KERNEL);
-+ if (!mt7531_pcs_config[i]) {
-+ ret = -ENOMEM;
-+ break;
-+ }
-+
-+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
-+ mt7531_pcs_config[i]->reg_bits = 16;
-+ mt7531_pcs_config[i]->val_bits = 32;
-+ mt7531_pcs_config[i]->reg_stride = 4;
-+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
-+ mt7531_pcs_config[i]->max_register = 0x17c;
-+
-+ regmap = devm_regmap_init(priv->dev,
-+ &mt7531_regmap_bus, priv,
-+ mt7531_pcs_config[i]);
-+ if (IS_ERR(regmap)) {
-+ ret = PTR_ERR(regmap);
-+ break;
-+ }
-+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
-+ MT7531_PHYA_CTRL_SIGNAL3, 0);
-+ if (!pcs) {
-+ ret = -ENXIO;
-+ break;
-+ }
-+ priv->ports[5 + i].sgmii_pcs = pcs;
- }
-
--static const struct regmap_config mt7531_pcs_config[] = {
-- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
-- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
--};
-+ if (ret && i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
-+
-+ return ret;
-+}
-
- static int
- mt753x_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-- struct regmap *regmap;
- int i, ret;
-
- /* Initialise the PCS devices */
-@@ -3225,15 +3255,11 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-- if (priv->id == ID_MT7531)
-- for (i = 0; i < 2; i++) {
-- regmap = devm_regmap_init(ds->dev,
-- &mt7531_regmap_bus, priv,
-- &mt7531_pcs_config[i]);
-- priv->ports[5 + i].sgmii_pcs =
-- mtk_pcs_lynxi_create(ds->dev, regmap,
-- MT7531_PHYA_CTRL_SIGNAL3, 0);
-- }
-+ if (priv->id == ID_MT7531) {
-+ ret = mt7531_create_sgmii(priv);
-+ if (ret && priv->irq)
-+ mt7530_free_irq_common(priv);
-+ }
-
- return ret;
- }
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch
deleted file mode 100644
index e9f69a8777..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 1bd099c49f65ed923b9f19b8c4b3cd1ff0024091 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:40 +0100
-Subject: [PATCH 06/16] net: dsa: mt7530: use unlocked regmap accessors
-
-Instead of wrapping the locked register accessor functions, use the
-unlocked variants and add locking wrapper functions to let regmap
-handle the locking.
-
-This is a preparation towards being able to always use regmap to
-access switch registers instead of open-coded accessor functions.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 23 ++++++++++++++---------
- 1 file changed, 14 insertions(+), 9 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3157,7 +3157,7 @@ static int mt7530_regmap_read(void *cont
- {
- struct mt7530_priv *priv = context;
-
-- *val = mt7530_read(priv, reg);
-+ *val = mt7530_mii_read(priv, reg);
- return 0;
- };
-
-@@ -3165,23 +3165,25 @@ static int mt7530_regmap_write(void *con
- {
- struct mt7530_priv *priv = context;
-
-- mt7530_write(priv, reg, val);
-+ mt7530_mii_write(priv, reg, val);
- return 0;
- };
-
--static int mt7530_regmap_update_bits(void *context, unsigned int reg,
-- unsigned int mask, unsigned int val)
-+static void
-+mt7530_mdio_regmap_lock(void *mdio_lock)
- {
-- struct mt7530_priv *priv = context;
-+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
-+}
-
-- mt7530_rmw(priv, reg, mask, val);
-- return 0;
--};
-+static void
-+mt7530_mdio_regmap_unlock(void *mdio_lock)
-+{
-+ mutex_unlock(mdio_lock);
-+}
-
- static const struct regmap_bus mt7531_regmap_bus = {
- .reg_write = mt7530_regmap_write,
- .reg_read = mt7530_regmap_read,
-- .reg_update_bits = mt7530_regmap_update_bits,
- };
-
- static int
-@@ -3207,6 +3209,9 @@ mt7531_create_sgmii(struct mt7530_priv *
- mt7531_pcs_config[i]->reg_stride = 4;
- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
- mt7531_pcs_config[i]->max_register = 0x17c;
-+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
-+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
-+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-
- regmap = devm_regmap_init(priv->dev,
- &mt7531_regmap_bus, priv,
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch
deleted file mode 100644
index a2dcc08b02..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch
+++ /dev/null
@@ -1,224 +0,0 @@
-From a08c045580e060a6886bbb656c50ae20b0c780b5 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:52 +0100
-Subject: [PATCH 07/16] net: dsa: mt7530: use regmap to access switch register
- space
-
-Use regmap API to access the switch register space.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++----------------
- drivers/net/dsa/mt7530.h | 2 +
- 2 files changed, 62 insertions(+), 39 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -184,9 +184,9 @@ core_clear(struct mt7530_priv *priv, u32
- }
-
- static int
--mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
- {
-- struct mii_bus *bus = priv->bus;
-+ struct mii_bus *bus = context;
- u16 page, r, lo, hi;
- int ret;
-
-@@ -198,24 +198,34 @@ mt7530_mii_write(struct mt7530_priv *pri
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0)
-- goto err;
-+ return ret;
-
- ret = bus->write(bus, 0x1f, r, lo);
- if (ret < 0)
-- goto err;
-+ return ret;
-
- ret = bus->write(bus, 0x1f, 0x10, hi);
--err:
-+ return ret;
-+}
-+
-+static int
-+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ int ret;
-+
-+ ret = regmap_write(priv->regmap, reg, val);
-+
- if (ret < 0)
-- dev_err(&bus->dev,
-+ dev_err(priv->dev,
- "failed to write mt7530 register\n");
-+
- return ret;
- }
-
--static u32
--mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
-+static int
-+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
- {
-- struct mii_bus *bus = priv->bus;
-+ struct mii_bus *bus = context;
- u16 page, r, lo, hi;
- int ret;
-
-@@ -224,17 +234,32 @@ mt7530_mii_read(struct mt7530_priv *priv
-
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
-- if (ret < 0) {
-+ if (ret < 0)
-+ return ret;
-+
-+ lo = bus->read(bus, 0x1f, r);
-+ hi = bus->read(bus, 0x1f, 0x10);
-+
-+ *val = (hi << 16) | (lo & 0xffff);
-+
-+ return 0;
-+}
-+
-+static u32
-+mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
-+{
-+ int ret;
-+ u32 val;
-+
-+ ret = regmap_read(priv->regmap, reg, &val);
-+ if (ret) {
- WARN_ON_ONCE(1);
-- dev_err(&bus->dev,
-+ dev_err(priv->dev,
- "failed to read mt7530 register\n");
- return 0;
- }
-
-- lo = bus->read(bus, 0x1f, r);
-- hi = bus->read(bus, 0x1f, 0x10);
--
-- return (hi << 16) | (lo & 0xffff);
-+ return val;
- }
-
- static void
-@@ -284,14 +309,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32
- u32 mask, u32 set)
- {
- struct mii_bus *bus = priv->bus;
-- u32 val;
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-
-- val = mt7530_mii_read(priv, reg);
-- val &= ~mask;
-- val |= set;
-- mt7530_mii_write(priv, reg, val);
-+ regmap_update_bits(priv->regmap, reg, mask, set);
-
- mutex_unlock(&bus->mdio_lock);
- }
-@@ -299,7 +320,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32
- static void
- mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
- {
-- mt7530_rmw(priv, reg, 0, val);
-+ mt7530_rmw(priv, reg, val, val);
- }
-
- static void
-@@ -3153,22 +3174,6 @@ static const struct phylink_pcs_ops mt75
- .pcs_an_restart = mt7530_pcs_an_restart,
- };
-
--static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
--{
-- struct mt7530_priv *priv = context;
--
-- *val = mt7530_mii_read(priv, reg);
-- return 0;
--};
--
--static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
--{
-- struct mt7530_priv *priv = context;
--
-- mt7530_mii_write(priv, reg, val);
-- return 0;
--};
--
- static void
- mt7530_mdio_regmap_lock(void *mdio_lock)
- {
-@@ -3181,7 +3186,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
- mutex_unlock(mdio_lock);
- }
-
--static const struct regmap_bus mt7531_regmap_bus = {
-+static const struct regmap_bus mt7530_regmap_bus = {
- .reg_write = mt7530_regmap_write,
- .reg_read = mt7530_regmap_read,
- };
-@@ -3214,7 +3219,7 @@ mt7531_create_sgmii(struct mt7530_priv *
- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-
- regmap = devm_regmap_init(priv->dev,
-- &mt7531_regmap_bus, priv,
-+ &mt7530_regmap_bus, priv->bus,
- mt7531_pcs_config[i]);
- if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
-@@ -3380,6 +3385,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
- static int
- mt7530_probe(struct mdio_device *mdiodev)
- {
-+ static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
-
-@@ -3459,6 +3465,21 @@ mt7530_probe(struct mdio_device *mdiodev
- mutex_init(&priv->reg_mutex);
- dev_set_drvdata(&mdiodev->dev, priv);
-
-+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
-+ GFP_KERNEL);
-+ if (!regmap_config)
-+ return -ENOMEM;
-+
-+ regmap_config->reg_bits = 16;
-+ regmap_config->val_bits = 32;
-+ regmap_config->reg_stride = 4;
-+ regmap_config->max_register = MT7530_CREV;
-+ regmap_config->disable_locking = true;
-+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
-+ priv->bus, regmap_config);
-+ if (IS_ERR(priv->regmap))
-+ return PTR_ERR(priv->regmap);
-+
- return dsa_register_switch(priv->ds);
- }
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -785,6 +785,7 @@ struct mt753x_info {
- * @dev: The device pointer
- * @ds: The pointer to the dsa core structure
- * @bus: The bus used for the device and built-in PHY
-+ * @regmap: The regmap instance representing all switch registers
- * @rstc: The pointer to reset control used by MCM
- * @core_pwr: The power supplied into the core
- * @io_pwr: The power supplied into the I/O
-@@ -805,6 +806,7 @@ struct mt7530_priv {
- struct device *dev;
- struct dsa_switch *ds;
- struct mii_bus *bus;
-+ struct regmap *regmap;
- struct reset_control *rstc;
- struct regulator *core_pwr;
- struct regulator *io_pwr;
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch
deleted file mode 100644
index abbecd5e40..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 6de2852297737171ba96b91e89bf302ca1fda869 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:04 +0100
-Subject: [PATCH 08/16] net: dsa: mt7530: move SGMII PCS creation to
- mt7530_probe function
-
-Move creating the SGMII PCS from mt753x_setup() to the more appropriate
-mt7530_probe() function.
-This is done also in preparation of moving all functions related to
-MDIO-connected MT753x switches to a separate module.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 13 +++++++------
- 1 file changed, 7 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3265,12 +3265,6 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-- if (priv->id == ID_MT7531) {
-- ret = mt7531_create_sgmii(priv);
-- if (ret && priv->irq)
-- mt7530_free_irq_common(priv);
-- }
--
- return ret;
- }
-
-@@ -3388,6 +3382,7 @@ mt7530_probe(struct mdio_device *mdiodev
- static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
-+ int ret;
-
- dn = mdiodev->dev.of_node;
-
-@@ -3480,6 +3475,12 @@ mt7530_probe(struct mdio_device *mdiodev
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
-+ if (priv->id == ID_MT7531) {
-+ ret = mt7531_create_sgmii(priv);
-+ if (ret)
-+ return ret;
-+ }
-+
- return dsa_register_switch(priv->ds);
- }
-
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch b/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch
deleted file mode 100644
index ef02d46938..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch
+++ /dev/null
@@ -1,273 +0,0 @@
-From 1557c679f71c82a994eae0baadbaeb62b71e15bf Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:16 +0100
-Subject: [PATCH 09/16] net: dsa: mt7530: introduce mutex helpers
-
-As the MDIO bus lock only needs to be involved if actually operating
-on an MDIO-connected switch we will need to skip locking for built-in
-switches which are accessed via MMIO.
-Create helper functions which simplify that upcoming change.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++--------------------
- 1 file changed, 36 insertions(+), 37 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -144,31 +144,40 @@ err:
- }
-
- static void
--core_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+mt7530_mutex_lock(struct mt7530_priv *priv)
- {
-- struct mii_bus *bus = priv->bus;
-+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+}
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+static void
-+mt7530_mutex_unlock(struct mt7530_priv *priv)
-+{
-+ mutex_unlock(&priv->bus->mdio_lock);
-+}
-+
-+static void
-+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ mt7530_mutex_lock(priv);
-
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static void
- core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
- {
-- struct mii_bus *bus = priv->bus;
- u32 val;
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
- val &= ~mask;
- val |= set;
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static void
-@@ -265,13 +274,11 @@ mt7530_mii_read(struct mt7530_priv *priv
- static void
- mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
- {
-- struct mii_bus *bus = priv->bus;
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- mt7530_mii_write(priv, reg, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static u32
-@@ -283,14 +290,13 @@ _mt7530_unlocked_read(struct mt7530_dumm
- static u32
- _mt7530_read(struct mt7530_dummy_poll *p)
- {
-- struct mii_bus *bus = p->priv->bus;
- u32 val;
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(p->priv);
-
- val = mt7530_mii_read(p->priv, p->reg);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(p->priv);
-
- return val;
- }
-@@ -308,13 +314,11 @@ static void
- mt7530_rmw(struct mt7530_priv *priv, u32 reg,
- u32 mask, u32 set)
- {
-- struct mii_bus *bus = priv->bus;
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- regmap_update_bits(priv->regmap, reg, mask, set);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static void
-@@ -660,14 +664,13 @@ static int
- mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
- int regnum)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- u32 reg, val;
- int ret;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
- !(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -700,7 +703,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
-
- ret = val & MT7531_MDIO_RW_DATA_MASK;
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -709,14 +712,13 @@ static int
- mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
- int regnum, u32 data)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- u32 val, reg;
- int ret;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
- !(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -748,7 +750,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
- }
-
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -756,14 +758,13 @@ out:
- static int
- mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- int ret;
- u32 val;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
- !(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -786,7 +787,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
-
- ret = val & MT7531_MDIO_RW_DATA_MASK;
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -795,14 +796,13 @@ static int
- mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
- u16 data)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- int ret;
- u32 reg;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
- !(reg & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -824,7 +824,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
- }
-
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -1344,7 +1344,6 @@ static int
- mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct mt7530_priv *priv = ds->priv;
-- struct mii_bus *bus = priv->bus;
- int length;
- u32 val;
-
-@@ -1355,7 +1354,7 @@ mt7530_port_change_mtu(struct dsa_switch
- if (!dsa_is_cpu_port(ds, port))
- return 0;
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- val = mt7530_mii_read(priv, MT7530_GMACCR);
- val &= ~MAX_RX_PKT_LEN_MASK;
-@@ -1376,7 +1375,7 @@ mt7530_port_change_mtu(struct dsa_switch
-
- mt7530_mii_write(priv, MT7530_GMACCR, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return 0;
- }
-@@ -2172,10 +2171,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
- u32 val;
- int p;
-
-- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
- val = mt7530_mii_read(priv, MT7530_SYS_INT_STS);
- mt7530_mii_write(priv, MT7530_SYS_INT_STS, val);
-- mutex_unlock(&priv->bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- for (p = 0; p < MT7530_NUM_PHYS; p++) {
- if (BIT(p) & val) {
-@@ -2211,7 +2210,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
- {
- struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-
-- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
- }
-
- static void
-@@ -2220,7 +2219,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da
- struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-
- mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
-- mutex_unlock(&priv->bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static struct irq_chip mt7530_irq_chip = {
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch b/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch
deleted file mode 100644
index 2e1ed2e652..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 25d15dee34a1a40d5fd71636a205e3211f09fd1d Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:28 +0100
-Subject: [PATCH 10/16] net: dsa: mt7530: move p5_intf_modes() function to
- mt7530.c
-
-In preparation of splitting mt7530.c into a driver for MDIO-connected
-as well as MDIO-accessed built-in switches on one hand and MMIO-accessed
-built-in switches move the p5_inft_modes() function from mt7530.h to
-mt7530.c. The function is only needed there and will trigger a compiler
-warning about a defined but unused function otherwise when including
-mt7530.h in the to-be-introduced bus-specific drivers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++
- drivers/net/dsa/mt7530.h | 18 ------------------
- 2 files changed, 18 insertions(+), 18 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -965,6 +965,24 @@ mt7530_set_ageing_time(struct dsa_switch
- return 0;
- }
-
-+static const char *p5_intf_modes(unsigned int p5_interface)
-+{
-+ switch (p5_interface) {
-+ case P5_DISABLED:
-+ return "DISABLED";
-+ case P5_INTF_SEL_PHY_P0:
-+ return "PHY P0";
-+ case P5_INTF_SEL_PHY_P4:
-+ return "PHY P4";
-+ case P5_INTF_SEL_GMAC5:
-+ return "GMAC5";
-+ case P5_INTF_SEL_GMAC5_SGMII:
-+ return "GMAC5_SGMII";
-+ default:
-+ return "unknown";
-+ }
-+}
-+
- static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
- {
- struct mt7530_priv *priv = ds->priv;
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -720,24 +720,6 @@ enum p5_interface_select {
- P5_INTF_SEL_GMAC5_SGMII,
- };
-
--static const char *p5_intf_modes(unsigned int p5_interface)
--{
-- switch (p5_interface) {
-- case P5_DISABLED:
-- return "DISABLED";
-- case P5_INTF_SEL_PHY_P0:
-- return "PHY P0";
-- case P5_INTF_SEL_PHY_P4:
-- return "PHY P4";
-- case P5_INTF_SEL_GMAC5:
-- return "GMAC5";
-- case P5_INTF_SEL_GMAC5_SGMII:
-- return "GMAC5_SGMII";
-- default:
-- return "unknown";
-- }
--}
--
- struct mt7530_priv;
-
- struct mt753x_pcs {
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch
deleted file mode 100644
index c9ff26ff20..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 37c9c0d8d0b2e24f8c9af72ecd4edd31537284d3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:39 +0100
-Subject: [PATCH 11/16] net: dsa: mt7530: introduce mt7530_probe_common helper
- function
-
-Move commonly used parts from mt7530_probe into new mt7530_probe_common
-helper function which will be used by both, mt7530_probe and the
-to-be-introduced mt7988_probe.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------
- 1 file changed, 54 insertions(+), 44 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3394,44 +3394,21 @@ static const struct of_device_id mt7530_
- MODULE_DEVICE_TABLE(of, mt7530_of_match);
-
- static int
--mt7530_probe(struct mdio_device *mdiodev)
-+mt7530_probe_common(struct mt7530_priv *priv)
- {
-- static struct regmap_config *regmap_config;
-- struct mt7530_priv *priv;
-- struct device_node *dn;
-- int ret;
-+ struct device *dev = priv->dev;
-
-- dn = mdiodev->dev.of_node;
--
-- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
- if (!priv->ds)
- return -ENOMEM;
-
-- priv->ds->dev = &mdiodev->dev;
-+ priv->ds->dev = dev;
- priv->ds->num_ports = MT7530_NUM_PORTS;
-
-- /* Use medatek,mcm property to distinguish hardware type that would
-- * casues a little bit differences on power-on sequence.
-- */
-- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-- if (priv->mcm) {
-- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
--
-- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-- if (IS_ERR(priv->rstc)) {
-- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-- return PTR_ERR(priv->rstc);
-- }
-- }
--
- /* Get the hardware identifier from the devicetree node.
- * We will need it for some of the clock and regulator setup.
- */
-- priv->info = of_device_get_match_data(&mdiodev->dev);
-+ priv->info = of_device_get_match_data(dev);
- if (!priv->info)
- return -EINVAL;
-
-@@ -3445,23 +3422,53 @@ mt7530_probe(struct mdio_device *mdiodev
- return -EINVAL;
-
- priv->id = priv->info->id;
-+ priv->dev = dev;
-+ priv->ds->priv = priv;
-+ priv->ds->ops = &mt7530_switch_ops;
-+ mutex_init(&priv->reg_mutex);
-+ dev_set_drvdata(dev, priv);
-
-- if (priv->id == ID_MT7530) {
-- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-- if (IS_ERR(priv->core_pwr))
-- return PTR_ERR(priv->core_pwr);
-+ return 0;
-+}
-
-- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-- if (IS_ERR(priv->io_pwr))
-- return PTR_ERR(priv->io_pwr);
-- }
-+static int
-+mt7530_probe(struct mdio_device *mdiodev)
-+{
-+ static struct regmap_config *regmap_config;
-+ struct mt7530_priv *priv;
-+ struct device_node *dn;
-+ int ret;
-+
-+ dn = mdiodev->dev.of_node;
-+
-+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-
-- /* Not MCM that indicates switch works as the remote standalone
-+ priv->bus = mdiodev->bus;
-+ priv->dev = &mdiodev->dev;
-+
-+ ret = mt7530_probe_common(priv);
-+ if (ret)
-+ return ret;
-+
-+ /* Use medatek,mcm property to distinguish hardware type that would
-+ * cause a little bit differences on power-on sequence.
-+ * Not MCM that indicates switch works as the remote standalone
- * integrated circuit so the GPIO pin would be used to complete
- * the reset, otherwise memory-mapped register accessing used
- * through syscon provides in the case of MCM.
- */
-- if (!priv->mcm) {
-+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-+ if (priv->mcm) {
-+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-+
-+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-+ if (IS_ERR(priv->rstc)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->rstc);
-+ }
-+ } else {
- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
- GPIOD_OUT_LOW);
- if (IS_ERR(priv->reset)) {
-@@ -3470,12 +3477,15 @@ mt7530_probe(struct mdio_device *mdiodev
- }
- }
-
-- priv->bus = mdiodev->bus;
-- priv->dev = &mdiodev->dev;
-- priv->ds->priv = priv;
-- priv->ds->ops = &mt7530_switch_ops;
-- mutex_init(&priv->reg_mutex);
-- dev_set_drvdata(&mdiodev->dev, priv);
-+ if (priv->id == ID_MT7530) {
-+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-+ if (IS_ERR(priv->core_pwr))
-+ return PTR_ERR(priv->core_pwr);
-+
-+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-+ if (IS_ERR(priv->io_pwr))
-+ return PTR_ERR(priv->io_pwr);
-+ }
-
- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
- GFP_KERNEL);
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch
deleted file mode 100644
index 7c1c80e7bc..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 720d736351761574af02ed093658ab60de60576c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:50 +0100
-Subject: [PATCH 12/16] net: dsa: mt7530: introduce mt7530_remove_common helper
- function
-
-Move commonly used parts from mt7530_remove into new
-mt7530_remove_common helper function which will be used by both,
-mt7530_remove and the to-be-introduced mt7988_remove.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 18 ++++++++++++------
- 1 file changed, 12 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3512,6 +3512,17 @@ mt7530_probe(struct mdio_device *mdiodev
- }
-
- static void
-+mt7530_remove_common(struct mt7530_priv *priv)
-+{
-+ if (priv->irq)
-+ mt7530_free_irq(priv);
-+
-+ dsa_unregister_switch(priv->ds);
-+
-+ mutex_destroy(&priv->reg_mutex);
-+}
-+
-+static void
- mt7530_remove(struct mdio_device *mdiodev)
- {
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-@@ -3530,16 +3541,11 @@ mt7530_remove(struct mdio_device *mdiode
- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
- ret);
-
-- if (priv->irq)
-- mt7530_free_irq(priv);
--
-- dsa_unregister_switch(priv->ds);
-+ mt7530_remove_common(priv);
-
- for (i = 0; i < 2; ++i)
- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-
-- mutex_destroy(&priv->reg_mutex);
--
- dev_set_drvdata(&mdiodev->dev, NULL);
- }
-
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch
deleted file mode 100644
index 84883147ac..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch
+++ /dev/null
@@ -1,692 +0,0 @@
-From cb675afcddbbeb2bfa6596e3bc236bc026cd425f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:19:13 +0100
-Subject: [PATCH 14/16] net: dsa: mt7530: introduce separate MDIO driver
-
-Split MT7530 switch driver into a common part and a part specific
-for MDIO connected switches and multi-chip modules.
-Move MDIO-specific functions to newly introduced mt7530-mdio.c while
-keeping the common parts in mt7530.c.
-Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is
-implied by CONFIG_NET_DSA_MT7530.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS | 1 +
- drivers/net/dsa/Kconfig | 15 +-
- drivers/net/dsa/Makefile | 1 +
- drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.c | 264 +--------------------------------
- drivers/net/dsa/mt7530.h | 6 +
- 6 files changed, 300 insertions(+), 258 deletions(-)
- create mode 100644 drivers/net/dsa/mt7530-mdio.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -11902,6 +11902,7 @@ M: Landen Chao <Landen.Chao@mediatek.com
- M: DENG Qingfang <dqfext@gmail.com>
- L: netdev@vger.kernel.org
- S: Maintained
-+F: drivers/net/dsa/mt7530-mdio.c
- F: drivers/net/dsa/mt7530.*
- F: net/dsa/tag_mtk.c
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -37,10 +37,22 @@ config NET_DSA_MT7530
- tristate "MediaTek MT753x and MT7621 Ethernet switch support"
- select NET_DSA_TAG_MTK
- select MEDIATEK_GE_PHY
-+ imply NET_DSA_MT7530_MDIO
-+ help
-+ This enables support for the MediaTek MT7530 and MT7531 Ethernet
-+ switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
-+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are
-+ supported as well.
-+
-+config NET_DSA_MT7530_MDIO
-+ tristate "MediaTek MT7530 MDIO interface driver"
-+ depends on NET_DSA_MT7530
- select PCS_MTK_LYNXI
- help
-- This enables support for the MediaTek MT7530, MT7531, and MT7621
-- Ethernet switch chips.
-+ This enables support for the MediaTek MT7530 and MT7531 switch
-+ chips which are connected via MDIO, as well as multi-chip
-+ module MT7530 which can be found in the MT7621AT, MT7621DAT,
-+ MT7621ST and MT7623AI SoCs.
-
- config NET_DSA_MV88E6060
- tristate "Marvell 88E6060 ethernet switch chip support"
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi
- endif
- obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
- obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
-+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
- obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
- obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
- realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
---- /dev/null
-+++ b/drivers/net/dsa/mt7530-mdio.c
-@@ -0,0 +1,271 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+
-+#include <linux/gpio/consumer.h>
-+#include <linux/mdio.h>
-+#include <linux/module.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_mdio.h>
-+#include <linux/of_net.h>
-+#include <linux/of_platform.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/regulator/consumer.h>
-+#include <net/dsa.h>
-+
-+#include "mt7530.h"
-+
-+static int
-+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-+{
-+ struct mii_bus *bus = context;
-+ u16 page, r, lo, hi;
-+ int ret;
-+
-+ page = (reg >> 6) & 0x3ff;
-+ r = (reg >> 2) & 0xf;
-+ lo = val & 0xffff;
-+ hi = val >> 16;
-+
-+ /* MT7530 uses 31 as the pseudo port */
-+ ret = bus->write(bus, 0x1f, 0x1f, page);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = bus->write(bus, 0x1f, r, lo);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = bus->write(bus, 0x1f, 0x10, hi);
-+ return ret;
-+}
-+
-+static int
-+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-+{
-+ struct mii_bus *bus = context;
-+ u16 page, r, lo, hi;
-+ int ret;
-+
-+ page = (reg >> 6) & 0x3ff;
-+ r = (reg >> 2) & 0xf;
-+
-+ /* MT7530 uses 31 as the pseudo port */
-+ ret = bus->write(bus, 0x1f, 0x1f, page);
-+ if (ret < 0)
-+ return ret;
-+
-+ lo = bus->read(bus, 0x1f, r);
-+ hi = bus->read(bus, 0x1f, 0x10);
-+
-+ *val = (hi << 16) | (lo & 0xffff);
-+
-+ return 0;
-+}
-+
-+static void
-+mt7530_mdio_regmap_lock(void *mdio_lock)
-+{
-+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
-+}
-+
-+static void
-+mt7530_mdio_regmap_unlock(void *mdio_lock)
-+{
-+ mutex_unlock(mdio_lock);
-+}
-+
-+static const struct regmap_bus mt7530_regmap_bus = {
-+ .reg_write = mt7530_regmap_write,
-+ .reg_read = mt7530_regmap_read,
-+};
-+
-+static int
-+mt7531_create_sgmii(struct mt7530_priv *priv)
-+{
-+ struct regmap_config *mt7531_pcs_config[2];
-+ struct phylink_pcs *pcs;
-+ struct regmap *regmap;
-+ int i, ret = 0;
-+
-+ for (i = 0; i < 2; i++) {
-+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
-+ sizeof(struct regmap_config),
-+ GFP_KERNEL);
-+ if (!mt7531_pcs_config[i]) {
-+ ret = -ENOMEM;
-+ break;
-+ }
-+
-+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
-+ mt7531_pcs_config[i]->reg_bits = 16;
-+ mt7531_pcs_config[i]->val_bits = 32;
-+ mt7531_pcs_config[i]->reg_stride = 4;
-+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
-+ mt7531_pcs_config[i]->max_register = 0x17c;
-+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
-+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
-+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-+
-+ regmap = devm_regmap_init(priv->dev,
-+ &mt7530_regmap_bus, priv->bus,
-+ mt7531_pcs_config[i]);
-+ if (IS_ERR(regmap)) {
-+ ret = PTR_ERR(regmap);
-+ break;
-+ }
-+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
-+ MT7531_PHYA_CTRL_SIGNAL3, 0);
-+ if (!pcs) {
-+ ret = -ENXIO;
-+ break;
-+ }
-+ priv->ports[5 + i].sgmii_pcs = pcs;
-+ }
-+
-+ if (ret && i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
-+
-+ return ret;
-+}
-+
-+static const struct of_device_id mt7530_of_match[] = {
-+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
-+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
-+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, mt7530_of_match);
-+
-+static int
-+mt7530_probe(struct mdio_device *mdiodev)
-+{
-+ static struct regmap_config *regmap_config;
-+ struct mt7530_priv *priv;
-+ struct device_node *dn;
-+ int ret;
-+
-+ dn = mdiodev->dev.of_node;
-+
-+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->bus = mdiodev->bus;
-+ priv->dev = &mdiodev->dev;
-+
-+ ret = mt7530_probe_common(priv);
-+ if (ret)
-+ return ret;
-+
-+ /* Use medatek,mcm property to distinguish hardware type that would
-+ * cause a little bit differences on power-on sequence.
-+ * Not MCM that indicates switch works as the remote standalone
-+ * integrated circuit so the GPIO pin would be used to complete
-+ * the reset, otherwise memory-mapped register accessing used
-+ * through syscon provides in the case of MCM.
-+ */
-+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-+ if (priv->mcm) {
-+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-+
-+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-+ if (IS_ERR(priv->rstc)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->rstc);
-+ }
-+ } else {
-+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
-+ GPIOD_OUT_LOW);
-+ if (IS_ERR(priv->reset)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->reset);
-+ }
-+ }
-+
-+ if (priv->id == ID_MT7530) {
-+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-+ if (IS_ERR(priv->core_pwr))
-+ return PTR_ERR(priv->core_pwr);
-+
-+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-+ if (IS_ERR(priv->io_pwr))
-+ return PTR_ERR(priv->io_pwr);
-+ }
-+
-+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
-+ GFP_KERNEL);
-+ if (!regmap_config)
-+ return -ENOMEM;
-+
-+ regmap_config->reg_bits = 16;
-+ regmap_config->val_bits = 32;
-+ regmap_config->reg_stride = 4;
-+ regmap_config->max_register = MT7530_CREV;
-+ regmap_config->disable_locking = true;
-+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
-+ priv->bus, regmap_config);
-+ if (IS_ERR(priv->regmap))
-+ return PTR_ERR(priv->regmap);
-+
-+ if (priv->id == ID_MT7531) {
-+ ret = mt7531_create_sgmii(priv);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return dsa_register_switch(priv->ds);
-+}
-+
-+static void
-+mt7530_remove(struct mdio_device *mdiodev)
-+{
-+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+ int ret = 0, i;
-+
-+ if (!priv)
-+ return;
-+
-+ ret = regulator_disable(priv->core_pwr);
-+ if (ret < 0)
-+ dev_err(priv->dev,
-+ "Failed to disable core power: %d\n", ret);
-+
-+ ret = regulator_disable(priv->io_pwr);
-+ if (ret < 0)
-+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
-+ ret);
-+
-+ mt7530_remove_common(priv);
-+
-+ for (i = 0; i < 2; ++i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-+}
-+
-+static void mt7530_shutdown(struct mdio_device *mdiodev)
-+{
-+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+
-+ if (!priv)
-+ return;
-+
-+ dsa_switch_shutdown(priv->ds);
-+
-+ dev_set_drvdata(&mdiodev->dev, NULL);
-+}
-+
-+static struct mdio_driver mt7530_mdio_driver = {
-+ .probe = mt7530_probe,
-+ .remove = mt7530_remove,
-+ .shutdown = mt7530_shutdown,
-+ .mdiodrv.driver = {
-+ .name = "mt7530-mdio",
-+ .of_match_table = mt7530_of_match,
-+ },
-+};
-+
-+mdio_module_driver(mt7530_mdio_driver);
-+
-+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
-+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -14,7 +14,6 @@
- #include <linux/of_mdio.h>
- #include <linux/of_net.h>
- #include <linux/of_platform.h>
--#include <linux/pcs/pcs-mtk-lynxi.h>
- #include <linux/phylink.h>
- #include <linux/regmap.h>
- #include <linux/regulator/consumer.h>
-@@ -193,31 +192,6 @@ core_clear(struct mt7530_priv *priv, u32
- }
-
- static int
--mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
--{
-- struct mii_bus *bus = context;
-- u16 page, r, lo, hi;
-- int ret;
--
-- page = (reg >> 6) & 0x3ff;
-- r = (reg >> 2) & 0xf;
-- lo = val & 0xffff;
-- hi = val >> 16;
--
-- /* MT7530 uses 31 as the pseudo port */
-- ret = bus->write(bus, 0x1f, 0x1f, page);
-- if (ret < 0)
-- return ret;
--
-- ret = bus->write(bus, 0x1f, r, lo);
-- if (ret < 0)
-- return ret;
--
-- ret = bus->write(bus, 0x1f, 0x10, hi);
-- return ret;
--}
--
--static int
- mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
- {
- int ret;
-@@ -231,29 +205,6 @@ mt7530_mii_write(struct mt7530_priv *pri
- return ret;
- }
-
--static int
--mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
--{
-- struct mii_bus *bus = context;
-- u16 page, r, lo, hi;
-- int ret;
--
-- page = (reg >> 6) & 0x3ff;
-- r = (reg >> 2) & 0xf;
--
-- /* MT7530 uses 31 as the pseudo port */
-- ret = bus->write(bus, 0x1f, 0x1f, page);
-- if (ret < 0)
-- return ret;
--
-- lo = bus->read(bus, 0x1f, r);
-- hi = bus->read(bus, 0x1f, 0x10);
--
-- *val = (hi << 16) | (lo & 0xffff);
--
-- return 0;
--}
--
- static u32
- mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
- {
-@@ -3191,72 +3142,6 @@ static const struct phylink_pcs_ops mt75
- .pcs_an_restart = mt7530_pcs_an_restart,
- };
-
--static void
--mt7530_mdio_regmap_lock(void *mdio_lock)
--{
-- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
--}
--
--static void
--mt7530_mdio_regmap_unlock(void *mdio_lock)
--{
-- mutex_unlock(mdio_lock);
--}
--
--static const struct regmap_bus mt7530_regmap_bus = {
-- .reg_write = mt7530_regmap_write,
-- .reg_read = mt7530_regmap_read,
--};
--
--static int
--mt7531_create_sgmii(struct mt7530_priv *priv)
--{
-- struct regmap_config *mt7531_pcs_config[2];
-- struct phylink_pcs *pcs;
-- struct regmap *regmap;
-- int i, ret = 0;
--
-- for (i = 0; i < 2; i++) {
-- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
-- sizeof(struct regmap_config),
-- GFP_KERNEL);
-- if (!mt7531_pcs_config[i]) {
-- ret = -ENOMEM;
-- break;
-- }
--
-- mt7531_pcs_config[i]->name = i ? "port6" : "port5";
-- mt7531_pcs_config[i]->reg_bits = 16;
-- mt7531_pcs_config[i]->val_bits = 32;
-- mt7531_pcs_config[i]->reg_stride = 4;
-- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
-- mt7531_pcs_config[i]->max_register = 0x17c;
-- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
-- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
-- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
--
-- regmap = devm_regmap_init(priv->dev,
-- &mt7530_regmap_bus, priv->bus,
-- mt7531_pcs_config[i]);
-- if (IS_ERR(regmap)) {
-- ret = PTR_ERR(regmap);
-- break;
-- }
-- pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
-- MT7531_PHYA_CTRL_SIGNAL3, 0);
-- if (!pcs) {
-- ret = -ENXIO;
-- break;
-- }
-- priv->ports[5 + i].sgmii_pcs = pcs;
-- }
--
-- if (ret && i)
-- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
--
-- return ret;
--}
--
- static int
- mt753x_setup(struct dsa_switch *ds)
- {
-@@ -3315,7 +3200,7 @@ static int mt753x_set_mac_eee(struct dsa
- return 0;
- }
-
--static const struct dsa_switch_ops mt7530_switch_ops = {
-+const struct dsa_switch_ops mt7530_switch_ops = {
- .get_tag_protocol = mtk_get_tag_protocol,
- .setup = mt753x_setup,
- .preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
-@@ -3350,8 +3235,9 @@ static const struct dsa_switch_ops mt753
- .get_mac_eee = mt753x_get_mac_eee,
- .set_mac_eee = mt753x_set_mac_eee,
- };
-+EXPORT_SYMBOL_GPL(mt7530_switch_ops);
-
--static const struct mt753x_info mt753x_table[] = {
-+const struct mt753x_info mt753x_table[] = {
- [ID_MT7621] = {
- .id = ID_MT7621,
- .pcs_ops = &mt7530_pcs_ops,
-@@ -3384,16 +3270,9 @@ static const struct mt753x_info mt753x_t
- .mac_port_config = mt7531_mac_config,
- },
- };
-+EXPORT_SYMBOL_GPL(mt753x_table);
-
--static const struct of_device_id mt7530_of_match[] = {
-- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
-- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
-- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
-- { /* sentinel */ },
--};
--MODULE_DEVICE_TABLE(of, mt7530_of_match);
--
--static int
-+int
- mt7530_probe_common(struct mt7530_priv *priv)
- {
- struct device *dev = priv->dev;
-@@ -3430,88 +3309,9 @@ mt7530_probe_common(struct mt7530_priv *
-
- return 0;
- }
-+EXPORT_SYMBOL_GPL(mt7530_probe_common);
-
--static int
--mt7530_probe(struct mdio_device *mdiodev)
--{
-- static struct regmap_config *regmap_config;
-- struct mt7530_priv *priv;
-- struct device_node *dn;
-- int ret;
--
-- dn = mdiodev->dev.of_node;
--
-- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- priv->bus = mdiodev->bus;
-- priv->dev = &mdiodev->dev;
--
-- ret = mt7530_probe_common(priv);
-- if (ret)
-- return ret;
--
-- /* Use medatek,mcm property to distinguish hardware type that would
-- * cause a little bit differences on power-on sequence.
-- * Not MCM that indicates switch works as the remote standalone
-- * integrated circuit so the GPIO pin would be used to complete
-- * the reset, otherwise memory-mapped register accessing used
-- * through syscon provides in the case of MCM.
-- */
-- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-- if (priv->mcm) {
-- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
--
-- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-- if (IS_ERR(priv->rstc)) {
-- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-- return PTR_ERR(priv->rstc);
-- }
-- } else {
-- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
-- GPIOD_OUT_LOW);
-- if (IS_ERR(priv->reset)) {
-- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-- return PTR_ERR(priv->reset);
-- }
-- }
--
-- if (priv->id == ID_MT7530) {
-- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-- if (IS_ERR(priv->core_pwr))
-- return PTR_ERR(priv->core_pwr);
--
-- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-- if (IS_ERR(priv->io_pwr))
-- return PTR_ERR(priv->io_pwr);
-- }
--
-- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
-- GFP_KERNEL);
-- if (!regmap_config)
-- return -ENOMEM;
--
-- regmap_config->reg_bits = 16;
-- regmap_config->val_bits = 32;
-- regmap_config->reg_stride = 4;
-- regmap_config->max_register = MT7530_CREV;
-- regmap_config->disable_locking = true;
-- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
-- priv->bus, regmap_config);
-- if (IS_ERR(priv->regmap))
-- return PTR_ERR(priv->regmap);
--
-- if (priv->id == ID_MT7531) {
-- ret = mt7531_create_sgmii(priv);
-- if (ret)
-- return ret;
-- }
--
-- return dsa_register_switch(priv->ds);
--}
--
--static void
-+void
- mt7530_remove_common(struct mt7530_priv *priv)
- {
- if (priv->irq)
-@@ -3522,57 +3322,6 @@ mt7530_remove_common(struct mt7530_priv
- mutex_destroy(&priv->reg_mutex);
- }
-
--static void
--mt7530_remove(struct mdio_device *mdiodev)
--{
-- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-- int ret = 0, i;
--
-- if (!priv)
-- return;
--
-- ret = regulator_disable(priv->core_pwr);
-- if (ret < 0)
-- dev_err(priv->dev,
-- "Failed to disable core power: %d\n", ret);
--
-- ret = regulator_disable(priv->io_pwr);
-- if (ret < 0)
-- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
-- ret);
--
-- mt7530_remove_common(priv);
--
-- for (i = 0; i < 2; ++i)
-- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
--
-- dev_set_drvdata(&mdiodev->dev, NULL);
--}
--
--static void mt7530_shutdown(struct mdio_device *mdiodev)
--{
-- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
--
-- if (!priv)
-- return;
--
-- dsa_switch_shutdown(priv->ds);
--
-- dev_set_drvdata(&mdiodev->dev, NULL);
--}
--
--static struct mdio_driver mt7530_mdio_driver = {
-- .probe = mt7530_probe,
-- .remove = mt7530_remove,
-- .shutdown = mt7530_shutdown,
-- .mdiodrv.driver = {
-- .name = "mt7530",
-- .of_match_table = mt7530_of_match,
-- },
--};
--
--mdio_module_driver(mt7530_mdio_driver);
--
- MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
- MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
- MODULE_LICENSE("GPL");
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL
- p->reg = reg;
- }
-
-+int mt7530_probe_common(struct mt7530_priv *priv);
-+void mt7530_remove_common(struct mt7530_priv *priv);
-+
-+extern const struct dsa_switch_ops mt7530_switch_ops;
-+extern const struct mt753x_info mt753x_table[];
-+
- #endif /* __MT7530_H */
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch b/target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch
deleted file mode 100644
index 59e193f9f6..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 54d4147a121cec5004a673a58572da346e4458f8 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:19:28 +0100
-Subject: [PATCH 15/16] net: dsa: mt7530: skip locking if MDIO bus isn't
- present
-
-As MT7530 and MT7531 internally use 32-bit wide registers, each access
-to any register of the switch requires several operations on the MDIO
-bus. Hence if there is congruent access, e.g. due to PCS or PHY
-polling, this can mess up and interfere with another ongoing register
-access sequence.
-
-However, the MDIO bus mutex is only relevant for MDIO-connected
-switches. Prepare switches which have there registers directly mapped
-into the SoCs register space via MMIO which do not require such
-locking. There we can simply use regmap's default locking mechanism.
-
-Hence guard mutex operations to only be performed in case of MDIO
-connected switches.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -145,13 +145,15 @@ err:
- static void
- mt7530_mutex_lock(struct mt7530_priv *priv)
- {
-- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ if (priv->bus)
-+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
- }
-
- static void
- mt7530_mutex_unlock(struct mt7530_priv *priv)
- {
-- mutex_unlock(&priv->bus->mdio_lock);
-+ if (priv->bus)
-+ mutex_unlock(&priv->bus->mdio_lock);
- }
-
- static void
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch
deleted file mode 100644
index c8417091f9..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch
+++ /dev/null
@@ -1,421 +0,0 @@
-From 110c18bfed41421edd677935dd33be5e6507ba92 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:19:40 +0100
-Subject: [PATCH 16/16] net: dsa: mt7530: introduce driver for MT7988 built-in
- switch
-
-Add driver for the built-in Gigabit Ethernet switch which can be found
-in the MediaTek MT7988 SoC.
-
-The switch shares most of its design with MT7530 and MT7531, but has
-it's registers mapped into the SoCs register space rather than being
-connected externally or internally via MDIO.
-
-Introduce a new platform driver to support that.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS | 2 +
- drivers/net/dsa/Kconfig | 12 +++
- drivers/net/dsa/Makefile | 1 +
- drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
- drivers/net/dsa/mt7530.c | 137 +++++++++++++++++++++++++++++++++-
- drivers/net/dsa/mt7530.h | 12 +--
- 6 files changed, 255 insertions(+), 10 deletions(-)
- create mode 100644 drivers/net/dsa/mt7530-mmio.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -11900,9 +11900,11 @@ MEDIATEK SWITCH DRIVER
- M: Sean Wang <sean.wang@mediatek.com>
- M: Landen Chao <Landen.Chao@mediatek.com>
- M: DENG Qingfang <dqfext@gmail.com>
-+M: Daniel Golle <daniel@makrotopia.org>
- L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/dsa/mt7530-mdio.c
-+F: drivers/net/dsa/mt7530-mmio.c
- F: drivers/net/dsa/mt7530.*
- F: net/dsa/tag_mtk.c
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -38,6 +38,7 @@ config NET_DSA_MT7530
- select NET_DSA_TAG_MTK
- select MEDIATEK_GE_PHY
- imply NET_DSA_MT7530_MDIO
-+ imply NET_DSA_MT7530_MMIO
- help
- This enables support for the MediaTek MT7530 and MT7531 Ethernet
- switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
-@@ -54,6 +55,17 @@ config NET_DSA_MT7530_MDIO
- module MT7530 which can be found in the MT7621AT, MT7621DAT,
- MT7621ST and MT7623AI SoCs.
-
-+config NET_DSA_MT7530_MMIO
-+ tristate "MediaTek MT7530 MMIO interface driver"
-+ depends on NET_DSA_MT7530
-+ depends on HAS_IOMEM
-+ help
-+ This enables support for the built-in Ethernet switch found
-+ in the MediaTek MT7988 SoC.
-+ The switch is a similar design as MT7531, but the switch registers
-+ are directly mapped into the SoCs register space rather than being
-+ accessible via MDIO.
-+
- config NET_DSA_MV88E6060
- tristate "Marvell 88E6060 ethernet switch chip support"
- select NET_DSA_TAG_TRAILER
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -8,6 +8,7 @@ endif
- obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
- obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
- obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
-+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o
- obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
- obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
- realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
---- /dev/null
-+++ b/drivers/net/dsa/mt7530-mmio.c
-@@ -0,0 +1,101 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/regmap.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/reset.h>
-+#include <net/dsa.h>
-+
-+#include "mt7530.h"
-+
-+static const struct of_device_id mt7988_of_match[] = {
-+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, mt7988_of_match);
-+
-+static int
-+mt7988_probe(struct platform_device *pdev)
-+{
-+ static struct regmap_config *sw_regmap_config;
-+ struct mt7530_priv *priv;
-+ void __iomem *base_addr;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->bus = NULL;
-+ priv->dev = &pdev->dev;
-+
-+ ret = mt7530_probe_common(priv);
-+ if (ret)
-+ return ret;
-+
-+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->rstc)) {
-+ dev_err(&pdev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->rstc);
-+ }
-+
-+ base_addr = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(base_addr)) {
-+ dev_err(&pdev->dev, "cannot request I/O memory space\n");
-+ return -ENXIO;
-+ }
-+
-+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL);
-+ if (!sw_regmap_config)
-+ return -ENOMEM;
-+
-+ sw_regmap_config->name = "switch";
-+ sw_regmap_config->reg_bits = 16;
-+ sw_regmap_config->val_bits = 32;
-+ sw_regmap_config->reg_stride = 4;
-+ sw_regmap_config->max_register = MT7530_CREV;
-+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config);
-+ if (IS_ERR(priv->regmap))
-+ return PTR_ERR(priv->regmap);
-+
-+ return dsa_register_switch(priv->ds);
-+}
-+
-+static int
-+mt7988_remove(struct platform_device *pdev)
-+{
-+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
-+
-+ if (priv)
-+ mt7530_remove_common(priv);
-+
-+ return 0;
-+}
-+
-+static void mt7988_shutdown(struct platform_device *pdev)
-+{
-+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
-+
-+ if (!priv)
-+ return;
-+
-+ dsa_switch_shutdown(priv->ds);
-+
-+ dev_set_drvdata(&pdev->dev, NULL);
-+}
-+
-+static struct platform_driver mt7988_platform_driver = {
-+ .probe = mt7988_probe,
-+ .remove = mt7988_remove,
-+ .shutdown = mt7988_shutdown,
-+ .driver = {
-+ .name = "mt7530-mmio",
-+ .of_match_table = mt7988_of_match,
-+ },
-+};
-+module_platform_driver(mt7988_platform_driver);
-+
-+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
-+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2219,6 +2219,47 @@ static const struct irq_domain_ops mt753
- };
-
- static void
-+mt7988_irq_mask(struct irq_data *d)
-+{
-+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-+
-+ priv->irq_enable &= ~BIT(d->hwirq);
-+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
-+}
-+
-+static void
-+mt7988_irq_unmask(struct irq_data *d)
-+{
-+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-+
-+ priv->irq_enable |= BIT(d->hwirq);
-+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
-+}
-+
-+static struct irq_chip mt7988_irq_chip = {
-+ .name = KBUILD_MODNAME,
-+ .irq_mask = mt7988_irq_mask,
-+ .irq_unmask = mt7988_irq_unmask,
-+};
-+
-+static int
-+mt7988_irq_map(struct irq_domain *domain, unsigned int irq,
-+ irq_hw_number_t hwirq)
-+{
-+ irq_set_chip_data(irq, domain->host_data);
-+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq);
-+ irq_set_nested_thread(irq, true);
-+ irq_set_noprobe(irq);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops mt7988_irq_domain_ops = {
-+ .map = mt7988_irq_map,
-+ .xlate = irq_domain_xlate_onecell,
-+};
-+
-+static void
- mt7530_setup_mdio_irq(struct mt7530_priv *priv)
- {
- struct dsa_switch *ds = priv->ds;
-@@ -2252,8 +2293,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
- return priv->irq ? : -EINVAL;
- }
-
-- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
-- &mt7530_irq_domain_ops, priv);
-+ if (priv->id == ID_MT7988)
-+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
-+ &mt7988_irq_domain_ops,
-+ priv);
-+ else
-+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
-+ &mt7530_irq_domain_ops,
-+ priv);
-+
- if (!priv->irq_domain) {
- dev_err(dev, "failed to create IRQ domain\n");
- return -ENOMEM;
-@@ -2754,6 +2802,25 @@ static void mt7531_mac_port_get_caps(str
- }
- }
-
-+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
-+ struct phylink_config *config)
-+{
-+ phy_interface_zero(config->supported_interfaces);
-+
-+ switch (port) {
-+ case 0 ... 4: /* Internal phy */
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ config->supported_interfaces);
-+ break;
-+
-+ case 6:
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ config->supported_interfaces);
-+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-+ MAC_10000FD;
-+ }
-+}
-+
- static int
- mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
- {
-@@ -2830,6 +2897,17 @@ static bool mt753x_is_mac_port(u32 port)
- }
-
- static int
-+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ if (dsa_is_cpu_port(ds, port) &&
-+ interface == PHY_INTERFACE_MODE_INTERNAL)
-+ return 0;
-+
-+ return -EINVAL;
-+}
-+
-+static int
- mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -2899,7 +2977,8 @@ mt753x_phylink_mac_config(struct dsa_swi
-
- switch (port) {
- case 0 ... 4: /* Internal phy */
-- if (state->interface != PHY_INTERFACE_MODE_GMII)
-+ if (state->interface != PHY_INTERFACE_MODE_GMII &&
-+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
- goto unsupported;
- break;
- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-@@ -2977,7 +3056,8 @@ static void mt753x_phylink_mac_link_up(s
- /* MT753x MAC works in 1G full duplex mode for all up-clocked
- * variants.
- */
-- if (interface == PHY_INTERFACE_MODE_TRGMII ||
-+ if (interface == PHY_INTERFACE_MODE_INTERNAL ||
-+ interface == PHY_INTERFACE_MODE_TRGMII ||
- (phy_interface_mode_is_8023z(interface))) {
- speed = SPEED_1000;
- duplex = DUPLEX_FULL;
-@@ -3057,6 +3137,21 @@ mt7531_cpu_port_config(struct dsa_switch
- return 0;
- }
-
-+static int
-+mt7988_cpu_port_config(struct dsa_switch *ds, int port)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ mt7530_write(priv, MT7530_PMCR_P(port),
-+ PMCR_CPU_PORT_SETTING(priv->id));
-+
-+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
-+ PHY_INTERFACE_MODE_INTERNAL, NULL,
-+ SPEED_10000, DUPLEX_FULL, true, true);
-+
-+ return 0;
-+}
-+
- static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
- {
-@@ -3202,6 +3297,27 @@ static int mt753x_set_mac_eee(struct dsa
- return 0;
- }
-
-+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-+{
-+ return 0;
-+}
-+
-+static int mt7988_setup(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ /* Reset the switch */
-+ reset_control_assert(priv->rstc);
-+ usleep_range(20, 50);
-+ reset_control_deassert(priv->rstc);
-+ usleep_range(20, 50);
-+
-+ /* Reset the switch PHYs */
-+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
-+
-+ return mt7531_setup_common(ds);
-+}
-+
- const struct dsa_switch_ops mt7530_switch_ops = {
- .get_tag_protocol = mtk_get_tag_protocol,
- .setup = mt753x_setup,
-@@ -3271,6 +3387,17 @@ const struct mt753x_info mt753x_table[]
- .mac_port_get_caps = mt7531_mac_port_get_caps,
- .mac_port_config = mt7531_mac_config,
- },
-+ [ID_MT7988] = {
-+ .id = ID_MT7988,
-+ .pcs_ops = &mt7530_pcs_ops,
-+ .sw_setup = mt7988_setup,
-+ .phy_read = mt7531_ind_phy_read,
-+ .phy_write = mt7531_ind_phy_write,
-+ .pad_setup = mt7988_pad_setup,
-+ .cpu_port_config = mt7988_cpu_port_config,
-+ .mac_port_get_caps = mt7988_mac_port_get_caps,
-+ .mac_port_config = mt7988_mac_config,
-+ },
- };
- EXPORT_SYMBOL_GPL(mt753x_table);
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -18,6 +18,7 @@ enum mt753x_id {
- ID_MT7530 = 0,
- ID_MT7621 = 1,
- ID_MT7531 = 2,
-+ ID_MT7988 = 3,
- };
-
- #define NUM_TRGMII_CTRL 5
-@@ -59,11 +60,11 @@ enum mt753x_id {
- #define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
- #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x)
-
--#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
-+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
- MT7531_CFC : MT7530_MFC)
--#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \
-+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
- MT7531_MIRROR_EN : MIRROR_EN)
--#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
-+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
- MT7531_MIRROR_MASK : MIRROR_MASK)
-
- /* Registers for BPDU and PAE frame control*/
-@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm {
- MT7531_FORCE_DPX | \
- MT7531_FORCE_RX_FC | \
- MT7531_FORCE_TX_FC)
--#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \
-- MT7531_FORCE_MODE : \
-- PMCR_FORCE_MODE)
-+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
-+ MT7531_FORCE_MODE : PMCR_FORCE_MODE)
- #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
diff --git a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch
deleted file mode 100644
index 2689647319..0000000000
--- a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 91daa4f62ce878b6e1ac5908aceb83550332447f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 16 Apr 2023 13:08:14 +0100
-Subject: [PATCH] net: dsa: mt7530: fix support for MT7531BE
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There are two variants of the MT7531 switch IC which got different
-features (and pins) regarding port 5:
- * MT7531AE: SGMII/1000Base-X/2500Base-X SerDes PCS
- * MT7531BE: RGMII
-
-Moving the creation of the SerDes PCS from mt753x_setup to mt7530_probe
-with commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation
-to mt7530_probe function") works fine for MT7531AE which got two
-instances of mtk-pcs-lynxi, however, MT7531BE requires mt7531_pll_setup
-to setup clocks before the single PCS on port 6 (usually used as CPU
-port) starts to work and hence the PCS creation failed on MT7531BE.
-
-Fix this by introducing a pointer to mt7531_create_sgmii function in
-struct mt7530_priv and call it again at the end of mt753x_setup like it
-was before commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS
-creation to mt7530_probe function").
-
-Fixes: 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/ZDvlLhhqheobUvOK@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530-mdio.c | 16 ++++++++--------
- drivers/net/dsa/mt7530.c | 6 ++++++
- drivers/net/dsa/mt7530.h | 4 ++--
- 3 files changed, 16 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/mt7530-mdio.c
-+++ b/drivers/net/dsa/mt7530-mdio.c
-@@ -81,14 +81,17 @@ static const struct regmap_bus mt7530_re
- };
-
- static int
--mt7531_create_sgmii(struct mt7530_priv *priv)
-+mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
- {
-- struct regmap_config *mt7531_pcs_config[2];
-+ struct regmap_config *mt7531_pcs_config[2] = {};
- struct phylink_pcs *pcs;
- struct regmap *regmap;
- int i, ret = 0;
-
-- for (i = 0; i < 2; i++) {
-+ /* MT7531AE has two SGMII units for port 5 and port 6
-+ * MT7531BE has only one SGMII unit for port 6
-+ */
-+ for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
- sizeof(struct regmap_config),
- GFP_KERNEL);
-@@ -208,11 +211,8 @@ mt7530_probe(struct mdio_device *mdiodev
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
-- if (priv->id == ID_MT7531) {
-- ret = mt7531_create_sgmii(priv);
-- if (ret)
-- return ret;
-- }
-+ if (priv->id == ID_MT7531)
-+ priv->create_sgmii = mt7531_create_sgmii;
-
- return dsa_register_switch(priv->ds);
- }
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3264,6 +3264,12 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-+ if (priv->create_sgmii) {
-+ ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
-+ if (ret && priv->irq)
-+ mt7530_free_irq(priv);
-+ }
-+
- return ret;
- }
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -779,10 +779,10 @@ struct mt753x_info {
- * registers
- * @p6_interface Holding the current port 6 interface
- * @p5_intf_sel: Holding the current port 5 interface select
-- *
- * @irq: IRQ number of the switch
- * @irq_domain: IRQ domain of the switch irq_chip
- * @irq_enable: IRQ enable bits, synced to SYS_INT_EN
-+ * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
- */
- struct mt7530_priv {
- struct device *dev;
-@@ -801,7 +801,6 @@ struct mt7530_priv {
- unsigned int p5_intf_sel;
- u8 mirror_rx;
- u8 mirror_tx;
--
- struct mt7530_port ports[MT7530_NUM_PORTS];
- struct mt753x_pcs pcs[MT7530_NUM_PORTS];
- /* protect among processes for registers access*/
-@@ -809,6 +808,7 @@ struct mt7530_priv {
- int irq;
- struct irq_domain *irq_domain;
- u32 irq_enable;
-+ int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
- };
-
- struct mt7530_hw_vlan_entry {
diff --git a/target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch b/target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch
deleted file mode 100644
index c7f5856e8d..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch
+++ /dev/null
@@ -1,1724 +0,0 @@
-From 70479a40954cf353e87a486997a3477108c75aa9 Mon Sep 17 00:00:00 2001
-From: Frank <Frank.Sae@motor-comm.com>
-Date: Fri, 28 Oct 2022 17:26:21 +0800
-Subject: [PATCH] net: phy: Add driver for Motorcomm yt8521 gigabit ethernet
- phy
-
-Add a driver for the motorcomm yt8521 gigabit ethernet phy. We have verified
- the driver on StarFive VisionFive development board, which is developed by
- Shanghai StarFive Technology Co., Ltd.. On the board, yt8521 gigabit ethernet
- phy works in utp mode, RGMII interface, supports 1000M/100M/10M speeds, and
- wol(magic package).
-
-Signed-off-by: Frank <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS | 1 +
- drivers/net/phy/Kconfig | 2 +-
- drivers/net/phy/motorcomm.c | 1635 ++++++++++++++++++++++++++++++++++-
- 3 files changed, 1635 insertions(+), 3 deletions(-)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -12701,6 +12701,7 @@ F: include/uapi/linux/meye.h
-
- MOTORCOMM PHY DRIVER
- M: Peter Geis <pgwipeout@gmail.com>
-+M: Frank <Frank.Sae@motor-comm.com>
- L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/phy/motorcomm.c
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -242,7 +242,7 @@ config MOTORCOMM_PHY
- tristate "Motorcomm PHYs"
- help
- Enables support for Motorcomm network PHYs.
-- Currently supports the YT8511 gigabit PHY.
-+ Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs.
-
- config NATIONAL_PHY
- tristate "National Semiconductor PHYs"
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1,15 +1,106 @@
- // SPDX-License-Identifier: GPL-2.0+
- /*
-- * Driver for Motorcomm PHYs
-+ * Motorcomm 8511/8521 PHY driver.
- *
- * Author: Peter Geis <pgwipeout@gmail.com>
-+ * Author: Frank <Frank.Sae@motor-comm.com>
- */
-
-+#include <linux/etherdevice.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/phy.h>
-
- #define PHY_ID_YT8511 0x0000010a
-+#define PHY_ID_YT8521 0x0000011A
-+
-+/* YT8521 Register Overview
-+ * UTP Register space | FIBER Register space
-+ * ------------------------------------------------------------
-+ * | UTP MII | FIBER MII |
-+ * | UTP MMD | |
-+ * | UTP Extended | FIBER Extended |
-+ * ------------------------------------------------------------
-+ * | Common Extended |
-+ * ------------------------------------------------------------
-+ */
-+
-+/* 0x10 ~ 0x15 , 0x1E and 0x1F are common MII registers of yt phy */
-+
-+/* Specific Function Control Register */
-+#define YTPHY_SPECIFIC_FUNCTION_CONTROL_REG 0x10
-+
-+/* 2b00 Manual MDI configuration
-+ * 2b01 Manual MDIX configuration
-+ * 2b10 Reserved
-+ * 2b11 Enable automatic crossover for all modes *default*
-+ */
-+#define YTPHY_SFCR_MDI_CROSSOVER_MODE_MASK (BIT(6) | BIT(5))
-+#define YTPHY_SFCR_CROSSOVER_EN BIT(3)
-+#define YTPHY_SFCR_SQE_TEST_EN BIT(2)
-+#define YTPHY_SFCR_POLARITY_REVERSAL_EN BIT(1)
-+#define YTPHY_SFCR_JABBER_DIS BIT(0)
-+
-+/* Specific Status Register */
-+#define YTPHY_SPECIFIC_STATUS_REG 0x11
-+#define YTPHY_SSR_SPEED_MODE_OFFSET 14
-+
-+#define YTPHY_SSR_SPEED_MODE_MASK (BIT(15) | BIT(14))
-+#define YTPHY_SSR_SPEED_10M 0x0
-+#define YTPHY_SSR_SPEED_100M 0x1
-+#define YTPHY_SSR_SPEED_1000M 0x2
-+#define YTPHY_SSR_DUPLEX_OFFSET 13
-+#define YTPHY_SSR_DUPLEX BIT(13)
-+#define YTPHY_SSR_PAGE_RECEIVED BIT(12)
-+#define YTPHY_SSR_SPEED_DUPLEX_RESOLVED BIT(11)
-+#define YTPHY_SSR_LINK BIT(10)
-+#define YTPHY_SSR_MDIX_CROSSOVER BIT(6)
-+#define YTPHY_SSR_DOWNGRADE BIT(5)
-+#define YTPHY_SSR_TRANSMIT_PAUSE BIT(3)
-+#define YTPHY_SSR_RECEIVE_PAUSE BIT(2)
-+#define YTPHY_SSR_POLARITY BIT(1)
-+#define YTPHY_SSR_JABBER BIT(0)
-+
-+/* Interrupt enable Register */
-+#define YTPHY_INTERRUPT_ENABLE_REG 0x12
-+#define YTPHY_IER_WOL BIT(6)
-+
-+/* Interrupt Status Register */
-+#define YTPHY_INTERRUPT_STATUS_REG 0x13
-+#define YTPHY_ISR_AUTONEG_ERR BIT(15)
-+#define YTPHY_ISR_SPEED_CHANGED BIT(14)
-+#define YTPHY_ISR_DUPLEX_CHANGED BIT(13)
-+#define YTPHY_ISR_PAGE_RECEIVED BIT(12)
-+#define YTPHY_ISR_LINK_FAILED BIT(11)
-+#define YTPHY_ISR_LINK_SUCCESSED BIT(10)
-+#define YTPHY_ISR_WOL BIT(6)
-+#define YTPHY_ISR_WIRESPEED_DOWNGRADE BIT(5)
-+#define YTPHY_ISR_SERDES_LINK_FAILED BIT(3)
-+#define YTPHY_ISR_SERDES_LINK_SUCCESSED BIT(2)
-+#define YTPHY_ISR_POLARITY_CHANGED BIT(1)
-+#define YTPHY_ISR_JABBER_HAPPENED BIT(0)
-+
-+/* Speed Auto Downgrade Control Register */
-+#define YTPHY_SPEED_AUTO_DOWNGRADE_CONTROL_REG 0x14
-+#define YTPHY_SADCR_SPEED_DOWNGRADE_EN BIT(5)
-+
-+/* If these bits are set to 3, the PHY attempts five times ( 3(set value) +
-+ * additional 2) before downgrading, default 0x3
-+ */
-+#define YTPHY_SADCR_SPEED_RETRY_LIMIT (0x3 << 2)
-+
-+/* Rx Error Counter Register */
-+#define YTPHY_RX_ERROR_COUNTER_REG 0x15
-+
-+/* Extended Register's Address Offset Register */
-+#define YTPHY_PAGE_SELECT 0x1E
-+
-+/* Extended Register's Data Register */
-+#define YTPHY_PAGE_DATA 0x1F
-+
-+/* FIBER Auto-Negotiation link partner ability */
-+#define YTPHY_FLPA_PAUSE (0x3 << 7)
-+#define YTPHY_FLPA_ASYM_PAUSE (0x2 << 7)
-
- #define YT8511_PAGE_SELECT 0x1e
- #define YT8511_PAGE 0x1f
-@@ -38,6 +129,352 @@
- #define YT8511_DELAY_FE_TX_EN (0xf << 12)
- #define YT8511_DELAY_FE_TX_DIS (0x2 << 12)
-
-+/* Extended register is different from MMD Register and MII Register.
-+ * We can use ytphy_read_ext/ytphy_write_ext/ytphy_modify_ext function to
-+ * operate extended register.
-+ * Extended Register start
-+ */
-+
-+/* Phy gmii clock gating Register */
-+#define YT8521_CLOCK_GATING_REG 0xC
-+#define YT8521_CGR_RX_CLK_EN BIT(12)
-+
-+#define YT8521_EXTREG_SLEEP_CONTROL1_REG 0x27
-+#define YT8521_ESC1R_SLEEP_SW BIT(15)
-+#define YT8521_ESC1R_PLLON_SLP BIT(14)
-+
-+/* Phy fiber Link timer cfg2 Register */
-+#define YT8521_LINK_TIMER_CFG2_REG 0xA5
-+#define YT8521_LTCR_EN_AUTOSEN BIT(15)
-+
-+/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers
-+ * of yt8521 phy. There is no need to switch reg space when operating these
-+ * registers.
-+ */
-+
-+#define YT8521_REG_SPACE_SELECT_REG 0xA000
-+#define YT8521_RSSR_SPACE_MASK BIT(1)
-+#define YT8521_RSSR_FIBER_SPACE (0x1 << 1)
-+#define YT8521_RSSR_UTP_SPACE (0x0 << 1)
-+#define YT8521_RSSR_TO_BE_ARBITRATED (0xFF)
-+
-+#define YT8521_CHIP_CONFIG_REG 0xA001
-+#define YT8521_CCR_SW_RST BIT(15)
-+
-+#define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0))
-+#define YT8521_CCR_MODE_UTP_TO_RGMII 0
-+#define YT8521_CCR_MODE_FIBER_TO_RGMII 1
-+#define YT8521_CCR_MODE_UTP_FIBER_TO_RGMII 2
-+#define YT8521_CCR_MODE_UTP_TO_SGMII 3
-+#define YT8521_CCR_MODE_SGPHY_TO_RGMAC 4
-+#define YT8521_CCR_MODE_SGMAC_TO_RGPHY 5
-+#define YT8521_CCR_MODE_UTP_TO_FIBER_AUTO 6
-+#define YT8521_CCR_MODE_UTP_TO_FIBER_FORCE 7
-+
-+/* 3 phy polling modes,poll mode combines utp and fiber mode*/
-+#define YT8521_MODE_FIBER 0x1
-+#define YT8521_MODE_UTP 0x2
-+#define YT8521_MODE_POLL 0x3
-+
-+#define YT8521_RGMII_CONFIG1_REG 0xA003
-+
-+/* TX Gig-E Delay is bits 3:0, default 0x1
-+ * TX Fast-E Delay is bits 7:4, default 0xf
-+ * RX Delay is bits 13:10, default 0x0
-+ * Delay = 150ps * N
-+ * On = 2250ps, off = 0ps
-+ */
-+#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10)
-+#define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
-+#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
-+#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4)
-+#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
-+#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
-+#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0)
-+#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
-+#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
-+
-+#define YTPHY_MISC_CONFIG_REG 0xA006
-+#define YTPHY_MCR_FIBER_SPEED_MASK BIT(0)
-+#define YTPHY_MCR_FIBER_1000BX (0x1 << 0)
-+#define YTPHY_MCR_FIBER_100FX (0x0 << 0)
-+
-+/* WOL MAC ADDR: MACADDR2(highest), MACADDR1(middle), MACADDR0(lowest) */
-+#define YTPHY_WOL_MACADDR2_REG 0xA007
-+#define YTPHY_WOL_MACADDR1_REG 0xA008
-+#define YTPHY_WOL_MACADDR0_REG 0xA009
-+
-+#define YTPHY_WOL_CONFIG_REG 0xA00A
-+#define YTPHY_WCR_INTR_SEL BIT(6)
-+#define YTPHY_WCR_ENABLE BIT(3)
-+
-+/* 2b00 84ms
-+ * 2b01 168ms *default*
-+ * 2b10 336ms
-+ * 2b11 672ms
-+ */
-+#define YTPHY_WCR_PULSE_WIDTH_MASK (BIT(2) | BIT(1))
-+#define YTPHY_WCR_PULSE_WIDTH_672MS (BIT(2) | BIT(1))
-+
-+/* 1b0 Interrupt and WOL events is level triggered and active LOW *default*
-+ * 1b1 Interrupt and WOL events is pulse triggered and active LOW
-+ */
-+#define YTPHY_WCR_TYPE_PULSE BIT(0)
-+
-+/* Extended Register end */
-+
-+struct yt8521_priv {
-+ /* combo_advertising is used for case of YT8521 in combo mode,
-+ * this means that yt8521 may work in utp or fiber mode which depends
-+ * on which media is connected (YT8521_RSSR_TO_BE_ARBITRATED).
-+ */
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(combo_advertising);
-+
-+ /* YT8521_MODE_FIBER / YT8521_MODE_UTP / YT8521_MODE_POLL*/
-+ u8 polling_mode;
-+ u8 strap_mode; /* 8 working modes */
-+ /* current reg page of yt8521 phy:
-+ * YT8521_RSSR_UTP_SPACE
-+ * YT8521_RSSR_FIBER_SPACE
-+ * YT8521_RSSR_TO_BE_ARBITRATED
-+ */
-+ u8 reg_page;
-+};
-+
-+/**
-+ * ytphy_read_ext() - read a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to read
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns the value of regnum reg or negative error code
-+ */
-+static int ytphy_read_ext(struct phy_device *phydev, u16 regnum)
-+{
-+ int ret;
-+
-+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __phy_read(phydev, YTPHY_PAGE_DATA);
-+}
-+
-+/**
-+ * ytphy_read_ext_with_lock() - read a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to read
-+ *
-+ * returns the value of regnum reg or negative error code
-+ */
-+static int ytphy_read_ext_with_lock(struct phy_device *phydev, u16 regnum)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_read_ext(phydev, regnum);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
-+/**
-+ * ytphy_write_ext() - write a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_write_ext(struct phy_device *phydev, u16 regnum, u16 val)
-+{
-+ int ret;
-+
-+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __phy_write(phydev, YTPHY_PAGE_DATA, val);
-+}
-+
-+/**
-+ * ytphy_write_ext_with_lock() - write a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_write_ext_with_lock(struct phy_device *phydev, u16 regnum,
-+ u16 val)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_write_ext(phydev, regnum, val);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
-+/**
-+ * ytphy_modify_ext() - bits modify a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's extended register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
-+ u16 set)
-+{
-+ int ret;
-+
-+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __phy_modify(phydev, YTPHY_PAGE_DATA, mask, set);
-+}
-+
-+/**
-+ * ytphy_modify_ext_with_lock() - bits modify a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's extended register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_modify_ext_with_lock(struct phy_device *phydev, u16 regnum,
-+ u16 mask, u16 set)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_modify_ext(phydev, regnum, mask, set);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
-+/**
-+ * ytphy_get_wol() - report whether wake-on-lan is enabled
-+ * @phydev: a pointer to a &struct phy_device
-+ * @wol: a pointer to a &struct ethtool_wolinfo
-+ *
-+ * NOTE: YTPHY_WOL_CONFIG_REG is common ext reg.
-+ */
-+static void ytphy_get_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int wol_config;
-+
-+ wol->supported = WAKE_MAGIC;
-+ wol->wolopts = 0;
-+
-+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG);
-+ if (wol_config < 0)
-+ return;
-+
-+ if (wol_config & YTPHY_WCR_ENABLE)
-+ wol->wolopts |= WAKE_MAGIC;
-+}
-+
-+/**
-+ * ytphy_set_wol() - turn wake-on-lan on or off
-+ * @phydev: a pointer to a &struct phy_device
-+ * @wol: a pointer to a &struct ethtool_wolinfo
-+ *
-+ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG
-+ * and YTPHY_WOL_MACADDR0_REG are common ext reg. The
-+ * YTPHY_INTERRUPT_ENABLE_REG of UTP is special, fiber also use this register.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
-+{
-+ struct net_device *p_attached_dev;
-+ const u16 mac_addr_reg[] = {
-+ YTPHY_WOL_MACADDR2_REG,
-+ YTPHY_WOL_MACADDR1_REG,
-+ YTPHY_WOL_MACADDR0_REG,
-+ };
-+ const u8 *mac_addr;
-+ int old_page;
-+ int ret = 0;
-+ u16 mask;
-+ u16 val;
-+ u8 i;
-+
-+ if (wol->wolopts & WAKE_MAGIC) {
-+ p_attached_dev = phydev->attached_dev;
-+ if (!p_attached_dev)
-+ return -ENODEV;
-+
-+ mac_addr = (const u8 *)p_attached_dev->dev_addr;
-+ if (!is_valid_ether_addr(mac_addr))
-+ return -EINVAL;
-+
-+ /* lock mdio bus then switch to utp reg space */
-+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* Store the device address for the magic packet */
-+ for (i = 0; i < 3; i++) {
-+ ret = ytphy_write_ext(phydev, mac_addr_reg[i],
-+ ((mac_addr[i * 2] << 8)) |
-+ (mac_addr[i * 2 + 1]));
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+ /* Enable WOL feature */
-+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL;
-+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS;
-+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ /* Enable WOL interrupt */
-+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0,
-+ YTPHY_IER_WOL);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ } else {
-+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* Disable WOL feature */
-+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0);
-+
-+ /* Disable WOL interrupt */
-+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG,
-+ YTPHY_IER_WOL, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
- static int yt8511_read_page(struct phy_device *phydev)
- {
- return __phy_read(phydev, YT8511_PAGE_SELECT);
-@@ -111,6 +548,1181 @@ err_restore_page:
- return phy_restore_page(phydev, oldpage, ret);
- }
-
-+/**
-+ * yt8521_read_page() - read reg page
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns current reg space of yt8521 (YT8521_RSSR_FIBER_SPACE/
-+ * YT8521_RSSR_UTP_SPACE) or negative errno code
-+ */
-+static int yt8521_read_page(struct phy_device *phydev)
-+{
-+ int old_page;
-+
-+ old_page = ytphy_read_ext(phydev, YT8521_REG_SPACE_SELECT_REG);
-+ if (old_page < 0)
-+ return old_page;
-+
-+ if ((old_page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE)
-+ return YT8521_RSSR_FIBER_SPACE;
-+
-+ return YT8521_RSSR_UTP_SPACE;
-+};
-+
-+/**
-+ * yt8521_write_page() - write reg page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to write.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_write_page(struct phy_device *phydev, int page)
-+{
-+ int mask = YT8521_RSSR_SPACE_MASK;
-+ int set;
-+
-+ if ((page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE)
-+ set = YT8521_RSSR_FIBER_SPACE;
-+ else
-+ set = YT8521_RSSR_UTP_SPACE;
-+
-+ return ytphy_modify_ext(phydev, YT8521_REG_SPACE_SELECT_REG, mask, set);
-+};
-+
-+/**
-+ * yt8521_probe() - read chip config then set suitable polling_mode
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct yt8521_priv *priv;
-+ int chip_config;
-+ int ret;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ phydev->priv = priv;
-+
-+ chip_config = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
-+ if (chip_config < 0)
-+ return chip_config;
-+
-+ priv->strap_mode = chip_config & YT8521_CCR_MODE_SEL_MASK;
-+ switch (priv->strap_mode) {
-+ case YT8521_CCR_MODE_FIBER_TO_RGMII:
-+ case YT8521_CCR_MODE_SGPHY_TO_RGMAC:
-+ case YT8521_CCR_MODE_SGMAC_TO_RGPHY:
-+ priv->polling_mode = YT8521_MODE_FIBER;
-+ priv->reg_page = YT8521_RSSR_FIBER_SPACE;
-+ phydev->port = PORT_FIBRE;
-+ break;
-+ case YT8521_CCR_MODE_UTP_FIBER_TO_RGMII:
-+ case YT8521_CCR_MODE_UTP_TO_FIBER_AUTO:
-+ case YT8521_CCR_MODE_UTP_TO_FIBER_FORCE:
-+ priv->polling_mode = YT8521_MODE_POLL;
-+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED;
-+ phydev->port = PORT_NONE;
-+ break;
-+ case YT8521_CCR_MODE_UTP_TO_SGMII:
-+ case YT8521_CCR_MODE_UTP_TO_RGMII:
-+ priv->polling_mode = YT8521_MODE_UTP;
-+ priv->reg_page = YT8521_RSSR_UTP_SPACE;
-+ phydev->port = PORT_TP;
-+ break;
-+ }
-+ /* set default reg space */
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = ytphy_write_ext_with_lock(phydev,
-+ YT8521_REG_SPACE_SELECT_REG,
-+ priv->reg_page);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_read_lpa(struct phy_device *phydev)
-+{
-+ int lpa, lpagb;
-+
-+ if (phydev->autoneg == AUTONEG_ENABLE) {
-+ if (!phydev->autoneg_complete) {
-+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
-+ 0);
-+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
-+ return 0;
-+ }
-+
-+ if (phydev->is_gigabit_capable) {
-+ lpagb = __phy_read(phydev, MII_STAT1000);
-+ if (lpagb < 0)
-+ return lpagb;
-+
-+ if (lpagb & LPA_1000MSFAIL) {
-+ int adv = __phy_read(phydev, MII_CTRL1000);
-+
-+ if (adv < 0)
-+ return adv;
-+
-+ if (adv & CTL1000_ENABLE_MASTER)
-+ phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n");
-+ else
-+ phydev_err(phydev, "Master/Slave resolution failed\n");
-+ return -ENOLINK;
-+ }
-+
-+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
-+ lpagb);
-+ }
-+
-+ lpa = __phy_read(phydev, MII_LPA);
-+ if (lpa < 0)
-+ return lpa;
-+
-+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
-+ } else {
-+ linkmode_zero(phydev->lp_advertising);
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_adjust_status() - update speed and duplex to phydev. when in fiber
-+ * mode, adjust speed and duplex.
-+ * @phydev: a pointer to a &struct phy_device
-+ * @status: yt8521 status read from YTPHY_SPECIFIC_STATUS_REG
-+ * @is_utp: false(yt8521 work in fiber mode) or true(yt8521 work in utp mode)
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0
-+ */
-+static int yt8521_adjust_status(struct phy_device *phydev, int status,
-+ bool is_utp)
-+{
-+ int speed_mode, duplex;
-+ int speed;
-+ int err;
-+ int lpa;
-+
-+ if (is_utp)
-+ duplex = (status & YTPHY_SSR_DUPLEX) >> YTPHY_SSR_DUPLEX_OFFSET;
-+ else
-+ duplex = DUPLEX_FULL; /* for fiber, it always DUPLEX_FULL */
-+
-+ speed_mode = (status & YTPHY_SSR_SPEED_MODE_MASK) >>
-+ YTPHY_SSR_SPEED_MODE_OFFSET;
-+
-+ switch (speed_mode) {
-+ case YTPHY_SSR_SPEED_10M:
-+ if (is_utp)
-+ speed = SPEED_10;
-+ else
-+ /* for fiber, it will never run here, default to
-+ * SPEED_UNKNOWN
-+ */
-+ speed = SPEED_UNKNOWN;
-+ break;
-+ case YTPHY_SSR_SPEED_100M:
-+ speed = SPEED_100;
-+ break;
-+ case YTPHY_SSR_SPEED_1000M:
-+ speed = SPEED_1000;
-+ break;
-+ default:
-+ speed = SPEED_UNKNOWN;
-+ break;
-+ }
-+
-+ phydev->speed = speed;
-+ phydev->duplex = duplex;
-+
-+ if (is_utp) {
-+ err = ytphy_utp_read_lpa(phydev);
-+ if (err < 0)
-+ return err;
-+
-+ phy_resolve_aneg_pause(phydev);
-+ } else {
-+ lpa = __phy_read(phydev, MII_LPA);
-+ if (lpa < 0)
-+ return lpa;
-+
-+ /* only support 1000baseX Full */
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-+ phydev->lp_advertising, lpa & LPA_1000XFULL);
-+
-+ if (!(lpa & YTPHY_FLPA_PAUSE)) {
-+ phydev->pause = 0;
-+ phydev->asym_pause = 0;
-+ } else if ((lpa & YTPHY_FLPA_ASYM_PAUSE)) {
-+ phydev->pause = 1;
-+ phydev->asym_pause = 1;
-+ } else {
-+ phydev->pause = 1;
-+ phydev->asym_pause = 0;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_read_status_paged() - determines the speed and duplex of one page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 1 (utp or fiber link),0 (no link) or negative errno code
-+ */
-+static int yt8521_read_status_paged(struct phy_device *phydev, int page)
-+{
-+ int fiber_latch_val;
-+ int fiber_curr_val;
-+ int old_page;
-+ int ret = 0;
-+ int status;
-+ int link;
-+
-+ linkmode_zero(phydev->lp_advertising);
-+ phydev->duplex = DUPLEX_UNKNOWN;
-+ phydev->speed = SPEED_UNKNOWN;
-+ phydev->asym_pause = 0;
-+ phydev->pause = 0;
-+
-+ /* YT8521 has two reg space (utp/fiber) for linkup with utp/fiber
-+ * respectively. but for utp/fiber combo mode, reg space should be
-+ * arbitrated based on media priority. by default, utp takes
-+ * priority. reg space should be properly set before read
-+ * YTPHY_SPECIFIC_STATUS_REG.
-+ */
-+
-+ page &= YT8521_RSSR_SPACE_MASK;
-+ old_page = phy_select_page(phydev, page);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* Read YTPHY_SPECIFIC_STATUS_REG, which indicates the speed and duplex
-+ * of the PHY is actually using.
-+ */
-+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ status = ret;
-+ link = !!(status & YTPHY_SSR_LINK);
-+
-+ /* When PHY is in fiber mode, speed transferred from 1000Mbps to
-+ * 100Mbps,there is not link down from YTPHY_SPECIFIC_STATUS_REG, so
-+ * we need check MII_BMSR to identify such case.
-+ */
-+ if (page == YT8521_RSSR_FIBER_SPACE) {
-+ ret = __phy_read(phydev, MII_BMSR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ fiber_latch_val = ret;
-+ ret = __phy_read(phydev, MII_BMSR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ fiber_curr_val = ret;
-+ if (link && fiber_latch_val != fiber_curr_val) {
-+ link = 0;
-+ phydev_info(phydev,
-+ "%s, fiber link down detect, latch = %04x, curr = %04x\n",
-+ __func__, fiber_latch_val, fiber_curr_val);
-+ }
-+ } else {
-+ /* Read autonegotiation status */
-+ ret = __phy_read(phydev, MII_BMSR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ phydev->autoneg_complete = ret & BMSR_ANEGCOMPLETE ? 1 : 0;
-+ }
-+
-+ if (link) {
-+ if (page == YT8521_RSSR_UTP_SPACE)
-+ yt8521_adjust_status(phydev, status, true);
-+ else
-+ yt8521_adjust_status(phydev, status, false);
-+ }
-+ return phy_restore_page(phydev, old_page, link);
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_read_status() - determines the negotiated speed and duplex
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_read_status(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int link_fiber = 0;
-+ int link_utp;
-+ int link;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ link = yt8521_read_status_paged(phydev, priv->reg_page);
-+ if (link < 0)
-+ return link;
-+ } else {
-+ /* when page is YT8521_RSSR_TO_BE_ARBITRATED, arbitration is
-+ * needed. by default, utp is higher priority.
-+ */
-+
-+ link_utp = yt8521_read_status_paged(phydev,
-+ YT8521_RSSR_UTP_SPACE);
-+ if (link_utp < 0)
-+ return link_utp;
-+
-+ if (!link_utp) {
-+ link_fiber = yt8521_read_status_paged(phydev,
-+ YT8521_RSSR_FIBER_SPACE);
-+ if (link_fiber < 0)
-+ return link_fiber;
-+ }
-+
-+ link = link_utp || link_fiber;
-+ }
-+
-+ if (link) {
-+ if (phydev->link == 0) {
-+ /* arbitrate reg space based on linkup media type. */
-+ if (priv->polling_mode == YT8521_MODE_POLL &&
-+ priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) {
-+ if (link_fiber)
-+ priv->reg_page =
-+ YT8521_RSSR_FIBER_SPACE;
-+ else
-+ priv->reg_page = YT8521_RSSR_UTP_SPACE;
-+
-+ ret = ytphy_write_ext_with_lock(phydev,
-+ YT8521_REG_SPACE_SELECT_REG,
-+ priv->reg_page);
-+ if (ret < 0)
-+ return ret;
-+
-+ phydev->port = link_fiber ? PORT_FIBRE : PORT_TP;
-+
-+ phydev_info(phydev, "%s, link up, media: %s\n",
-+ __func__,
-+ (phydev->port == PORT_TP) ?
-+ "UTP" : "Fiber");
-+ }
-+ }
-+ phydev->link = 1;
-+ } else {
-+ if (phydev->link == 1) {
-+ phydev_info(phydev, "%s, link down, media: %s\n",
-+ __func__, (phydev->port == PORT_TP) ?
-+ "UTP" : "Fiber");
-+
-+ /* When in YT8521_MODE_POLL mode, need prepare for next
-+ * arbitration.
-+ */
-+ if (priv->polling_mode == YT8521_MODE_POLL) {
-+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED;
-+ phydev->port = PORT_NONE;
-+ }
-+ }
-+
-+ phydev->link = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_modify_bmcr_paged - bits modify a PHY's BMCR register of one page
-+ * @phydev: the phy_device struct
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to operate
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's BMCR register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space
-+ * has MII_BMCR. poll mode combines utp and faber,so need do both.
-+ * If it is reset, it will wait for completion.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_modify_bmcr_paged(struct phy_device *phydev, int page,
-+ u16 mask, u16 set)
-+{
-+ int max_cnt = 500; /* the max wait time of reset ~ 500 ms */
-+ int old_page;
-+ int ret = 0;
-+
-+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ ret = __phy_modify(phydev, MII_BMCR, mask, set);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ /* If it is reset, need to wait for the reset to complete */
-+ if (set == BMCR_RESET) {
-+ while (max_cnt--) {
-+ usleep_range(1000, 1100);
-+ ret = __phy_read(phydev, MII_BMCR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ if (!(ret & BMCR_RESET))
-+ return phy_restore_page(phydev, old_page, 0);
-+ }
-+ }
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_modify_utp_fiber_bmcr - bits modify a PHY's BMCR register
-+ * @phydev: the phy_device struct
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's BMCR register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space
-+ * has MII_BMCR. poll mode combines utp and faber,so need do both.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_modify_utp_fiber_bmcr(struct phy_device *phydev, u16 mask,
-+ u16 set)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = yt8521_modify_bmcr_paged(phydev, priv->reg_page, mask,
-+ set);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_UTP_SPACE,
-+ mask, set);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_FIBER_SPACE,
-+ mask, set);
-+ if (ret < 0)
-+ return ret;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_soft_reset() - called to issue a PHY software reset
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_soft_reset(struct phy_device *phydev)
-+{
-+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_RESET);
-+}
-+
-+/**
-+ * yt8521_suspend() - suspend the hardware
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_suspend(struct phy_device *phydev)
-+{
-+ int wol_config;
-+
-+ /* YTPHY_WOL_CONFIG_REG is common ext reg */
-+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG);
-+ if (wol_config < 0)
-+ return wol_config;
-+
-+ /* if wol enable, do nothing */
-+ if (wol_config & YTPHY_WCR_ENABLE)
-+ return 0;
-+
-+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_PDOWN);
-+}
-+
-+/**
-+ * yt8521_resume() - resume the hardware
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_resume(struct phy_device *phydev)
-+{
-+ int ret;
-+ int wol_config;
-+
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG);
-+ if (wol_config < 0)
-+ return wol_config;
-+
-+ /* if wol enable, do nothing */
-+ if (wol_config & YTPHY_WCR_ENABLE)
-+ return 0;
-+
-+ return yt8521_modify_utp_fiber_bmcr(phydev, BMCR_PDOWN, 0);
-+}
-+
-+/**
-+ * yt8521_config_init() - called to initialize the PHY
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_config_init(struct phy_device *phydev)
-+{
-+ int old_page;
-+ int ret = 0;
-+ u16 val;
-+
-+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val |= YT8521_RC1R_RX_DELAY_DIS;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val |= YT8521_RC1R_RX_DELAY_EN;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val |= YT8521_RC1R_RX_DELAY_DIS;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val |= YT8521_RC1R_RX_DELAY_EN;
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ break;
-+ default: /* do not support other modes */
-+ ret = -EOPNOTSUPP;
-+ goto err_restore_page;
-+ }
-+
-+ /* set rgmii delay mode */
-+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII) {
-+ ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG,
-+ (YT8521_RC1R_RX_DELAY_MASK |
-+ YT8521_RC1R_FE_TX_DELAY_MASK |
-+ YT8521_RC1R_GE_TX_DELAY_MASK),
-+ val);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ /* enable RXC clock when no wire plug */
-+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
-+ YT8521_CGR_RX_CLK_EN, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_prepare_fiber_features() - A small helper function that setup
-+ * fiber's features.
-+ * @phydev: a pointer to a &struct phy_device
-+ * @dst: a pointer to store fiber's features
-+ */
-+static void yt8521_prepare_fiber_features(struct phy_device *phydev,
-+ unsigned long *dst)
-+{
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, dst);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, dst);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, dst);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, dst);
-+}
-+
-+/**
-+ * yt8521_fiber_setup_forced - configures/forces speed from @phydev
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_fiber_setup_forced(struct phy_device *phydev)
-+{
-+ u16 val;
-+ int ret;
-+
-+ if (phydev->speed == SPEED_1000)
-+ val = YTPHY_MCR_FIBER_1000BX;
-+ else if (phydev->speed == SPEED_100)
-+ val = YTPHY_MCR_FIBER_100FX;
-+ else
-+ return -EINVAL;
-+
-+ ret = __phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* disable Fiber auto sensing */
-+ ret = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG,
-+ YT8521_LTCR_EN_AUTOSEN, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ytphy_modify_ext(phydev, YTPHY_MISC_CONFIG_REG,
-+ YTPHY_MCR_FIBER_SPEED_MASK, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ return ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
-+ YT8521_CCR_SW_RST, 0);
-+}
-+
-+/**
-+ * ytphy_check_and_restart_aneg - Enable and restart auto-negotiation
-+ * @phydev: target phy_device struct
-+ * @restart: whether aneg restart is requested
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_check_and_restart_aneg(struct phy_device *phydev, bool restart)
-+{
-+ int ret;
-+
-+ if (!restart) {
-+ /* Advertisement hasn't changed, but maybe aneg was never on to
-+ * begin with? Or maybe phy was isolated?
-+ */
-+ ret = __phy_read(phydev, MII_BMCR);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE))
-+ restart = true;
-+ }
-+ /* Enable and Restart Autonegotiation
-+ * Don't isolate the PHY if we're negotiating
-+ */
-+ if (restart)
-+ return __phy_modify(phydev, MII_BMCR, BMCR_ISOLATE,
-+ BMCR_ANENABLE | BMCR_ANRESTART);
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_fiber_config_aneg - restart auto-negotiation or write
-+ * YTPHY_MISC_CONFIG_REG.
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_fiber_config_aneg(struct phy_device *phydev)
-+{
-+ int err, changed = 0;
-+ int bmcr;
-+ u16 adv;
-+
-+ if (phydev->autoneg != AUTONEG_ENABLE)
-+ return yt8521_fiber_setup_forced(phydev);
-+
-+ /* enable Fiber auto sensing */
-+ err = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG,
-+ 0, YT8521_LTCR_EN_AUTOSEN);
-+ if (err < 0)
-+ return err;
-+
-+ err = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
-+ YT8521_CCR_SW_RST, 0);
-+ if (err < 0)
-+ return err;
-+
-+ bmcr = __phy_read(phydev, MII_BMCR);
-+ if (bmcr < 0)
-+ return bmcr;
-+
-+ /* When it is coming from fiber forced mode, add bmcr power down
-+ * and power up to let aneg work fine.
-+ */
-+ if (!(bmcr & BMCR_ANENABLE)) {
-+ __phy_modify(phydev, MII_BMCR, 0, BMCR_PDOWN);
-+ usleep_range(1000, 1100);
-+ __phy_modify(phydev, MII_BMCR, BMCR_PDOWN, 0);
-+ }
-+
-+ adv = linkmode_adv_to_mii_adv_x(phydev->advertising,
-+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
-+
-+ /* Setup fiber advertisement */
-+ err = __phy_modify_changed(phydev, MII_ADVERTISE,
-+ ADVERTISE_1000XHALF | ADVERTISE_1000XFULL |
-+ ADVERTISE_1000XPAUSE |
-+ ADVERTISE_1000XPSE_ASYM,
-+ adv);
-+ if (err < 0)
-+ return err;
-+
-+ if (err > 0)
-+ changed = 1;
-+
-+ return ytphy_check_and_restart_aneg(phydev, changed);
-+}
-+
-+/**
-+ * ytphy_setup_master_slave
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE: The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_setup_master_slave(struct phy_device *phydev)
-+{
-+ u16 ctl = 0;
-+
-+ if (!phydev->is_gigabit_capable)
-+ return 0;
-+
-+ switch (phydev->master_slave_set) {
-+ case MASTER_SLAVE_CFG_MASTER_PREFERRED:
-+ ctl |= CTL1000_PREFER_MASTER;
-+ break;
-+ case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
-+ break;
-+ case MASTER_SLAVE_CFG_MASTER_FORCE:
-+ ctl |= CTL1000_AS_MASTER;
-+ fallthrough;
-+ case MASTER_SLAVE_CFG_SLAVE_FORCE:
-+ ctl |= CTL1000_ENABLE_MASTER;
-+ break;
-+ case MASTER_SLAVE_CFG_UNKNOWN:
-+ case MASTER_SLAVE_CFG_UNSUPPORTED:
-+ return 0;
-+ default:
-+ phydev_warn(phydev, "Unsupported Master/Slave mode\n");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return __phy_modify_changed(phydev, MII_CTRL1000,
-+ (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER |
-+ CTL1000_PREFER_MASTER), ctl);
-+}
-+
-+/**
-+ * ytphy_utp_config_advert - sanitize and advertise auto-negotiation parameters
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE: Writes MII_ADVERTISE with the appropriate values,
-+ * after sanitizing the values to make sure we only advertise
-+ * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
-+ * hasn't changed, and > 0 if it has changed.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_config_advert(struct phy_device *phydev)
-+{
-+ int err, bmsr, changed = 0;
-+ u32 adv;
-+
-+ /* Only allow advertising what this PHY supports */
-+ linkmode_and(phydev->advertising, phydev->advertising,
-+ phydev->supported);
-+
-+ adv = linkmode_adv_to_mii_adv_t(phydev->advertising);
-+
-+ /* Setup standard advertisement */
-+ err = __phy_modify_changed(phydev, MII_ADVERTISE,
-+ ADVERTISE_ALL | ADVERTISE_100BASE4 |
-+ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
-+ adv);
-+ if (err < 0)
-+ return err;
-+ if (err > 0)
-+ changed = 1;
-+
-+ bmsr = __phy_read(phydev, MII_BMSR);
-+ if (bmsr < 0)
-+ return bmsr;
-+
-+ /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all
-+ * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a
-+ * logical 1.
-+ */
-+ if (!(bmsr & BMSR_ESTATEN))
-+ return changed;
-+
-+ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
-+
-+ err = __phy_modify_changed(phydev, MII_CTRL1000,
-+ ADVERTISE_1000FULL | ADVERTISE_1000HALF,
-+ adv);
-+ if (err < 0)
-+ return err;
-+ if (err > 0)
-+ changed = 1;
-+
-+ return changed;
-+}
-+
-+/**
-+ * ytphy_utp_config_aneg - restart auto-negotiation or write BMCR
-+ * @phydev: target phy_device struct
-+ * @changed: whether autoneg is requested
-+ *
-+ * NOTE: If auto-negotiation is enabled, we configure the
-+ * advertising, and then restart auto-negotiation. If it is not
-+ * enabled, then we write the BMCR.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_config_aneg(struct phy_device *phydev, bool changed)
-+{
-+ int err;
-+ u16 ctl;
-+
-+ err = ytphy_setup_master_slave(phydev);
-+ if (err < 0)
-+ return err;
-+ else if (err)
-+ changed = true;
-+
-+ if (phydev->autoneg != AUTONEG_ENABLE) {
-+ /* configures/forces speed/duplex from @phydev */
-+
-+ ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
-+
-+ return __phy_modify(phydev, MII_BMCR, ~(BMCR_LOOPBACK |
-+ BMCR_ISOLATE | BMCR_PDOWN), ctl);
-+ }
-+
-+ err = ytphy_utp_config_advert(phydev);
-+ if (err < 0) /* error */
-+ return err;
-+ else if (err)
-+ changed = true;
-+
-+ return ytphy_check_and_restart_aneg(phydev, changed);
-+}
-+
-+/**
-+ * yt8521_config_aneg_paged() - switch reg space then call genphy_config_aneg
-+ * of one page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_config_aneg_paged(struct phy_device *phydev, int page)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(fiber_supported);
-+ struct yt8521_priv *priv = phydev->priv;
-+ int old_page;
-+ int ret = 0;
-+
-+ page &= YT8521_RSSR_SPACE_MASK;
-+
-+ old_page = phy_select_page(phydev, page);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED,
-+ * phydev->advertising should be updated.
-+ */
-+ if (priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) {
-+ linkmode_zero(fiber_supported);
-+ yt8521_prepare_fiber_features(phydev, fiber_supported);
-+
-+ /* prepare fiber_supported, then setup advertising. */
-+ if (page == YT8521_RSSR_FIBER_SPACE) {
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ fiber_supported);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ fiber_supported);
-+ linkmode_and(phydev->advertising,
-+ priv->combo_advertising, fiber_supported);
-+ } else {
-+ /* ETHTOOL_LINK_MODE_Autoneg_BIT is also used in utp */
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ fiber_supported);
-+ linkmode_andnot(phydev->advertising,
-+ priv->combo_advertising,
-+ fiber_supported);
-+ }
-+ }
-+
-+ if (page == YT8521_RSSR_FIBER_SPACE)
-+ ret = yt8521_fiber_config_aneg(phydev);
-+ else
-+ ret = ytphy_utp_config_aneg(phydev, false);
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_config_aneg() - change reg space then call yt8521_config_aneg_paged
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_config_aneg(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = yt8521_config_aneg_paged(phydev, priv->reg_page);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED,
-+ * phydev->advertising need to be saved at first run.
-+ * Because it contains the advertising which supported by both
-+ * mac and yt8521(utp and fiber).
-+ */
-+ if (linkmode_empty(priv->combo_advertising)) {
-+ linkmode_copy(priv->combo_advertising,
-+ phydev->advertising);
-+ }
-+
-+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_FIBER_SPACE);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* we don't known which will be link, so restore
-+ * phydev->advertising as default value.
-+ */
-+ linkmode_copy(phydev->advertising, priv->combo_advertising);
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_aneg_done_paged() - determines the auto negotiation result of one
-+ * page.
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 0(no link)or 1(fiber or utp link) or negative errno code
-+ */
-+static int yt8521_aneg_done_paged(struct phy_device *phydev, int page)
-+{
-+ int old_page;
-+ int ret = 0;
-+ int link;
-+
-+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ link = !!(ret & YTPHY_SSR_LINK);
-+ ret = link;
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_aneg_done() - determines the auto negotiation result
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0(no link)or 1(fiber or utp link) or negative errno code
-+ */
-+static int yt8521_aneg_done(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int link_fiber = 0;
-+ int link_utp;
-+ int link;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ link = yt8521_aneg_done_paged(phydev, priv->reg_page);
-+ } else {
-+ link_utp = yt8521_aneg_done_paged(phydev,
-+ YT8521_RSSR_UTP_SPACE);
-+ if (link_utp < 0)
-+ return link_utp;
-+
-+ if (!link_utp) {
-+ link_fiber = yt8521_aneg_done_paged(phydev,
-+ YT8521_RSSR_FIBER_SPACE);
-+ if (link_fiber < 0)
-+ return link_fiber;
-+ }
-+ link = link_fiber || link_utp;
-+ phydev_info(phydev, "%s, link_fiber: %d, link_utp: %d\n",
-+ __func__, link_fiber, link_utp);
-+ }
-+
-+ return link;
-+}
-+
-+/**
-+ * ytphy_utp_read_abilities - read PHY abilities from Clause 22 registers
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE: Reads the PHY's abilities and populates
-+ * phydev->supported accordingly.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_read_abilities(struct phy_device *phydev)
-+{
-+ int val;
-+
-+ linkmode_set_bit_array(phy_basic_ports_array,
-+ ARRAY_SIZE(phy_basic_ports_array),
-+ phydev->supported);
-+
-+ val = __phy_read(phydev, MII_BMSR);
-+ if (val < 0)
-+ return val;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported,
-+ val & BMSR_ANEGCAPABLE);
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported,
-+ val & BMSR_100FULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported,
-+ val & BMSR_100HALF);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported,
-+ val & BMSR_10FULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported,
-+ val & BMSR_10HALF);
-+
-+ if (val & BMSR_ESTATEN) {
-+ val = __phy_read(phydev, MII_ESTATUS);
-+ if (val < 0)
-+ return val;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-+ phydev->supported, val & ESTATUS_1000_TFULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-+ phydev->supported, val & ESTATUS_1000_THALF);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-+ phydev->supported, val & ESTATUS_1000_XFULL);
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_get_features_paged() - read supported link modes for one page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_get_features_paged(struct phy_device *phydev, int page)
-+{
-+ int old_page;
-+ int ret = 0;
-+
-+ page &= YT8521_RSSR_SPACE_MASK;
-+ old_page = phy_select_page(phydev, page);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ if (page == YT8521_RSSR_FIBER_SPACE) {
-+ linkmode_zero(phydev->supported);
-+ yt8521_prepare_fiber_features(phydev, phydev->supported);
-+ } else {
-+ ret = ytphy_utp_read_abilities(phydev);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_get_features - switch reg space then call yt8521_get_features_paged
-+ * @phydev: target phy_device struct
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_get_features(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = yt8521_get_features_paged(phydev, priv->reg_page);
-+ } else {
-+ ret = yt8521_get_features_paged(phydev,
-+ YT8521_RSSR_UTP_SPACE);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* add fiber's features to phydev->supported */
-+ yt8521_prepare_fiber_features(phydev, phydev->supported);
-+ }
-+ return ret;
-+}
-+
- static struct phy_driver motorcomm_phy_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(PHY_ID_YT8511),
-@@ -121,16 +1733,35 @@ static struct phy_driver motorcomm_phy_d
- .read_page = yt8511_read_page,
- .write_page = yt8511_write_page,
- },
-+ {
-+ PHY_ID_MATCH_EXACT(PHY_ID_YT8521),
-+ .name = "YT8521 Gigabit Ethernet",
-+ .get_features = yt8521_get_features,
-+ .probe = yt8521_probe,
-+ .read_page = yt8521_read_page,
-+ .write_page = yt8521_write_page,
-+ .get_wol = ytphy_get_wol,
-+ .set_wol = ytphy_set_wol,
-+ .config_aneg = yt8521_config_aneg,
-+ .aneg_done = yt8521_aneg_done,
-+ .config_init = yt8521_config_init,
-+ .read_status = yt8521_read_status,
-+ .soft_reset = yt8521_soft_reset,
-+ .suspend = yt8521_suspend,
-+ .resume = yt8521_resume,
-+ },
- };
-
- module_phy_driver(motorcomm_phy_drvs);
-
--MODULE_DESCRIPTION("Motorcomm PHY driver");
-+MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver");
- MODULE_AUTHOR("Peter Geis");
-+MODULE_AUTHOR("Frank");
- MODULE_LICENSE("GPL");
-
- static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
-+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
- { /* sentinal */ }
- };
-
diff --git a/target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch b/target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch
deleted file mode 100644
index cce71c8d84..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 4e0243e7128c9b25ea2739136076a95d6adaba5e Mon Sep 17 00:00:00 2001
-From: Frank <Frank.Sae@motor-comm.com>
-Date: Fri, 4 Nov 2022 16:44:41 +0800
-Subject: [PATCH] net: phy: fix yt8521 duplicated argument to & or |
-
-cocci warnings: (new ones prefixed by >>)
->> drivers/net/phy/motorcomm.c:1122:8-35: duplicated argument to & or |
- drivers/net/phy/motorcomm.c:1126:8-35: duplicated argument to & or |
- drivers/net/phy/motorcomm.c:1130:8-34: duplicated argument to & or |
- drivers/net/phy/motorcomm.c:1134:8-34: duplicated argument to & or |
-
- The second YT8521_RC1R_GE_TX_DELAY_xx should be YT8521_RC1R_FE_TX_DELAY_xx.
-
-Fixes: 70479a40954c ("net: phy: Add driver for Motorcomm yt8521 gigabit ethernet phy")
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Julia Lawall <julia.lawall@lip6.fr>
-Signed-off-by: Frank <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1119,19 +1119,19 @@ static int yt8521_config_init(struct phy
-
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_RGMII:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
- val |= YT8521_RC1R_RX_DELAY_DIS;
- break;
- case PHY_INTERFACE_MODE_RGMII_RXID:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
- val |= YT8521_RC1R_RX_DELAY_EN;
- break;
- case PHY_INTERFACE_MODE_RGMII_TXID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
- val |= YT8521_RC1R_RX_DELAY_DIS;
- break;
- case PHY_INTERFACE_MODE_RGMII_ID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
- val |= YT8521_RC1R_RX_DELAY_EN;
- break;
- case PHY_INTERFACE_MODE_SGMII:
diff --git a/target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch b/target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch
deleted file mode 100644
index 94d09092cf..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-From 813abcd98fb1b2cccf850cdfa092a4bfc50b2363 Mon Sep 17 00:00:00 2001
-From: Frank <Frank.Sae@motor-comm.com>
-Date: Tue, 22 Nov 2022 16:42:32 +0800
-Subject: [PATCH] net: phy: add Motorcomm YT8531S phy id.
-
-We added patch for motorcomm.c to support YT8531S. This patch has
-been tested on AM335x platform which has one YT8531S interface
-card and passed all test cases.
-The tested cases indluding: YT8531S UTP function with support of
-10M/100M/1000M; YT8531S Fiber function with support of 100M/1000M;
-and YT8531S Combo function that supports auto detection of media type.
-
-Since most functions of YT8531S are similar to YT8521 and we reuse some
-codes for YT8521 in the patch file.
-
-Signed-off-by: Frank <Frank.Sae@motor-comm.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 2 +-
- drivers/net/phy/motorcomm.c | 52 +++++++++++++++++++++++++++++++++----
- 2 files changed, 48 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -242,7 +242,7 @@ config MOTORCOMM_PHY
- tristate "Motorcomm PHYs"
- help
- Enables support for Motorcomm network PHYs.
-- Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs.
-+ Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs.
-
- config NATIONAL_PHY
- tristate "National Semiconductor PHYs"
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0+
- /*
-- * Motorcomm 8511/8521 PHY driver.
-+ * Motorcomm 8511/8521/8531S PHY driver.
- *
- * Author: Peter Geis <pgwipeout@gmail.com>
- * Author: Frank <Frank.Sae@motor-comm.com>
-@@ -12,9 +12,10 @@
- #include <linux/phy.h>
-
- #define PHY_ID_YT8511 0x0000010a
--#define PHY_ID_YT8521 0x0000011A
-+#define PHY_ID_YT8521 0x0000011A
-+#define PHY_ID_YT8531S 0x4F51E91A
-
--/* YT8521 Register Overview
-+/* YT8521/YT8531S Register Overview
- * UTP Register space | FIBER Register space
- * ------------------------------------------------------------
- * | UTP MII | FIBER MII |
-@@ -147,7 +148,7 @@
- #define YT8521_LINK_TIMER_CFG2_REG 0xA5
- #define YT8521_LTCR_EN_AUTOSEN BIT(15)
-
--/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers
-+/* 0xA000, 0xA001, 0xA003, 0xA006 ~ 0xA00A and 0xA012 are common ext registers
- * of yt8521 phy. There is no need to switch reg space when operating these
- * registers.
- */
-@@ -221,6 +222,9 @@
- */
- #define YTPHY_WCR_TYPE_PULSE BIT(0)
-
-+#define YT8531S_SYNCE_CFG_REG 0xA012
-+#define YT8531S_SCR_SYNCE_ENABLE BIT(6)
-+
- /* Extended Register end */
-
- struct yt8521_priv {
-@@ -648,6 +652,26 @@ static int yt8521_probe(struct phy_devic
- }
-
- /**
-+ * yt8531s_probe() - read chip config then set suitable polling_mode
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8531s_probe(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Disable SyncE clock output by default */
-+ ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG,
-+ YT8531S_SCR_SYNCE_ENABLE, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* same as yt8521_probe */
-+ return yt8521_probe(phydev);
-+}
-+
-+/**
- * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -1750,11 +1774,28 @@ static struct phy_driver motorcomm_phy_d
- .suspend = yt8521_suspend,
- .resume = yt8521_resume,
- },
-+ {
-+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S),
-+ .name = "YT8531S Gigabit Ethernet",
-+ .get_features = yt8521_get_features,
-+ .probe = yt8531s_probe,
-+ .read_page = yt8521_read_page,
-+ .write_page = yt8521_write_page,
-+ .get_wol = ytphy_get_wol,
-+ .set_wol = ytphy_set_wol,
-+ .config_aneg = yt8521_config_aneg,
-+ .aneg_done = yt8521_aneg_done,
-+ .config_init = yt8521_config_init,
-+ .read_status = yt8521_read_status,
-+ .soft_reset = yt8521_soft_reset,
-+ .suspend = yt8521_suspend,
-+ .resume = yt8521_resume,
-+ },
- };
-
- module_phy_driver(motorcomm_phy_drvs);
-
--MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver");
-+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver");
- MODULE_AUTHOR("Peter Geis");
- MODULE_AUTHOR("Frank");
- MODULE_LICENSE("GPL");
-@@ -1762,6 +1803,7 @@ MODULE_LICENSE("GPL");
- static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
-+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
- { /* sentinal */ }
- };
-
diff --git a/target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch b/target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch
deleted file mode 100644
index 94fc32aadb..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 4104a713204d62aca482eebb0c6226d82a0721eb Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Sat, 28 Jan 2023 14:35:57 +0800
-Subject: [PATCH] net: phy: fix the spelling problem of Sentinel
-
-CHECK: 'sentinal' may be misspelled - perhaps 'sentinel'?
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20230128063558.5850-1-Frank.Sae@motor-comm.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/motorcomm.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1804,7 +1804,7 @@ static const struct mdio_device_id __may
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
-- { /* sentinal */ }
-+ { /* sentinel */ }
- };
-
- MODULE_DEVICE_TABLE(mdio, motorcomm_tbl);
diff --git a/target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch b/target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch
deleted file mode 100644
index 076fa82d26..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 3c1dc22162d673d595855d24f95200ed2643f88f Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Sat, 28 Jan 2023 14:35:58 +0800
-Subject: [PATCH] net: phy: motorcomm: change the phy id of yt8521 and yt8531s
- to lowercase
-
-The phy id is usually defined in lower case.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20230128063558.5850-2-Frank.Sae@motor-comm.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/motorcomm.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -12,8 +12,8 @@
- #include <linux/phy.h>
-
- #define PHY_ID_YT8511 0x0000010a
--#define PHY_ID_YT8521 0x0000011A
--#define PHY_ID_YT8531S 0x4F51E91A
-+#define PHY_ID_YT8521 0x0000011a
-+#define PHY_ID_YT8531S 0x4f51e91a
-
- /* YT8521/YT8531S Register Overview
- * UTP Register space | FIBER Register space
diff --git a/target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch b/target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch
deleted file mode 100644
index ba9a6ab4cc..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 4869a146cd60fc8115230f0a45e15e534c531922 Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:34 +0800
-Subject: [PATCH] net: phy: Add BIT macro for Motorcomm yt8521/yt8531 gigabit
- ethernet phy
-
-Add BIT macro for Motorcomm yt8521/yt8531 gigabit ethernet phy.
- This is a preparatory patch. Add BIT macro for 0xA012 reg, and
- supplement for 0xA001 and 0xA003 reg. These will be used to support dts.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 55 ++++++++++++++++++++++++++++++++++---
- 1 file changed, 51 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -161,6 +161,11 @@
-
- #define YT8521_CHIP_CONFIG_REG 0xA001
- #define YT8521_CCR_SW_RST BIT(15)
-+/* 1b0 disable 1.9ns rxc clock delay *default*
-+ * 1b1 enable 1.9ns rxc clock delay
-+ */
-+#define YT8521_CCR_RXC_DLY_EN BIT(8)
-+#define YT8521_CCR_RXC_DLY_1_900_NS 1900
-
- #define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0))
- #define YT8521_CCR_MODE_UTP_TO_RGMII 0
-@@ -178,22 +183,41 @@
- #define YT8521_MODE_POLL 0x3
-
- #define YT8521_RGMII_CONFIG1_REG 0xA003
--
-+/* 1b0 use original tx_clk_rgmii *default*
-+ * 1b1 use inverted tx_clk_rgmii.
-+ */
-+#define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14)
- /* TX Gig-E Delay is bits 3:0, default 0x1
- * TX Fast-E Delay is bits 7:4, default 0xf
- * RX Delay is bits 13:10, default 0x0
- * Delay = 150ps * N
- * On = 2250ps, off = 0ps
- */
--#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10)
-+#define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10)
- #define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
- #define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
--#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4)
-+#define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
- #define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
- #define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
--#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0)
-+#define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
- #define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
- #define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
-+#define YT8521_RC1R_RGMII_0_000_NS 0
-+#define YT8521_RC1R_RGMII_0_150_NS 1
-+#define YT8521_RC1R_RGMII_0_300_NS 2
-+#define YT8521_RC1R_RGMII_0_450_NS 3
-+#define YT8521_RC1R_RGMII_0_600_NS 4
-+#define YT8521_RC1R_RGMII_0_750_NS 5
-+#define YT8521_RC1R_RGMII_0_900_NS 6
-+#define YT8521_RC1R_RGMII_1_050_NS 7
-+#define YT8521_RC1R_RGMII_1_200_NS 8
-+#define YT8521_RC1R_RGMII_1_350_NS 9
-+#define YT8521_RC1R_RGMII_1_500_NS 10
-+#define YT8521_RC1R_RGMII_1_650_NS 11
-+#define YT8521_RC1R_RGMII_1_800_NS 12
-+#define YT8521_RC1R_RGMII_1_950_NS 13
-+#define YT8521_RC1R_RGMII_2_100_NS 14
-+#define YT8521_RC1R_RGMII_2_250_NS 15
-
- #define YTPHY_MISC_CONFIG_REG 0xA006
- #define YTPHY_MCR_FIBER_SPEED_MASK BIT(0)
-@@ -222,6 +246,29 @@
- */
- #define YTPHY_WCR_TYPE_PULSE BIT(0)
-
-+#define YTPHY_SYNCE_CFG_REG 0xA012
-+#define YT8521_SCR_SYNCE_ENABLE BIT(5)
-+/* 1b0 output 25m clock
-+ * 1b1 output 125m clock *default*
-+ */
-+#define YT8521_SCR_CLK_FRE_SEL_125M BIT(3)
-+#define YT8521_SCR_CLK_SRC_MASK GENMASK(2, 1)
-+#define YT8521_SCR_CLK_SRC_PLL_125M 0
-+#define YT8521_SCR_CLK_SRC_UTP_RX 1
-+#define YT8521_SCR_CLK_SRC_SDS_RX 2
-+#define YT8521_SCR_CLK_SRC_REF_25M 3
-+#define YT8531_SCR_SYNCE_ENABLE BIT(6)
-+/* 1b0 output 25m clock *default*
-+ * 1b1 output 125m clock
-+ */
-+#define YT8531_SCR_CLK_FRE_SEL_125M BIT(4)
-+#define YT8531_SCR_CLK_SRC_MASK GENMASK(3, 1)
-+#define YT8531_SCR_CLK_SRC_PLL_125M 0
-+#define YT8531_SCR_CLK_SRC_UTP_RX 1
-+#define YT8531_SCR_CLK_SRC_SDS_RX 2
-+#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
-+#define YT8531_SCR_CLK_SRC_REF_25M 4
-+#define YT8531_SCR_CLK_SRC_SSC_25M 5
- #define YT8531S_SYNCE_CFG_REG 0xA012
- #define YT8531S_SCR_SYNCE_ENABLE BIT(6)
-
diff --git a/target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch b/target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch
deleted file mode 100644
index 6d89fae84c..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch
+++ /dev/null
@@ -1,343 +0,0 @@
-From a6e68f0f8769f79c67cdcfb6302feecd36197dec Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:35 +0800
-Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8521 gigabit
- ethernet phy
-
-Add dts support for Motorcomm yt8521 gigabit ethernet phy.
- Add ytphy_rgmii_clk_delay_config function to support dst config for
- the delay of rgmii clk. This funciont is common for yt8521, yt8531s
- and yt8531.
- This patch has been verified on AM335x platform.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 253 ++++++++++++++++++++++++++++--------
- 1 file changed, 199 insertions(+), 54 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -10,6 +10,7 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/phy.h>
-+#include <linux/of.h>
-
- #define PHY_ID_YT8511 0x0000010a
- #define PHY_ID_YT8521 0x0000011a
-@@ -187,21 +188,9 @@
- * 1b1 use inverted tx_clk_rgmii.
- */
- #define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14)
--/* TX Gig-E Delay is bits 3:0, default 0x1
-- * TX Fast-E Delay is bits 7:4, default 0xf
-- * RX Delay is bits 13:10, default 0x0
-- * Delay = 150ps * N
-- * On = 2250ps, off = 0ps
-- */
- #define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10)
--#define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
--#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
- #define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
--#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
--#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
- #define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
--#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
--#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
- #define YT8521_RC1R_RGMII_0_000_NS 0
- #define YT8521_RC1R_RGMII_0_150_NS 1
- #define YT8521_RC1R_RGMII_0_300_NS 2
-@@ -274,6 +263,10 @@
-
- /* Extended Register end */
-
-+#define YTPHY_DTS_OUTPUT_CLK_DIS 0
-+#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
-+#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
-+
- struct yt8521_priv {
- /* combo_advertising is used for case of YT8521 in combo mode,
- * this means that yt8521 may work in utp or fiber mode which depends
-@@ -641,6 +634,142 @@ static int yt8521_write_page(struct phy_
- };
-
- /**
-+ * struct ytphy_cfg_reg_map - map a config value to a register value
-+ * @cfg: value in device configuration
-+ * @reg: value in the register
-+ */
-+struct ytphy_cfg_reg_map {
-+ u32 cfg;
-+ u32 reg;
-+};
-+
-+static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
-+ /* for tx delay / rx delay with YT8521_CCR_RXC_DLY_EN is not set. */
-+ { 0, YT8521_RC1R_RGMII_0_000_NS },
-+ { 150, YT8521_RC1R_RGMII_0_150_NS },
-+ { 300, YT8521_RC1R_RGMII_0_300_NS },
-+ { 450, YT8521_RC1R_RGMII_0_450_NS },
-+ { 600, YT8521_RC1R_RGMII_0_600_NS },
-+ { 750, YT8521_RC1R_RGMII_0_750_NS },
-+ { 900, YT8521_RC1R_RGMII_0_900_NS },
-+ { 1050, YT8521_RC1R_RGMII_1_050_NS },
-+ { 1200, YT8521_RC1R_RGMII_1_200_NS },
-+ { 1350, YT8521_RC1R_RGMII_1_350_NS },
-+ { 1500, YT8521_RC1R_RGMII_1_500_NS },
-+ { 1650, YT8521_RC1R_RGMII_1_650_NS },
-+ { 1800, YT8521_RC1R_RGMII_1_800_NS },
-+ { 1950, YT8521_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */
-+ { 2100, YT8521_RC1R_RGMII_2_100_NS },
-+ { 2250, YT8521_RC1R_RGMII_2_250_NS },
-+
-+ /* only for rx delay with YT8521_CCR_RXC_DLY_EN is set. */
-+ { 0 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_000_NS },
-+ { 150 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_150_NS },
-+ { 300 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_300_NS },
-+ { 450 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_450_NS },
-+ { 600 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_600_NS },
-+ { 750 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_750_NS },
-+ { 900 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_900_NS },
-+ { 1050 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_050_NS },
-+ { 1200 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_200_NS },
-+ { 1350 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_350_NS },
-+ { 1500 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_500_NS },
-+ { 1650 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_650_NS },
-+ { 1800 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_800_NS },
-+ { 1950 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_950_NS },
-+ { 2100 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_100_NS },
-+ { 2250 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_250_NS }
-+};
-+
-+static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
-+ const char *prop_name,
-+ const struct ytphy_cfg_reg_map *tbl,
-+ int tb_size,
-+ u16 *rxc_dly_en,
-+ u32 dflt)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ int tb_size_half = tb_size / 2;
-+ u32 val;
-+ int i;
-+
-+ if (of_property_read_u32(node, prop_name, &val))
-+ goto err_dts_val;
-+
-+ /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
-+ * tb_size is valid.
-+ */
-+ if (!rxc_dly_en)
-+ tb_size = tb_size_half;
-+
-+ for (i = 0; i < tb_size; i++) {
-+ if (tbl[i].cfg == val) {
-+ if (rxc_dly_en && i < tb_size_half)
-+ *rxc_dly_en = 0;
-+ return tbl[i].reg;
-+ }
-+ }
-+
-+ phydev_warn(phydev, "Unsupported value %d for %s using default (%u)\n",
-+ val, prop_name, dflt);
-+
-+err_dts_val:
-+ /* when rxc_dly_en is not NULL, it is get the delay for rx.
-+ * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
-+ * so YT8521_CCR_RXC_DLY_EN should not be set.
-+ */
-+ if (rxc_dly_en)
-+ *rxc_dly_en = 0;
-+
-+ return dflt;
-+}
-+
-+static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
-+{
-+ int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
-+ u16 rxc_dly_en = YT8521_CCR_RXC_DLY_EN;
-+ u32 rx_reg, tx_reg;
-+ u16 mask, val = 0;
-+ int ret;
-+
-+ rx_reg = ytphy_get_delay_reg_value(phydev, "rx-internal-delay-ps",
-+ ytphy_rgmii_delays, tb_size,
-+ &rxc_dly_en,
-+ YT8521_RC1R_RGMII_1_950_NS);
-+ tx_reg = ytphy_get_delay_reg_value(phydev, "tx-internal-delay-ps",
-+ ytphy_rgmii_delays, tb_size, NULL,
-+ YT8521_RC1R_RGMII_1_950_NS);
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ rxc_dly_en = 0;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg);
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ rxc_dly_en = 0;
-+ val |= FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
-+ FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
-+ break;
-+ default: /* do not support other modes */
-+ return -EOPNOTSUPP;
-+ }
-+
-+ ret = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
-+ YT8521_CCR_RXC_DLY_EN, rxc_dly_en);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Generally, it is not necessary to adjust YT8521_RC1R_FE_TX_DELAY */
-+ mask = YT8521_RC1R_RX_DELAY_MASK | YT8521_RC1R_GE_TX_DELAY_MASK;
-+ return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val);
-+}
-+
-+/**
- * yt8521_probe() - read chip config then set suitable polling_mode
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -648,9 +777,12 @@ static int yt8521_write_page(struct phy_
- */
- static int yt8521_probe(struct phy_device *phydev)
- {
-+ struct device_node *node = phydev->mdio.dev.of_node;
- struct device *dev = &phydev->mdio.dev;
- struct yt8521_priv *priv;
- int chip_config;
-+ u16 mask, val;
-+ u32 freq;
- int ret;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-@@ -695,7 +827,45 @@ static int yt8521_probe(struct phy_devic
- return ret;
- }
-
-- return 0;
-+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq))
-+ freq = YTPHY_DTS_OUTPUT_CLK_DIS;
-+
-+ if (phydev->drv->phy_id == PHY_ID_YT8521) {
-+ switch (freq) {
-+ case YTPHY_DTS_OUTPUT_CLK_DIS:
-+ mask = YT8521_SCR_SYNCE_ENABLE;
-+ val = 0;
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_25M:
-+ mask = YT8521_SCR_SYNCE_ENABLE |
-+ YT8521_SCR_CLK_SRC_MASK |
-+ YT8521_SCR_CLK_FRE_SEL_125M;
-+ val = YT8521_SCR_SYNCE_ENABLE |
-+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK,
-+ YT8521_SCR_CLK_SRC_REF_25M);
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_125M:
-+ mask = YT8521_SCR_SYNCE_ENABLE |
-+ YT8521_SCR_CLK_SRC_MASK |
-+ YT8521_SCR_CLK_FRE_SEL_125M;
-+ val = YT8521_SCR_SYNCE_ENABLE |
-+ YT8521_SCR_CLK_FRE_SEL_125M |
-+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK,
-+ YT8521_SCR_CLK_SRC_PLL_125M);
-+ break;
-+ default:
-+ phydev_warn(phydev, "Freq err:%u\n", freq);
-+ return -EINVAL;
-+ }
-+ } else if (phydev->drv->phy_id == PHY_ID_YT8531S) {
-+ return 0;
-+ } else {
-+ phydev_warn(phydev, "PHY id err\n");
-+ return -EINVAL;
-+ }
-+
-+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask,
-+ val);
- }
-
- /**
-@@ -1180,61 +1350,36 @@ static int yt8521_resume(struct phy_devi
- */
- static int yt8521_config_init(struct phy_device *phydev)
- {
-+ struct device_node *node = phydev->mdio.dev.of_node;
- int old_page;
- int ret = 0;
-- u16 val;
-
- old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
- if (old_page < 0)
- goto err_restore_page;
-
-- switch (phydev->interface) {
-- case PHY_INTERFACE_MODE_RGMII:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
-- val |= YT8521_RC1R_RX_DELAY_DIS;
-- break;
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
-- val |= YT8521_RC1R_RX_DELAY_EN;
-- break;
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
-- val |= YT8521_RC1R_RX_DELAY_DIS;
-- break;
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
-- val |= YT8521_RC1R_RX_DELAY_EN;
-- break;
-- case PHY_INTERFACE_MODE_SGMII:
-- break;
-- default: /* do not support other modes */
-- ret = -EOPNOTSUPP;
-- goto err_restore_page;
-- }
--
- /* set rgmii delay mode */
- if (phydev->interface != PHY_INTERFACE_MODE_SGMII) {
-- ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG,
-- (YT8521_RC1R_RX_DELAY_MASK |
-- YT8521_RC1R_FE_TX_DELAY_MASK |
-- YT8521_RC1R_GE_TX_DELAY_MASK),
-- val);
-+ ret = ytphy_rgmii_clk_delay_config(phydev);
- if (ret < 0)
- goto err_restore_page;
- }
-
-- /* disable auto sleep */
-- ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
-- YT8521_ESC1R_SLEEP_SW, 0);
-- if (ret < 0)
-- goto err_restore_page;
--
-- /* enable RXC clock when no wire plug */
-- ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
-- YT8521_CGR_RX_CLK_EN, 0);
-- if (ret < 0)
-- goto err_restore_page;
-+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) {
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-
-+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) {
-+ /* enable RXC clock when no wire plug */
-+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
-+ YT8521_CGR_RX_CLK_EN, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
- err_restore_page:
- return phy_restore_page(phydev, old_page, ret);
- }
diff --git a/target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch b/target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch
deleted file mode 100644
index 86fc04695c..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 36152f87dda4af221b16258751451d9cd3d0fb0b Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:36 +0800
-Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8531s gigabit
- ethernet phy
-
-Add dts support for Motorcomm yt8531s gigabit ethernet phy.
- Change yt8521_probe to support clk config of yt8531s. Becase
- yt8521_probe does the things which yt8531s is needed, so
- removed yt8531s function.
- This patch has been verified on AM335x platform with yt8531s board.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 51 ++++++++++++++++++++-----------------
- 1 file changed, 27 insertions(+), 24 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -258,8 +258,6 @@
- #define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
- #define YT8531_SCR_CLK_SRC_REF_25M 4
- #define YT8531_SCR_CLK_SRC_SSC_25M 5
--#define YT8531S_SYNCE_CFG_REG 0xA012
--#define YT8531S_SCR_SYNCE_ENABLE BIT(6)
-
- /* Extended Register end */
-
-@@ -858,7 +856,32 @@ static int yt8521_probe(struct phy_devic
- return -EINVAL;
- }
- } else if (phydev->drv->phy_id == PHY_ID_YT8531S) {
-- return 0;
-+ switch (freq) {
-+ case YTPHY_DTS_OUTPUT_CLK_DIS:
-+ mask = YT8531_SCR_SYNCE_ENABLE;
-+ val = 0;
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_25M:
-+ mask = YT8531_SCR_SYNCE_ENABLE |
-+ YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_REF_25M);
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_125M:
-+ mask = YT8531_SCR_SYNCE_ENABLE |
-+ YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE |
-+ YT8531_SCR_CLK_FRE_SEL_125M |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_PLL_125M);
-+ break;
-+ default:
-+ phydev_warn(phydev, "Freq err:%u\n", freq);
-+ return -EINVAL;
-+ }
- } else {
- phydev_warn(phydev, "PHY id err\n");
- return -EINVAL;
-@@ -869,26 +892,6 @@ static int yt8521_probe(struct phy_devic
- }
-
- /**
-- * yt8531s_probe() - read chip config then set suitable polling_mode
-- * @phydev: a pointer to a &struct phy_device
-- *
-- * returns 0 or negative errno code
-- */
--static int yt8531s_probe(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Disable SyncE clock output by default */
-- ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG,
-- YT8531S_SCR_SYNCE_ENABLE, 0);
-- if (ret < 0)
-- return ret;
--
-- /* same as yt8521_probe */
-- return yt8521_probe(phydev);
--}
--
--/**
- * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -1970,7 +1973,7 @@ static struct phy_driver motorcomm_phy_d
- PHY_ID_MATCH_EXACT(PHY_ID_YT8531S),
- .name = "YT8531S Gigabit Ethernet",
- .get_features = yt8521_get_features,
-- .probe = yt8531s_probe,
-+ .probe = yt8521_probe,
- .read_page = yt8521_read_page,
- .write_page = yt8521_write_page,
- .get_wol = ytphy_get_wol,
diff --git a/target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch b/target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch
deleted file mode 100644
index a8b9e3d13b..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch
+++ /dev/null
@@ -1,302 +0,0 @@
-From 4ac94f728a588e7096dd5010cd7141a309ea7805 Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:37 +0800
-Subject: [PATCH] net: phy: Add driver for Motorcomm yt8531 gigabit ethernet
- phy
-
-Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have
- verified the driver on AM335x platform with yt8531 board. On the
- board, yt8531 gigabit ethernet phy works in utp mode, RGMII
- interface, supports 1000M/100M/10M speeds, and wol(magic package).
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 2 +-
- drivers/net/phy/motorcomm.c | 208 +++++++++++++++++++++++++++++++++++-
- 2 files changed, 207 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -242,7 +242,7 @@ config MOTORCOMM_PHY
- tristate "Motorcomm PHYs"
- help
- Enables support for Motorcomm network PHYs.
-- Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs.
-+ Currently supports YT85xx Gigabit Ethernet PHYs.
-
- config NATIONAL_PHY
- tristate "National Semiconductor PHYs"
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0+
- /*
-- * Motorcomm 8511/8521/8531S PHY driver.
-+ * Motorcomm 8511/8521/8531/8531S PHY driver.
- *
- * Author: Peter Geis <pgwipeout@gmail.com>
- * Author: Frank <Frank.Sae@motor-comm.com>
-@@ -14,6 +14,7 @@
-
- #define PHY_ID_YT8511 0x0000010a
- #define PHY_ID_YT8521 0x0000011a
-+#define PHY_ID_YT8531 0x4f51e91b
- #define PHY_ID_YT8531S 0x4f51e91a
-
- /* YT8521/YT8531S Register Overview
-@@ -517,6 +518,61 @@ err_restore_page:
- return phy_restore_page(phydev, old_page, ret);
- }
-
-+static int yt8531_set_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ const u16 mac_addr_reg[] = {
-+ YTPHY_WOL_MACADDR2_REG,
-+ YTPHY_WOL_MACADDR1_REG,
-+ YTPHY_WOL_MACADDR0_REG,
-+ };
-+ const u8 *mac_addr;
-+ u16 mask, val;
-+ int ret;
-+ u8 i;
-+
-+ if (wol->wolopts & WAKE_MAGIC) {
-+ mac_addr = phydev->attached_dev->dev_addr;
-+
-+ /* Store the device address for the magic packet */
-+ for (i = 0; i < 3; i++) {
-+ ret = ytphy_write_ext_with_lock(phydev, mac_addr_reg[i],
-+ ((mac_addr[i * 2] << 8)) |
-+ (mac_addr[i * 2 + 1]));
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ /* Enable WOL feature */
-+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL;
-+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS;
-+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG,
-+ mask, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Enable WOL interrupt */
-+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0,
-+ YTPHY_IER_WOL);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ /* Disable WOL feature */
-+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG,
-+ mask, 0);
-+
-+ /* Disable WOL interrupt */
-+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG,
-+ YTPHY_IER_WOL, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int yt8511_read_page(struct phy_device *phydev)
- {
- return __phy_read(phydev, YT8511_PAGE_SELECT);
-@@ -767,6 +823,17 @@ static int ytphy_rgmii_clk_delay_config(
- return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val);
- }
-
-+static int ytphy_rgmii_clk_delay_config_with_lock(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_rgmii_clk_delay_config(phydev);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
- /**
- * yt8521_probe() - read chip config then set suitable polling_mode
- * @phydev: a pointer to a &struct phy_device
-@@ -891,6 +958,43 @@ static int yt8521_probe(struct phy_devic
- val);
- }
-
-+static int yt8531_probe(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ u16 mask, val;
-+ u32 freq;
-+
-+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq))
-+ freq = YTPHY_DTS_OUTPUT_CLK_DIS;
-+
-+ switch (freq) {
-+ case YTPHY_DTS_OUTPUT_CLK_DIS:
-+ mask = YT8531_SCR_SYNCE_ENABLE;
-+ val = 0;
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_25M:
-+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_REF_25M);
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_125M:
-+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_PLL_125M);
-+ break;
-+ default:
-+ phydev_warn(phydev, "Freq err:%u\n", freq);
-+ return -EINVAL;
-+ }
-+
-+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask,
-+ val);
-+}
-+
- /**
- * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
- * @phydev: a pointer to a &struct phy_device
-@@ -1387,6 +1491,94 @@ err_restore_page:
- return phy_restore_page(phydev, old_page, ret);
- }
-
-+static int yt8531_config_init(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ int ret;
-+
-+ ret = ytphy_rgmii_clk_delay_config_with_lock(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) {
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) {
-+ /* enable RXC clock when no wire plug */
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YT8521_CLOCK_GATING_REG,
-+ YT8521_CGR_RX_CLK_EN, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8531_link_change_notify() - Adjust the tx clock direction according to
-+ * the current speed and dts config.
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * NOTE: This function is only used to adapt to VF2 with JH7110 SoC. Please
-+ * keep "motorcomm,tx-clk-adj-enabled" not exist in dts when the soc is not
-+ * JH7110.
-+ */
-+static void yt8531_link_change_notify(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ bool tx_clk_adj_enabled = false;
-+ bool tx_clk_1000_inverted;
-+ bool tx_clk_100_inverted;
-+ bool tx_clk_10_inverted;
-+ u16 val = 0;
-+ int ret;
-+
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-adj-enabled"))
-+ tx_clk_adj_enabled = true;
-+
-+ if (!tx_clk_adj_enabled)
-+ return;
-+
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-10-inverted"))
-+ tx_clk_10_inverted = true;
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-100-inverted"))
-+ tx_clk_100_inverted = true;
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-1000-inverted"))
-+ tx_clk_1000_inverted = true;
-+
-+ if (phydev->speed < 0)
-+ return;
-+
-+ switch (phydev->speed) {
-+ case SPEED_1000:
-+ if (tx_clk_1000_inverted)
-+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED;
-+ break;
-+ case SPEED_100:
-+ if (tx_clk_100_inverted)
-+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED;
-+ break;
-+ case SPEED_10:
-+ if (tx_clk_10_inverted)
-+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED;
-+ break;
-+ default:
-+ return;
-+ }
-+
-+ ret = ytphy_modify_ext_with_lock(phydev, YT8521_RGMII_CONFIG1_REG,
-+ YT8521_RC1R_TX_CLK_SEL_INVERTED, val);
-+ if (ret < 0)
-+ phydev_warn(phydev, "Modify TX_CLK_SEL err:%d\n", ret);
-+}
-+
- /**
- * yt8521_prepare_fiber_features() - A small helper function that setup
- * fiber's features.
-@@ -1970,6 +2162,17 @@ static struct phy_driver motorcomm_phy_d
- .resume = yt8521_resume,
- },
- {
-+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531),
-+ .name = "YT8531 Gigabit Ethernet",
-+ .probe = yt8531_probe,
-+ .config_init = yt8531_config_init,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
-+ .get_wol = ytphy_get_wol,
-+ .set_wol = yt8531_set_wol,
-+ .link_change_notify = yt8531_link_change_notify,
-+ },
-+ {
- PHY_ID_MATCH_EXACT(PHY_ID_YT8531S),
- .name = "YT8531S Gigabit Ethernet",
- .get_features = yt8521_get_features,
-@@ -1990,7 +2193,7 @@ static struct phy_driver motorcomm_phy_d
-
- module_phy_driver(motorcomm_phy_drvs);
-
--MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver");
-+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531/8531S PHY driver");
- MODULE_AUTHOR("Peter Geis");
- MODULE_AUTHOR("Frank");
- MODULE_LICENSE("GPL");
-@@ -1998,6 +2201,7 @@ MODULE_LICENSE("GPL");
- static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
-+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
- { /* sentinel */ }
- };
diff --git a/target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch b/target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch
deleted file mode 100644
index 29ae86dbbc..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 9753613f7399601f9bae6ee81e9d4274246c98ab Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <error27@gmail.com>
-Date: Wed, 15 Feb 2023 07:21:47 +0300
-Subject: [PATCH] net: phy: motorcomm: uninitialized variables in
- yt8531_link_change_notify()
-
-These booleans are never set to false, but are just used without being
-initialized.
-
-Fixes: 4ac94f728a58 ("net: phy: Add driver for Motorcomm yt8531 gigabit ethernet phy")
-Signed-off-by: Dan Carpenter <error27@gmail.com>
-Reviewed-by: Frank Sae <Frank.Sae@motor-comm.com>
-Link: https://lore.kernel.org/r/Y+xd2yJet2ImHLoQ@kili
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/motorcomm.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1533,10 +1533,10 @@ static int yt8531_config_init(struct phy
- static void yt8531_link_change_notify(struct phy_device *phydev)
- {
- struct device_node *node = phydev->mdio.dev.of_node;
-+ bool tx_clk_1000_inverted = false;
-+ bool tx_clk_100_inverted = false;
-+ bool tx_clk_10_inverted = false;
- bool tx_clk_adj_enabled = false;
-- bool tx_clk_1000_inverted;
-- bool tx_clk_100_inverted;
-- bool tx_clk_10_inverted;
- u16 val = 0;
- int ret;
-
diff --git a/target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch b/target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch
deleted file mode 100644
index 010ca9b68a..0000000000
--- a/target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-From 7a561e9351ae7e3fb1f08584d40b49c1e55dde60 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Thu, 20 Jul 2023 19:15:09 +0800
-Subject: [PATCH] net: phy: motorcomm: Add pad drive strength cfg support
-
-The motorcomm phy (YT8531) supports the ability to adjust the drive
-strength of the rx_clk/rx_data, and the default strength may not be
-suitable for all boards. So add configurable options to better match
-the boards.(e.g. StarFive VisionFive 2)
-
-When we configure the drive strength, we need to read the current
-LDO voltage value to ensure that it is a legal value at that LDO
-voltage.
-
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 118 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 118 insertions(+)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -163,6 +163,10 @@
-
- #define YT8521_CHIP_CONFIG_REG 0xA001
- #define YT8521_CCR_SW_RST BIT(15)
-+#define YT8531_RGMII_LDO_VOL_MASK GENMASK(5, 4)
-+#define YT8531_LDO_VOL_3V3 0x0
-+#define YT8531_LDO_VOL_1V8 0x2
-+
- /* 1b0 disable 1.9ns rxc clock delay *default*
- * 1b1 enable 1.9ns rxc clock delay
- */
-@@ -236,6 +240,12 @@
- */
- #define YTPHY_WCR_TYPE_PULSE BIT(0)
-
-+#define YTPHY_PAD_DRIVE_STRENGTH_REG 0xA010
-+#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13)
-+#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */
-+#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
-+#define YT8531_RGMII_RX_DS_DEFAULT 0x3
-+
- #define YTPHY_SYNCE_CFG_REG 0xA012
- #define YT8521_SCR_SYNCE_ENABLE BIT(5)
- /* 1b0 output 25m clock
-@@ -835,6 +845,110 @@ static int ytphy_rgmii_clk_delay_config_
- }
-
- /**
-+ * struct ytphy_ldo_vol_map - map a current value to a register value
-+ * @vol: ldo voltage
-+ * @ds: value in the register
-+ * @cur: value in device configuration
-+ */
-+struct ytphy_ldo_vol_map {
-+ u32 vol;
-+ u32 ds;
-+ u32 cur;
-+};
-+
-+static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 0, .cur = 1200},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 1, .cur = 2100},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 2, .cur = 2700},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 3, .cur = 2910},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 4, .cur = 3110},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 5, .cur = 3600},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 6, .cur = 3970},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 7, .cur = 4350},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 0, .cur = 3070},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 1, .cur = 4080},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 2, .cur = 4370},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 3, .cur = 4680},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 4, .cur = 5020},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 5, .cur = 5450},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 6, .cur = 5740},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 7, .cur = 6140},
-+};
-+
-+static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
-+{
-+ u32 val;
-+
-+ val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
-+ val = FIELD_GET(YT8531_RGMII_LDO_VOL_MASK, val);
-+
-+ return val <= YT8531_LDO_VOL_1V8 ? val : YT8531_LDO_VOL_1V8;
-+}
-+
-+static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
-+{
-+ u32 vol;
-+ int i;
-+
-+ vol = yt8531_get_ldo_vol(phydev);
-+ for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
-+ if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
-+ return yt8531_ldo_vol[i].ds;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int yt8531_set_ds(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ u32 ds_field_low, ds_field_hi, val;
-+ int ret, ds;
-+
-+ /* set rgmii rx clk driver strength */
-+ if (!of_property_read_u32(node, "motorcomm,rx-clk-drv-microamp", &val)) {
-+ ds = yt8531_get_ds_map(phydev, val);
-+ if (ds < 0)
-+ return dev_err_probe(&phydev->mdio.dev, ds,
-+ "No matching current value was found.\n");
-+ } else {
-+ ds = YT8531_RGMII_RX_DS_DEFAULT;
-+ }
-+
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YTPHY_PAD_DRIVE_STRENGTH_REG,
-+ YT8531_RGMII_RXC_DS_MASK,
-+ FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
-+ if (ret < 0)
-+ return ret;
-+
-+ /* set rgmii rx data driver strength */
-+ if (!of_property_read_u32(node, "motorcomm,rx-data-drv-microamp", &val)) {
-+ ds = yt8531_get_ds_map(phydev, val);
-+ if (ds < 0)
-+ return dev_err_probe(&phydev->mdio.dev, ds,
-+ "No matching current value was found.\n");
-+ } else {
-+ ds = YT8531_RGMII_RX_DS_DEFAULT;
-+ }
-+
-+ ds_field_hi = FIELD_GET(BIT(2), ds);
-+ ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
-+
-+ ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
-+ ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
-+
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YTPHY_PAD_DRIVE_STRENGTH_REG,
-+ YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
-+ ds_field_low | ds_field_hi);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+/**
- * yt8521_probe() - read chip config then set suitable polling_mode
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -1518,6 +1632,10 @@ static int yt8531_config_init(struct phy
- return ret;
- }
-
-+ ret = yt8531_set_ds(phydev);
-+ if (ret < 0)
-+ return ret;
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch b/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch
deleted file mode 100644
index a0cb367ba7..0000000000
--- a/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From bfac8c490d605bea03b1f1927582b6f396462164 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 27 Jun 2022 12:44:43 +0100
-Subject: [PATCH] net: phylink: disable PCS polling over major configuration
-
-While we are performing a major configuration, there is no point having
-the PCS polling timer running. Stop it before we begin preparing for
-the configuration change, and restart it only once we've successfully
-completed the change.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 30 ++++++++++++++++++++----------
- 1 file changed, 20 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -759,6 +759,18 @@ static void phylink_resolve_flow(struct
- }
- }
-
-+static void phylink_pcs_poll_stop(struct phylink *pl)
-+{
-+ if (pl->cfg_link_an_mode == MLO_AN_INBAND)
-+ del_timer(&pl->link_poll);
-+}
-+
-+static void phylink_pcs_poll_start(struct phylink *pl)
-+{
-+ if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
-+ mod_timer(&pl->link_poll, jiffies + HZ);
-+}
-+
- static void phylink_mac_config(struct phylink *pl,
- const struct phylink_link_state *state)
- {
-@@ -790,6 +802,7 @@ static void phylink_major_config(struct
- const struct phylink_link_state *state)
- {
- struct phylink_pcs *pcs = NULL;
-+ bool pcs_changed = false;
- int err;
-
- phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
-@@ -802,8 +815,12 @@ static void phylink_major_config(struct
- pcs);
- return;
- }
-+
-+ pcs_changed = pcs && pl->pcs != pcs;
- }
-
-+ phylink_pcs_poll_stop(pl);
-+
- if (pl->mac_ops->mac_prepare) {
- err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
- state->interface);
-@@ -817,8 +834,10 @@ static void phylink_major_config(struct
- /* If we have a new PCS, switch to the new PCS after preparing the MAC
- * for the change.
- */
-- if (pcs)
-- phylink_set_pcs(pl, pcs);
-+ if (pcs_changed) {
-+ pl->pcs = pcs;
-+ pl->pcs_ops = pcs->ops;
-+ }
-
- phylink_mac_config(pl, state);
-
-@@ -844,6 +863,8 @@ static void phylink_major_config(struct
- phylink_err(pl, "mac_finish failed: %pe\n",
- ERR_PTR(err));
- }
-+
-+ phylink_pcs_poll_start(pl);
- }
-
- /*
diff --git a/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch b/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch
deleted file mode 100644
index fec2fddfda..0000000000
--- a/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From b7d78b46d5e8dc77c656c13885d31e931923b915 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 29 Jun 2022 22:33:58 +0300
-Subject: [PATCH] net: phylink: fix NULL pl->pcs dereference during
- phylink_pcs_poll_start
-
-The current link mode of the phylink instance may not require an
-attached PCS. However, phylink_major_config() unconditionally
-dereferences this potentially NULL pointer when restarting the link poll
-timer, which will panic the kernel.
-
-Fix the problem by checking whether a PCS exists in phylink_pcs_poll_start(),
-otherwise do nothing. The code prior to the blamed patch also only
-looked at pcs->poll within an "if (pcs)" block.
-
-Fixes: bfac8c490d60 ("net: phylink: disable PCS polling over major configuration")
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Gerhard Engleder <gerhard@engleder-embedded.com>
-Tested-by: Michael Walle <michael@walle.cc> # on kontron-kbox-a-230-ls
-Tested-by: Nicolas Ferre <nicolas.ferre@microchip.com> # on sam9x60ek
-Link: https://lore.kernel.org/r/20220629193358.4007923-1-vladimir.oltean@nxp.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -767,7 +767,7 @@ static void phylink_pcs_poll_stop(struct
-
- static void phylink_pcs_poll_start(struct phylink *pl)
- {
-- if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
-+ if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
- mod_timer(&pl->link_poll, jiffies + HZ);
- }
-
diff --git a/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch
deleted file mode 100644
index 71b09cbe75..0000000000
--- a/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 13 Jul 2023 09:42:07 +0100
-Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods
-
-Add phylink PCS enable/disable callbacks that will allow us to place
-IEEE 802.3 register compliant PCS in power-down mode while not being
-used.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++--------
- include/linux/phylink.h | 16 +++++++++++++
- 2 files changed, 55 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -34,6 +34,10 @@ enum {
- PHYLINK_DISABLE_STOPPED,
- PHYLINK_DISABLE_LINK,
- PHYLINK_DISABLE_MAC_WOL,
-+
-+ PCS_STATE_DOWN = 0,
-+ PCS_STATE_STARTING,
-+ PCS_STATE_STARTED,
- };
-
- /**
-@@ -72,6 +76,7 @@ struct phylink {
- struct mutex state_mutex;
- struct phylink_link_state phy_state;
- struct work_struct resolve;
-+ unsigned int pcs_state;
-
- bool mac_link_dropped;
- bool using_mac_select_pcs;
-@@ -798,6 +803,22 @@ static void phylink_mac_pcs_an_restart(s
- }
- }
-
-+static void phylink_pcs_disable(struct phylink_pcs *pcs)
-+{
-+ if (pcs && pcs->ops->pcs_disable)
-+ pcs->ops->pcs_disable(pcs);
-+}
-+
-+static int phylink_pcs_enable(struct phylink_pcs *pcs)
-+{
-+ int err = 0;
-+
-+ if (pcs && pcs->ops->pcs_enable)
-+ err = pcs->ops->pcs_enable(pcs);
-+
-+ return err;
-+}
-+
- static void phylink_major_config(struct phylink *pl, bool restart,
- const struct phylink_link_state *state)
- {
-@@ -835,12 +856,16 @@ static void phylink_major_config(struct
- * for the change.
- */
- if (pcs_changed) {
-+ phylink_pcs_disable(pl->pcs);
- pl->pcs = pcs;
- pl->pcs_ops = pcs->ops;
- }
-
- phylink_mac_config(pl, state);
-
-+ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
-+ phylink_pcs_enable(pl->pcs);
-+
- if (pl->pcs_ops) {
- err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
- state->interface,
-@@ -1264,6 +1289,7 @@ struct phylink *phylink_create(struct ph
- pl->link_config.speed = SPEED_UNKNOWN;
- pl->link_config.duplex = DUPLEX_UNKNOWN;
- pl->link_config.an_enabled = true;
-+ pl->pcs_state = PCS_STATE_DOWN;
- pl->mac_ops = mac_ops;
- __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
- timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
-@@ -1655,6 +1681,8 @@ void phylink_start(struct phylink *pl)
- if (pl->netdev)
- netif_carrier_off(pl->netdev);
-
-+ pl->pcs_state = PCS_STATE_STARTING;
-+
- /* Apply the link configuration to the MAC when starting. This allows
- * a fixed-link to start with the correct parameters, and also
- * ensures that we set the appropriate advertisement for Serdes links.
-@@ -1665,6 +1693,8 @@ void phylink_start(struct phylink *pl)
- */
- phylink_mac_initial_config(pl, true);
-
-+ pl->pcs_state = PCS_STATE_STARTED;
-+
- clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
- phylink_run_resolve(pl);
-
-@@ -1684,16 +1714,9 @@ void phylink_start(struct phylink *pl)
- poll = true;
- }
-
-- switch (pl->cfg_link_an_mode) {
-- case MLO_AN_FIXED:
-+ if (pl->cfg_link_an_mode == MLO_AN_FIXED)
- poll |= pl->config->poll_fixed_state;
-- break;
-- case MLO_AN_INBAND:
-- poll |= pl->config->pcs_poll;
-- if (pl->pcs)
-- poll |= pl->pcs->poll;
-- break;
-- }
-+
- if (poll)
- mod_timer(&pl->link_poll, jiffies + HZ);
- if (pl->phydev)
-@@ -1730,6 +1753,10 @@ void phylink_stop(struct phylink *pl)
- }
-
- phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
-+
-+ pl->pcs_state = PCS_STATE_DOWN;
-+
-+ phylink_pcs_disable(pl->pcs);
- }
- EXPORT_SYMBOL_GPL(phylink_stop);
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -419,6 +419,8 @@ struct phylink_pcs {
- /**
- * struct phylink_pcs_ops - MAC PCS operations structure.
- * @pcs_validate: validate the link configuration.
-+ * @pcs_enable: enable the PCS.
-+ * @pcs_disable: disable the PCS.
- * @pcs_get_state: read the current MAC PCS link state from the hardware.
- * @pcs_config: configure the MAC PCS for the selected mode and state.
- * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
-@@ -428,6 +430,8 @@ struct phylink_pcs {
- struct phylink_pcs_ops {
- int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
- const struct phylink_link_state *state);
-+ int (*pcs_enable)(struct phylink_pcs *pcs);
-+ void (*pcs_disable)(struct phylink_pcs *pcs);
- void (*pcs_get_state)(struct phylink_pcs *pcs,
- struct phylink_link_state *state);
- int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
-@@ -458,6 +462,18 @@ int pcs_validate(struct phylink_pcs *pcs
- const struct phylink_link_state *state);
-
- /**
-+ * pcs_enable() - enable the PCS.
-+ * @pcs: a pointer to a &struct phylink_pcs.
-+ */
-+int pcs_enable(struct phylink_pcs *pcs);
-+
-+/**
-+ * pcs_disable() - disable the PCS.
-+ * @pcs: a pointer to a &struct phylink_pcs.
-+ */
-+void pcs_disable(struct phylink_pcs *pcs);
-+
-+/**
- * pcs_get_state() - Read the current inband link state from the hardware
- * @pcs: a pointer to a &struct phylink_pcs.
- * @state: a pointer to a &struct phylink_link_state.
diff --git a/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch
deleted file mode 100644
index eb9b4b7c09..0000000000
--- a/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 18 Aug 2023 04:07:46 +0100
-Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op
-
-When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface
-modes provided by mtk-pcs-lynxi we need to make sure to always perform
-a full configuration of the PHYA.
-
-Implement pcs_disable op which resets the stored interface mode to
-PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI
-PCS driver had previously been deselected in favor of another PCS
-driver such as the to-be-added driver for the USXGMII PCS found in
-MT7988.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/pcs/pcs-mtk-lynxi.c
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct
- }
- }
-
-+static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+
-+ mpcs->interface = PHY_INTERFACE_MODE_NA;
-+}
-+
- static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
- .pcs_get_state = mtk_pcs_lynxi_get_state,
- .pcs_config = mtk_pcs_lynxi_config,
- .pcs_an_restart = mtk_pcs_lynxi_restart_an,
- .pcs_link_up = mtk_pcs_lynxi_link_up,
-+ .pcs_disable = mtk_pcs_lynxi_disable,
- };
-
- struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
diff --git a/target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch b/target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch
deleted file mode 100644
index b0860db266..0000000000
--- a/target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From: Andy Ren <andy.ren@getcruise.com>
-Date: Mon, 7 Nov 2022 09:42:42 -0800
-Subject: [PATCH] net/core: Allow live renaming when an interface is up
-
-Allow a network interface to be renamed when the interface
-is up.
-
-As described in the netconsole documentation [1], when netconsole is
-used as a built-in, it will bring up the specified interface as soon as
-possible. As a result, user space will not be able to rename the
-interface since the kernel disallows renaming of interfaces that are
-administratively up unless the 'IFF_LIVE_RENAME_OK' private flag was set
-by the kernel.
-
-The original solution [2] to this problem was to add a new parameter to
-the netconsole configuration parameters that allows renaming of
-the interface used by netconsole while it is administratively up.
-However, during the discussion that followed, it became apparent that we
-have no reason to keep the current restriction and instead we should
-allow user space to rename interfaces regardless of their administrative
-state:
-
-1. The restriction was put in place over 20 years ago when renaming was
-only possible via IOCTL and before rtnetlink started notifying user
-space about such changes like it does today.
-
-2. The 'IFF_LIVE_RENAME_OK' flag was added over 3 years ago in version
-5.2 and no regressions were reported.
-
-3. In-kernel listeners to 'NETDEV_CHANGENAME' do not seem to care about
-the administrative state of interface.
-
-Therefore, allow user space to rename running interfaces by removing the
-restriction and the associated 'IFF_LIVE_RENAME_OK' flag. Help in
-possible triage by emitting a message to the kernel log that an
-interface was renamed while UP.
-
-[1] https://www.kernel.org/doc/Documentation/networking/netconsole.rst
-[2] https://lore.kernel.org/netdev/20221102002420.2613004-1-andy.ren@getcruise.com/
-
-Signed-off-by: Andy Ren <andy.ren@getcruise.com>
-Reviewed-by: Ido Schimmel <idosch@nvidia.com>
-Reviewed-by: David Ahern <dsahern@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1643,7 +1643,6 @@ struct net_device_ops {
- * @IFF_FAILOVER: device is a failover master device
- * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device
- * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device
-- * @IFF_LIVE_RENAME_OK: rename is allowed while device is up and running
- * @IFF_TX_SKB_NO_LINEAR: device/driver is capable of xmitting frames with
- * skb_headlen(skb) == 0 (data starts from frag0)
- */
-@@ -1678,7 +1677,7 @@ enum netdev_priv_flags {
- IFF_FAILOVER = 1<<27,
- IFF_FAILOVER_SLAVE = 1<<28,
- IFF_L3MDEV_RX_HANDLER = 1<<29,
-- IFF_LIVE_RENAME_OK = 1<<30,
-+ /* was IFF_LIVE_RENAME_OK */
- IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
- };
-
-@@ -1712,7 +1711,6 @@ enum netdev_priv_flags {
- #define IFF_FAILOVER IFF_FAILOVER
- #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
- #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
--#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK
- #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
-
- /* Specifies the type of the struct net_device::ml_priv pointer */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -1242,22 +1242,6 @@ int dev_change_name(struct net_device *d
-
- net = dev_net(dev);
-
-- /* Some auto-enslaved devices e.g. failover slaves are
-- * special, as userspace might rename the device after
-- * the interface had been brought up and running since
-- * the point kernel initiated auto-enslavement. Allow
-- * live name change even when these slave devices are
-- * up and running.
-- *
-- * Typically, users of these auto-enslaving devices
-- * don't actually care about slave name change, as
-- * they are supposed to operate on master interface
-- * directly.
-- */
-- if (dev->flags & IFF_UP &&
-- likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK)))
-- return -EBUSY;
--
- down_write(&devnet_rename_sem);
-
- if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
-@@ -1274,7 +1258,8 @@ int dev_change_name(struct net_device *d
- }
-
- if (oldname[0] && !strchr(oldname, '%'))
-- netdev_info(dev, "renamed from %s\n", oldname);
-+ netdev_info(dev, "renamed from %s%s\n", oldname,
-+ dev->flags & IFF_UP ? " (while UP)" : "");
-
- old_assign_type = dev->name_assign_type;
- dev->name_assign_type = NET_NAME_RENAMED;
---- a/net/core/failover.c
-+++ b/net/core/failover.c
-@@ -80,14 +80,14 @@ static int failover_slave_register(struc
- goto err_upper_link;
- }
-
-- slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
-+ slave_dev->priv_flags |= IFF_FAILOVER_SLAVE;
-
- if (fops && fops->slave_register &&
- !fops->slave_register(slave_dev, failover_dev))
- return NOTIFY_OK;
-
- netdev_upper_dev_unlink(slave_dev, failover_dev);
-- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
-+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
- err_upper_link:
- netdev_rx_handler_unregister(slave_dev);
- done:
-@@ -121,7 +121,7 @@ int failover_slave_unregister(struct net
-
- netdev_rx_handler_unregister(slave_dev);
- netdev_upper_dev_unlink(slave_dev, failover_dev);
-- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
-+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
-
- if (fops && fops->slave_unregister &&
- !fops->slave_unregister(slave_dev, failover_dev))
diff --git a/target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch b/target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch
deleted file mode 100644
index 2b3272cebd..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From 69649ef8405320f81497f4757faac8234f61b167 Mon Sep 17 00:00:00 2001
-From: Bjørn Mork <bjorn@mork.no>
-Date: Fri, 6 Jan 2023 17:07:39 +0100
-Subject: [PATCH] cdc_ether: no need to blacklist any r8152 devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The r8152 driver does not need this anymore.
-
-Dropping blacklist entries adds optional support for these
-devices in ECM mode.
-
-The 8153 devices are handled by the r8153_ecm driver when
-in ECM mode, and must still be blacklisted here.
-
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/cdc_ether.c | 114 ------------------------------------
- 1 file changed, 114 deletions(-)
-
---- a/drivers/net/usb/cdc_ether.c
-+++ b/drivers/net/usb/cdc_ether.c
-@@ -767,13 +767,6 @@ static const struct usb_device_id produc
- .driver_info = 0,
- },
-
--/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
- /* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */
- {
- USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM,
-@@ -781,119 +774,12 @@ static const struct usb_device_id produc
- .driver_info = 0,
- },
-
--/* Samsung USB Ethernet Adapters */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--#if IS_ENABLED(CONFIG_USB_RTL8152)
--/* Linksys USB3GIGV1 Ethernet Adapter */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--#endif
--
--/* Lenovo ThinkPad OneLink+ Dock (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3054, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* ThinkPad USB-C Dock (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* ThinkPad Thunderbolt 3 Dock (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3069, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Lenovo USB C to Ethernet Adapter (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x720c, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Lenovo USB-C Travel Hub (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7214, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
- /* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */
- {
- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x721e, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
- .driver_info = 0,
- },
--
--/* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* NVIDIA Tegra USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(NVIDIA_VENDOR_ID, 0x09ff, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Microsoft Surface 2 dock (based on Realtek RTL8152) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07ab, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07c6, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153B) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x0927, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
-
- /* Aquantia AQtion USB to 5GbE Controller (based on AQC111U) */
- {
diff --git a/target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch b/target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch
deleted file mode 100644
index 482c6c6f13..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 02767440e1dda9861a11ca1dbe0f19a760b1d5c2 Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Thu, 19 Jan 2023 15:40:43 +0800
-Subject: [PATCH] r8152: reduce the control transfer of rtl8152_get_version()
-
-Reduce the control transfer by moving calling rtl8152_get_version() in
-rtl8152_probe(). This could prevent from calling rtl8152_get_version()
-for unnecessary situations. For example, after setting config #2 for the
-device, there are two interfaces and rtl8152_probe() may be called
-twice. However, we don't need to call rtl8152_get_version() for this
-situation.
-
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -9602,20 +9602,21 @@ static int rtl8152_probe(struct usb_inte
- const struct usb_device_id *id)
- {
- struct usb_device *udev = interface_to_usbdev(intf);
-- u8 version = rtl8152_get_version(intf);
- struct r8152 *tp;
- struct net_device *netdev;
-+ u8 version;
- int ret;
-
-- if (version == RTL_VER_UNKNOWN)
-- return -ENODEV;
--
- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
- return -ENODEV;
-
- if (!rtl_check_vendor_ok(intf))
- return -ENODEV;
-
-+ version = rtl8152_get_version(intf);
-+ if (version == RTL_VER_UNKNOWN)
-+ return -ENODEV;
-+
- usb_reset_device(udev);
- netdev = alloc_etherdev(sizeof(struct r8152));
- if (!netdev) {
diff --git a/target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch b/target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch
deleted file mode 100644
index 5d1dfe3aef..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 5cc33f139e11b893ff6dc60d8a0ae865a65521ac Mon Sep 17 00:00:00 2001
-From: Douglas Anderson <dianders@chromium.org>
-Date: Thu, 6 Apr 2023 17:14:26 -0700
-Subject: [PATCH] r8152: Add __GFP_NOWARN to big allocations
-
-When memory is a little tight on my system, it's pretty easy to see
-warnings that look like this.
-
- ksoftirqd/0: page allocation failure: order:3, mode:0x40a20(GFP_ATOMIC|__GFP_COMP), nodemask=(null),cpuset=/,mems_allowed=0
- ...
- Call trace:
- dump_backtrace+0x0/0x1e8
- show_stack+0x20/0x2c
- dump_stack_lvl+0x60/0x78
- dump_stack+0x18/0x38
- warn_alloc+0x104/0x174
- __alloc_pages+0x588/0x67c
- alloc_rx_agg+0xa0/0x190 [r8152 ...]
- r8152_poll+0x270/0x760 [r8152 ...]
- __napi_poll+0x44/0x1ec
- net_rx_action+0x100/0x300
- __do_softirq+0xec/0x38c
- run_ksoftirqd+0x38/0xec
- smpboot_thread_fn+0xb8/0x248
- kthread+0x134/0x154
- ret_from_fork+0x10/0x20
-
-On a fragmented system it's normal that order 3 allocations will
-sometimes fail, especially atomic ones. The driver handles these
-failures fine and the WARN just creates spam in the logs for this
-case. The __GFP_NOWARN flag is exactly for this situation, so add it
-to the allocation.
-
-NOTE: my testing is on a 5.15 system, but there should be no reason
-that this would be fundamentally different on a mainline kernel.
-
-Signed-off-by: Douglas Anderson <dianders@chromium.org>
-Acked-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230406171411.1.I84dbef45786af440fd269b71e9436a96a8e7a152@changeid
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -1944,7 +1944,7 @@ static struct rx_agg *alloc_rx_agg(struc
- if (!rx_agg)
- return NULL;
-
-- rx_agg->page = alloc_pages(mflags | __GFP_COMP, order);
-+ rx_agg->page = alloc_pages(mflags | __GFP_COMP | __GFP_NOWARN, order);
- if (!rx_agg->page)
- goto free_rx;
-
diff --git a/target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch b/target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch
deleted file mode 100644
index 0da1a5b7cf..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 57df0fb9d511f91202114813e90128d65c0589f0 Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Wed, 26 Jul 2023 11:08:07 +0800
-Subject: [PATCH] r8152: adjust generic_ocp_write function
-
-Reduce the control transfer if all bytes of first or the last DWORD are
-written.
-
-The original method is to split the control transfer into three parts
-(the first DWORD, middle continuous data, and the last DWORD). However,
-they could be combined if whole bytes of the first DWORD or last DWORD
-are written. That is, the first DWORD or the last DWORD could be combined
-with the middle continuous data, if the byte_en is 0xff.
-
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230726030808.9093-418-nic_swsd@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 29 ++++++++++++++++++-----------
- 1 file changed, 18 insertions(+), 11 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -1310,16 +1310,24 @@ static int generic_ocp_write(struct r815
- byteen_end = byteen & BYTE_EN_END_MASK;
-
- byen = byteen_start | (byteen_start << 4);
-- ret = set_registers(tp, index, type | byen, 4, data);
-- if (ret < 0)
-- goto error1;
--
-- index += 4;
-- data += 4;
-- size -= 4;
-
-- if (size) {
-+ /* Split the first DWORD if the byte_en is not 0xff */
-+ if (byen != BYTE_EN_DWORD) {
-+ ret = set_registers(tp, index, type | byen, 4, data);
-+ if (ret < 0)
-+ goto error1;
-+
-+ index += 4;
-+ data += 4;
- size -= 4;
-+ }
-+
-+ if (size) {
-+ byen = byteen_end | (byteen_end >> 4);
-+
-+ /* Split the last DWORD if the byte_en is not 0xff */
-+ if (byen != BYTE_EN_DWORD)
-+ size -= 4;
-
- while (size) {
- if (size > limit) {
-@@ -1346,10 +1354,9 @@ static int generic_ocp_write(struct r815
- }
- }
-
-- byen = byteen_end | (byteen_end >> 4);
-- ret = set_registers(tp, index, type | byen, 4, data);
-- if (ret < 0)
-- goto error1;
-+ /* Set the last DWORD */
-+ if (byen != BYTE_EN_DWORD)
-+ ret = set_registers(tp, index, type | byen, 4, data);
- }
-
- error1:
diff --git a/target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch b/target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch
deleted file mode 100644
index 6c7efd7f2b..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From e5c266a61186b462c388c53a3564c375e72f2244 Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Wed, 26 Jul 2023 11:08:08 +0800
-Subject: [PATCH] r8152: set bp in bulk
-
-PLA_BP_0 ~ PLA_BP_15 (0xfc28 ~ 0xfc46) are continuous registers, so we
-could combine the control transfers into one control transfer.
-
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230726030808.9093-419-nic_swsd@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 75 ++++++++++++++---------------------------
- 1 file changed, 25 insertions(+), 50 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -3983,29 +3983,10 @@ static void rtl_reset_bmu(struct r8152 *
- /* Clear the bp to stop the firmware before loading a new one */
- static void rtl_clear_bp(struct r8152 *tp, u16 type)
- {
-- switch (tp->version) {
-- case RTL_VER_01:
-- case RTL_VER_02:
-- case RTL_VER_07:
-- break;
-- case RTL_VER_03:
-- case RTL_VER_04:
-- case RTL_VER_05:
-- case RTL_VER_06:
-- ocp_write_byte(tp, type, PLA_BP_EN, 0);
-- break;
-- case RTL_VER_14:
-- ocp_write_word(tp, type, USB_BP2_EN, 0);
-+ u16 bp[16] = {0};
-+ u16 bp_num;
-
-- ocp_write_word(tp, type, USB_BP_8, 0);
-- ocp_write_word(tp, type, USB_BP_9, 0);
-- ocp_write_word(tp, type, USB_BP_10, 0);
-- ocp_write_word(tp, type, USB_BP_11, 0);
-- ocp_write_word(tp, type, USB_BP_12, 0);
-- ocp_write_word(tp, type, USB_BP_13, 0);
-- ocp_write_word(tp, type, USB_BP_14, 0);
-- ocp_write_word(tp, type, USB_BP_15, 0);
-- break;
-+ switch (tp->version) {
- case RTL_VER_08:
- case RTL_VER_09:
- case RTL_VER_10:
-@@ -4013,32 +3994,31 @@ static void rtl_clear_bp(struct r8152 *t
- case RTL_VER_12:
- case RTL_VER_13:
- case RTL_VER_15:
-- default:
- if (type == MCU_TYPE_USB) {
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0);
--
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0);
-- } else {
-- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
-+ bp_num = 16;
-+ break;
- }
-+ fallthrough;
-+ case RTL_VER_03:
-+ case RTL_VER_04:
-+ case RTL_VER_05:
-+ case RTL_VER_06:
-+ ocp_write_byte(tp, type, PLA_BP_EN, 0);
-+ fallthrough;
-+ case RTL_VER_01:
-+ case RTL_VER_02:
-+ case RTL_VER_07:
-+ bp_num = 8;
-+ break;
-+ case RTL_VER_14:
-+ default:
-+ ocp_write_word(tp, type, USB_BP2_EN, 0);
-+ bp_num = 16;
- break;
- }
-
-- ocp_write_word(tp, type, PLA_BP_0, 0);
-- ocp_write_word(tp, type, PLA_BP_1, 0);
-- ocp_write_word(tp, type, PLA_BP_2, 0);
-- ocp_write_word(tp, type, PLA_BP_3, 0);
-- ocp_write_word(tp, type, PLA_BP_4, 0);
-- ocp_write_word(tp, type, PLA_BP_5, 0);
-- ocp_write_word(tp, type, PLA_BP_6, 0);
-- ocp_write_word(tp, type, PLA_BP_7, 0);
-+ generic_ocp_write(tp, PLA_BP_0, BYTE_EN_DWORD, bp_num << 1, bp, type);
-
- /* wait 3 ms to make sure the firmware is stopped */
- usleep_range(3000, 6000);
-@@ -5015,10 +4995,9 @@ static void rtl8152_fw_phy_nc_apply(stru
-
- static void rtl8152_fw_mac_apply(struct r8152 *tp, struct fw_mac *mac)
- {
-- u16 bp_en_addr, bp_index, type, bp_num, fw_ver_reg;
-+ u16 bp_en_addr, type, fw_ver_reg;
- u32 length;
- u8 *data;
-- int i;
-
- switch (__le32_to_cpu(mac->blk_hdr.type)) {
- case RTL_FW_PLA:
-@@ -5060,12 +5039,8 @@ static void rtl8152_fw_mac_apply(struct
- ocp_write_word(tp, type, __le16_to_cpu(mac->bp_ba_addr),
- __le16_to_cpu(mac->bp_ba_value));
-
-- bp_index = __le16_to_cpu(mac->bp_start);
-- bp_num = __le16_to_cpu(mac->bp_num);
-- for (i = 0; i < bp_num; i++) {
-- ocp_write_word(tp, type, bp_index, __le16_to_cpu(mac->bp[i]));
-- bp_index += 2;
-- }
-+ generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD,
-+ __le16_to_cpu(mac->bp_num) << 1, mac->bp, type);
-
- bp_en_addr = __le16_to_cpu(mac->bp_en_addr);
- if (bp_en_addr)
diff --git a/target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch b/target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch
deleted file mode 100644
index 3ef8f37911..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch
+++ /dev/null
@@ -1,398 +0,0 @@
-From d9962b0d42029bcb40fe3c38bce06d1870fa4df4 Mon Sep 17 00:00:00 2001
-From: Douglas Anderson <dianders@chromium.org>
-Date: Fri, 20 Oct 2023 14:06:59 -0700
-Subject: [PATCH] r8152: Block future register access if register access fails
-
-Even though the functions to read/write registers can fail, most of
-the places in the r8152 driver that read/write register values don't
-check error codes. The lack of error code checking is problematic in
-at least two ways.
-
-The first problem is that the r8152 driver often uses code patterns
-similar to this:
- x = read_register()
- x = x | SOME_BIT;
- write_register(x);
-
-...with the above pattern, if the read_register() fails and returns
-garbage then we'll end up trying to write modified garbage back to the
-Realtek adapter. If the write_register() succeeds that's bad. Note
-that as of commit f53a7ad18959 ("r8152: Set memory to all 0xFFs on
-failed reg reads") the "garbage" returned by read_register() will at
-least be consistent garbage, but it is still garbage.
-
-It turns out that this problem is very serious. Writing garbage to
-some of the hardware registers on the Ethernet adapter can put the
-adapter in such a bad state that it needs to be power cycled (fully
-unplugged and plugged in again) before it can enumerate again.
-
-The second problem is that the r8152 driver generally has functions
-that are long sequences of register writes. Assuming everything will
-be OK if a random register write fails in the middle isn't a great
-assumption.
-
-One might wonder if the above two problems are real. You could ask if
-we would really have a successful write after a failed read. It turns
-out that the answer appears to be "yes, this can happen". In fact,
-we've seen at least two distinct failure modes where this happens.
-
-On a sc7180-trogdor Chromebook if you drop into kdb for a while and
-then resume, you can see:
-1. We get a "Tx timeout"
-2. The "Tx timeout" queues up a USB reset.
-3. In rtl8152_pre_reset() we try to reinit the hardware.
-4. The first several (2-9) register accesses fail with a timeout, then
- things recover.
-
-The above test case was actually fixed by the patch ("r8152: Increase
-USB control msg timeout to 5000ms as per spec") but at least shows
-that we really can see successful calls after failed ones.
-
-On a different (AMD) based Chromebook with a particular adapter, we
-found that during reboot tests we'd also sometimes get a transitory
-failure. In this case we saw -EPIPE being returned sometimes. Retrying
-worked, but retrying is not always safe for all register accesses
-since reading/writing some registers might have side effects (like
-registers that clear on read).
-
-Let's fully lock out all register access if a register access fails.
-When we do this, we'll try to queue up a USB reset and try to unlock
-register access after the reset. This is slightly tricker than it
-sounds since the r8152 driver has an optimized reset sequence that
-only works reliably after probe happens. In order to handle this, we
-avoid the optimized reset if probe didn't finish. Instead, we simply
-retry the probe routine in this case.
-
-When locking out access, we'll use the existing infrastructure that
-the driver was using when it detected we were unplugged. This keeps us
-from getting stuck in delay loops in some parts of the driver.
-
-Signed-off-by: Douglas Anderson <dianders@chromium.org>
-Reviewed-by: Grant Grundler <grundler@chromium.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/r8152.c | 207 ++++++++++++++++++++++++++++++++++------
- 1 file changed, 176 insertions(+), 31 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -772,6 +772,9 @@ enum rtl8152_flags {
- SCHEDULE_TASKLET,
- GREEN_ETHERNET,
- RX_EPROTO,
-+ IN_PRE_RESET,
-+ PROBED_WITH_NO_ERRORS,
-+ PROBE_SHOULD_RETRY,
- };
-
- #define DEVICE_ID_THINKPAD_ONELINK_PLUS_DOCK 0x3054
-@@ -949,6 +952,8 @@ struct r8152 {
- u8 version;
- u8 duplex;
- u8 autoneg;
-+
-+ unsigned int reg_access_reset_count;
- };
-
- /**
-@@ -1196,6 +1201,96 @@ static unsigned int agg_buf_sz = 16384;
-
- #define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc))
-
-+/* If register access fails then we block access and issue a reset. If this
-+ * happens too many times in a row without a successful access then we stop
-+ * trying to reset and just leave access blocked.
-+ */
-+#define REGISTER_ACCESS_MAX_RESETS 3
-+
-+static void rtl_set_inaccessible(struct r8152 *tp)
-+{
-+ set_bit(RTL8152_INACCESSIBLE, &tp->flags);
-+ smp_mb__after_atomic();
-+}
-+
-+static void rtl_set_accessible(struct r8152 *tp)
-+{
-+ clear_bit(RTL8152_INACCESSIBLE, &tp->flags);
-+ smp_mb__after_atomic();
-+}
-+
-+static
-+int r8152_control_msg(struct r8152 *tp, unsigned int pipe, __u8 request,
-+ __u8 requesttype, __u16 value, __u16 index, void *data,
-+ __u16 size, const char *msg_tag)
-+{
-+ struct usb_device *udev = tp->udev;
-+ int ret;
-+
-+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
-+ return -ENODEV;
-+
-+ ret = usb_control_msg(udev, pipe, request, requesttype,
-+ value, index, data, size,
-+ USB_CTRL_GET_TIMEOUT);
-+
-+ /* No need to issue a reset to report an error if the USB device got
-+ * unplugged; just return immediately.
-+ */
-+ if (ret == -ENODEV)
-+ return ret;
-+
-+ /* If the write was successful then we're done */
-+ if (ret >= 0) {
-+ tp->reg_access_reset_count = 0;
-+ return ret;
-+ }
-+
-+ dev_err(&udev->dev,
-+ "Failed to %s %d bytes at %#06x/%#06x (%d)\n",
-+ msg_tag, size, value, index, ret);
-+
-+ /* Block all future register access until we reset. Much of the code
-+ * in the driver doesn't check for errors. Notably, many parts of the
-+ * driver do a read/modify/write of a register value without
-+ * confirming that the read succeeded. Writing back modified garbage
-+ * like this can fully wedge the adapter, requiring a power cycle.
-+ */
-+ rtl_set_inaccessible(tp);
-+
-+ /* If probe hasn't yet finished, then we'll request a retry of the
-+ * whole probe routine if we get any control transfer errors. We
-+ * never have to clear this bit since we free/reallocate the whole "tp"
-+ * structure if we retry probe.
-+ */
-+ if (!test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) {
-+ set_bit(PROBE_SHOULD_RETRY, &tp->flags);
-+ return ret;
-+ }
-+
-+ /* Failing to access registers in pre-reset is not surprising since we
-+ * wouldn't be resetting if things were behaving normally. The register
-+ * access we do in pre-reset isn't truly mandatory--we're just reusing
-+ * the disable() function and trying to be nice by powering the
-+ * adapter down before resetting it. Thus, if we're in pre-reset,
-+ * we'll return right away and not try to queue up yet another reset.
-+ * We know the post-reset is already coming.
-+ */
-+ if (test_bit(IN_PRE_RESET, &tp->flags))
-+ return ret;
-+
-+ if (tp->reg_access_reset_count < REGISTER_ACCESS_MAX_RESETS) {
-+ usb_queue_reset_device(tp->intf);
-+ tp->reg_access_reset_count++;
-+ } else if (tp->reg_access_reset_count == REGISTER_ACCESS_MAX_RESETS) {
-+ dev_err(&udev->dev,
-+ "Tried to reset %d times; giving up.\n",
-+ REGISTER_ACCESS_MAX_RESETS);
-+ }
-+
-+ return ret;
-+}
-+
- static
- int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
- {
-@@ -1206,9 +1301,10 @@ int get_registers(struct r8152 *tp, u16
- if (!tmp)
- return -ENOMEM;
-
-- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in,
-- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-- value, index, tmp, size, USB_CTRL_GET_TIMEOUT);
-+ ret = r8152_control_msg(tp, tp->pipe_ctrl_in,
-+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-+ value, index, tmp, size, "read");
-+
- if (ret < 0)
- memset(data, 0xff, size);
- else
-@@ -1229,9 +1325,9 @@ int set_registers(struct r8152 *tp, u16
- if (!tmp)
- return -ENOMEM;
-
-- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out,
-- RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
-- value, index, tmp, size, USB_CTRL_SET_TIMEOUT);
-+ ret = r8152_control_msg(tp, tp->pipe_ctrl_out,
-+ RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
-+ value, index, tmp, size, "write");
-
- kfree(tmp);
-
-@@ -1240,10 +1336,8 @@ int set_registers(struct r8152 *tp, u16
-
- static void rtl_set_unplug(struct r8152 *tp)
- {
-- if (tp->udev->state == USB_STATE_NOTATTACHED) {
-- set_bit(RTL8152_INACCESSIBLE, &tp->flags);
-- smp_mb__after_atomic();
-- }
-+ if (tp->udev->state == USB_STATE_NOTATTACHED)
-+ rtl_set_inaccessible(tp);
- }
-
- static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
-@@ -8268,7 +8362,7 @@ static int rtl8152_pre_reset(struct usb_
- struct r8152 *tp = usb_get_intfdata(intf);
- struct net_device *netdev;
-
-- if (!tp)
-+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
- return 0;
-
- netdev = tp->netdev;
-@@ -8283,7 +8377,9 @@ static int rtl8152_pre_reset(struct usb_
- napi_disable(&tp->napi);
- if (netif_carrier_ok(netdev)) {
- mutex_lock(&tp->control);
-+ set_bit(IN_PRE_RESET, &tp->flags);
- tp->rtl_ops.disable(tp);
-+ clear_bit(IN_PRE_RESET, &tp->flags);
- mutex_unlock(&tp->control);
- }
-
-@@ -8296,9 +8392,11 @@ static int rtl8152_post_reset(struct usb
- struct net_device *netdev;
- struct sockaddr sa;
-
-- if (!tp)
-+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
- return 0;
-
-+ rtl_set_accessible(tp);
-+
- /* reset the MAC address in case of policy change */
- if (determine_ethernet_addr(tp, &sa) >= 0) {
- rtnl_lock();
-@@ -9496,17 +9594,29 @@ static u8 __rtl_get_hw_ver(struct usb_de
- __le32 *tmp;
- u8 version;
- int ret;
-+ int i;
-
- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
- if (!tmp)
- return 0;
-
-- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-- PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp),
-- USB_CTRL_GET_TIMEOUT);
-- if (ret > 0)
-- ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK;
-+ /* Retry up to 3 times in case there is a transitory error. We do this
-+ * since retrying a read of the version is always safe and this
-+ * function doesn't take advantage of r8152_control_msg().
-+ */
-+ for (i = 0; i < 3; i++) {
-+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-+ PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp),
-+ USB_CTRL_GET_TIMEOUT);
-+ if (ret > 0) {
-+ ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK;
-+ break;
-+ }
-+ }
-+
-+ if (i != 0 && ret > 0)
-+ dev_warn(&udev->dev, "Needed %d retries to read version\n", i);
-
- kfree(tmp);
-
-@@ -9580,25 +9690,14 @@ u8 rtl8152_get_version(struct usb_interf
- }
- EXPORT_SYMBOL_GPL(rtl8152_get_version);
-
--static int rtl8152_probe(struct usb_interface *intf,
-- const struct usb_device_id *id)
-+static int rtl8152_probe_once(struct usb_interface *intf,
-+ const struct usb_device_id *id, u8 version)
- {
- struct usb_device *udev = interface_to_usbdev(intf);
- struct r8152 *tp;
- struct net_device *netdev;
-- u8 version;
- int ret;
-
-- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
-- return -ENODEV;
--
-- if (!rtl_check_vendor_ok(intf))
-- return -ENODEV;
--
-- version = rtl8152_get_version(intf);
-- if (version == RTL_VER_UNKNOWN)
-- return -ENODEV;
--
- usb_reset_device(udev);
- netdev = alloc_etherdev(sizeof(struct r8152));
- if (!netdev) {
-@@ -9771,10 +9870,20 @@ static int rtl8152_probe(struct usb_inte
- else
- device_set_wakeup_enable(&udev->dev, false);
-
-+ /* If we saw a control transfer error while probing then we may
-+ * want to try probe() again. Consider this an error.
-+ */
-+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
-+ goto out2;
-+
-+ set_bit(PROBED_WITH_NO_ERRORS, &tp->flags);
- netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION);
-
- return 0;
-
-+out2:
-+ unregister_netdev(netdev);
-+
- out1:
- tasklet_kill(&tp->tx_tl);
- cancel_delayed_work_sync(&tp->hw_phy_work);
-@@ -9783,10 +9892,46 @@ out1:
- rtl8152_release_firmware(tp);
- usb_set_intfdata(intf, NULL);
- out:
-+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
-+ ret = -EAGAIN;
-+
- free_netdev(netdev);
- return ret;
- }
-
-+#define RTL8152_PROBE_TRIES 3
-+
-+static int rtl8152_probe(struct usb_interface *intf,
-+ const struct usb_device_id *id)
-+{
-+ u8 version;
-+ int ret;
-+ int i;
-+
-+ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
-+ return -ENODEV;
-+
-+ if (!rtl_check_vendor_ok(intf))
-+ return -ENODEV;
-+
-+ version = rtl8152_get_version(intf);
-+ if (version == RTL_VER_UNKNOWN)
-+ return -ENODEV;
-+
-+ for (i = 0; i < RTL8152_PROBE_TRIES; i++) {
-+ ret = rtl8152_probe_once(intf, id, version);
-+ if (ret != -EAGAIN)
-+ break;
-+ }
-+ if (ret == -EAGAIN) {
-+ dev_err(&intf->dev,
-+ "r8152 failed probe after %d tries; giving up\n", i);
-+ return -ENODEV;
-+ }
-+
-+ return ret;
-+}
-+
- static void rtl8152_disconnect(struct usb_interface *intf)
- {
- struct r8152 *tp = usb_get_intfdata(intf);
diff --git a/target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch b/target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch
deleted file mode 100644
index 42ca9e2ad1..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 66eee612a1ba39f9a76a9ace4a34d012044767fb Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Tue, 26 Sep 2023 19:17:13 +0800
-Subject: [PATCH] r8152: break the loop when the budget is exhausted
-
-[ Upstream commit 2cf51f931797d9a47e75d999d0993a68cbd2a560 ]
-
-A bulk transfer of the USB may contain many packets. And, the total
-number of the packets in the bulk transfer may be more than budget.
-
-Originally, only budget packets would be handled by napi_gro_receive(),
-and the other packets would be queued in the driver for next schedule.
-
-This patch would break the loop about getting next bulk transfer, when
-the budget is exhausted. That is, only the current bulk transfer would
-be handled, and the other bulk transfers would be queued for next
-schedule. Besides, the packets which are more than the budget in the
-current bulk trasnfer would be still queued in the driver, as the
-original method.
-
-In addition, a bulk transfer wouldn't contain more than 400 packets, so
-the check of queue length is unnecessary. Therefore, I replace it with
-WARN_ON_ONCE().
-
-Fixes: cf74eb5a5bc8 ("eth: r8152: try to use a normal budget")
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230926111714.9448-433-nic_swsd@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/net/usb/r8152.c | 18 +++++++++++++-----
- 1 file changed, 13 insertions(+), 5 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -2539,7 +2539,7 @@ static int rx_bottom(struct r8152 *tp, i
- }
- }
-
-- if (list_empty(&tp->rx_done))
-+ if (list_empty(&tp->rx_done) || work_done >= budget)
- goto out1;
-
- clear_bit(RX_EPROTO, &tp->flags);
-@@ -2555,6 +2555,15 @@ static int rx_bottom(struct r8152 *tp, i
- struct urb *urb;
- u8 *rx_data;
-
-+ /* A bulk transfer of USB may contain may packets, so the
-+ * total packets may more than the budget. Deal with all
-+ * packets in current bulk transfer, and stop to handle the
-+ * next bulk transfer until next schedule, if budget is
-+ * exhausted.
-+ */
-+ if (work_done >= budget)
-+ break;
-+
- list_del_init(cursor);
-
- agg = list_entry(cursor, struct rx_agg, list);
-@@ -2574,9 +2583,7 @@ static int rx_bottom(struct r8152 *tp, i
- unsigned int pkt_len, rx_frag_head_sz;
- struct sk_buff *skb;
-
-- /* limit the skb numbers for rx_queue */
-- if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000))
-- break;
-+ WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000);
-
- pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
- if (pkt_len < ETH_ZLEN)
-@@ -2654,9 +2661,10 @@ submit:
- }
- }
-
-+ /* Splice the remained list back to rx_done for next schedule */
- if (!list_empty(&rx_queue)) {
- spin_lock_irqsave(&tp->rx_lock, flags);
-- list_splice_tail(&rx_queue, &tp->rx_done);
-+ list_splice(&rx_queue, &tp->rx_done);
- spin_unlock_irqrestore(&tp->rx_lock, flags);
- }
-
diff --git a/target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch b/target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch
deleted file mode 100644
index d578d0107f..0000000000
--- a/target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 1b0fce8c8e69485e49a7d34aac3d4c2a2aa15d62 Mon Sep 17 00:00:00 2001
-From: Davide Tronchin <davide.tronchin.94@gmail.com>
-Date: Thu, 29 Jun 2023 12:37:36 +0200
-Subject: [PATCH] net: usb: cdc_ether: add u-blox 0x1313 composition.
-
-Add CDC-ECM support for LARA-R6 01B.
-
-The new LARA-R6 product variant identified by the "01B" string can be
-configured (by AT interface) in three different USB modes:
-* Default mode (Vendor ID: 0x1546 Product ID: 0x1311) with 4 serial
-interfaces
-* RmNet mode (Vendor ID: 0x1546 Product ID: 0x1312) with 4 serial
-interfaces and 1 RmNet virtual network interface
-* CDC-ECM mode (Vendor ID: 0x1546 Product ID: 0x1313) with 4 serial
-interface and 1 CDC-ECM virtual network interface
-The first 4 interfaces of all the 3 configurations (default, RmNet, ECM)
-are the same.
-
-In CDC-ECM mode LARA-R6 01B exposes the following interfaces:
-If 0: Diagnostic
-If 1: AT parser
-If 2: AT parser
-If 3: AT parset/alternative functions
-If 4: CDC-ECM interface
-
-Signed-off-by: Davide Tronchin <davide.tronchin.94@gmail.com>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/cdc_ether.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/usb/cdc_ether.c
-+++ b/drivers/net/usb/cdc_ether.c
-@@ -878,6 +878,12 @@ static const struct usb_device_id produc
- USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long)&wwan_info,
- }, {
-+ /* U-blox LARA-R6 01B */
-+ USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1313, USB_CLASS_COMM,
-+ USB_CDC_SUBCLASS_ETHERNET,
-+ USB_CDC_PROTO_NONE),
-+ .driver_info = (unsigned long)&wwan_info,
-+}, {
- /* ZTE modules */
- USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_ETHERNET,
diff --git a/target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch b/target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch
deleted file mode 100644
index d9d6f36fce..0000000000
--- a/target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 2203718c2f59ffdd6c78d54e5add594aebb4461e Mon Sep 17 00:00:00 2001
-From: Georgi Valkov <gvalkov@gmail.com>
-Date: Wed, 7 Jun 2023 15:56:59 +0200
-Subject: [PATCH 1/4] usbnet: ipheth: fix risk of NULL pointer deallocation
-
-The cleanup precedure in ipheth_probe will attempt to free a
-NULL pointer in dev->ctrl_buf if the memory allocation for
-this buffer is not successful. While kfree ignores NULL pointers,
-and the existing code is safe, it is a better design to rearrange
-the goto labels and avoid this.
-
-Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/ipheth.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/usb/ipheth.c
-+++ b/drivers/net/usb/ipheth.c
-@@ -510,8 +510,8 @@ err_register_netdev:
- ipheth_free_urbs(dev);
- err_alloc_urbs:
- err_get_macaddr:
--err_alloc_ctrl_buf:
- kfree(dev->ctrl_buf);
-+err_alloc_ctrl_buf:
- err_endpoints:
- free_netdev(netdev);
- return retval;
diff --git a/target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch b/target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch
deleted file mode 100644
index adfec356d9..0000000000
--- a/target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 3e65efcca87a9bb5f3b864e0a43d167bc0a8688c Mon Sep 17 00:00:00 2001
-From: Foster Snowhill <forst@pen.gy>
-Date: Wed, 7 Jun 2023 15:57:00 +0200
-Subject: [PATCH 2/4] usbnet: ipheth: transmit URBs without trailing padding
-
-The behaviour of the official iOS tethering driver on macOS is to not
-transmit any trailing padding at the end of URBs. This is applicable
-to both NCM and legacy modes, including older devices.
-
-Adapt the driver to not include trailing padding in TX URBs, matching
-the behaviour of the official macOS driver.
-
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Tested-by: Georgi Valkov <gvalkov@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/ipheth.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/usb/ipheth.c
-+++ b/drivers/net/usb/ipheth.c
-@@ -373,12 +373,10 @@ static netdev_tx_t ipheth_tx(struct sk_b
- }
-
- memcpy(dev->tx_buf, skb->data, skb->len);
-- if (skb->len < IPHETH_BUF_SIZE)
-- memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
-
- usb_fill_bulk_urb(dev->tx_urb, udev,
- usb_sndbulkpipe(udev, dev->bulk_out),
-- dev->tx_buf, IPHETH_BUF_SIZE,
-+ dev->tx_buf, skb->len,
- ipheth_sndbulk_callback,
- dev);
- dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
diff --git a/target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch b/target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch
deleted file mode 100644
index e3f2b9c331..0000000000
--- a/target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch
+++ /dev/null
@@ -1,326 +0,0 @@
-From a2d274c62e44b1995c170595db3865c6fe701226 Mon Sep 17 00:00:00 2001
-From: Foster Snowhill <forst@pen.gy>
-Date: Wed, 7 Jun 2023 15:57:01 +0200
-Subject: [PATCH 3/4] usbnet: ipheth: add CDC NCM support
-
-Recent iOS releases support CDC NCM encapsulation on RX. This mode is
-the default on macOS and Windows. In this mode, an iOS device may include
-one or more Ethernet frames inside a single URB.
-
-Freshly booted iOS devices start in legacy mode, but are put into
-NCM mode by the official Apple driver. When reconnecting such a device
-from a macOS/Windows machine to a Linux host, the device stays in
-NCM mode, making it unusable with the legacy ipheth driver code.
-
-To correctly support such a device, the driver has to either support
-the NCM mode too, or put the device back into legacy mode.
-
-To match the behaviour of the macOS/Windows driver, and since there
-is no documented control command to revert to legacy mode, implement
-NCM support. The device is attempted to be put into NCM mode by default,
-and falls back to legacy mode if the attempt fails.
-
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Tested-by: Georgi Valkov <gvalkov@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/ipheth.c | 180 +++++++++++++++++++++++++++++++++------
- 1 file changed, 155 insertions(+), 25 deletions(-)
-
---- a/drivers/net/usb/ipheth.c
-+++ b/drivers/net/usb/ipheth.c
-@@ -52,6 +52,7 @@
- #include <linux/ethtool.h>
- #include <linux/usb.h>
- #include <linux/workqueue.h>
-+#include <linux/usb/cdc.h>
-
- #define USB_VENDOR_APPLE 0x05ac
-
-@@ -59,8 +60,12 @@
- #define IPHETH_USBINTF_SUBCLASS 253
- #define IPHETH_USBINTF_PROTO 1
-
--#define IPHETH_BUF_SIZE 1514
- #define IPHETH_IP_ALIGN 2 /* padding at front of URB */
-+#define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */
-+#define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN
-+#define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN)
-+#define IPHETH_RX_BUF_SIZE_NCM 65536
-+
- #define IPHETH_TX_TIMEOUT (5 * HZ)
-
- #define IPHETH_INTFNUM 2
-@@ -71,6 +76,7 @@
- #define IPHETH_CTRL_TIMEOUT (5 * HZ)
-
- #define IPHETH_CMD_GET_MACADDR 0x00
-+#define IPHETH_CMD_ENABLE_NCM 0x04
- #define IPHETH_CMD_CARRIER_CHECK 0x45
-
- #define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
-@@ -97,6 +103,8 @@ struct ipheth_device {
- u8 bulk_out;
- struct delayed_work carrier_work;
- bool confirmed_pairing;
-+ int (*rcvbulk_callback)(struct urb *urb);
-+ size_t rx_buf_len;
- };
-
- static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
-@@ -116,12 +124,12 @@ static int ipheth_alloc_urbs(struct iphe
- if (rx_urb == NULL)
- goto free_tx_urb;
-
-- tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
-+ tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_TX_BUF_SIZE,
- GFP_KERNEL, &tx_urb->transfer_dma);
- if (tx_buf == NULL)
- goto free_rx_urb;
-
-- rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
-+ rx_buf = usb_alloc_coherent(iphone->udev, iphone->rx_buf_len,
- GFP_KERNEL, &rx_urb->transfer_dma);
- if (rx_buf == NULL)
- goto free_tx_buf;
-@@ -134,7 +142,7 @@ static int ipheth_alloc_urbs(struct iphe
- return 0;
-
- free_tx_buf:
-- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
-+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, tx_buf,
- tx_urb->transfer_dma);
- free_rx_urb:
- usb_free_urb(rx_urb);
-@@ -146,9 +154,9 @@ error_nomem:
-
- static void ipheth_free_urbs(struct ipheth_device *iphone)
- {
-- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf,
-+ usb_free_coherent(iphone->udev, iphone->rx_buf_len, iphone->rx_buf,
- iphone->rx_urb->transfer_dma);
-- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
-+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, iphone->tx_buf,
- iphone->tx_urb->transfer_dma);
- usb_free_urb(iphone->rx_urb);
- usb_free_urb(iphone->tx_urb);
-@@ -160,15 +168,106 @@ static void ipheth_kill_urbs(struct iphe
- usb_kill_urb(dev->rx_urb);
- }
-
--static void ipheth_rcvbulk_callback(struct urb *urb)
-+static int ipheth_consume_skb(char *buf, int len, struct ipheth_device *dev)
- {
-- struct ipheth_device *dev;
- struct sk_buff *skb;
-- int status;
-+
-+ skb = dev_alloc_skb(len);
-+ if (!skb) {
-+ dev->net->stats.rx_dropped++;
-+ return -ENOMEM;
-+ }
-+
-+ skb_put_data(skb, buf, len);
-+ skb->dev = dev->net;
-+ skb->protocol = eth_type_trans(skb, dev->net);
-+
-+ dev->net->stats.rx_packets++;
-+ dev->net->stats.rx_bytes += len;
-+ netif_rx(skb);
-+
-+ return 0;
-+}
-+
-+static int ipheth_rcvbulk_callback_legacy(struct urb *urb)
-+{
-+ struct ipheth_device *dev;
-+ char *buf;
-+ int len;
-+
-+ dev = urb->context;
-+
-+ if (urb->actual_length <= IPHETH_IP_ALIGN) {
-+ dev->net->stats.rx_length_errors++;
-+ return -EINVAL;
-+ }
-+ len = urb->actual_length - IPHETH_IP_ALIGN;
-+ buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
-+
-+ return ipheth_consume_skb(buf, len, dev);
-+}
-+
-+static int ipheth_rcvbulk_callback_ncm(struct urb *urb)
-+{
-+ struct usb_cdc_ncm_nth16 *ncmh;
-+ struct usb_cdc_ncm_ndp16 *ncm0;
-+ struct usb_cdc_ncm_dpe16 *dpe;
-+ struct ipheth_device *dev;
-+ int retval = -EINVAL;
- char *buf;
- int len;
-
- dev = urb->context;
-+
-+ if (urb->actual_length < IPHETH_NCM_HEADER_SIZE) {
-+ dev->net->stats.rx_length_errors++;
-+ return retval;
-+ }
-+
-+ ncmh = urb->transfer_buffer;
-+ if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) ||
-+ le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) {
-+ dev->net->stats.rx_errors++;
-+ return retval;
-+ }
-+
-+ ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex);
-+ if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) ||
-+ le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >=
-+ urb->actual_length) {
-+ dev->net->stats.rx_errors++;
-+ return retval;
-+ }
-+
-+ dpe = ncm0->dpe16;
-+ while (le16_to_cpu(dpe->wDatagramIndex) != 0 &&
-+ le16_to_cpu(dpe->wDatagramLength) != 0) {
-+ if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length ||
-+ le16_to_cpu(dpe->wDatagramIndex) +
-+ le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) {
-+ dev->net->stats.rx_length_errors++;
-+ return retval;
-+ }
-+
-+ buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex);
-+ len = le16_to_cpu(dpe->wDatagramLength);
-+
-+ retval = ipheth_consume_skb(buf, len, dev);
-+ if (retval != 0)
-+ return retval;
-+
-+ dpe++;
-+ }
-+
-+ return 0;
-+}
-+
-+static void ipheth_rcvbulk_callback(struct urb *urb)
-+{
-+ struct ipheth_device *dev;
-+ int retval, status;
-+
-+ dev = urb->context;
- if (dev == NULL)
- return;
-
-@@ -191,25 +290,27 @@ static void ipheth_rcvbulk_callback(stru
- dev->net->stats.rx_length_errors++;
- return;
- }
-- len = urb->actual_length - IPHETH_IP_ALIGN;
-- buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
-
-- skb = dev_alloc_skb(len);
-- if (!skb) {
-- dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n",
-- __func__);
-- dev->net->stats.rx_dropped++;
-+ /* RX URBs starting with 0x00 0x01 do not encapsulate Ethernet frames,
-+ * but rather are control frames. Their purpose is not documented, and
-+ * they don't affect driver functionality, okay to drop them.
-+ * There is usually just one 4-byte control frame as the very first
-+ * URB received from the bulk IN endpoint.
-+ */
-+ if (unlikely
-+ (((char *)urb->transfer_buffer)[0] == 0 &&
-+ ((char *)urb->transfer_buffer)[1] == 1))
-+ goto rx_submit;
-+
-+ retval = dev->rcvbulk_callback(urb);
-+ if (retval != 0) {
-+ dev_err(&dev->intf->dev, "%s: callback retval: %d\n",
-+ __func__, retval);
- return;
- }
-
-- skb_put_data(skb, buf, len);
-- skb->dev = dev->net;
-- skb->protocol = eth_type_trans(skb, dev->net);
--
-- dev->net->stats.rx_packets++;
-- dev->net->stats.rx_bytes += len;
-+rx_submit:
- dev->confirmed_pairing = true;
-- netif_rx(skb);
- ipheth_rx_submit(dev, GFP_ATOMIC);
- }
-
-@@ -310,6 +411,27 @@ static int ipheth_get_macaddr(struct iph
- return retval;
- }
-
-+static int ipheth_enable_ncm(struct ipheth_device *dev)
-+{
-+ struct usb_device *udev = dev->udev;
-+ int retval;
-+
-+ retval = usb_control_msg(udev,
-+ usb_sndctrlpipe(udev, IPHETH_CTRL_ENDP),
-+ IPHETH_CMD_ENABLE_NCM, /* request */
-+ 0x41, /* request type */
-+ 0x00, /* value */
-+ 0x02, /* index */
-+ NULL,
-+ 0,
-+ IPHETH_CTRL_TIMEOUT);
-+
-+ dev_info(&dev->intf->dev, "%s: usb_control_msg: %d\n",
-+ __func__, retval);
-+
-+ return retval;
-+}
-+
- static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
- {
- struct usb_device *udev = dev->udev;
-@@ -317,7 +439,7 @@ static int ipheth_rx_submit(struct iphet
-
- usb_fill_bulk_urb(dev->rx_urb, udev,
- usb_rcvbulkpipe(udev, dev->bulk_in),
-- dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
-+ dev->rx_buf, dev->rx_buf_len,
- ipheth_rcvbulk_callback,
- dev);
- dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-@@ -365,7 +487,7 @@ static netdev_tx_t ipheth_tx(struct sk_b
- int retval;
-
- /* Paranoid */
-- if (skb->len > IPHETH_BUF_SIZE) {
-+ if (skb->len > IPHETH_TX_BUF_SIZE) {
- WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
- dev->net->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
-@@ -448,6 +570,8 @@ static int ipheth_probe(struct usb_inter
- dev->net = netdev;
- dev->intf = intf;
- dev->confirmed_pairing = false;
-+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_LEGACY;
-+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_legacy;
- /* Set up endpoints */
- hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
- if (hintf == NULL) {
-@@ -479,6 +603,12 @@ static int ipheth_probe(struct usb_inter
- if (retval)
- goto err_get_macaddr;
-
-+ retval = ipheth_enable_ncm(dev);
-+ if (!retval) {
-+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_NCM;
-+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_ncm;
-+ }
-+
- INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
-
- retval = ipheth_alloc_urbs(dev);
diff --git a/target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch b/target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch
deleted file mode 100644
index 2ab7e8fedd..0000000000
--- a/target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0c6e9d32ef0ccfcf2d875cbcff23bf345a54d585 Mon Sep 17 00:00:00 2001
-From: Foster Snowhill <forst@pen.gy>
-Date: Wed, 7 Jun 2023 15:57:02 +0200
-Subject: [PATCH 4/4] usbnet: ipheth: update Kconfig description
-
-This module has for a long time not been limited to iPhone <= 3GS.
-Update description to match the actual state of the driver.
-
-Remove dead link from 2010, instead reference an existing userspace
-iOS device pairing implementation as part of libimobiledevice.
-
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/Kconfig | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
---- a/drivers/net/usb/Kconfig
-+++ b/drivers/net/usb/Kconfig
-@@ -582,12 +582,10 @@ config USB_IPHETH
- default n
- help
- Module used to share Internet connection (tethering) from your
-- iPhone (Original, 3G and 3GS) to your system.
-- Note that you need userspace libraries and programs that are needed
-- to pair your device with your system and that understand the iPhone
-- protocol.
--
-- For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
-+ iPhone to your system.
-+ Note that you need a corresponding userspace library/program
-+ to pair your device with your system, for example usbmuxd
-+ <https://github.com/libimobiledevice/usbmuxd>.
-
- config USB_SIERRA_NET
- tristate "USB-to-WWAN Driver for Sierra Wireless modems"
diff --git a/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch b/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch
deleted file mode 100644
index b2af169b92..0000000000
--- a/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 16b1c4e01c89ba07367461e0bc4cb84993c2d027 Mon Sep 17 00:00:00 2001
-From: Jacky Chou <jackychou@asix.com.tw>
-Date: Mon, 15 Nov 2021 11:49:41 +0800
-Subject: [PATCH] net: usb: ax88179_178a: add TSO feature
-
-On low-effciency embedded platforms, transmission performance is poor
-due to on Bulk-out with single packet.
-Adding TSO feature improves the transmission performance and reduces
-the number of interrupt caused by Bulk-out complete.
-
-Reference to module, net: usb: aqc111.
-
-Signed-off-by: Jacky Chou <jackychou@asix.com.tw>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/ax88179_178a.c | 17 +++++++++++------
- 1 file changed, 11 insertions(+), 6 deletions(-)
-
---- a/drivers/net/usb/ax88179_178a.c
-+++ b/drivers/net/usb/ax88179_178a.c
-@@ -1333,11 +1333,12 @@ static int ax88179_bind(struct usbnet *d
- dev->mii.phy_id = 0x03;
- dev->mii.supports_gmii = 1;
-
-- dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-- NETIF_F_RXCSUM;
-+ dev->net->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
-+ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO;
-
-- dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-- NETIF_F_RXCSUM;
-+ dev->net->hw_features |= dev->net->features;
-+
-+ netif_set_gso_max_size(dev->net, 16384);
-
- ax88179_reset(dev);
-
-@@ -1502,17 +1503,19 @@ ax88179_tx_fixup(struct usbnet *dev, str
- {
- u32 tx_hdr1, tx_hdr2;
- int frame_size = dev->maxpacket;
-- int mss = skb_shinfo(skb)->gso_size;
- int headroom;
- void *ptr;
-
- tx_hdr1 = skb->len;
-- tx_hdr2 = mss;
-+ tx_hdr2 = skb_shinfo(skb)->gso_size; /* Set TSO mss */
- if (((skb->len + 8) % frame_size) == 0)
- tx_hdr2 |= 0x80008000; /* Enable padding */
-
- headroom = skb_headroom(skb) - 8;
-
-+ if ((dev->net->features & NETIF_F_SG) && skb_linearize(skb))
-+ return NULL;
-+
- if ((skb_header_cloned(skb) || headroom < 0) &&
- pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) {
- dev_kfree_skb_any(skb);
-@@ -1523,6 +1526,8 @@ ax88179_tx_fixup(struct usbnet *dev, str
- put_unaligned_le32(tx_hdr1, ptr);
- put_unaligned_le32(tx_hdr2, ptr + 4);
-
-+ usbnet_set_skb_tx_stats(skb, (skb_shinfo(skb)->gso_segs ?: 1), 0);
-+
- return skb;
- }
-
diff --git a/target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch b/target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch
deleted file mode 100644
index d6015a5658..0000000000
--- a/target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From d387e34fec407f881fdf165b5d7ec128ebff362f Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 19 Sep 2023 14:47:20 +0200
-Subject: [PATCH] net: sfp: add quirk for Fiberstone GPON-ONU-34-20BI
-
-Fiberstone GPON-ONU-34-20B can operate at 2500base-X, but report 1.2GBd
-NRZ in their EEPROM.
-
-The module also require the ignore tx fault fixup similar to Huawei MA5671A
-as it gets disabled on error messages with serial redirection enabled.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://lore.kernel.org/r/20230919124720.8210-1-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/sfp.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -368,6 +368,13 @@ static const struct sfp_quirk sfp_quirks
- .modes = sfp_quirk_2500basex,
- .fixup = sfp_fixup_long_startup,
- }, {
-+ // Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
-+ // NRZ in their EEPROM
-+ .vendor = "FS",
-+ .part = "GPON-ONU-34-20BI",
-+ .modes = sfp_quirk_2500basex,
-+ .fixup = sfp_fixup_ignore_tx_fault,
-+ }, {
- .vendor = "HALNy",
- .part = "HL-GSFP",
- .fixup = sfp_fixup_halny_gsfp,
diff --git a/target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch b/target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch
deleted file mode 100644
index b1072ce640..0000000000
--- a/target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 13344f8ce8a0d98aa7f5d69ce3b47393c73a343b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 27 Dec 2021 15:59:04 +0100
-Subject: [PATCH] dt-bindings: leds: add Broadcom's BCM63138 controller
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom used 2 LEDs hardware blocks for their BCM63xx SoCs:
-1. Older one (BCM6318, BCM6328, BCM6362, BCM63268, BCM6838)
-2. Newer one (BCM6848, BCM6858, BCM63138, BCM63148, BCM63381, BCM68360)
-
-The newer one was also later also used on BCM4908 SoC.
-
-Old block is already documented in the leds-bcm6328.yaml. This binding
-documents the new one which uses different registers & programming. It's
-first used in BCM63138 thus the binding name.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Pavel Machek <pavel@ucw.cz>
----
- .../bindings/leds/leds-bcm63138.yaml | 95 +++++++++++++++++++
- 1 file changed, 95 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/leds/leds-bcm63138.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/leds/leds-bcm63138.yaml
-@@ -0,0 +1,95 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/leds/leds-bcm63138.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Broadcom's BCM63138 LEDs controller
-+
-+maintainers:
-+ - Rafał Miłecki <rafal@milecki.pl>
-+
-+description: |
-+ This LEDs controller was first used on BCM63138 and later reused on BCM4908,
-+ BCM6848, BCM6858, BCM63138, BCM63148, BCM63381 and BCM68360 SoCs.
-+
-+ It supports up to 32 LEDs that can be connected parallelly or serially. It
-+ also includes limited support for hardware blinking.
-+
-+ Binding serially connected LEDs isn't documented yet.
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - items:
-+ - enum:
-+ - brcm,bcm4908-leds
-+ - brcm,bcm6848-leds
-+ - brcm,bcm6858-leds
-+ - brcm,bcm63148-leds
-+ - brcm,bcm63381-leds
-+ - brcm,bcm68360-leds
-+ - const: brcm,bcm63138-leds
-+ - const: brcm,bcm63138-leds
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#address-cells":
-+ const: 1
-+
-+ "#size-cells":
-+ const: 0
-+
-+patternProperties:
-+ "^led@[a-f0-9]+$":
-+ type: object
-+
-+ $ref: common.yaml#
-+
-+ properties:
-+ reg:
-+ maxItems: 1
-+ description: LED pin number
-+
-+ active-low:
-+ type: boolean
-+ description: Makes LED active low.
-+
-+ required:
-+ - reg
-+
-+ unevaluatedProperties: false
-+
-+required:
-+ - reg
-+ - "#address-cells"
-+ - "#size-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/leds/common.h>
-+
-+ leds@ff800800 {
-+ compatible = "brcm,bcm4908-leds", "brcm,bcm63138-leds";
-+ reg = <0xff800800 0xdc>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ led@0 {
-+ reg = <0x0>;
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_GREEN>;
-+ default-state = "on";
-+ };
-+
-+ led@3 {
-+ reg = <0x3>;
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_GREEN>;
-+ active-low;
-+ };
-+ };
diff --git a/target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch b/target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch
deleted file mode 100644
index 376584574f..0000000000
--- a/target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch
+++ /dev/null
@@ -1,356 +0,0 @@
-From a0ba692072d89075d0a75c7ad9df31f2c1ee9a1c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 27 Dec 2021 15:59:05 +0100
-Subject: [PATCH] leds: bcm63138: add support for BCM63138 controller
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's a new controller first introduced in BCM63138 SoC. Later it was
-also used in BCM4908, some BCM68xx and some BCM63xxx SoCs.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Pavel Machek <pavel@ucw.cz>
----
- drivers/leds/blink/Kconfig | 12 ++
- drivers/leds/blink/Makefile | 1 +
- drivers/leds/blink/leds-bcm63138.c | 308 +++++++++++++++++++++++++++++
- 3 files changed, 321 insertions(+)
- create mode 100644 drivers/leds/blink/leds-bcm63138.c
-
---- a/drivers/leds/blink/Kconfig
-+++ b/drivers/leds/blink/Kconfig
-@@ -1,3 +1,15 @@
-+config LEDS_BCM63138
-+ tristate "LED Support for Broadcom BCM63138 SoC"
-+ depends on LEDS_CLASS
-+ depends on ARCH_BCM4908 || ARCH_BCM_5301X || BCM63XX || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ depends on OF
-+ default ARCH_BCM4908
-+ help
-+ This option enables support for LED controller that is part of
-+ BCM63138 SoC. The same hardware block is known to be also used
-+ in BCM4908, BCM6848, BCM6858, BCM63148, BCM63381 and BCM68360.
-+
- config LEDS_LGM
- tristate "LED support for LGM SoC series"
- depends on X86 || COMPILE_TEST
---- a/drivers/leds/blink/Makefile
-+++ b/drivers/leds/blink/Makefile
-@@ -1,2 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_LEDS_BCM63138) += leds-bcm63138.o
- obj-$(CONFIG_LEDS_LGM) += leds-lgm-sso.o
---- /dev/null
-+++ b/drivers/leds/blink/leds-bcm63138.c
-@@ -0,0 +1,308 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
-+ */
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/leds.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/pinctrl/consumer.h>
-+#include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-+
-+#define BCM63138_MAX_LEDS 32
-+#define BCM63138_MAX_BRIGHTNESS 9
-+
-+#define BCM63138_LED_BITS 4 /* how many bits control a single LED */
-+#define BCM63138_LED_MASK ((1 << BCM63138_LED_BITS) - 1) /* 0xf */
-+#define BCM63138_LEDS_PER_REG (32 / BCM63138_LED_BITS) /* 8 */
-+
-+#define BCM63138_GLB_CTRL 0x00
-+#define BCM63138_GLB_CTRL_SERIAL_LED_DATA_PPOL 0x00000002
-+#define BCM63138_GLB_CTRL_SERIAL_LED_EN_POL 0x00000008
-+#define BCM63138_MASK 0x04
-+#define BCM63138_HW_LED_EN 0x08
-+#define BCM63138_SERIAL_LED_SHIFT_SEL 0x0c
-+#define BCM63138_FLASH_RATE_CTRL1 0x10
-+#define BCM63138_FLASH_RATE_CTRL2 0x14
-+#define BCM63138_FLASH_RATE_CTRL3 0x18
-+#define BCM63138_FLASH_RATE_CTRL4 0x1c
-+#define BCM63138_BRIGHT_CTRL1 0x20
-+#define BCM63138_BRIGHT_CTRL2 0x24
-+#define BCM63138_BRIGHT_CTRL3 0x28
-+#define BCM63138_BRIGHT_CTRL4 0x2c
-+#define BCM63138_POWER_LED_CFG 0x30
-+#define BCM63138_HW_POLARITY 0xb4
-+#define BCM63138_SW_DATA 0xb8
-+#define BCM63138_SW_POLARITY 0xbc
-+#define BCM63138_PARALLEL_LED_POLARITY 0xc0
-+#define BCM63138_SERIAL_LED_POLARITY 0xc4
-+#define BCM63138_HW_LED_STATUS 0xc8
-+#define BCM63138_FLASH_CTRL_STATUS 0xcc
-+#define BCM63138_FLASH_BRT_CTRL 0xd0
-+#define BCM63138_FLASH_P_LED_OUT_STATUS 0xd4
-+#define BCM63138_FLASH_S_LED_OUT_STATUS 0xd8
-+
-+struct bcm63138_leds {
-+ struct device *dev;
-+ void __iomem *base;
-+ spinlock_t lock;
-+};
-+
-+struct bcm63138_led {
-+ struct bcm63138_leds *leds;
-+ struct led_classdev cdev;
-+ u32 pin;
-+ bool active_low;
-+};
-+
-+/*
-+ * I/O access
-+ */
-+
-+static void bcm63138_leds_write(struct bcm63138_leds *leds, unsigned int reg,
-+ u32 data)
-+{
-+ writel(data, leds->base + reg);
-+}
-+
-+static unsigned long bcm63138_leds_read(struct bcm63138_leds *leds,
-+ unsigned int reg)
-+{
-+ return readl(leds->base + reg);
-+}
-+
-+static void bcm63138_leds_update_bits(struct bcm63138_leds *leds,
-+ unsigned int reg, u32 mask, u32 val)
-+{
-+ WARN_ON(val & ~mask);
-+
-+ bcm63138_leds_write(leds, reg, (bcm63138_leds_read(leds, reg) & ~mask) | (val & mask));
-+}
-+
-+/*
-+ * Helpers
-+ */
-+
-+static void bcm63138_leds_set_flash_rate(struct bcm63138_leds *leds,
-+ struct bcm63138_led *led,
-+ u8 value)
-+{
-+ int reg_offset = (led->pin >> fls((BCM63138_LEDS_PER_REG - 1))) * 4;
-+ int shift = (led->pin & (BCM63138_LEDS_PER_REG - 1)) * BCM63138_LED_BITS;
-+
-+ bcm63138_leds_update_bits(leds, BCM63138_FLASH_RATE_CTRL1 + reg_offset,
-+ BCM63138_LED_MASK << shift, value << shift);
-+}
-+
-+static void bcm63138_leds_set_bright(struct bcm63138_leds *leds,
-+ struct bcm63138_led *led,
-+ u8 value)
-+{
-+ int reg_offset = (led->pin >> fls((BCM63138_LEDS_PER_REG - 1))) * 4;
-+ int shift = (led->pin & (BCM63138_LEDS_PER_REG - 1)) * BCM63138_LED_BITS;
-+
-+ bcm63138_leds_update_bits(leds, BCM63138_BRIGHT_CTRL1 + reg_offset,
-+ BCM63138_LED_MASK << shift, value << shift);
-+}
-+
-+static void bcm63138_leds_enable_led(struct bcm63138_leds *leds,
-+ struct bcm63138_led *led,
-+ enum led_brightness value)
-+{
-+ u32 bit = BIT(led->pin);
-+
-+ bcm63138_leds_update_bits(leds, BCM63138_SW_DATA, bit,
-+ value == LED_OFF ? 0 : bit);
-+}
-+
-+/*
-+ * API callbacks
-+ */
-+
-+static void bcm63138_leds_brightness_set(struct led_classdev *led_cdev,
-+ enum led_brightness value)
-+{
-+ struct bcm63138_led *led = container_of(led_cdev, struct bcm63138_led, cdev);
-+ struct bcm63138_leds *leds = led->leds;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&leds->lock, flags);
-+
-+ bcm63138_leds_enable_led(leds, led, value);
-+ if (!value)
-+ bcm63138_leds_set_flash_rate(leds, led, 0);
-+ else
-+ bcm63138_leds_set_bright(leds, led, value);
-+
-+ spin_unlock_irqrestore(&leds->lock, flags);
-+}
-+
-+static int bcm63138_leds_blink_set(struct led_classdev *led_cdev,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct bcm63138_led *led = container_of(led_cdev, struct bcm63138_led, cdev);
-+ struct bcm63138_leds *leds = led->leds;
-+ unsigned long flags;
-+ u8 value;
-+
-+ if (!*delay_on && !*delay_off) {
-+ *delay_on = 640;
-+ *delay_off = 640;
-+ }
-+
-+ if (*delay_on != *delay_off) {
-+ dev_dbg(led_cdev->dev, "Blinking at unequal delays is not supported\n");
-+ return -EINVAL;
-+ }
-+
-+ switch (*delay_on) {
-+ case 1152 ... 1408: /* 1280 ms ± 10% */
-+ value = 0x7;
-+ break;
-+ case 576 ... 704: /* 640 ms ± 10% */
-+ value = 0x6;
-+ break;
-+ case 288 ... 352: /* 320 ms ± 10% */
-+ value = 0x5;
-+ break;
-+ case 126 ... 154: /* 140 ms ± 10% */
-+ value = 0x4;
-+ break;
-+ case 59 ... 72: /* 65 ms ± 10% */
-+ value = 0x3;
-+ break;
-+ default:
-+ dev_dbg(led_cdev->dev, "Blinking delay value %lu is unsupported\n",
-+ *delay_on);
-+ return -EINVAL;
-+ }
-+
-+ spin_lock_irqsave(&leds->lock, flags);
-+
-+ bcm63138_leds_enable_led(leds, led, BCM63138_MAX_BRIGHTNESS);
-+ bcm63138_leds_set_flash_rate(leds, led, value);
-+
-+ spin_unlock_irqrestore(&leds->lock, flags);
-+
-+ return 0;
-+}
-+
-+/*
-+ * LED driver
-+ */
-+
-+static void bcm63138_leds_create_led(struct bcm63138_leds *leds,
-+ struct device_node *np)
-+{
-+ struct led_init_data init_data = {
-+ .fwnode = of_fwnode_handle(np),
-+ };
-+ struct device *dev = leds->dev;
-+ struct bcm63138_led *led;
-+ struct pinctrl *pinctrl;
-+ u32 bit;
-+ int err;
-+
-+ led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
-+ if (!led) {
-+ dev_err(dev, "Failed to alloc LED\n");
-+ return;
-+ }
-+
-+ led->leds = leds;
-+
-+ if (of_property_read_u32(np, "reg", &led->pin)) {
-+ dev_err(dev, "Missing \"reg\" property in %pOF\n", np);
-+ goto err_free;
-+ }
-+
-+ if (led->pin >= BCM63138_MAX_LEDS) {
-+ dev_err(dev, "Invalid \"reg\" value %d\n", led->pin);
-+ goto err_free;
-+ }
-+
-+ led->active_low = of_property_read_bool(np, "active-low");
-+
-+ led->cdev.max_brightness = BCM63138_MAX_BRIGHTNESS;
-+ led->cdev.brightness_set = bcm63138_leds_brightness_set;
-+ led->cdev.blink_set = bcm63138_leds_blink_set;
-+
-+ err = devm_led_classdev_register_ext(dev, &led->cdev, &init_data);
-+ if (err) {
-+ dev_err(dev, "Failed to register LED %pOF: %d\n", np, err);
-+ goto err_free;
-+ }
-+
-+ pinctrl = devm_pinctrl_get_select_default(led->cdev.dev);
-+ if (IS_ERR(pinctrl) && PTR_ERR(pinctrl) != -ENODEV) {
-+ dev_warn(led->cdev.dev, "Failed to select %pOF pinctrl: %ld\n",
-+ np, PTR_ERR(pinctrl));
-+ }
-+
-+ bit = BIT(led->pin);
-+ bcm63138_leds_update_bits(leds, BCM63138_PARALLEL_LED_POLARITY, bit,
-+ led->active_low ? 0 : bit);
-+ bcm63138_leds_update_bits(leds, BCM63138_HW_LED_EN, bit, 0);
-+ bcm63138_leds_set_flash_rate(leds, led, 0);
-+ bcm63138_leds_enable_led(leds, led, led->cdev.brightness);
-+
-+ return;
-+
-+err_free:
-+ devm_kfree(dev, led);
-+}
-+
-+static int bcm63138_leds_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = dev_of_node(&pdev->dev);
-+ struct device *dev = &pdev->dev;
-+ struct bcm63138_leds *leds;
-+ struct device_node *child;
-+
-+ leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
-+ if (!leds)
-+ return -ENOMEM;
-+
-+ leds->dev = dev;
-+
-+ leds->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(leds->base))
-+ return PTR_ERR(leds->base);
-+
-+ spin_lock_init(&leds->lock);
-+
-+ bcm63138_leds_write(leds, BCM63138_GLB_CTRL,
-+ BCM63138_GLB_CTRL_SERIAL_LED_DATA_PPOL |
-+ BCM63138_GLB_CTRL_SERIAL_LED_EN_POL);
-+ bcm63138_leds_write(leds, BCM63138_HW_LED_EN, 0);
-+ bcm63138_leds_write(leds, BCM63138_SERIAL_LED_POLARITY, 0);
-+ bcm63138_leds_write(leds, BCM63138_PARALLEL_LED_POLARITY, 0);
-+
-+ for_each_available_child_of_node(np, child) {
-+ bcm63138_leds_create_led(leds, child);
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id bcm63138_leds_of_match_table[] = {
-+ { .compatible = "brcm,bcm63138-leds", },
-+ { },
-+};
-+
-+static struct platform_driver bcm63138_leds_driver = {
-+ .probe = bcm63138_leds_probe,
-+ .driver = {
-+ .name = "leds-bcm63xxx",
-+ .of_match_table = bcm63138_leds_of_match_table,
-+ },
-+};
-+
-+module_platform_driver(bcm63138_leds_driver);
-+
-+MODULE_AUTHOR("Rafał Miłecki");
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(of, bcm63138_leds_of_match_table);
diff --git a/target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch b/target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch
deleted file mode 100644
index 483826abed..0000000000
--- a/target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 13b64a0c19059b38150c79d65d350ae44034c5df Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 17 Jul 2022 14:42:46 +0200
-Subject: [PATCH] dt-bindings: leds: leds-bcm63138: unify full stops in
- descriptions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Description of "reg" doesn't have full stop at the end. It makes sense
-as it's a one-sentence only. Use the same style for "active-low".
-
-Reported-by: Pavel Machek <pavel@ucw.cz>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Pavel Machek <pavel@ucw.cz>
----
- Documentation/devicetree/bindings/leds/leds-bcm63138.yaml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/leds/leds-bcm63138.yaml
-+++ b/Documentation/devicetree/bindings/leds/leds-bcm63138.yaml
-@@ -54,7 +54,7 @@ patternProperties:
-
- active-low:
- type: boolean
-- description: Makes LED active low.
-+ description: Makes LED active low
-
- required:
- - reg
diff --git a/target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch b/target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch
deleted file mode 100644
index 5430b1f084..0000000000
--- a/target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From bcc607cdbb1f931111196699426f0cb83bfb296a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 17 Jul 2022 14:42:47 +0200
-Subject: [PATCH] leds: add help info about BCM63138 module name
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's what we do for all other LEDs drivers.
-
-Reported-by: Pavel Machek <pavel@ucw.cz>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Pavel Machek <pavel@ucw.cz>
----
- drivers/leds/blink/Kconfig | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/leds/blink/Kconfig
-+++ b/drivers/leds/blink/Kconfig
-@@ -10,6 +10,8 @@ config LEDS_BCM63138
- BCM63138 SoC. The same hardware block is known to be also used
- in BCM4908, BCM6848, BCM6858, BCM63148, BCM63381 and BCM68360.
-
-+ If compiled as module it will be called leds-bcm63138.
-+
- config LEDS_LGM
- tristate "LED support for LGM SoC series"
- depends on X86 || COMPILE_TEST
diff --git a/target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch b/target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch
deleted file mode 100644
index e125a54613..0000000000
--- a/target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 92cfc71ee2ddfb499ed53e21b28bdf8739bc70bc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 17 Jul 2022 14:42:48 +0200
-Subject: [PATCH] leds: leds-bcm63138: get rid of LED_OFF
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The whole "enum led_brightness" is marked as obsolete. Replace it with a
-(non-)zero check.
-
-Reported-by: Pavel Machek <pavel@ucw.cz>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Pavel Machek <pavel@ucw.cz>
----
- drivers/leds/blink/leds-bcm63138.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/leds/blink/leds-bcm63138.c
-+++ b/drivers/leds/blink/leds-bcm63138.c
-@@ -113,8 +113,7 @@ static void bcm63138_leds_enable_led(str
- {
- u32 bit = BIT(led->pin);
-
-- bcm63138_leds_update_bits(leds, BCM63138_SW_DATA, bit,
-- value == LED_OFF ? 0 : bit);
-+ bcm63138_leds_update_bits(leds, BCM63138_SW_DATA, bit, value ? bit : 0);
- }
-
- /*
diff --git a/target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch b/target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch
deleted file mode 100644
index ebab8c7c73..0000000000
--- a/target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch
+++ /dev/null
@@ -1,456 +0,0 @@
-From 7ae6478b304bc004c3139b422665b0e23b57f05c Mon Sep 17 00:00:00 2001
-From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Date: Wed, 13 Oct 2021 14:19:55 +0100
-Subject: [PATCH] nvmem: core: rework nvmem cell instance creation
-
-In the existing design, we do not create a instance per nvmem cell consumer
-but we directly refer cell from nvmem cell list that are added to provider.
-
-However this design has some limitations when consumers want to assign name
-or connection id the nvmem cell instance, ex: via "nvmem-cell-names" or
-id in nvmem_cell_get(id).
-
-Having a name associated with nvmem cell consumer instance will help
-provider drivers in performing post processing of nvmem cell data if required
-before data is seen by the consumers. This is pretty normal with some vendors
-storing nvmem cells like mac-address in a vendor specific data layouts that
-are not directly usable by the consumer drivers.
-
-With this patch nvmem cell will be created dynamically during nvmem_cell_get
-and destroyed in nvmem_cell_put, allowing consumers to associate name with
-nvmem cell consumer instance.
-
-With this patch a new struct nvmem_cell_entry replaces struct nvmem_cell
-for storing nvmem cell information within the core.
-This patch does not change nvmem-consumer interface based on nvmem_cell.
-
-Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20211013131957.30271-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 165 +++++++++++++++++++++++++++----------------
- 1 file changed, 105 insertions(+), 60 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -45,8 +45,7 @@ struct nvmem_device {
- #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
-
- #define FLAG_COMPAT BIT(0)
--
--struct nvmem_cell {
-+struct nvmem_cell_entry {
- const char *name;
- int offset;
- int bytes;
-@@ -57,6 +56,11 @@ struct nvmem_cell {
- struct list_head node;
- };
-
-+struct nvmem_cell {
-+ struct nvmem_cell_entry *entry;
-+ const char *id;
-+};
-+
- static DEFINE_MUTEX(nvmem_mutex);
- static DEFINE_IDA(nvmem_ida);
-
-@@ -424,7 +428,7 @@ static struct bus_type nvmem_bus_type =
- .name = "nvmem",
- };
-
--static void nvmem_cell_drop(struct nvmem_cell *cell)
-+static void nvmem_cell_entry_drop(struct nvmem_cell_entry *cell)
- {
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell);
- mutex_lock(&nvmem_mutex);
-@@ -437,13 +441,13 @@ static void nvmem_cell_drop(struct nvmem
-
- static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem)
- {
-- struct nvmem_cell *cell, *p;
-+ struct nvmem_cell_entry *cell, *p;
-
- list_for_each_entry_safe(cell, p, &nvmem->cells, node)
-- nvmem_cell_drop(cell);
-+ nvmem_cell_entry_drop(cell);
- }
-
--static void nvmem_cell_add(struct nvmem_cell *cell)
-+static void nvmem_cell_entry_add(struct nvmem_cell_entry *cell)
- {
- mutex_lock(&nvmem_mutex);
- list_add_tail(&cell->node, &cell->nvmem->cells);
-@@ -451,9 +455,9 @@ static void nvmem_cell_add(struct nvmem_
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell);
- }
-
--static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem,
-- const struct nvmem_cell_info *info,
-- struct nvmem_cell *cell)
-+static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info,
-+ struct nvmem_cell_entry *cell)
- {
- cell->nvmem = nvmem;
- cell->offset = info->offset;
-@@ -477,13 +481,13 @@ static int nvmem_cell_info_to_nvmem_cell
- return 0;
- }
-
--static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
-- const struct nvmem_cell_info *info,
-- struct nvmem_cell *cell)
-+static int nvmem_cell_info_to_nvmem_cell_entry(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info,
-+ struct nvmem_cell_entry *cell)
- {
- int err;
-
-- err = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, cell);
-+ err = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, cell);
- if (err)
- return err;
-
-@@ -507,7 +511,7 @@ static int nvmem_add_cells(struct nvmem_
- const struct nvmem_cell_info *info,
- int ncells)
- {
-- struct nvmem_cell **cells;
-+ struct nvmem_cell_entry **cells;
- int i, rval;
-
- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
-@@ -521,13 +525,13 @@ static int nvmem_add_cells(struct nvmem_
- goto err;
- }
-
-- rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]);
-+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
- if (rval) {
- kfree(cells[i]);
- goto err;
- }
-
-- nvmem_cell_add(cells[i]);
-+ nvmem_cell_entry_add(cells[i]);
- }
-
- /* remove tmp array */
-@@ -536,7 +540,7 @@ static int nvmem_add_cells(struct nvmem_
- return 0;
- err:
- while (i--)
-- nvmem_cell_drop(cells[i]);
-+ nvmem_cell_entry_drop(cells[i]);
-
- kfree(cells);
-
-@@ -573,7 +577,7 @@ static int nvmem_add_cells_from_table(st
- {
- const struct nvmem_cell_info *info;
- struct nvmem_cell_table *table;
-- struct nvmem_cell *cell;
-+ struct nvmem_cell_entry *cell;
- int rval = 0, i;
-
- mutex_lock(&nvmem_cell_mutex);
-@@ -588,15 +592,13 @@ static int nvmem_add_cells_from_table(st
- goto out;
- }
-
-- rval = nvmem_cell_info_to_nvmem_cell(nvmem,
-- info,
-- cell);
-+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell);
- if (rval) {
- kfree(cell);
- goto out;
- }
-
-- nvmem_cell_add(cell);
-+ nvmem_cell_entry_add(cell);
- }
- }
- }
-@@ -606,10 +608,10 @@ out:
- return rval;
- }
-
--static struct nvmem_cell *
--nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id)
-+static struct nvmem_cell_entry *
-+nvmem_find_cell_entry_by_name(struct nvmem_device *nvmem, const char *cell_id)
- {
-- struct nvmem_cell *iter, *cell = NULL;
-+ struct nvmem_cell_entry *iter, *cell = NULL;
-
- mutex_lock(&nvmem_mutex);
- list_for_each_entry(iter, &nvmem->cells, node) {
-@@ -680,7 +682,7 @@ static int nvmem_add_cells_from_of(struc
- {
- struct device_node *parent, *child;
- struct device *dev = &nvmem->dev;
-- struct nvmem_cell *cell;
-+ struct nvmem_cell_entry *cell;
- const __be32 *addr;
- int len;
-
-@@ -729,7 +731,7 @@ static int nvmem_add_cells_from_of(struc
- }
-
- cell->np = of_node_get(child);
-- nvmem_cell_add(cell);
-+ nvmem_cell_entry_add(cell);
- }
-
- return 0;
-@@ -1142,9 +1144,33 @@ struct nvmem_device *devm_nvmem_device_g
- }
- EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
-
-+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id)
-+{
-+ struct nvmem_cell *cell;
-+ const char *name = NULL;
-+
-+ cell = kzalloc(sizeof(*cell), GFP_KERNEL);
-+ if (!cell)
-+ return ERR_PTR(-ENOMEM);
-+
-+ if (id) {
-+ name = kstrdup_const(id, GFP_KERNEL);
-+ if (!name) {
-+ kfree(cell);
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ }
-+
-+ cell->id = name;
-+ cell->entry = entry;
-+
-+ return cell;
-+}
-+
- static struct nvmem_cell *
- nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
- {
-+ struct nvmem_cell_entry *cell_entry;
- struct nvmem_cell *cell = ERR_PTR(-ENOENT);
- struct nvmem_cell_lookup *lookup;
- struct nvmem_device *nvmem;
-@@ -1169,11 +1195,15 @@ nvmem_cell_get_from_lookup(struct device
- break;
- }
-
-- cell = nvmem_find_cell_by_name(nvmem,
-- lookup->cell_name);
-- if (!cell) {
-+ cell_entry = nvmem_find_cell_entry_by_name(nvmem,
-+ lookup->cell_name);
-+ if (!cell_entry) {
- __nvmem_device_put(nvmem);
- cell = ERR_PTR(-ENOENT);
-+ } else {
-+ cell = nvmem_create_cell(cell_entry, con_id);
-+ if (IS_ERR(cell))
-+ __nvmem_device_put(nvmem);
- }
- break;
- }
-@@ -1184,10 +1214,10 @@ nvmem_cell_get_from_lookup(struct device
- }
-
- #if IS_ENABLED(CONFIG_OF)
--static struct nvmem_cell *
--nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
-+static struct nvmem_cell_entry *
-+nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np)
- {
-- struct nvmem_cell *iter, *cell = NULL;
-+ struct nvmem_cell_entry *iter, *cell = NULL;
-
- mutex_lock(&nvmem_mutex);
- list_for_each_entry(iter, &nvmem->cells, node) {
-@@ -1217,6 +1247,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
- {
- struct device_node *cell_np, *nvmem_np;
- struct nvmem_device *nvmem;
-+ struct nvmem_cell_entry *cell_entry;
- struct nvmem_cell *cell;
- int index = 0;
-
-@@ -1237,12 +1268,16 @@ struct nvmem_cell *of_nvmem_cell_get(str
- if (IS_ERR(nvmem))
- return ERR_CAST(nvmem);
-
-- cell = nvmem_find_cell_by_node(nvmem, cell_np);
-- if (!cell) {
-+ cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
-+ if (!cell_entry) {
- __nvmem_device_put(nvmem);
- return ERR_PTR(-ENOENT);
- }
-
-+ cell = nvmem_create_cell(cell_entry, id);
-+ if (IS_ERR(cell))
-+ __nvmem_device_put(nvmem);
-+
- return cell;
- }
- EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
-@@ -1348,13 +1383,17 @@ EXPORT_SYMBOL(devm_nvmem_cell_put);
- */
- void nvmem_cell_put(struct nvmem_cell *cell)
- {
-- struct nvmem_device *nvmem = cell->nvmem;
-+ struct nvmem_device *nvmem = cell->entry->nvmem;
-+
-+ if (cell->id)
-+ kfree_const(cell->id);
-
-+ kfree(cell);
- __nvmem_device_put(nvmem);
- }
- EXPORT_SYMBOL_GPL(nvmem_cell_put);
-
--static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf)
-+static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void *buf)
- {
- u8 *p, *b;
- int i, extra, bit_offset = cell->bit_offset;
-@@ -1388,8 +1427,8 @@ static void nvmem_shift_read_buffer_in_p
- }
-
- static int __nvmem_cell_read(struct nvmem_device *nvmem,
-- struct nvmem_cell *cell,
-- void *buf, size_t *len)
-+ struct nvmem_cell_entry *cell,
-+ void *buf, size_t *len, const char *id)
- {
- int rc;
-
-@@ -1420,18 +1459,18 @@ static int __nvmem_cell_read(struct nvme
- */
- void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
- {
-- struct nvmem_device *nvmem = cell->nvmem;
-+ struct nvmem_device *nvmem = cell->entry->nvmem;
- u8 *buf;
- int rc;
-
- if (!nvmem)
- return ERR_PTR(-EINVAL);
-
-- buf = kzalloc(cell->bytes, GFP_KERNEL);
-+ buf = kzalloc(cell->entry->bytes, GFP_KERNEL);
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
-- rc = __nvmem_cell_read(nvmem, cell, buf, len);
-+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id);
- if (rc) {
- kfree(buf);
- return ERR_PTR(rc);
-@@ -1441,7 +1480,7 @@ void *nvmem_cell_read(struct nvmem_cell
- }
- EXPORT_SYMBOL_GPL(nvmem_cell_read);
-
--static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell,
-+static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell_entry *cell,
- u8 *_buf, int len)
- {
- struct nvmem_device *nvmem = cell->nvmem;
-@@ -1494,16 +1533,7 @@ err:
- return ERR_PTR(rc);
- }
-
--/**
-- * nvmem_cell_write() - Write to a given nvmem cell
-- *
-- * @cell: nvmem cell to be written.
-- * @buf: Buffer to be written.
-- * @len: length of buffer to be written to nvmem cell.
-- *
-- * Return: length of bytes written or negative on failure.
-- */
--int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
-+static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, size_t len)
- {
- struct nvmem_device *nvmem = cell->nvmem;
- int rc;
-@@ -1529,6 +1559,21 @@ int nvmem_cell_write(struct nvmem_cell *
-
- return len;
- }
-+
-+/**
-+ * nvmem_cell_write() - Write to a given nvmem cell
-+ *
-+ * @cell: nvmem cell to be written.
-+ * @buf: Buffer to be written.
-+ * @len: length of buffer to be written to nvmem cell.
-+ *
-+ * Return: length of bytes written or negative on failure.
-+ */
-+int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
-+{
-+ return __nvmem_cell_entry_write(cell->entry, buf, len);
-+}
-+
- EXPORT_SYMBOL_GPL(nvmem_cell_write);
-
- static int nvmem_cell_read_common(struct device *dev, const char *cell_id,
-@@ -1631,7 +1676,7 @@ static const void *nvmem_cell_read_varia
- if (IS_ERR(cell))
- return cell;
-
-- nbits = cell->nbits;
-+ nbits = cell->entry->nbits;
- buf = nvmem_cell_read(cell, len);
- nvmem_cell_put(cell);
- if (IS_ERR(buf))
-@@ -1727,18 +1772,18 @@ EXPORT_SYMBOL_GPL(nvmem_cell_read_variab
- ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
- struct nvmem_cell_info *info, void *buf)
- {
-- struct nvmem_cell cell;
-+ struct nvmem_cell_entry cell;
- int rc;
- ssize_t len;
-
- if (!nvmem)
- return -EINVAL;
-
-- rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell);
-+ rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell);
- if (rc)
- return rc;
-
-- rc = __nvmem_cell_read(nvmem, &cell, buf, &len);
-+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL);
- if (rc)
- return rc;
-
-@@ -1758,17 +1803,17 @@ EXPORT_SYMBOL_GPL(nvmem_device_cell_read
- int nvmem_device_cell_write(struct nvmem_device *nvmem,
- struct nvmem_cell_info *info, void *buf)
- {
-- struct nvmem_cell cell;
-+ struct nvmem_cell_entry cell;
- int rc;
-
- if (!nvmem)
- return -EINVAL;
-
-- rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell);
-+ rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell);
- if (rc)
- return rc;
-
-- return nvmem_cell_write(&cell, buf, cell.bytes);
-+ return __nvmem_cell_entry_write(&cell, buf, cell.bytes);
- }
- EXPORT_SYMBOL_GPL(nvmem_device_cell_write);
-
diff --git a/target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch b/target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch
deleted file mode 100644
index df264add24..0000000000
--- a/target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 5008062f1c3f5af3acf86164aa6fcc77b0c7bdce Mon Sep 17 00:00:00 2001
-From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Date: Wed, 13 Oct 2021 14:19:56 +0100
-Subject: [PATCH] nvmem: core: add nvmem cell post processing callback
-
-Some NVMEM providers have certain nvmem cells encoded, which requires
-post processing before actually using it.
-
-For example mac-address is stored in either in ascii or delimited or reverse-order.
-
-Having a post-process callback hook to provider drivers would enable them to
-do this vendor specific post processing before nvmem consumers see it.
-
-Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20211013131957.30271-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 9 +++++++++
- include/linux/nvmem-provider.h | 5 +++++
- 2 files changed, 14 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -38,6 +38,7 @@ struct nvmem_device {
- unsigned int nkeepout;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
-+ nvmem_cell_post_process_t cell_post_process;
- struct gpio_desc *wp_gpio;
- void *priv;
- };
-@@ -799,6 +800,7 @@ struct nvmem_device *nvmem_register(cons
- nvmem->type = config->type;
- nvmem->reg_read = config->reg_read;
- nvmem->reg_write = config->reg_write;
-+ nvmem->cell_post_process = config->cell_post_process;
- nvmem->keepout = config->keepout;
- nvmem->nkeepout = config->nkeepout;
- if (config->of_node)
-@@ -1441,6 +1443,13 @@ static int __nvmem_cell_read(struct nvme
- if (cell->bit_offset || cell->nbits)
- nvmem_shift_read_buffer_in_place(cell, buf);
-
-+ if (nvmem->cell_post_process) {
-+ rc = nvmem->cell_post_process(nvmem->priv, id,
-+ cell->offset, buf, cell->bytes);
-+ if (rc)
-+ return rc;
-+ }
-+
- if (len)
- *len = cell->bytes;
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -19,6 +19,9 @@ typedef int (*nvmem_reg_read_t)(void *pr
- void *val, size_t bytes);
- typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
- void *val, size_t bytes);
-+/* used for vendor specific post processing of cell data */
-+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset,
-+ void *buf, size_t bytes);
-
- enum nvmem_type {
- NVMEM_TYPE_UNKNOWN = 0,
-@@ -62,6 +65,7 @@ struct nvmem_keepout {
- * @no_of_node: Device should not use the parent's of_node even if it's !NULL.
- * @reg_read: Callback to read data.
- * @reg_write: Callback to write data.
-+ * @cell_post_process: Callback for vendor specific post processing of cell data
- * @size: Device size.
- * @word_size: Minimum read/write access granularity.
- * @stride: Minimum read/write access stride.
-@@ -92,6 +96,7 @@ struct nvmem_config {
- bool no_of_node;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
-+ nvmem_cell_post_process_t cell_post_process;
- int size;
- int word_size;
- int stride;
diff --git a/target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch b/target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch
deleted file mode 100644
index ee19228270..0000000000
--- a/target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From d0221a780cbc99fec6c27a98dba2828dc5735c00 Mon Sep 17 00:00:00 2001
-From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Date: Wed, 13 Oct 2021 14:19:57 +0100
-Subject: [PATCH] nvmem: imx-ocotp: add support for post processing
-
-Add .cell_post_process callback for imx-ocotp to deal with MAC address,
-since MAC address need to be reversed byte for some i.MX SoCs.
-
-Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20211013131957.30271-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/imx-ocotp.c | 25 +++++++++++++++++++++++++
- 1 file changed, 25 insertions(+)
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -97,6 +97,7 @@ struct ocotp_params {
- unsigned int bank_address_words;
- void (*set_timing)(struct ocotp_priv *priv);
- struct ocotp_ctrl_reg ctrl;
-+ bool reverse_mac_address;
- };
-
- static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
-@@ -221,6 +222,25 @@ read_end:
- return ret;
- }
-
-+static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset,
-+ void *data, size_t bytes)
-+{
-+ struct ocotp_priv *priv = context;
-+
-+ /* Deal with some post processing of nvmem cell data */
-+ if (id && !strcmp(id, "mac-address")) {
-+ if (priv->params->reverse_mac_address) {
-+ u8 *buf = data;
-+ int i;
-+
-+ for (i = 0; i < bytes/2; i++)
-+ swap(buf[i], buf[bytes - i - 1]);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
- static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv)
- {
- unsigned long clk_rate;
-@@ -468,6 +488,7 @@ static struct nvmem_config imx_ocotp_nvm
- .stride = 1,
- .reg_read = imx_ocotp_read,
- .reg_write = imx_ocotp_write,
-+ .cell_post_process = imx_ocotp_cell_pp,
- };
-
- static const struct ocotp_params imx6q_params = {
-@@ -530,6 +551,7 @@ static const struct ocotp_params imx8mq_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-+ .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mm_params = {
-@@ -537,6 +559,7 @@ static const struct ocotp_params imx8mm_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-+ .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mn_params = {
-@@ -544,6 +567,7 @@ static const struct ocotp_params imx8mn_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-+ .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mp_params = {
-@@ -551,6 +575,7 @@ static const struct ocotp_params imx8mp_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_8MP,
-+ .reverse_mac_address = true,
- };
-
- static const struct of_device_id imx_ocotp_dt_ids[] = {
diff --git a/target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch b/target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch
deleted file mode 100644
index 785bfe53f5..0000000000
--- a/target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 98e2c4efae214fb7086cac9117616eb6ea11475d Mon Sep 17 00:00:00 2001
-From: Chunfeng Yun <chunfeng.yun@mediatek.com>
-Date: Thu, 9 Dec 2021 17:42:34 +0000
-Subject: [PATCH] nvmem: mtk-efuse: support minimum one byte access stride and
- granularity
-
-In order to support nvmem bits property, should support minimum 1 byte
-read stride and minimum 1 byte read granularity at the same time.
-
-Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20211209174235.14049-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/mtk-efuse.c | 13 +++++++------
- 1 file changed, 7 insertions(+), 6 deletions(-)
-
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -19,11 +19,12 @@ static int mtk_reg_read(void *context,
- unsigned int reg, void *_val, size_t bytes)
- {
- struct mtk_efuse_priv *priv = context;
-- u32 *val = _val;
-- int i = 0, words = bytes / 4;
-+ void __iomem *addr = priv->base + reg;
-+ u8 *val = _val;
-+ int i;
-
-- while (words--)
-- *val++ = readl(priv->base + reg + (i++ * 4));
-+ for (i = 0; i < bytes; i++, val++)
-+ *val = readb(addr + i);
-
- return 0;
- }
-@@ -45,8 +46,8 @@ static int mtk_efuse_probe(struct platfo
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
-- econfig.stride = 4;
-- econfig.word_size = 4;
-+ econfig.stride = 1;
-+ econfig.word_size = 1;
- econfig.reg_read = mtk_reg_read;
- econfig.size = resource_size(res);
- econfig.priv = priv;
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch b/target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch
deleted file mode 100644
index ca5357c8d9..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 190fae468592bc2f0efc8b928920f8f712b5831e Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Sun, 20 Feb 2022 15:15:15 +0000
-Subject: [PATCH] nvmem: core: Remove unused devm_nvmem_unregister()
-
-There are no users and seems no will come of the devm_nvmem_unregister().
-Remove the function and remove the unused devm_nvmem_match() along with it.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220220151527.17216-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 22 ----------------------
- include/linux/nvmem-provider.h | 8 --------
- 2 files changed, 30 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -943,28 +943,6 @@ struct nvmem_device *devm_nvmem_register
- }
- EXPORT_SYMBOL_GPL(devm_nvmem_register);
-
--static int devm_nvmem_match(struct device *dev, void *res, void *data)
--{
-- struct nvmem_device **r = res;
--
-- return *r == data;
--}
--
--/**
-- * devm_nvmem_unregister() - Unregister previously registered managed nvmem
-- * device.
-- *
-- * @dev: Device that uses the nvmem device.
-- * @nvmem: Pointer to previously registered nvmem device.
-- *
-- * Return: Will be negative on error or zero on success.
-- */
--int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
--{
-- return devres_release(dev, devm_nvmem_release, devm_nvmem_match, nvmem);
--}
--EXPORT_SYMBOL(devm_nvmem_unregister);
--
- static struct nvmem_device *__nvmem_device_get(void *data,
- int (*match)(struct device *dev, const void *data))
- {
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -133,8 +133,6 @@ void nvmem_unregister(struct nvmem_devic
- struct nvmem_device *devm_nvmem_register(struct device *dev,
- const struct nvmem_config *cfg);
-
--int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem);
--
- void nvmem_add_cell_table(struct nvmem_cell_table *table);
- void nvmem_del_cell_table(struct nvmem_cell_table *table);
-
-@@ -153,12 +151,6 @@ devm_nvmem_register(struct device *dev,
- return nvmem_register(c);
- }
-
--static inline int
--devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
--{
-- return -EOPNOTSUPP;
--}
--
- static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {}
- static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {}
-
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch b/target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch
deleted file mode 100644
index b71a0a365b..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 5825b2c6762611e67ccaf3ccf64485365a120f0b Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Sun, 20 Feb 2022 15:15:16 +0000
-Subject: [PATCH] nvmem: core: Use devm_add_action_or_reset()
-
-Slightly simplify the devm_nvmem_register() by using the
-devm_add_action_or_reset().
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220220151527.17216-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 22 +++++++++-------------
- 1 file changed, 9 insertions(+), 13 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -905,9 +905,9 @@ void nvmem_unregister(struct nvmem_devic
- }
- EXPORT_SYMBOL_GPL(nvmem_unregister);
-
--static void devm_nvmem_release(struct device *dev, void *res)
-+static void devm_nvmem_unregister(void *nvmem)
- {
-- nvmem_unregister(*(struct nvmem_device **)res);
-+ nvmem_unregister(nvmem);
- }
-
- /**
-@@ -924,20 +924,16 @@ static void devm_nvmem_release(struct de
- struct nvmem_device *devm_nvmem_register(struct device *dev,
- const struct nvmem_config *config)
- {
-- struct nvmem_device **ptr, *nvmem;
--
-- ptr = devres_alloc(devm_nvmem_release, sizeof(*ptr), GFP_KERNEL);
-- if (!ptr)
-- return ERR_PTR(-ENOMEM);
-+ struct nvmem_device *nvmem;
-+ int ret;
-
- nvmem = nvmem_register(config);
-+ if (IS_ERR(nvmem))
-+ return nvmem;
-
-- if (!IS_ERR(nvmem)) {
-- *ptr = nvmem;
-- devres_add(dev, ptr);
-- } else {
-- devres_free(ptr);
-- }
-+ ret = devm_add_action_or_reset(dev, devm_nvmem_unregister, nvmem);
-+ if (ret)
-+ return ERR_PTR(ret);
-
- return nvmem;
- }
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch b/target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch
deleted file mode 100644
index 4f471f2667..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8c751e0d9a5264376935a84429a2d468c8877d99 Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Sun, 20 Feb 2022 15:15:17 +0000
-Subject: [PATCH] nvmem: core: Check input parameter for NULL in
- nvmem_unregister()
-
-nvmem_unregister() frees resources and standard pattern is to allow
-caller to not care if it's NULL or not. This will reduce burden on
-the callers to perform this check.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220220151527.17216-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -901,7 +901,8 @@ static void nvmem_device_release(struct
- */
- void nvmem_unregister(struct nvmem_device *nvmem)
- {
-- kref_put(&nvmem->refcnt, nvmem_device_release);
-+ if (nvmem)
-+ kref_put(&nvmem->refcnt, nvmem_device_release);
- }
- EXPORT_SYMBOL_GPL(nvmem_unregister);
-
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch b/target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch
deleted file mode 100644
index c98f8e9d54..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 05196facc052385960028ac634447ecf6c764ec3 Mon Sep 17 00:00:00 2001
-From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Date: Sun, 20 Feb 2022 15:15:18 +0000
-Subject: [PATCH] nvmem: qfprom: fix kerneldoc warning
-
-This patch fixes below kernel doc warning,
-warning: expecting prototype for qfprom_efuse_reg_write().
-Prototype was for qfprom_reg_write() instead
-
-No code changes.
-
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220220151527.17216-5-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qfprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -244,7 +244,7 @@ err_clk_prepared:
- }
-
- /**
-- * qfprom_efuse_reg_write() - Write to fuses.
-+ * qfprom_reg_write() - Write to fuses.
- * @context: Our driver data.
- * @reg: The offset to write at.
- * @_val: Pointer to data to write.
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch b/target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch
deleted file mode 100644
index 6aad6af080..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 07ae4fde9efada7878e1383d6ccc7da70315ca23 Mon Sep 17 00:00:00 2001
-From: Samuel Holland <samuel@sholland.org>
-Date: Sun, 20 Feb 2022 15:15:20 +0000
-Subject: [PATCH] nvmem: sunxi_sid: Add support for D1 variant
-
-D1 has a smaller eFuse block than some other recent SoCs, and it no
-longer requires a workaround to read the eFuse data.
-
-Signed-off-by: Samuel Holland <samuel@sholland.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220220151527.17216-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/sunxi_sid.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/nvmem/sunxi_sid.c
-+++ b/drivers/nvmem/sunxi_sid.c
-@@ -184,6 +184,11 @@ static const struct sunxi_sid_cfg sun8i_
- .need_register_readout = true,
- };
-
-+static const struct sunxi_sid_cfg sun20i_d1_cfg = {
-+ .value_offset = 0x200,
-+ .size = 0x100,
-+};
-+
- static const struct sunxi_sid_cfg sun50i_a64_cfg = {
- .value_offset = 0x200,
- .size = 0x100,
-@@ -200,6 +205,7 @@ static const struct of_device_id sunxi_s
- { .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg },
- { .compatible = "allwinner,sun8i-a83t-sid", .data = &sun50i_a64_cfg },
- { .compatible = "allwinner,sun8i-h3-sid", .data = &sun8i_h3_cfg },
-+ { .compatible = "allwinner,sun20i-d1-sid", .data = &sun20i_d1_cfg },
- { .compatible = "allwinner,sun50i-a64-sid", .data = &sun50i_a64_cfg },
- { .compatible = "allwinner,sun50i-h5-sid", .data = &sun50i_a64_cfg },
- { .compatible = "allwinner,sun50i-h6-sid", .data = &sun50i_h6_cfg },
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch b/target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch
deleted file mode 100644
index a73b42c5de..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 4dc8d89faed9bb05f116fa1794fc955b14910386 Mon Sep 17 00:00:00 2001
-From: Xiaoke Wang <xkernel.wang@foxmail.com>
-Date: Sun, 20 Feb 2022 15:15:21 +0000
-Subject: [PATCH] nvmem: meson-mx-efuse: replace unnecessary devm_kstrdup()
-
-Replace unnecessary devm_kstrdup() so to avoid redundant memory allocation.
-
-Suggested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220220151527.17216-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/meson-mx-efuse.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/meson-mx-efuse.c
-+++ b/drivers/nvmem/meson-mx-efuse.c
-@@ -209,8 +209,7 @@ static int meson_mx_efuse_probe(struct p
- if (IS_ERR(efuse->base))
- return PTR_ERR(efuse->base);
-
-- efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name,
-- GFP_KERNEL);
-+ efuse->config.name = drvdata->name;
- efuse->config.owner = THIS_MODULE;
- efuse->config.dev = &pdev->dev;
- efuse->config.priv = efuse;
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch b/target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch
deleted file mode 100644
index 6afb68b3f9..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From f78451012b9e159afdba31c3eb69f223a9f42adc Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Sun, 20 Feb 2022 15:15:23 +0000
-Subject: [PATCH] nvmem: add driver for Layerscape SFP (Security Fuse
- Processor)
-
-Add support for the Security Fuse Processor found on Layerscape SoCs.
-This driver implements basic read access.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220220151527.17216-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 12 +++++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/layerscape-sfp.c | 89 ++++++++++++++++++++++++++++++++++
- 3 files changed, 103 insertions(+)
- create mode 100644 drivers/nvmem/layerscape-sfp.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -300,4 +300,16 @@ config NVMEM_BRCM_NVRAM
- This driver provides support for Broadcom's NVRAM that can be accessed
- using I/O mapping.
-
-+config NVMEM_LAYERSCAPE_SFP
-+ tristate "Layerscape SFP (Security Fuse Processor) support"
-+ depends on ARCH_LAYERSCAPE || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This driver provides support to read the eFuses on Freescale
-+ Layerscape SoC's. For example, the vendor provides a per part
-+ unique ID there.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called layerscape-sfp.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.
- nvmem-rmem-y := rmem.o
- obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o
- nvmem_brcm_nvram-y := brcm_nvram.o
-+obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o
-+nvmem-layerscape-sfp-y := layerscape-sfp.o
---- /dev/null
-+++ b/drivers/nvmem/layerscape-sfp.c
-@@ -0,0 +1,89 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Layerscape SFP driver
-+ *
-+ * Copyright (c) 2022 Michael Walle <michael@walle.cc>
-+ *
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/platform_device.h>
-+#include <linux/property.h>
-+
-+#define LAYERSCAPE_SFP_OTP_OFFSET 0x0200
-+
-+struct layerscape_sfp_priv {
-+ void __iomem *base;
-+};
-+
-+struct layerscape_sfp_data {
-+ int size;
-+};
-+
-+static int layerscape_sfp_read(void *context, unsigned int offset, void *val,
-+ size_t bytes)
-+{
-+ struct layerscape_sfp_priv *priv = context;
-+
-+ memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset,
-+ bytes);
-+
-+ return 0;
-+}
-+
-+static struct nvmem_config layerscape_sfp_nvmem_config = {
-+ .name = "fsl-sfp",
-+ .reg_read = layerscape_sfp_read,
-+};
-+
-+static int layerscape_sfp_probe(struct platform_device *pdev)
-+{
-+ const struct layerscape_sfp_data *data;
-+ struct layerscape_sfp_priv *priv;
-+ struct nvmem_device *nvmem;
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ data = device_get_match_data(&pdev->dev);
-+
-+ layerscape_sfp_nvmem_config.size = data->size;
-+ layerscape_sfp_nvmem_config.dev = &pdev->dev;
-+ layerscape_sfp_nvmem_config.priv = priv;
-+
-+ nvmem = devm_nvmem_register(&pdev->dev, &layerscape_sfp_nvmem_config);
-+
-+ return PTR_ERR_OR_ZERO(nvmem);
-+}
-+
-+static const struct layerscape_sfp_data ls1028a_data = {
-+ .size = 0x88,
-+};
-+
-+static const struct of_device_id layerscape_sfp_dt_ids[] = {
-+ { .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, layerscape_sfp_dt_ids);
-+
-+static struct platform_driver layerscape_sfp_driver = {
-+ .probe = layerscape_sfp_probe,
-+ .driver = {
-+ .name = "layerscape_sfp",
-+ .of_match_table = layerscape_sfp_dt_ids,
-+ },
-+};
-+module_platform_driver(layerscape_sfp_driver);
-+
-+MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
-+MODULE_DESCRIPTION("Layerscape Security Fuse Processor driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch b/target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch
deleted file mode 100644
index 74bd4a7eb6..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From bc5c75e0a5a9400f81a987cc720100ac475fa4d8 Mon Sep 17 00:00:00 2001
-From: Knox Chiou <knoxchiou@chromium.org>
-Date: Wed, 23 Feb 2022 22:35:00 +0000
-Subject: [PATCH] nvmem: qfprom: Increase fuse blow timeout to prevent write
- fail
-
-sc7180 blow fuses got slightly chances to hit qfprom_reg_write timeout.
-Current timeout is simply too low. Since blowing fuses is a
-very rare operation, so the risk associated with overestimating this
-number is low.
-Increase fuse blow timeout from 1ms to 10ms.
-
-Reviewed-by: Douglas Anderson <dianders@chromium.org>
-Signed-off-by: Knox Chiou <knoxchiou@chromium.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220223223502.29454-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qfprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -22,7 +22,7 @@
-
- /* Amount of time required to hold charge to blow fuse in micro-seconds */
- #define QFPROM_FUSE_BLOW_POLL_US 100
--#define QFPROM_FUSE_BLOW_TIMEOUT_US 1000
-+#define QFPROM_FUSE_BLOW_TIMEOUT_US 10000
-
- #define QFPROM_BLOW_STATUS_OFFSET 0x048
- #define QFPROM_BLOW_STATUS_BUSY 0x1
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch b/target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch
deleted file mode 100644
index ac77fc9b1d..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch
+++ /dev/null
@@ -1,291 +0,0 @@
-From 8747ec2e9762ed9ae53b3a590938f454b6a1abdf Mon Sep 17 00:00:00 2001
-From: Vincent Shih <vincent.sunplus@gmail.com>
-Date: Wed, 23 Feb 2022 22:35:01 +0000
-Subject: [PATCH] nvmem: Add driver for OCOTP in Sunplus SP7021
-
-Add driver for OCOTP in Sunplus SP7021
-
-Signed-off-by: Vincent Shih <vincent.sunplus@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220223223502.29454-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- MAINTAINERS | 5 +
- drivers/nvmem/Kconfig | 12 ++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/sunplus-ocotp.c | 228 ++++++++++++++++++++++++++++++++++
- 4 files changed, 247 insertions(+)
- create mode 100644 drivers/nvmem/sunplus-ocotp.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -17966,6 +17966,11 @@ L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/ethernet/dlink/sundance.c
-
-+SUNPLUS OCOTP DRIVER
-+M: Vincent Shih <vincent.sunplus@gmail.com>
-+S: Maintained
-+F: drivers/nvmem/sunplus-ocotp.c
-+
- SUPERH
- M: Yoshinori Sato <ysato@users.sourceforge.jp>
- M: Rich Felker <dalias@libc.org>
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -312,4 +312,16 @@ config NVMEM_LAYERSCAPE_SFP
- This driver can also be built as a module. If so, the module
- will be called layerscape-sfp.
-
-+config NVMEM_SUNPLUS_OCOTP
-+ tristate "Sunplus SoC OTP support"
-+ depends on SOC_SP7021 || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This is a driver for the On-chip OTP controller (OCOTP) available
-+ on Sunplus SoCs. It provides access to 128 bytes of one-time
-+ programmable eFuse.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem-sunplus-ocotp.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -63,3 +63,5 @@ obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_
- nvmem_brcm_nvram-y := brcm_nvram.o
- obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o
- nvmem-layerscape-sfp-y := layerscape-sfp.o
-+obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
-+nvmem_sunplus_ocotp-y := sunplus-ocotp.o
---- /dev/null
-+++ b/drivers/nvmem/sunplus-ocotp.c
-@@ -0,0 +1,228 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+/*
-+ * The OCOTP driver for Sunplus SP7021
-+ *
-+ * Copyright (C) 2019 Sunplus Technology Inc., All rights reserved.
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+
-+/*
-+ * OTP memory
-+ * Each bank contains 4 words (32 bits).
-+ * Bank 0 starts at offset 0 from the base.
-+ */
-+
-+#define OTP_WORDS_PER_BANK 4
-+#define OTP_WORD_SIZE sizeof(u32)
-+#define OTP_BIT_ADDR_OF_BANK (8 * OTP_WORD_SIZE * OTP_WORDS_PER_BANK)
-+#define QAC628_OTP_NUM_BANKS 8
-+#define QAC628_OTP_SIZE (QAC628_OTP_NUM_BANKS * OTP_WORDS_PER_BANK * OTP_WORD_SIZE)
-+#define OTP_READ_TIMEOUT_US 200000
-+
-+/* HB_GPIO */
-+#define ADDRESS_8_DATA 0x20
-+
-+/* OTP_RX */
-+#define OTP_CONTROL_2 0x48
-+#define OTP_RD_PERIOD GENMASK(15, 8)
-+#define OTP_RD_PERIOD_MASK ~GENMASK(15, 8)
-+#define CPU_CLOCK FIELD_PREP(OTP_RD_PERIOD, 30)
-+#define SEL_BAK_KEY2 BIT(5)
-+#define SEL_BAK_KEY2_MASK ~BIT(5)
-+#define SW_TRIM_EN BIT(4)
-+#define SW_TRIM_EN_MASK ~BIT(4)
-+#define SEL_BAK_KEY BIT(3)
-+#define SEL_BAK_KEY_MASK ~BIT(3)
-+#define OTP_READ BIT(2)
-+#define OTP_LOAD_SECURE_DATA BIT(1)
-+#define OTP_LOAD_SECURE_DATA_MASK ~BIT(1)
-+#define OTP_DO_CRC BIT(0)
-+#define OTP_DO_CRC_MASK ~BIT(0)
-+#define OTP_STATUS 0x4c
-+#define OTP_READ_DONE BIT(4)
-+#define OTP_READ_DONE_MASK ~BIT(4)
-+#define OTP_LOAD_SECURE_DONE_MASK ~BIT(2)
-+#define OTP_READ_ADDRESS 0x50
-+
-+enum base_type {
-+ HB_GPIO,
-+ OTPRX,
-+ BASEMAX,
-+};
-+
-+struct sp_ocotp_priv {
-+ struct device *dev;
-+ void __iomem *base[BASEMAX];
-+ struct clk *clk;
-+};
-+
-+struct sp_ocotp_data {
-+ int size;
-+};
-+
-+const struct sp_ocotp_data sp_otp_v0 = {
-+ .size = QAC628_OTP_SIZE,
-+};
-+
-+static int sp_otp_read_real(struct sp_ocotp_priv *otp, int addr, char *value)
-+{
-+ unsigned int addr_data;
-+ unsigned int byte_shift;
-+ unsigned int status;
-+ int ret;
-+
-+ addr_data = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
-+ addr_data = addr_data / OTP_WORD_SIZE;
-+
-+ byte_shift = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
-+ byte_shift = byte_shift % OTP_WORD_SIZE;
-+
-+ addr = addr / (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
-+ addr = addr * OTP_BIT_ADDR_OF_BANK;
-+
-+ writel(readl(otp->base[OTPRX] + OTP_STATUS) & OTP_READ_DONE_MASK &
-+ OTP_LOAD_SECURE_DONE_MASK, otp->base[OTPRX] + OTP_STATUS);
-+ writel(addr, otp->base[OTPRX] + OTP_READ_ADDRESS);
-+ writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) | OTP_READ,
-+ otp->base[OTPRX] + OTP_CONTROL_2);
-+ writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) & SEL_BAK_KEY2_MASK & SW_TRIM_EN_MASK
-+ & SEL_BAK_KEY_MASK & OTP_LOAD_SECURE_DATA_MASK & OTP_DO_CRC_MASK,
-+ otp->base[OTPRX] + OTP_CONTROL_2);
-+ writel((readl(otp->base[OTPRX] + OTP_CONTROL_2) & OTP_RD_PERIOD_MASK) | CPU_CLOCK,
-+ otp->base[OTPRX] + OTP_CONTROL_2);
-+
-+ ret = readl_poll_timeout(otp->base[OTPRX] + OTP_STATUS, status,
-+ status & OTP_READ_DONE, 10, OTP_READ_TIMEOUT_US);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ *value = (readl(otp->base[HB_GPIO] + ADDRESS_8_DATA + addr_data * OTP_WORD_SIZE)
-+ >> (8 * byte_shift)) & 0xff;
-+
-+ return ret;
-+}
-+
-+static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes)
-+{
-+ struct sp_ocotp_priv *otp = priv;
-+ unsigned int addr;
-+ char *buf = value;
-+ char val[4];
-+ int ret;
-+
-+ ret = clk_enable(otp->clk);
-+ if (ret)
-+ return ret;
-+
-+ *buf = 0;
-+ for (addr = offset; addr < (offset + bytes); addr++) {
-+ ret = sp_otp_read_real(otp, addr, val);
-+ if (ret < 0) {
-+ dev_err(otp->dev, "OTP read fail:%d at %d", ret, addr);
-+ goto disable_clk;
-+ }
-+
-+ *buf++ = *val;
-+ }
-+
-+disable_clk:
-+ clk_disable(otp->clk);
-+
-+ return ret;
-+}
-+
-+static struct nvmem_config sp_ocotp_nvmem_config = {
-+ .name = "sp-ocotp",
-+ .read_only = true,
-+ .word_size = 1,
-+ .size = QAC628_OTP_SIZE,
-+ .stride = 1,
-+ .reg_read = sp_ocotp_read,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int sp_ocotp_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct nvmem_device *nvmem;
-+ struct sp_ocotp_priv *otp;
-+ struct resource *res;
-+ int ret;
-+
-+ otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
-+ if (!otp)
-+ return -ENOMEM;
-+
-+ otp->dev = dev;
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
-+ otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(otp->base[HB_GPIO]))
-+ return PTR_ERR(otp->base[HB_GPIO]);
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
-+ otp->base[OTPRX] = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(otp->base[OTPRX]))
-+ return PTR_ERR(otp->base[OTPRX]);
-+
-+ otp->clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(otp->clk))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(otp->clk),
-+ "devm_clk_get fail\n");
-+
-+ ret = clk_prepare(otp->clk);
-+ if (ret < 0) {
-+ dev_err(dev, "failed to prepare clk: %d\n", ret);
-+ return ret;
-+ }
-+
-+ sp_ocotp_nvmem_config.priv = otp;
-+ sp_ocotp_nvmem_config.dev = dev;
-+
-+ nvmem = devm_nvmem_register(dev, &sp_ocotp_nvmem_config);
-+ if (IS_ERR(nvmem))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(nvmem),
-+ "register nvmem device fail\n");
-+
-+ platform_set_drvdata(pdev, nvmem);
-+
-+ dev_dbg(dev, "banks:%d x wpb:%d x wsize:%d = %d",
-+ (int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK,
-+ (int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE);
-+
-+ dev_info(dev, "by Sunplus (C) 2020");
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id sp_ocotp_dt_ids[] = {
-+ { .compatible = "sunplus,sp7021-ocotp", .data = &sp_otp_v0 },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, sp_ocotp_dt_ids);
-+
-+static struct platform_driver sp_otp_driver = {
-+ .probe = sp_ocotp_probe,
-+ .driver = {
-+ .name = "sunplus,sp7021-ocotp",
-+ .of_match_table = sp_ocotp_dt_ids,
-+ }
-+};
-+module_platform_driver(sp_otp_driver);
-+
-+MODULE_AUTHOR("Vincent Shih <vincent.sunplus@gmail.com>");
-+MODULE_DESCRIPTION("Sunplus On-Chip OTP driver");
-+MODULE_LICENSE("GPL");
-+
diff --git a/target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch b/target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch
deleted file mode 100644
index 99781b3a7b..0000000000
--- a/target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 6e977eaa8280e957b87904b536661550f2a6b3e8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 25 Feb 2022 17:58:20 +0000
-Subject: [PATCH] nvmem: brcm_nvram: parse NVRAM content into NVMEM cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-NVRAM consist of header and NUL separated key-value pairs. Parse it and
-create NVMEM cell for every key-value entry.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220225175822.8293-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 90 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 90 insertions(+)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -6,12 +6,26 @@
- #include <linux/io.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
-+#include <linux/nvmem-consumer.h>
- #include <linux/nvmem-provider.h>
- #include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+#define NVRAM_MAGIC "FLSH"
-
- struct brcm_nvram {
- struct device *dev;
- void __iomem *base;
-+ struct nvmem_cell_info *cells;
-+ int ncells;
-+};
-+
-+struct brcm_nvram_header {
-+ char magic[4];
-+ __le32 len;
-+ __le32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
-+ __le32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
-+ __le32 config_ncdl; /* ncdl values for memc */
- };
-
- static int brcm_nvram_read(void *context, unsigned int offset, void *val,
-@@ -26,6 +40,75 @@ static int brcm_nvram_read(void *context
- return 0;
- }
-
-+static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
-+ size_t len)
-+{
-+ struct device *dev = priv->dev;
-+ char *var, *value, *eq;
-+ int idx;
-+
-+ priv->ncells = 0;
-+ for (var = data + sizeof(struct brcm_nvram_header);
-+ var < (char *)data + len && *var;
-+ var += strlen(var) + 1) {
-+ priv->ncells++;
-+ }
-+
-+ priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
-+ if (!priv->cells)
-+ return -ENOMEM;
-+
-+ for (var = data + sizeof(struct brcm_nvram_header), idx = 0;
-+ var < (char *)data + len && *var;
-+ var = value + strlen(value) + 1, idx++) {
-+ eq = strchr(var, '=');
-+ if (!eq)
-+ break;
-+ *eq = '\0';
-+ value = eq + 1;
-+
-+ priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
-+ if (!priv->cells[idx].name)
-+ return -ENOMEM;
-+ priv->cells[idx].offset = value - (char *)data;
-+ priv->cells[idx].bytes = strlen(value);
-+ }
-+
-+ return 0;
-+}
-+
-+static int brcm_nvram_parse(struct brcm_nvram *priv)
-+{
-+ struct device *dev = priv->dev;
-+ struct brcm_nvram_header header;
-+ uint8_t *data;
-+ size_t len;
-+ int err;
-+
-+ memcpy_fromio(&header, priv->base, sizeof(header));
-+
-+ if (memcmp(header.magic, NVRAM_MAGIC, 4)) {
-+ dev_err(dev, "Invalid NVRAM magic\n");
-+ return -EINVAL;
-+ }
-+
-+ len = le32_to_cpu(header.len);
-+
-+ data = kcalloc(1, len, GFP_KERNEL);
-+ memcpy_fromio(data, priv->base, len);
-+ data[len - 1] = '\0';
-+
-+ err = brcm_nvram_add_cells(priv, data, len);
-+ if (err) {
-+ dev_err(dev, "Failed to add cells: %d\n", err);
-+ return err;
-+ }
-+
-+ kfree(data);
-+
-+ return 0;
-+}
-+
- static int brcm_nvram_probe(struct platform_device *pdev)
- {
- struct nvmem_config config = {
-@@ -35,6 +118,7 @@ static int brcm_nvram_probe(struct platf
- struct device *dev = &pdev->dev;
- struct resource *res;
- struct brcm_nvram *priv;
-+ int err;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -46,7 +130,13 @@ static int brcm_nvram_probe(struct platf
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
-+ err = brcm_nvram_parse(priv);
-+ if (err)
-+ return err;
-+
- config.dev = dev;
-+ config.cells = priv->cells;
-+ config.ncells = priv->ncells;
- config.priv = priv;
- config.size = resource_size(res);
-
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch b/target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch
deleted file mode 100644
index ef3107db94..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 6bd0ffeaa389866089e9573b2298ae58d6359b75 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzk@kernel.org>
-Date: Mon, 21 Mar 2022 12:03:24 +0100
-Subject: [PATCH] nvmem: bcm-ocotp: mark ACPI device ID table as maybe unused
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-"bcm_otpc_acpi_ids" is used with ACPI_PTR, so a build with !CONFIG_ACPI
-has a warning:
-
- drivers/nvmem/bcm-ocotp.c:247:36: error:
- ‘bcm_otpc_acpi_ids’ defined but not used [-Werror=unused-const-variable=]
-
-Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
-Link: https://lore.kernel.org/r/20220321110326.44652-1-krzk@kernel.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/bcm-ocotp.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/bcm-ocotp.c
-+++ b/drivers/nvmem/bcm-ocotp.c
-@@ -244,7 +244,7 @@ static const struct of_device_id bcm_otp
- };
- MODULE_DEVICE_TABLE(of, bcm_otpc_dt_ids);
-
--static const struct acpi_device_id bcm_otpc_acpi_ids[] = {
-+static const struct acpi_device_id bcm_otpc_acpi_ids[] __maybe_unused = {
- { .id = "BRCM0700", .driver_data = (kernel_ulong_t)&otp_map },
- { .id = "BRCM0701", .driver_data = (kernel_ulong_t)&otp_map_v2 },
- { /* sentinel */ }
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch b/target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch
deleted file mode 100644
index a84d2316f0..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 1066f8156351fcd997125257cea47cf805ba4f6d Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzk@kernel.org>
-Date: Mon, 21 Mar 2022 12:03:25 +0100
-Subject: [PATCH] nvmem: sunplus-ocotp: staticize sp_otp_v0
-
-The "sp_otp_v0" file scope variable is not used outside, so make it
-static to fix warning:
-
- drivers/nvmem/sunplus-ocotp.c:74:29: sparse:
- sparse: symbol 'sp_otp_v0' was not declared. Should it be static?
-
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
-Link: https://lore.kernel.org/r/20220321110326.44652-2-krzk@kernel.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/sunplus-ocotp.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/sunplus-ocotp.c
-+++ b/drivers/nvmem/sunplus-ocotp.c
-@@ -71,7 +71,7 @@ struct sp_ocotp_data {
- int size;
- };
-
--const struct sp_ocotp_data sp_otp_v0 = {
-+static const struct sp_ocotp_data sp_otp_v0 = {
- .size = QAC628_OTP_SIZE,
- };
-
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch b/target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch
deleted file mode 100644
index 886ebc12a9..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 874dfbcf219ccc42a2cbd187d087c7db82c3024b Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzk@kernel.org>
-Date: Mon, 21 Mar 2022 12:03:26 +0100
-Subject: [PATCH] nvmem: sunplus-ocotp: drop useless probe confirmation
-
-Printing probe success is discouraged, because we can use tracing for
-this purpose. Remove useless print message after Sunplus OCOTP driver
-probe.
-
-Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
-Link: https://lore.kernel.org/r/20220321110326.44652-3-krzk@kernel.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/sunplus-ocotp.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/nvmem/sunplus-ocotp.c
-+++ b/drivers/nvmem/sunplus-ocotp.c
-@@ -202,8 +202,6 @@ static int sp_ocotp_probe(struct platfor
- (int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK,
- (int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE);
-
-- dev_info(dev, "by Sunplus (C) 2020");
--
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch b/target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch
deleted file mode 100644
index 3b1e76147a..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From dbc2f62061c6bfba0aee93161ee3194dcee84bd0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 29 Apr 2022 17:26:46 +0100
-Subject: [PATCH] nvmem: core: support passing DT node in cell info
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some hardware may have NVMEM cells described in Device Tree using
-individual nodes. Let drivers pass such nodes to the NVMEM subsystem so
-they can be later used by NVMEM consumers.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220429162701.2222-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 1 +
- include/linux/nvmem-consumer.h | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -467,6 +467,7 @@ static int nvmem_cell_info_to_nvmem_cell
-
- cell->bit_offset = info->bit_offset;
- cell->nbits = info->nbits;
-+ cell->np = info->np;
-
- if (cell->nbits)
- cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -25,6 +25,7 @@ struct nvmem_cell_info {
- unsigned int bytes;
- unsigned int bit_offset;
- unsigned int nbits;
-+ struct device_node *np;
- };
-
- /**
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch
deleted file mode 100644
index a9eacd9419..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 207775f7e17b8fd0426a2ac4a5b81e4e1d71849e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 29 Apr 2022 17:26:47 +0100
-Subject: [PATCH] nvmem: brcm_nvram: find Device Tree nodes for NVMEM cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-DT binding for Broadcom's NVRAM supports specifying NVMEM cells as NVMEM
-device (provider) subnodes. Look for such subnodes when collecing NVMEM
-cells. This allows NVMEM consumers to use NVRAM variables.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220429162701.2222-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -8,6 +8,7 @@
- #include <linux/module.h>
- #include <linux/nvmem-consumer.h>
- #include <linux/nvmem-provider.h>
-+#include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/slab.h>
-
-@@ -72,6 +73,7 @@ static int brcm_nvram_add_cells(struct b
- return -ENOMEM;
- priv->cells[idx].offset = value - (char *)data;
- priv->cells[idx].bytes = strlen(value);
-+ priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
- }
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch b/target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch
deleted file mode 100644
index ebeb6f5ad3..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From b6b7ef932ae838209254f016ecf8862d716a5ced Mon Sep 17 00:00:00 2001
-From: Sven Peter <sven@svenpeter.dev>
-Date: Fri, 29 Apr 2022 17:26:50 +0100
-Subject: [PATCH] nvmem: Add Apple eFuse driver
-
-Apple SoCs contain eFuses used to store factory-programmed data such
-as calibration values for the PCIe or the Type-C PHY. They are organized
-as 32bit values exposed as MMIO.
-
-Signed-off-by: Sven Peter <sven@svenpeter.dev>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220429162701.2222-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 12 ++++++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/apple-efuses.c | 80 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 94 insertions(+)
- create mode 100644 drivers/nvmem/apple-efuses.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -324,4 +324,16 @@ config NVMEM_SUNPLUS_OCOTP
- This driver can also be built as a module. If so, the module
- will be called nvmem-sunplus-ocotp.
-
-+config NVMEM_APPLE_EFUSES
-+ tristate "Apple eFuse support"
-+ depends on ARCH_APPLE || COMPILE_TEST
-+ default ARCH_APPLE
-+ help
-+ Say y here to enable support for reading eFuses on Apple SoCs
-+ such as the M1. These are e.g. used to store factory programmed
-+ calibration data required for the PCIe or the USB-C PHY.
-+
-+ This driver can also be built as a module. If so, the module will
-+ be called nvmem-apple-efuses.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -65,3 +65,5 @@ obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nv
- nvmem-layerscape-sfp-y := layerscape-sfp.o
- obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
- nvmem_sunplus_ocotp-y := sunplus-ocotp.o
-+obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
-+nvmem-apple-efuses-y := apple-efuses.o
---- /dev/null
-+++ b/drivers/nvmem/apple-efuses.c
-@@ -0,0 +1,80 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Apple SoC eFuse driver
-+ *
-+ * Copyright (C) The Asahi Linux Contributors
-+ */
-+
-+#include <linux/io.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/platform_device.h>
-+
-+struct apple_efuses_priv {
-+ void __iomem *fuses;
-+};
-+
-+static int apple_efuses_read(void *context, unsigned int offset, void *val,
-+ size_t bytes)
-+{
-+ struct apple_efuses_priv *priv = context;
-+ u32 *dst = val;
-+
-+ while (bytes >= sizeof(u32)) {
-+ *dst++ = readl_relaxed(priv->fuses + offset);
-+ bytes -= sizeof(u32);
-+ offset += sizeof(u32);
-+ }
-+
-+ return 0;
-+}
-+
-+static int apple_efuses_probe(struct platform_device *pdev)
-+{
-+ struct apple_efuses_priv *priv;
-+ struct resource *res;
-+ struct nvmem_config config = {
-+ .dev = &pdev->dev,
-+ .read_only = true,
-+ .reg_read = apple_efuses_read,
-+ .stride = sizeof(u32),
-+ .word_size = sizeof(u32),
-+ .name = "apple_efuses_nvmem",
-+ .id = NVMEM_DEVID_AUTO,
-+ .root_only = true,
-+ };
-+
-+ priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->fuses = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(priv->fuses))
-+ return PTR_ERR(priv->fuses);
-+
-+ config.priv = priv;
-+ config.size = resource_size(res);
-+
-+ return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config));
-+}
-+
-+static const struct of_device_id apple_efuses_of_match[] = {
-+ { .compatible = "apple,efuses", },
-+ {}
-+};
-+
-+MODULE_DEVICE_TABLE(of, apple_efuses_of_match);
-+
-+static struct platform_driver apple_efuses_driver = {
-+ .driver = {
-+ .name = "apple_efuses",
-+ .of_match_table = apple_efuses_of_match,
-+ },
-+ .probe = apple_efuses_probe,
-+};
-+
-+module_platform_driver(apple_efuses_driver);
-+
-+MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch b/target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch
deleted file mode 100644
index cd51d97006..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 517f6e2641a2802dce5a5aa0d18c7d37a35678d2 Mon Sep 17 00:00:00 2001
-From: Minghao Chi <chi.minghao@zte.com.cn>
-Date: Fri, 29 Apr 2022 17:26:54 +0100
-Subject: [PATCH] nvmem: qfprom: using pm_runtime_resume_and_get instead of
- pm_runtime_get_sync
-
-Using pm_runtime_resume_and_get is more appropriate
-for simplifing code
-
-Reported-by: Zeal Robot <zealci@zte.com.cn>
-Signed-off-by: Minghao Chi <chi.minghao@zte.com.cn>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220429162701.2222-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qfprom.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -217,9 +217,8 @@ static int qfprom_enable_fuse_blowing(co
- goto err_clk_rate_set;
- }
-
-- ret = pm_runtime_get_sync(priv->dev);
-+ ret = pm_runtime_resume_and_get(priv->dev);
- if (ret < 0) {
-- pm_runtime_put_noidle(priv->dev);
- dev_err(priv->dev, "Failed to enable power-domain\n");
- goto err_reg_enable;
- }
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch b/target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch
deleted file mode 100644
index e187238ca3..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 943eadbdb11314b41eacbcc484dfb7f93e271ff4 Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Fri, 29 Apr 2022 17:27:00 +0100
-Subject: [PATCH] nvmem: sfp: Use regmap
-
-This converts the SFP driver to use regmap. This will allow easily
-supporting devices with different endians. We disallow byte-level
-access, as regmap_bulk_read doesn't support it (and it's unclear what
-the correct result would be when we have an endianness difference).
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220429162701.2222-16-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 1 +
- drivers/nvmem/layerscape-sfp.c | 30 ++++++++++++++++++++++--------
- 2 files changed, 23 insertions(+), 8 deletions(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -304,6 +304,7 @@ config NVMEM_LAYERSCAPE_SFP
- tristate "Layerscape SFP (Security Fuse Processor) support"
- depends on ARCH_LAYERSCAPE || COMPILE_TEST
- depends on HAS_IOMEM
-+ select REGMAP_MMIO
- help
- This driver provides support to read the eFuses on Freescale
- Layerscape SoC's. For example, the vendor provides a per part
---- a/drivers/nvmem/layerscape-sfp.c
-+++ b/drivers/nvmem/layerscape-sfp.c
-@@ -13,15 +13,17 @@
- #include <linux/nvmem-provider.h>
- #include <linux/platform_device.h>
- #include <linux/property.h>
-+#include <linux/regmap.h>
-
- #define LAYERSCAPE_SFP_OTP_OFFSET 0x0200
-
- struct layerscape_sfp_priv {
-- void __iomem *base;
-+ struct regmap *regmap;
- };
-
- struct layerscape_sfp_data {
- int size;
-+ enum regmap_endian endian;
- };
-
- static int layerscape_sfp_read(void *context, unsigned int offset, void *val,
-@@ -29,15 +31,16 @@ static int layerscape_sfp_read(void *con
- {
- struct layerscape_sfp_priv *priv = context;
-
-- memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset,
-- bytes);
--
-- return 0;
-+ return regmap_bulk_read(priv->regmap,
-+ LAYERSCAPE_SFP_OTP_OFFSET + offset, val,
-+ bytes / 4);
- }
-
- static struct nvmem_config layerscape_sfp_nvmem_config = {
- .name = "fsl-sfp",
- .reg_read = layerscape_sfp_read,
-+ .word_size = 4,
-+ .stride = 4,
- };
-
- static int layerscape_sfp_probe(struct platform_device *pdev)
-@@ -45,16 +48,26 @@ static int layerscape_sfp_probe(struct p
- const struct layerscape_sfp_data *data;
- struct layerscape_sfp_priv *priv;
- struct nvmem_device *nvmem;
-+ struct regmap_config config = { 0 };
-+ void __iomem *base;
-
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
-- priv->base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(priv->base))
-- return PTR_ERR(priv->base);
-+ base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-
- data = device_get_match_data(&pdev->dev);
-+ config.reg_bits = 32;
-+ config.reg_stride = 4;
-+ config.val_bits = 32;
-+ config.val_format_endian = data->endian;
-+ config.max_register = LAYERSCAPE_SFP_OTP_OFFSET + data->size - 4;
-+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, &config);
-+ if (IS_ERR(priv->regmap))
-+ return PTR_ERR(priv->regmap);
-
- layerscape_sfp_nvmem_config.size = data->size;
- layerscape_sfp_nvmem_config.dev = &pdev->dev;
-@@ -67,6 +80,7 @@ static int layerscape_sfp_probe(struct p
-
- static const struct layerscape_sfp_data ls1028a_data = {
- .size = 0x88,
-+ .endian = REGMAP_ENDIAN_LITTLE,
- };
-
- static const struct of_device_id layerscape_sfp_dt_ids[] = {
diff --git a/target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch b/target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch
deleted file mode 100644
index ee00098618..0000000000
--- a/target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 33a1c6618677fe33f8e84cb7bedc45abbce89a50 Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Fri, 29 Apr 2022 17:27:01 +0100
-Subject: [PATCH] nvmem: sfp: Add support for TA 2.1 devices
-
-This adds support for Trust Architecture (TA) 2.1 devices to the SFP driver.
-There are few differences between TA 2.1 and TA 3.0, especially for
-read-only support, so just re-use the existing data.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220429162701.2222-17-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layerscape-sfp.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/nvmem/layerscape-sfp.c
-+++ b/drivers/nvmem/layerscape-sfp.c
-@@ -78,12 +78,18 @@ static int layerscape_sfp_probe(struct p
- return PTR_ERR_OR_ZERO(nvmem);
- }
-
-+static const struct layerscape_sfp_data ls1021a_data = {
-+ .size = 0x88,
-+ .endian = REGMAP_ENDIAN_BIG,
-+};
-+
- static const struct layerscape_sfp_data ls1028a_data = {
- .size = 0x88,
- .endian = REGMAP_ENDIAN_LITTLE,
- };
-
- static const struct of_device_id layerscape_sfp_dt_ids[] = {
-+ { .compatible = "fsl,ls1021a-sfp", .data = &ls1021a_data },
- { .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data },
- {},
- };
diff --git a/target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch b/target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch
deleted file mode 100644
index f54ba7ebee..0000000000
--- a/target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch
+++ /dev/null
@@ -1,389 +0,0 @@
-From 98830350d3fc824c1ff5c338140fe20f041a5916 Mon Sep 17 00:00:00 2001
-From: Claudiu Beznea <claudiu.beznea@microchip.com>
-Date: Wed, 6 Jul 2022 11:06:22 +0100
-Subject: [PATCH] nvmem: microchip-otpc: add support
-
-Add support for Microchip OTP controller available on SAMA7G5. The OTPC
-controls the access to a non-volatile memory. The memory behind OTPC is
-organized into packets, packets are composed by a fixed length header
-(4 bytes long) and a variable length payload (payload length is available
-in the header). When software request the data at an offset in memory
-the OTPC will return (via header + data registers) the whole packet that
-has a word at that offset. For the OTP memory layout like below:
-
-offset OTP Memory layout
-
- . .
- . ... .
- . .
-0x0E +-----------+ <--- packet X
- | header X |
-0x12 +-----------+
- | payload X |
-0x16 | |
- | |
-0x1A | |
- +-----------+
- . .
- . ... .
- . .
-
-if user requests data at address 0x16 the data started at 0x0E will be
-returned by controller. User will be able to fetch the whole packet
-starting at 0x0E (or parts of the packet) via proper registers. The same
-packet will be returned if software request the data at offset 0x0E or
-0x12 or 0x1A.
-
-The OTP will be populated by Microchip with at least 2 packets first one
-being boot configuration packet and the 2nd one being temperature
-calibration packet. The packet order will be preserved b/w different chip
-revisions but the packet sizes may change.
-
-For the above reasons and to keep the same software able to work on all
-chip variants the read function of the driver is working with a packet
-id instead of an offset in OTP memory.
-
-Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220706100627.6534-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- MAINTAINERS | 8 +
- drivers/nvmem/Kconfig | 7 +
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/microchip-otpc.c | 288 +++++++++++++++++++++++++++++++++
- 4 files changed, 305 insertions(+)
- create mode 100644 drivers/nvmem/microchip-otpc.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -12365,6 +12365,14 @@ S: Supported
- F: Documentation/devicetree/bindings/mtd/atmel-nand.txt
- F: drivers/mtd/nand/raw/atmel/*
-
-+MICROCHIP OTPC DRIVER
-+M: Claudiu Beznea <claudiu.beznea@microchip.com>
-+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-+S: Supported
-+F: Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml
-+F: drivers/nvmem/microchip-otpc.c
-+F: dt-bindings/nvmem/microchip,sama7g5-otpc.h
-+
- MICROCHIP PWM DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
- L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -107,6 +107,13 @@ config MTK_EFUSE
- This driver can also be built as a module. If so, the module
- will be called efuse-mtk.
-
-+config MICROCHIP_OTPC
-+ tristate "Microchip OTPC support"
-+ depends on ARCH_AT91 || COMPILE_TEST
-+ help
-+ This driver enable the OTP controller available on Microchip SAMA7G5
-+ SoCs. It controlls the access to the OTP memory connected to it.
-+
- config NVMEM_NINTENDO_OTP
- tristate "Nintendo Wii and Wii U OTP Support"
- depends on WII || COMPILE_TEST
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -67,3 +67,5 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvm
- nvmem_sunplus_ocotp-y := sunplus-ocotp.o
- obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
- nvmem-apple-efuses-y := apple-efuses.o
-+obj-$(CONFIG_MICROCHIP_OTPC) += nvmem-microchip-otpc.o
-+nvmem-microchip-otpc-y := microchip-otpc.o
---- /dev/null
-+++ b/drivers/nvmem/microchip-otpc.c
-@@ -0,0 +1,288 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * OTP Memory controller
-+ *
-+ * Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries
-+ *
-+ * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+
-+#define MCHP_OTPC_CR (0x0)
-+#define MCHP_OTPC_CR_READ BIT(6)
-+#define MCHP_OTPC_MR (0x4)
-+#define MCHP_OTPC_MR_ADDR GENMASK(31, 16)
-+#define MCHP_OTPC_AR (0x8)
-+#define MCHP_OTPC_SR (0xc)
-+#define MCHP_OTPC_SR_READ BIT(6)
-+#define MCHP_OTPC_HR (0x20)
-+#define MCHP_OTPC_HR_SIZE GENMASK(15, 8)
-+#define MCHP_OTPC_DR (0x24)
-+
-+#define MCHP_OTPC_NAME "mchp-otpc"
-+#define MCHP_OTPC_SIZE (11 * 1024)
-+
-+/**
-+ * struct mchp_otpc - OTPC private data structure
-+ * @base: base address
-+ * @dev: struct device pointer
-+ * @packets: list of packets in OTP memory
-+ * @npackets: number of packets in OTP memory
-+ */
-+struct mchp_otpc {
-+ void __iomem *base;
-+ struct device *dev;
-+ struct list_head packets;
-+ u32 npackets;
-+};
-+
-+/**
-+ * struct mchp_otpc_packet - OTPC packet data structure
-+ * @list: list head
-+ * @id: packet ID
-+ * @offset: packet offset (in words) in OTP memory
-+ */
-+struct mchp_otpc_packet {
-+ struct list_head list;
-+ u32 id;
-+ u32 offset;
-+};
-+
-+static struct mchp_otpc_packet *mchp_otpc_id_to_packet(struct mchp_otpc *otpc,
-+ u32 id)
-+{
-+ struct mchp_otpc_packet *packet;
-+
-+ if (id >= otpc->npackets)
-+ return NULL;
-+
-+ list_for_each_entry(packet, &otpc->packets, list) {
-+ if (packet->id == id)
-+ return packet;
-+ }
-+
-+ return NULL;
-+}
-+
-+static int mchp_otpc_prepare_read(struct mchp_otpc *otpc,
-+ unsigned int offset)
-+{
-+ u32 tmp;
-+
-+ /* Set address. */
-+ tmp = readl_relaxed(otpc->base + MCHP_OTPC_MR);
-+ tmp &= ~MCHP_OTPC_MR_ADDR;
-+ tmp |= FIELD_PREP(MCHP_OTPC_MR_ADDR, offset);
-+ writel_relaxed(tmp, otpc->base + MCHP_OTPC_MR);
-+
-+ /* Set read. */
-+ tmp = readl_relaxed(otpc->base + MCHP_OTPC_CR);
-+ tmp |= MCHP_OTPC_CR_READ;
-+ writel_relaxed(tmp, otpc->base + MCHP_OTPC_CR);
-+
-+ /* Wait for packet to be transferred into temporary buffers. */
-+ return read_poll_timeout(readl_relaxed, tmp, !(tmp & MCHP_OTPC_SR_READ),
-+ 10000, 2000, false, otpc->base + MCHP_OTPC_SR);
-+}
-+
-+/*
-+ * OTPC memory is organized into packets. Each packets contains a header and
-+ * a payload. Header is 4 bytes long and contains the size of the payload.
-+ * Payload size varies. The memory footprint is something as follows:
-+ *
-+ * Memory offset Memory footprint Packet ID
-+ * ------------- ---------------- ---------
-+ *
-+ * 0x0 +------------+ <-- packet 0
-+ * | header 0 |
-+ * 0x4 +------------+
-+ * | payload 0 |
-+ * . .
-+ * . ... .
-+ * . .
-+ * offset1 +------------+ <-- packet 1
-+ * | header 1 |
-+ * offset1 + 0x4 +------------+
-+ * | payload 1 |
-+ * . .
-+ * . ... .
-+ * . .
-+ * offset2 +------------+ <-- packet 2
-+ * . .
-+ * . ... .
-+ * . .
-+ * offsetN +------------+ <-- packet N
-+ * | header N |
-+ * offsetN + 0x4 +------------+
-+ * | payload N |
-+ * . .
-+ * . ... .
-+ * . .
-+ * +------------+
-+ *
-+ * where offset1, offset2, offsetN depends on the size of payload 0, payload 1,
-+ * payload N-1.
-+ *
-+ * The access to memory is done on a per packet basis: the control registers
-+ * need to be updated with an offset address (within a packet range) and the
-+ * data registers will be update by controller with information contained by
-+ * that packet. E.g. if control registers are updated with any address within
-+ * the range [offset1, offset2) the data registers are updated by controller
-+ * with packet 1. Header data is accessible though MCHP_OTPC_HR register.
-+ * Payload data is accessible though MCHP_OTPC_DR and MCHP_OTPC_AR registers.
-+ * There is no direct mapping b/w the offset requested by software and the
-+ * offset returned by hardware.
-+ *
-+ * For this, the read function will return the first requested bytes in the
-+ * packet. The user will have to be aware of the memory footprint before doing
-+ * the read request.
-+ */
-+static int mchp_otpc_read(void *priv, unsigned int off, void *val,
-+ size_t bytes)
-+{
-+ struct mchp_otpc *otpc = priv;
-+ struct mchp_otpc_packet *packet;
-+ u32 *buf = val;
-+ u32 offset;
-+ size_t len = 0;
-+ int ret, payload_size;
-+
-+ /*
-+ * We reach this point with off being multiple of stride = 4 to
-+ * be able to cross the subsystem. Inside the driver we use continuous
-+ * unsigned integer numbers for packet id, thus devide off by 4
-+ * before passing it to mchp_otpc_id_to_packet().
-+ */
-+ packet = mchp_otpc_id_to_packet(otpc, off / 4);
-+ if (!packet)
-+ return -EINVAL;
-+ offset = packet->offset;
-+
-+ while (len < bytes) {
-+ ret = mchp_otpc_prepare_read(otpc, offset);
-+ if (ret)
-+ return ret;
-+
-+ /* Read and save header content. */
-+ *buf++ = readl_relaxed(otpc->base + MCHP_OTPC_HR);
-+ len += sizeof(*buf);
-+ offset++;
-+ if (len >= bytes)
-+ break;
-+
-+ /* Read and save payload content. */
-+ payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, *(buf - 1));
-+ writel_relaxed(0UL, otpc->base + MCHP_OTPC_AR);
-+ do {
-+ *buf++ = readl_relaxed(otpc->base + MCHP_OTPC_DR);
-+ len += sizeof(*buf);
-+ offset++;
-+ payload_size--;
-+ } while (payload_size >= 0 && len < bytes);
-+ }
-+
-+ return 0;
-+}
-+
-+static int mchp_otpc_init_packets_list(struct mchp_otpc *otpc, u32 *size)
-+{
-+ struct mchp_otpc_packet *packet;
-+ u32 word, word_pos = 0, id = 0, npackets = 0, payload_size;
-+ int ret;
-+
-+ INIT_LIST_HEAD(&otpc->packets);
-+ *size = 0;
-+
-+ while (*size < MCHP_OTPC_SIZE) {
-+ ret = mchp_otpc_prepare_read(otpc, word_pos);
-+ if (ret)
-+ return ret;
-+
-+ word = readl_relaxed(otpc->base + MCHP_OTPC_HR);
-+ payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, word);
-+ if (!payload_size)
-+ break;
-+
-+ packet = devm_kzalloc(otpc->dev, sizeof(*packet), GFP_KERNEL);
-+ if (!packet)
-+ return -ENOMEM;
-+
-+ packet->id = id++;
-+ packet->offset = word_pos;
-+ INIT_LIST_HEAD(&packet->list);
-+ list_add_tail(&packet->list, &otpc->packets);
-+
-+ /* Count size by adding header and paload sizes. */
-+ *size += 4 * (payload_size + 1);
-+ /* Next word: this packet (header, payload) position + 1. */
-+ word_pos += payload_size + 2;
-+
-+ npackets++;
-+ }
-+
-+ otpc->npackets = npackets;
-+
-+ return 0;
-+}
-+
-+static struct nvmem_config mchp_nvmem_config = {
-+ .name = MCHP_OTPC_NAME,
-+ .type = NVMEM_TYPE_OTP,
-+ .read_only = true,
-+ .word_size = 4,
-+ .stride = 4,
-+ .reg_read = mchp_otpc_read,
-+};
-+
-+static int mchp_otpc_probe(struct platform_device *pdev)
-+{
-+ struct nvmem_device *nvmem;
-+ struct mchp_otpc *otpc;
-+ u32 size;
-+ int ret;
-+
-+ otpc = devm_kzalloc(&pdev->dev, sizeof(*otpc), GFP_KERNEL);
-+ if (!otpc)
-+ return -ENOMEM;
-+
-+ otpc->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(otpc->base))
-+ return PTR_ERR(otpc->base);
-+
-+ otpc->dev = &pdev->dev;
-+ ret = mchp_otpc_init_packets_list(otpc, &size);
-+ if (ret)
-+ return ret;
-+
-+ mchp_nvmem_config.dev = otpc->dev;
-+ mchp_nvmem_config.size = size;
-+ mchp_nvmem_config.priv = otpc;
-+ nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config);
-+
-+ return PTR_ERR_OR_ZERO(nvmem);
-+}
-+
-+static const struct of_device_id __maybe_unused mchp_otpc_ids[] = {
-+ { .compatible = "microchip,sama7g5-otpc", },
-+ { },
-+};
-+MODULE_DEVICE_TABLE(of, mchp_otpc_ids);
-+
-+static struct platform_driver mchp_otpc_driver = {
-+ .probe = mchp_otpc_probe,
-+ .driver = {
-+ .name = MCHP_OTPC_NAME,
-+ .of_match_table = of_match_ptr(mchp_otpc_ids),
-+ },
-+};
-+module_platform_driver(mchp_otpc_driver);
-+
-+MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea@microchip.com>");
-+MODULE_DESCRIPTION("Microchip SAMA7G5 OTPC driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch b/target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch
deleted file mode 100644
index 6a4126b9de..0000000000
--- a/target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From f5c97da8037b18d1256a58459fa96ed68e50fb41 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Wed, 6 Jul 2022 11:06:27 +0100
-Subject: [PATCH] nvmem: mtk-efuse: Simplify with
- devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-No functional changes.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220706100627.6534-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/mtk-efuse.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -41,8 +41,7 @@ static int mtk_efuse_probe(struct platfo
- if (!priv)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch b/target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch
deleted file mode 100644
index 9138807bc9..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch
+++ /dev/null
@@ -1,286 +0,0 @@
-From d5542923f200f95bddf524f36fd495f78aa28e3c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Sep 2022 13:20:48 +0100
-Subject: [PATCH] nvmem: add driver handling U-Boot environment variables
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-U-Boot stores its setup as environment variables. It's a list of
-key-value pairs stored on flash device with a custom header.
-
-This commit adds an NVMEM driver that:
-1. Provides NVMEM access to environment vars binary data
-2. Extracts variables as NVMEM cells
-
-Current Linux's NVMEM sysfs API allows reading whole NVMEM data block.
-It can be used by user-space tools for reading U-Boot env vars block
-without the hassle of finding its location. Parsing will still need to
-be re-done there.
-
-Kernel-parsed NVMEM cells can be read however by Linux drivers. This may
-be useful for Ethernet drivers for reading device MAC address which is
-often stored as U-Boot env variable.
-
-Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220916122100.170016-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- MAINTAINERS | 1 +
- drivers/nvmem/Kconfig | 13 +++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/u-boot-env.c | 218 +++++++++++++++++++++++++++++++++++++
- 4 files changed, 234 insertions(+)
- create mode 100644 drivers/nvmem/u-boot-env.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -344,4 +344,17 @@ config NVMEM_APPLE_EFUSES
- This driver can also be built as a module. If so, the module will
- be called nvmem-apple-efuses.
-
-+config NVMEM_U_BOOT_ENV
-+ tristate "U-Boot environment variables support"
-+ depends on OF && MTD
-+ select CRC32
-+ help
-+ U-Boot stores its setup as environment variables. This driver adds
-+ support for verifying & exporting such data. It also exposes variables
-+ as NVMEM cells so they can be referenced by other drivers.
-+
-+ Currently this drivers works only with env variables on top of MTD.
-+
-+ If compiled as module it will be called nvmem_u-boot-env.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -69,3 +69,5 @@ obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvme
- nvmem-apple-efuses-y := apple-efuses.o
- obj-$(CONFIG_MICROCHIP_OTPC) += nvmem-microchip-otpc.o
- nvmem-microchip-otpc-y := microchip-otpc.o
-+obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o
-+nvmem_u-boot-env-y := u-boot-env.o
---- /dev/null
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -0,0 +1,218 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
-+ */
-+
-+#include <linux/crc32.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+enum u_boot_env_format {
-+ U_BOOT_FORMAT_SINGLE,
-+ U_BOOT_FORMAT_REDUNDANT,
-+};
-+
-+struct u_boot_env {
-+ struct device *dev;
-+ enum u_boot_env_format format;
-+
-+ struct mtd_info *mtd;
-+
-+ /* Cells */
-+ struct nvmem_cell_info *cells;
-+ int ncells;
-+};
-+
-+struct u_boot_env_image_single {
-+ __le32 crc32;
-+ uint8_t data[];
-+} __packed;
-+
-+struct u_boot_env_image_redundant {
-+ __le32 crc32;
-+ u8 mark;
-+ uint8_t data[];
-+} __packed;
-+
-+static int u_boot_env_read(void *context, unsigned int offset, void *val,
-+ size_t bytes)
-+{
-+ struct u_boot_env *priv = context;
-+ struct device *dev = priv->dev;
-+ size_t bytes_read;
-+ int err;
-+
-+ err = mtd_read(priv->mtd, offset, bytes, &bytes_read, val);
-+ if (err && !mtd_is_bitflip(err)) {
-+ dev_err(dev, "Failed to read from mtd: %d\n", err);
-+ return err;
-+ }
-+
-+ if (bytes_read != bytes) {
-+ dev_err(dev, "Failed to read %zu bytes\n", bytes);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
-+ size_t data_offset, size_t data_len)
-+{
-+ struct device *dev = priv->dev;
-+ char *data = buf + data_offset;
-+ char *var, *value, *eq;
-+ int idx;
-+
-+ priv->ncells = 0;
-+ for (var = data; var < data + data_len && *var; var += strlen(var) + 1)
-+ priv->ncells++;
-+
-+ priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
-+ if (!priv->cells)
-+ return -ENOMEM;
-+
-+ for (var = data, idx = 0;
-+ var < data + data_len && *var;
-+ var = value + strlen(value) + 1, idx++) {
-+ eq = strchr(var, '=');
-+ if (!eq)
-+ break;
-+ *eq = '\0';
-+ value = eq + 1;
-+
-+ priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
-+ if (!priv->cells[idx].name)
-+ return -ENOMEM;
-+ priv->cells[idx].offset = data_offset + value - data;
-+ priv->cells[idx].bytes = strlen(value);
-+ }
-+
-+ if (WARN_ON(idx != priv->ncells))
-+ priv->ncells = idx;
-+
-+ return 0;
-+}
-+
-+static int u_boot_env_parse(struct u_boot_env *priv)
-+{
-+ struct device *dev = priv->dev;
-+ size_t crc32_data_offset;
-+ size_t crc32_data_len;
-+ size_t crc32_offset;
-+ size_t data_offset;
-+ size_t data_len;
-+ uint32_t crc32;
-+ uint32_t calc;
-+ size_t bytes;
-+ uint8_t *buf;
-+ int err;
-+
-+ buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
-+ if (!buf) {
-+ err = -ENOMEM;
-+ goto err_out;
-+ }
-+
-+ err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
-+ if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
-+ dev_err(dev, "Failed to read from mtd: %d\n", err);
-+ goto err_kfree;
-+ }
-+
-+ switch (priv->format) {
-+ case U_BOOT_FORMAT_SINGLE:
-+ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
-+ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
-+ data_offset = offsetof(struct u_boot_env_image_single, data);
-+ break;
-+ case U_BOOT_FORMAT_REDUNDANT:
-+ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
-+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, mark);
-+ data_offset = offsetof(struct u_boot_env_image_redundant, data);
-+ break;
-+ }
-+ crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset));
-+ crc32_data_len = priv->mtd->size - crc32_data_offset;
-+ data_len = priv->mtd->size - data_offset;
-+
-+ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
-+ if (calc != crc32) {
-+ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
-+ err = -EINVAL;
-+ goto err_kfree;
-+ }
-+
-+ buf[priv->mtd->size - 1] = '\0';
-+ err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
-+ if (err)
-+ dev_err(dev, "Failed to add cells: %d\n", err);
-+
-+err_kfree:
-+ kfree(buf);
-+err_out:
-+ return err;
-+}
-+
-+static int u_boot_env_probe(struct platform_device *pdev)
-+{
-+ struct nvmem_config config = {
-+ .name = "u-boot-env",
-+ .reg_read = u_boot_env_read,
-+ };
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ struct u_boot_env *priv;
-+ int err;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+ priv->dev = dev;
-+
-+ priv->format = (uintptr_t)of_device_get_match_data(dev);
-+
-+ priv->mtd = of_get_mtd_device_by_node(np);
-+ if (IS_ERR(priv->mtd)) {
-+ dev_err_probe(dev, PTR_ERR(priv->mtd), "Failed to get %pOF MTD\n", np);
-+ return PTR_ERR(priv->mtd);
-+ }
-+
-+ err = u_boot_env_parse(priv);
-+ if (err)
-+ return err;
-+
-+ config.dev = dev;
-+ config.cells = priv->cells;
-+ config.ncells = priv->ncells;
-+ config.priv = priv;
-+ config.size = priv->mtd->size;
-+
-+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
-+}
-+
-+static const struct of_device_id u_boot_env_of_match_table[] = {
-+ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
-+ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
-+ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
-+ {},
-+};
-+
-+static struct platform_driver u_boot_env_driver = {
-+ .probe = u_boot_env_probe,
-+ .driver = {
-+ .name = "u_boot_env",
-+ .of_match_table = u_boot_env_of_match_table,
-+ },
-+};
-+module_platform_driver(u_boot_env_driver);
-+
-+MODULE_AUTHOR("Rafał Miłecki");
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch b/target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch
deleted file mode 100644
index 48ad63fab5..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From d3524bb5b9a0c567b853a0024526afe87dde01ed Mon Sep 17 00:00:00 2001
-From: Kenneth Lee <klee33@uw.edu>
-Date: Fri, 16 Sep 2022 13:20:52 +0100
-Subject: [PATCH] nvmem: brcm_nvram: Use kzalloc for allocating only one
- element
-
-Use kzalloc(...) rather than kcalloc(1, ...) because the number of
-elements we are specifying in this case is 1, so kzalloc would
-accomplish the same thing and we can simplify.
-
-Signed-off-by: Kenneth Lee <klee33@uw.edu>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220916122100.170016-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -96,7 +96,7 @@ static int brcm_nvram_parse(struct brcm_
-
- len = le32_to_cpu(header.len);
-
-- data = kcalloc(1, len, GFP_KERNEL);
-+ data = kzalloc(len, GFP_KERNEL);
- memcpy_fromio(data, priv->base, len);
- data[len - 1] = '\0';
-
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch b/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch
deleted file mode 100644
index 4410fc4d61..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch
+++ /dev/null
@@ -1,281 +0,0 @@
-From 28fc7c986f01fdcfd28af648be2597624cac0e27 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Sep 2022 13:20:54 +0100
-Subject: [PATCH] nvmem: prefix all symbols with NVMEM_
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This unifies all NVMEM symbols. They follow one style now.
-
-Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
-Acked-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220916122100.170016-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/arm/configs/multi_v7_defconfig | 6 +++---
- arch/arm/configs/qcom_defconfig | 2 +-
- arch/arm64/configs/defconfig | 10 +++++-----
- arch/mips/configs/ci20_defconfig | 2 +-
- drivers/cpufreq/Kconfig.arm | 2 +-
- drivers/nvmem/Kconfig | 24 ++++++++++++------------
- drivers/nvmem/Makefile | 24 ++++++++++++------------
- drivers/soc/mediatek/Kconfig | 2 +-
- drivers/thermal/qcom/Kconfig | 2 +-
- 9 files changed, 37 insertions(+), 37 deletions(-)
-
---- a/arch/arm/configs/multi_v7_defconfig
-+++ b/arch/arm/configs/multi_v7_defconfig
-@@ -1124,10 +1124,10 @@ CONFIG_TI_PIPE3=y
- CONFIG_TWL4030_USB=m
- CONFIG_RAS=y
- CONFIG_NVMEM_IMX_OCOTP=y
--CONFIG_ROCKCHIP_EFUSE=m
-+CONFIG_NVMEM_ROCKCHIP_EFUSE=m
- CONFIG_NVMEM_SUNXI_SID=y
- CONFIG_NVMEM_VF610_OCOTP=y
--CONFIG_MESON_MX_EFUSE=m
-+CONFIG_NVMEM_MESON_MX_EFUSE=m
- CONFIG_NVMEM_RMEM=m
- CONFIG_FSI=m
- CONFIG_FSI_MASTER_GPIO=m
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -274,7 +274,7 @@ CONFIG_PHY_QCOM_USB_HS=y
- CONFIG_PHY_QCOM_USB_HSIC=y
- CONFIG_PHY_QCOM_QMP=y
- CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
--CONFIG_QCOM_QFPROM=y
-+CONFIG_NVMEM_QCOM_QFPROM=y
- CONFIG_INTERCONNECT=y
- CONFIG_INTERCONNECT_QCOM=y
- CONFIG_INTERCONNECT_QCOM_MSM8974=m
---- a/arch/arm64/configs/defconfig
-+++ b/arch/arm64/configs/defconfig
-@@ -1135,11 +1135,11 @@ CONFIG_QCOM_L3_PMU=y
- CONFIG_NVMEM_IMX_OCOTP=y
- CONFIG_NVMEM_IMX_OCOTP_SCU=y
- CONFIG_QCOM_QFPROM=y
--CONFIG_MTK_EFUSE=y
--CONFIG_ROCKCHIP_EFUSE=y
-+CONFIG_NVMEM_MTK_EFUSE=y
-+CONFIG_NVMEM_ROCKCHIP_EFUSE=y
- CONFIG_NVMEM_SUNXI_SID=y
--CONFIG_UNIPHIER_EFUSE=y
--CONFIG_MESON_EFUSE=m
-+CONFIG_NVMEM_UNIPHIER_EFUSE=y
-+CONFIG_NVMEM_MESON_EFUSE=m
- CONFIG_NVMEM_RMEM=m
- CONFIG_FPGA=y
- CONFIG_FPGA_MGR_STRATIX10_SOC=m
---- a/arch/mips/configs/ci20_defconfig
-+++ b/arch/mips/configs/ci20_defconfig
-@@ -137,7 +137,7 @@ CONFIG_MEMORY=y
- CONFIG_JZ4780_NEMC=y
- CONFIG_PWM=y
- CONFIG_PWM_JZ4740=m
--CONFIG_JZ4780_EFUSE=y
-+CONFIG_NVMEM_JZ4780_EFUSE=y
- CONFIG_JZ4770_PHY=y
- CONFIG_EXT4_FS=y
- # CONFIG_DNOTIFY is not set
---- a/drivers/cpufreq/Kconfig.arm
-+++ b/drivers/cpufreq/Kconfig.arm
-@@ -153,7 +153,7 @@ config ARM_OMAP2PLUS_CPUFREQ
- config ARM_QCOM_CPUFREQ_NVMEM
- tristate "Qualcomm nvmem based CPUFreq"
- depends on ARCH_QCOM
-- depends on QCOM_QFPROM
-+ depends on NVMEM_QCOM_QFPROM
- depends on QCOM_SMEM
- select PM_OPP
- help
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -52,7 +52,7 @@ config NVMEM_IMX_OCOTP_SCU
- This is a driver for the SCU On-Chip OTP Controller (OCOTP)
- available on i.MX8 SoCs.
-
--config JZ4780_EFUSE
-+config NVMEM_JZ4780_EFUSE
- tristate "JZ4780 EFUSE Memory Support"
- depends on MACH_INGENIC || COMPILE_TEST
- depends on HAS_IOMEM
-@@ -96,7 +96,7 @@ config NVMEM_MXS_OCOTP
- This driver can also be built as a module. If so, the module
- will be called nvmem-mxs-ocotp.
-
--config MTK_EFUSE
-+config NVMEM_MTK_EFUSE
- tristate "Mediatek SoCs EFUSE support"
- depends on ARCH_MEDIATEK || COMPILE_TEST
- depends on HAS_IOMEM
-@@ -107,7 +107,7 @@ config MTK_EFUSE
- This driver can also be built as a module. If so, the module
- will be called efuse-mtk.
-
--config MICROCHIP_OTPC
-+config NVMEM_MICROCHIP_OTPC
- tristate "Microchip OTPC support"
- depends on ARCH_AT91 || COMPILE_TEST
- help
-@@ -126,7 +126,7 @@ config NVMEM_NINTENDO_OTP
- This driver can also be built as a module. If so, the module
- will be called nvmem-nintendo-otp.
-
--config QCOM_QFPROM
-+config NVMEM_QCOM_QFPROM
- tristate "QCOM QFPROM Support"
- depends on ARCH_QCOM || COMPILE_TEST
- depends on HAS_IOMEM
-@@ -145,7 +145,7 @@ config NVMEM_SPMI_SDAM
- Qualcomm Technologies, Inc. PMICs. It provides the clients
- an interface to read/write to the SDAM module's shared memory.
-
--config ROCKCHIP_EFUSE
-+config NVMEM_ROCKCHIP_EFUSE
- tristate "Rockchip eFuse Support"
- depends on ARCH_ROCKCHIP || COMPILE_TEST
- depends on HAS_IOMEM
-@@ -156,7 +156,7 @@ config ROCKCHIP_EFUSE
- This driver can also be built as a module. If so, the module
- will be called nvmem_rockchip_efuse.
-
--config ROCKCHIP_OTP
-+config NVMEM_ROCKCHIP_OTP
- tristate "Rockchip OTP controller support"
- depends on ARCH_ROCKCHIP || COMPILE_TEST
- depends on HAS_IOMEM
-@@ -199,7 +199,7 @@ config NVMEM_SUNXI_SID
- This driver can also be built as a module. If so, the module
- will be called nvmem_sunxi_sid.
-
--config UNIPHIER_EFUSE
-+config NVMEM_UNIPHIER_EFUSE
- tristate "UniPhier SoCs eFuse support"
- depends on ARCH_UNIPHIER || COMPILE_TEST
- depends on HAS_IOMEM
-@@ -221,7 +221,7 @@ config NVMEM_VF610_OCOTP
- This driver can also be build as a module. If so, the module will
- be called nvmem-vf610-ocotp.
-
--config MESON_EFUSE
-+config NVMEM_MESON_EFUSE
- tristate "Amlogic Meson GX eFuse Support"
- depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM
- help
-@@ -231,7 +231,7 @@ config MESON_EFUSE
- This driver can also be built as a module. If so, the module
- will be called nvmem_meson_efuse.
-
--config MESON_MX_EFUSE
-+config NVMEM_MESON_MX_EFUSE
- tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support"
- depends on ARCH_MESON || COMPILE_TEST
- help
-@@ -251,13 +251,13 @@ config NVMEM_SNVS_LPGPR
- This driver can also be built as a module. If so, the module
- will be called nvmem-snvs-lpgpr.
-
--config RAVE_SP_EEPROM
-+config NVMEM_RAVE_SP_EEPROM
- tristate "Rave SP EEPROM Support"
- depends on RAVE_SP_CORE
- help
- Say y here to enable Rave SP EEPROM support.
-
--config SC27XX_EFUSE
-+config NVMEM_SC27XX_EFUSE
- tristate "Spreadtrum SC27XX eFuse Support"
- depends on MFD_SC27XX_PMIC || COMPILE_TEST
- depends on HAS_IOMEM
-@@ -278,7 +278,7 @@ config NVMEM_ZYNQMP
-
- If sure, say yes. If unsure, say no.
-
--config SPRD_EFUSE
-+config NVMEM_SPRD_EFUSE
- tristate "Spreadtrum SoC eFuse Support"
- depends on ARCH_SPRD || COMPILE_TEST
- depends on HAS_IOMEM
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -15,7 +15,7 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-i
- nvmem-imx-ocotp-y := imx-ocotp.o
- obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o
- nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o
--obj-$(CONFIG_JZ4780_EFUSE) += nvmem_jz4780_efuse.o
-+obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o
- nvmem_jz4780_efuse-y := jz4780-efuse.o
- obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o
- nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o
-@@ -25,37 +25,37 @@ obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-m
- nvmem-mxs-ocotp-y := mxs-ocotp.o
- obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o
- nvmem-nintendo-otp-y := nintendo-otp.o
--obj-$(CONFIG_MTK_EFUSE) += nvmem_mtk-efuse.o
-+obj-$(CONFIG_NVMEM_MTK_EFUSE) += nvmem_mtk-efuse.o
- nvmem_mtk-efuse-y := mtk-efuse.o
--obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o
-+obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o
- nvmem_qfprom-y := qfprom.o
- obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o
- nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o
--obj-$(CONFIG_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o
-+obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o
- nvmem_rockchip_efuse-y := rockchip-efuse.o
--obj-$(CONFIG_ROCKCHIP_OTP) += nvmem-rockchip-otp.o
-+obj-$(CONFIG_NVMEM_ROCKCHIP_OTP) += nvmem-rockchip-otp.o
- nvmem-rockchip-otp-y := rockchip-otp.o
- obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
- nvmem_stm32_romem-y := stm32-romem.o
- obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
- nvmem_sunxi_sid-y := sunxi_sid.o
--obj-$(CONFIG_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o
-+obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o
- nvmem-uniphier-efuse-y := uniphier-efuse.o
- obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvmem-vf610-ocotp.o
- nvmem-vf610-ocotp-y := vf610-ocotp.o
--obj-$(CONFIG_MESON_EFUSE) += nvmem_meson_efuse.o
-+obj-$(CONFIG_NVMEM_MESON_EFUSE) += nvmem_meson_efuse.o
- nvmem_meson_efuse-y := meson-efuse.o
--obj-$(CONFIG_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o
-+obj-$(CONFIG_NVMEM_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o
- nvmem_meson_mx_efuse-y := meson-mx-efuse.o
- obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o
- nvmem_snvs_lpgpr-y := snvs_lpgpr.o
--obj-$(CONFIG_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
-+obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
- nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
--obj-$(CONFIG_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o
-+obj-$(CONFIG_NVMEM_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o
- nvmem-sc27xx-efuse-y := sc27xx-efuse.o
- obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
- nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
--obj-$(CONFIG_SPRD_EFUSE) += nvmem_sprd_efuse.o
-+obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o
- nvmem_sprd_efuse-y := sprd-efuse.o
- obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
- nvmem-rmem-y := rmem.o
-@@ -67,7 +67,7 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvm
- nvmem_sunplus_ocotp-y := sunplus-ocotp.o
- obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
- nvmem-apple-efuses-y := apple-efuses.o
--obj-$(CONFIG_MICROCHIP_OTPC) += nvmem-microchip-otpc.o
-+obj-$(CONFIG_NVMEM_MICROCHIP_OTPC) += nvmem-microchip-otpc.o
- nvmem-microchip-otpc-y := microchip-otpc.o
- obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o
- nvmem_u-boot-env-y := u-boot-env.o
---- a/drivers/thermal/qcom/Kconfig
-+++ b/drivers/thermal/qcom/Kconfig
-@@ -1,7 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- config QCOM_TSENS
- tristate "Qualcomm TSENS Temperature Alarm"
-- depends on QCOM_QFPROM
-+ depends on NVMEM_QCOM_QFPROM
- depends on ARCH_QCOM || COMPILE_TEST
- help
- This enables the thermal sysfs driver for the TSENS device. It shows
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch b/target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch
deleted file mode 100644
index 4e45524bff..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch
+++ /dev/null
@@ -1,535 +0,0 @@
-From a06d9e5a63b7c2f622c908cd9600ce735e70f7c6 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Sep 2022 13:20:55 +0100
-Subject: [PATCH] nvmem: sort config symbols alphabetically
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Match what most subsystems do
-2. Simplify maintenance a bit
-3. Reduce amount of conflicts for new drivers patches
-
-While at it unify indent level in Makefile.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220916122100.170016-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 300 +++++++++++++++++++++--------------------
- drivers/nvmem/Makefile | 114 ++++++++--------
- 2 files changed, 208 insertions(+), 206 deletions(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -21,6 +21,40 @@ config NVMEM_SYSFS
- This interface is mostly used by userspace applications to
- read/write directly into nvmem.
-
-+# Devices
-+
-+config NVMEM_APPLE_EFUSES
-+ tristate "Apple eFuse support"
-+ depends on ARCH_APPLE || COMPILE_TEST
-+ default ARCH_APPLE
-+ help
-+ Say y here to enable support for reading eFuses on Apple SoCs
-+ such as the M1. These are e.g. used to store factory programmed
-+ calibration data required for the PCIe or the USB-C PHY.
-+
-+ This driver can also be built as a module. If so, the module will
-+ be called nvmem-apple-efuses.
-+
-+config NVMEM_BCM_OCOTP
-+ tristate "Broadcom On-Chip OTP Controller support"
-+ depends on ARCH_BCM_IPROC || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ default ARCH_BCM_IPROC
-+ help
-+ Say y here to enable read/write access to the Broadcom OTP
-+ controller.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem-bcm-ocotp.
-+
-+config NVMEM_BRCM_NVRAM
-+ tristate "Broadcom's NVRAM support"
-+ depends on ARCH_BCM_5301X || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This driver provides support for Broadcom's NVRAM that can be accessed
-+ using I/O mapping.
-+
- config NVMEM_IMX_IIM
- tristate "i.MX IC Identification Module support"
- depends on ARCH_MXC || COMPILE_TEST
-@@ -64,6 +98,19 @@ config NVMEM_JZ4780_EFUSE
- To compile this driver as a module, choose M here: the module
- will be called nvmem_jz4780_efuse.
-
-+config NVMEM_LAYERSCAPE_SFP
-+ tristate "Layerscape SFP (Security Fuse Processor) support"
-+ depends on ARCH_LAYERSCAPE || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ select REGMAP_MMIO
-+ help
-+ This driver provides support to read the eFuses on Freescale
-+ Layerscape SoC's. For example, the vendor provides a per part
-+ unique ID there.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called layerscape-sfp.
-+
- config NVMEM_LPC18XX_EEPROM
- tristate "NXP LPC18XX EEPROM Memory Support"
- depends on ARCH_LPC18XX || COMPILE_TEST
-@@ -84,17 +131,32 @@ config NVMEM_LPC18XX_OTP
- To compile this driver as a module, choose M here: the module
- will be called nvmem_lpc18xx_otp.
-
--config NVMEM_MXS_OCOTP
-- tristate "Freescale MXS On-Chip OTP Memory Support"
-- depends on ARCH_MXS || COMPILE_TEST
-- depends on HAS_IOMEM
-+config NVMEM_MESON_EFUSE
-+ tristate "Amlogic Meson GX eFuse Support"
-+ depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM
- help
-- If you say Y here, you will get readonly access to the
-- One Time Programmable memory pages that are stored
-- on the Freescale i.MX23/i.MX28 processor.
-+ This is a driver to retrieve specific values from the eFuse found on
-+ the Amlogic Meson GX SoCs.
-
- This driver can also be built as a module. If so, the module
-- will be called nvmem-mxs-ocotp.
-+ will be called nvmem_meson_efuse.
-+
-+config NVMEM_MESON_MX_EFUSE
-+ tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support"
-+ depends on ARCH_MESON || COMPILE_TEST
-+ help
-+ This is a driver to retrieve specific values from the eFuse found on
-+ the Amlogic Meson6, Meson8 and Meson8b SoCs.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem_meson_mx_efuse.
-+
-+config NVMEM_MICROCHIP_OTPC
-+ tristate "Microchip OTPC support"
-+ depends on ARCH_AT91 || COMPILE_TEST
-+ help
-+ This driver enable the OTP controller available on Microchip SAMA7G5
-+ SoCs. It controlls the access to the OTP memory connected to it.
-
- config NVMEM_MTK_EFUSE
- tristate "Mediatek SoCs EFUSE support"
-@@ -107,12 +169,17 @@ config NVMEM_MTK_EFUSE
- This driver can also be built as a module. If so, the module
- will be called efuse-mtk.
-
--config NVMEM_MICROCHIP_OTPC
-- tristate "Microchip OTPC support"
-- depends on ARCH_AT91 || COMPILE_TEST
-+config NVMEM_MXS_OCOTP
-+ tristate "Freescale MXS On-Chip OTP Memory Support"
-+ depends on ARCH_MXS || COMPILE_TEST
-+ depends on HAS_IOMEM
- help
-- This driver enable the OTP controller available on Microchip SAMA7G5
-- SoCs. It controlls the access to the OTP memory connected to it.
-+ If you say Y here, you will get readonly access to the
-+ One Time Programmable memory pages that are stored
-+ on the Freescale i.MX23/i.MX28 processor.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem-mxs-ocotp.
-
- config NVMEM_NINTENDO_OTP
- tristate "Nintendo Wii and Wii U OTP Support"
-@@ -137,13 +204,21 @@ config NVMEM_QCOM_QFPROM
- This driver can also be built as a module. If so, the module
- will be called nvmem_qfprom.
-
--config NVMEM_SPMI_SDAM
-- tristate "SPMI SDAM Support"
-- depends on SPMI
-+config NVMEM_RAVE_SP_EEPROM
-+ tristate "Rave SP EEPROM Support"
-+ depends on RAVE_SP_CORE
- help
-- This driver supports the Shared Direct Access Memory Module on
-- Qualcomm Technologies, Inc. PMICs. It provides the clients
-- an interface to read/write to the SDAM module's shared memory.
-+ Say y here to enable Rave SP EEPROM support.
-+
-+config NVMEM_RMEM
-+ tristate "Reserved Memory Based Driver Support"
-+ depends on HAS_IOMEM
-+ help
-+ This driver maps reserved memory into an nvmem device. It might be
-+ useful to expose information left by firmware in memory.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem-rmem.
-
- config NVMEM_ROCKCHIP_EFUSE
- tristate "Rockchip eFuse Support"
-@@ -167,79 +242,16 @@ config NVMEM_ROCKCHIP_OTP
- This driver can also be built as a module. If so, the module
- will be called nvmem_rockchip_otp.
-
--config NVMEM_BCM_OCOTP
-- tristate "Broadcom On-Chip OTP Controller support"
-- depends on ARCH_BCM_IPROC || COMPILE_TEST
-- depends on HAS_IOMEM
-- default ARCH_BCM_IPROC
-- help
-- Say y here to enable read/write access to the Broadcom OTP
-- controller.
--
-- This driver can also be built as a module. If so, the module
-- will be called nvmem-bcm-ocotp.
--
--config NVMEM_STM32_ROMEM
-- tristate "STMicroelectronics STM32 factory-programmed memory support"
-- depends on ARCH_STM32 || COMPILE_TEST
-- help
-- Say y here to enable read-only access for STMicroelectronics STM32
-- factory-programmed memory area.
--
-- This driver can also be built as a module. If so, the module
-- will be called nvmem-stm32-romem.
--
--config NVMEM_SUNXI_SID
-- tristate "Allwinner SoCs SID support"
-- depends on ARCH_SUNXI
-- help
-- This is a driver for the 'security ID' available on various Allwinner
-- devices.
--
-- This driver can also be built as a module. If so, the module
-- will be called nvmem_sunxi_sid.
--
--config NVMEM_UNIPHIER_EFUSE
-- tristate "UniPhier SoCs eFuse support"
-- depends on ARCH_UNIPHIER || COMPILE_TEST
-- depends on HAS_IOMEM
-- help
-- This is a simple driver to dump specified values of UniPhier SoC
-- from eFuse.
--
-- This driver can also be built as a module. If so, the module
-- will be called nvmem-uniphier-efuse.
--
--config NVMEM_VF610_OCOTP
-- tristate "VF610 SoC OCOTP support"
-- depends on SOC_VF610 || COMPILE_TEST
-+config NVMEM_SC27XX_EFUSE
-+ tristate "Spreadtrum SC27XX eFuse Support"
-+ depends on MFD_SC27XX_PMIC || COMPILE_TEST
- depends on HAS_IOMEM
- help
-- This is a driver for the 'OCOTP' peripheral available on Vybrid
-- devices like VF5xx and VF6xx.
--
-- This driver can also be build as a module. If so, the module will
-- be called nvmem-vf610-ocotp.
--
--config NVMEM_MESON_EFUSE
-- tristate "Amlogic Meson GX eFuse Support"
-- depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM
-- help
-- This is a driver to retrieve specific values from the eFuse found on
-- the Amlogic Meson GX SoCs.
--
-- This driver can also be built as a module. If so, the module
-- will be called nvmem_meson_efuse.
--
--config NVMEM_MESON_MX_EFUSE
-- tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support"
-- depends on ARCH_MESON || COMPILE_TEST
-- help
-- This is a driver to retrieve specific values from the eFuse found on
-- the Amlogic Meson6, Meson8 and Meson8b SoCs.
-+ This is a simple driver to dump specified values of Spreadtrum
-+ SC27XX PMICs from eFuse.
-
- This driver can also be built as a module. If so, the module
-- will be called nvmem_meson_mx_efuse.
-+ will be called nvmem-sc27xx-efuse.
-
- config NVMEM_SNVS_LPGPR
- tristate "Support for Low Power General Purpose Register"
-@@ -251,32 +263,13 @@ config NVMEM_SNVS_LPGPR
- This driver can also be built as a module. If so, the module
- will be called nvmem-snvs-lpgpr.
-
--config NVMEM_RAVE_SP_EEPROM
-- tristate "Rave SP EEPROM Support"
-- depends on RAVE_SP_CORE
-- help
-- Say y here to enable Rave SP EEPROM support.
--
--config NVMEM_SC27XX_EFUSE
-- tristate "Spreadtrum SC27XX eFuse Support"
-- depends on MFD_SC27XX_PMIC || COMPILE_TEST
-- depends on HAS_IOMEM
-- help
-- This is a simple driver to dump specified values of Spreadtrum
-- SC27XX PMICs from eFuse.
--
-- This driver can also be built as a module. If so, the module
-- will be called nvmem-sc27xx-efuse.
--
--config NVMEM_ZYNQMP
-- bool "Xilinx ZYNQMP SoC nvmem firmware support"
-- depends on ARCH_ZYNQMP
-+config NVMEM_SPMI_SDAM
-+ tristate "SPMI SDAM Support"
-+ depends on SPMI
- help
-- This is a driver to access hardware related data like
-- soc revision, IDCODE... etc by using the firmware
-- interface.
--
-- If sure, say yes. If unsure, say no.
-+ This driver supports the Shared Direct Access Memory Module on
-+ Qualcomm Technologies, Inc. PMICs. It provides the clients
-+ an interface to read/write to the SDAM module's shared memory.
-
- config NVMEM_SPRD_EFUSE
- tristate "Spreadtrum SoC eFuse Support"
-@@ -289,36 +282,15 @@ config NVMEM_SPRD_EFUSE
- This driver can also be built as a module. If so, the module
- will be called nvmem-sprd-efuse.
-
--config NVMEM_RMEM
-- tristate "Reserved Memory Based Driver Support"
-- depends on HAS_IOMEM
-- help
-- This driver maps reserved memory into an nvmem device. It might be
-- useful to expose information left by firmware in memory.
--
-- This driver can also be built as a module. If so, the module
-- will be called nvmem-rmem.
--
--config NVMEM_BRCM_NVRAM
-- tristate "Broadcom's NVRAM support"
-- depends on ARCH_BCM_5301X || COMPILE_TEST
-- depends on HAS_IOMEM
-- help
-- This driver provides support for Broadcom's NVRAM that can be accessed
-- using I/O mapping.
--
--config NVMEM_LAYERSCAPE_SFP
-- tristate "Layerscape SFP (Security Fuse Processor) support"
-- depends on ARCH_LAYERSCAPE || COMPILE_TEST
-- depends on HAS_IOMEM
-- select REGMAP_MMIO
-+config NVMEM_STM32_ROMEM
-+ tristate "STMicroelectronics STM32 factory-programmed memory support"
-+ depends on ARCH_STM32 || COMPILE_TEST
- help
-- This driver provides support to read the eFuses on Freescale
-- Layerscape SoC's. For example, the vendor provides a per part
-- unique ID there.
-+ Say y here to enable read-only access for STMicroelectronics STM32
-+ factory-programmed memory area.
-
- This driver can also be built as a module. If so, the module
-- will be called layerscape-sfp.
-+ will be called nvmem-stm32-romem.
-
- config NVMEM_SUNPLUS_OCOTP
- tristate "Sunplus SoC OTP support"
-@@ -332,17 +304,15 @@ config NVMEM_SUNPLUS_OCOTP
- This driver can also be built as a module. If so, the module
- will be called nvmem-sunplus-ocotp.
-
--config NVMEM_APPLE_EFUSES
-- tristate "Apple eFuse support"
-- depends on ARCH_APPLE || COMPILE_TEST
-- default ARCH_APPLE
-+config NVMEM_SUNXI_SID
-+ tristate "Allwinner SoCs SID support"
-+ depends on ARCH_SUNXI
- help
-- Say y here to enable support for reading eFuses on Apple SoCs
-- such as the M1. These are e.g. used to store factory programmed
-- calibration data required for the PCIe or the USB-C PHY.
-+ This is a driver for the 'security ID' available on various Allwinner
-+ devices.
-
-- This driver can also be built as a module. If so, the module will
-- be called nvmem-apple-efuses.
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem_sunxi_sid.
-
- config NVMEM_U_BOOT_ENV
- tristate "U-Boot environment variables support"
-@@ -357,4 +327,36 @@ config NVMEM_U_BOOT_ENV
-
- If compiled as module it will be called nvmem_u-boot-env.
-
-+config NVMEM_UNIPHIER_EFUSE
-+ tristate "UniPhier SoCs eFuse support"
-+ depends on ARCH_UNIPHIER || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This is a simple driver to dump specified values of UniPhier SoC
-+ from eFuse.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem-uniphier-efuse.
-+
-+config NVMEM_VF610_OCOTP
-+ tristate "VF610 SoC OCOTP support"
-+ depends on SOC_VF610 || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This is a driver for the 'OCOTP' peripheral available on Vybrid
-+ devices like VF5xx and VF6xx.
-+
-+ This driver can also be build as a module. If so, the module will
-+ be called nvmem-vf610-ocotp.
-+
-+config NVMEM_ZYNQMP
-+ bool "Xilinx ZYNQMP SoC nvmem firmware support"
-+ depends on ARCH_ZYNQMP
-+ help
-+ This is a driver to access hardware related data like
-+ soc revision, IDCODE... etc by using the firmware
-+ interface.
-+
-+ If sure, say yes. If unsure, say no.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -7,67 +7,67 @@ obj-$(CONFIG_NVMEM) += nvmem_core.o
- nvmem_core-y := core.o
-
- # Devices
--obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o
--nvmem-bcm-ocotp-y := bcm-ocotp.o
--obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-imx-iim.o
--nvmem-imx-iim-y := imx-iim.o
--obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o
--nvmem-imx-ocotp-y := imx-ocotp.o
-+obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
-+nvmem-apple-efuses-y := apple-efuses.o
-+obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o
-+nvmem-bcm-ocotp-y := bcm-ocotp.o
-+obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o
-+nvmem_brcm_nvram-y := brcm_nvram.o
-+obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-imx-iim.o
-+nvmem-imx-iim-y := imx-iim.o
-+obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o
-+nvmem-imx-ocotp-y := imx-ocotp.o
- obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o
--nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o
--obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o
--nvmem_jz4780_efuse-y := jz4780-efuse.o
-+nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o
-+obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o
-+nvmem_jz4780_efuse-y := jz4780-efuse.o
-+obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o
-+nvmem-layerscape-sfp-y := layerscape-sfp.o
- obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o
--nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o
--obj-$(CONFIG_NVMEM_LPC18XX_OTP) += nvmem_lpc18xx_otp.o
--nvmem_lpc18xx_otp-y := lpc18xx_otp.o
--obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o
--nvmem-mxs-ocotp-y := mxs-ocotp.o
--obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o
--nvmem-nintendo-otp-y := nintendo-otp.o
-+nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o
-+obj-$(CONFIG_NVMEM_LPC18XX_OTP) += nvmem_lpc18xx_otp.o
-+nvmem_lpc18xx_otp-y := lpc18xx_otp.o
-+obj-$(CONFIG_NVMEM_MESON_EFUSE) += nvmem_meson_efuse.o
-+nvmem_meson_efuse-y := meson-efuse.o
-+obj-$(CONFIG_NVMEM_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o
-+nvmem_meson_mx_efuse-y := meson-mx-efuse.o
-+obj-$(CONFIG_NVMEM_MICROCHIP_OTPC) += nvmem-microchip-otpc.o
-+nvmem-microchip-otpc-y := microchip-otpc.o
- obj-$(CONFIG_NVMEM_MTK_EFUSE) += nvmem_mtk-efuse.o
--nvmem_mtk-efuse-y := mtk-efuse.o
--obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o
--nvmem_qfprom-y := qfprom.o
--obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o
--nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o
-+nvmem_mtk-efuse-y := mtk-efuse.o
-+obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o
-+nvmem-mxs-ocotp-y := mxs-ocotp.o
-+obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o
-+nvmem-nintendo-otp-y := nintendo-otp.o
-+obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o
-+nvmem_qfprom-y := qfprom.o
-+obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
-+nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
-+obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
-+nvmem-rmem-y := rmem.o
- obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o
--nvmem_rockchip_efuse-y := rockchip-efuse.o
-+nvmem_rockchip_efuse-y := rockchip-efuse.o
- obj-$(CONFIG_NVMEM_ROCKCHIP_OTP) += nvmem-rockchip-otp.o
--nvmem-rockchip-otp-y := rockchip-otp.o
--obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
--nvmem_stm32_romem-y := stm32-romem.o
--obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
--nvmem_sunxi_sid-y := sunxi_sid.o
--obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o
--nvmem-uniphier-efuse-y := uniphier-efuse.o
--obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvmem-vf610-ocotp.o
--nvmem-vf610-ocotp-y := vf610-ocotp.o
--obj-$(CONFIG_NVMEM_MESON_EFUSE) += nvmem_meson_efuse.o
--nvmem_meson_efuse-y := meson-efuse.o
--obj-$(CONFIG_NVMEM_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o
--nvmem_meson_mx_efuse-y := meson-mx-efuse.o
--obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o
--nvmem_snvs_lpgpr-y := snvs_lpgpr.o
--obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
--nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
-+nvmem-rockchip-otp-y := rockchip-otp.o
- obj-$(CONFIG_NVMEM_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o
--nvmem-sc27xx-efuse-y := sc27xx-efuse.o
--obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
--nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
--obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o
--nvmem_sprd_efuse-y := sprd-efuse.o
--obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
--nvmem-rmem-y := rmem.o
--obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o
--nvmem_brcm_nvram-y := brcm_nvram.o
--obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o
--nvmem-layerscape-sfp-y := layerscape-sfp.o
-+nvmem-sc27xx-efuse-y := sc27xx-efuse.o
-+obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o
-+nvmem_snvs_lpgpr-y := snvs_lpgpr.o
-+obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o
-+nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o
-+obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o
-+nvmem_sprd_efuse-y := sprd-efuse.o
-+obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
-+nvmem_stm32_romem-y := stm32-romem.o
- obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
--nvmem_sunplus_ocotp-y := sunplus-ocotp.o
--obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
--nvmem-apple-efuses-y := apple-efuses.o
--obj-$(CONFIG_NVMEM_MICROCHIP_OTPC) += nvmem-microchip-otpc.o
--nvmem-microchip-otpc-y := microchip-otpc.o
--obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o
--nvmem_u-boot-env-y := u-boot-env.o
-+nvmem_sunplus_ocotp-y := sunplus-ocotp.o
-+obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
-+nvmem_sunxi_sid-y := sunxi_sid.o
-+obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o
-+nvmem_u-boot-env-y := u-boot-env.o
-+obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o
-+nvmem-uniphier-efuse-y := uniphier-efuse.o
-+obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvmem-vf610-ocotp.o
-+nvmem-vf610-ocotp-y := vf610-ocotp.o
-+obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
-+nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch
deleted file mode 100644
index e0a082adc4..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From d4d432670f7dee0a5432fcffcfc8699b25181ace Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Sep 2022 13:20:57 +0100
-Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-DT binding allows specifying NVMEM cells as NVMEM device (provider)
-subnodes. Looks for such subnodes when building NVMEM cells.
-
-This allows NVMEM consumers to use U-Boot environment variables.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220916122100.170016-11-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -92,6 +92,7 @@ static int u_boot_env_add_cells(struct u
- return -ENOMEM;
- priv->cells[idx].offset = data_offset + value - data;
- priv->cells[idx].bytes = strlen(value);
-+ priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
- }
-
- if (WARN_ON(idx != priv->ncells))
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch b/target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch
deleted file mode 100644
index 945c6128ff..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch
+++ /dev/null
@@ -1,274 +0,0 @@
-From 9e8f208ad5229ddda97cd4a83ecf89c735d99592 Mon Sep 17 00:00:00 2001
-From: Horatiu Vultur <horatiu.vultur@microchip.com>
-Date: Fri, 16 Sep 2022 13:20:59 +0100
-Subject: [PATCH] nvmem: lan9662-otp: add support
-
-Add support for OTP controller available on LAN9662. The OTPC controls
-the access to a non-volatile memory. The size of the memory is 8KB.
-The OTPC can access the memory based on an offset.
-Implement both the read and the write functionality.
-
-Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220916122100.170016-13-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 8 ++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/lan9662-otpc.c | 222 +++++++++++++++++++++++++++++++++++
- 3 files changed, 232 insertions(+)
- create mode 100644 drivers/nvmem/lan9662-otpc.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -98,6 +98,14 @@ config NVMEM_JZ4780_EFUSE
- To compile this driver as a module, choose M here: the module
- will be called nvmem_jz4780_efuse.
-
-+config NVMEM_LAN9662_OTPC
-+ tristate "Microchip LAN9662 OTP controller support"
-+ depends on SOC_LAN966 || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This driver enables the OTP controller available on Microchip LAN9662
-+ SoCs. It controls the access to the OTP memory connected to it.
-+
- config NVMEM_LAYERSCAPE_SFP
- tristate "Layerscape SFP (Security Fuse Processor) support"
- depends on ARCH_LAYERSCAPE || COMPILE_TEST
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -21,6 +21,8 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvm
- nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o
- obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o
- nvmem_jz4780_efuse-y := jz4780-efuse.o
-+obj-$(CONFIG_NVMEM_LAN9662_OTPC) += nvmem-lan9662-otpc.o
-+nvmem-lan9662-otpc-y := lan9662-otpc.o
- obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o
- nvmem-layerscape-sfp-y := layerscape-sfp.o
- obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o
---- /dev/null
-+++ b/drivers/nvmem/lan9662-otpc.c
-@@ -0,0 +1,222 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+
-+#define OTP_OTP_PWR_DN(t) (t + 0x00)
-+#define OTP_OTP_PWR_DN_OTP_PWRDN_N BIT(0)
-+#define OTP_OTP_ADDR_HI(t) (t + 0x04)
-+#define OTP_OTP_ADDR_LO(t) (t + 0x08)
-+#define OTP_OTP_PRGM_DATA(t) (t + 0x10)
-+#define OTP_OTP_PRGM_MODE(t) (t + 0x14)
-+#define OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE BIT(0)
-+#define OTP_OTP_RD_DATA(t) (t + 0x18)
-+#define OTP_OTP_FUNC_CMD(t) (t + 0x20)
-+#define OTP_OTP_FUNC_CMD_OTP_PROGRAM BIT(1)
-+#define OTP_OTP_FUNC_CMD_OTP_READ BIT(0)
-+#define OTP_OTP_CMD_GO(t) (t + 0x28)
-+#define OTP_OTP_CMD_GO_OTP_GO BIT(0)
-+#define OTP_OTP_PASS_FAIL(t) (t + 0x2c)
-+#define OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED BIT(3)
-+#define OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED BIT(2)
-+#define OTP_OTP_PASS_FAIL_OTP_FAIL BIT(0)
-+#define OTP_OTP_STATUS(t) (t + 0x30)
-+#define OTP_OTP_STATUS_OTP_CPUMPEN BIT(1)
-+#define OTP_OTP_STATUS_OTP_BUSY BIT(0)
-+
-+#define OTP_MEM_SIZE 8192
-+#define OTP_SLEEP_US 10
-+#define OTP_TIMEOUT_US 500000
-+
-+struct lan9662_otp {
-+ struct device *dev;
-+ void __iomem *base;
-+};
-+
-+static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag)
-+{
-+ u32 val;
-+
-+ return readl_poll_timeout(reg, val, !(val & flag),
-+ OTP_SLEEP_US, OTP_TIMEOUT_US);
-+}
-+
-+static int lan9662_otp_power(struct lan9662_otp *otp, bool up)
-+{
-+ void __iomem *pwrdn = OTP_OTP_PWR_DN(otp->base);
-+
-+ if (up) {
-+ writel(readl(pwrdn) & ~OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn);
-+ if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base),
-+ OTP_OTP_STATUS_OTP_CPUMPEN))
-+ return -ETIMEDOUT;
-+ } else {
-+ writel(readl(pwrdn) | OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn);
-+ }
-+
-+ return 0;
-+}
-+
-+static int lan9662_otp_execute(struct lan9662_otp *otp)
-+{
-+ if (lan9662_otp_wait_flag_clear(OTP_OTP_CMD_GO(otp->base),
-+ OTP_OTP_CMD_GO_OTP_GO))
-+ return -ETIMEDOUT;
-+
-+ if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base),
-+ OTP_OTP_STATUS_OTP_BUSY))
-+ return -ETIMEDOUT;
-+
-+ return 0;
-+}
-+
-+static void lan9662_otp_set_address(struct lan9662_otp *otp, u32 offset)
-+{
-+ writel(0xff & (offset >> 8), OTP_OTP_ADDR_HI(otp->base));
-+ writel(0xff & offset, OTP_OTP_ADDR_LO(otp->base));
-+}
-+
-+static int lan9662_otp_read_byte(struct lan9662_otp *otp, u32 offset, u8 *dst)
-+{
-+ u32 pass;
-+ int rc;
-+
-+ lan9662_otp_set_address(otp, offset);
-+ writel(OTP_OTP_FUNC_CMD_OTP_READ, OTP_OTP_FUNC_CMD(otp->base));
-+ writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base));
-+ rc = lan9662_otp_execute(otp);
-+ if (!rc) {
-+ pass = readl(OTP_OTP_PASS_FAIL(otp->base));
-+ if (pass & OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED)
-+ return -EACCES;
-+ *dst = (u8) readl(OTP_OTP_RD_DATA(otp->base));
-+ }
-+ return rc;
-+}
-+
-+static int lan9662_otp_write_byte(struct lan9662_otp *otp, u32 offset, u8 data)
-+{
-+ u32 pass;
-+ int rc;
-+
-+ lan9662_otp_set_address(otp, offset);
-+ writel(OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE, OTP_OTP_PRGM_MODE(otp->base));
-+ writel(data, OTP_OTP_PRGM_DATA(otp->base));
-+ writel(OTP_OTP_FUNC_CMD_OTP_PROGRAM, OTP_OTP_FUNC_CMD(otp->base));
-+ writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base));
-+
-+ rc = lan9662_otp_execute(otp);
-+ if (!rc) {
-+ pass = readl(OTP_OTP_PASS_FAIL(otp->base));
-+ if (pass & OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED)
-+ return -EACCES;
-+ if (pass & OTP_OTP_PASS_FAIL_OTP_FAIL)
-+ return -EIO;
-+ }
-+ return rc;
-+}
-+
-+static int lan9662_otp_read(void *context, unsigned int offset,
-+ void *_val, size_t bytes)
-+{
-+ struct lan9662_otp *otp = context;
-+ u8 *val = _val;
-+ uint8_t data;
-+ int i, rc = 0;
-+
-+ lan9662_otp_power(otp, true);
-+ for (i = 0; i < bytes; i++) {
-+ rc = lan9662_otp_read_byte(otp, offset + i, &data);
-+ if (rc < 0)
-+ break;
-+ *val++ = data;
-+ }
-+ lan9662_otp_power(otp, false);
-+
-+ return rc;
-+}
-+
-+static int lan9662_otp_write(void *context, unsigned int offset,
-+ void *_val, size_t bytes)
-+{
-+ struct lan9662_otp *otp = context;
-+ u8 *val = _val;
-+ u8 data, newdata;
-+ int i, rc = 0;
-+
-+ lan9662_otp_power(otp, true);
-+ for (i = 0; i < bytes; i++) {
-+ /* Skip zero bytes */
-+ if (val[i]) {
-+ rc = lan9662_otp_read_byte(otp, offset + i, &data);
-+ if (rc < 0)
-+ break;
-+
-+ newdata = data | val[i];
-+ if (newdata == data)
-+ continue;
-+
-+ rc = lan9662_otp_write_byte(otp, offset + i,
-+ newdata);
-+ if (rc < 0)
-+ break;
-+ }
-+ }
-+ lan9662_otp_power(otp, false);
-+
-+ return rc;
-+}
-+
-+static struct nvmem_config otp_config = {
-+ .name = "lan9662-otp",
-+ .stride = 1,
-+ .word_size = 1,
-+ .reg_read = lan9662_otp_read,
-+ .reg_write = lan9662_otp_write,
-+ .size = OTP_MEM_SIZE,
-+};
-+
-+static int lan9662_otp_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct nvmem_device *nvmem;
-+ struct lan9662_otp *otp;
-+
-+ otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL);
-+ if (!otp)
-+ return -ENOMEM;
-+
-+ otp->dev = dev;
-+ otp->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(otp->base))
-+ return PTR_ERR(otp->base);
-+
-+ otp_config.priv = otp;
-+ otp_config.dev = dev;
-+
-+ nvmem = devm_nvmem_register(dev, &otp_config);
-+
-+ return PTR_ERR_OR_ZERO(nvmem);
-+}
-+
-+static const struct of_device_id lan9662_otp_match[] = {
-+ { .compatible = "microchip,lan9662-otp", },
-+ { },
-+};
-+MODULE_DEVICE_TABLE(of, lan9662_otp_match);
-+
-+static struct platform_driver lan9662_otp_driver = {
-+ .probe = lan9662_otp_probe,
-+ .driver = {
-+ .name = "lan9662-otp",
-+ .of_match_table = lan9662_otp_match,
-+ },
-+};
-+module_platform_driver(lan9662_otp_driver);
-+
-+MODULE_AUTHOR("Horatiu Vultur <horatiu.vultur@microchip.com>");
-+MODULE_DESCRIPTION("lan9662 OTP driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch b/target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch
deleted file mode 100644
index 633a668a96..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3717ca3e0cc8683f93b41d3f06ca79631eb58715 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Sep 2022 13:21:00 +0100
-Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32
-
-Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220916122100.170016-14-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -139,7 +139,7 @@ static int u_boot_env_parse(struct u_boo
- data_offset = offsetof(struct u_boot_env_image_redundant, data);
- break;
- }
-- crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset));
-+ crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
- crc32_data_len = priv->mtd->size - crc32_data_offset;
- data_len = priv->mtd->size - data_offset;
-
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch b/target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch
deleted file mode 100644
index b663a1328d..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 1aeb122d214b92474c86fde00a03d6e2d69381b5 Mon Sep 17 00:00:00 2001
-From: Horatiu Vultur <horatiu.vultur@microchip.com>
-Date: Wed, 28 Sep 2022 21:51:12 +0200
-Subject: [PATCH] nvmem: lan9662-otp: Fix compatible string
-
-The device tree bindings for lan9662-otp expects the compatible string
-to be one of following compatible strings:
-microchip,lan9662-otpc
-microchip,lan9668-otpc
-
-The problem is that the lan9662-otp driver contains the
-microchip,lan9662-otp compatible string instead of
-microchip,lan9662-otpc.
-Fix this by updating the compatible string in the driver.
-
-Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support")
-Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
-Link: https://lore.kernel.org/r/20220928195112.630351-1-horatiu.vultur@microchip.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/lan9662-otpc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/lan9662-otpc.c
-+++ b/drivers/nvmem/lan9662-otpc.c
-@@ -203,7 +203,7 @@ static int lan9662_otp_probe(struct plat
- }
-
- static const struct of_device_id lan9662_otp_match[] = {
-- { .compatible = "microchip,lan9662-otp", },
-+ { .compatible = "microchip,lan9662-otpc", },
- { },
- };
- MODULE_DEVICE_TABLE(of, lan9662_otp_match);
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch b/target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch
deleted file mode 100644
index 967e891dbd..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From ee424f7d3960152f5f862bbb6943e59828dc7917 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Fri, 4 Nov 2022 17:52:03 +0100
-Subject: [PATCH] nvmem: u-boot-env: fix crc32_data_offset on redundant
- u-boot-env
-
-The Western Digital MyBook Live (PowerPC 464/APM82181)
-has a set of redundant u-boot-env. Loading up the driver
-the following error:
-
-| u_boot_env: Invalid calculated CRC32: 0x4f8f2c86 (expected: 0x98b14514)
-| u_boot_env: probe of partition@1e000 failed with error -22
-
-Looking up the userspace libubootenv utilities source [0],
-it looks like the "mark" or "flag" is not part of the
-crc32 sum... which is unfortunate :(
-
-|static int libuboot_load(struct uboot_ctx *ctx)
-|{
-|[...]
-| if (ctx->redundant) {
-| [...]
-| offsetdata = offsetof(struct uboot_env_redund, data);
-| [...] //-----^^
-| }
-| usable_envsize = ctx->size - offsetdata;
-| buf[0] = malloc(bufsize);
-|[...]
-| for (i = 0; i < copies; i++) {
-| data = (uint8_t *)(buf[i] + offsetdata);
-| uint32_t crc;
-|
-| ret = devread(ctx, i, buf[i]);
-| [...]
-| crc = *(uint32_t *)(buf[i] + offsetcrc);
-| dev->crc = crc32(0, (uint8_t *)data, usable_envsize);
-|
-
-[0] https://github.com/sbabic/libubootenv/blob/master/src/uboot_env.c#L951
-
-Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables")
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/70a16eae113e08db2390b76e174f4837caa135c3.1667580636.git.chunkeey@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -135,7 +135,7 @@ static int u_boot_env_parse(struct u_boo
- break;
- case U_BOOT_FORMAT_REDUNDANT:
- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
-- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, mark);
-+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
- data_offset = offsetof(struct u_boot_env_image_redundant, data);
- break;
- }
diff --git a/target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch b/target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch
deleted file mode 100644
index 0c842f0793..0000000000
--- a/target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 022b68f271de0e53024e6d5e96fee8e76d25eb95 Mon Sep 17 00:00:00 2001
-From: Horatiu Vultur <horatiu.vultur@microchip.com>
-Date: Fri, 18 Nov 2022 06:38:40 +0000
-Subject: [PATCH] nvmem: lan9662-otp: Change return type of
- lan9662_otp_wait_flag_clear()
-
-The blamed commit introduced the following smatch warning in the
-function lan9662_otp_wait_flag_clear:
-drivers/nvmem/lan9662-otpc.c:43 lan9662_otp_wait_flag_clear() warn: signedness bug returning '(-110)'
-
-Fix this by changing the return type of the function
-lan9662_otp_wait_flag_clear() to be int instead of bool.
-
-Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support")
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063840.6357-5-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/lan9662-otpc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/lan9662-otpc.c
-+++ b/drivers/nvmem/lan9662-otpc.c
-@@ -36,7 +36,7 @@ struct lan9662_otp {
- void __iomem *base;
- };
-
--static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag)
-+static int lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag)
- {
- u32 val;
-
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch b/target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch
deleted file mode 100644
index 33759632eb..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 18 Nov 2022 06:39:20 +0000
-Subject: [PATCH] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config
-
-Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare
-the next SoC in STM32MP family.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++-----
- 1 file changed, 16 insertions(+), 5 deletions(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -22,16 +22,15 @@
- /* shadow registers offest */
- #define STM32MP15_BSEC_DATA0 0x200
-
--/* 32 (x 32-bits) lower shadow registers */
--#define STM32MP15_BSEC_NUM_LOWER 32
--
- struct stm32_romem_cfg {
- int size;
-+ u8 lower;
- };
-
- struct stm32_romem_priv {
- void __iomem *base;
- struct nvmem_config cfg;
-+ u8 lower;
- };
-
- static int stm32_romem_read(void *context, unsigned int offset, void *buf,
-@@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context
- for (i = roffset; (i < roffset + rbytes); i += 4) {
- u32 otp = i >> 2;
-
-- if (otp < STM32MP15_BSEC_NUM_LOWER) {
-+ if (otp < priv->lower) {
- /* read lower data from shadow registers */
- val = readl_relaxed(
- priv->base + STM32MP15_BSEC_DATA0 + i);
-@@ -159,6 +158,8 @@ static int stm32_romem_probe(struct plat
- priv->cfg.priv = priv;
- priv->cfg.owner = THIS_MODULE;
-
-+ priv->lower = 0;
-+
- cfg = (const struct stm32_romem_cfg *)
- of_match_device(dev->driver->of_match_table, dev)->data;
- if (!cfg) {
-@@ -167,6 +168,7 @@ static int stm32_romem_probe(struct plat
- priv->cfg.reg_read = stm32_romem_read;
- } else {
- priv->cfg.size = cfg->size;
-+ priv->lower = cfg->lower;
- priv->cfg.reg_read = stm32_bsec_read;
- priv->cfg.reg_write = stm32_bsec_write;
- }
-@@ -174,8 +176,17 @@ static int stm32_romem_probe(struct plat
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
- }
-
-+/*
-+ * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
-+ * => 96 x 32-bits data words
-+ * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
-+ * => 32 (x 32-bits) lower shadow registers = words 0 to 31
-+ * - Upper: 2K bits, ECC protection, word programming only
-+ * => 64 (x 32-bits) = words 32 to 95
-+ */
- static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
-- .size = 384, /* 96 x 32-bits data words */
-+ .size = 384,
-+ .lower = 32,
- };
-
- static const struct of_device_id stm32_romem_of_match[] = {
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch b/target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch
deleted file mode 100644
index 5791df2606..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 18 Nov 2022 06:39:21 +0000
-Subject: [PATCH] nvmem: stm32: add warning when upper OTPs are updated
-
-As the upper OTPs are ECC protected, they support only one 32 bits word
-programming.
-For a second modification of this word, these ECC become invalid and
-this OTP will be no more accessible, the shadowed value is invalid.
-
-This patch adds a warning to indicate an upper OTP update, because this
-operation is dangerous as OTP is not locked by the driver after the first
-update to avoid a second update.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -132,6 +132,9 @@ static int stm32_bsec_write(void *contex
- }
- }
-
-+ if (offset + bytes >= priv->lower * 4)
-+ dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n");
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch b/target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch
deleted file mode 100644
index b83ad69c6b..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 18 Nov 2022 06:39:22 +0000
-Subject: [PATCH] nvmem: stm32: add nvmem type attribute
-
-Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP
-so userspace is able to know how the data is stored in BSEC.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -160,6 +160,7 @@ static int stm32_romem_probe(struct plat
- priv->cfg.dev = dev;
- priv->cfg.priv = priv;
- priv->cfg.owner = THIS_MODULE;
-+ priv->cfg.type = NVMEM_TYPE_OTP;
-
- priv->lower = 0;
-
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch b/target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch
deleted file mode 100644
index 52ba1e65b5..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001
-From: Jiangshan Yi <yijiangshan@kylinos.cn>
-Date: Fri, 18 Nov 2022 06:39:24 +0000
-Subject: [PATCH] nvmem: stm32: fix spelling typo in comment
-
-Fix spelling typo in comment.
-
-Reported-by: k2ci <kernel-bot@kylinos.cn>
-Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -19,7 +19,7 @@
- #define STM32_SMC_WRITE_SHADOW 0x03
- #define STM32_SMC_READ_OTP 0x04
-
--/* shadow registers offest */
-+/* shadow registers offset */
- #define STM32MP15_BSEC_DATA0 0x200
-
- struct stm32_romem_cfg {
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch b/target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch
deleted file mode 100644
index 8f024f4c1a..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001
-From: Colin Ian King <colin.i.king@gmail.com>
-Date: Fri, 18 Nov 2022 06:39:26 +0000
-Subject: [PATCH] nvmem: Kconfig: Fix spelling mistake "controlls" ->
- "controls"
-
-There is a spelling mistake in a Kconfig description. Fix it.
-
-Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC
- depends on ARCH_AT91 || COMPILE_TEST
- help
- This driver enable the OTP controller available on Microchip SAMA7G5
-- SoCs. It controlls the access to the OTP memory connected to it.
-+ SoCs. It controls the access to the OTP memory connected to it.
-
- config NVMEM_MTK_EFUSE
- tristate "Mediatek SoCs EFUSE support"
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch b/target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch
deleted file mode 100644
index 861386ad31..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 18 Nov 2022 06:39:27 +0000
-Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They
-decided to store U-Boot environment data inside U-Boot partition and to
-use a custom header (with "uEnv" magic and env data length).
-
-Add support for Broadcom's specific binding and their custom format.
-
-Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -16,6 +16,7 @@
- enum u_boot_env_format {
- U_BOOT_FORMAT_SINGLE,
- U_BOOT_FORMAT_REDUNDANT,
-+ U_BOOT_FORMAT_BROADCOM,
- };
-
- struct u_boot_env {
-@@ -40,6 +41,13 @@ struct u_boot_env_image_redundant {
- uint8_t data[];
- } __packed;
-
-+struct u_boot_env_image_broadcom {
-+ __le32 magic;
-+ __le32 len;
-+ __le32 crc32;
-+ uint8_t data[0];
-+} __packed;
-+
- static int u_boot_env_read(void *context, unsigned int offset, void *val,
- size_t bytes)
- {
-@@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boo
- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
- data_offset = offsetof(struct u_boot_env_image_redundant, data);
- break;
-+ case U_BOOT_FORMAT_BROADCOM:
-+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
-+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
-+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
-+ break;
- }
- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
- crc32_data_len = priv->mtd->size - crc32_data_offset;
-@@ -202,6 +215,7 @@ static const struct of_device_id u_boot_
- { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
- { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
- { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
-+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
- {},
- };
-
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch b/target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch
deleted file mode 100644
index 14108b5927..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From b0576ade3aaf24b376ea1a4406ae138e2a22b0c0 Mon Sep 17 00:00:00 2001
-From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
-Date: Fri, 27 Jan 2023 10:40:06 +0000
-Subject: [PATCH] nvmem: brcm_nvram: Add check for kzalloc
-
-Add the check for the return value of kzalloc in order to avoid
-NULL pointer dereference.
-
-Fixes: 6e977eaa8280 ("nvmem: brcm_nvram: parse NVRAM content into NVMEM cells")
-Cc: stable@vger.kernel.org
-Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230127104015.23839-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -97,6 +97,9 @@ static int brcm_nvram_parse(struct brcm_
- len = le32_to_cpu(header.len);
-
- data = kzalloc(len, GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
- memcpy_fromio(data, priv->base, len);
- data[len - 1] = '\0';
-
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch b/target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch
deleted file mode 100644
index 632b01cb2a..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From c151d5ed8e8fe0474bd61dce7f2076ca5916c683 Mon Sep 17 00:00:00 2001
-From: Samuel Holland <samuel@sholland.org>
-Date: Fri, 27 Jan 2023 10:40:07 +0000
-Subject: [PATCH] nvmem: sunxi_sid: Always use 32-bit MMIO reads
-
-The SID SRAM on at least some SoCs (A64 and D1) returns different values
-when read with bus cycles narrower than 32 bits. This is not immediately
-obvious, because memcpy_fromio() uses word-size accesses as long as
-enough data is being copied.
-
-The vendor driver always uses 32-bit MMIO reads, so do the same here.
-This is faster than the register-based method, which is currently used
-as a workaround on A64. And it fixes the values returned on D1, where
-the SRAM method was being used.
-
-The special case for the last word is needed to maintain .word_size == 1
-for sysfs ABI compatibility, as noted previously in commit de2a3eaea552
-("nvmem: sunxi_sid: Optimize register read-out method").
-
-Fixes: 07ae4fde9efa ("nvmem: sunxi_sid: Add support for D1 variant")
-Cc: stable@vger.kernel.org
-Tested-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Samuel Holland <samuel@sholland.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230127104015.23839-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/sunxi_sid.c | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/drivers/nvmem/sunxi_sid.c
-+++ b/drivers/nvmem/sunxi_sid.c
-@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context,
- void *val, size_t bytes)
- {
- struct sunxi_sid *sid = context;
-+ u32 word;
-
-- memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes);
-+ /* .stride = 4 so offset is guaranteed to be aligned */
-+ __ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4);
-+
-+ val += round_down(bytes, 4);
-+ offset += round_down(bytes, 4);
-+ bytes = bytes % 4;
-+
-+ if (!bytes)
-+ return 0;
-+
-+ /* Handle any trailing bytes */
-+ word = readl_relaxed(sid->base + sid->value_offset + offset);
-+ memcpy(val, &word, bytes);
-
- return 0;
- }
diff --git a/target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch b/target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch
deleted file mode 100644
index a229c303ad..0000000000
--- a/target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From edcf2fb660526b5ed29f93bd17328a2b4835c8b2 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Fri, 27 Jan 2023 10:40:12 +0000
-Subject: [PATCH] nvmem: core: fix device node refcounting
-
-In of_nvmem_cell_get(), of_get_next_parent() is used on cell_np. This
-will decrement the refcount on cell_np, but cell_np is still used later
-in the code. Use of_get_parent() instead and of_node_put() in the
-appropriate places.
-
-Fixes: 69aba7948cbe ("nvmem: Add a simple NVMEM framework for consumers")
-Fixes: 7ae6478b304b ("nvmem: core: rework nvmem cell instance creation")
-Cc: stable@vger.kernel.org
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230127104015.23839-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 11 ++++++++---
- 1 file changed, 8 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -1237,16 +1237,21 @@ struct nvmem_cell *of_nvmem_cell_get(str
- if (!cell_np)
- return ERR_PTR(-ENOENT);
-
-- nvmem_np = of_get_next_parent(cell_np);
-- if (!nvmem_np)
-+ nvmem_np = of_get_parent(cell_np);
-+ if (!nvmem_np) {
-+ of_node_put(cell_np);
- return ERR_PTR(-EINVAL);
-+ }
-
- nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
- of_node_put(nvmem_np);
-- if (IS_ERR(nvmem))
-+ if (IS_ERR(nvmem)) {
-+ of_node_put(cell_np);
- return ERR_CAST(nvmem);
-+ }
-
- cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
-+ of_node_put(cell_np);
- if (!cell_entry) {
- __nvmem_device_put(nvmem);
- return ERR_PTR(-ENOENT);
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch
deleted file mode 100644
index 01400fd490..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 6 Feb 2023 13:43:41 +0000
-Subject: [PATCH] nvmem: core: remove spurious white space
-
-Remove a spurious white space in for the ida_alloc() call.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons
- if (!nvmem)
- return ERR_PTR(-ENOMEM);
-
-- rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
-+ rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
- if (rval < 0) {
- kfree(nvmem);
- return ERR_PTR(rval);
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch
deleted file mode 100644
index 454d3bf0ed..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:46 +0000
-Subject: [PATCH] nvmem: core: add an index parameter to the cell
-
-Sometimes a cell can represend multiple values. For example, a base
-ethernet address stored in the NVMEM can be expanded into multiple
-discreet ones by adding an offset.
-
-For this use case, introduce an index parameter which is then used to
-distiguish between values. This parameter will then be passed to the
-post process hook which can then use it to create different values
-during reading.
-
-At the moment, there is only support for the device tree path. You can
-add the index to the phandle, e.g.
-
- &net {
- nvmem-cells = <&base_mac_address 2>;
- nvmem-cell-names = "mac-address";
- };
-
- &nvmem_provider {
- base_mac_address: base-mac-address@0 {
- #nvmem-cell-cells = <1>;
- reg = <0 6>;
- };
- };
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 37 ++++++++++++++++++++++++----------
- drivers/nvmem/imx-ocotp.c | 4 ++--
- include/linux/nvmem-provider.h | 4 ++--
- 3 files changed, 30 insertions(+), 15 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -60,6 +60,7 @@ struct nvmem_cell_entry {
- struct nvmem_cell {
- struct nvmem_cell_entry *entry;
- const char *id;
-+ int index;
- };
-
- static DEFINE_MUTEX(nvmem_mutex);
-@@ -1122,7 +1123,8 @@ struct nvmem_device *devm_nvmem_device_g
- }
- EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
-
--static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id)
-+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
-+ const char *id, int index)
- {
- struct nvmem_cell *cell;
- const char *name = NULL;
-@@ -1141,6 +1143,7 @@ static struct nvmem_cell *nvmem_create_c
-
- cell->id = name;
- cell->entry = entry;
-+ cell->index = index;
-
- return cell;
- }
-@@ -1179,7 +1182,7 @@ nvmem_cell_get_from_lookup(struct device
- __nvmem_device_put(nvmem);
- cell = ERR_PTR(-ENOENT);
- } else {
-- cell = nvmem_create_cell(cell_entry, con_id);
-+ cell = nvmem_create_cell(cell_entry, con_id, 0);
- if (IS_ERR(cell))
- __nvmem_device_put(nvmem);
- }
-@@ -1227,15 +1230,27 @@ struct nvmem_cell *of_nvmem_cell_get(str
- struct nvmem_device *nvmem;
- struct nvmem_cell_entry *cell_entry;
- struct nvmem_cell *cell;
-+ struct of_phandle_args cell_spec;
- int index = 0;
-+ int cell_index = 0;
-+ int ret;
-
- /* if cell name exists, find index to the name */
- if (id)
- index = of_property_match_string(np, "nvmem-cell-names", id);
-
-- cell_np = of_parse_phandle(np, "nvmem-cells", index);
-- if (!cell_np)
-- return ERR_PTR(-ENOENT);
-+ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells",
-+ "#nvmem-cell-cells",
-+ index, &cell_spec);
-+ if (ret)
-+ return ERR_PTR(ret);
-+
-+ if (cell_spec.args_count > 1)
-+ return ERR_PTR(-EINVAL);
-+
-+ cell_np = cell_spec.np;
-+ if (cell_spec.args_count)
-+ cell_index = cell_spec.args[0];
-
- nvmem_np = of_get_parent(cell_np);
- if (!nvmem_np) {
-@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
- return ERR_PTR(-ENOENT);
- }
-
-- cell = nvmem_create_cell(cell_entry, id);
-+ cell = nvmem_create_cell(cell_entry, id, cell_index);
- if (IS_ERR(cell))
- __nvmem_device_put(nvmem);
-
-@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p
- }
-
- static int __nvmem_cell_read(struct nvmem_device *nvmem,
-- struct nvmem_cell_entry *cell,
-- void *buf, size_t *len, const char *id)
-+ struct nvmem_cell_entry *cell,
-+ void *buf, size_t *len, const char *id, int index)
- {
- int rc;
-
-@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme
- nvmem_shift_read_buffer_in_place(cell, buf);
-
- if (nvmem->cell_post_process) {
-- rc = nvmem->cell_post_process(nvmem->priv, id,
-+ rc = nvmem->cell_post_process(nvmem->priv, id, index,
- cell->offset, buf, cell->bytes);
- if (rc)
- return rc;
-@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
-- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id);
-+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index);
- if (rc) {
- kfree(buf);
- return ERR_PTR(rc);
-@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv
- if (rc)
- return rc;
-
-- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL);
-+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0);
- if (rc)
- return rc;
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -222,8 +222,8 @@ read_end:
- return ret;
- }
-
--static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset,
-- void *data, size_t bytes)
-+static int imx_ocotp_cell_pp(void *context, const char *id, int index,
-+ unsigned int offset, void *data, size_t bytes)
- {
- struct ocotp_priv *priv = context;
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr
- typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
- void *val, size_t bytes);
- /* used for vendor specific post processing of cell data */
--typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset,
-- void *buf, size_t bytes);
-+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
-+ unsigned int offset, void *buf, size_t bytes);
-
- enum nvmem_type {
- NVMEM_TYPE_UNKNOWN = 0,
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch b/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch
deleted file mode 100644
index f3829b3e17..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:47 +0000
-Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h
-
-struct nvmem_cell_info is used to describe a cell. Thus this should
-really be in the nvmem-provider's header. There are two (unused) nvmem
-access methods which use the nvmem_cell_info to describe the cell to be
-accesses. One can argue, that they will create a cell before accessing,
-thus they are both a provider and a consumer.
-
-struct nvmem_cell_info will get used more and more by nvmem-providers,
-don't force them to also include the consumer header, although they are
-not.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/nvmem-consumer.h | 10 +---------
- include/linux/nvmem-provider.h | 19 ++++++++++++++++++-
- 2 files changed, 19 insertions(+), 10 deletions(-)
-
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -18,15 +18,7 @@ struct device_node;
- /* consumer cookie */
- struct nvmem_cell;
- struct nvmem_device;
--
--struct nvmem_cell_info {
-- const char *name;
-- unsigned int offset;
-- unsigned int bytes;
-- unsigned int bit_offset;
-- unsigned int nbits;
-- struct device_node *np;
--};
-+struct nvmem_cell_info;
-
- /**
- * struct nvmem_cell_lookup - cell lookup entry
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -14,7 +14,6 @@
- #include <linux/gpio/consumer.h>
-
- struct nvmem_device;
--struct nvmem_cell_info;
- typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
- void *val, size_t bytes);
- typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
-@@ -48,6 +47,24 @@ struct nvmem_keepout {
- };
-
- /**
-+ * struct nvmem_cell_info - NVMEM cell description
-+ * @name: Name.
-+ * @offset: Offset within the NVMEM device.
-+ * @bytes: Length of the cell.
-+ * @bit_offset: Bit offset if cell is smaller than a byte.
-+ * @nbits: Number of bits.
-+ * @np: Optional device_node pointer.
-+ */
-+struct nvmem_cell_info {
-+ const char *name;
-+ unsigned int offset;
-+ unsigned int bytes;
-+ unsigned int bit_offset;
-+ unsigned int nbits;
-+ struct device_node *np;
-+};
-+
-+/**
- * struct nvmem_config - NVMEM device configuration
- *
- * @dev: Parent device.
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch
deleted file mode 100644
index 8f996eab34..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:48 +0000
-Subject: [PATCH] nvmem: core: drop the removal of the cells in
- nvmem_add_cells()
-
-If nvmem_add_cells() fails, the whole nvmem_register() will fail
-and the cells will then be removed anyway. This is a preparation
-to introduce a nvmem_add_one_cell() which can then be used by
-nvmem_add_cells().
-
-This is then the same to what nvmem_add_cells_from_table() and
-nvmem_add_cells_from_of() do.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 14 ++++----------
- 1 file changed, 4 insertions(+), 10 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_
- int ncells)
- {
- struct nvmem_cell_entry **cells;
-- int i, rval;
-+ int i, rval = 0;
-
- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
- if (!cells)
-@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_
- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
- if (!cells[i]) {
- rval = -ENOMEM;
-- goto err;
-+ goto out;
- }
-
- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
- if (rval) {
- kfree(cells[i]);
-- goto err;
-+ goto out;
- }
-
- nvmem_cell_entry_add(cells[i]);
- }
-
-+out:
- /* remove tmp array */
- kfree(cells);
-
-- return 0;
--err:
-- while (i--)
-- nvmem_cell_entry_drop(cells[i]);
--
-- kfree(cells);
--
- return rval;
- }
-
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch
deleted file mode 100644
index 711ce229b2..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:49 +0000
-Subject: [PATCH] nvmem: core: add nvmem_add_one_cell()
-
-Add a new function to add exactly one cell. This will be used by the
-nvmem layout drivers to add custom cells. In contrast to the
-nvmem_add_cells(), this has the advantage that we don't have to assemble
-a list of cells on runtime.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 59 ++++++++++++++++++++--------------
- include/linux/nvmem-provider.h | 8 +++++
- 2 files changed, 43 insertions(+), 24 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell
- }
-
- /**
-+ * nvmem_add_one_cell() - Add one cell information to an nvmem device
-+ *
-+ * @nvmem: nvmem device to add cells to.
-+ * @info: nvmem cell info to add to the device
-+ *
-+ * Return: 0 or negative error code on failure.
-+ */
-+int nvmem_add_one_cell(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info)
-+{
-+ struct nvmem_cell_entry *cell;
-+ int rval;
-+
-+ cell = kzalloc(sizeof(*cell), GFP_KERNEL);
-+ if (!cell)
-+ return -ENOMEM;
-+
-+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell);
-+ if (rval) {
-+ kfree(cell);
-+ return rval;
-+ }
-+
-+ nvmem_cell_entry_add(cell);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(nvmem_add_one_cell);
-+
-+/**
- * nvmem_add_cells() - Add cell information to an nvmem device
- *
- * @nvmem: nvmem device to add cells to.
-@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_
- const struct nvmem_cell_info *info,
- int ncells)
- {
-- struct nvmem_cell_entry **cells;
-- int i, rval = 0;
--
-- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
-- if (!cells)
-- return -ENOMEM;
-+ int i, rval;
-
- for (i = 0; i < ncells; i++) {
-- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
-- if (!cells[i]) {
-- rval = -ENOMEM;
-- goto out;
-- }
--
-- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
-- if (rval) {
-- kfree(cells[i]);
-- goto out;
-- }
--
-- nvmem_cell_entry_add(cells[i]);
-+ rval = nvmem_add_one_cell(nvmem, &info[i]);
-+ if (rval)
-+ return rval;
- }
-
--out:
-- /* remove tmp array */
-- kfree(cells);
--
-- return rval;
-+ return 0;
- }
-
- /**
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -153,6 +153,9 @@ struct nvmem_device *devm_nvmem_register
- void nvmem_add_cell_table(struct nvmem_cell_table *table);
- void nvmem_del_cell_table(struct nvmem_cell_table *table);
-
-+int nvmem_add_one_cell(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info);
-+
- #else
-
- static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
-@@ -170,6 +173,11 @@ devm_nvmem_register(struct device *dev,
-
- static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {}
- static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {}
-+static inline int nvmem_add_one_cell(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info)
-+{
-+ return -EOPNOTSUPP;
-+}
-
- #endif /* CONFIG_NVMEM */
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch
deleted file mode 100644
index e1791e5c83..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:50 +0000
-Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in
- nvmem_add_cells_from_of()
-
-Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell().
-This will remove duplicate code and it will make it possible to add a
-hook to a nvmem layout in between, which can change fields before the
-cell is finally added.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 45 ++++++++++++++------------------------------
- 1 file changed, 14 insertions(+), 31 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc
-
- static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
- {
-- struct device_node *parent, *child;
- struct device *dev = &nvmem->dev;
-- struct nvmem_cell_entry *cell;
-+ struct device_node *child;
- const __be32 *addr;
-- int len;
-+ int len, ret;
-
-- parent = dev->of_node;
-+ for_each_child_of_node(dev->of_node, child) {
-+ struct nvmem_cell_info info = {0};
-
-- for_each_child_of_node(parent, child) {
- addr = of_get_property(child, "reg", &len);
- if (!addr)
- continue;
-@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc
- return -EINVAL;
- }
-
-- cell = kzalloc(sizeof(*cell), GFP_KERNEL);
-- if (!cell) {
-- of_node_put(child);
-- return -ENOMEM;
-- }
--
-- cell->nvmem = nvmem;
-- cell->offset = be32_to_cpup(addr++);
-- cell->bytes = be32_to_cpup(addr);
-- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
-+ info.offset = be32_to_cpup(addr++);
-+ info.bytes = be32_to_cpup(addr);
-+ info.name = kasprintf(GFP_KERNEL, "%pOFn", child);
-
- addr = of_get_property(child, "bits", &len);
- if (addr && len == (2 * sizeof(u32))) {
-- cell->bit_offset = be32_to_cpup(addr++);
-- cell->nbits = be32_to_cpup(addr);
-+ info.bit_offset = be32_to_cpup(addr++);
-+ info.nbits = be32_to_cpup(addr);
- }
-
-- if (cell->nbits)
-- cell->bytes = DIV_ROUND_UP(
-- cell->nbits + cell->bit_offset,
-- BITS_PER_BYTE);
--
-- if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
-- dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
-- cell->name, nvmem->stride);
-- /* Cells already added will be freed later. */
-- kfree_const(cell->name);
-- kfree(cell);
-+ info.np = of_node_get(child);
-+
-+ ret = nvmem_add_one_cell(nvmem, &info);
-+ kfree(info.name);
-+ if (ret) {
- of_node_put(child);
-- return -EINVAL;
-+ return ret;
- }
--
-- cell->np = of_node_get(child);
-- nvmem_cell_entry_add(cell);
- }
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch b/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch
deleted file mode 100644
index 172a78b76a..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch
+++ /dev/null
@@ -1,562 +0,0 @@
-From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Mon, 6 Feb 2023 13:43:51 +0000
-Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x
-
-For boot with OP-TEE on STM32MP13, the communication with the secure
-world no more use STMicroelectronics SMC but communication with the
-STM32MP BSEC TA, for data access (read/write) or lock operation:
-- all the request are sent to OP-TEE trusted application,
-- for upper OTP with ECC protection and with word programming only
- each OTP are permanently locked when programmed to avoid ECC error
- on the second write operation
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 11 +
- drivers/nvmem/Makefile | 1 +
- drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
- drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++
- drivers/nvmem/stm32-romem.c | 54 ++++-
- 5 files changed, 441 insertions(+), 3 deletions(-)
- create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
- create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
- This driver can also be built as a module. If so, the module
- will be called nvmem-sprd-efuse.
-
-+config NVMEM_STM32_BSEC_OPTEE_TA
-+ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
-+ depends on OPTEE
-+ help
-+ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
-+ trusted application STM32MP BSEC.
-+
-+ This library is a used by stm32-romem driver or included in the module
-+ called nvmem-stm32-romem.
-+
- config NVMEM_STM32_ROMEM
- tristate "STMicroelectronics STM32 factory-programmed memory support"
- depends on ARCH_STM32 || COMPILE_TEST
-+ imply NVMEM_STM32_BSEC_OPTEE_TA
- help
- Say y here to enable read-only access for STMicroelectronics STM32
- factory-programmed memory area.
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem
- nvmem_sprd_efuse-y := sprd-efuse.o
- obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
- nvmem_stm32_romem-y := stm32-romem.o
-+nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
- obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
- nvmem_sunplus_ocotp-y := sunplus-ocotp.o
- obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
---- /dev/null
-+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
-@@ -0,0 +1,298 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
-+ *
-+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
-+ */
-+
-+#include <linux/tee_drv.h>
-+
-+#include "stm32-bsec-optee-ta.h"
-+
-+/*
-+ * Read OTP memory
-+ *
-+ * [in] value[0].a OTP start offset in byte
-+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
-+ * [out] memref[1].buffer Output buffer to store read values
-+ * [out] memref[1].size Size of OTP to be read
-+ *
-+ * Return codes:
-+ * TEE_SUCCESS - Invoke command success
-+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
-+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
-+ */
-+#define PTA_BSEC_READ_MEM 0x0
-+
-+/*
-+ * Write OTP memory
-+ *
-+ * [in] value[0].a OTP start offset in byte
-+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
-+ * [in] memref[1].buffer Input buffer to read values
-+ * [in] memref[1].size Size of OTP to be written
-+ *
-+ * Return codes:
-+ * TEE_SUCCESS - Invoke command success
-+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
-+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
-+ */
-+#define PTA_BSEC_WRITE_MEM 0x1
-+
-+/* value of PTA_BSEC access type = value[in] b */
-+#define SHADOW_ACCESS 0
-+#define FUSE_ACCESS 1
-+#define LOCK_ACCESS 2
-+
-+/* Bitfield definition for LOCK status */
-+#define LOCK_PERM BIT(30)
-+
-+/* OP-TEE STM32MP BSEC TA UUID */
-+static const uuid_t stm32mp_bsec_ta_uuid =
-+ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
-+ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
-+
-+/*
-+ * Check whether this driver supports the BSEC TA in the TEE instance
-+ * represented by the params (ver/data) to this function.
-+ */
-+static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
-+ const void *data)
-+{
-+ /* Currently this driver only supports GP compliant, OP-TEE based TA */
-+ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
-+ (ver->gen_caps & TEE_GEN_CAP_GP))
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+/* Open a session to OP-TEE for STM32MP BSEC TA */
-+static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
-+{
-+ struct tee_ioctl_open_session_arg sess_arg;
-+ int rc;
-+
-+ memset(&sess_arg, 0, sizeof(sess_arg));
-+ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
-+ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
-+ sess_arg.num_params = 0;
-+
-+ rc = tee_client_open_session(ctx, &sess_arg, NULL);
-+ if ((rc < 0) || (sess_arg.ret != 0)) {
-+ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
-+ __func__, sess_arg.ret, rc);
-+ if (!rc)
-+ rc = -EINVAL;
-+ } else {
-+ *id = sess_arg.session;
-+ }
-+
-+ return rc;
-+}
-+
-+/* close a session to OP-TEE for STM32MP BSEC TA */
-+static void stm32_bsec_ta_close_session(void *ctx, u32 id)
-+{
-+ tee_client_close_session(ctx, id);
-+}
-+
-+/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
-+int stm32_bsec_optee_ta_open(struct tee_context **ctx)
-+{
-+ struct tee_context *tee_ctx;
-+ u32 session_id;
-+ int rc;
-+
-+ /* Open context with TEE driver */
-+ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
-+ if (IS_ERR(tee_ctx)) {
-+ rc = PTR_ERR(tee_ctx);
-+ if (rc == -ENOENT)
-+ return -EPROBE_DEFER;
-+ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
-+
-+ return rc;
-+ }
-+
-+ /* Check STM32MP BSEC TA presence */
-+ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
-+ if (rc) {
-+ tee_client_close_context(tee_ctx);
-+ return rc;
-+ }
-+
-+ stm32_bsec_ta_close_session(tee_ctx, session_id);
-+
-+ *ctx = tee_ctx;
-+
-+ return 0;
-+}
-+
-+/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
-+void stm32_bsec_optee_ta_close(void *ctx)
-+{
-+ tee_client_close_context(ctx);
-+}
-+
-+/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
-+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ struct tee_shm *shm;
-+ struct tee_ioctl_invoke_arg arg;
-+ struct tee_param param[2];
-+ u8 *shm_buf;
-+ u32 start, num_bytes;
-+ int ret;
-+ u32 session_id;
-+
-+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
-+ if (ret)
-+ return ret;
-+
-+ memset(&arg, 0, sizeof(arg));
-+ memset(&param, 0, sizeof(param));
-+
-+ arg.func = PTA_BSEC_READ_MEM;
-+ arg.session = session_id;
-+ arg.num_params = 2;
-+
-+ /* align access on 32bits */
-+ start = ALIGN_DOWN(offset, 4);
-+ num_bytes = round_up(offset + bytes - start, 4);
-+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-+ param[0].u.value.a = start;
-+ param[0].u.value.b = SHADOW_ACCESS;
-+
-+ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
-+ if (IS_ERR(shm)) {
-+ ret = PTR_ERR(shm);
-+ goto out_tee_session;
-+ }
-+
-+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
-+ param[1].u.memref.shm = shm;
-+ param[1].u.memref.size = num_bytes;
-+
-+ ret = tee_client_invoke_func(ctx, &arg, param);
-+ if (ret < 0 || arg.ret != 0) {
-+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
-+ arg.ret, ret);
-+ if (!ret)
-+ ret = -EIO;
-+ }
-+ if (!ret) {
-+ shm_buf = tee_shm_get_va(shm, 0);
-+ if (IS_ERR(shm_buf)) {
-+ ret = PTR_ERR(shm_buf);
-+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
-+ } else {
-+ /* read data from 32 bits aligned buffer */
-+ memcpy(buf, &shm_buf[offset % 4], bytes);
-+ }
-+ }
-+
-+ tee_shm_free(shm);
-+
-+out_tee_session:
-+ stm32_bsec_ta_close_session(ctx, session_id);
-+
-+ return ret;
-+}
-+
-+/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
-+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-+ unsigned int offset, void *buf, size_t bytes)
-+{ struct tee_shm *shm;
-+ struct tee_ioctl_invoke_arg arg;
-+ struct tee_param param[2];
-+ u8 *shm_buf;
-+ int ret;
-+ u32 session_id;
-+
-+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
-+ if (ret)
-+ return ret;
-+
-+ /* Allow only writing complete 32-bits aligned words */
-+ if ((bytes % 4) || (offset % 4))
-+ return -EINVAL;
-+
-+ memset(&arg, 0, sizeof(arg));
-+ memset(&param, 0, sizeof(param));
-+
-+ arg.func = PTA_BSEC_WRITE_MEM;
-+ arg.session = session_id;
-+ arg.num_params = 2;
-+
-+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-+ param[0].u.value.a = offset;
-+ param[0].u.value.b = FUSE_ACCESS;
-+
-+ shm = tee_shm_alloc_kernel_buf(ctx, bytes);
-+ if (IS_ERR(shm)) {
-+ ret = PTR_ERR(shm);
-+ goto out_tee_session;
-+ }
-+
-+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
-+ param[1].u.memref.shm = shm;
-+ param[1].u.memref.size = bytes;
-+
-+ shm_buf = tee_shm_get_va(shm, 0);
-+ if (IS_ERR(shm_buf)) {
-+ ret = PTR_ERR(shm_buf);
-+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
-+ tee_shm_free(shm);
-+
-+ goto out_tee_session;
-+ }
-+
-+ memcpy(shm_buf, buf, bytes);
-+
-+ ret = tee_client_invoke_func(ctx, &arg, param);
-+ if (ret < 0 || arg.ret != 0) {
-+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
-+ if (!ret)
-+ ret = -EIO;
-+ }
-+ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
-+
-+ /* Lock the upper OTPs with ECC protection, word programming only */
-+ if (!ret && ((offset + bytes) >= (lower * 4))) {
-+ u32 start, nb_lock;
-+ u32 *lock = (u32 *)shm_buf;
-+ int i;
-+
-+ /*
-+ * don't lock the lower OTPs, no ECC protection and incremental
-+ * bit programming, a second write is allowed
-+ */
-+ start = max_t(u32, offset, lower * 4);
-+ nb_lock = (offset + bytes - start) / 4;
-+
-+ param[0].u.value.a = start;
-+ param[0].u.value.b = LOCK_ACCESS;
-+ param[1].u.memref.size = nb_lock * 4;
-+
-+ for (i = 0; i < nb_lock; i++)
-+ lock[i] = LOCK_PERM;
-+
-+ ret = tee_client_invoke_func(ctx, &arg, param);
-+ if (ret < 0 || arg.ret != 0) {
-+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
-+ if (!ret)
-+ ret = -EIO;
-+ }
-+ pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
-+ start / 4, start / 4 + nb_lock, ret);
-+ }
-+
-+ tee_shm_free(shm);
-+
-+out_tee_session:
-+ stm32_bsec_ta_close_session(ctx, session_id);
-+
-+ return ret;
-+}
---- /dev/null
-+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
-@@ -0,0 +1,80 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+/*
-+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
-+ *
-+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
-+ */
-+
-+#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
-+/**
-+ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
-+ * @ctx: the OP-TEE context on success
-+ *
-+ * Return:
-+ * On success, 0. On failure, -errno.
-+ */
-+int stm32_bsec_optee_ta_open(struct tee_context **ctx);
-+
-+/**
-+ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
-+ * @ctx: the OP-TEE context
-+ *
-+ * This function used to clean the OP-TEE resources initialized in
-+ * stm32_bsec_optee_ta_open(); it can be used as callback to
-+ * devm_add_action_or_reset()
-+ */
-+void stm32_bsec_optee_ta_close(void *ctx);
-+
-+/**
-+ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
-+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
-+ * @offset: nvmem offset
-+ * @buf: buffer to fill with nvem values
-+ * @bytes: number of bytes to read
-+ *
-+ * Return:
-+ * On success, 0. On failure, -errno.
-+ */
-+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
-+ void *buf, size_t bytes);
-+
-+/**
-+ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
-+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
-+ * @lower: number of lower OTP, not protected by ECC
-+ * @offset: nvmem offset
-+ * @buf: buffer with nvem values
-+ * @bytes: number of bytes to write
-+ *
-+ * Return:
-+ * On success, 0. On failure, -errno.
-+ */
-+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-+ unsigned int offset, void *buf, size_t bytes);
-+
-+#else
-+
-+static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+static inline void stm32_bsec_optee_ta_close(void *ctx)
-+{
-+}
-+
-+static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
-+ unsigned int lower,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ return -EOPNOTSUPP;
-+}
-+#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -11,6 +11,9 @@
- #include <linux/module.h>
- #include <linux/nvmem-provider.h>
- #include <linux/of_device.h>
-+#include <linux/tee_drv.h>
-+
-+#include "stm32-bsec-optee-ta.h"
-
- /* BSEC secure service access from non-secure */
- #define STM32_SMC_BSEC 0x82001003
-@@ -25,12 +28,14 @@
- struct stm32_romem_cfg {
- int size;
- u8 lower;
-+ bool ta;
- };
-
- struct stm32_romem_priv {
- void __iomem *base;
- struct nvmem_config cfg;
- u8 lower;
-+ struct tee_context *ctx;
- };
-
- static int stm32_romem_read(void *context, unsigned int offset, void *buf,
-@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex
- return 0;
- }
-
-+static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ struct stm32_romem_priv *priv = context;
-+
-+ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
-+}
-+
-+static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ struct stm32_romem_priv *priv = context;
-+
-+ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
-+}
-+
- static int stm32_romem_probe(struct platform_device *pdev)
- {
- const struct stm32_romem_cfg *cfg;
- struct device *dev = &pdev->dev;
- struct stm32_romem_priv *priv;
- struct resource *res;
-+ int rc;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat
- } else {
- priv->cfg.size = cfg->size;
- priv->lower = cfg->lower;
-- priv->cfg.reg_read = stm32_bsec_read;
-- priv->cfg.reg_write = stm32_bsec_write;
-+ if (cfg->ta) {
-+ rc = stm32_bsec_optee_ta_open(&priv->ctx);
-+ /* wait for OP-TEE client driver to be up and ready */
-+ if (rc)
-+ return rc;
-+ }
-+ if (priv->ctx) {
-+ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
-+ if (rc) {
-+ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
-+ return rc;
-+ }
-+ priv->cfg.reg_read = stm32_bsec_pta_read;
-+ priv->cfg.reg_write = stm32_bsec_pta_write;
-+ } else {
-+ priv->cfg.reg_read = stm32_bsec_read;
-+ priv->cfg.reg_write = stm32_bsec_write;
-+ }
- }
-
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
- }
-
- /*
-- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
-+ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
- * => 96 x 32-bits data words
- * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
- * => 32 (x 32-bits) lower shadow registers = words 0 to 31
-@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat
- static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
- .size = 384,
- .lower = 32,
-+ .ta = false,
-+};
-+
-+static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
-+ .size = 384,
-+ .lower = 32,
-+ .ta = true,
- };
-
- static const struct of_device_id stm32_romem_of_match[] = {
-@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r
- .compatible = "st,stm32mp15-bsec",
- .data = (void *)&stm32mp15_bsec_cfg,
- }, {
-+ .compatible = "st,stm32mp13-bsec",
-+ .data = (void *)&stm32mp13_bsec_cfg,
- },
-+ { /* sentinel */ },
- };
- MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
-
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch b/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch
deleted file mode 100644
index cea8e93858..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Mon, 6 Feb 2023 13:43:52 +0000
-Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x
-
-On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used;
-the PTA BSEC should be used as it is done on STM32MP13x platform,
-but the BSEC SMC can be also used: it is a legacy mode in OP-TEE,
-not recommended but used in previous OP-TEE firmware.
-
-The presence of OP-TEE is dynamically detected in STM32MP15x device tree
-and the supported NVMEM backend is dynamically detected:
-- PTA with stm32_bsec_pta_find
-- SMC with stm32_bsec_check
-
-With OP-TEE but without PTA and SMC detection, the probe is deferred for
-STM32MP15x devices.
-
-On STM32MP13x platform, only the PTA is supported with cfg->ta = true
-and this detection is skipped.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++----
- 1 file changed, 34 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co
- return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
- }
-
-+static bool stm32_bsec_smc_check(void)
-+{
-+ u32 val;
-+ int ret;
-+
-+ /* check that the OP-TEE support the BSEC SMC (legacy mode) */
-+ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val);
-+
-+ return !ret;
-+}
-+
-+static bool optee_presence_check(void)
-+{
-+ struct device_node *np;
-+ bool tee_detected = false;
-+
-+ /* check that the OP-TEE node is present and available. */
-+ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz");
-+ if (np && of_device_is_available(np))
-+ tee_detected = true;
-+ of_node_put(np);
-+
-+ return tee_detected;
-+}
-+
- static int stm32_romem_probe(struct platform_device *pdev)
- {
- const struct stm32_romem_cfg *cfg;
-@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat
- } else {
- priv->cfg.size = cfg->size;
- priv->lower = cfg->lower;
-- if (cfg->ta) {
-+ if (cfg->ta || optee_presence_check()) {
- rc = stm32_bsec_optee_ta_open(&priv->ctx);
-- /* wait for OP-TEE client driver to be up and ready */
-- if (rc)
-- return rc;
-+ if (rc) {
-+ /* wait for OP-TEE client driver to be up and ready */
-+ if (rc == -EPROBE_DEFER)
-+ return -EPROBE_DEFER;
-+ /* BSEC PTA is required or SMC not supported */
-+ if (cfg->ta || !stm32_bsec_smc_check())
-+ return rc;
-+ }
- }
- if (priv->ctx) {
- rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch b/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch
deleted file mode 100644
index 9d6275a737..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001
-From: Randy Dunlap <rdunlap@infradead.org>
-Date: Mon, 6 Feb 2023 13:43:53 +0000
-Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning
-
-Convert an empty line to " *" to avoid a kernel-doc warning:
-
-drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line:
-
-Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
-Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Cc: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
-Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rave-sp-eeprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/rave-sp-eeprom.c
-+++ b/drivers/nvmem/rave-sp-eeprom.c
-@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size {
- * @type: Access type (see enum rave_sp_eeprom_access_type)
- * @success: Success flag (Success = 1, Failure = 0)
- * @data: Read data
--
-+ *
- * Note this structure corresponds to RSP_*_EEPROM payload from RAVE
- * SP ICD
- */
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch b/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch
deleted file mode 100644
index 1ab9e609d3..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001
-From: Johan Hovold <johan+linaro@kernel.org>
-Date: Mon, 6 Feb 2023 13:43:54 +0000
-Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time
-
-There are currently no in-tree users of the Qualcomm SDAM nvmem driver
-and there is generally no point in registering a driver that can be
-built as a module at subsys init time.
-
-Register the driver at the normal device init time instead and let
-driver core sort out the probe order.
-
-Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
-Reviewed-by: Bjorn Andersson <andersson@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qcom-spmi-sdam.c | 13 +------------
- 1 file changed, 1 insertion(+), 12 deletions(-)
-
---- a/drivers/nvmem/qcom-spmi-sdam.c
-+++ b/drivers/nvmem/qcom-spmi-sdam.c
-@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive
- },
- .probe = sdam_probe,
- };
--
--static int __init sdam_init(void)
--{
-- return platform_driver_register(&sdam_driver);
--}
--subsys_initcall(sdam_init);
--
--static void __exit sdam_exit(void)
--{
-- return platform_driver_unregister(&sdam_driver);
--}
--module_exit(sdam_exit);
-+module_platform_driver(sdam_driver);
-
- MODULE_DESCRIPTION("QCOM SPMI SDAM driver");
- MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch b/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch
deleted file mode 100644
index dcf704c6ff..0000000000
--- a/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Mon, 6 Feb 2023 13:43:56 +0000
-Subject: [PATCH] nvmem: stm32: fix OPTEE dependency
-
-The stm32 nvmem driver fails to link as built-in when OPTEE
-is a loadable module:
-
-aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
-stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session'
-aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
-stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context'
-
-Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only
-be built-in if OPTEE is either built-in or disabled, and
-make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE
- will be called nvmem-sprd-efuse.
-
- config NVMEM_STM32_BSEC_OPTEE_TA
-- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
-- depends on OPTEE
-+ def_bool NVMEM_STM32_ROMEM && OPTEE
- help
- Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
- trusted application STM32MP BSEC.
-@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA
- config NVMEM_STM32_ROMEM
- tristate "STMicroelectronics STM32 factory-programmed memory support"
- depends on ARCH_STM32 || COMPILE_TEST
-- imply NVMEM_STM32_BSEC_OPTEE_TA
-+ depends on OPTEE || !OPTEE
- help
- Say y here to enable read-only access for STMicroelectronics STM32
- factory-programmed memory area.
diff --git a/target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch b/target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch
deleted file mode 100644
index dbd734e9cf..0000000000
--- a/target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 078c6a1cbd4cd7496048786beec2e312577bebbf Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Tue, 11 Jan 2022 23:11:32 +0100
-Subject: [PATCH 1/1] net: qmi_wwan: add ZTE MF286D modem 19d2:1485
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Modem from ZTE MF286D is an Qualcomm MDM9250 based 3G/4G modem.
-
-T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=5000 MxCh= 0
-D: Ver= 3.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1
-P: Vendor=19d2 ProdID=1485 Rev=52.87
-S: Manufacturer=ZTE,Incorporated
-S: Product=ZTE Technologies MSM
-S: SerialNumber=MF286DZTED000000
-C:* #Ifs= 7 Cfg#= 1 Atr=80 MxPwr=896mA
-A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=06 Prot=00
-I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=ff Driver=rndis_host
-E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
-I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host
-E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
-E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
-E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
-E: Ad=84(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
-E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
-E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
-E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
-E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs
-E: Ad=05(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-E: Ad=89(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
-Acked-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/qmi_wwan.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/usb/qmi_wwan.c
-+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1317,6 +1317,7 @@ static const struct usb_device_id produc
- {QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */
- {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */
- {QMI_FIXED_INTF(0x19d2, 0x1432, 3)}, /* ZTE ME3620 */
-+ {QMI_FIXED_INTF(0x19d2, 0x1485, 5)}, /* ZTE MF286D */
- {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
- {QMI_FIXED_INTF(0x2001, 0x7e16, 3)}, /* D-Link DWM-221 */
- {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch b/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch
deleted file mode 100644
index 8328e87c0a..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From bcd1fe07def0f070eb5f31594620aaee6f81d31a Mon Sep 17 00:00:00 2001
-From: Nick Alcock <nick.alcock@oracle.com>
-Date: Tue, 4 Apr 2023 18:21:11 +0100
-Subject: [PATCH] nvmem: xilinx: zynqmp: make modular
-
-This driver has a MODULE_LICENSE but is not tristate so cannot be
-built as a module, unlike all its peers: make it modular to match.
-
-Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
-Suggested-by: Michal Simek <michal.simek@amd.com>
-Cc: Luis Chamberlain <mcgrof@kernel.org>
-Cc: linux-modules@vger.kernel.org
-Cc: linux-kernel@vger.kernel.org
-Cc: Hitomi Hasegawa <hasegawa-hitomi@fujitsu.com>
-Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Cc: Michal Simek <michal.simek@xilinx.com>
-Cc: linux-arm-kernel@lists.infradead.org
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -368,7 +368,7 @@ config NVMEM_VF610_OCOTP
- be called nvmem-vf610-ocotp.
-
- config NVMEM_ZYNQMP
-- bool "Xilinx ZYNQMP SoC nvmem firmware support"
-+ tristate "Xilinx ZYNQMP SoC nvmem firmware support"
- depends on ARCH_ZYNQMP
- help
- This is a driver to access hardware related data like
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch
deleted file mode 100644
index 23518d21f7..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch
+++ /dev/null
@@ -1,387 +0,0 @@
-From 266570f496b90dea8fda893c2cf7c28d63ae2bd9 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:21 +0100
-Subject: [PATCH] nvmem: core: introduce NVMEM layouts
-
-NVMEM layouts are used to generate NVMEM cells during runtime. Think of
-an EEPROM with a well-defined conent. For now, the content can be
-described by a device tree or a board file. But this only works if the
-offsets and lengths are static and don't change. One could also argue
-that putting the layout of the EEPROM in the device tree is the wrong
-place. Instead, the device tree should just have a specific compatible
-string.
-
-Right now there are two use cases:
- (1) The NVMEM cell needs special processing. E.g. if it only specifies
- a base MAC address offset and you need to add an offset, or it
- needs to parse a MAC from ASCII format or some proprietary format.
- (Post processing of cells is added in a later commit).
- (2) u-boot environment parsing. The cells don't have a particular
- offset but it needs parsing the content to determine the offsets
- and length.
-
-Co-developed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-14-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- Documentation/driver-api/nvmem.rst | 15 ++++
- drivers/nvmem/Kconfig | 4 +
- drivers/nvmem/Makefile | 1 +
- drivers/nvmem/core.c | 120 +++++++++++++++++++++++++++++
- drivers/nvmem/layouts/Kconfig | 5 ++
- drivers/nvmem/layouts/Makefile | 4 +
- include/linux/nvmem-consumer.h | 7 ++
- include/linux/nvmem-provider.h | 51 ++++++++++++
- 8 files changed, 207 insertions(+)
- create mode 100644 drivers/nvmem/layouts/Kconfig
- create mode 100644 drivers/nvmem/layouts/Makefile
-
---- a/Documentation/driver-api/nvmem.rst
-+++ b/Documentation/driver-api/nvmem.rst
-@@ -189,3 +189,18 @@ ex::
- =====================
-
- See Documentation/devicetree/bindings/nvmem/nvmem.txt
-+
-+8. NVMEM layouts
-+================
-+
-+NVMEM layouts are yet another mechanism to create cells. With the device
-+tree binding it is possible to specify simple cells by using an offset
-+and a length. Sometimes, the cells doesn't have a static offset, but
-+the content is still well defined, e.g. tag-length-values. In this case,
-+the NVMEM device content has to be first parsed and the cells need to
-+be added accordingly. Layouts let you read the content of the NVMEM device
-+and let you add cells dynamically.
-+
-+Another use case for layouts is the post processing of cells. With layouts,
-+it is possible to associate a custom post processing hook to a cell. It
-+even possible to add this hook to cells not created by the layout itself.
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -21,6 +21,10 @@ config NVMEM_SYSFS
- This interface is mostly used by userspace applications to
- read/write directly into nvmem.
-
-+# Layouts
-+
-+source "drivers/nvmem/layouts/Kconfig"
-+
- # Devices
-
- config NVMEM_APPLE_EFUSES
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -5,6 +5,7 @@
-
- obj-$(CONFIG_NVMEM) += nvmem_core.o
- nvmem_core-y := core.o
-+obj-y += layouts/
-
- # Devices
- obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -40,6 +40,7 @@ struct nvmem_device {
- nvmem_reg_write_t reg_write;
- nvmem_cell_post_process_t cell_post_process;
- struct gpio_desc *wp_gpio;
-+ struct nvmem_layout *layout;
- void *priv;
- };
-
-@@ -74,6 +75,9 @@ static LIST_HEAD(nvmem_lookup_list);
-
- static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
-
-+static DEFINE_SPINLOCK(nvmem_layout_lock);
-+static LIST_HEAD(nvmem_layouts);
-+
- static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
- void *val, size_t bytes)
- {
-@@ -728,6 +732,101 @@ static int nvmem_add_cells_from_of(struc
- return 0;
- }
-
-+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
-+{
-+ layout->owner = owner;
-+
-+ spin_lock(&nvmem_layout_lock);
-+ list_add(&layout->node, &nvmem_layouts);
-+ spin_unlock(&nvmem_layout_lock);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(__nvmem_layout_register);
-+
-+void nvmem_layout_unregister(struct nvmem_layout *layout)
-+{
-+ spin_lock(&nvmem_layout_lock);
-+ list_del(&layout->node);
-+ spin_unlock(&nvmem_layout_lock);
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-+
-+static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
-+{
-+ struct device_node *layout_np, *np = nvmem->dev.of_node;
-+ struct nvmem_layout *l, *layout = NULL;
-+
-+ layout_np = of_get_child_by_name(np, "nvmem-layout");
-+ if (!layout_np)
-+ return NULL;
-+
-+ spin_lock(&nvmem_layout_lock);
-+
-+ list_for_each_entry(l, &nvmem_layouts, node) {
-+ if (of_match_node(l->of_match_table, layout_np)) {
-+ if (try_module_get(l->owner))
-+ layout = l;
-+
-+ break;
-+ }
-+ }
-+
-+ spin_unlock(&nvmem_layout_lock);
-+ of_node_put(layout_np);
-+
-+ return layout;
-+}
-+
-+static void nvmem_layout_put(struct nvmem_layout *layout)
-+{
-+ if (layout)
-+ module_put(layout->owner);
-+}
-+
-+static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem)
-+{
-+ struct nvmem_layout *layout = nvmem->layout;
-+ int ret;
-+
-+ if (layout && layout->add_cells) {
-+ ret = layout->add_cells(&nvmem->dev, nvmem, layout);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+#if IS_ENABLED(CONFIG_OF)
-+/**
-+ * of_nvmem_layout_get_container() - Get OF node to layout container.
-+ *
-+ * @nvmem: nvmem device.
-+ *
-+ * Return: a node pointer with refcount incremented or NULL if no
-+ * container exists. Use of_node_put() on it when done.
-+ */
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
-+}
-+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container);
-+#endif
-+
-+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ struct device_node __maybe_unused *layout_np;
-+ const struct of_device_id *match;
-+
-+ layout_np = of_nvmem_layout_get_container(nvmem);
-+ match = of_match_node(layout->of_match_table, layout_np);
-+
-+ return match ? match->data : NULL;
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data);
-+
- /**
- * nvmem_register() - Register a nvmem device for given nvmem_config.
- * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
-@@ -834,6 +933,12 @@ struct nvmem_device *nvmem_register(cons
- goto err_put_device;
- }
-
-+ /*
-+ * If the driver supplied a layout by config->layout, the module
-+ * pointer will be NULL and nvmem_layout_put() will be a noop.
-+ */
-+ nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
-+
- if (config->cells) {
- rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
- if (rval)
-@@ -854,12 +959,17 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-+ rval = nvmem_add_cells_from_layout(nvmem);
-+ if (rval)
-+ goto err_remove_cells;
-+
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
-
- return nvmem;
-
- err_remove_cells:
- nvmem_device_remove_all_cells(nvmem);
-+ nvmem_layout_put(nvmem->layout);
- if (config->compat)
- nvmem_sysfs_remove_compat(nvmem, config);
- err_put_device:
-@@ -881,6 +991,7 @@ static void nvmem_device_release(struct
- device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
-
- nvmem_device_remove_all_cells(nvmem);
-+ nvmem_layout_put(nvmem->layout);
- device_unregister(&nvmem->dev);
- }
-
-@@ -1246,6 +1357,15 @@ struct nvmem_cell *of_nvmem_cell_get(str
- return ERR_PTR(-EINVAL);
- }
-
-+ /* nvmem layouts produce cells within the nvmem-layout container */
-+ if (of_node_name_eq(nvmem_np, "nvmem-layout")) {
-+ nvmem_np = of_get_next_parent(nvmem_np);
-+ if (!nvmem_np) {
-+ of_node_put(cell_np);
-+ return ERR_PTR(-EINVAL);
-+ }
-+ }
-+
- nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
- of_node_put(nvmem_np);
- if (IS_ERR(nvmem)) {
---- /dev/null
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -0,0 +1,5 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+menu "Layout Types"
-+
-+endmenu
---- /dev/null
-+++ b/drivers/nvmem/layouts/Makefile
-@@ -0,0 +1,4 @@
-+# SPDX-License-Identifier: GPL-2.0
-+#
-+# Makefile for nvmem layouts.
-+#
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -239,6 +239,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
- const char *id);
- struct nvmem_device *of_nvmem_device_get(struct device_node *np,
- const char *name);
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem);
- #else
- static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
- const char *id)
-@@ -251,6 +252,12 @@ static inline struct nvmem_device *of_nv
- {
- return ERR_PTR(-EOPNOTSUPP);
- }
-+
-+static inline struct device_node *
-+of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return ERR_PTR(-EOPNOTSUPP);
-+}
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
- #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -88,6 +88,7 @@ struct nvmem_cell_info {
- * @stride: Minimum read/write access stride.
- * @priv: User context passed to read/write callbacks.
- * @ignore_wp: Write Protect pin is managed by the provider.
-+ * @layout: Fixed layout associated with this nvmem device.
- *
- * Note: A default "nvmem<id>" name will be assigned to the device if
- * no name is specified in its configuration. In such case "<id>" is
-@@ -109,6 +110,7 @@ struct nvmem_config {
- bool read_only;
- bool root_only;
- bool ignore_wp;
-+ struct nvmem_layout *layout;
- struct device_node *of_node;
- bool no_of_node;
- nvmem_reg_read_t reg_read;
-@@ -142,6 +144,33 @@ struct nvmem_cell_table {
- struct list_head node;
- };
-
-+/**
-+ * struct nvmem_layout - NVMEM layout definitions
-+ *
-+ * @name: Layout name.
-+ * @of_match_table: Open firmware match table.
-+ * @add_cells: Will be called if a nvmem device is found which
-+ * has this layout. The function will add layout
-+ * specific cells with nvmem_add_one_cell().
-+ * @owner: Pointer to struct module.
-+ * @node: List node.
-+ *
-+ * A nvmem device can hold a well defined structure which can just be
-+ * evaluated during runtime. For example a TLV list, or a list of "name=val"
-+ * pairs. A nvmem layout can parse the nvmem device and add appropriate
-+ * cells.
-+ */
-+struct nvmem_layout {
-+ const char *name;
-+ const struct of_device_id *of_match_table;
-+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout);
-+
-+ /* private */
-+ struct module *owner;
-+ struct list_head node;
-+};
-+
- #if IS_ENABLED(CONFIG_NVMEM)
-
- struct nvmem_device *nvmem_register(const struct nvmem_config *cfg);
-@@ -156,6 +185,14 @@ void nvmem_del_cell_table(struct nvmem_c
- int nvmem_add_one_cell(struct nvmem_device *nvmem,
- const struct nvmem_cell_info *info);
-
-+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner);
-+#define nvmem_layout_register(layout) \
-+ __nvmem_layout_register(layout, THIS_MODULE)
-+void nvmem_layout_unregister(struct nvmem_layout *layout);
-+
-+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout);
-+
- #else
-
- static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
-@@ -179,5 +216,19 @@ static inline int nvmem_add_one_cell(str
- return -EOPNOTSUPP;
- }
-
-+static inline int nvmem_layout_register(struct nvmem_layout *layout)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {}
-+
-+static inline const void *
-+nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ return NULL;
-+}
-+
- #endif /* CONFIG_NVMEM */
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
deleted file mode 100644
index 6fa7b6382d..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:22 +0100
-Subject: [PATCH] nvmem: core: handle the absence of expected layouts
-
-Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout
-is not available. This condition cannot be triggered today as nvmem
-layout drivers are initialed as part of an early init call, but soon
-these drivers will be converted into modules and be initialized with a
-standard priority, so the unavailability of the drivers might become a
-reality that must be taken care of.
-
-Let's anticipate this by telling the caller the layout might not yet be
-available. A probe deferral is requested in this case.
-
-Please note this does not affect any nvmem device not using layouts,
-because an early check against the "nvmem-layout" container presence
-will return NULL in this case.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
- static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
- {
- struct device_node *layout_np, *np = nvmem->dev.of_node;
-- struct nvmem_layout *l, *layout = NULL;
-+ struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
-
- layout_np = of_get_child_by_name(np, "nvmem-layout");
- if (!layout_np)
-@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons
- * pointer will be NULL and nvmem_layout_put() will be a noop.
- */
- nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
-+ if (IS_ERR(nvmem->layout)) {
-+ rval = PTR_ERR(nvmem->layout);
-+ nvmem->layout = NULL;
-+
-+ if (rval == -EPROBE_DEFER)
-+ goto err_teardown_compat;
-+ }
-
- if (config->cells) {
- rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
-@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons
- err_remove_cells:
- nvmem_device_remove_all_cells(nvmem);
- nvmem_layout_put(nvmem->layout);
-+err_teardown_compat:
- if (config->compat)
- nvmem_sysfs_remove_compat(nvmem, config);
- err_put_device:
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch
deleted file mode 100644
index b9341666f9..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From b1c37bec1ccfe5ccab72bc0ddc0dfa45c43e2de2 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:23 +0100
-Subject: [PATCH] nvmem: core: request layout modules loading
-
-When a storage device like an eeprom or an mtd device probes, it
-registers an nvmem device if the nvmem subsystem has been enabled (bool
-symbol). During nvmem registration, if the device is using layouts to
-expose dynamic nvmem cells, the core will first try to get a reference
-over the layout driver callbacks. In practice there is not relationship
-that can be described between the storage driver and the nvmem
-layout. So there is no way we can enforce both drivers will be built-in
-or both will be modules. If the storage device driver is built-in but
-the layout is built as a module, instead of badly failing with an
-endless probe deferral loop, lets just make a modprobe call in case the
-driver was made available in an initramfs with
-of_device_node_request_module(), and offer a fully functional system to
-the user.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-16-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -17,6 +17,7 @@
- #include <linux/nvmem-provider.h>
- #include <linux/gpio/consumer.h>
- #include <linux/of.h>
-+#include <linux/of_device.h>
- #include <linux/slab.h>
-
- struct nvmem_device {
-@@ -761,6 +762,13 @@ static struct nvmem_layout *nvmem_layout
- if (!layout_np)
- return NULL;
-
-+ /*
-+ * In case the nvmem device was built-in while the layout was built as a
-+ * module, we shall manually request the layout driver loading otherwise
-+ * we'll never have any match.
-+ */
-+ of_request_module(layout_np);
-+
- spin_lock(&nvmem_layout_lock);
-
- list_for_each_entry(l, &nvmem_layouts, node) {
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch
deleted file mode 100644
index 53628cd4e4..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 345ec382cd4b736c36e01f155d08c913b225b736 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:24 +0100
-Subject: [PATCH] nvmem: core: add per-cell post processing
-
-Instead of relying on the name the consumer is using for the cell, like
-it is done for the nvmem .cell_post_process configuration parameter,
-provide a per-cell post processing hook. This can then be populated by
-the NVMEM provider (or the NVMEM layout) when adding the cell.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-17-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 17 +++++++++++++++++
- include/linux/nvmem-provider.h | 3 +++
- 2 files changed, 20 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -54,6 +54,7 @@ struct nvmem_cell_entry {
- int bytes;
- int bit_offset;
- int nbits;
-+ nvmem_cell_post_process_t read_post_process;
- struct device_node *np;
- struct nvmem_device *nvmem;
- struct list_head node;
-@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell
- cell->offset = info->offset;
- cell->bytes = info->bytes;
- cell->name = info->name;
-+ cell->read_post_process = info->read_post_process;
-
- cell->bit_offset = info->bit_offset;
- cell->nbits = info->nbits;
-@@ -1563,6 +1565,13 @@ static int __nvmem_cell_read(struct nvme
- if (cell->bit_offset || cell->nbits)
- nvmem_shift_read_buffer_in_place(cell, buf);
-
-+ if (cell->read_post_process) {
-+ rc = cell->read_post_process(nvmem->priv, id, index,
-+ cell->offset, buf, cell->bytes);
-+ if (rc)
-+ return rc;
-+ }
-+
- if (nvmem->cell_post_process) {
- rc = nvmem->cell_post_process(nvmem->priv, id, index,
- cell->offset, buf, cell->bytes);
-@@ -1671,6 +1680,14 @@ static int __nvmem_cell_entry_write(stru
- (cell->bit_offset == 0 && len != cell->bytes))
- return -EINVAL;
-
-+ /*
-+ * Any cells which have a read_post_process hook are read-only because
-+ * we cannot reverse the operation and it might affect other cells,
-+ * too.
-+ */
-+ if (cell->read_post_process)
-+ return -EINVAL;
-+
- if (cell->bit_offset || cell->nbits) {
- buf = nvmem_cell_prepare_write_buffer(cell, buf, len);
- if (IS_ERR(buf))
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -54,6 +54,8 @@ struct nvmem_keepout {
- * @bit_offset: Bit offset if cell is smaller than a byte.
- * @nbits: Number of bits.
- * @np: Optional device_node pointer.
-+ * @read_post_process: Callback for optional post processing of cell data
-+ * on reads.
- */
- struct nvmem_cell_info {
- const char *name;
-@@ -62,6 +64,7 @@ struct nvmem_cell_info {
- unsigned int bit_offset;
- unsigned int nbits;
- struct device_node *np;
-+ nvmem_cell_post_process_t read_post_process;
- };
-
- /**
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch
deleted file mode 100644
index 32990148c8..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From de12c9691501ccba41a154c223869f82be4c12fd Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:25 +0100
-Subject: [PATCH] nvmem: core: allow to modify a cell before adding it
-
-Provide a way to modify a cell before it will get added. This is useful
-to attach a custom post processing hook via a layout.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-18-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 4 ++++
- include/linux/nvmem-provider.h | 5 +++++
- 2 files changed, 9 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -695,6 +695,7 @@ static int nvmem_validate_keepouts(struc
-
- static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
- {
-+ struct nvmem_layout *layout = nvmem->layout;
- struct device *dev = &nvmem->dev;
- struct device_node *child;
- const __be32 *addr;
-@@ -724,6 +725,9 @@ static int nvmem_add_cells_from_of(struc
-
- info.np = of_node_get(child);
-
-+ if (layout && layout->fixup_cell_info)
-+ layout->fixup_cell_info(nvmem, layout, &info);
-+
- ret = nvmem_add_one_cell(nvmem, &info);
- kfree(info.name);
- if (ret) {
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -155,6 +155,8 @@ struct nvmem_cell_table {
- * @add_cells: Will be called if a nvmem device is found which
- * has this layout. The function will add layout
- * specific cells with nvmem_add_one_cell().
-+ * @fixup_cell_info: Will be called before a cell is added. Can be
-+ * used to modify the nvmem_cell_info.
- * @owner: Pointer to struct module.
- * @node: List node.
- *
-@@ -168,6 +170,9 @@ struct nvmem_layout {
- const struct of_device_id *of_match_table;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem,
- struct nvmem_layout *layout);
-+ void (*fixup_cell_info)(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout,
-+ struct nvmem_cell_info *cell);
-
- /* private */
- struct module *owner;
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch b/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch
deleted file mode 100644
index 2a5fa618ea..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 6c56a82d7895a213a43182a5d01a21a906a79847 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:26 +0100
-Subject: [PATCH] nvmem: imx-ocotp: replace global post processing with layouts
-
-In preparation of retiring the global post processing hook change this
-driver to use layouts. The layout will be supplied during registration
-and will be used to add the post processing hook to all added cells.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Tested-by: Michael Walle <michael@walle.cc> # on kontron-pitx-imx8m
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-19-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/imx-ocotp.c | 30 +++++++++++++++++++-----------
- 1 file changed, 19 insertions(+), 11 deletions(-)
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -225,18 +225,13 @@ read_end:
- static int imx_ocotp_cell_pp(void *context, const char *id, int index,
- unsigned int offset, void *data, size_t bytes)
- {
-- struct ocotp_priv *priv = context;
-+ u8 *buf = data;
-+ int i;
-
- /* Deal with some post processing of nvmem cell data */
-- if (id && !strcmp(id, "mac-address")) {
-- if (priv->params->reverse_mac_address) {
-- u8 *buf = data;
-- int i;
--
-- for (i = 0; i < bytes/2; i++)
-- swap(buf[i], buf[bytes - i - 1]);
-- }
-- }
-+ if (id && !strcmp(id, "mac-address"))
-+ for (i = 0; i < bytes / 2; i++)
-+ swap(buf[i], buf[bytes - i - 1]);
-
- return 0;
- }
-@@ -488,7 +483,6 @@ static struct nvmem_config imx_ocotp_nvm
- .stride = 1,
- .reg_read = imx_ocotp_read,
- .reg_write = imx_ocotp_write,
-- .cell_post_process = imx_ocotp_cell_pp,
- };
-
- static const struct ocotp_params imx6q_params = {
-@@ -595,6 +589,17 @@ static const struct of_device_id imx_oco
- };
- MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
-
-+static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout,
-+ struct nvmem_cell_info *cell)
-+{
-+ cell->read_post_process = imx_ocotp_cell_pp;
-+}
-+
-+struct nvmem_layout imx_ocotp_layout = {
-+ .fixup_cell_info = imx_ocotp_fixup_cell_info,
-+};
-+
- static int imx_ocotp_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -619,6 +624,9 @@ static int imx_ocotp_probe(struct platfo
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
-+ if (priv->params->reverse_mac_address)
-+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-+
- priv->config = &imx_ocotp_nvmem_config;
-
- clk_prepare_enable(priv->clk);
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch
deleted file mode 100644
index eac202b882..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 011e40a166fdaa65fb9946b7cd91efec85b70dbb Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:27 +0100
-Subject: [PATCH] nvmem: cell: drop global cell_post_process
-
-There are no users anymore for the global cell_post_process callback
-anymore. New users should use proper nvmem layouts.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-20-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 9 ---------
- include/linux/nvmem-provider.h | 2 --
- 2 files changed, 11 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -39,7 +39,6 @@ struct nvmem_device {
- unsigned int nkeepout;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
-- nvmem_cell_post_process_t cell_post_process;
- struct gpio_desc *wp_gpio;
- struct nvmem_layout *layout;
- void *priv;
-@@ -903,7 +902,6 @@ struct nvmem_device *nvmem_register(cons
- nvmem->type = config->type;
- nvmem->reg_read = config->reg_read;
- nvmem->reg_write = config->reg_write;
-- nvmem->cell_post_process = config->cell_post_process;
- nvmem->keepout = config->keepout;
- nvmem->nkeepout = config->nkeepout;
- if (config->of_node)
-@@ -1575,13 +1573,6 @@ static int __nvmem_cell_read(struct nvme
- if (rc)
- return rc;
- }
--
-- if (nvmem->cell_post_process) {
-- rc = nvmem->cell_post_process(nvmem->priv, id, index,
-- cell->offset, buf, cell->bytes);
-- if (rc)
-- return rc;
-- }
-
- if (len)
- *len = cell->bytes;
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -85,7 +85,6 @@ struct nvmem_cell_info {
- * @no_of_node: Device should not use the parent's of_node even if it's !NULL.
- * @reg_read: Callback to read data.
- * @reg_write: Callback to write data.
-- * @cell_post_process: Callback for vendor specific post processing of cell data
- * @size: Device size.
- * @word_size: Minimum read/write access granularity.
- * @stride: Minimum read/write access stride.
-@@ -118,7 +117,6 @@ struct nvmem_config {
- bool no_of_node;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
-- nvmem_cell_post_process_t cell_post_process;
- int size;
- int word_size;
- int stride;
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch
deleted file mode 100644
index 46b30a2ed9..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 8a134fd9f9323f4c39ec27055b3d3723cfb5c1e9 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:28 +0100
-Subject: [PATCH] nvmem: core: provide own priv pointer in post process
- callback
-
-It doesn't make any more sense to have a opaque pointer set up by the
-nvmem device. Usually, the layout isn't associated with a particular
-nvmem device. Instead, let the caller who set the post process callback
-provide the priv pointer.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-21-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 4 +++-
- include/linux/nvmem-provider.h | 5 ++++-
- 2 files changed, 7 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -54,6 +54,7 @@ struct nvmem_cell_entry {
- int bit_offset;
- int nbits;
- nvmem_cell_post_process_t read_post_process;
-+ void *priv;
- struct device_node *np;
- struct nvmem_device *nvmem;
- struct list_head node;
-@@ -471,6 +472,7 @@ static int nvmem_cell_info_to_nvmem_cell
- cell->bytes = info->bytes;
- cell->name = info->name;
- cell->read_post_process = info->read_post_process;
-+ cell->priv = info->priv;
-
- cell->bit_offset = info->bit_offset;
- cell->nbits = info->nbits;
-@@ -1568,7 +1570,7 @@ static int __nvmem_cell_read(struct nvme
- nvmem_shift_read_buffer_in_place(cell, buf);
-
- if (cell->read_post_process) {
-- rc = cell->read_post_process(nvmem->priv, id, index,
-+ rc = cell->read_post_process(cell->priv, id, index,
- cell->offset, buf, cell->bytes);
- if (rc)
- return rc;
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -20,7 +20,8 @@ typedef int (*nvmem_reg_write_t)(void *p
- void *val, size_t bytes);
- /* used for vendor specific post processing of cell data */
- typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
-- unsigned int offset, void *buf, size_t bytes);
-+ unsigned int offset, void *buf,
-+ size_t bytes);
-
- enum nvmem_type {
- NVMEM_TYPE_UNKNOWN = 0,
-@@ -56,6 +57,7 @@ struct nvmem_keepout {
- * @np: Optional device_node pointer.
- * @read_post_process: Callback for optional post processing of cell data
- * on reads.
-+ * @priv: Opaque data passed to the read_post_process hook.
- */
- struct nvmem_cell_info {
- const char *name;
-@@ -65,6 +67,7 @@ struct nvmem_cell_info {
- unsigned int nbits;
- struct device_node *np;
- nvmem_cell_post_process_t read_post_process;
-+ void *priv;
- };
-
- /**
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch
deleted file mode 100644
index 7d97658b60..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch
+++ /dev/null
@@ -1,215 +0,0 @@
-From d9fae023fe86069750092fc1c2f3a73e2fb18512 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:29 +0100
-Subject: [PATCH] nvmem: layouts: sl28vpd: Add new layout driver
-
-This layout applies to the VPD of the Kontron sl28 boards. The VPD only
-contains a base MAC address. Therefore, we have to add an individual
-offset to it. This is done by taking the second argument of the nvmem
-phandle into account. Also this let us checking the VPD version and the
-checksum.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-22-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/Kconfig | 9 ++
- drivers/nvmem/layouts/Makefile | 2 +
- drivers/nvmem/layouts/sl28vpd.c | 165 ++++++++++++++++++++++++++++++++
- 3 files changed, 176 insertions(+)
- create mode 100644 drivers/nvmem/layouts/sl28vpd.c
-
---- a/drivers/nvmem/layouts/Kconfig
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -2,4 +2,13 @@
-
- menu "Layout Types"
-
-+config NVMEM_LAYOUT_SL28_VPD
-+ tristate "Kontron sl28 VPD layout support"
-+ select CRC8
-+ help
-+ Say Y here if you want to support the VPD layout of the Kontron
-+ SMARC-sAL28 boards.
-+
-+ If unsure, say N.
-+
- endmenu
---- a/drivers/nvmem/layouts/Makefile
-+++ b/drivers/nvmem/layouts/Makefile
-@@ -2,3 +2,5 @@
- #
- # Makefile for nvmem layouts.
- #
-+
-+obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
---- /dev/null
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -0,0 +1,165 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/crc8.h>
-+#include <linux/etherdevice.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+#include <uapi/linux/if_ether.h>
-+
-+#define SL28VPD_MAGIC 'V'
-+
-+struct sl28vpd_header {
-+ u8 magic;
-+ u8 version;
-+} __packed;
-+
-+struct sl28vpd_v1 {
-+ struct sl28vpd_header header;
-+ char serial_number[15];
-+ u8 base_mac_address[ETH_ALEN];
-+ u8 crc8;
-+} __packed;
-+
-+static int sl28vpd_mac_address_pp(void *priv, const char *id, int index,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ if (bytes != ETH_ALEN)
-+ return -EINVAL;
-+
-+ if (index < 0)
-+ return -EINVAL;
-+
-+ if (!is_valid_ether_addr(buf))
-+ return -EINVAL;
-+
-+ eth_addr_add(buf, index);
-+
-+ return 0;
-+}
-+
-+static const struct nvmem_cell_info sl28vpd_v1_entries[] = {
-+ {
-+ .name = "serial-number",
-+ .offset = offsetof(struct sl28vpd_v1, serial_number),
-+ .bytes = sizeof_field(struct sl28vpd_v1, serial_number),
-+ },
-+ {
-+ .name = "base-mac-address",
-+ .offset = offsetof(struct sl28vpd_v1, base_mac_address),
-+ .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address),
-+ .read_post_process = sl28vpd_mac_address_pp,
-+ },
-+};
-+
-+static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem)
-+{
-+ struct sl28vpd_v1 data_v1;
-+ u8 table[CRC8_TABLE_SIZE];
-+ int ret;
-+ u8 crc;
-+
-+ crc8_populate_msb(table, 0x07);
-+
-+ ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1);
-+ if (ret < 0)
-+ return ret;
-+ else if (ret != sizeof(data_v1))
-+ return -EIO;
-+
-+ crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0);
-+
-+ if (crc != data_v1.crc8) {
-+ dev_err(dev,
-+ "Checksum is invalid (got %02x, expected %02x).\n",
-+ crc, data_v1.crc8);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ const struct nvmem_cell_info *pinfo;
-+ struct nvmem_cell_info info = {0};
-+ struct device_node *layout_np;
-+ struct sl28vpd_header hdr;
-+ int ret, i;
-+
-+ /* check header */
-+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr);
-+ if (ret < 0)
-+ return ret;
-+ else if (ret != sizeof(hdr))
-+ return -EIO;
-+
-+ if (hdr.magic != SL28VPD_MAGIC) {
-+ dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic);
-+ return -EINVAL;
-+ }
-+
-+ if (hdr.version != 1) {
-+ dev_err(dev, "Version %d is unsupported.\n", hdr.version);
-+ return -EINVAL;
-+ }
-+
-+ ret = sl28vpd_v1_check_crc(dev, nvmem);
-+ if (ret)
-+ return ret;
-+
-+ layout_np = of_nvmem_layout_get_container(nvmem);
-+ if (!layout_np)
-+ return -ENOENT;
-+
-+ for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) {
-+ pinfo = &sl28vpd_v1_entries[i];
-+
-+ info.name = pinfo->name;
-+ info.offset = pinfo->offset;
-+ info.bytes = pinfo->bytes;
-+ info.read_post_process = pinfo->read_post_process;
-+ info.np = of_get_child_by_name(layout_np, pinfo->name);
-+
-+ ret = nvmem_add_one_cell(nvmem, &info);
-+ if (ret) {
-+ of_node_put(layout_np);
-+ return ret;
-+ }
-+ }
-+
-+ of_node_put(layout_np);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id sl28vpd_of_match_table[] = {
-+ { .compatible = "kontron,sl28-vpd" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table);
-+
-+struct nvmem_layout sl28vpd_layout = {
-+ .name = "sl28-vpd",
-+ .of_match_table = sl28vpd_of_match_table,
-+ .add_cells = sl28vpd_add_cells,
-+};
-+
-+static int __init sl28vpd_init(void)
-+{
-+ return nvmem_layout_register(&sl28vpd_layout);
-+}
-+
-+static void __exit sl28vpd_exit(void)
-+{
-+ nvmem_layout_unregister(&sl28vpd_layout);
-+}
-+
-+module_init(sl28vpd_init);
-+module_exit(sl28vpd_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
-+MODULE_DESCRIPTION("NVMEM layout driver for the VPD of Kontron sl28 boards");
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch
deleted file mode 100644
index ca8b4bc069..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch
+++ /dev/null
@@ -1,306 +0,0 @@
-From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:31 +0100
-Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver
-
-This layout applies on top of any non volatile storage device containing
-an ONIE table factory flashed. This table follows the tlv
-(type-length-value) organization described in the link below. We cannot
-afford using regular parsers because the content of these tables is
-manufacturer specific and must be dynamically discovered.
-
-Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/Kconfig | 9 ++
- drivers/nvmem/layouts/Makefile | 1 +
- drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++
- 3 files changed, 267 insertions(+)
- create mode 100644 drivers/nvmem/layouts/onie-tlv.c
-
---- a/drivers/nvmem/layouts/Kconfig
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD
-
- If unsure, say N.
-
-+config NVMEM_LAYOUT_ONIE_TLV
-+ tristate "ONIE tlv support"
-+ select CRC32
-+ help
-+ Say Y here if you want to support the Open Compute Project ONIE
-+ Type-Length-Value standard table.
-+
-+ If unsure, say N.
-+
- endmenu
---- a/drivers/nvmem/layouts/Makefile
-+++ b/drivers/nvmem/layouts/Makefile
-@@ -4,3 +4,4 @@
- #
-
- obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
-+obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
---- /dev/null
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -0,0 +1,257 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * ONIE tlv NVMEM cells provider
-+ *
-+ * Copyright (C) 2022 Open Compute Group ONIE
-+ * Author: Miquel Raynal <miquel.raynal@bootlin.com>
-+ * Based on the nvmem driver written by: Vadym Kochan <vadym.kochan@plvision.eu>
-+ * Inspired by the first layout written by: Rafał Miłecki <rafal@milecki.pl>
-+ */
-+
-+#include <linux/crc32.h>
-+#include <linux/etherdevice.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+
-+#define ONIE_TLV_MAX_LEN 2048
-+#define ONIE_TLV_CRC_FIELD_SZ 6
-+#define ONIE_TLV_CRC_SZ 4
-+#define ONIE_TLV_HDR_ID "TlvInfo"
-+
-+struct onie_tlv_hdr {
-+ u8 id[8];
-+ u8 version;
-+ __be16 data_len;
-+} __packed;
-+
-+struct onie_tlv {
-+ u8 type;
-+ u8 len;
-+} __packed;
-+
-+static const char *onie_tlv_cell_name(u8 type)
-+{
-+ switch (type) {
-+ case 0x21:
-+ return "product-name";
-+ case 0x22:
-+ return "part-number";
-+ case 0x23:
-+ return "serial-number";
-+ case 0x24:
-+ return "mac-address";
-+ case 0x25:
-+ return "manufacture-date";
-+ case 0x26:
-+ return "device-version";
-+ case 0x27:
-+ return "label-revision";
-+ case 0x28:
-+ return "platform-name";
-+ case 0x29:
-+ return "onie-version";
-+ case 0x2A:
-+ return "num-macs";
-+ case 0x2B:
-+ return "manufacturer";
-+ case 0x2C:
-+ return "country-code";
-+ case 0x2D:
-+ return "vendor";
-+ case 0x2E:
-+ return "diag-version";
-+ case 0x2F:
-+ return "service-tag";
-+ case 0xFD:
-+ return "vendor-extension";
-+ case 0xFE:
-+ return "crc32";
-+ default:
-+ break;
-+ }
-+
-+ return NULL;
-+}
-+
-+static int onie_tlv_mac_read_cb(void *priv, const char *id, int index,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ eth_addr_add(buf, index);
-+
-+ return 0;
-+}
-+
-+static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf)
-+{
-+ switch (type) {
-+ case 0x24:
-+ return &onie_tlv_mac_read_cb;
-+ default:
-+ break;
-+ }
-+
-+ return NULL;
-+}
-+
-+static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem,
-+ size_t data_len, u8 *data)
-+{
-+ struct nvmem_cell_info cell = {};
-+ struct device_node *layout;
-+ struct onie_tlv tlv;
-+ unsigned int hdr_len = sizeof(struct onie_tlv_hdr);
-+ unsigned int offset = 0;
-+ int ret;
-+
-+ layout = of_nvmem_layout_get_container(nvmem);
-+ if (!layout)
-+ return -ENOENT;
-+
-+ while (offset < data_len) {
-+ memcpy(&tlv, data + offset, sizeof(tlv));
-+ if (offset + tlv.len >= data_len) {
-+ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n",
-+ tlv.len, hdr_len + offset);
-+ break;
-+ }
-+
-+ cell.name = onie_tlv_cell_name(tlv.type);
-+ if (!cell.name)
-+ continue;
-+
-+ cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len);
-+ cell.bytes = tlv.len;
-+ cell.np = of_get_child_by_name(layout, cell.name);
-+ cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv));
-+
-+ ret = nvmem_add_one_cell(nvmem, &cell);
-+ if (ret) {
-+ of_node_put(layout);
-+ return ret;
-+ }
-+
-+ offset += sizeof(tlv) + tlv.len;
-+ }
-+
-+ of_node_put(layout);
-+
-+ return 0;
-+}
-+
-+static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr)
-+{
-+ if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) {
-+ dev_err(dev, "Invalid header\n");
-+ return false;
-+ }
-+
-+ if (hdr->version != 0x1) {
-+ dev_err(dev, "Invalid version number\n");
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table)
-+{
-+ struct onie_tlv crc_hdr;
-+ u32 read_crc, calc_crc;
-+ __be32 crc_be;
-+
-+ memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr));
-+ if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) {
-+ dev_err(dev, "Invalid CRC field\n");
-+ return false;
-+ }
-+
-+ /* The table contains a JAMCRC, which is XOR'ed compared to the original
-+ * CRC32 implementation as known in the Ethernet world.
-+ */
-+ memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ);
-+ read_crc = be32_to_cpu(crc_be);
-+ calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF;
-+ if (read_crc != calc_crc) {
-+ dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n",
-+ read_crc, calc_crc);
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ struct onie_tlv_hdr hdr;
-+ size_t table_len, data_len, hdr_len;
-+ u8 *table, *data;
-+ int ret;
-+
-+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!onie_tlv_hdr_is_valid(dev, &hdr)) {
-+ dev_err(dev, "Invalid ONIE TLV header\n");
-+ return -EINVAL;
-+ }
-+
-+ hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len);
-+ data_len = be16_to_cpu(hdr.data_len);
-+ table_len = hdr_len + data_len;
-+ if (table_len > ONIE_TLV_MAX_LEN) {
-+ dev_err(dev, "Invalid ONIE TLV data length\n");
-+ return -EINVAL;
-+ }
-+
-+ table = devm_kmalloc(dev, table_len, GFP_KERNEL);
-+ if (!table)
-+ return -ENOMEM;
-+
-+ ret = nvmem_device_read(nvmem, 0, table_len, table);
-+ if (ret != table_len)
-+ return ret;
-+
-+ if (!onie_tlv_crc_is_valid(dev, table_len, table))
-+ return -EINVAL;
-+
-+ data = table + hdr_len;
-+ ret = onie_tlv_add_cells(dev, nvmem, data_len, data);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id onie_tlv_of_match_table[] = {
-+ { .compatible = "onie,tlv-layout", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table);
-+
-+static struct nvmem_layout onie_tlv_layout = {
-+ .name = "ONIE tlv layout",
-+ .of_match_table = onie_tlv_of_match_table,
-+ .add_cells = onie_tlv_parse_table,
-+};
-+
-+static int __init onie_tlv_init(void)
-+{
-+ return nvmem_layout_register(&onie_tlv_layout);
-+}
-+
-+static void __exit onie_tlv_exit(void)
-+{
-+ nvmem_layout_unregister(&onie_tlv_layout);
-+}
-+
-+module_init(onie_tlv_init);
-+module_exit(onie_tlv_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
-+MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing");
-+MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing");
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch b/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch
deleted file mode 100644
index 94a0911d73..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From a4fb434ef96ace5af758ca2c52c3a3f8f3abc87c Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Tue, 4 Apr 2023 18:21:34 +0100
-Subject: [PATCH] nvmem: stm32-romem: mark OF related data as maybe unused
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The driver can be compile tested with !CONFIG_OF making certain data
-unused:
-
- drivers/nvmem/stm32-romem.c:271:34: error: ‘stm32_romem_of_match’ defined but not used [-Werror=unused-const-variable=]
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-27-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -268,7 +268,7 @@ static const struct stm32_romem_cfg stm3
- .ta = true,
- };
-
--static const struct of_device_id stm32_romem_of_match[] = {
-+static const struct of_device_id stm32_romem_of_match[] __maybe_unused = {
- { .compatible = "st,stm32f4-otp", }, {
- .compatible = "st,stm32mp15-bsec",
- .data = (void *)&stm32mp15_bsec_cfg,
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch b/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch
deleted file mode 100644
index abda402bdd..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From de6e05097f7db066afb0ad4c88b730949f7b7749 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Tue, 4 Apr 2023 18:21:35 +0100
-Subject: [PATCH] nvmem: mtk-efuse: Support postprocessing for GPU speed
- binning data
-
-On some MediaTek SoCs GPU speed binning data is available for read
-in the SoC's eFuse array but it has a format that is incompatible
-with what the OPP API expects, as we read a number from 0 to 7 but
-opp-supported-hw is expecting a bitmask to enable an OPP entry:
-being what we read limited to 0-7, it's straightforward to simply
-convert the value to BIT(value) as a post-processing action.
-
-So, introduce post-processing support and enable it by evaluating
-the newly introduced platform data's `uses_post_processing` member,
-currently enabled only for MT8186.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-28-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/mtk-efuse.c | 53 +++++++++++++++++++++++++++++++++++++--
- 1 file changed, 51 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -10,6 +10,11 @@
- #include <linux/io.h>
- #include <linux/nvmem-provider.h>
- #include <linux/platform_device.h>
-+#include <linux/property.h>
-+
-+struct mtk_efuse_pdata {
-+ bool uses_post_processing;
-+};
-
- struct mtk_efuse_priv {
- void __iomem *base;
-@@ -29,6 +34,37 @@ static int mtk_reg_read(void *context,
- return 0;
- }
-
-+static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index,
-+ unsigned int offset, void *data, size_t bytes)
-+{
-+ u8 *val = data;
-+
-+ if (val[0] < 8)
-+ val[0] = BIT(val[0]);
-+
-+ return 0;
-+}
-+
-+static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout,
-+ struct nvmem_cell_info *cell)
-+{
-+ size_t sz = strlen(cell->name);
-+
-+ /*
-+ * On some SoCs, the GPU speedbin is not read as bitmask but as
-+ * a number with range [0-7] (max 3 bits): post process to use
-+ * it in OPP tables to describe supported-hw.
-+ */
-+ if (cell->nbits <= 3 &&
-+ strncmp(cell->name, "gpu-speedbin", min(sz, strlen("gpu-speedbin"))) == 0)
-+ cell->read_post_process = mtk_efuse_gpu_speedbin_pp;
-+}
-+
-+static struct nvmem_layout mtk_efuse_layout = {
-+ .fixup_cell_info = mtk_efuse_fixup_cell_info,
-+};
-+
- static int mtk_efuse_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -36,6 +72,7 @@ static int mtk_efuse_probe(struct platfo
- struct nvmem_device *nvmem;
- struct nvmem_config econfig = {};
- struct mtk_efuse_priv *priv;
-+ const struct mtk_efuse_pdata *pdata;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -45,20 +82,32 @@ static int mtk_efuse_probe(struct platfo
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
-+ pdata = device_get_match_data(dev);
- econfig.stride = 1;
- econfig.word_size = 1;
- econfig.reg_read = mtk_reg_read;
- econfig.size = resource_size(res);
- econfig.priv = priv;
- econfig.dev = dev;
-+ if (pdata->uses_post_processing)
-+ econfig.layout = &mtk_efuse_layout;
- nvmem = devm_nvmem_register(dev, &econfig);
-
- return PTR_ERR_OR_ZERO(nvmem);
- }
-
-+static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
-+ .uses_post_processing = true,
-+};
-+
-+static const struct mtk_efuse_pdata mtk_efuse_pdata = {
-+ .uses_post_processing = false,
-+};
-+
- static const struct of_device_id mtk_efuse_of_match[] = {
-- { .compatible = "mediatek,mt8173-efuse",},
-- { .compatible = "mediatek,efuse",},
-+ { .compatible = "mediatek,mt8173-efuse", .data = &mtk_efuse_pdata },
-+ { .compatible = "mediatek,mt8186-efuse", .data = &mtk_mt8186_efuse_pdata },
-+ { .compatible = "mediatek,efuse", .data = &mtk_efuse_pdata },
- {/* sentinel */},
- };
- MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch b/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch
deleted file mode 100644
index a0874f73d1..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 1dc552fa33cf98af3e784dbc0500da93cae3b24a Mon Sep 17 00:00:00 2001
-From: Yang Li <yang.lee@linux.alibaba.com>
-Date: Tue, 4 Apr 2023 18:21:38 +0100
-Subject: [PATCH] nvmem: bcm-ocotp: Use devm_platform_ioremap_resource()
-
-According to commit 7945f929f1a7 ("drivers: provide
-devm_platform_ioremap_resource()"), convert platform_get_resource(),
-devm_ioremap_resource() to a single call to use
-devm_platform_ioremap_resource(), as this is exactly what this function
-does.
-
-Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-31-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/bcm-ocotp.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/bcm-ocotp.c
-+++ b/drivers/nvmem/bcm-ocotp.c
-@@ -254,7 +254,6 @@ MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_
- static int bcm_otpc_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-- struct resource *res;
- struct otpc_priv *priv;
- struct nvmem_device *nvmem;
- int err;
-@@ -269,8 +268,7 @@ static int bcm_otpc_probe(struct platfor
- return -ENODEV;
-
- /* Get OTP base address register. */
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->base)) {
- dev_err(dev, "unable to map I/O memory\n");
- return PTR_ERR(priv->base);
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch b/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch
deleted file mode 100644
index 890dacd08d..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 649409990d2e93fac657be7c6960c28a2c601d65 Mon Sep 17 00:00:00 2001
-From: Yang Li <yang.lee@linux.alibaba.com>
-Date: Tue, 4 Apr 2023 18:21:39 +0100
-Subject: [PATCH] nvmem: nintendo-otp: Use devm_platform_ioremap_resource()
-
-According to commit 7945f929f1a7 ("drivers: provide
-devm_platform_ioremap_resource()"), convert platform_get_resource(),
-devm_ioremap_resource() to a single call to use
-devm_platform_ioremap_resource(), as this is exactly what this function
-does.
-
-Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-32-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/nintendo-otp.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/nintendo-otp.c
-+++ b/drivers/nvmem/nintendo-otp.c
-@@ -76,7 +76,6 @@ static int nintendo_otp_probe(struct pla
- struct device *dev = &pdev->dev;
- const struct of_device_id *of_id =
- of_match_device(nintendo_otp_of_table, dev);
-- struct resource *res;
- struct nvmem_device *nvmem;
- struct nintendo_otp_priv *priv;
-
-@@ -92,8 +91,7 @@ static int nintendo_otp_probe(struct pla
- if (!priv)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->regs = devm_ioremap_resource(dev, res);
-+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->regs))
- return PTR_ERR(priv->regs);
-
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch
deleted file mode 100644
index 3f5d3c1ad4..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From c2367aa60d5e34d48582362c6de34b4131d92be7 Mon Sep 17 00:00:00 2001
-From: Yang Li <yang.lee@linux.alibaba.com>
-Date: Tue, 4 Apr 2023 18:21:40 +0100
-Subject: [PATCH] nvmem: vf610-ocotp: Use
- devm_platform_get_and_ioremap_resource()
-
-According to commit 890cc39a8799 ("drivers: provide
-devm_platform_get_and_ioremap_resource()"), convert
-platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-33-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/vf610-ocotp.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/vf610-ocotp.c
-+++ b/drivers/nvmem/vf610-ocotp.c
-@@ -219,8 +219,7 @@ static int vf610_ocotp_probe(struct plat
- if (!ocotp_dev)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- ocotp_dev->base = devm_ioremap_resource(dev, res);
-+ ocotp_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(ocotp_dev->base))
- return PTR_ERR(ocotp_dev->base);
-
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch
deleted file mode 100644
index eeb407e9bb..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 55d4980ce55b6bb4be66877de4dbec513911b988 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Apr 2023 18:21:42 +0100
-Subject: [PATCH] nvmem: core: support specifying both: cell raw data & post
- read lengths
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Callback .read_post_process() is designed to modify raw cell content
-before providing it to the consumer. So far we were dealing with
-modifications that didn't affect cell size (length). In some cases
-however cell content needs to be reformatted and resized.
-
-It's required e.g. to provide properly formatted MAC address in case
-it's stored in a non-binary format (e.g. using ASCII).
-
-There were few discussions how to optimally handle that. Following
-possible solutions were considered:
-1. Allow .read_post_process() to realloc (resize) content buffer
-2. Allow .read_post_process() to adjust (decrease) just buffer length
-3. Register NVMEM cells using post-read sizes
-
-The preferred solution was the last one. The problem is that simply
-adjusting "bytes" in NVMEM providers would result in core code NOT
-passing whole raw data to .read_post_process() callbacks. It means
-callback functions couldn't do their job without somehow manually
-reading original cell content on their own.
-
-This patch deals with that by registering NVMEM cells with both lengths:
-raw content one and post read one. It allows:
-1. Core code to read whole raw cell content
-2. Callbacks to return content they want
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-35-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 11 +++++++----
- include/linux/nvmem-provider.h | 2 ++
- 2 files changed, 9 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -50,6 +50,7 @@ struct nvmem_device {
- struct nvmem_cell_entry {
- const char *name;
- int offset;
-+ size_t raw_len;
- int bytes;
- int bit_offset;
- int nbits;
-@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell
- {
- cell->nvmem = nvmem;
- cell->offset = info->offset;
-+ cell->raw_len = info->raw_len ?: info->bytes;
- cell->bytes = info->bytes;
- cell->name = info->name;
- cell->read_post_process = info->read_post_process;
-@@ -1560,7 +1562,7 @@ static int __nvmem_cell_read(struct nvme
- {
- int rc;
-
-- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes);
-+ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len);
-
- if (rc)
- return rc;
-@@ -1571,7 +1573,7 @@ static int __nvmem_cell_read(struct nvme
-
- if (cell->read_post_process) {
- rc = cell->read_post_process(cell->priv, id, index,
-- cell->offset, buf, cell->bytes);
-+ cell->offset, buf, cell->raw_len);
- if (rc)
- return rc;
- }
-@@ -1594,14 +1596,15 @@ static int __nvmem_cell_read(struct nvme
- */
- void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
- {
-- struct nvmem_device *nvmem = cell->entry->nvmem;
-+ struct nvmem_cell_entry *entry = cell->entry;
-+ struct nvmem_device *nvmem = entry->nvmem;
- u8 *buf;
- int rc;
-
- if (!nvmem)
- return ERR_PTR(-EINVAL);
-
-- buf = kzalloc(cell->entry->bytes, GFP_KERNEL);
-+ buf = kzalloc(max_t(size_t, entry->raw_len, entry->bytes), GFP_KERNEL);
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -51,6 +51,7 @@ struct nvmem_keepout {
- * struct nvmem_cell_info - NVMEM cell description
- * @name: Name.
- * @offset: Offset within the NVMEM device.
-+ * @raw_len: Length of raw data (without post processing).
- * @bytes: Length of the cell.
- * @bit_offset: Bit offset if cell is smaller than a byte.
- * @nbits: Number of bits.
-@@ -62,6 +63,7 @@ struct nvmem_keepout {
- struct nvmem_cell_info {
- const char *name;
- unsigned int offset;
-+ size_t raw_len;
- unsigned int bytes;
- unsigned int bit_offset;
- unsigned int nbits;
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch b/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch
deleted file mode 100644
index adde0ffc4b..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Apr 2023 18:21:43 +0100
-Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-U-Boot environment variables are stored in ASCII format so "ethaddr"
-requires parsing into binary to make it work with Ethernet interfaces.
-
-This includes support for indexes to support #nvmem-cell-cells = <1>.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 1 +
- drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++
- 2 files changed, 27 insertions(+)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV
- tristate "U-Boot environment variables support"
- depends on OF && MTD
- select CRC32
-+ select GENERIC_NET_UTILS
- help
- U-Boot stores its setup as environment variables. This driver adds
- support for verifying & exporting such data. It also exposes variables
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -4,6 +4,8 @@
- */
-
- #include <linux/crc32.h>
-+#include <linux/etherdevice.h>
-+#include <linux/if_ether.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
-@@ -70,6 +72,25 @@ static int u_boot_env_read(void *context
- return 0;
- }
-
-+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
-+ unsigned int offset, void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN];
-+
-+ if (bytes != 3 * ETH_ALEN - 1)
-+ return -EINVAL;
-+
-+ if (!mac_pton(buf, mac))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
- static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
- size_t data_offset, size_t data_len)
- {
-@@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u
- priv->cells[idx].offset = data_offset + value - data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-+ if (!strcmp(var, "ethaddr")) {
-+ priv->cells[idx].raw_len = strlen(value);
-+ priv->cells[idx].bytes = ETH_ALEN;
-+ priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
-+ }
- }
-
- if (WARN_ON(idx != priv->ncells))
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch b/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch
deleted file mode 100644
index 7c6fe22b5f..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 814c978f02db17f16e6aa2efa2a929372f06da09 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:44 +0100
-Subject: [PATCH] nvmem: Add macro to register nvmem layout drivers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Provide a module_nvmem_layout_driver() macro at the end of the
-nvmem-provider.h header to reduce the boilerplate when registering nvmem
-layout drivers.
-
-Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-37-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/nvmem-provider.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -9,6 +9,7 @@
- #ifndef _LINUX_NVMEM_PROVIDER_H
- #define _LINUX_NVMEM_PROVIDER_H
-
-+#include <linux/device/driver.h>
- #include <linux/err.h>
- #include <linux/errno.h>
- #include <linux/gpio/consumer.h>
-@@ -242,4 +243,9 @@ nvmem_layout_get_match_data(struct nvmem
- }
-
- #endif /* CONFIG_NVMEM */
-+
-+#define module_nvmem_layout_driver(__layout_driver) \
-+ module_driver(__layout_driver, nvmem_layout_register, \
-+ nvmem_layout_unregister)
-+
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch
deleted file mode 100644
index 06646dd68b..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0abdf99fe0c86252ba274703425f8d543d7e7f0d Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:45 +0100
-Subject: [PATCH] nvmem: layouts: sl28vpd: Use module_nvmem_layout_driver()
-
-Stop open-coding the module init/exit functions. Use the
-module_nvmem_layout_driver() instead.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-38-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/sl28vpd.c | 14 +-------------
- 1 file changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -146,19 +146,7 @@ struct nvmem_layout sl28vpd_layout = {
- .of_match_table = sl28vpd_of_match_table,
- .add_cells = sl28vpd_add_cells,
- };
--
--static int __init sl28vpd_init(void)
--{
-- return nvmem_layout_register(&sl28vpd_layout);
--}
--
--static void __exit sl28vpd_exit(void)
--{
-- nvmem_layout_unregister(&sl28vpd_layout);
--}
--
--module_init(sl28vpd_init);
--module_exit(sl28vpd_exit);
-+module_nvmem_layout_driver(sl28vpd_layout);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch b/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch
deleted file mode 100644
index 826f4378c2..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From d119eb38faab61125aaa4f63c74eef61585cf34c Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:46 +0100
-Subject: [PATCH] nvmem: layouts: onie-tlv: Use module_nvmem_layout_driver()
-
-Stop open-coding the module init/exit functions. Use the
-module_nvmem_layout_driver() instead.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-39-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/onie-tlv.c | 14 +-------------
- 1 file changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -237,19 +237,7 @@ static struct nvmem_layout onie_tlv_layo
- .of_match_table = onie_tlv_of_match_table,
- .add_cells = onie_tlv_parse_table,
- };
--
--static int __init onie_tlv_init(void)
--{
-- return nvmem_layout_register(&onie_tlv_layout);
--}
--
--static void __exit onie_tlv_exit(void)
--{
-- nvmem_layout_unregister(&onie_tlv_layout);
--}
--
--module_init(onie_tlv_init);
--module_exit(onie_tlv_exit);
-+module_nvmem_layout_driver(onie_tlv_layout);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch b/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch
deleted file mode 100644
index f20db85ceb..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 6b13e4b6a9a45028ac730e550380077df1845912 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:47 +0100
-Subject: [PATCH] nvmem: layouts: onie-tlv: Drop wrong module alias
-
-The MODULE_ALIAS macro is misused here as it carries the
-description. There is currently no relevant alias to provide so let's
-just drop it.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-40-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/onie-tlv.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -242,4 +242,3 @@ module_nvmem_layout_driver(onie_tlv_layo
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
- MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing");
--MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing");
diff --git a/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch b/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch
deleted file mode 100644
index 5cf847b57a..0000000000
--- a/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From a8642cd11635a35a5f1dc31857887900d6610778 Mon Sep 17 00:00:00 2001
-From: Tom Rix <trix@redhat.com>
-Date: Tue, 4 Apr 2023 18:21:48 +0100
-Subject: [PATCH] nvmem: layouts: sl28vpd: set varaiable sl28vpd_layout
- storage-class-specifier to static
-
-smatch reports
-drivers/nvmem/layouts/sl28vpd.c:144:21: warning: symbol
- 'sl28vpd_layout' was not declared. Should it be static?
-
-This variable is only used in one file so it should be static.
-
-Signed-off-by: Tom Rix <trix@redhat.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-41-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/sl28vpd.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -141,7 +141,7 @@ static const struct of_device_id sl28vpd
- };
- MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table);
-
--struct nvmem_layout sl28vpd_layout = {
-+static struct nvmem_layout sl28vpd_layout = {
- .name = "sl28-vpd",
- .of_match_table = sl28vpd_of_match_table,
- .add_cells = sl28vpd_add_cells,
diff --git a/target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch b/target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch
deleted file mode 100644
index 13ee2d4229..0000000000
--- a/target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From a5be5ce0e25439fae3cd42e3d775979547926812 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 3 Nov 2022 09:25:29 +0100
-Subject: [PATCH] firmware/nvram: bcm47xx: support init from IO memory
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Provide NVMEM content to the NVRAM driver from a simple
-memory resource. This is necessary to use NVRAM in a memory-
-mapped flash device. Patch taken from OpenWrts development
-tree.
-
-This patch makes it possible to use memory-mapped NVRAM
-on the D-Link DWL-8610AP and the D-Link DIR-890L.
-
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Cc: linux-mips@vger.kernel.org
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Cc: bcm-kernel-feedback-list@broadcom.com
-Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-[Added an export for modules potentially using the init symbol]
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221103082529.359084-1-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- drivers/firmware/broadcom/bcm47xx_nvram.c | 18 ++++++++++++++++++
- drivers/nvmem/brcm_nvram.c | 3 +++
- include/linux/bcm47xx_nvram.h | 6 ++++++
- 3 files changed, 27 insertions(+)
-
---- a/drivers/firmware/broadcom/bcm47xx_nvram.c
-+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
-@@ -110,6 +110,24 @@ found:
- return 0;
- }
-
-+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size)
-+{
-+ if (nvram_len) {
-+ pr_warn("nvram already initialized\n");
-+ return -EEXIST;
-+ }
-+
-+ if (!bcm47xx_nvram_is_valid(nvram_start)) {
-+ pr_err("No valid NVRAM found\n");
-+ return -ENOENT;
-+ }
-+
-+ bcm47xx_nvram_copy(nvram_start, res_size);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(bcm47xx_nvram_init_from_iomem);
-+
- /*
- * On bcm47xx we need access to the NVRAM very early, so we can't use mtd
- * subsystem to access flash. We can't even use platform device / driver to
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -3,6 +3,7 @@
- * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
- */
-
-+#include <linux/bcm47xx_nvram.h>
- #include <linux/io.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
-@@ -139,6 +140,8 @@ static int brcm_nvram_probe(struct platf
- if (err)
- return err;
-
-+ bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
-+
- config.dev = dev;
- config.cells = priv->cells;
- config.ncells = priv->ncells;
---- a/include/linux/bcm47xx_nvram.h
-+++ b/include/linux/bcm47xx_nvram.h
-@@ -11,6 +11,7 @@
- #include <linux/vmalloc.h>
-
- #ifdef CONFIG_BCM47XX_NVRAM
-+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size);
- int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
- int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
- int bcm47xx_nvram_gpio_pin(const char *name);
-@@ -20,6 +21,11 @@ static inline void bcm47xx_nvram_release
- vfree(nvram);
- };
- #else
-+static inline int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start,
-+ size_t res_size)
-+{
-+ return -ENOTSUPP;
-+}
- static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
- {
- return -ENOTSUPP;
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch b/target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch
deleted file mode 100644
index 38cfccd5ef..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From eebc6573ad940b62a87776db3917e912b4f52d78 Mon Sep 17 00:00:00 2001
-From: Tom Rix <trix@redhat.com>
-Date: Sun, 11 Jun 2023 15:03:05 +0100
-Subject: [PATCH] nvmem: imx-ocotp: set varaiable imx_ocotp_layout
- storage-class-specifier to static
-
-smatch reports
-drivers/nvmem/imx-ocotp.c:599:21: warning: symbol
- 'imx_ocotp_layout' was not declared. Should it be static?
-
-This variable is only used in one file so should be static.
-
-Signed-off-by: Tom Rix <trix@redhat.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-2-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/imx-ocotp.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -596,7 +596,7 @@ static void imx_ocotp_fixup_cell_info(st
- cell->read_post_process = imx_ocotp_cell_pp;
- }
-
--struct nvmem_layout imx_ocotp_layout = {
-+static struct nvmem_layout imx_ocotp_layout = {
- .fixup_cell_info = imx_ocotp_fixup_cell_info,
- };
-
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch b/target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch
deleted file mode 100644
index 7523e5ebf6..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 8a00fc606312c68b98add8fe8e6f7a013ce29e78 Mon Sep 17 00:00:00 2001
-From: Alexander Stein <alexander.stein@ew.tq-group.com>
-Date: Sun, 11 Jun 2023 15:03:06 +0100
-Subject: [PATCH] nvmem: imx-ocotp: Reverse MAC addresses on all i.MX derivates
-
-Not just i.MX8M, but all i.MX6/7 (and subtypes) need to reverse the
-MAC address read from fuses. Exceptions are i.MX6SLL and i.MX7ULP which
-do not support ethernet at all.
-
-Fixes: d0221a780cbc ("nvmem: imx-ocotp: add support for post processing")
-Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Tested-by: Richard Leitner <richard.leitner@skidata.com> # imx6q
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-3-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/imx-ocotp.c | 8 +-------
- 1 file changed, 1 insertion(+), 7 deletions(-)
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -97,7 +97,6 @@ struct ocotp_params {
- unsigned int bank_address_words;
- void (*set_timing)(struct ocotp_priv *priv);
- struct ocotp_ctrl_reg ctrl;
-- bool reverse_mac_address;
- };
-
- static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
-@@ -545,7 +544,6 @@ static const struct ocotp_params imx8mq_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-- .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mm_params = {
-@@ -553,7 +551,6 @@ static const struct ocotp_params imx8mm_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-- .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mn_params = {
-@@ -561,7 +558,6 @@ static const struct ocotp_params imx8mn_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-- .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mp_params = {
-@@ -569,7 +565,6 @@ static const struct ocotp_params imx8mp_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_8MP,
-- .reverse_mac_address = true,
- };
-
- static const struct of_device_id imx_ocotp_dt_ids[] = {
-@@ -624,8 +619,7 @@ static int imx_ocotp_probe(struct platfo
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
-- if (priv->params->reverse_mac_address)
-- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-
- priv->config = &imx_ocotp_nvmem_config;
-
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch b/target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch
deleted file mode 100644
index fb4d346a95..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 73bcd133c910bff3b6d3b3834d0d14be9444e90a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 11 Jun 2023 15:03:08 +0100
-Subject: [PATCH] nvmem: brcm_nvram: add .read_post_process() for MACs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Parse ASCII MAC format into byte based
-2. Calculate relative addresses based on index argument
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-5-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 1 +
- drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++
- 2 files changed, 29 insertions(+)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM
- tristate "Broadcom's NVRAM support"
- depends on ARCH_BCM_5301X || COMPILE_TEST
- depends on HAS_IOMEM
-+ select GENERIC_NET_UTILS
- help
- This driver provides support for Broadcom's NVRAM that can be accessed
- using I/O mapping.
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -4,6 +4,8 @@
- */
-
- #include <linux/bcm47xx_nvram.h>
-+#include <linux/etherdevice.h>
-+#include <linux/if_ether.h>
- #include <linux/io.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
-@@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context
- return 0;
- }
-
-+static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index,
-+ unsigned int offset, void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN];
-+
-+ if (bytes != 3 * ETH_ALEN - 1)
-+ return -EINVAL;
-+
-+ if (!mac_pton(buf, mac))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
- static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
- size_t len)
- {
-@@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct b
- priv->cells[idx].offset = value - (char *)data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-+ if (!strcmp(var, "et0macaddr") ||
-+ !strcmp(var, "et1macaddr") ||
-+ !strcmp(var, "et2macaddr")) {
-+ priv->cells[idx].raw_len = strlen(value);
-+ priv->cells[idx].bytes = ETH_ALEN;
-+ priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
-+ }
- }
-
- return 0;
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch b/target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch
deleted file mode 100644
index 3b6e6e57f5..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 8dc61364164e79e44c07fa2ac0a7b6939f00d5db Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:13 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Add clks and reg_read to rockchip_data
-
-In preparation to support new Rockchip OTP memory devices with different
-clock configurations and register layout, extend rockchip_data struct
-with the related members: clks, num_clks, reg_read.
-
-Additionally, to avoid managing redundant driver data, drop num_clks
-member from rockchip_otp struct and update all references to point to
-the equivalent member in rockchip_data.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-10-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++--------------
- 1 file changed, 49 insertions(+), 30 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -54,21 +54,19 @@
-
- #define OTPC_TIMEOUT 10000
-
-+struct rockchip_data {
-+ int size;
-+ const char * const *clks;
-+ int num_clks;
-+ nvmem_reg_read_t reg_read;
-+};
-+
- struct rockchip_otp {
- struct device *dev;
- void __iomem *base;
-- struct clk_bulk_data *clks;
-- int num_clks;
-+ struct clk_bulk_data *clks;
- struct reset_control *rst;
--};
--
--/* list of required clocks */
--static const char * const rockchip_otp_clocks[] = {
-- "otp", "apb_pclk", "phy",
--};
--
--struct rockchip_data {
-- int size;
-+ const struct rockchip_data *data;
- };
-
- static int rockchip_otp_reset(struct rockchip_otp *otp)
-@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struc
- return ret;
- }
-
--static int rockchip_otp_read(void *context, unsigned int offset,
-- void *val, size_t bytes)
-+static int px30_otp_read(void *context, unsigned int offset,
-+ void *val, size_t bytes)
- {
- struct rockchip_otp *otp = context;
- u8 *buf = val;
-- int ret = 0;
--
-- ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
-- if (ret < 0) {
-- dev_err(otp->dev, "failed to prepare/enable clks\n");
-- return ret;
-- }
-+ int ret;
-
- ret = rockchip_otp_reset(otp);
- if (ret) {
- dev_err(otp->dev, "failed to reset otp phy\n");
-- goto disable_clks;
-+ return ret;
- }
-
- ret = rockchip_otp_ecc_enable(otp, false);
- if (ret < 0) {
- dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
-- goto disable_clks;
-+ return ret;
- }
-
- writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
-@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *conte
-
- read_end:
- writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
--disable_clks:
-- clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
-+
-+ return ret;
-+}
-+
-+static int rockchip_otp_read(void *context, unsigned int offset,
-+ void *val, size_t bytes)
-+{
-+ struct rockchip_otp *otp = context;
-+ int ret;
-+
-+ if (!otp->data || !otp->data->reg_read)
-+ return -EINVAL;
-+
-+ ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
-+ if (ret < 0) {
-+ dev_err(otp->dev, "failed to prepare/enable clks\n");
-+ return ret;
-+ }
-+
-+ ret = otp->data->reg_read(context, offset, val, bytes);
-+
-+ clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
-
- return ret;
- }
-@@ -189,8 +201,15 @@ static struct nvmem_config otp_config =
- .reg_read = rockchip_otp_read,
- };
-
-+static const char * const px30_otp_clocks[] = {
-+ "otp", "apb_pclk", "phy",
-+};
-+
- static const struct rockchip_data px30_data = {
- .size = 0x40,
-+ .clks = px30_otp_clocks,
-+ .num_clks = ARRAY_SIZE(px30_otp_clocks),
-+ .reg_read = px30_otp_read,
- };
-
- static const struct of_device_id rockchip_otp_match[] = {
-@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct pla
- if (!otp)
- return -ENOMEM;
-
-+ otp->data = data;
- otp->dev = dev;
- otp->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(otp->base))
- return PTR_ERR(otp->base);
-
-- otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks);
-- otp->clks = devm_kcalloc(dev, otp->num_clks,
-- sizeof(*otp->clks), GFP_KERNEL);
-+ otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
-+ GFP_KERNEL);
- if (!otp->clks)
- return -ENOMEM;
-
-- for (i = 0; i < otp->num_clks; ++i)
-- otp->clks[i].id = rockchip_otp_clocks[i];
-+ for (i = 0; i < data->num_clks; ++i)
-+ otp->clks[i].id = data->clks[i];
-
-- ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks);
-+ ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
- if (ret)
- return ret;
-
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch b/target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch
deleted file mode 100644
index b5b66cfc5a..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 30fd21cfb1e64ef20035559a8246f5fbf682c40e Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:14 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Generalize rockchip_otp_wait_status()
-
-In preparation to support additional Rockchip OTP memory devices with
-different register layout, generalize rockchip_otp_wait_status() to
-accept a new parameter for specifying the offset of the status register.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-11-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct roc
- return 0;
- }
-
--static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag)
-+static int rockchip_otp_wait_status(struct rockchip_otp *otp,
-+ unsigned int reg, u32 flag)
- {
- u32 status = 0;
- int ret;
-
-- ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status,
-+ ret = readl_poll_timeout_atomic(otp->base + reg, status,
- (status & flag), 1, OTPC_TIMEOUT);
- if (ret)
- return ret;
-
- /* clean int status */
-- writel(flag, otp->base + OTPC_INT_STATUS);
-+ writel(flag, otp->base + reg);
-
- return 0;
- }
-@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struc
-
- writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
-
-- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
-+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE);
- if (ret < 0)
- dev_err(otp->dev, "timeout during ecc_enable\n");
-
-@@ -156,7 +157,7 @@ static int px30_otp_read(void *context,
- otp->base + OTPC_USER_ADDR);
- writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
- otp->base + OTPC_USER_ENABLE);
-- ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
-+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE);
- if (ret < 0) {
- dev_err(otp->dev, "timeout during read setup\n");
- goto read_end;
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch b/target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch
deleted file mode 100644
index 3a17479d95..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From d325c9dd2b6e94040ca722ddcadcd6af358dd2be Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:15 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Use
- devm_reset_control_array_get_exclusive()
-
-In preparation to support new Rockchip OTP memory devices having
-specific reset configurations, switch devm_reset_control_get() to
-devm_reset_control_array_get_exclusive().
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-12-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct pla
- if (ret)
- return ret;
-
-- otp->rst = devm_reset_control_get(dev, "phy");
-+ otp->rst = devm_reset_control_array_get_exclusive(dev);
- if (IS_ERR(otp->rst))
- return PTR_ERR(otp->rst);
-
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch b/target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch
deleted file mode 100644
index 37cb927b10..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 912517345b867a69542dc9f5c2cc3e9d8beaccf5 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:16 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Improve probe error handling
-
-Enhance error handling in the probe function by making use of
-dev_err_probe(), which ensures the error code is always printed, in
-addition to the specified error message.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-13-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 21 ++++++++++++---------
- 1 file changed, 12 insertions(+), 9 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct pla
- int ret, i;
-
- data = of_device_get_match_data(dev);
-- if (!data) {
-- dev_err(dev, "failed to get match data\n");
-- return -EINVAL;
-- }
-+ if (!data)
-+ return dev_err_probe(dev, -EINVAL, "failed to get match data\n");
-
- otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
- GFP_KERNEL);
-@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct pla
- otp->dev = dev;
- otp->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(otp->base))
-- return PTR_ERR(otp->base);
-+ return dev_err_probe(dev, PTR_ERR(otp->base),
-+ "failed to ioremap resource\n");
-
- otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
- GFP_KERNEL);
-@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct pla
-
- ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
- if (ret)
-- return ret;
-+ return dev_err_probe(dev, ret, "failed to get clocks\n");
-
- otp->rst = devm_reset_control_array_get_exclusive(dev);
- if (IS_ERR(otp->rst))
-- return PTR_ERR(otp->rst);
-+ return dev_err_probe(dev, PTR_ERR(otp->rst),
-+ "failed to get resets\n");
-
- otp_config.size = data->size;
- otp_config.priv = otp;
- otp_config.dev = dev;
-- nvmem = devm_nvmem_register(dev, &otp_config);
-
-- return PTR_ERR_OR_ZERO(nvmem);
-+ nvmem = devm_nvmem_register(dev, &otp_config);
-+ if (IS_ERR(nvmem))
-+ return dev_err_probe(dev, PTR_ERR(nvmem),
-+ "failed to register nvmem device\n");
-+ return 0;
- }
-
- static struct platform_driver rockchip_otp_driver = {
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch b/target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch
deleted file mode 100644
index c1e2231c9e..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:17 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588
-
-Add support for the OTP memory device found on the Rockchip RK3588 SoC.
-
-While here, remove the unnecessary 'void *' casts in the OF device ID
-table.
-
-Co-developed-by: Finley Xiao <finley.xiao@rock-chips.com>
-Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++-
- 1 file changed, 76 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -54,6 +54,19 @@
-
- #define OTPC_TIMEOUT 10000
-
-+/* RK3588 Register */
-+#define RK3588_OTPC_AUTO_CTRL 0x04
-+#define RK3588_OTPC_AUTO_EN 0x08
-+#define RK3588_OTPC_INT_ST 0x84
-+#define RK3588_OTPC_DOUT0 0x20
-+#define RK3588_NO_SECURE_OFFSET 0x300
-+#define RK3588_NBYTES 4
-+#define RK3588_BURST_NUM 1
-+#define RK3588_BURST_SHIFT 8
-+#define RK3588_ADDR_SHIFT 16
-+#define RK3588_AUTO_EN BIT(0)
-+#define RK3588_RD_DONE BIT(1)
-+
- struct rockchip_data {
- int size;
- const char * const *clks;
-@@ -171,6 +184,52 @@ read_end:
- return ret;
- }
-
-+static int rk3588_otp_read(void *context, unsigned int offset,
-+ void *val, size_t bytes)
-+{
-+ struct rockchip_otp *otp = context;
-+ unsigned int addr_start, addr_end, addr_len;
-+ int ret, i = 0;
-+ u32 data;
-+ u8 *buf;
-+
-+ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
-+ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
-+ addr_len = addr_end - addr_start;
-+ addr_start += RK3588_NO_SECURE_OFFSET;
-+
-+ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ while (addr_len--) {
-+ writel((addr_start << RK3588_ADDR_SHIFT) |
-+ (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
-+ otp->base + RK3588_OTPC_AUTO_CTRL);
-+ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
-+
-+ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
-+ RK3588_RD_DONE);
-+ if (ret < 0) {
-+ dev_err(otp->dev, "timeout during read setup\n");
-+ goto read_end;
-+ }
-+
-+ data = readl(otp->base + RK3588_OTPC_DOUT0);
-+ memcpy(&buf[i], &data, RK3588_NBYTES);
-+
-+ i += RK3588_NBYTES;
-+ addr_start++;
-+ }
-+
-+ memcpy(val, buf + offset % RK3588_NBYTES, bytes);
-+
-+read_end:
-+ kfree(buf);
-+
-+ return ret;
-+}
-+
- static int rockchip_otp_read(void *context, unsigned int offset,
- void *val, size_t bytes)
- {
-@@ -213,14 +272,29 @@ static const struct rockchip_data px30_d
- .reg_read = px30_otp_read,
- };
-
-+static const char * const rk3588_otp_clocks[] = {
-+ "otp", "apb_pclk", "phy", "arb",
-+};
-+
-+static const struct rockchip_data rk3588_data = {
-+ .size = 0x400,
-+ .clks = rk3588_otp_clocks,
-+ .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
-+ .reg_read = rk3588_otp_read,
-+};
-+
- static const struct of_device_id rockchip_otp_match[] = {
- {
- .compatible = "rockchip,px30-otp",
-- .data = (void *)&px30_data,
-+ .data = &px30_data,
- },
- {
- .compatible = "rockchip,rk3308-otp",
-- .data = (void *)&px30_data,
-+ .data = &px30_data,
-+ },
-+ {
-+ .compatible = "rockchip,rk3588-otp",
-+ .data = &rk3588_data,
- },
- { /* sentinel */ },
- };
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch b/target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch
deleted file mode 100644
index 220e3e9a05..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 9734408969e978a1c0d5d752be63dd638288e374 Mon Sep 17 00:00:00 2001
-From: Michal Simek <michal.simek@amd.com>
-Date: Sun, 11 Jun 2023 15:03:23 +0100
-Subject: [PATCH] nvmem: zynqmp: Switch @xilinx.com emails to @amd.com
-
-@xilinx.com is still working but better to switch to new amd.com after
-AMD/Xilinx acquisition.
-
-Signed-off-by: Michal Simek <michal.simek@amd.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-20-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/zynqmp_nvmem.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/zynqmp_nvmem.c
-+++ b/drivers/nvmem/zynqmp_nvmem.c
-@@ -76,6 +76,6 @@ static struct platform_driver zynqmp_nvm
-
- module_platform_driver(zynqmp_nvmem_driver);
-
--MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>, Nava kishore Manne <navam@xilinx.com>");
-+MODULE_AUTHOR("Michal Simek <michal.simek@amd.com>, Nava kishore Manne <nava.kishore.manne@amd.com>");
- MODULE_DESCRIPTION("ZynqMP NVMEM driver");
- MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch b/target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch
deleted file mode 100644
index f8e6be4241..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-From 22e9e6fcfb5042cb6d6c7874c459b034800092f1 Mon Sep 17 00:00:00 2001
-From: Peng Fan <peng.fan@nxp.com>
-Date: Sun, 11 Jun 2023 15:03:25 +0100
-Subject: [PATCH] nvmem: imx: support i.MX93 OCOTP
-
-Add i.MX93 OCOTP support. i.MX93 OCOTP has two parts: Fuse shadow
-block(fsb) and fuse managed by ELE. The FSB part could be directly
-accessed with MMIO, the ELE could only be accessed with ELE API.
-
-Currently the ELE API is not ready, so NULL function callback is used,
-but it was tested with downstream ELE API.
-
-Signed-off-by: Peng Fan <peng.fan@nxp.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-22-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 9 ++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/imx-ocotp-ele.c | 175 ++++++++++++++++++++++++++++++++++
- 3 files changed, 186 insertions(+)
- create mode 100644 drivers/nvmem/imx-ocotp-ele.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -83,6 +83,15 @@ config NVMEM_IMX_OCOTP
- This driver can also be built as a module. If so, the module
- will be called nvmem-imx-ocotp.
-
-+config NVMEM_IMX_OCOTP_ELE
-+ tristate "i.MX On-Chip OTP Controller support"
-+ depends on ARCH_MXC || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ depends on OF
-+ help
-+ This is a driver for the On-Chip OTP Controller (OCOTP)
-+ available on i.MX SoCs which has ELE.
-+
- config NVMEM_IMX_OCOTP_SCU
- tristate "i.MX8 SCU On-Chip OTP Controller support"
- depends on IMX_SCU
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -18,6 +18,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-im
- nvmem-imx-iim-y := imx-iim.o
- obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o
- nvmem-imx-ocotp-y := imx-ocotp.o
-+obj-$(CONFIG_NVMEM_IMX_OCOTP_ELE) += nvmem-imx-ocotp-ele.o
-+nvmem-imx-ocotp-ele-y := imx-ocotp-ele.o
- obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o
- nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o
- obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o
---- /dev/null
-+++ b/drivers/nvmem/imx-ocotp-ele.c
-@@ -0,0 +1,175 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * i.MX9 OCOTP fusebox driver
-+ *
-+ * Copyright 2023 NXP
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+enum fuse_type {
-+ FUSE_FSB = 1,
-+ FUSE_ELE = 2,
-+ FUSE_INVALID = -1
-+};
-+
-+struct ocotp_map_entry {
-+ u32 start; /* start word */
-+ u32 num; /* num words */
-+ enum fuse_type type;
-+};
-+
-+struct ocotp_devtype_data {
-+ u32 reg_off;
-+ char *name;
-+ u32 size;
-+ u32 num_entry;
-+ u32 flag;
-+ nvmem_reg_read_t reg_read;
-+ struct ocotp_map_entry entry[];
-+};
-+
-+struct imx_ocotp_priv {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct nvmem_config config;
-+ struct mutex lock;
-+ const struct ocotp_devtype_data *data;
-+};
-+
-+static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index)
-+{
-+ struct imx_ocotp_priv *priv = context;
-+ const struct ocotp_devtype_data *data = priv->data;
-+ u32 start, end;
-+ int i;
-+
-+ for (i = 0; i < data->num_entry; i++) {
-+ start = data->entry[i].start;
-+ end = data->entry[i].start + data->entry[i].num;
-+
-+ if (index >= start && index < end)
-+ return data->entry[i].type;
-+ }
-+
-+ return FUSE_INVALID;
-+}
-+
-+static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes)
-+{
-+ struct imx_ocotp_priv *priv = context;
-+ void __iomem *reg = priv->base + priv->data->reg_off;
-+ u32 count, index, num_bytes;
-+ enum fuse_type type;
-+ u32 *buf;
-+ void *p;
-+ int i;
-+
-+ index = offset;
-+ num_bytes = round_up(bytes, 4);
-+ count = num_bytes >> 2;
-+
-+ if (count > ((priv->data->size >> 2) - index))
-+ count = (priv->data->size >> 2) - index;
-+
-+ p = kzalloc(num_bytes, GFP_KERNEL);
-+ if (!p)
-+ return -ENOMEM;
-+
-+ mutex_lock(&priv->lock);
-+
-+ buf = p;
-+
-+ for (i = index; i < (index + count); i++) {
-+ type = imx_ocotp_fuse_type(context, i);
-+ if (type == FUSE_INVALID || type == FUSE_ELE) {
-+ *buf++ = 0;
-+ continue;
-+ }
-+
-+ *buf++ = readl_relaxed(reg + (i << 2));
-+ }
-+
-+ memcpy(val, (u8 *)p, bytes);
-+
-+ mutex_unlock(&priv->lock);
-+
-+ kfree(p);
-+
-+ return 0;
-+};
-+
-+static int imx_ele_ocotp_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct imx_ocotp_priv *priv;
-+ struct nvmem_device *nvmem;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->data = of_device_get_match_data(dev);
-+
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ priv->config.dev = dev;
-+ priv->config.name = "ELE-OCOTP";
-+ priv->config.id = NVMEM_DEVID_AUTO;
-+ priv->config.owner = THIS_MODULE;
-+ priv->config.size = priv->data->size;
-+ priv->config.reg_read = priv->data->reg_read;
-+ priv->config.word_size = 4;
-+ priv->config.stride = 1;
-+ priv->config.priv = priv;
-+ priv->config.read_only = true;
-+ mutex_init(&priv->lock);
-+
-+ nvmem = devm_nvmem_register(dev, &priv->config);
-+ if (IS_ERR(nvmem))
-+ return PTR_ERR(nvmem);
-+
-+ return 0;
-+}
-+
-+static const struct ocotp_devtype_data imx93_ocotp_data = {
-+ .reg_off = 0x8000,
-+ .reg_read = imx_ocotp_reg_read,
-+ .size = 2048,
-+ .num_entry = 6,
-+ .entry = {
-+ { 0, 52, FUSE_FSB },
-+ { 63, 1, FUSE_ELE},
-+ { 128, 16, FUSE_ELE },
-+ { 182, 1, FUSE_ELE },
-+ { 188, 1, FUSE_ELE },
-+ { 312, 200, FUSE_FSB }
-+ },
-+};
-+
-+static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
-+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
-+
-+static struct platform_driver imx_ele_ocotp_driver = {
-+ .driver = {
-+ .name = "imx_ele_ocotp",
-+ .of_match_table = imx_ele_ocotp_dt_ids,
-+ },
-+ .probe = imx_ele_ocotp_probe,
-+};
-+module_platform_driver(imx_ele_ocotp_driver);
-+
-+MODULE_DESCRIPTION("i.MX OCOTP/ELE driver");
-+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch b/target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch
deleted file mode 100644
index 59b2f9fa2c..0000000000
--- a/target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 27f699e578b1a72df89dfa3bc42e093a01dc8d10 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 11 Jun 2023 15:03:29 +0100
-Subject: [PATCH] nvmem: core: add support for fixed cells *layout*
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds support for the "fixed-layout" NVMEM layout binding. It allows
-defining NVMEM cells in a layout DT node named "nvmem-layout".
-
-While NVMEM subsystem supports layout drivers it has been discussed that
-"fixed-layout" may actually be supperted internally. It's because:
-1. It's a very basic layout
-2. It allows sharing code with legacy syntax parsing
-3. It's safer for soc_device_match() due to -EPROBE_DEFER
-4. This will make the syntax transition easier
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-26-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++---
- 1 file changed, 29 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -696,7 +696,7 @@ static int nvmem_validate_keepouts(struc
- return 0;
- }
-
--static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
-+static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
- {
- struct nvmem_layout *layout = nvmem->layout;
- struct device *dev = &nvmem->dev;
-@@ -704,7 +704,7 @@ static int nvmem_add_cells_from_of(struc
- const __be32 *addr;
- int len, ret;
-
-- for_each_child_of_node(dev->of_node, child) {
-+ for_each_child_of_node(np, child) {
- struct nvmem_cell_info info = {0};
-
- addr = of_get_property(child, "reg", &len);
-@@ -742,6 +742,28 @@ static int nvmem_add_cells_from_of(struc
- return 0;
- }
-
-+static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem)
-+{
-+ return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node);
-+}
-+
-+static int nvmem_add_cells_from_fixed_layout(struct nvmem_device *nvmem)
-+{
-+ struct device_node *layout_np;
-+ int err = 0;
-+
-+ layout_np = of_nvmem_layout_get_container(nvmem);
-+ if (!layout_np)
-+ return 0;
-+
-+ if (of_device_is_compatible(layout_np, "fixed-layout"))
-+ err = nvmem_add_cells_from_dt(nvmem, layout_np);
-+
-+ of_node_put(layout_np);
-+
-+ return err;
-+}
-+
- int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
- {
- layout->owner = owner;
-@@ -972,7 +994,7 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_of(nvmem);
-+ rval = nvmem_add_cells_from_legacy_of(nvmem);
- if (rval)
- goto err_remove_cells;
-
-@@ -982,6 +1004,10 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-+ rval = nvmem_add_cells_from_fixed_layout(nvmem);
-+ if (rval)
-+ goto err_remove_cells;
-+
- rval = nvmem_add_cells_from_layout(nvmem);
- if (rval)
- goto err_remove_cells;
diff --git a/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch b/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch
deleted file mode 100644
index 592111fb95..0000000000
--- a/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 156a5bb89ca6f3edd2be0bfd0de15e575442927e Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Tue, 3 Jan 2023 15:12:47 +0200
-Subject: [PATCH] leds: Move led_init_default_state_get() to the global header
-
-There are users inside and outside LED framework that have implemented
-a local copy of led_init_default_state_get(). In order to deduplicate
-that, as the first step move the declaration from LED header to the
-global one.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230103131256.33894-3-andriy.shevchenko@linux.intel.com
----
- drivers/leds/leds.h | 1 -
- include/linux/leds.h | 2 ++
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/leds/leds.h
-+++ b/drivers/leds/leds.h
-@@ -27,7 +27,6 @@ ssize_t led_trigger_read(struct file *fi
- ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t pos, size_t count);
--enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
-
- extern struct rw_semaphore leds_list_lock;
- extern struct list_head leds_list;
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -63,6 +63,8 @@ struct led_init_data {
- bool devname_mandatory;
- };
-
-+enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
-+
- struct led_hw_trigger_type {
- int dummy;
- };
diff --git a/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch b/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch
deleted file mode 100644
index dcdca90442..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 3e8b4d6277fd19d98c817576954dd6a4ff3caa2b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 17 Apr 2023 17:17:23 +0200
-Subject: [PATCH 1/9] net: dsa: qca8k: move qca8k_port_to_phy() to header
-
-Move qca8k_port_to_phy() to qca8k header as it's useful for future
-reference in Switch LEDs module since the same logic is applied to get
-the right index of the switch port.
-Make it inline as it's simple function that just decrease the port.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 15 ---------------
- drivers/net/dsa/qca/qca8k.h | 14 ++++++++++++++
- 2 files changed, 14 insertions(+), 15 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -716,21 +716,6 @@ err_clear_skb:
- return ret;
- }
-
--static u32
--qca8k_port_to_phy(int port)
--{
-- /* From Andrew Lunn:
-- * Port 0 has no internal phy.
-- * Port 1 has an internal PHY at MDIO address 0.
-- * Port 2 has an internal PHY at MDIO address 1.
-- * ...
-- * Port 5 has an internal PHY at MDIO address 4.
-- * Port 6 has no internal PHY.
-- */
--
-- return port - 1;
--}
--
- static int
- qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
- {
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -414,6 +414,20 @@ struct qca8k_fdb {
- u8 mac[6];
- };
-
-+static inline u32 qca8k_port_to_phy(int port)
-+{
-+ /* From Andrew Lunn:
-+ * Port 0 has no internal phy.
-+ * Port 1 has an internal PHY at MDIO address 0.
-+ * Port 2 has an internal PHY at MDIO address 1.
-+ * ...
-+ * Port 5 has an internal PHY at MDIO address 4.
-+ * Port 6 has no internal PHY.
-+ */
-+
-+ return port - 1;
-+}
-+
- /* Common setup function */
- extern const struct qca8k_mib_desc ar8327_mib[];
- extern const struct regmap_access_table qca8k_readable_table;
diff --git a/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch b/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch
deleted file mode 100644
index baf4c2e4ba..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch
+++ /dev/null
@@ -1,435 +0,0 @@
-From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 17 Apr 2023 17:17:24 +0200
-Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support
-
-Add LEDs basic support for qca8k Switch Family by adding basic
-brightness_set() support.
-
-Since these LEDs refelect port status, the default label is set to
-":port". DT binding should describe the color and function of the
-LEDs using standard LEDs api.
-Each LED always have the device name as prefix. The device name is
-composed from the mii bus id and the PHY addr resulting in example
-names like:
-- qca8k-0.0:00:amber:lan
-- qca8k-0.0:00:white:lan
-- qca8k-0.0:01:amber:lan
-- qca8k-0.0:01:white:lan
-
-These LEDs supports only blocking variant of the brightness_set()
-function since they can sleep during access of the switch leds to set
-the brightness.
-
-While at it add to the qca8k header file each mode defined by the Switch
-Documentation for future use.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/Kconfig | 8 ++
- drivers/net/dsa/qca/Makefile | 3 +
- drivers/net/dsa/qca/qca8k-8xxx.c | 5 +
- drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 60 ++++++++
- drivers/net/dsa/qca/qca8k_leds.h | 16 +++
- 6 files changed, 331 insertions(+)
- create mode 100644 drivers/net/dsa/qca/qca8k-leds.c
- create mode 100644 drivers/net/dsa/qca/qca8k_leds.h
-
---- a/drivers/net/dsa/qca/Kconfig
-+++ b/drivers/net/dsa/qca/Kconfig
-@@ -15,3 +15,11 @@ config NET_DSA_QCA8K
- help
- This enables support for the Qualcomm Atheros QCA8K Ethernet
- switch chips.
-+
-+config NET_DSA_QCA8K_LEDS_SUPPORT
-+ bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support"
-+ depends on NET_DSA_QCA8K
-+ depends on LEDS_CLASS
-+ help
-+ This enabled support for LEDs present on the Qualcomm Atheros
-+ QCA8K Ethernet switch chips.
---- a/drivers/net/dsa/qca/Makefile
-+++ b/drivers/net/dsa/qca/Makefile
-@@ -2,3 +2,6 @@
- obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o
- obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
- qca8k-y += qca8k-common.o qca8k-8xxx.o
-+ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
-+qca8k-y += qca8k-leds.o
-+endif
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -22,6 +22,7 @@
- #include <linux/dsa/tag_qca.h>
-
- #include "qca8k.h"
-+#include "qca8k_leds.h"
-
- static void
- qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
-@@ -1185,6 +1186,10 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-+ ret = qca8k_setup_led_ctrl(priv);
-+ if (ret)
-+ return ret;
-+
- /* Make sure MAC06 is disabled */
- ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -0,0 +1,239 @@
-+// SPDX-License-Identifier: GPL-2.0
-+#include <linux/regmap.h>
-+#include <net/dsa.h>
-+
-+#include "qca8k.h"
-+#include "qca8k_leds.h"
-+
-+static int
-+qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
-+{
-+ switch (port_num) {
-+ case 0:
-+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
-+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
-+ break;
-+ case 1:
-+ case 2:
-+ case 3:
-+ /* Port 123 are controlled on a different reg */
-+ reg_info->reg = QCA8K_LED_CTRL3_REG;
-+ reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num);
-+ break;
-+ case 4:
-+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
-+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_led_brightness_set(struct qca8k_led *led,
-+ enum led_brightness brightness)
-+{
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 mask, val;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ val = QCA8K_LED_ALWAYS_OFF;
-+ if (brightness)
-+ val = QCA8K_LED_ALWAYS_ON;
-+
-+ /* HW regs to control brightness is special and port 1-2-3
-+ * are placed in a different reg.
-+ *
-+ * To control port 0 brightness:
-+ * - the 2 bit (15, 14) of:
-+ * - QCA8K_LED_CTRL0_REG for led1
-+ * - QCA8K_LED_CTRL1_REG for led2
-+ * - QCA8K_LED_CTRL2_REG for led3
-+ *
-+ * To control port 4:
-+ * - the 2 bit (31, 30) of:
-+ * - QCA8K_LED_CTRL0_REG for led1
-+ * - QCA8K_LED_CTRL1_REG for led2
-+ * - QCA8K_LED_CTRL2_REG for led3
-+ *
-+ * To control port 1:
-+ * - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1
-+ * - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2
-+ * - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3
-+ *
-+ * To control port 2:
-+ * - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1
-+ * - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2
-+ * - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3
-+ *
-+ * To control port 3:
-+ * - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1
-+ * - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2
-+ * - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3
-+ *
-+ * To abstract this and have less code, we use the port and led numm
-+ * to calculate the shift and the correct reg due to this problem of
-+ * not having a 1:1 map of LED with the regs.
-+ */
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ mask = QCA8K_LED_PATTERN_EN_MASK;
-+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, reg_info.reg,
-+ mask << reg_info.shift,
-+ val << reg_info.shift);
-+}
-+
-+static int
-+qca8k_cled_brightness_set_blocking(struct led_classdev *ldev,
-+ enum led_brightness brightness)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+
-+ return qca8k_led_brightness_set(led, brightness);
-+}
-+
-+static enum led_brightness
-+qca8k_led_brightness_get(struct qca8k_led *led)
-+{
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 val;
-+ int ret;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ ret = regmap_read(priv->regmap, reg_info.reg, &val);
-+ if (ret)
-+ return 0;
-+
-+ val >>= reg_info.shift;
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ val &= QCA8K_LED_PATTERN_EN_MASK;
-+ val >>= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ /* Assume brightness ON only when the LED is set to always ON */
-+ return val == QCA8K_LED_ALWAYS_ON;
-+}
-+
-+static int
-+qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
-+{
-+ struct fwnode_handle *led = NULL, *leds = NULL;
-+ struct led_init_data init_data = { };
-+ struct dsa_switch *ds = priv->ds;
-+ enum led_default_state state;
-+ struct qca8k_led *port_led;
-+ int led_num, led_index;
-+ int ret;
-+
-+ leds = fwnode_get_named_child_node(port, "leds");
-+ if (!leds) {
-+ dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n",
-+ port_num);
-+ return 0;
-+ }
-+
-+ fwnode_for_each_child_node(leds, led) {
-+ /* Reg represent the led number of the port.
-+ * Each port can have at most 3 leds attached
-+ * Commonly:
-+ * 1. is gigabit led
-+ * 2. is mbit led
-+ * 3. additional status led
-+ */
-+ if (fwnode_property_read_u32(led, "reg", &led_num))
-+ continue;
-+
-+ if (led_num >= QCA8K_LED_PORT_COUNT) {
-+ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
-+ led_num, port_num);
-+ continue;
-+ }
-+
-+ led_index = QCA8K_LED_PORT_INDEX(port_num, led_num);
-+
-+ port_led = &priv->ports_led[led_index];
-+ port_led->port_num = port_num;
-+ port_led->led_num = led_num;
-+ port_led->priv = priv;
-+
-+ state = led_init_default_state_get(led);
-+ switch (state) {
-+ case LEDS_DEFSTATE_ON:
-+ port_led->cdev.brightness = 1;
-+ qca8k_led_brightness_set(port_led, 1);
-+ break;
-+ case LEDS_DEFSTATE_KEEP:
-+ port_led->cdev.brightness =
-+ qca8k_led_brightness_get(port_led);
-+ break;
-+ default:
-+ port_led->cdev.brightness = 0;
-+ qca8k_led_brightness_set(port_led, 0);
-+ }
-+
-+ port_led->cdev.max_brightness = 1;
-+ port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
-+ init_data.default_label = ":port";
-+ init_data.fwnode = led;
-+ init_data.devname_mandatory = true;
-+ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id,
-+ port_num);
-+ if (!init_data.devicename)
-+ return -ENOMEM;
-+
-+ ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
-+ if (ret)
-+ dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num);
-+
-+ kfree(init_data.devicename);
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+qca8k_setup_led_ctrl(struct qca8k_priv *priv)
-+{
-+ struct fwnode_handle *ports, *port;
-+ int port_num;
-+ int ret;
-+
-+ ports = device_get_named_child_node(priv->dev, "ports");
-+ if (!ports) {
-+ dev_info(priv->dev, "No ports node specified in device tree!");
-+ return 0;
-+ }
-+
-+ fwnode_for_each_child_node(ports, port) {
-+ if (fwnode_property_read_u32(port, "reg", &port_num))
-+ continue;
-+
-+ /* Skip checking for CPU port 0 and CPU port 6 as not supported */
-+ if (port_num == 0 || port_num == 6)
-+ continue;
-+
-+ /* Each port can have at most 3 different leds attached.
-+ * Switch port starts from 0 to 6, but port 0 and 6 are CPU
-+ * port. The port index needs to be decreased by one to identify
-+ * the correct port for LED setup.
-+ */
-+ ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -11,6 +11,7 @@
- #include <linux/delay.h>
- #include <linux/regmap.h>
- #include <linux/gpio.h>
-+#include <linux/leds.h>
- #include <linux/dsa/tag_qca.h>
-
- #define QCA8K_ETHERNET_MDIO_PRIORITY 7
-@@ -85,6 +86,51 @@
- #define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x)
- #define QCA8K_MDIO_MASTER_MAX_PORTS 5
- #define QCA8K_MDIO_MASTER_MAX_REG 32
-+
-+/* LED control register */
-+#define QCA8K_LED_PORT_COUNT 3
-+#define QCA8K_LED_COUNT ((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT)
-+#define QCA8K_LED_RULE_COUNT 6
-+#define QCA8K_LED_RULE_MAX 11
-+#define QCA8K_LED_PORT_INDEX(_phy, _led) (((_phy) * QCA8K_LED_PORT_COUNT) + (_led))
-+
-+#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led) ((((_phy) - 1) * 6) + 8 + (2 * (_led)))
-+#define QCA8K_LED_PHY123_PATTERN_EN_MASK GENMASK(1, 0)
-+
-+#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT 0
-+#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT 16
-+
-+#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4)
-+#define QCA8K_LED_CTRL0_REG 0x50
-+#define QCA8K_LED_CTRL1_REG 0x54
-+#define QCA8K_LED_CTRL2_REG 0x58
-+#define QCA8K_LED_CTRL3_REG 0x5C
-+#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16)
-+#define QCA8K_LED_CTRL_MASK GENMASK(15, 0)
-+#define QCA8K_LED_RULE_MASK GENMASK(13, 0)
-+#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0)
-+#define QCA8K_LED_BLINK_FREQ_SHITF 0
-+#define QCA8K_LED_BLINK_2HZ 0
-+#define QCA8K_LED_BLINK_4HZ 1
-+#define QCA8K_LED_BLINK_8HZ 2
-+#define QCA8K_LED_BLINK_AUTO 3
-+#define QCA8K_LED_LINKUP_OVER_MASK BIT(2)
-+#define QCA8K_LED_TX_BLINK_MASK BIT(4)
-+#define QCA8K_LED_RX_BLINK_MASK BIT(5)
-+#define QCA8K_LED_COL_BLINK_MASK BIT(7)
-+#define QCA8K_LED_LINK_10M_EN_MASK BIT(8)
-+#define QCA8K_LED_LINK_100M_EN_MASK BIT(9)
-+#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10)
-+#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11)
-+#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12)
-+#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13)
-+#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14)
-+#define QCA8K_LED_PATTERN_EN_SHIFT 14
-+#define QCA8K_LED_ALWAYS_OFF 0
-+#define QCA8K_LED_ALWAYS_BLINK_4HZ 1
-+#define QCA8K_LED_ALWAYS_ON 2
-+#define QCA8K_LED_RULE_CONTROLLED 3
-+
- #define QCA8K_GOL_MAC_ADDR0 0x60
- #define QCA8K_GOL_MAC_ADDR1 0x64
- #define QCA8K_MAX_FRAME_SIZE 0x78
-@@ -377,6 +423,19 @@ struct qca8k_mdio_cache {
- u16 page;
- };
-
-+struct qca8k_led_pattern_en {
-+ u32 reg;
-+ u8 shift;
-+};
-+
-+struct qca8k_led {
-+ u8 port_num;
-+ u8 led_num;
-+ u16 old_rule;
-+ struct qca8k_priv *priv;
-+ struct led_classdev cdev;
-+};
-+
- struct qca8k_priv {
- u8 switch_id;
- u8 switch_revision;
-@@ -399,6 +458,7 @@ struct qca8k_priv {
- struct qca8k_mib_eth_data mib_eth_data;
- struct qca8k_mdio_cache mdio_cache;
- const struct qca8k_match_data *info;
-+ struct qca8k_led ports_led[QCA8K_LED_COUNT];
- };
-
- struct qca8k_mib_desc {
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k_leds.h
-@@ -0,0 +1,16 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#ifndef __QCA8K_LEDS_H
-+#define __QCA8K_LEDS_H
-+
-+/* Leds Support function */
-+#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
-+int qca8k_setup_led_ctrl(struct qca8k_priv *priv);
-+#else
-+static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv)
-+{
-+ return 0;
-+}
-+#endif
-+
-+#endif /* __QCA8K_LEDS_H */
diff --git a/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch b/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch
deleted file mode 100644
index 231c4156df..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 91acadcc6e599dfc62717abcdad58a459cfb1684 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 17 Apr 2023 17:17:25 +0200
-Subject: [PATCH 3/9] net: dsa: qca8k: add LEDs blink_set() support
-
-Add LEDs blink_set() support to qca8k Switch Family.
-These LEDs support hw accellerated blinking at a fixed rate
-of 4Hz.
-
-Reject any other value since not supported by the LEDs switch.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Pavel Machek <pavel@ucw.cz>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-leds.c | 38 ++++++++++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-leds.c
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_le
- }
-
- static int
-+qca8k_cled_blink_set(struct led_classdev *ldev,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ;
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+
-+ if (*delay_on == 0 && *delay_off == 0) {
-+ *delay_on = 125;
-+ *delay_off = 125;
-+ }
-+
-+ if (*delay_on != 125 || *delay_off != 125) {
-+ /* The hardware only supports blinking at 4Hz. Fall back
-+ * to software implementation in other cases.
-+ */
-+ return -EINVAL;
-+ }
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ mask = QCA8K_LED_PATTERN_EN_MASK;
-+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
-+ val << reg_info.shift);
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
- {
- struct fwnode_handle *led = NULL, *leds = NULL;
-@@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv
-
- port_led->cdev.max_brightness = 1;
- port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
-+ port_led->cdev.blink_set = qca8k_cled_blink_set;
- init_data.default_label = ":port";
- init_data.fwnode = led;
- init_data.devname_mandatory = true;
diff --git a/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch b/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch
deleted file mode 100644
index bc905b4468..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From e5029edd53937a29801ef507cee12e657ff31ea9 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:26 +0200
-Subject: [PATCH 4/9] leds: Provide stubs for when CLASS_LED & NEW_LEDS are
- disabled
-
-Provide stubs for devm_led_classdev_register_ext() and
-led_init_default_state_get() so that LED drivers embedded within other
-drivers such as PHYs and Ethernet switches still build when LEDS_CLASS
-or NEW_LEDS are disabled. This also helps with Kconfig dependencies,
-which are somewhat hairy for phylib and mdio and only get worse when
-adding a dependency on LED_CLASS.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/leds.h | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -63,7 +63,15 @@ struct led_init_data {
- bool devname_mandatory;
- };
-
-+#if IS_ENABLED(CONFIG_NEW_LEDS)
- enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
-+#else
-+static inline enum led_default_state
-+led_init_default_state_get(struct fwnode_handle *fwnode)
-+{
-+ return LEDS_DEFSTATE_OFF;
-+}
-+#endif
-
- struct led_hw_trigger_type {
- int dummy;
-@@ -198,9 +206,19 @@ static inline int led_classdev_register(
- return led_classdev_register_ext(parent, led_cdev, NULL);
- }
-
-+#if IS_ENABLED(CONFIG_LEDS_CLASS)
- int devm_led_classdev_register_ext(struct device *parent,
- struct led_classdev *led_cdev,
- struct led_init_data *init_data);
-+#else
-+static inline int
-+devm_led_classdev_register_ext(struct device *parent,
-+ struct led_classdev *led_cdev,
-+ struct led_init_data *init_data)
-+{
-+ return 0;
-+}
-+#endif
-
- static inline int devm_led_classdev_register(struct device *parent,
- struct led_classdev *led_cdev)
diff --git a/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch b/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch
deleted file mode 100644
index 6e5ac8b249..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch
+++ /dev/null
@@ -1,191 +0,0 @@
-From 01e5b728e9e43ae444e0369695a5f72209906464 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:27 +0200
-Subject: [PATCH 5/9] net: phy: Add a binding for PHY LEDs
-
-Define common binding parsing for all PHY drivers with LEDs using
-phylib. Parse the DT as part of the phy_probe and add LEDs to the
-linux LED class infrastructure. For the moment, provide a dummy
-brightness function, which will later be replaced with a call into the
-PHY driver. This allows testing since the LED core might otherwise
-reject an LED whose brightness cannot be set.
-
-Add a dependency on LED_CLASS. It either needs to be built in, or not
-enabled, since a modular build can result in linker errors.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 1 +
- drivers/net/phy/phy_device.c | 76 ++++++++++++++++++++++++++++++++++++
- include/linux/phy.h | 16 ++++++++
- 3 files changed, 93 insertions(+)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -18,6 +18,7 @@ menuconfig PHYLIB
- depends on NETDEVICES
- select MDIO_DEVICE
- select MDIO_DEVRES
-+ depends on LEDS_CLASS || LEDS_CLASS=n
- help
- Ethernet controllers are usually attached to PHY
- devices. This option provides infrastructure for
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -19,10 +19,12 @@
- #include <linux/interrupt.h>
- #include <linux/io.h>
- #include <linux/kernel.h>
-+#include <linux/list.h>
- #include <linux/mdio.h>
- #include <linux/mii.h>
- #include <linux/mm.h>
- #include <linux/module.h>
-+#include <linux/of.h>
- #include <linux/netdevice.h>
- #include <linux/phy.h>
- #include <linux/phy_led_triggers.h>
-@@ -641,6 +643,7 @@ struct phy_device *phy_device_create(str
- device_initialize(&mdiodev->dev);
-
- dev->state = PHY_DOWN;
-+ INIT_LIST_HEAD(&dev->leds);
-
- mutex_init(&dev->lock);
- INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
-@@ -2942,6 +2945,74 @@ static bool phy_drv_supports_irq(struct
- return phydrv->config_intr && phydrv->handle_interrupt;
- }
-
-+/* Dummy implementation until calls into PHY driver are added */
-+static int phy_led_set_brightness(struct led_classdev *led_cdev,
-+ enum led_brightness value)
-+{
-+ return 0;
-+}
-+
-+static int of_phy_led(struct phy_device *phydev,
-+ struct device_node *led)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct led_init_data init_data = {};
-+ struct led_classdev *cdev;
-+ struct phy_led *phyled;
-+ int err;
-+
-+ phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL);
-+ if (!phyled)
-+ return -ENOMEM;
-+
-+ cdev = &phyled->led_cdev;
-+
-+ err = of_property_read_u8(led, "reg", &phyled->index);
-+ if (err)
-+ return err;
-+
-+ cdev->brightness_set_blocking = phy_led_set_brightness;
-+ cdev->max_brightness = 1;
-+ init_data.devicename = dev_name(&phydev->mdio.dev);
-+ init_data.fwnode = of_fwnode_handle(led);
-+ init_data.devname_mandatory = true;
-+
-+ err = devm_led_classdev_register_ext(dev, cdev, &init_data);
-+ if (err)
-+ return err;
-+
-+ list_add(&phyled->list, &phydev->leds);
-+
-+ return 0;
-+}
-+
-+static int of_phy_leds(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ struct device_node *leds, *led;
-+ int err;
-+
-+ if (!IS_ENABLED(CONFIG_OF_MDIO))
-+ return 0;
-+
-+ if (!node)
-+ return 0;
-+
-+ leds = of_get_child_by_name(node, "leds");
-+ if (!leds)
-+ return 0;
-+
-+ for_each_available_child_of_node(leds, led) {
-+ err = of_phy_led(phydev, led);
-+ if (err) {
-+ of_node_put(led);
-+ return err;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
- /**
- * fwnode_mdio_find_device - Given a fwnode, find the mdio_device
- * @fwnode: pointer to the mdio_device's fwnode
-@@ -3120,6 +3191,11 @@ static int phy_probe(struct device *dev)
- /* Set the state to READY by default */
- phydev->state = PHY_READY;
-
-+ /* Get the LEDs from the device tree, and instantiate standard
-+ * LEDs for them.
-+ */
-+ err = of_phy_leds(phydev);
-+
- out:
- /* Re-assert the reset signal on error */
- if (err)
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -14,6 +14,7 @@
- #include <linux/compiler.h>
- #include <linux/spinlock.h>
- #include <linux/ethtool.h>
-+#include <linux/leds.h>
- #include <linux/linkmode.h>
- #include <linux/netlink.h>
- #include <linux/mdio.h>
-@@ -590,6 +591,7 @@ struct macsec_ops;
- * @phy_num_led_triggers: Number of triggers in @phy_led_triggers
- * @led_link_trigger: LED trigger for link up/down
- * @last_triggered: last LED trigger for link speed
-+ * @leds: list of PHY LED structures
- * @master_slave_set: User requested master/slave configuration
- * @master_slave_get: Current master/slave advertisement
- * @master_slave_state: Current master/slave configuration
-@@ -678,6 +680,7 @@ struct phy_device {
-
- struct phy_led_trigger *led_link_trigger;
- #endif
-+ struct list_head leds;
-
- /*
- * Interrupt number for this PHY
-@@ -749,6 +752,19 @@ struct phy_tdr_config {
- #define PHY_PAIR_ALL -1
-
- /**
-+ * struct phy_led: An LED driven by the PHY
-+ *
-+ * @list: List of LEDs
-+ * @led_cdev: Standard LED class structure
-+ * @index: Number of the LED
-+ */
-+struct phy_led {
-+ struct list_head list;
-+ struct led_classdev led_cdev;
-+ u8 index;
-+};
-+
-+/**
- * struct phy_driver - Driver structure for a particular PHY type
- *
- * @mdiodrv: Data common to all MDIO devices
diff --git a/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
deleted file mode 100644
index 3968a884b8..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:28 +0200
-Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED
- brightness
-
-Linux LEDs can be software controlled via the brightness file in /sys.
-LED drivers need to implement a brightness_set function which the core
-will call. Implement an intermediary in phy_device, which will call
-into the phy driver if it implements the necessary function.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy_device.c | 15 ++++++++++++---
- include/linux/phy.h | 13 +++++++++++++
- 2 files changed, 25 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -2945,11 +2945,18 @@ static bool phy_drv_supports_irq(struct
- return phydrv->config_intr && phydrv->handle_interrupt;
- }
-
--/* Dummy implementation until calls into PHY driver are added */
- static int phy_led_set_brightness(struct led_classdev *led_cdev,
- enum led_brightness value)
- {
-- return 0;
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+ int err;
-+
-+ mutex_lock(&phydev->lock);
-+ err = phydev->drv->led_brightness_set(phydev, phyled->index, value);
-+ mutex_unlock(&phydev->lock);
-+
-+ return err;
- }
-
- static int of_phy_led(struct phy_device *phydev,
-@@ -2966,12 +2973,14 @@ static int of_phy_led(struct phy_device
- return -ENOMEM;
-
- cdev = &phyled->led_cdev;
-+ phyled->phydev = phydev;
-
- err = of_property_read_u8(led, "reg", &phyled->index);
- if (err)
- return err;
-
-- cdev->brightness_set_blocking = phy_led_set_brightness;
-+ if (phydev->drv->led_brightness_set)
-+ cdev->brightness_set_blocking = phy_led_set_brightness;
- cdev->max_brightness = 1;
- init_data.devicename = dev_name(&phydev->mdio.dev);
- init_data.fwnode = of_fwnode_handle(led);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -755,15 +755,19 @@ struct phy_tdr_config {
- * struct phy_led: An LED driven by the PHY
- *
- * @list: List of LEDs
-+ * @phydev: PHY this LED is attached to
- * @led_cdev: Standard LED class structure
- * @index: Number of the LED
- */
- struct phy_led {
- struct list_head list;
-+ struct phy_device *phydev;
- struct led_classdev led_cdev;
- u8 index;
- };
-
-+#define to_phy_led(d) container_of(d, struct phy_led, led_cdev)
-+
- /**
- * struct phy_driver - Driver structure for a particular PHY type
- *
-@@ -978,6 +982,15 @@ struct phy_driver {
- int (*get_sqi)(struct phy_device *dev);
- /** @get_sqi_max: Get the maximum signal quality indication */
- int (*get_sqi_max)(struct phy_device *dev);
-+
-+ /**
-+ * @led_brightness_set: Set a PHY LED brightness. Index
-+ * indicates which of the PHYs led should be set. Value
-+ * follows the standard LED class meaning, e.g. LED_OFF,
-+ * LED_HALF, LED_FULL.
-+ */
-+ int (*led_brightness_set)(struct phy_device *dev,
-+ u8 index, enum led_brightness value);
- };
- #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
- struct phy_driver, mdiodrv)
diff --git a/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch b/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch
deleted file mode 100644
index 053288ceca..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 2d3960e58ef7c83fe1dbf952f056b9e906cb6df8 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:29 +0200
-Subject: [PATCH 7/9] net: phy: marvell: Add software control of the LEDs
-
-Add a brightness function, so the LEDs can be controlled from
-software using the standard Linux LED infrastructure.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/marvell.c | 45 ++++++++++++++++++++++++++++++++++-----
- 1 file changed, 40 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -144,11 +144,13 @@
- /* WOL Event Interrupt Enable */
- #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7)
-
--/* LED Timer Control Register */
--#define MII_88E1318S_PHY_LED_TCR 0x12
--#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
--#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
--#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11)
-+#define MII_88E1318S_PHY_LED_FUNC 0x10
-+#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8)
-+#define MII_88E1318S_PHY_LED_FUNC_ON (0x9)
-+#define MII_88E1318S_PHY_LED_TCR 0x12
-+#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
-+#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
-+#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11)
-
- /* Magic Packet MAC address registers */
- #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17
-@@ -2793,6 +2795,34 @@ static int marvell_hwmon_probe(struct ph
- }
- #endif
-
-+static int m88e1318_led_brightness_set(struct phy_device *phydev,
-+ u8 index, enum led_brightness value)
-+{
-+ int reg;
-+
-+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC);
-+ if (reg < 0)
-+ return reg;
-+
-+ switch (index) {
-+ case 0:
-+ case 1:
-+ case 2:
-+ reg &= ~(0xf << (4 * index));
-+ if (value == LED_OFF)
-+ reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index);
-+ else
-+ reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC, reg);
-+}
-+
- static int marvell_probe(struct phy_device *phydev)
- {
- struct marvell_priv *priv;
-@@ -3041,6 +3071,7 @@ static struct phy_driver marvell_drivers
- .get_sset_count = marvell_get_sset_count,
- .get_strings = marvell_get_strings,
- .get_stats = marvell_get_stats,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1145,
-@@ -3147,6 +3178,7 @@ static struct phy_driver marvell_drivers
- .cable_test_start = marvell_vct7_cable_test_start,
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1540,
-@@ -3173,6 +3205,7 @@ static struct phy_driver marvell_drivers
- .cable_test_start = marvell_vct7_cable_test_start,
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1545,
-@@ -3199,6 +3232,7 @@ static struct phy_driver marvell_drivers
- .cable_test_start = marvell_vct7_cable_test_start,
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E3016,
-@@ -3340,6 +3374,7 @@ static struct phy_driver marvell_drivers
- .get_stats = marvell_get_stats,
- .get_tunable = m88e1540_get_tunable,
- .set_tunable = m88e1540_set_tunable,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- };
-
diff --git a/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
deleted file mode 100644
index 35e1a1c723..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 4e901018432e38eab35d2a352661ce4727795be1 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:30 +0200
-Subject: [PATCH 8/9] net: phy: phy_device: Call into the PHY driver to set LED
- blinking
-
-Linux LEDs can be requested to perform hardware accelerated
-blinking. Pass this to the PHY driver, if it implements the op.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy_device.c | 18 ++++++++++++++++++
- include/linux/phy.h | 12 ++++++++++++
- 2 files changed, 30 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -2959,6 +2959,22 @@ static int phy_led_set_brightness(struct
- return err;
- }
-
-+static int phy_led_blink_set(struct led_classdev *led_cdev,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+ int err;
-+
-+ mutex_lock(&phydev->lock);
-+ err = phydev->drv->led_blink_set(phydev, phyled->index,
-+ delay_on, delay_off);
-+ mutex_unlock(&phydev->lock);
-+
-+ return err;
-+}
-+
- static int of_phy_led(struct phy_device *phydev,
- struct device_node *led)
- {
-@@ -2981,6 +2997,8 @@ static int of_phy_led(struct phy_device
-
- if (phydev->drv->led_brightness_set)
- cdev->brightness_set_blocking = phy_led_set_brightness;
-+ if (phydev->drv->led_blink_set)
-+ cdev->blink_set = phy_led_blink_set;
- cdev->max_brightness = 1;
- init_data.devicename = dev_name(&phydev->mdio.dev);
- init_data.fwnode = of_fwnode_handle(led);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -991,6 +991,18 @@ struct phy_driver {
- */
- int (*led_brightness_set)(struct phy_device *dev,
- u8 index, enum led_brightness value);
-+
-+ /**
-+ * @led_blink_set: Set a PHY LED brightness. Index indicates
-+ * which of the PHYs led should be configured to blink. Delays
-+ * are in milliseconds and if both are zero then a sensible
-+ * default should be chosen. The call should adjust the
-+ * timings in that case and if it can't match the values
-+ * specified exactly.
-+ */
-+ int (*led_blink_set)(struct phy_device *dev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off);
- };
- #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
- struct phy_driver, mdiodrv)
diff --git a/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch b/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch
deleted file mode 100644
index 0f258c6b92..0000000000
--- a/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From ea9e86485decb2ac1750005bd96c166c9b780406 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:31 +0200
-Subject: [PATCH 9/9] net: phy: marvell: Implement led_blink_set()
-
-The Marvell PHY can blink the LEDs, simple on/off. All LEDs blink at
-the same rate, and the reset default is 84ms per blink, which is
-around 12Hz.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/marvell.c | 36 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 36 insertions(+)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -147,6 +147,8 @@
- #define MII_88E1318S_PHY_LED_FUNC 0x10
- #define MII_88E1318S_PHY_LED_FUNC_OFF (0x8)
- #define MII_88E1318S_PHY_LED_FUNC_ON (0x9)
-+#define MII_88E1318S_PHY_LED_FUNC_HI_Z (0xa)
-+#define MII_88E1318S_PHY_LED_FUNC_BLINK (0xb)
- #define MII_88E1318S_PHY_LED_TCR 0x12
- #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
- #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
-@@ -2823,6 +2825,35 @@ static int m88e1318_led_brightness_set(s
- MII_88E1318S_PHY_LED_FUNC, reg);
- }
-
-+static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ int reg;
-+
-+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC);
-+ if (reg < 0)
-+ return reg;
-+
-+ switch (index) {
-+ case 0:
-+ case 1:
-+ case 2:
-+ reg &= ~(0xf << (4 * index));
-+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
-+ /* Reset default is 84ms */
-+ *delay_on = 84 / 2;
-+ *delay_off = 84 / 2;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC, reg);
-+}
-+
- static int marvell_probe(struct phy_device *phydev)
- {
- struct marvell_priv *priv;
-@@ -3072,6 +3103,7 @@ static struct phy_driver marvell_drivers
- .get_strings = marvell_get_strings,
- .get_stats = marvell_get_stats,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1145,
-@@ -3179,6 +3211,7 @@ static struct phy_driver marvell_drivers
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1540,
-@@ -3206,6 +3239,7 @@ static struct phy_driver marvell_drivers
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1545,
-@@ -3233,6 +3267,7 @@ static struct phy_driver marvell_drivers
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E3016,
-@@ -3375,6 +3410,7 @@ static struct phy_driver marvell_drivers
- .get_tunable = m88e1540_get_tunable,
- .set_tunable = m88e1540_set_tunable,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- };
-
diff --git a/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch b/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch
deleted file mode 100644
index c5b611a125..0000000000
--- a/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 4774ad841bef97cc51df90195338c5b2573dd4cb Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 23 Apr 2023 19:28:00 +0200
-Subject: [PATCH] net: phy: marvell: Fix inconsistent indenting in
- led_blink_set
-
-Fix inconsistent indeinting in m88e1318_led_blink_set reported by kernel
-test robot, probably done by the presence of an if condition dropped in
-later revision of the same code.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Link: https://lore.kernel.org/oe-kbuild-all/202304240007.0VEX8QYG-lkp@intel.com/
-Fixes: ea9e86485dec ("net: phy: marvell: Implement led_blink_set()")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20230423172800.3470-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/marvell.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -2841,10 +2841,10 @@ static int m88e1318_led_blink_set(struct
- case 1:
- case 2:
- reg &= ~(0xf << (4 * index));
-- reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
-- /* Reset default is 84ms */
-- *delay_on = 84 / 2;
-- *delay_off = 84 / 2;
-+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
-+ /* Reset default is 84ms */
-+ *delay_on = 84 / 2;
-+ *delay_off = 84 / 2;
- break;
- default:
- return -EINVAL;
diff --git a/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch b/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch
deleted file mode 100644
index 3170c26058..0000000000
--- a/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From e2f24cb1b5daf9a4f6f3ba574c1fa74aab9807a4 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:40 +0200
-Subject: [PATCH 2/5] leds: trigger: netdev: Drop NETDEV_LED_MODE_LINKUP from
- mode
-
-Putting NETDEV_LED_MODE_LINKUP in the same list of the netdev trigger
-modes is wrong as it's used to set the link state of the device and not
-to set a blink mode as it's done by NETDEV_LED_LINK, NETDEV_LED_TX and
-NETDEV_LED_RX. It's also wrong to put this state in the same bitmap of the
-netdev trigger mode and should be external to it.
-
-Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool
-that will be true or false based on the carrier link. No functional
-change intended.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-3-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 19 ++++++++-----------
- 1 file changed, 8 insertions(+), 11 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -50,10 +50,10 @@ struct led_netdev_data {
- unsigned int last_activity;
-
- unsigned long mode;
-+ bool carrier_link_up;
- #define NETDEV_LED_LINK 0
- #define NETDEV_LED_TX 1
- #define NETDEV_LED_RX 2
--#define NETDEV_LED_MODE_LINKUP 3
- };
-
- enum netdev_led_attr {
-@@ -73,9 +73,9 @@ static void set_baseline_state(struct le
- if (!led_cdev->blink_brightness)
- led_cdev->blink_brightness = led_cdev->max_brightness;
-
-- if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode))
-+ if (!trigger_data->carrier_link_up) {
- led_set_brightness(led_cdev, LED_OFF);
-- else {
-+ } else {
- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode))
- led_set_brightness(led_cdev,
- led_cdev->blink_brightness);
-@@ -131,10 +131,9 @@ static ssize_t device_name_store(struct
- trigger_data->net_dev =
- dev_get_by_name(&init_net, trigger_data->device_name);
-
-- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = false;
- if (trigger_data->net_dev != NULL)
-- if (netif_carrier_ok(trigger_data->net_dev))
-- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev);
-
- trigger_data->last_activity = 0;
-
-@@ -315,11 +314,10 @@ static int netdev_trig_notify(struct not
-
- spin_lock_bh(&trigger_data->lock);
-
-- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = false;
- switch (evt) {
- case NETDEV_CHANGENAME:
-- if (netif_carrier_ok(dev))
-- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = netif_carrier_ok(dev);
- fallthrough;
- case NETDEV_REGISTER:
- if (trigger_data->net_dev)
-@@ -333,8 +331,7 @@ static int netdev_trig_notify(struct not
- break;
- case NETDEV_UP:
- case NETDEV_CHANGE:
-- if (netif_carrier_ok(dev))
-- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = netif_carrier_ok(dev);
- break;
- }
-
diff --git a/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch b/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch
deleted file mode 100644
index 19cc1d7c9e..0000000000
--- a/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From bdec9cb83936e0ac4cb87fed5b49fad0175f7dec Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:41 +0200
-Subject: [PATCH 3/5] leds: trigger: netdev: Rename add namespace to netdev
- trigger enum modes
-
-Rename NETDEV trigger enum modes to a more symbolic name and add a
-namespace to them.
-
-Also add __TRIGGER_NETDEV_MAX to identify the max modes of the netdev
-trigger.
-
-This is a cleanup to drop the define and no behaviour change are
-intended.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-4-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 58 ++++++++++++---------------
- 1 file changed, 25 insertions(+), 33 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -51,15 +51,15 @@ struct led_netdev_data {
-
- unsigned long mode;
- bool carrier_link_up;
--#define NETDEV_LED_LINK 0
--#define NETDEV_LED_TX 1
--#define NETDEV_LED_RX 2
- };
-
--enum netdev_led_attr {
-- NETDEV_ATTR_LINK,
-- NETDEV_ATTR_TX,
-- NETDEV_ATTR_RX
-+enum led_trigger_netdev_modes {
-+ TRIGGER_NETDEV_LINK = 0,
-+ TRIGGER_NETDEV_TX,
-+ TRIGGER_NETDEV_RX,
-+
-+ /* Keep last */
-+ __TRIGGER_NETDEV_MAX,
- };
-
- static void set_baseline_state(struct led_netdev_data *trigger_data)
-@@ -76,7 +76,7 @@ static void set_baseline_state(struct le
- if (!trigger_data->carrier_link_up) {
- led_set_brightness(led_cdev, LED_OFF);
- } else {
-- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode))
-+ if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode))
- led_set_brightness(led_cdev,
- led_cdev->blink_brightness);
- else
-@@ -85,8 +85,8 @@ static void set_baseline_state(struct le
- /* If we are looking for RX/TX start periodically
- * checking stats
- */
-- if (test_bit(NETDEV_LED_TX, &trigger_data->mode) ||
-- test_bit(NETDEV_LED_RX, &trigger_data->mode))
-+ if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
- schedule_delayed_work(&trigger_data->work, 0);
- }
- }
-@@ -146,20 +146,16 @@ static ssize_t device_name_store(struct
- static DEVICE_ATTR_RW(device_name);
-
- static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
-- enum netdev_led_attr attr)
-+ enum led_trigger_netdev_modes attr)
- {
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
- int bit;
-
- switch (attr) {
-- case NETDEV_ATTR_LINK:
-- bit = NETDEV_LED_LINK;
-- break;
-- case NETDEV_ATTR_TX:
-- bit = NETDEV_LED_TX;
-- break;
-- case NETDEV_ATTR_RX:
-- bit = NETDEV_LED_RX;
-+ case TRIGGER_NETDEV_LINK:
-+ case TRIGGER_NETDEV_TX:
-+ case TRIGGER_NETDEV_RX:
-+ bit = attr;
- break;
- default:
- return -EINVAL;
-@@ -169,7 +165,7 @@ static ssize_t netdev_led_attr_show(stru
- }
-
- static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
-- size_t size, enum netdev_led_attr attr)
-+ size_t size, enum led_trigger_netdev_modes attr)
- {
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
- unsigned long state;
-@@ -181,14 +177,10 @@ static ssize_t netdev_led_attr_store(str
- return ret;
-
- switch (attr) {
-- case NETDEV_ATTR_LINK:
-- bit = NETDEV_LED_LINK;
-- break;
-- case NETDEV_ATTR_TX:
-- bit = NETDEV_LED_TX;
-- break;
-- case NETDEV_ATTR_RX:
-- bit = NETDEV_LED_RX;
-+ case TRIGGER_NETDEV_LINK:
-+ case TRIGGER_NETDEV_TX:
-+ case TRIGGER_NETDEV_RX:
-+ bit = attr;
- break;
- default:
- return -EINVAL;
-@@ -360,21 +352,21 @@ static void netdev_trig_work(struct work
- }
-
- /* If we are not looking for RX/TX then return */
-- if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) &&
-- !test_bit(NETDEV_LED_RX, &trigger_data->mode))
-+ if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) &&
-+ !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
- return;
-
- dev_stats = dev_get_stats(trigger_data->net_dev, &temp);
- new_activity =
-- (test_bit(NETDEV_LED_TX, &trigger_data->mode) ?
-+ (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ?
- dev_stats->tx_packets : 0) +
-- (test_bit(NETDEV_LED_RX, &trigger_data->mode) ?
-+ (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ?
- dev_stats->rx_packets : 0);
-
- if (trigger_data->last_activity != new_activity) {
- led_stop_software_blink(trigger_data->led_cdev);
-
-- invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode);
-+ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode);
- interval = jiffies_to_msecs(
- atomic_read(&trigger_data->interval));
- /* base state is ON (link present) */
diff --git a/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch b/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch
deleted file mode 100644
index 3b45951f57..0000000000
--- a/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 164b67d53476a9d114be85c885bd31f783835be4 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:42 +0200
-Subject: [PATCH 4/5] leds: trigger: netdev: Convert device attr to macro
-
-Convert link tx and rx device attr to a common macro to reduce common
-code and in preparation for additional attr.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-5-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++-------------------
- 1 file changed, 16 insertions(+), 41 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -198,47 +198,22 @@ static ssize_t netdev_led_attr_store(str
- return size;
- }
-
--static ssize_t link_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK);
--}
--
--static ssize_t link_store(struct device *dev,
-- struct device_attribute *attr, const char *buf, size_t size)
--{
-- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK);
--}
--
--static DEVICE_ATTR_RW(link);
--
--static ssize_t tx_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX);
--}
--
--static ssize_t tx_store(struct device *dev,
-- struct device_attribute *attr, const char *buf, size_t size)
--{
-- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX);
--}
--
--static DEVICE_ATTR_RW(tx);
--
--static ssize_t rx_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX);
--}
--
--static ssize_t rx_store(struct device *dev,
-- struct device_attribute *attr, const char *buf, size_t size)
--{
-- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX);
--}
--
--static DEVICE_ATTR_RW(rx);
-+#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \
-+ static ssize_t trigger_name##_show(struct device *dev, \
-+ struct device_attribute *attr, char *buf) \
-+ { \
-+ return netdev_led_attr_show(dev, buf, trigger); \
-+ } \
-+ static ssize_t trigger_name##_store(struct device *dev, \
-+ struct device_attribute *attr, const char *buf, size_t size) \
-+ { \
-+ return netdev_led_attr_store(dev, buf, size, trigger); \
-+ } \
-+ static DEVICE_ATTR_RW(trigger_name)
-+
-+DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK);
-+DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
-+DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX);
-
- static ssize_t interval_show(struct device *dev,
- struct device_attribute *attr, char *buf)
diff --git a/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch b/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch
deleted file mode 100644
index 180bee9612..0000000000
--- a/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From d1b9e1391ab2dc80e9db87fe8b2de015c651e4c9 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:43 +0200
-Subject: [PATCH 5/5] leds: trigger: netdev: Use mutex instead of spinlocks
-
-Some LEDs may require to sleep while doing some operation like setting
-brightness and other cleanup.
-
-For this reason, using a spinlock will cause a sleep under spinlock
-warning.
-
-It should be safe to convert this to a sleepable lock since:
-- sysfs read/write can sleep
-- netdev_trig_work is a work queue and can sleep
-- netdev _trig_notify can sleep
-
-The spinlock was used when brightness didn't support sleeping, but this
-changed and now it supported with brightness_set_blocking().
-
-Convert to mutex lock to permit sleeping using brightness_set_blocking().
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -20,7 +20,7 @@
- #include <linux/list.h>
- #include <linux/module.h>
- #include <linux/netdevice.h>
--#include <linux/spinlock.h>
-+#include <linux/mutex.h>
- #include <linux/timer.h>
- #include "../leds.h"
-
-@@ -37,7 +37,7 @@
- */
-
- struct led_netdev_data {
-- spinlock_t lock;
-+ struct mutex lock;
-
- struct delayed_work work;
- struct notifier_block notifier;
-@@ -97,9 +97,9 @@ static ssize_t device_name_show(struct d
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
- ssize_t len;
-
-- spin_lock_bh(&trigger_data->lock);
-+ mutex_lock(&trigger_data->lock);
- len = sprintf(buf, "%s\n", trigger_data->device_name);
-- spin_unlock_bh(&trigger_data->lock);
-+ mutex_unlock(&trigger_data->lock);
-
- return len;
- }
-@@ -115,7 +115,7 @@ static ssize_t device_name_store(struct
-
- cancel_delayed_work_sync(&trigger_data->work);
-
-- spin_lock_bh(&trigger_data->lock);
-+ mutex_lock(&trigger_data->lock);
-
- if (trigger_data->net_dev) {
- dev_put(trigger_data->net_dev);
-@@ -138,7 +138,7 @@ static ssize_t device_name_store(struct
- trigger_data->last_activity = 0;
-
- set_baseline_state(trigger_data);
-- spin_unlock_bh(&trigger_data->lock);
-+ mutex_unlock(&trigger_data->lock);
-
- return size;
- }
-@@ -279,7 +279,7 @@ static int netdev_trig_notify(struct not
-
- cancel_delayed_work_sync(&trigger_data->work);
-
-- spin_lock_bh(&trigger_data->lock);
-+ mutex_lock(&trigger_data->lock);
-
- trigger_data->carrier_link_up = false;
- switch (evt) {
-@@ -304,7 +304,7 @@ static int netdev_trig_notify(struct not
-
- set_baseline_state(trigger_data);
-
-- spin_unlock_bh(&trigger_data->lock);
-+ mutex_unlock(&trigger_data->lock);
-
- return NOTIFY_DONE;
- }
-@@ -365,7 +365,7 @@ static int netdev_trig_activate(struct l
- if (!trigger_data)
- return -ENOMEM;
-
-- spin_lock_init(&trigger_data->lock);
-+ mutex_init(&trigger_data->lock);
-
- trigger_data->notifier.notifier_call = netdev_trig_notify;
- trigger_data->notifier.priority = 10;
diff --git a/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch b/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch
deleted file mode 100644
index ac18611733..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From ed554d3f945179c5b159bddfad7be34b403fe11a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:31 +0200
-Subject: [PATCH 01/13] leds: add APIs for LEDs hw control
-
-Add an option to permit LED driver to declare support for a specific
-trigger to use hw control and setup the LED to blink based on specific
-provided modes.
-
-Add APIs for LEDs hw control. These functions will be used to activate
-hardware control where a LED will use the provided flags, from an
-unique defined supported trigger, to setup the LED to be driven by
-hardware.
-
-Add hw_control_is_supported() to ask the LED driver if the requested
-mode by the trigger are supported and the LED can be setup to follow
-the requested modes.
-
-Deactivate hardware blink control by setting brightness to LED_OFF via
-the brightness_set() callback.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/leds.h | 37 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 37 insertions(+)
-
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -164,6 +164,43 @@ struct led_classdev {
-
- /* LEDs that have private triggers have this set */
- struct led_hw_trigger_type *trigger_type;
-+
-+ /* Unique trigger name supported by LED set in hw control mode */
-+ const char *hw_control_trigger;
-+ /*
-+ * Check if the LED driver supports the requested mode provided by the
-+ * defined supported trigger to setup the LED to hw control mode.
-+ *
-+ * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not
-+ * supported and software fallback needs to be used.
-+ * Return a negative error number on any other case for check fail due
-+ * to various reason like device not ready or timeouts.
-+ */
-+ int (*hw_control_is_supported)(struct led_classdev *led_cdev,
-+ unsigned long flags);
-+ /*
-+ * Activate hardware control, LED driver will use the provided flags
-+ * from the supported trigger and setup the LED to be driven by hardware
-+ * following the requested mode from the trigger flags.
-+ * Deactivate hardware blink control by setting brightness to LED_OFF via
-+ * the brightness_set() callback.
-+ *
-+ * Return 0 on success, a negative error number on flags apply fail.
-+ */
-+ int (*hw_control_set)(struct led_classdev *led_cdev,
-+ unsigned long flags);
-+ /*
-+ * Get from the LED driver the current mode that the LED is set in hw
-+ * control mode and put them in flags.
-+ * Trigger can use this to get the initial state of a LED already set in
-+ * hardware blink control.
-+ *
-+ * Return 0 on success, a negative error number on failing parsing the
-+ * initial mode. Error from this function is NOT FATAL as the device
-+ * may be in a not supported initial state by the attached LED trigger.
-+ */
-+ int (*hw_control_get)(struct led_classdev *led_cdev,
-+ unsigned long *flags);
- #endif
-
- #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
diff --git a/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch b/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch
deleted file mode 100644
index 1a221727a0..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 052c38eb17e866c5b4cd43924e7a5e20167b55c0 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:32 +0200
-Subject: [PATCH 02/13] leds: add API to get attached device for LED hw control
-
-Some specific LED triggers blink the LED based on events from a device
-or subsystem.
-For example, an LED could be blinked to indicate a network device is
-receiving packets, or a disk is reading blocks. To correctly enable and
-request the hw control of the LED, the trigger has to check if the
-network interface or block device configured via a /sys/class/led file
-match the one the LED driver provide for hw control for.
-
-Provide an API call to get the device which the LED blinks for.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/leds.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -201,6 +201,12 @@ struct led_classdev {
- */
- int (*hw_control_get)(struct led_classdev *led_cdev,
- unsigned long *flags);
-+ /*
-+ * Get the device this LED blinks in response to.
-+ * e.g. for a PHY LED, it is the network device. If the LED is
-+ * not yet associated to a device, return NULL.
-+ */
-+ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev);
- #endif
-
- #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
diff --git a/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch b/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch
deleted file mode 100644
index af9fb7fdc3..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 8aa2fd7b66980ecd2e45e95af61cf7eafede1211 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:33 +0200
-Subject: [PATCH 03/13] Documentation: leds: leds-class: Document new Hardware
- driven LEDs APIs
-
-Document new Hardware driven LEDs APIs.
-
-Some LEDs can be programmed to be driven by hardware. This is not
-limited to blink but also to turn off or on autonomously.
-To support this feature, a LED needs to implement various additional
-ops and needs to declare specific support for the supported triggers.
-
-Add documentation for each required value and API to make hw control
-possible and implementable by both LEDs and triggers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/leds/leds-class.rst | 81 +++++++++++++++++++++++++++++++
- 1 file changed, 81 insertions(+)
-
---- a/Documentation/leds/leds-class.rst
-+++ b/Documentation/leds/leds-class.rst
-@@ -169,6 +169,87 @@ Setting the brightness to zero with brig
- should completely turn off the LED and cancel the previously programmed
- hardware blinking function, if any.
-
-+Hardware driven LEDs
-+====================
-+
-+Some LEDs can be programmed to be driven by hardware. This is not
-+limited to blink but also to turn off or on autonomously.
-+To support this feature, a LED needs to implement various additional
-+ops and needs to declare specific support for the supported triggers.
-+
-+With hw control we refer to the LED driven by hardware.
-+
-+LED driver must define the following value to support hw control:
-+
-+ - hw_control_trigger:
-+ unique trigger name supported by the LED in hw control
-+ mode.
-+
-+LED driver must implement the following API to support hw control:
-+ - hw_control_is_supported:
-+ check if the flags passed by the supported trigger can
-+ be parsed and activate hw control on the LED.
-+
-+ Return 0 if the passed flags mask is supported and
-+ can be set with hw_control_set().
-+
-+ If the passed flags mask is not supported -EOPNOTSUPP
-+ must be returned, the LED trigger will use software
-+ fallback in this case.
-+
-+ Return a negative error in case of any other error like
-+ device not ready or timeouts.
-+
-+ - hw_control_set:
-+ activate hw control. LED driver will use the provided
-+ flags passed from the supported trigger, parse them to
-+ a set of mode and setup the LED to be driven by hardware
-+ following the requested modes.
-+
-+ Set LED_OFF via the brightness_set to deactivate hw control.
-+
-+ Return 0 on success, a negative error number on failing to
-+ apply flags.
-+
-+ - hw_control_get:
-+ get active modes from a LED already in hw control, parse
-+ them and set in flags the current active flags for the
-+ supported trigger.
-+
-+ Return 0 on success, a negative error number on failing
-+ parsing the initial mode.
-+ Error from this function is NOT FATAL as the device may
-+ be in a not supported initial state by the attached LED
-+ trigger.
-+
-+ - hw_control_get_device:
-+ return the device associated with the LED driver in
-+ hw control. A trigger might use this to match the
-+ returned device from this function with a configured
-+ device for the trigger as the source for blinking
-+ events and correctly enable hw control.
-+ (example a netdev trigger configured to blink for a
-+ particular dev match the returned dev from get_device
-+ to set hw control)
-+
-+ Returns a pointer to a struct device or NULL if nothing
-+ is currently attached.
-+
-+LED driver can activate additional modes by default to workaround the
-+impossibility of supporting each different mode on the supported trigger.
-+Examples are hardcoding the blink speed to a set interval, enable special
-+feature like bypassing blink if some requirements are not met.
-+
-+A trigger should first check if the hw control API are supported by the LED
-+driver and check if the trigger is supported to verify if hw control is possible,
-+use hw_control_is_supported to check if the flags are supported and only at
-+the end use hw_control_set to activate hw control.
-+
-+A trigger can use hw_control_get to check if a LED is already in hw control
-+and init their flags.
-+
-+When the LED is in hw control, no software blink is possible and doing so
-+will effectively disable hw control.
-
- Known Issues
- ============
diff --git a/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch b/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch
deleted file mode 100644
index 3c804c0b41..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 28a6a2ef18ad840a390d519840c303b03040961c Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:34 +0200
-Subject: [PATCH 04/13] leds: trigger: netdev: refactor code setting device
- name
-
-Move the code into a helper, ready for it to be called at
-other times. No intended behaviour change.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 29 ++++++++++++++++++---------
- 1 file changed, 20 insertions(+), 9 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -104,15 +104,9 @@ static ssize_t device_name_show(struct d
- return len;
- }
-
--static ssize_t device_name_store(struct device *dev,
-- struct device_attribute *attr, const char *buf,
-- size_t size)
-+static int set_device_name(struct led_netdev_data *trigger_data,
-+ const char *name, size_t size)
- {
-- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
--
-- if (size >= IFNAMSIZ)
-- return -EINVAL;
--
- cancel_delayed_work_sync(&trigger_data->work);
-
- mutex_lock(&trigger_data->lock);
-@@ -122,7 +116,7 @@ static ssize_t device_name_store(struct
- trigger_data->net_dev = NULL;
- }
-
-- memcpy(trigger_data->device_name, buf, size);
-+ memcpy(trigger_data->device_name, name, size);
- trigger_data->device_name[size] = 0;
- if (size > 0 && trigger_data->device_name[size - 1] == '\n')
- trigger_data->device_name[size - 1] = 0;
-@@ -140,6 +134,23 @@ static ssize_t device_name_store(struct
- set_baseline_state(trigger_data);
- mutex_unlock(&trigger_data->lock);
-
-+ return 0;
-+}
-+
-+static ssize_t device_name_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf,
-+ size_t size)
-+{
-+ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
-+ int ret;
-+
-+ if (size >= IFNAMSIZ)
-+ return -EINVAL;
-+
-+ ret = set_device_name(trigger_data, buf, size);
-+
-+ if (ret < 0)
-+ return ret;
- return size;
- }
-
diff --git a/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch b/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch
deleted file mode 100644
index 284b519482..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 4fd1b6d47a7a38e81fdc6f8be2ccd4216b3f93db Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:35 +0200
-Subject: [PATCH 05/13] leds: trigger: netdev: introduce check for possible hw
- control
-
-Introduce function to check if the requested mode can use hw control in
-preparation for hw control support. Currently everything is handled in
-software so can_hw_control will always return false.
-
-Add knob with the new value hw_control in trigger_data struct to
-set hw control possible. Useful for future implementation to implement
-in set_baseline_state() the required function to set the requested mode
-using LEDs hw control ops and in other function to reject set if hw
-control is currently active.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -51,6 +51,7 @@ struct led_netdev_data {
-
- unsigned long mode;
- bool carrier_link_up;
-+ bool hw_control;
- };
-
- enum led_trigger_netdev_modes {
-@@ -91,6 +92,11 @@ static void set_baseline_state(struct le
- }
- }
-
-+static bool can_hw_control(struct led_netdev_data *trigger_data)
-+{
-+ return false;
-+}
-+
- static ssize_t device_name_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -204,6 +210,8 @@ static ssize_t netdev_led_attr_store(str
- else
- clear_bit(bit, &trigger_data->mode);
-
-+ trigger_data->hw_control = can_hw_control(trigger_data);
-+
- set_baseline_state(trigger_data);
-
- return size;
diff --git a/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch b/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch
deleted file mode 100644
index 09759bc623..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 6352f25f9fadba59d5df2ba7139495759ccc81d5 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:36 +0200
-Subject: [PATCH 06/13] leds: trigger: netdev: add basic check for hw control
- support
-
-Add basic check for hw control support. Check if the required API are
-defined and check if the defined trigger supported in hw control for the
-LED driver match netdev.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -92,8 +92,22 @@ static void set_baseline_state(struct le
- }
- }
-
-+static bool supports_hw_control(struct led_classdev *led_cdev)
-+{
-+ if (!led_cdev->hw_control_get || !led_cdev->hw_control_set ||
-+ !led_cdev->hw_control_is_supported)
-+ return false;
-+
-+ return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name);
-+}
-+
- static bool can_hw_control(struct led_netdev_data *trigger_data)
- {
-+ struct led_classdev *led_cdev = trigger_data->led_cdev;
-+
-+ if (!supports_hw_control(led_cdev))
-+ return false;
-+
- return false;
- }
-
diff --git a/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch b/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch
deleted file mode 100644
index 6634906800..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From c84c80c7388f887b10dafd70fc55bc6c5fe9fa5a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:37 +0200
-Subject: [PATCH 07/13] leds: trigger: netdev: reject interval store for
- hw_control
-
-Reject interval store with hw_control enabled. It's are currently not
-supported and MUST be set to the default value with hw control enabled.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -265,6 +265,9 @@ static ssize_t interval_store(struct dev
- unsigned long value;
- int ret;
-
-+ if (trigger_data->hw_control)
-+ return -EINVAL;
-+
- ret = kstrtoul(buf, 0, &value);
- if (ret)
- return ret;
diff --git a/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch b/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch
deleted file mode 100644
index 52faa4809b..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 7c145a34ba6e380616af93262fcab9fc7261d851 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:38 +0200
-Subject: [PATCH 08/13] leds: trigger: netdev: add support for LED hw control
-
-Add support for LED hw control for the netdev trigger.
-
-The trigger on calling set_baseline_state to configure a new mode, will
-do various check to verify if hw control can be used for the requested
-mode in can_hw_control() function.
-
-It will first check if the LED driver supports hw control for the netdev
-trigger, then will use hw_control_is_supported() and finally will call
-hw_control_set() to apply the requested mode.
-
-To use such mode, interval MUST be set to the default value and net_dev
-MUST be set. If one of these 2 value are not valid, hw control will
-never be used and normal software fallback is used.
-
-The default interval value is moved to a define to make sure they are
-always synced.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 43 +++++++++++++++++++++++++--
- 1 file changed, 41 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -24,6 +24,8 @@
- #include <linux/timer.h>
- #include "../leds.h"
-
-+#define NETDEV_LED_DEFAULT_INTERVAL 50
-+
- /*
- * Configurable sysfs attributes:
- *
-@@ -68,6 +70,13 @@ static void set_baseline_state(struct le
- int current_brightness;
- struct led_classdev *led_cdev = trigger_data->led_cdev;
-
-+ /* Already validated, hw control is possible with the requested mode */
-+ if (trigger_data->hw_control) {
-+ led_cdev->hw_control_set(led_cdev, trigger_data->mode);
-+
-+ return;
-+ }
-+
- current_brightness = led_cdev->brightness;
- if (current_brightness)
- led_cdev->blink_brightness = current_brightness;
-@@ -103,12 +112,42 @@ static bool supports_hw_control(struct l
-
- static bool can_hw_control(struct led_netdev_data *trigger_data)
- {
-+ unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL);
-+ unsigned int interval = atomic_read(&trigger_data->interval);
- struct led_classdev *led_cdev = trigger_data->led_cdev;
-+ int ret;
-
- if (!supports_hw_control(led_cdev))
- return false;
-
-- return false;
-+ /*
-+ * Interval must be set to the default
-+ * value. Any different value is rejected if in hw
-+ * control.
-+ */
-+ if (interval != default_interval)
-+ return false;
-+
-+ /*
-+ * net_dev must be set with hw control, otherwise no
-+ * blinking can be happening and there is nothing to
-+ * offloaded.
-+ */
-+ if (!trigger_data->net_dev)
-+ return false;
-+
-+ /* Check if the requested mode is supported */
-+ ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode);
-+ /* Fall back to software blinking if not supported */
-+ if (ret == -EOPNOTSUPP)
-+ return false;
-+ if (ret) {
-+ dev_warn(led_cdev->dev,
-+ "Current mode check failed with error %d\n", ret);
-+ return false;
-+ }
-+
-+ return true;
- }
-
- static ssize_t device_name_show(struct device *dev,
-@@ -413,7 +452,7 @@ static int netdev_trig_activate(struct l
- trigger_data->device_name[0] = 0;
-
- trigger_data->mode = 0;
-- atomic_set(&trigger_data->interval, msecs_to_jiffies(50));
-+ atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL));
- trigger_data->last_activity = 0;
-
- led_set_trigger_data(led_cdev, trigger_data);
diff --git a/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch b/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch
deleted file mode 100644
index c129ffa4f5..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 33ec0b53befff2c0a7f3aa19ff08556d60585d6b Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:39 +0200
-Subject: [PATCH 09/13] leds: trigger: netdev: validate configured netdev
-
-The netdev which the LED should blink for is configurable in
-/sys/class/led/foo/device_name. Ensure when offloading that the
-configured netdev is the same as the netdev the LED is associated
-with. If it is not, only perform software blinking.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 24 ++++++++++++++++++++++--
- 1 file changed, 22 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -110,6 +110,24 @@ static bool supports_hw_control(struct l
- return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name);
- }
-
-+/*
-+ * Validate the configured netdev is the same as the one associated with
-+ * the LED driver in hw control.
-+ */
-+static bool validate_net_dev(struct led_classdev *led_cdev,
-+ struct net_device *net_dev)
-+{
-+ struct device *dev = led_cdev->hw_control_get_device(led_cdev);
-+ struct net_device *ndev;
-+
-+ if (!dev)
-+ return false;
-+
-+ ndev = to_net_dev(dev);
-+
-+ return ndev == net_dev;
-+}
-+
- static bool can_hw_control(struct led_netdev_data *trigger_data)
- {
- unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL);
-@@ -131,9 +149,11 @@ static bool can_hw_control(struct led_ne
- /*
- * net_dev must be set with hw control, otherwise no
- * blinking can be happening and there is nothing to
-- * offloaded.
-+ * offloaded. Additionally, for hw control to be
-+ * valid, the configured netdev must be the same as
-+ * netdev associated to the LED.
- */
-- if (!trigger_data->net_dev)
-+ if (!validate_net_dev(led_cdev, trigger_data->net_dev))
- return false;
-
- /* Check if the requested mode is supported */
diff --git a/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch b/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch
deleted file mode 100644
index e20594c99a..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 0316cc5629d15880dd3f097d221c55ca648bcd61 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:40 +0200
-Subject: [PATCH 10/13] leds: trigger: netdev: init mode if hw control already
- active
-
-On netdev trigger activation, hw control may be already active by
-default. If this is the case and a device is actually provided by
-hw_control_get_device(), init the already active mode and set the
-bool to hw_control bool to true to reflect the already set mode in the
-trigger_data.
-
-Co-developed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -454,6 +454,8 @@ static void netdev_trig_work(struct work
- static int netdev_trig_activate(struct led_classdev *led_cdev)
- {
- struct led_netdev_data *trigger_data;
-+ unsigned long mode;
-+ struct device *dev;
- int rc;
-
- trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
-@@ -475,6 +477,21 @@ static int netdev_trig_activate(struct l
- atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL));
- trigger_data->last_activity = 0;
-
-+ /* Check if hw control is active by default on the LED.
-+ * Init already enabled mode in hw control.
-+ */
-+ if (supports_hw_control(led_cdev) &&
-+ !led_cdev->hw_control_get(led_cdev, &mode)) {
-+ dev = led_cdev->hw_control_get_device(led_cdev);
-+ if (dev) {
-+ const char *name = dev_name(dev);
-+
-+ set_device_name(trigger_data, name, strlen(name));
-+ trigger_data->hw_control = true;
-+ trigger_data->mode = mode;
-+ }
-+ }
-+
- led_set_trigger_data(led_cdev, trigger_data);
-
- rc = register_netdevice_notifier(&trigger_data->notifier);
diff --git a/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch b/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch
deleted file mode 100644
index 70aed850d1..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 947acacab5ea151291b861cdfbde16ff5cf1b08c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:41 +0200
-Subject: [PATCH 11/13] leds: trigger: netdev: expose netdev trigger modes in
- linux include
-
-Expose netdev trigger modes to make them accessible by LED driver that
-will support netdev trigger for hw control.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 9 ---------
- include/linux/leds.h | 10 ++++++++++
- 2 files changed, 10 insertions(+), 9 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -56,15 +56,6 @@ struct led_netdev_data {
- bool hw_control;
- };
-
--enum led_trigger_netdev_modes {
-- TRIGGER_NETDEV_LINK = 0,
-- TRIGGER_NETDEV_TX,
-- TRIGGER_NETDEV_RX,
--
-- /* Keep last */
-- __TRIGGER_NETDEV_MAX,
--};
--
- static void set_baseline_state(struct led_netdev_data *trigger_data)
- {
- int current_brightness;
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -527,6 +527,16 @@ static inline void *led_get_trigger_data
-
- #endif /* CONFIG_LEDS_TRIGGERS */
-
-+/* Trigger specific enum */
-+enum led_trigger_netdev_modes {
-+ TRIGGER_NETDEV_LINK = 0,
-+ TRIGGER_NETDEV_TX,
-+ TRIGGER_NETDEV_RX,
-+
-+ /* Keep last */
-+ __TRIGGER_NETDEV_MAX,
-+};
-+
- /* Trigger specific functions */
- #ifdef CONFIG_LEDS_TRIGGER_DISK
- void ledtrig_disk_activity(bool write);
diff --git a/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch b/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch
deleted file mode 100644
index ad76d89b7b..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch
+++ /dev/null
@@ -1,200 +0,0 @@
-From e0256648c831af13cbfe4a1787327fcec01c2807 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:42 +0200
-Subject: [PATCH 12/13] net: dsa: qca8k: implement hw_control ops
-
-Implement hw_control ops to drive Switch LEDs based on hardware events.
-
-Netdev trigger is the declared supported trigger for hw control
-operation and supports the following mode:
-- tx
-- rx
-
-When hw_control_set is called, LEDs are set to follow the requested
-mode.
-Each LEDs will blink at 4Hz by default.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-leds.c | 154 +++++++++++++++++++++++++++++++
- 1 file changed, 154 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-leds.c
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -32,6 +32,43 @@ qca8k_get_enable_led_reg(int port_num, i
- }
-
- static int
-+qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
-+{
-+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
-+
-+ /* 6 total control rule:
-+ * 3 control rules for phy0-3 that applies to all their leds
-+ * 3 control rules for phy4
-+ */
-+ if (port_num == 4)
-+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
-+ else
-+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger)
-+{
-+ /* Parsing specific to netdev trigger */
-+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
-+ *offload_trigger |= QCA8K_LED_TX_BLINK_MASK;
-+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
-+ *offload_trigger |= QCA8K_LED_RX_BLINK_MASK;
-+
-+ if (rules && !*offload_trigger)
-+ return -EOPNOTSUPP;
-+
-+ /* Enable some default rule by default to the requested mode:
-+ * - Blink at 4Hz by default
-+ */
-+ *offload_trigger |= QCA8K_LED_BLINK_4HZ;
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_led_brightness_set(struct qca8k_led *led,
- enum led_brightness brightness)
- {
-@@ -165,6 +202,119 @@ qca8k_cled_blink_set(struct led_classdev
- }
-
- static int
-+qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 mask, val = QCA8K_LED_ALWAYS_OFF;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ if (enable)
-+ val = QCA8K_LED_RULE_CONTROLLED;
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ mask = QCA8K_LED_PATTERN_EN_MASK;
-+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
-+ val << reg_info.shift);
-+}
-+
-+static bool
-+qca8k_cled_hw_control_status(struct led_classdev *ldev)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 val;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ regmap_read(priv->regmap, reg_info.reg, &val);
-+
-+ val >>= reg_info.shift;
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ val &= QCA8K_LED_PATTERN_EN_MASK;
-+ val >>= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ return val == QCA8K_LED_RULE_CONTROLLED;
-+}
-+
-+static int
-+qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
-+{
-+ u32 offload_trigger = 0;
-+
-+ return qca8k_parse_netdev(rules, &offload_trigger);
-+}
-+
-+static int
-+qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 offload_trigger = 0;
-+ int ret;
-+
-+ ret = qca8k_parse_netdev(rules, &offload_trigger);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_cled_trigger_offload(ldev, true);
-+ if (ret)
-+ return ret;
-+
-+ qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ return regmap_update_bits(priv->regmap, reg_info.reg,
-+ QCA8K_LED_RULE_MASK << reg_info.shift,
-+ offload_trigger << reg_info.shift);
-+}
-+
-+static int
-+qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 val;
-+ int ret;
-+
-+ /* With hw control not active return err */
-+ if (!qca8k_cled_hw_control_status(ldev))
-+ return -EINVAL;
-+
-+ qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ ret = regmap_read(priv->regmap, reg_info.reg, &val);
-+ if (ret)
-+ return ret;
-+
-+ val >>= reg_info.shift;
-+ val &= QCA8K_LED_RULE_MASK;
-+
-+ /* Parsing specific to netdev trigger */
-+ if (val & QCA8K_LED_TX_BLINK_MASK)
-+ set_bit(TRIGGER_NETDEV_TX, rules);
-+ if (val & QCA8K_LED_RX_BLINK_MASK)
-+ set_bit(TRIGGER_NETDEV_RX, rules);
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
- {
- struct fwnode_handle *led = NULL, *leds = NULL;
-@@ -224,6 +374,10 @@ qca8k_parse_port_leds(struct qca8k_priv
- port_led->cdev.max_brightness = 1;
- port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
- port_led->cdev.blink_set = qca8k_cled_blink_set;
-+ port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported;
-+ port_led->cdev.hw_control_set = qca8k_cled_hw_control_set;
-+ port_led->cdev.hw_control_get = qca8k_cled_hw_control_get;
-+ port_led->cdev.hw_control_trigger = "netdev";
- init_data.default_label = ":port";
- init_data.fwnode = led;
- init_data.devname_mandatory = true;
diff --git a/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch b/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch
deleted file mode 100644
index feb6b9e1e4..0000000000
--- a/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 4f53c27f772e27e4cf4e5507d6f4d5980002cb6a Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:43 +0200
-Subject: [PATCH 13/13] net: dsa: qca8k: add op to get ports netdev
-
-In order that the LED trigger can blink the switch MAC ports LED, it
-needs to know the netdev associated to the port. Add the callback to
-return the struct device of the netdev.
-
-Add an helper function qca8k_phy_to_port() to convert the phy back to
-dsa_port index, as we reference LED port based on the internal PHY
-index and needs to be converted back.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-leds.c | 27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-leds.c
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -5,6 +5,18 @@
- #include "qca8k.h"
- #include "qca8k_leds.h"
-
-+static u32 qca8k_phy_to_port(int phy)
-+{
-+ /* Internal PHY 0 has port at index 1.
-+ * Internal PHY 1 has port at index 2.
-+ * Internal PHY 2 has port at index 3.
-+ * Internal PHY 3 has port at index 4.
-+ * Internal PHY 4 has port at index 5.
-+ */
-+
-+ return phy + 1;
-+}
-+
- static int
- qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
- {
-@@ -314,6 +326,20 @@ qca8k_cled_hw_control_get(struct led_cla
- return 0;
- }
-
-+static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ struct qca8k_priv *priv = led->priv;
-+ struct dsa_port *dp;
-+
-+ dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num));
-+ if (!dp)
-+ return NULL;
-+ if (dp->slave)
-+ return &dp->slave->dev;
-+ return NULL;
-+}
-+
- static int
- qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
- {
-@@ -377,6 +403,7 @@ qca8k_parse_port_leds(struct qca8k_priv
- port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported;
- port_led->cdev.hw_control_set = qca8k_cled_hw_control_set;
- port_led->cdev.hw_control_get = qca8k_cled_hw_control_get;
-+ port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device;
- port_led->cdev.hw_control_trigger = "netdev";
- init_data.default_label = ":port";
- init_data.fwnode = led;
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch b/target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch
deleted file mode 100644
index bf7a816bb2..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 9ccfcbeb8f32ff89e99b36cb9cdebaa0d1b44ed1 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:24 +0100
-Subject: [PATCH] nvmem: sunxi_sid: Convert to devm_platform_ioremap_resource()
-
-Use devm_platform_ioremap_resource() to simplify code.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/sunxi_sid.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/sunxi_sid.c
-+++ b/drivers/nvmem/sunxi_sid.c
-@@ -125,7 +125,6 @@ static int sun8i_sid_read_by_reg(void *c
- static int sunxi_sid_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-- struct resource *res;
- struct nvmem_config *nvmem_cfg;
- struct nvmem_device *nvmem;
- struct sunxi_sid *sid;
-@@ -142,8 +141,7 @@ static int sunxi_sid_probe(struct platfo
- return -EINVAL;
- sid->value_offset = cfg->value_offset;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- sid->base = devm_ioremap_resource(dev, res);
-+ sid->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(sid->base))
- return PTR_ERR(sid->base);
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch b/target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch
deleted file mode 100644
index f142d735de..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From cfadd0e7d9225566f320bc4dc716682be910be6c Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:25 +0100
-Subject: [PATCH] nvmem: brcm_nvram: Use
- devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -159,8 +159,7 @@ static int brcm_nvram_probe(struct platf
- return -ENOMEM;
- priv->dev = dev;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch b/target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch
deleted file mode 100644
index 0395bbf8bc..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 0b49178e2b6b4aac3c7fa3ce8d8c02208a13b988 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:26 +0100
-Subject: [PATCH] nvmem: lpc18xx_otp: Convert to
- devm_platform_ioremap_resource()
-
-Use devm_platform_ioremap_resource() to simplify code.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-5-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/lpc18xx_otp.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/lpc18xx_otp.c
-+++ b/drivers/nvmem/lpc18xx_otp.c
-@@ -68,14 +68,12 @@ static int lpc18xx_otp_probe(struct plat
- {
- struct nvmem_device *nvmem;
- struct lpc18xx_otp *otp;
-- struct resource *res;
-
- otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL);
- if (!otp)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- otp->base = devm_ioremap_resource(&pdev->dev, res);
-+ otp->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(otp->base))
- return PTR_ERR(otp->base);
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch b/target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch
deleted file mode 100644
index da077eb4b7..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0a223a097709b99a0ba738d6be5b4f52c04ffb64 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:27 +0100
-Subject: [PATCH] nvmem: meson-mx-efuse: Convert to
- devm_platform_ioremap_resource()
-
-Use devm_platform_ioremap_resource() to simplify code.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/meson-mx-efuse.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/meson-mx-efuse.c
-+++ b/drivers/nvmem/meson-mx-efuse.c
-@@ -194,7 +194,6 @@ static int meson_mx_efuse_probe(struct p
- {
- const struct meson_mx_efuse_platform_data *drvdata;
- struct meson_mx_efuse *efuse;
-- struct resource *res;
-
- drvdata = of_device_get_match_data(&pdev->dev);
- if (!drvdata)
-@@ -204,8 +203,7 @@ static int meson_mx_efuse_probe(struct p
- if (!efuse)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- efuse->base = devm_ioremap_resource(&pdev->dev, res);
-+ efuse->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(efuse->base))
- return PTR_ERR(efuse->base);
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch b/target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch
deleted file mode 100644
index dc144ddfbd..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 94904db28db49ac8fbb2a273d25156db26a3a985 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:28 +0100
-Subject: [PATCH] nvmem: rockchip-efuse: Use
- devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-efuse.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/rockchip-efuse.c
-+++ b/drivers/nvmem/rockchip-efuse.c
-@@ -267,8 +267,7 @@ static int rockchip_efuse_probe(struct p
- if (!efuse)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- efuse->base = devm_ioremap_resource(dev, res);
-+ efuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(efuse->base))
- return PTR_ERR(efuse->base);
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch
deleted file mode 100644
index 99e20939cc..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0a4a8c0d238fec1fa4b85591524ef42ad261cb97 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:29 +0100
-Subject: [PATCH] nvmem: stm32-romem: Use
- devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -196,8 +196,7 @@ static int stm32_romem_probe(struct plat
- if (!priv)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch b/target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch
deleted file mode 100644
index 6d93752e27..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 0bc0d6dc2a9a05ae6729b4622f09782d9f230815 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:30 +0100
-Subject: [PATCH] nvmem: qfprom: do some cleanup
-
-Use devm_platform_ioremap_resource() and
-devm_platform_get_and_ioremap_resource() to simplify code.
-BTW convert to use dev_err_probe() instead of open it.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qfprom.c | 17 +++++------------
- 1 file changed, 5 insertions(+), 12 deletions(-)
-
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -374,8 +374,7 @@ static int qfprom_probe(struct platform_
- return -ENOMEM;
-
- /* The corrected section is always provided */
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->qfpcorrected = devm_ioremap_resource(dev, res);
-+ priv->qfpcorrected = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->qfpcorrected))
- return PTR_ERR(priv->qfpcorrected);
-
-@@ -402,12 +401,10 @@ static int qfprom_probe(struct platform_
- priv->qfpraw = devm_ioremap_resource(dev, res);
- if (IS_ERR(priv->qfpraw))
- return PTR_ERR(priv->qfpraw);
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
-- priv->qfpconf = devm_ioremap_resource(dev, res);
-+ priv->qfpconf = devm_platform_ioremap_resource(pdev, 2);
- if (IS_ERR(priv->qfpconf))
- return PTR_ERR(priv->qfpconf);
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
-- priv->qfpsecurity = devm_ioremap_resource(dev, res);
-+ priv->qfpsecurity = devm_platform_ioremap_resource(pdev, 3);
- if (IS_ERR(priv->qfpsecurity))
- return PTR_ERR(priv->qfpsecurity);
-
-@@ -427,12 +424,8 @@ static int qfprom_probe(struct platform_
- return PTR_ERR(priv->vcc);
-
- priv->secclk = devm_clk_get(dev, "core");
-- if (IS_ERR(priv->secclk)) {
-- ret = PTR_ERR(priv->secclk);
-- if (ret != -EPROBE_DEFER)
-- dev_err(dev, "Error getting clock: %d\n", ret);
-- return ret;
-- }
-+ if (IS_ERR(priv->secclk))
-+ return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n");
-
- /* Only enable writing if we have SoC data. */
- if (priv->soc_data)
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch b/target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch
deleted file mode 100644
index 3e328a4c99..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 6ac41c556e22a0d7d267c9b9d48681d73af4b368 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:31 +0100
-Subject: [PATCH] nvmem: uniphier: Use devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/uniphier-efuse.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/uniphier-efuse.c
-+++ b/drivers/nvmem/uniphier-efuse.c
-@@ -41,8 +41,7 @@ static int uniphier_efuse_probe(struct p
- if (!priv)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch b/target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch
deleted file mode 100644
index acbe18e270..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From c8efcf7a86ebf2ff48584d270b3070a7075bc345 Mon Sep 17 00:00:00 2001
-From: Richard Alpe <richard@bit42.se>
-Date: Mon, 10 Apr 2023 10:20:51 +0200
-Subject: [PATCH] nvmem: add new NXP QorIQ eFuse driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add SFP (Security Fuse Processor) read support for NXP (Freescale)
-QorIQ series SOC's.
-
-This patch adds support for the T1023 SOC using the SFP offset from
-the existing T1023 device tree. In theory this should also work for
-T1024, T1014 and T1013 which uses the same SFP base offset.
-
-Signed-off-by: Richard Alpe <richard@bit42.se>
-Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/Kconfig | 12 ++++++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/qoriq-efuse.c | 78 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 92 insertions(+)
- create mode 100644 drivers/nvmem/qoriq-efuse.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -392,4 +392,16 @@ config NVMEM_ZYNQMP
-
- If sure, say yes. If unsure, say no.
-
-+config NVMEM_QORIQ_EFUSE
-+ tristate "NXP QorIQ eFuse support"
-+ depends on PPC_85xx || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This driver provides read support for the eFuses (SFP) on NXP QorIQ
-+ series SoC's. This includes secure boot settings, the globally unique
-+ NXP ID 'FUIDR' and the OEM unique ID 'OUIDR'.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem_qoriq_efuse.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -77,3 +77,5 @@ obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvme
- nvmem-vf610-ocotp-y := vf610-ocotp.o
- obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
- nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
-+obj-$(CONFIG_NVMEM_QORIQ_EFUSE) += nvmem-qoriq-efuse.o
-+nvmem-qoriq-efuse-y := qoriq-efuse.o
---- /dev/null
-+++ b/drivers/nvmem/qoriq-efuse.c
-@@ -0,0 +1,78 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2023 Westermo Network Technologies AB
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/platform_device.h>
-+
-+struct qoriq_efuse_priv {
-+ void __iomem *base;
-+};
-+
-+static int qoriq_efuse_read(void *context, unsigned int offset, void *val,
-+ size_t bytes)
-+{
-+ struct qoriq_efuse_priv *priv = context;
-+
-+ /* .stride = 4 so offset is guaranteed to be aligned */
-+ __ioread32_copy(val, priv->base + offset, bytes / 4);
-+
-+ /* Ignore trailing bytes (there shouldn't be any) */
-+
-+ return 0;
-+}
-+
-+static int qoriq_efuse_probe(struct platform_device *pdev)
-+{
-+ struct nvmem_config config = {
-+ .dev = &pdev->dev,
-+ .read_only = true,
-+ .reg_read = qoriq_efuse_read,
-+ .stride = sizeof(u32),
-+ .word_size = sizeof(u32),
-+ .name = "qoriq_efuse_read",
-+ .id = NVMEM_DEVID_AUTO,
-+ .root_only = true,
-+ };
-+ struct qoriq_efuse_priv *priv;
-+ struct nvmem_device *nvmem;
-+ struct resource *res;
-+
-+ priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ config.size = resource_size(res);
-+ config.priv = priv;
-+ nvmem = devm_nvmem_register(config.dev, &config);
-+
-+ return PTR_ERR_OR_ZERO(nvmem);
-+}
-+
-+static const struct of_device_id qoriq_efuse_of_match[] = {
-+ { .compatible = "fsl,t1023-sfp", },
-+ {/* sentinel */},
-+};
-+MODULE_DEVICE_TABLE(of, qoriq_efuse_of_match);
-+
-+static struct platform_driver qoriq_efuse_driver = {
-+ .probe = qoriq_efuse_probe,
-+ .driver = {
-+ .name = "qoriq-efuse",
-+ .of_match_table = qoriq_efuse_of_match,
-+ },
-+};
-+module_platform_driver(qoriq_efuse_driver);
-+
-+MODULE_AUTHOR("Richard Alpe <richard.alpe@bit42.se>");
-+MODULE_DESCRIPTION("NXP QorIQ Security Fuse Processor (SFP) Reader");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch b/target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch
deleted file mode 100644
index 67f30e34a2..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 9d53d595f688c9837e88a919229cc61a165c7b9e Mon Sep 17 00:00:00 2001
-From: Diederik de Haas <didi.debian@cknow.org>
-Date: Mon, 24 Jul 2023 13:36:22 +0200
-Subject: [PATCH] nvmem: Kconfig: Fix typo "drive" -> "driver"
-
-Fix typo where "driver" was meant instead of "drive".
-While at it, also capitalize "OTP".
-
-Signed-off-by: Diederik de Haas <didi.debian@cknow.org>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/Kconfig | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -247,7 +247,7 @@ config NVMEM_ROCKCHIP_EFUSE
- depends on ARCH_ROCKCHIP || COMPILE_TEST
- depends on HAS_IOMEM
- help
-- This is a simple drive to dump specified values of Rockchip SoC
-+ This is a simple driver to dump specified values of Rockchip SoC
- from eFuse, such as cpu-leakage.
-
- This driver can also be built as a module. If so, the module
-@@ -258,8 +258,8 @@ config NVMEM_ROCKCHIP_OTP
- depends on ARCH_ROCKCHIP || COMPILE_TEST
- depends on HAS_IOMEM
- help
-- This is a simple drive to dump specified values of Rockchip SoC
-- from otp, such as cpu-leakage.
-+ This is a simple driver to dump specified values of Rockchip SoC
-+ from OTP, such as cpu-leakage.
-
- This driver can also be built as a module. If so, the module
- will be called nvmem_rockchip_otp.
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch b/target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch
deleted file mode 100644
index d24a624ddf..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 0a9ec38c47c1ca4528aa058e2b9ea61901a7e632 Mon Sep 17 00:00:00 2001
-From: Komal Bajaj <quic_kbajaj@quicinc.com>
-Date: Tue, 1 Aug 2023 12:10:25 +0530
-Subject: [PATCH] nvmem: sec-qfprom: Add Qualcomm secure QFPROM support
-
-For some of the Qualcomm SoC's, it is possible that
-some of the fuse regions or entire qfprom region is
-protected from non-secure access. In such situations,
-the OS will have to use secure calls to read the region.
-With that motivation, add secure qfprom driver.
-
-Signed-off-by: Komal Bajaj <quic_kbajaj@quicinc.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/Kconfig | 13 ++++++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/sec-qfprom.c | 96 ++++++++++++++++++++++++++++++++++++++
- 3 files changed, 111 insertions(+)
- create mode 100644 drivers/nvmem/sec-qfprom.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -226,6 +226,19 @@ config NVMEM_QCOM_QFPROM
- This driver can also be built as a module. If so, the module
- will be called nvmem_qfprom.
-
-+config NVMEM_QCOM_SEC_QFPROM
-+ tristate "QCOM SECURE QFPROM Support"
-+ depends on ARCH_QCOM || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ depends on OF
-+ select QCOM_SCM
-+ help
-+ Say y here to enable secure QFPROM support. The secure QFPROM provides access
-+ functions for QFPROM data to rest of the drivers via nvmem interface.
-+
-+ This driver can also be built as a module. If so, the module will be called
-+ nvmem_sec_qfprom.
-+
- config NVMEM_RAVE_SP_EEPROM
- tristate "Rave SP EEPROM Support"
- depends on RAVE_SP_CORE
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -46,6 +46,8 @@ obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvme
- nvmem-nintendo-otp-y := nintendo-otp.o
- obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o
- nvmem_qfprom-y := qfprom.o
-+obj-$(CONFIG_NVMEM_QCOM_SEC_QFPROM) += nvmem_sec_qfprom.o
-+nvmem_sec_qfprom-y := sec-qfprom.o
- obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
- nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
- obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
---- /dev/null
-+++ b/drivers/nvmem/sec-qfprom.c
-@@ -0,0 +1,96 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#include <linux/firmware/qcom/qcom_scm.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+
-+/**
-+ * struct sec_qfprom - structure holding secure qfprom attributes
-+ *
-+ * @base: starting physical address for secure qfprom corrected address space.
-+ * @dev: qfprom device structure.
-+ */
-+struct sec_qfprom {
-+ phys_addr_t base;
-+ struct device *dev;
-+};
-+
-+static int sec_qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes)
-+{
-+ struct sec_qfprom *priv = context;
-+ unsigned int i;
-+ u8 *val = _val;
-+ u32 read_val;
-+ u8 *tmp;
-+
-+ for (i = 0; i < bytes; i++, reg++) {
-+ if (i == 0 || reg % 4 == 0) {
-+ if (qcom_scm_io_readl(priv->base + (reg & ~3), &read_val)) {
-+ dev_err(priv->dev, "Couldn't access fuse register\n");
-+ return -EINVAL;
-+ }
-+ tmp = (u8 *)&read_val;
-+ }
-+
-+ val[i] = tmp[reg & 3];
-+ }
-+
-+ return 0;
-+}
-+
-+static int sec_qfprom_probe(struct platform_device *pdev)
-+{
-+ struct nvmem_config econfig = {
-+ .name = "sec-qfprom",
-+ .stride = 1,
-+ .word_size = 1,
-+ .id = NVMEM_DEVID_AUTO,
-+ .reg_read = sec_qfprom_reg_read,
-+ };
-+ struct device *dev = &pdev->dev;
-+ struct nvmem_device *nvmem;
-+ struct sec_qfprom *priv;
-+ struct resource *res;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res)
-+ return -EINVAL;
-+
-+ priv->base = res->start;
-+
-+ econfig.size = resource_size(res);
-+ econfig.dev = dev;
-+ econfig.priv = priv;
-+
-+ priv->dev = dev;
-+
-+ nvmem = devm_nvmem_register(dev, &econfig);
-+
-+ return PTR_ERR_OR_ZERO(nvmem);
-+}
-+
-+static const struct of_device_id sec_qfprom_of_match[] = {
-+ { .compatible = "qcom,sec-qfprom" },
-+ {/* sentinel */},
-+};
-+MODULE_DEVICE_TABLE(of, sec_qfprom_of_match);
-+
-+static struct platform_driver qfprom_driver = {
-+ .probe = sec_qfprom_probe,
-+ .driver = {
-+ .name = "qcom_sec_qfprom",
-+ .of_match_table = sec_qfprom_of_match,
-+ },
-+};
-+module_platform_driver(qfprom_driver);
-+MODULE_DESCRIPTION("Qualcomm Secure QFPROM driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch b/target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch
deleted file mode 100644
index dab8ec2c24..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From c32f2186acc9abb4d766361255d7ddf07d15eeb2 Mon Sep 17 00:00:00 2001
-From: Atul Raut <rauji.raut@gmail.com>
-Date: Sun, 30 Jul 2023 15:39:15 -0700
-Subject: [PATCH] nvmem: u-boot-env:: Replace zero-length array with
- DECLARE_FLEX_ARRAY() helper
-
-We are moving toward replacing zero-length arrays with C99 flexible-array
-members since they are deprecated. Therefore, the new DECLARE_FLEX_ARRAY()
-helper macro should be used to replace the zero-length array declaration.
-
-This fixes warnings such as:
-./drivers/nvmem/u-boot-env.c:50:9-13: WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)
-
-Signed-off-by: Atul Raut <rauji.raut@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -47,7 +47,7 @@ struct u_boot_env_image_broadcom {
- __le32 magic;
- __le32 len;
- __le32 crc32;
-- uint8_t data[0];
-+ DECLARE_FLEX_ARRAY(uint8_t, data);
- } __packed;
-
- static int u_boot_env_read(void *context, unsigned int offset, void *val,
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch b/target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch
deleted file mode 100644
index f9532f39c3..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 104af6a5b199eb4dc7970d1304aef38ac5a6ed54 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:26 +0200
-Subject: [PATCH] nvmem: core: Create all cells before adding the nvmem device
-
-Let's pack all the cells creation in one place, so they are all created
-before we add the nvmem device.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/core.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -998,17 +998,17 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
--
-- rval = device_add(&nvmem->dev);
-+ rval = nvmem_add_cells_from_fixed_layout(nvmem);
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_fixed_layout(nvmem);
-+ rval = nvmem_add_cells_from_layout(nvmem);
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_layout(nvmem);
-+ dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
-+
-+ rval = device_add(&nvmem->dev);
- if (rval)
- goto err_remove_cells;
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch b/target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch
deleted file mode 100644
index 8f64d0c28b..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 6c7f48ea2e663b679aa8e60d8d8e1e6306a644f9 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:27 +0200
-Subject: [PATCH] nvmem: core: Return NULL when no nvmem layout is found
-
-Currently, of_nvmem_layout_get_container() returns NULL on error, or an
-error pointer if either CONFIG_NVMEM or CONFIG_OF is turned off. We
-should likely avoid this kind of mix for two reasons: to clarify the
-intend and anyway fix the !CONFIG_OF which will likely always if we use
-this helper somewhere else. Let's just return NULL when no layout is
-found, we don't need an error value here.
-
-Link: https://staticthinking.wordpress.com/2022/08/01/mixing-error-pointers-and-null/
-Fixes: 266570f496b9 ("nvmem: core: introduce NVMEM layouts")
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
-Closes: https://lore.kernel.org/r/202308030002.DnSFOrMB-lkp@intel.com/
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- include/linux/nvmem-consumer.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -256,7 +256,7 @@ static inline struct nvmem_device *of_nv
- static inline struct device_node *
- of_nvmem_layout_get_container(struct nvmem_device *nvmem)
- {
-- return ERR_PTR(-EOPNOTSUPP);
-+ return NULL;
- }
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch b/target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch
deleted file mode 100644
index 28d8bba194..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From b8257f61b4ddac6d7d0e19a5a4e8b07afb3b4ed3 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:28 +0200
-Subject: [PATCH] nvmem: core: Do not open-code existing functions
-
-Use of_nvmem_layout_get_container() instead of hardcoding it.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -786,10 +786,10 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
-
- static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
- {
-- struct device_node *layout_np, *np = nvmem->dev.of_node;
-+ struct device_node *layout_np;
- struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
-
-- layout_np = of_get_child_by_name(np, "nvmem-layout");
-+ layout_np = of_nvmem_layout_get_container(nvmem);
- if (!layout_np)
- return NULL;
-
diff --git a/target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch b/target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch
deleted file mode 100644
index b62a0e18da..0000000000
--- a/target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0991afbe4b1805e7f0113ef10d7c5f0698a739e4 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:29 +0200
-Subject: [PATCH] nvmem: core: Notify when a new layout is registered
-
-Tell listeners a new layout was introduced and is now available.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/core.c | 4 ++++
- include/linux/nvmem-consumer.h | 2 ++
- 2 files changed, 6 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -772,12 +772,16 @@ int __nvmem_layout_register(struct nvmem
- list_add(&layout->node, &nvmem_layouts);
- spin_unlock(&nvmem_layout_lock);
-
-+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout);
-+
- return 0;
- }
- EXPORT_SYMBOL_GPL(__nvmem_layout_register);
-
- void nvmem_layout_unregister(struct nvmem_layout *layout)
- {
-+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout);
-+
- spin_lock(&nvmem_layout_lock);
- list_del(&layout->node);
- spin_unlock(&nvmem_layout_lock);
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -43,6 +43,8 @@ enum {
- NVMEM_REMOVE,
- NVMEM_CELL_ADD,
- NVMEM_CELL_REMOVE,
-+ NVMEM_LAYOUT_ADD,
-+ NVMEM_LAYOUT_REMOVE,
- };
-
- #if IS_ENABLED(CONFIG_NVMEM)
diff --git a/target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch b/target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch
deleted file mode 100644
index 66d4028140..0000000000
--- a/target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 16724d6ea40a2c9315f5a0d81005dfa4d7a6da24 Mon Sep 17 00:00:00 2001
-From: Luca Weiss <luca.weiss@fairphone.com>
-Date: Fri, 20 Oct 2023 11:55:40 +0100
-Subject: [PATCH] nvmem: qfprom: Mark core clk as optional
-
-On some platforms like sc7280 on non-ChromeOS devices the core clock
-cannot be touched by Linux so we cannot provide it. Mark it as optional
-as accessing qfprom for reading works without it but we still prohibit
-writing if we cannot provide the clock.
-
-Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
-Reviewed-by: Douglas Anderson <dianders@chromium.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231020105545.216052-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qfprom.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -423,12 +423,12 @@ static int qfprom_probe(struct platform_
- if (IS_ERR(priv->vcc))
- return PTR_ERR(priv->vcc);
-
-- priv->secclk = devm_clk_get(dev, "core");
-+ priv->secclk = devm_clk_get_optional(dev, "core");
- if (IS_ERR(priv->secclk))
- return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n");
-
-- /* Only enable writing if we have SoC data. */
-- if (priv->soc_data)
-+ /* Only enable writing if we have SoC data and a valid clock */
-+ if (priv->soc_data && priv->secclk)
- econfig.reg_write = qfprom_reg_write;
- }
-
diff --git a/target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch b/target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch
deleted file mode 100644
index 9ce78e1f09..0000000000
--- a/target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch
+++ /dev/null
@@ -1,330 +0,0 @@
-From 2cc3b37f5b6df8189d55d0e812d9658ce256dfec Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 20 Oct 2023 11:55:41 +0100
-Subject: [PATCH] nvmem: add explicit config option to read old syntax fixed OF
- cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Binding for fixed NVMEM cells defined directly as NVMEM device subnodes
-has been deprecated. It has been replaced by the "fixed-layout" NVMEM
-layout binding.
-
-New syntax is meant to be clearer and should help avoiding imprecise
-bindings.
-
-NVMEM subsystem already supports the new binding. It should be a good
-idea to limit support for old syntax to existing drivers that actually
-support & use it (we can't break backward compatibility!). That way we
-additionally encourage new bindings & drivers to ignore deprecated
-binding.
-
-It wasn't clear (to me) if rtc and w1 code actually uses old syntax
-fixed cells. I enabled them to don't risk any breakage.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-[for meson-{efuse,mx-efuse}.c]
-Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-[for mtk-efuse.c, nvmem/core.c, nvmem-provider.h]
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-[MT8192, MT8195 Chromebooks]
-Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-[for microchip-otpc.c]
-Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
-[SAMA7G5-EK]
-Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231020105545.216052-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/mtd/mtdcore.c | 2 ++
- drivers/nvmem/apple-efuses.c | 1 +
- drivers/nvmem/core.c | 8 +++++---
- drivers/nvmem/imx-ocotp-scu.c | 1 +
- drivers/nvmem/imx-ocotp.c | 1 +
- drivers/nvmem/meson-efuse.c | 1 +
- drivers/nvmem/meson-mx-efuse.c | 1 +
- drivers/nvmem/microchip-otpc.c | 1 +
- drivers/nvmem/mtk-efuse.c | 1 +
- drivers/nvmem/qcom-spmi-sdam.c | 1 +
- drivers/nvmem/qfprom.c | 1 +
- drivers/nvmem/rave-sp-eeprom.c | 1 +
- drivers/nvmem/rockchip-efuse.c | 1 +
- drivers/nvmem/sc27xx-efuse.c | 1 +
- drivers/nvmem/sec-qfprom.c | 1 +
- drivers/nvmem/sprd-efuse.c | 1 +
- drivers/nvmem/stm32-romem.c | 1 +
- drivers/nvmem/sunplus-ocotp.c | 1 +
- drivers/nvmem/sunxi_sid.c | 1 +
- drivers/nvmem/uniphier-efuse.c | 1 +
- drivers/nvmem/zynqmp_nvmem.c | 1 +
- drivers/rtc/nvmem.c | 1 +
- drivers/w1/slaves/w1_ds250x.c | 1 +
- include/linux/nvmem-provider.h | 2 ++
- 24 files changed, 30 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -541,6 +541,7 @@ static int mtd_nvmem_add(struct mtd_info
- config.dev = &mtd->dev;
- config.name = dev_name(&mtd->dev);
- config.owner = THIS_MODULE;
-+ config.add_legacy_fixed_of_cells = of_device_is_compatible(node, "nvmem-cells");
- config.reg_read = mtd_nvmem_reg_read;
- config.size = mtd->size;
- config.word_size = 1;
-@@ -898,6 +899,7 @@ static struct nvmem_device *mtd_otp_nvme
- config.name = compatible;
- config.id = NVMEM_DEVID_AUTO;
- config.owner = THIS_MODULE;
-+ config.add_legacy_fixed_of_cells = true;
- config.type = NVMEM_TYPE_OTP;
- config.root_only = true;
- config.ignore_wp = true;
---- a/drivers/nvmem/apple-efuses.c
-+++ b/drivers/nvmem/apple-efuses.c
-@@ -36,6 +36,7 @@ static int apple_efuses_probe(struct pla
- struct resource *res;
- struct nvmem_config config = {
- .dev = &pdev->dev,
-+ .add_legacy_fixed_of_cells = true,
- .read_only = true,
- .reg_read = apple_efuses_read,
- .stride = sizeof(u32),
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -998,9 +998,11 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_legacy_of(nvmem);
-- if (rval)
-- goto err_remove_cells;
-+ if (config->add_legacy_fixed_of_cells) {
-+ rval = nvmem_add_cells_from_legacy_of(nvmem);
-+ if (rval)
-+ goto err_remove_cells;
-+ }
-
- rval = nvmem_add_cells_from_fixed_layout(nvmem);
- if (rval)
---- a/drivers/nvmem/imx-ocotp-scu.c
-+++ b/drivers/nvmem/imx-ocotp-scu.c
-@@ -220,6 +220,7 @@ static int imx_scu_ocotp_write(void *con
-
- static struct nvmem_config imx_scu_ocotp_nvmem_config = {
- .name = "imx-scu-ocotp",
-+ .add_legacy_fixed_of_cells = true,
- .read_only = false,
- .word_size = 4,
- .stride = 1,
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -616,6 +616,7 @@ static int imx_ocotp_probe(struct platfo
- return PTR_ERR(priv->clk);
-
- priv->params = of_device_get_match_data(&pdev->dev);
-+ imx_ocotp_nvmem_config.add_legacy_fixed_of_cells = true;
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
---- a/drivers/nvmem/meson-efuse.c
-+++ b/drivers/nvmem/meson-efuse.c
-@@ -74,6 +74,7 @@ static int meson_efuse_probe(struct plat
-
- econfig->dev = dev;
- econfig->name = dev_name(dev);
-+ econfig->add_legacy_fixed_of_cells = true;
- econfig->stride = 1;
- econfig->word_size = 1;
- econfig->reg_read = meson_efuse_read;
---- a/drivers/nvmem/meson-mx-efuse.c
-+++ b/drivers/nvmem/meson-mx-efuse.c
-@@ -211,6 +211,7 @@ static int meson_mx_efuse_probe(struct p
- efuse->config.owner = THIS_MODULE;
- efuse->config.dev = &pdev->dev;
- efuse->config.priv = efuse;
-+ efuse->config.add_legacy_fixed_of_cells = true;
- efuse->config.stride = drvdata->word_size;
- efuse->config.word_size = drvdata->word_size;
- efuse->config.size = SZ_512;
---- a/drivers/nvmem/microchip-otpc.c
-+++ b/drivers/nvmem/microchip-otpc.c
-@@ -261,6 +261,7 @@ static int mchp_otpc_probe(struct platfo
- return ret;
-
- mchp_nvmem_config.dev = otpc->dev;
-+ mchp_nvmem_config.add_legacy_fixed_of_cells = true;
- mchp_nvmem_config.size = size;
- mchp_nvmem_config.priv = otpc;
- nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config);
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -83,6 +83,7 @@ static int mtk_efuse_probe(struct platfo
- return PTR_ERR(priv->base);
-
- pdata = device_get_match_data(dev);
-+ econfig.add_legacy_fixed_of_cells = true;
- econfig.stride = 1;
- econfig.word_size = 1;
- econfig.reg_read = mtk_reg_read;
---- a/drivers/nvmem/qcom-spmi-sdam.c
-+++ b/drivers/nvmem/qcom-spmi-sdam.c
-@@ -142,6 +142,7 @@ static int sdam_probe(struct platform_de
- sdam->sdam_config.name = "spmi_sdam";
- sdam->sdam_config.id = NVMEM_DEVID_AUTO;
- sdam->sdam_config.owner = THIS_MODULE;
-+ sdam->sdam_config.add_legacy_fixed_of_cells = true;
- sdam->sdam_config.stride = 1;
- sdam->sdam_config.word_size = 1;
- sdam->sdam_config.reg_read = sdam_read;
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -357,6 +357,7 @@ static int qfprom_probe(struct platform_
- {
- struct nvmem_config econfig = {
- .name = "qfprom",
-+ .add_legacy_fixed_of_cells = true,
- .stride = 1,
- .word_size = 1,
- .id = NVMEM_DEVID_AUTO,
---- a/drivers/nvmem/rave-sp-eeprom.c
-+++ b/drivers/nvmem/rave-sp-eeprom.c
-@@ -328,6 +328,7 @@ static int rave_sp_eeprom_probe(struct p
- of_property_read_string(np, "zii,eeprom-name", &config.name);
- config.priv = eeprom;
- config.dev = dev;
-+ config.add_legacy_fixed_of_cells = true;
- config.size = size;
- config.reg_read = rave_sp_eeprom_reg_read;
- config.reg_write = rave_sp_eeprom_reg_write;
---- a/drivers/nvmem/rockchip-efuse.c
-+++ b/drivers/nvmem/rockchip-efuse.c
-@@ -205,6 +205,7 @@ static int rockchip_rk3399_efuse_read(vo
-
- static struct nvmem_config econfig = {
- .name = "rockchip-efuse",
-+ .add_legacy_fixed_of_cells = true,
- .stride = 1,
- .word_size = 1,
- .read_only = true,
---- a/drivers/nvmem/sc27xx-efuse.c
-+++ b/drivers/nvmem/sc27xx-efuse.c
-@@ -248,6 +248,7 @@ static int sc27xx_efuse_probe(struct pla
- econfig.reg_read = sc27xx_efuse_read;
- econfig.priv = efuse;
- econfig.dev = &pdev->dev;
-+ econfig.add_legacy_fixed_of_cells = true;
- nvmem = devm_nvmem_register(&pdev->dev, &econfig);
- if (IS_ERR(nvmem)) {
- dev_err(&pdev->dev, "failed to register nvmem config\n");
---- a/drivers/nvmem/sec-qfprom.c
-+++ b/drivers/nvmem/sec-qfprom.c
-@@ -47,6 +47,7 @@ static int sec_qfprom_probe(struct platf
- {
- struct nvmem_config econfig = {
- .name = "sec-qfprom",
-+ .add_legacy_fixed_of_cells = true,
- .stride = 1,
- .word_size = 1,
- .id = NVMEM_DEVID_AUTO,
---- a/drivers/nvmem/sprd-efuse.c
-+++ b/drivers/nvmem/sprd-efuse.c
-@@ -408,6 +408,7 @@ static int sprd_efuse_probe(struct platf
- econfig.read_only = false;
- econfig.name = "sprd-efuse";
- econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH;
-+ econfig.add_legacy_fixed_of_cells = true;
- econfig.reg_read = sprd_efuse_read;
- econfig.reg_write = sprd_efuse_write;
- econfig.priv = efuse;
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -207,6 +207,7 @@ static int stm32_romem_probe(struct plat
- priv->cfg.priv = priv;
- priv->cfg.owner = THIS_MODULE;
- priv->cfg.type = NVMEM_TYPE_OTP;
-+ priv->cfg.add_legacy_fixed_of_cells = true;
-
- priv->lower = 0;
-
---- a/drivers/nvmem/sunplus-ocotp.c
-+++ b/drivers/nvmem/sunplus-ocotp.c
-@@ -145,6 +145,7 @@ disable_clk:
-
- static struct nvmem_config sp_ocotp_nvmem_config = {
- .name = "sp-ocotp",
-+ .add_legacy_fixed_of_cells = true,
- .read_only = true,
- .word_size = 1,
- .size = QAC628_OTP_SIZE,
---- a/drivers/nvmem/sunxi_sid.c
-+++ b/drivers/nvmem/sunxi_sid.c
-@@ -154,6 +154,7 @@ static int sunxi_sid_probe(struct platfo
- nvmem_cfg->dev = dev;
- nvmem_cfg->name = "sunxi-sid";
- nvmem_cfg->type = NVMEM_TYPE_OTP;
-+ nvmem_cfg->add_legacy_fixed_of_cells = true;
- nvmem_cfg->read_only = true;
- nvmem_cfg->size = cfg->size;
- nvmem_cfg->word_size = 1;
---- a/drivers/nvmem/uniphier-efuse.c
-+++ b/drivers/nvmem/uniphier-efuse.c
-@@ -52,6 +52,7 @@ static int uniphier_efuse_probe(struct p
- econfig.size = resource_size(res);
- econfig.priv = priv;
- econfig.dev = dev;
-+ econfig.add_legacy_fixed_of_cells = true;
- nvmem = devm_nvmem_register(dev, &econfig);
-
- return PTR_ERR_OR_ZERO(nvmem);
---- a/drivers/nvmem/zynqmp_nvmem.c
-+++ b/drivers/nvmem/zynqmp_nvmem.c
-@@ -58,6 +58,7 @@ static int zynqmp_nvmem_probe(struct pla
-
- priv->dev = dev;
- econfig.dev = dev;
-+ econfig.add_legacy_fixed_of_cells = true;
- econfig.reg_read = zynqmp_nvmem_read;
- econfig.priv = priv;
-
---- a/drivers/rtc/nvmem.c
-+++ b/drivers/rtc/nvmem.c
-@@ -21,6 +21,7 @@ int devm_rtc_nvmem_register(struct rtc_d
-
- nvmem_config->dev = dev;
- nvmem_config->owner = rtc->owner;
-+ nvmem_config->add_legacy_fixed_of_cells = true;
- nvmem = devm_nvmem_register(dev, nvmem_config);
- if (IS_ERR(nvmem))
- dev_err(dev, "failed to register nvmem device for RTC\n");
---- a/drivers/w1/slaves/w1_ds250x.c
-+++ b/drivers/w1/slaves/w1_ds250x.c
-@@ -168,6 +168,7 @@ static int w1_eprom_add_slave(struct w1_
- struct nvmem_device *nvmem;
- struct nvmem_config nvmem_cfg = {
- .dev = &sl->dev,
-+ .add_legacy_fixed_of_cells = true,
- .reg_read = w1_nvmem_read,
- .type = NVMEM_TYPE_OTP,
- .read_only = true,
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -82,6 +82,7 @@ struct nvmem_cell_info {
- * @owner: Pointer to exporter module. Used for refcounting.
- * @cells: Optional array of pre-defined NVMEM cells.
- * @ncells: Number of elements in cells.
-+ * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax.
- * @keepout: Optional array of keepout ranges (sorted ascending by start).
- * @nkeepout: Number of elements in the keepout array.
- * @type: Type of the nvmem storage
-@@ -112,6 +113,7 @@ struct nvmem_config {
- struct module *owner;
- const struct nvmem_cell_info *cells;
- int ncells;
-+ bool add_legacy_fixed_of_cells;
- const struct nvmem_keepout *keepout;
- unsigned int nkeepout;
- enum nvmem_type type;
diff --git a/target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch b/target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch
deleted file mode 100644
index 84c0293982..0000000000
--- a/target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 0720219f4d34a88a9badb4de70cfad7585687d48 Mon Sep 17 00:00:00 2001
-From: Rob Herring <robh@kernel.org>
-Date: Fri, 20 Oct 2023 11:55:45 +0100
-Subject: [PATCH] nvmem: Use device_get_match_data()
-
-Use preferred device_get_match_data() instead of of_match_device() to
-get the driver match data. With this, adjust the includes to explicitly
-include the correct headers.
-
-Signed-off-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231020105545.216052-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/mxs-ocotp.c | 10 ++++------
- drivers/nvmem/stm32-romem.c | 7 ++++---
- 2 files changed, 8 insertions(+), 9 deletions(-)
-
---- a/drivers/nvmem/mxs-ocotp.c
-+++ b/drivers/nvmem/mxs-ocotp.c
-@@ -13,8 +13,9 @@
- #include <linux/io.h>
- #include <linux/module.h>
- #include <linux/nvmem-provider.h>
--#include <linux/of_device.h>
-+#include <linux/of.h>
- #include <linux/platform_device.h>
-+#include <linux/property.h>
- #include <linux/slab.h>
- #include <linux/stmp_device.h>
-
-@@ -140,11 +141,10 @@ static int mxs_ocotp_probe(struct platfo
- struct device *dev = &pdev->dev;
- const struct mxs_data *data;
- struct mxs_ocotp *otp;
-- const struct of_device_id *match;
- int ret;
-
-- match = of_match_device(dev->driver->of_match_table, dev);
-- if (!match || !match->data)
-+ data = device_get_match_data(dev);
-+ if (!data)
- return -EINVAL;
-
- otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
-@@ -169,8 +169,6 @@ static int mxs_ocotp_probe(struct platfo
- if (ret)
- return ret;
-
-- data = match->data;
--
- ocotp_config.size = data->size;
- ocotp_config.priv = otp;
- ocotp_config.dev = dev;
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -10,7 +10,9 @@
- #include <linux/io.h>
- #include <linux/module.h>
- #include <linux/nvmem-provider.h>
--#include <linux/of_device.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/property.h>
- #include <linux/tee_drv.h>
-
- #include "stm32-bsec-optee-ta.h"
-@@ -211,8 +213,7 @@ static int stm32_romem_probe(struct plat
-
- priv->lower = 0;
-
-- cfg = (const struct stm32_romem_cfg *)
-- of_match_device(dev->driver->of_match_table, dev)->data;
-+ cfg = device_get_match_data(dev);
- if (!cfg) {
- priv->cfg.read_only = true;
- priv->cfg.size = resource_size(res);
diff --git a/target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch b/target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch
deleted file mode 100644
index b23a23ef3a..0000000000
--- a/target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From f4cf4e5db331a5ce69e3f0b21d322cac0f4e4b5d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 23 Oct 2023 12:27:59 +0200
-Subject: [PATCH] Revert "nvmem: add new config option"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit 517f14d9cf3533d5ab4fded195ab6f80a92e378f.
-
-Config option "no_of_node" is no longer needed since adding a more
-explicit and targeted option "add_legacy_fixed_of_cells".
-
-That "no_of_node" config option was needed *earlier* to help mtd's case.
-
-DT nodes of MTD partitions (that are also NVMEM devices) may contain
-subnodes. Those SHOULD NOT be treated as NVMEM fixed cells.
-
-To prevent NVMEM core code from parsing subnodes a "no_of_node" option
-was added (and set to true in mtd) to make for_each_child_of_node() in
-NVMEM a no-op. That was a bit hacky because it was messing with
-"of_node" pointer to achieve some side-effect.
-
-With the introduction of "add_legacy_fixed_of_cells" config option
-things got more explicit. MTD subsystem simply tells NVMEM when to look
-for fixed cells and there is no need to hack "of_node" pointer anymore.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231023102759.31529-1-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/mtd/mtdcore.c | 1 -
- drivers/nvmem/core.c | 2 +-
- include/linux/nvmem-provider.h | 2 --
- 3 files changed, 1 insertion(+), 4 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -549,7 +549,6 @@ static int mtd_nvmem_add(struct mtd_info
- config.read_only = true;
- config.root_only = true;
- config.ignore_wp = true;
-- config.no_of_node = !of_device_is_compatible(node, "nvmem-cells");
- config.priv = mtd;
-
- mtd->nvmem = nvmem_register(&config);
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -936,7 +936,7 @@ struct nvmem_device *nvmem_register(cons
- nvmem->nkeepout = config->nkeepout;
- if (config->of_node)
- nvmem->dev.of_node = config->of_node;
-- else if (!config->no_of_node)
-+ else
- nvmem->dev.of_node = config->dev->of_node;
-
- switch (config->id) {
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -89,7 +89,6 @@ struct nvmem_cell_info {
- * @read_only: Device is read-only.
- * @root_only: Device is accessibly to root only.
- * @of_node: If given, this will be used instead of the parent's of_node.
-- * @no_of_node: Device should not use the parent's of_node even if it's !NULL.
- * @reg_read: Callback to read data.
- * @reg_write: Callback to write data.
- * @size: Device size.
-@@ -122,7 +121,6 @@ struct nvmem_config {
- bool ignore_wp;
- struct nvmem_layout *layout;
- struct device_node *of_node;
-- bool no_of_node;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
- int size;
diff --git a/target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch b/target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch
deleted file mode 100644
index bd5ceaabf7..0000000000
--- a/target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From b7c1e53751cb3990153084f31c41f25fde3b629c Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 24 Nov 2023 20:38:14 +0100
-Subject: [PATCH] nvmem: Do not expect fixed layouts to grab a layout driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Two series lived in parallel for some time, which led to this situation:
-- The nvmem-layout container is used for dynamic layouts
-- We now expect fixed layouts to also use the nvmem-layout container but
-this does not require any additional driver, the support is built-in the
-nvmem core.
-
-Ensure we don't refuse to probe for wrong reasons.
-
-Fixes: 27f699e578b1 ("nvmem: core: add support for fixed cells *layout*")
-Cc: stable@vger.kernel.org
-Reported-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Rafał Miłecki <rafal@milecki.pl>
-Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-
-Link: https://lore.kernel.org/r/20231124193814.360552-1-miquel.raynal@bootlin.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -797,6 +797,12 @@ static struct nvmem_layout *nvmem_layout
- if (!layout_np)
- return NULL;
-
-+ /* Fixed layouts don't have a matching driver */
-+ if (of_device_is_compatible(layout_np, "fixed-layout")) {
-+ of_node_put(layout_np);
-+ return NULL;
-+ }
-+
- /*
- * In case the nvmem device was built-in while the layout was built as a
- * module, we shall manually request the layout driver loading otherwise
diff --git a/target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch b/target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch
deleted file mode 100644
index d49a20599d..0000000000
--- a/target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From 1e37bf84afacd5ba17b7a13a18ca2bc78aff05c0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 15 Dec 2023 11:13:58 +0000
-Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This driver uses MMIO access for reading NVRAM from a flash device.
-Underneath there is a flash controller that reads data and provides
-mapping window.
-
-Using MMIO interface affects controller configuration and may break real
-controller driver. It was reported by multiple users of devices with
-NVRAM stored on NAND.
-
-Modify driver to read & cache NVRAM content during init and use that
-copy to provide NVMEM data when requested. On NAND flashes due to their
-alignment NVRAM partitions can be quite big (1 MiB and more) while
-actual NVRAM content stays quite small (usually 16 to 32 KiB). To avoid
-allocating so much memory check for actual data length.
-
-Link: https://lore.kernel.org/linux-mtd/CACna6rwf3_9QVjYcM+847biTX=K0EoWXuXcSMkJO1Vy_5vmVqA@mail.gmail.com/
-Fixes: 3fef9ed0627a ("nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM")
-Cc: <Stable@vger.kernel.org>
-Cc: Arınç ÜNAL <arinc.unal@arinc9.com>
-Cc: Florian Fainelli <florian.fainelli@broadcom.com>
-Cc: Scott Branden <scott.branden@broadcom.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111358.316727-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 134 ++++++++++++++++++++++++++-----------
- 1 file changed, 94 insertions(+), 40 deletions(-)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -17,9 +17,23 @@
-
- #define NVRAM_MAGIC "FLSH"
-
-+/**
-+ * struct brcm_nvram - driver state internal struct
-+ *
-+ * @dev: NVMEM device pointer
-+ * @nvmem_size: Size of the whole space available for NVRAM
-+ * @data: NVRAM data copy stored to avoid poking underlaying flash controller
-+ * @data_len: NVRAM data size
-+ * @padding_byte: Padding value used to fill remaining space
-+ * @cells: Array of discovered NVMEM cells
-+ * @ncells: Number of elements in cells
-+ */
- struct brcm_nvram {
- struct device *dev;
-- void __iomem *base;
-+ size_t nvmem_size;
-+ uint8_t *data;
-+ size_t data_len;
-+ uint8_t padding_byte;
- struct nvmem_cell_info *cells;
- int ncells;
- };
-@@ -36,10 +50,47 @@ static int brcm_nvram_read(void *context
- size_t bytes)
- {
- struct brcm_nvram *priv = context;
-- u8 *dst = val;
-+ size_t to_copy;
-+
-+ if (offset + bytes > priv->data_len)
-+ to_copy = max_t(ssize_t, (ssize_t)priv->data_len - offset, 0);
-+ else
-+ to_copy = bytes;
-+
-+ memcpy(val, priv->data + offset, to_copy);
-+
-+ memset((uint8_t *)val + to_copy, priv->padding_byte, bytes - to_copy);
-+
-+ return 0;
-+}
-+
-+static int brcm_nvram_copy_data(struct brcm_nvram *priv, struct platform_device *pdev)
-+{
-+ struct resource *res;
-+ void __iomem *base;
-+
-+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ priv->nvmem_size = resource_size(res);
-+
-+ priv->padding_byte = readb(base + priv->nvmem_size - 1);
-+ for (priv->data_len = priv->nvmem_size;
-+ priv->data_len;
-+ priv->data_len--) {
-+ if (readb(base + priv->data_len - 1) != priv->padding_byte)
-+ break;
-+ }
-+ WARN(priv->data_len > SZ_128K, "Unexpected (big) NVRAM size: %zu B\n", priv->data_len);
-
-- while (bytes--)
-- *dst++ = readb(priv->base + offset++);
-+ priv->data = devm_kzalloc(priv->dev, priv->data_len, GFP_KERNEL);
-+ if (!priv->data)
-+ return -ENOMEM;
-+
-+ memcpy_fromio(priv->data, base, priv->data_len);
-+
-+ bcm47xx_nvram_init_from_iomem(base, priv->data_len);
-
- return 0;
- }
-@@ -67,8 +118,13 @@ static int brcm_nvram_add_cells(struct b
- size_t len)
- {
- struct device *dev = priv->dev;
-- char *var, *value, *eq;
-+ char *var, *value;
-+ uint8_t tmp;
- int idx;
-+ int err = 0;
-+
-+ tmp = priv->data[len - 1];
-+ priv->data[len - 1] = '\0';
-
- priv->ncells = 0;
- for (var = data + sizeof(struct brcm_nvram_header);
-@@ -78,67 +134,68 @@ static int brcm_nvram_add_cells(struct b
- }
-
- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
-- if (!priv->cells)
-- return -ENOMEM;
-+ if (!priv->cells) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-
- for (var = data + sizeof(struct brcm_nvram_header), idx = 0;
- var < (char *)data + len && *var;
- var = value + strlen(value) + 1, idx++) {
-+ char *eq, *name;
-+
- eq = strchr(var, '=');
- if (!eq)
- break;
- *eq = '\0';
-+ name = devm_kstrdup(dev, var, GFP_KERNEL);
-+ *eq = '=';
-+ if (!name) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
- value = eq + 1;
-
-- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
-- if (!priv->cells[idx].name)
-- return -ENOMEM;
-+ priv->cells[idx].name = name;
- priv->cells[idx].offset = value - (char *)data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-- if (!strcmp(var, "et0macaddr") ||
-- !strcmp(var, "et1macaddr") ||
-- !strcmp(var, "et2macaddr")) {
-+ if (!strcmp(name, "et0macaddr") ||
-+ !strcmp(name, "et1macaddr") ||
-+ !strcmp(name, "et2macaddr")) {
- priv->cells[idx].raw_len = strlen(value);
- priv->cells[idx].bytes = ETH_ALEN;
- priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
- }
- }
-
-- return 0;
-+out:
-+ priv->data[len - 1] = tmp;
-+ return err;
- }
-
- static int brcm_nvram_parse(struct brcm_nvram *priv)
- {
-+ struct brcm_nvram_header *header = (struct brcm_nvram_header *)priv->data;
- struct device *dev = priv->dev;
-- struct brcm_nvram_header header;
-- uint8_t *data;
- size_t len;
- int err;
-
-- memcpy_fromio(&header, priv->base, sizeof(header));
--
-- if (memcmp(header.magic, NVRAM_MAGIC, 4)) {
-+ if (memcmp(header->magic, NVRAM_MAGIC, 4)) {
- dev_err(dev, "Invalid NVRAM magic\n");
- return -EINVAL;
- }
-
-- len = le32_to_cpu(header.len);
--
-- data = kzalloc(len, GFP_KERNEL);
-- if (!data)
-- return -ENOMEM;
--
-- memcpy_fromio(data, priv->base, len);
-- data[len - 1] = '\0';
--
-- err = brcm_nvram_add_cells(priv, data, len);
-- if (err) {
-- dev_err(dev, "Failed to add cells: %d\n", err);
-- return err;
-+ len = le32_to_cpu(header->len);
-+ if (len > priv->nvmem_size) {
-+ dev_err(dev, "NVRAM length (%zd) exceeds mapped size (%zd)\n", len,
-+ priv->nvmem_size);
-+ return -EINVAL;
- }
-
-- kfree(data);
-+ err = brcm_nvram_add_cells(priv, priv->data, len);
-+ if (err)
-+ dev_err(dev, "Failed to add cells: %d\n", err);
-
- return 0;
- }
-@@ -150,7 +207,6 @@ static int brcm_nvram_probe(struct platf
- .reg_read = brcm_nvram_read,
- };
- struct device *dev = &pdev->dev;
-- struct resource *res;
- struct brcm_nvram *priv;
- int err;
-
-@@ -159,21 +215,19 @@ static int brcm_nvram_probe(struct platf
- return -ENOMEM;
- priv->dev = dev;
-
-- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-- if (IS_ERR(priv->base))
-- return PTR_ERR(priv->base);
-+ err = brcm_nvram_copy_data(priv, pdev);
-+ if (err)
-+ return err;
-
- err = brcm_nvram_parse(priv);
- if (err)
- return err;
-
-- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
--
- config.dev = dev;
- config.cells = priv->cells;
- config.ncells = priv->ncells;
- config.priv = priv;
-- config.size = resource_size(res);
-+ config.size = priv->nvmem_size;
-
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
- }
diff --git a/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch b/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch
deleted file mode 100644
index 4a63b89f57..0000000000
--- a/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 5cb03751455c299b1bf10cb48631bf359cfb11b5 Mon Sep 17 00:00:00 2001
-From: "mark-yw.chen" <mark-yw.chen@mediatek.com>
-Date: Wed, 1 Sep 2021 11:32:25 +0800
-Subject: [PATCH 1/5] Bluetooth: btusb: Support public address configuration
- for MediaTek Chip.
-
-The MediaTek chip support vendor specific HCI command(0xfc1a) to
-change the public address. Add hdev->set_bdaddr handler for MediaTek
-Chip. After doing a power cycle or MediaTek Bluetooth reset, BD_ADDR
-will bring back the original one.
-
-Signed-off-by: mark-yw.chen <mark-yw.chen@mediatek.com>
-Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
----
- drivers/bluetooth/btusb.c | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -2289,6 +2289,23 @@ struct btmtk_section_map {
- };
- } __packed;
-
-+static int btusb_set_bdaddr_mtk(struct hci_dev *hdev, const bdaddr_t *bdaddr)
-+{
-+ struct sk_buff *skb;
-+ long ret;
-+
-+ skb = __hci_cmd_sync(hdev, 0xfc1a, sizeof(bdaddr), bdaddr, HCI_INIT_TIMEOUT);
-+ if (IS_ERR(skb)) {
-+ ret = PTR_ERR(skb);
-+ bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
-+ ret);
-+ return ret;
-+ }
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
- static void btusb_mtk_wmt_recv(struct urb *urb)
- {
- struct hci_dev *hdev = urb->context;
-@@ -3943,6 +3960,7 @@ static int btusb_probe(struct usb_interf
- hdev->shutdown = btusb_mtk_shutdown;
- hdev->manufacturer = 70;
- hdev->cmd_timeout = btusb_mtk_cmd_timeout;
-+ hdev->set_bdaddr = btusb_set_bdaddr_mtk;
- set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
- data->recv_acl = btusb_recv_acl_mtk;
- }
diff --git a/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch b/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch
deleted file mode 100644
index d21adada97..0000000000
--- a/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From af774a731f7b4c2a90a8476cd44045ba8d1263ba Mon Sep 17 00:00:00 2001
-From: David Yang <davidcomponentone@gmail.com>
-Date: Wed, 13 Oct 2021 08:56:33 +0800
-Subject: [PATCH 2/5] Bluetooth: btusb: Fix application of sizeof to pointer
-
-The coccinelle check report:
-"./drivers/bluetooth/btusb.c:2239:36-42:
-ERROR: application of sizeof to pointer".
-Using the real size to fix it.
-
-Fixes: 5a87679ffd443 ("Bluetooth: btusb: Support public address configuration for MediaTek Chip.")
-Reported-by: Zeal Robot <zealci@zte.com.cn>
-Signed-off-by: David Yang <davidcomponentone@gmail.com>
-Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
----
- drivers/bluetooth/btusb.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -2294,7 +2294,7 @@ static int btusb_set_bdaddr_mtk(struct h
- struct sk_buff *skb;
- long ret;
-
-- skb = __hci_cmd_sync(hdev, 0xfc1a, sizeof(bdaddr), bdaddr, HCI_INIT_TIMEOUT);
-+ skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
- if (IS_ERR(skb)) {
- ret = PTR_ERR(skb);
- bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
diff --git a/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch b/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch
deleted file mode 100644
index 30492ac48d..0000000000
--- a/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From e57186fc02cedff191c469a26cce615371e41740 Mon Sep 17 00:00:00 2001
-From: Yake Yang <yake.yang@mediatek.com>
-Date: Wed, 23 Feb 2022 07:55:59 +0800
-Subject: [PATCH 3/5] Bluetooth: btusb: Add a new PID/VID 13d3/3567 for MT7921
-
-Add VID 13D3 & PID 3567 for MediaTek MT7921 USB Bluetooth chip.
-
-The information in /sys/kernel/debug/usb/devices about the Bluetooth
-device is listed as the below.
-
-T: Bus=05 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
-D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
-P: Vendor=13d3 ProdID=3567 Rev= 1.00
-S: Manufacturer=MediaTek Inc.
-S: Product=Wireless_Device
-S: SerialNumber=000000000
-C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
-A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
-I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us
-E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
-I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
-E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
-E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
-I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
-E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
-E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
-
-Co-developed-by: Sean Wang <sean.wang@mediatek.com>
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Signed-off-by: Yake Yang <yake.yang@mediatek.com>
-Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
----
- drivers/bluetooth/btusb.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -478,6 +478,9 @@ static const struct usb_device_id blackl
- { USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK |
- BTUSB_WIDEBAND_SPEECH |
- BTUSB_VALID_LE_STATES },
-+ { USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK |
-+ BTUSB_WIDEBAND_SPEECH |
-+ BTUSB_VALID_LE_STATES },
- { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
- BTUSB_WIDEBAND_SPEECH |
- BTUSB_VALID_LE_STATES },
diff --git a/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch b/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch
deleted file mode 100644
index 6bcd81c3b8..0000000000
--- a/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From e507366cd1e8e1d4eebe537c08fd142cf0b617fa Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Thu, 28 Apr 2022 02:38:39 +0800
-Subject: [PATCH 4/5] Bluetooth: btusb: Add a new PID/VID 0489/e0c8 for MT7921
-
-Add VID 0489 & PID e0c8 for MediaTek MT7921 USB Bluetooth chip.
-
-The information in /sys/kernel/debug/usb/devices about the Bluetooth
-device is listed as the below.
-
-T: Bus=01 Lev=01 Prnt=01 Port=13 Cnt=03 Dev#= 4 Spd=480 MxCh= 0
-D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
-P: Vendor=0489 ProdID=e0c8 Rev= 1.00
-S: Manufacturer=MediaTek Inc.
-S: Product=Wireless_Device
-S: SerialNumber=000000000
-C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
-A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
-I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us
-E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
-I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
-E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
-E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
-I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
-E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
-E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
----
- drivers/bluetooth/btusb.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -469,6 +469,9 @@ static const struct usb_device_id blackl
- BTUSB_VALID_LE_STATES },
-
- /* Additional MediaTek MT7921 Bluetooth devices */
-+ { USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK |
-+ BTUSB_WIDEBAND_SPEECH |
-+ BTUSB_VALID_LE_STATES },
- { USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
- BTUSB_WIDEBAND_SPEECH |
- BTUSB_VALID_LE_STATES },
diff --git a/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch b/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch
deleted file mode 100644
index b6b76f64fc..0000000000
--- a/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From be55622ce673f9692cc15d26d77a050cda42a3d3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 9 Sep 2022 21:00:30 +0100
-Subject: [PATCH 1/1] Bluetooth: btusb: Add a new VID/PID 0e8d/0608 for MT7921
-
-Add a new PID/VID 0e8d/0608 for MT7921K chip found on AMD RZ608 module.
-
-From /sys/kernel/debug/usb/devices:
-T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 3 Spd=480 MxCh= 0
-D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
-P: Vendor=0e8d ProdID=0608 Rev= 1.00
-S: Manufacturer=MediaTek Inc.
-S: Product=Wireless_Device
-S: SerialNumber=000000000
-C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
-A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
-I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us
-E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
-I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
-E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
-E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
-I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
-E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
-E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
----
- drivers/bluetooth/btusb.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -487,6 +487,9 @@ static const struct usb_device_id blackl
- { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
- BTUSB_WIDEBAND_SPEECH |
- BTUSB_VALID_LE_STATES },
-+ { USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK |
-+ BTUSB_WIDEBAND_SPEECH |
-+ BTUSB_VALID_LE_STATES },
-
- /* MediaTek MT7922A Bluetooth devices */
- { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK |
diff --git a/target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch b/target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch
deleted file mode 100644
index 0ad89de560..0000000000
--- a/target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch
+++ /dev/null
@@ -1,359 +0,0 @@
-From 66a8f7f04979f4ad739085f01d99c8caf620b4f5 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 18 Jan 2022 18:35:02 +0100
-Subject: [PATCH] of: base: make small of_parse_phandle() variants static
- inline
-
-Make all the smaller variants of the of_parse_phandle() static inline.
-This also let us remove the empty function stubs if CONFIG_OF is not
-defined.
-
-Suggested-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Michael Walle <michael@walle.cc>
-[robh: move index < 0 check into __of_parse_phandle_with_args]
-Signed-off-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20220118173504.2867523-2-michael@walle.cc
----
- drivers/of/base.c | 131 +++------------------------------------
- include/linux/of.h | 148 ++++++++++++++++++++++++++++++++++++---------
- 2 files changed, 129 insertions(+), 150 deletions(-)
-
---- a/drivers/of/base.c
-+++ b/drivers/of/base.c
-@@ -1371,15 +1371,18 @@ int of_phandle_iterator_args(struct of_p
- return count;
- }
-
--static int __of_parse_phandle_with_args(const struct device_node *np,
-- const char *list_name,
-- const char *cells_name,
-- int cell_count, int index,
-- struct of_phandle_args *out_args)
-+int __of_parse_phandle_with_args(const struct device_node *np,
-+ const char *list_name,
-+ const char *cells_name,
-+ int cell_count, int index,
-+ struct of_phandle_args *out_args)
- {
- struct of_phandle_iterator it;
- int rc, cur_index = 0;
-
-+ if (index < 0)
-+ return -EINVAL;
-+
- /* Loop over the phandles until all the requested entry is found */
- of_for_each_phandle(&it, rc, np, list_name, cells_name, cell_count) {
- /*
-@@ -1422,82 +1425,7 @@ static int __of_parse_phandle_with_args(
- of_node_put(it.node);
- return rc;
- }
--
--/**
-- * of_parse_phandle - Resolve a phandle property to a device_node pointer
-- * @np: Pointer to device node holding phandle property
-- * @phandle_name: Name of property holding a phandle value
-- * @index: For properties holding a table of phandles, this is the index into
-- * the table
-- *
-- * Return: The device_node pointer with refcount incremented. Use
-- * of_node_put() on it when done.
-- */
--struct device_node *of_parse_phandle(const struct device_node *np,
-- const char *phandle_name, int index)
--{
-- struct of_phandle_args args;
--
-- if (index < 0)
-- return NULL;
--
-- if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
-- index, &args))
-- return NULL;
--
-- return args.np;
--}
--EXPORT_SYMBOL(of_parse_phandle);
--
--/**
-- * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
-- * @np: pointer to a device tree node containing a list
-- * @list_name: property name that contains a list
-- * @cells_name: property name that specifies phandles' arguments count
-- * @index: index of a phandle to parse out
-- * @out_args: optional pointer to output arguments structure (will be filled)
-- *
-- * This function is useful to parse lists of phandles and their arguments.
-- * Returns 0 on success and fills out_args, on error returns appropriate
-- * errno value.
-- *
-- * Caller is responsible to call of_node_put() on the returned out_args->np
-- * pointer.
-- *
-- * Example::
-- *
-- * phandle1: node1 {
-- * #list-cells = <2>;
-- * };
-- *
-- * phandle2: node2 {
-- * #list-cells = <1>;
-- * };
-- *
-- * node3 {
-- * list = <&phandle1 1 2 &phandle2 3>;
-- * };
-- *
-- * To get a device_node of the ``node2`` node you may call this:
-- * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
-- */
--int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
-- const char *cells_name, int index,
-- struct of_phandle_args *out_args)
--{
-- int cell_count = -1;
--
-- if (index < 0)
-- return -EINVAL;
--
-- /* If cells_name is NULL we assume a cell count of 0 */
-- if (!cells_name)
-- cell_count = 0;
--
-- return __of_parse_phandle_with_args(np, list_name, cells_name,
-- cell_count, index, out_args);
--}
--EXPORT_SYMBOL(of_parse_phandle_with_args);
-+EXPORT_SYMBOL(__of_parse_phandle_with_args);
-
- /**
- * of_parse_phandle_with_args_map() - Find a node pointed by phandle in a list and remap it
-@@ -1685,47 +1613,6 @@ free:
- EXPORT_SYMBOL(of_parse_phandle_with_args_map);
-
- /**
-- * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
-- * @np: pointer to a device tree node containing a list
-- * @list_name: property name that contains a list
-- * @cell_count: number of argument cells following the phandle
-- * @index: index of a phandle to parse out
-- * @out_args: optional pointer to output arguments structure (will be filled)
-- *
-- * This function is useful to parse lists of phandles and their arguments.
-- * Returns 0 on success and fills out_args, on error returns appropriate
-- * errno value.
-- *
-- * Caller is responsible to call of_node_put() on the returned out_args->np
-- * pointer.
-- *
-- * Example::
-- *
-- * phandle1: node1 {
-- * };
-- *
-- * phandle2: node2 {
-- * };
-- *
-- * node3 {
-- * list = <&phandle1 0 2 &phandle2 2 3>;
-- * };
-- *
-- * To get a device_node of the ``node2`` node you may call this:
-- * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
-- */
--int of_parse_phandle_with_fixed_args(const struct device_node *np,
-- const char *list_name, int cell_count,
-- int index, struct of_phandle_args *out_args)
--{
-- if (index < 0)
-- return -EINVAL;
-- return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
-- index, out_args);
--}
--EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
--
--/**
- * of_count_phandle_with_args() - Find the number of phandles references in a property
- * @np: pointer to a device tree node containing a list
- * @list_name: property name that contains a list
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -363,18 +363,12 @@ extern const struct of_device_id *of_mat
- const struct of_device_id *matches, const struct device_node *node);
- extern int of_modalias_node(struct device_node *node, char *modalias, int len);
- extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args);
--extern struct device_node *of_parse_phandle(const struct device_node *np,
-- const char *phandle_name,
-- int index);
--extern int of_parse_phandle_with_args(const struct device_node *np,
-- const char *list_name, const char *cells_name, int index,
-- struct of_phandle_args *out_args);
-+extern int __of_parse_phandle_with_args(const struct device_node *np,
-+ const char *list_name, const char *cells_name, int cell_count,
-+ int index, struct of_phandle_args *out_args);
- extern int of_parse_phandle_with_args_map(const struct device_node *np,
- const char *list_name, const char *stem_name, int index,
- struct of_phandle_args *out_args);
--extern int of_parse_phandle_with_fixed_args(const struct device_node *np,
-- const char *list_name, int cells_count, int index,
-- struct of_phandle_args *out_args);
- extern int of_count_phandle_with_args(const struct device_node *np,
- const char *list_name, const char *cells_name);
-
-@@ -714,18 +708,12 @@ static inline int of_property_read_strin
- return -ENOSYS;
- }
-
--static inline struct device_node *of_parse_phandle(const struct device_node *np,
-- const char *phandle_name,
-- int index)
--{
-- return NULL;
--}
--
--static inline int of_parse_phandle_with_args(const struct device_node *np,
-- const char *list_name,
-- const char *cells_name,
-- int index,
-- struct of_phandle_args *out_args)
-+static inline int __of_parse_phandle_with_args(const struct device_node *np,
-+ const char *list_name,
-+ const char *cells_name,
-+ int cell_count,
-+ int index,
-+ struct of_phandle_args *out_args)
- {
- return -ENOSYS;
- }
-@@ -739,13 +727,6 @@ static inline int of_parse_phandle_with_
- return -ENOSYS;
- }
-
--static inline int of_parse_phandle_with_fixed_args(const struct device_node *np,
-- const char *list_name, int cells_count, int index,
-- struct of_phandle_args *out_args)
--{
-- return -ENOSYS;
--}
--
- static inline int of_count_phandle_with_args(const struct device_node *np,
- const char *list_name,
- const char *cells_name)
-@@ -927,6 +908,117 @@ static inline bool of_node_is_type(const
- }
-
- /**
-+ * of_parse_phandle - Resolve a phandle property to a device_node pointer
-+ * @np: Pointer to device node holding phandle property
-+ * @phandle_name: Name of property holding a phandle value
-+ * @index: For properties holding a table of phandles, this is the index into
-+ * the table
-+ *
-+ * Return: The device_node pointer with refcount incremented. Use
-+ * of_node_put() on it when done.
-+ */
-+static inline struct device_node *of_parse_phandle(const struct device_node *np,
-+ const char *phandle_name,
-+ int index)
-+{
-+ struct of_phandle_args args;
-+
-+ if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
-+ index, &args))
-+ return NULL;
-+
-+ return args.np;
-+}
-+
-+/**
-+ * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
-+ * @np: pointer to a device tree node containing a list
-+ * @list_name: property name that contains a list
-+ * @cells_name: property name that specifies phandles' arguments count
-+ * @index: index of a phandle to parse out
-+ * @out_args: optional pointer to output arguments structure (will be filled)
-+ *
-+ * This function is useful to parse lists of phandles and their arguments.
-+ * Returns 0 on success and fills out_args, on error returns appropriate
-+ * errno value.
-+ *
-+ * Caller is responsible to call of_node_put() on the returned out_args->np
-+ * pointer.
-+ *
-+ * Example::
-+ *
-+ * phandle1: node1 {
-+ * #list-cells = <2>;
-+ * };
-+ *
-+ * phandle2: node2 {
-+ * #list-cells = <1>;
-+ * };
-+ *
-+ * node3 {
-+ * list = <&phandle1 1 2 &phandle2 3>;
-+ * };
-+ *
-+ * To get a device_node of the ``node2`` node you may call this:
-+ * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
-+ */
-+static inline int of_parse_phandle_with_args(const struct device_node *np,
-+ const char *list_name,
-+ const char *cells_name,
-+ int index,
-+ struct of_phandle_args *out_args)
-+{
-+ int cell_count = -1;
-+
-+ /* If cells_name is NULL we assume a cell count of 0 */
-+ if (!cells_name)
-+ cell_count = 0;
-+
-+ return __of_parse_phandle_with_args(np, list_name, cells_name,
-+ cell_count, index, out_args);
-+}
-+
-+/**
-+ * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
-+ * @np: pointer to a device tree node containing a list
-+ * @list_name: property name that contains a list
-+ * @cell_count: number of argument cells following the phandle
-+ * @index: index of a phandle to parse out
-+ * @out_args: optional pointer to output arguments structure (will be filled)
-+ *
-+ * This function is useful to parse lists of phandles and their arguments.
-+ * Returns 0 on success and fills out_args, on error returns appropriate
-+ * errno value.
-+ *
-+ * Caller is responsible to call of_node_put() on the returned out_args->np
-+ * pointer.
-+ *
-+ * Example::
-+ *
-+ * phandle1: node1 {
-+ * };
-+ *
-+ * phandle2: node2 {
-+ * };
-+ *
-+ * node3 {
-+ * list = <&phandle1 0 2 &phandle2 2 3>;
-+ * };
-+ *
-+ * To get a device_node of the ``node2`` node you may call this:
-+ * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
-+ */
-+static inline int of_parse_phandle_with_fixed_args(const struct device_node *np,
-+ const char *list_name,
-+ int cell_count,
-+ int index,
-+ struct of_phandle_args *out_args)
-+{
-+ return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
-+ index, out_args);
-+}
-+
-+/**
- * of_property_count_u8_elems - Count the number of u8 elements in a property
- *
- * @np: device node from which the property value is to be read.
diff --git a/target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch b/target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch
deleted file mode 100644
index 97f4c6981e..0000000000
--- a/target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From c5d264d4b527c96ae8903376a4b195df47b05203 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:43 +0000
-Subject: [PATCH] of: base: add of_parse_phandle_with_optional_args()
-
-Add a new variant of the of_parse_phandle_with_args() which treats the
-cells name as optional. If it's missing, it is assumed that the phandle
-has no arguments.
-
-Up until now, a nvmem node didn't have any arguments, so all the device
-trees haven't any '#*-cells' property. But there is a need for an
-additional argument for the phandle, for which we need a '#*-cells'
-property. Therefore, we need to support nvmem nodes with and without
-this property.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/of.h | 25 +++++++++++++++++++++++++
- 1 file changed, 25 insertions(+)
-
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -1019,6 +1019,31 @@ static inline int of_parse_phandle_with_
- }
-
- /**
-+ * of_parse_phandle_with_optional_args() - Find a node pointed by phandle in a list
-+ * @np: pointer to a device tree node containing a list
-+ * @list_name: property name that contains a list
-+ * @cells_name: property name that specifies phandles' arguments count
-+ * @index: index of a phandle to parse out
-+ * @out_args: optional pointer to output arguments structure (will be filled)
-+ *
-+ * Same as of_parse_phandle_with_args() except that if the cells_name property
-+ * is not found, cell_count of 0 is assumed.
-+ *
-+ * This is used to useful, if you have a phandle which didn't have arguments
-+ * before and thus doesn't have a '#*-cells' property but is now migrated to
-+ * having arguments while retaining backwards compatibility.
-+ */
-+static inline int of_parse_phandle_with_optional_args(const struct device_node *np,
-+ const char *list_name,
-+ const char *cells_name,
-+ int index,
-+ struct of_phandle_args *out_args)
-+{
-+ return __of_parse_phandle_with_args(np, list_name, cells_name,
-+ 0, index, out_args);
-+}
-+
-+/**
- * of_property_count_u8_elems - Count the number of u8 elements in a property
- *
- * @np: device node from which the property value is to be read.
diff --git a/target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch b/target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch
deleted file mode 100644
index 39d9fae723..0000000000
--- a/target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From ff24fed10ba414d19579e26e60b126fad2f2bb07 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:44 +0000
-Subject: [PATCH] of: property: make #.*-cells optional for simple props
-
-Sometimes, future bindings for phandles will get additional arguments.
-Thus the target node of the phandle will need a new #.*-cells property.
-To be backwards compatible, this needs to be optional.
-
-Prepare the DEFINE_SIMPLE_PROPS() to handle the cells name as optional.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Tested-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-11-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/property.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/of/property.c
-+++ b/drivers/of/property.c
-@@ -1173,8 +1173,8 @@ static struct device_node *parse_prop_ce
- if (strcmp(prop_name, list_name))
- return NULL;
-
-- if (of_parse_phandle_with_args(np, list_name, cells_name, index,
-- &sup_args))
-+ if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
-+ &sup_args))
- return NULL;
-
- return sup_args.np;
diff --git a/target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch b/target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch
deleted file mode 100644
index 774e793ca5..0000000000
--- a/target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From e2d8172043d2e50df19fcd59c11e5593de8188d7 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:45 +0000
-Subject: [PATCH] of: property: add #nvmem-cell-cells property
-
-Bindings describe the new '#nvmem-cell-cells' property. Now that the
-arguments count property is optional, we just add this property to the
-nvmem-cells.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Tested-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-12-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/property.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/of/property.c
-+++ b/drivers/of/property.c
-@@ -1276,7 +1276,7 @@ DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-c
- DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells")
- DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells")
- DEFINE_SIMPLE_PROP(extcon, "extcon", NULL)
--DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", NULL)
-+DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells")
- DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells")
- DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL)
- DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL)
diff --git a/target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch b/target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch
deleted file mode 100644
index 37eefc4570..0000000000
--- a/target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 553bd29700145e1849698985e9800f14e967da49 Mon Sep 17 00:00:00 2001
-From: Alexander Stein <alexander.stein@ew.tq-group.com>
-Date: Tue, 7 Feb 2023 12:05:29 +0100
-Subject: [PATCH] of: device: Ignore modalias of reused nodes
-
-If of_node is reused, do not use that node's modalias. This will hide
-the name of the actual device. This is rather prominent in USB glue
-drivers creating a platform device for the host controller.
-
-Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20230207110531.1060252-2-alexander.stein@ew.tq-group.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -249,7 +249,7 @@ static ssize_t of_device_get_modalias(st
- ssize_t csize;
- ssize_t tsize;
-
-- if ((!dev) || (!dev->of_node))
-+ if ((!dev) || (!dev->of_node) || dev->of_node_reused)
- return -ENODEV;
-
- /* Name & Type */
-@@ -372,7 +372,7 @@ int of_device_uevent_modalias(struct dev
- {
- int sl;
-
-- if ((!dev) || (!dev->of_node))
-+ if ((!dev) || (!dev->of_node) || dev->of_node_reused)
- return -ENODEV;
-
- /* Devicetree modalias is tricky, we add it in 2 steps */
diff --git a/target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch b/target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch
deleted file mode 100644
index dd5820e94a..0000000000
--- a/target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 2295bed9bebe8d1eef276194fed5b5fbe89c5363 Mon Sep 17 00:00:00 2001
-From: Alexander Stein <alexander.stein@ew.tq-group.com>
-Date: Tue, 7 Feb 2023 12:05:30 +0100
-Subject: [PATCH] of: device: Do not ignore error code in
- of_device_uevent_modalias
-
-of_device_get_modalias might return an error code, propagate that one.
-Otherwise the negative, signed integer is propagated to unsigned integer
-for the comparison resulting in a huge 'sl' size.
-
-Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20230207110531.1060252-3-alexander.stein@ew.tq-group.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -381,6 +381,8 @@ int of_device_uevent_modalias(struct dev
-
- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
- sizeof(env->buf) - env->buflen);
-+ if (sl < 0)
-+ return sl;
- if (sl >= (sizeof(env->buf) - env->buflen))
- return -ENOMEM;
- env->buflen += sl;
diff --git a/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch b/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch
deleted file mode 100644
index 4713cc71b1..0000000000
--- a/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 5c3d15e127ebfc0754cd18def7124633b6d46672 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:15 +0100
-Subject: [PATCH] of: Update of_device_get_modalias()
-
-This function only needs a "struct device_node" to work, but for
-convenience the author (and only user) of this helper did use a "struct
-device" and put it in device.c.
-
-Let's convert this helper to take a "struct device node" instead. This
-change asks for two additional changes: renaming it "of_modalias()"
-to fit the current naming, and moving it outside of device.c which will
-be done in a follow-up commit.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 29 +++++++++++++++++------------
- 1 file changed, 17 insertions(+), 12 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -241,7 +241,7 @@ const void *of_device_get_match_data(con
- }
- EXPORT_SYMBOL(of_device_get_match_data);
-
--static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
-+static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
- {
- const char *compat;
- char *c;
-@@ -249,19 +249,16 @@ static ssize_t of_device_get_modalias(st
- ssize_t csize;
- ssize_t tsize;
-
-- if ((!dev) || (!dev->of_node) || dev->of_node_reused)
-- return -ENODEV;
--
- /* Name & Type */
- /* %p eats all alphanum characters, so %c must be used here */
-- csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
-- of_node_get_device_type(dev->of_node));
-+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
-+ of_node_get_device_type(np));
- tsize = csize;
- len -= csize;
- if (str)
- str += csize;
-
-- of_property_for_each_string(dev->of_node, "compatible", p, compat) {
-+ of_property_for_each_string(np, "compatible", p, compat) {
- csize = strlen(compat) + 1;
- tsize += csize;
- if (csize > len)
-@@ -286,7 +283,10 @@ int of_device_request_module(struct devi
- ssize_t size;
- int ret;
-
-- size = of_device_get_modalias(dev, NULL, 0);
-+ if (!dev || !dev->of_node)
-+ return -ENODEV;
-+
-+ size = of_modalias(dev->of_node, NULL, 0);
- if (size < 0)
- return size;
-
-@@ -297,7 +297,7 @@ int of_device_request_module(struct devi
- if (!str)
- return -ENOMEM;
-
-- of_device_get_modalias(dev, str, size);
-+ of_modalias(dev->of_node, str, size);
- str[size - 1] = '\0';
- ret = request_module(str);
- kfree(str);
-@@ -314,7 +314,12 @@ EXPORT_SYMBOL_GPL(of_device_request_modu
- */
- ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
- {
-- ssize_t sl = of_device_get_modalias(dev, str, len - 2);
-+ ssize_t sl;
-+
-+ if (!dev || !dev->of_node || dev->of_node_reused)
-+ return -ENODEV;
-+
-+ sl = of_modalias(dev->of_node, str, len - 2);
- if (sl < 0)
- return sl;
- if (sl > len - 2)
-@@ -379,8 +384,8 @@ int of_device_uevent_modalias(struct dev
- if (add_uevent_var(env, "MODALIAS="))
- return -ENOMEM;
-
-- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
-- sizeof(env->buf) - env->buflen);
-+ sl = of_modalias(dev->of_node, &env->buf[env->buflen-1],
-+ sizeof(env->buf) - env->buflen);
- if (sl < 0)
- return sl;
- if (sl >= (sizeof(env->buf) - env->buflen))
diff --git a/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch
deleted file mode 100644
index 855d45311e..0000000000
--- a/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 673aa1ed1c9b6710bf24e3f0957d85e2f46c77db Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:16 +0100
-Subject: [PATCH] of: Rename of_modalias_node()
-
-This helper does not produce a real modalias, but tries to get the
-"product" compatible part of the "vendor,product" compatibles only. It
-is far from creating a purely useful modalias string and does not seem
-to be used like that directly anyway, so let's try to give this helper a
-more meaningful name before moving there a real modalias helper (already
-existing under of/device.c).
-
-Also update the various documentations to refer to the strings as
-"aliases" rather than "modaliases" which has a real meaning in the Linux
-kernel.
-
-There is no functional change.
-
-Cc: Rafael J. Wysocki <rafael@kernel.org>
-Cc: Len Brown <lenb@kernel.org>
-Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Cc: Maxime Ripard <mripard@kernel.org>
-Cc: Thomas Zimmermann <tzimmermann@suse.de>
-Cc: Sebastian Reichel <sre@kernel.org>
-Cc: Wolfram Sang <wsa@kernel.org>
-Cc: Mark Brown <broonie@kernel.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Acked-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Acked-by: Sebastian Reichel <sre@kernel.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/acpi/bus.c | 7 ++++---
- drivers/gpu/drm/drm_mipi_dsi.c | 2 +-
- drivers/hsi/hsi_core.c | 2 +-
- drivers/i2c/busses/i2c-powermac.c | 2 +-
- drivers/i2c/i2c-core-of.c | 2 +-
- drivers/of/base.c | 18 +++++++++++-------
- drivers/spi/spi.c | 4 ++--
- include/linux/of.h | 3 ++-
- 8 files changed, 23 insertions(+), 17 deletions(-)
-
---- a/drivers/acpi/bus.c
-+++ b/drivers/acpi/bus.c
-@@ -785,9 +785,10 @@ static bool acpi_of_modalias(struct acpi
- * @modalias: Pointer to buffer that modalias value will be copied into
- * @len: Length of modalias buffer
- *
-- * This is a counterpart of of_modalias_node() for struct acpi_device objects.
-- * If there is a compatible string for @adev, it will be copied to @modalias
-- * with the vendor prefix stripped; otherwise, @default_id will be used.
-+ * This is a counterpart of of_alias_from_compatible() for struct acpi_device
-+ * objects. If there is a compatible string for @adev, it will be copied to
-+ * @modalias with the vendor prefix stripped; otherwise, @default_id will be
-+ * used.
- */
- void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
- char *modalias, size_t len)
---- a/drivers/gpu/drm/drm_mipi_dsi.c
-+++ b/drivers/gpu/drm/drm_mipi_dsi.c
-@@ -160,7 +160,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_h
- int ret;
- u32 reg;
-
-- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
-+ if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) {
- drm_err(host, "modalias failure on %pOF\n", node);
- return ERR_PTR(-EINVAL);
- }
---- a/drivers/hsi/hsi_core.c
-+++ b/drivers/hsi/hsi_core.c
-@@ -207,7 +207,7 @@ static void hsi_add_client_from_dt(struc
- if (!cl)
- return;
-
-- err = of_modalias_node(client, name, sizeof(name));
-+ err = of_alias_from_compatible(client, name, sizeof(name));
- if (err)
- goto err;
-
---- a/drivers/i2c/busses/i2c-powermac.c
-+++ b/drivers/i2c/busses/i2c-powermac.c
-@@ -284,7 +284,7 @@ static bool i2c_powermac_get_type(struct
- */
-
- /* First try proper modalias */
-- if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) {
-+ if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) {
- snprintf(type, type_size, "MAC,%s", tmp);
- return true;
- }
---- a/drivers/i2c/i2c-core-of.c
-+++ b/drivers/i2c/i2c-core-of.c
-@@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device
-
- memset(info, 0, sizeof(*info));
-
-- if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) {
-+ if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) {
- dev_err(dev, "of_i2c: modalias failure on %pOF\n", node);
- return -EINVAL;
- }
---- a/drivers/of/base.c
-+++ b/drivers/of/base.c
-@@ -1159,19 +1159,23 @@ struct device_node *of_find_matching_nod
- EXPORT_SYMBOL(of_find_matching_node_and_match);
-
- /**
-- * of_modalias_node - Lookup appropriate modalias for a device node
-+ * of_alias_from_compatible - Lookup appropriate alias for a device node
-+ * depending on compatible
- * @node: pointer to a device tree node
-- * @modalias: Pointer to buffer that modalias value will be copied into
-- * @len: Length of modalias value
-+ * @alias: Pointer to buffer that alias value will be copied into
-+ * @len: Length of alias value
- *
- * Based on the value of the compatible property, this routine will attempt
-- * to choose an appropriate modalias value for a particular device tree node.
-+ * to choose an appropriate alias value for a particular device tree node.
- * It does this by stripping the manufacturer prefix (as delimited by a ',')
- * from the first entry in the compatible list property.
- *
-+ * Note: The matching on just the "product" side of the compatible is a relic
-+ * from I2C and SPI. Please do not add any new user.
-+ *
- * Return: This routine returns 0 on success, <0 on failure.
- */
--int of_modalias_node(struct device_node *node, char *modalias, int len)
-+int of_alias_from_compatible(const struct device_node *node, char *alias, int len)
- {
- const char *compatible, *p;
- int cplen;
-@@ -1180,10 +1184,10 @@ int of_modalias_node(struct device_node
- if (!compatible || strlen(compatible) > cplen)
- return -ENODEV;
- p = strchr(compatible, ',');
-- strlcpy(modalias, p ? p + 1 : compatible, len);
-+ strlcpy(alias, p ? p + 1 : compatible, len);
- return 0;
- }
--EXPORT_SYMBOL_GPL(of_modalias_node);
-+EXPORT_SYMBOL_GPL(of_alias_from_compatible);
-
- /**
- * of_find_node_by_phandle - Find a node given a phandle
---- a/drivers/spi/spi.c
-+++ b/drivers/spi/spi.c
-@@ -2140,8 +2140,8 @@ of_register_spi_device(struct spi_contro
- }
-
- /* Select device driver */
-- rc = of_modalias_node(nc, spi->modalias,
-- sizeof(spi->modalias));
-+ rc = of_alias_from_compatible(nc, spi->modalias,
-+ sizeof(spi->modalias));
- if (rc < 0) {
- dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc);
- goto err_out;
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -361,7 +361,8 @@ extern int of_n_addr_cells(struct device
- extern int of_n_size_cells(struct device_node *np);
- extern const struct of_device_id *of_match_node(
- const struct of_device_id *matches, const struct device_node *node);
--extern int of_modalias_node(struct device_node *node, char *modalias, int len);
-+extern int of_alias_from_compatible(const struct device_node *node, char *alias,
-+ int len);
- extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args);
- extern int __of_parse_phandle_with_args(const struct device_node *np,
- const char *list_name, const char *cells_name, int cell_count,
diff --git a/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch
deleted file mode 100644
index b4554b2eca..0000000000
--- a/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From bd7a7ed774afd1a4174df34227626c95573be517 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:17 +0100
-Subject: [PATCH] of: Move of_modalias() to module.c
-
-Create a specific .c file for OF related module handling.
-Move of_modalias() inside as a first step.
-
-The helper is exposed through of.h even though it is only used by core
-files because the users from device.c will soon be split into an OF-only
-helper in module.c as well as a device-oriented inline helper in
-of_device.h. Putting this helper in of_private.h would require to
-include of_private.h from of_device.h, which is not acceptable.
-
-Suggested-by: Rob Herring <robh+dt@kernel.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/Makefile | 2 +-
- drivers/of/device.c | 37 -------------------------------------
- drivers/of/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
- include/linux/of.h | 9 +++++++++
- 4 files changed, 54 insertions(+), 38 deletions(-)
- create mode 100644 drivers/of/module.c
-
---- a/drivers/of/Makefile
-+++ b/drivers/of/Makefile
-@@ -1,5 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
--obj-y = base.o device.o platform.o property.o
-+obj-y = base.o device.o module.o platform.o property.o
- obj-$(CONFIG_OF_KOBJ) += kobj.o
- obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
- obj-$(CONFIG_OF_FLATTREE) += fdt.o
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -1,5 +1,4 @@
- // SPDX-License-Identifier: GPL-2.0
--#include <linux/string.h>
- #include <linux/kernel.h>
- #include <linux/of.h>
- #include <linux/of_device.h>
-@@ -241,42 +240,6 @@ const void *of_device_get_match_data(con
- }
- EXPORT_SYMBOL(of_device_get_match_data);
-
--static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
--{
-- const char *compat;
-- char *c;
-- struct property *p;
-- ssize_t csize;
-- ssize_t tsize;
--
-- /* Name & Type */
-- /* %p eats all alphanum characters, so %c must be used here */
-- csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
-- of_node_get_device_type(np));
-- tsize = csize;
-- len -= csize;
-- if (str)
-- str += csize;
--
-- of_property_for_each_string(np, "compatible", p, compat) {
-- csize = strlen(compat) + 1;
-- tsize += csize;
-- if (csize > len)
-- continue;
--
-- csize = snprintf(str, len, "C%s", compat);
-- for (c = str; c; ) {
-- c = strchr(c, ' ');
-- if (c)
-- *c++ = '_';
-- }
-- len -= csize;
-- str += csize;
-- }
--
-- return tsize;
--}
--
- int of_device_request_module(struct device *dev)
- {
- char *str;
---- /dev/null
-+++ b/drivers/of/module.c
-@@ -0,0 +1,44 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Linux kernel module helpers.
-+ */
-+
-+#include <linux/of.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+
-+ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
-+{
-+ const char *compat;
-+ char *c;
-+ struct property *p;
-+ ssize_t csize;
-+ ssize_t tsize;
-+
-+ /* Name & Type */
-+ /* %p eats all alphanum characters, so %c must be used here */
-+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
-+ of_node_get_device_type(np));
-+ tsize = csize;
-+ len -= csize;
-+ if (str)
-+ str += csize;
-+
-+ of_property_for_each_string(np, "compatible", p, compat) {
-+ csize = strlen(compat) + 1;
-+ tsize += csize;
-+ if (csize > len)
-+ continue;
-+
-+ csize = snprintf(str, len, "C%s", compat);
-+ for (c = str; c; ) {
-+ c = strchr(c, ' ');
-+ if (c)
-+ *c++ = '_';
-+ }
-+ len -= csize;
-+ str += csize;
-+ }
-+
-+ return tsize;
-+}
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -373,6 +373,9 @@ extern int of_parse_phandle_with_args_ma
- extern int of_count_phandle_with_args(const struct device_node *np,
- const char *list_name, const char *cells_name);
-
-+/* module functions */
-+extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len);
-+
- /* phandle iterator functions */
- extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
- const struct device_node *np,
-@@ -735,6 +738,12 @@ static inline int of_count_phandle_with_
- return -ENOSYS;
- }
-
-+static inline ssize_t of_modalias(const struct device_node *np, char *str,
-+ ssize_t len)
-+{
-+ return -ENODEV;
-+}
-+
- static inline int of_phandle_iterator_init(struct of_phandle_iterator *it,
- const struct device_node *np,
- const char *list_name,
diff --git a/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch
deleted file mode 100644
index ad42039e11..0000000000
--- a/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From e6506f06d5e82765666902ccf9e9162f3e31d518 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:18 +0100
-Subject: [PATCH] of: Move the request module helper logic to module.c
-
-Depending on device.c for pure OF handling is considered
-backwards. Let's extract the content of of_device_request_module() to
-have the real logic under module.c.
-
-The next step will be to convert users of of_device_request_module() to
-use the new helper.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-11-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 25 ++-----------------------
- drivers/of/module.c | 30 ++++++++++++++++++++++++++++++
- include/linux/of.h | 6 ++++++
- 3 files changed, 38 insertions(+), 23 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -8,7 +8,6 @@
- #include <linux/dma-direct.h> /* for bus_dma_region */
- #include <linux/dma-map-ops.h>
- #include <linux/init.h>
--#include <linux/module.h>
- #include <linux/mod_devicetable.h>
- #include <linux/slab.h>
- #include <linux/platform_device.h>
-@@ -242,30 +241,10 @@ EXPORT_SYMBOL(of_device_get_match_data);
-
- int of_device_request_module(struct device *dev)
- {
-- char *str;
-- ssize_t size;
-- int ret;
--
-- if (!dev || !dev->of_node)
-+ if (!dev)
- return -ENODEV;
-
-- size = of_modalias(dev->of_node, NULL, 0);
-- if (size < 0)
-- return size;
--
-- /* Reserve an additional byte for the trailing '\0' */
-- size++;
--
-- str = kmalloc(size, GFP_KERNEL);
-- if (!str)
-- return -ENOMEM;
--
-- of_modalias(dev->of_node, str, size);
-- str[size - 1] = '\0';
-- ret = request_module(str);
-- kfree(str);
--
-- return ret;
-+ return of_request_module(dev->of_node);
- }
- EXPORT_SYMBOL_GPL(of_device_request_module);
-
---- a/drivers/of/module.c
-+++ b/drivers/of/module.c
-@@ -4,6 +4,7 @@
- */
-
- #include <linux/of.h>
-+#include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/string.h>
-
-@@ -42,3 +43,32 @@ ssize_t of_modalias(const struct device_
-
- return tsize;
- }
-+
-+int of_request_module(const struct device_node *np)
-+{
-+ char *str;
-+ ssize_t size;
-+ int ret;
-+
-+ if (!np)
-+ return -ENODEV;
-+
-+ size = of_modalias(np, NULL, 0);
-+ if (size < 0)
-+ return size;
-+
-+ /* Reserve an additional byte for the trailing '\0' */
-+ size++;
-+
-+ str = kmalloc(size, GFP_KERNEL);
-+ if (!str)
-+ return -ENOMEM;
-+
-+ of_modalias(np, str, size);
-+ str[size - 1] = '\0';
-+ ret = request_module(str);
-+ kfree(str);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(of_request_module);
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -375,6 +375,7 @@ extern int of_count_phandle_with_args(co
-
- /* module functions */
- extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len);
-+extern int of_request_module(const struct device_node *np);
-
- /* phandle iterator functions */
- extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
-@@ -743,6 +744,11 @@ static inline ssize_t of_modalias(const
- {
- return -ENODEV;
- }
-+
-+static inline int of_request_module(const struct device_node *np)
-+{
-+ return -ENODEV;
-+}
-
- static inline int of_phandle_iterator_init(struct of_phandle_iterator *it,
- const struct device_node *np,
diff --git a/target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch b/target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch
deleted file mode 100644
index 1365834563..0000000000
--- a/target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 4d70c74659d9746502b23d055dba03d1d28ec388 Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Wed, 30 Nov 2022 15:48:35 +0200
-Subject: [PATCH] i915: Move list_count() to list.h as list_count_nodes() for
- broader use
-
-Some of the existing users, and definitely will be new ones, want to
-count existing nodes in the list. Provide a generic API for that by
-moving code from i915 to list.h.
-
-Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
-Acked-by: Jani Nikula <jani.nikula@intel.com>
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Link: https://lore.kernel.org/r/20221130134838.23805-1-andriy.shevchenko@linux.intel.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 15 ++-------------
- include/linux/list.h | 15 +++++++++++++++
- 2 files changed, 17 insertions(+), 13 deletions(-)
-
---- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
-+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
-@@ -1639,17 +1639,6 @@ static void print_request_ring(struct dr
- }
- }
-
--static unsigned long list_count(struct list_head *list)
--{
-- struct list_head *pos;
-- unsigned long count = 0;
--
-- list_for_each(pos, list)
-- count++;
--
-- return count;
--}
--
- static unsigned long read_ul(void *p, size_t x)
- {
- return *(unsigned long *)(p + x);
-@@ -1824,8 +1813,8 @@ void intel_engine_dump(struct intel_engi
- spin_lock_irqsave(&engine->sched_engine->lock, flags);
- engine_dump_active_requests(engine, m);
-
-- drm_printf(m, "\tOn hold?: %lu\n",
-- list_count(&engine->sched_engine->hold));
-+ drm_printf(m, "\tOn hold?: %zu\n",
-+ list_count_nodes(&engine->sched_engine->hold));
- spin_unlock_irqrestore(&engine->sched_engine->lock, flags);
-
- drm_printf(m, "\tMMIO base: 0x%08x\n", engine->mmio_base);
---- a/include/linux/list.h
-+++ b/include/linux/list.h
-@@ -628,6 +628,21 @@ static inline void list_splice_tail_init
- pos = n, n = pos->prev)
-
- /**
-+ * list_count_nodes - count nodes in the list
-+ * @head: the head for your list.
-+ */
-+static inline size_t list_count_nodes(struct list_head *head)
-+{
-+ struct list_head *pos;
-+ size_t count = 0;
-+
-+ list_for_each(pos, head)
-+ count++;
-+
-+ return count;
-+}
-+
-+/**
- * list_entry_is_head - test if the entry points to the head of the list
- * @pos: the type * to cursor
- * @head: the head for your list.
diff --git a/target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch b/target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch
deleted file mode 100644
index 99ebe06438..0000000000
--- a/target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From a01633cd867b8ddf2d8321fe575dc3c54e037b09 Mon Sep 17 00:00:00 2001
-From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Date: Fri, 29 Jul 2022 16:03:46 +0200
-Subject: leds: turris-omnia: convert to use dev_groups
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The driver core supports the ability to handle the creation and removal
-of device-specific sysfs files in a race-free manner. Take advantage of
-that by converting this driver to use this by moving the sysfs
-attributes into a group and assigning the dev_groups pointer to it.
-
-Cc: Pavel Machek <pavel@ucw.cz>
-Cc: linux-leds@vger.kernel.org
-Cc: linux-kernel@vger.kernel.org
-Reviewed-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Pavel Machek <pavel@ucw.cz>
----
- drivers/leds/leds-turris-omnia.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
-(limited to 'drivers/leds/leds-turris-omnia.c')
-
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -260,9 +260,6 @@ static int omnia_leds_probe(struct i2c_c
- led += ret;
- }
-
-- if (devm_device_add_groups(dev, omnia_led_controller_groups))
-- dev_warn(dev, "Could not add attribute group!\n");
--
- return 0;
- }
-
-@@ -304,6 +301,7 @@ static struct i2c_driver omnia_leds_driv
- .driver = {
- .name = "leds-turris-omnia",
- .of_match_table = of_omnia_leds_match,
-+ .dev_groups = omnia_led_controller_groups,
- },
- };
-
diff --git a/target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch b/target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch
deleted file mode 100644
index 835a5e8847..0000000000
--- a/target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 72a29725b6f2577fa447ca9059cdcd17100043b4 Mon Sep 17 00:00:00 2001
-From: Marek Behún <kabel@kernel.org>
-Date: Wed, 2 Aug 2023 18:07:45 +0200
-Subject: leds: turris-omnia: Use sysfs_emit() instead of sprintf()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use the dedicated sysfs_emit() function instead of sprintf() in sysfs
-attribute accessor brightness_show().
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230802160748.11208-4-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/leds-turris-omnia.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-(limited to 'drivers/leds/leds-turris-omnia.c')
-
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -194,7 +194,7 @@ static ssize_t brightness_show(struct de
- if (ret < 0)
- return ret;
-
-- return sprintf(buf, "%d\n", ret);
-+ return sysfs_emit(buf, "%d\n", ret);
- }
-
- static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
diff --git a/target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch b/target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch
deleted file mode 100644
index 3f7dd64841..0000000000
--- a/target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch
+++ /dev/null
@@ -1,207 +0,0 @@
-From 4d5ed2621c2437d40b8fe92bd0fd34b0b1870753 Mon Sep 17 00:00:00 2001
-From: Marek Behún <kabel@kernel.org>
-Date: Mon, 18 Sep 2023 18:11:02 +0200
-Subject: leds: turris-omnia: Make set_brightness() more efficient
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Implement caching of the LED color and state values that are sent to MCU
-in order to make the set_brightness() operation more efficient by
-avoiding I2C transactions which are not needed.
-
-On Turris Omnia's MCU, which acts as the RGB LED controller, each LED
-has a RGB color, and a ON/OFF state, which are configurable via I2C
-commands CMD_LED_COLOR and CMD_LED_STATE.
-
-The CMD_LED_COLOR command sends 5 bytes and the CMD_LED_STATE command 2
-bytes over the I2C bus, which operates at 100 kHz. With I2C overhead
-this allows ~1670 color changing commands and ~3200 state changing
-commands per second (or around 1000 color + state changes per second).
-This may seem more than enough, but the issue is that the I2C bus is
-shared with another peripheral, the MCU. The MCU exposes an interrupt
-interface, and it can trigger hundreds of interrupts per second. Each
-time, we need to read the interrupt state register over this I2C bus.
-Whenever we are sending a LED color/state changing command, the
-interrupt reading is waiting.
-
-Currently, every time LED brightness or LED multi intensity is changed,
-we send a CMD_LED_STATE command, and if the computed color (brightness
-adjusted multi_intensity) is non-zero, we also send a CMD_LED_COLOR
-command.
-
-Consider for example the situation when we have a netdev trigger enabled
-for a LED. The netdev trigger does not change the LED color, only the
-brightness (either to 0 or to currently configured brightness), and so
-there is no need to send the CMD_LED_COLOR command. But each change of
-brightness to 0 sends one CMD_LED_STATE command, and each change of
-brightness to max_brightness sends one CMD_LED_STATE command and one
-CMD_LED_COLOR command:
- set_brightness(0) -> CMD_LED_STATE
- set_brightness(255) -> CMD_LED_STATE + CMD_LED_COLOR
- (unnecessary)
-
-We can avoid the unnecessary I2C transactions if we cache the values of
-state and color that are sent to the controller. If the color does not
-change from the one previously sent, there is no need to do the
-CMD_LED_COLOR I2C transaction, and if the state does not change, there
-is no need to do the CMD_LED_STATE transaction.
-
-Because we need to make sure that our cached values are consistent with
-the controller state, add explicit setting of the LED color to white at
-probe time (this is the default setting when MCU resets, but does not
-necessarily need to be the case, for example if U-Boot played with the
-LED colors).
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230918161104.20860-3-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/leds-turris-omnia.c | 96 ++++++++++++++++++++++++++++++++--------
- 1 file changed, 78 insertions(+), 18 deletions(-)
-
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -30,6 +30,8 @@
- struct omnia_led {
- struct led_classdev_mc mc_cdev;
- struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS];
-+ u8 cached_channels[OMNIA_LED_NUM_CHANNELS];
-+ bool on;
- int reg;
- };
-
-@@ -72,36 +74,82 @@ static int omnia_cmd_read_u8(const struc
- return -EIO;
- }
-
-+static int omnia_led_send_color_cmd(const struct i2c_client *client,
-+ struct omnia_led *led)
-+{
-+ char cmd[5];
-+ int ret;
-+
-+ cmd[0] = CMD_LED_COLOR;
-+ cmd[1] = led->reg;
-+ cmd[2] = led->subled_info[0].brightness;
-+ cmd[3] = led->subled_info[1].brightness;
-+ cmd[4] = led->subled_info[2].brightness;
-+
-+ /* Send the color change command */
-+ ret = i2c_master_send(client, cmd, 5);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Cache the RGB channel brightnesses */
-+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i)
-+ led->cached_channels[i] = led->subled_info[i].brightness;
-+
-+ return 0;
-+}
-+
-+/* Determine if the computed RGB channels are different from the cached ones */
-+static bool omnia_led_channels_changed(struct omnia_led *led)
-+{
-+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i)
-+ if (led->subled_info[i].brightness != led->cached_channels[i])
-+ return true;
-+
-+ return false;
-+}
-+
- static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
- enum led_brightness brightness)
- {
- struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
- struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
- struct omnia_led *led = to_omnia_led(mc_cdev);
-- u8 buf[5], state;
-- int ret;
-+ int err = 0;
-
- mutex_lock(&leds->lock);
-
-- led_mc_calc_color_components(&led->mc_cdev, brightness);
-+ /*
-+ * Only recalculate RGB brightnesses from intensities if brightness is
-+ * non-zero. Otherwise we won't be using them and we can save ourselves
-+ * some software divisions (Omnia's CPU does not implement the division
-+ * instruction).
-+ */
-+ if (brightness) {
-+ led_mc_calc_color_components(mc_cdev, brightness);
-+
-+ /*
-+ * Send color command only if brightness is non-zero and the RGB
-+ * channel brightnesses changed.
-+ */
-+ if (omnia_led_channels_changed(led))
-+ err = omnia_led_send_color_cmd(leds->client, led);
-+ }
-
-- buf[0] = CMD_LED_COLOR;
-- buf[1] = led->reg;
-- buf[2] = mc_cdev->subled_info[0].brightness;
-- buf[3] = mc_cdev->subled_info[1].brightness;
-- buf[4] = mc_cdev->subled_info[2].brightness;
--
-- state = CMD_LED_STATE_LED(led->reg);
-- if (buf[2] || buf[3] || buf[4])
-- state |= CMD_LED_STATE_ON;
--
-- ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
-- if (ret >= 0 && (state & CMD_LED_STATE_ON))
-- ret = i2c_master_send(leds->client, buf, 5);
-+ /* Send on/off state change only if (bool)brightness changed */
-+ if (!err && !brightness != !led->on) {
-+ u8 state = CMD_LED_STATE_LED(led->reg);
-+
-+ if (brightness)
-+ state |= CMD_LED_STATE_ON;
-+
-+ err = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
-+ if (!err)
-+ led->on = !!brightness;
-+ }
-
- mutex_unlock(&leds->lock);
-
-- return ret;
-+ return err;
- }
-
- static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
-@@ -129,11 +177,15 @@ static int omnia_led_register(struct i2c
- }
-
- led->subled_info[0].color_index = LED_COLOR_ID_RED;
-- led->subled_info[0].channel = 0;
- led->subled_info[1].color_index = LED_COLOR_ID_GREEN;
-- led->subled_info[1].channel = 1;
- led->subled_info[2].color_index = LED_COLOR_ID_BLUE;
-- led->subled_info[2].channel = 2;
-+
-+ /* Initial color is white */
-+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) {
-+ led->subled_info[i].intensity = 255;
-+ led->subled_info[i].brightness = 255;
-+ led->subled_info[i].channel = i;
-+ }
-
- led->mc_cdev.subled_info = led->subled_info;
- led->mc_cdev.num_colors = OMNIA_LED_NUM_CHANNELS;
-@@ -162,6 +214,14 @@ static int omnia_led_register(struct i2c
- return ret;
- }
-
-+ /* Set initial color and cache it */
-+ ret = omnia_led_send_color_cmd(client, led);
-+ if (ret < 0) {
-+ dev_err(dev, "Cannot set LED %pOF initial color: %i\n", np,
-+ ret);
-+ return ret;
-+ }
-+
- ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev,
- &init_data);
- if (ret < 0) {
diff --git a/target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch b/target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch
deleted file mode 100644
index 7f6bac37dd..0000000000
--- a/target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From aaf38273cf766d88296f4aa3f2e4e3c0d399a4a2 Mon Sep 17 00:00:00 2001
-From: Marek Behún <kabel@kernel.org>
-Date: Mon, 18 Sep 2023 18:11:03 +0200
-Subject: leds: turris-omnia: Support HW controlled mode via private trigger
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support for enabling MCU controlled mode of the Turris Omnia LEDs
-via a LED private trigger called "omnia-mcu". Recall that private LED
-triggers will only be listed in the sysfs trigger file for LEDs that
-support them (currently there is no user of this mechanism).
-
-When in MCU controlled mode, the user can still set LED color, but the
-blinking is done by MCU, which does different things for different LEDs:
-- WAN LED is blinked according to the LED[0] pin of the WAN PHY
-- LAN LEDs are blinked according to the LED[0] output of the
- corresponding port of the LAN switch
-- PCIe LEDs are blinked according to the logical OR of the MiniPCIe port
- LED pins
-
-In the future I want to make the netdev trigger to transparently offload
-the blinking to the HW if user sets compatible settings for the netdev
-trigger (for LEDs associated with network devices).
-There was some work on this already, and hopefully we will be able to
-complete it sometime, but for now there are still multiple blockers for
-this, and even if there weren't, we still would not be able to configure
-HW controlled mode for the LEDs associated with MiniPCIe ports.
-
-In the meantime let's support HW controlled mode via the private LED
-trigger mechanism. If, in the future, we manage to complete the netdev
-trigger offloading, we can still keep this private trigger for backwards
-compatibility, if needed.
-
-We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps
-control until the user first wants to take over it. If a different
-default trigger is specified in device-tree via the
-'linux,default-trigger' property, LED class will overwrite
-cdev->default_trigger, and so the DT property will be respected.
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230918161104.20860-4-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/Kconfig | 1 +
- drivers/leds/leds-turris-omnia.c | 98 ++++++++++++++++++++++++++++++++++++----
- 2 files changed, 91 insertions(+), 8 deletions(-)
-
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -164,6 +164,7 @@ config LEDS_TURRIS_OMNIA
- depends on I2C
- depends on MACH_ARMADA_38X || COMPILE_TEST
- depends on OF
-+ select LEDS_TRIGGERS
- help
- This option enables basic support for the LEDs found on the front
- side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -31,7 +31,7 @@ struct omnia_led {
- struct led_classdev_mc mc_cdev;
- struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS];
- u8 cached_channels[OMNIA_LED_NUM_CHANNELS];
-- bool on;
-+ bool on, hwtrig;
- int reg;
- };
-
-@@ -120,12 +120,14 @@ static int omnia_led_brightness_set_bloc
-
- /*
- * Only recalculate RGB brightnesses from intensities if brightness is
-- * non-zero. Otherwise we won't be using them and we can save ourselves
-- * some software divisions (Omnia's CPU does not implement the division
-- * instruction).
-+ * non-zero (if it is zero and the LED is in HW blinking mode, we use
-+ * max_brightness as brightness). Otherwise we won't be using them and
-+ * we can save ourselves some software divisions (Omnia's CPU does not
-+ * implement the division instruction).
- */
-- if (brightness) {
-- led_mc_calc_color_components(mc_cdev, brightness);
-+ if (brightness || led->hwtrig) {
-+ led_mc_calc_color_components(mc_cdev, brightness ?:
-+ cdev->max_brightness);
-
- /*
- * Send color command only if brightness is non-zero and the RGB
-@@ -135,8 +137,11 @@ static int omnia_led_brightness_set_bloc
- err = omnia_led_send_color_cmd(leds->client, led);
- }
-
-- /* Send on/off state change only if (bool)brightness changed */
-- if (!err && !brightness != !led->on) {
-+ /*
-+ * Send on/off state change only if (bool)brightness changed and the LED
-+ * is not being blinked by HW.
-+ */
-+ if (!err && !led->hwtrig && !brightness != !led->on) {
- u8 state = CMD_LED_STATE_LED(led->reg);
-
- if (brightness)
-@@ -152,6 +157,71 @@ static int omnia_led_brightness_set_bloc
- return err;
- }
-
-+static struct led_hw_trigger_type omnia_hw_trigger_type;
-+
-+static int omnia_hwtrig_activate(struct led_classdev *cdev)
-+{
-+ struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
-+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
-+ struct omnia_led *led = to_omnia_led(mc_cdev);
-+ int err = 0;
-+
-+ mutex_lock(&leds->lock);
-+
-+ if (!led->on) {
-+ /*
-+ * If the LED is off (brightness was set to 0), the last
-+ * configured color was not necessarily sent to the MCU.
-+ * Recompute with max_brightness and send if needed.
-+ */
-+ led_mc_calc_color_components(mc_cdev, cdev->max_brightness);
-+
-+ if (omnia_led_channels_changed(led))
-+ err = omnia_led_send_color_cmd(leds->client, led);
-+ }
-+
-+ if (!err) {
-+ /* Put the LED into MCU controlled mode */
-+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
-+ CMD_LED_MODE_LED(led->reg));
-+ if (!err)
-+ led->hwtrig = true;
-+ }
-+
-+ mutex_unlock(&leds->lock);
-+
-+ return err;
-+}
-+
-+static void omnia_hwtrig_deactivate(struct led_classdev *cdev)
-+{
-+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
-+ struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
-+ int err;
-+
-+ mutex_lock(&leds->lock);
-+
-+ led->hwtrig = false;
-+
-+ /* Put the LED into software mode */
-+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
-+ CMD_LED_MODE_LED(led->reg) |
-+ CMD_LED_MODE_USER);
-+
-+ mutex_unlock(&leds->lock);
-+
-+ if (err < 0)
-+ dev_err(cdev->dev, "Cannot put LED to software mode: %i\n",
-+ err);
-+}
-+
-+static struct led_trigger omnia_hw_trigger = {
-+ .name = "omnia-mcu",
-+ .activate = omnia_hwtrig_activate,
-+ .deactivate = omnia_hwtrig_deactivate,
-+ .trigger_type = &omnia_hw_trigger_type,
-+};
-+
- static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
- struct device_node *np)
- {
-@@ -195,6 +265,12 @@ static int omnia_led_register(struct i2c
- cdev = &led->mc_cdev.led_cdev;
- cdev->max_brightness = 255;
- cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
-+ cdev->trigger_type = &omnia_hw_trigger_type;
-+ /*
-+ * Use the omnia-mcu trigger as the default trigger. It may be rewritten
-+ * by LED class from the linux,default-trigger property.
-+ */
-+ cdev->default_trigger = omnia_hw_trigger.name;
-
- /* put the LED into software mode */
- ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
-@@ -309,6 +385,12 @@ static int omnia_leds_probe(struct i2c_c
-
- mutex_init(&leds->lock);
-
-+ ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
-+ if (ret < 0) {
-+ dev_err(dev, "Cannot register private LED trigger: %d\n", ret);
-+ return ret;
-+ }
-+
- led = &leds->leds[0];
- for_each_available_child_of_node(np, child) {
- ret = omnia_led_register(client, led, child);
diff --git a/target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch b/target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch
deleted file mode 100644
index 3bda4a9cef..0000000000
--- a/target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From 00125699bb35ef58fffa8425e32a44a7af82cd28 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 18 Sep 2023 18:11:04 +0200
-Subject: [PATCH 07/17] leds: turris-omnia: Add support for enabling/disabling
- HW gamma correction
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-If the MCU on Turris Omnia is running newer firmware versions, the LED
-controller supports RGB gamma correction (and enables it by default for
-newer boards).
-
-Determine whether the gamma correction setting feature is supported and
-add the ability to set it via sysfs attribute file.
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230918161104.20860-5-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- .../sysfs-class-led-driver-turris-omnia | 14 ++
- drivers/leds/leds-turris-omnia.c | 137 +++++++++++++++---
- 2 files changed, 134 insertions(+), 17 deletions(-)
-
---- a/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia
-+++ b/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia
-@@ -12,3 +12,17 @@ Description: (RW) On the front panel of
- able to change this setting from software.
-
- Format: %i
-+
-+What: /sys/class/leds/<led>/device/gamma_correction
-+Date: August 2023
-+KernelVersion: 6.6
-+Contact: Marek Behún <kabel@kernel.org>
-+Description: (RW) Newer versions of the microcontroller firmware of the
-+ Turris Omnia router support gamma correction for the RGB LEDs.
-+ This feature can be enabled/disabled by writing to this file.
-+
-+ If the feature is not supported because the MCU firmware is too
-+ old, the file always reads as 0, and writing to the file results
-+ in the EOPNOTSUPP error.
-+
-+ Format: %i
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -15,17 +15,30 @@
- #define OMNIA_BOARD_LEDS 12
- #define OMNIA_LED_NUM_CHANNELS 3
-
--#define CMD_LED_MODE 3
--#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
--#define CMD_LED_MODE_USER 0x10
--
--#define CMD_LED_STATE 4
--#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
--#define CMD_LED_STATE_ON 0x10
--
--#define CMD_LED_COLOR 5
--#define CMD_LED_SET_BRIGHTNESS 7
--#define CMD_LED_GET_BRIGHTNESS 8
-+/* MCU controller commands at I2C address 0x2a */
-+#define OMNIA_MCU_I2C_ADDR 0x2a
-+
-+#define CMD_GET_STATUS_WORD 0x01
-+#define STS_FEATURES_SUPPORTED BIT(2)
-+
-+#define CMD_GET_FEATURES 0x10
-+#define FEAT_LED_GAMMA_CORRECTION BIT(5)
-+
-+/* LED controller commands at I2C address 0x2b */
-+#define CMD_LED_MODE 0x03
-+#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
-+#define CMD_LED_MODE_USER 0x10
-+
-+#define CMD_LED_STATE 0x04
-+#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
-+#define CMD_LED_STATE_ON 0x10
-+
-+#define CMD_LED_COLOR 0x05
-+#define CMD_LED_SET_BRIGHTNESS 0x07
-+#define CMD_LED_GET_BRIGHTNESS 0x08
-+
-+#define CMD_SET_GAMMA_CORRECTION 0x30
-+#define CMD_GET_GAMMA_CORRECTION 0x31
-
- struct omnia_led {
- struct led_classdev_mc mc_cdev;
-@@ -40,6 +53,7 @@ struct omnia_led {
- struct omnia_leds {
- struct i2c_client *client;
- struct mutex lock;
-+ bool has_gamma_correction;
- struct omnia_led leds[];
- };
-
-@@ -50,30 +64,42 @@ static int omnia_cmd_write_u8(const stru
- return i2c_master_send(client, buf, sizeof(buf));
- }
-
--static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
-+static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
-+ void *reply, size_t len)
- {
- struct i2c_msg msgs[2];
-- u8 reply;
- int ret;
-
-- msgs[0].addr = client->addr;
-+ msgs[0].addr = addr;
- msgs[0].flags = 0;
- msgs[0].len = 1;
- msgs[0].buf = &cmd;
-- msgs[1].addr = client->addr;
-+ msgs[1].addr = addr;
- msgs[1].flags = I2C_M_RD;
-- msgs[1].len = 1;
-- msgs[1].buf = &reply;
-+ msgs[1].len = len;
-+ msgs[1].buf = reply;
-
-- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-+ ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
- if (likely(ret == ARRAY_SIZE(msgs)))
-- return reply;
-+ return len;
- else if (ret < 0)
- return ret;
- else
- return -EIO;
- }
-
-+static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
-+{
-+ u8 reply;
-+ int ret;
-+
-+ ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
-+ if (ret < 0)
-+ return ret;
-+
-+ return reply;
-+}
-+
- static int omnia_led_send_color_cmd(const struct i2c_client *client,
- struct omnia_led *led)
- {
-@@ -352,12 +378,74 @@ static ssize_t brightness_store(struct d
- }
- static DEVICE_ATTR_RW(brightness);
-
-+static ssize_t gamma_correction_show(struct device *dev,
-+ struct device_attribute *a, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct omnia_leds *leds = i2c_get_clientdata(client);
-+ int ret;
-+
-+ if (leds->has_gamma_correction) {
-+ ret = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ ret = 0;
-+ }
-+
-+ return sysfs_emit(buf, "%d\n", !!ret);
-+}
-+
-+static ssize_t gamma_correction_store(struct device *dev,
-+ struct device_attribute *a,
-+ const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct omnia_leds *leds = i2c_get_clientdata(client);
-+ bool val;
-+ int ret;
-+
-+ if (!leds->has_gamma_correction)
-+ return -EOPNOTSUPP;
-+
-+ if (kstrtobool(buf, &val) < 0)
-+ return -EINVAL;
-+
-+ ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
-+
-+ return ret < 0 ? ret : count;
-+}
-+static DEVICE_ATTR_RW(gamma_correction);
-+
- static struct attribute *omnia_led_controller_attrs[] = {
- &dev_attr_brightness.attr,
-+ &dev_attr_gamma_correction.attr,
- NULL,
- };
- ATTRIBUTE_GROUPS(omnia_led_controller);
-
-+static int omnia_mcu_get_features(const struct i2c_client *client)
-+{
-+ u16 reply;
-+ int err;
-+
-+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
-+ CMD_GET_STATUS_WORD, &reply, sizeof(reply));
-+ if (err < 0)
-+ return err;
-+
-+ /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
-+ if (!(le16_to_cpu(reply) & STS_FEATURES_SUPPORTED))
-+ return 0;
-+
-+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
-+ CMD_GET_FEATURES, &reply, sizeof(reply));
-+ if (err < 0)
-+ return err;
-+
-+ return le16_to_cpu(reply);
-+}
-+
- static int omnia_leds_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
-@@ -383,6 +471,21 @@ static int omnia_leds_probe(struct i2c_c
- leds->client = client;
- i2c_set_clientdata(client, leds);
-
-+ ret = omnia_mcu_get_features(client);
-+ if (ret < 0) {
-+ dev_err(dev, "Cannot determine MCU supported features: %d\n",
-+ ret);
-+ return ret;
-+ }
-+
-+ leds->has_gamma_correction = ret & FEAT_LED_GAMMA_CORRECTION;
-+ if (!leds->has_gamma_correction) {
-+ dev_info(dev,
-+ "Your board's MCU firmware does not support the LED gamma correction feature.\n");
-+ dev_info(dev,
-+ "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
-+ }
-+
- mutex_init(&leds->lock);
-
- ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
diff --git a/target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch b/target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch
deleted file mode 100644
index ec6171ec67..0000000000
--- a/target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From 33f339b70f020273ea40fb3c5d7b65697446bd6c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 16 Oct 2023 15:28:06 +0200
-Subject: [PATCH 08/17] leds: turris-omnia: Fix brightness setting and trigger
- activating
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-I have improperly refactored commits
- 4d5ed2621c24 ("leds: turris-omnia: Make set_brightness() more efficient")
-and
- aaf38273cf76 ("leds: turris-omnia: Support HW controlled mode via private trigger")
-after Lee requested a change in API semantics of the new functions I
-introduced in commit
- 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls").
-
-Before the change, the function omnia_cmd_write_u8() returned 0 on
-success, and afterwards it returned a positive value (number of bytes
-written). The latter version was applied, but the following commits did
-not properly account for this change.
-
-This results in non-functional LED's .brightness_set_blocking() and
-trigger's .activate() methods.
-
-The main reasoning behind the semantics change was that read/write
-methods should return the number of read/written bytes on success.
-It was pointed to me [1] that this is not always true (for example the
-regmap API does not do so), and since the driver never uses this number
-of read/written bytes information, I decided to fix this issue by
-changing the functions to the original semantics (return 0 on success).
-
-[1] https://lore.kernel.org/linux-gpio/ZQnn+Gi0xVlsGCYA@smile.fi.intel.com/
-
-Fixes: 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls")
-Signed-off-by: Marek Behún <kabel@kernel.org>
----
- drivers/leds/leds-turris-omnia.c | 37 +++++++++++++++++---------------
- 1 file changed, 20 insertions(+), 17 deletions(-)
-
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -60,8 +60,11 @@ struct omnia_leds {
- static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val)
- {
- u8 buf[2] = { cmd, val };
-+ int ret;
-+
-+ ret = i2c_master_send(client, buf, sizeof(buf));
-
-- return i2c_master_send(client, buf, sizeof(buf));
-+ return ret < 0 ? ret : 0;
- }
-
- static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
-@@ -81,7 +84,7 @@ static int omnia_cmd_read_raw(struct i2c
-
- ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
- if (likely(ret == ARRAY_SIZE(msgs)))
-- return len;
-+ return 0;
- else if (ret < 0)
- return ret;
- else
-@@ -91,11 +94,11 @@ static int omnia_cmd_read_raw(struct i2c
- static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
- {
- u8 reply;
-- int ret;
-+ int err;
-
-- ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
-- if (ret < 0)
-- return ret;
-+ err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
-+ if (err)
-+ return err;
-
- return reply;
- }
-@@ -236,7 +239,7 @@ static void omnia_hwtrig_deactivate(stru
-
- mutex_unlock(&leds->lock);
-
-- if (err < 0)
-+ if (err)
- dev_err(cdev->dev, "Cannot put LED to software mode: %i\n",
- err);
- }
-@@ -302,7 +305,7 @@ static int omnia_led_register(struct i2c
- ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
- CMD_LED_MODE_LED(led->reg) |
- CMD_LED_MODE_USER);
-- if (ret < 0) {
-+ if (ret) {
- dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np,
- ret);
- return ret;
-@@ -311,7 +314,7 @@ static int omnia_led_register(struct i2c
- /* disable the LED */
- ret = omnia_cmd_write_u8(client, CMD_LED_STATE,
- CMD_LED_STATE_LED(led->reg));
-- if (ret < 0) {
-+ if (ret) {
- dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret);
- return ret;
- }
-@@ -364,7 +367,7 @@ static ssize_t brightness_store(struct d
- {
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long brightness;
-- int ret;
-+ int err;
-
- if (kstrtoul(buf, 10, &brightness))
- return -EINVAL;
-@@ -372,9 +375,9 @@ static ssize_t brightness_store(struct d
- if (brightness > 100)
- return -EINVAL;
-
-- ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
-+ err = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
-
-- return ret < 0 ? ret : count;
-+ return err ?: count;
- }
- static DEVICE_ATTR_RW(brightness);
-
-@@ -403,7 +406,7 @@ static ssize_t gamma_correction_store(st
- struct i2c_client *client = to_i2c_client(dev);
- struct omnia_leds *leds = i2c_get_clientdata(client);
- bool val;
-- int ret;
-+ int err;
-
- if (!leds->has_gamma_correction)
- return -EOPNOTSUPP;
-@@ -411,9 +414,9 @@ static ssize_t gamma_correction_store(st
- if (kstrtobool(buf, &val) < 0)
- return -EINVAL;
-
-- ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
-+ err = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
-
-- return ret < 0 ? ret : count;
-+ return err ?: count;
- }
- static DEVICE_ATTR_RW(gamma_correction);
-
-@@ -431,7 +434,7 @@ static int omnia_mcu_get_features(const
-
- err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
- CMD_GET_STATUS_WORD, &reply, sizeof(reply));
-- if (err < 0)
-+ if (err)
- return err;
-
- /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
-@@ -440,7 +443,7 @@ static int omnia_mcu_get_features(const
-
- err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
- CMD_GET_FEATURES, &reply, sizeof(reply));
-- if (err < 0)
-+ if (err)
- return err;
-
- return le16_to_cpu(reply);
diff --git a/target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch b/target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch
deleted file mode 100644
index c2a938c614..0000000000
--- a/target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 472d7b9e8141729ec1e3fe6821b88563f6379533 Mon Sep 17 00:00:00 2001
-From: Olliver Schinagl <oliver@schinagl.nl>
-Date: Tue, 30 Aug 2022 15:46:13 +0200
-Subject: [PATCH] dt-bindings: leds: Expand LED_COLOR_ID definitions
-
-In commit 853a78a7d6c7 (dt-bindings: leds: Add LED_COLOR_ID definitions,
-Sun Jun 9 20:19:04 2019 +0200) the most basic color definitions where
-added. However, there's a little more very common LED colors.
-
-While the documentation states 'add what is missing', engineers tend to
-be lazy and will just use what currently exists. So this patch will take
-(a) list from online retailers [0], [1], [2] and use the common LED colors from
-there, this being reasonable as this is what is currently available to purchase.
-
-Note, that LIME seems to be the modern take to 'Yellow-green' or
-'Yellowish-green' from some older datasheets.
-
-[0]: https://www.digikey.com/en/products/filter/led-lighting-color/125
-[1]: https://eu.mouser.com/c/optoelectronics/led-lighting/led-emitters/standard-leds-smd
-[2]: https://nl.farnell.com/en-NL/c/optoelectronics-displays/led-products/standard-single-colour-leds-under-75ma
-
-Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Acked-by: Alexander Dahl <ada@thorsis.com>
-Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
-Link: https://lore.kernel.org/r/20220830134613.1564059-1-oliver@schinagl.nl
-Signed-off-by: Rob Herring <robh@kernel.org>
----
- include/dt-bindings/leds/common.h | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -33,7 +33,12 @@
- #define LED_COLOR_ID_MULTI 8 /* For multicolor LEDs */
- #define LED_COLOR_ID_RGB 9 /* For multicolor LEDs that can do arbitrary color,
- so this would include RGBW and similar */
--#define LED_COLOR_ID_MAX 10
-+#define LED_COLOR_ID_PURPLE 10
-+#define LED_COLOR_ID_ORANGE 11
-+#define LED_COLOR_ID_PINK 12
-+#define LED_COLOR_ID_CYAN 13
-+#define LED_COLOR_ID_LIME 14
-+#define LED_COLOR_ID_MAX 15
-
- /* Standard LED functions */
- /* Keyboard LEDs, usually it would be input4::capslock etc. */
diff --git a/target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch b/target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch
deleted file mode 100644
index d097c1b0f4..0000000000
--- a/target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 7f38b70042fcaa49219045bd1a9a2836e27a58ac Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:27 +0000
-Subject: [PATCH] of: device: Export of_device_make_bus_id()
-
-This helper is really handy to create unique device names based on their
-device tree path, we may need it outside of the OF core (in the NVMEM
-subsystem) so let's export it. As this helper has nothing patform
-specific, let's move it to of/device.c instead of of/platform.c so we
-can add its prototype to of_device.h.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Acked-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 41 +++++++++++++++++++++++++++++++++++++++
- drivers/of/platform.c | 40 --------------------------------------
- include/linux/of_device.h | 6 ++++++
- 3 files changed, 47 insertions(+), 40 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -337,3 +337,38 @@ int of_device_uevent_modalias(struct dev
- return 0;
- }
- EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
-+
-+/**
-+ * of_device_make_bus_id - Use the device node data to assign a unique name
-+ * @dev: pointer to device structure that is linked to a device tree node
-+ *
-+ * This routine will first try using the translated bus address to
-+ * derive a unique name. If it cannot, then it will prepend names from
-+ * parent nodes until a unique name can be derived.
-+ */
-+void of_device_make_bus_id(struct device *dev)
-+{
-+ struct device_node *node = dev->of_node;
-+ const __be32 *reg;
-+ u64 addr;
-+
-+ /* Construct the name, using parent nodes if necessary to ensure uniqueness */
-+ while (node->parent) {
-+ /*
-+ * If the address can be translated, then that is as much
-+ * uniqueness as we need. Make it the first component and return
-+ */
-+ reg = of_get_property(node, "reg", NULL);
-+ if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
-+ dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn",
-+ addr, node, dev_name(dev));
-+ return;
-+ }
-+
-+ /* format arguments only used if dev_name() resolves to NULL */
-+ dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s",
-+ kbasename(node->full_name), dev_name(dev));
-+ node = node->parent;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(of_device_make_bus_id);
---- a/drivers/of/platform.c
-+++ b/drivers/of/platform.c
-@@ -64,40 +64,6 @@ EXPORT_SYMBOL(of_find_device_by_node);
- */
-
- /**
-- * of_device_make_bus_id - Use the device node data to assign a unique name
-- * @dev: pointer to device structure that is linked to a device tree node
-- *
-- * This routine will first try using the translated bus address to
-- * derive a unique name. If it cannot, then it will prepend names from
-- * parent nodes until a unique name can be derived.
-- */
--static void of_device_make_bus_id(struct device *dev)
--{
-- struct device_node *node = dev->of_node;
-- const __be32 *reg;
-- u64 addr;
--
-- /* Construct the name, using parent nodes if necessary to ensure uniqueness */
-- while (node->parent) {
-- /*
-- * If the address can be translated, then that is as much
-- * uniqueness as we need. Make it the first component and return
-- */
-- reg = of_get_property(node, "reg", NULL);
-- if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
-- dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn",
-- addr, node, dev_name(dev));
-- return;
-- }
--
-- /* format arguments only used if dev_name() resolves to NULL */
-- dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s",
-- kbasename(node->full_name), dev_name(dev));
-- node = node->parent;
-- }
--}
--
--/**
- * of_device_alloc - Allocate and initialize an of_device
- * @np: device node to assign to device
- * @bus_id: Name to assign to the device. May be null to use default name.
---- a/include/linux/of_device.h
-+++ b/include/linux/of_device.h
-@@ -56,6 +56,9 @@ static inline int of_dma_configure(struc
- {
- return of_dma_configure_id(dev, np, force_dma, NULL);
- }
-+
-+void of_device_make_bus_id(struct device *dev);
-+
- #else /* CONFIG_OF */
-
- static inline int of_driver_match_device(struct device *dev,
-@@ -113,6 +116,9 @@ static inline int of_dma_configure(struc
- {
- return 0;
- }
-+
-+static inline void of_device_make_bus_id(struct device *dev) {}
-+
- #endif /* CONFIG_OF */
-
- #endif /* _LINUX_OF_DEVICE_H */
diff --git a/target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch b/target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch
deleted file mode 100644
index b71df6fa57..0000000000
--- a/target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From a067943129b4ec6b835e02cfd5fbef01093c1471 Mon Sep 17 00:00:00 2001
-From: Ondrej Jirman <megi@xff.cz>
-Date: Sun, 8 Oct 2023 16:40:13 +0200
-Subject: [PATCH] leds: core: Add more colors from DT bindings to led_colors
-
-The colors are already part of DT bindings. Make sure the kernel is
-able to convert them to strings.
-
-Signed-off-by: Ondrej Jirman <megi@xff.cz>
-Link: https://lore.kernel.org/r/20231008144014.1180334-1-megi@xff.cz
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/led-core.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/leds/led-core.c
-+++ b/drivers/leds/led-core.c
-@@ -36,6 +36,11 @@ const char * const led_colors[LED_COLOR_
- [LED_COLOR_ID_IR] = "ir",
- [LED_COLOR_ID_MULTI] = "multicolor",
- [LED_COLOR_ID_RGB] = "rgb",
-+ [LED_COLOR_ID_PURPLE] = "purple",
-+ [LED_COLOR_ID_ORANGE] = "orange",
-+ [LED_COLOR_ID_PINK] = "pink",
-+ [LED_COLOR_ID_CYAN] = "cyan",
-+ [LED_COLOR_ID_LIME] = "lime",
- };
- EXPORT_SYMBOL_GPL(led_colors);
-
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch b/target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
deleted file mode 100644
index 2093fac8a1..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 4a1a40233b4a9fc159a5c7a27dc34c5c7bc5be55 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:28 +0000
-Subject: [PATCH] nvmem: Move of_nvmem_layout_get_container() in another header
-
-nvmem-consumer.h is included by consumer devices, extracting data from
-NVMEM devices whereas nvmem-provider.h is included by devices providing
-NVMEM content.
-
-The only users of of_nvmem_layout_get_container() outside of the core
-are layout drivers, so better move its prototype to nvmem-provider.h.
-
-While we do so, we also move the kdoc associated with the function to
-the header rather than the .c file.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 8 --------
- include/linux/nvmem-consumer.h | 7 -------
- include/linux/nvmem-provider.h | 21 +++++++++++++++++++++
- 3 files changed, 21 insertions(+), 15 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -848,14 +848,6 @@ static int nvmem_add_cells_from_layout(s
- }
-
- #if IS_ENABLED(CONFIG_OF)
--/**
-- * of_nvmem_layout_get_container() - Get OF node to layout container.
-- *
-- * @nvmem: nvmem device.
-- *
-- * Return: a node pointer with refcount incremented or NULL if no
-- * container exists. Use of_node_put() on it when done.
-- */
- struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
- {
- return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -241,7 +241,6 @@ struct nvmem_cell *of_nvmem_cell_get(str
- const char *id);
- struct nvmem_device *of_nvmem_device_get(struct device_node *np,
- const char *name);
--struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem);
- #else
- static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
- const char *id)
-@@ -254,12 +253,6 @@ static inline struct nvmem_device *of_nv
- {
- return ERR_PTR(-EOPNOTSUPP);
- }
--
--static inline struct device_node *
--of_nvmem_layout_get_container(struct nvmem_device *nvmem)
--{
-- return NULL;
--}
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
- #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -244,6 +244,27 @@ nvmem_layout_get_match_data(struct nvmem
-
- #endif /* CONFIG_NVMEM */
-
-+#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-+
-+/**
-+ * of_nvmem_layout_get_container() - Get OF node of layout container
-+ *
-+ * @nvmem: nvmem device
-+ *
-+ * Return: a node pointer with refcount incremented or NULL if no
-+ * container exists. Use of_node_put() on it when done.
-+ */
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem);
-+
-+#else /* CONFIG_NVMEM && CONFIG_OF */
-+
-+static inline struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return NULL;
-+}
-+
-+#endif /* CONFIG_NVMEM && CONFIG_OF */
-+
- #define module_nvmem_layout_driver(__layout_driver) \
- module_driver(__layout_driver, nvmem_layout_register, \
- nvmem_layout_unregister)
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch b/target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch
deleted file mode 100644
index e722109f91..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From ec9c08a1cb8dc5e8e003f95f5f62de41dde235bb Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:29 +0000
-Subject: [PATCH] nvmem: Create a header for internal sharing
-
-Before adding all the NVMEM layout bus infrastructure to the core, let's
-move the main nvmem_device structure in an internal header, only
-available to the core. This way all the additional code can be added in
-a dedicated file in order to keep the current core file tidy.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 24 +-----------------------
- drivers/nvmem/internals.h | 35 +++++++++++++++++++++++++++++++++++
- 2 files changed, 36 insertions(+), 23 deletions(-)
- create mode 100644 drivers/nvmem/internals.h
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -20,29 +20,7 @@
- #include <linux/of_device.h>
- #include <linux/slab.h>
-
--struct nvmem_device {
-- struct module *owner;
-- struct device dev;
-- int stride;
-- int word_size;
-- int id;
-- struct kref refcnt;
-- size_t size;
-- bool read_only;
-- bool root_only;
-- int flags;
-- enum nvmem_type type;
-- struct bin_attribute eeprom;
-- struct device *base_dev;
-- struct list_head cells;
-- const struct nvmem_keepout *keepout;
-- unsigned int nkeepout;
-- nvmem_reg_read_t reg_read;
-- nvmem_reg_write_t reg_write;
-- struct gpio_desc *wp_gpio;
-- struct nvmem_layout *layout;
-- void *priv;
--};
-+#include "internals.h"
-
- #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
-
---- /dev/null
-+++ b/drivers/nvmem/internals.h
-@@ -0,0 +1,35 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+
-+#ifndef _LINUX_NVMEM_INTERNALS_H
-+#define _LINUX_NVMEM_INTERNALS_H
-+
-+#include <linux/device.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+
-+struct nvmem_device {
-+ struct module *owner;
-+ struct device dev;
-+ struct list_head node;
-+ int stride;
-+ int word_size;
-+ int id;
-+ struct kref refcnt;
-+ size_t size;
-+ bool read_only;
-+ bool root_only;
-+ int flags;
-+ enum nvmem_type type;
-+ struct bin_attribute eeprom;
-+ struct device *base_dev;
-+ struct list_head cells;
-+ const struct nvmem_keepout *keepout;
-+ unsigned int nkeepout;
-+ nvmem_reg_read_t reg_read;
-+ nvmem_reg_write_t reg_write;
-+ struct gpio_desc *wp_gpio;
-+ struct nvmem_layout *layout;
-+ void *priv;
-+};
-+
-+#endif /* ifndef _LINUX_NVMEM_INTERNALS_H */
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch b/target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
deleted file mode 100644
index db2d8c1b46..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 1b7c298a4ecbc28cc6ee94005734bff55eb83d22 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:30 +0000
-Subject: [PATCH] nvmem: Simplify the ->add_cells() hook
-
-The layout entry is not used and will anyway be made useless by the new
-layout bus infrastructure coming next, so drop it. While at it, clarify
-the kdoc entry.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-5-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 2 +-
- drivers/nvmem/layouts/onie-tlv.c | 3 +--
- drivers/nvmem/layouts/sl28vpd.c | 3 +--
- include/linux/nvmem-provider.h | 8 +++-----
- 4 files changed, 6 insertions(+), 10 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -817,7 +817,7 @@ static int nvmem_add_cells_from_layout(s
- int ret;
-
- if (layout && layout->add_cells) {
-- ret = layout->add_cells(&nvmem->dev, nvmem, layout);
-+ ret = layout->add_cells(&nvmem->dev, nvmem);
- if (ret)
- return ret;
- }
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -182,8 +182,7 @@ static bool onie_tlv_crc_is_valid(struct
- return true;
- }
-
--static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
-+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem)
- {
- struct onie_tlv_hdr hdr;
- size_t table_len, data_len, hdr_len;
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -80,8 +80,7 @@ static int sl28vpd_v1_check_crc(struct d
- return 0;
- }
-
--static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
-+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem)
- {
- const struct nvmem_cell_info *pinfo;
- struct nvmem_cell_info info = {0};
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -156,9 +156,8 @@ struct nvmem_cell_table {
- *
- * @name: Layout name.
- * @of_match_table: Open firmware match table.
-- * @add_cells: Will be called if a nvmem device is found which
-- * has this layout. The function will add layout
-- * specific cells with nvmem_add_one_cell().
-+ * @add_cells: Called to populate the layout using
-+ * nvmem_add_one_cell().
- * @fixup_cell_info: Will be called before a cell is added. Can be
- * used to modify the nvmem_cell_info.
- * @owner: Pointer to struct module.
-@@ -172,8 +171,7 @@ struct nvmem_cell_table {
- struct nvmem_layout {
- const char *name;
- const struct of_device_id *of_match_table;
-- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem,
-- struct nvmem_layout *layout);
-+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
- void (*fixup_cell_info)(struct nvmem_device *nvmem,
- struct nvmem_layout *layout,
- struct nvmem_cell_info *cell);
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch b/target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
deleted file mode 100644
index 65aa37f834..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
+++ /dev/null
@@ -1,169 +0,0 @@
-From 1172460e716784ac7e1049a537bdca8edbf97360 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:31 +0000
-Subject: [PATCH] nvmem: Move and rename ->fixup_cell_info()
-
-This hook is meant to be used by any provider and instantiating a layout
-just for this is useless. Let's instead move this hook to the nvmem
-device and add it to the config structure to be easily shared by the
-providers.
-
-While at moving this hook, rename it ->fixup_dt_cell_info() to clarify
-its main intended purpose.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 6 +++---
- drivers/nvmem/imx-ocotp.c | 11 +++--------
- drivers/nvmem/internals.h | 2 ++
- drivers/nvmem/mtk-efuse.c | 11 +++--------
- include/linux/nvmem-provider.h | 9 ++++-----
- 5 files changed, 15 insertions(+), 24 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -676,7 +676,6 @@ static int nvmem_validate_keepouts(struc
-
- static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
- {
-- struct nvmem_layout *layout = nvmem->layout;
- struct device *dev = &nvmem->dev;
- struct device_node *child;
- const __be32 *addr;
-@@ -706,8 +705,8 @@ static int nvmem_add_cells_from_dt(struc
-
- info.np = of_node_get(child);
-
-- if (layout && layout->fixup_cell_info)
-- layout->fixup_cell_info(nvmem, layout, &info);
-+ if (nvmem->fixup_dt_cell_info)
-+ nvmem->fixup_dt_cell_info(nvmem, &info);
-
- ret = nvmem_add_one_cell(nvmem, &info);
- kfree(info.name);
-@@ -896,6 +895,7 @@ struct nvmem_device *nvmem_register(cons
-
- kref_init(&nvmem->refcnt);
- INIT_LIST_HEAD(&nvmem->cells);
-+ nvmem->fixup_dt_cell_info = config->fixup_dt_cell_info;
-
- nvmem->owner = config->owner;
- if (!nvmem->owner && config->dev->driver)
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -584,17 +584,12 @@ static const struct of_device_id imx_oco
- };
- MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
-
--static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout,
-- struct nvmem_cell_info *cell)
-+static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell)
- {
- cell->read_post_process = imx_ocotp_cell_pp;
- }
-
--static struct nvmem_layout imx_ocotp_layout = {
-- .fixup_cell_info = imx_ocotp_fixup_cell_info,
--};
--
- static int imx_ocotp_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -620,7 +615,7 @@ static int imx_ocotp_probe(struct platfo
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
-- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-+ imx_ocotp_nvmem_config.fixup_dt_cell_info = &imx_ocotp_fixup_dt_cell_info;
-
- priv->config = &imx_ocotp_nvmem_config;
-
---- a/drivers/nvmem/internals.h
-+++ b/drivers/nvmem/internals.h
-@@ -23,6 +23,8 @@ struct nvmem_device {
- struct bin_attribute eeprom;
- struct device *base_dev;
- struct list_head cells;
-+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell);
- const struct nvmem_keepout *keepout;
- unsigned int nkeepout;
- nvmem_reg_read_t reg_read;
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -45,9 +45,8 @@ static int mtk_efuse_gpu_speedbin_pp(voi
- return 0;
- }
-
--static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout,
-- struct nvmem_cell_info *cell)
-+static void mtk_efuse_fixup_dt_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell)
- {
- size_t sz = strlen(cell->name);
-
-@@ -61,10 +60,6 @@ static void mtk_efuse_fixup_cell_info(st
- cell->read_post_process = mtk_efuse_gpu_speedbin_pp;
- }
-
--static struct nvmem_layout mtk_efuse_layout = {
-- .fixup_cell_info = mtk_efuse_fixup_cell_info,
--};
--
- static int mtk_efuse_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -91,7 +86,7 @@ static int mtk_efuse_probe(struct platfo
- econfig.priv = priv;
- econfig.dev = dev;
- if (pdata->uses_post_processing)
-- econfig.layout = &mtk_efuse_layout;
-+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
- nvmem = devm_nvmem_register(dev, &econfig);
-
- return PTR_ERR_OR_ZERO(nvmem);
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -83,6 +83,8 @@ struct nvmem_cell_info {
- * @cells: Optional array of pre-defined NVMEM cells.
- * @ncells: Number of elements in cells.
- * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax.
-+ * @fixup_dt_cell_info: Will be called before a cell is added. Can be
-+ * used to modify the nvmem_cell_info.
- * @keepout: Optional array of keepout ranges (sorted ascending by start).
- * @nkeepout: Number of elements in the keepout array.
- * @type: Type of the nvmem storage
-@@ -113,6 +115,8 @@ struct nvmem_config {
- const struct nvmem_cell_info *cells;
- int ncells;
- bool add_legacy_fixed_of_cells;
-+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell);
- const struct nvmem_keepout *keepout;
- unsigned int nkeepout;
- enum nvmem_type type;
-@@ -158,8 +162,6 @@ struct nvmem_cell_table {
- * @of_match_table: Open firmware match table.
- * @add_cells: Called to populate the layout using
- * nvmem_add_one_cell().
-- * @fixup_cell_info: Will be called before a cell is added. Can be
-- * used to modify the nvmem_cell_info.
- * @owner: Pointer to struct module.
- * @node: List node.
- *
-@@ -172,9 +174,6 @@ struct nvmem_layout {
- const char *name;
- const struct of_device_id *of_match_table;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
-- void (*fixup_cell_info)(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout,
-- struct nvmem_cell_info *cell);
-
- /* private */
- struct module *owner;
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch b/target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
deleted file mode 100644
index 1881332340..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
+++ /dev/null
@@ -1,763 +0,0 @@
-From fc29fd821d9ac2ae3d32a722fac39ce874efb883 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:32 +0000
-Subject: [PATCH] nvmem: core: Rework layouts to become regular devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Current layout support was initially written without modules support in
-mind. When the requirement for module support rose, the existing base
-was improved to adopt modularization support, but kind of a design flaw
-was introduced. With the existing implementation, when a storage device
-registers into NVMEM, the core tries to hook a layout (if any) and
-populates its cells immediately. This means, if the hardware description
-expects a layout to be hooked up, but no driver was provided for that,
-the storage medium will fail to probe and try later from
-scratch. Even if we consider that the hardware description shall be
-correct, we could still probe the storage device (especially if it
-contains the rootfs).
-
-One way to overcome this situation is to consider the layouts as
-devices, and leverage the native notifier mechanism. When a new NVMEM
-device is registered, we can populate its nvmem-layout child, if any,
-and wait for the matching to be done in order to get the cells (the
-waiting can be easily done with the NVMEM notifiers). If the layout
-driver is compiled as a module, it should automatically be loaded. This
-way, there is no strong order to enforce, any NVMEM device creation
-or NVMEM layout driver insertion will be observed as a new event which
-may lead to the creation of additional cells, without disturbing the
-probes with costly (and sometimes endless) deferrals.
-
-In order to achieve that goal we create a new bus for the nvmem-layouts
-with minimal logic to match nvmem-layout devices with nvmem-layout
-drivers. All this infrastructure code is created in the layouts.c file.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 1 +
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/core.c | 170 ++++++++++----------------
- drivers/nvmem/internals.h | 21 ++++
- drivers/nvmem/layouts.c | 201 +++++++++++++++++++++++++++++++
- drivers/nvmem/layouts/Kconfig | 8 ++
- drivers/nvmem/layouts/onie-tlv.c | 24 +++-
- drivers/nvmem/layouts/sl28vpd.c | 24 +++-
- include/linux/nvmem-provider.h | 38 +++---
- 9 files changed, 354 insertions(+), 135 deletions(-)
- create mode 100644 drivers/nvmem/layouts.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- menuconfig NVMEM
- bool "NVMEM Support"
-+ imply NVMEM_LAYOUTS
- help
- Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES...
-
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -5,6 +5,8 @@
-
- obj-$(CONFIG_NVMEM) += nvmem_core.o
- nvmem_core-y := core.o
-+obj-$(CONFIG_NVMEM_LAYOUTS) += nvmem_layouts.o
-+nvmem_layouts-y := layouts.o
- obj-y += layouts/
-
- # Devices
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -56,9 +56,6 @@ static LIST_HEAD(nvmem_lookup_list);
-
- static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
-
--static DEFINE_SPINLOCK(nvmem_layout_lock);
--static LIST_HEAD(nvmem_layouts);
--
- static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
- void *val, size_t bytes)
- {
-@@ -741,97 +738,22 @@ static int nvmem_add_cells_from_fixed_la
- return err;
- }
-
--int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
-+int nvmem_layout_register(struct nvmem_layout *layout)
- {
-- layout->owner = owner;
--
-- spin_lock(&nvmem_layout_lock);
-- list_add(&layout->node, &nvmem_layouts);
-- spin_unlock(&nvmem_layout_lock);
--
-- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout);
-+ if (!layout->add_cells)
-+ return -EINVAL;
-
-- return 0;
-+ /* Populate the cells */
-+ return layout->add_cells(&layout->nvmem->dev, layout->nvmem);
- }
--EXPORT_SYMBOL_GPL(__nvmem_layout_register);
-+EXPORT_SYMBOL_GPL(nvmem_layout_register);
-
- void nvmem_layout_unregister(struct nvmem_layout *layout)
- {
-- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout);
--
-- spin_lock(&nvmem_layout_lock);
-- list_del(&layout->node);
-- spin_unlock(&nvmem_layout_lock);
-+ /* Keep the API even with an empty stub in case we need it later */
- }
- EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-
--static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
--{
-- struct device_node *layout_np;
-- struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
--
-- layout_np = of_nvmem_layout_get_container(nvmem);
-- if (!layout_np)
-- return NULL;
--
-- /* Fixed layouts don't have a matching driver */
-- if (of_device_is_compatible(layout_np, "fixed-layout")) {
-- of_node_put(layout_np);
-- return NULL;
-- }
--
-- /*
-- * In case the nvmem device was built-in while the layout was built as a
-- * module, we shall manually request the layout driver loading otherwise
-- * we'll never have any match.
-- */
-- of_request_module(layout_np);
--
-- spin_lock(&nvmem_layout_lock);
--
-- list_for_each_entry(l, &nvmem_layouts, node) {
-- if (of_match_node(l->of_match_table, layout_np)) {
-- if (try_module_get(l->owner))
-- layout = l;
--
-- break;
-- }
-- }
--
-- spin_unlock(&nvmem_layout_lock);
-- of_node_put(layout_np);
--
-- return layout;
--}
--
--static void nvmem_layout_put(struct nvmem_layout *layout)
--{
-- if (layout)
-- module_put(layout->owner);
--}
--
--static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem)
--{
-- struct nvmem_layout *layout = nvmem->layout;
-- int ret;
--
-- if (layout && layout->add_cells) {
-- ret = layout->add_cells(&nvmem->dev, nvmem);
-- if (ret)
-- return ret;
-- }
--
-- return 0;
--}
--
--#if IS_ENABLED(CONFIG_OF)
--struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
--{
-- return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
--}
--EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container);
--#endif
--
- const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout)
- {
-@@ -839,7 +761,7 @@ const void *nvmem_layout_get_match_data(
- const struct of_device_id *match;
-
- layout_np = of_nvmem_layout_get_container(nvmem);
-- match = of_match_node(layout->of_match_table, layout_np);
-+ match = of_match_node(layout->dev.driver->of_match_table, layout_np);
-
- return match ? match->data : NULL;
- }
-@@ -951,19 +873,6 @@ struct nvmem_device *nvmem_register(cons
- goto err_put_device;
- }
-
-- /*
-- * If the driver supplied a layout by config->layout, the module
-- * pointer will be NULL and nvmem_layout_put() will be a noop.
-- */
-- nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
-- if (IS_ERR(nvmem->layout)) {
-- rval = PTR_ERR(nvmem->layout);
-- nvmem->layout = NULL;
--
-- if (rval == -EPROBE_DEFER)
-- goto err_teardown_compat;
-- }
--
- if (config->cells) {
- rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
- if (rval)
-@@ -984,24 +893,24 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_layout(nvmem);
-- if (rval)
-- goto err_remove_cells;
--
- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
-
- rval = device_add(&nvmem->dev);
- if (rval)
- goto err_remove_cells;
-
-+ rval = nvmem_populate_layout(nvmem);
-+ if (rval)
-+ goto err_remove_dev;
-+
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
-
- return nvmem;
-
-+err_remove_dev:
-+ device_del(&nvmem->dev);
- err_remove_cells:
- nvmem_device_remove_all_cells(nvmem);
-- nvmem_layout_put(nvmem->layout);
--err_teardown_compat:
- if (config->compat)
- nvmem_sysfs_remove_compat(nvmem, config);
- err_put_device:
-@@ -1023,7 +932,7 @@ static void nvmem_device_release(struct
- device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
-
- nvmem_device_remove_all_cells(nvmem);
-- nvmem_layout_put(nvmem->layout);
-+ nvmem_destroy_layout(nvmem);
- device_unregister(&nvmem->dev);
- }
-
-@@ -1325,6 +1234,12 @@ nvmem_cell_get_from_lookup(struct device
- return cell;
- }
-
-+static void nvmem_layout_module_put(struct nvmem_device *nvmem)
-+{
-+ if (nvmem->layout && nvmem->layout->dev.driver)
-+ module_put(nvmem->layout->dev.driver->owner);
-+}
-+
- #if IS_ENABLED(CONFIG_OF)
- static struct nvmem_cell_entry *
- nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np)
-@@ -1343,6 +1258,18 @@ nvmem_find_cell_entry_by_node(struct nvm
- return cell;
- }
-
-+static int nvmem_layout_module_get_optional(struct nvmem_device *nvmem)
-+{
-+ if (!nvmem->layout)
-+ return 0;
-+
-+ if (!nvmem->layout->dev.driver ||
-+ !try_module_get(nvmem->layout->dev.driver->owner))
-+ return -EPROBE_DEFER;
-+
-+ return 0;
-+}
-+
- /**
- * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
- *
-@@ -1405,16 +1332,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
- return ERR_CAST(nvmem);
- }
-
-+ ret = nvmem_layout_module_get_optional(nvmem);
-+ if (ret) {
-+ of_node_put(cell_np);
-+ __nvmem_device_put(nvmem);
-+ return ERR_PTR(ret);
-+ }
-+
- cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
- of_node_put(cell_np);
- if (!cell_entry) {
- __nvmem_device_put(nvmem);
-- return ERR_PTR(-ENOENT);
-+ nvmem_layout_module_put(nvmem);
-+ if (nvmem->layout)
-+ return ERR_PTR(-EPROBE_DEFER);
-+ else
-+ return ERR_PTR(-ENOENT);
- }
-
- cell = nvmem_create_cell(cell_entry, id, cell_index);
-- if (IS_ERR(cell))
-+ if (IS_ERR(cell)) {
- __nvmem_device_put(nvmem);
-+ nvmem_layout_module_put(nvmem);
-+ }
-
- return cell;
- }
-@@ -1528,6 +1468,7 @@ void nvmem_cell_put(struct nvmem_cell *c
-
- kfree(cell);
- __nvmem_device_put(nvmem);
-+ nvmem_layout_module_put(nvmem);
- }
- EXPORT_SYMBOL_GPL(nvmem_cell_put);
-
-@@ -2105,11 +2046,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name);
-
- static int __init nvmem_init(void)
- {
-- return bus_register(&nvmem_bus_type);
-+ int ret;
-+
-+ ret = bus_register(&nvmem_bus_type);
-+ if (ret)
-+ return ret;
-+
-+ ret = nvmem_layout_bus_register();
-+ if (ret)
-+ bus_unregister(&nvmem_bus_type);
-+
-+ return ret;
- }
-
- static void __exit nvmem_exit(void)
- {
-+ nvmem_layout_bus_unregister();
- bus_unregister(&nvmem_bus_type);
- }
-
---- a/drivers/nvmem/internals.h
-+++ b/drivers/nvmem/internals.h
-@@ -34,4 +34,25 @@ struct nvmem_device {
- void *priv;
- };
-
-+#if IS_ENABLED(CONFIG_OF)
-+int nvmem_layout_bus_register(void);
-+void nvmem_layout_bus_unregister(void);
-+int nvmem_populate_layout(struct nvmem_device *nvmem);
-+void nvmem_destroy_layout(struct nvmem_device *nvmem);
-+#else /* CONFIG_OF */
-+static inline int nvmem_layout_bus_register(void)
-+{
-+ return 0;
-+}
-+
-+static inline void nvmem_layout_bus_unregister(void) {}
-+
-+static inline int nvmem_populate_layout(struct nvmem_device *nvmem)
-+{
-+ return 0;
-+}
-+
-+static inline void nvmem_destroy_layout(struct nvmem_device *nvmem) { }
-+#endif /* CONFIG_OF */
-+
- #endif /* ifndef _LINUX_NVMEM_INTERNALS_H */
---- /dev/null
-+++ b/drivers/nvmem/layouts.c
-@@ -0,0 +1,201 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * NVMEM layout bus handling
-+ *
-+ * Copyright (C) 2023 Bootlin
-+ * Author: Miquel Raynal <miquel.raynal@bootlin.com
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/of_irq.h>
-+
-+#include "internals.h"
-+
-+#define to_nvmem_layout_driver(drv) \
-+ (container_of((drv), struct nvmem_layout_driver, driver))
-+#define to_nvmem_layout_device(_dev) \
-+ container_of((_dev), struct nvmem_layout, dev)
-+
-+static int nvmem_layout_bus_match(struct device *dev, struct device_driver *drv)
-+{
-+ return of_driver_match_device(dev, drv);
-+}
-+
-+static int nvmem_layout_bus_probe(struct device *dev)
-+{
-+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver);
-+ struct nvmem_layout *layout = to_nvmem_layout_device(dev);
-+
-+ if (!drv->probe || !drv->remove)
-+ return -EINVAL;
-+
-+ return drv->probe(layout);
-+}
-+
-+static void nvmem_layout_bus_remove(struct device *dev)
-+{
-+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver);
-+ struct nvmem_layout *layout = to_nvmem_layout_device(dev);
-+
-+ return drv->remove(layout);
-+}
-+
-+static struct bus_type nvmem_layout_bus_type = {
-+ .name = "nvmem-layout",
-+ .match = nvmem_layout_bus_match,
-+ .probe = nvmem_layout_bus_probe,
-+ .remove = nvmem_layout_bus_remove,
-+};
-+
-+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv)
-+{
-+ drv->driver.bus = &nvmem_layout_bus_type;
-+
-+ return driver_register(&drv->driver);
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_driver_register);
-+
-+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv)
-+{
-+ driver_unregister(&drv->driver);
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_driver_unregister);
-+
-+static void nvmem_layout_release_device(struct device *dev)
-+{
-+ struct nvmem_layout *layout = to_nvmem_layout_device(dev);
-+
-+ of_node_put(layout->dev.of_node);
-+ kfree(layout);
-+}
-+
-+static int nvmem_layout_create_device(struct nvmem_device *nvmem,
-+ struct device_node *np)
-+{
-+ struct nvmem_layout *layout;
-+ struct device *dev;
-+ int ret;
-+
-+ layout = kzalloc(sizeof(*layout), GFP_KERNEL);
-+ if (!layout)
-+ return -ENOMEM;
-+
-+ /* Create a bidirectional link */
-+ layout->nvmem = nvmem;
-+ nvmem->layout = layout;
-+
-+ /* Device model registration */
-+ dev = &layout->dev;
-+ device_initialize(dev);
-+ dev->parent = &nvmem->dev;
-+ dev->bus = &nvmem_layout_bus_type;
-+ dev->release = nvmem_layout_release_device;
-+ dev->coherent_dma_mask = DMA_BIT_MASK(32);
-+ dev->dma_mask = &dev->coherent_dma_mask;
-+ device_set_node(dev, of_fwnode_handle(of_node_get(np)));
-+ of_device_make_bus_id(dev);
-+ of_msi_configure(dev, dev->of_node);
-+
-+ ret = device_add(dev);
-+ if (ret) {
-+ put_device(dev);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id of_nvmem_layout_skip_table[] = {
-+ { .compatible = "fixed-layout", },
-+ {}
-+};
-+
-+static int nvmem_layout_bus_populate(struct nvmem_device *nvmem,
-+ struct device_node *layout_dn)
-+{
-+ int ret;
-+
-+ /* Make sure it has a compatible property */
-+ if (!of_get_property(layout_dn, "compatible", NULL)) {
-+ pr_debug("%s() - skipping %pOF, no compatible prop\n",
-+ __func__, layout_dn);
-+ return 0;
-+ }
-+
-+ /* Fixed layouts are parsed manually somewhere else for now */
-+ if (of_match_node(of_nvmem_layout_skip_table, layout_dn)) {
-+ pr_debug("%s() - skipping %pOF node\n", __func__, layout_dn);
-+ return 0;
-+ }
-+
-+ if (of_node_check_flag(layout_dn, OF_POPULATED_BUS)) {
-+ pr_debug("%s() - skipping %pOF, already populated\n",
-+ __func__, layout_dn);
-+
-+ return 0;
-+ }
-+
-+ /* NVMEM layout buses expect only a single device representing the layout */
-+ ret = nvmem_layout_create_device(nvmem, layout_dn);
-+ if (ret)
-+ return ret;
-+
-+ of_node_set_flag(layout_dn, OF_POPULATED_BUS);
-+
-+ return 0;
-+}
-+
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
-+}
-+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container);
-+
-+/*
-+ * Returns the number of devices populated, 0 if the operation was not relevant
-+ * for this nvmem device, an error code otherwise.
-+ */
-+int nvmem_populate_layout(struct nvmem_device *nvmem)
-+{
-+ struct device_node *layout_dn;
-+ int ret;
-+
-+ layout_dn = of_nvmem_layout_get_container(nvmem);
-+ if (!layout_dn)
-+ return 0;
-+
-+ /* Populate the layout device */
-+ device_links_supplier_sync_state_pause();
-+ ret = nvmem_layout_bus_populate(nvmem, layout_dn);
-+ device_links_supplier_sync_state_resume();
-+
-+ of_node_put(layout_dn);
-+ return ret;
-+}
-+
-+void nvmem_destroy_layout(struct nvmem_device *nvmem)
-+{
-+ struct device *dev;
-+
-+ if (!nvmem->layout)
-+ return;
-+
-+ dev = &nvmem->layout->dev;
-+ of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
-+ device_unregister(dev);
-+}
-+
-+int nvmem_layout_bus_register(void)
-+{
-+ return bus_register(&nvmem_layout_bus_type);
-+}
-+
-+void nvmem_layout_bus_unregister(void)
-+{
-+ bus_unregister(&nvmem_layout_bus_type);
-+}
---- a/drivers/nvmem/layouts/Kconfig
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -1,5 +1,11 @@
- # SPDX-License-Identifier: GPL-2.0
-
-+config NVMEM_LAYOUTS
-+ bool
-+ depends on OF
-+
-+if NVMEM_LAYOUTS
-+
- menu "Layout Types"
-
- config NVMEM_LAYOUT_SL28_VPD
-@@ -21,3 +27,5 @@ config NVMEM_LAYOUT_ONIE_TLV
- If unsure, say N.
-
- endmenu
-+
-+endif
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -225,16 +225,32 @@ static int onie_tlv_parse_table(struct d
- return 0;
- }
-
-+static int onie_tlv_probe(struct nvmem_layout *layout)
-+{
-+ layout->add_cells = onie_tlv_parse_table;
-+
-+ return nvmem_layout_register(layout);
-+}
-+
-+static void onie_tlv_remove(struct nvmem_layout *layout)
-+{
-+ nvmem_layout_unregister(layout);
-+}
-+
- static const struct of_device_id onie_tlv_of_match_table[] = {
- { .compatible = "onie,tlv-layout", },
- {},
- };
- MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table);
-
--static struct nvmem_layout onie_tlv_layout = {
-- .name = "ONIE tlv layout",
-- .of_match_table = onie_tlv_of_match_table,
-- .add_cells = onie_tlv_parse_table,
-+static struct nvmem_layout_driver onie_tlv_layout = {
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "onie-tlv-layout",
-+ .of_match_table = onie_tlv_of_match_table,
-+ },
-+ .probe = onie_tlv_probe,
-+ .remove = onie_tlv_remove,
- };
- module_nvmem_layout_driver(onie_tlv_layout);
-
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -134,16 +134,32 @@ static int sl28vpd_add_cells(struct devi
- return 0;
- }
-
-+static int sl28vpd_probe(struct nvmem_layout *layout)
-+{
-+ layout->add_cells = sl28vpd_add_cells;
-+
-+ return nvmem_layout_register(layout);
-+}
-+
-+static void sl28vpd_remove(struct nvmem_layout *layout)
-+{
-+ nvmem_layout_unregister(layout);
-+}
-+
- static const struct of_device_id sl28vpd_of_match_table[] = {
- { .compatible = "kontron,sl28-vpd" },
- {},
- };
- MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table);
-
--static struct nvmem_layout sl28vpd_layout = {
-- .name = "sl28-vpd",
-- .of_match_table = sl28vpd_of_match_table,
-- .add_cells = sl28vpd_add_cells,
-+static struct nvmem_layout_driver sl28vpd_layout = {
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "kontron-sl28vpd-layout",
-+ .of_match_table = sl28vpd_of_match_table,
-+ },
-+ .probe = sl28vpd_probe,
-+ .remove = sl28vpd_remove,
- };
- module_nvmem_layout_driver(sl28vpd_layout);
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -9,6 +9,7 @@
- #ifndef _LINUX_NVMEM_PROVIDER_H
- #define _LINUX_NVMEM_PROVIDER_H
-
-+#include <linux/device.h>
- #include <linux/device/driver.h>
- #include <linux/err.h>
- #include <linux/errno.h>
-@@ -158,12 +159,11 @@ struct nvmem_cell_table {
- /**
- * struct nvmem_layout - NVMEM layout definitions
- *
-- * @name: Layout name.
-- * @of_match_table: Open firmware match table.
-- * @add_cells: Called to populate the layout using
-- * nvmem_add_one_cell().
-- * @owner: Pointer to struct module.
-- * @node: List node.
-+ * @dev: Device-model layout device.
-+ * @nvmem: The underlying NVMEM device
-+ * @add_cells: Will be called if a nvmem device is found which
-+ * has this layout. The function will add layout
-+ * specific cells with nvmem_add_one_cell().
- *
- * A nvmem device can hold a well defined structure which can just be
- * evaluated during runtime. For example a TLV list, or a list of "name=val"
-@@ -171,13 +171,15 @@ struct nvmem_cell_table {
- * cells.
- */
- struct nvmem_layout {
-- const char *name;
-- const struct of_device_id *of_match_table;
-+ struct device dev;
-+ struct nvmem_device *nvmem;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
-+};
-
-- /* private */
-- struct module *owner;
-- struct list_head node;
-+struct nvmem_layout_driver {
-+ struct device_driver driver;
-+ int (*probe)(struct nvmem_layout *layout);
-+ void (*remove)(struct nvmem_layout *layout);
- };
-
- #if IS_ENABLED(CONFIG_NVMEM)
-@@ -194,11 +196,15 @@ void nvmem_del_cell_table(struct nvmem_c
- int nvmem_add_one_cell(struct nvmem_device *nvmem,
- const struct nvmem_cell_info *info);
-
--int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner);
--#define nvmem_layout_register(layout) \
-- __nvmem_layout_register(layout, THIS_MODULE)
-+int nvmem_layout_register(struct nvmem_layout *layout);
- void nvmem_layout_unregister(struct nvmem_layout *layout);
-
-+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv);
-+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv);
-+#define module_nvmem_layout_driver(__nvmem_layout_driver) \
-+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
-+ nvmem_layout_driver_unregister)
-+
- const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout);
-
-@@ -262,8 +268,4 @@ static inline struct device_node *of_nvm
-
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
--#define module_nvmem_layout_driver(__layout_driver) \
-- module_driver(__layout_driver, nvmem_layout_register, \
-- nvmem_layout_unregister)
--
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch b/target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
deleted file mode 100644
index 89872bec2e..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
+++ /dev/null
@@ -1,240 +0,0 @@
-From 0331c611949fffdf486652450901a4dc52bc5cca Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:34 +0000
-Subject: [PATCH] nvmem: core: Expose cells through sysfs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The binary content of nvmem devices is available to the user so in the
-easiest cases, finding the content of a cell is rather easy as it is
-just a matter of looking at a known and fixed offset. However, nvmem
-layouts have been recently introduced to cope with more advanced
-situations, where the offset and size of the cells is not known in
-advance or is dynamic. When using layouts, more advanced parsers are
-used by the kernel in order to give direct access to the content of each
-cell, regardless of its position/size in the underlying
-device. Unfortunately, these information are not accessible by users,
-unless by fully re-implementing the parser logic in userland.
-
-Let's expose the cells and their content through sysfs to avoid these
-situations. Of course the relevant NVMEM sysfs Kconfig option must be
-enabled for this support to be available.
-
-Not all nvmem devices expose cells. Indeed, the .bin_attrs attribute
-group member will be filled at runtime only when relevant and will
-remain empty otherwise. In this case, as the cells attribute group will
-be empty, it will not lead to any additional folder/file creation.
-
-Exposed cells are read-only. There is, in practice, everything in the
-core to support a write path, but as I don't see any need for that, I
-prefer to keep the interface simple (and probably safer). The interface
-is documented as being in the "testing" state which means we can later
-add a write attribute if though relevant.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Rafał Miłecki <rafal@milecki.pl>
-Tested-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 135 +++++++++++++++++++++++++++++++++++++-
- drivers/nvmem/internals.h | 1 +
- 2 files changed, 135 insertions(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -300,6 +300,43 @@ static umode_t nvmem_bin_attr_is_visible
- return nvmem_bin_attr_get_umode(nvmem);
- }
-
-+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
-+ const char *id, int index);
-+
-+static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj,
-+ struct bin_attribute *attr, char *buf,
-+ loff_t pos, size_t count)
-+{
-+ struct nvmem_cell_entry *entry;
-+ struct nvmem_cell *cell = NULL;
-+ size_t cell_sz, read_len;
-+ void *content;
-+
-+ entry = attr->private;
-+ cell = nvmem_create_cell(entry, entry->name, 0);
-+ if (IS_ERR(cell))
-+ return PTR_ERR(cell);
-+
-+ if (!cell)
-+ return -EINVAL;
-+
-+ content = nvmem_cell_read(cell, &cell_sz);
-+ if (IS_ERR(content)) {
-+ read_len = PTR_ERR(content);
-+ goto destroy_cell;
-+ }
-+
-+ read_len = min_t(unsigned int, cell_sz - pos, count);
-+ memcpy(buf, content + pos, read_len);
-+ kfree(content);
-+
-+destroy_cell:
-+ kfree_const(cell->id);
-+ kfree(cell);
-+
-+ return read_len;
-+}
-+
- /* default read/write permissions */
- static struct bin_attribute bin_attr_rw_nvmem = {
- .attr = {
-@@ -321,11 +358,21 @@ static const struct attribute_group nvme
- .is_bin_visible = nvmem_bin_attr_is_visible,
- };
-
-+/* Cell attributes will be dynamically allocated */
-+static struct attribute_group nvmem_cells_group = {
-+ .name = "cells",
-+};
-+
- static const struct attribute_group *nvmem_dev_groups[] = {
- &nvmem_bin_group,
- NULL,
- };
-
-+static const struct attribute_group *nvmem_cells_groups[] = {
-+ &nvmem_cells_group,
-+ NULL,
-+};
-+
- static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
- .attr = {
- .name = "eeprom",
-@@ -381,6 +428,68 @@ static void nvmem_sysfs_remove_compat(st
- device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
- }
-
-+static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem)
-+{
-+ struct bin_attribute **cells_attrs, *attrs;
-+ struct nvmem_cell_entry *entry;
-+ unsigned int ncells = 0, i = 0;
-+ int ret = 0;
-+
-+ mutex_lock(&nvmem_mutex);
-+
-+ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) {
-+ nvmem_cells_group.bin_attrs = NULL;
-+ goto unlock_mutex;
-+ }
-+
-+ /* Allocate an array of attributes with a sentinel */
-+ ncells = list_count_nodes(&nvmem->cells);
-+ cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
-+ sizeof(struct bin_attribute *), GFP_KERNEL);
-+ if (!cells_attrs) {
-+ ret = -ENOMEM;
-+ goto unlock_mutex;
-+ }
-+
-+ attrs = devm_kcalloc(&nvmem->dev, ncells, sizeof(struct bin_attribute), GFP_KERNEL);
-+ if (!attrs) {
-+ ret = -ENOMEM;
-+ goto unlock_mutex;
-+ }
-+
-+ /* Initialize each attribute to take the name and size of the cell */
-+ list_for_each_entry(entry, &nvmem->cells, node) {
-+ sysfs_bin_attr_init(&attrs[i]);
-+ attrs[i].attr.name = devm_kasprintf(&nvmem->dev, GFP_KERNEL,
-+ "%s@%x", entry->name,
-+ entry->offset);
-+ attrs[i].attr.mode = 0444;
-+ attrs[i].size = entry->bytes;
-+ attrs[i].read = &nvmem_cell_attr_read;
-+ attrs[i].private = entry;
-+ if (!attrs[i].attr.name) {
-+ ret = -ENOMEM;
-+ goto unlock_mutex;
-+ }
-+
-+ cells_attrs[i] = &attrs[i];
-+ i++;
-+ }
-+
-+ nvmem_cells_group.bin_attrs = cells_attrs;
-+
-+ ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups);
-+ if (ret)
-+ goto unlock_mutex;
-+
-+ nvmem->sysfs_cells_populated = true;
-+
-+unlock_mutex:
-+ mutex_unlock(&nvmem_mutex);
-+
-+ return ret;
-+}
-+
- #else /* CONFIG_NVMEM_SYSFS */
-
- static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
-@@ -740,11 +849,25 @@ static int nvmem_add_cells_from_fixed_la
-
- int nvmem_layout_register(struct nvmem_layout *layout)
- {
-+ int ret;
-+
- if (!layout->add_cells)
- return -EINVAL;
-
- /* Populate the cells */
-- return layout->add_cells(&layout->nvmem->dev, layout->nvmem);
-+ ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem);
-+ if (ret)
-+ return ret;
-+
-+#ifdef CONFIG_NVMEM_SYSFS
-+ ret = nvmem_populate_sysfs_cells(layout->nvmem);
-+ if (ret) {
-+ nvmem_device_remove_all_cells(layout->nvmem);
-+ return ret;
-+ }
-+#endif
-+
-+ return 0;
- }
- EXPORT_SYMBOL_GPL(nvmem_layout_register);
-
-@@ -903,10 +1026,20 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_dev;
-
-+#ifdef CONFIG_NVMEM_SYSFS
-+ rval = nvmem_populate_sysfs_cells(nvmem);
-+ if (rval)
-+ goto err_destroy_layout;
-+#endif
-+
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
-
- return nvmem;
-
-+#ifdef CONFIG_NVMEM_SYSFS
-+err_destroy_layout:
-+ nvmem_destroy_layout(nvmem);
-+#endif
- err_remove_dev:
- device_del(&nvmem->dev);
- err_remove_cells:
---- a/drivers/nvmem/internals.h
-+++ b/drivers/nvmem/internals.h
-@@ -32,6 +32,7 @@ struct nvmem_device {
- struct gpio_desc *wp_gpio;
- struct nvmem_layout *layout;
- void *priv;
-+ bool sysfs_cells_populated;
- };
-
- #if IS_ENABLED(CONFIG_OF)
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch b/target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch
deleted file mode 100644
index f686222f88..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From f0ac5b23039610619ca4a4805528553ecb6bc815 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 15 Dec 2023 11:15:36 +0000
-Subject: [PATCH] nvmem: stm32: add support for STM32MP25 BSEC to control OTP
- data
-
-On STM32MP25, OTP area may be read/written by using BSEC (boot, security
-and OTP control). The BSEC internal peripheral is only managed by the
-secure world.
-
-The 12 Kbits of OTP (effective) are organized into the following regions:
-- lower OTP (OTP0 to OTP127) = 4096 lower OTP bits,
- bitwise (1-bit) programmable
-- mid OTP (OTP128 to OTP255) = 4096 middle OTP bits,
- bulk (32-bit) programmable
-- upper OTP (OTP256 to OTP383) = 4096 upper OTP bits,
- bulk (32-bit) programmable,
- only accessible when BSEC is in closed state.
-
-As HWKEY and ECIES key are only accessible by ROM code;
-only 368 OTP words are managed in this driver (OTP0 to OTP267).
-
-This patch adds the STM32MP25 configuration for reading and writing
-the OTP data using the OP-TEE BSEC TA services.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-11-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -269,6 +269,19 @@ static const struct stm32_romem_cfg stm3
- .ta = true,
- };
-
-+/*
-+ * STM32MP25 BSEC OTP: 3 regions of 32-bits data words
-+ * lower OTP (OTP0 to OTP127), bitwise (1-bit) programmable
-+ * mid OTP (OTP128 to OTP255), bulk (32-bit) programmable
-+ * upper OTP (OTP256 to OTP383), bulk (32-bit) programmable
-+ * but no access to HWKEY and ECIES key: limited at OTP367
-+ */
-+static const struct stm32_romem_cfg stm32mp25_bsec_cfg = {
-+ .size = 368 * 4,
-+ .lower = 127,
-+ .ta = true,
-+};
-+
- static const struct of_device_id stm32_romem_of_match[] __maybe_unused = {
- { .compatible = "st,stm32f4-otp", }, {
- .compatible = "st,stm32mp15-bsec",
-@@ -276,6 +289,9 @@ static const struct of_device_id stm32_r
- }, {
- .compatible = "st,stm32mp13-bsec",
- .data = (void *)&stm32mp13_bsec_cfg,
-+ }, {
-+ .compatible = "st,stm32mp25-bsec",
-+ .data = (void *)&stm32mp25_bsec_cfg,
- },
- { /* sentinel */ },
- };
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch b/target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
deleted file mode 100644
index 1bf3ba35b6..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 401df0d4f4098ecc9c5278da2f50756d62e5b37d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 19 Dec 2023 13:01:03 +0100
-Subject: [PATCH] nvmem: layouts: refactor .add_cells() callback arguments
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Simply pass whole "struct nvmem_layout" instead of single variables.
-There is nothing in "struct nvmem_layout" that we have to hide from
-layout drivers. They also access it during .probe() and .remove().
-
-Thanks to this change:
-
-1. API gets more consistent
- All layouts drivers callbacks get the same argument
-
-2. Layouts get correct device
- Before this change NVMEM core code was passing NVMEM device instead
- of layout device. That resulted in:
- * Confusing prints
- * Calling devm_*() helpers on wrong device
- * Helpers like of_device_get_match_data() dereferencing NULLs
-
-3. It gets possible to get match data
- First of all nvmem_layout_get_match_data() requires passing "struct
- nvmem_layout" which .add_cells() callback didn't have before this. It
- doesn't matter much as it's rather useless now anyway (and will be
- dropped).
- What's more important however is that of_device_get_match_data() can
- be used now thanks to owning a proper device pointer.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Link: https://lore.kernel.org/r/20231219120104.3422-1-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 2 +-
- drivers/nvmem/layouts/onie-tlv.c | 4 +++-
- drivers/nvmem/layouts/sl28vpd.c | 4 +++-
- include/linux/nvmem-provider.h | 2 +-
- 4 files changed, 8 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -855,7 +855,7 @@ int nvmem_layout_register(struct nvmem_l
- return -EINVAL;
-
- /* Populate the cells */
-- ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem);
-+ ret = layout->add_cells(layout);
- if (ret)
- return ret;
-
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -182,8 +182,10 @@ static bool onie_tlv_crc_is_valid(struct
- return true;
- }
-
--static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem)
-+static int onie_tlv_parse_table(struct nvmem_layout *layout)
- {
-+ struct nvmem_device *nvmem = layout->nvmem;
-+ struct device *dev = &layout->dev;
- struct onie_tlv_hdr hdr;
- size_t table_len, data_len, hdr_len;
- u8 *table, *data;
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -80,8 +80,10 @@ static int sl28vpd_v1_check_crc(struct d
- return 0;
- }
-
--static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem)
-+static int sl28vpd_add_cells(struct nvmem_layout *layout)
- {
-+ struct nvmem_device *nvmem = layout->nvmem;
-+ struct device *dev = &layout->dev;
- const struct nvmem_cell_info *pinfo;
- struct nvmem_cell_info info = {0};
- struct device_node *layout_np;
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -173,7 +173,7 @@ struct nvmem_cell_table {
- struct nvmem_layout {
- struct device dev;
- struct nvmem_device *nvmem;
-- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
-+ int (*add_cells)(struct nvmem_layout *layout);
- };
-
- struct nvmem_layout_driver {
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch b/target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
deleted file mode 100644
index 514b5f2de5..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 43f60e3fb62edc7bd8891de8779fb422f4ae23ae Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 19 Dec 2023 13:01:04 +0100
-Subject: [PATCH] nvmem: drop nvmem_layout_get_match_data()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Thanks for layouts refactoring we now have "struct device" associated
-with layout. Also its OF pointer points directly to the "nvmem-layout"
-DT node.
-
-All it takes to get match data is a generic of_device_get_match_data().
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Link: https://lore.kernel.org/r/20231219120104.3422-2-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 13 -------------
- include/linux/nvmem-provider.h | 10 ----------
- 2 files changed, 23 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -877,19 +877,6 @@ void nvmem_layout_unregister(struct nvme
- }
- EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-
--const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
--{
-- struct device_node __maybe_unused *layout_np;
-- const struct of_device_id *match;
--
-- layout_np = of_nvmem_layout_get_container(nvmem);
-- match = of_match_node(layout->dev.driver->of_match_table, layout_np);
--
-- return match ? match->data : NULL;
--}
--EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data);
--
- /**
- * nvmem_register() - Register a nvmem device for given nvmem_config.
- * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -205,9 +205,6 @@ void nvmem_layout_driver_unregister(stru
- module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
- nvmem_layout_driver_unregister)
-
--const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout);
--
- #else
-
- static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
-@@ -238,13 +235,6 @@ static inline int nvmem_layout_register(
-
- static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {}
-
--static inline const void *
--nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
--{
-- return NULL;
--}
--
- #endif /* CONFIG_NVMEM */
-
- #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch b/target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
deleted file mode 100644
index aa0bbaa0c5..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 33cf42e68efc8ff529a7eee08a4f0ba8c8d0a207 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:17 +0100
-Subject: [PATCH] nvmem: core: add nvmem_dev_size() helper
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is required by layouts that need to read whole NVMEM content. It's
-especially useful for NVMEM devices without hardcoded layout (like
-U-Boot environment data block).
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-2-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 13 +++++++++++++
- include/linux/nvmem-consumer.h | 1 +
- 2 files changed, 14 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -2164,6 +2164,19 @@ const char *nvmem_dev_name(struct nvmem_
- }
- EXPORT_SYMBOL_GPL(nvmem_dev_name);
-
-+/**
-+ * nvmem_dev_size() - Get the size of a given nvmem device.
-+ *
-+ * @nvmem: nvmem device.
-+ *
-+ * Return: size of the nvmem device.
-+ */
-+size_t nvmem_dev_size(struct nvmem_device *nvmem)
-+{
-+ return nvmem->size;
-+}
-+EXPORT_SYMBOL_GPL(nvmem_dev_size);
-+
- static int __init nvmem_init(void)
- {
- int ret;
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem
- struct nvmem_cell_info *info, void *buf);
-
- const char *nvmem_dev_name(struct nvmem_device *nvmem);
-+size_t nvmem_dev_size(struct nvmem_device *nvmem);
-
- void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries,
- size_t nentries);
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch b/target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch
deleted file mode 100644
index fc826f3f7e..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 7c8979b42b1a9c5604f431ba804928e55919263c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:18 +0100
-Subject: [PATCH] nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem
- helper
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Simplify adding NVMEM cells.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-3-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 55 +++++++++++++++-----------------------
- 1 file changed, 21 insertions(+), 34 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -23,13 +23,10 @@ enum u_boot_env_format {
-
- struct u_boot_env {
- struct device *dev;
-+ struct nvmem_device *nvmem;
- enum u_boot_env_format format;
-
- struct mtd_info *mtd;
--
-- /* Cells */
-- struct nvmem_cell_info *cells;
-- int ncells;
- };
-
- struct u_boot_env_image_single {
-@@ -94,43 +91,36 @@ static int u_boot_env_read_post_process_
- static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
- size_t data_offset, size_t data_len)
- {
-+ struct nvmem_device *nvmem = priv->nvmem;
- struct device *dev = priv->dev;
- char *data = buf + data_offset;
- char *var, *value, *eq;
-- int idx;
--
-- priv->ncells = 0;
-- for (var = data; var < data + data_len && *var; var += strlen(var) + 1)
-- priv->ncells++;
--
-- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
-- if (!priv->cells)
-- return -ENOMEM;
-
-- for (var = data, idx = 0;
-+ for (var = data;
- var < data + data_len && *var;
-- var = value + strlen(value) + 1, idx++) {
-+ var = value + strlen(value) + 1) {
-+ struct nvmem_cell_info info = {};
-+
- eq = strchr(var, '=');
- if (!eq)
- break;
- *eq = '\0';
- value = eq + 1;
-
-- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
-- if (!priv->cells[idx].name)
-+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
-+ if (!info.name)
- return -ENOMEM;
-- priv->cells[idx].offset = data_offset + value - data;
-- priv->cells[idx].bytes = strlen(value);
-- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-+ info.offset = data_offset + value - data;
-+ info.bytes = strlen(value);
-+ info.np = of_get_child_by_name(dev->of_node, info.name);
- if (!strcmp(var, "ethaddr")) {
-- priv->cells[idx].raw_len = strlen(value);
-- priv->cells[idx].bytes = ETH_ALEN;
-- priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
-+ info.raw_len = strlen(value);
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
- }
-- }
-
-- if (WARN_ON(idx != priv->ncells))
-- priv->ncells = idx;
-+ nvmem_add_one_cell(nvmem, &info);
-+ }
-
- return 0;
- }
-@@ -209,7 +199,6 @@ static int u_boot_env_probe(struct platf
- struct device *dev = &pdev->dev;
- struct device_node *np = dev->of_node;
- struct u_boot_env *priv;
-- int err;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -224,17 +213,15 @@ static int u_boot_env_probe(struct platf
- return PTR_ERR(priv->mtd);
- }
-
-- err = u_boot_env_parse(priv);
-- if (err)
-- return err;
--
- config.dev = dev;
-- config.cells = priv->cells;
-- config.ncells = priv->ncells;
- config.priv = priv;
- config.size = priv->mtd->size;
-
-- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
-+ priv->nvmem = devm_nvmem_register(dev, &config);
-+ if (IS_ERR(priv->nvmem))
-+ return PTR_ERR(priv->nvmem);
-+
-+ return u_boot_env_parse(priv);
- }
-
- static const struct of_device_id u_boot_env_of_match_table[] = {
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch b/target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch
deleted file mode 100644
index 70abc7cf14..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From a832556d23c5a11115f300011a5874d6107a0d62 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:19 +0100
-Subject: [PATCH] nvmem: u-boot-env: use nvmem device helpers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use nvmem_dev_size() and nvmem_device_read() to make this driver less
-mtd dependent.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-4-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 23 +++++++++++++++--------
- 1 file changed, 15 insertions(+), 8 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -127,27 +127,34 @@ static int u_boot_env_add_cells(struct u
-
- static int u_boot_env_parse(struct u_boot_env *priv)
- {
-+ struct nvmem_device *nvmem = priv->nvmem;
- struct device *dev = priv->dev;
- size_t crc32_data_offset;
- size_t crc32_data_len;
- size_t crc32_offset;
- size_t data_offset;
- size_t data_len;
-+ size_t dev_size;
- uint32_t crc32;
- uint32_t calc;
-- size_t bytes;
- uint8_t *buf;
-+ int bytes;
- int err;
-
-- buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
-+ dev_size = nvmem_dev_size(nvmem);
-+
-+ buf = kcalloc(1, dev_size, GFP_KERNEL);
- if (!buf) {
- err = -ENOMEM;
- goto err_out;
- }
-
-- err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
-- if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
-- dev_err(dev, "Failed to read from mtd: %d\n", err);
-+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
-+ if (bytes < 0) {
-+ err = bytes;
-+ goto err_kfree;
-+ } else if (bytes != dev_size) {
-+ err = -EIO;
- goto err_kfree;
- }
-
-@@ -169,8 +176,8 @@ static int u_boot_env_parse(struct u_boo
- break;
- }
- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-- crc32_data_len = priv->mtd->size - crc32_data_offset;
-- data_len = priv->mtd->size - data_offset;
-+ crc32_data_len = dev_size - crc32_data_offset;
-+ data_len = dev_size - data_offset;
-
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
- if (calc != crc32) {
-@@ -179,7 +186,7 @@ static int u_boot_env_parse(struct u_boo
- goto err_kfree;
- }
-
-- buf[priv->mtd->size - 1] = '\0';
-+ buf[dev_size - 1] = '\0';
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
- if (err)
- dev_err(dev, "Failed to add cells: %d\n", err);
diff --git a/target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch b/target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch
deleted file mode 100644
index 273cfed874..0000000000
--- a/target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 6bafe07c930676d6430be471310958070816a595 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:20 +0100
-Subject: [PATCH] nvmem: u-boot-env: improve coding style
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Prefer kzalloc() over kcalloc()
- See memory-allocation.rst which says: "to be on the safe side it's
- best to use routines that set memory to zero, like kzalloc()"
-2. Drop dev_err() for u_boot_env_add_cells() fail
- It can fail only on -ENOMEM. We don't want to print error then.
-3. Add extra "crc32_addr" variable
- It makes code reading header's crc32 easier to understand / review.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-5-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -132,6 +132,7 @@ static int u_boot_env_parse(struct u_boo
- size_t crc32_data_offset;
- size_t crc32_data_len;
- size_t crc32_offset;
-+ __le32 *crc32_addr;
- size_t data_offset;
- size_t data_len;
- size_t dev_size;
-@@ -143,7 +144,7 @@ static int u_boot_env_parse(struct u_boo
-
- dev_size = nvmem_dev_size(nvmem);
-
-- buf = kcalloc(1, dev_size, GFP_KERNEL);
-+ buf = kzalloc(dev_size, GFP_KERNEL);
- if (!buf) {
- err = -ENOMEM;
- goto err_out;
-@@ -175,7 +176,8 @@ static int u_boot_env_parse(struct u_boo
- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
- break;
- }
-- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-+ crc32_addr = (__le32 *)(buf + crc32_offset);
-+ crc32 = le32_to_cpu(*crc32_addr);
- crc32_data_len = dev_size - crc32_data_offset;
- data_len = dev_size - data_offset;
-
-@@ -188,8 +190,6 @@ static int u_boot_env_parse(struct u_boo
-
- buf[dev_size - 1] = '\0';
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
-- if (err)
-- dev_err(dev, "Failed to add cells: %d\n", err);
-
- err_kfree:
- kfree(buf);
diff --git a/target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch b/target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch
deleted file mode 100644
index 8b6d3e79e7..0000000000
--- a/target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From ec18a2a83b8b9f7e39c80105ea148c769c46227b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 17 Jan 2024 16:17:36 +0100
-Subject: [PATCH] dt-bindings: leds: Add FUNCTION defines for per-band WLANs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Most wireless routers and access points can operate in multiple bands
-simultaneously. Vendors often equip their devices with per-band LEDs.
-
-Add defines for those very common functions to allow cleaner & clearer
-bindings.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20240117151736.27440-1-zajec5@gmail.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- include/dt-bindings/leds/common.h | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -94,6 +94,9 @@
- #define LED_FUNCTION_USB "usb"
- #define LED_FUNCTION_WAN "wan"
- #define LED_FUNCTION_WLAN "wlan"
-+#define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz"
-+#define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz"
-+#define LED_FUNCTION_WLAN_6GHZ "wlan-6ghz"
- #define LED_FUNCTION_WPS "wps"
-
- #endif /* __DT_BINDINGS_LEDS_H */
diff --git a/target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch b/target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch
deleted file mode 100644
index c1399ce307..0000000000
--- a/target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 64e558500d2d04878b8a6d6578850c475171d6ba Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 23 Feb 2024 12:22:23 +0100
-Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_WAN_ONLINE for Internet
- access
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's common for routers to have LED indicating link on the WAN port.
-
-Some devices however have an extra LED that's meant to be used if WAN
-connection is actually "online" (there is Internet access available).
-
-It was suggested to add #define for such use case.
-
-Link: https://lore.kernel.org/linux-devicetree/80e92209-5578-44e7-bd4b-603a29053ddf@collabora.com/T/#u
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20240223112223.1368-1-zajec5@gmail.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- include/dt-bindings/leds/common.h | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -93,6 +93,7 @@
- #define LED_FUNCTION_TX "tx"
- #define LED_FUNCTION_USB "usb"
- #define LED_FUNCTION_WAN "wan"
-+#define LED_FUNCTION_WAN_ONLINE "wan-online"
- #define LED_FUNCTION_WLAN "wlan"
- #define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz"
- #define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz"
diff --git a/target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch b/target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch
deleted file mode 100644
index e9d692b651..0000000000
--- a/target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From d3115128bdafb62628ab41861a4f06f6d02ac320 Mon Sep 17 00:00:00 2001
-From: Lech Perczak <lech.perczak@gmail.com>
-Date: Mon, 10 Jan 2022 23:48:44 +0100
-Subject: MIPS: ath79: drop _machine_restart again
-
-Commit 81424d0ad0d4 ("MIPS: ath79: Use the reset controller to restart
-OF machines") removed setup of _machine_restart on OF machines to use
-reset handler in reset controller driver.
-While removing remnants of non-OF machines in commit 3a77e0d75eed
-("MIPS: ath79: drop machfiles"), this was introduced again, making it
-impossible to use additional restart handlers registered through device
-tree. Drop setting _machine_restart altogether, and ath79_restart
-function, which is no longer used after this.
-
-Fixes: 3a77e0d75eed ("MIPS: ath79: drop machfiles")
-Cc: John Crispin <john@phrozen.org>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/ath79/setup.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
---- a/arch/mips/ath79/setup.c
-+++ b/arch/mips/ath79/setup.c
-@@ -34,15 +34,6 @@
-
- static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
-
--static void ath79_restart(char *command)
--{
-- local_irq_disable();
-- ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
-- for (;;)
-- if (cpu_wait)
-- cpu_wait();
--}
--
- static void ath79_halt(void)
- {
- while (1)
-@@ -234,7 +225,6 @@ void __init plat_mem_setup(void)
-
- detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
-
-- _machine_restart = ath79_restart;
- _machine_halt = ath79_halt;
- pm_power_off = ath79_halt;
- }
diff --git a/target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch b/target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch
deleted file mode 100644
index fabf177628..0000000000
--- a/target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 31d8f414e1596ba54a4315418e4c0086fda9e428 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Fri, 18 Feb 2022 10:06:43 +0100
-Subject: hwmon: (lm70) Add ti,tmp125 support
-
-The TMP125 is a 2 degree Celsius accurate Digital
-Temperature Sensor with a SPI interface.
-
-The temperature register is a 16-bit, read-only register.
-The MSB (Bit 15) is a leading zero and never set. Bits 14
-to 5 are the 1+9 temperature data bits in a two's
-complement format. Bits 4 to 0 are useless copies of
-Bit 5 value and therefore ignored.
-
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/43b19cbd4e7f51e9509e561b02b5d8d0e7079fac.1645175187.git.chunkeey@gmail.com
-Signed-off-by: Guenter Roeck <linux@roeck-us.net>
----
---- a/drivers/hwmon/lm70.c
-+++ b/drivers/hwmon/lm70.c
-@@ -34,6 +34,7 @@
- #define LM70_CHIP_LM71 2 /* NS LM71 */
- #define LM70_CHIP_LM74 3 /* NS LM74 */
- #define LM70_CHIP_TMP122 4 /* TI TMP122/TMP124 */
-+#define LM70_CHIP_TMP125 5 /* TI TMP125 */
-
- struct lm70 {
- struct spi_device *spi;
-@@ -87,6 +88,12 @@ static ssize_t temp1_input_show(struct d
- * LM71:
- * 14 bits of 2's complement data, discard LSB 2 bits,
- * resolution 0.0312 degrees celsius.
-+ *
-+ * TMP125:
-+ * MSB/D15 is a leading zero. D14 is the sign-bit. This is
-+ * followed by 9 temperature bits (D13..D5) in 2's complement
-+ * data format with a resolution of 0.25 degrees celsius per unit.
-+ * LSB 5 bits (D4..D0) share the same value as D5 and get discarded.
- */
- switch (p_lm70->chip) {
- case LM70_CHIP_LM70:
-@@ -102,6 +109,10 @@ static ssize_t temp1_input_show(struct d
- case LM70_CHIP_LM71:
- val = ((int)raw / 4) * 3125 / 100;
- break;
-+
-+ case LM70_CHIP_TMP125:
-+ val = (sign_extend32(raw, 14) / 32) * 250;
-+ break;
- }
-
- status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
-@@ -136,6 +147,10 @@ static const struct of_device_id lm70_of
- .data = (void *) LM70_CHIP_TMP122,
- },
- {
-+ .compatible = "ti,tmp125",
-+ .data = (void *) LM70_CHIP_TMP125,
-+ },
-+ {
- .compatible = "ti,lm71",
- .data = (void *) LM70_CHIP_LM71,
- },
-@@ -184,6 +199,7 @@ static const struct spi_device_id lm70_i
- { "lm70", LM70_CHIP_LM70 },
- { "tmp121", LM70_CHIP_TMP121 },
- { "tmp122", LM70_CHIP_TMP122 },
-+ { "tmp125", LM70_CHIP_TMP125 },
- { "lm71", LM70_CHIP_LM71 },
- { "lm74", LM70_CHIP_LM74 },
- { },
diff --git a/target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch b/target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch
deleted file mode 100644
index 39fdb32773..0000000000
--- a/target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From a79a5613e1907e1bf09bb6ba6fd5ff43b66c1afe Mon Sep 17 00:00:00 2001
-From: Lech Perczak <lech.perczak@gmail.com>
-Date: Fri, 1 Apr 2022 22:03:55 +0200
-Subject: [PATCH 1/3] cdc_ether: export usbnet_cdc_zte_rx_fixup
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Commit bfe9b9d2df66 ("cdc_ether: Improve ZTE MF823/831/910 handling")
-introduces a workaround for certain ZTE modems reporting invalid MAC
-addresses over CDC-ECM.
-The same issue was present on their RNDIS interface,which was fixed in
-commit a5a18bdf7453 ("rndis_host: Set valid random MAC on buggy devices").
-
-However, internal modem of ZTE MF286R router, on its RNDIS interface, also
-exhibits a second issue fixed already in CDC-ECM, of the device not
-respecting configured random MAC address. In order to share the fixup for
-this with rndis_host driver, export the workaround function, which will
-be re-used in the following commit in rndis_host.
-
-Cc: Kristian Evensen <kristian.evensen@gmail.com>
-Cc: Bjørn Mork <bjorn@mork.no>
-Cc: Oliver Neukum <oliver@neukum.org>
-Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
----
- drivers/net/usb/cdc_ether.c | 3 ++-
- include/linux/usb/usbnet.h | 1 +
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/net/usb/cdc_ether.c
-+++ b/drivers/net/usb/cdc_ether.c
-@@ -479,7 +479,7 @@ static int usbnet_cdc_zte_bind(struct us
- * device MAC address has been updated). Always set MAC address to that of the
- * device.
- */
--static int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-+int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
- {
- if (skb->len < ETH_HLEN || !(skb->data[0] & 0x02))
- return 1;
-@@ -489,6 +489,7 @@ static int usbnet_cdc_zte_rx_fixup(struc
-
- return 1;
- }
-+EXPORT_SYMBOL_GPL(usbnet_cdc_zte_rx_fixup);
-
- /* Ensure correct link state
- *
---- a/include/linux/usb/usbnet.h
-+++ b/include/linux/usb/usbnet.h
-@@ -214,6 +214,7 @@ extern int usbnet_ether_cdc_bind(struct
- extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *);
- extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
- extern void usbnet_cdc_status(struct usbnet *, struct urb *);
-+extern int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
-
- /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
- #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
diff --git a/target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch b/target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch
deleted file mode 100644
index 71a6df8102..0000000000
--- a/target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From aa8aff10e969aca0cb64f5e54ff7489355582667 Mon Sep 17 00:00:00 2001
-From: Lech Perczak <lech.perczak@gmail.com>
-Date: Fri, 1 Apr 2022 22:04:01 +0200
-Subject: [PATCH 2/3] rndis_host: enable the bogus MAC fixup for ZTE devices
- from cdc_ether
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Certain ZTE modems, namely: MF823. MF831, MF910, built-in modem from
-MF286R, expose both CDC-ECM and RNDIS network interfaces.
-They have a trait of ignoring the locally-administered MAC address
-configured on the interface both in CDC-ECM and RNDIS part,
-and this leads to dropping of incoming traffic by the host.
-However, the workaround was only present in CDC-ECM, and MF286R
-explicitly requires it in RNDIS mode.
-
-Re-use the workaround in rndis_host as well, to fix operation of MF286R
-module, some versions of which expose only the RNDIS interface. Do so by
-introducing new flag, RNDIS_DRIVER_DATA_DST_MAC_FIXUP, and testing for it
-in rndis_rx_fixup. This is required, as RNDIS uses frame batching, and all
-of the packets inside the batch need the fixup. This might introduce a
-performance penalty, because test is done for every returned Ethernet
-frame.
-
-Apply the workaround to both "flavors" of RNDIS interfaces, as older ZTE
-modems, like MF823 found in the wild, report the USB_CLASS_COMM class
-interfaces, while MF286R reports USB_CLASS_WIRELESS_CONTROLLER.
-
-Suggested-by: Bjørn Mork <bjorn@mork.no>
-Cc: Kristian Evensen <kristian.evensen@gmail.com>
-Cc: Oliver Neukum <oliver@neukum.org>
-Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
----
- drivers/net/usb/rndis_host.c | 32 ++++++++++++++++++++++++++++++++
- include/linux/usb/rndis_host.h | 1 +
- 2 files changed, 33 insertions(+)
-
---- a/drivers/net/usb/rndis_host.c
-+++ b/drivers/net/usb/rndis_host.c
-@@ -486,10 +486,14 @@ EXPORT_SYMBOL_GPL(rndis_unbind);
- */
- int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
- {
-+ bool dst_mac_fixup;
-+
- /* This check is no longer done by usbnet */
- if (skb->len < dev->net->hard_header_len)
- return 0;
-
-+ dst_mac_fixup = !!(dev->driver_info->data & RNDIS_DRIVER_DATA_DST_MAC_FIXUP);
-+
- /* peripheral may have batched packets to us... */
- while (likely(skb->len)) {
- struct rndis_data_hdr *hdr = (void *)skb->data;
-@@ -524,10 +528,17 @@ int rndis_rx_fixup(struct usbnet *dev, s
- break;
- skb_pull(skb, msg_len - sizeof *hdr);
- skb_trim(skb2, data_len);
-+
-+ if (unlikely(dst_mac_fixup))
-+ usbnet_cdc_zte_rx_fixup(dev, skb2);
-+
- usbnet_skb_return(dev, skb2);
- }
-
- /* caller will usbnet_skb_return the remaining packet */
-+ if (unlikely(dst_mac_fixup))
-+ usbnet_cdc_zte_rx_fixup(dev, skb);
-+
- return 1;
- }
- EXPORT_SYMBOL_GPL(rndis_rx_fixup);
-@@ -601,6 +612,17 @@ static const struct driver_info rndis_po
- .tx_fixup = rndis_tx_fixup,
- };
-
-+static const struct driver_info zte_rndis_info = {
-+ .description = "ZTE RNDIS device",
-+ .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
-+ .data = RNDIS_DRIVER_DATA_DST_MAC_FIXUP,
-+ .bind = rndis_bind,
-+ .unbind = rndis_unbind,
-+ .status = rndis_status,
-+ .rx_fixup = rndis_rx_fixup,
-+ .tx_fixup = rndis_tx_fixup,
-+};
-+
- /*-------------------------------------------------------------------------*/
-
- static const struct usb_device_id products [] = {
-@@ -615,6 +637,16 @@ static const struct usb_device_id produc
- USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
- .driver_info = (unsigned long)&rndis_info,
- }, {
-+ /* ZTE WWAN modules */
-+ USB_VENDOR_AND_INTERFACE_INFO(0x19d2,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long)&zte_rndis_info,
-+}, {
-+ /* ZTE WWAN modules, ACM flavour */
-+ USB_VENDOR_AND_INTERFACE_INFO(0x19d2,
-+ USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
-+ .driver_info = (unsigned long)&zte_rndis_info,
-+}, {
- /* RNDIS is MSFT's un-official variant of CDC ACM */
- USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
- .driver_info = (unsigned long) &rndis_info,
---- a/include/linux/usb/rndis_host.h
-+++ b/include/linux/usb/rndis_host.h
-@@ -197,6 +197,7 @@ struct rndis_keepalive_c { /* IN (option
-
- /* Flags for driver_info::data */
- #define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */
-+#define RNDIS_DRIVER_DATA_DST_MAC_FIXUP 2 /* device ignores configured MAC address */
-
- extern void rndis_status(struct usbnet *dev, struct urb *urb);
- extern int
diff --git a/target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch b/target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch
deleted file mode 100644
index bdd812cc90..0000000000
--- a/target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 9bfb4bcda7ba32d73ea322ea56a8ebe32e9247f6 Mon Sep 17 00:00:00 2001
-From: Lech Perczak <lech.perczak@gmail.com>
-Date: Sat, 2 Apr 2022 02:19:57 +0200
-Subject: [PATCH 3/3] rndis_host: limit scope of bogus MAC address detection to
- ZTE devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Reporting of bogus MAC addresses and ignoring configuration of new
-destination address wasn't observed outside of a range of ZTE devices,
-among which this seems to be the common bug. Align rndis_host driver
-with implementation found in cdc_ether, which also limits this workaround
-to ZTE devices.
-
-Suggested-by: Bjørn Mork <bjorn@mork.no>
-Cc: Kristian Evensen <kristian.evensen@gmail.com>
-Cc: Oliver Neukum <oliver@neukum.org>
-Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
----
- drivers/net/usb/rndis_host.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
---- a/drivers/net/usb/rndis_host.c
-+++ b/drivers/net/usb/rndis_host.c
-@@ -419,10 +419,7 @@ generic_rndis_bind(struct usbnet *dev, s
- goto halt_fail_and_release;
- }
-
-- if (bp[0] & 0x02)
-- eth_hw_addr_random(net);
-- else
-- ether_addr_copy(net->dev_addr, bp);
-+ ether_addr_copy(net->dev_addr, bp);
-
- /* set a nonzero filter to enable data transfers */
- memset(u.set, 0, sizeof *u.set);
-@@ -464,6 +461,16 @@ static int rndis_bind(struct usbnet *dev
- return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS);
- }
-
-+static int zte_rndis_bind(struct usbnet *dev, struct usb_interface *intf)
-+{
-+ int status = rndis_bind(dev, intf);
-+
-+ if (!status && (dev->net->dev_addr[0] & 0x02))
-+ eth_hw_addr_random(dev->net);
-+
-+ return status;
-+}
-+
- void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
- {
- struct rndis_halt *halt;
-@@ -616,7 +623,7 @@ static const struct driver_info zte_rndi
- .description = "ZTE RNDIS device",
- .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
- .data = RNDIS_DRIVER_DATA_DST_MAC_FIXUP,
-- .bind = rndis_bind,
-+ .bind = zte_rndis_bind,
- .unbind = rndis_unbind,
- .status = rndis_status,
- .rx_fixup = rndis_rx_fixup,
diff --git a/target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch b/target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch
deleted file mode 100644
index 38fbc3a3d7..0000000000
--- a/target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From dbf70fc204d2fbb0d8ad8f42038a60846502efda Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Mon, 10 Oct 2022 13:51:09 +0300
-Subject: [PATCH] mtd: spinand: winbond: fix flash identification
-
-Winbond uses 3 bytes to identify flash: vendor_id, dev_id_0, dev_id_1,
-but current driver uses only first 2 bytes of it for devices
-identification. As result Winbond W25N02KV flash (id_bytes: EF, AA, 22)
-is identified as W25N01GV (id_bytes: EF, AA, 21).
-
-Fix this by adding missed identification bytes.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-1-mikhail.kshevetskiy@iopsys.eu
----
- drivers/mtd/nand/spi/winbond.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/nand/spi/winbond.c
-+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct
-
- static const struct spinand_info winbond_spinand_table[] = {
- SPINAND_INFO("W25M02GV",
-- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab),
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
- NAND_ECCREQ(1, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -86,7 +86,7 @@ static const struct spinand_info winbond
- SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
- SPINAND_SELECT_TARGET(w25m02gv_select_target)),
- SPINAND_INFO("W25N01GV",
-- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa),
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(1, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
diff --git a/target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch b/target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch
deleted file mode 100644
index d75a1acc57..0000000000
--- a/target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 6154c7a583483d7b69f53bea868efdc369edd563 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Mon, 10 Oct 2022 13:51:10 +0300
-Subject: [PATCH] mtd: spinand: winbond: add Winbond W25N02KV flash support
-
-Add support of Winbond W25N02KV flash
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-2-mikhail.kshevetskiy@iopsys.eu
----
- drivers/mtd/nand/spi/winbond.c | 75 ++++++++++++++++++++++++++++++++++
- 1 file changed, 75 insertions(+)
-
---- a/drivers/mtd/nand/spi/winbond.c
-+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -74,6 +74,72 @@ static int w25m02gv_select_target(struct
- return spi_mem_exec_op(spinand->spimem, &op);
- }
-
-+static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = 64 + (16 * section);
-+ region->length = 13;
-+
-+ return 0;
-+}
-+
-+static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = (16 * section) + 2;
-+ region->length = 14;
-+
-+ return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
-+ .ecc = w25n02kv_ooblayout_ecc,
-+ .free = w25n02kv_ooblayout_free,
-+};
-+
-+static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
-+ u8 status)
-+{
-+ struct nand_device *nand = spinand_to_nand(spinand);
-+ u8 mbf = 0;
-+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
-+
-+ switch (status & STATUS_ECC_MASK) {
-+ case STATUS_ECC_NO_BITFLIPS:
-+ return 0;
-+
-+ case STATUS_ECC_UNCOR_ERROR:
-+ return -EBADMSG;
-+
-+ case STATUS_ECC_HAS_BITFLIPS:
-+ /*
-+ * Let's try to retrieve the real maximum number of bitflips
-+ * in order to avoid forcing the wear-leveling layer to move
-+ * data around if it's not necessary.
-+ */
-+ if (spi_mem_exec_op(spinand->spimem, &op))
-+ return nanddev_get_ecc_conf(nand)->strength;
-+
-+ mbf >>= 4;
-+
-+ if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
-+ return nanddev_get_ecc_conf(nand)->strength;
-+
-+ return mbf;
-+
-+ default:
-+ break;
-+ }
-+
-+ return -EINVAL;
-+}
-+
- static const struct spinand_info winbond_spinand_table[] = {
- SPINAND_INFO("W25M02GV",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
-@@ -94,6 +160,15 @@ static const struct spinand_info winbond
- &update_cache_variants),
- 0,
- SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
-+ SPINAND_INFO("W25N02KV",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
- };
-
- static int winbond_spinand_init(struct spinand_device *spinand)
diff --git a/target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch b/target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch
deleted file mode 100644
index 2f408f5a30..0000000000
--- a/target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From f5a05060670a4d8d6523afc7963eb559c2e3615f Mon Sep 17 00:00:00 2001
-From: Olivier Maignial <olivier.maignial@hotmail.fr>
-Date: Fri, 23 Jun 2023 17:33:37 +0200
-Subject: [PATCH] mtd: spinand: winbond: Fix ecc_get_status
-
-Reading ECC status is failing.
-
-w25n02kv_ecc_get_status() is using on-stack buffer for
-SPINAND_GET_FEATURE_OP() output. It is not suitable for
-DMA needs of spi-mem.
-
-Fix this by using the spi-mem operations dedicated buffer
-spinand->scratchbuf.
-
-See
-spinand->scratchbuf:
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/mtd/spinand.h?h=v6.3#n418
-spi_mem_check_op():
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-mem.c?h=v6.3#n199
-
-Fixes: 6154c7a58348 ("mtd: spinand: winbond: add Winbond W25N02KV flash support")
-Cc: stable@vger.kernel.org
-Signed-off-by: Olivier Maignial <olivier.maignial@hotmail.fr>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/DB4P250MB1032EDB9E36B764A33769039FE23A@DB4P250MB1032.EURP250.PROD.OUTLOOK.COM
----
- drivers/mtd/nand/spi/winbond.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/nand/spi/winbond.c
-+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struc
- {
- struct nand_device *nand = spinand_to_nand(spinand);
- u8 mbf = 0;
-- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
-+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf);
-
- switch (status & STATUS_ECC_MASK) {
- case STATUS_ECC_NO_BITFLIPS:
-@@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(struc
- if (spi_mem_exec_op(spinand->spimem, &op))
- return nanddev_get_ecc_conf(nand)->strength;
-
-- mbf >>= 4;
-+ mbf = *(spinand->scratchbuf) >> 4;
-
- if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
- return nanddev_get_ecc_conf(nand)->strength;
diff --git a/target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch b/target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch
deleted file mode 100644
index 177a8ce43e..0000000000
--- a/target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 19f291d8a65cd19e7595006c7872cd95aa6f9e93 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Fri, 4 Aug 2023 19:13:10 +0200
-Subject: [PATCH 893/898] net: dsa: mv88e6xxx: pass directly chip structure to
- mv88e6xxx_phy_is_internal
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Since this function is a simple helper, we do not need to pass a full
-dsa_switch structure, we can directly pass the mv88e6xxx_chip structure.
-Doing so will allow to share this function with any other function
-not manipulating dsa_switch structure but needing info about number of
-internal phys
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -459,10 +459,8 @@ restore_link:
- return err;
- }
-
--static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
-+static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port)
- {
-- struct mv88e6xxx_chip *chip = ds->priv;
--
- return port < chip->info->num_internal_phys;
- }
-
-@@ -704,7 +702,7 @@ static void mv88e6xxx_mac_config(struct
-
- mv88e6xxx_reg_lock(chip);
-
-- if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
-+ if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, port)) {
- /* In inband mode, the link may come up at any time while the
- * link is not forced down. Force the link down while we
- * reconfigure the interface mode.
diff --git a/target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch b/target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch
deleted file mode 100644
index 02cafa3765..0000000000
--- a/target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 03a50b4f81d9e8bcf86165d6b2ac9376d02e5df9 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:42 +0200
-Subject: [PATCH 894/898] net: dsa: mv88e6xxx: use mv88e6xxx_phy_is_internal in
- mv88e6xxx_port_ppu_updates
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Make sure to use existing helper to get internal PHYs count instead of
-redoing it manually
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -473,7 +473,7 @@ static int mv88e6xxx_port_ppu_updates(st
- * report whether the port is internal.
- */
- if (chip->info->family == MV88E6XXX_FAMILY_6250)
-- return port < chip->info->num_internal_phys;
-+ return mv88e6xxx_phy_is_internal(chip, port);
-
- err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
- if (err) {
diff --git a/target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch b/target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch
deleted file mode 100644
index 239620b686..0000000000
--- a/target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 07120894b24cc3cf2318925baeaaf0893e3312e4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:43 +0200
-Subject: [PATCH 895/898] net: dsa: mv88e6xxx: add field to specify internal
- phys layout
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-mv88e6xxx currently assumes that switch equipped with internal phys have
-those phys mapped contiguously starting from port 0 (see
-mv88e6xxx_phy_is_internal). However, some switches have internal PHYs but
-NOT starting from port 0. For example 88e6393X, 88E6193X and 88E6191X have
-integrated PHYs available on ports 1 to 8
-To properly support this offset, add a new field to allow specifying an
-internal PHYs layout. If field is not set, default layout is assumed (start
-at port 0)
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 4 +++-
- drivers/net/dsa/mv88e6xxx/chip.h | 5 +++++
- drivers/net/dsa/mv88e6xxx/global2.c | 5 ++++-
- 3 files changed, 12 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -461,7 +461,9 @@ restore_link:
-
- static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port)
- {
-- return port < chip->info->num_internal_phys;
-+ return port >= chip->info->internal_phys_offset &&
-+ port < chip->info->num_internal_phys +
-+ chip->info->internal_phys_offset;
- }
-
- static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
---- a/drivers/net/dsa/mv88e6xxx/chip.h
-+++ b/drivers/net/dsa/mv88e6xxx/chip.h
-@@ -165,6 +165,11 @@ struct mv88e6xxx_info {
-
- /* Supports PTP */
- bool ptp_support;
-+
-+ /* Internal PHY start index. 0 means that internal PHYs range starts at
-+ * port 0, 1 means internal PHYs range starts at port 1, etc
-+ */
-+ unsigned int internal_phys_offset;
- };
-
- struct mv88e6xxx_atu_entry {
---- a/drivers/net/dsa/mv88e6xxx/global2.c
-+++ b/drivers/net/dsa/mv88e6xxx/global2.c
-@@ -1185,8 +1185,11 @@ int mv88e6xxx_g2_irq_mdio_setup(struct m
- struct mii_bus *bus)
- {
- int phy, irq, err, err_phy;
-+ int phy_start = chip->info->internal_phys_offset;
-+ int phy_end = chip->info->internal_phys_offset +
-+ chip->info->num_internal_phys;
-
-- for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
-+ for (phy = phy_start; phy < phy_end; phy++) {
- irq = irq_find_mapping(chip->g2_irq.domain, phy);
- if (irq < 0) {
- err = irq;
diff --git a/target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch b/target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch
deleted file mode 100644
index 8aa498046d..0000000000
--- a/target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 492b06747f544c19b5ffe531a24b67858764c50e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:44 +0200
-Subject: [PATCH 896/898] net: dsa: mv88e6xxx: fix 88E6393X family internal
- phys layout
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-88E6393X/88E6193X/88E6191X switches have in fact 8 internal PHYs, but those
-are not present starting at port 0: supported ports go from 1 to 8
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -5372,7 +5372,8 @@ static const struct mv88e6xxx_info mv88e
- .name = "Marvell 88E6191X",
- .num_databases = 4096,
- .num_ports = 11, /* 10 + Z80 */
-- .num_internal_phys = 9,
-+ .num_internal_phys = 8,
-+ .internal_phys_offset = 1,
- .max_vid = 8191,
- .port_base_addr = 0x0,
- .phy_base_addr = 0x0,
-@@ -5394,7 +5395,8 @@ static const struct mv88e6xxx_info mv88e
- .name = "Marvell 88E6193X",
- .num_databases = 4096,
- .num_ports = 11, /* 10 + Z80 */
-- .num_internal_phys = 9,
-+ .num_internal_phys = 8,
-+ .internal_phys_offset = 1,
- .max_vid = 8191,
- .port_base_addr = 0x0,
- .phy_base_addr = 0x0,
-@@ -5704,7 +5706,8 @@ static const struct mv88e6xxx_info mv88e
- .name = "Marvell 88E6393X",
- .num_databases = 4096,
- .num_ports = 11, /* 10 + Z80 */
-- .num_internal_phys = 9,
-+ .num_internal_phys = 8,
-+ .internal_phys_offset = 1,
- .max_vid = 8191,
- .port_base_addr = 0x0,
- .phy_base_addr = 0x0,
diff --git a/target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch b/target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch
deleted file mode 100644
index f4de58ac32..0000000000
--- a/target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 68690045f8e220826517c0d6f9388ffc1faa57ea Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:45 +0200
-Subject: [PATCH 897/898] net: dsa: mv88e6xxx: pass mv88e6xxx_chip structure to
- port_max_speed_mode
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some switches families have minor differences on supported link speed for
-ports. Instead of redefining a new port_max_speed_mode for each different
-configuration, allow to pass mv88e6xxx_chip structure to allow
-differentiating those chips by known chip id
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Update one more instance of port_max_speed_mode that 5.15 has.
-[Robert Marko]
-Signed-off-by: Robert Marko <robimarko@gmail.com>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
- drivers/net/dsa/mv88e6xxx/chip.h | 3 ++-
- drivers/net/dsa/mv88e6xxx/port.c | 12 ++++++++----
- drivers/net/dsa/mv88e6xxx/port.h | 12 ++++++++----
- 4 files changed, 19 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -443,7 +443,7 @@ static int mv88e6xxx_port_setup_mac(stru
- }
-
- if (speed == SPEED_MAX && chip->info->ops->port_max_speed_mode)
-- mode = chip->info->ops->port_max_speed_mode(port);
-+ mode = chip->info->ops->port_max_speed_mode(chip, port);
-
- if (chip->info->ops->port_set_pause) {
- err = chip->info->ops->port_set_pause(chip, port, pause);
---- a/drivers/net/dsa/mv88e6xxx/chip.h
-+++ b/drivers/net/dsa/mv88e6xxx/chip.h
-@@ -485,7 +485,8 @@ struct mv88e6xxx_ops {
- int speed, int duplex);
-
- /* What interface mode should be used for maximum speed? */
-- phy_interface_t (*port_max_speed_mode)(int port);
-+ phy_interface_t (*port_max_speed_mode)(struct mv88e6xxx_chip *chip,
-+ int port);
-
- int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
-
---- a/drivers/net/dsa/mv88e6xxx/port.c
-+++ b/drivers/net/dsa/mv88e6xxx/port.c
-@@ -357,7 +357,8 @@ int mv88e6341_port_set_speed_duplex(stru
- duplex);
- }
-
--phy_interface_t mv88e6341_port_max_speed_mode(int port)
-+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 5)
- return PHY_INTERFACE_MODE_2500BASEX;
-@@ -402,7 +403,8 @@ int mv88e6390_port_set_speed_duplex(stru
- duplex);
- }
-
--phy_interface_t mv88e6390_port_max_speed_mode(int port)
-+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 9 || port == 10)
- return PHY_INTERFACE_MODE_2500BASEX;
-@@ -427,7 +429,8 @@ int mv88e6390x_port_set_speed_duplex(str
- duplex);
- }
-
--phy_interface_t mv88e6390x_port_max_speed_mode(int port)
-+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 9 || port == 10)
- return PHY_INTERFACE_MODE_XAUI;
-@@ -527,7 +530,8 @@ int mv88e6393x_port_set_speed_duplex(str
- return 0;
- }
-
--phy_interface_t mv88e6393x_port_max_speed_mode(int port)
-+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 0 || port == 9 || port == 10)
- return PHY_INTERFACE_MODE_10GBASER;
---- a/drivers/net/dsa/mv88e6xxx/port.h
-+++ b/drivers/net/dsa/mv88e6xxx/port.h
-@@ -350,10 +350,14 @@ int mv88e6390x_port_set_speed_duplex(str
- int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
- int speed, int duplex);
-
--phy_interface_t mv88e6341_port_max_speed_mode(int port);
--phy_interface_t mv88e6390_port_max_speed_mode(int port);
--phy_interface_t mv88e6390x_port_max_speed_mode(int port);
--phy_interface_t mv88e6393x_port_max_speed_mode(int port);
-+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-
- int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state);
-
diff --git a/target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch b/target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch
deleted file mode 100644
index d86adf034e..0000000000
--- a/target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From f318a015330a11befd8c69336efc6284e240f535 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:46 +0200
-Subject: [PATCH 898/898] net: dsa: mv88e6xxx: enable support for 88E6361
- switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Marvell 88E6361 is an 8-port switch derived from the
-88E6393X/88E9193X/88E6191X switches family. It can benefit from the
-existing mv88e6xxx driver by simply adding the proper switch description in
-the driver. Main differences with other switches from this
-family are:
-- 8 ports exposed (instead of 11): ports 1, 2 and 8 not available
-- No 5GBase-x nor SFI/USXGMII support
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Adapt to 5.15 since we dont have phylink_get_caps yet.
-So, update the old mv88e6393x_phylink_validate instead.
-Remove max_sid since 5.15 driver does not support it yet.
-[Robert Marko]
-Signed-off-by: Robert Marko <robimarko@gmail.com>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 49 +++++++++++++++++++++++++++++++-
- drivers/net/dsa/mv88e6xxx/chip.h | 3 +-
- drivers/net/dsa/mv88e6xxx/port.c | 14 +++++++--
- drivers/net/dsa/mv88e6xxx/port.h | 1 +
- 4 files changed, 62 insertions(+), 5 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -648,6 +648,8 @@ static void mv88e6393x_phylink_validate(
- {
- bool is_6191x =
- chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
-+ bool is_6361 =
-+ chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361;
-
- if (((port == 0 || port == 9) && !is_6191x) || port == 10) {
- phylink_set(mask, 10000baseT_Full);
-@@ -662,8 +664,28 @@ static void mv88e6393x_phylink_validate(
- phylink_set(mask, 2500baseT_Full);
- }
-
-+ if (port == 0 || port == 9 || port == 10) {
-+ phylink_set(mask, 1000baseX_Full);
-+
-+ /* 6191X supports >1G modes only on port 10 */
-+ if (!is_6191x || port == 10) {
-+ phylink_set(mask, 2500baseX_Full);
-+ phylink_set(mask, 2500baseT_Full);
-+
-+ if (!is_6361) {
-+ phylink_set(mask, 10000baseT_Full);
-+ phylink_set(mask, 10000baseKR_Full);
-+ phylink_set(mask, 10000baseCR_Full);
-+ phylink_set(mask, 10000baseSR_Full);
-+ phylink_set(mask, 10000baseLR_Full);
-+ phylink_set(mask, 10000baseLRM_Full);
-+ phylink_set(mask, 10000baseER_Full);
-+ phylink_set(mask, 5000baseT_Full);
-+ }
-+ }
-+ }
-+
- phylink_set(mask, 1000baseT_Full);
-- phylink_set(mask, 1000baseX_Full);
-
- mv88e6065_phylink_validate(chip, port, mask, state);
- }
-@@ -5651,6 +5673,31 @@ static const struct mv88e6xxx_info mv88e
- .ptp_support = true,
- .ops = &mv88e6352_ops,
- },
-+ [MV88E6361] = {
-+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
-+ .family = MV88E6XXX_FAMILY_6393,
-+ .name = "Marvell 88E6361",
-+ .num_databases = 4096,
-+ .num_macs = 16384,
-+ .num_ports = 11,
-+ /* Ports 1, 2 and 8 are not routed */
-+ .invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
-+ .num_internal_phys = 5,
-+ .internal_phys_offset = 3,
-+ .max_vid = 4095,
-+ .port_base_addr = 0x0,
-+ .phy_base_addr = 0x0,
-+ .global1_addr = 0x1b,
-+ .global2_addr = 0x1c,
-+ .age_time_coeff = 3750,
-+ .g1_irqs = 10,
-+ .g2_irqs = 14,
-+ .atu_move_port_mask = 0x1f,
-+ .pvt = true,
-+ .multi_chip = true,
-+ .ptp_support = true,
-+ .ops = &mv88e6393x_ops,
-+ },
- [MV88E6390] = {
- .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
- .family = MV88E6XXX_FAMILY_6390,
---- a/drivers/net/dsa/mv88e6xxx/chip.h
-+++ b/drivers/net/dsa/mv88e6xxx/chip.h
-@@ -81,6 +81,7 @@ enum mv88e6xxx_model {
- MV88E6350,
- MV88E6351,
- MV88E6352,
-+ MV88E6361,
- MV88E6390,
- MV88E6390X,
- MV88E6393X,
-@@ -99,7 +100,7 @@ enum mv88e6xxx_family {
- MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
- MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */
- MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */
-- MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6393X */
-+ MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6361 6393X */
- };
-
- /**
---- a/drivers/net/dsa/mv88e6xxx/port.c
-+++ b/drivers/net/dsa/mv88e6xxx/port.c
-@@ -451,6 +451,10 @@ int mv88e6393x_port_set_speed_duplex(str
- if (speed == SPEED_MAX)
- speed = (port > 0 && port < 9) ? 1000 : 10000;
-
-+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361 &&
-+ speed > 2500)
-+ return -EOPNOTSUPP;
-+
- if (speed == 200 && port != 0)
- return -EOPNOTSUPP;
-
-@@ -533,10 +537,14 @@ int mv88e6393x_port_set_speed_duplex(str
- phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
- int port)
- {
-- if (port == 0 || port == 9 || port == 10)
-- return PHY_INTERFACE_MODE_10GBASER;
-
-- return PHY_INTERFACE_MODE_NA;
-+ if (port != 0 && port != 9 && port != 10)
-+ return PHY_INTERFACE_MODE_NA;
-+
-+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361)
-+ return PHY_INTERFACE_MODE_2500BASEX;
-+
-+ return PHY_INTERFACE_MODE_10GBASER;
- }
-
- static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
---- a/drivers/net/dsa/mv88e6xxx/port.h
-+++ b/drivers/net/dsa/mv88e6xxx/port.h
-@@ -128,6 +128,7 @@
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6220 0x2200
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500
-+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6361 0x2610
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6141 0x3400
diff --git a/target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch b/target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch
deleted file mode 100644
index 283e226d16..0000000000
--- a/target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From mboxrd@z Thu Jan 1 00:00:00 1970
-Authentication-Results: smtp.subspace.kernel.org;
- dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="sMUeie/T"
-Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84BB8D6D
- for <bpf@vger.kernel.org>; Wed, 6 Dec 2023 15:16:16 -0800 (PST)
-Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-db5416d0fccso403298276.1
- for <bpf@vger.kernel.org>; Wed, 06 Dec 2023 15:16:16 -0800 (PST)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=google.com; s=20230601; t=1701904575; x=1702509375; darn=vger.kernel.org;
- h=cc:to:from:subject:message-id:references:mime-version:in-reply-to
- :date:from:to:cc:subject:date:message-id:reply-to;
- bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=;
- b=sMUeie/TxdytzC0EyT11QWi1TqTtiv7KCTs1F2vLmUUvPKNA3+1MHFo8ECW+0gQuDE
- FGrgdZKGK5mXQgkF0N3JiSLvKO8tpQOIB57JLCG5IVy5dr2vVv0ExU3Dag2Cc4oBIBIO
- w/cH95O1oPlvluIpATmAsxenVr7mFomU63BqYiRGLaEhWeb2hJ636GO8lubtsDfdFFoi
- GPOL2tQwV93VnqmywBBpFaNAULN0UoCFhfkKv5prvpkXq19sWI7zyorVZ+rdTYem5m4T
- dXsDaLXPtC3Dh2JOad1duSQIah/wCHYYUcV3IoFhwj2y0Uk/TTCrnZPORweSADcEy6Ho
- vDrA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20230601; t=1701904575; x=1702509375;
- h=cc:to:from:subject:message-id:references:mime-version:in-reply-to
- :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
- bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=;
- b=Dmc6aSntxPlxAk72zVO1G9WoZnFtLolxENlLscYYAHG3VE+PQ8gGN2rPzcGoKb2Btb
- 4b0PvjOzSlPQyghahdhdlz04RtAeeGG/MkfNiYjFql5OifIoovb51kroiPYrVsa7Ps7Y
- +Pxug0+NPdTm5s9TNz940ZKl3GRME8UTmVxpWJRX03XMOqb6Wgsh2SK9ahXKc4yRsi62
- 3a3J72WmmSgvimxwM/99fXwvoUQpiv2J1xCoqc1Ng4q4qSuZvzmHN7ZTGaUhLxOqLeLK
- 3W4RKHW6rZ7UjppuB6I3NXW+D344By2rdKp1sRXpjdQ0GS3YUcvlRETcJBXJudHfQP5Y
- CLOw==
-X-Gm-Message-State: AOJu0YzdCTLdwny+N99zeMgyKqFsEZhfIhL2cbgKA6zC1U/OLkxxRLoM
- XrYVBC9DmxCGmP4o+M/Z/kHUew/9faHlCiLGxw==
-X-Google-Smtp-Source: AGHT+IFRXxBV6JuX5Cl/k2o1+WKkCwkR8j20MJSkmoGCedPAtqFttH8OVh1/6vdfnq8MPN++A2h89peZQhyG8OsJ8A==
-X-Received: from jstitt-linux1.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:23b5])
- (user=justinstitt job=sendgmr) by 2002:a25:dac7:0:b0:da0:3117:f35 with SMTP
- id n190-20020a25dac7000000b00da031170f35mr28652ybf.3.1701904575576; Wed, 06
- Dec 2023 15:16:15 -0800 (PST)
-Date: Wed, 06 Dec 2023 23:16:10 +0000
-In-Reply-To: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com>
-Precedence: bulk
-X-Mailing-List: bpf@vger.kernel.org
-List-Id: <bpf.vger.kernel.org>
-List-Subscribe: <mailto:bpf+subscribe@vger.kernel.org>
-List-Unsubscribe: <mailto:bpf+unsubscribe@vger.kernel.org>
-Mime-Version: 1.0
-References: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com>
-X-Developer-Key: i=justinstitt@google.com; a=ed25519; pk=tC3hNkJQTpNX/gLKxTNQKDmiQl6QjBNCGKJINqAdJsE=
-X-Developer-Signature: v=1; a=ed25519-sha256; t=1701904573; l=1840;
- i=justinstitt@google.com; s=20230717; h=from:subject:message-id;
- bh=UMdetIL2ZsPIkSodqhw2fM21NHJVjCu0lRImFuNhVoM=; b=a8rMnXfVVQ5gsxHWG4WRMwOLxZgflqXZtNuKx26vv4DwYvvCtCiYjl3f1frOjV/Ul2kaxq5g/
- b/UOv678JKCDASVokxG5GJifAnU7/kqRxdhcwfRkrD8RUfcsmiZOfyF
-X-Mailer: b4 0.12.3
-Message-ID: <20231206-ethtool_puts_impl-v5-1-5a2528e17bf8@google.com>
-Subject: [PATCH net-next v5 1/3] ethtool: Implement ethtool_puts()
-From: justinstitt@google.com
-To: "David S. Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Shay Agroskin <shayagr@amazon.com>,
- Arthur Kiyanovski <akiyano@amazon.com>, David Arinzon <darinzon@amazon.com>, Noam Dagan <ndagan@amazon.com>,
- Saeed Bishara <saeedb@amazon.com>, Rasesh Mody <rmody@marvell.com>,
- Sudarsana Kalluru <skalluru@marvell.com>, GR-Linux-NIC-Dev@marvell.com,
- Dimitris Michailidis <dmichail@fungible.com>, Yisen Zhuang <yisen.zhuang@huawei.com>,
- Salil Mehta <salil.mehta@huawei.com>, Jesse Brandeburg <jesse.brandeburg@intel.com>,
- Tony Nguyen <anthony.l.nguyen@intel.com>, Louis Peens <louis.peens@corigine.com>,
- Shannon Nelson <shannon.nelson@amd.com>, Brett Creeley <brett.creeley@amd.com>, drivers@pensando.io,
- "K. Y. Srinivasan" <kys@microsoft.com>, Haiyang Zhang <haiyangz@microsoft.com>, Wei Liu <wei.liu@kernel.org>,
- Dexuan Cui <decui@microsoft.com>, Ronak Doshi <doshir@vmware.com>,
- VMware PV-Drivers Reviewers <pv-drivers@vmware.com>, Andy Whitcroft <apw@canonical.com>, Joe Perches <joe@perches.com>,
- Dwaipayan Ray <dwaipayanray1@gmail.com>, Lukas Bulwahn <lukas.bulwahn@gmail.com>,
- Hauke Mehrtens <hauke@hauke-m.de>, Andrew Lunn <andrew@lunn.ch>,
- Florian Fainelli <f.fainelli@gmail.com>, Vladimir Oltean <olteanv@gmail.com>,
- "=?utf-8?q?Ar=C4=B1n=C3=A7_=C3=9CNAL?=" <arinc.unal@arinc9.com>, Daniel Golle <daniel@makrotopia.org>,
- Landen Chao <Landen.Chao@mediatek.com>, DENG Qingfang <dqfext@gmail.com>,
- Sean Wang <sean.wang@mediatek.com>, Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Linus Walleij <linus.walleij@linaro.org>,
- "=?utf-8?q?Alvin_=C5=A0ipraga?=" <alsi@bang-olufsen.dk>, Wei Fang <wei.fang@nxp.com>,
- Shenwei Wang <shenwei.wang@nxp.com>, Clark Wang <xiaoning.wang@nxp.com>,
- NXP Linux Team <linux-imx@nxp.com>, Lars Povlsen <lars.povlsen@microchip.com>,
- Steen Hegelund <Steen.Hegelund@microchip.com>, Daniel Machon <daniel.machon@microchip.com>,
- UNGLinuxDriver@microchip.com, Jiawen Wu <jiawenwu@trustnetic.com>,
- Mengyuan Lou <mengyuanlou@net-swift.com>, Heiner Kallweit <hkallweit1@gmail.com>,
- Russell King <linux@armlinux.org.uk>, Alexei Starovoitov <ast@kernel.org>,
- Daniel Borkmann <daniel@iogearbox.net>, Jesper Dangaard Brouer <hawk@kernel.org>,
- John Fastabend <john.fastabend@gmail.com>
-Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
- Nick Desaulniers <ndesaulniers@google.com>, Nathan Chancellor <nathan@kernel.org>,
- Kees Cook <keescook@chromium.org>, intel-wired-lan@lists.osuosl.org,
- oss-drivers@corigine.com, linux-hyperv@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org,
- bpf@vger.kernel.org, Justin Stitt <justinstitt@google.com>
-Content-Type: text/plain; charset="utf-8"
-
-Use strscpy() to implement ethtool_puts().
-
-Functionally the same as ethtool_sprintf() when it's used with two
-arguments or with just "%s" format specifier.
-
-Signed-off-by: Justin Stitt <justinstitt@google.com>
----
- include/linux/ethtool.h | 13 +++++++++++++
- net/ethtool/ioctl.c | 7 +++++++
- 2 files changed, 20 insertions(+)
-
---- a/include/linux/ethtool.h
-+++ b/include/linux/ethtool.h
-@@ -788,4 +788,17 @@ int ethtool_get_phc_vclocks(struct net_d
- * next string.
- */
- extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...);
-+
-+/**
-+ * ethtool_puts - Write string to ethtool string data
-+ * @data: Pointer to a pointer to the start of string to update
-+ * @str: String to write
-+ *
-+ * Write string to *data without a trailing newline. Update *data
-+ * to point at start of next string.
-+ *
-+ * Prefer this function to ethtool_sprintf() when given only
-+ * two arguments or if @fmt is just "%s".
-+ */
-+extern void ethtool_puts(u8 **data, const char *str);
- #endif /* _LINUX_ETHTOOL_H */
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -1954,6 +1954,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
- }
- EXPORT_SYMBOL(ethtool_sprintf);
-
-+void ethtool_puts(u8 **data, const char *str)
-+{
-+ strscpy(*data, str, ETH_GSTRING_LEN);
-+ *data += ETH_GSTRING_LEN;
-+}
-+EXPORT_SYMBOL(ethtool_puts);
-+
- static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
- {
- struct ethtool_value id;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch b/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch
deleted file mode 100644
index fe32acc985..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch
+++ /dev/null
@@ -1,352 +0,0 @@
-From 8c20e2eb5f2a0175b774134685e4d7bd93e85ff8 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:18:59 -0700
-Subject: [PATCH 01/19] UPSTREAM: mm: multi-gen LRU: rename lru_gen_struct to
- lru_gen_folio
-
-Patch series "mm: multi-gen LRU: memcg LRU", v3.
-
-Overview
-========
-
-An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs,
-since each node and memcg combination has an LRU of folios (see
-mem_cgroup_lruvec()).
-
-Its goal is to improve the scalability of global reclaim, which is
-critical to system-wide memory overcommit in data centers. Note that
-memcg reclaim is currently out of scope.
-
-Its memory bloat is a pointer to each lruvec and negligible to each
-pglist_data. In terms of traversing memcgs during global reclaim, it
-improves the best-case complexity from O(n) to O(1) and does not affect
-the worst-case complexity O(n). Therefore, on average, it has a sublinear
-complexity in contrast to the current linear complexity.
-
-The basic structure of an memcg LRU can be understood by an analogy to
-the active/inactive LRU (of folios):
-1. It has the young and the old (generations), i.e., the counterparts
- to the active and the inactive;
-2. The increment of max_seq triggers promotion, i.e., the counterpart
- to activation;
-3. Other events trigger similar operations, e.g., offlining an memcg
- triggers demotion, i.e., the counterpart to deactivation.
-
-In terms of global reclaim, it has two distinct features:
-1. Sharding, which allows each thread to start at a random memcg (in
- the old generation) and improves parallelism;
-2. Eventual fairness, which allows direct reclaim to bail out at will
- and reduces latency without affecting fairness over some time.
-
-The commit message in patch 6 details the workflow:
-https://lore.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com/
-
-The following is a simple test to quickly verify its effectiveness.
-
- Test design:
- 1. Create multiple memcgs.
- 2. Each memcg contains a job (fio).
- 3. All jobs access the same amount of memory randomly.
- 4. The system does not experience global memory pressure.
- 5. Periodically write to the root memory.reclaim.
-
- Desired outcome:
- 1. All memcgs have similar pgsteal counts, i.e., stddev(pgsteal)
- over mean(pgsteal) is close to 0%.
- 2. The total pgsteal is close to the total requested through
- memory.reclaim, i.e., sum(pgsteal) over sum(requested) is close
- to 100%.
-
- Actual outcome [1]:
- MGLRU off MGLRU on
- stddev(pgsteal) / mean(pgsteal) 75% 20%
- sum(pgsteal) / sum(requested) 425% 95%
-
- ####################################################################
- MEMCGS=128
-
- for ((memcg = 0; memcg < $MEMCGS; memcg++)); do
- mkdir /sys/fs/cgroup/memcg$memcg
- done
-
- start() {
- echo $BASHPID > /sys/fs/cgroup/memcg$memcg/cgroup.procs
-
- fio -name=memcg$memcg --numjobs=1 --ioengine=mmap \
- --filename=/dev/zero --size=1920M --rw=randrw \
- --rate=64m,64m --random_distribution=random \
- --fadvise_hint=0 --time_based --runtime=10h \
- --group_reporting --minimal
- }
-
- for ((memcg = 0; memcg < $MEMCGS; memcg++)); do
- start &
- done
-
- sleep 600
-
- for ((i = 0; i < 600; i++)); do
- echo 256m >/sys/fs/cgroup/memory.reclaim
- sleep 6
- done
-
- for ((memcg = 0; memcg < $MEMCGS; memcg++)); do
- grep "pgsteal " /sys/fs/cgroup/memcg$memcg/memory.stat
- done
- ####################################################################
-
-[1]: This was obtained from running the above script (touches less
- than 256GB memory) on an EPYC 7B13 with 512GB DRAM for over an
- hour.
-
-This patch (of 8):
-
-The new name lru_gen_folio will be more distinct from the coming
-lru_gen_memcg.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-1-yuzhao@google.com
-Link: https://lkml.kernel.org/r/20221222041905.2431096-2-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit 391655fe08d1f942359a11148aa9aaf3f99d6d6f)
-Change-Id: I7df67e0e2435ba28f10eaa57d28d98b61a9210a6
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- include/linux/mm_inline.h | 4 ++--
- include/linux/mmzone.h | 6 +++---
- mm/vmscan.c | 34 +++++++++++++++++-----------------
- mm/workingset.c | 4 ++--
- 4 files changed, 24 insertions(+), 24 deletions(-)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(s
- int zone = folio_zonenum(folio);
- int delta = folio_nr_pages(folio);
- enum lru_list lru = type * LRU_INACTIVE_FILE;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
- VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
-@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(str
- int gen = folio_lru_gen(folio);
- int type = folio_is_file_lru(folio);
- int zone = folio_zonenum(folio);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE_FOLIO(gen != -1, folio);
-
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -404,7 +404,7 @@ enum {
- * The number of pages in each generation is eventually consistent and therefore
- * can be transiently negative when reset_batch_size() is pending.
- */
--struct lru_gen_struct {
-+struct lru_gen_folio {
- /* the aging increments the youngest generation number */
- unsigned long max_seq;
- /* the eviction increments the oldest generation numbers */
-@@ -461,7 +461,7 @@ struct lru_gen_mm_state {
- struct lru_gen_mm_walk {
- /* the lruvec under reclaim */
- struct lruvec *lruvec;
-- /* unstable max_seq from lru_gen_struct */
-+ /* unstable max_seq from lru_gen_folio */
- unsigned long max_seq;
- /* the next address within an mm to scan */
- unsigned long next_addr;
-@@ -524,7 +524,7 @@ struct lruvec {
- unsigned long flags;
- #ifdef CONFIG_LRU_GEN
- /* evictable pages divided into generations */
-- struct lru_gen_struct lrugen;
-+ struct lru_gen_folio lrugen;
- /* to concurrently iterate lru_gen_mm_list */
- struct lru_gen_mm_state mm_state;
- #endif
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lr
-
- static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
- {
-- /* see the comment on lru_gen_struct */
-+ /* see the comment on lru_gen_folio */
- return get_nr_gens(lruvec, LRU_GEN_FILE) >= MIN_NR_GENS &&
- get_nr_gens(lruvec, LRU_GEN_FILE) <= get_nr_gens(lruvec, LRU_GEN_ANON) &&
- get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS;
-@@ -3596,7 +3596,7 @@ struct ctrl_pos {
- static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
- struct ctrl_pos *pos)
- {
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- int hist = lru_hist_from_seq(lrugen->min_seq[type]);
-
- pos->refaulted = lrugen->avg_refaulted[type][tier] +
-@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec
- static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover)
- {
- int hist, tier;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1;
- unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1;
-
-@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio
- static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
- {
- int type = folio_is_file_lru(folio);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
- unsigned long new_flags, old_flags = READ_ONCE(folio->flags);
-
-@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru
- static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk)
- {
- int gen, type, zone;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- walk->batched = 0;
-
-@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *l
- {
- int zone;
- int remaining = MAX_LRU_BATCH;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
-
- if (type == LRU_GEN_ANON && !can_swap)
-@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lr
- {
- int gen, type, zone;
- bool success = false;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- DEFINE_MIN_SEQ(lruvec);
-
- VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
-@@ -4307,7 +4307,7 @@ next:
- ;
- }
-
-- /* see the comment on lru_gen_struct */
-+ /* see the comment on lru_gen_folio */
- if (can_swap) {
- min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
- min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
-@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *l
- {
- int prev, next;
- int type, zone;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- restart:
- spin_lock_irq(&lruvec->lru_lock);
-@@ -4389,7 +4389,7 @@ static bool try_to_inc_max_seq(struct lr
- bool success;
- struct lru_gen_mm_walk *walk;
- struct mm_struct *mm = NULL;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq));
-
-@@ -4454,7 +4454,7 @@ static bool should_run_aging(struct lruv
- unsigned long old = 0;
- unsigned long young = 0;
- unsigned long total = 0;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-
- for (type = !can_swap; type < ANON_AND_FILE; type++) {
-@@ -4740,7 +4740,7 @@ static bool sort_folio(struct lruvec *lr
- int delta = folio_nr_pages(folio);
- int refs = folio_lru_refs(folio);
- int tier = lru_tier_from_refs(refs);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio);
-
-@@ -4848,7 +4848,7 @@ static int scan_folios(struct lruvec *lr
- int scanned = 0;
- int isolated = 0;
- int remaining = MAX_LRU_BATCH;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-
- VM_WARN_ON_ONCE(!list_empty(list));
-@@ -5249,7 +5249,7 @@ done:
-
- static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
- {
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- if (lrugen->enabled) {
- enum lru_list lru;
-@@ -5531,7 +5531,7 @@ static void lru_gen_seq_show_full(struct
- int i;
- int type, tier;
- int hist = lru_hist_from_seq(seq);
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- for (tier = 0; tier < MAX_NR_TIERS; tier++) {
- seq_printf(m, " %10d", tier);
-@@ -5581,7 +5581,7 @@ static int lru_gen_seq_show(struct seq_f
- unsigned long seq;
- bool full = !debugfs_real_fops(m->file)->write;
- struct lruvec *lruvec = v;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- int nid = lruvec_pgdat(lruvec)->node_id;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
-@@ -5835,7 +5835,7 @@ void lru_gen_init_lruvec(struct lruvec *
- {
- int i;
- int gen, type, zone;
-- struct lru_gen_struct *lrugen = &lruvec->lrugen;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-
- lrugen->max_seq = MIN_NR_GENS + 1;
- lrugen->enabled = lru_gen_enabled();
---- a/mm/workingset.c
-+++ b/mm/workingset.c
-@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct fol
- unsigned long token;
- unsigned long min_seq;
- struct lruvec *lruvec;
-- struct lru_gen_struct *lrugen;
-+ struct lru_gen_folio *lrugen;
- int type = folio_is_file_lru(folio);
- int delta = folio_nr_pages(folio);
- int refs = folio_lru_refs(folio);
-@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio
- unsigned long token;
- unsigned long min_seq;
- struct lruvec *lruvec;
-- struct lru_gen_struct *lrugen;
-+ struct lru_gen_folio *lrugen;
- struct mem_cgroup *memcg;
- struct pglist_data *pgdat;
- int type = folio_is_file_lru(folio);
diff --git a/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch b/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch
deleted file mode 100644
index e5ad78b61d..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From 14f9a7a15f3d1af351f30e0438fd747b7ac253b0 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:01 -0700
-Subject: [PATCH 03/19] UPSTREAM: mm: multi-gen LRU: remove eviction fairness
- safeguard
-
-Recall that the eviction consumes the oldest generation: first it
-bucket-sorts folios whose gen counters were updated by the aging and
-reclaims the rest; then it increments lrugen->min_seq.
-
-The current eviction fairness safeguard for global reclaim has a
-dilemma: when there are multiple eligible memcgs, should it continue
-or stop upon meeting the reclaim goal? If it continues, it overshoots
-and increases direct reclaim latency; if it stops, it loses fairness
-between memcgs it has taken memory away from and those it has yet to.
-
-With memcg LRU, the eviction, while ensuring eventual fairness, will
-stop upon meeting its goal. Therefore the current eviction fairness
-safeguard for global reclaim will not be needed.
-
-Note that memcg LRU only applies to global reclaim. For memcg reclaim,
-the eviction will continue, even if it is overshooting. This becomes
-unconditional due to code simplification.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-4-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit a579086c99ed70cc4bfc104348dbe3dd8f2787e6)
-Change-Id: I08ac1b3c90e29cafd0566785aaa4bcdb5db7d22c
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 81 +++++++++++++++--------------------------------------
- 1 file changed, 23 insertions(+), 58 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_c
- return sc->target_mem_cgroup;
- }
-
-+static bool global_reclaim(struct scan_control *sc)
-+{
-+ return !sc->target_mem_cgroup || mem_cgroup_is_root(sc->target_mem_cgroup);
-+}
-+
- /**
- * writeback_throttling_sane - is the usual dirty throttling mechanism available?
- * @sc: scan_control in question
-@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_c
- return false;
- }
-
-+static bool global_reclaim(struct scan_control *sc)
-+{
-+ return true;
-+}
-+
- static bool writeback_throttling_sane(struct scan_control *sc)
- {
- return true;
-@@ -5005,8 +5015,7 @@ static int isolate_folios(struct lruvec
- return scanned;
- }
-
--static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
-- bool *need_swapping)
-+static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness)
- {
- int type;
- int scanned;
-@@ -5095,9 +5104,6 @@ retry:
- goto retry;
- }
-
-- if (need_swapping && type == LRU_GEN_ANON)
-- *need_swapping = true;
--
- return scanned;
- }
-
-@@ -5136,67 +5142,26 @@ done:
- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
- }
-
--static bool should_abort_scan(struct lruvec *lruvec, unsigned long seq,
-- struct scan_control *sc, bool need_swapping)
-+static unsigned long get_nr_to_reclaim(struct scan_control *sc)
- {
-- int i;
-- DEFINE_MAX_SEQ(lruvec);
--
-- if (!current_is_kswapd()) {
-- /* age each memcg at most once to ensure fairness */
-- if (max_seq - seq > 1)
-- return true;
--
-- /* over-swapping can increase allocation latency */
-- if (sc->nr_reclaimed >= sc->nr_to_reclaim && need_swapping)
-- return true;
--
-- /* give this thread a chance to exit and free its memory */
-- if (fatal_signal_pending(current)) {
-- sc->nr_reclaimed += MIN_LRU_BATCH;
-- return true;
-- }
--
-- if (cgroup_reclaim(sc))
-- return false;
-- } else if (sc->nr_reclaimed - sc->last_reclaimed < sc->nr_to_reclaim)
-- return false;
--
-- /* keep scanning at low priorities to ensure fairness */
-- if (sc->priority > DEF_PRIORITY - 2)
-- return false;
--
-- /*
-- * A minimum amount of work was done under global memory pressure. For
-- * kswapd, it may be overshooting. For direct reclaim, the allocation
-- * may succeed if all suitable zones are somewhat safe. In either case,
-- * it's better to stop now, and restart later if necessary.
-- */
-- for (i = 0; i <= sc->reclaim_idx; i++) {
-- unsigned long wmark;
-- struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i;
--
-- if (!managed_zone(zone))
-- continue;
--
-- wmark = current_is_kswapd() ? high_wmark_pages(zone) : low_wmark_pages(zone);
-- if (wmark > zone_page_state(zone, NR_FREE_PAGES))
-- return false;
-- }
-+ /* don't abort memcg reclaim to ensure fairness */
-+ if (!global_reclaim(sc))
-+ return -1;
-
-- sc->nr_reclaimed += MIN_LRU_BATCH;
-+ /* discount the previous progress for kswapd */
-+ if (current_is_kswapd())
-+ return sc->nr_to_reclaim + sc->last_reclaimed;
-
-- return true;
-+ return max(sc->nr_to_reclaim, compact_gap(sc->order));
- }
-
- static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
- struct blk_plug plug;
- bool need_aging = false;
-- bool need_swapping = false;
- unsigned long scanned = 0;
- unsigned long reclaimed = sc->nr_reclaimed;
-- DEFINE_MAX_SEQ(lruvec);
-+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
- lru_add_drain();
-
-@@ -5220,7 +5185,7 @@ static void lru_gen_shrink_lruvec(struct
- if (!nr_to_scan)
- goto done;
-
-- delta = evict_folios(lruvec, sc, swappiness, &need_swapping);
-+ delta = evict_folios(lruvec, sc, swappiness);
- if (!delta)
- goto done;
-
-@@ -5228,7 +5193,7 @@ static void lru_gen_shrink_lruvec(struct
- if (scanned >= nr_to_scan)
- break;
-
-- if (should_abort_scan(lruvec, max_seq, sc, need_swapping))
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
- break;
-
- cond_resched();
-@@ -5678,7 +5643,7 @@ static int run_eviction(struct lruvec *l
- if (sc->nr_reclaimed >= nr_to_reclaim)
- return 0;
-
-- if (!evict_folios(lruvec, sc, swappiness, NULL))
-+ if (!evict_folios(lruvec, sc, swappiness))
- return 0;
-
- cond_resched();
diff --git a/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch b/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch
deleted file mode 100644
index cb349abcdb..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From f3c93d2e37a3c56593d7ccf4f4bcf1b58426fdd8 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:02 -0700
-Subject: [PATCH 04/19] BACKPORT: mm: multi-gen LRU: remove aging fairness
- safeguard
-
-Recall that the aging produces the youngest generation: first it scans
-for accessed folios and updates their gen counters; then it increments
-lrugen->max_seq.
-
-The current aging fairness safeguard for kswapd uses two passes to
-ensure the fairness to multiple eligible memcgs. On the first pass,
-which is shared with the eviction, it checks whether all eligible
-memcgs are low on cold folios. If so, it requires a second pass, on
-which it ages all those memcgs at the same time.
-
-With memcg LRU, the aging, while ensuring eventual fairness, will run
-when necessary. Therefore the current aging fairness safeguard for
-kswapd will not be needed.
-
-Note that memcg LRU only applies to global reclaim. For memcg reclaim,
-the aging can be unfair to different memcgs, i.e., their
-lrugen->max_seq can be incremented at different paces.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-5-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit 7348cc91821b0cb24dfb00e578047f68299a50ab)
-[TJ: Resolved conflicts with older function signatures for
-min_cgroup_below_min / min_cgroup_below_low]
-Change-Id: I6e36ecfbaaefbc0a56d9a9d5d7cbe404ed7f57a5
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 126 ++++++++++++++++++++++++----------------------------
- 1 file changed, 59 insertions(+), 67 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -136,7 +136,6 @@ struct scan_control {
-
- #ifdef CONFIG_LRU_GEN
- /* help kswapd make better choices among multiple memcgs */
-- unsigned int memcgs_need_aging:1;
- unsigned long last_reclaimed;
- #endif
-
-@@ -4457,7 +4456,7 @@ done:
- return true;
- }
-
--static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq,
-+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
- struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
- {
- int gen, type, zone;
-@@ -4466,6 +4465,13 @@ static bool should_run_aging(struct lruv
- unsigned long total = 0;
- struct lru_gen_folio *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ /* whether this lruvec is completely out of cold folios */
-+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) {
-+ *nr_to_scan = 0;
-+ return true;
-+ }
-
- for (type = !can_swap; type < ANON_AND_FILE; type++) {
- unsigned long seq;
-@@ -4494,8 +4500,6 @@ static bool should_run_aging(struct lruv
- * stalls when the number of generations reaches MIN_NR_GENS. Hence, the
- * ideal number of generations is MIN_NR_GENS+1.
- */
-- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq)
-- return true;
- if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
- return false;
-
-@@ -4514,40 +4518,54 @@ static bool should_run_aging(struct lruv
- return false;
- }
-
--static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl)
-+static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
- {
-- bool need_aging;
-- unsigned long nr_to_scan;
-- int swappiness = get_swappiness(lruvec, sc);
-+ int gen, type, zone;
-+ unsigned long total = 0;
-+ bool can_swap = get_swappiness(lruvec, sc);
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
- DEFINE_MIN_SEQ(lruvec);
-
-- VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
-+ for (type = !can_swap; type < ANON_AND_FILE; type++) {
-+ unsigned long seq;
-
-- mem_cgroup_calculate_protection(NULL, memcg);
-+ for (seq = min_seq[type]; seq <= max_seq; seq++) {
-+ gen = lru_gen_from_seq(seq);
-
-- if (mem_cgroup_below_min(memcg))
-- return false;
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++)
-+ total += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
-+ }
-+ }
-
-- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan);
-+ /* whether the size is big enough to be helpful */
-+ return mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
-+}
-
-- if (min_ttl) {
-- int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
-- unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-+static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc,
-+ unsigned long min_ttl)
-+{
-+ int gen;
-+ unsigned long birth;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-
-- if (time_is_after_jiffies(birth + min_ttl))
-- return false;
-+ VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
-
-- /* the size is likely too small to be helpful */
-- if (!nr_to_scan && sc->priority != DEF_PRIORITY)
-- return false;
-- }
-+ /* see the comment on lru_gen_folio */
-+ gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
-+ birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-
-- if (need_aging)
-- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false);
-+ if (time_is_after_jiffies(birth + min_ttl))
-+ return false;
-
-- return true;
-+ if (!lruvec_is_sizable(lruvec, sc))
-+ return false;
-+
-+ mem_cgroup_calculate_protection(NULL, memcg);
-+
-+ return !mem_cgroup_below_min(memcg);
- }
-
- /* to protect the working set of the last N jiffies */
-@@ -4556,46 +4574,32 @@ static unsigned long lru_gen_min_ttl __r
- static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
- {
- struct mem_cgroup *memcg;
-- bool success = false;
- unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
-
- VM_WARN_ON_ONCE(!current_is_kswapd());
-
- sc->last_reclaimed = sc->nr_reclaimed;
-
-- /*
-- * To reduce the chance of going into the aging path, which can be
-- * costly, optimistically skip it if the flag below was cleared in the
-- * eviction path. This improves the overall performance when multiple
-- * memcgs are available.
-- */
-- if (!sc->memcgs_need_aging) {
-- sc->memcgs_need_aging = true;
-+ /* check the order to exclude compaction-induced reclaim */
-+ if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
- return;
-- }
--
-- set_mm_walk(pgdat);
-
- memcg = mem_cgroup_iter(NULL, NULL, NULL);
- do {
- struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
-
-- if (age_lruvec(lruvec, sc, min_ttl))
-- success = true;
-+ if (lruvec_is_reclaimable(lruvec, sc, min_ttl)) {
-+ mem_cgroup_iter_break(NULL, memcg);
-+ return;
-+ }
-
- cond_resched();
- } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
-
-- clear_mm_walk();
--
-- /* check the order to exclude compaction-induced reclaim */
-- if (success || !min_ttl || sc->order)
-- return;
--
- /*
- * The main goal is to OOM kill if every generation from all memcgs is
- * younger than min_ttl. However, another possibility is all memcgs are
-- * either below min or empty.
-+ * either too small or below min.
- */
- if (mutex_trylock(&oom_lock)) {
- struct oom_control oc = {
-@@ -5113,33 +5117,27 @@ retry:
- * reclaim.
- */
- static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
-- bool can_swap, bool *need_aging)
-+ bool can_swap)
- {
- unsigned long nr_to_scan;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
-- DEFINE_MIN_SEQ(lruvec);
-
- if (mem_cgroup_below_min(memcg) ||
- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
- return 0;
-
-- *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan);
-- if (!*need_aging)
-+ if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
- return nr_to_scan;
-
- /* skip the aging path at the default priority */
- if (sc->priority == DEF_PRIORITY)
-- goto done;
-+ return nr_to_scan;
-
-- /* leave the work to lru_gen_age_node() */
-- if (current_is_kswapd())
-- return 0;
-+ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false);
-
-- if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false))
-- return nr_to_scan;
--done:
-- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
-+ /* skip this lruvec as it's low on cold folios */
-+ return 0;
- }
-
- static unsigned long get_nr_to_reclaim(struct scan_control *sc)
-@@ -5158,9 +5156,7 @@ static unsigned long get_nr_to_reclaim(s
- static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
- struct blk_plug plug;
-- bool need_aging = false;
- unsigned long scanned = 0;
-- unsigned long reclaimed = sc->nr_reclaimed;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
- lru_add_drain();
-@@ -5181,13 +5177,13 @@ static void lru_gen_shrink_lruvec(struct
- else
- swappiness = 0;
-
-- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging);
-+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
- if (!nr_to_scan)
-- goto done;
-+ break;
-
- delta = evict_folios(lruvec, sc, swappiness);
- if (!delta)
-- goto done;
-+ break;
-
- scanned += delta;
- if (scanned >= nr_to_scan)
-@@ -5199,10 +5195,6 @@ static void lru_gen_shrink_lruvec(struct
- cond_resched();
- }
-
-- /* see the comment in lru_gen_age_node() */
-- if (sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH && !need_aging)
-- sc->memcgs_need_aging = false;
--done:
- clear_mm_walk();
-
- blk_finish_plug(&plug);
diff --git a/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch b/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch
deleted file mode 100644
index 42caab7c37..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From eca3858631e0cbad2ca6e40f788892749428e4cb Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:03 -0700
-Subject: [PATCH 05/19] UPSTREAM: mm: multi-gen LRU: shuffle should_run_aging()
-
-Move should_run_aging() next to its only caller left.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-6-yuzhao@google.com
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit 77d4459a4a1a472b7309e475f962dda87d950abd)
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
-Change-Id: I3b0383fe16b93a783b4d8c0b3a0b325160392576
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 124 ++++++++++++++++++++++++++--------------------------
- 1 file changed, 62 insertions(+), 62 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4456,68 +4456,6 @@ done:
- return true;
- }
-
--static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
-- struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
--{
-- int gen, type, zone;
-- unsigned long old = 0;
-- unsigned long young = 0;
-- unsigned long total = 0;
-- struct lru_gen_folio *lrugen = &lruvec->lrugen;
-- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-- DEFINE_MIN_SEQ(lruvec);
--
-- /* whether this lruvec is completely out of cold folios */
-- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) {
-- *nr_to_scan = 0;
-- return true;
-- }
--
-- for (type = !can_swap; type < ANON_AND_FILE; type++) {
-- unsigned long seq;
--
-- for (seq = min_seq[type]; seq <= max_seq; seq++) {
-- unsigned long size = 0;
--
-- gen = lru_gen_from_seq(seq);
--
-- for (zone = 0; zone < MAX_NR_ZONES; zone++)
-- size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
--
-- total += size;
-- if (seq == max_seq)
-- young += size;
-- else if (seq + MIN_NR_GENS == max_seq)
-- old += size;
-- }
-- }
--
-- /* try to scrape all its memory if this memcg was deleted */
-- *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
--
-- /*
-- * The aging tries to be lazy to reduce the overhead, while the eviction
-- * stalls when the number of generations reaches MIN_NR_GENS. Hence, the
-- * ideal number of generations is MIN_NR_GENS+1.
-- */
-- if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
-- return false;
--
-- /*
-- * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1)
-- * of the total number of pages for each generation. A reasonable range
-- * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The
-- * aging cares about the upper bound of hot pages, while the eviction
-- * cares about the lower bound of cold pages.
-- */
-- if (young * MIN_NR_GENS > total)
-- return true;
-- if (old * (MIN_NR_GENS + 2) < total)
-- return true;
--
-- return false;
--}
--
- static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
- {
- int gen, type, zone;
-@@ -5111,6 +5049,68 @@ retry:
- return scanned;
- }
-
-+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
-+ struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
-+{
-+ int gen, type, zone;
-+ unsigned long old = 0;
-+ unsigned long young = 0;
-+ unsigned long total = 0;
-+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ DEFINE_MIN_SEQ(lruvec);
-+
-+ /* whether this lruvec is completely out of cold folios */
-+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) {
-+ *nr_to_scan = 0;
-+ return true;
-+ }
-+
-+ for (type = !can_swap; type < ANON_AND_FILE; type++) {
-+ unsigned long seq;
-+
-+ for (seq = min_seq[type]; seq <= max_seq; seq++) {
-+ unsigned long size = 0;
-+
-+ gen = lru_gen_from_seq(seq);
-+
-+ for (zone = 0; zone < MAX_NR_ZONES; zone++)
-+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
-+
-+ total += size;
-+ if (seq == max_seq)
-+ young += size;
-+ else if (seq + MIN_NR_GENS == max_seq)
-+ old += size;
-+ }
-+ }
-+
-+ /* try to scrape all its memory if this memcg was deleted */
-+ *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
-+
-+ /*
-+ * The aging tries to be lazy to reduce the overhead, while the eviction
-+ * stalls when the number of generations reaches MIN_NR_GENS. Hence, the
-+ * ideal number of generations is MIN_NR_GENS+1.
-+ */
-+ if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
-+ return false;
-+
-+ /*
-+ * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1)
-+ * of the total number of pages for each generation. A reasonable range
-+ * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The
-+ * aging cares about the upper bound of hot pages, while the eviction
-+ * cares about the lower bound of cold pages.
-+ */
-+ if (young * MIN_NR_GENS > total)
-+ return true;
-+ if (old * (MIN_NR_GENS + 2) < total)
-+ return true;
-+
-+ return false;
-+}
-+
- /*
- * For future optimizations:
- * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
diff --git a/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch b/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch
deleted file mode 100644
index 69f52fa403..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch
+++ /dev/null
@@ -1,876 +0,0 @@
-From 8ee8571e47aa75221e5fbd4c9c7802fc4244c346 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:04 -0700
-Subject: [PATCH 06/19] BACKPORT: mm: multi-gen LRU: per-node lru_gen_folio
- lists
-
-For each node, memcgs are divided into two generations: the old and
-the young. For each generation, memcgs are randomly sharded into
-multiple bins to improve scalability. For each bin, an RCU hlist_nulls
-is virtually divided into three segments: the head, the tail and the
-default.
-
-An onlining memcg is added to the tail of a random bin in the old
-generation. The eviction starts at the head of a random bin in the old
-generation. The per-node memcg generation counter, whose reminder (mod
-2) indexes the old generation, is incremented when all its bins become
-empty.
-
-There are four operations:
-1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in
- its current generation (old or young) and updates its "seg" to
- "head";
-2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in
- its current generation (old or young) and updates its "seg" to
- "tail";
-3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in
- the old generation, updates its "gen" to "old" and resets its "seg"
- to "default";
-4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin
- in the young generation, updates its "gen" to "young" and resets
- its "seg" to "default".
-
-The events that trigger the above operations are:
-1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD;
-2. The first attempt to reclaim an memcg below low, which triggers
- MEMCG_LRU_TAIL;
-3. The first attempt to reclaim an memcg below reclaimable size
- threshold, which triggers MEMCG_LRU_TAIL;
-4. The second attempt to reclaim an memcg below reclaimable size
- threshold, which triggers MEMCG_LRU_YOUNG;
-5. Attempting to reclaim an memcg below min, which triggers
- MEMCG_LRU_YOUNG;
-6. Finishing the aging on the eviction path, which triggers
- MEMCG_LRU_YOUNG;
-7. Offlining an memcg, which triggers MEMCG_LRU_OLD.
-
-Note that memcg LRU only applies to global reclaim, and the
-round-robin incrementing of their max_seq counters ensures the
-eventual fairness to all eligible memcgs. For memcg reclaim, it still
-relies on mem_cgroup_iter().
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit e4dde56cd208674ce899b47589f263499e5b8cdc)
-[TJ: Resolved conflicts with older function signatures for
-min_cgroup_below_min / min_cgroup_below_low and includes]
-Change-Id: Idc8a0f635e035d72dd911f807d1224cb47cbd655
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- include/linux/memcontrol.h | 10 +
- include/linux/mm_inline.h | 17 ++
- include/linux/mmzone.h | 117 +++++++++++-
- mm/memcontrol.c | 16 ++
- mm/page_alloc.c | 1 +
- mm/vmscan.c | 374 +++++++++++++++++++++++++++++++++----
- 6 files changed, 500 insertions(+), 35 deletions(-)
-
---- a/include/linux/memcontrol.h
-+++ b/include/linux/memcontrol.h
-@@ -795,6 +795,11 @@ static inline void obj_cgroup_put(struct
- percpu_ref_put(&objcg->refcnt);
- }
-
-+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg)
-+{
-+ return !memcg || css_tryget(&memcg->css);
-+}
-+
- static inline void mem_cgroup_put(struct mem_cgroup *memcg)
- {
- if (memcg)
-@@ -1295,6 +1300,11 @@ static inline void obj_cgroup_put(struct
- {
- }
-
-+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg)
-+{
-+ return true;
-+}
-+
- static inline void mem_cgroup_put(struct mem_cgroup *memcg)
- {
- }
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void
- return current->in_lru_fault;
- }
-
-+#ifdef CONFIG_MEMCG
-+static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return READ_ONCE(lruvec->lrugen.seg);
-+}
-+#else
-+static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return 0;
-+}
-+#endif
-+
- static inline int lru_gen_from_seq(unsigned long seq)
- {
- return seq % MAX_NR_GENS;
-@@ -302,6 +314,11 @@ static inline bool lru_gen_in_fault(void
- return false;
- }
-
-+static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return 0;
-+}
-+
- static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
- {
- return false;
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -7,6 +7,7 @@
-
- #include <linux/spinlock.h>
- #include <linux/list.h>
-+#include <linux/list_nulls.h>
- #include <linux/wait.h>
- #include <linux/bitops.h>
- #include <linux/cache.h>
-@@ -367,6 +368,15 @@ struct page_vma_mapped_walk;
- #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
- #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
-
-+/* see the comment on MEMCG_NR_GENS */
-+enum {
-+ MEMCG_LRU_NOP,
-+ MEMCG_LRU_HEAD,
-+ MEMCG_LRU_TAIL,
-+ MEMCG_LRU_OLD,
-+ MEMCG_LRU_YOUNG,
-+};
-+
- #ifdef CONFIG_LRU_GEN
-
- enum {
-@@ -426,6 +436,14 @@ struct lru_gen_folio {
- atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
- /* whether the multi-gen LRU is enabled */
- bool enabled;
-+#ifdef CONFIG_MEMCG
-+ /* the memcg generation this lru_gen_folio belongs to */
-+ u8 gen;
-+ /* the list segment this lru_gen_folio belongs to */
-+ u8 seg;
-+ /* per-node lru_gen_folio list for global reclaim */
-+ struct hlist_nulls_node list;
-+#endif
- };
-
- enum {
-@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec *
- void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
-
- #ifdef CONFIG_MEMCG
-+
-+/*
-+ * For each node, memcgs are divided into two generations: the old and the
-+ * young. For each generation, memcgs are randomly sharded into multiple bins
-+ * to improve scalability. For each bin, the hlist_nulls is virtually divided
-+ * into three segments: the head, the tail and the default.
-+ *
-+ * An onlining memcg is added to the tail of a random bin in the old generation.
-+ * The eviction starts at the head of a random bin in the old generation. The
-+ * per-node memcg generation counter, whose reminder (mod MEMCG_NR_GENS) indexes
-+ * the old generation, is incremented when all its bins become empty.
-+ *
-+ * There are four operations:
-+ * 1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in its
-+ * current generation (old or young) and updates its "seg" to "head";
-+ * 2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in its
-+ * current generation (old or young) and updates its "seg" to "tail";
-+ * 3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in the old
-+ * generation, updates its "gen" to "old" and resets its "seg" to "default";
-+ * 4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin in the
-+ * young generation, updates its "gen" to "young" and resets its "seg" to
-+ * "default".
-+ *
-+ * The events that trigger the above operations are:
-+ * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD;
-+ * 2. The first attempt to reclaim an memcg below low, which triggers
-+ * MEMCG_LRU_TAIL;
-+ * 3. The first attempt to reclaim an memcg below reclaimable size threshold,
-+ * which triggers MEMCG_LRU_TAIL;
-+ * 4. The second attempt to reclaim an memcg below reclaimable size threshold,
-+ * which triggers MEMCG_LRU_YOUNG;
-+ * 5. Attempting to reclaim an memcg below min, which triggers MEMCG_LRU_YOUNG;
-+ * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG;
-+ * 7. Offlining an memcg, which triggers MEMCG_LRU_OLD.
-+ *
-+ * Note that memcg LRU only applies to global reclaim, and the round-robin
-+ * incrementing of their max_seq counters ensures the eventual fairness to all
-+ * eligible memcgs. For memcg reclaim, it still relies on mem_cgroup_iter().
-+ */
-+#define MEMCG_NR_GENS 2
-+#define MEMCG_NR_BINS 8
-+
-+struct lru_gen_memcg {
-+ /* the per-node memcg generation counter */
-+ unsigned long seq;
-+ /* each memcg has one lru_gen_folio per node */
-+ unsigned long nr_memcgs[MEMCG_NR_GENS];
-+ /* per-node lru_gen_folio list for global reclaim */
-+ struct hlist_nulls_head fifo[MEMCG_NR_GENS][MEMCG_NR_BINS];
-+ /* protects the above */
-+ spinlock_t lock;
-+};
-+
-+void lru_gen_init_pgdat(struct pglist_data *pgdat);
-+
- void lru_gen_init_memcg(struct mem_cgroup *memcg);
- void lru_gen_exit_memcg(struct mem_cgroup *memcg);
--#endif
-+void lru_gen_online_memcg(struct mem_cgroup *memcg);
-+void lru_gen_offline_memcg(struct mem_cgroup *memcg);
-+void lru_gen_release_memcg(struct mem_cgroup *memcg);
-+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op);
-+
-+#else /* !CONFIG_MEMCG */
-+
-+#define MEMCG_NR_GENS 1
-+
-+struct lru_gen_memcg {
-+};
-+
-+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat)
-+{
-+}
-+
-+#endif /* CONFIG_MEMCG */
-
- #else /* !CONFIG_LRU_GEN */
-
-+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat)
-+{
-+}
-+
- static inline void lru_gen_init_lruvec(struct lruvec *lruvec)
- {
- }
-@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(s
- }
-
- #ifdef CONFIG_MEMCG
-+
- static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
- {
- }
-@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(st
- static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg)
- {
- }
--#endif
-+
-+static inline void lru_gen_online_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+static inline void lru_gen_offline_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+static inline void lru_gen_release_memcg(struct mem_cgroup *memcg)
-+{
-+}
-+
-+static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
-+{
-+}
-+
-+#endif /* CONFIG_MEMCG */
-
- #endif /* CONFIG_LRU_GEN */
-
-@@ -1219,6 +1330,8 @@ typedef struct pglist_data {
- #ifdef CONFIG_LRU_GEN
- /* kswap mm walk data */
- struct lru_gen_mm_walk mm_walk;
-+ /* lru_gen_folio list */
-+ struct lru_gen_memcg memcg_lru;
- #endif
-
- CACHELINE_PADDING(_pad2_);
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struc
- struct mem_cgroup_per_node *mz;
- struct mem_cgroup_tree_per_node *mctz;
-
-+ if (lru_gen_enabled()) {
-+ struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec;
-+
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD)
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD);
-+
-+ return;
-+ }
-+
- mctz = soft_limit_tree.rb_tree_per_node[nid];
- if (!mctz)
- return;
-@@ -3524,6 +3534,9 @@ unsigned long mem_cgroup_soft_limit_recl
- struct mem_cgroup_tree_per_node *mctz;
- unsigned long excess;
-
-+ if (lru_gen_enabled())
-+ return 0;
-+
- if (order > 0)
- return 0;
-
-@@ -5387,6 +5400,7 @@ static int mem_cgroup_css_online(struct
- if (unlikely(mem_cgroup_is_root(memcg)))
- queue_delayed_work(system_unbound_wq, &stats_flush_dwork,
- 2UL*HZ);
-+ lru_gen_online_memcg(memcg);
- return 0;
- offline_kmem:
- memcg_offline_kmem(memcg);
-@@ -5418,6 +5432,7 @@ static void mem_cgroup_css_offline(struc
- memcg_offline_kmem(memcg);
- reparent_shrinker_deferred(memcg);
- wb_memcg_offline(memcg);
-+ lru_gen_offline_memcg(memcg);
-
- drain_all_stock(memcg);
-
-@@ -5429,6 +5444,7 @@ static void mem_cgroup_css_released(stru
- struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-
- invalidate_reclaim_iterators(memcg);
-+ lru_gen_release_memcg(memcg);
- }
-
- static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -7945,6 +7945,7 @@ static void __init free_area_init_node(i
- pgdat_set_deferred_range(pgdat);
-
- free_area_init_core(pgdat);
-+ lru_gen_init_pgdat(pgdat);
- }
-
- static void __init free_area_init_memoryless_node(int nid)
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -54,6 +54,8 @@
- #include <linux/shmem_fs.h>
- #include <linux/ctype.h>
- #include <linux/debugfs.h>
-+#include <linux/rculist_nulls.h>
-+#include <linux/random.h>
-
- #include <asm/tlbflush.h>
- #include <asm/div64.h>
-@@ -134,11 +136,6 @@ struct scan_control {
- /* Always discard instead of demoting to lower tier memory */
- unsigned int no_demotion:1;
-
--#ifdef CONFIG_LRU_GEN
-- /* help kswapd make better choices among multiple memcgs */
-- unsigned long last_reclaimed;
--#endif
--
- /* Allocation order */
- s8 order;
-
-@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca
- for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
- for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
-
-+#define get_memcg_gen(seq) ((seq) % MEMCG_NR_GENS)
-+#define get_memcg_bin(bin) ((bin) % MEMCG_NR_BINS)
-+
- static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
- {
- struct pglist_data *pgdat = NODE_DATA(nid);
-@@ -4442,8 +4442,7 @@ done:
- if (sc->priority <= DEF_PRIORITY - 2)
- wait_event_killable(lruvec->mm_state.wait,
- max_seq < READ_ONCE(lrugen->max_seq));
--
-- return max_seq < READ_ONCE(lrugen->max_seq);
-+ return false;
- }
-
- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
-@@ -4516,8 +4515,6 @@ static void lru_gen_age_node(struct pgli
-
- VM_WARN_ON_ONCE(!current_is_kswapd());
-
-- sc->last_reclaimed = sc->nr_reclaimed;
--
- /* check the order to exclude compaction-induced reclaim */
- if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
- return;
-@@ -5116,8 +5113,7 @@ static bool should_run_aging(struct lruv
- * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
- * reclaim.
- */
--static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
-- bool can_swap)
-+static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool can_swap)
- {
- unsigned long nr_to_scan;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-@@ -5134,10 +5130,8 @@ static unsigned long get_nr_to_scan(stru
- if (sc->priority == DEF_PRIORITY)
- return nr_to_scan;
-
-- try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false);
--
- /* skip this lruvec as it's low on cold folios */
-- return 0;
-+ return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? -1 : 0;
- }
-
- static unsigned long get_nr_to_reclaim(struct scan_control *sc)
-@@ -5146,29 +5140,18 @@ static unsigned long get_nr_to_reclaim(s
- if (!global_reclaim(sc))
- return -1;
-
-- /* discount the previous progress for kswapd */
-- if (current_is_kswapd())
-- return sc->nr_to_reclaim + sc->last_reclaimed;
--
- return max(sc->nr_to_reclaim, compact_gap(sc->order));
- }
-
--static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
- {
-- struct blk_plug plug;
-+ long nr_to_scan;
- unsigned long scanned = 0;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
-- lru_add_drain();
--
-- blk_start_plug(&plug);
--
-- set_mm_walk(lruvec_pgdat(lruvec));
--
- while (true) {
- int delta;
- int swappiness;
-- unsigned long nr_to_scan;
-
- if (sc->may_swap)
- swappiness = get_swappiness(lruvec, sc);
-@@ -5178,7 +5161,7 @@ static void lru_gen_shrink_lruvec(struct
- swappiness = 0;
-
- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
-- if (!nr_to_scan)
-+ if (nr_to_scan <= 0)
- break;
-
- delta = evict_folios(lruvec, sc, swappiness);
-@@ -5195,10 +5178,251 @@ static void lru_gen_shrink_lruvec(struct
- cond_resched();
- }
-
-+ /* whether try_to_inc_max_seq() was successful */
-+ return nr_to_scan < 0;
-+}
-+
-+static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ bool success;
-+ unsigned long scanned = sc->nr_scanned;
-+ unsigned long reclaimed = sc->nr_reclaimed;
-+ int seg = lru_gen_memcg_seg(lruvec);
-+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-+
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (!lruvec_is_sizable(lruvec, sc))
-+ return seg != MEMCG_LRU_TAIL ? MEMCG_LRU_TAIL : MEMCG_LRU_YOUNG;
-+
-+ mem_cgroup_calculate_protection(NULL, memcg);
-+
-+ if (mem_cgroup_below_min(memcg))
-+ return MEMCG_LRU_YOUNG;
-+
-+ if (mem_cgroup_below_low(memcg)) {
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (seg != MEMCG_LRU_TAIL)
-+ return MEMCG_LRU_TAIL;
-+
-+ memcg_memory_event(memcg, MEMCG_LOW);
-+ }
-+
-+ success = try_to_shrink_lruvec(lruvec, sc);
-+
-+ shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, sc->priority);
-+
-+ if (!sc->proactive)
-+ vmpressure(sc->gfp_mask, memcg, false, sc->nr_scanned - scanned,
-+ sc->nr_reclaimed - reclaimed);
-+
-+ sc->nr_reclaimed += current->reclaim_state->reclaimed_slab;
-+ current->reclaim_state->reclaimed_slab = 0;
-+
-+ return success ? MEMCG_LRU_YOUNG : 0;
-+}
-+
-+#ifdef CONFIG_MEMCG
-+
-+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ int gen;
-+ int bin;
-+ int first_bin;
-+ struct lruvec *lruvec;
-+ struct lru_gen_folio *lrugen;
-+ const struct hlist_nulls_node *pos;
-+ int op = 0;
-+ struct mem_cgroup *memcg = NULL;
-+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-+
-+ bin = first_bin = get_random_u32_below(MEMCG_NR_BINS);
-+restart:
-+ gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
-+
-+ rcu_read_lock();
-+
-+ hlist_nulls_for_each_entry_rcu(lrugen, pos, &pgdat->memcg_lru.fifo[gen][bin], list) {
-+ if (op)
-+ lru_gen_rotate_memcg(lruvec, op);
-+
-+ mem_cgroup_put(memcg);
-+
-+ lruvec = container_of(lrugen, struct lruvec, lrugen);
-+ memcg = lruvec_memcg(lruvec);
-+
-+ if (!mem_cgroup_tryget(memcg)) {
-+ op = 0;
-+ memcg = NULL;
-+ continue;
-+ }
-+
-+ rcu_read_unlock();
-+
-+ op = shrink_one(lruvec, sc);
-+
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
-+ goto success;
-+
-+ rcu_read_lock();
-+ }
-+
-+ rcu_read_unlock();
-+
-+ /* restart if raced with lru_gen_rotate_memcg() */
-+ if (gen != get_nulls_value(pos))
-+ goto restart;
-+
-+ /* try the rest of the bins of the current generation */
-+ bin = get_memcg_bin(bin + 1);
-+ if (bin != first_bin)
-+ goto restart;
-+success:
-+ if (op)
-+ lru_gen_rotate_memcg(lruvec, op);
-+
-+ mem_cgroup_put(memcg);
-+}
-+
-+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ struct blk_plug plug;
-+
-+ VM_WARN_ON_ONCE(global_reclaim(sc));
-+
-+ lru_add_drain();
-+
-+ blk_start_plug(&plug);
-+
-+ set_mm_walk(lruvec_pgdat(lruvec));
-+
-+ if (try_to_shrink_lruvec(lruvec, sc))
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
-+
-+ clear_mm_walk();
-+
-+ blk_finish_plug(&plug);
-+}
-+
-+#else /* !CONFIG_MEMCG */
-+
-+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ BUILD_BUG();
-+}
-+
-+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-+{
-+ BUILD_BUG();
-+}
-+
-+#endif
-+
-+static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ int priority;
-+ unsigned long reclaimable;
-+ struct lruvec *lruvec = mem_cgroup_lruvec(NULL, pgdat);
-+
-+ if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH)
-+ return;
-+ /*
-+ * Determine the initial priority based on ((total / MEMCG_NR_GENS) >>
-+ * priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, where the
-+ * estimated reclaimed_to_scanned_ratio = inactive / total.
-+ */
-+ reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE);
-+ if (get_swappiness(lruvec, sc))
-+ reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON);
-+
-+ reclaimable /= MEMCG_NR_GENS;
-+
-+ /* round down reclaimable and round up sc->nr_to_reclaim */
-+ priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1);
-+
-+ sc->priority = clamp(priority, 0, DEF_PRIORITY);
-+}
-+
-+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+ struct blk_plug plug;
-+ unsigned long reclaimed = sc->nr_reclaimed;
-+
-+ VM_WARN_ON_ONCE(!global_reclaim(sc));
-+
-+ lru_add_drain();
-+
-+ blk_start_plug(&plug);
-+
-+ set_mm_walk(pgdat);
-+
-+ set_initial_priority(pgdat, sc);
-+
-+ if (current_is_kswapd())
-+ sc->nr_reclaimed = 0;
-+
-+ if (mem_cgroup_disabled())
-+ shrink_one(&pgdat->__lruvec, sc);
-+ else
-+ shrink_many(pgdat, sc);
-+
-+ if (current_is_kswapd())
-+ sc->nr_reclaimed += reclaimed;
-+
- clear_mm_walk();
-
- blk_finish_plug(&plug);
-+
-+ /* kswapd should never fail */
-+ pgdat->kswapd_failures = 0;
-+}
-+
-+#ifdef CONFIG_MEMCG
-+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
-+{
-+ int seg;
-+ int old, new;
-+ int bin = get_random_u32_below(MEMCG_NR_BINS);
-+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ seg = 0;
-+ new = old = lruvec->lrugen.gen;
-+
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (op == MEMCG_LRU_HEAD)
-+ seg = MEMCG_LRU_HEAD;
-+ else if (op == MEMCG_LRU_TAIL)
-+ seg = MEMCG_LRU_TAIL;
-+ else if (op == MEMCG_LRU_OLD)
-+ new = get_memcg_gen(pgdat->memcg_lru.seq);
-+ else if (op == MEMCG_LRU_YOUNG)
-+ new = get_memcg_gen(pgdat->memcg_lru.seq + 1);
-+ else
-+ VM_WARN_ON_ONCE(true);
-+
-+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
-+
-+ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
-+ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
-+ else
-+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
-+
-+ pgdat->memcg_lru.nr_memcgs[old]--;
-+ pgdat->memcg_lru.nr_memcgs[new]++;
-+
-+ lruvec->lrugen.gen = new;
-+ WRITE_ONCE(lruvec->lrugen.seg, seg);
-+
-+ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq))
-+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
- }
-+#endif
-
- /******************************************************************************
- * state change
-@@ -5656,11 +5880,11 @@ static int run_cmd(char cmd, int memcg_i
-
- if (!mem_cgroup_disabled()) {
- rcu_read_lock();
-+
- memcg = mem_cgroup_from_id(memcg_id);
--#ifdef CONFIG_MEMCG
-- if (memcg && !css_tryget(&memcg->css))
-+ if (!mem_cgroup_tryget(memcg))
- memcg = NULL;
--#endif
-+
- rcu_read_unlock();
-
- if (!memcg)
-@@ -5808,6 +6032,19 @@ void lru_gen_init_lruvec(struct lruvec *
- }
-
- #ifdef CONFIG_MEMCG
-+
-+void lru_gen_init_pgdat(struct pglist_data *pgdat)
-+{
-+ int i, j;
-+
-+ spin_lock_init(&pgdat->memcg_lru.lock);
-+
-+ for (i = 0; i < MEMCG_NR_GENS; i++) {
-+ for (j = 0; j < MEMCG_NR_BINS; j++)
-+ INIT_HLIST_NULLS_HEAD(&pgdat->memcg_lru.fifo[i][j], i);
-+ }
-+}
-+
- void lru_gen_init_memcg(struct mem_cgroup *memcg)
- {
- INIT_LIST_HEAD(&memcg->mm_list.fifo);
-@@ -5831,7 +6068,69 @@ void lru_gen_exit_memcg(struct mem_cgrou
- }
- }
- }
--#endif
-+
-+void lru_gen_online_memcg(struct mem_cgroup *memcg)
-+{
-+ int gen;
-+ int nid;
-+ int bin = get_random_u32_below(MEMCG_NR_BINS);
-+
-+ for_each_node(nid) {
-+ struct pglist_data *pgdat = NODE_DATA(nid);
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ gen = get_memcg_gen(pgdat->memcg_lru.seq);
-+
-+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]);
-+ pgdat->memcg_lru.nr_memcgs[gen]++;
-+
-+ lruvec->lrugen.gen = gen;
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
-+ }
-+}
-+
-+void lru_gen_offline_memcg(struct mem_cgroup *memcg)
-+{
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD);
-+ }
-+}
-+
-+void lru_gen_release_memcg(struct mem_cgroup *memcg)
-+{
-+ int gen;
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct pglist_data *pgdat = NODE_DATA(nid);
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ gen = lruvec->lrugen.gen;
-+
-+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
-+ pgdat->memcg_lru.nr_memcgs[gen]--;
-+
-+ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq))
-+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
-+ }
-+}
-+
-+#endif /* CONFIG_MEMCG */
-
- static int __init init_lru_gen(void)
- {
-@@ -5858,6 +6157,10 @@ static void lru_gen_shrink_lruvec(struct
- {
- }
-
-+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc)
-+{
-+}
-+
- #endif /* CONFIG_LRU_GEN */
-
- static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-@@ -5871,7 +6174,7 @@ static void shrink_lruvec(struct lruvec
- bool proportional_reclaim;
- struct blk_plug plug;
-
-- if (lru_gen_enabled()) {
-+ if (lru_gen_enabled() && !global_reclaim(sc)) {
- lru_gen_shrink_lruvec(lruvec, sc);
- return;
- }
-@@ -6114,6 +6417,11 @@ static void shrink_node(pg_data_t *pgdat
- struct lruvec *target_lruvec;
- bool reclaimable = false;
-
-+ if (lru_gen_enabled() && global_reclaim(sc)) {
-+ lru_gen_shrink_node(pgdat, sc);
-+ return;
-+ }
-+
- target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
-
- again:
diff --git a/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch b/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch
deleted file mode 100644
index d60ddb9dcc..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From 11b14ee8cbbbebd8204609076a9327a1171cd253 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:05 -0700
-Subject: [PATCH 07/19] BACKPORT: mm: multi-gen LRU: clarify scan_control flags
-
-Among the flags in scan_control:
-1. sc->may_swap, which indicates swap constraint due to memsw.max, is
- supported as usual.
-2. sc->proactive, which indicates reclaim by memory.reclaim, may not
- opportunistically skip the aging path, since it is considered less
- latency sensitive.
-3. !(sc->gfp_mask & __GFP_IO), which indicates IO constraint, lowers
- swappiness to prioritize file LRU, since clean file folios are more
- likely to exist.
-4. sc->may_writepage and sc->may_unmap, which indicates opportunistic
- reclaim, are rejected, since unmapped clean folios are already
- prioritized. Scanning for more of them is likely futile and can
- cause high reclaim latency when there is a large number of memcgs.
-
-The rest are handled by the existing code.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-8-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit e9d4e1ee788097484606c32122f146d802a9c5fb)
-[TJ: Resolved conflict with older function signature for min_cgroup_below_min, and over
-cdded861182142ac4488a4d64c571107aeb77f53 ("ANDROID: MGLRU: Don't skip anon reclaim if swap low")]
-Change-Id: Ic2e779eaf4e91a3921831b4e2fa10c740dc59d50
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 55 +++++++++++++++++++++++++++--------------------------
- 1 file changed, 28 insertions(+), 27 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-
-+ if (!sc->may_swap)
-+ return 0;
-+
- if (!can_demote(pgdat->node_id, sc) &&
- mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
- return 0;
-@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruve
- } while (err == -EAGAIN);
- }
-
--static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat)
-+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat, bool force_alloc)
- {
- struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
-
-@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_wa
- VM_WARN_ON_ONCE(walk);
-
- walk = &pgdat->mm_walk;
-- } else if (!pgdat && !walk) {
-+ } else if (!walk && force_alloc) {
- VM_WARN_ON_ONCE(current_is_kswapd());
-
- walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
-@@ -4419,7 +4422,7 @@ static bool try_to_inc_max_seq(struct lr
- goto done;
- }
-
-- walk = set_mm_walk(NULL);
-+ walk = set_mm_walk(NULL, true);
- if (!walk) {
- success = iterate_mm_list_nowalk(lruvec, max_seq);
- goto done;
-@@ -4488,8 +4491,6 @@ static bool lruvec_is_reclaimable(struct
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MIN_SEQ(lruvec);
-
-- VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
--
- /* see the comment on lru_gen_folio */
- gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
- birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
-@@ -4753,12 +4754,8 @@ static bool isolate_folio(struct lruvec
- {
- bool success;
-
-- /* unmapping inhibited */
-- if (!sc->may_unmap && folio_mapped(folio))
-- return false;
--
- /* swapping inhibited */
-- if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) &&
-+ if (!(sc->gfp_mask & __GFP_IO) &&
- (folio_test_dirty(folio) ||
- (folio_test_anon(folio) && !folio_test_swapcache(folio))))
- return false;
-@@ -4857,9 +4854,8 @@ static int scan_folios(struct lruvec *lr
- __count_vm_events(PGSCAN_ANON + type, isolated);
-
- /*
-- * There might not be eligible pages due to reclaim_idx, may_unmap and
-- * may_writepage. Check the remaining to prevent livelock if it's not
-- * making progress.
-+ * There might not be eligible folios due to reclaim_idx. Check the
-+ * remaining to prevent livelock if it's not making progress.
- */
- return isolated || !remaining ? scanned : 0;
- }
-@@ -5119,8 +5115,7 @@ static long get_nr_to_scan(struct lruvec
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
-
-- if (mem_cgroup_below_min(memcg) ||
-- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
-+ if (mem_cgroup_below_min(memcg))
- return 0;
-
- if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
-@@ -5148,17 +5143,14 @@ static bool try_to_shrink_lruvec(struct
- long nr_to_scan;
- unsigned long scanned = 0;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-+ int swappiness = get_swappiness(lruvec, sc);
-+
-+ /* clean file folios are more likely to exist */
-+ if (swappiness && !(sc->gfp_mask & __GFP_IO))
-+ swappiness = 1;
-
- while (true) {
- int delta;
-- int swappiness;
--
-- if (sc->may_swap)
-- swappiness = get_swappiness(lruvec, sc);
-- else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc))
-- swappiness = 1;
-- else
-- swappiness = 0;
-
- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
- if (nr_to_scan <= 0)
-@@ -5289,12 +5281,13 @@ static void lru_gen_shrink_lruvec(struct
- struct blk_plug plug;
-
- VM_WARN_ON_ONCE(global_reclaim(sc));
-+ VM_WARN_ON_ONCE(!sc->may_writepage || !sc->may_unmap);
-
- lru_add_drain();
-
- blk_start_plug(&plug);
-
-- set_mm_walk(lruvec_pgdat(lruvec));
-+ set_mm_walk(NULL, sc->proactive);
-
- if (try_to_shrink_lruvec(lruvec, sc))
- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
-@@ -5350,11 +5343,19 @@ static void lru_gen_shrink_node(struct p
-
- VM_WARN_ON_ONCE(!global_reclaim(sc));
-
-+ /*
-+ * Unmapped clean folios are already prioritized. Scanning for more of
-+ * them is likely futile and can cause high reclaim latency when there
-+ * is a large number of memcgs.
-+ */
-+ if (!sc->may_writepage || !sc->may_unmap)
-+ goto done;
-+
- lru_add_drain();
-
- blk_start_plug(&plug);
-
-- set_mm_walk(pgdat);
-+ set_mm_walk(pgdat, sc->proactive);
-
- set_initial_priority(pgdat, sc);
-
-@@ -5372,7 +5373,7 @@ static void lru_gen_shrink_node(struct p
- clear_mm_walk();
-
- blk_finish_plug(&plug);
--
-+done:
- /* kswapd should never fail */
- pgdat->kswapd_failures = 0;
- }
-@@ -5944,7 +5945,7 @@ static ssize_t lru_gen_seq_write(struct
- set_task_reclaim_state(current, &sc.reclaim_state);
- flags = memalloc_noreclaim_save();
- blk_start_plug(&plug);
-- if (!set_mm_walk(NULL)) {
-+ if (!set_mm_walk(NULL, true)) {
- err = -ENOMEM;
- goto done;
- }
diff --git a/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch b/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch
deleted file mode 100644
index 3cbc84f8b8..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 25887d48dff860751a06caa4188bfaf6bfb6e4b2 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Wed, 21 Dec 2022 21:19:06 -0700
-Subject: [PATCH 08/19] UPSTREAM: mm: multi-gen LRU: simplify
- arch_has_hw_pte_young() check
-
-Scanning page tables when hardware does not set the accessed bit has
-no real use cases.
-
-Link: https://lkml.kernel.org/r/20221222041905.2431096-9-yuzhao@google.com
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Cc: Michal Hocko <mhocko@kernel.org>
-Cc: Mike Rapoport <rppt@kernel.org>
-Cc: Roman Gushchin <roman.gushchin@linux.dev>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit f386e9314025ea99dae639ed2032560a92081430)
-Change-Id: I84d97ab665b4e3bb862a9bc7d72f50dea7191a6b
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4417,7 +4417,7 @@ static bool try_to_inc_max_seq(struct lr
- * handful of PTEs. Spreading the work out over a period of time usually
- * is less efficient, but it avoids bursty page faults.
- */
-- if (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) {
-+ if (!arch_has_hw_pte_young() || !get_cap(LRU_GEN_MM_WALK)) {
- success = iterate_mm_list_nowalk(lruvec, max_seq);
- goto done;
- }
diff --git a/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch b/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch
deleted file mode 100644
index c1ad1c538e..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 620b0ee94455e48d124414cd06d8a53f69fb6453 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Mon, 13 Feb 2023 00:53:22 -0700
-Subject: [PATCH 09/19] UPSTREAM: mm: multi-gen LRU: avoid futile retries
-
-Recall that the per-node memcg LRU has two generations and they alternate
-when the last memcg (of a given node) is moved from one to the other.
-Each generation is also sharded into multiple bins to improve scalability.
-A reclaimer starts with a random bin (in the old generation) and, if it
-fails, it will retry, i.e., to try the rest of the bins.
-
-If a reclaimer fails with the last memcg, it should move this memcg to the
-young generation first, which causes the generations to alternate, and
-then retry. Otherwise, the retries will be futile because all other bins
-are empty.
-
-Link: https://lkml.kernel.org/r/20230213075322.1416966-1-yuzhao@google.com
-Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists")
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Reported-by: T.J. Mercier <tjmercier@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Bug: 274865848
-(cherry picked from commit 9f550d78b40da21b4da515db4c37d8d7b12aa1a6)
-Change-Id: Ie92535676b005ec9e7987632b742fdde8d54436f
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 25 +++++++++++++++----------
- 1 file changed, 15 insertions(+), 10 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -5218,18 +5218,20 @@ static int shrink_one(struct lruvec *lru
-
- static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
- {
-+ int op;
- int gen;
- int bin;
- int first_bin;
- struct lruvec *lruvec;
- struct lru_gen_folio *lrugen;
-+ struct mem_cgroup *memcg;
- const struct hlist_nulls_node *pos;
-- int op = 0;
-- struct mem_cgroup *memcg = NULL;
- unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
-
- bin = first_bin = get_random_u32_below(MEMCG_NR_BINS);
- restart:
-+ op = 0;
-+ memcg = NULL;
- gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
-
- rcu_read_lock();
-@@ -5253,14 +5255,22 @@ restart:
-
- op = shrink_one(lruvec, sc);
-
-- if (sc->nr_reclaimed >= nr_to_reclaim)
-- goto success;
--
- rcu_read_lock();
-+
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
-+ break;
- }
-
- rcu_read_unlock();
-
-+ if (op)
-+ lru_gen_rotate_memcg(lruvec, op);
-+
-+ mem_cgroup_put(memcg);
-+
-+ if (sc->nr_reclaimed >= nr_to_reclaim)
-+ return;
-+
- /* restart if raced with lru_gen_rotate_memcg() */
- if (gen != get_nulls_value(pos))
- goto restart;
-@@ -5269,11 +5279,6 @@ restart:
- bin = get_memcg_bin(bin + 1);
- if (bin != first_bin)
- goto restart;
--success:
-- if (op)
-- lru_gen_rotate_memcg(lruvec, op);
--
-- mem_cgroup_put(memcg);
- }
-
- static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
diff --git a/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch b/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch
deleted file mode 100644
index 67fe4f96ec..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch
+++ /dev/null
@@ -1,191 +0,0 @@
-From 70d216c71ff5c5b17dd1da6294f97b91fb6aba7a Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Fri, 30 Dec 2022 14:52:51 -0700
-Subject: [PATCH 10/19] UPSTREAM: mm: add vma_has_recency()
-
-Add vma_has_recency() to indicate whether a VMA may exhibit temporal
-locality that the LRU algorithm relies on.
-
-This function returns false for VMAs marked by VM_SEQ_READ or
-VM_RAND_READ. While the former flag indicates linear access, i.e., a
-special case of spatial locality, both flags indicate a lack of temporal
-locality, i.e., the reuse of an area within a relatively small duration.
-
-"Recency" is chosen over "locality" to avoid confusion between temporal
-and spatial localities.
-
-Before this patch, the active/inactive LRU only ignored the accessed bit
-from VMAs marked by VM_SEQ_READ. After this patch, the active/inactive
-LRU and MGLRU share the same logic: they both ignore the accessed bit if
-vma_has_recency() returns false.
-
-For the active/inactive LRU, the following fio test showed a [6, 8]%
-increase in IOPS when randomly accessing mapped files under memory
-pressure.
-
- kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo)
- kb=$((kb - 8*1024*1024))
-
- modprobe brd rd_nr=1 rd_size=$kb
- dd if=/dev/zero of=/dev/ram0 bs=1M
-
- mkfs.ext4 /dev/ram0
- mount /dev/ram0 /mnt/
- swapoff -a
-
- fio --name=test --directory=/mnt/ --ioengine=mmap --numjobs=8 \
- --size=8G --rw=randrw --time_based --runtime=10m \
- --group_reporting
-
-The discussion that led to this patch is here [1]. Additional test
-results are available in that thread.
-
-[1] https://lore.kernel.org/r/Y31s%2FK8T85jh05wH@google.com/
-
-Link: https://lkml.kernel.org/r/20221230215252.2628425-1-yuzhao@google.com
-Change-Id: I291dcb795197659e40e46539cd32b857677c34ad
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Alexander Viro <viro@zeniv.linux.org.uk>
-Cc: Andrea Righi <andrea.righi@canonical.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit 8788f6781486769d9598dcaedc3fe0eb12fc3e59)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- include/linux/mm_inline.h | 8 ++++++++
- mm/memory.c | 7 +++----
- mm/rmap.c | 42 +++++++++++++++++----------------------
- mm/vmscan.c | 5 ++++-
- 4 files changed, 33 insertions(+), 29 deletions(-)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -600,4 +600,12 @@ pte_install_uffd_wp_if_needed(struct vm_
- #endif
- }
-
-+static inline bool vma_has_recency(struct vm_area_struct *vma)
-+{
-+ if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
-+ return false;
-+
-+ return true;
-+}
-+
- #endif
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -1445,8 +1445,7 @@ again:
- force_flush = 1;
- set_page_dirty(page);
- }
-- if (pte_young(ptent) &&
-- likely(!(vma->vm_flags & VM_SEQ_READ)))
-+ if (pte_young(ptent) && likely(vma_has_recency(vma)))
- mark_page_accessed(page);
- }
- rss[mm_counter(page)]--;
-@@ -5219,8 +5218,8 @@ static inline void mm_account_fault(stru
- #ifdef CONFIG_LRU_GEN
- static void lru_gen_enter_fault(struct vm_area_struct *vma)
- {
-- /* the LRU algorithm doesn't apply to sequential or random reads */
-- current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ));
-+ /* the LRU algorithm only applies to accesses with recency */
-+ current->in_lru_fault = vma_has_recency(vma);
- }
-
- static void lru_gen_exit_fault(void)
---- a/mm/rmap.c
-+++ b/mm/rmap.c
-@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct
- }
-
- if (pvmw.pte) {
-- if (lru_gen_enabled() && pte_young(*pvmw.pte) &&
-- !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) {
-+ if (lru_gen_enabled() && pte_young(*pvmw.pte)) {
- lru_gen_look_around(&pvmw);
- referenced++;
- }
-
- if (ptep_clear_flush_young_notify(vma, address,
-- pvmw.pte)) {
-- /*
-- * Don't treat a reference through
-- * a sequentially read mapping as such.
-- * If the folio has been used in another mapping,
-- * we will catch it; if this other mapping is
-- * already gone, the unmap path will have set
-- * the referenced flag or activated the folio.
-- */
-- if (likely(!(vma->vm_flags & VM_SEQ_READ)))
-- referenced++;
-- }
-+ pvmw.pte))
-+ referenced++;
- } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
- if (pmdp_clear_flush_young_notify(vma, address,
- pvmw.pmd))
-@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma
- struct folio_referenced_arg *pra = arg;
- struct mem_cgroup *memcg = pra->memcg;
-
-- if (!mm_match_cgroup(vma->vm_mm, memcg))
-+ /*
-+ * Ignore references from this mapping if it has no recency. If the
-+ * folio has been used in another mapping, we will catch it; if this
-+ * other mapping is already gone, the unmap path will have set the
-+ * referenced flag or activated the folio in zap_pte_range().
-+ */
-+ if (!vma_has_recency(vma))
-+ return true;
-+
-+ /*
-+ * If we are reclaiming on behalf of a cgroup, skip counting on behalf
-+ * of references from different cgroups.
-+ */
-+ if (memcg && !mm_match_cgroup(vma->vm_mm, memcg))
- return true;
-
- return false;
-@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio
- .arg = (void *)&pra,
- .anon_lock = folio_lock_anon_vma_read,
- .try_lock = true,
-+ .invalid_vma = invalid_folio_referenced_vma,
- };
-
- *vm_flags = 0;
-@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio
- return 1;
- }
-
-- /*
-- * If we are reclaiming on behalf of a cgroup, skip
-- * counting on behalf of references from different
-- * cgroups
-- */
-- if (memcg) {
-- rwc.invalid_vma = invalid_folio_referenced_vma;
-- }
--
- rmap_walk(folio, &rwc);
- *vm_flags = pra.vm_flags;
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long
- if (is_vm_hugetlb_page(vma))
- return true;
-
-- if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ))
-+ if (!vma_has_recency(vma))
-+ return true;
-+
-+ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL))
- return true;
-
- if (vma == get_gate_vma(vma->vm_mm))
diff --git a/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch b/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch
deleted file mode 100644
index f9c39be920..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 9ca4e437a24dfc4ec6c362f319eb9850b9eca497 Mon Sep 17 00:00:00 2001
-From: Yu Zhao <yuzhao@google.com>
-Date: Fri, 30 Dec 2022 14:52:52 -0700
-Subject: [PATCH 11/19] UPSTREAM: mm: support POSIX_FADV_NOREUSE
-
-This patch adds POSIX_FADV_NOREUSE to vma_has_recency() so that the LRU
-algorithm can ignore access to mapped files marked by this flag.
-
-The advantages of POSIX_FADV_NOREUSE are:
-1. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not alter the
- default readahead behavior.
-2. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not split VMAs and
- therefore does not take mmap_lock.
-3. Unlike MADV_COLD, setting it has a negligible cost, regardless of
- how many pages it affects.
-
-Its limitations are:
-1. Like POSIX_FADV_RANDOM and POSIX_FADV_SEQUENTIAL, it currently does
- not support range. IOW, its scope is the entire file.
-2. It currently does not ignore access through file descriptors.
- Specifically, for the active/inactive LRU, given a file page shared
- by two users and one of them having set POSIX_FADV_NOREUSE on the
- file, this page will be activated upon the second user accessing
- it. This corner case can be covered by checking POSIX_FADV_NOREUSE
- before calling folio_mark_accessed() on the read path. But it is
- considered not worth the effort.
-
-There have been a few attempts to support POSIX_FADV_NOREUSE, e.g., [1].
-This time the goal is to fill a niche: a few desktop applications, e.g.,
-large file transferring and video encoding/decoding, want fast file
-streaming with mmap() rather than direct IO. Among those applications, an
-SVT-AV1 regression was reported when running with MGLRU [2]. The
-following test can reproduce that regression.
-
- kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo)
- kb=$((kb - 8*1024*1024))
-
- modprobe brd rd_nr=1 rd_size=$kb
- dd if=/dev/zero of=/dev/ram0 bs=1M
-
- mkfs.ext4 /dev/ram0
- mount /dev/ram0 /mnt/
- swapoff -a
-
- fallocate -l 8G /mnt/swapfile
- mkswap /mnt/swapfile
- swapon /mnt/swapfile
-
- wget http://ultravideo.cs.tut.fi/video/Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z
- 7z e -o/mnt/ Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z
- SvtAv1EncApp --preset 12 -w 3840 -h 2160 \
- -i /mnt/Bosphorus_3840x2160.y4m
-
-For MGLRU, the following change showed a [9-11]% increase in FPS,
-which makes it on par with the active/inactive LRU.
-
- patch Source/App/EncApp/EbAppMain.c <<EOF
- 31a32
- > #include <fcntl.h>
- 35d35
- < #include <fcntl.h> /* _O_BINARY */
- 117a118
- > posix_fadvise(config->mmap.fd, 0, 0, POSIX_FADV_NOREUSE);
- EOF
-
-[1] https://lore.kernel.org/r/1308923350-7932-1-git-send-email-andrea@betterlinux.com/
-[2] https://openbenchmarking.org/result/2209259-PTS-MGLRU8GB57
-
-Link: https://lkml.kernel.org/r/20221230215252.2628425-2-yuzhao@google.com
-Change-Id: I0b7f5f971d78014ea1ba44cee6a8ec902a4330d0
-Signed-off-by: Yu Zhao <yuzhao@google.com>
-Cc: Alexander Viro <viro@zeniv.linux.org.uk>
-Cc: Andrea Righi <andrea.righi@canonical.com>
-Cc: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Michael Larabel <Michael@MichaelLarabel.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit 17e810229cb3068b692fa078bd9b3a6527e0866a)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- include/linux/fs.h | 2 ++
- include/linux/mm_inline.h | 3 +++
- mm/fadvise.c | 5 ++++-
- 3 files changed, 9 insertions(+), 1 deletion(-)
-
---- a/include/linux/fs.h
-+++ b/include/linux/fs.h
-@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb
- /* File supports DIRECT IO */
- #define FMODE_CAN_ODIRECT ((__force fmode_t)0x400000)
-
-+#define FMODE_NOREUSE ((__force fmode_t)0x800000)
-+
- /* File was opened by fanotify and shouldn't generate fanotify events */
- #define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
-
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -605,6 +605,9 @@ static inline bool vma_has_recency(struc
- if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
- return false;
-
-+ if (vma->vm_file && (vma->vm_file->f_mode & FMODE_NOREUSE))
-+ return false;
-+
- return true;
- }
-
---- a/mm/fadvise.c
-+++ b/mm/fadvise.c
-@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l
- case POSIX_FADV_NORMAL:
- file->f_ra.ra_pages = bdi->ra_pages;
- spin_lock(&file->f_lock);
-- file->f_mode &= ~FMODE_RANDOM;
-+ file->f_mode &= ~(FMODE_RANDOM | FMODE_NOREUSE);
- spin_unlock(&file->f_lock);
- break;
- case POSIX_FADV_RANDOM:
-@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l
- force_page_cache_readahead(mapping, file, start_index, nrpages);
- break;
- case POSIX_FADV_NOREUSE:
-+ spin_lock(&file->f_lock);
-+ file->f_mode |= FMODE_NOREUSE;
-+ spin_unlock(&file->f_lock);
- break;
- case POSIX_FADV_DONTNEED:
- __filemap_fdatawrite_range(mapping, offset, endbyte,
diff --git a/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch b/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch
deleted file mode 100644
index bac2e3e344..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 1b5e4c317d80f4826eceb3781702d18d06b14394 Mon Sep 17 00:00:00 2001
-From: "T.J. Alumbaugh" <talumbau@google.com>
-Date: Wed, 18 Jan 2023 00:18:21 +0000
-Subject: [PATCH 12/19] UPSTREAM: mm: multi-gen LRU: section for working set
- protection
-
-Patch series "mm: multi-gen LRU: improve".
-
-This patch series improves a few MGLRU functions, collects related
-functions, and adds additional documentation.
-
-This patch (of 7):
-
-Add a section for working set protection in the code and the design doc.
-The admin doc already contains its usage.
-
-Link: https://lkml.kernel.org/r/20230118001827.1040870-1-talumbau@google.com
-Link: https://lkml.kernel.org/r/20230118001827.1040870-2-talumbau@google.com
-Change-Id: I65599075fd42951db7739a2ab7cee78516e157b3
-Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
-Cc: Yu Zhao <yuzhao@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit 7b8144e63d84716f16a1b929e0c7e03ae5c4d5c1)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- Documentation/mm/multigen_lru.rst | 15 +++++++++++++++
- mm/vmscan.c | 4 ++++
- 2 files changed, 19 insertions(+)
-
---- a/Documentation/mm/multigen_lru.rst
-+++ b/Documentation/mm/multigen_lru.rst
-@@ -141,6 +141,21 @@ loop has detected outlying refaults from
- this end, the feedback loop uses the first tier as the baseline, for
- the reason stated earlier.
-
-+Working set protection
-+----------------------
-+Each generation is timestamped at birth. If ``lru_gen_min_ttl`` is
-+set, an ``lruvec`` is protected from the eviction when its oldest
-+generation was born within ``lru_gen_min_ttl`` milliseconds. In other
-+words, it prevents the working set of ``lru_gen_min_ttl`` milliseconds
-+from getting evicted. The OOM killer is triggered if this working set
-+cannot be kept in memory.
-+
-+This time-based approach has the following advantages:
-+
-+1. It is easier to configure because it is agnostic to applications
-+ and memory sizes.
-+2. It is more reliable because it is directly wired to the OOM killer.
-+
- Summary
- -------
- The multi-gen LRU can be disassembled into the following parts:
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4461,6 +4461,10 @@ done:
- return true;
- }
-
-+/******************************************************************************
-+ * working set protection
-+ ******************************************************************************/
-+
- static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
- {
- int gen, type, zone;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch b/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch
deleted file mode 100644
index c28a1c5d5b..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 5ddf9d53d375e42af49b744bd7c2f8247c6bce15 Mon Sep 17 00:00:00 2001
-From: "T.J. Alumbaugh" <talumbau@google.com>
-Date: Wed, 18 Jan 2023 00:18:22 +0000
-Subject: [PATCH 13/19] UPSTREAM: mm: multi-gen LRU: section for rmap/PT walk
- feedback
-
-Add a section for lru_gen_look_around() in the code and the design doc.
-
-Link: https://lkml.kernel.org/r/20230118001827.1040870-3-talumbau@google.com
-Change-Id: I5097af63f61b3b69ec2abee6cdbdc33c296df213
-Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
-Cc: Yu Zhao <yuzhao@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit db19a43d9b3a8876552f00f656008206ef9a5efa)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- Documentation/mm/multigen_lru.rst | 14 ++++++++++++++
- mm/vmscan.c | 4 ++++
- 2 files changed, 18 insertions(+)
-
---- a/Documentation/mm/multigen_lru.rst
-+++ b/Documentation/mm/multigen_lru.rst
-@@ -156,6 +156,20 @@ This time-based approach has the followi
- and memory sizes.
- 2. It is more reliable because it is directly wired to the OOM killer.
-
-+Rmap/PT walk feedback
-+---------------------
-+Searching the rmap for PTEs mapping each page on an LRU list (to test
-+and clear the accessed bit) can be expensive because pages from
-+different VMAs (PA space) are not cache friendly to the rmap (VA
-+space). For workloads mostly using mapped pages, searching the rmap
-+can incur the highest CPU cost in the reclaim path.
-+
-+``lru_gen_look_around()`` exploits spatial locality to reduce the
-+trips into the rmap. It scans the adjacent PTEs of a young PTE and
-+promotes hot pages. If the scan was done cacheline efficiently, it
-+adds the PMD entry pointing to the PTE table to the Bloom filter. This
-+forms a feedback loop between the eviction and the aging.
-+
- Summary
- -------
- The multi-gen LRU can be disassembled into the following parts:
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4555,6 +4555,10 @@ static void lru_gen_age_node(struct pgli
- }
- }
-
-+/******************************************************************************
-+ * rmap/PT walk feedback
-+ ******************************************************************************/
-+
- /*
- * This function exploits spatial locality when shrink_folio_list() walks the
- * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If
diff --git a/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch b/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch
deleted file mode 100644
index a7dfb5ffe7..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch
+++ /dev/null
@@ -1,243 +0,0 @@
-From 397624e12244ec038f51cb1f178ccb7a2ec562e5 Mon Sep 17 00:00:00 2001
-From: "T.J. Alumbaugh" <talumbau@google.com>
-Date: Wed, 18 Jan 2023 00:18:23 +0000
-Subject: [PATCH 14/19] UPSTREAM: mm: multi-gen LRU: section for Bloom filters
-
-Move Bloom filters code into a dedicated section. Improve the design doc
-to explain Bloom filter usage and connection between aging and eviction in
-their use.
-
-Link: https://lkml.kernel.org/r/20230118001827.1040870-4-talumbau@google.com
-Change-Id: I73e866f687c1ed9f5c8538086aa39408b79897db
-Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
-Cc: Yu Zhao <yuzhao@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit ccbbbb85945d8f0255aa9dbc1b617017e2294f2c)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- Documentation/mm/multigen_lru.rst | 16 +++
- mm/vmscan.c | 180 +++++++++++++++---------------
- 2 files changed, 108 insertions(+), 88 deletions(-)
-
---- a/Documentation/mm/multigen_lru.rst
-+++ b/Documentation/mm/multigen_lru.rst
-@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done
- adds the PMD entry pointing to the PTE table to the Bloom filter. This
- forms a feedback loop between the eviction and the aging.
-
-+Bloom Filters
-+-------------
-+Bloom filters are a space and memory efficient data structure for set
-+membership test, i.e., test if an element is not in the set or may be
-+in the set.
-+
-+In the eviction path, specifically, in ``lru_gen_look_around()``, if a
-+PMD has a sufficient number of hot pages, its address is placed in the
-+filter. In the aging path, set membership means that the PTE range
-+will be scanned for young pages.
-+
-+Note that Bloom filters are probabilistic on set membership. If a test
-+is false positive, the cost is an additional scan of a range of PTEs,
-+which may yield hot pages anyway. Parameters of the filter itself can
-+control the false positive rate in the limit.
-+
- Summary
- -------
- The multi-gen LRU can be disassembled into the following parts:
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3209,6 +3209,98 @@ static bool __maybe_unused seq_is_valid(
- }
-
- /******************************************************************************
-+ * Bloom filters
-+ ******************************************************************************/
-+
-+/*
-+ * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when
-+ * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of
-+ * bits in a bitmap, k is the number of hash functions and n is the number of
-+ * inserted items.
-+ *
-+ * Page table walkers use one of the two filters to reduce their search space.
-+ * To get rid of non-leaf entries that no longer have enough leaf entries, the
-+ * aging uses the double-buffering technique to flip to the other filter each
-+ * time it produces a new generation. For non-leaf entries that have enough
-+ * leaf entries, the aging carries them over to the next generation in
-+ * walk_pmd_range(); the eviction also report them when walking the rmap
-+ * in lru_gen_look_around().
-+ *
-+ * For future optimizations:
-+ * 1. It's not necessary to keep both filters all the time. The spare one can be
-+ * freed after the RCU grace period and reallocated if needed again.
-+ * 2. And when reallocating, it's worth scaling its size according to the number
-+ * of inserted entries in the other filter, to reduce the memory overhead on
-+ * small systems and false positives on large systems.
-+ * 3. Jenkins' hash function is an alternative to Knuth's.
-+ */
-+#define BLOOM_FILTER_SHIFT 15
-+
-+static inline int filter_gen_from_seq(unsigned long seq)
-+{
-+ return seq % NR_BLOOM_FILTERS;
-+}
-+
-+static void get_item_key(void *item, int *key)
-+{
-+ u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2);
-+
-+ BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32));
-+
-+ key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1);
-+ key[1] = hash >> BLOOM_FILTER_SHIFT;
-+}
-+
-+static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
-+{
-+ int key[2];
-+ unsigned long *filter;
-+ int gen = filter_gen_from_seq(seq);
-+
-+ filter = READ_ONCE(lruvec->mm_state.filters[gen]);
-+ if (!filter)
-+ return true;
-+
-+ get_item_key(item, key);
-+
-+ return test_bit(key[0], filter) && test_bit(key[1], filter);
-+}
-+
-+static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
-+{
-+ int key[2];
-+ unsigned long *filter;
-+ int gen = filter_gen_from_seq(seq);
-+
-+ filter = READ_ONCE(lruvec->mm_state.filters[gen]);
-+ if (!filter)
-+ return;
-+
-+ get_item_key(item, key);
-+
-+ if (!test_bit(key[0], filter))
-+ set_bit(key[0], filter);
-+ if (!test_bit(key[1], filter))
-+ set_bit(key[1], filter);
-+}
-+
-+static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq)
-+{
-+ unsigned long *filter;
-+ int gen = filter_gen_from_seq(seq);
-+
-+ filter = lruvec->mm_state.filters[gen];
-+ if (filter) {
-+ bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT));
-+ return;
-+ }
-+
-+ filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT),
-+ __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
-+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
-+}
-+
-+/******************************************************************************
- * mm_struct list
- ******************************************************************************/
-
-@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct
- }
- #endif
-
--/*
-- * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when
-- * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of
-- * bits in a bitmap, k is the number of hash functions and n is the number of
-- * inserted items.
-- *
-- * Page table walkers use one of the two filters to reduce their search space.
-- * To get rid of non-leaf entries that no longer have enough leaf entries, the
-- * aging uses the double-buffering technique to flip to the other filter each
-- * time it produces a new generation. For non-leaf entries that have enough
-- * leaf entries, the aging carries them over to the next generation in
-- * walk_pmd_range(); the eviction also report them when walking the rmap
-- * in lru_gen_look_around().
-- *
-- * For future optimizations:
-- * 1. It's not necessary to keep both filters all the time. The spare one can be
-- * freed after the RCU grace period and reallocated if needed again.
-- * 2. And when reallocating, it's worth scaling its size according to the number
-- * of inserted entries in the other filter, to reduce the memory overhead on
-- * small systems and false positives on large systems.
-- * 3. Jenkins' hash function is an alternative to Knuth's.
-- */
--#define BLOOM_FILTER_SHIFT 15
--
--static inline int filter_gen_from_seq(unsigned long seq)
--{
-- return seq % NR_BLOOM_FILTERS;
--}
--
--static void get_item_key(void *item, int *key)
--{
-- u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2);
--
-- BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32));
--
-- key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1);
-- key[1] = hash >> BLOOM_FILTER_SHIFT;
--}
--
--static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq)
--{
-- unsigned long *filter;
-- int gen = filter_gen_from_seq(seq);
--
-- filter = lruvec->mm_state.filters[gen];
-- if (filter) {
-- bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT));
-- return;
-- }
--
-- filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT),
-- __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
-- WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
--}
--
--static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
--{
-- int key[2];
-- unsigned long *filter;
-- int gen = filter_gen_from_seq(seq);
--
-- filter = READ_ONCE(lruvec->mm_state.filters[gen]);
-- if (!filter)
-- return;
--
-- get_item_key(item, key);
--
-- if (!test_bit(key[0], filter))
-- set_bit(key[0], filter);
-- if (!test_bit(key[1], filter))
-- set_bit(key[1], filter);
--}
--
--static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
--{
-- int key[2];
-- unsigned long *filter;
-- int gen = filter_gen_from_seq(seq);
--
-- filter = READ_ONCE(lruvec->mm_state.filters[gen]);
-- if (!filter)
-- return true;
--
-- get_item_key(item, key);
--
-- return test_bit(key[0], filter) && test_bit(key[1], filter);
--}
--
- static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last)
- {
- int i;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch b/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch
deleted file mode 100644
index 101a0a3757..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch
+++ /dev/null
@@ -1,427 +0,0 @@
-From 48c916b812652f9453be5bd45a703728926d41ca Mon Sep 17 00:00:00 2001
-From: "T.J. Alumbaugh" <talumbau@google.com>
-Date: Wed, 18 Jan 2023 00:18:24 +0000
-Subject: [PATCH 15/19] UPSTREAM: mm: multi-gen LRU: section for memcg LRU
-
-Move memcg LRU code into a dedicated section. Improve the design doc to
-outline its architecture.
-
-Link: https://lkml.kernel.org/r/20230118001827.1040870-5-talumbau@google.com
-Change-Id: Id252e420cff7a858acb098cf2b3642da5c40f602
-Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
-Cc: Yu Zhao <yuzhao@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit 36c7b4db7c942ae9e1b111f0c6b468c8b2e33842)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- Documentation/mm/multigen_lru.rst | 33 +++-
- include/linux/mm_inline.h | 17 --
- include/linux/mmzone.h | 13 +-
- mm/memcontrol.c | 8 +-
- mm/vmscan.c | 250 +++++++++++++++++-------------
- 5 files changed, 178 insertions(+), 143 deletions(-)
-
---- a/Documentation/mm/multigen_lru.rst
-+++ b/Documentation/mm/multigen_lru.rst
-@@ -186,9 +186,40 @@ is false positive, the cost is an additi
- which may yield hot pages anyway. Parameters of the filter itself can
- control the false positive rate in the limit.
-
-+Memcg LRU
-+---------
-+An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs,
-+since each node and memcg combination has an LRU of folios (see
-+``mem_cgroup_lruvec()``). Its goal is to improve the scalability of
-+global reclaim, which is critical to system-wide memory overcommit in
-+data centers. Note that memcg LRU only applies to global reclaim.
-+
-+The basic structure of an memcg LRU can be understood by an analogy to
-+the active/inactive LRU (of folios):
-+
-+1. It has the young and the old (generations), i.e., the counterparts
-+ to the active and the inactive;
-+2. The increment of ``max_seq`` triggers promotion, i.e., the
-+ counterpart to activation;
-+3. Other events trigger similar operations, e.g., offlining an memcg
-+ triggers demotion, i.e., the counterpart to deactivation.
-+
-+In terms of global reclaim, it has two distinct features:
-+
-+1. Sharding, which allows each thread to start at a random memcg (in
-+ the old generation) and improves parallelism;
-+2. Eventual fairness, which allows direct reclaim to bail out at will
-+ and reduces latency without affecting fairness over some time.
-+
-+In terms of traversing memcgs during global reclaim, it improves the
-+best-case complexity from O(n) to O(1) and does not affect the
-+worst-case complexity O(n). Therefore, on average, it has a sublinear
-+complexity.
-+
- Summary
- -------
--The multi-gen LRU can be disassembled into the following parts:
-+The multi-gen LRU (of folios) can be disassembled into the following
-+parts:
-
- * Generations
- * Rmap walks
---- a/include/linux/mm_inline.h
-+++ b/include/linux/mm_inline.h
-@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void
- return current->in_lru_fault;
- }
-
--#ifdef CONFIG_MEMCG
--static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
--{
-- return READ_ONCE(lruvec->lrugen.seg);
--}
--#else
--static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
--{
-- return 0;
--}
--#endif
--
- static inline int lru_gen_from_seq(unsigned long seq)
- {
- return seq % MAX_NR_GENS;
-@@ -314,11 +302,6 @@ static inline bool lru_gen_in_fault(void
- return false;
- }
-
--static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
--{
-- return 0;
--}
--
- static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
- {
- return false;
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -368,15 +368,6 @@ struct page_vma_mapped_walk;
- #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
- #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
-
--/* see the comment on MEMCG_NR_GENS */
--enum {
-- MEMCG_LRU_NOP,
-- MEMCG_LRU_HEAD,
-- MEMCG_LRU_TAIL,
-- MEMCG_LRU_OLD,
-- MEMCG_LRU_YOUNG,
--};
--
- #ifdef CONFIG_LRU_GEN
-
- enum {
-@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgrou
- void lru_gen_online_memcg(struct mem_cgroup *memcg);
- void lru_gen_offline_memcg(struct mem_cgroup *memcg);
- void lru_gen_release_memcg(struct mem_cgroup *memcg);
--void lru_gen_rotate_memcg(struct lruvec *lruvec, int op);
-+void lru_gen_soft_reclaim(struct lruvec *lruvec);
-
- #else /* !CONFIG_MEMCG */
-
-@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg
- {
- }
-
--static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
-+static inline void lru_gen_soft_reclaim(struct lruvec *lruvec)
- {
- }
-
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struc
- struct mem_cgroup_tree_per_node *mctz;
-
- if (lru_gen_enabled()) {
-- struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec;
--
-- /* see the comment on MEMCG_NR_GENS */
-- if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD)
-- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD);
--
-+ if (soft_limit_excess(memcg))
-+ lru_gen_soft_reclaim(&memcg->nodeinfo[nid]->lruvec);
- return;
- }
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4692,6 +4692,148 @@ void lru_gen_look_around(struct page_vma
- }
-
- /******************************************************************************
-+ * memcg LRU
-+ ******************************************************************************/
-+
-+/* see the comment on MEMCG_NR_GENS */
-+enum {
-+ MEMCG_LRU_NOP,
-+ MEMCG_LRU_HEAD,
-+ MEMCG_LRU_TAIL,
-+ MEMCG_LRU_OLD,
-+ MEMCG_LRU_YOUNG,
-+};
-+
-+#ifdef CONFIG_MEMCG
-+
-+static int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return READ_ONCE(lruvec->lrugen.seg);
-+}
-+
-+static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
-+{
-+ int seg;
-+ int old, new;
-+ int bin = get_random_u32_below(MEMCG_NR_BINS);
-+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ seg = 0;
-+ new = old = lruvec->lrugen.gen;
-+
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (op == MEMCG_LRU_HEAD)
-+ seg = MEMCG_LRU_HEAD;
-+ else if (op == MEMCG_LRU_TAIL)
-+ seg = MEMCG_LRU_TAIL;
-+ else if (op == MEMCG_LRU_OLD)
-+ new = get_memcg_gen(pgdat->memcg_lru.seq);
-+ else if (op == MEMCG_LRU_YOUNG)
-+ new = get_memcg_gen(pgdat->memcg_lru.seq + 1);
-+ else
-+ VM_WARN_ON_ONCE(true);
-+
-+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
-+
-+ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
-+ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
-+ else
-+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
-+
-+ pgdat->memcg_lru.nr_memcgs[old]--;
-+ pgdat->memcg_lru.nr_memcgs[new]++;
-+
-+ lruvec->lrugen.gen = new;
-+ WRITE_ONCE(lruvec->lrugen.seg, seg);
-+
-+ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq))
-+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
-+}
-+
-+void lru_gen_online_memcg(struct mem_cgroup *memcg)
-+{
-+ int gen;
-+ int nid;
-+ int bin = get_random_u32_below(MEMCG_NR_BINS);
-+
-+ for_each_node(nid) {
-+ struct pglist_data *pgdat = NODE_DATA(nid);
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ gen = get_memcg_gen(pgdat->memcg_lru.seq);
-+
-+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]);
-+ pgdat->memcg_lru.nr_memcgs[gen]++;
-+
-+ lruvec->lrugen.gen = gen;
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
-+ }
-+}
-+
-+void lru_gen_offline_memcg(struct mem_cgroup *memcg)
-+{
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD);
-+ }
-+}
-+
-+void lru_gen_release_memcg(struct mem_cgroup *memcg)
-+{
-+ int gen;
-+ int nid;
-+
-+ for_each_node(nid) {
-+ struct pglist_data *pgdat = NODE_DATA(nid);
-+ struct lruvec *lruvec = get_lruvec(memcg, nid);
-+
-+ spin_lock(&pgdat->memcg_lru.lock);
-+
-+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
-+
-+ gen = lruvec->lrugen.gen;
-+
-+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
-+ pgdat->memcg_lru.nr_memcgs[gen]--;
-+
-+ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq))
-+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
-+
-+ spin_unlock(&pgdat->memcg_lru.lock);
-+ }
-+}
-+
-+void lru_gen_soft_reclaim(struct lruvec *lruvec)
-+{
-+ /* see the comment on MEMCG_NR_GENS */
-+ if (lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD)
-+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD);
-+}
-+
-+#else /* !CONFIG_MEMCG */
-+
-+static int lru_gen_memcg_seg(struct lruvec *lruvec)
-+{
-+ return 0;
-+}
-+
-+#endif
-+
-+/******************************************************************************
- * the eviction
- ******************************************************************************/
-
-@@ -5398,53 +5540,6 @@ done:
- pgdat->kswapd_failures = 0;
- }
-
--#ifdef CONFIG_MEMCG
--void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
--{
-- int seg;
-- int old, new;
-- int bin = get_random_u32_below(MEMCG_NR_BINS);
-- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
--
-- spin_lock(&pgdat->memcg_lru.lock);
--
-- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
--
-- seg = 0;
-- new = old = lruvec->lrugen.gen;
--
-- /* see the comment on MEMCG_NR_GENS */
-- if (op == MEMCG_LRU_HEAD)
-- seg = MEMCG_LRU_HEAD;
-- else if (op == MEMCG_LRU_TAIL)
-- seg = MEMCG_LRU_TAIL;
-- else if (op == MEMCG_LRU_OLD)
-- new = get_memcg_gen(pgdat->memcg_lru.seq);
-- else if (op == MEMCG_LRU_YOUNG)
-- new = get_memcg_gen(pgdat->memcg_lru.seq + 1);
-- else
-- VM_WARN_ON_ONCE(true);
--
-- hlist_nulls_del_rcu(&lruvec->lrugen.list);
--
-- if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
-- hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
-- else
-- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
--
-- pgdat->memcg_lru.nr_memcgs[old]--;
-- pgdat->memcg_lru.nr_memcgs[new]++;
--
-- lruvec->lrugen.gen = new;
-- WRITE_ONCE(lruvec->lrugen.seg, seg);
--
-- if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq))
-- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
--
-- spin_unlock(&pgdat->memcg_lru.lock);
--}
--#endif
--
- /******************************************************************************
- * state change
- ******************************************************************************/
-@@ -6090,67 +6185,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
- }
- }
-
--void lru_gen_online_memcg(struct mem_cgroup *memcg)
--{
-- int gen;
-- int nid;
-- int bin = get_random_u32_below(MEMCG_NR_BINS);
--
-- for_each_node(nid) {
-- struct pglist_data *pgdat = NODE_DATA(nid);
-- struct lruvec *lruvec = get_lruvec(memcg, nid);
--
-- spin_lock(&pgdat->memcg_lru.lock);
--
-- VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list));
--
-- gen = get_memcg_gen(pgdat->memcg_lru.seq);
--
-- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]);
-- pgdat->memcg_lru.nr_memcgs[gen]++;
--
-- lruvec->lrugen.gen = gen;
--
-- spin_unlock(&pgdat->memcg_lru.lock);
-- }
--}
--
--void lru_gen_offline_memcg(struct mem_cgroup *memcg)
--{
-- int nid;
--
-- for_each_node(nid) {
-- struct lruvec *lruvec = get_lruvec(memcg, nid);
--
-- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD);
-- }
--}
--
--void lru_gen_release_memcg(struct mem_cgroup *memcg)
--{
-- int gen;
-- int nid;
--
-- for_each_node(nid) {
-- struct pglist_data *pgdat = NODE_DATA(nid);
-- struct lruvec *lruvec = get_lruvec(memcg, nid);
--
-- spin_lock(&pgdat->memcg_lru.lock);
--
-- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
--
-- gen = lruvec->lrugen.gen;
--
-- hlist_nulls_del_rcu(&lruvec->lrugen.list);
-- pgdat->memcg_lru.nr_memcgs[gen]--;
--
-- if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq))
-- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
--
-- spin_unlock(&pgdat->memcg_lru.lock);
-- }
--}
--
- #endif /* CONFIG_MEMCG */
-
- static int __init init_lru_gen(void)
diff --git a/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch b/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch
deleted file mode 100644
index 1ee766f861..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From bec433f29537652ed054148edfd7e2183ddcf7c3 Mon Sep 17 00:00:00 2001
-From: "T.J. Alumbaugh" <talumbau@google.com>
-Date: Wed, 18 Jan 2023 00:18:25 +0000
-Subject: [PATCH 16/19] UPSTREAM: mm: multi-gen LRU: improve
- lru_gen_exit_memcg()
-
-Add warnings and poison ->next.
-
-Link: https://lkml.kernel.org/r/20230118001827.1040870-6-talumbau@google.com
-Change-Id: I53de9e04c1ae941e122b33cd45d2bbb5f34aae0c
-Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
-Cc: Yu Zhao <yuzhao@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit 37cc99979d04cca677c0ad5c0acd1149ec165d1b)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -6172,12 +6172,17 @@ void lru_gen_exit_memcg(struct mem_cgrou
- int i;
- int nid;
-
-+ VM_WARN_ON_ONCE(!list_empty(&memcg->mm_list.fifo));
-+
- for_each_node(nid) {
- struct lruvec *lruvec = get_lruvec(memcg, nid);
-
-+ VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers);
- VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
- sizeof(lruvec->lrugen.nr_pages)));
-
-+ lruvec->lrugen.list.next = LIST_POISON1;
-+
- for (i = 0; i < NR_BLOOM_FILTERS; i++) {
- bitmap_free(lruvec->mm_state.filters[i]);
- lruvec->mm_state.filters[i] = NULL;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch b/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch
deleted file mode 100644
index 2273977dc9..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From fc0e3b06e0f19917b7ecad7967a72f61d4743644 Mon Sep 17 00:00:00 2001
-From: "T.J. Alumbaugh" <talumbau@google.com>
-Date: Wed, 18 Jan 2023 00:18:26 +0000
-Subject: [PATCH 17/19] UPSTREAM: mm: multi-gen LRU: improve walk_pmd_range()
-
-Improve readability of walk_pmd_range() and walk_pmd_range_locked().
-
-Link: https://lkml.kernel.org/r/20230118001827.1040870-7-talumbau@google.com
-Change-Id: Ia084fbf53fe989673b7804ca8ca520af12d7d52a
-Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
-Cc: Yu Zhao <yuzhao@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit b5ff4133617d0eced35b685da0bd0929dd9fabb7)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 40 ++++++++++++++++++++--------------------
- 1 file changed, 20 insertions(+), 20 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3980,8 +3980,8 @@ restart:
- }
-
- #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
--static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
-- struct mm_walk *args, unsigned long *bitmap, unsigned long *start)
-+static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma,
-+ struct mm_walk *args, unsigned long *bitmap, unsigned long *first)
- {
- int i;
- pmd_t *pmd;
-@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t
- VM_WARN_ON_ONCE(pud_leaf(*pud));
-
- /* try to batch at most 1+MIN_LRU_BATCH+1 entries */
-- if (*start == -1) {
-- *start = next;
-+ if (*first == -1) {
-+ *first = addr;
-+ bitmap_zero(bitmap, MIN_LRU_BATCH);
- return;
- }
-
-- i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start);
-+ i = addr == -1 ? 0 : pmd_index(addr) - pmd_index(*first);
- if (i && i <= MIN_LRU_BATCH) {
- __set_bit(i - 1, bitmap);
- return;
- }
-
-- pmd = pmd_offset(pud, *start);
-+ pmd = pmd_offset(pud, *first);
-
- ptl = pmd_lockptr(args->mm, pmd);
- if (!spin_trylock(ptl))
-@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t
- do {
- unsigned long pfn;
- struct folio *folio;
-- unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start;
-+
-+ /* don't round down the first address */
-+ addr = i ? (*first & PMD_MASK) + i * PMD_SIZE : *first;
-
- pfn = get_pmd_pfn(pmd[i], vma, addr);
- if (pfn == -1)
- goto next;
-
- if (!pmd_trans_huge(pmd[i])) {
-- if (arch_has_hw_nonleaf_pmd_young() &&
-- get_cap(LRU_GEN_NONLEAF_YOUNG))
-+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG))
- pmdp_test_and_clear_young(vma, addr, pmd + i);
- goto next;
- }
-@@ -4053,12 +4055,11 @@ next:
- arch_leave_lazy_mmu_mode();
- spin_unlock(ptl);
- done:
-- *start = -1;
-- bitmap_zero(bitmap, MIN_LRU_BATCH);
-+ *first = -1;
- }
- #else
--static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
-- struct mm_walk *args, unsigned long *bitmap, unsigned long *start)
-+static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma,
-+ struct mm_walk *args, unsigned long *bitmap, unsigned long *first)
- {
- }
- #endif
-@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, u
- unsigned long next;
- unsigned long addr;
- struct vm_area_struct *vma;
-- unsigned long pos = -1;
-+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)];
-+ unsigned long first = -1;
- struct lru_gen_mm_walk *walk = args->private;
-- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {};
-
- VM_WARN_ON_ONCE(pud_leaf(*pud));
-
-@@ -4115,18 +4116,17 @@ restart:
- if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
- continue;
-
-- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
-+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first);
- continue;
- }
- #endif
- walk->mm_stats[MM_NONLEAF_TOTAL]++;
-
-- if (arch_has_hw_nonleaf_pmd_young() &&
-- get_cap(LRU_GEN_NONLEAF_YOUNG)) {
-+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG)) {
- if (!pmd_young(val))
- continue;
-
-- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
-+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first);
- }
-
- if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i))
-@@ -4143,7 +4143,7 @@ restart:
- update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i);
- }
-
-- walk_pmd_range_locked(pud, -1, vma, args, bitmap, &pos);
-+ walk_pmd_range_locked(pud, -1, vma, args, bitmap, &first);
-
- if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end))
- goto restart;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch b/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch
deleted file mode 100644
index 856199574a..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From e604c3ccb4dfbdde2467fccef9bb36170a392695 Mon Sep 17 00:00:00 2001
-From: "T.J. Alumbaugh" <talumbau@google.com>
-Date: Wed, 18 Jan 2023 00:18:27 +0000
-Subject: [PATCH 18/19] UPSTREAM: mm: multi-gen LRU: simplify
- lru_gen_look_around()
-
-Update the folio generation in place with or without
-current->reclaim_state->mm_walk. The LRU lock is held for longer, if
-mm_walk is NULL and the number of folios to update is more than
-PAGEVEC_SIZE.
-
-This causes a measurable regression from the LRU lock contention during a
-microbencmark. But a tiny regression is not worth the complexity.
-
-Link: https://lkml.kernel.org/r/20230118001827.1040870-8-talumbau@google.com
-Change-Id: I9ce18b4f4062e6c1c13c98ece9422478eb8e1846
-Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
-Cc: Yu Zhao <yuzhao@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-(cherry picked from commit abf086721a2f1e6897c57796f7268df1b194c750)
-Bug: 274865848
-Signed-off-by: T.J. Mercier <tjmercier@google.com>
----
- mm/vmscan.c | 73 +++++++++++++++++------------------------------------
- 1 file changed, 23 insertions(+), 50 deletions(-)
-
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -4573,13 +4573,12 @@ static void lru_gen_age_node(struct pgli
- void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
- {
- int i;
-- pte_t *pte;
- unsigned long start;
- unsigned long end;
-- unsigned long addr;
- struct lru_gen_mm_walk *walk;
- int young = 0;
-- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {};
-+ pte_t *pte = pvmw->pte;
-+ unsigned long addr = pvmw->address;
- struct folio *folio = pfn_folio(pvmw->pfn);
- struct mem_cgroup *memcg = folio_memcg(folio);
- struct pglist_data *pgdat = folio_pgdat(folio);
-@@ -4596,25 +4595,28 @@ void lru_gen_look_around(struct page_vma
- /* avoid taking the LRU lock under the PTL when possible */
- walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
-
-- start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start);
-- end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1;
-+ start = max(addr & PMD_MASK, pvmw->vma->vm_start);
-+ end = min(addr | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1;
-
- if (end - start > MIN_LRU_BATCH * PAGE_SIZE) {
-- if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2)
-+ if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2)
- end = start + MIN_LRU_BATCH * PAGE_SIZE;
-- else if (end - pvmw->address < MIN_LRU_BATCH * PAGE_SIZE / 2)
-+ else if (end - addr < MIN_LRU_BATCH * PAGE_SIZE / 2)
- start = end - MIN_LRU_BATCH * PAGE_SIZE;
- else {
-- start = pvmw->address - MIN_LRU_BATCH * PAGE_SIZE / 2;
-- end = pvmw->address + MIN_LRU_BATCH * PAGE_SIZE / 2;
-+ start = addr - MIN_LRU_BATCH * PAGE_SIZE / 2;
-+ end = addr + MIN_LRU_BATCH * PAGE_SIZE / 2;
- }
- }
-
-- pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE;
-+ /* folio_update_gen() requires stable folio_memcg() */
-+ if (!mem_cgroup_trylock_pages(memcg))
-+ return;
-
-- rcu_read_lock();
- arch_enter_lazy_mmu_mode();
-
-+ pte -= (addr - start) / PAGE_SIZE;
-+
- for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
- unsigned long pfn;
-
-@@ -4639,56 +4641,27 @@ void lru_gen_look_around(struct page_vma
- !folio_test_swapcache(folio)))
- folio_mark_dirty(folio);
-
-+ if (walk) {
-+ old_gen = folio_update_gen(folio, new_gen);
-+ if (old_gen >= 0 && old_gen != new_gen)
-+ update_batch_size(walk, folio, old_gen, new_gen);
-+
-+ continue;
-+ }
-+
- old_gen = folio_lru_gen(folio);
- if (old_gen < 0)
- folio_set_referenced(folio);
- else if (old_gen != new_gen)
-- __set_bit(i, bitmap);
-+ folio_activate(folio);
- }
-
- arch_leave_lazy_mmu_mode();
-- rcu_read_unlock();
-+ mem_cgroup_unlock_pages();
-
- /* feedback from rmap walkers to page table walkers */
- if (suitable_to_scan(i, young))
- update_bloom_filter(lruvec, max_seq, pvmw->pmd);
--
-- if (!walk && bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) {
-- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
-- folio = pfn_folio(pte_pfn(pte[i]));
-- folio_activate(folio);
-- }
-- return;
-- }
--
-- /* folio_update_gen() requires stable folio_memcg() */
-- if (!mem_cgroup_trylock_pages(memcg))
-- return;
--
-- if (!walk) {
-- spin_lock_irq(&lruvec->lru_lock);
-- new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq);
-- }
--
-- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
-- folio = pfn_folio(pte_pfn(pte[i]));
-- if (folio_memcg_rcu(folio) != memcg)
-- continue;
--
-- old_gen = folio_update_gen(folio, new_gen);
-- if (old_gen < 0 || old_gen == new_gen)
-- continue;
--
-- if (walk)
-- update_batch_size(walk, folio, old_gen, new_gen);
-- else
-- lru_gen_update_size(lruvec, folio, old_gen, new_gen);
-- }
--
-- if (!walk)
-- spin_unlock_irq(&lruvec->lru_lock);
--
-- mem_cgroup_unlock_pages();
- }
-
- /******************************************************************************
diff --git a/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch b/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch
deleted file mode 100644
index 1b0459cdb9..0000000000
--- a/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch
+++ /dev/null
@@ -1,273 +0,0 @@
-From 418038c22452df38cde519cc8c662bb15139764a Mon Sep 17 00:00:00 2001
-From: Kalesh Singh <kaleshsingh@google.com>
-Date: Thu, 13 Apr 2023 14:43:26 -0700
-Subject: [PATCH 19/19] mm: Multi-gen LRU: remove wait_event_killable()
-
-Android 14 and later default to MGLRU [1] and field telemetry showed
-occasional long tail latency (>100ms) in the reclaim path.
-
-Tracing revealed priority inversion in the reclaim path. In
-try_to_inc_max_seq(), when high priority tasks were blocked on
-wait_event_killable(), the preemption of the low priority task to call
-wake_up_all() caused those high priority tasks to wait longer than
-necessary. In general, this problem is not different from others of its
-kind, e.g., one caused by mutex_lock(). However, it is specific to MGLRU
-because it introduced the new wait queue lruvec->mm_state.wait.
-
-The purpose of this new wait queue is to avoid the thundering herd
-problem. If many direct reclaimers rush into try_to_inc_max_seq(), only
-one can succeed, i.e., the one to wake up the rest, and the rest who
-failed might cause premature OOM kills if they do not wait. So far there
-is no evidence supporting this scenario, based on how often the wait has
-been hit. And this begs the question how useful the wait queue is in
-practice.
-
-Based on Minchan's recommendation, which is in line with his commit
-6d4675e60135 ("mm: don't be stuck to rmap lock on reclaim path") and the
-rest of the MGLRU code which also uses trylock when possible, remove the
-wait queue.
-
-[1] https://android-review.googlesource.com/q/I7ed7fbfd6ef9ce10053347528125dd98c39e50bf
-
-Link: https://lkml.kernel.org/r/20230413214326.2147568-1-kaleshsingh@google.com
-Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
-Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
-Suggested-by: Minchan Kim <minchan@kernel.org>
-Reported-by: Wei Wang <wvw@google.com>
-Acked-by: Yu Zhao <yuzhao@google.com>
-Cc: Minchan Kim <minchan@kernel.org>
-Cc: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
-Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
-Cc: Suleiman Souhlal <suleiman@google.com>
-Cc: Suren Baghdasaryan <surenb@google.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- include/linux/mmzone.h | 8 +--
- mm/vmscan.c | 112 +++++++++++++++--------------------------
- 2 files changed, 42 insertions(+), 78 deletions(-)
-
---- a/include/linux/mmzone.h
-+++ b/include/linux/mmzone.h
-@@ -453,18 +453,14 @@ enum {
- struct lru_gen_mm_state {
- /* set to max_seq after each iteration */
- unsigned long seq;
-- /* where the current iteration continues (inclusive) */
-+ /* where the current iteration continues after */
- struct list_head *head;
-- /* where the last iteration ended (exclusive) */
-+ /* where the last iteration ended before */
- struct list_head *tail;
-- /* to wait for the last page table walker to finish */
-- struct wait_queue_head wait;
- /* Bloom filters flip after each iteration */
- unsigned long *filters[NR_BLOOM_FILTERS];
- /* the mm stats for debugging */
- unsigned long stats[NR_HIST_GENS][NR_MM_STATS];
-- /* the number of concurrent page table walkers */
-- int nr_walkers;
- };
-
- struct lru_gen_mm_walk {
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm
- if (!lruvec)
- continue;
-
-- /* where the last iteration ended (exclusive) */
-+ /* where the current iteration continues after */
-+ if (lruvec->mm_state.head == &mm->lru_gen.list)
-+ lruvec->mm_state.head = lruvec->mm_state.head->prev;
-+
-+ /* where the last iteration ended before */
- if (lruvec->mm_state.tail == &mm->lru_gen.list)
- lruvec->mm_state.tail = lruvec->mm_state.tail->next;
--
-- /* where the current iteration continues (inclusive) */
-- if (lruvec->mm_state.head != &mm->lru_gen.list)
-- continue;
--
-- lruvec->mm_state.head = lruvec->mm_state.head->next;
-- /* the deletion ends the current iteration */
-- if (lruvec->mm_state.head == &mm_list->fifo)
-- WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1);
- }
-
- list_del_init(&mm->lru_gen.list);
-@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruve
- struct mm_struct **iter)
- {
- bool first = false;
-- bool last = true;
-+ bool last = false;
- struct mm_struct *mm = NULL;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
- struct lru_gen_mm_state *mm_state = &lruvec->mm_state;
-
- /*
-- * There are four interesting cases for this page table walker:
-- * 1. It tries to start a new iteration of mm_list with a stale max_seq;
-- * there is nothing left to do.
-- * 2. It's the first of the current generation, and it needs to reset
-- * the Bloom filter for the next generation.
-- * 3. It reaches the end of mm_list, and it needs to increment
-- * mm_state->seq; the iteration is done.
-- * 4. It's the last of the current generation, and it needs to reset the
-- * mm stats counters for the next generation.
-+ * mm_state->seq is incremented after each iteration of mm_list. There
-+ * are three interesting cases for this page table walker:
-+ * 1. It tries to start a new iteration with a stale max_seq: there is
-+ * nothing left to do.
-+ * 2. It started the next iteration: it needs to reset the Bloom filter
-+ * so that a fresh set of PTE tables can be recorded.
-+ * 3. It ended the current iteration: it needs to reset the mm stats
-+ * counters and tell its caller to increment max_seq.
- */
- spin_lock(&mm_list->lock);
-
- VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq);
-- VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq);
-- VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers);
-
-- if (walk->max_seq <= mm_state->seq) {
-- if (!*iter)
-- last = false;
-+ if (walk->max_seq <= mm_state->seq)
- goto done;
-- }
-
-- if (!mm_state->nr_walkers) {
-- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
-+ if (!mm_state->head)
-+ mm_state->head = &mm_list->fifo;
-
-- mm_state->head = mm_list->fifo.next;
-+ if (mm_state->head == &mm_list->fifo)
- first = true;
-- }
--
-- while (!mm && mm_state->head != &mm_list->fifo) {
-- mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
-
-+ do {
- mm_state->head = mm_state->head->next;
-+ if (mm_state->head == &mm_list->fifo) {
-+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
-+ last = true;
-+ break;
-+ }
-
- /* force scan for those added after the last iteration */
-- if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) {
-- mm_state->tail = mm_state->head;
-+ if (!mm_state->tail || mm_state->tail == mm_state->head) {
-+ mm_state->tail = mm_state->head->next;
- walk->force_scan = true;
- }
-
-+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
- if (should_skip_mm(mm, walk))
- mm = NULL;
-- }
--
-- if (mm_state->head == &mm_list->fifo)
-- WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
-+ } while (!mm);
- done:
-- if (*iter && !mm)
-- mm_state->nr_walkers--;
-- if (!*iter && mm)
-- mm_state->nr_walkers++;
--
-- if (mm_state->nr_walkers)
-- last = false;
--
- if (*iter || last)
- reset_mm_stats(lruvec, walk, last);
-
-@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struc
-
- VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq);
-
-- if (max_seq > mm_state->seq && !mm_state->nr_walkers) {
-- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
--
-+ if (max_seq > mm_state->seq) {
-+ mm_state->head = NULL;
-+ mm_state->tail = NULL;
- WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
- reset_mm_stats(lruvec, NULL, true);
- success = true;
-@@ -4172,10 +4153,6 @@ restart:
-
- walk_pmd_range(&val, addr, next, args);
-
-- /* a racy check to curtail the waiting time */
-- if (wq_has_sleeper(&walk->lruvec->mm_state.wait))
-- return 1;
--
- if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
- end = (addr | ~PUD_MASK) + 1;
- goto done;
-@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruve
- walk->next_addr = FIRST_USER_ADDRESS;
-
- do {
-+ DEFINE_MAX_SEQ(lruvec);
-+
- err = -EBUSY;
-
-+ /* another thread might have called inc_max_seq() */
-+ if (walk->max_seq != max_seq)
-+ break;
-+
- /* folio_update_gen() requires stable folio_memcg() */
- if (!mem_cgroup_trylock_pages(memcg))
- break;
-@@ -4444,25 +4427,12 @@ static bool try_to_inc_max_seq(struct lr
- success = iterate_mm_list(lruvec, walk, &mm);
- if (mm)
- walk_mm(lruvec, mm, walk);
--
-- cond_resched();
- } while (mm);
- done:
-- if (!success) {
-- if (sc->priority <= DEF_PRIORITY - 2)
-- wait_event_killable(lruvec->mm_state.wait,
-- max_seq < READ_ONCE(lrugen->max_seq));
-- return false;
-- }
-+ if (success)
-+ inc_max_seq(lruvec, can_swap, force_scan);
-
-- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
--
-- inc_max_seq(lruvec, can_swap, force_scan);
-- /* either this sees any waiters or they will see updated max_seq */
-- if (wq_has_sleeper(&lruvec->mm_state.wait))
-- wake_up_all(&lruvec->mm_state.wait);
--
-- return true;
-+ return success;
- }
-
- /******************************************************************************
-@@ -6117,7 +6087,6 @@ void lru_gen_init_lruvec(struct lruvec *
- INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]);
-
- lruvec->mm_state.seq = MIN_NR_GENS;
-- init_waitqueue_head(&lruvec->mm_state.wait);
- }
-
- #ifdef CONFIG_MEMCG
-@@ -6150,7 +6119,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
- for_each_node(nid) {
- struct lruvec *lruvec = get_lruvec(memcg, nid);
-
-- VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers);
- VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
- sizeof(lruvec->lrugen.nr_pages)));
-
diff --git a/target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch b/target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch
deleted file mode 100644
index 2e6d881fe9..0000000000
--- a/target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From e2192de59e457aef8d1f055a452131f0b3e5d097 Mon Sep 17 00:00:00 2001
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Wed, 18 Jan 2023 14:26:53 +0100
-Subject: [PATCH] bitfield: add FIELD_PREP_CONST()
-
-Neither FIELD_PREP() nor *_encode_bits() can be used
-in constant contexts (such as initializers), but we
-don't want to define shift constants for all masks
-just for use in initializers, and having checks that
-the values fit is also useful.
-
-Therefore, add FIELD_PREP_CONST() which is a smaller
-version of FIELD_PREP() that can only take constant
-arguments and has less friendly (but not less strict)
-error checks, and expands to a constant value.
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Link: https://lore.kernel.org/r/20230118142652.53f20593504b.Iaeea0aee77a6493d70e573b4aa55c91c00e01e4b@changeid
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/linux/bitfield.h | 26 ++++++++++++++++++++++++++
- 1 file changed, 26 insertions(+)
-
---- a/include/linux/bitfield.h
-+++ b/include/linux/bitfield.h
-@@ -115,6 +115,32 @@
- ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
- })
-
-+#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
-+
-+/**
-+ * FIELD_PREP_CONST() - prepare a constant bitfield element
-+ * @_mask: shifted mask defining the field's length and position
-+ * @_val: value to put in the field
-+ *
-+ * FIELD_PREP_CONST() masks and shifts up the value. The result should
-+ * be combined with other fields of the bitfield using logical OR.
-+ *
-+ * Unlike FIELD_PREP() this is a constant expression and can therefore
-+ * be used in initializers. Error checking is less comfortable for this
-+ * version, and non-constant masks cannot be used.
-+ */
-+#define FIELD_PREP_CONST(_mask, _val) \
-+ ( \
-+ /* mask must be non-zero */ \
-+ BUILD_BUG_ON_ZERO((_mask) == 0) + \
-+ /* check if value fits */ \
-+ BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \
-+ /* check if mask is contiguous */ \
-+ __BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \
-+ /* and create the value */ \
-+ (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \
-+ )
-+
- /**
- * FIELD_GET() - extract a bitfield element
- * @_mask: shifted mask defining the field's length and position
diff --git a/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch b/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch
deleted file mode 100644
index d8d0cf9555..0000000000
--- a/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 579aee9fc594af94c242068c011b0233563d4bbf Mon Sep 17 00:00:00 2001
-From: Stephen Rothwell <sfr@canb.auug.org.au>
-Date: Mon, 10 Oct 2022 16:57:21 +1100
-Subject: [PATCH] powerpc: suppress some linker warnings in recent linker
- versions
-
-This is a follow on from commit
-
- 0d362be5b142 ("Makefile: link with -z noexecstack --no-warn-rwx-segments")
-
-for arch/powerpc/boot to address wanrings like:
-
- ld: warning: opal-calls.o: missing .note.GNU-stack section implies executable stack
- ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
- ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions
-
-This fixes issue https://github.com/linuxppc/issues/issues/417
-
-Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/20221010165721.106267e6@canb.auug.org.au
----
- arch/powerpc/boot/wrapper | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -215,6 +215,11 @@ ld_version()
- }'
- }
-
-+ld_is_lld()
-+{
-+ ${CROSS}ld -V 2>&1 | grep -q LLD
-+}
-+
- # Do not include PT_INTERP segment when linking pie. Non-pie linking
- # just ignores this option.
- LD_VERSION=$(${CROSS}ld --version | ld_version)
-@@ -223,6 +228,14 @@ if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VE
- nodl="--no-dynamic-linker"
- fi
-
-+# suppress some warnings in recent ld versions
-+nowarn="-z noexecstack"
-+if ! ld_is_lld; then
-+ if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then
-+ nowarn="$nowarn --no-warn-rwx-segments"
-+ fi
-+fi
-+
- platformo=$object/"$platform".o
- lds=$object/zImage.lds
- ext=strip
-@@ -504,7 +517,7 @@ if [ "$platform" != "miboot" ]; then
- text_start="-Ttext $link_address"
- fi
- #link everything
-- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \
-+ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $nowarn $rodynamic $notext -o "$ofile" $map \
- $platformo $tmp $object/wrapper.a
- rm $tmp
- fi
diff --git a/target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch b/target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch
deleted file mode 100644
index 239adff1af..0000000000
--- a/target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From 66a5c40f60f5d88ad8d47ba6a4ba05892853fa1f Mon Sep 17 00:00:00 2001
-From: Tanzir Hasan <tanzirh@google.com>
-Date: Tue, 26 Dec 2023 18:00:00 +0000
-Subject: [PATCH] kernel.h: removed REPEAT_BYTE from kernel.h
-
-This patch creates wordpart.h and includes it in asm/word-at-a-time.h
-for all architectures. WORD_AT_A_TIME_CONSTANTS depends on kernel.h
-because of REPEAT_BYTE. Moving this to another header and including it
-where necessary allows us to not include the bloated kernel.h. Making
-this implicit dependency on REPEAT_BYTE explicit allows for later
-improvements in the lib/string.c inclusion list.
-
-Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
-Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: Tanzir Hasan <tanzirh@google.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Link: https://lore.kernel.org/r/20231226-libstringheader-v6-1-80aa08c7652c@google.com
-Signed-off-by: Kees Cook <keescook@chromium.org>
----
- arch/arm/include/asm/word-at-a-time.h | 3 ++-
- arch/arm64/include/asm/word-at-a-time.h | 3 ++-
- arch/powerpc/include/asm/word-at-a-time.h | 4 ++--
- arch/riscv/include/asm/word-at-a-time.h | 3 ++-
- arch/s390/include/asm/word-at-a-time.h | 3 ++-
- arch/sh/include/asm/word-at-a-time.h | 2 ++
- arch/x86/include/asm/word-at-a-time.h | 3 ++-
- arch/x86/kvm/mmu/mmu.c | 1 +
- fs/namei.c | 2 +-
- include/asm-generic/word-at-a-time.h | 3 ++-
- include/linux/kernel.h | 8 --------
- include/linux/wordpart.h | 13 +++++++++++++
- 12 files changed, 31 insertions(+), 17 deletions(-)
- create mode 100644 include/linux/wordpart.h
-
---- a/arch/arm/include/asm/word-at-a-time.h
-+++ b/arch/arm/include/asm/word-at-a-time.h
-@@ -8,7 +8,8 @@
- * Little-endian word-at-a-time zero byte handling.
- * Heavily based on the x86 algorithm.
- */
--#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/wordpart.h>
-
- struct word_at_a_time {
- const unsigned long one_bits, high_bits;
---- a/arch/arm64/include/asm/word-at-a-time.h
-+++ b/arch/arm64/include/asm/word-at-a-time.h
-@@ -9,7 +9,8 @@
-
- #ifndef __AARCH64EB__
-
--#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/wordpart.h>
-
- struct word_at_a_time {
- const unsigned long one_bits, high_bits;
---- a/arch/powerpc/include/asm/word-at-a-time.h
-+++ b/arch/powerpc/include/asm/word-at-a-time.h
-@@ -4,8 +4,8 @@
- /*
- * Word-at-a-time interfaces for PowerPC.
- */
--
--#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/wordpart.h>
- #include <asm/asm-compat.h>
- #include <asm/extable.h>
-
---- a/arch/sh/include/asm/word-at-a-time.h
-+++ b/arch/sh/include/asm/word-at-a-time.h
-@@ -5,6 +5,8 @@
- #ifdef CONFIG_CPU_BIG_ENDIAN
- # include <asm-generic/word-at-a-time.h>
- #else
-+#include <linux/bitops.h>
-+#include <linux/wordpart.h>
- /*
- * Little-endian version cribbed from x86.
- */
---- a/arch/x86/include/asm/word-at-a-time.h
-+++ b/arch/x86/include/asm/word-at-a-time.h
-@@ -2,7 +2,8 @@
- #ifndef _ASM_WORD_AT_A_TIME_H
- #define _ASM_WORD_AT_A_TIME_H
-
--#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/wordpart.h>
-
- /*
- * This is largely generic for little-endian machines, but the
---- a/arch/x86/kvm/mmu/mmu.c
-+++ b/arch/x86/kvm/mmu/mmu.c
-@@ -44,6 +44,7 @@
- #include <linux/kern_levels.h>
- #include <linux/kstrtox.h>
- #include <linux/kthread.h>
-+#include <linux/wordpart.h>
-
- #include <asm/page.h>
- #include <asm/memtype.h>
---- a/fs/namei.c
-+++ b/fs/namei.c
-@@ -17,8 +17,8 @@
-
- #include <linux/init.h>
- #include <linux/export.h>
--#include <linux/kernel.h>
- #include <linux/slab.h>
-+#include <linux/wordpart.h>
- #include <linux/fs.h>
- #include <linux/namei.h>
- #include <linux/pagemap.h>
---- a/include/asm-generic/word-at-a-time.h
-+++ b/include/asm-generic/word-at-a-time.h
-@@ -2,7 +2,8 @@
- #ifndef _ASM_WORD_AT_A_TIME_H
- #define _ASM_WORD_AT_A_TIME_H
-
--#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/wordpart.h>
- #include <asm/byteorder.h>
-
- #ifdef __BIG_ENDIAN
---- a/include/linux/kernel.h
-+++ b/include/linux/kernel.h
-@@ -36,14 +36,6 @@
-
- #define STACK_MAGIC 0xdeadbeef
-
--/**
-- * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
-- * @x: value to repeat
-- *
-- * NOTE: @x is not checked for > 0xff; larger values produce odd results.
-- */
--#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
--
- /* generic data direction definitions */
- #define READ 0
- #define WRITE 1
---- /dev/null
-+++ b/include/linux/wordpart.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+
-+#ifndef _LINUX_WORDPART_H
-+#define _LINUX_WORDPART_H
-+/**
-+ * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
-+ * @x: value to repeat
-+ *
-+ * NOTE: @x is not checked for > 0xff; larger values produce odd results.
-+ */
-+#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
-+
-+#endif // _LINUX_WORDPART_H
diff --git a/target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch b/target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch
deleted file mode 100644
index 9bbd515852..0000000000
--- a/target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From adeb04362d74188c1e22ccb824b15a0a7b3de2f4 Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Wed, 14 Feb 2024 19:26:32 +0200
-Subject: [PATCH] kernel.h: Move upper_*_bits() and lower_*_bits() to
- wordpart.h
-
-The wordpart.h header is collecting APIs related to the handling
-parts of the word (usually in byte granularity). The upper_*_bits()
-and lower_*_bits() are good candidates to be moved to there.
-
-This helps to clean up header dependency hell with regard to kernel.h
-as the latter gathers completely unrelated stuff together and slows
-down compilation (especially when it's included into other header).
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Link: https://lore.kernel.org/r/20240214172752.3605073-1-andriy.shevchenko@linux.intel.com
-Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
-Signed-off-by: Kees Cook <keescook@chromium.org>
----
- include/linux/kernel.h | 30 ++----------------------------
- include/linux/wordpart.h | 29 +++++++++++++++++++++++++++++
- 2 files changed, 31 insertions(+), 28 deletions(-)
-
---- a/include/linux/kernel.h
-+++ b/include/linux/kernel.h
-@@ -30,6 +30,8 @@
- #include <linux/build_bug.h>
- #include <linux/static_call_types.h>
- #include <linux/instruction_pointer.h>
-+#include <linux/wordpart.h>
-+
- #include <asm/byteorder.h>
-
- #include <uapi/linux/kernel.h>
-@@ -55,34 +57,6 @@
- } \
- )
-
--/**
-- * upper_32_bits - return bits 32-63 of a number
-- * @n: the number we're accessing
-- *
-- * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
-- * the "right shift count >= width of type" warning when that quantity is
-- * 32-bits.
-- */
--#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
--
--/**
-- * lower_32_bits - return bits 0-31 of a number
-- * @n: the number we're accessing
-- */
--#define lower_32_bits(n) ((u32)((n) & 0xffffffff))
--
--/**
-- * upper_16_bits - return bits 16-31 of a number
-- * @n: the number we're accessing
-- */
--#define upper_16_bits(n) ((u16)((n) >> 16))
--
--/**
-- * lower_16_bits - return bits 0-15 of a number
-- * @n: the number we're accessing
-- */
--#define lower_16_bits(n) ((u16)((n) & 0xffff))
--
- struct completion;
- struct user;
-
---- a/include/linux/wordpart.h
-+++ b/include/linux/wordpart.h
-@@ -2,6 +2,35 @@
-
- #ifndef _LINUX_WORDPART_H
- #define _LINUX_WORDPART_H
-+
-+/**
-+ * upper_32_bits - return bits 32-63 of a number
-+ * @n: the number we're accessing
-+ *
-+ * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
-+ * the "right shift count >= width of type" warning when that quantity is
-+ * 32-bits.
-+ */
-+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
-+
-+/**
-+ * lower_32_bits - return bits 0-31 of a number
-+ * @n: the number we're accessing
-+ */
-+#define lower_32_bits(n) ((u32)((n) & 0xffffffff))
-+
-+/**
-+ * upper_16_bits - return bits 16-31 of a number
-+ * @n: the number we're accessing
-+ */
-+#define upper_16_bits(n) ((u16)((n) >> 16))
-+
-+/**
-+ * lower_16_bits - return bits 0-15 of a number
-+ * @n: the number we're accessing
-+ */
-+#define lower_16_bits(n) ((u16)((n) & 0xffff))
-+
- /**
- * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
- * @x: value to repeat
diff --git a/target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch b/target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch
deleted file mode 100644
index ba01bac8d2..0000000000
--- a/target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 8e7daa85641c9559c113f6b217bdc923397de77c Mon Sep 17 00:00:00 2001
-From: William Zhang <william.zhang@broadcom.com>
-Date: Thu, 22 Feb 2024 19:47:58 -0800
-Subject: [PATCH] mtd: rawnand: brcmnand: Support write protection setting from
- dts
-
-The write protection feature is controlled by the module parameter wp_on
-with default set to enabled. But not all the board use this feature
-especially in BCMBCA broadband board. And module parameter is not
-sufficient as different board can have different option. Add a device
-tree property and allow this feature to be configured through the board
-dts on per board basis.
-
-Signed-off-by: William Zhang <william.zhang@broadcom.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Reviewed-by: Kamal Dasu <kamal.dasu@broadcom.com>
-Reviewed-by: David Regan <dregan@broadcom.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-william.zhang@broadcom.com
----
- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-@@ -3188,6 +3188,10 @@ int brcmnand_probe(struct platform_devic
- /* Disable XOR addressing */
- brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
-
-+ /* Check if the board connects the WP pin */
-+ if (of_property_read_bool(dn, "brcm,wp-not-connected"))
-+ wp_on = 0;
-+
- if (ctrl->features & BRCMNAND_HAS_WP) {
- /* Permanently disable write protection */
- if (wp_on == 2)
diff --git a/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch b/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch
deleted file mode 100644
index eb6be5ed00..0000000000
--- a/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 63db0cb35e1cb3b3c134906d1062f65513fdda2d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Oct 2022 10:37:09 +0200
-Subject: [PATCH] mtd: core: simplify (a bit) code find partition-matching
- dynamic OF node
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Don't hardcode "partition-" string twice
-2. Use simpler logic & use ->name to avoid of_property_read_string()
-3. Use mtd_get_of_node() helper
-
-Cc: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-1-zajec5@gmail.com
----
- drivers/mtd/mtdcore.c | 16 +++++++---------
- 1 file changed, 7 insertions(+), 9 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -551,18 +551,16 @@ static void mtd_check_of_node(struct mtd
- struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
- const char *pname, *prefix = "partition-";
- int plen, mtd_name_len, offset, prefix_len;
-- struct mtd_info *parent;
- bool found = false;
-
- /* Check if MTD already has a device node */
-- if (dev_of_node(&mtd->dev))
-+ if (mtd_get_of_node(mtd))
- return;
-
- /* Check if a partitions node exist */
- if (!mtd_is_partition(mtd))
- return;
-- parent = mtd->parent;
-- parent_dn = of_node_get(dev_of_node(&parent->dev));
-+ parent_dn = of_node_get(mtd_get_of_node(mtd->parent));
- if (!parent_dn)
- return;
-
-@@ -575,15 +573,15 @@ static void mtd_check_of_node(struct mtd
-
- /* Search if a partition is defined with the same name */
- for_each_child_of_node(partitions, mtd_dn) {
-- offset = 0;
--
- /* Skip partition with no/wrong prefix */
-- if (!of_node_name_prefix(mtd_dn, "partition-"))
-+ if (!of_node_name_prefix(mtd_dn, prefix))
- continue;
-
- /* Label have priority. Check that first */
-- if (of_property_read_string(mtd_dn, "label", &pname)) {
-- of_property_read_string(mtd_dn, "name", &pname);
-+ if (!of_property_read_string(mtd_dn, "label", &pname)) {
-+ offset = 0;
-+ } else {
-+ pname = mtd_dn->name;
- offset = prefix_len;
- }
-
diff --git a/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch b/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch
deleted file mode 100644
index f8d3a370d4..0000000000
--- a/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From ddb8cefb7af288950447ca6eeeafb09977dab56f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Oct 2022 10:37:10 +0200
-Subject: [PATCH] mtd: core: try to find OF node for every MTD partition
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-So far this feature was limited to the top-level "nvmem-cells" node.
-There are multiple parsers creating partitions and subpartitions
-dynamically. Extend that code to handle them too.
-
-This allows finding partition-* node for every MTD (sub)partition.
-
-Random example:
-
-partitions {
- compatible = "brcm,bcm947xx-cfe-partitions";
-
- partition-firmware {
- compatible = "brcm,trx";
-
- partition-loader {
- };
- };
-};
-
-Cc: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-2-zajec5@gmail.com
----
- drivers/mtd/mtdcore.c | 18 ++++++------------
- 1 file changed, 6 insertions(+), 12 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -551,20 +551,22 @@ static void mtd_check_of_node(struct mtd
- struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
- const char *pname, *prefix = "partition-";
- int plen, mtd_name_len, offset, prefix_len;
-- bool found = false;
-
- /* Check if MTD already has a device node */
- if (mtd_get_of_node(mtd))
- return;
-
-- /* Check if a partitions node exist */
- if (!mtd_is_partition(mtd))
- return;
-+
- parent_dn = of_node_get(mtd_get_of_node(mtd->parent));
- if (!parent_dn)
- return;
-
-- partitions = of_get_child_by_name(parent_dn, "partitions");
-+ if (mtd_is_partition(mtd->parent))
-+ partitions = of_node_get(parent_dn);
-+ else
-+ partitions = of_get_child_by_name(parent_dn, "partitions");
- if (!partitions)
- goto exit_parent;
-
-@@ -588,19 +590,11 @@ static void mtd_check_of_node(struct mtd
- plen = strlen(pname) - offset;
- if (plen == mtd_name_len &&
- !strncmp(mtd->name, pname + offset, plen)) {
-- found = true;
-+ mtd_set_of_node(mtd, mtd_dn);
- break;
- }
- }
-
-- if (!found)
-- goto exit_partitions;
--
-- /* Set of_node only for nvmem */
-- if (of_device_is_compatible(mtd_dn, "nvmem-cells"))
-- mtd_set_of_node(mtd, mtd_dn);
--
--exit_partitions:
- of_node_put(partitions);
- exit_parent:
- of_node_put(parent_dn);
diff --git a/target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch b/target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch
deleted file mode 100644
index 5a5e11c8f7..0000000000
--- a/target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 26422ac78e9d8767bd4aabfbae616b15edbf6a1b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 22 Oct 2022 23:13:18 +0200
-Subject: [PATCH] mtd: core: set ROOT_DEV for partitions marked as rootfs in DT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds support for "linux,rootfs" binding that is used to mark flash
-partition containing rootfs. It's useful for devices using device tree
-that don't have bootloader passing root info in cmdline.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221022211318.32009-2-zajec5@gmail.com
----
- drivers/mtd/mtdcore.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -28,6 +28,7 @@
- #include <linux/leds.h>
- #include <linux/debugfs.h>
- #include <linux/nvmem-provider.h>
-+#include <linux/root_dev.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-@@ -737,6 +738,17 @@ int add_mtd_device(struct mtd_info *mtd)
- not->add(mtd);
-
- mutex_unlock(&mtd_table_mutex);
-+
-+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) {
-+ if (IS_BUILTIN(CONFIG_MTD)) {
-+ pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name);
-+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
-+ } else {
-+ pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n",
-+ mtd->index, mtd->name);
-+ }
-+ }
-+
- /* We _know_ we aren't being removed, because
- our caller is still holding us here. So none
- of this try_ nonsense, and no bitching about it
diff --git a/target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch b/target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch
deleted file mode 100644
index 4978dcedbf..0000000000
--- a/target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 773bbe10449731c9525457873e0c2342e5cf883b Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Thu, 11 Aug 2022 00:06:53 +0200
-Subject: [PATCH] mtd: spi-nor: add generic flash driver
-
-Our SFDP parsing is everything we need to support all basic operations
-of a flash device. If the flash isn't found in our in-kernel flash
-database, gracefully fall back to a driver described solely by its SFDP
-tables.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
-Tested-by: Tudor Ambarus <tudor.ambarus@microchip.com>
-Reviewed-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
-Link: https://lore.kernel.org/r/20220810220654.1297699-7-michael@walle.cc
----
- drivers/mtd/spi-nor/core.c | 26 ++++++++++++++++++++++++--
- drivers/mtd/spi-nor/core.h | 1 +
- drivers/mtd/spi-nor/sfdp.c | 27 +++++++++++++++++++++++++++
- 3 files changed, 52 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -1636,6 +1636,16 @@ static const struct spi_nor_manufacturer
- &spi_nor_xmc,
- };
-
-+static const struct flash_info spi_nor_generic_flash = {
-+ .name = "spi-nor-generic",
-+ /*
-+ * JESD216 rev A doesn't specify the page size, therefore we need a
-+ * sane default.
-+ */
-+ .page_size = 256,
-+ .parse_sfdp = true,
-+};
-+
- static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
- const u8 *id)
- {
-@@ -1669,6 +1679,14 @@ static const struct flash_info *spi_nor_
- }
-
- info = spi_nor_match_id(nor, id);
-+
-+ /* Fallback to a generic flash described only by its SFDP data. */
-+ if (!info) {
-+ ret = spi_nor_check_sfdp_signature(nor);
-+ if (!ret)
-+ info = &spi_nor_generic_flash;
-+ }
-+
- if (!info) {
- dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
- SPI_NOR_MAX_ID_LEN, id);
-@@ -2105,8 +2123,12 @@ static int spi_nor_select_pp(struct spi_
- * spi_nor_select_uniform_erase() - select optimum uniform erase type
- * @map: the erase map of the SPI NOR
- * @wanted_size: the erase type size to search for. Contains the value of
-- * info->sector_size or of the "small sector" size in case
-- * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined.
-+ * info->sector_size, the "small sector" size in case
-+ * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if
-+ * there is no information about the sector size. The
-+ * latter is the case if the flash parameters are parsed
-+ * solely by SFDP, then the largest supported erase type
-+ * is selected.
- *
- * Once the optimum uniform sector erase command is found, disable all the
- * other.
---- a/drivers/mtd/spi-nor/core.h
-+++ b/drivers/mtd/spi-nor/core.h
-@@ -708,6 +708,8 @@ int spi_nor_controller_ops_read_reg(stru
- int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode,
- const u8 *buf, size_t len);
-
-+int spi_nor_check_sfdp_signature(struct spi_nor *nor);
-+
- static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
- {
- return container_of(mtd, struct spi_nor, mtd);
---- a/drivers/mtd/spi-nor/sfdp.c
-+++ b/drivers/mtd/spi-nor/sfdp.c
-@@ -1250,6 +1250,33 @@ static void spi_nor_post_sfdp_fixups(str
- }
-
- /**
-+ * spi_nor_check_sfdp_signature() - check for a valid SFDP signature
-+ * @nor: pointer to a 'struct spi_nor'
-+ *
-+ * Used to detect if the flash supports the RDSFDP command as well as the
-+ * presence of a valid SFDP table.
-+ *
-+ * Return: 0 on success, -errno otherwise.
-+ */
-+int spi_nor_check_sfdp_signature(struct spi_nor *nor)
-+{
-+ u32 signature;
-+ int err;
-+
-+ /* Get the SFDP header. */
-+ err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(signature),
-+ &signature);
-+ if (err < 0)
-+ return err;
-+
-+ /* Check the SFDP signature. */
-+ if (le32_to_cpu(signature) != SFDP_SIGNATURE)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+/**
- * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
- * @nor: pointer to a 'struct spi_nor'
- *
diff --git a/target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch b/target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch
deleted file mode 100644
index cc05fa6b75..0000000000
--- a/target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From c67d90e058550403a3e6f9b05bfcdcfa12b1815c Mon Sep 17 00:00:00 2001
-From: Vincent Tremblay <vincent@vtremblay.dev>
-Date: Mon, 26 Dec 2022 21:35:48 -0500
-Subject: [PATCH] spidev: Add Silicon Labs EM3581 device compatible
-
-Add compatible string for Silicon Labs EM3581 device.
-
-Signed-off-by: Vincent Tremblay <vincent@vtremblay.dev>
-Link: https://lore.kernel.org/r/20221227023550.569547-2-vincent@vtremblay.dev
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spidev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/spi/spidev.c
-+++ b/drivers/spi/spidev.c
-@@ -700,6 +700,7 @@ static const struct spi_device_id spidev
- { .name = "m53cpld" },
- { .name = "spi-petra" },
- { .name = "spi-authenta" },
-+ { .name = "em3581" },
- {},
- };
- MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
-@@ -726,6 +727,7 @@ static const struct of_device_id spidev_
- { .compatible = "menlo,m53cpld", .data = &spidev_of_check },
- { .compatible = "cisco,spi-petra", .data = &spidev_of_check },
- { .compatible = "micron,spi-authenta", .data = &spidev_of_check },
-+ { .compatible = "silabs,em3581", .data = &spidev_of_check },
- {},
- };
- MODULE_DEVICE_TABLE(of, spidev_dt_ids);
diff --git a/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch b/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch
deleted file mode 100644
index 59d025e087..0000000000
--- a/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 6c9d1fd52956c3148e847a214bae9102b1811de5 Mon Sep 17 00:00:00 2001
-From: Vincent Tremblay <vincent@vtremblay.dev>
-Date: Tue, 27 Dec 2022 09:10:08 -0500
-Subject: [PATCH] spidev: Add Silicon Labs SI3210 device compatible
-
-Add compatible string for Silicon Labs SI3210 device.
-
-Signed-off-by: Vincent Tremblay <vincent@vtremblay.dev>
-Link: https://lore.kernel.org/r/20221227141011.111410-2-vincent@vtremblay.dev
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spidev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/spi/spidev.c
-+++ b/drivers/spi/spidev.c
-@@ -701,6 +701,7 @@ static const struct spi_device_id spidev
- { .name = "spi-petra" },
- { .name = "spi-authenta" },
- { .name = "em3581" },
-+ { .name = "si3210" },
- {},
- };
- MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
-@@ -728,6 +729,7 @@ static const struct of_device_id spidev_
- { .compatible = "cisco,spi-petra", .data = &spidev_of_check },
- { .compatible = "micron,spi-authenta", .data = &spidev_of_check },
- { .compatible = "silabs,em3581", .data = &spidev_of_check },
-+ { .compatible = "silabs,si3210", .data = &spidev_of_check },
- {},
- };
- MODULE_DEVICE_TABLE(of, spidev_dt_ids);
diff --git a/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch b/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch
deleted file mode 100644
index e570564a0b..0000000000
--- a/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch
+++ /dev/null
@@ -1,229 +0,0 @@
-From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 15 Oct 2022 11:29:50 +0200
-Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This parser deals with most TP-Link home routers. It reads info about
-partitions and registers them in the MTD subsystem.
-
-Example from TP-Link Archer C5 V2:
-
-spi-nor spi0.0: s25fl128s1 (16384 Kbytes)
-15 tplink-safeloader partitions found on MTD device spi0.0
-Creating 15 MTD partitions on "spi0.0":
-0x000000000000-0x000000040000 : "fs-uboot"
-0x000000040000-0x000000440000 : "os-image"
-0x000000440000-0x000000e40000 : "rootfs"
-0x000000e40000-0x000000e40200 : "default-mac"
-0x000000e40200-0x000000e40400 : "pin"
-0x000000e40400-0x000000e40600 : "product-info"
-0x000000e50000-0x000000e60000 : "partition-table"
-0x000000e60000-0x000000e60200 : "soft-version"
-0x000000e61000-0x000000e70000 : "support-list"
-0x000000e70000-0x000000e80000 : "profile"
-0x000000e80000-0x000000e90000 : "default-config"
-0x000000e90000-0x000000ee0000 : "user-config"
-0x000000ee0000-0x000000fe0000 : "log"
-0x000000fe0000-0x000000ff0000 : "radio_bk"
-0x000000ff0000-0x000001000000 : "radio"
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com
----
- drivers/mtd/parsers/Kconfig | 15 +++
- drivers/mtd/parsers/Makefile | 1 +
- drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++
- 3 files changed, 166 insertions(+)
- create mode 100644 drivers/mtd/parsers/tplink_safeloader.c
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -123,6 +123,21 @@ config MTD_AFS_PARTS
- for your particular device. It won't happen automatically. The
- 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example.
-
-+config MTD_PARSER_TPLINK_SAFELOADER
-+ tristate "TP-Link Safeloader partitions parser"
-+ depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST)
-+ help
-+ TP-Link home routers use flash partitions to store various data. Info
-+ about flash space layout is stored in a partitions table using a
-+ custom ASCII-based format.
-+
-+ That format was first found in devices with SafeLoader bootloader and
-+ was named after it. Later it was adapted to CFE and U-Boot
-+ bootloaders.
-+
-+ This driver reads partitions table, parses it and creates MTD
-+ partitions.
-+
- config MTD_PARSER_TRX
- tristate "Parser for TRX format partitions"
- depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST)
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -10,6 +10,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) +=
- ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o
- obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
- obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
-+obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o
- obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
- obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o
- obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
---- /dev/null
-+++ b/drivers/mtd/parsers/tplink_safeloader.c
-@@ -0,0 +1,150 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright © 2022 Rafał Miłecki <rafal@milecki.pl>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/of.h>
-+#include <linux/slab.h>
-+
-+#define TPLINK_SAFELOADER_DATA_OFFSET 4
-+#define TPLINK_SAFELOADER_MAX_PARTS 32
-+
-+struct safeloader_cmn_header {
-+ __be32 size;
-+ uint32_t unused;
-+} __packed;
-+
-+static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd)
-+{
-+ struct safeloader_cmn_header hdr;
-+ struct device_node *np;
-+ size_t bytes_read;
-+ size_t offset;
-+ size_t size;
-+ char *buf;
-+ int err;
-+
-+ np = mtd_get_of_node(mtd);
-+ if (mtd_is_partition(mtd))
-+ of_node_get(np);
-+ else
-+ np = of_get_child_by_name(np, "partitions");
-+
-+ if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) {
-+ pr_err("Failed to get partitions table offset\n");
-+ goto err_put;
-+ }
-+
-+ err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset);
-+ goto err_put;
-+ }
-+
-+ size = be32_to_cpu(hdr.size);
-+
-+ buf = kmalloc(size + 1, GFP_KERNEL);
-+ if (!buf)
-+ goto err_put;
-+
-+ err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr));
-+ goto err_kfree;
-+ }
-+
-+ buf[size] = '\0';
-+
-+ of_node_put(np);
-+
-+ return buf;
-+
-+err_kfree:
-+ kfree(buf);
-+err_put:
-+ of_node_put(np);
-+ return NULL;
-+}
-+
-+static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd,
-+ const struct mtd_partition **pparts,
-+ struct mtd_part_parser_data *data)
-+{
-+ struct mtd_partition *parts;
-+ char name[65];
-+ size_t offset;
-+ size_t bytes;
-+ char *buf;
-+ int idx;
-+ int err;
-+
-+ parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL);
-+ if (!parts) {
-+ err = -ENOMEM;
-+ goto err_out;
-+ }
-+
-+ buf = mtd_parser_tplink_safeloader_read_table(mtd);
-+ if (!buf) {
-+ err = -ENOENT;
-+ goto err_out;
-+ }
-+
-+ for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET;
-+ idx < TPLINK_SAFELOADER_MAX_PARTS &&
-+ sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n",
-+ name, &parts[idx].offset, &parts[idx].size, &bytes) == 3;
-+ idx++, offset += bytes + 1) {
-+ parts[idx].name = kstrdup(name, GFP_KERNEL);
-+ if (!parts[idx].name) {
-+ err = -ENOMEM;
-+ goto err_free;
-+ }
-+ }
-+
-+ if (idx == TPLINK_SAFELOADER_MAX_PARTS)
-+ pr_warn("Reached maximum number of partitions!\n");
-+
-+ kfree(buf);
-+
-+ *pparts = parts;
-+
-+ return idx;
-+
-+err_free:
-+ for (idx -= 1; idx >= 0; idx--)
-+ kfree(parts[idx].name);
-+err_out:
-+ return err;
-+};
-+
-+static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts,
-+ int nr_parts)
-+{
-+ int i;
-+
-+ for (i = 0; i < nr_parts; i++)
-+ kfree(pparts[i].name);
-+
-+ kfree(pparts);
-+}
-+
-+static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = {
-+ { .compatible = "tplink,safeloader-partitions" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table);
-+
-+static struct mtd_part_parser mtd_parser_tplink_safeloader = {
-+ .parse_fn = mtd_parser_tplink_safeloader_parse,
-+ .cleanup = mtd_parser_tplink_safeloader_cleanup,
-+ .name = "tplink-safeloader",
-+ .of_match_table = mtd_parser_tplink_safeloader_of_match_table,
-+};
-+module_mtd_part_parser(mtd_parser_tplink_safeloader);
-+
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch b/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch
deleted file mode 100644
index 7dbc271725..0000000000
--- a/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From ebed787a0becb9354f0a23620a5130cccd6c730c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 19 Jan 2023 03:45:43 +0000
-Subject: [PATCH] mtd: spinand: macronix: use scratch buffer for DMA operation
-
-The mx35lf1ge4ab_get_eccsr() function uses an SPI DMA operation to
-read the eccsr, hence the buffer should not be on stack. Since commit
-380583227c0c7f ("spi: spi-mem: Add extra sanity checks on the op param")
-the kernel emmits a warning and blocks such operations.
-
-Use the scratch buffer to get eccsr instead of trying to directly read
-into a stack-allocated variable.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Dhruva Gole <d-gole@ti.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/Y8i85zM0u4XdM46z@makrotopia.org
----
- drivers/mtd/nand/spi/macronix.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/spi/macronix.c
-+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -83,9 +83,10 @@ static int mx35lf1ge4ab_ecc_get_status(s
- * in order to avoid forcing the wear-leveling layer to move
- * data around if it's not necessary.
- */
-- if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
-+ if (mx35lf1ge4ab_get_eccsr(spinand, spinand->scratchbuf))
- return nanddev_get_ecc_conf(nand)->strength;
-
-+ eccsr = *spinand->scratchbuf;
- if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength ||
- !eccsr))
- return nanddev_get_ecc_conf(nand)->strength;
diff --git a/target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch b/target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch
deleted file mode 100644
index 657404196d..0000000000
--- a/target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 1ecf9e390452e73a362ea7fbde8f3f0db83de856 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 22 Dec 2022 19:33:04 +0000
-Subject: [PATCH] mtd: ubi: wire-up parent MTD device
-
-Wire up the device parent pointer of UBI devices to their lower MTD
-device, typically an MTD partition or whole-chip device.
-
-The most noticeable change is that in sysfs, previously ubi devices
-would be could in /sys/devices/virtual/ubi while after this change they
-would be correctly attached to their parent MTD device, e.g.
-
-/sys/devices/platform/1100d000.spi/spi_master/spi1/spi1.0/mtd/mtd2/ubi0.
-
-Locating UBI devices using /sys/class/ubi/ of course still works as
-well.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Richard Weinberger <richard@nod.at>
----
- drivers/mtd/ubi/build.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/ubi/build.c
-+++ b/drivers/mtd/ubi/build.c
-@@ -929,6 +929,7 @@ int ubi_attach_mtd_dev(struct mtd_info *
- ubi->dev.release = dev_release;
- ubi->dev.class = &ubi_class;
- ubi->dev.groups = ubi_dev_groups;
-+ ubi->dev.parent = &mtd->dev;
-
- ubi->mtd = mtd;
- ubi->ubi_num = ubi_num;
diff --git a/target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch b/target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch
deleted file mode 100644
index 48bf986118..0000000000
--- a/target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 05b8773ca33253ea562be145cf3145b05ef19f86 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 22 Dec 2022 19:33:31 +0000
-Subject: [PATCH] mtd: ubi: block: wire-up device parent
-
-ubiblock devices were previously only identifyable by their name, but
-not connected to their parent UBI volume device e.g. in sysfs.
-Properly parent ubiblock device as descendant of a UBI volume device
-to reflect device model hierachy.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Richard Weinberger <richard@nod.at>
----
- drivers/mtd/ubi/block.c | 2 +-
- drivers/mtd/ubi/kapi.c | 1 +
- include/linux/mtd/ubi.h | 1 +
- 3 files changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -452,7 +452,7 @@ int ubiblock_create(struct ubi_volume_in
- list_add_tail(&dev->list, &ubiblock_devices);
-
- /* Must be the last step: anyone can call file ops from now on */
-- ret = add_disk(dev->gd);
-+ ret = device_add_disk(vi->dev, dev->gd, NULL);
- if (ret)
- goto out_destroy_wq;
-
---- a/drivers/mtd/ubi/kapi.c
-+++ b/drivers/mtd/ubi/kapi.c
-@@ -79,6 +79,7 @@ void ubi_do_get_volume_info(struct ubi_d
- vi->name_len = vol->name_len;
- vi->name = vol->name;
- vi->cdev = vol->cdev.dev;
-+ vi->dev = &vol->dev;
- }
-
- /**
---- a/include/linux/mtd/ubi.h
-+++ b/include/linux/mtd/ubi.h
-@@ -110,6 +110,7 @@ struct ubi_volume_info {
- int name_len;
- const char *name;
- dev_t cdev;
-+ struct device *dev;
- };
-
- /**
diff --git a/target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch b/target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch
deleted file mode 100644
index 28f54d9e5e..0000000000
--- a/target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 281f7a6c1a33fffcde32001bacbb4f672140fbf9 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Wed, 8 Mar 2023 09:20:21 +0100
-Subject: [PATCH] mtd: core: prepare mtd_otp_nvmem_add() to handle
- -EPROBE_DEFER
-
-NVMEM soon will get the ability for nvmem layouts and these might
-not be ready when nvmem_register() is called and thus it might
-return -EPROBE_DEFER. Don't print the error message in this case.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
----
- drivers/mtd/mtdcore.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -955,8 +955,8 @@ static int mtd_otp_nvmem_add(struct mtd_
- nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size,
- mtd_nvmem_user_otp_reg_read);
- if (IS_ERR(nvmem)) {
-- dev_err(dev, "Failed to register OTP NVMEM device\n");
-- return PTR_ERR(nvmem);
-+ err = PTR_ERR(nvmem);
-+ goto err;
- }
- mtd->otp_user_nvmem = nvmem;
- }
-@@ -973,7 +973,6 @@ static int mtd_otp_nvmem_add(struct mtd_
- nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size,
- mtd_nvmem_fact_otp_reg_read);
- if (IS_ERR(nvmem)) {
-- dev_err(dev, "Failed to register OTP NVMEM device\n");
- err = PTR_ERR(nvmem);
- goto err;
- }
-@@ -985,7 +984,7 @@ static int mtd_otp_nvmem_add(struct mtd_
-
- err:
- nvmem_unregister(mtd->otp_user_nvmem);
-- return err;
-+ return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n");
- }
-
- /**
diff --git a/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch b/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch
deleted file mode 100644
index 6dbec3c752..0000000000
--- a/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From: Richard Gobert <richardbgobert@gmail.com>
-Date: Wed, 3 Jan 2024 15:44:21 +0100
-Subject: [PATCH] net: gro: parse ipv6 ext headers without frag0 invalidation
-
-The existing code always pulls the IPv6 header and sets the transport
-offset initially. Then optionally again pulls any extension headers in
-ipv6_gso_pull_exthdrs and sets the transport offset again on return from
-that call. skb->data is set at the start of the first extension header
-before calling ipv6_gso_pull_exthdrs, and must disable the frag0
-optimization because that function uses pskb_may_pull/pskb_pull instead of
-skb_gro_ helpers. It sets the GRO offset to the TCP header with
-skb_gro_pull and sets the transport header. Then returns skb->data to its
-position before this block.
-
-This commit introduces a new helper function - ipv6_gro_pull_exthdrs -
-which is used in ipv6_gro_receive to pull ipv6 ext headers instead of
-ipv6_gso_pull_exthdrs. Thus, there is no modification of skb->data, all
-operations use skb_gro_* helpers, and the frag0 fast path can be taken for
-IPv6 packets with ext headers.
-
-Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
-Reviewed-by: Willem de Bruijn <willemb@google.com>
-Reviewed-by: David Ahern <dsahern@kernel.org>
-Reviewed-by: Eric Dumazet <edumazet@google.com>
-Link: https://lore.kernel.org/r/504130f6-b56c-4dcc-882c-97942c59f5b7@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/net/ipv6/ip6_offload.c
-+++ b/net/ipv6/ip6_offload.c
-@@ -36,6 +36,40 @@
- INDIRECT_CALL_L4(cb, f2, f1, head, skb); \
- })
-
-+static int ipv6_gro_pull_exthdrs(struct sk_buff *skb, int off, int proto)
-+{
-+ const struct net_offload *ops = NULL;
-+ struct ipv6_opt_hdr *opth;
-+
-+ for (;;) {
-+ int len;
-+
-+ ops = rcu_dereference(inet6_offloads[proto]);
-+
-+ if (unlikely(!ops))
-+ break;
-+
-+ if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
-+ break;
-+
-+ opth = skb_gro_header(skb, off + sizeof(*opth), off);
-+ if (unlikely(!opth))
-+ break;
-+
-+ len = ipv6_optlen(opth);
-+
-+ opth = skb_gro_header(skb, off + len, off);
-+ if (unlikely(!opth))
-+ break;
-+ proto = opth->nexthdr;
-+
-+ off += len;
-+ }
-+
-+ skb_gro_pull(skb, off - skb_network_offset(skb));
-+ return proto;
-+}
-+
- static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
- {
- const struct net_offload *ops = NULL;
-@@ -224,28 +258,25 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *
- goto out;
-
- skb_set_network_header(skb, off);
-- skb_gro_pull(skb, sizeof(*iph));
-- skb_set_transport_header(skb, skb_gro_offset(skb));
-
-- flush += ntohs(iph->payload_len) != skb_gro_len(skb);
-+ flush += ntohs(iph->payload_len) != skb->len - hlen;
-
- proto = iph->nexthdr;
- ops = rcu_dereference(inet6_offloads[proto]);
- if (!ops || !ops->callbacks.gro_receive) {
-- pskb_pull(skb, skb_gro_offset(skb));
-- skb_gro_frag0_invalidate(skb);
-- proto = ipv6_gso_pull_exthdrs(skb, proto);
-- skb_gro_pull(skb, -skb_transport_offset(skb));
-- skb_reset_transport_header(skb);
-- __skb_push(skb, skb_gro_offset(skb));
-+ proto = ipv6_gro_pull_exthdrs(skb, hlen, proto);
-
- ops = rcu_dereference(inet6_offloads[proto]);
- if (!ops || !ops->callbacks.gro_receive)
- goto out;
-
-- iph = ipv6_hdr(skb);
-+ iph = skb_gro_network_header(skb);
-+ } else {
-+ skb_gro_pull(skb, sizeof(*iph));
- }
-
-+ skb_set_transport_header(skb, skb_gro_offset(skb));
-+
- NAPI_GRO_CB(skb)->proto = proto;
-
- flush--;
diff --git a/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch b/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch
deleted file mode 100644
index 28b7b4383e..0000000000
--- a/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 7390609b0121a1b982c5ecdfcd72dc328e5784ee Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:42 +0000
-Subject: [PATCH] net: add helper eth_addr_add()
-
-Add a helper to add an offset to a ethernet address. This comes in handy
-if you have a base ethernet address for multiple interfaces.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/etherdevice.h | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/include/linux/etherdevice.h
-+++ b/include/linux/etherdevice.h
-@@ -508,6 +508,20 @@ static inline void eth_addr_inc(u8 *addr
- }
-
- /**
-+ * eth_addr_add() - Add (or subtract) an offset to/from the given MAC address.
-+ *
-+ * @offset: Offset to add.
-+ * @addr: Pointer to a six-byte array containing Ethernet address to increment.
-+ */
-+static inline void eth_addr_add(u8 *addr, long offset)
-+{
-+ u64 u = ether_addr_to_u64(addr);
-+
-+ u += offset;
-+ u64_to_ether_addr(u, addr);
-+}
-+
-+/**
- * is_etherdev_addr - Tell if given Ethernet address belongs to the device.
- * @dev: Pointer to a device structure
- * @addr: Pointer to a six-byte array containing the Ethernet address
diff --git a/target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch b/target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch
deleted file mode 100644
index 56e14c5c0a..0000000000
--- a/target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From d387e34fec407f881fdf165b5d7ec128ebff362f Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 19 Sep 2023 14:47:20 +0200
-Subject: [PATCH] net: sfp: add quirk for Fiberstone GPON-ONU-34-20BI
-
-Fiberstone GPON-ONU-34-20B can operate at 2500base-X, but report 1.2GBd
-NRZ in their EEPROM.
-
-The module also require the ignore tx fault fixup similar to Huawei MA5671A
-as it gets disabled on error messages with serial redirection enabled.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://lore.kernel.org/r/20230919124720.8210-1-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/sfp.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -393,6 +393,11 @@ static const struct sfp_quirk sfp_quirks
- SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex,
- sfp_fixup_long_startup),
-
-+ // Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
-+ // NRZ in their EEPROM
-+ SFP_QUIRK("FS", "GPON-ONU-34-20BI", sfp_quirk_2500basex,
-+ sfp_fixup_ignore_tx_fault),
-+
- SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp),
-
- // HG MXPD-483II-F 2.5G supports 2500Base-X, but incorrectly reports
diff --git a/target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch b/target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch
deleted file mode 100644
index 0cad6c53d4..0000000000
--- a/target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch
+++ /dev/null
@@ -1,2306 +0,0 @@
-From d2213db3f49bce8e7a87c8de05b9a091f78f654e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 14 Nov 2023 15:08:41 +0100
-Subject: [PATCH 1/3] net: phy: aquantia: move to separate directory
-
-Move aquantia PHY driver to separate driectory in preparation for
-firmware loading support to keep things tidy.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 5 +----
- drivers/net/phy/Makefile | 6 +-----
- drivers/net/phy/aquantia/Kconfig | 5 +++++
- drivers/net/phy/aquantia/Makefile | 6 ++++++
- drivers/net/phy/{ => aquantia}/aquantia.h | 0
- drivers/net/phy/{ => aquantia}/aquantia_hwmon.c | 0
- drivers/net/phy/{ => aquantia}/aquantia_main.c | 0
- 7 files changed, 13 insertions(+), 9 deletions(-)
- create mode 100644 drivers/net/phy/aquantia/Kconfig
- create mode 100644 drivers/net/phy/aquantia/Makefile
- rename drivers/net/phy/{ => aquantia}/aquantia.h (100%)
- rename drivers/net/phy/{ => aquantia}/aquantia_hwmon.c (100%)
- rename drivers/net/phy/{ => aquantia}/aquantia_main.c (100%)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -90,10 +90,7 @@ config ADIN1100_PHY
- Currently supports the:
- - ADIN1100 - Robust,Industrial, Low Power 10BASE-T1L Ethernet PHY
-
--config AQUANTIA_PHY
-- tristate "Aquantia PHYs"
-- help
-- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
-+source "drivers/net/phy/aquantia/Kconfig"
-
- config AX88796B_PHY
- tristate "Asix PHYs"
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -33,11 +33,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
- obj-$(CONFIG_ADIN_PHY) += adin.o
- obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
- obj-$(CONFIG_AMD_PHY) += amd.o
--aquantia-objs += aquantia_main.o
--ifdef CONFIG_HWMON
--aquantia-objs += aquantia_hwmon.o
--endif
--obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
-+obj-$(CONFIG_AQUANTIA_PHY) += aquantia/
- obj-$(CONFIG_AT803X_PHY) += at803x.o
- obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
- obj-$(CONFIG_BCM54140_PHY) += bcm54140.o
---- /dev/null
-+++ b/drivers/net/phy/aquantia/Kconfig
-@@ -0,0 +1,5 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+config AQUANTIA_PHY
-+ tristate "Aquantia PHYs"
-+ help
-+ Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
---- /dev/null
-+++ b/drivers/net/phy/aquantia/Makefile
-@@ -0,0 +1,6 @@
-+# SPDX-License-Identifier: GPL-2.0
-+aquantia-objs += aquantia_main.o
-+ifdef CONFIG_HWMON
-+aquantia-objs += aquantia_hwmon.o
-+endif
-+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
---- a/drivers/net/phy/aquantia.h
-+++ /dev/null
-@@ -1,16 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 */
--/* HWMON driver for Aquantia PHY
-- *
-- * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-- * Author: Andrew Lunn <andrew@lunn.ch>
-- * Author: Heiner Kallweit <hkallweit1@gmail.com>
-- */
--
--#include <linux/device.h>
--#include <linux/phy.h>
--
--#if IS_REACHABLE(CONFIG_HWMON)
--int aqr_hwmon_probe(struct phy_device *phydev);
--#else
--static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
--#endif
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia.h
-@@ -0,0 +1,16 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/* HWMON driver for Aquantia PHY
-+ *
-+ * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-+ * Author: Andrew Lunn <andrew@lunn.ch>
-+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/phy.h>
-+
-+#if IS_REACHABLE(CONFIG_HWMON)
-+int aqr_hwmon_probe(struct phy_device *phydev);
-+#else
-+static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
-+#endif
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c
-@@ -0,0 +1,250 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/* HWMON driver for Aquantia PHY
-+ *
-+ * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-+ * Author: Andrew Lunn <andrew@lunn.ch>
-+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
-+ */
-+
-+#include <linux/phy.h>
-+#include <linux/device.h>
-+#include <linux/ctype.h>
-+#include <linux/hwmon.h>
-+
-+#include "aquantia.h"
-+
-+/* Vendor specific 1, MDIO_MMD_VEND2 */
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
-+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
-+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
-+#define VEND1_THERMAL_STAT1 0xc820
-+#define VEND1_THERMAL_STAT2 0xc821
-+#define VEND1_THERMAL_STAT2_VALID BIT(0)
-+#define VEND1_GENERAL_STAT1 0xc830
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
-+
-+#if IS_REACHABLE(CONFIG_HWMON)
-+
-+static umode_t aqr_hwmon_is_visible(const void *data,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel)
-+{
-+ if (type != hwmon_temp)
-+ return 0;
-+
-+ switch (attr) {
-+ case hwmon_temp_input:
-+ case hwmon_temp_min_alarm:
-+ case hwmon_temp_max_alarm:
-+ case hwmon_temp_lcrit_alarm:
-+ case hwmon_temp_crit_alarm:
-+ return 0444;
-+ case hwmon_temp_min:
-+ case hwmon_temp_max:
-+ case hwmon_temp_lcrit:
-+ case hwmon_temp_crit:
-+ return 0644;
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
-+{
-+ int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
-+
-+ if (temp < 0)
-+ return temp;
-+
-+ /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */
-+ *value = (s16)temp * 1000 / 256;
-+
-+ return 0;
-+}
-+
-+static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
-+{
-+ int temp;
-+
-+ if (value >= 128000 || value < -128000)
-+ return -ERANGE;
-+
-+ temp = value * 256 / 1000;
-+
-+ /* temp is in s16 range and we're interested in lower 16 bits only */
-+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp);
-+}
-+
-+static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit)
-+{
-+ int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
-+
-+ if (val < 0)
-+ return val;
-+
-+ return !!(val & bit);
-+}
-+
-+static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
-+{
-+ int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit);
-+
-+ if (val < 0)
-+ return val;
-+
-+ *value = val;
-+
-+ return 0;
-+}
-+
-+static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *value)
-+{
-+ struct phy_device *phydev = dev_get_drvdata(dev);
-+ int reg;
-+
-+ if (type != hwmon_temp)
-+ return -EOPNOTSUPP;
-+
-+ switch (attr) {
-+ case hwmon_temp_input:
-+ reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2,
-+ VEND1_THERMAL_STAT2_VALID);
-+ if (reg < 0)
-+ return reg;
-+ if (!reg)
-+ return -EBUSY;
-+
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
-+
-+ case hwmon_temp_lcrit:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_min:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-+ value);
-+ case hwmon_temp_max:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-+ value);
-+ case hwmon_temp_crit:
-+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_lcrit_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_LOW_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_min_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_LOW_TEMP_WARN,
-+ value);
-+ case hwmon_temp_max_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_HIGH_TEMP_WARN,
-+ value);
-+ case hwmon_temp_crit_alarm:
-+ return aqr_hwmon_status1(phydev,
-+ VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL,
-+ value);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long value)
-+{
-+ struct phy_device *phydev = dev_get_drvdata(dev);
-+
-+ if (type != hwmon_temp)
-+ return -EOPNOTSUPP;
-+
-+ switch (attr) {
-+ case hwmon_temp_lcrit:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-+ value);
-+ case hwmon_temp_min:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-+ value);
-+ case hwmon_temp_max:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-+ value);
-+ case hwmon_temp_crit:
-+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-+ value);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static const struct hwmon_ops aqr_hwmon_ops = {
-+ .is_visible = aqr_hwmon_is_visible,
-+ .read = aqr_hwmon_read,
-+ .write = aqr_hwmon_write,
-+};
-+
-+static u32 aqr_hwmon_chip_config[] = {
-+ HWMON_C_REGISTER_TZ,
-+ 0,
-+};
-+
-+static const struct hwmon_channel_info aqr_hwmon_chip = {
-+ .type = hwmon_chip,
-+ .config = aqr_hwmon_chip_config,
-+};
-+
-+static u32 aqr_hwmon_temp_config[] = {
-+ HWMON_T_INPUT |
-+ HWMON_T_MAX | HWMON_T_MIN |
-+ HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM |
-+ HWMON_T_CRIT | HWMON_T_LCRIT |
-+ HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM,
-+ 0,
-+};
-+
-+static const struct hwmon_channel_info aqr_hwmon_temp = {
-+ .type = hwmon_temp,
-+ .config = aqr_hwmon_temp_config,
-+};
-+
-+static const struct hwmon_channel_info *aqr_hwmon_info[] = {
-+ &aqr_hwmon_chip,
-+ &aqr_hwmon_temp,
-+ NULL,
-+};
-+
-+static const struct hwmon_chip_info aqr_hwmon_chip_info = {
-+ .ops = &aqr_hwmon_ops,
-+ .info = aqr_hwmon_info,
-+};
-+
-+int aqr_hwmon_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct device *hwmon_dev;
-+ char *hwmon_name;
-+ int i, j;
-+
-+ hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
-+ if (!hwmon_name)
-+ return -ENOMEM;
-+
-+ for (i = j = 0; hwmon_name[i]; i++) {
-+ if (isalnum(hwmon_name[i])) {
-+ if (i != j)
-+ hwmon_name[j] = hwmon_name[i];
-+ j++;
-+ }
-+ }
-+ hwmon_name[j] = '\0';
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name,
-+ phydev, &aqr_hwmon_chip_info, NULL);
-+
-+ return PTR_ERR_OR_ZERO(hwmon_dev);
-+}
-+
-+#endif
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -0,0 +1,842 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Driver for Aquantia PHY
-+ *
-+ * Author: Shaohui Xie <Shaohui.Xie@freescale.com>
-+ *
-+ * Copyright 2015 Freescale Semiconductor, Inc.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/bitfield.h>
-+#include <linux/phy.h>
-+
-+#include "aquantia.h"
-+
-+#define PHY_ID_AQ1202 0x03a1b445
-+#define PHY_ID_AQ2104 0x03a1b460
-+#define PHY_ID_AQR105 0x03a1b4a2
-+#define PHY_ID_AQR106 0x03a1b4d0
-+#define PHY_ID_AQR107 0x03a1b4e0
-+#define PHY_ID_AQCS109 0x03a1b5c2
-+#define PHY_ID_AQR405 0x03a1b4b0
-+#define PHY_ID_AQR113C 0x31c31c12
-+
-+#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7
-+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
-+
-+#define MDIO_AN_VEND_PROV 0xc400
-+#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15)
-+#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)
-+#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11)
-+#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
-+#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
-+#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
-+#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
-+
-+#define MDIO_AN_TX_VEND_STATUS1 0xc800
-+#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1)
-+#define MDIO_AN_TX_VEND_STATUS1_10BASET 0
-+#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1
-+#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2
-+#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3
-+#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4
-+#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5
-+#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0)
-+
-+#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00
-+#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1)
-+
-+#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01
-+#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0)
-+
-+#define MDIO_AN_TX_VEND_INT_MASK2 0xd401
-+#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0)
-+
-+#define MDIO_AN_RX_LP_STAT1 0xe820
-+#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15)
-+#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14)
-+#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13)
-+#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12)
-+#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2)
-+
-+#define MDIO_AN_RX_LP_STAT4 0xe823
-+#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8)
-+#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0)
-+
-+#define MDIO_AN_RX_VEND_STAT3 0xe832
-+#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
-+
-+/* MDIO_MMD_C22EXT */
-+#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292
-+#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294
-+#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297
-+#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313
-+#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315
-+#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317
-+#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318
-+#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319
-+#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
-+#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
-+
-+/* Vendor specific 1, MDIO_MMD_VEND1 */
-+#define VEND1_GLOBAL_FW_ID 0x0020
-+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
-+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
-+
-+#define VEND1_GLOBAL_GEN_STAT2 0xc831
-+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
-+
-+/* The following registers all have similar layouts; first the registers... */
-+#define VEND1_GLOBAL_CFG_10M 0x0310
-+#define VEND1_GLOBAL_CFG_100M 0x031b
-+#define VEND1_GLOBAL_CFG_1G 0x031c
-+#define VEND1_GLOBAL_CFG_2_5G 0x031d
-+#define VEND1_GLOBAL_CFG_5G 0x031e
-+#define VEND1_GLOBAL_CFG_10G 0x031f
-+/* ...and now the fields */
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-+
-+#define VEND1_GLOBAL_RSVD_STAT1 0xc885
-+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
-+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
-+
-+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
-+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
-+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
-+
-+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
-+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
-+
-+#define VEND1_GLOBAL_INT_STD_MASK 0xff00
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
-+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
-+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
-+
-+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
-+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
-+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
-+
-+/* Sleep and timeout for checking if the Processor-Intensive
-+ * MDIO operation is finished
-+ */
-+#define AQR107_OP_IN_PROG_SLEEP 1000
-+#define AQR107_OP_IN_PROG_TIMEOUT 100000
-+
-+struct aqr107_hw_stat {
-+ const char *name;
-+ int reg;
-+ int size;
-+};
-+
-+#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
-+static const struct aqr107_hw_stat aqr107_hw_stats[] = {
-+ SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26),
-+ SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26),
-+ SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8),
-+ SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26),
-+ SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26),
-+ SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8),
-+ SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8),
-+ SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8),
-+ SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16),
-+ SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22),
-+};
-+#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
-+
-+struct aqr107_priv {
-+ u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
-+};
-+
-+static int aqr107_get_sset_count(struct phy_device *phydev)
-+{
-+ return AQR107_SGMII_STAT_SZ;
-+}
-+
-+static void aqr107_get_strings(struct phy_device *phydev, u8 *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++)
-+ strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name,
-+ ETH_GSTRING_LEN);
-+}
-+
-+static u64 aqr107_get_stat(struct phy_device *phydev, int index)
-+{
-+ const struct aqr107_hw_stat *stat = aqr107_hw_stats + index;
-+ int len_l = min(stat->size, 16);
-+ int len_h = stat->size - len_l;
-+ u64 ret;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg);
-+ if (val < 0)
-+ return U64_MAX;
-+
-+ ret = val & GENMASK(len_l - 1, 0);
-+ if (len_h) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1);
-+ if (val < 0)
-+ return U64_MAX;
-+
-+ ret += (val & GENMASK(len_h - 1, 0)) << 16;
-+ }
-+
-+ return ret;
-+}
-+
-+static void aqr107_get_stats(struct phy_device *phydev,
-+ struct ethtool_stats *stats, u64 *data)
-+{
-+ struct aqr107_priv *priv = phydev->priv;
-+ u64 val;
-+ int i;
-+
-+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) {
-+ val = aqr107_get_stat(phydev, i);
-+ if (val == U64_MAX)
-+ phydev_err(phydev, "Reading HW Statistics failed for %s\n",
-+ aqr107_hw_stats[i].name);
-+ else
-+ priv->sgmii_stats[i] += val;
-+
-+ data[i] = priv->sgmii_stats[i];
-+ }
-+}
-+
-+static int aqr_config_aneg(struct phy_device *phydev)
-+{
-+ bool changed = false;
-+ u16 reg;
-+ int ret;
-+
-+ if (phydev->autoneg == AUTONEG_DISABLE)
-+ return genphy_c45_pma_setup_forced(phydev);
-+
-+ ret = genphy_c45_an_config_aneg(phydev);
-+ if (ret < 0)
-+ return ret;
-+ if (ret > 0)
-+ changed = true;
-+
-+ /* Clause 45 has no standardized support for 1000BaseT, therefore
-+ * use vendor registers for this mode.
-+ */
-+ reg = 0;
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
-+
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
-+
-+ /* Handle the case when the 2.5G and 5G speeds are not advertised */
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;
-+
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-+ phydev->advertising))
-+ reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;
-+
-+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-+ MDIO_AN_VEND_PROV_1000BASET_HALF |
-+ MDIO_AN_VEND_PROV_1000BASET_FULL |
-+ MDIO_AN_VEND_PROV_2500BASET_FULL |
-+ MDIO_AN_VEND_PROV_5000BASET_FULL, reg);
-+ if (ret < 0)
-+ return ret;
-+ if (ret > 0)
-+ changed = true;
-+
-+ return genphy_c45_check_and_restart_aneg(phydev, changed);
-+}
-+
-+static int aqr_config_intr(struct phy_device *phydev)
-+{
-+ bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
-+ int err;
-+
-+ if (en) {
-+ /* Clear any pending interrupts before enabling them */
-+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-+ if (err < 0)
-+ return err;
-+ }
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,
-+ en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);
-+ if (err < 0)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,
-+ en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);
-+ if (err < 0)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
-+ en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
-+ VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
-+ if (err < 0)
-+ return err;
-+
-+ if (!en) {
-+ /* Clear any pending interrupts after we have disabled them */
-+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-+ if (err < 0)
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
-+{
-+ int irq_status;
-+
-+ irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,
-+ MDIO_AN_TX_VEND_INT_STATUS2);
-+ if (irq_status < 0) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))
-+ return IRQ_NONE;
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int aqr_read_status(struct phy_device *phydev)
-+{
-+ int val;
-+
-+ if (phydev->autoneg == AUTONEG_ENABLE) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-+ if (val < 0)
-+ return val;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-+ phydev->lp_advertising,
-+ val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-+ phydev->lp_advertising,
-+ val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);
-+ }
-+
-+ return genphy_c45_read_status(phydev);
-+}
-+
-+static int aqr107_read_rate(struct phy_device *phydev)
-+{
-+ u32 config_reg;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
-+ if (val < 0)
-+ return val;
-+
-+ if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
-+ phydev->duplex = DUPLEX_FULL;
-+ else
-+ phydev->duplex = DUPLEX_HALF;
-+
-+ switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
-+ case MDIO_AN_TX_VEND_STATUS1_10BASET:
-+ phydev->speed = SPEED_10;
-+ config_reg = VEND1_GLOBAL_CFG_10M;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_100BASETX:
-+ phydev->speed = SPEED_100;
-+ config_reg = VEND1_GLOBAL_CFG_100M;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_1000BASET:
-+ phydev->speed = SPEED_1000;
-+ config_reg = VEND1_GLOBAL_CFG_1G;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_2500BASET:
-+ phydev->speed = SPEED_2500;
-+ config_reg = VEND1_GLOBAL_CFG_2_5G;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_5000BASET:
-+ phydev->speed = SPEED_5000;
-+ config_reg = VEND1_GLOBAL_CFG_5G;
-+ break;
-+ case MDIO_AN_TX_VEND_STATUS1_10GBASET:
-+ phydev->speed = SPEED_10000;
-+ config_reg = VEND1_GLOBAL_CFG_10G;
-+ break;
-+ default:
-+ phydev->speed = SPEED_UNKNOWN;
-+ return 0;
-+ }
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);
-+ if (val < 0)
-+ return val;
-+
-+ if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==
-+ VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)
-+ phydev->rate_matching = RATE_MATCH_PAUSE;
-+ else
-+ phydev->rate_matching = RATE_MATCH_NONE;
-+
-+ return 0;
-+}
-+
-+static int aqr107_read_status(struct phy_device *phydev)
-+{
-+ int val, ret;
-+
-+ ret = aqr_read_status(phydev);
-+ if (ret)
-+ return ret;
-+
-+ if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
-+ return 0;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
-+ if (val < 0)
-+ return val;
-+
-+ switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
-+ phydev->interface = PHY_INTERFACE_MODE_10GKR;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:
-+ phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
-+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
-+ phydev->interface = PHY_INTERFACE_MODE_USXGMII;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:
-+ phydev->interface = PHY_INTERFACE_MODE_XAUI;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:
-+ phydev->interface = PHY_INTERFACE_MODE_RXAUI;
-+ break;
-+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ break;
-+ default:
-+ phydev->interface = PHY_INTERFACE_MODE_NA;
-+ break;
-+ }
-+
-+ /* Read possibly downshifted rate from vendor register */
-+ return aqr107_read_rate(phydev);
-+}
-+
-+static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
-+{
-+ int val, cnt, enable;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);
-+ if (val < 0)
-+ return val;
-+
-+ enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);
-+ cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
-+
-+ *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;
-+
-+ return 0;
-+}
-+
-+static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
-+{
-+ int val = 0;
-+
-+ if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))
-+ return -E2BIG;
-+
-+ if (cnt != DOWNSHIFT_DEV_DISABLE) {
-+ val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;
-+ val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);
-+ }
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-+ MDIO_AN_VEND_PROV_DOWNSHIFT_EN |
-+ MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
-+}
-+
-+static int aqr107_get_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return aqr107_get_downshift(phydev, data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int aqr107_set_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, const void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return aqr107_set_downshift(phydev, *(const u8 *)data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+/* If we configure settings whilst firmware is still initializing the chip,
-+ * then these settings may be overwritten. Therefore make sure chip
-+ * initialization has completed. Use presence of the firmware ID as
-+ * indicator for initialization having completed.
-+ * The chip also provides a "reset completed" bit, but it's cleared after
-+ * read. Therefore function would time out if called again.
-+ */
-+static int aqr107_wait_reset_complete(struct phy_device *phydev)
-+{
-+ int val;
-+
-+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_FW_ID, val, val != 0,
-+ 20000, 2000000, false);
-+}
-+
-+static void aqr107_chip_info(struct phy_device *phydev)
-+{
-+ u8 fw_major, fw_minor, build_id, prov_id;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
-+ if (val < 0)
-+ return;
-+
-+ fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val);
-+ fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1);
-+ if (val < 0)
-+ return;
-+
-+ build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
-+ prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
-+
-+ phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
-+ fw_major, fw_minor, build_id, prov_id);
-+}
-+
-+static int aqr107_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Check that the PHY interface type is compatible */
-+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_1000BASEKX &&
-+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
-+ phydev->interface != PHY_INTERFACE_MODE_XGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_USXGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_10GKR &&
-+ phydev->interface != PHY_INTERFACE_MODE_10GBASER &&
-+ phydev->interface != PHY_INTERFACE_MODE_XAUI &&
-+ phydev->interface != PHY_INTERFACE_MODE_RXAUI)
-+ return -ENODEV;
-+
-+ WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
-+ "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");
-+
-+ ret = aqr107_wait_reset_complete(phydev);
-+ if (!ret)
-+ aqr107_chip_info(phydev);
-+
-+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
-+}
-+
-+static int aqcs109_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Check that the PHY interface type is compatible */
-+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
-+ return -ENODEV;
-+
-+ ret = aqr107_wait_reset_complete(phydev);
-+ if (!ret)
-+ aqr107_chip_info(phydev);
-+
-+ /* AQCS109 belongs to a chip family partially supporting 10G and 5G.
-+ * PMA speed ability bits are the same for all members of the family,
-+ * AQCS109 however supports speeds up to 2.5G only.
-+ */
-+ phy_set_max_speed(phydev, SPEED_2500);
-+
-+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
-+}
-+
-+static void aqr107_link_change_notify(struct phy_device *phydev)
-+{
-+ u8 fw_major, fw_minor;
-+ bool downshift, short_reach, afr;
-+ int mode, val;
-+
-+ if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE)
-+ return;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-+ /* call failed or link partner is no Aquantia PHY */
-+ if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY))
-+ return;
-+
-+ short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH;
-+ downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4);
-+ if (val < 0)
-+ return;
-+
-+ fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val);
-+ fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3);
-+ if (val < 0)
-+ return;
-+
-+ afr = val & MDIO_AN_RX_VEND_STAT3_AFR;
-+
-+ phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n",
-+ fw_major, fw_minor,
-+ short_reach ? ", short reach mode" : "",
-+ downshift ? ", fast-retrain downshift advertised" : "",
-+ afr ? ", fast reframe advertised" : "");
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9);
-+ if (val < 0)
-+ return;
-+
-+ mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val);
-+ if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2)
-+ phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
-+}
-+
-+static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
-+{
-+ int val, err;
-+
-+ /* The datasheet notes to wait at least 1ms after issuing a
-+ * processor intensive operation before checking.
-+ * We cannot use the 'sleep_before_read' parameter of read_poll_timeout
-+ * because that just determines the maximum time slept, not the minimum.
-+ */
-+ usleep_range(1000, 5000);
-+
-+ err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_GEN_STAT2, val,
-+ !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
-+ AQR107_OP_IN_PROG_SLEEP,
-+ AQR107_OP_IN_PROG_TIMEOUT, false);
-+ if (err) {
-+ phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+static int aqr107_get_rate_matching(struct phy_device *phydev,
-+ phy_interface_t iface)
-+{
-+ if (iface == PHY_INTERFACE_MODE_10GBASER ||
-+ iface == PHY_INTERFACE_MODE_2500BASEX ||
-+ iface == PHY_INTERFACE_MODE_NA)
-+ return RATE_MATCH_PAUSE;
-+ return RATE_MATCH_NONE;
-+}
-+
-+static int aqr107_suspend(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-+ MDIO_CTRL1_LPOWER);
-+ if (err)
-+ return err;
-+
-+ return aqr107_wait_processor_intensive_op(phydev);
-+}
-+
-+static int aqr107_resume(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-+ MDIO_CTRL1_LPOWER);
-+ if (err)
-+ return err;
-+
-+ return aqr107_wait_processor_intensive_op(phydev);
-+}
-+
-+static int aqr107_probe(struct phy_device *phydev)
-+{
-+ phydev->priv = devm_kzalloc(&phydev->mdio.dev,
-+ sizeof(struct aqr107_priv), GFP_KERNEL);
-+ if (!phydev->priv)
-+ return -ENOMEM;
-+
-+ return aqr_hwmon_probe(phydev);
-+}
-+
-+static struct phy_driver aqr_driver[] = {
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
-+ .name = "Aquantia AQ1202",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),
-+ .name = "Aquantia AQ2104",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
-+ .name = "Aquantia AQR105",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
-+ .name = "Aquantia AQR106",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
-+ .name = "Aquantia AQR107",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
-+ .name = "Aquantia AQCS109",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqcs109_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
-+ .name = "Aquantia AQR405",
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr_read_status,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
-+ .name = "Aquantia AQR113C",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+};
-+
-+module_phy_driver(aqr_driver);
-+
-+static struct mdio_device_id __maybe_unused aqr_tbl[] = {
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, aqr_tbl);
-+
-+MODULE_DESCRIPTION("Aquantia PHY driver");
-+MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/phy/aquantia_hwmon.c
-+++ /dev/null
-@@ -1,250 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/* HWMON driver for Aquantia PHY
-- *
-- * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-- * Author: Andrew Lunn <andrew@lunn.ch>
-- * Author: Heiner Kallweit <hkallweit1@gmail.com>
-- */
--
--#include <linux/phy.h>
--#include <linux/device.h>
--#include <linux/ctype.h>
--#include <linux/hwmon.h>
--
--#include "aquantia.h"
--
--/* Vendor specific 1, MDIO_MMD_VEND2 */
--#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
--#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
--#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
--#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
--#define VEND1_THERMAL_STAT1 0xc820
--#define VEND1_THERMAL_STAT2 0xc821
--#define VEND1_THERMAL_STAT2_VALID BIT(0)
--#define VEND1_GENERAL_STAT1 0xc830
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
--
--#if IS_REACHABLE(CONFIG_HWMON)
--
--static umode_t aqr_hwmon_is_visible(const void *data,
-- enum hwmon_sensor_types type,
-- u32 attr, int channel)
--{
-- if (type != hwmon_temp)
-- return 0;
--
-- switch (attr) {
-- case hwmon_temp_input:
-- case hwmon_temp_min_alarm:
-- case hwmon_temp_max_alarm:
-- case hwmon_temp_lcrit_alarm:
-- case hwmon_temp_crit_alarm:
-- return 0444;
-- case hwmon_temp_min:
-- case hwmon_temp_max:
-- case hwmon_temp_lcrit:
-- case hwmon_temp_crit:
-- return 0644;
-- default:
-- return 0;
-- }
--}
--
--static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
--{
-- int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
--
-- if (temp < 0)
-- return temp;
--
-- /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */
-- *value = (s16)temp * 1000 / 256;
--
-- return 0;
--}
--
--static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
--{
-- int temp;
--
-- if (value >= 128000 || value < -128000)
-- return -ERANGE;
--
-- temp = value * 256 / 1000;
--
-- /* temp is in s16 range and we're interested in lower 16 bits only */
-- return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp);
--}
--
--static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit)
--{
-- int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
--
-- if (val < 0)
-- return val;
--
-- return !!(val & bit);
--}
--
--static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
--{
-- int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit);
--
-- if (val < 0)
-- return val;
--
-- *value = val;
--
-- return 0;
--}
--
--static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
-- u32 attr, int channel, long *value)
--{
-- struct phy_device *phydev = dev_get_drvdata(dev);
-- int reg;
--
-- if (type != hwmon_temp)
-- return -EOPNOTSUPP;
--
-- switch (attr) {
-- case hwmon_temp_input:
-- reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2,
-- VEND1_THERMAL_STAT2_VALID);
-- if (reg < 0)
-- return reg;
-- if (!reg)
-- return -EBUSY;
--
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
--
-- case hwmon_temp_lcrit:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-- value);
-- case hwmon_temp_min:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-- value);
-- case hwmon_temp_max:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-- value);
-- case hwmon_temp_crit:
-- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-- value);
-- case hwmon_temp_lcrit_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_LOW_TEMP_FAIL,
-- value);
-- case hwmon_temp_min_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_LOW_TEMP_WARN,
-- value);
-- case hwmon_temp_max_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_HIGH_TEMP_WARN,
-- value);
-- case hwmon_temp_crit_alarm:
-- return aqr_hwmon_status1(phydev,
-- VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL,
-- value);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
-- u32 attr, int channel, long value)
--{
-- struct phy_device *phydev = dev_get_drvdata(dev);
--
-- if (type != hwmon_temp)
-- return -EOPNOTSUPP;
--
-- switch (attr) {
-- case hwmon_temp_lcrit:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
-- value);
-- case hwmon_temp_min:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
-- value);
-- case hwmon_temp_max:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
-- value);
-- case hwmon_temp_crit:
-- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
-- value);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static const struct hwmon_ops aqr_hwmon_ops = {
-- .is_visible = aqr_hwmon_is_visible,
-- .read = aqr_hwmon_read,
-- .write = aqr_hwmon_write,
--};
--
--static u32 aqr_hwmon_chip_config[] = {
-- HWMON_C_REGISTER_TZ,
-- 0,
--};
--
--static const struct hwmon_channel_info aqr_hwmon_chip = {
-- .type = hwmon_chip,
-- .config = aqr_hwmon_chip_config,
--};
--
--static u32 aqr_hwmon_temp_config[] = {
-- HWMON_T_INPUT |
-- HWMON_T_MAX | HWMON_T_MIN |
-- HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM |
-- HWMON_T_CRIT | HWMON_T_LCRIT |
-- HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM,
-- 0,
--};
--
--static const struct hwmon_channel_info aqr_hwmon_temp = {
-- .type = hwmon_temp,
-- .config = aqr_hwmon_temp_config,
--};
--
--static const struct hwmon_channel_info *aqr_hwmon_info[] = {
-- &aqr_hwmon_chip,
-- &aqr_hwmon_temp,
-- NULL,
--};
--
--static const struct hwmon_chip_info aqr_hwmon_chip_info = {
-- .ops = &aqr_hwmon_ops,
-- .info = aqr_hwmon_info,
--};
--
--int aqr_hwmon_probe(struct phy_device *phydev)
--{
-- struct device *dev = &phydev->mdio.dev;
-- struct device *hwmon_dev;
-- char *hwmon_name;
-- int i, j;
--
-- hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
-- if (!hwmon_name)
-- return -ENOMEM;
--
-- for (i = j = 0; hwmon_name[i]; i++) {
-- if (isalnum(hwmon_name[i])) {
-- if (i != j)
-- hwmon_name[j] = hwmon_name[i];
-- j++;
-- }
-- }
-- hwmon_name[j] = '\0';
--
-- hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name,
-- phydev, &aqr_hwmon_chip_info, NULL);
--
-- return PTR_ERR_OR_ZERO(hwmon_dev);
--}
--
--#endif
---- a/drivers/net/phy/aquantia_main.c
-+++ /dev/null
-@@ -1,842 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/*
-- * Driver for Aquantia PHY
-- *
-- * Author: Shaohui Xie <Shaohui.Xie@freescale.com>
-- *
-- * Copyright 2015 Freescale Semiconductor, Inc.
-- */
--
--#include <linux/kernel.h>
--#include <linux/module.h>
--#include <linux/delay.h>
--#include <linux/bitfield.h>
--#include <linux/phy.h>
--
--#include "aquantia.h"
--
--#define PHY_ID_AQ1202 0x03a1b445
--#define PHY_ID_AQ2104 0x03a1b460
--#define PHY_ID_AQR105 0x03a1b4a2
--#define PHY_ID_AQR106 0x03a1b4d0
--#define PHY_ID_AQR107 0x03a1b4e0
--#define PHY_ID_AQCS109 0x03a1b5c2
--#define PHY_ID_AQR405 0x03a1b4b0
--#define PHY_ID_AQR113C 0x31c31c12
--
--#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7
--#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
--
--#define MDIO_AN_VEND_PROV 0xc400
--#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15)
--#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)
--#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11)
--#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
--#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
--#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
--#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
--
--#define MDIO_AN_TX_VEND_STATUS1 0xc800
--#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1)
--#define MDIO_AN_TX_VEND_STATUS1_10BASET 0
--#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1
--#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2
--#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3
--#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4
--#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5
--#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0)
--
--#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00
--#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1)
--
--#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01
--#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0)
--
--#define MDIO_AN_TX_VEND_INT_MASK2 0xd401
--#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0)
--
--#define MDIO_AN_RX_LP_STAT1 0xe820
--#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15)
--#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14)
--#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13)
--#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12)
--#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2)
--
--#define MDIO_AN_RX_LP_STAT4 0xe823
--#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8)
--#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0)
--
--#define MDIO_AN_RX_VEND_STAT3 0xe832
--#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
--
--/* MDIO_MMD_C22EXT */
--#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292
--#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294
--#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297
--#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313
--#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315
--#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317
--#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318
--#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319
--#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
--#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
--
--/* Vendor specific 1, MDIO_MMD_VEND1 */
--#define VEND1_GLOBAL_FW_ID 0x0020
--#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
--#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
--
--#define VEND1_GLOBAL_GEN_STAT2 0xc831
--#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
--
--/* The following registers all have similar layouts; first the registers... */
--#define VEND1_GLOBAL_CFG_10M 0x0310
--#define VEND1_GLOBAL_CFG_100M 0x031b
--#define VEND1_GLOBAL_CFG_1G 0x031c
--#define VEND1_GLOBAL_CFG_2_5G 0x031d
--#define VEND1_GLOBAL_CFG_5G 0x031e
--#define VEND1_GLOBAL_CFG_10G 0x031f
--/* ...and now the fields */
--#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
--
--#define VEND1_GLOBAL_RSVD_STAT1 0xc885
--#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
--#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
--
--#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
--#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
--#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
--
--#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
--#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
--
--#define VEND1_GLOBAL_INT_STD_MASK 0xff00
--#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
--#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
--#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
--#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
--#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
--#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
--
--#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
--#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
--#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
--#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
--#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
--#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
--
--/* Sleep and timeout for checking if the Processor-Intensive
-- * MDIO operation is finished
-- */
--#define AQR107_OP_IN_PROG_SLEEP 1000
--#define AQR107_OP_IN_PROG_TIMEOUT 100000
--
--struct aqr107_hw_stat {
-- const char *name;
-- int reg;
-- int size;
--};
--
--#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
--static const struct aqr107_hw_stat aqr107_hw_stats[] = {
-- SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26),
-- SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26),
-- SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8),
-- SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26),
-- SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26),
-- SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8),
-- SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8),
-- SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8),
-- SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16),
-- SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22),
--};
--#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
--
--struct aqr107_priv {
-- u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
--};
--
--static int aqr107_get_sset_count(struct phy_device *phydev)
--{
-- return AQR107_SGMII_STAT_SZ;
--}
--
--static void aqr107_get_strings(struct phy_device *phydev, u8 *data)
--{
-- int i;
--
-- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++)
-- strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name,
-- ETH_GSTRING_LEN);
--}
--
--static u64 aqr107_get_stat(struct phy_device *phydev, int index)
--{
-- const struct aqr107_hw_stat *stat = aqr107_hw_stats + index;
-- int len_l = min(stat->size, 16);
-- int len_h = stat->size - len_l;
-- u64 ret;
-- int val;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg);
-- if (val < 0)
-- return U64_MAX;
--
-- ret = val & GENMASK(len_l - 1, 0);
-- if (len_h) {
-- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1);
-- if (val < 0)
-- return U64_MAX;
--
-- ret += (val & GENMASK(len_h - 1, 0)) << 16;
-- }
--
-- return ret;
--}
--
--static void aqr107_get_stats(struct phy_device *phydev,
-- struct ethtool_stats *stats, u64 *data)
--{
-- struct aqr107_priv *priv = phydev->priv;
-- u64 val;
-- int i;
--
-- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) {
-- val = aqr107_get_stat(phydev, i);
-- if (val == U64_MAX)
-- phydev_err(phydev, "Reading HW Statistics failed for %s\n",
-- aqr107_hw_stats[i].name);
-- else
-- priv->sgmii_stats[i] += val;
--
-- data[i] = priv->sgmii_stats[i];
-- }
--}
--
--static int aqr_config_aneg(struct phy_device *phydev)
--{
-- bool changed = false;
-- u16 reg;
-- int ret;
--
-- if (phydev->autoneg == AUTONEG_DISABLE)
-- return genphy_c45_pma_setup_forced(phydev);
--
-- ret = genphy_c45_an_config_aneg(phydev);
-- if (ret < 0)
-- return ret;
-- if (ret > 0)
-- changed = true;
--
-- /* Clause 45 has no standardized support for 1000BaseT, therefore
-- * use vendor registers for this mode.
-- */
-- reg = 0;
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
--
-- /* Handle the case when the 2.5G and 5G speeds are not advertised */
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-- phydev->advertising))
-- reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;
--
-- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-- MDIO_AN_VEND_PROV_1000BASET_HALF |
-- MDIO_AN_VEND_PROV_1000BASET_FULL |
-- MDIO_AN_VEND_PROV_2500BASET_FULL |
-- MDIO_AN_VEND_PROV_5000BASET_FULL, reg);
-- if (ret < 0)
-- return ret;
-- if (ret > 0)
-- changed = true;
--
-- return genphy_c45_check_and_restart_aneg(phydev, changed);
--}
--
--static int aqr_config_intr(struct phy_device *phydev)
--{
-- bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
-- int err;
--
-- if (en) {
-- /* Clear any pending interrupts before enabling them */
-- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-- if (err < 0)
-- return err;
-- }
--
-- err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,
-- en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);
-- if (err < 0)
-- return err;
--
-- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,
-- en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);
-- if (err < 0)
-- return err;
--
-- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
-- en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
-- VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
-- if (err < 0)
-- return err;
--
-- if (!en) {
-- /* Clear any pending interrupts after we have disabled them */
-- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
-- if (err < 0)
-- return err;
-- }
--
-- return 0;
--}
--
--static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
--{
-- int irq_status;
--
-- irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,
-- MDIO_AN_TX_VEND_INT_STATUS2);
-- if (irq_status < 0) {
-- phy_error(phydev);
-- return IRQ_NONE;
-- }
--
-- if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))
-- return IRQ_NONE;
--
-- phy_trigger_machine(phydev);
--
-- return IRQ_HANDLED;
--}
--
--static int aqr_read_status(struct phy_device *phydev)
--{
-- int val;
--
-- if (phydev->autoneg == AUTONEG_ENABLE) {
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-- if (val < 0)
-- return val;
--
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-- phydev->lp_advertising,
-- val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-- phydev->lp_advertising,
-- val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);
-- }
--
-- return genphy_c45_read_status(phydev);
--}
--
--static int aqr107_read_rate(struct phy_device *phydev)
--{
-- u32 config_reg;
-- int val;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
-- if (val < 0)
-- return val;
--
-- if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
-- phydev->duplex = DUPLEX_FULL;
-- else
-- phydev->duplex = DUPLEX_HALF;
--
-- switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
-- case MDIO_AN_TX_VEND_STATUS1_10BASET:
-- phydev->speed = SPEED_10;
-- config_reg = VEND1_GLOBAL_CFG_10M;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_100BASETX:
-- phydev->speed = SPEED_100;
-- config_reg = VEND1_GLOBAL_CFG_100M;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_1000BASET:
-- phydev->speed = SPEED_1000;
-- config_reg = VEND1_GLOBAL_CFG_1G;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_2500BASET:
-- phydev->speed = SPEED_2500;
-- config_reg = VEND1_GLOBAL_CFG_2_5G;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_5000BASET:
-- phydev->speed = SPEED_5000;
-- config_reg = VEND1_GLOBAL_CFG_5G;
-- break;
-- case MDIO_AN_TX_VEND_STATUS1_10GBASET:
-- phydev->speed = SPEED_10000;
-- config_reg = VEND1_GLOBAL_CFG_10G;
-- break;
-- default:
-- phydev->speed = SPEED_UNKNOWN;
-- return 0;
-- }
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);
-- if (val < 0)
-- return val;
--
-- if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==
-- VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)
-- phydev->rate_matching = RATE_MATCH_PAUSE;
-- else
-- phydev->rate_matching = RATE_MATCH_NONE;
--
-- return 0;
--}
--
--static int aqr107_read_status(struct phy_device *phydev)
--{
-- int val, ret;
--
-- ret = aqr_read_status(phydev);
-- if (ret)
-- return ret;
--
-- if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
-- return 0;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
-- if (val < 0)
-- return val;
--
-- switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
-- phydev->interface = PHY_INTERFACE_MODE_10GKR;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:
-- phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
-- phydev->interface = PHY_INTERFACE_MODE_10GBASER;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
-- phydev->interface = PHY_INTERFACE_MODE_USXGMII;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:
-- phydev->interface = PHY_INTERFACE_MODE_XAUI;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
-- phydev->interface = PHY_INTERFACE_MODE_SGMII;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:
-- phydev->interface = PHY_INTERFACE_MODE_RXAUI;
-- break;
-- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
-- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-- break;
-- default:
-- phydev->interface = PHY_INTERFACE_MODE_NA;
-- break;
-- }
--
-- /* Read possibly downshifted rate from vendor register */
-- return aqr107_read_rate(phydev);
--}
--
--static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
--{
-- int val, cnt, enable;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);
-- if (val < 0)
-- return val;
--
-- enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);
-- cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
--
-- *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;
--
-- return 0;
--}
--
--static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
--{
-- int val = 0;
--
-- if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))
-- return -E2BIG;
--
-- if (cnt != DOWNSHIFT_DEV_DISABLE) {
-- val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;
-- val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);
-- }
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
-- MDIO_AN_VEND_PROV_DOWNSHIFT_EN |
-- MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
--}
--
--static int aqr107_get_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return aqr107_get_downshift(phydev, data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static int aqr107_set_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, const void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return aqr107_set_downshift(phydev, *(const u8 *)data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--/* If we configure settings whilst firmware is still initializing the chip,
-- * then these settings may be overwritten. Therefore make sure chip
-- * initialization has completed. Use presence of the firmware ID as
-- * indicator for initialization having completed.
-- * The chip also provides a "reset completed" bit, but it's cleared after
-- * read. Therefore function would time out if called again.
-- */
--static int aqr107_wait_reset_complete(struct phy_device *phydev)
--{
-- int val;
--
-- return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-- VEND1_GLOBAL_FW_ID, val, val != 0,
-- 20000, 2000000, false);
--}
--
--static void aqr107_chip_info(struct phy_device *phydev)
--{
-- u8 fw_major, fw_minor, build_id, prov_id;
-- int val;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
-- if (val < 0)
-- return;
--
-- fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val);
-- fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1);
-- if (val < 0)
-- return;
--
-- build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
-- prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
--
-- phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
-- fw_major, fw_minor, build_id, prov_id);
--}
--
--static int aqr107_config_init(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Check that the PHY interface type is compatible */
-- if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_1000BASEKX &&
-- phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
-- phydev->interface != PHY_INTERFACE_MODE_XGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_USXGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_10GKR &&
-- phydev->interface != PHY_INTERFACE_MODE_10GBASER &&
-- phydev->interface != PHY_INTERFACE_MODE_XAUI &&
-- phydev->interface != PHY_INTERFACE_MODE_RXAUI)
-- return -ENODEV;
--
-- WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
-- "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");
--
-- ret = aqr107_wait_reset_complete(phydev);
-- if (!ret)
-- aqr107_chip_info(phydev);
--
-- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
--}
--
--static int aqcs109_config_init(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Check that the PHY interface type is compatible */
-- if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
-- phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
-- return -ENODEV;
--
-- ret = aqr107_wait_reset_complete(phydev);
-- if (!ret)
-- aqr107_chip_info(phydev);
--
-- /* AQCS109 belongs to a chip family partially supporting 10G and 5G.
-- * PMA speed ability bits are the same for all members of the family,
-- * AQCS109 however supports speeds up to 2.5G only.
-- */
-- phy_set_max_speed(phydev, SPEED_2500);
--
-- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
--}
--
--static void aqr107_link_change_notify(struct phy_device *phydev)
--{
-- u8 fw_major, fw_minor;
-- bool downshift, short_reach, afr;
-- int mode, val;
--
-- if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE)
-- return;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
-- /* call failed or link partner is no Aquantia PHY */
-- if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY))
-- return;
--
-- short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH;
-- downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4);
-- if (val < 0)
-- return;
--
-- fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val);
-- fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3);
-- if (val < 0)
-- return;
--
-- afr = val & MDIO_AN_RX_VEND_STAT3_AFR;
--
-- phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n",
-- fw_major, fw_minor,
-- short_reach ? ", short reach mode" : "",
-- downshift ? ", fast-retrain downshift advertised" : "",
-- afr ? ", fast reframe advertised" : "");
--
-- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9);
-- if (val < 0)
-- return;
--
-- mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val);
-- if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2)
-- phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
--}
--
--static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
--{
-- int val, err;
--
-- /* The datasheet notes to wait at least 1ms after issuing a
-- * processor intensive operation before checking.
-- * We cannot use the 'sleep_before_read' parameter of read_poll_timeout
-- * because that just determines the maximum time slept, not the minimum.
-- */
-- usleep_range(1000, 5000);
--
-- err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-- VEND1_GLOBAL_GEN_STAT2, val,
-- !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
-- AQR107_OP_IN_PROG_SLEEP,
-- AQR107_OP_IN_PROG_TIMEOUT, false);
-- if (err) {
-- phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
-- return err;
-- }
--
-- return 0;
--}
--
--static int aqr107_get_rate_matching(struct phy_device *phydev,
-- phy_interface_t iface)
--{
-- if (iface == PHY_INTERFACE_MODE_10GBASER ||
-- iface == PHY_INTERFACE_MODE_2500BASEX ||
-- iface == PHY_INTERFACE_MODE_NA)
-- return RATE_MATCH_PAUSE;
-- return RATE_MATCH_NONE;
--}
--
--static int aqr107_suspend(struct phy_device *phydev)
--{
-- int err;
--
-- err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-- MDIO_CTRL1_LPOWER);
-- if (err)
-- return err;
--
-- return aqr107_wait_processor_intensive_op(phydev);
--}
--
--static int aqr107_resume(struct phy_device *phydev)
--{
-- int err;
--
-- err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-- MDIO_CTRL1_LPOWER);
-- if (err)
-- return err;
--
-- return aqr107_wait_processor_intensive_op(phydev);
--}
--
--static int aqr107_probe(struct phy_device *phydev)
--{
-- phydev->priv = devm_kzalloc(&phydev->mdio.dev,
-- sizeof(struct aqr107_priv), GFP_KERNEL);
-- if (!phydev->priv)
-- return -ENOMEM;
--
-- return aqr_hwmon_probe(phydev);
--}
--
--static struct phy_driver aqr_driver[] = {
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
-- .name = "Aquantia AQ1202",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),
-- .name = "Aquantia AQ2104",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
-- .name = "Aquantia AQR105",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
-- .name = "Aquantia AQR106",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
-- .name = "Aquantia AQR107",
-- .probe = aqr107_probe,
-- .get_rate_matching = aqr107_get_rate_matching,
-- .config_init = aqr107_config_init,
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr107_read_status,
-- .get_tunable = aqr107_get_tunable,
-- .set_tunable = aqr107_set_tunable,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
-- .get_sset_count = aqr107_get_sset_count,
-- .get_strings = aqr107_get_strings,
-- .get_stats = aqr107_get_stats,
-- .link_change_notify = aqr107_link_change_notify,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
-- .name = "Aquantia AQCS109",
-- .probe = aqr107_probe,
-- .get_rate_matching = aqr107_get_rate_matching,
-- .config_init = aqcs109_config_init,
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr107_read_status,
-- .get_tunable = aqr107_get_tunable,
-- .set_tunable = aqr107_set_tunable,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
-- .get_sset_count = aqr107_get_sset_count,
-- .get_strings = aqr107_get_strings,
-- .get_stats = aqr107_get_stats,
-- .link_change_notify = aqr107_link_change_notify,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
-- .name = "Aquantia AQR405",
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr_read_status,
--},
--{
-- PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
-- .name = "Aquantia AQR113C",
-- .probe = aqr107_probe,
-- .get_rate_matching = aqr107_get_rate_matching,
-- .config_init = aqr107_config_init,
-- .config_aneg = aqr_config_aneg,
-- .config_intr = aqr_config_intr,
-- .handle_interrupt = aqr_handle_interrupt,
-- .read_status = aqr107_read_status,
-- .get_tunable = aqr107_get_tunable,
-- .set_tunable = aqr107_set_tunable,
-- .suspend = aqr107_suspend,
-- .resume = aqr107_resume,
-- .get_sset_count = aqr107_get_sset_count,
-- .get_strings = aqr107_get_strings,
-- .get_stats = aqr107_get_stats,
-- .link_change_notify = aqr107_link_change_notify,
--},
--};
--
--module_phy_driver(aqr_driver);
--
--static struct mdio_device_id __maybe_unused aqr_tbl[] = {
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
-- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
-- { }
--};
--
--MODULE_DEVICE_TABLE(mdio, aqr_tbl);
--
--MODULE_DESCRIPTION("Aquantia PHY driver");
--MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");
--MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch b/target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch
deleted file mode 100644
index 2b94522723..0000000000
--- a/target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From e1fbfa4a995d42e02e22b0dff2f8b4fdee1504b3 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 14 Nov 2023 15:08:42 +0100
-Subject: [PATCH 2/3] net: phy: aquantia: move MMD_VEND define to header
-
-Move MMD_VEND define to header to clean things up and in preparation for
-firmware loading support that require some define placed in
-aquantia_main.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/aquantia.h | 69 +++++++++++++++++++++++
- drivers/net/phy/aquantia/aquantia_hwmon.c | 14 -----
- drivers/net/phy/aquantia/aquantia_main.c | 55 ------------------
- 3 files changed, 69 insertions(+), 69 deletions(-)
-
---- a/drivers/net/phy/aquantia/aquantia.h
-+++ b/drivers/net/phy/aquantia/aquantia.h
-@@ -9,6 +9,75 @@
- #include <linux/device.h>
- #include <linux/phy.h>
-
-+/* Vendor specific 1, MDIO_MMD_VEND1 */
-+#define VEND1_GLOBAL_FW_ID 0x0020
-+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
-+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
-+
-+/* The following registers all have similar layouts; first the registers... */
-+#define VEND1_GLOBAL_CFG_10M 0x0310
-+#define VEND1_GLOBAL_CFG_100M 0x031b
-+#define VEND1_GLOBAL_CFG_1G 0x031c
-+#define VEND1_GLOBAL_CFG_2_5G 0x031d
-+#define VEND1_GLOBAL_CFG_5G 0x031e
-+#define VEND1_GLOBAL_CFG_10G 0x031f
-+/* ...and now the fields */
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
-+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-+
-+/* Vendor specific 1, MDIO_MMD_VEND2 */
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
-+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
-+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
-+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
-+#define VEND1_THERMAL_STAT1 0xc820
-+#define VEND1_THERMAL_STAT2 0xc821
-+#define VEND1_THERMAL_STAT2_VALID BIT(0)
-+#define VEND1_GENERAL_STAT1 0xc830
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
-+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
-+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
-+
-+#define VEND1_GLOBAL_GEN_STAT2 0xc831
-+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
-+
-+#define VEND1_GLOBAL_RSVD_STAT1 0xc885
-+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
-+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
-+
-+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
-+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
-+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
-+
-+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
-+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
-+
-+#define VEND1_GLOBAL_INT_STD_MASK 0xff00
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
-+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
-+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
-+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
-+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
-+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
-+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
-+
-+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
-+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
-+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
-+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
-+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
-+
- #if IS_REACHABLE(CONFIG_HWMON)
- int aqr_hwmon_probe(struct phy_device *phydev);
- #else
---- a/drivers/net/phy/aquantia/aquantia_hwmon.c
-+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c
-@@ -13,20 +13,6 @@
-
- #include "aquantia.h"
-
--/* Vendor specific 1, MDIO_MMD_VEND2 */
--#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
--#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
--#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
--#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
--#define VEND1_THERMAL_STAT1 0xc820
--#define VEND1_THERMAL_STAT2 0xc821
--#define VEND1_THERMAL_STAT2_VALID BIT(0)
--#define VEND1_GENERAL_STAT1 0xc830
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
--#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
--#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
--
- #if IS_REACHABLE(CONFIG_HWMON)
-
- static umode_t aqr_hwmon_is_visible(const void *data,
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -89,61 +89,6 @@
- #define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
- #define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
-
--/* Vendor specific 1, MDIO_MMD_VEND1 */
--#define VEND1_GLOBAL_FW_ID 0x0020
--#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
--#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
--
--#define VEND1_GLOBAL_GEN_STAT2 0xc831
--#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
--
--/* The following registers all have similar layouts; first the registers... */
--#define VEND1_GLOBAL_CFG_10M 0x0310
--#define VEND1_GLOBAL_CFG_100M 0x031b
--#define VEND1_GLOBAL_CFG_1G 0x031c
--#define VEND1_GLOBAL_CFG_2_5G 0x031d
--#define VEND1_GLOBAL_CFG_5G 0x031e
--#define VEND1_GLOBAL_CFG_10G 0x031f
--/* ...and now the fields */
--#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
--#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
--
--#define VEND1_GLOBAL_RSVD_STAT1 0xc885
--#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
--#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
--
--#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
--#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
--#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
--
--#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
--#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
--
--#define VEND1_GLOBAL_INT_STD_MASK 0xff00
--#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
--#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
--#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
--#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
--#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
--#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
--#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
--#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
--
--#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
--#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
--#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
--#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
--#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
--#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
--#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
--
- /* Sleep and timeout for checking if the Processor-Intensive
- * MDIO operation is finished
- */
diff --git a/target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch b/target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch
deleted file mode 100644
index aa52b3baa6..0000000000
--- a/target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch
+++ /dev/null
@@ -1,504 +0,0 @@
-From e93984ebc1c82bd34f7a1b3391efaceee0a8ae96 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Tue, 14 Nov 2023 15:08:43 +0100
-Subject: [PATCH 3/3] net: phy: aquantia: add firmware load support
-
-Aquantia PHY-s require firmware to be loaded before they start operating.
-It can be automatically loaded in case when there is a SPI-NOR connected
-to Aquantia PHY-s or can be loaded from the host via MDIO.
-
-This patch adds support for loading the firmware via MDIO as in most cases
-there is no SPI-NOR being used to save on cost.
-Firmware loading code itself is ported from mainline U-boot with cleanups.
-
-The firmware has mixed values both in big and little endian.
-PHY core itself is big-endian but it expects values to be in little-endian.
-The firmware is little-endian but CRC-16 value for it is stored at the end
-of firmware in big-endian.
-
-It seems the PHY does the conversion internally from firmware that is
-little-endian to the PHY that is big-endian on using the mailbox
-but mailbox returns a big-endian CRC-16 to verify the written data
-integrity.
-
-Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/Kconfig | 1 +
- drivers/net/phy/aquantia/Makefile | 2 +-
- drivers/net/phy/aquantia/aquantia.h | 32 ++
- drivers/net/phy/aquantia/aquantia_firmware.c | 370 +++++++++++++++++++
- drivers/net/phy/aquantia/aquantia_main.c | 6 +
- 5 files changed, 410 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/phy/aquantia/aquantia_firmware.c
-
---- a/drivers/net/phy/aquantia/Kconfig
-+++ b/drivers/net/phy/aquantia/Kconfig
-@@ -1,5 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0-only
- config AQUANTIA_PHY
- tristate "Aquantia PHYs"
-+ select CRC_CCITT
- help
- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
---- a/drivers/net/phy/aquantia/Makefile
-+++ b/drivers/net/phy/aquantia/Makefile
-@@ -1,5 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
--aquantia-objs += aquantia_main.o
-+aquantia-objs += aquantia_main.o aquantia_firmware.o
- ifdef CONFIG_HWMON
- aquantia-objs += aquantia_hwmon.o
- endif
---- a/drivers/net/phy/aquantia/aquantia.h
-+++ b/drivers/net/phy/aquantia/aquantia.h
-@@ -10,10 +10,35 @@
- #include <linux/phy.h>
-
- /* Vendor specific 1, MDIO_MMD_VEND1 */
-+#define VEND1_GLOBAL_SC 0x0
-+#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15)
-+#define VEND1_GLOBAL_SC_LOW_POWER BIT(11)
-+
- #define VEND1_GLOBAL_FW_ID 0x0020
- #define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
- #define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
-
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8)
-+
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16))
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x))
-+
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16))
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0)
-+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x))
-+
- /* The following registers all have similar layouts; first the registers... */
- #define VEND1_GLOBAL_CFG_10M 0x0310
- #define VEND1_GLOBAL_CFG_100M 0x031b
-@@ -28,6 +53,11 @@
- #define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-
- /* Vendor specific 1, MDIO_MMD_VEND2 */
-+#define VEND1_GLOBAL_CONTROL2 0xc001
-+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15)
-+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6)
-+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0)
-+
- #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
- #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
- #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
-@@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *p
- #else
- static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
- #endif
-+
-+int aqr_firmware_load(struct phy_device *phydev);
---- /dev/null
-+++ b/drivers/net/phy/aquantia/aquantia_firmware.c
-@@ -0,0 +1,370 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/bitfield.h>
-+#include <linux/of.h>
-+#include <linux/firmware.h>
-+#include <linux/crc-ccitt.h>
-+#include <linux/nvmem-consumer.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include "aquantia.h"
-+
-+#define UP_RESET_SLEEP 100
-+
-+/* addresses of memory segments in the phy */
-+#define DRAM_BASE_ADDR 0x3FFE0000
-+#define IRAM_BASE_ADDR 0x40000000
-+
-+/* firmware image format constants */
-+#define VERSION_STRING_SIZE 0x40
-+#define VERSION_STRING_OFFSET 0x0200
-+/* primary offset is written at an offset from the start of the fw blob */
-+#define PRIMARY_OFFSET_OFFSET 0x8
-+/* primary offset needs to be then added to a base offset */
-+#define PRIMARY_OFFSET_SHIFT 12
-+#define PRIMARY_OFFSET(x) ((x) << PRIMARY_OFFSET_SHIFT)
-+#define HEADER_OFFSET 0x300
-+
-+struct aqr_fw_header {
-+ u32 padding;
-+ u8 iram_offset[3];
-+ u8 iram_size[3];
-+ u8 dram_offset[3];
-+ u8 dram_size[3];
-+} __packed;
-+
-+enum aqr_fw_src {
-+ AQR_FW_SRC_NVMEM = 0,
-+ AQR_FW_SRC_FS,
-+};
-+
-+static const char * const aqr_fw_src_string[] = {
-+ [AQR_FW_SRC_NVMEM] = "NVMEM",
-+ [AQR_FW_SRC_FS] = "FS",
-+};
-+
-+/* AQR firmware doesn't have fixed offsets for iram and dram section
-+ * but instead provide an header with the offset to use on reading
-+ * and parsing the firmware.
-+ *
-+ * AQR firmware can't be trusted and each offset is validated to be
-+ * not negative and be in the size of the firmware itself.
-+ */
-+static bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
-+{
-+ return offset + get_size <= size;
-+}
-+
-+static int aqr_fw_get_be16(const u8 *data, size_t offset, size_t size, u16 *value)
-+{
-+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
-+ return -EINVAL;
-+
-+ *value = get_unaligned_be16(data + offset);
-+
-+ return 0;
-+}
-+
-+static int aqr_fw_get_le16(const u8 *data, size_t offset, size_t size, u16 *value)
-+{
-+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
-+ return -EINVAL;
-+
-+ *value = get_unaligned_le16(data + offset);
-+
-+ return 0;
-+}
-+
-+static int aqr_fw_get_le24(const u8 *data, size_t offset, size_t size, u32 *value)
-+{
-+ if (!aqr_fw_validate_get(size, offset, sizeof(u8) * 3))
-+ return -EINVAL;
-+
-+ *value = get_unaligned_le24(data + offset);
-+
-+ return 0;
-+}
-+
-+/* load data into the phy's memory */
-+static int aqr_fw_load_memory(struct phy_device *phydev, u32 addr,
-+ const u8 *data, size_t len)
-+{
-+ u16 crc = 0, up_crc;
-+ size_t pos;
-+
-+ /* PHY expect addr in LE */
-+ addr = (__force u32)cpu_to_le32(addr);
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET);
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE3,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(addr));
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE4,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(addr));
-+
-+ /* We assume and enforce the size to be word aligned.
-+ * If a firmware that is not word aligned is found, please report upstream.
-+ */
-+ for (pos = 0; pos < len; pos += sizeof(u32)) {
-+ u32 word;
-+
-+ /* FW data is always stored in little-endian */
-+ word = get_unaligned((const u32 *)(data + pos));
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word));
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE6,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(word));
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE1,
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE |
-+ VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE);
-+
-+ /* calculate CRC as we load data to the mailbox.
-+ * We convert word to big-endian as PHY is BE and mailbox will
-+ * return a BE CRC.
-+ */
-+ word = (__force u32)cpu_to_be32(word);
-+ crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word));
-+ }
-+
-+ up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2);
-+ if (crc != up_crc) {
-+ phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n",
-+ crc, up_crc);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
-+ enum aqr_fw_src fw_src)
-+{
-+ u16 calculated_crc, read_crc, read_primary_offset;
-+ u32 iram_offset = 0, iram_size = 0;
-+ u32 dram_offset = 0, dram_size = 0;
-+ char version[VERSION_STRING_SIZE];
-+ u32 primary_offset = 0;
-+ int ret;
-+
-+ /* extract saved CRC at the end of the fw
-+ * CRC is saved in big-endian as PHY is BE
-+ */
-+ ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
-+ if (ret) {
-+ phydev_err(phydev, "bad firmware CRC in firmware\n");
-+ return ret;
-+ }
-+ calculated_crc = crc_ccitt_false(0, data, size - sizeof(u16));
-+ if (read_crc != calculated_crc) {
-+ phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n",
-+ read_crc, calculated_crc);
-+ return -EINVAL;
-+ }
-+
-+ /* Get the primary offset to extract DRAM and IRAM sections. */
-+ ret = aqr_fw_get_le16(data, PRIMARY_OFFSET_OFFSET, size, &read_primary_offset);
-+ if (ret) {
-+ phydev_err(phydev, "bad primary offset in firmware\n");
-+ return ret;
-+ }
-+ primary_offset = PRIMARY_OFFSET(read_primary_offset);
-+
-+ /* Find the DRAM and IRAM sections within the firmware file.
-+ * Make sure the fw_header is correctly in the firmware.
-+ */
-+ if (!aqr_fw_validate_get(size, primary_offset + HEADER_OFFSET,
-+ sizeof(struct aqr_fw_header))) {
-+ phydev_err(phydev, "bad fw_header in firmware\n");
-+ return -EINVAL;
-+ }
-+
-+ /* offset are in LE and values needs to be converted to cpu endian */
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, iram_offset),
-+ size, &iram_offset);
-+ if (ret) {
-+ phydev_err(phydev, "bad iram offset in firmware\n");
-+ return ret;
-+ }
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, iram_size),
-+ size, &iram_size);
-+ if (ret) {
-+ phydev_err(phydev, "invalid iram size in firmware\n");
-+ return ret;
-+ }
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, dram_offset),
-+ size, &dram_offset);
-+ if (ret) {
-+ phydev_err(phydev, "bad dram offset in firmware\n");
-+ return ret;
-+ }
-+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
-+ offsetof(struct aqr_fw_header, dram_size),
-+ size, &dram_size);
-+ if (ret) {
-+ phydev_err(phydev, "invalid dram size in firmware\n");
-+ return ret;
-+ }
-+
-+ /* Increment the offset with the primary offset.
-+ * Validate iram/dram offset and size.
-+ */
-+ iram_offset += primary_offset;
-+ if (iram_size % sizeof(u32)) {
-+ phydev_err(phydev, "iram size if not aligned to word size. Please report this upstream!\n");
-+ return -EINVAL;
-+ }
-+ if (!aqr_fw_validate_get(size, iram_offset, iram_size)) {
-+ phydev_err(phydev, "invalid iram offset for iram size\n");
-+ return -EINVAL;
-+ }
-+
-+ dram_offset += primary_offset;
-+ if (dram_size % sizeof(u32)) {
-+ phydev_err(phydev, "dram size if not aligned to word size. Please report this upstream!\n");
-+ return -EINVAL;
-+ }
-+ if (!aqr_fw_validate_get(size, dram_offset, dram_size)) {
-+ phydev_err(phydev, "invalid iram offset for iram size\n");
-+ return -EINVAL;
-+ }
-+
-+ phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n",
-+ primary_offset, iram_offset, iram_size, dram_offset, dram_size);
-+
-+ if (!aqr_fw_validate_get(size, dram_offset + VERSION_STRING_OFFSET,
-+ VERSION_STRING_SIZE)) {
-+ phydev_err(phydev, "invalid version in firmware\n");
-+ return -EINVAL;
-+ }
-+ strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET,
-+ VERSION_STRING_SIZE);
-+ if (version[0] == '\0') {
-+ phydev_err(phydev, "invalid version in firmware\n");
-+ return -EINVAL;
-+ }
-+ phydev_info(phydev, "loading firmware version '%s' from '%s'\n", version,
-+ aqr_fw_src_string[fw_src]);
-+
-+ /* stall the microcprocessor */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
-+
-+ phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n",
-+ DRAM_BASE_ADDR, dram_offset, dram_size);
-+ ret = aqr_fw_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset,
-+ dram_size);
-+ if (ret)
-+ return ret;
-+
-+ phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n",
-+ IRAM_BASE_ADDR, iram_offset, iram_size);
-+ ret = aqr_fw_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset,
-+ iram_size);
-+ if (ret)
-+ return ret;
-+
-+ /* make sure soft reset and low power mode are clear */
-+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC,
-+ VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER);
-+
-+ /* Release the microprocessor. UP_RESET must be held for 100 usec. */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL |
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD |
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST);
-+ usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2);
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
-+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
-+
-+ return 0;
-+}
-+
-+static int aqr_firmware_load_nvmem(struct phy_device *phydev)
-+{
-+ struct nvmem_cell *cell;
-+ size_t size;
-+ u8 *buf;
-+ int ret;
-+
-+ cell = nvmem_cell_get(&phydev->mdio.dev, "firmware");
-+ if (IS_ERR(cell))
-+ return PTR_ERR(cell);
-+
-+ buf = nvmem_cell_read(cell, &size);
-+ if (IS_ERR(buf)) {
-+ ret = PTR_ERR(buf);
-+ goto exit;
-+ }
-+
-+ ret = aqr_fw_boot(phydev, buf, size, AQR_FW_SRC_NVMEM);
-+ if (ret)
-+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
-+
-+ kfree(buf);
-+exit:
-+ nvmem_cell_put(cell);
-+
-+ return ret;
-+}
-+
-+static int aqr_firmware_load_fs(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ const struct firmware *fw;
-+ const char *fw_name;
-+ int ret;
-+
-+ ret = of_property_read_string(dev->of_node, "firmware-name",
-+ &fw_name);
-+ if (ret)
-+ return ret;
-+
-+ ret = request_firmware(&fw, fw_name, dev);
-+ if (ret) {
-+ phydev_err(phydev, "failed to find FW file %s (%d)\n",
-+ fw_name, ret);
-+ return ret;
-+ }
-+
-+ ret = aqr_fw_boot(phydev, fw->data, fw->size, AQR_FW_SRC_FS);
-+ if (ret)
-+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
-+
-+ release_firmware(fw);
-+
-+ return ret;
-+}
-+
-+int aqr_firmware_load(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Check if the firmware is not already loaded by pooling
-+ * the current version returned by the PHY. If 0 is returned,
-+ * no firmware is loaded.
-+ */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
-+ if (ret > 0)
-+ goto exit;
-+
-+ ret = aqr_firmware_load_nvmem(phydev);
-+ if (!ret)
-+ goto exit;
-+
-+ ret = aqr_firmware_load_fs(phydev);
-+ if (ret)
-+ return ret;
-+
-+exit:
-+ return 0;
-+}
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -656,11 +656,17 @@ static int aqr107_resume(struct phy_devi
-
- static int aqr107_probe(struct phy_device *phydev)
- {
-+ int ret;
-+
- phydev->priv = devm_kzalloc(&phydev->mdio.dev,
- sizeof(struct aqr107_priv), GFP_KERNEL);
- if (!phydev->priv)
- return -ENOMEM;
-
-+ ret = aqr_firmware_load(phydev);
-+ if (ret)
-+ return ret;
-+
- return aqr_hwmon_probe(phydev);
- }
-
diff --git a/target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch b/target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch
deleted file mode 100644
index ff186742ba..0000000000
--- a/target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch
+++ /dev/null
@@ -1,326 +0,0 @@
-From 4e4aafcddbbfcdd6eed5780e190fcbfac8b4685a Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 9 Jan 2023 16:30:41 +0100
-Subject: [PATCH] net: mdio: Add dedicated C45 API to MDIO bus drivers
-
-Currently C22 and C45 transactions are mixed over a combined API calls
-which make use of a special bit in the reg address to indicate if a
-C45 transaction should be performed. This makes it impossible to know
-if the bus driver actually supports C45. Additionally, many C22 only
-drivers don't return -EOPNOTSUPP when asked to perform a C45
-transaction, they mistaking perform a C22 transaction.
-
-This is the first step to cleanly separate C22 from C45. To maintain
-backwards compatibility until all drivers which are capable of
-performing C45 are converted to this new API, the helper functions
-will fall back to the older API if the new API is not
-supported. Eventually this fallback will be removed.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mdio_bus.c | 189 +++++++++++++++++++++++++++++++++++++
- include/linux/mdio.h | 39 ++++----
- include/linux/phy.h | 5 +
- 3 files changed, 214 insertions(+), 19 deletions(-)
-
---- a/drivers/net/phy/mdio_bus.c
-+++ b/drivers/net/phy/mdio_bus.c
-@@ -832,6 +832,100 @@ int __mdiobus_modify_changed(struct mii_
- EXPORT_SYMBOL_GPL(__mdiobus_modify_changed);
-
- /**
-+ * __mdiobus_c45_read - Unlocked version of the mdiobus_c45_read function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @devad: device address to read
-+ * @regnum: register number to read
-+ *
-+ * Read a MDIO bus register. Caller must hold the mdio bus lock.
-+ *
-+ * NOTE: MUST NOT be called from interrupt context.
-+ */
-+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
-+{
-+ int retval;
-+
-+ lockdep_assert_held_once(&bus->mdio_lock);
-+
-+ if (bus->read_c45)
-+ retval = bus->read_c45(bus, addr, devad, regnum);
-+ else
-+ retval = bus->read(bus, addr, mdiobus_c45_addr(devad, regnum));
-+
-+ trace_mdio_access(bus, 1, addr, regnum, retval, retval);
-+ mdiobus_stats_acct(&bus->stats[addr], true, retval);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(__mdiobus_c45_read);
-+
-+/**
-+ * __mdiobus_c45_write - Unlocked version of the mdiobus_write function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @devad: device address to read
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * Write a MDIO bus register. Caller must hold the mdio bus lock.
-+ *
-+ * NOTE: MUST NOT be called from interrupt context.
-+ */
-+int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
-+ u16 val)
-+{
-+ int err;
-+
-+ lockdep_assert_held_once(&bus->mdio_lock);
-+
-+ if (bus->write_c45)
-+ err = bus->write_c45(bus, addr, devad, regnum, val);
-+ else
-+ err = bus->write(bus, addr, mdiobus_c45_addr(devad, regnum),
-+ val);
-+
-+ trace_mdio_access(bus, 0, addr, regnum, val, err);
-+ mdiobus_stats_acct(&bus->stats[addr], false, err);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL(__mdiobus_c45_write);
-+
-+/**
-+ * __mdiobus_c45_modify_changed - Unlocked version of the mdiobus_modify function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @devad: device address to read
-+ * @regnum: register number to modify
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * Read, modify, and if any change, write the register value back to the
-+ * device. Any error returns a negative number.
-+ *
-+ * NOTE: MUST NOT be called from interrupt context.
-+ */
-+static int __mdiobus_c45_modify_changed(struct mii_bus *bus, int addr,
-+ int devad, u32 regnum, u16 mask,
-+ u16 set)
-+{
-+ int new, ret;
-+
-+ ret = __mdiobus_c45_read(bus, addr, devad, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ new = (ret & ~mask) | set;
-+ if (new == ret)
-+ return 0;
-+
-+ ret = __mdiobus_c45_write(bus, addr, devad, regnum, new);
-+
-+ return ret < 0 ? ret : 1;
-+}
-+
-+/**
- * mdiobus_read_nested - Nested version of the mdiobus_read function
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -879,6 +973,29 @@ int mdiobus_read(struct mii_bus *bus, in
- EXPORT_SYMBOL(mdiobus_read);
-
- /**
-+ * mdiobus_c45_read - Convenience function for reading a given MII mgmt register
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @devad: device address to read
-+ * @regnum: register number to read
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
-+{
-+ int retval;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ retval = __mdiobus_c45_read(bus, addr, devad, regnum);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(mdiobus_c45_read);
-+
-+/**
- * mdiobus_write_nested - Nested version of the mdiobus_write function
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -928,6 +1045,31 @@ int mdiobus_write(struct mii_bus *bus, i
- EXPORT_SYMBOL(mdiobus_write);
-
- /**
-+ * mdiobus_c45_write - Convenience function for writing a given MII mgmt register
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @devad: device address to read
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
-+ u16 val)
-+{
-+ int err;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ err = __mdiobus_c45_write(bus, addr, devad, regnum, val);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL(mdiobus_c45_write);
-+
-+/**
- * mdiobus_modify - Convenience function for modifying a given mdio device
- * register
- * @bus: the mii_bus struct
-@@ -949,6 +1091,30 @@ int mdiobus_modify(struct mii_bus *bus,
- EXPORT_SYMBOL_GPL(mdiobus_modify);
-
- /**
-+ * mdiobus_c45_modify - Convenience function for modifying a given mdio device
-+ * register
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @devad: device address to read
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ */
-+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
-+ u16 mask, u16 set)
-+{
-+ int err;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum,
-+ mask, set);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return err < 0 ? err : 0;
-+}
-+EXPORT_SYMBOL_GPL(mdiobus_c45_modify);
-+
-+/**
- * mdiobus_modify_changed - Convenience function for modifying a given mdio
- * device register and returning if it changed
- * @bus: the mii_bus struct
-@@ -971,6 +1137,29 @@ int mdiobus_modify_changed(struct mii_bu
- EXPORT_SYMBOL_GPL(mdiobus_modify_changed);
-
- /**
-+ * mdiobus_c45_modify_changed - Convenience function for modifying a given mdio
-+ * device register and returning if it changed
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @devad: device address to read
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ */
-+int mdiobus_c45_modify_changed(struct mii_bus *bus, int devad, int addr,
-+ u32 regnum, u16 mask, u16 set)
-+{
-+ int err;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum, mask, set);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed);
-+
-+/**
- * mdio_bus_match - determine if given MDIO driver supports the given
- * MDIO device
- * @dev: target MDIO device
---- a/include/linux/mdio.h
-+++ b/include/linux/mdio.h
-@@ -423,6 +423,17 @@ int mdiobus_modify(struct mii_bus *bus,
- u16 set);
- int mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
- u16 mask, u16 set);
-+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum);
-+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum);
-+int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
-+ u16 val);
-+int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
-+ u16 val);
-+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
-+ u16 mask, u16 set);
-+
-+int mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, int devad,
-+ u32 regnum, u16 mask, u16 set);
-
- static inline int mdiodev_read(struct mdio_device *mdiodev, u32 regnum)
- {
-@@ -463,29 +474,19 @@ static inline u16 mdiobus_c45_devad(u32
- return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
- }
-
--static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
-- u16 regnum)
--{
-- return __mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
--}
--
--static inline int __mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
-- u16 regnum, u16 val)
--{
-- return __mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum),
-- val);
--}
--
--static inline int mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
-- u16 regnum)
-+static inline int mdiodev_c45_modify(struct mdio_device *mdiodev, int devad,
-+ u32 regnum, u16 mask, u16 set)
- {
-- return mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
-+ return mdiobus_c45_modify(mdiodev->bus, mdiodev->addr, devad, regnum,
-+ mask, set);
- }
-
--static inline int mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
-- u16 regnum, u16 val)
-+static inline int mdiodev_c45_modify_changed(struct mdio_device *mdiodev,
-+ int devad, u32 regnum, u16 mask,
-+ u16 set)
- {
-- return mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum), val);
-+ return mdiobus_c45_modify_changed(mdiodev->bus, mdiodev->addr, devad,
-+ regnum, mask, set);
- }
-
- int mdiobus_register_device(struct mdio_device *mdiodev);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -364,6 +364,11 @@ struct mii_bus {
- int (*read)(struct mii_bus *bus, int addr, int regnum);
- /** @write: Perform a write transfer on the bus */
- int (*write)(struct mii_bus *bus, int addr, int regnum, u16 val);
-+ /** @read_c45: Perform a C45 read transfer on the bus */
-+ int (*read_c45)(struct mii_bus *bus, int addr, int devnum, int regnum);
-+ /** @write_c45: Perform a C45 write transfer on the bus */
-+ int (*write_c45)(struct mii_bus *bus, int addr, int devnum,
-+ int regnum, u16 val);
- /** @reset: Perform a reset of the bus */
- int (*reset)(struct mii_bus *bus);
-
diff --git a/target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch b/target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch
deleted file mode 100644
index 80210e6da1..0000000000
--- a/target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 9a0e95e34e9c0a713ddfd48c3a88a20d2bdfd514 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Fri, 11 Aug 2023 13:10:07 +0200
-Subject: [PATCH] net: phy: Introduce PSGMII PHY interface mode
-
-The PSGMII interface is similar to QSGMII. The main difference
-is that the PSGMII interface combines five SGMII lines into a
-single link while in QSGMII only four lines are combined.
-
-Similarly to the QSGMII, this interface mode might also needs
-special handling within the MAC driver.
-
-It is commonly used by Qualcomm with their QCA807x PHY series and
-modern WiSoC-s.
-
-Add definitions for the PHY layer to allow to express this type
-of connection between the MAC and PHY.
-
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Signed-off-by: Robert Marko <robert.marko@sartura.hr>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/networking/phy.rst | 4 ++++
- drivers/net/phy/phy-core.c | 2 ++
- drivers/net/phy/phylink.c | 3 +++
- include/linux/phy.h | 4 ++++
- 4 files changed, 13 insertions(+)
-
---- a/Documentation/networking/phy.rst
-+++ b/Documentation/networking/phy.rst
-@@ -323,6 +323,10 @@ Some of the interface modes are describe
- contrast with the 1000BASE-X phy mode used for Clause 38 and 39 PMDs, this
- interface mode has different autonegotiation and only supports full duplex.
-
-+``PHY_INTERFACE_MODE_PSGMII``
-+ This is the Penta SGMII mode, it is similar to QSGMII but it combines 5
-+ SGMII lines into a single link compared to 4 on QSGMII.
-+
- Pause frames / flow control
- ===========================
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -140,6 +140,8 @@ int phy_interface_num_ports(phy_interfac
- case PHY_INTERFACE_MODE_QSGMII:
- case PHY_INTERFACE_MODE_QUSGMII:
- return 4;
-+ case PHY_INTERFACE_MODE_PSGMII:
-+ return 5;
- case PHY_INTERFACE_MODE_MAX:
- WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode");
- return 0;
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -187,6 +187,7 @@ static int phylink_interface_max_speed(p
- case PHY_INTERFACE_MODE_RGMII_RXID:
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_PSGMII:
- case PHY_INTERFACE_MODE_QSGMII:
- case PHY_INTERFACE_MODE_QUSGMII:
- case PHY_INTERFACE_MODE_SGMII:
-@@ -448,6 +449,7 @@ unsigned long phylink_get_capabilities(p
- case PHY_INTERFACE_MODE_RGMII_RXID:
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_PSGMII:
- case PHY_INTERFACE_MODE_QSGMII:
- case PHY_INTERFACE_MODE_QUSGMII:
- case PHY_INTERFACE_MODE_SGMII:
-@@ -814,6 +816,7 @@ static int phylink_parse_mode(struct phy
-
- switch (pl->link_config.interface) {
- case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_PSGMII:
- case PHY_INTERFACE_MODE_QSGMII:
- case PHY_INTERFACE_MODE_QUSGMII:
- case PHY_INTERFACE_MODE_RGMII:
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -103,6 +103,7 @@ extern const int phy_10gbit_features_arr
- * @PHY_INTERFACE_MODE_XGMII: 10 gigabit media-independent interface
- * @PHY_INTERFACE_MODE_XLGMII:40 gigabit media-independent interface
- * @PHY_INTERFACE_MODE_MOCA: Multimedia over Coax
-+ * @PHY_INTERFACE_MODE_PSGMII: Penta SGMII
- * @PHY_INTERFACE_MODE_QSGMII: Quad SGMII
- * @PHY_INTERFACE_MODE_TRGMII: Turbo RGMII
- * @PHY_INTERFACE_MODE_100BASEX: 100 BaseX
-@@ -140,6 +141,7 @@ typedef enum {
- PHY_INTERFACE_MODE_XGMII,
- PHY_INTERFACE_MODE_XLGMII,
- PHY_INTERFACE_MODE_MOCA,
-+ PHY_INTERFACE_MODE_PSGMII,
- PHY_INTERFACE_MODE_QSGMII,
- PHY_INTERFACE_MODE_TRGMII,
- PHY_INTERFACE_MODE_100BASEX,
-@@ -247,6 +249,8 @@ static inline const char *phy_modes(phy_
- return "xlgmii";
- case PHY_INTERFACE_MODE_MOCA:
- return "moca";
-+ case PHY_INTERFACE_MODE_PSGMII:
-+ return "psgmii";
- case PHY_INTERFACE_MODE_QSGMII:
- return "qsgmii";
- case PHY_INTERFACE_MODE_TRGMII:
diff --git a/target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch b/target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch
deleted file mode 100644
index 7cacb71b18..0000000000
--- a/target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From a593a2fcfdfb92cfd0ffc54bc81b07e6bfaaaf46 Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Thu, 16 Mar 2023 14:08:26 +0200
-Subject: [PATCH] net: phy: at803x: Replace of_gpio.h with what indeed is used
-
-of_gpio.h in this driver is solely used as a proxy to other headers.
-This is incorrect usage of the of_gpio.h. Replace it .h with what
-indeed is used in the code.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -13,12 +13,11 @@
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
- #include <linux/ethtool_netlink.h>
--#include <linux/of_gpio.h>
- #include <linux/bitfield.h>
--#include <linux/gpio/consumer.h>
- #include <linux/regulator/of_regulator.h>
- #include <linux/regulator/driver.h>
- #include <linux/regulator/consumer.h>
-+#include <linux/of.h>
- #include <linux/phylink.h>
- #include <linux/sfp.h>
- #include <dt-bindings/net/qca-ar803x.h>
diff --git a/target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch b/target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch
deleted file mode 100644
index dab4928960..0000000000
--- a/target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 8b8bc13d89a7d23d14b0e041c73f037c9db997b1 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 16 Jul 2023 16:49:19 +0800
-Subject: [PATCH 1/6] net: phy: at803x: support qca8081
- genphy_c45_pma_read_abilities
-
-qca8081 PHY supports to use genphy_c45_pma_read_abilities for
-getting the PHY features supported except for the autoneg ability
-
-but autoneg ability exists in MDIO_STAT1 instead of MMD7.1, add it
-manually after calling genphy_c45_pma_read_abilities.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 28 ++++++++++++++++++----------
- 1 file changed, 18 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -902,15 +902,6 @@ static int at803x_get_features(struct ph
- if (err)
- return err;
-
-- if (phydev->drv->phy_id == QCA8081_PHY_ID) {
-- err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE);
-- if (err < 0)
-- return err;
--
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported,
-- err & MDIO_PMA_NG_EXTABLE_2_5GBT);
-- }
--
- if (phydev->drv->phy_id != ATH8031_PHY_ID)
- return 0;
-
-@@ -1996,6 +1987,23 @@ static int qca808x_cable_test_get_status
- return 0;
- }
-
-+static int qca808x_get_features(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = genphy_c45_pma_read_abilities(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* The autoneg ability is not existed in bit3 of MMD7.1,
-+ * but it is supported by qca808x PHY, so we add it here
-+ * manually.
-+ */
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
-+
-+ return 0;
-+}
-+
- static struct phy_driver at803x_driver[] = {
- {
- /* Qualcomm Atheros AR8035 */
-@@ -2163,7 +2171,7 @@ static struct phy_driver at803x_driver[]
- .set_tunable = at803x_set_tunable,
- .set_wol = at803x_set_wol,
- .get_wol = at803x_get_wol,
-- .get_features = at803x_get_features,
-+ .get_features = qca808x_get_features,
- .config_aneg = at803x_config_aneg,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
diff --git a/target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch b/target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch
deleted file mode 100644
index 28874068ce..0000000000
--- a/target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From f3db55ae860a82e1224a909072783ef850e5d228 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 16 Jul 2023 16:49:20 +0800
-Subject: [PATCH 2/6] net: phy: at803x: merge qca8081 slave seed function
-
-merge the seed enablement and seed value configuration into
-one function, since the random seed value is needed to be
-configured when the seed is enabled.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 29 +++++++++--------------------
- 1 file changed, 9 insertions(+), 20 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1730,24 +1730,19 @@ static int qca808x_phy_fast_retrain_conf
- return 0;
- }
-
--static int qca808x_phy_ms_random_seed_set(struct phy_device *phydev)
--{
-- u16 seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
--
-- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-- QCA808X_MASTER_SLAVE_SEED_CFG,
-- FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value));
--}
--
- static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
- {
-- u16 seed_enable = 0;
-+ u16 seed_value;
-
-- if (enable)
-- seed_enable = QCA808X_MASTER_SLAVE_SEED_ENABLE;
-+ if (!enable)
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-+ QCA808X_MASTER_SLAVE_SEED_ENABLE, 0);
-
-+ seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-- QCA808X_MASTER_SLAVE_SEED_ENABLE, seed_enable);
-+ QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE,
-+ FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) |
-+ QCA808X_MASTER_SLAVE_SEED_ENABLE);
- }
-
- static int qca808x_config_init(struct phy_device *phydev)
-@@ -1771,12 +1766,7 @@ static int qca808x_config_init(struct ph
- if (ret)
- return ret;
-
-- /* Configure lower ramdom seed to make phy linked as slave mode */
-- ret = qca808x_phy_ms_random_seed_set(phydev);
-- if (ret)
-- return ret;
--
-- /* Enable seed */
-+ /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
- ret = qca808x_phy_ms_seed_enable(phydev, true);
- if (ret)
- return ret;
-@@ -1821,7 +1811,6 @@ static int qca808x_read_status(struct ph
- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
- qca808x_phy_ms_seed_enable(phydev, false);
- } else {
-- qca808x_phy_ms_random_seed_set(phydev);
- qca808x_phy_ms_seed_enable(phydev, true);
- }
- }
diff --git a/target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch b/target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch
deleted file mode 100644
index b91d2cab30..0000000000
--- a/target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 7cc3209558002d95c0d45a1276ba4f5f741eec42 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 16 Jul 2023 16:49:21 +0800
-Subject: [PATCH 3/6] net: phy: at803x: enable qca8081 slave seed conditionally
-
-qca8081 is the single port PHY, the slave prefer mode is used
-by default.
-
-if the phy master perfer mode is configured, the slave seed
-configuration should not be enabled, since the slave seed
-enablement is for making PHY linked as slave mode easily.
-
-disable slave seed if the master mode is preferred.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 25 ++++++++++++++++++++-----
- 1 file changed, 20 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1745,6 +1745,12 @@ static int qca808x_phy_ms_seed_enable(st
- QCA808X_MASTER_SLAVE_SEED_ENABLE);
- }
-
-+static bool qca808x_is_prefer_master(struct phy_device *phydev)
-+{
-+ return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) ||
-+ (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
-+}
-+
- static int qca808x_config_init(struct phy_device *phydev)
- {
- int ret;
-@@ -1766,11 +1772,17 @@ static int qca808x_config_init(struct ph
- if (ret)
- return ret;
-
-- /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
-- ret = qca808x_phy_ms_seed_enable(phydev, true);
-- if (ret)
-+ ret = genphy_read_master_slave(phydev);
-+ if (ret < 0)
- return ret;
-
-+ if (!qca808x_is_prefer_master(phydev)) {
-+ /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
-+ ret = qca808x_phy_ms_seed_enable(phydev, true);
-+ if (ret)
-+ return ret;
-+ }
-+
- /* Configure adc threshold as 100mv for the link 10M */
- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
- QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
-@@ -1802,13 +1814,16 @@ static int qca808x_read_status(struct ph
- phydev->interface = PHY_INTERFACE_MODE_SGMII;
- } else {
- /* generate seed as a lower random value to make PHY linked as SLAVE easily,
-- * except for master/slave configuration fault detected.
-+ * except for master/slave configuration fault detected or the master mode
-+ * preferred.
-+ *
- * the reason for not putting this code into the function link_change_notify is
- * the corner case where the link partner is also the qca8081 PHY and the seed
- * value is configured as the same value, the link can't be up and no link change
- * occurs.
- */
-- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
-+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-+ qca808x_is_prefer_master(phydev)) {
- qca808x_phy_ms_seed_enable(phydev, false);
- } else {
- qca808x_phy_ms_seed_enable(phydev, true);
diff --git a/target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch b/target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch
deleted file mode 100644
index b8db89d853..0000000000
--- a/target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From fea7cfb83d1a2782e39cd101dd44ed2548539de5 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 16 Jul 2023 16:49:22 +0800
-Subject: [PATCH 4/6] net: phy: at803x: support qca8081 1G chip type
-
-The qca8081 1G chip version does not support 2.5 capability, which
-is distinguished from qca8081 2.5G chip according to the bit0 of
-register mmd7.0x901d, the 1G version chip also has the same PHY ID
-as the normal qca8081 2.5G chip.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -272,6 +272,10 @@
- #define QCA808X_CDT_STATUS_STAT_OPEN 2
- #define QCA808X_CDT_STATUS_STAT_SHORT 3
-
-+/* QCA808X 1G chip type */
-+#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
-+#define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
-+
- MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-@@ -2005,6 +2009,17 @@ static int qca808x_get_features(struct p
- */
- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
-
-+ /* As for the qca8081 1G version chip, the 2500baseT ability is also
-+ * existed in the bit0 of MMD1.21, we need to remove it manually if
-+ * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
-+ */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (QCA808X_PHY_CHIP_TYPE_1G & ret)
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch b/target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch
deleted file mode 100644
index b54a86e5f5..0000000000
--- a/target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From df9401ff3e6eeaa42bfb06761967f1b71f5afce7 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 16 Jul 2023 16:49:23 +0800
-Subject: [PATCH 5/6] net: phy: at803x: remove qca8081 1G fast retrain and
- slave seed config
-
-The fast retrain and slave seed configs are only applicable when the 2.5G
-ability is supported.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 50 +++++++++++++++++++++++++---------------
- 1 file changed, 32 insertions(+), 18 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1755,6 +1755,11 @@ static bool qca808x_is_prefer_master(str
- (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
- }
-
-+static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
-+{
-+ return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-+}
-+
- static int qca808x_config_init(struct phy_device *phydev)
- {
- int ret;
-@@ -1771,20 +1776,24 @@ static int qca808x_config_init(struct ph
- if (ret)
- return ret;
-
-- /* Config the fast retrain for the link 2500M */
-- ret = qca808x_phy_fast_retrain_config(phydev);
-- if (ret)
-- return ret;
--
-- ret = genphy_read_master_slave(phydev);
-- if (ret < 0)
-- return ret;
--
-- if (!qca808x_is_prefer_master(phydev)) {
-- /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
-- ret = qca808x_phy_ms_seed_enable(phydev, true);
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-+ /* Config the fast retrain for the link 2500M */
-+ ret = qca808x_phy_fast_retrain_config(phydev);
- if (ret)
- return ret;
-+
-+ ret = genphy_read_master_slave(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!qca808x_is_prefer_master(phydev)) {
-+ /* Enable seed and configure lower ramdom seed to make phy
-+ * linked as slave mode.
-+ */
-+ ret = qca808x_phy_ms_seed_enable(phydev, true);
-+ if (ret)
-+ return ret;
-+ }
- }
-
- /* Configure adc threshold as 100mv for the link 10M */
-@@ -1826,11 +1835,13 @@ static int qca808x_read_status(struct ph
- * value is configured as the same value, the link can't be up and no link change
- * occurs.
- */
-- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-- qca808x_is_prefer_master(phydev)) {
-- qca808x_phy_ms_seed_enable(phydev, false);
-- } else {
-- qca808x_phy_ms_seed_enable(phydev, true);
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-+ qca808x_is_prefer_master(phydev)) {
-+ qca808x_phy_ms_seed_enable(phydev, false);
-+ } else {
-+ qca808x_phy_ms_seed_enable(phydev, true);
-+ }
- }
- }
-
-@@ -1845,7 +1856,10 @@ static int qca808x_soft_reset(struct phy
- if (ret < 0)
- return ret;
-
-- return qca808x_phy_ms_seed_enable(phydev, true);
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev))
-+ ret = qca808x_phy_ms_seed_enable(phydev, true);
-+
-+ return ret;
- }
-
- static bool qca808x_cdt_fault_length_valid(int cdt_code)
diff --git a/target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch b/target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch
deleted file mode 100644
index e382cf7876..0000000000
--- a/target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 723970affdd8766fa0d91cd34bf2ffc861538b5f Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 16 Jul 2023 16:49:24 +0800
-Subject: [PATCH 6/6] net: phy: at803x: add qca8081 fifo reset on the link
- changed
-
-The qca8081 sgmii fifo needs to be reset on link down and
-released on the link up in case of any abnormal issue
-such as the packet blocked on the PHY.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -276,6 +276,9 @@
- #define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
- #define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
-
-+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072
-+#define QCA8081_PHY_FIFO_RSTN BIT(11)
-+
- MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-@@ -2037,6 +2040,16 @@ static int qca808x_get_features(struct p
- return 0;
- }
-
-+static void qca808x_link_change_notify(struct phy_device *phydev)
-+{
-+ /* Assert interface sgmii fifo on link down, deassert it on link up,
-+ * the interface device address is always phy address added by 1.
-+ */
-+ mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
-+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
-+ QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
-+}
-+
- static struct phy_driver at803x_driver[] = {
- {
- /* Qualcomm Atheros AR8035 */
-@@ -2213,6 +2226,7 @@ static struct phy_driver at803x_driver[]
- .soft_reset = qca808x_soft_reset,
- .cable_test_start = qca808x_cable_test_start,
- .cable_test_get_status = qca808x_cable_test_get_status,
-+ .link_change_notify = qca808x_link_change_notify,
- }, };
-
- module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch b/target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch
deleted file mode 100644
index eb9172b1cc..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 6a3b8c573b5a152a6aa7a0b54c5e18b84c6ba6f5 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:49 +0100
-Subject: [PATCH 02/13] net: phy: at803x: move disable WOL to specific at8031
- probe
-
-Move the WOL disable call to specific at8031 probe to make at803x_probe
-more generic and drop extra check for PHY ID.
-
-Keep the same previous behaviour by first calling at803x_probe and then
-disabling WOL.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 27 +++++++++++++++++----------
- 1 file changed, 17 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -886,15 +886,6 @@ static int at803x_probe(struct phy_devic
- priv->is_fiber = true;
- break;
- }
--
-- /* Disable WoL in 1588 register which is enabled
-- * by default
-- */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-- AT803X_PHY_MMD3_WOL_CTRL,
-- AT803X_WOL_EN, 0);
-- if (ret)
-- return ret;
- }
-
- return 0;
-@@ -1591,6 +1582,22 @@ static int at803x_cable_test_start(struc
- return 0;
- }
-
-+static int at8031_probe(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = at803x_probe(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* Disable WoL in 1588 register which is enabled
-+ * by default
-+ */
-+ return phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+ AT803X_PHY_MMD3_WOL_CTRL,
-+ AT803X_WOL_EN, 0);
-+}
-+
- static int qca83xx_config_init(struct phy_device *phydev)
- {
- u8 switch_revision;
-@@ -2092,7 +2099,7 @@ static struct phy_driver at803x_driver[]
- PHY_ID_MATCH_EXACT(ATH8031_PHY_ID),
- .name = "Qualcomm Atheros AR8031/AR8033",
- .flags = PHY_POLL_CABLE_TEST,
-- .probe = at803x_probe,
-+ .probe = at8031_probe,
- .config_init = at803x_config_init,
- .config_aneg = at803x_config_aneg,
- .soft_reset = genphy_soft_reset,
diff --git a/target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch b/target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch
deleted file mode 100644
index 5a9d1764f1..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 07b1ad83b9ed6db1735ba10baf67b7a565ac0cef Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:50 +0100
-Subject: [PATCH 03/13] net: phy: at803x: raname hw_stats functions to qca83xx
- specific name
-
-The function and the struct related to hw_stats were specific to qca83xx
-PHY but were called following the convention in the driver of calling
-everything with at803x prefix.
-
-To better organize the code, rename these function a more specific name
-to better describe that they are specific to 83xx PHY family.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 44 ++++++++++++++++++++--------------------
- 1 file changed, 22 insertions(+), 22 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -295,7 +295,7 @@ struct at803x_hw_stat {
- enum stat_access_type access_type;
- };
-
--static struct at803x_hw_stat at803x_hw_stats[] = {
-+static struct at803x_hw_stat qca83xx_hw_stats[] = {
- { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
- { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
- { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
-@@ -311,7 +311,7 @@ struct at803x_priv {
- bool is_1000basex;
- struct regulator_dev *vddio_rdev;
- struct regulator_dev *vddh_rdev;
-- u64 stats[ARRAY_SIZE(at803x_hw_stats)];
-+ u64 stats[ARRAY_SIZE(qca83xx_hw_stats)];
- };
-
- struct at803x_context {
-@@ -529,24 +529,24 @@ static void at803x_get_wol(struct phy_de
- wol->wolopts |= WAKE_MAGIC;
- }
-
--static int at803x_get_sset_count(struct phy_device *phydev)
-+static int qca83xx_get_sset_count(struct phy_device *phydev)
- {
-- return ARRAY_SIZE(at803x_hw_stats);
-+ return ARRAY_SIZE(qca83xx_hw_stats);
- }
-
--static void at803x_get_strings(struct phy_device *phydev, u8 *data)
-+static void qca83xx_get_strings(struct phy_device *phydev, u8 *data)
- {
- int i;
-
-- for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) {
-+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) {
- strscpy(data + i * ETH_GSTRING_LEN,
-- at803x_hw_stats[i].string, ETH_GSTRING_LEN);
-+ qca83xx_hw_stats[i].string, ETH_GSTRING_LEN);
- }
- }
-
--static u64 at803x_get_stat(struct phy_device *phydev, int i)
-+static u64 qca83xx_get_stat(struct phy_device *phydev, int i)
- {
-- struct at803x_hw_stat stat = at803x_hw_stats[i];
-+ struct at803x_hw_stat stat = qca83xx_hw_stats[i];
- struct at803x_priv *priv = phydev->priv;
- int val;
- u64 ret;
-@@ -567,13 +567,13 @@ static u64 at803x_get_stat(struct phy_de
- return ret;
- }
-
--static void at803x_get_stats(struct phy_device *phydev,
-- struct ethtool_stats *stats, u64 *data)
-+static void qca83xx_get_stats(struct phy_device *phydev,
-+ struct ethtool_stats *stats, u64 *data)
- {
- int i;
-
-- for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++)
-- data[i] = at803x_get_stat(phydev, i);
-+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++)
-+ data[i] = qca83xx_get_stat(phydev, i);
- }
-
- static int at803x_suspend(struct phy_device *phydev)
-@@ -2175,9 +2175,9 @@ static struct phy_driver at803x_driver[]
- .flags = PHY_IS_INTERNAL,
- .config_init = qca83xx_config_init,
- .soft_reset = genphy_soft_reset,
-- .get_sset_count = at803x_get_sset_count,
-- .get_strings = at803x_get_strings,
-- .get_stats = at803x_get_stats,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
- .suspend = qca83xx_suspend,
- .resume = qca83xx_resume,
- }, {
-@@ -2191,9 +2191,9 @@ static struct phy_driver at803x_driver[]
- .flags = PHY_IS_INTERNAL,
- .config_init = qca83xx_config_init,
- .soft_reset = genphy_soft_reset,
-- .get_sset_count = at803x_get_sset_count,
-- .get_strings = at803x_get_strings,
-- .get_stats = at803x_get_stats,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
- .suspend = qca83xx_suspend,
- .resume = qca83xx_resume,
- }, {
-@@ -2207,9 +2207,9 @@ static struct phy_driver at803x_driver[]
- .flags = PHY_IS_INTERNAL,
- .config_init = qca83xx_config_init,
- .soft_reset = genphy_soft_reset,
-- .get_sset_count = at803x_get_sset_count,
-- .get_strings = at803x_get_strings,
-- .get_stats = at803x_get_stats,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
- .suspend = qca83xx_suspend,
- .resume = qca83xx_resume,
- }, {
diff --git a/target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch b/target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch
deleted file mode 100644
index f09142c5ed..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From d43cff3f82336c0bd965ea552232d9f4ddac71a6 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:51 +0100
-Subject: [PATCH 04/13] net: phy: at803x: move qca83xx specific check in
- dedicated functions
-
-Rework qca83xx specific check to dedicated function to tidy things up
-and drop useless phy_id check.
-
-Also drop an useless link_change_notify for QCA8337 as it did nothing an
-returned early.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 68 ++++++++++++++++++++++------------------
- 1 file changed, 37 insertions(+), 31 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1623,27 +1623,26 @@ static int qca83xx_config_init(struct ph
- break;
- }
-
-+ /* Following original QCA sourcecode set port to prefer master */
-+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
-+
-+ return 0;
-+}
-+
-+static int qca8327_config_init(struct phy_device *phydev)
-+{
- /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
- * Disable on init and enable only with 100m speed following
- * qca original source code.
- */
-- if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
-- phydev->drv->phy_id == QCA8327_B_PHY_ID)
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
-
-- /* Following original QCA sourcecode set port to prefer master */
-- phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
--
-- return 0;
-+ return qca83xx_config_init(phydev);
- }
-
- static void qca83xx_link_change_notify(struct phy_device *phydev)
- {
-- /* QCA8337 doesn't require DAC Amplitude adjustement */
-- if (phydev->drv->phy_id == QCA8337_PHY_ID)
-- return;
--
- /* Set DAC Amplitude adjustment to +6% for 100m on link running */
- if (phydev->state == PHY_RUNNING) {
- if (phydev->speed == SPEED_100)
-@@ -1686,19 +1685,6 @@ static int qca83xx_resume(struct phy_dev
-
- static int qca83xx_suspend(struct phy_device *phydev)
- {
-- u16 mask = 0;
--
-- /* Only QCA8337 support actual suspend.
-- * QCA8327 cause port unreliability when phy suspend
-- * is set.
-- */
-- if (phydev->drv->phy_id == QCA8337_PHY_ID) {
-- genphy_suspend(phydev);
-- } else {
-- mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-- phy_modify(phydev, MII_BMCR, mask, 0);
-- }
--
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
- AT803X_DEBUG_GATE_CLK_IN1000, 0);
-
-@@ -1709,6 +1695,27 @@ static int qca83xx_suspend(struct phy_de
- return 0;
- }
-
-+static int qca8337_suspend(struct phy_device *phydev)
-+{
-+ /* Only QCA8337 support actual suspend. */
-+ genphy_suspend(phydev);
-+
-+ return qca83xx_suspend(phydev);
-+}
-+
-+static int qca8327_suspend(struct phy_device *phydev)
-+{
-+ u16 mask = 0;
-+
-+ /* QCA8327 cause port unreliability when phy suspend
-+ * is set.
-+ */
-+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-+ phy_modify(phydev, MII_BMCR, mask, 0);
-+
-+ return qca83xx_suspend(phydev);
-+}
-+
- static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
- {
- int ret;
-@@ -2170,7 +2177,6 @@ static struct phy_driver at803x_driver[]
- .phy_id_mask = QCA8K_PHY_ID_MASK,
- .name = "Qualcomm Atheros 8337 internal PHY",
- /* PHY_GBIT_FEATURES */
-- .link_change_notify = qca83xx_link_change_notify,
- .probe = at803x_probe,
- .flags = PHY_IS_INTERNAL,
- .config_init = qca83xx_config_init,
-@@ -2178,7 +2184,7 @@ static struct phy_driver at803x_driver[]
- .get_sset_count = qca83xx_get_sset_count,
- .get_strings = qca83xx_get_strings,
- .get_stats = qca83xx_get_stats,
-- .suspend = qca83xx_suspend,
-+ .suspend = qca8337_suspend,
- .resume = qca83xx_resume,
- }, {
- /* QCA8327-A from switch QCA8327-AL1A */
-@@ -2189,12 +2195,12 @@ static struct phy_driver at803x_driver[]
- .link_change_notify = qca83xx_link_change_notify,
- .probe = at803x_probe,
- .flags = PHY_IS_INTERNAL,
-- .config_init = qca83xx_config_init,
-+ .config_init = qca8327_config_init,
- .soft_reset = genphy_soft_reset,
- .get_sset_count = qca83xx_get_sset_count,
- .get_strings = qca83xx_get_strings,
- .get_stats = qca83xx_get_stats,
-- .suspend = qca83xx_suspend,
-+ .suspend = qca8327_suspend,
- .resume = qca83xx_resume,
- }, {
- /* QCA8327-B from switch QCA8327-BL1A */
-@@ -2205,12 +2211,12 @@ static struct phy_driver at803x_driver[]
- .link_change_notify = qca83xx_link_change_notify,
- .probe = at803x_probe,
- .flags = PHY_IS_INTERNAL,
-- .config_init = qca83xx_config_init,
-+ .config_init = qca8327_config_init,
- .soft_reset = genphy_soft_reset,
- .get_sset_count = qca83xx_get_sset_count,
- .get_strings = qca83xx_get_strings,
- .get_stats = qca83xx_get_stats,
-- .suspend = qca83xx_suspend,
-+ .suspend = qca8327_suspend,
- .resume = qca83xx_resume,
- }, {
- /* Qualcomm QCA8081 */
diff --git a/target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch b/target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch
deleted file mode 100644
index a5cc67a8c8..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 900eef75cc5018e149c52fe305c9c3fe424c52a7 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:52 +0100
-Subject: [PATCH 05/13] net: phy: at803x: move specific DT option for at8031 to
- specific probe
-
-Move specific DT options for at8031 to specific probe to tidy things up
-and make at803x_parse_dt more generic.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 55 ++++++++++++++++++++++------------------
- 1 file changed, 31 insertions(+), 24 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -825,30 +825,6 @@ static int at803x_parse_dt(struct phy_de
- }
- }
-
-- /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
-- * options.
-- */
-- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-- if (of_property_read_bool(node, "qca,keep-pll-enabled"))
-- priv->flags |= AT803X_KEEP_PLL_ENABLED;
--
-- ret = at8031_register_regulators(phydev);
-- if (ret < 0)
-- return ret;
--
-- ret = devm_regulator_get_enable_optional(&phydev->mdio.dev,
-- "vddio");
-- if (ret) {
-- phydev_err(phydev, "failed to get VDDIO regulator\n");
-- return ret;
-- }
--
-- /* Only AR8031/8033 support 1000Base-X for SFP modules */
-- ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
-- if (ret < 0)
-- return ret;
-- }
--
- return 0;
- }
-
-@@ -1582,6 +1558,30 @@ static int at803x_cable_test_start(struc
- return 0;
- }
-
-+static int at8031_parse_dt(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ struct at803x_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (of_property_read_bool(node, "qca,keep-pll-enabled"))
-+ priv->flags |= AT803X_KEEP_PLL_ENABLED;
-+
-+ ret = at8031_register_regulators(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = devm_regulator_get_enable_optional(&phydev->mdio.dev,
-+ "vddio");
-+ if (ret) {
-+ phydev_err(phydev, "failed to get VDDIO regulator\n");
-+ return ret;
-+ }
-+
-+ /* Only AR8031/8033 support 1000Base-X for SFP modules */
-+ return phy_sfp_probe(phydev, &at803x_sfp_ops);
-+}
-+
- static int at8031_probe(struct phy_device *phydev)
- {
- int ret;
-@@ -1590,6 +1590,13 @@ static int at8031_probe(struct phy_devic
- if (ret)
- return ret;
-
-+ /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
-+ * options.
-+ */
-+ ret = at8031_parse_dt(phydev);
-+ if (ret)
-+ return ret;
-+
- /* Disable WoL in 1588 register which is enabled
- * by default
- */
diff --git a/target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch b/target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch
deleted file mode 100644
index 9e10e000e5..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 25d2ba94005fac18fe68878cddff59a67e115554 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:53 +0100
-Subject: [PATCH 06/13] net: phy: at803x: move specific at8031 probe mode check
- to dedicated probe
-
-Move specific at8031 probe mode check to dedicated probe to make
-at803x_probe more generic and keep code tidy.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 39 +++++++++++++++++++--------------------
- 1 file changed, 19 insertions(+), 20 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -844,26 +844,6 @@ static int at803x_probe(struct phy_devic
- if (ret)
- return ret;
-
-- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-- int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
-- int mode_cfg;
--
-- if (ccr < 0)
-- return ccr;
-- mode_cfg = ccr & AT803X_MODE_CFG_MASK;
--
-- switch (mode_cfg) {
-- case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
-- case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
-- priv->is_1000basex = true;
-- fallthrough;
-- case AT803X_MODE_CFG_FX100_RGMII_50OHM:
-- case AT803X_MODE_CFG_FX100_RGMII_75OHM:
-- priv->is_fiber = true;
-- break;
-- }
-- }
--
- return 0;
- }
-
-@@ -1584,6 +1564,9 @@ static int at8031_parse_dt(struct phy_de
-
- static int at8031_probe(struct phy_device *phydev)
- {
-+ struct at803x_priv *priv = phydev->priv;
-+ int mode_cfg;
-+ int ccr;
- int ret;
-
- ret = at803x_probe(phydev);
-@@ -1597,6 +1580,22 @@ static int at8031_probe(struct phy_devic
- if (ret)
- return ret;
-
-+ ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
-+ if (ccr < 0)
-+ return ccr;
-+ mode_cfg = ccr & AT803X_MODE_CFG_MASK;
-+
-+ switch (mode_cfg) {
-+ case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
-+ case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
-+ priv->is_1000basex = true;
-+ fallthrough;
-+ case AT803X_MODE_CFG_FX100_RGMII_50OHM:
-+ case AT803X_MODE_CFG_FX100_RGMII_75OHM:
-+ priv->is_fiber = true;
-+ break;
-+ }
-+
- /* Disable WoL in 1588 register which is enabled
- * by default
- */
diff --git a/target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch b/target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch
deleted file mode 100644
index c9ef6df827..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 3ae3bc426eaf57ca8f53d75777d9a5ef779bc7b7 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:54 +0100
-Subject: [PATCH 07/13] net: phy: at803x: move specific at8031 config_init to
- dedicated function
-
-Move specific at8031 config_init to dedicated function to make
-at803x_config_init more generic and tidy things up.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 45 ++++++++++++++++++++++------------------
- 1 file changed, 25 insertions(+), 20 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -951,27 +951,8 @@ static int at803x_hibernation_mode_confi
-
- static int at803x_config_init(struct phy_device *phydev)
- {
-- struct at803x_priv *priv = phydev->priv;
- int ret;
-
-- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-- /* Some bootloaders leave the fiber page selected.
-- * Switch to the appropriate page (fiber or copper), as otherwise we
-- * read the PHY capabilities from the wrong page.
-- */
-- phy_lock_mdio_bus(phydev);
-- ret = at803x_write_page(phydev,
-- priv->is_fiber ? AT803X_PAGE_FIBER :
-- AT803X_PAGE_COPPER);
-- phy_unlock_mdio_bus(phydev);
-- if (ret)
-- return ret;
--
-- ret = at8031_pll_config(phydev);
-- if (ret < 0)
-- return ret;
-- }
--
- /* The RX and TX delay default is:
- * after HW reset: RX delay enabled and TX delay disabled
- * after SW reset: RX delay enabled, while TX delay retains the
-@@ -1604,6 +1585,30 @@ static int at8031_probe(struct phy_devic
- AT803X_WOL_EN, 0);
- }
-
-+static int at8031_config_init(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int ret;
-+
-+ /* Some bootloaders leave the fiber page selected.
-+ * Switch to the appropriate page (fiber or copper), as otherwise we
-+ * read the PHY capabilities from the wrong page.
-+ */
-+ phy_lock_mdio_bus(phydev);
-+ ret = at803x_write_page(phydev,
-+ priv->is_fiber ? AT803X_PAGE_FIBER :
-+ AT803X_PAGE_COPPER);
-+ phy_unlock_mdio_bus(phydev);
-+ if (ret)
-+ return ret;
-+
-+ ret = at8031_pll_config(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ return at803x_config_init(phydev);
-+}
-+
- static int qca83xx_config_init(struct phy_device *phydev)
- {
- u8 switch_revision;
-@@ -2113,7 +2118,7 @@ static struct phy_driver at803x_driver[]
- .name = "Qualcomm Atheros AR8031/AR8033",
- .flags = PHY_POLL_CABLE_TEST,
- .probe = at8031_probe,
-- .config_init = at803x_config_init,
-+ .config_init = at8031_config_init,
- .config_aneg = at803x_config_aneg,
- .soft_reset = genphy_soft_reset,
- .set_wol = at803x_set_wol,
diff --git a/target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch b/target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch
deleted file mode 100644
index 6746a4d43c..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 27b89c9dc1b0393090d68d651b82f30ad2696baa Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:55 +0100
-Subject: [PATCH 08/13] net: phy: at803x: move specific at8031 WOL bits to
- dedicated function
-
-Move specific at8031 WOL enable/disable to dedicated function to make
-at803x_set_wol more generic.
-
-This is needed in preparation for PHY driver split as qca8081 share the
-same function to toggle WOL settings.
-
-In this new implementation WOL module in at8031 is enabled after the
-generic interrupt is setup. This should not cause any problem as the
-WOL_INT has a separate implementation and only relay on MAC bits.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 42 ++++++++++++++++++++++++----------------
- 1 file changed, 25 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -466,27 +466,11 @@ static int at803x_set_wol(struct phy_dev
- phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
- mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
-
-- /* Enable WOL function for 1588 */
-- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-- AT803X_PHY_MMD3_WOL_CTRL,
-- 0, AT803X_WOL_EN);
-- if (ret)
-- return ret;
-- }
- /* Enable WOL interrupt */
- ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
- if (ret)
- return ret;
- } else {
-- /* Disable WoL function for 1588 */
-- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-- AT803X_PHY_MMD3_WOL_CTRL,
-- AT803X_WOL_EN, 0);
-- if (ret)
-- return ret;
-- }
- /* Disable WOL interrupt */
- ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
- if (ret)
-@@ -1609,6 +1593,30 @@ static int at8031_config_init(struct phy
- return at803x_config_init(phydev);
- }
-
-+static int at8031_set_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int ret;
-+
-+ /* First setup MAC address and enable WOL interrupt */
-+ ret = at803x_set_wol(phydev, wol);
-+ if (ret)
-+ return ret;
-+
-+ if (wol->wolopts & WAKE_MAGIC)
-+ /* Enable WOL function for 1588 */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+ AT803X_PHY_MMD3_WOL_CTRL,
-+ 0, AT803X_WOL_EN);
-+ else
-+ /* Disable WoL function for 1588 */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+ AT803X_PHY_MMD3_WOL_CTRL,
-+ AT803X_WOL_EN, 0);
-+
-+ return ret;
-+}
-+
- static int qca83xx_config_init(struct phy_device *phydev)
- {
- u8 switch_revision;
-@@ -2121,7 +2129,7 @@ static struct phy_driver at803x_driver[]
- .config_init = at8031_config_init,
- .config_aneg = at803x_config_aneg,
- .soft_reset = genphy_soft_reset,
-- .set_wol = at803x_set_wol,
-+ .set_wol = at8031_set_wol,
- .get_wol = at803x_get_wol,
- .suspend = at803x_suspend,
- .resume = at803x_resume,
diff --git a/target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch b/target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch
deleted file mode 100644
index 0d284c3d24..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 30dd62191d3dd97c08f7f9dc9ce77ffab457e4fb Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:56 +0100
-Subject: [PATCH 09/13] net: phy: at803x: move specific at8031 config_intr to
- dedicated function
-
-Move specific at8031 config_intr bits to dedicated function to make
-at803x_config_initr more generic.
-
-This is needed in preparation for PHY driver split as qca8081 share the
-same function to setup interrupts.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 30 ++++++++++++++++++++++++------
- 1 file changed, 24 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -990,7 +990,6 @@ static int at803x_ack_interrupt(struct p
-
- static int at803x_config_intr(struct phy_device *phydev)
- {
-- struct at803x_priv *priv = phydev->priv;
- int err;
- int value;
-
-@@ -1007,10 +1006,6 @@ static int at803x_config_intr(struct phy
- value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
- value |= AT803X_INTR_ENABLE_LINK_FAIL;
- value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
-- if (priv->is_fiber) {
-- value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
-- value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
-- }
-
- err = phy_write(phydev, AT803X_INTR_ENABLE, value);
- } else {
-@@ -1617,6 +1612,29 @@ static int at8031_set_wol(struct phy_dev
- return ret;
- }
-
-+static int at8031_config_intr(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int err, value = 0;
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED &&
-+ priv->is_fiber) {
-+ /* Clear any pending interrupts */
-+ err = at803x_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
-+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
-+
-+ err = phy_set_bits(phydev, AT803X_INTR_ENABLE, value);
-+ if (err)
-+ return err;
-+ }
-+
-+ return at803x_config_intr(phydev);
-+}
-+
- static int qca83xx_config_init(struct phy_device *phydev)
- {
- u8 switch_revision;
-@@ -2137,7 +2155,7 @@ static struct phy_driver at803x_driver[]
- .write_page = at803x_write_page,
- .get_features = at803x_get_features,
- .read_status = at803x_read_status,
-- .config_intr = at803x_config_intr,
-+ .config_intr = at8031_config_intr,
- .handle_interrupt = at803x_handle_interrupt,
- .get_tunable = at803x_get_tunable,
- .set_tunable = at803x_set_tunable,
diff --git a/target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch b/target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch
deleted file mode 100644
index 210949ea81..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From a5ab9d8e7ae0da8328ac1637a9755311508dc8ab Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:57 +0100
-Subject: [PATCH 10/13] net: phy: at803x: make at8031 related DT functions name
- more specific
-
-Rename at8031 related DT function name to a more specific name
-referencing they are only related to at8031 and not to the generic
-at803x PHY family.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -583,7 +583,7 @@ static int at803x_resume(struct phy_devi
- return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
- }
-
--static int at803x_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
-+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
- unsigned int selector)
- {
- struct phy_device *phydev = rdev_get_drvdata(rdev);
-@@ -596,7 +596,7 @@ static int at803x_rgmii_reg_set_voltage_
- AT803X_DEBUG_RGMII_1V8, 0);
- }
-
--static int at803x_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
-+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
- {
- struct phy_device *phydev = rdev_get_drvdata(rdev);
- int val;
-@@ -610,8 +610,8 @@ static int at803x_rgmii_reg_get_voltage_
-
- static const struct regulator_ops vddio_regulator_ops = {
- .list_voltage = regulator_list_voltage_table,
-- .set_voltage_sel = at803x_rgmii_reg_set_voltage_sel,
-- .get_voltage_sel = at803x_rgmii_reg_get_voltage_sel,
-+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
-+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
- };
-
- static const unsigned int vddio_voltage_table[] = {
-@@ -666,7 +666,7 @@ static int at8031_register_regulators(st
- return 0;
- }
-
--static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
- {
- struct phy_device *phydev = upstream;
- __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
-@@ -710,10 +710,10 @@ static int at803x_sfp_insert(void *upstr
- return 0;
- }
-
--static const struct sfp_upstream_ops at803x_sfp_ops = {
-+static const struct sfp_upstream_ops at8031_sfp_ops = {
- .attach = phy_sfp_attach,
- .detach = phy_sfp_detach,
-- .module_insert = at803x_sfp_insert,
-+ .module_insert = at8031_sfp_insert,
- };
-
- static int at803x_parse_dt(struct phy_device *phydev)
-@@ -1519,7 +1519,7 @@ static int at8031_parse_dt(struct phy_de
- }
-
- /* Only AR8031/8033 support 1000Base-X for SFP modules */
-- return phy_sfp_probe(phydev, &at803x_sfp_ops);
-+ return phy_sfp_probe(phydev, &at8031_sfp_ops);
- }
-
- static int at8031_probe(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch b/target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch
deleted file mode 100644
index 5856b59751..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch
+++ /dev/null
@@ -1,297 +0,0 @@
-From f932a6dc8bae0dae9645b5b1b4c65aed8a8acb2a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:58 +0100
-Subject: [PATCH 11/13] net: phy: at803x: move at8031 functions in dedicated
- section
-
-Move at8031 functions in dedicated section with dedicated at8031
-parse_dt and probe.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 266 +++++++++++++++++++--------------------
- 1 file changed, 133 insertions(+), 133 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -583,139 +583,6 @@ static int at803x_resume(struct phy_devi
- return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
- }
-
--static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
-- unsigned int selector)
--{
-- struct phy_device *phydev = rdev_get_drvdata(rdev);
--
-- if (selector)
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-- 0, AT803X_DEBUG_RGMII_1V8);
-- else
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-- AT803X_DEBUG_RGMII_1V8, 0);
--}
--
--static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
--{
-- struct phy_device *phydev = rdev_get_drvdata(rdev);
-- int val;
--
-- val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F);
-- if (val < 0)
-- return val;
--
-- return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0;
--}
--
--static const struct regulator_ops vddio_regulator_ops = {
-- .list_voltage = regulator_list_voltage_table,
-- .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
-- .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
--};
--
--static const unsigned int vddio_voltage_table[] = {
-- 1500000,
-- 1800000,
--};
--
--static const struct regulator_desc vddio_desc = {
-- .name = "vddio",
-- .of_match = of_match_ptr("vddio-regulator"),
-- .n_voltages = ARRAY_SIZE(vddio_voltage_table),
-- .volt_table = vddio_voltage_table,
-- .ops = &vddio_regulator_ops,
-- .type = REGULATOR_VOLTAGE,
-- .owner = THIS_MODULE,
--};
--
--static const struct regulator_ops vddh_regulator_ops = {
--};
--
--static const struct regulator_desc vddh_desc = {
-- .name = "vddh",
-- .of_match = of_match_ptr("vddh-regulator"),
-- .n_voltages = 1,
-- .fixed_uV = 2500000,
-- .ops = &vddh_regulator_ops,
-- .type = REGULATOR_VOLTAGE,
-- .owner = THIS_MODULE,
--};
--
--static int at8031_register_regulators(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- struct device *dev = &phydev->mdio.dev;
-- struct regulator_config config = { };
--
-- config.dev = dev;
-- config.driver_data = phydev;
--
-- priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config);
-- if (IS_ERR(priv->vddio_rdev)) {
-- phydev_err(phydev, "failed to register VDDIO regulator\n");
-- return PTR_ERR(priv->vddio_rdev);
-- }
--
-- priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config);
-- if (IS_ERR(priv->vddh_rdev)) {
-- phydev_err(phydev, "failed to register VDDH regulator\n");
-- return PTR_ERR(priv->vddh_rdev);
-- }
--
-- return 0;
--}
--
--static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
--{
-- struct phy_device *phydev = upstream;
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
-- DECLARE_PHY_INTERFACE_MASK(interfaces);
-- phy_interface_t iface;
--
-- linkmode_zero(phy_support);
-- phylink_set(phy_support, 1000baseX_Full);
-- phylink_set(phy_support, 1000baseT_Full);
-- phylink_set(phy_support, Autoneg);
-- phylink_set(phy_support, Pause);
-- phylink_set(phy_support, Asym_Pause);
--
-- linkmode_zero(sfp_support);
-- sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces);
-- /* Some modules support 10G modes as well as others we support.
-- * Mask out non-supported modes so the correct interface is picked.
-- */
-- linkmode_and(sfp_support, phy_support, sfp_support);
--
-- if (linkmode_empty(sfp_support)) {
-- dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
-- return -EINVAL;
-- }
--
-- iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
--
-- /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
-- * interface for use with SFP modules.
-- * However, some copper modules detected as having a preferred SGMII
-- * interface do default to and function in 1000Base-X mode, so just
-- * print a warning and allow such modules, as they may have some chance
-- * of working.
-- */
-- if (iface == PHY_INTERFACE_MODE_SGMII)
-- dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
-- else if (iface != PHY_INTERFACE_MODE_1000BASEX)
-- return -EINVAL;
--
-- return 0;
--}
--
--static const struct sfp_upstream_ops at8031_sfp_ops = {
-- .attach = phy_sfp_attach,
-- .detach = phy_sfp_detach,
-- .module_insert = at8031_sfp_insert,
--};
--
- static int at803x_parse_dt(struct phy_device *phydev)
- {
- struct device_node *node = phydev->mdio.dev.of_node;
-@@ -1498,6 +1365,139 @@ static int at803x_cable_test_start(struc
- return 0;
- }
-
-+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
-+ unsigned int selector)
-+{
-+ struct phy_device *phydev = rdev_get_drvdata(rdev);
-+
-+ if (selector)
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-+ 0, AT803X_DEBUG_RGMII_1V8);
-+ else
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-+ AT803X_DEBUG_RGMII_1V8, 0);
-+}
-+
-+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
-+{
-+ struct phy_device *phydev = rdev_get_drvdata(rdev);
-+ int val;
-+
-+ val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F);
-+ if (val < 0)
-+ return val;
-+
-+ return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0;
-+}
-+
-+static const struct regulator_ops vddio_regulator_ops = {
-+ .list_voltage = regulator_list_voltage_table,
-+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
-+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
-+};
-+
-+static const unsigned int vddio_voltage_table[] = {
-+ 1500000,
-+ 1800000,
-+};
-+
-+static const struct regulator_desc vddio_desc = {
-+ .name = "vddio",
-+ .of_match = of_match_ptr("vddio-regulator"),
-+ .n_voltages = ARRAY_SIZE(vddio_voltage_table),
-+ .volt_table = vddio_voltage_table,
-+ .ops = &vddio_regulator_ops,
-+ .type = REGULATOR_VOLTAGE,
-+ .owner = THIS_MODULE,
-+};
-+
-+static const struct regulator_ops vddh_regulator_ops = {
-+};
-+
-+static const struct regulator_desc vddh_desc = {
-+ .name = "vddh",
-+ .of_match = of_match_ptr("vddh-regulator"),
-+ .n_voltages = 1,
-+ .fixed_uV = 2500000,
-+ .ops = &vddh_regulator_ops,
-+ .type = REGULATOR_VOLTAGE,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int at8031_register_regulators(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ struct device *dev = &phydev->mdio.dev;
-+ struct regulator_config config = { };
-+
-+ config.dev = dev;
-+ config.driver_data = phydev;
-+
-+ priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config);
-+ if (IS_ERR(priv->vddio_rdev)) {
-+ phydev_err(phydev, "failed to register VDDIO regulator\n");
-+ return PTR_ERR(priv->vddio_rdev);
-+ }
-+
-+ priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config);
-+ if (IS_ERR(priv->vddh_rdev)) {
-+ phydev_err(phydev, "failed to register VDDH regulator\n");
-+ return PTR_ERR(priv->vddh_rdev);
-+ }
-+
-+ return 0;
-+}
-+
-+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+{
-+ struct phy_device *phydev = upstream;
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
-+ DECLARE_PHY_INTERFACE_MASK(interfaces);
-+ phy_interface_t iface;
-+
-+ linkmode_zero(phy_support);
-+ phylink_set(phy_support, 1000baseX_Full);
-+ phylink_set(phy_support, 1000baseT_Full);
-+ phylink_set(phy_support, Autoneg);
-+ phylink_set(phy_support, Pause);
-+ phylink_set(phy_support, Asym_Pause);
-+
-+ linkmode_zero(sfp_support);
-+ sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces);
-+ /* Some modules support 10G modes as well as others we support.
-+ * Mask out non-supported modes so the correct interface is picked.
-+ */
-+ linkmode_and(sfp_support, phy_support, sfp_support);
-+
-+ if (linkmode_empty(sfp_support)) {
-+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
-+ return -EINVAL;
-+ }
-+
-+ iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
-+
-+ /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
-+ * interface for use with SFP modules.
-+ * However, some copper modules detected as having a preferred SGMII
-+ * interface do default to and function in 1000Base-X mode, so just
-+ * print a warning and allow such modules, as they may have some chance
-+ * of working.
-+ */
-+ if (iface == PHY_INTERFACE_MODE_SGMII)
-+ dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
-+ else if (iface != PHY_INTERFACE_MODE_1000BASEX)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static const struct sfp_upstream_ops at8031_sfp_ops = {
-+ .attach = phy_sfp_attach,
-+ .detach = phy_sfp_detach,
-+ .module_insert = at8031_sfp_insert,
-+};
-+
- static int at8031_parse_dt(struct phy_device *phydev)
- {
- struct device_node *node = phydev->mdio.dev.of_node;
diff --git a/target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch b/target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch
deleted file mode 100644
index 0a822c6d37..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 21a2802a8365cfa82cc02187c1f95136d85592ad Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:51:59 +0100
-Subject: [PATCH 12/13] net: phy: at803x: move at8035 specific DT parse to
- dedicated probe
-
-Move at8035 specific DT parse for clock out frequency to dedicated probe
-to make at803x probe function more generic.
-
-This is to tidy code and no behaviour change are intended.
-
-Detection logic is changed, we check if the clk 25m mask is set and if
-it's not zero, we assume the qca,clk-out-frequency property is set.
-
-The property is checked in the generic at803x_parse_dt called by
-at803x_probe.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 60 +++++++++++++++++++++++++++-------------
- 1 file changed, 41 insertions(+), 19 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -638,23 +638,6 @@ static int at803x_parse_dt(struct phy_de
-
- priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel);
- priv->clk_25m_mask |= AT803X_CLK_OUT_MASK;
--
-- /* Fixup for the AR8030/AR8035. This chip has another mask and
-- * doesn't support the DSP reference. Eg. the lowest bit of the
-- * mask. The upper two bits select the same frequencies. Mask
-- * the lowest bit here.
-- *
-- * Warning:
-- * There was no datasheet for the AR8030 available so this is
-- * just a guess. But the AR8035 is listed as pin compatible
-- * to the AR8030 so there might be a good chance it works on
-- * the AR8030 too.
-- */
-- if (phydev->drv->phy_id == ATH8030_PHY_ID ||
-- phydev->drv->phy_id == ATH8035_PHY_ID) {
-- priv->clk_25m_reg &= AT8035_CLK_OUT_MASK;
-- priv->clk_25m_mask &= AT8035_CLK_OUT_MASK;
-- }
- }
-
- ret = of_property_read_u32(node, "qca,clk-out-strength", &strength);
-@@ -1635,6 +1618,45 @@ static int at8031_config_intr(struct phy
- return at803x_config_intr(phydev);
- }
-
-+static int at8035_parse_dt(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+
-+ /* Mask is set by the generic at803x_parse_dt
-+ * if property is set. Assume property is set
-+ * with the mask not zero.
-+ */
-+ if (priv->clk_25m_mask) {
-+ /* Fixup for the AR8030/AR8035. This chip has another mask and
-+ * doesn't support the DSP reference. Eg. the lowest bit of the
-+ * mask. The upper two bits select the same frequencies. Mask
-+ * the lowest bit here.
-+ *
-+ * Warning:
-+ * There was no datasheet for the AR8030 available so this is
-+ * just a guess. But the AR8035 is listed as pin compatible
-+ * to the AR8030 so there might be a good chance it works on
-+ * the AR8030 too.
-+ */
-+ priv->clk_25m_reg &= AT8035_CLK_OUT_MASK;
-+ priv->clk_25m_mask &= AT8035_CLK_OUT_MASK;
-+ }
-+
-+ return 0;
-+}
-+
-+/* AR8030 and AR8035 shared the same special mask for clk_25m */
-+static int at8035_probe(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = at803x_probe(phydev);
-+ if (ret)
-+ return ret;
-+
-+ return at8035_parse_dt(phydev);
-+}
-+
- static int qca83xx_config_init(struct phy_device *phydev)
- {
- u8 switch_revision;
-@@ -2107,7 +2129,7 @@ static struct phy_driver at803x_driver[]
- PHY_ID_MATCH_EXACT(ATH8035_PHY_ID),
- .name = "Qualcomm Atheros AR8035",
- .flags = PHY_POLL_CABLE_TEST,
-- .probe = at803x_probe,
-+ .probe = at8035_probe,
- .config_aneg = at803x_config_aneg,
- .config_init = at803x_config_init,
- .soft_reset = genphy_soft_reset,
-@@ -2128,7 +2150,7 @@ static struct phy_driver at803x_driver[]
- .phy_id = ATH8030_PHY_ID,
- .name = "Qualcomm Atheros AR8030",
- .phy_id_mask = AT8030_PHY_ID_MASK,
-- .probe = at803x_probe,
-+ .probe = at8035_probe,
- .config_init = at803x_config_init,
- .link_change_notify = at803x_link_change_notify,
- .set_wol = at803x_set_wol,
diff --git a/target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch b/target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch
deleted file mode 100644
index e1ba6ec2d0..0000000000
--- a/target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch
+++ /dev/null
@@ -1,219 +0,0 @@
-From ef9df47b449e32e06501a11272809be49019bdb6 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 8 Dec 2023 15:52:00 +0100
-Subject: [PATCH 13/13] net: phy: at803x: drop specific PHY ID check from cable
- test functions
-
-Drop specific PHY ID check for cable test functions for at803x. This is
-done to make functions more generic. While at it better describe what
-the functions does by using more symbolic function names.
-
-PHYs that requires to set additional reg are moved to specific function
-calling the more generic one.
-
-cdt_start and cdt_wait_for_completion are changed to take an additional
-arg to pass specific values specific to the PHY.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 95 +++++++++++++++++++++-------------------
- 1 file changed, 50 insertions(+), 45 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1222,31 +1222,16 @@ static int at803x_cdt_fault_length(u16 s
- return (dt * 824) / 10;
- }
-
--static int at803x_cdt_start(struct phy_device *phydev, int pair)
-+static int at803x_cdt_start(struct phy_device *phydev,
-+ u32 cdt_start)
- {
-- u16 cdt;
--
-- /* qca8081 takes the different bit 15 to enable CDT test */
-- if (phydev->drv->phy_id == QCA8081_PHY_ID)
-- cdt = QCA808X_CDT_ENABLE_TEST |
-- QCA808X_CDT_LENGTH_UNIT |
-- QCA808X_CDT_INTER_CHECK_DIS;
-- else
-- cdt = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
-- AT803X_CDT_ENABLE_TEST;
--
-- return phy_write(phydev, AT803X_CDT, cdt);
-+ return phy_write(phydev, AT803X_CDT, cdt_start);
- }
-
--static int at803x_cdt_wait_for_completion(struct phy_device *phydev)
-+static int at803x_cdt_wait_for_completion(struct phy_device *phydev,
-+ u32 cdt_en)
- {
- int val, ret;
-- u16 cdt_en;
--
-- if (phydev->drv->phy_id == QCA8081_PHY_ID)
-- cdt_en = QCA808X_CDT_ENABLE_TEST;
-- else
-- cdt_en = AT803X_CDT_ENABLE_TEST;
-
- /* One test run takes about 25ms */
- ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
-@@ -1266,11 +1251,13 @@ static int at803x_cable_test_one_pair(st
- };
- int ret, val;
-
-- ret = at803x_cdt_start(phydev, pair);
-+ val = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
-+ AT803X_CDT_ENABLE_TEST;
-+ ret = at803x_cdt_start(phydev, val);
- if (ret)
- return ret;
-
-- ret = at803x_cdt_wait_for_completion(phydev);
-+ ret = at803x_cdt_wait_for_completion(phydev, AT803X_CDT_ENABLE_TEST);
- if (ret)
- return ret;
-
-@@ -1292,19 +1279,11 @@ static int at803x_cable_test_one_pair(st
- }
-
- static int at803x_cable_test_get_status(struct phy_device *phydev,
-- bool *finished)
-+ bool *finished, unsigned long pair_mask)
- {
-- unsigned long pair_mask;
- int retries = 20;
- int pair, ret;
-
-- if (phydev->phy_id == ATH9331_PHY_ID ||
-- phydev->phy_id == ATH8032_PHY_ID ||
-- phydev->phy_id == QCA9561_PHY_ID)
-- pair_mask = 0x3;
-- else
-- pair_mask = 0xf;
--
- *finished = false;
-
- /* According to the datasheet the CDT can be performed when
-@@ -1331,7 +1310,7 @@ static int at803x_cable_test_get_status(
- return 0;
- }
-
--static int at803x_cable_test_start(struct phy_device *phydev)
-+static void at803x_cable_test_autoneg(struct phy_device *phydev)
- {
- /* Enable auto-negotiation, but advertise no capabilities, no link
- * will be established. A restart of the auto-negotiation is not
-@@ -1339,11 +1318,11 @@ static int at803x_cable_test_start(struc
- */
- phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
- phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA);
-- if (phydev->phy_id != ATH9331_PHY_ID &&
-- phydev->phy_id != ATH8032_PHY_ID &&
-- phydev->phy_id != QCA9561_PHY_ID)
-- phy_write(phydev, MII_CTRL1000, 0);
-+}
-
-+static int at803x_cable_test_start(struct phy_device *phydev)
-+{
-+ at803x_cable_test_autoneg(phydev);
- /* we do all the (time consuming) work later */
- return 0;
- }
-@@ -1618,6 +1597,29 @@ static int at8031_config_intr(struct phy
- return at803x_config_intr(phydev);
- }
-
-+/* AR8031 and AR8035 share the same cable test get status reg */
-+static int at8031_cable_test_get_status(struct phy_device *phydev,
-+ bool *finished)
-+{
-+ return at803x_cable_test_get_status(phydev, finished, 0xf);
-+}
-+
-+/* AR8031 and AR8035 share the same cable test start logic */
-+static int at8031_cable_test_start(struct phy_device *phydev)
-+{
-+ at803x_cable_test_autoneg(phydev);
-+ phy_write(phydev, MII_CTRL1000, 0);
-+ /* we do all the (time consuming) work later */
-+ return 0;
-+}
-+
-+/* AR8032, AR9331 and QCA9561 share the same cable test get status reg */
-+static int at8032_cable_test_get_status(struct phy_device *phydev,
-+ bool *finished)
-+{
-+ return at803x_cable_test_get_status(phydev, finished, 0x3);
-+}
-+
- static int at8035_parse_dt(struct phy_device *phydev)
- {
- struct at803x_priv *priv = phydev->priv;
-@@ -2041,11 +2043,14 @@ static int qca808x_cable_test_get_status
-
- *finished = false;
-
-- ret = at803x_cdt_start(phydev, 0);
-+ val = QCA808X_CDT_ENABLE_TEST |
-+ QCA808X_CDT_LENGTH_UNIT |
-+ QCA808X_CDT_INTER_CHECK_DIS;
-+ ret = at803x_cdt_start(phydev, val);
- if (ret)
- return ret;
-
-- ret = at803x_cdt_wait_for_completion(phydev);
-+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
- if (ret)
- return ret;
-
-@@ -2143,8 +2148,8 @@ static struct phy_driver at803x_driver[]
- .handle_interrupt = at803x_handle_interrupt,
- .get_tunable = at803x_get_tunable,
- .set_tunable = at803x_set_tunable,
-- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at803x_cable_test_get_status,
-+ .cable_test_start = at8031_cable_test_start,
-+ .cable_test_get_status = at8031_cable_test_get_status,
- }, {
- /* Qualcomm Atheros AR8030 */
- .phy_id = ATH8030_PHY_ID,
-@@ -2181,8 +2186,8 @@ static struct phy_driver at803x_driver[]
- .handle_interrupt = at803x_handle_interrupt,
- .get_tunable = at803x_get_tunable,
- .set_tunable = at803x_set_tunable,
-- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at803x_cable_test_get_status,
-+ .cable_test_start = at8031_cable_test_start,
-+ .cable_test_get_status = at8031_cable_test_get_status,
- }, {
- /* Qualcomm Atheros AR8032 */
- PHY_ID_MATCH_EXACT(ATH8032_PHY_ID),
-@@ -2197,7 +2202,7 @@ static struct phy_driver at803x_driver[]
- .config_intr = at803x_config_intr,
- .handle_interrupt = at803x_handle_interrupt,
- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at803x_cable_test_get_status,
-+ .cable_test_get_status = at8032_cable_test_get_status,
- }, {
- /* ATHEROS AR9331 */
- PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
-@@ -2210,7 +2215,7 @@ static struct phy_driver at803x_driver[]
- .config_intr = at803x_config_intr,
- .handle_interrupt = at803x_handle_interrupt,
- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at803x_cable_test_get_status,
-+ .cable_test_get_status = at8032_cable_test_get_status,
- .read_status = at803x_read_status,
- .soft_reset = genphy_soft_reset,
- .config_aneg = at803x_config_aneg,
-@@ -2226,7 +2231,7 @@ static struct phy_driver at803x_driver[]
- .config_intr = at803x_config_intr,
- .handle_interrupt = at803x_handle_interrupt,
- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at803x_cable_test_get_status,
-+ .cable_test_get_status = at8032_cable_test_get_status,
- .read_status = at803x_read_status,
- .soft_reset = genphy_soft_reset,
- .config_aneg = at803x_config_aneg,
diff --git a/target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch b/target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch
deleted file mode 100644
index 0bb3673c02..0000000000
--- a/target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 8e732f1c6f2dc5e18f766d0f1b11df9db2dd044a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 14 Dec 2023 01:44:31 +0100
-Subject: [PATCH 1/2] net: phy: at803x: move specific qca808x config_aneg to
- dedicated function
-
-Move specific qca808x config_aneg to dedicated function to permit easier
-split of qca808x portion from at803x driver.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 66 ++++++++++++++++++++++++----------------
- 1 file changed, 40 insertions(+), 26 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1045,9 +1045,8 @@ static int at803x_config_mdix(struct phy
- FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
- }
-
--static int at803x_config_aneg(struct phy_device *phydev)
-+static int at803x_prepare_config_aneg(struct phy_device *phydev)
- {
-- struct at803x_priv *priv = phydev->priv;
- int ret;
-
- ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
-@@ -1064,33 +1063,22 @@ static int at803x_config_aneg(struct phy
- return ret;
- }
-
-- if (priv->is_1000basex)
-- return genphy_c37_config_aneg(phydev);
--
-- /* Do not restart auto-negotiation by setting ret to 0 defautly,
-- * when calling __genphy_config_aneg later.
-- */
-- ret = 0;
--
-- if (phydev->drv->phy_id == QCA8081_PHY_ID) {
-- int phy_ctrl = 0;
-+ return 0;
-+}
-
-- /* The reg MII_BMCR also needs to be configured for force mode, the
-- * genphy_config_aneg is also needed.
-- */
-- if (phydev->autoneg == AUTONEG_DISABLE)
-- genphy_c45_pma_setup_forced(phydev);
-+static int at803x_config_aneg(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int ret;
-
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
-- phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
-+ ret = at803x_prepare_config_aneg(phydev);
-+ if (ret)
-+ return ret;
-
-- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-- MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
-- if (ret < 0)
-- return ret;
-- }
-+ if (priv->is_1000basex)
-+ return genphy_c37_config_aneg(phydev);
-
-- return __genphy_config_aneg(phydev, ret);
-+ return genphy_config_aneg(phydev);
- }
-
- static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
-@@ -2118,6 +2106,32 @@ static int qca808x_get_features(struct p
- return 0;
- }
-
-+static int qca808x_config_aneg(struct phy_device *phydev)
-+{
-+ int phy_ctrl = 0;
-+ int ret;
-+
-+ ret = at803x_prepare_config_aneg(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* The reg MII_BMCR also needs to be configured for force mode, the
-+ * genphy_config_aneg is also needed.
-+ */
-+ if (phydev->autoneg == AUTONEG_DISABLE)
-+ genphy_c45_pma_setup_forced(phydev);
-+
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
-+ phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
-+
-+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-+ MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __genphy_config_aneg(phydev, ret);
-+}
-+
- static void qca808x_link_change_notify(struct phy_device *phydev)
- {
- /* Assert interface sgmii fifo on link down, deassert it on link up,
-@@ -2295,7 +2309,7 @@ static struct phy_driver at803x_driver[]
- .set_wol = at803x_set_wol,
- .get_wol = at803x_get_wol,
- .get_features = qca808x_get_features,
-- .config_aneg = at803x_config_aneg,
-+ .config_aneg = qca808x_config_aneg,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .read_status = qca808x_read_status,
diff --git a/target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch b/target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch
deleted file mode 100644
index 54ca3bdfc8..0000000000
--- a/target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 38eb804e8458ba181a03a0498ce4bf84eebd1931 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 14 Dec 2023 01:44:32 +0100
-Subject: [PATCH 2/2] net: phy: at803x: make read specific status function more
- generic
-
-Rework read specific status function to be more generic. The function
-apply different speed mask based on the PHY ID. Make it more generic by
-adding an additional arg to pass the specific speed (ss) mask and use
-the provided mask to parse the speed value.
-
-This is needed to permit an easier deatch of qca808x code from the
-at803x driver.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 26 ++++++++++++++++++--------
- 1 file changed, 18 insertions(+), 8 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -301,6 +301,11 @@ static struct at803x_hw_stat qca83xx_hw_
- { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
- };
-
-+struct at803x_ss_mask {
-+ u16 speed_mask;
-+ u8 speed_shift;
-+};
-+
- struct at803x_priv {
- int flags;
- u16 clk_25m_reg;
-@@ -921,7 +926,8 @@ static void at803x_link_change_notify(st
- }
- }
-
--static int at803x_read_specific_status(struct phy_device *phydev)
-+static int at803x_read_specific_status(struct phy_device *phydev,
-+ struct at803x_ss_mask ss_mask)
- {
- int ss;
-
-@@ -940,11 +946,8 @@ static int at803x_read_specific_status(s
- if (sfc < 0)
- return sfc;
-
-- /* qca8081 takes the different bits for speed value from at803x */
-- if (phydev->drv->phy_id == QCA8081_PHY_ID)
-- speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss);
-- else
-- speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss);
-+ speed = ss & ss_mask.speed_mask;
-+ speed >>= ss_mask.speed_shift;
-
- switch (speed) {
- case AT803X_SS_SPEED_10:
-@@ -989,6 +992,7 @@ static int at803x_read_specific_status(s
- static int at803x_read_status(struct phy_device *phydev)
- {
- struct at803x_priv *priv = phydev->priv;
-+ struct at803x_ss_mask ss_mask = { 0 };
- int err, old_link = phydev->link;
-
- if (priv->is_1000basex)
-@@ -1012,7 +1016,9 @@ static int at803x_read_status(struct phy
- if (err < 0)
- return err;
-
-- err = at803x_read_specific_status(phydev);
-+ ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
-+ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
-+ err = at803x_read_specific_status(phydev, ss_mask);
- if (err < 0)
- return err;
-
-@@ -1869,6 +1875,7 @@ static int qca808x_config_init(struct ph
-
- static int qca808x_read_status(struct phy_device *phydev)
- {
-+ struct at803x_ss_mask ss_mask = { 0 };
- int ret;
-
- ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
-@@ -1882,7 +1889,10 @@ static int qca808x_read_status(struct ph
- if (ret)
- return ret;
-
-- ret = at803x_read_specific_status(phydev);
-+ /* qca8081 takes the different bits for speed value from at803x */
-+ ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
-+ ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
-+ ret = at803x_read_specific_status(phydev, ss_mask);
- if (ret < 0)
- return ret;
-
diff --git a/target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch b/target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch
deleted file mode 100644
index 8097a33e49..0000000000
--- a/target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From fc9d7264ddc32eaa647d6bfcdc25cdf9f786fde0 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 18 Dec 2023 00:27:39 +0100
-Subject: [PATCH 1/2] net: phy: at803x: remove extra space after cast
-
-Remove extra space after cast as reported by checkpatch to keep code
-clean.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20231217232739.27065-1-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/at803x.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -462,7 +462,7 @@ static int at803x_set_wol(struct phy_dev
- if (!ndev)
- return -ENODEV;
-
-- mac = (const u8 *) ndev->dev_addr;
-+ mac = (const u8 *)ndev->dev_addr;
-
- if (!is_valid_ether_addr(mac))
- return -EINVAL;
diff --git a/target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch b/target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch
deleted file mode 100644
index b8d4591087..0000000000
--- a/target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 3ab5720881a924fb6405d9e6a3b09f1026467c47 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 18 Dec 2023 00:25:08 +0100
-Subject: [PATCH 2/2] net: phy: at803x: replace msleep(1) with usleep_range
-
-Replace msleep(1) with usleep_range as suggested by timers-howto guide.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20231217232508.26470-1-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/at803x.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -916,9 +916,9 @@ static void at803x_link_change_notify(st
- at803x_context_save(phydev, &context);
-
- phy_device_reset(phydev, 1);
-- msleep(1);
-+ usleep_range(1000, 2000);
- phy_device_reset(phydev, 0);
-- msleep(1);
-+ usleep_range(1000, 2000);
-
- at803x_context_restore(phydev, &context);
-
-@@ -1733,7 +1733,7 @@ static int qca83xx_resume(struct phy_dev
- if (ret)
- return ret;
-
-- msleep(1);
-+ usleep_range(1000, 2000);
-
- return 0;
- }
diff --git a/target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch b/target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch
deleted file mode 100644
index 776b7bb43f..0000000000
--- a/target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 7961ef1fa10ec35ad6923fb5751877116e4b035b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 19 Dec 2023 21:21:24 +0100
-Subject: [PATCH] net: phy: at803x: better align function varibles to open
- parenthesis
-
-Better align function variables to open parenthesis as suggested by
-checkpatch script for qca808x function to make code cleaner.
-
-For cable_test_get_status function some additional rework was needed to
-handle too long functions.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 67 ++++++++++++++++++++++------------------
- 1 file changed, 37 insertions(+), 30 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1781,27 +1781,27 @@ static int qca808x_phy_fast_retrain_conf
- return ret;
-
- phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
-- QCA808X_TOP_OPTION1_DATA);
-+ QCA808X_TOP_OPTION1_DATA);
- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
-- QCA808X_MSE_THRESHOLD_20DB_VALUE);
-+ QCA808X_MSE_THRESHOLD_20DB_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
-- QCA808X_MSE_THRESHOLD_17DB_VALUE);
-+ QCA808X_MSE_THRESHOLD_17DB_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
-- QCA808X_MSE_THRESHOLD_27DB_VALUE);
-+ QCA808X_MSE_THRESHOLD_27DB_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
-- QCA808X_MSE_THRESHOLD_28DB_VALUE);
-+ QCA808X_MSE_THRESHOLD_28DB_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
-- QCA808X_MMD3_DEBUG_1_VALUE);
-+ QCA808X_MMD3_DEBUG_1_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
-- QCA808X_MMD3_DEBUG_4_VALUE);
-+ QCA808X_MMD3_DEBUG_4_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
-- QCA808X_MMD3_DEBUG_5_VALUE);
-+ QCA808X_MMD3_DEBUG_5_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
-- QCA808X_MMD3_DEBUG_3_VALUE);
-+ QCA808X_MMD3_DEBUG_3_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
-- QCA808X_MMD3_DEBUG_6_VALUE);
-+ QCA808X_MMD3_DEBUG_6_VALUE);
- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
-- QCA808X_MMD3_DEBUG_2_VALUE);
-+ QCA808X_MMD3_DEBUG_2_VALUE);
-
- return 0;
- }
-@@ -1838,13 +1838,14 @@ static int qca808x_config_init(struct ph
-
- /* Active adc&vga on 802.3az for the link 1000M and 100M */
- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
-- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
-+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
- if (ret)
- return ret;
-
- /* Adjust the threshold on 802.3az for the link 1000M */
- ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
-- QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, QCA808X_MMD3_AZ_TRAINING_VAL);
-+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
-+ QCA808X_MMD3_AZ_TRAINING_VAL);
- if (ret)
- return ret;
-
-@@ -1870,7 +1871,8 @@ static int qca808x_config_init(struct ph
-
- /* Configure adc threshold as 100mv for the link 10M */
- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
-- QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
-+ QCA808X_ADC_THRESHOLD_MASK,
-+ QCA808X_ADC_THRESHOLD_100MV);
- }
-
- static int qca808x_read_status(struct phy_device *phydev)
-@@ -1883,7 +1885,7 @@ static int qca808x_read_status(struct ph
- return ret;
-
- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
-- ret & MDIO_AN_10GBT_STAT_LP2_5G);
-+ ret & MDIO_AN_10GBT_STAT_LP2_5G);
-
- ret = genphy_read_status(phydev);
- if (ret)
-@@ -1913,7 +1915,7 @@ static int qca808x_read_status(struct ph
- */
- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-- qca808x_is_prefer_master(phydev)) {
-+ qca808x_is_prefer_master(phydev)) {
- qca808x_phy_ms_seed_enable(phydev, false);
- } else {
- qca808x_phy_ms_seed_enable(phydev, true);
-@@ -2070,18 +2072,22 @@ static int qca808x_cable_test_get_status
- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
- qca808x_cable_test_result_trans(pair_d));
-
-- if (qca808x_cdt_fault_length_valid(pair_a))
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A,
-- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A));
-- if (qca808x_cdt_fault_length_valid(pair_b))
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B,
-- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B));
-- if (qca808x_cdt_fault_length_valid(pair_c))
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C,
-- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C));
-- if (qca808x_cdt_fault_length_valid(pair_d))
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D,
-- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D));
-+ if (qca808x_cdt_fault_length_valid(pair_a)) {
-+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A);
-+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-+ }
-+ if (qca808x_cdt_fault_length_valid(pair_b)) {
-+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B);
-+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-+ }
-+ if (qca808x_cdt_fault_length_valid(pair_c)) {
-+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C);
-+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-+ }
-+ if (qca808x_cdt_fault_length_valid(pair_d)) {
-+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D);
-+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-+ }
-
- *finished = true;
-
-@@ -2148,8 +2154,9 @@ static void qca808x_link_change_notify(s
- * the interface device address is always phy address added by 1.
- */
- mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
-- MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
-- QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
-+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
-+ QCA8081_PHY_FIFO_RSTN,
-+ phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
- }
-
- static struct phy_driver at803x_driver[] = {
diff --git a/target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch b/target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch
deleted file mode 100644
index d7196da46e..0000000000
--- a/target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 22eb276098da820d9440fad22901f9b74ed4d659 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 4 Jan 2024 22:30:38 +0100
-Subject: [PATCH 1/4] net: phy: at803x: generalize cdt fault length function
-
-Generalize cable test fault length function since they all base on the
-same magic values (already reverse engineered to understand the meaning
-of it) to have consistenct values on every PHY.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 13 ++++++-------
- 1 file changed, 6 insertions(+), 7 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1192,10 +1192,8 @@ static bool at803x_cdt_fault_length_vali
- return false;
- }
-
--static int at803x_cdt_fault_length(u16 status)
-+static int at803x_cdt_fault_length(int dt)
- {
-- int dt;
--
- /* According to the datasheet the distance to the fault is
- * DELTA_TIME * 0.824 meters.
- *
-@@ -1211,8 +1209,6 @@ static int at803x_cdt_fault_length(u16 s
- * With a VF of 0.69 we get the factor 0.824 mentioned in the
- * datasheet.
- */
-- dt = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, status);
--
- return (dt * 824) / 10;
- }
-
-@@ -1265,9 +1261,11 @@ static int at803x_cable_test_one_pair(st
- ethnl_cable_test_result(phydev, ethtool_pair[pair],
- at803x_cable_test_result_trans(val));
-
-- if (at803x_cdt_fault_length_valid(val))
-+ if (at803x_cdt_fault_length_valid(val)) {
-+ val = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, val);
- ethnl_cable_test_fault_length(phydev, ethtool_pair[pair],
- at803x_cdt_fault_length(val));
-+ }
-
- return 1;
- }
-@@ -1992,7 +1990,8 @@ static int qca808x_cdt_fault_length(stru
- if (val < 0)
- return val;
-
-- return (FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val) * 824) / 10;
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val);
-+ return at803x_cdt_fault_length(val);
- }
-
- static int qca808x_cable_test_start(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch b/target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch
deleted file mode 100644
index 5d38fe7e91..0000000000
--- a/target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From e0e9ada1df6133513249861c1d91c1dbefd9383b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 4 Jan 2024 22:30:39 +0100
-Subject: [PATCH 2/4] net: phy: at803x: refactor qca808x cable test get status
- function
-
-Refactor qca808x cable test get status function to remove code
-duplication and clean things up.
-
-The same logic is applied to each pair hence it can be generalized and
-moved to a common function.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 80 ++++++++++++++++++++++++----------------
- 1 file changed, 49 insertions(+), 31 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -2035,10 +2035,43 @@ static int qca808x_cable_test_start(stru
- return 0;
- }
-
-+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
-+ u16 status)
-+{
-+ u16 pair_code;
-+ int length;
-+
-+ switch (pair) {
-+ case ETHTOOL_A_CABLE_PAIR_A:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_B:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_C:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_D:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ ethnl_cable_test_result(phydev, pair,
-+ qca808x_cable_test_result_trans(pair_code));
-+
-+ if (qca808x_cdt_fault_length_valid(pair_code)) {
-+ length = qca808x_cdt_fault_length(phydev, pair);
-+ ethnl_cable_test_fault_length(phydev, pair, length);
-+ }
-+
-+ return 0;
-+}
-+
- static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
- {
- int ret, val;
-- int pair_a, pair_b, pair_c, pair_d;
-
- *finished = false;
-
-@@ -2057,36 +2090,21 @@ static int qca808x_cable_test_get_status
- if (val < 0)
- return val;
-
-- pair_a = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, val);
-- pair_b = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, val);
-- pair_c = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, val);
-- pair_d = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, val);
--
-- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
-- qca808x_cable_test_result_trans(pair_a));
-- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
-- qca808x_cable_test_result_trans(pair_b));
-- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C,
-- qca808x_cable_test_result_trans(pair_c));
-- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
-- qca808x_cable_test_result_trans(pair_d));
--
-- if (qca808x_cdt_fault_length_valid(pair_a)) {
-- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A);
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-- }
-- if (qca808x_cdt_fault_length_valid(pair_b)) {
-- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B);
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-- }
-- if (qca808x_cdt_fault_length_valid(pair_c)) {
-- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C);
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-- }
-- if (qca808x_cdt_fault_length_valid(pair_d)) {
-- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D);
-- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-- }
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-+ if (ret)
-+ return ret;
-
- *finished = true;
-
diff --git a/target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch b/target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch
deleted file mode 100644
index d5793860a9..0000000000
--- a/target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-From ea73e5ea442ee2aade67b1fb1233ccb3cbea2ceb Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 4 Jan 2024 22:30:40 +0100
-Subject: [PATCH 3/4] net: phy: at803x: add support for cdt cross short test
- for qca808x
-
-QCA808x PHY Family supports Cable Diagnostic Test also for Cross Pair
-Short.
-
-Add all the define to make enable and support these additional tests.
-
-Cross Short test was previously disabled by default, this is now changed
-and enabled by default. In this mode, the mask changed a bit and length
-is shifted based on the fault condition.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 86 ++++++++++++++++++++++++++++++++--------
- 1 file changed, 69 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -254,6 +254,7 @@
-
- #define QCA808X_CDT_ENABLE_TEST BIT(15)
- #define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
-+#define QCA808X_CDT_STATUS BIT(11)
- #define QCA808X_CDT_LENGTH_UNIT BIT(10)
-
- #define QCA808X_MMD3_CDT_STATUS 0x8064
-@@ -261,16 +262,44 @@
- #define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
- #define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
- #define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
--#define QCA808X_CDT_DIAG_LENGTH GENMASK(7, 0)
-+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
-+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
-
- #define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
- #define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
- #define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
- #define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
--#define QCA808X_CDT_STATUS_STAT_FAIL 0
--#define QCA808X_CDT_STATUS_STAT_NORMAL 1
--#define QCA808X_CDT_STATUS_STAT_OPEN 2
--#define QCA808X_CDT_STATUS_STAT_SHORT 3
-+
-+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
-+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
-+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
-+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
-+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
-+
-+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
-+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
-+
-+/* NORMAL are MDI with type set to 0 */
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+
-+/* Added for reference of existence but should be handled by wait_for_completion already */
-+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
-
- /* QCA808X 1G chip type */
- #define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
-@@ -1941,8 +1970,17 @@ static int qca808x_soft_reset(struct phy
- static bool qca808x_cdt_fault_length_valid(int cdt_code)
- {
- switch (cdt_code) {
-- case QCA808X_CDT_STATUS_STAT_SHORT:
-- case QCA808X_CDT_STATUS_STAT_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
- return true;
- default:
- return false;
-@@ -1954,17 +1992,28 @@ static int qca808x_cable_test_result_tra
- switch (cdt_code) {
- case QCA808X_CDT_STATUS_STAT_NORMAL:
- return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-- case QCA808X_CDT_STATUS_STAT_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-- case QCA808X_CDT_STATUS_STAT_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
- case QCA808X_CDT_STATUS_STAT_FAIL:
- default:
- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
- }
- }
-
--static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair)
-+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
-+ int result)
- {
- int val;
- u32 cdt_length_reg = 0;
-@@ -1990,7 +2039,11 @@ static int qca808x_cdt_fault_length(stru
- if (val < 0)
- return val;
-
-- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val);
-+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
-+ else
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
-+
- return at803x_cdt_fault_length(val);
- }
-
-@@ -2038,8 +2091,8 @@ static int qca808x_cable_test_start(stru
- static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
- u16 status)
- {
-+ int length, result;
- u16 pair_code;
-- int length;
-
- switch (pair) {
- case ETHTOOL_A_CABLE_PAIR_A:
-@@ -2058,11 +2111,11 @@ static int qca808x_cable_test_get_pair_s
- return -EINVAL;
- }
-
-- ethnl_cable_test_result(phydev, pair,
-- qca808x_cable_test_result_trans(pair_code));
-+ result = qca808x_cable_test_result_trans(pair_code);
-+ ethnl_cable_test_result(phydev, pair, result);
-
- if (qca808x_cdt_fault_length_valid(pair_code)) {
-- length = qca808x_cdt_fault_length(phydev, pair);
-+ length = qca808x_cdt_fault_length(phydev, pair, result);
- ethnl_cable_test_fault_length(phydev, pair, length);
- }
-
-@@ -2076,8 +2129,7 @@ static int qca808x_cable_test_get_status
- *finished = false;
-
- val = QCA808X_CDT_ENABLE_TEST |
-- QCA808X_CDT_LENGTH_UNIT |
-- QCA808X_CDT_INTER_CHECK_DIS;
-+ QCA808X_CDT_LENGTH_UNIT;
- ret = at803x_cdt_start(phydev, val);
- if (ret)
- return ret;
diff --git a/target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch b/target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch
deleted file mode 100644
index c146e502fe..0000000000
--- a/target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From c34d9452d4e5d98a655d7b625e85466320885416 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 4 Jan 2024 22:30:41 +0100
-Subject: [PATCH 4/4] net: phy: at803x: make read_status more generic
-
-Make read_status more generic in preparation on moving it to shared
-library as other PHY Family Driver will have the exact same
-implementation.
-
-The only specific part was a check for AR8031/33 if 1000basex was used.
-The check is moved to a dedicated function specific for those PHYs.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1020,13 +1020,9 @@ static int at803x_read_specific_status(s
-
- static int at803x_read_status(struct phy_device *phydev)
- {
-- struct at803x_priv *priv = phydev->priv;
- struct at803x_ss_mask ss_mask = { 0 };
- int err, old_link = phydev->link;
-
-- if (priv->is_1000basex)
-- return genphy_c37_read_status(phydev);
--
- /* Update the link, but return if there was an error */
- err = genphy_update_link(phydev);
- if (err)
-@@ -1618,6 +1614,17 @@ static int at8031_config_intr(struct phy
- return at803x_config_intr(phydev);
- }
-
-+/* AR8031 and AR8033 share the same read status logic */
-+static int at8031_read_status(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+
-+ if (priv->is_1000basex)
-+ return genphy_c37_read_status(phydev);
-+
-+ return at803x_read_status(phydev);
-+}
-+
- /* AR8031 and AR8035 share the same cable test get status reg */
- static int at8031_cable_test_get_status(struct phy_device *phydev,
- bool *finished)
-@@ -2281,7 +2288,7 @@ static struct phy_driver at803x_driver[]
- .read_page = at803x_read_page,
- .write_page = at803x_write_page,
- .get_features = at803x_get_features,
-- .read_status = at803x_read_status,
-+ .read_status = at8031_read_status,
- .config_intr = at8031_config_intr,
- .handle_interrupt = at803x_handle_interrupt,
- .get_tunable = at803x_get_tunable,
diff --git a/target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch b/target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch
deleted file mode 100644
index 36675e7588..0000000000
--- a/target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch
+++ /dev/null
@@ -1,408 +0,0 @@
-From 7196062b64ee470b91015f3d2e82d225948258ea Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 25 Jan 2024 21:37:01 +0100
-Subject: [PATCH 5/5] net: phy: at803x: add LED support for qca808x
-
-Add LED support for QCA8081 PHY.
-
-Documentation for this LEDs PHY is very scarce even with NDA access
-to Documentation for OEMs. Only the blink pattern are documented and are
-very confusing most of the time. No documentation is present about
-forcing the LED on/off or to always blink.
-
-Those settings were reversed by poking the regs and trying to find the
-correct bits to trigger these modes. Some bits mode are not clear and
-maybe the documentation option are not 100% correct. For the sake of LED
-support the reversed option are enough to add support for current LED
-APIs.
-
-Supported HW control modes are:
-- tx
-- rx
-- link_10
-- link_100
-- link_1000
-- link_2500
-- half_duplex
-- full_duplex
-
-Also add support for LED polarity set to set LED polarity to active
-high or low. QSDK sets this value to high by default but PHY reset value
-doesn't have this enabled by default.
-
-QSDK also sets 2 additional bits but their usage is not clear, info about
-this is added in the header. It was verified that for correct function
-of the LED if active high is needed, only BIT 6 is needed.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240125203702.4552-6-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/at803x.c | 327 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 327 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -301,6 +301,87 @@
- /* Added for reference of existence but should be handled by wait_for_completion already */
- #define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
-
-+#define QCA808X_MMD7_LED_GLOBAL 0x8073
-+#define QCA808X_LED_BLINK_1 GENMASK(11, 6)
-+#define QCA808X_LED_BLINK_2 GENMASK(5, 0)
-+/* Values are the same for both BLINK_1 and BLINK_2 */
-+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3)
-+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
-+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
-+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
-+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
-+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
-+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
-+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
-+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
-+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0)
-+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
-+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
-+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
-+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
-+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
-+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
-+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
-+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
-+
-+#define QCA808X_MMD7_LED2_CTRL 0x8074
-+#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075
-+#define QCA808X_MMD7_LED1_CTRL 0x8076
-+#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077
-+#define QCA808X_MMD7_LED0_CTRL 0x8078
-+#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2))
-+
-+/* LED hw control pattern is the same for every LED */
-+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0)
-+#define QCA808X_LED_SPEED2500_ON BIT(15)
-+#define QCA808X_LED_SPEED2500_BLINK BIT(14)
-+/* Follow blink trigger even if duplex or speed condition doesn't match */
-+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13)
-+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12)
-+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11)
-+#define QCA808X_LED_TX_BLINK BIT(10)
-+#define QCA808X_LED_RX_BLINK BIT(9)
-+#define QCA808X_LED_TX_ON_10MS BIT(8)
-+#define QCA808X_LED_RX_ON_10MS BIT(7)
-+#define QCA808X_LED_SPEED1000_ON BIT(6)
-+#define QCA808X_LED_SPEED100_ON BIT(5)
-+#define QCA808X_LED_SPEED10_ON BIT(4)
-+#define QCA808X_LED_COLLISION_BLINK BIT(3)
-+#define QCA808X_LED_SPEED1000_BLINK BIT(2)
-+#define QCA808X_LED_SPEED100_BLINK BIT(1)
-+#define QCA808X_LED_SPEED10_BLINK BIT(0)
-+
-+#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079
-+#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2))
-+
-+/* LED force ctrl is the same for every LED
-+ * No documentation exist for this, not even internal one
-+ * with NDA as QCOM gives only info about configuring
-+ * hw control pattern rules and doesn't indicate any way
-+ * to force the LED to specific mode.
-+ * These define comes from reverse and testing and maybe
-+ * lack of some info or some info are not entirely correct.
-+ * For the basic LED control and hw control these finding
-+ * are enough to support LED control in all the required APIs.
-+ *
-+ * On doing some comparison with implementation with qca807x,
-+ * it was found that it's 1:1 equal to it and confirms all the
-+ * reverse done. It was also found further specification with the
-+ * force mode and the blink modes.
-+ */
-+#define QCA808X_LED_FORCE_EN BIT(15)
-+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13)
-+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
-+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
-+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
-+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
-+
-+#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a
-+/* QSDK sets by default 0x46 to this reg that sets BIT 6 for
-+ * LED to active high. It's not clear what BIT 3 and BIT 4 does.
-+ */
-+#define QCA808X_LED_ACTIVE_HIGH BIT(6)
-+
- /* QCA808X 1G chip type */
- #define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
- #define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
-@@ -346,6 +427,7 @@ struct at803x_priv {
- struct regulator_dev *vddio_rdev;
- struct regulator_dev *vddh_rdev;
- u64 stats[ARRAY_SIZE(qca83xx_hw_stats)];
-+ int led_polarity_mode;
- };
-
- struct at803x_context {
-@@ -706,6 +788,9 @@ static int at803x_probe(struct phy_devic
- if (!priv)
- return -ENOMEM;
-
-+ /* Init LED polarity mode to -1 */
-+ priv->led_polarity_mode = -1;
-+
- phydev->priv = priv;
-
- ret = at803x_parse_dt(phydev);
-@@ -2235,6 +2320,242 @@ static void qca808x_link_change_notify(s
- phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
- }
-
-+static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
-+ u16 *offload_trigger)
-+{
-+ /* Parsing specific to netdev trigger */
-+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
-+ *offload_trigger |= QCA808X_LED_TX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
-+ *offload_trigger |= QCA808X_LED_RX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED10_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED100_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED1000_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED2500_ON;
-+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
-+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
-+
-+ if (rules && !*offload_trigger)
-+ return -EOPNOTSUPP;
-+
-+ /* Enable BLINK_CHECK_BYPASS by default to make the LED
-+ * blink even with duplex or speed mode not enabled.
-+ */
-+ *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS;
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN);
-+}
-+
-+static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 offload_trigger = 0;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ return qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-+}
-+
-+static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 reg, offload_trigger = 0;
-+ int ret;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_led_hw_control_enable(phydev, index);
-+ if (ret)
-+ return ret;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_PATTERN_MASK,
-+ offload_trigger);
-+}
-+
-+static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+ int val;
-+
-+ if (index > 2)
-+ return false;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+
-+ return !(val & QCA808X_LED_FORCE_EN);
-+}
-+
-+static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
-+ unsigned long *rules)
-+{
-+ u16 reg;
-+ int val;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ /* Check if we have hw control enabled */
-+ if (qca808x_led_hw_control_status(phydev, index))
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+ if (val & QCA808X_LED_TX_BLINK)
-+ set_bit(TRIGGER_NETDEV_TX, rules);
-+ if (val & QCA808X_LED_RX_BLINK)
-+ set_bit(TRIGGER_NETDEV_RX, rules);
-+ if (val & QCA808X_LED_SPEED10_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+ if (val & QCA808X_LED_SPEED100_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+ if (val & QCA808X_LED_SPEED1000_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+ if (val & QCA808X_LED_SPEED2500_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_2500, rules);
-+ if (val & QCA808X_LED_HALF_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-+ if (val & QCA808X_LED_FULL_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_PATTERN_MASK);
-+}
-+
-+static int qca808x_led_brightness_set(struct phy_device *phydev,
-+ u8 index, enum led_brightness value)
-+{
-+ u16 reg;
-+ int ret;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ if (!value) {
-+ ret = qca808x_led_hw_control_reset(phydev, index);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON :
-+ QCA808X_LED_FORCE_OFF);
-+}
-+
-+static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ int ret;
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ /* Set blink to 50% off, 50% on at 4Hz by default */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
-+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
-+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
-+ if (ret)
-+ return ret;
-+
-+ /* We use BLINK_1 for normal blinking */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
-+ if (ret)
-+ return ret;
-+
-+ /* We set blink to 4Hz, aka 250ms */
-+ *delay_on = 250 / 2;
-+ *delay_off = 250 / 2;
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
-+ unsigned long modes)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ bool active_low = false;
-+ u32 mode;
-+
-+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-+ switch (mode) {
-+ case PHY_LED_ACTIVE_LOW:
-+ active_low = true;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ /* PHY polarity is global and can't be set per LED.
-+ * To detect this, check if last requested polarity mode
-+ * match the new one.
-+ */
-+ if (priv->led_polarity_mode >= 0 &&
-+ priv->led_polarity_mode != active_low) {
-+ phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Save the last PHY polarity mode */
-+ priv->led_polarity_mode = active_low;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN,
-+ QCA808X_MMD7_LED_POLARITY_CTRL,
-+ QCA808X_LED_ACTIVE_HIGH,
-+ active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
-+}
-+
- static struct phy_driver at803x_driver[] = {
- {
- /* Qualcomm Atheros AR8035 */
-@@ -2411,6 +2732,12 @@ static struct phy_driver at803x_driver[]
- .cable_test_start = qca808x_cable_test_start,
- .cable_test_get_status = qca808x_cable_test_get_status,
- .link_change_notify = qca808x_link_change_notify,
-+ .led_brightness_set = qca808x_led_brightness_set,
-+ .led_blink_set = qca808x_led_blink_set,
-+ .led_hw_is_supported = qca808x_led_hw_is_supported,
-+ .led_hw_control_set = qca808x_led_hw_control_set,
-+ .led_hw_control_get = qca808x_led_hw_control_get,
-+ .led_polarity_set = qca808x_led_polarity_set,
- }, };
-
- module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch b/target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch
deleted file mode 100644
index 8c9babea7b..0000000000
--- a/target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch
+++ /dev/null
@@ -1,5598 +0,0 @@
-From 9e56ff53b4115875667760445b028357848b4748 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 Jan 2024 15:15:19 +0100
-Subject: [PATCH 1/5] net: phy: move at803x PHY driver to dedicated directory
-
-In preparation for addition of other Qcom PHY and to tidy things up,
-move the at803x PHY driver to dedicated directory.
-
-The same order in the Kconfig selection is saved.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240129141600.2592-2-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/Kconfig | 7 +------
- drivers/net/phy/Makefile | 2 +-
- drivers/net/phy/qcom/Kconfig | 7 +++++++
- drivers/net/phy/qcom/Makefile | 2 ++
- drivers/net/phy/{ => qcom}/at803x.c | 0
- 5 files changed, 11 insertions(+), 7 deletions(-)
- create mode 100644 drivers/net/phy/qcom/Kconfig
- create mode 100644 drivers/net/phy/qcom/Makefile
- rename drivers/net/phy/{ => qcom}/at803x.c (100%)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -277,12 +277,7 @@ config NXP_TJA11XX_PHY
- help
- Currently supports the NXP TJA1100 and TJA1101 PHY.
-
--config AT803X_PHY
-- tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs"
-- depends on REGULATOR
-- help
-- Currently supports the AR8030, AR8031, AR8033, AR8035 and internal
-- QCA8337(Internal qca8k PHY) model
-+source "drivers/net/phy/qcom/Kconfig"
-
- config QSEMI_PHY
- tristate "Quality Semiconductor PHYs"
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -34,7 +34,6 @@ obj-$(CONFIG_ADIN_PHY) += adin.o
- obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
- obj-$(CONFIG_AMD_PHY) += amd.o
- obj-$(CONFIG_AQUANTIA_PHY) += aquantia/
--obj-$(CONFIG_AT803X_PHY) += at803x.o
- obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
- obj-$(CONFIG_BCM54140_PHY) += bcm54140.o
- obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
-@@ -75,6 +74,7 @@ obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm
- obj-$(CONFIG_NATIONAL_PHY) += national.o
- obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp-c45-tja11xx.o
- obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o
-+obj-y += qcom/
- obj-$(CONFIG_QSEMI_PHY) += qsemi.o
- obj-$(CONFIG_REALTEK_PHY) += realtek.o
- obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
---- /dev/null
-+++ b/drivers/net/phy/qcom/Kconfig
-@@ -0,0 +1,7 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+config AT803X_PHY
-+ tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs"
-+ depends on REGULATOR
-+ help
-+ Currently supports the AR8030, AR8031, AR8033, AR8035 and internal
-+ QCA8337(Internal qca8k PHY) model
---- /dev/null
-+++ b/drivers/net/phy/qcom/Makefile
-@@ -0,0 +1,2 @@
-+# SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_AT803X_PHY) += at803x.o
---- a/drivers/net/phy/at803x.c
-+++ /dev/null
-@@ -1,2759 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0+
--/*
-- * drivers/net/phy/at803x.c
-- *
-- * Driver for Qualcomm Atheros AR803x PHY
-- *
-- * Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
-- */
--
--#include <linux/phy.h>
--#include <linux/module.h>
--#include <linux/string.h>
--#include <linux/netdevice.h>
--#include <linux/etherdevice.h>
--#include <linux/ethtool_netlink.h>
--#include <linux/bitfield.h>
--#include <linux/regulator/of_regulator.h>
--#include <linux/regulator/driver.h>
--#include <linux/regulator/consumer.h>
--#include <linux/of.h>
--#include <linux/phylink.h>
--#include <linux/sfp.h>
--#include <dt-bindings/net/qca-ar803x.h>
--
--#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
--#define AT803X_SFC_ASSERT_CRS BIT(11)
--#define AT803X_SFC_FORCE_LINK BIT(10)
--#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5)
--#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3
--#define AT803X_SFC_MANUAL_MDIX 0x1
--#define AT803X_SFC_MANUAL_MDI 0x0
--#define AT803X_SFC_SQE_TEST BIT(2)
--#define AT803X_SFC_POLARITY_REVERSAL BIT(1)
--#define AT803X_SFC_DISABLE_JABBER BIT(0)
--
--#define AT803X_SPECIFIC_STATUS 0x11
--#define AT803X_SS_SPEED_MASK GENMASK(15, 14)
--#define AT803X_SS_SPEED_1000 2
--#define AT803X_SS_SPEED_100 1
--#define AT803X_SS_SPEED_10 0
--#define AT803X_SS_DUPLEX BIT(13)
--#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11)
--#define AT803X_SS_MDIX BIT(6)
--
--#define QCA808X_SS_SPEED_MASK GENMASK(9, 7)
--#define QCA808X_SS_SPEED_2500 4
--
--#define AT803X_INTR_ENABLE 0x12
--#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
--#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
--#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13)
--#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12)
--#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11)
--#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10)
--#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8)
--#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7)
--#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5)
--#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1)
--#define AT803X_INTR_ENABLE_WOL BIT(0)
--
--#define AT803X_INTR_STATUS 0x13
--
--#define AT803X_SMART_SPEED 0x14
--#define AT803X_SMART_SPEED_ENABLE BIT(5)
--#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2)
--#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1)
--#define AT803X_CDT 0x16
--#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8)
--#define AT803X_CDT_ENABLE_TEST BIT(0)
--#define AT803X_CDT_STATUS 0x1c
--#define AT803X_CDT_STATUS_STAT_NORMAL 0
--#define AT803X_CDT_STATUS_STAT_SHORT 1
--#define AT803X_CDT_STATUS_STAT_OPEN 2
--#define AT803X_CDT_STATUS_STAT_FAIL 3
--#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8)
--#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0)
--#define AT803X_LED_CONTROL 0x18
--
--#define AT803X_PHY_MMD3_WOL_CTRL 0x8012
--#define AT803X_WOL_EN BIT(5)
--#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
--#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
--#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
--#define AT803X_REG_CHIP_CONFIG 0x1f
--#define AT803X_BT_BX_REG_SEL 0x8000
--
--#define AT803X_DEBUG_ADDR 0x1D
--#define AT803X_DEBUG_DATA 0x1E
--
--#define AT803X_MODE_CFG_MASK 0x0F
--#define AT803X_MODE_CFG_BASET_RGMII 0x00
--#define AT803X_MODE_CFG_BASET_SGMII 0x01
--#define AT803X_MODE_CFG_BX1000_RGMII_50OHM 0x02
--#define AT803X_MODE_CFG_BX1000_RGMII_75OHM 0x03
--#define AT803X_MODE_CFG_BX1000_CONV_50OHM 0x04
--#define AT803X_MODE_CFG_BX1000_CONV_75OHM 0x05
--#define AT803X_MODE_CFG_FX100_RGMII_50OHM 0x06
--#define AT803X_MODE_CFG_FX100_CONV_50OHM 0x07
--#define AT803X_MODE_CFG_RGMII_AUTO_MDET 0x0B
--#define AT803X_MODE_CFG_FX100_RGMII_75OHM 0x0E
--#define AT803X_MODE_CFG_FX100_CONV_75OHM 0x0F
--
--#define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
--#define AT803X_PSSR_MR_AN_COMPLETE 0x0200
--
--#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00
--#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
--#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
--#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
--
--#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05
--#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
--
--#define AT803X_DEBUG_REG_HIB_CTRL 0x0b
--#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10)
--#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
--#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15)
--
--#define AT803X_DEBUG_REG_3C 0x3C
--
--#define AT803X_DEBUG_REG_GREEN 0x3D
--#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
--
--#define AT803X_DEBUG_REG_1F 0x1F
--#define AT803X_DEBUG_PLL_ON BIT(2)
--#define AT803X_DEBUG_RGMII_1V8 BIT(3)
--
--#define MDIO_AZ_DEBUG 0x800D
--
--/* AT803x supports either the XTAL input pad, an internal PLL or the
-- * DSP as clock reference for the clock output pad. The XTAL reference
-- * is only used for 25 MHz output, all other frequencies need the PLL.
-- * The DSP as a clock reference is used in synchronous ethernet
-- * applications.
-- *
-- * By default the PLL is only enabled if there is a link. Otherwise
-- * the PHY will go into low power state and disabled the PLL. You can
-- * set the PLL_ON bit (see debug register 0x1f) to keep the PLL always
-- * enabled.
-- */
--#define AT803X_MMD7_CLK25M 0x8016
--#define AT803X_CLK_OUT_MASK GENMASK(4, 2)
--#define AT803X_CLK_OUT_25MHZ_XTAL 0
--#define AT803X_CLK_OUT_25MHZ_DSP 1
--#define AT803X_CLK_OUT_50MHZ_PLL 2
--#define AT803X_CLK_OUT_50MHZ_DSP 3
--#define AT803X_CLK_OUT_62_5MHZ_PLL 4
--#define AT803X_CLK_OUT_62_5MHZ_DSP 5
--#define AT803X_CLK_OUT_125MHZ_PLL 6
--#define AT803X_CLK_OUT_125MHZ_DSP 7
--
--/* The AR8035 has another mask which is compatible with the AR8031/AR8033 mask
-- * but doesn't support choosing between XTAL/PLL and DSP.
-- */
--#define AT8035_CLK_OUT_MASK GENMASK(4, 3)
--
--#define AT803X_CLK_OUT_STRENGTH_MASK GENMASK(8, 7)
--#define AT803X_CLK_OUT_STRENGTH_FULL 0
--#define AT803X_CLK_OUT_STRENGTH_HALF 1
--#define AT803X_CLK_OUT_STRENGTH_QUARTER 2
--
--#define AT803X_DEFAULT_DOWNSHIFT 5
--#define AT803X_MIN_DOWNSHIFT 2
--#define AT803X_MAX_DOWNSHIFT 9
--
--#define AT803X_MMD3_SMARTEEE_CTL1 0x805b
--#define AT803X_MMD3_SMARTEEE_CTL2 0x805c
--#define AT803X_MMD3_SMARTEEE_CTL3 0x805d
--#define AT803X_MMD3_SMARTEEE_CTL3_LPI_EN BIT(8)
--
--#define ATH9331_PHY_ID 0x004dd041
--#define ATH8030_PHY_ID 0x004dd076
--#define ATH8031_PHY_ID 0x004dd074
--#define ATH8032_PHY_ID 0x004dd023
--#define ATH8035_PHY_ID 0x004dd072
--#define AT8030_PHY_ID_MASK 0xffffffef
--
--#define QCA8081_PHY_ID 0x004dd101
--
--#define QCA8327_A_PHY_ID 0x004dd033
--#define QCA8327_B_PHY_ID 0x004dd034
--#define QCA8337_PHY_ID 0x004dd036
--#define QCA9561_PHY_ID 0x004dd042
--#define QCA8K_PHY_ID_MASK 0xffffffff
--
--#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0)
--
--#define AT803X_PAGE_FIBER 0
--#define AT803X_PAGE_COPPER 1
--
--/* don't turn off internal PLL */
--#define AT803X_KEEP_PLL_ENABLED BIT(0)
--#define AT803X_DISABLE_SMARTEEE BIT(1)
--
--/* disable hibernation mode */
--#define AT803X_DISABLE_HIBERNATION_MODE BIT(2)
--
--/* ADC threshold */
--#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80
--#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0)
--#define QCA808X_ADC_THRESHOLD_80MV 0
--#define QCA808X_ADC_THRESHOLD_100MV 0xf0
--#define QCA808X_ADC_THRESHOLD_200MV 0x0f
--#define QCA808X_ADC_THRESHOLD_300MV 0xff
--
--/* CLD control */
--#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007
--#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4)
--#define QCA808X_8023AZ_AFE_EN 0x90
--
--/* AZ control */
--#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008
--#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014
--#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E
--#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E
--#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020
--#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341
--
--#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c
--#define QCA808X_TOP_OPTION1_DATA 0x0
--
--#define QCA808X_PHY_MMD3_DEBUG_1 0xa100
--#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203
--#define QCA808X_PHY_MMD3_DEBUG_2 0xa101
--#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad
--#define QCA808X_PHY_MMD3_DEBUG_3 0xa103
--#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698
--#define QCA808X_PHY_MMD3_DEBUG_4 0xa105
--#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001
--#define QCA808X_PHY_MMD3_DEBUG_5 0xa106
--#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111
--#define QCA808X_PHY_MMD3_DEBUG_6 0xa011
--#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85
--
--/* master/slave seed config */
--#define QCA808X_PHY_DEBUG_LOCAL_SEED 9
--#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1)
--#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2)
--#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32
--
--/* Hibernation yields lower power consumpiton in contrast with normal operation mode.
-- * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s.
-- */
--#define QCA808X_DBG_AN_TEST 0xb
--#define QCA808X_HIBERNATION_EN BIT(15)
--
--#define QCA808X_CDT_ENABLE_TEST BIT(15)
--#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
--#define QCA808X_CDT_STATUS BIT(11)
--#define QCA808X_CDT_LENGTH_UNIT BIT(10)
--
--#define QCA808X_MMD3_CDT_STATUS 0x8064
--#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
--#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
--#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
--#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
--#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
--#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
--
--#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
--#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
--#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
--#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
--
--#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
--#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
--#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
--#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
--#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
--
--#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
--#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
--#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
--#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
--
--/* NORMAL are MDI with type set to 0 */
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI1)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI1)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI2)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI2)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI3)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI3)
--
--/* Added for reference of existence but should be handled by wait_for_completion already */
--#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
--
--#define QCA808X_MMD7_LED_GLOBAL 0x8073
--#define QCA808X_LED_BLINK_1 GENMASK(11, 6)
--#define QCA808X_LED_BLINK_2 GENMASK(5, 0)
--/* Values are the same for both BLINK_1 and BLINK_2 */
--#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3)
--#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
--#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
--#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
--#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
--#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
--#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
--#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
--#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
--#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0)
--#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
--#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
--#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
--#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
--#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
--#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
--#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
--#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
--
--#define QCA808X_MMD7_LED2_CTRL 0x8074
--#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075
--#define QCA808X_MMD7_LED1_CTRL 0x8076
--#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077
--#define QCA808X_MMD7_LED0_CTRL 0x8078
--#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2))
--
--/* LED hw control pattern is the same for every LED */
--#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0)
--#define QCA808X_LED_SPEED2500_ON BIT(15)
--#define QCA808X_LED_SPEED2500_BLINK BIT(14)
--/* Follow blink trigger even if duplex or speed condition doesn't match */
--#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13)
--#define QCA808X_LED_FULL_DUPLEX_ON BIT(12)
--#define QCA808X_LED_HALF_DUPLEX_ON BIT(11)
--#define QCA808X_LED_TX_BLINK BIT(10)
--#define QCA808X_LED_RX_BLINK BIT(9)
--#define QCA808X_LED_TX_ON_10MS BIT(8)
--#define QCA808X_LED_RX_ON_10MS BIT(7)
--#define QCA808X_LED_SPEED1000_ON BIT(6)
--#define QCA808X_LED_SPEED100_ON BIT(5)
--#define QCA808X_LED_SPEED10_ON BIT(4)
--#define QCA808X_LED_COLLISION_BLINK BIT(3)
--#define QCA808X_LED_SPEED1000_BLINK BIT(2)
--#define QCA808X_LED_SPEED100_BLINK BIT(1)
--#define QCA808X_LED_SPEED10_BLINK BIT(0)
--
--#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079
--#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2))
--
--/* LED force ctrl is the same for every LED
-- * No documentation exist for this, not even internal one
-- * with NDA as QCOM gives only info about configuring
-- * hw control pattern rules and doesn't indicate any way
-- * to force the LED to specific mode.
-- * These define comes from reverse and testing and maybe
-- * lack of some info or some info are not entirely correct.
-- * For the basic LED control and hw control these finding
-- * are enough to support LED control in all the required APIs.
-- *
-- * On doing some comparison with implementation with qca807x,
-- * it was found that it's 1:1 equal to it and confirms all the
-- * reverse done. It was also found further specification with the
-- * force mode and the blink modes.
-- */
--#define QCA808X_LED_FORCE_EN BIT(15)
--#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13)
--#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
--#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
--#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
--#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
--
--#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a
--/* QSDK sets by default 0x46 to this reg that sets BIT 6 for
-- * LED to active high. It's not clear what BIT 3 and BIT 4 does.
-- */
--#define QCA808X_LED_ACTIVE_HIGH BIT(6)
--
--/* QCA808X 1G chip type */
--#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
--#define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
--
--#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072
--#define QCA8081_PHY_FIFO_RSTN BIT(11)
--
--MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
--MODULE_AUTHOR("Matus Ujhelyi");
--MODULE_LICENSE("GPL");
--
--enum stat_access_type {
-- PHY,
-- MMD
--};
--
--struct at803x_hw_stat {
-- const char *string;
-- u8 reg;
-- u32 mask;
-- enum stat_access_type access_type;
--};
--
--static struct at803x_hw_stat qca83xx_hw_stats[] = {
-- { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
-- { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
-- { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
--};
--
--struct at803x_ss_mask {
-- u16 speed_mask;
-- u8 speed_shift;
--};
--
--struct at803x_priv {
-- int flags;
-- u16 clk_25m_reg;
-- u16 clk_25m_mask;
-- u8 smarteee_lpi_tw_1g;
-- u8 smarteee_lpi_tw_100m;
-- bool is_fiber;
-- bool is_1000basex;
-- struct regulator_dev *vddio_rdev;
-- struct regulator_dev *vddh_rdev;
-- u64 stats[ARRAY_SIZE(qca83xx_hw_stats)];
-- int led_polarity_mode;
--};
--
--struct at803x_context {
-- u16 bmcr;
-- u16 advertise;
-- u16 control1000;
-- u16 int_enable;
-- u16 smart_speed;
-- u16 led_control;
--};
--
--static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data)
--{
-- int ret;
--
-- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-- if (ret < 0)
-- return ret;
--
-- return phy_write(phydev, AT803X_DEBUG_DATA, data);
--}
--
--static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
--{
-- int ret;
--
-- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-- if (ret < 0)
-- return ret;
--
-- return phy_read(phydev, AT803X_DEBUG_DATA);
--}
--
--static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
-- u16 clear, u16 set)
--{
-- u16 val;
-- int ret;
--
-- ret = at803x_debug_reg_read(phydev, reg);
-- if (ret < 0)
-- return ret;
--
-- val = ret & 0xffff;
-- val &= ~clear;
-- val |= set;
--
-- return phy_write(phydev, AT803X_DEBUG_DATA, val);
--}
--
--static int at803x_write_page(struct phy_device *phydev, int page)
--{
-- int mask;
-- int set;
--
-- if (page == AT803X_PAGE_COPPER) {
-- set = AT803X_BT_BX_REG_SEL;
-- mask = 0;
-- } else {
-- set = 0;
-- mask = AT803X_BT_BX_REG_SEL;
-- }
--
-- return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set);
--}
--
--static int at803x_read_page(struct phy_device *phydev)
--{
-- int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG);
--
-- if (ccr < 0)
-- return ccr;
--
-- if (ccr & AT803X_BT_BX_REG_SEL)
-- return AT803X_PAGE_COPPER;
--
-- return AT803X_PAGE_FIBER;
--}
--
--static int at803x_enable_rx_delay(struct phy_device *phydev)
--{
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0,
-- AT803X_DEBUG_RX_CLK_DLY_EN);
--}
--
--static int at803x_enable_tx_delay(struct phy_device *phydev)
--{
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0,
-- AT803X_DEBUG_TX_CLK_DLY_EN);
--}
--
--static int at803x_disable_rx_delay(struct phy_device *phydev)
--{
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- AT803X_DEBUG_RX_CLK_DLY_EN, 0);
--}
--
--static int at803x_disable_tx_delay(struct phy_device *phydev)
--{
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE,
-- AT803X_DEBUG_TX_CLK_DLY_EN, 0);
--}
--
--/* save relevant PHY registers to private copy */
--static void at803x_context_save(struct phy_device *phydev,
-- struct at803x_context *context)
--{
-- context->bmcr = phy_read(phydev, MII_BMCR);
-- context->advertise = phy_read(phydev, MII_ADVERTISE);
-- context->control1000 = phy_read(phydev, MII_CTRL1000);
-- context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE);
-- context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED);
-- context->led_control = phy_read(phydev, AT803X_LED_CONTROL);
--}
--
--/* restore relevant PHY registers from private copy */
--static void at803x_context_restore(struct phy_device *phydev,
-- const struct at803x_context *context)
--{
-- phy_write(phydev, MII_BMCR, context->bmcr);
-- phy_write(phydev, MII_ADVERTISE, context->advertise);
-- phy_write(phydev, MII_CTRL1000, context->control1000);
-- phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable);
-- phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed);
-- phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
--}
--
--static int at803x_set_wol(struct phy_device *phydev,
-- struct ethtool_wolinfo *wol)
--{
-- int ret, irq_enabled;
--
-- if (wol->wolopts & WAKE_MAGIC) {
-- struct net_device *ndev = phydev->attached_dev;
-- const u8 *mac;
-- unsigned int i;
-- static const unsigned int offsets[] = {
-- AT803X_LOC_MAC_ADDR_32_47_OFFSET,
-- AT803X_LOC_MAC_ADDR_16_31_OFFSET,
-- AT803X_LOC_MAC_ADDR_0_15_OFFSET,
-- };
--
-- if (!ndev)
-- return -ENODEV;
--
-- mac = (const u8 *)ndev->dev_addr;
--
-- if (!is_valid_ether_addr(mac))
-- return -EINVAL;
--
-- for (i = 0; i < 3; i++)
-- phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
-- mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
--
-- /* Enable WOL interrupt */
-- ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
-- if (ret)
-- return ret;
-- } else {
-- /* Disable WOL interrupt */
-- ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
-- if (ret)
-- return ret;
-- }
--
-- /* Clear WOL status */
-- ret = phy_read(phydev, AT803X_INTR_STATUS);
-- if (ret < 0)
-- return ret;
--
-- /* Check if there are other interrupts except for WOL triggered when PHY is
-- * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can
-- * be passed up to the interrupt PIN.
-- */
-- irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-- if (irq_enabled < 0)
-- return irq_enabled;
--
-- irq_enabled &= ~AT803X_INTR_ENABLE_WOL;
-- if (ret & irq_enabled && !phy_polling_mode(phydev))
-- phy_trigger_machine(phydev);
--
-- return 0;
--}
--
--static void at803x_get_wol(struct phy_device *phydev,
-- struct ethtool_wolinfo *wol)
--{
-- int value;
--
-- wol->supported = WAKE_MAGIC;
-- wol->wolopts = 0;
--
-- value = phy_read(phydev, AT803X_INTR_ENABLE);
-- if (value < 0)
-- return;
--
-- if (value & AT803X_INTR_ENABLE_WOL)
-- wol->wolopts |= WAKE_MAGIC;
--}
--
--static int qca83xx_get_sset_count(struct phy_device *phydev)
--{
-- return ARRAY_SIZE(qca83xx_hw_stats);
--}
--
--static void qca83xx_get_strings(struct phy_device *phydev, u8 *data)
--{
-- int i;
--
-- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) {
-- strscpy(data + i * ETH_GSTRING_LEN,
-- qca83xx_hw_stats[i].string, ETH_GSTRING_LEN);
-- }
--}
--
--static u64 qca83xx_get_stat(struct phy_device *phydev, int i)
--{
-- struct at803x_hw_stat stat = qca83xx_hw_stats[i];
-- struct at803x_priv *priv = phydev->priv;
-- int val;
-- u64 ret;
--
-- if (stat.access_type == MMD)
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg);
-- else
-- val = phy_read(phydev, stat.reg);
--
-- if (val < 0) {
-- ret = U64_MAX;
-- } else {
-- val = val & stat.mask;
-- priv->stats[i] += val;
-- ret = priv->stats[i];
-- }
--
-- return ret;
--}
--
--static void qca83xx_get_stats(struct phy_device *phydev,
-- struct ethtool_stats *stats, u64 *data)
--{
-- int i;
--
-- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++)
-- data[i] = qca83xx_get_stat(phydev, i);
--}
--
--static int at803x_suspend(struct phy_device *phydev)
--{
-- int value;
-- int wol_enabled;
--
-- value = phy_read(phydev, AT803X_INTR_ENABLE);
-- wol_enabled = value & AT803X_INTR_ENABLE_WOL;
--
-- if (wol_enabled)
-- value = BMCR_ISOLATE;
-- else
-- value = BMCR_PDOWN;
--
-- phy_modify(phydev, MII_BMCR, 0, value);
--
-- return 0;
--}
--
--static int at803x_resume(struct phy_device *phydev)
--{
-- return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
--}
--
--static int at803x_parse_dt(struct phy_device *phydev)
--{
-- struct device_node *node = phydev->mdio.dev.of_node;
-- struct at803x_priv *priv = phydev->priv;
-- u32 freq, strength, tw;
-- unsigned int sel;
-- int ret;
--
-- if (!IS_ENABLED(CONFIG_OF_MDIO))
-- return 0;
--
-- if (of_property_read_bool(node, "qca,disable-smarteee"))
-- priv->flags |= AT803X_DISABLE_SMARTEEE;
--
-- if (of_property_read_bool(node, "qca,disable-hibernation-mode"))
-- priv->flags |= AT803X_DISABLE_HIBERNATION_MODE;
--
-- if (!of_property_read_u32(node, "qca,smarteee-tw-us-1g", &tw)) {
-- if (!tw || tw > 255) {
-- phydev_err(phydev, "invalid qca,smarteee-tw-us-1g\n");
-- return -EINVAL;
-- }
-- priv->smarteee_lpi_tw_1g = tw;
-- }
--
-- if (!of_property_read_u32(node, "qca,smarteee-tw-us-100m", &tw)) {
-- if (!tw || tw > 255) {
-- phydev_err(phydev, "invalid qca,smarteee-tw-us-100m\n");
-- return -EINVAL;
-- }
-- priv->smarteee_lpi_tw_100m = tw;
-- }
--
-- ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq);
-- if (!ret) {
-- switch (freq) {
-- case 25000000:
-- sel = AT803X_CLK_OUT_25MHZ_XTAL;
-- break;
-- case 50000000:
-- sel = AT803X_CLK_OUT_50MHZ_PLL;
-- break;
-- case 62500000:
-- sel = AT803X_CLK_OUT_62_5MHZ_PLL;
-- break;
-- case 125000000:
-- sel = AT803X_CLK_OUT_125MHZ_PLL;
-- break;
-- default:
-- phydev_err(phydev, "invalid qca,clk-out-frequency\n");
-- return -EINVAL;
-- }
--
-- priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel);
-- priv->clk_25m_mask |= AT803X_CLK_OUT_MASK;
-- }
--
-- ret = of_property_read_u32(node, "qca,clk-out-strength", &strength);
-- if (!ret) {
-- priv->clk_25m_mask |= AT803X_CLK_OUT_STRENGTH_MASK;
-- switch (strength) {
-- case AR803X_STRENGTH_FULL:
-- priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_FULL;
-- break;
-- case AR803X_STRENGTH_HALF:
-- priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_HALF;
-- break;
-- case AR803X_STRENGTH_QUARTER:
-- priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_QUARTER;
-- break;
-- default:
-- phydev_err(phydev, "invalid qca,clk-out-strength\n");
-- return -EINVAL;
-- }
-- }
--
-- return 0;
--}
--
--static int at803x_probe(struct phy_device *phydev)
--{
-- struct device *dev = &phydev->mdio.dev;
-- struct at803x_priv *priv;
-- int ret;
--
-- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- /* Init LED polarity mode to -1 */
-- priv->led_polarity_mode = -1;
--
-- phydev->priv = priv;
--
-- ret = at803x_parse_dt(phydev);
-- if (ret)
-- return ret;
--
-- return 0;
--}
--
--static int at803x_get_features(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- int err;
--
-- err = genphy_read_abilities(phydev);
-- if (err)
-- return err;
--
-- if (phydev->drv->phy_id != ATH8031_PHY_ID)
-- return 0;
--
-- /* AR8031/AR8033 have different status registers
-- * for copper and fiber operation. However, the
-- * extended status register is the same for both
-- * operation modes.
-- *
-- * As a result of that, ESTATUS_1000_XFULL is set
-- * to 1 even when operating in copper TP mode.
-- *
-- * Remove this mode from the supported link modes
-- * when not operating in 1000BaseX mode.
-- */
-- if (!priv->is_1000basex)
-- linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-- phydev->supported);
--
-- return 0;
--}
--
--static int at803x_smarteee_config(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- u16 mask = 0, val = 0;
-- int ret;
--
-- if (priv->flags & AT803X_DISABLE_SMARTEEE)
-- return phy_modify_mmd(phydev, MDIO_MMD_PCS,
-- AT803X_MMD3_SMARTEEE_CTL3,
-- AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, 0);
--
-- if (priv->smarteee_lpi_tw_1g) {
-- mask |= 0xff00;
-- val |= priv->smarteee_lpi_tw_1g << 8;
-- }
-- if (priv->smarteee_lpi_tw_100m) {
-- mask |= 0x00ff;
-- val |= priv->smarteee_lpi_tw_100m;
-- }
-- if (!mask)
-- return 0;
--
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL1,
-- mask, val);
-- if (ret)
-- return ret;
--
-- return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3,
-- AT803X_MMD3_SMARTEEE_CTL3_LPI_EN,
-- AT803X_MMD3_SMARTEEE_CTL3_LPI_EN);
--}
--
--static int at803x_clk_out_config(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
--
-- if (!priv->clk_25m_mask)
-- return 0;
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, AT803X_MMD7_CLK25M,
-- priv->clk_25m_mask, priv->clk_25m_reg);
--}
--
--static int at8031_pll_config(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
--
-- /* The default after hardware reset is PLL OFF. After a soft reset, the
-- * values are retained.
-- */
-- if (priv->flags & AT803X_KEEP_PLL_ENABLED)
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-- 0, AT803X_DEBUG_PLL_ON);
-- else
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-- AT803X_DEBUG_PLL_ON, 0);
--}
--
--static int at803x_hibernation_mode_config(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
--
-- /* The default after hardware reset is hibernation mode enabled. After
-- * software reset, the value is retained.
-- */
-- if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE))
-- return 0;
--
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-- AT803X_DEBUG_HIB_CTRL_PS_HIB_EN, 0);
--}
--
--static int at803x_config_init(struct phy_device *phydev)
--{
-- int ret;
--
-- /* The RX and TX delay default is:
-- * after HW reset: RX delay enabled and TX delay disabled
-- * after SW reset: RX delay enabled, while TX delay retains the
-- * value before reset.
-- */
-- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
-- phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
-- ret = at803x_enable_rx_delay(phydev);
-- else
-- ret = at803x_disable_rx_delay(phydev);
-- if (ret < 0)
-- return ret;
--
-- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
-- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
-- ret = at803x_enable_tx_delay(phydev);
-- else
-- ret = at803x_disable_tx_delay(phydev);
-- if (ret < 0)
-- return ret;
--
-- ret = at803x_smarteee_config(phydev);
-- if (ret < 0)
-- return ret;
--
-- ret = at803x_clk_out_config(phydev);
-- if (ret < 0)
-- return ret;
--
-- ret = at803x_hibernation_mode_config(phydev);
-- if (ret < 0)
-- return ret;
--
-- /* Ar803x extended next page bit is enabled by default. Cisco
-- * multigig switches read this bit and attempt to negotiate 10Gbps
-- * rates even if the next page bit is disabled. This is incorrect
-- * behaviour but we still need to accommodate it. XNP is only needed
-- * for 10Gbps support, so disable XNP.
-- */
-- return phy_modify(phydev, MII_ADVERTISE, MDIO_AN_CTRL1_XNP, 0);
--}
--
--static int at803x_ack_interrupt(struct phy_device *phydev)
--{
-- int err;
--
-- err = phy_read(phydev, AT803X_INTR_STATUS);
--
-- return (err < 0) ? err : 0;
--}
--
--static int at803x_config_intr(struct phy_device *phydev)
--{
-- int err;
-- int value;
--
-- value = phy_read(phydev, AT803X_INTR_ENABLE);
--
-- if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-- /* Clear any pending interrupts */
-- err = at803x_ack_interrupt(phydev);
-- if (err)
-- return err;
--
-- value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
-- value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
-- value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
-- value |= AT803X_INTR_ENABLE_LINK_FAIL;
-- value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
--
-- err = phy_write(phydev, AT803X_INTR_ENABLE, value);
-- } else {
-- err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
-- if (err)
-- return err;
--
-- /* Clear any pending interrupts */
-- err = at803x_ack_interrupt(phydev);
-- }
--
-- return err;
--}
--
--static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev)
--{
-- int irq_status, int_enabled;
--
-- irq_status = phy_read(phydev, AT803X_INTR_STATUS);
-- if (irq_status < 0) {
-- phy_error(phydev);
-- return IRQ_NONE;
-- }
--
-- /* Read the current enabled interrupts */
-- int_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-- if (int_enabled < 0) {
-- phy_error(phydev);
-- return IRQ_NONE;
-- }
--
-- /* See if this was one of our enabled interrupts */
-- if (!(irq_status & int_enabled))
-- return IRQ_NONE;
--
-- phy_trigger_machine(phydev);
--
-- return IRQ_HANDLED;
--}
--
--static void at803x_link_change_notify(struct phy_device *phydev)
--{
-- /*
-- * Conduct a hardware reset for AT8030 every time a link loss is
-- * signalled. This is necessary to circumvent a hardware bug that
-- * occurs when the cable is unplugged while TX packets are pending
-- * in the FIFO. In such cases, the FIFO enters an error mode it
-- * cannot recover from by software.
-- */
-- if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) {
-- struct at803x_context context;
--
-- at803x_context_save(phydev, &context);
--
-- phy_device_reset(phydev, 1);
-- usleep_range(1000, 2000);
-- phy_device_reset(phydev, 0);
-- usleep_range(1000, 2000);
--
-- at803x_context_restore(phydev, &context);
--
-- phydev_dbg(phydev, "%s(): phy was reset\n", __func__);
-- }
--}
--
--static int at803x_read_specific_status(struct phy_device *phydev,
-- struct at803x_ss_mask ss_mask)
--{
-- int ss;
--
-- /* Read the AT8035 PHY-Specific Status register, which indicates the
-- * speed and duplex that the PHY is actually using, irrespective of
-- * whether we are in autoneg mode or not.
-- */
-- ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
-- if (ss < 0)
-- return ss;
--
-- if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
-- int sfc, speed;
--
-- sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
-- if (sfc < 0)
-- return sfc;
--
-- speed = ss & ss_mask.speed_mask;
-- speed >>= ss_mask.speed_shift;
--
-- switch (speed) {
-- case AT803X_SS_SPEED_10:
-- phydev->speed = SPEED_10;
-- break;
-- case AT803X_SS_SPEED_100:
-- phydev->speed = SPEED_100;
-- break;
-- case AT803X_SS_SPEED_1000:
-- phydev->speed = SPEED_1000;
-- break;
-- case QCA808X_SS_SPEED_2500:
-- phydev->speed = SPEED_2500;
-- break;
-- }
-- if (ss & AT803X_SS_DUPLEX)
-- phydev->duplex = DUPLEX_FULL;
-- else
-- phydev->duplex = DUPLEX_HALF;
--
-- if (ss & AT803X_SS_MDIX)
-- phydev->mdix = ETH_TP_MDI_X;
-- else
-- phydev->mdix = ETH_TP_MDI;
--
-- switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) {
-- case AT803X_SFC_MANUAL_MDI:
-- phydev->mdix_ctrl = ETH_TP_MDI;
-- break;
-- case AT803X_SFC_MANUAL_MDIX:
-- phydev->mdix_ctrl = ETH_TP_MDI_X;
-- break;
-- case AT803X_SFC_AUTOMATIC_CROSSOVER:
-- phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-- break;
-- }
-- }
--
-- return 0;
--}
--
--static int at803x_read_status(struct phy_device *phydev)
--{
-- struct at803x_ss_mask ss_mask = { 0 };
-- int err, old_link = phydev->link;
--
-- /* Update the link, but return if there was an error */
-- err = genphy_update_link(phydev);
-- if (err)
-- return err;
--
-- /* why bother the PHY if nothing can have changed */
-- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-- return 0;
--
-- phydev->speed = SPEED_UNKNOWN;
-- phydev->duplex = DUPLEX_UNKNOWN;
-- phydev->pause = 0;
-- phydev->asym_pause = 0;
--
-- err = genphy_read_lpa(phydev);
-- if (err < 0)
-- return err;
--
-- ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
-- ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
-- err = at803x_read_specific_status(phydev, ss_mask);
-- if (err < 0)
-- return err;
--
-- if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
-- phy_resolve_aneg_pause(phydev);
--
-- return 0;
--}
--
--static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl)
--{
-- u16 val;
--
-- switch (ctrl) {
-- case ETH_TP_MDI:
-- val = AT803X_SFC_MANUAL_MDI;
-- break;
-- case ETH_TP_MDI_X:
-- val = AT803X_SFC_MANUAL_MDIX;
-- break;
-- case ETH_TP_MDI_AUTO:
-- val = AT803X_SFC_AUTOMATIC_CROSSOVER;
-- break;
-- default:
-- return 0;
-- }
--
-- return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL,
-- AT803X_SFC_MDI_CROSSOVER_MODE_M,
-- FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
--}
--
--static int at803x_prepare_config_aneg(struct phy_device *phydev)
--{
-- int ret;
--
-- ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
-- if (ret < 0)
-- return ret;
--
-- /* Changes of the midx bits are disruptive to the normal operation;
-- * therefore any changes to these registers must be followed by a
-- * software reset to take effect.
-- */
-- if (ret == 1) {
-- ret = genphy_soft_reset(phydev);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--static int at803x_config_aneg(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- int ret;
--
-- ret = at803x_prepare_config_aneg(phydev);
-- if (ret)
-- return ret;
--
-- if (priv->is_1000basex)
-- return genphy_c37_config_aneg(phydev);
--
-- return genphy_config_aneg(phydev);
--}
--
--static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
--{
-- int val;
--
-- val = phy_read(phydev, AT803X_SMART_SPEED);
-- if (val < 0)
-- return val;
--
-- if (val & AT803X_SMART_SPEED_ENABLE)
-- *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2;
-- else
-- *d = DOWNSHIFT_DEV_DISABLE;
--
-- return 0;
--}
--
--static int at803x_set_downshift(struct phy_device *phydev, u8 cnt)
--{
-- u16 mask, set;
-- int ret;
--
-- switch (cnt) {
-- case DOWNSHIFT_DEV_DEFAULT_COUNT:
-- cnt = AT803X_DEFAULT_DOWNSHIFT;
-- fallthrough;
-- case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT:
-- set = AT803X_SMART_SPEED_ENABLE |
-- AT803X_SMART_SPEED_BYPASS_TIMER |
-- FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2);
-- mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK;
-- break;
-- case DOWNSHIFT_DEV_DISABLE:
-- set = 0;
-- mask = AT803X_SMART_SPEED_ENABLE |
-- AT803X_SMART_SPEED_BYPASS_TIMER;
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set);
--
-- /* After changing the smart speed settings, we need to perform a
-- * software reset, use phy_init_hw() to make sure we set the
-- * reapply any values which might got lost during software reset.
-- */
-- if (ret == 1)
-- ret = phy_init_hw(phydev);
--
-- return ret;
--}
--
--static int at803x_get_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return at803x_get_downshift(phydev, data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static int at803x_set_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, const void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return at803x_set_downshift(phydev, *(const u8 *)data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static int at803x_cable_test_result_trans(u16 status)
--{
-- switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
-- case AT803X_CDT_STATUS_STAT_NORMAL:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-- case AT803X_CDT_STATUS_STAT_SHORT:
-- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-- case AT803X_CDT_STATUS_STAT_OPEN:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-- case AT803X_CDT_STATUS_STAT_FAIL:
-- default:
-- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-- }
--}
--
--static bool at803x_cdt_test_failed(u16 status)
--{
-- return FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status) ==
-- AT803X_CDT_STATUS_STAT_FAIL;
--}
--
--static bool at803x_cdt_fault_length_valid(u16 status)
--{
-- switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
-- case AT803X_CDT_STATUS_STAT_OPEN:
-- case AT803X_CDT_STATUS_STAT_SHORT:
-- return true;
-- }
-- return false;
--}
--
--static int at803x_cdt_fault_length(int dt)
--{
-- /* According to the datasheet the distance to the fault is
-- * DELTA_TIME * 0.824 meters.
-- *
-- * The author suspect the correct formula is:
-- *
-- * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2
-- *
-- * where c is the speed of light, VF is the velocity factor of
-- * the twisted pair cable, 125MHz the counter frequency and
-- * we need to divide by 2 because the hardware will measure the
-- * round trip time to the fault and back to the PHY.
-- *
-- * With a VF of 0.69 we get the factor 0.824 mentioned in the
-- * datasheet.
-- */
-- return (dt * 824) / 10;
--}
--
--static int at803x_cdt_start(struct phy_device *phydev,
-- u32 cdt_start)
--{
-- return phy_write(phydev, AT803X_CDT, cdt_start);
--}
--
--static int at803x_cdt_wait_for_completion(struct phy_device *phydev,
-- u32 cdt_en)
--{
-- int val, ret;
--
-- /* One test run takes about 25ms */
-- ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
-- !(val & cdt_en),
-- 30000, 100000, true);
--
-- return ret < 0 ? ret : 0;
--}
--
--static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair)
--{
-- static const int ethtool_pair[] = {
-- ETHTOOL_A_CABLE_PAIR_A,
-- ETHTOOL_A_CABLE_PAIR_B,
-- ETHTOOL_A_CABLE_PAIR_C,
-- ETHTOOL_A_CABLE_PAIR_D,
-- };
-- int ret, val;
--
-- val = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
-- AT803X_CDT_ENABLE_TEST;
-- ret = at803x_cdt_start(phydev, val);
-- if (ret)
-- return ret;
--
-- ret = at803x_cdt_wait_for_completion(phydev, AT803X_CDT_ENABLE_TEST);
-- if (ret)
-- return ret;
--
-- val = phy_read(phydev, AT803X_CDT_STATUS);
-- if (val < 0)
-- return val;
--
-- if (at803x_cdt_test_failed(val))
-- return 0;
--
-- ethnl_cable_test_result(phydev, ethtool_pair[pair],
-- at803x_cable_test_result_trans(val));
--
-- if (at803x_cdt_fault_length_valid(val)) {
-- val = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, val);
-- ethnl_cable_test_fault_length(phydev, ethtool_pair[pair],
-- at803x_cdt_fault_length(val));
-- }
--
-- return 1;
--}
--
--static int at803x_cable_test_get_status(struct phy_device *phydev,
-- bool *finished, unsigned long pair_mask)
--{
-- int retries = 20;
-- int pair, ret;
--
-- *finished = false;
--
-- /* According to the datasheet the CDT can be performed when
-- * there is no link partner or when the link partner is
-- * auto-negotiating. Starting the test will restart the AN
-- * automatically. It seems that doing this repeatedly we will
-- * get a slot where our link partner won't disturb our
-- * measurement.
-- */
-- while (pair_mask && retries--) {
-- for_each_set_bit(pair, &pair_mask, 4) {
-- ret = at803x_cable_test_one_pair(phydev, pair);
-- if (ret < 0)
-- return ret;
-- if (ret)
-- clear_bit(pair, &pair_mask);
-- }
-- if (pair_mask)
-- msleep(250);
-- }
--
-- *finished = true;
--
-- return 0;
--}
--
--static void at803x_cable_test_autoneg(struct phy_device *phydev)
--{
-- /* Enable auto-negotiation, but advertise no capabilities, no link
-- * will be established. A restart of the auto-negotiation is not
-- * required, because the cable test will automatically break the link.
-- */
-- phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
-- phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA);
--}
--
--static int at803x_cable_test_start(struct phy_device *phydev)
--{
-- at803x_cable_test_autoneg(phydev);
-- /* we do all the (time consuming) work later */
-- return 0;
--}
--
--static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
-- unsigned int selector)
--{
-- struct phy_device *phydev = rdev_get_drvdata(rdev);
--
-- if (selector)
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-- 0, AT803X_DEBUG_RGMII_1V8);
-- else
-- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-- AT803X_DEBUG_RGMII_1V8, 0);
--}
--
--static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
--{
-- struct phy_device *phydev = rdev_get_drvdata(rdev);
-- int val;
--
-- val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F);
-- if (val < 0)
-- return val;
--
-- return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0;
--}
--
--static const struct regulator_ops vddio_regulator_ops = {
-- .list_voltage = regulator_list_voltage_table,
-- .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
-- .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
--};
--
--static const unsigned int vddio_voltage_table[] = {
-- 1500000,
-- 1800000,
--};
--
--static const struct regulator_desc vddio_desc = {
-- .name = "vddio",
-- .of_match = of_match_ptr("vddio-regulator"),
-- .n_voltages = ARRAY_SIZE(vddio_voltage_table),
-- .volt_table = vddio_voltage_table,
-- .ops = &vddio_regulator_ops,
-- .type = REGULATOR_VOLTAGE,
-- .owner = THIS_MODULE,
--};
--
--static const struct regulator_ops vddh_regulator_ops = {
--};
--
--static const struct regulator_desc vddh_desc = {
-- .name = "vddh",
-- .of_match = of_match_ptr("vddh-regulator"),
-- .n_voltages = 1,
-- .fixed_uV = 2500000,
-- .ops = &vddh_regulator_ops,
-- .type = REGULATOR_VOLTAGE,
-- .owner = THIS_MODULE,
--};
--
--static int at8031_register_regulators(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- struct device *dev = &phydev->mdio.dev;
-- struct regulator_config config = { };
--
-- config.dev = dev;
-- config.driver_data = phydev;
--
-- priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config);
-- if (IS_ERR(priv->vddio_rdev)) {
-- phydev_err(phydev, "failed to register VDDIO regulator\n");
-- return PTR_ERR(priv->vddio_rdev);
-- }
--
-- priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config);
-- if (IS_ERR(priv->vddh_rdev)) {
-- phydev_err(phydev, "failed to register VDDH regulator\n");
-- return PTR_ERR(priv->vddh_rdev);
-- }
--
-- return 0;
--}
--
--static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
--{
-- struct phy_device *phydev = upstream;
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
-- DECLARE_PHY_INTERFACE_MASK(interfaces);
-- phy_interface_t iface;
--
-- linkmode_zero(phy_support);
-- phylink_set(phy_support, 1000baseX_Full);
-- phylink_set(phy_support, 1000baseT_Full);
-- phylink_set(phy_support, Autoneg);
-- phylink_set(phy_support, Pause);
-- phylink_set(phy_support, Asym_Pause);
--
-- linkmode_zero(sfp_support);
-- sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces);
-- /* Some modules support 10G modes as well as others we support.
-- * Mask out non-supported modes so the correct interface is picked.
-- */
-- linkmode_and(sfp_support, phy_support, sfp_support);
--
-- if (linkmode_empty(sfp_support)) {
-- dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
-- return -EINVAL;
-- }
--
-- iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
--
-- /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
-- * interface for use with SFP modules.
-- * However, some copper modules detected as having a preferred SGMII
-- * interface do default to and function in 1000Base-X mode, so just
-- * print a warning and allow such modules, as they may have some chance
-- * of working.
-- */
-- if (iface == PHY_INTERFACE_MODE_SGMII)
-- dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
-- else if (iface != PHY_INTERFACE_MODE_1000BASEX)
-- return -EINVAL;
--
-- return 0;
--}
--
--static const struct sfp_upstream_ops at8031_sfp_ops = {
-- .attach = phy_sfp_attach,
-- .detach = phy_sfp_detach,
-- .module_insert = at8031_sfp_insert,
--};
--
--static int at8031_parse_dt(struct phy_device *phydev)
--{
-- struct device_node *node = phydev->mdio.dev.of_node;
-- struct at803x_priv *priv = phydev->priv;
-- int ret;
--
-- if (of_property_read_bool(node, "qca,keep-pll-enabled"))
-- priv->flags |= AT803X_KEEP_PLL_ENABLED;
--
-- ret = at8031_register_regulators(phydev);
-- if (ret < 0)
-- return ret;
--
-- ret = devm_regulator_get_enable_optional(&phydev->mdio.dev,
-- "vddio");
-- if (ret) {
-- phydev_err(phydev, "failed to get VDDIO regulator\n");
-- return ret;
-- }
--
-- /* Only AR8031/8033 support 1000Base-X for SFP modules */
-- return phy_sfp_probe(phydev, &at8031_sfp_ops);
--}
--
--static int at8031_probe(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- int mode_cfg;
-- int ccr;
-- int ret;
--
-- ret = at803x_probe(phydev);
-- if (ret)
-- return ret;
--
-- /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
-- * options.
-- */
-- ret = at8031_parse_dt(phydev);
-- if (ret)
-- return ret;
--
-- ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
-- if (ccr < 0)
-- return ccr;
-- mode_cfg = ccr & AT803X_MODE_CFG_MASK;
--
-- switch (mode_cfg) {
-- case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
-- case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
-- priv->is_1000basex = true;
-- fallthrough;
-- case AT803X_MODE_CFG_FX100_RGMII_50OHM:
-- case AT803X_MODE_CFG_FX100_RGMII_75OHM:
-- priv->is_fiber = true;
-- break;
-- }
--
-- /* Disable WoL in 1588 register which is enabled
-- * by default
-- */
-- return phy_modify_mmd(phydev, MDIO_MMD_PCS,
-- AT803X_PHY_MMD3_WOL_CTRL,
-- AT803X_WOL_EN, 0);
--}
--
--static int at8031_config_init(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- int ret;
--
-- /* Some bootloaders leave the fiber page selected.
-- * Switch to the appropriate page (fiber or copper), as otherwise we
-- * read the PHY capabilities from the wrong page.
-- */
-- phy_lock_mdio_bus(phydev);
-- ret = at803x_write_page(phydev,
-- priv->is_fiber ? AT803X_PAGE_FIBER :
-- AT803X_PAGE_COPPER);
-- phy_unlock_mdio_bus(phydev);
-- if (ret)
-- return ret;
--
-- ret = at8031_pll_config(phydev);
-- if (ret < 0)
-- return ret;
--
-- return at803x_config_init(phydev);
--}
--
--static int at8031_set_wol(struct phy_device *phydev,
-- struct ethtool_wolinfo *wol)
--{
-- int ret;
--
-- /* First setup MAC address and enable WOL interrupt */
-- ret = at803x_set_wol(phydev, wol);
-- if (ret)
-- return ret;
--
-- if (wol->wolopts & WAKE_MAGIC)
-- /* Enable WOL function for 1588 */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-- AT803X_PHY_MMD3_WOL_CTRL,
-- 0, AT803X_WOL_EN);
-- else
-- /* Disable WoL function for 1588 */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-- AT803X_PHY_MMD3_WOL_CTRL,
-- AT803X_WOL_EN, 0);
--
-- return ret;
--}
--
--static int at8031_config_intr(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
-- int err, value = 0;
--
-- if (phydev->interrupts == PHY_INTERRUPT_ENABLED &&
-- priv->is_fiber) {
-- /* Clear any pending interrupts */
-- err = at803x_ack_interrupt(phydev);
-- if (err)
-- return err;
--
-- value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
-- value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
--
-- err = phy_set_bits(phydev, AT803X_INTR_ENABLE, value);
-- if (err)
-- return err;
-- }
--
-- return at803x_config_intr(phydev);
--}
--
--/* AR8031 and AR8033 share the same read status logic */
--static int at8031_read_status(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
--
-- if (priv->is_1000basex)
-- return genphy_c37_read_status(phydev);
--
-- return at803x_read_status(phydev);
--}
--
--/* AR8031 and AR8035 share the same cable test get status reg */
--static int at8031_cable_test_get_status(struct phy_device *phydev,
-- bool *finished)
--{
-- return at803x_cable_test_get_status(phydev, finished, 0xf);
--}
--
--/* AR8031 and AR8035 share the same cable test start logic */
--static int at8031_cable_test_start(struct phy_device *phydev)
--{
-- at803x_cable_test_autoneg(phydev);
-- phy_write(phydev, MII_CTRL1000, 0);
-- /* we do all the (time consuming) work later */
-- return 0;
--}
--
--/* AR8032, AR9331 and QCA9561 share the same cable test get status reg */
--static int at8032_cable_test_get_status(struct phy_device *phydev,
-- bool *finished)
--{
-- return at803x_cable_test_get_status(phydev, finished, 0x3);
--}
--
--static int at8035_parse_dt(struct phy_device *phydev)
--{
-- struct at803x_priv *priv = phydev->priv;
--
-- /* Mask is set by the generic at803x_parse_dt
-- * if property is set. Assume property is set
-- * with the mask not zero.
-- */
-- if (priv->clk_25m_mask) {
-- /* Fixup for the AR8030/AR8035. This chip has another mask and
-- * doesn't support the DSP reference. Eg. the lowest bit of the
-- * mask. The upper two bits select the same frequencies. Mask
-- * the lowest bit here.
-- *
-- * Warning:
-- * There was no datasheet for the AR8030 available so this is
-- * just a guess. But the AR8035 is listed as pin compatible
-- * to the AR8030 so there might be a good chance it works on
-- * the AR8030 too.
-- */
-- priv->clk_25m_reg &= AT8035_CLK_OUT_MASK;
-- priv->clk_25m_mask &= AT8035_CLK_OUT_MASK;
-- }
--
-- return 0;
--}
--
--/* AR8030 and AR8035 shared the same special mask for clk_25m */
--static int at8035_probe(struct phy_device *phydev)
--{
-- int ret;
--
-- ret = at803x_probe(phydev);
-- if (ret)
-- return ret;
--
-- return at8035_parse_dt(phydev);
--}
--
--static int qca83xx_config_init(struct phy_device *phydev)
--{
-- u8 switch_revision;
--
-- switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK;
--
-- switch (switch_revision) {
-- case 1:
-- /* For 100M waveform */
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
-- /* Turn on Gigabit clock */
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
-- break;
--
-- case 2:
-- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
-- fallthrough;
-- case 4:
-- phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
-- break;
-- }
--
-- /* Following original QCA sourcecode set port to prefer master */
-- phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
--
-- return 0;
--}
--
--static int qca8327_config_init(struct phy_device *phydev)
--{
-- /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
-- * Disable on init and enable only with 100m speed following
-- * qca original source code.
-- */
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- QCA8327_DEBUG_MANU_CTRL_EN, 0);
--
-- return qca83xx_config_init(phydev);
--}
--
--static void qca83xx_link_change_notify(struct phy_device *phydev)
--{
-- /* Set DAC Amplitude adjustment to +6% for 100m on link running */
-- if (phydev->state == PHY_RUNNING) {
-- if (phydev->speed == SPEED_100)
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- QCA8327_DEBUG_MANU_CTRL_EN,
-- QCA8327_DEBUG_MANU_CTRL_EN);
-- } else {
-- /* Reset DAC Amplitude adjustment */
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- QCA8327_DEBUG_MANU_CTRL_EN, 0);
-- }
--}
--
--static int qca83xx_resume(struct phy_device *phydev)
--{
-- int ret, val;
--
-- /* Skip reset if not suspended */
-- if (!phydev->suspended)
-- return 0;
--
-- /* Reinit the port, reset values set by suspend */
-- qca83xx_config_init(phydev);
--
-- /* Reset the port on port resume */
-- phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
--
-- /* On resume from suspend the switch execute a reset and
-- * restart auto-negotiation. Wait for reset to complete.
-- */
-- ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
-- 50000, 600000, true);
-- if (ret)
-- return ret;
--
-- usleep_range(1000, 2000);
--
-- return 0;
--}
--
--static int qca83xx_suspend(struct phy_device *phydev)
--{
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
-- AT803X_DEBUG_GATE_CLK_IN1000, 0);
--
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-- AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
-- AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
--
-- return 0;
--}
--
--static int qca8337_suspend(struct phy_device *phydev)
--{
-- /* Only QCA8337 support actual suspend. */
-- genphy_suspend(phydev);
--
-- return qca83xx_suspend(phydev);
--}
--
--static int qca8327_suspend(struct phy_device *phydev)
--{
-- u16 mask = 0;
--
-- /* QCA8327 cause port unreliability when phy suspend
-- * is set.
-- */
-- mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-- phy_modify(phydev, MII_BMCR, mask, 0);
--
-- return qca83xx_suspend(phydev);
--}
--
--static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Enable fast retrain */
-- ret = genphy_c45_fast_retrain(phydev, true);
-- if (ret)
-- return ret;
--
-- phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
-- QCA808X_TOP_OPTION1_DATA);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
-- QCA808X_MSE_THRESHOLD_20DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
-- QCA808X_MSE_THRESHOLD_17DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
-- QCA808X_MSE_THRESHOLD_27DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
-- QCA808X_MSE_THRESHOLD_28DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
-- QCA808X_MMD3_DEBUG_1_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
-- QCA808X_MMD3_DEBUG_4_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
-- QCA808X_MMD3_DEBUG_5_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
-- QCA808X_MMD3_DEBUG_3_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
-- QCA808X_MMD3_DEBUG_6_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
-- QCA808X_MMD3_DEBUG_2_VALUE);
--
-- return 0;
--}
--
--static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
--{
-- u16 seed_value;
--
-- if (!enable)
-- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-- QCA808X_MASTER_SLAVE_SEED_ENABLE, 0);
--
-- seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
-- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-- QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE,
-- FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) |
-- QCA808X_MASTER_SLAVE_SEED_ENABLE);
--}
--
--static bool qca808x_is_prefer_master(struct phy_device *phydev)
--{
-- return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) ||
-- (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
--}
--
--static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
--{
-- return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
--}
--
--static int qca808x_config_init(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Active adc&vga on 802.3az for the link 1000M and 100M */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
-- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
-- if (ret)
-- return ret;
--
-- /* Adjust the threshold on 802.3az for the link 1000M */
-- ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
-- QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
-- QCA808X_MMD3_AZ_TRAINING_VAL);
-- if (ret)
-- return ret;
--
-- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-- /* Config the fast retrain for the link 2500M */
-- ret = qca808x_phy_fast_retrain_config(phydev);
-- if (ret)
-- return ret;
--
-- ret = genphy_read_master_slave(phydev);
-- if (ret < 0)
-- return ret;
--
-- if (!qca808x_is_prefer_master(phydev)) {
-- /* Enable seed and configure lower ramdom seed to make phy
-- * linked as slave mode.
-- */
-- ret = qca808x_phy_ms_seed_enable(phydev, true);
-- if (ret)
-- return ret;
-- }
-- }
--
-- /* Configure adc threshold as 100mv for the link 10M */
-- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
-- QCA808X_ADC_THRESHOLD_MASK,
-- QCA808X_ADC_THRESHOLD_100MV);
--}
--
--static int qca808x_read_status(struct phy_device *phydev)
--{
-- struct at803x_ss_mask ss_mask = { 0 };
-- int ret;
--
-- ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
-- if (ret < 0)
-- return ret;
--
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
-- ret & MDIO_AN_10GBT_STAT_LP2_5G);
--
-- ret = genphy_read_status(phydev);
-- if (ret)
-- return ret;
--
-- /* qca8081 takes the different bits for speed value from at803x */
-- ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
-- ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
-- ret = at803x_read_specific_status(phydev, ss_mask);
-- if (ret < 0)
-- return ret;
--
-- if (phydev->link) {
-- if (phydev->speed == SPEED_2500)
-- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-- else
-- phydev->interface = PHY_INTERFACE_MODE_SGMII;
-- } else {
-- /* generate seed as a lower random value to make PHY linked as SLAVE easily,
-- * except for master/slave configuration fault detected or the master mode
-- * preferred.
-- *
-- * the reason for not putting this code into the function link_change_notify is
-- * the corner case where the link partner is also the qca8081 PHY and the seed
-- * value is configured as the same value, the link can't be up and no link change
-- * occurs.
-- */
-- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-- qca808x_is_prefer_master(phydev)) {
-- qca808x_phy_ms_seed_enable(phydev, false);
-- } else {
-- qca808x_phy_ms_seed_enable(phydev, true);
-- }
-- }
-- }
--
-- return 0;
--}
--
--static int qca808x_soft_reset(struct phy_device *phydev)
--{
-- int ret;
--
-- ret = genphy_soft_reset(phydev);
-- if (ret < 0)
-- return ret;
--
-- if (qca808x_has_fast_retrain_or_slave_seed(phydev))
-- ret = qca808x_phy_ms_seed_enable(phydev, true);
--
-- return ret;
--}
--
--static bool qca808x_cdt_fault_length_valid(int cdt_code)
--{
-- switch (cdt_code) {
-- case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-- return true;
-- default:
-- return false;
-- }
--}
--
--static int qca808x_cable_test_result_trans(int cdt_code)
--{
-- switch (cdt_code) {
-- case QCA808X_CDT_STATUS_STAT_NORMAL:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-- case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-- case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-- return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
-- case QCA808X_CDT_STATUS_STAT_FAIL:
-- default:
-- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-- }
--}
--
--static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
-- int result)
--{
-- int val;
-- u32 cdt_length_reg = 0;
--
-- switch (pair) {
-- case ETHTOOL_A_CABLE_PAIR_A:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_B:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_C:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_D:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
-- if (val < 0)
-- return val;
--
-- if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
-- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
-- else
-- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
--
-- return at803x_cdt_fault_length(val);
--}
--
--static int qca808x_cable_test_start(struct phy_device *phydev)
--{
-- int ret;
--
-- /* perform CDT with the following configs:
-- * 1. disable hibernation.
-- * 2. force PHY working in MDI mode.
-- * 3. for PHY working in 1000BaseT.
-- * 4. configure the threshold.
-- */
--
-- ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0);
-- if (ret < 0)
-- return ret;
--
-- ret = at803x_config_mdix(phydev, ETH_TP_MDI);
-- if (ret < 0)
-- return ret;
--
-- /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */
-- phydev->duplex = DUPLEX_FULL;
-- phydev->speed = SPEED_1000;
-- ret = genphy_c45_pma_setup_forced(phydev);
-- if (ret < 0)
-- return ret;
--
-- ret = genphy_setup_forced(phydev);
-- if (ret < 0)
-- return ret;
--
-- /* configure the thresholds for open, short, pair ok test */
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
--
-- return 0;
--}
--
--static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
-- u16 status)
--{
-- int length, result;
-- u16 pair_code;
--
-- switch (pair) {
-- case ETHTOOL_A_CABLE_PAIR_A:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_B:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_C:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_D:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- result = qca808x_cable_test_result_trans(pair_code);
-- ethnl_cable_test_result(phydev, pair, result);
--
-- if (qca808x_cdt_fault_length_valid(pair_code)) {
-- length = qca808x_cdt_fault_length(phydev, pair, result);
-- ethnl_cable_test_fault_length(phydev, pair, length);
-- }
--
-- return 0;
--}
--
--static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
--{
-- int ret, val;
--
-- *finished = false;
--
-- val = QCA808X_CDT_ENABLE_TEST |
-- QCA808X_CDT_LENGTH_UNIT;
-- ret = at803x_cdt_start(phydev, val);
-- if (ret)
-- return ret;
--
-- ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
-- if (ret)
-- return ret;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
-- if (val < 0)
-- return val;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-- if (ret)
-- return ret;
--
-- *finished = true;
--
-- return 0;
--}
--
--static int qca808x_get_features(struct phy_device *phydev)
--{
-- int ret;
--
-- ret = genphy_c45_pma_read_abilities(phydev);
-- if (ret)
-- return ret;
--
-- /* The autoneg ability is not existed in bit3 of MMD7.1,
-- * but it is supported by qca808x PHY, so we add it here
-- * manually.
-- */
-- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
--
-- /* As for the qca8081 1G version chip, the 2500baseT ability is also
-- * existed in the bit0 of MMD1.21, we need to remove it manually if
-- * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
-- */
-- ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-- if (ret < 0)
-- return ret;
--
-- if (QCA808X_PHY_CHIP_TYPE_1G & ret)
-- linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
--
-- return 0;
--}
--
--static int qca808x_config_aneg(struct phy_device *phydev)
--{
-- int phy_ctrl = 0;
-- int ret;
--
-- ret = at803x_prepare_config_aneg(phydev);
-- if (ret)
-- return ret;
--
-- /* The reg MII_BMCR also needs to be configured for force mode, the
-- * genphy_config_aneg is also needed.
-- */
-- if (phydev->autoneg == AUTONEG_DISABLE)
-- genphy_c45_pma_setup_forced(phydev);
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
-- phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
--
-- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-- MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
-- if (ret < 0)
-- return ret;
--
-- return __genphy_config_aneg(phydev, ret);
--}
--
--static void qca808x_link_change_notify(struct phy_device *phydev)
--{
-- /* Assert interface sgmii fifo on link down, deassert it on link up,
-- * the interface device address is always phy address added by 1.
-- */
-- mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
-- MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
-- QCA8081_PHY_FIFO_RSTN,
-- phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
--}
--
--static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
-- u16 *offload_trigger)
--{
-- /* Parsing specific to netdev trigger */
-- if (test_bit(TRIGGER_NETDEV_TX, &rules))
-- *offload_trigger |= QCA808X_LED_TX_BLINK;
-- if (test_bit(TRIGGER_NETDEV_RX, &rules))
-- *offload_trigger |= QCA808X_LED_RX_BLINK;
-- if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED10_ON;
-- if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED100_ON;
-- if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED1000_ON;
-- if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED2500_ON;
-- if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-- *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
-- if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-- *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
--
-- if (rules && !*offload_trigger)
-- return -EOPNOTSUPP;
--
-- /* Enable BLINK_CHECK_BYPASS by default to make the LED
-- * blink even with duplex or speed mode not enabled.
-- */
-- *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS;
--
-- return 0;
--}
--
--static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index)
--{
-- u16 reg;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN);
--}
--
--static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-- unsigned long rules)
--{
-- u16 offload_trigger = 0;
--
-- if (index > 2)
-- return -EINVAL;
--
-- return qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
--}
--
--static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index,
-- unsigned long rules)
--{
-- u16 reg, offload_trigger = 0;
-- int ret;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_CTRL(index);
--
-- ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-- if (ret)
-- return ret;
--
-- ret = qca808x_led_hw_control_enable(phydev, index);
-- if (ret)
-- return ret;
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_PATTERN_MASK,
-- offload_trigger);
--}
--
--static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
--{
-- u16 reg;
-- int val;
--
-- if (index > 2)
-- return false;
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
--
-- return !(val & QCA808X_LED_FORCE_EN);
--}
--
--static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
-- unsigned long *rules)
--{
-- u16 reg;
-- int val;
--
-- if (index > 2)
-- return -EINVAL;
--
-- /* Check if we have hw control enabled */
-- if (qca808x_led_hw_control_status(phydev, index))
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_CTRL(index);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-- if (val & QCA808X_LED_TX_BLINK)
-- set_bit(TRIGGER_NETDEV_TX, rules);
-- if (val & QCA808X_LED_RX_BLINK)
-- set_bit(TRIGGER_NETDEV_RX, rules);
-- if (val & QCA808X_LED_SPEED10_ON)
-- set_bit(TRIGGER_NETDEV_LINK_10, rules);
-- if (val & QCA808X_LED_SPEED100_ON)
-- set_bit(TRIGGER_NETDEV_LINK_100, rules);
-- if (val & QCA808X_LED_SPEED1000_ON)
-- set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-- if (val & QCA808X_LED_SPEED2500_ON)
-- set_bit(TRIGGER_NETDEV_LINK_2500, rules);
-- if (val & QCA808X_LED_HALF_DUPLEX_ON)
-- set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-- if (val & QCA808X_LED_FULL_DUPLEX_ON)
-- set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
--
-- return 0;
--}
--
--static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index)
--{
-- u16 reg;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_CTRL(index);
--
-- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_PATTERN_MASK);
--}
--
--static int qca808x_led_brightness_set(struct phy_device *phydev,
-- u8 index, enum led_brightness value)
--{
-- u16 reg;
-- int ret;
--
-- if (index > 2)
-- return -EINVAL;
--
-- if (!value) {
-- ret = qca808x_led_hw_control_reset(phydev, index);
-- if (ret)
-- return ret;
-- }
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-- QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON :
-- QCA808X_LED_FORCE_OFF);
--}
--
--static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
-- unsigned long *delay_on,
-- unsigned long *delay_off)
--{
-- int ret;
-- u16 reg;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- /* Set blink to 50% off, 50% on at 4Hz by default */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
-- QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
-- QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
-- if (ret)
-- return ret;
--
-- /* We use BLINK_1 for normal blinking */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
-- if (ret)
-- return ret;
--
-- /* We set blink to 4Hz, aka 250ms */
-- *delay_on = 250 / 2;
-- *delay_off = 250 / 2;
--
-- return 0;
--}
--
--static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
-- unsigned long modes)
--{
-- struct at803x_priv *priv = phydev->priv;
-- bool active_low = false;
-- u32 mode;
--
-- for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-- switch (mode) {
-- case PHY_LED_ACTIVE_LOW:
-- active_low = true;
-- break;
-- default:
-- return -EINVAL;
-- }
-- }
--
-- /* PHY polarity is global and can't be set per LED.
-- * To detect this, check if last requested polarity mode
-- * match the new one.
-- */
-- if (priv->led_polarity_mode >= 0 &&
-- priv->led_polarity_mode != active_low) {
-- phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
-- return -EINVAL;
-- }
--
-- /* Save the last PHY polarity mode */
-- priv->led_polarity_mode = active_low;
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN,
-- QCA808X_MMD7_LED_POLARITY_CTRL,
-- QCA808X_LED_ACTIVE_HIGH,
-- active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
--}
--
--static struct phy_driver at803x_driver[] = {
--{
-- /* Qualcomm Atheros AR8035 */
-- PHY_ID_MATCH_EXACT(ATH8035_PHY_ID),
-- .name = "Qualcomm Atheros AR8035",
-- .flags = PHY_POLL_CABLE_TEST,
-- .probe = at8035_probe,
-- .config_aneg = at803x_config_aneg,
-- .config_init = at803x_config_init,
-- .soft_reset = genphy_soft_reset,
-- .set_wol = at803x_set_wol,
-- .get_wol = at803x_get_wol,
-- .suspend = at803x_suspend,
-- .resume = at803x_resume,
-- /* PHY_GBIT_FEATURES */
-- .read_status = at803x_read_status,
-- .config_intr = at803x_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
-- .get_tunable = at803x_get_tunable,
-- .set_tunable = at803x_set_tunable,
-- .cable_test_start = at8031_cable_test_start,
-- .cable_test_get_status = at8031_cable_test_get_status,
--}, {
-- /* Qualcomm Atheros AR8030 */
-- .phy_id = ATH8030_PHY_ID,
-- .name = "Qualcomm Atheros AR8030",
-- .phy_id_mask = AT8030_PHY_ID_MASK,
-- .probe = at8035_probe,
-- .config_init = at803x_config_init,
-- .link_change_notify = at803x_link_change_notify,
-- .set_wol = at803x_set_wol,
-- .get_wol = at803x_get_wol,
-- .suspend = at803x_suspend,
-- .resume = at803x_resume,
-- /* PHY_BASIC_FEATURES */
-- .config_intr = at803x_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
--}, {
-- /* Qualcomm Atheros AR8031/AR8033 */
-- PHY_ID_MATCH_EXACT(ATH8031_PHY_ID),
-- .name = "Qualcomm Atheros AR8031/AR8033",
-- .flags = PHY_POLL_CABLE_TEST,
-- .probe = at8031_probe,
-- .config_init = at8031_config_init,
-- .config_aneg = at803x_config_aneg,
-- .soft_reset = genphy_soft_reset,
-- .set_wol = at8031_set_wol,
-- .get_wol = at803x_get_wol,
-- .suspend = at803x_suspend,
-- .resume = at803x_resume,
-- .read_page = at803x_read_page,
-- .write_page = at803x_write_page,
-- .get_features = at803x_get_features,
-- .read_status = at8031_read_status,
-- .config_intr = at8031_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
-- .get_tunable = at803x_get_tunable,
-- .set_tunable = at803x_set_tunable,
-- .cable_test_start = at8031_cable_test_start,
-- .cable_test_get_status = at8031_cable_test_get_status,
--}, {
-- /* Qualcomm Atheros AR8032 */
-- PHY_ID_MATCH_EXACT(ATH8032_PHY_ID),
-- .name = "Qualcomm Atheros AR8032",
-- .probe = at803x_probe,
-- .flags = PHY_POLL_CABLE_TEST,
-- .config_init = at803x_config_init,
-- .link_change_notify = at803x_link_change_notify,
-- .suspend = at803x_suspend,
-- .resume = at803x_resume,
-- /* PHY_BASIC_FEATURES */
-- .config_intr = at803x_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
-- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at8032_cable_test_get_status,
--}, {
-- /* ATHEROS AR9331 */
-- PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
-- .name = "Qualcomm Atheros AR9331 built-in PHY",
-- .probe = at803x_probe,
-- .suspend = at803x_suspend,
-- .resume = at803x_resume,
-- .flags = PHY_POLL_CABLE_TEST,
-- /* PHY_BASIC_FEATURES */
-- .config_intr = at803x_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
-- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at8032_cable_test_get_status,
-- .read_status = at803x_read_status,
-- .soft_reset = genphy_soft_reset,
-- .config_aneg = at803x_config_aneg,
--}, {
-- /* Qualcomm Atheros QCA9561 */
-- PHY_ID_MATCH_EXACT(QCA9561_PHY_ID),
-- .name = "Qualcomm Atheros QCA9561 built-in PHY",
-- .probe = at803x_probe,
-- .suspend = at803x_suspend,
-- .resume = at803x_resume,
-- .flags = PHY_POLL_CABLE_TEST,
-- /* PHY_BASIC_FEATURES */
-- .config_intr = at803x_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
-- .cable_test_start = at803x_cable_test_start,
-- .cable_test_get_status = at8032_cable_test_get_status,
-- .read_status = at803x_read_status,
-- .soft_reset = genphy_soft_reset,
-- .config_aneg = at803x_config_aneg,
--}, {
-- /* QCA8337 */
-- .phy_id = QCA8337_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "Qualcomm Atheros 8337 internal PHY",
-- /* PHY_GBIT_FEATURES */
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca83xx_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = qca83xx_get_sset_count,
-- .get_strings = qca83xx_get_strings,
-- .get_stats = qca83xx_get_stats,
-- .suspend = qca8337_suspend,
-- .resume = qca83xx_resume,
--}, {
-- /* QCA8327-A from switch QCA8327-AL1A */
-- .phy_id = QCA8327_A_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "Qualcomm Atheros 8327-A internal PHY",
-- /* PHY_GBIT_FEATURES */
-- .link_change_notify = qca83xx_link_change_notify,
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca8327_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = qca83xx_get_sset_count,
-- .get_strings = qca83xx_get_strings,
-- .get_stats = qca83xx_get_stats,
-- .suspend = qca8327_suspend,
-- .resume = qca83xx_resume,
--}, {
-- /* QCA8327-B from switch QCA8327-BL1A */
-- .phy_id = QCA8327_B_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "Qualcomm Atheros 8327-B internal PHY",
-- /* PHY_GBIT_FEATURES */
-- .link_change_notify = qca83xx_link_change_notify,
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca8327_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = qca83xx_get_sset_count,
-- .get_strings = qca83xx_get_strings,
-- .get_stats = qca83xx_get_stats,
-- .suspend = qca8327_suspend,
-- .resume = qca83xx_resume,
--}, {
-- /* Qualcomm QCA8081 */
-- PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
-- .name = "Qualcomm QCA8081",
-- .flags = PHY_POLL_CABLE_TEST,
-- .probe = at803x_probe,
-- .config_intr = at803x_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
-- .get_tunable = at803x_get_tunable,
-- .set_tunable = at803x_set_tunable,
-- .set_wol = at803x_set_wol,
-- .get_wol = at803x_get_wol,
-- .get_features = qca808x_get_features,
-- .config_aneg = qca808x_config_aneg,
-- .suspend = genphy_suspend,
-- .resume = genphy_resume,
-- .read_status = qca808x_read_status,
-- .config_init = qca808x_config_init,
-- .soft_reset = qca808x_soft_reset,
-- .cable_test_start = qca808x_cable_test_start,
-- .cable_test_get_status = qca808x_cable_test_get_status,
-- .link_change_notify = qca808x_link_change_notify,
-- .led_brightness_set = qca808x_led_brightness_set,
-- .led_blink_set = qca808x_led_blink_set,
-- .led_hw_is_supported = qca808x_led_hw_is_supported,
-- .led_hw_control_set = qca808x_led_hw_control_set,
-- .led_hw_control_get = qca808x_led_hw_control_get,
-- .led_polarity_set = qca808x_led_polarity_set,
--}, };
--
--module_phy_driver(at803x_driver);
--
--static struct mdio_device_id __maybe_unused atheros_tbl[] = {
-- { ATH8030_PHY_ID, AT8030_PHY_ID_MASK },
-- { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
-- { }
--};
--
--MODULE_DEVICE_TABLE(mdio, atheros_tbl);
---- /dev/null
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -0,0 +1,2759 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * drivers/net/phy/at803x.c
-+ *
-+ * Driver for Qualcomm Atheros AR803x PHY
-+ *
-+ * Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
-+ */
-+
-+#include <linux/phy.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ethtool_netlink.h>
-+#include <linux/bitfield.h>
-+#include <linux/regulator/of_regulator.h>
-+#include <linux/regulator/driver.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/of.h>
-+#include <linux/phylink.h>
-+#include <linux/sfp.h>
-+#include <dt-bindings/net/qca-ar803x.h>
-+
-+#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
-+#define AT803X_SFC_ASSERT_CRS BIT(11)
-+#define AT803X_SFC_FORCE_LINK BIT(10)
-+#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5)
-+#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3
-+#define AT803X_SFC_MANUAL_MDIX 0x1
-+#define AT803X_SFC_MANUAL_MDI 0x0
-+#define AT803X_SFC_SQE_TEST BIT(2)
-+#define AT803X_SFC_POLARITY_REVERSAL BIT(1)
-+#define AT803X_SFC_DISABLE_JABBER BIT(0)
-+
-+#define AT803X_SPECIFIC_STATUS 0x11
-+#define AT803X_SS_SPEED_MASK GENMASK(15, 14)
-+#define AT803X_SS_SPEED_1000 2
-+#define AT803X_SS_SPEED_100 1
-+#define AT803X_SS_SPEED_10 0
-+#define AT803X_SS_DUPLEX BIT(13)
-+#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11)
-+#define AT803X_SS_MDIX BIT(6)
-+
-+#define QCA808X_SS_SPEED_MASK GENMASK(9, 7)
-+#define QCA808X_SS_SPEED_2500 4
-+
-+#define AT803X_INTR_ENABLE 0x12
-+#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
-+#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
-+#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13)
-+#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12)
-+#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11)
-+#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10)
-+#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8)
-+#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7)
-+#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5)
-+#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1)
-+#define AT803X_INTR_ENABLE_WOL BIT(0)
-+
-+#define AT803X_INTR_STATUS 0x13
-+
-+#define AT803X_SMART_SPEED 0x14
-+#define AT803X_SMART_SPEED_ENABLE BIT(5)
-+#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2)
-+#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1)
-+#define AT803X_CDT 0x16
-+#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8)
-+#define AT803X_CDT_ENABLE_TEST BIT(0)
-+#define AT803X_CDT_STATUS 0x1c
-+#define AT803X_CDT_STATUS_STAT_NORMAL 0
-+#define AT803X_CDT_STATUS_STAT_SHORT 1
-+#define AT803X_CDT_STATUS_STAT_OPEN 2
-+#define AT803X_CDT_STATUS_STAT_FAIL 3
-+#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8)
-+#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0)
-+#define AT803X_LED_CONTROL 0x18
-+
-+#define AT803X_PHY_MMD3_WOL_CTRL 0x8012
-+#define AT803X_WOL_EN BIT(5)
-+#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
-+#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
-+#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
-+#define AT803X_REG_CHIP_CONFIG 0x1f
-+#define AT803X_BT_BX_REG_SEL 0x8000
-+
-+#define AT803X_DEBUG_ADDR 0x1D
-+#define AT803X_DEBUG_DATA 0x1E
-+
-+#define AT803X_MODE_CFG_MASK 0x0F
-+#define AT803X_MODE_CFG_BASET_RGMII 0x00
-+#define AT803X_MODE_CFG_BASET_SGMII 0x01
-+#define AT803X_MODE_CFG_BX1000_RGMII_50OHM 0x02
-+#define AT803X_MODE_CFG_BX1000_RGMII_75OHM 0x03
-+#define AT803X_MODE_CFG_BX1000_CONV_50OHM 0x04
-+#define AT803X_MODE_CFG_BX1000_CONV_75OHM 0x05
-+#define AT803X_MODE_CFG_FX100_RGMII_50OHM 0x06
-+#define AT803X_MODE_CFG_FX100_CONV_50OHM 0x07
-+#define AT803X_MODE_CFG_RGMII_AUTO_MDET 0x0B
-+#define AT803X_MODE_CFG_FX100_RGMII_75OHM 0x0E
-+#define AT803X_MODE_CFG_FX100_CONV_75OHM 0x0F
-+
-+#define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
-+#define AT803X_PSSR_MR_AN_COMPLETE 0x0200
-+
-+#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00
-+#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
-+#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
-+#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
-+
-+#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05
-+#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
-+
-+#define AT803X_DEBUG_REG_HIB_CTRL 0x0b
-+#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10)
-+#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
-+#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15)
-+
-+#define AT803X_DEBUG_REG_3C 0x3C
-+
-+#define AT803X_DEBUG_REG_GREEN 0x3D
-+#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
-+
-+#define AT803X_DEBUG_REG_1F 0x1F
-+#define AT803X_DEBUG_PLL_ON BIT(2)
-+#define AT803X_DEBUG_RGMII_1V8 BIT(3)
-+
-+#define MDIO_AZ_DEBUG 0x800D
-+
-+/* AT803x supports either the XTAL input pad, an internal PLL or the
-+ * DSP as clock reference for the clock output pad. The XTAL reference
-+ * is only used for 25 MHz output, all other frequencies need the PLL.
-+ * The DSP as a clock reference is used in synchronous ethernet
-+ * applications.
-+ *
-+ * By default the PLL is only enabled if there is a link. Otherwise
-+ * the PHY will go into low power state and disabled the PLL. You can
-+ * set the PLL_ON bit (see debug register 0x1f) to keep the PLL always
-+ * enabled.
-+ */
-+#define AT803X_MMD7_CLK25M 0x8016
-+#define AT803X_CLK_OUT_MASK GENMASK(4, 2)
-+#define AT803X_CLK_OUT_25MHZ_XTAL 0
-+#define AT803X_CLK_OUT_25MHZ_DSP 1
-+#define AT803X_CLK_OUT_50MHZ_PLL 2
-+#define AT803X_CLK_OUT_50MHZ_DSP 3
-+#define AT803X_CLK_OUT_62_5MHZ_PLL 4
-+#define AT803X_CLK_OUT_62_5MHZ_DSP 5
-+#define AT803X_CLK_OUT_125MHZ_PLL 6
-+#define AT803X_CLK_OUT_125MHZ_DSP 7
-+
-+/* The AR8035 has another mask which is compatible with the AR8031/AR8033 mask
-+ * but doesn't support choosing between XTAL/PLL and DSP.
-+ */
-+#define AT8035_CLK_OUT_MASK GENMASK(4, 3)
-+
-+#define AT803X_CLK_OUT_STRENGTH_MASK GENMASK(8, 7)
-+#define AT803X_CLK_OUT_STRENGTH_FULL 0
-+#define AT803X_CLK_OUT_STRENGTH_HALF 1
-+#define AT803X_CLK_OUT_STRENGTH_QUARTER 2
-+
-+#define AT803X_DEFAULT_DOWNSHIFT 5
-+#define AT803X_MIN_DOWNSHIFT 2
-+#define AT803X_MAX_DOWNSHIFT 9
-+
-+#define AT803X_MMD3_SMARTEEE_CTL1 0x805b
-+#define AT803X_MMD3_SMARTEEE_CTL2 0x805c
-+#define AT803X_MMD3_SMARTEEE_CTL3 0x805d
-+#define AT803X_MMD3_SMARTEEE_CTL3_LPI_EN BIT(8)
-+
-+#define ATH9331_PHY_ID 0x004dd041
-+#define ATH8030_PHY_ID 0x004dd076
-+#define ATH8031_PHY_ID 0x004dd074
-+#define ATH8032_PHY_ID 0x004dd023
-+#define ATH8035_PHY_ID 0x004dd072
-+#define AT8030_PHY_ID_MASK 0xffffffef
-+
-+#define QCA8081_PHY_ID 0x004dd101
-+
-+#define QCA8327_A_PHY_ID 0x004dd033
-+#define QCA8327_B_PHY_ID 0x004dd034
-+#define QCA8337_PHY_ID 0x004dd036
-+#define QCA9561_PHY_ID 0x004dd042
-+#define QCA8K_PHY_ID_MASK 0xffffffff
-+
-+#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0)
-+
-+#define AT803X_PAGE_FIBER 0
-+#define AT803X_PAGE_COPPER 1
-+
-+/* don't turn off internal PLL */
-+#define AT803X_KEEP_PLL_ENABLED BIT(0)
-+#define AT803X_DISABLE_SMARTEEE BIT(1)
-+
-+/* disable hibernation mode */
-+#define AT803X_DISABLE_HIBERNATION_MODE BIT(2)
-+
-+/* ADC threshold */
-+#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80
-+#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0)
-+#define QCA808X_ADC_THRESHOLD_80MV 0
-+#define QCA808X_ADC_THRESHOLD_100MV 0xf0
-+#define QCA808X_ADC_THRESHOLD_200MV 0x0f
-+#define QCA808X_ADC_THRESHOLD_300MV 0xff
-+
-+/* CLD control */
-+#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007
-+#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4)
-+#define QCA808X_8023AZ_AFE_EN 0x90
-+
-+/* AZ control */
-+#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008
-+#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014
-+#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E
-+#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E
-+#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020
-+#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341
-+
-+#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c
-+#define QCA808X_TOP_OPTION1_DATA 0x0
-+
-+#define QCA808X_PHY_MMD3_DEBUG_1 0xa100
-+#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203
-+#define QCA808X_PHY_MMD3_DEBUG_2 0xa101
-+#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad
-+#define QCA808X_PHY_MMD3_DEBUG_3 0xa103
-+#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698
-+#define QCA808X_PHY_MMD3_DEBUG_4 0xa105
-+#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001
-+#define QCA808X_PHY_MMD3_DEBUG_5 0xa106
-+#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111
-+#define QCA808X_PHY_MMD3_DEBUG_6 0xa011
-+#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85
-+
-+/* master/slave seed config */
-+#define QCA808X_PHY_DEBUG_LOCAL_SEED 9
-+#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1)
-+#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2)
-+#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32
-+
-+/* Hibernation yields lower power consumpiton in contrast with normal operation mode.
-+ * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s.
-+ */
-+#define QCA808X_DBG_AN_TEST 0xb
-+#define QCA808X_HIBERNATION_EN BIT(15)
-+
-+#define QCA808X_CDT_ENABLE_TEST BIT(15)
-+#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
-+#define QCA808X_CDT_STATUS BIT(11)
-+#define QCA808X_CDT_LENGTH_UNIT BIT(10)
-+
-+#define QCA808X_MMD3_CDT_STATUS 0x8064
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
-+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
-+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
-+
-+#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
-+#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
-+#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
-+#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
-+
-+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
-+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
-+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
-+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
-+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
-+
-+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
-+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
-+
-+/* NORMAL are MDI with type set to 0 */
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+
-+/* Added for reference of existence but should be handled by wait_for_completion already */
-+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
-+
-+#define QCA808X_MMD7_LED_GLOBAL 0x8073
-+#define QCA808X_LED_BLINK_1 GENMASK(11, 6)
-+#define QCA808X_LED_BLINK_2 GENMASK(5, 0)
-+/* Values are the same for both BLINK_1 and BLINK_2 */
-+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3)
-+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
-+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
-+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
-+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
-+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
-+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
-+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
-+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
-+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0)
-+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
-+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
-+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
-+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
-+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
-+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
-+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
-+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
-+
-+#define QCA808X_MMD7_LED2_CTRL 0x8074
-+#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075
-+#define QCA808X_MMD7_LED1_CTRL 0x8076
-+#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077
-+#define QCA808X_MMD7_LED0_CTRL 0x8078
-+#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2))
-+
-+/* LED hw control pattern is the same for every LED */
-+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0)
-+#define QCA808X_LED_SPEED2500_ON BIT(15)
-+#define QCA808X_LED_SPEED2500_BLINK BIT(14)
-+/* Follow blink trigger even if duplex or speed condition doesn't match */
-+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13)
-+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12)
-+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11)
-+#define QCA808X_LED_TX_BLINK BIT(10)
-+#define QCA808X_LED_RX_BLINK BIT(9)
-+#define QCA808X_LED_TX_ON_10MS BIT(8)
-+#define QCA808X_LED_RX_ON_10MS BIT(7)
-+#define QCA808X_LED_SPEED1000_ON BIT(6)
-+#define QCA808X_LED_SPEED100_ON BIT(5)
-+#define QCA808X_LED_SPEED10_ON BIT(4)
-+#define QCA808X_LED_COLLISION_BLINK BIT(3)
-+#define QCA808X_LED_SPEED1000_BLINK BIT(2)
-+#define QCA808X_LED_SPEED100_BLINK BIT(1)
-+#define QCA808X_LED_SPEED10_BLINK BIT(0)
-+
-+#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079
-+#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2))
-+
-+/* LED force ctrl is the same for every LED
-+ * No documentation exist for this, not even internal one
-+ * with NDA as QCOM gives only info about configuring
-+ * hw control pattern rules and doesn't indicate any way
-+ * to force the LED to specific mode.
-+ * These define comes from reverse and testing and maybe
-+ * lack of some info or some info are not entirely correct.
-+ * For the basic LED control and hw control these finding
-+ * are enough to support LED control in all the required APIs.
-+ *
-+ * On doing some comparison with implementation with qca807x,
-+ * it was found that it's 1:1 equal to it and confirms all the
-+ * reverse done. It was also found further specification with the
-+ * force mode and the blink modes.
-+ */
-+#define QCA808X_LED_FORCE_EN BIT(15)
-+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13)
-+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
-+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
-+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
-+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
-+
-+#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a
-+/* QSDK sets by default 0x46 to this reg that sets BIT 6 for
-+ * LED to active high. It's not clear what BIT 3 and BIT 4 does.
-+ */
-+#define QCA808X_LED_ACTIVE_HIGH BIT(6)
-+
-+/* QCA808X 1G chip type */
-+#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
-+#define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
-+
-+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072
-+#define QCA8081_PHY_FIFO_RSTN BIT(11)
-+
-+MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
-+MODULE_AUTHOR("Matus Ujhelyi");
-+MODULE_LICENSE("GPL");
-+
-+enum stat_access_type {
-+ PHY,
-+ MMD
-+};
-+
-+struct at803x_hw_stat {
-+ const char *string;
-+ u8 reg;
-+ u32 mask;
-+ enum stat_access_type access_type;
-+};
-+
-+static struct at803x_hw_stat qca83xx_hw_stats[] = {
-+ { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
-+ { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
-+ { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
-+};
-+
-+struct at803x_ss_mask {
-+ u16 speed_mask;
-+ u8 speed_shift;
-+};
-+
-+struct at803x_priv {
-+ int flags;
-+ u16 clk_25m_reg;
-+ u16 clk_25m_mask;
-+ u8 smarteee_lpi_tw_1g;
-+ u8 smarteee_lpi_tw_100m;
-+ bool is_fiber;
-+ bool is_1000basex;
-+ struct regulator_dev *vddio_rdev;
-+ struct regulator_dev *vddh_rdev;
-+ u64 stats[ARRAY_SIZE(qca83xx_hw_stats)];
-+ int led_polarity_mode;
-+};
-+
-+struct at803x_context {
-+ u16 bmcr;
-+ u16 advertise;
-+ u16 control1000;
-+ u16 int_enable;
-+ u16 smart_speed;
-+ u16 led_control;
-+};
-+
-+static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data)
-+{
-+ int ret;
-+
-+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ return phy_write(phydev, AT803X_DEBUG_DATA, data);
-+}
-+
-+static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
-+{
-+ int ret;
-+
-+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ return phy_read(phydev, AT803X_DEBUG_DATA);
-+}
-+
-+static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
-+ u16 clear, u16 set)
-+{
-+ u16 val;
-+ int ret;
-+
-+ ret = at803x_debug_reg_read(phydev, reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ val = ret & 0xffff;
-+ val &= ~clear;
-+ val |= set;
-+
-+ return phy_write(phydev, AT803X_DEBUG_DATA, val);
-+}
-+
-+static int at803x_write_page(struct phy_device *phydev, int page)
-+{
-+ int mask;
-+ int set;
-+
-+ if (page == AT803X_PAGE_COPPER) {
-+ set = AT803X_BT_BX_REG_SEL;
-+ mask = 0;
-+ } else {
-+ set = 0;
-+ mask = AT803X_BT_BX_REG_SEL;
-+ }
-+
-+ return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set);
-+}
-+
-+static int at803x_read_page(struct phy_device *phydev)
-+{
-+ int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG);
-+
-+ if (ccr < 0)
-+ return ccr;
-+
-+ if (ccr & AT803X_BT_BX_REG_SEL)
-+ return AT803X_PAGE_COPPER;
-+
-+ return AT803X_PAGE_FIBER;
-+}
-+
-+static int at803x_enable_rx_delay(struct phy_device *phydev)
-+{
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0,
-+ AT803X_DEBUG_RX_CLK_DLY_EN);
-+}
-+
-+static int at803x_enable_tx_delay(struct phy_device *phydev)
-+{
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0,
-+ AT803X_DEBUG_TX_CLK_DLY_EN);
-+}
-+
-+static int at803x_disable_rx_delay(struct phy_device *phydev)
-+{
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ AT803X_DEBUG_RX_CLK_DLY_EN, 0);
-+}
-+
-+static int at803x_disable_tx_delay(struct phy_device *phydev)
-+{
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE,
-+ AT803X_DEBUG_TX_CLK_DLY_EN, 0);
-+}
-+
-+/* save relevant PHY registers to private copy */
-+static void at803x_context_save(struct phy_device *phydev,
-+ struct at803x_context *context)
-+{
-+ context->bmcr = phy_read(phydev, MII_BMCR);
-+ context->advertise = phy_read(phydev, MII_ADVERTISE);
-+ context->control1000 = phy_read(phydev, MII_CTRL1000);
-+ context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE);
-+ context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED);
-+ context->led_control = phy_read(phydev, AT803X_LED_CONTROL);
-+}
-+
-+/* restore relevant PHY registers from private copy */
-+static void at803x_context_restore(struct phy_device *phydev,
-+ const struct at803x_context *context)
-+{
-+ phy_write(phydev, MII_BMCR, context->bmcr);
-+ phy_write(phydev, MII_ADVERTISE, context->advertise);
-+ phy_write(phydev, MII_CTRL1000, context->control1000);
-+ phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable);
-+ phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed);
-+ phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
-+}
-+
-+static int at803x_set_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int ret, irq_enabled;
-+
-+ if (wol->wolopts & WAKE_MAGIC) {
-+ struct net_device *ndev = phydev->attached_dev;
-+ const u8 *mac;
-+ unsigned int i;
-+ static const unsigned int offsets[] = {
-+ AT803X_LOC_MAC_ADDR_32_47_OFFSET,
-+ AT803X_LOC_MAC_ADDR_16_31_OFFSET,
-+ AT803X_LOC_MAC_ADDR_0_15_OFFSET,
-+ };
-+
-+ if (!ndev)
-+ return -ENODEV;
-+
-+ mac = (const u8 *)ndev->dev_addr;
-+
-+ if (!is_valid_ether_addr(mac))
-+ return -EINVAL;
-+
-+ for (i = 0; i < 3; i++)
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
-+ mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
-+
-+ /* Enable WOL interrupt */
-+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
-+ if (ret)
-+ return ret;
-+ } else {
-+ /* Disable WOL interrupt */
-+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ /* Clear WOL status */
-+ ret = phy_read(phydev, AT803X_INTR_STATUS);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Check if there are other interrupts except for WOL triggered when PHY is
-+ * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can
-+ * be passed up to the interrupt PIN.
-+ */
-+ irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-+ if (irq_enabled < 0)
-+ return irq_enabled;
-+
-+ irq_enabled &= ~AT803X_INTR_ENABLE_WOL;
-+ if (ret & irq_enabled && !phy_polling_mode(phydev))
-+ phy_trigger_machine(phydev);
-+
-+ return 0;
-+}
-+
-+static void at803x_get_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int value;
-+
-+ wol->supported = WAKE_MAGIC;
-+ wol->wolopts = 0;
-+
-+ value = phy_read(phydev, AT803X_INTR_ENABLE);
-+ if (value < 0)
-+ return;
-+
-+ if (value & AT803X_INTR_ENABLE_WOL)
-+ wol->wolopts |= WAKE_MAGIC;
-+}
-+
-+static int qca83xx_get_sset_count(struct phy_device *phydev)
-+{
-+ return ARRAY_SIZE(qca83xx_hw_stats);
-+}
-+
-+static void qca83xx_get_strings(struct phy_device *phydev, u8 *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) {
-+ strscpy(data + i * ETH_GSTRING_LEN,
-+ qca83xx_hw_stats[i].string, ETH_GSTRING_LEN);
-+ }
-+}
-+
-+static u64 qca83xx_get_stat(struct phy_device *phydev, int i)
-+{
-+ struct at803x_hw_stat stat = qca83xx_hw_stats[i];
-+ struct at803x_priv *priv = phydev->priv;
-+ int val;
-+ u64 ret;
-+
-+ if (stat.access_type == MMD)
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg);
-+ else
-+ val = phy_read(phydev, stat.reg);
-+
-+ if (val < 0) {
-+ ret = U64_MAX;
-+ } else {
-+ val = val & stat.mask;
-+ priv->stats[i] += val;
-+ ret = priv->stats[i];
-+ }
-+
-+ return ret;
-+}
-+
-+static void qca83xx_get_stats(struct phy_device *phydev,
-+ struct ethtool_stats *stats, u64 *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++)
-+ data[i] = qca83xx_get_stat(phydev, i);
-+}
-+
-+static int at803x_suspend(struct phy_device *phydev)
-+{
-+ int value;
-+ int wol_enabled;
-+
-+ value = phy_read(phydev, AT803X_INTR_ENABLE);
-+ wol_enabled = value & AT803X_INTR_ENABLE_WOL;
-+
-+ if (wol_enabled)
-+ value = BMCR_ISOLATE;
-+ else
-+ value = BMCR_PDOWN;
-+
-+ phy_modify(phydev, MII_BMCR, 0, value);
-+
-+ return 0;
-+}
-+
-+static int at803x_resume(struct phy_device *phydev)
-+{
-+ return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
-+}
-+
-+static int at803x_parse_dt(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ struct at803x_priv *priv = phydev->priv;
-+ u32 freq, strength, tw;
-+ unsigned int sel;
-+ int ret;
-+
-+ if (!IS_ENABLED(CONFIG_OF_MDIO))
-+ return 0;
-+
-+ if (of_property_read_bool(node, "qca,disable-smarteee"))
-+ priv->flags |= AT803X_DISABLE_SMARTEEE;
-+
-+ if (of_property_read_bool(node, "qca,disable-hibernation-mode"))
-+ priv->flags |= AT803X_DISABLE_HIBERNATION_MODE;
-+
-+ if (!of_property_read_u32(node, "qca,smarteee-tw-us-1g", &tw)) {
-+ if (!tw || tw > 255) {
-+ phydev_err(phydev, "invalid qca,smarteee-tw-us-1g\n");
-+ return -EINVAL;
-+ }
-+ priv->smarteee_lpi_tw_1g = tw;
-+ }
-+
-+ if (!of_property_read_u32(node, "qca,smarteee-tw-us-100m", &tw)) {
-+ if (!tw || tw > 255) {
-+ phydev_err(phydev, "invalid qca,smarteee-tw-us-100m\n");
-+ return -EINVAL;
-+ }
-+ priv->smarteee_lpi_tw_100m = tw;
-+ }
-+
-+ ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq);
-+ if (!ret) {
-+ switch (freq) {
-+ case 25000000:
-+ sel = AT803X_CLK_OUT_25MHZ_XTAL;
-+ break;
-+ case 50000000:
-+ sel = AT803X_CLK_OUT_50MHZ_PLL;
-+ break;
-+ case 62500000:
-+ sel = AT803X_CLK_OUT_62_5MHZ_PLL;
-+ break;
-+ case 125000000:
-+ sel = AT803X_CLK_OUT_125MHZ_PLL;
-+ break;
-+ default:
-+ phydev_err(phydev, "invalid qca,clk-out-frequency\n");
-+ return -EINVAL;
-+ }
-+
-+ priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel);
-+ priv->clk_25m_mask |= AT803X_CLK_OUT_MASK;
-+ }
-+
-+ ret = of_property_read_u32(node, "qca,clk-out-strength", &strength);
-+ if (!ret) {
-+ priv->clk_25m_mask |= AT803X_CLK_OUT_STRENGTH_MASK;
-+ switch (strength) {
-+ case AR803X_STRENGTH_FULL:
-+ priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_FULL;
-+ break;
-+ case AR803X_STRENGTH_HALF:
-+ priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_HALF;
-+ break;
-+ case AR803X_STRENGTH_QUARTER:
-+ priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_QUARTER;
-+ break;
-+ default:
-+ phydev_err(phydev, "invalid qca,clk-out-strength\n");
-+ return -EINVAL;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int at803x_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct at803x_priv *priv;
-+ int ret;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ /* Init LED polarity mode to -1 */
-+ priv->led_polarity_mode = -1;
-+
-+ phydev->priv = priv;
-+
-+ ret = at803x_parse_dt(phydev);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int at803x_get_features(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int err;
-+
-+ err = genphy_read_abilities(phydev);
-+ if (err)
-+ return err;
-+
-+ if (phydev->drv->phy_id != ATH8031_PHY_ID)
-+ return 0;
-+
-+ /* AR8031/AR8033 have different status registers
-+ * for copper and fiber operation. However, the
-+ * extended status register is the same for both
-+ * operation modes.
-+ *
-+ * As a result of that, ESTATUS_1000_XFULL is set
-+ * to 1 even when operating in copper TP mode.
-+ *
-+ * Remove this mode from the supported link modes
-+ * when not operating in 1000BaseX mode.
-+ */
-+ if (!priv->is_1000basex)
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-+ phydev->supported);
-+
-+ return 0;
-+}
-+
-+static int at803x_smarteee_config(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ u16 mask = 0, val = 0;
-+ int ret;
-+
-+ if (priv->flags & AT803X_DISABLE_SMARTEEE)
-+ return phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+ AT803X_MMD3_SMARTEEE_CTL3,
-+ AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, 0);
-+
-+ if (priv->smarteee_lpi_tw_1g) {
-+ mask |= 0xff00;
-+ val |= priv->smarteee_lpi_tw_1g << 8;
-+ }
-+ if (priv->smarteee_lpi_tw_100m) {
-+ mask |= 0x00ff;
-+ val |= priv->smarteee_lpi_tw_100m;
-+ }
-+ if (!mask)
-+ return 0;
-+
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL1,
-+ mask, val);
-+ if (ret)
-+ return ret;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3,
-+ AT803X_MMD3_SMARTEEE_CTL3_LPI_EN,
-+ AT803X_MMD3_SMARTEEE_CTL3_LPI_EN);
-+}
-+
-+static int at803x_clk_out_config(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+
-+ if (!priv->clk_25m_mask)
-+ return 0;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, AT803X_MMD7_CLK25M,
-+ priv->clk_25m_mask, priv->clk_25m_reg);
-+}
-+
-+static int at8031_pll_config(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+
-+ /* The default after hardware reset is PLL OFF. After a soft reset, the
-+ * values are retained.
-+ */
-+ if (priv->flags & AT803X_KEEP_PLL_ENABLED)
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-+ 0, AT803X_DEBUG_PLL_ON);
-+ else
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-+ AT803X_DEBUG_PLL_ON, 0);
-+}
-+
-+static int at803x_hibernation_mode_config(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+
-+ /* The default after hardware reset is hibernation mode enabled. After
-+ * software reset, the value is retained.
-+ */
-+ if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE))
-+ return 0;
-+
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-+ AT803X_DEBUG_HIB_CTRL_PS_HIB_EN, 0);
-+}
-+
-+static int at803x_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* The RX and TX delay default is:
-+ * after HW reset: RX delay enabled and TX delay disabled
-+ * after SW reset: RX delay enabled, while TX delay retains the
-+ * value before reset.
-+ */
-+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
-+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
-+ ret = at803x_enable_rx_delay(phydev);
-+ else
-+ ret = at803x_disable_rx_delay(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
-+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
-+ ret = at803x_enable_tx_delay(phydev);
-+ else
-+ ret = at803x_disable_tx_delay(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at803x_smarteee_config(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at803x_clk_out_config(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at803x_hibernation_mode_config(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Ar803x extended next page bit is enabled by default. Cisco
-+ * multigig switches read this bit and attempt to negotiate 10Gbps
-+ * rates even if the next page bit is disabled. This is incorrect
-+ * behaviour but we still need to accommodate it. XNP is only needed
-+ * for 10Gbps support, so disable XNP.
-+ */
-+ return phy_modify(phydev, MII_ADVERTISE, MDIO_AN_CTRL1_XNP, 0);
-+}
-+
-+static int at803x_ack_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_read(phydev, AT803X_INTR_STATUS);
-+
-+ return (err < 0) ? err : 0;
-+}
-+
-+static int at803x_config_intr(struct phy_device *phydev)
-+{
-+ int err;
-+ int value;
-+
-+ value = phy_read(phydev, AT803X_INTR_ENABLE);
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+ /* Clear any pending interrupts */
-+ err = at803x_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
-+ value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
-+ value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
-+ value |= AT803X_INTR_ENABLE_LINK_FAIL;
-+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
-+
-+ err = phy_write(phydev, AT803X_INTR_ENABLE, value);
-+ } else {
-+ err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
-+ if (err)
-+ return err;
-+
-+ /* Clear any pending interrupts */
-+ err = at803x_ack_interrupt(phydev);
-+ }
-+
-+ return err;
-+}
-+
-+static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev)
-+{
-+ int irq_status, int_enabled;
-+
-+ irq_status = phy_read(phydev, AT803X_INTR_STATUS);
-+ if (irq_status < 0) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ /* Read the current enabled interrupts */
-+ int_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-+ if (int_enabled < 0) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ /* See if this was one of our enabled interrupts */
-+ if (!(irq_status & int_enabled))
-+ return IRQ_NONE;
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void at803x_link_change_notify(struct phy_device *phydev)
-+{
-+ /*
-+ * Conduct a hardware reset for AT8030 every time a link loss is
-+ * signalled. This is necessary to circumvent a hardware bug that
-+ * occurs when the cable is unplugged while TX packets are pending
-+ * in the FIFO. In such cases, the FIFO enters an error mode it
-+ * cannot recover from by software.
-+ */
-+ if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) {
-+ struct at803x_context context;
-+
-+ at803x_context_save(phydev, &context);
-+
-+ phy_device_reset(phydev, 1);
-+ usleep_range(1000, 2000);
-+ phy_device_reset(phydev, 0);
-+ usleep_range(1000, 2000);
-+
-+ at803x_context_restore(phydev, &context);
-+
-+ phydev_dbg(phydev, "%s(): phy was reset\n", __func__);
-+ }
-+}
-+
-+static int at803x_read_specific_status(struct phy_device *phydev,
-+ struct at803x_ss_mask ss_mask)
-+{
-+ int ss;
-+
-+ /* Read the AT8035 PHY-Specific Status register, which indicates the
-+ * speed and duplex that the PHY is actually using, irrespective of
-+ * whether we are in autoneg mode or not.
-+ */
-+ ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
-+ if (ss < 0)
-+ return ss;
-+
-+ if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
-+ int sfc, speed;
-+
-+ sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
-+ if (sfc < 0)
-+ return sfc;
-+
-+ speed = ss & ss_mask.speed_mask;
-+ speed >>= ss_mask.speed_shift;
-+
-+ switch (speed) {
-+ case AT803X_SS_SPEED_10:
-+ phydev->speed = SPEED_10;
-+ break;
-+ case AT803X_SS_SPEED_100:
-+ phydev->speed = SPEED_100;
-+ break;
-+ case AT803X_SS_SPEED_1000:
-+ phydev->speed = SPEED_1000;
-+ break;
-+ case QCA808X_SS_SPEED_2500:
-+ phydev->speed = SPEED_2500;
-+ break;
-+ }
-+ if (ss & AT803X_SS_DUPLEX)
-+ phydev->duplex = DUPLEX_FULL;
-+ else
-+ phydev->duplex = DUPLEX_HALF;
-+
-+ if (ss & AT803X_SS_MDIX)
-+ phydev->mdix = ETH_TP_MDI_X;
-+ else
-+ phydev->mdix = ETH_TP_MDI;
-+
-+ switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) {
-+ case AT803X_SFC_MANUAL_MDI:
-+ phydev->mdix_ctrl = ETH_TP_MDI;
-+ break;
-+ case AT803X_SFC_MANUAL_MDIX:
-+ phydev->mdix_ctrl = ETH_TP_MDI_X;
-+ break;
-+ case AT803X_SFC_AUTOMATIC_CROSSOVER:
-+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-+ break;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int at803x_read_status(struct phy_device *phydev)
-+{
-+ struct at803x_ss_mask ss_mask = { 0 };
-+ int err, old_link = phydev->link;
-+
-+ /* Update the link, but return if there was an error */
-+ err = genphy_update_link(phydev);
-+ if (err)
-+ return err;
-+
-+ /* why bother the PHY if nothing can have changed */
-+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-+ return 0;
-+
-+ phydev->speed = SPEED_UNKNOWN;
-+ phydev->duplex = DUPLEX_UNKNOWN;
-+ phydev->pause = 0;
-+ phydev->asym_pause = 0;
-+
-+ err = genphy_read_lpa(phydev);
-+ if (err < 0)
-+ return err;
-+
-+ ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
-+ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
-+ err = at803x_read_specific_status(phydev, ss_mask);
-+ if (err < 0)
-+ return err;
-+
-+ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
-+ phy_resolve_aneg_pause(phydev);
-+
-+ return 0;
-+}
-+
-+static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl)
-+{
-+ u16 val;
-+
-+ switch (ctrl) {
-+ case ETH_TP_MDI:
-+ val = AT803X_SFC_MANUAL_MDI;
-+ break;
-+ case ETH_TP_MDI_X:
-+ val = AT803X_SFC_MANUAL_MDIX;
-+ break;
-+ case ETH_TP_MDI_AUTO:
-+ val = AT803X_SFC_AUTOMATIC_CROSSOVER;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL,
-+ AT803X_SFC_MDI_CROSSOVER_MODE_M,
-+ FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
-+}
-+
-+static int at803x_prepare_config_aneg(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Changes of the midx bits are disruptive to the normal operation;
-+ * therefore any changes to these registers must be followed by a
-+ * software reset to take effect.
-+ */
-+ if (ret == 1) {
-+ ret = genphy_soft_reset(phydev);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int at803x_config_aneg(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int ret;
-+
-+ ret = at803x_prepare_config_aneg(phydev);
-+ if (ret)
-+ return ret;
-+
-+ if (priv->is_1000basex)
-+ return genphy_c37_config_aneg(phydev);
-+
-+ return genphy_config_aneg(phydev);
-+}
-+
-+static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
-+{
-+ int val;
-+
-+ val = phy_read(phydev, AT803X_SMART_SPEED);
-+ if (val < 0)
-+ return val;
-+
-+ if (val & AT803X_SMART_SPEED_ENABLE)
-+ *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2;
-+ else
-+ *d = DOWNSHIFT_DEV_DISABLE;
-+
-+ return 0;
-+}
-+
-+static int at803x_set_downshift(struct phy_device *phydev, u8 cnt)
-+{
-+ u16 mask, set;
-+ int ret;
-+
-+ switch (cnt) {
-+ case DOWNSHIFT_DEV_DEFAULT_COUNT:
-+ cnt = AT803X_DEFAULT_DOWNSHIFT;
-+ fallthrough;
-+ case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT:
-+ set = AT803X_SMART_SPEED_ENABLE |
-+ AT803X_SMART_SPEED_BYPASS_TIMER |
-+ FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2);
-+ mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK;
-+ break;
-+ case DOWNSHIFT_DEV_DISABLE:
-+ set = 0;
-+ mask = AT803X_SMART_SPEED_ENABLE |
-+ AT803X_SMART_SPEED_BYPASS_TIMER;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set);
-+
-+ /* After changing the smart speed settings, we need to perform a
-+ * software reset, use phy_init_hw() to make sure we set the
-+ * reapply any values which might got lost during software reset.
-+ */
-+ if (ret == 1)
-+ ret = phy_init_hw(phydev);
-+
-+ return ret;
-+}
-+
-+static int at803x_get_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return at803x_get_downshift(phydev, data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int at803x_set_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, const void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return at803x_set_downshift(phydev, *(const u8 *)data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int at803x_cable_test_result_trans(u16 status)
-+{
-+ switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
-+ case AT803X_CDT_STATUS_STAT_NORMAL:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-+ case AT803X_CDT_STATUS_STAT_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-+ case AT803X_CDT_STATUS_STAT_OPEN:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-+ case AT803X_CDT_STATUS_STAT_FAIL:
-+ default:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-+ }
-+}
-+
-+static bool at803x_cdt_test_failed(u16 status)
-+{
-+ return FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status) ==
-+ AT803X_CDT_STATUS_STAT_FAIL;
-+}
-+
-+static bool at803x_cdt_fault_length_valid(u16 status)
-+{
-+ switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
-+ case AT803X_CDT_STATUS_STAT_OPEN:
-+ case AT803X_CDT_STATUS_STAT_SHORT:
-+ return true;
-+ }
-+ return false;
-+}
-+
-+static int at803x_cdt_fault_length(int dt)
-+{
-+ /* According to the datasheet the distance to the fault is
-+ * DELTA_TIME * 0.824 meters.
-+ *
-+ * The author suspect the correct formula is:
-+ *
-+ * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2
-+ *
-+ * where c is the speed of light, VF is the velocity factor of
-+ * the twisted pair cable, 125MHz the counter frequency and
-+ * we need to divide by 2 because the hardware will measure the
-+ * round trip time to the fault and back to the PHY.
-+ *
-+ * With a VF of 0.69 we get the factor 0.824 mentioned in the
-+ * datasheet.
-+ */
-+ return (dt * 824) / 10;
-+}
-+
-+static int at803x_cdt_start(struct phy_device *phydev,
-+ u32 cdt_start)
-+{
-+ return phy_write(phydev, AT803X_CDT, cdt_start);
-+}
-+
-+static int at803x_cdt_wait_for_completion(struct phy_device *phydev,
-+ u32 cdt_en)
-+{
-+ int val, ret;
-+
-+ /* One test run takes about 25ms */
-+ ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
-+ !(val & cdt_en),
-+ 30000, 100000, true);
-+
-+ return ret < 0 ? ret : 0;
-+}
-+
-+static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair)
-+{
-+ static const int ethtool_pair[] = {
-+ ETHTOOL_A_CABLE_PAIR_A,
-+ ETHTOOL_A_CABLE_PAIR_B,
-+ ETHTOOL_A_CABLE_PAIR_C,
-+ ETHTOOL_A_CABLE_PAIR_D,
-+ };
-+ int ret, val;
-+
-+ val = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
-+ AT803X_CDT_ENABLE_TEST;
-+ ret = at803x_cdt_start(phydev, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = at803x_cdt_wait_for_completion(phydev, AT803X_CDT_ENABLE_TEST);
-+ if (ret)
-+ return ret;
-+
-+ val = phy_read(phydev, AT803X_CDT_STATUS);
-+ if (val < 0)
-+ return val;
-+
-+ if (at803x_cdt_test_failed(val))
-+ return 0;
-+
-+ ethnl_cable_test_result(phydev, ethtool_pair[pair],
-+ at803x_cable_test_result_trans(val));
-+
-+ if (at803x_cdt_fault_length_valid(val)) {
-+ val = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, val);
-+ ethnl_cable_test_fault_length(phydev, ethtool_pair[pair],
-+ at803x_cdt_fault_length(val));
-+ }
-+
-+ return 1;
-+}
-+
-+static int at803x_cable_test_get_status(struct phy_device *phydev,
-+ bool *finished, unsigned long pair_mask)
-+{
-+ int retries = 20;
-+ int pair, ret;
-+
-+ *finished = false;
-+
-+ /* According to the datasheet the CDT can be performed when
-+ * there is no link partner or when the link partner is
-+ * auto-negotiating. Starting the test will restart the AN
-+ * automatically. It seems that doing this repeatedly we will
-+ * get a slot where our link partner won't disturb our
-+ * measurement.
-+ */
-+ while (pair_mask && retries--) {
-+ for_each_set_bit(pair, &pair_mask, 4) {
-+ ret = at803x_cable_test_one_pair(phydev, pair);
-+ if (ret < 0)
-+ return ret;
-+ if (ret)
-+ clear_bit(pair, &pair_mask);
-+ }
-+ if (pair_mask)
-+ msleep(250);
-+ }
-+
-+ *finished = true;
-+
-+ return 0;
-+}
-+
-+static void at803x_cable_test_autoneg(struct phy_device *phydev)
-+{
-+ /* Enable auto-negotiation, but advertise no capabilities, no link
-+ * will be established. A restart of the auto-negotiation is not
-+ * required, because the cable test will automatically break the link.
-+ */
-+ phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
-+ phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA);
-+}
-+
-+static int at803x_cable_test_start(struct phy_device *phydev)
-+{
-+ at803x_cable_test_autoneg(phydev);
-+ /* we do all the (time consuming) work later */
-+ return 0;
-+}
-+
-+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
-+ unsigned int selector)
-+{
-+ struct phy_device *phydev = rdev_get_drvdata(rdev);
-+
-+ if (selector)
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-+ 0, AT803X_DEBUG_RGMII_1V8);
-+ else
-+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
-+ AT803X_DEBUG_RGMII_1V8, 0);
-+}
-+
-+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
-+{
-+ struct phy_device *phydev = rdev_get_drvdata(rdev);
-+ int val;
-+
-+ val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F);
-+ if (val < 0)
-+ return val;
-+
-+ return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0;
-+}
-+
-+static const struct regulator_ops vddio_regulator_ops = {
-+ .list_voltage = regulator_list_voltage_table,
-+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
-+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
-+};
-+
-+static const unsigned int vddio_voltage_table[] = {
-+ 1500000,
-+ 1800000,
-+};
-+
-+static const struct regulator_desc vddio_desc = {
-+ .name = "vddio",
-+ .of_match = of_match_ptr("vddio-regulator"),
-+ .n_voltages = ARRAY_SIZE(vddio_voltage_table),
-+ .volt_table = vddio_voltage_table,
-+ .ops = &vddio_regulator_ops,
-+ .type = REGULATOR_VOLTAGE,
-+ .owner = THIS_MODULE,
-+};
-+
-+static const struct regulator_ops vddh_regulator_ops = {
-+};
-+
-+static const struct regulator_desc vddh_desc = {
-+ .name = "vddh",
-+ .of_match = of_match_ptr("vddh-regulator"),
-+ .n_voltages = 1,
-+ .fixed_uV = 2500000,
-+ .ops = &vddh_regulator_ops,
-+ .type = REGULATOR_VOLTAGE,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int at8031_register_regulators(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ struct device *dev = &phydev->mdio.dev;
-+ struct regulator_config config = { };
-+
-+ config.dev = dev;
-+ config.driver_data = phydev;
-+
-+ priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config);
-+ if (IS_ERR(priv->vddio_rdev)) {
-+ phydev_err(phydev, "failed to register VDDIO regulator\n");
-+ return PTR_ERR(priv->vddio_rdev);
-+ }
-+
-+ priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config);
-+ if (IS_ERR(priv->vddh_rdev)) {
-+ phydev_err(phydev, "failed to register VDDH regulator\n");
-+ return PTR_ERR(priv->vddh_rdev);
-+ }
-+
-+ return 0;
-+}
-+
-+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+{
-+ struct phy_device *phydev = upstream;
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
-+ DECLARE_PHY_INTERFACE_MASK(interfaces);
-+ phy_interface_t iface;
-+
-+ linkmode_zero(phy_support);
-+ phylink_set(phy_support, 1000baseX_Full);
-+ phylink_set(phy_support, 1000baseT_Full);
-+ phylink_set(phy_support, Autoneg);
-+ phylink_set(phy_support, Pause);
-+ phylink_set(phy_support, Asym_Pause);
-+
-+ linkmode_zero(sfp_support);
-+ sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces);
-+ /* Some modules support 10G modes as well as others we support.
-+ * Mask out non-supported modes so the correct interface is picked.
-+ */
-+ linkmode_and(sfp_support, phy_support, sfp_support);
-+
-+ if (linkmode_empty(sfp_support)) {
-+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
-+ return -EINVAL;
-+ }
-+
-+ iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
-+
-+ /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
-+ * interface for use with SFP modules.
-+ * However, some copper modules detected as having a preferred SGMII
-+ * interface do default to and function in 1000Base-X mode, so just
-+ * print a warning and allow such modules, as they may have some chance
-+ * of working.
-+ */
-+ if (iface == PHY_INTERFACE_MODE_SGMII)
-+ dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
-+ else if (iface != PHY_INTERFACE_MODE_1000BASEX)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static const struct sfp_upstream_ops at8031_sfp_ops = {
-+ .attach = phy_sfp_attach,
-+ .detach = phy_sfp_detach,
-+ .module_insert = at8031_sfp_insert,
-+};
-+
-+static int at8031_parse_dt(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ struct at803x_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (of_property_read_bool(node, "qca,keep-pll-enabled"))
-+ priv->flags |= AT803X_KEEP_PLL_ENABLED;
-+
-+ ret = at8031_register_regulators(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = devm_regulator_get_enable_optional(&phydev->mdio.dev,
-+ "vddio");
-+ if (ret) {
-+ phydev_err(phydev, "failed to get VDDIO regulator\n");
-+ return ret;
-+ }
-+
-+ /* Only AR8031/8033 support 1000Base-X for SFP modules */
-+ return phy_sfp_probe(phydev, &at8031_sfp_ops);
-+}
-+
-+static int at8031_probe(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int mode_cfg;
-+ int ccr;
-+ int ret;
-+
-+ ret = at803x_probe(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
-+ * options.
-+ */
-+ ret = at8031_parse_dt(phydev);
-+ if (ret)
-+ return ret;
-+
-+ ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
-+ if (ccr < 0)
-+ return ccr;
-+ mode_cfg = ccr & AT803X_MODE_CFG_MASK;
-+
-+ switch (mode_cfg) {
-+ case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
-+ case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
-+ priv->is_1000basex = true;
-+ fallthrough;
-+ case AT803X_MODE_CFG_FX100_RGMII_50OHM:
-+ case AT803X_MODE_CFG_FX100_RGMII_75OHM:
-+ priv->is_fiber = true;
-+ break;
-+ }
-+
-+ /* Disable WoL in 1588 register which is enabled
-+ * by default
-+ */
-+ return phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+ AT803X_PHY_MMD3_WOL_CTRL,
-+ AT803X_WOL_EN, 0);
-+}
-+
-+static int at8031_config_init(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int ret;
-+
-+ /* Some bootloaders leave the fiber page selected.
-+ * Switch to the appropriate page (fiber or copper), as otherwise we
-+ * read the PHY capabilities from the wrong page.
-+ */
-+ phy_lock_mdio_bus(phydev);
-+ ret = at803x_write_page(phydev,
-+ priv->is_fiber ? AT803X_PAGE_FIBER :
-+ AT803X_PAGE_COPPER);
-+ phy_unlock_mdio_bus(phydev);
-+ if (ret)
-+ return ret;
-+
-+ ret = at8031_pll_config(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ return at803x_config_init(phydev);
-+}
-+
-+static int at8031_set_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int ret;
-+
-+ /* First setup MAC address and enable WOL interrupt */
-+ ret = at803x_set_wol(phydev, wol);
-+ if (ret)
-+ return ret;
-+
-+ if (wol->wolopts & WAKE_MAGIC)
-+ /* Enable WOL function for 1588 */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+ AT803X_PHY_MMD3_WOL_CTRL,
-+ 0, AT803X_WOL_EN);
-+ else
-+ /* Disable WoL function for 1588 */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+ AT803X_PHY_MMD3_WOL_CTRL,
-+ AT803X_WOL_EN, 0);
-+
-+ return ret;
-+}
-+
-+static int at8031_config_intr(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ int err, value = 0;
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED &&
-+ priv->is_fiber) {
-+ /* Clear any pending interrupts */
-+ err = at803x_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
-+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
-+
-+ err = phy_set_bits(phydev, AT803X_INTR_ENABLE, value);
-+ if (err)
-+ return err;
-+ }
-+
-+ return at803x_config_intr(phydev);
-+}
-+
-+/* AR8031 and AR8033 share the same read status logic */
-+static int at8031_read_status(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+
-+ if (priv->is_1000basex)
-+ return genphy_c37_read_status(phydev);
-+
-+ return at803x_read_status(phydev);
-+}
-+
-+/* AR8031 and AR8035 share the same cable test get status reg */
-+static int at8031_cable_test_get_status(struct phy_device *phydev,
-+ bool *finished)
-+{
-+ return at803x_cable_test_get_status(phydev, finished, 0xf);
-+}
-+
-+/* AR8031 and AR8035 share the same cable test start logic */
-+static int at8031_cable_test_start(struct phy_device *phydev)
-+{
-+ at803x_cable_test_autoneg(phydev);
-+ phy_write(phydev, MII_CTRL1000, 0);
-+ /* we do all the (time consuming) work later */
-+ return 0;
-+}
-+
-+/* AR8032, AR9331 and QCA9561 share the same cable test get status reg */
-+static int at8032_cable_test_get_status(struct phy_device *phydev,
-+ bool *finished)
-+{
-+ return at803x_cable_test_get_status(phydev, finished, 0x3);
-+}
-+
-+static int at8035_parse_dt(struct phy_device *phydev)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+
-+ /* Mask is set by the generic at803x_parse_dt
-+ * if property is set. Assume property is set
-+ * with the mask not zero.
-+ */
-+ if (priv->clk_25m_mask) {
-+ /* Fixup for the AR8030/AR8035. This chip has another mask and
-+ * doesn't support the DSP reference. Eg. the lowest bit of the
-+ * mask. The upper two bits select the same frequencies. Mask
-+ * the lowest bit here.
-+ *
-+ * Warning:
-+ * There was no datasheet for the AR8030 available so this is
-+ * just a guess. But the AR8035 is listed as pin compatible
-+ * to the AR8030 so there might be a good chance it works on
-+ * the AR8030 too.
-+ */
-+ priv->clk_25m_reg &= AT8035_CLK_OUT_MASK;
-+ priv->clk_25m_mask &= AT8035_CLK_OUT_MASK;
-+ }
-+
-+ return 0;
-+}
-+
-+/* AR8030 and AR8035 shared the same special mask for clk_25m */
-+static int at8035_probe(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = at803x_probe(phydev);
-+ if (ret)
-+ return ret;
-+
-+ return at8035_parse_dt(phydev);
-+}
-+
-+static int qca83xx_config_init(struct phy_device *phydev)
-+{
-+ u8 switch_revision;
-+
-+ switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK;
-+
-+ switch (switch_revision) {
-+ case 1:
-+ /* For 100M waveform */
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
-+ /* Turn on Gigabit clock */
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
-+ break;
-+
-+ case 2:
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
-+ fallthrough;
-+ case 4:
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
-+ break;
-+ }
-+
-+ /* Following original QCA sourcecode set port to prefer master */
-+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
-+
-+ return 0;
-+}
-+
-+static int qca8327_config_init(struct phy_device *phydev)
-+{
-+ /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
-+ * Disable on init and enable only with 100m speed following
-+ * qca original source code.
-+ */
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+
-+ return qca83xx_config_init(phydev);
-+}
-+
-+static void qca83xx_link_change_notify(struct phy_device *phydev)
-+{
-+ /* Set DAC Amplitude adjustment to +6% for 100m on link running */
-+ if (phydev->state == PHY_RUNNING) {
-+ if (phydev->speed == SPEED_100)
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ QCA8327_DEBUG_MANU_CTRL_EN,
-+ QCA8327_DEBUG_MANU_CTRL_EN);
-+ } else {
-+ /* Reset DAC Amplitude adjustment */
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+ }
-+}
-+
-+static int qca83xx_resume(struct phy_device *phydev)
-+{
-+ int ret, val;
-+
-+ /* Skip reset if not suspended */
-+ if (!phydev->suspended)
-+ return 0;
-+
-+ /* Reinit the port, reset values set by suspend */
-+ qca83xx_config_init(phydev);
-+
-+ /* Reset the port on port resume */
-+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-+
-+ /* On resume from suspend the switch execute a reset and
-+ * restart auto-negotiation. Wait for reset to complete.
-+ */
-+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
-+ 50000, 600000, true);
-+ if (ret)
-+ return ret;
-+
-+ usleep_range(1000, 2000);
-+
-+ return 0;
-+}
-+
-+static int qca83xx_suspend(struct phy_device *phydev)
-+{
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
-+ AT803X_DEBUG_GATE_CLK_IN1000, 0);
-+
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-+ AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
-+ AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
-+
-+ return 0;
-+}
-+
-+static int qca8337_suspend(struct phy_device *phydev)
-+{
-+ /* Only QCA8337 support actual suspend. */
-+ genphy_suspend(phydev);
-+
-+ return qca83xx_suspend(phydev);
-+}
-+
-+static int qca8327_suspend(struct phy_device *phydev)
-+{
-+ u16 mask = 0;
-+
-+ /* QCA8327 cause port unreliability when phy suspend
-+ * is set.
-+ */
-+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-+ phy_modify(phydev, MII_BMCR, mask, 0);
-+
-+ return qca83xx_suspend(phydev);
-+}
-+
-+static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Enable fast retrain */
-+ ret = genphy_c45_fast_retrain(phydev, true);
-+ if (ret)
-+ return ret;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
-+ QCA808X_TOP_OPTION1_DATA);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
-+ QCA808X_MSE_THRESHOLD_20DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
-+ QCA808X_MSE_THRESHOLD_17DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
-+ QCA808X_MSE_THRESHOLD_27DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
-+ QCA808X_MSE_THRESHOLD_28DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
-+ QCA808X_MMD3_DEBUG_1_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
-+ QCA808X_MMD3_DEBUG_4_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
-+ QCA808X_MMD3_DEBUG_5_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
-+ QCA808X_MMD3_DEBUG_3_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
-+ QCA808X_MMD3_DEBUG_6_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
-+ QCA808X_MMD3_DEBUG_2_VALUE);
-+
-+ return 0;
-+}
-+
-+static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
-+{
-+ u16 seed_value;
-+
-+ if (!enable)
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-+ QCA808X_MASTER_SLAVE_SEED_ENABLE, 0);
-+
-+ seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-+ QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE,
-+ FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) |
-+ QCA808X_MASTER_SLAVE_SEED_ENABLE);
-+}
-+
-+static bool qca808x_is_prefer_master(struct phy_device *phydev)
-+{
-+ return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) ||
-+ (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
-+}
-+
-+static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
-+{
-+ return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-+}
-+
-+static int qca808x_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Active adc&vga on 802.3az for the link 1000M and 100M */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
-+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
-+ if (ret)
-+ return ret;
-+
-+ /* Adjust the threshold on 802.3az for the link 1000M */
-+ ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
-+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
-+ QCA808X_MMD3_AZ_TRAINING_VAL);
-+ if (ret)
-+ return ret;
-+
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-+ /* Config the fast retrain for the link 2500M */
-+ ret = qca808x_phy_fast_retrain_config(phydev);
-+ if (ret)
-+ return ret;
-+
-+ ret = genphy_read_master_slave(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!qca808x_is_prefer_master(phydev)) {
-+ /* Enable seed and configure lower ramdom seed to make phy
-+ * linked as slave mode.
-+ */
-+ ret = qca808x_phy_ms_seed_enable(phydev, true);
-+ if (ret)
-+ return ret;
-+ }
-+ }
-+
-+ /* Configure adc threshold as 100mv for the link 10M */
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
-+ QCA808X_ADC_THRESHOLD_MASK,
-+ QCA808X_ADC_THRESHOLD_100MV);
-+}
-+
-+static int qca808x_read_status(struct phy_device *phydev)
-+{
-+ struct at803x_ss_mask ss_mask = { 0 };
-+ int ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
-+ if (ret < 0)
-+ return ret;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
-+ ret & MDIO_AN_10GBT_STAT_LP2_5G);
-+
-+ ret = genphy_read_status(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* qca8081 takes the different bits for speed value from at803x */
-+ ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
-+ ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
-+ ret = at803x_read_specific_status(phydev, ss_mask);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (phydev->link) {
-+ if (phydev->speed == SPEED_2500)
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ else
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ } else {
-+ /* generate seed as a lower random value to make PHY linked as SLAVE easily,
-+ * except for master/slave configuration fault detected or the master mode
-+ * preferred.
-+ *
-+ * the reason for not putting this code into the function link_change_notify is
-+ * the corner case where the link partner is also the qca8081 PHY and the seed
-+ * value is configured as the same value, the link can't be up and no link change
-+ * occurs.
-+ */
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-+ qca808x_is_prefer_master(phydev)) {
-+ qca808x_phy_ms_seed_enable(phydev, false);
-+ } else {
-+ qca808x_phy_ms_seed_enable(phydev, true);
-+ }
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca808x_soft_reset(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = genphy_soft_reset(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev))
-+ ret = qca808x_phy_ms_seed_enable(phydev, true);
-+
-+ return ret;
-+}
-+
-+static bool qca808x_cdt_fault_length_valid(int cdt_code)
-+{
-+ switch (cdt_code) {
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-+ return true;
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int qca808x_cable_test_result_trans(int cdt_code)
-+{
-+ switch (cdt_code) {
-+ case QCA808X_CDT_STATUS_STAT_NORMAL:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
-+ case QCA808X_CDT_STATUS_STAT_FAIL:
-+ default:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-+ }
-+}
-+
-+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
-+ int result)
-+{
-+ int val;
-+ u32 cdt_length_reg = 0;
-+
-+ switch (pair) {
-+ case ETHTOOL_A_CABLE_PAIR_A:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_B:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_C:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_D:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
-+ if (val < 0)
-+ return val;
-+
-+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
-+ else
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
-+
-+ return at803x_cdt_fault_length(val);
-+}
-+
-+static int qca808x_cable_test_start(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* perform CDT with the following configs:
-+ * 1. disable hibernation.
-+ * 2. force PHY working in MDI mode.
-+ * 3. for PHY working in 1000BaseT.
-+ * 4. configure the threshold.
-+ */
-+
-+ ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at803x_config_mdix(phydev, ETH_TP_MDI);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */
-+ phydev->duplex = DUPLEX_FULL;
-+ phydev->speed = SPEED_1000;
-+ ret = genphy_c45_pma_setup_forced(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = genphy_setup_forced(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* configure the thresholds for open, short, pair ok test */
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
-+
-+ return 0;
-+}
-+
-+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
-+ u16 status)
-+{
-+ int length, result;
-+ u16 pair_code;
-+
-+ switch (pair) {
-+ case ETHTOOL_A_CABLE_PAIR_A:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_B:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_C:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_D:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ result = qca808x_cable_test_result_trans(pair_code);
-+ ethnl_cable_test_result(phydev, pair, result);
-+
-+ if (qca808x_cdt_fault_length_valid(pair_code)) {
-+ length = qca808x_cdt_fault_length(phydev, pair, result);
-+ ethnl_cable_test_fault_length(phydev, pair, length);
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
-+{
-+ int ret, val;
-+
-+ *finished = false;
-+
-+ val = QCA808X_CDT_ENABLE_TEST |
-+ QCA808X_CDT_LENGTH_UNIT;
-+ ret = at803x_cdt_start(phydev, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
-+ if (ret)
-+ return ret;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
-+ if (val < 0)
-+ return val;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-+ if (ret)
-+ return ret;
-+
-+ *finished = true;
-+
-+ return 0;
-+}
-+
-+static int qca808x_get_features(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = genphy_c45_pma_read_abilities(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* The autoneg ability is not existed in bit3 of MMD7.1,
-+ * but it is supported by qca808x PHY, so we add it here
-+ * manually.
-+ */
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
-+
-+ /* As for the qca8081 1G version chip, the 2500baseT ability is also
-+ * existed in the bit0 of MMD1.21, we need to remove it manually if
-+ * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
-+ */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (QCA808X_PHY_CHIP_TYPE_1G & ret)
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-+
-+ return 0;
-+}
-+
-+static int qca808x_config_aneg(struct phy_device *phydev)
-+{
-+ int phy_ctrl = 0;
-+ int ret;
-+
-+ ret = at803x_prepare_config_aneg(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* The reg MII_BMCR also needs to be configured for force mode, the
-+ * genphy_config_aneg is also needed.
-+ */
-+ if (phydev->autoneg == AUTONEG_DISABLE)
-+ genphy_c45_pma_setup_forced(phydev);
-+
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
-+ phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
-+
-+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-+ MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __genphy_config_aneg(phydev, ret);
-+}
-+
-+static void qca808x_link_change_notify(struct phy_device *phydev)
-+{
-+ /* Assert interface sgmii fifo on link down, deassert it on link up,
-+ * the interface device address is always phy address added by 1.
-+ */
-+ mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
-+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
-+ QCA8081_PHY_FIFO_RSTN,
-+ phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
-+}
-+
-+static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
-+ u16 *offload_trigger)
-+{
-+ /* Parsing specific to netdev trigger */
-+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
-+ *offload_trigger |= QCA808X_LED_TX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
-+ *offload_trigger |= QCA808X_LED_RX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED10_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED100_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED1000_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED2500_ON;
-+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
-+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
-+
-+ if (rules && !*offload_trigger)
-+ return -EOPNOTSUPP;
-+
-+ /* Enable BLINK_CHECK_BYPASS by default to make the LED
-+ * blink even with duplex or speed mode not enabled.
-+ */
-+ *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS;
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN);
-+}
-+
-+static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 offload_trigger = 0;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ return qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-+}
-+
-+static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 reg, offload_trigger = 0;
-+ int ret;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_led_hw_control_enable(phydev, index);
-+ if (ret)
-+ return ret;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_PATTERN_MASK,
-+ offload_trigger);
-+}
-+
-+static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+ int val;
-+
-+ if (index > 2)
-+ return false;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+
-+ return !(val & QCA808X_LED_FORCE_EN);
-+}
-+
-+static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
-+ unsigned long *rules)
-+{
-+ u16 reg;
-+ int val;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ /* Check if we have hw control enabled */
-+ if (qca808x_led_hw_control_status(phydev, index))
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+ if (val & QCA808X_LED_TX_BLINK)
-+ set_bit(TRIGGER_NETDEV_TX, rules);
-+ if (val & QCA808X_LED_RX_BLINK)
-+ set_bit(TRIGGER_NETDEV_RX, rules);
-+ if (val & QCA808X_LED_SPEED10_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+ if (val & QCA808X_LED_SPEED100_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+ if (val & QCA808X_LED_SPEED1000_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+ if (val & QCA808X_LED_SPEED2500_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_2500, rules);
-+ if (val & QCA808X_LED_HALF_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-+ if (val & QCA808X_LED_FULL_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_PATTERN_MASK);
-+}
-+
-+static int qca808x_led_brightness_set(struct phy_device *phydev,
-+ u8 index, enum led_brightness value)
-+{
-+ u16 reg;
-+ int ret;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ if (!value) {
-+ ret = qca808x_led_hw_control_reset(phydev, index);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON :
-+ QCA808X_LED_FORCE_OFF);
-+}
-+
-+static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ int ret;
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ /* Set blink to 50% off, 50% on at 4Hz by default */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
-+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
-+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
-+ if (ret)
-+ return ret;
-+
-+ /* We use BLINK_1 for normal blinking */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
-+ if (ret)
-+ return ret;
-+
-+ /* We set blink to 4Hz, aka 250ms */
-+ *delay_on = 250 / 2;
-+ *delay_off = 250 / 2;
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
-+ unsigned long modes)
-+{
-+ struct at803x_priv *priv = phydev->priv;
-+ bool active_low = false;
-+ u32 mode;
-+
-+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-+ switch (mode) {
-+ case PHY_LED_ACTIVE_LOW:
-+ active_low = true;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ /* PHY polarity is global and can't be set per LED.
-+ * To detect this, check if last requested polarity mode
-+ * match the new one.
-+ */
-+ if (priv->led_polarity_mode >= 0 &&
-+ priv->led_polarity_mode != active_low) {
-+ phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Save the last PHY polarity mode */
-+ priv->led_polarity_mode = active_low;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN,
-+ QCA808X_MMD7_LED_POLARITY_CTRL,
-+ QCA808X_LED_ACTIVE_HIGH,
-+ active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
-+}
-+
-+static struct phy_driver at803x_driver[] = {
-+{
-+ /* Qualcomm Atheros AR8035 */
-+ PHY_ID_MATCH_EXACT(ATH8035_PHY_ID),
-+ .name = "Qualcomm Atheros AR8035",
-+ .flags = PHY_POLL_CABLE_TEST,
-+ .probe = at8035_probe,
-+ .config_aneg = at803x_config_aneg,
-+ .config_init = at803x_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .set_wol = at803x_set_wol,
-+ .get_wol = at803x_get_wol,
-+ .suspend = at803x_suspend,
-+ .resume = at803x_resume,
-+ /* PHY_GBIT_FEATURES */
-+ .read_status = at803x_read_status,
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .get_tunable = at803x_get_tunable,
-+ .set_tunable = at803x_set_tunable,
-+ .cable_test_start = at8031_cable_test_start,
-+ .cable_test_get_status = at8031_cable_test_get_status,
-+}, {
-+ /* Qualcomm Atheros AR8030 */
-+ .phy_id = ATH8030_PHY_ID,
-+ .name = "Qualcomm Atheros AR8030",
-+ .phy_id_mask = AT8030_PHY_ID_MASK,
-+ .probe = at8035_probe,
-+ .config_init = at803x_config_init,
-+ .link_change_notify = at803x_link_change_notify,
-+ .set_wol = at803x_set_wol,
-+ .get_wol = at803x_get_wol,
-+ .suspend = at803x_suspend,
-+ .resume = at803x_resume,
-+ /* PHY_BASIC_FEATURES */
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+}, {
-+ /* Qualcomm Atheros AR8031/AR8033 */
-+ PHY_ID_MATCH_EXACT(ATH8031_PHY_ID),
-+ .name = "Qualcomm Atheros AR8031/AR8033",
-+ .flags = PHY_POLL_CABLE_TEST,
-+ .probe = at8031_probe,
-+ .config_init = at8031_config_init,
-+ .config_aneg = at803x_config_aneg,
-+ .soft_reset = genphy_soft_reset,
-+ .set_wol = at8031_set_wol,
-+ .get_wol = at803x_get_wol,
-+ .suspend = at803x_suspend,
-+ .resume = at803x_resume,
-+ .read_page = at803x_read_page,
-+ .write_page = at803x_write_page,
-+ .get_features = at803x_get_features,
-+ .read_status = at8031_read_status,
-+ .config_intr = at8031_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .get_tunable = at803x_get_tunable,
-+ .set_tunable = at803x_set_tunable,
-+ .cable_test_start = at8031_cable_test_start,
-+ .cable_test_get_status = at8031_cable_test_get_status,
-+}, {
-+ /* Qualcomm Atheros AR8032 */
-+ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID),
-+ .name = "Qualcomm Atheros AR8032",
-+ .probe = at803x_probe,
-+ .flags = PHY_POLL_CABLE_TEST,
-+ .config_init = at803x_config_init,
-+ .link_change_notify = at803x_link_change_notify,
-+ .suspend = at803x_suspend,
-+ .resume = at803x_resume,
-+ /* PHY_BASIC_FEATURES */
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .cable_test_start = at803x_cable_test_start,
-+ .cable_test_get_status = at8032_cable_test_get_status,
-+}, {
-+ /* ATHEROS AR9331 */
-+ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
-+ .name = "Qualcomm Atheros AR9331 built-in PHY",
-+ .probe = at803x_probe,
-+ .suspend = at803x_suspend,
-+ .resume = at803x_resume,
-+ .flags = PHY_POLL_CABLE_TEST,
-+ /* PHY_BASIC_FEATURES */
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .cable_test_start = at803x_cable_test_start,
-+ .cable_test_get_status = at8032_cable_test_get_status,
-+ .read_status = at803x_read_status,
-+ .soft_reset = genphy_soft_reset,
-+ .config_aneg = at803x_config_aneg,
-+}, {
-+ /* Qualcomm Atheros QCA9561 */
-+ PHY_ID_MATCH_EXACT(QCA9561_PHY_ID),
-+ .name = "Qualcomm Atheros QCA9561 built-in PHY",
-+ .probe = at803x_probe,
-+ .suspend = at803x_suspend,
-+ .resume = at803x_resume,
-+ .flags = PHY_POLL_CABLE_TEST,
-+ /* PHY_BASIC_FEATURES */
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .cable_test_start = at803x_cable_test_start,
-+ .cable_test_get_status = at8032_cable_test_get_status,
-+ .read_status = at803x_read_status,
-+ .soft_reset = genphy_soft_reset,
-+ .config_aneg = at803x_config_aneg,
-+}, {
-+ /* QCA8337 */
-+ .phy_id = QCA8337_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8337 internal PHY",
-+ /* PHY_GBIT_FEATURES */
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca83xx_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
-+ .suspend = qca8337_suspend,
-+ .resume = qca83xx_resume,
-+}, {
-+ /* QCA8327-A from switch QCA8327-AL1A */
-+ .phy_id = QCA8327_A_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8327-A internal PHY",
-+ /* PHY_GBIT_FEATURES */
-+ .link_change_notify = qca83xx_link_change_notify,
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca8327_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
-+ .suspend = qca8327_suspend,
-+ .resume = qca83xx_resume,
-+}, {
-+ /* QCA8327-B from switch QCA8327-BL1A */
-+ .phy_id = QCA8327_B_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8327-B internal PHY",
-+ /* PHY_GBIT_FEATURES */
-+ .link_change_notify = qca83xx_link_change_notify,
-+ .probe = at803x_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca8327_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
-+ .suspend = qca8327_suspend,
-+ .resume = qca83xx_resume,
-+}, {
-+ /* Qualcomm QCA8081 */
-+ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
-+ .name = "Qualcomm QCA8081",
-+ .flags = PHY_POLL_CABLE_TEST,
-+ .probe = at803x_probe,
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .get_tunable = at803x_get_tunable,
-+ .set_tunable = at803x_set_tunable,
-+ .set_wol = at803x_set_wol,
-+ .get_wol = at803x_get_wol,
-+ .get_features = qca808x_get_features,
-+ .config_aneg = qca808x_config_aneg,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
-+ .read_status = qca808x_read_status,
-+ .config_init = qca808x_config_init,
-+ .soft_reset = qca808x_soft_reset,
-+ .cable_test_start = qca808x_cable_test_start,
-+ .cable_test_get_status = qca808x_cable_test_get_status,
-+ .link_change_notify = qca808x_link_change_notify,
-+ .led_brightness_set = qca808x_led_brightness_set,
-+ .led_blink_set = qca808x_led_blink_set,
-+ .led_hw_is_supported = qca808x_led_hw_is_supported,
-+ .led_hw_control_set = qca808x_led_hw_control_set,
-+ .led_hw_control_get = qca808x_led_hw_control_get,
-+ .led_polarity_set = qca808x_led_polarity_set,
-+}, };
-+
-+module_phy_driver(at803x_driver);
-+
-+static struct mdio_device_id __maybe_unused atheros_tbl[] = {
-+ { ATH8030_PHY_ID, AT8030_PHY_ID_MASK },
-+ { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, atheros_tbl);
diff --git a/target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch b/target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch
deleted file mode 100644
index 7d0e1f4a28..0000000000
--- a/target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch
+++ /dev/null
@@ -1,243 +0,0 @@
-From 6fb760972c49490b03f3db2ad64cf30bdd28c54a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 Jan 2024 15:15:20 +0100
-Subject: [PATCH 2/5] net: phy: qcom: create and move functions to shared
- library
-
-Create and move functions to shared library in preparation for qca83xx
-PHY Family to be detached from at803x driver.
-
-Only the shared defines are moved to the shared qcom.h header.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240129141600.2592-3-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/qcom/Kconfig | 4 ++
- drivers/net/phy/qcom/Makefile | 1 +
- drivers/net/phy/qcom/at803x.c | 69 +----------------------------
- drivers/net/phy/qcom/qcom-phy-lib.c | 53 ++++++++++++++++++++++
- drivers/net/phy/qcom/qcom.h | 34 ++++++++++++++
- 5 files changed, 94 insertions(+), 67 deletions(-)
- create mode 100644 drivers/net/phy/qcom/qcom-phy-lib.c
- create mode 100644 drivers/net/phy/qcom/qcom.h
-
---- a/drivers/net/phy/qcom/Kconfig
-+++ b/drivers/net/phy/qcom/Kconfig
-@@ -1,6 +1,10 @@
- # SPDX-License-Identifier: GPL-2.0-only
-+config QCOM_NET_PHYLIB
-+ tristate
-+
- config AT803X_PHY
- tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs"
-+ select QCOM_NET_PHYLIB
- depends on REGULATOR
- help
- Currently supports the AR8030, AR8031, AR8033, AR8035 and internal
---- a/drivers/net/phy/qcom/Makefile
-+++ b/drivers/net/phy/qcom/Makefile
-@@ -1,2 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o
- obj-$(CONFIG_AT803X_PHY) += at803x.o
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -22,6 +22,8 @@
- #include <linux/sfp.h>
- #include <dt-bindings/net/qca-ar803x.h>
-
-+#include "qcom.h"
-+
- #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
- #define AT803X_SFC_ASSERT_CRS BIT(11)
- #define AT803X_SFC_FORCE_LINK BIT(10)
-@@ -84,9 +86,6 @@
- #define AT803X_REG_CHIP_CONFIG 0x1f
- #define AT803X_BT_BX_REG_SEL 0x8000
-
--#define AT803X_DEBUG_ADDR 0x1D
--#define AT803X_DEBUG_DATA 0x1E
--
- #define AT803X_MODE_CFG_MASK 0x0F
- #define AT803X_MODE_CFG_BASET_RGMII 0x00
- #define AT803X_MODE_CFG_BASET_SGMII 0x01
-@@ -103,19 +102,6 @@
- #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
- #define AT803X_PSSR_MR_AN_COMPLETE 0x0200
-
--#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00
--#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
--#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
--#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
--
--#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05
--#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
--
--#define AT803X_DEBUG_REG_HIB_CTRL 0x0b
--#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10)
--#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
--#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15)
--
- #define AT803X_DEBUG_REG_3C 0x3C
-
- #define AT803X_DEBUG_REG_GREEN 0x3D
-@@ -393,18 +379,6 @@ MODULE_DESCRIPTION("Qualcomm Atheros AR8
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-
--enum stat_access_type {
-- PHY,
-- MMD
--};
--
--struct at803x_hw_stat {
-- const char *string;
-- u8 reg;
-- u32 mask;
-- enum stat_access_type access_type;
--};
--
- static struct at803x_hw_stat qca83xx_hw_stats[] = {
- { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
- { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
-@@ -439,45 +413,6 @@ struct at803x_context {
- u16 led_control;
- };
-
--static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data)
--{
-- int ret;
--
-- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-- if (ret < 0)
-- return ret;
--
-- return phy_write(phydev, AT803X_DEBUG_DATA, data);
--}
--
--static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
--{
-- int ret;
--
-- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-- if (ret < 0)
-- return ret;
--
-- return phy_read(phydev, AT803X_DEBUG_DATA);
--}
--
--static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
-- u16 clear, u16 set)
--{
-- u16 val;
-- int ret;
--
-- ret = at803x_debug_reg_read(phydev, reg);
-- if (ret < 0)
-- return ret;
--
-- val = ret & 0xffff;
-- val &= ~clear;
-- val |= set;
--
-- return phy_write(phydev, AT803X_DEBUG_DATA, val);
--}
--
- static int at803x_write_page(struct phy_device *phydev, int page)
- {
- int mask;
---- /dev/null
-+++ b/drivers/net/phy/qcom/qcom-phy-lib.c
-@@ -0,0 +1,53 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/phy.h>
-+#include <linux/module.h>
-+
-+#include "qcom.h"
-+
-+MODULE_DESCRIPTION("Qualcomm PHY driver Common Functions");
-+MODULE_AUTHOR("Matus Ujhelyi");
-+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
-+MODULE_LICENSE("GPL");
-+
-+int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
-+{
-+ int ret;
-+
-+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ return phy_read(phydev, AT803X_DEBUG_DATA);
-+}
-+EXPORT_SYMBOL_GPL(at803x_debug_reg_read);
-+
-+int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
-+ u16 clear, u16 set)
-+{
-+ u16 val;
-+ int ret;
-+
-+ ret = at803x_debug_reg_read(phydev, reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ val = ret & 0xffff;
-+ val &= ~clear;
-+ val |= set;
-+
-+ return phy_write(phydev, AT803X_DEBUG_DATA, val);
-+}
-+EXPORT_SYMBOL_GPL(at803x_debug_reg_mask);
-+
-+int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data)
-+{
-+ int ret;
-+
-+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-+ if (ret < 0)
-+ return ret;
-+
-+ return phy_write(phydev, AT803X_DEBUG_DATA, data);
-+}
-+EXPORT_SYMBOL_GPL(at803x_debug_reg_write);
---- /dev/null
-+++ b/drivers/net/phy/qcom/qcom.h
-@@ -0,0 +1,34 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+
-+#define AT803X_DEBUG_ADDR 0x1D
-+#define AT803X_DEBUG_DATA 0x1E
-+
-+#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00
-+#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
-+#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
-+#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
-+
-+#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05
-+#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
-+
-+#define AT803X_DEBUG_REG_HIB_CTRL 0x0b
-+#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10)
-+#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
-+#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15)
-+
-+enum stat_access_type {
-+ PHY,
-+ MMD
-+};
-+
-+struct at803x_hw_stat {
-+ const char *string;
-+ u8 reg;
-+ u32 mask;
-+ enum stat_access_type access_type;
-+};
-+
-+int at803x_debug_reg_read(struct phy_device *phydev, u16 reg);
-+int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
-+ u16 clear, u16 set);
-+int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data);
diff --git a/target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch b/target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch
deleted file mode 100644
index 6ac09dcb9a..0000000000
--- a/target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch
+++ /dev/null
@@ -1,638 +0,0 @@
-From 2e45d404d99d43bb7127b74b5dea8818df64996c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 Jan 2024 15:15:21 +0100
-Subject: [PATCH 3/5] net: phy: qcom: deatch qca83xx PHY driver from at803x
-
-Deatch qca83xx PHY driver from at803x.
-
-The QCA83xx PHYs implement specific function and doesn't use generic
-at803x so it can be detached from the driver and moved to a dedicated
-one.
-
-Probe function and priv struct is reimplemented to allocate and use
-only the qca83xx specific data. Unused data from at803x PHY driver
-are dropped from at803x priv struct.
-
-This is to make slimmer PHY drivers instead of including lots of bloat
-that would never be used in specific SoC.
-
-A new Kconfig flag QCA83XX_PHY is introduced to compile the new
-introduced PHY driver.
-
-As the Kconfig name starts with Qualcomm the same order is kept.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240129141600.2592-4-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/qcom/Kconfig | 11 +-
- drivers/net/phy/qcom/Makefile | 1 +
- drivers/net/phy/qcom/at803x.c | 235 ----------------------------
- drivers/net/phy/qcom/qca83xx.c | 275 +++++++++++++++++++++++++++++++++
- 4 files changed, 284 insertions(+), 238 deletions(-)
- create mode 100644 drivers/net/phy/qcom/qca83xx.c
-
---- a/drivers/net/phy/qcom/Kconfig
-+++ b/drivers/net/phy/qcom/Kconfig
-@@ -3,9 +3,14 @@ config QCOM_NET_PHYLIB
- tristate
-
- config AT803X_PHY
-- tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs"
-+ tristate "Qualcomm Atheros AR803X PHYs"
- select QCOM_NET_PHYLIB
- depends on REGULATOR
- help
-- Currently supports the AR8030, AR8031, AR8033, AR8035 and internal
-- QCA8337(Internal qca8k PHY) model
-+ Currently supports the AR8030, AR8031, AR8033, AR8035 model
-+
-+config QCA83XX_PHY
-+ tristate "Qualcomm Atheros QCA833x PHYs"
-+ select QCOM_NET_PHYLIB
-+ help
-+ Currently supports the internal QCA8337(Internal qca8k PHY) model
---- a/drivers/net/phy/qcom/Makefile
-+++ b/drivers/net/phy/qcom/Makefile
-@@ -1,3 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o
- obj-$(CONFIG_AT803X_PHY) += at803x.o
-+obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -102,17 +102,10 @@
- #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
- #define AT803X_PSSR_MR_AN_COMPLETE 0x0200
-
--#define AT803X_DEBUG_REG_3C 0x3C
--
--#define AT803X_DEBUG_REG_GREEN 0x3D
--#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
--
- #define AT803X_DEBUG_REG_1F 0x1F
- #define AT803X_DEBUG_PLL_ON BIT(2)
- #define AT803X_DEBUG_RGMII_1V8 BIT(3)
-
--#define MDIO_AZ_DEBUG 0x800D
--
- /* AT803x supports either the XTAL input pad, an internal PLL or the
- * DSP as clock reference for the clock output pad. The XTAL reference
- * is only used for 25 MHz output, all other frequencies need the PLL.
-@@ -163,13 +156,7 @@
-
- #define QCA8081_PHY_ID 0x004dd101
-
--#define QCA8327_A_PHY_ID 0x004dd033
--#define QCA8327_B_PHY_ID 0x004dd034
--#define QCA8337_PHY_ID 0x004dd036
- #define QCA9561_PHY_ID 0x004dd042
--#define QCA8K_PHY_ID_MASK 0xffffffff
--
--#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0)
-
- #define AT803X_PAGE_FIBER 0
- #define AT803X_PAGE_COPPER 1
-@@ -379,12 +366,6 @@ MODULE_DESCRIPTION("Qualcomm Atheros AR8
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-
--static struct at803x_hw_stat qca83xx_hw_stats[] = {
-- { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
-- { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
-- { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
--};
--
- struct at803x_ss_mask {
- u16 speed_mask;
- u8 speed_shift;
-@@ -400,7 +381,6 @@ struct at803x_priv {
- bool is_1000basex;
- struct regulator_dev *vddio_rdev;
- struct regulator_dev *vddh_rdev;
-- u64 stats[ARRAY_SIZE(qca83xx_hw_stats)];
- int led_polarity_mode;
- };
-
-@@ -564,53 +544,6 @@ static void at803x_get_wol(struct phy_de
- wol->wolopts |= WAKE_MAGIC;
- }
-
--static int qca83xx_get_sset_count(struct phy_device *phydev)
--{
-- return ARRAY_SIZE(qca83xx_hw_stats);
--}
--
--static void qca83xx_get_strings(struct phy_device *phydev, u8 *data)
--{
-- int i;
--
-- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) {
-- strscpy(data + i * ETH_GSTRING_LEN,
-- qca83xx_hw_stats[i].string, ETH_GSTRING_LEN);
-- }
--}
--
--static u64 qca83xx_get_stat(struct phy_device *phydev, int i)
--{
-- struct at803x_hw_stat stat = qca83xx_hw_stats[i];
-- struct at803x_priv *priv = phydev->priv;
-- int val;
-- u64 ret;
--
-- if (stat.access_type == MMD)
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg);
-- else
-- val = phy_read(phydev, stat.reg);
--
-- if (val < 0) {
-- ret = U64_MAX;
-- } else {
-- val = val & stat.mask;
-- priv->stats[i] += val;
-- ret = priv->stats[i];
-- }
--
-- return ret;
--}
--
--static void qca83xx_get_stats(struct phy_device *phydev,
-- struct ethtool_stats *stats, u64 *data)
--{
-- int i;
--
-- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++)
-- data[i] = qca83xx_get_stat(phydev, i);
--}
--
- static int at803x_suspend(struct phy_device *phydev)
- {
- int value;
-@@ -1707,124 +1640,6 @@ static int at8035_probe(struct phy_devic
- return at8035_parse_dt(phydev);
- }
-
--static int qca83xx_config_init(struct phy_device *phydev)
--{
-- u8 switch_revision;
--
-- switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK;
--
-- switch (switch_revision) {
-- case 1:
-- /* For 100M waveform */
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
-- /* Turn on Gigabit clock */
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
-- break;
--
-- case 2:
-- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
-- fallthrough;
-- case 4:
-- phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
-- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
-- break;
-- }
--
-- /* Following original QCA sourcecode set port to prefer master */
-- phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
--
-- return 0;
--}
--
--static int qca8327_config_init(struct phy_device *phydev)
--{
-- /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
-- * Disable on init and enable only with 100m speed following
-- * qca original source code.
-- */
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- QCA8327_DEBUG_MANU_CTRL_EN, 0);
--
-- return qca83xx_config_init(phydev);
--}
--
--static void qca83xx_link_change_notify(struct phy_device *phydev)
--{
-- /* Set DAC Amplitude adjustment to +6% for 100m on link running */
-- if (phydev->state == PHY_RUNNING) {
-- if (phydev->speed == SPEED_100)
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- QCA8327_DEBUG_MANU_CTRL_EN,
-- QCA8327_DEBUG_MANU_CTRL_EN);
-- } else {
-- /* Reset DAC Amplitude adjustment */
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-- QCA8327_DEBUG_MANU_CTRL_EN, 0);
-- }
--}
--
--static int qca83xx_resume(struct phy_device *phydev)
--{
-- int ret, val;
--
-- /* Skip reset if not suspended */
-- if (!phydev->suspended)
-- return 0;
--
-- /* Reinit the port, reset values set by suspend */
-- qca83xx_config_init(phydev);
--
-- /* Reset the port on port resume */
-- phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
--
-- /* On resume from suspend the switch execute a reset and
-- * restart auto-negotiation. Wait for reset to complete.
-- */
-- ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
-- 50000, 600000, true);
-- if (ret)
-- return ret;
--
-- usleep_range(1000, 2000);
--
-- return 0;
--}
--
--static int qca83xx_suspend(struct phy_device *phydev)
--{
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
-- AT803X_DEBUG_GATE_CLK_IN1000, 0);
--
-- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-- AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
-- AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
--
-- return 0;
--}
--
--static int qca8337_suspend(struct phy_device *phydev)
--{
-- /* Only QCA8337 support actual suspend. */
-- genphy_suspend(phydev);
--
-- return qca83xx_suspend(phydev);
--}
--
--static int qca8327_suspend(struct phy_device *phydev)
--{
-- u16 mask = 0;
--
-- /* QCA8327 cause port unreliability when phy suspend
-- * is set.
-- */
-- mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-- phy_modify(phydev, MII_BMCR, mask, 0);
--
-- return qca83xx_suspend(phydev);
--}
--
- static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
- {
- int ret;
-@@ -2599,53 +2414,6 @@ static struct phy_driver at803x_driver[]
- .soft_reset = genphy_soft_reset,
- .config_aneg = at803x_config_aneg,
- }, {
-- /* QCA8337 */
-- .phy_id = QCA8337_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "Qualcomm Atheros 8337 internal PHY",
-- /* PHY_GBIT_FEATURES */
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca83xx_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = qca83xx_get_sset_count,
-- .get_strings = qca83xx_get_strings,
-- .get_stats = qca83xx_get_stats,
-- .suspend = qca8337_suspend,
-- .resume = qca83xx_resume,
--}, {
-- /* QCA8327-A from switch QCA8327-AL1A */
-- .phy_id = QCA8327_A_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "Qualcomm Atheros 8327-A internal PHY",
-- /* PHY_GBIT_FEATURES */
-- .link_change_notify = qca83xx_link_change_notify,
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca8327_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = qca83xx_get_sset_count,
-- .get_strings = qca83xx_get_strings,
-- .get_stats = qca83xx_get_stats,
-- .suspend = qca8327_suspend,
-- .resume = qca83xx_resume,
--}, {
-- /* QCA8327-B from switch QCA8327-BL1A */
-- .phy_id = QCA8327_B_PHY_ID,
-- .phy_id_mask = QCA8K_PHY_ID_MASK,
-- .name = "Qualcomm Atheros 8327-B internal PHY",
-- /* PHY_GBIT_FEATURES */
-- .link_change_notify = qca83xx_link_change_notify,
-- .probe = at803x_probe,
-- .flags = PHY_IS_INTERNAL,
-- .config_init = qca8327_config_init,
-- .soft_reset = genphy_soft_reset,
-- .get_sset_count = qca83xx_get_sset_count,
-- .get_strings = qca83xx_get_strings,
-- .get_stats = qca83xx_get_stats,
-- .suspend = qca8327_suspend,
-- .resume = qca83xx_resume,
--}, {
- /* Qualcomm QCA8081 */
- PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
- .name = "Qualcomm QCA8081",
-@@ -2683,9 +2451,6 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
- { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
- { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
- { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
- { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
- { }
---- /dev/null
-+++ b/drivers/net/phy/qcom/qca83xx.c
-@@ -0,0 +1,275 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+
-+#include <linux/phy.h>
-+#include <linux/module.h>
-+
-+#include "qcom.h"
-+
-+#define AT803X_DEBUG_REG_3C 0x3C
-+
-+#define AT803X_DEBUG_REG_GREEN 0x3D
-+#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
-+
-+#define MDIO_AZ_DEBUG 0x800D
-+
-+#define QCA8327_A_PHY_ID 0x004dd033
-+#define QCA8327_B_PHY_ID 0x004dd034
-+#define QCA8337_PHY_ID 0x004dd036
-+#define QCA8K_PHY_ID_MASK 0xffffffff
-+
-+#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0)
-+
-+static struct at803x_hw_stat qca83xx_hw_stats[] = {
-+ { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
-+ { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
-+ { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
-+};
-+
-+struct qca83xx_priv {
-+ u64 stats[ARRAY_SIZE(qca83xx_hw_stats)];
-+};
-+
-+MODULE_DESCRIPTION("Qualcomm Atheros QCA83XX PHY driver");
-+MODULE_AUTHOR("Matus Ujhelyi");
-+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
-+MODULE_LICENSE("GPL");
-+
-+static int qca83xx_get_sset_count(struct phy_device *phydev)
-+{
-+ return ARRAY_SIZE(qca83xx_hw_stats);
-+}
-+
-+static void qca83xx_get_strings(struct phy_device *phydev, u8 *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) {
-+ strscpy(data + i * ETH_GSTRING_LEN,
-+ qca83xx_hw_stats[i].string, ETH_GSTRING_LEN);
-+ }
-+}
-+
-+static u64 qca83xx_get_stat(struct phy_device *phydev, int i)
-+{
-+ struct at803x_hw_stat stat = qca83xx_hw_stats[i];
-+ struct qca83xx_priv *priv = phydev->priv;
-+ int val;
-+ u64 ret;
-+
-+ if (stat.access_type == MMD)
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg);
-+ else
-+ val = phy_read(phydev, stat.reg);
-+
-+ if (val < 0) {
-+ ret = U64_MAX;
-+ } else {
-+ val = val & stat.mask;
-+ priv->stats[i] += val;
-+ ret = priv->stats[i];
-+ }
-+
-+ return ret;
-+}
-+
-+static void qca83xx_get_stats(struct phy_device *phydev,
-+ struct ethtool_stats *stats, u64 *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++)
-+ data[i] = qca83xx_get_stat(phydev, i);
-+}
-+
-+static int qca83xx_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct qca83xx_priv *priv;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ phydev->priv = priv;
-+
-+ return 0;
-+}
-+
-+static int qca83xx_config_init(struct phy_device *phydev)
-+{
-+ u8 switch_revision;
-+
-+ switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK;
-+
-+ switch (switch_revision) {
-+ case 1:
-+ /* For 100M waveform */
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
-+ /* Turn on Gigabit clock */
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
-+ break;
-+
-+ case 2:
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
-+ fallthrough;
-+ case 4:
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
-+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
-+ break;
-+ }
-+
-+ /* Following original QCA sourcecode set port to prefer master */
-+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
-+
-+ return 0;
-+}
-+
-+static int qca8327_config_init(struct phy_device *phydev)
-+{
-+ /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
-+ * Disable on init and enable only with 100m speed following
-+ * qca original source code.
-+ */
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+
-+ return qca83xx_config_init(phydev);
-+}
-+
-+static void qca83xx_link_change_notify(struct phy_device *phydev)
-+{
-+ /* Set DAC Amplitude adjustment to +6% for 100m on link running */
-+ if (phydev->state == PHY_RUNNING) {
-+ if (phydev->speed == SPEED_100)
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ QCA8327_DEBUG_MANU_CTRL_EN,
-+ QCA8327_DEBUG_MANU_CTRL_EN);
-+ } else {
-+ /* Reset DAC Amplitude adjustment */
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+ }
-+}
-+
-+static int qca83xx_resume(struct phy_device *phydev)
-+{
-+ int ret, val;
-+
-+ /* Skip reset if not suspended */
-+ if (!phydev->suspended)
-+ return 0;
-+
-+ /* Reinit the port, reset values set by suspend */
-+ qca83xx_config_init(phydev);
-+
-+ /* Reset the port on port resume */
-+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-+
-+ /* On resume from suspend the switch execute a reset and
-+ * restart auto-negotiation. Wait for reset to complete.
-+ */
-+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
-+ 50000, 600000, true);
-+ if (ret)
-+ return ret;
-+
-+ usleep_range(1000, 2000);
-+
-+ return 0;
-+}
-+
-+static int qca83xx_suspend(struct phy_device *phydev)
-+{
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
-+ AT803X_DEBUG_GATE_CLK_IN1000, 0);
-+
-+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-+ AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
-+ AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
-+
-+ return 0;
-+}
-+
-+static int qca8337_suspend(struct phy_device *phydev)
-+{
-+ /* Only QCA8337 support actual suspend. */
-+ genphy_suspend(phydev);
-+
-+ return qca83xx_suspend(phydev);
-+}
-+
-+static int qca8327_suspend(struct phy_device *phydev)
-+{
-+ u16 mask = 0;
-+
-+ /* QCA8327 cause port unreliability when phy suspend
-+ * is set.
-+ */
-+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-+ phy_modify(phydev, MII_BMCR, mask, 0);
-+
-+ return qca83xx_suspend(phydev);
-+}
-+
-+static struct phy_driver qca83xx_driver[] = {
-+{
-+ /* QCA8337 */
-+ .phy_id = QCA8337_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8337 internal PHY",
-+ /* PHY_GBIT_FEATURES */
-+ .probe = qca83xx_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca83xx_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
-+ .suspend = qca8337_suspend,
-+ .resume = qca83xx_resume,
-+}, {
-+ /* QCA8327-A from switch QCA8327-AL1A */
-+ .phy_id = QCA8327_A_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8327-A internal PHY",
-+ /* PHY_GBIT_FEATURES */
-+ .link_change_notify = qca83xx_link_change_notify,
-+ .probe = qca83xx_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca8327_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
-+ .suspend = qca8327_suspend,
-+ .resume = qca83xx_resume,
-+}, {
-+ /* QCA8327-B from switch QCA8327-BL1A */
-+ .phy_id = QCA8327_B_PHY_ID,
-+ .phy_id_mask = QCA8K_PHY_ID_MASK,
-+ .name = "Qualcomm Atheros 8327-B internal PHY",
-+ /* PHY_GBIT_FEATURES */
-+ .link_change_notify = qca83xx_link_change_notify,
-+ .probe = qca83xx_probe,
-+ .flags = PHY_IS_INTERNAL,
-+ .config_init = qca8327_config_init,
-+ .soft_reset = genphy_soft_reset,
-+ .get_sset_count = qca83xx_get_sset_count,
-+ .get_strings = qca83xx_get_strings,
-+ .get_stats = qca83xx_get_stats,
-+ .suspend = qca8327_suspend,
-+ .resume = qca83xx_resume,
-+}, };
-+
-+module_phy_driver(qca83xx_driver);
-+
-+static struct mdio_device_id __maybe_unused qca83xx_tbl[] = {
-+ { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
-+ { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, qca83xx_tbl);
diff --git a/target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch b/target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch
deleted file mode 100644
index 9c43ad13b4..0000000000
--- a/target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch
+++ /dev/null
@@ -1,1014 +0,0 @@
-From 249d2b80e4db0e38503ed0ec2af6c7401bc099b9 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 Jan 2024 15:15:22 +0100
-Subject: [PATCH 4/5] net: phy: qcom: move additional functions to shared
- library
-
-Move additional functions to shared library in preparation for qca808x
-PHY Family to be detached from at803x driver.
-
-Only the shared defines are moved to the shared qcom.h header.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240129141600.2592-5-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/qcom/at803x.c | 426 +---------------------------
- drivers/net/phy/qcom/qcom-phy-lib.c | 376 ++++++++++++++++++++++++
- drivers/net/phy/qcom/qcom.h | 86 ++++++
- 3 files changed, 463 insertions(+), 425 deletions(-)
-
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -24,65 +24,11 @@
-
- #include "qcom.h"
-
--#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
--#define AT803X_SFC_ASSERT_CRS BIT(11)
--#define AT803X_SFC_FORCE_LINK BIT(10)
--#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5)
--#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3
--#define AT803X_SFC_MANUAL_MDIX 0x1
--#define AT803X_SFC_MANUAL_MDI 0x0
--#define AT803X_SFC_SQE_TEST BIT(2)
--#define AT803X_SFC_POLARITY_REVERSAL BIT(1)
--#define AT803X_SFC_DISABLE_JABBER BIT(0)
--
--#define AT803X_SPECIFIC_STATUS 0x11
--#define AT803X_SS_SPEED_MASK GENMASK(15, 14)
--#define AT803X_SS_SPEED_1000 2
--#define AT803X_SS_SPEED_100 1
--#define AT803X_SS_SPEED_10 0
--#define AT803X_SS_DUPLEX BIT(13)
--#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11)
--#define AT803X_SS_MDIX BIT(6)
--
--#define QCA808X_SS_SPEED_MASK GENMASK(9, 7)
--#define QCA808X_SS_SPEED_2500 4
--
--#define AT803X_INTR_ENABLE 0x12
--#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
--#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
--#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13)
--#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12)
--#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11)
--#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10)
--#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8)
--#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7)
--#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5)
--#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1)
--#define AT803X_INTR_ENABLE_WOL BIT(0)
--
--#define AT803X_INTR_STATUS 0x13
--
--#define AT803X_SMART_SPEED 0x14
--#define AT803X_SMART_SPEED_ENABLE BIT(5)
--#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2)
--#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1)
--#define AT803X_CDT 0x16
--#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8)
--#define AT803X_CDT_ENABLE_TEST BIT(0)
--#define AT803X_CDT_STATUS 0x1c
--#define AT803X_CDT_STATUS_STAT_NORMAL 0
--#define AT803X_CDT_STATUS_STAT_SHORT 1
--#define AT803X_CDT_STATUS_STAT_OPEN 2
--#define AT803X_CDT_STATUS_STAT_FAIL 3
--#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8)
--#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0)
- #define AT803X_LED_CONTROL 0x18
-
- #define AT803X_PHY_MMD3_WOL_CTRL 0x8012
- #define AT803X_WOL_EN BIT(5)
--#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
--#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
--#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
-+
- #define AT803X_REG_CHIP_CONFIG 0x1f
- #define AT803X_BT_BX_REG_SEL 0x8000
-
-@@ -138,10 +84,6 @@
- #define AT803X_CLK_OUT_STRENGTH_HALF 1
- #define AT803X_CLK_OUT_STRENGTH_QUARTER 2
-
--#define AT803X_DEFAULT_DOWNSHIFT 5
--#define AT803X_MIN_DOWNSHIFT 2
--#define AT803X_MAX_DOWNSHIFT 9
--
- #define AT803X_MMD3_SMARTEEE_CTL1 0x805b
- #define AT803X_MMD3_SMARTEEE_CTL2 0x805c
- #define AT803X_MMD3_SMARTEEE_CTL3 0x805d
-@@ -366,11 +308,6 @@ MODULE_DESCRIPTION("Qualcomm Atheros AR8
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-
--struct at803x_ss_mask {
-- u16 speed_mask;
-- u8 speed_shift;
--};
--
- struct at803x_priv {
- int flags;
- u16 clk_25m_reg;
-@@ -470,80 +407,6 @@ static void at803x_context_restore(struc
- phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
- }
-
--static int at803x_set_wol(struct phy_device *phydev,
-- struct ethtool_wolinfo *wol)
--{
-- int ret, irq_enabled;
--
-- if (wol->wolopts & WAKE_MAGIC) {
-- struct net_device *ndev = phydev->attached_dev;
-- const u8 *mac;
-- unsigned int i;
-- static const unsigned int offsets[] = {
-- AT803X_LOC_MAC_ADDR_32_47_OFFSET,
-- AT803X_LOC_MAC_ADDR_16_31_OFFSET,
-- AT803X_LOC_MAC_ADDR_0_15_OFFSET,
-- };
--
-- if (!ndev)
-- return -ENODEV;
--
-- mac = (const u8 *)ndev->dev_addr;
--
-- if (!is_valid_ether_addr(mac))
-- return -EINVAL;
--
-- for (i = 0; i < 3; i++)
-- phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
-- mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
--
-- /* Enable WOL interrupt */
-- ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
-- if (ret)
-- return ret;
-- } else {
-- /* Disable WOL interrupt */
-- ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
-- if (ret)
-- return ret;
-- }
--
-- /* Clear WOL status */
-- ret = phy_read(phydev, AT803X_INTR_STATUS);
-- if (ret < 0)
-- return ret;
--
-- /* Check if there are other interrupts except for WOL triggered when PHY is
-- * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can
-- * be passed up to the interrupt PIN.
-- */
-- irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-- if (irq_enabled < 0)
-- return irq_enabled;
--
-- irq_enabled &= ~AT803X_INTR_ENABLE_WOL;
-- if (ret & irq_enabled && !phy_polling_mode(phydev))
-- phy_trigger_machine(phydev);
--
-- return 0;
--}
--
--static void at803x_get_wol(struct phy_device *phydev,
-- struct ethtool_wolinfo *wol)
--{
-- int value;
--
-- wol->supported = WAKE_MAGIC;
-- wol->wolopts = 0;
--
-- value = phy_read(phydev, AT803X_INTR_ENABLE);
-- if (value < 0)
-- return;
--
-- if (value & AT803X_INTR_ENABLE_WOL)
-- wol->wolopts |= WAKE_MAGIC;
--}
--
- static int at803x_suspend(struct phy_device *phydev)
- {
- int value;
-@@ -816,73 +679,6 @@ static int at803x_config_init(struct phy
- return phy_modify(phydev, MII_ADVERTISE, MDIO_AN_CTRL1_XNP, 0);
- }
-
--static int at803x_ack_interrupt(struct phy_device *phydev)
--{
-- int err;
--
-- err = phy_read(phydev, AT803X_INTR_STATUS);
--
-- return (err < 0) ? err : 0;
--}
--
--static int at803x_config_intr(struct phy_device *phydev)
--{
-- int err;
-- int value;
--
-- value = phy_read(phydev, AT803X_INTR_ENABLE);
--
-- if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-- /* Clear any pending interrupts */
-- err = at803x_ack_interrupt(phydev);
-- if (err)
-- return err;
--
-- value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
-- value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
-- value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
-- value |= AT803X_INTR_ENABLE_LINK_FAIL;
-- value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
--
-- err = phy_write(phydev, AT803X_INTR_ENABLE, value);
-- } else {
-- err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
-- if (err)
-- return err;
--
-- /* Clear any pending interrupts */
-- err = at803x_ack_interrupt(phydev);
-- }
--
-- return err;
--}
--
--static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev)
--{
-- int irq_status, int_enabled;
--
-- irq_status = phy_read(phydev, AT803X_INTR_STATUS);
-- if (irq_status < 0) {
-- phy_error(phydev);
-- return IRQ_NONE;
-- }
--
-- /* Read the current enabled interrupts */
-- int_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-- if (int_enabled < 0) {
-- phy_error(phydev);
-- return IRQ_NONE;
-- }
--
-- /* See if this was one of our enabled interrupts */
-- if (!(irq_status & int_enabled))
-- return IRQ_NONE;
--
-- phy_trigger_machine(phydev);
--
-- return IRQ_HANDLED;
--}
--
- static void at803x_link_change_notify(struct phy_device *phydev)
- {
- /*
-@@ -908,69 +704,6 @@ static void at803x_link_change_notify(st
- }
- }
-
--static int at803x_read_specific_status(struct phy_device *phydev,
-- struct at803x_ss_mask ss_mask)
--{
-- int ss;
--
-- /* Read the AT8035 PHY-Specific Status register, which indicates the
-- * speed and duplex that the PHY is actually using, irrespective of
-- * whether we are in autoneg mode or not.
-- */
-- ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
-- if (ss < 0)
-- return ss;
--
-- if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
-- int sfc, speed;
--
-- sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
-- if (sfc < 0)
-- return sfc;
--
-- speed = ss & ss_mask.speed_mask;
-- speed >>= ss_mask.speed_shift;
--
-- switch (speed) {
-- case AT803X_SS_SPEED_10:
-- phydev->speed = SPEED_10;
-- break;
-- case AT803X_SS_SPEED_100:
-- phydev->speed = SPEED_100;
-- break;
-- case AT803X_SS_SPEED_1000:
-- phydev->speed = SPEED_1000;
-- break;
-- case QCA808X_SS_SPEED_2500:
-- phydev->speed = SPEED_2500;
-- break;
-- }
-- if (ss & AT803X_SS_DUPLEX)
-- phydev->duplex = DUPLEX_FULL;
-- else
-- phydev->duplex = DUPLEX_HALF;
--
-- if (ss & AT803X_SS_MDIX)
-- phydev->mdix = ETH_TP_MDI_X;
-- else
-- phydev->mdix = ETH_TP_MDI;
--
-- switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) {
-- case AT803X_SFC_MANUAL_MDI:
-- phydev->mdix_ctrl = ETH_TP_MDI;
-- break;
-- case AT803X_SFC_MANUAL_MDIX:
-- phydev->mdix_ctrl = ETH_TP_MDI_X;
-- break;
-- case AT803X_SFC_AUTOMATIC_CROSSOVER:
-- phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-- break;
-- }
-- }
--
-- return 0;
--}
--
- static int at803x_read_status(struct phy_device *phydev)
- {
- struct at803x_ss_mask ss_mask = { 0 };
-@@ -1006,50 +739,6 @@ static int at803x_read_status(struct phy
- return 0;
- }
-
--static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl)
--{
-- u16 val;
--
-- switch (ctrl) {
-- case ETH_TP_MDI:
-- val = AT803X_SFC_MANUAL_MDI;
-- break;
-- case ETH_TP_MDI_X:
-- val = AT803X_SFC_MANUAL_MDIX;
-- break;
-- case ETH_TP_MDI_AUTO:
-- val = AT803X_SFC_AUTOMATIC_CROSSOVER;
-- break;
-- default:
-- return 0;
-- }
--
-- return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL,
-- AT803X_SFC_MDI_CROSSOVER_MODE_M,
-- FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
--}
--
--static int at803x_prepare_config_aneg(struct phy_device *phydev)
--{
-- int ret;
--
-- ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
-- if (ret < 0)
-- return ret;
--
-- /* Changes of the midx bits are disruptive to the normal operation;
-- * therefore any changes to these registers must be followed by a
-- * software reset to take effect.
-- */
-- if (ret == 1) {
-- ret = genphy_soft_reset(phydev);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
- static int at803x_config_aneg(struct phy_device *phydev)
- {
- struct at803x_priv *priv = phydev->priv;
-@@ -1065,80 +754,6 @@ static int at803x_config_aneg(struct phy
- return genphy_config_aneg(phydev);
- }
-
--static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
--{
-- int val;
--
-- val = phy_read(phydev, AT803X_SMART_SPEED);
-- if (val < 0)
-- return val;
--
-- if (val & AT803X_SMART_SPEED_ENABLE)
-- *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2;
-- else
-- *d = DOWNSHIFT_DEV_DISABLE;
--
-- return 0;
--}
--
--static int at803x_set_downshift(struct phy_device *phydev, u8 cnt)
--{
-- u16 mask, set;
-- int ret;
--
-- switch (cnt) {
-- case DOWNSHIFT_DEV_DEFAULT_COUNT:
-- cnt = AT803X_DEFAULT_DOWNSHIFT;
-- fallthrough;
-- case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT:
-- set = AT803X_SMART_SPEED_ENABLE |
-- AT803X_SMART_SPEED_BYPASS_TIMER |
-- FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2);
-- mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK;
-- break;
-- case DOWNSHIFT_DEV_DISABLE:
-- set = 0;
-- mask = AT803X_SMART_SPEED_ENABLE |
-- AT803X_SMART_SPEED_BYPASS_TIMER;
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set);
--
-- /* After changing the smart speed settings, we need to perform a
-- * software reset, use phy_init_hw() to make sure we set the
-- * reapply any values which might got lost during software reset.
-- */
-- if (ret == 1)
-- ret = phy_init_hw(phydev);
--
-- return ret;
--}
--
--static int at803x_get_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return at803x_get_downshift(phydev, data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
--static int at803x_set_tunable(struct phy_device *phydev,
-- struct ethtool_tunable *tuna, const void *data)
--{
-- switch (tuna->id) {
-- case ETHTOOL_PHY_DOWNSHIFT:
-- return at803x_set_downshift(phydev, *(const u8 *)data);
-- default:
-- return -EOPNOTSUPP;
-- }
--}
--
- static int at803x_cable_test_result_trans(u16 status)
- {
- switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
-@@ -1170,45 +785,6 @@ static bool at803x_cdt_fault_length_vali
- return false;
- }
-
--static int at803x_cdt_fault_length(int dt)
--{
-- /* According to the datasheet the distance to the fault is
-- * DELTA_TIME * 0.824 meters.
-- *
-- * The author suspect the correct formula is:
-- *
-- * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2
-- *
-- * where c is the speed of light, VF is the velocity factor of
-- * the twisted pair cable, 125MHz the counter frequency and
-- * we need to divide by 2 because the hardware will measure the
-- * round trip time to the fault and back to the PHY.
-- *
-- * With a VF of 0.69 we get the factor 0.824 mentioned in the
-- * datasheet.
-- */
-- return (dt * 824) / 10;
--}
--
--static int at803x_cdt_start(struct phy_device *phydev,
-- u32 cdt_start)
--{
-- return phy_write(phydev, AT803X_CDT, cdt_start);
--}
--
--static int at803x_cdt_wait_for_completion(struct phy_device *phydev,
-- u32 cdt_en)
--{
-- int val, ret;
--
-- /* One test run takes about 25ms */
-- ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
-- !(val & cdt_en),
-- 30000, 100000, true);
--
-- return ret < 0 ? ret : 0;
--}
--
- static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair)
- {
- static const int ethtool_pair[] = {
---- a/drivers/net/phy/qcom/qcom-phy-lib.c
-+++ b/drivers/net/phy/qcom/qcom-phy-lib.c
-@@ -3,6 +3,9 @@
- #include <linux/phy.h>
- #include <linux/module.h>
-
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+
- #include "qcom.h"
-
- MODULE_DESCRIPTION("Qualcomm PHY driver Common Functions");
-@@ -51,3 +54,376 @@ int at803x_debug_reg_write(struct phy_de
- return phy_write(phydev, AT803X_DEBUG_DATA, data);
- }
- EXPORT_SYMBOL_GPL(at803x_debug_reg_write);
-+
-+int at803x_set_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int ret, irq_enabled;
-+
-+ if (wol->wolopts & WAKE_MAGIC) {
-+ struct net_device *ndev = phydev->attached_dev;
-+ const u8 *mac;
-+ unsigned int i;
-+ static const unsigned int offsets[] = {
-+ AT803X_LOC_MAC_ADDR_32_47_OFFSET,
-+ AT803X_LOC_MAC_ADDR_16_31_OFFSET,
-+ AT803X_LOC_MAC_ADDR_0_15_OFFSET,
-+ };
-+
-+ if (!ndev)
-+ return -ENODEV;
-+
-+ mac = (const u8 *)ndev->dev_addr;
-+
-+ if (!is_valid_ether_addr(mac))
-+ return -EINVAL;
-+
-+ for (i = 0; i < 3; i++)
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
-+ mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
-+
-+ /* Enable WOL interrupt */
-+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
-+ if (ret)
-+ return ret;
-+ } else {
-+ /* Disable WOL interrupt */
-+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ /* Clear WOL status */
-+ ret = phy_read(phydev, AT803X_INTR_STATUS);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Check if there are other interrupts except for WOL triggered when PHY is
-+ * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can
-+ * be passed up to the interrupt PIN.
-+ */
-+ irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-+ if (irq_enabled < 0)
-+ return irq_enabled;
-+
-+ irq_enabled &= ~AT803X_INTR_ENABLE_WOL;
-+ if (ret & irq_enabled && !phy_polling_mode(phydev))
-+ phy_trigger_machine(phydev);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(at803x_set_wol);
-+
-+void at803x_get_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int value;
-+
-+ wol->supported = WAKE_MAGIC;
-+ wol->wolopts = 0;
-+
-+ value = phy_read(phydev, AT803X_INTR_ENABLE);
-+ if (value < 0)
-+ return;
-+
-+ if (value & AT803X_INTR_ENABLE_WOL)
-+ wol->wolopts |= WAKE_MAGIC;
-+}
-+EXPORT_SYMBOL_GPL(at803x_get_wol);
-+
-+int at803x_ack_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_read(phydev, AT803X_INTR_STATUS);
-+
-+ return (err < 0) ? err : 0;
-+}
-+EXPORT_SYMBOL_GPL(at803x_ack_interrupt);
-+
-+int at803x_config_intr(struct phy_device *phydev)
-+{
-+ int err;
-+ int value;
-+
-+ value = phy_read(phydev, AT803X_INTR_ENABLE);
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+ /* Clear any pending interrupts */
-+ err = at803x_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
-+ value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
-+ value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
-+ value |= AT803X_INTR_ENABLE_LINK_FAIL;
-+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
-+
-+ err = phy_write(phydev, AT803X_INTR_ENABLE, value);
-+ } else {
-+ err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
-+ if (err)
-+ return err;
-+
-+ /* Clear any pending interrupts */
-+ err = at803x_ack_interrupt(phydev);
-+ }
-+
-+ return err;
-+}
-+EXPORT_SYMBOL_GPL(at803x_config_intr);
-+
-+irqreturn_t at803x_handle_interrupt(struct phy_device *phydev)
-+{
-+ int irq_status, int_enabled;
-+
-+ irq_status = phy_read(phydev, AT803X_INTR_STATUS);
-+ if (irq_status < 0) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ /* Read the current enabled interrupts */
-+ int_enabled = phy_read(phydev, AT803X_INTR_ENABLE);
-+ if (int_enabled < 0) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ /* See if this was one of our enabled interrupts */
-+ if (!(irq_status & int_enabled))
-+ return IRQ_NONE;
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+EXPORT_SYMBOL_GPL(at803x_handle_interrupt);
-+
-+int at803x_read_specific_status(struct phy_device *phydev,
-+ struct at803x_ss_mask ss_mask)
-+{
-+ int ss;
-+
-+ /* Read the AT8035 PHY-Specific Status register, which indicates the
-+ * speed and duplex that the PHY is actually using, irrespective of
-+ * whether we are in autoneg mode or not.
-+ */
-+ ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
-+ if (ss < 0)
-+ return ss;
-+
-+ if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
-+ int sfc, speed;
-+
-+ sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
-+ if (sfc < 0)
-+ return sfc;
-+
-+ speed = ss & ss_mask.speed_mask;
-+ speed >>= ss_mask.speed_shift;
-+
-+ switch (speed) {
-+ case AT803X_SS_SPEED_10:
-+ phydev->speed = SPEED_10;
-+ break;
-+ case AT803X_SS_SPEED_100:
-+ phydev->speed = SPEED_100;
-+ break;
-+ case AT803X_SS_SPEED_1000:
-+ phydev->speed = SPEED_1000;
-+ break;
-+ case QCA808X_SS_SPEED_2500:
-+ phydev->speed = SPEED_2500;
-+ break;
-+ }
-+ if (ss & AT803X_SS_DUPLEX)
-+ phydev->duplex = DUPLEX_FULL;
-+ else
-+ phydev->duplex = DUPLEX_HALF;
-+
-+ if (ss & AT803X_SS_MDIX)
-+ phydev->mdix = ETH_TP_MDI_X;
-+ else
-+ phydev->mdix = ETH_TP_MDI;
-+
-+ switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) {
-+ case AT803X_SFC_MANUAL_MDI:
-+ phydev->mdix_ctrl = ETH_TP_MDI;
-+ break;
-+ case AT803X_SFC_MANUAL_MDIX:
-+ phydev->mdix_ctrl = ETH_TP_MDI_X;
-+ break;
-+ case AT803X_SFC_AUTOMATIC_CROSSOVER:
-+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-+ break;
-+ }
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(at803x_read_specific_status);
-+
-+int at803x_config_mdix(struct phy_device *phydev, u8 ctrl)
-+{
-+ u16 val;
-+
-+ switch (ctrl) {
-+ case ETH_TP_MDI:
-+ val = AT803X_SFC_MANUAL_MDI;
-+ break;
-+ case ETH_TP_MDI_X:
-+ val = AT803X_SFC_MANUAL_MDIX;
-+ break;
-+ case ETH_TP_MDI_AUTO:
-+ val = AT803X_SFC_AUTOMATIC_CROSSOVER;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL,
-+ AT803X_SFC_MDI_CROSSOVER_MODE_M,
-+ FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
-+}
-+EXPORT_SYMBOL_GPL(at803x_config_mdix);
-+
-+int at803x_prepare_config_aneg(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Changes of the midx bits are disruptive to the normal operation;
-+ * therefore any changes to these registers must be followed by a
-+ * software reset to take effect.
-+ */
-+ if (ret == 1) {
-+ ret = genphy_soft_reset(phydev);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg);
-+
-+static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
-+{
-+ int val;
-+
-+ val = phy_read(phydev, AT803X_SMART_SPEED);
-+ if (val < 0)
-+ return val;
-+
-+ if (val & AT803X_SMART_SPEED_ENABLE)
-+ *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2;
-+ else
-+ *d = DOWNSHIFT_DEV_DISABLE;
-+
-+ return 0;
-+}
-+
-+static int at803x_set_downshift(struct phy_device *phydev, u8 cnt)
-+{
-+ u16 mask, set;
-+ int ret;
-+
-+ switch (cnt) {
-+ case DOWNSHIFT_DEV_DEFAULT_COUNT:
-+ cnt = AT803X_DEFAULT_DOWNSHIFT;
-+ fallthrough;
-+ case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT:
-+ set = AT803X_SMART_SPEED_ENABLE |
-+ AT803X_SMART_SPEED_BYPASS_TIMER |
-+ FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2);
-+ mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK;
-+ break;
-+ case DOWNSHIFT_DEV_DISABLE:
-+ set = 0;
-+ mask = AT803X_SMART_SPEED_ENABLE |
-+ AT803X_SMART_SPEED_BYPASS_TIMER;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set);
-+
-+ /* After changing the smart speed settings, we need to perform a
-+ * software reset, use phy_init_hw() to make sure we set the
-+ * reapply any values which might got lost during software reset.
-+ */
-+ if (ret == 1)
-+ ret = phy_init_hw(phydev);
-+
-+ return ret;
-+}
-+
-+int at803x_get_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return at803x_get_downshift(phydev, data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(at803x_get_tunable);
-+
-+int at803x_set_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, const void *data)
-+{
-+ switch (tuna->id) {
-+ case ETHTOOL_PHY_DOWNSHIFT:
-+ return at803x_set_downshift(phydev, *(const u8 *)data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(at803x_set_tunable);
-+
-+int at803x_cdt_fault_length(int dt)
-+{
-+ /* According to the datasheet the distance to the fault is
-+ * DELTA_TIME * 0.824 meters.
-+ *
-+ * The author suspect the correct formula is:
-+ *
-+ * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2
-+ *
-+ * where c is the speed of light, VF is the velocity factor of
-+ * the twisted pair cable, 125MHz the counter frequency and
-+ * we need to divide by 2 because the hardware will measure the
-+ * round trip time to the fault and back to the PHY.
-+ *
-+ * With a VF of 0.69 we get the factor 0.824 mentioned in the
-+ * datasheet.
-+ */
-+ return (dt * 824) / 10;
-+}
-+EXPORT_SYMBOL_GPL(at803x_cdt_fault_length);
-+
-+int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start)
-+{
-+ return phy_write(phydev, AT803X_CDT, cdt_start);
-+}
-+EXPORT_SYMBOL_GPL(at803x_cdt_start);
-+
-+int at803x_cdt_wait_for_completion(struct phy_device *phydev,
-+ u32 cdt_en)
-+{
-+ int val, ret;
-+
-+ /* One test run takes about 25ms */
-+ ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
-+ !(val & cdt_en),
-+ 30000, 100000, true);
-+
-+ return ret < 0 ? ret : 0;
-+}
-+EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion);
---- a/drivers/net/phy/qcom/qcom.h
-+++ b/drivers/net/phy/qcom/qcom.h
-@@ -1,5 +1,63 @@
- /* SPDX-License-Identifier: GPL-2.0 */
-
-+#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
-+#define AT803X_SFC_ASSERT_CRS BIT(11)
-+#define AT803X_SFC_FORCE_LINK BIT(10)
-+#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5)
-+#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3
-+#define AT803X_SFC_MANUAL_MDIX 0x1
-+#define AT803X_SFC_MANUAL_MDI 0x0
-+#define AT803X_SFC_SQE_TEST BIT(2)
-+#define AT803X_SFC_POLARITY_REVERSAL BIT(1)
-+#define AT803X_SFC_DISABLE_JABBER BIT(0)
-+
-+#define AT803X_SPECIFIC_STATUS 0x11
-+#define AT803X_SS_SPEED_MASK GENMASK(15, 14)
-+#define AT803X_SS_SPEED_1000 2
-+#define AT803X_SS_SPEED_100 1
-+#define AT803X_SS_SPEED_10 0
-+#define AT803X_SS_DUPLEX BIT(13)
-+#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11)
-+#define AT803X_SS_MDIX BIT(6)
-+
-+#define QCA808X_SS_SPEED_MASK GENMASK(9, 7)
-+#define QCA808X_SS_SPEED_2500 4
-+
-+#define AT803X_INTR_ENABLE 0x12
-+#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
-+#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
-+#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13)
-+#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12)
-+#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11)
-+#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10)
-+#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8)
-+#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7)
-+#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5)
-+#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1)
-+#define AT803X_INTR_ENABLE_WOL BIT(0)
-+
-+#define AT803X_INTR_STATUS 0x13
-+
-+#define AT803X_SMART_SPEED 0x14
-+#define AT803X_SMART_SPEED_ENABLE BIT(5)
-+#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2)
-+#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1)
-+
-+#define AT803X_CDT 0x16
-+#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8)
-+#define AT803X_CDT_ENABLE_TEST BIT(0)
-+#define AT803X_CDT_STATUS 0x1c
-+#define AT803X_CDT_STATUS_STAT_NORMAL 0
-+#define AT803X_CDT_STATUS_STAT_SHORT 1
-+#define AT803X_CDT_STATUS_STAT_OPEN 2
-+#define AT803X_CDT_STATUS_STAT_FAIL 3
-+#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8)
-+#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0)
-+
-+#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
-+#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
-+#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
-+
- #define AT803X_DEBUG_ADDR 0x1D
- #define AT803X_DEBUG_DATA 0x1E
-
-@@ -16,6 +74,10 @@
- #define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
- #define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15)
-
-+#define AT803X_DEFAULT_DOWNSHIFT 5
-+#define AT803X_MIN_DOWNSHIFT 2
-+#define AT803X_MAX_DOWNSHIFT 9
-+
- enum stat_access_type {
- PHY,
- MMD
-@@ -28,7 +90,31 @@ struct at803x_hw_stat {
- enum stat_access_type access_type;
- };
-
-+struct at803x_ss_mask {
-+ u16 speed_mask;
-+ u8 speed_shift;
-+};
-+
- int at803x_debug_reg_read(struct phy_device *phydev, u16 reg);
- int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
- u16 clear, u16 set);
- int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data);
-+int at803x_set_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol);
-+void at803x_get_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol);
-+int at803x_ack_interrupt(struct phy_device *phydev);
-+int at803x_config_intr(struct phy_device *phydev);
-+irqreturn_t at803x_handle_interrupt(struct phy_device *phydev);
-+int at803x_read_specific_status(struct phy_device *phydev,
-+ struct at803x_ss_mask ss_mask);
-+int at803x_config_mdix(struct phy_device *phydev, u8 ctrl);
-+int at803x_prepare_config_aneg(struct phy_device *phydev);
-+int at803x_get_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, void *data);
-+int at803x_set_tunable(struct phy_device *phydev,
-+ struct ethtool_tunable *tuna, const void *data);
-+int at803x_cdt_fault_length(int dt);
-+int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start);
-+int at803x_cdt_wait_for_completion(struct phy_device *phydev,
-+ u32 cdt_en);
diff --git a/target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch b/target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch
deleted file mode 100644
index 597dcea4c0..0000000000
--- a/target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch
+++ /dev/null
@@ -1,1936 +0,0 @@
-From c89414adf2ec7cd9e7080c419aa5847f1db1009c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 Jan 2024 15:15:23 +0100
-Subject: [PATCH 5/5] net: phy: qcom: detach qca808x PHY driver from at803x
-
-Almost all the QCA8081 PHY driver OPs are specific and only some of them
-use the generic at803x.
-
-To make the at803x code slimmer, move all the specific qca808x regs and
-functions to a dedicated PHY driver.
-
-Probe function and priv struct is reworked to allocate and use only the
-qca808x specific data. Unused data from at803x PHY driver are dropped
-from at803x priv struct.
-
-Also a new Kconfig is introduced QCA808X_PHY, to compile the newly
-introduced PHY driver for QCA8081 PHY.
-
-As the Kconfig name starts with Qualcomm the same order is kept.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240129141600.2592-6-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/qcom/Kconfig | 6 +
- drivers/net/phy/qcom/Makefile | 1 +
- drivers/net/phy/qcom/at803x.c | 897 +------------------------------
- drivers/net/phy/qcom/qca808x.c | 934 +++++++++++++++++++++++++++++++++
- 4 files changed, 942 insertions(+), 896 deletions(-)
- create mode 100644 drivers/net/phy/qcom/qca808x.c
-
---- a/drivers/net/phy/qcom/Kconfig
-+++ b/drivers/net/phy/qcom/Kconfig
-@@ -14,3 +14,9 @@ config QCA83XX_PHY
- select QCOM_NET_PHYLIB
- help
- Currently supports the internal QCA8337(Internal qca8k PHY) model
-+
-+config QCA808X_PHY
-+ tristate "Qualcomm QCA808x PHYs"
-+ select QCOM_NET_PHYLIB
-+ help
-+ Currently supports the QCA8081 model
---- a/drivers/net/phy/qcom/Makefile
-+++ b/drivers/net/phy/qcom/Makefile
-@@ -2,3 +2,4 @@
- obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o
- obj-$(CONFIG_AT803X_PHY) += at803x.o
- obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o
-+obj-$(CONFIG_QCA808X_PHY) += qca808x.o
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -96,8 +96,6 @@
- #define ATH8035_PHY_ID 0x004dd072
- #define AT8030_PHY_ID_MASK 0xffffffef
-
--#define QCA8081_PHY_ID 0x004dd101
--
- #define QCA9561_PHY_ID 0x004dd042
-
- #define AT803X_PAGE_FIBER 0
-@@ -110,201 +108,7 @@
- /* disable hibernation mode */
- #define AT803X_DISABLE_HIBERNATION_MODE BIT(2)
-
--/* ADC threshold */
--#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80
--#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0)
--#define QCA808X_ADC_THRESHOLD_80MV 0
--#define QCA808X_ADC_THRESHOLD_100MV 0xf0
--#define QCA808X_ADC_THRESHOLD_200MV 0x0f
--#define QCA808X_ADC_THRESHOLD_300MV 0xff
--
--/* CLD control */
--#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007
--#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4)
--#define QCA808X_8023AZ_AFE_EN 0x90
--
--/* AZ control */
--#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008
--#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014
--#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E
--#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E
--#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419
--
--#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020
--#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341
--
--#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c
--#define QCA808X_TOP_OPTION1_DATA 0x0
--
--#define QCA808X_PHY_MMD3_DEBUG_1 0xa100
--#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203
--#define QCA808X_PHY_MMD3_DEBUG_2 0xa101
--#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad
--#define QCA808X_PHY_MMD3_DEBUG_3 0xa103
--#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698
--#define QCA808X_PHY_MMD3_DEBUG_4 0xa105
--#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001
--#define QCA808X_PHY_MMD3_DEBUG_5 0xa106
--#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111
--#define QCA808X_PHY_MMD3_DEBUG_6 0xa011
--#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85
--
--/* master/slave seed config */
--#define QCA808X_PHY_DEBUG_LOCAL_SEED 9
--#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1)
--#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2)
--#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32
--
--/* Hibernation yields lower power consumpiton in contrast with normal operation mode.
-- * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s.
-- */
--#define QCA808X_DBG_AN_TEST 0xb
--#define QCA808X_HIBERNATION_EN BIT(15)
--
--#define QCA808X_CDT_ENABLE_TEST BIT(15)
--#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
--#define QCA808X_CDT_STATUS BIT(11)
--#define QCA808X_CDT_LENGTH_UNIT BIT(10)
--
--#define QCA808X_MMD3_CDT_STATUS 0x8064
--#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
--#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
--#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
--#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
--#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
--#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
--
--#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
--#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
--#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
--#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
--
--#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
--#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
--#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
--#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
--#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
--
--#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
--#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
--#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
--#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
--
--/* NORMAL are MDI with type set to 0 */
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI1)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI1)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI2)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI2)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI3)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI3)
--
--/* Added for reference of existence but should be handled by wait_for_completion already */
--#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
--
--#define QCA808X_MMD7_LED_GLOBAL 0x8073
--#define QCA808X_LED_BLINK_1 GENMASK(11, 6)
--#define QCA808X_LED_BLINK_2 GENMASK(5, 0)
--/* Values are the same for both BLINK_1 and BLINK_2 */
--#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3)
--#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
--#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
--#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
--#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
--#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
--#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
--#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
--#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
--#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0)
--#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
--#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
--#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
--#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
--#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
--#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
--#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
--#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
--
--#define QCA808X_MMD7_LED2_CTRL 0x8074
--#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075
--#define QCA808X_MMD7_LED1_CTRL 0x8076
--#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077
--#define QCA808X_MMD7_LED0_CTRL 0x8078
--#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2))
--
--/* LED hw control pattern is the same for every LED */
--#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0)
--#define QCA808X_LED_SPEED2500_ON BIT(15)
--#define QCA808X_LED_SPEED2500_BLINK BIT(14)
--/* Follow blink trigger even if duplex or speed condition doesn't match */
--#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13)
--#define QCA808X_LED_FULL_DUPLEX_ON BIT(12)
--#define QCA808X_LED_HALF_DUPLEX_ON BIT(11)
--#define QCA808X_LED_TX_BLINK BIT(10)
--#define QCA808X_LED_RX_BLINK BIT(9)
--#define QCA808X_LED_TX_ON_10MS BIT(8)
--#define QCA808X_LED_RX_ON_10MS BIT(7)
--#define QCA808X_LED_SPEED1000_ON BIT(6)
--#define QCA808X_LED_SPEED100_ON BIT(5)
--#define QCA808X_LED_SPEED10_ON BIT(4)
--#define QCA808X_LED_COLLISION_BLINK BIT(3)
--#define QCA808X_LED_SPEED1000_BLINK BIT(2)
--#define QCA808X_LED_SPEED100_BLINK BIT(1)
--#define QCA808X_LED_SPEED10_BLINK BIT(0)
--
--#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079
--#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2))
--
--/* LED force ctrl is the same for every LED
-- * No documentation exist for this, not even internal one
-- * with NDA as QCOM gives only info about configuring
-- * hw control pattern rules and doesn't indicate any way
-- * to force the LED to specific mode.
-- * These define comes from reverse and testing and maybe
-- * lack of some info or some info are not entirely correct.
-- * For the basic LED control and hw control these finding
-- * are enough to support LED control in all the required APIs.
-- *
-- * On doing some comparison with implementation with qca807x,
-- * it was found that it's 1:1 equal to it and confirms all the
-- * reverse done. It was also found further specification with the
-- * force mode and the blink modes.
-- */
--#define QCA808X_LED_FORCE_EN BIT(15)
--#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13)
--#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
--#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
--#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
--#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
--
--#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a
--/* QSDK sets by default 0x46 to this reg that sets BIT 6 for
-- * LED to active high. It's not clear what BIT 3 and BIT 4 does.
-- */
--#define QCA808X_LED_ACTIVE_HIGH BIT(6)
--
--/* QCA808X 1G chip type */
--#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
--#define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
--
--#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072
--#define QCA8081_PHY_FIFO_RSTN BIT(11)
--
--MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
-+MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-
-@@ -318,7 +122,6 @@ struct at803x_priv {
- bool is_1000basex;
- struct regulator_dev *vddio_rdev;
- struct regulator_dev *vddh_rdev;
-- int led_polarity_mode;
- };
-
- struct at803x_context {
-@@ -519,9 +322,6 @@ static int at803x_probe(struct phy_devic
- if (!priv)
- return -ENOMEM;
-
-- /* Init LED polarity mode to -1 */
-- priv->led_polarity_mode = -1;
--
- phydev->priv = priv;
-
- ret = at803x_parse_dt(phydev);
-@@ -1216,672 +1016,6 @@ static int at8035_probe(struct phy_devic
- return at8035_parse_dt(phydev);
- }
-
--static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Enable fast retrain */
-- ret = genphy_c45_fast_retrain(phydev, true);
-- if (ret)
-- return ret;
--
-- phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
-- QCA808X_TOP_OPTION1_DATA);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
-- QCA808X_MSE_THRESHOLD_20DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
-- QCA808X_MSE_THRESHOLD_17DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
-- QCA808X_MSE_THRESHOLD_27DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
-- QCA808X_MSE_THRESHOLD_28DB_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
-- QCA808X_MMD3_DEBUG_1_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
-- QCA808X_MMD3_DEBUG_4_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
-- QCA808X_MMD3_DEBUG_5_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
-- QCA808X_MMD3_DEBUG_3_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
-- QCA808X_MMD3_DEBUG_6_VALUE);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
-- QCA808X_MMD3_DEBUG_2_VALUE);
--
-- return 0;
--}
--
--static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
--{
-- u16 seed_value;
--
-- if (!enable)
-- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-- QCA808X_MASTER_SLAVE_SEED_ENABLE, 0);
--
-- seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
-- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-- QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE,
-- FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) |
-- QCA808X_MASTER_SLAVE_SEED_ENABLE);
--}
--
--static bool qca808x_is_prefer_master(struct phy_device *phydev)
--{
-- return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) ||
-- (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
--}
--
--static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
--{
-- return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
--}
--
--static int qca808x_config_init(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Active adc&vga on 802.3az for the link 1000M and 100M */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
-- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
-- if (ret)
-- return ret;
--
-- /* Adjust the threshold on 802.3az for the link 1000M */
-- ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
-- QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
-- QCA808X_MMD3_AZ_TRAINING_VAL);
-- if (ret)
-- return ret;
--
-- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-- /* Config the fast retrain for the link 2500M */
-- ret = qca808x_phy_fast_retrain_config(phydev);
-- if (ret)
-- return ret;
--
-- ret = genphy_read_master_slave(phydev);
-- if (ret < 0)
-- return ret;
--
-- if (!qca808x_is_prefer_master(phydev)) {
-- /* Enable seed and configure lower ramdom seed to make phy
-- * linked as slave mode.
-- */
-- ret = qca808x_phy_ms_seed_enable(phydev, true);
-- if (ret)
-- return ret;
-- }
-- }
--
-- /* Configure adc threshold as 100mv for the link 10M */
-- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
-- QCA808X_ADC_THRESHOLD_MASK,
-- QCA808X_ADC_THRESHOLD_100MV);
--}
--
--static int qca808x_read_status(struct phy_device *phydev)
--{
-- struct at803x_ss_mask ss_mask = { 0 };
-- int ret;
--
-- ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
-- if (ret < 0)
-- return ret;
--
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
-- ret & MDIO_AN_10GBT_STAT_LP2_5G);
--
-- ret = genphy_read_status(phydev);
-- if (ret)
-- return ret;
--
-- /* qca8081 takes the different bits for speed value from at803x */
-- ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
-- ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
-- ret = at803x_read_specific_status(phydev, ss_mask);
-- if (ret < 0)
-- return ret;
--
-- if (phydev->link) {
-- if (phydev->speed == SPEED_2500)
-- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-- else
-- phydev->interface = PHY_INTERFACE_MODE_SGMII;
-- } else {
-- /* generate seed as a lower random value to make PHY linked as SLAVE easily,
-- * except for master/slave configuration fault detected or the master mode
-- * preferred.
-- *
-- * the reason for not putting this code into the function link_change_notify is
-- * the corner case where the link partner is also the qca8081 PHY and the seed
-- * value is configured as the same value, the link can't be up and no link change
-- * occurs.
-- */
-- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-- qca808x_is_prefer_master(phydev)) {
-- qca808x_phy_ms_seed_enable(phydev, false);
-- } else {
-- qca808x_phy_ms_seed_enable(phydev, true);
-- }
-- }
-- }
--
-- return 0;
--}
--
--static int qca808x_soft_reset(struct phy_device *phydev)
--{
-- int ret;
--
-- ret = genphy_soft_reset(phydev);
-- if (ret < 0)
-- return ret;
--
-- if (qca808x_has_fast_retrain_or_slave_seed(phydev))
-- ret = qca808x_phy_ms_seed_enable(phydev, true);
--
-- return ret;
--}
--
--static bool qca808x_cdt_fault_length_valid(int cdt_code)
--{
-- switch (cdt_code) {
-- case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-- return true;
-- default:
-- return false;
-- }
--}
--
--static int qca808x_cable_test_result_trans(int cdt_code)
--{
-- switch (cdt_code) {
-- case QCA808X_CDT_STATUS_STAT_NORMAL:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-- case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-- case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-- return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
-- case QCA808X_CDT_STATUS_STAT_FAIL:
-- default:
-- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-- }
--}
--
--static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
-- int result)
--{
-- int val;
-- u32 cdt_length_reg = 0;
--
-- switch (pair) {
-- case ETHTOOL_A_CABLE_PAIR_A:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_B:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_C:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_D:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
-- if (val < 0)
-- return val;
--
-- if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
-- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
-- else
-- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
--
-- return at803x_cdt_fault_length(val);
--}
--
--static int qca808x_cable_test_start(struct phy_device *phydev)
--{
-- int ret;
--
-- /* perform CDT with the following configs:
-- * 1. disable hibernation.
-- * 2. force PHY working in MDI mode.
-- * 3. for PHY working in 1000BaseT.
-- * 4. configure the threshold.
-- */
--
-- ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0);
-- if (ret < 0)
-- return ret;
--
-- ret = at803x_config_mdix(phydev, ETH_TP_MDI);
-- if (ret < 0)
-- return ret;
--
-- /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */
-- phydev->duplex = DUPLEX_FULL;
-- phydev->speed = SPEED_1000;
-- ret = genphy_c45_pma_setup_forced(phydev);
-- if (ret < 0)
-- return ret;
--
-- ret = genphy_setup_forced(phydev);
-- if (ret < 0)
-- return ret;
--
-- /* configure the thresholds for open, short, pair ok test */
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
-- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
--
-- return 0;
--}
--
--static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
-- u16 status)
--{
-- int length, result;
-- u16 pair_code;
--
-- switch (pair) {
-- case ETHTOOL_A_CABLE_PAIR_A:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_B:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_C:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_D:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- result = qca808x_cable_test_result_trans(pair_code);
-- ethnl_cable_test_result(phydev, pair, result);
--
-- if (qca808x_cdt_fault_length_valid(pair_code)) {
-- length = qca808x_cdt_fault_length(phydev, pair, result);
-- ethnl_cable_test_fault_length(phydev, pair, length);
-- }
--
-- return 0;
--}
--
--static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
--{
-- int ret, val;
--
-- *finished = false;
--
-- val = QCA808X_CDT_ENABLE_TEST |
-- QCA808X_CDT_LENGTH_UNIT;
-- ret = at803x_cdt_start(phydev, val);
-- if (ret)
-- return ret;
--
-- ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
-- if (ret)
-- return ret;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
-- if (val < 0)
-- return val;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-- if (ret)
-- return ret;
--
-- *finished = true;
--
-- return 0;
--}
--
--static int qca808x_get_features(struct phy_device *phydev)
--{
-- int ret;
--
-- ret = genphy_c45_pma_read_abilities(phydev);
-- if (ret)
-- return ret;
--
-- /* The autoneg ability is not existed in bit3 of MMD7.1,
-- * but it is supported by qca808x PHY, so we add it here
-- * manually.
-- */
-- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
--
-- /* As for the qca8081 1G version chip, the 2500baseT ability is also
-- * existed in the bit0 of MMD1.21, we need to remove it manually if
-- * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
-- */
-- ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-- if (ret < 0)
-- return ret;
--
-- if (QCA808X_PHY_CHIP_TYPE_1G & ret)
-- linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
--
-- return 0;
--}
--
--static int qca808x_config_aneg(struct phy_device *phydev)
--{
-- int phy_ctrl = 0;
-- int ret;
--
-- ret = at803x_prepare_config_aneg(phydev);
-- if (ret)
-- return ret;
--
-- /* The reg MII_BMCR also needs to be configured for force mode, the
-- * genphy_config_aneg is also needed.
-- */
-- if (phydev->autoneg == AUTONEG_DISABLE)
-- genphy_c45_pma_setup_forced(phydev);
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
-- phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
--
-- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-- MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
-- if (ret < 0)
-- return ret;
--
-- return __genphy_config_aneg(phydev, ret);
--}
--
--static void qca808x_link_change_notify(struct phy_device *phydev)
--{
-- /* Assert interface sgmii fifo on link down, deassert it on link up,
-- * the interface device address is always phy address added by 1.
-- */
-- mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
-- MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
-- QCA8081_PHY_FIFO_RSTN,
-- phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
--}
--
--static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
-- u16 *offload_trigger)
--{
-- /* Parsing specific to netdev trigger */
-- if (test_bit(TRIGGER_NETDEV_TX, &rules))
-- *offload_trigger |= QCA808X_LED_TX_BLINK;
-- if (test_bit(TRIGGER_NETDEV_RX, &rules))
-- *offload_trigger |= QCA808X_LED_RX_BLINK;
-- if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED10_ON;
-- if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED100_ON;
-- if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED1000_ON;
-- if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
-- *offload_trigger |= QCA808X_LED_SPEED2500_ON;
-- if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-- *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
-- if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-- *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
--
-- if (rules && !*offload_trigger)
-- return -EOPNOTSUPP;
--
-- /* Enable BLINK_CHECK_BYPASS by default to make the LED
-- * blink even with duplex or speed mode not enabled.
-- */
-- *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS;
--
-- return 0;
--}
--
--static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index)
--{
-- u16 reg;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN);
--}
--
--static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-- unsigned long rules)
--{
-- u16 offload_trigger = 0;
--
-- if (index > 2)
-- return -EINVAL;
--
-- return qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
--}
--
--static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index,
-- unsigned long rules)
--{
-- u16 reg, offload_trigger = 0;
-- int ret;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_CTRL(index);
--
-- ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-- if (ret)
-- return ret;
--
-- ret = qca808x_led_hw_control_enable(phydev, index);
-- if (ret)
-- return ret;
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_PATTERN_MASK,
-- offload_trigger);
--}
--
--static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
--{
-- u16 reg;
-- int val;
--
-- if (index > 2)
-- return false;
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
--
-- return !(val & QCA808X_LED_FORCE_EN);
--}
--
--static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
-- unsigned long *rules)
--{
-- u16 reg;
-- int val;
--
-- if (index > 2)
-- return -EINVAL;
--
-- /* Check if we have hw control enabled */
-- if (qca808x_led_hw_control_status(phydev, index))
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_CTRL(index);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-- if (val & QCA808X_LED_TX_BLINK)
-- set_bit(TRIGGER_NETDEV_TX, rules);
-- if (val & QCA808X_LED_RX_BLINK)
-- set_bit(TRIGGER_NETDEV_RX, rules);
-- if (val & QCA808X_LED_SPEED10_ON)
-- set_bit(TRIGGER_NETDEV_LINK_10, rules);
-- if (val & QCA808X_LED_SPEED100_ON)
-- set_bit(TRIGGER_NETDEV_LINK_100, rules);
-- if (val & QCA808X_LED_SPEED1000_ON)
-- set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-- if (val & QCA808X_LED_SPEED2500_ON)
-- set_bit(TRIGGER_NETDEV_LINK_2500, rules);
-- if (val & QCA808X_LED_HALF_DUPLEX_ON)
-- set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-- if (val & QCA808X_LED_FULL_DUPLEX_ON)
-- set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
--
-- return 0;
--}
--
--static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index)
--{
-- u16 reg;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_CTRL(index);
--
-- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_PATTERN_MASK);
--}
--
--static int qca808x_led_brightness_set(struct phy_device *phydev,
-- u8 index, enum led_brightness value)
--{
-- u16 reg;
-- int ret;
--
-- if (index > 2)
-- return -EINVAL;
--
-- if (!value) {
-- ret = qca808x_led_hw_control_reset(phydev, index);
-- if (ret)
-- return ret;
-- }
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-- QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON :
-- QCA808X_LED_FORCE_OFF);
--}
--
--static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
-- unsigned long *delay_on,
-- unsigned long *delay_off)
--{
-- int ret;
-- u16 reg;
--
-- if (index > 2)
-- return -EINVAL;
--
-- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- /* Set blink to 50% off, 50% on at 4Hz by default */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
-- QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
-- QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
-- if (ret)
-- return ret;
--
-- /* We use BLINK_1 for normal blinking */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
-- if (ret)
-- return ret;
--
-- /* We set blink to 4Hz, aka 250ms */
-- *delay_on = 250 / 2;
-- *delay_off = 250 / 2;
--
-- return 0;
--}
--
--static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
-- unsigned long modes)
--{
-- struct at803x_priv *priv = phydev->priv;
-- bool active_low = false;
-- u32 mode;
--
-- for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-- switch (mode) {
-- case PHY_LED_ACTIVE_LOW:
-- active_low = true;
-- break;
-- default:
-- return -EINVAL;
-- }
-- }
--
-- /* PHY polarity is global and can't be set per LED.
-- * To detect this, check if last requested polarity mode
-- * match the new one.
-- */
-- if (priv->led_polarity_mode >= 0 &&
-- priv->led_polarity_mode != active_low) {
-- phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
-- return -EINVAL;
-- }
--
-- /* Save the last PHY polarity mode */
-- priv->led_polarity_mode = active_low;
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN,
-- QCA808X_MMD7_LED_POLARITY_CTRL,
-- QCA808X_LED_ACTIVE_HIGH,
-- active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
--}
--
- static struct phy_driver at803x_driver[] = {
- {
- /* Qualcomm Atheros AR8035 */
-@@ -1989,34 +1123,6 @@ static struct phy_driver at803x_driver[]
- .read_status = at803x_read_status,
- .soft_reset = genphy_soft_reset,
- .config_aneg = at803x_config_aneg,
--}, {
-- /* Qualcomm QCA8081 */
-- PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
-- .name = "Qualcomm QCA8081",
-- .flags = PHY_POLL_CABLE_TEST,
-- .probe = at803x_probe,
-- .config_intr = at803x_config_intr,
-- .handle_interrupt = at803x_handle_interrupt,
-- .get_tunable = at803x_get_tunable,
-- .set_tunable = at803x_set_tunable,
-- .set_wol = at803x_set_wol,
-- .get_wol = at803x_get_wol,
-- .get_features = qca808x_get_features,
-- .config_aneg = qca808x_config_aneg,
-- .suspend = genphy_suspend,
-- .resume = genphy_resume,
-- .read_status = qca808x_read_status,
-- .config_init = qca808x_config_init,
-- .soft_reset = qca808x_soft_reset,
-- .cable_test_start = qca808x_cable_test_start,
-- .cable_test_get_status = qca808x_cable_test_get_status,
-- .link_change_notify = qca808x_link_change_notify,
-- .led_brightness_set = qca808x_led_brightness_set,
-- .led_blink_set = qca808x_led_blink_set,
-- .led_hw_is_supported = qca808x_led_hw_is_supported,
-- .led_hw_control_set = qca808x_led_hw_control_set,
-- .led_hw_control_get = qca808x_led_hw_control_get,
-- .led_polarity_set = qca808x_led_polarity_set,
- }, };
-
- module_phy_driver(at803x_driver);
-@@ -2028,7 +1134,6 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
- { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
- { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
-- { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
- { }
- };
-
---- /dev/null
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -0,0 +1,934 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+
-+#include <linux/phy.h>
-+#include <linux/module.h>
-+#include <linux/ethtool_netlink.h>
-+
-+#include "qcom.h"
-+
-+/* ADC threshold */
-+#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80
-+#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0)
-+#define QCA808X_ADC_THRESHOLD_80MV 0
-+#define QCA808X_ADC_THRESHOLD_100MV 0xf0
-+#define QCA808X_ADC_THRESHOLD_200MV 0x0f
-+#define QCA808X_ADC_THRESHOLD_300MV 0xff
-+
-+/* CLD control */
-+#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007
-+#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4)
-+#define QCA808X_8023AZ_AFE_EN 0x90
-+
-+/* AZ control */
-+#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008
-+#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014
-+#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E
-+#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E
-+#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020
-+#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341
-+
-+#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c
-+#define QCA808X_TOP_OPTION1_DATA 0x0
-+
-+#define QCA808X_PHY_MMD3_DEBUG_1 0xa100
-+#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203
-+#define QCA808X_PHY_MMD3_DEBUG_2 0xa101
-+#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad
-+#define QCA808X_PHY_MMD3_DEBUG_3 0xa103
-+#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698
-+#define QCA808X_PHY_MMD3_DEBUG_4 0xa105
-+#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001
-+#define QCA808X_PHY_MMD3_DEBUG_5 0xa106
-+#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111
-+#define QCA808X_PHY_MMD3_DEBUG_6 0xa011
-+#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85
-+
-+/* master/slave seed config */
-+#define QCA808X_PHY_DEBUG_LOCAL_SEED 9
-+#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1)
-+#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2)
-+#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32
-+
-+/* Hibernation yields lower power consumpiton in contrast with normal operation mode.
-+ * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s.
-+ */
-+#define QCA808X_DBG_AN_TEST 0xb
-+#define QCA808X_HIBERNATION_EN BIT(15)
-+
-+#define QCA808X_CDT_ENABLE_TEST BIT(15)
-+#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
-+#define QCA808X_CDT_STATUS BIT(11)
-+#define QCA808X_CDT_LENGTH_UNIT BIT(10)
-+
-+#define QCA808X_MMD3_CDT_STATUS 0x8064
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
-+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
-+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
-+
-+#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
-+#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
-+#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
-+#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
-+
-+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
-+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
-+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
-+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
-+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
-+
-+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
-+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
-+
-+/* NORMAL are MDI with type set to 0 */
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+
-+/* Added for reference of existence but should be handled by wait_for_completion already */
-+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
-+
-+#define QCA808X_MMD7_LED_GLOBAL 0x8073
-+#define QCA808X_LED_BLINK_1 GENMASK(11, 6)
-+#define QCA808X_LED_BLINK_2 GENMASK(5, 0)
-+/* Values are the same for both BLINK_1 and BLINK_2 */
-+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3)
-+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
-+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
-+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
-+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
-+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
-+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
-+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
-+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
-+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0)
-+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
-+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
-+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
-+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
-+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
-+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
-+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
-+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
-+
-+#define QCA808X_MMD7_LED2_CTRL 0x8074
-+#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075
-+#define QCA808X_MMD7_LED1_CTRL 0x8076
-+#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077
-+#define QCA808X_MMD7_LED0_CTRL 0x8078
-+#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2))
-+
-+/* LED hw control pattern is the same for every LED */
-+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0)
-+#define QCA808X_LED_SPEED2500_ON BIT(15)
-+#define QCA808X_LED_SPEED2500_BLINK BIT(14)
-+/* Follow blink trigger even if duplex or speed condition doesn't match */
-+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13)
-+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12)
-+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11)
-+#define QCA808X_LED_TX_BLINK BIT(10)
-+#define QCA808X_LED_RX_BLINK BIT(9)
-+#define QCA808X_LED_TX_ON_10MS BIT(8)
-+#define QCA808X_LED_RX_ON_10MS BIT(7)
-+#define QCA808X_LED_SPEED1000_ON BIT(6)
-+#define QCA808X_LED_SPEED100_ON BIT(5)
-+#define QCA808X_LED_SPEED10_ON BIT(4)
-+#define QCA808X_LED_COLLISION_BLINK BIT(3)
-+#define QCA808X_LED_SPEED1000_BLINK BIT(2)
-+#define QCA808X_LED_SPEED100_BLINK BIT(1)
-+#define QCA808X_LED_SPEED10_BLINK BIT(0)
-+
-+#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079
-+#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2))
-+
-+/* LED force ctrl is the same for every LED
-+ * No documentation exist for this, not even internal one
-+ * with NDA as QCOM gives only info about configuring
-+ * hw control pattern rules and doesn't indicate any way
-+ * to force the LED to specific mode.
-+ * These define comes from reverse and testing and maybe
-+ * lack of some info or some info are not entirely correct.
-+ * For the basic LED control and hw control these finding
-+ * are enough to support LED control in all the required APIs.
-+ *
-+ * On doing some comparison with implementation with qca807x,
-+ * it was found that it's 1:1 equal to it and confirms all the
-+ * reverse done. It was also found further specification with the
-+ * force mode and the blink modes.
-+ */
-+#define QCA808X_LED_FORCE_EN BIT(15)
-+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13)
-+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
-+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
-+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
-+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
-+
-+#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a
-+/* QSDK sets by default 0x46 to this reg that sets BIT 6 for
-+ * LED to active high. It's not clear what BIT 3 and BIT 4 does.
-+ */
-+#define QCA808X_LED_ACTIVE_HIGH BIT(6)
-+
-+/* QCA808X 1G chip type */
-+#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
-+#define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
-+
-+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072
-+#define QCA8081_PHY_FIFO_RSTN BIT(11)
-+
-+#define QCA8081_PHY_ID 0x004dd101
-+
-+MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
-+MODULE_AUTHOR("Matus Ujhelyi");
-+MODULE_LICENSE("GPL");
-+
-+struct qca808x_priv {
-+ int led_polarity_mode;
-+};
-+
-+static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Enable fast retrain */
-+ ret = genphy_c45_fast_retrain(phydev, true);
-+ if (ret)
-+ return ret;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
-+ QCA808X_TOP_OPTION1_DATA);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
-+ QCA808X_MSE_THRESHOLD_20DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
-+ QCA808X_MSE_THRESHOLD_17DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
-+ QCA808X_MSE_THRESHOLD_27DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
-+ QCA808X_MSE_THRESHOLD_28DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
-+ QCA808X_MMD3_DEBUG_1_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
-+ QCA808X_MMD3_DEBUG_4_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
-+ QCA808X_MMD3_DEBUG_5_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
-+ QCA808X_MMD3_DEBUG_3_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
-+ QCA808X_MMD3_DEBUG_6_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
-+ QCA808X_MMD3_DEBUG_2_VALUE);
-+
-+ return 0;
-+}
-+
-+static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
-+{
-+ u16 seed_value;
-+
-+ if (!enable)
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-+ QCA808X_MASTER_SLAVE_SEED_ENABLE, 0);
-+
-+ seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
-+ QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE,
-+ FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) |
-+ QCA808X_MASTER_SLAVE_SEED_ENABLE);
-+}
-+
-+static bool qca808x_is_prefer_master(struct phy_device *phydev)
-+{
-+ return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) ||
-+ (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
-+}
-+
-+static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
-+{
-+ return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-+}
-+
-+static int qca808x_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct qca808x_priv *priv;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ /* Init LED polarity mode to -1 */
-+ priv->led_polarity_mode = -1;
-+
-+ phydev->priv = priv;
-+
-+ return 0;
-+}
-+
-+static int qca808x_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Active adc&vga on 802.3az for the link 1000M and 100M */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
-+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
-+ if (ret)
-+ return ret;
-+
-+ /* Adjust the threshold on 802.3az for the link 1000M */
-+ ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
-+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
-+ QCA808X_MMD3_AZ_TRAINING_VAL);
-+ if (ret)
-+ return ret;
-+
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-+ /* Config the fast retrain for the link 2500M */
-+ ret = qca808x_phy_fast_retrain_config(phydev);
-+ if (ret)
-+ return ret;
-+
-+ ret = genphy_read_master_slave(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!qca808x_is_prefer_master(phydev)) {
-+ /* Enable seed and configure lower ramdom seed to make phy
-+ * linked as slave mode.
-+ */
-+ ret = qca808x_phy_ms_seed_enable(phydev, true);
-+ if (ret)
-+ return ret;
-+ }
-+ }
-+
-+ /* Configure adc threshold as 100mv for the link 10M */
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
-+ QCA808X_ADC_THRESHOLD_MASK,
-+ QCA808X_ADC_THRESHOLD_100MV);
-+}
-+
-+static int qca808x_read_status(struct phy_device *phydev)
-+{
-+ struct at803x_ss_mask ss_mask = { 0 };
-+ int ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
-+ if (ret < 0)
-+ return ret;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
-+ ret & MDIO_AN_10GBT_STAT_LP2_5G);
-+
-+ ret = genphy_read_status(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* qca8081 takes the different bits for speed value from at803x */
-+ ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
-+ ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
-+ ret = at803x_read_specific_status(phydev, ss_mask);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (phydev->link) {
-+ if (phydev->speed == SPEED_2500)
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ else
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ } else {
-+ /* generate seed as a lower random value to make PHY linked as SLAVE easily,
-+ * except for master/slave configuration fault detected or the master mode
-+ * preferred.
-+ *
-+ * the reason for not putting this code into the function link_change_notify is
-+ * the corner case where the link partner is also the qca8081 PHY and the seed
-+ * value is configured as the same value, the link can't be up and no link change
-+ * occurs.
-+ */
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
-+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
-+ qca808x_is_prefer_master(phydev)) {
-+ qca808x_phy_ms_seed_enable(phydev, false);
-+ } else {
-+ qca808x_phy_ms_seed_enable(phydev, true);
-+ }
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca808x_soft_reset(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = genphy_soft_reset(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (qca808x_has_fast_retrain_or_slave_seed(phydev))
-+ ret = qca808x_phy_ms_seed_enable(phydev, true);
-+
-+ return ret;
-+}
-+
-+static bool qca808x_cdt_fault_length_valid(int cdt_code)
-+{
-+ switch (cdt_code) {
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-+ return true;
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int qca808x_cable_test_result_trans(int cdt_code)
-+{
-+ switch (cdt_code) {
-+ case QCA808X_CDT_STATUS_STAT_NORMAL:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
-+ case QCA808X_CDT_STATUS_STAT_FAIL:
-+ default:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-+ }
-+}
-+
-+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
-+ int result)
-+{
-+ int val;
-+ u32 cdt_length_reg = 0;
-+
-+ switch (pair) {
-+ case ETHTOOL_A_CABLE_PAIR_A:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_B:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_C:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_D:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
-+ if (val < 0)
-+ return val;
-+
-+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
-+ else
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
-+
-+ return at803x_cdt_fault_length(val);
-+}
-+
-+static int qca808x_cable_test_start(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* perform CDT with the following configs:
-+ * 1. disable hibernation.
-+ * 2. force PHY working in MDI mode.
-+ * 3. for PHY working in 1000BaseT.
-+ * 4. configure the threshold.
-+ */
-+
-+ ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at803x_config_mdix(phydev, ETH_TP_MDI);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */
-+ phydev->duplex = DUPLEX_FULL;
-+ phydev->speed = SPEED_1000;
-+ ret = genphy_c45_pma_setup_forced(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = genphy_setup_forced(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* configure the thresholds for open, short, pair ok test */
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
-+
-+ return 0;
-+}
-+
-+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
-+ u16 status)
-+{
-+ int length, result;
-+ u16 pair_code;
-+
-+ switch (pair) {
-+ case ETHTOOL_A_CABLE_PAIR_A:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_B:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_C:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_D:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ result = qca808x_cable_test_result_trans(pair_code);
-+ ethnl_cable_test_result(phydev, pair, result);
-+
-+ if (qca808x_cdt_fault_length_valid(pair_code)) {
-+ length = qca808x_cdt_fault_length(phydev, pair, result);
-+ ethnl_cable_test_fault_length(phydev, pair, length);
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
-+{
-+ int ret, val;
-+
-+ *finished = false;
-+
-+ val = QCA808X_CDT_ENABLE_TEST |
-+ QCA808X_CDT_LENGTH_UNIT;
-+ ret = at803x_cdt_start(phydev, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
-+ if (ret)
-+ return ret;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
-+ if (val < 0)
-+ return val;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-+ if (ret)
-+ return ret;
-+
-+ *finished = true;
-+
-+ return 0;
-+}
-+
-+static int qca808x_get_features(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = genphy_c45_pma_read_abilities(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* The autoneg ability is not existed in bit3 of MMD7.1,
-+ * but it is supported by qca808x PHY, so we add it here
-+ * manually.
-+ */
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
-+
-+ /* As for the qca8081 1G version chip, the 2500baseT ability is also
-+ * existed in the bit0 of MMD1.21, we need to remove it manually if
-+ * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
-+ */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (QCA808X_PHY_CHIP_TYPE_1G & ret)
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-+
-+ return 0;
-+}
-+
-+static int qca808x_config_aneg(struct phy_device *phydev)
-+{
-+ int phy_ctrl = 0;
-+ int ret;
-+
-+ ret = at803x_prepare_config_aneg(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* The reg MII_BMCR also needs to be configured for force mode, the
-+ * genphy_config_aneg is also needed.
-+ */
-+ if (phydev->autoneg == AUTONEG_DISABLE)
-+ genphy_c45_pma_setup_forced(phydev);
-+
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
-+ phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
-+
-+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-+ MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __genphy_config_aneg(phydev, ret);
-+}
-+
-+static void qca808x_link_change_notify(struct phy_device *phydev)
-+{
-+ /* Assert interface sgmii fifo on link down, deassert it on link up,
-+ * the interface device address is always phy address added by 1.
-+ */
-+ mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
-+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
-+ QCA8081_PHY_FIFO_RSTN,
-+ phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
-+}
-+
-+static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
-+ u16 *offload_trigger)
-+{
-+ /* Parsing specific to netdev trigger */
-+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
-+ *offload_trigger |= QCA808X_LED_TX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
-+ *offload_trigger |= QCA808X_LED_RX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED10_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED100_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED1000_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED2500_ON;
-+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
-+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
-+
-+ if (rules && !*offload_trigger)
-+ return -EOPNOTSUPP;
-+
-+ /* Enable BLINK_CHECK_BYPASS by default to make the LED
-+ * blink even with duplex or speed mode not enabled.
-+ */
-+ *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS;
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN);
-+}
-+
-+static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 offload_trigger = 0;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ return qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-+}
-+
-+static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 reg, offload_trigger = 0;
-+ int ret;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_led_hw_control_enable(phydev, index);
-+ if (ret)
-+ return ret;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_PATTERN_MASK,
-+ offload_trigger);
-+}
-+
-+static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+ int val;
-+
-+ if (index > 2)
-+ return false;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+
-+ return !(val & QCA808X_LED_FORCE_EN);
-+}
-+
-+static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
-+ unsigned long *rules)
-+{
-+ u16 reg;
-+ int val;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ /* Check if we have hw control enabled */
-+ if (qca808x_led_hw_control_status(phydev, index))
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+ if (val & QCA808X_LED_TX_BLINK)
-+ set_bit(TRIGGER_NETDEV_TX, rules);
-+ if (val & QCA808X_LED_RX_BLINK)
-+ set_bit(TRIGGER_NETDEV_RX, rules);
-+ if (val & QCA808X_LED_SPEED10_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+ if (val & QCA808X_LED_SPEED100_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+ if (val & QCA808X_LED_SPEED1000_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+ if (val & QCA808X_LED_SPEED2500_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_2500, rules);
-+ if (val & QCA808X_LED_HALF_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-+ if (val & QCA808X_LED_FULL_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_CTRL(index);
-+
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_PATTERN_MASK);
-+}
-+
-+static int qca808x_led_brightness_set(struct phy_device *phydev,
-+ u8 index, enum led_brightness value)
-+{
-+ u16 reg;
-+ int ret;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ if (!value) {
-+ ret = qca808x_led_hw_control_reset(phydev, index);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON :
-+ QCA808X_LED_FORCE_OFF);
-+}
-+
-+static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ int ret;
-+ u16 reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
-+
-+ /* Set blink to 50% off, 50% on at 4Hz by default */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
-+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
-+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
-+ if (ret)
-+ return ret;
-+
-+ /* We use BLINK_1 for normal blinking */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
-+ if (ret)
-+ return ret;
-+
-+ /* We set blink to 4Hz, aka 250ms */
-+ *delay_on = 250 / 2;
-+ *delay_off = 250 / 2;
-+
-+ return 0;
-+}
-+
-+static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
-+ unsigned long modes)
-+{
-+ struct qca808x_priv *priv = phydev->priv;
-+ bool active_low = false;
-+ u32 mode;
-+
-+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-+ switch (mode) {
-+ case PHY_LED_ACTIVE_LOW:
-+ active_low = true;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ /* PHY polarity is global and can't be set per LED.
-+ * To detect this, check if last requested polarity mode
-+ * match the new one.
-+ */
-+ if (priv->led_polarity_mode >= 0 &&
-+ priv->led_polarity_mode != active_low) {
-+ phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Save the last PHY polarity mode */
-+ priv->led_polarity_mode = active_low;
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN,
-+ QCA808X_MMD7_LED_POLARITY_CTRL,
-+ QCA808X_LED_ACTIVE_HIGH,
-+ active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
-+}
-+
-+static struct phy_driver qca808x_driver[] = {
-+{
-+ /* Qualcomm QCA8081 */
-+ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
-+ .name = "Qualcomm QCA8081",
-+ .flags = PHY_POLL_CABLE_TEST,
-+ .probe = qca808x_probe,
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .get_tunable = at803x_get_tunable,
-+ .set_tunable = at803x_set_tunable,
-+ .set_wol = at803x_set_wol,
-+ .get_wol = at803x_get_wol,
-+ .get_features = qca808x_get_features,
-+ .config_aneg = qca808x_config_aneg,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
-+ .read_status = qca808x_read_status,
-+ .config_init = qca808x_config_init,
-+ .soft_reset = qca808x_soft_reset,
-+ .cable_test_start = qca808x_cable_test_start,
-+ .cable_test_get_status = qca808x_cable_test_get_status,
-+ .link_change_notify = qca808x_link_change_notify,
-+ .led_brightness_set = qca808x_led_brightness_set,
-+ .led_blink_set = qca808x_led_blink_set,
-+ .led_hw_is_supported = qca808x_led_hw_is_supported,
-+ .led_hw_control_set = qca808x_led_hw_control_set,
-+ .led_hw_control_get = qca808x_led_hw_control_get,
-+ .led_polarity_set = qca808x_led_polarity_set,
-+}, };
-+
-+module_phy_driver(qca808x_driver);
-+
-+static struct mdio_device_id __maybe_unused qca808x_tbl[] = {
-+ { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, qca808x_tbl);
diff --git a/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch b/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch
deleted file mode 100644
index 80c870159b..0000000000
--- a/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch
+++ /dev/null
@@ -1,394 +0,0 @@
-From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:57:50 +0000
-Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS
-
-The SGMII core found in several MediaTek SoCs is identical to what can
-also be found in MediaTek's MT7531 Ethernet switch IC.
-As this has not always been clear, both drivers developed different
-implementations to deal with the PCS.
-Recently Alexander Couzens pointed out this fact which lead to the
-development of this shared driver.
-
-Add a dedicated driver, mostly by copying the code now found in the
-Ethernet driver. The now redundant code will be removed by a follow-up
-commit.
-
-Suggested-by: Alexander Couzens <lynxis@fe80.eu>
-Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- MAINTAINERS | 8 +
- drivers/net/pcs/Kconfig | 7 +
- drivers/net/pcs/Makefile | 1 +
- drivers/net/pcs/pcs-mtk-lynxi.c | 305 ++++++++++++++++++++++++++++++
- include/linux/pcs/pcs-mtk-lynxi.h | 13 ++
- 5 files changed, 334 insertions(+)
- create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
- create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -12935,6 +12935,14 @@ L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/ethernet/mediatek/
-
-+MEDIATEK ETHERNET PCS DRIVER
-+M: Alexander Couzens <lynxis@fe80.eu>
-+M: Daniel Golle <daniel@makrotopia.org>
-+L: netdev@vger.kernel.org
-+S: Maintained
-+F: drivers/net/pcs/pcs-mtk-lynxi.c
-+F: include/linux/pcs/pcs-mtk-lynxi.h
-+
- MEDIATEK I2C CONTROLLER DRIVER
- M: Qii Wang <qii.wang@mediatek.com>
- L: linux-i2c@vger.kernel.org
---- a/drivers/net/pcs/Kconfig
-+++ b/drivers/net/pcs/Kconfig
-@@ -32,4 +32,11 @@ config PCS_ALTERA_TSE
- This module provides helper functions for the Altera Triple Speed
- Ethernet SGMII PCS, that can be found on the Intel Socfpga family.
-
-+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.
-+
- endmenu
---- a/drivers/net/pcs/Makefile
-+++ b/drivers/net/pcs/Makefile
-@@ -7,3 +7,4 @@ obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
- obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
- obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o
- obj-$(CONFIG_PCS_ALTERA_TSE) += pcs-altera-tse.o
-+obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
---- /dev/null
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -0,0 +1,305 @@
-+// SPDX-License-Identifier: GPL-2.0
-+// Copyright (c) 2018-2019 MediaTek Inc.
-+/* A library for MediaTek SGMII circuit
-+ *
-+ * Author: Sean Wang <sean.wang@mediatek.com>
-+ * Author: Alexander Couzens <lynxis@fe80.eu>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ *
-+ */
-+
-+#include <linux/mdio.h>
-+#include <linux/of.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
-+#include <linux/phylink.h>
-+#include <linux/regmap.h>
-+
-+/* SGMII subsystem config registers */
-+/* BMCR (low 16) BMSR (high 16) */
-+#define SGMSYS_PCS_CONTROL_1 0x0
-+#define SGMII_BMCR GENMASK(15, 0)
-+#define SGMII_BMSR GENMASK(31, 16)
-+
-+#define SGMSYS_PCS_DEVICE_ID 0x4
-+#define SGMII_LYNXI_DEV_ID 0x4d544950
-+
-+#define SGMSYS_PCS_ADVERTISE 0x8
-+#define SGMII_ADVERTISE GENMASK(15, 0)
-+#define SGMII_LPA GENMASK(31, 16)
-+
-+#define SGMSYS_PCS_SCRATCH 0x14
-+#define SGMII_DEV_VERSION GENMASK(31, 16)
-+
-+/* Register to programmable link timer, the unit in 2 * 8ns */
-+#define SGMSYS_PCS_LINK_TIMER 0x18
-+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
-+#define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \
-+ ((ns) / 2 / 8))
-+
-+/* Register to control remote fault */
-+#define SGMSYS_SGMII_MODE 0x20
-+#define SGMII_IF_MODE_SGMII BIT(0)
-+#define SGMII_SPEED_DUPLEX_AN BIT(1)
-+#define SGMII_SPEED_MASK GENMASK(3, 2)
-+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
-+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
-+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
-+#define SGMII_DUPLEX_HALF BIT(4)
-+#define SGMII_REMOTE_FAULT_DIS BIT(8)
-+
-+/* Register to reset SGMII design */
-+#define SGMSYS_RESERVED_0 0x34
-+#define SGMII_SW_RESET BIT(0)
-+
-+/* Register to set SGMII speed, ANA RG_ Control Signals III */
-+#define SGMII_PHY_SPEED_MASK GENMASK(3, 2)
-+#define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0)
-+#define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1)
-+
-+/* Register to power up QPHY */
-+#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
-+#define SGMII_PHYA_PWD BIT(4)
-+
-+/* Register to QPHY wrapper control */
-+#define SGMSYS_QPHY_WRAP_CTRL 0xec
-+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
-+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
-+
-+/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated
-+ * data
-+ * @regmap: The register map pointing at the range used to setup
-+ * SGMII modes
-+ * @dev: Pointer to device owning the PCS
-+ * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap
-+ * @interface: Currently configured interface mode
-+ * @pcs: Phylink PCS structure
-+ * @flags: Flags indicating hardware properties
-+ */
-+struct mtk_pcs_lynxi {
-+ struct regmap *regmap;
-+ u32 ana_rgc3;
-+ phy_interface_t interface;
-+ struct phylink_pcs pcs;
-+ u32 flags;
-+};
-+
-+static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
-+{
-+ return container_of(pcs, struct mtk_pcs_lynxi, pcs);
-+}
-+
-+static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+ unsigned int bm, adv;
-+
-+ /* Read the BMSR and LPA */
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+
-+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-+ FIELD_GET(SGMII_LPA, adv));
-+}
-+
-+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface,
-+ const unsigned long *advertising,
-+ bool permit_pause_to_mac)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+ bool mode_changed = false, changed, use_an;
-+ unsigned int rgc3, sgm_mode, bmcr;
-+ int advertise, link_timer;
-+
-+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-+ advertising);
-+ if (advertise < 0)
-+ return 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
-+ * other words, 1000Mbps or 2500Mbps).
-+ */
-+ if (interface == PHY_INTERFACE_MODE_SGMII) {
-+ sgm_mode = SGMII_IF_MODE_SGMII;
-+ if (phylink_autoneg_inband(mode)) {
-+ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-+ SGMII_SPEED_DUPLEX_AN;
-+ use_an = true;
-+ } else {
-+ use_an = false;
-+ }
-+ } else if (phylink_autoneg_inband(mode)) {
-+ /* 1000base-X or 2500base-X autoneg */
-+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
-+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ advertising);
-+ } else {
-+ /* 1000base-X or 2500base-X without autoneg */
-+ sgm_mode = 0;
-+ use_an = false;
-+ }
-+
-+ if (use_an)
-+ bmcr = BMCR_ANENABLE;
-+ else
-+ bmcr = 0;
-+
-+ if (mpcs->interface != interface) {
-+ link_timer = phylink_get_link_timer_ns(interface);
-+ if (link_timer < 0)
-+ return link_timer;
-+
-+ /* PHYA power down */
-+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD);
-+
-+ /* Reset SGMII PCS state */
-+ regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
-+ SGMII_SW_RESET);
-+
-+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-+ SGMII_PN_SWAP_MASK,
-+ SGMII_PN_SWAP_TX_RX);
-+
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+ rgc3 = SGMII_PHY_SPEED_3_125G;
-+ else
-+ rgc3 = SGMII_PHY_SPEED_1_25G;
-+
-+ /* Configure the underlying interface speed */
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ SGMII_PHY_SPEED_MASK, rgc3);
-+
-+ /* Setup the link timer */
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
-+ SGMII_LINK_TIMER_VAL(link_timer));
-+
-+ mpcs->interface = interface;
-+ mode_changed = true;
-+ }
-+
-+ /* Update the advertisement, noting whether it has changed */
-+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-+ SGMII_ADVERTISE, advertise, &changed);
-+
-+ /* Update the sgmsys mode register */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-+ SGMII_IF_MODE_SGMII, sgm_mode);
-+
-+ /* Update the BMCR */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ BMCR_ANENABLE, bmcr);
-+
-+ /* Release PHYA power down state
-+ * Only removing bit SGMII_PHYA_PWD isn't enough.
-+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-+ * prevents SGMII from working. The SGMII still shows link but no traffic
-+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-+ * taken from a good working state of the SGMII interface.
-+ * Unknown how much the QPHY needs but it is racy without a sleep.
-+ * Tested on mt7622 & mt7986.
-+ */
-+ usleep_range(50, 100);
-+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-+
-+ return changed || mode_changed;
-+}
-+
-+static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+
-+ regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
-+}
-+
-+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface, int speed,
-+ int duplex)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+ unsigned int sgm_mode;
-+
-+ if (!phylink_autoneg_inband(mode)) {
-+ /* Force the speed and duplex setting */
-+ if (speed == SPEED_10)
-+ sgm_mode = SGMII_SPEED_10;
-+ else if (speed == SPEED_100)
-+ sgm_mode = SGMII_SPEED_100;
-+ else
-+ sgm_mode = SGMII_SPEED_1000;
-+
-+ if (duplex != DUPLEX_FULL)
-+ sgm_mode |= SGMII_DUPLEX_HALF;
-+
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
-+ sgm_mode);
-+ }
-+}
-+
-+static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
-+ .pcs_get_state = mtk_pcs_lynxi_get_state,
-+ .pcs_config = mtk_pcs_lynxi_config,
-+ .pcs_an_restart = mtk_pcs_lynxi_restart_an,
-+ .pcs_link_up = mtk_pcs_lynxi_link_up,
-+};
-+
-+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
-+ struct regmap *regmap, u32 ana_rgc3,
-+ u32 flags)
-+{
-+ struct mtk_pcs_lynxi *mpcs;
-+ u32 id, ver;
-+ int ret;
-+
-+ ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id);
-+ if (ret < 0)
-+ return NULL;
-+
-+ if (id != SGMII_LYNXI_DEV_ID) {
-+ dev_err(dev, "unknown PCS device id %08x\n", id);
-+ return NULL;
-+ }
-+
-+ ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver);
-+ if (ret < 0)
-+ return NULL;
-+
-+ ver = FIELD_GET(SGMII_DEV_VERSION, ver);
-+ if (ver != 0x1) {
-+ dev_err(dev, "unknown PCS device version %04x\n", ver);
-+ return NULL;
-+ }
-+
-+ 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;
-+
-+ mpcs->ana_rgc3 = ana_rgc3;
-+ mpcs->regmap = regmap;
-+ mpcs->flags = flags;
-+ mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
-+ mpcs->pcs.poll = true;
-+ mpcs->interface = PHY_INTERFACE_MODE_NA;
-+
-+ return &mpcs->pcs;
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_create);
-+
-+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs)
-+{
-+ if (!pcs)
-+ return;
-+
-+ kfree(pcs_to_mtk_pcs_lynxi(pcs));
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_destroy);
-+
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/include/linux/pcs/pcs-mtk-lynxi.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __LINUX_PCS_MTK_LYNXI_H
-+#define __LINUX_PCS_MTK_LYNXI_H
-+
-+#include <linux/phylink.h>
-+#include <linux/regmap.h>
-+
-+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
-+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
-+ struct regmap *regmap,
-+ u32 ana_rgc3, u32 flags);
-+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
-+#endif
diff --git a/target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch b/target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch
deleted file mode 100644
index 6decc3430b..0000000000
--- a/target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From ebb30ccbbdbd6fae5177b676da4f4ac92bb4f635 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 15 Dec 2023 14:15:31 +0100
-Subject: [PATCH 1/4] net: phy: make addr type u8 in phy_package_shared struct
-
-Switch addr type in phy_package_shared struct to u8.
-
-The value is already checked to be non negative and to be less than
-PHY_MAX_ADDR, hence u8 is better suited than using int.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/phy.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -330,7 +330,7 @@ struct mdio_bus_stats {
- * phy_package_leave().
- */
- struct phy_package_shared {
-- int addr;
-+ u8 addr;
- refcount_t refcnt;
- unsigned long flags;
- size_t priv_size;
diff --git a/target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch b/target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch
deleted file mode 100644
index 0cf01df3d3..0000000000
--- a/target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch
+++ /dev/null
@@ -1,341 +0,0 @@
-From 9eea577eb1155fe4a183bc5e7bf269b0b2e7a6ba Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 15 Dec 2023 14:15:32 +0100
-Subject: [PATCH 2/4] net: phy: extend PHY package API to support multiple
- global address
-
-Current API for PHY package are limited to single address to configure
-global settings for the PHY package.
-
-It was found that some PHY package (for example the qca807x, a PHY
-package that is shipped with a bundle of 5 PHY) requires multiple PHY
-address to configure global settings. An example scenario is a PHY that
-have a dedicated PHY for PSGMII/serdes calibrarion and have a specific
-PHY in the package where the global PHY mode is set and affects every
-other PHY in the package.
-
-Change the API in the following way:
-- Change phy_package_join() to take the base addr of the PHY package
- instead of the global PHY addr.
-- Make __/phy_package_write/read() require an additional arg that
- select what global PHY address to use by passing the offset from the
- base addr passed on phy_package_join().
-
-Each user of this API is updated to follow this new implementation
-following a pattern where an enum is defined to declare the offset of the
-addr.
-
-We also drop the check if shared is defined as any user of the
-phy_package_read/write is expected to use phy_package_join first. Misuse
-of this will correctly trigger a kernel panic for NULL pointer
-exception.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/bcm54140.c | 16 ++++++--
- drivers/net/phy/mscc/mscc.h | 5 +++
- drivers/net/phy/mscc/mscc_main.c | 4 +-
- drivers/net/phy/phy_device.c | 35 +++++++++--------
- include/linux/phy.h | 64 +++++++++++++++++++++-----------
- 5 files changed, 80 insertions(+), 44 deletions(-)
-
---- a/drivers/net/phy/bcm54140.c
-+++ b/drivers/net/phy/bcm54140.c
-@@ -128,6 +128,10 @@
- #define BCM54140_DEFAULT_DOWNSHIFT 5
- #define BCM54140_MAX_DOWNSHIFT 9
-
-+enum bcm54140_global_phy {
-+ BCM54140_BASE_ADDR = 0,
-+};
-+
- struct bcm54140_priv {
- int port;
- int base_addr;
-@@ -429,11 +433,13 @@ static int bcm54140_base_read_rdb(struct
- int ret;
-
- phy_lock_mdio_bus(phydev);
-- ret = __phy_package_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
-+ ret = __phy_package_write(phydev, BCM54140_BASE_ADDR,
-+ MII_BCM54XX_RDB_ADDR, rdb);
- if (ret < 0)
- goto out;
-
-- ret = __phy_package_read(phydev, MII_BCM54XX_RDB_DATA);
-+ ret = __phy_package_read(phydev, BCM54140_BASE_ADDR,
-+ MII_BCM54XX_RDB_DATA);
-
- out:
- phy_unlock_mdio_bus(phydev);
-@@ -446,11 +452,13 @@ static int bcm54140_base_write_rdb(struc
- int ret;
-
- phy_lock_mdio_bus(phydev);
-- ret = __phy_package_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
-+ ret = __phy_package_write(phydev, BCM54140_BASE_ADDR,
-+ MII_BCM54XX_RDB_ADDR, rdb);
- if (ret < 0)
- goto out;
-
-- ret = __phy_package_write(phydev, MII_BCM54XX_RDB_DATA, val);
-+ ret = __phy_package_write(phydev, BCM54140_BASE_ADDR,
-+ MII_BCM54XX_RDB_DATA, val);
-
- out:
- phy_unlock_mdio_bus(phydev);
---- a/drivers/net/phy/mscc/mscc.h
-+++ b/drivers/net/phy/mscc/mscc.h
-@@ -414,6 +414,11 @@ struct vsc8531_private {
- * gpio_lock: used for PHC operations. Common for all PHYs as the load/save GPIO
- * is shared.
- */
-+
-+enum vsc85xx_global_phy {
-+ VSC88XX_BASE_ADDR = 0,
-+};
-+
- struct vsc85xx_shared_private {
- struct mutex gpio_lock;
- };
---- a/drivers/net/phy/mscc/mscc_main.c
-+++ b/drivers/net/phy/mscc/mscc_main.c
-@@ -700,7 +700,7 @@ int phy_base_write(struct phy_device *ph
- dump_stack();
- }
-
-- return __phy_package_write(phydev, regnum, val);
-+ return __phy_package_write(phydev, VSC88XX_BASE_ADDR, regnum, val);
- }
-
- /* phydev->bus->mdio_lock should be locked when using this function */
-@@ -711,7 +711,7 @@ int phy_base_read(struct phy_device *phy
- dump_stack();
- }
-
-- return __phy_package_read(phydev, regnum);
-+ return __phy_package_read(phydev, VSC88XX_BASE_ADDR, regnum);
- }
-
- u32 vsc85xx_csr_read(struct phy_device *phydev,
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1602,20 +1602,22 @@ EXPORT_SYMBOL_GPL(phy_driver_is_genphy_1
- /**
- * phy_package_join - join a common PHY group
- * @phydev: target phy_device struct
-- * @addr: cookie and PHY address for global register access
-+ * @base_addr: cookie and base PHY address of PHY package for offset
-+ * calculation of global register access
- * @priv_size: if non-zero allocate this amount of bytes for private data
- *
- * This joins a PHY group and provides a shared storage for all phydevs in
- * this group. This is intended to be used for packages which contain
- * more than one PHY, for example a quad PHY transceiver.
- *
-- * The addr parameter serves as a cookie which has to have the same value
-- * for all members of one group and as a PHY address to access generic
-- * registers of a PHY package. Usually, one of the PHY addresses of the
-- * different PHYs in the package provides access to these global registers.
-+ * The base_addr parameter serves as cookie which has to have the same values
-+ * for all members of one group and as the base PHY address of the PHY package
-+ * for offset calculation to access generic registers of a PHY package.
-+ * Usually, one of the PHY addresses of the different PHYs in the package
-+ * provides access to these global registers.
- * The address which is given here, will be used in the phy_package_read()
-- * and phy_package_write() convenience functions. If your PHY doesn't have
-- * global registers you can just pick any of the PHY addresses.
-+ * and phy_package_write() convenience functions as base and added to the
-+ * passed offset in those functions.
- *
- * This will set the shared pointer of the phydev to the shared storage.
- * If this is the first call for a this cookie the shared storage will be
-@@ -1625,17 +1627,17 @@ EXPORT_SYMBOL_GPL(phy_driver_is_genphy_1
- * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
- * with the same cookie but a different priv_size is an error.
- */
--int phy_package_join(struct phy_device *phydev, int addr, size_t priv_size)
-+int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
- {
- struct mii_bus *bus = phydev->mdio.bus;
- struct phy_package_shared *shared;
- int ret;
-
-- if (addr < 0 || addr >= PHY_MAX_ADDR)
-+ if (base_addr < 0 || base_addr >= PHY_MAX_ADDR)
- return -EINVAL;
-
- mutex_lock(&bus->shared_lock);
-- shared = bus->shared[addr];
-+ shared = bus->shared[base_addr];
- if (!shared) {
- ret = -ENOMEM;
- shared = kzalloc(sizeof(*shared), GFP_KERNEL);
-@@ -1647,9 +1649,9 @@ int phy_package_join(struct phy_device *
- goto err_free;
- shared->priv_size = priv_size;
- }
-- shared->addr = addr;
-+ shared->base_addr = base_addr;
- refcount_set(&shared->refcnt, 1);
-- bus->shared[addr] = shared;
-+ bus->shared[base_addr] = shared;
- } else {
- ret = -EINVAL;
- if (priv_size && priv_size != shared->priv_size)
-@@ -1687,7 +1689,7 @@ void phy_package_leave(struct phy_device
- return;
-
- if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
-- bus->shared[shared->addr] = NULL;
-+ bus->shared[shared->base_addr] = NULL;
- mutex_unlock(&bus->shared_lock);
- kfree(shared->priv);
- kfree(shared);
-@@ -1706,7 +1708,8 @@ static void devm_phy_package_leave(struc
- * devm_phy_package_join - resource managed phy_package_join()
- * @dev: device that is registering this PHY package
- * @phydev: target phy_device struct
-- * @addr: cookie and PHY address for global register access
-+ * @base_addr: cookie and base PHY address of PHY package for offset
-+ * calculation of global register access
- * @priv_size: if non-zero allocate this amount of bytes for private data
- *
- * Managed phy_package_join(). Shared storage fetched by this function,
-@@ -1714,7 +1717,7 @@ static void devm_phy_package_leave(struc
- * phy_package_join() for more information.
- */
- int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
-- int addr, size_t priv_size)
-+ int base_addr, size_t priv_size)
- {
- struct phy_device **ptr;
- int ret;
-@@ -1724,7 +1727,7 @@ int devm_phy_package_join(struct device
- if (!ptr)
- return -ENOMEM;
-
-- ret = phy_package_join(phydev, addr, priv_size);
-+ ret = phy_package_join(phydev, base_addr, priv_size);
-
- if (!ret) {
- *ptr = phydev;
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -319,7 +319,8 @@ struct mdio_bus_stats {
-
- /**
- * struct phy_package_shared - Shared information in PHY packages
-- * @addr: Common PHY address used to combine PHYs in one package
-+ * @base_addr: Base PHY address of PHY package used to combine PHYs
-+ * in one package and for offset calculation of phy_package_read/write
- * @refcnt: Number of PHYs connected to this shared data
- * @flags: Initialization of PHY package
- * @priv_size: Size of the shared private data @priv
-@@ -330,7 +331,7 @@ struct mdio_bus_stats {
- * phy_package_leave().
- */
- struct phy_package_shared {
-- u8 addr;
-+ u8 base_addr;
- refcount_t refcnt;
- unsigned long flags;
- size_t priv_size;
-@@ -1763,10 +1764,10 @@ int phy_ethtool_get_link_ksettings(struc
- int phy_ethtool_set_link_ksettings(struct net_device *ndev,
- const struct ethtool_link_ksettings *cmd);
- int phy_ethtool_nway_reset(struct net_device *ndev);
--int phy_package_join(struct phy_device *phydev, int addr, size_t priv_size);
-+int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size);
- void phy_package_leave(struct phy_device *phydev);
- int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
-- int addr, size_t priv_size);
-+ int base_addr, size_t priv_size);
-
- #if IS_ENABLED(CONFIG_PHYLIB)
- int __init mdio_bus_init(void);
-@@ -1778,46 +1779,65 @@ int phy_ethtool_get_sset_count(struct ph
- int phy_ethtool_get_stats(struct phy_device *phydev,
- struct ethtool_stats *stats, u64 *data);
-
--static inline int phy_package_read(struct phy_device *phydev, u32 regnum)
-+static inline int phy_package_address(struct phy_device *phydev,
-+ unsigned int addr_offset)
- {
- struct phy_package_shared *shared = phydev->shared;
-+ u8 base_addr = shared->base_addr;
-
-- if (!shared)
-+ if (addr_offset >= PHY_MAX_ADDR - base_addr)
- return -EIO;
-
-- return mdiobus_read(phydev->mdio.bus, shared->addr, regnum);
-+ /* we know that addr will be in the range 0..31 and thus the
-+ * implicit cast to a signed int is not a problem.
-+ */
-+ return base_addr + addr_offset;
- }
-
--static inline int __phy_package_read(struct phy_device *phydev, u32 regnum)
-+static inline int phy_package_read(struct phy_device *phydev,
-+ unsigned int addr_offset, u32 regnum)
- {
-- struct phy_package_shared *shared = phydev->shared;
-+ int addr = phy_package_address(phydev, addr_offset);
-
-- if (!shared)
-- return -EIO;
-+ if (addr < 0)
-+ return addr;
-+
-+ return mdiobus_read(phydev->mdio.bus, addr, regnum);
-+}
-+
-+static inline int __phy_package_read(struct phy_device *phydev,
-+ unsigned int addr_offset, u32 regnum)
-+{
-+ int addr = phy_package_address(phydev, addr_offset);
-+
-+ if (addr < 0)
-+ return addr;
-
-- return __mdiobus_read(phydev->mdio.bus, shared->addr, regnum);
-+ return __mdiobus_read(phydev->mdio.bus, addr, regnum);
- }
-
- static inline int phy_package_write(struct phy_device *phydev,
-- u32 regnum, u16 val)
-+ unsigned int addr_offset, u32 regnum,
-+ u16 val)
- {
-- struct phy_package_shared *shared = phydev->shared;
-+ int addr = phy_package_address(phydev, addr_offset);
-
-- if (!shared)
-- return -EIO;
-+ if (addr < 0)
-+ return addr;
-
-- return mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val);
-+ return mdiobus_write(phydev->mdio.bus, addr, regnum, val);
- }
-
- static inline int __phy_package_write(struct phy_device *phydev,
-- u32 regnum, u16 val)
-+ unsigned int addr_offset, u32 regnum,
-+ u16 val)
- {
-- struct phy_package_shared *shared = phydev->shared;
-+ int addr = phy_package_address(phydev, addr_offset);
-
-- if (!shared)
-- return -EIO;
-+ if (addr < 0)
-+ return addr;
-
-- return __mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val);
-+ return __mdiobus_write(phydev->mdio.bus, addr, regnum, val);
- }
-
- static inline bool __phy_package_set_once(struct phy_device *phydev,
diff --git a/target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch b/target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch
deleted file mode 100644
index 4a17d46453..0000000000
--- a/target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 028672bd1d73cf65249a420c1de75e8d2acd2f6a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 15 Dec 2023 14:15:33 +0100
-Subject: [PATCH 3/4] net: phy: restructure __phy_write/read_mmd to helper and
- phydev user
-
-Restructure phy_write_mmd and phy_read_mmd to implement generic helper
-for direct mdiobus access for mmd and use these helper for phydev user.
-
-This is needed in preparation of PHY package API that requires generic
-access to the mdiobus and are deatched from phydev struct but instead
-access them based on PHY package base_addr and offsets.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy-core.c | 64 ++++++++++++++++++--------------------
- 1 file changed, 30 insertions(+), 34 deletions(-)
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -528,6 +528,28 @@ static void mmd_phy_indirect(struct mii_
- devad | MII_MMD_CTRL_NOINCR);
- }
-
-+static int mmd_phy_read(struct mii_bus *bus, int phy_addr, bool is_c45,
-+ int devad, u32 regnum)
-+{
-+ if (is_c45)
-+ return __mdiobus_c45_read(bus, phy_addr, devad, regnum);
-+
-+ mmd_phy_indirect(bus, phy_addr, devad, regnum);
-+ /* Read the content of the MMD's selected register */
-+ return __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
-+}
-+
-+static int mmd_phy_write(struct mii_bus *bus, int phy_addr, bool is_c45,
-+ int devad, u32 regnum, u16 val)
-+{
-+ if (is_c45)
-+ return __mdiobus_c45_write(bus, phy_addr, devad, regnum, val);
-+
-+ mmd_phy_indirect(bus, phy_addr, devad, regnum);
-+ /* Write the data into MMD's selected register */
-+ return __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
-+}
-+
- /**
- * __phy_read_mmd - Convenience function for reading a register
- * from an MMD on a given PHY.
-@@ -539,26 +561,14 @@ static void mmd_phy_indirect(struct mii_
- */
- int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
- {
-- int val;
--
- if (regnum > (u16)~0 || devad > 32)
- return -EINVAL;
-
-- if (phydev->drv && phydev->drv->read_mmd) {
-- val = phydev->drv->read_mmd(phydev, devad, regnum);
-- } else if (phydev->is_c45) {
-- val = __mdiobus_c45_read(phydev->mdio.bus, phydev->mdio.addr,
-- devad, regnum);
-- } else {
-- struct mii_bus *bus = phydev->mdio.bus;
-- int phy_addr = phydev->mdio.addr;
--
-- mmd_phy_indirect(bus, phy_addr, devad, regnum);
--
-- /* Read the content of the MMD's selected register */
-- val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
-- }
-- return val;
-+ if (phydev->drv && phydev->drv->read_mmd)
-+ return phydev->drv->read_mmd(phydev, devad, regnum);
-+
-+ return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr,
-+ phydev->is_c45, devad, regnum);
- }
- EXPORT_SYMBOL(__phy_read_mmd);
-
-@@ -595,28 +605,14 @@ EXPORT_SYMBOL(phy_read_mmd);
- */
- int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
- {
-- int ret;
--
- if (regnum > (u16)~0 || devad > 32)
- return -EINVAL;
-
-- if (phydev->drv && phydev->drv->write_mmd) {
-- ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
-- } else if (phydev->is_c45) {
-- ret = __mdiobus_c45_write(phydev->mdio.bus, phydev->mdio.addr,
-- devad, regnum, val);
-- } else {
-- struct mii_bus *bus = phydev->mdio.bus;
-- int phy_addr = phydev->mdio.addr;
-+ if (phydev->drv && phydev->drv->write_mmd)
-+ return phydev->drv->write_mmd(phydev, devad, regnum, val);
-
-- mmd_phy_indirect(bus, phy_addr, devad, regnum);
--
-- /* Write the data into MMD's selected register */
-- __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
--
-- ret = 0;
-- }
-- return ret;
-+ return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr,
-+ phydev->is_c45, devad, regnum, val);
- }
- EXPORT_SYMBOL(__phy_write_mmd);
-
diff --git a/target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch b/target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch
deleted file mode 100644
index a628a37929..0000000000
--- a/target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-From d63710fc0f1a501fd75a7025e3070a96ffa1645f Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 15 Dec 2023 14:15:34 +0100
-Subject: [PATCH 4/4] net: phy: add support for PHY package MMD read/write
-
-Some PHY in PHY package may require to read/write MMD regs to correctly
-configure the PHY package.
-
-Add support for these additional required function in both lock and no
-lock variant.
-
-It's assumed that the entire PHY package is either C22 or C45. We use
-C22 or C45 way of writing/reading to mmd regs based on the passed phydev
-whether it's C22 or C45.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy-core.c | 140 +++++++++++++++++++++++++++++++++++++
- include/linux/phy.h | 16 +++++
- 2 files changed, 156 insertions(+)
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -639,6 +639,146 @@ int phy_write_mmd(struct phy_device *phy
- EXPORT_SYMBOL(phy_write_mmd);
-
- /**
-+ * __phy_package_read_mmd - read MMD reg relative to PHY package base addr
-+ * @phydev: The phy_device struct
-+ * @addr_offset: The offset to be added to PHY package base_addr
-+ * @devad: The MMD to read from
-+ * @regnum: The register on the MMD to read
-+ *
-+ * Convenience helper for reading a register of an MMD on a given PHY
-+ * using the PHY package base address. The base address is added to
-+ * the addr_offset value.
-+ *
-+ * Same calling rules as for __phy_read();
-+ *
-+ * NOTE: It's assumed that the entire PHY package is either C22 or C45.
-+ */
-+int __phy_package_read_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum)
-+{
-+ int addr = phy_package_address(phydev, addr_offset);
-+
-+ if (addr < 0)
-+ return addr;
-+
-+ if (regnum > (u16)~0 || devad > 32)
-+ return -EINVAL;
-+
-+ return mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad,
-+ regnum);
-+}
-+EXPORT_SYMBOL(__phy_package_read_mmd);
-+
-+/**
-+ * phy_package_read_mmd - read MMD reg relative to PHY package base addr
-+ * @phydev: The phy_device struct
-+ * @addr_offset: The offset to be added to PHY package base_addr
-+ * @devad: The MMD to read from
-+ * @regnum: The register on the MMD to read
-+ *
-+ * Convenience helper for reading a register of an MMD on a given PHY
-+ * using the PHY package base address. The base address is added to
-+ * the addr_offset value.
-+ *
-+ * Same calling rules as for phy_read();
-+ *
-+ * NOTE: It's assumed that the entire PHY package is either C22 or C45.
-+ */
-+int phy_package_read_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum)
-+{
-+ int addr = phy_package_address(phydev, addr_offset);
-+ int val;
-+
-+ if (addr < 0)
-+ return addr;
-+
-+ if (regnum > (u16)~0 || devad > 32)
-+ return -EINVAL;
-+
-+ phy_lock_mdio_bus(phydev);
-+ val = mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad,
-+ regnum);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return val;
-+}
-+EXPORT_SYMBOL(phy_package_read_mmd);
-+
-+/**
-+ * __phy_package_write_mmd - write MMD reg relative to PHY package base addr
-+ * @phydev: The phy_device struct
-+ * @addr_offset: The offset to be added to PHY package base_addr
-+ * @devad: The MMD to write to
-+ * @regnum: The register on the MMD to write
-+ * @val: value to write to @regnum
-+ *
-+ * Convenience helper for writing a register of an MMD on a given PHY
-+ * using the PHY package base address. The base address is added to
-+ * the addr_offset value.
-+ *
-+ * Same calling rules as for __phy_write();
-+ *
-+ * NOTE: It's assumed that the entire PHY package is either C22 or C45.
-+ */
-+int __phy_package_write_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum, u16 val)
-+{
-+ int addr = phy_package_address(phydev, addr_offset);
-+
-+ if (addr < 0)
-+ return addr;
-+
-+ if (regnum > (u16)~0 || devad > 32)
-+ return -EINVAL;
-+
-+ return mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad,
-+ regnum, val);
-+}
-+EXPORT_SYMBOL(__phy_package_write_mmd);
-+
-+/**
-+ * phy_package_write_mmd - write MMD reg relative to PHY package base addr
-+ * @phydev: The phy_device struct
-+ * @addr_offset: The offset to be added to PHY package base_addr
-+ * @devad: The MMD to write to
-+ * @regnum: The register on the MMD to write
-+ * @val: value to write to @regnum
-+ *
-+ * Convenience helper for writing a register of an MMD on a given PHY
-+ * using the PHY package base address. The base address is added to
-+ * the addr_offset value.
-+ *
-+ * Same calling rules as for phy_write();
-+ *
-+ * NOTE: It's assumed that the entire PHY package is either C22 or C45.
-+ */
-+int phy_package_write_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum, u16 val)
-+{
-+ int addr = phy_package_address(phydev, addr_offset);
-+ int ret;
-+
-+ if (addr < 0)
-+ return addr;
-+
-+ if (regnum > (u16)~0 || devad > 32)
-+ return -EINVAL;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad,
-+ regnum, val);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(phy_package_write_mmd);
-+
-+/**
- * phy_modify_changed - Function for modifying a PHY register
- * @phydev: the phy_device struct
- * @regnum: register number to modify
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1840,6 +1840,22 @@ static inline int __phy_package_write(st
- return __mdiobus_write(phydev->mdio.bus, addr, regnum, val);
- }
-
-+int __phy_package_read_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum);
-+
-+int phy_package_read_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum);
-+
-+int __phy_package_write_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum, u16 val);
-+
-+int phy_package_write_mmd(struct phy_device *phydev,
-+ unsigned int addr_offset, int devad,
-+ u32 regnum, u16 val);
-+
- static inline bool __phy_package_set_once(struct phy_device *phydev,
- unsigned int b)
- {
diff --git a/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch b/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch
deleted file mode 100644
index 2886123f2d..0000000000
--- a/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From affa013f494486079c3c5ad2d00cebc41a3d7445 Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Mon, 17 Oct 2022 16:22:36 -0400
-Subject: [PATCH 01/21] net: fman: memac: Add serdes support
-
-This adds support for using a serdes which has to be configured. This is
-primarly in preparation for phylink conversion, which will then change the
-serdes mode dynamically.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../net/ethernet/freescale/fman/fman_memac.c | 49 ++++++++++++++++++-
- 1 file changed, 47 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/freescale/fman/fman_memac.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
-@@ -13,6 +13,7 @@
- #include <linux/io.h>
- #include <linux/phy.h>
- #include <linux/phy_fixed.h>
-+#include <linux/phy/phy.h>
- #include <linux/of_mdio.h>
-
- /* PCS registers */
-@@ -324,6 +325,7 @@ struct fman_mac {
- void *fm;
- struct fman_rev_info fm_rev_info;
- bool basex_if;
-+ struct phy *serdes;
- struct phy_device *pcsphy;
- bool allmulti_enabled;
- };
-@@ -1203,17 +1205,56 @@ int memac_initialization(struct mac_devi
- }
- }
-
-+ memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
-+ err = PTR_ERR(memac->serdes);
-+ if (err == -ENODEV || err == -ENOSYS) {
-+ dev_dbg(mac_dev->dev, "could not get (optional) serdes\n");
-+ memac->serdes = NULL;
-+ } else if (IS_ERR(memac->serdes)) {
-+ dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
-+ goto _return_fm_mac_free;
-+ } else {
-+ err = phy_init(memac->serdes);
-+ if (err) {
-+ dev_err_probe(mac_dev->dev, err,
-+ "could not initialize serdes\n");
-+ goto _return_fm_mac_free;
-+ }
-+
-+ err = phy_power_on(memac->serdes);
-+ if (err) {
-+ dev_err_probe(mac_dev->dev, err,
-+ "could not power on serdes\n");
-+ goto _return_phy_exit;
-+ }
-+
-+ if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
-+ memac->phy_if == PHY_INTERFACE_MODE_1000BASEX ||
-+ memac->phy_if == PHY_INTERFACE_MODE_2500BASEX ||
-+ memac->phy_if == PHY_INTERFACE_MODE_QSGMII ||
-+ memac->phy_if == PHY_INTERFACE_MODE_XGMII) {
-+ err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
-+ memac->phy_if);
-+ if (err) {
-+ dev_err_probe(mac_dev->dev, err,
-+ "could not set serdes mode to %s\n",
-+ phy_modes(memac->phy_if));
-+ goto _return_phy_power_off;
-+ }
-+ }
-+ }
-+
- if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
- struct phy_device *phy;
-
- err = of_phy_register_fixed_link(mac_node);
- if (err)
-- goto _return_fm_mac_free;
-+ goto _return_phy_power_off;
-
- fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
- if (!fixed_link) {
- err = -ENOMEM;
-- goto _return_fm_mac_free;
-+ goto _return_phy_power_off;
- }
-
- mac_dev->phy_node = of_node_get(mac_node);
-@@ -1242,6 +1283,10 @@ int memac_initialization(struct mac_devi
-
- goto _return;
-
-+_return_phy_power_off:
-+ phy_power_off(memac->serdes);
-+_return_phy_exit:
-+ phy_exit(memac->serdes);
- _return_fixed_link_free:
- kfree(fixed_link);
- _return_fm_mac_free:
diff --git a/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch b/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch
deleted file mode 100644
index 873debc080..0000000000
--- a/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch
+++ /dev/null
@@ -1,384 +0,0 @@
-From fe60e7154d3a35af975c5e6570d6ec31aab9a731 Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Mon, 17 Oct 2022 16:22:37 -0400
-Subject: [PATCH 02/21] net: fman: memac: Use lynx pcs driver
-
-Although not stated in the datasheet, as far as I can tell PCS for mEMACs
-is a "Lynx." By reusing the existing driver, we can remove the PCS
-management code from the memac driver. This requires calling some PCS
-functions manually which phylink would usually do for us, but we will let
-it do that soon.
-
-One problem is that we don't actually have a PCS for QSGMII. We pretend
-that each mEMAC's MDIO bus has four QSGMII PCSs, but this is not the case.
-Only the "base" mEMAC's MDIO bus has the four QSGMII PCSs. This is not an
-issue yet, because we never get the PCS state. However, it will be once the
-conversion to phylink is complete, since the links will appear to never
-come up. To get around this, we allow specifying multiple PCSs in pcsphy.
-This breaks backwards compatibility with old device trees, but only for
-QSGMII. IMO this is the only reasonable way to figure out what the actual
-QSGMII PCS is.
-
-Additionally, we now also support a separate XFI PCS. This can allow the
-SerDes driver to set different addresses for the SGMII and XFI PCSs so they
-can be accessed at the same time.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/freescale/fman/Kconfig | 3 +
- .../net/ethernet/freescale/fman/fman_memac.c | 258 +++++++-----------
- 2 files changed, 105 insertions(+), 156 deletions(-)
-
---- a/drivers/net/ethernet/freescale/fman/Kconfig
-+++ b/drivers/net/ethernet/freescale/fman/Kconfig
-@@ -4,6 +4,9 @@ config FSL_FMAN
- depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
- select GENERIC_ALLOCATOR
- select PHYLIB
-+ select PHYLINK
-+ select PCS
-+ select PCS_LYNX
- select CRC32
- default n
- help
---- a/drivers/net/ethernet/freescale/fman/fman_memac.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
-@@ -11,43 +11,12 @@
-
- #include <linux/slab.h>
- #include <linux/io.h>
-+#include <linux/pcs-lynx.h>
- #include <linux/phy.h>
- #include <linux/phy_fixed.h>
- #include <linux/phy/phy.h>
- #include <linux/of_mdio.h>
-
--/* PCS registers */
--#define MDIO_SGMII_CR 0x00
--#define MDIO_SGMII_DEV_ABIL_SGMII 0x04
--#define MDIO_SGMII_LINK_TMR_L 0x12
--#define MDIO_SGMII_LINK_TMR_H 0x13
--#define MDIO_SGMII_IF_MODE 0x14
--
--/* SGMII Control defines */
--#define SGMII_CR_AN_EN 0x1000
--#define SGMII_CR_RESTART_AN 0x0200
--#define SGMII_CR_FD 0x0100
--#define SGMII_CR_SPEED_SEL1_1G 0x0040
--#define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \
-- SGMII_CR_SPEED_SEL1_1G)
--
--/* SGMII Device Ability for SGMII defines */
--#define MDIO_SGMII_DEV_ABIL_SGMII_MODE 0x4001
--#define MDIO_SGMII_DEV_ABIL_BASEX_MODE 0x01A0
--
--/* Link timer define */
--#define LINK_TMR_L 0xa120
--#define LINK_TMR_H 0x0007
--#define LINK_TMR_L_BASEX 0xaf08
--#define LINK_TMR_H_BASEX 0x002f
--
--/* SGMII IF Mode defines */
--#define IF_MODE_USE_SGMII_AN 0x0002
--#define IF_MODE_SGMII_EN 0x0001
--#define IF_MODE_SGMII_SPEED_100M 0x0004
--#define IF_MODE_SGMII_SPEED_1G 0x0008
--#define IF_MODE_SGMII_DUPLEX_HALF 0x0010
--
- /* Num of additional exact match MAC adr regs */
- #define MEMAC_NUM_OF_PADDRS 7
-
-@@ -326,7 +295,9 @@ struct fman_mac {
- struct fman_rev_info fm_rev_info;
- bool basex_if;
- struct phy *serdes;
-- struct phy_device *pcsphy;
-+ struct phylink_pcs *sgmii_pcs;
-+ struct phylink_pcs *qsgmii_pcs;
-+ struct phylink_pcs *xfi_pcs;
- bool allmulti_enabled;
- };
-
-@@ -487,91 +458,22 @@ static u32 get_mac_addr_hash_code(u64 et
- return xor_val;
- }
-
--static void setup_sgmii_internal_phy(struct fman_mac *memac,
-- struct fixed_phy_status *fixed_link)
--{
-- u16 tmp_reg16;
--
-- if (WARN_ON(!memac->pcsphy))
-- return;
--
-- /* SGMII mode */
-- tmp_reg16 = IF_MODE_SGMII_EN;
-- if (!fixed_link)
-- /* AN enable */
-- tmp_reg16 |= IF_MODE_USE_SGMII_AN;
-- else {
-- switch (fixed_link->speed) {
-- case 10:
-- /* For 10M: IF_MODE[SPEED_10M] = 0 */
-- break;
-- case 100:
-- tmp_reg16 |= IF_MODE_SGMII_SPEED_100M;
-- break;
-- case 1000:
-- default:
-- tmp_reg16 |= IF_MODE_SGMII_SPEED_1G;
-- break;
-- }
-- if (!fixed_link->duplex)
-- tmp_reg16 |= IF_MODE_SGMII_DUPLEX_HALF;
-- }
-- phy_write(memac->pcsphy, MDIO_SGMII_IF_MODE, tmp_reg16);
--
-- /* Device ability according to SGMII specification */
-- tmp_reg16 = MDIO_SGMII_DEV_ABIL_SGMII_MODE;
-- phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16);
--
-- /* Adjust link timer for SGMII -
-- * According to Cisco SGMII specification the timer should be 1.6 ms.
-- * The link_timer register is configured in units of the clock.
-- * - When running as 1G SGMII, Serdes clock is 125 MHz, so
-- * unit = 1 / (125*10^6 Hz) = 8 ns.
-- * 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2*10^5 = 0x30d40
-- * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
-- * unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
-- * 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5*10^5 = 0x7a120.
-- * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
-- * we always set up here a value of 2.5 SGMII.
-- */
-- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H);
-- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L);
--
-- if (!fixed_link)
-- /* Restart AN */
-- tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN;
-+static void setup_sgmii_internal(struct fman_mac *memac,
-+ struct phylink_pcs *pcs,
-+ struct fixed_phy_status *fixed_link)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
-+ phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX :
-+ PHY_INTERFACE_MODE_SGMII;
-+ unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND;
-+
-+ linkmode_set_pause(advertising, true, true);
-+ pcs->ops->pcs_config(pcs, mode, iface, advertising, true);
-+ if (fixed_link)
-+ pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed,
-+ fixed_link->duplex);
- else
-- /* AN disabled */
-- tmp_reg16 = SGMII_CR_DEF_VAL & ~SGMII_CR_AN_EN;
-- phy_write(memac->pcsphy, 0x0, tmp_reg16);
--}
--
--static void setup_sgmii_internal_phy_base_x(struct fman_mac *memac)
--{
-- u16 tmp_reg16;
--
-- /* AN Device capability */
-- tmp_reg16 = MDIO_SGMII_DEV_ABIL_BASEX_MODE;
-- phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16);
--
-- /* Adjust link timer for SGMII -
-- * For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
-- * The link_timer register is configured in units of the clock.
-- * - When running as 1G SGMII, Serdes clock is 125 MHz, so
-- * unit = 1 / (125*10^6 Hz) = 8 ns.
-- * 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
-- * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
-- * unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
-- * 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
-- * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
-- * we always set up here a value of 2.5 SGMII.
-- */
-- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H_BASEX);
-- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L_BASEX);
--
-- /* Restart AN */
-- tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN;
-- phy_write(memac->pcsphy, 0x0, tmp_reg16);
-+ pcs->ops->pcs_an_restart(pcs);
- }
-
- static int check_init_parameters(struct fman_mac *memac)
-@@ -983,7 +885,6 @@ static int memac_set_exception(struct fm
- static int memac_init(struct fman_mac *memac)
- {
- struct memac_cfg *memac_drv_param;
-- u8 i;
- enet_addr_t eth_addr;
- bool slow_10g_if = false;
- struct fixed_phy_status *fixed_link = NULL;
-@@ -1036,32 +937,10 @@ static int memac_init(struct fman_mac *m
- iowrite32be(reg32, &memac->regs->command_config);
- }
-
-- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) {
-- /* Configure internal SGMII PHY */
-- if (memac->basex_if)
-- setup_sgmii_internal_phy_base_x(memac);
-- else
-- setup_sgmii_internal_phy(memac, fixed_link);
-- } else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) {
-- /* Configure 4 internal SGMII PHYs */
-- for (i = 0; i < 4; i++) {
-- u8 qsmgii_phy_addr, phy_addr;
-- /* QSGMII PHY address occupies 3 upper bits of 5-bit
-- * phy_address; the lower 2 bits are used to extend
-- * register address space and access each one of 4
-- * ports inside QSGMII.
-- */
-- phy_addr = memac->pcsphy->mdio.addr;
-- qsmgii_phy_addr = (u8)((phy_addr << 2) | i);
-- memac->pcsphy->mdio.addr = qsmgii_phy_addr;
-- if (memac->basex_if)
-- setup_sgmii_internal_phy_base_x(memac);
-- else
-- setup_sgmii_internal_phy(memac, fixed_link);
--
-- memac->pcsphy->mdio.addr = phy_addr;
-- }
-- }
-+ if (memac->phy_if == PHY_INTERFACE_MODE_SGMII)
-+ setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link);
-+ else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII)
-+ setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link);
-
- /* Max Frame Length */
- err = fman_set_mac_max_frame(memac->fm, memac->mac_id,
-@@ -1097,12 +976,25 @@ static int memac_init(struct fman_mac *m
- return 0;
- }
-
-+static void pcs_put(struct phylink_pcs *pcs)
-+{
-+ struct mdio_device *mdiodev;
-+
-+ if (IS_ERR_OR_NULL(pcs))
-+ return;
-+
-+ mdiodev = lynx_get_mdio_device(pcs);
-+ lynx_pcs_destroy(pcs);
-+ mdio_device_free(mdiodev);
-+}
-+
- static int memac_free(struct fman_mac *memac)
- {
- free_init_resources(memac);
-
-- if (memac->pcsphy)
-- put_device(&memac->pcsphy->mdio.dev);
-+ pcs_put(memac->sgmii_pcs);
-+ pcs_put(memac->qsgmii_pcs);
-+ pcs_put(memac->xfi_pcs);
-
- kfree(memac->memac_drv_param);
- kfree(memac);
-@@ -1153,12 +1045,31 @@ static struct fman_mac *memac_config(str
- return memac;
- }
-
-+static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node,
-+ int index)
-+{
-+ struct device_node *node;
-+ struct mdio_device *mdiodev = NULL;
-+ struct phylink_pcs *pcs;
-+
-+ node = of_parse_phandle(mac_node, "pcsphy-handle", index);
-+ if (node && of_device_is_available(node))
-+ mdiodev = of_mdio_find_device(node);
-+ of_node_put(node);
-+
-+ if (!mdiodev)
-+ return ERR_PTR(-EPROBE_DEFER);
-+
-+ pcs = lynx_pcs_create(mdiodev);
-+ return pcs;
-+}
-+
- int memac_initialization(struct mac_device *mac_dev,
- struct device_node *mac_node,
- struct fman_mac_params *params)
- {
- int err;
-- struct device_node *phy_node;
-+ struct phylink_pcs *pcs;
- struct fixed_phy_status *fixed_link;
- struct fman_mac *memac;
-
-@@ -1188,23 +1099,58 @@ int memac_initialization(struct mac_devi
- memac = mac_dev->fman_mac;
- memac->memac_drv_param->max_frame_length = fman_get_max_frm();
- memac->memac_drv_param->reset_on_init = true;
-- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
-- memac->phy_if == PHY_INTERFACE_MODE_QSGMII) {
-- phy_node = of_parse_phandle(mac_node, "pcsphy-handle", 0);
-- if (!phy_node) {
-- pr_err("PCS PHY node is not available\n");
-- err = -EINVAL;
-+
-+ err = of_property_match_string(mac_node, "pcs-handle-names", "xfi");
-+ if (err >= 0) {
-+ memac->xfi_pcs = memac_pcs_create(mac_node, err);
-+ if (IS_ERR(memac->xfi_pcs)) {
-+ err = PTR_ERR(memac->xfi_pcs);
-+ dev_err_probe(mac_dev->dev, err, "missing xfi pcs\n");
- goto _return_fm_mac_free;
- }
-+ } else if (err != -EINVAL && err != -ENODATA) {
-+ goto _return_fm_mac_free;
-+ }
-
-- memac->pcsphy = of_phy_find_device(phy_node);
-- if (!memac->pcsphy) {
-- pr_err("of_phy_find_device (PCS PHY) failed\n");
-- err = -EINVAL;
-+ err = of_property_match_string(mac_node, "pcs-handle-names", "qsgmii");
-+ if (err >= 0) {
-+ memac->qsgmii_pcs = memac_pcs_create(mac_node, err);
-+ if (IS_ERR(memac->qsgmii_pcs)) {
-+ err = PTR_ERR(memac->qsgmii_pcs);
-+ dev_err_probe(mac_dev->dev, err,
-+ "missing qsgmii pcs\n");
- goto _return_fm_mac_free;
- }
-+ } else if (err != -EINVAL && err != -ENODATA) {
-+ goto _return_fm_mac_free;
-+ }
-+
-+ /* For compatibility, if pcs-handle-names is missing, we assume this
-+ * phy is the first one in pcsphy-handle
-+ */
-+ err = of_property_match_string(mac_node, "pcs-handle-names", "sgmii");
-+ if (err == -EINVAL || err == -ENODATA)
-+ pcs = memac_pcs_create(mac_node, 0);
-+ else if (err < 0)
-+ goto _return_fm_mac_free;
-+ else
-+ pcs = memac_pcs_create(mac_node, err);
-+
-+ if (!pcs) {
-+ dev_err(mac_dev->dev, "missing pcs\n");
-+ err = -ENOENT;
-+ goto _return_fm_mac_free;
- }
-
-+ /* If err is set here, it means that pcs-handle-names was missing above
-+ * (and therefore that xfi_pcs cannot be set). If we are defaulting to
-+ * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII.
-+ */
-+ if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
-+ memac->xfi_pcs = pcs;
-+ else
-+ memac->sgmii_pcs = pcs;
-+
- memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
- err = PTR_ERR(memac->serdes);
- if (err == -ENODEV || err == -ENOSYS) {
diff --git a/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch b/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch
deleted file mode 100644
index 63b651bb2d..0000000000
--- a/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch
+++ /dev/null
@@ -1,2451 +0,0 @@
-From 38e50fc3d43882a43115b4f1ca3eb88255163c5b Mon Sep 17 00:00:00 2001
-From: Sean Anderson <sean.anderson@seco.com>
-Date: Mon, 17 Oct 2022 16:22:38 -0400
-Subject: [PATCH 03/21] net: dpaa: Convert to phylink
-
-This converts DPAA to phylink. All macs are converted. This should work
-with no device tree modifications (including those made in this series),
-except for QSGMII (as noted previously).
-
-The mEMAC configuration is one of the tricker areas. I have tried to
-capture all the restrictions across the various models. Most of the time,
-we assume that if the serdes supports a mode or the phy-interface-mode
-specifies it, then we support it. The only place we can't do this is
-(RG)MII, since there's no serdes. In that case, we rely on a (new)
-devicetree property. There are also several cases where half-duplex is
-broken. Unfortunately, only a single compatible is used for the MAC, so we
-have to use the board compatible instead.
-
-The 10GEC conversion is very straightforward, since it only supports XAUI.
-There is generally nothing to configure.
-
-The dTSEC conversion is broadly similar to mEMAC, but is simpler because we
-don't support configuring the SerDes (though this can be easily added) and
-we don't have multiple PCSs. From what I can tell, there's nothing
-different in the driver or documentation between SGMII and 1000BASE-X
-except for the advertising. Similarly, I couldn't find anything about
-2500BASE-X. In both cases, I treat them like SGMII. These modes aren't used
-by any in-tree boards. Similarly, despite being mentioned in the driver, I
-couldn't find any documented SoCs which supported QSGMII. I have left it
-unimplemented for now.
-
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/freescale/dpaa/Kconfig | 4 +-
- .../net/ethernet/freescale/dpaa/dpaa_eth.c | 89 +--
- .../ethernet/freescale/dpaa/dpaa_ethtool.c | 90 +--
- drivers/net/ethernet/freescale/fman/Kconfig | 1 -
- .../net/ethernet/freescale/fman/fman_dtsec.c | 458 +++++++--------
- .../net/ethernet/freescale/fman/fman_mac.h | 10 -
- .../net/ethernet/freescale/fman/fman_memac.c | 547 +++++++++---------
- .../net/ethernet/freescale/fman/fman_tgec.c | 131 ++---
- drivers/net/ethernet/freescale/fman/mac.c | 168 +-----
- drivers/net/ethernet/freescale/fman/mac.h | 23 +-
- 10 files changed, 612 insertions(+), 909 deletions(-)
-
---- a/drivers/net/ethernet/freescale/dpaa/Kconfig
-+++ b/drivers/net/ethernet/freescale/dpaa/Kconfig
-@@ -2,8 +2,8 @@
- menuconfig FSL_DPAA_ETH
- tristate "DPAA Ethernet"
- depends on FSL_DPAA && FSL_FMAN
-- select PHYLIB
-- select FIXED_PHY
-+ select PHYLINK
-+ select PCS_LYNX
- help
- Data Path Acceleration Architecture Ethernet driver,
- supporting the Freescale QorIQ chips.
---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
-+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
-@@ -264,8 +264,19 @@ static int dpaa_netdev_init(struct net_d
- net_dev->needed_headroom = priv->tx_headroom;
- net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
-
-- mac_dev->net_dev = net_dev;
-+ /* The rest of the config is filled in by the mac device already */
-+ mac_dev->phylink_config.dev = &net_dev->dev;
-+ mac_dev->phylink_config.type = PHYLINK_NETDEV;
- mac_dev->update_speed = dpaa_eth_cgr_set_speed;
-+ mac_dev->phylink = phylink_create(&mac_dev->phylink_config,
-+ dev_fwnode(mac_dev->dev),
-+ mac_dev->phy_if,
-+ mac_dev->phylink_ops);
-+ if (IS_ERR(mac_dev->phylink)) {
-+ err = PTR_ERR(mac_dev->phylink);
-+ dev_err_probe(dev, err, "Could not create phylink\n");
-+ return err;
-+ }
-
- /* start without the RUNNING flag, phylib controls it later */
- netif_carrier_off(net_dev);
-@@ -273,6 +284,7 @@ static int dpaa_netdev_init(struct net_d
- err = register_netdev(net_dev);
- if (err < 0) {
- dev_err(dev, "register_netdev() = %d\n", err);
-+ phylink_destroy(mac_dev->phylink);
- return err;
- }
-
-@@ -295,8 +307,7 @@ static int dpaa_stop(struct net_device *
- */
- msleep(200);
-
-- if (mac_dev->phy_dev)
-- phy_stop(mac_dev->phy_dev);
-+ phylink_stop(mac_dev->phylink);
- mac_dev->disable(mac_dev->fman_mac);
-
- for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
-@@ -305,8 +316,7 @@ static int dpaa_stop(struct net_device *
- err = error;
- }
-
-- if (net_dev->phydev)
-- phy_disconnect(net_dev->phydev);
-+ phylink_disconnect_phy(mac_dev->phylink);
- net_dev->phydev = NULL;
-
- msleep(200);
-@@ -834,10 +844,10 @@ static int dpaa_eth_cgr_init(struct dpaa
-
- /* Set different thresholds based on the configured MAC speed.
- * This may turn suboptimal if the MAC is reconfigured at another
-- * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
-+ * speed, so MACs must call dpaa_eth_cgr_set_speed in their link_up
- * callback.
- */
-- if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
-+ if (priv->mac_dev->phylink_config.mac_capabilities & MAC_10000FD)
- cs_th = DPAA_CS_THRESHOLD_10G;
- else
- cs_th = DPAA_CS_THRESHOLD_1G;
-@@ -866,7 +876,7 @@ out_error:
-
- static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed)
- {
-- struct net_device *net_dev = mac_dev->net_dev;
-+ struct net_device *net_dev = to_net_dev(mac_dev->phylink_config.dev);
- struct dpaa_priv *priv = netdev_priv(net_dev);
- struct qm_mcc_initcgr opts = { };
- u32 cs_th;
-@@ -2905,58 +2915,6 @@ static void dpaa_eth_napi_disable(struct
- }
- }
-
--static void dpaa_adjust_link(struct net_device *net_dev)
--{
-- struct mac_device *mac_dev;
-- struct dpaa_priv *priv;
--
-- priv = netdev_priv(net_dev);
-- mac_dev = priv->mac_dev;
-- mac_dev->adjust_link(mac_dev);
--}
--
--/* The Aquantia PHYs are capable of performing rate adaptation */
--#define PHY_VEND_AQUANTIA 0x03a1b400
--#define PHY_VEND_AQUANTIA2 0x31c31c00
--
--static int dpaa_phy_init(struct net_device *net_dev)
--{
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-- struct mac_device *mac_dev;
-- struct phy_device *phy_dev;
-- struct dpaa_priv *priv;
-- u32 phy_vendor;
--
-- priv = netdev_priv(net_dev);
-- mac_dev = priv->mac_dev;
--
-- phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
-- &dpaa_adjust_link, 0,
-- mac_dev->phy_if);
-- if (!phy_dev) {
-- netif_err(priv, ifup, net_dev, "init_phy() failed\n");
-- return -ENODEV;
-- }
--
-- phy_vendor = phy_dev->drv->phy_id & GENMASK(31, 10);
-- /* Unless the PHY is capable of rate adaptation */
-- if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII ||
-- (phy_vendor != PHY_VEND_AQUANTIA &&
-- phy_vendor != PHY_VEND_AQUANTIA2)) {
-- /* remove any features not supported by the controller */
-- ethtool_convert_legacy_u32_to_link_mode(mask,
-- mac_dev->if_support);
-- linkmode_and(phy_dev->supported, phy_dev->supported, mask);
-- }
--
-- phy_support_asym_pause(phy_dev);
--
-- mac_dev->phy_dev = phy_dev;
-- net_dev->phydev = phy_dev;
--
-- return 0;
--}
--
- static int dpaa_open(struct net_device *net_dev)
- {
- struct mac_device *mac_dev;
-@@ -2967,7 +2925,8 @@ static int dpaa_open(struct net_device *
- mac_dev = priv->mac_dev;
- dpaa_eth_napi_enable(priv);
-
-- err = dpaa_phy_init(net_dev);
-+ err = phylink_of_phy_connect(mac_dev->phylink,
-+ mac_dev->dev->of_node, 0);
- if (err)
- goto phy_init_failed;
-
-@@ -2982,7 +2941,7 @@ static int dpaa_open(struct net_device *
- netif_err(priv, ifup, net_dev, "mac_dev->enable() = %d\n", err);
- goto mac_start_failed;
- }
-- phy_start(priv->mac_dev->phy_dev);
-+ phylink_start(mac_dev->phylink);
-
- netif_tx_start_all_queues(net_dev);
-
-@@ -2991,6 +2950,7 @@ static int dpaa_open(struct net_device *
- mac_start_failed:
- for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++)
- fman_port_disable(mac_dev->port[i]);
-+ phylink_disconnect_phy(mac_dev->phylink);
-
- phy_init_failed:
- dpaa_eth_napi_disable(priv);
-@@ -3146,10 +3106,12 @@ static int dpaa_ts_ioctl(struct net_devi
- static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
- {
- int ret = -EINVAL;
-+ struct dpaa_priv *priv = netdev_priv(net_dev);
-
- if (cmd == SIOCGMIIREG) {
- if (net_dev->phydev)
-- return phy_mii_ioctl(net_dev->phydev, rq, cmd);
-+ return phylink_mii_ioctl(priv->mac_dev->phylink, rq,
-+ cmd);
- }
-
- if (cmd == SIOCSHWTSTAMP)
-@@ -3552,6 +3514,7 @@ static int dpaa_remove(struct platform_d
-
- dev_set_drvdata(dev, NULL);
- unregister_netdev(net_dev);
-+ phylink_destroy(priv->mac_dev->phylink);
-
- err = dpaa_fq_free(dev, &priv->dpaa_fq_list);
-
---- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
-+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
-@@ -54,27 +54,19 @@ static char dpaa_stats_global[][ETH_GSTR
- static int dpaa_get_link_ksettings(struct net_device *net_dev,
- struct ethtool_link_ksettings *cmd)
- {
-- if (!net_dev->phydev)
-- return 0;
-+ struct dpaa_priv *priv = netdev_priv(net_dev);
-+ struct mac_device *mac_dev = priv->mac_dev;
-
-- phy_ethtool_ksettings_get(net_dev->phydev, cmd);
--
-- return 0;
-+ return phylink_ethtool_ksettings_get(mac_dev->phylink, cmd);
- }
-
- static int dpaa_set_link_ksettings(struct net_device *net_dev,
- const struct ethtool_link_ksettings *cmd)
- {
-- int err;
--
-- if (!net_dev->phydev)
-- return -ENODEV;
-+ struct dpaa_priv *priv = netdev_priv(net_dev);
-+ struct mac_device *mac_dev = priv->mac_dev;
-
-- err = phy_ethtool_ksettings_set(net_dev->phydev, cmd);
-- if (err < 0)
-- netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", err);
--
-- return err;
-+ return phylink_ethtool_ksettings_set(mac_dev->phylink, cmd);
- }
-
- static void dpaa_get_drvinfo(struct net_device *net_dev,
-@@ -99,80 +91,28 @@ static void dpaa_set_msglevel(struct net
-
- static int dpaa_nway_reset(struct net_device *net_dev)
- {
-- int err;
--
-- if (!net_dev->phydev)
-- return -ENODEV;
-+ struct dpaa_priv *priv = netdev_priv(net_dev);
-+ struct mac_device *mac_dev = priv->mac_dev;
-
-- err = 0;
-- if (net_dev->phydev->autoneg) {
-- err = phy_start_aneg(net_dev->phydev);
-- if (err < 0)
-- netdev_err(net_dev, "phy_start_aneg() = %d\n",
-- err);
-- }
--
-- return err;
-+ return phylink_ethtool_nway_reset(mac_dev->phylink);
- }
-
- static void dpaa_get_pauseparam(struct net_device *net_dev,
- struct ethtool_pauseparam *epause)
- {
-- struct mac_device *mac_dev;
-- struct dpaa_priv *priv;
--
-- priv = netdev_priv(net_dev);
-- mac_dev = priv->mac_dev;
--
-- if (!net_dev->phydev)
-- return;
-+ struct dpaa_priv *priv = netdev_priv(net_dev);
-+ struct mac_device *mac_dev = priv->mac_dev;
-
-- epause->autoneg = mac_dev->autoneg_pause;
-- epause->rx_pause = mac_dev->rx_pause_active;
-- epause->tx_pause = mac_dev->tx_pause_active;
-+ phylink_ethtool_get_pauseparam(mac_dev->phylink, epause);
- }
-
- static int dpaa_set_pauseparam(struct net_device *net_dev,
- struct ethtool_pauseparam *epause)
- {
-- struct mac_device *mac_dev;
-- struct phy_device *phydev;
-- bool rx_pause, tx_pause;
-- struct dpaa_priv *priv;
-- int err;
--
-- priv = netdev_priv(net_dev);
-- mac_dev = priv->mac_dev;
--
-- phydev = net_dev->phydev;
-- if (!phydev) {
-- netdev_err(net_dev, "phy device not initialized\n");
-- return -ENODEV;
-- }
--
-- if (!phy_validate_pause(phydev, epause))
-- return -EINVAL;
--
-- /* The MAC should know how to handle PAUSE frame autonegotiation before
-- * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
-- * settings.
-- */
-- mac_dev->autoneg_pause = !!epause->autoneg;
-- mac_dev->rx_pause_req = !!epause->rx_pause;
-- mac_dev->tx_pause_req = !!epause->tx_pause;
--
-- /* Determine the sym/asym advertised PAUSE capabilities from the desired
-- * rx/tx pause settings.
-- */
--
-- phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause);
--
-- fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
-- err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
-- if (err < 0)
-- netdev_err(net_dev, "set_mac_active_pause() = %d\n", err);
-+ struct dpaa_priv *priv = netdev_priv(net_dev);
-+ struct mac_device *mac_dev = priv->mac_dev;
-
-- return err;
-+ return phylink_ethtool_set_pauseparam(mac_dev->phylink, epause);
- }
-
- static int dpaa_get_sset_count(struct net_device *net_dev, int type)
---- a/drivers/net/ethernet/freescale/fman/Kconfig
-+++ b/drivers/net/ethernet/freescale/fman/Kconfig
-@@ -3,7 +3,6 @@ config FSL_FMAN
- tristate "FMan support"
- depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
- select GENERIC_ALLOCATOR
-- select PHYLIB
- select PHYLINK
- select PCS
- select PCS_LYNX
---- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
-@@ -17,6 +17,7 @@
- #include <linux/crc32.h>
- #include <linux/of_mdio.h>
- #include <linux/mii.h>
-+#include <linux/netdevice.h>
-
- /* TBI register addresses */
- #define MII_TBICON 0x11
-@@ -29,9 +30,6 @@
- #define TBICON_CLK_SELECT 0x0020 /* Clock select */
- #define TBICON_MI_MODE 0x0010 /* GMII mode (TBI if not set) */
-
--#define TBIANA_SGMII 0x4001
--#define TBIANA_1000X 0x01a0
--
- /* Interrupt Mask Register (IMASK) */
- #define DTSEC_IMASK_BREN 0x80000000
- #define DTSEC_IMASK_RXCEN 0x40000000
-@@ -92,9 +90,10 @@
-
- #define DTSEC_ECNTRL_GMIIM 0x00000040
- #define DTSEC_ECNTRL_TBIM 0x00000020
--#define DTSEC_ECNTRL_SGMIIM 0x00000002
- #define DTSEC_ECNTRL_RPM 0x00000010
- #define DTSEC_ECNTRL_R100M 0x00000008
-+#define DTSEC_ECNTRL_RMM 0x00000004
-+#define DTSEC_ECNTRL_SGMIIM 0x00000002
- #define DTSEC_ECNTRL_QSGMIIM 0x00000001
-
- #define TCTRL_TTSE 0x00000040
-@@ -318,7 +317,8 @@ struct fman_mac {
- void *fm;
- struct fman_rev_info fm_rev_info;
- bool basex_if;
-- struct phy_device *tbiphy;
-+ struct mdio_device *tbidev;
-+ struct phylink_pcs pcs;
- };
-
- static void set_dflts(struct dtsec_cfg *cfg)
-@@ -356,56 +356,14 @@ static int init(struct dtsec_regs __iome
- phy_interface_t iface, u16 iface_speed, u64 addr,
- u32 exception_mask, u8 tbi_addr)
- {
-- bool is_rgmii, is_sgmii, is_qsgmii;
- enet_addr_t eth_addr;
-- u32 tmp;
-+ u32 tmp = 0;
- int i;
-
- /* Soft reset */
- iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
- iowrite32be(0, &regs->maccfg1);
-
-- /* dtsec_id2 */
-- tmp = ioread32be(&regs->tsec_id2);
--
-- /* check RGMII support */
-- if (iface == PHY_INTERFACE_MODE_RGMII ||
-- iface == PHY_INTERFACE_MODE_RGMII_ID ||
-- iface == PHY_INTERFACE_MODE_RGMII_RXID ||
-- iface == PHY_INTERFACE_MODE_RGMII_TXID ||
-- iface == PHY_INTERFACE_MODE_RMII)
-- if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
-- return -EINVAL;
--
-- if (iface == PHY_INTERFACE_MODE_SGMII ||
-- iface == PHY_INTERFACE_MODE_MII)
-- if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
-- return -EINVAL;
--
-- is_rgmii = iface == PHY_INTERFACE_MODE_RGMII ||
-- iface == PHY_INTERFACE_MODE_RGMII_ID ||
-- iface == PHY_INTERFACE_MODE_RGMII_RXID ||
-- iface == PHY_INTERFACE_MODE_RGMII_TXID;
-- is_sgmii = iface == PHY_INTERFACE_MODE_SGMII;
-- is_qsgmii = iface == PHY_INTERFACE_MODE_QSGMII;
--
-- tmp = 0;
-- if (is_rgmii || iface == PHY_INTERFACE_MODE_GMII)
-- tmp |= DTSEC_ECNTRL_GMIIM;
-- if (is_sgmii)
-- tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
-- if (is_qsgmii)
-- tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
-- DTSEC_ECNTRL_QSGMIIM);
-- if (is_rgmii)
-- tmp |= DTSEC_ECNTRL_RPM;
-- if (iface_speed == SPEED_100)
-- tmp |= DTSEC_ECNTRL_R100M;
--
-- iowrite32be(tmp, &regs->ecntrl);
--
-- tmp = 0;
--
- if (cfg->tx_pause_time)
- tmp |= cfg->tx_pause_time;
- if (cfg->tx_pause_time_extd)
-@@ -446,17 +404,10 @@ static int init(struct dtsec_regs __iome
-
- tmp = 0;
-
-- if (iface_speed < SPEED_1000)
-- tmp |= MACCFG2_NIBBLE_MODE;
-- else if (iface_speed == SPEED_1000)
-- tmp |= MACCFG2_BYTE_MODE;
--
- tmp |= (cfg->preamble_len << MACCFG2_PREAMBLE_LENGTH_SHIFT) &
- MACCFG2_PREAMBLE_LENGTH_MASK;
- if (cfg->tx_pad_crc)
- tmp |= MACCFG2_PAD_CRC_EN;
-- /* Full Duplex */
-- tmp |= MACCFG2_FULL_DUPLEX;
- iowrite32be(tmp, &regs->maccfg2);
-
- tmp = (((cfg->non_back_to_back_ipg1 <<
-@@ -525,10 +476,6 @@ static void set_bucket(struct dtsec_regs
-
- static int check_init_parameters(struct fman_mac *dtsec)
- {
-- if (dtsec->max_speed >= SPEED_10000) {
-- pr_err("1G MAC driver supports 1G or lower speeds\n");
-- return -EINVAL;
-- }
- if ((dtsec->dtsec_drv_param)->rx_prepend >
- MAX_PACKET_ALIGNMENT) {
- pr_err("packetAlignmentPadding can't be > than %d\n",
-@@ -630,22 +577,10 @@ static int get_exception_flag(enum fman_
- return bit_mask;
- }
-
--static bool is_init_done(struct dtsec_cfg *dtsec_drv_params)
--{
-- /* Checks if dTSEC driver parameters were initialized */
-- if (!dtsec_drv_params)
-- return true;
--
-- return false;
--}
--
- static u16 dtsec_get_max_frame_length(struct fman_mac *dtsec)
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
-
-- if (is_init_done(dtsec->dtsec_drv_param))
-- return 0;
--
- return (u16)ioread32be(&regs->maxfrm);
- }
-
-@@ -682,6 +617,7 @@ static void dtsec_isr(void *handle)
- dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_COL_RET_LMT);
- if (event & DTSEC_IMASK_XFUNEN) {
- /* FM_TX_LOCKUP_ERRATA_DTSEC6 Errata workaround */
-+ /* FIXME: This races with the rest of the driver! */
- if (dtsec->fm_rev_info.major == 2) {
- u32 tpkt1, tmp_reg1, tpkt2, tmp_reg2, i;
- /* a. Write 0x00E0_0C00 to DTSEC_ID
-@@ -814,6 +750,43 @@ static void free_init_resources(struct f
- dtsec->unicast_addr_hash = NULL;
- }
-
-+static struct fman_mac *pcs_to_dtsec(struct phylink_pcs *pcs)
-+{
-+ return container_of(pcs, struct fman_mac, pcs);
-+}
-+
-+static void dtsec_pcs_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
-+{
-+ struct fman_mac *dtsec = pcs_to_dtsec(pcs);
-+
-+ phylink_mii_c22_pcs_get_state(dtsec->tbidev, state);
-+}
-+
-+static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface,
-+ const unsigned long *advertising,
-+ bool permit_pause_to_mac)
-+{
-+ struct fman_mac *dtsec = pcs_to_dtsec(pcs);
-+
-+ return phylink_mii_c22_pcs_config(dtsec->tbidev, mode, interface,
-+ advertising);
-+}
-+
-+static void dtsec_pcs_an_restart(struct phylink_pcs *pcs)
-+{
-+ struct fman_mac *dtsec = pcs_to_dtsec(pcs);
-+
-+ phylink_mii_c22_pcs_an_restart(dtsec->tbidev);
-+}
-+
-+static const struct phylink_pcs_ops dtsec_pcs_ops = {
-+ .pcs_get_state = dtsec_pcs_get_state,
-+ .pcs_config = dtsec_pcs_config,
-+ .pcs_an_restart = dtsec_pcs_an_restart,
-+};
-+
- static void graceful_start(struct fman_mac *dtsec)
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
-@@ -854,36 +827,11 @@ static void graceful_stop(struct fman_ma
-
- static int dtsec_enable(struct fman_mac *dtsec)
- {
-- struct dtsec_regs __iomem *regs = dtsec->regs;
-- u32 tmp;
--
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
-- /* Enable */
-- tmp = ioread32be(&regs->maccfg1);
-- tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN;
-- iowrite32be(tmp, &regs->maccfg1);
--
-- /* Graceful start - clear the graceful Rx/Tx stop bit */
-- graceful_start(dtsec);
--
- return 0;
- }
-
- static void dtsec_disable(struct fman_mac *dtsec)
- {
-- struct dtsec_regs __iomem *regs = dtsec->regs;
-- u32 tmp;
--
-- WARN_ON_ONCE(!is_init_done(dtsec->dtsec_drv_param));
--
-- /* Graceful stop - Assert the graceful Rx/Tx stop bit */
-- graceful_stop(dtsec);
--
-- tmp = ioread32be(&regs->maccfg1);
-- tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
-- iowrite32be(tmp, &regs->maccfg1);
- }
-
- static int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
-@@ -894,11 +842,6 @@ static int dtsec_set_tx_pause_frames(str
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 ptv = 0;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
-- graceful_stop(dtsec);
--
- if (pause_time) {
- /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 Errata workaround */
- if (dtsec->fm_rev_info.major == 2 && pause_time <= 320) {
-@@ -919,8 +862,6 @@ static int dtsec_set_tx_pause_frames(str
- iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
- &regs->maccfg1);
-
-- graceful_start(dtsec);
--
- return 0;
- }
-
-@@ -929,11 +870,6 @@ static int dtsec_accept_rx_pause_frames(
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 tmp;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
-- graceful_stop(dtsec);
--
- tmp = ioread32be(&regs->maccfg1);
- if (en)
- tmp |= MACCFG1_RX_FLOW;
-@@ -941,17 +877,125 @@ static int dtsec_accept_rx_pause_frames(
- tmp &= ~MACCFG1_RX_FLOW;
- iowrite32be(tmp, &regs->maccfg1);
-
-+ return 0;
-+}
-+
-+static struct phylink_pcs *dtsec_select_pcs(struct phylink_config *config,
-+ phy_interface_t iface)
-+{
-+ struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac;
-+
-+ switch (iface) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ return &dtsec->pcs;
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
-+ const struct phylink_link_state *state)
-+{
-+ struct mac_device *mac_dev = fman_config_to_mac(config);
-+ struct dtsec_regs __iomem *regs = mac_dev->fman_mac->regs;
-+ u32 tmp;
-+
-+ switch (state->interface) {
-+ case PHY_INTERFACE_MODE_RMII:
-+ tmp = DTSEC_ECNTRL_RMM;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ tmp = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM;
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ tmp = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM;
-+ break;
-+ default:
-+ dev_warn(mac_dev->dev, "cannot configure dTSEC for %s\n",
-+ phy_modes(state->interface));
-+ return;
-+ }
-+
-+ iowrite32be(tmp, &regs->ecntrl);
-+}
-+
-+static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ struct mac_device *mac_dev = fman_config_to_mac(config);
-+ struct fman_mac *dtsec = mac_dev->fman_mac;
-+ struct dtsec_regs __iomem *regs = dtsec->regs;
-+ u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
-+ FSL_FM_PAUSE_TIME_DISABLE;
-+ u32 tmp;
-+
-+ dtsec_set_tx_pause_frames(dtsec, 0, pause_time, 0);
-+ dtsec_accept_rx_pause_frames(dtsec, rx_pause);
-+
-+ tmp = ioread32be(&regs->ecntrl);
-+ if (speed == SPEED_100)
-+ tmp |= DTSEC_ECNTRL_R100M;
-+ else
-+ tmp &= ~DTSEC_ECNTRL_R100M;
-+ iowrite32be(tmp, &regs->ecntrl);
-+
-+ tmp = ioread32be(&regs->maccfg2);
-+ tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE | MACCFG2_FULL_DUPLEX);
-+ if (speed >= SPEED_1000)
-+ tmp |= MACCFG2_BYTE_MODE;
-+ else
-+ tmp |= MACCFG2_NIBBLE_MODE;
-+
-+ if (duplex == DUPLEX_FULL)
-+ tmp |= MACCFG2_FULL_DUPLEX;
-+
-+ iowrite32be(tmp, &regs->maccfg2);
-+
-+ mac_dev->update_speed(mac_dev, speed);
-+
-+ /* Enable */
-+ tmp = ioread32be(&regs->maccfg1);
-+ tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN;
-+ iowrite32be(tmp, &regs->maccfg1);
-+
-+ /* Graceful start - clear the graceful Rx/Tx stop bit */
- graceful_start(dtsec);
-+}
-
-- return 0;
-+static void dtsec_link_down(struct phylink_config *config, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac;
-+ struct dtsec_regs __iomem *regs = dtsec->regs;
-+ u32 tmp;
-+
-+ /* Graceful stop - Assert the graceful Rx/Tx stop bit */
-+ graceful_stop(dtsec);
-+
-+ tmp = ioread32be(&regs->maccfg1);
-+ tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
-+ iowrite32be(tmp, &regs->maccfg1);
- }
-
-+static const struct phylink_mac_ops dtsec_mac_ops = {
-+ .validate = phylink_generic_validate,
-+ .mac_select_pcs = dtsec_select_pcs,
-+ .mac_config = dtsec_mac_config,
-+ .mac_link_up = dtsec_link_up,
-+ .mac_link_down = dtsec_link_down,
-+};
-+
- static int dtsec_modify_mac_address(struct fman_mac *dtsec,
- const enet_addr_t *enet_addr)
- {
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- graceful_stop(dtsec);
-
- /* Initialize MAC Station Address registers (1 & 2)
-@@ -975,9 +1019,6 @@ static int dtsec_add_hash_mac_address(st
- u32 crc = 0xFFFFFFFF;
- bool mcast, ghtx;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? true : false);
-@@ -1037,9 +1078,6 @@ static int dtsec_set_allmulti(struct fma
- u32 tmp;
- struct dtsec_regs __iomem *regs = dtsec->regs;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- tmp = ioread32be(&regs->rctrl);
- if (enable)
- tmp |= RCTRL_MPROM;
-@@ -1056,9 +1094,6 @@ static int dtsec_set_tstamp(struct fman_
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 rctrl, tctrl;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- rctrl = ioread32be(&regs->rctrl);
- tctrl = ioread32be(&regs->tctrl);
-
-@@ -1087,9 +1122,6 @@ static int dtsec_del_hash_mac_address(st
- u32 crc = 0xFFFFFFFF;
- bool mcast, ghtx;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? true : false);
-@@ -1153,9 +1185,6 @@ static int dtsec_set_promiscuous(struct
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 tmp;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- /* Set unicast promiscuous */
- tmp = ioread32be(&regs->rctrl);
- if (new_val)
-@@ -1177,90 +1206,12 @@ static int dtsec_set_promiscuous(struct
- return 0;
- }
-
--static int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
--{
-- struct dtsec_regs __iomem *regs = dtsec->regs;
-- u32 tmp;
--
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
-- graceful_stop(dtsec);
--
-- tmp = ioread32be(&regs->maccfg2);
--
-- /* Full Duplex */
-- tmp |= MACCFG2_FULL_DUPLEX;
--
-- tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
-- if (speed < SPEED_1000)
-- tmp |= MACCFG2_NIBBLE_MODE;
-- else if (speed == SPEED_1000)
-- tmp |= MACCFG2_BYTE_MODE;
-- iowrite32be(tmp, &regs->maccfg2);
--
-- tmp = ioread32be(&regs->ecntrl);
-- if (speed == SPEED_100)
-- tmp |= DTSEC_ECNTRL_R100M;
-- else
-- tmp &= ~DTSEC_ECNTRL_R100M;
-- iowrite32be(tmp, &regs->ecntrl);
--
-- graceful_start(dtsec);
--
-- return 0;
--}
--
--static int dtsec_restart_autoneg(struct fman_mac *dtsec)
--{
-- u16 tmp_reg16;
--
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
-- tmp_reg16 = phy_read(dtsec->tbiphy, MII_BMCR);
--
-- tmp_reg16 &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
-- tmp_reg16 |= (BMCR_ANENABLE | BMCR_ANRESTART |
-- BMCR_FULLDPLX | BMCR_SPEED1000);
--
-- phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
--
-- return 0;
--}
--
--static void adjust_link_dtsec(struct mac_device *mac_dev)
--{
-- struct phy_device *phy_dev = mac_dev->phy_dev;
-- struct fman_mac *fman_mac;
-- bool rx_pause, tx_pause;
-- int err;
--
-- fman_mac = mac_dev->fman_mac;
-- if (!phy_dev->link) {
-- dtsec_restart_autoneg(fman_mac);
--
-- return;
-- }
--
-- dtsec_adjust_link(fman_mac, phy_dev->speed);
-- mac_dev->update_speed(mac_dev, phy_dev->speed);
-- fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
-- err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
-- if (err < 0)
-- dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
-- err);
--}
--
- static int dtsec_set_exception(struct fman_mac *dtsec,
- enum fman_mac_exceptions exception, bool enable)
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 bit_mask = 0;
-
-- if (!is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- if (exception != FM_MAC_EX_1G_1588_TS_RX_ERR) {
- bit_mask = get_exception_flag(exception);
- if (bit_mask) {
-@@ -1310,12 +1261,9 @@ static int dtsec_init(struct fman_mac *d
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
- struct dtsec_cfg *dtsec_drv_param;
-- u16 max_frm_ln;
-+ u16 max_frm_ln, tbicon;
- int err;
-
-- if (is_init_done(dtsec->dtsec_drv_param))
-- return -EINVAL;
--
- if (DEFAULT_RESET_ON_INIT &&
- (fman_reset_mac(dtsec->fm, dtsec->mac_id) != 0)) {
- pr_err("Can't reset MAC!\n");
-@@ -1330,38 +1278,19 @@ static int dtsec_init(struct fman_mac *d
-
- err = init(dtsec->regs, dtsec_drv_param, dtsec->phy_if,
- dtsec->max_speed, dtsec->addr, dtsec->exceptions,
-- dtsec->tbiphy->mdio.addr);
-+ dtsec->tbidev->addr);
- if (err) {
- free_init_resources(dtsec);
- pr_err("DTSEC version doesn't support this i/f mode\n");
- return err;
- }
-
-- if (dtsec->phy_if == PHY_INTERFACE_MODE_SGMII) {
-- u16 tmp_reg16;
--
-- /* Configure the TBI PHY Control Register */
-- tmp_reg16 = TBICON_CLK_SELECT | TBICON_SOFT_RESET;
-- phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
--
-- tmp_reg16 = TBICON_CLK_SELECT;
-- phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
--
-- tmp_reg16 = (BMCR_RESET | BMCR_ANENABLE |
-- BMCR_FULLDPLX | BMCR_SPEED1000);
-- phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
--
-- if (dtsec->basex_if)
-- tmp_reg16 = TBIANA_1000X;
-- else
-- tmp_reg16 = TBIANA_SGMII;
-- phy_write(dtsec->tbiphy, MII_ADVERTISE, tmp_reg16);
-+ /* Configure the TBI PHY Control Register */
-+ tbicon = TBICON_CLK_SELECT | TBICON_SOFT_RESET;
-+ mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon);
-
-- tmp_reg16 = (BMCR_ANENABLE | BMCR_ANRESTART |
-- BMCR_FULLDPLX | BMCR_SPEED1000);
--
-- phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
-- }
-+ tbicon = TBICON_CLK_SELECT;
-+ mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon);
-
- /* Max Frame Length */
- max_frm_ln = (u16)ioread32be(&regs->maxfrm);
-@@ -1406,6 +1335,8 @@ static int dtsec_free(struct fman_mac *d
-
- kfree(dtsec->dtsec_drv_param);
- dtsec->dtsec_drv_param = NULL;
-+ if (!IS_ERR_OR_NULL(dtsec->tbidev))
-+ put_device(&dtsec->tbidev->dev);
- kfree(dtsec);
-
- return 0;
-@@ -1434,7 +1365,6 @@ static struct fman_mac *dtsec_config(str
-
- dtsec->regs = mac_dev->vaddr;
- dtsec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
-- dtsec->max_speed = params->max_speed;
- dtsec->phy_if = mac_dev->phy_if;
- dtsec->mac_id = params->mac_id;
- dtsec->exceptions = (DTSEC_IMASK_BREN |
-@@ -1457,7 +1387,6 @@ static struct fman_mac *dtsec_config(str
- dtsec->en_tsu_err_exception = dtsec->dtsec_drv_param->ptp_exception_en;
-
- dtsec->fm = params->fm;
-- dtsec->basex_if = params->basex_if;
-
- /* Save FMan revision */
- fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);
-@@ -1476,18 +1405,18 @@ int dtsec_initialization(struct mac_devi
- int err;
- struct fman_mac *dtsec;
- struct device_node *phy_node;
-+ unsigned long capabilities;
-+ unsigned long *supported;
-
-+ mac_dev->phylink_ops = &dtsec_mac_ops;
- mac_dev->set_promisc = dtsec_set_promiscuous;
- mac_dev->change_addr = dtsec_modify_mac_address;
- mac_dev->add_hash_mac_addr = dtsec_add_hash_mac_address;
- mac_dev->remove_hash_mac_addr = dtsec_del_hash_mac_address;
-- mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
-- mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
- mac_dev->set_exception = dtsec_set_exception;
- mac_dev->set_allmulti = dtsec_set_allmulti;
- mac_dev->set_tstamp = dtsec_set_tstamp;
- mac_dev->set_multi = fman_set_multi;
-- mac_dev->adjust_link = adjust_link_dtsec;
- mac_dev->enable = dtsec_enable;
- mac_dev->disable = dtsec_disable;
-
-@@ -1502,19 +1431,56 @@ int dtsec_initialization(struct mac_devi
- dtsec->dtsec_drv_param->tx_pad_crc = true;
-
- phy_node = of_parse_phandle(mac_node, "tbi-handle", 0);
-- if (!phy_node) {
-- pr_err("TBI PHY node is not available\n");
-+ if (!phy_node || of_device_is_available(phy_node)) {
-+ of_node_put(phy_node);
- err = -EINVAL;
-+ dev_err_probe(mac_dev->dev, err,
-+ "TBI PCS node is not available\n");
- goto _return_fm_mac_free;
- }
-
-- dtsec->tbiphy = of_phy_find_device(phy_node);
-- if (!dtsec->tbiphy) {
-- pr_err("of_phy_find_device (TBI PHY) failed\n");
-- err = -EINVAL;
-+ dtsec->tbidev = of_mdio_find_device(phy_node);
-+ of_node_put(phy_node);
-+ if (!dtsec->tbidev) {
-+ err = -EPROBE_DEFER;
-+ dev_err_probe(mac_dev->dev, err,
-+ "could not find mdiodev for PCS\n");
- goto _return_fm_mac_free;
- }
-- put_device(&dtsec->tbiphy->mdio.dev);
-+ dtsec->pcs.ops = &dtsec_pcs_ops;
-+ dtsec->pcs.poll = true;
-+
-+ supported = mac_dev->phylink_config.supported_interfaces;
-+
-+ /* FIXME: Can we use DTSEC_ID2_INT_FULL_OFF to determine if these are
-+ * supported? If not, we can determine support via the phy if SerDes
-+ * support is added.
-+ */
-+ if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII ||
-+ mac_dev->phy_if == PHY_INTERFACE_MODE_1000BASEX) {
-+ __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
-+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
-+ } else if (mac_dev->phy_if == PHY_INTERFACE_MODE_2500BASEX) {
-+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
-+ }
-+
-+ if (!(ioread32be(&dtsec->regs->tsec_id2) & DTSEC_ID2_INT_REDUCED_OFF)) {
-+ phy_interface_set_rgmii(supported);
-+
-+ /* DTSEC_ID2_INT_REDUCED_OFF indicates that the dTSEC supports
-+ * RMII and RGMII. However, the only SoCs which support RMII
-+ * are the P1017 and P1023. Avoid advertising this mode on
-+ * other SoCs. This is a bit of a moot point, since there's no
-+ * in-tree support for ethernet on these platforms...
-+ */
-+ if (of_machine_is_compatible("fsl,P1023") ||
-+ of_machine_is_compatible("fsl,P1023RDB"))
-+ __set_bit(PHY_INTERFACE_MODE_RMII, supported);
-+ }
-+
-+ capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
-+ capabilities |= MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
-+ mac_dev->phylink_config.mac_capabilities = capabilities;
-
- err = dtsec_init(dtsec);
- if (err < 0)
---- a/drivers/net/ethernet/freescale/fman/fman_mac.h
-+++ b/drivers/net/ethernet/freescale/fman/fman_mac.h
-@@ -170,20 +170,10 @@ struct fman_mac_params {
- * 0 - FM_MAX_NUM_OF_10G_MACS
- */
- u8 mac_id;
-- /* Note that the speed should indicate the maximum rate that
-- * this MAC should support rather than the actual speed;
-- */
-- u16 max_speed;
- /* A handle to the FM object this port related to */
- void *fm;
- fman_mac_exception_cb *event_cb; /* MDIO Events Callback Routine */
- fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */
-- /* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
-- * and phy or backplane; Note: 1000BaseX auto-negotiation relates only
-- * to interface between MAC and phy/backplane, SGMII phy can still
-- * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps
-- */
-- bool basex_if;
- };
-
- struct eth_hash_t {
---- a/drivers/net/ethernet/freescale/fman/fman_memac.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
-@@ -278,9 +278,6 @@ struct fman_mac {
- struct memac_regs __iomem *regs;
- /* MAC address of device */
- u64 addr;
-- /* Ethernet physical interface */
-- phy_interface_t phy_if;
-- u16 max_speed;
- struct mac_device *dev_id; /* device cookie used by the exception cbs */
- fman_mac_exception_cb *exception_cb;
- fman_mac_exception_cb *event_cb;
-@@ -293,12 +290,12 @@ struct fman_mac {
- struct memac_cfg *memac_drv_param;
- void *fm;
- struct fman_rev_info fm_rev_info;
-- bool basex_if;
- struct phy *serdes;
- struct phylink_pcs *sgmii_pcs;
- struct phylink_pcs *qsgmii_pcs;
- struct phylink_pcs *xfi_pcs;
- bool allmulti_enabled;
-+ bool rgmii_no_half_duplex;
- };
-
- static void add_addr_in_paddr(struct memac_regs __iomem *regs, const u8 *adr,
-@@ -356,7 +353,6 @@ static void set_exception(struct memac_r
- }
-
- static int init(struct memac_regs __iomem *regs, struct memac_cfg *cfg,
-- phy_interface_t phy_if, u16 speed, bool slow_10g_if,
- u32 exceptions)
- {
- u32 tmp;
-@@ -384,41 +380,6 @@ static int init(struct memac_regs __iome
- iowrite32be((u32)cfg->pause_quanta, &regs->pause_quanta[0]);
- iowrite32be((u32)0, &regs->pause_thresh[0]);
-
-- /* IF_MODE */
-- tmp = 0;
-- switch (phy_if) {
-- case PHY_INTERFACE_MODE_XGMII:
-- tmp |= IF_MODE_10G;
-- break;
-- case PHY_INTERFACE_MODE_MII:
-- tmp |= IF_MODE_MII;
-- break;
-- default:
-- tmp |= IF_MODE_GMII;
-- if (phy_if == PHY_INTERFACE_MODE_RGMII ||
-- phy_if == PHY_INTERFACE_MODE_RGMII_ID ||
-- phy_if == PHY_INTERFACE_MODE_RGMII_RXID ||
-- phy_if == PHY_INTERFACE_MODE_RGMII_TXID)
-- tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
-- }
-- iowrite32be(tmp, &regs->if_mode);
--
-- /* TX_FIFO_SECTIONS */
-- tmp = 0;
-- if (phy_if == PHY_INTERFACE_MODE_XGMII) {
-- if (slow_10g_if) {
-- tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
-- TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
-- } else {
-- tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
-- TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
-- }
-- } else {
-- tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
-- TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
-- }
-- iowrite32be(tmp, &regs->tx_fifo_sections);
--
- /* clear all pending events and set-up interrupts */
- iowrite32be(0xffffffff, &regs->ievent);
- set_exception(regs, exceptions, true);
-@@ -458,24 +419,6 @@ static u32 get_mac_addr_hash_code(u64 et
- return xor_val;
- }
-
--static void setup_sgmii_internal(struct fman_mac *memac,
-- struct phylink_pcs *pcs,
-- struct fixed_phy_status *fixed_link)
--{
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
-- phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX :
-- PHY_INTERFACE_MODE_SGMII;
-- unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND;
--
-- linkmode_set_pause(advertising, true, true);
-- pcs->ops->pcs_config(pcs, mode, iface, advertising, true);
-- if (fixed_link)
-- pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed,
-- fixed_link->duplex);
-- else
-- pcs->ops->pcs_an_restart(pcs);
--}
--
- static int check_init_parameters(struct fman_mac *memac)
- {
- if (!memac->exception_cb) {
-@@ -581,41 +524,31 @@ static void free_init_resources(struct f
- memac->unicast_addr_hash = NULL;
- }
-
--static bool is_init_done(struct memac_cfg *memac_drv_params)
--{
-- /* Checks if mEMAC driver parameters were initialized */
-- if (!memac_drv_params)
-- return true;
--
-- return false;
--}
--
- static int memac_enable(struct fman_mac *memac)
- {
-- struct memac_regs __iomem *regs = memac->regs;
-- u32 tmp;
-+ int ret;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
-+ ret = phy_init(memac->serdes);
-+ if (ret) {
-+ dev_err(memac->dev_id->dev,
-+ "could not initialize serdes: %pe\n", ERR_PTR(ret));
-+ return ret;
-+ }
-
-- tmp = ioread32be(&regs->command_config);
-- tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
-- iowrite32be(tmp, &regs->command_config);
-+ ret = phy_power_on(memac->serdes);
-+ if (ret) {
-+ dev_err(memac->dev_id->dev,
-+ "could not power on serdes: %pe\n", ERR_PTR(ret));
-+ phy_exit(memac->serdes);
-+ }
-
-- return 0;
-+ return ret;
- }
-
- static void memac_disable(struct fman_mac *memac)
--
- {
-- struct memac_regs __iomem *regs = memac->regs;
-- u32 tmp;
--
-- WARN_ON_ONCE(!is_init_done(memac->memac_drv_param));
--
-- tmp = ioread32be(&regs->command_config);
-- tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
-- iowrite32be(tmp, &regs->command_config);
-+ phy_power_off(memac->serdes);
-+ phy_exit(memac->serdes);
- }
-
- static int memac_set_promiscuous(struct fman_mac *memac, bool new_val)
-@@ -623,9 +556,6 @@ static int memac_set_promiscuous(struct
- struct memac_regs __iomem *regs = memac->regs;
- u32 tmp;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- tmp = ioread32be(&regs->command_config);
- if (new_val)
- tmp |= CMD_CFG_PROMIS_EN;
-@@ -637,73 +567,12 @@ static int memac_set_promiscuous(struct
- return 0;
- }
-
--static int memac_adjust_link(struct fman_mac *memac, u16 speed)
--{
-- struct memac_regs __iomem *regs = memac->regs;
-- u32 tmp;
--
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
-- tmp = ioread32be(&regs->if_mode);
--
-- /* Set full duplex */
-- tmp &= ~IF_MODE_HD;
--
-- if (phy_interface_mode_is_rgmii(memac->phy_if)) {
-- /* Configure RGMII in manual mode */
-- tmp &= ~IF_MODE_RGMII_AUTO;
-- tmp &= ~IF_MODE_RGMII_SP_MASK;
-- /* Full duplex */
-- tmp |= IF_MODE_RGMII_FD;
--
-- switch (speed) {
-- case SPEED_1000:
-- tmp |= IF_MODE_RGMII_1000;
-- break;
-- case SPEED_100:
-- tmp |= IF_MODE_RGMII_100;
-- break;
-- case SPEED_10:
-- tmp |= IF_MODE_RGMII_10;
-- break;
-- default:
-- break;
-- }
-- }
--
-- iowrite32be(tmp, &regs->if_mode);
--
-- return 0;
--}
--
--static void adjust_link_memac(struct mac_device *mac_dev)
--{
-- struct phy_device *phy_dev = mac_dev->phy_dev;
-- struct fman_mac *fman_mac;
-- bool rx_pause, tx_pause;
-- int err;
--
-- fman_mac = mac_dev->fman_mac;
-- memac_adjust_link(fman_mac, phy_dev->speed);
-- mac_dev->update_speed(mac_dev, phy_dev->speed);
--
-- fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
-- err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
-- if (err < 0)
-- dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
-- err);
--}
--
- static int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
- u16 pause_time, u16 thresh_time)
- {
- struct memac_regs __iomem *regs = memac->regs;
- u32 tmp;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- tmp = ioread32be(&regs->tx_fifo_sections);
-
- GET_TX_EMPTY_DEFAULT_VALUE(tmp);
-@@ -738,9 +607,6 @@ static int memac_accept_rx_pause_frames(
- struct memac_regs __iomem *regs = memac->regs;
- u32 tmp;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- tmp = ioread32be(&regs->command_config);
- if (en)
- tmp &= ~CMD_CFG_PAUSE_IGNORE;
-@@ -752,12 +618,175 @@ static int memac_accept_rx_pause_frames(
- return 0;
- }
-
-+static void memac_validate(struct phylink_config *config,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
-+ unsigned long caps = config->mac_capabilities;
-+
-+ if (phy_interface_mode_is_rgmii(state->interface) &&
-+ memac->rgmii_no_half_duplex)
-+ caps &= ~(MAC_10HD | MAC_100HD);
-+
-+ phylink_validate_mask_caps(supported, state, caps);
-+}
-+
-+/**
-+ * memac_if_mode() - Convert an interface mode into an IF_MODE config
-+ * @interface: A phy interface mode
-+ *
-+ * Return: A configuration word, suitable for programming into the lower bits
-+ * of %IF_MODE.
-+ */
-+static u32 memac_if_mode(phy_interface_t interface)
-+{
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_MII:
-+ return IF_MODE_MII;
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ return IF_MODE_GMII | IF_MODE_RGMII;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ return IF_MODE_GMII;
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ return IF_MODE_10G;
-+ default:
-+ WARN_ON_ONCE(1);
-+ return 0;
-+ }
-+}
-+
-+static struct phylink_pcs *memac_select_pcs(struct phylink_config *config,
-+ phy_interface_t iface)
-+{
-+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
-+
-+ switch (iface) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ return memac->sgmii_pcs;
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ return memac->qsgmii_pcs;
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ return memac->xfi_pcs;
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+static int memac_prepare(struct phylink_config *config, unsigned int mode,
-+ phy_interface_t iface)
-+{
-+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
-+
-+ switch (iface) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ return phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
-+ iface);
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static void memac_mac_config(struct phylink_config *config, unsigned int mode,
-+ const struct phylink_link_state *state)
-+{
-+ struct mac_device *mac_dev = fman_config_to_mac(config);
-+ struct memac_regs __iomem *regs = mac_dev->fman_mac->regs;
-+ u32 tmp = ioread32be(&regs->if_mode);
-+
-+ tmp &= ~(IF_MODE_MASK | IF_MODE_RGMII);
-+ tmp |= memac_if_mode(state->interface);
-+ if (phylink_autoneg_inband(mode))
-+ tmp |= IF_MODE_RGMII_AUTO;
-+ iowrite32be(tmp, &regs->if_mode);
-+}
-+
-+static void memac_link_up(struct phylink_config *config, struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ struct mac_device *mac_dev = fman_config_to_mac(config);
-+ struct fman_mac *memac = mac_dev->fman_mac;
-+ struct memac_regs __iomem *regs = memac->regs;
-+ u32 tmp = memac_if_mode(interface);
-+ u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
-+ FSL_FM_PAUSE_TIME_DISABLE;
-+
-+ memac_set_tx_pause_frames(memac, 0, pause_time, 0);
-+ memac_accept_rx_pause_frames(memac, rx_pause);
-+
-+ if (duplex == DUPLEX_HALF)
-+ tmp |= IF_MODE_HD;
-+
-+ switch (speed) {
-+ case SPEED_1000:
-+ tmp |= IF_MODE_RGMII_1000;
-+ break;
-+ case SPEED_100:
-+ tmp |= IF_MODE_RGMII_100;
-+ break;
-+ case SPEED_10:
-+ tmp |= IF_MODE_RGMII_10;
-+ break;
-+ }
-+ iowrite32be(tmp, &regs->if_mode);
-+
-+ /* TODO: EEE? */
-+
-+ if (speed == SPEED_10000) {
-+ if (memac->fm_rev_info.major == 6 &&
-+ memac->fm_rev_info.minor == 4)
-+ tmp = TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G;
-+ else
-+ tmp = TX_FIFO_SECTIONS_TX_AVAIL_10G;
-+ tmp |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G;
-+ } else {
-+ tmp = TX_FIFO_SECTIONS_TX_AVAIL_1G |
-+ TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G;
-+ }
-+ iowrite32be(tmp, &regs->tx_fifo_sections);
-+
-+ mac_dev->update_speed(mac_dev, speed);
-+
-+ tmp = ioread32be(&regs->command_config);
-+ tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
-+ iowrite32be(tmp, &regs->command_config);
-+}
-+
-+static void memac_link_down(struct phylink_config *config, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
-+ struct memac_regs __iomem *regs = memac->regs;
-+ u32 tmp;
-+
-+ /* TODO: graceful */
-+ tmp = ioread32be(&regs->command_config);
-+ tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
-+ iowrite32be(tmp, &regs->command_config);
-+}
-+
-+static const struct phylink_mac_ops memac_mac_ops = {
-+ .validate = memac_validate,
-+ .mac_select_pcs = memac_select_pcs,
-+ .mac_prepare = memac_prepare,
-+ .mac_config = memac_mac_config,
-+ .mac_link_up = memac_link_up,
-+ .mac_link_down = memac_link_down,
-+};
-+
- static int memac_modify_mac_address(struct fman_mac *memac,
- const enet_addr_t *enet_addr)
- {
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- add_addr_in_paddr(memac->regs, (const u8 *)(*enet_addr), 0);
-
- return 0;
-@@ -771,9 +800,6 @@ static int memac_add_hash_mac_address(st
- u32 hash;
- u64 addr;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- if (!(addr & GROUP_ADDRESS)) {
-@@ -802,9 +828,6 @@ static int memac_set_allmulti(struct fma
- u32 entry;
- struct memac_regs __iomem *regs = memac->regs;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- if (enable) {
- for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
- iowrite32be(entry | HASH_CTRL_MCAST_EN,
-@@ -834,9 +857,6 @@ static int memac_del_hash_mac_address(st
- u32 hash;
- u64 addr;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK;
-@@ -864,9 +884,6 @@ static int memac_set_exception(struct fm
- {
- u32 bit_mask = 0;
-
-- if (!is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- bit_mask = get_exception_flag(exception);
- if (bit_mask) {
- if (enable)
-@@ -886,23 +903,15 @@ static int memac_init(struct fman_mac *m
- {
- struct memac_cfg *memac_drv_param;
- enet_addr_t eth_addr;
-- bool slow_10g_if = false;
-- struct fixed_phy_status *fixed_link = NULL;
- int err;
- u32 reg32 = 0;
-
-- if (is_init_done(memac->memac_drv_param))
-- return -EINVAL;
--
- err = check_init_parameters(memac);
- if (err)
- return err;
-
- memac_drv_param = memac->memac_drv_param;
-
-- if (memac->fm_rev_info.major == 6 && memac->fm_rev_info.minor == 4)
-- slow_10g_if = true;
--
- /* First, reset the MAC if desired. */
- if (memac_drv_param->reset_on_init) {
- err = reset(memac->regs);
-@@ -918,10 +927,7 @@ static int memac_init(struct fman_mac *m
- add_addr_in_paddr(memac->regs, (const u8 *)eth_addr, 0);
- }
-
-- fixed_link = memac_drv_param->fixed_link;
--
-- init(memac->regs, memac->memac_drv_param, memac->phy_if,
-- memac->max_speed, slow_10g_if, memac->exceptions);
-+ init(memac->regs, memac->memac_drv_param, memac->exceptions);
-
- /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 errata workaround
- * Exists only in FMan 6.0 and 6.3.
-@@ -937,11 +943,6 @@ static int memac_init(struct fman_mac *m
- iowrite32be(reg32, &memac->regs->command_config);
- }
-
-- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII)
-- setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link);
-- else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII)
-- setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link);
--
- /* Max Frame Length */
- err = fman_set_mac_max_frame(memac->fm, memac->mac_id,
- memac_drv_param->max_frame_length);
-@@ -970,9 +971,6 @@ static int memac_init(struct fman_mac *m
- fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id,
- FMAN_INTR_TYPE_NORMAL, memac_exception, memac);
-
-- kfree(memac_drv_param);
-- memac->memac_drv_param = NULL;
--
- return 0;
- }
-
-@@ -995,7 +993,6 @@ static int memac_free(struct fman_mac *m
- pcs_put(memac->sgmii_pcs);
- pcs_put(memac->qsgmii_pcs);
- pcs_put(memac->xfi_pcs);
--
- kfree(memac->memac_drv_param);
- kfree(memac);
-
-@@ -1028,8 +1025,6 @@ static struct fman_mac *memac_config(str
- memac->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
-
- memac->regs = mac_dev->vaddr;
-- memac->max_speed = params->max_speed;
-- memac->phy_if = mac_dev->phy_if;
- memac->mac_id = params->mac_id;
- memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER |
- MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI);
-@@ -1037,7 +1032,6 @@ static struct fman_mac *memac_config(str
- memac->event_cb = params->event_cb;
- memac->dev_id = mac_dev;
- memac->fm = params->fm;
-- memac->basex_if = params->basex_if;
-
- /* Save FMan revision */
- fman_get_revision(memac->fm, &memac->fm_rev_info);
-@@ -1064,37 +1058,44 @@ static struct phylink_pcs *memac_pcs_cre
- return pcs;
- }
-
-+static bool memac_supports(struct mac_device *mac_dev, phy_interface_t iface)
-+{
-+ /* If there's no serdes device, assume that it's been configured for
-+ * whatever the default interface mode is.
-+ */
-+ if (!mac_dev->fman_mac->serdes)
-+ return mac_dev->phy_if == iface;
-+ /* Otherwise, ask the serdes */
-+ return !phy_validate(mac_dev->fman_mac->serdes, PHY_MODE_ETHERNET,
-+ iface, NULL);
-+}
-+
- int memac_initialization(struct mac_device *mac_dev,
- struct device_node *mac_node,
- struct fman_mac_params *params)
- {
- int err;
-+ struct device_node *fixed;
- struct phylink_pcs *pcs;
-- struct fixed_phy_status *fixed_link;
- struct fman_mac *memac;
-+ unsigned long capabilities;
-+ unsigned long *supported;
-
-+ mac_dev->phylink_ops = &memac_mac_ops;
- mac_dev->set_promisc = memac_set_promiscuous;
- mac_dev->change_addr = memac_modify_mac_address;
- mac_dev->add_hash_mac_addr = memac_add_hash_mac_address;
- mac_dev->remove_hash_mac_addr = memac_del_hash_mac_address;
-- mac_dev->set_tx_pause = memac_set_tx_pause_frames;
-- mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
- mac_dev->set_exception = memac_set_exception;
- mac_dev->set_allmulti = memac_set_allmulti;
- mac_dev->set_tstamp = memac_set_tstamp;
- mac_dev->set_multi = fman_set_multi;
-- mac_dev->adjust_link = adjust_link_memac;
- mac_dev->enable = memac_enable;
- mac_dev->disable = memac_disable;
-
-- if (params->max_speed == SPEED_10000)
-- mac_dev->phy_if = PHY_INTERFACE_MODE_XGMII;
--
- mac_dev->fman_mac = memac_config(mac_dev, params);
-- if (!mac_dev->fman_mac) {
-- err = -EINVAL;
-- goto _return;
-- }
-+ if (!mac_dev->fman_mac)
-+ return -EINVAL;
-
- memac = mac_dev->fman_mac;
- memac->memac_drv_param->max_frame_length = fman_get_max_frm();
-@@ -1136,9 +1137,9 @@ int memac_initialization(struct mac_devi
- else
- pcs = memac_pcs_create(mac_node, err);
-
-- if (!pcs) {
-- dev_err(mac_dev->dev, "missing pcs\n");
-- err = -ENOENT;
-+ if (IS_ERR(pcs)) {
-+ err = PTR_ERR(pcs);
-+ dev_err_probe(mac_dev->dev, err, "missing pcs\n");
- goto _return_fm_mac_free;
- }
-
-@@ -1159,84 +1160,100 @@ int memac_initialization(struct mac_devi
- } else if (IS_ERR(memac->serdes)) {
- dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
- goto _return_fm_mac_free;
-- } else {
-- err = phy_init(memac->serdes);
-- if (err) {
-- dev_err_probe(mac_dev->dev, err,
-- "could not initialize serdes\n");
-- goto _return_fm_mac_free;
-- }
--
-- err = phy_power_on(memac->serdes);
-- if (err) {
-- dev_err_probe(mac_dev->dev, err,
-- "could not power on serdes\n");
-- goto _return_phy_exit;
-- }
--
-- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
-- memac->phy_if == PHY_INTERFACE_MODE_1000BASEX ||
-- memac->phy_if == PHY_INTERFACE_MODE_2500BASEX ||
-- memac->phy_if == PHY_INTERFACE_MODE_QSGMII ||
-- memac->phy_if == PHY_INTERFACE_MODE_XGMII) {
-- err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
-- memac->phy_if);
-- if (err) {
-- dev_err_probe(mac_dev->dev, err,
-- "could not set serdes mode to %s\n",
-- phy_modes(memac->phy_if));
-- goto _return_phy_power_off;
-- }
-- }
- }
-
-- if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
-- struct phy_device *phy;
--
-- err = of_phy_register_fixed_link(mac_node);
-- if (err)
-- goto _return_phy_power_off;
--
-- fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
-- if (!fixed_link) {
-- err = -ENOMEM;
-- goto _return_phy_power_off;
-- }
-+ /* The internal connection to the serdes is XGMII, but this isn't
-+ * really correct for the phy mode (which is the external connection).
-+ * However, this is how all older device trees say that they want
-+ * 10GBASE-R (aka XFI), so just convert it for them.
-+ */
-+ if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
-+ mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
-
-- mac_dev->phy_node = of_node_get(mac_node);
-- phy = of_phy_find_device(mac_dev->phy_node);
-- if (!phy) {
-- err = -EINVAL;
-- of_node_put(mac_dev->phy_node);
-- goto _return_fixed_link_free;
-- }
-+ /* TODO: The following interface modes are supported by (some) hardware
-+ * but not by this driver:
-+ * - 1000BASE-KX
-+ * - 10GBASE-KR
-+ * - XAUI/HiGig
-+ */
-+ supported = mac_dev->phylink_config.supported_interfaces;
-
-- fixed_link->link = phy->link;
-- fixed_link->speed = phy->speed;
-- fixed_link->duplex = phy->duplex;
-- fixed_link->pause = phy->pause;
-- fixed_link->asym_pause = phy->asym_pause;
-+ /* Note that half duplex is only supported on 10/100M interfaces. */
-
-- put_device(&phy->mdio.dev);
-- memac->memac_drv_param->fixed_link = fixed_link;
-+ if (memac->sgmii_pcs &&
-+ (memac_supports(mac_dev, PHY_INTERFACE_MODE_SGMII) ||
-+ memac_supports(mac_dev, PHY_INTERFACE_MODE_1000BASEX))) {
-+ __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
-+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
-+ }
-+
-+ if (memac->sgmii_pcs &&
-+ memac_supports(mac_dev, PHY_INTERFACE_MODE_2500BASEX))
-+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
-+
-+ if (memac->qsgmii_pcs &&
-+ memac_supports(mac_dev, PHY_INTERFACE_MODE_QSGMII))
-+ __set_bit(PHY_INTERFACE_MODE_QSGMII, supported);
-+ else if (mac_dev->phy_if == PHY_INTERFACE_MODE_QSGMII)
-+ dev_warn(mac_dev->dev, "no QSGMII pcs specified\n");
-+
-+ if (memac->xfi_pcs &&
-+ memac_supports(mac_dev, PHY_INTERFACE_MODE_10GBASER)) {
-+ __set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
-+ } else {
-+ /* From what I can tell, no 10g macs support RGMII. */
-+ phy_interface_set_rgmii(supported);
-+ __set_bit(PHY_INTERFACE_MODE_MII, supported);
- }
-
-+ capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10 | MAC_100;
-+ capabilities |= MAC_1000FD | MAC_2500FD | MAC_10000FD;
-+
-+ /* These SoCs don't support half duplex at all; there's no different
-+ * FMan version or compatible, so we just have to check the machine
-+ * compatible instead
-+ */
-+ if (of_machine_is_compatible("fsl,ls1043a") ||
-+ of_machine_is_compatible("fsl,ls1046a") ||
-+ of_machine_is_compatible("fsl,B4QDS"))
-+ capabilities &= ~(MAC_10HD | MAC_100HD);
-+
-+ mac_dev->phylink_config.mac_capabilities = capabilities;
-+
-+ /* The T2080 and T4240 don't support half duplex RGMII. There is no
-+ * other way to identify these SoCs, so just use the machine
-+ * compatible.
-+ */
-+ if (of_machine_is_compatible("fsl,T2080QDS") ||
-+ of_machine_is_compatible("fsl,T2080RDB") ||
-+ of_machine_is_compatible("fsl,T2081QDS") ||
-+ of_machine_is_compatible("fsl,T4240QDS") ||
-+ of_machine_is_compatible("fsl,T4240RDB"))
-+ memac->rgmii_no_half_duplex = true;
-+
-+ /* Most boards should use MLO_AN_INBAND, but existing boards don't have
-+ * a managed property. Default to MLO_AN_INBAND if nothing else is
-+ * specified. We need to be careful and not enable this if we have a
-+ * fixed link or if we are using MII or RGMII, since those
-+ * configurations modes don't use in-band autonegotiation.
-+ */
-+ fixed = of_get_child_by_name(mac_node, "fixed-link");
-+ if (!fixed && !of_property_read_bool(mac_node, "fixed-link") &&
-+ !of_property_read_bool(mac_node, "managed") &&
-+ mac_dev->phy_if != PHY_INTERFACE_MODE_MII &&
-+ !phy_interface_mode_is_rgmii(mac_dev->phy_if))
-+ mac_dev->phylink_config.ovr_an_inband = true;
-+ of_node_put(fixed);
-+
- err = memac_init(mac_dev->fman_mac);
- if (err < 0)
-- goto _return_fixed_link_free;
-+ goto _return_fm_mac_free;
-
- dev_info(mac_dev->dev, "FMan MEMAC\n");
-
-- goto _return;
-+ return 0;
-
--_return_phy_power_off:
-- phy_power_off(memac->serdes);
--_return_phy_exit:
-- phy_exit(memac->serdes);
--_return_fixed_link_free:
-- kfree(fixed_link);
- _return_fm_mac_free:
- memac_free(mac_dev->fman_mac);
--_return:
- return err;
- }
---- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
-@@ -13,6 +13,7 @@
- #include <linux/bitrev.h>
- #include <linux/io.h>
- #include <linux/crc32.h>
-+#include <linux/netdevice.h>
-
- /* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
- #define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
-@@ -243,10 +244,6 @@ static int init(struct tgec_regs __iomem
-
- static int check_init_parameters(struct fman_mac *tgec)
- {
-- if (tgec->max_speed < SPEED_10000) {
-- pr_err("10G MAC driver only support 10G speed\n");
-- return -EINVAL;
-- }
- if (!tgec->exception_cb) {
- pr_err("uninitialized exception_cb\n");
- return -EINVAL;
-@@ -384,40 +381,13 @@ static void free_init_resources(struct f
- tgec->unicast_addr_hash = NULL;
- }
-
--static bool is_init_done(struct tgec_cfg *cfg)
--{
-- /* Checks if tGEC driver parameters were initialized */
-- if (!cfg)
-- return true;
--
-- return false;
--}
--
- static int tgec_enable(struct fman_mac *tgec)
- {
-- struct tgec_regs __iomem *regs = tgec->regs;
-- u32 tmp;
--
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
-- tmp = ioread32be(&regs->command_config);
-- tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
-- iowrite32be(tmp, &regs->command_config);
--
- return 0;
- }
-
- static void tgec_disable(struct fman_mac *tgec)
- {
-- struct tgec_regs __iomem *regs = tgec->regs;
-- u32 tmp;
--
-- WARN_ON_ONCE(!is_init_done(tgec->cfg));
--
-- tmp = ioread32be(&regs->command_config);
-- tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
-- iowrite32be(tmp, &regs->command_config);
- }
-
- static int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
-@@ -425,9 +395,6 @@ static int tgec_set_promiscuous(struct f
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 tmp;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- tmp = ioread32be(&regs->command_config);
- if (new_val)
- tmp |= CMD_CFG_PROMIS_EN;
-@@ -444,9 +411,6 @@ static int tgec_set_tx_pause_frames(stru
- {
- struct tgec_regs __iomem *regs = tgec->regs;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- iowrite32be((u32)pause_time, &regs->pause_quant);
-
- return 0;
-@@ -457,9 +421,6 @@ static int tgec_accept_rx_pause_frames(s
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 tmp;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- tmp = ioread32be(&regs->command_config);
- if (!en)
- tmp |= CMD_CFG_PAUSE_IGNORE;
-@@ -470,12 +431,53 @@ static int tgec_accept_rx_pause_frames(s
- return 0;
- }
-
-+static void tgec_mac_config(struct phylink_config *config, unsigned int mode,
-+ const struct phylink_link_state *state)
-+{
-+}
-+
-+static void tgec_link_up(struct phylink_config *config, struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ struct mac_device *mac_dev = fman_config_to_mac(config);
-+ struct fman_mac *tgec = mac_dev->fman_mac;
-+ struct tgec_regs __iomem *regs = tgec->regs;
-+ u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
-+ FSL_FM_PAUSE_TIME_DISABLE;
-+ u32 tmp;
-+
-+ tgec_set_tx_pause_frames(tgec, 0, pause_time, 0);
-+ tgec_accept_rx_pause_frames(tgec, rx_pause);
-+ mac_dev->update_speed(mac_dev, speed);
-+
-+ tmp = ioread32be(&regs->command_config);
-+ tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
-+ iowrite32be(tmp, &regs->command_config);
-+}
-+
-+static void tgec_link_down(struct phylink_config *config, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct fman_mac *tgec = fman_config_to_mac(config)->fman_mac;
-+ struct tgec_regs __iomem *regs = tgec->regs;
-+ u32 tmp;
-+
-+ tmp = ioread32be(&regs->command_config);
-+ tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
-+ iowrite32be(tmp, &regs->command_config);
-+}
-+
-+static const struct phylink_mac_ops tgec_mac_ops = {
-+ .validate = phylink_generic_validate,
-+ .mac_config = tgec_mac_config,
-+ .mac_link_up = tgec_link_up,
-+ .mac_link_down = tgec_link_down,
-+};
-+
- static int tgec_modify_mac_address(struct fman_mac *tgec,
- const enet_addr_t *p_enet_addr)
- {
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- tgec->addr = ENET_ADDR_TO_UINT64(*p_enet_addr);
- set_mac_address(tgec->regs, (const u8 *)(*p_enet_addr));
-
-@@ -490,9 +492,6 @@ static int tgec_add_hash_mac_address(str
- u32 crc = 0xFFFFFFFF, hash;
- u64 addr;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- if (!(addr & GROUP_ADDRESS)) {
-@@ -525,9 +524,6 @@ static int tgec_set_allmulti(struct fman
- u32 entry;
- struct tgec_regs __iomem *regs = tgec->regs;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- if (enable) {
- for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
- iowrite32be(entry | TGEC_HASH_MCAST_EN,
-@@ -548,9 +544,6 @@ static int tgec_set_tstamp(struct fman_m
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 tmp;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- tmp = ioread32be(&regs->command_config);
-
- if (enable)
-@@ -572,9 +565,6 @@ static int tgec_del_hash_mac_address(str
- u32 crc = 0xFFFFFFFF, hash;
- u64 addr;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- addr = ((*(u64 *)eth_addr) >> 16);
-
- /* CRC calculation */
-@@ -601,22 +591,12 @@ static int tgec_del_hash_mac_address(str
- return 0;
- }
-
--static void tgec_adjust_link(struct mac_device *mac_dev)
--{
-- struct phy_device *phy_dev = mac_dev->phy_dev;
--
-- mac_dev->update_speed(mac_dev, phy_dev->speed);
--}
--
- static int tgec_set_exception(struct fman_mac *tgec,
- enum fman_mac_exceptions exception, bool enable)
- {
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 bit_mask = 0;
-
-- if (!is_init_done(tgec->cfg))
-- return -EINVAL;
--
- bit_mask = get_exception_flag(exception);
- if (bit_mask) {
- if (enable)
-@@ -641,9 +621,6 @@ static int tgec_init(struct fman_mac *tg
- enet_addr_t eth_addr;
- int err;
-
-- if (is_init_done(tgec->cfg))
-- return -EINVAL;
--
- if (DEFAULT_RESET_ON_INIT &&
- (fman_reset_mac(tgec->fm, tgec->mac_id) != 0)) {
- pr_err("Can't reset MAC!\n");
-@@ -753,7 +730,6 @@ static struct fman_mac *tgec_config(stru
-
- tgec->regs = mac_dev->vaddr;
- tgec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
-- tgec->max_speed = params->max_speed;
- tgec->mac_id = params->mac_id;
- tgec->exceptions = (TGEC_IMASK_MDIO_SCAN_EVENT |
- TGEC_IMASK_REM_FAULT |
-@@ -788,17 +764,15 @@ int tgec_initialization(struct mac_devic
- int err;
- struct fman_mac *tgec;
-
-+ mac_dev->phylink_ops = &tgec_mac_ops;
- mac_dev->set_promisc = tgec_set_promiscuous;
- mac_dev->change_addr = tgec_modify_mac_address;
- mac_dev->add_hash_mac_addr = tgec_add_hash_mac_address;
- mac_dev->remove_hash_mac_addr = tgec_del_hash_mac_address;
-- mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
-- mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
- mac_dev->set_exception = tgec_set_exception;
- mac_dev->set_allmulti = tgec_set_allmulti;
- mac_dev->set_tstamp = tgec_set_tstamp;
- mac_dev->set_multi = fman_set_multi;
-- mac_dev->adjust_link = tgec_adjust_link;
- mac_dev->enable = tgec_enable;
- mac_dev->disable = tgec_disable;
-
-@@ -808,6 +782,19 @@ int tgec_initialization(struct mac_devic
- goto _return;
- }
-
-+ /* The internal connection to the serdes is XGMII, but this isn't
-+ * really correct for the phy mode (which is the external connection).
-+ * However, this is how all older device trees say that they want
-+ * XAUI, so just convert it for them.
-+ */
-+ if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
-+ mac_dev->phy_if = PHY_INTERFACE_MODE_XAUI;
-+
-+ __set_bit(PHY_INTERFACE_MODE_XAUI,
-+ mac_dev->phylink_config.supported_interfaces);
-+ mac_dev->phylink_config.mac_capabilities =
-+ MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10000FD;
-+
- tgec = mac_dev->fman_mac;
- tgec->cfg->max_frame_length = fman_get_max_frm();
- err = tgec_init(tgec);
---- a/drivers/net/ethernet/freescale/fman/mac.c
-+++ b/drivers/net/ethernet/freescale/fman/mac.c
-@@ -15,6 +15,7 @@
- #include <linux/phy.h>
- #include <linux/netdevice.h>
- #include <linux/phy_fixed.h>
-+#include <linux/phylink.h>
- #include <linux/etherdevice.h>
- #include <linux/libfdt_env.h>
-
-@@ -93,130 +94,8 @@ int fman_set_multi(struct net_device *ne
- return 0;
- }
-
--/**
-- * fman_set_mac_active_pause
-- * @mac_dev: A pointer to the MAC device
-- * @rx: Pause frame setting for RX
-- * @tx: Pause frame setting for TX
-- *
-- * Set the MAC RX/TX PAUSE frames settings
-- *
-- * Avoid redundant calls to FMD, if the MAC driver already contains the desired
-- * active PAUSE settings. Otherwise, the new active settings should be reflected
-- * in FMan.
-- *
-- * Return: 0 on success; Error code otherwise.
-- */
--int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
--{
-- struct fman_mac *fman_mac = mac_dev->fman_mac;
-- int err = 0;
--
-- if (rx != mac_dev->rx_pause_active) {
-- err = mac_dev->set_rx_pause(fman_mac, rx);
-- if (likely(err == 0))
-- mac_dev->rx_pause_active = rx;
-- }
--
-- if (tx != mac_dev->tx_pause_active) {
-- u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE :
-- FSL_FM_PAUSE_TIME_DISABLE);
--
-- err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0);
--
-- if (likely(err == 0))
-- mac_dev->tx_pause_active = tx;
-- }
--
-- return err;
--}
--EXPORT_SYMBOL(fman_set_mac_active_pause);
--
--/**
-- * fman_get_pause_cfg
-- * @mac_dev: A pointer to the MAC device
-- * @rx_pause: Return value for RX setting
-- * @tx_pause: Return value for TX setting
-- *
-- * Determine the MAC RX/TX PAUSE frames settings based on PHY
-- * autonegotiation or values set by eththool.
-- *
-- * Return: Pointer to FMan device.
-- */
--void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
-- bool *tx_pause)
--{
-- struct phy_device *phy_dev = mac_dev->phy_dev;
-- u16 lcl_adv, rmt_adv;
-- u8 flowctrl;
--
-- *rx_pause = *tx_pause = false;
--
-- if (!phy_dev->duplex)
-- return;
--
-- /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
-- * are those set by ethtool.
-- */
-- if (!mac_dev->autoneg_pause) {
-- *rx_pause = mac_dev->rx_pause_req;
-- *tx_pause = mac_dev->tx_pause_req;
-- return;
-- }
--
-- /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
-- * settings depend on the result of the link negotiation.
-- */
--
-- /* get local capabilities */
-- lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising);
--
-- /* get link partner capabilities */
-- rmt_adv = 0;
-- if (phy_dev->pause)
-- rmt_adv |= LPA_PAUSE_CAP;
-- if (phy_dev->asym_pause)
-- rmt_adv |= LPA_PAUSE_ASYM;
--
-- /* Calculate TX/RX settings based on local and peer advertised
-- * symmetric/asymmetric PAUSE capabilities.
-- */
-- flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
-- if (flowctrl & FLOW_CTRL_RX)
-- *rx_pause = true;
-- if (flowctrl & FLOW_CTRL_TX)
-- *tx_pause = true;
--}
--EXPORT_SYMBOL(fman_get_pause_cfg);
--
--#define DTSEC_SUPPORTED \
-- (SUPPORTED_10baseT_Half \
-- | SUPPORTED_10baseT_Full \
-- | SUPPORTED_100baseT_Half \
-- | SUPPORTED_100baseT_Full \
-- | SUPPORTED_Autoneg \
-- | SUPPORTED_Pause \
-- | SUPPORTED_Asym_Pause \
-- | SUPPORTED_FIBRE \
-- | SUPPORTED_MII)
--
- static DEFINE_MUTEX(eth_lock);
-
--static const u16 phy2speed[] = {
-- [PHY_INTERFACE_MODE_MII] = SPEED_100,
-- [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
-- [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
-- [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
-- [PHY_INTERFACE_MODE_RMII] = SPEED_100,
-- [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
-- [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
-- [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
-- [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
-- [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
-- [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
-- [PHY_INTERFACE_MODE_XGMII] = SPEED_10000
--};
--
- static struct platform_device *dpaa_eth_add_device(int fman_id,
- struct mac_device *mac_dev)
- {
-@@ -263,8 +142,8 @@ no_mem:
- }
-
- static const struct of_device_id mac_match[] = {
-- { .compatible = "fsl,fman-dtsec", .data = dtsec_initialization },
-- { .compatible = "fsl,fman-xgec", .data = tgec_initialization },
-+ { .compatible = "fsl,fman-dtsec", .data = dtsec_initialization },
-+ { .compatible = "fsl,fman-xgec", .data = tgec_initialization },
- { .compatible = "fsl,fman-memac", .data = memac_initialization },
- {}
- };
-@@ -295,6 +174,7 @@ static int mac_probe(struct platform_dev
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-+ platform_set_drvdata(_of_dev, mac_dev);
-
- /* Save private information */
- mac_dev->priv = priv;
-@@ -424,57 +304,21 @@ static int mac_probe(struct platform_dev
- }
- mac_dev->phy_if = phy_if;
-
-- priv->speed = phy2speed[mac_dev->phy_if];
-- params.max_speed = priv->speed;
-- mac_dev->if_support = DTSEC_SUPPORTED;
-- /* We don't support half-duplex in SGMII mode */
-- if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
-- mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
-- SUPPORTED_100baseT_Half);
--
-- /* Gigabit support (no half-duplex) */
-- if (params.max_speed == 1000)
-- mac_dev->if_support |= SUPPORTED_1000baseT_Full;
--
-- /* The 10G interface only supports one mode */
-- if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
-- mac_dev->if_support = SUPPORTED_10000baseT_Full;
--
-- /* Get the rest of the PHY information */
-- mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
--
-- params.basex_if = false;
- params.mac_id = priv->cell_index;
- params.fm = (void *)priv->fman;
- params.exception_cb = mac_exception;
- params.event_cb = mac_exception;
-
- err = init(mac_dev, mac_node, &params);
-- if (err < 0) {
-- dev_err(dev, "mac_dev->init() = %d\n", err);
-- of_node_put(mac_dev->phy_node);
-- return err;
-- }
--
-- /* pause frame autonegotiation enabled */
-- mac_dev->autoneg_pause = true;
--
-- /* By intializing the values to false, force FMD to enable PAUSE frames
-- * on RX and TX
-- */
-- mac_dev->rx_pause_req = true;
-- mac_dev->tx_pause_req = true;
-- mac_dev->rx_pause_active = false;
-- mac_dev->tx_pause_active = false;
-- err = fman_set_mac_active_pause(mac_dev, true, true);
- if (err < 0)
-- dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
-+ return err;
-
- if (!is_zero_ether_addr(mac_dev->addr))
- dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
-
- priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
- if (IS_ERR(priv->eth_dev)) {
-+ err = PTR_ERR(priv->eth_dev);
- dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
- priv->cell_index);
- priv->eth_dev = NULL;
---- a/drivers/net/ethernet/freescale/fman/mac.h
-+++ b/drivers/net/ethernet/freescale/fman/mac.h
-@@ -9,6 +9,7 @@
- #include <linux/device.h>
- #include <linux/if_ether.h>
- #include <linux/phy.h>
-+#include <linux/phylink.h>
- #include <linux/list.h>
-
- #include "fman_port.h"
-@@ -24,32 +25,22 @@ struct mac_device {
- struct resource *res;
- u8 addr[ETH_ALEN];
- struct fman_port *port[2];
-- u32 if_support;
-- struct phy_device *phy_dev;
-+ struct phylink *phylink;
-+ struct phylink_config phylink_config;
- phy_interface_t phy_if;
-- struct device_node *phy_node;
-- struct net_device *net_dev;
-
-- bool autoneg_pause;
-- bool rx_pause_req;
-- bool tx_pause_req;
-- bool rx_pause_active;
-- bool tx_pause_active;
- bool promisc;
- bool allmulti;
-
-+ const struct phylink_mac_ops *phylink_ops;
- int (*enable)(struct fman_mac *mac_dev);
- void (*disable)(struct fman_mac *mac_dev);
-- void (*adjust_link)(struct mac_device *mac_dev);
- int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
- int (*change_addr)(struct fman_mac *mac_dev, const enet_addr_t *enet_addr);
- int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
- int (*set_tstamp)(struct fman_mac *mac_dev, bool enable);
- int (*set_multi)(struct net_device *net_dev,
- struct mac_device *mac_dev);
-- int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
-- int (*set_tx_pause)(struct fman_mac *mac_dev, u8 priority,
-- u16 pause_time, u16 thresh_time);
- int (*set_exception)(struct fman_mac *mac_dev,
- enum fman_mac_exceptions exception, bool enable);
- int (*add_hash_mac_addr)(struct fman_mac *mac_dev,
-@@ -63,6 +54,12 @@ struct mac_device {
- struct mac_priv_s *priv;
- };
-
-+static inline struct mac_device
-+*fman_config_to_mac(struct phylink_config *config)
-+{
-+ return container_of(config, struct mac_device, phylink_config);
-+}
-+
- struct dpaa_eth_data {
- struct mac_device *mac_dev;
- int mac_hw_id;
diff --git a/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch b/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch
deleted file mode 100644
index 06c348b1cd..0000000000
--- a/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From bf4de031052fe7c5309e8956c342d4e5ce79038e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 17 Oct 2022 16:22:35 -0400
-Subject: [PATCH 04/21] net: phylink: provide phylink_validate_mask_caps()
- helper
-
-Provide a helper that restricts the link modes according to the
-phylink capabilities.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-[rebased on net-next/master and added documentation]
-Signed-off-by: Sean Anderson <sean.anderson@seco.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 41 +++++++++++++++++++++++++++------------
- include/linux/phylink.h | 3 +++
- 2 files changed, 32 insertions(+), 12 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -564,31 +564,48 @@ unsigned long phylink_get_capabilities(p
- EXPORT_SYMBOL_GPL(phylink_get_capabilities);
-
- /**
-- * phylink_generic_validate() - generic validate() callback implementation
-- * @config: a pointer to a &struct phylink_config.
-+ * phylink_validate_mask_caps() - Restrict link modes based on caps
- * @supported: ethtool bitmask for supported link modes.
-- * @state: a pointer to a &struct phylink_link_state.
-+ * @state: an (optional) pointer to a &struct phylink_link_state.
-+ * @mac_capabilities: bitmask of MAC capabilities
- *
-- * Generic implementation of the validate() callback that MAC drivers can
-- * use when they pass the range of supported interfaces and MAC capabilities.
-- * This makes use of phylink_get_linkmodes().
-+ * Calculate the supported link modes based on @mac_capabilities, and restrict
-+ * @supported and @state based on that. Use this function if your capabiliies
-+ * aren't constant, such as if they vary depending on the interface.
- */
--void phylink_generic_validate(struct phylink_config *config,
-- unsigned long *supported,
-- struct phylink_link_state *state)
-+void phylink_validate_mask_caps(unsigned long *supported,
-+ struct phylink_link_state *state,
-+ unsigned long mac_capabilities)
- {
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
- unsigned long caps;
-
- phylink_set_port_modes(mask);
- phylink_set(mask, Autoneg);
-- caps = phylink_get_capabilities(state->interface,
-- config->mac_capabilities,
-+ caps = phylink_get_capabilities(state->interface, mac_capabilities,
- state->rate_matching);
- phylink_caps_to_linkmodes(mask, caps);
-
- linkmode_and(supported, supported, mask);
-- linkmode_and(state->advertising, state->advertising, mask);
-+ if (state)
-+ linkmode_and(state->advertising, state->advertising, mask);
-+}
-+EXPORT_SYMBOL_GPL(phylink_validate_mask_caps);
-+
-+/**
-+ * phylink_generic_validate() - generic validate() callback implementation
-+ * @config: a pointer to a &struct phylink_config.
-+ * @supported: ethtool bitmask for supported link modes.
-+ * @state: a pointer to a &struct phylink_link_state.
-+ *
-+ * Generic implementation of the validate() callback that MAC drivers can
-+ * use when they pass the range of supported interfaces and MAC capabilities.
-+ */
-+void phylink_generic_validate(struct phylink_config *config,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ phylink_validate_mask_caps(supported, state, config->mac_capabilities);
- }
- EXPORT_SYMBOL_GPL(phylink_generic_validate);
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -558,6 +558,9 @@ void phylink_caps_to_linkmodes(unsigned
- unsigned long phylink_get_capabilities(phy_interface_t interface,
- unsigned long mac_capabilities,
- int rate_matching);
-+void phylink_validate_mask_caps(unsigned long *supported,
-+ struct phylink_link_state *state,
-+ unsigned long caps);
- void phylink_generic_validate(struct phylink_config *config,
- unsigned long *supported,
- struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch b/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch
deleted file mode 100644
index e3a1dda688..0000000000
--- a/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 2bf7e4a68c42eed909f3c29582e1fb85cb157e35 Mon Sep 17 00:00:00 2001
-From: Jakub Kicinski <kuba@kernel.org>
-Date: Tue, 25 Oct 2022 11:51:26 -0700
-Subject: [PATCH 05/21] phylink: require valid state argument to
- phylink_validate_mask_caps()
-
-state is deferenced earlier in the function, the NULL check
-is pointless. Since we don't have any crash reports presumably
-it's safe to assume state is not NULL.
-
-Fixes: f392a1846489 ("net: phylink: provide phylink_validate_mask_caps() helper")
-Reviewed-by: Sean Anderson <sean.anderson@seco.com>
-Link: https://lore.kernel.org/r/20221025185126.1720553-1-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -566,7 +566,7 @@ EXPORT_SYMBOL_GPL(phylink_get_capabiliti
- /**
- * phylink_validate_mask_caps() - Restrict link modes based on caps
- * @supported: ethtool bitmask for supported link modes.
-- * @state: an (optional) pointer to a &struct phylink_link_state.
-+ * @state: pointer to a &struct phylink_link_state.
- * @mac_capabilities: bitmask of MAC capabilities
- *
- * Calculate the supported link modes based on @mac_capabilities, and restrict
-@@ -587,8 +587,7 @@ void phylink_validate_mask_caps(unsigned
- phylink_caps_to_linkmodes(mask, caps);
-
- linkmode_and(supported, supported, mask);
-- if (state)
-- linkmode_and(state->advertising, state->advertising, mask);
-+ linkmode_and(state->advertising, state->advertising, mask);
- }
- EXPORT_SYMBOL_GPL(phylink_validate_mask_caps);
-
diff --git a/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch b/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch
deleted file mode 100644
index c217ed87b5..0000000000
--- a/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f8fc363bf0c023e4736a0328174b4a24b44ab23a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:37 +0100
-Subject: [PATCH 06/21] net: phylink: add phylink_get_link_timer_ns() helper
-
-Add a helper to convert the PHY interface mode to the required link
-timer setting as stated by the appropriate standard. Inappropriate
-interface modes return an error.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/linux/phylink.h | 24 ++++++++++++++++++++++++
- 1 file changed, 24 insertions(+)
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -617,6 +617,30 @@ int phylink_speed_up(struct phylink *pl)
-
- void phylink_set_port_modes(unsigned long *bits);
-
-+/**
-+ * phylink_get_link_timer_ns - return the PCS link timer value
-+ * @interface: link &typedef phy_interface_t mode
-+ *
-+ * Return the PCS link timer setting in nanoseconds for the PHY @interface
-+ * mode, or -EINVAL if not appropriate.
-+ */
-+static inline int phylink_get_link_timer_ns(phy_interface_t interface)
-+{
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ return 1600000;
-+
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ return 10000000;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
- void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
- u16 bmsr, u16 lpa);
- void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
diff --git a/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch b/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch
deleted file mode 100644
index 31fde5f18e..0000000000
--- a/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-From b45b773a96b0e9e8d51e5d005485f4e376d6ce9a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 4 Nov 2022 17:13:01 +0000
-Subject: [PATCH 07/21] net: remove explicit phylink_generic_validate()
- references
-
-Virtually all conventional network drivers are now converted to use
-phylink_generic_validate() - only DSA drivers and fman_memac remain,
-so lets remove the necessity for network drivers to explicitly set
-this member, and default to phylink_generic_validate() when unset.
-This is possible as .validate must currently be set.
-
-Any remaining instances that have not been addressed by this patch can
-be fixed up later.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Link: https://lore.kernel.org/r/E1or0FZ-001tRa-DI@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/altera/altera_tse_main.c | 1 -
- drivers/net/ethernet/atheros/ag71xx.c | 1 -
- drivers/net/ethernet/cadence/macb_main.c | 1 -
- drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 1 -
- drivers/net/ethernet/freescale/enetc/enetc_pf.c | 1 -
- drivers/net/ethernet/freescale/fman/fman_dtsec.c | 1 -
- drivers/net/ethernet/freescale/fman/fman_tgec.c | 1 -
- drivers/net/ethernet/marvell/mvneta.c | 1 -
- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 -
- drivers/net/ethernet/marvell/prestera/prestera_main.c | 1 -
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 -
- drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c | 1 -
- drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 1 -
- drivers/net/ethernet/mscc/ocelot_net.c | 1 -
- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 -
- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 1 -
- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1 -
- drivers/net/phy/phylink.c | 5 ++++-
- drivers/net/usb/asix_devices.c | 1 -
- include/linux/phylink.h | 5 +++++
- 20 files changed, 9 insertions(+), 19 deletions(-)
-
---- a/drivers/net/ethernet/altera/altera_tse_main.c
-+++ b/drivers/net/ethernet/altera/altera_tse_main.c
-@@ -1096,7 +1096,6 @@ static struct phylink_pcs *alt_tse_selec
- }
-
- static const struct phylink_mac_ops alt_tse_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_an_restart = alt_tse_mac_an_restart,
- .mac_config = alt_tse_mac_config,
- .mac_link_down = alt_tse_mac_link_down,
---- a/drivers/net/ethernet/atheros/ag71xx.c
-+++ b/drivers/net/ethernet/atheros/ag71xx.c
-@@ -1086,7 +1086,6 @@ static void ag71xx_mac_link_up(struct ph
- }
-
- static const struct phylink_mac_ops ag71xx_phylink_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_config = ag71xx_mac_config,
- .mac_link_down = ag71xx_mac_link_down,
- .mac_link_up = ag71xx_mac_link_up,
---- a/drivers/net/ethernet/cadence/macb_main.c
-+++ b/drivers/net/ethernet/cadence/macb_main.c
-@@ -752,7 +752,6 @@ static struct phylink_pcs *macb_mac_sele
- }
-
- static const struct phylink_mac_ops macb_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = macb_mac_select_pcs,
- .mac_config = macb_mac_config,
- .mac_link_down = macb_mac_link_down,
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-@@ -235,7 +235,6 @@ static void dpaa2_mac_link_down(struct p
- }
-
- static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = dpaa2_mac_select_pcs,
- .mac_config = dpaa2_mac_config,
- .mac_link_up = dpaa2_mac_link_up,
---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
-+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
-@@ -1111,7 +1111,6 @@ static void enetc_pl_mac_link_down(struc
- }
-
- static const struct phylink_mac_ops enetc_mac_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = enetc_pl_mac_select_pcs,
- .mac_config = enetc_pl_mac_config,
- .mac_link_up = enetc_pl_mac_link_up,
---- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
-@@ -986,7 +986,6 @@ static void dtsec_link_down(struct phyli
- }
-
- static const struct phylink_mac_ops dtsec_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = dtsec_select_pcs,
- .mac_config = dtsec_mac_config,
- .mac_link_up = dtsec_link_up,
---- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
-@@ -469,7 +469,6 @@ static void tgec_link_down(struct phylin
- }
-
- static const struct phylink_mac_ops tgec_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_config = tgec_mac_config,
- .mac_link_up = tgec_link_up,
- .mac_link_down = tgec_link_down,
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -4228,7 +4228,6 @@ static void mvneta_mac_link_up(struct ph
- }
-
- static const struct phylink_mac_ops mvneta_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = mvneta_mac_select_pcs,
- .mac_prepare = mvneta_mac_prepare,
- .mac_config = mvneta_mac_config,
---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-@@ -6633,7 +6633,6 @@ static void mvpp2_mac_link_down(struct p
- }
-
- static const struct phylink_mac_ops mvpp2_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = mvpp2_select_pcs,
- .mac_prepare = mvpp2_mac_prepare,
- .mac_config = mvpp2_mac_config,
---- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
-+++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
-@@ -360,7 +360,6 @@ static void prestera_pcs_an_restart(stru
- }
-
- static const struct phylink_mac_ops prestera_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = prestera_mac_select_pcs,
- .mac_config = prestera_mac_config,
- .mac_link_down = prestera_mac_link_down,
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -653,7 +653,6 @@ static void mtk_mac_link_up(struct phyli
- }
-
- static const struct phylink_mac_ops mtk_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = mtk_mac_select_pcs,
- .mac_pcs_get_state = mtk_mac_pcs_get_state,
- .mac_config = mtk_mac_config,
---- a/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c
-+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c
-@@ -125,7 +125,6 @@ static void lan966x_pcs_aneg_restart(str
- }
-
- const struct phylink_mac_ops lan966x_phylink_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = lan966x_phylink_mac_select,
- .mac_config = lan966x_phylink_mac_config,
- .mac_prepare = lan966x_phylink_mac_prepare,
---- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
-+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
-@@ -138,7 +138,6 @@ const struct phylink_pcs_ops sparx5_phyl
- };
-
- const struct phylink_mac_ops sparx5_phylink_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = sparx5_phylink_mac_select_pcs,
- .mac_config = sparx5_phylink_mac_config,
- .mac_link_down = sparx5_phylink_mac_link_down,
---- a/drivers/net/ethernet/mscc/ocelot_net.c
-+++ b/drivers/net/ethernet/mscc/ocelot_net.c
-@@ -1737,7 +1737,6 @@ static void vsc7514_phylink_mac_link_up(
- }
-
- static const struct phylink_mac_ops ocelot_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_config = vsc7514_phylink_mac_config,
- .mac_link_down = vsc7514_phylink_mac_link_down,
- .mac_link_up = vsc7514_phylink_mac_link_up,
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -1090,7 +1090,6 @@ static void stmmac_mac_link_up(struct ph
- }
-
- static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = stmmac_mac_select_pcs,
- .mac_config = stmmac_mac_config,
- .mac_link_down = stmmac_mac_link_down,
---- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
-+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
-@@ -1493,7 +1493,6 @@ static void am65_cpsw_nuss_mac_link_up(s
- }
-
- static const struct phylink_mac_ops am65_cpsw_phylink_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_config = am65_cpsw_nuss_mac_config,
- .mac_link_down = am65_cpsw_nuss_mac_link_down,
- .mac_link_up = am65_cpsw_nuss_mac_link_up,
---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-@@ -1736,7 +1736,6 @@ static void axienet_mac_link_up(struct p
- }
-
- static const struct phylink_mac_ops axienet_phylink_ops = {
-- .validate = phylink_generic_validate,
- .mac_select_pcs = axienet_mac_select_pcs,
- .mac_config = axienet_mac_config,
- .mac_link_down = axienet_mac_link_down,
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -651,7 +651,10 @@ static int phylink_validate_mac_and_pcs(
- }
-
- /* Then validate the link parameters with the MAC */
-- pl->mac_ops->validate(pl->config, supported, state);
-+ if (pl->mac_ops->validate)
-+ pl->mac_ops->validate(pl->config, supported, state);
-+ else
-+ phylink_generic_validate(pl->config, supported, state);
-
- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
- }
---- a/drivers/net/usb/asix_devices.c
-+++ b/drivers/net/usb/asix_devices.c
-@@ -787,7 +787,6 @@ static void ax88772_mac_link_up(struct p
- }
-
- static const struct phylink_mac_ops ax88772_phylink_mac_ops = {
-- .validate = phylink_generic_validate,
- .mac_config = ax88772_mac_config,
- .mac_link_down = ax88772_mac_link_down,
- .mac_link_up = ax88772_mac_link_up,
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -207,6 +207,11 @@ struct phylink_mac_ops {
- *
- * If the @state->interface mode is not supported, then the @supported
- * mask must be cleared.
-+ *
-+ * This member is optional; if not set, the generic validator will be
-+ * used making use of @config->mac_capabilities and
-+ * @config->supported_interfaces to determine which link modes are
-+ * supported.
- */
- void validate(struct phylink_config *config, unsigned long *supported,
- struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch b/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch
deleted file mode 100644
index 37d82b2cd7..0000000000
--- a/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From a90ac762d345890b40d88a1385a34a2449c2d75e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Mar 2023 09:23:42 +0000
-Subject: [PATCH] net: sfp: make sfp_bus_find_fwnode() take a const fwnode
-
-sfp_bus_find_fwnode() does not write to the fwnode, so let's make it
-const.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/sfp-bus.c | 2 +-
- include/linux/sfp.h | 5 +++--
- 2 files changed, 4 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -603,7 +603,7 @@ static void sfp_upstream_clear(struct sf
- * - %-ENOMEM if we failed to allocate the bus.
- * - an error from the upstream's connect_phy() method.
- */
--struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
-+struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
- {
- struct fwnode_reference_args ref;
- struct sfp_bus *bus;
---- a/include/linux/sfp.h
-+++ b/include/linux/sfp.h
-@@ -548,7 +548,7 @@ int sfp_get_module_eeprom_by_page(struct
- void sfp_upstream_start(struct sfp_bus *bus);
- void sfp_upstream_stop(struct sfp_bus *bus);
- void sfp_bus_put(struct sfp_bus *bus);
--struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode);
-+struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
- int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
- const struct sfp_upstream_ops *ops);
- void sfp_bus_del_upstream(struct sfp_bus *bus);
-@@ -610,7 +610,8 @@ static inline void sfp_bus_put(struct sf
- {
- }
-
--static inline struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
-+static inline struct sfp_bus *
-+sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
- {
- return NULL;
- }
diff --git a/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch b/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch
deleted file mode 100644
index 290cb8d161..0000000000
--- a/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From ecec0ebbc6381a5a375f1cf10c4858f24e91e2ef Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 15 Mar 2023 14:46:49 +0000
-Subject: [PATCH] net: pcs: lynx: don't print an_enabled in pcs_get_state()
-
-an_enabled will be going away, and in any case, pcs_get_state() should
-not be updating this member. Remove the print.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/pcs/pcs-lynx.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/pcs/pcs-lynx.c
-+++ b/drivers/net/pcs/pcs-lynx.c
-@@ -115,11 +115,11 @@ static void lynx_pcs_get_state(struct ph
- }
-
- dev_dbg(&lynx->mdio->dev,
-- "mode=%s/%s/%s link=%u an_enabled=%u an_complete=%u\n",
-+ "mode=%s/%s/%s link=%u an_complete=%u\n",
- phy_modes(state->interface),
- phy_speed_to_str(state->speed),
- phy_duplex_to_str(state->duplex),
-- state->link, state->an_enabled, state->an_complete);
-+ state->link, state->an_complete);
- }
-
- static int lynx_pcs_config_giga(struct mdio_device *pcs, unsigned int mode,
diff --git a/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch b/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch
deleted file mode 100644
index 38ea265476..0000000000
--- a/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 99d0f3a1095f4c938b1665025c29411edafe8a01 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 21 Mar 2023 15:58:44 +0000
-Subject: [PATCH] net: dpaa2-mac: use Autoneg bit rather than an_enabled
-
-The Autoneg bit in the advertising bitmap and state->an_enabled are
-always identical. Thus, we will be removing state->an_enabled.
-
-Use the Autoneg bit in the advertising bitmap to indicate whether
-autonegotiation should be used, rather than using the an_enabled
-member which will be going away. This means we use the same condition
-as phylink_mii_c22_pcs_config().
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
-@@ -158,7 +158,8 @@ static void dpaa2_mac_config(struct phyl
- struct dpmac_link_state *dpmac_state = &mac->state;
- int err;
-
-- if (state->an_enabled)
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ state->advertising))
- dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
- else
- dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG;
diff --git a/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch b/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch
deleted file mode 100644
index cb9c411cfb..0000000000
--- a/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 471c40bde606ec0b1ce8c616f7998739c7a783a6 Mon Sep 17 00:00:00 2001
-From: Ivan Bornyakov <i.bornyakov@metrotek.ru>
-Date: Fri, 10 Feb 2023 18:46:27 +0300
-Subject: [PATCH 10/21] net: phylink: support validated pause and autoneg in
- fixed-link
-
-In fixed-link setup phylink_parse_fixedlink() unconditionally sets
-Pause, Asym_Pause and Autoneg bits to "supported" bitmap, while MAC may
-not support these.
-
-This leads to ethtool reporting:
-
- > Supported pause frame use: Symmetric Receive-only
- > Supports auto-negotiation: Yes
-
-regardless of what is actually supported.
-
-Instead of unconditionally set Pause, Asym_Pause and Autoneg it is
-sensible to set them according to validated "supported" bitmap, i.e. the
-result of phylink_validate().
-
-Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 17 ++++++++++++++---
- 1 file changed, 14 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -709,6 +709,7 @@ static int phylink_parse_fixedlink(struc
- struct fwnode_handle *fwnode)
- {
- struct fwnode_handle *fixed_node;
-+ bool pause, asym_pause, autoneg;
- const struct phy_setting *s;
- struct gpio_desc *desc;
- u32 speed;
-@@ -781,13 +782,23 @@ static int phylink_parse_fixedlink(struc
- linkmode_copy(pl->link_config.advertising, pl->supported);
- phylink_validate(pl, pl->supported, &pl->link_config);
-
-+ pause = phylink_test(pl->supported, Pause);
-+ asym_pause = phylink_test(pl->supported, Asym_Pause);
-+ autoneg = phylink_test(pl->supported, Autoneg);
- s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex,
- pl->supported, true);
- linkmode_zero(pl->supported);
- phylink_set(pl->supported, MII);
-- phylink_set(pl->supported, Pause);
-- phylink_set(pl->supported, Asym_Pause);
-- phylink_set(pl->supported, Autoneg);
-+
-+ if (pause)
-+ phylink_set(pl->supported, Pause);
-+
-+ if (asym_pause)
-+ phylink_set(pl->supported, Asym_Pause);
-+
-+ if (autoneg)
-+ phylink_set(pl->supported, Autoneg);
-+
- if (s) {
- __set_bit(s->bit, pl->supported);
- __set_bit(s->bit, pl->link_config.lp_advertising);
diff --git a/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch b/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch
deleted file mode 100644
index 03b4f9d0c4..0000000000
--- a/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-From 7211ffd70941933a7825a56cf480f07ee81c321c Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 21 Mar 2023 15:58:54 +0000
-Subject: [PATCH 11/21] net: phylink: remove an_enabled
-
-The Autoneg bit in the advertising bitmap and state->an_enabled are
-always identical. state->an_enabled is now no longer used by any
-drivers, so lets kill this duplication.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 37 +++++++++++++++++--------------------
- include/linux/phylink.h | 2 --
- 2 files changed, 17 insertions(+), 22 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -841,7 +841,6 @@ static int phylink_parse_mode(struct phy
- phylink_set(pl->supported, Autoneg);
- phylink_set(pl->supported, Asym_Pause);
- phylink_set(pl->supported, Pause);
-- pl->link_config.an_enabled = true;
- pl->cfg_link_an_mode = MLO_AN_INBAND;
-
- switch (pl->link_config.interface) {
-@@ -944,9 +943,6 @@ static int phylink_parse_mode(struct phy
- "failed to validate link configuration for in-band status\n");
- return -EINVAL;
- }
--
-- /* Check if MAC/PCS also supports Autoneg. */
-- pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg);
- }
-
- return 0;
-@@ -956,7 +952,8 @@ static void phylink_apply_manual_flow(st
- struct phylink_link_state *state)
- {
- /* If autoneg is disabled, pause AN is also disabled */
-- if (!state->an_enabled)
-+ if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ state->advertising))
- state->pause &= ~MLO_PAUSE_AN;
-
- /* Manual configuration of pause modes */
-@@ -996,21 +993,22 @@ static void phylink_mac_config(struct ph
- const struct phylink_link_state *state)
- {
- phylink_dbg(pl,
-- "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
-+ "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u\n",
- __func__, phylink_an_mode_str(pl->cur_link_an_mode),
- phy_modes(state->interface),
- phy_speed_to_str(state->speed),
- phy_duplex_to_str(state->duplex),
- phy_rate_matching_to_str(state->rate_matching),
- __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
-- state->pause, state->link, state->an_enabled);
-+ state->pause, state->link);
-
- pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state);
- }
-
- static void phylink_mac_pcs_an_restart(struct phylink *pl)
- {
-- if (pl->link_config.an_enabled &&
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ pl->link_config.advertising) &&
- phy_interface_mode_is_8023z(pl->link_config.interface) &&
- phylink_autoneg_inband(pl->cur_link_an_mode)) {
- if (pl->pcs)
-@@ -1137,9 +1135,9 @@ static void phylink_mac_pcs_get_state(st
- linkmode_copy(state->advertising, pl->link_config.advertising);
- linkmode_zero(state->lp_advertising);
- state->interface = pl->link_config.interface;
-- state->an_enabled = pl->link_config.an_enabled;
- state->rate_matching = pl->link_config.rate_matching;
-- if (state->an_enabled) {
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ state->advertising)) {
- state->speed = SPEED_UNKNOWN;
- state->duplex = DUPLEX_UNKNOWN;
- state->pause = MLO_PAUSE_NONE;
-@@ -1531,7 +1529,6 @@ struct phylink *phylink_create(struct ph
- pl->link_config.pause = MLO_PAUSE_AN;
- pl->link_config.speed = SPEED_UNKNOWN;
- pl->link_config.duplex = DUPLEX_UNKNOWN;
-- pl->link_config.an_enabled = true;
- pl->mac_ops = mac_ops;
- __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
- timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
-@@ -2155,8 +2152,9 @@ static void phylink_get_ksettings(const
- kset->base.speed = state->speed;
- kset->base.duplex = state->duplex;
- }
-- kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE :
-- AUTONEG_DISABLE;
-+ kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ state->advertising) ?
-+ AUTONEG_ENABLE : AUTONEG_DISABLE;
- }
-
- /**
-@@ -2303,9 +2301,8 @@ int phylink_ethtool_ksettings_set(struct
- /* We have ruled out the case with a PHY attached, and the
- * fixed-link cases. All that is left are in-band links.
- */
-- config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE;
- linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising,
-- config.an_enabled);
-+ kset->base.autoneg == AUTONEG_ENABLE);
-
- /* If this link is with an SFP, ensure that changes to advertised modes
- * also cause the associated interface to be selected such that the
-@@ -2339,13 +2336,14 @@ int phylink_ethtool_ksettings_set(struct
- }
-
- /* If autonegotiation is enabled, we must have an advertisement */
-- if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ config.advertising) &&
-+ phylink_is_empty_linkmode(config.advertising))
- return -EINVAL;
-
- mutex_lock(&pl->state_mutex);
- pl->link_config.speed = config.speed;
- pl->link_config.duplex = config.duplex;
-- pl->link_config.an_enabled = config.an_enabled;
-
- if (pl->link_config.interface != config.interface) {
- /* The interface changed, e.g. 1000base-X <-> 2500base-X */
-@@ -2951,7 +2949,6 @@ static int phylink_sfp_config_phy(struct
- config.speed = SPEED_UNKNOWN;
- config.duplex = DUPLEX_UNKNOWN;
- config.pause = MLO_PAUSE_AN;
-- config.an_enabled = pl->link_config.an_enabled;
-
- /* Ignore errors if we're expecting a PHY to attach later */
- ret = phylink_validate(pl, support, &config);
-@@ -3020,7 +3017,6 @@ static int phylink_sfp_config_optical(st
- config.speed = SPEED_UNKNOWN;
- config.duplex = DUPLEX_UNKNOWN;
- config.pause = MLO_PAUSE_AN;
-- config.an_enabled = true;
-
- /* For all the interfaces that are supported, reduce the sfp_support
- * mask to only those link modes that can be supported.
-@@ -3354,7 +3350,8 @@ void phylink_mii_c22_pcs_decode_state(st
- /* If there is no link or autonegotiation is disabled, the LP advertisement
- * data is not meaningful, so don't go any further.
- */
-- if (!state->link || !state->an_enabled)
-+ if (!state->link || !linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ state->advertising))
- return;
-
- switch (state->interface) {
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -93,7 +93,6 @@ static inline bool phylink_autoneg_inban
- * the medium link mode (@speed and @duplex) and the speed/duplex of the phy
- * interface mode (@interface) are different.
- * @link: true if the link is up.
-- * @an_enabled: true if autonegotiation is enabled/desired.
- * @an_complete: true if autonegotiation has completed.
- */
- struct phylink_link_state {
-@@ -105,7 +104,6 @@ struct phylink_link_state {
- int pause;
- int rate_matching;
- unsigned int link:1;
-- unsigned int an_enabled:1;
- unsigned int an_complete:1;
- };
-
diff --git a/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch b/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch
deleted file mode 100644
index c06a367b8b..0000000000
--- a/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From a3555d1f5c208f0a63eafee77381f68d304a0512 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 12 May 2023 17:58:37 +0100
-Subject: [PATCH 12/21] net: phylink: constify fwnode arguments
-
-Both phylink_create() and phylink_fwnode_phy_connect() do not modify
-the fwnode argument that they are passed, so lets constify these.
-
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 11 ++++++-----
- include/linux/phylink.h | 9 +++++----
- 2 files changed, 11 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -706,7 +706,7 @@ static int phylink_validate(struct phyli
- }
-
- static int phylink_parse_fixedlink(struct phylink *pl,
-- struct fwnode_handle *fwnode)
-+ const struct fwnode_handle *fwnode)
- {
- struct fwnode_handle *fixed_node;
- bool pause, asym_pause, autoneg;
-@@ -817,7 +817,8 @@ static int phylink_parse_fixedlink(struc
- return 0;
- }
-
--static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
-+static int phylink_parse_mode(struct phylink *pl,
-+ const struct fwnode_handle *fwnode)
- {
- struct fwnode_handle *dn;
- const char *managed;
-@@ -1440,7 +1441,7 @@ static void phylink_fixed_poll(struct ti
- static const struct sfp_upstream_ops sfp_phylink_ops;
-
- static int phylink_register_sfp(struct phylink *pl,
-- struct fwnode_handle *fwnode)
-+ const struct fwnode_handle *fwnode)
- {
- struct sfp_bus *bus;
- int ret;
-@@ -1479,7 +1480,7 @@ static int phylink_register_sfp(struct p
- * must use IS_ERR() to check for errors from this function.
- */
- struct phylink *phylink_create(struct phylink_config *config,
-- struct fwnode_handle *fwnode,
-+ const struct fwnode_handle *fwnode,
- phy_interface_t iface,
- const struct phylink_mac_ops *mac_ops)
- {
-@@ -1809,7 +1810,7 @@ EXPORT_SYMBOL_GPL(phylink_of_phy_connect
- * Returns 0 on success or a negative errno.
- */
- int phylink_fwnode_phy_connect(struct phylink *pl,
-- struct fwnode_handle *fwnode,
-+ const struct fwnode_handle *fwnode,
- u32 flags)
- {
- struct fwnode_handle *phy_fwnode;
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -568,16 +568,17 @@ void phylink_generic_validate(struct phy
- unsigned long *supported,
- struct phylink_link_state *state);
-
--struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
-- phy_interface_t iface,
-- const struct phylink_mac_ops *mac_ops);
-+struct phylink *phylink_create(struct phylink_config *,
-+ const struct fwnode_handle *,
-+ phy_interface_t,
-+ const struct phylink_mac_ops *);
- void phylink_destroy(struct phylink *);
- bool phylink_expects_phy(struct phylink *pl);
-
- int phylink_connect_phy(struct phylink *, struct phy_device *);
- int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags);
- int phylink_fwnode_phy_connect(struct phylink *pl,
-- struct fwnode_handle *fwnode,
-+ const struct fwnode_handle *fwnode,
- u32 flags);
- void phylink_disconnect_phy(struct phylink *);
-
diff --git a/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch b/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch
deleted file mode 100644
index 2649634dc7..0000000000
--- a/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 4a0faa02d419a6728abef0f1d8a32d8c35ef95e6 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Mar 2023 09:23:53 +0000
-Subject: [PATCH] net: phy: constify fwnode_get_phy_node() fwnode argument
-
-fwnode_get_phy_node() does not motify the fwnode structure, so make
-the argument const,
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy_device.c | 2 +-
- include/linux/phy.h | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3003,7 +3003,7 @@ EXPORT_SYMBOL_GPL(device_phy_find_device
- * and "phy-device" are not supported in ACPI. DT supports all the three
- * named references to the phy node.
- */
--struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode)
-+struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode)
- {
- struct fwnode_handle *phy_node;
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1473,7 +1473,7 @@ int fwnode_get_phy_id(struct fwnode_hand
- struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode);
- struct phy_device *fwnode_phy_find_device(struct fwnode_handle *phy_fwnode);
- struct phy_device *device_phy_find_device(struct device *dev);
--struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode);
-+struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode);
- struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45);
- int phy_device_register(struct phy_device *phy);
- void phy_device_free(struct phy_device *phydev);
diff --git a/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch b/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch
deleted file mode 100644
index 5eba18b026..0000000000
--- a/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From cc73de0411f7d3cdd157564a78f7a39058420ff8 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sat, 13 May 2023 22:03:45 +0100
-Subject: [PATCH 13/21] net: phylink: fix ksettings_set() ethtool call
-
-While testing a Fiberstore SFP-10G-T module (which uses 10GBASE-R with
-rate adaption) in a Clearfog platform (which can't do that) it was
-found that the PHYs advertisement was not limited according to the
-hosts capabilities when using ethtool to change it.
-
-Fix this by ensuring that we mask the advertisement with the computed
-support mask as the very first thing we do.
-
-Fixes: cbc1bb1e4689 ("net: phylink: simplify phy case for ksettings_set method")
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -2226,6 +2226,10 @@ int phylink_ethtool_ksettings_set(struct
-
- ASSERT_RTNL();
-
-+ /* Mask out unsupported advertisements */
-+ linkmode_and(config.advertising, kset->link_modes.advertising,
-+ pl->supported);
-+
- if (pl->phydev) {
- /* We can rely on phylib for this update; we also do not need
- * to update the pl->link_config settings:
-@@ -2250,10 +2254,6 @@ int phylink_ethtool_ksettings_set(struct
-
- config = pl->link_config;
-
-- /* Mask out unsupported advertisements */
-- linkmode_and(config.advertising, kset->link_modes.advertising,
-- pl->supported);
--
- /* FIXME: should we reject autoneg if phy/mac does not support it? */
- switch (kset->base.autoneg) {
- case AUTONEG_DISABLE:
diff --git a/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch b/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch
deleted file mode 100644
index f9670539fc..0000000000
--- a/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From 0100d1c5789018ba77bf2f4fab3bd91ecece7b3b Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 17 May 2023 11:38:12 +0100
-Subject: [PATCH 14/21] net: sfp: add support for setting signalling rate
-
-Add support to the SFP layer to allow phylink to set the signalling
-rate for a SFP module. The rate given will be in units of kilo-baud
-(1000 baud).
-
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 24 ++++++++++++++++++++++++
- drivers/net/phy/sfp-bus.c | 20 ++++++++++++++++++++
- drivers/net/phy/sfp.c | 5 +++++
- drivers/net/phy/sfp.h | 1 +
- include/linux/sfp.h | 6 ++++++
- 5 files changed, 56 insertions(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -156,6 +156,23 @@ static const char *phylink_an_mode_str(u
- return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
- }
-
-+static unsigned int phylink_interface_signal_rate(phy_interface_t interface)
-+{
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_1000BASEX: /* 1.25Mbd */
-+ return 1250;
-+ case PHY_INTERFACE_MODE_2500BASEX: /* 3.125Mbd */
-+ return 3125;
-+ case PHY_INTERFACE_MODE_5GBASER: /* 5.15625Mbd */
-+ return 5156;
-+ case PHY_INTERFACE_MODE_10GBASER: /* 10.3125Mbd */
-+ return 10313;
-+ default:
-+ return 0;
-+ }
-+}
-+
- /**
- * phylink_interface_max_speed() - get the maximum speed of a phy interface
- * @interface: phy interface mode defined by &typedef phy_interface_t
-@@ -1024,6 +1041,7 @@ static void phylink_major_config(struct
- {
- struct phylink_pcs *pcs = NULL;
- bool pcs_changed = false;
-+ unsigned int rate_kbd;
- int err;
-
- phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
-@@ -1083,6 +1101,12 @@ static void phylink_major_config(struct
- ERR_PTR(err));
- }
-
-+ if (pl->sfp_bus) {
-+ rate_kbd = phylink_interface_signal_rate(state->interface);
-+ if (rate_kbd)
-+ sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd);
-+ }
-+
- phylink_pcs_poll_start(pl);
- }
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -586,6 +586,26 @@ static void sfp_upstream_clear(struct sf
- }
-
- /**
-+ * sfp_upstream_set_signal_rate() - set data signalling rate
-+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
-+ * @rate_kbd: signalling rate in units of 1000 baud
-+ *
-+ * Configure the rate select settings on the SFP module for the signalling
-+ * rate (not the same as the data rate).
-+ *
-+ * Locks that may be held:
-+ * Phylink's state_mutex
-+ * rtnl lock
-+ * SFP's sm_mutex
-+ */
-+void sfp_upstream_set_signal_rate(struct sfp_bus *bus, unsigned int rate_kbd)
-+{
-+ if (bus->registered)
-+ bus->socket_ops->set_signal_rate(bus->sfp, rate_kbd);
-+}
-+EXPORT_SYMBOL_GPL(sfp_upstream_set_signal_rate);
-+
-+/**
- * sfp_bus_find_fwnode() - parse and locate the SFP bus from fwnode
- * @fwnode: firmware node for the parent device (MAC or PHY)
- *
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -2473,6 +2473,10 @@ static void sfp_stop(struct sfp *sfp)
- sfp_sm_event(sfp, SFP_E_DEV_DOWN);
- }
-
-+static void sfp_set_signal_rate(struct sfp *sfp, unsigned int rate_kbd)
-+{
-+}
-+
- static int sfp_module_info(struct sfp *sfp, struct ethtool_modinfo *modinfo)
- {
- /* locking... and check module is present */
-@@ -2551,6 +2555,7 @@ static const struct sfp_socket_ops sfp_m
- .detach = sfp_detach,
- .start = sfp_start,
- .stop = sfp_stop,
-+ .set_signal_rate = sfp_set_signal_rate,
- .module_info = sfp_module_info,
- .module_eeprom = sfp_module_eeprom,
- .module_eeprom_by_page = sfp_module_eeprom_by_page,
---- a/drivers/net/phy/sfp.h
-+++ b/drivers/net/phy/sfp.h
-@@ -19,6 +19,7 @@ struct sfp_socket_ops {
- void (*detach)(struct sfp *sfp);
- void (*start)(struct sfp *sfp);
- void (*stop)(struct sfp *sfp);
-+ void (*set_signal_rate)(struct sfp *sfp, unsigned int rate_kbd);
- int (*module_info)(struct sfp *sfp, struct ethtool_modinfo *modinfo);
- int (*module_eeprom)(struct sfp *sfp, struct ethtool_eeprom *ee,
- u8 *data);
---- a/include/linux/sfp.h
-+++ b/include/linux/sfp.h
-@@ -547,6 +547,7 @@ int sfp_get_module_eeprom_by_page(struct
- struct netlink_ext_ack *extack);
- void sfp_upstream_start(struct sfp_bus *bus);
- void sfp_upstream_stop(struct sfp_bus *bus);
-+void sfp_upstream_set_signal_rate(struct sfp_bus *bus, unsigned int rate_kbd);
- void sfp_bus_put(struct sfp_bus *bus);
- struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
- int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
-@@ -606,6 +607,11 @@ static inline void sfp_upstream_stop(str
- {
- }
-
-+static inline void sfp_upstream_set_signal_rate(struct sfp_bus *bus,
-+ unsigned int rate_kbd)
-+{
-+}
-+
- static inline void sfp_bus_put(struct sfp_bus *bus)
- {
- }
diff --git a/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch b/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch
deleted file mode 100644
index 8a694c86da..0000000000
--- a/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From b84acdb07222a701bfc6403b374249c86f97d18d Mon Sep 17 00:00:00 2001
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Fri, 19 May 2023 14:03:59 +0100
-Subject: [PATCH 15/21] net: phy: add helpers for comparing phy IDs
-
-There are several places which open code comparing PHY IDs. Provide a
-couple of helpers to assist with this, using a slightly simpler test
-than the original:
-
-- phy_id_compare() compares two arbitary PHY IDs and a mask of the
- significant bits in the ID.
-- phydev_id_compare() compares the bound phydev with the specified
- PHY ID, using the bound driver's mask.
-
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/micrel.c | 6 +++---
- drivers/net/phy/phy_device.c | 16 +++++++---------
- drivers/net/phy/phylink.c | 4 ++--
- include/linux/phy.h | 28 ++++++++++++++++++++++++++++
- 4 files changed, 40 insertions(+), 14 deletions(-)
-
---- a/drivers/net/phy/micrel.c
-+++ b/drivers/net/phy/micrel.c
-@@ -620,7 +620,7 @@ static int ksz8051_ksz8795_match_phy_dev
- {
- int ret;
-
-- if ((phydev->phy_id & MICREL_PHY_ID_MASK) != PHY_ID_KSZ8051)
-+ if (!phy_id_compare(phydev->phy_id, PHY_ID_KSZ8051, MICREL_PHY_ID_MASK))
- return 0;
-
- ret = phy_read(phydev, MII_BMSR);
-@@ -1455,7 +1455,7 @@ static int ksz9x31_cable_test_fault_leng
- *
- * distance to fault = (VCT_DATA - 22) * 4 / cable propagation velocity
- */
-- if ((phydev->phy_id & MICREL_PHY_ID_MASK) == PHY_ID_KSZ9131)
-+ if (phydev_id_compare(phydev, PHY_ID_KSZ9131))
- dt = clamp(dt - 22, 0, 255);
-
- return (dt * 400) / 10;
-@@ -1887,7 +1887,7 @@ static __always_inline int ksz886x_cable
- */
- dt = FIELD_GET(data_mask, status);
-
-- if ((phydev->phy_id & MICREL_PHY_ID_MASK) == PHY_ID_LAN8814)
-+ if (phydev_id_compare(phydev, PHY_ID_LAN8814))
- return ((dt - 22) * 800) / 10;
- else
- return (dt * 400) / 10;
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -422,8 +422,7 @@ int phy_unregister_fixup(const char *bus
- fixup = list_entry(pos, struct phy_fixup, list);
-
- if ((!strcmp(fixup->bus_id, bus_id)) &&
-- ((fixup->phy_uid & phy_uid_mask) ==
-- (phy_uid & phy_uid_mask))) {
-+ phy_id_compare(fixup->phy_uid, phy_uid, phy_uid_mask)) {
- list_del(&fixup->list);
- kfree(fixup);
- ret = 0;
-@@ -459,8 +458,8 @@ static int phy_needs_fixup(struct phy_de
- if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)
- return 0;
-
-- if ((fixup->phy_uid & fixup->phy_uid_mask) !=
-- (phydev->phy_id & fixup->phy_uid_mask))
-+ if (!phy_id_compare(phydev->phy_id, fixup->phy_uid,
-+ fixup->phy_uid_mask))
- if (fixup->phy_uid != PHY_ANY_UID)
- return 0;
-
-@@ -507,15 +506,14 @@ static int phy_bus_match(struct device *
- if (phydev->c45_ids.device_ids[i] == 0xffffffff)
- continue;
-
-- if ((phydrv->phy_id & phydrv->phy_id_mask) ==
-- (phydev->c45_ids.device_ids[i] &
-- phydrv->phy_id_mask))
-+ if (phy_id_compare(phydev->c45_ids.device_ids[i],
-+ phydrv->phy_id, phydrv->phy_id_mask))
- return 1;
- }
- return 0;
- } else {
-- return (phydrv->phy_id & phydrv->phy_id_mask) ==
-- (phydev->phy_id & phydrv->phy_id_mask);
-+ return phy_id_compare(phydev->phy_id, phydrv->phy_id,
-+ phydrv->phy_id_mask);
- }
- }
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -3151,8 +3151,8 @@ static void phylink_sfp_link_up(void *up
- */
- static bool phylink_phy_no_inband(struct phy_device *phy)
- {
-- return phy->is_c45 &&
-- (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150;
-+ return phy->is_c45 && phy_id_compare(phy->c45_ids.device_ids[1],
-+ 0xae025150, 0xfffffff0);
- }
-
- static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -993,6 +993,34 @@ struct phy_driver {
- #define PHY_ID_MATCH_MODEL(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 4)
- #define PHY_ID_MATCH_VENDOR(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 10)
-
-+/**
-+ * phy_id_compare - compare @id1 with @id2 taking account of @mask
-+ * @id1: first PHY ID
-+ * @id2: second PHY ID
-+ * @mask: the PHY ID mask, set bits are significant in matching
-+ *
-+ * Return true if the bits from @id1 and @id2 specified by @mask match.
-+ * This uses an equivalent test to (@id & @mask) == (@phy_id & @mask).
-+ */
-+static inline bool phy_id_compare(u32 id1, u32 id2, u32 mask)
-+{
-+ return !((id1 ^ id2) & mask);
-+}
-+
-+/**
-+ * phydev_id_compare - compare @id with the PHY's Clause 22 ID
-+ * @phydev: the PHY device
-+ * @id: the PHY ID to be matched
-+ *
-+ * Compare the @phydev clause 22 ID with the provided @id and return true or
-+ * false depending whether it matches, using the bound driver mask. The
-+ * @phydev must be bound to a driver.
-+ */
-+static inline bool phydev_id_compare(struct phy_device *phydev, u32 id)
-+{
-+ return phy_id_compare(id, phydev->phy_id, phydev->drv->phy_id_mask);
-+}
-+
- /* A Structure for boards to register fixups with the PHY Lib */
- struct phy_fixup {
- struct list_head list;
diff --git a/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch b/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch
deleted file mode 100644
index 5970355a6c..0000000000
--- a/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 441e1e44301fc5762a06737f8ec04bf1ce3fb039 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sat, 20 May 2023 11:41:42 +0100
-Subject: [PATCH 16/21] net: phylink: require supported_interfaces to be filled
-
-We have been requiring the supported_interfaces bitmap to be filled in
-by MAC drivers that have a mac_select_pcs() method. Now that all MAC
-drivers fill in the supported_interfaces bitmap, it is time to enforce
-this. We have already required supported_interfaces to be set in order
-for optical SFPs to be configured in commit f81fa96d8a6c ("net: phylink:
-use phy_interface_t bitmaps for optical modules").
-
-Refuse phylink creation if supported_interfaces is empty, and remove
-code to deal with cases where this mask is empty.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/E1q0K1u-006EIP-ET@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 26 +++++++++++---------------
- 1 file changed, 11 insertions(+), 15 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -710,14 +710,11 @@ static int phylink_validate(struct phyli
- {
- const unsigned long *interfaces = pl->config->supported_interfaces;
-
-- if (!phy_interface_empty(interfaces)) {
-- if (state->interface == PHY_INTERFACE_MODE_NA)
-- return phylink_validate_mask(pl, supported, state,
-- interfaces);
-+ if (state->interface == PHY_INTERFACE_MODE_NA)
-+ return phylink_validate_mask(pl, supported, state, interfaces);
-
-- if (!test_bit(state->interface, interfaces))
-- return -EINVAL;
-- }
-+ if (!test_bit(state->interface, interfaces))
-+ return -EINVAL;
-
- return phylink_validate_mac_and_pcs(pl, supported, state);
- }
-@@ -1512,19 +1509,18 @@ struct phylink *phylink_create(struct ph
- struct phylink *pl;
- int ret;
-
-- if (mac_ops->mac_select_pcs &&
-- mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) !=
-- ERR_PTR(-EOPNOTSUPP))
-- using_mac_select_pcs = true;
--
- /* Validate the supplied configuration */
-- if (using_mac_select_pcs &&
-- phy_interface_empty(config->supported_interfaces)) {
-+ if (phy_interface_empty(config->supported_interfaces)) {
- dev_err(config->dev,
-- "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n");
-+ "phylink: error: empty supported_interfaces\n");
- return ERR_PTR(-EINVAL);
- }
-
-+ if (mac_ops->mac_select_pcs &&
-+ mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) !=
-+ ERR_PTR(-EOPNOTSUPP))
-+ using_mac_select_pcs = true;
-+
- pl = kzalloc(sizeof(*pl), GFP_KERNEL);
- if (!pl)
- return ERR_PTR(-ENOMEM);
diff --git a/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch b/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch
deleted file mode 100644
index 3a26b4b600..0000000000
--- a/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 4b624a39f2ab523ca6a6ad9448fab1deb7b101e2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 23 May 2023 11:15:53 +0100
-Subject: [PATCH 17/21] net: phylink: remove duplicated linkmode pause
- resolution
-
-Phylink had two chunks of code virtually the same for resolving the
-negotiated pause modes. Factor this down to one function.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 15 ++++-----------
- 1 file changed, 4 insertions(+), 11 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -976,11 +976,10 @@ static void phylink_apply_manual_flow(st
- state->pause = pl->link_config.pause;
- }
-
--static void phylink_resolve_flow(struct phylink_link_state *state)
-+static void phylink_resolve_an_pause(struct phylink_link_state *state)
- {
- bool tx_pause, rx_pause;
-
-- state->pause = MLO_PAUSE_NONE;
- if (state->duplex == DUPLEX_FULL) {
- linkmode_resolve_pause(state->advertising,
- state->lp_advertising,
-@@ -1192,7 +1191,8 @@ static void phylink_get_fixed_state(stru
- else if (pl->link_gpio)
- state->link = !!gpiod_get_value_cansleep(pl->link_gpio);
-
-- phylink_resolve_flow(state);
-+ state->pause = MLO_PAUSE_NONE;
-+ phylink_resolve_an_pause(state);
- }
-
- static void phylink_mac_initial_config(struct phylink *pl, bool force_restart)
-@@ -3215,7 +3215,6 @@ static const struct sfp_upstream_ops sfp
- static void phylink_decode_c37_word(struct phylink_link_state *state,
- uint16_t config_reg, int speed)
- {
-- bool tx_pause, rx_pause;
- int fd_bit;
-
- if (speed == SPEED_2500)
-@@ -3234,13 +3233,7 @@ static void phylink_decode_c37_word(stru
- state->link = false;
- }
-
-- linkmode_resolve_pause(state->advertising, state->lp_advertising,
-- &tx_pause, &rx_pause);
--
-- if (tx_pause)
-- state->pause |= MLO_PAUSE_TX;
-- if (rx_pause)
-- state->pause |= MLO_PAUSE_RX;
-+ phylink_resolve_an_pause(state);
- }
-
- static void phylink_decode_sgmii_word(struct phylink_link_state *state,
diff --git a/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch b/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch
deleted file mode 100644
index 2b2634f80c..0000000000
--- a/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From aa8b6bd2b1f235b262bd27f317a0516f196c2c6a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 23 May 2023 11:15:58 +0100
-Subject: [PATCH 18/21] net: phylink: add function to resolve clause 73
- negotiation
-
-Add a function to resolve clause 73 negotiation according to the
-priority resolution function described in clause 73.3.6.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 39 +++++++++++++++++++++++++++++++++++++++
- include/linux/phylink.h | 2 ++
- 2 files changed, 41 insertions(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -3212,6 +3212,45 @@ static const struct sfp_upstream_ops sfp
-
- /* Helpers for MAC drivers */
-
-+static struct {
-+ int bit;
-+ int speed;
-+} phylink_c73_priority_resolution[] = {
-+ { ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, SPEED_100000 },
-+ { ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, SPEED_100000 },
-+ /* 100GBASE-KP4 and 100GBASE-CR10 not supported */
-+ { ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, SPEED_40000 },
-+ { ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, SPEED_40000 },
-+ { ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, SPEED_10000 },
-+ { ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, SPEED_10000 },
-+ /* 5GBASE-KR not supported */
-+ { ETHTOOL_LINK_MODE_2500baseX_Full_BIT, SPEED_2500 },
-+ { ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, SPEED_1000 },
-+};
-+
-+void phylink_resolve_c73(struct phylink_link_state *state)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(phylink_c73_priority_resolution); i++) {
-+ int bit = phylink_c73_priority_resolution[i].bit;
-+ if (linkmode_test_bit(bit, state->advertising) &&
-+ linkmode_test_bit(bit, state->lp_advertising))
-+ break;
-+ }
-+
-+ if (i < ARRAY_SIZE(phylink_c73_priority_resolution)) {
-+ state->speed = phylink_c73_priority_resolution[i].speed;
-+ state->duplex = DUPLEX_FULL;
-+ } else {
-+ /* negotiation failure */
-+ state->link = false;
-+ }
-+
-+ phylink_resolve_an_pause(state);
-+}
-+EXPORT_SYMBOL_GPL(phylink_resolve_c73);
-+
- static void phylink_decode_c37_word(struct phylink_link_state *state,
- uint16_t config_reg, int speed)
- {
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -656,6 +656,8 @@ int phylink_mii_c22_pcs_config(struct md
- const unsigned long *advertising);
- void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs);
-
-+void phylink_resolve_c73(struct phylink_link_state *state);
-+
- void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs,
- struct phylink_link_state *state);
-
diff --git a/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch b/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch
deleted file mode 100644
index eea99a5d78..0000000000
--- a/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 796d709363135a6bd6a8ccc07b509c939e5b855f Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 23 May 2023 16:31:50 +0100
-Subject: [PATCH 19/21] net: phylink: provide phylink_pcs_config() and
- phylink_pcs_link_up()
-
-Add two helper functions for calling PCS methods. phylink_pcs_config()
-allows us to handle PCS configuration specifics in one location, rather
-than the two call sites. phylink_pcs_link_up() gives us consistency.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://lore.kernel.org/r/E1q1TzK-007Exd-Rs@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 53 ++++++++++++++++++++++++---------------
- 1 file changed, 33 insertions(+), 20 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -991,6 +991,25 @@ static void phylink_resolve_an_pause(str
- }
- }
-
-+static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+ const struct phylink_link_state *state,
-+ bool permit_pause_to_mac)
-+{
-+ if (!pcs)
-+ return 0;
-+
-+ return pcs->ops->pcs_config(pcs, mode, state->interface,
-+ state->advertising, permit_pause_to_mac);
-+}
-+
-+static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface, int speed,
-+ int duplex)
-+{
-+ if (pcs && pcs->ops->pcs_link_up)
-+ pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
-+}
-+
- static void phylink_pcs_poll_stop(struct phylink *pl)
- {
- if (pl->cfg_link_an_mode == MLO_AN_INBAND)
-@@ -1074,18 +1093,15 @@ static void phylink_major_config(struct
-
- phylink_mac_config(pl, state);
-
-- if (pl->pcs) {
-- err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
-- state->interface,
-- state->advertising,
-- !!(pl->link_config.pause &
-- MLO_PAUSE_AN));
-- if (err < 0)
-- phylink_err(pl, "pcs_config failed: %pe\n",
-- ERR_PTR(err));
-- if (err > 0)
-- restart = true;
-- }
-+ err = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, state,
-+ !!(pl->link_config.pause &
-+ MLO_PAUSE_AN));
-+ if (err < 0)
-+ phylink_err(pl, "pcs_config failed: %pe\n",
-+ ERR_PTR(err));
-+ else if (err > 0)
-+ restart = true;
-+
- if (restart)
- phylink_mac_pcs_an_restart(pl);
-
-@@ -1136,11 +1152,9 @@ static int phylink_change_inband_advert(
- * restart negotiation if the pcs_config() helper indicates that
- * the programmed advertisement has changed.
- */
-- ret = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
-- pl->link_config.interface,
-- pl->link_config.advertising,
-- !!(pl->link_config.pause &
-- MLO_PAUSE_AN));
-+ ret = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode,
-+ &pl->link_config,
-+ !!(pl->link_config.pause & MLO_PAUSE_AN));
- if (ret < 0)
- return ret;
-
-@@ -1272,9 +1286,8 @@ static void phylink_link_up(struct phyli
-
- pl->cur_interface = link_state.interface;
-
-- if (pl->pcs && pl->pcs->ops->pcs_link_up)
-- pl->pcs->ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode,
-- pl->cur_interface, speed, duplex);
-+ phylink_pcs_link_up(pl->pcs, pl->cur_link_an_mode, pl->cur_interface,
-+ speed, duplex);
-
- pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
- pl->cur_interface, speed, duplex,
diff --git a/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch b/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch
deleted file mode 100644
index 2f7f7a5737..0000000000
--- a/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 11933aa76865621d8e82553c8f3bc07796a5aaa2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 1 Jun 2023 10:12:06 +0100
-Subject: [PATCH 20/21] net: phylink: actually fix ksettings_set() ethtool call
-
-Raju Lakkaraju reported that the below commit caused a regression
-with Lan743x drivers and a 2.5G SFP. Sadly, this is because the commit
-was utterly wrong. Let's fix this properly by not moving the
-linkmode_and(), but instead copying the link ksettings and then
-modifying the advertising mask before passing the modified link
-ksettings to phylib.
-
-Fixes: df0acdc59b09 ("net: phylink: fix ksettings_set() ethtool call")
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://lore.kernel.org/r/E1q4eLm-00Ayxk-GZ@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -2259,11 +2259,13 @@ int phylink_ethtool_ksettings_set(struct
-
- ASSERT_RTNL();
-
-- /* Mask out unsupported advertisements */
-- linkmode_and(config.advertising, kset->link_modes.advertising,
-- pl->supported);
--
- if (pl->phydev) {
-+ struct ethtool_link_ksettings phy_kset = *kset;
-+
-+ linkmode_and(phy_kset.link_modes.advertising,
-+ phy_kset.link_modes.advertising,
-+ pl->supported);
-+
- /* We can rely on phylib for this update; we also do not need
- * to update the pl->link_config settings:
- * - the configuration returned via ksettings_get() will come
-@@ -2282,10 +2284,13 @@ int phylink_ethtool_ksettings_set(struct
- * the presence of a PHY, this should not be changed as that
- * should be determined from the media side advertisement.
- */
-- return phy_ethtool_ksettings_set(pl->phydev, kset);
-+ return phy_ethtool_ksettings_set(pl->phydev, &phy_kset);
- }
-
- config = pl->link_config;
-+ /* Mask out unsupported advertisements */
-+ linkmode_and(config.advertising, kset->link_modes.advertising,
-+ pl->supported);
-
- /* FIXME: should we reject autoneg if phy/mac does not support it? */
- switch (kset->base.autoneg) {
diff --git a/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch b/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch
deleted file mode 100644
index e1a8539aae..0000000000
--- a/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch
+++ /dev/null
@@ -1,324 +0,0 @@
-From 79b07c3e9c4a2272927be8848c26b372516e1958 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 16 Jun 2023 13:06:22 +0100
-Subject: [PATCH 21/21] net: phylink: add PCS negotiation mode
-
-PCS have to work out whether they should enable PCS negotiation by
-looking at the "mode" and "interface" arguments, and the Autoneg bit
-in the advertising mask.
-
-This leads to some complex logic, so lets pull that out into phylink
-and instead pass a "neg_mode" argument to the PCS configuration and
-link up methods, instead of the "mode" argument.
-
-In order to transition drivers, add a "neg_mode" flag to the phylink
-PCS structure to PCS can indicate whether they want to be passed the
-neg_mode or the old mode argument.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://lore.kernel.org/r/E1qA8De-00EaFA-Ht@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 45 +++++++++++++----
- include/linux/phylink.h | 104 +++++++++++++++++++++++++++++++++++---
- 2 files changed, 132 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -71,6 +71,7 @@ struct phylink {
- struct mutex state_mutex;
- struct phylink_link_state phy_state;
- struct work_struct resolve;
-+ unsigned int pcs_neg_mode;
-
- bool mac_link_dropped;
- bool using_mac_select_pcs;
-@@ -991,23 +992,23 @@ static void phylink_resolve_an_pause(str
- }
- }
-
--static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
- const struct phylink_link_state *state,
- bool permit_pause_to_mac)
- {
- if (!pcs)
- return 0;
-
-- return pcs->ops->pcs_config(pcs, mode, state->interface,
-+ return pcs->ops->pcs_config(pcs, neg_mode, state->interface,
- state->advertising, permit_pause_to_mac);
- }
-
--static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface, int speed,
- int duplex)
- {
- if (pcs && pcs->ops->pcs_link_up)
-- pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
-+ pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex);
- }
-
- static void phylink_pcs_poll_stop(struct phylink *pl)
-@@ -1057,10 +1058,15 @@ static void phylink_major_config(struct
- struct phylink_pcs *pcs = NULL;
- bool pcs_changed = false;
- unsigned int rate_kbd;
-+ unsigned int neg_mode;
- int err;
-
- phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
-
-+ pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
-+ state->interface,
-+ state->advertising);
-+
- if (pl->using_mac_select_pcs) {
- pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
- if (IS_ERR(pcs)) {
-@@ -1093,9 +1099,12 @@ static void phylink_major_config(struct
-
- phylink_mac_config(pl, state);
-
-- err = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, state,
-- !!(pl->link_config.pause &
-- MLO_PAUSE_AN));
-+ neg_mode = pl->cur_link_an_mode;
-+ if (pl->pcs && pl->pcs->neg_mode)
-+ neg_mode = pl->pcs_neg_mode;
-+
-+ err = phylink_pcs_config(pl->pcs, neg_mode, state,
-+ !!(pl->link_config.pause & MLO_PAUSE_AN));
- if (err < 0)
- phylink_err(pl, "pcs_config failed: %pe\n",
- ERR_PTR(err));
-@@ -1130,6 +1139,7 @@ static void phylink_major_config(struct
- */
- static int phylink_change_inband_advert(struct phylink *pl)
- {
-+ unsigned int neg_mode;
- int ret;
-
- if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
-@@ -1148,12 +1158,20 @@ static int phylink_change_inband_advert(
- __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
- pl->link_config.pause);
-
-+ /* Recompute the PCS neg mode */
-+ pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
-+ pl->link_config.interface,
-+ pl->link_config.advertising);
-+
-+ neg_mode = pl->cur_link_an_mode;
-+ if (pl->pcs->neg_mode)
-+ neg_mode = pl->pcs_neg_mode;
-+
- /* Modern PCS-based method; update the advert at the PCS, and
- * restart negotiation if the pcs_config() helper indicates that
- * the programmed advertisement has changed.
- */
-- ret = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode,
-- &pl->link_config,
-+ ret = phylink_pcs_config(pl->pcs, neg_mode, &pl->link_config,
- !!(pl->link_config.pause & MLO_PAUSE_AN));
- if (ret < 0)
- return ret;
-@@ -1256,6 +1274,7 @@ static void phylink_link_up(struct phyli
- struct phylink_link_state link_state)
- {
- struct net_device *ndev = pl->netdev;
-+ unsigned int neg_mode;
- int speed, duplex;
- bool rx_pause;
-
-@@ -1286,8 +1305,12 @@ static void phylink_link_up(struct phyli
-
- pl->cur_interface = link_state.interface;
-
-- phylink_pcs_link_up(pl->pcs, pl->cur_link_an_mode, pl->cur_interface,
-- speed, duplex);
-+ neg_mode = pl->cur_link_an_mode;
-+ if (pl->pcs && pl->pcs->neg_mode)
-+ neg_mode = pl->pcs_neg_mode;
-+
-+ phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed,
-+ duplex);
-
- pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
- pl->cur_interface, speed, duplex,
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -21,6 +21,24 @@ enum {
- MLO_AN_FIXED, /* Fixed-link mode */
- MLO_AN_INBAND, /* In-band protocol */
-
-+ /* PCS "negotiation" mode.
-+ * PHYLINK_PCS_NEG_NONE - protocol has no inband capability
-+ * PHYLINK_PCS_NEG_OUTBAND - some out of band or fixed link setting
-+ * PHYLINK_PCS_NEG_INBAND_DISABLED - inband mode disabled, e.g.
-+ * 1000base-X with autoneg off
-+ * PHYLINK_PCS_NEG_INBAND_ENABLED - inband mode enabled
-+ * Additionally, this can be tested using bitmasks:
-+ * PHYLINK_PCS_NEG_INBAND - inband mode selected
-+ * PHYLINK_PCS_NEG_ENABLED - negotiation mode enabled
-+ */
-+ PHYLINK_PCS_NEG_NONE = 0,
-+ PHYLINK_PCS_NEG_ENABLED = BIT(4),
-+ PHYLINK_PCS_NEG_OUTBAND = BIT(5),
-+ PHYLINK_PCS_NEG_INBAND = BIT(6),
-+ PHYLINK_PCS_NEG_INBAND_DISABLED = PHYLINK_PCS_NEG_INBAND,
-+ PHYLINK_PCS_NEG_INBAND_ENABLED = PHYLINK_PCS_NEG_INBAND |
-+ PHYLINK_PCS_NEG_ENABLED,
-+
- /* MAC_SYM_PAUSE and MAC_ASYM_PAUSE are used when configuring our
- * autonegotiation advertisement. They correspond to the PAUSE and
- * ASM_DIR bits defined by 802.3, respectively.
-@@ -80,6 +98,70 @@ static inline bool phylink_autoneg_inban
- }
-
- /**
-+ * phylink_pcs_neg_mode() - helper to determine PCS inband mode
-+ * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
-+ * @interface: interface mode to be used
-+ * @advertising: adertisement ethtool link mode mask
-+ *
-+ * Determines the negotiation mode to be used by the PCS, and returns
-+ * one of:
-+ * %PHYLINK_PCS_NEG_NONE: interface mode does not support inband
-+ * %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY)
-+ * will be used.
-+ * %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg disabled
-+ * %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled
-+ *
-+ * Note: this is for cases where the PCS itself is involved in negotiation
-+ * (e.g. Clause 37, SGMII and similar) not Clause 73.
-+ */
-+static inline unsigned int phylink_pcs_neg_mode(unsigned int mode,
-+ phy_interface_t interface,
-+ const unsigned long *advertising)
-+{
-+ unsigned int neg_mode;
-+
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ case PHY_INTERFACE_MODE_QUSGMII:
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ /* These protocols are designed for use with a PHY which
-+ * communicates its negotiation result back to the MAC via
-+ * inband communication. Note: there exist PHYs that run
-+ * with SGMII but do not send the inband data.
-+ */
-+ if (!phylink_autoneg_inband(mode))
-+ neg_mode = PHYLINK_PCS_NEG_OUTBAND;
-+ else
-+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ /* 1000base-X is designed for use media-side for Fibre
-+ * connections, and thus the Autoneg bit needs to be
-+ * taken into account. We also do this for 2500base-X
-+ * as well, but drivers may not support this, so may
-+ * need to override this.
-+ */
-+ if (!phylink_autoneg_inband(mode))
-+ neg_mode = PHYLINK_PCS_NEG_OUTBAND;
-+ else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ advertising))
-+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
-+ else
-+ neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED;
-+ break;
-+
-+ default:
-+ neg_mode = PHYLINK_PCS_NEG_NONE;
-+ break;
-+ }
-+
-+ return neg_mode;
-+}
-+
-+/**
- * struct phylink_link_state - link state structure
- * @advertising: ethtool bitmask containing advertised link modes
- * @lp_advertising: ethtool bitmask containing link partner advertised link
-@@ -436,6 +518,7 @@ struct phylink_pcs_ops;
- /**
- * struct phylink_pcs - PHYLINK PCS instance
- * @ops: a pointer to the &struct phylink_pcs_ops structure
-+ * @neg_mode: provide PCS neg mode via "mode" argument
- * @poll: poll the PCS for link changes
- *
- * This structure is designed to be embedded within the PCS private data,
-@@ -443,6 +526,7 @@ struct phylink_pcs_ops;
- */
- struct phylink_pcs {
- const struct phylink_pcs_ops *ops;
-+ bool neg_mode;
- bool poll;
- };
-
-@@ -460,12 +544,12 @@ struct phylink_pcs_ops {
- const struct phylink_link_state *state);
- void (*pcs_get_state)(struct phylink_pcs *pcs,
- struct phylink_link_state *state);
-- int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
-+ int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac);
- void (*pcs_an_restart)(struct phylink_pcs *pcs);
-- void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int mode,
-+ void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface, int speed, int duplex);
- };
-
-@@ -508,7 +592,7 @@ void pcs_get_state(struct phylink_pcs *p
- /**
- * pcs_config() - Configure the PCS mode and advertisement
- * @pcs: a pointer to a &struct phylink_pcs.
-- * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
-+ * @neg_mode: link negotiation mode (see below)
- * @interface: interface mode to be used
- * @advertising: adertisement ethtool link mode mask
- * @permit_pause_to_mac: permit forwarding pause resolution to MAC
-@@ -526,8 +610,12 @@ void pcs_get_state(struct phylink_pcs *p
- * For 1000BASE-X, the advertisement should be programmed into the PCS.
- *
- * For most 10GBASE-R, there is no advertisement.
-+ *
-+ * The %neg_mode argument should be tested via the phylink_mode_*() family of
-+ * functions, or for PCS that set pcs->neg_mode true, should be tested
-+ * against the %PHYLINK_PCS_NEG_* definitions.
- */
--int pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+int pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface, const unsigned long *advertising,
- bool permit_pause_to_mac);
-
-@@ -543,7 +631,7 @@ void pcs_an_restart(struct phylink_pcs *
- /**
- * pcs_link_up() - program the PCS for the resolved link configuration
- * @pcs: a pointer to a &struct phylink_pcs.
-- * @mode: link autonegotiation mode
-+ * @neg_mode: link negotiation mode (see below)
- * @interface: link &typedef phy_interface_t mode
- * @speed: link speed
- * @duplex: link duplex
-@@ -552,8 +640,12 @@ void pcs_an_restart(struct phylink_pcs *
- * the resolved link parameters. For example, a PCS operating in SGMII
- * mode without in-band AN needs to be manually configured for the link
- * and duplex setting. Otherwise, this should be a no-op.
-+ *
-+ * The %mode argument should be tested via the phylink_mode_*() family of
-+ * functions, or for PCS that set pcs->neg_mode true, should be tested
-+ * against the %PHYLINK_PCS_NEG_* definitions.
- */
--void pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface, int speed, int duplex);
- #endif
-
diff --git a/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch b/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch
deleted file mode 100644
index 473e9d5836..0000000000
--- a/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From cdb08aa0473730315dbc088d5394e59622314034 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 16 Jun 2023 13:06:27 +0100
-Subject: [PATCH 1/2] net: phylink: convert phylink_mii_c22_pcs_config() to
- neg_mode
-
-Use phylink_pcs_neg_mode() for phylink_mii_c22_pcs_config(). This
-results in no functional change.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://lore.kernel.org/r/E1qA8Dj-00EaFG-Mt@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 9 ++++-----
- 1 file changed, 4 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -3558,6 +3558,7 @@ int phylink_mii_c22_pcs_config(struct md
- phy_interface_t interface,
- const unsigned long *advertising)
- {
-+ unsigned int neg_mode;
- bool changed = 0;
- u16 bmcr;
- int ret, adv;
-@@ -3571,15 +3572,13 @@ int phylink_mii_c22_pcs_config(struct md
- changed = ret;
- }
-
-- /* Ensure ISOLATE bit is disabled */
-- if (mode == MLO_AN_INBAND &&
-- (interface == PHY_INTERFACE_MODE_SGMII ||
-- interface == PHY_INTERFACE_MODE_QSGMII ||
-- linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising)))
-+ neg_mode = phylink_pcs_neg_mode(mode, interface, advertising);
-+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
- bmcr = BMCR_ANENABLE;
- else
- bmcr = 0;
-
-+ /* Configure the inband state. Ensure ISOLATE bit is disabled */
- ret = mdiodev_modify(pcs, MII_BMCR, BMCR_ANENABLE | BMCR_ISOLATE, bmcr);
- if (ret < 0)
- return ret;
diff --git a/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch b/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch
deleted file mode 100644
index 5572850e95..0000000000
--- a/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From febf2aaf05641f3258cc30e072aff65cffc7c82c Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 16 Jun 2023 13:06:32 +0100
-Subject: [PATCH 2/2] net: phylink: pass neg_mode into
- phylink_mii_c22_pcs_config()
-
-Convert fman_dtsec, xilinx_axienet and pcs-lynx to pass the neg_mode
-into phylink_mii_c22_pcs_config(). Where appropriate, drivers are
-updated to have neg_mode passed into their pcs_config() and
-pcs_link_up() functions. For other drivers, we just hoist the call
-to phylink_pcs_neg_mode() to their pcs_config() method out of
-phylink_mii_c22_pcs_config().
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://lore.kernel.org/r/E1qA8Do-00EaFM-Ra@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/freescale/fman/fman_dtsec.c | 7 ++++---
- .../net/ethernet/xilinx/xilinx_axienet_main.c | 6 ++++--
- drivers/net/pcs/pcs-lynx.c | 18 ++++++++++++------
- drivers/net/phy/phylink.c | 9 ++++-----
- include/linux/phylink.h | 5 +++--
- 5 files changed, 27 insertions(+), 18 deletions(-)
-
---- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
-+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
-@@ -763,15 +763,15 @@ static void dtsec_pcs_get_state(struct p
- phylink_mii_c22_pcs_get_state(dtsec->tbidev, state);
- }
-
--static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac)
- {
- struct fman_mac *dtsec = pcs_to_dtsec(pcs);
-
-- return phylink_mii_c22_pcs_config(dtsec->tbidev, mode, interface,
-- advertising);
-+ return phylink_mii_c22_pcs_config(dtsec->tbidev, interface,
-+ advertising, neg_mode);
- }
-
- static void dtsec_pcs_an_restart(struct phylink_pcs *pcs)
-@@ -1447,6 +1447,7 @@ int dtsec_initialization(struct mac_devi
- goto _return_fm_mac_free;
- }
- dtsec->pcs.ops = &dtsec_pcs_ops;
-+ dtsec->pcs.neg_mode = true;
- dtsec->pcs.poll = true;
-
- supported = mac_dev->phylink_config.supported_interfaces;
---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-@@ -1631,7 +1631,7 @@ static void axienet_pcs_an_restart(struc
- phylink_mii_c22_pcs_an_restart(pcs_phy);
- }
-
--static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac)
-@@ -1653,7 +1653,8 @@ static int axienet_pcs_config(struct phy
- }
- }
-
-- ret = phylink_mii_c22_pcs_config(pcs_phy, mode, interface, advertising);
-+ ret = phylink_mii_c22_pcs_config(pcs_phy, interface, advertising,
-+ neg_mode);
- if (ret < 0)
- netdev_warn(ndev, "Failed to configure PCS: %d\n", ret);
-
-@@ -2129,6 +2130,7 @@ static int axienet_probe(struct platform
- }
- of_node_put(np);
- lp->pcs.ops = &axienet_pcs_ops;
-+ lp->pcs.neg_mode = true;
- lp->pcs.poll = true;
- }
-
---- a/drivers/net/pcs/pcs-lynx.c
-+++ b/drivers/net/pcs/pcs-lynx.c
-@@ -122,9 +122,10 @@ static void lynx_pcs_get_state(struct ph
- state->link, state->an_complete);
- }
-
--static int lynx_pcs_config_giga(struct mdio_device *pcs, unsigned int mode,
-+static int lynx_pcs_config_giga(struct mdio_device *pcs,
- phy_interface_t interface,
-- const unsigned long *advertising)
-+ const unsigned long *advertising,
-+ unsigned int neg_mode)
- {
- u32 link_timer;
- u16 if_mode;
-@@ -137,8 +138,9 @@ static int lynx_pcs_config_giga(struct m
-
- if_mode = 0;
- } else {
-+ /* SGMII and QSGMII */
- if_mode = IF_MODE_SGMII_EN;
-- if (mode == MLO_AN_INBAND) {
-+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
- if_mode |= IF_MODE_USE_SGMII_AN;
-
- /* Adjust link timer for SGMII */
-@@ -154,7 +156,8 @@ static int lynx_pcs_config_giga(struct m
- if (err)
- return err;
-
-- return phylink_mii_c22_pcs_config(pcs, mode, interface, advertising);
-+ return phylink_mii_c22_pcs_config(pcs, interface, advertising,
-+ neg_mode);
- }
-
- static int lynx_pcs_config_usxgmii(struct mdio_device *pcs, unsigned int mode,
-@@ -181,13 +184,16 @@ static int lynx_pcs_config(struct phylin
- bool permit)
- {
- struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs);
-+ unsigned int neg_mode;
-+
-+ neg_mode = phylink_pcs_neg_mode(mode, ifmode, advertising);
-
- switch (ifmode) {
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_QSGMII:
-- return lynx_pcs_config_giga(lynx->mdio, mode, ifmode,
-- advertising);
-+ return lynx_pcs_config_giga(lynx->mdio, ifmode, advertising,
-+ neg_mode);
- case PHY_INTERFACE_MODE_2500BASEX:
- if (phylink_autoneg_inband(mode)) {
- dev_err(&lynx->mdio->dev,
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -3545,20 +3545,20 @@ EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_en
- /**
- * phylink_mii_c22_pcs_config() - configure clause 22 PCS
- * @pcs: a pointer to a &struct mdio_device.
-- * @mode: link autonegotiation mode
- * @interface: the PHY interface mode being configured
- * @advertising: the ethtool advertisement mask
-+ * @neg_mode: PCS negotiation mode
- *
- * Configure a Clause 22 PCS PHY with the appropriate negotiation
- * parameters for the @mode, @interface and @advertising parameters.
- * Returns negative error number on failure, zero if the advertisement
- * has not changed, or positive if there is a change.
- */
--int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode,
-+int phylink_mii_c22_pcs_config(struct mdio_device *pcs,
- phy_interface_t interface,
-- const unsigned long *advertising)
-+ const unsigned long *advertising,
-+ unsigned int neg_mode)
- {
-- unsigned int neg_mode;
- bool changed = 0;
- u16 bmcr;
- int ret, adv;
-@@ -3572,7 +3572,6 @@ int phylink_mii_c22_pcs_config(struct md
- changed = ret;
- }
-
-- neg_mode = phylink_pcs_neg_mode(mode, interface, advertising);
- if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
- bmcr = BMCR_ANENABLE;
- else
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -743,9 +743,10 @@ void phylink_mii_c22_pcs_get_state(struc
- struct phylink_link_state *state);
- int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
- const unsigned long *advertising);
--int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode,
-+int phylink_mii_c22_pcs_config(struct mdio_device *pcs,
- phy_interface_t interface,
-- const unsigned long *advertising);
-+ const unsigned long *advertising,
-+ unsigned int neg_mode);
- void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs);
-
- void phylink_resolve_c73(struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch b/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch
deleted file mode 100644
index 5e0128766c..0000000000
--- a/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 3b2de56a146f34e3f70a84cc3a1897064e445d16 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 16 Jun 2023 13:06:43 +0100
-Subject: [PATCH] net: pcs: lynxi: update PCS driver to use neg_mode
-
-Update the Lynxi PCS driver to use neg_mode rather than the mode
-argument. This ensures that the link_up() method will always program
-the speed and duplex when negotiation is disabled.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://lore.kernel.org/r/E1qA8Dz-00EaFY-5A@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/pcs/pcs-mtk-lynxi.c | 39 ++++++++++++++-------------------
- 1 file changed, 16 insertions(+), 23 deletions(-)
-
---- a/drivers/net/pcs/pcs-mtk-lynxi.c
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -102,13 +102,13 @@ static void mtk_pcs_lynxi_get_state(stru
- FIELD_GET(SGMII_LPA, adv));
- }
-
--static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
-+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac)
- {
- struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-- bool mode_changed = false, changed, use_an;
-+ bool mode_changed = false, changed;
- unsigned int rgc3, sgm_mode, bmcr;
- int advertise, link_timer;
-
-@@ -121,30 +121,22 @@ static int mtk_pcs_lynxi_config(struct p
- * we assume that fixes it's speed at bitrate = line rate (in
- * other words, 1000Mbps or 2500Mbps).
- */
-- if (interface == PHY_INTERFACE_MODE_SGMII) {
-+ if (interface == PHY_INTERFACE_MODE_SGMII)
- sgm_mode = SGMII_IF_MODE_SGMII;
-- if (phylink_autoneg_inband(mode)) {
-- sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-- SGMII_SPEED_DUPLEX_AN;
-- use_an = true;
-- } else {
-- use_an = false;
-- }
-- } else if (phylink_autoneg_inband(mode)) {
-- /* 1000base-X or 2500base-X autoneg */
-- sgm_mode = SGMII_REMOTE_FAULT_DIS;
-- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-- advertising);
-- } else {
-+ else
- /* 1000base-X or 2500base-X without autoneg */
- sgm_mode = 0;
-- use_an = false;
-- }
-
-- if (use_an)
-+ if (neg_mode & PHYLINK_PCS_NEG_INBAND)
-+ sgm_mode |= SGMII_REMOTE_FAULT_DIS;
-+
-+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
-+ if (interface == PHY_INTERFACE_MODE_SGMII)
-+ sgm_mode |= SGMII_SPEED_DUPLEX_AN;
- bmcr = BMCR_ANENABLE;
-- else
-+ } else {
- bmcr = 0;
-+ }
-
- if (mpcs->interface != interface) {
- link_timer = phylink_get_link_timer_ns(interface);
-@@ -216,14 +208,15 @@ static void mtk_pcs_lynxi_restart_an(str
- regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
- }
-
--static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs,
-+ unsigned int neg_mode,
- phy_interface_t interface, int speed,
- int duplex)
- {
- struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
- unsigned int sgm_mode;
-
-- if (!phylink_autoneg_inband(mode)) {
-+ if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
- /* Force the speed and duplex setting */
- if (speed == SPEED_10)
- sgm_mode = SGMII_SPEED_10;
-@@ -286,6 +279,7 @@ struct phylink_pcs *mtk_pcs_lynxi_create
- mpcs->regmap = regmap;
- mpcs->flags = flags;
- mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
-+ mpcs->pcs.neg_mode = true;
- mpcs->pcs.poll = true;
- mpcs->interface = PHY_INTERFACE_MODE_NA;
-
diff --git a/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch b/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch
deleted file mode 100644
index 3dd22d2916..0000000000
--- a/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 459fd2f11204c962e3153020f4f56748e0e10afb Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 21 Mar 2023 15:58:49 +0000
-Subject: [PATCH] net: pcs: xpcs: use Autoneg bit rather than an_enabled
-
-The Autoneg bit in the advertising bitmap and state->an_enabled are
-always identical. Thus, we will be removing state->an_enabled.
-
-Use the Autoneg bit in the advertising bitmap to indicate whether
-autonegotiation should be used, rather than using the an_enabled
-member which will be going away.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/pcs/pcs-xpcs.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
---- a/drivers/net/pcs/pcs-xpcs.c
-+++ b/drivers/net/pcs/pcs-xpcs.c
-@@ -931,6 +931,7 @@ static int xpcs_get_state_c73(struct dw_
- struct phylink_link_state *state,
- const struct xpcs_compat *compat)
- {
-+ bool an_enabled;
- int ret;
-
- /* Link needs to be read first ... */
-@@ -948,11 +949,13 @@ static int xpcs_get_state_c73(struct dw_
- return xpcs_do_config(xpcs, state->interface, MLO_AN_INBAND, NULL);
- }
-
-- if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) {
-+ an_enabled = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ state->advertising);
-+ if (an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) {
- state->an_complete = true;
- xpcs_read_lpa_c73(xpcs, state);
- xpcs_resolve_lpa_c73(xpcs, state);
-- } else if (state->an_enabled) {
-+ } else if (an_enabled) {
- state->link = 0;
- } else if (state->link) {
- xpcs_resolve_pma(xpcs, state);
-@@ -1007,7 +1010,8 @@ static int xpcs_get_state_c37_1000basex(
- {
- int lpa, bmsr;
-
-- if (state->an_enabled) {
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ state->advertising)) {
- /* Reset link state */
- state->link = false;
-
diff --git a/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch b/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch
deleted file mode 100644
index 7cae8515fa..0000000000
--- a/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 43fb622d91a9f408322735d2f736495c1009f575 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 9 May 2023 12:50:04 +0100
-Subject: [PATCH] net: pcs: xpcs: fix incorrect number of interfaces
-
-In synopsys_xpcs_compat[], the DW_XPCS_2500BASEX entry was setting
-the number of interfaces using the xpcs_2500basex_features array
-rather than xpcs_2500basex_interfaces. This causes us to overflow
-the array of interfaces. Fix this.
-
-Fixes: f27abde3042a ("net: pcs: add 2500BASEX support for Intel mGbE controller")
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/pcs/pcs-xpcs.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/pcs/pcs-xpcs.c
-+++ b/drivers/net/pcs/pcs-xpcs.c
-@@ -1211,7 +1211,7 @@ static const struct xpcs_compat synopsys
- [DW_XPCS_2500BASEX] = {
- .supported = xpcs_2500basex_features,
- .interface = xpcs_2500basex_interfaces,
-- .num_interfaces = ARRAY_SIZE(xpcs_2500basex_features),
-+ .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
- .an_mode = DW_2500BASEX,
- },
- };
diff --git a/target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch b/target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch
deleted file mode 100644
index 0a7b5358f1..0000000000
--- a/target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From f2ec98566775dd4341ec1dcf93aa5859c60de826 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 1 Feb 2024 14:46:00 +0100
-Subject: [PATCH 1/2] net: phy: qcom: qca808x: fix logic error in LED
- brightness set
-
-In switching to using phy_modify_mmd and a more short version of the
-LED ON/OFF condition in later revision, it was made a logic error where
-
-value ? QCA808X_LED_FORCE_ON : QCA808X_LED_FORCE_OFF is always true as
-value is always OR with QCA808X_LED_FORCE_EN due to missing ()
-resulting in the testing condition being QCA808X_LED_FORCE_EN | value.
-
-Add the () to apply the correct condition and restore correct
-functionality of the brightness ON/OFF.
-
-Fixes: 7196062b64ee ("net: phy: at803x: add LED support for qca808x")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/qca808x.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -820,8 +820,8 @@ static int qca808x_led_brightness_set(st
-
- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-- QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON :
-- QCA808X_LED_FORCE_OFF);
-+ QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON :
-+ QCA808X_LED_FORCE_OFF));
- }
-
- static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
diff --git a/target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch b/target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch
deleted file mode 100644
index e32ed7f777..0000000000
--- a/target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From f203c8c77c7616c099647636f4c67d59a45fe8a2 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 1 Feb 2024 14:46:01 +0100
-Subject: [PATCH 2/2] net: phy: qcom: qca808x: default to LED active High if
- not set
-
-qca808x PHY provide support for the led_polarity_set OP to configure
-and apply the active-low property but on PHY reset, the Active High bit
-is not set resulting in the LED driven as active-low.
-
-To fix this, check if active-low is not set in DT and enable Active High
-polarity by default to restore correct funcionality of the LED.
-
-Fixes: 7196062b64ee ("net: phy: at803x: add LED support for qca808x")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/qca808x.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -290,8 +290,18 @@ static int qca808x_probe(struct phy_devi
-
- static int qca808x_config_init(struct phy_device *phydev)
- {
-+ struct qca808x_priv *priv = phydev->priv;
- int ret;
-
-+ /* Default to LED Active High if active-low not in DT */
-+ if (priv->led_polarity_mode == -1) {
-+ ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN,
-+ QCA808X_MMD7_LED_POLARITY_CTRL,
-+ QCA808X_LED_ACTIVE_HIGH);
-+ if (ret)
-+ return ret;
-+ }
-+
- /* Active adc&vga on 802.3az for the link 1000M and 100M */
- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
diff --git a/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch b/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch
deleted file mode 100644
index b355031aa5..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 385ef48f468696d6d172eb367656a3466fa0408d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 6 Feb 2024 18:31:05 +0100
-Subject: [PATCH 02/10] net: phy: add support for scanning PHY in PHY packages
- nodes
-
-Add support for scanning PHY in PHY package nodes. PHY packages nodes
-are just container for actual PHY on the MDIO bus.
-
-Their PHY address defined in the PHY package node are absolute and
-reflect the address on the MDIO bus.
-
-mdio_bus.c and of_mdio.c is updated to now support and parse also
-PHY package subnode by checking if the node name match
-"ethernet-phy-package".
-
-As PHY package reg is mandatory and each PHY in the PHY package must
-have a reg, every invalid PHY Package node is ignored and will be
-skipped by the autoscan fallback.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/mdio/of_mdio.c | 79 +++++++++++++++++++++++++++-----------
- drivers/net/phy/mdio_bus.c | 44 +++++++++++++++++----
- 2 files changed, 92 insertions(+), 31 deletions(-)
-
---- a/drivers/net/mdio/of_mdio.c
-+++ b/drivers/net/mdio/of_mdio.c
-@@ -138,6 +138,53 @@ bool of_mdiobus_child_is_phy(struct devi
- }
- EXPORT_SYMBOL(of_mdiobus_child_is_phy);
-
-+static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np,
-+ bool *scanphys)
-+{
-+ struct device_node *child;
-+ int addr, rc = 0;
-+
-+ /* Loop over the child nodes and register a phy_device for each phy */
-+ for_each_available_child_of_node(np, child) {
-+ if (of_node_name_eq(child, "ethernet-phy-package")) {
-+ /* Ignore invalid ethernet-phy-package node */
-+ if (!of_find_property(child, "reg", NULL))
-+ continue;
-+
-+ rc = __of_mdiobus_parse_phys(mdio, child, NULL);
-+ if (rc && rc != -ENODEV)
-+ goto exit;
-+
-+ continue;
-+ }
-+
-+ addr = of_mdio_parse_addr(&mdio->dev, child);
-+ if (addr < 0) {
-+ /* Skip scanning for invalid ethernet-phy-package node */
-+ if (scanphys)
-+ *scanphys = true;
-+ continue;
-+ }
-+
-+ if (of_mdiobus_child_is_phy(child))
-+ rc = of_mdiobus_register_phy(mdio, child, addr);
-+ else
-+ rc = of_mdiobus_register_device(mdio, child, addr);
-+
-+ if (rc == -ENODEV)
-+ dev_err(&mdio->dev,
-+ "MDIO device at address %d is missing.\n",
-+ addr);
-+ else if (rc)
-+ goto exit;
-+ }
-+
-+ return 0;
-+exit:
-+ of_node_put(child);
-+ return rc;
-+}
-+
- /**
- * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree
- * @mdio: pointer to mii_bus structure
-@@ -179,33 +226,18 @@ int __of_mdiobus_register(struct mii_bus
- return rc;
-
- /* Loop over the child nodes and register a phy_device for each phy */
-- for_each_available_child_of_node(np, child) {
-- addr = of_mdio_parse_addr(&mdio->dev, child);
-- if (addr < 0) {
-- scanphys = true;
-- continue;
-- }
--
-- if (of_mdiobus_child_is_phy(child))
-- rc = of_mdiobus_register_phy(mdio, child, addr);
-- else
-- rc = of_mdiobus_register_device(mdio, child, addr);
--
-- if (rc == -ENODEV)
-- dev_err(&mdio->dev,
-- "MDIO device at address %d is missing.\n",
-- addr);
-- else if (rc)
-- goto unregister;
-- }
-+ rc = __of_mdiobus_parse_phys(mdio, np, &scanphys);
-+ if (rc)
-+ goto unregister;
-
- if (!scanphys)
- return 0;
-
- /* auto scan for PHYs with empty reg property */
- for_each_available_child_of_node(np, child) {
-- /* Skip PHYs with reg property set */
-- if (of_find_property(child, "reg", NULL))
-+ /* Skip PHYs with reg property set or ethernet-phy-package node */
-+ if (of_find_property(child, "reg", NULL) ||
-+ of_node_name_eq(child, "ethernet-phy-package"))
- continue;
-
- for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
-@@ -226,15 +258,16 @@ int __of_mdiobus_register(struct mii_bus
- if (!rc)
- break;
- if (rc != -ENODEV)
-- goto unregister;
-+ goto put_unregister;
- }
- }
- }
-
- return 0;
-
--unregister:
-+put_unregister:
- of_node_put(child);
-+unregister:
- mdiobus_unregister(mdio);
- return rc;
- }
---- a/drivers/net/phy/mdio_bus.c
-+++ b/drivers/net/phy/mdio_bus.c
-@@ -448,19 +448,34 @@ EXPORT_SYMBOL(of_mdio_find_bus);
- * found, set the of_node pointer for the mdio device. This allows
- * auto-probed phy devices to be supplied with information passed in
- * via DT.
-+ * If a PHY package is found, PHY is searched also there.
- */
--static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
-- struct mdio_device *mdiodev)
-+static int of_mdiobus_find_phy(struct device *dev, struct mdio_device *mdiodev,
-+ struct device_node *np)
- {
-- struct device *dev = &mdiodev->dev;
- struct device_node *child;
-
-- if (dev->of_node || !bus->dev.of_node)
-- return;
--
-- for_each_available_child_of_node(bus->dev.of_node, child) {
-+ for_each_available_child_of_node(np, child) {
- int addr;
-
-+ if (of_node_name_eq(child, "ethernet-phy-package")) {
-+ /* Validate PHY package reg presence */
-+ if (!of_find_property(child, "reg", NULL)) {
-+ of_node_put(child);
-+ return -EINVAL;
-+ }
-+
-+ if (!of_mdiobus_find_phy(dev, mdiodev, child)) {
-+ /* The refcount for the PHY package will be
-+ * incremented later when PHY join the Package.
-+ */
-+ of_node_put(child);
-+ return 0;
-+ }
-+
-+ continue;
-+ }
-+
- addr = of_mdio_parse_addr(dev, child);
- if (addr < 0)
- continue;
-@@ -470,9 +485,22 @@ static void of_mdiobus_link_mdiodev(stru
- /* The refcount on "child" is passed to the mdio
- * device. Do _not_ use of_node_put(child) here.
- */
-- return;
-+ return 0;
- }
- }
-+
-+ return -ENODEV;
-+}
-+
-+static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
-+ struct mdio_device *mdiodev)
-+{
-+ struct device *dev = &mdiodev->dev;
-+
-+ if (dev->of_node || !bus->dev.of_node)
-+ return;
-+
-+ of_mdiobus_find_phy(dev, mdiodev, bus->dev.of_node);
- }
- #else /* !IS_ENABLED(CONFIG_OF_MDIO) */
- static inline void of_mdiobus_link_mdiodev(struct mii_bus *mdio,
diff --git a/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch b/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch
deleted file mode 100644
index 3c7bf6c132..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch
+++ /dev/null
@@ -1,185 +0,0 @@
-From 471e8fd3afcef5a9f9089f0bd21965ad9ba35c91 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 6 Feb 2024 18:31:06 +0100
-Subject: [PATCH 03/10] net: phy: add devm/of_phy_package_join helper
-
-Add devm/of_phy_package_join helper to join PHYs in a PHY package. These
-are variant of the manual phy_package_join with the difference that
-these will use DT nodes to derive the base_addr instead of manually
-passing an hardcoded value.
-
-An additional value is added in phy_package_shared, "np" to reference
-the PHY package node pointer in specific PHY driver probe_once and
-config_init_once functions to make use of additional specific properties
-defined in the PHY package node in DT.
-
-The np value is filled only with of_phy_package_join if a valid PHY
-package node is found. A valid PHY package node must have the node name
-set to "ethernet-phy-package".
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy_device.c | 96 ++++++++++++++++++++++++++++++++++++
- include/linux/phy.h | 6 +++
- 2 files changed, 102 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1648,6 +1648,7 @@ int phy_package_join(struct phy_device *
- shared->priv_size = priv_size;
- }
- shared->base_addr = base_addr;
-+ shared->np = NULL;
- refcount_set(&shared->refcnt, 1);
- bus->shared[base_addr] = shared;
- } else {
-@@ -1671,6 +1672,63 @@ err_unlock:
- EXPORT_SYMBOL_GPL(phy_package_join);
-
- /**
-+ * of_phy_package_join - join a common PHY group in PHY package
-+ * @phydev: target phy_device struct
-+ * @priv_size: if non-zero allocate this amount of bytes for private data
-+ *
-+ * This is a variant of phy_package_join for PHY package defined in DT.
-+ *
-+ * The parent node of the @phydev is checked as a valid PHY package node
-+ * structure (by matching the node name "ethernet-phy-package") and the
-+ * base_addr for the PHY package is passed to phy_package_join.
-+ *
-+ * With this configuration the shared struct will also have the np value
-+ * filled to use additional DT defined properties in PHY specific
-+ * probe_once and config_init_once PHY package OPs.
-+ *
-+ * Returns < 0 on error, 0 on success. Esp. calling phy_package_join()
-+ * with the same cookie but a different priv_size is an error. Or a parent
-+ * node is not detected or is not valid or doesn't match the expected node
-+ * name for PHY package.
-+ */
-+int of_phy_package_join(struct phy_device *phydev, size_t priv_size)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ struct device_node *package_node;
-+ u32 base_addr;
-+ int ret;
-+
-+ if (!node)
-+ return -EINVAL;
-+
-+ package_node = of_get_parent(node);
-+ if (!package_node)
-+ return -EINVAL;
-+
-+ if (!of_node_name_eq(package_node, "ethernet-phy-package")) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ if (of_property_read_u32(package_node, "reg", &base_addr)) {
-+ ret = -EINVAL;
-+ goto exit;
-+ }
-+
-+ ret = phy_package_join(phydev, base_addr, priv_size);
-+ if (ret)
-+ goto exit;
-+
-+ phydev->shared->np = package_node;
-+
-+ return 0;
-+exit:
-+ of_node_put(package_node);
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(of_phy_package_join);
-+
-+/**
- * phy_package_leave - leave a common PHY group
- * @phydev: target phy_device struct
- *
-@@ -1686,6 +1744,10 @@ void phy_package_leave(struct phy_device
- if (!shared)
- return;
-
-+ /* Decrease the node refcount on leave if present */
-+ if (shared->np)
-+ of_node_put(shared->np);
-+
- if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
- bus->shared[shared->base_addr] = NULL;
- mutex_unlock(&bus->shared_lock);
-@@ -1739,6 +1801,40 @@ int devm_phy_package_join(struct device
- EXPORT_SYMBOL_GPL(devm_phy_package_join);
-
- /**
-+ * devm_of_phy_package_join - resource managed of_phy_package_join()
-+ * @dev: device that is registering this PHY package
-+ * @phydev: target phy_device struct
-+ * @priv_size: if non-zero allocate this amount of bytes for private data
-+ *
-+ * Managed of_phy_package_join(). Shared storage fetched by this function,
-+ * phy_package_leave() is automatically called on driver detach. See
-+ * of_phy_package_join() for more information.
-+ */
-+int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev,
-+ size_t priv_size)
-+{
-+ struct phy_device **ptr;
-+ int ret;
-+
-+ ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
-+ GFP_KERNEL);
-+ if (!ptr)
-+ return -ENOMEM;
-+
-+ ret = of_phy_package_join(phydev, priv_size);
-+
-+ if (!ret) {
-+ *ptr = phydev;
-+ devres_add(dev, ptr);
-+ } else {
-+ devres_free(ptr);
-+ }
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(devm_of_phy_package_join);
-+
-+/**
- * phy_detach - detach a PHY device from its network device
- * @phydev: target phy_device struct
- *
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -321,6 +321,7 @@ struct mdio_bus_stats {
- * struct phy_package_shared - Shared information in PHY packages
- * @base_addr: Base PHY address of PHY package used to combine PHYs
- * in one package and for offset calculation of phy_package_read/write
-+ * @np: Pointer to the Device Node if PHY package defined in DT
- * @refcnt: Number of PHYs connected to this shared data
- * @flags: Initialization of PHY package
- * @priv_size: Size of the shared private data @priv
-@@ -332,6 +333,8 @@ struct mdio_bus_stats {
- */
- struct phy_package_shared {
- u8 base_addr;
-+ /* With PHY package defined in DT this points to the PHY package node */
-+ struct device_node *np;
- refcount_t refcnt;
- unsigned long flags;
- size_t priv_size;
-@@ -1793,9 +1796,12 @@ int phy_ethtool_set_link_ksettings(struc
- const struct ethtool_link_ksettings *cmd);
- int phy_ethtool_nway_reset(struct net_device *ndev);
- int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size);
-+int of_phy_package_join(struct phy_device *phydev, size_t priv_size);
- void phy_package_leave(struct phy_device *phydev);
- int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
- int base_addr, size_t priv_size);
-+int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev,
-+ size_t priv_size);
-
- #if IS_ENABLED(CONFIG_PHYLIB)
- int __init mdio_bus_init(void);
diff --git a/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch b/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch
deleted file mode 100644
index e935725630..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch
+++ /dev/null
@@ -1,583 +0,0 @@
-From 737eb75a815f9c08dcbb6631db57f4f4b0540a5b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 6 Feb 2024 18:31:07 +0100
-Subject: [PATCH 04/10] net: phy: qcom: move more function to shared library
-
-Move more function to shared library in preparation for introduction of
-new PHY Family qca807x that will make use of both functions from at803x
-and qca808x as it's a transition PHY with some implementation of at803x
-and some from the new qca808x.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/at803x.c | 35 -----
- drivers/net/phy/qcom/qca808x.c | 205 ----------------------------
- drivers/net/phy/qcom/qcom-phy-lib.c | 193 ++++++++++++++++++++++++++
- drivers/net/phy/qcom/qcom.h | 51 +++++++
- 4 files changed, 244 insertions(+), 240 deletions(-)
-
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -504,41 +504,6 @@ static void at803x_link_change_notify(st
- }
- }
-
--static int at803x_read_status(struct phy_device *phydev)
--{
-- struct at803x_ss_mask ss_mask = { 0 };
-- int err, old_link = phydev->link;
--
-- /* Update the link, but return if there was an error */
-- err = genphy_update_link(phydev);
-- if (err)
-- return err;
--
-- /* why bother the PHY if nothing can have changed */
-- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-- return 0;
--
-- phydev->speed = SPEED_UNKNOWN;
-- phydev->duplex = DUPLEX_UNKNOWN;
-- phydev->pause = 0;
-- phydev->asym_pause = 0;
--
-- err = genphy_read_lpa(phydev);
-- if (err < 0)
-- return err;
--
-- ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
-- ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
-- err = at803x_read_specific_status(phydev, ss_mask);
-- if (err < 0)
-- return err;
--
-- if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
-- phy_resolve_aneg_pause(phydev);
--
-- return 0;
--}
--
- static int at803x_config_aneg(struct phy_device *phydev)
- {
- struct at803x_priv *priv = phydev->priv;
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -2,7 +2,6 @@
-
- #include <linux/phy.h>
- #include <linux/module.h>
--#include <linux/ethtool_netlink.h>
-
- #include "qcom.h"
-
-@@ -63,55 +62,6 @@
- #define QCA808X_DBG_AN_TEST 0xb
- #define QCA808X_HIBERNATION_EN BIT(15)
-
--#define QCA808X_CDT_ENABLE_TEST BIT(15)
--#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
--#define QCA808X_CDT_STATUS BIT(11)
--#define QCA808X_CDT_LENGTH_UNIT BIT(10)
--
--#define QCA808X_MMD3_CDT_STATUS 0x8064
--#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
--#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
--#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
--#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
--#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
--#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
--
--#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
--#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
--#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
--#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
--
--#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
--#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
--#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
--#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
--#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
--
--#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
--#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
--#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
--#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
--
--/* NORMAL are MDI with type set to 0 */
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI1)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI1)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI2)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI2)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-- QCA808X_CDT_STATUS_STAT_MDI3)
--#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-- QCA808X_CDT_STATUS_STAT_MDI3)
--
--/* Added for reference of existence but should be handled by wait_for_completion already */
--#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
--
- #define QCA808X_MMD7_LED_GLOBAL 0x8073
- #define QCA808X_LED_BLINK_1 GENMASK(11, 6)
- #define QCA808X_LED_BLINK_2 GENMASK(5, 0)
-@@ -406,86 +356,6 @@ static int qca808x_soft_reset(struct phy
- return ret;
- }
-
--static bool qca808x_cdt_fault_length_valid(int cdt_code)
--{
-- switch (cdt_code) {
-- case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-- return true;
-- default:
-- return false;
-- }
--}
--
--static int qca808x_cable_test_result_trans(int cdt_code)
--{
-- switch (cdt_code) {
-- case QCA808X_CDT_STATUS_STAT_NORMAL:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-- case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-- case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-- return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
-- case QCA808X_CDT_STATUS_STAT_FAIL:
-- default:
-- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-- }
--}
--
--static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
-- int result)
--{
-- int val;
-- u32 cdt_length_reg = 0;
--
-- switch (pair) {
-- case ETHTOOL_A_CABLE_PAIR_A:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_B:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_C:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
-- break;
-- case ETHTOOL_A_CABLE_PAIR_D:
-- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
-- if (val < 0)
-- return val;
--
-- if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
-- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
-- else
-- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
--
-- return at803x_cdt_fault_length(val);
--}
--
- static int qca808x_cable_test_start(struct phy_device *phydev)
- {
- int ret;
-@@ -526,81 +396,6 @@ static int qca808x_cable_test_start(stru
-
- return 0;
- }
--
--static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
-- u16 status)
--{
-- int length, result;
-- u16 pair_code;
--
-- switch (pair) {
-- case ETHTOOL_A_CABLE_PAIR_A:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_B:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_C:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
-- break;
-- case ETHTOOL_A_CABLE_PAIR_D:
-- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- result = qca808x_cable_test_result_trans(pair_code);
-- ethnl_cable_test_result(phydev, pair, result);
--
-- if (qca808x_cdt_fault_length_valid(pair_code)) {
-- length = qca808x_cdt_fault_length(phydev, pair, result);
-- ethnl_cable_test_fault_length(phydev, pair, length);
-- }
--
-- return 0;
--}
--
--static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
--{
-- int ret, val;
--
-- *finished = false;
--
-- val = QCA808X_CDT_ENABLE_TEST |
-- QCA808X_CDT_LENGTH_UNIT;
-- ret = at803x_cdt_start(phydev, val);
-- if (ret)
-- return ret;
--
-- ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
-- if (ret)
-- return ret;
--
-- val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
-- if (val < 0)
-- return val;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-- if (ret)
-- return ret;
--
-- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-- if (ret)
-- return ret;
--
-- *finished = true;
--
-- return 0;
--}
-
- static int qca808x_get_features(struct phy_device *phydev)
- {
---- a/drivers/net/phy/qcom/qcom-phy-lib.c
-+++ b/drivers/net/phy/qcom/qcom-phy-lib.c
-@@ -5,6 +5,7 @@
-
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
-+#include <linux/ethtool_netlink.h>
-
- #include "qcom.h"
-
-@@ -311,6 +312,42 @@ int at803x_prepare_config_aneg(struct ph
- }
- EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg);
-
-+int at803x_read_status(struct phy_device *phydev)
-+{
-+ struct at803x_ss_mask ss_mask = { 0 };
-+ int err, old_link = phydev->link;
-+
-+ /* Update the link, but return if there was an error */
-+ err = genphy_update_link(phydev);
-+ if (err)
-+ return err;
-+
-+ /* why bother the PHY if nothing can have changed */
-+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-+ return 0;
-+
-+ phydev->speed = SPEED_UNKNOWN;
-+ phydev->duplex = DUPLEX_UNKNOWN;
-+ phydev->pause = 0;
-+ phydev->asym_pause = 0;
-+
-+ err = genphy_read_lpa(phydev);
-+ if (err < 0)
-+ return err;
-+
-+ ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
-+ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
-+ err = at803x_read_specific_status(phydev, ss_mask);
-+ if (err < 0)
-+ return err;
-+
-+ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
-+ phy_resolve_aneg_pause(phydev);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(at803x_read_status);
-+
- static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
- {
- int val;
-@@ -427,3 +464,159 @@ int at803x_cdt_wait_for_completion(struc
- return ret < 0 ? ret : 0;
- }
- EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion);
-+
-+static bool qca808x_cdt_fault_length_valid(int cdt_code)
-+{
-+ switch (cdt_code) {
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-+ return true;
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int qca808x_cable_test_result_trans(int cdt_code)
-+{
-+ switch (cdt_code) {
-+ case QCA808X_CDT_STATUS_STAT_NORMAL:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OK;
-+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
-+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
-+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
-+ case QCA808X_CDT_STATUS_STAT_FAIL:
-+ default:
-+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
-+ }
-+}
-+
-+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
-+ int result)
-+{
-+ int val;
-+ u32 cdt_length_reg = 0;
-+
-+ switch (pair) {
-+ case ETHTOOL_A_CABLE_PAIR_A:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_B:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_C:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_D:
-+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
-+ if (val < 0)
-+ return val;
-+
-+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
-+ else
-+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
-+
-+ return at803x_cdt_fault_length(val);
-+}
-+
-+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
-+ u16 status)
-+{
-+ int length, result;
-+ u16 pair_code;
-+
-+ switch (pair) {
-+ case ETHTOOL_A_CABLE_PAIR_A:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_B:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_C:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
-+ break;
-+ case ETHTOOL_A_CABLE_PAIR_D:
-+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ result = qca808x_cable_test_result_trans(pair_code);
-+ ethnl_cable_test_result(phydev, pair, result);
-+
-+ if (qca808x_cdt_fault_length_valid(pair_code)) {
-+ length = qca808x_cdt_fault_length(phydev, pair, result);
-+ ethnl_cable_test_fault_length(phydev, pair, length);
-+ }
-+
-+ return 0;
-+}
-+
-+int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
-+{
-+ int ret, val;
-+
-+ *finished = false;
-+
-+ val = QCA808X_CDT_ENABLE_TEST |
-+ QCA808X_CDT_LENGTH_UNIT;
-+ ret = at803x_cdt_start(phydev, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
-+ if (ret)
-+ return ret;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
-+ if (val < 0)
-+ return val;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
-+ if (ret)
-+ return ret;
-+
-+ *finished = true;
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status);
---- a/drivers/net/phy/qcom/qcom.h
-+++ b/drivers/net/phy/qcom/qcom.h
-@@ -54,6 +54,55 @@
- #define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8)
- #define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0)
-
-+#define QCA808X_CDT_ENABLE_TEST BIT(15)
-+#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
-+#define QCA808X_CDT_STATUS BIT(11)
-+#define QCA808X_CDT_LENGTH_UNIT BIT(10)
-+
-+#define QCA808X_MMD3_CDT_STATUS 0x8064
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
-+#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
-+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
-+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
-+
-+#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
-+#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
-+#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
-+#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
-+
-+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
-+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
-+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
-+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
-+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
-+
-+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
-+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
-+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
-+
-+/* NORMAL are MDI with type set to 0 */
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI1)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI2)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
-+ QCA808X_CDT_STATUS_STAT_MDI3)
-+
-+/* Added for reference of existence but should be handled by wait_for_completion already */
-+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
-+
- #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
- #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
- #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
-@@ -110,6 +159,7 @@ int at803x_read_specific_status(struct p
- struct at803x_ss_mask ss_mask);
- int at803x_config_mdix(struct phy_device *phydev, u8 ctrl);
- int at803x_prepare_config_aneg(struct phy_device *phydev);
-+int at803x_read_status(struct phy_device *phydev);
- int at803x_get_tunable(struct phy_device *phydev,
- struct ethtool_tunable *tuna, void *data);
- int at803x_set_tunable(struct phy_device *phydev,
-@@ -118,3 +168,4 @@ int at803x_cdt_fault_length(int dt);
- int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start);
- int at803x_cdt_wait_for_completion(struct phy_device *phydev,
- u32 cdt_en);
-+int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished);
diff --git a/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch b/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch
deleted file mode 100644
index acaa4a644e..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 9b1d5e055508393561e26bd1720f4c2639b03b1a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 6 Feb 2024 18:31:09 +0100
-Subject: [PATCH 06/10] net: phy: provide whether link has changed in
- c37_read_status
-
-Some PHY driver might require additional regs call after
-genphy_c37_read_status() is called.
-
-Expand genphy_c37_read_status to provide a bool wheather the link has
-changed or not to permit PHY driver to skip additional regs call if
-nothing has changed.
-
-Every user of genphy_c37_read_status() is updated with the new
-additional bool.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/broadcom.c | 3 ++-
- drivers/net/phy/phy_device.c | 11 +++++++++--
- drivers/net/phy/qcom/at803x.c | 3 ++-
- include/linux/phy.h | 2 +-
- 4 files changed, 14 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/broadcom.c
-+++ b/drivers/net/phy/broadcom.c
-@@ -609,10 +609,11 @@ static int bcm54616s_config_aneg(struct
- static int bcm54616s_read_status(struct phy_device *phydev)
- {
- struct bcm54616s_phy_priv *priv = phydev->priv;
-+ bool changed;
- int err;
-
- if (priv->mode_1000bx_en)
-- err = genphy_c37_read_status(phydev);
-+ err = genphy_c37_read_status(phydev, &changed);
- else
- err = genphy_read_status(phydev);
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -2549,12 +2549,15 @@ EXPORT_SYMBOL(genphy_read_status);
- /**
- * genphy_c37_read_status - check the link status and update current link state
- * @phydev: target phy_device struct
-+ * @changed: pointer where to store if link changed
- *
- * Description: Check the link, then figure out the current state
- * by comparing what we advertise with what the link partner
- * advertises. This function is for Clause 37 1000Base-X mode.
-+ *
-+ * If link has changed, @changed is set to true, false otherwise.
- */
--int genphy_c37_read_status(struct phy_device *phydev)
-+int genphy_c37_read_status(struct phy_device *phydev, bool *changed)
- {
- int lpa, err, old_link = phydev->link;
-
-@@ -2564,9 +2567,13 @@ int genphy_c37_read_status(struct phy_de
- return err;
-
- /* why bother the PHY if nothing can have changed */
-- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) {
-+ *changed = false;
- return 0;
-+ }
-
-+ /* Signal link has changed */
-+ *changed = true;
- phydev->duplex = DUPLEX_UNKNOWN;
- phydev->pause = 0;
- phydev->asym_pause = 0;
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -912,9 +912,10 @@ static int at8031_config_intr(struct phy
- static int at8031_read_status(struct phy_device *phydev)
- {
- struct at803x_priv *priv = phydev->priv;
-+ bool changed;
-
- if (priv->is_1000basex)
-- return genphy_c37_read_status(phydev);
-+ return genphy_c37_read_status(phydev, &changed);
-
- return at803x_read_status(phydev);
- }
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1688,7 +1688,7 @@ int genphy_write_mmd_unsupported(struct
-
- /* Clause 37 */
- int genphy_c37_config_aneg(struct phy_device *phydev);
--int genphy_c37_read_status(struct phy_device *phydev);
-+int genphy_c37_read_status(struct phy_device *phydev, bool *changed);
-
- /* Clause 45 PHY */
- int genphy_c45_restart_aneg(struct phy_device *phydev);
diff --git a/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch b/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch
deleted file mode 100644
index bbf0f76d68..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch
+++ /dev/null
@@ -1,668 +0,0 @@
-From d1cb613efbd3cd7d0c000167816beb3f248f5eb8 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robert.marko@sartura.hr>
-Date: Tue, 6 Feb 2024 18:31:10 +0100
-Subject: [PATCH 07/10] net: phy: qcom: add support for QCA807x PHY Family
-
-This adds driver for the Qualcomm QCA8072 and QCA8075 PHY-s.
-
-They are 2 or 5 port IEEE 802.3 clause 22 compliant 10BASE-Te,
-100BASE-TX and 1000BASE-T PHY-s.
-
-They feature 2 SerDes, one for PSGMII or QSGMII connection with
-MAC, while second one is SGMII for connection to MAC or fiber.
-
-Both models have a combo port that supports 1000BASE-X and
-100BASE-FX fiber.
-
-PHY package can be configured in 3 mode following this table:
-
- First Serdes mode Second Serdes mode
-Option 1 PSGMII for copper Disabled
- ports 0-4
-Option 2 PSGMII for copper 1000BASE-X / 100BASE-FX
- ports 0-4
-Option 3 QSGMII for copper SGMII for
- ports 0-3 copper port 4
-
-Each PHY inside of QCA807x series has 4 digitally controlled
-output only pins that natively drive LED-s.
-But some vendors used these to driver generic LED-s controlled
-by userspace, so lets enable registering each PHY as GPIO
-controller and add driver for it.
-
-These are commonly used in Qualcomm IPQ40xx, IPQ60xx and IPQ807x
-boards.
-
-Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Robert Marko <robert.marko@sartura.hr>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/Kconfig | 8 +
- drivers/net/phy/qcom/Makefile | 1 +
- drivers/net/phy/qcom/qca807x.c | 597 +++++++++++++++++++++++++++++++++
- 3 files changed, 606 insertions(+)
- create mode 100644 drivers/net/phy/qcom/qca807x.c
-
---- a/drivers/net/phy/qcom/Kconfig
-+++ b/drivers/net/phy/qcom/Kconfig
-@@ -20,3 +20,11 @@ config QCA808X_PHY
- select QCOM_NET_PHYLIB
- help
- Currently supports the QCA8081 model
-+
-+config QCA807X_PHY
-+ tristate "Qualcomm QCA807x PHYs"
-+ select QCOM_NET_PHYLIB
-+ depends on OF_MDIO
-+ help
-+ Currently supports the Qualcomm QCA8072, QCA8075 and the PSGMII
-+ control PHY.
---- a/drivers/net/phy/qcom/Makefile
-+++ b/drivers/net/phy/qcom/Makefile
-@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-ph
- obj-$(CONFIG_AT803X_PHY) += at803x.o
- obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o
- obj-$(CONFIG_QCA808X_PHY) += qca808x.o
-+obj-$(CONFIG_QCA807X_PHY) += qca807x.o
---- /dev/null
-+++ b/drivers/net/phy/qcom/qca807x.c
-@@ -0,0 +1,597 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Copyright (c) 2023 Sartura Ltd.
-+ *
-+ * Author: Robert Marko <robert.marko@sartura.hr>
-+ * Christian Marangi <ansuelsmth@gmail.com>
-+ *
-+ * Qualcomm QCA8072 and QCA8075 PHY driver
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/phy.h>
-+#include <linux/bitfield.h>
-+#include <linux/gpio/driver.h>
-+#include <linux/sfp.h>
-+
-+#include "qcom.h"
-+
-+#define QCA807X_CHIP_CONFIGURATION 0x1f
-+#define QCA807X_BT_BX_REG_SEL BIT(15)
-+#define QCA807X_BT_BX_REG_SEL_FIBER 0
-+#define QCA807X_BT_BX_REG_SEL_COPPER 1
-+#define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0)
-+#define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4
-+#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3
-+#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0
-+
-+#define QCA807X_MEDIA_SELECT_STATUS 0x1a
-+#define QCA807X_MEDIA_DETECTED_COPPER BIT(5)
-+#define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4)
-+#define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3)
-+
-+#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e
-+#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0)
-+
-+#define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a
-+#define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0)
-+/* List of tweaks enabled by this bit:
-+ * - With both FULL amplitude and FULL bias current: bias current
-+ * is set to half.
-+ * - With only DSP amplitude: bias current is set to half and
-+ * is set to 1/4 with cable < 10m.
-+ * - With DSP bias current (included both DSP amplitude and
-+ * DSP bias current): bias current is half the detected current
-+ * with cable < 10m.
-+ */
-+#define QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK BIT(2)
-+#define QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT BIT(1)
-+#define QCA807X_CONTROL_DAC_DSP_AMPLITUDE BIT(0)
-+
-+#define QCA807X_MMD7_LED_100N_1 0x8074
-+#define QCA807X_MMD7_LED_100N_2 0x8075
-+#define QCA807X_MMD7_LED_1000N_1 0x8076
-+#define QCA807X_MMD7_LED_1000N_2 0x8077
-+
-+#define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2))
-+#define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2))
-+
-+#define QCA807X_GPIO_FORCE_EN BIT(15)
-+#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13)
-+
-+#define QCA807X_FUNCTION_CONTROL 0x10
-+#define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5)
-+#define QCA807X_FC_MDI_CROSSOVER_AUTO 3
-+#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1
-+#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0
-+
-+/* PQSGMII Analog PHY specific */
-+#define PQSGMII_CTRL_REG 0x0
-+#define PQSGMII_ANALOG_SW_RESET BIT(6)
-+#define PQSGMII_DRIVE_CONTROL_1 0xb
-+#define PQSGMII_TX_DRIVER_MASK GENMASK(7, 4)
-+#define PQSGMII_TX_DRIVER_140MV 0x0
-+#define PQSGMII_TX_DRIVER_160MV 0x1
-+#define PQSGMII_TX_DRIVER_180MV 0x2
-+#define PQSGMII_TX_DRIVER_200MV 0x3
-+#define PQSGMII_TX_DRIVER_220MV 0x4
-+#define PQSGMII_TX_DRIVER_240MV 0x5
-+#define PQSGMII_TX_DRIVER_260MV 0x6
-+#define PQSGMII_TX_DRIVER_280MV 0x7
-+#define PQSGMII_TX_DRIVER_300MV 0x8
-+#define PQSGMII_TX_DRIVER_320MV 0x9
-+#define PQSGMII_TX_DRIVER_400MV 0xa
-+#define PQSGMII_TX_DRIVER_500MV 0xb
-+#define PQSGMII_TX_DRIVER_600MV 0xc
-+#define PQSGMII_MODE_CTRL 0x6d
-+#define PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0)
-+#define PQSGMII_MMD3_SERDES_CONTROL 0x805a
-+
-+#define PHY_ID_QCA8072 0x004dd0b2
-+#define PHY_ID_QCA8075 0x004dd0b1
-+
-+#define QCA807X_COMBO_ADDR_OFFSET 4
-+#define QCA807X_PQSGMII_ADDR_OFFSET 5
-+#define SERDES_RESET_SLEEP 100
-+
-+enum qca807x_global_phy {
-+ QCA807X_COMBO_ADDR = 4,
-+ QCA807X_PQSGMII_ADDR = 5,
-+};
-+
-+struct qca807x_shared_priv {
-+ unsigned int package_mode;
-+ u32 tx_drive_strength;
-+};
-+
-+struct qca807x_gpio_priv {
-+ struct phy_device *phy;
-+};
-+
-+struct qca807x_priv {
-+ bool dac_full_amplitude;
-+ bool dac_full_bias_current;
-+ bool dac_disable_bias_current_tweak;
-+};
-+
-+static int qca807x_cable_test_start(struct phy_device *phydev)
-+{
-+ /* we do all the (time consuming) work later */
-+ return 0;
-+}
-+
-+#ifdef CONFIG_GPIOLIB
-+static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
-+{
-+ return GPIO_LINE_DIRECTION_OUT;
-+}
-+
-+static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset)
-+{
-+ struct qca807x_gpio_priv *priv = gpiochip_get_data(gc);
-+ u16 reg;
-+ int val;
-+
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(offset);
-+ val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg);
-+
-+ return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val);
-+}
-+
-+static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
-+{
-+ struct qca807x_gpio_priv *priv = gpiochip_get_data(gc);
-+ u16 reg;
-+ int val;
-+
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(offset);
-+
-+ val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg);
-+ val &= ~QCA807X_GPIO_FORCE_MODE_MASK;
-+ val |= QCA807X_GPIO_FORCE_EN;
-+ val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value);
-+
-+ phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val);
-+}
-+
-+static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value)
-+{
-+ qca807x_gpio_set(gc, offset, value);
-+
-+ return 0;
-+}
-+
-+static int qca807x_gpio(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct qca807x_gpio_priv *priv;
-+ struct gpio_chip *gc;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->phy = phydev;
-+
-+ gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
-+ if (!gc)
-+ return -ENOMEM;
-+
-+ gc->label = dev_name(dev);
-+ gc->base = -1;
-+ gc->ngpio = 2;
-+ gc->parent = dev;
-+ gc->owner = THIS_MODULE;
-+ gc->can_sleep = true;
-+ gc->get_direction = qca807x_gpio_get_direction;
-+ gc->direction_output = qca807x_gpio_dir_out;
-+ gc->get = qca807x_gpio_get;
-+ gc->set = qca807x_gpio_set;
-+
-+ return devm_gpiochip_add_data(dev, gc, priv);
-+}
-+#endif
-+
-+static int qca807x_read_fiber_status(struct phy_device *phydev)
-+{
-+ bool changed;
-+ int ss, err;
-+
-+ err = genphy_c37_read_status(phydev, &changed);
-+ if (err || !changed)
-+ return err;
-+
-+ /* Read the QCA807x PHY-Specific Status register fiber page,
-+ * which indicates the speed and duplex that the PHY is actually
-+ * using, irrespective of whether we are in autoneg mode or not.
-+ */
-+ ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
-+ if (ss < 0)
-+ return ss;
-+
-+ phydev->speed = SPEED_UNKNOWN;
-+ phydev->duplex = DUPLEX_UNKNOWN;
-+ if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
-+ switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) {
-+ case AT803X_SS_SPEED_100:
-+ phydev->speed = SPEED_100;
-+ break;
-+ case AT803X_SS_SPEED_1000:
-+ phydev->speed = SPEED_1000;
-+ break;
-+ }
-+
-+ if (ss & AT803X_SS_DUPLEX)
-+ phydev->duplex = DUPLEX_FULL;
-+ else
-+ phydev->duplex = DUPLEX_HALF;
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca807x_read_status(struct phy_device *phydev)
-+{
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) {
-+ switch (phydev->port) {
-+ case PORT_FIBRE:
-+ return qca807x_read_fiber_status(phydev);
-+ case PORT_TP:
-+ return at803x_read_status(phydev);
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ return at803x_read_status(phydev);
-+}
-+
-+static int qca807x_phy_package_probe_once(struct phy_device *phydev)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+ struct qca807x_shared_priv *priv = shared->priv;
-+ unsigned int tx_drive_strength;
-+ const char *package_mode_name;
-+
-+ /* Default to 600mw if not defined */
-+ if (of_property_read_u32(shared->np, "qcom,tx-drive-strength-milliwatt",
-+ &tx_drive_strength))
-+ tx_drive_strength = 600;
-+
-+ switch (tx_drive_strength) {
-+ case 140:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_140MV;
-+ break;
-+ case 160:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_160MV;
-+ break;
-+ case 180:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_180MV;
-+ break;
-+ case 200:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_200MV;
-+ break;
-+ case 220:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_220MV;
-+ break;
-+ case 240:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_240MV;
-+ break;
-+ case 260:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_260MV;
-+ break;
-+ case 280:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_280MV;
-+ break;
-+ case 300:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_300MV;
-+ break;
-+ case 320:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_320MV;
-+ break;
-+ case 400:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_400MV;
-+ break;
-+ case 500:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_500MV;
-+ break;
-+ case 600:
-+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_600MV;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ priv->package_mode = PHY_INTERFACE_MODE_NA;
-+ if (!of_property_read_string(shared->np, "qcom,package-mode",
-+ &package_mode_name)) {
-+ if (!strcasecmp(package_mode_name,
-+ phy_modes(PHY_INTERFACE_MODE_PSGMII)))
-+ priv->package_mode = PHY_INTERFACE_MODE_PSGMII;
-+ else if (!strcasecmp(package_mode_name,
-+ phy_modes(PHY_INTERFACE_MODE_QSGMII)))
-+ priv->package_mode = PHY_INTERFACE_MODE_QSGMII;
-+ else
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca807x_phy_package_config_init_once(struct phy_device *phydev)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+ struct qca807x_shared_priv *priv = shared->priv;
-+ int val, ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+
-+ /* Set correct PHY package mode */
-+ val = __phy_package_read(phydev, QCA807X_COMBO_ADDR,
-+ QCA807X_CHIP_CONFIGURATION);
-+ val &= ~QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK;
-+ /* package_mode can be QSGMII or PSGMII and we validate
-+ * this in probe_once.
-+ * With package_mode to NA, we default to PSGMII.
-+ */
-+ switch (priv->package_mode) {
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ val |= QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII;
-+ break;
-+ case PHY_INTERFACE_MODE_PSGMII:
-+ default:
-+ val |= QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER;
-+ }
-+ ret = __phy_package_write(phydev, QCA807X_COMBO_ADDR,
-+ QCA807X_CHIP_CONFIGURATION, val);
-+ if (ret)
-+ goto exit;
-+
-+ /* After mode change Serdes reset is required */
-+ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR,
-+ PQSGMII_CTRL_REG);
-+ val &= ~PQSGMII_ANALOG_SW_RESET;
-+ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR,
-+ PQSGMII_CTRL_REG, val);
-+ if (ret)
-+ goto exit;
-+
-+ msleep(SERDES_RESET_SLEEP);
-+
-+ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR,
-+ PQSGMII_CTRL_REG);
-+ val |= PQSGMII_ANALOG_SW_RESET;
-+ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR,
-+ PQSGMII_CTRL_REG, val);
-+ if (ret)
-+ goto exit;
-+
-+ /* Workaround to enable AZ transmitting ability */
-+ val = __phy_package_read_mmd(phydev, QCA807X_PQSGMII_ADDR,
-+ MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL);
-+ val &= ~PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK;
-+ ret = __phy_package_write_mmd(phydev, QCA807X_PQSGMII_ADDR,
-+ MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL, val);
-+ if (ret)
-+ goto exit;
-+
-+ /* Set PQSGMII TX AMP strength */
-+ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR,
-+ PQSGMII_DRIVE_CONTROL_1);
-+ val &= ~PQSGMII_TX_DRIVER_MASK;
-+ val |= FIELD_PREP(PQSGMII_TX_DRIVER_MASK, priv->tx_drive_strength);
-+ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR,
-+ PQSGMII_DRIVE_CONTROL_1, val);
-+ if (ret)
-+ goto exit;
-+
-+ /* Prevent PSGMII going into hibernation via PSGMII self test */
-+ val = __phy_package_read_mmd(phydev, QCA807X_COMBO_ADDR,
-+ MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL);
-+ val &= ~BIT(1);
-+ ret = __phy_package_write_mmd(phydev, QCA807X_COMBO_ADDR,
-+ MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL, val);
-+
-+exit:
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
-+static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+{
-+ struct phy_device *phydev = upstream;
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
-+ phy_interface_t iface;
-+ int ret;
-+ DECLARE_PHY_INTERFACE_MASK(interfaces);
-+
-+ sfp_parse_support(phydev->sfp_bus, id, support, interfaces);
-+ iface = sfp_select_interface(phydev->sfp_bus, support);
-+
-+ dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface));
-+
-+ switch (iface) {
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_100BASEX:
-+ /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */
-+ ret = phy_modify(phydev,
-+ QCA807X_CHIP_CONFIGURATION,
-+ QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK,
-+ QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER);
-+ /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */
-+ ret = phy_set_bits_mmd(phydev,
-+ MDIO_MMD_AN,
-+ QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION,
-+ QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN);
-+ /* Select fiber page */
-+ ret = phy_clear_bits(phydev,
-+ QCA807X_CHIP_CONFIGURATION,
-+ QCA807X_BT_BX_REG_SEL);
-+
-+ phydev->port = PORT_FIBRE;
-+ break;
-+ default:
-+ dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n");
-+ return -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static void qca807x_sfp_remove(void *upstream)
-+{
-+ struct phy_device *phydev = upstream;
-+
-+ /* Select copper page */
-+ phy_set_bits(phydev,
-+ QCA807X_CHIP_CONFIGURATION,
-+ QCA807X_BT_BX_REG_SEL);
-+
-+ phydev->port = PORT_TP;
-+}
-+
-+static const struct sfp_upstream_ops qca807x_sfp_ops = {
-+ .attach = phy_sfp_attach,
-+ .detach = phy_sfp_detach,
-+ .module_insert = qca807x_sfp_insert,
-+ .module_remove = qca807x_sfp_remove,
-+};
-+
-+static int qca807x_probe(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ struct qca807x_shared_priv *shared_priv;
-+ struct device *dev = &phydev->mdio.dev;
-+ struct phy_package_shared *shared;
-+ struct qca807x_priv *priv;
-+ int ret;
-+
-+ ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv));
-+ if (ret)
-+ return ret;
-+
-+ if (phy_package_probe_once(phydev)) {
-+ ret = qca807x_phy_package_probe_once(phydev);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ shared = phydev->shared;
-+ shared_priv = shared->priv;
-+
-+ /* Make sure PHY follow PHY package mode if enforced */
-+ if (shared_priv->package_mode != PHY_INTERFACE_MODE_NA &&
-+ phydev->interface != shared_priv->package_mode)
-+ return -EINVAL;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->dac_full_amplitude = of_property_read_bool(node, "qcom,dac-full-amplitude");
-+ priv->dac_full_bias_current = of_property_read_bool(node, "qcom,dac-full-bias-current");
-+ priv->dac_disable_bias_current_tweak = of_property_read_bool(node,
-+ "qcom,dac-disable-bias-current-tweak");
-+
-+ if (IS_ENABLED(CONFIG_GPIOLIB)) {
-+ /* Do not register a GPIO controller unless flagged for it */
-+ if (of_property_read_bool(node, "gpio-controller")) {
-+ ret = qca807x_gpio(phydev);
-+ if (ret)
-+ return ret;
-+ }
-+ }
-+
-+ /* Attach SFP bus on combo port*/
-+ if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) {
-+ ret = phy_sfp_probe(phydev, &qca807x_sfp_ops);
-+ if (ret)
-+ return ret;
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising);
-+ }
-+
-+ phydev->priv = priv;
-+
-+ return 0;
-+}
-+
-+static int qca807x_config_init(struct phy_device *phydev)
-+{
-+ struct qca807x_priv *priv = phydev->priv;
-+ u16 control_dac;
-+ int ret;
-+
-+ if (phy_package_init_once(phydev)) {
-+ ret = qca807x_phy_package_config_init_once(phydev);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ control_dac = phy_read_mmd(phydev, MDIO_MMD_AN,
-+ QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH);
-+ control_dac &= ~QCA807X_CONTROL_DAC_MASK;
-+ if (!priv->dac_full_amplitude)
-+ control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE;
-+ if (!priv->dac_full_amplitude)
-+ control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT;
-+ if (!priv->dac_disable_bias_current_tweak)
-+ control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK;
-+ return phy_write_mmd(phydev, MDIO_MMD_AN,
-+ QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH,
-+ control_dac);
-+}
-+
-+static struct phy_driver qca807x_drivers[] = {
-+ {
-+ PHY_ID_MATCH_EXACT(PHY_ID_QCA8072),
-+ .name = "Qualcomm QCA8072",
-+ .flags = PHY_POLL_CABLE_TEST,
-+ /* PHY_GBIT_FEATURES */
-+ .probe = qca807x_probe,
-+ .config_init = qca807x_config_init,
-+ .read_status = qca807x_read_status,
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .soft_reset = genphy_soft_reset,
-+ .get_tunable = at803x_get_tunable,
-+ .set_tunable = at803x_set_tunable,
-+ .resume = genphy_resume,
-+ .suspend = genphy_suspend,
-+ .cable_test_start = qca807x_cable_test_start,
-+ .cable_test_get_status = qca808x_cable_test_get_status,
-+ },
-+ {
-+ PHY_ID_MATCH_EXACT(PHY_ID_QCA8075),
-+ .name = "Qualcomm QCA8075",
-+ .flags = PHY_POLL_CABLE_TEST,
-+ /* PHY_GBIT_FEATURES */
-+ .probe = qca807x_probe,
-+ .config_init = qca807x_config_init,
-+ .read_status = qca807x_read_status,
-+ .config_intr = at803x_config_intr,
-+ .handle_interrupt = at803x_handle_interrupt,
-+ .soft_reset = genphy_soft_reset,
-+ .get_tunable = at803x_get_tunable,
-+ .set_tunable = at803x_set_tunable,
-+ .resume = genphy_resume,
-+ .suspend = genphy_suspend,
-+ .cable_test_start = qca807x_cable_test_start,
-+ .cable_test_get_status = qca808x_cable_test_get_status,
-+ },
-+};
-+module_phy_driver(qca807x_drivers);
-+
-+static struct mdio_device_id __maybe_unused qca807x_tbl[] = {
-+ { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) },
-+ { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) },
-+ { }
-+};
-+
-+MODULE_AUTHOR("Robert Marko <robert.marko@sartura.hr>");
-+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
-+MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver");
-+MODULE_DEVICE_TABLE(mdio, qca807x_tbl);
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch b/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch
deleted file mode 100644
index cf4d74e8c5..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From ee9d9807bee0e6af8ca2a4db6f0d1dc0e5b41f44 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 6 Feb 2024 18:31:11 +0100
-Subject: [PATCH 08/10] net: phy: qcom: move common qca808x LED define to
- shared header
-
-The LED implementation of qca808x and qca807x is the same but qca807x
-supports also Fiber port and have different hw control bits for Fiber
-port.
-
-In preparation for qca807x introduction, move all the common define to
-shared header.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/qca808x.c | 65 ----------------------------------
- drivers/net/phy/qcom/qcom.h | 65 ++++++++++++++++++++++++++++++++++
- 2 files changed, 65 insertions(+), 65 deletions(-)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -62,29 +62,6 @@
- #define QCA808X_DBG_AN_TEST 0xb
- #define QCA808X_HIBERNATION_EN BIT(15)
-
--#define QCA808X_MMD7_LED_GLOBAL 0x8073
--#define QCA808X_LED_BLINK_1 GENMASK(11, 6)
--#define QCA808X_LED_BLINK_2 GENMASK(5, 0)
--/* Values are the same for both BLINK_1 and BLINK_2 */
--#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3)
--#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
--#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
--#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
--#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
--#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
--#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
--#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
--#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
--#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0)
--#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
--#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
--#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
--#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
--#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
--#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
--#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
--#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
--
- #define QCA808X_MMD7_LED2_CTRL 0x8074
- #define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075
- #define QCA808X_MMD7_LED1_CTRL 0x8076
-@@ -92,51 +69,9 @@
- #define QCA808X_MMD7_LED0_CTRL 0x8078
- #define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2))
-
--/* LED hw control pattern is the same for every LED */
--#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0)
--#define QCA808X_LED_SPEED2500_ON BIT(15)
--#define QCA808X_LED_SPEED2500_BLINK BIT(14)
--/* Follow blink trigger even if duplex or speed condition doesn't match */
--#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13)
--#define QCA808X_LED_FULL_DUPLEX_ON BIT(12)
--#define QCA808X_LED_HALF_DUPLEX_ON BIT(11)
--#define QCA808X_LED_TX_BLINK BIT(10)
--#define QCA808X_LED_RX_BLINK BIT(9)
--#define QCA808X_LED_TX_ON_10MS BIT(8)
--#define QCA808X_LED_RX_ON_10MS BIT(7)
--#define QCA808X_LED_SPEED1000_ON BIT(6)
--#define QCA808X_LED_SPEED100_ON BIT(5)
--#define QCA808X_LED_SPEED10_ON BIT(4)
--#define QCA808X_LED_COLLISION_BLINK BIT(3)
--#define QCA808X_LED_SPEED1000_BLINK BIT(2)
--#define QCA808X_LED_SPEED100_BLINK BIT(1)
--#define QCA808X_LED_SPEED10_BLINK BIT(0)
--
- #define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079
- #define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2))
-
--/* LED force ctrl is the same for every LED
-- * No documentation exist for this, not even internal one
-- * with NDA as QCOM gives only info about configuring
-- * hw control pattern rules and doesn't indicate any way
-- * to force the LED to specific mode.
-- * These define comes from reverse and testing and maybe
-- * lack of some info or some info are not entirely correct.
-- * For the basic LED control and hw control these finding
-- * are enough to support LED control in all the required APIs.
-- *
-- * On doing some comparison with implementation with qca807x,
-- * it was found that it's 1:1 equal to it and confirms all the
-- * reverse done. It was also found further specification with the
-- * force mode and the blink modes.
-- */
--#define QCA808X_LED_FORCE_EN BIT(15)
--#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13)
--#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
--#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
--#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
--#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
--
- #define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a
- /* QSDK sets by default 0x46 to this reg that sets BIT 6 for
- * LED to active high. It's not clear what BIT 3 and BIT 4 does.
---- a/drivers/net/phy/qcom/qcom.h
-+++ b/drivers/net/phy/qcom/qcom.h
-@@ -103,6 +103,71 @@
- /* Added for reference of existence but should be handled by wait_for_completion already */
- #define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
-
-+#define QCA808X_MMD7_LED_GLOBAL 0x8073
-+#define QCA808X_LED_BLINK_1 GENMASK(11, 6)
-+#define QCA808X_LED_BLINK_2 GENMASK(5, 0)
-+/* Values are the same for both BLINK_1 and BLINK_2 */
-+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3)
-+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
-+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
-+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
-+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
-+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
-+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
-+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
-+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
-+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0)
-+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
-+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
-+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
-+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
-+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
-+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
-+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
-+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
-+
-+/* LED hw control pattern is the same for every LED */
-+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0)
-+#define QCA808X_LED_SPEED2500_ON BIT(15)
-+#define QCA808X_LED_SPEED2500_BLINK BIT(14)
-+/* Follow blink trigger even if duplex or speed condition doesn't match */
-+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13)
-+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12)
-+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11)
-+#define QCA808X_LED_TX_BLINK BIT(10)
-+#define QCA808X_LED_RX_BLINK BIT(9)
-+#define QCA808X_LED_TX_ON_10MS BIT(8)
-+#define QCA808X_LED_RX_ON_10MS BIT(7)
-+#define QCA808X_LED_SPEED1000_ON BIT(6)
-+#define QCA808X_LED_SPEED100_ON BIT(5)
-+#define QCA808X_LED_SPEED10_ON BIT(4)
-+#define QCA808X_LED_COLLISION_BLINK BIT(3)
-+#define QCA808X_LED_SPEED1000_BLINK BIT(2)
-+#define QCA808X_LED_SPEED100_BLINK BIT(1)
-+#define QCA808X_LED_SPEED10_BLINK BIT(0)
-+
-+/* LED force ctrl is the same for every LED
-+ * No documentation exist for this, not even internal one
-+ * with NDA as QCOM gives only info about configuring
-+ * hw control pattern rules and doesn't indicate any way
-+ * to force the LED to specific mode.
-+ * These define comes from reverse and testing and maybe
-+ * lack of some info or some info are not entirely correct.
-+ * For the basic LED control and hw control these finding
-+ * are enough to support LED control in all the required APIs.
-+ *
-+ * On doing some comparison with implementation with qca807x,
-+ * it was found that it's 1:1 equal to it and confirms all the
-+ * reverse done. It was also found further specification with the
-+ * force mode and the blink modes.
-+ */
-+#define QCA808X_LED_FORCE_EN BIT(15)
-+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13)
-+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
-+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
-+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
-+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
-+
- #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
- #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
- #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
diff --git a/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch b/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch
deleted file mode 100644
index da73c1d3b8..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 47b930d0dd437af927145dba50a2e2ea1ba97c67 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 6 Feb 2024 18:31:12 +0100
-Subject: [PATCH 09/10] net: phy: qcom: generalize some qca808x LED functions
-
-Generalize some qca808x LED functions in preparation for qca807x LED
-support.
-
-The LED implementation of qca808x and qca807x is the same but qca807x
-supports also Fiber port and have different hw control bits for Fiber
-port. To limit code duplication introduce micro functions that takes reg
-instead of LED index to tweak all the supported LED modes.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/qca808x.c | 38 +++-----------------
- drivers/net/phy/qcom/qcom-phy-lib.c | 54 +++++++++++++++++++++++++++++
- drivers/net/phy/qcom/qcom.h | 7 ++++
- 3 files changed, 65 insertions(+), 34 deletions(-)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -437,9 +437,7 @@ static int qca808x_led_hw_control_enable
- return -EINVAL;
-
- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN);
-+ return qca808x_led_reg_hw_control_enable(phydev, reg);
- }
-
- static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-@@ -480,16 +478,12 @@ static int qca808x_led_hw_control_set(st
- static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
- {
- u16 reg;
-- int val;
-
- if (index > 2)
- return false;
-
- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
--
-- return !(val & QCA808X_LED_FORCE_EN);
-+ return qca808x_led_reg_hw_control_status(phydev, reg);
- }
-
- static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
-@@ -557,44 +551,20 @@ static int qca808x_led_brightness_set(st
- }
-
- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-- QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON :
-- QCA808X_LED_FORCE_OFF));
-+ return qca808x_led_reg_brightness_set(phydev, reg, value);
- }
-
- static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
- unsigned long *delay_on,
- unsigned long *delay_off)
- {
-- int ret;
- u16 reg;
-
- if (index > 2)
- return -EINVAL;
-
- reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
--
-- /* Set blink to 50% off, 50% on at 4Hz by default */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
-- QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
-- QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
-- if (ret)
-- return ret;
--
-- /* We use BLINK_1 for normal blinking */
-- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
-- if (ret)
-- return ret;
--
-- /* We set blink to 4Hz, aka 250ms */
-- *delay_on = 250 / 2;
-- *delay_off = 250 / 2;
--
-- return 0;
-+ return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off);
- }
-
- static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
---- a/drivers/net/phy/qcom/qcom-phy-lib.c
-+++ b/drivers/net/phy/qcom/qcom-phy-lib.c
-@@ -620,3 +620,57 @@ int qca808x_cable_test_get_status(struct
- return 0;
- }
- EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status);
-+
-+int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg)
-+{
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN);
-+}
-+EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_enable);
-+
-+bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg)
-+{
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+ return !(val & QCA808X_LED_FORCE_EN);
-+}
-+EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_status);
-+
-+int qca808x_led_reg_brightness_set(struct phy_device *phydev,
-+ u16 reg, enum led_brightness value)
-+{
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON :
-+ QCA808X_LED_FORCE_OFF));
-+}
-+EXPORT_SYMBOL_GPL(qca808x_led_reg_brightness_set);
-+
-+int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ int ret;
-+
-+ /* Set blink to 50% off, 50% on at 4Hz by default */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
-+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
-+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
-+ if (ret)
-+ return ret;
-+
-+ /* We use BLINK_1 for normal blinking */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
-+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
-+ if (ret)
-+ return ret;
-+
-+ /* We set blink to 4Hz, aka 250ms */
-+ *delay_on = 250 / 2;
-+ *delay_off = 250 / 2;
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(qca808x_led_reg_blink_set);
---- a/drivers/net/phy/qcom/qcom.h
-+++ b/drivers/net/phy/qcom/qcom.h
-@@ -234,3 +234,10 @@ int at803x_cdt_start(struct phy_device *
- int at803x_cdt_wait_for_completion(struct phy_device *phydev,
- u32 cdt_en);
- int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished);
-+int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg);
-+bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg);
-+int qca808x_led_reg_brightness_set(struct phy_device *phydev,
-+ u16 reg, enum led_brightness value);
-+int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off);
diff --git a/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch b/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch
deleted file mode 100644
index 3bd36f6ffe..0000000000
--- a/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch
+++ /dev/null
@@ -1,326 +0,0 @@
-From f508a226b517a6a8afd78a317de46bc83e3e3d51 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 6 Feb 2024 18:31:13 +0100
-Subject: [PATCH 10/10] net: phy: qca807x: add support for configurable LED
-
-QCA8072/5 have up to 2 LEDs attached for PHY.
-
-LEDs can be configured to be ON/hw blink or be set to HW control.
-
-Hw blink mode is set to blink at 4Hz or 250ms.
-
-PHY can support both copper (TP) or fiber (FIBRE) kind and supports
-different HW control modes based on the port type.
-
-HW control modes supported for netdev trigger for copper ports are:
-- LINK_10
-- LINK_100
-- LINK_1000
-- TX
-- RX
-- FULL_DUPLEX
-- HALF_DUPLEX
-
-HW control modes supported for netdev trigger for fiber ports are:
-- LINK_100
-- LINK_1000
-- TX
-- RX
-- FULL_DUPLEX
-- HALF_DUPLEX
-
-LED support conflicts with GPIO controller feature and must be disabled
-if gpio-controller is used for the PHY.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/qca807x.c | 256 ++++++++++++++++++++++++++++++++-
- 1 file changed, 254 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/qcom/qca807x.c
-+++ b/drivers/net/phy/qcom/qca807x.c
-@@ -57,8 +57,18 @@
- #define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2))
- #define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2))
-
--#define QCA807X_GPIO_FORCE_EN BIT(15)
--#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13)
-+/* LED hw control pattern for fiber port */
-+#define QCA807X_LED_FIBER_PATTERN_MASK GENMASK(11, 1)
-+#define QCA807X_LED_FIBER_TXACT_BLK_EN BIT(10)
-+#define QCA807X_LED_FIBER_RXACT_BLK_EN BIT(9)
-+#define QCA807X_LED_FIBER_FDX_ON_EN BIT(6)
-+#define QCA807X_LED_FIBER_HDX_ON_EN BIT(5)
-+#define QCA807X_LED_FIBER_1000BX_ON_EN BIT(2)
-+#define QCA807X_LED_FIBER_100FX_ON_EN BIT(1)
-+
-+/* Some device repurpose the LED as GPIO out */
-+#define QCA807X_GPIO_FORCE_EN QCA808X_LED_FORCE_EN
-+#define QCA807X_GPIO_FORCE_MODE_MASK QCA808X_LED_FORCE_MODE_MASK
-
- #define QCA807X_FUNCTION_CONTROL 0x10
- #define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5)
-@@ -121,6 +131,233 @@ static int qca807x_cable_test_start(stru
- return 0;
- }
-
-+static int qca807x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
-+ u16 *offload_trigger)
-+{
-+ /* Parsing specific to netdev trigger */
-+ switch (phydev->port) {
-+ case PORT_TP:
-+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
-+ *offload_trigger |= QCA808X_LED_TX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
-+ *offload_trigger |= QCA808X_LED_RX_BLINK;
-+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED10_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED100_ON;
-+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+ *offload_trigger |= QCA808X_LED_SPEED1000_ON;
-+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
-+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
-+ break;
-+ case PORT_FIBRE:
-+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
-+ *offload_trigger |= QCA807X_LED_FIBER_TXACT_BLK_EN;
-+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
-+ *offload_trigger |= QCA807X_LED_FIBER_RXACT_BLK_EN;
-+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+ *offload_trigger |= QCA807X_LED_FIBER_100FX_ON_EN;
-+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+ *offload_trigger |= QCA807X_LED_FIBER_1000BX_ON_EN;
-+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-+ *offload_trigger |= QCA807X_LED_FIBER_HDX_ON_EN;
-+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-+ *offload_trigger |= QCA807X_LED_FIBER_FDX_ON_EN;
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ if (rules && !*offload_trigger)
-+ return -EOPNOTSUPP;
-+
-+ return 0;
-+}
-+
-+static int qca807x_led_hw_control_enable(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 1)
-+ return -EINVAL;
-+
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
-+ return qca808x_led_reg_hw_control_enable(phydev, reg);
-+}
-+
-+static int qca807x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 offload_trigger = 0;
-+
-+ if (index > 1)
-+ return -EINVAL;
-+
-+ return qca807x_led_parse_netdev(phydev, rules, &offload_trigger);
-+}
-+
-+static int qca807x_led_hw_control_set(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ u16 reg, mask, offload_trigger = 0;
-+ int ret;
-+
-+ if (index > 1)
-+ return -EINVAL;
-+
-+ ret = qca807x_led_parse_netdev(phydev, rules, &offload_trigger);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca807x_led_hw_control_enable(phydev, index);
-+ if (ret)
-+ return ret;
-+
-+ switch (phydev->port) {
-+ case PORT_TP:
-+ reg = QCA807X_MMD7_LED_CTRL(index);
-+ mask = QCA808X_LED_PATTERN_MASK;
-+ break;
-+ case PORT_FIBRE:
-+ /* HW control pattern bits are in LED FORCE reg */
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
-+ mask = QCA807X_LED_FIBER_PATTERN_MASK;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, mask,
-+ offload_trigger);
-+}
-+
-+static bool qca807x_led_hw_control_status(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg;
-+
-+ if (index > 1)
-+ return false;
-+
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
-+ return qca808x_led_reg_hw_control_status(phydev, reg);
-+}
-+
-+static int qca807x_led_hw_control_get(struct phy_device *phydev, u8 index,
-+ unsigned long *rules)
-+{
-+ u16 reg;
-+ int val;
-+
-+ if (index > 1)
-+ return -EINVAL;
-+
-+ /* Check if we have hw control enabled */
-+ if (qca807x_led_hw_control_status(phydev, index))
-+ return -EINVAL;
-+
-+ /* Parsing specific to netdev trigger */
-+ switch (phydev->port) {
-+ case PORT_TP:
-+ reg = QCA807X_MMD7_LED_CTRL(index);
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+ if (val & QCA808X_LED_TX_BLINK)
-+ set_bit(TRIGGER_NETDEV_TX, rules);
-+ if (val & QCA808X_LED_RX_BLINK)
-+ set_bit(TRIGGER_NETDEV_RX, rules);
-+ if (val & QCA808X_LED_SPEED10_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+ if (val & QCA808X_LED_SPEED100_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+ if (val & QCA808X_LED_SPEED1000_ON)
-+ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+ if (val & QCA808X_LED_HALF_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-+ if (val & QCA808X_LED_FULL_DUPLEX_ON)
-+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
-+ break;
-+ case PORT_FIBRE:
-+ /* HW control pattern bits are in LED FORCE reg */
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
-+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
-+ if (val & QCA807X_LED_FIBER_TXACT_BLK_EN)
-+ set_bit(TRIGGER_NETDEV_TX, rules);
-+ if (val & QCA807X_LED_FIBER_RXACT_BLK_EN)
-+ set_bit(TRIGGER_NETDEV_RX, rules);
-+ if (val & QCA807X_LED_FIBER_100FX_ON_EN)
-+ set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+ if (val & QCA807X_LED_FIBER_1000BX_ON_EN)
-+ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+ if (val & QCA807X_LED_FIBER_HDX_ON_EN)
-+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-+ if (val & QCA807X_LED_FIBER_FDX_ON_EN)
-+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca807x_led_hw_control_reset(struct phy_device *phydev, u8 index)
-+{
-+ u16 reg, mask;
-+
-+ if (index > 1)
-+ return -EINVAL;
-+
-+ switch (phydev->port) {
-+ case PORT_TP:
-+ reg = QCA807X_MMD7_LED_CTRL(index);
-+ mask = QCA808X_LED_PATTERN_MASK;
-+ break;
-+ case PORT_FIBRE:
-+ /* HW control pattern bits are in LED FORCE reg */
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
-+ mask = QCA807X_LED_FIBER_PATTERN_MASK;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, mask);
-+}
-+
-+static int qca807x_led_brightness_set(struct phy_device *phydev,
-+ u8 index, enum led_brightness value)
-+{
-+ u16 reg;
-+ int ret;
-+
-+ if (index > 1)
-+ return -EINVAL;
-+
-+ /* If we are setting off the LED reset any hw control rule */
-+ if (!value) {
-+ ret = qca807x_led_hw_control_reset(phydev, index);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
-+ return qca808x_led_reg_brightness_set(phydev, reg, value);
-+}
-+
-+static int qca807x_led_blink_set(struct phy_device *phydev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ u16 reg;
-+
-+ if (index > 1)
-+ return -EINVAL;
-+
-+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
-+ return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off);
-+}
-+
- #ifdef CONFIG_GPIOLIB
- static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
- {
-@@ -496,6 +733,16 @@ static int qca807x_probe(struct phy_devi
- "qcom,dac-disable-bias-current-tweak");
-
- if (IS_ENABLED(CONFIG_GPIOLIB)) {
-+ /* Make sure we don't have mixed leds node and gpio-controller
-+ * to prevent registering leds and having gpio-controller usage
-+ * conflicting with them.
-+ */
-+ if (of_find_property(node, "leds", NULL) &&
-+ of_find_property(node, "gpio-controller", NULL)) {
-+ phydev_err(phydev, "Invalid property detected. LEDs and gpio-controller are mutually exclusive.");
-+ return -EINVAL;
-+ }
-+
- /* Do not register a GPIO controller unless flagged for it */
- if (of_property_read_bool(node, "gpio-controller")) {
- ret = qca807x_gpio(phydev);
-@@ -580,6 +827,11 @@ static struct phy_driver qca807x_drivers
- .suspend = genphy_suspend,
- .cable_test_start = qca807x_cable_test_start,
- .cable_test_get_status = qca808x_cable_test_get_status,
-+ .led_brightness_set = qca807x_led_brightness_set,
-+ .led_blink_set = qca807x_led_blink_set,
-+ .led_hw_is_supported = qca807x_led_hw_is_supported,
-+ .led_hw_control_set = qca807x_led_hw_control_set,
-+ .led_hw_control_get = qca807x_led_hw_control_get,
- },
- };
- module_phy_driver(qca807x_drivers);
diff --git a/target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch b/target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch
deleted file mode 100644
index 53652c38fc..0000000000
--- a/target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 3be0d950b62852a693182cb678948f481de02825 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Mon, 12 Feb 2024 12:49:34 +0100
-Subject: [PATCH] net: phy: qca807x: move interface mode check to
- .config_init_once
-
-Currently, we are checking whether the PHY package mode matches the
-individual PHY interface modes at PHY package probe time, but at that time
-we only know the PHY package mode and not the individual PHY interface
-modes as of_get_phy_mode() that populates it will only get called once the
-netdev to which PHY-s are attached to is being probed and thus this check
-will always fail and return -EINVAL.
-
-So, lets move this check to .config_init_once as at that point individual
-PHY interface modes should be populated.
-
-Fixes: d1cb613efbd3 ("net: phy: qcom: add support for QCA807x PHY Family")
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240212115043.1725918-1-robimarko@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/qcom/qca807x.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/qcom/qca807x.c
-+++ b/drivers/net/phy/qcom/qca807x.c
-@@ -562,6 +562,11 @@ static int qca807x_phy_package_config_in
- struct qca807x_shared_priv *priv = shared->priv;
- int val, ret;
-
-+ /* Make sure PHY follow PHY package mode if enforced */
-+ if (priv->package_mode != PHY_INTERFACE_MODE_NA &&
-+ phydev->interface != priv->package_mode)
-+ return -EINVAL;
-+
- phy_lock_mdio_bus(phydev);
-
- /* Set correct PHY package mode */
-@@ -718,11 +723,6 @@ static int qca807x_probe(struct phy_devi
- shared = phydev->shared;
- shared_priv = shared->priv;
-
-- /* Make sure PHY follow PHY package mode if enforced */
-- if (shared_priv->package_mode != PHY_INTERFACE_MODE_NA &&
-- phydev->interface != shared_priv->package_mode)
-- return -EINVAL;
--
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
diff --git a/target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch b/target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch
deleted file mode 100644
index 9b9ce2a3cd..0000000000
--- a/target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 6a4aee277740d04ac0fd54cfa17cc28261932ddc Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 25 Mar 2024 20:06:19 +0100
-Subject: [PATCH] net: phy: qcom: at803x: fix kernel panic with at8031_probe
-
-On reworking and splitting the at803x driver, in splitting function of
-at803x PHYs it was added a NULL dereference bug where priv is referenced
-before it's actually allocated and then is tried to write to for the
-is_1000basex and is_fiber variables in the case of at8031, writing on
-the wrong address.
-
-Fix this by correctly setting priv local variable only after
-at803x_probe is called and actually allocates priv in the phydev struct.
-
-Reported-by: William Wortel <wwortel@dorpstraat.com>
-Cc: <stable@vger.kernel.org>
-Fixes: 25d2ba94005f ("net: phy: at803x: move specific at8031 probe mode check to dedicated probe")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240325190621.2665-1-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/qcom/at803x.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -797,7 +797,7 @@ static int at8031_parse_dt(struct phy_de
-
- static int at8031_probe(struct phy_device *phydev)
- {
-- struct at803x_priv *priv = phydev->priv;
-+ struct at803x_priv *priv;
- int mode_cfg;
- int ccr;
- int ret;
-@@ -806,6 +806,8 @@ static int at8031_probe(struct phy_devic
- if (ret)
- return ret;
-
-+ priv = phydev->priv;
-+
- /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
- * options.
- */
diff --git a/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch b/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch
deleted file mode 100644
index e6a240dbda..0000000000
--- a/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From bdce82e960d1205d118662f575cec39379984e34 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 31 Jan 2024 03:26:04 +0100
-Subject: [PATCH] net: mdio: ipq4019: add support for clock-frequency property
-
-The IPQ4019 MDIO internally divide the clock feed by AHB based on the
-MDIO_MODE reg. On reset or power up, the default value for the
-divider is 0xff that reflect the divider set to /256.
-
-This makes the MDC run at a very low rate, that is, considering AHB is
-always fixed to 100Mhz, a value of 390KHz.
-
-This hasn't have been a problem as MDIO wasn't used for time sensitive
-operation, it is now that on IPQ807x is usually mounted with PHY that
-requires MDIO to load their firmware (example Aquantia PHY).
-
-To handle this problem and permit to set the correct designed MDC
-frequency for the SoC add support for the standard "clock-frequency"
-property for the MDIO node.
-
-The divider supports value from /1 to /256 and the common value are to
-set it to /16 to reflect 6.25Mhz or to /8 on newer platform to reflect
-12.5Mhz.
-
-To scan if the requested rate is supported by the divider, loop with
-each supported divider and stop when the requested rate match the final
-rate with the current divider. An error is returned if the rate doesn't
-match any value.
-
-On MDIO reset, the divider is restored to the requested value to prevent
-any kind of downclocking caused by the divider reverting to a default
-value.
-
-To follow 802.3 spec of 2.5MHz of default value, if divider is set at
-/256 and "clock-frequency" is not set in DT, assume nobody set the
-divider and try to find the closest MDC rate to 2.5MHz. (in the case of
-AHB set to 100MHz, it's 1.5625MHz)
-
-While at is also document other bits of the MDIO_MODE reg to have a
-clear idea of what is actually applied there.
-
-Documentation of some BITs is skipped as they are marked as reserved and
-their usage is not clear (RES 11:9 GENPHY 16:13 RES1 19:17)
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/mdio/mdio-ipq4019.c | 109 ++++++++++++++++++++++++++++++--
- 1 file changed, 103 insertions(+), 6 deletions(-)
-
---- a/drivers/net/mdio/mdio-ipq4019.c
-+++ b/drivers/net/mdio/mdio-ipq4019.c
-@@ -14,6 +14,20 @@
- #include <linux/clk.h>
-
- #define MDIO_MODE_REG 0x40
-+#define MDIO_MODE_MDC_MODE BIT(12)
-+/* 0 = Clause 22, 1 = Clause 45 */
-+#define MDIO_MODE_C45 BIT(8)
-+#define MDIO_MODE_DIV_MASK GENMASK(7, 0)
-+#define MDIO_MODE_DIV(x) FIELD_PREP(MDIO_MODE_DIV_MASK, (x) - 1)
-+#define MDIO_MODE_DIV_1 0x0
-+#define MDIO_MODE_DIV_2 0x1
-+#define MDIO_MODE_DIV_4 0x3
-+#define MDIO_MODE_DIV_8 0x7
-+#define MDIO_MODE_DIV_16 0xf
-+#define MDIO_MODE_DIV_32 0x1f
-+#define MDIO_MODE_DIV_64 0x3f
-+#define MDIO_MODE_DIV_128 0x7f
-+#define MDIO_MODE_DIV_256 0xff
- #define MDIO_ADDR_REG 0x44
- #define MDIO_DATA_WRITE_REG 0x48
- #define MDIO_DATA_READ_REG 0x4c
-@@ -26,9 +40,6 @@
- #define MDIO_CMD_ACCESS_CODE_C45_WRITE 1
- #define MDIO_CMD_ACCESS_CODE_C45_READ 2
-
--/* 0 = Clause 22, 1 = Clause 45 */
--#define MDIO_MODE_C45 BIT(8)
--
- #define IPQ4019_MDIO_TIMEOUT 10000
- #define IPQ4019_MDIO_SLEEP 10
-
-@@ -41,6 +52,7 @@ struct ipq4019_mdio_data {
- void __iomem *membase;
- void __iomem *eth_ldo_rdy;
- struct clk *mdio_clk;
-+ unsigned int mdc_rate;
- };
-
- static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
-@@ -179,6 +191,38 @@ static int ipq4019_mdio_write(struct mii
- return 0;
- }
-
-+static int ipq4019_mdio_set_div(struct ipq4019_mdio_data *priv)
-+{
-+ unsigned long ahb_rate;
-+ int div;
-+ u32 val;
-+
-+ /* If we don't have a clock for AHB use the fixed value */
-+ ahb_rate = IPQ_MDIO_CLK_RATE;
-+ if (priv->mdio_clk)
-+ ahb_rate = clk_get_rate(priv->mdio_clk);
-+
-+ /* MDC rate is ahb_rate/(MDIO_MODE_DIV + 1)
-+ * While supported, internal documentation doesn't
-+ * assure correct functionality of the MDIO bus
-+ * with divider of 1, 2 or 4.
-+ */
-+ for (div = 8; div <= 256; div *= 2) {
-+ /* The requested rate is supported by the div */
-+ if (priv->mdc_rate == DIV_ROUND_UP(ahb_rate, div)) {
-+ val = readl(priv->membase + MDIO_MODE_REG);
-+ val &= ~MDIO_MODE_DIV_MASK;
-+ val |= MDIO_MODE_DIV(div);
-+ writel(val, priv->membase + MDIO_MODE_REG);
-+
-+ return 0;
-+ }
-+ }
-+
-+ /* The requested rate is not supported */
-+ return -EINVAL;
-+}
-+
- static int ipq_mdio_reset(struct mii_bus *bus)
- {
- struct ipq4019_mdio_data *priv = bus->priv;
-@@ -201,10 +245,58 @@ static int ipq_mdio_reset(struct mii_bus
- return ret;
-
- ret = clk_prepare_enable(priv->mdio_clk);
-- if (ret == 0)
-- mdelay(10);
-+ if (ret)
-+ return ret;
-+
-+ mdelay(10);
-
-- return ret;
-+ /* Restore MDC rate */
-+ return ipq4019_mdio_set_div(priv);
-+}
-+
-+static void ipq4019_mdio_select_mdc_rate(struct platform_device *pdev,
-+ struct ipq4019_mdio_data *priv)
-+{
-+ unsigned long ahb_rate;
-+ int div;
-+ u32 val;
-+
-+ /* MDC rate defined in DT, we don't have to decide a default value */
-+ if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
-+ &priv->mdc_rate))
-+ return;
-+
-+ /* If we don't have a clock for AHB use the fixed value */
-+ ahb_rate = IPQ_MDIO_CLK_RATE;
-+ if (priv->mdio_clk)
-+ ahb_rate = clk_get_rate(priv->mdio_clk);
-+
-+ /* Check what is the current div set */
-+ val = readl(priv->membase + MDIO_MODE_REG);
-+ div = FIELD_GET(MDIO_MODE_DIV_MASK, val);
-+
-+ /* div is not set to the default value of /256
-+ * Probably someone changed that (bootloader, other drivers)
-+ * Keep this and don't overwrite it.
-+ */
-+ if (div != MDIO_MODE_DIV_256) {
-+ priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div + 1);
-+ return;
-+ }
-+
-+ /* If div is /256 assume nobody have set this value and
-+ * try to find one MDC rate that is close the 802.3 spec of
-+ * 2.5MHz
-+ */
-+ for (div = 256; div >= 8; div /= 2) {
-+ /* Stop as soon as we found a divider that
-+ * reached the closest value to 2.5MHz
-+ */
-+ if (DIV_ROUND_UP(ahb_rate, div) > 2500000)
-+ break;
-+
-+ priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div);
-+ }
- }
-
- static int ipq4019_mdio_probe(struct platform_device *pdev)
-@@ -228,6 +320,11 @@ static int ipq4019_mdio_probe(struct pla
- if (IS_ERR(priv->mdio_clk))
- return PTR_ERR(priv->mdio_clk);
-
-+ ipq4019_mdio_select_mdc_rate(pdev, priv);
-+ ret = ipq4019_mdio_set_div(priv);
-+ if (ret)
-+ return ret;
-+
- /* The platform resource is provided on the chipset IPQ5018 */
- /* This resource is optional */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
diff --git a/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch b/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch
deleted file mode 100644
index d32a7edf93..0000000000
--- a/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 7edce370d87a23e8ed46af5b76a9fef1e341b67b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 28 Nov 2023 14:59:28 +0100
-Subject: [PATCH] net: phy: aquantia: drop wrong endianness conversion for addr
- and CRC
-
-On further testing on BE target with kernel test robot, it was notice
-that the endianness conversion for addr and CRC in fw_load_memory was
-wrong.
-
-Drop the cpu_to_le32 conversion for addr load as it's not needed.
-
-Use get_unaligned_le32 instead of get_unaligned for FW data word load to
-correctly convert data in the correct order to follow system endian.
-
-Also drop the cpu_to_be32 for CRC calculation as it's wrong and would
-cause different CRC on BE system.
-The loaded word is swapped internally and MAILBOX calculates the CRC on
-the swapped word. To correctly calculate the CRC to be later matched
-with the one from MAILBOX, use an u8 struct and swap the word there to
-keep the same order on both LE and BE for crc_ccitt_false function.
-Also add additional comments on how the CRC verification for the loaded
-section works.
-
-CRC is calculated as we load the section and verified with the MAILBOX
-only after the entire section is loaded to skip additional slowdown by
-loop the section data again.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Closes: https://lore.kernel.org/oe-kbuild-all/202311210414.sEJZjlcD-lkp@intel.com/
-Fixes: e93984ebc1c8 ("net: phy: aquantia: add firmware load support")
-Tested-by: Robert Marko <robimarko@gmail.com> # ipq8072 LE device
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://lore.kernel.org/r/20231128135928.9841-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/aquantia/aquantia_firmware.c | 24 ++++++++++++--------
- 1 file changed, 14 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/aquantia/aquantia_firmware.c
-+++ b/drivers/net/phy/aquantia/aquantia_firmware.c
-@@ -93,9 +93,6 @@ static int aqr_fw_load_memory(struct phy
- u16 crc = 0, up_crc;
- size_t pos;
-
-- /* PHY expect addr in LE */
-- addr = (__force u32)cpu_to_le32(addr);
--
- phy_write_mmd(phydev, MDIO_MMD_VEND1,
- VEND1_GLOBAL_MAILBOX_INTERFACE1,
- VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET);
-@@ -110,10 +107,11 @@ static int aqr_fw_load_memory(struct phy
- * If a firmware that is not word aligned is found, please report upstream.
- */
- for (pos = 0; pos < len; pos += sizeof(u32)) {
-+ u8 crc_data[4];
- u32 word;
-
- /* FW data is always stored in little-endian */
-- word = get_unaligned((const u32 *)(data + pos));
-+ word = get_unaligned_le32((const u32 *)(data + pos));
-
- phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5,
- VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word));
-@@ -124,15 +122,21 @@ static int aqr_fw_load_memory(struct phy
- VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE |
- VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE);
-
-- /* calculate CRC as we load data to the mailbox.
-- * We convert word to big-endian as PHY is BE and mailbox will
-- * return a BE CRC.
-+ /* Word is swapped internally and MAILBOX CRC is calculated
-+ * using big-endian order. Mimic what the PHY does to have a
-+ * matching CRC...
- */
-- word = (__force u32)cpu_to_be32(word);
-- crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word));
-- }
-+ crc_data[0] = word >> 24;
-+ crc_data[1] = word >> 16;
-+ crc_data[2] = word >> 8;
-+ crc_data[3] = word;
-
-+ /* ...calculate CRC as we load data... */
-+ crc = crc_ccitt_false(crc, crc_data, sizeof(crc_data));
-+ }
-+ /* ...gets CRC from MAILBOX after we have loaded the entire section... */
- up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2);
-+ /* ...and make sure it does match our calculated CRC */
- if (crc != up_crc) {
- phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n",
- crc, up_crc);
diff --git a/target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch b/target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch
deleted file mode 100644
index cf0d2a3a89..0000000000
--- a/target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 1b9827ceab08450308f7971d6fd700ec88b6ce67 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 3 Dec 2022 14:20:37 +0100
-Subject: [PATCH 098/250] net: mtk_eth_soc: enable flow offload support for
- MT7986 SoC
-
-Since Wireless Ethernet Dispatcher is now available for mt7986 in mt76,
-enable hw flow support for MT7986 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/fdcaacd827938e6a8c4aa1ac2c13e46d2c08c821.1670072898.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4332,6 +4332,7 @@ static const struct mtk_soc_data mt7986_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7986_CLKS_BITMAP,
- .required_pctl = false,
-+ .offload_version = 2,
- .hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
- .txrx = {
diff --git a/target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch b/target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch
deleted file mode 100644
index c48613929d..0000000000
--- a/target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch
+++ /dev/null
@@ -1,591 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Sat, 5 Nov 2022 23:36:18 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: introduce wed mcu support
-
-Introduce WED mcu support used to configure WED WO chip.
-This is a preliminary patch in order to add RX Wireless
-Ethernet Dispatch available on MT7986 SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.h
-
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,7 +5,7 @@
-
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
- mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
--mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o
-+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o
- ifdef CONFIG_DEBUG_FS
- mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
- endif
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -0,0 +1,359 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2022 MediaTek Inc.
-+ *
-+ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
-+ * Sujuan Chen <sujuan.chen@mediatek.com>
-+ */
-+
-+#include <linux/firmware.h>
-+#include <linux/of_address.h>
-+#include <linux/of_reserved_mem.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/soc/mediatek/mtk_wed.h>
-+
-+#include "mtk_wed_regs.h"
-+#include "mtk_wed_wo.h"
-+#include "mtk_wed.h"
-+
-+static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
-+{
-+ return readl(wo->boot.addr + reg);
-+}
-+
-+static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
-+{
-+ writel(val, wo->boot.addr + reg);
-+}
-+
-+static struct sk_buff *
-+mtk_wed_mcu_msg_alloc(const void *data, int data_len)
-+{
-+ int length = sizeof(struct mtk_wed_mcu_hdr) + data_len;
-+ struct sk_buff *skb;
-+
-+ skb = alloc_skb(length, GFP_KERNEL);
-+ if (!skb)
-+ return NULL;
-+
-+ memset(skb->head, 0, length);
-+ skb_reserve(skb, sizeof(struct mtk_wed_mcu_hdr));
-+ if (data && data_len)
-+ skb_put_data(skb, data, data_len);
-+
-+ return skb;
-+}
-+
-+static struct sk_buff *
-+mtk_wed_mcu_get_response(struct mtk_wed_wo *wo, unsigned long expires)
-+{
-+ if (!time_is_after_jiffies(expires))
-+ return NULL;
-+
-+ wait_event_timeout(wo->mcu.wait, !skb_queue_empty(&wo->mcu.res_q),
-+ expires - jiffies);
-+ return skb_dequeue(&wo->mcu.res_q);
-+}
-+
-+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb)
-+{
-+ skb_queue_tail(&wo->mcu.res_q, skb);
-+ wake_up(&wo->mcu.wait);
-+}
-+
-+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo,
-+ struct sk_buff *skb)
-+{
-+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+
-+ switch (hdr->cmd) {
-+ case MTK_WED_WO_EVT_LOG_DUMP: {
-+ const char *msg = (const char *)(skb->data + sizeof(*hdr));
-+
-+ dev_notice(wo->hw->dev, "%s\n", msg);
-+ break;
-+ }
-+ case MTK_WED_WO_EVT_PROFILING: {
-+ struct mtk_wed_wo_log_info *info;
-+ u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info);
-+ int i;
-+
-+ info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr));
-+ for (i = 0 ; i < count ; i++)
-+ dev_notice(wo->hw->dev,
-+ "SN:%u latency: total=%u, rro:%u, mod:%u\n",
-+ le32_to_cpu(info[i].sn),
-+ le32_to_cpu(info[i].total),
-+ le32_to_cpu(info[i].rro),
-+ le32_to_cpu(info[i].mod));
-+ break;
-+ }
-+ case MTK_WED_WO_EVT_RXCNT_INFO:
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dev_kfree_skb(skb);
-+}
-+
-+static int
-+mtk_wed_mcu_skb_send_msg(struct mtk_wed_wo *wo, struct sk_buff *skb,
-+ int id, int cmd, u16 *wait_seq, bool wait_resp)
-+{
-+ struct mtk_wed_mcu_hdr *hdr;
-+
-+ /* TODO: make it dynamic based on cmd */
-+ wo->mcu.timeout = 20 * HZ;
-+
-+ hdr = (struct mtk_wed_mcu_hdr *)skb_push(skb, sizeof(*hdr));
-+ hdr->cmd = cmd;
-+ hdr->length = cpu_to_le16(skb->len);
-+
-+ if (wait_resp && wait_seq) {
-+ u16 seq = ++wo->mcu.seq;
-+
-+ if (!seq)
-+ seq = ++wo->mcu.seq;
-+ *wait_seq = seq;
-+
-+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_NEED_RSP);
-+ hdr->seq = cpu_to_le16(seq);
-+ }
-+ if (id == MTK_WED_MODULE_ID_WO)
-+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO);
-+
-+ dev_kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_mcu_parse_response(struct mtk_wed_wo *wo, struct sk_buff *skb,
-+ int cmd, int seq)
-+{
-+ struct mtk_wed_mcu_hdr *hdr;
-+
-+ if (!skb) {
-+ dev_err(wo->hw->dev, "Message %08x (seq %d) timeout\n",
-+ cmd, seq);
-+ return -ETIMEDOUT;
-+ }
-+
-+ hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+ if (le16_to_cpu(hdr->seq) != seq)
-+ return -EAGAIN;
-+
-+ skb_pull(skb, sizeof(*hdr));
-+ switch (cmd) {
-+ case MTK_WED_WO_CMD_RXCNT_INFO:
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
-+ const void *data, int len, bool wait_resp)
-+{
-+ unsigned long expires;
-+ struct sk_buff *skb;
-+ u16 seq;
-+ int ret;
-+
-+ skb = mtk_wed_mcu_msg_alloc(data, len);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ mutex_lock(&wo->mcu.mutex);
-+
-+ ret = mtk_wed_mcu_skb_send_msg(wo, skb, id, cmd, &seq, wait_resp);
-+ if (ret || !wait_resp)
-+ goto unlock;
-+
-+ expires = jiffies + wo->mcu.timeout;
-+ do {
-+ skb = mtk_wed_mcu_get_response(wo, expires);
-+ ret = mtk_wed_mcu_parse_response(wo, skb, cmd, seq);
-+ dev_kfree_skb(skb);
-+ } while (ret == -EAGAIN);
-+
-+unlock:
-+ mutex_unlock(&wo->mcu.mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+mtk_wed_get_memory_region(struct mtk_wed_wo *wo,
-+ struct mtk_wed_wo_memory_region *region)
-+{
-+ struct reserved_mem *rmem;
-+ struct device_node *np;
-+ int index;
-+
-+ index = of_property_match_string(wo->hw->node, "memory-region-names",
-+ region->name);
-+ if (index < 0)
-+ return index;
-+
-+ np = of_parse_phandle(wo->hw->node, "memory-region", index);
-+ if (!np)
-+ return -ENODEV;
-+
-+ rmem = of_reserved_mem_lookup(np);
-+ of_node_put(np);
-+
-+ if (!rmem)
-+ return -ENODEV;
-+
-+ region->phy_addr = rmem->base;
-+ region->size = rmem->size;
-+ region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size);
-+
-+ return !region->addr ? -EINVAL : 0;
-+}
-+
-+static int
-+mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw,
-+ struct mtk_wed_wo_memory_region *region)
-+{
-+ const u8 *first_region_ptr, *region_ptr, *trailer_ptr, *ptr = fw->data;
-+ const struct mtk_wed_fw_trailer *trailer;
-+ const struct mtk_wed_fw_region *fw_region;
-+
-+ trailer_ptr = fw->data + fw->size - sizeof(*trailer);
-+ trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr;
-+ region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region);
-+ first_region_ptr = region_ptr;
-+
-+ while (region_ptr < trailer_ptr) {
-+ u32 length;
-+
-+ fw_region = (const struct mtk_wed_fw_region *)region_ptr;
-+ length = le32_to_cpu(fw_region->len);
-+
-+ if (region->phy_addr != le32_to_cpu(fw_region->addr))
-+ goto next;
-+
-+ if (region->size < length)
-+ goto next;
-+
-+ if (first_region_ptr < ptr + length)
-+ goto next;
-+
-+ if (region->shared && region->consumed)
-+ return 0;
-+
-+ if (!region->shared || !region->consumed) {
-+ memcpy_toio(region->addr, ptr, length);
-+ region->consumed = true;
-+ return 0;
-+ }
-+next:
-+ region_ptr += sizeof(*fw_region);
-+ ptr += length;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int
-+mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
-+{
-+ static struct mtk_wed_wo_memory_region mem_region[] = {
-+ [MTK_WED_WO_REGION_EMI] = {
-+ .name = "wo-emi",
-+ },
-+ [MTK_WED_WO_REGION_ILM] = {
-+ .name = "wo-ilm",
-+ },
-+ [MTK_WED_WO_REGION_DATA] = {
-+ .name = "wo-data",
-+ .shared = true,
-+ },
-+ };
-+ const struct mtk_wed_fw_trailer *trailer;
-+ const struct firmware *fw;
-+ const char *fw_name;
-+ u32 val, boot_cr;
-+ int ret, i;
-+
-+ /* load firmware region metadata */
-+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
-+ ret = mtk_wed_get_memory_region(wo, &mem_region[i]);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ wo->boot.name = "wo-boot";
-+ ret = mtk_wed_get_memory_region(wo, &wo->boot);
-+ if (ret)
-+ return ret;
-+
-+ /* set dummy cr */
-+ wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL,
-+ wo->hw->index + 1);
-+
-+ /* load firmware */
-+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+ ret = request_firmware(&fw, fw_name, wo->hw->dev);
-+ if (ret)
-+ return ret;
-+
-+ trailer = (void *)(fw->data + fw->size -
-+ sizeof(struct mtk_wed_fw_trailer));
-+ dev_info(wo->hw->dev,
-+ "MTK WED WO Firmware Version: %.10s, Build Time: %.15s\n",
-+ trailer->fw_ver, trailer->build_date);
-+ dev_info(wo->hw->dev, "MTK WED WO Chip ID %02x Region %d\n",
-+ trailer->chip_id, trailer->num_region);
-+
-+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
-+ ret = mtk_wed_mcu_run_firmware(wo, fw, &mem_region[i]);
-+ if (ret)
-+ goto out;
-+ }
-+
-+ /* set the start address */
-+ boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR
-+ : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
-+ wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
-+ /* wo firmware reset */
-+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
-+
-+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
-+ val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK
-+ : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
-+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
-+out:
-+ release_firmware(fw);
-+
-+ return ret;
-+}
-+
-+static u32
-+mtk_wed_mcu_read_fw_dl(struct mtk_wed_wo *wo)
-+{
-+ return wed_r32(wo->hw->wed_dev,
-+ MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL);
-+}
-+
-+int mtk_wed_mcu_init(struct mtk_wed_wo *wo)
-+{
-+ u32 val;
-+ int ret;
-+
-+ skb_queue_head_init(&wo->mcu.res_q);
-+ init_waitqueue_head(&wo->mcu.wait);
-+ mutex_init(&wo->mcu.mutex);
-+
-+ ret = mtk_wed_mcu_load_firmware(wo);
-+ if (ret)
-+ return ret;
-+
-+ return readx_poll_timeout(mtk_wed_mcu_read_fw_dl, wo, val, !val,
-+ 100, MTK_FW_DL_TIMEOUT);
-+}
-+
-+MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
-+MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -152,6 +152,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10)
-
-+#define MTK_WED_SCR0 0x3c0
- #define MTK_WED_WPDMA_INT_TRIGGER 0x504
- #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
- #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -0,0 +1,150 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/* Copyright (C) 2022 Lorenzo Bianconi <lorenzo@kernel.org> */
-+
-+#ifndef __MTK_WED_WO_H
-+#define __MTK_WED_WO_H
-+
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+
-+struct mtk_wed_hw;
-+
-+struct mtk_wed_mcu_hdr {
-+ /* DW0 */
-+ u8 version;
-+ u8 cmd;
-+ __le16 length;
-+
-+ /* DW1 */
-+ __le16 seq;
-+ __le16 flag;
-+
-+ /* DW2 */
-+ __le32 status;
-+
-+ /* DW3 */
-+ u8 rsv[20];
-+};
-+
-+struct mtk_wed_wo_log_info {
-+ __le32 sn;
-+ __le32 total;
-+ __le32 rro;
-+ __le32 mod;
-+};
-+
-+enum mtk_wed_wo_event {
-+ MTK_WED_WO_EVT_LOG_DUMP = 0x1,
-+ MTK_WED_WO_EVT_PROFILING = 0x2,
-+ MTK_WED_WO_EVT_RXCNT_INFO = 0x3,
-+};
-+
-+#define MTK_WED_MODULE_ID_WO 1
-+#define MTK_FW_DL_TIMEOUT 4000000 /* us */
-+#define MTK_WOCPU_TIMEOUT 2000000 /* us */
-+
-+enum {
-+ MTK_WED_WARP_CMD_FLAG_RSP = BIT(0),
-+ MTK_WED_WARP_CMD_FLAG_NEED_RSP = BIT(1),
-+ MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2),
-+};
-+
-+enum {
-+ MTK_WED_WO_REGION_EMI,
-+ MTK_WED_WO_REGION_ILM,
-+ MTK_WED_WO_REGION_DATA,
-+ MTK_WED_WO_REGION_BOOT,
-+ __MTK_WED_WO_REGION_MAX,
-+};
-+
-+enum mtk_wed_dummy_cr_idx {
-+ MTK_WED_DUMMY_CR_FWDL,
-+ MTK_WED_DUMMY_CR_WO_STATUS,
-+};
-+
-+#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
-+#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
-+
-+#define MTK_WO_MCU_CFG_LS_BASE 0
-+#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
-+#define MTK_WO_MCU_CFG_LS_FW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x004)
-+#define MTK_WO_MCU_CFG_LS_CFG_DBG1_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x00c)
-+#define MTK_WO_MCU_CFG_LS_CFG_DBG2_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x010)
-+#define MTK_WO_MCU_CFG_LS_WF_MCCR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x014)
-+#define MTK_WO_MCU_CFG_LS_WF_MCCR_SET_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x018)
-+#define MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x01c)
-+#define MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x050)
-+#define MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x060)
-+#define MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x064)
-+
-+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5)
-+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0)
-+
-+struct mtk_wed_wo_memory_region {
-+ const char *name;
-+ void __iomem *addr;
-+ phys_addr_t phy_addr;
-+ u32 size;
-+ bool shared:1;
-+ bool consumed:1;
-+};
-+
-+struct mtk_wed_fw_region {
-+ __le32 decomp_crc;
-+ __le32 decomp_len;
-+ __le32 decomp_blk_sz;
-+ u8 rsv0[4];
-+ __le32 addr;
-+ __le32 len;
-+ u8 feature_set;
-+ u8 rsv1[15];
-+} __packed;
-+
-+struct mtk_wed_fw_trailer {
-+ u8 chip_id;
-+ u8 eco_code;
-+ u8 num_region;
-+ u8 format_ver;
-+ u8 format_flag;
-+ u8 rsv[2];
-+ char fw_ver[10];
-+ char build_date[15];
-+ u32 crc;
-+};
-+
-+struct mtk_wed_wo {
-+ struct mtk_wed_hw *hw;
-+ struct mtk_wed_wo_memory_region boot;
-+
-+ struct {
-+ struct mutex mutex;
-+ int timeout;
-+ u16 seq;
-+
-+ struct sk_buff_head res_q;
-+ wait_queue_head_t wait;
-+ } mcu;
-+};
-+
-+static inline int
-+mtk_wed_mcu_check_msg(struct mtk_wed_wo *wo, struct sk_buff *skb)
-+{
-+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+
-+ if (hdr->version)
-+ return -EINVAL;
-+
-+ if (skb->len < sizeof(*hdr) || skb->len != le16_to_cpu(hdr->length))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb);
-+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo,
-+ struct sk_buff *skb);
-+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
-+ const void *data, int len, bool wait_resp);
-+int mtk_wed_mcu_init(struct mtk_wed_wo *wo);
-+
-+#endif /* __MTK_WED_WO_H */
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -11,6 +11,35 @@
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-
-+enum mtk_wed_wo_cmd {
-+ MTK_WED_WO_CMD_WED_CFG,
-+ MTK_WED_WO_CMD_WED_RX_STAT,
-+ MTK_WED_WO_CMD_RRO_SER,
-+ MTK_WED_WO_CMD_DBG_INFO,
-+ MTK_WED_WO_CMD_DEV_INFO,
-+ MTK_WED_WO_CMD_BSS_INFO,
-+ MTK_WED_WO_CMD_STA_REC,
-+ MTK_WED_WO_CMD_DEV_INFO_DUMP,
-+ MTK_WED_WO_CMD_BSS_INFO_DUMP,
-+ MTK_WED_WO_CMD_STA_REC_DUMP,
-+ MTK_WED_WO_CMD_BA_INFO_DUMP,
-+ MTK_WED_WO_CMD_FBCMD_Q_DUMP,
-+ MTK_WED_WO_CMD_FW_LOG_CTRL,
-+ MTK_WED_WO_CMD_LOG_FLUSH,
-+ MTK_WED_WO_CMD_CHANGE_STATE,
-+ MTK_WED_WO_CMD_CPU_STATS_ENABLE,
-+ MTK_WED_WO_CMD_CPU_STATS_DUMP,
-+ MTK_WED_WO_CMD_EXCEPTION_INIT,
-+ MTK_WED_WO_CMD_PROF_CTRL,
-+ MTK_WED_WO_CMD_STA_BA_DUMP,
-+ MTK_WED_WO_CMD_BA_CTRL_DUMP,
-+ MTK_WED_WO_CMD_RXCNT_CTRL,
-+ MTK_WED_WO_CMD_RXCNT_INFO,
-+ MTK_WED_WO_CMD_SET_CAP,
-+ MTK_WED_WO_CMD_CCIF_RING_DUMP,
-+ MTK_WED_WO_CMD_WED_END
-+};
-+
- enum mtk_wed_bus_tye {
- MTK_WED_BUS_PCIE,
- MTK_WED_BUS_AXI,
diff --git a/target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch b/target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch
deleted file mode 100644
index fd5f45df2a..0000000000
--- a/target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch
+++ /dev/null
@@ -1,737 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:19 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: introduce wed wo support
-
-Introduce WO chip support to mtk wed driver. MTK WED WO is used to
-implement RX Wireless Ethernet Dispatch and offload traffic received by
-wlan nic to the wired interface.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.c
-
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,7 +5,7 @@
-
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
- mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.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_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
- endif
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -16,6 +16,7 @@
- #include "mtk_wed_regs.h"
- #include "mtk_wed.h"
- #include "mtk_ppe.h"
-+#include "mtk_wed_wo.h"
-
- #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
-
-@@ -355,6 +356,8 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mtk_wed_free_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-+ if (hw->version != 1)
-+ mtk_wed_wo_deinit(hw);
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
- struct device_node *wlan_node;
-@@ -878,9 +881,11 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (hw->hifsys)
-+ if (hw->version == 1)
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
-+ else
-+ ret = mtk_wed_wo_init(hw);
-
- out:
- mutex_unlock(&hw_lock);
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -10,6 +10,7 @@
- #include <linux/netdevice.h>
-
- struct mtk_eth;
-+struct mtk_wed_wo;
-
- struct mtk_wed_hw {
- struct device_node *node;
-@@ -22,6 +23,7 @@ struct mtk_wed_hw {
- struct regmap *mirror;
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
-+ struct mtk_wed_wo *wed_wo;
- u32 debugfs_reg;
- u32 num_flows;
- u8 version;
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -122,8 +122,7 @@ mtk_wed_mcu_skb_send_msg(struct mtk_wed_
- if (id == MTK_WED_MODULE_ID_WO)
- hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO);
-
-- dev_kfree_skb(skb);
-- return 0;
-+ return mtk_wed_wo_queue_tx_skb(wo, &wo->q_tx, skb);
- }
-
- static int
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -0,0 +1,508 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (C) 2022 MediaTek Inc.
-+ *
-+ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
-+ * Sujuan Chen <sujuan.chen@mediatek.com>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/of_platform.h>
-+#include <linux/interrupt.h>
-+#include <linux/of_address.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/of_irq.h>
-+#include <linux/bitfield.h>
-+
-+#include "mtk_wed.h"
-+#include "mtk_wed_regs.h"
-+#include "mtk_wed_wo.h"
-+
-+static u32
-+mtk_wed_mmio_r32(struct mtk_wed_wo *wo, u32 reg)
-+{
-+ u32 val;
-+
-+ if (regmap_read(wo->mmio.regs, reg, &val))
-+ val = ~0;
-+
-+ return val;
-+}
-+
-+static void
-+mtk_wed_mmio_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
-+{
-+ regmap_write(wo->mmio.regs, reg, val);
-+}
-+
-+static u32
-+mtk_wed_wo_get_isr(struct mtk_wed_wo *wo)
-+{
-+ u32 val = mtk_wed_mmio_r32(wo, MTK_WED_WO_CCIF_RCHNUM);
-+
-+ return val & MTK_WED_WO_CCIF_RCHNUM_MASK;
-+}
-+
-+static void
-+mtk_wed_wo_set_isr(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_IRQ0_MASK, mask);
-+}
-+
-+static void
-+mtk_wed_wo_set_ack(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_ACK, mask);
-+}
-+
-+static void
-+mtk_wed_wo_set_isr_mask(struct mtk_wed_wo *wo, u32 mask, u32 val, bool set)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&wo->mmio.lock, flags);
-+ wo->mmio.irq_mask &= ~mask;
-+ wo->mmio.irq_mask |= val;
-+ if (set)
-+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask);
-+ spin_unlock_irqrestore(&wo->mmio.lock, flags);
-+}
-+
-+static void
-+mtk_wed_wo_irq_enable(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_wo_set_isr_mask(wo, 0, mask, false);
-+ tasklet_schedule(&wo->mmio.irq_tasklet);
-+}
-+
-+static void
-+mtk_wed_wo_irq_disable(struct mtk_wed_wo *wo, u32 mask)
-+{
-+ mtk_wed_wo_set_isr_mask(wo, mask, 0, true);
-+}
-+
-+static void
-+mtk_wed_wo_kickout(struct mtk_wed_wo *wo)
-+{
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_BUSY, 1 << MTK_WED_WO_TXCH_NUM);
-+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_TCHNUM, MTK_WED_WO_TXCH_NUM);
-+}
-+
-+static void
-+mtk_wed_wo_queue_kick(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ u32 val)
-+{
-+ wmb();
-+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, val);
-+}
-+
-+static void *
-+mtk_wed_wo_dequeue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, u32 *len,
-+ bool flush)
-+{
-+ int buf_len = SKB_WITH_OVERHEAD(q->buf_size);
-+ int index = (q->tail + 1) % q->n_desc;
-+ struct mtk_wed_wo_queue_entry *entry;
-+ struct mtk_wed_wo_queue_desc *desc;
-+ void *buf;
-+
-+ if (!q->queued)
-+ return NULL;
-+
-+ if (flush)
-+ q->desc[index].ctrl |= cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE);
-+ else if (!(q->desc[index].ctrl & cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE)))
-+ return NULL;
-+
-+ q->tail = index;
-+ q->queued--;
-+
-+ desc = &q->desc[index];
-+ entry = &q->entry[index];
-+ buf = entry->buf;
-+ if (len)
-+ *len = FIELD_GET(MTK_WED_WO_CTL_SD_LEN0,
-+ le32_to_cpu(READ_ONCE(desc->ctrl)));
-+ if (buf)
-+ dma_unmap_single(wo->hw->dev, entry->addr, buf_len,
-+ DMA_FROM_DEVICE);
-+ entry->buf = NULL;
-+
-+ return buf;
-+}
-+
-+static int
-+mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ gfp_t gfp, bool rx)
-+{
-+ enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-+ int n_buf = 0;
-+
-+ spin_lock_bh(&q->lock);
-+ while (q->queued < q->n_desc) {
-+ void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp);
-+ struct mtk_wed_wo_queue_entry *entry;
-+ dma_addr_t addr;
-+
-+ if (!buf)
-+ break;
-+
-+ addr = dma_map_single(wo->hw->dev, buf, q->buf_size, dir);
-+ if (unlikely(dma_mapping_error(wo->hw->dev, addr))) {
-+ skb_free_frag(buf);
-+ break;
-+ }
-+
-+ q->head = (q->head + 1) % q->n_desc;
-+ entry = &q->entry[q->head];
-+ entry->addr = addr;
-+ entry->len = q->buf_size;
-+ q->entry[q->head].buf = buf;
-+
-+ if (rx) {
-+ struct mtk_wed_wo_queue_desc *desc = &q->desc[q->head];
-+ u32 ctrl = MTK_WED_WO_CTL_LAST_SEC0 |
-+ FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0,
-+ entry->len);
-+
-+ WRITE_ONCE(desc->buf0, cpu_to_le32(addr));
-+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
-+ }
-+ q->queued++;
-+ n_buf++;
-+ }
-+ spin_unlock_bh(&q->lock);
-+
-+ return n_buf;
-+}
-+
-+static void
-+mtk_wed_wo_rx_complete(struct mtk_wed_wo *wo)
-+{
-+ mtk_wed_wo_set_ack(wo, MTK_WED_WO_RXCH_INT_MASK);
-+ mtk_wed_wo_irq_enable(wo, MTK_WED_WO_RXCH_INT_MASK);
-+}
-+
-+static void
-+mtk_wed_wo_rx_run_queue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ for (;;) {
-+ struct mtk_wed_mcu_hdr *hdr;
-+ struct sk_buff *skb;
-+ void *data;
-+ u32 len;
-+
-+ data = mtk_wed_wo_dequeue(wo, q, &len, false);
-+ if (!data)
-+ break;
-+
-+ skb = build_skb(data, q->buf_size);
-+ if (!skb) {
-+ skb_free_frag(data);
-+ continue;
-+ }
-+
-+ __skb_put(skb, len);
-+ if (mtk_wed_mcu_check_msg(wo, skb)) {
-+ dev_kfree_skb(skb);
-+ continue;
-+ }
-+
-+ hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-+ if (hdr->flag & cpu_to_le16(MTK_WED_WARP_CMD_FLAG_RSP))
-+ mtk_wed_mcu_rx_event(wo, skb);
-+ else
-+ mtk_wed_mcu_rx_unsolicited_event(wo, skb);
-+ }
-+
-+ if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) {
-+ u32 index = (q->head - 1) % q->n_desc;
-+
-+ mtk_wed_wo_queue_kick(wo, q, index);
-+ }
-+}
-+
-+static irqreturn_t
-+mtk_wed_wo_irq_handler(int irq, void *data)
-+{
-+ struct mtk_wed_wo *wo = data;
-+
-+ mtk_wed_wo_set_isr(wo, 0);
-+ tasklet_schedule(&wo->mmio.irq_tasklet);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void mtk_wed_wo_irq_tasklet(struct tasklet_struct *t)
-+{
-+ struct mtk_wed_wo *wo = from_tasklet(wo, t, mmio.irq_tasklet);
-+ u32 intr, mask;
-+
-+ /* disable interrupts */
-+ mtk_wed_wo_set_isr(wo, 0);
-+
-+ intr = mtk_wed_wo_get_isr(wo);
-+ intr &= wo->mmio.irq_mask;
-+ mask = intr & (MTK_WED_WO_RXCH_INT_MASK | MTK_WED_WO_EXCEPTION_INT_MASK);
-+ mtk_wed_wo_irq_disable(wo, mask);
-+
-+ if (intr & MTK_WED_WO_RXCH_INT_MASK) {
-+ mtk_wed_wo_rx_run_queue(wo, &wo->q_rx);
-+ mtk_wed_wo_rx_complete(wo);
-+ }
-+}
-+
-+/* mtk wed wo hw queues */
-+
-+static int
-+mtk_wed_wo_queue_alloc(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ int n_desc, int buf_size, int index,
-+ struct mtk_wed_wo_queue_regs *regs)
-+{
-+ spin_lock_init(&q->lock);
-+ q->regs = *regs;
-+ q->n_desc = n_desc;
-+ q->buf_size = buf_size;
-+
-+ q->desc = dmam_alloc_coherent(wo->hw->dev, n_desc * sizeof(*q->desc),
-+ &q->desc_dma, GFP_KERNEL);
-+ if (!q->desc)
-+ return -ENOMEM;
-+
-+ q->entry = devm_kzalloc(wo->hw->dev, n_desc * sizeof(*q->entry),
-+ GFP_KERNEL);
-+ if (!q->entry)
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_wo_queue_free(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0);
-+ dma_free_coherent(wo->hw->dev, q->n_desc * sizeof(*q->desc), q->desc,
-+ q->desc_dma);
-+}
-+
-+static void
-+mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ struct page *page;
-+ int i;
-+
-+ spin_lock_bh(&q->lock);
-+ for (i = 0; i < q->n_desc; i++) {
-+ struct mtk_wed_wo_queue_entry *entry = &q->entry[i];
-+
-+ dma_unmap_single(wo->hw->dev, entry->addr, entry->len,
-+ DMA_TO_DEVICE);
-+ skb_free_frag(entry->buf);
-+ entry->buf = NULL;
-+ }
-+ spin_unlock_bh(&q->lock);
-+
-+ if (!q->cache.va)
-+ return;
-+
-+ page = virt_to_page(q->cache.va);
-+ __page_frag_cache_drain(page, q->cache.pagecnt_bias);
-+ memset(&q->cache, 0, sizeof(q->cache));
-+}
-+
-+static void
-+mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ struct page *page;
-+
-+ spin_lock_bh(&q->lock);
-+ for (;;) {
-+ void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
-+
-+ if (!buf)
-+ break;
-+
-+ skb_free_frag(buf);
-+ }
-+ spin_unlock_bh(&q->lock);
-+
-+ if (!q->cache.va)
-+ return;
-+
-+ page = virt_to_page(q->cache.va);
-+ __page_frag_cache_drain(page, q->cache.pagecnt_bias);
-+ memset(&q->cache, 0, sizeof(q->cache));
-+}
-+
-+static void
-+mtk_wed_wo_queue_reset(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
-+{
-+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0);
-+ mtk_wed_mmio_w32(wo, q->regs.desc_base, q->desc_dma);
-+ mtk_wed_mmio_w32(wo, q->regs.ring_size, q->n_desc);
-+}
-+
-+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-+ struct sk_buff *skb)
-+{
-+ struct mtk_wed_wo_queue_entry *entry;
-+ struct mtk_wed_wo_queue_desc *desc;
-+ int ret = 0, index;
-+ u32 ctrl;
-+
-+ spin_lock_bh(&q->lock);
-+
-+ q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx);
-+ index = (q->head + 1) % q->n_desc;
-+ if (q->tail == index) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ entry = &q->entry[index];
-+ if (skb->len > entry->len) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ desc = &q->desc[index];
-+ q->head = index;
-+
-+ dma_sync_single_for_cpu(wo->hw->dev, entry->addr, skb->len,
-+ DMA_TO_DEVICE);
-+ memcpy(entry->buf, skb->data, skb->len);
-+ dma_sync_single_for_device(wo->hw->dev, entry->addr, skb->len,
-+ DMA_TO_DEVICE);
-+
-+ ctrl = FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, skb->len) |
-+ MTK_WED_WO_CTL_LAST_SEC0 | MTK_WED_WO_CTL_DMA_DONE;
-+ WRITE_ONCE(desc->buf0, cpu_to_le32(entry->addr));
-+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
-+
-+ mtk_wed_wo_queue_kick(wo, q, q->head);
-+ mtk_wed_wo_kickout(wo);
-+out:
-+ spin_unlock_bh(&q->lock);
-+
-+ dev_kfree_skb(skb);
-+
-+ return ret;
-+}
-+
-+static int
-+mtk_wed_wo_exception_init(struct mtk_wed_wo *wo)
-+{
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_wo_hardware_init(struct mtk_wed_wo *wo)
-+{
-+ struct mtk_wed_wo_queue_regs regs;
-+ struct device_node *np;
-+ int ret;
-+
-+ np = of_parse_phandle(wo->hw->node, "mediatek,wo-ccif", 0);
-+ if (!np)
-+ return -ENODEV;
-+
-+ wo->mmio.regs = syscon_regmap_lookup_by_phandle(np, NULL);
-+ if (IS_ERR_OR_NULL(wo->mmio.regs))
-+ return PTR_ERR(wo->mmio.regs);
-+
-+ wo->mmio.irq = irq_of_parse_and_map(np, 0);
-+ wo->mmio.irq_mask = MTK_WED_WO_ALL_INT_MASK;
-+ spin_lock_init(&wo->mmio.lock);
-+ tasklet_setup(&wo->mmio.irq_tasklet, mtk_wed_wo_irq_tasklet);
-+
-+ ret = devm_request_irq(wo->hw->dev, wo->mmio.irq,
-+ mtk_wed_wo_irq_handler, IRQF_TRIGGER_HIGH,
-+ KBUILD_MODNAME, wo);
-+ if (ret)
-+ goto error;
-+
-+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY1;
-+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY2;
-+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW4;
-+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY3;
-+
-+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_tx, MTK_WED_WO_RING_SIZE,
-+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_TXCH_NUM,
-+ &regs);
-+ if (ret)
-+ goto error;
-+
-+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false);
-+ mtk_wed_wo_queue_reset(wo, &wo->q_tx);
-+
-+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY5;
-+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY6;
-+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW8;
-+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY7;
-+
-+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_rx, MTK_WED_WO_RING_SIZE,
-+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_RXCH_NUM,
-+ &regs);
-+ if (ret)
-+ goto error;
-+
-+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true);
-+ mtk_wed_wo_queue_reset(wo, &wo->q_rx);
-+
-+ /* rx queue irqmask */
-+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask);
-+
-+ return 0;
-+
-+error:
-+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo);
-+
-+ return ret;
-+}
-+
-+static void
-+mtk_wed_wo_hw_deinit(struct mtk_wed_wo *wo)
-+{
-+ /* disable interrupts */
-+ mtk_wed_wo_set_isr(wo, 0);
-+
-+ tasklet_disable(&wo->mmio.irq_tasklet);
-+
-+ disable_irq(wo->mmio.irq);
-+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo);
-+
-+ mtk_wed_wo_queue_tx_clean(wo, &wo->q_tx);
-+ mtk_wed_wo_queue_rx_clean(wo, &wo->q_rx);
-+ mtk_wed_wo_queue_free(wo, &wo->q_tx);
-+ mtk_wed_wo_queue_free(wo, &wo->q_rx);
-+}
-+
-+int mtk_wed_wo_init(struct mtk_wed_hw *hw)
-+{
-+ struct mtk_wed_wo *wo;
-+ int ret;
-+
-+ wo = devm_kzalloc(hw->dev, sizeof(*wo), GFP_KERNEL);
-+ if (!wo)
-+ return -ENOMEM;
-+
-+ hw->wed_wo = wo;
-+ wo->hw = hw;
-+
-+ ret = mtk_wed_wo_hardware_init(wo);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_wed_mcu_init(wo);
-+ if (ret)
-+ return ret;
-+
-+ return mtk_wed_wo_exception_init(wo);
-+}
-+
-+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw)
-+{
-+ struct mtk_wed_wo *wo = hw->wed_wo;
-+
-+ mtk_wed_wo_hw_deinit(wo);
-+}
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -80,6 +80,54 @@ enum mtk_wed_dummy_cr_idx {
- #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5)
- #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0)
-
-+#define MTK_WED_WO_RING_SIZE 256
-+#define MTK_WED_WO_CMD_LEN 1504
-+
-+#define MTK_WED_WO_TXCH_NUM 0
-+#define MTK_WED_WO_RXCH_NUM 1
-+#define MTK_WED_WO_RXCH_WO_EXCEPTION 7
-+
-+#define MTK_WED_WO_TXCH_INT_MASK BIT(0)
-+#define MTK_WED_WO_RXCH_INT_MASK BIT(1)
-+#define MTK_WED_WO_EXCEPTION_INT_MASK BIT(7)
-+#define MTK_WED_WO_ALL_INT_MASK (MTK_WED_WO_RXCH_INT_MASK | \
-+ MTK_WED_WO_EXCEPTION_INT_MASK)
-+
-+#define MTK_WED_WO_CCIF_BUSY 0x004
-+#define MTK_WED_WO_CCIF_START 0x008
-+#define MTK_WED_WO_CCIF_TCHNUM 0x00c
-+#define MTK_WED_WO_CCIF_RCHNUM 0x010
-+#define MTK_WED_WO_CCIF_RCHNUM_MASK GENMASK(7, 0)
-+
-+#define MTK_WED_WO_CCIF_ACK 0x014
-+#define MTK_WED_WO_CCIF_IRQ0_MASK 0x018
-+#define MTK_WED_WO_CCIF_IRQ1_MASK 0x01c
-+#define MTK_WED_WO_CCIF_DUMMY1 0x020
-+#define MTK_WED_WO_CCIF_DUMMY2 0x024
-+#define MTK_WED_WO_CCIF_DUMMY3 0x028
-+#define MTK_WED_WO_CCIF_DUMMY4 0x02c
-+#define MTK_WED_WO_CCIF_SHADOW1 0x030
-+#define MTK_WED_WO_CCIF_SHADOW2 0x034
-+#define MTK_WED_WO_CCIF_SHADOW3 0x038
-+#define MTK_WED_WO_CCIF_SHADOW4 0x03c
-+#define MTK_WED_WO_CCIF_DUMMY5 0x050
-+#define MTK_WED_WO_CCIF_DUMMY6 0x054
-+#define MTK_WED_WO_CCIF_DUMMY7 0x058
-+#define MTK_WED_WO_CCIF_DUMMY8 0x05c
-+#define MTK_WED_WO_CCIF_SHADOW5 0x060
-+#define MTK_WED_WO_CCIF_SHADOW6 0x064
-+#define MTK_WED_WO_CCIF_SHADOW7 0x068
-+#define MTK_WED_WO_CCIF_SHADOW8 0x06c
-+
-+#define MTK_WED_WO_CTL_SD_LEN1 GENMASK(13, 0)
-+#define MTK_WED_WO_CTL_LAST_SEC1 BIT(14)
-+#define MTK_WED_WO_CTL_BURST BIT(15)
-+#define MTK_WED_WO_CTL_SD_LEN0_SHIFT 16
-+#define MTK_WED_WO_CTL_SD_LEN0 GENMASK(29, 16)
-+#define MTK_WED_WO_CTL_LAST_SEC0 BIT(30)
-+#define MTK_WED_WO_CTL_DMA_DONE BIT(31)
-+#define MTK_WED_WO_INFO_WINFO GENMASK(15, 0)
-+
- struct mtk_wed_wo_memory_region {
- const char *name;
- void __iomem *addr;
-@@ -112,10 +160,53 @@ struct mtk_wed_fw_trailer {
- u32 crc;
- };
-
-+struct mtk_wed_wo_queue_regs {
-+ u32 desc_base;
-+ u32 ring_size;
-+ u32 cpu_idx;
-+ u32 dma_idx;
-+};
-+
-+struct mtk_wed_wo_queue_desc {
-+ __le32 buf0;
-+ __le32 ctrl;
-+ __le32 buf1;
-+ __le32 info;
-+ __le32 reserved[4];
-+} __packed __aligned(32);
-+
-+struct mtk_wed_wo_queue_entry {
-+ dma_addr_t addr;
-+ void *buf;
-+ u32 len;
-+};
-+
-+struct mtk_wed_wo_queue {
-+ struct mtk_wed_wo_queue_regs regs;
-+
-+ struct page_frag_cache cache;
-+ spinlock_t lock;
-+
-+ struct mtk_wed_wo_queue_desc *desc;
-+ dma_addr_t desc_dma;
-+
-+ struct mtk_wed_wo_queue_entry *entry;
-+
-+ u16 head;
-+ u16 tail;
-+ int n_desc;
-+ int queued;
-+ int buf_size;
-+
-+};
-+
- struct mtk_wed_wo {
- struct mtk_wed_hw *hw;
- struct mtk_wed_wo_memory_region boot;
-
-+ struct mtk_wed_wo_queue q_tx;
-+ struct mtk_wed_wo_queue q_rx;
-+
- struct {
- struct mutex mutex;
- int timeout;
-@@ -124,6 +215,15 @@ struct mtk_wed_wo {
- struct sk_buff_head res_q;
- wait_queue_head_t wait;
- } mcu;
-+
-+ struct {
-+ struct regmap *regs;
-+
-+ spinlock_t lock;
-+ struct tasklet_struct irq_tasklet;
-+ int irq;
-+ u32 irq_mask;
-+ } mmio;
- };
-
- static inline int
-@@ -146,5 +246,9 @@ void mtk_wed_mcu_rx_unsolicited_event(st
- int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
- const void *data, int len, bool wait_resp);
- int mtk_wed_mcu_init(struct mtk_wed_wo *wo);
-+int mtk_wed_wo_init(struct mtk_wed_hw *hw);
-+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw);
-+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *dev, struct mtk_wed_wo_queue *q,
-+ struct sk_buff *skb);
-
- #endif /* __MTK_WED_WO_H */
diff --git a/target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch b/target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch
deleted file mode 100644
index a002a5f851..0000000000
--- a/target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:20 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: rename tx_wdma array in rx_wdma
-
-Rename tx_wdma queue array in rx_wdma since this is rx side of wdma soc.
-Moreover rename mtk_wed_wdma_ring_setup routine in
-mtk_wed_wdma_rx_ring_setup()
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -253,8 +253,8 @@ mtk_wed_free_tx_rings(struct mtk_wed_dev
-
- for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
- mtk_wed_free_ring(dev, &dev->tx_ring[i]);
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
-+ mtk_wed_free_ring(dev, &dev->rx_wdma[i]);
- }
-
- static void
-@@ -688,10 +688,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device
- }
-
- static int
--mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
-- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
-+ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
-
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size))
- return -ENOMEM;
-@@ -805,9 +805,9 @@ mtk_wed_start(struct mtk_wed_device *dev
- {
- int i;
-
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- if (!dev->tx_wdma[i].desc)
-- mtk_wed_wdma_ring_setup(dev, i, 16);
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
-+ if (!dev->rx_wdma[i].desc)
-+ mtk_wed_wdma_rx_ring_setup(dev, i, 16);
-
- mtk_wed_hw_init(dev);
- mtk_wed_configure_irq(dev, irq_mask);
-@@ -916,7 +916,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- sizeof(*ring->desc)))
- return -ENOMEM;
-
-- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
- return -ENOMEM;
-
- ring->reg_base = MTK_WED_RING_TX(idx);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -7,6 +7,7 @@
- #include <linux/pci.h>
-
- #define MTK_WED_TX_QUEUES 2
-+#define MTK_WED_RX_QUEUES 2
-
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-@@ -66,7 +67,7 @@ struct mtk_wed_device {
-
- struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring txfree_ring;
-- struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
-+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-
- struct {
- int size;
diff --git a/target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch b/target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch
deleted file mode 100644
index eca29739b4..0000000000
--- a/target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch
+++ /dev/null
@@ -1,1521 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:21 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add configure wed wo support
-
-Enable RX Wireless Ethernet Dispatch available on MT7986 Soc.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -9,6 +9,7 @@
- #include <linux/skbuff.h>
- #include <linux/of_platform.h>
- #include <linux/of_address.h>
-+#include <linux/of_reserved_mem.h>
- #include <linux/mfd/syscon.h>
- #include <linux/debugfs.h>
- #include <linux/soc/mediatek/mtk_wed.h>
-@@ -23,6 +24,7 @@
- #define MTK_WED_PKT_SIZE 1900
- #define MTK_WED_BUF_SIZE 2048
- #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
-+#define MTK_WED_RX_RING_SIZE 1536
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 1024
-@@ -31,6 +33,10 @@
- #define MTK_WED_PER_GROUP_PKT 128
-
- #define MTK_WED_FBUF_SIZE 128
-+#define MTK_WED_MIOD_CNT 16
-+#define MTK_WED_FB_CMD_CNT 1024
-+#define MTK_WED_RRO_QUE_CNT 8192
-+#define MTK_WED_MIOD_ENTRY_CNT 128
-
- static struct mtk_wed_hw *hw_list[2];
- static DEFINE_MUTEX(hw_lock);
-@@ -65,12 +71,76 @@ wdma_set(struct mtk_wed_device *dev, u32
- wdma_m32(dev, reg, 0, mask);
- }
-
-+static void
-+wdma_clr(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ wdma_m32(dev, reg, mask, 0);
-+}
-+
-+static u32
-+wifi_r32(struct mtk_wed_device *dev, u32 reg)
-+{
-+ return readl(dev->wlan.base + reg);
-+}
-+
-+static void
-+wifi_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
-+{
-+ writel(val, dev->wlan.base + reg);
-+}
-+
- static u32
- mtk_wed_read_reset(struct mtk_wed_device *dev)
- {
- return wed_r32(dev, MTK_WED_RESET);
- }
-
-+static u32
-+mtk_wdma_read_reset(struct mtk_wed_device *dev)
-+{
-+ return wdma_r32(dev, MTK_WDMA_GLO_CFG);
-+}
-+
-+static void
-+mtk_wdma_rx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
-+ int i;
-+
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
-+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 1000))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
-+ if (dev->rx_wdma[i].desc)
-+ continue;
-+
-+ wdma_w32(dev,
-+ MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+ }
-+}
-+
-+static void
-+mtk_wdma_tx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
-+ int i;
-+
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 1000))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
-+ if (dev->tx_wdma[i].desc)
-+ continue;
-+
-+ wdma_w32(dev,
-+ MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+ }
-+}
-+
- static void
- mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
- {
-@@ -82,6 +152,54 @@ mtk_wed_reset(struct mtk_wed_device *dev
- WARN_ON_ONCE(1);
- }
-
-+static u32
-+mtk_wed_wo_read_status(struct mtk_wed_device *dev)
-+{
-+ return wed_r32(dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_WO_STATUS);
-+}
-+
-+static void
-+mtk_wed_wo_reset(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ u8 state = MTK_WED_WO_STATE_DISABLE;
-+ void __iomem *reg;
-+ u32 val;
-+
-+ mtk_wdma_tx_reset(dev);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+
-+ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &state,
-+ sizeof(state), false);
-+
-+ if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val,
-+ val == MTK_WED_WOIF_DISABLE_DONE,
-+ 100, MTK_WOCPU_TIMEOUT))
-+ dev_err(dev->hw->dev, "failed to disable wed-wo\n");
-+
-+ reg = ioremap(MTK_WED_WO_CPU_MCUSYS_RESET_ADDR, 4);
-+
-+ val = readl(reg);
-+ switch (dev->hw->index) {
-+ case 0:
-+ val |= MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ val &= ~MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ break;
-+ case 1:
-+ val |= MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ val &= ~MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK;
-+ writel(val, reg);
-+ break;
-+ default:
-+ break;
-+ }
-+ iounmap(reg);
-+}
-+
- static struct mtk_wed_hw *
- mtk_wed_assign(struct mtk_wed_device *dev)
- {
-@@ -116,7 +234,7 @@ out:
- }
-
- static int
--mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
-+mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-@@ -133,16 +251,16 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi
- if (!page_list)
- return -ENOMEM;
-
-- dev->buf_ring.size = ring_size;
-- dev->buf_ring.pages = page_list;
-+ dev->tx_buf_ring.size = ring_size;
-+ dev->tx_buf_ring.pages = page_list;
-
- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
- &desc_phys, GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
-- dev->buf_ring.desc = desc;
-- dev->buf_ring.desc_phys = desc_phys;
-+ dev->tx_buf_ring.desc = desc;
-+ dev->tx_buf_ring.desc_phys = desc_phys;
-
- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
- dma_addr_t page_phys, buf_phys;
-@@ -203,10 +321,10 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi
- }
-
- static void
--mtk_wed_free_buffer(struct mtk_wed_device *dev)
-+mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
- {
-- struct mtk_wdma_desc *desc = dev->buf_ring.desc;
-- void **page_list = dev->buf_ring.pages;
-+ struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
-+ void **page_list = dev->tx_buf_ring.pages;
- int page_idx;
- int i;
-
-@@ -216,7 +334,8 @@ mtk_wed_free_buffer(struct mtk_wed_devic
- if (!desc)
- goto free_pagelist;
-
-- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
-+ for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size;
-+ i += MTK_WED_BUF_PER_PAGE) {
- void *page = page_list[page_idx++];
- dma_addr_t buf_addr;
-
-@@ -229,13 +348,59 @@ mtk_wed_free_buffer(struct mtk_wed_devic
- __free_page(page);
- }
-
-- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc),
-- desc, dev->buf_ring.desc_phys);
-+ dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc),
-+ desc, dev->tx_buf_ring.desc_phys);
-
- free_pagelist:
- kfree(page_list);
- }
-
-+static int
-+mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ struct mtk_rxbm_desc *desc;
-+ dma_addr_t desc_phys;
-+
-+ dev->rx_buf_ring.size = dev->wlan.rx_nbuf;
-+ desc = dma_alloc_coherent(dev->hw->dev,
-+ dev->wlan.rx_nbuf * sizeof(*desc),
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc)
-+ return -ENOMEM;
-+
-+ dev->rx_buf_ring.desc = desc;
-+ dev->rx_buf_ring.desc_phys = desc_phys;
-+ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
-+
-+ if (!desc)
-+ return;
-+
-+ dev->wlan.release_rx_buf(dev);
-+ dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc),
-+ desc, dev->rx_buf_ring.desc_phys);
-+}
-+
-+static void
-+mtk_wed_rx_buffer_hw_init(struct mtk_wed_device *dev)
-+{
-+ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD,
-+ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size));
-+ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys);
-+ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL |
-+ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt));
-+ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
-+ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+}
-+
- static void
- mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
- {
-@@ -247,6 +412,13 @@ mtk_wed_free_ring(struct mtk_wed_device
- }
-
- static void
-+mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
-+{
-+ mtk_wed_free_rx_buffer(dev);
-+ mtk_wed_free_ring(dev, &dev->rro.ring);
-+}
-+
-+static void
- mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
- {
- int i;
-@@ -291,6 +463,38 @@ mtk_wed_set_512_support(struct mtk_wed_d
- }
- }
-
-+#define MTK_WFMDA_RX_DMA_EN BIT(2)
-+static void
-+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
-+{
-+ u32 val;
-+ int i;
-+
-+ if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED))
-+ return; /* queue is not configured by mt76 */
-+
-+ for (i = 0; i < 3; i++) {
-+ u32 cur_idx;
-+
-+ cur_idx = wed_r32(dev,
-+ MTK_WED_WPDMA_RING_RX_DATA(idx) +
-+ MTK_WED_RING_OFS_CPU_IDX);
-+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
-+ break;
-+
-+ usleep_range(100000, 200000);
-+ }
-+
-+ if (i == 3) {
-+ dev_err(dev->hw->dev, "rx dma enable failed\n");
-+ return;
-+ }
-+
-+ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) |
-+ MTK_WFMDA_RX_DMA_EN;
-+ wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val);
-+}
-+
- static void
- mtk_wed_dma_disable(struct mtk_wed_device *dev)
- {
-@@ -304,20 +508,25 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WED_GLO_CFG_TX_DMA_EN |
- MTK_WED_GLO_CFG_RX_DMA_EN);
-
-- wdma_m32(dev, MTK_WDMA_GLO_CFG,
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_TX_DMA_EN |
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0);
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-
- if (dev->hw->version == 1) {
- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
-- wdma_m32(dev, MTK_WDMA_GLO_CFG,
-- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0);
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_EN);
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+
- mtk_wed_set_512_support(dev, false);
- }
- }
-@@ -338,6 +547,13 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
- wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-+
-+ if (dev->hw->version == 1)
-+ return;
-+
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
- }
-
- static void
-@@ -353,11 +569,21 @@ mtk_wed_detach(struct mtk_wed_device *de
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-+ }
-
-- mtk_wed_free_buffer(dev);
-+ mtk_wed_free_tx_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-- if (hw->version != 1)
-+
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ mtk_wed_wo_reset(dev);
-+ mtk_wed_free_rx_rings(dev);
- mtk_wed_wo_deinit(hw);
-+ mtk_wdma_rx_reset(dev);
-+ }
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
- struct device_node *wlan_node;
-@@ -434,10 +660,12 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- } else {
- mtk_wed_bus_init(dev);
-
-- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
- }
- }
-
-@@ -487,6 +715,132 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- }
- }
-
-+static int
-+mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-+ int size)
-+{
-+ ring->desc = dma_alloc_coherent(dev->hw->dev,
-+ size * sizeof(*ring->desc),
-+ &ring->desc_phys, GFP_KERNEL);
-+ if (!ring->desc)
-+ return -ENOMEM;
-+
-+ ring->desc_size = sizeof(*ring->desc);
-+ ring->size = size;
-+ memset(ring->desc, 0, size);
-+
-+ return 0;
-+}
-+
-+#define MTK_WED_MIOD_COUNT (MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT)
-+static int
-+mtk_wed_rro_alloc(struct mtk_wed_device *dev)
-+{
-+ struct reserved_mem *rmem;
-+ struct device_node *np;
-+ int index;
-+
-+ index = of_property_match_string(dev->hw->node, "memory-region-names",
-+ "wo-dlm");
-+ if (index < 0)
-+ return index;
-+
-+ np = of_parse_phandle(dev->hw->node, "memory-region", index);
-+ if (!np)
-+ return -ENODEV;
-+
-+ rmem = of_reserved_mem_lookup(np);
-+ of_node_put(np);
-+
-+ if (!rmem)
-+ return -ENODEV;
-+
-+ dev->rro.miod_phys = rmem->base;
-+ dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys;
-+
-+ return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring,
-+ MTK_WED_RRO_QUE_CNT);
-+}
-+
-+static int
-+mtk_wed_rro_cfg(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ struct {
-+ struct {
-+ __le32 base;
-+ __le32 cnt;
-+ __le32 unit;
-+ } ring[2];
-+ __le32 wed;
-+ u8 version;
-+ } req = {
-+ .ring[0] = {
-+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE),
-+ .cnt = cpu_to_le32(MTK_WED_MIOD_CNT),
-+ .unit = cpu_to_le32(MTK_WED_MIOD_ENTRY_CNT),
-+ },
-+ .ring[1] = {
-+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE +
-+ MTK_WED_MIOD_COUNT),
-+ .cnt = cpu_to_le32(MTK_WED_FB_CMD_CNT),
-+ .unit = cpu_to_le32(4),
-+ },
-+ };
-+
-+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_WED_CFG,
-+ &req, sizeof(req), true);
-+}
-+
-+static void
-+mtk_wed_rro_hw_init(struct mtk_wed_device *dev)
-+{
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CFG,
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_MID_DW, 0x70 >> 2) |
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_MOD_DW, 0x10 >> 2) |
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_ENTRY_DW,
-+ MTK_WED_MIOD_ENTRY_CNT >> 2));
-+
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_phys);
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL1,
-+ FIELD_PREP(MTK_WED_RROQM_MIOD_CNT, MTK_WED_MIOD_CNT));
-+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_phys);
-+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL1,
-+ FIELD_PREP(MTK_WED_RROQM_FDBK_CNT, MTK_WED_FB_CMD_CNT));
-+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL2, 0);
-+ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.ring.desc_phys);
-+
-+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
-+ MTK_WED_RROQM_RST_IDX_MIOD |
-+ MTK_WED_RROQM_RST_IDX_FDBK);
-+
-+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL2, MTK_WED_MIOD_CNT - 1);
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
-+}
-+
-+static void
-+mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
-+{
-+ wed_w32(dev, MTK_WED_RESET, MTK_WED_RESET_RX_ROUTE_QM);
-+
-+ for (;;) {
-+ usleep_range(100, 200);
-+ if (!(wed_r32(dev, MTK_WED_RESET) & MTK_WED_RESET_RX_ROUTE_QM))
-+ break;
-+ }
-+
-+ /* configure RX_ROUTE_QM */
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ /* enable RX_ROUTE_QM */
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
-+}
-+
- static void
- mtk_wed_hw_init(struct mtk_wed_device *dev)
- {
-@@ -498,11 +852,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- wed_w32(dev, MTK_WED_TX_BM_CTRL,
- MTK_WED_TX_BM_CTRL_PAUSE |
- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-- dev->buf_ring.size / 128) |
-+ dev->tx_buf_ring.size / 128) |
- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
- MTK_WED_TX_RING_SIZE / 256));
-
-- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
-+ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys);
-
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
-@@ -529,9 +883,9 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- wed_w32(dev, MTK_WED_TX_TKID_CTRL,
- MTK_WED_TX_TKID_CTRL_PAUSE |
- FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM,
-- dev->buf_ring.size / 128) |
-+ dev->tx_buf_ring.size / 128) |
- FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
-- dev->buf_ring.size / 128));
-+ dev->tx_buf_ring.size / 128));
- wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
- FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
- MTK_WED_TX_TKID_DYN_THR_HI);
-@@ -539,18 +893,28 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-- if (dev->hw->version == 1)
-+ if (dev->hw->version == 1) {
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-- else
-+ } else {
- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
-+ /* rx hw init */
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+
-+ mtk_wed_rx_buffer_hw_init(dev);
-+ mtk_wed_rro_hw_init(dev);
-+ mtk_wed_route_qm_hw_init(dev);
-+ }
-
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
- }
-
- static void
--mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size)
-+mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx)
- {
- void *head = (void *)ring->desc;
- int i;
-@@ -560,7 +924,10 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
-
- desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size);
- desc->buf0 = 0;
-- desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ if (tx)
-+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ else
-+ desc->ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST);
- desc->buf1 = 0;
- desc->info = 0;
- }
-@@ -616,7 +983,8 @@ mtk_wed_reset_dma(struct mtk_wed_device
- if (!dev->tx_ring[i].desc)
- continue;
-
-- mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE);
-+ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE,
-+ true);
- }
-
- if (mtk_wed_poll_busy(dev))
-@@ -634,6 +1002,9 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-+ if (mtk_wed_get_rx_capa(dev))
-+ mtk_wdma_rx_reset(dev);
-+
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
-@@ -668,12 +1039,11 @@ mtk_wed_reset_dma(struct mtk_wed_device
- MTK_WED_WPDMA_RESET_IDX_RX);
- wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
- }
--
- }
-
- static int
- mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-- int size, u32 desc_size)
-+ int size, u32 desc_size, bool tx)
- {
- ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size,
- &ring->desc_phys, GFP_KERNEL);
-@@ -682,7 +1052,7 @@ mtk_wed_ring_alloc(struct mtk_wed_device
-
- ring->desc_size = desc_size;
- ring->size = size;
-- mtk_wed_ring_reset(ring, size);
-+ mtk_wed_ring_reset(ring, size, tx);
-
- return 0;
- }
-@@ -691,9 +1061,14 @@ static int
- mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
-- struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
-+ struct mtk_wed_ring *wdma;
-
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size))
-+ if (idx >= ARRAY_SIZE(dev->rx_wdma))
-+ return -EINVAL;
-+
-+ wdma = &dev->rx_wdma[idx];
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-+ true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -710,6 +1085,60 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
- return 0;
- }
-
-+static int
-+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+{
-+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
-+ struct mtk_wed_ring *wdma;
-+
-+ if (idx >= ARRAY_SIZE(dev->tx_wdma))
-+ return -EINVAL;
-+
-+ wdma = &dev->tx_wdma[idx];
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-+ true))
-+ return -ENOMEM;
-+
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-+ wdma->desc_phys);
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
-+ size);
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
-+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
-+
-+ if (!idx) {
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
-+ wdma->desc_phys);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_COUNT,
-+ size);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_CPU_IDX,
-+ 0);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_DMA_IDX,
-+ 0);
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
-+ u32 reason, u32 hash)
-+{
-+ struct mtk_eth *eth = dev->hw->eth;
-+ struct ethhdr *eh;
-+
-+ if (!skb)
-+ return;
-+
-+ if (reason != MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-+ return;
-+
-+ skb_set_mac_header(skb, 0);
-+ eh = eth_hdr(skb);
-+ skb->protocol = eh->h_proto;
-+ mtk_ppe_check_skb(eth->ppe[dev->hw->index], skb, hash);
-+}
-+
- static void
- mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
- {
-@@ -732,6 +1161,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev
-
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
-+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
-+ GENMASK(1, 0));
- /* initail tx interrupt trigger */
- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
- MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-@@ -750,6 +1181,16 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
- dev->wlan.txfree_tbit));
-
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-+ dev->wlan.rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-+ dev->wlan.rx_tbit[1]));
-+
- wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
- wed_set(dev, MTK_WED_WDMA_INT_CTRL,
- FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL,
-@@ -787,9 +1228,15 @@ mtk_wed_dma_enable(struct mtk_wed_device
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
-+ int i;
-+
- wed_set(dev, MTK_WED_WPDMA_CTRL,
- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+
- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-@@ -797,6 +1244,15 @@ mtk_wed_dma_enable(struct mtk_wed_device
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-+ 0x2));
-+
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-+ mtk_wed_check_wfdma_rx_fill(dev, i);
- }
- }
-
-@@ -822,7 +1278,19 @@ mtk_wed_start(struct mtk_wed_device *dev
- val |= BIT(0) | (BIT(1) * !!dev->hw->index);
- regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
- } else {
-- mtk_wed_set_512_support(dev, true);
-+ /* driver set mid ready and only once */
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK1,
-+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK2,
-+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-+
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK1);
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK2);
-+
-+ if (mtk_wed_rro_cfg(dev))
-+ return;
-+
-+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
- }
-
- mtk_wed_dma_enable(dev);
-@@ -856,7 +1324,7 @@ mtk_wed_attach(struct mtk_wed_device *de
- if (!hw) {
- module_put(THIS_MODULE);
- ret = -ENODEV;
-- goto out;
-+ goto unlock;
- }
-
- device = dev->wlan.bus_type == MTK_WED_BUS_PCIE
-@@ -869,15 +1337,24 @@ mtk_wed_attach(struct mtk_wed_device *de
- dev->dev = hw->dev;
- dev->irq = hw->irq;
- dev->wdma_idx = hw->index;
-+ dev->version = hw->version;
-
- if (hw->eth->dma_dev == hw->eth->dev &&
- of_dma_is_coherent(hw->eth->dev->of_node))
- mtk_eth_set_dma_device(hw->eth, hw->dev);
-
-- ret = mtk_wed_buffer_alloc(dev);
-- if (ret) {
-- mtk_wed_detach(dev);
-+ ret = mtk_wed_tx_buffer_alloc(dev);
-+ if (ret)
- goto out;
-+
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ ret = mtk_wed_rx_buffer_alloc(dev);
-+ if (ret)
-+ goto out;
-+
-+ ret = mtk_wed_rro_alloc(dev);
-+ if (ret)
-+ goto out;
- }
-
- mtk_wed_hw_init_early(dev);
-@@ -886,8 +1363,10 @@ mtk_wed_attach(struct mtk_wed_device *de
- BIT(hw->index), 0);
- else
- ret = mtk_wed_wo_init(hw);
--
- out:
-+ if (ret)
-+ mtk_wed_detach(dev);
-+unlock:
- mutex_unlock(&hw_lock);
-
- return ret;
-@@ -910,10 +1389,11 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- * WDMA RX.
- */
-
-- BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring));
-+ if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
-+ return -EINVAL;
-
- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-- sizeof(*ring->desc)))
-+ sizeof(*ring->desc), true))
- return -ENOMEM;
-
- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-@@ -960,6 +1440,37 @@ mtk_wed_txfree_ring_setup(struct mtk_wed
- return 0;
- }
-
-+static int
-+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_ring[idx];
-+
-+ if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
-+ return -EINVAL;
-+
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
-+ sizeof(*ring->desc), false))
-+ return -ENOMEM;
-+
-+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ return -ENOMEM;
-+
-+ ring->reg_base = MTK_WED_RING_RX_DATA(idx);
-+ ring->wpdma = regs;
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+
-+ /* WPDMA -> WED */
-+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
-+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_RX_RING_SIZE);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_BASE,
-+ ring->desc_phys);
-+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_COUNT,
-+ MTK_WED_RX_RING_SIZE);
-+
-+ return 0;
-+}
-+
- static u32
- mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
- {
-@@ -1056,7 +1567,9 @@ void mtk_wed_add_hw(struct device_node *
- static const struct mtk_wed_ops wed_ops = {
- .attach = mtk_wed_attach,
- .tx_ring_setup = mtk_wed_tx_ring_setup,
-+ .rx_ring_setup = mtk_wed_rx_ring_setup,
- .txfree_ring_setup = mtk_wed_txfree_ring_setup,
-+ .msg_update = mtk_wed_mcu_msg_update,
- .start = mtk_wed_start,
- .stop = mtk_wed_stop,
- .reset_dma = mtk_wed_reset_dma,
-@@ -1065,6 +1578,7 @@ void mtk_wed_add_hw(struct device_node *
- .irq_get = mtk_wed_irq_get,
- .irq_set_mask = mtk_wed_irq_set_mask,
- .detach = mtk_wed_detach,
-+ .ppe_check = mtk_wed_ppe_check,
- };
- struct device_node *eth_np = eth->dev->of_node;
- struct platform_device *pdev;
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -87,6 +87,24 @@ wpdma_tx_w32(struct mtk_wed_device *dev,
- }
-
- static inline u32
-+wpdma_rx_r32(struct mtk_wed_device *dev, int ring, u32 reg)
-+{
-+ if (!dev->rx_ring[ring].wpdma)
-+ return 0;
-+
-+ return readl(dev->rx_ring[ring].wpdma + reg);
-+}
-+
-+static inline void
-+wpdma_rx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val)
-+{
-+ if (!dev->rx_ring[ring].wpdma)
-+ return;
-+
-+ writel(val, dev->rx_ring[ring].wpdma + reg);
-+}
-+
-+static inline u32
- wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg)
- {
- if (!dev->txfree_ring.wpdma)
-@@ -128,6 +146,7 @@ static inline int mtk_wed_flow_add(int i
- static inline void mtk_wed_flow_remove(int index)
- {
- }
-+
- #endif
-
- #ifdef CONFIG_DEBUG_FS
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -10,6 +10,7 @@
- #include <linux/of_reserved_mem.h>
- #include <linux/mfd/syscon.h>
- #include <linux/soc/mediatek/mtk_wed.h>
-+#include <asm/unaligned.h>
-
- #include "mtk_wed_regs.h"
- #include "mtk_wed_wo.h"
-@@ -60,24 +61,37 @@ void mtk_wed_mcu_rx_event(struct mtk_wed
- wake_up(&wo->mcu.wait);
- }
-
-+static void
-+mtk_wed_update_rx_stats(struct mtk_wed_device *wed, struct sk_buff *skb)
-+{
-+ u32 count = get_unaligned_le32(skb->data);
-+ struct mtk_wed_wo_rx_stats *stats;
-+ int i;
-+
-+ if (count * sizeof(*stats) > skb->len - sizeof(u32))
-+ return;
-+
-+ stats = (struct mtk_wed_wo_rx_stats *)(skb->data + sizeof(u32));
-+ for (i = 0 ; i < count ; i++)
-+ wed->wlan.update_wo_rx_stats(wed, &stats[i]);
-+}
-+
- void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo,
- struct sk_buff *skb)
- {
- struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data;
-
-- switch (hdr->cmd) {
-- case MTK_WED_WO_EVT_LOG_DUMP: {
-- const char *msg = (const char *)(skb->data + sizeof(*hdr));
-+ skb_pull(skb, sizeof(*hdr));
-
-- dev_notice(wo->hw->dev, "%s\n", msg);
-+ switch (hdr->cmd) {
-+ case MTK_WED_WO_EVT_LOG_DUMP:
-+ dev_notice(wo->hw->dev, "%s\n", skb->data);
- break;
-- }
- case MTK_WED_WO_EVT_PROFILING: {
-- struct mtk_wed_wo_log_info *info;
-- u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info);
-+ struct mtk_wed_wo_log_info *info = (void *)skb->data;
-+ u32 count = skb->len / sizeof(*info);
- int i;
-
-- info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr));
- for (i = 0 ; i < count ; i++)
- dev_notice(wo->hw->dev,
- "SN:%u latency: total=%u, rro:%u, mod:%u\n",
-@@ -88,6 +102,7 @@ void mtk_wed_mcu_rx_unsolicited_event(st
- break;
- }
- case MTK_WED_WO_EVT_RXCNT_INFO:
-+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb);
- break;
- default:
- break;
-@@ -144,6 +159,8 @@ mtk_wed_mcu_parse_response(struct mtk_we
- skb_pull(skb, sizeof(*hdr));
- switch (cmd) {
- case MTK_WED_WO_CMD_RXCNT_INFO:
-+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb);
-+ break;
- default:
- break;
- }
-@@ -182,6 +199,18 @@ unlock:
- return ret;
- }
-
-+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data,
-+ int len)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+
-+ if (dev->hw->version == 1)
-+ return 0;
-+
-+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len,
-+ true);
-+}
-+
- static int
- mtk_wed_get_memory_region(struct mtk_wed_wo *wo,
- struct mtk_wed_wo_memory_region *region)
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -4,6 +4,7 @@
- #ifndef __MTK_WED_REGS_H
- #define __MTK_WED_REGS_H
-
-+#define MTK_WFDMA_DESC_CTRL_TO_HOST BIT(8)
- #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0)
- #define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0)
- #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15)
-@@ -28,6 +29,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_WED_TX_DMA BIT(12)
- #define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
- #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
-+#define MTK_WED_RESET_RX_RRO_QM BIT(20)
-+#define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
- #define MTK_WED_RESET_WED BIT(31)
-
- #define MTK_WED_CTRL 0x00c
-@@ -39,8 +42,12 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11)
--#define MTK_WED_CTRL_RESERVE_EN BIT(12)
--#define MTK_WED_CTRL_RESERVE_BUSY BIT(13)
-+#define MTK_WED_CTRL_WED_RX_BM_EN BIT(12)
-+#define MTK_WED_CTRL_WED_RX_BM_BUSY BIT(13)
-+#define MTK_WED_CTRL_RX_RRO_QM_EN BIT(14)
-+#define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
-+#define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
-+#define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
- #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
- #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25)
- #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
-@@ -62,6 +69,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22)
- #define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24)
-+#define MTK_WED_EXT_INT_STATUS_RX_DRV_GET_BM_DMAD_SKIP BIT(25)
-+#define MTK_WED_EXT_INT_STATUS_WPDMA_RX_D_DRV_ERR BIT(26)
-+#define MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY BIT(27)
- #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
- MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
- MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
-@@ -71,6 +81,8 @@ struct mtk_wdma_desc {
- MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR)
-
- #define MTK_WED_EXT_INT_MASK 0x028
-+#define MTK_WED_EXT_INT_MASK1 0x02c
-+#define MTK_WED_EXT_INT_MASK2 0x030
-
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-@@ -151,6 +163,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10)
-
- #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10)
-+#define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
-
- #define MTK_WED_SCR0 0x3c0
- #define MTK_WED_WPDMA_INT_TRIGGER 0x504
-@@ -213,6 +226,12 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10)
-
- #define MTK_WED_WPDMA_INT_CTRL_RX 0x534
-+#define MTK_WED_WPDMA_INT_CTRL_RX0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RX0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RX1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RX1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG GENMASK(14, 10)
-
- #define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538
- #define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0)
-@@ -242,11 +261,34 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10)
- #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10)
-+#define MTK_WED_WPDMA_RING_RX_DATA(_n) (0x730 + (_n) * 0x10)
-+
-+#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
-+#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)
-+#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)
-+
-+#define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
-+#define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
-+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-+
-+#define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
-+#define MTK_WED_WPDMA_RX_RING 0x770
-+
-+#define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
-+
-+#define MTK_WED_WDMA_RING_TX 0x800
-+
-+#define MTK_WED_WDMA_TX_MIB 0x810
-+
- #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
- #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
-
- #define MTK_WED_WDMA_GLO_CFG 0xa04
- #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
-+#define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
- #define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2)
- #define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3)
- #define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4)
-@@ -291,6 +333,20 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4)
- #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4)
-
-+#define MTK_WED_RX_BM_RX_DMAD 0xd80
-+#define MTK_WED_RX_BM_RX_DMAD_SDL0 GENMASK(13, 0)
-+
-+#define MTK_WED_RX_BM_BASE 0xd84
-+#define MTK_WED_RX_BM_INIT_PTR 0xd88
-+#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0)
-+#define MTK_WED_RX_BM_INIT_SW_TAIL BIT(16)
-+
-+#define MTK_WED_RX_PTR 0xd8c
-+
-+#define MTK_WED_RX_BM_DYN_ALLOC_TH 0xdb4
-+#define MTK_WED_RX_BM_DYN_ALLOC_TH_H GENMASK(31, 16)
-+#define MTK_WED_RX_BM_DYN_ALLOC_TH_L GENMASK(15, 0)
-+
- #define MTK_WED_RING_OFS_BASE 0x00
- #define MTK_WED_RING_OFS_COUNT 0x04
- #define MTK_WED_RING_OFS_CPU_IDX 0x08
-@@ -301,7 +357,9 @@ struct mtk_wdma_desc {
-
- #define MTK_WDMA_GLO_CFG 0x204
- #define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0)
-+#define MTK_WDMA_GLO_CFG_TX_DMA_BUSY BIT(1)
- #define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2)
-+#define MTK_WDMA_GLO_CFG_RX_DMA_BUSY BIT(3)
- #define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26)
- #define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27)
- #define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28)
-@@ -330,4 +388,70 @@ struct mtk_wdma_desc {
- /* DMA channel mapping */
- #define HIFSYS_DMA_AG_MAP 0x008
-
-+#define MTK_WED_RTQM_GLO_CFG 0xb00
-+#define MTK_WED_RTQM_BUSY BIT(1)
-+#define MTK_WED_RTQM_Q_RST BIT(2)
-+#define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
-+#define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-+
-+#define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
-+#define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
-+#define MTK_WED_RTQM_Q2N_MIB 0xb80
-+#define MTK_WED_RTQM_Q2H_MIB(_n) (0xb84 + (_n) * 0x4)
-+
-+#define MTK_WED_RTQM_Q2B_MIB 0xb8c
-+#define MTK_WED_RTQM_PFDBK_MIB 0xb90
-+
-+#define MTK_WED_RROQM_GLO_CFG 0xc04
-+#define MTK_WED_RROQM_RST_IDX 0xc08
-+#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
-+#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4)
-+
-+#define MTK_WED_RROQM_MIOD_CTRL0 0xc40
-+#define MTK_WED_RROQM_MIOD_CTRL1 0xc44
-+#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0)
-+
-+#define MTK_WED_RROQM_MIOD_CTRL2 0xc48
-+#define MTK_WED_RROQM_MIOD_CTRL3 0xc4c
-+
-+#define MTK_WED_RROQM_FDBK_CTRL0 0xc50
-+#define MTK_WED_RROQM_FDBK_CTRL1 0xc54
-+#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0)
-+
-+#define MTK_WED_RROQM_FDBK_CTRL2 0xc58
-+
-+#define MTK_WED_RROQ_BASE_L 0xc80
-+#define MTK_WED_RROQ_BASE_H 0xc84
-+
-+#define MTK_WED_RROQM_MIOD_CFG 0xc8c
-+#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0)
-+#define MTK_WED_RROQM_MIOD_MOD_DW GENMASK(13, 8)
-+#define MTK_WED_RROQM_MIOD_ENTRY_DW GENMASK(22, 16)
-+
-+#define MTK_WED_RROQM_MID_MIB 0xcc0
-+#define MTK_WED_RROQM_MOD_MIB 0xcc4
-+#define MTK_WED_RROQM_MOD_COHERENT_MIB 0xcc8
-+#define MTK_WED_RROQM_FDBK_MIB 0xcd0
-+#define MTK_WED_RROQM_FDBK_COHERENT_MIB 0xcd4
-+#define MTK_WED_RROQM_FDBK_IND_MIB 0xce0
-+#define MTK_WED_RROQM_FDBK_ENQ_MIB 0xce4
-+#define MTK_WED_RROQM_FDBK_ANC_MIB 0xce8
-+#define MTK_WED_RROQM_FDBK_ANC2H_MIB 0xcec
-+
-+#define MTK_WED_RX_BM_RX_DMAD 0xd80
-+#define MTK_WED_RX_BM_BASE 0xd84
-+#define MTK_WED_RX_BM_INIT_PTR 0xd88
-+#define MTK_WED_RX_BM_PTR 0xd8c
-+#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
-+#define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0)
-+
-+#define MTK_WED_RX_BM_BLEN 0xd90
-+#define MTK_WED_RX_BM_STS 0xd94
-+#define MTK_WED_RX_BM_INTF2 0xd98
-+#define MTK_WED_RX_BM_INTF 0xd9c
-+#define MTK_WED_RX_BM_ERR_STS 0xda8
-+
-+#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
-+#define MTK_WED_PCIE_INT_MASK 0x0
-+
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -49,6 +49,10 @@ enum {
- MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2),
- };
-
-+#define MTK_WED_WO_CPU_MCUSYS_RESET_ADDR 0x15194050
-+#define MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK 0x20
-+#define MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK 0x1
-+
- enum {
- MTK_WED_WO_REGION_EMI,
- MTK_WED_WO_REGION_ILM,
-@@ -57,6 +61,28 @@ enum {
- __MTK_WED_WO_REGION_MAX,
- };
-
-+enum mtk_wed_wo_state {
-+ MTK_WED_WO_STATE_UNDEFINED,
-+ MTK_WED_WO_STATE_INIT,
-+ MTK_WED_WO_STATE_ENABLE,
-+ MTK_WED_WO_STATE_DISABLE,
-+ MTK_WED_WO_STATE_HALT,
-+ MTK_WED_WO_STATE_GATING,
-+ MTK_WED_WO_STATE_SER_RESET,
-+ MTK_WED_WO_STATE_WF_RESET,
-+};
-+
-+enum mtk_wed_wo_done_state {
-+ MTK_WED_WOIF_UNDEFINED,
-+ MTK_WED_WOIF_DISABLE_DONE,
-+ MTK_WED_WOIF_TRIGGER_ENABLE,
-+ MTK_WED_WOIF_ENABLE_DONE,
-+ MTK_WED_WOIF_TRIGGER_GATING,
-+ MTK_WED_WOIF_GATING_DONE,
-+ MTK_WED_WOIF_TRIGGER_HALT,
-+ MTK_WED_WOIF_HALT_DONE,
-+};
-+
- enum mtk_wed_dummy_cr_idx {
- MTK_WED_DUMMY_CR_FWDL,
- MTK_WED_DUMMY_CR_WO_STATUS,
-@@ -245,6 +271,8 @@ void mtk_wed_mcu_rx_unsolicited_event(st
- struct sk_buff *skb);
- int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,
- const void *data, int len, bool wait_resp);
-+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data,
-+ int len);
- int mtk_wed_mcu_init(struct mtk_wed_wo *wo);
- int mtk_wed_wo_init(struct mtk_wed_hw *hw);
- void mtk_wed_wo_deinit(struct mtk_wed_hw *hw);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -5,10 +5,13 @@
- #include <linux/rcupdate.h>
- #include <linux/regmap.h>
- #include <linux/pci.h>
-+#include <linux/skbuff.h>
-
- #define MTK_WED_TX_QUEUES 2
- #define MTK_WED_RX_QUEUES 2
-
-+#define WED_WO_STA_REC 0x6
-+
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-
-@@ -41,21 +44,37 @@ enum mtk_wed_wo_cmd {
- MTK_WED_WO_CMD_WED_END
- };
-
-+struct mtk_rxbm_desc {
-+ __le32 buf0;
-+ __le32 token;
-+} __packed __aligned(4);
-+
- enum mtk_wed_bus_tye {
- MTK_WED_BUS_PCIE,
- MTK_WED_BUS_AXI,
- };
-
-+#define MTK_WED_RING_CONFIGURED BIT(0)
- struct mtk_wed_ring {
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
- u32 desc_size;
- int size;
-+ u32 flags;
-
- u32 reg_base;
- void __iomem *wpdma;
- };
-
-+struct mtk_wed_wo_rx_stats {
-+ __le16 wlan_idx;
-+ __le16 tid;
-+ __le32 rx_pkt_cnt;
-+ __le32 rx_byte_cnt;
-+ __le32 rx_err_cnt;
-+ __le32 rx_drop_cnt;
-+};
-+
- struct mtk_wed_device {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- const struct mtk_wed_ops *ops;
-@@ -64,9 +83,12 @@ struct mtk_wed_device {
- bool init_done, running;
- int wdma_idx;
- int irq;
-+ u8 version;
-
- struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
-+ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
- struct mtk_wed_ring txfree_ring;
-+ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-
- struct {
-@@ -74,7 +96,20 @@ struct mtk_wed_device {
- void **pages;
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-- } buf_ring;
-+ } tx_buf_ring;
-+
-+ struct {
-+ int size;
-+ struct page_frag_cache rx_page;
-+ struct mtk_rxbm_desc *desc;
-+ dma_addr_t desc_phys;
-+ } rx_buf_ring;
-+
-+ struct {
-+ struct mtk_wed_ring ring;
-+ dma_addr_t miod_phys;
-+ dma_addr_t fdbk_phys;
-+ } rro;
-
- /* filled by driver: */
- struct {
-@@ -83,22 +118,36 @@ struct mtk_wed_device {
- struct pci_dev *pci_dev;
- };
- enum mtk_wed_bus_tye bus_type;
-+ void __iomem *base;
-+ u32 phy_base;
-
- u32 wpdma_phys;
- u32 wpdma_int;
- u32 wpdma_mask;
- u32 wpdma_tx;
- u32 wpdma_txfree;
-+ u32 wpdma_rx_glo;
-+ u32 wpdma_rx;
-+
-+ bool wcid_512;
-
- u16 token_start;
- unsigned int nbuf;
-+ unsigned int rx_nbuf;
-+ unsigned int rx_npkt;
-+ unsigned int rx_size;
-
- u8 tx_tbit[MTK_WED_TX_QUEUES];
-+ u8 rx_tbit[MTK_WED_RX_QUEUES];
- u8 txfree_tbit;
-
- u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
- int (*offload_enable)(struct mtk_wed_device *wed);
- void (*offload_disable)(struct mtk_wed_device *wed);
-+ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size);
-+ void (*release_rx_buf)(struct mtk_wed_device *wed);
-+ void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
-+ struct mtk_wed_wo_rx_stats *stats);
- } wlan;
- #endif
- };
-@@ -107,9 +156,15 @@ struct mtk_wed_ops {
- int (*attach)(struct mtk_wed_device *dev);
- int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
-+ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
- int (*txfree_ring_setup)(struct mtk_wed_device *dev,
- void __iomem *regs);
-+ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
-+ void *data, int len);
- void (*detach)(struct mtk_wed_device *dev);
-+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
-+ u32 reason, u32 hash);
-
- void (*stop)(struct mtk_wed_device *dev);
- void (*start)(struct mtk_wed_device *dev, u32 irq_mask);
-@@ -144,6 +199,16 @@ mtk_wed_device_attach(struct mtk_wed_dev
- return ret;
- }
-
-+static inline bool
-+mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
-+{
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ return dev->version != 1;
-+#else
-+ return false;
-+#endif
-+}
-+
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- #define mtk_wed_device_active(_dev) !!(_dev)->ops
- #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
-@@ -160,6 +225,12 @@ mtk_wed_device_attach(struct mtk_wed_dev
- (_dev)->ops->irq_get(_dev, _mask)
- #define mtk_wed_device_irq_set_mask(_dev, _mask) \
- (_dev)->ops->irq_set_mask(_dev, _mask)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
-+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
-+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
-+ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -173,6 +244,9 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
- #define mtk_wed_device_irq_get(_dev, _mask) 0
- #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
-+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch b/target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch
deleted file mode 100644
index bb1066dece..0000000000
--- a/target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:22 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add rx mib counters
-
-Introduce WED RX MIB counters support available on MT7986a SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -2,6 +2,7 @@
- /* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
-
- #include <linux/seq_file.h>
-+#include <linux/soc/mediatek/mtk_wed.h>
- #include "mtk_wed.h"
- #include "mtk_wed_regs.h"
-
-@@ -18,6 +19,8 @@ enum {
- DUMP_TYPE_WDMA,
- DUMP_TYPE_WPDMA_TX,
- DUMP_TYPE_WPDMA_TXFREE,
-+ DUMP_TYPE_WPDMA_RX,
-+ DUMP_TYPE_WED_RRO,
- };
-
- #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
-@@ -36,6 +39,9 @@ enum {
-
- #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n)
- #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE)
-+#define DUMP_WPDMA_RX_RING(_n) DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n)
-+#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO)
-+#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO)
-
- static void
- print_reg_val(struct seq_file *s, const char *name, u32 val)
-@@ -57,6 +63,7 @@ dump_wed_regs(struct seq_file *s, struct
- cur > regs ? "\n" : "",
- cur->name);
- continue;
-+ case DUMP_TYPE_WED_RRO:
- case DUMP_TYPE_WED:
- val = wed_r32(dev, cur->offset);
- break;
-@@ -69,6 +76,9 @@ dump_wed_regs(struct seq_file *s, struct
- case DUMP_TYPE_WPDMA_TXFREE:
- val = wpdma_txfree_r32(dev, cur->offset);
- break;
-+ case DUMP_TYPE_WPDMA_RX:
-+ val = wpdma_rx_r32(dev, cur->base, cur->offset);
-+ break;
- }
- print_reg_val(s, cur->name, val);
- }
-@@ -132,6 +142,80 @@ wed_txinfo_show(struct seq_file *s, void
- }
- DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
-
-+static int
-+wed_rxinfo_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("WPDMA RX"),
-+ DUMP_WPDMA_RX_RING(0),
-+ DUMP_WPDMA_RX_RING(1),
-+
-+ DUMP_STR("WPDMA RX"),
-+ DUMP_WED(WED_WPDMA_RX_D_MIB(0)),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)),
-+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)),
-+ DUMP_WED(WED_WPDMA_RX_D_MIB(1)),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)),
-+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)),
-+ DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB),
-+
-+ DUMP_STR("WED RX"),
-+ DUMP_WED_RING(WED_RING_RX_DATA(0)),
-+ DUMP_WED_RING(WED_RING_RX_DATA(1)),
-+
-+ DUMP_STR("WED RRO"),
-+ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
-+ DUMP_WED(WED_RROQM_MID_MIB),
-+ DUMP_WED(WED_RROQM_MOD_MIB),
-+ DUMP_WED(WED_RROQM_MOD_COHERENT_MIB),
-+ DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0),
-+ DUMP_WED(WED_RROQM_FDBK_IND_MIB),
-+ DUMP_WED(WED_RROQM_FDBK_ENQ_MIB),
-+ DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
-+ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
-+
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_R2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2N_MIB),
-+ DUMP_WED(WED_RTQM_Q2B_MIB),
-+ DUMP_WED(WED_RTQM_PFDBK_MIB),
-+
-+ DUMP_STR("WED WDMA TX"),
-+ DUMP_WED(WED_WDMA_TX_MIB),
-+ DUMP_WED_RING(WED_WDMA_RING_TX),
-+
-+ DUMP_STR("WDMA TX"),
-+ DUMP_WDMA(WDMA_GLO_CFG),
-+ DUMP_WDMA_RING(WDMA_RING_TX(0)),
-+ DUMP_WDMA_RING(WDMA_RING_TX(1)),
-+
-+ DUMP_STR("WED RX BM"),
-+ DUMP_WED(WED_RX_BM_BASE),
-+ DUMP_WED(WED_RX_BM_RX_DMAD),
-+ DUMP_WED(WED_RX_BM_PTR),
-+ DUMP_WED(WED_RX_BM_TKID_MIB),
-+ DUMP_WED(WED_RX_BM_BLEN),
-+ DUMP_WED(WED_RX_BM_STS),
-+ DUMP_WED(WED_RX_BM_INTF2),
-+ DUMP_WED(WED_RX_BM_INTF),
-+ DUMP_WED(WED_RX_BM_ERR_STS),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev)
-+ return 0;
-+
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rxinfo);
-
- static int
- mtk_wed_reg_set(void *data, u64 val)
-@@ -175,4 +259,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w
- debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
- debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
- debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-+ if (hw->version != 1)
-+ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
-+ &wed_rxinfo_fops);
- }
diff --git a/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch b/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch
deleted file mode 100644
index 5a79242e3b..0000000000
--- a/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 17 Nov 2022 00:58:46 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in
- mtk_pending_work
-
-Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is
-set only in mtk_pending_work() and it runs holding rtnl lock
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3479,11 +3479,8 @@ static void mtk_pending_work(struct work
- rtnl_lock();
-
- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
-+ set_bit(MTK_RESETTING, &eth->state);
-
-- while (test_and_set_bit_lock(MTK_RESETTING, &eth->state))
-- cpu_relax();
--
-- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__);
- /* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!eth->netdev[i])
-@@ -3517,7 +3514,7 @@ static void mtk_pending_work(struct work
-
- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
-
-- clear_bit_unlock(MTK_RESETTING, &eth->state);
-+ clear_bit(MTK_RESETTING, &eth->state);
-
- rtnl_unlock();
- }
diff --git a/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch b/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch
deleted file mode 100644
index 117ccc0902..0000000000
--- a/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Thu, 24 Nov 2022 11:18:14 +0800
-Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed
- v1
-
-All wed versions should enable the wcid overwritten feature,
-since the wcid size is controlled by the wlan driver.
-
-Tested-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Co-developed-by: Bo Jiao <bo.jiao@mediatek.com>
-Signed-off-by: Bo Jiao <bo.jiao@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
--
-- mtk_wed_set_512_support(dev, false);
- }
-+
-+ mtk_wed_set_512_support(dev, false);
- }
-
- static void
-@@ -1290,9 +1290,10 @@ mtk_wed_start(struct mtk_wed_device *dev
- if (mtk_wed_rro_cfg(dev))
- return;
-
-- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
- }
-
-+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-+
- mtk_wed_dma_enable(dev);
- dev->running = true;
- }
-@@ -1358,11 +1359,13 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (hw->version == 1)
-+ if (hw->version == 1) {
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
-- else
-+ } else {
-+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
- ret = mtk_wed_wo_init(hw);
-+ }
- out:
- if (ret)
- mtk_wed_detach(dev);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -20,6 +20,8 @@ struct mtk_wdma_desc {
- __le32 info;
- } __packed __aligned(4);
-
-+#define MTK_WED_REV_ID 0x004
-+
- #define MTK_WED_RESET 0x008
- #define MTK_WED_RESET_TX_BM BIT(0)
- #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -85,6 +85,9 @@ struct mtk_wed_device {
- int irq;
- u8 version;
-
-+ /* used by wlan driver */
-+ u32 rev_id;
-+
- struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
- struct mtk_wed_ring txfree_ring;
diff --git a/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch b/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch
deleted file mode 100644
index ec58c3fc57..0000000000
--- a/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:51 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: return status value in
- mtk_wdma_rx_reset
-
-Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine.
-Increase poll timeout to 10ms in order to be aligned with vendor sdk.
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic
- return wdma_r32(dev, MTK_WDMA_GLO_CFG);
- }
-
--static void
-+static int
- mtk_wdma_rx_reset(struct mtk_wed_device *dev)
- {
- u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
-- int i;
-+ int i, ret;
-
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
-- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-- !(status & mask), 0, 1000))
-+ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 10000);
-+ if (ret)
- dev_err(dev->hw->dev, "rx reset failed\n");
-
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-+
- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
- if (dev->rx_wdma[i].desc)
- continue;
-@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device
- wdma_w32(dev,
- MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
- }
-+
-+ return ret;
- }
-
- static void
-@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mtk_wed_stop(dev);
-
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
--
-+ mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
- if (mtk_wed_get_rx_capa(dev)) {
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de
- mtk_wed_wo_reset(dev);
- mtk_wed_free_rx_rings(dev);
- mtk_wed_wo_deinit(hw);
-- mtk_wdma_rx_reset(dev);
- }
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
-@@ -999,11 +1002,7 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
--
-- if (mtk_wed_get_rx_capa(dev))
-- mtk_wdma_rx_reset(dev);
-+ mtk_wdma_rx_reset(dev);
-
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
diff --git a/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch b/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch
deleted file mode 100644
index 10c1732c96..0000000000
--- a/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:52 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX
- configuration in mtk_wdma_tx_reset
-
-Remove duplicated code. Increase poll timeout to 10ms in order to be
-aligned with vendor sdk.
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device
-
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-- !(status & mask), 0, 1000))
-+ !(status & mask), 0, 10000))
- dev_err(dev->hw->dev, "tx reset failed\n");
-
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
-- if (dev->tx_wdma[i].desc)
-- continue;
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
- wdma_w32(dev,
- MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
-- }
- }
-
- static void
-@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-- if (mtk_wed_get_rx_capa(dev)) {
-- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-- }
--
- mtk_wed_free_tx_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-
diff --git a/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch b/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch
deleted file mode 100644
index f4e842d515..0000000000
--- a/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:53 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop
-
-Update mtk_wed_stop routine and rename old mtk_wed_stop() to
-mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet
-Dispatcher reset support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- static void
- mtk_wed_stop(struct mtk_wed_device *dev)
- {
-- mtk_wed_dma_disable(dev);
- mtk_wed_set_ext_int(dev, false);
-
-- wed_clr(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WDMA_INT_AGENT_EN |
-- MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
-- MTK_WED_CTRL_WED_TX_BM_EN |
-- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
- wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
-@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev)
-
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
- wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
-- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+}
-+
-+static void
-+mtk_wed_deinit(struct mtk_wed_device *dev)
-+{
-+ mtk_wed_stop(dev);
-+ mtk_wed_dma_disable(dev);
-+
-+ wed_clr(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
-+ MTK_WED_CTRL_WED_TX_BM_EN |
-+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+
-+ if (dev->hw->version == 1)
-+ return;
-+
-+ wed_clr(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_ROUTE_QM_EN |
-+ MTK_WED_CTRL_WED_RX_BM_EN |
-+ MTK_WED_CTRL_RX_RRO_QM_EN);
- }
-
- static void
-@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de
-
- mutex_lock(&hw_lock);
-
-- mtk_wed_stop(dev);
-+ mtk_wed_deinit(dev);
-
- mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-@@ -670,7 +684,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- {
- u32 mask, set;
-
-- mtk_wed_stop(dev);
-+ mtk_wed_deinit(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
- mtk_wed_set_wpdma(dev);
-
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
- (_dev)->ops->msg_update(_dev, _id, _msg, _len)
-+#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
-+#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
-+#define mtk_wed_device_stop(_dev) do {} while (0)
-+#define mtk_wed_device_dma_reset(_dev) do {} while (0)
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch b/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch
deleted file mode 100644
index a0fc9da99e..0000000000
--- a/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch
+++ /dev/null
@@ -1,309 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:54 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine
-
-Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless
-Ethernet Dispatcher available on MT7986 SoC.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -944,42 +944,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
- }
-
- static u32
--mtk_wed_check_busy(struct mtk_wed_device *dev)
-+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
- {
-- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) &
-- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) &
-- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
-- return true;
--
-- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) &
-- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
-- return true;
--
-- if (wed_r32(dev, MTK_WED_CTRL) &
-- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY))
-- return true;
--
-- return false;
-+ return !!(wed_r32(dev, reg) & mask);
- }
-
- static int
--mtk_wed_poll_busy(struct mtk_wed_device *dev)
-+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
- {
- int sleep = 15000;
- int timeout = 100 * sleep;
- u32 val;
-
- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-- timeout, false, dev);
-+ timeout, false, dev, reg, mask);
-+}
-+
-+static int
-+mtk_wed_rx_reset(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ u8 val = MTK_WED_WO_STATE_SER_RESET;
-+ int i, ret;
-+
-+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
-+ sizeof(val), true);
-+ if (ret)
-+ return ret;
-+
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
-+ if (ret) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
-+ } else {
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
-+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
-+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+ }
-+
-+ /* reset rro qm */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_RRO_QM_BUSY);
-+ if (ret) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM);
-+ } else {
-+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
-+ MTK_WED_RROQM_RST_IDX_MIOD |
-+ MTK_WED_RROQM_RST_IDX_FDBK);
-+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
-+ }
-+
-+ /* reset route qm */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
-+ if (ret)
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
-+ else
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ MTK_WED_RTQM_Q_RST);
-+
-+ /* reset tx wdma */
-+ mtk_wdma_tx_reset(dev);
-+
-+ /* reset tx wdma drv */
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
-+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
-+
-+ /* reset wed rx dma */
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_RX_DMA_BUSY);
-+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN);
-+ if (ret) {
-+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
-+ } else {
-+ struct mtk_eth *eth = dev->hw->eth;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ wed_set(dev, MTK_WED_RESET_IDX,
-+ MTK_WED_RESET_IDX_RX_V2);
-+ else
-+ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
-+ }
-+
-+ /* reset rx bm */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_RX_BM_BUSY);
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
-+
-+ /* wo change to enable state */
-+ val = MTK_WED_WO_STATE_ENABLE;
-+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
-+ sizeof(val), true);
-+ if (ret)
-+ return ret;
-+
-+ /* wed_rx_ring_reset */
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) {
-+ if (!dev->rx_ring[i].desc)
-+ continue;
-+
-+ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE,
-+ false);
-+ }
-+ mtk_wed_free_rx_buffer(dev);
-+
-+ return 0;
- }
-
- static void
-@@ -997,19 +1085,23 @@ mtk_wed_reset_dma(struct mtk_wed_device
- true);
- }
-
-- if (mtk_wed_poll_busy(dev))
-- busy = mtk_wed_check_busy(dev);
--
-+ /* 1. reset WED tx DMA */
-+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN);
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_TX_DMA_BUSY);
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
- } else {
-- wed_w32(dev, MTK_WED_RESET_IDX,
-- MTK_WED_RESET_IDX_TX |
-- MTK_WED_RESET_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-- mtk_wdma_rx_reset(dev);
-+ /* 2. reset WDMA rx DMA */
-+ busy = !!mtk_wdma_rx_reset(dev);
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ if (!busy)
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
-
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
-@@ -1026,6 +1118,9 @@ mtk_wed_reset_dma(struct mtk_wed_device
- MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE);
- }
-
-+ /* 3. reset WED WPDMA tx */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-+
- for (i = 0; i < 100; i++) {
- val = wed_r32(dev, MTK_WED_TX_BM_INTF);
- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
-@@ -1033,8 +1128,19 @@ mtk_wed_reset_dma(struct mtk_wed_device
- }
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN);
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-+ /* 4. reset WED WPDMA tx */
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ if (!busy)
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY);
-+
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
-@@ -1045,6 +1151,17 @@ mtk_wed_reset_dma(struct mtk_wed_device
- MTK_WED_WPDMA_RESET_IDX_RX);
- wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
- }
-+
-+ dev->init_done = false;
-+ if (dev->hw->version == 1)
-+ return;
-+
-+ if (!busy) {
-+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
-+ }
-+
-+ mtk_wed_rx_reset(dev);
- }
-
- static int
-@@ -1267,6 +1384,9 @@ mtk_wed_start(struct mtk_wed_device *dev
- {
- int i;
-
-+ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev))
-+ return;
-+
- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
- if (!dev->rx_wdma[i].desc)
- mtk_wed_wdma_rx_ring_setup(dev, i, 16);
-@@ -1355,10 +1475,6 @@ mtk_wed_attach(struct mtk_wed_device *de
- goto out;
-
- if (mtk_wed_get_rx_capa(dev)) {
-- ret = mtk_wed_rx_buffer_alloc(dev);
-- if (ret)
-- goto out;
--
- ret = mtk_wed_rro_alloc(dev);
- if (ret)
- goto out;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -24,11 +24,15 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_RESET 0x008
- #define MTK_WED_RESET_TX_BM BIT(0)
-+#define MTK_WED_RESET_RX_BM BIT(1)
- #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
- #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
- #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
-+#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10)
- #define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11)
- #define MTK_WED_RESET_WED_TX_DMA BIT(12)
-+#define MTK_WED_RESET_WED_RX_DMA BIT(13)
-+#define MTK_WED_RESET_WDMA_TX_DRV BIT(16)
- #define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
- #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
- #define MTK_WED_RESET_RX_RRO_QM BIT(20)
-@@ -158,6 +162,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_IDX 0x20c
- #define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
- #define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
-+#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6)
-+#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
-
- #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
- #define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4)
-@@ -267,6 +273,9 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
- #define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1)
-+#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3)
-+#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4)
- #define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)
- #define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)
-
diff --git a/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch b/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch
deleted file mode 100644
index 4404971cc7..0000000000
--- a/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 24 Nov 2022 16:22:55 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
-
-Introduce reset parameter to mtk_wed_tx_ring_setup signature.
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1181,7 +1181,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device
- }
-
- static int
--mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
-+ bool reset)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-@@ -1190,8 +1191,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
- return -EINVAL;
-
- wdma = &dev->rx_wdma[idx];
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-- true))
-+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1389,7 +1390,7 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
- if (!dev->rx_wdma[i].desc)
-- mtk_wed_wdma_rx_ring_setup(dev, i, 16);
-+ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
-
- mtk_wed_hw_init(dev);
- mtk_wed_configure_irq(dev, irq_mask);
-@@ -1498,7 +1499,8 @@ unlock:
- }
-
- static int
--mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
-+ bool reset)
- {
- struct mtk_wed_ring *ring = &dev->tx_ring[idx];
-
-@@ -1517,11 +1519,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
- return -EINVAL;
-
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-- sizeof(*ring->desc), true))
-+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-+ sizeof(*ring->desc), true))
- return -ENOMEM;
-
-- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
-+ reset))
- return -ENOMEM;
-
- ring->reg_base = MTK_WED_RING_TX(idx);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -158,7 +158,7 @@ struct mtk_wed_device {
- struct mtk_wed_ops {
- int (*attach)(struct mtk_wed_device *dev);
- int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
-- void __iomem *regs);
-+ void __iomem *regs, bool reset);
- int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
- int (*txfree_ring_setup)(struct mtk_wed_device *dev,
-@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- #define mtk_wed_device_active(_dev) !!(_dev)->ops
- #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
- #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
--#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \
-- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \
-+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)
- #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
- (_dev)->ops->txfree_ring_setup(_dev, _regs)
- #define mtk_wed_device_reg_read(_dev, _reg) \
-@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active
- }
- #define mtk_wed_device_detach(_dev) do {} while (0)
- #define mtk_wed_device_start(_dev, _mask) do {} while (0)
--#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
- #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
- #define mtk_wed_device_reg_read(_dev, _reg) 0
- #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
diff --git a/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch b/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch
deleted file mode 100644
index f9b11326b1..0000000000
--- a/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 1 Dec 2022 16:26:53 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in
- mtk_wed_wo_queue_refill
-
-In order to fix the following sleep while atomic bug always alloc pages
-with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in
-spin_lock critical section.
-
-[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT)
-[ 9.054665] Call trace:
-[ 9.057096] dump_backtrace+0x0/0x154
-[ 9.060751] show_stack+0x14/0x1c
-[ 9.064052] dump_stack_lvl+0x64/0x7c
-[ 9.067702] dump_stack+0x14/0x2c
-[ 9.071001] ___might_sleep+0xec/0x120
-[ 9.074736] __might_sleep+0x4c/0x9c
-[ 9.078296] __alloc_pages+0x184/0x2e4
-[ 9.082030] page_frag_alloc_align+0x98/0x1ac
-[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234
-[ 9.090974] mtk_wed_wo_init+0x174/0x2c0
-[ 9.094881] mtk_wed_attach+0x7c8/0x7e0
-[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e]
-[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e]
-[ 9.108727] pci_device_probe+0xac/0x13c
-[ 9.112638] really_probe.part.0+0x98/0x2f4
-[ 9.116807] __driver_probe_device+0x94/0x13c
-[ 9.121147] driver_probe_device+0x40/0x114
-[ 9.125314] __driver_attach+0x7c/0x180
-[ 9.129133] bus_for_each_dev+0x5c/0x90
-[ 9.132953] driver_attach+0x20/0x2c
-[ 9.136513] bus_add_driver+0x104/0x1fc
-[ 9.140333] driver_register+0x74/0x120
-[ 9.144153] __pci_register_driver+0x40/0x50
-[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e]
-[ 9.152848] do_one_initcall+0x40/0x25c
-[ 9.156669] do_init_module+0x44/0x230
-[ 9.160403] load_module+0x1f30/0x2750
-[ 9.164135] __do_sys_init_module+0x150/0x200
-[ 9.168475] __arm64_sys_init_module+0x18/0x20
-[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0
-[ 9.177589] do_el0_svc+0x48/0xe0
-[ 9.180889] el0_svc+0x14/0x50
-[ 9.183929] el0t_64_sync_handler+0x9c/0x120
-[ 9.188183] el0t_64_sync+0x158/0x15c
-
-Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
-Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo
-
- static int
- mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
-- gfp_t gfp, bool rx)
-+ bool rx)
- {
- enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
- int n_buf = 0;
-
- spin_lock_bh(&q->lock);
- while (q->queued < q->n_desc) {
-- void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp);
- struct mtk_wed_wo_queue_entry *entry;
- dma_addr_t addr;
-+ void *buf;
-
-+ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC);
- if (!buf)
- break;
-
-@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w
- mtk_wed_mcu_rx_unsolicited_event(wo, skb);
- }
-
-- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) {
-+ if (mtk_wed_wo_queue_refill(wo, q, true)) {
- u32 index = (q->head - 1) % q->n_desc;
-
- mtk_wed_wo_queue_kick(wo, q, index);
-@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
- if (ret)
- goto error;
-
-- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false);
-+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false);
- mtk_wed_wo_queue_reset(wo, &wo->q_tx);
-
- regs.desc_base = MTK_WED_WO_CCIF_DUMMY5;
-@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
- if (ret)
- goto error;
-
-- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true);
-+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true);
- mtk_wed_wo_queue_reset(wo, &wo->q_rx);
-
- /* rx queue irqmask */
diff --git a/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch b/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch
deleted file mode 100644
index fa6f56dbe7..0000000000
--- a/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 10 Jan 2023 10:31:26 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue
-
-Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and
-mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher
-MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization
-and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in
-mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been
-disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill
-routines can't run concurrently get rid of spinlock for mcu rx queue.
-
-Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
- enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
- int n_buf = 0;
-
-- spin_lock_bh(&q->lock);
- while (q->queued < q->n_desc) {
- struct mtk_wed_wo_queue_entry *entry;
- dma_addr_t addr;
-@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
- q->queued++;
- n_buf++;
- }
-- spin_unlock_bh(&q->lock);
-
- return n_buf;
- }
-@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
- {
- struct page *page;
-
-- spin_lock_bh(&q->lock);
- for (;;) {
- void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
-
-@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
-
- skb_free_frag(buf);
- }
-- spin_unlock_bh(&q->lock);
-
- if (!q->cache.va)
- return;
diff --git a/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch b/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch
deleted file mode 100644
index 9b1e4c3250..0000000000
--- a/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 12 Jan 2023 10:21:29 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue
-
-Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue,
-we do not need to protect WED MCU tx queue with a spin lock since
-the tx queue is accessed in the two following routines:
-- mtk_wed_wo_queue_tx_skb():
- it is run at initialization and during mt7915 normal operation.
- Moreover MCU messages are serialized through MCU mutex.
-- mtk_wed_wo_queue_tx_clean():
- it runs just at mt7915 driver module unload when no more messages
- are sent to the MCU.
-
-Remove tx queue spinlock.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo
- int n_desc, int buf_size, int index,
- struct mtk_wed_wo_queue_regs *regs)
- {
-- spin_lock_init(&q->lock);
- q->regs = *regs;
- q->n_desc = n_desc;
- q->buf_size = buf_size;
-@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
- struct page *page;
- int i;
-
-- spin_lock_bh(&q->lock);
- for (i = 0; i < q->n_desc; i++) {
- struct mtk_wed_wo_queue_entry *entry = &q->entry[i];
-
-@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
- skb_free_frag(entry->buf);
- entry->buf = NULL;
- }
-- spin_unlock_bh(&q->lock);
-
- if (!q->cache.va)
- return;
-@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
- int ret = 0, index;
- u32 ctrl;
-
-- spin_lock_bh(&q->lock);
--
- q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx);
- index = (q->head + 1) % q->n_desc;
- if (q->tail == index) {
-@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
- mtk_wed_wo_queue_kick(wo, q, q->head);
- mtk_wed_wo_kickout(wo);
- out:
-- spin_unlock_bh(&q->lock);
--
- dev_kfree_skb(skb);
-
- return ret;
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -211,7 +211,6 @@ struct mtk_wed_wo_queue {
- struct mtk_wed_wo_queue_regs regs;
-
- struct page_frag_cache cache;
-- spinlock_t lock;
-
- struct mtk_wed_wo_queue_desc *desc;
- dma_addr_t desc_dma;
diff --git a/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch b/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch
deleted file mode 100644
index fde0af25df..0000000000
--- a/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:28 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility
- routine
-
-This is a preliminary patch to add Wireless Ethernet Dispatcher reset
-support.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3255,6 +3255,27 @@ static void mtk_set_mcr_max_rx(struct mt
- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
- }
-
-+static void mtk_hw_reset(struct mtk_eth *eth)
-+{
-+ u32 val;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-+ val = RSTCTRL_PPE0_V2;
-+ } else {
-+ val = RSTCTRL_PPE0;
-+ }
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1;
-+
-+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-+ 0x3ffffff);
-+}
-+
- static int mtk_hw_init(struct mtk_eth *eth)
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-@@ -3294,22 +3315,9 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-- val = RSTCTRL_PPE0_V2;
-- } else {
-- val = RSTCTRL_PPE0;
-- }
--
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val |= RSTCTRL_PPE1;
--
-- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-+ mtk_hw_reset(eth);
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-- 0x3ffffff);
--
- /* Set FE to PDMAv2 if necessary */
- val = mtk_r32(eth, MTK_FE_GLO_MISC);
- mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
diff --git a/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch b/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch
deleted file mode 100644
index e6a94f616e..0000000000
--- a/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:29 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset
- support
-
-Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch
-to align reset procedure to vendor sdk and avoid to power down the chip
-during hw reset.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3276,7 +3276,54 @@ static void mtk_hw_reset(struct mtk_eth
- 0x3ffffff);
- }
-
--static int mtk_hw_init(struct mtk_eth *eth)
-+static u32 mtk_hw_reset_read(struct mtk_eth *eth)
-+{
-+ u32 val;
-+
-+ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val);
-+ return val;
-+}
-+
-+static void mtk_hw_warm_reset(struct mtk_eth *eth)
-+{
-+ u32 rst_mask, val;
-+
-+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE,
-+ RSTCTRL_FE);
-+ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val,
-+ val & RSTCTRL_FE, 1, 1000)) {
-+ dev_err(eth->dev, "warm reset failed\n");
-+ mtk_hw_reset(eth);
-+ return;
-+ }
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
-+ else
-+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ rst_mask |= RSTCTRL_PPE1;
-+
-+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
-+
-+ udelay(1);
-+ val = mtk_hw_reset_read(eth);
-+ if (!(val & rst_mask))
-+ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n",
-+ val, rst_mask);
-+
-+ rst_mask |= RSTCTRL_FE;
-+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask);
-+
-+ udelay(1);
-+ val = mtk_hw_reset_read(eth);
-+ if (val & rst_mask)
-+ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n",
-+ val, rst_mask);
-+}
-+
-+static int mtk_hw_init(struct mtk_eth *eth, bool reset)
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
- ETHSYS_DMA_AG_MAP_PPE;
-@@ -3315,7 +3362,12 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
- }
-
-- mtk_hw_reset(eth);
-+ msleep(100);
-+
-+ if (reset)
-+ mtk_hw_warm_reset(eth);
-+ else
-+ mtk_hw_reset(eth);
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- /* Set FE to PDMAv2 if necessary */
-@@ -3506,7 +3558,7 @@ static void mtk_pending_work(struct work
- if (eth->dev->pins)
- pinctrl_select_state(eth->dev->pins->p,
- eth->dev->pins->default_state);
-- mtk_hw_init(eth);
-+ mtk_hw_init(eth, true);
-
- /* restart DMA and enable IRQs */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-@@ -4108,7 +4160,7 @@ static int mtk_probe(struct platform_dev
- eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
- INIT_WORK(&eth->pending_work, mtk_pending_work);
-
-- err = mtk_hw_init(eth);
-+ err = mtk_hw_init(eth, false);
- if (err)
- goto err_wed_exit;
-
diff --git a/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch b/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch
deleted file mode 100644
index 7fdf7aa581..0000000000
--- a/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch
+++ /dev/null
@@ -1,262 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:30 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor
- sdk
-
-Avoid to power-down the ethernet chip during hw reset and align reset
-procedure to vendor sdk.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2843,14 +2843,29 @@ static void mtk_dma_free(struct mtk_eth
- kfree(eth->scratch_head);
- }
-
-+static bool mtk_hw_reset_check(struct mtk_eth *eth)
-+{
-+ u32 val = mtk_r32(eth, MTK_INT_STATUS2);
-+
-+ 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) ||
-+ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL);
-+}
-+
- static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue)
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-
-+ if (test_bit(MTK_RESETTING, &eth->state))
-+ return;
-+
-+ if (!mtk_hw_reset_check(eth))
-+ return;
-+
- eth->netdev[mac->id]->stats.tx_errors++;
-- netif_err(eth, tx_err, dev,
-- "transmit timed out\n");
-+ netif_err(eth, tx_err, dev, "transmit timed out\n");
-+
- schedule_work(&eth->pending_work);
- }
-
-@@ -3330,15 +3345,17 @@ static int mtk_hw_init(struct mtk_eth *e
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- int i, val, ret;
-
-- if (test_and_set_bit(MTK_HW_INIT, &eth->state))
-+ if (!reset && test_and_set_bit(MTK_HW_INIT, &eth->state))
- return 0;
-
-- pm_runtime_enable(eth->dev);
-- pm_runtime_get_sync(eth->dev);
-+ if (!reset) {
-+ pm_runtime_enable(eth->dev);
-+ pm_runtime_get_sync(eth->dev);
-
-- ret = mtk_clk_enable(eth);
-- if (ret)
-- goto err_disable_pm;
-+ ret = mtk_clk_enable(eth);
-+ if (ret)
-+ goto err_disable_pm;
-+ }
-
- if (eth->ethsys)
- regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask,
-@@ -3467,8 +3484,10 @@ static int mtk_hw_init(struct mtk_eth *e
- return 0;
-
- err_disable_pm:
-- pm_runtime_put_sync(eth->dev);
-- pm_runtime_disable(eth->dev);
-+ if (!reset) {
-+ pm_runtime_put_sync(eth->dev);
-+ pm_runtime_disable(eth->dev);
-+ }
-
- return ret;
- }
-@@ -3530,30 +3549,53 @@ static int mtk_do_ioctl(struct net_devic
- return -EOPNOTSUPP;
- }
-
-+static void mtk_prepare_for_reset(struct mtk_eth *eth)
-+{
-+ u32 val;
-+ int i;
-+
-+ /* disabe FE P3 and P4 */
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= MTK_FE_LINK_DOWN_P4;
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
-+
-+ /* adjust PPE configurations to prepare for reset */
-+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
-+ mtk_ppe_prepare_reset(eth->ppe[i]);
-+
-+ /* disable NETSYS interrupts */
-+ mtk_w32(eth, 0, MTK_FE_INT_ENABLE);
-+
-+ /* force link down GMAC */
-+ for (i = 0; i < 2; i++) {
-+ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK;
-+ mtk_w32(eth, val, MTK_MAC_MCR(i));
-+ }
-+}
-+
- static void mtk_pending_work(struct work_struct *work)
- {
- struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
-- int err, i;
- unsigned long restart = 0;
-+ u32 val;
-+ int i;
-
- rtnl_lock();
--
-- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
- set_bit(MTK_RESETTING, &eth->state);
-
-+ mtk_prepare_for_reset(eth);
-+
- /* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i])
-+ if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
- continue;
-+
- mtk_stop(eth->netdev[i]);
- __set_bit(i, &restart);
- }
-- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__);
-
-- /* restart underlying hardware such as power, clock, pin mux
-- * and the connected phy
-- */
-- mtk_hw_deinit(eth);
-+ usleep_range(15000, 16000);
-
- if (eth->dev->pins)
- pinctrl_select_state(eth->dev->pins->p,
-@@ -3564,15 +3606,19 @@ static void mtk_pending_work(struct work
- for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!test_bit(i, &restart))
- continue;
-- err = mtk_open(eth->netdev[i]);
-- if (err) {
-+
-+ if (mtk_open(eth->netdev[i])) {
- netif_alert(eth, ifup, eth->netdev[i],
-- "Driver up/down cycle failed, closing device.\n");
-+ "Driver up/down cycle failed\n");
- dev_close(eth->netdev[i]);
- }
- }
-
-- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
-+ /* enabe FE P3 and P4 */
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val &= ~MTK_FE_LINK_DOWN_P4;
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
-
- clear_bit(MTK_RESETTING, &eth->state);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -72,12 +72,24 @@
- #define MTK_HW_LRO_REPLACE_DELTA 1000
- #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522
-
-+/* Frame Engine Global Configuration */
-+#define MTK_FE_GLO_CFG 0x00
-+#define MTK_FE_LINK_DOWN_P3 BIT(11)
-+#define MTK_FE_LINK_DOWN_P4 BIT(12)
-+
- /* Frame Engine Global Reset Register */
- #define MTK_RST_GL 0x04
- #define RST_GL_PSE BIT(0)
-
- /* Frame Engine Interrupt Status Register */
- #define MTK_INT_STATUS2 0x08
-+#define MTK_FE_INT_ENABLE 0x0c
-+#define MTK_FE_INT_FQ_EMPTY BIT(8)
-+#define MTK_FE_INT_TSO_FAIL BIT(12)
-+#define MTK_FE_INT_TSO_ILLEGAL BIT(13)
-+#define MTK_FE_INT_TSO_ALIGN BIT(14)
-+#define MTK_FE_INT_RFIFO_OV BIT(18)
-+#define MTK_FE_INT_RFIFO_UF BIT(19)
- #define MTK_GDM1_AF BIT(28)
- #define MTK_GDM2_AF BIT(29)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -710,6 +710,33 @@ int mtk_foe_entry_idle_time(struct mtk_p
- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
- }
-
-+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
-+{
-+ if (!ppe)
-+ return -EINVAL;
-+
-+ /* disable KA */
-+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
-+ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
-+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0);
-+ usleep_range(10000, 11000);
-+
-+ /* set KA timer to maximum */
-+ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
-+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff);
-+
-+ /* set KA tick select */
-+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL);
-+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
-+ usleep_range(10000, 11000);
-+
-+ /* disable scan mode */
-+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE);
-+ usleep_range(10000, 11000);
-+
-+ return mtk_ppe_wait_busy(ppe);
-+}
-+
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version, int index)
- {
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- void mtk_ppe_deinit(struct mtk_eth *eth);
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -58,6 +58,12 @@
- #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16)
- #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18)
- #define MTK_PPE_TB_CFG_INFO_SEL BIT(20)
-+#define MTK_PPE_TB_TICK_SEL BIT(24)
-+
-+#define MTK_PPE_BIND_LMT1 0x230
-+#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16)
-+
-+#define MTK_PPE_KEEPALIVE 0x234
-
- enum {
- MTK_PPE_SCAN_MODE_DISABLED,
diff --git a/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch b/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch
deleted file mode 100644
index a77f3da7f8..0000000000
--- a/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:31 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to
- mtk_hw_reset_check
-
-Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs.
-
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -50,6 +50,7 @@ static const struct mtk_reg_map mtk_reg_
- .delay_irq = 0x0a0c,
- .irq_status = 0x0a20,
- .irq_mask = 0x0a28,
-+ .adma_rx_dbg0 = 0x0a38,
- .int_grp = 0x0a50,
- },
- .qdma = {
-@@ -79,6 +80,8 @@ static const struct mtk_reg_map mtk_reg_
- [0] = 0x2800,
- [1] = 0x2c00,
- },
-+ .pse_iq_sta = 0x0110,
-+ .pse_oq_sta = 0x0118,
- };
-
- static const struct mtk_reg_map mt7628_reg_map = {
-@@ -109,6 +112,7 @@ static const struct mtk_reg_map mt7986_r
- .delay_irq = 0x620c,
- .irq_status = 0x6220,
- .irq_mask = 0x6228,
-+ .adma_rx_dbg0 = 0x6238,
- .int_grp = 0x6250,
- },
- .qdma = {
-@@ -138,6 +142,8 @@ static const struct mtk_reg_map mt7986_r
- [0] = 0x4800,
- [1] = 0x4c00,
- },
-+ .pse_iq_sta = 0x0180,
-+ .pse_oq_sta = 0x01a0,
- };
-
- /* strings used by ethtool */
-@@ -3338,6 +3344,102 @@ static void mtk_hw_warm_reset(struct mtk
- val, rst_mask);
- }
-
-+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 oq_hang, cdm1_busy, adma_busy;
-+ bool wtx_busy, cdm_full, oq_free;
-+ u32 wdidx, val, gdm1_fc, gdm2_fc;
-+ bool qfsm_hang, qfwd_hang;
-+ bool ret = false;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-+ return false;
-+
-+ /* WDMA sanity checks */
-+ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc);
-+
-+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204);
-+ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val);
-+
-+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230);
-+ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val);
-+
-+ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) &&
-+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) &&
-+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16)));
-+
-+ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) {
-+ if (++eth->reset.wdma_hang_count > 2) {
-+ eth->reset.wdma_hang_count = 0;
-+ ret = true;
-+ }
-+ goto out;
-+ }
-+
-+ /* QDMA sanity checks */
-+ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234);
-+ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308);
-+
-+ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0;
-+ 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);
-+
-+ if (qfsm_hang && qfwd_hang &&
-+ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) ||
-+ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) {
-+ if (++eth->reset.qdma_hang_count > 2) {
-+ eth->reset.qdma_hang_count = 0;
-+ ret = true;
-+ }
-+ goto out;
-+ }
-+
-+ /* ADMA sanity checks */
-+ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0));
-+ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16));
-+ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) &&
-+ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6));
-+
-+ if (oq_hang && cdm1_busy && adma_busy) {
-+ if (++eth->reset.adma_hang_count > 2) {
-+ eth->reset.adma_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;
-+out:
-+ eth->reset.wdidx = wdidx;
-+
-+ return ret;
-+}
-+
-+static void mtk_hw_reset_monitor_work(struct work_struct *work)
-+{
-+ struct delayed_work *del_work = to_delayed_work(work);
-+ struct mtk_eth *eth = container_of(del_work, struct mtk_eth,
-+ reset.monitor_work);
-+
-+ if (test_bit(MTK_RESETTING, &eth->state))
-+ goto out;
-+
-+ /* DMA stuck checks */
-+ if (mtk_hw_check_dma_hang(eth))
-+ schedule_work(&eth->pending_work);
-+
-+out:
-+ schedule_delayed_work(&eth->reset.monitor_work,
-+ MTK_DMA_MONITOR_TIMEOUT);
-+}
-+
- static int mtk_hw_init(struct mtk_eth *eth, bool reset)
- {
- u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-@@ -3656,6 +3758,7 @@ static int mtk_cleanup(struct mtk_eth *e
- mtk_unreg_dev(eth);
- mtk_free_dev(eth);
- cancel_work_sync(&eth->pending_work);
-+ cancel_delayed_work_sync(&eth->reset.monitor_work);
-
- return 0;
- }
-@@ -4093,6 +4196,7 @@ static int mtk_probe(struct platform_dev
-
- eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
- INIT_WORK(&eth->rx_dim.work, mtk_dim_rx);
-+ INIT_DELAYED_WORK(&eth->reset.monitor_work, mtk_hw_reset_monitor_work);
-
- eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
- INIT_WORK(&eth->tx_dim.work, mtk_dim_tx);
-@@ -4295,6 +4399,8 @@ static int mtk_probe(struct platform_dev
- netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx);
-
- platform_set_drvdata(pdev, eth);
-+ schedule_delayed_work(&eth->reset.monitor_work,
-+ MTK_DMA_MONITOR_TIMEOUT);
-
- return 0;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -257,6 +257,8 @@
-
- #define MTK_RX_DONE_INT_V2 BIT(14)
-
-+#define MTK_CDM_TXFIFO_RDY BIT(7)
-+
- /* QDMA Interrupt grouping registers */
- #define MTK_RLS_DONE_INT BIT(0)
-
-@@ -542,6 +544,17 @@
- #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c)
- #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110)
-
-+#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_MAC_FSM(x) (0x1010C + ((x) * 0x100))
-+
- struct mtk_rx_dma {
- unsigned int rxd1;
- unsigned int rxd2;
-@@ -938,6 +951,7 @@ struct mtk_reg_map {
- u32 delay_irq; /* delay interrupt */
- u32 irq_status; /* interrupt status */
- u32 irq_mask; /* interrupt mask */
-+ u32 adma_rx_dbg0;
- u32 int_grp;
- } pdma;
- struct {
-@@ -964,6 +978,8 @@ struct mtk_reg_map {
- u32 gdma_to_ppe;
- u32 ppe_base;
- u32 wdma_base[2];
-+ u32 pse_iq_sta;
-+ u32 pse_oq_sta;
- };
-
- /* struct mtk_eth_data - This is the structure holding all differences
-@@ -1006,6 +1022,8 @@ struct mtk_soc_data {
- } txrx;
- };
-
-+#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
-+
- /* currently no SoC has more than 2 macs */
- #define MTK_MAX_DEVS 2
-
-@@ -1128,6 +1146,14 @@ struct mtk_eth {
- struct rhashtable flow_table;
-
- struct bpf_prog __rcu *prog;
-+
-+ struct {
-+ struct delayed_work monitor_work;
-+ u32 wdidx;
-+ u8 wdma_hang_count;
-+ u8 qdma_hang_count;
-+ u8 adma_hang_count;
-+ } reset;
- };
-
- /* struct mtk_mac - the structure that holds the info about the MACs of the
diff --git a/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch b/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch
deleted file mode 100644
index 3f047da758..0000000000
--- a/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 14 Jan 2023 18:01:32 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks
-
-Introduce reset and reset_complete wlan callback to schedule WLAN driver
-reset when ethernet/wed driver is resetting.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3687,6 +3687,11 @@ static void mtk_pending_work(struct work
- set_bit(MTK_RESETTING, &eth->state);
-
- mtk_prepare_for_reset(eth);
-+ mtk_wed_fe_reset();
-+ /* Run again reset preliminary configuration in order to avoid any
-+ * possible race during FE reset since it can run releasing RTNL lock.
-+ */
-+ mtk_prepare_for_reset(eth);
-
- /* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-@@ -3724,6 +3729,8 @@ static void mtk_pending_work(struct work
-
- clear_bit(MTK_RESETTING, &eth->state);
-
-+ mtk_wed_fe_reset_complete();
-+
- rtnl_unlock();
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device *
- iounmap(reg);
- }
-
-+void mtk_wed_fe_reset(void)
-+{
-+ int i;
-+
-+ mutex_lock(&hw_lock);
-+
-+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
-+ struct mtk_wed_hw *hw = hw_list[i];
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+ int err;
-+
-+ if (!dev || !dev->wlan.reset)
-+ continue;
-+
-+ /* reset callback blocks until WLAN reset is completed */
-+ err = dev->wlan.reset(dev);
-+ if (err)
-+ dev_err(dev->dev, "wlan reset failed: %d\n", err);
-+ }
-+
-+ mutex_unlock(&hw_lock);
-+}
-+
-+void mtk_wed_fe_reset_complete(void)
-+{
-+ int i;
-+
-+ mutex_lock(&hw_lock);
-+
-+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
-+ struct mtk_wed_hw *hw = hw_list[i];
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev || !dev->wlan.reset_complete)
-+ continue;
-+
-+ dev->wlan.reset_complete(dev);
-+ }
-+
-+ mutex_unlock(&hw_lock);
-+}
-+
- static struct mtk_wed_hw *
- mtk_wed_assign(struct mtk_wed_device *dev)
- {
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node *
- void mtk_wed_exit(void);
- int mtk_wed_flow_add(int index);
- void mtk_wed_flow_remove(int index);
-+void mtk_wed_fe_reset(void);
-+void mtk_wed_fe_reset_complete(void);
- #else
- static inline void
- mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i
- {
- }
-
-+static inline void mtk_wed_fe_reset(void)
-+{
-+}
-+
-+static inline void mtk_wed_fe_reset_complete(void)
-+{
-+}
- #endif
-
- #ifdef CONFIG_DEBUG_FS
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -151,6 +151,8 @@ struct mtk_wed_device {
- void (*release_rx_buf)(struct mtk_wed_device *wed);
- void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
- struct mtk_wed_wo_rx_stats *stats);
-+ int (*reset)(struct mtk_wed_device *wed);
-+ void (*reset_complete)(struct mtk_wed_device *wed);
- } wlan;
- #endif
- };
diff --git a/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch b/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch
deleted file mode 100644
index c63628da99..0000000000
--- a/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 5 Dec 2022 12:34:42 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback
-
-This patch adds reset parameter to mtk_wed_rx_ring_setup signature
-in order to align rx_ring_setup callback to tx_ring_setup one introduced
-in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to
-tx_ring_setup callback")'
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1252,7 +1252,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
- }
-
- static int
--mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
-+ bool reset)
- {
- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-@@ -1261,8 +1262,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
- return -EINVAL;
-
- wdma = &dev->tx_wdma[idx];
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
-- true))
-+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1272,6 +1273,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
-
-+ if (reset)
-+ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true);
-+
- if (!idx) {
- wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
-@@ -1611,18 +1615,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed
- }
-
- static int
--mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
-+ bool reset)
- {
- struct mtk_wed_ring *ring = &dev->rx_ring[idx];
-
- if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
- return -EINVAL;
-
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
-- sizeof(*ring->desc), false))
-+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
-+ sizeof(*ring->desc), false))
- return -ENOMEM;
-
-- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
-+ reset))
- return -ENOMEM;
-
- ring->reg_base = MTK_WED_RING_RX_DATA(idx);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -162,7 +162,7 @@ struct mtk_wed_ops {
- int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs, bool reset);
- int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-- void __iomem *regs);
-+ void __iomem *regs, bool reset);
- int (*txfree_ring_setup)(struct mtk_wed_device *dev,
- void __iomem *regs);
- int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
-@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- (_dev)->ops->irq_get(_dev, _mask)
- #define mtk_wed_device_irq_set_mask(_dev, _mask) \
- (_dev)->ops->irq_set_mask(_dev, _mask)
--#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
-- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
-+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset)
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
- (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
-@@ -251,7 +251,7 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
- #define mtk_wed_device_irq_get(_dev, _mask) 0
- #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
--#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
- #define mtk_wed_device_stop(_dev) do {} while (0)
diff --git a/target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch b/target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch
deleted file mode 100644
index 45af898cf0..0000000000
--- a/target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 19:50:31 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: account for vlan in rx
- header length
-
-The network stack assumes that devices can handle an extra VLAN tag without
-increasing the MTU
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -29,7 +29,7 @@
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_DMA_SIZE 512
- #define MTK_MAC_COUNT 2
--#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
-+#define MTK_RX_ETH_HLEN (VLAN_ETH_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 | \
diff --git a/target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch b/target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch
deleted file mode 100644
index 41d1bceac4..0000000000
--- a/target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 19:53:57 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: increase tx ring side for
- QDMA devices
-
-In order to use the hardware traffic shaper feature, a larger tx ring is
-needed, especially for the scratch ring, which the hardware shaper uses to
-reorder packets.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -943,7 +943,7 @@ static int mtk_init_fq_dma(struct mtk_et
- {
- const struct mtk_soc_data *soc = eth->soc;
- dma_addr_t phy_ring_tail;
-- int cnt = MTK_DMA_SIZE;
-+ int cnt = MTK_QDMA_RING_SIZE;
- dma_addr_t dma_addr;
- int i;
-
-@@ -2207,19 +2207,25 @@ static int mtk_tx_alloc(struct mtk_eth *
- struct mtk_tx_ring *ring = &eth->tx_ring;
- int i, sz = soc->txrx.txd_size;
- struct mtk_tx_dma_v2 *txd;
-+ int ring_size;
-
-- ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf),
-+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
-+ ring_size = MTK_QDMA_RING_SIZE;
-+ else
-+ ring_size = MTK_DMA_SIZE;
-+
-+ ring->buf = kcalloc(ring_size, sizeof(*ring->buf),
- GFP_KERNEL);
- if (!ring->buf)
- goto no_tx_mem;
-
-- ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
-+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
- &ring->phys, GFP_KERNEL);
- if (!ring->dma)
- goto no_tx_mem;
-
-- for (i = 0; i < MTK_DMA_SIZE; i++) {
-- int next = (i + 1) % MTK_DMA_SIZE;
-+ for (i = 0; i < ring_size; i++) {
-+ int next = (i + 1) % ring_size;
- u32 next_ptr = ring->phys + next * sz;
-
- txd = ring->dma + i * sz;
-@@ -2239,22 +2245,22 @@ static int mtk_tx_alloc(struct mtk_eth *
- * descriptors in ring->dma_pdma.
- */
- if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz,
-+ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
- &ring->phys_pdma, GFP_KERNEL);
- if (!ring->dma_pdma)
- goto no_tx_mem;
-
-- for (i = 0; i < MTK_DMA_SIZE; i++) {
-+ for (i = 0; i < ring_size; i++) {
- ring->dma_pdma[i].txd2 = TX_DMA_DESP2_DEF;
- ring->dma_pdma[i].txd4 = 0;
- }
- }
-
-- ring->dma_size = MTK_DMA_SIZE;
-- atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
-+ ring->dma_size = ring_size;
-+ atomic_set(&ring->free_count, ring_size - 2);
- ring->next_free = ring->dma;
- ring->last_free = (void *)txd;
-- ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz));
-+ ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz));
- ring->thresh = MAX_SKB_FRAGS;
-
- /* make sure that all changes to the dma ring are flushed before we
-@@ -2266,14 +2272,14 @@ static int mtk_tx_alloc(struct mtk_eth *
- mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr);
- mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr);
- mtk_w32(eth,
-- ring->phys + ((MTK_DMA_SIZE - 1) * sz),
-+ ring->phys + ((ring_size - 1) * sz),
- soc->reg_map->qdma.crx_ptr);
- mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
- soc->reg_map->qdma.qtx_cfg);
- } else {
- mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
-- mtk_w32(eth, MTK_DMA_SIZE, MT7628_TX_MAX_CNT0);
-+ mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0);
- mtk_w32(eth, 0, MT7628_TX_CTX_IDX0);
- mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx);
- }
-@@ -2291,7 +2297,7 @@ static void mtk_tx_clean(struct mtk_eth
- int i;
-
- if (ring->buf) {
-- for (i = 0; i < MTK_DMA_SIZE; i++)
-+ for (i = 0; i < ring->dma_size; i++)
- mtk_tx_unmap(eth, &ring->buf[i], NULL, false);
- kfree(ring->buf);
- ring->buf = NULL;
-@@ -2299,14 +2305,14 @@ static void mtk_tx_clean(struct mtk_eth
-
- if (ring->dma) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * soc->txrx.txd_size,
-+ ring->dma_size * soc->txrx.txd_size,
- ring->dma, ring->phys);
- ring->dma = NULL;
- }
-
- if (ring->dma_pdma) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * soc->txrx.txd_size,
-+ ring->dma_size * soc->txrx.txd_size,
- ring->dma_pdma, ring->phys_pdma);
- ring->dma_pdma = NULL;
- }
-@@ -2831,7 +2837,7 @@ static void mtk_dma_free(struct mtk_eth
- netdev_reset_queue(eth->netdev[i]);
- if (eth->scratch_ring) {
- dma_free_coherent(eth->dma_dev,
-- MTK_DMA_SIZE * soc->txrx.txd_size,
-+ MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
- eth->scratch_ring, eth->phy_scratch_ring);
- eth->scratch_ring = NULL;
- eth->phy_scratch_ring = 0;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -27,6 +27,7 @@
- #define MTK_MAX_RX_LENGTH_2K 2048
- #define MTK_TX_DMA_BUF_LEN 0x3fff
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
-+#define MTK_QDMA_RING_SIZE 2048
- #define MTK_DMA_SIZE 512
- #define MTK_MAC_COUNT 2
- #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN)
diff --git a/target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch b/target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch
deleted file mode 100644
index c9823daa1d..0000000000
--- a/target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Nov 2022 19:49:08 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid port_mg assignment on
- MT7622 and newer
-
-On newer chips, this field is unused and contains some bits related to queue
-assignment. Initialize it to 0 in those cases.
-Fix offload_version on MT7621 and MT7623, which still need the previous value.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4478,7 +4478,7 @@ static const struct mtk_soc_data mt7621_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7621_CLKS_BITMAP,
- .required_pctl = false,
-- .offload_version = 2,
-+ .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
-@@ -4517,7 +4517,7 @@ static const struct mtk_soc_data mt7623_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
-- .offload_version = 2,
-+ .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -175,6 +175,8 @@ int mtk_foe_entry_prepare(struct mtk_eth
- val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) |
- FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf);
- } else {
-+ int port_mg = eth->soc->offload_version > 1 ? 0 : 0x3f;
-+
- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) |
- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
-@@ -182,7 +184,7 @@ int mtk_foe_entry_prepare(struct mtk_eth
- entry->ib1 = val;
-
- val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) |
-- FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) |
-+ FIELD_PREP(MTK_FOE_IB2_PORT_MG, port_mg) |
- FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f);
- }
-
diff --git a/target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch b/target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch
deleted file mode 100644
index 0d462b0c85..0000000000
--- a/target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch
+++ /dev/null
@@ -1,654 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 20:17:27 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: implement multi-queue
- support for per-port queues
-
-When sending traffic to multiple ports with different link speeds, queued
-packets to one port can drown out tx to other ports.
-In order to better handle transmission to multiple ports, use the hardware
-shaper feature to implement weighted fair queueing between ports.
-Weight and maximum rate are automatically adjusted based on the link speed
-of the port.
-The first 3 queues are unrestricted and reserved for non-DSA direct tx on
-GMAC ports. The following queues are automatically assigned by the MTK DSA
-tag driver based on the target port number.
-The PPE offload code configures the queues for offloaded traffic in the same
-way.
-This feature is only supported on devices supporting QDMA. All queues still
-share the same DMA ring and descriptor pool.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -55,6 +55,7 @@ static const struct mtk_reg_map mtk_reg_
- },
- .qdma = {
- .qtx_cfg = 0x1800,
-+ .qtx_sch = 0x1804,
- .rx_ptr = 0x1900,
- .rx_cnt_cfg = 0x1904,
- .qcrx_ptr = 0x1908,
-@@ -62,6 +63,7 @@ static const struct mtk_reg_map mtk_reg_
- .rst_idx = 0x1a08,
- .delay_irq = 0x1a0c,
- .fc_th = 0x1a10,
-+ .tx_sch_rate = 0x1a14,
- .int_grp = 0x1a20,
- .hred = 0x1a44,
- .ctx_ptr = 0x1b00,
-@@ -117,6 +119,7 @@ static const struct mtk_reg_map mt7986_r
- },
- .qdma = {
- .qtx_cfg = 0x4400,
-+ .qtx_sch = 0x4404,
- .rx_ptr = 0x4500,
- .rx_cnt_cfg = 0x4504,
- .qcrx_ptr = 0x4508,
-@@ -134,6 +137,7 @@ static const struct mtk_reg_map mt7986_r
- .fq_tail = 0x4724,
- .fq_count = 0x4728,
- .fq_blen = 0x472c,
-+ .tx_sch_rate = 0x4798,
- },
- .gdm1_cnt = 0x1c00,
- .gdma_to_ppe = 0x3333,
-@@ -619,6 +623,75 @@ static void mtk_mac_link_down(struct phy
- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-
-+static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-+ int speed)
-+{
-+ const struct mtk_soc_data *soc = eth->soc;
-+ u32 ofs, val;
-+
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA))
-+ return;
-+
-+ val = MTK_QTX_SCH_MIN_RATE_EN |
-+ /* minimum: 10 Mbps */
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-+
-+ if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-+ switch (speed) {
-+ case SPEED_10:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 2) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_100:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3);
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_1000:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 105) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10);
-+ break;
-+ default:
-+ break;
-+ }
-+ } else {
-+ switch (speed) {
-+ case SPEED_10:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_100:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5);
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
-+ break;
-+ case SPEED_1000:
-+ val |= MTK_QTX_SCH_MAX_RATE_EN |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) |
-+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ ofs = MTK_QTX_OFFSET * idx;
-+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
-+}
-+
- static void mtk_mac_link_up(struct phylink_config *config,
- struct phy_device *phy,
- unsigned int mode, phy_interface_t interface,
-@@ -644,6 +717,8 @@ static void mtk_mac_link_up(struct phyli
- break;
- }
-
-+ mtk_set_queue_speed(mac->hw, mac->id, speed);
-+
- /* Configure duplex */
- if (duplex == DUPLEX_FULL)
- mcr |= MAC_MCR_FORCE_DPX;
-@@ -1104,7 +1179,8 @@ static void mtk_tx_set_dma_desc_v1(struc
-
- WRITE_ONCE(desc->txd1, info->addr);
-
-- data = TX_DMA_SWC | TX_DMA_PLEN0(info->size);
-+ data = TX_DMA_SWC | TX_DMA_PLEN0(info->size) |
-+ FIELD_PREP(TX_DMA_PQID, info->qid);
- if (info->last)
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-@@ -1138,9 +1214,6 @@ static void mtk_tx_set_dma_desc_v2(struc
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-
-- if (!info->qid && mac->id)
-- info->qid = MTK_QDMA_GMAC2_QID;
--
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
- data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
- WRITE_ONCE(desc->txd4, data);
-@@ -1184,11 +1257,12 @@ static int mtk_tx_map(struct sk_buff *sk
- .gso = gso,
- .csum = skb->ip_summed == CHECKSUM_PARTIAL,
- .vlan = skb_vlan_tag_present(skb),
-- .qid = skb->mark & MTK_QDMA_TX_MASK,
-+ .qid = skb_get_queue_mapping(skb),
- .vlan_tci = skb_vlan_tag_get(skb),
- .first = true,
- .last = !skb_is_nonlinear(skb),
- };
-+ struct netdev_queue *txq;
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
- const struct mtk_soc_data *soc = eth->soc;
-@@ -1196,8 +1270,10 @@ static int mtk_tx_map(struct sk_buff *sk
- struct mtk_tx_dma *itxd_pdma, *txd_pdma;
- struct mtk_tx_buf *itx_buf, *tx_buf;
- int i, n_desc = 1;
-+ int queue = skb_get_queue_mapping(skb);
- int k = 0;
-
-+ txq = netdev_get_tx_queue(dev, queue);
- itxd = ring->next_free;
- itxd_pdma = qdma_to_pdma(ring, itxd);
- if (itxd == ring->last_free)
-@@ -1246,7 +1322,7 @@ static int mtk_tx_map(struct sk_buff *sk
- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
- txd_info.size = min_t(unsigned int, frag_size,
- soc->txrx.dma_max_len);
-- txd_info.qid = skb->mark & MTK_QDMA_TX_MASK;
-+ txd_info.qid = queue;
- txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
- !(frag_size - txd_info.size);
- txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
-@@ -1285,7 +1361,7 @@ static int mtk_tx_map(struct sk_buff *sk
- txd_pdma->txd2 |= TX_DMA_LS1;
- }
-
-- netdev_sent_queue(dev, skb->len);
-+ netdev_tx_sent_queue(txq, skb->len);
- skb_tx_timestamp(skb);
-
- ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-@@ -1297,8 +1373,7 @@ static int mtk_tx_map(struct sk_buff *sk
- wmb();
-
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
-- if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) ||
-- !netdev_xmit_more())
-+ if (netif_xmit_stopped(txq) || !netdev_xmit_more())
- mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr);
- } else {
- int next_idx;
-@@ -1367,7 +1442,7 @@ static void mtk_wake_queue(struct mtk_et
- for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!eth->netdev[i])
- continue;
-- netif_wake_queue(eth->netdev[i]);
-+ netif_tx_wake_all_queues(eth->netdev[i]);
- }
- }
-
-@@ -1391,7 +1466,7 @@ static netdev_tx_t mtk_start_xmit(struct
-
- tx_num = mtk_cal_txd_req(eth, skb);
- if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
-- netif_stop_queue(dev);
-+ netif_tx_stop_all_queues(dev);
- netif_err(eth, tx_queued, dev,
- "Tx Ring full when queue awake!\n");
- spin_unlock(&eth->page_lock);
-@@ -1417,7 +1492,7 @@ static netdev_tx_t mtk_start_xmit(struct
- goto drop;
-
- if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
-- netif_stop_queue(dev);
-+ netif_tx_stop_all_queues(dev);
-
- spin_unlock(&eth->page_lock);
-
-@@ -1584,10 +1659,12 @@ static int mtk_xdp_submit_frame(struct m
- struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf);
- const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_ring *ring = &eth->tx_ring;
-+ struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_tx_dma_desc_info txd_info = {
- .size = xdpf->len,
- .first = true,
- .last = !xdp_frame_has_frags(xdpf),
-+ .qid = mac->id,
- };
- int err, index = 0, n_desc = 1, nr_frags;
- struct mtk_tx_buf *htx_buf, *tx_buf;
-@@ -1637,6 +1714,7 @@ static int mtk_xdp_submit_frame(struct m
- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
- txd_info.size = skb_frag_size(&sinfo->frags[index]);
- txd_info.last = index + 1 == nr_frags;
-+ txd_info.qid = mac->id;
- data = skb_frag_address(&sinfo->frags[index]);
-
- index++;
-@@ -1991,8 +2069,46 @@ rx_done:
- return done;
- }
-
-+struct mtk_poll_state {
-+ struct netdev_queue *txq;
-+ unsigned int total;
-+ unsigned int done;
-+ unsigned int bytes;
-+};
-+
-+static void
-+mtk_poll_tx_done(struct mtk_eth *eth, struct mtk_poll_state *state, u8 mac,
-+ struct sk_buff *skb)
-+{
-+ struct netdev_queue *txq;
-+ struct net_device *dev;
-+ unsigned int bytes = skb->len;
-+
-+ state->total++;
-+ eth->tx_packets++;
-+ eth->tx_bytes += bytes;
-+
-+ dev = eth->netdev[mac];
-+ if (!dev)
-+ return;
-+
-+ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
-+ if (state->txq == txq) {
-+ state->done++;
-+ state->bytes += bytes;
-+ return;
-+ }
-+
-+ if (state->txq)
-+ netdev_tx_completed_queue(state->txq, state->done, state->bytes);
-+
-+ state->txq = txq;
-+ state->done = 1;
-+ state->bytes = bytes;
-+}
-+
- static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
-- unsigned int *done, unsigned int *bytes)
-+ struct mtk_poll_state *state)
- {
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct mtk_tx_ring *ring = &eth->tx_ring;
-@@ -2024,12 +2140,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
- break;
-
- if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-- if (tx_buf->type == MTK_TYPE_SKB) {
-- struct sk_buff *skb = tx_buf->data;
-+ if (tx_buf->type == MTK_TYPE_SKB)
-+ mtk_poll_tx_done(eth, state, mac, tx_buf->data);
-
-- bytes[mac] += skb->len;
-- done[mac]++;
-- }
- budget--;
- }
- mtk_tx_unmap(eth, tx_buf, &bq, true);
-@@ -2048,7 +2161,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
- }
-
- static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget,
-- unsigned int *done, unsigned int *bytes)
-+ struct mtk_poll_state *state)
- {
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct mtk_tx_buf *tx_buf;
-@@ -2066,12 +2179,8 @@ static int mtk_poll_tx_pdma(struct mtk_e
- break;
-
- if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
-- if (tx_buf->type == MTK_TYPE_SKB) {
-- struct sk_buff *skb = tx_buf->data;
--
-- bytes[0] += skb->len;
-- done[0]++;
-- }
-+ if (tx_buf->type == MTK_TYPE_SKB)
-+ mtk_poll_tx_done(eth, state, 0, tx_buf->data);
- budget--;
- }
- mtk_tx_unmap(eth, tx_buf, &bq, true);
-@@ -2093,26 +2202,15 @@ static int mtk_poll_tx(struct mtk_eth *e
- {
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct dim_sample dim_sample = {};
-- unsigned int done[MTK_MAX_DEVS];
-- unsigned int bytes[MTK_MAX_DEVS];
-- int total = 0, i;
--
-- memset(done, 0, sizeof(done));
-- memset(bytes, 0, sizeof(bytes));
-+ struct mtk_poll_state state = {};
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-- budget = mtk_poll_tx_qdma(eth, budget, done, bytes);
-+ budget = mtk_poll_tx_qdma(eth, budget, &state);
- else
-- budget = mtk_poll_tx_pdma(eth, budget, done, bytes);
-+ budget = mtk_poll_tx_pdma(eth, budget, &state);
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i] || !done[i])
-- continue;
-- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
-- total += done[i];
-- eth->tx_packets += done[i];
-- eth->tx_bytes += bytes[i];
-- }
-+ if (state.txq)
-+ netdev_tx_completed_queue(state.txq, state.done, state.bytes);
-
- dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes,
- &dim_sample);
-@@ -2122,7 +2220,7 @@ static int mtk_poll_tx(struct mtk_eth *e
- (atomic_read(&ring->free_count) > ring->thresh))
- mtk_wake_queue(eth);
-
-- return total;
-+ return state.total;
- }
-
- static void mtk_handle_status_irq(struct mtk_eth *eth)
-@@ -2208,6 +2306,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- int i, sz = soc->txrx.txd_size;
- struct mtk_tx_dma_v2 *txd;
- int ring_size;
-+ u32 ofs, val;
-
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
- ring_size = MTK_QDMA_RING_SIZE;
-@@ -2275,8 +2374,25 @@ static int mtk_tx_alloc(struct mtk_eth *
- ring->phys + ((ring_size - 1) * sz),
- soc->reg_map->qdma.crx_ptr);
- mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
-- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
-- soc->reg_map->qdma.qtx_cfg);
-+
-+ for (i = 0, ofs = 0; i < MTK_QDMA_NUM_QUEUES; i++) {
-+ val = (QDMA_RES_THRES << 8) | QDMA_RES_THRES;
-+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs);
-+
-+ val = MTK_QTX_SCH_MIN_RATE_EN |
-+ /* minimum: 10 Mbps */
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
-+ ofs += MTK_QTX_OFFSET;
-+ }
-+ val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16);
-+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
- } else {
- mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
- mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0);
-@@ -2961,7 +3077,7 @@ static int mtk_start_dma(struct mtk_eth
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
- val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
- MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
-- MTK_CHK_DDONE_EN;
-+ MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
- else
- val |= MTK_RX_BT_32DWORDS;
- mtk_w32(eth, val, reg_map->qdma.glo_cfg);
-@@ -3007,6 +3123,45 @@ static void mtk_gdm_config(struct mtk_et
- mtk_w32(eth, 0, MTK_RST_GL);
- }
-
-+static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr)
-+{
-+ struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier);
-+ struct mtk_eth *eth = mac->hw;
-+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-+ struct ethtool_link_ksettings s;
-+ struct net_device *ldev;
-+ struct list_head *iter;
-+ struct dsa_port *dp;
-+
-+ if (event != NETDEV_CHANGE)
-+ return NOTIFY_DONE;
-+
-+ netdev_for_each_lower_dev(dev, ldev, iter) {
-+ if (netdev_priv(ldev) == mac)
-+ goto found;
-+ }
-+
-+ return NOTIFY_DONE;
-+
-+found:
-+ if (!dsa_slave_dev_check(dev))
-+ return NOTIFY_DONE;
-+
-+ if (__ethtool_get_link_ksettings(dev, &s))
-+ return NOTIFY_DONE;
-+
-+ if (s.base.speed == 0 || s.base.speed == ((__u32)-1))
-+ return NOTIFY_DONE;
-+
-+ dp = dsa_port_from_netdev(dev);
-+ if (dp->index >= MTK_QDMA_NUM_QUEUES)
-+ return NOTIFY_DONE;
-+
-+ mtk_set_queue_speed(eth, dp->index + 3, s.base.speed);
-+
-+ return NOTIFY_DONE;
-+}
-+
- static int mtk_open(struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
-@@ -3049,7 +3204,8 @@ static int mtk_open(struct net_device *d
- refcount_inc(&eth->dma_refcnt);
-
- phylink_start(mac->phylink);
-- netif_start_queue(dev);
-+ netif_tx_start_all_queues(dev);
-+
- return 0;
- }
-
-@@ -3758,8 +3914,12 @@ static int mtk_unreg_dev(struct mtk_eth
- int i;
-
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ struct mtk_mac *mac;
- if (!eth->netdev[i])
- continue;
-+ mac = netdev_priv(eth->netdev[i]);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-+ unregister_netdevice_notifier(&mac->device_notifier);
- unregister_netdev(eth->netdev[i]);
- }
-
-@@ -3976,6 +4136,23 @@ static int mtk_set_rxnfc(struct net_devi
- return ret;
- }
-
-+static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb,
-+ struct net_device *sb_dev)
-+{
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ unsigned int queue = 0;
-+
-+ if (netdev_uses_dsa(dev))
-+ queue = skb_get_queue_mapping(skb) + 3;
-+ else
-+ queue = mac->id;
-+
-+ if (queue >= dev->num_tx_queues)
-+ queue = 0;
-+
-+ return queue;
-+}
-+
- static const struct ethtool_ops mtk_ethtool_ops = {
- .get_link_ksettings = mtk_get_link_ksettings,
- .set_link_ksettings = mtk_set_link_ksettings,
-@@ -4010,6 +4187,7 @@ static const struct net_device_ops mtk_n
- .ndo_setup_tc = mtk_eth_setup_tc,
- .ndo_bpf = mtk_xdp,
- .ndo_xdp_xmit = mtk_xdp_xmit,
-+ .ndo_select_queue = mtk_select_queue,
- };
-
- static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
-@@ -4019,6 +4197,7 @@ static int mtk_add_mac(struct mtk_eth *e
- struct phylink *phylink;
- struct mtk_mac *mac;
- int id, err;
-+ int txqs = 1;
-
- if (!_id) {
- dev_err(eth->dev, "missing mac id\n");
-@@ -4036,7 +4215,10 @@ static int mtk_add_mac(struct mtk_eth *e
- return -EINVAL;
- }
-
-- eth->netdev[id] = alloc_etherdev(sizeof(*mac));
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-+ txqs = MTK_QDMA_NUM_QUEUES;
-+
-+ eth->netdev[id] = alloc_etherdev_mqs(sizeof(*mac), txqs, 1);
- if (!eth->netdev[id]) {
- dev_err(eth->dev, "alloc_etherdev failed\n");
- return -ENOMEM;
-@@ -4144,6 +4326,11 @@ static int mtk_add_mac(struct mtk_eth *e
- else
- eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN;
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
-+ mac->device_notifier.notifier_call = mtk_device_event;
-+ register_netdevice_notifier(&mac->device_notifier);
-+ }
-+
- return 0;
-
- free_netdev:
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -22,6 +22,7 @@
- #include <linux/bpf_trace.h>
- #include "mtk_ppe.h"
-
-+#define MTK_QDMA_NUM_QUEUES 16
- #define MTK_QDMA_PAGE_SIZE 2048
- #define MTK_MAX_RX_LENGTH 1536
- #define MTK_MAX_RX_LENGTH_2K 2048
-@@ -216,8 +217,26 @@
- #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3)
-
- /* QDMA TX Queue Configuration Registers */
-+#define MTK_QTX_OFFSET 0x10
- #define QDMA_RES_THRES 4
-
-+/* QDMA Tx Queue Scheduler Configuration Registers */
-+#define MTK_QTX_SCH_TX_SEL BIT(31)
-+#define MTK_QTX_SCH_TX_SEL_V2 GENMASK(31, 30)
-+
-+#define MTK_QTX_SCH_LEAKY_BUCKET_EN BIT(30)
-+#define MTK_QTX_SCH_LEAKY_BUCKET_SIZE GENMASK(29, 28)
-+#define MTK_QTX_SCH_MIN_RATE_EN BIT(27)
-+#define MTK_QTX_SCH_MIN_RATE_MAN GENMASK(26, 20)
-+#define MTK_QTX_SCH_MIN_RATE_EXP GENMASK(19, 16)
-+#define MTK_QTX_SCH_MAX_RATE_WEIGHT GENMASK(15, 12)
-+#define MTK_QTX_SCH_MAX_RATE_EN BIT(11)
-+#define MTK_QTX_SCH_MAX_RATE_MAN GENMASK(10, 4)
-+#define MTK_QTX_SCH_MAX_RATE_EXP GENMASK(3, 0)
-+
-+/* QDMA TX Scheduler Rate Control Register */
-+#define MTK_QDMA_TX_SCH_MAX_WFQ BIT(15)
-+
- /* QDMA Global Configuration Register */
- #define MTK_RX_2B_OFFSET BIT(31)
- #define MTK_RX_BT_32DWORDS (3 << 11)
-@@ -236,6 +255,7 @@
- #define MTK_WCOMP_EN BIT(24)
- #define MTK_RESV_BUF (0x40 << 16)
- #define MTK_MUTLI_CNT (0x4 << 12)
-+#define MTK_LEAKY_BUCKET_EN BIT(11)
-
- /* QDMA Flow Control Register */
- #define FC_THRES_DROP_MODE BIT(20)
-@@ -266,8 +286,6 @@
- #define MTK_STAT_OFFSET 0x40
-
- /* QDMA TX NUM */
--#define MTK_QDMA_TX_NUM 16
--#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1)
- #define QID_BITS_V2(x) (((x) & 0x3f) << 16)
- #define MTK_QDMA_GMAC2_QID 8
-
-@@ -297,6 +315,7 @@
- #define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
- #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len)
- #define TX_DMA_SWC BIT(14)
-+#define TX_DMA_PQID GENMASK(3, 0)
-
- /* PDMA on MT7628 */
- #define TX_DMA_DONE BIT(31)
-@@ -957,6 +976,7 @@ struct mtk_reg_map {
- } pdma;
- struct {
- u32 qtx_cfg; /* tx queue configuration */
-+ u32 qtx_sch; /* tx queue scheduler configuration */
- u32 rx_ptr; /* rx base pointer */
- u32 rx_cnt_cfg; /* rx max count configuration */
- u32 qcrx_ptr; /* rx cpu pointer */
-@@ -974,6 +994,7 @@ struct mtk_reg_map {
- u32 fq_tail; /* fq tail pointer */
- u32 fq_count; /* fq free page count */
- u32 fq_blen; /* fq free page buffer length */
-+ u32 tx_sch_rate; /* tx scheduler rate control registers */
- } qdma;
- u32 gdm1_cnt;
- u32 gdma_to_ppe;
-@@ -1177,6 +1198,7 @@ struct mtk_mac {
- __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
- int hwlro_ip_cnt;
- unsigned int syscfg0;
-+ struct notifier_block device_notifier;
- };
-
- /* the struct describing the SoC. these are declared in the soc_xyz.c files */
diff --git a/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch b/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch
deleted file mode 100644
index 186df4bdc9..0000000000
--- a/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 18:16:03 +0200
-Subject: [PATCH] net: dsa: tag_mtk: assign per-port queues
-
-Keeps traffic sent to the switch within link speed limits
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/dsa/tag_mtk.c
-+++ b/net/dsa/tag_mtk.c
-@@ -25,6 +25,8 @@ static struct sk_buff *mtk_tag_xmit(stru
- u8 xmit_tpid;
- u8 *mtk_tag;
-
-+ skb_set_queue_mapping(skb, dp->index);
-+
- /* Build the special tag after the MAC Source Address. If VLAN header
- * is present, it's required that VLAN header and special tag is
- * being combined. Only in this way we can allow the switch can parse
diff --git a/target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch b/target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch
deleted file mode 100644
index d29177eee7..0000000000
--- a/target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 3 Nov 2022 17:49:44 +0100
-Subject: [PATCH] net: ethernet: mediatek: ppe: assign per-port queues
- for offloaded traffic
-
-Keeps traffic sent to the switch within link speed limits
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -399,6 +399,24 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- return 0;
- }
-
-+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ unsigned int queue)
-+{
-+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ *ib2 &= ~MTK_FOE_IB2_QID_V2;
-+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue);
-+ *ib2 |= MTK_FOE_IB2_PSE_QOS_V2;
-+ } else {
-+ *ib2 &= ~MTK_FOE_IB2_QID;
-+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID, queue);
-+ *ib2 |= MTK_FOE_IB2_PSE_QOS;
-+ }
-+
-+ return 0;
-+}
-+
- static bool
- mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry,
- struct mtk_foe_entry *data)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -68,7 +68,9 @@ enum {
- #define MTK_FOE_IB2_DSCP GENMASK(31, 24)
-
- /* CONFIG_MEDIATEK_NETSYS_V2 */
-+#define MTK_FOE_IB2_QID_V2 GENMASK(6, 0)
- #define MTK_FOE_IB2_PORT_MG_V2 BIT(7)
-+#define MTK_FOE_IB2_PSE_QOS_V2 BIT(8)
- #define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9)
- #define MTK_FOE_IB2_MULTICAST_V2 BIT(13)
- #define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19)
-@@ -351,6 +353,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
- int sid);
- int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
- int wdma_idx, int txq, int bss, int wcid);
-+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-+ unsigned int queue);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -188,7 +188,7 @@ mtk_flow_set_output_device(struct mtk_et
- int *wed_index)
- {
- struct mtk_wdma_info info = {};
-- int pse_port, dsa_port;
-+ int pse_port, dsa_port, queue;
-
- if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
- mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
-@@ -212,8 +212,6 @@ mtk_flow_set_output_device(struct mtk_et
- }
-
- dsa_port = mtk_flow_get_dsa_port(&dev);
-- if (dsa_port >= 0)
-- mtk_foe_entry_set_dsa(eth, foe, dsa_port);
-
- if (dev == eth->netdev[0])
- pse_port = 1;
-@@ -222,6 +220,14 @@ mtk_flow_set_output_device(struct mtk_et
- else
- return -EOPNOTSUPP;
-
-+ if (dsa_port >= 0) {
-+ mtk_foe_entry_set_dsa(eth, foe, dsa_port);
-+ queue = 3 + dsa_port;
-+ } else {
-+ queue = pse_port - 1;
-+ }
-+ mtk_foe_entry_set_queue(eth, foe, queue);
-+
- out:
- mtk_foe_entry_set_pse_port(eth, foe, pse_port);
-
diff --git a/target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch b/target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch
deleted file mode 100644
index 6b7f3d6018..0000000000
--- a/target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 8 Nov 2022 15:03:15 +0100
-Subject: [PATCH] net: dsa: add support for DSA rx offloading via
- metadata dst
-
-If a metadata dst is present with the type METADATA_HW_PORT_MUX on a dsa cpu
-port netdev, assume that it carries the port number and that there is no DSA
-tag present in the skb data.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/core/flow_dissector.c
-+++ b/net/core/flow_dissector.c
-@@ -971,12 +971,14 @@ bool __skb_flow_dissect(const struct net
- #if IS_ENABLED(CONFIG_NET_DSA)
- if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
- proto == htons(ETH_P_XDSA))) {
-+ struct metadata_dst *md_dst = skb_metadata_dst(skb);
- const struct dsa_device_ops *ops;
- int offset = 0;
-
- ops = skb->dev->dsa_ptr->tag_ops;
- /* Only DSA header taggers break flow dissection */
-- if (ops->needed_headroom) {
-+ if (ops->needed_headroom &&
-+ (!md_dst || md_dst->type != METADATA_HW_PORT_MUX)) {
- if (ops->flow_dissect)
- ops->flow_dissect(skb, &proto, &offset);
- else
---- a/net/dsa/dsa.c
-+++ b/net/dsa/dsa.c
-@@ -11,6 +11,7 @@
- #include <linux/netdevice.h>
- #include <linux/sysfs.h>
- #include <linux/ptp_classify.h>
-+#include <net/dst_metadata.h>
-
- #include "dsa_priv.h"
-
-@@ -216,6 +217,7 @@ static bool dsa_skb_defer_rx_timestamp(s
- static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *pt, struct net_device *unused)
- {
-+ struct metadata_dst *md_dst = skb_metadata_dst(skb);
- struct dsa_port *cpu_dp = dev->dsa_ptr;
- struct sk_buff *nskb = NULL;
- struct dsa_slave_priv *p;
-@@ -229,7 +231,22 @@ static int dsa_switch_rcv(struct sk_buff
- if (!skb)
- return 0;
-
-- nskb = cpu_dp->rcv(skb, dev);
-+ if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) {
-+ unsigned int port = md_dst->u.port_info.port_id;
-+
-+ skb_dst_drop(skb);
-+ if (!skb_has_extensions(skb))
-+ skb->slow_gro = 0;
-+
-+ skb->dev = dsa_master_find_slave(dev, 0, port);
-+ if (likely(skb->dev)) {
-+ dsa_default_offload_fwd_mark(skb);
-+ nskb = skb;
-+ }
-+ } else {
-+ nskb = cpu_dp->rcv(skb, dev);
-+ }
-+
- if (!nskb) {
- kfree_skb(skb);
- return 0;
diff --git a/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch
deleted file mode 100644
index 53d8ff472e..0000000000
--- a/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 11:01:12 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix VLAN rx hardware
- acceleration
-
-- enable VLAN untagging for PDMA rx
-- make it possible to disable the feature via ethtool
-- pass VLAN tag to the DSA driver
-- untag special tag on PDMA only if no non-DSA devices are in use
-- disable special tag untagging on 7986 for now, since it's not working yet
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -23,6 +23,7 @@
- #include <linux/jhash.h>
- #include <linux/bitfield.h>
- #include <net/dsa.h>
-+#include <net/dst_metadata.h>
-
- #include "mtk_eth_soc.h"
- #include "mtk_wed.h"
-@@ -2020,16 +2021,22 @@ static int mtk_poll_rx(struct napi_struc
- htons(RX_DMA_VPID(trxd.rxd4)),
- RX_DMA_VID(trxd.rxd4));
- } else if (trxd.rxd2 & RX_DMA_VTAG) {
-- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-+ __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)),
- RX_DMA_VID(trxd.rxd3));
- }
-+ }
-+
-+ /* When using VLAN untagging in combination with DSA, the
-+ * hardware treats the MTK special tag as a VLAN and untags it.
-+ */
-+ if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) {
-+ unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0);
-
-- /* If the device is attached to a dsa switch, the special
-- * tag inserted in VLAN field by hw switch can * be offloaded
-- * by RX HW VLAN offload. Clear vlan info.
-- */
-- if (netdev_uses_dsa(netdev))
-- __vlan_hwaccel_clear_tag(skb);
-+ if (port < ARRAY_SIZE(eth->dsa_meta) &&
-+ eth->dsa_meta[port])
-+ skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
-+
-+ __vlan_hwaccel_clear_tag(skb);
- }
-
- skb_record_rx_queue(skb, 0);
-@@ -2857,15 +2864,30 @@ static netdev_features_t mtk_fix_feature
-
- static int mtk_set_features(struct net_device *dev, netdev_features_t features)
- {
-- int err = 0;
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+ netdev_features_t diff = dev->features ^ features;
-+ int i;
-+
-+ if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
-+ mtk_hwlro_netdev_disable(dev);
-
-- if (!((dev->features ^ features) & NETIF_F_LRO))
-+ /* Set RX VLAN offloading */
-+ if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
- return 0;
-
-- if (!(features & NETIF_F_LRO))
-- mtk_hwlro_netdev_disable(dev);
-+ mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
-+ MTK_CDMP_EG_CTRL);
-
-- return err;
-+ /* sync features with other MAC */
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i] || eth->netdev[i] == dev)
-+ continue;
-+ eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
-+ eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
-+ }
-+
-+ return 0;
- }
-
- /* wait for DMA to finish whatever it is doing before we start using it again */
-@@ -3162,11 +3184,45 @@ found:
- return NOTIFY_DONE;
- }
-
-+static bool mtk_uses_dsa(struct net_device *dev)
-+{
-+#if IS_ENABLED(CONFIG_NET_DSA)
-+ return netdev_uses_dsa(dev) &&
-+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK;
-+#else
-+ return false;
-+#endif
-+}
-+
- static int mtk_open(struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-- int err;
-+ int i, err;
-+
-+ if (mtk_uses_dsa(dev) && !eth->prog) {
-+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+ struct metadata_dst *md_dst = eth->dsa_meta[i];
-+
-+ if (md_dst)
-+ continue;
-+
-+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-+ GFP_KERNEL);
-+ if (!md_dst)
-+ return -ENOMEM;
-+
-+ md_dst->u.port_info.port_id = i;
-+ eth->dsa_meta[i] = md_dst;
-+ }
-+ } else {
-+ /* Hardware special tag parsing needs to be disabled if at least
-+ * one MAC does not use DSA.
-+ */
-+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+ val &= ~MTK_CDMP_STAG_EN;
-+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-+ }
-
- err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
- if (err) {
-@@ -3687,6 +3743,10 @@ static int mtk_hw_init(struct mtk_eth *e
- */
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
-+ }
-
- /* Enable RX VLan Offloading */
- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-@@ -3906,6 +3966,12 @@ static int mtk_free_dev(struct mtk_eth *
- free_netdev(eth->netdev[i]);
- }
-
-+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+ if (!eth->dsa_meta[i])
-+ break;
-+ metadata_dst_free(eth->dsa_meta[i]);
-+ }
-+
- return 0;
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -22,6 +22,9 @@
- #include <linux/bpf_trace.h>
- #include "mtk_ppe.h"
-
-+#define MTK_MAX_DSA_PORTS 7
-+#define MTK_DSA_PORT_MASK GENMASK(2, 0)
-+
- #define MTK_QDMA_NUM_QUEUES 16
- #define MTK_QDMA_PAGE_SIZE 2048
- #define MTK_MAX_RX_LENGTH 1536
-@@ -105,6 +108,9 @@
- #define MTK_CDMQ_IG_CTRL 0x1400
- #define MTK_CDMQ_STAG_EN BIT(0)
-
-+/* CDMQ Exgress Control Register */
-+#define MTK_CDMQ_EG_CTRL 0x1404
-+
- /* CDMP Ingress Control Register */
- #define MTK_CDMP_IG_CTRL 0x400
- #define MTK_CDMP_STAG_EN BIT(0)
-@@ -1164,6 +1170,8 @@ struct mtk_eth {
-
- int ip_align;
-
-+ struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS];
-+
- struct mtk_ppe *ppe[2];
- struct rhashtable flow_table;
-
diff --git a/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch b/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch
deleted file mode 100644
index 08d72fc820..0000000000
--- a/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sat, 28 Jan 2023 12:42:32 +0300
-Subject: [PATCH] net: ethernet: mtk_eth_soc: disable hardware DSA untagging
- for second MAC
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-According to my tests on MT7621AT and MT7623NI SoCs, hardware DSA untagging
-won't work on the second MAC. Therefore, disable this feature when the
-second MAC of the MT7621 and MT7623 SoCs is being used.
-
-Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging")
-Link: https://lore.kernel.org/netdev/6249fc14-b38a-c770-36b4-5af6d41c21d3@arinc9.com/
-Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20230128094232.2451947-1-arinc.unal@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3200,7 +3200,8 @@ static int mtk_open(struct net_device *d
- struct mtk_eth *eth = mac->hw;
- int i, err;
-
-- if (mtk_uses_dsa(dev) && !eth->prog) {
-+ if ((mtk_uses_dsa(dev) && !eth->prog) &&
-+ !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) {
- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
- struct metadata_dst *md_dst = eth->dsa_meta[i];
-
-@@ -3217,7 +3218,8 @@ static int mtk_open(struct net_device *d
- }
- } else {
- /* Hardware special tag parsing needs to be disabled if at least
-- * one MAC does not use DSA.
-+ * one MAC does not use DSA, or the second MAC of the MT7621 and
-+ * MT7623 SoCs is being used.
- */
- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
- val &= ~MTK_CDMP_STAG_EN;
diff --git a/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch b/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch
deleted file mode 100644
index 30c32d5cce..0000000000
--- a/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sun, 5 Feb 2023 20:53:31 +0300
-Subject: [PATCH] net: ethernet: mtk_eth_soc: enable special tag when any MAC
- uses DSA
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The special tag is only enabled when the first MAC uses DSA. However, it
-must be enabled when any MAC uses DSA. Change the check accordingly.
-
-This fixes hardware DSA untagging not working on the second MAC of the
-MT7621 and MT7623 SoCs, and likely other SoCs too. Therefore, remove the
-check that disables hardware DSA untagging for the second MAC of the MT7621
-and MT7623 SoCs.
-
-Fixes: a1f47752fd62 ("net: ethernet: mtk_eth_soc: disable hardware DSA untagging for second MAC")
-Co-developed-by: Richard van Schagen <richard@routerhints.com>
-Signed-off-by: Richard van Schagen <richard@routerhints.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3135,7 +3135,7 @@ static void mtk_gdm_config(struct mtk_et
-
- val |= config;
-
-- if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0]))
-+ if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i]))
- val |= MTK_GDMA_SPECIAL_TAG;
-
- mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-@@ -3200,8 +3200,7 @@ static int mtk_open(struct net_device *d
- struct mtk_eth *eth = mac->hw;
- int i, err;
-
-- if ((mtk_uses_dsa(dev) && !eth->prog) &&
-- !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) {
-+ if (mtk_uses_dsa(dev) && !eth->prog) {
- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
- struct metadata_dst *md_dst = eth->dsa_meta[i];
-
-@@ -3218,8 +3217,7 @@ static int mtk_open(struct net_device *d
- }
- } else {
- /* Hardware special tag parsing needs to be disabled if at least
-- * one MAC does not use DSA, or the second MAC of the MT7621 and
-- * MT7623 SoCs is being used.
-+ * one MAC does not use DSA.
- */
- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
- val &= ~MTK_CDMP_STAG_EN;
diff --git a/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch b/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch
deleted file mode 100644
index eb3b0c63bc..0000000000
--- a/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 7 Feb 2023 12:30:27 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix DSA TX tag hwaccel for switch
- port 0
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Arınç reports that on his MT7621AT Unielec U7621-06 board and MT7623NI
-Bananapi BPI-R2, packets received by the CPU over mt7530 switch port 0
-(of which this driver acts as the DSA master) are not processed
-correctly by software. More precisely, they arrive without a DSA tag
-(in packet or in the hwaccel area - skb_metadata_dst()), so DSA cannot
-demux them towards the switch's interface for port 0. Traffic from other
-ports receives a skb_metadata_dst() with the correct port and is demuxed
-properly.
-
-Looking at mtk_poll_rx(), it becomes apparent that this driver uses the
-skb vlan hwaccel area:
-
- union {
- u32 vlan_all;
- struct {
- __be16 vlan_proto;
- __u16 vlan_tci;
- };
- };
-
-as a temporary storage for the VLAN hwaccel tag, or the DSA hwaccel tag.
-If this is a DSA master it's a DSA hwaccel tag, and finally clears up
-the skb VLAN hwaccel header.
-
-I'm guessing that the problem is the (mis)use of API.
-skb_vlan_tag_present() looks like this:
-
- #define skb_vlan_tag_present(__skb) (!!(__skb)->vlan_all)
-
-So if both vlan_proto and vlan_tci are zeroes, skb_vlan_tag_present()
-returns precisely false. I don't know for sure what is the format of the
-DSA hwaccel tag, but I surely know that lowermost 3 bits of vlan_proto
-are 0 when receiving from port 0:
-
- unsigned int port = vlan_proto & GENMASK(2, 0);
-
-If the RX descriptor has no other bits set to non-zero values in
-RX_DMA_VTAG, then the call to __vlan_hwaccel_put_tag() will not, in
-fact, make the subsequent skb_vlan_tag_present() return true, because
-it's implemented like this:
-
-static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb,
- __be16 vlan_proto, u16 vlan_tci)
-{
- skb->vlan_proto = vlan_proto;
- skb->vlan_tci = vlan_tci;
-}
-
-What we need to do to fix this problem (assuming this is the problem) is
-to stop using skb->vlan_all as temporary storage for driver affairs, and
-just create some local variables that serve the same purpose, but
-hopefully better. Instead of calling skb_vlan_tag_present(), let's look
-at a boolean has_hwaccel_tag which we set to true when the RX DMA
-descriptors have something. Disambiguate based on netdev_uses_dsa()
-whether this is a VLAN or DSA hwaccel tag, and only call
-__vlan_hwaccel_put_tag() if we're certain it's a VLAN tag.
-
-Arınç confirms that the treatment works, so this validates the
-assumption.
-
-Link: https://lore.kernel.org/netdev/704f3a72-fc9e-714a-db54-272e17612637@arinc9.com/
-Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging")
-Reported-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1876,7 +1876,9 @@ static int mtk_poll_rx(struct napi_struc
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
-+ bool has_hwaccel_tag = false;
- struct net_device *netdev;
-+ u16 vlan_proto, vlan_tci;
- dma_addr_t dma_addr;
- u32 hash, reason;
- int mac = 0;
-@@ -2016,27 +2018,29 @@ static int mtk_poll_rx(struct napi_struc
-
- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- if (trxd.rxd3 & RX_DMA_VTAG_V2)
-- __vlan_hwaccel_put_tag(skb,
-- htons(RX_DMA_VPID(trxd.rxd4)),
-- RX_DMA_VID(trxd.rxd4));
-+ if (trxd.rxd3 & RX_DMA_VTAG_V2) {
-+ vlan_proto = RX_DMA_VPID(trxd.rxd4);
-+ vlan_tci = RX_DMA_VID(trxd.rxd4);
-+ has_hwaccel_tag = true;
-+ }
- } else if (trxd.rxd2 & RX_DMA_VTAG) {
-- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)),
-- RX_DMA_VID(trxd.rxd3));
-+ vlan_proto = RX_DMA_VPID(trxd.rxd3);
-+ vlan_tci = RX_DMA_VID(trxd.rxd3);
-+ has_hwaccel_tag = true;
- }
- }
-
- /* When using VLAN untagging in combination with DSA, the
- * hardware treats the MTK special tag as a VLAN and untags it.
- */
-- if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) {
-- unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0);
-+ if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
-+ unsigned int port = vlan_proto & GENMASK(2, 0);
-
- if (port < ARRAY_SIZE(eth->dsa_meta) &&
- eth->dsa_meta[port])
- skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
--
-- __vlan_hwaccel_clear_tag(skb);
-+ } else if (has_hwaccel_tag) {
-+ __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
- }
-
- skb_record_rx_queue(skb, 0);
diff --git a/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch b/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch
deleted file mode 100644
index a3bb1c5db7..0000000000
--- a/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Date: Sun, 12 Feb 2023 07:51:51 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: No need to clear memory after a
- dma_alloc_coherent() call
-
-dma_alloc_coherent() already clears the allocated memory, there is no need
-to explicitly call memset().
-
-Moreover, it is likely that the size in the memset() is incorrect and
-should be "size * sizeof(*ring->desc)".
-
-Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Link: https://lore.kernel.org/r/d5acce7dd108887832c9719f62c7201b4c83b3fb.1676184599.git.christophe.jaillet@wanadoo.fr
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -779,7 +779,6 @@ mtk_wed_rro_ring_alloc(struct mtk_wed_de
-
- ring->desc_size = sizeof(*ring->desc);
- ring->size = size;
-- memset(ring->desc, 0, size);
-
- return 0;
- }
diff --git a/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch b/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch
deleted file mode 100644
index e043a681da..0000000000
--- a/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 7 Dec 2022 15:04:54 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: fix some possible NULL pointer
- dereferences
-
-Fix possible NULL pointer dereference in mtk_wed_detach routine checking
-wo pointer is properly allocated before running mtk_wed_wo_reset() and
-mtk_wed_wo_deinit().
-Even if it is just a theoretical issue at the moment check wo pointer is
-not NULL in mtk_wed_mcu_msg_update.
-Moreover, honor mtk_wed_mcu_send_msg return value in mtk_wed_wo_reset()
-
-Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support")
-Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -174,9 +174,10 @@ mtk_wed_wo_reset(struct mtk_wed_device *
- mtk_wdma_tx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-
-- mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-- MTK_WED_WO_CMD_CHANGE_STATE, &state,
-- sizeof(state), false);
-+ if (mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-+ MTK_WED_WO_CMD_CHANGE_STATE, &state,
-+ sizeof(state), false))
-+ return;
-
- if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val,
- val == MTK_WED_WOIF_DISABLE_DONE,
-@@ -632,9 +633,11 @@ mtk_wed_detach(struct mtk_wed_device *de
- mtk_wed_free_tx_rings(dev);
-
- if (mtk_wed_get_rx_capa(dev)) {
-- mtk_wed_wo_reset(dev);
-+ if (hw->wed_wo)
-+ mtk_wed_wo_reset(dev);
- mtk_wed_free_rx_rings(dev);
-- mtk_wed_wo_deinit(hw);
-+ if (hw->wed_wo)
-+ mtk_wed_wo_deinit(hw);
- }
-
- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -207,6 +207,9 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- if (dev->hw->version == 1)
- return 0;
-
-+ if (WARN_ON(!wo))
-+ return -ENODEV;
-+
- return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len,
- true);
- }
diff --git a/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch b/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch
deleted file mode 100644
index 0afe7106e5..0000000000
--- a/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 7 Dec 2022 15:04:55 +0100
-Subject: [PATCH] net: ethernet: mtk_wed: fix possible deadlock if
- mtk_wed_wo_init fails
-
-Introduce __mtk_wed_detach() in order to avoid a deadlock in
-mtk_wed_attach routine if mtk_wed_wo_init fails since both
-mtk_wed_attach and mtk_wed_detach run holding hw_lock mutex.
-
-Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -619,12 +619,10 @@ mtk_wed_deinit(struct mtk_wed_device *de
- }
-
- static void
--mtk_wed_detach(struct mtk_wed_device *dev)
-+__mtk_wed_detach(struct mtk_wed_device *dev)
- {
- struct mtk_wed_hw *hw = dev->hw;
-
-- mutex_lock(&hw_lock);
--
- mtk_wed_deinit(dev);
-
- mtk_wdma_rx_reset(dev);
-@@ -657,6 +655,13 @@ mtk_wed_detach(struct mtk_wed_device *de
- module_put(THIS_MODULE);
-
- hw->wed_dev = NULL;
-+}
-+
-+static void
-+mtk_wed_detach(struct mtk_wed_device *dev)
-+{
-+ mutex_lock(&hw_lock);
-+ __mtk_wed_detach(dev);
- mutex_unlock(&hw_lock);
- }
-
-@@ -1538,8 +1543,10 @@ mtk_wed_attach(struct mtk_wed_device *de
- ret = mtk_wed_wo_init(hw);
- }
- out:
-- if (ret)
-- mtk_wed_detach(dev);
-+ if (ret) {
-+ dev_err(dev->hw->dev, "failed to attach wed device\n");
-+ __mtk_wed_detach(dev);
-+ }
- unlock:
- mutex_unlock(&hw_lock);
-
diff --git a/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch b/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch
deleted file mode 100644
index f6d91d3080..0000000000
--- a/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 24 Mar 2023 14:56:58 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix tx throughput regression with
- direct 1G links
-
-Using the QDMA tx scheduler to throttle tx to line speed works fine for
-switch ports, but apparently caused a regression on non-switch ports.
-
-Based on a number of tests, it seems that this throttling can be safely
-dropped without re-introducing the issues on switch ports that the
-tx scheduling changes resolved.
-
-Link: https://lore.kernel.org/netdev/trinity-92c3826f-c2c8-40af-8339-bc6d0d3ffea4-1678213958520@3c-app-gmx-bs16/
-Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues")
-Reported-by: Frank Wunderlich <frank-w@public-files.de>
-Reported-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -718,8 +718,6 @@ static void mtk_mac_link_up(struct phyli
- break;
- }
-
-- mtk_set_queue_speed(mac->hw, mac->id, speed);
--
- /* Configure duplex */
- if (duplex == DUPLEX_FULL)
- mcr |= MAC_MCR_FORCE_DPX;
diff --git a/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch b/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch
deleted file mode 100644
index 850b806410..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From b6a709cb51f7bdc55c01cec886098a9753ce8c28 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:42 +0100
-Subject: [PATCH 01/10] net: mtk_eth_soc: add definitions for PCS
-
-As a result of help from Frank Wunderlich to investigate and test, we
-know a bit more about the PCS on the Mediatek platforms. Update the
-definitions from this investigation.
-
-This PCS appears similar, but not identical to the Lynx PCS.
-
-Although not included in this patch, but for future reference, the PHY
-ID registers at offset 4 read as 0x4d544950 'MTIP'.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++++++++---
- 1 file changed, 10 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -504,8 +504,10 @@
- #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-
- /* SGMII subsystem config registers */
--/* Register to auto-negotiation restart */
-+/* BMCR (low 16) BMSR (high 16) */
- #define SGMSYS_PCS_CONTROL_1 0x0
-+#define SGMII_BMCR GENMASK(15, 0)
-+#define SGMII_BMSR GENMASK(31, 16)
- #define SGMII_AN_RESTART BIT(9)
- #define SGMII_ISOLATE BIT(10)
- #define SGMII_AN_ENABLE BIT(12)
-@@ -515,13 +517,18 @@
- #define SGMII_PCS_FAULT BIT(23)
- #define SGMII_AN_EXPANSION_CLR BIT(30)
-
-+#define SGMSYS_PCS_ADVERTISE 0x8
-+#define SGMII_ADVERTISE GENMASK(15, 0)
-+#define SGMII_LPA GENMASK(31, 16)
-+
- /* Register to programmable link timer, the unit in 2 * 8ns */
- #define SGMSYS_PCS_LINK_TIMER 0x18
--#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & GENMASK(19, 0))
-+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
-+#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
-
- /* Register to control remote fault */
- #define SGMSYS_SGMII_MODE 0x20
--#define SGMII_IF_MODE_BIT0 BIT(0)
-+#define SGMII_IF_MODE_SGMII BIT(0)
- #define SGMII_SPEED_DUPLEX_AN BIT(1)
- #define SGMII_SPEED_MASK GENMASK(3, 2)
- #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
diff --git a/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch b/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch
deleted file mode 100644
index 4ea428c9d6..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 5cf7797526ee81bea0f627bccaa3d887f48f53e0 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:47 +0100
-Subject: [PATCH 02/10] net: mtk_eth_soc: eliminate unnecessary error handling
-
-The functions called by the pcs_config() method always return zero, so
-there is no point trying to handle an error from these functions. Make
-these functions void, eliminate the "err" variable and simply return
-zero from the pcs_config() function itself.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++------------
- 1 file changed, 6 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -20,7 +20,7 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
- }
-
- /* For SGMII interface mode */
--static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
-+static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
- unsigned int val;
-
-@@ -39,16 +39,13 @@ static int mtk_pcs_setup_mode_an(struct
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
- val &= ~SGMII_PHYA_PWD;
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
--
-- return 0;
--
- }
-
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
- * fixed speed.
- */
--static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
-- phy_interface_t interface)
-+static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
-+ phy_interface_t interface)
- {
- unsigned int val;
-
-@@ -73,8 +70,6 @@ static int mtk_pcs_setup_mode_force(stru
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
- val &= ~SGMII_PHYA_PWD;
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
--
-- return 0;
- }
-
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -83,15 +78,14 @@ static int mtk_pcs_config(struct phylink
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- int err = 0;
-
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
-- err = mtk_pcs_setup_mode_force(mpcs, interface);
-+ mtk_pcs_setup_mode_force(mpcs, interface);
- else if (phylink_autoneg_inband(mode))
-- err = mtk_pcs_setup_mode_an(mpcs);
-+ mtk_pcs_setup_mode_an(mpcs);
-
-- return err;
-+ return 0;
- }
-
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
diff --git a/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch b/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch
deleted file mode 100644
index 64a4a72fa6..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From c000dca098002da193b98099df051c9ead0cacb4 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:52 +0100
-Subject: [PATCH 03/10] net: mtk_eth_soc: add pcs_get_state() implementation
-
-Add a pcs_get_state() implementation which uses the advertisements
-to compute the resulting link modes, and BMSR contents to determine
-negotiation and link status.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -19,6 +19,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
- return container_of(pcs, struct mtk_pcs, pcs);
- }
-
-+static void mtk_pcs_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
-+{
-+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ unsigned int bm, adv;
-+
-+ /* Read the BMSR and LPA */
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+
-+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-+ FIELD_GET(SGMII_LPA, adv));
-+}
-+
- /* For SGMII interface mode */
- static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
-@@ -117,6 +131,7 @@ static void mtk_pcs_link_up(struct phyli
- }
-
- static const struct phylink_pcs_ops mtk_pcs_ops = {
-+ .pcs_get_state = mtk_pcs_get_state,
- .pcs_config = mtk_pcs_config,
- .pcs_an_restart = mtk_pcs_restart_an,
- .pcs_link_up = mtk_pcs_link_up,
diff --git a/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch b/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch
deleted file mode 100644
index 24610fe11e..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From 0d2351dc2768061689abd4de1529fa206bbd574e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:58 +0100
-Subject: [PATCH 04/10] net: mtk_eth_soc: convert mtk_sgmii to use
- regmap_update_bits()
-
-mtk_sgmii does a lot of read-modify-write operations, for which there
-is a specific regmap function. Use this function instead of open-coding
-the operations.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 61 ++++++++++-------------
- 1 file changed, 26 insertions(+), 35 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -36,23 +36,18 @@ static void mtk_pcs_get_state(struct phy
- /* For SGMII interface mode */
- static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
-- unsigned int val;
--
- /* Setup the link timer and QPHY power up inside SGMIISYS */
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
- SGMII_LINK_TIMER_DEFAULT);
-
-- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val |= SGMII_REMOTE_FAULT_DIS;
-- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
--
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
-- val |= SGMII_AN_RESTART;
-- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
--
-- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-- val &= ~SGMII_PHYA_PWD;
-- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
-+
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_RESTART, SGMII_AN_RESTART);
-+
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
- }
-
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
-@@ -61,29 +56,26 @@ static void mtk_pcs_setup_mode_an(struct
- static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
- phy_interface_t interface)
- {
-- unsigned int val;
-+ unsigned int rgc3;
-
-- regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
-- val &= ~RG_PHY_SPEED_MASK;
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- val |= RG_PHY_SPEED_3_125G;
-- regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
-+ rgc3 = RG_PHY_SPEED_3_125G;
-+
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ RG_PHY_SPEED_3_125G, rgc3);
-
- /* Disable SGMII AN */
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
-- val &= ~SGMII_AN_ENABLE;
-- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_ENABLE, 0);
-
- /* Set the speed etc but leave the duplex unchanged */
-- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
-- val |= SGMII_SPEED_1000;
-- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
-+ SGMII_SPEED_1000);
-
- /* Release PHYA power down state */
-- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-- val &= ~SGMII_PHYA_PWD;
-- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
- }
-
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -105,29 +97,28 @@ static int mtk_pcs_config(struct phylink
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int val;
-
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
-- val |= SGMII_AN_RESTART;
-- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_RESTART, SGMII_AN_RESTART);
- }
-
- static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface, int speed, int duplex)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int val;
-+ unsigned int sgm_mode;
-
- if (!phy_interface_mode_is_8023z(interface))
- return;
-
- /* SGMII force duplex setting */
-- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val &= ~SGMII_DUPLEX_FULL;
- if (duplex == DUPLEX_FULL)
-- val |= SGMII_DUPLEX_FULL;
-+ sgm_mode = SGMII_DUPLEX_FULL;
-+ else
-+ sgm_mode = 0;
-
-- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_DUPLEX_FULL, sgm_mode);
- }
-
- static const struct phylink_pcs_ops mtk_pcs_ops = {
diff --git a/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch b/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch
deleted file mode 100644
index ba76ca40ff..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 12198c3a410fe69843e335c1bbf6d4c2a4d48e4e Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:03 +0100
-Subject: [PATCH 05/10] net: mtk_eth_soc: add out of band forcing of speed and
- duplex in pcs_link_up
-
-Add support for forcing the link speed and duplex setting in the
-pcs_link_up() method for out of band modes, which will be useful when
-we finish converting the pcs_config() method. Until then, we still have
-to force duplex for 802.3z modes to work correctly.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 28 ++++++++++++++---------
- 1 file changed, 17 insertions(+), 11 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -108,17 +108,23 @@ static void mtk_pcs_link_up(struct phyli
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int sgm_mode;
-
-- if (!phy_interface_mode_is_8023z(interface))
-- return;
-+ if (!phylink_autoneg_inband(mode) ||
-+ phy_interface_mode_is_8023z(interface)) {
-+ /* Force the speed and duplex setting */
-+ if (speed == SPEED_10)
-+ sgm_mode = SGMII_SPEED_10;
-+ else if (speed == SPEED_100)
-+ sgm_mode = SGMII_SPEED_100;
-+ else
-+ sgm_mode = SGMII_SPEED_1000;
-
-- /* SGMII force duplex setting */
-- if (duplex == DUPLEX_FULL)
-- sgm_mode = SGMII_DUPLEX_FULL;
-- else
-- sgm_mode = 0;
-+ if (duplex == DUPLEX_FULL)
-+ sgm_mode |= SGMII_DUPLEX_FULL;
-
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_DUPLEX_FULL, sgm_mode);
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
-+ sgm_mode);
-+ }
- }
-
- static const struct phylink_pcs_ops mtk_pcs_ops = {
diff --git a/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch b/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch
deleted file mode 100644
index b76e159275..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 6f38fffe2179dd29612aea2c67c46ed6682b4e46 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:08 +0100
-Subject: [PATCH 06/10] net: mtk_eth_soc: move PHY power up
-
-The PHY power up is common to both configuration paths, so move it into
-the parent function. We need to do this for all serdes modes.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -45,9 +45,6 @@ static void mtk_pcs_setup_mode_an(struct
-
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_RESTART, SGMII_AN_RESTART);
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
- }
-
- /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
-@@ -72,10 +69,6 @@ static void mtk_pcs_setup_mode_force(str
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
- SGMII_SPEED_1000);
--
-- /* Release PHYA power down state */
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
- }
-
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -91,6 +84,10 @@ static int mtk_pcs_config(struct phylink
- else if (phylink_autoneg_inband(mode))
- mtk_pcs_setup_mode_an(mpcs);
-
-+ /* Release PHYA power down state */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch b/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch
deleted file mode 100644
index cd9f0699b3..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f752c0df13dfeb721c11d3debb79f08cf437344f Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:13 +0100
-Subject: [PATCH 07/10] net: mtk_eth_soc: move interface speed selection
-
-Move the selection of the underlying interface speed to the pcs_config
-function, so we always program the interface speed.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++++++--------
- 1 file changed, 10 insertions(+), 8 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -53,14 +53,6 @@ static void mtk_pcs_setup_mode_an(struct
- static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
- phy_interface_t interface)
- {
-- unsigned int rgc3;
--
-- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- rgc3 = RG_PHY_SPEED_3_125G;
--
-- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-- RG_PHY_SPEED_3_125G, rgc3);
--
- /* Disable SGMII AN */
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_ENABLE, 0);
-@@ -77,6 +69,16 @@ static int mtk_pcs_config(struct phylink
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ unsigned int rgc3;
-+
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+ rgc3 = RG_PHY_SPEED_3_125G;
-+ else
-+ rgc3 = 0;
-+
-+ /* Configure the underlying interface speed */
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ RG_PHY_SPEED_3_125G, rgc3);
-
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
diff --git a/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch b/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch
deleted file mode 100644
index f08358e963..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From c125c66ea71b9377ae2478c4f1b87b180cc5c6ef Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:18 +0100
-Subject: [PATCH 08/10] net: mtk_eth_soc: add advertisement programming
-
-Program the advertisement into the mtk PCS block.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -70,16 +70,27 @@ static int mtk_pcs_config(struct phylink
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int rgc3;
-+ int advertise;
-+ bool changed;
-
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- rgc3 = RG_PHY_SPEED_3_125G;
- else
- rgc3 = 0;
-
-+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-+ advertising);
-+ if (advertise < 0)
-+ return advertise;
-+
- /* Configure the underlying interface speed */
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-
-+ /* Update the advertisement, noting whether it has changed */
-+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-+ SGMII_ADVERTISE, advertise, &changed);
-+
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
- mtk_pcs_setup_mode_force(mpcs, interface);
-@@ -90,7 +101,7 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, 0);
-
-- return 0;
-+ return changed;
- }
-
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
diff --git a/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch b/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch
deleted file mode 100644
index 602d52c6f4..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 3027d89f87707e7f3e5b683e0d37a32afb5bde96 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:23 +0100
-Subject: [PATCH 09/10] net: mtk_eth_soc: move and correct link timer
- programming
-
-Program the link timer appropriately for the interface mode being
-used, using the newly introduced phylink helper that provides the
-nanosecond link timer interval.
-
-The intervals are 1.6ms for SGMII based protocols and 10ms for
-802.3z based protocols.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++-----
- 1 file changed, 8 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -36,10 +36,6 @@ static void mtk_pcs_get_state(struct phy
- /* For SGMII interface mode */
- static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
- {
-- /* Setup the link timer and QPHY power up inside SGMIISYS */
-- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
-- SGMII_LINK_TIMER_DEFAULT);
--
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
-
-@@ -69,8 +65,8 @@ static int mtk_pcs_config(struct phylink
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ int advertise, link_timer;
- unsigned int rgc3;
-- int advertise;
- bool changed;
-
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-@@ -83,6 +79,10 @@ static int mtk_pcs_config(struct phylink
- if (advertise < 0)
- return advertise;
-
-+ link_timer = phylink_get_link_timer_ns(interface);
-+ if (link_timer < 0)
-+ return link_timer;
-+
- /* Configure the underlying interface speed */
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-@@ -91,6 +91,9 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
- SGMII_ADVERTISE, advertise, &changed);
-
-+ /* Setup the link timer and QPHY power up inside SGMIISYS */
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-+
- /* Setup SGMIISYS with the determined property */
- if (interface != PHY_INTERFACE_MODE_SGMII)
- mtk_pcs_setup_mode_force(mpcs, interface);
diff --git a/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch b/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch
deleted file mode 100644
index 0e9a0535a7..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From 81b0f12a2a8a1699a7d49c3995e5f71e4ec018e6 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:11:28 +0100
-Subject: [PATCH 10/10] net: mtk_eth_soc: add support for in-band 802.3z
- negotiation
-
-As a result of help from Frank Wunderlich to investigate and test, we
-now know how to program this PCS for in-band 802.3z negotiation. Add
-support for this by moving the contents of the two functions into the
-common mtk_pcs_config() function and adding the register settings for
-802.3z negotiation.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 77 ++++++++++++-----------
- 1 file changed, 42 insertions(+), 35 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -33,41 +33,15 @@ static void mtk_pcs_get_state(struct phy
- FIELD_GET(SGMII_LPA, adv));
- }
-
--/* For SGMII interface mode */
--static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
--{
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_RESTART, SGMII_AN_RESTART);
--}
--
--/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
-- * fixed speed.
-- */
--static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
-- phy_interface_t interface)
--{
-- /* Disable SGMII AN */
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_ENABLE, 0);
--
-- /* Set the speed etc but leave the duplex unchanged */
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
-- SGMII_SPEED_1000);
--}
--
- static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac)
- {
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-+ unsigned int rgc3, sgm_mode, bmcr;
- int advertise, link_timer;
-- unsigned int rgc3;
-- bool changed;
-+ bool changed, use_an;
-
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- rgc3 = RG_PHY_SPEED_3_125G;
-@@ -83,6 +57,37 @@ static int mtk_pcs_config(struct phylink
- if (link_timer < 0)
- return link_timer;
-
-+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
-+ * we assume that fixes it's speed at bitrate = line rate (in
-+ * other words, 1000Mbps or 2500Mbps).
-+ */
-+ if (interface == PHY_INTERFACE_MODE_SGMII) {
-+ sgm_mode = SGMII_IF_MODE_SGMII;
-+ if (phylink_autoneg_inband(mode)) {
-+ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-+ SGMII_SPEED_DUPLEX_AN;
-+ use_an = true;
-+ } else {
-+ use_an = false;
-+ }
-+ } else if (phylink_autoneg_inband(mode)) {
-+ /* 1000base-X or 2500base-X autoneg */
-+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
-+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ advertising);
-+ } else {
-+ /* 1000base-X or 2500base-X without autoneg */
-+ sgm_mode = 0;
-+ use_an = false;
-+ }
-+
-+ if (use_an) {
-+ /* FIXME: Do we need to set AN_RESTART here? */
-+ bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
-+ } else {
-+ bmcr = 0;
-+ }
-+
- /* Configure the underlying interface speed */
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-@@ -94,11 +99,14 @@ static int mtk_pcs_config(struct phylink
- /* Setup the link timer and QPHY power up inside SGMIISYS */
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-
-- /* Setup SGMIISYS with the determined property */
-- if (interface != PHY_INTERFACE_MODE_SGMII)
-- mtk_pcs_setup_mode_force(mpcs, interface);
-- else if (phylink_autoneg_inband(mode))
-- mtk_pcs_setup_mode_an(mpcs);
-+ /* Update the sgmsys mode register */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-+ SGMII_IF_MODE_SGMII, sgm_mode);
-+
-+ /* Update the BMCR */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
-
- /* Release PHYA power down state */
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-@@ -121,8 +129,7 @@ static void mtk_pcs_link_up(struct phyli
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int sgm_mode;
-
-- if (!phylink_autoneg_inband(mode) ||
-- phy_interface_mode_is_8023z(interface)) {
-+ if (!phylink_autoneg_inband(mode)) {
- /* Force the speed and duplex setting */
- if (speed == SPEED_10)
- sgm_mode = SGMII_SPEED_10;
diff --git a/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch b/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch
deleted file mode 100644
index a02c583deb..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Wed, 1 Feb 2023 19:23:29 +0100
-Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered
- down on configuration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The code expect the PHY to be in power down which is only true after reset.
-Allow changes of the SGMII parameters more than once.
-
-Only power down when reconfiguring to avoid bouncing the link when there's
-no reason to - based on code from Russell King.
-
-There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-prevents SGMII from working. The SGMII still shows link but no traffic
-can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-taken from a good working state of the SGMII interface.
-
-Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC")
-Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
-[ bmork: rebased and squashed into one patch ]
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------
- 2 files changed, 30 insertions(+), 11 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1067,11 +1067,13 @@ struct mtk_soc_data {
- * @regmap: The register map pointing at the range used to setup
- * SGMII modes
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
-+ * @interface: Currently configured interface mode
- * @pcs: Phylink PCS structure
- */
- struct mtk_pcs {
- struct regmap *regmap;
- u32 ana_rgc3;
-+ phy_interface_t interface;
- struct phylink_pcs pcs;
- };
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink
- int advertise, link_timer;
- bool changed, use_an;
-
-- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- rgc3 = RG_PHY_SPEED_3_125G;
-- else
-- rgc3 = 0;
--
- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
- advertising);
- if (advertise < 0)
-@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink
- bmcr = 0;
- }
-
-- /* Configure the underlying interface speed */
-- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-- RG_PHY_SPEED_3_125G, rgc3);
-+ if (mpcs->interface != interface) {
-+ /* PHYA power down */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-+
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+ rgc3 = RG_PHY_SPEED_3_125G;
-+ else
-+ rgc3 = 0;
-+
-+ /* Configure the underlying interface speed */
-+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+ RG_PHY_SPEED_3_125G, rgc3);
-+
-+ mpcs->interface = interface;
-+ }
-
- /* Update the advertisement, noting whether it has changed */
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
-
-- /* Release PHYA power down state */
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
-+ /* Release PHYA power down state
-+ * Only removing bit SGMII_PHYA_PWD isn't enough.
-+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-+ * prevents SGMII from working. The SGMII still shows link but no traffic
-+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-+ * taken from a good working state of the SGMII interface.
-+ * Unknown how much the QPHY needs but it is racy without a sleep.
-+ * Tested on mt7622 & mt7986.
-+ */
-+ usleep_range(50, 100);
-+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-
- return changed;
- }
-@@ -171,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- return PTR_ERR(ss->pcs[i].regmap);
-
- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
-+ ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
- }
-
- return 0;
diff --git a/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch b/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch
deleted file mode 100644
index a06298c0a9..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
-Date: Wed, 1 Feb 2023 19:23:30 +0100
-Subject: [PATCH 12/13] net: mediatek: sgmii: fix duplex configuration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The logic of the duplex bit is inverted. Setting it means half
-duplex, not full duplex.
-
-Fix and rename macro to avoid confusion.
-
-Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -534,7 +534,7 @@
- #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
- #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
- #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
--#define SGMII_DUPLEX_FULL BIT(4)
-+#define SGMII_DUPLEX_HALF BIT(4)
- #define SGMII_IF_MODE_BIT5 BIT(5)
- #define SGMII_REMOTE_FAULT_DIS BIT(8)
- #define SGMII_CODE_SYNC_SET_VAL BIT(9)
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -154,11 +154,11 @@ static void mtk_pcs_link_up(struct phyli
- else
- sgm_mode = SGMII_SPEED_1000;
-
-- if (duplex == DUPLEX_FULL)
-- sgm_mode |= SGMII_DUPLEX_FULL;
-+ if (duplex != DUPLEX_FULL)
-+ sgm_mode |= SGMII_DUPLEX_HALF;
-
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
-+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
- sgm_mode);
- }
- }
diff --git a/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch b/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch
deleted file mode 100644
index 56d7a1348f..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Wed, 1 Feb 2023 19:23:31 +0100
-Subject: [PATCH 13/13] mtk_sgmii: enable PCS polling to allow SFP work
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently there is no IRQ handling (even the SGMII supports it).
-Enable polling to support SFP ports.
-
-Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
-[ bmork: changed "1" => "true" ]
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -187,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
- return PTR_ERR(ss->pcs[i].regmap);
-
- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
-+ ss->pcs[i].pcs.poll = true;
- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
- }
-
diff --git a/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch b/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch
deleted file mode 100644
index 6acc62d4ab..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 611e2dabb4b3243d176739fd6a5a34d007fa3f86 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 14 Mar 2023 00:34:26 +0000
-Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: reset PCS state
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Reset the internal PCS state machine when changing interface mode.
-This prevents confusing the state machine when changing interface
-modes, e.g. from SGMII to 2500Base-X or vice-versa.
-
-Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -542,6 +542,10 @@
- #define SGMII_SEND_AN_ERROR_EN BIT(11)
- #define SGMII_IF_MODE_MASK GENMASK(5, 1)
-
-+/* Register to reset SGMII design */
-+#define SGMII_RESERVED_0 0x34
-+#define SGMII_SW_RESET BIT(0)
-+
- /* Register to set SGMII speed, ANA RG_ Control Signals III*/
- #define SGMSYS_ANA_RG_CS3 0x2028
- #define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-
-+ /* Reset SGMII PCS state */
-+ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
-+ SGMII_SW_RESET, SGMII_SW_RESET);
-+
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- rgc3 = RG_PHY_SPEED_3_125G;
- else
diff --git a/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch b/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch
deleted file mode 100644
index 0fabeea20c..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 14 Mar 2023 00:34:45 +0000
-Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Only restart auto-negotiation and write link timer if actually
-necessary. This prevents losing the link in case of minor
-changes.
-
-Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink
- const unsigned long *advertising,
- bool permit_pause_to_mac)
- {
-+ bool mode_changed = false, changed, use_an;
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int rgc3, sgm_mode, bmcr;
- int advertise, link_timer;
-- bool changed, use_an;
-
- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
- advertising);
- if (advertise < 0)
- return advertise;
-
-- link_timer = phylink_get_link_timer_ns(interface);
-- if (link_timer < 0)
-- return link_timer;
--
- /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
- * we assume that fixes it's speed at bitrate = line rate (in
- * other words, 1000Mbps or 2500Mbps).
-@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink
- }
-
- if (use_an) {
-- /* FIXME: Do we need to set AN_RESTART here? */
-- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
-+ bmcr = SGMII_AN_ENABLE;
- } else {
- bmcr = 0;
- }
-
- if (mpcs->interface != interface) {
-+ link_timer = phylink_get_link_timer_ns(interface);
-+ if (link_timer < 0)
-+ return link_timer;
-+
- /* PHYA power down */
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-
-+ /* Setup the link timer */
-+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-+
- mpcs->interface = interface;
-+ mode_changed = true;
- }
-
- /* Update the advertisement, noting whether it has changed */
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
- SGMII_ADVERTISE, advertise, &changed);
-
-- /* Setup the link timer and QPHY power up inside SGMIISYS */
-- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
--
- /* Update the sgmsys mode register */
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink
-
- /* Update the BMCR */
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
-+ SGMII_AN_ENABLE, bmcr);
-
- /* Release PHYA power down state
- * Only removing bit SGMII_PHYA_PWD isn't enough.
-@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink
- usleep_range(50, 100);
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-
-- return changed;
-+ return changed || mode_changed;
- }
-
- static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
diff --git a/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch b/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch
deleted file mode 100644
index 3f3f73183e..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From f5d43ddd334b7c32fcaed9ba46afbd85cb467f1f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:56:28 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for MT7981 SoC
-
-The MediaTek MT7981 SoC comes with two 1G/2.5G SGMII ports, just like
-MT7986.
-
-In addition MT7981 is equipped with a built-in 1000Base-T PHY which can
-be used with GMAC1.
-
-As many MT7981 boards make use of inverting SGMII signal polarity, add
-new device-tree attribute 'mediatek,pn_swap' to support them.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 31 ++++++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 10 +++++++
- 4 files changed, 73 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy(
-
- static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
- {
-- unsigned int val = 0;
-+ unsigned int val = 0, mask = 0, reg = 0;
- bool updated = true;
-
- switch (path) {
- case MTK_ETH_PATH_GMAC2_SGMII:
-- val = CO_QPHY_SEL;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) {
-+ reg = USB_PHY_SWITCH_REG;
-+ val = SGMII_QPHY_SEL;
-+ mask = QPHY_SEL_MASK;
-+ } else {
-+ reg = INFRA_MISC2;
-+ val = CO_QPHY_SEL;
-+ mask = val;
-+ }
- break;
- default:
- updated = false;
-@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
- }
-
- if (updated)
-- regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
-+ regmap_update_bits(eth->infra, reg, mask, val);
-
- dev_dbg(eth->dev, "path %s in %s updated = %d\n",
- mtk_eth_path_name(path), __func__, updated);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4802,6 +4802,26 @@ static const struct mtk_soc_data mt7629_
- },
- };
-
-+static const struct mtk_soc_data mt7981_data = {
-+ .reg_map = &mt7986_reg_map,
-+ .ana_rgc3 = 0x128,
-+ .caps = MT7981_CAPS,
-+ .hw_features = MTK_HW_FEATURES,
-+ .required_clks = MT7981_CLKS_BITMAP,
-+ .required_pctl = false,
-+ .offload_version = 2,
-+ .hash_offset = 4,
-+ .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+};
-+
- static const struct mtk_soc_data mt7986_data = {
- .reg_map = &mt7986_reg_map,
- .ana_rgc3 = 0x128,
-@@ -4844,6 +4864,7 @@ const struct of_device_id of_mtk_match[]
- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
-+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
- {},
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -556,11 +556,22 @@
- #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
- #define SGMII_PHYA_PWD BIT(4)
-
-+/* Register to QPHY wrapper control */
-+#define SGMSYS_QPHY_WRAP_CTRL 0xec
-+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
-+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
-+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
-+
- /* Infrasys subsystem config registers */
- #define INFRA_MISC2 0x70c
- #define CO_QPHY_SEL BIT(0)
- #define GEPHY_MAC_SEL BIT(1)
-
-+/* Top misc registers */
-+#define USB_PHY_SWITCH_REG 0x218
-+#define QPHY_SEL_MASK GENMASK(1, 0)
-+#define SGMII_QPHY_SEL 0x2
-+
- /* MT7628/88 specific stuff */
- #define MT7628_PDMA_OFFSET 0x0800
- #define MT7628_SDM_OFFSET 0x0c00
-@@ -741,6 +752,17 @@ enum mtk_clks_map {
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK) | \
- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
-+#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
-+ BIT(MTK_CLK_WOCPU0) | \
-+ BIT(MTK_CLK_SGMII_TX_250M) | \
-+ BIT(MTK_CLK_SGMII_RX_250M) | \
-+ BIT(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT(MTK_CLK_SGMII2_CDR_FB) | \
-+ BIT(MTK_CLK_SGMII_CK))
- #define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
-@@ -854,6 +876,7 @@ enum mkt_eth_capabilities {
- MTK_NETSYS_V2_BIT,
- MTK_SOC_MT7628_BIT,
- MTK_RSTCTRL_PPE1_BIT,
-+ MTK_U3_COPHY_V2_BIT,
-
- /* MUX BITS*/
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-@@ -888,6 +911,7 @@ enum mkt_eth_capabilities {
- #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
- #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -960,6 +984,11 @@ enum mkt_eth_capabilities {
- MTK_MUX_U3_GMAC2_TO_QPHY | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
-
-+#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_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+
- #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-@@ -1073,12 +1102,14 @@ struct mtk_soc_data {
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
- * @interface: Currently configured interface mode
- * @pcs: Phylink PCS structure
-+ * @flags: Flags indicating hardware properties
- */
- struct mtk_pcs {
- struct regmap *regmap;
- u32 ana_rgc3;
- phy_interface_t interface;
- struct phylink_pcs pcs;
-+ u32 flags;
- };
-
- /* struct mtk_sgmii - This is the structure holding sgmii regmap and its
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -87,6 +87,11 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-
-+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-+ SGMII_PN_SWAP_MASK,
-+ SGMII_PN_SWAP_TX_RX);
-+
- /* Reset SGMII PCS state */
- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
- SGMII_SW_RESET, SGMII_SW_RESET);
-@@ -186,6 +191,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
-
- ss->pcs[i].ana_rgc3 = ana_rgc3;
- ss->pcs[i].regmap = syscon_node_to_regmap(np);
-+
-+ ss->pcs[i].flags = 0;
-+ if (of_property_read_bool(np, "mediatek,pnswap"))
-+ ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
-+
- of_node_put(np);
- if (IS_ERR(ss->pcs[i].regmap))
- return PTR_ERR(ss->pcs[i].regmap);
diff --git a/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch b/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch
deleted file mode 100644
index c60a4337ef..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From c0a440031d4314d1023c1b87f43a4233634eebdb Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:57:15 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: set MDIO bus clock frequency
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Set MDIO bus clock frequency and allow setting a custom maximum
-frequency from device tree.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 +++++++
- 2 files changed, 28 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -743,8 +743,10 @@ static const struct phylink_mac_ops mtk_
-
- static int mtk_mdio_init(struct mtk_eth *eth)
- {
-+ unsigned int max_clk = 2500000, divider;
- struct device_node *mii_np;
- int ret;
-+ u32 val;
-
- mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
- if (!mii_np) {
-@@ -771,6 +773,25 @@ static int mtk_mdio_init(struct mtk_eth
- eth->mii_bus->parent = eth->dev;
-
- snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
-+
-+ if (!of_property_read_u32(mii_np, "clock-frequency", &val)) {
-+ if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
-+ dev_err(eth->dev, "MDIO clock frequency out of range");
-+ ret = -EINVAL;
-+ goto err_put_node;
-+ }
-+ max_clk = val;
-+ }
-+ divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
-+
-+ /* Configure MDC Divider */
-+ val = mtk_r32(eth, MTK_PPSC);
-+ val &= ~PPSC_MDC_CFG;
-+ val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
-+ mtk_w32(eth, val, MTK_PPSC);
-+
-+ dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
-+
- ret = of_mdiobus_register(eth->mii_bus, mii_np);
-
- err_put_node:
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -363,6 +363,13 @@
- #define RX_DMA_VTAG_V2 BIT(0)
- #define RX_DMA_L4_VALID_V2 BIT(2)
-
-+/* PHY Polling and SMI Master Control registers */
-+#define MTK_PPSC 0x10000
-+#define PPSC_MDC_CFG GENMASK(29, 24)
-+#define PPSC_MDC_TURBO BIT(20)
-+#define MDC_MAX_FREQ 25000000
-+#define MDC_MAX_DIVIDER 63
-+
- /* PHY Indirect Access Control registers */
- #define MTK_PHY_IAC 0x10004
- #define PHY_IAC_ACCESS BIT(31)
diff --git a/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch b/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch
deleted file mode 100644
index d73eccedbb..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch
+++ /dev/null
@@ -1,512 +0,0 @@
-From 2a3ec7ae313310c1092e4256208cc04d1958e469 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:58:02 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: switch to external PCS driver
-
-Now that we got a PCS driver, use it and remove the now redundant
-PCS code and it's header macros from the Ethernet driver.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/Kconfig | 2 +
- drivers/net/ethernet/mediatek/Makefile | 2 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +--------
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 217 --------------------
- 5 files changed, 56 insertions(+), 319 deletions(-)
- delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -19,6 +19,8 @@ config NET_MEDIATEK_SOC
- select DIMLIB
- select PAGE_POOL
- select PAGE_POOL_STATS
-+ select PCS_MTK_LYNXI
-+ select REGMAP_MMIO
- help
- This driver supports the gigabit ethernet MACs in the
- MediaTek SoC family.
---- 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_sgmii.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_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
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -20,6 +20,7 @@
- #include <linux/interrupt.h>
- #include <linux/pinctrl/devinfo.h>
- #include <linux/phylink.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
- #include <linux/jhash.h>
- #include <linux/bitfield.h>
- #include <net/dsa.h>
-@@ -400,7 +401,7 @@ static struct phylink_pcs *mtk_mac_selec
- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
- 0 : mac->id;
-
-- return mtk_sgmii_select_pcs(eth->sgmii, sid);
-+ return eth->sgmii_pcs[sid];
- }
-
- return NULL;
-@@ -4015,8 +4016,17 @@ static int mtk_unreg_dev(struct mtk_eth
- return 0;
- }
-
-+static void mtk_sgmii_destroy(struct mtk_eth *eth)
-+{
-+ int i;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++)
-+ mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
-+}
-+
- static int mtk_cleanup(struct mtk_eth *eth)
- {
-+ mtk_sgmii_destroy(eth);
- mtk_unreg_dev(eth);
- mtk_free_dev(eth);
- cancel_work_sync(&eth->pending_work);
-@@ -4456,6 +4466,36 @@ void mtk_eth_set_dma_device(struct mtk_e
- rtnl_unlock();
- }
-
-+static int mtk_sgmii_init(struct mtk_eth *eth)
-+{
-+ struct device_node *np;
-+ struct regmap *regmap;
-+ u32 flags;
-+ int i;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
-+ if (!np)
-+ break;
-+
-+ regmap = syscon_node_to_regmap(np);
-+ flags = 0;
-+ if (of_property_read_bool(np, "mediatek,pnswap"))
-+ flags |= MTK_SGMII_FLAG_PN_SWAP;
-+
-+ of_node_put(np);
-+
-+ if (IS_ERR(regmap))
-+ return PTR_ERR(regmap);
-+
-+ eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap,
-+ eth->soc->ana_rgc3,
-+ flags);
-+ }
-+
-+ return 0;
-+}
-+
- static int mtk_probe(struct platform_device *pdev)
- {
- struct resource *res = NULL;
-@@ -4519,13 +4559,7 @@ static int mtk_probe(struct platform_dev
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
-- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii),
-- GFP_KERNEL);
-- if (!eth->sgmii)
-- return -ENOMEM;
--
-- err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node,
-- eth->soc->ana_rgc3);
-+ err = mtk_sgmii_init(eth);
-
- if (err)
- return err;
-@@ -4536,14 +4570,17 @@ static int mtk_probe(struct platform_dev
- "mediatek,pctl");
- if (IS_ERR(eth->pctl)) {
- dev_err(&pdev->dev, "no pctl regmap found\n");
-- return PTR_ERR(eth->pctl);
-+ err = PTR_ERR(eth->pctl);
-+ goto err_destroy_sgmii;
- }
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!res)
-- return -EINVAL;
-+ if (!res) {
-+ err = -EINVAL;
-+ goto err_destroy_sgmii;
-+ }
- }
-
- if (eth->soc->offload_version) {
-@@ -4702,6 +4739,8 @@ err_deinit_hw:
- mtk_hw_deinit(eth);
- err_wed_exit:
- mtk_wed_exit();
-+err_destroy_sgmii:
-+ mtk_sgmii_destroy(eth);
-
- return err;
- }
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -510,65 +510,6 @@
- #define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
- #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-
--/* SGMII subsystem config registers */
--/* BMCR (low 16) BMSR (high 16) */
--#define SGMSYS_PCS_CONTROL_1 0x0
--#define SGMII_BMCR GENMASK(15, 0)
--#define SGMII_BMSR GENMASK(31, 16)
--#define SGMII_AN_RESTART BIT(9)
--#define SGMII_ISOLATE BIT(10)
--#define SGMII_AN_ENABLE BIT(12)
--#define SGMII_LINK_STATYS BIT(18)
--#define SGMII_AN_ABILITY BIT(19)
--#define SGMII_AN_COMPLETE BIT(21)
--#define SGMII_PCS_FAULT BIT(23)
--#define SGMII_AN_EXPANSION_CLR BIT(30)
--
--#define SGMSYS_PCS_ADVERTISE 0x8
--#define SGMII_ADVERTISE GENMASK(15, 0)
--#define SGMII_LPA GENMASK(31, 16)
--
--/* Register to programmable link timer, the unit in 2 * 8ns */
--#define SGMSYS_PCS_LINK_TIMER 0x18
--#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
--#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
--
--/* Register to control remote fault */
--#define SGMSYS_SGMII_MODE 0x20
--#define SGMII_IF_MODE_SGMII BIT(0)
--#define SGMII_SPEED_DUPLEX_AN BIT(1)
--#define SGMII_SPEED_MASK GENMASK(3, 2)
--#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
--#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
--#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
--#define SGMII_DUPLEX_HALF BIT(4)
--#define SGMII_IF_MODE_BIT5 BIT(5)
--#define SGMII_REMOTE_FAULT_DIS BIT(8)
--#define SGMII_CODE_SYNC_SET_VAL BIT(9)
--#define SGMII_CODE_SYNC_SET_EN BIT(10)
--#define SGMII_SEND_AN_ERROR_EN BIT(11)
--#define SGMII_IF_MODE_MASK GENMASK(5, 1)
--
--/* Register to reset SGMII design */
--#define SGMII_RESERVED_0 0x34
--#define SGMII_SW_RESET BIT(0)
--
--/* Register to set SGMII speed, ANA RG_ Control Signals III*/
--#define SGMSYS_ANA_RG_CS3 0x2028
--#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
--#define RG_PHY_SPEED_1_25G 0x0
--#define RG_PHY_SPEED_3_125G BIT(2)
--
--/* Register to power up QPHY */
--#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
--#define SGMII_PHYA_PWD BIT(4)
--
--/* Register to QPHY wrapper control */
--#define SGMSYS_QPHY_WRAP_CTRL 0xec
--#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
--#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
--#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
--
- /* Infrasys subsystem config registers */
- #define INFRA_MISC2 0x70c
- #define CO_QPHY_SEL BIT(0)
-@@ -1102,31 +1043,6 @@ struct mtk_soc_data {
- /* currently no SoC has more than 2 macs */
- #define MTK_MAX_DEVS 2
-
--/* struct mtk_pcs - This structure holds each sgmii regmap and associated
-- * data
-- * @regmap: The register map pointing at the range used to setup
-- * SGMII modes
-- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
-- * @interface: Currently configured interface mode
-- * @pcs: Phylink PCS structure
-- * @flags: Flags indicating hardware properties
-- */
--struct mtk_pcs {
-- struct regmap *regmap;
-- u32 ana_rgc3;
-- phy_interface_t interface;
-- struct phylink_pcs pcs;
-- u32 flags;
--};
--
--/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
-- * characteristics
-- * @pcs Array of individual PCS structures
-- */
--struct mtk_sgmii {
-- struct mtk_pcs pcs[MTK_MAX_DEVS];
--};
--
- /* struct mtk_eth - This is the main datasructure for holding the state
- * of the driver
- * @dev: The device pointer
-@@ -1146,6 +1062,7 @@ struct mtk_sgmii {
- * MII modes
- * @infra: The register map pointing at the range used to setup
- * SGMII and GePHY path
-+ * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances
- * @pctl: The register map pointing at the range used to setup
- * GMAC port drive/slew values
- * @dma_refcnt: track how many netdevs are using the DMA engine
-@@ -1186,8 +1103,8 @@ struct mtk_eth {
- u32 msg_enable;
- unsigned long sysclk;
- struct regmap *ethsys;
-- struct regmap *infra;
-- struct mtk_sgmii *sgmii;
-+ struct regmap *infra;
-+ struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
- struct regmap *pctl;
- bool hwlro;
- refcount_t dma_refcnt;
-@@ -1349,10 +1266,6 @@ void mtk_stats_update_mac(struct mtk_mac
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
- u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
-
--struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
--int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
-- u32 ana_rgc3);
--
- int mtk_gmac_sgmii_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);
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ /dev/null
-@@ -1,217 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--// Copyright (c) 2018-2019 MediaTek Inc.
--
--/* A library for MediaTek SGMII circuit
-- *
-- * Author: Sean Wang <sean.wang@mediatek.com>
-- *
-- */
--
--#include <linux/mfd/syscon.h>
--#include <linux/of.h>
--#include <linux/phylink.h>
--#include <linux/regmap.h>
--
--#include "mtk_eth_soc.h"
--
--static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
--{
-- return container_of(pcs, struct mtk_pcs, pcs);
--}
--
--static void mtk_pcs_get_state(struct phylink_pcs *pcs,
-- struct phylink_link_state *state)
--{
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int bm, adv;
--
-- /* Read the BMSR and LPA */
-- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
--
-- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-- FIELD_GET(SGMII_LPA, adv));
--}
--
--static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-- phy_interface_t interface,
-- const unsigned long *advertising,
-- bool permit_pause_to_mac)
--{
-- bool mode_changed = false, changed, use_an;
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int rgc3, sgm_mode, bmcr;
-- int advertise, link_timer;
--
-- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-- advertising);
-- if (advertise < 0)
-- return 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
-- * other words, 1000Mbps or 2500Mbps).
-- */
-- if (interface == PHY_INTERFACE_MODE_SGMII) {
-- sgm_mode = SGMII_IF_MODE_SGMII;
-- if (phylink_autoneg_inband(mode)) {
-- sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-- SGMII_SPEED_DUPLEX_AN;
-- use_an = true;
-- } else {
-- use_an = false;
-- }
-- } else if (phylink_autoneg_inband(mode)) {
-- /* 1000base-X or 2500base-X autoneg */
-- sgm_mode = SGMII_REMOTE_FAULT_DIS;
-- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-- advertising);
-- } else {
-- /* 1000base-X or 2500base-X without autoneg */
-- sgm_mode = 0;
-- use_an = false;
-- }
--
-- if (use_an) {
-- bmcr = SGMII_AN_ENABLE;
-- } else {
-- bmcr = 0;
-- }
--
-- if (mpcs->interface != interface) {
-- link_timer = phylink_get_link_timer_ns(interface);
-- if (link_timer < 0)
-- return link_timer;
--
-- /* PHYA power down */
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
--
-- if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-- SGMII_PN_SWAP_MASK,
-- SGMII_PN_SWAP_TX_RX);
--
-- /* Reset SGMII PCS state */
-- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
-- SGMII_SW_RESET, SGMII_SW_RESET);
--
-- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- rgc3 = RG_PHY_SPEED_3_125G;
-- else
-- rgc3 = 0;
--
-- /* Configure the underlying interface speed */
-- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-- RG_PHY_SPEED_3_125G, rgc3);
--
-- /* Setup the link timer */
-- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
--
-- mpcs->interface = interface;
-- mode_changed = true;
-- }
--
-- /* Update the advertisement, noting whether it has changed */
-- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-- SGMII_ADVERTISE, advertise, &changed);
--
-- /* Update the sgmsys mode register */
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-- SGMII_IF_MODE_SGMII, sgm_mode);
--
-- /* Update the BMCR */
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_ENABLE, bmcr);
--
-- /* Release PHYA power down state
-- * Only removing bit SGMII_PHYA_PWD isn't enough.
-- * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-- * prevents SGMII from working. The SGMII still shows link but no traffic
-- * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-- * taken from a good working state of the SGMII interface.
-- * Unknown how much the QPHY needs but it is racy without a sleep.
-- * Tested on mt7622 & mt7986.
-- */
-- usleep_range(50, 100);
-- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
--
-- return changed || mode_changed;
--}
--
--static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
--{
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_RESTART, SGMII_AN_RESTART);
--}
--
--static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-- phy_interface_t interface, int speed, int duplex)
--{
-- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-- unsigned int sgm_mode;
--
-- if (!phylink_autoneg_inband(mode)) {
-- /* Force the speed and duplex setting */
-- if (speed == SPEED_10)
-- sgm_mode = SGMII_SPEED_10;
-- else if (speed == SPEED_100)
-- sgm_mode = SGMII_SPEED_100;
-- else
-- sgm_mode = SGMII_SPEED_1000;
--
-- if (duplex != DUPLEX_FULL)
-- sgm_mode |= SGMII_DUPLEX_HALF;
--
-- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-- SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
-- sgm_mode);
-- }
--}
--
--static const struct phylink_pcs_ops mtk_pcs_ops = {
-- .pcs_get_state = mtk_pcs_get_state,
-- .pcs_config = mtk_pcs_config,
-- .pcs_an_restart = mtk_pcs_restart_an,
-- .pcs_link_up = mtk_pcs_link_up,
--};
--
--int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
--{
-- struct device_node *np;
-- int i;
--
-- for (i = 0; i < MTK_MAX_DEVS; i++) {
-- np = of_parse_phandle(r, "mediatek,sgmiisys", i);
-- if (!np)
-- break;
--
-- ss->pcs[i].ana_rgc3 = ana_rgc3;
-- ss->pcs[i].regmap = syscon_node_to_regmap(np);
--
-- ss->pcs[i].flags = 0;
-- if (of_property_read_bool(np, "mediatek,pnswap"))
-- ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
--
-- of_node_put(np);
-- if (IS_ERR(ss->pcs[i].regmap))
-- return PTR_ERR(ss->pcs[i].regmap);
--
-- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
-- ss->pcs[i].pcs.poll = true;
-- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
-- }
--
-- return 0;
--}
--
--struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
--{
-- if (!ss->pcs[id].regmap)
-- return NULL;
--
-- return &ss->pcs[id].pcs;
--}
diff --git a/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch
deleted file mode 100644
index 9ce2735951..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From f5af7931d2a2cae66d0f9dad4ba517b1b00620b3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 19 Apr 2023 19:07:23 +0100
-Subject: [PATCH] net: mtk_eth_soc: use WO firmware for MT7981
-
-In order to support wireless offloading on MT7981 we need to load the
-appropriate firmware. Recognize MT7981 and load mt7981_wo.bin.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 7 ++++++-
- drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 +
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- wo->hw->index + 1);
-
- /* load firmware */
-- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+ if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
-+ fw_name = MT7981_FIRMWARE_WO;
-+ else
-+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+
- ret = request_firmware(&fw, fw_name, wo->hw->dev);
- if (ret)
- return ret;
-@@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *
- 100, MTK_FW_DL_TIMEOUT);
- }
-
-+MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx {
- MTK_WED_DUMMY_CR_WO_STATUS,
- };
-
-+#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
- #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
- #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
-
diff --git a/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch
deleted file mode 100644
index d715c4aa68..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 7c83e28f10830aa5105c25eaabe890e3adac36aa Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 9 May 2023 03:20:06 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix NULL pointer dereference
-
-Check for NULL pointer to avoid kernel crashing in case of missing WO
-firmware in case only a single WEDv2 device has been initialized, e.g. on
-MT7981 which can connect just one wireless frontend.
-
-Fixes: 86ce0d09e424 ("net: ethernet: mtk_eth_soc: use WO firmware for MT7981")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -647,7 +647,7 @@ __mtk_wed_detach(struct mtk_wed_device *
- BIT(hw->index), BIT(hw->index));
- }
-
-- if (!hw_list[!hw->index]->wed_dev &&
-+ if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) &&
- hw->eth->dma_dev != hw->eth->dev)
- mtk_eth_set_dma_device(hw->eth, hw->eth->dev);
-
diff --git a/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch b/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch
deleted file mode 100644
index 5c3de57591..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch
+++ /dev/null
@@ -1,403 +0,0 @@
-From f601293f37c4be618c5efaef85d2ee21f97e82e0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:57:35 +0000
-Subject: [PATCH 092/250] net: ethernet: mtk_eth_soc: ppe: add support for flow
- accounting
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The PPE units found in MT7622 and newer support packet and byte
-accounting of hw-offloaded flows. Add support for reading those counters
-as found in MediaTek's SDK[1].
-
-[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +
- drivers/net/ethernet/mediatek/mtk_ppe.c | 114 +++++++++++++++++-
- drivers/net/ethernet/mediatek/mtk_ppe.h | 25 +++-
- .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +-
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 8 ++
- drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +++
- 7 files changed, 172 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4690,8 +4690,8 @@ static int mtk_probe(struct platform_dev
- for (i = 0; i < num_ppe; i++) {
- u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
-
-- eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
-- eth->soc->offload_version, i);
-+ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
-+
- if (!eth->ppe[i]) {
- err = -ENOMEM;
- goto err_deinit_ppe;
-@@ -4815,6 +4815,7 @@ static const struct mtk_soc_data mt7622_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 2,
-+ .has_accounting = true,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4852,6 +4853,7 @@ static const struct mtk_soc_data mt7629_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7629_CLKS_BITMAP,
- .required_pctl = false,
-+ .has_accounting = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4872,6 +4874,7 @@ static const struct mtk_soc_data mt7981_
- .offload_version = 2,
- .hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .has_accounting = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4892,6 +4895,7 @@ static const struct mtk_soc_data mt7986_
- .offload_version = 2,
- .hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
-+ .has_accounting = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1011,6 +1011,8 @@ struct mtk_reg_map {
- * the extra setup for those pins used by GMAC.
- * @hash_offset Flow table hash offset.
- * @foe_entry_size Foe table entry size.
-+ * @has_accounting Bool indicating support for accounting of
-+ * offloaded flows.
- * @txd_size Tx DMA descriptor size.
- * @rxd_size Rx DMA descriptor size.
- * @rx_irq_done_mask Rx irq done register mask.
-@@ -1028,6 +1030,7 @@ struct mtk_soc_data {
- u8 hash_offset;
- u16 foe_entry_size;
- netdev_features_t hw_features;
-+ bool has_accounting;
- struct {
- u32 txd_size;
- u32 rxd_size;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_
- return ret;
- }
-
-+static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
-+{
-+ int ret;
-+ u32 val;
-+
-+ ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
-+ !(val & MTK_PPE_MIB_SER_CR_ST),
-+ 20, MTK_PPE_WAIT_TIMEOUT_US);
-+
-+ if (ret)
-+ dev_err(ppe->dev, "MIB table busy");
-+
-+ return ret;
-+}
-+
-+static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
-+{
-+ u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
-+ u32 val, cnt_r0, cnt_r1, cnt_r2;
-+ int ret;
-+
-+ val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
-+ ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
-+
-+ ret = mtk_ppe_mib_wait_busy(ppe);
-+ if (ret)
-+ return ret;
-+
-+ cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
-+ cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-+ cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
-+
-+ byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-+ byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-+ pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-+ pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+
-+ return 0;
-+}
-+
- static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
- {
- ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
-@@ -459,6 +501,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
- dma_wmb();
- mtk_ppe_cache_clear(ppe);
-+ if (ppe->accounting) {
-+ struct mtk_foe_accounting *acct;
-+
-+ acct = ppe->acct_table + entry->hash * sizeof(*acct);
-+ acct->packets = 0;
-+ acct->bytes = 0;
-+ }
- }
- entry->hash = 0xffff;
-
-@@ -566,6 +615,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- wmb();
- hwe->ib1 = entry->ib1;
-
-+ if (ppe->accounting)
-+ *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+
- dma_wmb();
-
- mtk_ppe_cache_clear(ppe);
-@@ -757,11 +809,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
- return mtk_ppe_wait_busy(ppe);
- }
-
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-- int version, int index)
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+ struct mtk_foe_accounting *diff)
-+{
-+ struct mtk_foe_accounting *acct;
-+ int size = sizeof(struct mtk_foe_accounting);
-+ u64 bytes, packets;
-+
-+ if (!ppe->accounting)
-+ return NULL;
-+
-+ if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
-+ return NULL;
-+
-+ acct = ppe->acct_table + index * size;
-+
-+ acct->bytes += bytes;
-+ acct->packets += packets;
-+
-+ if (diff) {
-+ diff->bytes = bytes;
-+ diff->packets = packets;
-+ }
-+
-+ return acct;
-+}
-+
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
- {
-+ bool accounting = eth->soc->has_accounting;
- const struct mtk_soc_data *soc = eth->soc;
-+ struct mtk_foe_accounting *acct;
- struct device *dev = eth->dev;
-+ struct mtk_mib_entry *mib;
- struct mtk_ppe *ppe;
- u32 foe_flow_size;
- void *foe;
-@@ -778,7 +858,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- ppe->base = base;
- ppe->eth = eth;
- ppe->dev = dev;
-- ppe->version = version;
-+ ppe->version = eth->soc->offload_version;
-+ ppe->accounting = accounting;
-
- foe = dmam_alloc_coherent(ppe->dev,
- MTK_PPE_ENTRIES * soc->foe_entry_size,
-@@ -794,6 +875,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
- if (!ppe->foe_flow)
- goto err_free_l2_flows;
-
-+ if (accounting) {
-+ mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
-+ &ppe->mib_phys, GFP_KERNEL);
-+ if (!mib)
-+ return NULL;
-+
-+ ppe->mib_table = mib;
-+
-+ acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
-+ GFP_KERNEL);
-+
-+ if (!acct)
-+ return NULL;
-+
-+ ppe->acct_table = acct;
-+ }
-+
- mtk_ppe_debugfs_init(ppe, index);
-
- return ppe;
-@@ -923,6 +1021,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
- ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
- }
-+
-+ if (ppe->accounting && ppe->mib_phys) {
-+ ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
-+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
-+ MTK_PPE_MIB_CFG_EN);
-+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
-+ MTK_PPE_MIB_CFG_RD_CLR);
-+ ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
-+ MTK_PPE_MIB_CFG_RD_CLR);
-+ }
- }
-
- int mtk_ppe_stop(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -57,6 +57,7 @@ enum {
- #define MTK_FOE_IB2_MULTICAST BIT(8)
-
- #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12)
-+#define MTK_FOE_IB2_MIB_CNT BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO BIT(17)
-
-@@ -285,16 +286,34 @@ struct mtk_flow_entry {
- unsigned long cookie;
- };
-
-+struct mtk_mib_entry {
-+ u32 byt_cnt_l;
-+ u16 byt_cnt_h;
-+ u32 pkt_cnt_l;
-+ u8 pkt_cnt_h;
-+ u8 _rsv0;
-+ u32 _rsv1;
-+} __packed;
-+
-+struct mtk_foe_accounting {
-+ u64 bytes;
-+ u64 packets;
-+};
-+
- struct mtk_ppe {
- struct mtk_eth *eth;
- struct device *dev;
- void __iomem *base;
- int version;
- char dirname[5];
-+ bool accounting;
-
- void *foe_table;
- dma_addr_t foe_phys;
-
-+ struct mtk_mib_entry *mib_table;
-+ dma_addr_t mib_phys;
-+
- u16 foe_check_time[MTK_PPE_ENTRIES];
- struct hlist_head *foe_flow;
-
-@@ -303,8 +322,8 @@ struct mtk_ppe {
- void *acct_table;
- };
-
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-- int version, int index);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
-+
- void mtk_ppe_deinit(struct mtk_eth *eth);
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-@@ -359,5 +378,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+ struct mtk_foe_accounting *diff);
-
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
- struct mtk_foe_mac_info *l2;
- struct mtk_flow_addr_info ai = {};
-+ struct mtk_foe_accounting *acct;
- unsigned char h_source[ETH_ALEN];
- unsigned char h_dest[ETH_ALEN];
- int type, state;
-@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- if (bind && state != MTK_FOE_STATE_BIND)
- continue;
-
-+ acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-+
- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
- seq_printf(m, "%05x %s %7s", i,
- mtk_foe_entry_state_str(state),
-@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
-
- seq_printf(m, " eth=%pM->%pM etype=%04x"
-- " vlan=%d,%d ib1=%08x ib2=%08x\n",
-+ " vlan=%d,%d ib1=%08x ib2=%08x"
-+ " packets=%llu bytes=%llu\n",
- h_source, h_dest, ntohs(l2->etype),
-- l2->vlan1, l2->vlan2, entry->ib1, ib2);
-+ l2->vlan1, l2->vlan2, entry->ib1, ib2,
-+ acct ? acct->packets : 0, acct ? acct->bytes : 0);
- }
-
- return 0;
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -497,6 +497,7 @@ static int
- mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
- {
- struct mtk_flow_entry *entry;
-+ struct mtk_foe_accounting diff;
- u32 idle;
-
- entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
-@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e
- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
- f->stats.lastused = jiffies - idle * HZ;
-
-+ if (entry->hash != 0xFFFF &&
-+ mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
-+ &diff)) {
-+ f->stats.pkts += diff.packets;
-+ f->stats.bytes += diff.bytes;
-+ }
-+
- return 0;
- }
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -149,6 +149,20 @@ enum {
-
- #define MTK_PPE_MIB_TB_BASE 0x338
-
-+#define MTK_PPE_MIB_SER_CR 0x33C
-+#define MTK_PPE_MIB_SER_CR_ST BIT(16)
-+#define MTK_PPE_MIB_SER_CR_ADDR GENMASK(13, 0)
-+
-+#define MTK_PPE_MIB_SER_R0 0x340
-+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW GENMASK(31, 0)
-+
-+#define MTK_PPE_MIB_SER_R1 0x344
-+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW GENMASK(31, 16)
-+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH GENMASK(15, 0)
-+
-+#define MTK_PPE_MIB_SER_R2 0x348
-+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0)
-+
- #define MTK_PPE_MIB_CACHE_CTL 0x350
- #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
- #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)
diff --git a/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
deleted file mode 100644
index 64352426ae..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 88a0fd5927b7c2c7aecd6dc747d898eb38043d2b Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 20 Apr 2023 22:06:42 +0100
-Subject: [PATCH 093/250] net: mtk_eth_soc: mediatek: fix ppe flow accounting
- for v1 hardware
-
-Older chips (like MT7622) use a different bit in ib2 to enable hardware
-counter support. Add macros for both and select the appropriate bit.
-
-Fixes: 3fbe4d8c0e53 ("net: ethernet: mtk_eth_soc: ppe: add support for flow accounting")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 10 ++++++++--
- drivers/net/ethernet/mediatek/mtk_ppe.h | 3 ++-
- 2 files changed, 10 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -599,6 +599,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- struct mtk_eth *eth = ppe->eth;
- u16 timestamp = mtk_eth_timestamp(eth);
- struct mtk_foe_entry *hwe;
-+ u32 val;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-@@ -615,8 +616,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- wmb();
- hwe->ib1 = entry->ib1;
-
-- if (ppe->accounting)
-- *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+ if (ppe->accounting) {
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ val = MTK_FOE_IB2_MIB_CNT_V2;
-+ else
-+ val = MTK_FOE_IB2_MIB_CNT;
-+ *mtk_foe_entry_ib2(eth, hwe) |= val;
-+ }
-
- dma_wmb();
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -55,9 +55,10 @@ enum {
- #define MTK_FOE_IB2_PSE_QOS BIT(4)
- #define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5)
- #define MTK_FOE_IB2_MULTICAST BIT(8)
-+#define MTK_FOE_IB2_MIB_CNT BIT(10)
-
- #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12)
--#define MTK_FOE_IB2_MIB_CNT BIT(15)
-+#define MTK_FOE_IB2_MIB_CNT_V2 BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO BIT(17)
-
diff --git a/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
deleted file mode 100644
index 7e3d5a3308..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 20 Nov 2022 23:01:00 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload,
- only use DSA untagging
-
-Through testing I found out that hardware vlan rx offload support seems to
-have some hardware issues. At least when using multiple MACs and when receiving
-tagged packets on the secondary MAC, the hardware can sometimes start to emit
-wrong tags on the first MAC as well.
-
-In order to avoid such issues, drop the feature configuration and use the
-offload feature only for DSA hardware untagging on MT7621/MT7622 devices which
-only use one MAC.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1896,9 +1896,7 @@ static int mtk_poll_rx(struct napi_struc
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
-- bool has_hwaccel_tag = false;
- struct net_device *netdev;
-- u16 vlan_proto, vlan_tci;
- dma_addr_t dma_addr;
- u32 hash, reason;
- int mac = 0;
-@@ -2033,36 +2031,21 @@ static int mtk_poll_rx(struct napi_struc
- skb_checksum_none_assert(skb);
- skb->protocol = eth_type_trans(skb, netdev);
-
-- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-- mtk_ppe_check_skb(eth->ppe[0], skb, hash);
--
-- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-- if (trxd.rxd3 & RX_DMA_VTAG_V2) {
-- vlan_proto = RX_DMA_VPID(trxd.rxd4);
-- vlan_tci = RX_DMA_VID(trxd.rxd4);
-- has_hwaccel_tag = true;
-- }
-- } else if (trxd.rxd2 & RX_DMA_VTAG) {
-- vlan_proto = RX_DMA_VPID(trxd.rxd3);
-- vlan_tci = RX_DMA_VID(trxd.rxd3);
-- has_hwaccel_tag = true;
-- }
-- }
--
- /* When using VLAN untagging in combination with DSA, the
- * hardware treats the MTK special tag as a VLAN and untags it.
- */
-- if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
-- unsigned int port = vlan_proto & GENMASK(2, 0);
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-+ (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-+ unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-
- if (port < ARRAY_SIZE(eth->dsa_meta) &&
- eth->dsa_meta[port])
- skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
-- } else if (has_hwaccel_tag) {
-- __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
- }
-
-+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-+ mtk_ppe_check_skb(eth->ppe[0], skb, hash);
-+
- skb_record_rx_queue(skb, 0);
- napi_gro_receive(napi, skb);
-
-@@ -2888,29 +2871,11 @@ static netdev_features_t mtk_fix_feature
-
- static int mtk_set_features(struct net_device *dev, netdev_features_t features)
- {
-- struct mtk_mac *mac = netdev_priv(dev);
-- struct mtk_eth *eth = mac->hw;
- netdev_features_t diff = dev->features ^ features;
-- int i;
-
- if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
- mtk_hwlro_netdev_disable(dev);
-
-- /* Set RX VLAN offloading */
-- if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
-- return 0;
--
-- mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
-- MTK_CDMP_EG_CTRL);
--
-- /* sync features with other MAC */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i] || eth->netdev[i] == dev)
-- continue;
-- eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
-- eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
-- }
--
- return 0;
- }
-
-@@ -3224,30 +3189,6 @@ static int mtk_open(struct net_device *d
- struct mtk_eth *eth = mac->hw;
- int i, err;
-
-- if (mtk_uses_dsa(dev) && !eth->prog) {
-- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-- struct metadata_dst *md_dst = eth->dsa_meta[i];
--
-- if (md_dst)
-- continue;
--
-- md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-- GFP_KERNEL);
-- if (!md_dst)
-- return -ENOMEM;
--
-- md_dst->u.port_info.port_id = i;
-- eth->dsa_meta[i] = md_dst;
-- }
-- } else {
-- /* Hardware special tag parsing needs to be disabled if at least
-- * one MAC does not use DSA.
-- */
-- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-- val &= ~MTK_CDMP_STAG_EN;
-- mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-- }
--
- err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
- if (err) {
- netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3286,6 +3227,35 @@ static int mtk_open(struct net_device *d
- phylink_start(mac->phylink);
- netif_tx_start_all_queues(dev);
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ return 0;
-+
-+ if (mtk_uses_dsa(dev) && !eth->prog) {
-+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+ struct metadata_dst *md_dst = eth->dsa_meta[i];
-+
-+ if (md_dst)
-+ continue;
-+
-+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-+ GFP_KERNEL);
-+ if (!md_dst)
-+ return -ENOMEM;
-+
-+ md_dst->u.port_info.port_id = i;
-+ eth->dsa_meta[i] = md_dst;
-+ }
-+ } else {
-+ /* Hardware special tag parsing needs to be disabled if at least
-+ * one MAC does not use DSA.
-+ */
-+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+ val &= ~MTK_CDMP_STAG_EN;
-+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-+
-+ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
-+ }
-+
- return 0;
- }
-
-@@ -3770,10 +3740,9 @@ static int mtk_hw_init(struct mtk_eth *e
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
-- }
-
-- /* Enable RX VLan Offloading */
-- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+ }
-
- /* set interrupt delays based on current Net DIM sample */
- mtk_dim_rx(&eth->rx_dim.work);
-@@ -4413,7 +4382,7 @@ static int mtk_add_mac(struct mtk_eth *e
- eth->netdev[id]->hw_features |= NETIF_F_LRO;
-
- eth->netdev[id]->vlan_features = eth->soc->hw_features &
-- ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
-+ ~NETIF_F_HW_VLAN_CTAG_TX;
- eth->netdev[id]->features |= eth->soc->hw_features;
- eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -48,7 +48,6 @@
- #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
- NETIF_F_RXCSUM | \
- NETIF_F_HW_VLAN_CTAG_TX | \
-- NETIF_F_HW_VLAN_CTAG_RX | \
- NETIF_F_SG | NETIF_F_TSO | \
- NETIF_F_TSO6 | \
- NETIF_F_IPV6_CSUM |\
diff --git a/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch
deleted file mode 100644
index 2704faec12..0000000000
--- a/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 19 Jul 2023 01:39:36 +0100
-Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always
- mtk_get_ib1_pkt_type
-
-entries and bind debugfs files would display wrong data on NETSYS_V2 and
-later because instead of using mtk_get_ib1_pkt_type the driver would use
-MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs.
-Use mtk_get_ib1_pkt_type so entries and bind records display correctly.
-
-Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-
- acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-
-- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-+ type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
- seq_printf(m, "%05x %s %7s", i,
- mtk_foe_entry_state_str(state),
- mtk_foe_pkt_type_str(type));
diff --git a/target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch b/target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch
deleted file mode 100644
index 64d1b160d3..0000000000
--- a/target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 380b50ae3a04222334a3779b3787eba844b1177f Mon Sep 17 00:00:00 2001
-From: Marco von Rosenberg <marcovr@selfnet.de>
-Date: Thu, 16 Nov 2023 20:32:31 +0100
-Subject: net: phy: broadcom: Wire suspend/resume for BCM54612E
-
-The BCM54612E ethernet PHY supports IDDQ-SR.
-Therefore wire-up the suspend and resume callbacks
-to point to bcm54xx_suspend() and bcm54xx_resume().
-
-Signed-off-by: Marco von Rosenberg <marcovr@selfnet.de>
-Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/broadcom.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/phy/broadcom.c
-+++ b/drivers/net/phy/broadcom.c
-@@ -942,6 +942,8 @@ static struct phy_driver broadcom_driver
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
-+ .suspend = bcm54xx_suspend,
-+ .resume = bcm54xx_resume,
- }, {
- .phy_id = PHY_ID_BCM54616S,
- .phy_id_mask = 0xfffffff0,
diff --git a/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch
deleted file mode 100644
index afce0cf04c..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 19 Jul 2023 12:29:49 +0200
-Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE
- macros
-
-Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more
-explicit foe_entry size for different chipset revisions.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++-----
- drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++
- 2 files changed, 8 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4764,7 +4764,7 @@ static const struct mtk_soc_data mt7621_
- .required_pctl = false,
- .offload_version = 1,
- .hash_offset = 2,
-- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4785,7 +4785,7 @@ static const struct mtk_soc_data mt7622_
- .offload_version = 2,
- .hash_offset = 2,
- .has_accounting = true,
-- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4804,7 +4804,7 @@ static const struct mtk_soc_data mt7623_
- .required_pctl = true,
- .offload_version = 1,
- .hash_offset = 2,
-- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4842,8 +4842,8 @@ static const struct mtk_soc_data mt7981_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 4,
-- .foe_entry_size = sizeof(struct mtk_foe_entry),
- .has_accounting = true,
-+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4863,8 +4863,8 @@ static const struct mtk_soc_data mt7986_
- .required_pctl = false,
- .offload_version = 2,
- .hash_offset = 4,
-- .foe_entry_size = sizeof(struct mtk_foe_entry),
- .has_accounting = true,
-+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd {
- struct mtk_foe_mac_info l2;
- };
-
-+#define MTK_FOE_ENTRY_V1_SIZE 80
-+#define MTK_FOE_ENTRY_V2_SIZE 96
-+
- struct mtk_foe_entry {
- u32 ib1;
-
diff --git a/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch
deleted file mode 100644
index 28bf2b6d5f..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sat, 22 Jul 2023 21:32:49 +0100
-Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL
- configuration
-
-MT7623 GMAC0 attempts to configure the system clocking according to the
-required speed in the .mac_config callback for non-SGMII, non-baseX and
-non-TRGMII modes.
-
-state->speed setting has never been reliable in the .mac_config
-callback - there are cases where this is not the link speed,
-particularly via ethtool paths, so this has always been unreliable (as
-detailed in phylink's documentation.)
-
-There is the additional issue that mtk_gmac0_rgmii_adjust() will only
-be called if state->interface changes, which means it only configures
-the system clocking on the very first .mac_config call, which will be
-made when the network device is first brought up before any link is
-established.
-
-Essentially, this code is incredibly buggy, and probably never worked.
-
-Moreover, checking the in-kernel DT files, it seems no platform makes
-use of this code path.
-
-Therefore, let's remove it, and disable interface modes for port 0 that
-are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623.
-
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++---------------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- 2 files changed, 17 insertions(+), 38 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -352,7 +352,7 @@ static int mt7621_gmac0_rgmii_adjust(str
- }
-
- static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth,
-- phy_interface_t interface, int speed)
-+ phy_interface_t interface)
- {
- u32 val;
- int ret;
-@@ -366,26 +366,7 @@ static void mtk_gmac0_rgmii_adjust(struc
- return;
- }
-
-- val = (speed == SPEED_1000) ?
-- INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100;
-- mtk_w32(eth, val, INTF_MODE);
--
-- regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0,
-- ETHSYS_TRGMII_CLK_SEL362_5,
-- ETHSYS_TRGMII_CLK_SEL362_5);
--
-- val = (speed == SPEED_1000) ? 250000000 : 500000000;
-- ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val);
-- if (ret)
-- dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret);
--
-- val = (speed == SPEED_1000) ?
-- RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100;
-- mtk_w32(eth, val, TRGMII_RCK_CTRL);
--
-- val = (speed == SPEED_1000) ?
-- TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100;
-- mtk_w32(eth, val, TRGMII_TCK_CTRL);
-+ dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
- }
-
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
-@@ -471,17 +452,8 @@ static void mtk_mac_config(struct phylin
- state->interface))
- goto err_phy;
- } else {
-- /* FIXME: this is incorrect. Not only does it
-- * use state->speed (which is not guaranteed
-- * to be correct) but it also makes use of it
-- * in a code path that will only be reachable
-- * when the PHY interface mode changes, not
-- * when the speed changes. Consequently, RGMII
-- * is probably broken.
-- */
- mtk_gmac0_rgmii_adjust(mac->hw,
-- state->interface,
-- state->speed);
-+ state->interface);
-
- /* mt7623_pad_clk_setup */
- for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-@@ -4341,13 +4313,19 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
-
-- __set_bit(PHY_INTERFACE_MODE_MII,
-- mac->phylink_config.supported_interfaces);
-- __set_bit(PHY_INTERFACE_MODE_GMII,
-- mac->phylink_config.supported_interfaces);
-+ /* MT7623 gmac0 is now missing its speed-specific PLL configuration
-+ * in its .mac_config method (since state->speed is not valid there.
-+ * Disable support for MII, GMII and RGMII.
-+ */
-+ if (!mac->hw->soc->disable_pll_modes || mac->id != 0) {
-+ __set_bit(PHY_INTERFACE_MODE_MII,
-+ mac->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_GMII,
-+ mac->phylink_config.supported_interfaces);
-
-- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
-- phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
-+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
-+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
-+ }
-
- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
- __set_bit(PHY_INTERFACE_MODE_TRGMII,
-@@ -4805,6 +4783,7 @@ static const struct mtk_soc_data mt7623_
- .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-+ .disable_pll_modes = true,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1030,6 +1030,7 @@ struct mtk_soc_data {
- u16 foe_entry_size;
- netdev_features_t hw_features;
- bool has_accounting;
-+ bool disable_pll_modes;
- struct {
- u32 txd_size;
- u32 rxd_size;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch
deleted file mode 100644
index fd458a67bc..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sat, 22 Jul 2023 21:32:54 +0100
-Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state
- and modernise
-
-Remove the .mac_pcs_get_state function, since as far as I can tell is
-never called - no DT appears to specify an in-band-status management
-nor SFP support for this driver.
-
-Removal of this, along with the previous patch to remove the incorrect
-clocking configuration, means that the driver becomes non-legacy, so
-we can remove the "legacy_pre_march2020" status from this driver.
-
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ---------------------
- 1 file changed, 35 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -554,38 +554,6 @@ static int mtk_mac_finish(struct phylink
- return 0;
- }
-
--static void mtk_mac_pcs_get_state(struct phylink_config *config,
-- struct phylink_link_state *state)
--{
-- struct mtk_mac *mac = container_of(config, struct mtk_mac,
-- phylink_config);
-- u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id));
--
-- state->link = (pmsr & MAC_MSR_LINK);
-- state->duplex = (pmsr & MAC_MSR_DPX) >> 1;
--
-- switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) {
-- case 0:
-- state->speed = SPEED_10;
-- break;
-- case MAC_MSR_SPEED_100:
-- state->speed = SPEED_100;
-- break;
-- case MAC_MSR_SPEED_1000:
-- state->speed = SPEED_1000;
-- break;
-- default:
-- state->speed = SPEED_UNKNOWN;
-- break;
-- }
--
-- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
-- if (pmsr & MAC_MSR_RX_FC)
-- state->pause |= MLO_PAUSE_RX;
-- if (pmsr & MAC_MSR_TX_FC)
-- state->pause |= MLO_PAUSE_TX;
--}
--
- static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -707,7 +675,6 @@ static void mtk_mac_link_up(struct phyli
-
- static const struct phylink_mac_ops mtk_phylink_ops = {
- .mac_select_pcs = mtk_mac_select_pcs,
-- .mac_pcs_get_state = mtk_mac_pcs_get_state,
- .mac_config = mtk_mac_config,
- .mac_finish = mtk_mac_finish,
- .mac_link_down = mtk_mac_link_down,
-@@ -4308,8 +4275,6 @@ static int mtk_add_mac(struct mtk_eth *e
-
- mac->phylink_config.dev = &eth->netdev[id]->dev;
- mac->phylink_config.type = PHYLINK_NETDEV;
-- /* This driver makes use of state->speed in mac_config */
-- mac->phylink_config.legacy_pre_march2020 = true;
- mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
-
diff --git a/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch
deleted file mode 100644
index aa259e7175..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch
+++ /dev/null
@@ -1,550 +0,0 @@
-From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:02 +0100
-Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in
- mtk_soc_data
-
-Introduce version field in mtk_soc_data data structure in order to
-make mtk_eth driver easier to maintain for chipset configuration
-codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++--------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 36 +++++++-----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++---
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 2 +-
- drivers/net/ethernet/mediatek/mtk_wed.c | 4 +-
- 5 files changed, 66 insertions(+), 49 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -579,7 +579,7 @@ static void mtk_set_queue_speed(struct m
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
- MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v1(eth))
- val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-
- if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-@@ -954,7 +954,7 @@ static bool mtk_rx_get_desc(struct mtk_e
- rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
- rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
- rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
- rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
- }
-@@ -1012,7 +1012,7 @@ static int mtk_init_fq_dma(struct mtk_et
-
- txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
- txd->txd4 = 0;
-- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- txd->txd5 = 0;
- txd->txd6 = 0;
- txd->txd7 = 0;
-@@ -1203,7 +1203,7 @@ static void mtk_tx_set_dma_desc(struct n
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- mtk_tx_set_dma_desc_v2(dev, txd, info);
- else
- mtk_tx_set_dma_desc_v1(dev, txd, info);
-@@ -1510,7 +1510,7 @@ static void mtk_update_rx_cpu_idx(struct
-
- static bool mtk_page_pool_enabled(struct mtk_eth *eth)
- {
-- return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);
-+ return eth->soc->version == 2;
- }
-
- static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
-@@ -1852,7 +1852,7 @@ static int mtk_poll_rx(struct napi_struc
- break;
-
- /* find out which mac the packet come from. values start at 1 */
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-@@ -1948,7 +1948,7 @@ static int mtk_poll_rx(struct napi_struc
- skb->dev = netdev;
- bytes += skb->len;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
- hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
- if (hash != MTK_RXD5_FOE_ENTRY)
-@@ -1973,8 +1973,8 @@ static int mtk_poll_rx(struct napi_struc
- /* When using VLAN untagging in combination with DSA, the
- * hardware treats the MTK special tag as a VLAN and untags it.
- */
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-- (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-+ if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) &&
-+ netdev_uses_dsa(netdev)) {
- unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-
- if (port < ARRAY_SIZE(eth->dsa_meta) &&
-@@ -2284,7 +2284,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- txd->txd2 = next_ptr;
- txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
- txd->txd4 = 0;
-- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- txd->txd5 = 0;
- txd->txd6 = 0;
- txd->txd7 = 0;
-@@ -2337,14 +2337,14 @@ static int mtk_tx_alloc(struct mtk_eth *
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
- FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
- MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v1(eth))
- val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
- mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
- ofs += MTK_QTX_OFFSET;
- }
- val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16);
- mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate);
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
- } else {
- mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
-@@ -2473,7 +2473,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-
- rxd->rxd3 = 0;
- rxd->rxd4 = 0;
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- rxd->rxd5 = 0;
- rxd->rxd6 = 0;
- rxd->rxd7 = 0;
-@@ -3024,7 +3024,7 @@ static int mtk_start_dma(struct mtk_eth
- MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
- MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
- MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
- MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
-@@ -3166,7 +3166,7 @@ static int mtk_open(struct net_device *d
- phylink_start(mac->phylink);
- netif_tx_start_all_queues(dev);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return 0;
-
- if (mtk_uses_dsa(dev) && !eth->prog) {
-@@ -3431,7 +3431,7 @@ static void mtk_hw_reset(struct mtk_eth
- {
- u32 val;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
- val = RSTCTRL_PPE0_V2;
- } else {
-@@ -3443,7 +3443,7 @@ static void mtk_hw_reset(struct mtk_eth
-
- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
- 0x3ffffff);
- }
-@@ -3469,7 +3469,7 @@ static void mtk_hw_warm_reset(struct mtk
- return;
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
- else
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
-@@ -3639,7 +3639,7 @@ static int mtk_hw_init(struct mtk_eth *e
- else
- mtk_hw_reset(eth);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- /* Set FE to PDMAv2 if necessary */
- val = mtk_r32(eth, MTK_FE_GLO_MISC);
- mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
-@@ -3676,7 +3676,7 @@ static int mtk_hw_init(struct mtk_eth *e
- */
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ 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);
-
-@@ -3698,7 +3698,7 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- /* PSE should not drop port8 and port9 packets from WDMA Tx */
- mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-
-@@ -4487,7 +4487,7 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- err = -EINVAL;
-@@ -4595,9 +4595,8 @@ static int mtk_probe(struct platform_dev
- }
-
- if (eth->soc->offload_version) {
-- u32 num_ppe;
-+ u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
-
-- num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
- num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
- for (i = 0; i < num_ppe; i++) {
- u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
-@@ -4689,6 +4688,7 @@ static const struct mtk_soc_data mt2701_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
-+ .version = 1,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4705,6 +4705,7 @@ static const struct mtk_soc_data mt7621_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7621_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 1,
- .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-@@ -4725,6 +4726,7 @@ static const struct mtk_soc_data mt7622_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7622_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 1,
- .offload_version = 2,
- .hash_offset = 2,
- .has_accounting = true,
-@@ -4745,6 +4747,7 @@ static const struct mtk_soc_data mt7623_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7623_CLKS_BITMAP,
- .required_pctl = true,
-+ .version = 1,
- .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-@@ -4767,6 +4770,7 @@ static const struct mtk_soc_data mt7629_
- .required_clks = MT7629_CLKS_BITMAP,
- .required_pctl = false,
- .has_accounting = true,
-+ .version = 1,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4784,6 +4788,7 @@ static const struct mtk_soc_data mt7981_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7981_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 2,
- .offload_version = 2,
- .hash_offset = 4,
- .has_accounting = true,
-@@ -4805,6 +4810,7 @@ static const struct mtk_soc_data mt7986_
- .hw_features = MTK_HW_FEATURES,
- .required_clks = MT7986_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 2,
- .offload_version = 2,
- .hash_offset = 4,
- .has_accounting = true,
-@@ -4825,6 +4831,7 @@ static const struct mtk_soc_data rt5350_
- .hw_features = MTK_HW_FEATURES_MT7628,
- .required_clks = MT7628_CLKS_BITMAP,
- .required_pctl = false,
-+ .version = 1,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -820,7 +820,6 @@ enum mkt_eth_capabilities {
- MTK_SHARED_INT_BIT,
- MTK_TRGMII_MT7621_CLK_BIT,
- MTK_QDMA_BIT,
-- MTK_NETSYS_V2_BIT,
- MTK_SOC_MT7628_BIT,
- MTK_RSTCTRL_PPE1_BIT,
- MTK_U3_COPHY_V2_BIT,
-@@ -855,7 +854,6 @@ enum mkt_eth_capabilities {
- #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
- #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
- #define MTK_QDMA BIT(MTK_QDMA_BIT)
--#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
- #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
- #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
-@@ -934,11 +932,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_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+ MTK_RSTCTRL_PPE1)
-
- #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
-- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+ MTK_RSTCTRL_PPE1)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
-@@ -1009,6 +1007,7 @@ struct mtk_reg_map {
- * @required_pctl A bool value to show whether the SoC requires
- * the extra setup for those pins used by GMAC.
- * @hash_offset Flow table hash offset.
-+ * @version SoC version.
- * @foe_entry_size Foe table entry size.
- * @has_accounting Bool indicating support for accounting of
- * offloaded flows.
-@@ -1027,6 +1026,7 @@ struct mtk_soc_data {
- bool required_pctl;
- u8 offload_version;
- u8 hash_offset;
-+ u8 version;
- u16 foe_entry_size;
- netdev_features_t hw_features;
- bool has_accounting;
-@@ -1183,6 +1183,16 @@ 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[];
-
-+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
-+{
-+ return eth->soc->version == 1;
-+}
-+
-+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
-+{
-+ return eth->soc->version > 1;
-+}
-+
- static inline struct mtk_foe_entry *
- mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
- {
-@@ -1193,7 +1203,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u
-
- static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-
- return MTK_FOE_IB1_BIND_TIMESTAMP;
-@@ -1201,7 +1211,7 @@ static inline u32 mtk_get_ib1_ts_mask(st
-
- static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_PPPOE_V2;
-
- return MTK_FOE_IB1_BIND_PPPOE;
-@@ -1209,7 +1219,7 @@ static inline u32 mtk_get_ib1_ppoe_mask(
-
- static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_VLAN_TAG_V2;
-
- return MTK_FOE_IB1_BIND_VLAN_TAG;
-@@ -1217,7 +1227,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m
-
- static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_BIND_VLAN_LAYER_V2;
-
- return MTK_FOE_IB1_BIND_VLAN_LAYER;
-@@ -1225,7 +1235,7 @@ static inline u32 mtk_get_ib1_vlan_layer
-
- static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
-
- return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
-@@ -1233,7 +1243,7 @@ static inline u32 mtk_prep_ib1_vlan_laye
-
- static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
-
- return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
-@@ -1241,7 +1251,7 @@ static inline u32 mtk_get_ib1_vlan_layer
-
- static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB1_PACKET_TYPE_V2;
-
- return MTK_FOE_IB1_PACKET_TYPE;
-@@ -1249,7 +1259,7 @@ static inline u32 mtk_get_ib1_pkt_type_m
-
- static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val);
-
- return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val);
-@@ -1257,7 +1267,7 @@ static inline u32 mtk_get_ib1_pkt_type(s
-
- static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
- {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- return MTK_FOE_IB2_MULTICAST_V2;
-
- return MTK_FOE_IB2_MULTICAST;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth
-
- memset(entry, 0, sizeof(*entry));
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) |
- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
-@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
- u32 val = *ib2;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- val &= ~MTK_FOE_IB2_DEST_PORT_V2;
- val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port);
- } else {
-@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
- *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
- MTK_FOE_IB2_WDMA_WINFO_V2;
-@@ -446,7 +446,7 @@ int mtk_foe_entry_set_queue(struct mtk_e
- {
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- *ib2 &= ~MTK_FOE_IB2_QID_V2;
- *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue);
- *ib2 |= MTK_FOE_IB2_PSE_QOS_V2;
-@@ -601,7 +601,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- struct mtk_foe_entry *hwe;
- u32 val;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2,
- timestamp);
-@@ -617,7 +617,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- hwe->ib1 = entry->ib1;
-
- if (ppe->accounting) {
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- val = MTK_FOE_IB2_MIB_CNT_V2;
- else
- val = MTK_FOE_IB2_MIB_CNT;
-@@ -965,7 +965,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_SCAN_MODE_CHECK_AGE) |
- FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
- MTK_PPE_ENTRIES_SHIFT);
-- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(ppe->eth))
- val |= MTK_PPE_TB_CFG_INFO_SEL;
- ppe_w32(ppe, MTK_PPE_TB_CFG, val);
-
-@@ -981,7 +981,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_FLOW_CFG_IP4_NAPT |
- MTK_PPE_FLOW_CFG_IP4_DSLITE |
- MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
-- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(ppe->eth))
- val |= MTK_PPE_MD_TOAP_BYP_CRSN0 |
- MTK_PPE_MD_TOAP_BYP_CRSN1 |
- MTK_PPE_MD_TOAP_BYP_CRSN2 |
-@@ -1023,7 +1023,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
-
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
-
-- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) {
- ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
- ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
- }
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
- if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
- mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
- info.bss, info.wcid);
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
- switch (info.wdma_idx) {
- case 0:
- pse_port = 8;
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1084,7 +1084,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- } else {
- struct mtk_eth *eth = dev->hw->eth;
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+ if (mtk_is_netsys_v2_or_greater(eth))
- wed_set(dev, MTK_WED_RESET_IDX,
- MTK_WED_RESET_IDX_RX_V2);
- else
-@@ -1806,7 +1806,7 @@ void mtk_wed_add_hw(struct device_node *
- hw->wdma = wdma;
- hw->index = index;
- hw->irq = irq;
-- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
-+ hw->version = mtk_is_netsys_v1(eth) ? 1 : 2;
-
- if (hw->version == 1) {
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
diff --git a/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch
deleted file mode 100644
index 7b945bb869..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:27 +0100
-Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3
-
-This is a preliminary patch to add MT7988 SoC support since it runs 3
-macs instead of 2.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1043,8 +1043,8 @@ struct mtk_soc_data {
-
- #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
-
--/* currently no SoC has more than 2 macs */
--#define MTK_MAX_DEVS 2
-+/* currently no SoC has more than 3 macs */
-+#define MTK_MAX_DEVS 3
-
- /* struct mtk_eth - This is the main datasructure for holding the state
- * of the driver
diff --git a/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch b/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch
deleted file mode 100644
index 3db23f7897..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:44 +0100
-Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and
- remove MTK_MAC_COUNT
-
-Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++---------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
- 2 files changed, 27 insertions(+), 23 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -880,7 +880,7 @@ static void mtk_stats_update(struct mtk_
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->mac[i] || !eth->mac[i]->hw_stats)
- continue;
- if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
-@@ -1385,7 +1385,7 @@ static int mtk_queue_stopped(struct mtk_
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- if (netif_queue_stopped(eth->netdev[i]))
-@@ -1399,7 +1399,7 @@ static void mtk_wake_queue(struct mtk_et
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- netif_tx_wake_all_queues(eth->netdev[i]);
-@@ -1858,7 +1858,7 @@ static int mtk_poll_rx(struct napi_struc
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
- mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
-
-- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
-+ if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
- !eth->netdev[mac]))
- goto release_desc;
-
-@@ -2898,7 +2898,7 @@ static void mtk_dma_free(struct mtk_eth
- const struct mtk_soc_data *soc = eth->soc;
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++)
-+ for (i = 0; i < MTK_MAX_DEVS; i++)
- if (eth->netdev[i])
- netdev_reset_queue(eth->netdev[i]);
- if (eth->scratch_ring) {
-@@ -3052,8 +3052,13 @@ static void mtk_gdm_config(struct mtk_et
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
- return;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ u32 val;
-+
-+ if (!eth->netdev[i])
-+ continue;
-+
-+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-
- /* default setup the forward port to send frame to PDMA */
- val &= ~0xffff;
-@@ -3063,7 +3068,7 @@ static void mtk_gdm_config(struct mtk_et
-
- val |= config;
-
-- if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i]))
-+ if (netdev_uses_dsa(eth->netdev[i]))
- val |= MTK_GDMA_SPECIAL_TAG;
-
- mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-@@ -3660,15 +3665,15 @@ static int mtk_hw_init(struct mtk_eth *e
- * up with the more appropriate value when mtk_mac_config call is being
- * invoked.
- */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- struct net_device *dev = eth->netdev[i];
-
-- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
-- if (dev) {
-- struct mtk_mac *mac = netdev_priv(dev);
-+ if (!dev)
-+ continue;
-
-- mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
-- }
-+ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
-+ mtk_set_mcr_max_rx(netdev_priv(dev),
-+ dev->mtu + MTK_RX_ETH_HLEN);
- }
-
- /* Indicates CDM to parse the MTK special tag from CPU
-@@ -3848,7 +3853,7 @@ static void mtk_pending_work(struct work
- mtk_prepare_for_reset(eth);
-
- /* stop all devices to make sure that dma is properly shut down */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
- continue;
-
-@@ -3864,8 +3869,8 @@ static void mtk_pending_work(struct work
- mtk_hw_init(eth, true);
-
- /* restart DMA and enable IRQs */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!test_bit(i, &restart))
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ if (!eth->netdev[i] || !test_bit(i, &restart))
- continue;
-
- if (mtk_open(eth->netdev[i])) {
-@@ -3892,7 +3897,7 @@ static int mtk_free_dev(struct mtk_eth *
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- free_netdev(eth->netdev[i]);
-@@ -3911,7 +3916,7 @@ static int mtk_unreg_dev(struct mtk_eth
- {
- int i;
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- struct mtk_mac *mac;
- if (!eth->netdev[i])
- continue;
-@@ -4212,7 +4217,7 @@ static int mtk_add_mac(struct mtk_eth *e
- }
-
- id = be32_to_cpup(_id);
-- if (id >= MTK_MAC_COUNT) {
-+ if (id >= MTK_MAX_DEVS) {
- dev_err(eth->dev, "%d is not a valid mac id\n", id);
- return -EINVAL;
- }
-@@ -4357,7 +4362,7 @@ void mtk_eth_set_dma_device(struct mtk_e
-
- rtnl_lock();
-
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- dev = eth->netdev[i];
-
- if (!dev || !(dev->flags & IFF_UP))
-@@ -4663,7 +4668,7 @@ static int mtk_remove(struct platform_de
- int i;
-
- /* stop all devices to make sure that dma is properly shut down */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
- if (!eth->netdev[i])
- continue;
- mtk_stop(eth->netdev[i]);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -33,7 +33,6 @@
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_QDMA_RING_SIZE 2048
- #define MTK_DMA_SIZE 512
--#define MTK_MAC_COUNT 2
- #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN)
- #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
- #define MTK_DMA_DUMMY_DESC 0xffffffff
diff --git a/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch b/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch
deleted file mode 100644
index e40dc3d0a9..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch
+++ /dev/null
@@ -1,307 +0,0 @@
-From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:52:59 +0100
-Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version
- support
-
-Introduce NETSYS_V3 chipset version support.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++--
- 2 files changed, 116 insertions(+), 37 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -860,17 +860,32 @@ void mtk_stats_update_mac(struct mtk_mac
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
- hw_stats->rx_flow_control_packets +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
-- hw_stats->tx_skip +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
-- hw_stats->tx_collisions +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
-- hw_stats->tx_bytes +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
-- if (stats)
-- hw_stats->tx_bytes += (stats << 32);
-- hw_stats->tx_packets +=
-- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ hw_stats->tx_skip +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
-+ hw_stats->tx_collisions +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
-+ hw_stats->tx_bytes +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
-+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
-+ if (stats)
-+ hw_stats->tx_bytes += (stats << 32);
-+ hw_stats->tx_packets +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
-+ } else {
-+ hw_stats->tx_skip +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
-+ hw_stats->tx_collisions +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
-+ hw_stats->tx_bytes +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
-+ if (stats)
-+ hw_stats->tx_bytes += (stats << 32);
-+ hw_stats->tx_packets +=
-+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+ }
- }
-
- u64_stats_update_end(&hw_stats->syncp);
-@@ -1174,7 +1189,10 @@ static void mtk_tx_set_dma_desc_v2(struc
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-
-- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+ if (mac->id == MTK_GMAC3_ID)
-+ data = PSE_GDM3_PORT;
-+ else
-+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
- data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
- WRITE_ONCE(desc->txd4, data);
-
-@@ -1185,6 +1203,8 @@ static void mtk_tx_set_dma_desc_v2(struc
- /* tx checksum offload */
- if (info->csum)
- data |= TX_DMA_CHKSUM_V2;
-+ if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev))
-+ data |= TX_DMA_SPTAG_V3;
- }
- WRITE_ONCE(desc->txd5, data);
-
-@@ -1250,8 +1270,7 @@ static int mtk_tx_map(struct sk_buff *sk
- mtk_tx_set_dma_desc(dev, itxd, &txd_info);
-
- itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-- MTK_TX_FLAGS_FPORT1;
-+ itx_buf->mac_id = mac->id;
- setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
- k++);
-
-@@ -1299,8 +1318,7 @@ static int mtk_tx_map(struct sk_buff *sk
- memset(tx_buf, 0, sizeof(*tx_buf));
- tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
- tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
-- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-- MTK_TX_FLAGS_FPORT1;
-+ tx_buf->mac_id = mac->id;
-
- setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
- txd_info.size, k++);
-@@ -1602,7 +1620,7 @@ static int mtk_xdp_frame_map(struct mtk_
- }
- mtk_tx_set_dma_desc(dev, txd, txd_info);
-
-- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
-+ tx_buf->mac_id = mac->id;
- tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
- tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
-
-@@ -1852,11 +1870,24 @@ static int mtk_poll_rx(struct napi_struc
- break;
-
- /* find out which mac the packet come from. values start at 1 */
-- if (mtk_is_netsys_v2_or_greater(eth))
-- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
-- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-+ if (mtk_is_netsys_v2_or_greater(eth)) {
-+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
-+
-+ switch (val) {
-+ case PSE_GDM1_PORT:
-+ case PSE_GDM2_PORT:
-+ mac = val - 1;
-+ break;
-+ case PSE_GDM3_PORT:
-+ mac = MTK_GMAC3_ID;
-+ break;
-+ default:
-+ break;
-+ }
-+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
- mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
-+ }
-
- if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
- !eth->netdev[mac]))
-@@ -2078,7 +2109,6 @@ static int mtk_poll_tx_qdma(struct mtk_e
-
- while ((cpu != dma) && budget) {
- u32 next_cpu = desc->txd2;
-- int mac = 0;
-
- desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
- if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
-@@ -2086,15 +2116,13 @@ static int mtk_poll_tx_qdma(struct mtk_e
-
- tx_buf = mtk_desc_to_tx_buf(ring, desc,
- eth->soc->txrx.txd_size);
-- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
-- mac = 1;
--
- if (!tx_buf->data)
- break;
-
- if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
- if (tx_buf->type == MTK_TYPE_SKB)
-- mtk_poll_tx_done(eth, state, mac, tx_buf->data);
-+ mtk_poll_tx_done(eth, state, tx_buf->mac_id,
-+ tx_buf->data);
-
- budget--;
- }
-@@ -3703,7 +3731,24 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ /* PSE should not drop port1, port8 and port9 packets */
-+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
-+
-+ /* GDM and CDM Threshold */
-+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
-+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
-+
-+ /* Disable GDM1 RX CRC stripping */
-+ mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0));
-+
-+ /* PSE GDM3 MIB counter has incorrect hw default values,
-+ * so the driver ought to read clear the values beforehand
-+ * in case ethtool retrieve wrong mib values.
-+ */
-+ for (i = 0; i < 0x80; i += 0x4)
-+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
-+ } else if (!mtk_is_netsys_v1(eth)) {
- /* PSE should not drop port8 and port9 packets from WDMA Tx */
- mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-
-@@ -4265,7 +4310,11 @@ static int mtk_add_mac(struct mtk_eth *e
- }
- spin_lock_init(&mac->hw_stats->stats_lock);
- u64_stats_init(&mac->hw_stats->syncp);
-- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-+
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ mac->hw_stats->reg_offset = id * 0x80;
-+ else
-+ mac->hw_stats->reg_offset = id * 0x40;
-
- /* phylink create */
- err = of_get_phy_mode(np, &phy_mode);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -122,6 +122,7 @@
- #define MTK_GDMA_ICS_EN BIT(22)
- #define MTK_GDMA_TCS_EN BIT(21)
- #define MTK_GDMA_UCS_EN BIT(20)
-+#define MTK_GDMA_STRP_CRC BIT(16)
- #define MTK_GDMA_TO_PDMA 0x0
- #define MTK_GDMA_DROP_ALL 0x7777
-
-@@ -287,8 +288,6 @@
- /* QDMA Interrupt grouping registers */
- #define MTK_RLS_DONE_INT BIT(0)
-
--#define MTK_STAT_OFFSET 0x40
--
- /* QDMA TX NUM */
- #define QID_BITS_V2(x) (((x) & 0x3f) << 16)
- #define MTK_QDMA_GMAC2_QID 8
-@@ -301,6 +300,8 @@
- #define TX_DMA_CHKSUM_V2 (0x7 << 28)
- #define TX_DMA_TSO_V2 BIT(31)
-
-+#define TX_DMA_SPTAG_V3 BIT(27)
-+
- /* QDMA V2 descriptor txd4 */
- #define TX_DMA_FPORT_SHIFT_V2 8
- #define TX_DMA_FPORT_MASK_V2 0xf
-@@ -634,12 +635,6 @@ enum mtk_tx_flags {
- */
- MTK_TX_FLAGS_SINGLE0 = 0x01,
- MTK_TX_FLAGS_PAGE0 = 0x02,
--
-- /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted
-- * SKB out instead of looking up through hardware TX descriptor.
-- */
-- MTK_TX_FLAGS_FPORT0 = 0x04,
-- MTK_TX_FLAGS_FPORT1 = 0x08,
- };
-
- /* This enum allows us to identify how the clock is defined on the array of the
-@@ -725,6 +720,35 @@ enum mtk_dev_state {
- MTK_RESETTING
- };
-
-+/* PSE Port Definition */
-+enum mtk_pse_port {
-+ PSE_ADMA_PORT = 0,
-+ PSE_GDM1_PORT,
-+ PSE_GDM2_PORT,
-+ PSE_PPE0_PORT,
-+ PSE_PPE1_PORT,
-+ PSE_QDMA_TX_PORT,
-+ PSE_QDMA_RX_PORT,
-+ PSE_DROP_PORT,
-+ PSE_WDMA0_PORT,
-+ PSE_WDMA1_PORT,
-+ PSE_TDMA_PORT,
-+ PSE_NONE_PORT,
-+ PSE_PPE2_PORT,
-+ PSE_WDMA2_PORT,
-+ PSE_EIP197_PORT,
-+ PSE_GDM3_PORT,
-+ PSE_PORT_MAX
-+};
-+
-+/* GMAC Identifier */
-+enum mtk_gmac_id {
-+ MTK_GMAC1_ID = 0,
-+ MTK_GMAC2_ID,
-+ MTK_GMAC3_ID,
-+ MTK_GMAC_ID_MAX
-+};
-+
- enum mtk_tx_buf_type {
- MTK_TYPE_SKB,
- MTK_TYPE_XDP_TX,
-@@ -743,7 +767,8 @@ struct mtk_tx_buf {
- enum mtk_tx_buf_type type;
- void *data;
-
-- u32 flags;
-+ u16 mac_id;
-+ u16 flags;
- DEFINE_DMA_UNMAP_ADDR(dma_addr0);
- DEFINE_DMA_UNMAP_LEN(dma_len0);
- DEFINE_DMA_UNMAP_ADDR(dma_addr1);
-@@ -1192,6 +1217,11 @@ static inline bool mtk_is_netsys_v2_or_g
- return eth->soc->version > 1;
- }
-
-+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
-+{
-+ return eth->soc->version > 2;
-+}
-+
- static inline struct mtk_foe_entry *
- mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
- {
diff --git a/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
deleted file mode 100644
index 7a0b285f2c..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:53:13 +0100
-Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in
- mtk_soc_data struct to u64
-
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 56 ++++++++++----------
- 2 files changed, 39 insertions(+), 39 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -15,10 +15,10 @@
- struct mtk_eth_muxc {
- const char *name;
- int cap_bit;
-- int (*set_path)(struct mtk_eth *eth, int path);
-+ int (*set_path)(struct mtk_eth *eth, u64 path);
- };
-
--static const char *mtk_eth_path_name(int path)
-+static const char *mtk_eth_path_name(u64 path)
- {
- switch (path) {
- case MTK_ETH_PATH_GMAC1_RGMII:
-@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
- }
- }
-
--static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
-+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
- bool updated = true;
- u32 val, mask, set;
-@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
- return 0;
- }
-
--static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
-+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
- bool updated = true;
-@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
- return 0;
- }
-
--static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
-+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0, mask = 0, reg = 0;
- bool updated = true;
-@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
- return 0;
- }
-
--static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
- bool updated = true;
-@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
- return 0;
- }
-
--static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
- bool updated = true;
-@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
- },
- };
-
--static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
-+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
- {
- int i, err = 0;
-
-@@ -249,7 +249,7 @@ out:
-
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
-- int path;
-+ u64 path;
-
- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
- MTK_ETH_PATH_GMAC2_SGMII;
-@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
-
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
- {
-- int path = 0;
-+ u64 path = 0;
-
- if (mac_id == 1)
- path = MTK_ETH_PATH_GMAC2_GEPHY;
-@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
-
- int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
-- int path;
-+ u64 path;
-
- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII :
- MTK_ETH_PATH_GMAC2_RGMII;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -866,41 +866,41 @@ enum mkt_eth_capabilities {
- };
-
- /* Supported hardware group on SoCs */
--#define MTK_RGMII BIT(MTK_RGMII_BIT)
--#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
--#define MTK_SGMII BIT(MTK_SGMII_BIT)
--#define MTK_ESW BIT(MTK_ESW_BIT)
--#define MTK_GEPHY BIT(MTK_GEPHY_BIT)
--#define MTK_MUX BIT(MTK_MUX_BIT)
--#define MTK_INFRA BIT(MTK_INFRA_BIT)
--#define MTK_SHARED_SGMII BIT(MTK_SHARED_SGMII_BIT)
--#define MTK_HWLRO BIT(MTK_HWLRO_BIT)
--#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
--#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
--#define MTK_QDMA BIT(MTK_QDMA_BIT)
--#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
--#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
--#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
-+#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_ESW BIT_ULL(MTK_ESW_BIT)
-+#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
-+#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
-+#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_SHARED_INT BIT_ULL(MTK_SHARED_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)
-+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
-- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
- #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY \
-- BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
-- BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
-- BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
-- BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-+ BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-
- /* Supported path present on SoCs */
--#define MTK_ETH_PATH_GMAC1_RGMII BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_SGMII BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_RGMII BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_GEPHY BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
--#define MTK_ETH_PATH_GDM1_ESW BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
-+#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_TRGMII BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
-+#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
-
- #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
- #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -1045,7 +1045,7 @@ struct mtk_reg_map {
- struct mtk_soc_data {
- const struct mtk_reg_map *reg_map;
- u32 ana_rgc3;
-- u32 caps;
-+ u64 caps;
- u32 required_clks;
- bool required_pctl;
- u8 offload_version;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch
deleted file mode 100644
index 5947d385f2..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 25 Jul 2023 01:53:28 +0100
-Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to
- u64
-
-The to-be-added MT7988 SoC adds many new clocks which need to be
-controlled by the Ethernet driver, which will result in their total
-number exceeding 32.
-Prepare by converting clock bitmaps into 64-bit types.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++----------
- 1 file changed, 49 insertions(+), 47 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -666,54 +666,56 @@ enum mtk_clks_map {
- MTK_CLK_MAX
- };
-
--#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
-- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
-- BIT(MTK_CLK_TRGPLL))
--#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
-- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_GP2) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII_CK) | \
-- BIT(MTK_CLK_ETH2PLL))
-+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_TRGPLL))
-+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII_CK) | \
-+ BIT_ULL(MTK_CLK_ETH2PLL))
- #define MT7621_CLKS_BITMAP (0)
- #define MT7628_CLKS_BITMAP (0)
--#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
-- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII2_TX_250M) | \
-- BIT(MTK_CLK_SGMII2_RX_250M) | \
-- BIT(MTK_CLK_SGMII2_CDR_REF) | \
-- BIT(MTK_CLK_SGMII2_CDR_FB) | \
-- BIT(MTK_CLK_SGMII_CK) | \
-- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
--#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_WOCPU0) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII2_TX_250M) | \
-- BIT(MTK_CLK_SGMII2_RX_250M) | \
-- BIT(MTK_CLK_SGMII2_CDR_REF) | \
-- BIT(MTK_CLK_SGMII2_CDR_FB) | \
-- BIT(MTK_CLK_SGMII_CK))
--#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
-- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
-- BIT(MTK_CLK_SGMII_TX_250M) | \
-- BIT(MTK_CLK_SGMII_RX_250M) | \
-- BIT(MTK_CLK_SGMII_CDR_REF) | \
-- BIT(MTK_CLK_SGMII_CDR_FB) | \
-- BIT(MTK_CLK_SGMII2_TX_250M) | \
-- BIT(MTK_CLK_SGMII2_RX_250M) | \
-- BIT(MTK_CLK_SGMII2_CDR_REF) | \
-- BIT(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII_CK) | \
-+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
-+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_WOCPU0) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII_CK))
-+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_GP1) | \
-+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
-
- enum mtk_dev_state {
- MTK_HW_INIT,
-@@ -1046,7 +1048,7 @@ struct mtk_soc_data {
- const struct mtk_reg_map *reg_map;
- u32 ana_rgc3;
- u64 caps;
-- u32 required_clks;
-+ u64 required_clks;
- bool required_pctl;
- u8 offload_version;
- u8 hash_offset;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch
deleted file mode 100644
index 8b1493ce14..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch
+++ /dev/null
@@ -1,477 +0,0 @@
-From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 25 Jul 2023 01:57:42 +0100
-Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for
- MT7988 SoC
-
-Introduce support for ethernet chip available in MT7988 SoC to
-mtk_eth_soc driver. As a first step support only the first GMAC which
-is hard-wired to the internal DSA switch having 4 built-in gigabit
-Ethernet PHYs.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 201 +++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 86 +++++++-
- 3 files changed, 273 insertions(+), 28 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64
- static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
- bool updated = true;
-- u32 val, mask, set;
-+ u32 mask, set, reg;
-
- switch (path) {
- case MTK_ETH_PATH_GMAC1_SGMII:
-@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str
- break;
- }
-
-- if (updated) {
-- val = mtk_r32(eth, MTK_MAC_MISC);
-- val = (val & mask) | set;
-- mtk_w32(eth, val, MTK_MAC_MISC);
-- }
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ reg = MTK_MAC_MISC_V3;
-+ else
-+ reg = MTK_MAC_MISC;
-+
-+ if (updated)
-+ mtk_m32(eth, mask, set, reg);
-
- dev_dbg(eth->dev, "path %s in %s updated = %d\n",
- mtk_eth_path_name(path), __func__, updated);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
- .pse_oq_sta = 0x01a0,
- };
-
-+static const struct mtk_reg_map mt7988_reg_map = {
-+ .tx_irq_mask = 0x461c,
-+ .tx_irq_status = 0x4618,
-+ .pdma = {
-+ .rx_ptr = 0x6900,
-+ .rx_cnt_cfg = 0x6904,
-+ .pcrx_ptr = 0x6908,
-+ .glo_cfg = 0x6a04,
-+ .rst_idx = 0x6a08,
-+ .delay_irq = 0x6a0c,
-+ .irq_status = 0x6a20,
-+ .irq_mask = 0x6a28,
-+ .adma_rx_dbg0 = 0x6a38,
-+ .int_grp = 0x6a50,
-+ },
-+ .qdma = {
-+ .qtx_cfg = 0x4400,
-+ .qtx_sch = 0x4404,
-+ .rx_ptr = 0x4500,
-+ .rx_cnt_cfg = 0x4504,
-+ .qcrx_ptr = 0x4508,
-+ .glo_cfg = 0x4604,
-+ .rst_idx = 0x4608,
-+ .delay_irq = 0x460c,
-+ .fc_th = 0x4610,
-+ .int_grp = 0x4620,
-+ .hred = 0x4644,
-+ .ctx_ptr = 0x4700,
-+ .dtx_ptr = 0x4704,
-+ .crx_ptr = 0x4710,
-+ .drx_ptr = 0x4714,
-+ .fq_head = 0x4720,
-+ .fq_tail = 0x4724,
-+ .fq_count = 0x4728,
-+ .fq_blen = 0x472c,
-+ .tx_sch_rate = 0x4798,
-+ },
-+ .gdm1_cnt = 0x1c00,
-+ .gdma_to_ppe = 0x3333,
-+ .ppe_base = 0x2000,
-+ .wdma_base = {
-+ [0] = 0x4800,
-+ [1] = 0x4c00,
-+ },
-+ .pse_iq_sta = 0x0180,
-+ .pse_oq_sta = 0x01a0,
-+};
-+
- /* strings used by ethtool */
- static const struct mtk_ethtool_stats {
- char str[ETH_GSTRING_LEN];
-@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
- };
-
- static const char * const mtk_clks_source_name[] = {
-- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
-- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
-- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
-- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
-+ "ethif",
-+ "sgmiitop",
-+ "esw",
-+ "gp0",
-+ "gp1",
-+ "gp2",
-+ "gp3",
-+ "xgp1",
-+ "xgp2",
-+ "xgp3",
-+ "crypto",
-+ "fe",
-+ "trgpll",
-+ "sgmii_tx250m",
-+ "sgmii_rx250m",
-+ "sgmii_cdr_ref",
-+ "sgmii_cdr_fb",
-+ "sgmii2_tx250m",
-+ "sgmii2_rx250m",
-+ "sgmii2_cdr_ref",
-+ "sgmii2_cdr_fb",
-+ "sgmii_ck",
-+ "eth2pll",
-+ "wocpu0",
-+ "wocpu1",
-+ "netsys0",
-+ "netsys1",
-+ "ethwarp_wocpu2",
-+ "ethwarp_wocpu1",
-+ "ethwarp_wocpu0",
-+ "top_usxgmii0_sel",
-+ "top_usxgmii1_sel",
-+ "top_sgm0_sel",
-+ "top_sgm1_sel",
-+ "top_xfi_phy0_xtal_sel",
-+ "top_xfi_phy1_xtal_sel",
-+ "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",
- };
-
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
-@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
- return __raw_readl(eth->base + reg);
- }
-
--static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg)
-+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg)
- {
- u32 val;
-
-@@ -369,6 +461,19 @@ static void mtk_gmac0_rgmii_adjust(struc
- dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
- }
-
-+static void mtk_setup_bridge_switch(struct mtk_eth *eth)
-+{
-+ /* Force Port1 XGMAC Link Up */
-+ mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID),
-+ MTK_XGMAC_STS(MTK_GMAC1_ID));
-+
-+ /* Adjust GSW bridge IPG to 11 */
-+ mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK,
-+ (GSW_IPG_11 << GSWTX_IPG_SHIFT) |
-+ (GSW_IPG_11 << GSWRX_IPG_SHIFT),
-+ MTK_GSW_CFG);
-+}
-+
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
- phy_interface_t interface)
- {
-@@ -438,6 +543,8 @@ static void mtk_mac_config(struct phylin
- goto init_err;
- }
- break;
-+ case PHY_INTERFACE_MODE_INTERNAL:
-+ break;
- default:
- goto err_phy;
- }
-@@ -515,6 +622,15 @@ static void mtk_mac_config(struct phylin
- return;
- }
-
-+ /* Setup gmac */
-+ if (mtk_is_netsys_v3_or_greater(eth) &&
-+ mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
-+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+
-+ mtk_setup_bridge_switch(eth);
-+ }
-+
- return;
-
- err_phy:
-@@ -724,11 +840,15 @@ static int mtk_mdio_init(struct mtk_eth
- }
- divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
-
-+ /* Configure MDC Turbo Mode */
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3);
-+
- /* Configure MDC Divider */
-- val = mtk_r32(eth, MTK_PPSC);
-- val &= ~PPSC_MDC_CFG;
-- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
-- mtk_w32(eth, val, MTK_PPSC);
-+ val = FIELD_PREP(PPSC_MDC_CFG, divider);
-+ if (!mtk_is_netsys_v3_or_greater(eth))
-+ val |= PPSC_MDC_TURBO;
-+ mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC);
-
- dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
-
-@@ -1189,10 +1309,19 @@ static void mtk_tx_set_dma_desc_v2(struc
- data |= TX_DMA_LS0;
- WRITE_ONCE(desc->txd3, data);
-
-- if (mac->id == MTK_GMAC3_ID)
-- data = PSE_GDM3_PORT;
-- else
-- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+ /* set forward port */
-+ switch (mac->id) {
-+ case MTK_GMAC1_ID:
-+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
-+ break;
-+ case MTK_GMAC2_ID:
-+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
-+ break;
-+ case MTK_GMAC3_ID:
-+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
-+ break;
-+ }
-+
- data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
- WRITE_ONCE(desc->txd4, data);
-
-@@ -4359,6 +4488,17 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->phylink_config.supported_interfaces);
- }
-
-+ if (mtk_is_netsys_v3_or_greater(mac->hw) &&
-+ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) &&
-+ id == MTK_GMAC1_ID) {
-+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
-+ MAC_SYM_PAUSE |
-+ MAC_10000FD;
-+ phy_interface_zero(mac->phylink_config.supported_interfaces);
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ mac->phylink_config.supported_interfaces);
-+ }
-+
- phylink = phylink_create(&mac->phylink_config,
- of_fwnode_handle(mac->of_node),
- phy_mode, &mtk_phylink_ops);
-@@ -4879,6 +5019,24 @@ static const struct mtk_soc_data mt7986_
- },
- };
-
-+static const struct mtk_soc_data mt7988_data = {
-+ .reg_map = &mt7988_reg_map,
-+ .ana_rgc3 = 0x128,
-+ .caps = MT7988_CAPS,
-+ .hw_features = MTK_HW_FEATURES,
-+ .required_clks = MT7988_CLKS_BITMAP,
-+ .required_pctl = false,
-+ .version = 3,
-+ .txrx = {
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+};
-+
- static const struct mtk_soc_data rt5350_data = {
- .reg_map = &mt7628_reg_map,
- .caps = MT7628_CAPS,
-@@ -4897,14 +5055,15 @@ static const struct mtk_soc_data rt5350_
- };
-
- const struct of_device_id of_mtk_match[] = {
-- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
-- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
-- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
-- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
-- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
-- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
-- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
-- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
-+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
-+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
-+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
-+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
-+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
-+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
-+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
-+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
-+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
- {},
- };
- MODULE_DEVICE_TABLE(of, of_mtk_match);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -117,7 +117,8 @@
- #define MTK_CDMP_EG_CTRL 0x404
-
- /* GDM Exgress Control Register */
--#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
-+#define MTK_GDMA_FWD_CFG(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x540 : 0x500 + (_x * 0x1000); })
- #define MTK_GDMA_SPECIAL_TAG BIT(24)
- #define MTK_GDMA_ICS_EN BIT(22)
- #define MTK_GDMA_TCS_EN BIT(21)
-@@ -126,6 +127,11 @@
- #define MTK_GDMA_TO_PDMA 0x0
- #define MTK_GDMA_DROP_ALL 0x7777
-
-+/* GDM Egress Control Register */
-+#define MTK_GDMA_EG_CTRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x544 : 0x504 + (_x * 0x1000); })
-+#define MTK_GDMA_XGDM_SEL BIT(31)
-+
- /* Unicast Filter MAC Address Register - Low */
- #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
-
-@@ -389,7 +395,26 @@
- #define PHY_IAC_TIMEOUT HZ
-
- #define MTK_MAC_MISC 0x1000c
-+#define MTK_MAC_MISC_V3 0x10010
- #define MTK_MUX_TO_ESW BIT(0)
-+#define MISC_MDC_TURBO BIT(4)
-+
-+/* XMAC status registers */
-+#define MTK_XGMAC_STS(x) (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C)
-+#define MTK_XGMAC_FORCE_LINK(x) (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15))
-+#define MTK_USXGMII_PCS_LINK BIT(8)
-+#define MTK_XGMAC_RX_FC BIT(5)
-+#define MTK_XGMAC_TX_FC BIT(4)
-+#define MTK_USXGMII_PCS_MODE GENMASK(3, 1)
-+#define MTK_XGMAC_LINK_STS BIT(0)
-+
-+/* GSW bridge registers */
-+#define MTK_GSW_CFG (0x10080)
-+#define GSWTX_IPG_MASK GENMASK(19, 16)
-+#define GSWTX_IPG_SHIFT 16
-+#define GSWRX_IPG_MASK GENMASK(3, 0)
-+#define GSWRX_IPG_SHIFT 0
-+#define GSW_IPG_11 11
-
- /* Mac control registers */
- #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100))
-@@ -647,6 +672,11 @@ enum mtk_clks_map {
- MTK_CLK_GP0,
- MTK_CLK_GP1,
- MTK_CLK_GP2,
-+ MTK_CLK_GP3,
-+ MTK_CLK_XGP1,
-+ MTK_CLK_XGP2,
-+ MTK_CLK_XGP3,
-+ MTK_CLK_CRYPTO,
- MTK_CLK_FE,
- MTK_CLK_TRGPLL,
- MTK_CLK_SGMII_TX_250M,
-@@ -663,6 +693,27 @@ enum mtk_clks_map {
- MTK_CLK_WOCPU1,
- MTK_CLK_NETSYS0,
- MTK_CLK_NETSYS1,
-+ MTK_CLK_ETHWARP_WOCPU2,
-+ MTK_CLK_ETHWARP_WOCPU1,
-+ MTK_CLK_ETHWARP_WOCPU0,
-+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
-+ MTK_CLK_TOP_SGM_0_SEL,
-+ MTK_CLK_TOP_SGM_1_SEL,
-+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
-+ MTK_CLK_TOP_ETH_GMII_SEL,
-+ MTK_CLK_TOP_ETH_REFCK_50M_SEL,
-+ MTK_CLK_TOP_ETH_SYS_200M_SEL,
-+ MTK_CLK_TOP_ETH_SYS_SEL,
-+ MTK_CLK_TOP_ETH_XGMII_SEL,
-+ MTK_CLK_TOP_ETH_MII_SEL,
-+ MTK_CLK_TOP_NETSYS_SEL,
-+ MTK_CLK_TOP_NETSYS_500M_SEL,
-+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
-+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
-+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
-+ MTK_CLK_TOP_NETSYS_WARP_SEL,
- MTK_CLK_MAX
- };
-
-@@ -716,6 +767,36 @@ enum mtk_clks_map {
- BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
- BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
- BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
-+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
-+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
-+ BIT_ULL(MTK_CLK_CRYPTO) | \
-+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
-+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
-+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
-+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
-
- enum mtk_dev_state {
- MTK_HW_INIT,
-@@ -964,6 +1045,8 @@ enum mkt_eth_capabilities {
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_RSTCTRL_PPE1)
-
-+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
-+
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
- u32 size;
-@@ -1309,6 +1392,7 @@ void mtk_stats_update_mac(struct mtk_mac
-
- 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_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
diff --git a/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch
deleted file mode 100644
index bb48dadec0..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 27 Jul 2023 09:02:26 +0200
-Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support
- for MT7988 SoC
-
-In order to recycle pages, enable page_pool allocator for MT7988 SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1657,7 +1657,7 @@ static void mtk_update_rx_cpu_idx(struct
-
- static bool mtk_page_pool_enabled(struct mtk_eth *eth)
- {
-- return eth->soc->version == 2;
-+ return mtk_is_netsys_v2_or_greater(eth);
- }
-
- static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
diff --git a/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch
deleted file mode 100644
index bb8deb9846..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 27 Jul 2023 09:07:28 +0200
-Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw
- flowtable_offload for MT7988 SoC
-
-Enable hw Packet Process Engine (PPE) for MT7988 SoC.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
- drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++----
- drivers/net/ethernet/mediatek/mtk_ppe.h | 19 ++++++++++++++++++-
- 3 files changed, 36 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5027,6 +5027,9 @@ static const struct mtk_soc_data mt7988_
- .required_clks = MT7988_CLKS_BITMAP,
- .required_pctl = false,
- .version = 3,
-+ .offload_version = 2,
-+ .hash_offset = 4,
-+ .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ switch (eth->soc->version) {
-+ case 3:
-+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
-+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
-+ MTK_FOE_IB2_WDMA_WINFO_V2;
-+ l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
-+ FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
-+ break;
-+ case 2:
- *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
- *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
- MTK_FOE_IB2_WDMA_WINFO_V2;
- l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
- FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
-- } else {
-+ break;
-+ default:
- *ib2 &= ~MTK_FOE_IB2_PORT_MG;
- *ib2 |= MTK_FOE_IB2_WDMA_WINFO;
- if (wdma_idx)
-@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
- FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
- FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
-+ break;
- }
-
- return 0;
-@@ -950,8 +960,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- mtk_ppe_init_foe_table(ppe);
- ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
-
-- val = MTK_PPE_TB_CFG_ENTRY_80B |
-- MTK_PPE_TB_CFG_AGE_NON_L4 |
-+ val = MTK_PPE_TB_CFG_AGE_NON_L4 |
- MTK_PPE_TB_CFG_AGE_UNBIND |
- MTK_PPE_TB_CFG_AGE_TCP |
- MTK_PPE_TB_CFG_AGE_UDP |
-@@ -967,6 +976,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
- MTK_PPE_ENTRIES_SHIFT);
- if (mtk_is_netsys_v2_or_greater(ppe->eth))
- val |= MTK_PPE_TB_CFG_INFO_SEL;
-+ if (!mtk_is_netsys_v3_or_greater(ppe->eth))
-+ val |= MTK_PPE_TB_CFG_ENTRY_80B;
- ppe_w32(ppe, MTK_PPE_TB_CFG, val);
-
- ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK,
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -85,6 +85,17 @@ enum {
- #define MTK_FOE_WINFO_BSS GENMASK(5, 0)
- #define MTK_FOE_WINFO_WCID GENMASK(15, 6)
-
-+#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16)
-+#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0)
-+
-+#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0)
-+#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16)
-+#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20)
-+#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21)
-+#define MTK_FOE_WINFO_PAO_IS_SP BIT(22)
-+#define MTK_FOE_WINFO_PAO_HF BIT(23)
-+#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24)
-+
- enum {
- MTK_FOE_STATE_INVALID,
- MTK_FOE_STATE_UNBIND,
-@@ -106,8 +117,13 @@ struct mtk_foe_mac_info {
- u16 pppoe_id;
- u16 src_mac_lo;
-
-+ /* netsys_v2 */
- u16 minfo;
- u16 winfo;
-+
-+ /* netsys_v3 */
-+ u32 w3info;
-+ u32 wpao;
- };
-
- /* software-only entry type */
-@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd {
-
- #define MTK_FOE_ENTRY_V1_SIZE 80
- #define MTK_FOE_ENTRY_V2_SIZE 96
-+#define MTK_FOE_ENTRY_V3_SIZE 128
-
- struct mtk_foe_entry {
- u32 ib1;
-@@ -228,7 +245,7 @@ struct mtk_foe_entry {
- struct mtk_foe_ipv4_dslite dslite;
- struct mtk_foe_ipv6 ipv6;
- struct mtk_foe_ipv6_6rd ipv6_6rd;
-- u32 data[23];
-+ u32 data[31];
- };
- };
-
diff --git a/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch
deleted file mode 100644
index c985b6a9c7..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 2 Aug 2023 04:31:09 +0100
-Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow
- accounting on MT7988
-
-NETSYS_V3 uses 64 bits for each counters while older SoCs are using
-48/40 bits for each counter.
-Support reading per-flow byte and package counters on NETSYS_V3.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
- drivers/net/ethernet/mediatek/mtk_ppe.c | 21 +++++++++++++-------
- drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 2 ++
- 3 files changed, 17 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5029,6 +5029,7 @@ static const struct mtk_soc_data mt7988_
- .version = 3,
- .offload_version = 2,
- .hash_offset = 4,
-+ .has_accounting = true,
- .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
- .txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct
-
- static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
- {
-- u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
- u32 val, cnt_r0, cnt_r1, cnt_r2;
- int ret;
-
-@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk
- cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
- cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
-
-- byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-- byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-- pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-- pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-- *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+ if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
-+ /* 64 bit for each counter */
-+ u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
-+ *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
-+ *packets = ((u64)cnt_r3 << 32) | cnt_r2;
-+ } else {
-+ /* 48 bit byte counter, 40 bit packet counter */
-+ u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-+ u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-+ u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-+ u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+ }
-
- return 0;
- }
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -163,6 +163,8 @@ enum {
- #define MTK_PPE_MIB_SER_R2 0x348
- #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0)
-
-+#define MTK_PPE_MIB_SER_R3 0x34c
-+
- #define MTK_PPE_MIB_CACHE_CTL 0x350
- #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
- #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)
diff --git a/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch
deleted file mode 100644
index 6f1639a572..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 21 Aug 2023 17:12:44 +0100
-Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw
- reset
-
-When a hardware reset is triggered on devices not initializing WED the
-calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a
-pointer on uninitialized stack memory.
-Break out of both functions in case a hw_list entry is 0.
-
-Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void)
-
- for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
- struct mtk_wed_hw *hw = hw_list[i];
-- struct mtk_wed_device *dev = hw->wed_dev;
-+ struct mtk_wed_device *dev;
- int err;
-
-+ if (!hw)
-+ break;
-+
-+ dev = hw->wed_dev;
- if (!dev || !dev->wlan.reset)
- continue;
-
-@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void)
-
- for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
- struct mtk_wed_hw *hw = hw_list[i];
-- struct mtk_wed_device *dev = hw->wed_dev;
-+ struct mtk_wed_device *dev;
-+
-+ if (!hw)
-+ break;
-
-+ dev = hw->wed_dev;
- if (!dev || !dev->wlan.reset_complete)
- continue;
-
diff --git a/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch
deleted file mode 100644
index 2190761fdd..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:31:24 +0100
-Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions
- for MT7988
-
-More register macros need to be adjusted for the 3rd GMAC on MT7988.
-Account for added bit in SYSCFG0_SGMII_MASK.
-
-Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -133,10 +133,12 @@
- #define MTK_GDMA_XGDM_SEL BIT(31)
-
- /* Unicast Filter MAC Address Register - Low */
--#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
-+#define MTK_GDMA_MAC_ADRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x548 : 0x508 + (_x * 0x1000); })
-
- /* Unicast Filter MAC Address Register - High */
--#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
-+#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
-+ 0x54C : 0x50C + (_x * 0x1000); })
-
- /* FE global misc reg*/
- #define MTK_FE_GLO_MISC 0x124
-@@ -503,7 +505,7 @@
- #define ETHSYS_SYSCFG0 0x14
- #define SYSCFG0_GE_MASK 0x3
- #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2)))
--#define SYSCFG0_SGMII_MASK GENMASK(9, 8)
-+#define SYSCFG0_SGMII_MASK GENMASK(9, 7)
- #define SYSCFG0_SGMII_GMAC1 ((2 << 8) & SYSCFG0_SGMII_MASK)
- #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK)
- #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
diff --git a/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch
deleted file mode 100644
index e87e0f2522..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:32:03 +0100
-Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988
-
-Add bits needed to reset the frame engine on MT7988.
-
-Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++--
- 2 files changed, 68 insertions(+), 24 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3593,19 +3593,34 @@ static void mtk_hw_reset(struct mtk_eth
- {
- u32 val;
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v2_or_greater(eth))
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-+
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ val = RSTCTRL_PPE0_V3;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1_V3;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ val |= RSTCTRL_PPE2;
-+
-+ val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
-+ } else if (mtk_is_netsys_v2_or_greater(eth)) {
- val = RSTCTRL_PPE0_V2;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= RSTCTRL_PPE1;
- } else {
- val = RSTCTRL_PPE0;
- }
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val |= RSTCTRL_PPE1;
--
- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
-
-- if (mtk_is_netsys_v2_or_greater(eth))
-+ if (mtk_is_netsys_v3_or_greater(eth))
-+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-+ 0x6f8ff);
-+ else if (mtk_is_netsys_v2_or_greater(eth))
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
- 0x3ffffff);
- }
-@@ -3631,13 +3646,21 @@ static void mtk_hw_warm_reset(struct mtk
- return;
- }
-
-- if (mtk_is_netsys_v2_or_greater(eth))
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ rst_mask |= RSTCTRL_PPE1_V3;
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ rst_mask |= RSTCTRL_PPE2;
-+
-+ rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
-+ } else if (mtk_is_netsys_v2_or_greater(eth)) {
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
-- else
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ rst_mask |= RSTCTRL_PPE1;
-+ } else {
- rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
--
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- rst_mask |= RSTCTRL_PPE1;
-+ }
-
- regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
-
-@@ -3989,11 +4012,17 @@ static void mtk_prepare_for_reset(struct
- u32 val;
- int i;
-
-- /* disabe FE P3 and P4 */
-- val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val |= MTK_FE_LINK_DOWN_P4;
-- mtk_w32(eth, val, MTK_FE_GLO_CFG);
-+ /* set FE PPE ports link down */
-+ for (i = MTK_GMAC1_ID;
-+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
-+ i += 2) {
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
-+ }
-
- /* adjust PPE configurations to prepare for reset */
- for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
-@@ -4054,11 +4083,18 @@ static void mtk_pending_work(struct work
- }
- }
-
-- /* enabe FE P3 and P4 */
-- val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-- val &= ~MTK_FE_LINK_DOWN_P4;
-- mtk_w32(eth, val, MTK_FE_GLO_CFG);
-+ /* set FE PPE ports link up */
-+ for (i = MTK_GMAC1_ID;
-+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
-+ i += 2) {
-+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
-+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
-+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
-+
-+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
-+ }
-
- clear_bit(MTK_RESETTING, &eth->state);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -76,9 +76,8 @@
- #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522
-
- /* Frame Engine Global Configuration */
--#define MTK_FE_GLO_CFG 0x00
--#define MTK_FE_LINK_DOWN_P3 BIT(11)
--#define MTK_FE_LINK_DOWN_P4 BIT(12)
-+#define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00)
-+#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16)
-
- /* Frame Engine Global Reset Register */
- #define MTK_RST_GL 0x04
-@@ -522,9 +521,15 @@
- /* ethernet reset control register */
- #define ETHSYS_RSTCTRL 0x34
- #define RSTCTRL_FE BIT(6)
-+#define RSTCTRL_WDMA0 BIT(24)
-+#define RSTCTRL_WDMA1 BIT(25)
-+#define RSTCTRL_WDMA2 BIT(26)
- #define RSTCTRL_PPE0 BIT(31)
- #define RSTCTRL_PPE0_V2 BIT(30)
- #define RSTCTRL_PPE1 BIT(31)
-+#define RSTCTRL_PPE0_V3 BIT(29)
-+#define RSTCTRL_PPE1_V3 BIT(30)
-+#define RSTCTRL_PPE2 BIT(31)
- #define RSTCTRL_ETH BIT(23)
-
- /* ethernet reset check idle register */
-@@ -931,6 +936,7 @@ enum mkt_eth_capabilities {
- MTK_QDMA_BIT,
- MTK_SOC_MT7628_BIT,
- MTK_RSTCTRL_PPE1_BIT,
-+ MTK_RSTCTRL_PPE2_BIT,
- MTK_U3_COPHY_V2_BIT,
-
- /* MUX BITS*/
-@@ -965,6 +971,7 @@ enum mkt_eth_capabilities {
- #define MTK_QDMA BIT_ULL(MTK_QDMA_BIT)
- #define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
- #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
-@@ -1047,7 +1054,8 @@ enum mkt_eth_capabilities {
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_RSTCTRL_PPE1)
-
--#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
-+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
-+ MTK_RSTCTRL_PPE2)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch
deleted file mode 100644
index 2d0951a9ec..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:32:54 +0100
-Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC
- SRAM
-
-MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet
-DMA rings. Support using the SRAM without breaking existing device tree
-bindings, ie. only new SoC starting from MT7988 will have the SRAM
-declared as additional resource in device tree. For MT7981 and MT7986
-an offset on top of the main I/O base is used.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++-----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++-
- 2 files changed, 78 insertions(+), 22 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1117,10 +1117,13 @@ static int mtk_init_fq_dma(struct mtk_et
- dma_addr_t dma_addr;
- int i;
-
-- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
-- cnt * soc->txrx.txd_size,
-- &eth->phy_scratch_ring,
-- GFP_KERNEL);
-+ 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->txrx.txd_size,
-+ &eth->phy_scratch_ring,
-+ GFP_KERNEL);
- if (unlikely(!eth->scratch_ring))
- return -ENOMEM;
-
-@@ -2428,8 +2431,14 @@ static int mtk_tx_alloc(struct mtk_eth *
- if (!ring->buf)
- goto no_tx_mem;
-
-- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
-- &ring->phys, GFP_KERNEL);
-+ if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
-+ ring->dma = eth->sram_base + ring_size * sz;
-+ ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
-+ } else {
-+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
-+ &ring->phys, GFP_KERNEL);
-+ }
-+
- if (!ring->dma)
- goto no_tx_mem;
-
-@@ -2528,8 +2537,7 @@ static void mtk_tx_clean(struct mtk_eth
- kfree(ring->buf);
- ring->buf = NULL;
- }
--
-- if (ring->dma) {
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
- dma_free_coherent(eth->dma_dev,
- ring->dma_size * soc->txrx.txd_size,
- ring->dma, ring->phys);
-@@ -2548,9 +2556,14 @@ static int mtk_rx_alloc(struct mtk_eth *
- {
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
- struct mtk_rx_ring *ring;
-- int rx_data_len, rx_dma_size;
-+ int rx_data_len, rx_dma_size, tx_ring_size;
- int i;
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
-+ tx_ring_size = MTK_QDMA_RING_SIZE;
-+ else
-+ tx_ring_size = MTK_DMA_SIZE;
-+
- if (rx_flag == MTK_RX_FLAGS_QDMA) {
- if (ring_no)
- return -EINVAL;
-@@ -2585,9 +2598,20 @@ static int mtk_rx_alloc(struct mtk_eth *
- ring->page_pool = pp;
- }
-
-- ring->dma = dma_alloc_coherent(eth->dma_dev,
-- rx_dma_size * eth->soc->txrx.rxd_size,
-- &ring->phys, GFP_KERNEL);
-+ 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->txrx.rxd_size,
-+ &ring->phys, GFP_KERNEL);
-+ } else {
-+ struct mtk_tx_ring *tx_ring = &eth->tx_ring;
-+
-+ ring->dma = tx_ring->dma + tx_ring_size *
-+ eth->soc->txrx.txd_size * (ring_no + 1);
-+ ring->phys = tx_ring->phys + tx_ring_size *
-+ eth->soc->txrx.txd_size * (ring_no + 1);
-+ }
-+
- if (!ring->dma)
- return -ENOMEM;
-
-@@ -2672,7 +2696,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- return 0;
- }
-
--static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
-+static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
- {
- int i;
-
-@@ -2695,7 +2719,7 @@ static void mtk_rx_clean(struct mtk_eth
- ring->data = NULL;
- }
-
-- if (ring->dma) {
-+ if (!in_sram && ring->dma) {
- dma_free_coherent(eth->dma_dev,
- ring->dma_size * eth->soc->txrx.rxd_size,
- ring->dma, ring->phys);
-@@ -3058,7 +3082,7 @@ static void mtk_dma_free(struct mtk_eth
- for (i = 0; i < MTK_MAX_DEVS; i++)
- if (eth->netdev[i])
- netdev_reset_queue(eth->netdev[i]);
-- if (eth->scratch_ring) {
-+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
- dma_free_coherent(eth->dma_dev,
- MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
- eth->scratch_ring, eth->phy_scratch_ring);
-@@ -3066,13 +3090,13 @@ static void mtk_dma_free(struct mtk_eth
- eth->phy_scratch_ring = 0;
- }
- mtk_tx_clean(eth);
-- mtk_rx_clean(eth, &eth->rx_ring[0]);
-- mtk_rx_clean(eth, &eth->rx_ring_qdma);
-+ mtk_rx_clean(eth, &eth->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM));
-+ mtk_rx_clean(eth, &eth->rx_ring_qdma, false);
-
- if (eth->hwlro) {
- mtk_hwlro_rx_uninit(eth);
- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
-- mtk_rx_clean(eth, &eth->rx_ring[i]);
-+ mtk_rx_clean(eth, &eth->rx_ring[i], false);
- }
-
- kfree(eth->scratch_head);
-@@ -4640,7 +4664,7 @@ static int mtk_sgmii_init(struct mtk_eth
-
- static int mtk_probe(struct platform_device *pdev)
- {
-- struct resource *res = NULL;
-+ struct resource *res = NULL, *res_sram;
- struct device_node *mac_np;
- struct mtk_eth *eth;
- int err, i;
-@@ -4660,6 +4684,20 @@ static int mtk_probe(struct platform_dev
- 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;
-+ }
-+ }
-+
- spin_lock_init(&eth->page_lock);
- spin_lock_init(&eth->tx_irq_lock);
- spin_lock_init(&eth->rx_irq_lock);
-@@ -4723,6 +4761,18 @@ static int mtk_probe(struct platform_dev
- 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) {
-+ err = -EINVAL;
-+ goto err_destroy_sgmii;
-+ }
-+ eth->phy_scratch_ring = res_sram->start;
-+ } else {
-+ eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET;
-+ }
-+ }
- }
-
- if (eth->soc->offload_version) {
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -139,6 +139,9 @@
- #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
-+
- /* FE global misc reg*/
- #define MTK_FE_GLO_MISC 0x124
-
-@@ -938,6 +941,7 @@ enum mkt_eth_capabilities {
- MTK_RSTCTRL_PPE1_BIT,
- MTK_RSTCTRL_PPE2_BIT,
- MTK_U3_COPHY_V2_BIT,
-+ MTK_SRAM_BIT,
-
- /* MUX BITS*/
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-@@ -973,6 +977,7 @@ enum mkt_eth_capabilities {
- #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
- #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
- #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
-+#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -1048,14 +1053,14 @@ 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_RSTCTRL_PPE1 | MTK_SRAM)
-
- #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
-- MTK_RSTCTRL_PPE1)
-+ MTK_RSTCTRL_PPE1 | MTK_SRAM)
-
- #define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
-- MTK_RSTCTRL_PPE2)
-+ MTK_RSTCTRL_PPE2 | MTK_SRAM)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
-@@ -1215,6 +1220,7 @@ struct mtk_eth {
- struct device *dev;
- struct device *dma_dev;
- void __iomem *base;
-+ void *sram_base;
- spinlock_t page_lock;
- spinlock_t tx_irq_lock;
- spinlock_t rx_irq_lock;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch
deleted file mode 100644
index 416c4f48ef..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 17:33:12 +0100
-Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA
- addressing on MT7988
-
-Systems having 4 GiB of RAM and more require DMA addressing beyond the
-current 32-bit limit. Starting from MT7988 the hardware now supports
-36-bit DMA addressing, let's use that new capability in the driver to
-avoid running into swiotlb on systems with 4 GiB of RAM or more.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++--
- 2 files changed, 48 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1310,6 +1310,10 @@ static void mtk_tx_set_dma_desc_v2(struc
- data = TX_DMA_PLEN0(info->size);
- if (info->last)
- data |= TX_DMA_LS0;
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ data |= TX_DMA_PREP_ADDR64(info->addr);
-+
- WRITE_ONCE(desc->txd3, data);
-
- /* set forward port */
-@@ -1979,6 +1983,7 @@ static int mtk_poll_rx(struct napi_struc
- bool xdp_flush = false;
- int idx;
- struct sk_buff *skb;
-+ u64 addr64 = 0;
- u8 *data, *new_data;
- struct mtk_rx_dma_v2 *rxd, trxd;
- int done = 0, bytes = 0;
-@@ -2094,7 +2099,10 @@ static int mtk_poll_rx(struct napi_struc
- goto release_desc;
- }
-
-- dma_unmap_single(eth->dma_dev, trxd.rxd1,
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ addr64 = RX_DMA_GET_ADDR64(trxd.rxd2);
-+
-+ dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
- ring->buf_size, DMA_FROM_DEVICE);
-
- skb = build_skb(data, ring->frag_size);
-@@ -2160,6 +2168,9 @@ release_desc:
- else
- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
-+
- ring->calc_idx = idx;
- done++;
- }
-@@ -2652,6 +2663,9 @@ static int mtk_rx_alloc(struct mtk_eth *
- else
- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
-+
- rxd->rxd3 = 0;
- rxd->rxd4 = 0;
- if (mtk_is_netsys_v2_or_greater(eth)) {
-@@ -2698,6 +2712,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-
- static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
- {
-+ u64 addr64 = 0;
- int i;
-
- if (ring->data && ring->dma) {
-@@ -2711,7 +2726,10 @@ static void mtk_rx_clean(struct mtk_eth
- if (!rxd->rxd1)
- continue;
-
-- dma_unmap_single(eth->dma_dev, rxd->rxd1,
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ addr64 = RX_DMA_GET_ADDR64(rxd->rxd2);
-+
-+ dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64),
- ring->buf_size, DMA_FROM_DEVICE);
- mtk_rx_put_buff(ring, ring->data[i], false);
- }
-@@ -4698,6 +4716,14 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
-+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
-+ if (err) {
-+ dev_err(&pdev->dev, "Wrong DMA config\n");
-+ return -EINVAL;
-+ }
-+ }
-+
- spin_lock_init(&eth->page_lock);
- spin_lock_init(&eth->tx_irq_lock);
- spin_lock_init(&eth->rx_irq_lock);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -331,6 +331,14 @@
- #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len)
- #define TX_DMA_SWC BIT(14)
- #define TX_DMA_PQID GENMASK(3, 0)
-+#define TX_DMA_ADDR64_MASK GENMASK(3, 0)
-+#if IS_ENABLED(CONFIG_64BIT)
-+# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32)
-+# define TX_DMA_PREP_ADDR64(x) FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32))
-+#else
-+# define TX_DMA_GET_ADDR64(x) (0)
-+# define TX_DMA_PREP_ADDR64(x) (0)
-+#endif
-
- /* PDMA on MT7628 */
- #define TX_DMA_DONE BIT(31)
-@@ -343,6 +351,14 @@
- #define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
- #define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
- #define RX_DMA_VTAG BIT(15)
-+#define RX_DMA_ADDR64_MASK GENMASK(3, 0)
-+#if IS_ENABLED(CONFIG_64BIT)
-+# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32)
-+# define RX_DMA_PREP_ADDR64(x) FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32))
-+#else
-+# define RX_DMA_GET_ADDR64(x) (0)
-+# define RX_DMA_PREP_ADDR64(x) (0)
-+#endif
-
- /* QDMA descriptor rxd3 */
- #define RX_DMA_VID(x) ((x) & VLAN_VID_MASK)
-@@ -942,6 +958,7 @@ enum mkt_eth_capabilities {
- MTK_RSTCTRL_PPE2_BIT,
- MTK_U3_COPHY_V2_BIT,
- MTK_SRAM_BIT,
-+ MTK_36BIT_DMA_BIT,
-
- /* MUX BITS*/
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-@@ -978,6 +995,7 @@ enum mkt_eth_capabilities {
- #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
- #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
- #define MTK_SRAM BIT_ULL(MTK_SRAM_BIT)
-+#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
-
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -1059,8 +1077,8 @@ enum mkt_eth_capabilities {
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_RSTCTRL_PPE1 | MTK_SRAM)
-
--#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
-- MTK_RSTCTRL_PPE2 | MTK_SRAM)
-+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
-+ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
-
- struct mtk_tx_dma_desc_info {
- dma_addr_t addr;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch b/target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch
deleted file mode 100644
index d761866d0d..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From e10a35abb3da12b812cfb6fc6137926a0c81e39a Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 10 Sep 2023 22:40:30 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix uninitialized variable
-
-Variable dma_addr in function mtk_poll_rx can be uninitialized on
-some of the error paths. In practise this doesn't matter, even random
-data present in uninitialized stack memory can safely be used in the
-way it happens in the error path.
-
-However, in order to make Smatch happy make sure the variable is
-always initialized.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1987,11 +1987,11 @@ static int mtk_poll_rx(struct napi_struc
- u8 *data, *new_data;
- struct mtk_rx_dma_v2 *rxd, trxd;
- int done = 0, bytes = 0;
-+ dma_addr_t dma_addr = DMA_MAPPING_ERROR;
-
- while (done < budget) {
- unsigned int pktlen, *rxdcsum;
- struct net_device *netdev;
-- dma_addr_t dma_addr;
- u32 hash, reason;
- int mac = 0;
-
-@@ -2168,7 +2168,8 @@ release_desc:
- else
- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
-
-- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) &&
-+ likely(dma_addr != DMA_MAPPING_ERROR))
- rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
-
- ring->calc_idx = idx;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch b/target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch
deleted file mode 100644
index ac3e3a3e67..0000000000
--- a/target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 5a124b1fd3e6cb15a943f0cdfe96aa8f6d3d2f39 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 9 Sep 2023 20:41:56 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix pse_port configuration for
- MT7988
-
-MT7988 SoC support 3 NICs. Fix pse_port configuration in
-mtk_flow_set_output_device routine if the traffic is offloaded to eth2.
-Rely on mtk_pse_port definitions.
-
-Fixes: 88efedf517e6 ("net: ethernet: mtk_eth_soc: enable nft hw flowtable_offload for MT7988 SoC")
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -214,9 +214,11 @@ mtk_flow_set_output_device(struct mtk_et
- dsa_port = mtk_flow_get_dsa_port(&dev);
-
- if (dev == eth->netdev[0])
-- pse_port = 1;
-+ pse_port = PSE_GDM1_PORT;
- else if (dev == eth->netdev[1])
-- pse_port = 2;
-+ pse_port = PSE_GDM2_PORT;
-+ else if (dev == eth->netdev[2])
-+ pse_port = PSE_GDM3_PORT;
- else
- return -EOPNOTSUPP;
-
diff --git a/target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch
deleted file mode 100644
index 46da5b283f..0000000000
--- a/target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch
+++ /dev/null
@@ -1,271 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 20 Mar 2023 11:44:30 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add code for offloading flows
- from wlan devices
-
-WED version 2 (on MT7986 and later) can offload flows originating from wireless
-devices. In order to make that work, ndo_setup_tc needs to be implemented on
-the netdevs. This adds the required code to offload flows coming in from WED,
-while keeping track of the incoming wed index used for selecting the correct
-PPE device.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 37 ++++---
- drivers/net/ethernet/mediatek/mtk_wed.c | 101 ++++++++++++++++++
- include/linux/soc/mediatek/mtk_wed.h | 6 ++
- 4 files changed, 133 insertions(+), 14 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1435,6 +1435,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
- int mtk_eth_offload_init(struct mtk_eth *eth);
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
- void *type_data);
-+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
-+ int ppe_index);
-+void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
- void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
-
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -237,7 +237,8 @@ out:
- }
-
- static int
--mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
-+mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f,
-+ int ppe_index)
- {
- struct flow_rule *rule = flow_cls_offload_flow_rule(f);
- struct flow_action_entry *act;
-@@ -454,6 +455,7 @@ mtk_flow_offload_replace(struct mtk_eth
- entry->cookie = f->cookie;
- memcpy(&entry->data, &foe, sizeof(entry->data));
- entry->wed_index = wed_index;
-+ entry->ppe_index = ppe_index;
-
- err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry);
- if (err < 0)
-@@ -522,25 +524,15 @@ mtk_flow_offload_stats(struct mtk_eth *e
-
- static DEFINE_MUTEX(mtk_flow_offload_mutex);
-
--static int
--mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
-+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
-+ int ppe_index)
- {
-- struct flow_cls_offload *cls = type_data;
-- struct net_device *dev = cb_priv;
-- struct mtk_mac *mac = netdev_priv(dev);
-- struct mtk_eth *eth = mac->hw;
- int err;
-
-- if (!tc_can_offload(dev))
-- return -EOPNOTSUPP;
--
-- if (type != TC_SETUP_CLSFLOWER)
-- return -EOPNOTSUPP;
--
- mutex_lock(&mtk_flow_offload_mutex);
- switch (cls->command) {
- case FLOW_CLS_REPLACE:
-- err = mtk_flow_offload_replace(eth, cls);
-+ err = mtk_flow_offload_replace(eth, cls, ppe_index);
- break;
- case FLOW_CLS_DESTROY:
- err = mtk_flow_offload_destroy(eth, cls);
-@@ -558,6 +550,23 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_
- }
-
- static int
-+mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
-+{
-+ struct flow_cls_offload *cls = type_data;
-+ struct net_device *dev = cb_priv;
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+
-+ if (!tc_can_offload(dev))
-+ return -EOPNOTSUPP;
-+
-+ if (type != TC_SETUP_CLSFLOWER)
-+ return -EOPNOTSUPP;
-+
-+ return mtk_flow_offload_cmd(eth, cls, 0);
-+}
-+
-+static int
- mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
- {
- struct mtk_mac *mac = netdev_priv(dev);
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -13,6 +13,8 @@
- #include <linux/mfd/syscon.h>
- #include <linux/debugfs.h>
- #include <linux/soc/mediatek/mtk_wed.h>
-+#include <net/flow_offload.h>
-+#include <net/pkt_cls.h>
- #include "mtk_eth_soc.h"
- #include "mtk_wed_regs.h"
- #include "mtk_wed.h"
-@@ -41,6 +43,11 @@
- static struct mtk_wed_hw *hw_list[2];
- static DEFINE_MUTEX(hw_lock);
-
-+struct mtk_wed_flow_block_priv {
-+ struct mtk_wed_hw *hw;
-+ struct net_device *dev;
-+};
-+
- static void
- wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
- {
-@@ -1753,6 +1760,99 @@ out:
- mutex_unlock(&hw_lock);
- }
-
-+static int
-+mtk_wed_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
-+{
-+ struct mtk_wed_flow_block_priv *priv = cb_priv;
-+ struct flow_cls_offload *cls = type_data;
-+ struct mtk_wed_hw *hw = priv->hw;
-+
-+ if (!tc_can_offload(priv->dev))
-+ return -EOPNOTSUPP;
-+
-+ if (type != TC_SETUP_CLSFLOWER)
-+ return -EOPNOTSUPP;
-+
-+ return mtk_flow_offload_cmd(hw->eth, cls, hw->index);
-+}
-+
-+static int
-+mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev,
-+ struct flow_block_offload *f)
-+{
-+ struct mtk_wed_flow_block_priv *priv;
-+ static LIST_HEAD(block_cb_list);
-+ struct flow_block_cb *block_cb;
-+ struct mtk_eth *eth = hw->eth;
-+ flow_setup_cb_t *cb;
-+
-+ if (!eth->soc->offload_version)
-+ return -EOPNOTSUPP;
-+
-+ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
-+ return -EOPNOTSUPP;
-+
-+ cb = mtk_wed_setup_tc_block_cb;
-+ f->driver_block_list = &block_cb_list;
-+
-+ switch (f->command) {
-+ case FLOW_BLOCK_BIND:
-+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
-+ if (block_cb) {
-+ flow_block_cb_incref(block_cb);
-+ return 0;
-+ }
-+
-+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->hw = hw;
-+ priv->dev = dev;
-+ block_cb = flow_block_cb_alloc(cb, dev, priv, NULL);
-+ if (IS_ERR(block_cb)) {
-+ kfree(priv);
-+ return PTR_ERR(block_cb);
-+ }
-+
-+ flow_block_cb_incref(block_cb);
-+ flow_block_cb_add(block_cb, f);
-+ list_add_tail(&block_cb->driver_list, &block_cb_list);
-+ return 0;
-+ case FLOW_BLOCK_UNBIND:
-+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
-+ if (!block_cb)
-+ return -ENOENT;
-+
-+ if (!flow_block_cb_decref(block_cb)) {
-+ flow_block_cb_remove(block_cb, f);
-+ list_del(&block_cb->driver_list);
-+ kfree(block_cb->cb_priv);
-+ }
-+ return 0;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+static int
-+mtk_wed_setup_tc(struct mtk_wed_device *wed, struct net_device *dev,
-+ enum tc_setup_type type, void *type_data)
-+{
-+ struct mtk_wed_hw *hw = wed->hw;
-+
-+ if (hw->version < 2)
-+ return -EOPNOTSUPP;
-+
-+ switch (type) {
-+ case TC_SETUP_BLOCK:
-+ case TC_SETUP_FT:
-+ return mtk_wed_setup_tc_block(hw, dev, type_data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
- void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, phys_addr_t wdma_phy,
- int index)
-@@ -1772,6 +1872,7 @@ void mtk_wed_add_hw(struct device_node *
- .irq_set_mask = mtk_wed_irq_set_mask,
- .detach = mtk_wed_detach,
- .ppe_check = mtk_wed_ppe_check,
-+ .setup_tc = mtk_wed_setup_tc,
- };
- struct device_node *eth_np = eth->dev->of_node;
- struct platform_device *pdev;
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -6,6 +6,7 @@
- #include <linux/regmap.h>
- #include <linux/pci.h>
- #include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-
- #define MTK_WED_TX_QUEUES 2
- #define MTK_WED_RX_QUEUES 2
-@@ -180,6 +181,8 @@ struct mtk_wed_ops {
-
- u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
- void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
-+ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev,
-+ enum tc_setup_type type, void *type_data);
- };
-
- extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -238,6 +241,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
- (_dev)->ops->msg_update(_dev, _id, _msg, _len)
- #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
- #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
-+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \
-+ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data)
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -256,6 +261,7 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
- #define mtk_wed_device_stop(_dev) do {} while (0)
- #define mtk_wed_device_dma_reset(_dev) do {} while (0)
-+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch
deleted file mode 100644
index b1796641a3..0000000000
--- a/target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 20 Mar 2023 15:37:55 +0100
-Subject: [PATCH] net: ethernet: mediatek: mtk_ppe: prefer newly added l2
- flows over existing ones
-
-When a device is roaming between interfaces and a new flow entry is created,
-we should assume that its output device is more up to date than whatever
-entry existed already.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -656,10 +656,20 @@ void mtk_foe_entry_clear(struct mtk_ppe
- static int
- mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-+ struct mtk_flow_entry *prev;
-+
- entry->type = MTK_FLOW_TYPE_L2;
-
-- return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node,
-- mtk_flow_l2_ht_params);
-+ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &entry->l2_node,
-+ mtk_flow_l2_ht_params);
-+ if (likely(!prev))
-+ return 0;
-+
-+ if (IS_ERR(prev))
-+ return PTR_ERR(prev);
-+
-+ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node,
-+ &entry->l2_node, mtk_flow_l2_ht_params);
- }
-
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
diff --git a/target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch b/target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch
deleted file mode 100644
index 8b8a8e11c7..0000000000
--- a/target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch
+++ /dev/null
@@ -1,334 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 10:24:11 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: improve keeping track of
- offloaded flows
-
-Unify tracking of L2 and L3 flows. Use the generic list field in struct
-mtk_foe_entry for tracking L2 subflows. Preparation for improving
-flow accounting support.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------
- drivers/net/ethernet/mediatek/mtk_ppe.h | 15 +--
- 2 files changed, 86 insertions(+), 91 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -476,42 +476,43 @@ int mtk_foe_entry_set_queue(struct mtk_e
- return 0;
- }
-
-+static int
-+mtk_flow_entry_match_len(struct mtk_eth *eth, struct mtk_foe_entry *entry)
-+{
-+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1);
-+
-+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE)
-+ return offsetof(struct mtk_foe_entry, ipv6._rsv);
-+ else
-+ return offsetof(struct mtk_foe_entry, ipv4.ib2);
-+}
-+
- static bool
- mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry,
-- struct mtk_foe_entry *data)
-+ struct mtk_foe_entry *data, int len)
- {
-- int type, len;
--
- if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP)
- return false;
-
-- type = mtk_get_ib1_pkt_type(eth, entry->data.ib1);
-- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE)
-- len = offsetof(struct mtk_foe_entry, ipv6._rsv);
-- else
-- len = offsetof(struct mtk_foe_entry, ipv4.ib2);
--
- return !memcmp(&entry->data.data, &data->data, len - 4);
- }
-
- static void
--__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ bool set_state)
- {
-- struct hlist_head *head;
- struct hlist_node *tmp;
-
- if (entry->type == MTK_FLOW_TYPE_L2) {
- rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node,
- mtk_flow_l2_ht_params);
-
-- head = &entry->l2_flows;
-- hlist_for_each_entry_safe(entry, tmp, head, l2_data.list)
-- __mtk_foe_entry_clear(ppe, entry);
-+ hlist_for_each_entry_safe(entry, tmp, &entry->l2_flows, l2_list)
-+ __mtk_foe_entry_clear(ppe, entry, set_state);
- return;
- }
-
-- hlist_del_init(&entry->list);
-- if (entry->hash != 0xffff) {
-+ if (entry->hash != 0xffff && set_state) {
- struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
-
- hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-@@ -531,7 +532,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW)
- return;
-
-- hlist_del_init(&entry->l2_data.list);
-+ hlist_del_init(&entry->l2_list);
-+ hlist_del_init(&entry->list);
- kfree(entry);
- }
-
-@@ -547,66 +549,55 @@ static int __mtk_foe_entry_idle_time(str
- return now - timestamp;
- }
-
-+static bool
-+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+{
-+ struct mtk_foe_entry foe = {};
-+ struct mtk_foe_entry *hwe;
-+ u16 hash = entry->hash;
-+ int len;
-+
-+ if (hash == 0xffff)
-+ return false;
-+
-+ hwe = mtk_foe_get_entry(ppe, hash);
-+ len = mtk_flow_entry_match_len(ppe->eth, &entry->data);
-+ memcpy(&foe, hwe, len);
-+
-+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) ||
-+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND)
-+ return false;
-+
-+ entry->data.ib1 = foe.ib1;
-+
-+ return true;
-+}
-+
- static void
- mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth);
- struct mtk_flow_entry *cur;
-- struct mtk_foe_entry *hwe;
- struct hlist_node *tmp;
- int idle;
-
- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) {
-+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) {
- int cur_idle;
-- u32 ib1;
--
-- hwe = mtk_foe_get_entry(ppe, cur->hash);
-- ib1 = READ_ONCE(hwe->ib1);
-
-- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) {
-- cur->hash = 0xffff;
-- __mtk_foe_entry_clear(ppe, cur);
-+ if (!mtk_flow_entry_update(ppe, cur)) {
-+ __mtk_foe_entry_clear(ppe, entry, false);
- continue;
- }
-
-- cur_idle = __mtk_foe_entry_idle_time(ppe, ib1);
-+ cur_idle = __mtk_foe_entry_idle_time(ppe, cur->data.ib1);
- if (cur_idle >= idle)
- continue;
-
- idle = cur_idle;
- entry->data.ib1 &= ~ib1_ts_mask;
-- entry->data.ib1 |= hwe->ib1 & ib1_ts_mask;
-- }
--}
--
--static void
--mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
--{
-- struct mtk_foe_entry foe = {};
-- struct mtk_foe_entry *hwe;
--
-- spin_lock_bh(&ppe_lock);
--
-- if (entry->type == MTK_FLOW_TYPE_L2) {
-- mtk_flow_entry_update_l2(ppe, entry);
-- goto out;
-+ entry->data.ib1 |= cur->data.ib1 & ib1_ts_mask;
- }
--
-- if (entry->hash == 0xffff)
-- goto out;
--
-- hwe = mtk_foe_get_entry(ppe, entry->hash);
-- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size);
-- if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) {
-- entry->hash = 0xffff;
-- goto out;
-- }
--
-- entry->data.ib1 = foe.ib1;
--
--out:
-- spin_unlock_bh(&ppe_lock);
- }
-
- static void
-@@ -649,7 +640,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- spin_lock_bh(&ppe_lock);
-- __mtk_foe_entry_clear(ppe, entry);
-+ __mtk_foe_entry_clear(ppe, entry, true);
-+ hlist_del_init(&entry->list);
- spin_unlock_bh(&ppe_lock);
- }
-
-@@ -696,8 +688,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
- {
- const struct mtk_soc_data *soc = ppe->eth->soc;
- struct mtk_flow_entry *flow_info;
-- struct mtk_foe_entry foe = {}, *hwe;
- struct mtk_foe_mac_info *l2;
-+ struct mtk_foe_entry *hwe;
- u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP;
- int type;
-
-@@ -705,30 +697,30 @@ mtk_foe_entry_commit_subflow(struct mtk_
- if (!flow_info)
- return;
-
-- flow_info->l2_data.base_flow = entry;
- flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW;
- flow_info->hash = hash;
- hlist_add_head(&flow_info->list,
- &ppe->foe_flow[hash / soc->hash_offset]);
-- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
-+ hlist_add_head(&flow_info->l2_list, &entry->l2_flows);
-
- hwe = mtk_foe_get_entry(ppe, hash);
-- memcpy(&foe, hwe, soc->foe_entry_size);
-- foe.ib1 &= ib1_mask;
-- foe.ib1 |= entry->data.ib1 & ~ib1_mask;
-+ memcpy(&flow_info->data, hwe, soc->foe_entry_size);
-+ flow_info->data.ib1 &= ib1_mask;
-+ flow_info->data.ib1 |= entry->data.ib1 & ~ib1_mask;
-
-- l2 = mtk_foe_entry_l2(ppe->eth, &foe);
-+ l2 = mtk_foe_entry_l2(ppe->eth, &flow_info->data);
- memcpy(l2, &entry->data.bridge.l2, sizeof(*l2));
-
-- type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1);
-+ type = mtk_get_ib1_pkt_type(ppe->eth, flow_info->data.ib1);
- if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT)
-- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new));
-+ memcpy(&flow_info->data.ipv4.new, &flow_info->data.ipv4.orig,
-+ sizeof(flow_info->data.ipv4.new));
- else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP)
- l2->etype = ETH_P_IPV6;
-
-- *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2;
-+ *mtk_foe_entry_ib2(ppe->eth, &flow_info->data) = entry->data.bridge.ib2;
-
-- __mtk_foe_entry_commit(ppe, &foe, hash);
-+ __mtk_foe_entry_commit(ppe, &flow_info->data, hash);
- }
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
-@@ -738,9 +730,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash);
- struct mtk_flow_entry *entry;
- struct mtk_foe_bridge key = {};
-+ struct mtk_foe_entry foe = {};
- struct hlist_node *n;
- struct ethhdr *eh;
- bool found = false;
-+ int entry_len;
- u8 *tag;
-
- spin_lock_bh(&ppe_lock);
-@@ -748,20 +742,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND)
- goto out;
-
-- hlist_for_each_entry_safe(entry, n, head, list) {
-- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) {
-- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) ==
-- MTK_FOE_STATE_BIND))
-- continue;
--
-- entry->hash = 0xffff;
-- __mtk_foe_entry_clear(ppe, entry);
-- continue;
-- }
-+ entry_len = mtk_flow_entry_match_len(ppe->eth, hwe);
-+ memcpy(&foe, hwe, entry_len);
-
-- if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) {
-+ hlist_for_each_entry_safe(entry, n, head, list) {
-+ if (found ||
-+ !mtk_flow_entry_match(ppe->eth, entry, &foe, entry_len)) {
- if (entry->hash != 0xffff)
-- entry->hash = 0xffff;
-+ __mtk_foe_entry_clear(ppe, entry, false);
- continue;
- }
-
-@@ -810,9 +798,17 @@ out:
-
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
-- mtk_flow_entry_update(ppe, entry);
-+ int idle;
-+
-+ spin_lock_bh(&ppe_lock);
-+ if (entry->type == MTK_FLOW_TYPE_L2)
-+ mtk_flow_entry_update_l2(ppe, entry);
-+ else
-+ mtk_flow_entry_update(ppe, entry);
-+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-+ spin_unlock_bh(&ppe_lock);
-
-- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-+ return idle;
- }
-
- int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -286,7 +286,12 @@ enum {
-
- struct mtk_flow_entry {
- union {
-- struct hlist_node list;
-+ /* regular flows + L2 subflows */
-+ struct {
-+ struct hlist_node list;
-+ struct hlist_node l2_list;
-+ };
-+ /* L2 flows */
- struct {
- struct rhash_head l2_node;
- struct hlist_head l2_flows;
-@@ -296,13 +301,7 @@ struct mtk_flow_entry {
- s8 wed_index;
- u8 ppe_index;
- u16 hash;
-- union {
-- struct mtk_foe_entry data;
-- struct {
-- struct mtk_flow_entry *base_flow;
-- struct hlist_node list;
-- } l2_data;
-- };
-+ struct mtk_foe_entry data;
- struct rhash_head node;
- unsigned long cookie;
- };
diff --git a/target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch b/target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch
deleted file mode 100644
index e20f94f1d4..0000000000
--- a/target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch
+++ /dev/null
@@ -1,342 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 11:05:22 +0100
-Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for L2
- flows
-
-For L2 flows, the packet/byte counters should report the sum of the
-counters of their subflows, both current and expired.
-In order to make this work, change the way that accounting data is tracked.
-Reset counters when a flow enters bind. Once it expires (or enters unbind),
-store the last counter value in struct mtk_flow_entry.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -79,9 +79,9 @@ static int mtk_ppe_mib_wait_busy(struct
- int ret;
- u32 val;
-
-- ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
-- !(val & MTK_PPE_MIB_SER_CR_ST),
-- 20, MTK_PPE_WAIT_TIMEOUT_US);
-+ ret = readl_poll_timeout_atomic(ppe->base + MTK_PPE_MIB_SER_CR, val,
-+ !(val & MTK_PPE_MIB_SER_CR_ST),
-+ 20, MTK_PPE_WAIT_TIMEOUT_US);
-
- if (ret)
- dev_err(ppe->dev, "MIB table busy");
-@@ -89,17 +89,31 @@ static int mtk_ppe_mib_wait_busy(struct
- return ret;
- }
-
--static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
-+static inline struct mtk_foe_accounting *
-+mtk_ppe_acct_data(struct mtk_ppe *ppe, u16 index)
-+{
-+ if (!ppe->acct_table)
-+ return NULL;
-+
-+ return ppe->acct_table + index * sizeof(struct mtk_foe_accounting);
-+}
-+
-+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index)
- {
- u32 val, cnt_r0, cnt_r1, cnt_r2;
-+ struct mtk_foe_accounting *acct;
- int ret;
-
- val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
- ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
-
-+ acct = mtk_ppe_acct_data(ppe, index);
-+ if (!acct)
-+ return NULL;
-+
- ret = mtk_ppe_mib_wait_busy(ppe);
- if (ret)
-- return ret;
-+ return acct;
-
- cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
- cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-@@ -108,19 +122,19 @@ static int mtk_mib_entry_read(struct mtk
- if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
- /* 64 bit for each counter */
- u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
-- *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
-- *packets = ((u64)cnt_r3 << 32) | cnt_r2;
-+ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0;
-+ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2;
- } else {
- /* 48 bit byte counter, 40 bit packet counter */
- u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
- u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
- u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
- u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-- *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low;
- }
-
-- return 0;
-+ return acct;
- }
-
- static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
-@@ -519,13 +533,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
- dma_wmb();
- mtk_ppe_cache_clear(ppe);
-- if (ppe->accounting) {
-- struct mtk_foe_accounting *acct;
--
-- acct = ppe->acct_table + entry->hash * sizeof(*acct);
-- acct->packets = 0;
-- acct->bytes = 0;
-- }
- }
- entry->hash = 0xffff;
-
-@@ -550,11 +557,14 @@ static int __mtk_foe_entry_idle_time(str
- }
-
- static bool
--mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
-+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ u64 *packets, u64 *bytes)
- {
-+ struct mtk_foe_accounting *acct;
- struct mtk_foe_entry foe = {};
- struct mtk_foe_entry *hwe;
- u16 hash = entry->hash;
-+ bool ret = false;
- int len;
-
- if (hash == 0xffff)
-@@ -565,18 +575,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp
- memcpy(&foe, hwe, len);
-
- if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) ||
-- FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND)
-- return false;
-+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) {
-+ acct = mtk_ppe_acct_data(ppe, hash);
-+ if (acct) {
-+ entry->prev_packets += acct->packets;
-+ entry->prev_bytes += acct->bytes;
-+ }
-+
-+ goto out;
-+ }
-
- entry->data.ib1 = foe.ib1;
-+ acct = mtk_ppe_mib_entry_read(ppe, hash);
-+ ret = true;
-+
-+out:
-+ if (acct) {
-+ *packets += acct->packets;
-+ *bytes += acct->bytes;
-+ }
-
-- return true;
-+ return ret;
- }
-
- static void
- mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- {
- u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth);
-+ u64 *packets = &entry->packets;
-+ u64 *bytes = &entry->bytes;
- struct mtk_flow_entry *cur;
- struct hlist_node *tmp;
- int idle;
-@@ -585,7 +612,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe
- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) {
- int cur_idle;
-
-- if (!mtk_flow_entry_update(ppe, cur)) {
-+ if (!mtk_flow_entry_update(ppe, cur, packets, bytes)) {
-+ entry->prev_packets += cur->prev_packets;
-+ entry->prev_bytes += cur->prev_bytes;
- __mtk_foe_entry_clear(ppe, entry, false);
- continue;
- }
-@@ -600,10 +629,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe
- }
- }
-
-+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ int *idle)
-+{
-+ entry->packets = entry->prev_packets;
-+ entry->bytes = entry->prev_bytes;
-+
-+ spin_lock_bh(&ppe_lock);
-+
-+ if (entry->type == MTK_FLOW_TYPE_L2)
-+ mtk_flow_entry_update_l2(ppe, entry);
-+ else
-+ mtk_flow_entry_update(ppe, entry, &entry->packets, &entry->bytes);
-+
-+ *idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-+
-+ spin_unlock_bh(&ppe_lock);
-+}
-+
- static void
- __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
- u16 hash)
- {
-+ struct mtk_foe_accounting *acct;
- struct mtk_eth *eth = ppe->eth;
- u16 timestamp = mtk_eth_timestamp(eth);
- struct mtk_foe_entry *hwe;
-@@ -634,6 +682,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-
- dma_wmb();
-
-+ acct = mtk_ppe_mib_entry_read(ppe, hash);
-+ if (acct) {
-+ acct->packets = 0;
-+ acct->bytes = 0;
-+ }
-+
- mtk_ppe_cache_clear(ppe);
- }
-
-@@ -796,21 +850,6 @@ out:
- spin_unlock_bh(&ppe_lock);
- }
-
--int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
--{
-- int idle;
--
-- spin_lock_bh(&ppe_lock);
-- if (entry->type == MTK_FLOW_TYPE_L2)
-- mtk_flow_entry_update_l2(ppe, entry);
-- else
-- mtk_flow_entry_update(ppe, entry);
-- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
-- spin_unlock_bh(&ppe_lock);
--
-- return idle;
--}
--
- int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
- {
- if (!ppe)
-@@ -838,32 +877,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
- return mtk_ppe_wait_busy(ppe);
- }
-
--struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-- struct mtk_foe_accounting *diff)
--{
-- struct mtk_foe_accounting *acct;
-- int size = sizeof(struct mtk_foe_accounting);
-- u64 bytes, packets;
--
-- if (!ppe->accounting)
-- return NULL;
--
-- if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
-- return NULL;
--
-- acct = ppe->acct_table + index * size;
--
-- acct->bytes += bytes;
-- acct->packets += packets;
--
-- if (diff) {
-- diff->bytes = bytes;
-- diff->packets = packets;
-- }
--
-- return acct;
--}
--
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
- {
- bool accounting = eth->soc->has_accounting;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -304,6 +304,8 @@ struct mtk_flow_entry {
- struct mtk_foe_entry data;
- struct rhash_head node;
- unsigned long cookie;
-+ u64 prev_packets, prev_bytes;
-+ u64 packets, bytes;
- };
-
- struct mtk_mib_entry {
-@@ -348,6 +350,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth)
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
- int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
-+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index);
-
- void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
-
-@@ -396,9 +399,8 @@ int mtk_foe_entry_set_queue(struct mtk_e
- unsigned int queue);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
--int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
--struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-- struct mtk_foe_accounting *diff);
-+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
-+ int *idle);
-
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -96,7 +96,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
- if (bind && state != MTK_FOE_STATE_BIND)
- continue;
-
-- acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-+ acct = mtk_ppe_mib_entry_read(ppe, i);
-
- type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
- seq_printf(m, "%05x %s %7s", i,
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -501,24 +501,21 @@ static int
- mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
- {
- struct mtk_flow_entry *entry;
-- struct mtk_foe_accounting diff;
-- u32 idle;
-+ u64 packets, bytes;
-+ int idle;
-
- entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
- mtk_flow_ht_params);
- if (!entry)
- return -ENOENT;
-
-- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
-+ packets = entry->packets;
-+ bytes = entry->bytes;
-+ mtk_foe_entry_get_stats(eth->ppe[entry->ppe_index], entry, &idle);
-+ f->stats.pkts += entry->packets - packets;
-+ f->stats.bytes += entry->bytes - bytes;
- f->stats.lastused = jiffies - idle * HZ;
-
-- if (entry->hash != 0xFFFF &&
-- mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
-- &diff)) {
-- f->stats.pkts += diff.packets;
-- f->stats.bytes += diff.bytes;
-- }
--
- return 0;
- }
-
diff --git a/target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch b/target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch
deleted file mode 100644
index a224b62624..0000000000
--- a/target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sun, 27 Aug 2023 19:31:41 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: add some more info in wed_txinfo_show
- handler
-
-Add some new info in Wireless Ethernet Dispatcher wed_txinfo_show
-debugfs handler useful during debugging.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/3390292655d568180b73d2a25576f61aa63310e5.1693157377.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -127,8 +127,17 @@ wed_txinfo_show(struct seq_file *s, void
- DUMP_WDMA_RING(WDMA_RING_RX(0)),
- DUMP_WDMA_RING(WDMA_RING_RX(1)),
-
-- DUMP_STR("TX FREE"),
-+ DUMP_STR("WED TX FREE"),
- DUMP_WED(WED_RX_MIB(0)),
-+ DUMP_WED_RING(WED_RING_RX(0)),
-+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)),
-+ DUMP_WED(WED_RX_MIB(1)),
-+ DUMP_WED_RING(WED_RING_RX(1)),
-+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)),
-+
-+ DUMP_STR("WED WPDMA TX FREE"),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX(0)),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX(1)),
- };
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -266,6 +266,8 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4)
- #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_MIB(_n) (0x5e0 + (_n) * 4)
-+#define MTK_WED_WPDMA_RX_COHERENT_MIB(_n) (0x5f0 + (_n) * 4)
-
- #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10)
- #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10)
diff --git a/target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch b/target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch
deleted file mode 100644
index df6edfdf94..0000000000
--- a/target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sun, 27 Aug 2023 19:33:47 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: minor change in wed_{tx,rx}info_show
-
-No functional changes, just cosmetic ones.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/71e046c72a978745f0435af265dda610aa9bfbcf.1693157578.git.lorenzo@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -84,7 +84,6 @@ dump_wed_regs(struct seq_file *s, struct
- }
- }
-
--
- static int
- wed_txinfo_show(struct seq_file *s, void *data)
- {
-@@ -142,10 +141,8 @@ wed_txinfo_show(struct seq_file *s, void
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
-- if (!dev)
-- return 0;
--
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-
- return 0;
- }
-@@ -217,10 +214,8 @@ wed_rxinfo_show(struct seq_file *s, void
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
-- if (!dev)
-- return 0;
--
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-
- return 0;
- }
diff --git a/target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch b/target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch
deleted file mode 100644
index 0bf9dea24f..0000000000
--- a/target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Sep 2023 10:22:56 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on mtk_pse_port definitions
- in mtk_flow_set_output_device
-
-Similar to ethernet ports, rely on mtk_pse_port definitions for
-pse wdma ports as well.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/b86bdb717e963e3246c1dec5f736c810703cf056.1694506814.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -196,10 +196,10 @@ mtk_flow_set_output_device(struct mtk_et
- if (mtk_is_netsys_v2_or_greater(eth)) {
- switch (info.wdma_idx) {
- case 0:
-- pse_port = 8;
-+ pse_port = PSE_WDMA0_PORT;
- break;
- case 1:
-- pse_port = 9;
-+ pse_port = PSE_WDMA1_PORT;
- break;
- default:
- return -EINVAL;
diff --git a/target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch b/target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
deleted file mode 100644
index c99e1334d4..0000000000
--- a/target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Sep 2023 10:28:00 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: check update_wo_rx_stats in
- mtk_wed_update_rx_stats()
-
-Check if update_wo_rx_stats function pointer is properly set in
-mtk_wed_update_rx_stats routine before accessing it.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/b0d233386e059bccb59f18f69afb79a7806e5ded.1694507226.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -68,6 +68,9 @@ mtk_wed_update_rx_stats(struct mtk_wed_d
- struct mtk_wed_wo_rx_stats *stats;
- int i;
-
-+ if (!wed->wlan.update_wo_rx_stats)
-+ return;
-+
- if (count * sizeof(*stats) > skb->len - sizeof(u32))
- return;
-
diff --git a/target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch b/target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch
deleted file mode 100644
index cd7fb92e20..0000000000
--- a/target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 13 Sep 2023 20:42:47 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: do not assume offload callbacks are
- always set
-
-Check if wlan.offload_enable and wlan.offload_disable callbacks are set
-in mtk_wed_flow_add/mtk_wed_flow_remove since mt7996 will not rely
-on them.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1712,19 +1712,20 @@ mtk_wed_irq_set_mask(struct mtk_wed_devi
- int mtk_wed_flow_add(int index)
- {
- struct mtk_wed_hw *hw = hw_list[index];
-- int ret;
-+ int ret = 0;
-
-- if (!hw || !hw->wed_dev)
-- return -ENODEV;
-+ mutex_lock(&hw_lock);
-
-- if (hw->num_flows) {
-- hw->num_flows++;
-- return 0;
-+ if (!hw || !hw->wed_dev) {
-+ ret = -ENODEV;
-+ goto out;
- }
-
-- mutex_lock(&hw_lock);
-- if (!hw->wed_dev) {
-- ret = -ENODEV;
-+ if (!hw->wed_dev->wlan.offload_enable)
-+ goto out;
-+
-+ if (hw->num_flows) {
-+ hw->num_flows++;
- goto out;
- }
-
-@@ -1743,14 +1744,15 @@ void mtk_wed_flow_remove(int index)
- {
- struct mtk_wed_hw *hw = hw_list[index];
-
-- if (!hw)
-- return;
-+ mutex_lock(&hw_lock);
-
-- if (--hw->num_flows)
-- return;
-+ if (!hw || !hw->wed_dev)
-+ goto out;
-
-- mutex_lock(&hw_lock);
-- if (!hw->wed_dev)
-+ if (!hw->wed_dev->wlan.offload_disable)
-+ goto out;
-+
-+ if (--hw->num_flows)
- goto out;
-
- hw->wed_dev->wlan.offload_disable(hw->wed_dev);
diff --git a/target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch b/target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
deleted file mode 100644
index 2948188650..0000000000
--- a/target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
+++ /dev/null
@@ -1,232 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:05 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce versioning utility routines
-
-Similar to mtk_eth_soc, introduce the following wed versioning
-utility routines:
-- mtk_wed_is_v1
-- mtk_wed_is_v2
-
-This is a preliminary patch to introduce WED support for MT7988 SoC
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -277,7 +277,7 @@ mtk_wed_assign(struct mtk_wed_device *de
- if (!hw->wed_dev)
- goto out;
-
-- if (hw->version == 1)
-+ if (mtk_wed_is_v1(hw))
- return NULL;
-
- /* MT7986 WED devices do not have any pcie slot restrictions */
-@@ -358,7 +358,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- desc->buf0 = cpu_to_le32(buf_phys);
- desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
- MTK_WED_BUF_SIZE - txd_size) |
-@@ -497,7 +497,7 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- {
- u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
- else
- mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-@@ -576,7 +576,7 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
- wdma_clr(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return;
-
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
-@@ -624,7 +624,7 @@ mtk_wed_deinit(struct mtk_wed_device *de
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return;
-
- wed_clr(dev, MTK_WED_CTRL,
-@@ -730,7 +730,7 @@ mtk_wed_bus_init(struct mtk_wed_device *
- static void
- mtk_wed_set_wpdma(struct mtk_wed_device *dev)
- {
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
- } else {
- mtk_wed_bus_init(dev);
-@@ -761,7 +761,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
- wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- u32 offset = dev->hw->index ? 0x04000400 : 0;
-
- wdma_set(dev, MTK_WDMA_GLO_CFG,
-@@ -934,7 +934,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_TX_BM_TKID,
- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
- dev->wlan.token_start) |
-@@ -967,7 +967,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-@@ -1217,7 +1217,7 @@ mtk_wed_reset_dma(struct mtk_wed_device
- }
-
- dev->init_done = false;
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return;
-
- if (!busy) {
-@@ -1343,7 +1343,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
- MTK_WED_PCIE_INT_TRIGGER_STATUS);
-
-@@ -1416,7 +1416,7 @@ mtk_wed_dma_enable(struct mtk_wed_device
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
-@@ -1465,7 +1465,7 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- mtk_wed_set_ext_int(dev, true);
-
-- if (dev->hw->version == 1) {
-+ if (mtk_wed_is_v1(dev->hw)) {
- u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN |
- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID,
- dev->hw->index);
-@@ -1550,7 +1550,7 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (hw->version == 1) {
-+ if (mtk_wed_is_v1(hw)) {
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
- } else {
-@@ -1618,7 +1618,7 @@ static int
- mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
- {
- struct mtk_wed_ring *ring = &dev->txfree_ring;
-- int i, index = dev->hw->version == 1;
-+ int i, index = mtk_wed_is_v1(dev->hw);
-
- /*
- * For txfree event handling, the same DMA ring is shared between WED
-@@ -1676,7 +1676,7 @@ mtk_wed_irq_get(struct mtk_wed_device *d
- {
- u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
- else
- ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-@@ -1843,7 +1843,7 @@ mtk_wed_setup_tc(struct mtk_wed_device *
- {
- struct mtk_wed_hw *hw = wed->hw;
-
-- if (hw->version < 2)
-+ if (mtk_wed_is_v1(hw))
- return -EOPNOTSUPP;
-
- switch (type) {
-@@ -1917,9 +1917,9 @@ void mtk_wed_add_hw(struct device_node *
- hw->wdma = wdma;
- hw->index = index;
- hw->irq = irq;
-- hw->version = mtk_is_netsys_v1(eth) ? 1 : 2;
-+ hw->version = eth->soc->version;
-
-- if (hw->version == 1) {
-+ if (mtk_wed_is_v1(hw)) {
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
- "mediatek,pcie-mirror");
- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -40,6 +40,16 @@ struct mtk_wdma_info {
- };
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static inline bool mtk_wed_is_v1(struct mtk_wed_hw *hw)
-+{
-+ return hw->version == 1;
-+}
-+
-+static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw)
-+{
-+ return hw->version == 2;
-+}
-+
- static inline void
- wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
- {
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -263,7 +263,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w
- debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
- debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
- debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-- if (hw->version != 1)
-+ if (!mtk_wed_is_v1(hw))
- debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
- &wed_rxinfo_fops);
- }
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- {
- struct mtk_wed_wo *wo = dev->hw->wed_wo;
-
-- if (dev->hw->version == 1)
-+ if (mtk_wed_is_v1(dev->hw))
- return 0;
-
- if (WARN_ON(!wo))
diff --git a/target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch b/target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch
deleted file mode 100644
index bc34aa33a9..0000000000
--- a/target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:06 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: do not configure rx offload if not
- supported
-
-Check if rx offload is supported running mtk_wed_get_rx_capa routine
-before configuring it. This is a preliminary patch to introduce Wireless
-Ethernet Dispatcher (WED) support for MT7988 SoC.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-
-- if (mtk_wed_is_v1(dev->hw))
-+ if (!mtk_wed_get_rx_capa(dev))
- return;
-
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
-@@ -732,16 +732,21 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- {
- if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
-- } else {
-- mtk_wed_bus_init(dev);
--
-- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
-+ return;
- }
-+
-+ mtk_wed_bus_init(dev);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-+
-+ if (!mtk_wed_get_rx_capa(dev))
-+ return;
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
- }
-
- static void
-@@ -973,15 +978,17 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
- } else {
- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
-- /* rx hw init */
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-- MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-- MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
--
-- mtk_wed_rx_buffer_hw_init(dev);
-- mtk_wed_rro_hw_init(dev);
-- mtk_wed_route_qm_hw_init(dev);
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ /* rx hw init */
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+
-+ mtk_wed_rx_buffer_hw_init(dev);
-+ mtk_wed_rro_hw_init(dev);
-+ mtk_wed_route_qm_hw_init(dev);
-+ }
- }
-
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
-@@ -1353,8 +1360,6 @@ mtk_wed_configure_irq(struct mtk_wed_dev
-
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
-- wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
-- GENMASK(1, 0));
- /* initail tx interrupt trigger */
- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
- MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-@@ -1373,15 +1378,20 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
- dev->wlan.txfree_tbit));
-
-- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-- MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-- MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-- MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-- MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-- dev->wlan.rx_tbit[0]) |
-- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-- dev->wlan.rx_tbit[1]));
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-+ dev->wlan.rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-+ dev->wlan.rx_tbit[1]));
-+
-+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
-+ GENMASK(1, 0));
-+ }
-
- wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
- wed_set(dev, MTK_WED_WDMA_INT_CTRL,
-@@ -1400,6 +1410,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- static void
- mtk_wed_dma_enable(struct mtk_wed_device *dev)
- {
-+ int i;
-+
- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-
- wed_set(dev, MTK_WED_GLO_CFG,
-@@ -1419,33 +1431,33 @@ mtk_wed_dma_enable(struct mtk_wed_device
- if (mtk_wed_is_v1(dev->hw)) {
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
-- } else {
-- int i;
-+ return;
-+ }
-
-- wed_set(dev, MTK_WED_WPDMA_CTRL,
-- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-+ wed_set(dev, MTK_WED_WPDMA_CTRL,
-+ MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
-+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-
-- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+ if (!mtk_wed_get_rx_capa(dev))
-+ return;
-
-- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
--
-- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
-- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-
-- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-- MTK_WED_WPDMA_RX_D_RX_DRV_EN |
-- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-- 0x2));
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-+ 0x2));
-
-- for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-- mtk_wed_check_wfdma_rx_fill(dev, i);
-- }
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-+ mtk_wed_check_wfdma_rx_fill(dev, i);
- }
-
- static void
-@@ -1472,7 +1484,7 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- val |= BIT(0) | (BIT(1) * !!dev->hw->index);
- regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
-- } else {
-+ } else if (mtk_wed_get_rx_capa(dev)) {
- /* driver set mid ready and only once */
- wed_w32(dev, MTK_WED_EXT_INT_MASK1,
- MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-@@ -1484,7 +1496,6 @@ mtk_wed_start(struct mtk_wed_device *dev
-
- if (mtk_wed_rro_cfg(dev))
- return;
--
- }
-
- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-@@ -1550,13 +1561,14 @@ mtk_wed_attach(struct mtk_wed_device *de
- }
-
- mtk_wed_hw_init_early(dev);
-- if (mtk_wed_is_v1(hw)) {
-+ if (mtk_wed_is_v1(hw))
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
-- } else {
-+ else
- dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
-+
-+ if (mtk_wed_get_rx_capa(dev))
- ret = mtk_wed_wo_init(hw);
-- }
- out:
- if (ret) {
- dev_err(dev->hw->dev, "failed to attach wed device\n");
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- {
- struct mtk_wed_wo *wo = dev->hw->wed_wo;
-
-- if (mtk_wed_is_v1(dev->hw))
-+ if (!mtk_wed_get_rx_capa(dev))
- return 0;
-
- if (WARN_ON(!wo))
diff --git a/target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch b/target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch
deleted file mode 100644
index d83434fb2c..0000000000
--- a/target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:07 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: rename mtk_rxbm_desc in
- mtk_wed_bm_desc
-
-Rename mtk_rxbm_desc structure in mtk_wed_bm_desc since it will be used
-even on tx side by MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -421,7 +421,7 @@ free_pagelist:
- static int
- mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
- {
-- struct mtk_rxbm_desc *desc;
-+ struct mtk_wed_bm_desc *desc;
- dma_addr_t desc_phys;
-
- dev->rx_buf_ring.size = dev->wlan.rx_nbuf;
-@@ -441,7 +441,7 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d
- static void
- mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
- {
-- struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
-+ struct mtk_wed_bm_desc *desc = dev->rx_buf_ring.desc;
-
- if (!desc)
- return;
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -45,7 +45,7 @@ enum mtk_wed_wo_cmd {
- MTK_WED_WO_CMD_WED_END
- };
-
--struct mtk_rxbm_desc {
-+struct mtk_wed_bm_desc {
- __le32 buf0;
- __le32 token;
- } __packed __aligned(4);
-@@ -105,7 +105,7 @@ struct mtk_wed_device {
- struct {
- int size;
- struct page_frag_cache rx_page;
-- struct mtk_rxbm_desc *desc;
-+ struct mtk_wed_bm_desc *desc;
- dma_addr_t desc_phys;
- } rx_buf_ring;
-
diff --git a/target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch b/target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch
deleted file mode 100644
index 8000a8759e..0000000000
--- a/target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:08 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce mtk_wed_buf structure
-
-Introduce mtk_wed_buf structure to store both virtual and physical
-addresses allocated in mtk_wed_tx_buffer_alloc() routine. This is a
-preliminary patch to add WED support for MT7988 SoC since it relies on a
-different dma descriptor layout not storing page dma addresses.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -299,9 +299,9 @@ out:
- static int
- mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
-+ struct mtk_wed_buf *page_list;
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-- void **page_list;
- int token = dev->wlan.token_start;
- int ring_size;
- int n_pages;
-@@ -342,7 +342,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- return -ENOMEM;
- }
-
-- page_list[page_idx++] = page;
-+ page_list[page_idx].p = page;
-+ page_list[page_idx++].phy_addr = page_phys;
- dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
-
-@@ -386,8 +387,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- static void
- mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
- {
-+ struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages;
- struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
-- void **page_list = dev->tx_buf_ring.pages;
- int page_idx;
- int i;
-
-@@ -399,13 +400,12 @@ mtk_wed_free_tx_buffer(struct mtk_wed_de
-
- for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size;
- i += MTK_WED_BUF_PER_PAGE) {
-- void *page = page_list[page_idx++];
-- dma_addr_t buf_addr;
-+ dma_addr_t buf_addr = page_list[page_idx].phy_addr;
-+ void *page = page_list[page_idx++].p;
-
- if (!page)
- break;
-
-- buf_addr = le32_to_cpu(desc[i].buf0);
- dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- __free_page(page);
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -76,6 +76,11 @@ struct mtk_wed_wo_rx_stats {
- __le32 rx_drop_cnt;
- };
-
-+struct mtk_wed_buf {
-+ void *p;
-+ dma_addr_t phy_addr;
-+};
-+
- struct mtk_wed_device {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- const struct mtk_wed_ops *ops;
-@@ -97,7 +102,7 @@ struct mtk_wed_device {
-
- struct {
- int size;
-- void **pages;
-+ struct mtk_wed_buf *pages;
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
- } tx_buf_ring;
diff --git a/target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch b/target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch
deleted file mode 100644
index 98d782b1d0..0000000000
--- a/target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:09 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: move mem_region array out of
- mtk_wed_mcu_load_firmware
-
-Remove mtk_wed_wo_memory_region boot structure in mtk_wed_wo.
-This is a preliminary patch to introduce WED support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -16,14 +16,30 @@
- #include "mtk_wed_wo.h"
- #include "mtk_wed.h"
-
-+static struct mtk_wed_wo_memory_region mem_region[] = {
-+ [MTK_WED_WO_REGION_EMI] = {
-+ .name = "wo-emi",
-+ },
-+ [MTK_WED_WO_REGION_ILM] = {
-+ .name = "wo-ilm",
-+ },
-+ [MTK_WED_WO_REGION_DATA] = {
-+ .name = "wo-data",
-+ .shared = true,
-+ },
-+ [MTK_WED_WO_REGION_BOOT] = {
-+ .name = "wo-boot",
-+ },
-+};
-+
- static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
- {
-- return readl(wo->boot.addr + reg);
-+ return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
- }
-
- static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
- {
-- writel(val, wo->boot.addr + reg);
-+ writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
- }
-
- static struct sk_buff *
-@@ -294,18 +310,6 @@ next:
- static int
- mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
- {
-- static struct mtk_wed_wo_memory_region mem_region[] = {
-- [MTK_WED_WO_REGION_EMI] = {
-- .name = "wo-emi",
-- },
-- [MTK_WED_WO_REGION_ILM] = {
-- .name = "wo-ilm",
-- },
-- [MTK_WED_WO_REGION_DATA] = {
-- .name = "wo-data",
-- .shared = true,
-- },
-- };
- const struct mtk_wed_fw_trailer *trailer;
- const struct firmware *fw;
- const char *fw_name;
-@@ -319,11 +323,6 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- return ret;
- }
-
-- wo->boot.name = "wo-boot";
-- ret = mtk_wed_get_memory_region(wo, &wo->boot);
-- if (ret)
-- return ret;
--
- /* set dummy cr */
- wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL,
- wo->hw->index + 1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -228,7 +228,6 @@ struct mtk_wed_wo_queue {
-
- struct mtk_wed_wo {
- struct mtk_wed_hw *hw;
-- struct mtk_wed_wo_memory_region boot;
-
- struct mtk_wed_wo_queue q_tx;
- struct mtk_wed_wo_queue q_rx;
diff --git a/target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch b/target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch
deleted file mode 100644
index 48b0d02049..0000000000
--- a/target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:10 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: make memory region optional
-
-Make mtk_wed_wo_memory_region optionals.
-This is a preliminary patch to introduce Wireless Ethernet Dispatcher
-support for MT7988 SoC since MT7988 WED fw image will have a different
-layout.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -234,19 +234,13 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- }
-
- static int
--mtk_wed_get_memory_region(struct mtk_wed_wo *wo,
-+mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index,
- struct mtk_wed_wo_memory_region *region)
- {
- struct reserved_mem *rmem;
- struct device_node *np;
-- int index;
-
-- index = of_property_match_string(wo->hw->node, "memory-region-names",
-- region->name);
-- if (index < 0)
-- return index;
--
-- np = of_parse_phandle(wo->hw->node, "memory-region", index);
-+ np = of_parse_phandle(hw->node, "memory-region", index);
- if (!np)
- return -ENODEV;
-
-@@ -258,7 +252,7 @@ mtk_wed_get_memory_region(struct mtk_wed
-
- region->phy_addr = rmem->base;
- region->size = rmem->size;
-- region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size);
-+ region->addr = devm_ioremap(hw->dev, region->phy_addr, region->size);
-
- return !region->addr ? -EINVAL : 0;
- }
-@@ -271,6 +265,9 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_
- const struct mtk_wed_fw_trailer *trailer;
- const struct mtk_wed_fw_region *fw_region;
-
-+ if (!region->phy_addr || !region->size)
-+ return 0;
-+
- trailer_ptr = fw->data + fw->size - sizeof(*trailer);
- trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr;
- region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region);
-@@ -318,7 +315,13 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
-
- /* load firmware region metadata */
- for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
-- ret = mtk_wed_get_memory_region(wo, &mem_region[i]);
-+ int index = of_property_match_string(wo->hw->node,
-+ "memory-region-names",
-+ mem_region[i].name);
-+ if (index < 0)
-+ continue;
-+
-+ ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]);
- if (ret)
- return ret;
- }
diff --git a/target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch b/target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
deleted file mode 100644
index c43114fb5b..0000000000
--- a/target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:12 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_soc_data structure
-
-Introduce mtk_wed_soc_data utility structure to contain per-SoC
-definitions.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -48,6 +48,26 @@ struct mtk_wed_flow_block_priv {
- struct net_device *dev;
- };
-
-+static const struct mtk_wed_soc_data mt7622_data = {
-+ .regmap = {
-+ .tx_bm_tkid = 0x088,
-+ .wpdma_rx_ring0 = 0x770,
-+ .reset_idx_tx_mask = GENMASK(3, 0),
-+ .reset_idx_rx_mask = GENMASK(17, 16),
-+ },
-+ .wdma_desc_size = sizeof(struct mtk_wdma_desc),
-+};
-+
-+static const struct mtk_wed_soc_data mt7986_data = {
-+ .regmap = {
-+ .tx_bm_tkid = 0x0c8,
-+ .wpdma_rx_ring0 = 0x770,
-+ .reset_idx_tx_mask = GENMASK(1, 0),
-+ .reset_idx_rx_mask = GENMASK(7, 6),
-+ },
-+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
-+};
-+
- static void
- wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
- {
-@@ -746,7 +766,7 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- return;
-
- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
-+ wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx);
- }
-
- static void
-@@ -940,22 +960,10 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
- if (mtk_wed_is_v1(dev->hw)) {
-- wed_w32(dev, MTK_WED_TX_BM_TKID,
-- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-- dev->wlan.token_start) |
-- FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-- dev->wlan.token_start +
-- dev->wlan.nbuf - 1));
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
- MTK_WED_TX_BM_DYN_THR_HI);
- } else {
-- wed_w32(dev, MTK_WED_TX_BM_TKID_V2,
-- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-- dev->wlan.token_start) |
-- FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-- dev->wlan.token_start +
-- dev->wlan.nbuf - 1));
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) |
- MTK_WED_TX_BM_DYN_THR_HI_V2);
-@@ -970,6 +978,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- MTK_WED_TX_TKID_DYN_THR_HI);
- }
-
-+ wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid,
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, dev->wlan.token_start) |
-+ FIELD_PREP(MTK_WED_TX_BM_TKID_END,
-+ dev->wlan.token_start + dev->wlan.nbuf - 1));
-+
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
- if (mtk_wed_is_v1(dev->hw)) {
-@@ -1104,13 +1117,8 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- if (ret) {
- mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
- } else {
-- struct mtk_eth *eth = dev->hw->eth;
--
-- if (mtk_is_netsys_v2_or_greater(eth))
-- wed_set(dev, MTK_WED_RESET_IDX,
-- MTK_WED_RESET_IDX_RX_V2);
-- else
-- wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
-+ wed_set(dev, MTK_WED_RESET_IDX,
-+ dev->hw->soc->regmap.reset_idx_rx_mask);
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-@@ -1163,7 +1171,8 @@ mtk_wed_reset_dma(struct mtk_wed_device
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
- } else {
-- wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
-+ wed_w32(dev, MTK_WED_RESET_IDX,
-+ dev->hw->soc->regmap.reset_idx_tx_mask);
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-@@ -1255,7 +1264,6 @@ static int
- mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
- bool reset)
- {
-- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-
- if (idx >= ARRAY_SIZE(dev->rx_wdma))
-@@ -1263,7 +1271,7 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
-
- wdma = &dev->rx_wdma[idx];
- if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- desc_size, true))
-+ dev->hw->soc->wdma_desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1284,7 +1292,6 @@ static int
- mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
- bool reset)
- {
-- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
- struct mtk_wed_ring *wdma;
-
- if (idx >= ARRAY_SIZE(dev->tx_wdma))
-@@ -1292,7 +1299,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
-
- wdma = &dev->tx_wdma[idx];
- if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- desc_size, true))
-+ dev->hw->soc->wdma_desc_size, true))
- return -ENOMEM;
-
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1931,7 +1938,12 @@ void mtk_wed_add_hw(struct device_node *
- hw->irq = irq;
- hw->version = eth->soc->version;
-
-- if (mtk_wed_is_v1(hw)) {
-+ switch (hw->version) {
-+ case 2:
-+ hw->soc = &mt7986_data;
-+ break;
-+ default:
-+ case 1:
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
- "mediatek,pcie-mirror");
- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
-@@ -1945,6 +1957,8 @@ void mtk_wed_add_hw(struct device_node *
- regmap_write(hw->mirror, 0, 0);
- regmap_write(hw->mirror, 4, 0);
- }
-+ hw->soc = &mt7622_data;
-+ break;
- }
-
- mtk_wed_hw_add_debugfs(hw);
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -12,7 +12,18 @@
- struct mtk_eth;
- struct mtk_wed_wo;
-
-+struct mtk_wed_soc_data {
-+ struct {
-+ u32 tx_bm_tkid;
-+ u32 wpdma_rx_ring0;
-+ u32 reset_idx_tx_mask;
-+ u32 reset_idx_rx_mask;
-+ } regmap;
-+ u32 wdma_desc_size;
-+};
-+
- struct mtk_wed_hw {
-+ const struct mtk_wed_soc_data *soc;
- struct device_node *node;
- struct mtk_eth *eth;
- struct regmap *regs;
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -100,8 +100,6 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_TX_BM_BASE 0x084
-
--#define MTK_WED_TX_BM_TKID 0x088
--#define MTK_WED_TX_BM_TKID_V2 0x0c8
- #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
- #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-
-@@ -160,9 +158,6 @@ struct mtk_wdma_desc {
- #define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31)
-
- #define MTK_WED_RESET_IDX 0x20c
--#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
--#define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
--#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6)
- #define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
-
- #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
-@@ -286,7 +281,6 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-
- #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
--#define MTK_WED_WPDMA_RX_RING 0x770
-
- #define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
- #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
diff --git a/target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch b/target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
deleted file mode 100644
index f874899c5b..0000000000
--- a/target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
+++ /dev/null
@@ -1,1280 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:13 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce WED support for MT7988
-
-Similar to MT7986 and MT7622, enable Wireless Ethernet Ditpatcher for
-MT7988 in order to offload traffic forwarded from LAN/WLAN to WLAN/LAN
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -195,6 +195,7 @@ static const struct mtk_reg_map mt7988_r
- .wdma_base = {
- [0] = 0x4800,
- [1] = 0x4c00,
-+ [2] = 0x5000,
- },
- .pse_iq_sta = 0x0180,
- .pse_oq_sta = 0x01a0,
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1132,7 +1132,7 @@ struct mtk_reg_map {
- u32 gdm1_cnt;
- u32 gdma_to_ppe;
- u32 ppe_base;
-- u32 wdma_base[2];
-+ u32 wdma_base[3];
- u32 pse_iq_sta;
- u32 pse_oq_sta;
- };
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -201,6 +201,9 @@ mtk_flow_set_output_device(struct mtk_et
- case 1:
- pse_port = PSE_WDMA1_PORT;
- break;
-+ case 2:
-+ pse_port = PSE_WDMA2_PORT;
-+ break;
- default:
- return -EINVAL;
- }
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -16,17 +16,19 @@
- #include <net/flow_offload.h>
- #include <net/pkt_cls.h>
- #include "mtk_eth_soc.h"
--#include "mtk_wed_regs.h"
- #include "mtk_wed.h"
- #include "mtk_ppe.h"
- #include "mtk_wed_wo.h"
-
- #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
-
--#define MTK_WED_PKT_SIZE 1900
-+#define MTK_WED_PKT_SIZE 1920
- #define MTK_WED_BUF_SIZE 2048
-+#define MTK_WED_PAGE_BUF_SIZE 128
- #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
-+#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
- #define MTK_WED_RX_RING_SIZE 1536
-+#define MTK_WED_RX_PG_BM_CNT 8192
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 1024
-@@ -40,7 +42,10 @@
- #define MTK_WED_RRO_QUE_CNT 8192
- #define MTK_WED_MIOD_ENTRY_CNT 128
-
--static struct mtk_wed_hw *hw_list[2];
-+#define MTK_WED_TX_BM_DMA_SIZE 65536
-+#define MTK_WED_TX_BM_PKT_CNT 32768
-+
-+static struct mtk_wed_hw *hw_list[3];
- static DEFINE_MUTEX(hw_lock);
-
- struct mtk_wed_flow_block_priv {
-@@ -55,6 +60,7 @@ static const struct mtk_wed_soc_data mt7
- .reset_idx_tx_mask = GENMASK(3, 0),
- .reset_idx_rx_mask = GENMASK(17, 16),
- },
-+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc),
- .wdma_desc_size = sizeof(struct mtk_wdma_desc),
- };
-
-@@ -65,6 +71,18 @@ static const struct mtk_wed_soc_data mt7
- .reset_idx_tx_mask = GENMASK(1, 0),
- .reset_idx_rx_mask = GENMASK(7, 6),
- },
-+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc),
-+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
-+};
-+
-+static const struct mtk_wed_soc_data mt7988_data = {
-+ .regmap = {
-+ .tx_bm_tkid = 0x0c8,
-+ .wpdma_rx_ring0 = 0x7d0,
-+ .reset_idx_tx_mask = GENMASK(1, 0),
-+ .reset_idx_rx_mask = GENMASK(7, 6),
-+ },
-+ .tx_ring_desc_size = sizeof(struct mtk_wed_bm_desc),
- .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
- };
-
-@@ -319,33 +337,38 @@ out:
- static int
- mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
-+ u32 desc_size = dev->hw->soc->tx_ring_desc_size;
-+ int i, page_idx = 0, n_pages, ring_size;
-+ int token = dev->wlan.token_start;
- struct mtk_wed_buf *page_list;
-- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
-- int token = dev->wlan.token_start;
-- int ring_size;
-- int n_pages;
-- int i, page_idx;
-+ void *desc_ptr;
-
-- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-- n_pages = ring_size / MTK_WED_BUF_PER_PAGE;
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-+ dev->tx_buf_ring.size = ring_size;
-+ } else {
-+ dev->tx_buf_ring.size = MTK_WED_TX_BM_DMA_SIZE;
-+ ring_size = MTK_WED_TX_BM_PKT_CNT;
-+ }
-+ n_pages = dev->tx_buf_ring.size / MTK_WED_BUF_PER_PAGE;
-
- page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
- if (!page_list)
- return -ENOMEM;
-
-- dev->tx_buf_ring.size = ring_size;
- dev->tx_buf_ring.pages = page_list;
-
-- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
-- &desc_phys, GFP_KERNEL);
-- if (!desc)
-+ desc_ptr = dma_alloc_coherent(dev->hw->dev,
-+ dev->tx_buf_ring.size * desc_size,
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc_ptr)
- return -ENOMEM;
-
-- dev->tx_buf_ring.desc = desc;
-+ dev->tx_buf_ring.desc = desc_ptr;
- dev->tx_buf_ring.desc_phys = desc_phys;
-
-- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
-+ for (i = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
- dma_addr_t page_phys, buf_phys;
- struct page *page;
- void *buf;
-@@ -371,28 +394,31 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
- buf_phys = page_phys;
-
- for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
-- u32 txd_size;
-- u32 ctrl;
--
-- txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
-+ struct mtk_wdma_desc *desc = desc_ptr;
-
- desc->buf0 = cpu_to_le32(buf_phys);
-- desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ u32 txd_size, ctrl;
-
-- if (mtk_wed_is_v1(dev->hw))
-- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-- MTK_WED_BUF_SIZE - txd_size) |
-- MTK_WDMA_DESC_CTRL_LAST_SEG1;
-- else
-- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) |
-- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2,
-- MTK_WED_BUF_SIZE - txd_size) |
-- MTK_WDMA_DESC_CTRL_LAST_SEG0;
-- desc->ctrl = cpu_to_le32(ctrl);
-- desc->info = 0;
-- desc++;
-+ txd_size = dev->wlan.init_buf(buf, buf_phys,
-+ token++);
-+ desc->buf1 = cpu_to_le32(buf_phys + txd_size);
-+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size);
-+ if (mtk_wed_is_v1(dev->hw))
-+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG1 |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-+ MTK_WED_BUF_SIZE - txd_size);
-+ else
-+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG0 |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2,
-+ MTK_WED_BUF_SIZE - txd_size);
-+ desc->ctrl = cpu_to_le32(ctrl);
-+ desc->info = 0;
-+ } else {
-+ desc->ctrl = cpu_to_le32(token << 16);
-+ }
-
-+ desc_ptr += desc_size;
- buf += MTK_WED_BUF_SIZE;
- buf_phys += MTK_WED_BUF_SIZE;
- }
-@@ -408,31 +434,31 @@ static void
- mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
- {
- struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages;
-- struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
-- int page_idx;
-- int i;
-+ struct mtk_wed_hw *hw = dev->hw;
-+ int i, page_idx = 0;
-
- if (!page_list)
- return;
-
-- if (!desc)
-+ if (!dev->tx_buf_ring.desc)
- goto free_pagelist;
-
-- for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size;
-- i += MTK_WED_BUF_PER_PAGE) {
-- dma_addr_t buf_addr = page_list[page_idx].phy_addr;
-+ for (i = 0; i < dev->tx_buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
-+ dma_addr_t page_phy = page_list[page_idx].phy_addr;
- void *page = page_list[page_idx++].p;
-
- if (!page)
- break;
-
-- dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
-+ dma_unmap_page(dev->hw->dev, page_phy, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- __free_page(page);
- }
-
-- dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc),
-- desc, dev->tx_buf_ring.desc_phys);
-+ dma_free_coherent(dev->hw->dev,
-+ dev->tx_buf_ring.size * hw->soc->tx_ring_desc_size,
-+ dev->tx_buf_ring.desc,
-+ dev->tx_buf_ring.desc_phys);
-
- free_pagelist:
- kfree(page_list);
-@@ -517,13 +543,23 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- {
- u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-- if (mtk_wed_is_v1(dev->hw))
-+ switch (dev->hw->version) {
-+ case 1:
- mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
-- else
-+ break;
-+ case 2:
- mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
- MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH |
- MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
-+ break;
-+ case 3:
-+ mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-+ break;
-+ default:
-+ break;
-+ }
-
- if (!dev->hw->num_flows)
- mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-@@ -535,6 +571,9 @@ mtk_wed_set_ext_int(struct mtk_wed_devic
- static void
- mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable)
- {
-+ if (!mtk_wed_is_v2(dev->hw))
-+ return;
-+
- if (enable) {
- wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
- wed_w32(dev, MTK_WED_TXP_DW1,
-@@ -609,6 +648,14 @@ mtk_wed_dma_disable(struct mtk_wed_devic
- MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw) &&
-+ mtk_wed_get_rx_capa(dev)) {
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG,
-+ MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG,
-+ MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ }
- }
-
- mtk_wed_set_512_support(dev, false);
-@@ -651,6 +698,14 @@ mtk_wed_deinit(struct mtk_wed_device *de
- MTK_WED_CTRL_RX_ROUTE_QM_EN |
- MTK_WED_CTRL_WED_RX_BM_EN |
- MTK_WED_CTRL_RX_RRO_QM_EN);
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
-+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_TX_AMSDU);
-+ wed_clr(dev, MTK_WED_PCIE_INT_CTRL,
-+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER);
-+ }
- }
-
- static void
-@@ -700,21 +755,37 @@ mtk_wed_detach(struct mtk_wed_device *de
- mutex_unlock(&hw_lock);
- }
-
--#define PCIE_BASE_ADDR0 0x11280000
- static void
- mtk_wed_bus_init(struct mtk_wed_device *dev)
- {
- switch (dev->wlan.bus_type) {
- case MTK_WED_BUS_PCIE: {
- struct device_node *np = dev->hw->eth->dev->of_node;
-- struct regmap *regs;
-
-- regs = syscon_regmap_lookup_by_phandle(np,
-- "mediatek,wed-pcie");
-- if (IS_ERR(regs))
-- break;
-+ if (mtk_wed_is_v2(dev->hw)) {
-+ struct regmap *regs;
-+
-+ regs = syscon_regmap_lookup_by_phandle(np,
-+ "mediatek,wed-pcie");
-+ if (IS_ERR(regs))
-+ break;
-
-- regmap_update_bits(regs, 0, BIT(0), BIT(0));
-+ regmap_update_bits(regs, 0, BIT(0), BIT(0));
-+ }
-+
-+ if (dev->wlan.msi) {
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM,
-+ dev->hw->pcie_base | 0xc08);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE,
-+ dev->hw->pcie_base | 0xc04);
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(8));
-+ } else {
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM,
-+ dev->hw->pcie_base | 0x180);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE,
-+ dev->hw->pcie_base | 0x184);
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-+ }
-
- wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
-@@ -722,19 +793,9 @@ mtk_wed_bus_init(struct mtk_wed_device *
- /* pcie interrupt control: pola/source selection */
- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
-- wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
--
-- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
-- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
--
-- /* pcie interrupt status trigger register */
-- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
--
-- /* pola setting */
-- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER |
-+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL,
-+ dev->hw->index));
- break;
- }
- case MTK_WED_BUS_AXI:
-@@ -772,18 +833,19 @@ mtk_wed_set_wpdma(struct mtk_wed_device
- static void
- mtk_wed_hw_init_early(struct mtk_wed_device *dev)
- {
-- u32 mask, set;
-+ u32 set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2);
-+ u32 mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE;
-
- mtk_wed_deinit(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
- mtk_wed_set_wpdma(dev);
-
-- mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
-- MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-- set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
-- MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
-- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ mask |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-+ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-+ set |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
-+ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
-+ }
- wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-
- if (mtk_wed_is_v1(dev->hw)) {
-@@ -931,11 +993,18 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_
- }
-
- /* configure RX_ROUTE_QM */
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-- FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ if (mtk_wed_is_v2(dev->hw)) {
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT,
-+ 0x3 + dev->hw->index));
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ } else {
-+ wed_set(dev, MTK_WED_RTQM_ENQ_CFG0,
-+ FIELD_PREP(MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT,
-+ 0x3 + dev->hw->index));
-+ }
- /* enable RX_ROUTE_QM */
- wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
- }
-@@ -948,22 +1017,30 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- dev->init_done = true;
- mtk_wed_set_ext_int(dev, false);
-- wed_w32(dev, MTK_WED_TX_BM_CTRL,
-- MTK_WED_TX_BM_CTRL_PAUSE |
-- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-- dev->tx_buf_ring.size / 128) |
-- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
-- MTK_WED_TX_RING_SIZE / 256));
-
- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys);
--
- wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
-
- if (mtk_wed_is_v1(dev->hw)) {
-+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-+ dev->tx_buf_ring.size / 128) |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
-+ MTK_WED_TX_RING_SIZE / 256));
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
- MTK_WED_TX_BM_DYN_THR_HI);
-- } else {
-+ } else if (mtk_wed_is_v2(dev->hw)) {
-+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
-+ dev->tx_buf_ring.size / 128) |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
-+ MTK_WED_TX_RING_SIZE / 256));
-+ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
-+ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
-+ MTK_WED_TX_TKID_DYN_THR_HI);
- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) |
- MTK_WED_TX_BM_DYN_THR_HI_V2);
-@@ -973,9 +1050,6 @@ mtk_wed_hw_init(struct mtk_wed_device *d
- dev->tx_buf_ring.size / 128) |
- FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
- dev->tx_buf_ring.size / 128));
-- wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
-- FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
-- MTK_WED_TX_TKID_DYN_THR_HI);
- }
-
- wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid,
-@@ -985,26 +1059,62 @@ mtk_wed_hw_init(struct mtk_wed_device *d
-
- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* switch to new bm architecture */
-+ wed_clr(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_LEGACY_EN);
-+
-+ wed_w32(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3,
-+ dev->wlan.nbuf / 128) |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3,
-+ dev->wlan.nbuf / 128));
-+ /* return SKBID + SDP back to bm */
-+ wed_set(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_FREE_FORMAT);
-+
-+ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR,
-+ MTK_WED_TX_BM_PKT_CNT |
-+ MTK_WED_TX_BM_INIT_SW_TAIL_IDX);
-+ }
-+
- if (mtk_wed_is_v1(dev->hw)) {
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-- } else {
-- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
-- if (mtk_wed_get_rx_capa(dev)) {
-- /* rx hw init */
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-- MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-- MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
--
-- mtk_wed_rx_buffer_hw_init(dev);
-- mtk_wed_rro_hw_init(dev);
-- mtk_wed_route_qm_hw_init(dev);
-- }
-+ } else if (mtk_wed_get_rx_capa(dev)) {
-+ /* rx hw init */
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+
-+ /* reset prefetch index of ring */
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+
-+ /* reset prefetch FIFO of ring */
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR |
-+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, 0);
-+
-+ mtk_wed_rx_buffer_hw_init(dev);
-+ mtk_wed_rro_hw_init(dev);
-+ mtk_wed_route_qm_hw_init(dev);
- }
-
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
-+ if (!mtk_wed_is_v1(dev->hw))
-+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
- }
-
- static void
-@@ -1302,6 +1412,24 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
- dev->hw->soc->wdma_desc_size, true))
- return -ENOMEM;
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ struct mtk_wdma_desc *desc = wdma->desc;
-+ int i;
-+
-+ for (i = 0; i < MTK_WED_WDMA_RING_SIZE; i++) {
-+ desc->buf0 = 0;
-+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ desc->buf1 = 0;
-+ desc->info = cpu_to_le32(MTK_WDMA_TXD0_DESC_INFO_DMA_DONE);
-+ desc++;
-+ desc->buf0 = 0;
-+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ desc->buf1 = 0;
-+ desc->info = cpu_to_le32(MTK_WDMA_TXD1_DESC_INFO_DMA_DONE);
-+ desc++;
-+ }
-+ }
-+
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
-@@ -1367,6 +1495,9 @@ mtk_wed_configure_irq(struct mtk_wed_dev
-
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_TKID_ALI_EN);
-+
- /* initail tx interrupt trigger */
- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
- MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-@@ -1419,33 +1550,60 @@ mtk_wed_dma_enable(struct mtk_wed_device
- {
- int i;
-
-- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-+ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
-+ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ wdma_set(dev, MTK_WDMA_GLO_CFG,
-+ MTK_WDMA_GLO_CFG_TX_DMA_EN |
-+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-+ wed_set(dev, MTK_WED_WPDMA_CTRL, MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-+ } else {
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR);
-+ wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-+ }
-
- wed_set(dev, MTK_WED_GLO_CFG,
- MTK_WED_GLO_CFG_TX_DMA_EN |
- MTK_WED_GLO_CFG_RX_DMA_EN);
-- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+
- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-
-- wdma_set(dev, MTK_WDMA_GLO_CFG,
-- MTK_WDMA_GLO_CFG_TX_DMA_EN |
-- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
--
- if (mtk_wed_is_v1(dev->hw)) {
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- return;
- }
-
-- wed_set(dev, MTK_WED_WPDMA_CTRL,
-- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_BURST_SIZE, 0x10) |
-+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_LOW_THRES, 0x8));
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN);
-+
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
-+
-+ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ }
-+
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
-@@ -1457,11 +1615,22 @@ mtk_wed_dma_enable(struct mtk_wed_device
- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RXD_READ_LEN);
- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
- MTK_WED_WPDMA_RX_D_RX_DRV_EN |
- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-- 0x2));
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, 0x2));
-+
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE, 0x10) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_LOW_THRES, 0x8));
-+
-+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
-+ wdma_set(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ }
-
- for (i = 0; i < MTK_WED_RX_QUEUES; i++)
- mtk_wed_check_wfdma_rx_fill(dev, i);
-@@ -1501,6 +1670,12 @@ mtk_wed_start(struct mtk_wed_device *dev
- wed_r32(dev, MTK_WED_EXT_INT_MASK1);
- wed_r32(dev, MTK_WED_EXT_INT_MASK2);
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK3,
-+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK3);
-+ }
-+
- if (mtk_wed_rro_cfg(dev))
- return;
- }
-@@ -1552,6 +1727,7 @@ mtk_wed_attach(struct mtk_wed_device *de
- dev->irq = hw->irq;
- dev->wdma_idx = hw->index;
- dev->version = hw->version;
-+ dev->hw->pcie_base = mtk_wed_get_pcie_base(dev);
-
- if (hw->eth->dma_dev == hw->eth->dev &&
- of_dma_is_coherent(hw->eth->dev->of_node))
-@@ -1619,6 +1795,23 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
- ring->reg_base = MTK_WED_RING_TX(idx);
- ring->wpdma = regs;
-
-+ if (mtk_wed_is_v3_or_greater(dev->hw) && idx == 1) {
-+ /* reset prefetch index */
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ /* reset prefetch FIFO */
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG,
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR |
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR);
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0);
-+ }
-+
- /* WED -> WPDMA */
- wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
- wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_TX_RING_SIZE);
-@@ -1693,15 +1886,13 @@ mtk_wed_rx_ring_setup(struct mtk_wed_dev
- static u32
- mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
- {
-- u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-+ u32 val, ext_mask;
-
-- if (mtk_wed_is_v1(dev->hw))
-- ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ ext_mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
- else
-- ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-- MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH |
-- MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
-+ ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
- val = wed_r32(dev, MTK_WED_EXT_INT_STATUS);
- wed_w32(dev, MTK_WED_EXT_INT_STATUS, val);
-@@ -1942,6 +2133,9 @@ void mtk_wed_add_hw(struct device_node *
- case 2:
- hw->soc = &mt7986_data;
- break;
-+ case 3:
-+ hw->soc = &mt7988_data;
-+ break;
- default:
- case 1:
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -9,6 +9,8 @@
- #include <linux/regmap.h>
- #include <linux/netdevice.h>
-
-+#include "mtk_wed_regs.h"
-+
- struct mtk_eth;
- struct mtk_wed_wo;
-
-@@ -19,6 +21,7 @@ struct mtk_wed_soc_data {
- u32 reset_idx_tx_mask;
- u32 reset_idx_rx_mask;
- } regmap;
-+ u32 tx_ring_desc_size;
- u32 wdma_desc_size;
- };
-
-@@ -35,6 +38,7 @@ struct mtk_wed_hw {
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
- struct mtk_wed_wo *wed_wo;
-+ u32 pcie_base;
- u32 debugfs_reg;
- u32 num_flows;
- u8 version;
-@@ -61,6 +65,16 @@ static inline bool mtk_wed_is_v2(struct
- return hw->version == 2;
- }
-
-+static inline bool mtk_wed_is_v3(struct mtk_wed_hw *hw)
-+{
-+ return hw->version == 3;
-+}
-+
-+static inline bool mtk_wed_is_v3_or_greater(struct mtk_wed_hw *hw)
-+{
-+ return hw->version > 2;
-+}
-+
- static inline void
- wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
- {
-@@ -143,6 +157,21 @@ wpdma_txfree_w32(struct mtk_wed_device *
- writel(val, dev->txfree_ring.wpdma + reg);
- }
-
-+static inline u32 mtk_wed_get_pcie_base(struct mtk_wed_device *dev)
-+{
-+ if (!mtk_wed_is_v3_or_greater(dev->hw))
-+ return MTK_WED_PCIE_BASE;
-+
-+ switch (dev->hw->index) {
-+ case 1:
-+ return MTK_WED_PCIE_BASE1;
-+ case 2:
-+ return MTK_WED_PCIE_BASE2;
-+ default:
-+ return MTK_WED_PCIE_BASE0;
-+ }
-+}
-+
- void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, phys_addr_t wdma_phy,
- int index);
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -331,10 +331,22 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- wo->hw->index + 1);
-
- /* load firmware */
-- if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
-- fw_name = MT7981_FIRMWARE_WO;
-- else
-- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+ switch (wo->hw->version) {
-+ case 2:
-+ if (of_device_is_compatible(wo->hw->node,
-+ "mediatek,mt7981-wed"))
-+ fw_name = MT7981_FIRMWARE_WO;
-+ else
-+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1
-+ : MT7986_FIRMWARE_WO0;
-+ break;
-+ case 3:
-+ fw_name = wo->hw->index ? MT7988_FIRMWARE_WO1
-+ : MT7988_FIRMWARE_WO0;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-
- ret = request_firmware(&fw, fw_name, wo->hw->dev);
- if (ret)
-@@ -355,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- }
-
- /* set the start address */
-- boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR
-- : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
-+ if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
-+ boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR;
-+ else
-+ boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
- wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
- /* wo firmware reset */
- wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
-
-- val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
-- val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK
-- : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
-+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
-+ MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
- wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
- out:
- release_firmware(fw);
-@@ -398,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *
- MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
-+MODULE_FIRMWARE(MT7988_FIRMWARE_WO0);
-+MODULE_FIRMWARE(MT7988_FIRMWARE_WO1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -13,6 +13,9 @@
- #define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30)
- #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
-
-+#define MTK_WDMA_TXD0_DESC_INFO_DMA_DONE BIT(29)
-+#define MTK_WDMA_TXD1_DESC_INFO_DMA_DONE BIT(31)
-+
- struct mtk_wdma_desc {
- __le32 buf0;
- __le32 ctrl;
-@@ -37,6 +40,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
- #define MTK_WED_RESET_RX_RRO_QM BIT(20)
- #define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
-+#define MTK_WED_RESET_TX_AMSDU BIT(22)
- #define MTK_WED_RESET_WED BIT(31)
-
- #define MTK_WED_CTRL 0x00c
-@@ -44,6 +48,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1)
- #define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2)
- #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
-+#define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
-+#define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
-+#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7)
- #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
- #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
-@@ -54,9 +61,14 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
- #define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
- #define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
-+#define MTK_WED_CTRL_TX_TKID_ALI_EN BIT(20)
-+#define MTK_WED_CTRL_TX_TKID_ALI_BUSY BIT(21)
-+#define MTK_WED_CTRL_TX_AMSDU_EN BIT(22)
-+#define MTK_WED_CTRL_TX_AMSDU_BUSY BIT(23)
- #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
- #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25)
- #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
-+#define MTK_WED_CTRL_FLD_MIB_RD_CLR BIT(28)
-
- #define MTK_WED_EXT_INT_STATUS 0x020
- #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0)
-@@ -89,6 +101,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_MASK 0x028
- #define MTK_WED_EXT_INT_MASK1 0x02c
- #define MTK_WED_EXT_INT_MASK2 0x030
-+#define MTK_WED_EXT_INT_MASK3 0x034
-
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-@@ -96,9 +109,14 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_BM_CTRL 0x080
- #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
- #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-+#define MTK_WED_TX_BM_CTRL_LEGACY_EN BIT(26)
-+#define MTK_WED_TX_TKID_CTRL_FREE_FORMAT BIT(27)
- #define MTK_WED_TX_BM_CTRL_PAUSE BIT(28)
-
- #define MTK_WED_TX_BM_BASE 0x084
-+#define MTK_WED_TX_BM_INIT_PTR 0x088
-+#define MTK_WED_TX_BM_SW_TAIL_IDX GENMASK(16, 0)
-+#define MTK_WED_TX_BM_INIT_SW_TAIL_IDX BIT(16)
-
- #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
- #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-@@ -122,6 +140,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16)
- #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
-
-+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0)
-+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16)
-+
- #define MTK_WED_TX_TKID_DYN_THR 0x0e0
- #define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0)
- #define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16)
-@@ -199,12 +220,15 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7)
--#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(15, 12)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4 BIT(18)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19)
--#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK BIT(20)
- #define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21)
- #define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST BIT(25)
- #define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK BIT(30)
-
- #define MTK_WED_WPDMA_RESET_IDX 0x50c
- #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0)
-@@ -250,9 +274,10 @@ struct mtk_wdma_desc {
- #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16)
-
- #define MTK_WED_PCIE_INT_CTRL 0x57c
--#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
--#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
- #define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12)
-+#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
-+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
-+#define MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER BIT(21)
-
- #define MTK_WED_WPDMA_CFG_BASE 0x580
- #define MTK_WED_WPDMA_CFG_INT_MASK 0x584
-@@ -286,6 +311,20 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
- #define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
-
-+#define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
-+#define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
-+#define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX 0x7b8
-+#define MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR BIT(15)
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX 0x7bc
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG 0x7c0
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR BIT(16)
-+
- #define MTK_WED_WDMA_RING_TX 0x800
-
- #define MTK_WED_WDMA_TX_MIB 0x810
-@@ -293,6 +332,18 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
- #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
-
-+#define MTK_WED_WDMA_RX_PREF_CFG 0x950
-+#define MTK_WED_WDMA_RX_PREF_EN BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
-+#define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
-+#define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
-+#define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
-+#define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
-+
-+#define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
-+#define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR BIT(16)
-+
- #define MTK_WED_WDMA_GLO_CFG 0xa04
- #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
- #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
-@@ -325,6 +376,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16)
-
- #define MTK_WED_WDMA_INT_CTRL 0xa2c
-+#define MTK_WED_WDMA_INT_POLL_PRD GENMASK(7, 0)
- #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16)
-
- #define MTK_WED_WDMA_CFG_BASE 0xaa0
-@@ -388,6 +440,18 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_INT_GRP1 0x250
- #define MTK_WDMA_INT_GRP2 0x254
-
-+#define MTK_WDMA_PREF_TX_CFG 0x2d0
-+#define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
-+
-+#define MTK_WDMA_PREF_RX_CFG 0x2dc
-+#define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
-+
-+#define MTK_WDMA_WRBK_TX_CFG 0x300
-+#define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
-+
-+#define MTK_WDMA_WRBK_RX_CFG 0x344
-+#define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
-+
- #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
- #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
- #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
-@@ -401,6 +465,30 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
- #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-
-+#define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
-+#define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
-+#define MTK_WED_RTQM_IGRS0_I2H_PKT_CNT(_n) (0xb2c + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS0_FDROP_CNT 0xb34
-+
-+#define MTK_WED_RTQM_IGRS1_I2HW_DMAD_CNT 0xb44
-+#define MTK_WED_RTQM_IGRS1_I2H_DMAD_CNT(_n) (0xb48 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS1_I2HW_PKT_CNT 0xb50
-+#define MTK_WED_RTQM_IGRS1_I2H_PKT_CNT(_n) (0xb54 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS1_FDROP_CNT 0xb5c
-+
-+#define MTK_WED_RTQM_IGRS2_I2HW_DMAD_CNT 0xb6c
-+#define MTK_WED_RTQM_IGRS2_I2H_DMAD_CNT(_n) (0xb70 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS2_I2HW_PKT_CNT 0xb78
-+#define MTK_WED_RTQM_IGRS2_I2H_PKT_CNT(_n) (0xb7c + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS2_FDROP_CNT 0xb84
-+
-+#define MTK_WED_RTQM_IGRS3_I2HW_DMAD_CNT 0xb94
-+#define MTK_WED_RTQM_IGRS3_I2H_DMAD_CNT(_n) (0xb98 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS3_I2HW_PKT_CNT 0xba0
-+#define MTK_WED_RTQM_IGRS3_I2H_PKT_CNT(_n) (0xba4 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS3_FDROP_CNT 0xbac
-+
- #define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
- #define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
- #define MTK_WED_RTQM_Q2N_MIB 0xb80
-@@ -409,6 +497,24 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q2B_MIB 0xb8c
- #define MTK_WED_RTQM_PFDBK_MIB 0xb90
-
-+#define MTK_WED_RTQM_ENQ_CFG0 0xbb8
-+#define MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT GENMASK(15, 12)
-+
-+#define MTK_WED_RTQM_FDROP_MIB 0xb84
-+#define MTK_WED_RTQM_ENQ_I2Q_DMAD_CNT 0xbbc
-+#define MTK_WED_RTQM_ENQ_I2N_DMAD_CNT 0xbc0
-+#define MTK_WED_RTQM_ENQ_I2Q_PKT_CNT 0xbc4
-+#define MTK_WED_RTQM_ENQ_I2N_PKT_CNT 0xbc8
-+#define MTK_WED_RTQM_ENQ_USED_ENTRY_CNT 0xbcc
-+#define MTK_WED_RTQM_ENQ_ERR_CNT 0xbd0
-+
-+#define MTK_WED_RTQM_DEQ_DMAD_CNT 0xbd8
-+#define MTK_WED_RTQM_DEQ_Q2I_DMAD_CNT 0xbdc
-+#define MTK_WED_RTQM_DEQ_PKT_CNT 0xbe0
-+#define MTK_WED_RTQM_DEQ_Q2I_PKT_CNT 0xbe4
-+#define MTK_WED_RTQM_DEQ_USED_PFDBK_CNT 0xbe8
-+#define MTK_WED_RTQM_DEQ_ERR_CNT 0xbec
-+
- #define MTK_WED_RROQM_GLO_CFG 0xc04
- #define MTK_WED_RROQM_RST_IDX 0xc08
- #define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
-@@ -458,7 +564,116 @@ struct mtk_wdma_desc {
- #define MTK_WED_RX_BM_INTF 0xd9c
- #define MTK_WED_RX_BM_ERR_STS 0xda8
-
-+#define MTK_RRO_IND_CMD_SIGNATURE 0xe00
-+#define MTK_RRO_IND_CMD_DMA_IDX GENMASK(11, 0)
-+#define MTK_RRO_IND_CMD_MAGIC_CNT GENMASK(30, 28)
-+
-+#define MTK_WED_IND_CMD_RX_CTRL0 0xe04
-+#define MTK_WED_IND_CMD_PROC_IDX GENMASK(11, 0)
-+#define MTK_WED_IND_CMD_PREFETCH_FREE_CNT GENMASK(19, 16)
-+#define MTK_WED_IND_CMD_MAGIC_CNT GENMASK(30, 28)
-+
-+#define MTK_WED_IND_CMD_RX_CTRL1 0xe08
-+#define MTK_WED_IND_CMD_RX_CTRL2 0xe0c
-+#define MTK_WED_IND_CMD_MAX_CNT GENMASK(11, 0)
-+#define MTK_WED_IND_CMD_BASE_M GENMASK(19, 16)
-+
-+#define MTK_WED_RRO_CFG0 0xe10
-+#define MTK_WED_RRO_CFG1 0xe14
-+#define MTK_WED_RRO_CFG1_MAX_WIN_SZ GENMASK(31, 29)
-+#define MTK_WED_RRO_CFG1_ACK_SN_BASE_M GENMASK(19, 16)
-+#define MTK_WED_RRO_CFG1_PARTICL_SE_ID GENMASK(11, 0)
-+
-+#define MTK_WED_ADDR_ELEM_CFG0 0xe18
-+#define MTK_WED_ADDR_ELEM_CFG1 0xe1c
-+#define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT GENMASK(19, 16)
-+
-+#define MTK_WED_ADDR_ELEM_TBL_CFG 0xe20
-+#define MTK_WED_ADDR_ELEM_TBL_OFFSET GENMASK(6, 0)
-+#define MTK_WED_ADDR_ELEM_TBL_RD_RDY BIT(28)
-+#define MTK_WED_ADDR_ELEM_TBL_WR_RDY BIT(29)
-+#define MTK_WED_ADDR_ELEM_TBL_RD BIT(30)
-+#define MTK_WED_ADDR_ELEM_TBL_WR BIT(31)
-+
-+#define MTK_WED_RADDR_ELEM_TBL_WDATA 0xe24
-+#define MTK_WED_RADDR_ELEM_TBL_RDATA 0xe28
-+
-+#define MTK_WED_PN_CHECK_CFG 0xe30
-+#define MTK_WED_PN_CHECK_SE_ID GENMASK(11, 0)
-+#define MTK_WED_PN_CHECK_RD_RDY BIT(28)
-+#define MTK_WED_PN_CHECK_WR_RDY BIT(29)
-+#define MTK_WED_PN_CHECK_RD BIT(30)
-+#define MTK_WED_PN_CHECK_WR BIT(31)
-+
-+#define MTK_WED_PN_CHECK_WDATA_M 0xe38
-+#define MTK_WED_PN_CHECK_IS_FIRST BIT(17)
-+
-+#define MTK_WED_RRO_MSDU_PG_RING_CFG(_n) (0xe44 + (_n) * 0x8)
-+
-+#define MTK_WED_RRO_MSDU_PG_RING2_CFG 0xe58
-+#define MTK_WED_RRO_MSDU_PG_DRV_CLR BIT(26)
-+#define MTK_WED_RRO_MSDU_PG_DRV_EN BIT(31)
-+
-+#define MTK_WED_RRO_MSDU_PG_CTRL0(_n) (0xe5c + (_n) * 0xc)
-+#define MTK_WED_RRO_MSDU_PG_CTRL1(_n) (0xe60 + (_n) * 0xc)
-+#define MTK_WED_RRO_MSDU_PG_CTRL2(_n) (0xe64 + (_n) * 0xc)
-+
-+#define MTK_WED_RRO_RX_D_RX(_n) (0xe80 + (_n) * 0x10)
-+
-+#define MTK_WED_RRO_RX_MAGIC_CNT BIT(13)
-+
-+#define MTK_WED_RRO_RX_D_CFG(_n) (0xea0 + (_n) * 0x4)
-+#define MTK_WED_RRO_RX_D_DRV_CLR BIT(26)
-+#define MTK_WED_RRO_RX_D_DRV_EN BIT(31)
-+
-+#define MTK_WED_RRO_PG_BM_RX_DMAM 0xeb0
-+#define MTK_WED_RRO_PG_BM_RX_SDL0 GENMASK(13, 0)
-+
-+#define MTK_WED_RRO_PG_BM_BASE 0xeb4
-+#define MTK_WED_RRO_PG_BM_INIT_PTR 0xeb8
-+#define MTK_WED_RRO_PG_BM_SW_TAIL_IDX GENMASK(15, 0)
-+#define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX BIT(16)
-+
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX 0xeec
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG GENMASK(14, 10)
-+
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG 0xef4
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG GENMASK(14, 10)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN BIT(16)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
-+
-+#define MTK_WED_RX_IND_CMD_CNT0 0xf20
-+#define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
-+
-+#define MTK_WED_RX_IND_CMD_CNT(_n) (0xf20 + (_n) * 0x4)
-+#define MTK_WED_IND_CMD_MAGIC_CNT_FAIL_CNT GENMASK(15, 0)
-+
-+#define MTK_WED_RX_ADDR_ELEM_CNT(_n) (0xf48 + (_n) * 0x4)
-+#define MTK_WED_ADDR_ELEM_SIG_FAIL_CNT GENMASK(15, 0)
-+#define MTK_WED_ADDR_ELEM_FIRST_SIG_FAIL_CNT GENMASK(31, 16)
-+#define MTK_WED_ADDR_ELEM_ACKSN_CNT GENMASK(27, 0)
-+
-+#define MTK_WED_RX_MSDU_PG_CNT(_n) (0xf5c + (_n) * 0x4)
-+
-+#define MTK_WED_RX_PN_CHK_CNT 0xf70
-+#define MTK_WED_PN_CHK_FAIL_CNT GENMASK(15, 0)
-+
- #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
- #define MTK_WED_PCIE_INT_MASK 0x0
-
-+#define MTK_WED_PCIE_BASE 0x11280000
-+#define MTK_WED_PCIE_BASE0 0x11300000
-+#define MTK_WED_PCIE_BASE1 0x11310000
-+#define MTK_WED_PCIE_BASE2 0x11290000
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -91,6 +91,8 @@ enum mtk_wed_dummy_cr_idx {
- #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
- #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
- #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
-+#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin"
-+#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin"
-
- #define MTK_WO_MCU_CFG_LS_BASE 0
- #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -139,6 +139,8 @@ struct mtk_wed_device {
- u32 wpdma_rx;
-
- bool wcid_512;
-+ bool hw_rro;
-+ bool msi;
-
- u16 token_start;
- unsigned int nbuf;
-@@ -212,10 +214,12 @@ mtk_wed_device_attach(struct mtk_wed_dev
- return ret;
- }
-
--static inline bool
--mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
-+static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
- {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ if (dev->version == 3)
-+ return dev->wlan.hw_rro;
-+
- return dev->version != 1;
- #else
- return false;
diff --git a/target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch b/target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch
deleted file mode 100644
index e91ae69d08..0000000000
--- a/target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:14 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: refactor mtk_wed_check_wfdma_rx_fill
- routine
-
-Refactor mtk_wed_check_wfdma_rx_fill() in order to be reused adding HW
-receive offload support for MT7988 SoC.
-
-Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -585,22 +585,15 @@ mtk_wed_set_512_support(struct mtk_wed_d
- }
- }
-
--#define MTK_WFMDA_RX_DMA_EN BIT(2)
--static void
--mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
-+static int
-+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev,
-+ struct mtk_wed_ring *ring)
- {
-- u32 val;
- int i;
-
-- if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED))
-- return; /* queue is not configured by mt76 */
--
- for (i = 0; i < 3; i++) {
-- u32 cur_idx;
-+ u32 cur_idx = readl(ring->wpdma + MTK_WED_RING_OFS_CPU_IDX);
-
-- cur_idx = wed_r32(dev,
-- MTK_WED_WPDMA_RING_RX_DATA(idx) +
-- MTK_WED_RING_OFS_CPU_IDX);
- if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
- break;
-
-@@ -609,12 +602,10 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_w
-
- if (i == 3) {
- dev_err(dev->hw->dev, "rx dma enable failed\n");
-- return;
-+ return -ETIMEDOUT;
- }
-
-- val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) |
-- MTK_WFMDA_RX_DMA_EN;
-- wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val);
-+ return 0;
- }
-
- static void
-@@ -1545,6 +1536,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev
- wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
- }
-
-+#define MTK_WFMDA_RX_DMA_EN BIT(2)
- static void
- mtk_wed_dma_enable(struct mtk_wed_device *dev)
- {
-@@ -1632,8 +1624,26 @@ mtk_wed_dma_enable(struct mtk_wed_device
- wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
- }
-
-- for (i = 0; i < MTK_WED_RX_QUEUES; i++)
-- mtk_wed_check_wfdma_rx_fill(dev, i);
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) {
-+ struct mtk_wed_ring *ring = &dev->rx_ring[i];
-+ u32 val;
-+
-+ if (!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue; /* queue is not configured by mt76 */
-+
-+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) {
-+ dev_err(dev->hw->dev,
-+ "rx_ring(%d) dma enable failed\n", i);
-+ continue;
-+ }
-+
-+ val = wifi_r32(dev,
-+ dev->wlan.wpdma_rx_glo -
-+ dev->wlan.phy_base) | MTK_WFMDA_RX_DMA_EN;
-+ wifi_w32(dev,
-+ dev->wlan.wpdma_rx_glo - dev->wlan.phy_base,
-+ val);
-+ }
- }
-
- static void
diff --git a/target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch b/target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch
deleted file mode 100644
index 6534d73d8e..0000000000
--- a/target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch
+++ /dev/null
@@ -1,465 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:15 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce partial AMSDU offload
- support for MT7988
-
-Introduce partial AMSDU offload support for MT7988 SoC in order to merge
-in hw packets belonging to the same AMSDU before passing them to the
-WLAN nic.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -438,7 +438,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
- }
-
- int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-- int wdma_idx, int txq, int bss, int wcid)
-+ int wdma_idx, int txq, int bss, int wcid,
-+ bool amsdu_en)
- {
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
- u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
-@@ -450,6 +451,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
- MTK_FOE_IB2_WDMA_WINFO_V2;
- l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
- FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
-+ l2->amsdu = FIELD_PREP(MTK_FOE_WINFO_AMSDU_EN, amsdu_en);
- break;
- case 2:
- *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -88,13 +88,13 @@ enum {
- #define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16)
- #define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0)
-
--#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0)
--#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16)
--#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20)
--#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21)
--#define MTK_FOE_WINFO_PAO_IS_SP BIT(22)
--#define MTK_FOE_WINFO_PAO_HF BIT(23)
--#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24)
-+#define MTK_FOE_WINFO_AMSDU_USR_INFO GENMASK(15, 0)
-+#define MTK_FOE_WINFO_AMSDU_TID GENMASK(19, 16)
-+#define MTK_FOE_WINFO_AMSDU_IS_FIXEDRATE BIT(20)
-+#define MTK_FOE_WINFO_AMSDU_IS_PRIOR BIT(21)
-+#define MTK_FOE_WINFO_AMSDU_IS_SP BIT(22)
-+#define MTK_FOE_WINFO_AMSDU_HF BIT(23)
-+#define MTK_FOE_WINFO_AMSDU_EN BIT(24)
-
- enum {
- MTK_FOE_STATE_INVALID,
-@@ -123,7 +123,7 @@ struct mtk_foe_mac_info {
-
- /* netsys_v3 */
- u32 w3info;
-- u32 wpao;
-+ u32 amsdu;
- };
-
- /* software-only entry type */
-@@ -394,7 +394,8 @@ int mtk_foe_entry_set_vlan(struct mtk_et
- int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
- int sid);
- int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
-- int wdma_idx, int txq, int bss, int wcid);
-+ int wdma_idx, int txq, int bss, int wcid,
-+ bool amsdu_en);
- int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
- unsigned int queue);
- int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -111,6 +111,7 @@ mtk_flow_get_wdma_info(struct net_device
- info->queue = path->mtk_wdma.queue;
- info->bss = path->mtk_wdma.bss;
- info->wcid = path->mtk_wdma.wcid;
-+ info->amsdu = path->mtk_wdma.amsdu;
-
- return 0;
- }
-@@ -192,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
-
- if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
- mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
-- info.bss, info.wcid);
-+ info.bss, info.wcid, info.amsdu);
- if (mtk_is_netsys_v2_or_greater(eth)) {
- switch (info.wdma_idx) {
- case 0:
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -29,6 +29,8 @@
- #define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
- #define MTK_WED_RX_RING_SIZE 1536
- #define MTK_WED_RX_PG_BM_CNT 8192
-+#define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4)
-+#define MTK_WED_AMSDU_NPAGES 32
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 1024
-@@ -172,6 +174,23 @@ mtk_wdma_rx_reset(struct mtk_wed_device
- return ret;
- }
-
-+static u32
-+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ return !!(wed_r32(dev, reg) & mask);
-+}
-+
-+static int
-+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ int sleep = 15000;
-+ int timeout = 100 * sleep;
-+ u32 val;
-+
-+ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-+ timeout, false, dev, reg, mask);
-+}
-+
- static void
- mtk_wdma_tx_reset(struct mtk_wed_device *dev)
- {
-@@ -335,6 +354,118 @@ out:
- }
-
- static int
-+mtk_wed_amsdu_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_hw *hw = dev->hw;
-+ struct mtk_wed_amsdu *wed_amsdu;
-+ int i;
-+
-+ if (!mtk_wed_is_v3_or_greater(hw))
-+ return 0;
-+
-+ wed_amsdu = devm_kcalloc(hw->dev, MTK_WED_AMSDU_NPAGES,
-+ sizeof(*wed_amsdu), GFP_KERNEL);
-+ if (!wed_amsdu)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
-+ void *ptr;
-+
-+ /* each segment is 64K */
-+ ptr = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN |
-+ __GFP_ZERO | __GFP_COMP |
-+ GFP_DMA32,
-+ get_order(MTK_WED_AMSDU_BUF_SIZE));
-+ if (!ptr)
-+ goto error;
-+
-+ wed_amsdu[i].txd = ptr;
-+ wed_amsdu[i].txd_phy = dma_map_single(hw->dev, ptr,
-+ MTK_WED_AMSDU_BUF_SIZE,
-+ DMA_TO_DEVICE);
-+ if (dma_mapping_error(hw->dev, wed_amsdu[i].txd_phy))
-+ goto error;
-+ }
-+ dev->hw->wed_amsdu = wed_amsdu;
-+
-+ return 0;
-+
-+error:
-+ for (i--; i >= 0; i--)
-+ dma_unmap_single(hw->dev, wed_amsdu[i].txd_phy,
-+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
-+ return -ENOMEM;
-+}
-+
-+static void
-+mtk_wed_amsdu_free_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
-+ int i;
-+
-+ if (!wed_amsdu)
-+ return;
-+
-+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
-+ dma_unmap_single(dev->hw->dev, wed_amsdu[i].txd_phy,
-+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
-+ free_pages((unsigned long)wed_amsdu[i].txd,
-+ get_order(MTK_WED_AMSDU_BUF_SIZE));
-+ }
-+}
-+
-+static int
-+mtk_wed_amsdu_init(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
-+ int i, ret;
-+
-+ if (!wed_amsdu)
-+ return 0;
-+
-+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++)
-+ wed_w32(dev, MTK_WED_AMSDU_HIFTXD_BASE_L(i),
-+ wed_amsdu[i].txd_phy);
-+
-+ /* init all sta parameter */
-+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO_INIT, MTK_WED_AMSDU_STA_RMVL |
-+ MTK_WED_AMSDU_STA_WTBL_HDRT_MODE |
-+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_LEN,
-+ dev->wlan.amsdu_max_len >> 8) |
-+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_NUM,
-+ dev->wlan.amsdu_max_subframes));
-+
-+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO, MTK_WED_AMSDU_STA_INFO_DO_INIT);
-+
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_AMSDU_STA_INFO,
-+ MTK_WED_AMSDU_STA_INFO_DO_INIT);
-+ if (ret) {
-+ dev_err(dev->hw->dev, "amsdu initialization failed\n");
-+ return ret;
-+ }
-+
-+ /* init partial amsdu offload txd src */
-+ wed_set(dev, MTK_WED_AMSDU_HIFTXD_CFG,
-+ FIELD_PREP(MTK_WED_AMSDU_HIFTXD_SRC, dev->hw->index));
-+
-+ /* init qmem */
-+ wed_set(dev, MTK_WED_AMSDU_PSE, MTK_WED_AMSDU_PSE_RESET);
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_MON_AMSDU_QMEM_STS1, BIT(29));
-+ if (ret) {
-+ pr_info("%s: amsdu qmem initialization failed\n", __func__);
-+ return ret;
-+ }
-+
-+ /* eagle E1 PCIE1 tx ring 22 flow control issue */
-+ if (dev->wlan.id == 0x7991)
-+ wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING);
-+
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
-+
-+ return 0;
-+}
-+
-+static int
- mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
- u32 desc_size = dev->hw->soc->tx_ring_desc_size;
-@@ -708,6 +839,7 @@ __mtk_wed_detach(struct mtk_wed_device *
-
- mtk_wdma_rx_reset(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+ mtk_wed_amsdu_free_buffer(dev);
- mtk_wed_free_tx_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-
-@@ -1128,23 +1260,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
- }
- }
-
--static u32
--mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
--{
-- return !!(wed_r32(dev, reg) & mask);
--}
--
--static int
--mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
--{
-- int sleep = 15000;
-- int timeout = 100 * sleep;
-- u32 val;
--
-- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-- timeout, false, dev, reg, mask);
--}
--
- static int
- mtk_wed_rx_reset(struct mtk_wed_device *dev)
- {
-@@ -1691,6 +1806,7 @@ mtk_wed_start(struct mtk_wed_device *dev
- }
-
- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-+ mtk_wed_amsdu_init(dev);
-
- mtk_wed_dma_enable(dev);
- dev->running = true;
-@@ -1747,6 +1863,10 @@ mtk_wed_attach(struct mtk_wed_device *de
- if (ret)
- goto out;
-
-+ ret = mtk_wed_amsdu_buffer_alloc(dev);
-+ if (ret)
-+ goto out;
-+
- if (mtk_wed_get_rx_capa(dev)) {
- ret = mtk_wed_rro_alloc(dev);
- if (ret)
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -25,6 +25,11 @@ struct mtk_wed_soc_data {
- u32 wdma_desc_size;
- };
-
-+struct mtk_wed_amsdu {
-+ void *txd;
-+ dma_addr_t txd_phy;
-+};
-+
- struct mtk_wed_hw {
- const struct mtk_wed_soc_data *soc;
- struct device_node *node;
-@@ -38,6 +43,7 @@ struct mtk_wed_hw {
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
- struct mtk_wed_wo *wed_wo;
-+ struct mtk_wed_amsdu *wed_amsdu;
- u32 pcie_base;
- u32 debugfs_reg;
- u32 num_flows;
-@@ -52,6 +58,7 @@ struct mtk_wdma_info {
- u8 queue;
- u16 wcid;
- u8 bss;
-+ u8 amsdu;
- };
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -672,6 +672,82 @@ struct mtk_wdma_desc {
- #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
- #define MTK_WED_PCIE_INT_MASK 0x0
-
-+#define MTK_WED_AMSDU_FIFO 0x1800
-+#define MTK_WED_AMSDU_IS_PRIOR0_RING BIT(10)
-+
-+#define MTK_WED_AMSDU_STA_INFO 0x01810
-+#define MTK_WED_AMSDU_STA_INFO_DO_INIT BIT(0)
-+#define MTK_WED_AMSDU_STA_INFO_SET_INIT BIT(1)
-+
-+#define MTK_WED_AMSDU_STA_INFO_INIT 0x01814
-+#define MTK_WED_AMSDU_STA_WTBL_HDRT_MODE BIT(0)
-+#define MTK_WED_AMSDU_STA_RMVL BIT(1)
-+#define MTK_WED_AMSDU_STA_MAX_AMSDU_LEN GENMASK(7, 2)
-+#define MTK_WED_AMSDU_STA_MAX_AMSDU_NUM GENMASK(11, 8)
-+
-+#define MTK_WED_AMSDU_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4)
-+
-+#define MTK_WED_AMSDU_PSE 0x1910
-+#define MTK_WED_AMSDU_PSE_RESET BIT(16)
-+
-+#define MTK_WED_AMSDU_HIFTXD_CFG 0x1968
-+#define MTK_WED_AMSDU_HIFTXD_SRC GENMASK(16, 15)
-+
-+#define MTK_WED_MON_AMSDU_FIFO_DMAD 0x1a34
-+
-+#define MTK_WED_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50)
-+#define MTK_WED_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50)
-+
-+#define MTK_WED_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50)
-+#define MTK_WED_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0)
-+#define MTK_WED_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16)
-+
-+#define MTK_WED_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50)
-+#define MTK_WED_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0)
-+#define MTK_WED_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16)
-+#define MTK_WED_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24)
-+
-+#define MTK_WED_MON_AMSDU_QMEM_STS1 0x1e04
-+
-+#define MTK_WED_MON_AMSDU_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4)
-+#define MTK_WED_AMSDU_QMEM_FQ_CNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_SP_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID0_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID1_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID2_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID3_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID4_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID5_QCNT GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID6_QCNT GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID7_QCNT GENMASK(11, 0)
-+
-+#define MTK_WED_MON_AMSDU_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4)
-+#define MTK_WED_AMSDU_QMEM_FQ_HEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_SP_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID0_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID1_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID2_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID3_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID4_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID5_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID6_QHEAD GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID7_QHEAD GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_FQ_TAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_SP_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID0_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID1_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID2_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID3_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID4_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID5_QTAIL GENMASK(11, 0)
-+#define MTK_WED_AMSDU_QMEM_TID6_QTAIL GENMASK(27, 16)
-+#define MTK_WED_AMSDU_QMEM_TID7_QTAIL GENMASK(11, 0)
-+
-+#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4)
-+
- #define MTK_WED_PCIE_BASE 0x11280000
- #define MTK_WED_PCIE_BASE0 0x11300000
- #define MTK_WED_PCIE_BASE1 0x11310000
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -928,6 +928,7 @@ struct net_device_path {
- u8 queue;
- u16 wcid;
- u8 bss;
-+ u8 amsdu;
- } mtk_wdma;
- };
- };
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -129,6 +129,7 @@ struct mtk_wed_device {
- enum mtk_wed_bus_tye bus_type;
- void __iomem *base;
- u32 phy_base;
-+ u32 id;
-
- u32 wpdma_phys;
- u32 wpdma_int;
-@@ -147,10 +148,12 @@ struct mtk_wed_device {
- unsigned int rx_nbuf;
- unsigned int rx_npkt;
- unsigned int rx_size;
-+ unsigned int amsdu_max_len;
-
- u8 tx_tbit[MTK_WED_TX_QUEUES];
- u8 rx_tbit[MTK_WED_RX_QUEUES];
- u8 txfree_tbit;
-+ u8 amsdu_max_subframes;
-
- u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
- int (*offload_enable)(struct mtk_wed_device *wed);
-@@ -224,6 +227,15 @@ static inline bool mtk_wed_get_rx_capa(s
- #else
- return false;
- #endif
-+}
-+
-+static inline bool mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev)
-+{
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ return dev->version == 3;
-+#else
-+ return false;
-+#endif
- }
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
diff --git a/target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch b/target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
deleted file mode 100644
index 0cf4c18875..0000000000
--- a/target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
+++ /dev/null
@@ -1,483 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:16 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: introduce hw_rro support for MT7988
-
-MT7988 SoC support 802.11 receive reordering offload in hw while
-MT7986 SoC implements it through the firmware running on the mcu.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -26,7 +26,7 @@
- #define MTK_WED_BUF_SIZE 2048
- #define MTK_WED_PAGE_BUF_SIZE 128
- #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
--#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
-+#define MTK_WED_RX_BUF_PER_PAGE (PAGE_SIZE / MTK_WED_PAGE_BUF_SIZE)
- #define MTK_WED_RX_RING_SIZE 1536
- #define MTK_WED_RX_PG_BM_CNT 8192
- #define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4)
-@@ -596,6 +596,68 @@ free_pagelist:
- }
-
- static int
-+mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ int n_pages = MTK_WED_RX_PG_BM_CNT / MTK_WED_RX_BUF_PER_PAGE;
-+ struct mtk_wed_buf *page_list;
-+ struct mtk_wed_bm_desc *desc;
-+ dma_addr_t desc_phys;
-+ int i, page_idx = 0;
-+
-+ if (!dev->wlan.hw_rro)
-+ return 0;
-+
-+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
-+ if (!page_list)
-+ return -ENOMEM;
-+
-+ dev->hw_rro.size = dev->wlan.rx_nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-+ dev->hw_rro.pages = page_list;
-+ desc = dma_alloc_coherent(dev->hw->dev,
-+ dev->wlan.rx_nbuf * sizeof(*desc),
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc)
-+ return -ENOMEM;
-+
-+ dev->hw_rro.desc = desc;
-+ dev->hw_rro.desc_phys = desc_phys;
-+
-+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) {
-+ dma_addr_t page_phys, buf_phys;
-+ struct page *page;
-+ int s;
-+
-+ page = __dev_alloc_page(GFP_KERNEL);
-+ if (!page)
-+ return -ENOMEM;
-+
-+ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ if (dma_mapping_error(dev->hw->dev, page_phys)) {
-+ __free_page(page);
-+ return -ENOMEM;
-+ }
-+
-+ page_list[page_idx].p = page;
-+ page_list[page_idx++].phy_addr = page_phys;
-+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+
-+ buf_phys = page_phys;
-+ for (s = 0; s < MTK_WED_RX_BUF_PER_PAGE; s++) {
-+ desc->buf0 = cpu_to_le32(buf_phys);
-+ buf_phys += MTK_WED_PAGE_BUF_SIZE;
-+ desc++;
-+ }
-+
-+ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ }
-+
-+ return 0;
-+}
-+
-+static int
- mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
- {
- struct mtk_wed_bm_desc *desc;
-@@ -612,7 +674,42 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d
- dev->rx_buf_ring.desc_phys = desc_phys;
- dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
-
-- return 0;
-+ return mtk_wed_hwrro_buffer_alloc(dev);
-+}
-+
-+static void
-+mtk_wed_hwrro_free_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_buf *page_list = dev->hw_rro.pages;
-+ struct mtk_wed_bm_desc *desc = dev->hw_rro.desc;
-+ int i, page_idx = 0;
-+
-+ if (!dev->wlan.hw_rro)
-+ return;
-+
-+ if (!page_list)
-+ return;
-+
-+ if (!desc)
-+ goto free_pagelist;
-+
-+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) {
-+ dma_addr_t buf_addr = page_list[page_idx].phy_addr;
-+ void *page = page_list[page_idx++].p;
-+
-+ if (!page)
-+ break;
-+
-+ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ __free_page(page);
-+ }
-+
-+ dma_free_coherent(dev->hw->dev, dev->hw_rro.size * sizeof(*desc),
-+ desc, dev->hw_rro.desc_phys);
-+
-+free_pagelist:
-+ kfree(page_list);
- }
-
- static void
-@@ -626,6 +723,28 @@ mtk_wed_free_rx_buffer(struct mtk_wed_de
- dev->wlan.release_rx_buf(dev);
- dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc),
- desc, dev->rx_buf_ring.desc_phys);
-+
-+ mtk_wed_hwrro_free_buffer(dev);
-+}
-+
-+static void
-+mtk_wed_hwrro_init(struct mtk_wed_device *dev)
-+{
-+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
-+ return;
-+
-+ wed_set(dev, MTK_WED_RRO_PG_BM_RX_DMAM,
-+ FIELD_PREP(MTK_WED_RRO_PG_BM_RX_SDL0, 128));
-+
-+ wed_w32(dev, MTK_WED_RRO_PG_BM_BASE, dev->hw_rro.desc_phys);
-+
-+ wed_w32(dev, MTK_WED_RRO_PG_BM_INIT_PTR,
-+ MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX |
-+ FIELD_PREP(MTK_WED_RRO_PG_BM_SW_TAIL_IDX,
-+ MTK_WED_RX_PG_BM_CNT));
-+
-+ /* enable rx_page_bm to fetch dmad */
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
- }
-
- static void
-@@ -639,6 +758,8 @@ mtk_wed_rx_buffer_hw_init(struct mtk_wed
- wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
- FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
- wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
-+
-+ mtk_wed_hwrro_init(dev);
- }
-
- static void
-@@ -934,6 +1055,8 @@ mtk_wed_bus_init(struct mtk_wed_device *
- static void
- mtk_wed_set_wpdma(struct mtk_wed_device *dev)
- {
-+ int i;
-+
- if (mtk_wed_is_v1(dev->hw)) {
- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
- return;
-@@ -951,6 +1074,15 @@ mtk_wed_set_wpdma(struct mtk_wed_device
-
- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
- wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx);
-+
-+ if (!dev->wlan.hw_rro)
-+ return;
-+
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(0), dev->wlan.wpdma_rx_rro[0]);
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(1), dev->wlan.wpdma_rx_rro[1]);
-+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++)
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING_CFG(i),
-+ dev->wlan.wpdma_rx_pg + i * 0x10);
- }
-
- static void
-@@ -1762,6 +1894,165 @@ mtk_wed_dma_enable(struct mtk_wed_device
- }
-
- static void
-+mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask, bool reset)
-+{
-+ int i;
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
-+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
-+
-+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
-+ return;
-+
-+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG,
-+ dev->wlan.rro_rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG,
-+ dev->wlan.rro_rx_tbit[1]));
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG,
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[1]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[2]));
-+
-+ /* RRO_MSDU_PG_RING2_CFG1_FLD_DRV_EN should be enabled after
-+ * WM FWDL completed, otherwise RRO_MSDU_PG ring may broken
-+ */
-+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_EN);
-+
-+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) {
-+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[i];
-+
-+ if (!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue;
-+
-+ if (mtk_wed_check_wfdma_rx_fill(dev, ring))
-+ dev_err(dev->hw->dev,
-+ "rx_rro_ring(%d) initialization failed\n", i);
-+ }
-+
-+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) {
-+ struct mtk_wed_ring *ring = &dev->rx_page_ring[i];
-+
-+ if (!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue;
-+
-+ if (mtk_wed_check_wfdma_rx_fill(dev, ring))
-+ dev_err(dev->hw->dev,
-+ "rx_page_ring(%d) initialization failed\n", i);
-+ }
-+}
-+
-+static void
-+mtk_wed_rro_rx_ring_setup(struct mtk_wed_device *dev, int idx,
-+ void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx];
-+
-+ ring->wpdma = regs;
-+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_BASE,
-+ readl(regs));
-+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+}
-+
-+static void
-+mtk_wed_msdu_pg_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx];
-+
-+ ring->wpdma = regs;
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_BASE,
-+ readl(regs));
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+}
-+
-+static int
-+mtk_wed_ind_rx_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->ind_cmd_ring;
-+ u32 val = readl(regs + MTK_WED_RING_OFS_COUNT);
-+ int i, count = 0;
-+
-+ ring->wpdma = regs;
-+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_BASE,
-+ readl(regs) & 0xfffffff0);
-+
-+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+
-+ /* ack sn cr */
-+ wed_w32(dev, MTK_WED_RRO_CFG0, dev->wlan.phy_base +
-+ dev->wlan.ind_cmd.ack_sn_addr);
-+ wed_w32(dev, MTK_WED_RRO_CFG1,
-+ FIELD_PREP(MTK_WED_RRO_CFG1_MAX_WIN_SZ,
-+ dev->wlan.ind_cmd.win_size) |
-+ FIELD_PREP(MTK_WED_RRO_CFG1_PARTICL_SE_ID,
-+ dev->wlan.ind_cmd.particular_sid));
-+
-+ /* particular session addr element */
-+ wed_w32(dev, MTK_WED_ADDR_ELEM_CFG0,
-+ dev->wlan.ind_cmd.particular_se_phys);
-+
-+ for (i = 0; i < dev->wlan.ind_cmd.se_group_nums; i++) {
-+ wed_w32(dev, MTK_WED_RADDR_ELEM_TBL_WDATA,
-+ dev->wlan.ind_cmd.addr_elem_phys[i] >> 4);
-+ wed_w32(dev, MTK_WED_ADDR_ELEM_TBL_CFG,
-+ MTK_WED_ADDR_ELEM_TBL_WR | (i & 0x7f));
-+
-+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
-+ while (!(val & MTK_WED_ADDR_ELEM_TBL_WR_RDY) && count++ < 100)
-+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
-+ if (count >= 100)
-+ dev_err(dev->hw->dev,
-+ "write ba session base failed\n");
-+ }
-+
-+ /* pn check init */
-+ for (i = 0; i < dev->wlan.ind_cmd.particular_sid; i++) {
-+ wed_w32(dev, MTK_WED_PN_CHECK_WDATA_M,
-+ MTK_WED_PN_CHECK_IS_FIRST);
-+
-+ wed_w32(dev, MTK_WED_PN_CHECK_CFG, MTK_WED_PN_CHECK_WR |
-+ FIELD_PREP(MTK_WED_PN_CHECK_SE_ID, i));
-+
-+ count = 0;
-+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
-+ while (!(val & MTK_WED_PN_CHECK_WR_RDY) && count++ < 100)
-+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
-+ if (count >= 100)
-+ dev_err(dev->hw->dev,
-+ "session(%d) initialization failed\n", i);
-+ }
-+
-+ wed_w32(dev, MTK_WED_RX_IND_CMD_CNT0, MTK_WED_RX_IND_CMD_DBG_CNT_EN);
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
-+
-+ return 0;
-+}
-+
-+static void
- mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
- {
- int i;
-@@ -2215,6 +2506,10 @@ void mtk_wed_add_hw(struct device_node *
- .detach = mtk_wed_detach,
- .ppe_check = mtk_wed_ppe_check,
- .setup_tc = mtk_wed_setup_tc,
-+ .start_hw_rro = mtk_wed_start_hw_rro,
-+ .rro_rx_ring_setup = mtk_wed_rro_rx_ring_setup,
-+ .msdu_pg_rx_ring_setup = mtk_wed_msdu_pg_rx_ring_setup,
-+ .ind_rx_ring_setup = mtk_wed_ind_rx_ring_setup,
- };
- struct device_node *eth_np = eth->dev->of_node;
- struct platform_device *pdev;
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -10,6 +10,7 @@
-
- #define MTK_WED_TX_QUEUES 2
- #define MTK_WED_RX_QUEUES 2
-+#define MTK_WED_RX_PAGE_QUEUES 3
-
- #define WED_WO_STA_REC 0x6
-
-@@ -99,6 +100,9 @@ struct mtk_wed_device {
- struct mtk_wed_ring txfree_ring;
- struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-+ struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES];
-+ struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES];
-+ struct mtk_wed_ring ind_cmd_ring;
-
- struct {
- int size;
-@@ -120,6 +124,13 @@ struct mtk_wed_device {
- dma_addr_t fdbk_phys;
- } rro;
-
-+ struct {
-+ int size;
-+ struct mtk_wed_buf *pages;
-+ struct mtk_wed_bm_desc *desc;
-+ dma_addr_t desc_phys;
-+ } hw_rro;
-+
- /* filled by driver: */
- struct {
- union {
-@@ -138,6 +149,8 @@ struct mtk_wed_device {
- u32 wpdma_txfree;
- u32 wpdma_rx_glo;
- u32 wpdma_rx;
-+ u32 wpdma_rx_rro[MTK_WED_RX_QUEUES];
-+ u32 wpdma_rx_pg;
-
- bool wcid_512;
- bool hw_rro;
-@@ -152,9 +165,20 @@ struct mtk_wed_device {
-
- u8 tx_tbit[MTK_WED_TX_QUEUES];
- u8 rx_tbit[MTK_WED_RX_QUEUES];
-+ u8 rro_rx_tbit[MTK_WED_RX_QUEUES];
-+ u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES];
- u8 txfree_tbit;
- u8 amsdu_max_subframes;
-
-+ struct {
-+ u8 se_group_nums;
-+ u16 win_size;
-+ u16 particular_sid;
-+ u32 ack_sn_addr;
-+ dma_addr_t particular_se_phys;
-+ dma_addr_t addr_elem_phys[1024];
-+ } ind_cmd;
-+
- u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
- int (*offload_enable)(struct mtk_wed_device *wed);
- void (*offload_disable)(struct mtk_wed_device *wed);
-@@ -193,6 +217,14 @@ struct mtk_wed_ops {
- void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
- int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev,
- enum tc_setup_type type, void *type_data);
-+ void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask,
-+ bool reset);
-+ void (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
-+ void (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
-+ int (*ind_rx_ring_setup)(struct mtk_wed_device *dev,
-+ void __iomem *regs);
- };
-
- extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -264,6 +296,15 @@ static inline bool mtk_wed_is_amsdu_supp
- #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
- #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \
- (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data)
-+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) \
-+ (_dev)->ops->start_hw_rro(_dev, _mask, _reset)
-+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \
-+ (_dev)->ops->ind_rx_ring_setup(_dev, _regs)
-+
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -283,6 +324,10 @@ static inline bool mtk_wed_device_active
- #define mtk_wed_device_stop(_dev) do {} while (0)
- #define mtk_wed_device_dma_reset(_dev) do {} while (0)
- #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP
-+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) do {} while (0)
-+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV
- #endif
-
- #endif
diff --git a/target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch b/target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch
deleted file mode 100644
index 5ea43a4445..0000000000
--- a/target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 18 Sep 2023 12:29:17 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: debugfs: move wed_v2 specific regs
- out of regs array
-
-Move specific WED2.0 debugfs entries out of regs array. This is a
-preliminary patch to introduce WED 3.0 debugfs info.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -151,7 +151,7 @@ DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
- static int
- wed_rxinfo_show(struct seq_file *s, void *data)
- {
-- static const struct reg_dump regs[] = {
-+ static const struct reg_dump regs_common[] = {
- DUMP_STR("WPDMA RX"),
- DUMP_WPDMA_RX_RING(0),
- DUMP_WPDMA_RX_RING(1),
-@@ -169,7 +169,7 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED_RING(WED_RING_RX_DATA(0)),
- DUMP_WED_RING(WED_RING_RX_DATA(1)),
-
-- DUMP_STR("WED RRO"),
-+ DUMP_STR("WED WO RRO"),
- DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
- DUMP_WED(WED_RROQM_MID_MIB),
- DUMP_WED(WED_RROQM_MOD_MIB),
-@@ -180,17 +180,6 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
- DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
-
-- DUMP_STR("WED Route QM"),
-- DUMP_WED(WED_RTQM_R2H_MIB(0)),
-- DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-- DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-- DUMP_WED(WED_RTQM_R2H_MIB(1)),
-- DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-- DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-- DUMP_WED(WED_RTQM_Q2N_MIB),
-- DUMP_WED(WED_RTQM_Q2B_MIB),
-- DUMP_WED(WED_RTQM_PFDBK_MIB),
--
- DUMP_STR("WED WDMA TX"),
- DUMP_WED(WED_WDMA_TX_MIB),
- DUMP_WED_RING(WED_WDMA_RING_TX),
-@@ -211,11 +200,25 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED(WED_RX_BM_INTF),
- DUMP_WED(WED_RX_BM_ERR_STS),
- };
-+ static const struct reg_dump regs_wed_v2[] = {
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_R2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2N_MIB),
-+ DUMP_WED(WED_RTQM_Q2B_MIB),
-+ DUMP_WED(WED_RTQM_PFDBK_MIB),
-+ };
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
-- if (dev)
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ if (dev) {
-+ dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common));
-+ dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
-+ }
-
- return 0;
- }
diff --git a/target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch b/target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch
deleted file mode 100644
index f491d2fd80..0000000000
--- a/target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch
+++ /dev/null
@@ -1,432 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:18 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: debugfs: add WED 3.0 debugfs entries
-
-Introduce WED3.0 debugfs entries useful for debugging.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -11,6 +11,7 @@ struct reg_dump {
- u16 offset;
- u8 type;
- u8 base;
-+ u32 mask;
- };
-
- enum {
-@@ -25,6 +26,8 @@ enum {
-
- #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
- #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
-+#define DUMP_REG_MASK(_reg, _mask) \
-+ { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask }
- #define DUMP_RING(_prefix, _base, ...) \
- { _prefix " BASE", _base, __VA_ARGS__ }, \
- { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \
-@@ -32,6 +35,7 @@ enum {
- { _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
-
- #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
-+#define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask)
- #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
-
- #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
-@@ -212,12 +216,58 @@ wed_rxinfo_show(struct seq_file *s, void
- DUMP_WED(WED_RTQM_Q2B_MIB),
- DUMP_WED(WED_RTQM_PFDBK_MIB),
- };
-+ static const struct reg_dump regs_wed_v3[] = {
-+ DUMP_STR("WED RX RRO DATA"),
-+ DUMP_WED_RING(WED_RRO_RX_D_RX(0)),
-+ DUMP_WED_RING(WED_RRO_RX_D_RX(1)),
-+
-+ DUMP_STR("WED RX MSDU PAGE"),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)),
-+
-+ DUMP_STR("WED RX IND CMD"),
-+ DUMP_WED(WED_IND_CMD_RX_CTRL1),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
-+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT),
-+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
-+ WED_IND_CMD_PREFETCH_FREE_CNT),
-+ DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID),
-+
-+ DUMP_STR("WED ADDR ELEM"),
-+ DUMP_WED(WED_ADDR_ELEM_CFG0),
-+ DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
-+ WED_ADDR_ELEM_PREFETCH_FREE_CNT),
-+
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_ERR_CNT),
-+
-+ DUMP_WED(WED_RTQM_DEQ_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_PKT_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_ERR_CNT),
-+ };
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
- if (dev) {
- dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common));
-- dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
-+ if (mtk_wed_is_v2(hw))
-+ dump_wed_regs(s, dev,
-+ regs_wed_v2, ARRAY_SIZE(regs_wed_v2));
-+ else
-+ dump_wed_regs(s, dev,
-+ regs_wed_v3, ARRAY_SIZE(regs_wed_v3));
- }
-
- return 0;
-@@ -225,6 +275,314 @@ wed_rxinfo_show(struct seq_file *s, void
- DEFINE_SHOW_ATTRIBUTE(wed_rxinfo);
-
- static int
-+wed_amsdu_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("WED AMDSU INFO"),
-+ DUMP_WED(WED_MON_AMSDU_FIFO_DMAD),
-+
-+ DUMP_STR("WED AMDSU ENG0 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(0)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(0)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG1 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(1)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(1)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG2 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(2)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(2)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG3 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(3)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(3)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG4 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(4)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(4)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG5 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(5)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(5)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG6 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(6)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(6)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG7 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(7)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(7)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED AMDSU ENG8 INFO"),
-+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(8)),
-+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(8)),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
-+ WED_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
-+ WED_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
-+ WED_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
-+ WED_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
-+ WED_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("WED QMEM INFO"),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_FQ_CNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_SP_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID0_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID1_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID2_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID3_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID4_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID5_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID6_QCNT),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID7_QCNT),
-+
-+ DUMP_STR("WED QMEM HEAD INFO"),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_FQ_HEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_SP_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID0_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID1_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID2_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID3_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID4_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID5_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID6_QHEAD),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID7_QHEAD),
-+
-+ DUMP_STR("WED QMEM TAIL INFO"),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_FQ_TAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_SP_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID0_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID1_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID2_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID3_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID4_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID5_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID6_QTAIL),
-+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID7_QTAIL),
-+
-+ DUMP_STR("WED HIFTXD MSDU INFO"),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(1)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(2)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(3)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(4)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(5)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(6)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(7)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(8)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(9)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(10)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(11)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(12)),
-+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(13)),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_amsdu);
-+
-+static int
-+wed_rtqm_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"),
-+ DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS1(Legacy)"),
-+ DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS2(RRO3.0)"),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS3(DEBUG)"),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rtqm);
-+
-+static int
-+wed_rro_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs[] = {
-+ DUMP_STR("RRO/IND CMD CNT"),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(1)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(2)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(3)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(4)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(5)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(6)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(7)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(8)),
-+ DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9),
-+ WED_IND_CMD_MAGIC_CNT_FAIL_CNT),
-+
-+ DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)),
-+ DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1),
-+ WED_ADDR_ELEM_SIG_FAIL_CNT),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(1)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(2)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(3)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(4)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(5)),
-+ DUMP_WED_MASK(WED_RX_PN_CHK_CNT,
-+ WED_PN_CHK_FAIL_CNT),
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (dev)
-+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rro);
-+
-+static int
- mtk_wed_reg_set(void *data, u64 val)
- {
- struct mtk_wed_hw *hw = data;
-@@ -266,7 +624,16 @@ void mtk_wed_hw_add_debugfs(struct mtk_w
- debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
- debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
- debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-- if (!mtk_wed_is_v1(hw))
-+ if (!mtk_wed_is_v1(hw)) {
- debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
- &wed_rxinfo_fops);
-+ if (mtk_wed_is_v3_or_greater(hw)) {
-+ debugfs_create_file_unsafe("amsdu", 0400, dir, hw,
-+ &wed_amsdu_fops);
-+ debugfs_create_file_unsafe("rtqm", 0400, dir, hw,
-+ &wed_rtqm_fops);
-+ debugfs_create_file_unsafe("rro", 0400, dir, hw,
-+ &wed_rro_fops);
-+ }
-+ }
- }
diff --git a/target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch b/target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch
deleted file mode 100644
index aaaabf05e8..0000000000
--- a/target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch
+++ /dev/null
@@ -1,587 +0,0 @@
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 12:29:19 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: add wed 3.0 reset support
-
-Introduce support for resetting Wireless Ethernet Dispatcher 3.0
-available on MT988 SoC.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -148,6 +148,90 @@ mtk_wdma_read_reset(struct mtk_wed_devic
- return wdma_r32(dev, MTK_WDMA_GLO_CFG);
- }
-
-+static void
-+mtk_wdma_v3_rx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status;
-+
-+ if (!mtk_wed_is_v3_or_greater(dev->hw))
-+ return;
-+
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG))
-+ dev_err(dev->hw->dev, "rx reset failed\n");
-+
-+ /* prefetch FIFO */
-+ wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
-+
-+ /* core FIFO */
-+ wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG,
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG,
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
-+
-+ /* writeback FIFO */
-+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+
-+ /* prefetch ring status */
-+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
-+
-+ /* writeback ring status */
-+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
-+}
-+
- static int
- mtk_wdma_rx_reset(struct mtk_wed_device *dev)
- {
-@@ -160,6 +244,7 @@ mtk_wdma_rx_reset(struct mtk_wed_device
- if (ret)
- dev_err(dev->hw->dev, "rx reset failed\n");
-
-+ mtk_wdma_v3_rx_reset(dev);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-@@ -192,6 +277,84 @@ mtk_wed_poll_busy(struct mtk_wed_device
- }
-
- static void
-+mtk_wdma_v3_tx_reset(struct mtk_wed_device *dev)
-+{
-+ u32 status;
-+
-+ if (!mtk_wed_is_v3_or_greater(dev->hw))
-+ return;
-+
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ if (read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY),
-+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG))
-+ dev_err(dev->hw->dev, "tx reset failed\n");
-+
-+ /* prefetch FIFO */
-+ wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
-+
-+ /* core FIFO */
-+ wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG,
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG,
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
-+
-+ /* writeback FIFO */
-+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1),
-+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+
-+ /* prefetch ring status */
-+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG,
-+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
-+
-+ /* writeback ring status */
-+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG,
-+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
-+}
-+
-+static void
- mtk_wdma_tx_reset(struct mtk_wed_device *dev)
- {
- u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
-@@ -202,6 +365,7 @@ mtk_wdma_tx_reset(struct mtk_wed_device
- !(status & mask), 0, 10000))
- dev_err(dev->hw->dev, "tx reset failed\n");
-
-+ mtk_wdma_v3_tx_reset(dev);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-@@ -1405,13 +1569,33 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- if (ret)
- return ret;
-
-+ if (dev->wlan.hw_rro) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS,
-+ MTK_WED_RX_IND_CMD_BUSY);
-+ mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG);
-+ }
-+
- wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
- MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
-+ if (!ret && mtk_wed_is_v3_or_greater(dev->hw))
-+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_BUSY);
- if (ret) {
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
- } else {
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* 1.a. disable prefetch HW */
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_BUSY);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL);
-+ }
-+
- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
- MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
- MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-@@ -1439,23 +1623,52 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
- }
-
-+ if (dev->wlan.hw_rro) {
-+ /* disable rro msdu page drv */
-+ wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_EN);
-+
-+ /* disable rro data drv */
-+ wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
-+
-+ /* rro msdu page drv reset */
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+
-+ /* rro data drv reset */
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2),
-+ MTK_WED_RRO_RX_D_DRV_CLR);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2),
-+ MTK_WED_RRO_RX_D_DRV_CLR);
-+ }
-+
- /* reset route qm */
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
- ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
-- if (ret)
-+ if (ret) {
- mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
-- else
-- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-- MTK_WED_RTQM_Q_RST);
-+ } else if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ wed_set(dev, MTK_WED_RTQM_RST, BIT(0));
-+ wed_clr(dev, MTK_WED_RTQM_RST, BIT(0));
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
-+ } else {
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ }
-
- /* reset tx wdma */
- mtk_wdma_tx_reset(dev);
-
- /* reset tx wdma drv */
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
-- mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS,
-+ MTK_WED_WPDMA_STATUS_TX_DRV);
-+ else
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
-
- /* reset wed rx dma */
-@@ -1476,6 +1689,14 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- MTK_WED_CTRL_WED_RX_BM_BUSY);
- mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
-
-+ if (dev->wlan.hw_rro) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_RX_PG_BM_BUSY);
-+ wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
-+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
-+ }
-+
- /* wo change to enable state */
- val = MTK_WED_WO_STATE_ENABLE;
- ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
-@@ -1493,6 +1714,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *
- false);
- }
- mtk_wed_free_rx_buffer(dev);
-+ mtk_wed_hwrro_free_buffer(dev);
-
- return 0;
- }
-@@ -1526,15 +1748,41 @@ mtk_wed_reset_dma(struct mtk_wed_device
-
- /* 2. reset WDMA rx DMA */
- busy = !!mtk_wdma_rx_reset(dev);
-- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ val = MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE |
-+ wed_r32(dev, MTK_WED_WDMA_GLO_CFG);
-+ val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN;
-+ wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val);
-+ } else {
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ }
-+
- if (!busy)
- busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
-+ if (!busy && mtk_wed_is_v3_or_greater(dev->hw))
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_BUSY);
-
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
- } else {
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* 1.a. disable prefetch HW */
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_BUSY);
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
-+
-+ /* 2. Reset dma index */
-+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
-+ MTK_WED_WDMA_RESET_IDX_RX_ALL);
-+ }
-+
- wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
- MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV);
- wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0);
-@@ -1550,8 +1798,13 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
- for (i = 0; i < 100; i++) {
-- val = wed_r32(dev, MTK_WED_TX_BM_INTF);
-- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
-+ if (mtk_wed_is_v1(dev->hw))
-+ val = FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP,
-+ wed_r32(dev, MTK_WED_TX_BM_INTF));
-+ else
-+ val = FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP,
-+ wed_r32(dev, MTK_WED_TX_TKID_INTF));
-+ if (val == 0x40)
- break;
- }
-
-@@ -1573,6 +1826,8 @@ mtk_wed_reset_dma(struct mtk_wed_device
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV);
-+ if (mtk_wed_is_v3_or_greater(dev->hw))
-+ wed_w32(dev, MTK_WED_RX1_CTRL2, 0);
- } else {
- wed_w32(dev, MTK_WED_WPDMA_RESET_IDX,
- MTK_WED_WPDMA_RESET_IDX_TX |
-@@ -1589,7 +1844,14 @@ mtk_wed_reset_dma(struct mtk_wed_device
- wed_w32(dev, MTK_WED_RESET_IDX, 0);
- }
-
-- mtk_wed_rx_reset(dev);
-+ if (mtk_wed_is_v3_or_greater(dev->hw)) {
-+ /* reset amsdu engine */
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
-+ mtk_wed_reset(dev, MTK_WED_RESET_TX_AMSDU);
-+ }
-+
-+ if (mtk_wed_get_rx_capa(dev))
-+ mtk_wed_rx_reset(dev);
- }
-
- static int
-@@ -1841,6 +2103,7 @@ mtk_wed_dma_enable(struct mtk_wed_device
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
-
- wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
- }
-
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-@@ -1904,6 +2167,12 @@ mtk_wed_start_hw_rro(struct mtk_wed_devi
- if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
- return;
-
-+ if (reset) {
-+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_EN);
-+ return;
-+ }
-+
- wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
- wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
- MTK_WED_RRO_MSDU_PG_DRV_CLR);
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -28,6 +28,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET 0x008
- #define MTK_WED_RESET_TX_BM BIT(0)
- #define MTK_WED_RESET_RX_BM BIT(1)
-+#define MTK_WED_RESET_RX_PG_BM BIT(2)
-+#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3)
- #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
- #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
- #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
-@@ -106,6 +108,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-
-+#define MTK_WED_WPDMA_STATUS 0x068
-+#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8)
-+
- #define MTK_WED_TX_BM_CTRL 0x080
- #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
- #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-@@ -140,6 +145,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16)
- #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
-
-+#define MTK_WED_TX_TKID_INTF 0x0dc
-+#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16)
-+
- #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0)
- #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16)
-
-@@ -190,6 +198,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
-
- #define MTK_WED_SCR0 0x3c0
-+#define MTK_WED_RX1_CTRL2 0x418
- #define MTK_WED_WPDMA_INT_TRIGGER 0x504
- #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
- #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
-@@ -303,6 +312,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
- #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
-+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20)
- #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-
- #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
-@@ -313,6 +323,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
- #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1)
- #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
- #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
-
-@@ -334,11 +345,13 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WDMA_RX_PREF_CFG 0x950
- #define MTK_WED_WDMA_RX_PREF_EN BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1)
- #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
- #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
- #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
- #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
- #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
-+#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27)
-
- #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
- #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
-@@ -367,6 +380,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WDMA_RESET_IDX 0xa08
- #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
-+#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20)
- #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
-
- #define MTK_WED_WDMA_INT_CLR 0xa24
-@@ -437,21 +451,62 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30)
- #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31)
-
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12)
-+
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21)
-+
- #define MTK_WDMA_INT_GRP1 0x250
- #define MTK_WDMA_INT_GRP2 0x254
-
- #define MTK_WDMA_PREF_TX_CFG 0x2d0
- #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
-+#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1)
-
- #define MTK_WDMA_PREF_RX_CFG 0x2dc
- #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
-+#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1)
-+
-+#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0
-+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0)
-+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16)
-+
-+#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4
-+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0)
-+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16)
-+
-+#define MTK_WDMA_PREF_SIDX_CFG 0x2e4
-+#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
-+#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
-
- #define MTK_WDMA_WRBK_TX_CFG 0x300
-+#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0)
- #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
-
-+#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4)
-+#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0)
-+
- #define MTK_WDMA_WRBK_RX_CFG 0x344
-+#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0)
- #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
-
-+#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4)
-+#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0)
-+
-+#define MTK_WDMA_WRBK_SIDX_CFG 0x388
-+#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
-+#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
-+
- #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
- #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
- #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
-@@ -465,6 +520,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
- #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-
-+#define MTK_WED_RTQM_RST 0xb04
-+
- #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
- #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
- #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
-@@ -653,6 +710,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
- #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
-
-+#define MTK_WED_RRO_RX_HW_STS 0xf00
-+#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0)
-+
- #define MTK_WED_RX_IND_CMD_CNT0 0xf20
- #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
-
diff --git a/target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch b/target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch
deleted file mode 100644
index 32ac37e8d0..0000000000
--- a/target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 038ba1dc4e54d51d953f5618d8eb5dd39bd9de25 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 13 Feb 2024 14:35:51 +0100
-Subject: [PATCH] net: phy: aquantia: add AQR111 and AQR111B0 PHY ID
-
-Add Aquantia AQR111 and AQR111B0 PHY ID. These PHY advertise 10G speed
-but actually supports up to 5G speed, hence some manual fixup is needed.
-
-The Aquantia AQR111B0 PHY is just a variant of the AQR111 with smaller
-chip size.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240213133558.1836-1-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/aquantia/aquantia_main.c | 52 ++++++++++++++++++++++++
- 1 file changed, 52 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -22,6 +22,8 @@
- #define PHY_ID_AQR107 0x03a1b4e0
- #define PHY_ID_AQCS109 0x03a1b5c2
- #define PHY_ID_AQR405 0x03a1b4b0
-+#define PHY_ID_AQR111 0x03a1b610
-+#define PHY_ID_AQR111B0 0x03a1b612
- #define PHY_ID_AQR113C 0x31c31c12
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
-@@ -670,6 +672,16 @@ static int aqr107_probe(struct phy_devic
- return aqr_hwmon_probe(phydev);
- }
-
-+static int aqr111_config_init(struct phy_device *phydev)
-+{
-+ /* AQR111 reports supporting speed up to 10G,
-+ * however only speeds up to 5G are supported.
-+ */
-+ phy_set_max_speed(phydev, SPEED_5000);
-+
-+ return aqr107_config_init(phydev);
-+}
-+
- static struct phy_driver aqr_driver[] = {
- {
- PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
-@@ -744,6 +756,44 @@ static struct phy_driver aqr_driver[] =
- .link_change_notify = aqr107_link_change_notify,
- },
- {
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111),
-+ .name = "Aquantia AQR111",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr111_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),
-+ .name = "Aquantia AQR111B0",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr111_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
- PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
- .name = "Aquantia AQR405",
- .config_aneg = aqr_config_aneg,
-@@ -782,6 +832,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
- { }
- };
diff --git a/target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch b/target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch
deleted file mode 100644
index 073bbbd49d..0000000000
--- a/target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 71b605d32017e5b8d257db7344bc2f8e8fcc973e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 15 Feb 2024 16:30:05 +0100
-Subject: [PATCH] net: phy: aquantia: add AQR113 PHY ID
-
-Add Aquantia AQR113 PHY ID. Aquantia AQR113 is just a chip size variant of
-the already supported AQR133C where the only difference is the PHY ID
-and the hw chip size.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -24,6 +24,7 @@
- #define PHY_ID_AQR405 0x03a1b4b0
- #define PHY_ID_AQR111 0x03a1b610
- #define PHY_ID_AQR111B0 0x03a1b612
-+#define PHY_ID_AQR113 0x31c31c40
- #define PHY_ID_AQR113C 0x31c31c12
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
-@@ -802,6 +803,25 @@ static struct phy_driver aqr_driver[] =
- .read_status = aqr_read_status,
- },
- {
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113),
-+ .name = "Aquantia AQR113",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
-+{
- PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
- .name = "Aquantia AQR113C",
- .probe = aqr107_probe,
-@@ -834,6 +854,7 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
- { }
- };
diff --git a/target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch b/target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch
deleted file mode 100644
index 965b8c91b2..0000000000
--- a/target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 6d47302a3f0ba31445478d518d98bd55918bc8ab Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 15 Feb 2024 22:43:30 +0100
-Subject: [PATCH] net: phy: aquantia: add AQR813 PHY ID
-
-Aquantia AQR813 is the Octal Port variant of the AQR113. Add PHY ID for
-it to provide support for it.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -26,6 +26,7 @@
- #define PHY_ID_AQR111B0 0x03a1b612
- #define PHY_ID_AQR113 0x31c31c40
- #define PHY_ID_AQR113C 0x31c31c12
-+#define PHY_ID_AQR813 0x31c31cb2
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -840,6 +841,25 @@ static struct phy_driver aqr_driver[] =
- .get_stats = aqr107_get_stats,
- .link_change_notify = aqr107_link_change_notify,
- },
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
-+ .name = "Aquantia AQR813",
-+ .probe = aqr107_probe,
-+ .get_rate_matching = aqr107_get_rate_matching,
-+ .config_init = aqr107_config_init,
-+ .config_aneg = aqr_config_aneg,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_tunable = aqr107_get_tunable,
-+ .set_tunable = aqr107_set_tunable,
-+ .suspend = aqr107_suspend,
-+ .resume = aqr107_resume,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+ .link_change_notify = aqr107_link_change_notify,
-+},
- };
-
- module_phy_driver(aqr_driver);
-@@ -856,6 +876,7 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
- { }
- };
-
diff --git a/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch b/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch
deleted file mode 100644
index 4cef7194eb..0000000000
--- a/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From f13b2b33c7674fa0988dfaa9adb95d7d912b489f Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 10 Apr 2024 20:42:38 +0100
-Subject: [PATCH 1/2] net: dsa: introduce dsa_phylink_to_port()
-
-We convert from a phylink_config struct to a dsa_port struct in many
-places, let's provide a helper for this.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/E1rudqA-006K9B-85@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/net/dsa.h | 6 ++++++
- net/dsa/port.c | 12 ++++++------
- 2 files changed, 12 insertions(+), 6 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -337,6 +337,12 @@ struct dsa_port {
- struct list_head vlans;
- };
-
-+static inline struct dsa_port *
-+dsa_phylink_to_port(struct phylink_config *config)
-+{
-+ return container_of(config, struct dsa_port, pl_config);
-+}
-+
- /* TODO: ideally DSA ports would have a single dp->link_dp member,
- * and no dst->rtable nor this struct dsa_link would be needed,
- * but this would require some more complex tree walking,
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1552,7 +1552,7 @@ static void dsa_port_phylink_validate(st
- unsigned long *supported,
- struct phylink_link_state *state)
- {
-- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
- struct dsa_switch *ds = dp->ds;
-
- if (!ds->ops->phylink_validate) {
-@@ -1567,7 +1567,7 @@ static void dsa_port_phylink_validate(st
- static void dsa_port_phylink_mac_pcs_get_state(struct phylink_config *config,
- struct phylink_link_state *state)
- {
-- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
- struct dsa_switch *ds = dp->ds;
- int err;
-
-@@ -1589,7 +1589,7 @@ static struct phylink_pcs *
- dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
- phy_interface_t interface)
- {
-- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
- struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
- struct dsa_switch *ds = dp->ds;
-
-@@ -1603,7 +1603,7 @@ static void dsa_port_phylink_mac_config(
- unsigned int mode,
- const struct phylink_link_state *state)
- {
-- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
- struct dsa_switch *ds = dp->ds;
-
- if (!ds->ops->phylink_mac_config)
-@@ -1614,7 +1614,7 @@ static void dsa_port_phylink_mac_config(
-
- static void dsa_port_phylink_mac_an_restart(struct phylink_config *config)
- {
-- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
- struct dsa_switch *ds = dp->ds;
-
- if (!ds->ops->phylink_mac_an_restart)
-@@ -1627,7 +1627,7 @@ static void dsa_port_phylink_mac_link_do
- unsigned int mode,
- phy_interface_t interface)
- {
-- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
- struct phy_device *phydev = NULL;
- struct dsa_switch *ds = dp->ds;
-
-@@ -1650,7 +1650,7 @@ static void dsa_port_phylink_mac_link_up
- int speed, int duplex,
- bool tx_pause, bool rx_pause)
- {
-- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
- struct dsa_switch *ds = dp->ds;
-
- if (!ds->ops->phylink_mac_link_up) {
diff --git a/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch b/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch
deleted file mode 100644
index 0119925ab0..0000000000
--- a/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 10 Apr 2024 20:42:43 +0100
-Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own
- phylink mac ops
-
-Rather than having a shim for each and every phylink MAC operation,
-allow DSA switch drivers to provide their own ops structure. When a
-DSA driver provides the phylink MAC operations, the shimmed ops must
-not be provided, so fail an attempt to register a switch with both
-the phylink_mac_ops in struct dsa_switch and the phylink_mac_*
-operations populated in dsa_switch_ops populated.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/net/dsa.h | 5 +++++
- net/dsa/dsa.c | 11 +++++++++++
- net/dsa/port.c | 26 ++++++++++++++++++++------
- 3 files changed, 36 insertions(+), 6 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -468,6 +468,11 @@ struct dsa_switch {
- const struct dsa_switch_ops *ops;
-
- /*
-+ * Allow a DSA switch driver to override the phylink MAC ops
-+ */
-+ const struct phylink_mac_ops *phylink_mac_ops;
-+
-+ /*
- * Slave mii_bus and devices for the individual ports.
- */
- u32 phys_mii_mask;
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -1675,6 +1675,7 @@ static const struct phylink_mac_ops dsa_
-
- int dsa_port_phylink_create(struct dsa_port *dp)
- {
-+ const struct phylink_mac_ops *mac_ops;
- struct dsa_switch *ds = dp->ds;
- phy_interface_t mode;
- struct phylink *pl;
-@@ -1694,8 +1695,12 @@ int dsa_port_phylink_create(struct dsa_p
- if (ds->ops->phylink_get_caps)
- ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
-
-- pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
-- mode, &dsa_port_phylink_mac_ops);
-+ mac_ops = &dsa_port_phylink_mac_ops;
-+ if (ds->phylink_mac_ops)
-+ mac_ops = ds->phylink_mac_ops;
-+
-+ pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
-+ mac_ops);
- if (IS_ERR(pl)) {
- pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
- return PTR_ERR(pl);
-@@ -1961,12 +1966,23 @@ static void dsa_shared_port_validate_of(
- dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
- }
-
-+static void dsa_shared_port_link_down(struct dsa_port *dp)
-+{
-+ struct dsa_switch *ds = dp->ds;
-+
-+ if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
-+ ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
-+ PHY_INTERFACE_MODE_NA);
-+ else if (ds->ops->phylink_mac_link_down)
-+ ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
-+ PHY_INTERFACE_MODE_NA);
-+}
-+
- int dsa_shared_port_link_register_of(struct dsa_port *dp)
- {
- struct dsa_switch *ds = dp->ds;
- bool missing_link_description;
- bool missing_phy_mode;
-- int port = dp->index;
-
- dsa_shared_port_validate_of(dp, &missing_phy_mode,
- &missing_link_description);
-@@ -1982,9 +1998,7 @@ int dsa_shared_port_link_register_of(str
- "Skipping phylink registration for %s port %d\n",
- dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
- } else {
-- if (ds->ops->phylink_mac_link_down)
-- ds->ops->phylink_mac_link_down(ds, port,
-- MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
-+ dsa_shared_port_link_down(dp);
-
- return dsa_shared_port_phylink_register(dp);
- }
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -1758,6 +1758,15 @@ static int dsa_switch_probe(struct dsa_s
- if (!ds->num_ports)
- return -EINVAL;
-
-+ if (ds->phylink_mac_ops) {
-+ if (ds->ops->phylink_mac_select_pcs ||
-+ ds->ops->phylink_mac_config ||
-+ ds->ops->phylink_mac_link_down ||
-+ ds->ops->phylink_mac_link_up ||
-+ ds->ops->adjust_link)
-+ return -EINVAL;
-+ }
-+
- if (np) {
- err = dsa_switch_parse_of(ds, np);
- if (err)
diff --git a/target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch b/target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch
deleted file mode 100644
index 789b93e9f9..0000000000
--- a/target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 7f3eb2174512fe6c9c0f062e96eccb0d3cc6d5cd Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 18 Oct 2023 14:35:47 +0200
-Subject: [PATCH] net: introduce napi_is_scheduled helper
-
-We currently have napi_if_scheduled_mark_missed that can be used to
-check if napi is scheduled but that does more thing than simply checking
-it and return a bool. Some driver already implement custom function to
-check if napi is scheduled.
-
-Drop these custom function and introduce napi_is_scheduled that simply
-check if napi is scheduled atomically.
-
-Update any driver and code that implement a similar check and instead
-use this new helper.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/chelsio/cxgb3/sge.c | 8 --------
- drivers/net/wireless/realtek/rtw89/core.c | 2 +-
- include/linux/netdevice.h | 23 +++++++++++++++++++++++
- net/core/dev.c | 2 +-
- 4 files changed, 25 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/chelsio/cxgb3/sge.c
-+++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c
-@@ -2507,14 +2507,6 @@ static int napi_rx_handler(struct napi_s
- return work_done;
- }
-
--/*
-- * Returns true if the device is already scheduled for polling.
-- */
--static inline int napi_is_scheduled(struct napi_struct *napi)
--{
-- return test_bit(NAPI_STATE_SCHED, &napi->state);
--}
--
- /**
- * process_pure_responses - process pure responses from a response queue
- * @adap: the adapter
---- a/drivers/net/wireless/realtek/rtw89/core.c
-+++ b/drivers/net/wireless/realtek/rtw89/core.c
-@@ -1479,7 +1479,7 @@ static void rtw89_core_rx_to_mac80211(st
- struct napi_struct *napi = &rtwdev->napi;
-
- /* In low power mode, napi isn't scheduled. Receive it to netif. */
-- if (unlikely(!test_bit(NAPI_STATE_SCHED, &napi->state)))
-+ if (unlikely(!napi_is_scheduled(napi)))
- napi = NULL;
-
- rtw89_core_hw_to_sband_rate(rx_status);
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -468,6 +468,29 @@ static inline bool napi_prefer_busy_poll
- return test_bit(NAPI_STATE_PREFER_BUSY_POLL, &n->state);
- }
-
-+/**
-+ * napi_is_scheduled - test if NAPI is scheduled
-+ * @n: NAPI context
-+ *
-+ * This check is "best-effort". With no locking implemented,
-+ * a NAPI can be scheduled or terminate right after this check
-+ * and produce not precise results.
-+ *
-+ * NAPI_STATE_SCHED is an internal state, napi_is_scheduled
-+ * should not be used normally and napi_schedule should be
-+ * used instead.
-+ *
-+ * Use only if the driver really needs to check if a NAPI
-+ * is scheduled for example in the context of delayed timer
-+ * that can be skipped if a NAPI is already scheduled.
-+ *
-+ * Return True if NAPI is scheduled, False otherwise.
-+ */
-+static inline bool napi_is_scheduled(struct napi_struct *n)
-+{
-+ return test_bit(NAPI_STATE_SCHED, &n->state);
-+}
-+
- bool napi_schedule_prep(struct napi_struct *n);
-
- /**
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -6533,7 +6533,7 @@ static int __napi_poll(struct napi_struc
- * accidentally calling ->poll() when NAPI is not scheduled.
- */
- work = 0;
-- if (test_bit(NAPI_STATE_SCHED, &n->state)) {
-+ if (napi_is_scheduled(n)) {
- work = n->poll(n, weight);
- trace_napi_poll(n, work, weight);
- }
diff --git a/target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch b/target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch
deleted file mode 100644
index aa0d730bc8..0000000000
--- a/target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 2d1a42cf7f77cda54dbbee18d00b1200e7bc22aa Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 18 Oct 2023 14:35:48 +0200
-Subject: [PATCH 1/3] net: stmmac: improve TX timer arm logic
-
-There is currently a problem with the TX timer getting armed multiple
-unnecessary times causing big performance regression on some device that
-suffer from heavy handling of hrtimer rearm.
-
-The use of the TX timer is an old implementation that predates the napi
-implementation and the interrupt enable/disable handling.
-
-Due to stmmac being a very old code, the TX timer was never evaluated
-again with this new implementation and was kept there causing
-performance regression. The performance regression started to appear
-with kernel version 4.19 with 8fce33317023 ("net: stmmac: Rework coalesce
-timer and fix multi-queue races") where the timer was reduced to 1ms
-causing it to be armed 40 times more than before.
-
-Decreasing the timer made the problem more present and caused the
-regression in the other of 600-700mbps on some device (regression where
-this was notice is ipq806x).
-
-The problem is in the fact that handling the hrtimer on some target is
-expensive and recent kernel made the timer armed much more times.
-A solution that was proposed was reverting the hrtimer change and use
-mod_timer but such solution would still hide the real problem in the
-current implementation.
-
-To fix the regression, apply some additional logic and skip arming the
-timer when not needed.
-
-Arm the timer ONLY if a napi is not already scheduled. Running the timer
-is redundant since the same function (stmmac_tx_clean) will run in the
-napi TX poll. Also try to cancel any timer if a napi is scheduled to
-prevent redundant run of TX call.
-
-With the following new logic the original performance are restored while
-keeping using the hrtimer.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -2974,13 +2974,25 @@ static void stmmac_tx_timer_arm(struct s
- {
- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- u32 tx_coal_timer = priv->tx_coal_timer[queue];
-+ struct stmmac_channel *ch;
-+ struct napi_struct *napi;
-
- if (!tx_coal_timer)
- return;
-
-- hrtimer_start(&tx_q->txtimer,
-- STMMAC_COAL_TIMER(tx_coal_timer),
-- HRTIMER_MODE_REL);
-+ ch = &priv->channel[tx_q->queue_index];
-+ napi = tx_q->xsk_pool ? &ch->rxtx_napi : &ch->tx_napi;
-+
-+ /* Arm timer only if napi is not already scheduled.
-+ * Try to cancel any timer if napi is scheduled, timer will be armed
-+ * again in the next scheduled napi.
-+ */
-+ if (unlikely(!napi_is_scheduled(napi)))
-+ hrtimer_start(&tx_q->txtimer,
-+ STMMAC_COAL_TIMER(tx_coal_timer),
-+ HRTIMER_MODE_REL);
-+ else
-+ hrtimer_try_to_cancel(&tx_q->txtimer);
- }
-
- /**
diff --git a/target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch b/target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch
deleted file mode 100644
index 8736120654..0000000000
--- a/target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From a594166387fe08e6f5a32130c400249a35b298f9 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 18 Oct 2023 14:35:49 +0200
-Subject: [PATCH 2/3] net: stmmac: move TX timer arm after DMA enable
-
-Move TX timer arm call after DMA interrupt is enabled again.
-
-The TX timer arm function changed logic and now is skipped if a napi is
-already scheduled. By moving the TX timer arm call after DMA is enabled,
-we permit to correctly skip if a DMA interrupt has been fired and a napi
-has been scheduled again.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 +++++++++++++++----
- 1 file changed, 18 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -2527,9 +2527,13 @@ static void stmmac_bump_dma_threshold(st
- * @priv: driver private structure
- * @budget: napi budget limiting this functions packet handling
- * @queue: TX queue index
-+ * @pending_packets: signal to arm the TX coal timer
- * Description: it reclaims the transmit resources after transmission completes.
-+ * If some packets still needs to be handled, due to TX coalesce, set
-+ * pending_packets to true to make NAPI arm the TX coal timer.
- */
--static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
-+static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
-+ bool *pending_packets)
- {
- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
- unsigned int bytes_compl = 0, pkts_compl = 0;
-@@ -2692,7 +2696,7 @@ static int stmmac_tx_clean(struct stmmac
-
- /* We still have pending packets, let's call for a new scheduling */
- if (tx_q->dirty_tx != tx_q->cur_tx)
-- stmmac_tx_timer_arm(priv, queue);
-+ *pending_packets = true;
-
- __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue));
-
-@@ -5490,12 +5494,13 @@ static int stmmac_napi_poll_tx(struct na
- struct stmmac_channel *ch =
- container_of(napi, struct stmmac_channel, tx_napi);
- struct stmmac_priv *priv = ch->priv_data;
-+ bool pending_packets = false;
- u32 chan = ch->index;
- int work_done;
-
- priv->xstats.napi_poll++;
-
-- work_done = stmmac_tx_clean(priv, budget, chan);
-+ work_done = stmmac_tx_clean(priv, budget, chan, &pending_packets);
- work_done = min(work_done, budget);
-
- if (work_done < budget && napi_complete_done(napi, work_done)) {
-@@ -5506,6 +5511,10 @@ static int stmmac_napi_poll_tx(struct na
- spin_unlock_irqrestore(&ch->lock, flags);
- }
-
-+ /* TX still have packet to handle, check if we need to arm tx timer */
-+ if (pending_packets)
-+ stmmac_tx_timer_arm(priv, chan);
-+
- return work_done;
- }
-
-@@ -5514,12 +5523,13 @@ static int stmmac_napi_poll_rxtx(struct
- struct stmmac_channel *ch =
- container_of(napi, struct stmmac_channel, rxtx_napi);
- struct stmmac_priv *priv = ch->priv_data;
-+ bool tx_pending_packets = false;
- int rx_done, tx_done, rxtx_done;
- u32 chan = ch->index;
-
- priv->xstats.napi_poll++;
-
-- tx_done = stmmac_tx_clean(priv, budget, chan);
-+ tx_done = stmmac_tx_clean(priv, budget, chan, &tx_pending_packets);
- tx_done = min(tx_done, budget);
-
- rx_done = stmmac_rx_zc(priv, budget, chan);
-@@ -5544,6 +5554,10 @@ static int stmmac_napi_poll_rxtx(struct
- spin_unlock_irqrestore(&ch->lock, flags);
- }
-
-+ /* TX still have packet to handle, check if we need to arm tx timer */
-+ if (tx_pending_packets)
-+ stmmac_tx_timer_arm(priv, chan);
-+
- return min(rxtx_done, budget - 1);
- }
-
diff --git a/target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch b/target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch
deleted file mode 100644
index bce54eba4f..0000000000
--- a/target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 039550960a2235cfe2dfaa773df9f98f8da31a0c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 18 Oct 2023 14:35:50 +0200
-Subject: [PATCH 3/3] net: stmmac: increase TX coalesce timer to 5ms
-
-Commit 8fce33317023 ("net: stmmac: Rework coalesce timer and fix
-multi-queue races") decreased the TX coalesce timer from 40ms to 1ms.
-
-This caused some performance regression on some target (regression was
-reported at least on ipq806x) in the order of 600mbps dropping from
-gigabit handling to only 200mbps.
-
-The problem was identified in the TX timer getting armed too much time.
-While this was fixed and improved in another commit, performance can be
-improved even further by increasing the timer delay a bit moving from
-1ms to 5ms.
-
-The value is a good balance between battery saving by prevending too
-much interrupt to be generated and permitting good performance for
-internet oriented devices.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/stmicro/stmmac/common.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/common.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
-@@ -287,7 +287,7 @@ struct stmmac_safety_stats {
- #define MIN_DMA_RIWT 0x10
- #define DEF_DMA_RIWT 0xa0
- /* Tx coalesce parameters */
--#define STMMAC_COAL_TX_TIMER 1000
-+#define STMMAC_COAL_TX_TIMER 5000
- #define STMMAC_MAX_COAL_TX_TICK 100000
- #define STMMAC_TX_MAX_FRAMES 256
- #define STMMAC_TX_FRAMES 25
diff --git a/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch b/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch
deleted file mode 100644
index c0320ad6f9..0000000000
--- a/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From cfbd6de588ef659c198083205dc954a6d3ed2aec Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 29 Dec 2022 17:33:35 +0100
-Subject: [PATCH 4/5] net: dsa: qca8k: introduce single mii read/write lo/hi
-
-It may be useful to read/write just the lo or hi half of a reg.
-
-This is especially useful for phy poll with the use of mdio master.
-The mdio master reg is composed by the first 16 bit related to setup and
-the other half with the returned data or data to write.
-
-Refactor the mii function to permit single mii read/write of lo or hi
-half of the reg.
-
-Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 106 ++++++++++++++++++++++++-------
- 1 file changed, 84 insertions(+), 22 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -37,42 +37,104 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u
- }
-
- static int
--qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
- {
- int ret;
-+ u16 lo;
-
-- ret = bus->read(bus, phy_id, regnum);
-- if (ret >= 0) {
-- *val = ret;
-- ret = bus->read(bus, phy_id, regnum + 1);
-- *val |= ret << 16;
-- }
-+ lo = val & 0xffff;
-+ ret = bus->write(bus, phy_id, regnum, lo);
-+ if (ret < 0)
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to write qca8k 32bit lo register\n");
-+
-+ return ret;
-+}
-
-- if (ret < 0) {
-+static int
-+qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
-+{
-+ int ret;
-+ u16 hi;
-+
-+ hi = (u16)(val >> 16);
-+ ret = bus->write(bus, phy_id, regnum, hi);
-+ if (ret < 0)
- dev_err_ratelimited(&bus->dev,
-- "failed to read qca8k 32bit register\n");
-- *val = 0;
-- return ret;
-- }
-+ "failed to write qca8k 32bit hi register\n");
-
-+ return ret;
-+}
-+
-+static int
-+qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+{
-+ int ret;
-+
-+ ret = bus->read(bus, phy_id, regnum);
-+ if (ret < 0)
-+ goto err;
-+
-+ *val = ret & 0xffff;
- return 0;
-+
-+err:
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to read qca8k 32bit lo register\n");
-+ *val = 0;
-+
-+ return ret;
- }
-
--static void
--qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
-+static int
-+qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
- {
-- u16 lo, hi;
- int ret;
-
-- lo = val & 0xffff;
-- hi = (u16)(val >> 16);
-+ ret = bus->read(bus, phy_id, regnum);
-+ if (ret < 0)
-+ goto err;
-
-- ret = bus->write(bus, phy_id, regnum, lo);
-- if (ret >= 0)
-- ret = bus->write(bus, phy_id, regnum + 1, hi);
-+ *val = ret << 16;
-+ return 0;
-+
-+err:
-+ dev_err_ratelimited(&bus->dev,
-+ "failed to read qca8k 32bit hi register\n");
-+ *val = 0;
-+
-+ return ret;
-+}
-+
-+static int
-+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
-+{
-+ u32 hi, lo;
-+ int ret;
-+
-+ *val = 0;
-+
-+ ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo);
- if (ret < 0)
-- dev_err_ratelimited(&bus->dev,
-- "failed to write qca8k 32bit register\n");
-+ goto err;
-+
-+ ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi);
-+ if (ret < 0)
-+ goto err;
-+
-+ *val = lo | hi;
-+
-+err:
-+ return ret;
-+}
-+
-+static void
-+qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
-+{
-+ if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0)
-+ return;
-+
-+ qca8k_mii_write_hi(bus, phy_id, regnum + 1, val);
- }
-
- static int
diff --git a/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch b/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch
deleted file mode 100644
index dcafad0fd5..0000000000
--- a/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From a4165830ca237f2b3318faf62562bce8ce12a389 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 29 Dec 2022 17:33:36 +0100
-Subject: [PATCH 5/5] net: dsa: qca8k: improve mdio master read/write by using
- single lo/hi
-
-Improve mdio master read/write by using singe mii read/write lo/hi.
-
-In a read and write we need to poll the mdio master regs in a busy loop
-to check for a specific bit present in the upper half of the reg. We can
-ignore the other half since it won't contain useful data. This will save
-an additional useless read for each read and write operation.
-
-In a read operation the returned data is present in the mdio master reg
-lower half. We can ignore the other half since it won't contain useful
-data. This will save an additional useless read for each read operation.
-
-In a read operation it's needed to just set the hi half of the mdio
-master reg as the lo half will be replaced by the result. This will save
-an additional useless write for each read operation.
-
-Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -754,9 +754,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
-
- qca8k_split_addr(reg, &r1, &r2, &page);
-
-- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
-+ ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0,
- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-- bus, 0x10 | r2, r1, &val);
-+ bus, 0x10 | r2, r1 + 1, &val);
-
- /* Check if qca8k_read has failed for a different reason
- * before returnting -ETIMEDOUT
-@@ -798,7 +798,7 @@ qca8k_mdio_write(struct qca8k_priv *priv
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
-@@ -828,18 +828,18 @@ qca8k_mdio_read(struct qca8k_priv *priv,
- if (ret)
- goto exit;
-
-- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val);
-
- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
- QCA8K_MDIO_MASTER_BUSY);
- if (ret)
- goto exit;
-
-- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-+ ret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, &val);
-
- exit:
- /* even if the busy_wait timeouts try to clear the MASTER_EN */
-- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
-+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);
-
- mutex_unlock(&bus->mdio_lock);
-
diff --git a/target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch b/target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch
deleted file mode 100644
index 9331fd536d..0000000000
--- a/target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From e03cea60c3db8c6b011cc36ecef9281dff8377f3 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 25 Jan 2023 21:35:16 +0100
-Subject: [PATCH] net: dsa: qca8k: add QCA8K_ATU_TABLE_SIZE define for fdb
- access
-
-Add and use QCA8K_ATU_TABLE_SIZE instead of hardcoding the ATU size with
-a pure number and using sizeof on the array.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-common.c | 10 ++++++----
- drivers/net/dsa/qca/qca8k.h | 2 ++
- 2 files changed, 8 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -150,11 +150,12 @@ static int qca8k_busy_wait(struct qca8k_
-
- static int qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
- {
-- u32 reg[3];
-+ u32 reg[QCA8K_ATU_TABLE_SIZE];
- int ret;
-
- /* load the ARL table into an array */
-- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg,
-+ QCA8K_ATU_TABLE_SIZE * sizeof(u32));
- if (ret)
- return ret;
-
-@@ -178,7 +179,7 @@ static int qca8k_fdb_read(struct qca8k_p
- static void qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask,
- const u8 *mac, u8 aging)
- {
-- u32 reg[3] = { 0 };
-+ u32 reg[QCA8K_ATU_TABLE_SIZE] = { 0 };
-
- /* vid - 83:72 */
- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
-@@ -195,7 +196,8 @@ static void qca8k_fdb_write(struct qca8k
- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
-
- /* load the array into the ARL table */
-- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
-+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg,
-+ QCA8K_ATU_TABLE_SIZE * sizeof(u32));
- }
-
- static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -148,6 +148,8 @@
- #define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474
-
- /* Lookup registers */
-+#define QCA8K_ATU_TABLE_SIZE 3 /* 12 bytes wide table / sizeof(u32) */
-+
- #define QCA8K_REG_ATU_DATA0 0x600
- #define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24)
- #define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16)
diff --git a/target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch b/target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch
deleted file mode 100644
index b8f8071b0a..0000000000
--- a/target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From c766e077d927e1775902c18827205ea2ade3a35d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 25 Jan 2023 21:35:17 +0100
-Subject: [PATCH] net: dsa: qca8k: convert to regmap read/write API
-
-Convert qca8k to regmap read/write bulk API. The mgmt eth can write up
-to 32 bytes of data at times. Currently we use a custom function to do
-it but regmap now supports declaration of read/write bulk even without a
-bus.
-
-Drop the custom function and rework the regmap function to this new
-implementation.
-
-Rework the qca8k_fdb_read/write function to use the new
-regmap_bulk_read/write as the old qca8k_bulk_read/write are now dropped.
-
-Cc: Mark Brown <broonie@kernel.org>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 92 ++++++++++++++++++++++++------
- drivers/net/dsa/qca/qca8k-common.c | 47 ++-------------
- drivers/net/dsa/qca/qca8k.h | 3 -
- 3 files changed, 77 insertions(+), 65 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -425,16 +425,12 @@ qca8k_regmap_update_bits_eth(struct qca8
- }
-
- static int
--qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
-+qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val)
- {
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
- struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- int ret;
-
-- if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
-- return 0;
--
- qca8k_split_addr(reg, &r1, &r2, &page);
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-@@ -451,16 +447,12 @@ exit:
- }
-
- static int
--qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
-+qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val)
- {
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
- struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- int ret;
-
-- if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
-- return 0;
--
- qca8k_split_addr(reg, &r1, &r2, &page);
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-@@ -477,17 +469,14 @@ exit:
- }
-
- static int
--qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
-+qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg,
-+ uint32_t mask, uint32_t write_val)
- {
-- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
- struct mii_bus *bus = priv->bus;
- u16 r1, r2, page;
- u32 val;
- int ret;
-
-- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
-- return 0;
--
- qca8k_split_addr(reg, &r1, &r2, &page);
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-@@ -510,17 +499,84 @@ exit:
- return ret;
- }
-
-+static int
-+qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len,
-+ void *val_buf, size_t val_len)
-+{
-+ int i, count = val_len / sizeof(u32), ret;
-+ u32 reg = *(u32 *)reg_buf & U16_MAX;
-+ struct qca8k_priv *priv = ctx;
-+
-+ if (priv->mgmt_master &&
-+ !qca8k_read_eth(priv, reg, val_buf, val_len))
-+ return 0;
-+
-+ /* loop count times and increment reg of 4 */
-+ for (i = 0; i < count; i++, reg += sizeof(u32)) {
-+ ret = qca8k_read_mii(priv, reg, val_buf + i);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len,
-+ const void *val_buf, size_t val_len)
-+{
-+ int i, count = val_len / sizeof(u32), ret;
-+ u32 reg = *(u32 *)reg_buf & U16_MAX;
-+ struct qca8k_priv *priv = ctx;
-+ u32 *val = (u32 *)val_buf;
-+
-+ if (priv->mgmt_master &&
-+ !qca8k_write_eth(priv, reg, val, val_len))
-+ return 0;
-+
-+ /* loop count times, increment reg of 4 and increment val ptr to
-+ * the next value
-+ */
-+ for (i = 0; i < count; i++, reg += sizeof(u32), val++) {
-+ ret = qca8k_write_mii(priv, reg, *val);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_bulk_write(void *ctx, const void *data, size_t bytes)
-+{
-+ return qca8k_bulk_gather_write(ctx, data, sizeof(u16), data + sizeof(u16),
-+ bytes - sizeof(u16));
-+}
-+
-+static int
-+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
-+{
-+ struct qca8k_priv *priv = ctx;
-+
-+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
-+ return 0;
-+
-+ return qca8k_regmap_update_bits_mii(priv, reg, mask, write_val);
-+}
-+
- static struct regmap_config qca8k_regmap_config = {
- .reg_bits = 16,
- .val_bits = 32,
- .reg_stride = 4,
- .max_register = 0x16ac, /* end MIB - Port6 range */
-- .reg_read = qca8k_regmap_read,
-- .reg_write = qca8k_regmap_write,
-+ .read = qca8k_bulk_read,
-+ .write = qca8k_bulk_write,
- .reg_update_bits = qca8k_regmap_update_bits,
- .rd_table = &qca8k_readable_table,
- .disable_locking = true, /* Locking is handled by qca8k read/write */
- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
-+ .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */
-+ .max_raw_write = 32,
- };
-
- static int
-@@ -2112,8 +2168,6 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-
- static const struct qca8k_info_ops qca8xxx_ops = {
- .autocast_mib = qca8k_get_ethtool_stats_eth,
-- .read_eth = qca8k_read_eth,
-- .write_eth = qca8k_write_eth,
- };
-
- static const struct qca8k_match_data qca8327 = {
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -101,45 +101,6 @@ const struct regmap_access_table qca8k_r
- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
- };
-
--/* TODO: remove these extra ops when we can support regmap bulk read/write */
--static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
--
-- if (priv->mgmt_master && priv->info->ops->read_eth &&
-- !priv->info->ops->read_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
--/* TODO: remove these extra ops when we can support regmap bulk read/write */
--static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
--{
-- int i, count = len / sizeof(u32), ret;
-- u32 tmp;
--
-- if (priv->mgmt_master && priv->info->ops->write_eth &&
-- !priv->info->ops->write_eth(priv, reg, val, len))
-- return 0;
--
-- for (i = 0; i < count; i++) {
-- tmp = val[i];
--
-- ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
-- if (ret < 0)
-- return ret;
-- }
--
-- return 0;
--}
--
- static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
- {
- u32 val;
-@@ -154,8 +115,8 @@ static int qca8k_fdb_read(struct qca8k_p
- int ret;
-
- /* load the ARL table into an array */
-- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg,
-- QCA8K_ATU_TABLE_SIZE * sizeof(u32));
-+ ret = regmap_bulk_read(priv->regmap, QCA8K_REG_ATU_DATA0, reg,
-+ QCA8K_ATU_TABLE_SIZE);
- if (ret)
- return ret;
-
-@@ -196,8 +157,8 @@ static void qca8k_fdb_write(struct qca8k
- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
-
- /* load the array into the ARL table */
-- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg,
-- QCA8K_ATU_TABLE_SIZE * sizeof(u32));
-+ regmap_bulk_write(priv->regmap, QCA8K_REG_ATU_DATA0, reg,
-+ QCA8K_ATU_TABLE_SIZE);
- }
-
- static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -330,9 +330,6 @@ struct qca8k_priv;
-
- struct qca8k_info_ops {
- int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data);
-- /* TODO: remove these extra ops when we can support regmap bulk read/write */
-- int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
-- int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
- };
-
- struct qca8k_match_data {
diff --git a/target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch b/target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch
deleted file mode 100644
index 3619440f07..0000000000
--- a/target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 2c39dd025da489cf87d26469d9f5ff19715324a0 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 24 Jul 2023 05:25:28 +0200
-Subject: [PATCH 1/4] net: dsa: qca8k: enable use_single_write for qca8xxx
-
-The qca8xxx switch supports 2 way to write reg values, a slow way using
-mdio and a fast way by sending specially crafted mgmt packet to
-read/write reg.
-
-The fast way can support up to 32 bytes of data as eth packet are used
-to send/receive.
-
-This correctly works for almost the entire regmap of the switch but with
-the use of some kernel selftests for dsa drivers it was found a funny
-and interesting hw defect/limitation.
-
-For some specific reg, bulk write won't work and will result in writing
-only part of the requested regs resulting in half data written. This was
-especially hard to track and discover due to the total strangeness of
-the problem and also by the specific regs where this occurs.
-
-This occurs in the specific regs of the ATU table, where multiple entry
-needs to be written to compose the entire entry.
-It was discovered that with a bulk write of 12 bytes on
-QCA8K_REG_ATU_DATA0 only QCA8K_REG_ATU_DATA0 and QCA8K_REG_ATU_DATA2
-were written, but QCA8K_REG_ATU_DATA1 was always zero.
-Tcpdump was used to make sure the specially crafted packet was correct
-and this was confirmed.
-
-The problem was hard to track as the lack of QCA8K_REG_ATU_DATA1
-resulted in an entry somehow possible as the first bytes of the mac
-address are set in QCA8K_REG_ATU_DATA0 and the entry type is set in
-QCA8K_REG_ATU_DATA2.
-
-Funlly enough writing QCA8K_REG_ATU_DATA1 results in the same problem
-with QCA8K_REG_ATU_DATA2 empty and QCA8K_REG_ATU_DATA1 and
-QCA8K_REG_ATU_FUNC correctly written.
-A speculation on the problem might be that there are some kind of
-indirection internally when accessing these regs and they can't be
-accessed all together, due to the fact that it's really a table mapped
-somewhere in the switch SRAM.
-
-Even more funny is the fact that every other reg was tested with all
-kind of combination and they are not affected by this problem. Read
-operation was also tested and always worked so it's not affected by this
-problem.
-
-The problem is not present if we limit writing a single reg at times.
-
-To handle this hardware defect, enable use_single_write so that bulk
-api can correctly split the write in multiple different operation
-effectively reverting to a non-bulk write.
-
-Cc: Mark Brown <broonie@kernel.org>
-Fixes: c766e077d927 ("net: dsa: qca8k: convert to regmap read/write API")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -575,8 +575,11 @@ static struct regmap_config qca8k_regmap
- .rd_table = &qca8k_readable_table,
- .disable_locking = true, /* Locking is handled by qca8k read/write */
- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
-- .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */
-- .max_raw_write = 32,
-+ .max_raw_read = 32, /* mgmt eth can read up to 8 registers at time */
-+ /* ATU regs suffer from a bug where some data are not correctly
-+ * written. Disable bulk write to correctly write ATU entry.
-+ */
-+ .use_single_write = true,
- };
-
- static int
diff --git a/target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch b/target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch
deleted file mode 100644
index d31789370e..0000000000
--- a/target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 23cfc7172e5297d0bee49ac6f6f8248d1cf0820d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 30 Jul 2023 09:41:10 +0200
-Subject: [PATCH 1/4] net: dsa: qca8k: make learning configurable and keep off
- if standalone
-
-Address learning should initially be turned off by the driver for port
-operation in standalone mode, then the DSA core handles changes to it
-via ds->ops->port_bridge_flags().
-
-Currently this is not the case for qca8k where learning is enabled
-unconditionally in qca8k_setup for every user port.
-
-Handle ports configured in standalone mode by making the learning
-configurable and not enabling it by default.
-
-Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
-enable learning for bridge that request it and tweak
-.port_stp_state_set to correctly disable learning when port is
-configured in standalone mode.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://lore.kernel.org/r/20230730074113.21889-2-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++--
- drivers/net/dsa/qca/qca8k-common.c | 48 ++++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 6 ++++
- 3 files changed, 58 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1905,9 +1905,8 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-- /* Enable ARP Auto-learning by default */
-- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_LEARN);
-+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-+ QCA8K_PORT_LOOKUP_LEARN);
- if (ret)
- return ret;
-
-@@ -2013,6 +2012,8 @@ static const struct dsa_switch_ops qca8k
- .port_change_mtu = qca8k_port_change_mtu,
- .port_max_mtu = qca8k_port_max_mtu,
- .port_stp_state_set = qca8k_port_stp_state_set,
-+ .port_pre_bridge_flags = qca8k_port_pre_bridge_flags,
-+ .port_bridge_flags = qca8k_port_bridge_flags,
- .port_bridge_join = qca8k_port_bridge_join,
- .port_bridge_leave = qca8k_port_bridge_leave,
- .port_fast_age = qca8k_port_fast_age,
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -565,9 +565,26 @@ int qca8k_get_mac_eee(struct dsa_switch
- return 0;
- }
-
-+static int qca8k_port_configure_learning(struct dsa_switch *ds, int port,
-+ bool learning)
-+{
-+ struct qca8k_priv *priv = ds->priv;
-+
-+ if (learning)
-+ return regmap_set_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_LEARN);
-+ else
-+ return regmap_clear_bits(priv->regmap,
-+ QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_LEARN);
-+}
-+
- void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
- {
-+ struct dsa_port *dp = dsa_to_port(ds, port);
- struct qca8k_priv *priv = ds->priv;
-+ bool learning = false;
- u32 stp_state;
-
- switch (state) {
-@@ -582,8 +599,11 @@ void qca8k_port_stp_state_set(struct dsa
- break;
- case BR_STATE_LEARNING:
- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
-+ learning = dp->learning;
- break;
- case BR_STATE_FORWARDING:
-+ learning = dp->learning;
-+ fallthrough;
- default:
- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
- break;
-@@ -591,6 +611,34 @@ void qca8k_port_stp_state_set(struct dsa
-
- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
-+
-+ qca8k_port_configure_learning(ds, port, learning);
-+}
-+
-+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
-+ struct switchdev_brport_flags flags,
-+ struct netlink_ext_ack *extack)
-+{
-+ if (flags.mask & ~BR_LEARNING)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
-+ struct switchdev_brport_flags flags,
-+ struct netlink_ext_ack *extack)
-+{
-+ int ret;
-+
-+ if (flags.mask & BR_LEARNING) {
-+ ret = qca8k_port_configure_learning(ds, port,
-+ flags.val & BR_LEARNING);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
- }
-
- int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -448,6 +448,12 @@ int qca8k_get_mac_eee(struct dsa_switch
-
- /* Common bridge function */
- void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
-+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
-+ struct switchdev_brport_flags flags,
-+ struct netlink_ext_ack *extack);
-+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
-+ struct switchdev_brport_flags flags,
-+ struct netlink_ext_ack *extack);
- int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
- struct dsa_bridge bridge,
- bool *tx_fwd_offload,
diff --git a/target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch b/target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch
deleted file mode 100644
index 4b457f67de..0000000000
--- a/target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 18e8feae4a807994e4906d659116d249bfecd4c5 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 30 Jul 2023 09:41:11 +0200
-Subject: [PATCH 2/4] net: dsa: qca8k: limit user ports access to the first CPU
- port on setup
-
-In preparation for multi-CPU support, set CPU port LOOKUP MEMBER outside
-the port loop and setup the LOOKUP MEMBER mask for user ports only to
-the first CPU port.
-
-This is to handle flooding condition where every CPU port is set as
-target and prevent packet duplication for unknown frames from user ports.
-
-Secondary CPU port LOOKUP MEMBER mask will be setup later when
-port_change_master will be implemented.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20230730074113.21889-3-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 14 ++++++--------
- 1 file changed, 6 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1885,18 +1885,16 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-+ /* CPU port gets connected to all user ports of the switch */
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
-+ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-+ if (ret)
-+ return ret;
-+
- /* Setup connection between CPU port & user ports
- * Configure specific switch configuration for ports
- */
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- /* CPU port gets connected to all user ports of the switch */
-- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-- if (ret)
-- return ret;
-- }
--
- /* Individual user ports get connected to CPU port only */
- if (dsa_is_user_port(ds, i)) {
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
diff --git a/target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch b/target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch
deleted file mode 100644
index f556628b5b..0000000000
--- a/target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From a9108b0712bf018dc69020864b21485b71b17dfc Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 30 Jul 2023 09:41:12 +0200
-Subject: [PATCH 3/4] net: dsa: qca8k: move qca8xxx hol fixup to separate
- function
-
-Move qca8xxx hol fixup to separate function to tidy things up and to
-permit using a more efficent loop in future patch.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://lore.kernel.org/r/20230730074113.21889-4-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 78 +++++++++++++++++---------------
- 1 file changed, 42 insertions(+), 36 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1795,6 +1795,46 @@ static int qca8k_connect_tag_protocol(st
- return 0;
- }
-
-+static void qca8k_setup_hol_fixup(struct qca8k_priv *priv, int port)
-+{
-+ u32 mask;
-+
-+ switch (port) {
-+ /* The 2 CPU port and port 5 requires some different
-+ * priority than any other ports.
-+ */
-+ case 0:
-+ case 5:
-+ case 6:
-+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
-+ break;
-+ default:
-+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
-+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
-+ }
-+ regmap_write(priv->regmap, QCA8K_REG_PORT_HOL_CTRL0(port), mask);
-+
-+ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
-+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_WRED_EN;
-+ regmap_update_bits(priv->regmap, QCA8K_REG_PORT_HOL_CTRL1(port),
-+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
-+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+ QCA8K_PORT_HOL_CTRL1_WRED_EN,
-+ mask);
-+}
-+
- static int
- qca8k_setup(struct dsa_switch *ds)
- {
-@@ -1930,42 +1970,8 @@ qca8k_setup(struct dsa_switch *ds)
- * missing settings to improve switch stability under load condition.
- * This problem is limited to qca8337 and other qca8k switch are not affected.
- */
-- if (priv->switch_id == QCA8K_ID_QCA8337) {
-- switch (i) {
-- /* The 2 CPU port and port 5 requires some different
-- * priority than any other ports.
-- */
-- case 0:
-- case 5:
-- case 6:
-- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
-- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
-- break;
-- default:
-- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
-- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
-- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
-- }
-- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
--
-- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
-- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_WRED_EN;
-- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
-- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
-- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-- QCA8K_PORT_HOL_CTRL1_WRED_EN,
-- mask);
-- }
-+ if (priv->switch_id == QCA8K_ID_QCA8337)
-+ qca8k_setup_hol_fixup(priv, i);
- }
-
- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
diff --git a/target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch b/target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch
deleted file mode 100644
index faa0142ca9..0000000000
--- a/target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From 01e6f8ad8d26ced14b0cf288c42e55d03a7c5070 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 30 Jul 2023 09:41:13 +0200
-Subject: [PATCH 4/4] net: dsa: qca8k: use dsa_for_each macro instead of for
- loop
-
-Convert for loop to dsa_for_each macro to save some redundant write on
-unconnected/unused port and tidy things up.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://lore.kernel.org/r/20230730074113.21889-5-ansuelsmth@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 107 ++++++++++++++++---------------
- 1 file changed, 54 insertions(+), 53 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1839,7 +1839,8 @@ static int
- qca8k_setup(struct dsa_switch *ds)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-- int cpu_port, ret, i;
-+ struct dsa_port *dp;
-+ int cpu_port, ret;
- u32 mask;
-
- cpu_port = qca8k_find_cpu_port(ds);
-@@ -1890,27 +1891,27 @@ qca8k_setup(struct dsa_switch *ds)
- dev_warn(priv->dev, "mib init failed");
-
- /* Initial setup of all ports */
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+ dsa_switch_for_each_port(dp, ds) {
- /* Disable forwarding by default on all ports */
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(dp->index),
- QCA8K_PORT_LOOKUP_MEMBER, 0);
- if (ret)
- return ret;
-+ }
-
-- /* Enable QCA header mode on all cpu ports */
-- if (dsa_is_cpu_port(ds, i)) {
-- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
-- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
-- if (ret) {
-- dev_err(priv->dev, "failed enabling QCA header mode");
-- return ret;
-- }
-+ /* Disable MAC by default on all user ports */
-+ dsa_switch_for_each_user_port(dp, ds)
-+ qca8k_port_set_status(priv, dp->index, 0);
-+
-+ /* Enable QCA header mode on all cpu ports */
-+ dsa_switch_for_each_cpu_port(dp, ds) {
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(dp->index),
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
-+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
-+ if (ret) {
-+ dev_err(priv->dev, "failed enabling QCA header mode on port %d", dp->index);
-+ return ret;
- }
--
-- /* Disable MAC by default on all user ports */
-- if (dsa_is_user_port(ds, i))
-- qca8k_port_set_status(priv, i, 0);
- }
-
- /* Forward all unknown frames to CPU port for Linux processing
-@@ -1932,48 +1933,48 @@ qca8k_setup(struct dsa_switch *ds)
- return ret;
-
- /* Setup connection between CPU port & user ports
-- * Configure specific switch configuration for ports
-+ * Individual user ports get connected to CPU port only
- */
-- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-- /* Individual user ports get connected to CPU port only */
-- if (dsa_is_user_port(ds, i)) {
-- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_MEMBER,
-- BIT(cpu_port));
-- if (ret)
-- return ret;
--
-- ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
-- QCA8K_PORT_LOOKUP_LEARN);
-- if (ret)
-- return ret;
--
-- /* For port based vlans to work we need to set the
-- * default egress vid
-- */
-- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-- QCA8K_EGREES_VLAN_PORT_MASK(i),
-- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF));
-- if (ret)
-- return ret;
--
-- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-- if (ret)
-- return ret;
-- }
-+ dsa_switch_for_each_user_port(dp, ds) {
-+ u8 port = dp->index;
-
-- /* The port 5 of the qca8337 have some problem in flood condition. The
-- * original legacy driver had some specific buffer and priority settings
-- * for the different port suggested by the QCA switch team. Add this
-- * missing settings to improve switch stability under load condition.
-- * This problem is limited to qca8337 and other qca8k switch are not affected.
-+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER,
-+ BIT(cpu_port));
-+ if (ret)
-+ return ret;
-+
-+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_LEARN);
-+ if (ret)
-+ return ret;
-+
-+ /* For port based vlans to work we need to set the
-+ * default egress vid
- */
-- if (priv->switch_id == QCA8K_ID_QCA8337)
-- qca8k_setup_hol_fixup(priv, i);
-+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
-+ QCA8K_EGREES_VLAN_PORT_MASK(port),
-+ QCA8K_EGREES_VLAN_PORT(port, QCA8K_PORT_VID_DEF));
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
-+ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-+ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-+ if (ret)
-+ return ret;
- }
-
-+ /* The port 5 of the qca8337 have some problem in flood condition. The
-+ * original legacy driver had some specific buffer and priority settings
-+ * for the different port suggested by the QCA switch team. Add this
-+ * missing settings to improve switch stability under load condition.
-+ * This problem is limited to qca8337 and other qca8k switch are not affected.
-+ */
-+ if (priv->switch_id == QCA8K_ID_QCA8337)
-+ dsa_switch_for_each_available_port(dp, ds)
-+ qca8k_setup_hol_fixup(priv, dp->index);
-+
- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
- if (priv->switch_id == QCA8K_ID_QCA8327) {
- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
diff --git a/target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch b/target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch
deleted file mode 100644
index 632f422d1f..0000000000
--- a/target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 5652d1741574eb89cc02576e50ee3e348bd6dd77 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Wed, 4 Oct 2023 11:19:03 +0200
-Subject: [PATCH 1/2] net: dsa: qca8k: fix regmap bulk read/write methods on
- big endian systems
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Commit c766e077d927 ("net: dsa: qca8k: convert to regmap read/write
-API") introduced bulk read/write methods to qca8k's regmap.
-
-The regmap bulk read/write methods get the register address in a buffer
-passed as a void pointer parameter (the same buffer contains also the
-read/written values). The register address occupies only as many bytes
-as it requires at the beginning of this buffer. For example if the
-.reg_bits member in regmap_config is 16 (as is the case for this
-driver), the register address occupies only the first 2 bytes in this
-buffer, so it can be cast to u16.
-
-But the original commit implementing these bulk read/write methods cast
-the buffer to u32:
- u32 reg = *(u32 *)reg_buf & U16_MAX;
-taking the first 4 bytes. This works on little endian systems where the
-first 2 bytes of the buffer correspond to the low 16-bits, but it
-obviously cannot work on big endian systems.
-
-Fix this by casting the beginning of the buffer to u16 as
- u32 reg = *(u16 *)reg_buf;
-
-Fixes: c766e077d927 ("net: dsa: qca8k: convert to regmap read/write API")
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Tested-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -504,8 +504,8 @@ qca8k_bulk_read(void *ctx, const void *r
- void *val_buf, size_t val_len)
- {
- int i, count = val_len / sizeof(u32), ret;
-- u32 reg = *(u32 *)reg_buf & U16_MAX;
- struct qca8k_priv *priv = ctx;
-+ u32 reg = *(u16 *)reg_buf;
-
- if (priv->mgmt_master &&
- !qca8k_read_eth(priv, reg, val_buf, val_len))
-@@ -526,8 +526,8 @@ qca8k_bulk_gather_write(void *ctx, const
- const void *val_buf, size_t val_len)
- {
- int i, count = val_len / sizeof(u32), ret;
-- u32 reg = *(u32 *)reg_buf & U16_MAX;
- struct qca8k_priv *priv = ctx;
-+ u32 reg = *(u16 *)reg_buf;
- u32 *val = (u32 *)val_buf;
-
- if (priv->mgmt_master &&
diff --git a/target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch b/target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch
deleted file mode 100644
index e0319fd355..0000000000
--- a/target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 27b692012840f658c84a3102c0aeca2676f03132 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 15 Dec 2022 03:47:59 +0000
-Subject: [PATCH 01/48] net: dsa: mt7530: remove redundant assignment
-
-Russell King correctly pointed out that the MAC_2500FD capability is
-already added for port 5 (if not in RGMII mode) and port 6 (which only
-supports SGMII) by mt7531_mac_port_get_caps. Remove the reduntant
-setting of this capability flag which was added by a previous commit.
-
-Fixes: e19de30d2080 ("net: dsa: mt7530: add support for in-band link status")
-Reported-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/Y5qY7x6la5TxZxzX@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3198,9 +3198,6 @@ static void mt753x_phylink_get_caps(stru
- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000FD;
-
-- if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
-- config->mac_capabilities |= MAC_2500FD;
--
- /* This driver does not make use of the speed, duplex, pause or the
- * advertisement in its mac_config, so it is safe to mark this driver
- * as non-legacy.
diff --git a/target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch
deleted file mode 100644
index 2697f2e563..0000000000
--- a/target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch
+++ /dev/null
@@ -1,477 +0,0 @@
-From 05dc5ea089f947a69a5db092ef4cad6a0f3c96ce Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:58:43 +0000
-Subject: [PATCH 02/48] net: dsa: mt7530: use external PCS driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Implement regmap access wrappers, for now only to be used by the
-pcs-mtk-lynxi driver.
-Make use of this external PCS driver and drop the now reduntant
-implementation in mt7530.c.
-As a nice side effect the SGMII registers can now also more easily be
-inspected for debugging via /sys/kernel/debug/regmap.
-
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/Kconfig | 1 +
- drivers/net/dsa/mt7530.c | 277 ++++++++++-----------------------------
- drivers/net/dsa/mt7530.h | 47 +------
- 3 files changed, 71 insertions(+), 254 deletions(-)
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -37,6 +37,7 @@ config NET_DSA_MT7530
- tristate "MediaTek MT753x and MT7621 Ethernet switch support"
- select NET_DSA_TAG_MTK
- select MEDIATEK_GE_PHY
-+ select PCS_MTK_LYNXI
- help
- This enables support for the MediaTek MT7530, MT7531, and MT7621
- Ethernet switch chips.
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -14,6 +14,7 @@
- #include <linux/of_mdio.h>
- #include <linux/of_net.h>
- #include <linux/of_platform.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
- #include <linux/phylink.h>
- #include <linux/regmap.h>
- #include <linux/regulator/consumer.h>
-@@ -2839,128 +2840,11 @@ static int mt7531_rgmii_setup(struct mt7
- return 0;
- }
-
--static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-- phy_interface_t interface, int speed, int duplex)
--{
-- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-- int port = pcs_to_mt753x_pcs(pcs)->port;
-- unsigned int val;
--
-- /* For adjusting speed and duplex of SGMII force mode. */
-- if (interface != PHY_INTERFACE_MODE_SGMII ||
-- phylink_autoneg_inband(mode))
-- return;
--
-- /* SGMII force mode setting */
-- val = mt7530_read(priv, MT7531_SGMII_MODE(port));
-- val &= ~MT7531_SGMII_IF_MODE_MASK;
--
-- switch (speed) {
-- case SPEED_10:
-- val |= MT7531_SGMII_FORCE_SPEED_10;
-- break;
-- case SPEED_100:
-- val |= MT7531_SGMII_FORCE_SPEED_100;
-- break;
-- case SPEED_1000:
-- val |= MT7531_SGMII_FORCE_SPEED_1000;
-- break;
-- }
--
-- /* MT7531 SGMII 1G force mode can only work in full duplex mode,
-- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
-- *
-- * The speed check is unnecessary as the MAC capabilities apply
-- * this restriction. --rmk
-- */
-- if ((speed == SPEED_10 || speed == SPEED_100) &&
-- duplex != DUPLEX_FULL)
-- val |= MT7531_SGMII_FORCE_HALF_DUPLEX;
--
-- mt7530_write(priv, MT7531_SGMII_MODE(port), val);
--}
--
- static bool mt753x_is_mac_port(u32 port)
- {
- return (port == 5 || port == 6);
- }
-
--static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
-- phy_interface_t interface)
--{
-- u32 val;
--
-- if (!mt753x_is_mac_port(port))
-- return -EINVAL;
--
-- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-- MT7531_SGMII_PHYA_PWD);
--
-- val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
-- val &= ~MT7531_RG_TPHY_SPEED_MASK;
-- /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B
-- * encoding.
-- */
-- val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ?
-- MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G;
-- mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
--
-- mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
--
-- /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex
-- * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
-- */
-- mt7530_rmw(priv, MT7531_SGMII_MODE(port),
-- MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS,
-- MT7531_SGMII_FORCE_SPEED_1000);
--
-- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
--
-- return 0;
--}
--
--static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
-- phy_interface_t interface)
--{
-- if (!mt753x_is_mac_port(port))
-- return -EINVAL;
--
-- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-- MT7531_SGMII_PHYA_PWD);
--
-- mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
-- MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G);
--
-- mt7530_set(priv, MT7531_SGMII_MODE(port),
-- MT7531_SGMII_REMOTE_FAULT_DIS |
-- MT7531_SGMII_SPEED_DUPLEX_AN);
--
-- mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port),
-- MT7531_SGMII_TX_CONFIG_MASK, 1);
--
-- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
--
-- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART);
--
-- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
--
-- return 0;
--}
--
--static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
--{
-- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-- int port = pcs_to_mt753x_pcs(pcs)->port;
-- u32 val;
--
-- /* Only restart AN when AN is enabled */
-- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-- if (val & MT7531_SGMII_AN_ENABLE) {
-- val |= MT7531_SGMII_AN_RESTART;
-- mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
-- }
--}
--
- static int
- mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
-@@ -2983,11 +2867,11 @@ mt7531_mac_config(struct dsa_switch *ds,
- phydev = dp->slave->phydev;
- return mt7531_rgmii_setup(priv, port, interface, phydev);
- case PHY_INTERFACE_MODE_SGMII:
-- return mt7531_sgmii_setup_mode_an(priv, port, interface);
- case PHY_INTERFACE_MODE_NA:
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_2500BASEX:
-- return mt7531_sgmii_setup_mode_force(priv, port, interface);
-+ /* handled in SGMII PCS driver */
-+ return 0;
- default:
- return -EINVAL;
- }
-@@ -3012,11 +2896,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
-
- switch (interface) {
- case PHY_INTERFACE_MODE_TRGMII:
-+ return &priv->pcs[port].pcs;
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_2500BASEX:
-- return &priv->pcs[port].pcs;
--
-+ return priv->ports[port].sgmii_pcs;
- default:
- return NULL;
- }
-@@ -3254,86 +3138,6 @@ static void mt7530_pcs_get_state(struct
- state->pause |= MLO_PAUSE_TX;
- }
-
--static int
--mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
-- struct phylink_link_state *state)
--{
-- u32 status, val;
-- u16 config_reg;
--
-- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-- state->link = !!(status & MT7531_SGMII_LINK_STATUS);
-- state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
-- if (state->interface == PHY_INTERFACE_MODE_SGMII &&
-- (status & MT7531_SGMII_AN_ENABLE)) {
-- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
-- config_reg = val >> 16;
--
-- switch (config_reg & LPA_SGMII_SPD_MASK) {
-- case LPA_SGMII_1000:
-- state->speed = SPEED_1000;
-- break;
-- case LPA_SGMII_100:
-- state->speed = SPEED_100;
-- break;
-- case LPA_SGMII_10:
-- state->speed = SPEED_10;
-- break;
-- default:
-- dev_err(priv->dev, "invalid sgmii PHY speed\n");
-- state->link = false;
-- return -EINVAL;
-- }
--
-- if (config_reg & LPA_SGMII_FULL_DUPLEX)
-- state->duplex = DUPLEX_FULL;
-- else
-- state->duplex = DUPLEX_HALF;
-- }
--
-- return 0;
--}
--
--static void
--mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
-- struct phylink_link_state *state)
--{
-- unsigned int val;
--
-- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-- state->link = !!(val & MT7531_SGMII_LINK_STATUS);
-- if (!state->link)
-- return;
--
-- state->an_complete = state->link;
--
-- if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
-- state->speed = SPEED_2500;
-- else
-- state->speed = SPEED_1000;
--
-- state->duplex = DUPLEX_FULL;
-- state->pause = MLO_PAUSE_NONE;
--}
--
--static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
-- struct phylink_link_state *state)
--{
-- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-- int port = pcs_to_mt753x_pcs(pcs)->port;
--
-- if (state->interface == PHY_INTERFACE_MODE_SGMII) {
-- mt7531_sgmii_pcs_get_state_an(priv, port, state);
-- return;
-- } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
-- (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
-- mt7531_sgmii_pcs_get_state_inband(priv, port, state);
-- return;
-- }
--
-- state->link = false;
--}
--
- static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface,
- const unsigned long *advertising,
-@@ -3353,18 +3157,57 @@ static const struct phylink_pcs_ops mt75
- .pcs_an_restart = mt7530_pcs_an_restart,
- };
-
--static const struct phylink_pcs_ops mt7531_pcs_ops = {
-- .pcs_validate = mt753x_pcs_validate,
-- .pcs_get_state = mt7531_pcs_get_state,
-- .pcs_config = mt753x_pcs_config,
-- .pcs_an_restart = mt7531_pcs_an_restart,
-- .pcs_link_up = mt7531_pcs_link_up,
-+static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-+{
-+ struct mt7530_priv *priv = context;
-+
-+ *val = mt7530_read(priv, reg);
-+ return 0;
-+};
-+
-+static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-+{
-+ struct mt7530_priv *priv = context;
-+
-+ mt7530_write(priv, reg, val);
-+ return 0;
-+};
-+
-+static int mt7530_regmap_update_bits(void *context, unsigned int reg,
-+ unsigned int mask, unsigned int val)
-+{
-+ struct mt7530_priv *priv = context;
-+
-+ mt7530_rmw(priv, reg, mask, val);
-+ return 0;
-+};
-+
-+static const struct regmap_bus mt7531_regmap_bus = {
-+ .reg_write = mt7530_regmap_write,
-+ .reg_read = mt7530_regmap_read,
-+ .reg_update_bits = mt7530_regmap_update_bits,
-+};
-+
-+#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
-+ { \
-+ .name = _name, \
-+ .reg_bits = 16, \
-+ .val_bits = 32, \
-+ .reg_stride = 4, \
-+ .reg_base = _reg_base, \
-+ .max_register = 0x17c, \
-+ }
-+
-+static const struct regmap_config mt7531_pcs_config[] = {
-+ MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
-+ MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
- };
-
- static int
- mt753x_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-+ struct regmap *regmap;
- int i, ret;
-
- /* Initialise the PCS devices */
-@@ -3372,8 +3215,6 @@ mt753x_setup(struct dsa_switch *ds)
- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
- priv->pcs[i].priv = priv;
- priv->pcs[i].port = i;
-- if (mt753x_is_mac_port(i))
-- priv->pcs[i].pcs.poll = 1;
- }
-
- ret = priv->info->sw_setup(ds);
-@@ -3388,6 +3229,16 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-+ if (priv->id == ID_MT7531)
-+ for (i = 0; i < 2; i++) {
-+ regmap = devm_regmap_init(ds->dev,
-+ &mt7531_regmap_bus, priv,
-+ &mt7531_pcs_config[i]);
-+ priv->ports[5 + i].sgmii_pcs =
-+ mtk_pcs_lynxi_create(ds->dev, regmap,
-+ MT7531_PHYA_CTRL_SIGNAL3, 0);
-+ }
-+
- return ret;
- }
-
-@@ -3480,7 +3331,7 @@ static const struct mt753x_info mt753x_t
- },
- [ID_MT7531] = {
- .id = ID_MT7531,
-- .pcs_ops = &mt7531_pcs_ops,
-+ .pcs_ops = &mt7530_pcs_ops,
- .sw_setup = mt7531_setup,
- .phy_read = mt7531_ind_phy_read,
- .phy_write = mt7531_ind_phy_write,
-@@ -3588,7 +3439,7 @@ static void
- mt7530_remove(struct mdio_device *mdiodev)
- {
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-- int ret = 0;
-+ int ret = 0, i;
-
- if (!priv)
- return;
-@@ -3607,6 +3458,10 @@ mt7530_remove(struct mdio_device *mdiode
- mt7530_free_irq(priv);
-
- dsa_unregister_switch(priv->ds);
-+
-+ for (i = 0; i < 2; ++i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-+
- mutex_destroy(&priv->reg_mutex);
- }
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm {
- CCR_TX_OCT_CNT_BAD)
-
- /* MT7531 SGMII register group */
--#define MT7531_SGMII_REG_BASE 0x5000
--#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
-- ((p) - 5) * 0x1000 + (r))
--
--/* Register forSGMII PCS_CONTROL_1 */
--#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00)
--#define MT7531_SGMII_LINK_STATUS BIT(18)
--#define MT7531_SGMII_AN_ENABLE BIT(12)
--#define MT7531_SGMII_AN_RESTART BIT(9)
--#define MT7531_SGMII_AN_COMPLETE BIT(21)
--
--/* Register for SGMII PCS_SPPED_ABILITY */
--#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
--#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0)
--#define MT7531_SGMII_TX_CONFIG BIT(0)
--
--/* Register for SGMII_MODE */
--#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20)
--#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8)
--#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1)
--#define MT7531_SGMII_FORCE_DUPLEX BIT(4)
--#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2)
--#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3)
--#define MT7531_SGMII_FORCE_SPEED_100 BIT(2)
--#define MT7531_SGMII_FORCE_SPEED_10 0
--#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1)
--
--enum mt7531_sgmii_force_duplex {
-- MT7531_SGMII_FORCE_FULL_DUPLEX = 0,
-- MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10,
--};
--
--/* Fields of QPHY_PWR_STATE_CTRL */
--#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8)
--#define MT7531_SGMII_PHYA_PWD BIT(4)
--
--/* Values of SGMII SPEED */
--#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128)
--#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3))
--#define MT7531_RG_TPHY_SPEED_1_25G 0x0
--#define MT7531_RG_TPHY_SPEED_3_125G BIT(2)
-+#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000)
-+#define MT7531_PHYA_CTRL_SIGNAL3 0x128
-
- /* Register for system reset */
- #define MT7530_SYS_CTRL 0x7000
-@@ -741,13 +702,13 @@ struct mt7530_fdb {
- * @pm: The matrix used to show all connections with the port.
- * @pvid: The VLAN specified is to be considered a PVID at ingress. Any
- * untagged frames will be assigned to the related VLAN.
-- * @vlan_filtering: The flags indicating whether the port that can recognize
-- * VLAN-tagged frames.
-+ * @sgmii_pcs: Pointer to PCS instance for SerDes ports
- */
- struct mt7530_port {
- bool enable;
- u32 pm;
- u16 pvid;
-+ struct phylink_pcs *sgmii_pcs;
- };
-
- /* Port 5 interface select definitions */
diff --git a/target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch b/target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch
deleted file mode 100644
index d8f559b416..0000000000
--- a/target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From cafbb70e148e7a4e318dcc1e36a96643815b6245 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:19 +0100
-Subject: [PATCH 03/48] net: dsa: mt7530: make some noise if register read
- fails
-
-Simply returning the negative error value instead of the read value
-doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1)
-so this kind of error will not go unnoticed.
-
-Suggested-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -224,9 +224,10 @@ mt7530_mii_read(struct mt7530_priv *priv
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0) {
-+ WARN_ON_ONCE(1);
- dev_err(&bus->dev,
- "failed to read mt7530 register\n");
-- return ret;
-+ return 0;
- }
-
- lo = bus->read(bus, 0x1f, r);
diff --git a/target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch
deleted file mode 100644
index 1bf19a813e..0000000000
--- a/target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From 8f83ad87e2df26ddf9b8afd4d2873644a872d929 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:30 +0100
-Subject: [PATCH 04/48] net: dsa: mt7530: refactor SGMII PCS creation
-
-Instead of macro templates use a dedidated function and allocated
-regmap_config when creating the regmaps for the pcs-mtk-lynxi
-instances.
-This is in preparation to switching to use unlocked regmap accessors
-and have regmap's locking API handle locking for us.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++-------------
- 1 file changed, 50 insertions(+), 24 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3189,26 +3189,56 @@ static const struct regmap_bus mt7531_re
- .reg_update_bits = mt7530_regmap_update_bits,
- };
-
--#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
-- { \
-- .name = _name, \
-- .reg_bits = 16, \
-- .val_bits = 32, \
-- .reg_stride = 4, \
-- .reg_base = _reg_base, \
-- .max_register = 0x17c, \
-+static int
-+mt7531_create_sgmii(struct mt7530_priv *priv)
-+{
-+ struct regmap_config *mt7531_pcs_config[2];
-+ struct phylink_pcs *pcs;
-+ struct regmap *regmap;
-+ int i, ret = 0;
-+
-+ for (i = 0; i < 2; i++) {
-+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
-+ sizeof(struct regmap_config),
-+ GFP_KERNEL);
-+ if (!mt7531_pcs_config[i]) {
-+ ret = -ENOMEM;
-+ break;
-+ }
-+
-+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
-+ mt7531_pcs_config[i]->reg_bits = 16;
-+ mt7531_pcs_config[i]->val_bits = 32;
-+ mt7531_pcs_config[i]->reg_stride = 4;
-+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
-+ mt7531_pcs_config[i]->max_register = 0x17c;
-+
-+ regmap = devm_regmap_init(priv->dev,
-+ &mt7531_regmap_bus, priv,
-+ mt7531_pcs_config[i]);
-+ if (IS_ERR(regmap)) {
-+ ret = PTR_ERR(regmap);
-+ break;
-+ }
-+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
-+ MT7531_PHYA_CTRL_SIGNAL3, 0);
-+ if (!pcs) {
-+ ret = -ENXIO;
-+ break;
-+ }
-+ priv->ports[5 + i].sgmii_pcs = pcs;
- }
-
--static const struct regmap_config mt7531_pcs_config[] = {
-- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
-- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
--};
-+ if (ret && i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
-+
-+ return ret;
-+}
-
- static int
- mt753x_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-- struct regmap *regmap;
- int i, ret;
-
- /* Initialise the PCS devices */
-@@ -3230,15 +3260,11 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-- if (priv->id == ID_MT7531)
-- for (i = 0; i < 2; i++) {
-- regmap = devm_regmap_init(ds->dev,
-- &mt7531_regmap_bus, priv,
-- &mt7531_pcs_config[i]);
-- priv->ports[5 + i].sgmii_pcs =
-- mtk_pcs_lynxi_create(ds->dev, regmap,
-- MT7531_PHYA_CTRL_SIGNAL3, 0);
-- }
-+ if (priv->id == ID_MT7531) {
-+ ret = mt7531_create_sgmii(priv);
-+ if (ret && priv->irq)
-+ mt7530_free_irq_common(priv);
-+ }
-
- return ret;
- }
diff --git a/target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch
deleted file mode 100644
index bd28b4be76..0000000000
--- a/target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From efb41b8e9b7bbb08ace1930373bff63d4f5cc6e2 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:40 +0100
-Subject: [PATCH 05/48] net: dsa: mt7530: use unlocked regmap accessors
-
-Instead of wrapping the locked register accessor functions, use the
-unlocked variants and add locking wrapper functions to let regmap
-handle the locking.
-
-This is a preparation towards being able to always use regmap to
-access switch registers instead of open-coded accessor functions.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 23 ++++++++++++++---------
- 1 file changed, 14 insertions(+), 9 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3162,7 +3162,7 @@ static int mt7530_regmap_read(void *cont
- {
- struct mt7530_priv *priv = context;
-
-- *val = mt7530_read(priv, reg);
-+ *val = mt7530_mii_read(priv, reg);
- return 0;
- };
-
-@@ -3170,23 +3170,25 @@ static int mt7530_regmap_write(void *con
- {
- struct mt7530_priv *priv = context;
-
-- mt7530_write(priv, reg, val);
-+ mt7530_mii_write(priv, reg, val);
- return 0;
- };
-
--static int mt7530_regmap_update_bits(void *context, unsigned int reg,
-- unsigned int mask, unsigned int val)
-+static void
-+mt7530_mdio_regmap_lock(void *mdio_lock)
- {
-- struct mt7530_priv *priv = context;
-+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
-+}
-
-- mt7530_rmw(priv, reg, mask, val);
-- return 0;
--};
-+static void
-+mt7530_mdio_regmap_unlock(void *mdio_lock)
-+{
-+ mutex_unlock(mdio_lock);
-+}
-
- static const struct regmap_bus mt7531_regmap_bus = {
- .reg_write = mt7530_regmap_write,
- .reg_read = mt7530_regmap_read,
-- .reg_update_bits = mt7530_regmap_update_bits,
- };
-
- static int
-@@ -3212,6 +3214,9 @@ mt7531_create_sgmii(struct mt7530_priv *
- mt7531_pcs_config[i]->reg_stride = 4;
- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
- mt7531_pcs_config[i]->max_register = 0x17c;
-+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
-+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
-+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-
- regmap = devm_regmap_init(priv->dev,
- &mt7531_regmap_bus, priv,
diff --git a/target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch
deleted file mode 100644
index 42c225d91c..0000000000
--- a/target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch
+++ /dev/null
@@ -1,224 +0,0 @@
-From c7945d11a060797c31b3f47d9c9e515b0bf2082f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:17:52 +0100
-Subject: [PATCH 06/48] net: dsa: mt7530: use regmap to access switch register
- space
-
-Use regmap API to access the switch register space.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++----------------
- drivers/net/dsa/mt7530.h | 2 +
- 2 files changed, 62 insertions(+), 39 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -183,9 +183,9 @@ core_clear(struct mt7530_priv *priv, u32
- }
-
- static int
--mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
- {
-- struct mii_bus *bus = priv->bus;
-+ struct mii_bus *bus = context;
- u16 page, r, lo, hi;
- int ret;
-
-@@ -197,24 +197,34 @@ mt7530_mii_write(struct mt7530_priv *pri
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0)
-- goto err;
-+ return ret;
-
- ret = bus->write(bus, 0x1f, r, lo);
- if (ret < 0)
-- goto err;
-+ return ret;
-
- ret = bus->write(bus, 0x1f, 0x10, hi);
--err:
-+ return ret;
-+}
-+
-+static int
-+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ int ret;
-+
-+ ret = regmap_write(priv->regmap, reg, val);
-+
- if (ret < 0)
-- dev_err(&bus->dev,
-+ dev_err(priv->dev,
- "failed to write mt7530 register\n");
-+
- return ret;
- }
-
--static u32
--mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
-+static int
-+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
- {
-- struct mii_bus *bus = priv->bus;
-+ struct mii_bus *bus = context;
- u16 page, r, lo, hi;
- int ret;
-
-@@ -223,17 +233,32 @@ mt7530_mii_read(struct mt7530_priv *priv
-
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
-- if (ret < 0) {
-+ if (ret < 0)
-+ return ret;
-+
-+ lo = bus->read(bus, 0x1f, r);
-+ hi = bus->read(bus, 0x1f, 0x10);
-+
-+ *val = (hi << 16) | (lo & 0xffff);
-+
-+ return 0;
-+}
-+
-+static u32
-+mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
-+{
-+ int ret;
-+ u32 val;
-+
-+ ret = regmap_read(priv->regmap, reg, &val);
-+ if (ret) {
- WARN_ON_ONCE(1);
-- dev_err(&bus->dev,
-+ dev_err(priv->dev,
- "failed to read mt7530 register\n");
- return 0;
- }
-
-- lo = bus->read(bus, 0x1f, r);
-- hi = bus->read(bus, 0x1f, 0x10);
--
-- return (hi << 16) | (lo & 0xffff);
-+ return val;
- }
-
- static void
-@@ -283,14 +308,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32
- u32 mask, u32 set)
- {
- struct mii_bus *bus = priv->bus;
-- u32 val;
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-
-- val = mt7530_mii_read(priv, reg);
-- val &= ~mask;
-- val |= set;
-- mt7530_mii_write(priv, reg, val);
-+ regmap_update_bits(priv->regmap, reg, mask, set);
-
- mutex_unlock(&bus->mdio_lock);
- }
-@@ -298,7 +319,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32
- static void
- mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
- {
-- mt7530_rmw(priv, reg, 0, val);
-+ mt7530_rmw(priv, reg, val, val);
- }
-
- static void
-@@ -3158,22 +3179,6 @@ static const struct phylink_pcs_ops mt75
- .pcs_an_restart = mt7530_pcs_an_restart,
- };
-
--static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
--{
-- struct mt7530_priv *priv = context;
--
-- *val = mt7530_mii_read(priv, reg);
-- return 0;
--};
--
--static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
--{
-- struct mt7530_priv *priv = context;
--
-- mt7530_mii_write(priv, reg, val);
-- return 0;
--};
--
- static void
- mt7530_mdio_regmap_lock(void *mdio_lock)
- {
-@@ -3186,7 +3191,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
- mutex_unlock(mdio_lock);
- }
-
--static const struct regmap_bus mt7531_regmap_bus = {
-+static const struct regmap_bus mt7530_regmap_bus = {
- .reg_write = mt7530_regmap_write,
- .reg_read = mt7530_regmap_read,
- };
-@@ -3219,7 +3224,7 @@ mt7531_create_sgmii(struct mt7530_priv *
- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-
- regmap = devm_regmap_init(priv->dev,
-- &mt7531_regmap_bus, priv,
-+ &mt7530_regmap_bus, priv->bus,
- mt7531_pcs_config[i]);
- if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
-@@ -3385,6 +3390,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
- static int
- mt7530_probe(struct mdio_device *mdiodev)
- {
-+ static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
-
-@@ -3464,6 +3470,21 @@ mt7530_probe(struct mdio_device *mdiodev
- mutex_init(&priv->reg_mutex);
- dev_set_drvdata(&mdiodev->dev, priv);
-
-+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
-+ GFP_KERNEL);
-+ if (!regmap_config)
-+ return -ENOMEM;
-+
-+ regmap_config->reg_bits = 16;
-+ regmap_config->val_bits = 32;
-+ regmap_config->reg_stride = 4;
-+ regmap_config->max_register = MT7530_CREV;
-+ regmap_config->disable_locking = true;
-+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
-+ priv->bus, regmap_config);
-+ if (IS_ERR(priv->regmap))
-+ return PTR_ERR(priv->regmap);
-+
- return dsa_register_switch(priv->ds);
- }
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -785,6 +785,7 @@ struct mt753x_info {
- * @dev: The device pointer
- * @ds: The pointer to the dsa core structure
- * @bus: The bus used for the device and built-in PHY
-+ * @regmap: The regmap instance representing all switch registers
- * @rstc: The pointer to reset control used by MCM
- * @core_pwr: The power supplied into the core
- * @io_pwr: The power supplied into the I/O
-@@ -805,6 +806,7 @@ struct mt7530_priv {
- struct device *dev;
- struct dsa_switch *ds;
- struct mii_bus *bus;
-+ struct regmap *regmap;
- struct reset_control *rstc;
- struct regulator *core_pwr;
- struct regulator *io_pwr;
diff --git a/target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch
deleted file mode 100644
index 9cd817c056..0000000000
--- a/target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 6b64b5bc3045a7e1ee5278df4f4ff315cd43d88a Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:04 +0100
-Subject: [PATCH 07/48] net: dsa: mt7530: move SGMII PCS creation to
- mt7530_probe function
-
-Move creating the SGMII PCS from mt753x_setup() to the more appropriate
-mt7530_probe() function.
-This is done also in preparation of moving all functions related to
-MDIO-connected MT753x switches to a separate module.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 13 +++++++------
- 1 file changed, 7 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3270,12 +3270,6 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-- if (priv->id == ID_MT7531) {
-- ret = mt7531_create_sgmii(priv);
-- if (ret && priv->irq)
-- mt7530_free_irq_common(priv);
-- }
--
- return ret;
- }
-
-@@ -3393,6 +3387,7 @@ mt7530_probe(struct mdio_device *mdiodev
- static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
-+ int ret;
-
- dn = mdiodev->dev.of_node;
-
-@@ -3485,6 +3480,12 @@ mt7530_probe(struct mdio_device *mdiodev
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
-+ if (priv->id == ID_MT7531) {
-+ ret = mt7531_create_sgmii(priv);
-+ if (ret)
-+ return ret;
-+ }
-+
- return dsa_register_switch(priv->ds);
- }
-
diff --git a/target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch b/target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch
deleted file mode 100644
index 4f77078eef..0000000000
--- a/target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch
+++ /dev/null
@@ -1,273 +0,0 @@
-From 504d39cbda402df3e6fd123d040520393b6a6297 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:16 +0100
-Subject: [PATCH 08/48] net: dsa: mt7530: introduce mutex helpers
-
-As the MDIO bus lock only needs to be involved if actually operating
-on an MDIO-connected switch we will need to skip locking for built-in
-switches which are accessed via MMIO.
-Create helper functions which simplify that upcoming change.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++--------------------
- 1 file changed, 36 insertions(+), 37 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -143,31 +143,40 @@ err:
- }
-
- static void
--core_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+mt7530_mutex_lock(struct mt7530_priv *priv)
- {
-- struct mii_bus *bus = priv->bus;
-+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+}
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+static void
-+mt7530_mutex_unlock(struct mt7530_priv *priv)
-+{
-+ mutex_unlock(&priv->bus->mdio_lock);
-+}
-+
-+static void
-+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ mt7530_mutex_lock(priv);
-
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static void
- core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
- {
-- struct mii_bus *bus = priv->bus;
- u32 val;
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
- val &= ~mask;
- val |= set;
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static void
-@@ -264,13 +273,11 @@ mt7530_mii_read(struct mt7530_priv *priv
- static void
- mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
- {
-- struct mii_bus *bus = priv->bus;
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- mt7530_mii_write(priv, reg, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static u32
-@@ -282,14 +289,13 @@ _mt7530_unlocked_read(struct mt7530_dumm
- static u32
- _mt7530_read(struct mt7530_dummy_poll *p)
- {
-- struct mii_bus *bus = p->priv->bus;
- u32 val;
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(p->priv);
-
- val = mt7530_mii_read(p->priv, p->reg);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(p->priv);
-
- return val;
- }
-@@ -307,13 +313,11 @@ static void
- mt7530_rmw(struct mt7530_priv *priv, u32 reg,
- u32 mask, u32 set)
- {
-- struct mii_bus *bus = priv->bus;
--
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- regmap_update_bits(priv->regmap, reg, mask, set);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static void
-@@ -659,14 +663,13 @@ static int
- mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
- int regnum)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- u32 reg, val;
- int ret;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
- !(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -699,7 +702,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
-
- ret = val & MT7531_MDIO_RW_DATA_MASK;
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -708,14 +711,13 @@ static int
- mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
- int regnum, u32 data)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- u32 val, reg;
- int ret;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
- !(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -747,7 +749,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
- }
-
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -755,14 +757,13 @@ out:
- static int
- mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- int ret;
- u32 val;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
- !(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -785,7 +786,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
-
- ret = val & MT7531_MDIO_RW_DATA_MASK;
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -794,14 +795,13 @@ static int
- mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
- u16 data)
- {
-- struct mii_bus *bus = priv->bus;
- struct mt7530_dummy_poll p;
- int ret;
- u32 reg;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
- !(reg & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -823,7 +823,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
- }
-
- out:
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return ret;
- }
-@@ -1343,7 +1343,6 @@ static int
- mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct mt7530_priv *priv = ds->priv;
-- struct mii_bus *bus = priv->bus;
- int length;
- u32 val;
-
-@@ -1354,7 +1353,7 @@ mt7530_port_change_mtu(struct dsa_switch
- if (!dsa_is_cpu_port(ds, port))
- return 0;
-
-- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
-
- val = mt7530_mii_read(priv, MT7530_GMACCR);
- val &= ~MAX_RX_PKT_LEN_MASK;
-@@ -1375,7 +1374,7 @@ mt7530_port_change_mtu(struct dsa_switch
-
- mt7530_mii_write(priv, MT7530_GMACCR, val);
-
-- mutex_unlock(&bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- return 0;
- }
-@@ -2176,10 +2175,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
- u32 val;
- int p;
-
-- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
- val = mt7530_mii_read(priv, MT7530_SYS_INT_STS);
- mt7530_mii_write(priv, MT7530_SYS_INT_STS, val);
-- mutex_unlock(&priv->bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
-
- for (p = 0; p < MT7530_NUM_PHYS; p++) {
- if (BIT(p) & val) {
-@@ -2215,7 +2214,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
- {
- struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-
-- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ mt7530_mutex_lock(priv);
- }
-
- static void
-@@ -2224,7 +2223,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da
- struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-
- mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
-- mutex_unlock(&priv->bus->mdio_lock);
-+ mt7530_mutex_unlock(priv);
- }
-
- static struct irq_chip mt7530_irq_chip = {
diff --git a/target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch b/target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch
deleted file mode 100644
index 9cb0b2dd61..0000000000
--- a/target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From dbef24b66807eef7498740fa8b8441bee64a96c4 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:28 +0100
-Subject: [PATCH 09/48] net: dsa: mt7530: move p5_intf_modes() function to
- mt7530.c
-
-In preparation of splitting mt7530.c into a driver for MDIO-connected
-as well as MDIO-accessed built-in switches on one hand and MMIO-accessed
-built-in switches move the p5_inft_modes() function from mt7530.h to
-mt7530.c. The function is only needed there and will trigger a compiler
-warning about a defined but unused function otherwise when including
-mt7530.h in the to-be-introduced bus-specific drivers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++
- drivers/net/dsa/mt7530.h | 18 ------------------
- 2 files changed, 18 insertions(+), 18 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -964,6 +964,24 @@ mt7530_set_ageing_time(struct dsa_switch
- return 0;
- }
-
-+static const char *p5_intf_modes(unsigned int p5_interface)
-+{
-+ switch (p5_interface) {
-+ case P5_DISABLED:
-+ return "DISABLED";
-+ case P5_INTF_SEL_PHY_P0:
-+ return "PHY P0";
-+ case P5_INTF_SEL_PHY_P4:
-+ return "PHY P4";
-+ case P5_INTF_SEL_GMAC5:
-+ return "GMAC5";
-+ case P5_INTF_SEL_GMAC5_SGMII:
-+ return "GMAC5_SGMII";
-+ default:
-+ return "unknown";
-+ }
-+}
-+
- static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
- {
- struct mt7530_priv *priv = ds->priv;
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -720,24 +720,6 @@ enum p5_interface_select {
- P5_INTF_SEL_GMAC5_SGMII,
- };
-
--static const char *p5_intf_modes(unsigned int p5_interface)
--{
-- switch (p5_interface) {
-- case P5_DISABLED:
-- return "DISABLED";
-- case P5_INTF_SEL_PHY_P0:
-- return "PHY P0";
-- case P5_INTF_SEL_PHY_P4:
-- return "PHY P4";
-- case P5_INTF_SEL_GMAC5:
-- return "GMAC5";
-- case P5_INTF_SEL_GMAC5_SGMII:
-- return "GMAC5_SGMII";
-- default:
-- return "unknown";
-- }
--}
--
- struct mt7530_priv;
-
- struct mt753x_pcs {
diff --git a/target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch
deleted file mode 100644
index a6af682826..0000000000
--- a/target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From a0c6527a38d518ff175c1b6ce248e9b06cc98d3b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:39 +0100
-Subject: [PATCH 10/48] net: dsa: mt7530: introduce mt7530_probe_common helper
- function
-
-Move commonly used parts from mt7530_probe into new mt7530_probe_common
-helper function which will be used by both, mt7530_probe and the
-to-be-introduced mt7988_probe.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------
- 1 file changed, 54 insertions(+), 44 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3399,44 +3399,21 @@ static const struct of_device_id mt7530_
- MODULE_DEVICE_TABLE(of, mt7530_of_match);
-
- static int
--mt7530_probe(struct mdio_device *mdiodev)
-+mt7530_probe_common(struct mt7530_priv *priv)
- {
-- static struct regmap_config *regmap_config;
-- struct mt7530_priv *priv;
-- struct device_node *dn;
-- int ret;
-+ struct device *dev = priv->dev;
-
-- dn = mdiodev->dev.of_node;
--
-- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
- if (!priv->ds)
- return -ENOMEM;
-
-- priv->ds->dev = &mdiodev->dev;
-+ priv->ds->dev = dev;
- priv->ds->num_ports = MT7530_NUM_PORTS;
-
-- /* Use medatek,mcm property to distinguish hardware type that would
-- * casues a little bit differences on power-on sequence.
-- */
-- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-- if (priv->mcm) {
-- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
--
-- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-- if (IS_ERR(priv->rstc)) {
-- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-- return PTR_ERR(priv->rstc);
-- }
-- }
--
- /* Get the hardware identifier from the devicetree node.
- * We will need it for some of the clock and regulator setup.
- */
-- priv->info = of_device_get_match_data(&mdiodev->dev);
-+ priv->info = of_device_get_match_data(dev);
- if (!priv->info)
- return -EINVAL;
-
-@@ -3450,23 +3427,53 @@ mt7530_probe(struct mdio_device *mdiodev
- return -EINVAL;
-
- priv->id = priv->info->id;
-+ priv->dev = dev;
-+ priv->ds->priv = priv;
-+ priv->ds->ops = &mt7530_switch_ops;
-+ mutex_init(&priv->reg_mutex);
-+ dev_set_drvdata(dev, priv);
-
-- if (priv->id == ID_MT7530) {
-- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-- if (IS_ERR(priv->core_pwr))
-- return PTR_ERR(priv->core_pwr);
-+ return 0;
-+}
-
-- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-- if (IS_ERR(priv->io_pwr))
-- return PTR_ERR(priv->io_pwr);
-- }
-+static int
-+mt7530_probe(struct mdio_device *mdiodev)
-+{
-+ static struct regmap_config *regmap_config;
-+ struct mt7530_priv *priv;
-+ struct device_node *dn;
-+ int ret;
-+
-+ dn = mdiodev->dev.of_node;
-+
-+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-
-- /* Not MCM that indicates switch works as the remote standalone
-+ priv->bus = mdiodev->bus;
-+ priv->dev = &mdiodev->dev;
-+
-+ ret = mt7530_probe_common(priv);
-+ if (ret)
-+ return ret;
-+
-+ /* Use medatek,mcm property to distinguish hardware type that would
-+ * cause a little bit differences on power-on sequence.
-+ * Not MCM that indicates switch works as the remote standalone
- * integrated circuit so the GPIO pin would be used to complete
- * the reset, otherwise memory-mapped register accessing used
- * through syscon provides in the case of MCM.
- */
-- if (!priv->mcm) {
-+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-+ if (priv->mcm) {
-+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-+
-+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-+ if (IS_ERR(priv->rstc)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->rstc);
-+ }
-+ } else {
- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
- GPIOD_OUT_LOW);
- if (IS_ERR(priv->reset)) {
-@@ -3475,12 +3482,15 @@ mt7530_probe(struct mdio_device *mdiodev
- }
- }
-
-- priv->bus = mdiodev->bus;
-- priv->dev = &mdiodev->dev;
-- priv->ds->priv = priv;
-- priv->ds->ops = &mt7530_switch_ops;
-- mutex_init(&priv->reg_mutex);
-- dev_set_drvdata(&mdiodev->dev, priv);
-+ if (priv->id == ID_MT7530) {
-+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-+ if (IS_ERR(priv->core_pwr))
-+ return PTR_ERR(priv->core_pwr);
-+
-+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-+ if (IS_ERR(priv->io_pwr))
-+ return PTR_ERR(priv->io_pwr);
-+ }
-
- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
- GFP_KERNEL);
diff --git a/target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch
deleted file mode 100644
index 4192753e89..0000000000
--- a/target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From a7783b0b6f3b38abd34cecf515811691714dee57 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:18:50 +0100
-Subject: [PATCH 11/48] net: dsa: mt7530: introduce mt7530_remove_common helper
- function
-
-Move commonly used parts from mt7530_remove into new
-mt7530_remove_common helper function which will be used by both,
-mt7530_remove and the to-be-introduced mt7988_remove.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 18 ++++++++++++------
- 1 file changed, 12 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3517,6 +3517,17 @@ mt7530_probe(struct mdio_device *mdiodev
- }
-
- static void
-+mt7530_remove_common(struct mt7530_priv *priv)
-+{
-+ if (priv->irq)
-+ mt7530_free_irq(priv);
-+
-+ dsa_unregister_switch(priv->ds);
-+
-+ mutex_destroy(&priv->reg_mutex);
-+}
-+
-+static void
- mt7530_remove(struct mdio_device *mdiodev)
- {
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-@@ -3535,15 +3546,10 @@ mt7530_remove(struct mdio_device *mdiode
- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
- ret);
-
-- if (priv->irq)
-- mt7530_free_irq(priv);
--
-- dsa_unregister_switch(priv->ds);
-+ mt7530_remove_common(priv);
-
- for (i = 0; i < 2; ++i)
- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
--
-- mutex_destroy(&priv->reg_mutex);
- }
-
- static void mt7530_shutdown(struct mdio_device *mdiodev)
diff --git a/target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch
deleted file mode 100644
index 72a499381f..0000000000
--- a/target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch
+++ /dev/null
@@ -1,695 +0,0 @@
-From 5313432ca1e1a0677ad7b4f17a7e0186473f47aa Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:19:13 +0100
-Subject: [PATCH 12/48] net: dsa: mt7530: introduce separate MDIO driver
-
-Split MT7530 switch driver into a common part and a part specific
-for MDIO connected switches and multi-chip modules.
-Move MDIO-specific functions to newly introduced mt7530-mdio.c while
-keeping the common parts in mt7530.c.
-Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is
-implied by CONFIG_NET_DSA_MT7530.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS | 1 +
- drivers/net/dsa/Kconfig | 18 ++-
- drivers/net/dsa/Makefile | 1 +
- drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.c | 264 +--------------------------------
- drivers/net/dsa/mt7530.h | 6 +
- 6 files changed, 302 insertions(+), 259 deletions(-)
- create mode 100644 drivers/net/dsa/mt7530-mdio.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -13069,6 +13069,7 @@ M: Landen Chao <Landen.Chao@mediatek.com
- M: DENG Qingfang <dqfext@gmail.com>
- L: netdev@vger.kernel.org
- S: Maintained
-+F: drivers/net/dsa/mt7530-mdio.c
- F: drivers/net/dsa/mt7530.*
- F: net/dsa/tag_mtk.c
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -34,13 +34,25 @@ config NET_DSA_LANTIQ_GSWIP
- the xrx200 / VR9 SoC.
-
- config NET_DSA_MT7530
-- tristate "MediaTek MT753x and MT7621 Ethernet switch support"
-+ tristate "MediaTek MT7530 and MT7531 Ethernet switch support"
- select NET_DSA_TAG_MTK
-+ imply NET_DSA_MT7530_MDIO
-+ help
-+ This enables support for the MediaTek MT7530 and MT7531 Ethernet
-+ switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
-+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are
-+ supported as well.
-+
-+config NET_DSA_MT7530_MDIO
-+ tristate "MediaTek MT7530 MDIO interface driver"
-+ depends on NET_DSA_MT7530
- select MEDIATEK_GE_PHY
- select PCS_MTK_LYNXI
- help
-- This enables support for the MediaTek MT7530, MT7531, and MT7621
-- Ethernet switch chips.
-+ This enables support for the MediaTek MT7530 and MT7531 switch
-+ chips which are connected via MDIO, as well as multi-chip
-+ module MT7530 which can be found in the MT7621AT, MT7621DAT,
-+ MT7621ST and MT7623AI SoCs.
-
- config NET_DSA_MV88E6060
- tristate "Marvell 88E6060 ethernet switch chip support"
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi
- endif
- obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
- obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
-+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
- obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
- obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
- obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
---- /dev/null
-+++ b/drivers/net/dsa/mt7530-mdio.c
-@@ -0,0 +1,271 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+
-+#include <linux/gpio/consumer.h>
-+#include <linux/mdio.h>
-+#include <linux/module.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_mdio.h>
-+#include <linux/of_net.h>
-+#include <linux/of_platform.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/regulator/consumer.h>
-+#include <net/dsa.h>
-+
-+#include "mt7530.h"
-+
-+static int
-+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-+{
-+ struct mii_bus *bus = context;
-+ u16 page, r, lo, hi;
-+ int ret;
-+
-+ page = (reg >> 6) & 0x3ff;
-+ r = (reg >> 2) & 0xf;
-+ lo = val & 0xffff;
-+ hi = val >> 16;
-+
-+ /* MT7530 uses 31 as the pseudo port */
-+ ret = bus->write(bus, 0x1f, 0x1f, page);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = bus->write(bus, 0x1f, r, lo);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = bus->write(bus, 0x1f, 0x10, hi);
-+ return ret;
-+}
-+
-+static int
-+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-+{
-+ struct mii_bus *bus = context;
-+ u16 page, r, lo, hi;
-+ int ret;
-+
-+ page = (reg >> 6) & 0x3ff;
-+ r = (reg >> 2) & 0xf;
-+
-+ /* MT7530 uses 31 as the pseudo port */
-+ ret = bus->write(bus, 0x1f, 0x1f, page);
-+ if (ret < 0)
-+ return ret;
-+
-+ lo = bus->read(bus, 0x1f, r);
-+ hi = bus->read(bus, 0x1f, 0x10);
-+
-+ *val = (hi << 16) | (lo & 0xffff);
-+
-+ return 0;
-+}
-+
-+static void
-+mt7530_mdio_regmap_lock(void *mdio_lock)
-+{
-+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
-+}
-+
-+static void
-+mt7530_mdio_regmap_unlock(void *mdio_lock)
-+{
-+ mutex_unlock(mdio_lock);
-+}
-+
-+static const struct regmap_bus mt7530_regmap_bus = {
-+ .reg_write = mt7530_regmap_write,
-+ .reg_read = mt7530_regmap_read,
-+};
-+
-+static int
-+mt7531_create_sgmii(struct mt7530_priv *priv)
-+{
-+ struct regmap_config *mt7531_pcs_config[2];
-+ struct phylink_pcs *pcs;
-+ struct regmap *regmap;
-+ int i, ret = 0;
-+
-+ for (i = 0; i < 2; i++) {
-+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
-+ sizeof(struct regmap_config),
-+ GFP_KERNEL);
-+ if (!mt7531_pcs_config[i]) {
-+ ret = -ENOMEM;
-+ break;
-+ }
-+
-+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
-+ mt7531_pcs_config[i]->reg_bits = 16;
-+ mt7531_pcs_config[i]->val_bits = 32;
-+ mt7531_pcs_config[i]->reg_stride = 4;
-+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
-+ mt7531_pcs_config[i]->max_register = 0x17c;
-+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
-+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
-+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-+
-+ regmap = devm_regmap_init(priv->dev,
-+ &mt7530_regmap_bus, priv->bus,
-+ mt7531_pcs_config[i]);
-+ if (IS_ERR(regmap)) {
-+ ret = PTR_ERR(regmap);
-+ break;
-+ }
-+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
-+ MT7531_PHYA_CTRL_SIGNAL3, 0);
-+ if (!pcs) {
-+ ret = -ENXIO;
-+ break;
-+ }
-+ priv->ports[5 + i].sgmii_pcs = pcs;
-+ }
-+
-+ if (ret && i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
-+
-+ return ret;
-+}
-+
-+static const struct of_device_id mt7530_of_match[] = {
-+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
-+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
-+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, mt7530_of_match);
-+
-+static int
-+mt7530_probe(struct mdio_device *mdiodev)
-+{
-+ static struct regmap_config *regmap_config;
-+ struct mt7530_priv *priv;
-+ struct device_node *dn;
-+ int ret;
-+
-+ dn = mdiodev->dev.of_node;
-+
-+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->bus = mdiodev->bus;
-+ priv->dev = &mdiodev->dev;
-+
-+ ret = mt7530_probe_common(priv);
-+ if (ret)
-+ return ret;
-+
-+ /* Use medatek,mcm property to distinguish hardware type that would
-+ * cause a little bit differences on power-on sequence.
-+ * Not MCM that indicates switch works as the remote standalone
-+ * integrated circuit so the GPIO pin would be used to complete
-+ * the reset, otherwise memory-mapped register accessing used
-+ * through syscon provides in the case of MCM.
-+ */
-+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-+ if (priv->mcm) {
-+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-+
-+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-+ if (IS_ERR(priv->rstc)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->rstc);
-+ }
-+ } else {
-+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
-+ GPIOD_OUT_LOW);
-+ if (IS_ERR(priv->reset)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->reset);
-+ }
-+ }
-+
-+ if (priv->id == ID_MT7530) {
-+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-+ if (IS_ERR(priv->core_pwr))
-+ return PTR_ERR(priv->core_pwr);
-+
-+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-+ if (IS_ERR(priv->io_pwr))
-+ return PTR_ERR(priv->io_pwr);
-+ }
-+
-+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
-+ GFP_KERNEL);
-+ if (!regmap_config)
-+ return -ENOMEM;
-+
-+ regmap_config->reg_bits = 16;
-+ regmap_config->val_bits = 32;
-+ regmap_config->reg_stride = 4;
-+ regmap_config->max_register = MT7530_CREV;
-+ regmap_config->disable_locking = true;
-+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
-+ priv->bus, regmap_config);
-+ if (IS_ERR(priv->regmap))
-+ return PTR_ERR(priv->regmap);
-+
-+ if (priv->id == ID_MT7531) {
-+ ret = mt7531_create_sgmii(priv);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return dsa_register_switch(priv->ds);
-+}
-+
-+static void
-+mt7530_remove(struct mdio_device *mdiodev)
-+{
-+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+ int ret = 0, i;
-+
-+ if (!priv)
-+ return;
-+
-+ ret = regulator_disable(priv->core_pwr);
-+ if (ret < 0)
-+ dev_err(priv->dev,
-+ "Failed to disable core power: %d\n", ret);
-+
-+ ret = regulator_disable(priv->io_pwr);
-+ if (ret < 0)
-+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
-+ ret);
-+
-+ mt7530_remove_common(priv);
-+
-+ for (i = 0; i < 2; ++i)
-+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-+}
-+
-+static void mt7530_shutdown(struct mdio_device *mdiodev)
-+{
-+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+
-+ if (!priv)
-+ return;
-+
-+ dsa_switch_shutdown(priv->ds);
-+
-+ dev_set_drvdata(&mdiodev->dev, NULL);
-+}
-+
-+static struct mdio_driver mt7530_mdio_driver = {
-+ .probe = mt7530_probe,
-+ .remove = mt7530_remove,
-+ .shutdown = mt7530_shutdown,
-+ .mdiodrv.driver = {
-+ .name = "mt7530-mdio",
-+ .of_match_table = mt7530_of_match,
-+ },
-+};
-+
-+mdio_module_driver(mt7530_mdio_driver);
-+
-+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
-+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -14,7 +14,6 @@
- #include <linux/of_mdio.h>
- #include <linux/of_net.h>
- #include <linux/of_platform.h>
--#include <linux/pcs/pcs-mtk-lynxi.h>
- #include <linux/phylink.h>
- #include <linux/regmap.h>
- #include <linux/regulator/consumer.h>
-@@ -192,31 +191,6 @@ core_clear(struct mt7530_priv *priv, u32
- }
-
- static int
--mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
--{
-- struct mii_bus *bus = context;
-- u16 page, r, lo, hi;
-- int ret;
--
-- page = (reg >> 6) & 0x3ff;
-- r = (reg >> 2) & 0xf;
-- lo = val & 0xffff;
-- hi = val >> 16;
--
-- /* MT7530 uses 31 as the pseudo port */
-- ret = bus->write(bus, 0x1f, 0x1f, page);
-- if (ret < 0)
-- return ret;
--
-- ret = bus->write(bus, 0x1f, r, lo);
-- if (ret < 0)
-- return ret;
--
-- ret = bus->write(bus, 0x1f, 0x10, hi);
-- return ret;
--}
--
--static int
- mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
- {
- int ret;
-@@ -230,29 +204,6 @@ mt7530_mii_write(struct mt7530_priv *pri
- return ret;
- }
-
--static int
--mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
--{
-- struct mii_bus *bus = context;
-- u16 page, r, lo, hi;
-- int ret;
--
-- page = (reg >> 6) & 0x3ff;
-- r = (reg >> 2) & 0xf;
--
-- /* MT7530 uses 31 as the pseudo port */
-- ret = bus->write(bus, 0x1f, 0x1f, page);
-- if (ret < 0)
-- return ret;
--
-- lo = bus->read(bus, 0x1f, r);
-- hi = bus->read(bus, 0x1f, 0x10);
--
-- *val = (hi << 16) | (lo & 0xffff);
--
-- return 0;
--}
--
- static u32
- mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
- {
-@@ -3196,72 +3147,6 @@ static const struct phylink_pcs_ops mt75
- .pcs_an_restart = mt7530_pcs_an_restart,
- };
-
--static void
--mt7530_mdio_regmap_lock(void *mdio_lock)
--{
-- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
--}
--
--static void
--mt7530_mdio_regmap_unlock(void *mdio_lock)
--{
-- mutex_unlock(mdio_lock);
--}
--
--static const struct regmap_bus mt7530_regmap_bus = {
-- .reg_write = mt7530_regmap_write,
-- .reg_read = mt7530_regmap_read,
--};
--
--static int
--mt7531_create_sgmii(struct mt7530_priv *priv)
--{
-- struct regmap_config *mt7531_pcs_config[2];
-- struct phylink_pcs *pcs;
-- struct regmap *regmap;
-- int i, ret = 0;
--
-- for (i = 0; i < 2; i++) {
-- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
-- sizeof(struct regmap_config),
-- GFP_KERNEL);
-- if (!mt7531_pcs_config[i]) {
-- ret = -ENOMEM;
-- break;
-- }
--
-- mt7531_pcs_config[i]->name = i ? "port6" : "port5";
-- mt7531_pcs_config[i]->reg_bits = 16;
-- mt7531_pcs_config[i]->val_bits = 32;
-- mt7531_pcs_config[i]->reg_stride = 4;
-- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
-- mt7531_pcs_config[i]->max_register = 0x17c;
-- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
-- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
-- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
--
-- regmap = devm_regmap_init(priv->dev,
-- &mt7530_regmap_bus, priv->bus,
-- mt7531_pcs_config[i]);
-- if (IS_ERR(regmap)) {
-- ret = PTR_ERR(regmap);
-- break;
-- }
-- pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
-- MT7531_PHYA_CTRL_SIGNAL3, 0);
-- if (!pcs) {
-- ret = -ENXIO;
-- break;
-- }
-- priv->ports[5 + i].sgmii_pcs = pcs;
-- }
--
-- if (ret && i)
-- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
--
-- return ret;
--}
--
- static int
- mt753x_setup(struct dsa_switch *ds)
- {
-@@ -3320,7 +3205,7 @@ static int mt753x_set_mac_eee(struct dsa
- return 0;
- }
-
--static const struct dsa_switch_ops mt7530_switch_ops = {
-+const struct dsa_switch_ops mt7530_switch_ops = {
- .get_tag_protocol = mtk_get_tag_protocol,
- .setup = mt753x_setup,
- .preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
-@@ -3355,8 +3240,9 @@ static const struct dsa_switch_ops mt753
- .get_mac_eee = mt753x_get_mac_eee,
- .set_mac_eee = mt753x_set_mac_eee,
- };
-+EXPORT_SYMBOL_GPL(mt7530_switch_ops);
-
--static const struct mt753x_info mt753x_table[] = {
-+const struct mt753x_info mt753x_table[] = {
- [ID_MT7621] = {
- .id = ID_MT7621,
- .pcs_ops = &mt7530_pcs_ops,
-@@ -3389,16 +3275,9 @@ static const struct mt753x_info mt753x_t
- .mac_port_config = mt7531_mac_config,
- },
- };
-+EXPORT_SYMBOL_GPL(mt753x_table);
-
--static const struct of_device_id mt7530_of_match[] = {
-- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
-- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
-- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
-- { /* sentinel */ },
--};
--MODULE_DEVICE_TABLE(of, mt7530_of_match);
--
--static int
-+int
- mt7530_probe_common(struct mt7530_priv *priv)
- {
- struct device *dev = priv->dev;
-@@ -3435,88 +3314,9 @@ mt7530_probe_common(struct mt7530_priv *
-
- return 0;
- }
-+EXPORT_SYMBOL_GPL(mt7530_probe_common);
-
--static int
--mt7530_probe(struct mdio_device *mdiodev)
--{
-- static struct regmap_config *regmap_config;
-- struct mt7530_priv *priv;
-- struct device_node *dn;
-- int ret;
--
-- dn = mdiodev->dev.of_node;
--
-- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- priv->bus = mdiodev->bus;
-- priv->dev = &mdiodev->dev;
--
-- ret = mt7530_probe_common(priv);
-- if (ret)
-- return ret;
--
-- /* Use medatek,mcm property to distinguish hardware type that would
-- * cause a little bit differences on power-on sequence.
-- * Not MCM that indicates switch works as the remote standalone
-- * integrated circuit so the GPIO pin would be used to complete
-- * the reset, otherwise memory-mapped register accessing used
-- * through syscon provides in the case of MCM.
-- */
-- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-- if (priv->mcm) {
-- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
--
-- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-- if (IS_ERR(priv->rstc)) {
-- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-- return PTR_ERR(priv->rstc);
-- }
-- } else {
-- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
-- GPIOD_OUT_LOW);
-- if (IS_ERR(priv->reset)) {
-- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-- return PTR_ERR(priv->reset);
-- }
-- }
--
-- if (priv->id == ID_MT7530) {
-- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-- if (IS_ERR(priv->core_pwr))
-- return PTR_ERR(priv->core_pwr);
--
-- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-- if (IS_ERR(priv->io_pwr))
-- return PTR_ERR(priv->io_pwr);
-- }
--
-- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
-- GFP_KERNEL);
-- if (!regmap_config)
-- return -ENOMEM;
--
-- regmap_config->reg_bits = 16;
-- regmap_config->val_bits = 32;
-- regmap_config->reg_stride = 4;
-- regmap_config->max_register = MT7530_CREV;
-- regmap_config->disable_locking = true;
-- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
-- priv->bus, regmap_config);
-- if (IS_ERR(priv->regmap))
-- return PTR_ERR(priv->regmap);
--
-- if (priv->id == ID_MT7531) {
-- ret = mt7531_create_sgmii(priv);
-- if (ret)
-- return ret;
-- }
--
-- return dsa_register_switch(priv->ds);
--}
--
--static void
-+void
- mt7530_remove_common(struct mt7530_priv *priv)
- {
- if (priv->irq)
-@@ -3526,55 +3326,7 @@ mt7530_remove_common(struct mt7530_priv
-
- mutex_destroy(&priv->reg_mutex);
- }
--
--static void
--mt7530_remove(struct mdio_device *mdiodev)
--{
-- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-- int ret = 0, i;
--
-- if (!priv)
-- return;
--
-- ret = regulator_disable(priv->core_pwr);
-- if (ret < 0)
-- dev_err(priv->dev,
-- "Failed to disable core power: %d\n", ret);
--
-- ret = regulator_disable(priv->io_pwr);
-- if (ret < 0)
-- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
-- ret);
--
-- mt7530_remove_common(priv);
--
-- for (i = 0; i < 2; ++i)
-- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
--}
--
--static void mt7530_shutdown(struct mdio_device *mdiodev)
--{
-- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
--
-- if (!priv)
-- return;
--
-- dsa_switch_shutdown(priv->ds);
--
-- dev_set_drvdata(&mdiodev->dev, NULL);
--}
--
--static struct mdio_driver mt7530_mdio_driver = {
-- .probe = mt7530_probe,
-- .remove = mt7530_remove,
-- .shutdown = mt7530_shutdown,
-- .mdiodrv.driver = {
-- .name = "mt7530",
-- .of_match_table = mt7530_of_match,
-- },
--};
--
--mdio_module_driver(mt7530_mdio_driver);
-+EXPORT_SYMBOL_GPL(mt7530_remove_common);
-
- MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
- MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL
- p->reg = reg;
- }
-
-+int mt7530_probe_common(struct mt7530_priv *priv);
-+void mt7530_remove_common(struct mt7530_priv *priv);
-+
-+extern const struct dsa_switch_ops mt7530_switch_ops;
-+extern const struct mt753x_info mt753x_table[];
-+
- #endif /* __MT7530_H */
diff --git a/target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch b/target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch
deleted file mode 100644
index dae7dd4a48..0000000000
--- a/target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 86e1168a214b7ab0883acf1e7a6885a7a949e3e7 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:19:28 +0100
-Subject: [PATCH 13/48] net: dsa: mt7530: skip locking if MDIO bus isn't
- present
-
-As MT7530 and MT7531 internally use 32-bit wide registers, each access
-to any register of the switch requires several operations on the MDIO
-bus. Hence if there is congruent access, e.g. due to PCS or PHY
-polling, this can mess up and interfere with another ongoing register
-access sequence.
-
-However, the MDIO bus mutex is only relevant for MDIO-connected
-switches. Prepare switches which have there registers directly mapped
-into the SoCs register space via MMIO which do not require such
-locking. There we can simply use regmap's default locking mechanism.
-
-Hence guard mutex operations to only be performed in case of MDIO
-connected switches.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -144,13 +144,15 @@ err:
- static void
- mt7530_mutex_lock(struct mt7530_priv *priv)
- {
-- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ if (priv->bus)
-+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
- }
-
- static void
- mt7530_mutex_unlock(struct mt7530_priv *priv)
- {
-- mutex_unlock(&priv->bus->mdio_lock);
-+ if (priv->bus)
-+ mutex_unlock(&priv->bus->mdio_lock);
- }
-
- static void
diff --git a/target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch
deleted file mode 100644
index f5573fc6c4..0000000000
--- a/target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch
+++ /dev/null
@@ -1,421 +0,0 @@
-From a1b87b6322db9186c8689710fe3e98f59e540949 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 02:19:40 +0100
-Subject: [PATCH 14/48] net: dsa: mt7530: introduce driver for MT7988 built-in
- switch
-
-Add driver for the built-in Gigabit Ethernet switch which can be found
-in the MediaTek MT7988 SoC.
-
-The switch shares most of its design with MT7530 and MT7531, but has
-it's registers mapped into the SoCs register space rather than being
-connected externally or internally via MDIO.
-
-Introduce a new platform driver to support that.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS | 2 +
- drivers/net/dsa/Kconfig | 12 +++
- drivers/net/dsa/Makefile | 1 +
- drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
- drivers/net/dsa/mt7530.c | 135 +++++++++++++++++++++++++++++++++-
- drivers/net/dsa/mt7530.h | 12 +--
- 6 files changed, 253 insertions(+), 10 deletions(-)
- create mode 100644 drivers/net/dsa/mt7530-mmio.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -13067,9 +13067,11 @@ MEDIATEK SWITCH DRIVER
- M: Sean Wang <sean.wang@mediatek.com>
- M: Landen Chao <Landen.Chao@mediatek.com>
- M: DENG Qingfang <dqfext@gmail.com>
-+M: Daniel Golle <daniel@makrotopia.org>
- L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/dsa/mt7530-mdio.c
-+F: drivers/net/dsa/mt7530-mmio.c
- F: drivers/net/dsa/mt7530.*
- F: net/dsa/tag_mtk.c
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -37,6 +37,7 @@ config NET_DSA_MT7530
- tristate "MediaTek MT7530 and MT7531 Ethernet switch support"
- select NET_DSA_TAG_MTK
- imply NET_DSA_MT7530_MDIO
-+ imply NET_DSA_MT7530_MMIO
- help
- This enables support for the MediaTek MT7530 and MT7531 Ethernet
- switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
-@@ -54,6 +55,17 @@ config NET_DSA_MT7530_MDIO
- module MT7530 which can be found in the MT7621AT, MT7621DAT,
- MT7621ST and MT7623AI SoCs.
-
-+config NET_DSA_MT7530_MMIO
-+ tristate "MediaTek MT7530 MMIO interface driver"
-+ depends on NET_DSA_MT7530
-+ depends on HAS_IOMEM
-+ help
-+ This enables support for the built-in Ethernet switch found
-+ in the MediaTek MT7988 SoC.
-+ The switch is a similar design as MT7531, but the switch registers
-+ are directly mapped into the SoCs register space rather than being
-+ accessible via MDIO.
-+
- config NET_DSA_MV88E6060
- tristate "Marvell 88E6060 ethernet switch chip support"
- select NET_DSA_TAG_TRAILER
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -8,6 +8,7 @@ endif
- obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
- obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
- obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
-+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o
- obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
- obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
- obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
---- /dev/null
-+++ b/drivers/net/dsa/mt7530-mmio.c
-@@ -0,0 +1,101 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/regmap.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/reset.h>
-+#include <net/dsa.h>
-+
-+#include "mt7530.h"
-+
-+static const struct of_device_id mt7988_of_match[] = {
-+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, mt7988_of_match);
-+
-+static int
-+mt7988_probe(struct platform_device *pdev)
-+{
-+ static struct regmap_config *sw_regmap_config;
-+ struct mt7530_priv *priv;
-+ void __iomem *base_addr;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->bus = NULL;
-+ priv->dev = &pdev->dev;
-+
-+ ret = mt7530_probe_common(priv);
-+ if (ret)
-+ return ret;
-+
-+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->rstc)) {
-+ dev_err(&pdev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->rstc);
-+ }
-+
-+ base_addr = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(base_addr)) {
-+ dev_err(&pdev->dev, "cannot request I/O memory space\n");
-+ return -ENXIO;
-+ }
-+
-+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL);
-+ if (!sw_regmap_config)
-+ return -ENOMEM;
-+
-+ sw_regmap_config->name = "switch";
-+ sw_regmap_config->reg_bits = 16;
-+ sw_regmap_config->val_bits = 32;
-+ sw_regmap_config->reg_stride = 4;
-+ sw_regmap_config->max_register = MT7530_CREV;
-+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config);
-+ if (IS_ERR(priv->regmap))
-+ return PTR_ERR(priv->regmap);
-+
-+ return dsa_register_switch(priv->ds);
-+}
-+
-+static int
-+mt7988_remove(struct platform_device *pdev)
-+{
-+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
-+
-+ if (priv)
-+ mt7530_remove_common(priv);
-+
-+ return 0;
-+}
-+
-+static void mt7988_shutdown(struct platform_device *pdev)
-+{
-+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
-+
-+ if (!priv)
-+ return;
-+
-+ dsa_switch_shutdown(priv->ds);
-+
-+ dev_set_drvdata(&pdev->dev, NULL);
-+}
-+
-+static struct platform_driver mt7988_platform_driver = {
-+ .probe = mt7988_probe,
-+ .remove = mt7988_remove,
-+ .shutdown = mt7988_shutdown,
-+ .driver = {
-+ .name = "mt7530-mmio",
-+ .of_match_table = mt7988_of_match,
-+ },
-+};
-+module_platform_driver(mt7988_platform_driver);
-+
-+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
-+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2223,6 +2223,47 @@ static const struct irq_domain_ops mt753
- };
-
- static void
-+mt7988_irq_mask(struct irq_data *d)
-+{
-+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-+
-+ priv->irq_enable &= ~BIT(d->hwirq);
-+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
-+}
-+
-+static void
-+mt7988_irq_unmask(struct irq_data *d)
-+{
-+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
-+
-+ priv->irq_enable |= BIT(d->hwirq);
-+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
-+}
-+
-+static struct irq_chip mt7988_irq_chip = {
-+ .name = KBUILD_MODNAME,
-+ .irq_mask = mt7988_irq_mask,
-+ .irq_unmask = mt7988_irq_unmask,
-+};
-+
-+static int
-+mt7988_irq_map(struct irq_domain *domain, unsigned int irq,
-+ irq_hw_number_t hwirq)
-+{
-+ irq_set_chip_data(irq, domain->host_data);
-+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq);
-+ irq_set_nested_thread(irq, true);
-+ irq_set_noprobe(irq);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops mt7988_irq_domain_ops = {
-+ .map = mt7988_irq_map,
-+ .xlate = irq_domain_xlate_onecell,
-+};
-+
-+static void
- mt7530_setup_mdio_irq(struct mt7530_priv *priv)
- {
- struct dsa_switch *ds = priv->ds;
-@@ -2256,8 +2297,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
- return priv->irq ? : -EINVAL;
- }
-
-- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
-- &mt7530_irq_domain_ops, priv);
-+ if (priv->id == ID_MT7988)
-+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
-+ &mt7988_irq_domain_ops,
-+ priv);
-+ else
-+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
-+ &mt7530_irq_domain_ops,
-+ priv);
-+
- if (!priv->irq_domain) {
- dev_err(dev, "failed to create IRQ domain\n");
- return -ENOMEM;
-@@ -2762,6 +2810,25 @@ static void mt7531_mac_port_get_caps(str
- }
- }
-
-+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
-+ struct phylink_config *config)
-+{
-+ phy_interface_zero(config->supported_interfaces);
-+
-+ switch (port) {
-+ case 0 ... 4: /* Internal phy */
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ config->supported_interfaces);
-+ break;
-+
-+ case 6:
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ config->supported_interfaces);
-+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-+ MAC_10000FD;
-+ }
-+}
-+
- static int
- mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
- {
-@@ -2838,6 +2905,17 @@ static bool mt753x_is_mac_port(u32 port)
- }
-
- static int
-+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ if (dsa_is_cpu_port(ds, port) &&
-+ interface == PHY_INTERFACE_MODE_INTERNAL)
-+ return 0;
-+
-+ return -EINVAL;
-+}
-+
-+static int
- mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -2907,7 +2985,8 @@ mt753x_phylink_mac_config(struct dsa_swi
-
- switch (port) {
- case 0 ... 4: /* Internal phy */
-- if (state->interface != PHY_INTERFACE_MODE_GMII)
-+ if (state->interface != PHY_INTERFACE_MODE_GMII &&
-+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
- goto unsupported;
- break;
- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-@@ -2985,7 +3064,8 @@ static void mt753x_phylink_mac_link_up(s
- /* MT753x MAC works in 1G full duplex mode for all up-clocked
- * variants.
- */
-- if (interface == PHY_INTERFACE_MODE_TRGMII ||
-+ if (interface == PHY_INTERFACE_MODE_INTERNAL ||
-+ interface == PHY_INTERFACE_MODE_TRGMII ||
- (phy_interface_mode_is_8023z(interface))) {
- speed = SPEED_1000;
- duplex = DUPLEX_FULL;
-@@ -3065,6 +3145,21 @@ mt7531_cpu_port_config(struct dsa_switch
- return 0;
- }
-
-+static int
-+mt7988_cpu_port_config(struct dsa_switch *ds, int port)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ mt7530_write(priv, MT7530_PMCR_P(port),
-+ PMCR_CPU_PORT_SETTING(priv->id));
-+
-+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
-+ PHY_INTERFACE_MODE_INTERNAL, NULL,
-+ SPEED_10000, DUPLEX_FULL, true, true);
-+
-+ return 0;
-+}
-+
- static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
- {
-@@ -3207,6 +3302,27 @@ static int mt753x_set_mac_eee(struct dsa
- return 0;
- }
-
-+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-+{
-+ return 0;
-+}
-+
-+static int mt7988_setup(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ /* Reset the switch */
-+ reset_control_assert(priv->rstc);
-+ usleep_range(20, 50);
-+ reset_control_deassert(priv->rstc);
-+ usleep_range(20, 50);
-+
-+ /* Reset the switch PHYs */
-+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
-+
-+ return mt7531_setup_common(ds);
-+}
-+
- const struct dsa_switch_ops mt7530_switch_ops = {
- .get_tag_protocol = mtk_get_tag_protocol,
- .setup = mt753x_setup,
-@@ -3276,6 +3392,17 @@ const struct mt753x_info mt753x_table[]
- .mac_port_get_caps = mt7531_mac_port_get_caps,
- .mac_port_config = mt7531_mac_config,
- },
-+ [ID_MT7988] = {
-+ .id = ID_MT7988,
-+ .pcs_ops = &mt7530_pcs_ops,
-+ .sw_setup = mt7988_setup,
-+ .phy_read = mt7531_ind_phy_read,
-+ .phy_write = mt7531_ind_phy_write,
-+ .pad_setup = mt7988_pad_setup,
-+ .cpu_port_config = mt7988_cpu_port_config,
-+ .mac_port_get_caps = mt7988_mac_port_get_caps,
-+ .mac_port_config = mt7988_mac_config,
-+ },
- };
- EXPORT_SYMBOL_GPL(mt753x_table);
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -18,6 +18,7 @@ enum mt753x_id {
- ID_MT7530 = 0,
- ID_MT7621 = 1,
- ID_MT7531 = 2,
-+ ID_MT7988 = 3,
- };
-
- #define NUM_TRGMII_CTRL 5
-@@ -59,11 +60,11 @@ enum mt753x_id {
- #define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
- #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x)
-
--#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
-+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
- MT7531_CFC : MT7530_MFC)
--#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \
-+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
- MT7531_MIRROR_EN : MIRROR_EN)
--#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
-+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
- MT7531_MIRROR_MASK : MIRROR_MASK)
-
- /* Registers for BPDU and PAE frame control*/
-@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm {
- MT7531_FORCE_DPX | \
- MT7531_FORCE_RX_FC | \
- MT7531_FORCE_TX_FC)
--#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \
-- MT7531_FORCE_MODE : \
-- PMCR_FORCE_MODE)
-+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
-+ MT7531_FORCE_MODE : PMCR_FORCE_MODE)
- #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
diff --git a/target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch
deleted file mode 100644
index 40209b0305..0000000000
--- a/target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From ed01748319b25456c5226ed0cb5e49e970da0e4f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 16 Apr 2023 13:08:14 +0100
-Subject: [PATCH 15/48] net: dsa: mt7530: fix support for MT7531BE
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There are two variants of the MT7531 switch IC which got different
-features (and pins) regarding port 5:
- * MT7531AE: SGMII/1000Base-X/2500Base-X SerDes PCS
- * MT7531BE: RGMII
-
-Moving the creation of the SerDes PCS from mt753x_setup to mt7530_probe
-with commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation
-to mt7530_probe function") works fine for MT7531AE which got two
-instances of mtk-pcs-lynxi, however, MT7531BE requires mt7531_pll_setup
-to setup clocks before the single PCS on port 6 (usually used as CPU
-port) starts to work and hence the PCS creation failed on MT7531BE.
-
-Fix this by introducing a pointer to mt7531_create_sgmii function in
-struct mt7530_priv and call it again at the end of mt753x_setup like it
-was before commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS
-creation to mt7530_probe function").
-
-Fixes: 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/ZDvlLhhqheobUvOK@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530-mdio.c | 16 ++++++++--------
- drivers/net/dsa/mt7530.c | 6 ++++++
- drivers/net/dsa/mt7530.h | 4 ++--
- 3 files changed, 16 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/mt7530-mdio.c
-+++ b/drivers/net/dsa/mt7530-mdio.c
-@@ -81,14 +81,17 @@ static const struct regmap_bus mt7530_re
- };
-
- static int
--mt7531_create_sgmii(struct mt7530_priv *priv)
-+mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
- {
-- struct regmap_config *mt7531_pcs_config[2];
-+ struct regmap_config *mt7531_pcs_config[2] = {};
- struct phylink_pcs *pcs;
- struct regmap *regmap;
- int i, ret = 0;
-
-- for (i = 0; i < 2; i++) {
-+ /* MT7531AE has two SGMII units for port 5 and port 6
-+ * MT7531BE has only one SGMII unit for port 6
-+ */
-+ for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
- sizeof(struct regmap_config),
- GFP_KERNEL);
-@@ -208,11 +211,8 @@ mt7530_probe(struct mdio_device *mdiodev
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
-- if (priv->id == ID_MT7531) {
-- ret = mt7531_create_sgmii(priv);
-- if (ret)
-- return ret;
-- }
-+ if (priv->id == ID_MT7531)
-+ priv->create_sgmii = mt7531_create_sgmii;
-
- return dsa_register_switch(priv->ds);
- }
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3269,6 +3269,12 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-+ if (priv->create_sgmii) {
-+ ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
-+ if (ret && priv->irq)
-+ mt7530_free_irq(priv);
-+ }
-+
- return ret;
- }
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -779,10 +779,10 @@ struct mt753x_info {
- * registers
- * @p6_interface Holding the current port 6 interface
- * @p5_intf_sel: Holding the current port 5 interface select
-- *
- * @irq: IRQ number of the switch
- * @irq_domain: IRQ domain of the switch irq_chip
- * @irq_enable: IRQ enable bits, synced to SYS_INT_EN
-+ * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
- */
- struct mt7530_priv {
- struct device *dev;
-@@ -801,7 +801,6 @@ struct mt7530_priv {
- unsigned int p5_intf_sel;
- u8 mirror_rx;
- u8 mirror_tx;
--
- struct mt7530_port ports[MT7530_NUM_PORTS];
- struct mt753x_pcs pcs[MT7530_NUM_PORTS];
- /* protect among processes for registers access*/
-@@ -809,6 +808,7 @@ struct mt7530_priv {
- int irq;
- struct irq_domain *irq_domain;
- u32 irq_enable;
-+ int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
- };
-
- struct mt7530_hw_vlan_entry {
diff --git a/target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch b/target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch
deleted file mode 100644
index 78e332b1c2..0000000000
--- a/target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From fb6858e2c3b931433ea4d25871c272ee4c01bd99 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 16 Jun 2023 13:07:29 +0100
-Subject: [PATCH 17/48] net: dsa: mt7530: update PCS driver to use neg_mode
-
-Update mt7530's embedded PCS driver to use neg_mode, even though it
-makes no use of it or the "mode" argument. This makes the driver
-consistent with converted drivers.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://lore.kernel.org/r/E1qA8Ej-00EaGR-Fk@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3225,7 +3225,7 @@ static void mt7530_pcs_get_state(struct
- state->pause |= MLO_PAUSE_TX;
- }
-
--static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac)
-@@ -3253,6 +3253,7 @@ mt753x_setup(struct dsa_switch *ds)
- /* Initialise the PCS devices */
- for (i = 0; i < priv->ds->num_ports; i++) {
- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-+ priv->pcs[i].pcs.neg_mode = true;
- priv->pcs[i].priv = priv;
- priv->pcs[i].port = i;
- }
diff --git a/target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch b/target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch
deleted file mode 100644
index ffcf51dab5..0000000000
--- a/target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 03ede98ecc29b59fb364f735d6de0e6a4c1735fc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
-Date: Mon, 18 Sep 2023 21:19:12 +0200
-Subject: [PATCH 18/48] net: dsa: mt7530: Convert to platform remove callback
- returning void
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The .remove() callback for a platform driver returns an int which makes
-many driver authors wrongly assume it's possible to do error handling by
-returning an error code. However the value returned is ignored (apart
-from emitting a warning) and this typically results in resource leaks.
-To improve here there is a quest to make the remove callback return
-void. In the first step of this quest all drivers are converted to
-.remove_new() which already returns void. Eventually after all drivers
-are converted, .remove_new() is renamed to .remove().
-
-Trivially convert this driver from always returning zero in the remove
-callback to the void returning variant.
-
-Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530-mmio.c | 7 ++-----
- 1 file changed, 2 insertions(+), 5 deletions(-)
-
---- a/drivers/net/dsa/mt7530-mmio.c
-+++ b/drivers/net/dsa/mt7530-mmio.c
-@@ -62,15 +62,12 @@ mt7988_probe(struct platform_device *pde
- return dsa_register_switch(priv->ds);
- }
-
--static int
--mt7988_remove(struct platform_device *pdev)
-+static void mt7988_remove(struct platform_device *pdev)
- {
- struct mt7530_priv *priv = platform_get_drvdata(pdev);
-
- if (priv)
- mt7530_remove_common(priv);
--
-- return 0;
- }
-
- static void mt7988_shutdown(struct platform_device *pdev)
-@@ -87,7 +84,7 @@ static void mt7988_shutdown(struct platf
-
- static struct platform_driver mt7988_platform_driver = {
- .probe = mt7988_probe,
-- .remove = mt7988_remove,
-+ .remove_new = mt7988_remove,
- .shutdown = mt7988_shutdown,
- .driver = {
- .name = "mt7530-mmio",
diff --git a/target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch b/target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch
deleted file mode 100644
index d69ee7f104..0000000000
--- a/target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 1a1a723d47c046d6c251651c9ade589040dafacf Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 27 Sep 2023 13:13:56 +0100
-Subject: [PATCH 19/48] net: dsa: mt753x: remove mt753x_phylink_pcs_link_up()
-
-Remove the mt753x_phylink_pcs_link_up() function for two reasons:
-
-1) priv->pcs[i].pcs.neg_mode is set true, meaning it doesn't take a
- MLO_AN_FIXED anymore, but one of PHYLINK_PCS_NEG_*. However, this
- is inconsequential due to...
-2) priv->pcs[port].pcs.ops is always initialised to point at
- mt7530_pcs_ops, which does not have a pcs_link_up() member.
-
-So, let's remove mt753x_phylink_pcs_link_up() entirely.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://lore.kernel.org/r/E1qlTQS-008BWe-Va@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 11 -----------
- 1 file changed, 11 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3040,15 +3040,6 @@ static void mt753x_phylink_mac_link_down
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
- }
-
--static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs,
-- unsigned int mode,
-- phy_interface_t interface,
-- int speed, int duplex)
--{
-- if (pcs->ops->pcs_link_up)
-- pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
--}
--
- static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-@@ -3137,8 +3128,6 @@ mt7531_cpu_port_config(struct dsa_switch
- return ret;
- mt7530_write(priv, MT7530_PMCR_P(port),
- PMCR_CPU_PORT_SETTING(priv->id));
-- mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED,
-- interface, speed, DUPLEX_FULL);
- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
- speed, DUPLEX_FULL, true, true);
-
diff --git a/target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch b/target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch
deleted file mode 100644
index 8af6820270..0000000000
--- a/target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 51e9c79a4d40fa3a64c0fbdab1ebbebf7cce2dba Mon Sep 17 00:00:00 2001
-From: Justin Stitt <justinstitt@google.com>
-Date: Mon, 9 Oct 2023 18:29:19 +0000
-Subject: [PATCH 20/48] net: dsa: mt7530: replace deprecated strncpy with
- ethtool_sprintf
-
-`strncpy` is deprecated for use on NUL-terminated destination strings
-[1] and as such we should prefer more robust and less ambiguous string
-interfaces.
-
-ethtool_sprintf() is designed specifically for get_strings() usage.
-Let's replace strncpy in favor of this more robust and easier to
-understand interface.
-
-Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1]
-Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2]
-Link: https://github.com/KSPP/linux/issues/90
-Signed-off-by: Justin Stitt <justinstitt@google.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20231009-strncpy-drivers-net-dsa-mt7530-c-v1-1-ec6677a6436a@google.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -843,8 +843,7 @@ mt7530_get_strings(struct dsa_switch *ds
- return;
-
- for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++)
-- strncpy(data + i * ETH_GSTRING_LEN, mt7530_mib[i].name,
-- ETH_GSTRING_LEN);
-+ ethtool_sprintf(&data, "%s", mt7530_mib[i].name);
- }
-
- static void
diff --git a/target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch b/target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch
deleted file mode 100644
index 4c6c057739..0000000000
--- a/target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 38be6fdf7e93431e91aac3884837b22236325f68 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:34:31 +0300
-Subject: [PATCH 21/48] net: dsa: mt7530: support OF-based registration of
- switch MDIO bus
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently the MDIO bus of the switches the MT7530 DSA subdriver controls
-can only be registered as non-OF-based. Bring support for registering the
-bus OF-based.
-
-The subdrivers that control switches [with MDIO bus] probed on OF must
-follow this logic to support all cases properly:
-
-No switch MDIO bus defined: Populate ds->user_mii_bus, register the MDIO
-bus, set the interrupts for PHYs if "interrupt-controller" is defined at
-the switch node. This case should only be covered for the switches which
-their dt-bindings documentation didn't document the MDIO bus from the
-start. This is to keep supporting the device trees that do not describe the
-MDIO bus on the device tree but the MDIO bus is being used nonetheless.
-
-Switch MDIO bus defined: Don't populate ds->user_mii_bus, register the MDIO
-bus, set the interrupts for PHYs if ["interrupt-controller" is defined at
-the switch node and "interrupts" is defined at the PHY nodes under the
-switch MDIO bus node].
-
-Switch MDIO bus defined but explicitly disabled: If the device tree says
-status = "disabled" for the MDIO bus, we shouldn't need an MDIO bus at all.
-Instead, just exit as early as possible and do not call any MDIO API.
-
-The use of ds->user_mii_bus is inappropriate when the MDIO bus of the
-switch is described on the device tree [1], which is why we don't populate
-ds->user_mii_bus in that case.
-
-Link: https://lore.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/ [1]
-Suggested-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122053431.7751-1-arinc.unal@arinc9.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 34 ++++++++++++++++++++++++++--------
- 1 file changed, 26 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2350,24 +2350,40 @@ mt7530_free_irq_common(struct mt7530_pri
- static void
- mt7530_free_irq(struct mt7530_priv *priv)
- {
-- mt7530_free_mdio_irq(priv);
-+ struct device_node *mnp, *np = priv->dev->of_node;
-+
-+ mnp = of_get_child_by_name(np, "mdio");
-+ if (!mnp)
-+ mt7530_free_mdio_irq(priv);
-+ of_node_put(mnp);
-+
- mt7530_free_irq_common(priv);
- }
-
- static int
- mt7530_setup_mdio(struct mt7530_priv *priv)
- {
-+ struct device_node *mnp, *np = priv->dev->of_node;
- struct dsa_switch *ds = priv->ds;
- struct device *dev = priv->dev;
- struct mii_bus *bus;
- static int idx;
-- int ret;
-+ int ret = 0;
-+
-+ mnp = of_get_child_by_name(np, "mdio");
-+
-+ if (mnp && !of_device_is_available(mnp))
-+ goto out;
-
- bus = devm_mdiobus_alloc(dev);
-- if (!bus)
-- return -ENOMEM;
-+ if (!bus) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ if (!mnp)
-+ ds->slave_mii_bus = bus;
-
-- ds->slave_mii_bus = bus;
- bus->priv = priv;
- bus->name = KBUILD_MODNAME "-mii";
- snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d", idx++);
-@@ -2376,16 +2392,18 @@ mt7530_setup_mdio(struct mt7530_priv *pr
- bus->parent = dev;
- bus->phy_mask = ~ds->phys_mii_mask;
-
-- if (priv->irq)
-+ if (priv->irq && !mnp)
- mt7530_setup_mdio_irq(priv);
-
-- ret = devm_mdiobus_register(dev, bus);
-+ ret = devm_of_mdiobus_register(dev, bus, mnp);
- if (ret) {
- dev_err(dev, "failed to register MDIO bus: %d\n", ret);
-- if (priv->irq)
-+ if (priv->irq && !mnp)
- mt7530_free_mdio_irq(priv);
- }
-
-+out:
-+ of_node_put(mnp);
- return ret;
- }
-
diff --git a/target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch b/target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch
deleted file mode 100644
index 0b141b4a3f..0000000000
--- a/target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 022a254fafce88367914dfc8168fe687fc528cdb Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 24 Jan 2024 05:17:25 +0000
-Subject: [PATCH 22/48] net: dsa: mt7530: fix 10M/100M speed on MT7988 switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Setup PMCR port register for actual speed and duplex on internally
-connected PHYs of the MT7988 built-in switch. This fixes links with
-speeds other than 1000M.
-
-Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/a5b04dfa8256d8302f402545a51ac4c626fdba25.1706071272.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3072,8 +3072,7 @@ static void mt753x_phylink_mac_link_up(s
- /* MT753x MAC works in 1G full duplex mode for all up-clocked
- * variants.
- */
-- if (interface == PHY_INTERFACE_MODE_INTERNAL ||
-- interface == PHY_INTERFACE_MODE_TRGMII ||
-+ if (interface == PHY_INTERFACE_MODE_TRGMII ||
- (phy_interface_mode_is_8023z(interface))) {
- speed = SPEED_1000;
- duplex = DUPLEX_FULL;
diff --git a/target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch b/target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch
deleted file mode 100644
index 44d8e07c12..0000000000
--- a/target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From a385398f77fad9eabe7cdc253e1a356484acc316 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:35:52 +0300
-Subject: [PATCH 23/48] net: dsa: mt7530: always trap frames to active CPU port
- on MT7530
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-On the MT7530 switch, the CPU_PORT field indicates which CPU port to trap
-frames to, regardless of the affinity of the inbound user port.
-
-When multiple CPU ports are in use, if the DSA conduit interface is down,
-trapped frames won't be passed to the conduit interface.
-
-To make trapping frames work including this case, implement
-ds->ops->conduit_state_change() on this subdriver and set the CPU_PORT
-field to the numerically smallest CPU port whose conduit interface is up.
-Introduce the active_cpu_ports field to store the information of the active
-CPU ports. Correct the macros, CPU_PORT is bits 4 through 6 of the
-register.
-
-Add a comment to explain frame trapping for this switch.
-
-Currently, the driver doesn't support the use of multiple CPU ports so this
-is not necessarily a bug fix.
-
-Suggested-by: Vladimir Oltean <olteanv@gmail.com>
-Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-1-042401f2b279@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 35 +++++++++++++++++++++++++++++++----
- drivers/net/dsa/mt7530.h | 6 ++++--
- 2 files changed, 35 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1239,10 +1239,6 @@ mt753x_cpu_port_enable(struct dsa_switch
- mt7530_set(priv, MT7530_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
- UNU_FFP(BIT(port)));
-
-- /* Set CPU port number */
-- if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
-- mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
--
- /* Add the CPU port to the CPU port bitmap for MT7531. Trapped frames
- * will be forwarded to the CPU port that is affine to the inbound user
- * port.
-@@ -3314,6 +3310,36 @@ static int mt753x_set_mac_eee(struct dsa
- return 0;
- }
-
-+static void
-+mt753x_conduit_state_change(struct dsa_switch *ds,
-+ const struct net_device *conduit,
-+ bool operational)
-+{
-+ struct dsa_port *cpu_dp = conduit->dsa_ptr;
-+ struct mt7530_priv *priv = ds->priv;
-+ int val = 0;
-+ u8 mask;
-+
-+ /* Set the CPU port to trap frames to for MT7530. Trapped frames will be
-+ * forwarded to the numerically smallest CPU port whose conduit
-+ * interface is up.
-+ */
-+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
-+ return;
-+
-+ mask = BIT(cpu_dp->index);
-+
-+ if (operational)
-+ priv->active_cpu_ports |= mask;
-+ else
-+ priv->active_cpu_ports &= ~mask;
-+
-+ if (priv->active_cpu_ports)
-+ val = CPU_EN | CPU_PORT(__ffs(priv->active_cpu_ports));
-+
-+ mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
-+}
-+
- static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
- {
- return 0;
-@@ -3369,6 +3395,7 @@ const struct dsa_switch_ops mt7530_switc
- .phylink_mac_link_up = mt753x_phylink_mac_link_up,
- .get_mac_eee = mt753x_get_mac_eee,
- .set_mac_eee = mt753x_set_mac_eee,
-+ .master_state_change = mt753x_conduit_state_change,
- };
- EXPORT_SYMBOL_GPL(mt7530_switch_ops);
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -45,8 +45,8 @@ enum mt753x_id {
- #define UNU_FFP(x) (((x) & 0xff) << 8)
- #define UNU_FFP_MASK UNU_FFP(~0)
- #define CPU_EN BIT(7)
--#define CPU_PORT(x) ((x) << 4)
--#define CPU_MASK (0xf << 4)
-+#define CPU_PORT_MASK GENMASK(6, 4)
-+#define CPU_PORT(x) FIELD_PREP(CPU_PORT_MASK, x)
- #define MIRROR_EN BIT(3)
- #define MIRROR_PORT(x) ((x) & 0x7)
- #define MIRROR_MASK 0x7
-@@ -783,6 +783,7 @@ struct mt753x_info {
- * @irq_domain: IRQ domain of the switch irq_chip
- * @irq_enable: IRQ enable bits, synced to SYS_INT_EN
- * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
-+ * @active_cpu_ports: Holding the active CPU ports
- */
- struct mt7530_priv {
- struct device *dev;
-@@ -809,6 +810,7 @@ struct mt7530_priv {
- struct irq_domain *irq_domain;
- u32 irq_enable;
- int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
-+ u8 active_cpu_ports;
- };
-
- struct mt7530_hw_vlan_entry {
diff --git a/target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch b/target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch
deleted file mode 100644
index 3454948b86..0000000000
--- a/target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From e3c8f69af69e6c4022094309445c009faf5e8cef Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:35:53 +0300
-Subject: [PATCH 24/48] net: dsa: mt7530: use p5_interface_select as data type
- for p5_intf_sel
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use the p5_interface_select enumeration as the data type for the
-p5_intf_sel field. This ensures p5_intf_sel can only take the values
-defined in the p5_interface_select enumeration.
-
-Remove the explicit assignment of 0 to P5_DISABLED as the first enum item
-is automatically assigned 0.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-2-042401f2b279@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -713,7 +713,7 @@ struct mt7530_port {
-
- /* Port 5 interface select definitions */
- enum p5_interface_select {
-- P5_DISABLED = 0,
-+ P5_DISABLED,
- P5_INTF_SEL_PHY_P0,
- P5_INTF_SEL_PHY_P4,
- P5_INTF_SEL_GMAC5,
-@@ -799,7 +799,7 @@ struct mt7530_priv {
- bool mcm;
- phy_interface_t p6_interface;
- phy_interface_t p5_interface;
-- unsigned int p5_intf_sel;
-+ enum p5_interface_select p5_intf_sel;
- u8 mirror_rx;
- u8 mirror_tx;
- struct mt7530_port ports[MT7530_NUM_PORTS];
diff --git a/target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch b/target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch
deleted file mode 100644
index 357579e2bd..0000000000
--- a/target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-From b0d590a5cdd95ed863717b279751d6166083889f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:35:54 +0300
-Subject: [PATCH 25/48] net: dsa: mt7530: store port 5 SGMII capability of
- MT7531
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Introduce the p5_sgmii field to store the information for whether port 5
-has got SGMII or not. Instead of reading the MT7531_TOP_SIG_SR register
-multiple times, the register will be read once and the value will be
-stored on the p5_sgmii field. This saves unnecessary reads of the
-register.
-
-Move the comment about MT7531AE and MT7531BE to mt7531_setup(), where the
-switch is identified.
-
-Get rid of mt7531_dual_sgmii_supported() now that priv->p5_sgmii stores the
-information. Address the code where mt7531_dual_sgmii_supported() is used.
-
-Get rid of mt7531_is_rgmii_port() which just prints the opposite of
-priv->p5_sgmii.
-
-Instead of calling mt7531_pll_setup() then returning, do not call it if
-port 5 is SGMII.
-
-Remove P5_INTF_SEL_GMAC5_SGMII. The p5_interface_select enum is supposed to
-represent the mode that port 5 is being used in, not the hardware
-information of port 5. Set p5_intf_sel to P5_INTF_SEL_GMAC5 instead, if
-port 5 is not dsa_is_unused_port().
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-3-042401f2b279@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530-mdio.c | 7 ++---
- drivers/net/dsa/mt7530.c | 48 ++++++++++++-----------------------
- drivers/net/dsa/mt7530.h | 6 +++--
- 3 files changed, 22 insertions(+), 39 deletions(-)
-
---- a/drivers/net/dsa/mt7530-mdio.c
-+++ b/drivers/net/dsa/mt7530-mdio.c
-@@ -81,17 +81,14 @@ static const struct regmap_bus mt7530_re
- };
-
- static int
--mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
-+mt7531_create_sgmii(struct mt7530_priv *priv)
- {
- struct regmap_config *mt7531_pcs_config[2] = {};
- struct phylink_pcs *pcs;
- struct regmap *regmap;
- int i, ret = 0;
-
-- /* MT7531AE has two SGMII units for port 5 and port 6
-- * MT7531BE has only one SGMII unit for port 6
-- */
-- for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
-+ for (i = priv->p5_sgmii ? 0 : 1; i < 2; i++) {
- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
- sizeof(struct regmap_config),
- GFP_KERNEL);
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -487,15 +487,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
- return 0;
- }
-
--static bool mt7531_dual_sgmii_supported(struct mt7530_priv *priv)
--{
-- u32 val;
--
-- val = mt7530_read(priv, MT7531_TOP_SIG_SR);
--
-- return (val & PAD_DUAL_SGMII_EN) != 0;
--}
--
- static int
- mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
- {
-@@ -510,9 +501,6 @@ mt7531_pll_setup(struct mt7530_priv *pri
- u32 xtal;
- u32 val;
-
-- if (mt7531_dual_sgmii_supported(priv))
-- return;
--
- val = mt7530_read(priv, MT7531_CREV);
- top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
- hwstrap = mt7530_read(priv, MT7531_HWTRAP);
-@@ -927,8 +915,6 @@ static const char *p5_intf_modes(unsigne
- return "PHY P4";
- case P5_INTF_SEL_GMAC5:
- return "GMAC5";
-- case P5_INTF_SEL_GMAC5_SGMII:
-- return "GMAC5_SGMII";
- default:
- return "unknown";
- }
-@@ -2697,6 +2683,12 @@ mt7531_setup(struct dsa_switch *ds)
- return -ENODEV;
- }
-
-+ /* MT7531AE has got two SGMII units. One for port 5, one for port 6.
-+ * MT7531BE has got only one SGMII unit which is for port 6.
-+ */
-+ val = mt7530_read(priv, MT7531_TOP_SIG_SR);
-+ priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
-+
- /* all MACs must be forced link-down before sw reset */
- for (i = 0; i < MT7530_NUM_PORTS; i++)
- mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
-@@ -2706,21 +2698,18 @@ mt7531_setup(struct dsa_switch *ds)
- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
- SYS_CTRL_REG_RST);
-
-- mt7531_pll_setup(priv);
--
-- if (mt7531_dual_sgmii_supported(priv)) {
-- priv->p5_intf_sel = P5_INTF_SEL_GMAC5_SGMII;
--
-+ if (!priv->p5_sgmii) {
-+ mt7531_pll_setup(priv);
-+ } else {
- /* Let ds->slave_mii_bus be able to access external phy. */
- mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK,
- MT7531_EXT_P_MDC_11);
- mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK,
- MT7531_EXT_P_MDIO_12);
-- } else {
-- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
- }
-- dev_dbg(ds->dev, "P5 support %s interface\n",
-- p5_intf_modes(priv->p5_intf_sel));
-+
-+ if (!dsa_is_unused_port(ds, 5))
-+ priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
-
- mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
- MT7531_GPIO0_INTERRUPT);
-@@ -2787,11 +2776,6 @@ static void mt7530_mac_port_get_caps(str
- }
- }
-
--static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port)
--{
-- return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
--}
--
- static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
- {
-@@ -2804,7 +2788,7 @@ static void mt7531_mac_port_get_caps(str
- break;
-
- case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
-- if (mt7531_is_rgmii_port(priv, port)) {
-+ if (!priv->p5_sgmii) {
- phy_interface_set_rgmii(config->supported_interfaces);
- break;
- }
-@@ -2871,7 +2855,7 @@ static int mt7531_rgmii_setup(struct mt7
- {
- u32 val;
-
-- if (!mt7531_is_rgmii_port(priv, port)) {
-+ if (priv->p5_sgmii) {
- dev_err(priv->dev, "RGMII mode is not available for port %d\n",
- port);
- return -EINVAL;
-@@ -3114,7 +3098,7 @@ mt7531_cpu_port_config(struct dsa_switch
-
- switch (port) {
- case 5:
-- if (mt7531_is_rgmii_port(priv, port))
-+ if (!priv->p5_sgmii)
- interface = PHY_INTERFACE_MODE_RGMII;
- else
- interface = PHY_INTERFACE_MODE_2500BASEX;
-@@ -3272,7 +3256,7 @@ mt753x_setup(struct dsa_switch *ds)
- mt7530_free_irq_common(priv);
-
- if (priv->create_sgmii) {
-- ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
-+ ret = priv->create_sgmii(priv);
- if (ret && priv->irq)
- mt7530_free_irq(priv);
- }
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -717,7 +717,6 @@ enum p5_interface_select {
- P5_INTF_SEL_PHY_P0,
- P5_INTF_SEL_PHY_P4,
- P5_INTF_SEL_GMAC5,
-- P5_INTF_SEL_GMAC5_SGMII,
- };
-
- struct mt7530_priv;
-@@ -779,6 +778,8 @@ struct mt753x_info {
- * registers
- * @p6_interface Holding the current port 6 interface
- * @p5_intf_sel: Holding the current port 5 interface select
-+ * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
-+ * has got SGMII
- * @irq: IRQ number of the switch
- * @irq_domain: IRQ domain of the switch irq_chip
- * @irq_enable: IRQ enable bits, synced to SYS_INT_EN
-@@ -800,6 +801,7 @@ struct mt7530_priv {
- phy_interface_t p6_interface;
- phy_interface_t p5_interface;
- enum p5_interface_select p5_intf_sel;
-+ bool p5_sgmii;
- u8 mirror_rx;
- u8 mirror_tx;
- struct mt7530_port ports[MT7530_NUM_PORTS];
-@@ -809,7 +811,7 @@ struct mt7530_priv {
- int irq;
- struct irq_domain *irq_domain;
- u32 irq_enable;
-- int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
-+ int (*create_sgmii)(struct mt7530_priv *priv);
- u8 active_cpu_ports;
- };
-
diff --git a/target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch b/target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch
deleted file mode 100644
index 46dbd53ede..0000000000
--- a/target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From 0dcde4c1e7c47822a6b00d6f96b7f19e51536026 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:35:55 +0300
-Subject: [PATCH 26/48] net: dsa: mt7530: improve comments regarding switch
- ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There's no logic to numerically order the CPU ports. Just state the port
-number instead.
-
-Remove the irrelevant PHY muxing information from
-mt7530_mac_port_get_caps(). Explain the supported MII modes instead.
-
-Remove the out of place PHY muxing information from
-mt753x_phylink_mac_config(). The function is for MT7530, MT7531, and the
-switch on the MT7988 SoC but there's no PHY muxing on MT7531 or the switch
-on the MT7988 SoC.
-
-These comments were gradually introduced with the commits below.
-commit ca366d6c889b ("net: dsa: mt7530: Convert to PHYLINK API")
-commit 38f790a80560 ("net: dsa: mt7530: Add support for port 5")
-commit 88bdef8be9f6 ("net: dsa: mt7530: Extend device data ready for adding
-a new hardware")
-commit c288575f7810 ("net: dsa: mt7530: Add the support of MT7531 switch")
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-4-042401f2b279@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 30 ++++++++++++++++++++----------
- 1 file changed, 20 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2754,12 +2754,14 @@ static void mt7530_mac_port_get_caps(str
- struct phylink_config *config)
- {
- switch (port) {
-- case 0 ... 4: /* Internal phy */
-+ /* Ports which are connected to switch PHYs. There is no MII pinout. */
-+ case 0 ... 4:
- __set_bit(PHY_INTERFACE_MODE_GMII,
- config->supported_interfaces);
- break;
-
-- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-+ /* Port 5 supports rgmii with delays, mii, and gmii. */
-+ case 5:
- phy_interface_set_rgmii(config->supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_MII,
- config->supported_interfaces);
-@@ -2767,7 +2769,8 @@ static void mt7530_mac_port_get_caps(str
- config->supported_interfaces);
- break;
-
-- case 6: /* 1st cpu port */
-+ /* Port 6 supports rgmii and trgmii. */
-+ case 6:
- __set_bit(PHY_INTERFACE_MODE_RGMII,
- config->supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_TRGMII,
-@@ -2782,19 +2785,24 @@ static void mt7531_mac_port_get_caps(str
- struct mt7530_priv *priv = ds->priv;
-
- switch (port) {
-- case 0 ... 4: /* Internal phy */
-+ /* Ports which are connected to switch PHYs. There is no MII pinout. */
-+ case 0 ... 4:
- __set_bit(PHY_INTERFACE_MODE_GMII,
- config->supported_interfaces);
- break;
-
-- case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
-+ /* Port 5 supports rgmii with delays on MT7531BE, sgmii/802.3z on
-+ * MT7531AE.
-+ */
-+ case 5:
- if (!priv->p5_sgmii) {
- phy_interface_set_rgmii(config->supported_interfaces);
- break;
- }
- fallthrough;
-
-- case 6: /* 1st cpu port supports sgmii/8023z only */
-+ /* Port 6 supports sgmii/802.3z. */
-+ case 6:
- __set_bit(PHY_INTERFACE_MODE_SGMII,
- config->supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-@@ -2813,11 +2821,13 @@ static void mt7988_mac_port_get_caps(str
- phy_interface_zero(config->supported_interfaces);
-
- switch (port) {
-- case 0 ... 4: /* Internal phy */
-+ /* Ports which are connected to switch PHYs. There is no MII pinout. */
-+ case 0 ... 4:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
- break;
-
-+ /* Port 6 is connected to SoC's XGMII MAC. There is no MII pinout. */
- case 6:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
-@@ -2981,12 +2991,12 @@ mt753x_phylink_mac_config(struct dsa_swi
- u32 mcr_cur, mcr_new;
-
- switch (port) {
-- case 0 ... 4: /* Internal phy */
-+ case 0 ... 4:
- if (state->interface != PHY_INTERFACE_MODE_GMII &&
- state->interface != PHY_INTERFACE_MODE_INTERNAL)
- goto unsupported;
- break;
-- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-+ case 5:
- if (priv->p5_interface == state->interface)
- break;
-
-@@ -2996,7 +3006,7 @@ mt753x_phylink_mac_config(struct dsa_swi
- if (priv->p5_intf_sel != P5_DISABLED)
- priv->p5_interface = state->interface;
- break;
-- case 6: /* 1st cpu port */
-+ case 6:
- if (priv->p6_interface == state->interface)
- break;
-
diff --git a/target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch b/target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch
deleted file mode 100644
index 43f629b243..0000000000
--- a/target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 0f03d9bfa1da1d26cb950e4b35b1ff7b9be1828f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:35:56 +0300
-Subject: [PATCH 27/48] net: dsa: mt7530: improve code path for setting up port
- 5
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There're two code paths for setting up port 5:
-
-mt7530_setup()
--> mt7530_setup_port5()
-
-mt753x_phylink_mac_config()
--> mt753x_mac_config()
- -> mt7530_mac_config()
- -> mt7530_setup_port5()
-
-Currently mt7530_setup_port5() from mt7530_setup() always runs. If port 5
-is used as a CPU, DSA, or user port, mt7530_setup_port5() from
-mt753x_phylink_mac_config() won't run. That is because priv->p5_interface
-set on mt7530_setup_port5() will match state->interface on
-mt753x_phylink_mac_config() which will stop running mt7530_setup_port5()
-again.
-
-Therefore, mt7530_setup_port5() will never run from
-mt753x_phylink_mac_config().
-
-Address this by not running mt7530_setup_port5() from mt7530_setup() if
-port 5 is used as a CPU, DSA, or user port. This driver isn't in the
-dsa_switches_apply_workarounds[] array so phylink will always be present.
-
-To keep the cases where port 5 isn't controlled by phylink working as
-before, preserve the mt7530_setup_port5() call from mt7530_setup().
-
-Do not set priv->p5_intf_sel to P5_DISABLED. It is already set to that when
-"priv" is allocated.
-
-Move setting the interface to a more specific location. It's supposed to be
-overwritten if PHY muxing is detected.
-
-Improve the comment which explains the process.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-5-042401f2b279@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 17 ++++++++---------
- 1 file changed, 8 insertions(+), 9 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2532,16 +2532,15 @@ mt7530_setup(struct dsa_switch *ds)
- return ret;
-
- /* Setup port 5 */
-- priv->p5_intf_sel = P5_DISABLED;
-- interface = PHY_INTERFACE_MODE_NA;
--
- if (!dsa_is_unused_port(ds, 5)) {
- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
-- ret = of_get_phy_mode(dsa_to_port(ds, 5)->dn, &interface);
-- if (ret && ret != -ENODEV)
-- return ret;
- } else {
-- /* Scan the ethernet nodes. look for GMAC1, lookup used phy */
-+ /* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY.
-+ * Set priv->p5_intf_sel to the appropriate value if PHY muxing
-+ * is detected.
-+ */
-+ interface = PHY_INTERFACE_MODE_NA;
-+
- for_each_child_of_node(dn, mac_np) {
- if (!of_device_is_compatible(mac_np,
- "mediatek,eth-mac"))
-@@ -2572,6 +2571,8 @@ mt7530_setup(struct dsa_switch *ds)
- of_node_put(phy_node);
- break;
- }
-+
-+ mt7530_setup_port5(ds, interface);
- }
-
- #ifdef CONFIG_GPIOLIB
-@@ -2582,8 +2583,6 @@ mt7530_setup(struct dsa_switch *ds)
- }
- #endif /* CONFIG_GPIOLIB */
-
-- mt7530_setup_port5(ds, interface);
--
- /* Flush the FDB table */
- ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
- if (ret < 0)
diff --git a/target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch b/target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch
deleted file mode 100644
index 385d587729..0000000000
--- a/target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 120581c81ad19704a9325505c83a82b7e760e96e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:35:57 +0300
-Subject: [PATCH 28/48] net: dsa: mt7530: do not set priv->p5_interface on
- mt7530_setup_port5()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Running mt7530_setup_port5() from mt7530_setup() used to handle all cases
-of configuring port 5, including phylink.
-
-Setting priv->p5_interface under mt7530_setup_port5() makes sure that
-mt7530_setup_port5() from mt753x_phylink_mac_config() won't run.
-
-The commit ("net: dsa: mt7530: improve code path for setting up port 5")
-makes so that mt7530_setup_port5() from mt7530_setup() runs only on
-non-phylink cases.
-
-Get rid of unnecessarily setting priv->p5_interface under
-mt7530_setup_port5() as port 5 phylink configuration will be done by
-running mt7530_setup_port5() from mt753x_phylink_mac_config() now.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-6-042401f2b279@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -985,8 +985,6 @@ static void mt7530_setup_port5(struct ds
- dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
- val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
-
-- priv->p5_interface = interface;
--
- unlock_exit:
- mutex_unlock(&priv->reg_mutex);
- }
diff --git a/target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch b/target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch
deleted file mode 100644
index b4c0b75c49..0000000000
--- a/target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 3b423061eb3a62e59b57939ae1e1234756a0f6a1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Jan 2024 08:35:58 +0300
-Subject: [PATCH 29/48] net: dsa: mt7530: do not run mt7530_setup_port5() if
- port 5 is disabled
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There's no need to run all the code on mt7530_setup_port5() if port 5 is
-disabled. The only case for calling mt7530_setup_port5() from
-mt7530_setup() is when PHY muxing is enabled. That is because port 5 is not
-defined as a port on the devicetree, therefore, it cannot be controlled by
-phylink.
-
-Because of this, run mt7530_setup_port5() if priv->p5_intf_sel is
-P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4. Remove the P5_DISABLED case from
-mt7530_setup_port5().
-
-Stop initialising the interface variable as the remaining cases will always
-call mt7530_setup_port5() with it initialised.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-7-042401f2b279@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 9 +++------
- 1 file changed, 3 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -949,9 +949,6 @@ static void mt7530_setup_port5(struct ds
- /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
- val &= ~MHWTRAP_P5_DIS;
- break;
-- case P5_DISABLED:
-- interface = PHY_INTERFACE_MODE_NA;
-- break;
- default:
- dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
- priv->p5_intf_sel);
-@@ -2537,8 +2534,6 @@ mt7530_setup(struct dsa_switch *ds)
- * Set priv->p5_intf_sel to the appropriate value if PHY muxing
- * is detected.
- */
-- interface = PHY_INTERFACE_MODE_NA;
--
- for_each_child_of_node(dn, mac_np) {
- if (!of_device_is_compatible(mac_np,
- "mediatek,eth-mac"))
-@@ -2570,7 +2565,9 @@ mt7530_setup(struct dsa_switch *ds)
- break;
- }
-
-- mt7530_setup_port5(ds, interface);
-+ if (priv->p5_intf_sel == P5_INTF_SEL_PHY_P0 ||
-+ priv->p5_intf_sel == P5_INTF_SEL_PHY_P4)
-+ mt7530_setup_port5(ds, interface);
- }
-
- #ifdef CONFIG_GPIOLIB
diff --git a/target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch b/target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch
deleted file mode 100644
index 89527e2b39..0000000000
--- a/target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 959f4ac4940bebb84bdd25ac61470b3965e1e475 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 6 Feb 2024 01:08:02 +0300
-Subject: [PATCH 30/48] net: dsa: mt7530: empty default case on
- mt7530_setup_port5()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There're two code paths for setting up port 5:
-
-mt7530_setup()
--> mt7530_setup_port5()
-
-mt753x_phylink_mac_config()
--> mt753x_mac_config()
- -> mt7530_mac_config()
- -> mt7530_setup_port5()
-
-On the first code path, priv->p5_intf_sel is either set to
-P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4 when mt7530_setup_port5() is run.
-
-On the second code path, priv->p5_intf_sel is set to P5_INTF_SEL_GMAC5 when
-mt7530_setup_port5() is run.
-
-Empty the default case which will never run but is needed nonetheless to
-handle all the remaining enumeration values.
-
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-1-d7d92a185cb1@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -950,9 +950,7 @@ static void mt7530_setup_port5(struct ds
- val &= ~MHWTRAP_P5_DIS;
- break;
- default:
-- dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
-- priv->p5_intf_sel);
-- goto unlock_exit;
-+ break;
- }
-
- /* Setup RGMII settings */
-@@ -982,7 +980,6 @@ static void mt7530_setup_port5(struct ds
- dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
- val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
-
--unlock_exit:
- mutex_unlock(&priv->reg_mutex);
- }
-
diff --git a/target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch b/target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch
deleted file mode 100644
index 0dc4baf0c7..0000000000
--- a/target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 9ec0a800c8e0850e1358b7402d6af557af81cb38 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 6 Feb 2024 01:08:03 +0300
-Subject: [PATCH 31/48] net: dsa: mt7530: move XTAL check to mt7530_setup()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The crystal frequency concerns the switch core. The frequency should be
-checked when the switch is being set up so the driver can reject the
-unsupported hardware earlier and without requiring port 6 to be used.
-
-Move it to mt7530_setup(). Drop the unnecessary function printing.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-2-d7d92a185cb1@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 13 ++++++-------
- 1 file changed, 6 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -422,13 +422,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
-
- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
-
-- if (xtal == HWTRAP_XTAL_20MHZ) {
-- dev_err(priv->dev,
-- "%s: MT7530 with a 20MHz XTAL is not supported!\n",
-- __func__);
-- return -EINVAL;
-- }
--
- switch (interface) {
- case PHY_INTERFACE_MODE_RGMII:
- trgint = 0;
-@@ -2461,6 +2454,12 @@ mt7530_setup(struct dsa_switch *ds)
- return -ENODEV;
- }
-
-+ if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) {
-+ dev_err(priv->dev,
-+ "MT7530 with a 20MHz XTAL is not supported!\n");
-+ return -EINVAL;
-+ }
-+
- /* Reset the switch through internal reset */
- mt7530_write(priv, MT7530_SYS_CTRL,
- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
diff --git a/target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch b/target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch
deleted file mode 100644
index 46e1b50f24..0000000000
--- a/target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 7199c736aa8cd9c69ae681a9c733408372c2ce76 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 6 Feb 2024 01:08:04 +0300
-Subject: [PATCH 32/48] net: dsa: mt7530: simplify mt7530_pad_clk_setup()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This code is from before this driver was converted to phylink API. Phylink
-deals with the unsupported interface cases before mt7530_pad_clk_setup() is
-run. Therefore, the default case would never run. However, it must be
-defined nonetheless to handle all the remaining enumeration values, the
-phy-modes.
-
-Switch to if statement for RGMII and return which simplifies the code and
-saves an indent.
-
-Set P6_INTF_MODE, which is the three least significant bits of the
-MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
-after reset. This is to keep supporting dynamic reconfiguration of the port
-in the case the interface changes from TRGMII to RGMII.
-
-Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
-being used.
-
-Read XTAL after checking for RGMII as it's only needed for the TRGMII
-interface mode.
-
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-3-d7d92a185cb1@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 91 ++++++++++++++++++----------------------
- 1 file changed, 40 insertions(+), 51 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -418,65 +418,54 @@ static int
- mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
- {
- struct mt7530_priv *priv = ds->priv;
-- u32 ncpo1, ssc_delta, trgint, xtal;
-+ u32 ncpo1, ssc_delta, xtal;
-
-- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
-+ /* Disable the MT7530 TRGMII clocks */
-+ core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
-
-- switch (interface) {
-- case PHY_INTERFACE_MODE_RGMII:
-- trgint = 0;
-- break;
-- case PHY_INTERFACE_MODE_TRGMII:
-- trgint = 1;
-- if (xtal == HWTRAP_XTAL_25MHZ)
-- ssc_delta = 0x57;
-- else
-- ssc_delta = 0x87;
-- if (priv->id == ID_MT7621) {
-- /* PLL frequency: 125MHz: 1.0GBit */
-- if (xtal == HWTRAP_XTAL_40MHZ)
-- ncpo1 = 0x0640;
-- if (xtal == HWTRAP_XTAL_25MHZ)
-- ncpo1 = 0x0a00;
-- } else { /* PLL frequency: 250MHz: 2.0Gbit */
-- if (xtal == HWTRAP_XTAL_40MHZ)
-- ncpo1 = 0x0c80;
-- if (xtal == HWTRAP_XTAL_25MHZ)
-- ncpo1 = 0x1400;
-- }
-- break;
-- default:
-- dev_err(priv->dev, "xMII interface %d not supported\n",
-- interface);
-- return -EINVAL;
-+ if (interface == PHY_INTERFACE_MODE_RGMII) {
-+ mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
-+ P6_INTF_MODE(0));
-+ return 0;
- }
-
-- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
-- P6_INTF_MODE(trgint));
-+ mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
-
-- if (trgint) {
-- /* Disable the MT7530 TRGMII clocks */
-- core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
--
-- /* Setup the MT7530 TRGMII Tx Clock */
-- core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
-- core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
-- core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
-- core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
-- core_write(priv, CORE_PLL_GROUP4,
-- RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
-- RG_SYSPLL_BIAS_LPF_EN);
-- core_write(priv, CORE_PLL_GROUP2,
-- RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-- RG_SYSPLL_POSDIV(1));
-- core_write(priv, CORE_PLL_GROUP7,
-- RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
-- RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
-+ xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
-
-- /* Enable the MT7530 TRGMII clocks */
-- core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
-+ if (xtal == HWTRAP_XTAL_25MHZ)
-+ ssc_delta = 0x57;
-+ else
-+ ssc_delta = 0x87;
-+
-+ if (priv->id == ID_MT7621) {
-+ /* PLL frequency: 125MHz: 1.0GBit */
-+ if (xtal == HWTRAP_XTAL_40MHZ)
-+ ncpo1 = 0x0640;
-+ if (xtal == HWTRAP_XTAL_25MHZ)
-+ ncpo1 = 0x0a00;
-+ } else { /* PLL frequency: 250MHz: 2.0Gbit */
-+ if (xtal == HWTRAP_XTAL_40MHZ)
-+ ncpo1 = 0x0c80;
-+ if (xtal == HWTRAP_XTAL_25MHZ)
-+ ncpo1 = 0x1400;
- }
-
-+ /* Setup the MT7530 TRGMII Tx Clock */
-+ core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
-+ core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
-+ core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
-+ core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
-+ core_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
-+ RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
-+ core_write(priv, CORE_PLL_GROUP2, RG_SYSPLL_EN_NORMAL |
-+ RG_SYSPLL_VODEN | RG_SYSPLL_POSDIV(1));
-+ core_write(priv, CORE_PLL_GROUP7, RG_LCDDS_PCW_NCPO_CHG |
-+ RG_LCCDS_C(3) | RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
-+
-+ /* Enable the MT7530 TRGMII clocks */
-+ core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch b/target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch
deleted file mode 100644
index 7d78b7df70..0000000000
--- a/target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 921a7deee767aa157b5372863a4c1cac53e5c53a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 6 Feb 2024 01:08:05 +0300
-Subject: [PATCH 33/48] net: dsa: mt7530: call port 6 setup from
- mt7530_mac_config()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more
-things than setting up port 6. That part was moved to more appropriate
-locations, mt7530_setup() and mt7530_pll_setup().
-
-Now that all it does is set up port 6, rename it to mt7530_setup_port6(),
-and move it to a more appropriate location, under mt7530_mac_config().
-
-Change mt7530_setup_port6() to void as there're no error cases.
-
-Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function
-pointer.
-
-This is the code path for setting up the ports before:
-
-dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
--> mt753x_mac_config()
- -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
- -> mt7530_setup_port5()
--> mt753x_pad_setup()
- -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
-
-This is after:
-
-dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
--> mt753x_mac_config()
- -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
- -> mt7530_setup_port5()
- -> mt7530_setup_port6()
-
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-4-d7d92a185cb1@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -414,8 +414,8 @@ mt753x_preferred_default_local_cpu_port(
- }
-
- /* Setup port 6 interface mode and TRGMII TX circuit */
--static int
--mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
-+static void
-+mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
- {
- struct mt7530_priv *priv = ds->priv;
- u32 ncpo1, ssc_delta, xtal;
-@@ -426,7 +426,7 @@ mt7530_pad_clk_setup(struct dsa_switch *
- if (interface == PHY_INTERFACE_MODE_RGMII) {
- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
- P6_INTF_MODE(0));
-- return 0;
-+ return;
- }
-
- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
-@@ -465,7 +465,11 @@ mt7530_pad_clk_setup(struct dsa_switch *
-
- /* Enable the MT7530 TRGMII clocks */
- core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
-+}
-
-+static int
-+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
-+{
- return 0;
- }
-
-@@ -2829,11 +2833,10 @@ mt7530_mac_config(struct dsa_switch *ds,
- {
- struct mt7530_priv *priv = ds->priv;
-
-- /* Only need to setup port5. */
-- if (port != 5)
-- return 0;
--
-- mt7530_setup_port5(priv->ds, interface);
-+ if (port == 5)
-+ mt7530_setup_port5(priv->ds, interface);
-+ else if (port == 6)
-+ mt7530_setup_port6(priv->ds, interface);
-
- return 0;
- }
diff --git a/target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch b/target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch
deleted file mode 100644
index 725830e769..0000000000
--- a/target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From fcbc5d900fa53f79963fe4626069739ee5567b4b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 6 Feb 2024 01:08:06 +0300
-Subject: [PATCH 34/48] net: dsa: mt7530: remove pad_setup function pointer
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The pad_setup function pointer was introduced with 88bdef8be9f6 ("net: dsa:
-mt7530: Extend device data ready for adding a new hardware"). It was being
-used to set up the core clock and port 6 of the MT7530 switch, and pll of
-the MT7531 switch.
-
-All of these were moved to more appropriate locations, and it was never
-used for the switch on the MT7988 SoC. Therefore, this function pointer
-hasn't got a use anymore. Remove it.
-
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-5-d7d92a185cb1@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 36 ++----------------------------------
- drivers/net/dsa/mt7530.h | 3 ---
- 2 files changed, 2 insertions(+), 37 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -467,18 +467,6 @@ mt7530_setup_port6(struct dsa_switch *ds
- core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
- }
-
--static int
--mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
--{
-- return 0;
--}
--
--static int
--mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
--{
-- return 0;
--}
--
- static void
- mt7531_pll_setup(struct mt7530_priv *priv)
- {
-@@ -2820,14 +2808,6 @@ static void mt7988_mac_port_get_caps(str
- }
-
- static int
--mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- return priv->info->pad_setup(ds, state->interface);
--}
--
--static int
- mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -2992,8 +2972,6 @@ mt753x_phylink_mac_config(struct dsa_swi
- if (priv->p6_interface == state->interface)
- break;
-
-- mt753x_pad_setup(ds, state);
--
- if (mt753x_mac_config(ds, port, mode, state) < 0)
- goto unsupported;
-
-@@ -3316,11 +3294,6 @@ mt753x_conduit_state_change(struct dsa_s
- mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
- }
-
--static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
--{
-- return 0;
--}
--
- static int mt7988_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-@@ -3382,7 +3355,6 @@ const struct mt753x_info mt753x_table[]
- .sw_setup = mt7530_setup,
- .phy_read = mt7530_phy_read,
- .phy_write = mt7530_phy_write,
-- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
- .mac_port_config = mt7530_mac_config,
- },
-@@ -3392,7 +3364,6 @@ const struct mt753x_info mt753x_table[]
- .sw_setup = mt7530_setup,
- .phy_read = mt7530_phy_read,
- .phy_write = mt7530_phy_write,
-- .pad_setup = mt7530_pad_clk_setup,
- .mac_port_get_caps = mt7530_mac_port_get_caps,
- .mac_port_config = mt7530_mac_config,
- },
-@@ -3402,7 +3373,6 @@ const struct mt753x_info mt753x_table[]
- .sw_setup = mt7531_setup,
- .phy_read = mt7531_ind_phy_read,
- .phy_write = mt7531_ind_phy_write,
-- .pad_setup = mt7531_pad_setup,
- .cpu_port_config = mt7531_cpu_port_config,
- .mac_port_get_caps = mt7531_mac_port_get_caps,
- .mac_port_config = mt7531_mac_config,
-@@ -3413,7 +3383,6 @@ const struct mt753x_info mt753x_table[]
- .sw_setup = mt7988_setup,
- .phy_read = mt7531_ind_phy_read,
- .phy_write = mt7531_ind_phy_write,
-- .pad_setup = mt7988_pad_setup,
- .cpu_port_config = mt7988_cpu_port_config,
- .mac_port_get_caps = mt7988_mac_port_get_caps,
- .mac_port_config = mt7988_mac_config,
-@@ -3443,9 +3412,8 @@ mt7530_probe_common(struct mt7530_priv *
- /* Sanity check if these required device operations are filled
- * properly.
- */
-- if (!priv->info->sw_setup || !priv->info->pad_setup ||
-- !priv->info->phy_read || !priv->info->phy_write ||
-- !priv->info->mac_port_get_caps ||
-+ if (!priv->info->sw_setup || !priv->info->phy_read ||
-+ !priv->info->phy_write || !priv->info->mac_port_get_caps ||
- !priv->info->mac_port_config)
- return -EINVAL;
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -732,8 +732,6 @@ struct mt753x_pcs {
- * @sw_setup: Holding the handler to a device initialization
- * @phy_read: Holding the way reading PHY port
- * @phy_write: Holding the way writing PHY port
-- * @pad_setup: Holding the way setting up the bus pad for a certain
-- * MAC port
- * @phy_mode_supported: Check if the PHY type is being supported on a certain
- * port
- * @mac_port_validate: Holding the way to set addition validate type for a
-@@ -749,7 +747,6 @@ struct mt753x_info {
- int (*sw_setup)(struct dsa_switch *ds);
- int (*phy_read)(struct mt7530_priv *priv, int port, int regnum);
- int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
-- int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
- int (*cpu_port_config)(struct dsa_switch *ds, int port);
- void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
- struct phylink_config *config);
diff --git a/target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch b/target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch
deleted file mode 100644
index 606c48234c..0000000000
--- a/target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 58a94eb63233bb2ede13b183b6a6a03aa0a2dfc3 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 6 Feb 2024 01:08:07 +0300
-Subject: [PATCH 35/48] net: dsa: mt7530: correct port capabilities of MT7988
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-On the switch on the MT7988 SoC, as shown in Block Diagram 8.1.1.3 on page
-125 of "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open
-Version) v0.1", there are only 4 PHYs. That's port 0 to 3. Set the case for
-ports which connect to switch PHYs to '0 ... 3'.
-
-Port 4 and 5 are not used at all in this design.
-
-Link: https://wiki.banana-pi.org/Banana_Pi_BPI-R4#Documents [1]
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-6-d7d92a185cb1@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2793,7 +2793,7 @@ static void mt7988_mac_port_get_caps(str
-
- switch (port) {
- /* Ports which are connected to switch PHYs. There is no MII pinout. */
-- case 0 ... 4:
-+ case 0 ... 3:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
- break;
diff --git a/target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch b/target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch
deleted file mode 100644
index e2f1f23435..0000000000
--- a/target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 4440ce33074be6bd55d1a0c8b5f4b6d433ae2c74 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 6 Feb 2024 01:08:08 +0300
-Subject: [PATCH 36/48] net: dsa: mt7530: do not clear
- config->supported_interfaces
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There's no need to clear the config->supported_interfaces bitmap before
-reporting the supported interfaces as all bits in the bitmap will already
-be initialized to zero when the phylink_config structure is allocated. The
-"config" pointer points to &dp->phylink_config, and "dp" is allocated by
-dsa_port_touch() with kzalloc(), so all its fields are filled with zeroes.
-
-There's no code that would change the bitmap beforehand. Remove it.
-
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-7-d7d92a185cb1@arinc9.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2789,8 +2789,6 @@ static void mt7531_mac_port_get_caps(str
- static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
- {
-- phy_interface_zero(config->supported_interfaces);
--
- switch (port) {
- /* Ports which are connected to switch PHYs. There is no MII pinout. */
- case 0 ... 3:
diff --git a/target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch b/target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch
deleted file mode 100644
index be6fe39f38..0000000000
--- a/target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 2f507aaeb1a12044f2376a255c2afff1f7432b0b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:42:57 +0200
-Subject: [PATCH 37/48] net: dsa: mt7530: remove .mac_port_config for MT7988
- and make it optional
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-For the switch on the MT7988 SoC, the mac_port_config member for ID_MT7988
-in mt753x_table is not needed as the interfaces of all MACs are already
-handled on mt7988_mac_port_get_caps().
-
-Therefore, remove the mac_port_config member from ID_MT7988 in
-mt753x_table. Before calling priv->info->mac_port_config(), if there's no
-mac_port_config member in mt753x_table, exit mt753x_mac_config()
-successfully.
-
-Remove calling priv->info->mac_port_config() from the sanity check as the
-sanity check requires a pointer to a mac_port_config function to be
-non-NULL. This will fail for MT7988 as mac_port_config won't be a member of
-its info table.
-
-Co-developed-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 18 ++++--------------
- 1 file changed, 4 insertions(+), 14 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2872,17 +2872,6 @@ static bool mt753x_is_mac_port(u32 port)
- }
-
- static int
--mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-- phy_interface_t interface)
--{
-- if (dsa_is_cpu_port(ds, port) &&
-- interface == PHY_INTERFACE_MODE_INTERNAL)
-- return 0;
--
-- return -EINVAL;
--}
--
--static int
- mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -2922,6 +2911,9 @@ mt753x_mac_config(struct dsa_switch *ds,
- {
- struct mt7530_priv *priv = ds->priv;
-
-+ if (!priv->info->mac_port_config)
-+ return 0;
-+
- return priv->info->mac_port_config(ds, port, mode, state->interface);
- }
-
-@@ -3383,7 +3375,6 @@ const struct mt753x_info mt753x_table[]
- .phy_write = mt7531_ind_phy_write,
- .cpu_port_config = mt7988_cpu_port_config,
- .mac_port_get_caps = mt7988_mac_port_get_caps,
-- .mac_port_config = mt7988_mac_config,
- },
- };
- EXPORT_SYMBOL_GPL(mt753x_table);
-@@ -3411,8 +3402,7 @@ mt7530_probe_common(struct mt7530_priv *
- * properly.
- */
- if (!priv->info->sw_setup || !priv->info->phy_read ||
-- !priv->info->phy_write || !priv->info->mac_port_get_caps ||
-- !priv->info->mac_port_config)
-+ !priv->info->phy_write || !priv->info->mac_port_get_caps)
- return -EINVAL;
-
- priv->id = priv->info->id;
diff --git a/target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch b/target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch
deleted file mode 100644
index b8473ed128..0000000000
--- a/target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0e297b1c662825f7dcd97272323c81f502987e0f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:42:58 +0200
-Subject: [PATCH 38/48] net: dsa: mt7530: set interrupt register only for
- MT7530
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Setting this register related to interrupts is only needed for the MT7530
-switch. Make an exclusive check to ensure this.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2259,7 +2259,7 @@ mt7530_setup_irq(struct mt7530_priv *pri
- }
-
- /* This register must be set for MT7530 to properly fire interrupts */
-- if (priv->id != ID_MT7531)
-+ if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
- mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL);
-
- ret = request_threaded_irq(priv->irq, NULL, mt7530_irq_thread_fn,
diff --git a/target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch b/target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch
deleted file mode 100644
index 216a781087..0000000000
--- a/target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0eb6bc551371070325b6606cc3bed6734ecad87d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:42:59 +0200
-Subject: [PATCH 39/48] net: dsa: mt7530: do not use SW_PHY_RST to reset MT7531
- switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-According to the document MT7531 Reference Manual for Development Board
-v1.0, the SW_PHY_RST bit on the SYS_CTRL register doesn't exist for
-MT7531. This is likely why forcing link down on all ports is necessary for
-MT7531.
-
-Therefore, do not set SW_PHY_RST on mt7531_setup().
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2660,14 +2660,12 @@ mt7531_setup(struct dsa_switch *ds)
- val = mt7530_read(priv, MT7531_TOP_SIG_SR);
- priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
-
-- /* all MACs must be forced link-down before sw reset */
-+ /* Force link down on all ports before internal reset */
- for (i = 0; i < MT7530_NUM_PORTS; i++)
- mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
-
- /* Reset the switch through internal reset */
-- mt7530_write(priv, MT7530_SYS_CTRL,
-- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
-- SYS_CTRL_REG_RST);
-+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
-
- if (!priv->p5_sgmii) {
- mt7531_pll_setup(priv);
diff --git a/target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch b/target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch
deleted file mode 100644
index f920a6604d..0000000000
--- a/target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From bb20b1b4d832de4eb98ec7c22906db7c04e3f7c5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:43:00 +0200
-Subject: [PATCH 40/48] net: dsa: mt7530: get rid of useless error returns on
- phylink code path
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove error returns on the cases where they are already handled with the
-function the mac_port_get_caps member in mt753x_table points to.
-
-mt7531_mac_config() is also called from mt7531_cpu_port_config() outside of
-phylink but the port and interface modes are already handled there.
-
-Change the functions and the mac_port_config function pointer to void now
-that there're no error returns anymore.
-
-Remove mt753x_is_mac_port() that used to help the said error returns.
-
-On mt7531_mac_config(), switch to if statements to simplify the code.
-
-Remove internal phy cases from mt753x_phylink_mac_config(), there is no
-need to check the interface mode as that's already handled with the
-function the mac_port_get_caps member in mt753x_table points to.
-
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 81 ++++++++--------------------------------
- drivers/net/dsa/mt7530.h | 6 +--
- 2 files changed, 19 insertions(+), 68 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2803,7 +2803,7 @@ static void mt7988_mac_port_get_caps(str
- }
- }
-
--static int
-+static void
- mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -2813,22 +2813,14 @@ mt7530_mac_config(struct dsa_switch *ds,
- mt7530_setup_port5(priv->ds, interface);
- else if (port == 6)
- mt7530_setup_port6(priv->ds, interface);
--
-- return 0;
- }
-
--static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
-- phy_interface_t interface,
-- struct phy_device *phydev)
-+static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
-+ phy_interface_t interface,
-+ struct phy_device *phydev)
- {
- u32 val;
-
-- if (priv->p5_sgmii) {
-- dev_err(priv->dev, "RGMII mode is not available for port %d\n",
-- port);
-- return -EINVAL;
-- }
--
- val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
- val |= GP_CLK_EN;
- val &= ~GP_MODE_MASK;
-@@ -2856,20 +2848,14 @@ static int mt7531_rgmii_setup(struct mt7
- case PHY_INTERFACE_MODE_RGMII_ID:
- break;
- default:
-- return -EINVAL;
-+ break;
- }
- }
-- mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
-
-- return 0;
--}
--
--static bool mt753x_is_mac_port(u32 port)
--{
-- return (port == 5 || port == 6);
-+ mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
- }
-
--static int
-+static void
- mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -2877,42 +2863,21 @@ mt7531_mac_config(struct dsa_switch *ds,
- struct phy_device *phydev;
- struct dsa_port *dp;
-
-- if (!mt753x_is_mac_port(port)) {
-- dev_err(priv->dev, "port %d is not a MAC port\n", port);
-- return -EINVAL;
-- }
--
-- switch (interface) {
-- case PHY_INTERFACE_MODE_RGMII:
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-+ if (phy_interface_mode_is_rgmii(interface)) {
- dp = dsa_to_port(ds, port);
- phydev = dp->slave->phydev;
-- return mt7531_rgmii_setup(priv, port, interface, phydev);
-- case PHY_INTERFACE_MODE_SGMII:
-- case PHY_INTERFACE_MODE_NA:
-- case PHY_INTERFACE_MODE_1000BASEX:
-- case PHY_INTERFACE_MODE_2500BASEX:
-- /* handled in SGMII PCS driver */
-- return 0;
-- default:
-- return -EINVAL;
-+ mt7531_rgmii_setup(priv, port, interface, phydev);
- }
--
-- return -EINVAL;
- }
-
--static int
-+static void
- mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- const struct phylink_link_state *state)
- {
- struct mt7530_priv *priv = ds->priv;
-
-- if (!priv->info->mac_port_config)
-- return 0;
--
-- return priv->info->mac_port_config(ds, port, mode, state->interface);
-+ if (priv->info->mac_port_config)
-+ priv->info->mac_port_config(ds, port, mode, state->interface);
- }
-
- static struct phylink_pcs *
-@@ -2941,17 +2906,11 @@ mt753x_phylink_mac_config(struct dsa_swi
- u32 mcr_cur, mcr_new;
-
- switch (port) {
-- case 0 ... 4:
-- if (state->interface != PHY_INTERFACE_MODE_GMII &&
-- state->interface != PHY_INTERFACE_MODE_INTERNAL)
-- goto unsupported;
-- break;
- case 5:
- if (priv->p5_interface == state->interface)
- break;
-
-- if (mt753x_mac_config(ds, port, mode, state) < 0)
-- goto unsupported;
-+ mt753x_mac_config(ds, port, mode, state);
-
- if (priv->p5_intf_sel != P5_DISABLED)
- priv->p5_interface = state->interface;
-@@ -2960,16 +2919,10 @@ mt753x_phylink_mac_config(struct dsa_swi
- if (priv->p6_interface == state->interface)
- break;
-
-- if (mt753x_mac_config(ds, port, mode, state) < 0)
-- goto unsupported;
-+ mt753x_mac_config(ds, port, mode, state);
-
- priv->p6_interface = state->interface;
- break;
-- default:
--unsupported:
-- dev_err(ds->dev, "%s: unsupported %s port: %i\n",
-- __func__, phy_modes(state->interface), port);
-- return;
- }
-
- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
-@@ -3052,7 +3005,6 @@ mt7531_cpu_port_config(struct dsa_switch
- struct mt7530_priv *priv = ds->priv;
- phy_interface_t interface;
- int speed;
-- int ret;
-
- switch (port) {
- case 5:
-@@ -3077,9 +3029,8 @@ mt7531_cpu_port_config(struct dsa_switch
- else
- speed = SPEED_1000;
-
-- ret = mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
-- if (ret)
-- return ret;
-+ mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
-+
- mt7530_write(priv, MT7530_PMCR_P(port),
- PMCR_CPU_PORT_SETTING(priv->id));
- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -753,9 +753,9 @@ struct mt753x_info {
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
- phy_interface_t interface,
- unsigned long *supported);
-- int (*mac_port_config)(struct dsa_switch *ds, int port,
-- unsigned int mode,
-- phy_interface_t interface);
-+ void (*mac_port_config)(struct dsa_switch *ds, int port,
-+ unsigned int mode,
-+ phy_interface_t interface);
- };
-
- /* struct mt7530_priv - This is the main data structure for holding the state
diff --git a/target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch b/target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch
deleted file mode 100644
index eb0a5706ec..0000000000
--- a/target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch
+++ /dev/null
@@ -1,305 +0,0 @@
-From 8554f6a7914d28b179671540f527897d85c88809 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:43:01 +0200
-Subject: [PATCH 41/48] net: dsa: mt7530: get rid of
- priv->info->cpu_port_config()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-priv->info->cpu_port_config() is used for MT7531 and the switch on the
-MT7988 SoC. It sets up the ports described as a CPU port earlier than the
-phylink code path would do.
-
-This function is useless as:
-- Configuring the MACs can be done from the phylink_mac_config code path
- instead.
-- All the link configuration it does on the CPU ports are later undone with
- the port_enable, phylink_mac_config, and then phylink_mac_link_up code
- path [1].
-
-priv->p5_interface and priv->p6_interface were being used to prevent
-configuring the MACs from the phylink_mac_config code path. Remove them now
-that they hold no purpose.
-
-Remove priv->info->cpu_port_config(). On mt753x_phylink_mac_config, switch
-to if statements to simplify the code.
-
-Remove the overwriting of the speed and duplex interfaces for certain
-interface modes. Phylink already provides the speed and duplex variables
-with proper values. Phylink already sets the max speed of TRGMII to
-SPEED_1000. Add SPEED_2500 for PHY_INTERFACE_MODE_2500BASEX to where the
-speed and EEE bits are set instead.
-
-On the switch on the MT7988 SoC, PHY_INTERFACE_MODE_INTERNAL is being used
-to describe the interface mode of the 10G MAC, which is of port 6. On
-mt7988_cpu_port_config() PMCR_FORCE_SPEED_1000 was set via the
-PMCR_CPU_PORT_SETTING() mask. Add SPEED_10000 case to where the speed bits
-are set to cover this. No need to add it to where the EEE bits are set as
-the "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
-v0.1" document shows that these bits don't exist on the MT7530_PMCR_P(6)
-register.
-
-Remove the definition of PMCR_CPU_PORT_SETTING() now that it holds no
-purpose.
-
-Change mt753x_cpu_port_enable() to void now that there're no error cases
-left.
-
-Link: https://lore.kernel.org/netdev/ZHy2jQLesdYFMQtO@shell.armlinux.org.uk/ [1]
-Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 114 +++------------------------------------
- drivers/net/dsa/mt7530.h | 11 ----
- 2 files changed, 7 insertions(+), 118 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1170,18 +1170,10 @@ mt753x_trap_frames(struct mt7530_priv *p
- MT753X_BPDU_CPU_ONLY);
- }
-
--static int
-+static void
- mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
- {
- struct mt7530_priv *priv = ds->priv;
-- int ret;
--
-- /* Setup max capability of CPU port at first */
-- if (priv->info->cpu_port_config) {
-- ret = priv->info->cpu_port_config(ds, port);
-- if (ret)
-- return ret;
-- }
-
- /* Enable Mediatek header mode on the cpu port */
- mt7530_write(priv, MT7530_PVC_P(port),
-@@ -1207,8 +1199,6 @@ mt753x_cpu_port_enable(struct dsa_switch
- /* Set to fallback mode for independent VLAN learning */
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
- MT7530_PORT_FALLBACK_MODE);
--
-- return 0;
- }
-
- static int
-@@ -2461,8 +2451,6 @@ mt7530_setup(struct dsa_switch *ds)
- val |= MHWTRAP_MANUAL;
- mt7530_write(priv, MT7530_MHWTRAP, val);
-
-- priv->p6_interface = PHY_INTERFACE_MODE_NA;
--
- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ)
- mt7530_pll_setup(priv);
-
-@@ -2480,9 +2468,7 @@ mt7530_setup(struct dsa_switch *ds)
- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
-
- if (dsa_is_cpu_port(ds, i)) {
-- ret = mt753x_cpu_port_enable(ds, i);
-- if (ret)
-- return ret;
-+ mt753x_cpu_port_enable(ds, i);
- } else {
- mt7530_port_disable(ds, i);
-
-@@ -2589,9 +2575,7 @@ mt7531_setup_common(struct dsa_switch *d
- mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
-
- if (dsa_is_cpu_port(ds, i)) {
-- ret = mt753x_cpu_port_enable(ds, i);
-- if (ret)
-- return ret;
-+ mt753x_cpu_port_enable(ds, i);
- } else {
- mt7530_port_disable(ds, i);
-
-@@ -2683,10 +2667,6 @@ mt7531_setup(struct dsa_switch *ds)
- mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
- MT7531_GPIO0_INTERRUPT);
-
-- /* Let phylink decide the interface later. */
-- priv->p5_interface = PHY_INTERFACE_MODE_NA;
-- priv->p6_interface = PHY_INTERFACE_MODE_NA;
--
- /* Enable Energy-Efficient Ethernet (EEE) and PHY core PLL, since
- * phy_device has not yet been created provided for
- * phy_[read,write]_mmd_indirect is called, we provide our own
-@@ -2905,26 +2885,9 @@ mt753x_phylink_mac_config(struct dsa_swi
- struct mt7530_priv *priv = ds->priv;
- u32 mcr_cur, mcr_new;
-
-- switch (port) {
-- case 5:
-- if (priv->p5_interface == state->interface)
-- break;
--
-+ if (port == 5 || port == 6)
- mt753x_mac_config(ds, port, mode, state);
-
-- if (priv->p5_intf_sel != P5_DISABLED)
-- priv->p5_interface = state->interface;
-- break;
-- case 6:
-- if (priv->p6_interface == state->interface)
-- break;
--
-- mt753x_mac_config(ds, port, mode, state);
--
-- priv->p6_interface = state->interface;
-- break;
-- }
--
- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
- mcr_new = mcr_cur;
- mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-@@ -2960,17 +2923,10 @@ static void mt753x_phylink_mac_link_up(s
-
- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
-
-- /* MT753x MAC works in 1G full duplex mode for all up-clocked
-- * variants.
-- */
-- if (interface == PHY_INTERFACE_MODE_TRGMII ||
-- (phy_interface_mode_is_8023z(interface))) {
-- speed = SPEED_1000;
-- duplex = DUPLEX_FULL;
-- }
--
- switch (speed) {
- case SPEED_1000:
-+ case SPEED_2500:
-+ case SPEED_10000:
- mcr |= PMCR_FORCE_SPEED_1000;
- break;
- case SPEED_100:
-@@ -2988,6 +2944,7 @@ static void mt753x_phylink_mac_link_up(s
- if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
- switch (speed) {
- case SPEED_1000:
-+ case SPEED_2500:
- mcr |= PMCR_FORCE_EEE1G;
- break;
- case SPEED_100:
-@@ -2999,61 +2956,6 @@ static void mt753x_phylink_mac_link_up(s
- mt7530_set(priv, MT7530_PMCR_P(port), mcr);
- }
-
--static int
--mt7531_cpu_port_config(struct dsa_switch *ds, int port)
--{
-- struct mt7530_priv *priv = ds->priv;
-- phy_interface_t interface;
-- int speed;
--
-- switch (port) {
-- case 5:
-- if (!priv->p5_sgmii)
-- interface = PHY_INTERFACE_MODE_RGMII;
-- else
-- interface = PHY_INTERFACE_MODE_2500BASEX;
--
-- priv->p5_interface = interface;
-- break;
-- case 6:
-- interface = PHY_INTERFACE_MODE_2500BASEX;
--
-- priv->p6_interface = interface;
-- break;
-- default:
-- return -EINVAL;
-- }
--
-- if (interface == PHY_INTERFACE_MODE_2500BASEX)
-- speed = SPEED_2500;
-- else
-- speed = SPEED_1000;
--
-- mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
--
-- mt7530_write(priv, MT7530_PMCR_P(port),
-- PMCR_CPU_PORT_SETTING(priv->id));
-- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
-- speed, DUPLEX_FULL, true, true);
--
-- return 0;
--}
--
--static int
--mt7988_cpu_port_config(struct dsa_switch *ds, int port)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- mt7530_write(priv, MT7530_PMCR_P(port),
-- PMCR_CPU_PORT_SETTING(priv->id));
--
-- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
-- PHY_INTERFACE_MODE_INTERNAL, NULL,
-- SPEED_10000, DUPLEX_FULL, true, true);
--
-- return 0;
--}
--
- static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
- {
-@@ -3312,7 +3214,6 @@ const struct mt753x_info mt753x_table[]
- .sw_setup = mt7531_setup,
- .phy_read = mt7531_ind_phy_read,
- .phy_write = mt7531_ind_phy_write,
-- .cpu_port_config = mt7531_cpu_port_config,
- .mac_port_get_caps = mt7531_mac_port_get_caps,
- .mac_port_config = mt7531_mac_config,
- },
-@@ -3322,7 +3223,6 @@ const struct mt753x_info mt753x_table[]
- .sw_setup = mt7988_setup,
- .phy_read = mt7531_ind_phy_read,
- .phy_write = mt7531_ind_phy_write,
-- .cpu_port_config = mt7988_cpu_port_config,
- .mac_port_get_caps = mt7988_mac_port_get_caps,
- },
- };
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -340,13 +340,6 @@ enum mt7530_vlan_port_acc_frm {
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
- PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
- PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
--#define PMCR_CPU_PORT_SETTING(id) (PMCR_FORCE_MODE_ID((id)) | \
-- PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
-- PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
-- PMCR_TX_EN | PMCR_RX_EN | \
-- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
-- PMCR_FORCE_SPEED_1000 | \
-- PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-
- #define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100)
- #define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24)
-@@ -747,7 +740,6 @@ struct mt753x_info {
- int (*sw_setup)(struct dsa_switch *ds);
- int (*phy_read)(struct mt7530_priv *priv, int port, int regnum);
- int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
-- int (*cpu_port_config)(struct dsa_switch *ds, int port);
- void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
- struct phylink_config *config);
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
-@@ -773,7 +765,6 @@ struct mt753x_info {
- * @ports: Holding the state among ports
- * @reg_mutex: The lock for protecting among process accessing
- * registers
-- * @p6_interface Holding the current port 6 interface
- * @p5_intf_sel: Holding the current port 5 interface select
- * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
- * has got SGMII
-@@ -795,8 +786,6 @@ struct mt7530_priv {
- const struct mt753x_info *info;
- unsigned int id;
- bool mcm;
-- phy_interface_t p6_interface;
-- phy_interface_t p5_interface;
- enum p5_interface_select p5_intf_sel;
- bool p5_sgmii;
- u8 mirror_rx;
diff --git a/target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch b/target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch
deleted file mode 100644
index c83a627808..0000000000
--- a/target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0c282205ef8c6dd6d2c145fac1fb6aba3e65c02d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:43:02 +0200
-Subject: [PATCH 42/48] net: dsa: mt7530: get rid of mt753x_mac_config()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There is no need for a separate function to call
-priv->info->mac_port_config(). Call it from mt753x_phylink_mac_config()
-instead and remove mt753x_mac_config().
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 14 ++------------
- 1 file changed, 2 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2850,16 +2850,6 @@ mt7531_mac_config(struct dsa_switch *ds,
- }
- }
-
--static void
--mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-- const struct phylink_link_state *state)
--{
-- struct mt7530_priv *priv = ds->priv;
--
-- if (priv->info->mac_port_config)
-- priv->info->mac_port_config(ds, port, mode, state->interface);
--}
--
- static struct phylink_pcs *
- mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
- phy_interface_t interface)
-@@ -2885,8 +2875,8 @@ mt753x_phylink_mac_config(struct dsa_swi
- struct mt7530_priv *priv = ds->priv;
- u32 mcr_cur, mcr_new;
-
-- if (port == 5 || port == 6)
-- mt753x_mac_config(ds, port, mode, state);
-+ if ((port == 5 || port == 6) && priv->info->mac_port_config)
-+ priv->info->mac_port_config(ds, port, mode, state->interface);
-
- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
- mcr_new = mcr_cur;
diff --git a/target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch b/target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch
deleted file mode 100644
index 84ee7416bf..0000000000
--- a/target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From d55c300aa1fe240aa3eba18550ba6c4e2c4bd157 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:43:03 +0200
-Subject: [PATCH 43/48] net: dsa: mt7530: put initialising PCS devices code
- back to original order
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The commit fae463084032 ("net: dsa: mt753x: fix pcs conversion regression")
-fixes regression caused by cpu_port_config manually calling phylink
-operations. cpu_port_config was deemed useless and was removed. Therefore,
-put initialising PCS devices code back to its original order.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3034,17 +3034,9 @@ static int
- mt753x_setup(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-- int i, ret;
-+ int ret = priv->info->sw_setup(ds);
-+ int i;
-
-- /* Initialise the PCS devices */
-- for (i = 0; i < priv->ds->num_ports; i++) {
-- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-- priv->pcs[i].pcs.neg_mode = true;
-- priv->pcs[i].priv = priv;
-- priv->pcs[i].port = i;
-- }
--
-- ret = priv->info->sw_setup(ds);
- if (ret)
- return ret;
-
-@@ -3056,6 +3048,14 @@ mt753x_setup(struct dsa_switch *ds)
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-
-+ /* Initialise the PCS devices */
-+ for (i = 0; i < priv->ds->num_ports; i++) {
-+ priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-+ priv->pcs[i].pcs.neg_mode = true;
-+ priv->pcs[i].priv = priv;
-+ priv->pcs[i].port = i;
-+ }
-+
- if (priv->create_sgmii) {
- ret = priv->create_sgmii(priv);
- if (ret && priv->irq)
diff --git a/target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch b/target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch
deleted file mode 100644
index 814a9d06e7..0000000000
--- a/target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From a9544caa482a7ed215117a902f04185216997831 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:43:04 +0200
-Subject: [PATCH 44/48] net: dsa: mt7530: sort link settings ops and force link
- down on all ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-port_enable and port_disable clears the link settings. Move that to
-mt7530_setup() and mt7531_setup_common() which set up the switches. This
-way, the link settings are cleared on all ports at setup, and then only
-once with phylink_mac_link_down() when a link goes down.
-
-Enable force mode at setup to apply the force part of the link settings.
-This ensures that disabled ports will have their link down.
-
-Suggested-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1222,7 +1222,6 @@ mt7530_port_enable(struct dsa_switch *ds
- priv->ports[port].enable = true;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- priv->ports[port].pm);
-- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
-
- mutex_unlock(&priv->reg_mutex);
-
-@@ -1242,7 +1241,6 @@ mt7530_port_disable(struct dsa_switch *d
- priv->ports[port].enable = false;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
-- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
-
- mutex_unlock(&priv->reg_mutex);
- }
-@@ -2460,6 +2458,12 @@ mt7530_setup(struct dsa_switch *ds)
- mt7530_mib_reset(ds);
-
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ /* Clear link settings and enable force mode to force link down
-+ * on all ports until they're enabled later.
-+ */
-+ mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
-+ PMCR_FORCE_MODE, PMCR_FORCE_MODE);
-+
- /* Disable forwarding by default on all ports */
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
-@@ -2565,6 +2569,12 @@ mt7531_setup_common(struct dsa_switch *d
- UNU_FFP_MASK);
-
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ /* Clear link settings and enable force mode to force link down
-+ * on all ports until they're enabled later.
-+ */
-+ mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
-+ MT7531_FORCE_MODE, MT7531_FORCE_MODE);
-+
- /* Disable forwarding by default on all ports */
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
diff --git a/target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch b/target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch
deleted file mode 100644
index d9f91a932a..0000000000
--- a/target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 89017cac5f6fbaab23955818c31b3c7f1eb26f4a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Mar 2024 12:43:05 +0200
-Subject: [PATCH 45/48] net: dsa: mt7530: simplify link operations
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The "MT7621 Giga Switch Programming Guide v0.3", "MT7531 Reference Manual
-for Development Board v1.0", and "MT7988A Wi-Fi 7 Generation Router
-Platform: Datasheet (Open Version) v0.1" documents show that these bits are
-enabled at reset:
-
-PMCR_IFG_XMIT(1) (not part of PMCR_LINK_SETTINGS_MASK)
-PMCR_MAC_MODE (not part of PMCR_LINK_SETTINGS_MASK)
-PMCR_TX_EN
-PMCR_RX_EN
-PMCR_BACKOFF_EN (not part of PMCR_LINK_SETTINGS_MASK)
-PMCR_BACKPR_EN (not part of PMCR_LINK_SETTINGS_MASK)
-PMCR_TX_FC_EN
-PMCR_RX_FC_EN
-
-These bits also don't exist on the MT7530_PMCR_P(6) register of the switch
-on the MT7988 SoC:
-
-PMCR_IFG_XMIT()
-PMCR_MAC_MODE
-PMCR_BACKOFF_EN
-PMCR_BACKPR_EN
-
-Remove the setting of the bits not part of PMCR_LINK_SETTINGS_MASK on
-phylink_mac_config as they're already set.
-
-The bit for setting the port on force mode is already done on
-mt7530_setup() and mt7531_setup_common(). So get rid of
-PMCR_FORCE_MODE_ID() which helped determine which bit to use for the switch
-model.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 12 +-----------
- drivers/net/dsa/mt7530.h | 2 --
- 2 files changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2883,23 +2883,13 @@ mt753x_phylink_mac_config(struct dsa_swi
- const struct phylink_link_state *state)
- {
- struct mt7530_priv *priv = ds->priv;
-- u32 mcr_cur, mcr_new;
-
- if ((port == 5 || port == 6) && priv->info->mac_port_config)
- priv->info->mac_port_config(ds, port, mode, state->interface);
-
-- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
-- mcr_new = mcr_cur;
-- mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-- mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
-- PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id);
--
- /* Are we connected to external phy */
- if (port == 5 && dsa_is_user_port(ds, 5))
-- mcr_new |= PMCR_EXT_PHY;
--
-- if (mcr_new != mcr_cur)
-- mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
-+ mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
- }
-
- static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -333,8 +333,6 @@ enum mt7530_vlan_port_acc_frm {
- MT7531_FORCE_DPX | \
- MT7531_FORCE_RX_FC | \
- MT7531_FORCE_TX_FC)
--#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
-- MT7531_FORCE_MODE : PMCR_FORCE_MODE)
- #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
diff --git a/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch b/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch
deleted file mode 100644
index 8962e560f7..0000000000
--- a/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 5754b3bdcd872aa229881b8f07f84a8404c7d72a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 12 Apr 2024 16:15:34 +0100
-Subject: [PATCH 1/5] net: dsa: mt7530: provide own phylink MAC operations
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Convert mt753x to provide its own phylink MAC operations, thus avoiding
-the shim layer in DSA's port.c
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/E1rvIco-006bQu-Fq@rmk-PC.armlinux.org.uk
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 46 +++++++++++++++++++++++++---------------
- 1 file changed, 29 insertions(+), 17 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2861,28 +2861,34 @@ mt7531_mac_config(struct dsa_switch *ds,
- }
-
- static struct phylink_pcs *
--mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
-+mt753x_phylink_mac_select_pcs(struct phylink_config *config,
- phy_interface_t interface)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
-+ struct mt7530_priv *priv = dp->ds->priv;
-
- switch (interface) {
- case PHY_INTERFACE_MODE_TRGMII:
-- return &priv->pcs[port].pcs;
-+ return &priv->pcs[dp->index].pcs;
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_2500BASEX:
-- return priv->ports[port].sgmii_pcs;
-+ return priv->ports[dp->index].sgmii_pcs;
- default:
- return NULL;
- }
- }
-
- static void
--mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode,
- const struct phylink_link_state *state)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
-+ struct dsa_switch *ds = dp->ds;
-+ struct mt7530_priv *priv;
-+ int port = dp->index;
-+
-+ priv = ds->priv;
-
- if ((port == 5 || port == 6) && priv->info->mac_port_config)
- priv->info->mac_port_config(ds, port, mode, state->interface);
-@@ -2892,23 +2898,25 @@ mt753x_phylink_mac_config(struct dsa_swi
- mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
- }
-
--static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
-+static void mt753x_phylink_mac_link_down(struct phylink_config *config,
- unsigned int mode,
- phy_interface_t interface)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
-+ struct mt7530_priv *priv = dp->ds->priv;
-
-- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
-+ mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
- }
-
--static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
-+static void mt753x_phylink_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phydev,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev,
- int speed, int duplex,
- bool tx_pause, bool rx_pause)
- {
-- struct mt7530_priv *priv = ds->priv;
-+ struct dsa_port *dp = dsa_phylink_to_port(config);
-+ struct mt7530_priv *priv = dp->ds->priv;
- u32 mcr;
-
- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
-@@ -2943,7 +2951,7 @@ static void mt753x_phylink_mac_link_up(s
- }
- }
-
-- mt7530_set(priv, MT7530_PMCR_P(port), mcr);
-+ mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
- }
-
- static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
-@@ -3169,16 +3177,19 @@ const struct dsa_switch_ops mt7530_switc
- .port_mirror_add = mt753x_port_mirror_add,
- .port_mirror_del = mt753x_port_mirror_del,
- .phylink_get_caps = mt753x_phylink_get_caps,
-- .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
-- .phylink_mac_config = mt753x_phylink_mac_config,
-- .phylink_mac_link_down = mt753x_phylink_mac_link_down,
-- .phylink_mac_link_up = mt753x_phylink_mac_link_up,
- .get_mac_eee = mt753x_get_mac_eee,
- .set_mac_eee = mt753x_set_mac_eee,
- .master_state_change = mt753x_conduit_state_change,
- };
- EXPORT_SYMBOL_GPL(mt7530_switch_ops);
-
-+static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
-+ .mac_select_pcs = mt753x_phylink_mac_select_pcs,
-+ .mac_config = mt753x_phylink_mac_config,
-+ .mac_link_down = mt753x_phylink_mac_link_down,
-+ .mac_link_up = mt753x_phylink_mac_link_up,
-+};
-+
- const struct mt753x_info mt753x_table[] = {
- [ID_MT7621] = {
- .id = ID_MT7621,
-@@ -3248,6 +3259,7 @@ mt7530_probe_common(struct mt7530_priv *
- priv->dev = dev;
- priv->ds->priv = priv;
- priv->ds->ops = &mt7530_switch_ops;
-+ priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
- mutex_init(&priv->reg_mutex);
- dev_set_drvdata(dev, priv);
-
diff --git a/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch b/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch
deleted file mode 100644
index cd5b7b287d..0000000000
--- a/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 019a17a5e76940ea86114838d1d638d4dc8d3750 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sat, 13 Apr 2024 16:01:40 +0300
-Subject: [PATCH 3/5] net: dsa: mt7530: fix port mirroring for MT7988 SoC
- switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
-v0.1" document shows bits 16 to 18 as the MIRROR_PORT field of the CPU
-forward control register. Currently, the MT7530 DSA subdriver configures
-bits 0 to 2 of the CPU forward control register which breaks the port
-mirroring feature for the MT7988 SoC switch.
-
-Fix this by using the MT7531_MIRROR_PORT_GET() and MT7531_MIRROR_PORT_SET()
-macros which utilise the correct bits.
-
-Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch")
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1890,14 +1890,16 @@ mt7530_port_vlan_del(struct dsa_switch *
-
- static int mt753x_mirror_port_get(unsigned int id, u32 val)
- {
-- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) :
-- MIRROR_PORT(val);
-+ return (id == ID_MT7531 || id == ID_MT7988) ?
-+ MT7531_MIRROR_PORT_GET(val) :
-+ MIRROR_PORT(val);
- }
-
- static int mt753x_mirror_port_set(unsigned int id, u32 val)
- {
-- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) :
-- MIRROR_PORT(val);
-+ return (id == ID_MT7531 || id == ID_MT7988) ?
-+ MT7531_MIRROR_PORT_SET(val) :
-+ MIRROR_PORT(val);
- }
-
- static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
diff --git a/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch b/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch
deleted file mode 100644
index e9c8f955c9..0000000000
--- a/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch
+++ /dev/null
@@ -1,238 +0,0 @@
-From 5053a6cf1d50d785078562470d2a63695a9f3bf2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Thu, 18 Apr 2024 08:35:30 +0300
-Subject: [PATCH 4/5] net: dsa: mt7530-mdio: read PHY address of switch from
- device tree
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Read the PHY address the switch listens on from the reg property of the
-switch node on the device tree. This change brings support for MT7530
-switches on boards with such bootstrapping configuration where the switch
-listens on a different PHY address than the hardcoded PHY address on the
-driver, 31.
-
-As described on the "MT7621 Programming Guide v0.4" document, the MT7530
-switch and its PHYs can be configured to listen on the range of 7-12,
-15-20, 23-28, and 31 and 0-4 PHY addresses.
-
-There are operations where the switch PHY registers are used. For the PHY
-address of the control PHY, transform the MT753X_CTRL_PHY_ADDR constant
-into a macro and use it. The PHY address for the control PHY is 0 when the
-switch listens on 31. In any other case, it is one greater than the PHY
-address the switch listens on.
-
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530-mdio.c | 28 +++++++++++++-------------
- drivers/net/dsa/mt7530.c | 37 +++++++++++++++++++++++------------
- drivers/net/dsa/mt7530.h | 4 +++-
- 3 files changed, 41 insertions(+), 28 deletions(-)
-
---- a/drivers/net/dsa/mt7530-mdio.c
-+++ b/drivers/net/dsa/mt7530-mdio.c
-@@ -18,7 +18,8 @@
- static int
- mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
- {
-- struct mii_bus *bus = context;
-+ struct mt7530_priv *priv = context;
-+ struct mii_bus *bus = priv->bus;
- u16 page, r, lo, hi;
- int ret;
-
-@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsig
- lo = val & 0xffff;
- hi = val >> 16;
-
-- /* MT7530 uses 31 as the pseudo port */
-- ret = bus->write(bus, 0x1f, 0x1f, page);
-+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
- if (ret < 0)
- return ret;
-
-- ret = bus->write(bus, 0x1f, r, lo);
-+ ret = bus->write(bus, priv->mdiodev->addr, r, lo);
- if (ret < 0)
- return ret;
-
-- ret = bus->write(bus, 0x1f, 0x10, hi);
-+ ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi);
- return ret;
- }
-
- static int
- mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
- {
-- struct mii_bus *bus = context;
-+ struct mt7530_priv *priv = context;
-+ struct mii_bus *bus = priv->bus;
- u16 page, r, lo, hi;
- int ret;
-
- page = (reg >> 6) & 0x3ff;
- r = (reg >> 2) & 0xf;
-
-- /* MT7530 uses 31 as the pseudo port */
-- ret = bus->write(bus, 0x1f, 0x1f, page);
-+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
- if (ret < 0)
- return ret;
-
-- lo = bus->read(bus, 0x1f, r);
-- hi = bus->read(bus, 0x1f, 0x10);
-+ lo = bus->read(bus, priv->mdiodev->addr, r);
-+ hi = bus->read(bus, priv->mdiodev->addr, 0x10);
-
- *val = (hi << 16) | (lo & 0xffff);
-
-@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *
- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-
-- regmap = devm_regmap_init(priv->dev,
-- &mt7530_regmap_bus, priv->bus,
-+ regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
- mt7531_pcs_config[i]);
- if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
-@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev
-
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
-+ priv->mdiodev = mdiodev;
-
- ret = mt7530_probe_common(priv);
- if (ret)
-@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev
- regmap_config->reg_stride = 4;
- regmap_config->max_register = MT7530_CREV;
- regmap_config->disable_locking = true;
-- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
-- priv->bus, regmap_config);
-+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
-+ regmap_config);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -86,22 +86,26 @@ core_read_mmd_indirect(struct mt7530_pri
- int value, ret;
-
- /* Write the desired MMD Devad */
-- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_CTRL, devad);
- if (ret < 0)
- goto err;
-
- /* Write the desired MMD register address */
-- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_DATA, prtad);
- if (ret < 0)
- goto err;
-
- /* Select the Function : DATA with no post increment */
-- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
- if (ret < 0)
- goto err;
-
- /* Read the content of the MMD's selected register */
-- value = bus->read(bus, 0, MII_MMD_DATA);
-+ value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_DATA);
-
- return value;
- err:
-@@ -118,22 +122,26 @@ core_write_mmd_indirect(struct mt7530_pr
- int ret;
-
- /* Write the desired MMD Devad */
-- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_CTRL, devad);
- if (ret < 0)
- goto err;
-
- /* Write the desired MMD register address */
-- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_DATA, prtad);
- if (ret < 0)
- goto err;
-
- /* Select the Function : DATA with no post increment */
-- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
- if (ret < 0)
- goto err;
-
- /* Write the data into MMD's selected register */
-- ret = bus->write(bus, 0, MII_MMD_DATA, data);
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_DATA, data);
- err:
- if (ret < 0)
- dev_err(&bus->dev,
-@@ -2684,16 +2692,19 @@ mt7531_setup(struct dsa_switch *ds)
- * phy_[read,write]_mmd_indirect is called, we provide our own
- * mt7531_ind_mmd_phy_[read,write] to complete this function.
- */
-- val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
-+ val = mt7531_ind_c45_phy_read(priv,
-+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MDIO_MMD_VEND2, CORE_PLL_GROUP4);
- val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
- val &= ~MT7531_PHY_PLL_OFF;
-- mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
-- CORE_PLL_GROUP4, val);
-+ mt7531_ind_c45_phy_write(priv,
-+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
-
- /* Disable EEE advertisement on the switch PHYs. */
-- for (i = MT753X_CTRL_PHY_ADDR;
-- i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
-+ for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
-+ i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
-+ i++) {
- mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
- 0);
- }
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -629,7 +629,7 @@ enum mt7531_clk_skew {
- #define MT7531_PHY_PLL_OFF BIT(5)
- #define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
-
--#define MT753X_CTRL_PHY_ADDR 0
-+#define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f)
-
- #define CORE_PLL_GROUP5 0x404
- #define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
-@@ -771,6 +771,7 @@ struct mt753x_info {
- * @irq_enable: IRQ enable bits, synced to SYS_INT_EN
- * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
- * @active_cpu_ports: Holding the active CPU ports
-+ * @mdiodev: The pointer to the MDIO device structure
- */
- struct mt7530_priv {
- struct device *dev;
-@@ -797,6 +798,7 @@ struct mt7530_priv {
- u32 irq_enable;
- int (*create_sgmii)(struct mt7530_priv *priv);
- u8 active_cpu_ports;
-+ struct mdio_device *mdiodev;
- };
-
- struct mt7530_hw_vlan_entry {
diff --git a/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch b/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch
deleted file mode 100644
index d9d70f1d4d..0000000000
--- a/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-From 9764a08b3d260f4e7799d34bbfe64463db940d74 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Thu, 18 Apr 2024 08:35:31 +0300
-Subject: [PATCH 5/5] net: dsa: mt7530: simplify core operations
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The core_rmw() function calls core_read_mmd_indirect() to read the
-requested register, and then calls core_write_mmd_indirect() to write the
-requested value to the register. Because Clause 22 is used to access Clause
-45 registers, some operations on core_write_mmd_indirect() are
-unnecessarily run. Get rid of core_read_mmd_indirect() and
-core_write_mmd_indirect(), and run only the necessary operations on
-core_write() and core_rmw().
-
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 108 ++++++++++++++++-----------------------
- 1 file changed, 43 insertions(+), 65 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -74,116 +74,94 @@ static const struct mt7530_mib_desc mt75
- MIB_DESC(1, 0xb8, "RxArlDrop"),
- };
-
--/* Since phy_device has not yet been created and
-- * phy_{read,write}_mmd_indirect is not available, we provide our own
-- * core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers
-- * to complete this function.
-- */
--static int
--core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
-+static void
-+mt7530_mutex_lock(struct mt7530_priv *priv)
-+{
-+ if (priv->bus)
-+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+}
-+
-+static void
-+mt7530_mutex_unlock(struct mt7530_priv *priv)
-+{
-+ if (priv->bus)
-+ mutex_unlock(&priv->bus->mdio_lock);
-+}
-+
-+static void
-+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
- {
- struct mii_bus *bus = priv->bus;
-- int value, ret;
-+ int ret;
-+
-+ mt7530_mutex_lock(priv);
-
- /* Write the desired MMD Devad */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_CTRL, devad);
-+ MII_MMD_CTRL, MDIO_MMD_VEND2);
- if (ret < 0)
- goto err;
-
- /* Write the desired MMD register address */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_DATA, prtad);
-+ MII_MMD_DATA, reg);
- if (ret < 0)
- goto err;
-
- /* Select the Function : DATA with no post increment */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
-+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
- if (ret < 0)
- goto err;
-
-- /* Read the content of the MMD's selected register */
-- value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_DATA);
--
-- return value;
-+ /* Write the data into MMD's selected register */
-+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_DATA, val);
- err:
-- dev_err(&bus->dev, "failed to read mmd register\n");
-+ if (ret < 0)
-+ dev_err(&bus->dev, "failed to write mmd register\n");
-
-- return ret;
-+ mt7530_mutex_unlock(priv);
- }
-
--static int
--core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
-- int devad, u32 data)
-+static void
-+core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
- {
- struct mii_bus *bus = priv->bus;
-+ u32 val;
- int ret;
-
-+ mt7530_mutex_lock(priv);
-+
- /* Write the desired MMD Devad */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_CTRL, devad);
-+ MII_MMD_CTRL, MDIO_MMD_VEND2);
- if (ret < 0)
- goto err;
-
- /* Write the desired MMD register address */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_DATA, prtad);
-+ MII_MMD_DATA, reg);
- if (ret < 0)
- goto err;
-
- /* Select the Function : DATA with no post increment */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
-+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
- if (ret < 0)
- goto err;
-
-+ /* Read the content of the MMD's selected register */
-+ val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-+ MII_MMD_DATA);
-+ val &= ~mask;
-+ val |= set;
- /* Write the data into MMD's selected register */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
-- MII_MMD_DATA, data);
-+ MII_MMD_DATA, val);
- err:
- if (ret < 0)
-- dev_err(&bus->dev,
-- "failed to write mmd register\n");
-- return ret;
--}
--
--static void
--mt7530_mutex_lock(struct mt7530_priv *priv)
--{
-- if (priv->bus)
-- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
--}
--
--static void
--mt7530_mutex_unlock(struct mt7530_priv *priv)
--{
-- if (priv->bus)
-- mutex_unlock(&priv->bus->mdio_lock);
--}
--
--static void
--core_write(struct mt7530_priv *priv, u32 reg, u32 val)
--{
-- mt7530_mutex_lock(priv);
--
-- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
--
-- mt7530_mutex_unlock(priv);
--}
--
--static void
--core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
--{
-- u32 val;
--
-- mt7530_mutex_lock(priv);
--
-- val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
-- val &= ~mask;
-- val |= set;
-- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
-+ dev_err(&bus->dev, "failed to write mmd register\n");
-
- mt7530_mutex_unlock(priv);
- }
diff --git a/target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch b/target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch
deleted file mode 100644
index 44cf60cf14..0000000000
--- a/target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 856e8954a0a88d1a4d2b43e9002b9249131a156f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:08 +0300
-Subject: [PATCH 01/15] net: dsa: mt7530: disable EEE abilities on failure on
- MT7531 and MT7988
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 bits let the
-PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits determine the 1G/100 EEE
-abilities of the MAC. If MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 are
-unset, the abilities are left to be determined by PHY auto polling.
-
-The commit 40b5d2f15c09 ("net: dsa: mt7530: Add support for EEE features")
-made it so that the PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits are set on
-mt753x_phylink_mac_link_up(). But it did not set the MT7531_FORCE_EEE1G and
-MT7531_FORCE_EEE100 bits. Because of this, the EEE abilities will be
-determined by PHY auto polling, regardless of the result of phy_init_eee().
-
-Define these bits and add them to the MT7531_FORCE_MODE mask which is set
-in mt7531_setup_common(). With this, there won't be any EEE abilities set
-when phy_init_eee() returns a negative value.
-
-Thanks to Russell for explaining when phy_init_eee() could return a
-negative value below.
-
-Looking at phy_init_eee(), it could return a negative value when:
-
-1. phydev->drv is NULL
-2. if genphy_c45_eee_is_active() returns negative
-3. if genphy_c45_eee_is_active() returns zero, it returns -EPROTONOSUPPORT
-4. if phy_set_bits_mmd() fails (e.g. communication error with the PHY)
-
-If we then look at genphy_c45_eee_is_active(), then:
-
-genphy_c45_read_eee_adv() and genphy_c45_read_eee_lpa() propagate their
-non-zero return values, otherwise this function returns zero or positive
-integer.
-
-If we then look at genphy_c45_read_eee_adv(), then a failure of
-phy_read_mmd() would cause a negative value to be returned.
-
-Looking at genphy_c45_read_eee_lpa(), the same is true.
-
-So, it can be summarised as:
-
-- phydev->drv is NULL
-- there is a communication error accessing the PHY
-- EEE is not active
-
-otherwise, it returns zero on success.
-
-If one wishes to determine whether an error occurred vs EEE not being
-supported through negotiation for the negotiated speed, if it returns
--EPROTONOSUPPORT in the latter case. Other error codes mean either the
-driver has been unloaded or communication error.
-
-In conclusion, determining the EEE abilities by PHY auto polling shouldn't
-result in having any EEE abilities enabled, when one of the last two
-situations in the summary happens. And it seems that if phydev->drv is
-NULL, there would be bigger problems with the device than a broken link. So
-this is not a bugfix.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.h | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -328,11 +328,15 @@ enum mt7530_vlan_port_acc_frm {
- #define MT7531_FORCE_DPX BIT(29)
- #define MT7531_FORCE_RX_FC BIT(28)
- #define MT7531_FORCE_TX_FC BIT(27)
-+#define MT7531_FORCE_EEE100 BIT(26)
-+#define MT7531_FORCE_EEE1G BIT(25)
- #define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \
- MT7531_FORCE_SPD | \
- MT7531_FORCE_DPX | \
- MT7531_FORCE_RX_FC | \
-- MT7531_FORCE_TX_FC)
-+ MT7531_FORCE_TX_FC | \
-+ MT7531_FORCE_EEE100 | \
-+ MT7531_FORCE_EEE1G)
- #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
diff --git a/target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch b/target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch
deleted file mode 100644
index 158e5f8c00..0000000000
--- a/target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch
+++ /dev/null
@@ -1,200 +0,0 @@
-From 712ad00d2f43814c81a7abfcbc339690a05fb6a0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:09 +0300
-Subject: [PATCH 02/15] net: dsa: mt7530: refactor MT7530_PMCR_P()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MT7530_PMCR_P() registers are on MT7530, MT7531, and the switch on the
-MT7988 SoC. Rename the definition for them to MT753X_PMCR_P(). Bit 15 is
-for MT7530 only. Add MT7530 prefix to the definition for bit 15.
-
-Use GENMASK and FIELD_PREP for PMCR_IFG_XMIT().
-
-Rename PMCR_TX_EN and PMCR_RX_EN to PMCR_MAC_TX_EN and PMCR_MAC_TX_EN to
-follow the naming on the "MT7621 Giga Switch Programming Guide v0.3",
-"MT7531 Reference Manual for Development Board v1.0", and "MT7988A Wi-Fi 7
-Generation Router Platform: Datasheet (Open Version) v0.1" documents.
-
-These documents show that PMCR_RX_FC_EN is at bit 5. Correct this along
-with renaming it to PMCR_FORCE_RX_FC_EN, and the same for PMCR_TX_FC_EN.
-
-Remove PMCR_SPEED_MASK which doesn't have a use.
-
-Rename the force mode definitions for MT7531 to FORCE_MODE. Add MASK at the
-end for the mask that includes all force mode definitions.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 24 ++++++++---------
- drivers/net/dsa/mt7530.h | 58 +++++++++++++++++++++-------------------
- 2 files changed, 42 insertions(+), 40 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -903,7 +903,7 @@ static void mt7530_setup_port5(struct ds
- val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
-
- /* Setup the MAC by default for the cpu port */
-- mt7530_write(priv, MT7530_PMCR_P(5), 0x56300);
-+ mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
- break;
- case P5_INTF_SEL_GMAC5:
- /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
-@@ -2449,8 +2449,8 @@ mt7530_setup(struct dsa_switch *ds)
- /* Clear link settings and enable force mode to force link down
- * on all ports until they're enabled later.
- */
-- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
-- PMCR_FORCE_MODE, PMCR_FORCE_MODE);
-+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
-+ MT7530_FORCE_MODE, MT7530_FORCE_MODE);
-
- /* Disable forwarding by default on all ports */
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
-@@ -2560,8 +2560,8 @@ mt7531_setup_common(struct dsa_switch *d
- /* Clear link settings and enable force mode to force link down
- * on all ports until they're enabled later.
- */
-- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
-- MT7531_FORCE_MODE, MT7531_FORCE_MODE);
-+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
-+ MT7531_FORCE_MODE_MASK, MT7531_FORCE_MODE_MASK);
-
- /* Disable forwarding by default on all ports */
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
-@@ -2644,7 +2644,7 @@ mt7531_setup(struct dsa_switch *ds)
-
- /* Force link down on all ports before internal reset */
- for (i = 0; i < MT7530_NUM_PORTS; i++)
-- mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
-+ mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK);
-
- /* Reset the switch through internal reset */
- mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
-@@ -2886,7 +2886,7 @@ mt753x_phylink_mac_config(struct phylink
-
- /* Are we connected to external phy */
- if (port == 5 && dsa_is_user_port(ds, 5))
-- mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
-+ mt7530_set(priv, MT753X_PMCR_P(port), PMCR_EXT_PHY);
- }
-
- static void mt753x_phylink_mac_link_down(struct phylink_config *config,
-@@ -2896,7 +2896,7 @@ static void mt753x_phylink_mac_link_down
- struct dsa_port *dp = dsa_phylink_to_port(config);
- struct mt7530_priv *priv = dp->ds->priv;
-
-- mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
-+ mt7530_clear(priv, MT753X_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
- }
-
- static void mt753x_phylink_mac_link_up(struct phylink_config *config,
-@@ -2910,7 +2910,7 @@ static void mt753x_phylink_mac_link_up(s
- struct mt7530_priv *priv = dp->ds->priv;
- u32 mcr;
-
-- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
-+ mcr = PMCR_MAC_RX_EN | PMCR_MAC_TX_EN | PMCR_FORCE_LNK;
-
- switch (speed) {
- case SPEED_1000:
-@@ -2925,9 +2925,9 @@ static void mt753x_phylink_mac_link_up(s
- if (duplex == DUPLEX_FULL) {
- mcr |= PMCR_FORCE_FDX;
- if (tx_pause)
-- mcr |= PMCR_TX_FC_EN;
-+ mcr |= PMCR_FORCE_TX_FC_EN;
- if (rx_pause)
-- mcr |= PMCR_RX_FC_EN;
-+ mcr |= PMCR_FORCE_RX_FC_EN;
- }
-
- if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
-@@ -2942,7 +2942,7 @@ static void mt753x_phylink_mac_link_up(s
- }
- }
-
-- mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
-+ mt7530_set(priv, MT753X_PMCR_P(dp->index), mcr);
- }
-
- static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -304,44 +304,46 @@ enum mt7530_vlan_port_acc_frm {
- #define G0_PORT_VID_DEF G0_PORT_VID(0)
-
- /* Register for port MAC control register */
--#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100))
--#define PMCR_IFG_XMIT(x) (((x) & 0x3) << 18)
-+#define MT753X_PMCR_P(x) (0x3000 + ((x) * 0x100))
-+#define PMCR_IFG_XMIT_MASK GENMASK(19, 18)
-+#define PMCR_IFG_XMIT(x) FIELD_PREP(PMCR_IFG_XMIT_MASK, x)
- #define PMCR_EXT_PHY BIT(17)
- #define PMCR_MAC_MODE BIT(16)
--#define PMCR_FORCE_MODE BIT(15)
--#define PMCR_TX_EN BIT(14)
--#define PMCR_RX_EN BIT(13)
-+#define MT7530_FORCE_MODE BIT(15)
-+#define PMCR_MAC_TX_EN BIT(14)
-+#define PMCR_MAC_RX_EN BIT(13)
- #define PMCR_BACKOFF_EN BIT(9)
- #define PMCR_BACKPR_EN BIT(8)
- #define PMCR_FORCE_EEE1G BIT(7)
- #define PMCR_FORCE_EEE100 BIT(6)
--#define PMCR_TX_FC_EN BIT(5)
--#define PMCR_RX_FC_EN BIT(4)
-+#define PMCR_FORCE_RX_FC_EN BIT(5)
-+#define PMCR_FORCE_TX_FC_EN BIT(4)
- #define PMCR_FORCE_SPEED_1000 BIT(3)
- #define PMCR_FORCE_SPEED_100 BIT(2)
- #define PMCR_FORCE_FDX BIT(1)
- #define PMCR_FORCE_LNK BIT(0)
--#define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \
-- PMCR_FORCE_SPEED_1000)
--#define MT7531_FORCE_LNK BIT(31)
--#define MT7531_FORCE_SPD BIT(30)
--#define MT7531_FORCE_DPX BIT(29)
--#define MT7531_FORCE_RX_FC BIT(28)
--#define MT7531_FORCE_TX_FC BIT(27)
--#define MT7531_FORCE_EEE100 BIT(26)
--#define MT7531_FORCE_EEE1G BIT(25)
--#define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \
-- MT7531_FORCE_SPD | \
-- MT7531_FORCE_DPX | \
-- MT7531_FORCE_RX_FC | \
-- MT7531_FORCE_TX_FC | \
-- MT7531_FORCE_EEE100 | \
-- MT7531_FORCE_EEE1G)
--#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
-- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
-- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
-- PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
-- PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
-+#define MT7531_FORCE_MODE_LNK BIT(31)
-+#define MT7531_FORCE_MODE_SPD BIT(30)
-+#define MT7531_FORCE_MODE_DPX BIT(29)
-+#define MT7531_FORCE_MODE_RX_FC BIT(28)
-+#define MT7531_FORCE_MODE_TX_FC BIT(27)
-+#define MT7531_FORCE_MODE_EEE100 BIT(26)
-+#define MT7531_FORCE_MODE_EEE1G BIT(25)
-+#define MT7531_FORCE_MODE_MASK (MT7531_FORCE_MODE_LNK | \
-+ MT7531_FORCE_MODE_SPD | \
-+ MT7531_FORCE_MODE_DPX | \
-+ MT7531_FORCE_MODE_RX_FC | \
-+ MT7531_FORCE_MODE_TX_FC | \
-+ MT7531_FORCE_MODE_EEE100 | \
-+ MT7531_FORCE_MODE_EEE1G)
-+#define PMCR_LINK_SETTINGS_MASK (PMCR_MAC_TX_EN | PMCR_MAC_RX_EN | \
-+ PMCR_FORCE_EEE1G | \
-+ PMCR_FORCE_EEE100 | \
-+ PMCR_FORCE_RX_FC_EN | \
-+ PMCR_FORCE_TX_FC_EN | \
-+ PMCR_FORCE_SPEED_1000 | \
-+ PMCR_FORCE_SPEED_100 | \
-+ PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-
- #define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100)
- #define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24)
diff --git a/target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch b/target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch
deleted file mode 100644
index 9a0ce7c36c..0000000000
--- a/target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch
+++ /dev/null
@@ -1,185 +0,0 @@
-From 875ec5b67ab88e969b171e6e9ea803e3ed759614 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:10 +0300
-Subject: [PATCH 03/15] net: dsa: mt7530: rename p5_intf_sel and use only for
- MT7530 switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The p5_intf_sel pointer is used to store the information of whether PHY
-muxing is used or not. PHY muxing is a feature specific to port 5 of the
-MT7530 switch. Do not use it for other switch models.
-
-Rename the pointer to p5_mode to store the mode the port is being used in.
-Rename the p5_interface_select enum to mt7530_p5_mode, the string
-representation to mt7530_p5_mode_str, and the enum elements.
-
-If PHY muxing is not detected, the default mode, GMAC5, will be used.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 62 +++++++++++++++++-----------------------
- drivers/net/dsa/mt7530.h | 15 +++++-----
- 2 files changed, 33 insertions(+), 44 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -864,19 +864,15 @@ mt7530_set_ageing_time(struct dsa_switch
- return 0;
- }
-
--static const char *p5_intf_modes(unsigned int p5_interface)
-+static const char *mt7530_p5_mode_str(unsigned int mode)
- {
-- switch (p5_interface) {
-- case P5_DISABLED:
-- return "DISABLED";
-- case P5_INTF_SEL_PHY_P0:
-- return "PHY P0";
-- case P5_INTF_SEL_PHY_P4:
-- return "PHY P4";
-- case P5_INTF_SEL_GMAC5:
-- return "GMAC5";
-+ switch (mode) {
-+ case MUX_PHY_P0:
-+ return "MUX PHY P0";
-+ case MUX_PHY_P4:
-+ return "MUX PHY P4";
- default:
-- return "unknown";
-+ return "GMAC5";
- }
- }
-
-@@ -893,23 +889,23 @@ static void mt7530_setup_port5(struct ds
- val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS;
- val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL;
-
-- switch (priv->p5_intf_sel) {
-- case P5_INTF_SEL_PHY_P0:
-- /* MT7530_P5_MODE_GPHY_P0: 2nd GMAC -> P5 -> P0 */
-+ switch (priv->p5_mode) {
-+ /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
-+ case MUX_PHY_P0:
- val |= MHWTRAP_PHY0_SEL;
- fallthrough;
-- case P5_INTF_SEL_PHY_P4:
-- /* MT7530_P5_MODE_GPHY_P4: 2nd GMAC -> P5 -> P4 */
-+
-+ /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
-+ case MUX_PHY_P4:
- val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
-
- /* Setup the MAC by default for the cpu port */
- mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
- break;
-- case P5_INTF_SEL_GMAC5:
-- /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
-- val &= ~MHWTRAP_P5_DIS;
-- break;
-+
-+ /* GMAC5: P5 -> SoC MAC or external PHY */
- default:
-+ val &= ~MHWTRAP_P5_DIS;
- break;
- }
-
-@@ -937,8 +933,8 @@ static void mt7530_setup_port5(struct ds
-
- mt7530_write(priv, MT7530_MHWTRAP, val);
-
-- dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
-- val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
-+ dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val,
-+ mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface));
-
- mutex_unlock(&priv->reg_mutex);
- }
-@@ -2481,13 +2477,11 @@ mt7530_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-- /* Setup port 5 */
-- if (!dsa_is_unused_port(ds, 5)) {
-- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
-- } else {
-+ /* Check for PHY muxing on port 5 */
-+ if (dsa_is_unused_port(ds, 5)) {
- /* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY.
-- * Set priv->p5_intf_sel to the appropriate value if PHY muxing
-- * is detected.
-+ * Set priv->p5_mode to the appropriate value if PHY muxing is
-+ * detected.
- */
- for_each_child_of_node(dn, mac_np) {
- if (!of_device_is_compatible(mac_np,
-@@ -2511,17 +2505,16 @@ mt7530_setup(struct dsa_switch *ds)
- }
- id = of_mdio_parse_addr(ds->dev, phy_node);
- if (id == 0)
-- priv->p5_intf_sel = P5_INTF_SEL_PHY_P0;
-+ priv->p5_mode = MUX_PHY_P0;
- if (id == 4)
-- priv->p5_intf_sel = P5_INTF_SEL_PHY_P4;
-+ priv->p5_mode = MUX_PHY_P4;
- }
- of_node_put(mac_np);
- of_node_put(phy_node);
- break;
- }
-
-- if (priv->p5_intf_sel == P5_INTF_SEL_PHY_P0 ||
-- priv->p5_intf_sel == P5_INTF_SEL_PHY_P4)
-+ if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4)
- mt7530_setup_port5(ds, interface);
- }
-
-@@ -2659,9 +2652,6 @@ mt7531_setup(struct dsa_switch *ds)
- MT7531_EXT_P_MDIO_12);
- }
-
-- if (!dsa_is_unused_port(ds, 5))
-- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
--
- mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
- MT7531_GPIO0_INTERRUPT);
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -708,12 +708,11 @@ struct mt7530_port {
- struct phylink_pcs *sgmii_pcs;
- };
-
--/* Port 5 interface select definitions */
--enum p5_interface_select {
-- P5_DISABLED,
-- P5_INTF_SEL_PHY_P0,
-- P5_INTF_SEL_PHY_P4,
-- P5_INTF_SEL_GMAC5,
-+/* Port 5 mode definitions of the MT7530 switch */
-+enum mt7530_p5_mode {
-+ GMAC5,
-+ MUX_PHY_P0,
-+ MUX_PHY_P4,
- };
-
- struct mt7530_priv;
-@@ -769,7 +768,7 @@ struct mt753x_info {
- * @ports: Holding the state among ports
- * @reg_mutex: The lock for protecting among process accessing
- * registers
-- * @p5_intf_sel: Holding the current port 5 interface select
-+ * @p5_mode: Holding the current mode of port 5 of the MT7530 switch
- * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
- * has got SGMII
- * @irq: IRQ number of the switch
-@@ -791,7 +790,7 @@ struct mt7530_priv {
- const struct mt753x_info *info;
- unsigned int id;
- bool mcm;
-- enum p5_interface_select p5_intf_sel;
-+ enum mt7530_p5_mode p5_mode;
- bool p5_sgmii;
- u8 mirror_rx;
- u8 mirror_tx;
diff --git a/target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch b/target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch
deleted file mode 100644
index c8ffd5f07c..0000000000
--- a/target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch
+++ /dev/null
@@ -1,169 +0,0 @@
-From 83fe3df057e641cd0e88425e579d7a5a370ca430 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:11 +0300
-Subject: [PATCH 04/15] net: dsa: mt7530: rename mt753x_bpdu_port_fw enum to
- mt753x_to_cpu_fw
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The mt753x_bpdu_port_fw enum is globally used for manipulating the process
-of deciding the forwardable ports, specifically concerning the CPU port(s).
-Therefore, rename it and the values in it to mt753x_to_cpu_fw.
-
-Change FOLLOW_MFC to SYSTEM_DEFAULT to be on par with the switch documents.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 44 ++++++++++-------------
- drivers/net/dsa/mt7530.h | 76 ++++++++++++++++++++--------------------
- 2 files changed, 56 insertions(+), 64 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1114,42 +1114,34 @@ mt753x_trap_frames(struct mt7530_priv *p
- * VLAN-untagged.
- */
- mt7530_rmw(priv, MT753X_BPC,
-- MT753X_PAE_BPDU_FR | MT753X_PAE_EG_TAG_MASK |
-- MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK |
-- MT753X_BPDU_PORT_FW_MASK,
-- MT753X_PAE_BPDU_FR |
-- MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) |
-- MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_BPDU_CPU_ONLY);
-+ PAE_BPDU_FR | PAE_EG_TAG_MASK | PAE_PORT_FW_MASK |
-+ BPDU_EG_TAG_MASK | BPDU_PORT_FW_MASK,
-+ PAE_BPDU_FR | PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-+ PAE_PORT_FW(TO_CPU_FW_CPU_ONLY) |
-+ BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-+ TO_CPU_FW_CPU_ONLY);
-
- /* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress
- * them VLAN-untagged.
- */
- mt7530_rmw(priv, MT753X_RGAC1,
-- MT753X_R02_BPDU_FR | MT753X_R02_EG_TAG_MASK |
-- MT753X_R02_PORT_FW_MASK | MT753X_R01_BPDU_FR |
-- MT753X_R01_EG_TAG_MASK | MT753X_R01_PORT_FW_MASK,
-- MT753X_R02_BPDU_FR |
-- MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) |
-- MT753X_R01_BPDU_FR |
-- MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_BPDU_CPU_ONLY);
-+ R02_BPDU_FR | R02_EG_TAG_MASK | R02_PORT_FW_MASK |
-+ R01_BPDU_FR | R01_EG_TAG_MASK | R01_PORT_FW_MASK,
-+ R02_BPDU_FR | R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-+ R02_PORT_FW(TO_CPU_FW_CPU_ONLY) | R01_BPDU_FR |
-+ R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-+ TO_CPU_FW_CPU_ONLY);
-
- /* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress
- * them VLAN-untagged.
- */
- mt7530_rmw(priv, MT753X_RGAC2,
-- MT753X_R0E_BPDU_FR | MT753X_R0E_EG_TAG_MASK |
-- MT753X_R0E_PORT_FW_MASK | MT753X_R03_BPDU_FR |
-- MT753X_R03_EG_TAG_MASK | MT753X_R03_PORT_FW_MASK,
-- MT753X_R0E_BPDU_FR |
-- MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) |
-- MT753X_R03_BPDU_FR |
-- MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_BPDU_CPU_ONLY);
-+ R0E_BPDU_FR | R0E_EG_TAG_MASK | R0E_PORT_FW_MASK |
-+ R03_BPDU_FR | R03_EG_TAG_MASK | R03_PORT_FW_MASK,
-+ R0E_BPDU_FR | R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-+ R0E_PORT_FW(TO_CPU_FW_CPU_ONLY) | R03_BPDU_FR |
-+ R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-+ TO_CPU_FW_CPU_ONLY);
- }
-
- static void
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -67,47 +67,47 @@ enum mt753x_id {
- #define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
- MT7531_MIRROR_MASK : MIRROR_MASK)
-
--/* Registers for BPDU and PAE frame control*/
-+/* Register for BPDU and PAE frame control */
- #define MT753X_BPC 0x24
--#define MT753X_PAE_BPDU_FR BIT(25)
--#define MT753X_PAE_EG_TAG_MASK GENMASK(24, 22)
--#define MT753X_PAE_EG_TAG(x) FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x)
--#define MT753X_PAE_PORT_FW_MASK GENMASK(18, 16)
--#define MT753X_PAE_PORT_FW(x) FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x)
--#define MT753X_BPDU_EG_TAG_MASK GENMASK(8, 6)
--#define MT753X_BPDU_EG_TAG(x) FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x)
--#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0)
-+#define PAE_BPDU_FR BIT(25)
-+#define PAE_EG_TAG_MASK GENMASK(24, 22)
-+#define PAE_EG_TAG(x) FIELD_PREP(PAE_EG_TAG_MASK, x)
-+#define PAE_PORT_FW_MASK GENMASK(18, 16)
-+#define PAE_PORT_FW(x) FIELD_PREP(PAE_PORT_FW_MASK, x)
-+#define BPDU_EG_TAG_MASK GENMASK(8, 6)
-+#define BPDU_EG_TAG(x) FIELD_PREP(BPDU_EG_TAG_MASK, x)
-+#define BPDU_PORT_FW_MASK GENMASK(2, 0)
-
--/* Register for :01 and :02 MAC DA frame control */
-+/* Register for 01-80-C2-00-00-[01,02] MAC DA frame control */
- #define MT753X_RGAC1 0x28
--#define MT753X_R02_BPDU_FR BIT(25)
--#define MT753X_R02_EG_TAG_MASK GENMASK(24, 22)
--#define MT753X_R02_EG_TAG(x) FIELD_PREP(MT753X_R02_EG_TAG_MASK, x)
--#define MT753X_R02_PORT_FW_MASK GENMASK(18, 16)
--#define MT753X_R02_PORT_FW(x) FIELD_PREP(MT753X_R02_PORT_FW_MASK, x)
--#define MT753X_R01_BPDU_FR BIT(9)
--#define MT753X_R01_EG_TAG_MASK GENMASK(8, 6)
--#define MT753X_R01_EG_TAG(x) FIELD_PREP(MT753X_R01_EG_TAG_MASK, x)
--#define MT753X_R01_PORT_FW_MASK GENMASK(2, 0)
-+#define R02_BPDU_FR BIT(25)
-+#define R02_EG_TAG_MASK GENMASK(24, 22)
-+#define R02_EG_TAG(x) FIELD_PREP(R02_EG_TAG_MASK, x)
-+#define R02_PORT_FW_MASK GENMASK(18, 16)
-+#define R02_PORT_FW(x) FIELD_PREP(R02_PORT_FW_MASK, x)
-+#define R01_BPDU_FR BIT(9)
-+#define R01_EG_TAG_MASK GENMASK(8, 6)
-+#define R01_EG_TAG(x) FIELD_PREP(R01_EG_TAG_MASK, x)
-+#define R01_PORT_FW_MASK GENMASK(2, 0)
-
--/* Register for :03 and :0E MAC DA frame control */
-+/* Register for 01-80-C2-00-00-[03,0E] MAC DA frame control */
- #define MT753X_RGAC2 0x2c
--#define MT753X_R0E_BPDU_FR BIT(25)
--#define MT753X_R0E_EG_TAG_MASK GENMASK(24, 22)
--#define MT753X_R0E_EG_TAG(x) FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x)
--#define MT753X_R0E_PORT_FW_MASK GENMASK(18, 16)
--#define MT753X_R0E_PORT_FW(x) FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
--#define MT753X_R03_BPDU_FR BIT(9)
--#define MT753X_R03_EG_TAG_MASK GENMASK(8, 6)
--#define MT753X_R03_EG_TAG(x) FIELD_PREP(MT753X_R03_EG_TAG_MASK, x)
--#define MT753X_R03_PORT_FW_MASK GENMASK(2, 0)
-+#define R0E_BPDU_FR BIT(25)
-+#define R0E_EG_TAG_MASK GENMASK(24, 22)
-+#define R0E_EG_TAG(x) FIELD_PREP(R0E_EG_TAG_MASK, x)
-+#define R0E_PORT_FW_MASK GENMASK(18, 16)
-+#define R0E_PORT_FW(x) FIELD_PREP(R0E_PORT_FW_MASK, x)
-+#define R03_BPDU_FR BIT(9)
-+#define R03_EG_TAG_MASK GENMASK(8, 6)
-+#define R03_EG_TAG(x) FIELD_PREP(R03_EG_TAG_MASK, x)
-+#define R03_PORT_FW_MASK GENMASK(2, 0)
-
--enum mt753x_bpdu_port_fw {
-- MT753X_BPDU_FOLLOW_MFC,
-- MT753X_BPDU_CPU_EXCLUDE = 4,
-- MT753X_BPDU_CPU_INCLUDE = 5,
-- MT753X_BPDU_CPU_ONLY = 6,
-- MT753X_BPDU_DROP = 7,
-+enum mt753x_to_cpu_fw {
-+ TO_CPU_FW_SYSTEM_DEFAULT,
-+ TO_CPU_FW_CPU_EXCLUDE = 4,
-+ TO_CPU_FW_CPU_INCLUDE = 5,
-+ TO_CPU_FW_CPU_ONLY = 6,
-+ TO_CPU_FW_DROP = 7,
- };
-
- /* Registers for address table access */
diff --git a/target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch b/target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch
deleted file mode 100644
index c977fe46cd..0000000000
--- a/target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From 1dbc1bdc2869e6d2929235c70d64e393aa5a5fa2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:12 +0300
-Subject: [PATCH 05/15] net: dsa: mt7530: refactor MT7530_MFC and MT7531_CFC,
- add MT7531_QRY_FFP
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MT7530_MFC register is on MT7530, MT7531, and the switch on the MT7988
-SoC. Rename it to MT753X_MFC. Bit 7 to 0 differs between MT7530 and
-MT7531/MT7988. Add MT7530 prefix to these definitions, and define the
-IGMP/MLD Query Frame Flooding Ports mask for MT7531.
-
-Rename the cases of MIRROR_MASK to MIRROR_PORT_MASK.
-
-Move mt753x_mirror_port_get() and mt753x_port_mirror_set() to mt7530.h as
-macros.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 38 ++++++++--------------
- drivers/net/dsa/mt7530.h | 69 +++++++++++++++++++++++++---------------
- 2 files changed, 57 insertions(+), 50 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1154,7 +1154,7 @@ mt753x_cpu_port_enable(struct dsa_switch
- PORT_SPEC_TAG);
-
- /* Enable flooding on the CPU port */
-- mt7530_set(priv, MT7530_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
-+ mt7530_set(priv, MT753X_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
- UNU_FFP(BIT(port)));
-
- /* Add the CPU port to the CPU port bitmap for MT7531. Trapped frames
-@@ -1318,15 +1318,15 @@ mt7530_port_bridge_flags(struct dsa_swit
- flags.val & BR_LEARNING ? 0 : SA_DIS);
-
- if (flags.mask & BR_FLOOD)
-- mt7530_rmw(priv, MT7530_MFC, UNU_FFP(BIT(port)),
-+ mt7530_rmw(priv, MT753X_MFC, UNU_FFP(BIT(port)),
- flags.val & BR_FLOOD ? UNU_FFP(BIT(port)) : 0);
-
- if (flags.mask & BR_MCAST_FLOOD)
-- mt7530_rmw(priv, MT7530_MFC, UNM_FFP(BIT(port)),
-+ mt7530_rmw(priv, MT753X_MFC, UNM_FFP(BIT(port)),
- flags.val & BR_MCAST_FLOOD ? UNM_FFP(BIT(port)) : 0);
-
- if (flags.mask & BR_BCAST_FLOOD)
-- mt7530_rmw(priv, MT7530_MFC, BC_FFP(BIT(port)),
-+ mt7530_rmw(priv, MT753X_MFC, BC_FFP(BIT(port)),
- flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0);
-
- return 0;
-@@ -1862,20 +1862,6 @@ mt7530_port_vlan_del(struct dsa_switch *
- return 0;
- }
-
--static int mt753x_mirror_port_get(unsigned int id, u32 val)
--{
-- return (id == ID_MT7531 || id == ID_MT7988) ?
-- MT7531_MIRROR_PORT_GET(val) :
-- MIRROR_PORT(val);
--}
--
--static int mt753x_mirror_port_set(unsigned int id, u32 val)
--{
-- return (id == ID_MT7531 || id == ID_MT7988) ?
-- MT7531_MIRROR_PORT_SET(val) :
-- MIRROR_PORT(val);
--}
--
- static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
- struct dsa_mall_mirror_tc_entry *mirror,
- bool ingress, struct netlink_ext_ack *extack)
-@@ -1891,14 +1877,14 @@ static int mt753x_port_mirror_add(struct
- val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
-
- /* MT7530 only supports one monitor port */
-- monitor_port = mt753x_mirror_port_get(priv->id, val);
-+ monitor_port = MT753X_MIRROR_PORT_GET(priv->id, val);
- if (val & MT753X_MIRROR_EN(priv->id) &&
- monitor_port != mirror->to_local_port)
- return -EEXIST;
-
- val |= MT753X_MIRROR_EN(priv->id);
-- val &= ~MT753X_MIRROR_MASK(priv->id);
-- val |= mt753x_mirror_port_set(priv->id, mirror->to_local_port);
-+ val &= ~MT753X_MIRROR_PORT_MASK(priv->id);
-+ val |= MT753X_MIRROR_PORT_SET(priv->id, mirror->to_local_port);
- mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val);
-
- val = mt7530_read(priv, MT7530_PCR_P(port));
-@@ -2538,7 +2524,7 @@ mt7531_setup_common(struct dsa_switch *d
- mt7530_mib_reset(ds);
-
- /* Disable flooding on all ports */
-- mt7530_clear(priv, MT7530_MFC, BC_FFP_MASK | UNM_FFP_MASK |
-+ mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK |
- UNU_FFP_MASK);
-
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-@@ -3100,10 +3086,12 @@ mt753x_conduit_state_change(struct dsa_s
- else
- priv->active_cpu_ports &= ~mask;
-
-- if (priv->active_cpu_ports)
-- val = CPU_EN | CPU_PORT(__ffs(priv->active_cpu_ports));
-+ if (priv->active_cpu_ports) {
-+ val = MT7530_CPU_EN |
-+ MT7530_CPU_PORT(__ffs(priv->active_cpu_ports));
-+ }
-
-- mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
-+ mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val);
- }
-
- static int mt7988_setup(struct dsa_switch *ds)
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -36,36 +36,55 @@ enum mt753x_id {
- #define MT753X_AGC 0xc
- #define LOCAL_EN BIT(7)
-
--/* Registers to mac forward control for unknown frames */
--#define MT7530_MFC 0x10
--#define BC_FFP(x) (((x) & 0xff) << 24)
--#define BC_FFP_MASK BC_FFP(~0)
--#define UNM_FFP(x) (((x) & 0xff) << 16)
--#define UNM_FFP_MASK UNM_FFP(~0)
--#define UNU_FFP(x) (((x) & 0xff) << 8)
--#define UNU_FFP_MASK UNU_FFP(~0)
--#define CPU_EN BIT(7)
--#define CPU_PORT_MASK GENMASK(6, 4)
--#define CPU_PORT(x) FIELD_PREP(CPU_PORT_MASK, x)
--#define MIRROR_EN BIT(3)
--#define MIRROR_PORT(x) ((x) & 0x7)
--#define MIRROR_MASK 0x7
-+/* Register for MAC forward control */
-+#define MT753X_MFC 0x10
-+#define BC_FFP_MASK GENMASK(31, 24)
-+#define BC_FFP(x) FIELD_PREP(BC_FFP_MASK, x)
-+#define UNM_FFP_MASK GENMASK(23, 16)
-+#define UNM_FFP(x) FIELD_PREP(UNM_FFP_MASK, x)
-+#define UNU_FFP_MASK GENMASK(15, 8)
-+#define UNU_FFP(x) FIELD_PREP(UNU_FFP_MASK, x)
-+#define MT7530_CPU_EN BIT(7)
-+#define MT7530_CPU_PORT_MASK GENMASK(6, 4)
-+#define MT7530_CPU_PORT(x) FIELD_PREP(MT7530_CPU_PORT_MASK, x)
-+#define MT7530_MIRROR_EN BIT(3)
-+#define MT7530_MIRROR_PORT_MASK GENMASK(2, 0)
-+#define MT7530_MIRROR_PORT_GET(x) FIELD_GET(MT7530_MIRROR_PORT_MASK, x)
-+#define MT7530_MIRROR_PORT_SET(x) FIELD_PREP(MT7530_MIRROR_PORT_MASK, x)
-+#define MT7531_QRY_FFP_MASK GENMASK(7, 0)
-+#define MT7531_QRY_FFP(x) FIELD_PREP(MT7531_QRY_FFP_MASK, x)
-
--/* Registers for CPU forward control */
-+/* Register for CPU forward control */
- #define MT7531_CFC 0x4
- #define MT7531_MIRROR_EN BIT(19)
--#define MT7531_MIRROR_MASK (MIRROR_MASK << 16)
--#define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK)
--#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
-+#define MT7531_MIRROR_PORT_MASK GENMASK(18, 16)
-+#define MT7531_MIRROR_PORT_GET(x) FIELD_GET(MT7531_MIRROR_PORT_MASK, x)
-+#define MT7531_MIRROR_PORT_SET(x) FIELD_PREP(MT7531_MIRROR_PORT_MASK, x)
- #define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
- #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x)
-
--#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
-- MT7531_CFC : MT7530_MFC)
--#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
-- MT7531_MIRROR_EN : MIRROR_EN)
--#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
-- MT7531_MIRROR_MASK : MIRROR_MASK)
-+#define MT753X_MIRROR_REG(id) ((id == ID_MT7531 || \
-+ id == ID_MT7988) ? \
-+ MT7531_CFC : MT753X_MFC)
-+
-+#define MT753X_MIRROR_EN(id) ((id == ID_MT7531 || \
-+ id == ID_MT7988) ? \
-+ MT7531_MIRROR_EN : MT7530_MIRROR_EN)
-+
-+#define MT753X_MIRROR_PORT_MASK(id) ((id == ID_MT7531 || \
-+ id == ID_MT7988) ? \
-+ MT7531_MIRROR_PORT_MASK : \
-+ MT7530_MIRROR_PORT_MASK)
-+
-+#define MT753X_MIRROR_PORT_GET(id, val) ((id == ID_MT7531 || \
-+ id == ID_MT7988) ? \
-+ MT7531_MIRROR_PORT_GET(val) : \
-+ MT7530_MIRROR_PORT_GET(val))
-+
-+#define MT753X_MIRROR_PORT_SET(id, val) ((id == ID_MT7531 || \
-+ id == ID_MT7988) ? \
-+ MT7531_MIRROR_PORT_SET(val) : \
-+ MT7530_MIRROR_PORT_SET(val))
-
- /* Register for BPDU and PAE frame control */
- #define MT753X_BPC 0x24
diff --git a/target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch b/target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch
deleted file mode 100644
index 3c487d21f6..0000000000
--- a/target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch
+++ /dev/null
@@ -1,257 +0,0 @@
-From 3ccf67597d35c06a7319e407b1c42f78a7966779 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:13 +0300
-Subject: [PATCH 06/15] net: dsa: mt7530: refactor MT7530_HWTRAP and
- MT7530_MHWTRAP
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MT7530_HWTRAP and MT7530_MHWTRAP registers are on MT7530 and MT7531.
-It's called hardware trap on MT7530, software trap on MT7531. That's
-because some bits of the trap on MT7530 cannot be modified by software
-whilst all bits of the trap on MT7531 can. Rename the definitions for them
-to MT753X_TRAP and MT753X_MTRAP. Add MT7530 and MT7531 prefixes to the
-definitions specific to the switch model.
-
-Remove the extra parentheses from MT7530_XTAL_40MHZ and MT7530_XTAL_20MHZ.
-
-Rename MHWTRAP_PHY0_SEL, MHWTRAP_MANUAL, and MHWTRAP_PHY_ACCESS to be on
-par with the "MT7621 Giga Switch Programming Guide v0.3" document.
-
-Make an enumaration for the XTAL frequency. Set the data type of the xtal
-variable on mt7531_pll_setup() to it.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 59 ++++++++++++++++++++--------------------
- drivers/net/dsa/mt7530.h | 50 ++++++++++++++++------------------
- 2 files changed, 54 insertions(+), 55 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -417,23 +417,23 @@ mt7530_setup_port6(struct dsa_switch *ds
-
- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
-
-- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
-+ xtal = mt7530_read(priv, MT753X_MTRAP) & MT7530_XTAL_MASK;
-
-- if (xtal == HWTRAP_XTAL_25MHZ)
-+ if (xtal == MT7530_XTAL_25MHZ)
- ssc_delta = 0x57;
- else
- ssc_delta = 0x87;
-
- if (priv->id == ID_MT7621) {
- /* PLL frequency: 125MHz: 1.0GBit */
-- if (xtal == HWTRAP_XTAL_40MHZ)
-+ if (xtal == MT7530_XTAL_40MHZ)
- ncpo1 = 0x0640;
-- if (xtal == HWTRAP_XTAL_25MHZ)
-+ if (xtal == MT7530_XTAL_25MHZ)
- ncpo1 = 0x0a00;
- } else { /* PLL frequency: 250MHz: 2.0Gbit */
-- if (xtal == HWTRAP_XTAL_40MHZ)
-+ if (xtal == MT7530_XTAL_40MHZ)
- ncpo1 = 0x0c80;
-- if (xtal == HWTRAP_XTAL_25MHZ)
-+ if (xtal == MT7530_XTAL_25MHZ)
- ncpo1 = 0x1400;
- }
-
-@@ -456,19 +456,20 @@ mt7530_setup_port6(struct dsa_switch *ds
- static void
- mt7531_pll_setup(struct mt7530_priv *priv)
- {
-+ enum mt7531_xtal_fsel xtal;
- u32 top_sig;
- u32 hwstrap;
-- u32 xtal;
- u32 val;
-
- val = mt7530_read(priv, MT7531_CREV);
- top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
-- hwstrap = mt7530_read(priv, MT7531_HWTRAP);
-+ hwstrap = mt7530_read(priv, MT753X_TRAP);
- if ((val & CHIP_REV_M) > 0)
-- xtal = (top_sig & PAD_MCM_SMI_EN) ? HWTRAP_XTAL_FSEL_40MHZ :
-- HWTRAP_XTAL_FSEL_25MHZ;
-+ xtal = (top_sig & PAD_MCM_SMI_EN) ? MT7531_XTAL_FSEL_40MHZ :
-+ MT7531_XTAL_FSEL_25MHZ;
- else
-- xtal = hwstrap & HWTRAP_XTAL_FSEL_MASK;
-+ xtal = (hwstrap & MT7531_XTAL25) ? MT7531_XTAL_FSEL_25MHZ :
-+ MT7531_XTAL_FSEL_40MHZ;
-
- /* Step 1 : Disable MT7531 COREPLL */
- val = mt7530_read(priv, MT7531_PLLGP_EN);
-@@ -497,13 +498,13 @@ mt7531_pll_setup(struct mt7530_priv *pri
- usleep_range(25, 35);
-
- switch (xtal) {
-- case HWTRAP_XTAL_FSEL_25MHZ:
-+ case MT7531_XTAL_FSEL_25MHZ:
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
- val &= ~RG_COREPLL_SDM_PCW_M;
- val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
- break;
-- case HWTRAP_XTAL_FSEL_40MHZ:
-+ case MT7531_XTAL_FSEL_40MHZ:
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
- val &= ~RG_COREPLL_SDM_PCW_M;
- val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
-@@ -884,20 +885,20 @@ static void mt7530_setup_port5(struct ds
-
- mutex_lock(&priv->reg_mutex);
-
-- val = mt7530_read(priv, MT7530_MHWTRAP);
-+ val = mt7530_read(priv, MT753X_MTRAP);
-
-- val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS;
-- val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL;
-+ val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS;
-+ val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL;
-
- switch (priv->p5_mode) {
- /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
- case MUX_PHY_P0:
-- val |= MHWTRAP_PHY0_SEL;
-+ val |= MT7530_P5_PHY0_SEL;
- fallthrough;
-
- /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
- case MUX_PHY_P4:
-- val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
-+ val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS;
-
- /* Setup the MAC by default for the cpu port */
- mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
-@@ -905,13 +906,13 @@ static void mt7530_setup_port5(struct ds
-
- /* GMAC5: P5 -> SoC MAC or external PHY */
- default:
-- val &= ~MHWTRAP_P5_DIS;
-+ val &= ~MT7530_P5_DIS;
- break;
- }
-
- /* Setup RGMII settings */
- if (phy_interface_mode_is_rgmii(interface)) {
-- val |= MHWTRAP_P5_RGMII_MODE;
-+ val |= MT7530_P5_RGMII_MODE;
-
- /* P5 RGMII RX Clock Control: delay setting for 1000M */
- mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);
-@@ -931,7 +932,7 @@ static void mt7530_setup_port5(struct ds
- P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1));
- }
-
-- mt7530_write(priv, MT7530_MHWTRAP, val);
-+ mt7530_write(priv, MT753X_MTRAP, val);
-
- dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val,
- mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface));
-@@ -2370,7 +2371,7 @@ mt7530_setup(struct dsa_switch *ds)
- }
-
- /* Waiting for MT7530 got to stable */
-- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP);
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP);
- ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
- 20, 1000000);
- if (ret < 0) {
-@@ -2385,7 +2386,7 @@ mt7530_setup(struct dsa_switch *ds)
- return -ENODEV;
- }
-
-- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) {
-+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_20MHZ) {
- dev_err(priv->dev,
- "MT7530 with a 20MHz XTAL is not supported!\n");
- return -EINVAL;
-@@ -2406,12 +2407,12 @@ mt7530_setup(struct dsa_switch *ds)
- RD_TAP_MASK, RD_TAP(16));
-
- /* Enable port 6 */
-- val = mt7530_read(priv, MT7530_MHWTRAP);
-- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
-- val |= MHWTRAP_MANUAL;
-- mt7530_write(priv, MT7530_MHWTRAP, val);
-+ val = mt7530_read(priv, MT753X_MTRAP);
-+ val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS;
-+ val |= MT7530_CHG_TRAP;
-+ mt7530_write(priv, MT753X_MTRAP, val);
-
-- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ)
-+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
- mt7530_pll_setup(priv);
-
- mt753x_trap_frames(priv);
-@@ -2591,7 +2592,7 @@ mt7531_setup(struct dsa_switch *ds)
- }
-
- /* Waiting for MT7530 got to stable */
-- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP);
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP);
- ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
- 20, 1000000);
- if (ret < 0) {
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -495,32 +495,30 @@ enum mt7531_clk_skew {
- MT7531_CLK_SKEW_REVERSE = 3,
- };
-
--/* Register for hw trap status */
--#define MT7530_HWTRAP 0x7800
--#define HWTRAP_XTAL_MASK (BIT(10) | BIT(9))
--#define HWTRAP_XTAL_25MHZ (BIT(10) | BIT(9))
--#define HWTRAP_XTAL_40MHZ (BIT(10))
--#define HWTRAP_XTAL_20MHZ (BIT(9))
-+/* Register for trap status */
-+#define MT753X_TRAP 0x7800
-+#define MT7530_XTAL_MASK (BIT(10) | BIT(9))
-+#define MT7530_XTAL_25MHZ (BIT(10) | BIT(9))
-+#define MT7530_XTAL_40MHZ BIT(10)
-+#define MT7530_XTAL_20MHZ BIT(9)
-+#define MT7531_XTAL25 BIT(7)
-
--#define MT7531_HWTRAP 0x7800
--#define HWTRAP_XTAL_FSEL_MASK BIT(7)
--#define HWTRAP_XTAL_FSEL_25MHZ BIT(7)
--#define HWTRAP_XTAL_FSEL_40MHZ 0
--/* Unique fields of (M)HWSTRAP for MT7531 */
--#define XTAL_FSEL_S 7
--#define XTAL_FSEL_M BIT(7)
--#define PHY_EN BIT(6)
--#define CHG_STRAP BIT(8)
-+/* Register for trap modification */
-+#define MT753X_MTRAP 0x7804
-+#define MT7530_P5_PHY0_SEL BIT(20)
-+#define MT7530_CHG_TRAP BIT(16)
-+#define MT7530_P5_MAC_SEL BIT(13)
-+#define MT7530_P6_DIS BIT(8)
-+#define MT7530_P5_RGMII_MODE BIT(7)
-+#define MT7530_P5_DIS BIT(6)
-+#define MT7530_PHY_INDIRECT_ACCESS BIT(5)
-+#define MT7531_CHG_STRAP BIT(8)
-+#define MT7531_PHY_EN BIT(6)
-
--/* Register for hw trap modification */
--#define MT7530_MHWTRAP 0x7804
--#define MHWTRAP_PHY0_SEL BIT(20)
--#define MHWTRAP_MANUAL BIT(16)
--#define MHWTRAP_P5_MAC_SEL BIT(13)
--#define MHWTRAP_P6_DIS BIT(8)
--#define MHWTRAP_P5_RGMII_MODE BIT(7)
--#define MHWTRAP_P5_DIS BIT(6)
--#define MHWTRAP_PHY_ACCESS BIT(5)
-+enum mt7531_xtal_fsel {
-+ MT7531_XTAL_FSEL_25MHZ,
-+ MT7531_XTAL_FSEL_40MHZ,
-+};
-
- /* Register for TOP signal control */
- #define MT7530_TOP_SIG_CTRL 0x7808
diff --git a/target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch b/target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch
deleted file mode 100644
index cfc38f81d0..0000000000
--- a/target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 2982f395c9a513b168f1e685588f70013cba2f5f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:14 +0300
-Subject: [PATCH 07/15] net: dsa: mt7530: move MT753X_MTRAP operations for
- MT7530
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-On MT7530, the media-independent interfaces of port 5 and 6 are controlled
-by the MT7530_P5_DIS and MT7530_P6_DIS bits of the hardware trap. Deal with
-these bits only when the relevant port is being enabled or disabled. This
-ensures that these ports will be disabled when they are not in use.
-
-Do not set MT7530_CHG_TRAP on mt7530_setup_port5() as that's already being
-done on mt7530_setup().
-
-Instead of globally setting MT7530_P5_MAC_SEL, clear it, then set it only
-on the appropriate case.
-
-If PHY muxing is detected, clear MT7530_P5_DIS before calling
-mt7530_setup_port5().
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 38 +++++++++++++++++++++++++++-----------
- 1 file changed, 27 insertions(+), 11 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -887,8 +887,7 @@ static void mt7530_setup_port5(struct ds
-
- val = mt7530_read(priv, MT753X_MTRAP);
-
-- val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS;
-- val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL;
-+ val &= ~MT7530_P5_PHY0_SEL & ~MT7530_P5_MAC_SEL & ~MT7530_P5_RGMII_MODE;
-
- switch (priv->p5_mode) {
- /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
-@@ -898,15 +897,13 @@ static void mt7530_setup_port5(struct ds
-
- /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
- case MUX_PHY_P4:
-- val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS;
--
- /* Setup the MAC by default for the cpu port */
- mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
- break;
-
- /* GMAC5: P5 -> SoC MAC or external PHY */
- default:
-- val &= ~MT7530_P5_DIS;
-+ val |= MT7530_P5_MAC_SEL;
- break;
- }
-
-@@ -1200,6 +1197,14 @@ mt7530_port_enable(struct dsa_switch *ds
-
- mutex_unlock(&priv->reg_mutex);
-
-+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
-+ return 0;
-+
-+ if (port == 5)
-+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS);
-+ else if (port == 6)
-+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P6_DIS);
-+
- return 0;
- }
-
-@@ -1218,6 +1223,14 @@ mt7530_port_disable(struct dsa_switch *d
- PCR_MATRIX_CLR);
-
- mutex_unlock(&priv->reg_mutex);
-+
-+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
-+ return;
-+
-+ if (port == 5)
-+ mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS);
-+ else if (port == 6)
-+ mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS);
- }
-
- static int
-@@ -2406,11 +2419,11 @@ mt7530_setup(struct dsa_switch *ds)
- mt7530_rmw(priv, MT7530_TRGMII_RD(i),
- RD_TAP_MASK, RD_TAP(16));
-
-- /* Enable port 6 */
-- val = mt7530_read(priv, MT753X_MTRAP);
-- val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS;
-- val |= MT7530_CHG_TRAP;
-- mt7530_write(priv, MT753X_MTRAP, val);
-+ /* Allow modifying the trap and directly access PHY registers via the
-+ * MDIO bus the switch is on.
-+ */
-+ mt7530_rmw(priv, MT753X_MTRAP, MT7530_CHG_TRAP |
-+ MT7530_PHY_INDIRECT_ACCESS, MT7530_CHG_TRAP);
-
- if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
- mt7530_pll_setup(priv);
-@@ -2493,8 +2506,11 @@ mt7530_setup(struct dsa_switch *ds)
- break;
- }
-
-- if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4)
-+ if (priv->p5_mode == MUX_PHY_P0 ||
-+ priv->p5_mode == MUX_PHY_P4) {
-+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS);
- mt7530_setup_port5(ds, interface);
-+ }
- }
-
- #ifdef CONFIG_GPIOLIB
diff --git a/target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch b/target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch
deleted file mode 100644
index 178ac8022f..0000000000
--- a/target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 1f5669efca65564c7533704917f79003c6b36c9c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:15 +0300
-Subject: [PATCH 08/15] net: dsa: mt7530: return mt7530_setup_mdio &
- mt7531_setup_common on error
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The mt7530_setup_mdio() and mt7531_setup_common() functions should be
-checked for errors. Return if the functions return a non-zero value.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2672,7 +2672,9 @@ mt7531_setup(struct dsa_switch *ds)
- 0);
- }
-
-- mt7531_setup_common(ds);
-+ ret = mt7531_setup_common(ds);
-+ if (ret)
-+ return ret;
-
- /* Setup VLAN ID 0 for VLAN-unaware bridges */
- ret = mt7530_setup_vlan0(priv);
-@@ -3031,6 +3033,8 @@ mt753x_setup(struct dsa_switch *ds)
- ret = mt7530_setup_mdio(priv);
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
-+ if (ret)
-+ return ret;
-
- /* Initialise the PCS devices */
- for (i = 0; i < priv->ds->num_ports; i++) {
diff --git a/target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch b/target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch
deleted file mode 100644
index af8edf5a42..0000000000
--- a/target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 6cc2d4ccd77509df74b7b8ef46bbc6ba0a571318 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:16 +0300
-Subject: [PATCH 09/15] net: dsa: mt7530: define MAC speed capabilities per
- switch model
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-With the support of the MT7988 SoC switch, the MAC speed capabilities
-defined on mt753x_phylink_get_caps() won't apply to all switch models
-anymore. Move them to more appropriate locations instead of overwriting
-config->mac_capabilities.
-
-Remove the comment on mt753x_phylink_get_caps() as it's become invalid with
-the support of MT7531 and MT7988 SoC switch.
-
-Add break to case 6 of mt7988_mac_port_get_caps() to be explicit.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2690,6 +2690,8 @@ mt7531_setup(struct dsa_switch *ds)
- static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
- {
-+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
-+
- switch (port) {
- /* Ports which are connected to switch PHYs. There is no MII pinout. */
- case 0 ... 4:
-@@ -2721,6 +2723,8 @@ static void mt7531_mac_port_get_caps(str
- {
- struct mt7530_priv *priv = ds->priv;
-
-+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
-+
- switch (port) {
- /* Ports which are connected to switch PHYs. There is no MII pinout. */
- case 0 ... 4:
-@@ -2760,14 +2764,17 @@ static void mt7988_mac_port_get_caps(str
- case 0 ... 3:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
-+
-+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
- break;
-
- /* Port 6 is connected to SoC's XGMII MAC. There is no MII pinout. */
- case 6:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
-- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-- MAC_10000FD;
-+
-+ config->mac_capabilities |= MAC_10000FD;
-+ break;
- }
- }
-
-@@ -2937,9 +2944,7 @@ static void mt753x_phylink_get_caps(stru
- {
- struct mt7530_priv *priv = ds->priv;
-
-- /* This switch only supports full-duplex at 1Gbps */
-- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-- MAC_10 | MAC_100 | MAC_1000FD;
-+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
-
- /* This driver does not make use of the speed, duplex, pause or the
- * advertisement in its mac_config, so it is safe to mark this driver
diff --git a/target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch b/target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch
deleted file mode 100644
index 3825952dc3..0000000000
--- a/target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From dd0f15fc877c10567699190bce0f55e96f4ad6b5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:17 +0300
-Subject: [PATCH 10/15] net: dsa: mt7530: get rid of function sanity check
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Get rid of checking whether functions are filled properly. priv->info which
-is an mt753x_info structure is filled and checked for before this check.
-It's unnecessary checking whether it's filled properly.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 7 -------
- 1 file changed, 7 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3235,13 +3235,6 @@ mt7530_probe_common(struct mt7530_priv *
- if (!priv->info)
- return -EINVAL;
-
-- /* Sanity check if these required device operations are filled
-- * properly.
-- */
-- if (!priv->info->sw_setup || !priv->info->phy_read ||
-- !priv->info->phy_write || !priv->info->mac_port_get_caps)
-- return -EINVAL;
--
- priv->id = priv->info->id;
- priv->dev = dev;
- priv->ds->priv = priv;
diff --git a/target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch b/target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch
deleted file mode 100644
index df47458014..0000000000
--- a/target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 2dff9759602b069f97ccc939e15a47ca051b2983 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:18 +0300
-Subject: [PATCH 11/15] net: dsa: mt7530: refactor MT7530_PMEEECR_P()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MT7530_PMEEECR_P() register is on MT7530, MT7531, and the switch on the
-MT7988 SoC. Rename the definition for them to MT753X_PMEEECR_P(). Use the
-FIELD_PREP and FIELD_GET macros. Rename GET_LPI_THRESH() and
-SET_LPI_THRESH() to LPI_THRESH_GET() and LPI_THRESH_SET().
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 8 ++++----
- drivers/net/dsa/mt7530.h | 13 +++++++------
- 2 files changed, 11 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3062,10 +3062,10 @@ static int mt753x_get_mac_eee(struct dsa
- struct ethtool_eee *e)
- {
- struct mt7530_priv *priv = ds->priv;
-- u32 eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port));
-+ u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
-
- e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN);
-- e->tx_lpi_timer = GET_LPI_THRESH(eeecr);
-+ e->tx_lpi_timer = LPI_THRESH_GET(eeecr);
-
- return 0;
- }
-@@ -3079,11 +3079,11 @@ static int mt753x_set_mac_eee(struct dsa
- if (e->tx_lpi_timer > 0xFFF)
- return -EINVAL;
-
-- set = SET_LPI_THRESH(e->tx_lpi_timer);
-+ set = LPI_THRESH_SET(e->tx_lpi_timer);
- if (!e->tx_lpi_enabled)
- /* Force LPI Mode without a delay */
- set |= LPI_MODE_EN;
-- mt7530_rmw(priv, MT7530_PMEEECR_P(port), mask, set);
-+ mt7530_rmw(priv, MT753X_PMEEECR_P(port), mask, set);
-
- return 0;
- }
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -364,13 +364,14 @@ enum mt7530_vlan_port_acc_frm {
- PMCR_FORCE_SPEED_100 | \
- PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-
--#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100)
--#define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24)
--#define WAKEUP_TIME_100(x) (((x) & 0xFF) << 16)
-+#define MT753X_PMEEECR_P(x) (0x3004 + (x) * 0x100)
-+#define WAKEUP_TIME_1000_MASK GENMASK(31, 24)
-+#define WAKEUP_TIME_1000(x) FIELD_PREP(WAKEUP_TIME_1000_MASK, x)
-+#define WAKEUP_TIME_100_MASK GENMASK(23, 16)
-+#define WAKEUP_TIME_100(x) FIELD_PREP(WAKEUP_TIME_100_MASK, x)
- #define LPI_THRESH_MASK GENMASK(15, 4)
--#define LPI_THRESH_SHT 4
--#define SET_LPI_THRESH(x) (((x) << LPI_THRESH_SHT) & LPI_THRESH_MASK)
--#define GET_LPI_THRESH(x) (((x) & LPI_THRESH_MASK) >> LPI_THRESH_SHT)
-+#define LPI_THRESH_GET(x) FIELD_GET(LPI_THRESH_MASK, x)
-+#define LPI_THRESH_SET(x) FIELD_PREP(LPI_THRESH_MASK, x)
- #define LPI_MODE_EN BIT(0)
-
- #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100)
diff --git a/target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch b/target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch
deleted file mode 100644
index 7ce2d4c04e..0000000000
--- a/target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 21d67c2fabfe40baf33202d3287b67b6c16f8382 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:19 +0300
-Subject: [PATCH 12/15] net: dsa: mt7530: get rid of mac_port_validate member
- of mt753x_info
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The mac_port_validate member of the mt753x_info structure is not being
-used, remove it. Improve the member description section in the process.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.h | 10 +++-------
- 1 file changed, 3 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -743,13 +743,12 @@ struct mt753x_pcs {
-
- /* struct mt753x_info - This is the main data structure for holding the specific
- * part for each supported device
-+ * @id: Holding the identifier to a switch model
-+ * @pcs_ops: Holding the pointer to the MAC PCS operations structure
- * @sw_setup: Holding the handler to a device initialization
- * @phy_read: Holding the way reading PHY port
- * @phy_write: Holding the way writing PHY port
-- * @phy_mode_supported: Check if the PHY type is being supported on a certain
-- * port
-- * @mac_port_validate: Holding the way to set addition validate type for a
-- * certan MAC port
-+ * @mac_port_get_caps: Holding the handler that provides MAC capabilities
- * @mac_port_config: Holding the way setting up the PHY attribute to a
- * certain MAC port
- */
-@@ -763,9 +762,6 @@ struct mt753x_info {
- int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
- void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
- struct phylink_config *config);
-- void (*mac_port_validate)(struct dsa_switch *ds, int port,
-- phy_interface_t interface,
-- unsigned long *supported);
- void (*mac_port_config)(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface);
diff --git a/target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch b/target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch
deleted file mode 100644
index e9512421c2..0000000000
--- a/target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 6efc8ae3eb0363328f479191a0cf0dc12a16e090 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:20 +0300
-Subject: [PATCH 13/15] net: dsa: mt7530: use priv->ds->num_ports instead of
- MT7530_NUM_PORTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use priv->ds->num_ports on all for loops which configure the switch
-registers. In the future, the value of MT7530_NUM_PORTS will depend on
-priv->id. Therefore, this change prepares the subdriver for a simpler
-implementation.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1418,7 +1418,7 @@ mt7530_port_set_vlan_unaware(struct dsa_
- mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
- G0_PORT_VID_DEF);
-
-- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ for (i = 0; i < priv->ds->num_ports; i++) {
- if (dsa_is_user_port(ds, i) &&
- dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
- all_user_ports_removed = false;
-@@ -2433,7 +2433,7 @@ mt7530_setup(struct dsa_switch *ds)
- /* Enable and reset MIB counters */
- mt7530_mib_reset(ds);
-
-- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ for (i = 0; i < priv->ds->num_ports; i++) {
- /* Clear link settings and enable force mode to force link down
- * on all ports until they're enabled later.
- */
-@@ -2544,7 +2544,7 @@ mt7531_setup_common(struct dsa_switch *d
- mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK |
- UNU_FFP_MASK);
-
-- for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ for (i = 0; i < priv->ds->num_ports; i++) {
- /* Clear link settings and enable force mode to force link down
- * on all ports until they're enabled later.
- */
-@@ -2631,7 +2631,7 @@ mt7531_setup(struct dsa_switch *ds)
- priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
-
- /* Force link down on all ports before internal reset */
-- for (i = 0; i < MT7530_NUM_PORTS; i++)
-+ for (i = 0; i < priv->ds->num_ports; i++)
- mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK);
-
- /* Reset the switch through internal reset */
diff --git a/target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch b/target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch
deleted file mode 100644
index 3b3330bdce..0000000000
--- a/target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 4794c12e3aefe05dd0063c2b6b0101854b143bac Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:21 +0300
-Subject: [PATCH 14/15] net: dsa: mt7530: do not pass port variable to
- mt7531_rgmii_setup()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The mt7531_rgmii_setup() function does not use the port variable, do not
-pass the variable to it.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2790,7 +2790,7 @@ mt7530_mac_config(struct dsa_switch *ds,
- mt7530_setup_port6(priv->ds, interface);
- }
-
--static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
-+static void mt7531_rgmii_setup(struct mt7530_priv *priv,
- phy_interface_t interface,
- struct phy_device *phydev)
- {
-@@ -2841,7 +2841,7 @@ mt7531_mac_config(struct dsa_switch *ds,
- if (phy_interface_mode_is_rgmii(interface)) {
- dp = dsa_to_port(ds, port);
- phydev = dp->slave->phydev;
-- mt7531_rgmii_setup(priv, port, interface, phydev);
-+ mt7531_rgmii_setup(priv, interface, phydev);
- }
- }
-
diff --git a/target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch b/target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch
deleted file mode 100644
index 6d28e5b5f9..0000000000
--- a/target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c45832fe783f468aaaace09ae95a30cbf0acf724 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Mon, 22 Apr 2024 10:15:22 +0300
-Subject: [PATCH 15/15] net: dsa: mt7530: explain exposing MDIO bus of MT7531AE
- better
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on MT7531AE.
-Therefore, the GPIO 11-12 pins are set to function as MDC and MDIO to
-expose the MDIO bus of the switch. Replace the comment with a better
-explanation.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2640,7 +2640,10 @@ mt7531_setup(struct dsa_switch *ds)
- if (!priv->p5_sgmii) {
- mt7531_pll_setup(priv);
- } else {
-- /* Let ds->slave_mii_bus be able to access external phy. */
-+ /* Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on
-+ * MT7531AE. Set the GPIO 11-12 pins to function as MDC and MDIO
-+ * to expose the MDIO bus of the switch.
-+ */
- mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK,
- MT7531_EXT_P_MDC_11);
- mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK,
diff --git a/target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch b/target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch
deleted file mode 100644
index 29079e03c5..0000000000
--- a/target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 16e6592cd5c5bd74d8890973489f60176c692614 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sun, 28 Apr 2024 12:19:58 +0300
-Subject: [PATCH] net: dsa: mt7530: do not set MT7530_P5_DIS when PHY muxing is
- being used
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-DSA initalises the ds->num_ports amount of ports in
-dsa_switch_touch_ports(). When the PHY muxing feature is in use, port 5
-won't be defined in the device tree. Because of this, the type member of
-the dsa_port structure for this port will be assigned DSA_PORT_TYPE_UNUSED.
-The dsa_port_setup() function calls ds->ops->port_disable() when the port
-type is DSA_PORT_TYPE_UNUSED.
-
-The MT7530_P5_DIS bit is unset in mt7530_setup() when PHY muxing is being
-used. mt7530_port_disable() which is assigned to ds->ops->port_disable() is
-called afterwards. Currently, mt7530_port_disable() sets MT7530_P5_DIS
-which breaks network connectivity when PHY muxing is being used.
-
-Therefore, do not set MT7530_P5_DIS when PHY muxing is being used.
-
-Fixes: 377174c5760c ("net: dsa: mt7530: move MT753X_MTRAP operations for MT7530")
-Reported-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240428-for-netnext-mt7530-do-not-disable-port5-when-phy-muxing-v2-1-bb7c37d293f8@arinc9.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1227,7 +1227,8 @@ mt7530_port_disable(struct dsa_switch *d
- if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
- return;
-
-- if (port == 5)
-+ /* Do not set MT7530_P5_DIS when port 5 is being used for PHY muxing. */
-+ if (port == 5 && priv->p5_mode == GMAC5)
- mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS);
- else if (port == 6)
- mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS);
diff --git a/target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch b/target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch
deleted file mode 100644
index 69bbb8e229..0000000000
--- a/target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From d8dcf5bd6d0eace9f7c1daa14b63b3925b09d033 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 30 Apr 2024 08:01:33 +0300
-Subject: [PATCH] net: dsa: mt7530: detect PHY muxing when PHY is defined on
- switch MDIO bus
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently, the MT7530 DSA subdriver configures the MT7530 switch to provide
-direct access to switch PHYs, meaning, the switch PHYs listen on the MDIO
-bus the switch listens on. The PHY muxing feature makes use of this.
-
-This is problematic as the PHY may be attached before the switch is
-initialised, in which case, the PHY will fail to be attached.
-
-Since commit 91374ba537bd ("net: dsa: mt7530: support OF-based registration
-of switch MDIO bus"), we can describe the switch PHYs on the MDIO bus of
-the switch on the device tree. Extend the check to detect PHY muxing when
-the PHY is defined on the MDIO bus of the switch on the device tree.
-
-When the PHY is described this way, the switch will be initialised first,
-then the switch MDIO bus will be registered. Only after these steps, the
-PHY will be attached.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20240430-b4-for-netnext-mt7530-use-switch-mdio-bus-for-phy-muxing-v2-1-9104d886d0db@arinc9.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2489,7 +2489,8 @@ mt7530_setup(struct dsa_switch *ds)
- if (!phy_node)
- continue;
-
-- if (phy_node->parent == priv->dev->of_node->parent) {
-+ if (phy_node->parent == priv->dev->of_node->parent ||
-+ phy_node->parent->parent == priv->dev->of_node) {
- ret = of_get_phy_mode(mac_np, &interface);
- if (ret && ret != -ENODEV) {
- of_node_put(mac_np);
diff --git a/target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch b/target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch
deleted file mode 100644
index 3cf98acc85..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch
+++ /dev/null
@@ -1,1724 +0,0 @@
-From 70479a40954cf353e87a486997a3477108c75aa9 Mon Sep 17 00:00:00 2001
-From: Frank <Frank.Sae@motor-comm.com>
-Date: Fri, 28 Oct 2022 17:26:21 +0800
-Subject: [PATCH] net: phy: Add driver for Motorcomm yt8521 gigabit ethernet
- phy
-
-Add a driver for the motorcomm yt8521 gigabit ethernet phy. We have verified
- the driver on StarFive VisionFive development board, which is developed by
- Shanghai StarFive Technology Co., Ltd.. On the board, yt8521 gigabit ethernet
- phy works in utp mode, RGMII interface, supports 1000M/100M/10M speeds, and
- wol(magic package).
-
-Signed-off-by: Frank <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS | 1 +
- drivers/net/phy/Kconfig | 2 +-
- drivers/net/phy/motorcomm.c | 1635 ++++++++++++++++++++++++++++++++++-
- 3 files changed, 1635 insertions(+), 3 deletions(-)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -13971,6 +13971,7 @@ F: include/uapi/linux/meye.h
-
- MOTORCOMM PHY DRIVER
- M: Peter Geis <pgwipeout@gmail.com>
-+M: Frank <Frank.Sae@motor-comm.com>
- L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/phy/motorcomm.c
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -257,7 +257,7 @@ config MOTORCOMM_PHY
- tristate "Motorcomm PHYs"
- help
- Enables support for Motorcomm network PHYs.
-- Currently supports the YT8511 gigabit PHY.
-+ Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs.
-
- config NATIONAL_PHY
- tristate "National Semiconductor PHYs"
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1,15 +1,106 @@
- // SPDX-License-Identifier: GPL-2.0+
- /*
-- * Driver for Motorcomm PHYs
-+ * Motorcomm 8511/8521 PHY driver.
- *
- * Author: Peter Geis <pgwipeout@gmail.com>
-+ * Author: Frank <Frank.Sae@motor-comm.com>
- */
-
-+#include <linux/etherdevice.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/phy.h>
-
- #define PHY_ID_YT8511 0x0000010a
-+#define PHY_ID_YT8521 0x0000011A
-+
-+/* YT8521 Register Overview
-+ * UTP Register space | FIBER Register space
-+ * ------------------------------------------------------------
-+ * | UTP MII | FIBER MII |
-+ * | UTP MMD | |
-+ * | UTP Extended | FIBER Extended |
-+ * ------------------------------------------------------------
-+ * | Common Extended |
-+ * ------------------------------------------------------------
-+ */
-+
-+/* 0x10 ~ 0x15 , 0x1E and 0x1F are common MII registers of yt phy */
-+
-+/* Specific Function Control Register */
-+#define YTPHY_SPECIFIC_FUNCTION_CONTROL_REG 0x10
-+
-+/* 2b00 Manual MDI configuration
-+ * 2b01 Manual MDIX configuration
-+ * 2b10 Reserved
-+ * 2b11 Enable automatic crossover for all modes *default*
-+ */
-+#define YTPHY_SFCR_MDI_CROSSOVER_MODE_MASK (BIT(6) | BIT(5))
-+#define YTPHY_SFCR_CROSSOVER_EN BIT(3)
-+#define YTPHY_SFCR_SQE_TEST_EN BIT(2)
-+#define YTPHY_SFCR_POLARITY_REVERSAL_EN BIT(1)
-+#define YTPHY_SFCR_JABBER_DIS BIT(0)
-+
-+/* Specific Status Register */
-+#define YTPHY_SPECIFIC_STATUS_REG 0x11
-+#define YTPHY_SSR_SPEED_MODE_OFFSET 14
-+
-+#define YTPHY_SSR_SPEED_MODE_MASK (BIT(15) | BIT(14))
-+#define YTPHY_SSR_SPEED_10M 0x0
-+#define YTPHY_SSR_SPEED_100M 0x1
-+#define YTPHY_SSR_SPEED_1000M 0x2
-+#define YTPHY_SSR_DUPLEX_OFFSET 13
-+#define YTPHY_SSR_DUPLEX BIT(13)
-+#define YTPHY_SSR_PAGE_RECEIVED BIT(12)
-+#define YTPHY_SSR_SPEED_DUPLEX_RESOLVED BIT(11)
-+#define YTPHY_SSR_LINK BIT(10)
-+#define YTPHY_SSR_MDIX_CROSSOVER BIT(6)
-+#define YTPHY_SSR_DOWNGRADE BIT(5)
-+#define YTPHY_SSR_TRANSMIT_PAUSE BIT(3)
-+#define YTPHY_SSR_RECEIVE_PAUSE BIT(2)
-+#define YTPHY_SSR_POLARITY BIT(1)
-+#define YTPHY_SSR_JABBER BIT(0)
-+
-+/* Interrupt enable Register */
-+#define YTPHY_INTERRUPT_ENABLE_REG 0x12
-+#define YTPHY_IER_WOL BIT(6)
-+
-+/* Interrupt Status Register */
-+#define YTPHY_INTERRUPT_STATUS_REG 0x13
-+#define YTPHY_ISR_AUTONEG_ERR BIT(15)
-+#define YTPHY_ISR_SPEED_CHANGED BIT(14)
-+#define YTPHY_ISR_DUPLEX_CHANGED BIT(13)
-+#define YTPHY_ISR_PAGE_RECEIVED BIT(12)
-+#define YTPHY_ISR_LINK_FAILED BIT(11)
-+#define YTPHY_ISR_LINK_SUCCESSED BIT(10)
-+#define YTPHY_ISR_WOL BIT(6)
-+#define YTPHY_ISR_WIRESPEED_DOWNGRADE BIT(5)
-+#define YTPHY_ISR_SERDES_LINK_FAILED BIT(3)
-+#define YTPHY_ISR_SERDES_LINK_SUCCESSED BIT(2)
-+#define YTPHY_ISR_POLARITY_CHANGED BIT(1)
-+#define YTPHY_ISR_JABBER_HAPPENED BIT(0)
-+
-+/* Speed Auto Downgrade Control Register */
-+#define YTPHY_SPEED_AUTO_DOWNGRADE_CONTROL_REG 0x14
-+#define YTPHY_SADCR_SPEED_DOWNGRADE_EN BIT(5)
-+
-+/* If these bits are set to 3, the PHY attempts five times ( 3(set value) +
-+ * additional 2) before downgrading, default 0x3
-+ */
-+#define YTPHY_SADCR_SPEED_RETRY_LIMIT (0x3 << 2)
-+
-+/* Rx Error Counter Register */
-+#define YTPHY_RX_ERROR_COUNTER_REG 0x15
-+
-+/* Extended Register's Address Offset Register */
-+#define YTPHY_PAGE_SELECT 0x1E
-+
-+/* Extended Register's Data Register */
-+#define YTPHY_PAGE_DATA 0x1F
-+
-+/* FIBER Auto-Negotiation link partner ability */
-+#define YTPHY_FLPA_PAUSE (0x3 << 7)
-+#define YTPHY_FLPA_ASYM_PAUSE (0x2 << 7)
-
- #define YT8511_PAGE_SELECT 0x1e
- #define YT8511_PAGE 0x1f
-@@ -38,6 +129,352 @@
- #define YT8511_DELAY_FE_TX_EN (0xf << 12)
- #define YT8511_DELAY_FE_TX_DIS (0x2 << 12)
-
-+/* Extended register is different from MMD Register and MII Register.
-+ * We can use ytphy_read_ext/ytphy_write_ext/ytphy_modify_ext function to
-+ * operate extended register.
-+ * Extended Register start
-+ */
-+
-+/* Phy gmii clock gating Register */
-+#define YT8521_CLOCK_GATING_REG 0xC
-+#define YT8521_CGR_RX_CLK_EN BIT(12)
-+
-+#define YT8521_EXTREG_SLEEP_CONTROL1_REG 0x27
-+#define YT8521_ESC1R_SLEEP_SW BIT(15)
-+#define YT8521_ESC1R_PLLON_SLP BIT(14)
-+
-+/* Phy fiber Link timer cfg2 Register */
-+#define YT8521_LINK_TIMER_CFG2_REG 0xA5
-+#define YT8521_LTCR_EN_AUTOSEN BIT(15)
-+
-+/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers
-+ * of yt8521 phy. There is no need to switch reg space when operating these
-+ * registers.
-+ */
-+
-+#define YT8521_REG_SPACE_SELECT_REG 0xA000
-+#define YT8521_RSSR_SPACE_MASK BIT(1)
-+#define YT8521_RSSR_FIBER_SPACE (0x1 << 1)
-+#define YT8521_RSSR_UTP_SPACE (0x0 << 1)
-+#define YT8521_RSSR_TO_BE_ARBITRATED (0xFF)
-+
-+#define YT8521_CHIP_CONFIG_REG 0xA001
-+#define YT8521_CCR_SW_RST BIT(15)
-+
-+#define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0))
-+#define YT8521_CCR_MODE_UTP_TO_RGMII 0
-+#define YT8521_CCR_MODE_FIBER_TO_RGMII 1
-+#define YT8521_CCR_MODE_UTP_FIBER_TO_RGMII 2
-+#define YT8521_CCR_MODE_UTP_TO_SGMII 3
-+#define YT8521_CCR_MODE_SGPHY_TO_RGMAC 4
-+#define YT8521_CCR_MODE_SGMAC_TO_RGPHY 5
-+#define YT8521_CCR_MODE_UTP_TO_FIBER_AUTO 6
-+#define YT8521_CCR_MODE_UTP_TO_FIBER_FORCE 7
-+
-+/* 3 phy polling modes,poll mode combines utp and fiber mode*/
-+#define YT8521_MODE_FIBER 0x1
-+#define YT8521_MODE_UTP 0x2
-+#define YT8521_MODE_POLL 0x3
-+
-+#define YT8521_RGMII_CONFIG1_REG 0xA003
-+
-+/* TX Gig-E Delay is bits 3:0, default 0x1
-+ * TX Fast-E Delay is bits 7:4, default 0xf
-+ * RX Delay is bits 13:10, default 0x0
-+ * Delay = 150ps * N
-+ * On = 2250ps, off = 0ps
-+ */
-+#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10)
-+#define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
-+#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
-+#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4)
-+#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
-+#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
-+#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0)
-+#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
-+#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
-+
-+#define YTPHY_MISC_CONFIG_REG 0xA006
-+#define YTPHY_MCR_FIBER_SPEED_MASK BIT(0)
-+#define YTPHY_MCR_FIBER_1000BX (0x1 << 0)
-+#define YTPHY_MCR_FIBER_100FX (0x0 << 0)
-+
-+/* WOL MAC ADDR: MACADDR2(highest), MACADDR1(middle), MACADDR0(lowest) */
-+#define YTPHY_WOL_MACADDR2_REG 0xA007
-+#define YTPHY_WOL_MACADDR1_REG 0xA008
-+#define YTPHY_WOL_MACADDR0_REG 0xA009
-+
-+#define YTPHY_WOL_CONFIG_REG 0xA00A
-+#define YTPHY_WCR_INTR_SEL BIT(6)
-+#define YTPHY_WCR_ENABLE BIT(3)
-+
-+/* 2b00 84ms
-+ * 2b01 168ms *default*
-+ * 2b10 336ms
-+ * 2b11 672ms
-+ */
-+#define YTPHY_WCR_PULSE_WIDTH_MASK (BIT(2) | BIT(1))
-+#define YTPHY_WCR_PULSE_WIDTH_672MS (BIT(2) | BIT(1))
-+
-+/* 1b0 Interrupt and WOL events is level triggered and active LOW *default*
-+ * 1b1 Interrupt and WOL events is pulse triggered and active LOW
-+ */
-+#define YTPHY_WCR_TYPE_PULSE BIT(0)
-+
-+/* Extended Register end */
-+
-+struct yt8521_priv {
-+ /* combo_advertising is used for case of YT8521 in combo mode,
-+ * this means that yt8521 may work in utp or fiber mode which depends
-+ * on which media is connected (YT8521_RSSR_TO_BE_ARBITRATED).
-+ */
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(combo_advertising);
-+
-+ /* YT8521_MODE_FIBER / YT8521_MODE_UTP / YT8521_MODE_POLL*/
-+ u8 polling_mode;
-+ u8 strap_mode; /* 8 working modes */
-+ /* current reg page of yt8521 phy:
-+ * YT8521_RSSR_UTP_SPACE
-+ * YT8521_RSSR_FIBER_SPACE
-+ * YT8521_RSSR_TO_BE_ARBITRATED
-+ */
-+ u8 reg_page;
-+};
-+
-+/**
-+ * ytphy_read_ext() - read a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to read
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns the value of regnum reg or negative error code
-+ */
-+static int ytphy_read_ext(struct phy_device *phydev, u16 regnum)
-+{
-+ int ret;
-+
-+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __phy_read(phydev, YTPHY_PAGE_DATA);
-+}
-+
-+/**
-+ * ytphy_read_ext_with_lock() - read a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to read
-+ *
-+ * returns the value of regnum reg or negative error code
-+ */
-+static int ytphy_read_ext_with_lock(struct phy_device *phydev, u16 regnum)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_read_ext(phydev, regnum);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
-+/**
-+ * ytphy_write_ext() - write a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_write_ext(struct phy_device *phydev, u16 regnum, u16 val)
-+{
-+ int ret;
-+
-+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __phy_write(phydev, YTPHY_PAGE_DATA, val);
-+}
-+
-+/**
-+ * ytphy_write_ext_with_lock() - write a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_write_ext_with_lock(struct phy_device *phydev, u16 regnum,
-+ u16 val)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_write_ext(phydev, regnum, val);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
-+/**
-+ * ytphy_modify_ext() - bits modify a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's extended register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
-+ u16 set)
-+{
-+ int ret;
-+
-+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ return __phy_modify(phydev, YTPHY_PAGE_DATA, mask, set);
-+}
-+
-+/**
-+ * ytphy_modify_ext_with_lock() - bits modify a PHY's extended register
-+ * @phydev: a pointer to a &struct phy_device
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's extended register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ *
-+ * returns 0 or negative error code
-+ */
-+static int ytphy_modify_ext_with_lock(struct phy_device *phydev, u16 regnum,
-+ u16 mask, u16 set)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_modify_ext(phydev, regnum, mask, set);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
-+/**
-+ * ytphy_get_wol() - report whether wake-on-lan is enabled
-+ * @phydev: a pointer to a &struct phy_device
-+ * @wol: a pointer to a &struct ethtool_wolinfo
-+ *
-+ * NOTE: YTPHY_WOL_CONFIG_REG is common ext reg.
-+ */
-+static void ytphy_get_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ int wol_config;
-+
-+ wol->supported = WAKE_MAGIC;
-+ wol->wolopts = 0;
-+
-+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG);
-+ if (wol_config < 0)
-+ return;
-+
-+ if (wol_config & YTPHY_WCR_ENABLE)
-+ wol->wolopts |= WAKE_MAGIC;
-+}
-+
-+/**
-+ * ytphy_set_wol() - turn wake-on-lan on or off
-+ * @phydev: a pointer to a &struct phy_device
-+ * @wol: a pointer to a &struct ethtool_wolinfo
-+ *
-+ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG
-+ * and YTPHY_WOL_MACADDR0_REG are common ext reg. The
-+ * YTPHY_INTERRUPT_ENABLE_REG of UTP is special, fiber also use this register.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
-+{
-+ struct net_device *p_attached_dev;
-+ const u16 mac_addr_reg[] = {
-+ YTPHY_WOL_MACADDR2_REG,
-+ YTPHY_WOL_MACADDR1_REG,
-+ YTPHY_WOL_MACADDR0_REG,
-+ };
-+ const u8 *mac_addr;
-+ int old_page;
-+ int ret = 0;
-+ u16 mask;
-+ u16 val;
-+ u8 i;
-+
-+ if (wol->wolopts & WAKE_MAGIC) {
-+ p_attached_dev = phydev->attached_dev;
-+ if (!p_attached_dev)
-+ return -ENODEV;
-+
-+ mac_addr = (const u8 *)p_attached_dev->dev_addr;
-+ if (!is_valid_ether_addr(mac_addr))
-+ return -EINVAL;
-+
-+ /* lock mdio bus then switch to utp reg space */
-+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* Store the device address for the magic packet */
-+ for (i = 0; i < 3; i++) {
-+ ret = ytphy_write_ext(phydev, mac_addr_reg[i],
-+ ((mac_addr[i * 2] << 8)) |
-+ (mac_addr[i * 2 + 1]));
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+ /* Enable WOL feature */
-+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL;
-+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS;
-+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ /* Enable WOL interrupt */
-+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0,
-+ YTPHY_IER_WOL);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ } else {
-+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* Disable WOL feature */
-+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0);
-+
-+ /* Disable WOL interrupt */
-+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG,
-+ YTPHY_IER_WOL, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
- static int yt8511_read_page(struct phy_device *phydev)
- {
- return __phy_read(phydev, YT8511_PAGE_SELECT);
-@@ -111,6 +548,1181 @@ err_restore_page:
- return phy_restore_page(phydev, oldpage, ret);
- }
-
-+/**
-+ * yt8521_read_page() - read reg page
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns current reg space of yt8521 (YT8521_RSSR_FIBER_SPACE/
-+ * YT8521_RSSR_UTP_SPACE) or negative errno code
-+ */
-+static int yt8521_read_page(struct phy_device *phydev)
-+{
-+ int old_page;
-+
-+ old_page = ytphy_read_ext(phydev, YT8521_REG_SPACE_SELECT_REG);
-+ if (old_page < 0)
-+ return old_page;
-+
-+ if ((old_page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE)
-+ return YT8521_RSSR_FIBER_SPACE;
-+
-+ return YT8521_RSSR_UTP_SPACE;
-+};
-+
-+/**
-+ * yt8521_write_page() - write reg page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to write.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_write_page(struct phy_device *phydev, int page)
-+{
-+ int mask = YT8521_RSSR_SPACE_MASK;
-+ int set;
-+
-+ if ((page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE)
-+ set = YT8521_RSSR_FIBER_SPACE;
-+ else
-+ set = YT8521_RSSR_UTP_SPACE;
-+
-+ return ytphy_modify_ext(phydev, YT8521_REG_SPACE_SELECT_REG, mask, set);
-+};
-+
-+/**
-+ * yt8521_probe() - read chip config then set suitable polling_mode
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct yt8521_priv *priv;
-+ int chip_config;
-+ int ret;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ phydev->priv = priv;
-+
-+ chip_config = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
-+ if (chip_config < 0)
-+ return chip_config;
-+
-+ priv->strap_mode = chip_config & YT8521_CCR_MODE_SEL_MASK;
-+ switch (priv->strap_mode) {
-+ case YT8521_CCR_MODE_FIBER_TO_RGMII:
-+ case YT8521_CCR_MODE_SGPHY_TO_RGMAC:
-+ case YT8521_CCR_MODE_SGMAC_TO_RGPHY:
-+ priv->polling_mode = YT8521_MODE_FIBER;
-+ priv->reg_page = YT8521_RSSR_FIBER_SPACE;
-+ phydev->port = PORT_FIBRE;
-+ break;
-+ case YT8521_CCR_MODE_UTP_FIBER_TO_RGMII:
-+ case YT8521_CCR_MODE_UTP_TO_FIBER_AUTO:
-+ case YT8521_CCR_MODE_UTP_TO_FIBER_FORCE:
-+ priv->polling_mode = YT8521_MODE_POLL;
-+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED;
-+ phydev->port = PORT_NONE;
-+ break;
-+ case YT8521_CCR_MODE_UTP_TO_SGMII:
-+ case YT8521_CCR_MODE_UTP_TO_RGMII:
-+ priv->polling_mode = YT8521_MODE_UTP;
-+ priv->reg_page = YT8521_RSSR_UTP_SPACE;
-+ phydev->port = PORT_TP;
-+ break;
-+ }
-+ /* set default reg space */
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = ytphy_write_ext_with_lock(phydev,
-+ YT8521_REG_SPACE_SELECT_REG,
-+ priv->reg_page);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_read_lpa(struct phy_device *phydev)
-+{
-+ int lpa, lpagb;
-+
-+ if (phydev->autoneg == AUTONEG_ENABLE) {
-+ if (!phydev->autoneg_complete) {
-+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
-+ 0);
-+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
-+ return 0;
-+ }
-+
-+ if (phydev->is_gigabit_capable) {
-+ lpagb = __phy_read(phydev, MII_STAT1000);
-+ if (lpagb < 0)
-+ return lpagb;
-+
-+ if (lpagb & LPA_1000MSFAIL) {
-+ int adv = __phy_read(phydev, MII_CTRL1000);
-+
-+ if (adv < 0)
-+ return adv;
-+
-+ if (adv & CTL1000_ENABLE_MASTER)
-+ phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n");
-+ else
-+ phydev_err(phydev, "Master/Slave resolution failed\n");
-+ return -ENOLINK;
-+ }
-+
-+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
-+ lpagb);
-+ }
-+
-+ lpa = __phy_read(phydev, MII_LPA);
-+ if (lpa < 0)
-+ return lpa;
-+
-+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
-+ } else {
-+ linkmode_zero(phydev->lp_advertising);
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_adjust_status() - update speed and duplex to phydev. when in fiber
-+ * mode, adjust speed and duplex.
-+ * @phydev: a pointer to a &struct phy_device
-+ * @status: yt8521 status read from YTPHY_SPECIFIC_STATUS_REG
-+ * @is_utp: false(yt8521 work in fiber mode) or true(yt8521 work in utp mode)
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0
-+ */
-+static int yt8521_adjust_status(struct phy_device *phydev, int status,
-+ bool is_utp)
-+{
-+ int speed_mode, duplex;
-+ int speed;
-+ int err;
-+ int lpa;
-+
-+ if (is_utp)
-+ duplex = (status & YTPHY_SSR_DUPLEX) >> YTPHY_SSR_DUPLEX_OFFSET;
-+ else
-+ duplex = DUPLEX_FULL; /* for fiber, it always DUPLEX_FULL */
-+
-+ speed_mode = (status & YTPHY_SSR_SPEED_MODE_MASK) >>
-+ YTPHY_SSR_SPEED_MODE_OFFSET;
-+
-+ switch (speed_mode) {
-+ case YTPHY_SSR_SPEED_10M:
-+ if (is_utp)
-+ speed = SPEED_10;
-+ else
-+ /* for fiber, it will never run here, default to
-+ * SPEED_UNKNOWN
-+ */
-+ speed = SPEED_UNKNOWN;
-+ break;
-+ case YTPHY_SSR_SPEED_100M:
-+ speed = SPEED_100;
-+ break;
-+ case YTPHY_SSR_SPEED_1000M:
-+ speed = SPEED_1000;
-+ break;
-+ default:
-+ speed = SPEED_UNKNOWN;
-+ break;
-+ }
-+
-+ phydev->speed = speed;
-+ phydev->duplex = duplex;
-+
-+ if (is_utp) {
-+ err = ytphy_utp_read_lpa(phydev);
-+ if (err < 0)
-+ return err;
-+
-+ phy_resolve_aneg_pause(phydev);
-+ } else {
-+ lpa = __phy_read(phydev, MII_LPA);
-+ if (lpa < 0)
-+ return lpa;
-+
-+ /* only support 1000baseX Full */
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-+ phydev->lp_advertising, lpa & LPA_1000XFULL);
-+
-+ if (!(lpa & YTPHY_FLPA_PAUSE)) {
-+ phydev->pause = 0;
-+ phydev->asym_pause = 0;
-+ } else if ((lpa & YTPHY_FLPA_ASYM_PAUSE)) {
-+ phydev->pause = 1;
-+ phydev->asym_pause = 1;
-+ } else {
-+ phydev->pause = 1;
-+ phydev->asym_pause = 0;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_read_status_paged() - determines the speed and duplex of one page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 1 (utp or fiber link),0 (no link) or negative errno code
-+ */
-+static int yt8521_read_status_paged(struct phy_device *phydev, int page)
-+{
-+ int fiber_latch_val;
-+ int fiber_curr_val;
-+ int old_page;
-+ int ret = 0;
-+ int status;
-+ int link;
-+
-+ linkmode_zero(phydev->lp_advertising);
-+ phydev->duplex = DUPLEX_UNKNOWN;
-+ phydev->speed = SPEED_UNKNOWN;
-+ phydev->asym_pause = 0;
-+ phydev->pause = 0;
-+
-+ /* YT8521 has two reg space (utp/fiber) for linkup with utp/fiber
-+ * respectively. but for utp/fiber combo mode, reg space should be
-+ * arbitrated based on media priority. by default, utp takes
-+ * priority. reg space should be properly set before read
-+ * YTPHY_SPECIFIC_STATUS_REG.
-+ */
-+
-+ page &= YT8521_RSSR_SPACE_MASK;
-+ old_page = phy_select_page(phydev, page);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* Read YTPHY_SPECIFIC_STATUS_REG, which indicates the speed and duplex
-+ * of the PHY is actually using.
-+ */
-+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ status = ret;
-+ link = !!(status & YTPHY_SSR_LINK);
-+
-+ /* When PHY is in fiber mode, speed transferred from 1000Mbps to
-+ * 100Mbps,there is not link down from YTPHY_SPECIFIC_STATUS_REG, so
-+ * we need check MII_BMSR to identify such case.
-+ */
-+ if (page == YT8521_RSSR_FIBER_SPACE) {
-+ ret = __phy_read(phydev, MII_BMSR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ fiber_latch_val = ret;
-+ ret = __phy_read(phydev, MII_BMSR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ fiber_curr_val = ret;
-+ if (link && fiber_latch_val != fiber_curr_val) {
-+ link = 0;
-+ phydev_info(phydev,
-+ "%s, fiber link down detect, latch = %04x, curr = %04x\n",
-+ __func__, fiber_latch_val, fiber_curr_val);
-+ }
-+ } else {
-+ /* Read autonegotiation status */
-+ ret = __phy_read(phydev, MII_BMSR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ phydev->autoneg_complete = ret & BMSR_ANEGCOMPLETE ? 1 : 0;
-+ }
-+
-+ if (link) {
-+ if (page == YT8521_RSSR_UTP_SPACE)
-+ yt8521_adjust_status(phydev, status, true);
-+ else
-+ yt8521_adjust_status(phydev, status, false);
-+ }
-+ return phy_restore_page(phydev, old_page, link);
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_read_status() - determines the negotiated speed and duplex
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_read_status(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int link_fiber = 0;
-+ int link_utp;
-+ int link;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ link = yt8521_read_status_paged(phydev, priv->reg_page);
-+ if (link < 0)
-+ return link;
-+ } else {
-+ /* when page is YT8521_RSSR_TO_BE_ARBITRATED, arbitration is
-+ * needed. by default, utp is higher priority.
-+ */
-+
-+ link_utp = yt8521_read_status_paged(phydev,
-+ YT8521_RSSR_UTP_SPACE);
-+ if (link_utp < 0)
-+ return link_utp;
-+
-+ if (!link_utp) {
-+ link_fiber = yt8521_read_status_paged(phydev,
-+ YT8521_RSSR_FIBER_SPACE);
-+ if (link_fiber < 0)
-+ return link_fiber;
-+ }
-+
-+ link = link_utp || link_fiber;
-+ }
-+
-+ if (link) {
-+ if (phydev->link == 0) {
-+ /* arbitrate reg space based on linkup media type. */
-+ if (priv->polling_mode == YT8521_MODE_POLL &&
-+ priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) {
-+ if (link_fiber)
-+ priv->reg_page =
-+ YT8521_RSSR_FIBER_SPACE;
-+ else
-+ priv->reg_page = YT8521_RSSR_UTP_SPACE;
-+
-+ ret = ytphy_write_ext_with_lock(phydev,
-+ YT8521_REG_SPACE_SELECT_REG,
-+ priv->reg_page);
-+ if (ret < 0)
-+ return ret;
-+
-+ phydev->port = link_fiber ? PORT_FIBRE : PORT_TP;
-+
-+ phydev_info(phydev, "%s, link up, media: %s\n",
-+ __func__,
-+ (phydev->port == PORT_TP) ?
-+ "UTP" : "Fiber");
-+ }
-+ }
-+ phydev->link = 1;
-+ } else {
-+ if (phydev->link == 1) {
-+ phydev_info(phydev, "%s, link down, media: %s\n",
-+ __func__, (phydev->port == PORT_TP) ?
-+ "UTP" : "Fiber");
-+
-+ /* When in YT8521_MODE_POLL mode, need prepare for next
-+ * arbitration.
-+ */
-+ if (priv->polling_mode == YT8521_MODE_POLL) {
-+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED;
-+ phydev->port = PORT_NONE;
-+ }
-+ }
-+
-+ phydev->link = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_modify_bmcr_paged - bits modify a PHY's BMCR register of one page
-+ * @phydev: the phy_device struct
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to operate
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's BMCR register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space
-+ * has MII_BMCR. poll mode combines utp and faber,so need do both.
-+ * If it is reset, it will wait for completion.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_modify_bmcr_paged(struct phy_device *phydev, int page,
-+ u16 mask, u16 set)
-+{
-+ int max_cnt = 500; /* the max wait time of reset ~ 500 ms */
-+ int old_page;
-+ int ret = 0;
-+
-+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ ret = __phy_modify(phydev, MII_BMCR, mask, set);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ /* If it is reset, need to wait for the reset to complete */
-+ if (set == BMCR_RESET) {
-+ while (max_cnt--) {
-+ usleep_range(1000, 1100);
-+ ret = __phy_read(phydev, MII_BMCR);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ if (!(ret & BMCR_RESET))
-+ return phy_restore_page(phydev, old_page, 0);
-+ }
-+ }
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_modify_utp_fiber_bmcr - bits modify a PHY's BMCR register
-+ * @phydev: the phy_device struct
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * NOTE: Convenience function which allows a PHY's BMCR register to be
-+ * modified as new register value = (old register value & ~mask) | set.
-+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space
-+ * has MII_BMCR. poll mode combines utp and faber,so need do both.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_modify_utp_fiber_bmcr(struct phy_device *phydev, u16 mask,
-+ u16 set)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = yt8521_modify_bmcr_paged(phydev, priv->reg_page, mask,
-+ set);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_UTP_SPACE,
-+ mask, set);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_FIBER_SPACE,
-+ mask, set);
-+ if (ret < 0)
-+ return ret;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_soft_reset() - called to issue a PHY software reset
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_soft_reset(struct phy_device *phydev)
-+{
-+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_RESET);
-+}
-+
-+/**
-+ * yt8521_suspend() - suspend the hardware
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_suspend(struct phy_device *phydev)
-+{
-+ int wol_config;
-+
-+ /* YTPHY_WOL_CONFIG_REG is common ext reg */
-+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG);
-+ if (wol_config < 0)
-+ return wol_config;
-+
-+ /* if wol enable, do nothing */
-+ if (wol_config & YTPHY_WCR_ENABLE)
-+ return 0;
-+
-+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_PDOWN);
-+}
-+
-+/**
-+ * yt8521_resume() - resume the hardware
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_resume(struct phy_device *phydev)
-+{
-+ int ret;
-+ int wol_config;
-+
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG);
-+ if (wol_config < 0)
-+ return wol_config;
-+
-+ /* if wol enable, do nothing */
-+ if (wol_config & YTPHY_WCR_ENABLE)
-+ return 0;
-+
-+ return yt8521_modify_utp_fiber_bmcr(phydev, BMCR_PDOWN, 0);
-+}
-+
-+/**
-+ * yt8521_config_init() - called to initialize the PHY
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_config_init(struct phy_device *phydev)
-+{
-+ int old_page;
-+ int ret = 0;
-+ u16 val;
-+
-+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val |= YT8521_RC1R_RX_DELAY_DIS;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val |= YT8521_RC1R_RX_DELAY_EN;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val |= YT8521_RC1R_RX_DELAY_DIS;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val |= YT8521_RC1R_RX_DELAY_EN;
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ break;
-+ default: /* do not support other modes */
-+ ret = -EOPNOTSUPP;
-+ goto err_restore_page;
-+ }
-+
-+ /* set rgmii delay mode */
-+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII) {
-+ ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG,
-+ (YT8521_RC1R_RX_DELAY_MASK |
-+ YT8521_RC1R_FE_TX_DELAY_MASK |
-+ YT8521_RC1R_GE_TX_DELAY_MASK),
-+ val);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ /* enable RXC clock when no wire plug */
-+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
-+ YT8521_CGR_RX_CLK_EN, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_prepare_fiber_features() - A small helper function that setup
-+ * fiber's features.
-+ * @phydev: a pointer to a &struct phy_device
-+ * @dst: a pointer to store fiber's features
-+ */
-+static void yt8521_prepare_fiber_features(struct phy_device *phydev,
-+ unsigned long *dst)
-+{
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, dst);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, dst);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, dst);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, dst);
-+}
-+
-+/**
-+ * yt8521_fiber_setup_forced - configures/forces speed from @phydev
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_fiber_setup_forced(struct phy_device *phydev)
-+{
-+ u16 val;
-+ int ret;
-+
-+ if (phydev->speed == SPEED_1000)
-+ val = YTPHY_MCR_FIBER_1000BX;
-+ else if (phydev->speed == SPEED_100)
-+ val = YTPHY_MCR_FIBER_100FX;
-+ else
-+ return -EINVAL;
-+
-+ ret = __phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* disable Fiber auto sensing */
-+ ret = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG,
-+ YT8521_LTCR_EN_AUTOSEN, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ytphy_modify_ext(phydev, YTPHY_MISC_CONFIG_REG,
-+ YTPHY_MCR_FIBER_SPEED_MASK, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ return ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
-+ YT8521_CCR_SW_RST, 0);
-+}
-+
-+/**
-+ * ytphy_check_and_restart_aneg - Enable and restart auto-negotiation
-+ * @phydev: target phy_device struct
-+ * @restart: whether aneg restart is requested
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_check_and_restart_aneg(struct phy_device *phydev, bool restart)
-+{
-+ int ret;
-+
-+ if (!restart) {
-+ /* Advertisement hasn't changed, but maybe aneg was never on to
-+ * begin with? Or maybe phy was isolated?
-+ */
-+ ret = __phy_read(phydev, MII_BMCR);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE))
-+ restart = true;
-+ }
-+ /* Enable and Restart Autonegotiation
-+ * Don't isolate the PHY if we're negotiating
-+ */
-+ if (restart)
-+ return __phy_modify(phydev, MII_BMCR, BMCR_ISOLATE,
-+ BMCR_ANENABLE | BMCR_ANRESTART);
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_fiber_config_aneg - restart auto-negotiation or write
-+ * YTPHY_MISC_CONFIG_REG.
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE:The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_fiber_config_aneg(struct phy_device *phydev)
-+{
-+ int err, changed = 0;
-+ int bmcr;
-+ u16 adv;
-+
-+ if (phydev->autoneg != AUTONEG_ENABLE)
-+ return yt8521_fiber_setup_forced(phydev);
-+
-+ /* enable Fiber auto sensing */
-+ err = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG,
-+ 0, YT8521_LTCR_EN_AUTOSEN);
-+ if (err < 0)
-+ return err;
-+
-+ err = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
-+ YT8521_CCR_SW_RST, 0);
-+ if (err < 0)
-+ return err;
-+
-+ bmcr = __phy_read(phydev, MII_BMCR);
-+ if (bmcr < 0)
-+ return bmcr;
-+
-+ /* When it is coming from fiber forced mode, add bmcr power down
-+ * and power up to let aneg work fine.
-+ */
-+ if (!(bmcr & BMCR_ANENABLE)) {
-+ __phy_modify(phydev, MII_BMCR, 0, BMCR_PDOWN);
-+ usleep_range(1000, 1100);
-+ __phy_modify(phydev, MII_BMCR, BMCR_PDOWN, 0);
-+ }
-+
-+ adv = linkmode_adv_to_mii_adv_x(phydev->advertising,
-+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
-+
-+ /* Setup fiber advertisement */
-+ err = __phy_modify_changed(phydev, MII_ADVERTISE,
-+ ADVERTISE_1000XHALF | ADVERTISE_1000XFULL |
-+ ADVERTISE_1000XPAUSE |
-+ ADVERTISE_1000XPSE_ASYM,
-+ adv);
-+ if (err < 0)
-+ return err;
-+
-+ if (err > 0)
-+ changed = 1;
-+
-+ return ytphy_check_and_restart_aneg(phydev, changed);
-+}
-+
-+/**
-+ * ytphy_setup_master_slave
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE: The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_setup_master_slave(struct phy_device *phydev)
-+{
-+ u16 ctl = 0;
-+
-+ if (!phydev->is_gigabit_capable)
-+ return 0;
-+
-+ switch (phydev->master_slave_set) {
-+ case MASTER_SLAVE_CFG_MASTER_PREFERRED:
-+ ctl |= CTL1000_PREFER_MASTER;
-+ break;
-+ case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
-+ break;
-+ case MASTER_SLAVE_CFG_MASTER_FORCE:
-+ ctl |= CTL1000_AS_MASTER;
-+ fallthrough;
-+ case MASTER_SLAVE_CFG_SLAVE_FORCE:
-+ ctl |= CTL1000_ENABLE_MASTER;
-+ break;
-+ case MASTER_SLAVE_CFG_UNKNOWN:
-+ case MASTER_SLAVE_CFG_UNSUPPORTED:
-+ return 0;
-+ default:
-+ phydev_warn(phydev, "Unsupported Master/Slave mode\n");
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return __phy_modify_changed(phydev, MII_CTRL1000,
-+ (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER |
-+ CTL1000_PREFER_MASTER), ctl);
-+}
-+
-+/**
-+ * ytphy_utp_config_advert - sanitize and advertise auto-negotiation parameters
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE: Writes MII_ADVERTISE with the appropriate values,
-+ * after sanitizing the values to make sure we only advertise
-+ * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
-+ * hasn't changed, and > 0 if it has changed.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_config_advert(struct phy_device *phydev)
-+{
-+ int err, bmsr, changed = 0;
-+ u32 adv;
-+
-+ /* Only allow advertising what this PHY supports */
-+ linkmode_and(phydev->advertising, phydev->advertising,
-+ phydev->supported);
-+
-+ adv = linkmode_adv_to_mii_adv_t(phydev->advertising);
-+
-+ /* Setup standard advertisement */
-+ err = __phy_modify_changed(phydev, MII_ADVERTISE,
-+ ADVERTISE_ALL | ADVERTISE_100BASE4 |
-+ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
-+ adv);
-+ if (err < 0)
-+ return err;
-+ if (err > 0)
-+ changed = 1;
-+
-+ bmsr = __phy_read(phydev, MII_BMSR);
-+ if (bmsr < 0)
-+ return bmsr;
-+
-+ /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all
-+ * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a
-+ * logical 1.
-+ */
-+ if (!(bmsr & BMSR_ESTATEN))
-+ return changed;
-+
-+ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
-+
-+ err = __phy_modify_changed(phydev, MII_CTRL1000,
-+ ADVERTISE_1000FULL | ADVERTISE_1000HALF,
-+ adv);
-+ if (err < 0)
-+ return err;
-+ if (err > 0)
-+ changed = 1;
-+
-+ return changed;
-+}
-+
-+/**
-+ * ytphy_utp_config_aneg - restart auto-negotiation or write BMCR
-+ * @phydev: target phy_device struct
-+ * @changed: whether autoneg is requested
-+ *
-+ * NOTE: If auto-negotiation is enabled, we configure the
-+ * advertising, and then restart auto-negotiation. If it is not
-+ * enabled, then we write the BMCR.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_config_aneg(struct phy_device *phydev, bool changed)
-+{
-+ int err;
-+ u16 ctl;
-+
-+ err = ytphy_setup_master_slave(phydev);
-+ if (err < 0)
-+ return err;
-+ else if (err)
-+ changed = true;
-+
-+ if (phydev->autoneg != AUTONEG_ENABLE) {
-+ /* configures/forces speed/duplex from @phydev */
-+
-+ ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
-+
-+ return __phy_modify(phydev, MII_BMCR, ~(BMCR_LOOPBACK |
-+ BMCR_ISOLATE | BMCR_PDOWN), ctl);
-+ }
-+
-+ err = ytphy_utp_config_advert(phydev);
-+ if (err < 0) /* error */
-+ return err;
-+ else if (err)
-+ changed = true;
-+
-+ return ytphy_check_and_restart_aneg(phydev, changed);
-+}
-+
-+/**
-+ * yt8521_config_aneg_paged() - switch reg space then call genphy_config_aneg
-+ * of one page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_config_aneg_paged(struct phy_device *phydev, int page)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(fiber_supported);
-+ struct yt8521_priv *priv = phydev->priv;
-+ int old_page;
-+ int ret = 0;
-+
-+ page &= YT8521_RSSR_SPACE_MASK;
-+
-+ old_page = phy_select_page(phydev, page);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED,
-+ * phydev->advertising should be updated.
-+ */
-+ if (priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) {
-+ linkmode_zero(fiber_supported);
-+ yt8521_prepare_fiber_features(phydev, fiber_supported);
-+
-+ /* prepare fiber_supported, then setup advertising. */
-+ if (page == YT8521_RSSR_FIBER_SPACE) {
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ fiber_supported);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ fiber_supported);
-+ linkmode_and(phydev->advertising,
-+ priv->combo_advertising, fiber_supported);
-+ } else {
-+ /* ETHTOOL_LINK_MODE_Autoneg_BIT is also used in utp */
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+ fiber_supported);
-+ linkmode_andnot(phydev->advertising,
-+ priv->combo_advertising,
-+ fiber_supported);
-+ }
-+ }
-+
-+ if (page == YT8521_RSSR_FIBER_SPACE)
-+ ret = yt8521_fiber_config_aneg(phydev);
-+ else
-+ ret = ytphy_utp_config_aneg(phydev, false);
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_config_aneg() - change reg space then call yt8521_config_aneg_paged
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_config_aneg(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = yt8521_config_aneg_paged(phydev, priv->reg_page);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED,
-+ * phydev->advertising need to be saved at first run.
-+ * Because it contains the advertising which supported by both
-+ * mac and yt8521(utp and fiber).
-+ */
-+ if (linkmode_empty(priv->combo_advertising)) {
-+ linkmode_copy(priv->combo_advertising,
-+ phydev->advertising);
-+ }
-+
-+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_UTP_SPACE);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_FIBER_SPACE);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* we don't known which will be link, so restore
-+ * phydev->advertising as default value.
-+ */
-+ linkmode_copy(phydev->advertising, priv->combo_advertising);
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_aneg_done_paged() - determines the auto negotiation result of one
-+ * page.
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 0(no link)or 1(fiber or utp link) or negative errno code
-+ */
-+static int yt8521_aneg_done_paged(struct phy_device *phydev, int page)
-+{
-+ int old_page;
-+ int ret = 0;
-+ int link;
-+
-+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG);
-+ if (ret < 0)
-+ goto err_restore_page;
-+
-+ link = !!(ret & YTPHY_SSR_LINK);
-+ ret = link;
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_aneg_done() - determines the auto negotiation result
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0(no link)or 1(fiber or utp link) or negative errno code
-+ */
-+static int yt8521_aneg_done(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int link_fiber = 0;
-+ int link_utp;
-+ int link;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ link = yt8521_aneg_done_paged(phydev, priv->reg_page);
-+ } else {
-+ link_utp = yt8521_aneg_done_paged(phydev,
-+ YT8521_RSSR_UTP_SPACE);
-+ if (link_utp < 0)
-+ return link_utp;
-+
-+ if (!link_utp) {
-+ link_fiber = yt8521_aneg_done_paged(phydev,
-+ YT8521_RSSR_FIBER_SPACE);
-+ if (link_fiber < 0)
-+ return link_fiber;
-+ }
-+ link = link_fiber || link_utp;
-+ phydev_info(phydev, "%s, link_fiber: %d, link_utp: %d\n",
-+ __func__, link_fiber, link_utp);
-+ }
-+
-+ return link;
-+}
-+
-+/**
-+ * ytphy_utp_read_abilities - read PHY abilities from Clause 22 registers
-+ * @phydev: target phy_device struct
-+ *
-+ * NOTE: Reads the PHY's abilities and populates
-+ * phydev->supported accordingly.
-+ * The caller must have taken the MDIO bus lock.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int ytphy_utp_read_abilities(struct phy_device *phydev)
-+{
-+ int val;
-+
-+ linkmode_set_bit_array(phy_basic_ports_array,
-+ ARRAY_SIZE(phy_basic_ports_array),
-+ phydev->supported);
-+
-+ val = __phy_read(phydev, MII_BMSR);
-+ if (val < 0)
-+ return val;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported,
-+ val & BMSR_ANEGCAPABLE);
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported,
-+ val & BMSR_100FULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported,
-+ val & BMSR_100HALF);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported,
-+ val & BMSR_10FULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported,
-+ val & BMSR_10HALF);
-+
-+ if (val & BMSR_ESTATEN) {
-+ val = __phy_read(phydev, MII_ESTATUS);
-+ if (val < 0)
-+ return val;
-+
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-+ phydev->supported, val & ESTATUS_1000_TFULL);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-+ phydev->supported, val & ESTATUS_1000_THALF);
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
-+ phydev->supported, val & ESTATUS_1000_XFULL);
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8521_get_features_paged() - read supported link modes for one page
-+ * @phydev: a pointer to a &struct phy_device
-+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to
-+ * operate.
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_get_features_paged(struct phy_device *phydev, int page)
-+{
-+ int old_page;
-+ int ret = 0;
-+
-+ page &= YT8521_RSSR_SPACE_MASK;
-+ old_page = phy_select_page(phydev, page);
-+ if (old_page < 0)
-+ goto err_restore_page;
-+
-+ if (page == YT8521_RSSR_FIBER_SPACE) {
-+ linkmode_zero(phydev->supported);
-+ yt8521_prepare_fiber_features(phydev, phydev->supported);
-+ } else {
-+ ret = ytphy_utp_read_abilities(phydev);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-+
-+err_restore_page:
-+ return phy_restore_page(phydev, old_page, ret);
-+}
-+
-+/**
-+ * yt8521_get_features - switch reg space then call yt8521_get_features_paged
-+ * @phydev: target phy_device struct
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8521_get_features(struct phy_device *phydev)
-+{
-+ struct yt8521_priv *priv = phydev->priv;
-+ int ret;
-+
-+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) {
-+ ret = yt8521_get_features_paged(phydev, priv->reg_page);
-+ } else {
-+ ret = yt8521_get_features_paged(phydev,
-+ YT8521_RSSR_UTP_SPACE);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* add fiber's features to phydev->supported */
-+ yt8521_prepare_fiber_features(phydev, phydev->supported);
-+ }
-+ return ret;
-+}
-+
- static struct phy_driver motorcomm_phy_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(PHY_ID_YT8511),
-@@ -121,16 +1733,35 @@ static struct phy_driver motorcomm_phy_d
- .read_page = yt8511_read_page,
- .write_page = yt8511_write_page,
- },
-+ {
-+ PHY_ID_MATCH_EXACT(PHY_ID_YT8521),
-+ .name = "YT8521 Gigabit Ethernet",
-+ .get_features = yt8521_get_features,
-+ .probe = yt8521_probe,
-+ .read_page = yt8521_read_page,
-+ .write_page = yt8521_write_page,
-+ .get_wol = ytphy_get_wol,
-+ .set_wol = ytphy_set_wol,
-+ .config_aneg = yt8521_config_aneg,
-+ .aneg_done = yt8521_aneg_done,
-+ .config_init = yt8521_config_init,
-+ .read_status = yt8521_read_status,
-+ .soft_reset = yt8521_soft_reset,
-+ .suspend = yt8521_suspend,
-+ .resume = yt8521_resume,
-+ },
- };
-
- module_phy_driver(motorcomm_phy_drvs);
-
--MODULE_DESCRIPTION("Motorcomm PHY driver");
-+MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver");
- MODULE_AUTHOR("Peter Geis");
-+MODULE_AUTHOR("Frank");
- MODULE_LICENSE("GPL");
-
- static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
-+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
- { /* sentinal */ }
- };
-
diff --git a/target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch b/target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch
deleted file mode 100644
index cce71c8d84..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 4e0243e7128c9b25ea2739136076a95d6adaba5e Mon Sep 17 00:00:00 2001
-From: Frank <Frank.Sae@motor-comm.com>
-Date: Fri, 4 Nov 2022 16:44:41 +0800
-Subject: [PATCH] net: phy: fix yt8521 duplicated argument to & or |
-
-cocci warnings: (new ones prefixed by >>)
->> drivers/net/phy/motorcomm.c:1122:8-35: duplicated argument to & or |
- drivers/net/phy/motorcomm.c:1126:8-35: duplicated argument to & or |
- drivers/net/phy/motorcomm.c:1130:8-34: duplicated argument to & or |
- drivers/net/phy/motorcomm.c:1134:8-34: duplicated argument to & or |
-
- The second YT8521_RC1R_GE_TX_DELAY_xx should be YT8521_RC1R_FE_TX_DELAY_xx.
-
-Fixes: 70479a40954c ("net: phy: Add driver for Motorcomm yt8521 gigabit ethernet phy")
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Julia Lawall <julia.lawall@lip6.fr>
-Signed-off-by: Frank <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1119,19 +1119,19 @@ static int yt8521_config_init(struct phy
-
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_RGMII:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
- val |= YT8521_RC1R_RX_DELAY_DIS;
- break;
- case PHY_INTERFACE_MODE_RGMII_RXID:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS;
-+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
- val |= YT8521_RC1R_RX_DELAY_EN;
- break;
- case PHY_INTERFACE_MODE_RGMII_TXID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
- val |= YT8521_RC1R_RX_DELAY_DIS;
- break;
- case PHY_INTERFACE_MODE_RGMII_ID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN;
-+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
- val |= YT8521_RC1R_RX_DELAY_EN;
- break;
- case PHY_INTERFACE_MODE_SGMII:
diff --git a/target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch b/target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch
deleted file mode 100644
index d22cc69425..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-From 813abcd98fb1b2cccf850cdfa092a4bfc50b2363 Mon Sep 17 00:00:00 2001
-From: Frank <Frank.Sae@motor-comm.com>
-Date: Tue, 22 Nov 2022 16:42:32 +0800
-Subject: [PATCH] net: phy: add Motorcomm YT8531S phy id.
-
-We added patch for motorcomm.c to support YT8531S. This patch has
-been tested on AM335x platform which has one YT8531S interface
-card and passed all test cases.
-The tested cases indluding: YT8531S UTP function with support of
-10M/100M/1000M; YT8531S Fiber function with support of 100M/1000M;
-and YT8531S Combo function that supports auto detection of media type.
-
-Since most functions of YT8531S are similar to YT8521 and we reuse some
-codes for YT8521 in the patch file.
-
-Signed-off-by: Frank <Frank.Sae@motor-comm.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 2 +-
- drivers/net/phy/motorcomm.c | 52 +++++++++++++++++++++++++++++++++----
- 2 files changed, 48 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -257,7 +257,7 @@ config MOTORCOMM_PHY
- tristate "Motorcomm PHYs"
- help
- Enables support for Motorcomm network PHYs.
-- Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs.
-+ Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs.
-
- config NATIONAL_PHY
- tristate "National Semiconductor PHYs"
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0+
- /*
-- * Motorcomm 8511/8521 PHY driver.
-+ * Motorcomm 8511/8521/8531S PHY driver.
- *
- * Author: Peter Geis <pgwipeout@gmail.com>
- * Author: Frank <Frank.Sae@motor-comm.com>
-@@ -12,9 +12,10 @@
- #include <linux/phy.h>
-
- #define PHY_ID_YT8511 0x0000010a
--#define PHY_ID_YT8521 0x0000011A
-+#define PHY_ID_YT8521 0x0000011A
-+#define PHY_ID_YT8531S 0x4F51E91A
-
--/* YT8521 Register Overview
-+/* YT8521/YT8531S Register Overview
- * UTP Register space | FIBER Register space
- * ------------------------------------------------------------
- * | UTP MII | FIBER MII |
-@@ -147,7 +148,7 @@
- #define YT8521_LINK_TIMER_CFG2_REG 0xA5
- #define YT8521_LTCR_EN_AUTOSEN BIT(15)
-
--/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers
-+/* 0xA000, 0xA001, 0xA003, 0xA006 ~ 0xA00A and 0xA012 are common ext registers
- * of yt8521 phy. There is no need to switch reg space when operating these
- * registers.
- */
-@@ -221,6 +222,9 @@
- */
- #define YTPHY_WCR_TYPE_PULSE BIT(0)
-
-+#define YT8531S_SYNCE_CFG_REG 0xA012
-+#define YT8531S_SCR_SYNCE_ENABLE BIT(6)
-+
- /* Extended Register end */
-
- struct yt8521_priv {
-@@ -648,6 +652,26 @@ static int yt8521_probe(struct phy_devic
- }
-
- /**
-+ * yt8531s_probe() - read chip config then set suitable polling_mode
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * returns 0 or negative errno code
-+ */
-+static int yt8531s_probe(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Disable SyncE clock output by default */
-+ ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG,
-+ YT8531S_SCR_SYNCE_ENABLE, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* same as yt8521_probe */
-+ return yt8521_probe(phydev);
-+}
-+
-+/**
- * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -1750,11 +1774,28 @@ static struct phy_driver motorcomm_phy_d
- .suspend = yt8521_suspend,
- .resume = yt8521_resume,
- },
-+ {
-+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S),
-+ .name = "YT8531S Gigabit Ethernet",
-+ .get_features = yt8521_get_features,
-+ .probe = yt8531s_probe,
-+ .read_page = yt8521_read_page,
-+ .write_page = yt8521_write_page,
-+ .get_wol = ytphy_get_wol,
-+ .set_wol = ytphy_set_wol,
-+ .config_aneg = yt8521_config_aneg,
-+ .aneg_done = yt8521_aneg_done,
-+ .config_init = yt8521_config_init,
-+ .read_status = yt8521_read_status,
-+ .soft_reset = yt8521_soft_reset,
-+ .suspend = yt8521_suspend,
-+ .resume = yt8521_resume,
-+ },
- };
-
- module_phy_driver(motorcomm_phy_drvs);
-
--MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver");
-+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver");
- MODULE_AUTHOR("Peter Geis");
- MODULE_AUTHOR("Frank");
- MODULE_LICENSE("GPL");
-@@ -1762,6 +1803,7 @@ MODULE_LICENSE("GPL");
- static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
-+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
- { /* sentinal */ }
- };
-
diff --git a/target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch b/target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch
deleted file mode 100644
index 94fc32aadb..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 4104a713204d62aca482eebb0c6226d82a0721eb Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Sat, 28 Jan 2023 14:35:57 +0800
-Subject: [PATCH] net: phy: fix the spelling problem of Sentinel
-
-CHECK: 'sentinal' may be misspelled - perhaps 'sentinel'?
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20230128063558.5850-1-Frank.Sae@motor-comm.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/motorcomm.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1804,7 +1804,7 @@ static const struct mdio_device_id __may
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
-- { /* sentinal */ }
-+ { /* sentinel */ }
- };
-
- MODULE_DEVICE_TABLE(mdio, motorcomm_tbl);
diff --git a/target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch b/target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch
deleted file mode 100644
index 076fa82d26..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 3c1dc22162d673d595855d24f95200ed2643f88f Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Sat, 28 Jan 2023 14:35:58 +0800
-Subject: [PATCH] net: phy: motorcomm: change the phy id of yt8521 and yt8531s
- to lowercase
-
-The phy id is usually defined in lower case.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20230128063558.5850-2-Frank.Sae@motor-comm.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/motorcomm.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -12,8 +12,8 @@
- #include <linux/phy.h>
-
- #define PHY_ID_YT8511 0x0000010a
--#define PHY_ID_YT8521 0x0000011A
--#define PHY_ID_YT8531S 0x4F51E91A
-+#define PHY_ID_YT8521 0x0000011a
-+#define PHY_ID_YT8531S 0x4f51e91a
-
- /* YT8521/YT8531S Register Overview
- * UTP Register space | FIBER Register space
diff --git a/target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch b/target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch
deleted file mode 100644
index ba9a6ab4cc..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 4869a146cd60fc8115230f0a45e15e534c531922 Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:34 +0800
-Subject: [PATCH] net: phy: Add BIT macro for Motorcomm yt8521/yt8531 gigabit
- ethernet phy
-
-Add BIT macro for Motorcomm yt8521/yt8531 gigabit ethernet phy.
- This is a preparatory patch. Add BIT macro for 0xA012 reg, and
- supplement for 0xA001 and 0xA003 reg. These will be used to support dts.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 55 ++++++++++++++++++++++++++++++++++---
- 1 file changed, 51 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -161,6 +161,11 @@
-
- #define YT8521_CHIP_CONFIG_REG 0xA001
- #define YT8521_CCR_SW_RST BIT(15)
-+/* 1b0 disable 1.9ns rxc clock delay *default*
-+ * 1b1 enable 1.9ns rxc clock delay
-+ */
-+#define YT8521_CCR_RXC_DLY_EN BIT(8)
-+#define YT8521_CCR_RXC_DLY_1_900_NS 1900
-
- #define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0))
- #define YT8521_CCR_MODE_UTP_TO_RGMII 0
-@@ -178,22 +183,41 @@
- #define YT8521_MODE_POLL 0x3
-
- #define YT8521_RGMII_CONFIG1_REG 0xA003
--
-+/* 1b0 use original tx_clk_rgmii *default*
-+ * 1b1 use inverted tx_clk_rgmii.
-+ */
-+#define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14)
- /* TX Gig-E Delay is bits 3:0, default 0x1
- * TX Fast-E Delay is bits 7:4, default 0xf
- * RX Delay is bits 13:10, default 0x0
- * Delay = 150ps * N
- * On = 2250ps, off = 0ps
- */
--#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10)
-+#define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10)
- #define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
- #define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
--#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4)
-+#define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
- #define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
- #define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
--#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0)
-+#define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
- #define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
- #define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
-+#define YT8521_RC1R_RGMII_0_000_NS 0
-+#define YT8521_RC1R_RGMII_0_150_NS 1
-+#define YT8521_RC1R_RGMII_0_300_NS 2
-+#define YT8521_RC1R_RGMII_0_450_NS 3
-+#define YT8521_RC1R_RGMII_0_600_NS 4
-+#define YT8521_RC1R_RGMII_0_750_NS 5
-+#define YT8521_RC1R_RGMII_0_900_NS 6
-+#define YT8521_RC1R_RGMII_1_050_NS 7
-+#define YT8521_RC1R_RGMII_1_200_NS 8
-+#define YT8521_RC1R_RGMII_1_350_NS 9
-+#define YT8521_RC1R_RGMII_1_500_NS 10
-+#define YT8521_RC1R_RGMII_1_650_NS 11
-+#define YT8521_RC1R_RGMII_1_800_NS 12
-+#define YT8521_RC1R_RGMII_1_950_NS 13
-+#define YT8521_RC1R_RGMII_2_100_NS 14
-+#define YT8521_RC1R_RGMII_2_250_NS 15
-
- #define YTPHY_MISC_CONFIG_REG 0xA006
- #define YTPHY_MCR_FIBER_SPEED_MASK BIT(0)
-@@ -222,6 +246,29 @@
- */
- #define YTPHY_WCR_TYPE_PULSE BIT(0)
-
-+#define YTPHY_SYNCE_CFG_REG 0xA012
-+#define YT8521_SCR_SYNCE_ENABLE BIT(5)
-+/* 1b0 output 25m clock
-+ * 1b1 output 125m clock *default*
-+ */
-+#define YT8521_SCR_CLK_FRE_SEL_125M BIT(3)
-+#define YT8521_SCR_CLK_SRC_MASK GENMASK(2, 1)
-+#define YT8521_SCR_CLK_SRC_PLL_125M 0
-+#define YT8521_SCR_CLK_SRC_UTP_RX 1
-+#define YT8521_SCR_CLK_SRC_SDS_RX 2
-+#define YT8521_SCR_CLK_SRC_REF_25M 3
-+#define YT8531_SCR_SYNCE_ENABLE BIT(6)
-+/* 1b0 output 25m clock *default*
-+ * 1b1 output 125m clock
-+ */
-+#define YT8531_SCR_CLK_FRE_SEL_125M BIT(4)
-+#define YT8531_SCR_CLK_SRC_MASK GENMASK(3, 1)
-+#define YT8531_SCR_CLK_SRC_PLL_125M 0
-+#define YT8531_SCR_CLK_SRC_UTP_RX 1
-+#define YT8531_SCR_CLK_SRC_SDS_RX 2
-+#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
-+#define YT8531_SCR_CLK_SRC_REF_25M 4
-+#define YT8531_SCR_CLK_SRC_SSC_25M 5
- #define YT8531S_SYNCE_CFG_REG 0xA012
- #define YT8531S_SCR_SYNCE_ENABLE BIT(6)
-
diff --git a/target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch b/target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch
deleted file mode 100644
index 6d89fae84c..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch
+++ /dev/null
@@ -1,343 +0,0 @@
-From a6e68f0f8769f79c67cdcfb6302feecd36197dec Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:35 +0800
-Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8521 gigabit
- ethernet phy
-
-Add dts support for Motorcomm yt8521 gigabit ethernet phy.
- Add ytphy_rgmii_clk_delay_config function to support dst config for
- the delay of rgmii clk. This funciont is common for yt8521, yt8531s
- and yt8531.
- This patch has been verified on AM335x platform.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 253 ++++++++++++++++++++++++++++--------
- 1 file changed, 199 insertions(+), 54 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -10,6 +10,7 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/phy.h>
-+#include <linux/of.h>
-
- #define PHY_ID_YT8511 0x0000010a
- #define PHY_ID_YT8521 0x0000011a
-@@ -187,21 +188,9 @@
- * 1b1 use inverted tx_clk_rgmii.
- */
- #define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14)
--/* TX Gig-E Delay is bits 3:0, default 0x1
-- * TX Fast-E Delay is bits 7:4, default 0xf
-- * RX Delay is bits 13:10, default 0x0
-- * Delay = 150ps * N
-- * On = 2250ps, off = 0ps
-- */
- #define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10)
--#define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
--#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
- #define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
--#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
--#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
- #define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
--#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
--#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
- #define YT8521_RC1R_RGMII_0_000_NS 0
- #define YT8521_RC1R_RGMII_0_150_NS 1
- #define YT8521_RC1R_RGMII_0_300_NS 2
-@@ -274,6 +263,10 @@
-
- /* Extended Register end */
-
-+#define YTPHY_DTS_OUTPUT_CLK_DIS 0
-+#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
-+#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
-+
- struct yt8521_priv {
- /* combo_advertising is used for case of YT8521 in combo mode,
- * this means that yt8521 may work in utp or fiber mode which depends
-@@ -641,6 +634,142 @@ static int yt8521_write_page(struct phy_
- };
-
- /**
-+ * struct ytphy_cfg_reg_map - map a config value to a register value
-+ * @cfg: value in device configuration
-+ * @reg: value in the register
-+ */
-+struct ytphy_cfg_reg_map {
-+ u32 cfg;
-+ u32 reg;
-+};
-+
-+static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
-+ /* for tx delay / rx delay with YT8521_CCR_RXC_DLY_EN is not set. */
-+ { 0, YT8521_RC1R_RGMII_0_000_NS },
-+ { 150, YT8521_RC1R_RGMII_0_150_NS },
-+ { 300, YT8521_RC1R_RGMII_0_300_NS },
-+ { 450, YT8521_RC1R_RGMII_0_450_NS },
-+ { 600, YT8521_RC1R_RGMII_0_600_NS },
-+ { 750, YT8521_RC1R_RGMII_0_750_NS },
-+ { 900, YT8521_RC1R_RGMII_0_900_NS },
-+ { 1050, YT8521_RC1R_RGMII_1_050_NS },
-+ { 1200, YT8521_RC1R_RGMII_1_200_NS },
-+ { 1350, YT8521_RC1R_RGMII_1_350_NS },
-+ { 1500, YT8521_RC1R_RGMII_1_500_NS },
-+ { 1650, YT8521_RC1R_RGMII_1_650_NS },
-+ { 1800, YT8521_RC1R_RGMII_1_800_NS },
-+ { 1950, YT8521_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */
-+ { 2100, YT8521_RC1R_RGMII_2_100_NS },
-+ { 2250, YT8521_RC1R_RGMII_2_250_NS },
-+
-+ /* only for rx delay with YT8521_CCR_RXC_DLY_EN is set. */
-+ { 0 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_000_NS },
-+ { 150 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_150_NS },
-+ { 300 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_300_NS },
-+ { 450 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_450_NS },
-+ { 600 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_600_NS },
-+ { 750 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_750_NS },
-+ { 900 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_900_NS },
-+ { 1050 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_050_NS },
-+ { 1200 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_200_NS },
-+ { 1350 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_350_NS },
-+ { 1500 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_500_NS },
-+ { 1650 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_650_NS },
-+ { 1800 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_800_NS },
-+ { 1950 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_950_NS },
-+ { 2100 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_100_NS },
-+ { 2250 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_250_NS }
-+};
-+
-+static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
-+ const char *prop_name,
-+ const struct ytphy_cfg_reg_map *tbl,
-+ int tb_size,
-+ u16 *rxc_dly_en,
-+ u32 dflt)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ int tb_size_half = tb_size / 2;
-+ u32 val;
-+ int i;
-+
-+ if (of_property_read_u32(node, prop_name, &val))
-+ goto err_dts_val;
-+
-+ /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
-+ * tb_size is valid.
-+ */
-+ if (!rxc_dly_en)
-+ tb_size = tb_size_half;
-+
-+ for (i = 0; i < tb_size; i++) {
-+ if (tbl[i].cfg == val) {
-+ if (rxc_dly_en && i < tb_size_half)
-+ *rxc_dly_en = 0;
-+ return tbl[i].reg;
-+ }
-+ }
-+
-+ phydev_warn(phydev, "Unsupported value %d for %s using default (%u)\n",
-+ val, prop_name, dflt);
-+
-+err_dts_val:
-+ /* when rxc_dly_en is not NULL, it is get the delay for rx.
-+ * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
-+ * so YT8521_CCR_RXC_DLY_EN should not be set.
-+ */
-+ if (rxc_dly_en)
-+ *rxc_dly_en = 0;
-+
-+ return dflt;
-+}
-+
-+static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
-+{
-+ int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
-+ u16 rxc_dly_en = YT8521_CCR_RXC_DLY_EN;
-+ u32 rx_reg, tx_reg;
-+ u16 mask, val = 0;
-+ int ret;
-+
-+ rx_reg = ytphy_get_delay_reg_value(phydev, "rx-internal-delay-ps",
-+ ytphy_rgmii_delays, tb_size,
-+ &rxc_dly_en,
-+ YT8521_RC1R_RGMII_1_950_NS);
-+ tx_reg = ytphy_get_delay_reg_value(phydev, "tx-internal-delay-ps",
-+ ytphy_rgmii_delays, tb_size, NULL,
-+ YT8521_RC1R_RGMII_1_950_NS);
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ rxc_dly_en = 0;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg);
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ rxc_dly_en = 0;
-+ val |= FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
-+ FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
-+ break;
-+ default: /* do not support other modes */
-+ return -EOPNOTSUPP;
-+ }
-+
-+ ret = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
-+ YT8521_CCR_RXC_DLY_EN, rxc_dly_en);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Generally, it is not necessary to adjust YT8521_RC1R_FE_TX_DELAY */
-+ mask = YT8521_RC1R_RX_DELAY_MASK | YT8521_RC1R_GE_TX_DELAY_MASK;
-+ return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val);
-+}
-+
-+/**
- * yt8521_probe() - read chip config then set suitable polling_mode
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -648,9 +777,12 @@ static int yt8521_write_page(struct phy_
- */
- static int yt8521_probe(struct phy_device *phydev)
- {
-+ struct device_node *node = phydev->mdio.dev.of_node;
- struct device *dev = &phydev->mdio.dev;
- struct yt8521_priv *priv;
- int chip_config;
-+ u16 mask, val;
-+ u32 freq;
- int ret;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-@@ -695,7 +827,45 @@ static int yt8521_probe(struct phy_devic
- return ret;
- }
-
-- return 0;
-+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq))
-+ freq = YTPHY_DTS_OUTPUT_CLK_DIS;
-+
-+ if (phydev->drv->phy_id == PHY_ID_YT8521) {
-+ switch (freq) {
-+ case YTPHY_DTS_OUTPUT_CLK_DIS:
-+ mask = YT8521_SCR_SYNCE_ENABLE;
-+ val = 0;
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_25M:
-+ mask = YT8521_SCR_SYNCE_ENABLE |
-+ YT8521_SCR_CLK_SRC_MASK |
-+ YT8521_SCR_CLK_FRE_SEL_125M;
-+ val = YT8521_SCR_SYNCE_ENABLE |
-+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK,
-+ YT8521_SCR_CLK_SRC_REF_25M);
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_125M:
-+ mask = YT8521_SCR_SYNCE_ENABLE |
-+ YT8521_SCR_CLK_SRC_MASK |
-+ YT8521_SCR_CLK_FRE_SEL_125M;
-+ val = YT8521_SCR_SYNCE_ENABLE |
-+ YT8521_SCR_CLK_FRE_SEL_125M |
-+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK,
-+ YT8521_SCR_CLK_SRC_PLL_125M);
-+ break;
-+ default:
-+ phydev_warn(phydev, "Freq err:%u\n", freq);
-+ return -EINVAL;
-+ }
-+ } else if (phydev->drv->phy_id == PHY_ID_YT8531S) {
-+ return 0;
-+ } else {
-+ phydev_warn(phydev, "PHY id err\n");
-+ return -EINVAL;
-+ }
-+
-+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask,
-+ val);
- }
-
- /**
-@@ -1180,61 +1350,36 @@ static int yt8521_resume(struct phy_devi
- */
- static int yt8521_config_init(struct phy_device *phydev)
- {
-+ struct device_node *node = phydev->mdio.dev.of_node;
- int old_page;
- int ret = 0;
-- u16 val;
-
- old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
- if (old_page < 0)
- goto err_restore_page;
-
-- switch (phydev->interface) {
-- case PHY_INTERFACE_MODE_RGMII:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
-- val |= YT8521_RC1R_RX_DELAY_DIS;
-- break;
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
-- val |= YT8521_RC1R_RX_DELAY_EN;
-- break;
-- case PHY_INTERFACE_MODE_RGMII_TXID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
-- val |= YT8521_RC1R_RX_DELAY_DIS;
-- break;
-- case PHY_INTERFACE_MODE_RGMII_ID:
-- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
-- val |= YT8521_RC1R_RX_DELAY_EN;
-- break;
-- case PHY_INTERFACE_MODE_SGMII:
-- break;
-- default: /* do not support other modes */
-- ret = -EOPNOTSUPP;
-- goto err_restore_page;
-- }
--
- /* set rgmii delay mode */
- if (phydev->interface != PHY_INTERFACE_MODE_SGMII) {
-- ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG,
-- (YT8521_RC1R_RX_DELAY_MASK |
-- YT8521_RC1R_FE_TX_DELAY_MASK |
-- YT8521_RC1R_GE_TX_DELAY_MASK),
-- val);
-+ ret = ytphy_rgmii_clk_delay_config(phydev);
- if (ret < 0)
- goto err_restore_page;
- }
-
-- /* disable auto sleep */
-- ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
-- YT8521_ESC1R_SLEEP_SW, 0);
-- if (ret < 0)
-- goto err_restore_page;
--
-- /* enable RXC clock when no wire plug */
-- ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
-- YT8521_CGR_RX_CLK_EN, 0);
-- if (ret < 0)
-- goto err_restore_page;
-+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) {
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
-
-+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) {
-+ /* enable RXC clock when no wire plug */
-+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
-+ YT8521_CGR_RX_CLK_EN, 0);
-+ if (ret < 0)
-+ goto err_restore_page;
-+ }
- err_restore_page:
- return phy_restore_page(phydev, old_page, ret);
- }
diff --git a/target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch b/target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch
deleted file mode 100644
index 86fc04695c..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 36152f87dda4af221b16258751451d9cd3d0fb0b Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:36 +0800
-Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8531s gigabit
- ethernet phy
-
-Add dts support for Motorcomm yt8531s gigabit ethernet phy.
- Change yt8521_probe to support clk config of yt8531s. Becase
- yt8521_probe does the things which yt8531s is needed, so
- removed yt8531s function.
- This patch has been verified on AM335x platform with yt8531s board.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 51 ++++++++++++++++++++-----------------
- 1 file changed, 27 insertions(+), 24 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -258,8 +258,6 @@
- #define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
- #define YT8531_SCR_CLK_SRC_REF_25M 4
- #define YT8531_SCR_CLK_SRC_SSC_25M 5
--#define YT8531S_SYNCE_CFG_REG 0xA012
--#define YT8531S_SCR_SYNCE_ENABLE BIT(6)
-
- /* Extended Register end */
-
-@@ -858,7 +856,32 @@ static int yt8521_probe(struct phy_devic
- return -EINVAL;
- }
- } else if (phydev->drv->phy_id == PHY_ID_YT8531S) {
-- return 0;
-+ switch (freq) {
-+ case YTPHY_DTS_OUTPUT_CLK_DIS:
-+ mask = YT8531_SCR_SYNCE_ENABLE;
-+ val = 0;
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_25M:
-+ mask = YT8531_SCR_SYNCE_ENABLE |
-+ YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_REF_25M);
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_125M:
-+ mask = YT8531_SCR_SYNCE_ENABLE |
-+ YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE |
-+ YT8531_SCR_CLK_FRE_SEL_125M |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_PLL_125M);
-+ break;
-+ default:
-+ phydev_warn(phydev, "Freq err:%u\n", freq);
-+ return -EINVAL;
-+ }
- } else {
- phydev_warn(phydev, "PHY id err\n");
- return -EINVAL;
-@@ -869,26 +892,6 @@ static int yt8521_probe(struct phy_devic
- }
-
- /**
-- * yt8531s_probe() - read chip config then set suitable polling_mode
-- * @phydev: a pointer to a &struct phy_device
-- *
-- * returns 0 or negative errno code
-- */
--static int yt8531s_probe(struct phy_device *phydev)
--{
-- int ret;
--
-- /* Disable SyncE clock output by default */
-- ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG,
-- YT8531S_SCR_SYNCE_ENABLE, 0);
-- if (ret < 0)
-- return ret;
--
-- /* same as yt8521_probe */
-- return yt8521_probe(phydev);
--}
--
--/**
- * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -1970,7 +1973,7 @@ static struct phy_driver motorcomm_phy_d
- PHY_ID_MATCH_EXACT(PHY_ID_YT8531S),
- .name = "YT8531S Gigabit Ethernet",
- .get_features = yt8521_get_features,
-- .probe = yt8531s_probe,
-+ .probe = yt8521_probe,
- .read_page = yt8521_read_page,
- .write_page = yt8521_write_page,
- .get_wol = ytphy_get_wol,
diff --git a/target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch b/target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch
deleted file mode 100644
index 60eea4fa47..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch
+++ /dev/null
@@ -1,302 +0,0 @@
-From 4ac94f728a588e7096dd5010cd7141a309ea7805 Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:37 +0800
-Subject: [PATCH] net: phy: Add driver for Motorcomm yt8531 gigabit ethernet
- phy
-
-Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have
- verified the driver on AM335x platform with yt8531 board. On the
- board, yt8531 gigabit ethernet phy works in utp mode, RGMII
- interface, supports 1000M/100M/10M speeds, and wol(magic package).
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 2 +-
- drivers/net/phy/motorcomm.c | 208 +++++++++++++++++++++++++++++++++++-
- 2 files changed, 207 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -257,7 +257,7 @@ config MOTORCOMM_PHY
- tristate "Motorcomm PHYs"
- help
- Enables support for Motorcomm network PHYs.
-- Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs.
-+ Currently supports YT85xx Gigabit Ethernet PHYs.
-
- config NATIONAL_PHY
- tristate "National Semiconductor PHYs"
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0+
- /*
-- * Motorcomm 8511/8521/8531S PHY driver.
-+ * Motorcomm 8511/8521/8531/8531S PHY driver.
- *
- * Author: Peter Geis <pgwipeout@gmail.com>
- * Author: Frank <Frank.Sae@motor-comm.com>
-@@ -14,6 +14,7 @@
-
- #define PHY_ID_YT8511 0x0000010a
- #define PHY_ID_YT8521 0x0000011a
-+#define PHY_ID_YT8531 0x4f51e91b
- #define PHY_ID_YT8531S 0x4f51e91a
-
- /* YT8521/YT8531S Register Overview
-@@ -517,6 +518,61 @@ err_restore_page:
- return phy_restore_page(phydev, old_page, ret);
- }
-
-+static int yt8531_set_wol(struct phy_device *phydev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ const u16 mac_addr_reg[] = {
-+ YTPHY_WOL_MACADDR2_REG,
-+ YTPHY_WOL_MACADDR1_REG,
-+ YTPHY_WOL_MACADDR0_REG,
-+ };
-+ const u8 *mac_addr;
-+ u16 mask, val;
-+ int ret;
-+ u8 i;
-+
-+ if (wol->wolopts & WAKE_MAGIC) {
-+ mac_addr = phydev->attached_dev->dev_addr;
-+
-+ /* Store the device address for the magic packet */
-+ for (i = 0; i < 3; i++) {
-+ ret = ytphy_write_ext_with_lock(phydev, mac_addr_reg[i],
-+ ((mac_addr[i * 2] << 8)) |
-+ (mac_addr[i * 2 + 1]));
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ /* Enable WOL feature */
-+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL;
-+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS;
-+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG,
-+ mask, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Enable WOL interrupt */
-+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0,
-+ YTPHY_IER_WOL);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ /* Disable WOL feature */
-+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL;
-+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG,
-+ mask, 0);
-+
-+ /* Disable WOL interrupt */
-+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG,
-+ YTPHY_IER_WOL, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int yt8511_read_page(struct phy_device *phydev)
- {
- return __phy_read(phydev, YT8511_PAGE_SELECT);
-@@ -767,6 +823,17 @@ static int ytphy_rgmii_clk_delay_config(
- return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val);
- }
-
-+static int ytphy_rgmii_clk_delay_config_with_lock(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ phy_lock_mdio_bus(phydev);
-+ ret = ytphy_rgmii_clk_delay_config(phydev);
-+ phy_unlock_mdio_bus(phydev);
-+
-+ return ret;
-+}
-+
- /**
- * yt8521_probe() - read chip config then set suitable polling_mode
- * @phydev: a pointer to a &struct phy_device
-@@ -891,6 +958,43 @@ static int yt8521_probe(struct phy_devic
- val);
- }
-
-+static int yt8531_probe(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ u16 mask, val;
-+ u32 freq;
-+
-+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq))
-+ freq = YTPHY_DTS_OUTPUT_CLK_DIS;
-+
-+ switch (freq) {
-+ case YTPHY_DTS_OUTPUT_CLK_DIS:
-+ mask = YT8531_SCR_SYNCE_ENABLE;
-+ val = 0;
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_25M:
-+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_REF_25M);
-+ break;
-+ case YTPHY_DTS_OUTPUT_CLK_125M:
-+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
-+ YT8531_SCR_CLK_FRE_SEL_125M;
-+ val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
-+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+ YT8531_SCR_CLK_SRC_PLL_125M);
-+ break;
-+ default:
-+ phydev_warn(phydev, "Freq err:%u\n", freq);
-+ return -EINVAL;
-+ }
-+
-+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask,
-+ val);
-+}
-+
- /**
- * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp
- * @phydev: a pointer to a &struct phy_device
-@@ -1387,6 +1491,94 @@ err_restore_page:
- return phy_restore_page(phydev, old_page, ret);
- }
-
-+static int yt8531_config_init(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ int ret;
-+
-+ ret = ytphy_rgmii_clk_delay_config_with_lock(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) {
-+ /* disable auto sleep */
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YT8521_EXTREG_SLEEP_CONTROL1_REG,
-+ YT8521_ESC1R_SLEEP_SW, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) {
-+ /* enable RXC clock when no wire plug */
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YT8521_CLOCK_GATING_REG,
-+ YT8521_CGR_RX_CLK_EN, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * yt8531_link_change_notify() - Adjust the tx clock direction according to
-+ * the current speed and dts config.
-+ * @phydev: a pointer to a &struct phy_device
-+ *
-+ * NOTE: This function is only used to adapt to VF2 with JH7110 SoC. Please
-+ * keep "motorcomm,tx-clk-adj-enabled" not exist in dts when the soc is not
-+ * JH7110.
-+ */
-+static void yt8531_link_change_notify(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ bool tx_clk_adj_enabled = false;
-+ bool tx_clk_1000_inverted;
-+ bool tx_clk_100_inverted;
-+ bool tx_clk_10_inverted;
-+ u16 val = 0;
-+ int ret;
-+
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-adj-enabled"))
-+ tx_clk_adj_enabled = true;
-+
-+ if (!tx_clk_adj_enabled)
-+ return;
-+
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-10-inverted"))
-+ tx_clk_10_inverted = true;
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-100-inverted"))
-+ tx_clk_100_inverted = true;
-+ if (of_property_read_bool(node, "motorcomm,tx-clk-1000-inverted"))
-+ tx_clk_1000_inverted = true;
-+
-+ if (phydev->speed < 0)
-+ return;
-+
-+ switch (phydev->speed) {
-+ case SPEED_1000:
-+ if (tx_clk_1000_inverted)
-+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED;
-+ break;
-+ case SPEED_100:
-+ if (tx_clk_100_inverted)
-+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED;
-+ break;
-+ case SPEED_10:
-+ if (tx_clk_10_inverted)
-+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED;
-+ break;
-+ default:
-+ return;
-+ }
-+
-+ ret = ytphy_modify_ext_with_lock(phydev, YT8521_RGMII_CONFIG1_REG,
-+ YT8521_RC1R_TX_CLK_SEL_INVERTED, val);
-+ if (ret < 0)
-+ phydev_warn(phydev, "Modify TX_CLK_SEL err:%d\n", ret);
-+}
-+
- /**
- * yt8521_prepare_fiber_features() - A small helper function that setup
- * fiber's features.
-@@ -1970,6 +2162,17 @@ static struct phy_driver motorcomm_phy_d
- .resume = yt8521_resume,
- },
- {
-+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531),
-+ .name = "YT8531 Gigabit Ethernet",
-+ .probe = yt8531_probe,
-+ .config_init = yt8531_config_init,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
-+ .get_wol = ytphy_get_wol,
-+ .set_wol = yt8531_set_wol,
-+ .link_change_notify = yt8531_link_change_notify,
-+ },
-+ {
- PHY_ID_MATCH_EXACT(PHY_ID_YT8531S),
- .name = "YT8531S Gigabit Ethernet",
- .get_features = yt8521_get_features,
-@@ -1990,7 +2193,7 @@ static struct phy_driver motorcomm_phy_d
-
- module_phy_driver(motorcomm_phy_drvs);
-
--MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver");
-+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531/8531S PHY driver");
- MODULE_AUTHOR("Peter Geis");
- MODULE_AUTHOR("Frank");
- MODULE_LICENSE("GPL");
-@@ -1998,6 +2201,7 @@ MODULE_LICENSE("GPL");
- static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
-+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531) },
- { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
- { /* sentinel */ }
- };
diff --git a/target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch b/target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch
deleted file mode 100644
index 29ae86dbbc..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 9753613f7399601f9bae6ee81e9d4274246c98ab Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <error27@gmail.com>
-Date: Wed, 15 Feb 2023 07:21:47 +0300
-Subject: [PATCH] net: phy: motorcomm: uninitialized variables in
- yt8531_link_change_notify()
-
-These booleans are never set to false, but are just used without being
-initialized.
-
-Fixes: 4ac94f728a58 ("net: phy: Add driver for Motorcomm yt8531 gigabit ethernet phy")
-Signed-off-by: Dan Carpenter <error27@gmail.com>
-Reviewed-by: Frank Sae <Frank.Sae@motor-comm.com>
-Link: https://lore.kernel.org/r/Y+xd2yJet2ImHLoQ@kili
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/motorcomm.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -1533,10 +1533,10 @@ static int yt8531_config_init(struct phy
- static void yt8531_link_change_notify(struct phy_device *phydev)
- {
- struct device_node *node = phydev->mdio.dev.of_node;
-+ bool tx_clk_1000_inverted = false;
-+ bool tx_clk_100_inverted = false;
-+ bool tx_clk_10_inverted = false;
- bool tx_clk_adj_enabled = false;
-- bool tx_clk_1000_inverted;
-- bool tx_clk_100_inverted;
-- bool tx_clk_10_inverted;
- u16 val = 0;
- int ret;
-
diff --git a/target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch b/target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch
deleted file mode 100644
index 010ca9b68a..0000000000
--- a/target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-From 7a561e9351ae7e3fb1f08584d40b49c1e55dde60 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Thu, 20 Jul 2023 19:15:09 +0800
-Subject: [PATCH] net: phy: motorcomm: Add pad drive strength cfg support
-
-The motorcomm phy (YT8531) supports the ability to adjust the drive
-strength of the rx_clk/rx_data, and the default strength may not be
-suitable for all boards. So add configurable options to better match
-the boards.(e.g. StarFive VisionFive 2)
-
-When we configure the drive strength, we need to read the current
-LDO voltage value to ensure that it is a legal value at that LDO
-voltage.
-
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/motorcomm.c | 118 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 118 insertions(+)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -163,6 +163,10 @@
-
- #define YT8521_CHIP_CONFIG_REG 0xA001
- #define YT8521_CCR_SW_RST BIT(15)
-+#define YT8531_RGMII_LDO_VOL_MASK GENMASK(5, 4)
-+#define YT8531_LDO_VOL_3V3 0x0
-+#define YT8531_LDO_VOL_1V8 0x2
-+
- /* 1b0 disable 1.9ns rxc clock delay *default*
- * 1b1 enable 1.9ns rxc clock delay
- */
-@@ -236,6 +240,12 @@
- */
- #define YTPHY_WCR_TYPE_PULSE BIT(0)
-
-+#define YTPHY_PAD_DRIVE_STRENGTH_REG 0xA010
-+#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13)
-+#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */
-+#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
-+#define YT8531_RGMII_RX_DS_DEFAULT 0x3
-+
- #define YTPHY_SYNCE_CFG_REG 0xA012
- #define YT8521_SCR_SYNCE_ENABLE BIT(5)
- /* 1b0 output 25m clock
-@@ -835,6 +845,110 @@ static int ytphy_rgmii_clk_delay_config_
- }
-
- /**
-+ * struct ytphy_ldo_vol_map - map a current value to a register value
-+ * @vol: ldo voltage
-+ * @ds: value in the register
-+ * @cur: value in device configuration
-+ */
-+struct ytphy_ldo_vol_map {
-+ u32 vol;
-+ u32 ds;
-+ u32 cur;
-+};
-+
-+static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 0, .cur = 1200},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 1, .cur = 2100},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 2, .cur = 2700},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 3, .cur = 2910},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 4, .cur = 3110},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 5, .cur = 3600},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 6, .cur = 3970},
-+ {.vol = YT8531_LDO_VOL_1V8, .ds = 7, .cur = 4350},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 0, .cur = 3070},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 1, .cur = 4080},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 2, .cur = 4370},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 3, .cur = 4680},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 4, .cur = 5020},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 5, .cur = 5450},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 6, .cur = 5740},
-+ {.vol = YT8531_LDO_VOL_3V3, .ds = 7, .cur = 6140},
-+};
-+
-+static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
-+{
-+ u32 val;
-+
-+ val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
-+ val = FIELD_GET(YT8531_RGMII_LDO_VOL_MASK, val);
-+
-+ return val <= YT8531_LDO_VOL_1V8 ? val : YT8531_LDO_VOL_1V8;
-+}
-+
-+static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
-+{
-+ u32 vol;
-+ int i;
-+
-+ vol = yt8531_get_ldo_vol(phydev);
-+ for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
-+ if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
-+ return yt8531_ldo_vol[i].ds;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int yt8531_set_ds(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ u32 ds_field_low, ds_field_hi, val;
-+ int ret, ds;
-+
-+ /* set rgmii rx clk driver strength */
-+ if (!of_property_read_u32(node, "motorcomm,rx-clk-drv-microamp", &val)) {
-+ ds = yt8531_get_ds_map(phydev, val);
-+ if (ds < 0)
-+ return dev_err_probe(&phydev->mdio.dev, ds,
-+ "No matching current value was found.\n");
-+ } else {
-+ ds = YT8531_RGMII_RX_DS_DEFAULT;
-+ }
-+
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YTPHY_PAD_DRIVE_STRENGTH_REG,
-+ YT8531_RGMII_RXC_DS_MASK,
-+ FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
-+ if (ret < 0)
-+ return ret;
-+
-+ /* set rgmii rx data driver strength */
-+ if (!of_property_read_u32(node, "motorcomm,rx-data-drv-microamp", &val)) {
-+ ds = yt8531_get_ds_map(phydev, val);
-+ if (ds < 0)
-+ return dev_err_probe(&phydev->mdio.dev, ds,
-+ "No matching current value was found.\n");
-+ } else {
-+ ds = YT8531_RGMII_RX_DS_DEFAULT;
-+ }
-+
-+ ds_field_hi = FIELD_GET(BIT(2), ds);
-+ ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
-+
-+ ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
-+ ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
-+
-+ ret = ytphy_modify_ext_with_lock(phydev,
-+ YTPHY_PAD_DRIVE_STRENGTH_REG,
-+ YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
-+ ds_field_low | ds_field_hi);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+/**
- * yt8521_probe() - read chip config then set suitable polling_mode
- * @phydev: a pointer to a &struct phy_device
- *
-@@ -1518,6 +1632,10 @@ static int yt8531_config_init(struct phy
- return ret;
- }
-
-+ ret = yt8531_set_ds(phydev);
-+ if (ret < 0)
-+ return ret;
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch
deleted file mode 100644
index f82c8fc622..0000000000
--- a/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 13 Jul 2023 09:42:07 +0100
-Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods
-
-Add phylink PCS enable/disable callbacks that will allow us to place
-IEEE 802.3 register compliant PCS in power-down mode while not being
-used.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++--------
- include/linux/phylink.h | 16 +++++++++++++
- 2 files changed, 55 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -34,6 +34,10 @@ enum {
- PHYLINK_DISABLE_STOPPED,
- PHYLINK_DISABLE_LINK,
- PHYLINK_DISABLE_MAC_WOL,
-+
-+ PCS_STATE_DOWN = 0,
-+ PCS_STATE_STARTING,
-+ PCS_STATE_STARTED,
- };
-
- /**
-@@ -72,6 +76,7 @@ struct phylink {
- struct phylink_link_state phy_state;
- struct work_struct resolve;
- unsigned int pcs_neg_mode;
-+ unsigned int pcs_state;
-
- bool mac_link_dropped;
- bool using_mac_select_pcs;
-@@ -992,6 +997,22 @@ static void phylink_resolve_an_pause(str
- }
- }
-
-+static void phylink_pcs_disable(struct phylink_pcs *pcs)
-+{
-+ if (pcs && pcs->ops->pcs_disable)
-+ pcs->ops->pcs_disable(pcs);
-+}
-+
-+static int phylink_pcs_enable(struct phylink_pcs *pcs)
-+{
-+ int err = 0;
-+
-+ if (pcs && pcs->ops->pcs_enable)
-+ err = pcs->ops->pcs_enable(pcs);
-+
-+ return err;
-+}
-+
- static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
- const struct phylink_link_state *state,
- bool permit_pause_to_mac)
-@@ -1094,11 +1115,17 @@ static void phylink_major_config(struct
- /* If we have a new PCS, switch to the new PCS after preparing the MAC
- * for the change.
- */
-- if (pcs_changed)
-+ if (pcs_changed) {
-+ phylink_pcs_disable(pl->pcs);
-+
- pl->pcs = pcs;
-+ }
-
- phylink_mac_config(pl, state);
-
-+ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
-+ phylink_pcs_enable(pl->pcs);
-+
- neg_mode = pl->cur_link_an_mode;
- if (pl->pcs && pl->pcs->neg_mode)
- neg_mode = pl->pcs_neg_mode;
-@@ -1586,6 +1613,7 @@ struct phylink *phylink_create(struct ph
- pl->link_config.pause = MLO_PAUSE_AN;
- pl->link_config.speed = SPEED_UNKNOWN;
- pl->link_config.duplex = DUPLEX_UNKNOWN;
-+ pl->pcs_state = PCS_STATE_DOWN;
- pl->mac_ops = mac_ops;
- __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
- timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
-@@ -1987,6 +2015,8 @@ void phylink_start(struct phylink *pl)
- if (pl->netdev)
- netif_carrier_off(pl->netdev);
-
-+ pl->pcs_state = PCS_STATE_STARTING;
-+
- /* Apply the link configuration to the MAC when starting. This allows
- * a fixed-link to start with the correct parameters, and also
- * ensures that we set the appropriate advertisement for Serdes links.
-@@ -1997,6 +2027,8 @@ void phylink_start(struct phylink *pl)
- */
- phylink_mac_initial_config(pl, true);
-
-+ pl->pcs_state = PCS_STATE_STARTED;
-+
- phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED);
-
- if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
-@@ -2015,15 +2047,9 @@ void phylink_start(struct phylink *pl)
- poll = true;
- }
-
-- switch (pl->cfg_link_an_mode) {
-- case MLO_AN_FIXED:
-+ if (pl->cfg_link_an_mode == MLO_AN_FIXED)
- poll |= pl->config->poll_fixed_state;
-- break;
-- case MLO_AN_INBAND:
-- if (pl->pcs)
-- poll |= pl->pcs->poll;
-- break;
-- }
-+
- if (poll)
- mod_timer(&pl->link_poll, jiffies + HZ);
- if (pl->phydev)
-@@ -2060,6 +2086,10 @@ void phylink_stop(struct phylink *pl)
- }
-
- phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
-+
-+ pl->pcs_state = PCS_STATE_DOWN;
-+
-+ phylink_pcs_disable(pl->pcs);
- }
- EXPORT_SYMBOL_GPL(phylink_stop);
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -533,6 +533,8 @@ struct phylink_pcs {
- /**
- * struct phylink_pcs_ops - MAC PCS operations structure.
- * @pcs_validate: validate the link configuration.
-+ * @pcs_enable: enable the PCS.
-+ * @pcs_disable: disable the PCS.
- * @pcs_get_state: read the current MAC PCS link state from the hardware.
- * @pcs_config: configure the MAC PCS for the selected mode and state.
- * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
-@@ -542,6 +544,8 @@ struct phylink_pcs {
- struct phylink_pcs_ops {
- int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
- const struct phylink_link_state *state);
-+ int (*pcs_enable)(struct phylink_pcs *pcs);
-+ void (*pcs_disable)(struct phylink_pcs *pcs);
- void (*pcs_get_state)(struct phylink_pcs *pcs,
- struct phylink_link_state *state);
- int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode,
-@@ -572,6 +576,18 @@ int pcs_validate(struct phylink_pcs *pcs
- const struct phylink_link_state *state);
-
- /**
-+ * pcs_enable() - enable the PCS.
-+ * @pcs: a pointer to a &struct phylink_pcs.
-+ */
-+int pcs_enable(struct phylink_pcs *pcs);
-+
-+/**
-+ * pcs_disable() - disable the PCS.
-+ * @pcs: a pointer to a &struct phylink_pcs.
-+ */
-+void pcs_disable(struct phylink_pcs *pcs);
-+
-+/**
- * pcs_get_state() - Read the current inband link state from the hardware
- * @pcs: a pointer to a &struct phylink_pcs.
- * @state: a pointer to a &struct phylink_link_state.
diff --git a/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch
deleted file mode 100644
index 6b6369761a..0000000000
--- a/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 18 Aug 2023 04:07:46 +0100
-Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op
-
-When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface
-modes provided by mtk-pcs-lynxi we need to make sure to always perform
-a full configuration of the PHYA.
-
-Implement pcs_disable op which resets the stored interface mode to
-PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI
-PCS driver had previously been deselected in favor of another PCS
-driver such as the to-be-added driver for the USXGMII PCS found in
-MT7988.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/pcs/pcs-mtk-lynxi.c
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -234,11 +234,19 @@ static void mtk_pcs_lynxi_link_up(struct
- }
- }
-
-+static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs)
-+{
-+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+
-+ mpcs->interface = PHY_INTERFACE_MODE_NA;
-+}
-+
- static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
- .pcs_get_state = mtk_pcs_lynxi_get_state,
- .pcs_config = mtk_pcs_lynxi_config,
- .pcs_an_restart = mtk_pcs_lynxi_restart_an,
- .pcs_link_up = mtk_pcs_lynxi_link_up,
-+ .pcs_disable = mtk_pcs_lynxi_disable,
- };
-
- struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
diff --git a/target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch b/target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch
deleted file mode 100644
index c4141eee93..0000000000
--- a/target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From: Andy Ren <andy.ren@getcruise.com>
-Date: Mon, 7 Nov 2022 09:42:42 -0800
-Subject: [PATCH] net/core: Allow live renaming when an interface is up
-
-Allow a network interface to be renamed when the interface
-is up.
-
-As described in the netconsole documentation [1], when netconsole is
-used as a built-in, it will bring up the specified interface as soon as
-possible. As a result, user space will not be able to rename the
-interface since the kernel disallows renaming of interfaces that are
-administratively up unless the 'IFF_LIVE_RENAME_OK' private flag was set
-by the kernel.
-
-The original solution [2] to this problem was to add a new parameter to
-the netconsole configuration parameters that allows renaming of
-the interface used by netconsole while it is administratively up.
-However, during the discussion that followed, it became apparent that we
-have no reason to keep the current restriction and instead we should
-allow user space to rename interfaces regardless of their administrative
-state:
-
-1. The restriction was put in place over 20 years ago when renaming was
-only possible via IOCTL and before rtnetlink started notifying user
-space about such changes like it does today.
-
-2. The 'IFF_LIVE_RENAME_OK' flag was added over 3 years ago in version
-5.2 and no regressions were reported.
-
-3. In-kernel listeners to 'NETDEV_CHANGENAME' do not seem to care about
-the administrative state of interface.
-
-Therefore, allow user space to rename running interfaces by removing the
-restriction and the associated 'IFF_LIVE_RENAME_OK' flag. Help in
-possible triage by emitting a message to the kernel log that an
-interface was renamed while UP.
-
-[1] https://www.kernel.org/doc/Documentation/networking/netconsole.rst
-[2] https://lore.kernel.org/netdev/20221102002420.2613004-1-andy.ren@getcruise.com/
-
-Signed-off-by: Andy Ren <andy.ren@getcruise.com>
-Reviewed-by: Ido Schimmel <idosch@nvidia.com>
-Reviewed-by: David Ahern <dsahern@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1691,7 +1691,6 @@ struct net_device_ops {
- * @IFF_FAILOVER: device is a failover master device
- * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device
- * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device
-- * @IFF_LIVE_RENAME_OK: rename is allowed while device is up and running
- * @IFF_TX_SKB_NO_LINEAR: device/driver is capable of xmitting frames with
- * skb_headlen(skb) == 0 (data starts from frag0)
- * @IFF_CHANGE_PROTO_DOWN: device supports setting carrier via IFLA_PROTO_DOWN
-@@ -1727,7 +1726,7 @@ enum netdev_priv_flags {
- IFF_FAILOVER = 1<<27,
- IFF_FAILOVER_SLAVE = 1<<28,
- IFF_L3MDEV_RX_HANDLER = 1<<29,
-- IFF_LIVE_RENAME_OK = 1<<30,
-+ /* was IFF_LIVE_RENAME_OK */
- IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
- IFF_CHANGE_PROTO_DOWN = BIT_ULL(32),
- };
-@@ -1762,7 +1761,6 @@ enum netdev_priv_flags {
- #define IFF_FAILOVER IFF_FAILOVER
- #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
- #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
--#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK
- #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
-
- /* Specifies the type of the struct net_device::ml_priv pointer */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -1188,22 +1188,6 @@ int dev_change_name(struct net_device *d
-
- net = dev_net(dev);
-
-- /* Some auto-enslaved devices e.g. failover slaves are
-- * special, as userspace might rename the device after
-- * the interface had been brought up and running since
-- * the point kernel initiated auto-enslavement. Allow
-- * live name change even when these slave devices are
-- * up and running.
-- *
-- * Typically, users of these auto-enslaving devices
-- * don't actually care about slave name change, as
-- * they are supposed to operate on master interface
-- * directly.
-- */
-- if (dev->flags & IFF_UP &&
-- likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK)))
-- return -EBUSY;
--
- down_write(&devnet_rename_sem);
-
- if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
-@@ -1220,7 +1204,8 @@ int dev_change_name(struct net_device *d
- }
-
- if (oldname[0] && !strchr(oldname, '%'))
-- netdev_info(dev, "renamed from %s\n", oldname);
-+ netdev_info(dev, "renamed from %s%s\n", oldname,
-+ dev->flags & IFF_UP ? " (while UP)" : "");
-
- old_assign_type = dev->name_assign_type;
- dev->name_assign_type = NET_NAME_RENAMED;
---- a/net/core/failover.c
-+++ b/net/core/failover.c
-@@ -80,14 +80,14 @@ static int failover_slave_register(struc
- goto err_upper_link;
- }
-
-- slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
-+ slave_dev->priv_flags |= IFF_FAILOVER_SLAVE;
-
- if (fops && fops->slave_register &&
- !fops->slave_register(slave_dev, failover_dev))
- return NOTIFY_OK;
-
- netdev_upper_dev_unlink(slave_dev, failover_dev);
-- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
-+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
- err_upper_link:
- netdev_rx_handler_unregister(slave_dev);
- done:
-@@ -121,7 +121,7 @@ int failover_slave_unregister(struct net
-
- netdev_rx_handler_unregister(slave_dev);
- netdev_upper_dev_unlink(slave_dev, failover_dev);
-- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
-+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
-
- if (fops && fops->slave_unregister &&
- !fops->slave_unregister(slave_dev, failover_dev))
diff --git a/target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch b/target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch
deleted file mode 100644
index 17131c16d3..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From 69649ef8405320f81497f4757faac8234f61b167 Mon Sep 17 00:00:00 2001
-From: Bjørn Mork <bjorn@mork.no>
-Date: Fri, 6 Jan 2023 17:07:39 +0100
-Subject: [PATCH] cdc_ether: no need to blacklist any r8152 devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The r8152 driver does not need this anymore.
-
-Dropping blacklist entries adds optional support for these
-devices in ECM mode.
-
-The 8153 devices are handled by the r8153_ecm driver when
-in ECM mode, and must still be blacklisted here.
-
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/cdc_ether.c | 114 ------------------------------------
- 1 file changed, 114 deletions(-)
-
---- a/drivers/net/usb/cdc_ether.c
-+++ b/drivers/net/usb/cdc_ether.c
-@@ -768,13 +768,6 @@ static const struct usb_device_id produc
- .driver_info = 0,
- },
-
--/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
- /* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */
- {
- USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM,
-@@ -782,119 +775,12 @@ static const struct usb_device_id produc
- .driver_info = 0,
- },
-
--/* Samsung USB Ethernet Adapters */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--#if IS_ENABLED(CONFIG_USB_RTL8152)
--/* Linksys USB3GIGV1 Ethernet Adapter */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--#endif
--
--/* Lenovo ThinkPad OneLink+ Dock (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3054, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* ThinkPad USB-C Dock (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* ThinkPad Thunderbolt 3 Dock (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3069, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Lenovo USB C to Ethernet Adapter (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x720c, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Lenovo USB-C Travel Hub (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7214, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
- /* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */
- {
- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x721e, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
- .driver_info = 0,
- },
--
--/* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* NVIDIA Tegra USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(NVIDIA_VENDOR_ID, 0x09ff, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Microsoft Surface 2 dock (based on Realtek RTL8152) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07ab, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07c6, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153B) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x0927, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
--
--/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
--{
-- USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM,
-- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-- .driver_info = 0,
--},
-
- /* Aquantia AQtion USB to 5GbE Controller (based on AQC111U) */
- {
diff --git a/target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch b/target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch
deleted file mode 100644
index 565fbb3074..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 02767440e1dda9861a11ca1dbe0f19a760b1d5c2 Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Thu, 19 Jan 2023 15:40:43 +0800
-Subject: [PATCH] r8152: reduce the control transfer of rtl8152_get_version()
-
-Reduce the control transfer by moving calling rtl8152_get_version() in
-rtl8152_probe(). This could prevent from calling rtl8152_get_version()
-for unnecessary situations. For example, after setting config #2 for the
-device, there are two interfaces and rtl8152_probe() may be called
-twice. However, we don't need to call rtl8152_get_version() for this
-situation.
-
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -9638,20 +9638,21 @@ static int rtl8152_probe(struct usb_inte
- const struct usb_device_id *id)
- {
- struct usb_device *udev = interface_to_usbdev(intf);
-- u8 version = rtl8152_get_version(intf);
- struct r8152 *tp;
- struct net_device *netdev;
-+ u8 version;
- int ret;
-
-- if (version == RTL_VER_UNKNOWN)
-- return -ENODEV;
--
- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
- return -ENODEV;
-
- if (!rtl_check_vendor_ok(intf))
- return -ENODEV;
-
-+ version = rtl8152_get_version(intf);
-+ if (version == RTL_VER_UNKNOWN)
-+ return -ENODEV;
-+
- usb_reset_device(udev);
- netdev = alloc_etherdev(sizeof(struct r8152));
- if (!netdev) {
diff --git a/target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch b/target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch
deleted file mode 100644
index cdabca36d2..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 5cc33f139e11b893ff6dc60d8a0ae865a65521ac Mon Sep 17 00:00:00 2001
-From: Douglas Anderson <dianders@chromium.org>
-Date: Thu, 6 Apr 2023 17:14:26 -0700
-Subject: [PATCH] r8152: Add __GFP_NOWARN to big allocations
-
-When memory is a little tight on my system, it's pretty easy to see
-warnings that look like this.
-
- ksoftirqd/0: page allocation failure: order:3, mode:0x40a20(GFP_ATOMIC|__GFP_COMP), nodemask=(null),cpuset=/,mems_allowed=0
- ...
- Call trace:
- dump_backtrace+0x0/0x1e8
- show_stack+0x20/0x2c
- dump_stack_lvl+0x60/0x78
- dump_stack+0x18/0x38
- warn_alloc+0x104/0x174
- __alloc_pages+0x588/0x67c
- alloc_rx_agg+0xa0/0x190 [r8152 ...]
- r8152_poll+0x270/0x760 [r8152 ...]
- __napi_poll+0x44/0x1ec
- net_rx_action+0x100/0x300
- __do_softirq+0xec/0x38c
- run_ksoftirqd+0x38/0xec
- smpboot_thread_fn+0xb8/0x248
- kthread+0x134/0x154
- ret_from_fork+0x10/0x20
-
-On a fragmented system it's normal that order 3 allocations will
-sometimes fail, especially atomic ones. The driver handles these
-failures fine and the WARN just creates spam in the logs for this
-case. The __GFP_NOWARN flag is exactly for this situation, so add it
-to the allocation.
-
-NOTE: my testing is on a 5.15 system, but there should be no reason
-that this would be fundamentally different on a mainline kernel.
-
-Signed-off-by: Douglas Anderson <dianders@chromium.org>
-Acked-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230406171411.1.I84dbef45786af440fd269b71e9436a96a8e7a152@changeid
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -1947,7 +1947,7 @@ static struct rx_agg *alloc_rx_agg(struc
- if (!rx_agg)
- return NULL;
-
-- rx_agg->page = alloc_pages(mflags | __GFP_COMP, order);
-+ rx_agg->page = alloc_pages(mflags | __GFP_COMP | __GFP_NOWARN, order);
- if (!rx_agg->page)
- goto free_rx;
-
diff --git a/target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch b/target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch
deleted file mode 100644
index 3ba79d6cc6..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 57df0fb9d511f91202114813e90128d65c0589f0 Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Wed, 26 Jul 2023 11:08:07 +0800
-Subject: [PATCH] r8152: adjust generic_ocp_write function
-
-Reduce the control transfer if all bytes of first or the last DWORD are
-written.
-
-The original method is to split the control transfer into three parts
-(the first DWORD, middle continuous data, and the last DWORD). However,
-they could be combined if whole bytes of the first DWORD or last DWORD
-are written. That is, the first DWORD or the last DWORD could be combined
-with the middle continuous data, if the byte_en is 0xff.
-
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230726030808.9093-418-nic_swsd@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 29 ++++++++++++++++++-----------
- 1 file changed, 18 insertions(+), 11 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -1313,16 +1313,24 @@ static int generic_ocp_write(struct r815
- byteen_end = byteen & BYTE_EN_END_MASK;
-
- byen = byteen_start | (byteen_start << 4);
-- ret = set_registers(tp, index, type | byen, 4, data);
-- if (ret < 0)
-- goto error1;
--
-- index += 4;
-- data += 4;
-- size -= 4;
-
-- if (size) {
-+ /* Split the first DWORD if the byte_en is not 0xff */
-+ if (byen != BYTE_EN_DWORD) {
-+ ret = set_registers(tp, index, type | byen, 4, data);
-+ if (ret < 0)
-+ goto error1;
-+
-+ index += 4;
-+ data += 4;
- size -= 4;
-+ }
-+
-+ if (size) {
-+ byen = byteen_end | (byteen_end >> 4);
-+
-+ /* Split the last DWORD if the byte_en is not 0xff */
-+ if (byen != BYTE_EN_DWORD)
-+ size -= 4;
-
- while (size) {
- if (size > limit) {
-@@ -1349,10 +1357,9 @@ static int generic_ocp_write(struct r815
- }
- }
-
-- byen = byteen_end | (byteen_end >> 4);
-- ret = set_registers(tp, index, type | byen, 4, data);
-- if (ret < 0)
-- goto error1;
-+ /* Set the last DWORD */
-+ if (byen != BYTE_EN_DWORD)
-+ ret = set_registers(tp, index, type | byen, 4, data);
- }
-
- error1:
diff --git a/target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch b/target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch
deleted file mode 100644
index bc70c5af02..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From e5c266a61186b462c388c53a3564c375e72f2244 Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Wed, 26 Jul 2023 11:08:08 +0800
-Subject: [PATCH] r8152: set bp in bulk
-
-PLA_BP_0 ~ PLA_BP_15 (0xfc28 ~ 0xfc46) are continuous registers, so we
-could combine the control transfers into one control transfer.
-
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230726030808.9093-419-nic_swsd@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 75 ++++++++++++++---------------------------
- 1 file changed, 25 insertions(+), 50 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -3990,29 +3990,10 @@ static void rtl_reset_bmu(struct r8152 *
- /* Clear the bp to stop the firmware before loading a new one */
- static void rtl_clear_bp(struct r8152 *tp, u16 type)
- {
-- switch (tp->version) {
-- case RTL_VER_01:
-- case RTL_VER_02:
-- case RTL_VER_07:
-- break;
-- case RTL_VER_03:
-- case RTL_VER_04:
-- case RTL_VER_05:
-- case RTL_VER_06:
-- ocp_write_byte(tp, type, PLA_BP_EN, 0);
-- break;
-- case RTL_VER_14:
-- ocp_write_word(tp, type, USB_BP2_EN, 0);
-+ u16 bp[16] = {0};
-+ u16 bp_num;
-
-- ocp_write_word(tp, type, USB_BP_8, 0);
-- ocp_write_word(tp, type, USB_BP_9, 0);
-- ocp_write_word(tp, type, USB_BP_10, 0);
-- ocp_write_word(tp, type, USB_BP_11, 0);
-- ocp_write_word(tp, type, USB_BP_12, 0);
-- ocp_write_word(tp, type, USB_BP_13, 0);
-- ocp_write_word(tp, type, USB_BP_14, 0);
-- ocp_write_word(tp, type, USB_BP_15, 0);
-- break;
-+ switch (tp->version) {
- case RTL_VER_08:
- case RTL_VER_09:
- case RTL_VER_10:
-@@ -4020,32 +4001,31 @@ static void rtl_clear_bp(struct r8152 *t
- case RTL_VER_12:
- case RTL_VER_13:
- case RTL_VER_15:
-- default:
- if (type == MCU_TYPE_USB) {
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0);
--
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0);
-- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0);
-- } else {
-- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
-+ bp_num = 16;
-+ break;
- }
-+ fallthrough;
-+ case RTL_VER_03:
-+ case RTL_VER_04:
-+ case RTL_VER_05:
-+ case RTL_VER_06:
-+ ocp_write_byte(tp, type, PLA_BP_EN, 0);
-+ fallthrough;
-+ case RTL_VER_01:
-+ case RTL_VER_02:
-+ case RTL_VER_07:
-+ bp_num = 8;
-+ break;
-+ case RTL_VER_14:
-+ default:
-+ ocp_write_word(tp, type, USB_BP2_EN, 0);
-+ bp_num = 16;
- break;
- }
-
-- ocp_write_word(tp, type, PLA_BP_0, 0);
-- ocp_write_word(tp, type, PLA_BP_1, 0);
-- ocp_write_word(tp, type, PLA_BP_2, 0);
-- ocp_write_word(tp, type, PLA_BP_3, 0);
-- ocp_write_word(tp, type, PLA_BP_4, 0);
-- ocp_write_word(tp, type, PLA_BP_5, 0);
-- ocp_write_word(tp, type, PLA_BP_6, 0);
-- ocp_write_word(tp, type, PLA_BP_7, 0);
-+ generic_ocp_write(tp, PLA_BP_0, BYTE_EN_DWORD, bp_num << 1, bp, type);
-
- /* wait 3 ms to make sure the firmware is stopped */
- usleep_range(3000, 6000);
-@@ -5022,10 +5002,9 @@ static void rtl8152_fw_phy_nc_apply(stru
-
- static void rtl8152_fw_mac_apply(struct r8152 *tp, struct fw_mac *mac)
- {
-- u16 bp_en_addr, bp_index, type, bp_num, fw_ver_reg;
-+ u16 bp_en_addr, type, fw_ver_reg;
- u32 length;
- u8 *data;
-- int i;
-
- switch (__le32_to_cpu(mac->blk_hdr.type)) {
- case RTL_FW_PLA:
-@@ -5067,12 +5046,8 @@ static void rtl8152_fw_mac_apply(struct
- ocp_write_word(tp, type, __le16_to_cpu(mac->bp_ba_addr),
- __le16_to_cpu(mac->bp_ba_value));
-
-- bp_index = __le16_to_cpu(mac->bp_start);
-- bp_num = __le16_to_cpu(mac->bp_num);
-- for (i = 0; i < bp_num; i++) {
-- ocp_write_word(tp, type, bp_index, __le16_to_cpu(mac->bp[i]));
-- bp_index += 2;
-- }
-+ generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD,
-+ __le16_to_cpu(mac->bp_num) << 1, mac->bp, type);
-
- bp_en_addr = __le16_to_cpu(mac->bp_en_addr);
- if (bp_en_addr)
diff --git a/target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch b/target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch
deleted file mode 100644
index d7fdcdb2c6..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From cf74eb5a5bc867258e7d0b0d1c3c4a60e1e3de2f Mon Sep 17 00:00:00 2001
-From: Jakub Kicinski <kuba@kernel.org>
-Date: Mon, 14 Aug 2023 08:35:21 -0700
-Subject: [PATCH] eth: r8152: try to use a normal budget
-
-Mario reports that loading r8152 on his system leads to a:
-
- netif_napi_add_weight() called with weight 256
-
-warning getting printed. We don't have any solid data
-on why such high budget was chosen, and it may cause
-stalls in processing other softirqs and rt threads.
-So try to switch back to the default (64) weight.
-
-If this slows down someone's system we should investigate
-which part of stopping starting the NAPI poll in this
-driver are expensive.
-
-Reported-by: Mario Limonciello <mario.limonciello@amd.com>
-Link: https://lore.kernel.org/all/0bfd445a-81f7-f702-08b0-bd5a72095e49@amd.com/
-Acked-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230814153521.2697982-1-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -9784,8 +9784,7 @@ static int rtl8152_probe(struct usb_inte
-
- usb_set_intfdata(intf, tp);
-
-- netif_napi_add_weight(netdev, &tp->napi, r8152_poll,
-- tp->support_2500full ? 256 : 64);
-+ netif_napi_add(netdev, &tp->napi, r8152_poll);
-
- ret = register_netdev(netdev);
- if (ret != 0) {
diff --git a/target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch b/target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch
deleted file mode 100644
index 8901767be5..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch
+++ /dev/null
@@ -1,398 +0,0 @@
-From d9962b0d42029bcb40fe3c38bce06d1870fa4df4 Mon Sep 17 00:00:00 2001
-From: Douglas Anderson <dianders@chromium.org>
-Date: Fri, 20 Oct 2023 14:06:59 -0700
-Subject: [PATCH] r8152: Block future register access if register access fails
-
-Even though the functions to read/write registers can fail, most of
-the places in the r8152 driver that read/write register values don't
-check error codes. The lack of error code checking is problematic in
-at least two ways.
-
-The first problem is that the r8152 driver often uses code patterns
-similar to this:
- x = read_register()
- x = x | SOME_BIT;
- write_register(x);
-
-...with the above pattern, if the read_register() fails and returns
-garbage then we'll end up trying to write modified garbage back to the
-Realtek adapter. If the write_register() succeeds that's bad. Note
-that as of commit f53a7ad18959 ("r8152: Set memory to all 0xFFs on
-failed reg reads") the "garbage" returned by read_register() will at
-least be consistent garbage, but it is still garbage.
-
-It turns out that this problem is very serious. Writing garbage to
-some of the hardware registers on the Ethernet adapter can put the
-adapter in such a bad state that it needs to be power cycled (fully
-unplugged and plugged in again) before it can enumerate again.
-
-The second problem is that the r8152 driver generally has functions
-that are long sequences of register writes. Assuming everything will
-be OK if a random register write fails in the middle isn't a great
-assumption.
-
-One might wonder if the above two problems are real. You could ask if
-we would really have a successful write after a failed read. It turns
-out that the answer appears to be "yes, this can happen". In fact,
-we've seen at least two distinct failure modes where this happens.
-
-On a sc7180-trogdor Chromebook if you drop into kdb for a while and
-then resume, you can see:
-1. We get a "Tx timeout"
-2. The "Tx timeout" queues up a USB reset.
-3. In rtl8152_pre_reset() we try to reinit the hardware.
-4. The first several (2-9) register accesses fail with a timeout, then
- things recover.
-
-The above test case was actually fixed by the patch ("r8152: Increase
-USB control msg timeout to 5000ms as per spec") but at least shows
-that we really can see successful calls after failed ones.
-
-On a different (AMD) based Chromebook with a particular adapter, we
-found that during reboot tests we'd also sometimes get a transitory
-failure. In this case we saw -EPIPE being returned sometimes. Retrying
-worked, but retrying is not always safe for all register accesses
-since reading/writing some registers might have side effects (like
-registers that clear on read).
-
-Let's fully lock out all register access if a register access fails.
-When we do this, we'll try to queue up a USB reset and try to unlock
-register access after the reset. This is slightly tricker than it
-sounds since the r8152 driver has an optimized reset sequence that
-only works reliably after probe happens. In order to handle this, we
-avoid the optimized reset if probe didn't finish. Instead, we simply
-retry the probe routine in this case.
-
-When locking out access, we'll use the existing infrastructure that
-the driver was using when it detected we were unplugged. This keeps us
-from getting stuck in delay loops in some parts of the driver.
-
-Signed-off-by: Douglas Anderson <dianders@chromium.org>
-Reviewed-by: Grant Grundler <grundler@chromium.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/r8152.c | 207 ++++++++++++++++++++++++++++++++++------
- 1 file changed, 176 insertions(+), 31 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -772,6 +772,9 @@ enum rtl8152_flags {
- SCHEDULE_TASKLET,
- GREEN_ETHERNET,
- RX_EPROTO,
-+ IN_PRE_RESET,
-+ PROBED_WITH_NO_ERRORS,
-+ PROBE_SHOULD_RETRY,
- };
-
- #define DEVICE_ID_LENOVO_USB_C_TRAVEL_HUB 0x721e
-@@ -952,6 +955,8 @@ struct r8152 {
- u8 version;
- u8 duplex;
- u8 autoneg;
-+
-+ unsigned int reg_access_reset_count;
- };
-
- /**
-@@ -1199,6 +1204,96 @@ static unsigned int agg_buf_sz = 16384;
-
- #define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc))
-
-+/* If register access fails then we block access and issue a reset. If this
-+ * happens too many times in a row without a successful access then we stop
-+ * trying to reset and just leave access blocked.
-+ */
-+#define REGISTER_ACCESS_MAX_RESETS 3
-+
-+static void rtl_set_inaccessible(struct r8152 *tp)
-+{
-+ set_bit(RTL8152_INACCESSIBLE, &tp->flags);
-+ smp_mb__after_atomic();
-+}
-+
-+static void rtl_set_accessible(struct r8152 *tp)
-+{
-+ clear_bit(RTL8152_INACCESSIBLE, &tp->flags);
-+ smp_mb__after_atomic();
-+}
-+
-+static
-+int r8152_control_msg(struct r8152 *tp, unsigned int pipe, __u8 request,
-+ __u8 requesttype, __u16 value, __u16 index, void *data,
-+ __u16 size, const char *msg_tag)
-+{
-+ struct usb_device *udev = tp->udev;
-+ int ret;
-+
-+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
-+ return -ENODEV;
-+
-+ ret = usb_control_msg(udev, pipe, request, requesttype,
-+ value, index, data, size,
-+ USB_CTRL_GET_TIMEOUT);
-+
-+ /* No need to issue a reset to report an error if the USB device got
-+ * unplugged; just return immediately.
-+ */
-+ if (ret == -ENODEV)
-+ return ret;
-+
-+ /* If the write was successful then we're done */
-+ if (ret >= 0) {
-+ tp->reg_access_reset_count = 0;
-+ return ret;
-+ }
-+
-+ dev_err(&udev->dev,
-+ "Failed to %s %d bytes at %#06x/%#06x (%d)\n",
-+ msg_tag, size, value, index, ret);
-+
-+ /* Block all future register access until we reset. Much of the code
-+ * in the driver doesn't check for errors. Notably, many parts of the
-+ * driver do a read/modify/write of a register value without
-+ * confirming that the read succeeded. Writing back modified garbage
-+ * like this can fully wedge the adapter, requiring a power cycle.
-+ */
-+ rtl_set_inaccessible(tp);
-+
-+ /* If probe hasn't yet finished, then we'll request a retry of the
-+ * whole probe routine if we get any control transfer errors. We
-+ * never have to clear this bit since we free/reallocate the whole "tp"
-+ * structure if we retry probe.
-+ */
-+ if (!test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) {
-+ set_bit(PROBE_SHOULD_RETRY, &tp->flags);
-+ return ret;
-+ }
-+
-+ /* Failing to access registers in pre-reset is not surprising since we
-+ * wouldn't be resetting if things were behaving normally. The register
-+ * access we do in pre-reset isn't truly mandatory--we're just reusing
-+ * the disable() function and trying to be nice by powering the
-+ * adapter down before resetting it. Thus, if we're in pre-reset,
-+ * we'll return right away and not try to queue up yet another reset.
-+ * We know the post-reset is already coming.
-+ */
-+ if (test_bit(IN_PRE_RESET, &tp->flags))
-+ return ret;
-+
-+ if (tp->reg_access_reset_count < REGISTER_ACCESS_MAX_RESETS) {
-+ usb_queue_reset_device(tp->intf);
-+ tp->reg_access_reset_count++;
-+ } else if (tp->reg_access_reset_count == REGISTER_ACCESS_MAX_RESETS) {
-+ dev_err(&udev->dev,
-+ "Tried to reset %d times; giving up.\n",
-+ REGISTER_ACCESS_MAX_RESETS);
-+ }
-+
-+ return ret;
-+}
-+
- static
- int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
- {
-@@ -1209,9 +1304,10 @@ int get_registers(struct r8152 *tp, u16
- if (!tmp)
- return -ENOMEM;
-
-- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in,
-- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-- value, index, tmp, size, USB_CTRL_GET_TIMEOUT);
-+ ret = r8152_control_msg(tp, tp->pipe_ctrl_in,
-+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-+ value, index, tmp, size, "read");
-+
- if (ret < 0)
- memset(data, 0xff, size);
- else
-@@ -1232,9 +1328,9 @@ int set_registers(struct r8152 *tp, u16
- if (!tmp)
- return -ENOMEM;
-
-- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out,
-- RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
-- value, index, tmp, size, USB_CTRL_SET_TIMEOUT);
-+ ret = r8152_control_msg(tp, tp->pipe_ctrl_out,
-+ RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
-+ value, index, tmp, size, "write");
-
- kfree(tmp);
-
-@@ -1243,10 +1339,8 @@ int set_registers(struct r8152 *tp, u16
-
- static void rtl_set_unplug(struct r8152 *tp)
- {
-- if (tp->udev->state == USB_STATE_NOTATTACHED) {
-- set_bit(RTL8152_INACCESSIBLE, &tp->flags);
-- smp_mb__after_atomic();
-- }
-+ if (tp->udev->state == USB_STATE_NOTATTACHED)
-+ rtl_set_inaccessible(tp);
- }
-
- static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
-@@ -8275,7 +8369,7 @@ static int rtl8152_pre_reset(struct usb_
- struct r8152 *tp = usb_get_intfdata(intf);
- struct net_device *netdev;
-
-- if (!tp)
-+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
- return 0;
-
- netdev = tp->netdev;
-@@ -8290,7 +8384,9 @@ static int rtl8152_pre_reset(struct usb_
- napi_disable(&tp->napi);
- if (netif_carrier_ok(netdev)) {
- mutex_lock(&tp->control);
-+ set_bit(IN_PRE_RESET, &tp->flags);
- tp->rtl_ops.disable(tp);
-+ clear_bit(IN_PRE_RESET, &tp->flags);
- mutex_unlock(&tp->control);
- }
-
-@@ -8303,9 +8399,11 @@ static int rtl8152_post_reset(struct usb
- struct net_device *netdev;
- struct sockaddr sa;
-
-- if (!tp)
-+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
- return 0;
-
-+ rtl_set_accessible(tp);
-+
- /* reset the MAC address in case of policy change */
- if (determine_ethernet_addr(tp, &sa) >= 0) {
- rtnl_lock();
-@@ -9507,17 +9605,29 @@ static u8 __rtl_get_hw_ver(struct usb_de
- __le32 *tmp;
- u8 version;
- int ret;
-+ int i;
-
- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
- if (!tmp)
- return 0;
-
-- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-- PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp),
-- USB_CTRL_GET_TIMEOUT);
-- if (ret > 0)
-- ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK;
-+ /* Retry up to 3 times in case there is a transitory error. We do this
-+ * since retrying a read of the version is always safe and this
-+ * function doesn't take advantage of r8152_control_msg().
-+ */
-+ for (i = 0; i < 3; i++) {
-+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-+ PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp),
-+ USB_CTRL_GET_TIMEOUT);
-+ if (ret > 0) {
-+ ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK;
-+ break;
-+ }
-+ }
-+
-+ if (i != 0 && ret > 0)
-+ dev_warn(&udev->dev, "Needed %d retries to read version\n", i);
-
- kfree(tmp);
-
-@@ -9616,25 +9726,14 @@ static bool rtl8152_supports_lenovo_macp
- return 0;
- }
-
--static int rtl8152_probe(struct usb_interface *intf,
-- const struct usb_device_id *id)
-+static int rtl8152_probe_once(struct usb_interface *intf,
-+ const struct usb_device_id *id, u8 version)
- {
- struct usb_device *udev = interface_to_usbdev(intf);
- struct r8152 *tp;
- struct net_device *netdev;
-- u8 version;
- int ret;
-
-- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
-- return -ENODEV;
--
-- if (!rtl_check_vendor_ok(intf))
-- return -ENODEV;
--
-- version = rtl8152_get_version(intf);
-- if (version == RTL_VER_UNKNOWN)
-- return -ENODEV;
--
- usb_reset_device(udev);
- netdev = alloc_etherdev(sizeof(struct r8152));
- if (!netdev) {
-@@ -9797,10 +9896,20 @@ static int rtl8152_probe(struct usb_inte
- else
- device_set_wakeup_enable(&udev->dev, false);
-
-+ /* If we saw a control transfer error while probing then we may
-+ * want to try probe() again. Consider this an error.
-+ */
-+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
-+ goto out2;
-+
-+ set_bit(PROBED_WITH_NO_ERRORS, &tp->flags);
- netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION);
-
- return 0;
-
-+out2:
-+ unregister_netdev(netdev);
-+
- out1:
- tasklet_kill(&tp->tx_tl);
- cancel_delayed_work_sync(&tp->hw_phy_work);
-@@ -9809,10 +9918,46 @@ out1:
- rtl8152_release_firmware(tp);
- usb_set_intfdata(intf, NULL);
- out:
-+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
-+ ret = -EAGAIN;
-+
- free_netdev(netdev);
- return ret;
- }
-
-+#define RTL8152_PROBE_TRIES 3
-+
-+static int rtl8152_probe(struct usb_interface *intf,
-+ const struct usb_device_id *id)
-+{
-+ u8 version;
-+ int ret;
-+ int i;
-+
-+ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
-+ return -ENODEV;
-+
-+ if (!rtl_check_vendor_ok(intf))
-+ return -ENODEV;
-+
-+ version = rtl8152_get_version(intf);
-+ if (version == RTL_VER_UNKNOWN)
-+ return -ENODEV;
-+
-+ for (i = 0; i < RTL8152_PROBE_TRIES; i++) {
-+ ret = rtl8152_probe_once(intf, id, version);
-+ if (ret != -EAGAIN)
-+ break;
-+ }
-+ if (ret == -EAGAIN) {
-+ dev_err(&intf->dev,
-+ "r8152 failed probe after %d tries; giving up\n", i);
-+ return -ENODEV;
-+ }
-+
-+ return ret;
-+}
-+
- static void rtl8152_disconnect(struct usb_interface *intf)
- {
- struct r8152 *tp = usb_get_intfdata(intf);
diff --git a/target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch b/target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch
deleted file mode 100644
index 7bbd1be820..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 66eee612a1ba39f9a76a9ace4a34d012044767fb Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Tue, 26 Sep 2023 19:17:13 +0800
-Subject: [PATCH] r8152: break the loop when the budget is exhausted
-
-[ Upstream commit 2cf51f931797d9a47e75d999d0993a68cbd2a560 ]
-
-A bulk transfer of the USB may contain many packets. And, the total
-number of the packets in the bulk transfer may be more than budget.
-
-Originally, only budget packets would be handled by napi_gro_receive(),
-and the other packets would be queued in the driver for next schedule.
-
-This patch would break the loop about getting next bulk transfer, when
-the budget is exhausted. That is, only the current bulk transfer would
-be handled, and the other bulk transfers would be queued for next
-schedule. Besides, the packets which are more than the budget in the
-current bulk trasnfer would be still queued in the driver, as the
-original method.
-
-In addition, a bulk transfer wouldn't contain more than 400 packets, so
-the check of queue length is unnecessary. Therefore, I replace it with
-WARN_ON_ONCE().
-
-Fixes: cf74eb5a5bc8 ("eth: r8152: try to use a normal budget")
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230926111714.9448-433-nic_swsd@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/net/usb/r8152.c | 18 +++++++++++++-----
- 1 file changed, 13 insertions(+), 5 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -2542,7 +2542,7 @@ static int rx_bottom(struct r8152 *tp, i
- }
- }
-
-- if (list_empty(&tp->rx_done))
-+ if (list_empty(&tp->rx_done) || work_done >= budget)
- goto out1;
-
- clear_bit(RX_EPROTO, &tp->flags);
-@@ -2558,6 +2558,15 @@ static int rx_bottom(struct r8152 *tp, i
- struct urb *urb;
- u8 *rx_data;
-
-+ /* A bulk transfer of USB may contain may packets, so the
-+ * total packets may more than the budget. Deal with all
-+ * packets in current bulk transfer, and stop to handle the
-+ * next bulk transfer until next schedule, if budget is
-+ * exhausted.
-+ */
-+ if (work_done >= budget)
-+ break;
-+
- list_del_init(cursor);
-
- agg = list_entry(cursor, struct rx_agg, list);
-@@ -2577,9 +2586,7 @@ static int rx_bottom(struct r8152 *tp, i
- unsigned int pkt_len, rx_frag_head_sz;
- struct sk_buff *skb;
-
-- /* limit the skb numbers for rx_queue */
-- if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000))
-- break;
-+ WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000);
-
- pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
- if (pkt_len < ETH_ZLEN)
-@@ -2657,9 +2664,10 @@ submit:
- }
- }
-
-+ /* Splice the remained list back to rx_done for next schedule */
- if (!list_empty(&rx_queue)) {
- spin_lock_irqsave(&tp->rx_lock, flags);
-- list_splice_tail(&rx_queue, &tp->rx_done);
-+ list_splice(&rx_queue, &tp->rx_done);
- spin_unlock_irqrestore(&tp->rx_lock, flags);
- }
-
diff --git a/target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch b/target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch
deleted file mode 100644
index c858152067..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 1b0fce8c8e69485e49a7d34aac3d4c2a2aa15d62 Mon Sep 17 00:00:00 2001
-From: Davide Tronchin <davide.tronchin.94@gmail.com>
-Date: Thu, 29 Jun 2023 12:37:36 +0200
-Subject: [PATCH] net: usb: cdc_ether: add u-blox 0x1313 composition.
-
-Add CDC-ECM support for LARA-R6 01B.
-
-The new LARA-R6 product variant identified by the "01B" string can be
-configured (by AT interface) in three different USB modes:
-* Default mode (Vendor ID: 0x1546 Product ID: 0x1311) with 4 serial
-interfaces
-* RmNet mode (Vendor ID: 0x1546 Product ID: 0x1312) with 4 serial
-interfaces and 1 RmNet virtual network interface
-* CDC-ECM mode (Vendor ID: 0x1546 Product ID: 0x1313) with 4 serial
-interface and 1 CDC-ECM virtual network interface
-The first 4 interfaces of all the 3 configurations (default, RmNet, ECM)
-are the same.
-
-In CDC-ECM mode LARA-R6 01B exposes the following interfaces:
-If 0: Diagnostic
-If 1: AT parser
-If 2: AT parser
-If 3: AT parset/alternative functions
-If 4: CDC-ECM interface
-
-Signed-off-by: Davide Tronchin <davide.tronchin.94@gmail.com>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/cdc_ether.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/usb/cdc_ether.c
-+++ b/drivers/net/usb/cdc_ether.c
-@@ -879,6 +879,12 @@ static const struct usb_device_id produc
- USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long)&wwan_info,
- }, {
-+ /* U-blox LARA-R6 01B */
-+ USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1313, USB_CLASS_COMM,
-+ USB_CDC_SUBCLASS_ETHERNET,
-+ USB_CDC_PROTO_NONE),
-+ .driver_info = (unsigned long)&wwan_info,
-+}, {
- /* ZTE modules */
- USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_ETHERNET,
diff --git a/target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch b/target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch
deleted file mode 100644
index 3c9680a279..0000000000
--- a/target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 788d30daa8f97f06166b6a63f0e51f2a4c2f036a Mon Sep 17 00:00:00 2001
-From: Hayes Wang <hayeswang@realtek.com>
-Date: Tue, 26 Sep 2023 19:17:14 +0800
-Subject: [PATCH] r8152: use napi_gro_frags
-
-Use napi_gro_frags() for the skb of fragments when the work_done is less
-than budget.
-
-Signed-off-by: Hayes Wang <hayeswang@realtek.com>
-Link: https://lore.kernel.org/r/20230926111714.9448-434-nic_swsd@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/r8152.c | 67 ++++++++++++++++++++++++++++++-----------
- 1 file changed, 50 insertions(+), 17 deletions(-)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -2583,8 +2583,9 @@ static int rx_bottom(struct r8152 *tp, i
- while (urb->actual_length > len_used) {
- struct net_device *netdev = tp->netdev;
- struct net_device_stats *stats = &netdev->stats;
-- unsigned int pkt_len, rx_frag_head_sz;
-+ unsigned int pkt_len, rx_frag_head_sz, len;
- struct sk_buff *skb;
-+ bool use_frags;
-
- WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000);
-
-@@ -2597,45 +2598,77 @@ static int rx_bottom(struct r8152 *tp, i
- break;
-
- pkt_len -= ETH_FCS_LEN;
-+ len = pkt_len;
- rx_data += sizeof(struct rx_desc);
-
-- if (!agg_free || tp->rx_copybreak > pkt_len)
-- rx_frag_head_sz = pkt_len;
-+ if (!agg_free || tp->rx_copybreak > len)
-+ use_frags = false;
- else
-- rx_frag_head_sz = tp->rx_copybreak;
-+ use_frags = true;
-+
-+ if (use_frags) {
-+ /* If the budget is exhausted, the packet
-+ * would be queued in the driver. That is,
-+ * napi_gro_frags() wouldn't be called, so
-+ * we couldn't use napi_get_frags().
-+ */
-+ if (work_done >= budget) {
-+ rx_frag_head_sz = tp->rx_copybreak;
-+ skb = napi_alloc_skb(napi,
-+ rx_frag_head_sz);
-+ } else {
-+ rx_frag_head_sz = 0;
-+ skb = napi_get_frags(napi);
-+ }
-+ } else {
-+ rx_frag_head_sz = 0;
-+ skb = napi_alloc_skb(napi, len);
-+ }
-
-- skb = napi_alloc_skb(napi, rx_frag_head_sz);
- if (!skb) {
- stats->rx_dropped++;
- goto find_next_rx;
- }
-
- skb->ip_summed = r8152_rx_csum(tp, rx_desc);
-- memcpy(skb->data, rx_data, rx_frag_head_sz);
-- skb_put(skb, rx_frag_head_sz);
-- pkt_len -= rx_frag_head_sz;
-- rx_data += rx_frag_head_sz;
-- if (pkt_len) {
-+ rtl_rx_vlan_tag(rx_desc, skb);
-+
-+ if (use_frags) {
-+ if (rx_frag_head_sz) {
-+ memcpy(skb->data, rx_data,
-+ rx_frag_head_sz);
-+ skb_put(skb, rx_frag_head_sz);
-+ len -= rx_frag_head_sz;
-+ rx_data += rx_frag_head_sz;
-+ skb->protocol = eth_type_trans(skb,
-+ netdev);
-+ }
-+
- skb_add_rx_frag(skb, 0, agg->page,
- agg_offset(agg, rx_data),
-- pkt_len,
-- SKB_DATA_ALIGN(pkt_len));
-+ len, SKB_DATA_ALIGN(len));
- get_page(agg->page);
-+ } else {
-+ memcpy(skb->data, rx_data, len);
-+ skb_put(skb, len);
-+ skb->protocol = eth_type_trans(skb, netdev);
- }
-
-- skb->protocol = eth_type_trans(skb, netdev);
-- rtl_rx_vlan_tag(rx_desc, skb);
- if (work_done < budget) {
-+ if (use_frags)
-+ napi_gro_frags(napi);
-+ else
-+ napi_gro_receive(napi, skb);
-+
- work_done++;
- stats->rx_packets++;
-- stats->rx_bytes += skb->len;
-- napi_gro_receive(napi, skb);
-+ stats->rx_bytes += pkt_len;
- } else {
- __skb_queue_tail(&tp->rx_queue, skb);
- }
-
- find_next_rx:
-- rx_data = rx_agg_align(rx_data + pkt_len + ETH_FCS_LEN);
-+ rx_data = rx_agg_align(rx_data + len + ETH_FCS_LEN);
- rx_desc = (struct rx_desc *)rx_data;
- len_used = agg_offset(agg, rx_data);
- len_used += sizeof(struct rx_desc);
diff --git a/target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch b/target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch
deleted file mode 100644
index d9d6f36fce..0000000000
--- a/target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 2203718c2f59ffdd6c78d54e5add594aebb4461e Mon Sep 17 00:00:00 2001
-From: Georgi Valkov <gvalkov@gmail.com>
-Date: Wed, 7 Jun 2023 15:56:59 +0200
-Subject: [PATCH 1/4] usbnet: ipheth: fix risk of NULL pointer deallocation
-
-The cleanup precedure in ipheth_probe will attempt to free a
-NULL pointer in dev->ctrl_buf if the memory allocation for
-this buffer is not successful. While kfree ignores NULL pointers,
-and the existing code is safe, it is a better design to rearrange
-the goto labels and avoid this.
-
-Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/ipheth.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/usb/ipheth.c
-+++ b/drivers/net/usb/ipheth.c
-@@ -510,8 +510,8 @@ err_register_netdev:
- ipheth_free_urbs(dev);
- err_alloc_urbs:
- err_get_macaddr:
--err_alloc_ctrl_buf:
- kfree(dev->ctrl_buf);
-+err_alloc_ctrl_buf:
- err_endpoints:
- free_netdev(netdev);
- return retval;
diff --git a/target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch b/target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch
deleted file mode 100644
index adfec356d9..0000000000
--- a/target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 3e65efcca87a9bb5f3b864e0a43d167bc0a8688c Mon Sep 17 00:00:00 2001
-From: Foster Snowhill <forst@pen.gy>
-Date: Wed, 7 Jun 2023 15:57:00 +0200
-Subject: [PATCH 2/4] usbnet: ipheth: transmit URBs without trailing padding
-
-The behaviour of the official iOS tethering driver on macOS is to not
-transmit any trailing padding at the end of URBs. This is applicable
-to both NCM and legacy modes, including older devices.
-
-Adapt the driver to not include trailing padding in TX URBs, matching
-the behaviour of the official macOS driver.
-
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Tested-by: Georgi Valkov <gvalkov@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/ipheth.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/usb/ipheth.c
-+++ b/drivers/net/usb/ipheth.c
-@@ -373,12 +373,10 @@ static netdev_tx_t ipheth_tx(struct sk_b
- }
-
- memcpy(dev->tx_buf, skb->data, skb->len);
-- if (skb->len < IPHETH_BUF_SIZE)
-- memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
-
- usb_fill_bulk_urb(dev->tx_urb, udev,
- usb_sndbulkpipe(udev, dev->bulk_out),
-- dev->tx_buf, IPHETH_BUF_SIZE,
-+ dev->tx_buf, skb->len,
- ipheth_sndbulk_callback,
- dev);
- dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
diff --git a/target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch b/target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch
deleted file mode 100644
index e3f2b9c331..0000000000
--- a/target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch
+++ /dev/null
@@ -1,326 +0,0 @@
-From a2d274c62e44b1995c170595db3865c6fe701226 Mon Sep 17 00:00:00 2001
-From: Foster Snowhill <forst@pen.gy>
-Date: Wed, 7 Jun 2023 15:57:01 +0200
-Subject: [PATCH 3/4] usbnet: ipheth: add CDC NCM support
-
-Recent iOS releases support CDC NCM encapsulation on RX. This mode is
-the default on macOS and Windows. In this mode, an iOS device may include
-one or more Ethernet frames inside a single URB.
-
-Freshly booted iOS devices start in legacy mode, but are put into
-NCM mode by the official Apple driver. When reconnecting such a device
-from a macOS/Windows machine to a Linux host, the device stays in
-NCM mode, making it unusable with the legacy ipheth driver code.
-
-To correctly support such a device, the driver has to either support
-the NCM mode too, or put the device back into legacy mode.
-
-To match the behaviour of the macOS/Windows driver, and since there
-is no documented control command to revert to legacy mode, implement
-NCM support. The device is attempted to be put into NCM mode by default,
-and falls back to legacy mode if the attempt fails.
-
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Tested-by: Georgi Valkov <gvalkov@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/ipheth.c | 180 +++++++++++++++++++++++++++++++++------
- 1 file changed, 155 insertions(+), 25 deletions(-)
-
---- a/drivers/net/usb/ipheth.c
-+++ b/drivers/net/usb/ipheth.c
-@@ -52,6 +52,7 @@
- #include <linux/ethtool.h>
- #include <linux/usb.h>
- #include <linux/workqueue.h>
-+#include <linux/usb/cdc.h>
-
- #define USB_VENDOR_APPLE 0x05ac
-
-@@ -59,8 +60,12 @@
- #define IPHETH_USBINTF_SUBCLASS 253
- #define IPHETH_USBINTF_PROTO 1
-
--#define IPHETH_BUF_SIZE 1514
- #define IPHETH_IP_ALIGN 2 /* padding at front of URB */
-+#define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */
-+#define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN
-+#define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN)
-+#define IPHETH_RX_BUF_SIZE_NCM 65536
-+
- #define IPHETH_TX_TIMEOUT (5 * HZ)
-
- #define IPHETH_INTFNUM 2
-@@ -71,6 +76,7 @@
- #define IPHETH_CTRL_TIMEOUT (5 * HZ)
-
- #define IPHETH_CMD_GET_MACADDR 0x00
-+#define IPHETH_CMD_ENABLE_NCM 0x04
- #define IPHETH_CMD_CARRIER_CHECK 0x45
-
- #define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
-@@ -97,6 +103,8 @@ struct ipheth_device {
- u8 bulk_out;
- struct delayed_work carrier_work;
- bool confirmed_pairing;
-+ int (*rcvbulk_callback)(struct urb *urb);
-+ size_t rx_buf_len;
- };
-
- static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
-@@ -116,12 +124,12 @@ static int ipheth_alloc_urbs(struct iphe
- if (rx_urb == NULL)
- goto free_tx_urb;
-
-- tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
-+ tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_TX_BUF_SIZE,
- GFP_KERNEL, &tx_urb->transfer_dma);
- if (tx_buf == NULL)
- goto free_rx_urb;
-
-- rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
-+ rx_buf = usb_alloc_coherent(iphone->udev, iphone->rx_buf_len,
- GFP_KERNEL, &rx_urb->transfer_dma);
- if (rx_buf == NULL)
- goto free_tx_buf;
-@@ -134,7 +142,7 @@ static int ipheth_alloc_urbs(struct iphe
- return 0;
-
- free_tx_buf:
-- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
-+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, tx_buf,
- tx_urb->transfer_dma);
- free_rx_urb:
- usb_free_urb(rx_urb);
-@@ -146,9 +154,9 @@ error_nomem:
-
- static void ipheth_free_urbs(struct ipheth_device *iphone)
- {
-- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf,
-+ usb_free_coherent(iphone->udev, iphone->rx_buf_len, iphone->rx_buf,
- iphone->rx_urb->transfer_dma);
-- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
-+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, iphone->tx_buf,
- iphone->tx_urb->transfer_dma);
- usb_free_urb(iphone->rx_urb);
- usb_free_urb(iphone->tx_urb);
-@@ -160,15 +168,106 @@ static void ipheth_kill_urbs(struct iphe
- usb_kill_urb(dev->rx_urb);
- }
-
--static void ipheth_rcvbulk_callback(struct urb *urb)
-+static int ipheth_consume_skb(char *buf, int len, struct ipheth_device *dev)
- {
-- struct ipheth_device *dev;
- struct sk_buff *skb;
-- int status;
-+
-+ skb = dev_alloc_skb(len);
-+ if (!skb) {
-+ dev->net->stats.rx_dropped++;
-+ return -ENOMEM;
-+ }
-+
-+ skb_put_data(skb, buf, len);
-+ skb->dev = dev->net;
-+ skb->protocol = eth_type_trans(skb, dev->net);
-+
-+ dev->net->stats.rx_packets++;
-+ dev->net->stats.rx_bytes += len;
-+ netif_rx(skb);
-+
-+ return 0;
-+}
-+
-+static int ipheth_rcvbulk_callback_legacy(struct urb *urb)
-+{
-+ struct ipheth_device *dev;
-+ char *buf;
-+ int len;
-+
-+ dev = urb->context;
-+
-+ if (urb->actual_length <= IPHETH_IP_ALIGN) {
-+ dev->net->stats.rx_length_errors++;
-+ return -EINVAL;
-+ }
-+ len = urb->actual_length - IPHETH_IP_ALIGN;
-+ buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
-+
-+ return ipheth_consume_skb(buf, len, dev);
-+}
-+
-+static int ipheth_rcvbulk_callback_ncm(struct urb *urb)
-+{
-+ struct usb_cdc_ncm_nth16 *ncmh;
-+ struct usb_cdc_ncm_ndp16 *ncm0;
-+ struct usb_cdc_ncm_dpe16 *dpe;
-+ struct ipheth_device *dev;
-+ int retval = -EINVAL;
- char *buf;
- int len;
-
- dev = urb->context;
-+
-+ if (urb->actual_length < IPHETH_NCM_HEADER_SIZE) {
-+ dev->net->stats.rx_length_errors++;
-+ return retval;
-+ }
-+
-+ ncmh = urb->transfer_buffer;
-+ if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) ||
-+ le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) {
-+ dev->net->stats.rx_errors++;
-+ return retval;
-+ }
-+
-+ ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex);
-+ if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) ||
-+ le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >=
-+ urb->actual_length) {
-+ dev->net->stats.rx_errors++;
-+ return retval;
-+ }
-+
-+ dpe = ncm0->dpe16;
-+ while (le16_to_cpu(dpe->wDatagramIndex) != 0 &&
-+ le16_to_cpu(dpe->wDatagramLength) != 0) {
-+ if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length ||
-+ le16_to_cpu(dpe->wDatagramIndex) +
-+ le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) {
-+ dev->net->stats.rx_length_errors++;
-+ return retval;
-+ }
-+
-+ buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex);
-+ len = le16_to_cpu(dpe->wDatagramLength);
-+
-+ retval = ipheth_consume_skb(buf, len, dev);
-+ if (retval != 0)
-+ return retval;
-+
-+ dpe++;
-+ }
-+
-+ return 0;
-+}
-+
-+static void ipheth_rcvbulk_callback(struct urb *urb)
-+{
-+ struct ipheth_device *dev;
-+ int retval, status;
-+
-+ dev = urb->context;
- if (dev == NULL)
- return;
-
-@@ -191,25 +290,27 @@ static void ipheth_rcvbulk_callback(stru
- dev->net->stats.rx_length_errors++;
- return;
- }
-- len = urb->actual_length - IPHETH_IP_ALIGN;
-- buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
-
-- skb = dev_alloc_skb(len);
-- if (!skb) {
-- dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n",
-- __func__);
-- dev->net->stats.rx_dropped++;
-+ /* RX URBs starting with 0x00 0x01 do not encapsulate Ethernet frames,
-+ * but rather are control frames. Their purpose is not documented, and
-+ * they don't affect driver functionality, okay to drop them.
-+ * There is usually just one 4-byte control frame as the very first
-+ * URB received from the bulk IN endpoint.
-+ */
-+ if (unlikely
-+ (((char *)urb->transfer_buffer)[0] == 0 &&
-+ ((char *)urb->transfer_buffer)[1] == 1))
-+ goto rx_submit;
-+
-+ retval = dev->rcvbulk_callback(urb);
-+ if (retval != 0) {
-+ dev_err(&dev->intf->dev, "%s: callback retval: %d\n",
-+ __func__, retval);
- return;
- }
-
-- skb_put_data(skb, buf, len);
-- skb->dev = dev->net;
-- skb->protocol = eth_type_trans(skb, dev->net);
--
-- dev->net->stats.rx_packets++;
-- dev->net->stats.rx_bytes += len;
-+rx_submit:
- dev->confirmed_pairing = true;
-- netif_rx(skb);
- ipheth_rx_submit(dev, GFP_ATOMIC);
- }
-
-@@ -310,6 +411,27 @@ static int ipheth_get_macaddr(struct iph
- return retval;
- }
-
-+static int ipheth_enable_ncm(struct ipheth_device *dev)
-+{
-+ struct usb_device *udev = dev->udev;
-+ int retval;
-+
-+ retval = usb_control_msg(udev,
-+ usb_sndctrlpipe(udev, IPHETH_CTRL_ENDP),
-+ IPHETH_CMD_ENABLE_NCM, /* request */
-+ 0x41, /* request type */
-+ 0x00, /* value */
-+ 0x02, /* index */
-+ NULL,
-+ 0,
-+ IPHETH_CTRL_TIMEOUT);
-+
-+ dev_info(&dev->intf->dev, "%s: usb_control_msg: %d\n",
-+ __func__, retval);
-+
-+ return retval;
-+}
-+
- static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
- {
- struct usb_device *udev = dev->udev;
-@@ -317,7 +439,7 @@ static int ipheth_rx_submit(struct iphet
-
- usb_fill_bulk_urb(dev->rx_urb, udev,
- usb_rcvbulkpipe(udev, dev->bulk_in),
-- dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
-+ dev->rx_buf, dev->rx_buf_len,
- ipheth_rcvbulk_callback,
- dev);
- dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-@@ -365,7 +487,7 @@ static netdev_tx_t ipheth_tx(struct sk_b
- int retval;
-
- /* Paranoid */
-- if (skb->len > IPHETH_BUF_SIZE) {
-+ if (skb->len > IPHETH_TX_BUF_SIZE) {
- WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
- dev->net->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
-@@ -448,6 +570,8 @@ static int ipheth_probe(struct usb_inter
- dev->net = netdev;
- dev->intf = intf;
- dev->confirmed_pairing = false;
-+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_LEGACY;
-+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_legacy;
- /* Set up endpoints */
- hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
- if (hintf == NULL) {
-@@ -479,6 +603,12 @@ static int ipheth_probe(struct usb_inter
- if (retval)
- goto err_get_macaddr;
-
-+ retval = ipheth_enable_ncm(dev);
-+ if (!retval) {
-+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_NCM;
-+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_ncm;
-+ }
-+
- INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
-
- retval = ipheth_alloc_urbs(dev);
diff --git a/target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch b/target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch
deleted file mode 100644
index 9089c4d8c3..0000000000
--- a/target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0c6e9d32ef0ccfcf2d875cbcff23bf345a54d585 Mon Sep 17 00:00:00 2001
-From: Foster Snowhill <forst@pen.gy>
-Date: Wed, 7 Jun 2023 15:57:02 +0200
-Subject: [PATCH 4/4] usbnet: ipheth: update Kconfig description
-
-This module has for a long time not been limited to iPhone <= 3GS.
-Update description to match the actual state of the driver.
-
-Remove dead link from 2010, instead reference an existing userspace
-iOS device pairing implementation as part of libimobiledevice.
-
-Signed-off-by: Foster Snowhill <forst@pen.gy>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/Kconfig | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
---- a/drivers/net/usb/Kconfig
-+++ b/drivers/net/usb/Kconfig
-@@ -583,12 +583,10 @@ config USB_IPHETH
- default n
- help
- Module used to share Internet connection (tethering) from your
-- iPhone (Original, 3G and 3GS) to your system.
-- Note that you need userspace libraries and programs that are needed
-- to pair your device with your system and that understand the iPhone
-- protocol.
--
-- For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
-+ iPhone to your system.
-+ Note that you need a corresponding userspace library/program
-+ to pair your device with your system, for example usbmuxd
-+ <https://github.com/libimobiledevice/usbmuxd>.
-
- config USB_SIERRA_NET
- tristate "USB-to-WWAN Driver for Sierra Wireless modems"
diff --git a/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch b/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch
deleted file mode 100644
index 36083bbaf5..0000000000
--- a/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From b3f1a164c7f742503dc7159011f7ad6b092b660e Mon Sep 17 00:00:00 2001
-From: Greg Ungerer <gerg@kernel.org>
-Date: Fri, 24 Nov 2023 14:15:28 +1000
-Subject: [PATCH] net: dsa: mv88e6xxx: fix marvell 6350 switch probing
-
-As of commit de5c9bf40c45 ("net: phylink: require supported_interfaces to
-be filled") Marvell 88e6350 switches fail to be probed:
-
- ...
- mv88e6085 d0072004.mdio-mii:11: switch 0x3710 detected: Marvell 88E6350, revision 2
- mv88e6085 d0072004.mdio-mii:11: phylink: error: empty supported_interfaces
- error creating PHYLINK: -22
- mv88e6085: probe of d0072004.mdio-mii:11 failed with error -22
- ...
-
-The problem stems from the use of mv88e6185_phylink_get_caps() to get
-the device capabilities. Create a new dedicated phylink_get_caps for the
-6351 family (which the 6350 is one of) to properly support their set of
-capabilities.
-
-According to chip.h the 6351 switch family includes the 6171, 6175, 6350
-and 6351 switches, so update each of these to use the correct
-phylink_get_caps.
-
-Fixes: de5c9bf40c45 ("net: phylink: require supported_interfaces to be filled")
-Signed-off-by: Greg Ungerer <gerg@kernel.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 20 ++++++++++++++++----
- 1 file changed, 16 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -652,6 +652,18 @@ static void mv88e6250_phylink_get_caps(s
- config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
- }
-
-+static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-+ struct phylink_config *config)
-+{
-+ unsigned long *supported = config->supported_interfaces;
-+
-+ /* Translate the default cmode */
-+ mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
-+
-+ config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
-+ MAC_1000FD;
-+}
-+
- static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
- {
- u16 reg, val;
-@@ -4501,7 +4513,7 @@ static const struct mv88e6xxx_ops mv88e6
- .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
- .stu_getnext = mv88e6352_g1_stu_getnext,
- .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
-- .phylink_get_caps = mv88e6185_phylink_get_caps,
-+ .phylink_get_caps = mv88e6351_phylink_get_caps,
- };
-
- static const struct mv88e6xxx_ops mv88e6172_ops = {
-@@ -4604,7 +4616,7 @@ static const struct mv88e6xxx_ops mv88e6
- .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
- .stu_getnext = mv88e6352_g1_stu_getnext,
- .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
-- .phylink_get_caps = mv88e6185_phylink_get_caps,
-+ .phylink_get_caps = mv88e6351_phylink_get_caps,
- };
-
- static const struct mv88e6xxx_ops mv88e6176_ops = {
-@@ -5281,7 +5293,7 @@ static const struct mv88e6xxx_ops mv88e6
- .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
- .stu_getnext = mv88e6352_g1_stu_getnext,
- .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
-- .phylink_get_caps = mv88e6185_phylink_get_caps,
-+ .phylink_get_caps = mv88e6351_phylink_get_caps,
- };
-
- static const struct mv88e6xxx_ops mv88e6351_ops = {
-@@ -5327,7 +5339,7 @@ static const struct mv88e6xxx_ops mv88e6
- .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
- .avb_ops = &mv88e6352_avb_ops,
- .ptp_ops = &mv88e6352_ptp_ops,
-- .phylink_get_caps = mv88e6185_phylink_get_caps,
-+ .phylink_get_caps = mv88e6351_phylink_get_caps,
- };
-
- static const struct mv88e6xxx_ops mv88e6352_ops = {
diff --git a/target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch b/target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch
deleted file mode 100644
index 7f963b3cf6..0000000000
--- a/target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch
+++ /dev/null
@@ -1,1140 +0,0 @@
-From 71e79430117d56c409c5ea485a263bc0d8083390 Mon Sep 17 00:00:00 2001
-From: Eric Woudstra <ericwouds@gmail.com>
-Date: Tue, 26 Mar 2024 17:23:05 +0100
-Subject: [PATCH] net: phy: air_en8811h: Add the Airoha EN8811H PHY driver
-
-Add the driver for the Airoha EN8811H 2.5 Gigabit PHY. The phy supports
-100/1000/2500 Mbps with auto negotiation only.
-
-The driver uses two firmware files, for which updated versions are added to
-linux-firmware already.
-
-Note: At phy-address + 8 there is another device on the mdio bus, that
-belongs to the EN881H. While the original driver writes to it, Airoha
-has confirmed this is not needed. Therefore, communication with this
-device is not included in this driver.
-
-Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240326162305.303598-3-ericwouds@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/Kconfig | 5 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/air_en8811h.c | 1086 +++++++++++++++++++++++++++++++++
- 3 files changed, 1092 insertions(+)
- create mode 100644 drivers/net/phy/air_en8811h.c
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -63,6 +63,11 @@ config SFP
-
- comment "MII PHY device drivers"
-
-+config AIR_EN8811H_PHY
-+ tristate "Airoha EN8811H 2.5 Gigabit PHY"
-+ help
-+ Currently supports the Airoha EN8811H PHY.
-+
- config AMD_PHY
- tristate "AMD PHYs"
- help
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -32,6 +32,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
-
- obj-$(CONFIG_ADIN_PHY) += adin.o
- obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
-+obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o
- obj-$(CONFIG_AMD_PHY) += amd.o
- obj-$(CONFIG_AQUANTIA_PHY) += aquantia/
- obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
---- /dev/null
-+++ b/drivers/net/phy/air_en8811h.c
-@@ -0,0 +1,1086 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Driver for the Airoha EN8811H 2.5 Gigabit PHY.
-+ *
-+ * Limitations of the EN8811H:
-+ * - Only full duplex supported
-+ * - Forced speed (AN off) is not supported by hardware (100Mbps)
-+ *
-+ * Source originated from airoha's en8811h.c and en8811h.h v1.2.1
-+ *
-+ * Copyright (C) 2023 Airoha Technology Corp.
-+ */
-+
-+#include <linux/phy.h>
-+#include <linux/firmware.h>
-+#include <linux/property.h>
-+#include <linux/wordpart.h>
-+#include <asm/unaligned.h>
-+
-+#define EN8811H_PHY_ID 0x03a2a411
-+
-+#define EN8811H_MD32_DM "airoha/EthMD32.dm.bin"
-+#define EN8811H_MD32_DSP "airoha/EthMD32.DSP.bin"
-+
-+#define AIR_FW_ADDR_DM 0x00000000
-+#define AIR_FW_ADDR_DSP 0x00100000
-+
-+/* MII Registers */
-+#define AIR_AUX_CTRL_STATUS 0x1d
-+#define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2)
-+#define AIR_AUX_CTRL_STATUS_SPEED_100 0x4
-+#define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8
-+#define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc
-+
-+#define AIR_EXT_PAGE_ACCESS 0x1f
-+#define AIR_PHY_PAGE_STANDARD 0x0000
-+#define AIR_PHY_PAGE_EXTENDED_4 0x0004
-+
-+/* MII Registers Page 4*/
-+#define AIR_BPBUS_MODE 0x10
-+#define AIR_BPBUS_MODE_ADDR_FIXED 0x0000
-+#define AIR_BPBUS_MODE_ADDR_INCR BIT(15)
-+#define AIR_BPBUS_WR_ADDR_HIGH 0x11
-+#define AIR_BPBUS_WR_ADDR_LOW 0x12
-+#define AIR_BPBUS_WR_DATA_HIGH 0x13
-+#define AIR_BPBUS_WR_DATA_LOW 0x14
-+#define AIR_BPBUS_RD_ADDR_HIGH 0x15
-+#define AIR_BPBUS_RD_ADDR_LOW 0x16
-+#define AIR_BPBUS_RD_DATA_HIGH 0x17
-+#define AIR_BPBUS_RD_DATA_LOW 0x18
-+
-+/* Registers on MDIO_MMD_VEND1 */
-+#define EN8811H_PHY_FW_STATUS 0x8009
-+#define EN8811H_PHY_READY 0x02
-+
-+#define AIR_PHY_MCU_CMD_1 0x800c
-+#define AIR_PHY_MCU_CMD_1_MODE1 0x0
-+#define AIR_PHY_MCU_CMD_2 0x800d
-+#define AIR_PHY_MCU_CMD_2_MODE1 0x0
-+#define AIR_PHY_MCU_CMD_3 0x800e
-+#define AIR_PHY_MCU_CMD_3_MODE1 0x1101
-+#define AIR_PHY_MCU_CMD_3_DOCMD 0x1100
-+#define AIR_PHY_MCU_CMD_4 0x800f
-+#define AIR_PHY_MCU_CMD_4_MODE1 0x0002
-+#define AIR_PHY_MCU_CMD_4_INTCLR 0x00e4
-+
-+/* Registers on MDIO_MMD_VEND2 */
-+#define AIR_PHY_LED_BCR 0x021
-+#define AIR_PHY_LED_BCR_MODE_MASK GENMASK(1, 0)
-+#define AIR_PHY_LED_BCR_TIME_TEST BIT(2)
-+#define AIR_PHY_LED_BCR_CLK_EN BIT(3)
-+#define AIR_PHY_LED_BCR_EXT_CTRL BIT(15)
-+
-+#define AIR_PHY_LED_DUR_ON 0x022
-+
-+#define AIR_PHY_LED_DUR_BLINK 0x023
-+
-+#define AIR_PHY_LED_ON(i) (0x024 + ((i) * 2))
-+#define AIR_PHY_LED_ON_MASK (GENMASK(6, 0) | BIT(8))
-+#define AIR_PHY_LED_ON_LINK1000 BIT(0)
-+#define AIR_PHY_LED_ON_LINK100 BIT(1)
-+#define AIR_PHY_LED_ON_LINK10 BIT(2)
-+#define AIR_PHY_LED_ON_LINKDOWN BIT(3)
-+#define AIR_PHY_LED_ON_FDX BIT(4) /* Full duplex */
-+#define AIR_PHY_LED_ON_HDX BIT(5) /* Half duplex */
-+#define AIR_PHY_LED_ON_FORCE_ON BIT(6)
-+#define AIR_PHY_LED_ON_LINK2500 BIT(8)
-+#define AIR_PHY_LED_ON_POLARITY BIT(14)
-+#define AIR_PHY_LED_ON_ENABLE BIT(15)
-+
-+#define AIR_PHY_LED_BLINK(i) (0x025 + ((i) * 2))
-+#define AIR_PHY_LED_BLINK_1000TX BIT(0)
-+#define AIR_PHY_LED_BLINK_1000RX BIT(1)
-+#define AIR_PHY_LED_BLINK_100TX BIT(2)
-+#define AIR_PHY_LED_BLINK_100RX BIT(3)
-+#define AIR_PHY_LED_BLINK_10TX BIT(4)
-+#define AIR_PHY_LED_BLINK_10RX BIT(5)
-+#define AIR_PHY_LED_BLINK_COLLISION BIT(6)
-+#define AIR_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
-+#define AIR_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
-+#define AIR_PHY_LED_BLINK_FORCE_BLINK BIT(9)
-+#define AIR_PHY_LED_BLINK_2500TX BIT(10)
-+#define AIR_PHY_LED_BLINK_2500RX BIT(11)
-+
-+/* Registers on BUCKPBUS */
-+#define EN8811H_2P5G_LPA 0x3b30
-+#define EN8811H_2P5G_LPA_2P5G BIT(0)
-+
-+#define EN8811H_FW_VERSION 0x3b3c
-+
-+#define EN8811H_POLARITY 0xca0f8
-+#define EN8811H_POLARITY_TX_NORMAL BIT(0)
-+#define EN8811H_POLARITY_RX_REVERSE BIT(1)
-+
-+#define EN8811H_GPIO_OUTPUT 0xcf8b8
-+#define EN8811H_GPIO_OUTPUT_345 (BIT(3) | BIT(4) | BIT(5))
-+
-+#define EN8811H_FW_CTRL_1 0x0f0018
-+#define EN8811H_FW_CTRL_1_START 0x0
-+#define EN8811H_FW_CTRL_1_FINISH 0x1
-+#define EN8811H_FW_CTRL_2 0x800000
-+#define EN8811H_FW_CTRL_2_LOADING BIT(11)
-+
-+/* Led definitions */
-+#define EN8811H_LED_COUNT 3
-+
-+/* Default LED setup:
-+ * GPIO5 <-> LED0 On: Link detected, blink Rx/Tx
-+ * GPIO4 <-> LED1 On: Link detected at 2500 or 1000 Mbps
-+ * GPIO3 <-> LED2 On: Link detected at 2500 or 100 Mbps
-+ */
-+#define AIR_DEFAULT_TRIGGER_LED0 (BIT(TRIGGER_NETDEV_LINK) | \
-+ BIT(TRIGGER_NETDEV_RX) | \
-+ BIT(TRIGGER_NETDEV_TX))
-+#define AIR_DEFAULT_TRIGGER_LED1 (BIT(TRIGGER_NETDEV_LINK_2500) | \
-+ BIT(TRIGGER_NETDEV_LINK_1000))
-+#define AIR_DEFAULT_TRIGGER_LED2 (BIT(TRIGGER_NETDEV_LINK_2500) | \
-+ BIT(TRIGGER_NETDEV_LINK_100))
-+
-+struct led {
-+ unsigned long rules;
-+ unsigned long state;
-+};
-+
-+struct en8811h_priv {
-+ u32 firmware_version;
-+ bool mcu_needs_restart;
-+ struct led led[EN8811H_LED_COUNT];
-+};
-+
-+enum {
-+ AIR_PHY_LED_STATE_FORCE_ON,
-+ AIR_PHY_LED_STATE_FORCE_BLINK,
-+};
-+
-+enum {
-+ AIR_PHY_LED_DUR_BLINK_32MS,
-+ AIR_PHY_LED_DUR_BLINK_64MS,
-+ AIR_PHY_LED_DUR_BLINK_128MS,
-+ AIR_PHY_LED_DUR_BLINK_256MS,
-+ AIR_PHY_LED_DUR_BLINK_512MS,
-+ AIR_PHY_LED_DUR_BLINK_1024MS,
-+};
-+
-+enum {
-+ AIR_LED_DISABLE,
-+ AIR_LED_ENABLE,
-+};
-+
-+enum {
-+ AIR_ACTIVE_LOW,
-+ AIR_ACTIVE_HIGH,
-+};
-+
-+enum {
-+ AIR_LED_MODE_DISABLE,
-+ AIR_LED_MODE_USER_DEFINE,
-+};
-+
-+#define AIR_PHY_LED_DUR_UNIT 1024
-+#define AIR_PHY_LED_DUR (AIR_PHY_LED_DUR_UNIT << AIR_PHY_LED_DUR_BLINK_64MS)
-+
-+static const unsigned long en8811h_led_trig = BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
-+ BIT(TRIGGER_NETDEV_LINK) |
-+ BIT(TRIGGER_NETDEV_LINK_10) |
-+ BIT(TRIGGER_NETDEV_LINK_100) |
-+ BIT(TRIGGER_NETDEV_LINK_1000) |
-+ BIT(TRIGGER_NETDEV_LINK_2500) |
-+ BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX);
-+
-+static int air_phy_read_page(struct phy_device *phydev)
-+{
-+ return __phy_read(phydev, AIR_EXT_PAGE_ACCESS);
-+}
-+
-+static int air_phy_write_page(struct phy_device *phydev, int page)
-+{
-+ return __phy_write(phydev, AIR_EXT_PAGE_ACCESS, page);
-+}
-+
-+static int __air_buckpbus_reg_write(struct phy_device *phydev,
-+ u32 pbus_address, u32 pbus_data)
-+{
-+ int ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH,
-+ upper_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW,
-+ lower_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH,
-+ upper_16_bits(pbus_data));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW,
-+ lower_16_bits(pbus_data));
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int air_buckpbus_reg_write(struct phy_device *phydev,
-+ u32 pbus_address, u32 pbus_data)
-+{
-+ int saved_page;
-+ int ret = 0;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ if (saved_page >= 0) {
-+ ret = __air_buckpbus_reg_write(phydev, pbus_address,
-+ pbus_data);
-+ if (ret < 0)
-+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
-+ pbus_address, ret);
-+ }
-+
-+ return phy_restore_page(phydev, saved_page, ret);
-+}
-+
-+static int __air_buckpbus_reg_read(struct phy_device *phydev,
-+ u32 pbus_address, u32 *pbus_data)
-+{
-+ int pbus_data_low, pbus_data_high;
-+ int ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_HIGH,
-+ upper_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_LOW,
-+ lower_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
-+ if (pbus_data_high < 0)
-+ return ret;
-+
-+ pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
-+ if (pbus_data_low < 0)
-+ return ret;
-+
-+ *pbus_data = pbus_data_low | (pbus_data_high << 16);
-+ return 0;
-+}
-+
-+static int air_buckpbus_reg_read(struct phy_device *phydev,
-+ u32 pbus_address, u32 *pbus_data)
-+{
-+ int saved_page;
-+ int ret = 0;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ if (saved_page >= 0) {
-+ ret = __air_buckpbus_reg_read(phydev, pbus_address, pbus_data);
-+ if (ret < 0)
-+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
-+ pbus_address, ret);
-+ }
-+
-+ return phy_restore_page(phydev, saved_page, ret);
-+}
-+
-+static int __air_buckpbus_reg_modify(struct phy_device *phydev,
-+ u32 pbus_address, u32 mask, u32 set)
-+{
-+ int pbus_data_low, pbus_data_high;
-+ u32 pbus_data_old, pbus_data_new;
-+ int ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_HIGH,
-+ upper_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_LOW,
-+ lower_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
-+ if (pbus_data_high < 0)
-+ return ret;
-+
-+ pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
-+ if (pbus_data_low < 0)
-+ return ret;
-+
-+ pbus_data_old = pbus_data_low | (pbus_data_high << 16);
-+ pbus_data_new = (pbus_data_old & ~mask) | set;
-+ if (pbus_data_new == pbus_data_old)
-+ return 0;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH,
-+ upper_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW,
-+ lower_16_bits(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH,
-+ upper_16_bits(pbus_data_new));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW,
-+ lower_16_bits(pbus_data_new));
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int air_buckpbus_reg_modify(struct phy_device *phydev,
-+ u32 pbus_address, u32 mask, u32 set)
-+{
-+ int saved_page;
-+ int ret = 0;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ if (saved_page >= 0) {
-+ ret = __air_buckpbus_reg_modify(phydev, pbus_address, mask,
-+ set);
-+ if (ret < 0)
-+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
-+ pbus_address, ret);
-+ }
-+
-+ return phy_restore_page(phydev, saved_page, ret);
-+}
-+
-+static int __air_write_buf(struct phy_device *phydev, u32 address,
-+ const struct firmware *fw)
-+{
-+ unsigned int offset;
-+ int ret;
-+ u16 val;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_INCR);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH,
-+ upper_16_bits(address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW,
-+ lower_16_bits(address));
-+ if (ret < 0)
-+ return ret;
-+
-+ for (offset = 0; offset < fw->size; offset += 4) {
-+ val = get_unaligned_le16(&fw->data[offset + 2]);
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ val = get_unaligned_le16(&fw->data[offset]);
-+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW, val);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int air_write_buf(struct phy_device *phydev, u32 address,
-+ const struct firmware *fw)
-+{
-+ int saved_page;
-+ int ret = 0;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ if (saved_page >= 0) {
-+ ret = __air_write_buf(phydev, address, fw);
-+ if (ret < 0)
-+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
-+ address, ret);
-+ }
-+
-+ return phy_restore_page(phydev, saved_page, ret);
-+}
-+
-+static int en8811h_wait_mcu_ready(struct phy_device *phydev)
-+{
-+ int ret, reg_value;
-+
-+ /* Because of mdio-lock, may have to wait for multiple loads */
-+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+ EN8811H_PHY_FW_STATUS, reg_value,
-+ reg_value == EN8811H_PHY_READY,
-+ 20000, 7500000, true);
-+ if (ret) {
-+ phydev_err(phydev, "MCU not ready: 0x%x\n", reg_value);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+static int en8811h_load_firmware(struct phy_device *phydev)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ struct device *dev = &phydev->mdio.dev;
-+ const struct firmware *fw1, *fw2;
-+ int ret;
-+
-+ ret = request_firmware_direct(&fw1, EN8811H_MD32_DM, dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = request_firmware_direct(&fw2, EN8811H_MD32_DSP, dev);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_rel1;
-+
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
-+ EN8811H_FW_CTRL_1_START);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+
-+ ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
-+ EN8811H_FW_CTRL_2_LOADING,
-+ EN8811H_FW_CTRL_2_LOADING);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+
-+ ret = air_write_buf(phydev, AIR_FW_ADDR_DM, fw1);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+
-+ ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, fw2);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+
-+ ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
-+ EN8811H_FW_CTRL_2_LOADING, 0);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
-+ EN8811H_FW_CTRL_1_FINISH);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+
-+ ret = en8811h_wait_mcu_ready(phydev);
-+
-+ air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,
-+ &priv->firmware_version);
-+ phydev_info(phydev, "MD32 firmware version: %08x\n",
-+ priv->firmware_version);
-+
-+en8811h_load_firmware_out:
-+ release_firmware(fw2);
-+
-+en8811h_load_firmware_rel1:
-+ release_firmware(fw1);
-+
-+ if (ret < 0)
-+ phydev_err(phydev, "Load firmware failed: %d\n", ret);
-+
-+ return ret;
-+}
-+
-+static int en8811h_restart_mcu(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
-+ EN8811H_FW_CTRL_1_START);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
-+ EN8811H_FW_CTRL_1_FINISH);
-+ if (ret < 0)
-+ return ret;
-+
-+ return en8811h_wait_mcu_ready(phydev);
-+}
-+
-+static int air_hw_led_on_set(struct phy_device *phydev, u8 index, bool on)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ bool changed;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ if (on)
-+ changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_ON,
-+ &priv->led[index].state);
-+ else
-+ changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_ON,
-+ &priv->led[index].state);
-+
-+ changed |= (priv->led[index].rules != 0);
-+
-+ if (changed)
-+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
-+ AIR_PHY_LED_ON(index),
-+ AIR_PHY_LED_ON_MASK,
-+ on ? AIR_PHY_LED_ON_FORCE_ON : 0);
-+
-+ return 0;
-+}
-+
-+static int air_hw_led_blink_set(struct phy_device *phydev, u8 index,
-+ bool blinking)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ bool changed;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ if (blinking)
-+ changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_BLINK,
-+ &priv->led[index].state);
-+ else
-+ changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK,
-+ &priv->led[index].state);
-+
-+ changed |= (priv->led[index].rules != 0);
-+
-+ if (changed)
-+ return phy_write_mmd(phydev, MDIO_MMD_VEND2,
-+ AIR_PHY_LED_BLINK(index),
-+ blinking ?
-+ AIR_PHY_LED_BLINK_FORCE_BLINK : 0);
-+ else
-+ return 0;
-+}
-+
-+static int air_led_blink_set(struct phy_device *phydev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ bool blinking = false;
-+ int err;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
-+ blinking = true;
-+ *delay_on = 50;
-+ *delay_off = 50;
-+ }
-+
-+ err = air_hw_led_blink_set(phydev, index, blinking);
-+ if (err)
-+ return err;
-+
-+ /* led-blink set, so switch led-on off */
-+ err = air_hw_led_on_set(phydev, index, false);
-+ if (err)
-+ return err;
-+
-+ /* hw-control is off*/
-+ if (!!test_bit(AIR_PHY_LED_STATE_FORCE_BLINK, &priv->led[index].state))
-+ priv->led[index].rules = 0;
-+
-+ return 0;
-+}
-+
-+static int air_led_brightness_set(struct phy_device *phydev, u8 index,
-+ enum led_brightness value)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ int err;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ /* led-on set, so switch led-blink off */
-+ err = air_hw_led_blink_set(phydev, index, false);
-+ if (err)
-+ return err;
-+
-+ err = air_hw_led_on_set(phydev, index, (value != LED_OFF));
-+ if (err)
-+ return err;
-+
-+ /* hw-control is off */
-+ if (!!test_bit(AIR_PHY_LED_STATE_FORCE_ON, &priv->led[index].state))
-+ priv->led[index].rules = 0;
-+
-+ return 0;
-+}
-+
-+static int air_led_hw_control_get(struct phy_device *phydev, u8 index,
-+ unsigned long *rules)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ *rules = priv->led[index].rules;
-+
-+ return 0;
-+};
-+
-+static int air_led_hw_control_set(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ u16 on = 0, blink = 0;
-+ int ret;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ priv->led[index].rules = rules;
-+
-+ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
-+ on |= AIR_PHY_LED_ON_FDX;
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
-+ on |= AIR_PHY_LED_ON_LINK10;
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
-+ on |= AIR_PHY_LED_ON_LINK100;
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
-+ on |= AIR_PHY_LED_ON_LINK1000;
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK)))
-+ on |= AIR_PHY_LED_ON_LINK2500;
-+
-+ if (rules & BIT(TRIGGER_NETDEV_RX)) {
-+ blink |= AIR_PHY_LED_BLINK_10RX |
-+ AIR_PHY_LED_BLINK_100RX |
-+ AIR_PHY_LED_BLINK_1000RX |
-+ AIR_PHY_LED_BLINK_2500RX;
-+ }
-+
-+ if (rules & BIT(TRIGGER_NETDEV_TX)) {
-+ blink |= AIR_PHY_LED_BLINK_10TX |
-+ AIR_PHY_LED_BLINK_100TX |
-+ AIR_PHY_LED_BLINK_1000TX |
-+ AIR_PHY_LED_BLINK_2500TX;
-+ }
-+
-+ if (blink || on) {
-+ /* switch hw-control on, so led-on and led-blink are off */
-+ clear_bit(AIR_PHY_LED_STATE_FORCE_ON,
-+ &priv->led[index].state);
-+ clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK,
-+ &priv->led[index].state);
-+ } else {
-+ priv->led[index].rules = 0;
-+ }
-+
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
-+ AIR_PHY_LED_ON_MASK, on);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BLINK(index),
-+ blink);
-+};
-+
-+static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol)
-+{
-+ int val = 0;
-+ int err;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ if (state == AIR_LED_ENABLE)
-+ val |= AIR_PHY_LED_ON_ENABLE;
-+ else
-+ val &= ~AIR_PHY_LED_ON_ENABLE;
-+
-+ if (pol == AIR_ACTIVE_HIGH)
-+ val |= AIR_PHY_LED_ON_POLARITY;
-+ else
-+ val &= ~AIR_PHY_LED_ON_POLARITY;
-+
-+ err = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
-+ AIR_PHY_LED_ON_ENABLE |
-+ AIR_PHY_LED_ON_POLARITY, val);
-+
-+ if (err < 0)
-+ return err;
-+
-+ return 0;
-+}
-+
-+static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ int ret, i;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_BLINK,
-+ dur);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_ON,
-+ dur >> 1);
-+ if (ret < 0)
-+ return ret;
-+
-+ switch (mode) {
-+ case AIR_LED_MODE_DISABLE:
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
-+ AIR_PHY_LED_BCR_EXT_CTRL |
-+ AIR_PHY_LED_BCR_MODE_MASK, 0);
-+ if (ret < 0)
-+ return ret;
-+ break;
-+ case AIR_LED_MODE_USER_DEFINE:
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
-+ AIR_PHY_LED_BCR_EXT_CTRL |
-+ AIR_PHY_LED_BCR_CLK_EN,
-+ AIR_PHY_LED_BCR_EXT_CTRL |
-+ AIR_PHY_LED_BCR_CLK_EN);
-+ if (ret < 0)
-+ return ret;
-+ break;
-+ default:
-+ phydev_err(phydev, "LED mode %d is not supported\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ for (i = 0; i < num; ++i) {
-+ ret = air_led_init(phydev, i, AIR_LED_ENABLE, AIR_ACTIVE_HIGH);
-+ if (ret < 0) {
-+ phydev_err(phydev, "LED%d init failed: %d\n", i, ret);
-+ return ret;
-+ }
-+ air_led_hw_control_set(phydev, i, priv->led[i].rules);
-+ }
-+
-+ return 0;
-+}
-+
-+static int en8811h_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ /* All combinations of the supported triggers are allowed */
-+ if (rules & ~en8811h_led_trig)
-+ return -EOPNOTSUPP;
-+
-+ return 0;
-+};
-+
-+static int en8811h_probe(struct phy_device *phydev)
-+{
-+ struct en8811h_priv *priv;
-+ int ret;
-+
-+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct en8811h_priv),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+ phydev->priv = priv;
-+
-+ ret = en8811h_load_firmware(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* mcu has just restarted after firmware load */
-+ priv->mcu_needs_restart = false;
-+
-+ priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0;
-+ priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1;
-+ priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2;
-+
-+ /* MDIO_DEVS1/2 empty, so set mmds_present bits here */
-+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
-+
-+ ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR,
-+ AIR_LED_MODE_DISABLE);
-+ if (ret < 0) {
-+ phydev_err(phydev, "Failed to disable leds: %d\n", ret);
-+ return ret;
-+ }
-+
-+ /* Configure led gpio pins as output */
-+ ret = air_buckpbus_reg_modify(phydev, EN8811H_GPIO_OUTPUT,
-+ EN8811H_GPIO_OUTPUT_345,
-+ EN8811H_GPIO_OUTPUT_345);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int en8811h_config_init(struct phy_device *phydev)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ struct device *dev = &phydev->mdio.dev;
-+ u32 pbus_value;
-+ int ret;
-+
-+ /* If restart happened in .probe(), no need to restart now */
-+ if (priv->mcu_needs_restart) {
-+ ret = en8811h_restart_mcu(phydev);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ /* Next calls to .config_init() mcu needs to restart */
-+ priv->mcu_needs_restart = true;
-+ }
-+
-+ /* Select mode 1, the only mode supported.
-+ * Configures the SerDes for 2500Base-X with rate adaptation
-+ */
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_1,
-+ AIR_PHY_MCU_CMD_1_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_2,
-+ AIR_PHY_MCU_CMD_2_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_3,
-+ AIR_PHY_MCU_CMD_3_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_4,
-+ AIR_PHY_MCU_CMD_4_MODE1);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Serdes polarity */
-+ pbus_value = 0;
-+ if (device_property_read_bool(dev, "airoha,pnswap-rx"))
-+ pbus_value |= EN8811H_POLARITY_RX_REVERSE;
-+ else
-+ pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
-+ if (device_property_read_bool(dev, "airoha,pnswap-tx"))
-+ pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
-+ else
-+ pbus_value |= EN8811H_POLARITY_TX_NORMAL;
-+ ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
-+ EN8811H_POLARITY_RX_REVERSE |
-+ EN8811H_POLARITY_TX_NORMAL, pbus_value);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR,
-+ AIR_LED_MODE_USER_DEFINE);
-+ if (ret < 0) {
-+ phydev_err(phydev, "Failed to initialize leds: %d\n", ret);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int en8811h_get_features(struct phy_device *phydev)
-+{
-+ linkmode_set_bit_array(phy_basic_ports_array,
-+ ARRAY_SIZE(phy_basic_ports_array),
-+ phydev->supported);
-+
-+ return genphy_c45_pma_read_abilities(phydev);
-+}
-+
-+static int en8811h_get_rate_matching(struct phy_device *phydev,
-+ phy_interface_t iface)
-+{
-+ return RATE_MATCH_PAUSE;
-+}
-+
-+static int en8811h_config_aneg(struct phy_device *phydev)
-+{
-+ bool changed = false;
-+ int ret;
-+ u32 adv;
-+
-+ if (phydev->autoneg == AUTONEG_DISABLE) {
-+ phydev_warn(phydev, "Disabling autoneg is not supported\n");
-+ return -EINVAL;
-+ }
-+
-+ adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
-+
-+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-+ MDIO_AN_10GBT_CTRL_ADV2_5G, adv);
-+ if (ret < 0)
-+ return ret;
-+ if (ret > 0)
-+ changed = true;
-+
-+ return __genphy_config_aneg(phydev, changed);
-+}
-+
-+static int en8811h_read_status(struct phy_device *phydev)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ u32 pbus_value;
-+ int ret, val;
-+
-+ ret = genphy_update_link(phydev);
-+ if (ret)
-+ return ret;
-+
-+ phydev->master_slave_get = MASTER_SLAVE_CFG_UNSUPPORTED;
-+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
-+ phydev->speed = SPEED_UNKNOWN;
-+ phydev->duplex = DUPLEX_UNKNOWN;
-+ phydev->pause = 0;
-+ phydev->asym_pause = 0;
-+ phydev->rate_matching = RATE_MATCH_PAUSE;
-+
-+ ret = genphy_read_master_slave(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = genphy_read_lpa(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Get link partner 2.5GBASE-T ability from vendor register */
-+ ret = air_buckpbus_reg_read(phydev, EN8811H_2P5G_LPA, &pbus_value);
-+ if (ret < 0)
-+ return ret;
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+ phydev->lp_advertising,
-+ pbus_value & EN8811H_2P5G_LPA_2P5G);
-+
-+ if (phydev->autoneg_complete)
-+ phy_resolve_aneg_pause(phydev);
-+
-+ if (!phydev->link)
-+ return 0;
-+
-+ /* Get real speed from vendor register */
-+ val = phy_read(phydev, AIR_AUX_CTRL_STATUS);
-+ if (val < 0)
-+ return val;
-+ switch (val & AIR_AUX_CTRL_STATUS_SPEED_MASK) {
-+ case AIR_AUX_CTRL_STATUS_SPEED_2500:
-+ phydev->speed = SPEED_2500;
-+ break;
-+ case AIR_AUX_CTRL_STATUS_SPEED_1000:
-+ phydev->speed = SPEED_1000;
-+ break;
-+ case AIR_AUX_CTRL_STATUS_SPEED_100:
-+ phydev->speed = SPEED_100;
-+ break;
-+ }
-+
-+ /* Firmware before version 24011202 has no vendor register 2P5G_LPA.
-+ * Assume link partner advertised it if connected at 2500Mbps.
-+ */
-+ if (priv->firmware_version < 0x24011202) {
-+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+ phydev->lp_advertising,
-+ phydev->speed == SPEED_2500);
-+ }
-+
-+ /* Only supports full duplex */
-+ phydev->duplex = DUPLEX_FULL;
-+
-+ return 0;
-+}
-+
-+static int en8811h_clear_intr(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_3,
-+ AIR_PHY_MCU_CMD_3_DOCMD);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_4,
-+ AIR_PHY_MCU_CMD_4_INTCLR);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static irqreturn_t en8811h_handle_interrupt(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = en8811h_clear_intr(phydev);
-+ if (ret < 0) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static struct phy_driver en8811h_driver[] = {
-+{
-+ PHY_ID_MATCH_MODEL(EN8811H_PHY_ID),
-+ .name = "Airoha EN8811H",
-+ .probe = en8811h_probe,
-+ .get_features = en8811h_get_features,
-+ .config_init = en8811h_config_init,
-+ .get_rate_matching = en8811h_get_rate_matching,
-+ .config_aneg = en8811h_config_aneg,
-+ .read_status = en8811h_read_status,
-+ .config_intr = en8811h_clear_intr,
-+ .handle_interrupt = en8811h_handle_interrupt,
-+ .led_hw_is_supported = en8811h_led_hw_is_supported,
-+ .read_page = air_phy_read_page,
-+ .write_page = air_phy_write_page,
-+ .led_blink_set = air_led_blink_set,
-+ .led_brightness_set = air_led_brightness_set,
-+ .led_hw_control_set = air_led_hw_control_set,
-+ .led_hw_control_get = air_led_hw_control_get,
-+} };
-+
-+module_phy_driver(en8811h_driver);
-+
-+static struct mdio_device_id __maybe_unused en8811h_tbl[] = {
-+ { PHY_ID_MATCH_MODEL(EN8811H_PHY_ID) },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, en8811h_tbl);
-+MODULE_FIRMWARE(EN8811H_MD32_DM);
-+MODULE_FIRMWARE(EN8811H_MD32_DSP);
-+
-+MODULE_DESCRIPTION("Airoha EN8811H PHY drivers");
-+MODULE_AUTHOR("Airoha");
-+MODULE_AUTHOR("Eric Woudstra <ericwouds@gmail.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch b/target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch
deleted file mode 100644
index 1bd0eefe77..0000000000
--- a/target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 87c33315af380ca12a2e59ac94edad4fe0481b4c Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@linaro.org>
-Date: Fri, 5 Apr 2024 13:08:59 +0300
-Subject: [PATCH] net: phy: air_en8811h: fix some error codes
-
-These error paths accidentally return "ret" which is zero/success
-instead of the correct error code.
-
-Fixes: 71e79430117d ("net: phy: air_en8811h: Add the Airoha EN8811H PHY driver")
-Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/7ef2e230-dfb7-4a77-8973-9e5be1a99fc2@moroto.mountain
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/air_en8811h.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/air_en8811h.c
-+++ b/drivers/net/phy/air_en8811h.c
-@@ -272,11 +272,11 @@ static int __air_buckpbus_reg_read(struc
-
- pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
- if (pbus_data_high < 0)
-- return ret;
-+ return pbus_data_high;
-
- pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
- if (pbus_data_low < 0)
-- return ret;
-+ return pbus_data_low;
-
- *pbus_data = pbus_data_low | (pbus_data_high << 16);
- return 0;
-@@ -323,11 +323,11 @@ static int __air_buckpbus_reg_modify(str
-
- pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
- if (pbus_data_high < 0)
-- return ret;
-+ return pbus_data_high;
-
- pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
- if (pbus_data_low < 0)
-- return ret;
-+ return pbus_data_low;
-
- pbus_data_old = pbus_data_low | (pbus_data_high << 16);
- pbus_data_new = (pbus_data_old & ~mask) | set;
diff --git a/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch b/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch
deleted file mode 100644
index 592111fb95..0000000000
--- a/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 156a5bb89ca6f3edd2be0bfd0de15e575442927e Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Tue, 3 Jan 2023 15:12:47 +0200
-Subject: [PATCH] leds: Move led_init_default_state_get() to the global header
-
-There are users inside and outside LED framework that have implemented
-a local copy of led_init_default_state_get(). In order to deduplicate
-that, as the first step move the declaration from LED header to the
-global one.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230103131256.33894-3-andriy.shevchenko@linux.intel.com
----
- drivers/leds/leds.h | 1 -
- include/linux/leds.h | 2 ++
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/leds/leds.h
-+++ b/drivers/leds/leds.h
-@@ -27,7 +27,6 @@ ssize_t led_trigger_read(struct file *fi
- ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t pos, size_t count);
--enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
-
- extern struct rw_semaphore leds_list_lock;
- extern struct list_head leds_list;
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -63,6 +63,8 @@ struct led_init_data {
- bool devname_mandatory;
- };
-
-+enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
-+
- struct led_hw_trigger_type {
- int dummy;
- };
diff --git a/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch b/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch
deleted file mode 100644
index f6a025fa12..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 3e8b4d6277fd19d98c817576954dd6a4ff3caa2b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 17 Apr 2023 17:17:23 +0200
-Subject: [PATCH 1/9] net: dsa: qca8k: move qca8k_port_to_phy() to header
-
-Move qca8k_port_to_phy() to qca8k header as it's useful for future
-reference in Switch LEDs module since the same logic is applied to get
-the right index of the switch port.
-Make it inline as it's simple function that just decrease the port.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 15 ---------------
- drivers/net/dsa/qca/qca8k.h | 14 ++++++++++++++
- 2 files changed, 14 insertions(+), 15 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -789,21 +789,6 @@ err_clear_skb:
- return ret;
- }
-
--static u32
--qca8k_port_to_phy(int port)
--{
-- /* From Andrew Lunn:
-- * Port 0 has no internal phy.
-- * Port 1 has an internal PHY at MDIO address 0.
-- * Port 2 has an internal PHY at MDIO address 1.
-- * ...
-- * Port 5 has an internal PHY at MDIO address 4.
-- * Port 6 has no internal PHY.
-- */
--
-- return port - 1;
--}
--
- static int
- qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
- {
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -421,6 +421,20 @@ struct qca8k_fdb {
- u8 mac[6];
- };
-
-+static inline u32 qca8k_port_to_phy(int port)
-+{
-+ /* From Andrew Lunn:
-+ * Port 0 has no internal phy.
-+ * Port 1 has an internal PHY at MDIO address 0.
-+ * Port 2 has an internal PHY at MDIO address 1.
-+ * ...
-+ * Port 5 has an internal PHY at MDIO address 4.
-+ * Port 6 has no internal PHY.
-+ */
-+
-+ return port - 1;
-+}
-+
- /* Common setup function */
- extern const struct qca8k_mib_desc ar8327_mib[];
- extern const struct regmap_access_table qca8k_readable_table;
diff --git a/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch b/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch
deleted file mode 100644
index 409fe9c7a1..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch
+++ /dev/null
@@ -1,435 +0,0 @@
-From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 17 Apr 2023 17:17:24 +0200
-Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support
-
-Add LEDs basic support for qca8k Switch Family by adding basic
-brightness_set() support.
-
-Since these LEDs refelect port status, the default label is set to
-":port". DT binding should describe the color and function of the
-LEDs using standard LEDs api.
-Each LED always have the device name as prefix. The device name is
-composed from the mii bus id and the PHY addr resulting in example
-names like:
-- qca8k-0.0:00:amber:lan
-- qca8k-0.0:00:white:lan
-- qca8k-0.0:01:amber:lan
-- qca8k-0.0:01:white:lan
-
-These LEDs supports only blocking variant of the brightness_set()
-function since they can sleep during access of the switch leds to set
-the brightness.
-
-While at it add to the qca8k header file each mode defined by the Switch
-Documentation for future use.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/Kconfig | 8 ++
- drivers/net/dsa/qca/Makefile | 3 +
- drivers/net/dsa/qca/qca8k-8xxx.c | 5 +
- drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 60 ++++++++
- drivers/net/dsa/qca/qca8k_leds.h | 16 +++
- 6 files changed, 331 insertions(+)
- create mode 100644 drivers/net/dsa/qca/qca8k-leds.c
- create mode 100644 drivers/net/dsa/qca/qca8k_leds.h
-
---- a/drivers/net/dsa/qca/Kconfig
-+++ b/drivers/net/dsa/qca/Kconfig
-@@ -15,3 +15,11 @@ config NET_DSA_QCA8K
- help
- This enables support for the Qualcomm Atheros QCA8K Ethernet
- switch chips.
-+
-+config NET_DSA_QCA8K_LEDS_SUPPORT
-+ bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support"
-+ depends on NET_DSA_QCA8K
-+ depends on LEDS_CLASS
-+ help
-+ This enabled support for LEDs present on the Qualcomm Atheros
-+ QCA8K Ethernet switch chips.
---- a/drivers/net/dsa/qca/Makefile
-+++ b/drivers/net/dsa/qca/Makefile
-@@ -2,3 +2,6 @@
- obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o
- obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
- qca8k-y += qca8k-common.o qca8k-8xxx.o
-+ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
-+qca8k-y += qca8k-leds.o
-+endif
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -22,6 +22,7 @@
- #include <linux/dsa/tag_qca.h>
-
- #include "qca8k.h"
-+#include "qca8k_leds.h"
-
- static void
- qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
-@@ -1851,6 +1852,10 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-+ ret = qca8k_setup_led_ctrl(priv);
-+ if (ret)
-+ return ret;
-+
- qca8k_setup_pcs(priv, &priv->pcs_port_0, 0);
- qca8k_setup_pcs(priv, &priv->pcs_port_6, 6);
-
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -0,0 +1,239 @@
-+// SPDX-License-Identifier: GPL-2.0
-+#include <linux/regmap.h>
-+#include <net/dsa.h>
-+
-+#include "qca8k.h"
-+#include "qca8k_leds.h"
-+
-+static int
-+qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
-+{
-+ switch (port_num) {
-+ case 0:
-+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
-+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
-+ break;
-+ case 1:
-+ case 2:
-+ case 3:
-+ /* Port 123 are controlled on a different reg */
-+ reg_info->reg = QCA8K_LED_CTRL3_REG;
-+ reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num);
-+ break;
-+ case 4:
-+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
-+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_led_brightness_set(struct qca8k_led *led,
-+ enum led_brightness brightness)
-+{
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 mask, val;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ val = QCA8K_LED_ALWAYS_OFF;
-+ if (brightness)
-+ val = QCA8K_LED_ALWAYS_ON;
-+
-+ /* HW regs to control brightness is special and port 1-2-3
-+ * are placed in a different reg.
-+ *
-+ * To control port 0 brightness:
-+ * - the 2 bit (15, 14) of:
-+ * - QCA8K_LED_CTRL0_REG for led1
-+ * - QCA8K_LED_CTRL1_REG for led2
-+ * - QCA8K_LED_CTRL2_REG for led3
-+ *
-+ * To control port 4:
-+ * - the 2 bit (31, 30) of:
-+ * - QCA8K_LED_CTRL0_REG for led1
-+ * - QCA8K_LED_CTRL1_REG for led2
-+ * - QCA8K_LED_CTRL2_REG for led3
-+ *
-+ * To control port 1:
-+ * - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1
-+ * - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2
-+ * - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3
-+ *
-+ * To control port 2:
-+ * - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1
-+ * - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2
-+ * - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3
-+ *
-+ * To control port 3:
-+ * - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1
-+ * - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2
-+ * - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3
-+ *
-+ * To abstract this and have less code, we use the port and led numm
-+ * to calculate the shift and the correct reg due to this problem of
-+ * not having a 1:1 map of LED with the regs.
-+ */
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ mask = QCA8K_LED_PATTERN_EN_MASK;
-+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, reg_info.reg,
-+ mask << reg_info.shift,
-+ val << reg_info.shift);
-+}
-+
-+static int
-+qca8k_cled_brightness_set_blocking(struct led_classdev *ldev,
-+ enum led_brightness brightness)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+
-+ return qca8k_led_brightness_set(led, brightness);
-+}
-+
-+static enum led_brightness
-+qca8k_led_brightness_get(struct qca8k_led *led)
-+{
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 val;
-+ int ret;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ ret = regmap_read(priv->regmap, reg_info.reg, &val);
-+ if (ret)
-+ return 0;
-+
-+ val >>= reg_info.shift;
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ val &= QCA8K_LED_PATTERN_EN_MASK;
-+ val >>= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ /* Assume brightness ON only when the LED is set to always ON */
-+ return val == QCA8K_LED_ALWAYS_ON;
-+}
-+
-+static int
-+qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
-+{
-+ struct fwnode_handle *led = NULL, *leds = NULL;
-+ struct led_init_data init_data = { };
-+ struct dsa_switch *ds = priv->ds;
-+ enum led_default_state state;
-+ struct qca8k_led *port_led;
-+ int led_num, led_index;
-+ int ret;
-+
-+ leds = fwnode_get_named_child_node(port, "leds");
-+ if (!leds) {
-+ dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n",
-+ port_num);
-+ return 0;
-+ }
-+
-+ fwnode_for_each_child_node(leds, led) {
-+ /* Reg represent the led number of the port.
-+ * Each port can have at most 3 leds attached
-+ * Commonly:
-+ * 1. is gigabit led
-+ * 2. is mbit led
-+ * 3. additional status led
-+ */
-+ if (fwnode_property_read_u32(led, "reg", &led_num))
-+ continue;
-+
-+ if (led_num >= QCA8K_LED_PORT_COUNT) {
-+ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
-+ led_num, port_num);
-+ continue;
-+ }
-+
-+ led_index = QCA8K_LED_PORT_INDEX(port_num, led_num);
-+
-+ port_led = &priv->ports_led[led_index];
-+ port_led->port_num = port_num;
-+ port_led->led_num = led_num;
-+ port_led->priv = priv;
-+
-+ state = led_init_default_state_get(led);
-+ switch (state) {
-+ case LEDS_DEFSTATE_ON:
-+ port_led->cdev.brightness = 1;
-+ qca8k_led_brightness_set(port_led, 1);
-+ break;
-+ case LEDS_DEFSTATE_KEEP:
-+ port_led->cdev.brightness =
-+ qca8k_led_brightness_get(port_led);
-+ break;
-+ default:
-+ port_led->cdev.brightness = 0;
-+ qca8k_led_brightness_set(port_led, 0);
-+ }
-+
-+ port_led->cdev.max_brightness = 1;
-+ port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
-+ init_data.default_label = ":port";
-+ init_data.fwnode = led;
-+ init_data.devname_mandatory = true;
-+ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id,
-+ port_num);
-+ if (!init_data.devicename)
-+ return -ENOMEM;
-+
-+ ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
-+ if (ret)
-+ dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num);
-+
-+ kfree(init_data.devicename);
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+qca8k_setup_led_ctrl(struct qca8k_priv *priv)
-+{
-+ struct fwnode_handle *ports, *port;
-+ int port_num;
-+ int ret;
-+
-+ ports = device_get_named_child_node(priv->dev, "ports");
-+ if (!ports) {
-+ dev_info(priv->dev, "No ports node specified in device tree!");
-+ return 0;
-+ }
-+
-+ fwnode_for_each_child_node(ports, port) {
-+ if (fwnode_property_read_u32(port, "reg", &port_num))
-+ continue;
-+
-+ /* Skip checking for CPU port 0 and CPU port 6 as not supported */
-+ if (port_num == 0 || port_num == 6)
-+ continue;
-+
-+ /* Each port can have at most 3 different leds attached.
-+ * Switch port starts from 0 to 6, but port 0 and 6 are CPU
-+ * port. The port index needs to be decreased by one to identify
-+ * the correct port for LED setup.
-+ */
-+ ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -11,6 +11,7 @@
- #include <linux/delay.h>
- #include <linux/regmap.h>
- #include <linux/gpio.h>
-+#include <linux/leds.h>
- #include <linux/dsa/tag_qca.h>
-
- #define QCA8K_ETHERNET_MDIO_PRIORITY 7
-@@ -85,6 +86,51 @@
- #define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x)
- #define QCA8K_MDIO_MASTER_MAX_PORTS 5
- #define QCA8K_MDIO_MASTER_MAX_REG 32
-+
-+/* LED control register */
-+#define QCA8K_LED_PORT_COUNT 3
-+#define QCA8K_LED_COUNT ((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT)
-+#define QCA8K_LED_RULE_COUNT 6
-+#define QCA8K_LED_RULE_MAX 11
-+#define QCA8K_LED_PORT_INDEX(_phy, _led) (((_phy) * QCA8K_LED_PORT_COUNT) + (_led))
-+
-+#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led) ((((_phy) - 1) * 6) + 8 + (2 * (_led)))
-+#define QCA8K_LED_PHY123_PATTERN_EN_MASK GENMASK(1, 0)
-+
-+#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT 0
-+#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT 16
-+
-+#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4)
-+#define QCA8K_LED_CTRL0_REG 0x50
-+#define QCA8K_LED_CTRL1_REG 0x54
-+#define QCA8K_LED_CTRL2_REG 0x58
-+#define QCA8K_LED_CTRL3_REG 0x5C
-+#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16)
-+#define QCA8K_LED_CTRL_MASK GENMASK(15, 0)
-+#define QCA8K_LED_RULE_MASK GENMASK(13, 0)
-+#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0)
-+#define QCA8K_LED_BLINK_FREQ_SHITF 0
-+#define QCA8K_LED_BLINK_2HZ 0
-+#define QCA8K_LED_BLINK_4HZ 1
-+#define QCA8K_LED_BLINK_8HZ 2
-+#define QCA8K_LED_BLINK_AUTO 3
-+#define QCA8K_LED_LINKUP_OVER_MASK BIT(2)
-+#define QCA8K_LED_TX_BLINK_MASK BIT(4)
-+#define QCA8K_LED_RX_BLINK_MASK BIT(5)
-+#define QCA8K_LED_COL_BLINK_MASK BIT(7)
-+#define QCA8K_LED_LINK_10M_EN_MASK BIT(8)
-+#define QCA8K_LED_LINK_100M_EN_MASK BIT(9)
-+#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10)
-+#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11)
-+#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12)
-+#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13)
-+#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14)
-+#define QCA8K_LED_PATTERN_EN_SHIFT 14
-+#define QCA8K_LED_ALWAYS_OFF 0
-+#define QCA8K_LED_ALWAYS_BLINK_4HZ 1
-+#define QCA8K_LED_ALWAYS_ON 2
-+#define QCA8K_LED_RULE_CONTROLLED 3
-+
- #define QCA8K_GOL_MAC_ADDR0 0x60
- #define QCA8K_GOL_MAC_ADDR1 0x64
- #define QCA8K_MAX_FRAME_SIZE 0x78
-@@ -382,6 +428,19 @@ struct qca8k_pcs {
- int port;
- };
-
-+struct qca8k_led_pattern_en {
-+ u32 reg;
-+ u8 shift;
-+};
-+
-+struct qca8k_led {
-+ u8 port_num;
-+ u8 led_num;
-+ u16 old_rule;
-+ struct qca8k_priv *priv;
-+ struct led_classdev cdev;
-+};
-+
- struct qca8k_priv {
- u8 switch_id;
- u8 switch_revision;
-@@ -406,6 +465,7 @@ struct qca8k_priv {
- struct qca8k_pcs pcs_port_0;
- struct qca8k_pcs pcs_port_6;
- const struct qca8k_match_data *info;
-+ struct qca8k_led ports_led[QCA8K_LED_COUNT];
- };
-
- struct qca8k_mib_desc {
---- /dev/null
-+++ b/drivers/net/dsa/qca/qca8k_leds.h
-@@ -0,0 +1,16 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#ifndef __QCA8K_LEDS_H
-+#define __QCA8K_LEDS_H
-+
-+/* Leds Support function */
-+#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
-+int qca8k_setup_led_ctrl(struct qca8k_priv *priv);
-+#else
-+static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv)
-+{
-+ return 0;
-+}
-+#endif
-+
-+#endif /* __QCA8K_LEDS_H */
diff --git a/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch b/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch
deleted file mode 100644
index 231c4156df..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 91acadcc6e599dfc62717abcdad58a459cfb1684 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 17 Apr 2023 17:17:25 +0200
-Subject: [PATCH 3/9] net: dsa: qca8k: add LEDs blink_set() support
-
-Add LEDs blink_set() support to qca8k Switch Family.
-These LEDs support hw accellerated blinking at a fixed rate
-of 4Hz.
-
-Reject any other value since not supported by the LEDs switch.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Pavel Machek <pavel@ucw.cz>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-leds.c | 38 ++++++++++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-leds.c
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_le
- }
-
- static int
-+qca8k_cled_blink_set(struct led_classdev *ldev,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ;
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+
-+ if (*delay_on == 0 && *delay_off == 0) {
-+ *delay_on = 125;
-+ *delay_off = 125;
-+ }
-+
-+ if (*delay_on != 125 || *delay_off != 125) {
-+ /* The hardware only supports blinking at 4Hz. Fall back
-+ * to software implementation in other cases.
-+ */
-+ return -EINVAL;
-+ }
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ mask = QCA8K_LED_PATTERN_EN_MASK;
-+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
-+ val << reg_info.shift);
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
- {
- struct fwnode_handle *led = NULL, *leds = NULL;
-@@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv
-
- port_led->cdev.max_brightness = 1;
- port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
-+ port_led->cdev.blink_set = qca8k_cled_blink_set;
- init_data.default_label = ":port";
- init_data.fwnode = led;
- init_data.devname_mandatory = true;
diff --git a/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch b/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch
deleted file mode 100644
index bc905b4468..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From e5029edd53937a29801ef507cee12e657ff31ea9 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:26 +0200
-Subject: [PATCH 4/9] leds: Provide stubs for when CLASS_LED & NEW_LEDS are
- disabled
-
-Provide stubs for devm_led_classdev_register_ext() and
-led_init_default_state_get() so that LED drivers embedded within other
-drivers such as PHYs and Ethernet switches still build when LEDS_CLASS
-or NEW_LEDS are disabled. This also helps with Kconfig dependencies,
-which are somewhat hairy for phylib and mdio and only get worse when
-adding a dependency on LED_CLASS.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/leds.h | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -63,7 +63,15 @@ struct led_init_data {
- bool devname_mandatory;
- };
-
-+#if IS_ENABLED(CONFIG_NEW_LEDS)
- enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
-+#else
-+static inline enum led_default_state
-+led_init_default_state_get(struct fwnode_handle *fwnode)
-+{
-+ return LEDS_DEFSTATE_OFF;
-+}
-+#endif
-
- struct led_hw_trigger_type {
- int dummy;
-@@ -198,9 +206,19 @@ static inline int led_classdev_register(
- return led_classdev_register_ext(parent, led_cdev, NULL);
- }
-
-+#if IS_ENABLED(CONFIG_LEDS_CLASS)
- int devm_led_classdev_register_ext(struct device *parent,
- struct led_classdev *led_cdev,
- struct led_init_data *init_data);
-+#else
-+static inline int
-+devm_led_classdev_register_ext(struct device *parent,
-+ struct led_classdev *led_cdev,
-+ struct led_init_data *init_data)
-+{
-+ return 0;
-+}
-+#endif
-
- static inline int devm_led_classdev_register(struct device *parent,
- struct led_classdev *led_cdev)
diff --git a/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch b/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch
deleted file mode 100644
index 0d2c0bcd83..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch
+++ /dev/null
@@ -1,191 +0,0 @@
-From 01e5b728e9e43ae444e0369695a5f72209906464 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:27 +0200
-Subject: [PATCH 5/9] net: phy: Add a binding for PHY LEDs
-
-Define common binding parsing for all PHY drivers with LEDs using
-phylib. Parse the DT as part of the phy_probe and add LEDs to the
-linux LED class infrastructure. For the moment, provide a dummy
-brightness function, which will later be replaced with a call into the
-PHY driver. This allows testing since the LED core might otherwise
-reject an LED whose brightness cannot be set.
-
-Add a dependency on LED_CLASS. It either needs to be built in, or not
-enabled, since a modular build can result in linker errors.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig | 1 +
- drivers/net/phy/phy_device.c | 76 ++++++++++++++++++++++++++++++++++++
- include/linux/phy.h | 16 ++++++++
- 3 files changed, 93 insertions(+)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -18,6 +18,7 @@ menuconfig PHYLIB
- depends on NETDEVICES
- select MDIO_DEVICE
- select MDIO_DEVRES
-+ depends on LEDS_CLASS || LEDS_CLASS=n
- help
- Ethernet controllers are usually attached to PHY
- devices. This option provides infrastructure for
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -19,10 +19,12 @@
- #include <linux/interrupt.h>
- #include <linux/io.h>
- #include <linux/kernel.h>
-+#include <linux/list.h>
- #include <linux/mdio.h>
- #include <linux/mii.h>
- #include <linux/mm.h>
- #include <linux/module.h>
-+#include <linux/of.h>
- #include <linux/netdevice.h>
- #include <linux/phy.h>
- #include <linux/phy_led_triggers.h>
-@@ -642,6 +644,7 @@ struct phy_device *phy_device_create(str
- device_initialize(&mdiodev->dev);
-
- dev->state = PHY_DOWN;
-+ INIT_LIST_HEAD(&dev->leds);
-
- mutex_init(&dev->lock);
- INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
-@@ -3035,6 +3038,74 @@ static bool phy_drv_supports_irq(struct
- return phydrv->config_intr && phydrv->handle_interrupt;
- }
-
-+/* Dummy implementation until calls into PHY driver are added */
-+static int phy_led_set_brightness(struct led_classdev *led_cdev,
-+ enum led_brightness value)
-+{
-+ return 0;
-+}
-+
-+static int of_phy_led(struct phy_device *phydev,
-+ struct device_node *led)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ struct led_init_data init_data = {};
-+ struct led_classdev *cdev;
-+ struct phy_led *phyled;
-+ int err;
-+
-+ phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL);
-+ if (!phyled)
-+ return -ENOMEM;
-+
-+ cdev = &phyled->led_cdev;
-+
-+ err = of_property_read_u8(led, "reg", &phyled->index);
-+ if (err)
-+ return err;
-+
-+ cdev->brightness_set_blocking = phy_led_set_brightness;
-+ cdev->max_brightness = 1;
-+ init_data.devicename = dev_name(&phydev->mdio.dev);
-+ init_data.fwnode = of_fwnode_handle(led);
-+ init_data.devname_mandatory = true;
-+
-+ err = devm_led_classdev_register_ext(dev, cdev, &init_data);
-+ if (err)
-+ return err;
-+
-+ list_add(&phyled->list, &phydev->leds);
-+
-+ return 0;
-+}
-+
-+static int of_phy_leds(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ struct device_node *leds, *led;
-+ int err;
-+
-+ if (!IS_ENABLED(CONFIG_OF_MDIO))
-+ return 0;
-+
-+ if (!node)
-+ return 0;
-+
-+ leds = of_get_child_by_name(node, "leds");
-+ if (!leds)
-+ return 0;
-+
-+ for_each_available_child_of_node(leds, led) {
-+ err = of_phy_led(phydev, led);
-+ if (err) {
-+ of_node_put(led);
-+ return err;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
- /**
- * fwnode_mdio_find_device - Given a fwnode, find the mdio_device
- * @fwnode: pointer to the mdio_device's fwnode
-@@ -3213,6 +3284,11 @@ static int phy_probe(struct device *dev)
- /* Set the state to READY by default */
- phydev->state = PHY_READY;
-
-+ /* Get the LEDs from the device tree, and instantiate standard
-+ * LEDs for them.
-+ */
-+ err = of_phy_leds(phydev);
-+
- out:
- /* Re-assert the reset signal on error */
- if (err)
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -14,6 +14,7 @@
- #include <linux/compiler.h>
- #include <linux/spinlock.h>
- #include <linux/ethtool.h>
-+#include <linux/leds.h>
- #include <linux/linkmode.h>
- #include <linux/netlink.h>
- #include <linux/mdio.h>
-@@ -606,6 +607,7 @@ struct macsec_ops;
- * @phy_num_led_triggers: Number of triggers in @phy_led_triggers
- * @led_link_trigger: LED trigger for link up/down
- * @last_triggered: last LED trigger for link speed
-+ * @leds: list of PHY LED structures
- * @master_slave_set: User requested master/slave configuration
- * @master_slave_get: Current master/slave advertisement
- * @master_slave_state: Current master/slave configuration
-@@ -698,6 +700,7 @@ struct phy_device {
-
- struct phy_led_trigger *led_link_trigger;
- #endif
-+ struct list_head leds;
-
- /*
- * Interrupt number for this PHY
-@@ -772,6 +775,19 @@ struct phy_tdr_config {
- #define PHY_PAIR_ALL -1
-
- /**
-+ * struct phy_led: An LED driven by the PHY
-+ *
-+ * @list: List of LEDs
-+ * @led_cdev: Standard LED class structure
-+ * @index: Number of the LED
-+ */
-+struct phy_led {
-+ struct list_head list;
-+ struct led_classdev led_cdev;
-+ u8 index;
-+};
-+
-+/**
- * struct phy_driver - Driver structure for a particular PHY type
- *
- * @mdiodrv: Data common to all MDIO devices
diff --git a/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
deleted file mode 100644
index 4873c40a77..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:28 +0200
-Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED
- brightness
-
-Linux LEDs can be software controlled via the brightness file in /sys.
-LED drivers need to implement a brightness_set function which the core
-will call. Implement an intermediary in phy_device, which will call
-into the phy driver if it implements the necessary function.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy_device.c | 15 ++++++++++++---
- include/linux/phy.h | 13 +++++++++++++
- 2 files changed, 25 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3038,11 +3038,18 @@ static bool phy_drv_supports_irq(struct
- return phydrv->config_intr && phydrv->handle_interrupt;
- }
-
--/* Dummy implementation until calls into PHY driver are added */
- static int phy_led_set_brightness(struct led_classdev *led_cdev,
- enum led_brightness value)
- {
-- return 0;
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+ int err;
-+
-+ mutex_lock(&phydev->lock);
-+ err = phydev->drv->led_brightness_set(phydev, phyled->index, value);
-+ mutex_unlock(&phydev->lock);
-+
-+ return err;
- }
-
- static int of_phy_led(struct phy_device *phydev,
-@@ -3059,12 +3066,14 @@ static int of_phy_led(struct phy_device
- return -ENOMEM;
-
- cdev = &phyled->led_cdev;
-+ phyled->phydev = phydev;
-
- err = of_property_read_u8(led, "reg", &phyled->index);
- if (err)
- return err;
-
-- cdev->brightness_set_blocking = phy_led_set_brightness;
-+ if (phydev->drv->led_brightness_set)
-+ cdev->brightness_set_blocking = phy_led_set_brightness;
- cdev->max_brightness = 1;
- init_data.devicename = dev_name(&phydev->mdio.dev);
- init_data.fwnode = of_fwnode_handle(led);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -778,15 +778,19 @@ struct phy_tdr_config {
- * struct phy_led: An LED driven by the PHY
- *
- * @list: List of LEDs
-+ * @phydev: PHY this LED is attached to
- * @led_cdev: Standard LED class structure
- * @index: Number of the LED
- */
- struct phy_led {
- struct list_head list;
-+ struct phy_device *phydev;
- struct led_classdev led_cdev;
- u8 index;
- };
-
-+#define to_phy_led(d) container_of(d, struct phy_led, led_cdev)
-+
- /**
- * struct phy_driver - Driver structure for a particular PHY type
- *
-@@ -1001,6 +1005,15 @@ struct phy_driver {
- int (*get_sqi)(struct phy_device *dev);
- /** @get_sqi_max: Get the maximum signal quality indication */
- int (*get_sqi_max)(struct phy_device *dev);
-+
-+ /**
-+ * @led_brightness_set: Set a PHY LED brightness. Index
-+ * indicates which of the PHYs led should be set. Value
-+ * follows the standard LED class meaning, e.g. LED_OFF,
-+ * LED_HALF, LED_FULL.
-+ */
-+ int (*led_brightness_set)(struct phy_device *dev,
-+ u8 index, enum led_brightness value);
- };
- #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
- struct phy_driver, mdiodrv)
diff --git a/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch b/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch
deleted file mode 100644
index 5114c0e6da..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 2d3960e58ef7c83fe1dbf952f056b9e906cb6df8 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:29 +0200
-Subject: [PATCH 7/9] net: phy: marvell: Add software control of the LEDs
-
-Add a brightness function, so the LEDs can be controlled from
-software using the standard Linux LED infrastructure.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/marvell.c | 45 ++++++++++++++++++++++++++++++++++-----
- 1 file changed, 40 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -144,11 +144,13 @@
- /* WOL Event Interrupt Enable */
- #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7)
-
--/* LED Timer Control Register */
--#define MII_88E1318S_PHY_LED_TCR 0x12
--#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
--#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
--#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11)
-+#define MII_88E1318S_PHY_LED_FUNC 0x10
-+#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8)
-+#define MII_88E1318S_PHY_LED_FUNC_ON (0x9)
-+#define MII_88E1318S_PHY_LED_TCR 0x12
-+#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
-+#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
-+#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11)
-
- /* Magic Packet MAC address registers */
- #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17
-@@ -2832,6 +2834,34 @@ static int marvell_hwmon_probe(struct ph
- }
- #endif
-
-+static int m88e1318_led_brightness_set(struct phy_device *phydev,
-+ u8 index, enum led_brightness value)
-+{
-+ int reg;
-+
-+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC);
-+ if (reg < 0)
-+ return reg;
-+
-+ switch (index) {
-+ case 0:
-+ case 1:
-+ case 2:
-+ reg &= ~(0xf << (4 * index));
-+ if (value == LED_OFF)
-+ reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index);
-+ else
-+ reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC, reg);
-+}
-+
- static int marvell_probe(struct phy_device *phydev)
- {
- struct marvell_priv *priv;
-@@ -3081,6 +3111,7 @@ static struct phy_driver marvell_drivers
- .get_sset_count = marvell_get_sset_count,
- .get_strings = marvell_get_strings,
- .get_stats = marvell_get_stats,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1145,
-@@ -3187,6 +3218,7 @@ static struct phy_driver marvell_drivers
- .cable_test_start = marvell_vct7_cable_test_start,
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1540,
-@@ -3213,6 +3245,7 @@ static struct phy_driver marvell_drivers
- .cable_test_start = marvell_vct7_cable_test_start,
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1545,
-@@ -3239,6 +3272,7 @@ static struct phy_driver marvell_drivers
- .cable_test_start = marvell_vct7_cable_test_start,
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E3016,
-@@ -3380,6 +3414,7 @@ static struct phy_driver marvell_drivers
- .get_stats = marvell_get_stats,
- .get_tunable = m88e1540_get_tunable,
- .set_tunable = m88e1540_set_tunable,
-+ .led_brightness_set = m88e1318_led_brightness_set,
- },
- };
-
diff --git a/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
deleted file mode 100644
index 00bdcc5468..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 4e901018432e38eab35d2a352661ce4727795be1 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:30 +0200
-Subject: [PATCH 8/9] net: phy: phy_device: Call into the PHY driver to set LED
- blinking
-
-Linux LEDs can be requested to perform hardware accelerated
-blinking. Pass this to the PHY driver, if it implements the op.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy_device.c | 18 ++++++++++++++++++
- include/linux/phy.h | 12 ++++++++++++
- 2 files changed, 30 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3052,6 +3052,22 @@ static int phy_led_set_brightness(struct
- return err;
- }
-
-+static int phy_led_blink_set(struct led_classdev *led_cdev,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+ int err;
-+
-+ mutex_lock(&phydev->lock);
-+ err = phydev->drv->led_blink_set(phydev, phyled->index,
-+ delay_on, delay_off);
-+ mutex_unlock(&phydev->lock);
-+
-+ return err;
-+}
-+
- static int of_phy_led(struct phy_device *phydev,
- struct device_node *led)
- {
-@@ -3074,6 +3090,8 @@ static int of_phy_led(struct phy_device
-
- if (phydev->drv->led_brightness_set)
- cdev->brightness_set_blocking = phy_led_set_brightness;
-+ if (phydev->drv->led_blink_set)
-+ cdev->blink_set = phy_led_blink_set;
- cdev->max_brightness = 1;
- init_data.devicename = dev_name(&phydev->mdio.dev);
- init_data.fwnode = of_fwnode_handle(led);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1014,6 +1014,18 @@ struct phy_driver {
- */
- int (*led_brightness_set)(struct phy_device *dev,
- u8 index, enum led_brightness value);
-+
-+ /**
-+ * @led_blink_set: Set a PHY LED brightness. Index indicates
-+ * which of the PHYs led should be configured to blink. Delays
-+ * are in milliseconds and if both are zero then a sensible
-+ * default should be chosen. The call should adjust the
-+ * timings in that case and if it can't match the values
-+ * specified exactly.
-+ */
-+ int (*led_blink_set)(struct phy_device *dev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off);
- };
- #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
- struct phy_driver, mdiodrv)
diff --git a/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch b/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch
deleted file mode 100644
index 8d5081a43c..0000000000
--- a/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From ea9e86485decb2ac1750005bd96c166c9b780406 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 17 Apr 2023 17:17:31 +0200
-Subject: [PATCH 9/9] net: phy: marvell: Implement led_blink_set()
-
-The Marvell PHY can blink the LEDs, simple on/off. All LEDs blink at
-the same rate, and the reset default is 84ms per blink, which is
-around 12Hz.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/marvell.c | 36 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 36 insertions(+)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -147,6 +147,8 @@
- #define MII_88E1318S_PHY_LED_FUNC 0x10
- #define MII_88E1318S_PHY_LED_FUNC_OFF (0x8)
- #define MII_88E1318S_PHY_LED_FUNC_ON (0x9)
-+#define MII_88E1318S_PHY_LED_FUNC_HI_Z (0xa)
-+#define MII_88E1318S_PHY_LED_FUNC_BLINK (0xb)
- #define MII_88E1318S_PHY_LED_TCR 0x12
- #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
- #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
-@@ -2862,6 +2864,35 @@ static int m88e1318_led_brightness_set(s
- MII_88E1318S_PHY_LED_FUNC, reg);
- }
-
-+static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ int reg;
-+
-+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC);
-+ if (reg < 0)
-+ return reg;
-+
-+ switch (index) {
-+ case 0:
-+ case 1:
-+ case 2:
-+ reg &= ~(0xf << (4 * index));
-+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
-+ /* Reset default is 84ms */
-+ *delay_on = 84 / 2;
-+ *delay_off = 84 / 2;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC, reg);
-+}
-+
- static int marvell_probe(struct phy_device *phydev)
- {
- struct marvell_priv *priv;
-@@ -3112,6 +3143,7 @@ static struct phy_driver marvell_drivers
- .get_strings = marvell_get_strings,
- .get_stats = marvell_get_stats,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1145,
-@@ -3219,6 +3251,7 @@ static struct phy_driver marvell_drivers
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1540,
-@@ -3246,6 +3279,7 @@ static struct phy_driver marvell_drivers
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1545,
-@@ -3273,6 +3307,7 @@ static struct phy_driver marvell_drivers
- .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E3016,
-@@ -3415,6 +3450,7 @@ static struct phy_driver marvell_drivers
- .get_tunable = m88e1540_get_tunable,
- .set_tunable = m88e1540_set_tunable,
- .led_brightness_set = m88e1318_led_brightness_set,
-+ .led_blink_set = m88e1318_led_blink_set,
- },
- };
-
diff --git a/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch b/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch
deleted file mode 100644
index 56df3f095e..0000000000
--- a/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 4774ad841bef97cc51df90195338c5b2573dd4cb Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 23 Apr 2023 19:28:00 +0200
-Subject: [PATCH] net: phy: marvell: Fix inconsistent indenting in
- led_blink_set
-
-Fix inconsistent indeinting in m88e1318_led_blink_set reported by kernel
-test robot, probably done by the presence of an if condition dropped in
-later revision of the same code.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Link: https://lore.kernel.org/oe-kbuild-all/202304240007.0VEX8QYG-lkp@intel.com/
-Fixes: ea9e86485dec ("net: phy: marvell: Implement led_blink_set()")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20230423172800.3470-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/marvell.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -2880,10 +2880,10 @@ static int m88e1318_led_blink_set(struct
- case 1:
- case 2:
- reg &= ~(0xf << (4 * index));
-- reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
-- /* Reset default is 84ms */
-- *delay_on = 84 / 2;
-- *delay_off = 84 / 2;
-+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
-+ /* Reset default is 84ms */
-+ *delay_on = 84 / 2;
-+ *delay_off = 84 / 2;
- break;
- default:
- return -EINVAL;
diff --git a/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch b/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch
deleted file mode 100644
index 3170c26058..0000000000
--- a/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From e2f24cb1b5daf9a4f6f3ba574c1fa74aab9807a4 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:40 +0200
-Subject: [PATCH 2/5] leds: trigger: netdev: Drop NETDEV_LED_MODE_LINKUP from
- mode
-
-Putting NETDEV_LED_MODE_LINKUP in the same list of the netdev trigger
-modes is wrong as it's used to set the link state of the device and not
-to set a blink mode as it's done by NETDEV_LED_LINK, NETDEV_LED_TX and
-NETDEV_LED_RX. It's also wrong to put this state in the same bitmap of the
-netdev trigger mode and should be external to it.
-
-Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool
-that will be true or false based on the carrier link. No functional
-change intended.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-3-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 19 ++++++++-----------
- 1 file changed, 8 insertions(+), 11 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -50,10 +50,10 @@ struct led_netdev_data {
- unsigned int last_activity;
-
- unsigned long mode;
-+ bool carrier_link_up;
- #define NETDEV_LED_LINK 0
- #define NETDEV_LED_TX 1
- #define NETDEV_LED_RX 2
--#define NETDEV_LED_MODE_LINKUP 3
- };
-
- enum netdev_led_attr {
-@@ -73,9 +73,9 @@ static void set_baseline_state(struct le
- if (!led_cdev->blink_brightness)
- led_cdev->blink_brightness = led_cdev->max_brightness;
-
-- if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode))
-+ if (!trigger_data->carrier_link_up) {
- led_set_brightness(led_cdev, LED_OFF);
-- else {
-+ } else {
- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode))
- led_set_brightness(led_cdev,
- led_cdev->blink_brightness);
-@@ -131,10 +131,9 @@ static ssize_t device_name_store(struct
- trigger_data->net_dev =
- dev_get_by_name(&init_net, trigger_data->device_name);
-
-- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = false;
- if (trigger_data->net_dev != NULL)
-- if (netif_carrier_ok(trigger_data->net_dev))
-- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev);
-
- trigger_data->last_activity = 0;
-
-@@ -315,11 +314,10 @@ static int netdev_trig_notify(struct not
-
- spin_lock_bh(&trigger_data->lock);
-
-- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = false;
- switch (evt) {
- case NETDEV_CHANGENAME:
-- if (netif_carrier_ok(dev))
-- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = netif_carrier_ok(dev);
- fallthrough;
- case NETDEV_REGISTER:
- if (trigger_data->net_dev)
-@@ -333,8 +331,7 @@ static int netdev_trig_notify(struct not
- break;
- case NETDEV_UP:
- case NETDEV_CHANGE:
-- if (netif_carrier_ok(dev))
-- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
-+ trigger_data->carrier_link_up = netif_carrier_ok(dev);
- break;
- }
-
diff --git a/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch b/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch
deleted file mode 100644
index 19cc1d7c9e..0000000000
--- a/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From bdec9cb83936e0ac4cb87fed5b49fad0175f7dec Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:41 +0200
-Subject: [PATCH 3/5] leds: trigger: netdev: Rename add namespace to netdev
- trigger enum modes
-
-Rename NETDEV trigger enum modes to a more symbolic name and add a
-namespace to them.
-
-Also add __TRIGGER_NETDEV_MAX to identify the max modes of the netdev
-trigger.
-
-This is a cleanup to drop the define and no behaviour change are
-intended.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-4-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 58 ++++++++++++---------------
- 1 file changed, 25 insertions(+), 33 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -51,15 +51,15 @@ struct led_netdev_data {
-
- unsigned long mode;
- bool carrier_link_up;
--#define NETDEV_LED_LINK 0
--#define NETDEV_LED_TX 1
--#define NETDEV_LED_RX 2
- };
-
--enum netdev_led_attr {
-- NETDEV_ATTR_LINK,
-- NETDEV_ATTR_TX,
-- NETDEV_ATTR_RX
-+enum led_trigger_netdev_modes {
-+ TRIGGER_NETDEV_LINK = 0,
-+ TRIGGER_NETDEV_TX,
-+ TRIGGER_NETDEV_RX,
-+
-+ /* Keep last */
-+ __TRIGGER_NETDEV_MAX,
- };
-
- static void set_baseline_state(struct led_netdev_data *trigger_data)
-@@ -76,7 +76,7 @@ static void set_baseline_state(struct le
- if (!trigger_data->carrier_link_up) {
- led_set_brightness(led_cdev, LED_OFF);
- } else {
-- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode))
-+ if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode))
- led_set_brightness(led_cdev,
- led_cdev->blink_brightness);
- else
-@@ -85,8 +85,8 @@ static void set_baseline_state(struct le
- /* If we are looking for RX/TX start periodically
- * checking stats
- */
-- if (test_bit(NETDEV_LED_TX, &trigger_data->mode) ||
-- test_bit(NETDEV_LED_RX, &trigger_data->mode))
-+ if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
- schedule_delayed_work(&trigger_data->work, 0);
- }
- }
-@@ -146,20 +146,16 @@ static ssize_t device_name_store(struct
- static DEVICE_ATTR_RW(device_name);
-
- static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
-- enum netdev_led_attr attr)
-+ enum led_trigger_netdev_modes attr)
- {
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
- int bit;
-
- switch (attr) {
-- case NETDEV_ATTR_LINK:
-- bit = NETDEV_LED_LINK;
-- break;
-- case NETDEV_ATTR_TX:
-- bit = NETDEV_LED_TX;
-- break;
-- case NETDEV_ATTR_RX:
-- bit = NETDEV_LED_RX;
-+ case TRIGGER_NETDEV_LINK:
-+ case TRIGGER_NETDEV_TX:
-+ case TRIGGER_NETDEV_RX:
-+ bit = attr;
- break;
- default:
- return -EINVAL;
-@@ -169,7 +165,7 @@ static ssize_t netdev_led_attr_show(stru
- }
-
- static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
-- size_t size, enum netdev_led_attr attr)
-+ size_t size, enum led_trigger_netdev_modes attr)
- {
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
- unsigned long state;
-@@ -181,14 +177,10 @@ static ssize_t netdev_led_attr_store(str
- return ret;
-
- switch (attr) {
-- case NETDEV_ATTR_LINK:
-- bit = NETDEV_LED_LINK;
-- break;
-- case NETDEV_ATTR_TX:
-- bit = NETDEV_LED_TX;
-- break;
-- case NETDEV_ATTR_RX:
-- bit = NETDEV_LED_RX;
-+ case TRIGGER_NETDEV_LINK:
-+ case TRIGGER_NETDEV_TX:
-+ case TRIGGER_NETDEV_RX:
-+ bit = attr;
- break;
- default:
- return -EINVAL;
-@@ -360,21 +352,21 @@ static void netdev_trig_work(struct work
- }
-
- /* If we are not looking for RX/TX then return */
-- if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) &&
-- !test_bit(NETDEV_LED_RX, &trigger_data->mode))
-+ if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) &&
-+ !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
- return;
-
- dev_stats = dev_get_stats(trigger_data->net_dev, &temp);
- new_activity =
-- (test_bit(NETDEV_LED_TX, &trigger_data->mode) ?
-+ (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ?
- dev_stats->tx_packets : 0) +
-- (test_bit(NETDEV_LED_RX, &trigger_data->mode) ?
-+ (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ?
- dev_stats->rx_packets : 0);
-
- if (trigger_data->last_activity != new_activity) {
- led_stop_software_blink(trigger_data->led_cdev);
-
-- invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode);
-+ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode);
- interval = jiffies_to_msecs(
- atomic_read(&trigger_data->interval));
- /* base state is ON (link present) */
diff --git a/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch b/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch
deleted file mode 100644
index 3b45951f57..0000000000
--- a/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 164b67d53476a9d114be85c885bd31f783835be4 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:42 +0200
-Subject: [PATCH 4/5] leds: trigger: netdev: Convert device attr to macro
-
-Convert link tx and rx device attr to a common macro to reduce common
-code and in preparation for additional attr.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-5-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++-------------------
- 1 file changed, 16 insertions(+), 41 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -198,47 +198,22 @@ static ssize_t netdev_led_attr_store(str
- return size;
- }
-
--static ssize_t link_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK);
--}
--
--static ssize_t link_store(struct device *dev,
-- struct device_attribute *attr, const char *buf, size_t size)
--{
-- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK);
--}
--
--static DEVICE_ATTR_RW(link);
--
--static ssize_t tx_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX);
--}
--
--static ssize_t tx_store(struct device *dev,
-- struct device_attribute *attr, const char *buf, size_t size)
--{
-- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX);
--}
--
--static DEVICE_ATTR_RW(tx);
--
--static ssize_t rx_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX);
--}
--
--static ssize_t rx_store(struct device *dev,
-- struct device_attribute *attr, const char *buf, size_t size)
--{
-- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX);
--}
--
--static DEVICE_ATTR_RW(rx);
-+#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \
-+ static ssize_t trigger_name##_show(struct device *dev, \
-+ struct device_attribute *attr, char *buf) \
-+ { \
-+ return netdev_led_attr_show(dev, buf, trigger); \
-+ } \
-+ static ssize_t trigger_name##_store(struct device *dev, \
-+ struct device_attribute *attr, const char *buf, size_t size) \
-+ { \
-+ return netdev_led_attr_store(dev, buf, size, trigger); \
-+ } \
-+ static DEVICE_ATTR_RW(trigger_name)
-+
-+DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK);
-+DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
-+DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX);
-
- static ssize_t interval_show(struct device *dev,
- struct device_attribute *attr, char *buf)
diff --git a/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch b/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch
deleted file mode 100644
index 180bee9612..0000000000
--- a/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From d1b9e1391ab2dc80e9db87fe8b2de015c651e4c9 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 19 Apr 2023 23:07:43 +0200
-Subject: [PATCH 5/5] leds: trigger: netdev: Use mutex instead of spinlocks
-
-Some LEDs may require to sleep while doing some operation like setting
-brightness and other cleanup.
-
-For this reason, using a spinlock will cause a sleep under spinlock
-warning.
-
-It should be safe to convert this to a sleepable lock since:
-- sysfs read/write can sleep
-- netdev_trig_work is a work queue and can sleep
-- netdev _trig_notify can sleep
-
-The spinlock was used when brightness didn't support sleeping, but this
-changed and now it supported with brightness_set_blocking().
-
-Convert to mutex lock to permit sleeping using brightness_set_blocking().
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com
----
- drivers/leds/trigger/ledtrig-netdev.c | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -20,7 +20,7 @@
- #include <linux/list.h>
- #include <linux/module.h>
- #include <linux/netdevice.h>
--#include <linux/spinlock.h>
-+#include <linux/mutex.h>
- #include <linux/timer.h>
- #include "../leds.h"
-
-@@ -37,7 +37,7 @@
- */
-
- struct led_netdev_data {
-- spinlock_t lock;
-+ struct mutex lock;
-
- struct delayed_work work;
- struct notifier_block notifier;
-@@ -97,9 +97,9 @@ static ssize_t device_name_show(struct d
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
- ssize_t len;
-
-- spin_lock_bh(&trigger_data->lock);
-+ mutex_lock(&trigger_data->lock);
- len = sprintf(buf, "%s\n", trigger_data->device_name);
-- spin_unlock_bh(&trigger_data->lock);
-+ mutex_unlock(&trigger_data->lock);
-
- return len;
- }
-@@ -115,7 +115,7 @@ static ssize_t device_name_store(struct
-
- cancel_delayed_work_sync(&trigger_data->work);
-
-- spin_lock_bh(&trigger_data->lock);
-+ mutex_lock(&trigger_data->lock);
-
- if (trigger_data->net_dev) {
- dev_put(trigger_data->net_dev);
-@@ -138,7 +138,7 @@ static ssize_t device_name_store(struct
- trigger_data->last_activity = 0;
-
- set_baseline_state(trigger_data);
-- spin_unlock_bh(&trigger_data->lock);
-+ mutex_unlock(&trigger_data->lock);
-
- return size;
- }
-@@ -279,7 +279,7 @@ static int netdev_trig_notify(struct not
-
- cancel_delayed_work_sync(&trigger_data->work);
-
-- spin_lock_bh(&trigger_data->lock);
-+ mutex_lock(&trigger_data->lock);
-
- trigger_data->carrier_link_up = false;
- switch (evt) {
-@@ -304,7 +304,7 @@ static int netdev_trig_notify(struct not
-
- set_baseline_state(trigger_data);
-
-- spin_unlock_bh(&trigger_data->lock);
-+ mutex_unlock(&trigger_data->lock);
-
- return NOTIFY_DONE;
- }
-@@ -365,7 +365,7 @@ static int netdev_trig_activate(struct l
- if (!trigger_data)
- return -ENOMEM;
-
-- spin_lock_init(&trigger_data->lock);
-+ mutex_init(&trigger_data->lock);
-
- trigger_data->notifier.notifier_call = netdev_trig_notify;
- trigger_data->notifier.priority = 10;
diff --git a/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch b/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch
deleted file mode 100644
index ac18611733..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From ed554d3f945179c5b159bddfad7be34b403fe11a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:31 +0200
-Subject: [PATCH 01/13] leds: add APIs for LEDs hw control
-
-Add an option to permit LED driver to declare support for a specific
-trigger to use hw control and setup the LED to blink based on specific
-provided modes.
-
-Add APIs for LEDs hw control. These functions will be used to activate
-hardware control where a LED will use the provided flags, from an
-unique defined supported trigger, to setup the LED to be driven by
-hardware.
-
-Add hw_control_is_supported() to ask the LED driver if the requested
-mode by the trigger are supported and the LED can be setup to follow
-the requested modes.
-
-Deactivate hardware blink control by setting brightness to LED_OFF via
-the brightness_set() callback.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/leds.h | 37 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 37 insertions(+)
-
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -164,6 +164,43 @@ struct led_classdev {
-
- /* LEDs that have private triggers have this set */
- struct led_hw_trigger_type *trigger_type;
-+
-+ /* Unique trigger name supported by LED set in hw control mode */
-+ const char *hw_control_trigger;
-+ /*
-+ * Check if the LED driver supports the requested mode provided by the
-+ * defined supported trigger to setup the LED to hw control mode.
-+ *
-+ * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not
-+ * supported and software fallback needs to be used.
-+ * Return a negative error number on any other case for check fail due
-+ * to various reason like device not ready or timeouts.
-+ */
-+ int (*hw_control_is_supported)(struct led_classdev *led_cdev,
-+ unsigned long flags);
-+ /*
-+ * Activate hardware control, LED driver will use the provided flags
-+ * from the supported trigger and setup the LED to be driven by hardware
-+ * following the requested mode from the trigger flags.
-+ * Deactivate hardware blink control by setting brightness to LED_OFF via
-+ * the brightness_set() callback.
-+ *
-+ * Return 0 on success, a negative error number on flags apply fail.
-+ */
-+ int (*hw_control_set)(struct led_classdev *led_cdev,
-+ unsigned long flags);
-+ /*
-+ * Get from the LED driver the current mode that the LED is set in hw
-+ * control mode and put them in flags.
-+ * Trigger can use this to get the initial state of a LED already set in
-+ * hardware blink control.
-+ *
-+ * Return 0 on success, a negative error number on failing parsing the
-+ * initial mode. Error from this function is NOT FATAL as the device
-+ * may be in a not supported initial state by the attached LED trigger.
-+ */
-+ int (*hw_control_get)(struct led_classdev *led_cdev,
-+ unsigned long *flags);
- #endif
-
- #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
diff --git a/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch b/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch
deleted file mode 100644
index 1a221727a0..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 052c38eb17e866c5b4cd43924e7a5e20167b55c0 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:32 +0200
-Subject: [PATCH 02/13] leds: add API to get attached device for LED hw control
-
-Some specific LED triggers blink the LED based on events from a device
-or subsystem.
-For example, an LED could be blinked to indicate a network device is
-receiving packets, or a disk is reading blocks. To correctly enable and
-request the hw control of the LED, the trigger has to check if the
-network interface or block device configured via a /sys/class/led file
-match the one the LED driver provide for hw control for.
-
-Provide an API call to get the device which the LED blinks for.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/leds.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -201,6 +201,12 @@ struct led_classdev {
- */
- int (*hw_control_get)(struct led_classdev *led_cdev,
- unsigned long *flags);
-+ /*
-+ * Get the device this LED blinks in response to.
-+ * e.g. for a PHY LED, it is the network device. If the LED is
-+ * not yet associated to a device, return NULL.
-+ */
-+ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev);
- #endif
-
- #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
diff --git a/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch b/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch
deleted file mode 100644
index af9fb7fdc3..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 8aa2fd7b66980ecd2e45e95af61cf7eafede1211 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:33 +0200
-Subject: [PATCH 03/13] Documentation: leds: leds-class: Document new Hardware
- driven LEDs APIs
-
-Document new Hardware driven LEDs APIs.
-
-Some LEDs can be programmed to be driven by hardware. This is not
-limited to blink but also to turn off or on autonomously.
-To support this feature, a LED needs to implement various additional
-ops and needs to declare specific support for the supported triggers.
-
-Add documentation for each required value and API to make hw control
-possible and implementable by both LEDs and triggers.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/leds/leds-class.rst | 81 +++++++++++++++++++++++++++++++
- 1 file changed, 81 insertions(+)
-
---- a/Documentation/leds/leds-class.rst
-+++ b/Documentation/leds/leds-class.rst
-@@ -169,6 +169,87 @@ Setting the brightness to zero with brig
- should completely turn off the LED and cancel the previously programmed
- hardware blinking function, if any.
-
-+Hardware driven LEDs
-+====================
-+
-+Some LEDs can be programmed to be driven by hardware. This is not
-+limited to blink but also to turn off or on autonomously.
-+To support this feature, a LED needs to implement various additional
-+ops and needs to declare specific support for the supported triggers.
-+
-+With hw control we refer to the LED driven by hardware.
-+
-+LED driver must define the following value to support hw control:
-+
-+ - hw_control_trigger:
-+ unique trigger name supported by the LED in hw control
-+ mode.
-+
-+LED driver must implement the following API to support hw control:
-+ - hw_control_is_supported:
-+ check if the flags passed by the supported trigger can
-+ be parsed and activate hw control on the LED.
-+
-+ Return 0 if the passed flags mask is supported and
-+ can be set with hw_control_set().
-+
-+ If the passed flags mask is not supported -EOPNOTSUPP
-+ must be returned, the LED trigger will use software
-+ fallback in this case.
-+
-+ Return a negative error in case of any other error like
-+ device not ready or timeouts.
-+
-+ - hw_control_set:
-+ activate hw control. LED driver will use the provided
-+ flags passed from the supported trigger, parse them to
-+ a set of mode and setup the LED to be driven by hardware
-+ following the requested modes.
-+
-+ Set LED_OFF via the brightness_set to deactivate hw control.
-+
-+ Return 0 on success, a negative error number on failing to
-+ apply flags.
-+
-+ - hw_control_get:
-+ get active modes from a LED already in hw control, parse
-+ them and set in flags the current active flags for the
-+ supported trigger.
-+
-+ Return 0 on success, a negative error number on failing
-+ parsing the initial mode.
-+ Error from this function is NOT FATAL as the device may
-+ be in a not supported initial state by the attached LED
-+ trigger.
-+
-+ - hw_control_get_device:
-+ return the device associated with the LED driver in
-+ hw control. A trigger might use this to match the
-+ returned device from this function with a configured
-+ device for the trigger as the source for blinking
-+ events and correctly enable hw control.
-+ (example a netdev trigger configured to blink for a
-+ particular dev match the returned dev from get_device
-+ to set hw control)
-+
-+ Returns a pointer to a struct device or NULL if nothing
-+ is currently attached.
-+
-+LED driver can activate additional modes by default to workaround the
-+impossibility of supporting each different mode on the supported trigger.
-+Examples are hardcoding the blink speed to a set interval, enable special
-+feature like bypassing blink if some requirements are not met.
-+
-+A trigger should first check if the hw control API are supported by the LED
-+driver and check if the trigger is supported to verify if hw control is possible,
-+use hw_control_is_supported to check if the flags are supported and only at
-+the end use hw_control_set to activate hw control.
-+
-+A trigger can use hw_control_get to check if a LED is already in hw control
-+and init their flags.
-+
-+When the LED is in hw control, no software blink is possible and doing so
-+will effectively disable hw control.
-
- Known Issues
- ============
diff --git a/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch b/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch
deleted file mode 100644
index 3c804c0b41..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 28a6a2ef18ad840a390d519840c303b03040961c Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:34 +0200
-Subject: [PATCH 04/13] leds: trigger: netdev: refactor code setting device
- name
-
-Move the code into a helper, ready for it to be called at
-other times. No intended behaviour change.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 29 ++++++++++++++++++---------
- 1 file changed, 20 insertions(+), 9 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -104,15 +104,9 @@ static ssize_t device_name_show(struct d
- return len;
- }
-
--static ssize_t device_name_store(struct device *dev,
-- struct device_attribute *attr, const char *buf,
-- size_t size)
-+static int set_device_name(struct led_netdev_data *trigger_data,
-+ const char *name, size_t size)
- {
-- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
--
-- if (size >= IFNAMSIZ)
-- return -EINVAL;
--
- cancel_delayed_work_sync(&trigger_data->work);
-
- mutex_lock(&trigger_data->lock);
-@@ -122,7 +116,7 @@ static ssize_t device_name_store(struct
- trigger_data->net_dev = NULL;
- }
-
-- memcpy(trigger_data->device_name, buf, size);
-+ memcpy(trigger_data->device_name, name, size);
- trigger_data->device_name[size] = 0;
- if (size > 0 && trigger_data->device_name[size - 1] == '\n')
- trigger_data->device_name[size - 1] = 0;
-@@ -140,6 +134,23 @@ static ssize_t device_name_store(struct
- set_baseline_state(trigger_data);
- mutex_unlock(&trigger_data->lock);
-
-+ return 0;
-+}
-+
-+static ssize_t device_name_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf,
-+ size_t size)
-+{
-+ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
-+ int ret;
-+
-+ if (size >= IFNAMSIZ)
-+ return -EINVAL;
-+
-+ ret = set_device_name(trigger_data, buf, size);
-+
-+ if (ret < 0)
-+ return ret;
- return size;
- }
-
diff --git a/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch b/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch
deleted file mode 100644
index 284b519482..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 4fd1b6d47a7a38e81fdc6f8be2ccd4216b3f93db Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:35 +0200
-Subject: [PATCH 05/13] leds: trigger: netdev: introduce check for possible hw
- control
-
-Introduce function to check if the requested mode can use hw control in
-preparation for hw control support. Currently everything is handled in
-software so can_hw_control will always return false.
-
-Add knob with the new value hw_control in trigger_data struct to
-set hw control possible. Useful for future implementation to implement
-in set_baseline_state() the required function to set the requested mode
-using LEDs hw control ops and in other function to reject set if hw
-control is currently active.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -51,6 +51,7 @@ struct led_netdev_data {
-
- unsigned long mode;
- bool carrier_link_up;
-+ bool hw_control;
- };
-
- enum led_trigger_netdev_modes {
-@@ -91,6 +92,11 @@ static void set_baseline_state(struct le
- }
- }
-
-+static bool can_hw_control(struct led_netdev_data *trigger_data)
-+{
-+ return false;
-+}
-+
- static ssize_t device_name_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -204,6 +210,8 @@ static ssize_t netdev_led_attr_store(str
- else
- clear_bit(bit, &trigger_data->mode);
-
-+ trigger_data->hw_control = can_hw_control(trigger_data);
-+
- set_baseline_state(trigger_data);
-
- return size;
diff --git a/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch b/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch
deleted file mode 100644
index 09759bc623..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 6352f25f9fadba59d5df2ba7139495759ccc81d5 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:36 +0200
-Subject: [PATCH 06/13] leds: trigger: netdev: add basic check for hw control
- support
-
-Add basic check for hw control support. Check if the required API are
-defined and check if the defined trigger supported in hw control for the
-LED driver match netdev.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -92,8 +92,22 @@ static void set_baseline_state(struct le
- }
- }
-
-+static bool supports_hw_control(struct led_classdev *led_cdev)
-+{
-+ if (!led_cdev->hw_control_get || !led_cdev->hw_control_set ||
-+ !led_cdev->hw_control_is_supported)
-+ return false;
-+
-+ return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name);
-+}
-+
- static bool can_hw_control(struct led_netdev_data *trigger_data)
- {
-+ struct led_classdev *led_cdev = trigger_data->led_cdev;
-+
-+ if (!supports_hw_control(led_cdev))
-+ return false;
-+
- return false;
- }
-
diff --git a/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch b/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch
deleted file mode 100644
index 6634906800..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From c84c80c7388f887b10dafd70fc55bc6c5fe9fa5a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:37 +0200
-Subject: [PATCH 07/13] leds: trigger: netdev: reject interval store for
- hw_control
-
-Reject interval store with hw_control enabled. It's are currently not
-supported and MUST be set to the default value with hw control enabled.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -265,6 +265,9 @@ static ssize_t interval_store(struct dev
- unsigned long value;
- int ret;
-
-+ if (trigger_data->hw_control)
-+ return -EINVAL;
-+
- ret = kstrtoul(buf, 0, &value);
- if (ret)
- return ret;
diff --git a/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch b/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch
deleted file mode 100644
index 52faa4809b..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 7c145a34ba6e380616af93262fcab9fc7261d851 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:38 +0200
-Subject: [PATCH 08/13] leds: trigger: netdev: add support for LED hw control
-
-Add support for LED hw control for the netdev trigger.
-
-The trigger on calling set_baseline_state to configure a new mode, will
-do various check to verify if hw control can be used for the requested
-mode in can_hw_control() function.
-
-It will first check if the LED driver supports hw control for the netdev
-trigger, then will use hw_control_is_supported() and finally will call
-hw_control_set() to apply the requested mode.
-
-To use such mode, interval MUST be set to the default value and net_dev
-MUST be set. If one of these 2 value are not valid, hw control will
-never be used and normal software fallback is used.
-
-The default interval value is moved to a define to make sure they are
-always synced.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 43 +++++++++++++++++++++++++--
- 1 file changed, 41 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -24,6 +24,8 @@
- #include <linux/timer.h>
- #include "../leds.h"
-
-+#define NETDEV_LED_DEFAULT_INTERVAL 50
-+
- /*
- * Configurable sysfs attributes:
- *
-@@ -68,6 +70,13 @@ static void set_baseline_state(struct le
- int current_brightness;
- struct led_classdev *led_cdev = trigger_data->led_cdev;
-
-+ /* Already validated, hw control is possible with the requested mode */
-+ if (trigger_data->hw_control) {
-+ led_cdev->hw_control_set(led_cdev, trigger_data->mode);
-+
-+ return;
-+ }
-+
- current_brightness = led_cdev->brightness;
- if (current_brightness)
- led_cdev->blink_brightness = current_brightness;
-@@ -103,12 +112,42 @@ static bool supports_hw_control(struct l
-
- static bool can_hw_control(struct led_netdev_data *trigger_data)
- {
-+ unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL);
-+ unsigned int interval = atomic_read(&trigger_data->interval);
- struct led_classdev *led_cdev = trigger_data->led_cdev;
-+ int ret;
-
- if (!supports_hw_control(led_cdev))
- return false;
-
-- return false;
-+ /*
-+ * Interval must be set to the default
-+ * value. Any different value is rejected if in hw
-+ * control.
-+ */
-+ if (interval != default_interval)
-+ return false;
-+
-+ /*
-+ * net_dev must be set with hw control, otherwise no
-+ * blinking can be happening and there is nothing to
-+ * offloaded.
-+ */
-+ if (!trigger_data->net_dev)
-+ return false;
-+
-+ /* Check if the requested mode is supported */
-+ ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode);
-+ /* Fall back to software blinking if not supported */
-+ if (ret == -EOPNOTSUPP)
-+ return false;
-+ if (ret) {
-+ dev_warn(led_cdev->dev,
-+ "Current mode check failed with error %d\n", ret);
-+ return false;
-+ }
-+
-+ return true;
- }
-
- static ssize_t device_name_show(struct device *dev,
-@@ -413,7 +452,7 @@ static int netdev_trig_activate(struct l
- trigger_data->device_name[0] = 0;
-
- trigger_data->mode = 0;
-- atomic_set(&trigger_data->interval, msecs_to_jiffies(50));
-+ atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL));
- trigger_data->last_activity = 0;
-
- led_set_trigger_data(led_cdev, trigger_data);
diff --git a/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch b/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch
deleted file mode 100644
index c129ffa4f5..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 33ec0b53befff2c0a7f3aa19ff08556d60585d6b Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:39 +0200
-Subject: [PATCH 09/13] leds: trigger: netdev: validate configured netdev
-
-The netdev which the LED should blink for is configurable in
-/sys/class/led/foo/device_name. Ensure when offloading that the
-configured netdev is the same as the netdev the LED is associated
-with. If it is not, only perform software blinking.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 24 ++++++++++++++++++++++--
- 1 file changed, 22 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -110,6 +110,24 @@ static bool supports_hw_control(struct l
- return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name);
- }
-
-+/*
-+ * Validate the configured netdev is the same as the one associated with
-+ * the LED driver in hw control.
-+ */
-+static bool validate_net_dev(struct led_classdev *led_cdev,
-+ struct net_device *net_dev)
-+{
-+ struct device *dev = led_cdev->hw_control_get_device(led_cdev);
-+ struct net_device *ndev;
-+
-+ if (!dev)
-+ return false;
-+
-+ ndev = to_net_dev(dev);
-+
-+ return ndev == net_dev;
-+}
-+
- static bool can_hw_control(struct led_netdev_data *trigger_data)
- {
- unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL);
-@@ -131,9 +149,11 @@ static bool can_hw_control(struct led_ne
- /*
- * net_dev must be set with hw control, otherwise no
- * blinking can be happening and there is nothing to
-- * offloaded.
-+ * offloaded. Additionally, for hw control to be
-+ * valid, the configured netdev must be the same as
-+ * netdev associated to the LED.
- */
-- if (!trigger_data->net_dev)
-+ if (!validate_net_dev(led_cdev, trigger_data->net_dev))
- return false;
-
- /* Check if the requested mode is supported */
diff --git a/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch b/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch
deleted file mode 100644
index e20594c99a..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 0316cc5629d15880dd3f097d221c55ca648bcd61 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:40 +0200
-Subject: [PATCH 10/13] leds: trigger: netdev: init mode if hw control already
- active
-
-On netdev trigger activation, hw control may be already active by
-default. If this is the case and a device is actually provided by
-hw_control_get_device(), init the already active mode and set the
-bool to hw_control bool to true to reflect the already set mode in the
-trigger_data.
-
-Co-developed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -454,6 +454,8 @@ static void netdev_trig_work(struct work
- static int netdev_trig_activate(struct led_classdev *led_cdev)
- {
- struct led_netdev_data *trigger_data;
-+ unsigned long mode;
-+ struct device *dev;
- int rc;
-
- trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
-@@ -475,6 +477,21 @@ static int netdev_trig_activate(struct l
- atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL));
- trigger_data->last_activity = 0;
-
-+ /* Check if hw control is active by default on the LED.
-+ * Init already enabled mode in hw control.
-+ */
-+ if (supports_hw_control(led_cdev) &&
-+ !led_cdev->hw_control_get(led_cdev, &mode)) {
-+ dev = led_cdev->hw_control_get_device(led_cdev);
-+ if (dev) {
-+ const char *name = dev_name(dev);
-+
-+ set_device_name(trigger_data, name, strlen(name));
-+ trigger_data->hw_control = true;
-+ trigger_data->mode = mode;
-+ }
-+ }
-+
- led_set_trigger_data(led_cdev, trigger_data);
-
- rc = register_netdevice_notifier(&trigger_data->notifier);
diff --git a/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch b/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch
deleted file mode 100644
index 70aed850d1..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 947acacab5ea151291b861cdfbde16ff5cf1b08c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:41 +0200
-Subject: [PATCH 11/13] leds: trigger: netdev: expose netdev trigger modes in
- linux include
-
-Expose netdev trigger modes to make them accessible by LED driver that
-will support netdev trigger for hw control.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 9 ---------
- include/linux/leds.h | 10 ++++++++++
- 2 files changed, 10 insertions(+), 9 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -56,15 +56,6 @@ struct led_netdev_data {
- bool hw_control;
- };
-
--enum led_trigger_netdev_modes {
-- TRIGGER_NETDEV_LINK = 0,
-- TRIGGER_NETDEV_TX,
-- TRIGGER_NETDEV_RX,
--
-- /* Keep last */
-- __TRIGGER_NETDEV_MAX,
--};
--
- static void set_baseline_state(struct led_netdev_data *trigger_data)
- {
- int current_brightness;
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -527,6 +527,16 @@ static inline void *led_get_trigger_data
-
- #endif /* CONFIG_LEDS_TRIGGERS */
-
-+/* Trigger specific enum */
-+enum led_trigger_netdev_modes {
-+ TRIGGER_NETDEV_LINK = 0,
-+ TRIGGER_NETDEV_TX,
-+ TRIGGER_NETDEV_RX,
-+
-+ /* Keep last */
-+ __TRIGGER_NETDEV_MAX,
-+};
-+
- /* Trigger specific functions */
- #ifdef CONFIG_LEDS_TRIGGER_DISK
- void ledtrig_disk_activity(bool write);
diff --git a/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch b/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch
deleted file mode 100644
index ad76d89b7b..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch
+++ /dev/null
@@ -1,200 +0,0 @@
-From e0256648c831af13cbfe4a1787327fcec01c2807 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 29 May 2023 18:32:42 +0200
-Subject: [PATCH 12/13] net: dsa: qca8k: implement hw_control ops
-
-Implement hw_control ops to drive Switch LEDs based on hardware events.
-
-Netdev trigger is the declared supported trigger for hw control
-operation and supports the following mode:
-- tx
-- rx
-
-When hw_control_set is called, LEDs are set to follow the requested
-mode.
-Each LEDs will blink at 4Hz by default.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-leds.c | 154 +++++++++++++++++++++++++++++++
- 1 file changed, 154 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-leds.c
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -32,6 +32,43 @@ qca8k_get_enable_led_reg(int port_num, i
- }
-
- static int
-+qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
-+{
-+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
-+
-+ /* 6 total control rule:
-+ * 3 control rules for phy0-3 that applies to all their leds
-+ * 3 control rules for phy4
-+ */
-+ if (port_num == 4)
-+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
-+ else
-+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
-+
-+ return 0;
-+}
-+
-+static int
-+qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger)
-+{
-+ /* Parsing specific to netdev trigger */
-+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
-+ *offload_trigger |= QCA8K_LED_TX_BLINK_MASK;
-+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
-+ *offload_trigger |= QCA8K_LED_RX_BLINK_MASK;
-+
-+ if (rules && !*offload_trigger)
-+ return -EOPNOTSUPP;
-+
-+ /* Enable some default rule by default to the requested mode:
-+ * - Blink at 4Hz by default
-+ */
-+ *offload_trigger |= QCA8K_LED_BLINK_4HZ;
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_led_brightness_set(struct qca8k_led *led,
- enum led_brightness brightness)
- {
-@@ -165,6 +202,119 @@ qca8k_cled_blink_set(struct led_classdev
- }
-
- static int
-+qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 mask, val = QCA8K_LED_ALWAYS_OFF;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ if (enable)
-+ val = QCA8K_LED_RULE_CONTROLLED;
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ mask = QCA8K_LED_PATTERN_EN_MASK;
-+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
-+ val << reg_info.shift);
-+}
-+
-+static bool
-+qca8k_cled_hw_control_status(struct led_classdev *ldev)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 val;
-+
-+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ regmap_read(priv->regmap, reg_info.reg, &val);
-+
-+ val >>= reg_info.shift;
-+
-+ if (led->port_num == 0 || led->port_num == 4) {
-+ val &= QCA8K_LED_PATTERN_EN_MASK;
-+ val >>= QCA8K_LED_PATTERN_EN_SHIFT;
-+ } else {
-+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
-+ }
-+
-+ return val == QCA8K_LED_RULE_CONTROLLED;
-+}
-+
-+static int
-+qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
-+{
-+ u32 offload_trigger = 0;
-+
-+ return qca8k_parse_netdev(rules, &offload_trigger);
-+}
-+
-+static int
-+qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 offload_trigger = 0;
-+ int ret;
-+
-+ ret = qca8k_parse_netdev(rules, &offload_trigger);
-+ if (ret)
-+ return ret;
-+
-+ ret = qca8k_cled_trigger_offload(ldev, true);
-+ if (ret)
-+ return ret;
-+
-+ qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ return regmap_update_bits(priv->regmap, reg_info.reg,
-+ QCA8K_LED_RULE_MASK << reg_info.shift,
-+ offload_trigger << reg_info.shift);
-+}
-+
-+static int
-+qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ struct qca8k_led_pattern_en reg_info;
-+ struct qca8k_priv *priv = led->priv;
-+ u32 val;
-+ int ret;
-+
-+ /* With hw control not active return err */
-+ if (!qca8k_cled_hw_control_status(ldev))
-+ return -EINVAL;
-+
-+ qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
-+
-+ ret = regmap_read(priv->regmap, reg_info.reg, &val);
-+ if (ret)
-+ return ret;
-+
-+ val >>= reg_info.shift;
-+ val &= QCA8K_LED_RULE_MASK;
-+
-+ /* Parsing specific to netdev trigger */
-+ if (val & QCA8K_LED_TX_BLINK_MASK)
-+ set_bit(TRIGGER_NETDEV_TX, rules);
-+ if (val & QCA8K_LED_RX_BLINK_MASK)
-+ set_bit(TRIGGER_NETDEV_RX, rules);
-+
-+ return 0;
-+}
-+
-+static int
- qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
- {
- struct fwnode_handle *led = NULL, *leds = NULL;
-@@ -224,6 +374,10 @@ qca8k_parse_port_leds(struct qca8k_priv
- port_led->cdev.max_brightness = 1;
- port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
- port_led->cdev.blink_set = qca8k_cled_blink_set;
-+ port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported;
-+ port_led->cdev.hw_control_set = qca8k_cled_hw_control_set;
-+ port_led->cdev.hw_control_get = qca8k_cled_hw_control_get;
-+ port_led->cdev.hw_control_trigger = "netdev";
- init_data.default_label = ":port";
- init_data.fwnode = led;
- init_data.devname_mandatory = true;
diff --git a/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch b/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch
deleted file mode 100644
index feb6b9e1e4..0000000000
--- a/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 4f53c27f772e27e4cf4e5507d6f4d5980002cb6a Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Mon, 29 May 2023 18:32:43 +0200
-Subject: [PATCH 13/13] net: dsa: qca8k: add op to get ports netdev
-
-In order that the LED trigger can blink the switch MAC ports LED, it
-needs to know the netdev associated to the port. Add the callback to
-return the struct device of the netdev.
-
-Add an helper function qca8k_phy_to_port() to convert the phy back to
-dsa_port index, as we reference LED port based on the internal PHY
-index and needs to be converted back.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca/qca8k-leds.c | 27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-leds.c
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -5,6 +5,18 @@
- #include "qca8k.h"
- #include "qca8k_leds.h"
-
-+static u32 qca8k_phy_to_port(int phy)
-+{
-+ /* Internal PHY 0 has port at index 1.
-+ * Internal PHY 1 has port at index 2.
-+ * Internal PHY 2 has port at index 3.
-+ * Internal PHY 3 has port at index 4.
-+ * Internal PHY 4 has port at index 5.
-+ */
-+
-+ return phy + 1;
-+}
-+
- static int
- qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
- {
-@@ -314,6 +326,20 @@ qca8k_cled_hw_control_get(struct led_cla
- return 0;
- }
-
-+static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev)
-+{
-+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
-+ struct qca8k_priv *priv = led->priv;
-+ struct dsa_port *dp;
-+
-+ dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num));
-+ if (!dp)
-+ return NULL;
-+ if (dp->slave)
-+ return &dp->slave->dev;
-+ return NULL;
-+}
-+
- static int
- qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
- {
-@@ -377,6 +403,7 @@ qca8k_parse_port_leds(struct qca8k_priv
- port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported;
- port_led->cdev.hw_control_set = qca8k_cled_hw_control_set;
- port_led->cdev.hw_control_get = qca8k_cled_hw_control_get;
-+ port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device;
- port_led->cdev.hw_control_trigger = "netdev";
- init_data.default_label = ":port";
- init_data.fwnode = led;
diff --git a/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch b/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch
deleted file mode 100644
index 1c564b3897..0000000000
--- a/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From d5e01266e7f5fa12400d4c8aa4e86fe89dcc61e9 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 19 Jun 2023 22:46:58 +0200
-Subject: [PATCH 1/3] leds: trigger: netdev: add additional specific link speed
- mode
-
-Add additional modes for specific link speed. Use ethtool APIs to get the
-current link speed and enable the LED accordingly. Under netdev event
-handler the rtnl lock is already held and is not needed to be set to
-access ethtool APIs.
-
-This is especially useful for PHY and Switch that supports LEDs hw
-control for specific link speed. (example scenario a PHY that have 2 LED
-connected one green and one orange where the green is turned on with
-1000mbps speed and orange is turned on with 10mpbs speed)
-
-On mode set from sysfs we check if we have enabled split link speed mode
-and reject enabling generic link mode to prevent wrong and redundant
-configuration.
-
-Rework logic on the set baseline state to support these new modes to
-select if we need to turn on or off the LED.
-
-Add additional modes:
-- link_10: Turn on LED when link speed is 10mbps
-- link_100: Turn on LED when link speed is 100mbps
-- link_1000: Turn on LED when link speed is 1000mbps
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Lee Jones <lee@kernel.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 80 +++++++++++++++++++++++----
- include/linux/leds.h | 3 +
- 2 files changed, 73 insertions(+), 10 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -13,6 +13,7 @@
- #include <linux/atomic.h>
- #include <linux/ctype.h>
- #include <linux/device.h>
-+#include <linux/ethtool.h>
- #include <linux/init.h>
- #include <linux/jiffies.h>
- #include <linux/kernel.h>
-@@ -21,6 +22,7 @@
- #include <linux/module.h>
- #include <linux/netdevice.h>
- #include <linux/mutex.h>
-+#include <linux/rtnetlink.h>
- #include <linux/timer.h>
- #include "../leds.h"
-
-@@ -52,6 +54,8 @@ struct led_netdev_data {
- unsigned int last_activity;
-
- unsigned long mode;
-+ int link_speed;
-+
- bool carrier_link_up;
- bool hw_control;
- };
-@@ -77,7 +81,24 @@ static void set_baseline_state(struct le
- if (!trigger_data->carrier_link_up) {
- led_set_brightness(led_cdev, LED_OFF);
- } else {
-+ bool blink_on = false;
-+
- if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode))
-+ blink_on = true;
-+
-+ if (test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) &&
-+ trigger_data->link_speed == SPEED_10)
-+ blink_on = true;
-+
-+ if (test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) &&
-+ trigger_data->link_speed == SPEED_100)
-+ blink_on = true;
-+
-+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) &&
-+ trigger_data->link_speed == SPEED_1000)
-+ blink_on = true;
-+
-+ if (blink_on)
- led_set_brightness(led_cdev,
- led_cdev->blink_brightness);
- else
-@@ -161,6 +182,18 @@ static bool can_hw_control(struct led_ne
- return true;
- }
-
-+static void get_device_state(struct led_netdev_data *trigger_data)
-+{
-+ struct ethtool_link_ksettings cmd;
-+
-+ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev);
-+ if (!trigger_data->carrier_link_up)
-+ return;
-+
-+ if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd))
-+ trigger_data->link_speed = cmd.base.speed;
-+}
-+
- static ssize_t device_name_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -196,8 +229,12 @@ static int set_device_name(struct led_ne
- dev_get_by_name(&init_net, trigger_data->device_name);
-
- trigger_data->carrier_link_up = false;
-- if (trigger_data->net_dev != NULL)
-- trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev);
-+ trigger_data->link_speed = SPEED_UNKNOWN;
-+ if (trigger_data->net_dev != NULL) {
-+ rtnl_lock();
-+ get_device_state(trigger_data);
-+ rtnl_unlock();
-+ }
-
- trigger_data->last_activity = 0;
-
-@@ -234,6 +271,9 @@ static ssize_t netdev_led_attr_show(stru
-
- switch (attr) {
- case TRIGGER_NETDEV_LINK:
-+ case TRIGGER_NETDEV_LINK_10:
-+ case TRIGGER_NETDEV_LINK_100:
-+ case TRIGGER_NETDEV_LINK_1000:
- case TRIGGER_NETDEV_TX:
- case TRIGGER_NETDEV_RX:
- bit = attr;
-@@ -249,7 +289,7 @@ static ssize_t netdev_led_attr_store(str
- size_t size, enum led_trigger_netdev_modes attr)
- {
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
-- unsigned long state;
-+ unsigned long state, mode = trigger_data->mode;
- int ret;
- int bit;
-
-@@ -259,6 +299,9 @@ static ssize_t netdev_led_attr_store(str
-
- switch (attr) {
- case TRIGGER_NETDEV_LINK:
-+ case TRIGGER_NETDEV_LINK_10:
-+ case TRIGGER_NETDEV_LINK_100:
-+ case TRIGGER_NETDEV_LINK_1000:
- case TRIGGER_NETDEV_TX:
- case TRIGGER_NETDEV_RX:
- bit = attr;
-@@ -267,13 +310,20 @@ static ssize_t netdev_led_attr_store(str
- return -EINVAL;
- }
-
-- cancel_delayed_work_sync(&trigger_data->work);
--
- if (state)
-- set_bit(bit, &trigger_data->mode);
-+ set_bit(bit, &mode);
- else
-- clear_bit(bit, &trigger_data->mode);
-+ clear_bit(bit, &mode);
-+
-+ if (test_bit(TRIGGER_NETDEV_LINK, &mode) &&
-+ (test_bit(TRIGGER_NETDEV_LINK_10, &mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_100, &mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_1000, &mode)))
-+ return -EINVAL;
-+
-+ cancel_delayed_work_sync(&trigger_data->work);
-
-+ trigger_data->mode = mode;
- trigger_data->hw_control = can_hw_control(trigger_data);
-
- set_baseline_state(trigger_data);
-@@ -295,6 +345,9 @@ static ssize_t netdev_led_attr_store(str
- static DEVICE_ATTR_RW(trigger_name)
-
- DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK);
-+DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10);
-+DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100);
-+DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
- DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
- DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX);
-
-@@ -338,6 +391,9 @@ static DEVICE_ATTR_RW(interval);
- static struct attribute *netdev_trig_attrs[] = {
- &dev_attr_device_name.attr,
- &dev_attr_link.attr,
-+ &dev_attr_link_10.attr,
-+ &dev_attr_link_100.attr,
-+ &dev_attr_link_1000.attr,
- &dev_attr_rx.attr,
- &dev_attr_tx.attr,
- &dev_attr_interval.attr,
-@@ -368,9 +424,10 @@ static int netdev_trig_notify(struct not
- mutex_lock(&trigger_data->lock);
-
- trigger_data->carrier_link_up = false;
-+ trigger_data->link_speed = SPEED_UNKNOWN;
- switch (evt) {
- case NETDEV_CHANGENAME:
-- trigger_data->carrier_link_up = netif_carrier_ok(dev);
-+ get_device_state(trigger_data);
- fallthrough;
- case NETDEV_REGISTER:
- if (trigger_data->net_dev)
-@@ -384,7 +441,7 @@ static int netdev_trig_notify(struct not
- break;
- case NETDEV_UP:
- case NETDEV_CHANGE:
-- trigger_data->carrier_link_up = netif_carrier_ok(dev);
-+ get_device_state(trigger_data);
- break;
- }
-
-@@ -427,7 +484,10 @@ static void netdev_trig_work(struct work
- if (trigger_data->last_activity != new_activity) {
- led_stop_software_blink(trigger_data->led_cdev);
-
-- invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode);
-+ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode);
- interval = jiffies_to_msecs(
- atomic_read(&trigger_data->interval));
- /* base state is ON (link present) */
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -530,6 +530,9 @@ static inline void *led_get_trigger_data
- /* Trigger specific enum */
- enum led_trigger_netdev_modes {
- TRIGGER_NETDEV_LINK = 0,
-+ TRIGGER_NETDEV_LINK_10,
-+ TRIGGER_NETDEV_LINK_100,
-+ TRIGGER_NETDEV_LINK_1000,
- TRIGGER_NETDEV_TX,
- TRIGGER_NETDEV_RX,
-
diff --git a/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch b/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch
deleted file mode 100644
index a5ab461828..0000000000
--- a/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From f22f95b9ff1551c9bab13104131929f33d51f23f Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 19 Jun 2023 22:46:59 +0200
-Subject: [PATCH 2/3] leds: trigger: netdev: add additional specific link
- duplex mode
-
-Add additional modes for specific link duplex. Use ethtool APIs to get the
-current link duplex and enable the LED accordingly. Under netdev event
-handler the rtnl lock is already held and is not needed to be set to
-access ethtool APIs.
-
-This is especially useful for PHY and Switch that supports LEDs hw
-control for specific link duplex.
-
-Add additional modes:
-- half_duplex: Turn on LED when link is half duplex
-- full_duplex: Turn on LED when link is full duplex
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Lee Jones <lee@kernel.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 27 +++++++++++++++++++++++++--
- include/linux/leds.h | 2 ++
- 2 files changed, 27 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -55,6 +55,7 @@ struct led_netdev_data {
-
- unsigned long mode;
- int link_speed;
-+ u8 duplex;
-
- bool carrier_link_up;
- bool hw_control;
-@@ -98,6 +99,14 @@ static void set_baseline_state(struct le
- trigger_data->link_speed == SPEED_1000)
- blink_on = true;
-
-+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) &&
-+ trigger_data->duplex == DUPLEX_HALF)
-+ blink_on = true;
-+
-+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode) &&
-+ trigger_data->duplex == DUPLEX_FULL)
-+ blink_on = true;
-+
- if (blink_on)
- led_set_brightness(led_cdev,
- led_cdev->blink_brightness);
-@@ -190,8 +199,10 @@ static void get_device_state(struct led_
- if (!trigger_data->carrier_link_up)
- return;
-
-- if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd))
-+ if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd)) {
- trigger_data->link_speed = cmd.base.speed;
-+ trigger_data->duplex = cmd.base.duplex;
-+ }
- }
-
- static ssize_t device_name_show(struct device *dev,
-@@ -230,6 +241,7 @@ static int set_device_name(struct led_ne
-
- trigger_data->carrier_link_up = false;
- trigger_data->link_speed = SPEED_UNKNOWN;
-+ trigger_data->duplex = DUPLEX_UNKNOWN;
- if (trigger_data->net_dev != NULL) {
- rtnl_lock();
- get_device_state(trigger_data);
-@@ -274,6 +286,8 @@ static ssize_t netdev_led_attr_show(stru
- case TRIGGER_NETDEV_LINK_10:
- case TRIGGER_NETDEV_LINK_100:
- case TRIGGER_NETDEV_LINK_1000:
-+ case TRIGGER_NETDEV_HALF_DUPLEX:
-+ case TRIGGER_NETDEV_FULL_DUPLEX:
- case TRIGGER_NETDEV_TX:
- case TRIGGER_NETDEV_RX:
- bit = attr;
-@@ -302,6 +316,8 @@ static ssize_t netdev_led_attr_store(str
- case TRIGGER_NETDEV_LINK_10:
- case TRIGGER_NETDEV_LINK_100:
- case TRIGGER_NETDEV_LINK_1000:
-+ case TRIGGER_NETDEV_HALF_DUPLEX:
-+ case TRIGGER_NETDEV_FULL_DUPLEX:
- case TRIGGER_NETDEV_TX:
- case TRIGGER_NETDEV_RX:
- bit = attr;
-@@ -348,6 +364,8 @@ DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETD
- DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10);
- DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100);
- DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
-+DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX);
-+DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX);
- DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
- DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX);
-
-@@ -394,6 +412,8 @@ static struct attribute *netdev_trig_att
- &dev_attr_link_10.attr,
- &dev_attr_link_100.attr,
- &dev_attr_link_1000.attr,
-+ &dev_attr_full_duplex.attr,
-+ &dev_attr_half_duplex.attr,
- &dev_attr_rx.attr,
- &dev_attr_tx.attr,
- &dev_attr_interval.attr,
-@@ -425,6 +445,7 @@ static int netdev_trig_notify(struct not
-
- trigger_data->carrier_link_up = false;
- trigger_data->link_speed = SPEED_UNKNOWN;
-+ trigger_data->duplex = DUPLEX_UNKNOWN;
- switch (evt) {
- case NETDEV_CHANGENAME:
- get_device_state(trigger_data);
-@@ -487,7 +508,9 @@ static void netdev_trig_work(struct work
- invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode) ||
- test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) ||
- test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) ||
-- test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode);
-+ test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode);
- interval = jiffies_to_msecs(
- atomic_read(&trigger_data->interval));
- /* base state is ON (link present) */
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -533,6 +533,8 @@ enum led_trigger_netdev_modes {
- TRIGGER_NETDEV_LINK_10,
- TRIGGER_NETDEV_LINK_100,
- TRIGGER_NETDEV_LINK_1000,
-+ TRIGGER_NETDEV_HALF_DUPLEX,
-+ TRIGGER_NETDEV_FULL_DUPLEX,
- TRIGGER_NETDEV_TX,
- TRIGGER_NETDEV_RX,
-
diff --git a/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch b/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch
deleted file mode 100644
index 67528cafe0..0000000000
--- a/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From b655892ffd6d89b0c7407e099c40dbde82ee3f03 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 19 Jun 2023 22:47:00 +0200
-Subject: [PATCH 3/3] leds: trigger: netdev: expose hw_control status via sysfs
-
-Expose hw_control status via sysfs for the netdev trigger to give
-userspace better understanding of the current state of the trigger and
-the LED.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
-Acked-by: Lee Jones <lee@kernel.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -406,6 +406,16 @@ static ssize_t interval_store(struct dev
-
- static DEVICE_ATTR_RW(interval);
-
-+static ssize_t hw_control_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
-+
-+ return sprintf(buf, "%d\n", trigger_data->hw_control);
-+}
-+
-+static DEVICE_ATTR_RO(hw_control);
-+
- static struct attribute *netdev_trig_attrs[] = {
- &dev_attr_device_name.attr,
- &dev_attr_link.attr,
-@@ -417,6 +427,7 @@ static struct attribute *netdev_trig_att
- &dev_attr_rx.attr,
- &dev_attr_tx.attr,
- &dev_attr_interval.attr,
-+ &dev_attr_hw_control.attr,
- NULL
- };
- ATTRIBUTE_GROUPS(netdev_trig);
diff --git a/target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch b/target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch
deleted file mode 100644
index ac322e1939..0000000000
--- a/target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 2555f35a4f428a9bfdf09aa0459dbfdf59a24a9a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 21 Jun 2023 11:54:09 +0200
-Subject: [PATCH] net: dsa: qca8k: add support for additional modes for netdev
- trigger
-
-The QCA8K switch supports additional modes that can be handled in
-hardware for the LED netdev trigger.
-
-Add these additional modes to further support the Switch LEDs and
-offload more blink modes.
-
-Add additional modes:
-- link_10
-- link_100
-- link_1000
-- half_duplex
-- full_duplex
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://lore.kernel.org/r/20230621095409.25859-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca/qca8k-leds.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-leds.c
-+++ b/drivers/net/dsa/qca/qca8k-leds.c
-@@ -68,6 +68,16 @@ qca8k_parse_netdev(unsigned long rules,
- *offload_trigger |= QCA8K_LED_TX_BLINK_MASK;
- if (test_bit(TRIGGER_NETDEV_RX, &rules))
- *offload_trigger |= QCA8K_LED_RX_BLINK_MASK;
-+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+ *offload_trigger |= QCA8K_LED_LINK_10M_EN_MASK;
-+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+ *offload_trigger |= QCA8K_LED_LINK_100M_EN_MASK;
-+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+ *offload_trigger |= QCA8K_LED_LINK_1000M_EN_MASK;
-+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
-+ *offload_trigger |= QCA8K_LED_HALF_DUPLEX_MASK;
-+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
-+ *offload_trigger |= QCA8K_LED_FULL_DUPLEX_MASK;
-
- if (rules && !*offload_trigger)
- return -EOPNOTSUPP;
-@@ -322,6 +332,16 @@ qca8k_cled_hw_control_get(struct led_cla
- set_bit(TRIGGER_NETDEV_TX, rules);
- if (val & QCA8K_LED_RX_BLINK_MASK)
- set_bit(TRIGGER_NETDEV_RX, rules);
-+ if (val & QCA8K_LED_LINK_10M_EN_MASK)
-+ set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+ if (val & QCA8K_LED_LINK_100M_EN_MASK)
-+ set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+ if (val & QCA8K_LED_LINK_1000M_EN_MASK)
-+ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+ if (val & QCA8K_LED_HALF_DUPLEX_MASK)
-+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
-+ if (val & QCA8K_LED_FULL_DUPLEX_MASK)
-+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
-
- return 0;
- }
diff --git a/target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch b/target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch
deleted file mode 100644
index 8c062dc3b4..0000000000
--- a/target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 4f86eb098e18fd0f032877dfa1a7e8c1503ca409 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:41 +0200
-Subject: [PATCH 1/6] net: dsa: mv88e6xxx: pass directly chip structure to
- mv88e6xxx_phy_is_internal
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Since this function is a simple helper, we do not need to pass a full
-dsa_switch structure, we can directly pass the mv88e6xxx_chip structure.
-Doing so will allow to share this function with any other function
-not manipulating dsa_switch structure but needing info about number of
-internal phys
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -470,10 +470,8 @@ restore_link:
- return err;
- }
-
--static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
-+static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port)
- {
-- struct mv88e6xxx_chip *chip = ds->priv;
--
- return port < chip->info->num_internal_phys;
- }
-
-@@ -591,7 +589,7 @@ static void mv88e6095_phylink_get_caps(s
-
- config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
-
-- if (mv88e6xxx_phy_is_internal(chip->ds, port)) {
-+ if (mv88e6xxx_phy_is_internal(chip, port)) {
- __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
- } else {
- if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
-@@ -851,7 +849,7 @@ static void mv88e6xxx_get_caps(struct ds
- chip->info->ops->phylink_get_caps(chip, port, config);
- mv88e6xxx_reg_unlock(chip);
-
-- if (mv88e6xxx_phy_is_internal(ds, port)) {
-+ if (mv88e6xxx_phy_is_internal(chip, port)) {
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
- /* Internal ports with no phy-mode need GMII for PHYLIB */
-@@ -872,7 +870,7 @@ static void mv88e6xxx_mac_config(struct
-
- mv88e6xxx_reg_lock(chip);
-
-- if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
-+ if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, port)) {
- /* In inband mode, the link may come up at any time while the
- * link is not forced down. Force the link down while we
- * reconfigure the interface mode.
diff --git a/target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch b/target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch
deleted file mode 100644
index 75a21a931d..0000000000
--- a/target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 73cbfad9296eed004992806e056db5b48583ca41 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:42 +0200
-Subject: [PATCH 2/6] net: dsa: mv88e6xxx: use mv88e6xxx_phy_is_internal in
- mv88e6xxx_port_ppu_updates
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Make sure to use existing helper to get internal PHYs count instead of
-redoing it manually
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -484,7 +484,7 @@ static int mv88e6xxx_port_ppu_updates(st
- * report whether the port is internal.
- */
- if (chip->info->family == MV88E6XXX_FAMILY_6250)
-- return port < chip->info->num_internal_phys;
-+ return mv88e6xxx_phy_is_internal(chip, port);
-
- err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
- if (err) {
diff --git a/target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch b/target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch
deleted file mode 100644
index e24dca819b..0000000000
--- a/target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 1414d30660d201f515a9d877571ceea9ca190b6a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:43 +0200
-Subject: [PATCH 3/6] net: dsa: mv88e6xxx: add field to specify internal phys
- layout
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-mv88e6xxx currently assumes that switch equipped with internal phys have
-those phys mapped contiguously starting from port 0 (see
-mv88e6xxx_phy_is_internal). However, some switches have internal PHYs but
-NOT starting from port 0. For example 88e6393X, 88E6193X and 88E6191X have
-integrated PHYs available on ports 1 to 8
-To properly support this offset, add a new field to allow specifying an
-internal PHYs layout. If field is not set, default layout is assumed (start
-at port 0)
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 4 +++-
- drivers/net/dsa/mv88e6xxx/chip.h | 5 +++++
- drivers/net/dsa/mv88e6xxx/global2.c | 5 ++++-
- 3 files changed, 12 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -472,7 +472,9 @@ restore_link:
-
- static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port)
- {
-- return port < chip->info->num_internal_phys;
-+ return port >= chip->info->internal_phys_offset &&
-+ port < chip->info->num_internal_phys +
-+ chip->info->internal_phys_offset;
- }
-
- static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
---- a/drivers/net/dsa/mv88e6xxx/chip.h
-+++ b/drivers/net/dsa/mv88e6xxx/chip.h
-@@ -167,6 +167,11 @@ struct mv88e6xxx_info {
-
- /* Supports PTP */
- bool ptp_support;
-+
-+ /* Internal PHY start index. 0 means that internal PHYs range starts at
-+ * port 0, 1 means internal PHYs range starts at port 1, etc
-+ */
-+ unsigned int internal_phys_offset;
- };
-
- struct mv88e6xxx_atu_entry {
---- a/drivers/net/dsa/mv88e6xxx/global2.c
-+++ b/drivers/net/dsa/mv88e6xxx/global2.c
-@@ -1185,8 +1185,11 @@ int mv88e6xxx_g2_irq_mdio_setup(struct m
- struct mii_bus *bus)
- {
- int phy, irq, err, err_phy;
-+ int phy_start = chip->info->internal_phys_offset;
-+ int phy_end = chip->info->internal_phys_offset +
-+ chip->info->num_internal_phys;
-
-- for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
-+ for (phy = phy_start; phy < phy_end; phy++) {
- irq = irq_find_mapping(chip->g2_irq.domain, phy);
- if (irq < 0) {
- err = irq;
diff --git a/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch b/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch
deleted file mode 100644
index cadc70fd73..0000000000
--- a/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From eb8c75f82a6711387f3b9e03e28923f3e75a761b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:44 +0200
-Subject: [PATCH 4/6] net: dsa: mv88e6xxx: fix 88E6393X family internal phys
- layout
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-88E6393X/88E6193X/88E6191X switches have in fact 8 internal PHYs, but those
-are not present starting at port 0: supported ports go from 1 to 8
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -5998,7 +5998,8 @@ static const struct mv88e6xxx_info mv88e
- .name = "Marvell 88E6191X",
- .num_databases = 4096,
- .num_ports = 11, /* 10 + Z80 */
-- .num_internal_phys = 9,
-+ .num_internal_phys = 8,
-+ .internal_phys_offset = 1,
- .max_vid = 8191,
- .max_sid = 63,
- .port_base_addr = 0x0,
-@@ -6021,7 +6022,8 @@ static const struct mv88e6xxx_info mv88e
- .name = "Marvell 88E6193X",
- .num_databases = 4096,
- .num_ports = 11, /* 10 + Z80 */
-- .num_internal_phys = 9,
-+ .num_internal_phys = 8,
-+ .internal_phys_offset = 1,
- .max_vid = 8191,
- .max_sid = 63,
- .port_base_addr = 0x0,
-@@ -6340,7 +6342,8 @@ static const struct mv88e6xxx_info mv88e
- .name = "Marvell 88E6393X",
- .num_databases = 4096,
- .num_ports = 11, /* 10 + Z80 */
-- .num_internal_phys = 9,
-+ .num_internal_phys = 8,
-+ .internal_phys_offset = 1,
- .max_vid = 8191,
- .max_sid = 63,
- .port_base_addr = 0x0,
diff --git a/target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch b/target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch
deleted file mode 100644
index e2d3b57ccc..0000000000
--- a/target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From cef945452c8468efce75ba0dc8420510a5b84af9 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:45 +0200
-Subject: [PATCH 5/6] net: dsa: mv88e6xxx: pass mv88e6xxx_chip structure to
- port_max_speed_mode
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some switches families have minor differences on supported link speed for
-ports. Instead of redefining a new port_max_speed_mode for each different
-configuration, allow to pass mv88e6xxx_chip structure to allow
-differentiating those chips by known chip id
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
- drivers/net/dsa/mv88e6xxx/chip.h | 3 ++-
- drivers/net/dsa/mv88e6xxx/port.c | 12 ++++++++----
- drivers/net/dsa/mv88e6xxx/port.h | 12 ++++++++----
- 4 files changed, 19 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3350,7 +3350,7 @@ static int mv88e6xxx_setup_port(struct m
- caps = pl_config.mac_capabilities;
-
- if (chip->info->ops->port_max_speed_mode)
-- mode = chip->info->ops->port_max_speed_mode(port);
-+ mode = chip->info->ops->port_max_speed_mode(chip, port);
- else
- mode = PHY_INTERFACE_MODE_NA;
-
---- a/drivers/net/dsa/mv88e6xxx/chip.h
-+++ b/drivers/net/dsa/mv88e6xxx/chip.h
-@@ -514,7 +514,8 @@ struct mv88e6xxx_ops {
- int speed, int duplex);
-
- /* What interface mode should be used for maximum speed? */
-- phy_interface_t (*port_max_speed_mode)(int port);
-+ phy_interface_t (*port_max_speed_mode)(struct mv88e6xxx_chip *chip,
-+ int port);
-
- int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
-
---- a/drivers/net/dsa/mv88e6xxx/port.c
-+++ b/drivers/net/dsa/mv88e6xxx/port.c
-@@ -342,7 +342,8 @@ int mv88e6341_port_set_speed_duplex(stru
- duplex);
- }
-
--phy_interface_t mv88e6341_port_max_speed_mode(int port)
-+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 5)
- return PHY_INTERFACE_MODE_2500BASEX;
-@@ -381,7 +382,8 @@ int mv88e6390_port_set_speed_duplex(stru
- duplex);
- }
-
--phy_interface_t mv88e6390_port_max_speed_mode(int port)
-+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 9 || port == 10)
- return PHY_INTERFACE_MODE_2500BASEX;
-@@ -403,7 +405,8 @@ int mv88e6390x_port_set_speed_duplex(str
- duplex);
- }
-
--phy_interface_t mv88e6390x_port_max_speed_mode(int port)
-+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 9 || port == 10)
- return PHY_INTERFACE_MODE_XAUI;
-@@ -500,7 +503,8 @@ int mv88e6393x_port_set_speed_duplex(str
- return 0;
- }
-
--phy_interface_t mv88e6393x_port_max_speed_mode(int port)
-+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port)
- {
- if (port == 0 || port == 9 || port == 10)
- return PHY_INTERFACE_MODE_10GBASER;
---- a/drivers/net/dsa/mv88e6xxx/port.h
-+++ b/drivers/net/dsa/mv88e6xxx/port.h
-@@ -359,10 +359,14 @@ int mv88e6390x_port_set_speed_duplex(str
- int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
- int speed, int duplex);
-
--phy_interface_t mv88e6341_port_max_speed_mode(int port);
--phy_interface_t mv88e6390_port_max_speed_mode(int port);
--phy_interface_t mv88e6390x_port_max_speed_mode(int port);
--phy_interface_t mv88e6393x_port_max_speed_mode(int port);
-+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
-+ int port);
-
- int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state);
-
diff --git a/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch b/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch
deleted file mode 100644
index 471e6a3903..0000000000
--- a/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 23680321789863bab2d60af507858ce50ff9f56a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
-Date: Mon, 29 May 2023 10:02:46 +0200
-Subject: [PATCH 6/6] net: dsa: mv88e6xxx: enable support for 88E6361 switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Marvell 88E6361 is an 8-port switch derived from the
-88E6393X/88E9193X/88E6191X switches family. It can benefit from the
-existing mv88e6xxx driver by simply adding the proper switch description in
-the driver. Main differences with other switches from this
-family are:
-- 8 ports exposed (instead of 11): ports 1, 2 and 8 not available
-- No 5GBase-x nor SFI/USXGMII support
-
-Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 42 ++++++++++++++++++++++++++++----
- drivers/net/dsa/mv88e6xxx/chip.h | 3 ++-
- drivers/net/dsa/mv88e6xxx/port.c | 14 ++++++++---
- drivers/net/dsa/mv88e6xxx/port.h | 1 +
- 4 files changed, 51 insertions(+), 9 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -809,6 +809,8 @@ static void mv88e6393x_phylink_get_caps(
- unsigned long *supported = config->supported_interfaces;
- bool is_6191x =
- chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
-+ bool is_6361 =
-+ chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361;
-
- mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
-
-@@ -823,13 +825,17 @@ static void mv88e6393x_phylink_get_caps(
- /* 6191X supports >1G modes only on port 10 */
- if (!is_6191x || port == 10) {
- __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
-- __set_bit(PHY_INTERFACE_MODE_5GBASER, supported);
-- __set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
-+ config->mac_capabilities |= MAC_2500FD;
-+
-+ /* 6361 only supports up to 2500BaseX */
-+ if (!is_6361) {
-+ __set_bit(PHY_INTERFACE_MODE_5GBASER, supported);
-+ __set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
-+ config->mac_capabilities |= MAC_5000FD |
-+ MAC_10000FD;
-+ }
- /* FIXME: USXGMII is not supported yet */
- /* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */
--
-- config->mac_capabilities |= MAC_2500FD | MAC_5000FD |
-- MAC_10000FD;
- }
- }
-
-@@ -6285,6 +6291,32 @@ static const struct mv88e6xxx_info mv88e
- .ptp_support = true,
- .ops = &mv88e6352_ops,
- },
-+ [MV88E6361] = {
-+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
-+ .family = MV88E6XXX_FAMILY_6393,
-+ .name = "Marvell 88E6361",
-+ .num_databases = 4096,
-+ .num_macs = 16384,
-+ .num_ports = 11,
-+ /* Ports 1, 2 and 8 are not routed */
-+ .invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
-+ .num_internal_phys = 5,
-+ .internal_phys_offset = 3,
-+ .max_vid = 4095,
-+ .max_sid = 63,
-+ .port_base_addr = 0x0,
-+ .phy_base_addr = 0x0,
-+ .global1_addr = 0x1b,
-+ .global2_addr = 0x1c,
-+ .age_time_coeff = 3750,
-+ .g1_irqs = 10,
-+ .g2_irqs = 14,
-+ .atu_move_port_mask = 0x1f,
-+ .pvt = true,
-+ .multi_chip = true,
-+ .ptp_support = true,
-+ .ops = &mv88e6393x_ops,
-+ },
- [MV88E6390] = {
- .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
- .family = MV88E6XXX_FAMILY_6390,
---- a/drivers/net/dsa/mv88e6xxx/chip.h
-+++ b/drivers/net/dsa/mv88e6xxx/chip.h
-@@ -82,6 +82,7 @@ enum mv88e6xxx_model {
- MV88E6350,
- MV88E6351,
- MV88E6352,
-+ MV88E6361,
- MV88E6390,
- MV88E6390X,
- MV88E6393X,
-@@ -100,7 +101,7 @@ enum mv88e6xxx_family {
- MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
- MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */
- MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */
-- MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6393X */
-+ MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6361 6393X */
- };
-
- /**
---- a/drivers/net/dsa/mv88e6xxx/port.c
-+++ b/drivers/net/dsa/mv88e6xxx/port.c
-@@ -424,6 +424,10 @@ int mv88e6393x_port_set_speed_duplex(str
- u16 reg, ctrl;
- int err;
-
-+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361 &&
-+ speed > 2500)
-+ return -EOPNOTSUPP;
-+
- if (speed == 200 && port != 0)
- return -EOPNOTSUPP;
-
-@@ -506,10 +510,14 @@ int mv88e6393x_port_set_speed_duplex(str
- phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
- int port)
- {
-- if (port == 0 || port == 9 || port == 10)
-- return PHY_INTERFACE_MODE_10GBASER;
-
-- return PHY_INTERFACE_MODE_NA;
-+ if (port != 0 && port != 9 && port != 10)
-+ return PHY_INTERFACE_MODE_NA;
-+
-+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361)
-+ return PHY_INTERFACE_MODE_2500BASEX;
-+
-+ return PHY_INTERFACE_MODE_10GBASER;
- }
-
- static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
---- a/drivers/net/dsa/mv88e6xxx/port.h
-+++ b/drivers/net/dsa/mv88e6xxx/port.h
-@@ -133,6 +133,7 @@
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6220 0x2200
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500
-+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6361 0x2610
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100
- #define MV88E6XXX_PORT_SWITCH_ID_PROD_6141 0x3400
diff --git a/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch b/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch
deleted file mode 100644
index 33759632eb..0000000000
--- a/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 18 Nov 2022 06:39:20 +0000
-Subject: [PATCH] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config
-
-Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare
-the next SoC in STM32MP family.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++-----
- 1 file changed, 16 insertions(+), 5 deletions(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -22,16 +22,15 @@
- /* shadow registers offest */
- #define STM32MP15_BSEC_DATA0 0x200
-
--/* 32 (x 32-bits) lower shadow registers */
--#define STM32MP15_BSEC_NUM_LOWER 32
--
- struct stm32_romem_cfg {
- int size;
-+ u8 lower;
- };
-
- struct stm32_romem_priv {
- void __iomem *base;
- struct nvmem_config cfg;
-+ u8 lower;
- };
-
- static int stm32_romem_read(void *context, unsigned int offset, void *buf,
-@@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context
- for (i = roffset; (i < roffset + rbytes); i += 4) {
- u32 otp = i >> 2;
-
-- if (otp < STM32MP15_BSEC_NUM_LOWER) {
-+ if (otp < priv->lower) {
- /* read lower data from shadow registers */
- val = readl_relaxed(
- priv->base + STM32MP15_BSEC_DATA0 + i);
-@@ -159,6 +158,8 @@ static int stm32_romem_probe(struct plat
- priv->cfg.priv = priv;
- priv->cfg.owner = THIS_MODULE;
-
-+ priv->lower = 0;
-+
- cfg = (const struct stm32_romem_cfg *)
- of_match_device(dev->driver->of_match_table, dev)->data;
- if (!cfg) {
-@@ -167,6 +168,7 @@ static int stm32_romem_probe(struct plat
- priv->cfg.reg_read = stm32_romem_read;
- } else {
- priv->cfg.size = cfg->size;
-+ priv->lower = cfg->lower;
- priv->cfg.reg_read = stm32_bsec_read;
- priv->cfg.reg_write = stm32_bsec_write;
- }
-@@ -174,8 +176,17 @@ static int stm32_romem_probe(struct plat
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
- }
-
-+/*
-+ * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
-+ * => 96 x 32-bits data words
-+ * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
-+ * => 32 (x 32-bits) lower shadow registers = words 0 to 31
-+ * - Upper: 2K bits, ECC protection, word programming only
-+ * => 64 (x 32-bits) = words 32 to 95
-+ */
- static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
-- .size = 384, /* 96 x 32-bits data words */
-+ .size = 384,
-+ .lower = 32,
- };
-
- static const struct of_device_id stm32_romem_of_match[] = {
diff --git a/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch b/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch
deleted file mode 100644
index 5791df2606..0000000000
--- a/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 18 Nov 2022 06:39:21 +0000
-Subject: [PATCH] nvmem: stm32: add warning when upper OTPs are updated
-
-As the upper OTPs are ECC protected, they support only one 32 bits word
-programming.
-For a second modification of this word, these ECC become invalid and
-this OTP will be no more accessible, the shadowed value is invalid.
-
-This patch adds a warning to indicate an upper OTP update, because this
-operation is dangerous as OTP is not locked by the driver after the first
-update to avoid a second update.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -132,6 +132,9 @@ static int stm32_bsec_write(void *contex
- }
- }
-
-+ if (offset + bytes >= priv->lower * 4)
-+ dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n");
-+
- return 0;
- }
-
diff --git a/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch b/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch
deleted file mode 100644
index b83ad69c6b..0000000000
--- a/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 18 Nov 2022 06:39:22 +0000
-Subject: [PATCH] nvmem: stm32: add nvmem type attribute
-
-Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP
-so userspace is able to know how the data is stored in BSEC.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -160,6 +160,7 @@ static int stm32_romem_probe(struct plat
- priv->cfg.dev = dev;
- priv->cfg.priv = priv;
- priv->cfg.owner = THIS_MODULE;
-+ priv->cfg.type = NVMEM_TYPE_OTP;
-
- priv->lower = 0;
-
diff --git a/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch b/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch
deleted file mode 100644
index 52ba1e65b5..0000000000
--- a/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001
-From: Jiangshan Yi <yijiangshan@kylinos.cn>
-Date: Fri, 18 Nov 2022 06:39:24 +0000
-Subject: [PATCH] nvmem: stm32: fix spelling typo in comment
-
-Fix spelling typo in comment.
-
-Reported-by: k2ci <kernel-bot@kylinos.cn>
-Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -19,7 +19,7 @@
- #define STM32_SMC_WRITE_SHADOW 0x03
- #define STM32_SMC_READ_OTP 0x04
-
--/* shadow registers offest */
-+/* shadow registers offset */
- #define STM32MP15_BSEC_DATA0 0x200
-
- struct stm32_romem_cfg {
diff --git a/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch b/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch
deleted file mode 100644
index 8f024f4c1a..0000000000
--- a/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001
-From: Colin Ian King <colin.i.king@gmail.com>
-Date: Fri, 18 Nov 2022 06:39:26 +0000
-Subject: [PATCH] nvmem: Kconfig: Fix spelling mistake "controlls" ->
- "controls"
-
-There is a spelling mistake in a Kconfig description. Fix it.
-
-Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC
- depends on ARCH_AT91 || COMPILE_TEST
- help
- This driver enable the OTP controller available on Microchip SAMA7G5
-- SoCs. It controlls the access to the OTP memory connected to it.
-+ SoCs. It controls the access to the OTP memory connected to it.
-
- config NVMEM_MTK_EFUSE
- tristate "Mediatek SoCs EFUSE support"
diff --git a/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch b/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch
deleted file mode 100644
index 861386ad31..0000000000
--- a/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 18 Nov 2022 06:39:27 +0000
-Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They
-decided to store U-Boot environment data inside U-Boot partition and to
-use a custom header (with "uEnv" magic and env data length).
-
-Add support for Broadcom's specific binding and their custom format.
-
-Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -16,6 +16,7 @@
- enum u_boot_env_format {
- U_BOOT_FORMAT_SINGLE,
- U_BOOT_FORMAT_REDUNDANT,
-+ U_BOOT_FORMAT_BROADCOM,
- };
-
- struct u_boot_env {
-@@ -40,6 +41,13 @@ struct u_boot_env_image_redundant {
- uint8_t data[];
- } __packed;
-
-+struct u_boot_env_image_broadcom {
-+ __le32 magic;
-+ __le32 len;
-+ __le32 crc32;
-+ uint8_t data[0];
-+} __packed;
-+
- static int u_boot_env_read(void *context, unsigned int offset, void *val,
- size_t bytes)
- {
-@@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boo
- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
- data_offset = offsetof(struct u_boot_env_image_redundant, data);
- break;
-+ case U_BOOT_FORMAT_BROADCOM:
-+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
-+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
-+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
-+ break;
- }
- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
- crc32_data_len = priv->mtd->size - crc32_data_offset;
-@@ -202,6 +215,7 @@ static const struct of_device_id u_boot_
- { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
- { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
- { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
-+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
- {},
- };
-
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch
deleted file mode 100644
index 01400fd490..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 6 Feb 2023 13:43:41 +0000
-Subject: [PATCH] nvmem: core: remove spurious white space
-
-Remove a spurious white space in for the ida_alloc() call.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons
- if (!nvmem)
- return ERR_PTR(-ENOMEM);
-
-- rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
-+ rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
- if (rval < 0) {
- kfree(nvmem);
- return ERR_PTR(rval);
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch
deleted file mode 100644
index 454d3bf0ed..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:46 +0000
-Subject: [PATCH] nvmem: core: add an index parameter to the cell
-
-Sometimes a cell can represend multiple values. For example, a base
-ethernet address stored in the NVMEM can be expanded into multiple
-discreet ones by adding an offset.
-
-For this use case, introduce an index parameter which is then used to
-distiguish between values. This parameter will then be passed to the
-post process hook which can then use it to create different values
-during reading.
-
-At the moment, there is only support for the device tree path. You can
-add the index to the phandle, e.g.
-
- &net {
- nvmem-cells = <&base_mac_address 2>;
- nvmem-cell-names = "mac-address";
- };
-
- &nvmem_provider {
- base_mac_address: base-mac-address@0 {
- #nvmem-cell-cells = <1>;
- reg = <0 6>;
- };
- };
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 37 ++++++++++++++++++++++++----------
- drivers/nvmem/imx-ocotp.c | 4 ++--
- include/linux/nvmem-provider.h | 4 ++--
- 3 files changed, 30 insertions(+), 15 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -60,6 +60,7 @@ struct nvmem_cell_entry {
- struct nvmem_cell {
- struct nvmem_cell_entry *entry;
- const char *id;
-+ int index;
- };
-
- static DEFINE_MUTEX(nvmem_mutex);
-@@ -1122,7 +1123,8 @@ struct nvmem_device *devm_nvmem_device_g
- }
- EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
-
--static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id)
-+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
-+ const char *id, int index)
- {
- struct nvmem_cell *cell;
- const char *name = NULL;
-@@ -1141,6 +1143,7 @@ static struct nvmem_cell *nvmem_create_c
-
- cell->id = name;
- cell->entry = entry;
-+ cell->index = index;
-
- return cell;
- }
-@@ -1179,7 +1182,7 @@ nvmem_cell_get_from_lookup(struct device
- __nvmem_device_put(nvmem);
- cell = ERR_PTR(-ENOENT);
- } else {
-- cell = nvmem_create_cell(cell_entry, con_id);
-+ cell = nvmem_create_cell(cell_entry, con_id, 0);
- if (IS_ERR(cell))
- __nvmem_device_put(nvmem);
- }
-@@ -1227,15 +1230,27 @@ struct nvmem_cell *of_nvmem_cell_get(str
- struct nvmem_device *nvmem;
- struct nvmem_cell_entry *cell_entry;
- struct nvmem_cell *cell;
-+ struct of_phandle_args cell_spec;
- int index = 0;
-+ int cell_index = 0;
-+ int ret;
-
- /* if cell name exists, find index to the name */
- if (id)
- index = of_property_match_string(np, "nvmem-cell-names", id);
-
-- cell_np = of_parse_phandle(np, "nvmem-cells", index);
-- if (!cell_np)
-- return ERR_PTR(-ENOENT);
-+ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells",
-+ "#nvmem-cell-cells",
-+ index, &cell_spec);
-+ if (ret)
-+ return ERR_PTR(ret);
-+
-+ if (cell_spec.args_count > 1)
-+ return ERR_PTR(-EINVAL);
-+
-+ cell_np = cell_spec.np;
-+ if (cell_spec.args_count)
-+ cell_index = cell_spec.args[0];
-
- nvmem_np = of_get_parent(cell_np);
- if (!nvmem_np) {
-@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
- return ERR_PTR(-ENOENT);
- }
-
-- cell = nvmem_create_cell(cell_entry, id);
-+ cell = nvmem_create_cell(cell_entry, id, cell_index);
- if (IS_ERR(cell))
- __nvmem_device_put(nvmem);
-
-@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p
- }
-
- static int __nvmem_cell_read(struct nvmem_device *nvmem,
-- struct nvmem_cell_entry *cell,
-- void *buf, size_t *len, const char *id)
-+ struct nvmem_cell_entry *cell,
-+ void *buf, size_t *len, const char *id, int index)
- {
- int rc;
-
-@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme
- nvmem_shift_read_buffer_in_place(cell, buf);
-
- if (nvmem->cell_post_process) {
-- rc = nvmem->cell_post_process(nvmem->priv, id,
-+ rc = nvmem->cell_post_process(nvmem->priv, id, index,
- cell->offset, buf, cell->bytes);
- if (rc)
- return rc;
-@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
-- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id);
-+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index);
- if (rc) {
- kfree(buf);
- return ERR_PTR(rc);
-@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv
- if (rc)
- return rc;
-
-- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL);
-+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0);
- if (rc)
- return rc;
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -222,8 +222,8 @@ read_end:
- return ret;
- }
-
--static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset,
-- void *data, size_t bytes)
-+static int imx_ocotp_cell_pp(void *context, const char *id, int index,
-+ unsigned int offset, void *data, size_t bytes)
- {
- struct ocotp_priv *priv = context;
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr
- typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
- void *val, size_t bytes);
- /* used for vendor specific post processing of cell data */
--typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset,
-- void *buf, size_t bytes);
-+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
-+ unsigned int offset, void *buf, size_t bytes);
-
- enum nvmem_type {
- NVMEM_TYPE_UNKNOWN = 0,
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch b/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch
deleted file mode 100644
index f3829b3e17..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:47 +0000
-Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h
-
-struct nvmem_cell_info is used to describe a cell. Thus this should
-really be in the nvmem-provider's header. There are two (unused) nvmem
-access methods which use the nvmem_cell_info to describe the cell to be
-accesses. One can argue, that they will create a cell before accessing,
-thus they are both a provider and a consumer.
-
-struct nvmem_cell_info will get used more and more by nvmem-providers,
-don't force them to also include the consumer header, although they are
-not.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/nvmem-consumer.h | 10 +---------
- include/linux/nvmem-provider.h | 19 ++++++++++++++++++-
- 2 files changed, 19 insertions(+), 10 deletions(-)
-
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -18,15 +18,7 @@ struct device_node;
- /* consumer cookie */
- struct nvmem_cell;
- struct nvmem_device;
--
--struct nvmem_cell_info {
-- const char *name;
-- unsigned int offset;
-- unsigned int bytes;
-- unsigned int bit_offset;
-- unsigned int nbits;
-- struct device_node *np;
--};
-+struct nvmem_cell_info;
-
- /**
- * struct nvmem_cell_lookup - cell lookup entry
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -14,7 +14,6 @@
- #include <linux/gpio/consumer.h>
-
- struct nvmem_device;
--struct nvmem_cell_info;
- typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
- void *val, size_t bytes);
- typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
-@@ -48,6 +47,24 @@ struct nvmem_keepout {
- };
-
- /**
-+ * struct nvmem_cell_info - NVMEM cell description
-+ * @name: Name.
-+ * @offset: Offset within the NVMEM device.
-+ * @bytes: Length of the cell.
-+ * @bit_offset: Bit offset if cell is smaller than a byte.
-+ * @nbits: Number of bits.
-+ * @np: Optional device_node pointer.
-+ */
-+struct nvmem_cell_info {
-+ const char *name;
-+ unsigned int offset;
-+ unsigned int bytes;
-+ unsigned int bit_offset;
-+ unsigned int nbits;
-+ struct device_node *np;
-+};
-+
-+/**
- * struct nvmem_config - NVMEM device configuration
- *
- * @dev: Parent device.
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch
deleted file mode 100644
index 8f996eab34..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:48 +0000
-Subject: [PATCH] nvmem: core: drop the removal of the cells in
- nvmem_add_cells()
-
-If nvmem_add_cells() fails, the whole nvmem_register() will fail
-and the cells will then be removed anyway. This is a preparation
-to introduce a nvmem_add_one_cell() which can then be used by
-nvmem_add_cells().
-
-This is then the same to what nvmem_add_cells_from_table() and
-nvmem_add_cells_from_of() do.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 14 ++++----------
- 1 file changed, 4 insertions(+), 10 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_
- int ncells)
- {
- struct nvmem_cell_entry **cells;
-- int i, rval;
-+ int i, rval = 0;
-
- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
- if (!cells)
-@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_
- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
- if (!cells[i]) {
- rval = -ENOMEM;
-- goto err;
-+ goto out;
- }
-
- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
- if (rval) {
- kfree(cells[i]);
-- goto err;
-+ goto out;
- }
-
- nvmem_cell_entry_add(cells[i]);
- }
-
-+out:
- /* remove tmp array */
- kfree(cells);
-
-- return 0;
--err:
-- while (i--)
-- nvmem_cell_entry_drop(cells[i]);
--
-- kfree(cells);
--
- return rval;
- }
-
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch
deleted file mode 100644
index 711ce229b2..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:49 +0000
-Subject: [PATCH] nvmem: core: add nvmem_add_one_cell()
-
-Add a new function to add exactly one cell. This will be used by the
-nvmem layout drivers to add custom cells. In contrast to the
-nvmem_add_cells(), this has the advantage that we don't have to assemble
-a list of cells on runtime.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 59 ++++++++++++++++++++--------------
- include/linux/nvmem-provider.h | 8 +++++
- 2 files changed, 43 insertions(+), 24 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell
- }
-
- /**
-+ * nvmem_add_one_cell() - Add one cell information to an nvmem device
-+ *
-+ * @nvmem: nvmem device to add cells to.
-+ * @info: nvmem cell info to add to the device
-+ *
-+ * Return: 0 or negative error code on failure.
-+ */
-+int nvmem_add_one_cell(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info)
-+{
-+ struct nvmem_cell_entry *cell;
-+ int rval;
-+
-+ cell = kzalloc(sizeof(*cell), GFP_KERNEL);
-+ if (!cell)
-+ return -ENOMEM;
-+
-+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell);
-+ if (rval) {
-+ kfree(cell);
-+ return rval;
-+ }
-+
-+ nvmem_cell_entry_add(cell);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(nvmem_add_one_cell);
-+
-+/**
- * nvmem_add_cells() - Add cell information to an nvmem device
- *
- * @nvmem: nvmem device to add cells to.
-@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_
- const struct nvmem_cell_info *info,
- int ncells)
- {
-- struct nvmem_cell_entry **cells;
-- int i, rval = 0;
--
-- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
-- if (!cells)
-- return -ENOMEM;
-+ int i, rval;
-
- for (i = 0; i < ncells; i++) {
-- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
-- if (!cells[i]) {
-- rval = -ENOMEM;
-- goto out;
-- }
--
-- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
-- if (rval) {
-- kfree(cells[i]);
-- goto out;
-- }
--
-- nvmem_cell_entry_add(cells[i]);
-+ rval = nvmem_add_one_cell(nvmem, &info[i]);
-+ if (rval)
-+ return rval;
- }
-
--out:
-- /* remove tmp array */
-- kfree(cells);
--
-- return rval;
-+ return 0;
- }
-
- /**
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -153,6 +153,9 @@ struct nvmem_device *devm_nvmem_register
- void nvmem_add_cell_table(struct nvmem_cell_table *table);
- void nvmem_del_cell_table(struct nvmem_cell_table *table);
-
-+int nvmem_add_one_cell(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info);
-+
- #else
-
- static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
-@@ -170,6 +173,11 @@ devm_nvmem_register(struct device *dev,
-
- static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {}
- static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {}
-+static inline int nvmem_add_one_cell(struct nvmem_device *nvmem,
-+ const struct nvmem_cell_info *info)
-+{
-+ return -EOPNOTSUPP;
-+}
-
- #endif /* CONFIG_NVMEM */
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch
deleted file mode 100644
index e1791e5c83..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:50 +0000
-Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in
- nvmem_add_cells_from_of()
-
-Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell().
-This will remove duplicate code and it will make it possible to add a
-hook to a nvmem layout in between, which can change fields before the
-cell is finally added.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 45 ++++++++++++++------------------------------
- 1 file changed, 14 insertions(+), 31 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc
-
- static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
- {
-- struct device_node *parent, *child;
- struct device *dev = &nvmem->dev;
-- struct nvmem_cell_entry *cell;
-+ struct device_node *child;
- const __be32 *addr;
-- int len;
-+ int len, ret;
-
-- parent = dev->of_node;
-+ for_each_child_of_node(dev->of_node, child) {
-+ struct nvmem_cell_info info = {0};
-
-- for_each_child_of_node(parent, child) {
- addr = of_get_property(child, "reg", &len);
- if (!addr)
- continue;
-@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc
- return -EINVAL;
- }
-
-- cell = kzalloc(sizeof(*cell), GFP_KERNEL);
-- if (!cell) {
-- of_node_put(child);
-- return -ENOMEM;
-- }
--
-- cell->nvmem = nvmem;
-- cell->offset = be32_to_cpup(addr++);
-- cell->bytes = be32_to_cpup(addr);
-- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
-+ info.offset = be32_to_cpup(addr++);
-+ info.bytes = be32_to_cpup(addr);
-+ info.name = kasprintf(GFP_KERNEL, "%pOFn", child);
-
- addr = of_get_property(child, "bits", &len);
- if (addr && len == (2 * sizeof(u32))) {
-- cell->bit_offset = be32_to_cpup(addr++);
-- cell->nbits = be32_to_cpup(addr);
-+ info.bit_offset = be32_to_cpup(addr++);
-+ info.nbits = be32_to_cpup(addr);
- }
-
-- if (cell->nbits)
-- cell->bytes = DIV_ROUND_UP(
-- cell->nbits + cell->bit_offset,
-- BITS_PER_BYTE);
--
-- if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
-- dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
-- cell->name, nvmem->stride);
-- /* Cells already added will be freed later. */
-- kfree_const(cell->name);
-- kfree(cell);
-+ info.np = of_node_get(child);
-+
-+ ret = nvmem_add_one_cell(nvmem, &info);
-+ kfree(info.name);
-+ if (ret) {
- of_node_put(child);
-- return -EINVAL;
-+ return ret;
- }
--
-- cell->np = of_node_get(child);
-- nvmem_cell_entry_add(cell);
- }
-
- return 0;
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch b/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch
deleted file mode 100644
index 172a78b76a..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch
+++ /dev/null
@@ -1,562 +0,0 @@
-From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Mon, 6 Feb 2023 13:43:51 +0000
-Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x
-
-For boot with OP-TEE on STM32MP13, the communication with the secure
-world no more use STMicroelectronics SMC but communication with the
-STM32MP BSEC TA, for data access (read/write) or lock operation:
-- all the request are sent to OP-TEE trusted application,
-- for upper OTP with ECC protection and with word programming only
- each OTP are permanently locked when programmed to avoid ECC error
- on the second write operation
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 11 +
- drivers/nvmem/Makefile | 1 +
- drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
- drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++
- drivers/nvmem/stm32-romem.c | 54 ++++-
- 5 files changed, 441 insertions(+), 3 deletions(-)
- create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
- create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
- This driver can also be built as a module. If so, the module
- will be called nvmem-sprd-efuse.
-
-+config NVMEM_STM32_BSEC_OPTEE_TA
-+ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
-+ depends on OPTEE
-+ help
-+ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
-+ trusted application STM32MP BSEC.
-+
-+ This library is a used by stm32-romem driver or included in the module
-+ called nvmem-stm32-romem.
-+
- config NVMEM_STM32_ROMEM
- tristate "STMicroelectronics STM32 factory-programmed memory support"
- depends on ARCH_STM32 || COMPILE_TEST
-+ imply NVMEM_STM32_BSEC_OPTEE_TA
- help
- Say y here to enable read-only access for STMicroelectronics STM32
- factory-programmed memory area.
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem
- nvmem_sprd_efuse-y := sprd-efuse.o
- obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
- nvmem_stm32_romem-y := stm32-romem.o
-+nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
- obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
- nvmem_sunplus_ocotp-y := sunplus-ocotp.o
- obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
---- /dev/null
-+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
-@@ -0,0 +1,298 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
-+ *
-+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
-+ */
-+
-+#include <linux/tee_drv.h>
-+
-+#include "stm32-bsec-optee-ta.h"
-+
-+/*
-+ * Read OTP memory
-+ *
-+ * [in] value[0].a OTP start offset in byte
-+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
-+ * [out] memref[1].buffer Output buffer to store read values
-+ * [out] memref[1].size Size of OTP to be read
-+ *
-+ * Return codes:
-+ * TEE_SUCCESS - Invoke command success
-+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
-+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
-+ */
-+#define PTA_BSEC_READ_MEM 0x0
-+
-+/*
-+ * Write OTP memory
-+ *
-+ * [in] value[0].a OTP start offset in byte
-+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
-+ * [in] memref[1].buffer Input buffer to read values
-+ * [in] memref[1].size Size of OTP to be written
-+ *
-+ * Return codes:
-+ * TEE_SUCCESS - Invoke command success
-+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
-+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
-+ */
-+#define PTA_BSEC_WRITE_MEM 0x1
-+
-+/* value of PTA_BSEC access type = value[in] b */
-+#define SHADOW_ACCESS 0
-+#define FUSE_ACCESS 1
-+#define LOCK_ACCESS 2
-+
-+/* Bitfield definition for LOCK status */
-+#define LOCK_PERM BIT(30)
-+
-+/* OP-TEE STM32MP BSEC TA UUID */
-+static const uuid_t stm32mp_bsec_ta_uuid =
-+ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
-+ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
-+
-+/*
-+ * Check whether this driver supports the BSEC TA in the TEE instance
-+ * represented by the params (ver/data) to this function.
-+ */
-+static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
-+ const void *data)
-+{
-+ /* Currently this driver only supports GP compliant, OP-TEE based TA */
-+ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
-+ (ver->gen_caps & TEE_GEN_CAP_GP))
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+/* Open a session to OP-TEE for STM32MP BSEC TA */
-+static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
-+{
-+ struct tee_ioctl_open_session_arg sess_arg;
-+ int rc;
-+
-+ memset(&sess_arg, 0, sizeof(sess_arg));
-+ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
-+ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
-+ sess_arg.num_params = 0;
-+
-+ rc = tee_client_open_session(ctx, &sess_arg, NULL);
-+ if ((rc < 0) || (sess_arg.ret != 0)) {
-+ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
-+ __func__, sess_arg.ret, rc);
-+ if (!rc)
-+ rc = -EINVAL;
-+ } else {
-+ *id = sess_arg.session;
-+ }
-+
-+ return rc;
-+}
-+
-+/* close a session to OP-TEE for STM32MP BSEC TA */
-+static void stm32_bsec_ta_close_session(void *ctx, u32 id)
-+{
-+ tee_client_close_session(ctx, id);
-+}
-+
-+/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
-+int stm32_bsec_optee_ta_open(struct tee_context **ctx)
-+{
-+ struct tee_context *tee_ctx;
-+ u32 session_id;
-+ int rc;
-+
-+ /* Open context with TEE driver */
-+ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
-+ if (IS_ERR(tee_ctx)) {
-+ rc = PTR_ERR(tee_ctx);
-+ if (rc == -ENOENT)
-+ return -EPROBE_DEFER;
-+ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
-+
-+ return rc;
-+ }
-+
-+ /* Check STM32MP BSEC TA presence */
-+ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
-+ if (rc) {
-+ tee_client_close_context(tee_ctx);
-+ return rc;
-+ }
-+
-+ stm32_bsec_ta_close_session(tee_ctx, session_id);
-+
-+ *ctx = tee_ctx;
-+
-+ return 0;
-+}
-+
-+/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
-+void stm32_bsec_optee_ta_close(void *ctx)
-+{
-+ tee_client_close_context(ctx);
-+}
-+
-+/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
-+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ struct tee_shm *shm;
-+ struct tee_ioctl_invoke_arg arg;
-+ struct tee_param param[2];
-+ u8 *shm_buf;
-+ u32 start, num_bytes;
-+ int ret;
-+ u32 session_id;
-+
-+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
-+ if (ret)
-+ return ret;
-+
-+ memset(&arg, 0, sizeof(arg));
-+ memset(&param, 0, sizeof(param));
-+
-+ arg.func = PTA_BSEC_READ_MEM;
-+ arg.session = session_id;
-+ arg.num_params = 2;
-+
-+ /* align access on 32bits */
-+ start = ALIGN_DOWN(offset, 4);
-+ num_bytes = round_up(offset + bytes - start, 4);
-+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-+ param[0].u.value.a = start;
-+ param[0].u.value.b = SHADOW_ACCESS;
-+
-+ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
-+ if (IS_ERR(shm)) {
-+ ret = PTR_ERR(shm);
-+ goto out_tee_session;
-+ }
-+
-+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
-+ param[1].u.memref.shm = shm;
-+ param[1].u.memref.size = num_bytes;
-+
-+ ret = tee_client_invoke_func(ctx, &arg, param);
-+ if (ret < 0 || arg.ret != 0) {
-+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
-+ arg.ret, ret);
-+ if (!ret)
-+ ret = -EIO;
-+ }
-+ if (!ret) {
-+ shm_buf = tee_shm_get_va(shm, 0);
-+ if (IS_ERR(shm_buf)) {
-+ ret = PTR_ERR(shm_buf);
-+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
-+ } else {
-+ /* read data from 32 bits aligned buffer */
-+ memcpy(buf, &shm_buf[offset % 4], bytes);
-+ }
-+ }
-+
-+ tee_shm_free(shm);
-+
-+out_tee_session:
-+ stm32_bsec_ta_close_session(ctx, session_id);
-+
-+ return ret;
-+}
-+
-+/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
-+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-+ unsigned int offset, void *buf, size_t bytes)
-+{ struct tee_shm *shm;
-+ struct tee_ioctl_invoke_arg arg;
-+ struct tee_param param[2];
-+ u8 *shm_buf;
-+ int ret;
-+ u32 session_id;
-+
-+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
-+ if (ret)
-+ return ret;
-+
-+ /* Allow only writing complete 32-bits aligned words */
-+ if ((bytes % 4) || (offset % 4))
-+ return -EINVAL;
-+
-+ memset(&arg, 0, sizeof(arg));
-+ memset(&param, 0, sizeof(param));
-+
-+ arg.func = PTA_BSEC_WRITE_MEM;
-+ arg.session = session_id;
-+ arg.num_params = 2;
-+
-+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-+ param[0].u.value.a = offset;
-+ param[0].u.value.b = FUSE_ACCESS;
-+
-+ shm = tee_shm_alloc_kernel_buf(ctx, bytes);
-+ if (IS_ERR(shm)) {
-+ ret = PTR_ERR(shm);
-+ goto out_tee_session;
-+ }
-+
-+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
-+ param[1].u.memref.shm = shm;
-+ param[1].u.memref.size = bytes;
-+
-+ shm_buf = tee_shm_get_va(shm, 0);
-+ if (IS_ERR(shm_buf)) {
-+ ret = PTR_ERR(shm_buf);
-+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
-+ tee_shm_free(shm);
-+
-+ goto out_tee_session;
-+ }
-+
-+ memcpy(shm_buf, buf, bytes);
-+
-+ ret = tee_client_invoke_func(ctx, &arg, param);
-+ if (ret < 0 || arg.ret != 0) {
-+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
-+ if (!ret)
-+ ret = -EIO;
-+ }
-+ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
-+
-+ /* Lock the upper OTPs with ECC protection, word programming only */
-+ if (!ret && ((offset + bytes) >= (lower * 4))) {
-+ u32 start, nb_lock;
-+ u32 *lock = (u32 *)shm_buf;
-+ int i;
-+
-+ /*
-+ * don't lock the lower OTPs, no ECC protection and incremental
-+ * bit programming, a second write is allowed
-+ */
-+ start = max_t(u32, offset, lower * 4);
-+ nb_lock = (offset + bytes - start) / 4;
-+
-+ param[0].u.value.a = start;
-+ param[0].u.value.b = LOCK_ACCESS;
-+ param[1].u.memref.size = nb_lock * 4;
-+
-+ for (i = 0; i < nb_lock; i++)
-+ lock[i] = LOCK_PERM;
-+
-+ ret = tee_client_invoke_func(ctx, &arg, param);
-+ if (ret < 0 || arg.ret != 0) {
-+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
-+ if (!ret)
-+ ret = -EIO;
-+ }
-+ pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
-+ start / 4, start / 4 + nb_lock, ret);
-+ }
-+
-+ tee_shm_free(shm);
-+
-+out_tee_session:
-+ stm32_bsec_ta_close_session(ctx, session_id);
-+
-+ return ret;
-+}
---- /dev/null
-+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
-@@ -0,0 +1,80 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+/*
-+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
-+ *
-+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
-+ */
-+
-+#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
-+/**
-+ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
-+ * @ctx: the OP-TEE context on success
-+ *
-+ * Return:
-+ * On success, 0. On failure, -errno.
-+ */
-+int stm32_bsec_optee_ta_open(struct tee_context **ctx);
-+
-+/**
-+ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
-+ * @ctx: the OP-TEE context
-+ *
-+ * This function used to clean the OP-TEE resources initialized in
-+ * stm32_bsec_optee_ta_open(); it can be used as callback to
-+ * devm_add_action_or_reset()
-+ */
-+void stm32_bsec_optee_ta_close(void *ctx);
-+
-+/**
-+ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
-+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
-+ * @offset: nvmem offset
-+ * @buf: buffer to fill with nvem values
-+ * @bytes: number of bytes to read
-+ *
-+ * Return:
-+ * On success, 0. On failure, -errno.
-+ */
-+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
-+ void *buf, size_t bytes);
-+
-+/**
-+ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
-+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
-+ * @lower: number of lower OTP, not protected by ECC
-+ * @offset: nvmem offset
-+ * @buf: buffer with nvem values
-+ * @bytes: number of bytes to write
-+ *
-+ * Return:
-+ * On success, 0. On failure, -errno.
-+ */
-+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-+ unsigned int offset, void *buf, size_t bytes);
-+
-+#else
-+
-+static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+static inline void stm32_bsec_optee_ta_close(void *ctx)
-+{
-+}
-+
-+static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
-+ unsigned int lower,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ return -EOPNOTSUPP;
-+}
-+#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -11,6 +11,9 @@
- #include <linux/module.h>
- #include <linux/nvmem-provider.h>
- #include <linux/of_device.h>
-+#include <linux/tee_drv.h>
-+
-+#include "stm32-bsec-optee-ta.h"
-
- /* BSEC secure service access from non-secure */
- #define STM32_SMC_BSEC 0x82001003
-@@ -25,12 +28,14 @@
- struct stm32_romem_cfg {
- int size;
- u8 lower;
-+ bool ta;
- };
-
- struct stm32_romem_priv {
- void __iomem *base;
- struct nvmem_config cfg;
- u8 lower;
-+ struct tee_context *ctx;
- };
-
- static int stm32_romem_read(void *context, unsigned int offset, void *buf,
-@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex
- return 0;
- }
-
-+static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ struct stm32_romem_priv *priv = context;
-+
-+ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
-+}
-+
-+static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ struct stm32_romem_priv *priv = context;
-+
-+ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
-+}
-+
- static int stm32_romem_probe(struct platform_device *pdev)
- {
- const struct stm32_romem_cfg *cfg;
- struct device *dev = &pdev->dev;
- struct stm32_romem_priv *priv;
- struct resource *res;
-+ int rc;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat
- } else {
- priv->cfg.size = cfg->size;
- priv->lower = cfg->lower;
-- priv->cfg.reg_read = stm32_bsec_read;
-- priv->cfg.reg_write = stm32_bsec_write;
-+ if (cfg->ta) {
-+ rc = stm32_bsec_optee_ta_open(&priv->ctx);
-+ /* wait for OP-TEE client driver to be up and ready */
-+ if (rc)
-+ return rc;
-+ }
-+ if (priv->ctx) {
-+ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
-+ if (rc) {
-+ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
-+ return rc;
-+ }
-+ priv->cfg.reg_read = stm32_bsec_pta_read;
-+ priv->cfg.reg_write = stm32_bsec_pta_write;
-+ } else {
-+ priv->cfg.reg_read = stm32_bsec_read;
-+ priv->cfg.reg_write = stm32_bsec_write;
-+ }
- }
-
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
- }
-
- /*
-- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
-+ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
- * => 96 x 32-bits data words
- * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
- * => 32 (x 32-bits) lower shadow registers = words 0 to 31
-@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat
- static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
- .size = 384,
- .lower = 32,
-+ .ta = false,
-+};
-+
-+static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
-+ .size = 384,
-+ .lower = 32,
-+ .ta = true,
- };
-
- static const struct of_device_id stm32_romem_of_match[] = {
-@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r
- .compatible = "st,stm32mp15-bsec",
- .data = (void *)&stm32mp15_bsec_cfg,
- }, {
-+ .compatible = "st,stm32mp13-bsec",
-+ .data = (void *)&stm32mp13_bsec_cfg,
- },
-+ { /* sentinel */ },
- };
- MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
-
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch b/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch
deleted file mode 100644
index cea8e93858..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Mon, 6 Feb 2023 13:43:52 +0000
-Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x
-
-On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used;
-the PTA BSEC should be used as it is done on STM32MP13x platform,
-but the BSEC SMC can be also used: it is a legacy mode in OP-TEE,
-not recommended but used in previous OP-TEE firmware.
-
-The presence of OP-TEE is dynamically detected in STM32MP15x device tree
-and the supported NVMEM backend is dynamically detected:
-- PTA with stm32_bsec_pta_find
-- SMC with stm32_bsec_check
-
-With OP-TEE but without PTA and SMC detection, the probe is deferred for
-STM32MP15x devices.
-
-On STM32MP13x platform, only the PTA is supported with cfg->ta = true
-and this detection is skipped.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++----
- 1 file changed, 34 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co
- return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
- }
-
-+static bool stm32_bsec_smc_check(void)
-+{
-+ u32 val;
-+ int ret;
-+
-+ /* check that the OP-TEE support the BSEC SMC (legacy mode) */
-+ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val);
-+
-+ return !ret;
-+}
-+
-+static bool optee_presence_check(void)
-+{
-+ struct device_node *np;
-+ bool tee_detected = false;
-+
-+ /* check that the OP-TEE node is present and available. */
-+ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz");
-+ if (np && of_device_is_available(np))
-+ tee_detected = true;
-+ of_node_put(np);
-+
-+ return tee_detected;
-+}
-+
- static int stm32_romem_probe(struct platform_device *pdev)
- {
- const struct stm32_romem_cfg *cfg;
-@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat
- } else {
- priv->cfg.size = cfg->size;
- priv->lower = cfg->lower;
-- if (cfg->ta) {
-+ if (cfg->ta || optee_presence_check()) {
- rc = stm32_bsec_optee_ta_open(&priv->ctx);
-- /* wait for OP-TEE client driver to be up and ready */
-- if (rc)
-- return rc;
-+ if (rc) {
-+ /* wait for OP-TEE client driver to be up and ready */
-+ if (rc == -EPROBE_DEFER)
-+ return -EPROBE_DEFER;
-+ /* BSEC PTA is required or SMC not supported */
-+ if (cfg->ta || !stm32_bsec_smc_check())
-+ return rc;
-+ }
- }
- if (priv->ctx) {
- rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch b/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch
deleted file mode 100644
index 9d6275a737..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001
-From: Randy Dunlap <rdunlap@infradead.org>
-Date: Mon, 6 Feb 2023 13:43:53 +0000
-Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning
-
-Convert an empty line to " *" to avoid a kernel-doc warning:
-
-drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line:
-
-Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
-Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Cc: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
-Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
-Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rave-sp-eeprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/rave-sp-eeprom.c
-+++ b/drivers/nvmem/rave-sp-eeprom.c
-@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size {
- * @type: Access type (see enum rave_sp_eeprom_access_type)
- * @success: Success flag (Success = 1, Failure = 0)
- * @data: Read data
--
-+ *
- * Note this structure corresponds to RSP_*_EEPROM payload from RAVE
- * SP ICD
- */
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch b/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch
deleted file mode 100644
index 1ab9e609d3..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001
-From: Johan Hovold <johan+linaro@kernel.org>
-Date: Mon, 6 Feb 2023 13:43:54 +0000
-Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time
-
-There are currently no in-tree users of the Qualcomm SDAM nvmem driver
-and there is generally no point in registering a driver that can be
-built as a module at subsys init time.
-
-Register the driver at the normal device init time instead and let
-driver core sort out the probe order.
-
-Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
-Reviewed-by: Bjorn Andersson <andersson@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qcom-spmi-sdam.c | 13 +------------
- 1 file changed, 1 insertion(+), 12 deletions(-)
-
---- a/drivers/nvmem/qcom-spmi-sdam.c
-+++ b/drivers/nvmem/qcom-spmi-sdam.c
-@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive
- },
- .probe = sdam_probe,
- };
--
--static int __init sdam_init(void)
--{
-- return platform_driver_register(&sdam_driver);
--}
--subsys_initcall(sdam_init);
--
--static void __exit sdam_exit(void)
--{
-- return platform_driver_unregister(&sdam_driver);
--}
--module_exit(sdam_exit);
-+module_platform_driver(sdam_driver);
-
- MODULE_DESCRIPTION("QCOM SPMI SDAM driver");
- MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch b/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch
deleted file mode 100644
index dcf704c6ff..0000000000
--- a/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Mon, 6 Feb 2023 13:43:56 +0000
-Subject: [PATCH] nvmem: stm32: fix OPTEE dependency
-
-The stm32 nvmem driver fails to link as built-in when OPTEE
-is a loadable module:
-
-aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
-stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session'
-aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
-stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context'
-
-Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only
-be built-in if OPTEE is either built-in or disabled, and
-make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE
- will be called nvmem-sprd-efuse.
-
- config NVMEM_STM32_BSEC_OPTEE_TA
-- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
-- depends on OPTEE
-+ def_bool NVMEM_STM32_ROMEM && OPTEE
- help
- Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
- trusted application STM32MP BSEC.
-@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA
- config NVMEM_STM32_ROMEM
- tristate "STMicroelectronics STM32 factory-programmed memory support"
- depends on ARCH_STM32 || COMPILE_TEST
-- imply NVMEM_STM32_BSEC_OPTEE_TA
-+ depends on OPTEE || !OPTEE
- help
- Say y here to enable read-only access for STMicroelectronics STM32
- factory-programmed memory area.
diff --git a/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch b/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch
deleted file mode 100644
index 5c4206da14..0000000000
--- a/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 4d70c74659d9746502b23d055dba03d1d28ec388 Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Wed, 30 Nov 2022 15:48:35 +0200
-Subject: [PATCH] i915: Move list_count() to list.h as list_count_nodes() for
- broader use
-
-Some of the existing users, and definitely will be new ones, want to
-count existing nodes in the list. Provide a generic API for that by
-moving code from i915 to list.h.
-
-Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
-Acked-by: Jani Nikula <jani.nikula@intel.com>
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Link: https://lore.kernel.org/r/20221130134838.23805-1-andriy.shevchenko@linux.intel.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 15 ++-------------
- include/linux/list.h | 15 +++++++++++++++
- 2 files changed, 17 insertions(+), 13 deletions(-)
-
---- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
-+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
-@@ -4157,17 +4157,6 @@ void intel_execlists_show_requests(struc
- spin_unlock_irqrestore(&sched_engine->lock, flags);
- }
-
--static unsigned long list_count(struct list_head *list)
--{
-- struct list_head *pos;
-- unsigned long count = 0;
--
-- list_for_each(pos, list)
-- count++;
--
-- return count;
--}
--
- void intel_execlists_dump_active_requests(struct intel_engine_cs *engine,
- struct i915_request *hung_rq,
- struct drm_printer *m)
-@@ -4178,8 +4167,8 @@ void intel_execlists_dump_active_request
-
- intel_engine_dump_active_requests(&engine->sched_engine->requests, hung_rq, m);
-
-- drm_printf(m, "\tOn hold?: %lu\n",
-- list_count(&engine->sched_engine->hold));
-+ drm_printf(m, "\tOn hold?: %zu\n",
-+ list_count_nodes(&engine->sched_engine->hold));
-
- spin_unlock_irqrestore(&engine->sched_engine->lock, flags);
- }
---- a/include/linux/list.h
-+++ b/include/linux/list.h
-@@ -656,6 +656,21 @@ static inline void list_splice_tail_init
- pos = n, n = pos->prev)
-
- /**
-+ * list_count_nodes - count nodes in the list
-+ * @head: the head for your list.
-+ */
-+static inline size_t list_count_nodes(struct list_head *head)
-+{
-+ struct list_head *pos;
-+ size_t count = 0;
-+
-+ list_for_each(pos, head)
-+ count++;
-+
-+ return count;
-+}
-+
-+/**
- * list_entry_is_head - test if the entry points to the head of the list
- * @pos: the type * to cursor
- * @head: the head for your list.
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch b/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch
deleted file mode 100644
index 8328e87c0a..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From bcd1fe07def0f070eb5f31594620aaee6f81d31a Mon Sep 17 00:00:00 2001
-From: Nick Alcock <nick.alcock@oracle.com>
-Date: Tue, 4 Apr 2023 18:21:11 +0100
-Subject: [PATCH] nvmem: xilinx: zynqmp: make modular
-
-This driver has a MODULE_LICENSE but is not tristate so cannot be
-built as a module, unlike all its peers: make it modular to match.
-
-Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
-Suggested-by: Michal Simek <michal.simek@amd.com>
-Cc: Luis Chamberlain <mcgrof@kernel.org>
-Cc: linux-modules@vger.kernel.org
-Cc: linux-kernel@vger.kernel.org
-Cc: Hitomi Hasegawa <hasegawa-hitomi@fujitsu.com>
-Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Cc: Michal Simek <michal.simek@xilinx.com>
-Cc: linux-arm-kernel@lists.infradead.org
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -368,7 +368,7 @@ config NVMEM_VF610_OCOTP
- be called nvmem-vf610-ocotp.
-
- config NVMEM_ZYNQMP
-- bool "Xilinx ZYNQMP SoC nvmem firmware support"
-+ tristate "Xilinx ZYNQMP SoC nvmem firmware support"
- depends on ARCH_ZYNQMP
- help
- This is a driver to access hardware related data like
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch
deleted file mode 100644
index 94cd23c18a..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch
+++ /dev/null
@@ -1,387 +0,0 @@
-From 266570f496b90dea8fda893c2cf7c28d63ae2bd9 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:21 +0100
-Subject: [PATCH] nvmem: core: introduce NVMEM layouts
-
-NVMEM layouts are used to generate NVMEM cells during runtime. Think of
-an EEPROM with a well-defined conent. For now, the content can be
-described by a device tree or a board file. But this only works if the
-offsets and lengths are static and don't change. One could also argue
-that putting the layout of the EEPROM in the device tree is the wrong
-place. Instead, the device tree should just have a specific compatible
-string.
-
-Right now there are two use cases:
- (1) The NVMEM cell needs special processing. E.g. if it only specifies
- a base MAC address offset and you need to add an offset, or it
- needs to parse a MAC from ASCII format or some proprietary format.
- (Post processing of cells is added in a later commit).
- (2) u-boot environment parsing. The cells don't have a particular
- offset but it needs parsing the content to determine the offsets
- and length.
-
-Co-developed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-14-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- Documentation/driver-api/nvmem.rst | 15 ++++
- drivers/nvmem/Kconfig | 4 +
- drivers/nvmem/Makefile | 1 +
- drivers/nvmem/core.c | 120 +++++++++++++++++++++++++++++
- drivers/nvmem/layouts/Kconfig | 5 ++
- drivers/nvmem/layouts/Makefile | 4 +
- include/linux/nvmem-consumer.h | 7 ++
- include/linux/nvmem-provider.h | 51 ++++++++++++
- 8 files changed, 207 insertions(+)
- create mode 100644 drivers/nvmem/layouts/Kconfig
- create mode 100644 drivers/nvmem/layouts/Makefile
-
---- a/Documentation/driver-api/nvmem.rst
-+++ b/Documentation/driver-api/nvmem.rst
-@@ -185,3 +185,18 @@ ex::
- =====================
-
- See Documentation/devicetree/bindings/nvmem/nvmem.txt
-+
-+8. NVMEM layouts
-+================
-+
-+NVMEM layouts are yet another mechanism to create cells. With the device
-+tree binding it is possible to specify simple cells by using an offset
-+and a length. Sometimes, the cells doesn't have a static offset, but
-+the content is still well defined, e.g. tag-length-values. In this case,
-+the NVMEM device content has to be first parsed and the cells need to
-+be added accordingly. Layouts let you read the content of the NVMEM device
-+and let you add cells dynamically.
-+
-+Another use case for layouts is the post processing of cells. With layouts,
-+it is possible to associate a custom post processing hook to a cell. It
-+even possible to add this hook to cells not created by the layout itself.
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -21,6 +21,10 @@ config NVMEM_SYSFS
- This interface is mostly used by userspace applications to
- read/write directly into nvmem.
-
-+# Layouts
-+
-+source "drivers/nvmem/layouts/Kconfig"
-+
- # Devices
-
- config NVMEM_APPLE_EFUSES
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -5,6 +5,7 @@
-
- obj-$(CONFIG_NVMEM) += nvmem_core.o
- nvmem_core-y := core.o
-+obj-y += layouts/
-
- # Devices
- obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -40,6 +40,7 @@ struct nvmem_device {
- nvmem_reg_write_t reg_write;
- nvmem_cell_post_process_t cell_post_process;
- struct gpio_desc *wp_gpio;
-+ struct nvmem_layout *layout;
- void *priv;
- };
-
-@@ -74,6 +75,9 @@ static LIST_HEAD(nvmem_lookup_list);
-
- static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
-
-+static DEFINE_SPINLOCK(nvmem_layout_lock);
-+static LIST_HEAD(nvmem_layouts);
-+
- static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
- void *val, size_t bytes)
- {
-@@ -728,6 +732,101 @@ static int nvmem_add_cells_from_of(struc
- return 0;
- }
-
-+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
-+{
-+ layout->owner = owner;
-+
-+ spin_lock(&nvmem_layout_lock);
-+ list_add(&layout->node, &nvmem_layouts);
-+ spin_unlock(&nvmem_layout_lock);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(__nvmem_layout_register);
-+
-+void nvmem_layout_unregister(struct nvmem_layout *layout)
-+{
-+ spin_lock(&nvmem_layout_lock);
-+ list_del(&layout->node);
-+ spin_unlock(&nvmem_layout_lock);
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-+
-+static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
-+{
-+ struct device_node *layout_np, *np = nvmem->dev.of_node;
-+ struct nvmem_layout *l, *layout = NULL;
-+
-+ layout_np = of_get_child_by_name(np, "nvmem-layout");
-+ if (!layout_np)
-+ return NULL;
-+
-+ spin_lock(&nvmem_layout_lock);
-+
-+ list_for_each_entry(l, &nvmem_layouts, node) {
-+ if (of_match_node(l->of_match_table, layout_np)) {
-+ if (try_module_get(l->owner))
-+ layout = l;
-+
-+ break;
-+ }
-+ }
-+
-+ spin_unlock(&nvmem_layout_lock);
-+ of_node_put(layout_np);
-+
-+ return layout;
-+}
-+
-+static void nvmem_layout_put(struct nvmem_layout *layout)
-+{
-+ if (layout)
-+ module_put(layout->owner);
-+}
-+
-+static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem)
-+{
-+ struct nvmem_layout *layout = nvmem->layout;
-+ int ret;
-+
-+ if (layout && layout->add_cells) {
-+ ret = layout->add_cells(&nvmem->dev, nvmem, layout);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+#if IS_ENABLED(CONFIG_OF)
-+/**
-+ * of_nvmem_layout_get_container() - Get OF node to layout container.
-+ *
-+ * @nvmem: nvmem device.
-+ *
-+ * Return: a node pointer with refcount incremented or NULL if no
-+ * container exists. Use of_node_put() on it when done.
-+ */
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
-+}
-+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container);
-+#endif
-+
-+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ struct device_node __maybe_unused *layout_np;
-+ const struct of_device_id *match;
-+
-+ layout_np = of_nvmem_layout_get_container(nvmem);
-+ match = of_match_node(layout->of_match_table, layout_np);
-+
-+ return match ? match->data : NULL;
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data);
-+
- /**
- * nvmem_register() - Register a nvmem device for given nvmem_config.
- * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
-@@ -834,6 +933,12 @@ struct nvmem_device *nvmem_register(cons
- goto err_put_device;
- }
-
-+ /*
-+ * If the driver supplied a layout by config->layout, the module
-+ * pointer will be NULL and nvmem_layout_put() will be a noop.
-+ */
-+ nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
-+
- if (config->cells) {
- rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
- if (rval)
-@@ -854,12 +959,17 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-+ rval = nvmem_add_cells_from_layout(nvmem);
-+ if (rval)
-+ goto err_remove_cells;
-+
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
-
- return nvmem;
-
- err_remove_cells:
- nvmem_device_remove_all_cells(nvmem);
-+ nvmem_layout_put(nvmem->layout);
- if (config->compat)
- nvmem_sysfs_remove_compat(nvmem, config);
- err_put_device:
-@@ -881,6 +991,7 @@ static void nvmem_device_release(struct
- device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
-
- nvmem_device_remove_all_cells(nvmem);
-+ nvmem_layout_put(nvmem->layout);
- device_unregister(&nvmem->dev);
- }
-
-@@ -1246,6 +1357,15 @@ struct nvmem_cell *of_nvmem_cell_get(str
- return ERR_PTR(-EINVAL);
- }
-
-+ /* nvmem layouts produce cells within the nvmem-layout container */
-+ if (of_node_name_eq(nvmem_np, "nvmem-layout")) {
-+ nvmem_np = of_get_next_parent(nvmem_np);
-+ if (!nvmem_np) {
-+ of_node_put(cell_np);
-+ return ERR_PTR(-EINVAL);
-+ }
-+ }
-+
- nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
- of_node_put(nvmem_np);
- if (IS_ERR(nvmem)) {
---- /dev/null
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -0,0 +1,5 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+menu "Layout Types"
-+
-+endmenu
---- /dev/null
-+++ b/drivers/nvmem/layouts/Makefile
-@@ -0,0 +1,4 @@
-+# SPDX-License-Identifier: GPL-2.0
-+#
-+# Makefile for nvmem layouts.
-+#
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -239,6 +239,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
- const char *id);
- struct nvmem_device *of_nvmem_device_get(struct device_node *np,
- const char *name);
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem);
- #else
- static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
- const char *id)
-@@ -251,6 +252,12 @@ static inline struct nvmem_device *of_nv
- {
- return ERR_PTR(-EOPNOTSUPP);
- }
-+
-+static inline struct device_node *
-+of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return ERR_PTR(-EOPNOTSUPP);
-+}
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
- #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -88,6 +88,7 @@ struct nvmem_cell_info {
- * @stride: Minimum read/write access stride.
- * @priv: User context passed to read/write callbacks.
- * @ignore_wp: Write Protect pin is managed by the provider.
-+ * @layout: Fixed layout associated with this nvmem device.
- *
- * Note: A default "nvmem<id>" name will be assigned to the device if
- * no name is specified in its configuration. In such case "<id>" is
-@@ -109,6 +110,7 @@ struct nvmem_config {
- bool read_only;
- bool root_only;
- bool ignore_wp;
-+ struct nvmem_layout *layout;
- struct device_node *of_node;
- bool no_of_node;
- nvmem_reg_read_t reg_read;
-@@ -142,6 +144,33 @@ struct nvmem_cell_table {
- struct list_head node;
- };
-
-+/**
-+ * struct nvmem_layout - NVMEM layout definitions
-+ *
-+ * @name: Layout name.
-+ * @of_match_table: Open firmware match table.
-+ * @add_cells: Will be called if a nvmem device is found which
-+ * has this layout. The function will add layout
-+ * specific cells with nvmem_add_one_cell().
-+ * @owner: Pointer to struct module.
-+ * @node: List node.
-+ *
-+ * A nvmem device can hold a well defined structure which can just be
-+ * evaluated during runtime. For example a TLV list, or a list of "name=val"
-+ * pairs. A nvmem layout can parse the nvmem device and add appropriate
-+ * cells.
-+ */
-+struct nvmem_layout {
-+ const char *name;
-+ const struct of_device_id *of_match_table;
-+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout);
-+
-+ /* private */
-+ struct module *owner;
-+ struct list_head node;
-+};
-+
- #if IS_ENABLED(CONFIG_NVMEM)
-
- struct nvmem_device *nvmem_register(const struct nvmem_config *cfg);
-@@ -156,6 +185,14 @@ void nvmem_del_cell_table(struct nvmem_c
- int nvmem_add_one_cell(struct nvmem_device *nvmem,
- const struct nvmem_cell_info *info);
-
-+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner);
-+#define nvmem_layout_register(layout) \
-+ __nvmem_layout_register(layout, THIS_MODULE)
-+void nvmem_layout_unregister(struct nvmem_layout *layout);
-+
-+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout);
-+
- #else
-
- static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
-@@ -179,5 +216,19 @@ static inline int nvmem_add_one_cell(str
- return -EOPNOTSUPP;
- }
-
-+static inline int nvmem_layout_register(struct nvmem_layout *layout)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {}
-+
-+static inline const void *
-+nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ return NULL;
-+}
-+
- #endif /* CONFIG_NVMEM */
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
deleted file mode 100644
index 6fa7b6382d..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:22 +0100
-Subject: [PATCH] nvmem: core: handle the absence of expected layouts
-
-Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout
-is not available. This condition cannot be triggered today as nvmem
-layout drivers are initialed as part of an early init call, but soon
-these drivers will be converted into modules and be initialized with a
-standard priority, so the unavailability of the drivers might become a
-reality that must be taken care of.
-
-Let's anticipate this by telling the caller the layout might not yet be
-available. A probe deferral is requested in this case.
-
-Please note this does not affect any nvmem device not using layouts,
-because an early check against the "nvmem-layout" container presence
-will return NULL in this case.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
- static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
- {
- struct device_node *layout_np, *np = nvmem->dev.of_node;
-- struct nvmem_layout *l, *layout = NULL;
-+ struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
-
- layout_np = of_get_child_by_name(np, "nvmem-layout");
- if (!layout_np)
-@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons
- * pointer will be NULL and nvmem_layout_put() will be a noop.
- */
- nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
-+ if (IS_ERR(nvmem->layout)) {
-+ rval = PTR_ERR(nvmem->layout);
-+ nvmem->layout = NULL;
-+
-+ if (rval == -EPROBE_DEFER)
-+ goto err_teardown_compat;
-+ }
-
- if (config->cells) {
- rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
-@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons
- err_remove_cells:
- nvmem_device_remove_all_cells(nvmem);
- nvmem_layout_put(nvmem->layout);
-+err_teardown_compat:
- if (config->compat)
- nvmem_sysfs_remove_compat(nvmem, config);
- err_put_device:
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch
deleted file mode 100644
index b9341666f9..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From b1c37bec1ccfe5ccab72bc0ddc0dfa45c43e2de2 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:23 +0100
-Subject: [PATCH] nvmem: core: request layout modules loading
-
-When a storage device like an eeprom or an mtd device probes, it
-registers an nvmem device if the nvmem subsystem has been enabled (bool
-symbol). During nvmem registration, if the device is using layouts to
-expose dynamic nvmem cells, the core will first try to get a reference
-over the layout driver callbacks. In practice there is not relationship
-that can be described between the storage driver and the nvmem
-layout. So there is no way we can enforce both drivers will be built-in
-or both will be modules. If the storage device driver is built-in but
-the layout is built as a module, instead of badly failing with an
-endless probe deferral loop, lets just make a modprobe call in case the
-driver was made available in an initramfs with
-of_device_node_request_module(), and offer a fully functional system to
-the user.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-16-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -17,6 +17,7 @@
- #include <linux/nvmem-provider.h>
- #include <linux/gpio/consumer.h>
- #include <linux/of.h>
-+#include <linux/of_device.h>
- #include <linux/slab.h>
-
- struct nvmem_device {
-@@ -761,6 +762,13 @@ static struct nvmem_layout *nvmem_layout
- if (!layout_np)
- return NULL;
-
-+ /*
-+ * In case the nvmem device was built-in while the layout was built as a
-+ * module, we shall manually request the layout driver loading otherwise
-+ * we'll never have any match.
-+ */
-+ of_request_module(layout_np);
-+
- spin_lock(&nvmem_layout_lock);
-
- list_for_each_entry(l, &nvmem_layouts, node) {
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch
deleted file mode 100644
index 53628cd4e4..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 345ec382cd4b736c36e01f155d08c913b225b736 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:24 +0100
-Subject: [PATCH] nvmem: core: add per-cell post processing
-
-Instead of relying on the name the consumer is using for the cell, like
-it is done for the nvmem .cell_post_process configuration parameter,
-provide a per-cell post processing hook. This can then be populated by
-the NVMEM provider (or the NVMEM layout) when adding the cell.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-17-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 17 +++++++++++++++++
- include/linux/nvmem-provider.h | 3 +++
- 2 files changed, 20 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -54,6 +54,7 @@ struct nvmem_cell_entry {
- int bytes;
- int bit_offset;
- int nbits;
-+ nvmem_cell_post_process_t read_post_process;
- struct device_node *np;
- struct nvmem_device *nvmem;
- struct list_head node;
-@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell
- cell->offset = info->offset;
- cell->bytes = info->bytes;
- cell->name = info->name;
-+ cell->read_post_process = info->read_post_process;
-
- cell->bit_offset = info->bit_offset;
- cell->nbits = info->nbits;
-@@ -1563,6 +1565,13 @@ static int __nvmem_cell_read(struct nvme
- if (cell->bit_offset || cell->nbits)
- nvmem_shift_read_buffer_in_place(cell, buf);
-
-+ if (cell->read_post_process) {
-+ rc = cell->read_post_process(nvmem->priv, id, index,
-+ cell->offset, buf, cell->bytes);
-+ if (rc)
-+ return rc;
-+ }
-+
- if (nvmem->cell_post_process) {
- rc = nvmem->cell_post_process(nvmem->priv, id, index,
- cell->offset, buf, cell->bytes);
-@@ -1671,6 +1680,14 @@ static int __nvmem_cell_entry_write(stru
- (cell->bit_offset == 0 && len != cell->bytes))
- return -EINVAL;
-
-+ /*
-+ * Any cells which have a read_post_process hook are read-only because
-+ * we cannot reverse the operation and it might affect other cells,
-+ * too.
-+ */
-+ if (cell->read_post_process)
-+ return -EINVAL;
-+
- if (cell->bit_offset || cell->nbits) {
- buf = nvmem_cell_prepare_write_buffer(cell, buf, len);
- if (IS_ERR(buf))
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -54,6 +54,8 @@ struct nvmem_keepout {
- * @bit_offset: Bit offset if cell is smaller than a byte.
- * @nbits: Number of bits.
- * @np: Optional device_node pointer.
-+ * @read_post_process: Callback for optional post processing of cell data
-+ * on reads.
- */
- struct nvmem_cell_info {
- const char *name;
-@@ -62,6 +64,7 @@ struct nvmem_cell_info {
- unsigned int bit_offset;
- unsigned int nbits;
- struct device_node *np;
-+ nvmem_cell_post_process_t read_post_process;
- };
-
- /**
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch
deleted file mode 100644
index 32990148c8..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From de12c9691501ccba41a154c223869f82be4c12fd Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:25 +0100
-Subject: [PATCH] nvmem: core: allow to modify a cell before adding it
-
-Provide a way to modify a cell before it will get added. This is useful
-to attach a custom post processing hook via a layout.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-18-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 4 ++++
- include/linux/nvmem-provider.h | 5 +++++
- 2 files changed, 9 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -695,6 +695,7 @@ static int nvmem_validate_keepouts(struc
-
- static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
- {
-+ struct nvmem_layout *layout = nvmem->layout;
- struct device *dev = &nvmem->dev;
- struct device_node *child;
- const __be32 *addr;
-@@ -724,6 +725,9 @@ static int nvmem_add_cells_from_of(struc
-
- info.np = of_node_get(child);
-
-+ if (layout && layout->fixup_cell_info)
-+ layout->fixup_cell_info(nvmem, layout, &info);
-+
- ret = nvmem_add_one_cell(nvmem, &info);
- kfree(info.name);
- if (ret) {
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -155,6 +155,8 @@ struct nvmem_cell_table {
- * @add_cells: Will be called if a nvmem device is found which
- * has this layout. The function will add layout
- * specific cells with nvmem_add_one_cell().
-+ * @fixup_cell_info: Will be called before a cell is added. Can be
-+ * used to modify the nvmem_cell_info.
- * @owner: Pointer to struct module.
- * @node: List node.
- *
-@@ -168,6 +170,9 @@ struct nvmem_layout {
- const struct of_device_id *of_match_table;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem,
- struct nvmem_layout *layout);
-+ void (*fixup_cell_info)(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout,
-+ struct nvmem_cell_info *cell);
-
- /* private */
- struct module *owner;
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch b/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch
deleted file mode 100644
index 2a5fa618ea..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 6c56a82d7895a213a43182a5d01a21a906a79847 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:26 +0100
-Subject: [PATCH] nvmem: imx-ocotp: replace global post processing with layouts
-
-In preparation of retiring the global post processing hook change this
-driver to use layouts. The layout will be supplied during registration
-and will be used to add the post processing hook to all added cells.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Tested-by: Michael Walle <michael@walle.cc> # on kontron-pitx-imx8m
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-19-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/imx-ocotp.c | 30 +++++++++++++++++++-----------
- 1 file changed, 19 insertions(+), 11 deletions(-)
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -225,18 +225,13 @@ read_end:
- static int imx_ocotp_cell_pp(void *context, const char *id, int index,
- unsigned int offset, void *data, size_t bytes)
- {
-- struct ocotp_priv *priv = context;
-+ u8 *buf = data;
-+ int i;
-
- /* Deal with some post processing of nvmem cell data */
-- if (id && !strcmp(id, "mac-address")) {
-- if (priv->params->reverse_mac_address) {
-- u8 *buf = data;
-- int i;
--
-- for (i = 0; i < bytes/2; i++)
-- swap(buf[i], buf[bytes - i - 1]);
-- }
-- }
-+ if (id && !strcmp(id, "mac-address"))
-+ for (i = 0; i < bytes / 2; i++)
-+ swap(buf[i], buf[bytes - i - 1]);
-
- return 0;
- }
-@@ -488,7 +483,6 @@ static struct nvmem_config imx_ocotp_nvm
- .stride = 1,
- .reg_read = imx_ocotp_read,
- .reg_write = imx_ocotp_write,
-- .cell_post_process = imx_ocotp_cell_pp,
- };
-
- static const struct ocotp_params imx6q_params = {
-@@ -595,6 +589,17 @@ static const struct of_device_id imx_oco
- };
- MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
-
-+static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout,
-+ struct nvmem_cell_info *cell)
-+{
-+ cell->read_post_process = imx_ocotp_cell_pp;
-+}
-+
-+struct nvmem_layout imx_ocotp_layout = {
-+ .fixup_cell_info = imx_ocotp_fixup_cell_info,
-+};
-+
- static int imx_ocotp_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -619,6 +624,9 @@ static int imx_ocotp_probe(struct platfo
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
-+ if (priv->params->reverse_mac_address)
-+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-+
- priv->config = &imx_ocotp_nvmem_config;
-
- clk_prepare_enable(priv->clk);
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch
deleted file mode 100644
index eac202b882..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 011e40a166fdaa65fb9946b7cd91efec85b70dbb Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:27 +0100
-Subject: [PATCH] nvmem: cell: drop global cell_post_process
-
-There are no users anymore for the global cell_post_process callback
-anymore. New users should use proper nvmem layouts.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-20-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 9 ---------
- include/linux/nvmem-provider.h | 2 --
- 2 files changed, 11 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -39,7 +39,6 @@ struct nvmem_device {
- unsigned int nkeepout;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
-- nvmem_cell_post_process_t cell_post_process;
- struct gpio_desc *wp_gpio;
- struct nvmem_layout *layout;
- void *priv;
-@@ -903,7 +902,6 @@ struct nvmem_device *nvmem_register(cons
- nvmem->type = config->type;
- nvmem->reg_read = config->reg_read;
- nvmem->reg_write = config->reg_write;
-- nvmem->cell_post_process = config->cell_post_process;
- nvmem->keepout = config->keepout;
- nvmem->nkeepout = config->nkeepout;
- if (config->of_node)
-@@ -1575,13 +1573,6 @@ static int __nvmem_cell_read(struct nvme
- if (rc)
- return rc;
- }
--
-- if (nvmem->cell_post_process) {
-- rc = nvmem->cell_post_process(nvmem->priv, id, index,
-- cell->offset, buf, cell->bytes);
-- if (rc)
-- return rc;
-- }
-
- if (len)
- *len = cell->bytes;
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -85,7 +85,6 @@ struct nvmem_cell_info {
- * @no_of_node: Device should not use the parent's of_node even if it's !NULL.
- * @reg_read: Callback to read data.
- * @reg_write: Callback to write data.
-- * @cell_post_process: Callback for vendor specific post processing of cell data
- * @size: Device size.
- * @word_size: Minimum read/write access granularity.
- * @stride: Minimum read/write access stride.
-@@ -118,7 +117,6 @@ struct nvmem_config {
- bool no_of_node;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
-- nvmem_cell_post_process_t cell_post_process;
- int size;
- int word_size;
- int stride;
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch
deleted file mode 100644
index 46b30a2ed9..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 8a134fd9f9323f4c39ec27055b3d3723cfb5c1e9 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:28 +0100
-Subject: [PATCH] nvmem: core: provide own priv pointer in post process
- callback
-
-It doesn't make any more sense to have a opaque pointer set up by the
-nvmem device. Usually, the layout isn't associated with a particular
-nvmem device. Instead, let the caller who set the post process callback
-provide the priv pointer.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-21-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 4 +++-
- include/linux/nvmem-provider.h | 5 ++++-
- 2 files changed, 7 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -54,6 +54,7 @@ struct nvmem_cell_entry {
- int bit_offset;
- int nbits;
- nvmem_cell_post_process_t read_post_process;
-+ void *priv;
- struct device_node *np;
- struct nvmem_device *nvmem;
- struct list_head node;
-@@ -471,6 +472,7 @@ static int nvmem_cell_info_to_nvmem_cell
- cell->bytes = info->bytes;
- cell->name = info->name;
- cell->read_post_process = info->read_post_process;
-+ cell->priv = info->priv;
-
- cell->bit_offset = info->bit_offset;
- cell->nbits = info->nbits;
-@@ -1568,7 +1570,7 @@ static int __nvmem_cell_read(struct nvme
- nvmem_shift_read_buffer_in_place(cell, buf);
-
- if (cell->read_post_process) {
-- rc = cell->read_post_process(nvmem->priv, id, index,
-+ rc = cell->read_post_process(cell->priv, id, index,
- cell->offset, buf, cell->bytes);
- if (rc)
- return rc;
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -20,7 +20,8 @@ typedef int (*nvmem_reg_write_t)(void *p
- void *val, size_t bytes);
- /* used for vendor specific post processing of cell data */
- typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
-- unsigned int offset, void *buf, size_t bytes);
-+ unsigned int offset, void *buf,
-+ size_t bytes);
-
- enum nvmem_type {
- NVMEM_TYPE_UNKNOWN = 0,
-@@ -56,6 +57,7 @@ struct nvmem_keepout {
- * @np: Optional device_node pointer.
- * @read_post_process: Callback for optional post processing of cell data
- * on reads.
-+ * @priv: Opaque data passed to the read_post_process hook.
- */
- struct nvmem_cell_info {
- const char *name;
-@@ -65,6 +67,7 @@ struct nvmem_cell_info {
- unsigned int nbits;
- struct device_node *np;
- nvmem_cell_post_process_t read_post_process;
-+ void *priv;
- };
-
- /**
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch
deleted file mode 100644
index 7d97658b60..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch
+++ /dev/null
@@ -1,215 +0,0 @@
-From d9fae023fe86069750092fc1c2f3a73e2fb18512 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 4 Apr 2023 18:21:29 +0100
-Subject: [PATCH] nvmem: layouts: sl28vpd: Add new layout driver
-
-This layout applies to the VPD of the Kontron sl28 boards. The VPD only
-contains a base MAC address. Therefore, we have to add an individual
-offset to it. This is done by taking the second argument of the nvmem
-phandle into account. Also this let us checking the VPD version and the
-checksum.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-22-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/Kconfig | 9 ++
- drivers/nvmem/layouts/Makefile | 2 +
- drivers/nvmem/layouts/sl28vpd.c | 165 ++++++++++++++++++++++++++++++++
- 3 files changed, 176 insertions(+)
- create mode 100644 drivers/nvmem/layouts/sl28vpd.c
-
---- a/drivers/nvmem/layouts/Kconfig
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -2,4 +2,13 @@
-
- menu "Layout Types"
-
-+config NVMEM_LAYOUT_SL28_VPD
-+ tristate "Kontron sl28 VPD layout support"
-+ select CRC8
-+ help
-+ Say Y here if you want to support the VPD layout of the Kontron
-+ SMARC-sAL28 boards.
-+
-+ If unsure, say N.
-+
- endmenu
---- a/drivers/nvmem/layouts/Makefile
-+++ b/drivers/nvmem/layouts/Makefile
-@@ -2,3 +2,5 @@
- #
- # Makefile for nvmem layouts.
- #
-+
-+obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
---- /dev/null
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -0,0 +1,165 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/crc8.h>
-+#include <linux/etherdevice.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+#include <uapi/linux/if_ether.h>
-+
-+#define SL28VPD_MAGIC 'V'
-+
-+struct sl28vpd_header {
-+ u8 magic;
-+ u8 version;
-+} __packed;
-+
-+struct sl28vpd_v1 {
-+ struct sl28vpd_header header;
-+ char serial_number[15];
-+ u8 base_mac_address[ETH_ALEN];
-+ u8 crc8;
-+} __packed;
-+
-+static int sl28vpd_mac_address_pp(void *priv, const char *id, int index,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ if (bytes != ETH_ALEN)
-+ return -EINVAL;
-+
-+ if (index < 0)
-+ return -EINVAL;
-+
-+ if (!is_valid_ether_addr(buf))
-+ return -EINVAL;
-+
-+ eth_addr_add(buf, index);
-+
-+ return 0;
-+}
-+
-+static const struct nvmem_cell_info sl28vpd_v1_entries[] = {
-+ {
-+ .name = "serial-number",
-+ .offset = offsetof(struct sl28vpd_v1, serial_number),
-+ .bytes = sizeof_field(struct sl28vpd_v1, serial_number),
-+ },
-+ {
-+ .name = "base-mac-address",
-+ .offset = offsetof(struct sl28vpd_v1, base_mac_address),
-+ .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address),
-+ .read_post_process = sl28vpd_mac_address_pp,
-+ },
-+};
-+
-+static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem)
-+{
-+ struct sl28vpd_v1 data_v1;
-+ u8 table[CRC8_TABLE_SIZE];
-+ int ret;
-+ u8 crc;
-+
-+ crc8_populate_msb(table, 0x07);
-+
-+ ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1);
-+ if (ret < 0)
-+ return ret;
-+ else if (ret != sizeof(data_v1))
-+ return -EIO;
-+
-+ crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0);
-+
-+ if (crc != data_v1.crc8) {
-+ dev_err(dev,
-+ "Checksum is invalid (got %02x, expected %02x).\n",
-+ crc, data_v1.crc8);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ const struct nvmem_cell_info *pinfo;
-+ struct nvmem_cell_info info = {0};
-+ struct device_node *layout_np;
-+ struct sl28vpd_header hdr;
-+ int ret, i;
-+
-+ /* check header */
-+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr);
-+ if (ret < 0)
-+ return ret;
-+ else if (ret != sizeof(hdr))
-+ return -EIO;
-+
-+ if (hdr.magic != SL28VPD_MAGIC) {
-+ dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic);
-+ return -EINVAL;
-+ }
-+
-+ if (hdr.version != 1) {
-+ dev_err(dev, "Version %d is unsupported.\n", hdr.version);
-+ return -EINVAL;
-+ }
-+
-+ ret = sl28vpd_v1_check_crc(dev, nvmem);
-+ if (ret)
-+ return ret;
-+
-+ layout_np = of_nvmem_layout_get_container(nvmem);
-+ if (!layout_np)
-+ return -ENOENT;
-+
-+ for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) {
-+ pinfo = &sl28vpd_v1_entries[i];
-+
-+ info.name = pinfo->name;
-+ info.offset = pinfo->offset;
-+ info.bytes = pinfo->bytes;
-+ info.read_post_process = pinfo->read_post_process;
-+ info.np = of_get_child_by_name(layout_np, pinfo->name);
-+
-+ ret = nvmem_add_one_cell(nvmem, &info);
-+ if (ret) {
-+ of_node_put(layout_np);
-+ return ret;
-+ }
-+ }
-+
-+ of_node_put(layout_np);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id sl28vpd_of_match_table[] = {
-+ { .compatible = "kontron,sl28-vpd" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table);
-+
-+struct nvmem_layout sl28vpd_layout = {
-+ .name = "sl28-vpd",
-+ .of_match_table = sl28vpd_of_match_table,
-+ .add_cells = sl28vpd_add_cells,
-+};
-+
-+static int __init sl28vpd_init(void)
-+{
-+ return nvmem_layout_register(&sl28vpd_layout);
-+}
-+
-+static void __exit sl28vpd_exit(void)
-+{
-+ nvmem_layout_unregister(&sl28vpd_layout);
-+}
-+
-+module_init(sl28vpd_init);
-+module_exit(sl28vpd_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
-+MODULE_DESCRIPTION("NVMEM layout driver for the VPD of Kontron sl28 boards");
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch
deleted file mode 100644
index ca8b4bc069..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch
+++ /dev/null
@@ -1,306 +0,0 @@
-From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:31 +0100
-Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver
-
-This layout applies on top of any non volatile storage device containing
-an ONIE table factory flashed. This table follows the tlv
-(type-length-value) organization described in the link below. We cannot
-afford using regular parsers because the content of these tables is
-manufacturer specific and must be dynamically discovered.
-
-Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/Kconfig | 9 ++
- drivers/nvmem/layouts/Makefile | 1 +
- drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++
- 3 files changed, 267 insertions(+)
- create mode 100644 drivers/nvmem/layouts/onie-tlv.c
-
---- a/drivers/nvmem/layouts/Kconfig
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD
-
- If unsure, say N.
-
-+config NVMEM_LAYOUT_ONIE_TLV
-+ tristate "ONIE tlv support"
-+ select CRC32
-+ help
-+ Say Y here if you want to support the Open Compute Project ONIE
-+ Type-Length-Value standard table.
-+
-+ If unsure, say N.
-+
- endmenu
---- a/drivers/nvmem/layouts/Makefile
-+++ b/drivers/nvmem/layouts/Makefile
-@@ -4,3 +4,4 @@
- #
-
- obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
-+obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
---- /dev/null
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -0,0 +1,257 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * ONIE tlv NVMEM cells provider
-+ *
-+ * Copyright (C) 2022 Open Compute Group ONIE
-+ * Author: Miquel Raynal <miquel.raynal@bootlin.com>
-+ * Based on the nvmem driver written by: Vadym Kochan <vadym.kochan@plvision.eu>
-+ * Inspired by the first layout written by: Rafał Miłecki <rafal@milecki.pl>
-+ */
-+
-+#include <linux/crc32.h>
-+#include <linux/etherdevice.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+
-+#define ONIE_TLV_MAX_LEN 2048
-+#define ONIE_TLV_CRC_FIELD_SZ 6
-+#define ONIE_TLV_CRC_SZ 4
-+#define ONIE_TLV_HDR_ID "TlvInfo"
-+
-+struct onie_tlv_hdr {
-+ u8 id[8];
-+ u8 version;
-+ __be16 data_len;
-+} __packed;
-+
-+struct onie_tlv {
-+ u8 type;
-+ u8 len;
-+} __packed;
-+
-+static const char *onie_tlv_cell_name(u8 type)
-+{
-+ switch (type) {
-+ case 0x21:
-+ return "product-name";
-+ case 0x22:
-+ return "part-number";
-+ case 0x23:
-+ return "serial-number";
-+ case 0x24:
-+ return "mac-address";
-+ case 0x25:
-+ return "manufacture-date";
-+ case 0x26:
-+ return "device-version";
-+ case 0x27:
-+ return "label-revision";
-+ case 0x28:
-+ return "platform-name";
-+ case 0x29:
-+ return "onie-version";
-+ case 0x2A:
-+ return "num-macs";
-+ case 0x2B:
-+ return "manufacturer";
-+ case 0x2C:
-+ return "country-code";
-+ case 0x2D:
-+ return "vendor";
-+ case 0x2E:
-+ return "diag-version";
-+ case 0x2F:
-+ return "service-tag";
-+ case 0xFD:
-+ return "vendor-extension";
-+ case 0xFE:
-+ return "crc32";
-+ default:
-+ break;
-+ }
-+
-+ return NULL;
-+}
-+
-+static int onie_tlv_mac_read_cb(void *priv, const char *id, int index,
-+ unsigned int offset, void *buf,
-+ size_t bytes)
-+{
-+ eth_addr_add(buf, index);
-+
-+ return 0;
-+}
-+
-+static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf)
-+{
-+ switch (type) {
-+ case 0x24:
-+ return &onie_tlv_mac_read_cb;
-+ default:
-+ break;
-+ }
-+
-+ return NULL;
-+}
-+
-+static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem,
-+ size_t data_len, u8 *data)
-+{
-+ struct nvmem_cell_info cell = {};
-+ struct device_node *layout;
-+ struct onie_tlv tlv;
-+ unsigned int hdr_len = sizeof(struct onie_tlv_hdr);
-+ unsigned int offset = 0;
-+ int ret;
-+
-+ layout = of_nvmem_layout_get_container(nvmem);
-+ if (!layout)
-+ return -ENOENT;
-+
-+ while (offset < data_len) {
-+ memcpy(&tlv, data + offset, sizeof(tlv));
-+ if (offset + tlv.len >= data_len) {
-+ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n",
-+ tlv.len, hdr_len + offset);
-+ break;
-+ }
-+
-+ cell.name = onie_tlv_cell_name(tlv.type);
-+ if (!cell.name)
-+ continue;
-+
-+ cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len);
-+ cell.bytes = tlv.len;
-+ cell.np = of_get_child_by_name(layout, cell.name);
-+ cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv));
-+
-+ ret = nvmem_add_one_cell(nvmem, &cell);
-+ if (ret) {
-+ of_node_put(layout);
-+ return ret;
-+ }
-+
-+ offset += sizeof(tlv) + tlv.len;
-+ }
-+
-+ of_node_put(layout);
-+
-+ return 0;
-+}
-+
-+static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr)
-+{
-+ if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) {
-+ dev_err(dev, "Invalid header\n");
-+ return false;
-+ }
-+
-+ if (hdr->version != 0x1) {
-+ dev_err(dev, "Invalid version number\n");
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table)
-+{
-+ struct onie_tlv crc_hdr;
-+ u32 read_crc, calc_crc;
-+ __be32 crc_be;
-+
-+ memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr));
-+ if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) {
-+ dev_err(dev, "Invalid CRC field\n");
-+ return false;
-+ }
-+
-+ /* The table contains a JAMCRC, which is XOR'ed compared to the original
-+ * CRC32 implementation as known in the Ethernet world.
-+ */
-+ memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ);
-+ read_crc = be32_to_cpu(crc_be);
-+ calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF;
-+ if (read_crc != calc_crc) {
-+ dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n",
-+ read_crc, calc_crc);
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout)
-+{
-+ struct onie_tlv_hdr hdr;
-+ size_t table_len, data_len, hdr_len;
-+ u8 *table, *data;
-+ int ret;
-+
-+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!onie_tlv_hdr_is_valid(dev, &hdr)) {
-+ dev_err(dev, "Invalid ONIE TLV header\n");
-+ return -EINVAL;
-+ }
-+
-+ hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len);
-+ data_len = be16_to_cpu(hdr.data_len);
-+ table_len = hdr_len + data_len;
-+ if (table_len > ONIE_TLV_MAX_LEN) {
-+ dev_err(dev, "Invalid ONIE TLV data length\n");
-+ return -EINVAL;
-+ }
-+
-+ table = devm_kmalloc(dev, table_len, GFP_KERNEL);
-+ if (!table)
-+ return -ENOMEM;
-+
-+ ret = nvmem_device_read(nvmem, 0, table_len, table);
-+ if (ret != table_len)
-+ return ret;
-+
-+ if (!onie_tlv_crc_is_valid(dev, table_len, table))
-+ return -EINVAL;
-+
-+ data = table + hdr_len;
-+ ret = onie_tlv_add_cells(dev, nvmem, data_len, data);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id onie_tlv_of_match_table[] = {
-+ { .compatible = "onie,tlv-layout", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table);
-+
-+static struct nvmem_layout onie_tlv_layout = {
-+ .name = "ONIE tlv layout",
-+ .of_match_table = onie_tlv_of_match_table,
-+ .add_cells = onie_tlv_parse_table,
-+};
-+
-+static int __init onie_tlv_init(void)
-+{
-+ return nvmem_layout_register(&onie_tlv_layout);
-+}
-+
-+static void __exit onie_tlv_exit(void)
-+{
-+ nvmem_layout_unregister(&onie_tlv_layout);
-+}
-+
-+module_init(onie_tlv_init);
-+module_exit(onie_tlv_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
-+MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing");
-+MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing");
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch b/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch
deleted file mode 100644
index 94a0911d73..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From a4fb434ef96ace5af758ca2c52c3a3f8f3abc87c Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Tue, 4 Apr 2023 18:21:34 +0100
-Subject: [PATCH] nvmem: stm32-romem: mark OF related data as maybe unused
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The driver can be compile tested with !CONFIG_OF making certain data
-unused:
-
- drivers/nvmem/stm32-romem.c:271:34: error: ‘stm32_romem_of_match’ defined but not used [-Werror=unused-const-variable=]
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-27-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -268,7 +268,7 @@ static const struct stm32_romem_cfg stm3
- .ta = true,
- };
-
--static const struct of_device_id stm32_romem_of_match[] = {
-+static const struct of_device_id stm32_romem_of_match[] __maybe_unused = {
- { .compatible = "st,stm32f4-otp", }, {
- .compatible = "st,stm32mp15-bsec",
- .data = (void *)&stm32mp15_bsec_cfg,
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch b/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch
deleted file mode 100644
index abda402bdd..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From de6e05097f7db066afb0ad4c88b730949f7b7749 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Tue, 4 Apr 2023 18:21:35 +0100
-Subject: [PATCH] nvmem: mtk-efuse: Support postprocessing for GPU speed
- binning data
-
-On some MediaTek SoCs GPU speed binning data is available for read
-in the SoC's eFuse array but it has a format that is incompatible
-with what the OPP API expects, as we read a number from 0 to 7 but
-opp-supported-hw is expecting a bitmask to enable an OPP entry:
-being what we read limited to 0-7, it's straightforward to simply
-convert the value to BIT(value) as a post-processing action.
-
-So, introduce post-processing support and enable it by evaluating
-the newly introduced platform data's `uses_post_processing` member,
-currently enabled only for MT8186.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-28-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/mtk-efuse.c | 53 +++++++++++++++++++++++++++++++++++++--
- 1 file changed, 51 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -10,6 +10,11 @@
- #include <linux/io.h>
- #include <linux/nvmem-provider.h>
- #include <linux/platform_device.h>
-+#include <linux/property.h>
-+
-+struct mtk_efuse_pdata {
-+ bool uses_post_processing;
-+};
-
- struct mtk_efuse_priv {
- void __iomem *base;
-@@ -29,6 +34,37 @@ static int mtk_reg_read(void *context,
- return 0;
- }
-
-+static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index,
-+ unsigned int offset, void *data, size_t bytes)
-+{
-+ u8 *val = data;
-+
-+ if (val[0] < 8)
-+ val[0] = BIT(val[0]);
-+
-+ return 0;
-+}
-+
-+static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_layout *layout,
-+ struct nvmem_cell_info *cell)
-+{
-+ size_t sz = strlen(cell->name);
-+
-+ /*
-+ * On some SoCs, the GPU speedbin is not read as bitmask but as
-+ * a number with range [0-7] (max 3 bits): post process to use
-+ * it in OPP tables to describe supported-hw.
-+ */
-+ if (cell->nbits <= 3 &&
-+ strncmp(cell->name, "gpu-speedbin", min(sz, strlen("gpu-speedbin"))) == 0)
-+ cell->read_post_process = mtk_efuse_gpu_speedbin_pp;
-+}
-+
-+static struct nvmem_layout mtk_efuse_layout = {
-+ .fixup_cell_info = mtk_efuse_fixup_cell_info,
-+};
-+
- static int mtk_efuse_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -36,6 +72,7 @@ static int mtk_efuse_probe(struct platfo
- struct nvmem_device *nvmem;
- struct nvmem_config econfig = {};
- struct mtk_efuse_priv *priv;
-+ const struct mtk_efuse_pdata *pdata;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -45,20 +82,32 @@ static int mtk_efuse_probe(struct platfo
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
-+ pdata = device_get_match_data(dev);
- econfig.stride = 1;
- econfig.word_size = 1;
- econfig.reg_read = mtk_reg_read;
- econfig.size = resource_size(res);
- econfig.priv = priv;
- econfig.dev = dev;
-+ if (pdata->uses_post_processing)
-+ econfig.layout = &mtk_efuse_layout;
- nvmem = devm_nvmem_register(dev, &econfig);
-
- return PTR_ERR_OR_ZERO(nvmem);
- }
-
-+static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
-+ .uses_post_processing = true,
-+};
-+
-+static const struct mtk_efuse_pdata mtk_efuse_pdata = {
-+ .uses_post_processing = false,
-+};
-+
- static const struct of_device_id mtk_efuse_of_match[] = {
-- { .compatible = "mediatek,mt8173-efuse",},
-- { .compatible = "mediatek,efuse",},
-+ { .compatible = "mediatek,mt8173-efuse", .data = &mtk_efuse_pdata },
-+ { .compatible = "mediatek,mt8186-efuse", .data = &mtk_mt8186_efuse_pdata },
-+ { .compatible = "mediatek,efuse", .data = &mtk_efuse_pdata },
- {/* sentinel */},
- };
- MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch b/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch
deleted file mode 100644
index 200eb1928f..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 1dc552fa33cf98af3e784dbc0500da93cae3b24a Mon Sep 17 00:00:00 2001
-From: Yang Li <yang.lee@linux.alibaba.com>
-Date: Tue, 4 Apr 2023 18:21:38 +0100
-Subject: [PATCH] nvmem: bcm-ocotp: Use devm_platform_ioremap_resource()
-
-According to commit 7945f929f1a7 ("drivers: provide
-devm_platform_ioremap_resource()"), convert platform_get_resource(),
-devm_ioremap_resource() to a single call to use
-devm_platform_ioremap_resource(), as this is exactly what this function
-does.
-
-Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-31-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/bcm-ocotp.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/bcm-ocotp.c
-+++ b/drivers/nvmem/bcm-ocotp.c
-@@ -244,7 +244,6 @@ MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_
- static int bcm_otpc_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-- struct resource *res;
- struct otpc_priv *priv;
- struct nvmem_device *nvmem;
- int err;
-@@ -259,8 +258,7 @@ static int bcm_otpc_probe(struct platfor
- return -ENODEV;
-
- /* Get OTP base address register. */
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->base)) {
- dev_err(dev, "unable to map I/O memory\n");
- return PTR_ERR(priv->base);
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch b/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch
deleted file mode 100644
index 890dacd08d..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 649409990d2e93fac657be7c6960c28a2c601d65 Mon Sep 17 00:00:00 2001
-From: Yang Li <yang.lee@linux.alibaba.com>
-Date: Tue, 4 Apr 2023 18:21:39 +0100
-Subject: [PATCH] nvmem: nintendo-otp: Use devm_platform_ioremap_resource()
-
-According to commit 7945f929f1a7 ("drivers: provide
-devm_platform_ioremap_resource()"), convert platform_get_resource(),
-devm_ioremap_resource() to a single call to use
-devm_platform_ioremap_resource(), as this is exactly what this function
-does.
-
-Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-32-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/nintendo-otp.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/nintendo-otp.c
-+++ b/drivers/nvmem/nintendo-otp.c
-@@ -76,7 +76,6 @@ static int nintendo_otp_probe(struct pla
- struct device *dev = &pdev->dev;
- const struct of_device_id *of_id =
- of_match_device(nintendo_otp_of_table, dev);
-- struct resource *res;
- struct nvmem_device *nvmem;
- struct nintendo_otp_priv *priv;
-
-@@ -92,8 +91,7 @@ static int nintendo_otp_probe(struct pla
- if (!priv)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->regs = devm_ioremap_resource(dev, res);
-+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->regs))
- return PTR_ERR(priv->regs);
-
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch
deleted file mode 100644
index 3f5d3c1ad4..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From c2367aa60d5e34d48582362c6de34b4131d92be7 Mon Sep 17 00:00:00 2001
-From: Yang Li <yang.lee@linux.alibaba.com>
-Date: Tue, 4 Apr 2023 18:21:40 +0100
-Subject: [PATCH] nvmem: vf610-ocotp: Use
- devm_platform_get_and_ioremap_resource()
-
-According to commit 890cc39a8799 ("drivers: provide
-devm_platform_get_and_ioremap_resource()"), convert
-platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-33-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/vf610-ocotp.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/vf610-ocotp.c
-+++ b/drivers/nvmem/vf610-ocotp.c
-@@ -219,8 +219,7 @@ static int vf610_ocotp_probe(struct plat
- if (!ocotp_dev)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- ocotp_dev->base = devm_ioremap_resource(dev, res);
-+ ocotp_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(ocotp_dev->base))
- return PTR_ERR(ocotp_dev->base);
-
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch
deleted file mode 100644
index eeb407e9bb..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 55d4980ce55b6bb4be66877de4dbec513911b988 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Apr 2023 18:21:42 +0100
-Subject: [PATCH] nvmem: core: support specifying both: cell raw data & post
- read lengths
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Callback .read_post_process() is designed to modify raw cell content
-before providing it to the consumer. So far we were dealing with
-modifications that didn't affect cell size (length). In some cases
-however cell content needs to be reformatted and resized.
-
-It's required e.g. to provide properly formatted MAC address in case
-it's stored in a non-binary format (e.g. using ASCII).
-
-There were few discussions how to optimally handle that. Following
-possible solutions were considered:
-1. Allow .read_post_process() to realloc (resize) content buffer
-2. Allow .read_post_process() to adjust (decrease) just buffer length
-3. Register NVMEM cells using post-read sizes
-
-The preferred solution was the last one. The problem is that simply
-adjusting "bytes" in NVMEM providers would result in core code NOT
-passing whole raw data to .read_post_process() callbacks. It means
-callback functions couldn't do their job without somehow manually
-reading original cell content on their own.
-
-This patch deals with that by registering NVMEM cells with both lengths:
-raw content one and post read one. It allows:
-1. Core code to read whole raw cell content
-2. Callbacks to return content they want
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-35-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 11 +++++++----
- include/linux/nvmem-provider.h | 2 ++
- 2 files changed, 9 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -50,6 +50,7 @@ struct nvmem_device {
- struct nvmem_cell_entry {
- const char *name;
- int offset;
-+ size_t raw_len;
- int bytes;
- int bit_offset;
- int nbits;
-@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell
- {
- cell->nvmem = nvmem;
- cell->offset = info->offset;
-+ cell->raw_len = info->raw_len ?: info->bytes;
- cell->bytes = info->bytes;
- cell->name = info->name;
- cell->read_post_process = info->read_post_process;
-@@ -1560,7 +1562,7 @@ static int __nvmem_cell_read(struct nvme
- {
- int rc;
-
-- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes);
-+ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len);
-
- if (rc)
- return rc;
-@@ -1571,7 +1573,7 @@ static int __nvmem_cell_read(struct nvme
-
- if (cell->read_post_process) {
- rc = cell->read_post_process(cell->priv, id, index,
-- cell->offset, buf, cell->bytes);
-+ cell->offset, buf, cell->raw_len);
- if (rc)
- return rc;
- }
-@@ -1594,14 +1596,15 @@ static int __nvmem_cell_read(struct nvme
- */
- void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
- {
-- struct nvmem_device *nvmem = cell->entry->nvmem;
-+ struct nvmem_cell_entry *entry = cell->entry;
-+ struct nvmem_device *nvmem = entry->nvmem;
- u8 *buf;
- int rc;
-
- if (!nvmem)
- return ERR_PTR(-EINVAL);
-
-- buf = kzalloc(cell->entry->bytes, GFP_KERNEL);
-+ buf = kzalloc(max_t(size_t, entry->raw_len, entry->bytes), GFP_KERNEL);
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -51,6 +51,7 @@ struct nvmem_keepout {
- * struct nvmem_cell_info - NVMEM cell description
- * @name: Name.
- * @offset: Offset within the NVMEM device.
-+ * @raw_len: Length of raw data (without post processing).
- * @bytes: Length of the cell.
- * @bit_offset: Bit offset if cell is smaller than a byte.
- * @nbits: Number of bits.
-@@ -62,6 +63,7 @@ struct nvmem_keepout {
- struct nvmem_cell_info {
- const char *name;
- unsigned int offset;
-+ size_t raw_len;
- unsigned int bytes;
- unsigned int bit_offset;
- unsigned int nbits;
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch b/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch
deleted file mode 100644
index adde0ffc4b..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 4 Apr 2023 18:21:43 +0100
-Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-U-Boot environment variables are stored in ASCII format so "ethaddr"
-requires parsing into binary to make it work with Ethernet interfaces.
-
-This includes support for indexes to support #nvmem-cell-cells = <1>.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 1 +
- drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++
- 2 files changed, 27 insertions(+)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV
- tristate "U-Boot environment variables support"
- depends on OF && MTD
- select CRC32
-+ select GENERIC_NET_UTILS
- help
- U-Boot stores its setup as environment variables. This driver adds
- support for verifying & exporting such data. It also exposes variables
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -4,6 +4,8 @@
- */
-
- #include <linux/crc32.h>
-+#include <linux/etherdevice.h>
-+#include <linux/if_ether.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
-@@ -70,6 +72,25 @@ static int u_boot_env_read(void *context
- return 0;
- }
-
-+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
-+ unsigned int offset, void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN];
-+
-+ if (bytes != 3 * ETH_ALEN - 1)
-+ return -EINVAL;
-+
-+ if (!mac_pton(buf, mac))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
- static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
- size_t data_offset, size_t data_len)
- {
-@@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u
- priv->cells[idx].offset = data_offset + value - data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-+ if (!strcmp(var, "ethaddr")) {
-+ priv->cells[idx].raw_len = strlen(value);
-+ priv->cells[idx].bytes = ETH_ALEN;
-+ priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
-+ }
- }
-
- if (WARN_ON(idx != priv->ncells))
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch b/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch
deleted file mode 100644
index 7c6fe22b5f..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 814c978f02db17f16e6aa2efa2a929372f06da09 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:44 +0100
-Subject: [PATCH] nvmem: Add macro to register nvmem layout drivers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Provide a module_nvmem_layout_driver() macro at the end of the
-nvmem-provider.h header to reduce the boilerplate when registering nvmem
-layout drivers.
-
-Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-37-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/nvmem-provider.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -9,6 +9,7 @@
- #ifndef _LINUX_NVMEM_PROVIDER_H
- #define _LINUX_NVMEM_PROVIDER_H
-
-+#include <linux/device/driver.h>
- #include <linux/err.h>
- #include <linux/errno.h>
- #include <linux/gpio/consumer.h>
-@@ -242,4 +243,9 @@ nvmem_layout_get_match_data(struct nvmem
- }
-
- #endif /* CONFIG_NVMEM */
-+
-+#define module_nvmem_layout_driver(__layout_driver) \
-+ module_driver(__layout_driver, nvmem_layout_register, \
-+ nvmem_layout_unregister)
-+
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch
deleted file mode 100644
index 06646dd68b..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0abdf99fe0c86252ba274703425f8d543d7e7f0d Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:45 +0100
-Subject: [PATCH] nvmem: layouts: sl28vpd: Use module_nvmem_layout_driver()
-
-Stop open-coding the module init/exit functions. Use the
-module_nvmem_layout_driver() instead.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-38-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/sl28vpd.c | 14 +-------------
- 1 file changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -146,19 +146,7 @@ struct nvmem_layout sl28vpd_layout = {
- .of_match_table = sl28vpd_of_match_table,
- .add_cells = sl28vpd_add_cells,
- };
--
--static int __init sl28vpd_init(void)
--{
-- return nvmem_layout_register(&sl28vpd_layout);
--}
--
--static void __exit sl28vpd_exit(void)
--{
-- nvmem_layout_unregister(&sl28vpd_layout);
--}
--
--module_init(sl28vpd_init);
--module_exit(sl28vpd_exit);
-+module_nvmem_layout_driver(sl28vpd_layout);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch b/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch
deleted file mode 100644
index 826f4378c2..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From d119eb38faab61125aaa4f63c74eef61585cf34c Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:46 +0100
-Subject: [PATCH] nvmem: layouts: onie-tlv: Use module_nvmem_layout_driver()
-
-Stop open-coding the module init/exit functions. Use the
-module_nvmem_layout_driver() instead.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-39-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/onie-tlv.c | 14 +-------------
- 1 file changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -237,19 +237,7 @@ static struct nvmem_layout onie_tlv_layo
- .of_match_table = onie_tlv_of_match_table,
- .add_cells = onie_tlv_parse_table,
- };
--
--static int __init onie_tlv_init(void)
--{
-- return nvmem_layout_register(&onie_tlv_layout);
--}
--
--static void __exit onie_tlv_exit(void)
--{
-- nvmem_layout_unregister(&onie_tlv_layout);
--}
--
--module_init(onie_tlv_init);
--module_exit(onie_tlv_exit);
-+module_nvmem_layout_driver(onie_tlv_layout);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch b/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch
deleted file mode 100644
index f20db85ceb..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 6b13e4b6a9a45028ac730e550380077df1845912 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:47 +0100
-Subject: [PATCH] nvmem: layouts: onie-tlv: Drop wrong module alias
-
-The MODULE_ALIAS macro is misused here as it carries the
-description. There is currently no relevant alias to provide so let's
-just drop it.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-40-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/onie-tlv.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -242,4 +242,3 @@ module_nvmem_layout_driver(onie_tlv_layo
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
- MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing");
--MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing");
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch b/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch
deleted file mode 100644
index 5cf847b57a..0000000000
--- a/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From a8642cd11635a35a5f1dc31857887900d6610778 Mon Sep 17 00:00:00 2001
-From: Tom Rix <trix@redhat.com>
-Date: Tue, 4 Apr 2023 18:21:48 +0100
-Subject: [PATCH] nvmem: layouts: sl28vpd: set varaiable sl28vpd_layout
- storage-class-specifier to static
-
-smatch reports
-drivers/nvmem/layouts/sl28vpd.c:144:21: warning: symbol
- 'sl28vpd_layout' was not declared. Should it be static?
-
-This variable is only used in one file so it should be static.
-
-Signed-off-by: Tom Rix <trix@redhat.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-41-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/layouts/sl28vpd.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -141,7 +141,7 @@ static const struct of_device_id sl28vpd
- };
- MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table);
-
--struct nvmem_layout sl28vpd_layout = {
-+static struct nvmem_layout sl28vpd_layout = {
- .name = "sl28-vpd",
- .of_match_table = sl28vpd_of_match_table,
- .add_cells = sl28vpd_add_cells,
diff --git a/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch b/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch
deleted file mode 100644
index 13ee2d4229..0000000000
--- a/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From a5be5ce0e25439fae3cd42e3d775979547926812 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 3 Nov 2022 09:25:29 +0100
-Subject: [PATCH] firmware/nvram: bcm47xx: support init from IO memory
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Provide NVMEM content to the NVRAM driver from a simple
-memory resource. This is necessary to use NVRAM in a memory-
-mapped flash device. Patch taken from OpenWrts development
-tree.
-
-This patch makes it possible to use memory-mapped NVRAM
-on the D-Link DWL-8610AP and the D-Link DIR-890L.
-
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Cc: linux-mips@vger.kernel.org
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Cc: bcm-kernel-feedback-list@broadcom.com
-Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-[Added an export for modules potentially using the init symbol]
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221103082529.359084-1-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- drivers/firmware/broadcom/bcm47xx_nvram.c | 18 ++++++++++++++++++
- drivers/nvmem/brcm_nvram.c | 3 +++
- include/linux/bcm47xx_nvram.h | 6 ++++++
- 3 files changed, 27 insertions(+)
-
---- a/drivers/firmware/broadcom/bcm47xx_nvram.c
-+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
-@@ -110,6 +110,24 @@ found:
- return 0;
- }
-
-+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size)
-+{
-+ if (nvram_len) {
-+ pr_warn("nvram already initialized\n");
-+ return -EEXIST;
-+ }
-+
-+ if (!bcm47xx_nvram_is_valid(nvram_start)) {
-+ pr_err("No valid NVRAM found\n");
-+ return -ENOENT;
-+ }
-+
-+ bcm47xx_nvram_copy(nvram_start, res_size);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(bcm47xx_nvram_init_from_iomem);
-+
- /*
- * On bcm47xx we need access to the NVRAM very early, so we can't use mtd
- * subsystem to access flash. We can't even use platform device / driver to
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -3,6 +3,7 @@
- * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
- */
-
-+#include <linux/bcm47xx_nvram.h>
- #include <linux/io.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
-@@ -139,6 +140,8 @@ static int brcm_nvram_probe(struct platf
- if (err)
- return err;
-
-+ bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
-+
- config.dev = dev;
- config.cells = priv->cells;
- config.ncells = priv->ncells;
---- a/include/linux/bcm47xx_nvram.h
-+++ b/include/linux/bcm47xx_nvram.h
-@@ -11,6 +11,7 @@
- #include <linux/vmalloc.h>
-
- #ifdef CONFIG_BCM47XX_NVRAM
-+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size);
- int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
- int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
- int bcm47xx_nvram_gpio_pin(const char *name);
-@@ -20,6 +21,11 @@ static inline void bcm47xx_nvram_release
- vfree(nvram);
- };
- #else
-+static inline int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start,
-+ size_t res_size)
-+{
-+ return -ENOTSUPP;
-+}
- static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
- {
- return -ENOTSUPP;
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch b/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch
deleted file mode 100644
index 38cfccd5ef..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From eebc6573ad940b62a87776db3917e912b4f52d78 Mon Sep 17 00:00:00 2001
-From: Tom Rix <trix@redhat.com>
-Date: Sun, 11 Jun 2023 15:03:05 +0100
-Subject: [PATCH] nvmem: imx-ocotp: set varaiable imx_ocotp_layout
- storage-class-specifier to static
-
-smatch reports
-drivers/nvmem/imx-ocotp.c:599:21: warning: symbol
- 'imx_ocotp_layout' was not declared. Should it be static?
-
-This variable is only used in one file so should be static.
-
-Signed-off-by: Tom Rix <trix@redhat.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-2-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/imx-ocotp.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -596,7 +596,7 @@ static void imx_ocotp_fixup_cell_info(st
- cell->read_post_process = imx_ocotp_cell_pp;
- }
-
--struct nvmem_layout imx_ocotp_layout = {
-+static struct nvmem_layout imx_ocotp_layout = {
- .fixup_cell_info = imx_ocotp_fixup_cell_info,
- };
-
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch b/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch
deleted file mode 100644
index 7523e5ebf6..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 8a00fc606312c68b98add8fe8e6f7a013ce29e78 Mon Sep 17 00:00:00 2001
-From: Alexander Stein <alexander.stein@ew.tq-group.com>
-Date: Sun, 11 Jun 2023 15:03:06 +0100
-Subject: [PATCH] nvmem: imx-ocotp: Reverse MAC addresses on all i.MX derivates
-
-Not just i.MX8M, but all i.MX6/7 (and subtypes) need to reverse the
-MAC address read from fuses. Exceptions are i.MX6SLL and i.MX7ULP which
-do not support ethernet at all.
-
-Fixes: d0221a780cbc ("nvmem: imx-ocotp: add support for post processing")
-Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Tested-by: Richard Leitner <richard.leitner@skidata.com> # imx6q
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-3-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/imx-ocotp.c | 8 +-------
- 1 file changed, 1 insertion(+), 7 deletions(-)
-
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -97,7 +97,6 @@ struct ocotp_params {
- unsigned int bank_address_words;
- void (*set_timing)(struct ocotp_priv *priv);
- struct ocotp_ctrl_reg ctrl;
-- bool reverse_mac_address;
- };
-
- static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
-@@ -545,7 +544,6 @@ static const struct ocotp_params imx8mq_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-- .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mm_params = {
-@@ -553,7 +551,6 @@ static const struct ocotp_params imx8mm_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-- .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mn_params = {
-@@ -561,7 +558,6 @@ static const struct ocotp_params imx8mn_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
-- .reverse_mac_address = true,
- };
-
- static const struct ocotp_params imx8mp_params = {
-@@ -569,7 +565,6 @@ static const struct ocotp_params imx8mp_
- .bank_address_words = 0,
- .set_timing = imx_ocotp_set_imx6_timing,
- .ctrl = IMX_OCOTP_BM_CTRL_8MP,
-- .reverse_mac_address = true,
- };
-
- static const struct of_device_id imx_ocotp_dt_ids[] = {
-@@ -624,8 +619,7 @@ static int imx_ocotp_probe(struct platfo
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
-- if (priv->params->reverse_mac_address)
-- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-
- priv->config = &imx_ocotp_nvmem_config;
-
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch b/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch
deleted file mode 100644
index fb4d346a95..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 73bcd133c910bff3b6d3b3834d0d14be9444e90a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 11 Jun 2023 15:03:08 +0100
-Subject: [PATCH] nvmem: brcm_nvram: add .read_post_process() for MACs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Parse ASCII MAC format into byte based
-2. Calculate relative addresses based on index argument
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-5-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 1 +
- drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++
- 2 files changed, 29 insertions(+)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM
- tristate "Broadcom's NVRAM support"
- depends on ARCH_BCM_5301X || COMPILE_TEST
- depends on HAS_IOMEM
-+ select GENERIC_NET_UTILS
- help
- This driver provides support for Broadcom's NVRAM that can be accessed
- using I/O mapping.
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -4,6 +4,8 @@
- */
-
- #include <linux/bcm47xx_nvram.h>
-+#include <linux/etherdevice.h>
-+#include <linux/if_ether.h>
- #include <linux/io.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
-@@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context
- return 0;
- }
-
-+static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index,
-+ unsigned int offset, void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN];
-+
-+ if (bytes != 3 * ETH_ALEN - 1)
-+ return -EINVAL;
-+
-+ if (!mac_pton(buf, mac))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
- static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
- size_t len)
- {
-@@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct b
- priv->cells[idx].offset = value - (char *)data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-+ if (!strcmp(var, "et0macaddr") ||
-+ !strcmp(var, "et1macaddr") ||
-+ !strcmp(var, "et2macaddr")) {
-+ priv->cells[idx].raw_len = strlen(value);
-+ priv->cells[idx].bytes = ETH_ALEN;
-+ priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
-+ }
- }
-
- return 0;
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch b/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch
deleted file mode 100644
index 3b6e6e57f5..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 8dc61364164e79e44c07fa2ac0a7b6939f00d5db Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:13 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Add clks and reg_read to rockchip_data
-
-In preparation to support new Rockchip OTP memory devices with different
-clock configurations and register layout, extend rockchip_data struct
-with the related members: clks, num_clks, reg_read.
-
-Additionally, to avoid managing redundant driver data, drop num_clks
-member from rockchip_otp struct and update all references to point to
-the equivalent member in rockchip_data.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-10-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++--------------
- 1 file changed, 49 insertions(+), 30 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -54,21 +54,19 @@
-
- #define OTPC_TIMEOUT 10000
-
-+struct rockchip_data {
-+ int size;
-+ const char * const *clks;
-+ int num_clks;
-+ nvmem_reg_read_t reg_read;
-+};
-+
- struct rockchip_otp {
- struct device *dev;
- void __iomem *base;
-- struct clk_bulk_data *clks;
-- int num_clks;
-+ struct clk_bulk_data *clks;
- struct reset_control *rst;
--};
--
--/* list of required clocks */
--static const char * const rockchip_otp_clocks[] = {
-- "otp", "apb_pclk", "phy",
--};
--
--struct rockchip_data {
-- int size;
-+ const struct rockchip_data *data;
- };
-
- static int rockchip_otp_reset(struct rockchip_otp *otp)
-@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struc
- return ret;
- }
-
--static int rockchip_otp_read(void *context, unsigned int offset,
-- void *val, size_t bytes)
-+static int px30_otp_read(void *context, unsigned int offset,
-+ void *val, size_t bytes)
- {
- struct rockchip_otp *otp = context;
- u8 *buf = val;
-- int ret = 0;
--
-- ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
-- if (ret < 0) {
-- dev_err(otp->dev, "failed to prepare/enable clks\n");
-- return ret;
-- }
-+ int ret;
-
- ret = rockchip_otp_reset(otp);
- if (ret) {
- dev_err(otp->dev, "failed to reset otp phy\n");
-- goto disable_clks;
-+ return ret;
- }
-
- ret = rockchip_otp_ecc_enable(otp, false);
- if (ret < 0) {
- dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
-- goto disable_clks;
-+ return ret;
- }
-
- writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
-@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *conte
-
- read_end:
- writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
--disable_clks:
-- clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
-+
-+ return ret;
-+}
-+
-+static int rockchip_otp_read(void *context, unsigned int offset,
-+ void *val, size_t bytes)
-+{
-+ struct rockchip_otp *otp = context;
-+ int ret;
-+
-+ if (!otp->data || !otp->data->reg_read)
-+ return -EINVAL;
-+
-+ ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
-+ if (ret < 0) {
-+ dev_err(otp->dev, "failed to prepare/enable clks\n");
-+ return ret;
-+ }
-+
-+ ret = otp->data->reg_read(context, offset, val, bytes);
-+
-+ clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
-
- return ret;
- }
-@@ -189,8 +201,15 @@ static struct nvmem_config otp_config =
- .reg_read = rockchip_otp_read,
- };
-
-+static const char * const px30_otp_clocks[] = {
-+ "otp", "apb_pclk", "phy",
-+};
-+
- static const struct rockchip_data px30_data = {
- .size = 0x40,
-+ .clks = px30_otp_clocks,
-+ .num_clks = ARRAY_SIZE(px30_otp_clocks),
-+ .reg_read = px30_otp_read,
- };
-
- static const struct of_device_id rockchip_otp_match[] = {
-@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct pla
- if (!otp)
- return -ENOMEM;
-
-+ otp->data = data;
- otp->dev = dev;
- otp->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(otp->base))
- return PTR_ERR(otp->base);
-
-- otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks);
-- otp->clks = devm_kcalloc(dev, otp->num_clks,
-- sizeof(*otp->clks), GFP_KERNEL);
-+ otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
-+ GFP_KERNEL);
- if (!otp->clks)
- return -ENOMEM;
-
-- for (i = 0; i < otp->num_clks; ++i)
-- otp->clks[i].id = rockchip_otp_clocks[i];
-+ for (i = 0; i < data->num_clks; ++i)
-+ otp->clks[i].id = data->clks[i];
-
-- ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks);
-+ ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
- if (ret)
- return ret;
-
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch b/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch
deleted file mode 100644
index b5b66cfc5a..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 30fd21cfb1e64ef20035559a8246f5fbf682c40e Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:14 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Generalize rockchip_otp_wait_status()
-
-In preparation to support additional Rockchip OTP memory devices with
-different register layout, generalize rockchip_otp_wait_status() to
-accept a new parameter for specifying the offset of the status register.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-11-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct roc
- return 0;
- }
-
--static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag)
-+static int rockchip_otp_wait_status(struct rockchip_otp *otp,
-+ unsigned int reg, u32 flag)
- {
- u32 status = 0;
- int ret;
-
-- ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status,
-+ ret = readl_poll_timeout_atomic(otp->base + reg, status,
- (status & flag), 1, OTPC_TIMEOUT);
- if (ret)
- return ret;
-
- /* clean int status */
-- writel(flag, otp->base + OTPC_INT_STATUS);
-+ writel(flag, otp->base + reg);
-
- return 0;
- }
-@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struc
-
- writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
-
-- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
-+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE);
- if (ret < 0)
- dev_err(otp->dev, "timeout during ecc_enable\n");
-
-@@ -156,7 +157,7 @@ static int px30_otp_read(void *context,
- otp->base + OTPC_USER_ADDR);
- writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
- otp->base + OTPC_USER_ENABLE);
-- ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
-+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE);
- if (ret < 0) {
- dev_err(otp->dev, "timeout during read setup\n");
- goto read_end;
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch b/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch
deleted file mode 100644
index 3a17479d95..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From d325c9dd2b6e94040ca722ddcadcd6af358dd2be Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:15 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Use
- devm_reset_control_array_get_exclusive()
-
-In preparation to support new Rockchip OTP memory devices having
-specific reset configurations, switch devm_reset_control_get() to
-devm_reset_control_array_get_exclusive().
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-12-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct pla
- if (ret)
- return ret;
-
-- otp->rst = devm_reset_control_get(dev, "phy");
-+ otp->rst = devm_reset_control_array_get_exclusive(dev);
- if (IS_ERR(otp->rst))
- return PTR_ERR(otp->rst);
-
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch b/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch
deleted file mode 100644
index 37cb927b10..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 912517345b867a69542dc9f5c2cc3e9d8beaccf5 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:16 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Improve probe error handling
-
-Enhance error handling in the probe function by making use of
-dev_err_probe(), which ensures the error code is always printed, in
-addition to the specified error message.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-13-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 21 ++++++++++++---------
- 1 file changed, 12 insertions(+), 9 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct pla
- int ret, i;
-
- data = of_device_get_match_data(dev);
-- if (!data) {
-- dev_err(dev, "failed to get match data\n");
-- return -EINVAL;
-- }
-+ if (!data)
-+ return dev_err_probe(dev, -EINVAL, "failed to get match data\n");
-
- otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
- GFP_KERNEL);
-@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct pla
- otp->dev = dev;
- otp->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(otp->base))
-- return PTR_ERR(otp->base);
-+ return dev_err_probe(dev, PTR_ERR(otp->base),
-+ "failed to ioremap resource\n");
-
- otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
- GFP_KERNEL);
-@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct pla
-
- ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
- if (ret)
-- return ret;
-+ return dev_err_probe(dev, ret, "failed to get clocks\n");
-
- otp->rst = devm_reset_control_array_get_exclusive(dev);
- if (IS_ERR(otp->rst))
-- return PTR_ERR(otp->rst);
-+ return dev_err_probe(dev, PTR_ERR(otp->rst),
-+ "failed to get resets\n");
-
- otp_config.size = data->size;
- otp_config.priv = otp;
- otp_config.dev = dev;
-- nvmem = devm_nvmem_register(dev, &otp_config);
-
-- return PTR_ERR_OR_ZERO(nvmem);
-+ nvmem = devm_nvmem_register(dev, &otp_config);
-+ if (IS_ERR(nvmem))
-+ return dev_err_probe(dev, PTR_ERR(nvmem),
-+ "failed to register nvmem device\n");
-+ return 0;
- }
-
- static struct platform_driver rockchip_otp_driver = {
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch b/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch
deleted file mode 100644
index c1e2231c9e..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sun, 11 Jun 2023 15:03:17 +0100
-Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588
-
-Add support for the OTP memory device found on the Rockchip RK3588 SoC.
-
-While here, remove the unnecessary 'void *' casts in the OF device ID
-table.
-
-Co-developed-by: Finley Xiao <finley.xiao@rock-chips.com>
-Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++-
- 1 file changed, 76 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/rockchip-otp.c
-+++ b/drivers/nvmem/rockchip-otp.c
-@@ -54,6 +54,19 @@
-
- #define OTPC_TIMEOUT 10000
-
-+/* RK3588 Register */
-+#define RK3588_OTPC_AUTO_CTRL 0x04
-+#define RK3588_OTPC_AUTO_EN 0x08
-+#define RK3588_OTPC_INT_ST 0x84
-+#define RK3588_OTPC_DOUT0 0x20
-+#define RK3588_NO_SECURE_OFFSET 0x300
-+#define RK3588_NBYTES 4
-+#define RK3588_BURST_NUM 1
-+#define RK3588_BURST_SHIFT 8
-+#define RK3588_ADDR_SHIFT 16
-+#define RK3588_AUTO_EN BIT(0)
-+#define RK3588_RD_DONE BIT(1)
-+
- struct rockchip_data {
- int size;
- const char * const *clks;
-@@ -171,6 +184,52 @@ read_end:
- return ret;
- }
-
-+static int rk3588_otp_read(void *context, unsigned int offset,
-+ void *val, size_t bytes)
-+{
-+ struct rockchip_otp *otp = context;
-+ unsigned int addr_start, addr_end, addr_len;
-+ int ret, i = 0;
-+ u32 data;
-+ u8 *buf;
-+
-+ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
-+ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
-+ addr_len = addr_end - addr_start;
-+ addr_start += RK3588_NO_SECURE_OFFSET;
-+
-+ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ while (addr_len--) {
-+ writel((addr_start << RK3588_ADDR_SHIFT) |
-+ (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
-+ otp->base + RK3588_OTPC_AUTO_CTRL);
-+ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
-+
-+ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
-+ RK3588_RD_DONE);
-+ if (ret < 0) {
-+ dev_err(otp->dev, "timeout during read setup\n");
-+ goto read_end;
-+ }
-+
-+ data = readl(otp->base + RK3588_OTPC_DOUT0);
-+ memcpy(&buf[i], &data, RK3588_NBYTES);
-+
-+ i += RK3588_NBYTES;
-+ addr_start++;
-+ }
-+
-+ memcpy(val, buf + offset % RK3588_NBYTES, bytes);
-+
-+read_end:
-+ kfree(buf);
-+
-+ return ret;
-+}
-+
- static int rockchip_otp_read(void *context, unsigned int offset,
- void *val, size_t bytes)
- {
-@@ -213,14 +272,29 @@ static const struct rockchip_data px30_d
- .reg_read = px30_otp_read,
- };
-
-+static const char * const rk3588_otp_clocks[] = {
-+ "otp", "apb_pclk", "phy", "arb",
-+};
-+
-+static const struct rockchip_data rk3588_data = {
-+ .size = 0x400,
-+ .clks = rk3588_otp_clocks,
-+ .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
-+ .reg_read = rk3588_otp_read,
-+};
-+
- static const struct of_device_id rockchip_otp_match[] = {
- {
- .compatible = "rockchip,px30-otp",
-- .data = (void *)&px30_data,
-+ .data = &px30_data,
- },
- {
- .compatible = "rockchip,rk3308-otp",
-- .data = (void *)&px30_data,
-+ .data = &px30_data,
-+ },
-+ {
-+ .compatible = "rockchip,rk3588-otp",
-+ .data = &rk3588_data,
- },
- { /* sentinel */ },
- };
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch b/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch
deleted file mode 100644
index 220e3e9a05..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 9734408969e978a1c0d5d752be63dd638288e374 Mon Sep 17 00:00:00 2001
-From: Michal Simek <michal.simek@amd.com>
-Date: Sun, 11 Jun 2023 15:03:23 +0100
-Subject: [PATCH] nvmem: zynqmp: Switch @xilinx.com emails to @amd.com
-
-@xilinx.com is still working but better to switch to new amd.com after
-AMD/Xilinx acquisition.
-
-Signed-off-by: Michal Simek <michal.simek@amd.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-20-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/zynqmp_nvmem.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/zynqmp_nvmem.c
-+++ b/drivers/nvmem/zynqmp_nvmem.c
-@@ -76,6 +76,6 @@ static struct platform_driver zynqmp_nvm
-
- module_platform_driver(zynqmp_nvmem_driver);
-
--MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>, Nava kishore Manne <navam@xilinx.com>");
-+MODULE_AUTHOR("Michal Simek <michal.simek@amd.com>, Nava kishore Manne <nava.kishore.manne@amd.com>");
- MODULE_DESCRIPTION("ZynqMP NVMEM driver");
- MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch b/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch
deleted file mode 100644
index f8e6be4241..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-From 22e9e6fcfb5042cb6d6c7874c459b034800092f1 Mon Sep 17 00:00:00 2001
-From: Peng Fan <peng.fan@nxp.com>
-Date: Sun, 11 Jun 2023 15:03:25 +0100
-Subject: [PATCH] nvmem: imx: support i.MX93 OCOTP
-
-Add i.MX93 OCOTP support. i.MX93 OCOTP has two parts: Fuse shadow
-block(fsb) and fuse managed by ELE. The FSB part could be directly
-accessed with MMIO, the ELE could only be accessed with ELE API.
-
-Currently the ELE API is not ready, so NULL function callback is used,
-but it was tested with downstream ELE API.
-
-Signed-off-by: Peng Fan <peng.fan@nxp.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-22-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 9 ++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/imx-ocotp-ele.c | 175 ++++++++++++++++++++++++++++++++++
- 3 files changed, 186 insertions(+)
- create mode 100644 drivers/nvmem/imx-ocotp-ele.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -83,6 +83,15 @@ config NVMEM_IMX_OCOTP
- This driver can also be built as a module. If so, the module
- will be called nvmem-imx-ocotp.
-
-+config NVMEM_IMX_OCOTP_ELE
-+ tristate "i.MX On-Chip OTP Controller support"
-+ depends on ARCH_MXC || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ depends on OF
-+ help
-+ This is a driver for the On-Chip OTP Controller (OCOTP)
-+ available on i.MX SoCs which has ELE.
-+
- config NVMEM_IMX_OCOTP_SCU
- tristate "i.MX8 SCU On-Chip OTP Controller support"
- depends on IMX_SCU
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -18,6 +18,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-im
- nvmem-imx-iim-y := imx-iim.o
- obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o
- nvmem-imx-ocotp-y := imx-ocotp.o
-+obj-$(CONFIG_NVMEM_IMX_OCOTP_ELE) += nvmem-imx-ocotp-ele.o
-+nvmem-imx-ocotp-ele-y := imx-ocotp-ele.o
- obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o
- nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o
- obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o
---- /dev/null
-+++ b/drivers/nvmem/imx-ocotp-ele.c
-@@ -0,0 +1,175 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * i.MX9 OCOTP fusebox driver
-+ *
-+ * Copyright 2023 NXP
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+enum fuse_type {
-+ FUSE_FSB = 1,
-+ FUSE_ELE = 2,
-+ FUSE_INVALID = -1
-+};
-+
-+struct ocotp_map_entry {
-+ u32 start; /* start word */
-+ u32 num; /* num words */
-+ enum fuse_type type;
-+};
-+
-+struct ocotp_devtype_data {
-+ u32 reg_off;
-+ char *name;
-+ u32 size;
-+ u32 num_entry;
-+ u32 flag;
-+ nvmem_reg_read_t reg_read;
-+ struct ocotp_map_entry entry[];
-+};
-+
-+struct imx_ocotp_priv {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct nvmem_config config;
-+ struct mutex lock;
-+ const struct ocotp_devtype_data *data;
-+};
-+
-+static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index)
-+{
-+ struct imx_ocotp_priv *priv = context;
-+ const struct ocotp_devtype_data *data = priv->data;
-+ u32 start, end;
-+ int i;
-+
-+ for (i = 0; i < data->num_entry; i++) {
-+ start = data->entry[i].start;
-+ end = data->entry[i].start + data->entry[i].num;
-+
-+ if (index >= start && index < end)
-+ return data->entry[i].type;
-+ }
-+
-+ return FUSE_INVALID;
-+}
-+
-+static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes)
-+{
-+ struct imx_ocotp_priv *priv = context;
-+ void __iomem *reg = priv->base + priv->data->reg_off;
-+ u32 count, index, num_bytes;
-+ enum fuse_type type;
-+ u32 *buf;
-+ void *p;
-+ int i;
-+
-+ index = offset;
-+ num_bytes = round_up(bytes, 4);
-+ count = num_bytes >> 2;
-+
-+ if (count > ((priv->data->size >> 2) - index))
-+ count = (priv->data->size >> 2) - index;
-+
-+ p = kzalloc(num_bytes, GFP_KERNEL);
-+ if (!p)
-+ return -ENOMEM;
-+
-+ mutex_lock(&priv->lock);
-+
-+ buf = p;
-+
-+ for (i = index; i < (index + count); i++) {
-+ type = imx_ocotp_fuse_type(context, i);
-+ if (type == FUSE_INVALID || type == FUSE_ELE) {
-+ *buf++ = 0;
-+ continue;
-+ }
-+
-+ *buf++ = readl_relaxed(reg + (i << 2));
-+ }
-+
-+ memcpy(val, (u8 *)p, bytes);
-+
-+ mutex_unlock(&priv->lock);
-+
-+ kfree(p);
-+
-+ return 0;
-+};
-+
-+static int imx_ele_ocotp_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct imx_ocotp_priv *priv;
-+ struct nvmem_device *nvmem;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->data = of_device_get_match_data(dev);
-+
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ priv->config.dev = dev;
-+ priv->config.name = "ELE-OCOTP";
-+ priv->config.id = NVMEM_DEVID_AUTO;
-+ priv->config.owner = THIS_MODULE;
-+ priv->config.size = priv->data->size;
-+ priv->config.reg_read = priv->data->reg_read;
-+ priv->config.word_size = 4;
-+ priv->config.stride = 1;
-+ priv->config.priv = priv;
-+ priv->config.read_only = true;
-+ mutex_init(&priv->lock);
-+
-+ nvmem = devm_nvmem_register(dev, &priv->config);
-+ if (IS_ERR(nvmem))
-+ return PTR_ERR(nvmem);
-+
-+ return 0;
-+}
-+
-+static const struct ocotp_devtype_data imx93_ocotp_data = {
-+ .reg_off = 0x8000,
-+ .reg_read = imx_ocotp_reg_read,
-+ .size = 2048,
-+ .num_entry = 6,
-+ .entry = {
-+ { 0, 52, FUSE_FSB },
-+ { 63, 1, FUSE_ELE},
-+ { 128, 16, FUSE_ELE },
-+ { 182, 1, FUSE_ELE },
-+ { 188, 1, FUSE_ELE },
-+ { 312, 200, FUSE_FSB }
-+ },
-+};
-+
-+static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
-+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
-+
-+static struct platform_driver imx_ele_ocotp_driver = {
-+ .driver = {
-+ .name = "imx_ele_ocotp",
-+ .of_match_table = imx_ele_ocotp_dt_ids,
-+ },
-+ .probe = imx_ele_ocotp_probe,
-+};
-+module_platform_driver(imx_ele_ocotp_driver);
-+
-+MODULE_DESCRIPTION("i.MX OCOTP/ELE driver");
-+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch b/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch
deleted file mode 100644
index 59b2f9fa2c..0000000000
--- a/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 27f699e578b1a72df89dfa3bc42e093a01dc8d10 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 11 Jun 2023 15:03:29 +0100
-Subject: [PATCH] nvmem: core: add support for fixed cells *layout*
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds support for the "fixed-layout" NVMEM layout binding. It allows
-defining NVMEM cells in a layout DT node named "nvmem-layout".
-
-While NVMEM subsystem supports layout drivers it has been discussed that
-"fixed-layout" may actually be supperted internally. It's because:
-1. It's a very basic layout
-2. It allows sharing code with legacy syntax parsing
-3. It's safer for soc_device_match() due to -EPROBE_DEFER
-4. This will make the syntax transition easier
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Message-ID: <20230611140330.154222-26-srinivas.kandagatla@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++---
- 1 file changed, 29 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -696,7 +696,7 @@ static int nvmem_validate_keepouts(struc
- return 0;
- }
-
--static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
-+static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
- {
- struct nvmem_layout *layout = nvmem->layout;
- struct device *dev = &nvmem->dev;
-@@ -704,7 +704,7 @@ static int nvmem_add_cells_from_of(struc
- const __be32 *addr;
- int len, ret;
-
-- for_each_child_of_node(dev->of_node, child) {
-+ for_each_child_of_node(np, child) {
- struct nvmem_cell_info info = {0};
-
- addr = of_get_property(child, "reg", &len);
-@@ -742,6 +742,28 @@ static int nvmem_add_cells_from_of(struc
- return 0;
- }
-
-+static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem)
-+{
-+ return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node);
-+}
-+
-+static int nvmem_add_cells_from_fixed_layout(struct nvmem_device *nvmem)
-+{
-+ struct device_node *layout_np;
-+ int err = 0;
-+
-+ layout_np = of_nvmem_layout_get_container(nvmem);
-+ if (!layout_np)
-+ return 0;
-+
-+ if (of_device_is_compatible(layout_np, "fixed-layout"))
-+ err = nvmem_add_cells_from_dt(nvmem, layout_np);
-+
-+ of_node_put(layout_np);
-+
-+ return err;
-+}
-+
- int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
- {
- layout->owner = owner;
-@@ -972,7 +994,7 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_of(nvmem);
-+ rval = nvmem_add_cells_from_legacy_of(nvmem);
- if (rval)
- goto err_remove_cells;
-
-@@ -982,6 +1004,10 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-+ rval = nvmem_add_cells_from_fixed_layout(nvmem);
-+ if (rval)
-+ goto err_remove_cells;
-+
- rval = nvmem_add_cells_from_layout(nvmem);
- if (rval)
- goto err_remove_cells;
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch b/target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch
deleted file mode 100644
index bf7a816bb2..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 9ccfcbeb8f32ff89e99b36cb9cdebaa0d1b44ed1 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:24 +0100
-Subject: [PATCH] nvmem: sunxi_sid: Convert to devm_platform_ioremap_resource()
-
-Use devm_platform_ioremap_resource() to simplify code.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/sunxi_sid.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/sunxi_sid.c
-+++ b/drivers/nvmem/sunxi_sid.c
-@@ -125,7 +125,6 @@ static int sun8i_sid_read_by_reg(void *c
- static int sunxi_sid_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-- struct resource *res;
- struct nvmem_config *nvmem_cfg;
- struct nvmem_device *nvmem;
- struct sunxi_sid *sid;
-@@ -142,8 +141,7 @@ static int sunxi_sid_probe(struct platfo
- return -EINVAL;
- sid->value_offset = cfg->value_offset;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- sid->base = devm_ioremap_resource(dev, res);
-+ sid->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(sid->base))
- return PTR_ERR(sid->base);
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch b/target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch
deleted file mode 100644
index f142d735de..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From cfadd0e7d9225566f320bc4dc716682be910be6c Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:25 +0100
-Subject: [PATCH] nvmem: brcm_nvram: Use
- devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -159,8 +159,7 @@ static int brcm_nvram_probe(struct platf
- return -ENOMEM;
- priv->dev = dev;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch b/target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch
deleted file mode 100644
index 0395bbf8bc..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 0b49178e2b6b4aac3c7fa3ce8d8c02208a13b988 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:26 +0100
-Subject: [PATCH] nvmem: lpc18xx_otp: Convert to
- devm_platform_ioremap_resource()
-
-Use devm_platform_ioremap_resource() to simplify code.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-5-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/lpc18xx_otp.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/lpc18xx_otp.c
-+++ b/drivers/nvmem/lpc18xx_otp.c
-@@ -68,14 +68,12 @@ static int lpc18xx_otp_probe(struct plat
- {
- struct nvmem_device *nvmem;
- struct lpc18xx_otp *otp;
-- struct resource *res;
-
- otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL);
- if (!otp)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- otp->base = devm_ioremap_resource(&pdev->dev, res);
-+ otp->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(otp->base))
- return PTR_ERR(otp->base);
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch b/target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch
deleted file mode 100644
index da077eb4b7..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0a223a097709b99a0ba738d6be5b4f52c04ffb64 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:27 +0100
-Subject: [PATCH] nvmem: meson-mx-efuse: Convert to
- devm_platform_ioremap_resource()
-
-Use devm_platform_ioremap_resource() to simplify code.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/meson-mx-efuse.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/nvmem/meson-mx-efuse.c
-+++ b/drivers/nvmem/meson-mx-efuse.c
-@@ -194,7 +194,6 @@ static int meson_mx_efuse_probe(struct p
- {
- const struct meson_mx_efuse_platform_data *drvdata;
- struct meson_mx_efuse *efuse;
-- struct resource *res;
-
- drvdata = of_device_get_match_data(&pdev->dev);
- if (!drvdata)
-@@ -204,8 +203,7 @@ static int meson_mx_efuse_probe(struct p
- if (!efuse)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- efuse->base = devm_ioremap_resource(&pdev->dev, res);
-+ efuse->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(efuse->base))
- return PTR_ERR(efuse->base);
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch b/target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch
deleted file mode 100644
index dc144ddfbd..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 94904db28db49ac8fbb2a273d25156db26a3a985 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:28 +0100
-Subject: [PATCH] nvmem: rockchip-efuse: Use
- devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/rockchip-efuse.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/rockchip-efuse.c
-+++ b/drivers/nvmem/rockchip-efuse.c
-@@ -267,8 +267,7 @@ static int rockchip_efuse_probe(struct p
- if (!efuse)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- efuse->base = devm_ioremap_resource(dev, res);
-+ efuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(efuse->base))
- return PTR_ERR(efuse->base);
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch
deleted file mode 100644
index 99e20939cc..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0a4a8c0d238fec1fa4b85591524ef42ad261cb97 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:29 +0100
-Subject: [PATCH] nvmem: stm32-romem: Use
- devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -196,8 +196,7 @@ static int stm32_romem_probe(struct plat
- if (!priv)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch b/target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch
deleted file mode 100644
index 6d93752e27..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 0bc0d6dc2a9a05ae6729b4622f09782d9f230815 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:30 +0100
-Subject: [PATCH] nvmem: qfprom: do some cleanup
-
-Use devm_platform_ioremap_resource() and
-devm_platform_get_and_ioremap_resource() to simplify code.
-BTW convert to use dev_err_probe() instead of open it.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qfprom.c | 17 +++++------------
- 1 file changed, 5 insertions(+), 12 deletions(-)
-
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -374,8 +374,7 @@ static int qfprom_probe(struct platform_
- return -ENOMEM;
-
- /* The corrected section is always provided */
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->qfpcorrected = devm_ioremap_resource(dev, res);
-+ priv->qfpcorrected = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->qfpcorrected))
- return PTR_ERR(priv->qfpcorrected);
-
-@@ -402,12 +401,10 @@ static int qfprom_probe(struct platform_
- priv->qfpraw = devm_ioremap_resource(dev, res);
- if (IS_ERR(priv->qfpraw))
- return PTR_ERR(priv->qfpraw);
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
-- priv->qfpconf = devm_ioremap_resource(dev, res);
-+ priv->qfpconf = devm_platform_ioremap_resource(pdev, 2);
- if (IS_ERR(priv->qfpconf))
- return PTR_ERR(priv->qfpconf);
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
-- priv->qfpsecurity = devm_ioremap_resource(dev, res);
-+ priv->qfpsecurity = devm_platform_ioremap_resource(pdev, 3);
- if (IS_ERR(priv->qfpsecurity))
- return PTR_ERR(priv->qfpsecurity);
-
-@@ -427,12 +424,8 @@ static int qfprom_probe(struct platform_
- return PTR_ERR(priv->vcc);
-
- priv->secclk = devm_clk_get(dev, "core");
-- if (IS_ERR(priv->secclk)) {
-- ret = PTR_ERR(priv->secclk);
-- if (ret != -EPROBE_DEFER)
-- dev_err(dev, "Error getting clock: %d\n", ret);
-- return ret;
-- }
-+ if (IS_ERR(priv->secclk))
-+ return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n");
-
- /* Only enable writing if we have SoC data. */
- if (priv->soc_data)
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch b/target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch
deleted file mode 100644
index 3e328a4c99..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 6ac41c556e22a0d7d267c9b9d48681d73af4b368 Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Wed, 23 Aug 2023 14:27:31 +0100
-Subject: [PATCH] nvmem: uniphier: Use devm_platform_get_and_ioremap_resource()
-
-Convert platform_get_resource(), devm_ioremap_resource() to a single
-call to devm_platform_get_and_ioremap_resource(), as this is exactly
-what this function does.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230823132744.350618-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/uniphier-efuse.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/nvmem/uniphier-efuse.c
-+++ b/drivers/nvmem/uniphier-efuse.c
-@@ -41,8 +41,7 @@ static int uniphier_efuse_probe(struct p
- if (!priv)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- priv->base = devm_ioremap_resource(dev, res);
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch b/target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch
deleted file mode 100644
index acbe18e270..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From c8efcf7a86ebf2ff48584d270b3070a7075bc345 Mon Sep 17 00:00:00 2001
-From: Richard Alpe <richard@bit42.se>
-Date: Mon, 10 Apr 2023 10:20:51 +0200
-Subject: [PATCH] nvmem: add new NXP QorIQ eFuse driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add SFP (Security Fuse Processor) read support for NXP (Freescale)
-QorIQ series SOC's.
-
-This patch adds support for the T1023 SOC using the SFP offset from
-the existing T1023 device tree. In theory this should also work for
-T1024, T1014 and T1013 which uses the same SFP base offset.
-
-Signed-off-by: Richard Alpe <richard@bit42.se>
-Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/Kconfig | 12 ++++++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/qoriq-efuse.c | 78 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 92 insertions(+)
- create mode 100644 drivers/nvmem/qoriq-efuse.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -392,4 +392,16 @@ config NVMEM_ZYNQMP
-
- If sure, say yes. If unsure, say no.
-
-+config NVMEM_QORIQ_EFUSE
-+ tristate "NXP QorIQ eFuse support"
-+ depends on PPC_85xx || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ This driver provides read support for the eFuses (SFP) on NXP QorIQ
-+ series SoC's. This includes secure boot settings, the globally unique
-+ NXP ID 'FUIDR' and the OEM unique ID 'OUIDR'.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called nvmem_qoriq_efuse.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -77,3 +77,5 @@ obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvme
- nvmem-vf610-ocotp-y := vf610-ocotp.o
- obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
- nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
-+obj-$(CONFIG_NVMEM_QORIQ_EFUSE) += nvmem-qoriq-efuse.o
-+nvmem-qoriq-efuse-y := qoriq-efuse.o
---- /dev/null
-+++ b/drivers/nvmem/qoriq-efuse.c
-@@ -0,0 +1,78 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2023 Westermo Network Technologies AB
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/platform_device.h>
-+
-+struct qoriq_efuse_priv {
-+ void __iomem *base;
-+};
-+
-+static int qoriq_efuse_read(void *context, unsigned int offset, void *val,
-+ size_t bytes)
-+{
-+ struct qoriq_efuse_priv *priv = context;
-+
-+ /* .stride = 4 so offset is guaranteed to be aligned */
-+ __ioread32_copy(val, priv->base + offset, bytes / 4);
-+
-+ /* Ignore trailing bytes (there shouldn't be any) */
-+
-+ return 0;
-+}
-+
-+static int qoriq_efuse_probe(struct platform_device *pdev)
-+{
-+ struct nvmem_config config = {
-+ .dev = &pdev->dev,
-+ .read_only = true,
-+ .reg_read = qoriq_efuse_read,
-+ .stride = sizeof(u32),
-+ .word_size = sizeof(u32),
-+ .name = "qoriq_efuse_read",
-+ .id = NVMEM_DEVID_AUTO,
-+ .root_only = true,
-+ };
-+ struct qoriq_efuse_priv *priv;
-+ struct nvmem_device *nvmem;
-+ struct resource *res;
-+
-+ priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ config.size = resource_size(res);
-+ config.priv = priv;
-+ nvmem = devm_nvmem_register(config.dev, &config);
-+
-+ return PTR_ERR_OR_ZERO(nvmem);
-+}
-+
-+static const struct of_device_id qoriq_efuse_of_match[] = {
-+ { .compatible = "fsl,t1023-sfp", },
-+ {/* sentinel */},
-+};
-+MODULE_DEVICE_TABLE(of, qoriq_efuse_of_match);
-+
-+static struct platform_driver qoriq_efuse_driver = {
-+ .probe = qoriq_efuse_probe,
-+ .driver = {
-+ .name = "qoriq-efuse",
-+ .of_match_table = qoriq_efuse_of_match,
-+ },
-+};
-+module_platform_driver(qoriq_efuse_driver);
-+
-+MODULE_AUTHOR("Richard Alpe <richard.alpe@bit42.se>");
-+MODULE_DESCRIPTION("NXP QorIQ Security Fuse Processor (SFP) Reader");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch b/target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch
deleted file mode 100644
index 67f30e34a2..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 9d53d595f688c9837e88a919229cc61a165c7b9e Mon Sep 17 00:00:00 2001
-From: Diederik de Haas <didi.debian@cknow.org>
-Date: Mon, 24 Jul 2023 13:36:22 +0200
-Subject: [PATCH] nvmem: Kconfig: Fix typo "drive" -> "driver"
-
-Fix typo where "driver" was meant instead of "drive".
-While at it, also capitalize "OTP".
-
-Signed-off-by: Diederik de Haas <didi.debian@cknow.org>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/Kconfig | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -247,7 +247,7 @@ config NVMEM_ROCKCHIP_EFUSE
- depends on ARCH_ROCKCHIP || COMPILE_TEST
- depends on HAS_IOMEM
- help
-- This is a simple drive to dump specified values of Rockchip SoC
-+ This is a simple driver to dump specified values of Rockchip SoC
- from eFuse, such as cpu-leakage.
-
- This driver can also be built as a module. If so, the module
-@@ -258,8 +258,8 @@ config NVMEM_ROCKCHIP_OTP
- depends on ARCH_ROCKCHIP || COMPILE_TEST
- depends on HAS_IOMEM
- help
-- This is a simple drive to dump specified values of Rockchip SoC
-- from otp, such as cpu-leakage.
-+ This is a simple driver to dump specified values of Rockchip SoC
-+ from OTP, such as cpu-leakage.
-
- This driver can also be built as a module. If so, the module
- will be called nvmem_rockchip_otp.
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch b/target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch
deleted file mode 100644
index af4a2926dc..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 0a9ec38c47c1ca4528aa058e2b9ea61901a7e632 Mon Sep 17 00:00:00 2001
-From: Komal Bajaj <quic_kbajaj@quicinc.com>
-Date: Tue, 1 Aug 2023 12:10:25 +0530
-Subject: [PATCH] nvmem: sec-qfprom: Add Qualcomm secure QFPROM support
-
-For some of the Qualcomm SoC's, it is possible that
-some of the fuse regions or entire qfprom region is
-protected from non-secure access. In such situations,
-the OS will have to use secure calls to read the region.
-With that motivation, add secure qfprom driver.
-
-Signed-off-by: Komal Bajaj <quic_kbajaj@quicinc.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/Kconfig | 13 ++++++
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/sec-qfprom.c | 96 ++++++++++++++++++++++++++++++++++++++
- 3 files changed, 111 insertions(+)
- create mode 100644 drivers/nvmem/sec-qfprom.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -226,6 +226,19 @@ config NVMEM_QCOM_QFPROM
- This driver can also be built as a module. If so, the module
- will be called nvmem_qfprom.
-
-+config NVMEM_QCOM_SEC_QFPROM
-+ tristate "QCOM SECURE QFPROM Support"
-+ depends on ARCH_QCOM || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ depends on OF
-+ select QCOM_SCM
-+ help
-+ Say y here to enable secure QFPROM support. The secure QFPROM provides access
-+ functions for QFPROM data to rest of the drivers via nvmem interface.
-+
-+ This driver can also be built as a module. If so, the module will be called
-+ nvmem_sec_qfprom.
-+
- config NVMEM_RAVE_SP_EEPROM
- tristate "Rave SP EEPROM Support"
- depends on RAVE_SP_CORE
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -46,6 +46,8 @@ obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvme
- nvmem-nintendo-otp-y := nintendo-otp.o
- obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o
- nvmem_qfprom-y := qfprom.o
-+obj-$(CONFIG_NVMEM_QCOM_SEC_QFPROM) += nvmem_sec_qfprom.o
-+nvmem_sec_qfprom-y := sec-qfprom.o
- obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
- nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
- obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
---- /dev/null
-+++ b/drivers/nvmem/sec-qfprom.c
-@@ -0,0 +1,96 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#include <linux/qcom_scm.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+
-+/**
-+ * struct sec_qfprom - structure holding secure qfprom attributes
-+ *
-+ * @base: starting physical address for secure qfprom corrected address space.
-+ * @dev: qfprom device structure.
-+ */
-+struct sec_qfprom {
-+ phys_addr_t base;
-+ struct device *dev;
-+};
-+
-+static int sec_qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes)
-+{
-+ struct sec_qfprom *priv = context;
-+ unsigned int i;
-+ u8 *val = _val;
-+ u32 read_val;
-+ u8 *tmp;
-+
-+ for (i = 0; i < bytes; i++, reg++) {
-+ if (i == 0 || reg % 4 == 0) {
-+ if (qcom_scm_io_readl(priv->base + (reg & ~3), &read_val)) {
-+ dev_err(priv->dev, "Couldn't access fuse register\n");
-+ return -EINVAL;
-+ }
-+ tmp = (u8 *)&read_val;
-+ }
-+
-+ val[i] = tmp[reg & 3];
-+ }
-+
-+ return 0;
-+}
-+
-+static int sec_qfprom_probe(struct platform_device *pdev)
-+{
-+ struct nvmem_config econfig = {
-+ .name = "sec-qfprom",
-+ .stride = 1,
-+ .word_size = 1,
-+ .id = NVMEM_DEVID_AUTO,
-+ .reg_read = sec_qfprom_reg_read,
-+ };
-+ struct device *dev = &pdev->dev;
-+ struct nvmem_device *nvmem;
-+ struct sec_qfprom *priv;
-+ struct resource *res;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res)
-+ return -EINVAL;
-+
-+ priv->base = res->start;
-+
-+ econfig.size = resource_size(res);
-+ econfig.dev = dev;
-+ econfig.priv = priv;
-+
-+ priv->dev = dev;
-+
-+ nvmem = devm_nvmem_register(dev, &econfig);
-+
-+ return PTR_ERR_OR_ZERO(nvmem);
-+}
-+
-+static const struct of_device_id sec_qfprom_of_match[] = {
-+ { .compatible = "qcom,sec-qfprom" },
-+ {/* sentinel */},
-+};
-+MODULE_DEVICE_TABLE(of, sec_qfprom_of_match);
-+
-+static struct platform_driver qfprom_driver = {
-+ .probe = sec_qfprom_probe,
-+ .driver = {
-+ .name = "qcom_sec_qfprom",
-+ .of_match_table = sec_qfprom_of_match,
-+ },
-+};
-+module_platform_driver(qfprom_driver);
-+MODULE_DESCRIPTION("Qualcomm Secure QFPROM driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch b/target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch
deleted file mode 100644
index dab8ec2c24..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From c32f2186acc9abb4d766361255d7ddf07d15eeb2 Mon Sep 17 00:00:00 2001
-From: Atul Raut <rauji.raut@gmail.com>
-Date: Sun, 30 Jul 2023 15:39:15 -0700
-Subject: [PATCH] nvmem: u-boot-env:: Replace zero-length array with
- DECLARE_FLEX_ARRAY() helper
-
-We are moving toward replacing zero-length arrays with C99 flexible-array
-members since they are deprecated. Therefore, the new DECLARE_FLEX_ARRAY()
-helper macro should be used to replace the zero-length array declaration.
-
-This fixes warnings such as:
-./drivers/nvmem/u-boot-env.c:50:9-13: WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)
-
-Signed-off-by: Atul Raut <rauji.raut@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -47,7 +47,7 @@ struct u_boot_env_image_broadcom {
- __le32 magic;
- __le32 len;
- __le32 crc32;
-- uint8_t data[0];
-+ DECLARE_FLEX_ARRAY(uint8_t, data);
- } __packed;
-
- static int u_boot_env_read(void *context, unsigned int offset, void *val,
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch b/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch
deleted file mode 100644
index f9532f39c3..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 104af6a5b199eb4dc7970d1304aef38ac5a6ed54 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:26 +0200
-Subject: [PATCH] nvmem: core: Create all cells before adding the nvmem device
-
-Let's pack all the cells creation in one place, so they are all created
-before we add the nvmem device.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/core.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -998,17 +998,17 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
--
-- rval = device_add(&nvmem->dev);
-+ rval = nvmem_add_cells_from_fixed_layout(nvmem);
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_fixed_layout(nvmem);
-+ rval = nvmem_add_cells_from_layout(nvmem);
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_layout(nvmem);
-+ dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
-+
-+ rval = device_add(&nvmem->dev);
- if (rval)
- goto err_remove_cells;
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch b/target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch
deleted file mode 100644
index 8f64d0c28b..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 6c7f48ea2e663b679aa8e60d8d8e1e6306a644f9 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:27 +0200
-Subject: [PATCH] nvmem: core: Return NULL when no nvmem layout is found
-
-Currently, of_nvmem_layout_get_container() returns NULL on error, or an
-error pointer if either CONFIG_NVMEM or CONFIG_OF is turned off. We
-should likely avoid this kind of mix for two reasons: to clarify the
-intend and anyway fix the !CONFIG_OF which will likely always if we use
-this helper somewhere else. Let's just return NULL when no layout is
-found, we don't need an error value here.
-
-Link: https://staticthinking.wordpress.com/2022/08/01/mixing-error-pointers-and-null/
-Fixes: 266570f496b9 ("nvmem: core: introduce NVMEM layouts")
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
-Closes: https://lore.kernel.org/r/202308030002.DnSFOrMB-lkp@intel.com/
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- include/linux/nvmem-consumer.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -256,7 +256,7 @@ static inline struct nvmem_device *of_nv
- static inline struct device_node *
- of_nvmem_layout_get_container(struct nvmem_device *nvmem)
- {
-- return ERR_PTR(-EOPNOTSUPP);
-+ return NULL;
- }
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch b/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch
deleted file mode 100644
index 28d8bba194..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From b8257f61b4ddac6d7d0e19a5a4e8b07afb3b4ed3 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:28 +0200
-Subject: [PATCH] nvmem: core: Do not open-code existing functions
-
-Use of_nvmem_layout_get_container() instead of hardcoding it.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -786,10 +786,10 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
-
- static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
- {
-- struct device_node *layout_np, *np = nvmem->dev.of_node;
-+ struct device_node *layout_np;
- struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
-
-- layout_np = of_get_child_by_name(np, "nvmem-layout");
-+ layout_np = of_nvmem_layout_get_container(nvmem);
- if (!layout_np)
- return NULL;
-
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch b/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch
deleted file mode 100644
index b62a0e18da..0000000000
--- a/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0991afbe4b1805e7f0113ef10d7c5f0698a739e4 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 8 Aug 2023 08:29:29 +0200
-Subject: [PATCH] nvmem: core: Notify when a new layout is registered
-
-Tell listeners a new layout was introduced and is now available.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/core.c | 4 ++++
- include/linux/nvmem-consumer.h | 2 ++
- 2 files changed, 6 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -772,12 +772,16 @@ int __nvmem_layout_register(struct nvmem
- list_add(&layout->node, &nvmem_layouts);
- spin_unlock(&nvmem_layout_lock);
-
-+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout);
-+
- return 0;
- }
- EXPORT_SYMBOL_GPL(__nvmem_layout_register);
-
- void nvmem_layout_unregister(struct nvmem_layout *layout)
- {
-+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout);
-+
- spin_lock(&nvmem_layout_lock);
- list_del(&layout->node);
- spin_unlock(&nvmem_layout_lock);
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -43,6 +43,8 @@ enum {
- NVMEM_REMOVE,
- NVMEM_CELL_ADD,
- NVMEM_CELL_REMOVE,
-+ NVMEM_LAYOUT_ADD,
-+ NVMEM_LAYOUT_REMOVE,
- };
-
- #if IS_ENABLED(CONFIG_NVMEM)
diff --git a/target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch b/target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch
deleted file mode 100644
index e17be439b2..0000000000
--- a/target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From a75b58a46423cfd9b1f73581f4bd2ac2ae743996 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Wed, 2 Aug 2023 18:07:45 +0200
-Subject: [PATCH 1/6] leds: turris-omnia: Use sysfs_emit() instead of sprintf()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use the dedicated sysfs_emit() function instead of sprintf() in sysfs
-attribute accessor brightness_show().
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230802160748.11208-4-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/leds-turris-omnia.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -194,7 +194,7 @@ static ssize_t brightness_show(struct de
- if (ret < 0)
- return ret;
-
-- return sprintf(buf, "%d\n", ret);
-+ return sysfs_emit(buf, "%d\n", ret);
- }
-
- static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
diff --git a/target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch b/target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch
deleted file mode 100644
index d84ad67125..0000000000
--- a/target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch
+++ /dev/null
@@ -1,207 +0,0 @@
-From a64c3c1357275b1fd61bc9734f638cdb5d8a8bbb Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 18 Sep 2023 18:11:02 +0200
-Subject: [PATCH 4/6] leds: turris-omnia: Make set_brightness() more efficient
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Implement caching of the LED color and state values that are sent to MCU
-in order to make the set_brightness() operation more efficient by
-avoiding I2C transactions which are not needed.
-
-On Turris Omnia's MCU, which acts as the RGB LED controller, each LED
-has a RGB color, and a ON/OFF state, which are configurable via I2C
-commands CMD_LED_COLOR and CMD_LED_STATE.
-
-The CMD_LED_COLOR command sends 5 bytes and the CMD_LED_STATE command 2
-bytes over the I2C bus, which operates at 100 kHz. With I2C overhead
-this allows ~1670 color changing commands and ~3200 state changing
-commands per second (or around 1000 color + state changes per second).
-This may seem more than enough, but the issue is that the I2C bus is
-shared with another peripheral, the MCU. The MCU exposes an interrupt
-interface, and it can trigger hundreds of interrupts per second. Each
-time, we need to read the interrupt state register over this I2C bus.
-Whenever we are sending a LED color/state changing command, the
-interrupt reading is waiting.
-
-Currently, every time LED brightness or LED multi intensity is changed,
-we send a CMD_LED_STATE command, and if the computed color (brightness
-adjusted multi_intensity) is non-zero, we also send a CMD_LED_COLOR
-command.
-
-Consider for example the situation when we have a netdev trigger enabled
-for a LED. The netdev trigger does not change the LED color, only the
-brightness (either to 0 or to currently configured brightness), and so
-there is no need to send the CMD_LED_COLOR command. But each change of
-brightness to 0 sends one CMD_LED_STATE command, and each change of
-brightness to max_brightness sends one CMD_LED_STATE command and one
-CMD_LED_COLOR command:
- set_brightness(0) -> CMD_LED_STATE
- set_brightness(255) -> CMD_LED_STATE + CMD_LED_COLOR
- (unnecessary)
-
-We can avoid the unnecessary I2C transactions if we cache the values of
-state and color that are sent to the controller. If the color does not
-change from the one previously sent, there is no need to do the
-CMD_LED_COLOR I2C transaction, and if the state does not change, there
-is no need to do the CMD_LED_STATE transaction.
-
-Because we need to make sure that our cached values are consistent with
-the controller state, add explicit setting of the LED color to white at
-probe time (this is the default setting when MCU resets, but does not
-necessarily need to be the case, for example if U-Boot played with the
-LED colors).
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230918161104.20860-3-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/leds-turris-omnia.c | 96 ++++++++++++++++++++++++++------
- 1 file changed, 78 insertions(+), 18 deletions(-)
-
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -30,6 +30,8 @@
- struct omnia_led {
- struct led_classdev_mc mc_cdev;
- struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS];
-+ u8 cached_channels[OMNIA_LED_NUM_CHANNELS];
-+ bool on;
- int reg;
- };
-
-@@ -72,36 +74,82 @@ static int omnia_cmd_read_u8(const struc
- return -EIO;
- }
-
-+static int omnia_led_send_color_cmd(const struct i2c_client *client,
-+ struct omnia_led *led)
-+{
-+ char cmd[5];
-+ int ret;
-+
-+ cmd[0] = CMD_LED_COLOR;
-+ cmd[1] = led->reg;
-+ cmd[2] = led->subled_info[0].brightness;
-+ cmd[3] = led->subled_info[1].brightness;
-+ cmd[4] = led->subled_info[2].brightness;
-+
-+ /* Send the color change command */
-+ ret = i2c_master_send(client, cmd, 5);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Cache the RGB channel brightnesses */
-+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i)
-+ led->cached_channels[i] = led->subled_info[i].brightness;
-+
-+ return 0;
-+}
-+
-+/* Determine if the computed RGB channels are different from the cached ones */
-+static bool omnia_led_channels_changed(struct omnia_led *led)
-+{
-+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i)
-+ if (led->subled_info[i].brightness != led->cached_channels[i])
-+ return true;
-+
-+ return false;
-+}
-+
- static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
- enum led_brightness brightness)
- {
- struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
- struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
- struct omnia_led *led = to_omnia_led(mc_cdev);
-- u8 buf[5], state;
-- int ret;
-+ int err = 0;
-
- mutex_lock(&leds->lock);
-
-- led_mc_calc_color_components(&led->mc_cdev, brightness);
-+ /*
-+ * Only recalculate RGB brightnesses from intensities if brightness is
-+ * non-zero. Otherwise we won't be using them and we can save ourselves
-+ * some software divisions (Omnia's CPU does not implement the division
-+ * instruction).
-+ */
-+ if (brightness) {
-+ led_mc_calc_color_components(mc_cdev, brightness);
-+
-+ /*
-+ * Send color command only if brightness is non-zero and the RGB
-+ * channel brightnesses changed.
-+ */
-+ if (omnia_led_channels_changed(led))
-+ err = omnia_led_send_color_cmd(leds->client, led);
-+ }
-
-- buf[0] = CMD_LED_COLOR;
-- buf[1] = led->reg;
-- buf[2] = mc_cdev->subled_info[0].brightness;
-- buf[3] = mc_cdev->subled_info[1].brightness;
-- buf[4] = mc_cdev->subled_info[2].brightness;
--
-- state = CMD_LED_STATE_LED(led->reg);
-- if (buf[2] || buf[3] || buf[4])
-- state |= CMD_LED_STATE_ON;
--
-- ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
-- if (ret >= 0 && (state & CMD_LED_STATE_ON))
-- ret = i2c_master_send(leds->client, buf, 5);
-+ /* Send on/off state change only if (bool)brightness changed */
-+ if (!err && !brightness != !led->on) {
-+ u8 state = CMD_LED_STATE_LED(led->reg);
-+
-+ if (brightness)
-+ state |= CMD_LED_STATE_ON;
-+
-+ err = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
-+ if (!err)
-+ led->on = !!brightness;
-+ }
-
- mutex_unlock(&leds->lock);
-
-- return ret;
-+ return err;
- }
-
- static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
-@@ -129,11 +177,15 @@ static int omnia_led_register(struct i2c
- }
-
- led->subled_info[0].color_index = LED_COLOR_ID_RED;
-- led->subled_info[0].channel = 0;
- led->subled_info[1].color_index = LED_COLOR_ID_GREEN;
-- led->subled_info[1].channel = 1;
- led->subled_info[2].color_index = LED_COLOR_ID_BLUE;
-- led->subled_info[2].channel = 2;
-+
-+ /* Initial color is white */
-+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) {
-+ led->subled_info[i].intensity = 255;
-+ led->subled_info[i].brightness = 255;
-+ led->subled_info[i].channel = i;
-+ }
-
- led->mc_cdev.subled_info = led->subled_info;
- led->mc_cdev.num_colors = OMNIA_LED_NUM_CHANNELS;
-@@ -162,6 +214,14 @@ static int omnia_led_register(struct i2c
- return ret;
- }
-
-+ /* Set initial color and cache it */
-+ ret = omnia_led_send_color_cmd(client, led);
-+ if (ret < 0) {
-+ dev_err(dev, "Cannot set LED %pOF initial color: %i\n", np,
-+ ret);
-+ return ret;
-+ }
-+
- ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev,
- &init_data);
- if (ret < 0) {
diff --git a/target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch b/target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch
deleted file mode 100644
index 00773ab0f6..0000000000
--- a/target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From e965e0f6de60874fc0a0caed9a9e0122999e0c7b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 18 Sep 2023 18:11:03 +0200
-Subject: [PATCH 5/6] leds: turris-omnia: Support HW controlled mode via
- private trigger
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support for enabling MCU controlled mode of the Turris Omnia LEDs
-via a LED private trigger called "omnia-mcu". Recall that private LED
-triggers will only be listed in the sysfs trigger file for LEDs that
-support them (currently there is no user of this mechanism).
-
-When in MCU controlled mode, the user can still set LED color, but the
-blinking is done by MCU, which does different things for different LEDs:
-- WAN LED is blinked according to the LED[0] pin of the WAN PHY
-- LAN LEDs are blinked according to the LED[0] output of the
- corresponding port of the LAN switch
-- PCIe LEDs are blinked according to the logical OR of the MiniPCIe port
- LED pins
-
-In the future I want to make the netdev trigger to transparently offload
-the blinking to the HW if user sets compatible settings for the netdev
-trigger (for LEDs associated with network devices).
-There was some work on this already, and hopefully we will be able to
-complete it sometime, but for now there are still multiple blockers for
-this, and even if there weren't, we still would not be able to configure
-HW controlled mode for the LEDs associated with MiniPCIe ports.
-
-In the meantime let's support HW controlled mode via the private LED
-trigger mechanism. If, in the future, we manage to complete the netdev
-trigger offloading, we can still keep this private trigger for backwards
-compatibility, if needed.
-
-We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps
-control until the user first wants to take over it. If a different
-default trigger is specified in device-tree via the
-'linux,default-trigger' property, LED class will overwrite
-cdev->default_trigger, and so the DT property will be respected.
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230918161104.20860-4-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/Kconfig | 1 +
- drivers/leds/leds-turris-omnia.c | 98 +++++++++++++++++++++++++++++---
- 2 files changed, 91 insertions(+), 8 deletions(-)
-
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -164,6 +164,7 @@ config LEDS_TURRIS_OMNIA
- depends on I2C
- depends on MACH_ARMADA_38X || COMPILE_TEST
- depends on OF
-+ select LEDS_TRIGGERS
- help
- This option enables basic support for the LEDs found on the front
- side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -31,7 +31,7 @@ struct omnia_led {
- struct led_classdev_mc mc_cdev;
- struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS];
- u8 cached_channels[OMNIA_LED_NUM_CHANNELS];
-- bool on;
-+ bool on, hwtrig;
- int reg;
- };
-
-@@ -120,12 +120,14 @@ static int omnia_led_brightness_set_bloc
-
- /*
- * Only recalculate RGB brightnesses from intensities if brightness is
-- * non-zero. Otherwise we won't be using them and we can save ourselves
-- * some software divisions (Omnia's CPU does not implement the division
-- * instruction).
-+ * non-zero (if it is zero and the LED is in HW blinking mode, we use
-+ * max_brightness as brightness). Otherwise we won't be using them and
-+ * we can save ourselves some software divisions (Omnia's CPU does not
-+ * implement the division instruction).
- */
-- if (brightness) {
-- led_mc_calc_color_components(mc_cdev, brightness);
-+ if (brightness || led->hwtrig) {
-+ led_mc_calc_color_components(mc_cdev, brightness ?:
-+ cdev->max_brightness);
-
- /*
- * Send color command only if brightness is non-zero and the RGB
-@@ -135,8 +137,11 @@ static int omnia_led_brightness_set_bloc
- err = omnia_led_send_color_cmd(leds->client, led);
- }
-
-- /* Send on/off state change only if (bool)brightness changed */
-- if (!err && !brightness != !led->on) {
-+ /*
-+ * Send on/off state change only if (bool)brightness changed and the LED
-+ * is not being blinked by HW.
-+ */
-+ if (!err && !led->hwtrig && !brightness != !led->on) {
- u8 state = CMD_LED_STATE_LED(led->reg);
-
- if (brightness)
-@@ -152,6 +157,71 @@ static int omnia_led_brightness_set_bloc
- return err;
- }
-
-+static struct led_hw_trigger_type omnia_hw_trigger_type;
-+
-+static int omnia_hwtrig_activate(struct led_classdev *cdev)
-+{
-+ struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
-+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
-+ struct omnia_led *led = to_omnia_led(mc_cdev);
-+ int err = 0;
-+
-+ mutex_lock(&leds->lock);
-+
-+ if (!led->on) {
-+ /*
-+ * If the LED is off (brightness was set to 0), the last
-+ * configured color was not necessarily sent to the MCU.
-+ * Recompute with max_brightness and send if needed.
-+ */
-+ led_mc_calc_color_components(mc_cdev, cdev->max_brightness);
-+
-+ if (omnia_led_channels_changed(led))
-+ err = omnia_led_send_color_cmd(leds->client, led);
-+ }
-+
-+ if (!err) {
-+ /* Put the LED into MCU controlled mode */
-+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
-+ CMD_LED_MODE_LED(led->reg));
-+ if (!err)
-+ led->hwtrig = true;
-+ }
-+
-+ mutex_unlock(&leds->lock);
-+
-+ return err;
-+}
-+
-+static void omnia_hwtrig_deactivate(struct led_classdev *cdev)
-+{
-+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
-+ struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
-+ int err;
-+
-+ mutex_lock(&leds->lock);
-+
-+ led->hwtrig = false;
-+
-+ /* Put the LED into software mode */
-+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
-+ CMD_LED_MODE_LED(led->reg) |
-+ CMD_LED_MODE_USER);
-+
-+ mutex_unlock(&leds->lock);
-+
-+ if (err < 0)
-+ dev_err(cdev->dev, "Cannot put LED to software mode: %i\n",
-+ err);
-+}
-+
-+static struct led_trigger omnia_hw_trigger = {
-+ .name = "omnia-mcu",
-+ .activate = omnia_hwtrig_activate,
-+ .deactivate = omnia_hwtrig_deactivate,
-+ .trigger_type = &omnia_hw_trigger_type,
-+};
-+
- static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
- struct device_node *np)
- {
-@@ -195,6 +265,12 @@ static int omnia_led_register(struct i2c
- cdev = &led->mc_cdev.led_cdev;
- cdev->max_brightness = 255;
- cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
-+ cdev->trigger_type = &omnia_hw_trigger_type;
-+ /*
-+ * Use the omnia-mcu trigger as the default trigger. It may be rewritten
-+ * by LED class from the linux,default-trigger property.
-+ */
-+ cdev->default_trigger = omnia_hw_trigger.name;
-
- /* put the LED into software mode */
- ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
-@@ -309,6 +385,12 @@ static int omnia_leds_probe(struct i2c_c
-
- mutex_init(&leds->lock);
-
-+ ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
-+ if (ret < 0) {
-+ dev_err(dev, "Cannot register private LED trigger: %d\n", ret);
-+ return ret;
-+ }
-+
- led = &leds->leds[0];
- for_each_available_child_of_node(np, child) {
- ret = omnia_led_register(client, led, child);
diff --git a/target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch b/target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch
deleted file mode 100644
index e98397922d..0000000000
--- a/target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From 0efb3f9609d3de5a7d8c31e3835d7eb3e6adce79 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 18 Sep 2023 18:11:04 +0200
-Subject: [PATCH 6/6] leds: turris-omnia: Add support for enabling/disabling HW
- gamma correction
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-If the MCU on Turris Omnia is running newer firmware versions, the LED
-controller supports RGB gamma correction (and enables it by default for
-newer boards).
-
-Determine whether the gamma correction setting feature is supported and
-add the ability to set it via sysfs attribute file.
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Link: https://lore.kernel.org/r/20230918161104.20860-5-kabel@kernel.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- .../sysfs-class-led-driver-turris-omnia | 14 ++
- drivers/leds/leds-turris-omnia.c | 137 +++++++++++++++---
- 2 files changed, 134 insertions(+), 17 deletions(-)
-
---- a/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia
-+++ b/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia
-@@ -12,3 +12,17 @@ Description: (RW) On the front panel of
- able to change this setting from software.
-
- Format: %i
-+
-+What: /sys/class/leds/<led>/device/gamma_correction
-+Date: August 2023
-+KernelVersion: 6.6
-+Contact: Marek Behún <kabel@kernel.org>
-+Description: (RW) Newer versions of the microcontroller firmware of the
-+ Turris Omnia router support gamma correction for the RGB LEDs.
-+ This feature can be enabled/disabled by writing to this file.
-+
-+ If the feature is not supported because the MCU firmware is too
-+ old, the file always reads as 0, and writing to the file results
-+ in the EOPNOTSUPP error.
-+
-+ Format: %i
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -15,17 +15,30 @@
- #define OMNIA_BOARD_LEDS 12
- #define OMNIA_LED_NUM_CHANNELS 3
-
--#define CMD_LED_MODE 3
--#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
--#define CMD_LED_MODE_USER 0x10
--
--#define CMD_LED_STATE 4
--#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
--#define CMD_LED_STATE_ON 0x10
--
--#define CMD_LED_COLOR 5
--#define CMD_LED_SET_BRIGHTNESS 7
--#define CMD_LED_GET_BRIGHTNESS 8
-+/* MCU controller commands at I2C address 0x2a */
-+#define OMNIA_MCU_I2C_ADDR 0x2a
-+
-+#define CMD_GET_STATUS_WORD 0x01
-+#define STS_FEATURES_SUPPORTED BIT(2)
-+
-+#define CMD_GET_FEATURES 0x10
-+#define FEAT_LED_GAMMA_CORRECTION BIT(5)
-+
-+/* LED controller commands at I2C address 0x2b */
-+#define CMD_LED_MODE 0x03
-+#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
-+#define CMD_LED_MODE_USER 0x10
-+
-+#define CMD_LED_STATE 0x04
-+#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
-+#define CMD_LED_STATE_ON 0x10
-+
-+#define CMD_LED_COLOR 0x05
-+#define CMD_LED_SET_BRIGHTNESS 0x07
-+#define CMD_LED_GET_BRIGHTNESS 0x08
-+
-+#define CMD_SET_GAMMA_CORRECTION 0x30
-+#define CMD_GET_GAMMA_CORRECTION 0x31
-
- struct omnia_led {
- struct led_classdev_mc mc_cdev;
-@@ -40,6 +53,7 @@ struct omnia_led {
- struct omnia_leds {
- struct i2c_client *client;
- struct mutex lock;
-+ bool has_gamma_correction;
- struct omnia_led leds[];
- };
-
-@@ -50,30 +64,42 @@ static int omnia_cmd_write_u8(const stru
- return i2c_master_send(client, buf, sizeof(buf));
- }
-
--static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
-+static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
-+ void *reply, size_t len)
- {
- struct i2c_msg msgs[2];
-- u8 reply;
- int ret;
-
-- msgs[0].addr = client->addr;
-+ msgs[0].addr = addr;
- msgs[0].flags = 0;
- msgs[0].len = 1;
- msgs[0].buf = &cmd;
-- msgs[1].addr = client->addr;
-+ msgs[1].addr = addr;
- msgs[1].flags = I2C_M_RD;
-- msgs[1].len = 1;
-- msgs[1].buf = &reply;
-+ msgs[1].len = len;
-+ msgs[1].buf = reply;
-
-- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-+ ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
- if (likely(ret == ARRAY_SIZE(msgs)))
-- return reply;
-+ return len;
- else if (ret < 0)
- return ret;
- else
- return -EIO;
- }
-
-+static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
-+{
-+ u8 reply;
-+ int ret;
-+
-+ ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
-+ if (ret < 0)
-+ return ret;
-+
-+ return reply;
-+}
-+
- static int omnia_led_send_color_cmd(const struct i2c_client *client,
- struct omnia_led *led)
- {
-@@ -352,12 +378,74 @@ static ssize_t brightness_store(struct d
- }
- static DEVICE_ATTR_RW(brightness);
-
-+static ssize_t gamma_correction_show(struct device *dev,
-+ struct device_attribute *a, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct omnia_leds *leds = i2c_get_clientdata(client);
-+ int ret;
-+
-+ if (leds->has_gamma_correction) {
-+ ret = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ ret = 0;
-+ }
-+
-+ return sysfs_emit(buf, "%d\n", !!ret);
-+}
-+
-+static ssize_t gamma_correction_store(struct device *dev,
-+ struct device_attribute *a,
-+ const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct omnia_leds *leds = i2c_get_clientdata(client);
-+ bool val;
-+ int ret;
-+
-+ if (!leds->has_gamma_correction)
-+ return -EOPNOTSUPP;
-+
-+ if (kstrtobool(buf, &val) < 0)
-+ return -EINVAL;
-+
-+ ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
-+
-+ return ret < 0 ? ret : count;
-+}
-+static DEVICE_ATTR_RW(gamma_correction);
-+
- static struct attribute *omnia_led_controller_attrs[] = {
- &dev_attr_brightness.attr,
-+ &dev_attr_gamma_correction.attr,
- NULL,
- };
- ATTRIBUTE_GROUPS(omnia_led_controller);
-
-+static int omnia_mcu_get_features(const struct i2c_client *client)
-+{
-+ u16 reply;
-+ int err;
-+
-+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
-+ CMD_GET_STATUS_WORD, &reply, sizeof(reply));
-+ if (err < 0)
-+ return err;
-+
-+ /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
-+ if (!(le16_to_cpu(reply) & STS_FEATURES_SUPPORTED))
-+ return 0;
-+
-+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
-+ CMD_GET_FEATURES, &reply, sizeof(reply));
-+ if (err < 0)
-+ return err;
-+
-+ return le16_to_cpu(reply);
-+}
-+
- static int omnia_leds_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
-@@ -383,6 +471,21 @@ static int omnia_leds_probe(struct i2c_c
- leds->client = client;
- i2c_set_clientdata(client, leds);
-
-+ ret = omnia_mcu_get_features(client);
-+ if (ret < 0) {
-+ dev_err(dev, "Cannot determine MCU supported features: %d\n",
-+ ret);
-+ return ret;
-+ }
-+
-+ leds->has_gamma_correction = ret & FEAT_LED_GAMMA_CORRECTION;
-+ if (!leds->has_gamma_correction) {
-+ dev_info(dev,
-+ "Your board's MCU firmware does not support the LED gamma correction feature.\n");
-+ dev_info(dev,
-+ "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
-+ }
-+
- mutex_init(&leds->lock);
-
- ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
diff --git a/target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch b/target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch
deleted file mode 100644
index b0cebdcf14..0000000000
--- a/target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From ffec49d391c5f0195360912b216aa24dbc9b53c8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 16 Oct 2023 16:15:38 +0200
-Subject: [PATCH] leds: turris-omnia: Fix brightness setting and trigger
- activating
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-I have improperly refactored commits
- 4d5ed2621c24 ("leds: turris-omnia: Make set_brightness() more efficient")
-and
- aaf38273cf76 ("leds: turris-omnia: Support HW controlled mode via private trigger")
-after Lee requested a change in API semantics of the new functions I
-introduced in commit
- 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls").
-
-Before the change, the function omnia_cmd_write_u8() returned 0 on
-success, and afterwards it returned a positive value (number of bytes
-written). The latter version was applied, but the following commits did
-not properly account for this change.
-
-This results in non-functional LED's .brightness_set_blocking() and
-trigger's .activate() methods.
-
-The main reasoning behind the semantics change was that read/write
-methods should return the number of read/written bytes on success.
-It was pointed to me [1] that this is not always true (for example the
-regmap API does not do so), and since the driver never uses this number
-of read/written bytes information, I decided to fix this issue by
-changing the functions to the original semantics (return 0 on success).
-
-[1] https://lore.kernel.org/linux-gpio/ZQnn+Gi0xVlsGCYA@smile.fi.intel.com/
-
-Fixes: 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls")
-Signed-off-by: Marek Behún <kabel@kernel.org>
----
- drivers/leds/leds-turris-omnia.c | 37 +++++++++++++++++---------------
- 1 file changed, 20 insertions(+), 17 deletions(-)
-
---- a/drivers/leds/leds-turris-omnia.c
-+++ b/drivers/leds/leds-turris-omnia.c
-@@ -60,8 +60,11 @@ struct omnia_leds {
- static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val)
- {
- u8 buf[2] = { cmd, val };
-+ int ret;
-+
-+ ret = i2c_master_send(client, buf, sizeof(buf));
-
-- return i2c_master_send(client, buf, sizeof(buf));
-+ return ret < 0 ? ret : 0;
- }
-
- static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
-@@ -81,7 +84,7 @@ static int omnia_cmd_read_raw(struct i2c
-
- ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
- if (likely(ret == ARRAY_SIZE(msgs)))
-- return len;
-+ return 0;
- else if (ret < 0)
- return ret;
- else
-@@ -91,11 +94,11 @@ static int omnia_cmd_read_raw(struct i2c
- static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
- {
- u8 reply;
-- int ret;
-+ int err;
-
-- ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
-- if (ret < 0)
-- return ret;
-+ err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
-+ if (err)
-+ return err;
-
- return reply;
- }
-@@ -236,7 +239,7 @@ static void omnia_hwtrig_deactivate(stru
-
- mutex_unlock(&leds->lock);
-
-- if (err < 0)
-+ if (err)
- dev_err(cdev->dev, "Cannot put LED to software mode: %i\n",
- err);
- }
-@@ -302,7 +305,7 @@ static int omnia_led_register(struct i2c
- ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
- CMD_LED_MODE_LED(led->reg) |
- CMD_LED_MODE_USER);
-- if (ret < 0) {
-+ if (ret) {
- dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np,
- ret);
- return ret;
-@@ -311,7 +314,7 @@ static int omnia_led_register(struct i2c
- /* disable the LED */
- ret = omnia_cmd_write_u8(client, CMD_LED_STATE,
- CMD_LED_STATE_LED(led->reg));
-- if (ret < 0) {
-+ if (ret) {
- dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret);
- return ret;
- }
-@@ -364,7 +367,7 @@ static ssize_t brightness_store(struct d
- {
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long brightness;
-- int ret;
-+ int err;
-
- if (kstrtoul(buf, 10, &brightness))
- return -EINVAL;
-@@ -372,9 +375,9 @@ static ssize_t brightness_store(struct d
- if (brightness > 100)
- return -EINVAL;
-
-- ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
-+ err = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
-
-- return ret < 0 ? ret : count;
-+ return err ?: count;
- }
- static DEVICE_ATTR_RW(brightness);
-
-@@ -403,7 +406,7 @@ static ssize_t gamma_correction_store(st
- struct i2c_client *client = to_i2c_client(dev);
- struct omnia_leds *leds = i2c_get_clientdata(client);
- bool val;
-- int ret;
-+ int err;
-
- if (!leds->has_gamma_correction)
- return -EOPNOTSUPP;
-@@ -411,9 +414,9 @@ static ssize_t gamma_correction_store(st
- if (kstrtobool(buf, &val) < 0)
- return -EINVAL;
-
-- ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
-+ err = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
-
-- return ret < 0 ? ret : count;
-+ return err ?: count;
- }
- static DEVICE_ATTR_RW(gamma_correction);
-
-@@ -431,7 +434,7 @@ static int omnia_mcu_get_features(const
-
- err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
- CMD_GET_STATUS_WORD, &reply, sizeof(reply));
-- if (err < 0)
-+ if (err)
- return err;
-
- /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
-@@ -440,7 +443,7 @@ static int omnia_mcu_get_features(const
-
- err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
- CMD_GET_FEATURES, &reply, sizeof(reply));
-- if (err < 0)
-+ if (err)
- return err;
-
- return le16_to_cpu(reply);
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch b/target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch
deleted file mode 100644
index 66d4028140..0000000000
--- a/target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 16724d6ea40a2c9315f5a0d81005dfa4d7a6da24 Mon Sep 17 00:00:00 2001
-From: Luca Weiss <luca.weiss@fairphone.com>
-Date: Fri, 20 Oct 2023 11:55:40 +0100
-Subject: [PATCH] nvmem: qfprom: Mark core clk as optional
-
-On some platforms like sc7280 on non-ChromeOS devices the core clock
-cannot be touched by Linux so we cannot provide it. Mark it as optional
-as accessing qfprom for reading works without it but we still prohibit
-writing if we cannot provide the clock.
-
-Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
-Reviewed-by: Douglas Anderson <dianders@chromium.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231020105545.216052-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/qfprom.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -423,12 +423,12 @@ static int qfprom_probe(struct platform_
- if (IS_ERR(priv->vcc))
- return PTR_ERR(priv->vcc);
-
-- priv->secclk = devm_clk_get(dev, "core");
-+ priv->secclk = devm_clk_get_optional(dev, "core");
- if (IS_ERR(priv->secclk))
- return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n");
-
-- /* Only enable writing if we have SoC data. */
-- if (priv->soc_data)
-+ /* Only enable writing if we have SoC data and a valid clock */
-+ if (priv->soc_data && priv->secclk)
- econfig.reg_write = qfprom_reg_write;
- }
-
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch b/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch
deleted file mode 100644
index be293e6f2a..0000000000
--- a/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch
+++ /dev/null
@@ -1,330 +0,0 @@
-From 2cc3b37f5b6df8189d55d0e812d9658ce256dfec Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 20 Oct 2023 11:55:41 +0100
-Subject: [PATCH] nvmem: add explicit config option to read old syntax fixed OF
- cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Binding for fixed NVMEM cells defined directly as NVMEM device subnodes
-has been deprecated. It has been replaced by the "fixed-layout" NVMEM
-layout binding.
-
-New syntax is meant to be clearer and should help avoiding imprecise
-bindings.
-
-NVMEM subsystem already supports the new binding. It should be a good
-idea to limit support for old syntax to existing drivers that actually
-support & use it (we can't break backward compatibility!). That way we
-additionally encourage new bindings & drivers to ignore deprecated
-binding.
-
-It wasn't clear (to me) if rtc and w1 code actually uses old syntax
-fixed cells. I enabled them to don't risk any breakage.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-[for meson-{efuse,mx-efuse}.c]
-Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-[for mtk-efuse.c, nvmem/core.c, nvmem-provider.h]
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-[MT8192, MT8195 Chromebooks]
-Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-[for microchip-otpc.c]
-Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
-[SAMA7G5-EK]
-Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231020105545.216052-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/mtd/mtdcore.c | 2 ++
- drivers/nvmem/apple-efuses.c | 1 +
- drivers/nvmem/core.c | 8 +++++---
- drivers/nvmem/imx-ocotp-scu.c | 1 +
- drivers/nvmem/imx-ocotp.c | 1 +
- drivers/nvmem/meson-efuse.c | 1 +
- drivers/nvmem/meson-mx-efuse.c | 1 +
- drivers/nvmem/microchip-otpc.c | 1 +
- drivers/nvmem/mtk-efuse.c | 1 +
- drivers/nvmem/qcom-spmi-sdam.c | 1 +
- drivers/nvmem/qfprom.c | 1 +
- drivers/nvmem/rave-sp-eeprom.c | 1 +
- drivers/nvmem/rockchip-efuse.c | 1 +
- drivers/nvmem/sc27xx-efuse.c | 1 +
- drivers/nvmem/sec-qfprom.c | 1 +
- drivers/nvmem/sprd-efuse.c | 1 +
- drivers/nvmem/stm32-romem.c | 1 +
- drivers/nvmem/sunplus-ocotp.c | 1 +
- drivers/nvmem/sunxi_sid.c | 1 +
- drivers/nvmem/uniphier-efuse.c | 1 +
- drivers/nvmem/zynqmp_nvmem.c | 1 +
- drivers/rtc/nvmem.c | 1 +
- drivers/w1/slaves/w1_ds250x.c | 1 +
- include/linux/nvmem-provider.h | 2 ++
- 24 files changed, 30 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -523,6 +523,7 @@ static int mtd_nvmem_add(struct mtd_info
- config.dev = &mtd->dev;
- config.name = dev_name(&mtd->dev);
- config.owner = THIS_MODULE;
-+ config.add_legacy_fixed_of_cells = of_device_is_compatible(node, "nvmem-cells");
- config.reg_read = mtd_nvmem_reg_read;
- config.size = mtd->size;
- config.word_size = 1;
-@@ -891,6 +892,7 @@ static struct nvmem_device *mtd_otp_nvme
- config.name = compatible;
- config.id = NVMEM_DEVID_AUTO;
- config.owner = THIS_MODULE;
-+ config.add_legacy_fixed_of_cells = true;
- config.type = NVMEM_TYPE_OTP;
- config.root_only = true;
- config.ignore_wp = true;
---- a/drivers/nvmem/apple-efuses.c
-+++ b/drivers/nvmem/apple-efuses.c
-@@ -36,6 +36,7 @@ static int apple_efuses_probe(struct pla
- struct resource *res;
- struct nvmem_config config = {
- .dev = &pdev->dev,
-+ .add_legacy_fixed_of_cells = true,
- .read_only = true,
- .reg_read = apple_efuses_read,
- .stride = sizeof(u32),
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -998,9 +998,11 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_legacy_of(nvmem);
-- if (rval)
-- goto err_remove_cells;
-+ if (config->add_legacy_fixed_of_cells) {
-+ rval = nvmem_add_cells_from_legacy_of(nvmem);
-+ if (rval)
-+ goto err_remove_cells;
-+ }
-
- rval = nvmem_add_cells_from_fixed_layout(nvmem);
- if (rval)
---- a/drivers/nvmem/imx-ocotp-scu.c
-+++ b/drivers/nvmem/imx-ocotp-scu.c
-@@ -220,6 +220,7 @@ static int imx_scu_ocotp_write(void *con
-
- static struct nvmem_config imx_scu_ocotp_nvmem_config = {
- .name = "imx-scu-ocotp",
-+ .add_legacy_fixed_of_cells = true,
- .read_only = false,
- .word_size = 4,
- .stride = 1,
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -616,6 +616,7 @@ static int imx_ocotp_probe(struct platfo
- return PTR_ERR(priv->clk);
-
- priv->params = of_device_get_match_data(&pdev->dev);
-+ imx_ocotp_nvmem_config.add_legacy_fixed_of_cells = true;
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
---- a/drivers/nvmem/meson-efuse.c
-+++ b/drivers/nvmem/meson-efuse.c
-@@ -74,6 +74,7 @@ static int meson_efuse_probe(struct plat
-
- econfig->dev = dev;
- econfig->name = dev_name(dev);
-+ econfig->add_legacy_fixed_of_cells = true;
- econfig->stride = 1;
- econfig->word_size = 1;
- econfig->reg_read = meson_efuse_read;
---- a/drivers/nvmem/meson-mx-efuse.c
-+++ b/drivers/nvmem/meson-mx-efuse.c
-@@ -211,6 +211,7 @@ static int meson_mx_efuse_probe(struct p
- efuse->config.owner = THIS_MODULE;
- efuse->config.dev = &pdev->dev;
- efuse->config.priv = efuse;
-+ efuse->config.add_legacy_fixed_of_cells = true;
- efuse->config.stride = drvdata->word_size;
- efuse->config.word_size = drvdata->word_size;
- efuse->config.size = SZ_512;
---- a/drivers/nvmem/microchip-otpc.c
-+++ b/drivers/nvmem/microchip-otpc.c
-@@ -261,6 +261,7 @@ static int mchp_otpc_probe(struct platfo
- return ret;
-
- mchp_nvmem_config.dev = otpc->dev;
-+ mchp_nvmem_config.add_legacy_fixed_of_cells = true;
- mchp_nvmem_config.size = size;
- mchp_nvmem_config.priv = otpc;
- nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config);
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -83,6 +83,7 @@ static int mtk_efuse_probe(struct platfo
- return PTR_ERR(priv->base);
-
- pdata = device_get_match_data(dev);
-+ econfig.add_legacy_fixed_of_cells = true;
- econfig.stride = 1;
- econfig.word_size = 1;
- econfig.reg_read = mtk_reg_read;
---- a/drivers/nvmem/qcom-spmi-sdam.c
-+++ b/drivers/nvmem/qcom-spmi-sdam.c
-@@ -142,6 +142,7 @@ static int sdam_probe(struct platform_de
- sdam->sdam_config.name = "spmi_sdam";
- sdam->sdam_config.id = NVMEM_DEVID_AUTO;
- sdam->sdam_config.owner = THIS_MODULE;
-+ sdam->sdam_config.add_legacy_fixed_of_cells = true;
- sdam->sdam_config.stride = 1;
- sdam->sdam_config.word_size = 1;
- sdam->sdam_config.reg_read = sdam_read;
---- a/drivers/nvmem/qfprom.c
-+++ b/drivers/nvmem/qfprom.c
-@@ -357,6 +357,7 @@ static int qfprom_probe(struct platform_
- {
- struct nvmem_config econfig = {
- .name = "qfprom",
-+ .add_legacy_fixed_of_cells = true,
- .stride = 1,
- .word_size = 1,
- .id = NVMEM_DEVID_AUTO,
---- a/drivers/nvmem/rave-sp-eeprom.c
-+++ b/drivers/nvmem/rave-sp-eeprom.c
-@@ -328,6 +328,7 @@ static int rave_sp_eeprom_probe(struct p
- of_property_read_string(np, "zii,eeprom-name", &config.name);
- config.priv = eeprom;
- config.dev = dev;
-+ config.add_legacy_fixed_of_cells = true;
- config.size = size;
- config.reg_read = rave_sp_eeprom_reg_read;
- config.reg_write = rave_sp_eeprom_reg_write;
---- a/drivers/nvmem/rockchip-efuse.c
-+++ b/drivers/nvmem/rockchip-efuse.c
-@@ -205,6 +205,7 @@ static int rockchip_rk3399_efuse_read(vo
-
- static struct nvmem_config econfig = {
- .name = "rockchip-efuse",
-+ .add_legacy_fixed_of_cells = true,
- .stride = 1,
- .word_size = 1,
- .read_only = true,
---- a/drivers/nvmem/sc27xx-efuse.c
-+++ b/drivers/nvmem/sc27xx-efuse.c
-@@ -248,6 +248,7 @@ static int sc27xx_efuse_probe(struct pla
- econfig.reg_read = sc27xx_efuse_read;
- econfig.priv = efuse;
- econfig.dev = &pdev->dev;
-+ econfig.add_legacy_fixed_of_cells = true;
- nvmem = devm_nvmem_register(&pdev->dev, &econfig);
- if (IS_ERR(nvmem)) {
- dev_err(&pdev->dev, "failed to register nvmem config\n");
---- a/drivers/nvmem/sec-qfprom.c
-+++ b/drivers/nvmem/sec-qfprom.c
-@@ -47,6 +47,7 @@ static int sec_qfprom_probe(struct platf
- {
- struct nvmem_config econfig = {
- .name = "sec-qfprom",
-+ .add_legacy_fixed_of_cells = true,
- .stride = 1,
- .word_size = 1,
- .id = NVMEM_DEVID_AUTO,
---- a/drivers/nvmem/sprd-efuse.c
-+++ b/drivers/nvmem/sprd-efuse.c
-@@ -408,6 +408,7 @@ static int sprd_efuse_probe(struct platf
- econfig.read_only = false;
- econfig.name = "sprd-efuse";
- econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH;
-+ econfig.add_legacy_fixed_of_cells = true;
- econfig.reg_read = sprd_efuse_read;
- econfig.reg_write = sprd_efuse_write;
- econfig.priv = efuse;
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -207,6 +207,7 @@ static int stm32_romem_probe(struct plat
- priv->cfg.priv = priv;
- priv->cfg.owner = THIS_MODULE;
- priv->cfg.type = NVMEM_TYPE_OTP;
-+ priv->cfg.add_legacy_fixed_of_cells = true;
-
- priv->lower = 0;
-
---- a/drivers/nvmem/sunplus-ocotp.c
-+++ b/drivers/nvmem/sunplus-ocotp.c
-@@ -145,6 +145,7 @@ disable_clk:
-
- static struct nvmem_config sp_ocotp_nvmem_config = {
- .name = "sp-ocotp",
-+ .add_legacy_fixed_of_cells = true,
- .read_only = true,
- .word_size = 1,
- .size = QAC628_OTP_SIZE,
---- a/drivers/nvmem/sunxi_sid.c
-+++ b/drivers/nvmem/sunxi_sid.c
-@@ -154,6 +154,7 @@ static int sunxi_sid_probe(struct platfo
- nvmem_cfg->dev = dev;
- nvmem_cfg->name = "sunxi-sid";
- nvmem_cfg->type = NVMEM_TYPE_OTP;
-+ nvmem_cfg->add_legacy_fixed_of_cells = true;
- nvmem_cfg->read_only = true;
- nvmem_cfg->size = cfg->size;
- nvmem_cfg->word_size = 1;
---- a/drivers/nvmem/uniphier-efuse.c
-+++ b/drivers/nvmem/uniphier-efuse.c
-@@ -52,6 +52,7 @@ static int uniphier_efuse_probe(struct p
- econfig.size = resource_size(res);
- econfig.priv = priv;
- econfig.dev = dev;
-+ econfig.add_legacy_fixed_of_cells = true;
- nvmem = devm_nvmem_register(dev, &econfig);
-
- return PTR_ERR_OR_ZERO(nvmem);
---- a/drivers/nvmem/zynqmp_nvmem.c
-+++ b/drivers/nvmem/zynqmp_nvmem.c
-@@ -58,6 +58,7 @@ static int zynqmp_nvmem_probe(struct pla
-
- priv->dev = dev;
- econfig.dev = dev;
-+ econfig.add_legacy_fixed_of_cells = true;
- econfig.reg_read = zynqmp_nvmem_read;
- econfig.priv = priv;
-
---- a/drivers/rtc/nvmem.c
-+++ b/drivers/rtc/nvmem.c
-@@ -21,6 +21,7 @@ int devm_rtc_nvmem_register(struct rtc_d
-
- nvmem_config->dev = dev;
- nvmem_config->owner = rtc->owner;
-+ nvmem_config->add_legacy_fixed_of_cells = true;
- nvmem = devm_nvmem_register(dev, nvmem_config);
- if (IS_ERR(nvmem))
- dev_err(dev, "failed to register nvmem device for RTC\n");
---- a/drivers/w1/slaves/w1_ds250x.c
-+++ b/drivers/w1/slaves/w1_ds250x.c
-@@ -168,6 +168,7 @@ static int w1_eprom_add_slave(struct w1_
- struct nvmem_device *nvmem;
- struct nvmem_config nvmem_cfg = {
- .dev = &sl->dev,
-+ .add_legacy_fixed_of_cells = true,
- .reg_read = w1_nvmem_read,
- .type = NVMEM_TYPE_OTP,
- .read_only = true,
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -82,6 +82,7 @@ struct nvmem_cell_info {
- * @owner: Pointer to exporter module. Used for refcounting.
- * @cells: Optional array of pre-defined NVMEM cells.
- * @ncells: Number of elements in cells.
-+ * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax.
- * @keepout: Optional array of keepout ranges (sorted ascending by start).
- * @nkeepout: Number of elements in the keepout array.
- * @type: Type of the nvmem storage
-@@ -112,6 +113,7 @@ struct nvmem_config {
- struct module *owner;
- const struct nvmem_cell_info *cells;
- int ncells;
-+ bool add_legacy_fixed_of_cells;
- const struct nvmem_keepout *keepout;
- unsigned int nkeepout;
- enum nvmem_type type;
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch b/target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch
deleted file mode 100644
index 84c0293982..0000000000
--- a/target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 0720219f4d34a88a9badb4de70cfad7585687d48 Mon Sep 17 00:00:00 2001
-From: Rob Herring <robh@kernel.org>
-Date: Fri, 20 Oct 2023 11:55:45 +0100
-Subject: [PATCH] nvmem: Use device_get_match_data()
-
-Use preferred device_get_match_data() instead of of_match_device() to
-get the driver match data. With this, adjust the includes to explicitly
-include the correct headers.
-
-Signed-off-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231020105545.216052-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/mxs-ocotp.c | 10 ++++------
- drivers/nvmem/stm32-romem.c | 7 ++++---
- 2 files changed, 8 insertions(+), 9 deletions(-)
-
---- a/drivers/nvmem/mxs-ocotp.c
-+++ b/drivers/nvmem/mxs-ocotp.c
-@@ -13,8 +13,9 @@
- #include <linux/io.h>
- #include <linux/module.h>
- #include <linux/nvmem-provider.h>
--#include <linux/of_device.h>
-+#include <linux/of.h>
- #include <linux/platform_device.h>
-+#include <linux/property.h>
- #include <linux/slab.h>
- #include <linux/stmp_device.h>
-
-@@ -140,11 +141,10 @@ static int mxs_ocotp_probe(struct platfo
- struct device *dev = &pdev->dev;
- const struct mxs_data *data;
- struct mxs_ocotp *otp;
-- const struct of_device_id *match;
- int ret;
-
-- match = of_match_device(dev->driver->of_match_table, dev);
-- if (!match || !match->data)
-+ data = device_get_match_data(dev);
-+ if (!data)
- return -EINVAL;
-
- otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
-@@ -169,8 +169,6 @@ static int mxs_ocotp_probe(struct platfo
- if (ret)
- return ret;
-
-- data = match->data;
--
- ocotp_config.size = data->size;
- ocotp_config.priv = otp;
- ocotp_config.dev = dev;
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -10,7 +10,9 @@
- #include <linux/io.h>
- #include <linux/module.h>
- #include <linux/nvmem-provider.h>
--#include <linux/of_device.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/property.h>
- #include <linux/tee_drv.h>
-
- #include "stm32-bsec-optee-ta.h"
-@@ -211,8 +213,7 @@ static int stm32_romem_probe(struct plat
-
- priv->lower = 0;
-
-- cfg = (const struct stm32_romem_cfg *)
-- of_match_device(dev->driver->of_match_table, dev)->data;
-+ cfg = device_get_match_data(dev);
- if (!cfg) {
- priv->cfg.read_only = true;
- priv->cfg.size = resource_size(res);
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch b/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
deleted file mode 100644
index 7d80ad37f1..0000000000
--- a/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From f4cf4e5db331a5ce69e3f0b21d322cac0f4e4b5d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 23 Oct 2023 12:27:59 +0200
-Subject: [PATCH] Revert "nvmem: add new config option"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit 517f14d9cf3533d5ab4fded195ab6f80a92e378f.
-
-Config option "no_of_node" is no longer needed since adding a more
-explicit and targeted option "add_legacy_fixed_of_cells".
-
-That "no_of_node" config option was needed *earlier* to help mtd's case.
-
-DT nodes of MTD partitions (that are also NVMEM devices) may contain
-subnodes. Those SHOULD NOT be treated as NVMEM fixed cells.
-
-To prevent NVMEM core code from parsing subnodes a "no_of_node" option
-was added (and set to true in mtd) to make for_each_child_of_node() in
-NVMEM a no-op. That was a bit hacky because it was messing with
-"of_node" pointer to achieve some side-effect.
-
-With the introduction of "add_legacy_fixed_of_cells" config option
-things got more explicit. MTD subsystem simply tells NVMEM when to look
-for fixed cells and there is no need to hack "of_node" pointer anymore.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231023102759.31529-1-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/mtd/mtdcore.c | 1 -
- drivers/nvmem/core.c | 2 +-
- include/linux/nvmem-provider.h | 2 --
- 3 files changed, 1 insertion(+), 4 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -531,7 +531,6 @@ static int mtd_nvmem_add(struct mtd_info
- config.read_only = true;
- config.root_only = true;
- config.ignore_wp = true;
-- config.no_of_node = !of_device_is_compatible(node, "nvmem-cells");
- config.priv = mtd;
-
- mtd->nvmem = nvmem_register(&config);
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -936,7 +936,7 @@ struct nvmem_device *nvmem_register(cons
- nvmem->nkeepout = config->nkeepout;
- if (config->of_node)
- nvmem->dev.of_node = config->of_node;
-- else if (!config->no_of_node)
-+ else
- nvmem->dev.of_node = config->dev->of_node;
-
- switch (config->id) {
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -89,7 +89,6 @@ struct nvmem_cell_info {
- * @read_only: Device is read-only.
- * @root_only: Device is accessibly to root only.
- * @of_node: If given, this will be used instead of the parent's of_node.
-- * @no_of_node: Device should not use the parent's of_node even if it's !NULL.
- * @reg_read: Callback to read data.
- * @reg_write: Callback to write data.
- * @size: Device size.
-@@ -122,7 +121,6 @@ struct nvmem_config {
- bool ignore_wp;
- struct nvmem_layout *layout;
- struct device_node *of_node;
-- bool no_of_node;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
- int size;
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch b/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch
deleted file mode 100644
index bd5ceaabf7..0000000000
--- a/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From b7c1e53751cb3990153084f31c41f25fde3b629c Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 24 Nov 2023 20:38:14 +0100
-Subject: [PATCH] nvmem: Do not expect fixed layouts to grab a layout driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Two series lived in parallel for some time, which led to this situation:
-- The nvmem-layout container is used for dynamic layouts
-- We now expect fixed layouts to also use the nvmem-layout container but
-this does not require any additional driver, the support is built-in the
-nvmem core.
-
-Ensure we don't refuse to probe for wrong reasons.
-
-Fixes: 27f699e578b1 ("nvmem: core: add support for fixed cells *layout*")
-Cc: stable@vger.kernel.org
-Reported-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Rafał Miłecki <rafal@milecki.pl>
-Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-
-Link: https://lore.kernel.org/r/20231124193814.360552-1-miquel.raynal@bootlin.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -797,6 +797,12 @@ static struct nvmem_layout *nvmem_layout
- if (!layout_np)
- return NULL;
-
-+ /* Fixed layouts don't have a matching driver */
-+ if (of_device_is_compatible(layout_np, "fixed-layout")) {
-+ of_node_put(layout_np);
-+ return NULL;
-+ }
-+
- /*
- * In case the nvmem device was built-in while the layout was built as a
- * module, we shall manually request the layout driver loading otherwise
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch b/target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch
deleted file mode 100644
index d49a20599d..0000000000
--- a/target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From 1e37bf84afacd5ba17b7a13a18ca2bc78aff05c0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 15 Dec 2023 11:13:58 +0000
-Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This driver uses MMIO access for reading NVRAM from a flash device.
-Underneath there is a flash controller that reads data and provides
-mapping window.
-
-Using MMIO interface affects controller configuration and may break real
-controller driver. It was reported by multiple users of devices with
-NVRAM stored on NAND.
-
-Modify driver to read & cache NVRAM content during init and use that
-copy to provide NVMEM data when requested. On NAND flashes due to their
-alignment NVRAM partitions can be quite big (1 MiB and more) while
-actual NVRAM content stays quite small (usually 16 to 32 KiB). To avoid
-allocating so much memory check for actual data length.
-
-Link: https://lore.kernel.org/linux-mtd/CACna6rwf3_9QVjYcM+847biTX=K0EoWXuXcSMkJO1Vy_5vmVqA@mail.gmail.com/
-Fixes: 3fef9ed0627a ("nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM")
-Cc: <Stable@vger.kernel.org>
-Cc: Arınç ÜNAL <arinc.unal@arinc9.com>
-Cc: Florian Fainelli <florian.fainelli@broadcom.com>
-Cc: Scott Branden <scott.branden@broadcom.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111358.316727-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/brcm_nvram.c | 134 ++++++++++++++++++++++++++-----------
- 1 file changed, 94 insertions(+), 40 deletions(-)
-
---- a/drivers/nvmem/brcm_nvram.c
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -17,9 +17,23 @@
-
- #define NVRAM_MAGIC "FLSH"
-
-+/**
-+ * struct brcm_nvram - driver state internal struct
-+ *
-+ * @dev: NVMEM device pointer
-+ * @nvmem_size: Size of the whole space available for NVRAM
-+ * @data: NVRAM data copy stored to avoid poking underlaying flash controller
-+ * @data_len: NVRAM data size
-+ * @padding_byte: Padding value used to fill remaining space
-+ * @cells: Array of discovered NVMEM cells
-+ * @ncells: Number of elements in cells
-+ */
- struct brcm_nvram {
- struct device *dev;
-- void __iomem *base;
-+ size_t nvmem_size;
-+ uint8_t *data;
-+ size_t data_len;
-+ uint8_t padding_byte;
- struct nvmem_cell_info *cells;
- int ncells;
- };
-@@ -36,10 +50,47 @@ static int brcm_nvram_read(void *context
- size_t bytes)
- {
- struct brcm_nvram *priv = context;
-- u8 *dst = val;
-+ size_t to_copy;
-+
-+ if (offset + bytes > priv->data_len)
-+ to_copy = max_t(ssize_t, (ssize_t)priv->data_len - offset, 0);
-+ else
-+ to_copy = bytes;
-+
-+ memcpy(val, priv->data + offset, to_copy);
-+
-+ memset((uint8_t *)val + to_copy, priv->padding_byte, bytes - to_copy);
-+
-+ return 0;
-+}
-+
-+static int brcm_nvram_copy_data(struct brcm_nvram *priv, struct platform_device *pdev)
-+{
-+ struct resource *res;
-+ void __iomem *base;
-+
-+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ priv->nvmem_size = resource_size(res);
-+
-+ priv->padding_byte = readb(base + priv->nvmem_size - 1);
-+ for (priv->data_len = priv->nvmem_size;
-+ priv->data_len;
-+ priv->data_len--) {
-+ if (readb(base + priv->data_len - 1) != priv->padding_byte)
-+ break;
-+ }
-+ WARN(priv->data_len > SZ_128K, "Unexpected (big) NVRAM size: %zu B\n", priv->data_len);
-
-- while (bytes--)
-- *dst++ = readb(priv->base + offset++);
-+ priv->data = devm_kzalloc(priv->dev, priv->data_len, GFP_KERNEL);
-+ if (!priv->data)
-+ return -ENOMEM;
-+
-+ memcpy_fromio(priv->data, base, priv->data_len);
-+
-+ bcm47xx_nvram_init_from_iomem(base, priv->data_len);
-
- return 0;
- }
-@@ -67,8 +118,13 @@ static int brcm_nvram_add_cells(struct b
- size_t len)
- {
- struct device *dev = priv->dev;
-- char *var, *value, *eq;
-+ char *var, *value;
-+ uint8_t tmp;
- int idx;
-+ int err = 0;
-+
-+ tmp = priv->data[len - 1];
-+ priv->data[len - 1] = '\0';
-
- priv->ncells = 0;
- for (var = data + sizeof(struct brcm_nvram_header);
-@@ -78,67 +134,68 @@ static int brcm_nvram_add_cells(struct b
- }
-
- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
-- if (!priv->cells)
-- return -ENOMEM;
-+ if (!priv->cells) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-
- for (var = data + sizeof(struct brcm_nvram_header), idx = 0;
- var < (char *)data + len && *var;
- var = value + strlen(value) + 1, idx++) {
-+ char *eq, *name;
-+
- eq = strchr(var, '=');
- if (!eq)
- break;
- *eq = '\0';
-+ name = devm_kstrdup(dev, var, GFP_KERNEL);
-+ *eq = '=';
-+ if (!name) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
- value = eq + 1;
-
-- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
-- if (!priv->cells[idx].name)
-- return -ENOMEM;
-+ priv->cells[idx].name = name;
- priv->cells[idx].offset = value - (char *)data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-- if (!strcmp(var, "et0macaddr") ||
-- !strcmp(var, "et1macaddr") ||
-- !strcmp(var, "et2macaddr")) {
-+ if (!strcmp(name, "et0macaddr") ||
-+ !strcmp(name, "et1macaddr") ||
-+ !strcmp(name, "et2macaddr")) {
- priv->cells[idx].raw_len = strlen(value);
- priv->cells[idx].bytes = ETH_ALEN;
- priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
- }
- }
-
-- return 0;
-+out:
-+ priv->data[len - 1] = tmp;
-+ return err;
- }
-
- static int brcm_nvram_parse(struct brcm_nvram *priv)
- {
-+ struct brcm_nvram_header *header = (struct brcm_nvram_header *)priv->data;
- struct device *dev = priv->dev;
-- struct brcm_nvram_header header;
-- uint8_t *data;
- size_t len;
- int err;
-
-- memcpy_fromio(&header, priv->base, sizeof(header));
--
-- if (memcmp(header.magic, NVRAM_MAGIC, 4)) {
-+ if (memcmp(header->magic, NVRAM_MAGIC, 4)) {
- dev_err(dev, "Invalid NVRAM magic\n");
- return -EINVAL;
- }
-
-- len = le32_to_cpu(header.len);
--
-- data = kzalloc(len, GFP_KERNEL);
-- if (!data)
-- return -ENOMEM;
--
-- memcpy_fromio(data, priv->base, len);
-- data[len - 1] = '\0';
--
-- err = brcm_nvram_add_cells(priv, data, len);
-- if (err) {
-- dev_err(dev, "Failed to add cells: %d\n", err);
-- return err;
-+ len = le32_to_cpu(header->len);
-+ if (len > priv->nvmem_size) {
-+ dev_err(dev, "NVRAM length (%zd) exceeds mapped size (%zd)\n", len,
-+ priv->nvmem_size);
-+ return -EINVAL;
- }
-
-- kfree(data);
-+ err = brcm_nvram_add_cells(priv, priv->data, len);
-+ if (err)
-+ dev_err(dev, "Failed to add cells: %d\n", err);
-
- return 0;
- }
-@@ -150,7 +207,6 @@ static int brcm_nvram_probe(struct platf
- .reg_read = brcm_nvram_read,
- };
- struct device *dev = &pdev->dev;
-- struct resource *res;
- struct brcm_nvram *priv;
- int err;
-
-@@ -159,21 +215,19 @@ static int brcm_nvram_probe(struct platf
- return -ENOMEM;
- priv->dev = dev;
-
-- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-- if (IS_ERR(priv->base))
-- return PTR_ERR(priv->base);
-+ err = brcm_nvram_copy_data(priv, pdev);
-+ if (err)
-+ return err;
-
- err = brcm_nvram_parse(priv);
- if (err)
- return err;
-
-- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
--
- config.dev = dev;
- config.cells = priv->cells;
- config.ncells = priv->ncells;
- config.priv = priv;
-- config.size = resource_size(res);
-+ config.size = priv->nvmem_size;
-
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
- }
diff --git a/target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch b/target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch
deleted file mode 100644
index bf36e19fcc..0000000000
--- a/target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From ec18a2a83b8b9f7e39c80105ea148c769c46227b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 17 Jan 2024 16:17:36 +0100
-Subject: [PATCH] dt-bindings: leds: Add FUNCTION defines for per-band WLANs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Most wireless routers and access points can operate in multiple bands
-simultaneously. Vendors often equip their devices with per-band LEDs.
-
-Add defines for those very common functions to allow cleaner & clearer
-bindings.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20240117151736.27440-1-zajec5@gmail.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- include/dt-bindings/leds/common.h | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -101,6 +101,9 @@
- #define LED_FUNCTION_USB "usb"
- #define LED_FUNCTION_WAN "wan"
- #define LED_FUNCTION_WLAN "wlan"
-+#define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz"
-+#define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz"
-+#define LED_FUNCTION_WLAN_6GHZ "wlan-6ghz"
- #define LED_FUNCTION_WPS "wps"
-
- #endif /* __DT_BINDINGS_LEDS_H */
diff --git a/target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch b/target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch
deleted file mode 100644
index eabb9bbe9a..0000000000
--- a/target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 64e558500d2d04878b8a6d6578850c475171d6ba Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 23 Feb 2024 12:22:23 +0100
-Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_WAN_ONLINE for Internet
- access
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's common for routers to have LED indicating link on the WAN port.
-
-Some devices however have an extra LED that's meant to be used if WAN
-connection is actually "online" (there is Internet access available).
-
-It was suggested to add #define for such use case.
-
-Link: https://lore.kernel.org/linux-devicetree/80e92209-5578-44e7-bd4b-603a29053ddf@collabora.com/T/#u
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20240223112223.1368-1-zajec5@gmail.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- include/dt-bindings/leds/common.h | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -100,6 +100,7 @@
- #define LED_FUNCTION_TX "tx"
- #define LED_FUNCTION_USB "usb"
- #define LED_FUNCTION_WAN "wan"
-+#define LED_FUNCTION_WAN_ONLINE "wan-online"
- #define LED_FUNCTION_WLAN "wlan"
- #define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz"
- #define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz"
diff --git a/target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch b/target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch
deleted file mode 100644
index 564fe9822d..0000000000
--- a/target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-From 7f38b70042fcaa49219045bd1a9a2836e27a58ac Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:27 +0000
-Subject: [PATCH] of: device: Export of_device_make_bus_id()
-
-This helper is really handy to create unique device names based on their
-device tree path, we may need it outside of the OF core (in the NVMEM
-subsystem) so let's export it. As this helper has nothing patform
-specific, let's move it to of/device.c instead of of/platform.c so we
-can add its prototype to of_device.h.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Acked-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 41 +++++++++++++++++++++++++++++++++++++++
- drivers/of/platform.c | 40 --------------------------------------
- include/linux/of_device.h | 6 ++++++
- 3 files changed, 47 insertions(+), 40 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -395,3 +395,44 @@ int of_device_uevent_modalias(struct dev
- return 0;
- }
- EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
-+
-+/**
-+ * of_device_make_bus_id - Use the device node data to assign a unique name
-+ * @dev: pointer to device structure that is linked to a device tree node
-+ *
-+ * This routine will first try using the translated bus address to
-+ * derive a unique name. If it cannot, then it will prepend names from
-+ * parent nodes until a unique name can be derived.
-+ */
-+void of_device_make_bus_id(struct device *dev)
-+{
-+ struct device_node *node = dev->of_node;
-+ const __be32 *reg;
-+ u64 addr;
-+ u32 mask;
-+
-+ /* Construct the name, using parent nodes if necessary to ensure uniqueness */
-+ while (node->parent) {
-+ /*
-+ * If the address can be translated, then that is as much
-+ * uniqueness as we need. Make it the first component and return
-+ */
-+ reg = of_get_property(node, "reg", NULL);
-+ if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
-+ if (!of_property_read_u32(node, "mask", &mask))
-+ dev_set_name(dev, dev_name(dev) ? "%llx.%x.%pOFn:%s" : "%llx.%x.%pOFn",
-+ addr, ffs(mask) - 1, node, dev_name(dev));
-+
-+ else
-+ dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn",
-+ addr, node, dev_name(dev));
-+ return;
-+ }
-+
-+ /* format arguments only used if dev_name() resolves to NULL */
-+ dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s",
-+ kbasename(node->full_name), dev_name(dev));
-+ node = node->parent;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(of_device_make_bus_id);
---- a/drivers/of/platform.c
-+++ b/drivers/of/platform.c
-@@ -64,46 +64,6 @@ EXPORT_SYMBOL(of_find_device_by_node);
- */
-
- /**
-- * of_device_make_bus_id - Use the device node data to assign a unique name
-- * @dev: pointer to device structure that is linked to a device tree node
-- *
-- * This routine will first try using the translated bus address to
-- * derive a unique name. If it cannot, then it will prepend names from
-- * parent nodes until a unique name can be derived.
-- */
--static void of_device_make_bus_id(struct device *dev)
--{
-- struct device_node *node = dev->of_node;
-- const __be32 *reg;
-- u64 addr;
-- u32 mask;
--
-- /* Construct the name, using parent nodes if necessary to ensure uniqueness */
-- while (node->parent) {
-- /*
-- * If the address can be translated, then that is as much
-- * uniqueness as we need. Make it the first component and return
-- */
-- reg = of_get_property(node, "reg", NULL);
-- if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
-- if (!of_property_read_u32(node, "mask", &mask))
-- dev_set_name(dev, dev_name(dev) ? "%llx.%x.%pOFn:%s" : "%llx.%x.%pOFn",
-- addr, ffs(mask) - 1, node, dev_name(dev));
--
-- else
-- dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn",
-- addr, node, dev_name(dev));
-- return;
-- }
--
-- /* format arguments only used if dev_name() resolves to NULL */
-- dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s",
-- kbasename(node->full_name), dev_name(dev));
-- node = node->parent;
-- }
--}
--
--/**
- * of_device_alloc - Allocate and initialize an of_device
- * @np: device node to assign to device
- * @bus_id: Name to assign to the device. May be null to use default name.
---- a/include/linux/of_device.h
-+++ b/include/linux/of_device.h
-@@ -56,6 +56,9 @@ static inline int of_dma_configure(struc
- {
- return of_dma_configure_id(dev, np, force_dma, NULL);
- }
-+
-+void of_device_make_bus_id(struct device *dev);
-+
- #else /* CONFIG_OF */
-
- static inline int of_driver_match_device(struct device *dev,
-@@ -113,6 +116,9 @@ static inline int of_dma_configure(struc
- {
- return 0;
- }
-+
-+static inline void of_device_make_bus_id(struct device *dev) {}
-+
- #endif /* CONFIG_OF */
-
- #endif /* _LINUX_OF_DEVICE_H */
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch b/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
deleted file mode 100644
index 2093fac8a1..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 4a1a40233b4a9fc159a5c7a27dc34c5c7bc5be55 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:28 +0000
-Subject: [PATCH] nvmem: Move of_nvmem_layout_get_container() in another header
-
-nvmem-consumer.h is included by consumer devices, extracting data from
-NVMEM devices whereas nvmem-provider.h is included by devices providing
-NVMEM content.
-
-The only users of of_nvmem_layout_get_container() outside of the core
-are layout drivers, so better move its prototype to nvmem-provider.h.
-
-While we do so, we also move the kdoc associated with the function to
-the header rather than the .c file.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 8 --------
- include/linux/nvmem-consumer.h | 7 -------
- include/linux/nvmem-provider.h | 21 +++++++++++++++++++++
- 3 files changed, 21 insertions(+), 15 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -848,14 +848,6 @@ static int nvmem_add_cells_from_layout(s
- }
-
- #if IS_ENABLED(CONFIG_OF)
--/**
-- * of_nvmem_layout_get_container() - Get OF node to layout container.
-- *
-- * @nvmem: nvmem device.
-- *
-- * Return: a node pointer with refcount incremented or NULL if no
-- * container exists. Use of_node_put() on it when done.
-- */
- struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
- {
- return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -241,7 +241,6 @@ struct nvmem_cell *of_nvmem_cell_get(str
- const char *id);
- struct nvmem_device *of_nvmem_device_get(struct device_node *np,
- const char *name);
--struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem);
- #else
- static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
- const char *id)
-@@ -254,12 +253,6 @@ static inline struct nvmem_device *of_nv
- {
- return ERR_PTR(-EOPNOTSUPP);
- }
--
--static inline struct device_node *
--of_nvmem_layout_get_container(struct nvmem_device *nvmem)
--{
-- return NULL;
--}
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
- #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -244,6 +244,27 @@ nvmem_layout_get_match_data(struct nvmem
-
- #endif /* CONFIG_NVMEM */
-
-+#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-+
-+/**
-+ * of_nvmem_layout_get_container() - Get OF node of layout container
-+ *
-+ * @nvmem: nvmem device
-+ *
-+ * Return: a node pointer with refcount incremented or NULL if no
-+ * container exists. Use of_node_put() on it when done.
-+ */
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem);
-+
-+#else /* CONFIG_NVMEM && CONFIG_OF */
-+
-+static inline struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return NULL;
-+}
-+
-+#endif /* CONFIG_NVMEM && CONFIG_OF */
-+
- #define module_nvmem_layout_driver(__layout_driver) \
- module_driver(__layout_driver, nvmem_layout_register, \
- nvmem_layout_unregister)
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch b/target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch
deleted file mode 100644
index e722109f91..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From ec9c08a1cb8dc5e8e003f95f5f62de41dde235bb Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:29 +0000
-Subject: [PATCH] nvmem: Create a header for internal sharing
-
-Before adding all the NVMEM layout bus infrastructure to the core, let's
-move the main nvmem_device structure in an internal header, only
-available to the core. This way all the additional code can be added in
-a dedicated file in order to keep the current core file tidy.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-4-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 24 +-----------------------
- drivers/nvmem/internals.h | 35 +++++++++++++++++++++++++++++++++++
- 2 files changed, 36 insertions(+), 23 deletions(-)
- create mode 100644 drivers/nvmem/internals.h
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -20,29 +20,7 @@
- #include <linux/of_device.h>
- #include <linux/slab.h>
-
--struct nvmem_device {
-- struct module *owner;
-- struct device dev;
-- int stride;
-- int word_size;
-- int id;
-- struct kref refcnt;
-- size_t size;
-- bool read_only;
-- bool root_only;
-- int flags;
-- enum nvmem_type type;
-- struct bin_attribute eeprom;
-- struct device *base_dev;
-- struct list_head cells;
-- const struct nvmem_keepout *keepout;
-- unsigned int nkeepout;
-- nvmem_reg_read_t reg_read;
-- nvmem_reg_write_t reg_write;
-- struct gpio_desc *wp_gpio;
-- struct nvmem_layout *layout;
-- void *priv;
--};
-+#include "internals.h"
-
- #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
-
---- /dev/null
-+++ b/drivers/nvmem/internals.h
-@@ -0,0 +1,35 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+
-+#ifndef _LINUX_NVMEM_INTERNALS_H
-+#define _LINUX_NVMEM_INTERNALS_H
-+
-+#include <linux/device.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+
-+struct nvmem_device {
-+ struct module *owner;
-+ struct device dev;
-+ struct list_head node;
-+ int stride;
-+ int word_size;
-+ int id;
-+ struct kref refcnt;
-+ size_t size;
-+ bool read_only;
-+ bool root_only;
-+ int flags;
-+ enum nvmem_type type;
-+ struct bin_attribute eeprom;
-+ struct device *base_dev;
-+ struct list_head cells;
-+ const struct nvmem_keepout *keepout;
-+ unsigned int nkeepout;
-+ nvmem_reg_read_t reg_read;
-+ nvmem_reg_write_t reg_write;
-+ struct gpio_desc *wp_gpio;
-+ struct nvmem_layout *layout;
-+ void *priv;
-+};
-+
-+#endif /* ifndef _LINUX_NVMEM_INTERNALS_H */
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch b/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
deleted file mode 100644
index db2d8c1b46..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 1b7c298a4ecbc28cc6ee94005734bff55eb83d22 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:30 +0000
-Subject: [PATCH] nvmem: Simplify the ->add_cells() hook
-
-The layout entry is not used and will anyway be made useless by the new
-layout bus infrastructure coming next, so drop it. While at it, clarify
-the kdoc entry.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-5-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 2 +-
- drivers/nvmem/layouts/onie-tlv.c | 3 +--
- drivers/nvmem/layouts/sl28vpd.c | 3 +--
- include/linux/nvmem-provider.h | 8 +++-----
- 4 files changed, 6 insertions(+), 10 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -817,7 +817,7 @@ static int nvmem_add_cells_from_layout(s
- int ret;
-
- if (layout && layout->add_cells) {
-- ret = layout->add_cells(&nvmem->dev, nvmem, layout);
-+ ret = layout->add_cells(&nvmem->dev, nvmem);
- if (ret)
- return ret;
- }
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -182,8 +182,7 @@ static bool onie_tlv_crc_is_valid(struct
- return true;
- }
-
--static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
-+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem)
- {
- struct onie_tlv_hdr hdr;
- size_t table_len, data_len, hdr_len;
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -80,8 +80,7 @@ static int sl28vpd_v1_check_crc(struct d
- return 0;
- }
-
--static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
-+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem)
- {
- const struct nvmem_cell_info *pinfo;
- struct nvmem_cell_info info = {0};
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -156,9 +156,8 @@ struct nvmem_cell_table {
- *
- * @name: Layout name.
- * @of_match_table: Open firmware match table.
-- * @add_cells: Will be called if a nvmem device is found which
-- * has this layout. The function will add layout
-- * specific cells with nvmem_add_one_cell().
-+ * @add_cells: Called to populate the layout using
-+ * nvmem_add_one_cell().
- * @fixup_cell_info: Will be called before a cell is added. Can be
- * used to modify the nvmem_cell_info.
- * @owner: Pointer to struct module.
-@@ -172,8 +171,7 @@ struct nvmem_cell_table {
- struct nvmem_layout {
- const char *name;
- const struct of_device_id *of_match_table;
-- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem,
-- struct nvmem_layout *layout);
-+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
- void (*fixup_cell_info)(struct nvmem_device *nvmem,
- struct nvmem_layout *layout,
- struct nvmem_cell_info *cell);
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch b/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
deleted file mode 100644
index 65aa37f834..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
+++ /dev/null
@@ -1,169 +0,0 @@
-From 1172460e716784ac7e1049a537bdca8edbf97360 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:31 +0000
-Subject: [PATCH] nvmem: Move and rename ->fixup_cell_info()
-
-This hook is meant to be used by any provider and instantiating a layout
-just for this is useless. Let's instead move this hook to the nvmem
-device and add it to the config structure to be easily shared by the
-providers.
-
-While at moving this hook, rename it ->fixup_dt_cell_info() to clarify
-its main intended purpose.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-6-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 6 +++---
- drivers/nvmem/imx-ocotp.c | 11 +++--------
- drivers/nvmem/internals.h | 2 ++
- drivers/nvmem/mtk-efuse.c | 11 +++--------
- include/linux/nvmem-provider.h | 9 ++++-----
- 5 files changed, 15 insertions(+), 24 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -676,7 +676,6 @@ static int nvmem_validate_keepouts(struc
-
- static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
- {
-- struct nvmem_layout *layout = nvmem->layout;
- struct device *dev = &nvmem->dev;
- struct device_node *child;
- const __be32 *addr;
-@@ -706,8 +705,8 @@ static int nvmem_add_cells_from_dt(struc
-
- info.np = of_node_get(child);
-
-- if (layout && layout->fixup_cell_info)
-- layout->fixup_cell_info(nvmem, layout, &info);
-+ if (nvmem->fixup_dt_cell_info)
-+ nvmem->fixup_dt_cell_info(nvmem, &info);
-
- ret = nvmem_add_one_cell(nvmem, &info);
- kfree(info.name);
-@@ -896,6 +895,7 @@ struct nvmem_device *nvmem_register(cons
-
- kref_init(&nvmem->refcnt);
- INIT_LIST_HEAD(&nvmem->cells);
-+ nvmem->fixup_dt_cell_info = config->fixup_dt_cell_info;
-
- nvmem->owner = config->owner;
- if (!nvmem->owner && config->dev->driver)
---- a/drivers/nvmem/imx-ocotp.c
-+++ b/drivers/nvmem/imx-ocotp.c
-@@ -584,17 +584,12 @@ static const struct of_device_id imx_oco
- };
- MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
-
--static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout,
-- struct nvmem_cell_info *cell)
-+static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell)
- {
- cell->read_post_process = imx_ocotp_cell_pp;
- }
-
--static struct nvmem_layout imx_ocotp_layout = {
-- .fixup_cell_info = imx_ocotp_fixup_cell_info,
--};
--
- static int imx_ocotp_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -620,7 +615,7 @@ static int imx_ocotp_probe(struct platfo
- imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
- imx_ocotp_nvmem_config.dev = dev;
- imx_ocotp_nvmem_config.priv = priv;
-- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
-+ imx_ocotp_nvmem_config.fixup_dt_cell_info = &imx_ocotp_fixup_dt_cell_info;
-
- priv->config = &imx_ocotp_nvmem_config;
-
---- a/drivers/nvmem/internals.h
-+++ b/drivers/nvmem/internals.h
-@@ -23,6 +23,8 @@ struct nvmem_device {
- struct bin_attribute eeprom;
- struct device *base_dev;
- struct list_head cells;
-+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell);
- const struct nvmem_keepout *keepout;
- unsigned int nkeepout;
- nvmem_reg_read_t reg_read;
---- a/drivers/nvmem/mtk-efuse.c
-+++ b/drivers/nvmem/mtk-efuse.c
-@@ -45,9 +45,8 @@ static int mtk_efuse_gpu_speedbin_pp(voi
- return 0;
- }
-
--static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout,
-- struct nvmem_cell_info *cell)
-+static void mtk_efuse_fixup_dt_cell_info(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell)
- {
- size_t sz = strlen(cell->name);
-
-@@ -61,10 +60,6 @@ static void mtk_efuse_fixup_cell_info(st
- cell->read_post_process = mtk_efuse_gpu_speedbin_pp;
- }
-
--static struct nvmem_layout mtk_efuse_layout = {
-- .fixup_cell_info = mtk_efuse_fixup_cell_info,
--};
--
- static int mtk_efuse_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -91,7 +86,7 @@ static int mtk_efuse_probe(struct platfo
- econfig.priv = priv;
- econfig.dev = dev;
- if (pdata->uses_post_processing)
-- econfig.layout = &mtk_efuse_layout;
-+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
- nvmem = devm_nvmem_register(dev, &econfig);
-
- return PTR_ERR_OR_ZERO(nvmem);
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -83,6 +83,8 @@ struct nvmem_cell_info {
- * @cells: Optional array of pre-defined NVMEM cells.
- * @ncells: Number of elements in cells.
- * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax.
-+ * @fixup_dt_cell_info: Will be called before a cell is added. Can be
-+ * used to modify the nvmem_cell_info.
- * @keepout: Optional array of keepout ranges (sorted ascending by start).
- * @nkeepout: Number of elements in the keepout array.
- * @type: Type of the nvmem storage
-@@ -113,6 +115,8 @@ struct nvmem_config {
- const struct nvmem_cell_info *cells;
- int ncells;
- bool add_legacy_fixed_of_cells;
-+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem,
-+ struct nvmem_cell_info *cell);
- const struct nvmem_keepout *keepout;
- unsigned int nkeepout;
- enum nvmem_type type;
-@@ -158,8 +162,6 @@ struct nvmem_cell_table {
- * @of_match_table: Open firmware match table.
- * @add_cells: Called to populate the layout using
- * nvmem_add_one_cell().
-- * @fixup_cell_info: Will be called before a cell is added. Can be
-- * used to modify the nvmem_cell_info.
- * @owner: Pointer to struct module.
- * @node: List node.
- *
-@@ -172,9 +174,6 @@ struct nvmem_layout {
- const char *name;
- const struct of_device_id *of_match_table;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
-- void (*fixup_cell_info)(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout,
-- struct nvmem_cell_info *cell);
-
- /* private */
- struct module *owner;
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch b/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
deleted file mode 100644
index 1881332340..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
+++ /dev/null
@@ -1,763 +0,0 @@
-From fc29fd821d9ac2ae3d32a722fac39ce874efb883 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:32 +0000
-Subject: [PATCH] nvmem: core: Rework layouts to become regular devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Current layout support was initially written without modules support in
-mind. When the requirement for module support rose, the existing base
-was improved to adopt modularization support, but kind of a design flaw
-was introduced. With the existing implementation, when a storage device
-registers into NVMEM, the core tries to hook a layout (if any) and
-populates its cells immediately. This means, if the hardware description
-expects a layout to be hooked up, but no driver was provided for that,
-the storage medium will fail to probe and try later from
-scratch. Even if we consider that the hardware description shall be
-correct, we could still probe the storage device (especially if it
-contains the rootfs).
-
-One way to overcome this situation is to consider the layouts as
-devices, and leverage the native notifier mechanism. When a new NVMEM
-device is registered, we can populate its nvmem-layout child, if any,
-and wait for the matching to be done in order to get the cells (the
-waiting can be easily done with the NVMEM notifiers). If the layout
-driver is compiled as a module, it should automatically be loaded. This
-way, there is no strong order to enforce, any NVMEM device creation
-or NVMEM layout driver insertion will be observed as a new event which
-may lead to the creation of additional cells, without disturbing the
-probes with costly (and sometimes endless) deferrals.
-
-In order to achieve that goal we create a new bus for the nvmem-layouts
-with minimal logic to match nvmem-layout devices with nvmem-layout
-drivers. All this infrastructure code is created in the layouts.c file.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/Kconfig | 1 +
- drivers/nvmem/Makefile | 2 +
- drivers/nvmem/core.c | 170 ++++++++++----------------
- drivers/nvmem/internals.h | 21 ++++
- drivers/nvmem/layouts.c | 201 +++++++++++++++++++++++++++++++
- drivers/nvmem/layouts/Kconfig | 8 ++
- drivers/nvmem/layouts/onie-tlv.c | 24 +++-
- drivers/nvmem/layouts/sl28vpd.c | 24 +++-
- include/linux/nvmem-provider.h | 38 +++---
- 9 files changed, 354 insertions(+), 135 deletions(-)
- create mode 100644 drivers/nvmem/layouts.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- menuconfig NVMEM
- bool "NVMEM Support"
-+ imply NVMEM_LAYOUTS
- help
- Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES...
-
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -5,6 +5,8 @@
-
- obj-$(CONFIG_NVMEM) += nvmem_core.o
- nvmem_core-y := core.o
-+obj-$(CONFIG_NVMEM_LAYOUTS) += nvmem_layouts.o
-+nvmem_layouts-y := layouts.o
- obj-y += layouts/
-
- # Devices
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -56,9 +56,6 @@ static LIST_HEAD(nvmem_lookup_list);
-
- static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
-
--static DEFINE_SPINLOCK(nvmem_layout_lock);
--static LIST_HEAD(nvmem_layouts);
--
- static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
- void *val, size_t bytes)
- {
-@@ -741,97 +738,22 @@ static int nvmem_add_cells_from_fixed_la
- return err;
- }
-
--int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
-+int nvmem_layout_register(struct nvmem_layout *layout)
- {
-- layout->owner = owner;
--
-- spin_lock(&nvmem_layout_lock);
-- list_add(&layout->node, &nvmem_layouts);
-- spin_unlock(&nvmem_layout_lock);
--
-- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout);
-+ if (!layout->add_cells)
-+ return -EINVAL;
-
-- return 0;
-+ /* Populate the cells */
-+ return layout->add_cells(&layout->nvmem->dev, layout->nvmem);
- }
--EXPORT_SYMBOL_GPL(__nvmem_layout_register);
-+EXPORT_SYMBOL_GPL(nvmem_layout_register);
-
- void nvmem_layout_unregister(struct nvmem_layout *layout)
- {
-- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout);
--
-- spin_lock(&nvmem_layout_lock);
-- list_del(&layout->node);
-- spin_unlock(&nvmem_layout_lock);
-+ /* Keep the API even with an empty stub in case we need it later */
- }
- EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-
--static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
--{
-- struct device_node *layout_np;
-- struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
--
-- layout_np = of_nvmem_layout_get_container(nvmem);
-- if (!layout_np)
-- return NULL;
--
-- /* Fixed layouts don't have a matching driver */
-- if (of_device_is_compatible(layout_np, "fixed-layout")) {
-- of_node_put(layout_np);
-- return NULL;
-- }
--
-- /*
-- * In case the nvmem device was built-in while the layout was built as a
-- * module, we shall manually request the layout driver loading otherwise
-- * we'll never have any match.
-- */
-- of_request_module(layout_np);
--
-- spin_lock(&nvmem_layout_lock);
--
-- list_for_each_entry(l, &nvmem_layouts, node) {
-- if (of_match_node(l->of_match_table, layout_np)) {
-- if (try_module_get(l->owner))
-- layout = l;
--
-- break;
-- }
-- }
--
-- spin_unlock(&nvmem_layout_lock);
-- of_node_put(layout_np);
--
-- return layout;
--}
--
--static void nvmem_layout_put(struct nvmem_layout *layout)
--{
-- if (layout)
-- module_put(layout->owner);
--}
--
--static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem)
--{
-- struct nvmem_layout *layout = nvmem->layout;
-- int ret;
--
-- if (layout && layout->add_cells) {
-- ret = layout->add_cells(&nvmem->dev, nvmem);
-- if (ret)
-- return ret;
-- }
--
-- return 0;
--}
--
--#if IS_ENABLED(CONFIG_OF)
--struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
--{
-- return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
--}
--EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container);
--#endif
--
- const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout)
- {
-@@ -839,7 +761,7 @@ const void *nvmem_layout_get_match_data(
- const struct of_device_id *match;
-
- layout_np = of_nvmem_layout_get_container(nvmem);
-- match = of_match_node(layout->of_match_table, layout_np);
-+ match = of_match_node(layout->dev.driver->of_match_table, layout_np);
-
- return match ? match->data : NULL;
- }
-@@ -951,19 +873,6 @@ struct nvmem_device *nvmem_register(cons
- goto err_put_device;
- }
-
-- /*
-- * If the driver supplied a layout by config->layout, the module
-- * pointer will be NULL and nvmem_layout_put() will be a noop.
-- */
-- nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
-- if (IS_ERR(nvmem->layout)) {
-- rval = PTR_ERR(nvmem->layout);
-- nvmem->layout = NULL;
--
-- if (rval == -EPROBE_DEFER)
-- goto err_teardown_compat;
-- }
--
- if (config->cells) {
- rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
- if (rval)
-@@ -984,24 +893,24 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-- rval = nvmem_add_cells_from_layout(nvmem);
-- if (rval)
-- goto err_remove_cells;
--
- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
-
- rval = device_add(&nvmem->dev);
- if (rval)
- goto err_remove_cells;
-
-+ rval = nvmem_populate_layout(nvmem);
-+ if (rval)
-+ goto err_remove_dev;
-+
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
-
- return nvmem;
-
-+err_remove_dev:
-+ device_del(&nvmem->dev);
- err_remove_cells:
- nvmem_device_remove_all_cells(nvmem);
-- nvmem_layout_put(nvmem->layout);
--err_teardown_compat:
- if (config->compat)
- nvmem_sysfs_remove_compat(nvmem, config);
- err_put_device:
-@@ -1023,7 +932,7 @@ static void nvmem_device_release(struct
- device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
-
- nvmem_device_remove_all_cells(nvmem);
-- nvmem_layout_put(nvmem->layout);
-+ nvmem_destroy_layout(nvmem);
- device_unregister(&nvmem->dev);
- }
-
-@@ -1325,6 +1234,12 @@ nvmem_cell_get_from_lookup(struct device
- return cell;
- }
-
-+static void nvmem_layout_module_put(struct nvmem_device *nvmem)
-+{
-+ if (nvmem->layout && nvmem->layout->dev.driver)
-+ module_put(nvmem->layout->dev.driver->owner);
-+}
-+
- #if IS_ENABLED(CONFIG_OF)
- static struct nvmem_cell_entry *
- nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np)
-@@ -1343,6 +1258,18 @@ nvmem_find_cell_entry_by_node(struct nvm
- return cell;
- }
-
-+static int nvmem_layout_module_get_optional(struct nvmem_device *nvmem)
-+{
-+ if (!nvmem->layout)
-+ return 0;
-+
-+ if (!nvmem->layout->dev.driver ||
-+ !try_module_get(nvmem->layout->dev.driver->owner))
-+ return -EPROBE_DEFER;
-+
-+ return 0;
-+}
-+
- /**
- * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
- *
-@@ -1405,16 +1332,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
- return ERR_CAST(nvmem);
- }
-
-+ ret = nvmem_layout_module_get_optional(nvmem);
-+ if (ret) {
-+ of_node_put(cell_np);
-+ __nvmem_device_put(nvmem);
-+ return ERR_PTR(ret);
-+ }
-+
- cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
- of_node_put(cell_np);
- if (!cell_entry) {
- __nvmem_device_put(nvmem);
-- return ERR_PTR(-ENOENT);
-+ nvmem_layout_module_put(nvmem);
-+ if (nvmem->layout)
-+ return ERR_PTR(-EPROBE_DEFER);
-+ else
-+ return ERR_PTR(-ENOENT);
- }
-
- cell = nvmem_create_cell(cell_entry, id, cell_index);
-- if (IS_ERR(cell))
-+ if (IS_ERR(cell)) {
- __nvmem_device_put(nvmem);
-+ nvmem_layout_module_put(nvmem);
-+ }
-
- return cell;
- }
-@@ -1528,6 +1468,7 @@ void nvmem_cell_put(struct nvmem_cell *c
-
- kfree(cell);
- __nvmem_device_put(nvmem);
-+ nvmem_layout_module_put(nvmem);
- }
- EXPORT_SYMBOL_GPL(nvmem_cell_put);
-
-@@ -2105,11 +2046,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name);
-
- static int __init nvmem_init(void)
- {
-- return bus_register(&nvmem_bus_type);
-+ int ret;
-+
-+ ret = bus_register(&nvmem_bus_type);
-+ if (ret)
-+ return ret;
-+
-+ ret = nvmem_layout_bus_register();
-+ if (ret)
-+ bus_unregister(&nvmem_bus_type);
-+
-+ return ret;
- }
-
- static void __exit nvmem_exit(void)
- {
-+ nvmem_layout_bus_unregister();
- bus_unregister(&nvmem_bus_type);
- }
-
---- a/drivers/nvmem/internals.h
-+++ b/drivers/nvmem/internals.h
-@@ -34,4 +34,25 @@ struct nvmem_device {
- void *priv;
- };
-
-+#if IS_ENABLED(CONFIG_OF)
-+int nvmem_layout_bus_register(void);
-+void nvmem_layout_bus_unregister(void);
-+int nvmem_populate_layout(struct nvmem_device *nvmem);
-+void nvmem_destroy_layout(struct nvmem_device *nvmem);
-+#else /* CONFIG_OF */
-+static inline int nvmem_layout_bus_register(void)
-+{
-+ return 0;
-+}
-+
-+static inline void nvmem_layout_bus_unregister(void) {}
-+
-+static inline int nvmem_populate_layout(struct nvmem_device *nvmem)
-+{
-+ return 0;
-+}
-+
-+static inline void nvmem_destroy_layout(struct nvmem_device *nvmem) { }
-+#endif /* CONFIG_OF */
-+
- #endif /* ifndef _LINUX_NVMEM_INTERNALS_H */
---- /dev/null
-+++ b/drivers/nvmem/layouts.c
-@@ -0,0 +1,201 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * NVMEM layout bus handling
-+ *
-+ * Copyright (C) 2023 Bootlin
-+ * Author: Miquel Raynal <miquel.raynal@bootlin.com
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/of_irq.h>
-+
-+#include "internals.h"
-+
-+#define to_nvmem_layout_driver(drv) \
-+ (container_of((drv), struct nvmem_layout_driver, driver))
-+#define to_nvmem_layout_device(_dev) \
-+ container_of((_dev), struct nvmem_layout, dev)
-+
-+static int nvmem_layout_bus_match(struct device *dev, struct device_driver *drv)
-+{
-+ return of_driver_match_device(dev, drv);
-+}
-+
-+static int nvmem_layout_bus_probe(struct device *dev)
-+{
-+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver);
-+ struct nvmem_layout *layout = to_nvmem_layout_device(dev);
-+
-+ if (!drv->probe || !drv->remove)
-+ return -EINVAL;
-+
-+ return drv->probe(layout);
-+}
-+
-+static void nvmem_layout_bus_remove(struct device *dev)
-+{
-+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver);
-+ struct nvmem_layout *layout = to_nvmem_layout_device(dev);
-+
-+ return drv->remove(layout);
-+}
-+
-+static struct bus_type nvmem_layout_bus_type = {
-+ .name = "nvmem-layout",
-+ .match = nvmem_layout_bus_match,
-+ .probe = nvmem_layout_bus_probe,
-+ .remove = nvmem_layout_bus_remove,
-+};
-+
-+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv)
-+{
-+ drv->driver.bus = &nvmem_layout_bus_type;
-+
-+ return driver_register(&drv->driver);
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_driver_register);
-+
-+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv)
-+{
-+ driver_unregister(&drv->driver);
-+}
-+EXPORT_SYMBOL_GPL(nvmem_layout_driver_unregister);
-+
-+static void nvmem_layout_release_device(struct device *dev)
-+{
-+ struct nvmem_layout *layout = to_nvmem_layout_device(dev);
-+
-+ of_node_put(layout->dev.of_node);
-+ kfree(layout);
-+}
-+
-+static int nvmem_layout_create_device(struct nvmem_device *nvmem,
-+ struct device_node *np)
-+{
-+ struct nvmem_layout *layout;
-+ struct device *dev;
-+ int ret;
-+
-+ layout = kzalloc(sizeof(*layout), GFP_KERNEL);
-+ if (!layout)
-+ return -ENOMEM;
-+
-+ /* Create a bidirectional link */
-+ layout->nvmem = nvmem;
-+ nvmem->layout = layout;
-+
-+ /* Device model registration */
-+ dev = &layout->dev;
-+ device_initialize(dev);
-+ dev->parent = &nvmem->dev;
-+ dev->bus = &nvmem_layout_bus_type;
-+ dev->release = nvmem_layout_release_device;
-+ dev->coherent_dma_mask = DMA_BIT_MASK(32);
-+ dev->dma_mask = &dev->coherent_dma_mask;
-+ device_set_node(dev, of_fwnode_handle(of_node_get(np)));
-+ of_device_make_bus_id(dev);
-+ of_msi_configure(dev, dev->of_node);
-+
-+ ret = device_add(dev);
-+ if (ret) {
-+ put_device(dev);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id of_nvmem_layout_skip_table[] = {
-+ { .compatible = "fixed-layout", },
-+ {}
-+};
-+
-+static int nvmem_layout_bus_populate(struct nvmem_device *nvmem,
-+ struct device_node *layout_dn)
-+{
-+ int ret;
-+
-+ /* Make sure it has a compatible property */
-+ if (!of_get_property(layout_dn, "compatible", NULL)) {
-+ pr_debug("%s() - skipping %pOF, no compatible prop\n",
-+ __func__, layout_dn);
-+ return 0;
-+ }
-+
-+ /* Fixed layouts are parsed manually somewhere else for now */
-+ if (of_match_node(of_nvmem_layout_skip_table, layout_dn)) {
-+ pr_debug("%s() - skipping %pOF node\n", __func__, layout_dn);
-+ return 0;
-+ }
-+
-+ if (of_node_check_flag(layout_dn, OF_POPULATED_BUS)) {
-+ pr_debug("%s() - skipping %pOF, already populated\n",
-+ __func__, layout_dn);
-+
-+ return 0;
-+ }
-+
-+ /* NVMEM layout buses expect only a single device representing the layout */
-+ ret = nvmem_layout_create_device(nvmem, layout_dn);
-+ if (ret)
-+ return ret;
-+
-+ of_node_set_flag(layout_dn, OF_POPULATED_BUS);
-+
-+ return 0;
-+}
-+
-+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
-+{
-+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
-+}
-+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container);
-+
-+/*
-+ * Returns the number of devices populated, 0 if the operation was not relevant
-+ * for this nvmem device, an error code otherwise.
-+ */
-+int nvmem_populate_layout(struct nvmem_device *nvmem)
-+{
-+ struct device_node *layout_dn;
-+ int ret;
-+
-+ layout_dn = of_nvmem_layout_get_container(nvmem);
-+ if (!layout_dn)
-+ return 0;
-+
-+ /* Populate the layout device */
-+ device_links_supplier_sync_state_pause();
-+ ret = nvmem_layout_bus_populate(nvmem, layout_dn);
-+ device_links_supplier_sync_state_resume();
-+
-+ of_node_put(layout_dn);
-+ return ret;
-+}
-+
-+void nvmem_destroy_layout(struct nvmem_device *nvmem)
-+{
-+ struct device *dev;
-+
-+ if (!nvmem->layout)
-+ return;
-+
-+ dev = &nvmem->layout->dev;
-+ of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
-+ device_unregister(dev);
-+}
-+
-+int nvmem_layout_bus_register(void)
-+{
-+ return bus_register(&nvmem_layout_bus_type);
-+}
-+
-+void nvmem_layout_bus_unregister(void)
-+{
-+ bus_unregister(&nvmem_layout_bus_type);
-+}
---- a/drivers/nvmem/layouts/Kconfig
-+++ b/drivers/nvmem/layouts/Kconfig
-@@ -1,5 +1,11 @@
- # SPDX-License-Identifier: GPL-2.0
-
-+config NVMEM_LAYOUTS
-+ bool
-+ depends on OF
-+
-+if NVMEM_LAYOUTS
-+
- menu "Layout Types"
-
- config NVMEM_LAYOUT_SL28_VPD
-@@ -21,3 +27,5 @@ config NVMEM_LAYOUT_ONIE_TLV
- If unsure, say N.
-
- endmenu
-+
-+endif
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -225,16 +225,32 @@ static int onie_tlv_parse_table(struct d
- return 0;
- }
-
-+static int onie_tlv_probe(struct nvmem_layout *layout)
-+{
-+ layout->add_cells = onie_tlv_parse_table;
-+
-+ return nvmem_layout_register(layout);
-+}
-+
-+static void onie_tlv_remove(struct nvmem_layout *layout)
-+{
-+ nvmem_layout_unregister(layout);
-+}
-+
- static const struct of_device_id onie_tlv_of_match_table[] = {
- { .compatible = "onie,tlv-layout", },
- {},
- };
- MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table);
-
--static struct nvmem_layout onie_tlv_layout = {
-- .name = "ONIE tlv layout",
-- .of_match_table = onie_tlv_of_match_table,
-- .add_cells = onie_tlv_parse_table,
-+static struct nvmem_layout_driver onie_tlv_layout = {
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "onie-tlv-layout",
-+ .of_match_table = onie_tlv_of_match_table,
-+ },
-+ .probe = onie_tlv_probe,
-+ .remove = onie_tlv_remove,
- };
- module_nvmem_layout_driver(onie_tlv_layout);
-
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -134,16 +134,32 @@ static int sl28vpd_add_cells(struct devi
- return 0;
- }
-
-+static int sl28vpd_probe(struct nvmem_layout *layout)
-+{
-+ layout->add_cells = sl28vpd_add_cells;
-+
-+ return nvmem_layout_register(layout);
-+}
-+
-+static void sl28vpd_remove(struct nvmem_layout *layout)
-+{
-+ nvmem_layout_unregister(layout);
-+}
-+
- static const struct of_device_id sl28vpd_of_match_table[] = {
- { .compatible = "kontron,sl28-vpd" },
- {},
- };
- MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table);
-
--static struct nvmem_layout sl28vpd_layout = {
-- .name = "sl28-vpd",
-- .of_match_table = sl28vpd_of_match_table,
-- .add_cells = sl28vpd_add_cells,
-+static struct nvmem_layout_driver sl28vpd_layout = {
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "kontron-sl28vpd-layout",
-+ .of_match_table = sl28vpd_of_match_table,
-+ },
-+ .probe = sl28vpd_probe,
-+ .remove = sl28vpd_remove,
- };
- module_nvmem_layout_driver(sl28vpd_layout);
-
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -9,6 +9,7 @@
- #ifndef _LINUX_NVMEM_PROVIDER_H
- #define _LINUX_NVMEM_PROVIDER_H
-
-+#include <linux/device.h>
- #include <linux/device/driver.h>
- #include <linux/err.h>
- #include <linux/errno.h>
-@@ -158,12 +159,11 @@ struct nvmem_cell_table {
- /**
- * struct nvmem_layout - NVMEM layout definitions
- *
-- * @name: Layout name.
-- * @of_match_table: Open firmware match table.
-- * @add_cells: Called to populate the layout using
-- * nvmem_add_one_cell().
-- * @owner: Pointer to struct module.
-- * @node: List node.
-+ * @dev: Device-model layout device.
-+ * @nvmem: The underlying NVMEM device
-+ * @add_cells: Will be called if a nvmem device is found which
-+ * has this layout. The function will add layout
-+ * specific cells with nvmem_add_one_cell().
- *
- * A nvmem device can hold a well defined structure which can just be
- * evaluated during runtime. For example a TLV list, or a list of "name=val"
-@@ -171,13 +171,15 @@ struct nvmem_cell_table {
- * cells.
- */
- struct nvmem_layout {
-- const char *name;
-- const struct of_device_id *of_match_table;
-+ struct device dev;
-+ struct nvmem_device *nvmem;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
-+};
-
-- /* private */
-- struct module *owner;
-- struct list_head node;
-+struct nvmem_layout_driver {
-+ struct device_driver driver;
-+ int (*probe)(struct nvmem_layout *layout);
-+ void (*remove)(struct nvmem_layout *layout);
- };
-
- #if IS_ENABLED(CONFIG_NVMEM)
-@@ -194,11 +196,15 @@ void nvmem_del_cell_table(struct nvmem_c
- int nvmem_add_one_cell(struct nvmem_device *nvmem,
- const struct nvmem_cell_info *info);
-
--int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner);
--#define nvmem_layout_register(layout) \
-- __nvmem_layout_register(layout, THIS_MODULE)
-+int nvmem_layout_register(struct nvmem_layout *layout);
- void nvmem_layout_unregister(struct nvmem_layout *layout);
-
-+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv);
-+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv);
-+#define module_nvmem_layout_driver(__nvmem_layout_driver) \
-+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
-+ nvmem_layout_driver_unregister)
-+
- const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout);
-
-@@ -262,8 +268,4 @@ static inline struct device_node *of_nvm
-
- #endif /* CONFIG_NVMEM && CONFIG_OF */
-
--#define module_nvmem_layout_driver(__layout_driver) \
-- module_driver(__layout_driver, nvmem_layout_register, \
-- nvmem_layout_unregister)
--
- #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch b/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
deleted file mode 100644
index 89872bec2e..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
+++ /dev/null
@@ -1,240 +0,0 @@
-From 0331c611949fffdf486652450901a4dc52bc5cca Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Fri, 15 Dec 2023 11:15:34 +0000
-Subject: [PATCH] nvmem: core: Expose cells through sysfs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The binary content of nvmem devices is available to the user so in the
-easiest cases, finding the content of a cell is rather easy as it is
-just a matter of looking at a known and fixed offset. However, nvmem
-layouts have been recently introduced to cope with more advanced
-situations, where the offset and size of the cells is not known in
-advance or is dynamic. When using layouts, more advanced parsers are
-used by the kernel in order to give direct access to the content of each
-cell, regardless of its position/size in the underlying
-device. Unfortunately, these information are not accessible by users,
-unless by fully re-implementing the parser logic in userland.
-
-Let's expose the cells and their content through sysfs to avoid these
-situations. Of course the relevant NVMEM sysfs Kconfig option must be
-enabled for this support to be available.
-
-Not all nvmem devices expose cells. Indeed, the .bin_attrs attribute
-group member will be filled at runtime only when relevant and will
-remain empty otherwise. In this case, as the cells attribute group will
-be empty, it will not lead to any additional folder/file creation.
-
-Exposed cells are read-only. There is, in practice, everything in the
-core to support a write path, but as I don't see any need for that, I
-prefer to keep the interface simple (and probably safer). The interface
-is documented as being in the "testing" state which means we can later
-add a write attribute if though relevant.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Tested-by: Rafał Miłecki <rafal@milecki.pl>
-Tested-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 135 +++++++++++++++++++++++++++++++++++++-
- drivers/nvmem/internals.h | 1 +
- 2 files changed, 135 insertions(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -300,6 +300,43 @@ static umode_t nvmem_bin_attr_is_visible
- return nvmem_bin_attr_get_umode(nvmem);
- }
-
-+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
-+ const char *id, int index);
-+
-+static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj,
-+ struct bin_attribute *attr, char *buf,
-+ loff_t pos, size_t count)
-+{
-+ struct nvmem_cell_entry *entry;
-+ struct nvmem_cell *cell = NULL;
-+ size_t cell_sz, read_len;
-+ void *content;
-+
-+ entry = attr->private;
-+ cell = nvmem_create_cell(entry, entry->name, 0);
-+ if (IS_ERR(cell))
-+ return PTR_ERR(cell);
-+
-+ if (!cell)
-+ return -EINVAL;
-+
-+ content = nvmem_cell_read(cell, &cell_sz);
-+ if (IS_ERR(content)) {
-+ read_len = PTR_ERR(content);
-+ goto destroy_cell;
-+ }
-+
-+ read_len = min_t(unsigned int, cell_sz - pos, count);
-+ memcpy(buf, content + pos, read_len);
-+ kfree(content);
-+
-+destroy_cell:
-+ kfree_const(cell->id);
-+ kfree(cell);
-+
-+ return read_len;
-+}
-+
- /* default read/write permissions */
- static struct bin_attribute bin_attr_rw_nvmem = {
- .attr = {
-@@ -321,11 +358,21 @@ static const struct attribute_group nvme
- .is_bin_visible = nvmem_bin_attr_is_visible,
- };
-
-+/* Cell attributes will be dynamically allocated */
-+static struct attribute_group nvmem_cells_group = {
-+ .name = "cells",
-+};
-+
- static const struct attribute_group *nvmem_dev_groups[] = {
- &nvmem_bin_group,
- NULL,
- };
-
-+static const struct attribute_group *nvmem_cells_groups[] = {
-+ &nvmem_cells_group,
-+ NULL,
-+};
-+
- static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
- .attr = {
- .name = "eeprom",
-@@ -381,6 +428,68 @@ static void nvmem_sysfs_remove_compat(st
- device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
- }
-
-+static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem)
-+{
-+ struct bin_attribute **cells_attrs, *attrs;
-+ struct nvmem_cell_entry *entry;
-+ unsigned int ncells = 0, i = 0;
-+ int ret = 0;
-+
-+ mutex_lock(&nvmem_mutex);
-+
-+ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) {
-+ nvmem_cells_group.bin_attrs = NULL;
-+ goto unlock_mutex;
-+ }
-+
-+ /* Allocate an array of attributes with a sentinel */
-+ ncells = list_count_nodes(&nvmem->cells);
-+ cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
-+ sizeof(struct bin_attribute *), GFP_KERNEL);
-+ if (!cells_attrs) {
-+ ret = -ENOMEM;
-+ goto unlock_mutex;
-+ }
-+
-+ attrs = devm_kcalloc(&nvmem->dev, ncells, sizeof(struct bin_attribute), GFP_KERNEL);
-+ if (!attrs) {
-+ ret = -ENOMEM;
-+ goto unlock_mutex;
-+ }
-+
-+ /* Initialize each attribute to take the name and size of the cell */
-+ list_for_each_entry(entry, &nvmem->cells, node) {
-+ sysfs_bin_attr_init(&attrs[i]);
-+ attrs[i].attr.name = devm_kasprintf(&nvmem->dev, GFP_KERNEL,
-+ "%s@%x", entry->name,
-+ entry->offset);
-+ attrs[i].attr.mode = 0444;
-+ attrs[i].size = entry->bytes;
-+ attrs[i].read = &nvmem_cell_attr_read;
-+ attrs[i].private = entry;
-+ if (!attrs[i].attr.name) {
-+ ret = -ENOMEM;
-+ goto unlock_mutex;
-+ }
-+
-+ cells_attrs[i] = &attrs[i];
-+ i++;
-+ }
-+
-+ nvmem_cells_group.bin_attrs = cells_attrs;
-+
-+ ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups);
-+ if (ret)
-+ goto unlock_mutex;
-+
-+ nvmem->sysfs_cells_populated = true;
-+
-+unlock_mutex:
-+ mutex_unlock(&nvmem_mutex);
-+
-+ return ret;
-+}
-+
- #else /* CONFIG_NVMEM_SYSFS */
-
- static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
-@@ -740,11 +849,25 @@ static int nvmem_add_cells_from_fixed_la
-
- int nvmem_layout_register(struct nvmem_layout *layout)
- {
-+ int ret;
-+
- if (!layout->add_cells)
- return -EINVAL;
-
- /* Populate the cells */
-- return layout->add_cells(&layout->nvmem->dev, layout->nvmem);
-+ ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem);
-+ if (ret)
-+ return ret;
-+
-+#ifdef CONFIG_NVMEM_SYSFS
-+ ret = nvmem_populate_sysfs_cells(layout->nvmem);
-+ if (ret) {
-+ nvmem_device_remove_all_cells(layout->nvmem);
-+ return ret;
-+ }
-+#endif
-+
-+ return 0;
- }
- EXPORT_SYMBOL_GPL(nvmem_layout_register);
-
-@@ -903,10 +1026,20 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_dev;
-
-+#ifdef CONFIG_NVMEM_SYSFS
-+ rval = nvmem_populate_sysfs_cells(nvmem);
-+ if (rval)
-+ goto err_destroy_layout;
-+#endif
-+
- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
-
- return nvmem;
-
-+#ifdef CONFIG_NVMEM_SYSFS
-+err_destroy_layout:
-+ nvmem_destroy_layout(nvmem);
-+#endif
- err_remove_dev:
- device_del(&nvmem->dev);
- err_remove_cells:
---- a/drivers/nvmem/internals.h
-+++ b/drivers/nvmem/internals.h
-@@ -32,6 +32,7 @@ struct nvmem_device {
- struct gpio_desc *wp_gpio;
- struct nvmem_layout *layout;
- void *priv;
-+ bool sysfs_cells_populated;
- };
-
- #if IS_ENABLED(CONFIG_OF)
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch b/target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch
deleted file mode 100644
index f686222f88..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From f0ac5b23039610619ca4a4805528553ecb6bc815 Mon Sep 17 00:00:00 2001
-From: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Date: Fri, 15 Dec 2023 11:15:36 +0000
-Subject: [PATCH] nvmem: stm32: add support for STM32MP25 BSEC to control OTP
- data
-
-On STM32MP25, OTP area may be read/written by using BSEC (boot, security
-and OTP control). The BSEC internal peripheral is only managed by the
-secure world.
-
-The 12 Kbits of OTP (effective) are organized into the following regions:
-- lower OTP (OTP0 to OTP127) = 4096 lower OTP bits,
- bitwise (1-bit) programmable
-- mid OTP (OTP128 to OTP255) = 4096 middle OTP bits,
- bulk (32-bit) programmable
-- upper OTP (OTP256 to OTP383) = 4096 upper OTP bits,
- bulk (32-bit) programmable,
- only accessible when BSEC is in closed state.
-
-As HWKEY and ECIES key are only accessible by ROM code;
-only 368 OTP words are managed in this driver (OTP0 to OTP267).
-
-This patch adds the STM32MP25 configuration for reading and writing
-the OTP data using the OP-TEE BSEC TA services.
-
-Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231215111536.316972-11-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/stm32-romem.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/drivers/nvmem/stm32-romem.c
-+++ b/drivers/nvmem/stm32-romem.c
-@@ -269,6 +269,19 @@ static const struct stm32_romem_cfg stm3
- .ta = true,
- };
-
-+/*
-+ * STM32MP25 BSEC OTP: 3 regions of 32-bits data words
-+ * lower OTP (OTP0 to OTP127), bitwise (1-bit) programmable
-+ * mid OTP (OTP128 to OTP255), bulk (32-bit) programmable
-+ * upper OTP (OTP256 to OTP383), bulk (32-bit) programmable
-+ * but no access to HWKEY and ECIES key: limited at OTP367
-+ */
-+static const struct stm32_romem_cfg stm32mp25_bsec_cfg = {
-+ .size = 368 * 4,
-+ .lower = 127,
-+ .ta = true,
-+};
-+
- static const struct of_device_id stm32_romem_of_match[] __maybe_unused = {
- { .compatible = "st,stm32f4-otp", }, {
- .compatible = "st,stm32mp15-bsec",
-@@ -276,6 +289,9 @@ static const struct of_device_id stm32_r
- }, {
- .compatible = "st,stm32mp13-bsec",
- .data = (void *)&stm32mp13_bsec_cfg,
-+ }, {
-+ .compatible = "st,stm32mp25-bsec",
-+ .data = (void *)&stm32mp25_bsec_cfg,
- },
- { /* sentinel */ },
- };
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch b/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
deleted file mode 100644
index 1bf3ba35b6..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 401df0d4f4098ecc9c5278da2f50756d62e5b37d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 19 Dec 2023 13:01:03 +0100
-Subject: [PATCH] nvmem: layouts: refactor .add_cells() callback arguments
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Simply pass whole "struct nvmem_layout" instead of single variables.
-There is nothing in "struct nvmem_layout" that we have to hide from
-layout drivers. They also access it during .probe() and .remove().
-
-Thanks to this change:
-
-1. API gets more consistent
- All layouts drivers callbacks get the same argument
-
-2. Layouts get correct device
- Before this change NVMEM core code was passing NVMEM device instead
- of layout device. That resulted in:
- * Confusing prints
- * Calling devm_*() helpers on wrong device
- * Helpers like of_device_get_match_data() dereferencing NULLs
-
-3. It gets possible to get match data
- First of all nvmem_layout_get_match_data() requires passing "struct
- nvmem_layout" which .add_cells() callback didn't have before this. It
- doesn't matter much as it's rather useless now anyway (and will be
- dropped).
- What's more important however is that of_device_get_match_data() can
- be used now thanks to owning a proper device pointer.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Link: https://lore.kernel.org/r/20231219120104.3422-1-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 2 +-
- drivers/nvmem/layouts/onie-tlv.c | 4 +++-
- drivers/nvmem/layouts/sl28vpd.c | 4 +++-
- include/linux/nvmem-provider.h | 2 +-
- 4 files changed, 8 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -855,7 +855,7 @@ int nvmem_layout_register(struct nvmem_l
- return -EINVAL;
-
- /* Populate the cells */
-- ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem);
-+ ret = layout->add_cells(layout);
- if (ret)
- return ret;
-
---- a/drivers/nvmem/layouts/onie-tlv.c
-+++ b/drivers/nvmem/layouts/onie-tlv.c
-@@ -182,8 +182,10 @@ static bool onie_tlv_crc_is_valid(struct
- return true;
- }
-
--static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem)
-+static int onie_tlv_parse_table(struct nvmem_layout *layout)
- {
-+ struct nvmem_device *nvmem = layout->nvmem;
-+ struct device *dev = &layout->dev;
- struct onie_tlv_hdr hdr;
- size_t table_len, data_len, hdr_len;
- u8 *table, *data;
---- a/drivers/nvmem/layouts/sl28vpd.c
-+++ b/drivers/nvmem/layouts/sl28vpd.c
-@@ -80,8 +80,10 @@ static int sl28vpd_v1_check_crc(struct d
- return 0;
- }
-
--static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem)
-+static int sl28vpd_add_cells(struct nvmem_layout *layout)
- {
-+ struct nvmem_device *nvmem = layout->nvmem;
-+ struct device *dev = &layout->dev;
- const struct nvmem_cell_info *pinfo;
- struct nvmem_cell_info info = {0};
- struct device_node *layout_np;
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -173,7 +173,7 @@ struct nvmem_cell_table {
- struct nvmem_layout {
- struct device dev;
- struct nvmem_device *nvmem;
-- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
-+ int (*add_cells)(struct nvmem_layout *layout);
- };
-
- struct nvmem_layout_driver {
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch b/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
deleted file mode 100644
index 514b5f2de5..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 43f60e3fb62edc7bd8891de8779fb422f4ae23ae Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 19 Dec 2023 13:01:04 +0100
-Subject: [PATCH] nvmem: drop nvmem_layout_get_match_data()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Thanks for layouts refactoring we now have "struct device" associated
-with layout. Also its OF pointer points directly to the "nvmem-layout"
-DT node.
-
-All it takes to get match data is a generic of_device_get_match_data().
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Michael Walle <michael@walle.cc>
-Link: https://lore.kernel.org/r/20231219120104.3422-2-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 13 -------------
- include/linux/nvmem-provider.h | 10 ----------
- 2 files changed, 23 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -877,19 +877,6 @@ void nvmem_layout_unregister(struct nvme
- }
- EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-
--const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
--{
-- struct device_node __maybe_unused *layout_np;
-- const struct of_device_id *match;
--
-- layout_np = of_nvmem_layout_get_container(nvmem);
-- match = of_match_node(layout->dev.driver->of_match_table, layout_np);
--
-- return match ? match->data : NULL;
--}
--EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data);
--
- /**
- * nvmem_register() - Register a nvmem device for given nvmem_config.
- * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -205,9 +205,6 @@ void nvmem_layout_driver_unregister(stru
- module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
- nvmem_layout_driver_unregister)
-
--const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout);
--
- #else
-
- static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
-@@ -238,13 +235,6 @@ static inline int nvmem_layout_register(
-
- static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {}
-
--static inline const void *
--nvmem_layout_get_match_data(struct nvmem_device *nvmem,
-- struct nvmem_layout *layout)
--{
-- return NULL;
--}
--
- #endif /* CONFIG_NVMEM */
-
- #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch b/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
deleted file mode 100644
index aa0bbaa0c5..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 33cf42e68efc8ff529a7eee08a4f0ba8c8d0a207 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:17 +0100
-Subject: [PATCH] nvmem: core: add nvmem_dev_size() helper
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is required by layouts that need to read whole NVMEM content. It's
-especially useful for NVMEM devices without hardcoded layout (like
-U-Boot environment data block).
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-2-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 13 +++++++++++++
- include/linux/nvmem-consumer.h | 1 +
- 2 files changed, 14 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -2164,6 +2164,19 @@ const char *nvmem_dev_name(struct nvmem_
- }
- EXPORT_SYMBOL_GPL(nvmem_dev_name);
-
-+/**
-+ * nvmem_dev_size() - Get the size of a given nvmem device.
-+ *
-+ * @nvmem: nvmem device.
-+ *
-+ * Return: size of the nvmem device.
-+ */
-+size_t nvmem_dev_size(struct nvmem_device *nvmem)
-+{
-+ return nvmem->size;
-+}
-+EXPORT_SYMBOL_GPL(nvmem_dev_size);
-+
- static int __init nvmem_init(void)
- {
- int ret;
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem
- struct nvmem_cell_info *info, void *buf);
-
- const char *nvmem_dev_name(struct nvmem_device *nvmem);
-+size_t nvmem_dev_size(struct nvmem_device *nvmem);
-
- void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries,
- size_t nentries);
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch b/target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch
deleted file mode 100644
index fc826f3f7e..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 7c8979b42b1a9c5604f431ba804928e55919263c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:18 +0100
-Subject: [PATCH] nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem
- helper
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Simplify adding NVMEM cells.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-3-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 55 +++++++++++++++-----------------------
- 1 file changed, 21 insertions(+), 34 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -23,13 +23,10 @@ enum u_boot_env_format {
-
- struct u_boot_env {
- struct device *dev;
-+ struct nvmem_device *nvmem;
- enum u_boot_env_format format;
-
- struct mtd_info *mtd;
--
-- /* Cells */
-- struct nvmem_cell_info *cells;
-- int ncells;
- };
-
- struct u_boot_env_image_single {
-@@ -94,43 +91,36 @@ static int u_boot_env_read_post_process_
- static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
- size_t data_offset, size_t data_len)
- {
-+ struct nvmem_device *nvmem = priv->nvmem;
- struct device *dev = priv->dev;
- char *data = buf + data_offset;
- char *var, *value, *eq;
-- int idx;
--
-- priv->ncells = 0;
-- for (var = data; var < data + data_len && *var; var += strlen(var) + 1)
-- priv->ncells++;
--
-- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
-- if (!priv->cells)
-- return -ENOMEM;
-
-- for (var = data, idx = 0;
-+ for (var = data;
- var < data + data_len && *var;
-- var = value + strlen(value) + 1, idx++) {
-+ var = value + strlen(value) + 1) {
-+ struct nvmem_cell_info info = {};
-+
- eq = strchr(var, '=');
- if (!eq)
- break;
- *eq = '\0';
- value = eq + 1;
-
-- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
-- if (!priv->cells[idx].name)
-+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
-+ if (!info.name)
- return -ENOMEM;
-- priv->cells[idx].offset = data_offset + value - data;
-- priv->cells[idx].bytes = strlen(value);
-- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-+ info.offset = data_offset + value - data;
-+ info.bytes = strlen(value);
-+ info.np = of_get_child_by_name(dev->of_node, info.name);
- if (!strcmp(var, "ethaddr")) {
-- priv->cells[idx].raw_len = strlen(value);
-- priv->cells[idx].bytes = ETH_ALEN;
-- priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
-+ info.raw_len = strlen(value);
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
- }
-- }
-
-- if (WARN_ON(idx != priv->ncells))
-- priv->ncells = idx;
-+ nvmem_add_one_cell(nvmem, &info);
-+ }
-
- return 0;
- }
-@@ -209,7 +199,6 @@ static int u_boot_env_probe(struct platf
- struct device *dev = &pdev->dev;
- struct device_node *np = dev->of_node;
- struct u_boot_env *priv;
-- int err;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -224,17 +213,15 @@ static int u_boot_env_probe(struct platf
- return PTR_ERR(priv->mtd);
- }
-
-- err = u_boot_env_parse(priv);
-- if (err)
-- return err;
--
- config.dev = dev;
-- config.cells = priv->cells;
-- config.ncells = priv->ncells;
- config.priv = priv;
- config.size = priv->mtd->size;
-
-- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
-+ priv->nvmem = devm_nvmem_register(dev, &config);
-+ if (IS_ERR(priv->nvmem))
-+ return PTR_ERR(priv->nvmem);
-+
-+ return u_boot_env_parse(priv);
- }
-
- static const struct of_device_id u_boot_env_of_match_table[] = {
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch b/target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch
deleted file mode 100644
index 70abc7cf14..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From a832556d23c5a11115f300011a5874d6107a0d62 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:19 +0100
-Subject: [PATCH] nvmem: u-boot-env: use nvmem device helpers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use nvmem_dev_size() and nvmem_device_read() to make this driver less
-mtd dependent.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-4-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 23 +++++++++++++++--------
- 1 file changed, 15 insertions(+), 8 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -127,27 +127,34 @@ static int u_boot_env_add_cells(struct u
-
- static int u_boot_env_parse(struct u_boot_env *priv)
- {
-+ struct nvmem_device *nvmem = priv->nvmem;
- struct device *dev = priv->dev;
- size_t crc32_data_offset;
- size_t crc32_data_len;
- size_t crc32_offset;
- size_t data_offset;
- size_t data_len;
-+ size_t dev_size;
- uint32_t crc32;
- uint32_t calc;
-- size_t bytes;
- uint8_t *buf;
-+ int bytes;
- int err;
-
-- buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
-+ dev_size = nvmem_dev_size(nvmem);
-+
-+ buf = kcalloc(1, dev_size, GFP_KERNEL);
- if (!buf) {
- err = -ENOMEM;
- goto err_out;
- }
-
-- err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
-- if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
-- dev_err(dev, "Failed to read from mtd: %d\n", err);
-+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
-+ if (bytes < 0) {
-+ err = bytes;
-+ goto err_kfree;
-+ } else if (bytes != dev_size) {
-+ err = -EIO;
- goto err_kfree;
- }
-
-@@ -169,8 +176,8 @@ static int u_boot_env_parse(struct u_boo
- break;
- }
- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-- crc32_data_len = priv->mtd->size - crc32_data_offset;
-- data_len = priv->mtd->size - data_offset;
-+ crc32_data_len = dev_size - crc32_data_offset;
-+ data_len = dev_size - data_offset;
-
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
- if (calc != crc32) {
-@@ -179,7 +186,7 @@ static int u_boot_env_parse(struct u_boo
- goto err_kfree;
- }
-
-- buf[priv->mtd->size - 1] = '\0';
-+ buf[dev_size - 1] = '\0';
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
- if (err)
- dev_err(dev, "Failed to add cells: %d\n", err);
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch b/target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch
deleted file mode 100644
index 273cfed874..0000000000
--- a/target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 6bafe07c930676d6430be471310958070816a595 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:20 +0100
-Subject: [PATCH] nvmem: u-boot-env: improve coding style
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Prefer kzalloc() over kcalloc()
- See memory-allocation.rst which says: "to be on the safe side it's
- best to use routines that set memory to zero, like kzalloc()"
-2. Drop dev_err() for u_boot_env_add_cells() fail
- It can fail only on -ENOMEM. We don't want to print error then.
-3. Add extra "crc32_addr" variable
- It makes code reading header's crc32 easier to understand / review.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-5-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -132,6 +132,7 @@ static int u_boot_env_parse(struct u_boo
- size_t crc32_data_offset;
- size_t crc32_data_len;
- size_t crc32_offset;
-+ __le32 *crc32_addr;
- size_t data_offset;
- size_t data_len;
- size_t dev_size;
-@@ -143,7 +144,7 @@ static int u_boot_env_parse(struct u_boo
-
- dev_size = nvmem_dev_size(nvmem);
-
-- buf = kcalloc(1, dev_size, GFP_KERNEL);
-+ buf = kzalloc(dev_size, GFP_KERNEL);
- if (!buf) {
- err = -ENOMEM;
- goto err_out;
-@@ -175,7 +176,8 @@ static int u_boot_env_parse(struct u_boo
- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
- break;
- }
-- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-+ crc32_addr = (__le32 *)(buf + crc32_offset);
-+ crc32 = le32_to_cpu(*crc32_addr);
- crc32_data_len = dev_size - crc32_data_offset;
- data_len = dev_size - data_offset;
-
-@@ -188,8 +190,6 @@ static int u_boot_env_parse(struct u_boo
-
- buf[dev_size - 1] = '\0';
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
-- if (err)
-- dev_err(dev, "Failed to add cells: %d\n", err);
-
- err_kfree:
- kfree(buf);
diff --git a/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch b/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch
deleted file mode 100644
index 3b68403690..0000000000
--- a/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 4bb7aac70b5d8a4bddf4ee0791b834f9f56883d2 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Thu, 20 Apr 2023 10:45:51 +0200
-Subject: [PATCH] net: phy: fix circular LEDS_CLASS dependencies
-
-The CONFIG_PHYLIB symbol is selected by a number of device drivers that
-need PHY support, but it now has a dependency on CONFIG_LEDS_CLASS,
-which may not be enabled, causing build failures.
-
-Avoid the risk of missing and circular dependencies by guarding the
-phylib LED support itself in another Kconfig symbol that can only be
-enabled if the dependency is met.
-
-This could be made a hidden symbol and always enabled when both CONFIG_OF
-and CONFIG_LEDS_CLASS are reachable from the phylib, but there may be an
-advantage in having users see this option when they have a misconfigured
-kernel without built-in LED support.
-
-Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs")
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20230420084624.3005701-1-arnd@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/Kconfig | 9 ++++++++-
- drivers/net/phy/phy_device.c | 3 ++-
- 2 files changed, 10 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -18,7 +18,6 @@ menuconfig PHYLIB
- depends on NETDEVICES
- select MDIO_DEVICE
- select MDIO_DEVRES
-- depends on LEDS_CLASS || LEDS_CLASS=n
- help
- Ethernet controllers are usually attached to PHY
- devices. This option provides infrastructure for
-@@ -45,6 +44,14 @@ config LED_TRIGGER_PHY
- <Speed in megabits>Mbps OR <Speed in gigabits>Gbps OR link
- for any speed known to the PHY.
-
-+config PHYLIB_LEDS
-+ bool "Support probing LEDs from device tree"
-+ depends on LEDS_CLASS=y || LEDS_CLASS=PHYLIB
-+ depends on OF
-+ default y
-+ help
-+ When LED class support is enabled, phylib can automatically
-+ probe LED setting from device tree.
-
- config FIXED_PHY
- tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs"
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3314,7 +3314,8 @@ static int phy_probe(struct device *dev)
- /* Get the LEDs from the device tree, and instantiate standard
- * LEDs for them.
- */
-- err = of_phy_leds(phydev);
-+ if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
-+ err = of_phy_leds(phydev);
-
- out:
- /* Re-assert the reset signal on error */
diff --git a/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch b/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch
deleted file mode 100644
index 622bb9e94a..0000000000
--- a/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From aed8fdad2152d946add50bec00a6b07c457bdcdf Mon Sep 17 00:00:00 2001
-From: Alexander Stein <alexander.stein@ew.tq-group.com>
-Date: Mon, 24 Apr 2023 16:16:48 +0200
-Subject: [PATCH] net: phy: Fix reading LED reg property
-
-'reg' is always encoded in 32 bits, thus it has to be read using the
-function with the corresponding bit width.
-
-Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs")
-Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Link: https://lore.kernel.org/r/20230424141648.317944-1-alexander.stein@ew.tq-group.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy_device.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3075,6 +3075,7 @@ static int of_phy_led(struct phy_device
- struct led_init_data init_data = {};
- struct led_classdev *cdev;
- struct phy_led *phyled;
-+ u32 index;
- int err;
-
- phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL);
-@@ -3084,10 +3085,13 @@ static int of_phy_led(struct phy_device
- cdev = &phyled->led_cdev;
- phyled->phydev = phydev;
-
-- err = of_property_read_u8(led, "reg", &phyled->index);
-+ err = of_property_read_u32(led, "reg", &index);
- if (err)
- return err;
-+ if (index > U8_MAX)
-+ return -EINVAL;
-
-+ phyled->index = index;
- if (phydev->drv->led_brightness_set)
- cdev->brightness_set_blocking = phy_led_set_brightness;
- if (phydev->drv->led_blink_set)
diff --git a/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch b/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch
deleted file mode 100644
index 80197e963b..0000000000
--- a/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From c938ab4da0eb1620ae3243b0b24c572ddfc318fc Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Sat, 17 Jun 2023 17:55:00 +0200
-Subject: [PATCH] net: phy: Manual remove LEDs to ensure correct ordering
-
-If the core is left to remove the LEDs via devm_, it is performed too
-late, after the PHY driver is removed from the PHY. This results in
-dereferencing a NULL pointer when the LED core tries to turn the LED
-off before destroying the LED.
-
-Manually unregister the LEDs at a safe point in phy_remove.
-
-Cc: stable@vger.kernel.org
-Reported-by: Florian Fainelli <f.fainelli@gmail.com>
-Suggested-by: Florian Fainelli <f.fainelli@gmail.com>
-Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs")
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/phy_device.c | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3068,6 +3068,15 @@ static int phy_led_blink_set(struct led_
- return err;
- }
-
-+static void phy_leds_unregister(struct phy_device *phydev)
-+{
-+ struct phy_led *phyled;
-+
-+ list_for_each_entry(phyled, &phydev->leds, list) {
-+ led_classdev_unregister(&phyled->led_cdev);
-+ }
-+}
-+
- static int of_phy_led(struct phy_device *phydev,
- struct device_node *led)
- {
-@@ -3101,7 +3110,7 @@ static int of_phy_led(struct phy_device
- init_data.fwnode = of_fwnode_handle(led);
- init_data.devname_mandatory = true;
-
-- err = devm_led_classdev_register_ext(dev, cdev, &init_data);
-+ err = led_classdev_register_ext(dev, cdev, &init_data);
- if (err)
- return err;
-
-@@ -3130,6 +3139,7 @@ static int of_phy_leds(struct phy_device
- err = of_phy_led(phydev, led);
- if (err) {
- of_node_put(led);
-+ phy_leds_unregister(phydev);
- return err;
- }
- }
-@@ -3335,6 +3345,9 @@ static int phy_remove(struct device *dev
-
- cancel_delayed_work_sync(&phydev->state_queue);
-
-+ if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
-+ phy_leds_unregister(phydev);
-+
- phydev->state = PHY_DOWN;
-
- sfp_bus_del_upstream(phydev->sfp_bus);
diff --git a/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch b/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch
deleted file mode 100644
index 609115b04a..0000000000
--- a/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From af7320ecae0ce646fd2c4a88341a3fbc243553da Mon Sep 17 00:00:00 2001
-From: Yang Li <yang.lee@linux.alibaba.com>
-Date: Thu, 11 May 2023 15:08:20 +0800
-Subject: [PATCH] leds: trigger: netdev: Remove NULL check before dev_{put,
- hold}
-
-The call netdev_{put, hold} of dev_{put, hold} will check NULL,
-so there is no need to check before using dev_{put, hold},
-remove it to silence the warnings:
-
-./drivers/leds/trigger/ledtrig-netdev.c:291:3-10: WARNING: NULL check before dev_{put, hold} functions is not needed.
-./drivers/leds/trigger/ledtrig-netdev.c:401:2-9: WARNING: NULL check before dev_{put, hold} functions is not needed.
-
-Reported-by: Abaci Robot <abaci@linux.alibaba.com>
-Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=4929
-Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
-Link: https://lore.kernel.org/r/20230511070820.52731-1-yang.lee@linux.alibaba.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -462,8 +462,7 @@ static int netdev_trig_notify(struct not
- get_device_state(trigger_data);
- fallthrough;
- case NETDEV_REGISTER:
-- if (trigger_data->net_dev)
-- dev_put(trigger_data->net_dev);
-+ dev_put(trigger_data->net_dev);
- dev_hold(dev);
- trigger_data->net_dev = dev;
- break;
-@@ -594,8 +593,7 @@ static void netdev_trig_deactivate(struc
-
- cancel_delayed_work_sync(&trigger_data->work);
-
-- if (trigger_data->net_dev)
-- dev_put(trigger_data->net_dev);
-+ dev_put(trigger_data->net_dev);
-
- kfree(trigger_data);
- }
diff --git a/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch b/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch
deleted file mode 100644
index 2f7a6ced90..0000000000
--- a/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 97c5209b3d374a25ebdb4c2ea9e9c1b121768da0 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@linaro.org>
-Date: Wed, 14 Jun 2023 10:03:59 +0300
-Subject: [PATCH] leds: trigger: netdev: uninitialized variable in
- netdev_trig_activate()
-
-The qca8k_cled_hw_control_get() function which implements ->hw_control_get
-sets the appropriate bits but does not clear them. This leads to an
-uninitialized variable bug. Fix this by setting mode to zero at the
-start.
-
-Fixes: e0256648c831 ("net: dsa: qca8k: implement hw_control ops")
-Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Lee Jones <lee@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/leds/trigger/ledtrig-netdev.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -538,7 +538,7 @@ static void netdev_trig_work(struct work
- static int netdev_trig_activate(struct led_classdev *led_cdev)
- {
- struct led_netdev_data *trigger_data;
-- unsigned long mode;
-+ unsigned long mode = 0;
- struct device *dev;
- int rc;
-
diff --git a/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch b/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch
deleted file mode 100644
index dedf84c64b..0000000000
--- a/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 7df1f14c04cbb1950e79c19793420f87227c3e80 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Tue, 8 Aug 2023 23:04:33 +0200
-Subject: [PATCH 1/4] led: trig: netdev: Fix requesting offload device
-
-When the netdev trigger is activates, it tries to determine what
-device the LED blinks for, and what the current blink mode is.
-
-The documentation for hw_control_get() says:
-
- * Return 0 on success, a negative error number on failing parsing the
- * initial mode. Error from this function is NOT FATAL as the device
- * may be in a not supported initial state by the attached LED trigger.
- */
-
-For the Marvell PHY and the Armada 370-rd board, the initial LED blink
-mode is not supported by the trigger, so it returns an error. This
-resulted in not getting the device the LED is blinking for. As a
-result, the device is unknown and offloaded is never performed.
-
-Change to condition to always get the device if offloading is
-supported, and reduce the scope of testing for an error from
-hw_control_get() to skip setting trigger internal state if there is an
-error.
-
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20230808210436.838995-2-andrew@lunn.ch
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -564,15 +564,17 @@ static int netdev_trig_activate(struct l
- /* Check if hw control is active by default on the LED.
- * Init already enabled mode in hw control.
- */
-- if (supports_hw_control(led_cdev) &&
-- !led_cdev->hw_control_get(led_cdev, &mode)) {
-+ if (supports_hw_control(led_cdev)) {
- dev = led_cdev->hw_control_get_device(led_cdev);
- if (dev) {
- const char *name = dev_name(dev);
-
- set_device_name(trigger_data, name, strlen(name));
- trigger_data->hw_control = true;
-- trigger_data->mode = mode;
-+
-+ rc = led_cdev->hw_control_get(led_cdev, &mode);
-+ if (!rc)
-+ trigger_data->mode = mode;
- }
- }
-
diff --git a/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
deleted file mode 100644
index 505513a53f..0000000000
--- a/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From 1dcc03c9a7a824a31eaaecdfaa03542fb25feb6c Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Tue, 8 Aug 2023 23:04:34 +0200
-Subject: [PATCH 2/4] net: phy: phy_device: Call into the PHY driver to set LED
- offload
-
-Linux LEDs can be requested to perform hardware accelerated blinking
-to indicate link, RX, TX etc. Pass the rules for blinking to the PHY
-driver, if it implements the ops needed to determine if a given
-pattern can be offloaded, to offload it, and what the current offload
-is. Additionally implement the op needed to get what device the LED is
-for.
-
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20230808210436.838995-3-andrew@lunn.ch
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy_device.c | 68 ++++++++++++++++++++++++++++++++++++
- include/linux/phy.h | 33 +++++++++++++++++
- 2 files changed, 101 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3068,6 +3068,61 @@ static int phy_led_blink_set(struct led_
- return err;
- }
-
-+static __maybe_unused struct device *
-+phy_led_hw_control_get_device(struct led_classdev *led_cdev)
-+{
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+
-+ if (phydev->attached_dev)
-+ return &phydev->attached_dev->dev;
-+ return NULL;
-+}
-+
-+static int __maybe_unused
-+phy_led_hw_control_get(struct led_classdev *led_cdev,
-+ unsigned long *rules)
-+{
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+ int err;
-+
-+ mutex_lock(&phydev->lock);
-+ err = phydev->drv->led_hw_control_get(phydev, phyled->index, rules);
-+ mutex_unlock(&phydev->lock);
-+
-+ return err;
-+}
-+
-+static int __maybe_unused
-+phy_led_hw_control_set(struct led_classdev *led_cdev,
-+ unsigned long rules)
-+{
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+ int err;
-+
-+ mutex_lock(&phydev->lock);
-+ err = phydev->drv->led_hw_control_set(phydev, phyled->index, rules);
-+ mutex_unlock(&phydev->lock);
-+
-+ return err;
-+}
-+
-+static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev,
-+ unsigned long rules)
-+{
-+ struct phy_led *phyled = to_phy_led(led_cdev);
-+ struct phy_device *phydev = phyled->phydev;
-+ int err;
-+
-+ mutex_lock(&phydev->lock);
-+ err = phydev->drv->led_hw_is_supported(phydev, phyled->index, rules);
-+ mutex_unlock(&phydev->lock);
-+
-+ return err;
-+}
-+
- static void phy_leds_unregister(struct phy_device *phydev)
- {
- struct phy_led *phyled;
-@@ -3105,6 +3160,19 @@ static int of_phy_led(struct phy_device
- cdev->brightness_set_blocking = phy_led_set_brightness;
- if (phydev->drv->led_blink_set)
- cdev->blink_set = phy_led_blink_set;
-+
-+#ifdef CONFIG_LEDS_TRIGGERS
-+ if (phydev->drv->led_hw_is_supported &&
-+ phydev->drv->led_hw_control_set &&
-+ phydev->drv->led_hw_control_get) {
-+ cdev->hw_control_is_supported = phy_led_hw_is_supported;
-+ cdev->hw_control_set = phy_led_hw_control_set;
-+ cdev->hw_control_get = phy_led_hw_control_get;
-+ cdev->hw_control_trigger = "netdev";
-+ }
-+
-+ cdev->hw_control_get_device = phy_led_hw_control_get_device;
-+#endif
- cdev->max_brightness = 1;
- init_data.devicename = dev_name(&phydev->mdio.dev);
- init_data.fwnode = of_fwnode_handle(led);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1026,6 +1026,39 @@ struct phy_driver {
- int (*led_blink_set)(struct phy_device *dev, u8 index,
- unsigned long *delay_on,
- unsigned long *delay_off);
-+ /**
-+ * @led_hw_is_supported: Can the HW support the given rules.
-+ * @dev: PHY device which has the LED
-+ * @index: Which LED of the PHY device
-+ * @rules The core is interested in these rules
-+ *
-+ * Return 0 if yes, -EOPNOTSUPP if not, or an error code.
-+ */
-+ int (*led_hw_is_supported)(struct phy_device *dev, u8 index,
-+ unsigned long rules);
-+ /**
-+ * @led_hw_control_set: Set the HW to control the LED
-+ * @dev: PHY device which has the LED
-+ * @index: Which LED of the PHY device
-+ * @rules The rules used to control the LED
-+ *
-+ * Returns 0, or a an error code.
-+ */
-+ int (*led_hw_control_set)(struct phy_device *dev, u8 index,
-+ unsigned long rules);
-+ /**
-+ * @led_hw_control_get: Get how the HW is controlling the LED
-+ * @dev: PHY device which has the LED
-+ * @index: Which LED of the PHY device
-+ * @rules Pointer to the rules used to control the LED
-+ *
-+ * Set *@rules to how the HW is currently blinking. Returns 0
-+ * on success, or a error code if the current blinking cannot
-+ * be represented in rules, or some other error happens.
-+ */
-+ int (*led_hw_control_get)(struct phy_device *dev, u8 index,
-+ unsigned long *rules);
-+
- };
- #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
- struct phy_driver, mdiodrv)
diff --git a/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch b/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch
deleted file mode 100644
index 1300583b66..0000000000
--- a/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch
+++ /dev/null
@@ -1,344 +0,0 @@
-From 460b0b648fab24f576c481424e0de5479ffb9786 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Tue, 8 Aug 2023 23:04:35 +0200
-Subject: [PATCH 3/4] net: phy: marvell: Add support for offloading LED
- blinking
-
-Add the code needed to indicate if a given blinking pattern can be
-offloaded, to offload a pattern and to try to return the current
-pattern.
-
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20230808210436.838995-4-andrew@lunn.ch
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/marvell.c | 281 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 281 insertions(+)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -2893,6 +2893,272 @@ static int m88e1318_led_blink_set(struct
- MII_88E1318S_PHY_LED_FUNC, reg);
- }
-
-+struct marvell_led_rules {
-+ int mode;
-+ unsigned long rules;
-+};
-+
-+static const struct marvell_led_rules marvell_led0[] = {
-+ {
-+ .mode = 0,
-+ .rules = BIT(TRIGGER_NETDEV_LINK),
-+ },
-+ {
-+ .mode = 1,
-+ .rules = (BIT(TRIGGER_NETDEV_LINK) |
-+ BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 3,
-+ .rules = (BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 4,
-+ .rules = (BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 5,
-+ .rules = BIT(TRIGGER_NETDEV_TX),
-+ },
-+ {
-+ .mode = 6,
-+ .rules = BIT(TRIGGER_NETDEV_LINK),
-+ },
-+ {
-+ .mode = 7,
-+ .rules = BIT(TRIGGER_NETDEV_LINK_1000),
-+ },
-+ {
-+ .mode = 8,
-+ .rules = 0,
-+ },
-+};
-+
-+static const struct marvell_led_rules marvell_led1[] = {
-+ {
-+ .mode = 1,
-+ .rules = (BIT(TRIGGER_NETDEV_LINK) |
-+ BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 2,
-+ .rules = (BIT(TRIGGER_NETDEV_LINK) |
-+ BIT(TRIGGER_NETDEV_RX)),
-+ },
-+ {
-+ .mode = 3,
-+ .rules = (BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 4,
-+ .rules = (BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 6,
-+ .rules = (BIT(TRIGGER_NETDEV_LINK_100) |
-+ BIT(TRIGGER_NETDEV_LINK_1000)),
-+ },
-+ {
-+ .mode = 7,
-+ .rules = BIT(TRIGGER_NETDEV_LINK_100),
-+ },
-+ {
-+ .mode = 8,
-+ .rules = 0,
-+ },
-+};
-+
-+static const struct marvell_led_rules marvell_led2[] = {
-+ {
-+ .mode = 0,
-+ .rules = BIT(TRIGGER_NETDEV_LINK),
-+ },
-+ {
-+ .mode = 1,
-+ .rules = (BIT(TRIGGER_NETDEV_LINK) |
-+ BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 3,
-+ .rules = (BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 4,
-+ .rules = (BIT(TRIGGER_NETDEV_RX) |
-+ BIT(TRIGGER_NETDEV_TX)),
-+ },
-+ {
-+ .mode = 5,
-+ .rules = BIT(TRIGGER_NETDEV_TX),
-+ },
-+ {
-+ .mode = 6,
-+ .rules = (BIT(TRIGGER_NETDEV_LINK_10) |
-+ BIT(TRIGGER_NETDEV_LINK_1000)),
-+ },
-+ {
-+ .mode = 7,
-+ .rules = BIT(TRIGGER_NETDEV_LINK_10),
-+ },
-+ {
-+ .mode = 8,
-+ .rules = 0,
-+ },
-+};
-+
-+static int marvell_find_led_mode(unsigned long rules,
-+ const struct marvell_led_rules *marvell_rules,
-+ int count,
-+ int *mode)
-+{
-+ int i;
-+
-+ for (i = 0; i < count; i++) {
-+ if (marvell_rules[i].rules == rules) {
-+ *mode = marvell_rules[i].mode;
-+ return 0;
-+ }
-+ }
-+ return -EOPNOTSUPP;
-+}
-+
-+static int marvell_get_led_mode(u8 index, unsigned long rules, int *mode)
-+{
-+ int ret;
-+
-+ switch (index) {
-+ case 0:
-+ ret = marvell_find_led_mode(rules, marvell_led0,
-+ ARRAY_SIZE(marvell_led0), mode);
-+ break;
-+ case 1:
-+ ret = marvell_find_led_mode(rules, marvell_led1,
-+ ARRAY_SIZE(marvell_led1), mode);
-+ break;
-+ case 2:
-+ ret = marvell_find_led_mode(rules, marvell_led2,
-+ ARRAY_SIZE(marvell_led2), mode);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static int marvell_find_led_rules(unsigned long *rules,
-+ const struct marvell_led_rules *marvell_rules,
-+ int count,
-+ int mode)
-+{
-+ int i;
-+
-+ for (i = 0; i < count; i++) {
-+ if (marvell_rules[i].mode == mode) {
-+ *rules = marvell_rules[i].rules;
-+ return 0;
-+ }
-+ }
-+ return -EOPNOTSUPP;
-+}
-+
-+static int marvell_get_led_rules(u8 index, unsigned long *rules, int mode)
-+{
-+ int ret;
-+
-+ switch (index) {
-+ case 0:
-+ ret = marvell_find_led_rules(rules, marvell_led0,
-+ ARRAY_SIZE(marvell_led0), mode);
-+ break;
-+ case 1:
-+ ret = marvell_find_led_rules(rules, marvell_led1,
-+ ARRAY_SIZE(marvell_led1), mode);
-+ break;
-+ case 2:
-+ ret = marvell_find_led_rules(rules, marvell_led2,
-+ ARRAY_SIZE(marvell_led2), mode);
-+ break;
-+ default:
-+ ret = -EOPNOTSUPP;
-+ }
-+
-+ return ret;
-+}
-+
-+static int m88e1318_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ int mode, ret;
-+
-+ switch (index) {
-+ case 0:
-+ case 1:
-+ case 2:
-+ ret = marvell_get_led_mode(index, rules, &mode);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static int m88e1318_led_hw_control_set(struct phy_device *phydev, u8 index,
-+ unsigned long rules)
-+{
-+ int mode, ret, reg;
-+
-+ switch (index) {
-+ case 0:
-+ case 1:
-+ case 2:
-+ ret = marvell_get_led_mode(index, rules, &mode);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ }
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC);
-+ if (reg < 0)
-+ return reg;
-+
-+ reg &= ~(0xf << (4 * index));
-+ reg |= mode << (4 * index);
-+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC, reg);
-+}
-+
-+static int m88e1318_led_hw_control_get(struct phy_device *phydev, u8 index,
-+ unsigned long *rules)
-+{
-+ int mode, reg;
-+
-+ if (index > 2)
-+ return -EINVAL;
-+
-+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
-+ MII_88E1318S_PHY_LED_FUNC);
-+ if (reg < 0)
-+ return reg;
-+
-+ mode = (reg >> (4 * index)) & 0xf;
-+
-+ return marvell_get_led_rules(index, rules, mode);
-+}
-+
- static int marvell_probe(struct phy_device *phydev)
- {
- struct marvell_priv *priv;
-@@ -3144,6 +3410,9 @@ static struct phy_driver marvell_drivers
- .get_stats = marvell_get_stats,
- .led_brightness_set = m88e1318_led_brightness_set,
- .led_blink_set = m88e1318_led_blink_set,
-+ .led_hw_is_supported = m88e1318_led_hw_is_supported,
-+ .led_hw_control_set = m88e1318_led_hw_control_set,
-+ .led_hw_control_get = m88e1318_led_hw_control_get,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1145,
-@@ -3252,6 +3521,9 @@ static struct phy_driver marvell_drivers
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
- .led_blink_set = m88e1318_led_blink_set,
-+ .led_hw_is_supported = m88e1318_led_hw_is_supported,
-+ .led_hw_control_set = m88e1318_led_hw_control_set,
-+ .led_hw_control_get = m88e1318_led_hw_control_get,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1540,
-@@ -3280,6 +3552,9 @@ static struct phy_driver marvell_drivers
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
- .led_blink_set = m88e1318_led_blink_set,
-+ .led_hw_is_supported = m88e1318_led_hw_is_supported,
-+ .led_hw_control_set = m88e1318_led_hw_control_set,
-+ .led_hw_control_get = m88e1318_led_hw_control_get,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E1545,
-@@ -3308,6 +3583,9 @@ static struct phy_driver marvell_drivers
- .cable_test_get_status = marvell_vct7_cable_test_get_status,
- .led_brightness_set = m88e1318_led_brightness_set,
- .led_blink_set = m88e1318_led_blink_set,
-+ .led_hw_is_supported = m88e1318_led_hw_is_supported,
-+ .led_hw_control_set = m88e1318_led_hw_control_set,
-+ .led_hw_control_get = m88e1318_led_hw_control_get,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E3016,
-@@ -3451,6 +3729,9 @@ static struct phy_driver marvell_drivers
- .set_tunable = m88e1540_set_tunable,
- .led_brightness_set = m88e1318_led_brightness_set,
- .led_blink_set = m88e1318_led_blink_set,
-+ .led_hw_is_supported = m88e1318_led_hw_is_supported,
-+ .led_hw_control_set = m88e1318_led_hw_control_set,
-+ .led_hw_control_get = m88e1318_led_hw_control_get,
- },
- };
-
diff --git a/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch b/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch
deleted file mode 100644
index d6a69aa9ca..0000000000
--- a/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From e8fbcc47a8e935f36f044d85f21a99acecbd7bfb Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Tue, 8 Aug 2023 23:04:36 +0200
-Subject: [PATCH 4/4] leds: trig-netdev: Disable offload on deactivation of
- trigger
-
-Ensure that the offloading of blinking is stopped when the trigger is
-deactivated. Calling led_set_brightness() is documented as stopping
-offload and setting the LED to a constant brightness.
-
-Suggested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20230808210436.838995-5-andrew@lunn.ch
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -595,6 +595,8 @@ static void netdev_trig_deactivate(struc
-
- cancel_delayed_work_sync(&trigger_data->work);
-
-+ led_set_brightness(led_cdev, LED_OFF);
-+
- dev_put(trigger_data->net_dev);
-
- kfree(trigger_data);
diff --git a/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch b/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch
deleted file mode 100644
index f568c3f6ce..0000000000
--- a/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From c5d264d4b527c96ae8903376a4b195df47b05203 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:43 +0000
-Subject: [PATCH] of: base: add of_parse_phandle_with_optional_args()
-
-Add a new variant of the of_parse_phandle_with_args() which treats the
-cells name as optional. If it's missing, it is assumed that the phandle
-has no arguments.
-
-Up until now, a nvmem node didn't have any arguments, so all the device
-trees haven't any '#*-cells' property. But there is a need for an
-additional argument for the phandle, for which we need a '#*-cells'
-property. Therefore, we need to support nvmem nodes with and without
-this property.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/linux/of.h | 25 +++++++++++++++++++++++++
- 1 file changed, 25 insertions(+)
-
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -1009,6 +1009,31 @@ static inline int of_parse_phandle_with_
- }
-
- /**
-+ * of_parse_phandle_with_optional_args() - Find a node pointed by phandle in a list
-+ * @np: pointer to a device tree node containing a list
-+ * @list_name: property name that contains a list
-+ * @cells_name: property name that specifies phandles' arguments count
-+ * @index: index of a phandle to parse out
-+ * @out_args: optional pointer to output arguments structure (will be filled)
-+ *
-+ * Same as of_parse_phandle_with_args() except that if the cells_name property
-+ * is not found, cell_count of 0 is assumed.
-+ *
-+ * This is used to useful, if you have a phandle which didn't have arguments
-+ * before and thus doesn't have a '#*-cells' property but is now migrated to
-+ * having arguments while retaining backwards compatibility.
-+ */
-+static inline int of_parse_phandle_with_optional_args(const struct device_node *np,
-+ const char *list_name,
-+ const char *cells_name,
-+ int index,
-+ struct of_phandle_args *out_args)
-+{
-+ return __of_parse_phandle_with_args(np, list_name, cells_name,
-+ 0, index, out_args);
-+}
-+
-+/**
- * of_property_count_u8_elems - Count the number of u8 elements in a property
- *
- * @np: device node from which the property value is to be read.
diff --git a/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch b/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch
deleted file mode 100644
index 66c29126b6..0000000000
--- a/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From ff24fed10ba414d19579e26e60b126fad2f2bb07 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:44 +0000
-Subject: [PATCH] of: property: make #.*-cells optional for simple props
-
-Sometimes, future bindings for phandles will get additional arguments.
-Thus the target node of the phandle will need a new #.*-cells property.
-To be backwards compatible, this needs to be optional.
-
-Prepare the DEFINE_SIMPLE_PROPS() to handle the cells name as optional.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Tested-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-11-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/property.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/of/property.c
-+++ b/drivers/of/property.c
-@@ -1146,8 +1146,8 @@ static struct device_node *parse_prop_ce
- if (strcmp(prop_name, list_name))
- return NULL;
-
-- if (of_parse_phandle_with_args(np, list_name, cells_name, index,
-- &sup_args))
-+ if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
-+ &sup_args))
- return NULL;
-
- return sup_args.np;
diff --git a/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch b/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch
deleted file mode 100644
index 07354d7da7..0000000000
--- a/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From e2d8172043d2e50df19fcd59c11e5593de8188d7 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 6 Feb 2023 13:43:45 +0000
-Subject: [PATCH] of: property: add #nvmem-cell-cells property
-
-Bindings describe the new '#nvmem-cell-cells' property. Now that the
-arguments count property is optional, we just add this property to the
-nvmem-cells.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Tested-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230206134356.839737-12-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/property.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/of/property.c
-+++ b/drivers/of/property.c
-@@ -1251,7 +1251,7 @@ DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-c
- DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells")
- DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells")
- DEFINE_SIMPLE_PROP(extcon, "extcon", NULL)
--DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", NULL)
-+DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells")
- DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells")
- DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL)
- DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL)
diff --git a/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch b/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch
deleted file mode 100644
index 8dc370618e..0000000000
--- a/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 553bd29700145e1849698985e9800f14e967da49 Mon Sep 17 00:00:00 2001
-From: Alexander Stein <alexander.stein@ew.tq-group.com>
-Date: Tue, 7 Feb 2023 12:05:29 +0100
-Subject: [PATCH] of: device: Ignore modalias of reused nodes
-
-If of_node is reused, do not use that node's modalias. This will hide
-the name of the actual device. This is rather prominent in USB glue
-drivers creating a platform device for the host controller.
-
-Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20230207110531.1060252-2-alexander.stein@ew.tq-group.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -256,7 +256,7 @@ static ssize_t of_device_get_modalias(st
- ssize_t csize;
- ssize_t tsize;
-
-- if ((!dev) || (!dev->of_node))
-+ if ((!dev) || (!dev->of_node) || dev->of_node_reused)
- return -ENODEV;
-
- /* Name & Type */
-@@ -379,7 +379,7 @@ int of_device_uevent_modalias(struct dev
- {
- int sl;
-
-- if ((!dev) || (!dev->of_node))
-+ if ((!dev) || (!dev->of_node) || dev->of_node_reused)
- return -ENODEV;
-
- /* Devicetree modalias is tricky, we add it in 2 steps */
diff --git a/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch b/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch
deleted file mode 100644
index dcdc2313ba..0000000000
--- a/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 2295bed9bebe8d1eef276194fed5b5fbe89c5363 Mon Sep 17 00:00:00 2001
-From: Alexander Stein <alexander.stein@ew.tq-group.com>
-Date: Tue, 7 Feb 2023 12:05:30 +0100
-Subject: [PATCH] of: device: Do not ignore error code in
- of_device_uevent_modalias
-
-of_device_get_modalias might return an error code, propagate that one.
-Otherwise the negative, signed integer is propagated to unsigned integer
-for the comparison resulting in a huge 'sl' size.
-
-Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20230207110531.1060252-3-alexander.stein@ew.tq-group.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -388,6 +388,8 @@ int of_device_uevent_modalias(struct dev
-
- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
- sizeof(env->buf) - env->buflen);
-+ if (sl < 0)
-+ return sl;
- if (sl >= (sizeof(env->buf) - env->buflen))
- return -ENOMEM;
- env->buflen += sl;
diff --git a/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch b/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch
deleted file mode 100644
index 280ed9085c..0000000000
--- a/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 5c3d15e127ebfc0754cd18def7124633b6d46672 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:15 +0100
-Subject: [PATCH] of: Update of_device_get_modalias()
-
-This function only needs a "struct device_node" to work, but for
-convenience the author (and only user) of this helper did use a "struct
-device" and put it in device.c.
-
-Let's convert this helper to take a "struct device node" instead. This
-change asks for two additional changes: renaming it "of_modalias()"
-to fit the current naming, and moving it outside of device.c which will
-be done in a follow-up commit.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-8-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 29 +++++++++++++++++------------
- 1 file changed, 17 insertions(+), 12 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -248,7 +248,7 @@ const void *of_device_get_match_data(con
- }
- EXPORT_SYMBOL(of_device_get_match_data);
-
--static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
-+static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
- {
- const char *compat;
- char *c;
-@@ -256,19 +256,16 @@ static ssize_t of_device_get_modalias(st
- ssize_t csize;
- ssize_t tsize;
-
-- if ((!dev) || (!dev->of_node) || dev->of_node_reused)
-- return -ENODEV;
--
- /* Name & Type */
- /* %p eats all alphanum characters, so %c must be used here */
-- csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
-- of_node_get_device_type(dev->of_node));
-+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
-+ of_node_get_device_type(np));
- tsize = csize;
- len -= csize;
- if (str)
- str += csize;
-
-- of_property_for_each_string(dev->of_node, "compatible", p, compat) {
-+ of_property_for_each_string(np, "compatible", p, compat) {
- csize = strlen(compat) + 1;
- tsize += csize;
- if (csize > len)
-@@ -293,7 +290,10 @@ int of_device_request_module(struct devi
- ssize_t size;
- int ret;
-
-- size = of_device_get_modalias(dev, NULL, 0);
-+ if (!dev || !dev->of_node)
-+ return -ENODEV;
-+
-+ size = of_modalias(dev->of_node, NULL, 0);
- if (size < 0)
- return size;
-
-@@ -304,7 +304,7 @@ int of_device_request_module(struct devi
- if (!str)
- return -ENOMEM;
-
-- of_device_get_modalias(dev, str, size);
-+ of_modalias(dev->of_node, str, size);
- str[size - 1] = '\0';
- ret = request_module(str);
- kfree(str);
-@@ -321,7 +321,12 @@ EXPORT_SYMBOL_GPL(of_device_request_modu
- */
- ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
- {
-- ssize_t sl = of_device_get_modalias(dev, str, len - 2);
-+ ssize_t sl;
-+
-+ if (!dev || !dev->of_node || dev->of_node_reused)
-+ return -ENODEV;
-+
-+ sl = of_modalias(dev->of_node, str, len - 2);
- if (sl < 0)
- return sl;
- if (sl > len - 2)
-@@ -386,8 +391,8 @@ int of_device_uevent_modalias(struct dev
- if (add_uevent_var(env, "MODALIAS="))
- return -ENOMEM;
-
-- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
-- sizeof(env->buf) - env->buflen);
-+ sl = of_modalias(dev->of_node, &env->buf[env->buflen-1],
-+ sizeof(env->buf) - env->buflen);
- if (sl < 0)
- return sl;
- if (sl >= (sizeof(env->buf) - env->buflen))
diff --git a/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch
deleted file mode 100644
index c11ccc6c3e..0000000000
--- a/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 673aa1ed1c9b6710bf24e3f0957d85e2f46c77db Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:16 +0100
-Subject: [PATCH] of: Rename of_modalias_node()
-
-This helper does not produce a real modalias, but tries to get the
-"product" compatible part of the "vendor,product" compatibles only. It
-is far from creating a purely useful modalias string and does not seem
-to be used like that directly anyway, so let's try to give this helper a
-more meaningful name before moving there a real modalias helper (already
-existing under of/device.c).
-
-Also update the various documentations to refer to the strings as
-"aliases" rather than "modaliases" which has a real meaning in the Linux
-kernel.
-
-There is no functional change.
-
-Cc: Rafael J. Wysocki <rafael@kernel.org>
-Cc: Len Brown <lenb@kernel.org>
-Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Cc: Maxime Ripard <mripard@kernel.org>
-Cc: Thomas Zimmermann <tzimmermann@suse.de>
-Cc: Sebastian Reichel <sre@kernel.org>
-Cc: Wolfram Sang <wsa@kernel.org>
-Cc: Mark Brown <broonie@kernel.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Acked-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Acked-by: Sebastian Reichel <sre@kernel.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-9-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/acpi/bus.c | 7 ++++---
- drivers/gpu/drm/drm_mipi_dsi.c | 2 +-
- drivers/hsi/hsi_core.c | 2 +-
- drivers/i2c/busses/i2c-powermac.c | 2 +-
- drivers/i2c/i2c-core-of.c | 2 +-
- drivers/of/base.c | 18 +++++++++++-------
- drivers/spi/spi.c | 4 ++--
- include/linux/of.h | 3 ++-
- 8 files changed, 23 insertions(+), 17 deletions(-)
-
---- a/drivers/acpi/bus.c
-+++ b/drivers/acpi/bus.c
-@@ -806,9 +806,10 @@ static bool acpi_of_modalias(struct acpi
- * @modalias: Pointer to buffer that modalias value will be copied into
- * @len: Length of modalias buffer
- *
-- * This is a counterpart of of_modalias_node() for struct acpi_device objects.
-- * If there is a compatible string for @adev, it will be copied to @modalias
-- * with the vendor prefix stripped; otherwise, @default_id will be used.
-+ * This is a counterpart of of_alias_from_compatible() for struct acpi_device
-+ * objects. If there is a compatible string for @adev, it will be copied to
-+ * @modalias with the vendor prefix stripped; otherwise, @default_id will be
-+ * used.
- */
- void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
- char *modalias, size_t len)
---- a/drivers/gpu/drm/drm_mipi_dsi.c
-+++ b/drivers/gpu/drm/drm_mipi_dsi.c
-@@ -160,7 +160,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_h
- int ret;
- u32 reg;
-
-- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
-+ if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) {
- drm_err(host, "modalias failure on %pOF\n", node);
- return ERR_PTR(-EINVAL);
- }
---- a/drivers/hsi/hsi_core.c
-+++ b/drivers/hsi/hsi_core.c
-@@ -207,7 +207,7 @@ static void hsi_add_client_from_dt(struc
- if (!cl)
- return;
-
-- err = of_modalias_node(client, name, sizeof(name));
-+ err = of_alias_from_compatible(client, name, sizeof(name));
- if (err)
- goto err;
-
---- a/drivers/i2c/busses/i2c-powermac.c
-+++ b/drivers/i2c/busses/i2c-powermac.c
-@@ -284,7 +284,7 @@ static bool i2c_powermac_get_type(struct
- */
-
- /* First try proper modalias */
-- if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) {
-+ if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) {
- snprintf(type, type_size, "MAC,%s", tmp);
- return true;
- }
---- a/drivers/i2c/i2c-core-of.c
-+++ b/drivers/i2c/i2c-core-of.c
-@@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device
-
- memset(info, 0, sizeof(*info));
-
-- if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) {
-+ if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) {
- dev_err(dev, "of_i2c: modalias failure on %pOF\n", node);
- return -EINVAL;
- }
---- a/drivers/of/base.c
-+++ b/drivers/of/base.c
-@@ -1208,19 +1208,23 @@ struct device_node *of_find_matching_nod
- EXPORT_SYMBOL(of_find_matching_node_and_match);
-
- /**
-- * of_modalias_node - Lookup appropriate modalias for a device node
-+ * of_alias_from_compatible - Lookup appropriate alias for a device node
-+ * depending on compatible
- * @node: pointer to a device tree node
-- * @modalias: Pointer to buffer that modalias value will be copied into
-- * @len: Length of modalias value
-+ * @alias: Pointer to buffer that alias value will be copied into
-+ * @len: Length of alias value
- *
- * Based on the value of the compatible property, this routine will attempt
-- * to choose an appropriate modalias value for a particular device tree node.
-+ * to choose an appropriate alias value for a particular device tree node.
- * It does this by stripping the manufacturer prefix (as delimited by a ',')
- * from the first entry in the compatible list property.
- *
-+ * Note: The matching on just the "product" side of the compatible is a relic
-+ * from I2C and SPI. Please do not add any new user.
-+ *
- * Return: This routine returns 0 on success, <0 on failure.
- */
--int of_modalias_node(struct device_node *node, char *modalias, int len)
-+int of_alias_from_compatible(const struct device_node *node, char *alias, int len)
- {
- const char *compatible, *p;
- int cplen;
-@@ -1229,10 +1233,10 @@ int of_modalias_node(struct device_node
- if (!compatible || strlen(compatible) > cplen)
- return -ENODEV;
- p = strchr(compatible, ',');
-- strscpy(modalias, p ? p + 1 : compatible, len);
-+ strscpy(alias, p ? p + 1 : compatible, len);
- return 0;
- }
--EXPORT_SYMBOL_GPL(of_modalias_node);
-+EXPORT_SYMBOL_GPL(of_alias_from_compatible);
-
- /**
- * of_find_node_by_phandle - Find a node given a phandle
---- a/drivers/spi/spi.c
-+++ b/drivers/spi/spi.c
-@@ -2334,8 +2334,8 @@ of_register_spi_device(struct spi_contro
- }
-
- /* Select device driver */
-- rc = of_modalias_node(nc, spi->modalias,
-- sizeof(spi->modalias));
-+ rc = of_alias_from_compatible(nc, spi->modalias,
-+ sizeof(spi->modalias));
- if (rc < 0) {
- dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc);
- goto err_out;
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -362,7 +362,8 @@ extern int of_n_addr_cells(struct device
- extern int of_n_size_cells(struct device_node *np);
- extern const struct of_device_id *of_match_node(
- const struct of_device_id *matches, const struct device_node *node);
--extern int of_modalias_node(struct device_node *node, char *modalias, int len);
-+extern int of_alias_from_compatible(const struct device_node *node, char *alias,
-+ int len);
- extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args);
- extern int __of_parse_phandle_with_args(const struct device_node *np,
- const char *list_name, const char *cells_name, int cell_count,
diff --git a/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch
deleted file mode 100644
index 39a84161a2..0000000000
--- a/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From bd7a7ed774afd1a4174df34227626c95573be517 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:17 +0100
-Subject: [PATCH] of: Move of_modalias() to module.c
-
-Create a specific .c file for OF related module handling.
-Move of_modalias() inside as a first step.
-
-The helper is exposed through of.h even though it is only used by core
-files because the users from device.c will soon be split into an OF-only
-helper in module.c as well as a device-oriented inline helper in
-of_device.h. Putting this helper in of_private.h would require to
-include of_private.h from of_device.h, which is not acceptable.
-
-Suggested-by: Rob Herring <robh+dt@kernel.org>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-10-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/Makefile | 2 +-
- drivers/of/device.c | 37 -------------------------------------
- drivers/of/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
- include/linux/of.h | 9 +++++++++
- 4 files changed, 54 insertions(+), 38 deletions(-)
- create mode 100644 drivers/of/module.c
-
---- a/drivers/of/Makefile
-+++ b/drivers/of/Makefile
-@@ -1,5 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
--obj-y = base.o device.o platform.o property.o
-+obj-y = base.o device.o module.o platform.o property.o
- obj-$(CONFIG_OF_KOBJ) += kobj.o
- obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
- obj-$(CONFIG_OF_FLATTREE) += fdt.o
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -1,5 +1,4 @@
- // SPDX-License-Identifier: GPL-2.0
--#include <linux/string.h>
- #include <linux/kernel.h>
- #include <linux/of.h>
- #include <linux/of_device.h>
-@@ -248,42 +247,6 @@ const void *of_device_get_match_data(con
- }
- EXPORT_SYMBOL(of_device_get_match_data);
-
--static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
--{
-- const char *compat;
-- char *c;
-- struct property *p;
-- ssize_t csize;
-- ssize_t tsize;
--
-- /* Name & Type */
-- /* %p eats all alphanum characters, so %c must be used here */
-- csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
-- of_node_get_device_type(np));
-- tsize = csize;
-- len -= csize;
-- if (str)
-- str += csize;
--
-- of_property_for_each_string(np, "compatible", p, compat) {
-- csize = strlen(compat) + 1;
-- tsize += csize;
-- if (csize > len)
-- continue;
--
-- csize = snprintf(str, len, "C%s", compat);
-- for (c = str; c; ) {
-- c = strchr(c, ' ');
-- if (c)
-- *c++ = '_';
-- }
-- len -= csize;
-- str += csize;
-- }
--
-- return tsize;
--}
--
- int of_device_request_module(struct device *dev)
- {
- char *str;
---- /dev/null
-+++ b/drivers/of/module.c
-@@ -0,0 +1,44 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Linux kernel module helpers.
-+ */
-+
-+#include <linux/of.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+
-+ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
-+{
-+ const char *compat;
-+ char *c;
-+ struct property *p;
-+ ssize_t csize;
-+ ssize_t tsize;
-+
-+ /* Name & Type */
-+ /* %p eats all alphanum characters, so %c must be used here */
-+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
-+ of_node_get_device_type(np));
-+ tsize = csize;
-+ len -= csize;
-+ if (str)
-+ str += csize;
-+
-+ of_property_for_each_string(np, "compatible", p, compat) {
-+ csize = strlen(compat) + 1;
-+ tsize += csize;
-+ if (csize > len)
-+ continue;
-+
-+ csize = snprintf(str, len, "C%s", compat);
-+ for (c = str; c; ) {
-+ c = strchr(c, ' ');
-+ if (c)
-+ *c++ = '_';
-+ }
-+ len -= csize;
-+ str += csize;
-+ }
-+
-+ return tsize;
-+}
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -374,6 +374,9 @@ extern int of_parse_phandle_with_args_ma
- extern int of_count_phandle_with_args(const struct device_node *np,
- const char *list_name, const char *cells_name);
-
-+/* module functions */
-+extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len);
-+
- /* phandle iterator functions */
- extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
- const struct device_node *np,
-@@ -731,6 +734,12 @@ static inline int of_count_phandle_with_
- return -ENOSYS;
- }
-
-+static inline ssize_t of_modalias(const struct device_node *np, char *str,
-+ ssize_t len)
-+{
-+ return -ENODEV;
-+}
-+
- static inline int of_phandle_iterator_init(struct of_phandle_iterator *it,
- const struct device_node *np,
- const char *list_name,
diff --git a/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch
deleted file mode 100644
index 046c1df561..0000000000
--- a/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From e6506f06d5e82765666902ccf9e9162f3e31d518 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Tue, 4 Apr 2023 18:21:18 +0100
-Subject: [PATCH] of: Move the request module helper logic to module.c
-
-Depending on device.c for pure OF handling is considered
-backwards. Let's extract the content of of_device_request_module() to
-have the real logic under module.c.
-
-The next step will be to convert users of of_device_request_module() to
-use the new helper.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20230404172148.82422-11-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/of/device.c | 25 ++-----------------------
- drivers/of/module.c | 30 ++++++++++++++++++++++++++++++
- include/linux/of.h | 6 ++++++
- 3 files changed, 38 insertions(+), 23 deletions(-)
-
---- a/drivers/of/device.c
-+++ b/drivers/of/device.c
-@@ -8,7 +8,6 @@
- #include <linux/dma-direct.h> /* for bus_dma_region */
- #include <linux/dma-map-ops.h>
- #include <linux/init.h>
--#include <linux/module.h>
- #include <linux/mod_devicetable.h>
- #include <linux/slab.h>
- #include <linux/platform_device.h>
-@@ -249,30 +248,10 @@ EXPORT_SYMBOL(of_device_get_match_data);
-
- int of_device_request_module(struct device *dev)
- {
-- char *str;
-- ssize_t size;
-- int ret;
--
-- if (!dev || !dev->of_node)
-+ if (!dev)
- return -ENODEV;
-
-- size = of_modalias(dev->of_node, NULL, 0);
-- if (size < 0)
-- return size;
--
-- /* Reserve an additional byte for the trailing '\0' */
-- size++;
--
-- str = kmalloc(size, GFP_KERNEL);
-- if (!str)
-- return -ENOMEM;
--
-- of_modalias(dev->of_node, str, size);
-- str[size - 1] = '\0';
-- ret = request_module(str);
-- kfree(str);
--
-- return ret;
-+ return of_request_module(dev->of_node);
- }
- EXPORT_SYMBOL_GPL(of_device_request_module);
-
---- a/drivers/of/module.c
-+++ b/drivers/of/module.c
-@@ -4,6 +4,7 @@
- */
-
- #include <linux/of.h>
-+#include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/string.h>
-
-@@ -42,3 +43,32 @@ ssize_t of_modalias(const struct device_
-
- return tsize;
- }
-+
-+int of_request_module(const struct device_node *np)
-+{
-+ char *str;
-+ ssize_t size;
-+ int ret;
-+
-+ if (!np)
-+ return -ENODEV;
-+
-+ size = of_modalias(np, NULL, 0);
-+ if (size < 0)
-+ return size;
-+
-+ /* Reserve an additional byte for the trailing '\0' */
-+ size++;
-+
-+ str = kmalloc(size, GFP_KERNEL);
-+ if (!str)
-+ return -ENOMEM;
-+
-+ of_modalias(np, str, size);
-+ str[size - 1] = '\0';
-+ ret = request_module(str);
-+ kfree(str);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(of_request_module);
---- a/include/linux/of.h
-+++ b/include/linux/of.h
-@@ -376,6 +376,7 @@ extern int of_count_phandle_with_args(co
-
- /* module functions */
- extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len);
-+extern int of_request_module(const struct device_node *np);
-
- /* phandle iterator functions */
- extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
-@@ -739,6 +740,11 @@ static inline ssize_t of_modalias(const
- {
- return -ENODEV;
- }
-+
-+static inline int of_request_module(const struct device_node *np)
-+{
-+ return -ENODEV;
-+}
-
- static inline int of_phandle_iterator_init(struct of_phandle_iterator *it,
- const struct device_node *np,
diff --git a/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch b/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch
deleted file mode 100644
index 3319f431ba..0000000000
--- a/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch
+++ /dev/null
@@ -1,207 +0,0 @@
-From 77faa07c185c969e742cbb3e6aa487a11b0b616c Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Tue, 30 Aug 2022 09:57:42 +0300
-Subject: [PATCH] dt-bindings: arm: qcom: document qcom,msm-id and
- qcom,board-id
-
-The top level qcom,msm-id and qcom,board-id properties are utilized by
-bootloaders on Qualcomm MSM platforms to determine which device tree
-should be used and passed to the kernel.
-
-The commit b32e592d3c28 ("devicetree: bindings: Document qcom board
-compatible format") from 2015 was a consensus during discussion about
-upstreaming qcom,msm-id and qcom,board-id fields. There are however still
-problems with that consensus:
-1. It was reached 7 years ago but it turned out its implementation did
- not reach all possible products.
-
-2. Initially additional tool (dtbTool) was needed for parsing these
- fields to create a QCDT image consisting of multiple DTBs, later the
- bootloaders were improved and they use these qcom,msm-id and
- qcom,board-id properties directly.
-
-3. Extracting relevant information from the board compatible requires
- this additional tool (dtbTool), which makes the build process more
- complicated and not easily reproducible (DTBs are modified after the
- kernel build).
-
-4. Some versions of Qualcomm bootloaders expect these properties even
- when booting with a single DTB. The community is stuck with these
- bootloaders thus they require properties in the DTBs.
-
-Since several upstreamed Qualcomm SoC-based boards require these
-properties to properly boot and the properties are reportedly used by
-bootloaders, document them along with the bindings header with constants
-used by: bootloader, some DTS and socinfo driver.
-
-Link: https://lore.kernel.org/r/a3c932d1-a102-ce18-deea-18cbbd05ecab@linaro.org/
-Co-developed-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
-Link: https://lore.kernel.org/r/20220830065744.161163-2-krzysztof.kozlowski@linaro.org
----
- include/dt-bindings/arm/qcom,ids.h | 155 +++++++++++++++++++++++++++++
- 1 file changed, 155 insertions(+)
- create mode 100644 include/dt-bindings/arm/qcom,ids.h
-
---- /dev/null
-+++ b/include/dt-bindings/arm/qcom,ids.h
-@@ -0,0 +1,155 @@
-+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
-+/*
-+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2022 Linaro Ltd
-+ * Author: Krzysztof Kozlowski <krzk@kernel.org> based on previous work of Kumar Gala.
-+ */
-+#ifndef _DT_BINDINGS_ARM_QCOM_IDS_H
-+#define _DT_BINDINGS_ARM_QCOM_IDS_H
-+
-+/*
-+ * The MSM chipset and hardware revision used by Qualcomm bootloaders, DTS for
-+ * older chipsets (qcom,msm-id) and in socinfo driver:
-+ */
-+#define QCOM_ID_MSM8960 87
-+#define QCOM_ID_APQ8064 109
-+#define QCOM_ID_MSM8660A 122
-+#define QCOM_ID_MSM8260A 123
-+#define QCOM_ID_APQ8060A 124
-+#define QCOM_ID_MSM8974 126
-+#define QCOM_ID_MPQ8064 130
-+#define QCOM_ID_MSM8960AB 138
-+#define QCOM_ID_APQ8060AB 139
-+#define QCOM_ID_MSM8260AB 140
-+#define QCOM_ID_MSM8660AB 141
-+#define QCOM_ID_MSM8626 145
-+#define QCOM_ID_MSM8610 147
-+#define QCOM_ID_APQ8064AB 153
-+#define QCOM_ID_MSM8226 158
-+#define QCOM_ID_MSM8526 159
-+#define QCOM_ID_MSM8110 161
-+#define QCOM_ID_MSM8210 162
-+#define QCOM_ID_MSM8810 163
-+#define QCOM_ID_MSM8212 164
-+#define QCOM_ID_MSM8612 165
-+#define QCOM_ID_MSM8112 166
-+#define QCOM_ID_MSM8225Q 168
-+#define QCOM_ID_MSM8625Q 169
-+#define QCOM_ID_MSM8125Q 170
-+#define QCOM_ID_APQ8064AA 172
-+#define QCOM_ID_APQ8084 178
-+#define QCOM_ID_APQ8074 184
-+#define QCOM_ID_MSM8274 185
-+#define QCOM_ID_MSM8674 186
-+#define QCOM_ID_MSM8974PRO_AC 194
-+#define QCOM_ID_MSM8126 198
-+#define QCOM_ID_APQ8026 199
-+#define QCOM_ID_MSM8926 200
-+#define QCOM_ID_MSM8326 205
-+#define QCOM_ID_MSM8916 206
-+#define QCOM_ID_MSM8994 207
-+#define QCOM_ID_APQ8074PRO_AA 208
-+#define QCOM_ID_APQ8074PRO_AB 209
-+#define QCOM_ID_APQ8074PRO_AC 210
-+#define QCOM_ID_MSM8274PRO_AA 211
-+#define QCOM_ID_MSM8274PRO_AB 212
-+#define QCOM_ID_MSM8274PRO_AC 213
-+#define QCOM_ID_MSM8674PRO_AA 214
-+#define QCOM_ID_MSM8674PRO_AB 215
-+#define QCOM_ID_MSM8674PRO_AC 216
-+#define QCOM_ID_MSM8974PRO_AA 217
-+#define QCOM_ID_MSM8974PRO_AB 218
-+#define QCOM_ID_APQ8028 219
-+#define QCOM_ID_MSM8128 220
-+#define QCOM_ID_MSM8228 221
-+#define QCOM_ID_MSM8528 222
-+#define QCOM_ID_MSM8628 223
-+#define QCOM_ID_MSM8928 224
-+#define QCOM_ID_MSM8510 225
-+#define QCOM_ID_MSM8512 226
-+#define QCOM_ID_MSM8936 233
-+#define QCOM_ID_MSM8939 239
-+#define QCOM_ID_APQ8036 240
-+#define QCOM_ID_APQ8039 241
-+#define QCOM_ID_MSM8996 246
-+#define QCOM_ID_APQ8016 247
-+#define QCOM_ID_MSM8216 248
-+#define QCOM_ID_MSM8116 249
-+#define QCOM_ID_MSM8616 250
-+#define QCOM_ID_MSM8992 251
-+#define QCOM_ID_APQ8094 253
-+#define QCOM_ID_MDM9607 290
-+#define QCOM_ID_APQ8096 291
-+#define QCOM_ID_MSM8998 292
-+#define QCOM_ID_MSM8953 293
-+#define QCOM_ID_MDM8207 296
-+#define QCOM_ID_MDM9207 297
-+#define QCOM_ID_MDM9307 298
-+#define QCOM_ID_MDM9628 299
-+#define QCOM_ID_APQ8053 304
-+#define QCOM_ID_MSM8996SG 305
-+#define QCOM_ID_MSM8996AU 310
-+#define QCOM_ID_APQ8096AU 311
-+#define QCOM_ID_APQ8096SG 312
-+#define QCOM_ID_SDM660 317
-+#define QCOM_ID_SDM630 318
-+#define QCOM_ID_APQ8098 319
-+#define QCOM_ID_SDM845 321
-+#define QCOM_ID_MDM9206 322
-+#define QCOM_ID_IPQ8074 323
-+#define QCOM_ID_SDA660 324
-+#define QCOM_ID_SDM658 325
-+#define QCOM_ID_SDA658 326
-+#define QCOM_ID_SDA630 327
-+#define QCOM_ID_SDM450 338
-+#define QCOM_ID_SDA845 341
-+#define QCOM_ID_IPQ8072 342
-+#define QCOM_ID_IPQ8076 343
-+#define QCOM_ID_IPQ8078 344
-+#define QCOM_ID_SDM636 345
-+#define QCOM_ID_SDA636 346
-+#define QCOM_ID_SDM632 349
-+#define QCOM_ID_SDA632 350
-+#define QCOM_ID_SDA450 351
-+#define QCOM_ID_SM8250 356
-+#define QCOM_ID_IPQ8070 375
-+#define QCOM_ID_IPQ8071 376
-+#define QCOM_ID_IPQ8072A 389
-+#define QCOM_ID_IPQ8074A 390
-+#define QCOM_ID_IPQ8076A 391
-+#define QCOM_ID_IPQ8078A 392
-+#define QCOM_ID_SM6125 394
-+#define QCOM_ID_IPQ8070A 395
-+#define QCOM_ID_IPQ8071A 396
-+#define QCOM_ID_IPQ6018 402
-+#define QCOM_ID_IPQ6028 403
-+#define QCOM_ID_IPQ6000 421
-+#define QCOM_ID_IPQ6010 422
-+#define QCOM_ID_SC7180 425
-+#define QCOM_ID_SM6350 434
-+#define QCOM_ID_SM8350 439
-+#define QCOM_ID_SC8280XP 449
-+#define QCOM_ID_IPQ6005 453
-+#define QCOM_ID_QRB5165 455
-+#define QCOM_ID_SM8450 457
-+#define QCOM_ID_SM7225 459
-+#define QCOM_ID_SA8295P 460
-+#define QCOM_ID_SA8540P 461
-+#define QCOM_ID_SM8450_2 480
-+#define QCOM_ID_SM8450_3 482
-+#define QCOM_ID_SC7280 487
-+#define QCOM_ID_SC7180P 495
-+#define QCOM_ID_SM6375 507
-+
-+/*
-+ * The board type and revision information, used by Qualcomm bootloaders and
-+ * DTS for older chipsets (qcom,board-id):
-+ */
-+#define QCOM_BOARD_ID(a, major, minor) \
-+ (((major & 0xff) << 16) | ((minor & 0xff) << 8) | QCOM_BOARD_ID_##a)
-+
-+#define QCOM_BOARD_ID_MTP 8
-+#define QCOM_BOARD_ID_DRAGONBOARD 10
-+#define QCOM_BOARD_ID_SBC 24
-+
-+#endif /* _DT_BINDINGS_ARM_QCOM_IDS_H */
diff --git a/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch b/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch
deleted file mode 100644
index 394087a27a..0000000000
--- a/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch
+++ /dev/null
@@ -1,171 +0,0 @@
-From 7cbff3c3f867ff3b24de674f44ca03f54e416a37 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Sat, 31 Dec 2022 00:27:42 +0100
-Subject: [PATCH] soc: qcom: socinfo: move SMEM item struct and defines to a
- header
-
-Move SMEM item struct and related defines to a header in order to be able
-to reuse them in the Qualcomm NVMEM CPUFreq driver instead of duplicating
-them.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
-Link: https://lore.kernel.org/r/20230526204802.3081168-1-robimarko@gmail.com
----
- drivers/soc/qcom/socinfo.c | 58 +--------------------------
- include/linux/soc/qcom/socinfo.h | 67 ++++++++++++++++++++++++++++++++
- 2 files changed, 68 insertions(+), 57 deletions(-)
- create mode 100644 include/linux/soc/qcom/socinfo.h
-
---- a/drivers/soc/qcom/socinfo.c
-+++ b/drivers/soc/qcom/socinfo.c
-@@ -11,6 +11,7 @@
- #include <linux/random.h>
- #include <linux/slab.h>
- #include <linux/soc/qcom/smem.h>
-+#include <linux/soc/qcom/socinfo.h>
- #include <linux/string.h>
- #include <linux/sys_soc.h>
- #include <linux/types.h>
-@@ -25,15 +26,6 @@
- #define SOCINFO_MINOR(ver) ((ver) & 0xffff)
- #define SOCINFO_VERSION(maj, min) ((((maj) & 0xffff) << 16)|((min) & 0xffff))
-
--#define SMEM_SOCINFO_BUILD_ID_LENGTH 32
--#define SMEM_SOCINFO_CHIP_ID_LENGTH 32
--
--/*
-- * SMEM item id, used to acquire handles to respective
-- * SMEM region.
-- */
--#define SMEM_HW_SW_BUILD_ID 137
--
- #ifdef CONFIG_DEBUG_FS
- #define SMEM_IMAGE_VERSION_BLOCKS_COUNT 32
- #define SMEM_IMAGE_VERSION_SIZE 4096
-@@ -116,54 +108,6 @@ static const char *const pmic_models[] =
- };
- #endif /* CONFIG_DEBUG_FS */
-
--/* Socinfo SMEM item structure */
--struct socinfo {
-- __le32 fmt;
-- __le32 id;
-- __le32 ver;
-- char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH];
-- /* Version 2 */
-- __le32 raw_id;
-- __le32 raw_ver;
-- /* Version 3 */
-- __le32 hw_plat;
-- /* Version 4 */
-- __le32 plat_ver;
-- /* Version 5 */
-- __le32 accessory_chip;
-- /* Version 6 */
-- __le32 hw_plat_subtype;
-- /* Version 7 */
-- __le32 pmic_model;
-- __le32 pmic_die_rev;
-- /* Version 8 */
-- __le32 pmic_model_1;
-- __le32 pmic_die_rev_1;
-- __le32 pmic_model_2;
-- __le32 pmic_die_rev_2;
-- /* Version 9 */
-- __le32 foundry_id;
-- /* Version 10 */
-- __le32 serial_num;
-- /* Version 11 */
-- __le32 num_pmics;
-- __le32 pmic_array_offset;
-- /* Version 12 */
-- __le32 chip_family;
-- __le32 raw_device_family;
-- __le32 raw_device_num;
-- /* Version 13 */
-- __le32 nproduct_id;
-- char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH];
-- /* Version 14 */
-- __le32 num_clusters;
-- __le32 ncluster_array_offset;
-- __le32 num_defective_parts;
-- __le32 ndefective_parts_array_offset;
-- /* Version 15 */
-- __le32 nmodem_supported;
--};
--
- #ifdef CONFIG_DEBUG_FS
- struct socinfo_params {
- u32 raw_device_family;
---- /dev/null
-+++ b/include/linux/soc/qcom/socinfo.h
-@@ -0,0 +1,67 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2017-2019, Linaro Ltd.
-+ */
-+
-+#ifndef __QCOM_SOCINFO_H__
-+#define __QCOM_SOCINFO_H__
-+
-+/*
-+ * SMEM item id, used to acquire handles to respective
-+ * SMEM region.
-+ */
-+#define SMEM_HW_SW_BUILD_ID 137
-+
-+#define SMEM_SOCINFO_BUILD_ID_LENGTH 32
-+#define SMEM_SOCINFO_CHIP_ID_LENGTH 32
-+
-+/* Socinfo SMEM item structure */
-+struct socinfo {
-+ __le32 fmt;
-+ __le32 id;
-+ __le32 ver;
-+ char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH];
-+ /* Version 2 */
-+ __le32 raw_id;
-+ __le32 raw_ver;
-+ /* Version 3 */
-+ __le32 hw_plat;
-+ /* Version 4 */
-+ __le32 plat_ver;
-+ /* Version 5 */
-+ __le32 accessory_chip;
-+ /* Version 6 */
-+ __le32 hw_plat_subtype;
-+ /* Version 7 */
-+ __le32 pmic_model;
-+ __le32 pmic_die_rev;
-+ /* Version 8 */
-+ __le32 pmic_model_1;
-+ __le32 pmic_die_rev_1;
-+ __le32 pmic_model_2;
-+ __le32 pmic_die_rev_2;
-+ /* Version 9 */
-+ __le32 foundry_id;
-+ /* Version 10 */
-+ __le32 serial_num;
-+ /* Version 11 */
-+ __le32 num_pmics;
-+ __le32 pmic_array_offset;
-+ /* Version 12 */
-+ __le32 chip_family;
-+ __le32 raw_device_family;
-+ __le32 raw_device_num;
-+ /* Version 13 */
-+ __le32 nproduct_id;
-+ char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH];
-+ /* Version 14 */
-+ __le32 num_clusters;
-+ __le32 ncluster_array_offset;
-+ __le32 num_defective_parts;
-+ __le32 ndefective_parts_array_offset;
-+ /* Version 15 */
-+ __le32 nmodem_supported;
-+};
-+
-+#endif
diff --git a/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch b/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch
deleted file mode 100644
index 7c7c3f3635..0000000000
--- a/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 9f1bbff157a69db7684f5da2f73b2325c638a90e Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Fri, 26 May 2023 22:47:59 +0200
-Subject: [PATCH] soc: qcom: smem: Switch to EXPORT_SYMBOL_GPL()
-
-SMEM has been GPL licensed from the start, and there is no reason to use
-EXPORT_SYMBOL() so switch to the GPL version.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
-Reviewed-by: Trilok Soni <quic_tsoni@quicinc.com>
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
-Link: https://lore.kernel.org/r/20230526204802.3081168-2-robimarko@gmail.com
----
- drivers/soc/qcom/smem.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/soc/qcom/smem.c
-+++ b/drivers/soc/qcom/smem.c
-@@ -500,7 +500,7 @@ int qcom_smem_alloc(unsigned host, unsig
-
- return ret;
- }
--EXPORT_SYMBOL(qcom_smem_alloc);
-+EXPORT_SYMBOL_GPL(qcom_smem_alloc);
-
- static void *qcom_smem_get_global(struct qcom_smem *smem,
- unsigned item,
-@@ -674,7 +674,7 @@ void *qcom_smem_get(unsigned host, unsig
- return ptr;
-
- }
--EXPORT_SYMBOL(qcom_smem_get);
-+EXPORT_SYMBOL_GPL(qcom_smem_get);
-
- /**
- * qcom_smem_get_free_space() - retrieve amount of free space in a partition
-@@ -719,7 +719,7 @@ int qcom_smem_get_free_space(unsigned ho
-
- return ret;
- }
--EXPORT_SYMBOL(qcom_smem_get_free_space);
-+EXPORT_SYMBOL_GPL(qcom_smem_get_free_space);
-
- static bool addr_in_range(void __iomem *base, size_t size, void *addr)
- {
-@@ -770,7 +770,7 @@ phys_addr_t qcom_smem_virt_to_phys(void
-
- return 0;
- }
--EXPORT_SYMBOL(qcom_smem_virt_to_phys);
-+EXPORT_SYMBOL_GPL(qcom_smem_virt_to_phys);
-
- static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
- {
diff --git a/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch b/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch
deleted file mode 100644
index 4a816bb0f9..0000000000
--- a/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From c3ecf2602a32d9b9e5fc997076c0d2836495c085 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Fri, 26 May 2023 22:48:00 +0200
-Subject: [PATCH] soc: qcom: smem: introduce qcom_smem_get_soc_id()
-
-Introduce a helper to return the SoC SMEM ID, which is used to identify the
-exact SoC model as there may be differences in the same SoC family.
-
-Currently, cpufreq-nvmem does this completely in the driver and there has
-been more interest expresed for other drivers to use this information so
-lets expose a common helper to prevent redoing it in individual drivers
-since this field is present on every SMEM table version.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
-Link: https://lore.kernel.org/r/20230526204802.3081168-3-robimarko@gmail.com
----
- drivers/soc/qcom/smem.c | 23 +++++++++++++++++++++++
- include/linux/soc/qcom/smem.h | 2 ++
- 2 files changed, 25 insertions(+)
-
---- a/drivers/soc/qcom/smem.c
-+++ b/drivers/soc/qcom/smem.c
-@@ -14,6 +14,7 @@
- #include <linux/sizes.h>
- #include <linux/slab.h>
- #include <linux/soc/qcom/smem.h>
-+#include <linux/soc/qcom/socinfo.h>
-
- /*
- * The Qualcomm shared memory system is a allocate only heap structure that
-@@ -772,6 +773,28 @@ phys_addr_t qcom_smem_virt_to_phys(void
- }
- EXPORT_SYMBOL_GPL(qcom_smem_virt_to_phys);
-
-+/**
-+ * qcom_smem_get_soc_id() - return the SoC ID
-+ * @id: On success, we return the SoC ID here.
-+ *
-+ * Look up SoC ID from HW/SW build ID and return it.
-+ *
-+ * Return: 0 on success, negative errno on failure.
-+ */
-+int qcom_smem_get_soc_id(u32 *id)
-+{
-+ struct socinfo *info;
-+
-+ info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID, NULL);
-+ if (IS_ERR(info))
-+ return PTR_ERR(info);
-+
-+ *id = __le32_to_cpu(info->id);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(qcom_smem_get_soc_id);
-+
- static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
- {
- struct smem_header *header;
---- a/include/linux/soc/qcom/smem.h
-+++ b/include/linux/soc/qcom/smem.h
-@@ -11,4 +11,6 @@ int qcom_smem_get_free_space(unsigned ho
-
- phys_addr_t qcom_smem_virt_to_phys(void *p);
-
-+int qcom_smem_get_soc_id(u32 *id);
-+
- #endif
diff --git a/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch b/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
deleted file mode 100644
index e0f10f7642..0000000000
--- a/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 2b8634d1468ff498cc91b6adf993c27ae6fa079d Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Fri, 26 May 2023 22:48:01 +0200
-Subject: [PATCH] cpufreq: qcom-nvmem: use SoC ID-s from bindings
-
-SMEM SoC ID-s are now stored in DT bindings so lets use those instead of
-defining them in the driver again.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
-Link: https://lore.kernel.org/r/20230526204802.3081168-4-robimarko@gmail.com
----
- drivers/cpufreq/qcom-cpufreq-nvmem.c | 15 +++++----------
- 1 file changed, 5 insertions(+), 10 deletions(-)
-
---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
-+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
-@@ -30,12 +30,7 @@
-
- #define MSM_ID_SMEM 137
-
--enum _msm_id {
-- MSM8996V3 = 0xF6ul,
-- APQ8096V3 = 0x123ul,
-- MSM8996SG = 0x131ul,
-- APQ8096SG = 0x138ul,
--};
-+#include <dt-bindings/arm/qcom,ids.h>
-
- enum _msm8996_version {
- MSM8996_V3,
-@@ -153,12 +148,12 @@ static enum _msm8996_version qcom_cpufre
- msm_id++;
-
- switch ((enum _msm_id)*msm_id) {
-- case MSM8996V3:
-- case APQ8096V3:
-+ case QCOM_ID_MSM8996:
-+ case QCOM_ID_APQ8096:
- version = MSM8996_V3;
- break;
-- case MSM8996SG:
-- case APQ8096SG:
-+ case QCOM_ID_MSM8996SG:
-+ case QCOM_ID_APQ8096SG:
- version = MSM8996_SG;
- break;
- default:
diff --git a/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch b/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch
deleted file mode 100644
index 93e776f62c..0000000000
--- a/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From e7992615acacc27baeec310197108143afc77337 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Fri, 26 May 2023 22:48:02 +0200
-Subject: [PATCH] cpufreq: qcom-nvmem: use helper to get SMEM SoC ID
-
-Now that SMEM exports a helper to get the SMEM SoC ID lets utilize it.
-Currently qcom_cpufreq_get_msm_id() is encoding the returned SMEM SoC ID
-into an enum, however there is no reason to do so and we can just match
-directly on the SMEM SoC ID as returned by qcom_smem_get_soc_id().
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
-Link: https://lore.kernel.org/r/20230526204802.3081168-5-robimarko@gmail.com
----
- drivers/cpufreq/qcom-cpufreq-nvmem.c | 56 +++++-----------------------
- 1 file changed, 10 insertions(+), 46 deletions(-)
-
---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
-+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
-@@ -28,16 +28,8 @@
- #include <linux/slab.h>
- #include <linux/soc/qcom/smem.h>
-
--#define MSM_ID_SMEM 137
--
- #include <dt-bindings/arm/qcom,ids.h>
-
--enum _msm8996_version {
-- MSM8996_V3,
-- MSM8996_SG,
-- NUM_OF_MSM8996_VERSIONS,
--};
--
- struct qcom_cpufreq_drv;
-
- struct qcom_cpufreq_match_data {
-@@ -134,60 +126,32 @@ static void get_krait_bin_format_b(struc
- dev_dbg(cpu_dev, "PVS version: %d\n", *pvs_ver);
- }
-
--static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
--{
-- size_t len;
-- u32 *msm_id;
-- enum _msm8996_version version;
--
-- msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len);
-- if (IS_ERR(msm_id))
-- return NUM_OF_MSM8996_VERSIONS;
--
-- /* The first 4 bytes are format, next to them is the actual msm-id */
-- msm_id++;
--
-- switch ((enum _msm_id)*msm_id) {
-- case QCOM_ID_MSM8996:
-- case QCOM_ID_APQ8096:
-- version = MSM8996_V3;
-- break;
-- case QCOM_ID_MSM8996SG:
-- case QCOM_ID_APQ8096SG:
-- version = MSM8996_SG;
-- break;
-- default:
-- version = NUM_OF_MSM8996_VERSIONS;
-- }
--
-- return version;
--}
--
- static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
- struct nvmem_cell *speedbin_nvmem,
- char **pvs_name,
- struct qcom_cpufreq_drv *drv)
- {
- size_t len;
-+ u32 msm_id;
- u8 *speedbin;
-- enum _msm8996_version msm8996_version;
-+ int ret;
- *pvs_name = NULL;
-
-- msm8996_version = qcom_cpufreq_get_msm_id();
-- if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
-- dev_err(cpu_dev, "Not Snapdragon 820/821!");
-- return -ENODEV;
-- }
-+ ret = qcom_smem_get_soc_id(&msm_id);
-+ if (ret)
-+ return ret;
-
- speedbin = nvmem_cell_read(speedbin_nvmem, &len);
- if (IS_ERR(speedbin))
- return PTR_ERR(speedbin);
-
-- switch (msm8996_version) {
-- case MSM8996_V3:
-+ switch (msm_id) {
-+ case QCOM_ID_MSM8996:
-+ case QCOM_ID_APQ8096:
- drv->versions = 1 << (unsigned int)(*speedbin);
- break;
-- case MSM8996_SG:
-+ case QCOM_ID_MSM8996SG:
-+ case QCOM_ID_APQ8096SG:
- drv->versions = 1 << ((unsigned int)(*speedbin) + 4);
- break;
- default:
diff --git a/target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch b/target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch
deleted file mode 100644
index ddda6e4e78..0000000000
--- a/target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From edd25a77e69b7c546c28077e5dffe72c54c0afe8 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Thu, 21 Sep 2023 22:18:12 +0200
-Subject: [PATCH 2/4] rtc: rtc7301: Support byte-addressed IO
-
-The old RTC7301 driver in OpenWrt used byte access, but the
-current mainline Linux driver uses 32bit word access.
-
-Make this configurable using device properties using the
-standard property "reg-io-width" in e.g. device tree.
-
-This is needed for the USRobotics USR8200 which has the
-chip connected using byte accesses.
-
-Debugging and testing by Howard Harte.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/rtc/rtc-r7301.c | 35 +++++++++++++++++++++++++++++++++--
- 1 file changed, 33 insertions(+), 2 deletions(-)
-
---- a/drivers/rtc/rtc-r7301.c
-+++ b/drivers/rtc/rtc-r7301.c
-@@ -14,6 +14,7 @@
- #include <linux/module.h>
- #include <linux/mod_devicetable.h>
- #include <linux/delay.h>
-+#include <linux/property.h>
- #include <linux/regmap.h>
- #include <linux/platform_device.h>
- #include <linux/rtc.h>
-@@ -55,12 +56,23 @@ struct rtc7301_priv {
- u8 bank;
- };
-
--static const struct regmap_config rtc7301_regmap_config = {
-+/*
-+ * When the device is memory-mapped, some platforms pack the registers into
-+ * 32-bit access using the lower 8 bits at each 4-byte stride, while others
-+ * expose them as simply consecutive bytes.
-+ */
-+static const struct regmap_config rtc7301_regmap_32_config = {
- .reg_bits = 32,
- .val_bits = 8,
- .reg_stride = 4,
- };
-
-+static const struct regmap_config rtc7301_regmap_8_config = {
-+ .reg_bits = 8,
-+ .val_bits = 8,
-+ .reg_stride = 1,
-+};
-+
- static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)
- {
- int reg_stride = regmap_get_reg_stride(priv->regmap);
-@@ -356,7 +368,9 @@ static int __init rtc7301_rtc_probe(stru
- void __iomem *regs;
- struct rtc7301_priv *priv;
- struct rtc_device *rtc;
-+ static const struct regmap_config *mapconf;
- int ret;
-+ u32 val;
-
- priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -366,8 +380,25 @@ static int __init rtc7301_rtc_probe(stru
- if (IS_ERR(regs))
- return PTR_ERR(regs);
-
-+ ret = device_property_read_u32(&dev->dev, "reg-io-width", &val);
-+ if (ret)
-+ /* Default to 32bit accesses */
-+ val = 4;
-+
-+ switch (val) {
-+ case 1:
-+ mapconf = &rtc7301_regmap_8_config;
-+ break;
-+ case 4:
-+ mapconf = &rtc7301_regmap_32_config;
-+ break;
-+ default:
-+ dev_err(&dev->dev, "invalid reg-io-width %d\n", val);
-+ return -EINVAL;
-+ }
-+
- priv->regmap = devm_regmap_init_mmio(&dev->dev, regs,
-- &rtc7301_regmap_config);
-+ mapconf);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
diff --git a/target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch b/target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch
deleted file mode 100644
index e8e73c1e5f..0000000000
--- a/target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 49e5663b505070424e18099841943f34342aa405 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 24 Sep 2023 01:09:01 +0200
-Subject: [PATCH] net: phy: amd: Support the Altima AMI101L
-
-The Altima AC101L is obviously compatible with the AMD PHY,
-as seen by reading the datasheet.
-
-Datasheet: https://docs.broadcom.com/doc/AC101L-DS05-405-RDS.pdf
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/net/phy/Kconfig | 4 ++--
- drivers/net/phy/amd.c | 33 +++++++++++++++++++++++----------
- 2 files changed, 25 insertions(+), 12 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -77,9 +77,9 @@ config AIR_EN8811H_PHY
- Currently supports the Airoha EN8811H PHY.
-
- config AMD_PHY
-- tristate "AMD PHYs"
-+ tristate "AMD and Altima PHYs"
- help
-- Currently supports the am79c874
-+ Currently supports the AMD am79c874 and Altima AC101L.
-
- config MESON_GXL_PHY
- tristate "Amlogic Meson GXL Internal PHY"
---- a/drivers/net/phy/amd.c
-+++ b/drivers/net/phy/amd.c
-@@ -13,6 +13,7 @@
- #include <linux/mii.h>
- #include <linux/phy.h>
-
-+#define PHY_ID_AC101L 0x00225520
- #define PHY_ID_AM79C874 0x0022561b
-
- #define MII_AM79C_IR 17 /* Interrupt Status/Control Register */
-@@ -87,19 +88,31 @@ static irqreturn_t am79c_handle_interrup
- return IRQ_HANDLED;
- }
-
--static struct phy_driver am79c_driver[] = { {
-- .phy_id = PHY_ID_AM79C874,
-- .name = "AM79C874",
-- .phy_id_mask = 0xfffffff0,
-- /* PHY_BASIC_FEATURES */
-- .config_init = am79c_config_init,
-- .config_intr = am79c_config_intr,
-- .handle_interrupt = am79c_handle_interrupt,
--} };
-+static struct phy_driver am79c_drivers[] = {
-+ {
-+ .phy_id = PHY_ID_AM79C874,
-+ .name = "AM79C874",
-+ .phy_id_mask = 0xfffffff0,
-+ /* PHY_BASIC_FEATURES */
-+ .config_init = am79c_config_init,
-+ .config_intr = am79c_config_intr,
-+ .handle_interrupt = am79c_handle_interrupt,
-+ },
-+ {
-+ .phy_id = PHY_ID_AC101L,
-+ .name = "AC101L",
-+ .phy_id_mask = 0xfffffff0,
-+ /* PHY_BASIC_FEATURES */
-+ .config_init = am79c_config_init,
-+ .config_intr = am79c_config_intr,
-+ .handle_interrupt = am79c_handle_interrupt,
-+ },
-+};
-
--module_phy_driver(am79c_driver);
-+module_phy_driver(am79c_drivers);
-
- static struct mdio_device_id __maybe_unused amd_tbl[] = {
-+ { PHY_ID_AC101L, 0xfffffff0 },
- { PHY_ID_AM79C874, 0xfffffff0 },
- { }
- };
diff --git a/target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch b/target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch
deleted file mode 100644
index b71df6fa57..0000000000
--- a/target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From a067943129b4ec6b835e02cfd5fbef01093c1471 Mon Sep 17 00:00:00 2001
-From: Ondrej Jirman <megi@xff.cz>
-Date: Sun, 8 Oct 2023 16:40:13 +0200
-Subject: [PATCH] leds: core: Add more colors from DT bindings to led_colors
-
-The colors are already part of DT bindings. Make sure the kernel is
-able to convert them to strings.
-
-Signed-off-by: Ondrej Jirman <megi@xff.cz>
-Link: https://lore.kernel.org/r/20231008144014.1180334-1-megi@xff.cz
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/led-core.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/leds/led-core.c
-+++ b/drivers/leds/led-core.c
-@@ -36,6 +36,11 @@ const char * const led_colors[LED_COLOR_
- [LED_COLOR_ID_IR] = "ir",
- [LED_COLOR_ID_MULTI] = "multicolor",
- [LED_COLOR_ID_RGB] = "rgb",
-+ [LED_COLOR_ID_PURPLE] = "purple",
-+ [LED_COLOR_ID_ORANGE] = "orange",
-+ [LED_COLOR_ID_PINK] = "pink",
-+ [LED_COLOR_ID_CYAN] = "cyan",
-+ [LED_COLOR_ID_LIME] = "lime",
- };
- EXPORT_SYMBOL_GPL(led_colors);
-
diff --git a/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch b/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
deleted file mode 100644
index 1c8e014a1a..0000000000
--- a/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From bc8e1da69a68d9871773b657d18400a7941cbdef Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 28 Nov 2023 04:00:10 +0000
-Subject: [PATCH] leds: trigger: netdev: Extend speeds up to 10G
-
-Add 2.5G, 5G and 10G as available speeds to the netdev LED trigger.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/99e7d3304c6bba7f4863a4a80764a869855f2085.1701143925.git.daniel@makrotopia.org
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 32 ++++++++++++++++++++++++++-
- include/linux/leds.h | 3 +++
- 2 files changed, 34 insertions(+), 1 deletion(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -99,6 +99,18 @@ static void set_baseline_state(struct le
- trigger_data->link_speed == SPEED_1000)
- blink_on = true;
-
-+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) &&
-+ trigger_data->link_speed == SPEED_2500)
-+ blink_on = true;
-+
-+ if (test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) &&
-+ trigger_data->link_speed == SPEED_5000)
-+ blink_on = true;
-+
-+ if (test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) &&
-+ trigger_data->link_speed == SPEED_10000)
-+ blink_on = true;
-+
- if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) &&
- trigger_data->duplex == DUPLEX_HALF)
- blink_on = true;
-@@ -286,6 +298,9 @@ static ssize_t netdev_led_attr_show(stru
- case TRIGGER_NETDEV_LINK_10:
- case TRIGGER_NETDEV_LINK_100:
- case TRIGGER_NETDEV_LINK_1000:
-+ case TRIGGER_NETDEV_LINK_2500:
-+ case TRIGGER_NETDEV_LINK_5000:
-+ case TRIGGER_NETDEV_LINK_10000:
- case TRIGGER_NETDEV_HALF_DUPLEX:
- case TRIGGER_NETDEV_FULL_DUPLEX:
- case TRIGGER_NETDEV_TX:
-@@ -316,6 +331,9 @@ static ssize_t netdev_led_attr_store(str
- case TRIGGER_NETDEV_LINK_10:
- case TRIGGER_NETDEV_LINK_100:
- case TRIGGER_NETDEV_LINK_1000:
-+ case TRIGGER_NETDEV_LINK_2500:
-+ case TRIGGER_NETDEV_LINK_5000:
-+ case TRIGGER_NETDEV_LINK_10000:
- case TRIGGER_NETDEV_HALF_DUPLEX:
- case TRIGGER_NETDEV_FULL_DUPLEX:
- case TRIGGER_NETDEV_TX:
-@@ -334,7 +352,10 @@ static ssize_t netdev_led_attr_store(str
- if (test_bit(TRIGGER_NETDEV_LINK, &mode) &&
- (test_bit(TRIGGER_NETDEV_LINK_10, &mode) ||
- test_bit(TRIGGER_NETDEV_LINK_100, &mode) ||
-- test_bit(TRIGGER_NETDEV_LINK_1000, &mode)))
-+ test_bit(TRIGGER_NETDEV_LINK_1000, &mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_2500, &mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_5000, &mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_10000, &mode)))
- return -EINVAL;
-
- cancel_delayed_work_sync(&trigger_data->work);
-@@ -364,6 +385,9 @@ DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETD
- DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10);
- DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100);
- DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
-+DEFINE_NETDEV_TRIGGER(link_2500, TRIGGER_NETDEV_LINK_2500);
-+DEFINE_NETDEV_TRIGGER(link_5000, TRIGGER_NETDEV_LINK_5000);
-+DEFINE_NETDEV_TRIGGER(link_10000, TRIGGER_NETDEV_LINK_10000);
- DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX);
- DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX);
- DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
-@@ -422,6 +446,9 @@ static struct attribute *netdev_trig_att
- &dev_attr_link_10.attr,
- &dev_attr_link_100.attr,
- &dev_attr_link_1000.attr,
-+ &dev_attr_link_2500.attr,
-+ &dev_attr_link_5000.attr,
-+ &dev_attr_link_10000.attr,
- &dev_attr_full_duplex.attr,
- &dev_attr_half_duplex.attr,
- &dev_attr_rx.attr,
-@@ -519,6 +546,9 @@ static void netdev_trig_work(struct work
- test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) ||
- test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) ||
- test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) ||
-+ test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) ||
- test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) ||
- test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode);
- interval = jiffies_to_msecs(
---- a/include/linux/leds.h
-+++ b/include/linux/leds.h
-@@ -533,6 +533,9 @@ enum led_trigger_netdev_modes {
- TRIGGER_NETDEV_LINK_10,
- TRIGGER_NETDEV_LINK_100,
- TRIGGER_NETDEV_LINK_1000,
-+ TRIGGER_NETDEV_LINK_2500,
-+ TRIGGER_NETDEV_LINK_5000,
-+ TRIGGER_NETDEV_LINK_10000,
- TRIGGER_NETDEV_HALF_DUPLEX,
- TRIGGER_NETDEV_FULL_DUPLEX,
- TRIGGER_NETDEV_TX,
diff --git a/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch b/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch
deleted file mode 100644
index 0182e6d1a2..0000000000
--- a/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 7ae215ee7bb855f13c80565470fc7f67db4ba82f Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 25 Jan 2024 21:36:59 +0100
-Subject: [PATCH 3/5] net: phy: add support for PHY LEDs polarity modes
-
-Add support for PHY LEDs polarity modes. Some PHY require LED to be set
-to active low to be turned ON. Adds support for this by declaring
-active-low property in DT.
-
-PHY driver needs to declare .led_polarity_set() to configure LED
-polarity modes. Function will pass the index with the LED index and a
-bitmap with all the required modes to set.
-
-Current supported modes are:
-- active-low with the flag PHY_LED_ACTIVE_LOW. LED is set to active-low
- to turn it ON.
-- inactive-high-impedance with the flag PHY_LED_INACTIVE_HIGH_IMPEDANCE.
- LED is set to high impedance to turn it OFF.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240125203702.4552-4-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy_device.c | 16 ++++++++++++++++
- include/linux/phy.h | 22 ++++++++++++++++++++++
- 2 files changed, 38 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3138,6 +3138,7 @@ static int of_phy_led(struct phy_device
- struct device *dev = &phydev->mdio.dev;
- struct led_init_data init_data = {};
- struct led_classdev *cdev;
-+ unsigned long modes = 0;
- struct phy_led *phyled;
- u32 index;
- int err;
-@@ -3155,6 +3156,21 @@ static int of_phy_led(struct phy_device
- if (index > U8_MAX)
- return -EINVAL;
-
-+ if (of_property_read_bool(led, "active-low"))
-+ set_bit(PHY_LED_ACTIVE_LOW, &modes);
-+ if (of_property_read_bool(led, "inactive-high-impedance"))
-+ set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes);
-+
-+ if (modes) {
-+ /* Return error if asked to set polarity modes but not supported */
-+ if (!phydev->drv->led_polarity_set)
-+ return -EINVAL;
-+
-+ err = phydev->drv->led_polarity_set(phydev, index, modes);
-+ if (err)
-+ return err;
-+ }
-+
- phyled->index = index;
- if (phydev->drv->led_brightness_set)
- cdev->brightness_set_blocking = phy_led_set_brightness;
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -791,6 +791,15 @@ struct phy_led {
-
- #define to_phy_led(d) container_of(d, struct phy_led, led_cdev)
-
-+/* Modes for PHY LED configuration */
-+enum phy_led_modes {
-+ PHY_LED_ACTIVE_LOW = 0,
-+ PHY_LED_INACTIVE_HIGH_IMPEDANCE = 1,
-+
-+ /* keep it last */
-+ __PHY_LED_MODES_NUM,
-+};
-+
- /**
- * struct phy_driver - Driver structure for a particular PHY type
- *
-@@ -1059,6 +1068,19 @@ struct phy_driver {
- int (*led_hw_control_get)(struct phy_device *dev, u8 index,
- unsigned long *rules);
-
-+ /**
-+ * @led_polarity_set: Set the LED polarity modes
-+ * @dev: PHY device which has the LED
-+ * @index: Which LED of the PHY device
-+ * @modes: bitmap of LED polarity modes
-+ *
-+ * Configure LED with all the required polarity modes in @modes
-+ * to make it correctly turn ON or OFF.
-+ *
-+ * Returns 0, or an error code.
-+ */
-+ int (*led_polarity_set)(struct phy_device *dev, int index,
-+ unsigned long modes);
- };
- #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
- struct phy_driver, mdiodrv)
diff --git a/target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch b/target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch
deleted file mode 100644
index cbb9172032..0000000000
--- a/target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-From fe2b1226656afae56702d1d84c6900f6b67df297 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 1 Dec 2023 11:23:22 +0100
-Subject: [PATCH] leds: trigger: netdev: fix RTNL handling to prevent potential
- deadlock
-
-When working on LED support for r8169 I got the following lockdep
-warning. Easiest way to prevent this scenario seems to be to take
-the RTNL lock before the trigger_data lock in set_device_name().
-
-======================================================
-WARNING: possible circular locking dependency detected
-6.7.0-rc2-next-20231124+ #2 Not tainted
-------------------------------------------------------
-bash/383 is trying to acquire lock:
-ffff888103aa1c68 (&trigger_data->lock){+.+.}-{3:3}, at: netdev_trig_notify+0xec/0x190 [ledtrig_netdev]
-
-but task is already holding lock:
-ffffffff8cddf808 (rtnl_mutex){+.+.}-{3:3}, at: rtnl_lock+0x12/0x20
-
-which lock already depends on the new lock.
-
-the existing dependency chain (in reverse order) is:
-
--> #1 (rtnl_mutex){+.+.}-{3:3}:
- __mutex_lock+0x9b/0xb50
- mutex_lock_nested+0x16/0x20
- rtnl_lock+0x12/0x20
- set_device_name+0xa9/0x120 [ledtrig_netdev]
- netdev_trig_activate+0x1a1/0x230 [ledtrig_netdev]
- led_trigger_set+0x172/0x2c0
- led_trigger_write+0xf1/0x140
- sysfs_kf_bin_write+0x5d/0x80
- kernfs_fop_write_iter+0x15d/0x210
- vfs_write+0x1f0/0x510
- ksys_write+0x6c/0xf0
- __x64_sys_write+0x14/0x20
- do_syscall_64+0x3f/0xf0
- entry_SYSCALL_64_after_hwframe+0x6c/0x74
-
--> #0 (&trigger_data->lock){+.+.}-{3:3}:
- __lock_acquire+0x1459/0x25a0
- lock_acquire+0xc8/0x2d0
- __mutex_lock+0x9b/0xb50
- mutex_lock_nested+0x16/0x20
- netdev_trig_notify+0xec/0x190 [ledtrig_netdev]
- call_netdevice_register_net_notifiers+0x5a/0x100
- register_netdevice_notifier+0x85/0x120
- netdev_trig_activate+0x1d4/0x230 [ledtrig_netdev]
- led_trigger_set+0x172/0x2c0
- led_trigger_write+0xf1/0x140
- sysfs_kf_bin_write+0x5d/0x80
- kernfs_fop_write_iter+0x15d/0x210
- vfs_write+0x1f0/0x510
- ksys_write+0x6c/0xf0
- __x64_sys_write+0x14/0x20
- do_syscall_64+0x3f/0xf0
- entry_SYSCALL_64_after_hwframe+0x6c/0x74
-
-other info that might help us debug this:
-
- Possible unsafe locking scenario:
-
- CPU0 CPU1
- ---- ----
- lock(rtnl_mutex);
- lock(&trigger_data->lock);
- lock(rtnl_mutex);
- lock(&trigger_data->lock);
-
- *** DEADLOCK ***
-
-8 locks held by bash/383:
- #0: ffff888103ff33f0 (sb_writers#3){.+.+}-{0:0}, at: ksys_write+0x6c/0xf0
- #1: ffff888103aa1e88 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x114/0x210
- #2: ffff8881036f1890 (kn->active#82){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x11d/0x210
- #3: ffff888108e2c358 (&led_cdev->led_access){+.+.}-{3:3}, at: led_trigger_write+0x30/0x140
- #4: ffffffff8cdd9e10 (triggers_list_lock){++++}-{3:3}, at: led_trigger_write+0x75/0x140
- #5: ffff888108e2c270 (&led_cdev->trigger_lock){++++}-{3:3}, at: led_trigger_write+0xe3/0x140
- #6: ffffffff8cdde3d0 (pernet_ops_rwsem){++++}-{3:3}, at: register_netdevice_notifier+0x1c/0x120
- #7: ffffffff8cddf808 (rtnl_mutex){+.+.}-{3:3}, at: rtnl_lock+0x12/0x20
-
-stack backtrace:
-CPU: 0 PID: 383 Comm: bash Not tainted 6.7.0-rc2-next-20231124+ #2
-Hardware name: Default string Default string/Default string, BIOS ADLN.M6.SODIMM.ZB.CY.015 08/08/2023
-Call Trace:
- <TASK>
- dump_stack_lvl+0x5c/0xd0
- dump_stack+0x10/0x20
- print_circular_bug+0x2dd/0x410
- check_noncircular+0x131/0x150
- __lock_acquire+0x1459/0x25a0
- lock_acquire+0xc8/0x2d0
- ? netdev_trig_notify+0xec/0x190 [ledtrig_netdev]
- __mutex_lock+0x9b/0xb50
- ? netdev_trig_notify+0xec/0x190 [ledtrig_netdev]
- ? __this_cpu_preempt_check+0x13/0x20
- ? netdev_trig_notify+0xec/0x190 [ledtrig_netdev]
- ? __cancel_work_timer+0x11c/0x1b0
- ? __mutex_lock+0x123/0xb50
- mutex_lock_nested+0x16/0x20
- ? mutex_lock_nested+0x16/0x20
- netdev_trig_notify+0xec/0x190 [ledtrig_netdev]
- call_netdevice_register_net_notifiers+0x5a/0x100
- register_netdevice_notifier+0x85/0x120
- netdev_trig_activate+0x1d4/0x230 [ledtrig_netdev]
- led_trigger_set+0x172/0x2c0
- ? preempt_count_add+0x49/0xc0
- led_trigger_write+0xf1/0x140
- sysfs_kf_bin_write+0x5d/0x80
- kernfs_fop_write_iter+0x15d/0x210
- vfs_write+0x1f0/0x510
- ksys_write+0x6c/0xf0
- __x64_sys_write+0x14/0x20
- do_syscall_64+0x3f/0xf0
- entry_SYSCALL_64_after_hwframe+0x6c/0x74
-RIP: 0033:0x7f269055d034
-Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 80 3d 35 c3 0d 00 00 74 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 48 89 54 24 18 48
-RSP: 002b:00007ffddb7ef748 EFLAGS: 00000202 ORIG_RAX: 0000000000000001
-RAX: ffffffffffffffda RBX: 0000000000000007 RCX: 00007f269055d034
-RDX: 0000000000000007 RSI: 000055bf5f4af3c0 RDI: 0000000000000001
-RBP: 000055bf5f4af3c0 R08: 0000000000000073 R09: 0000000000000001
-R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000007
-R13: 00007f26906325c0 R14: 00007f269062ff20 R15: 0000000000000000
- </TASK>
-
-Fixes: d5e01266e7f5 ("leds: trigger: netdev: add additional specific link speed mode")
-Cc: stable@vger.kernel.org
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/fb5c8294-2a10-4bf5-8f10-3d2b77d2757e@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -235,6 +235,11 @@ static int set_device_name(struct led_ne
- {
- cancel_delayed_work_sync(&trigger_data->work);
-
-+ /*
-+ * Take RTNL lock before trigger_data lock to prevent potential
-+ * deadlock with netdev notifier registration.
-+ */
-+ rtnl_lock();
- mutex_lock(&trigger_data->lock);
-
- if (trigger_data->net_dev) {
-@@ -254,16 +259,14 @@ static int set_device_name(struct led_ne
- trigger_data->carrier_link_up = false;
- trigger_data->link_speed = SPEED_UNKNOWN;
- trigger_data->duplex = DUPLEX_UNKNOWN;
-- if (trigger_data->net_dev != NULL) {
-- rtnl_lock();
-+ if (trigger_data->net_dev)
- get_device_state(trigger_data);
-- rtnl_unlock();
-- }
-
- trigger_data->last_activity = 0;
-
- set_baseline_state(trigger_data);
- mutex_unlock(&trigger_data->lock);
-+ rtnl_unlock();
-
- return 0;
- }
diff --git a/target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch b/target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch
deleted file mode 100644
index 51b4bbbfcb..0000000000
--- a/target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 9b78d919632b7149d311aaad5a977e4b48b10321 Mon Sep 17 00:00:00 2001
-From: Paolo Abeni <pabeni@redhat.com>
-Date: Wed, 26 Apr 2023 10:15:31 +0200
-Subject: [PATCH] net: phy: hide the PHYLIB_LEDS knob
-
-commit 4bb7aac70b5d ("net: phy: fix circular LEDS_CLASS dependencies")
-solved a build failure, but introduces a new config knob with a default
-'y' value: PHYLIB_LEDS.
-
-The latter is against the current new config policy. The exception
-was raised to allow the user to catch bad configurations without led
-support.
-
-Anyway the current definition of PHYLIB_LEDS does not fit the above
-goal: if LEDS_CLASS is disabled, the new config will be available
-only with PHYLIB disabled, too.
-
-Hide the mentioned config, to preserve the randconfig testing done so
-far, while respecting the mentioned policy.
-
-Suggested-by: Andrew Lunn <andrew@lunn.ch>
-Suggested-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Link: https://lore.kernel.org/r/d82489be8ed911c383c3447e9abf469995ccf39a.1682496488.git.pabeni@redhat.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/Kconfig | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -45,10 +45,8 @@ config LED_TRIGGER_PHY
- for any speed known to the PHY.
-
- config PHYLIB_LEDS
-- bool "Support probing LEDs from device tree"
-+ def_bool OF
- depends on LEDS_CLASS=y || LEDS_CLASS=PHYLIB
-- depends on OF
-- default y
- help
- When LED class support is enabled, phylib can automatically
- probe LED setting from device tree.
diff --git a/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch b/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch
deleted file mode 100644
index 8d391678ff..0000000000
--- a/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 12ce20e02e532f101b725d71c52a36c5cc8ad1e6 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sun, 4 Feb 2024 00:54:01 +0100
-Subject: [PATCH] leds: trigger: netdev: Fix kernel panic on interface rename
- trig notify
-
-Commit d5e01266e7f5 ("leds: trigger: netdev: add additional specific link
-speed mode") in the various changes, reworked the way to set the LINKUP
-mode in commit cee4bd16c319 ("leds: trigger: netdev: Recheck
-NETDEV_LED_MODE_LINKUP on dev rename") and moved it to a generic function.
-
-This changed the logic where, in the previous implementation the dev
-from the trigger event was used to check if the carrier was ok, but in
-the new implementation with the generic function, the dev in
-trigger_data is used instead.
-
-This is problematic and cause a possible kernel panic due to the fact
-that the dev in the trigger_data still reference the old one as the
-new one (passed from the trigger event) still has to be hold and saved
-in the trigger_data struct (done in the NETDEV_REGISTER case).
-
-On calling of get_device_state(), an invalid net_dev is used and this
-cause a kernel panic.
-
-To handle this correctly, move the call to get_device_state() after the
-new net_dev is correctly set in trigger_data (in the NETDEV_REGISTER
-case) and correctly parse the new dev.
-
-Fixes: d5e01266e7f5 ("leds: trigger: netdev: add additional specific link speed mode")
-Cc: stable@vger.kernel.org
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/20240203235413.1146-1-ansuelsmth@gmail.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/trigger/ledtrig-netdev.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/trigger/ledtrig-netdev.c
-+++ b/drivers/leds/trigger/ledtrig-netdev.c
-@@ -489,12 +489,12 @@ static int netdev_trig_notify(struct not
- trigger_data->duplex = DUPLEX_UNKNOWN;
- switch (evt) {
- case NETDEV_CHANGENAME:
-- get_device_state(trigger_data);
-- fallthrough;
- case NETDEV_REGISTER:
- dev_put(trigger_data->net_dev);
- dev_hold(dev);
- trigger_data->net_dev = dev;
-+ if (evt == NETDEV_CHANGENAME)
-+ get_device_state(trigger_data);
- break;
- case NETDEV_UNREGISTER:
- dev_put(trigger_data->net_dev);
diff --git a/target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch b/target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch
deleted file mode 100644
index 1bf5196790..0000000000
--- a/target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From a38a6e5d2dc41feeaa839cd61196f86c0ee223b8 Mon Sep 17 00:00:00 2001
-From: Johan Hovold <johan+linaro@kernel.org>
-Date: Fri, 4 Nov 2022 10:39:13 +0100
-Subject: [PATCH 01/13] bus: mhi: host: pci_generic: add support for
- sc8280xp-crd SDX55 variant
-
-The SC8280XP Compute Reference Design (CRD) has an on-PCB SDX55 modem
-which uses MBIM.
-
-The exact channel configuration is not known but the Foxconn SDX55
-configuration allows the modem to be used so reuse that one for now.
-
-Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Link: https://lore.kernel.org/r/20221104093913.23347-1-johan+linaro@kernel.org
-[mani: modified the subject to format "bus: mhi: host"]
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -542,6 +542,8 @@ static const struct mhi_pci_dev_info mhi
- static const struct pci_device_id mhi_pci_id_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304),
- .driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info },
-+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c),
-+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },
- /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200),
- .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info },
diff --git a/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch b/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch
deleted file mode 100644
index 0dabc48bfa..0000000000
--- a/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 6a150325917a6df9467beeaa6518ab91ada81d97 Mon Sep 17 00:00:00 2001
-From: Song Fuchang <song.fc@gmail.com>
-Date: Mon, 7 Nov 2022 19:18:35 +0530
-Subject: [PATCH 02/13] bus: mhi: host: pci_generic: Add HP variant of T99W175
-
-The Foxconn T99W175 modem has an HP variant, which has
-the following output from lspci:
-
-01:00.0 Wireless controller [0d40]: Device 03f0:0a6c
-
-It also has some HP-specific serial numbers on the
-metal case. It works well with this driver, so add
-support for this to the pci_generic driver.
-
-Signed-off-by: Song Fuchang <song.fc@gmail.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-[mani: manually applied the patch]
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -596,6 +596,9 @@ static const struct pci_device_id mhi_pc
- /* MV32-WB (Cinterion) */
- { PCI_DEVICE(0x1269, 0x00bb),
- .driver_data = (kernel_ulong_t) &mhi_mv32_info },
-+ /* T99W175 (sdx55), HP variant */
-+ { PCI_DEVICE(0x03f0, 0x0a6c),
-+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },
- { }
- };
- MODULE_DEVICE_TABLE(pci, mhi_pci_id_table);
diff --git a/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch b/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch
deleted file mode 100644
index fbf6c8a501..0000000000
--- a/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From e8bc362f158f45185778e2bec081146aeeb283b5 Mon Sep 17 00:00:00 2001
-From: Slark Xiao <slark_xiao@163.com>
-Date: Mon, 7 Nov 2022 19:27:00 +0800
-Subject: [PATCH 03/13] bus: mhi: host: pci_generic: Add definition for some
- VIDs
-
-To make code neat and for convenience purpose, add definition for some
-VIDs. Adding it locally until these VIDs are used in multiple places.
-
-Signed-off-by: Slark Xiao <slark_xiao@163.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Link: https://lore.kernel.org/r/20221107112700.773-1-slark_xiao@163.com
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 18 +++++++++++-------
- 1 file changed, 11 insertions(+), 7 deletions(-)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -24,6 +24,10 @@
-
- #define HEALTH_CHECK_PERIOD (HZ * 2)
-
-+/* PCI VID definitions */
-+#define PCI_VENDOR_ID_THALES 0x1269
-+#define PCI_VENDOR_ID_QUECTEL 0x1eac
-+
- /**
- * struct mhi_pci_dev_info - MHI PCI device specific information
- * @config: MHI controller configuration
-@@ -557,11 +561,11 @@ static const struct pci_device_id mhi_pc
- .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
- .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
-- { PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */
-+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
-- { PCI_DEVICE(0x1eac, 0x1002), /* EM160R-GL (sdx24) */
-+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
-- { PCI_DEVICE(0x1eac, 0x2001), /* EM120R-GL for FCCL (sdx24) */
-+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- /* T99W175 (sdx55), Both for eSIM and Non-eSIM */
- { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab),
-@@ -585,16 +589,16 @@ static const struct pci_device_id mhi_pc
- { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9),
- .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
- /* MV31-W (Cinterion) */
-- { PCI_DEVICE(0x1269, 0x00b3),
-+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3),
- .driver_data = (kernel_ulong_t) &mhi_mv31_info },
- /* MV31-W (Cinterion), based on new baseline */
-- { PCI_DEVICE(0x1269, 0x00b4),
-+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b4),
- .driver_data = (kernel_ulong_t) &mhi_mv31_info },
- /* MV32-WA (Cinterion) */
-- { PCI_DEVICE(0x1269, 0x00ba),
-+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00ba),
- .driver_data = (kernel_ulong_t) &mhi_mv32_info },
- /* MV32-WB (Cinterion) */
-- { PCI_DEVICE(0x1269, 0x00bb),
-+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00bb),
- .driver_data = (kernel_ulong_t) &mhi_mv32_info },
- /* T99W175 (sdx55), HP variant */
- { PCI_DEVICE(0x03f0, 0x0a6c),
diff --git a/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch b/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch
deleted file mode 100644
index 2f5a0ac11d..0000000000
--- a/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 6c00e1e4e9817e85b8ba83024cfa88382f898841 Mon Sep 17 00:00:00 2001
-From: Bjorn Helgaas <bhelgaas@google.com>
-Date: Tue, 7 Mar 2023 14:16:25 -0600
-Subject: [PATCH 04/13] bus: mhi: host: pci_generic: Drop redundant
- pci_enable_pcie_error_reporting()
-
-pci_enable_pcie_error_reporting() enables the device to send ERR_*
-Messages. Since commit <f26e58bf6f54> ("PCI/AER: Enable error reporting
-when AER is native"), the PCI core does this for all devices during
-enumeration, so the driver doesn't need to do it itself.
-
-Remove the redundant pci_enable_pcie_error_reporting() call from the
-driver. Also remove the corresponding pci_disable_pcie_error_reporting()
-from the driver .remove() path.
-
-Note that this only controls ERR_* Messages from the device. An ERR_*
-Message may cause the Root Port to generate an interrupt, depending on the
-AER Root Error Command register managed by the AER service driver.
-
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
-Link: https://lore.kernel.org/r/20230307201625.879567-1-helgaas@kernel.org
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 8 +-------
- 1 file changed, 1 insertion(+), 7 deletions(-)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -8,7 +8,6 @@
- * Copyright (C) 2020 Linaro Ltd <loic.poulain@linaro.org>
- */
-
--#include <linux/aer.h>
- #include <linux/delay.h>
- #include <linux/device.h>
- #include <linux/mhi.h>
-@@ -901,11 +900,9 @@ static int mhi_pci_probe(struct pci_dev
- mhi_pdev->pci_state = pci_store_saved_state(pdev);
- pci_load_saved_state(pdev, NULL);
-
-- pci_enable_pcie_error_reporting(pdev);
--
- err = mhi_register_controller(mhi_cntrl, mhi_cntrl_config);
- if (err)
-- goto err_disable_reporting;
-+ return err;
-
- /* MHI bus does not power up the controller by default */
- err = mhi_prepare_for_power_up(mhi_cntrl);
-@@ -939,8 +936,6 @@ err_unprepare:
- mhi_unprepare_after_power_down(mhi_cntrl);
- err_unregister:
- mhi_unregister_controller(mhi_cntrl);
--err_disable_reporting:
-- pci_disable_pcie_error_reporting(pdev);
-
- return err;
- }
-@@ -963,7 +958,6 @@ static void mhi_pci_remove(struct pci_de
- pm_runtime_get_noresume(&pdev->dev);
-
- mhi_unregister_controller(mhi_cntrl);
-- pci_disable_pcie_error_reporting(pdev);
- }
-
- static void mhi_pci_shutdown(struct pci_dev *pdev)
diff --git a/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch b/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch
deleted file mode 100644
index f757ca28e5..0000000000
--- a/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 537350abfcc6b639884d1ef7bff35d31a624549b Mon Sep 17 00:00:00 2001
-From: Slark Xiao <slark_xiao@163.com>
-Date: Wed, 29 Mar 2023 15:22:39 +0800
-Subject: [PATCH 05/13] bus: mhi: pci_generic: Add Foxconn T99W510
-
-The Foxconn T99W510 device is designed based on Qualcomm
-SDX24. Add 3 variants for different potential customer.
-
-Signed-off-by: Slark Xiao <slark_xiao@163.com>
-Link: https://lore.kernel.org/r/20230329072239.93632-1-slark_xiao@163.com
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -363,6 +363,15 @@ static const struct mhi_controller_confi
- .event_cfg = mhi_foxconn_sdx55_events,
- };
-
-+static const struct mhi_pci_dev_info mhi_foxconn_sdx24_info = {
-+ .name = "foxconn-sdx24",
-+ .config = &modem_foxconn_sdx55_config,
-+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM,
-+ .dma_data_width = 32,
-+ .mru_default = 32768,
-+ .sideband_wake = false,
-+};
-+
- static const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = {
- .name = "foxconn-sdx55",
- .fw = "qcom/sdx55m/sbl1.mbn",
-@@ -587,6 +596,15 @@ static const struct pci_device_id mhi_pc
- /* T99W373 (sdx62) */
- { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9),
- .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
-+ /* T99W510 (sdx24), variant 1 */
-+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f0),
-+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info },
-+ /* T99W510 (sdx24), variant 2 */
-+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f1),
-+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info },
-+ /* T99W510 (sdx24), variant 3 */
-+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f2),
-+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info },
- /* MV31-W (Cinterion) */
- { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3),
- .driver_data = (kernel_ulong_t) &mhi_mv31_info },
diff --git a/target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch b/target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch
deleted file mode 100644
index 8c319ebeb7..0000000000
--- a/target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 440b01a2a9a62352cfa355354d3a4de6c5d96adf Mon Sep 17 00:00:00 2001
-From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Date: Fri, 19 May 2023 19:28:03 +0530
-Subject: [PATCH 06/13] bus: mhi: host: pci_generic: Add support for IP_SW0
- channels
-
-IP_SW0 channels are used to transfer data over the networking interface
-between MHI endpoint and the host. Define the channels in the MHI v1
-channel config along with dedicated event rings.
-
-Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
-Link: https://lore.kernel.org/r/20230519135803.13850-1-manivannan.sadhasivam@linaro.org
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 26 ++++++++++++++++++++++----
- 1 file changed, 22 insertions(+), 4 deletions(-)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -212,6 +212,19 @@ struct mhi_pci_dev_info {
- .offload_channel = false, \
- }
-
-+#define MHI_EVENT_CONFIG_SW_DATA(ev_ring, el_count) \
-+ { \
-+ .num_elements = el_count, \
-+ .irq_moderation_ms = 0, \
-+ .irq = (ev_ring) + 1, \
-+ .priority = 1, \
-+ .mode = MHI_DB_BRST_DISABLE, \
-+ .data_type = MHI_ER_DATA, \
-+ .hardware_event = false, \
-+ .client_managed = false, \
-+ .offload_channel = false, \
-+ }
-+
- #define MHI_EVENT_CONFIG_HW_DATA(ev_ring, el_count, ch_num) \
- { \
- .num_elements = el_count, \
-@@ -237,8 +250,10 @@ static const struct mhi_channel_config m
- MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0),
- MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),
- MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),
-- MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2),
-- MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 3),
-+ MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2),
-+ MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 64, 3),
-+ MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 4),
-+ MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 5),
- };
-
- static struct mhi_event_config modem_qcom_v1_mhi_events[] = {
-@@ -246,9 +261,12 @@ static struct mhi_event_config modem_qco
- MHI_EVENT_CONFIG_CTRL(0, 64),
- /* DIAG dedicated event ring */
- MHI_EVENT_CONFIG_DATA(1, 128),
-+ /* Software channels dedicated event ring */
-+ MHI_EVENT_CONFIG_SW_DATA(2, 64),
-+ MHI_EVENT_CONFIG_SW_DATA(3, 64),
- /* Hardware channels request dedicated hardware event rings */
-- MHI_EVENT_CONFIG_HW_DATA(2, 1024, 100),
-- MHI_EVENT_CONFIG_HW_DATA(3, 2048, 101)
-+ MHI_EVENT_CONFIG_HW_DATA(4, 1024, 100),
-+ MHI_EVENT_CONFIG_HW_DATA(5, 2048, 101)
- };
-
- static const struct mhi_controller_config modem_qcom_v1_mhiv_config = {
diff --git a/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch b/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch
deleted file mode 100644
index 5c15eec712..0000000000
--- a/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 2dc36ddb6ca4eeda21204dc9e57750494c74c06d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Duke=20Xin=20=28=E8=BE=9B=E5=AE=89=E6=96=87=29?=
- <duke_xinanwen@163.com>
-Date: Thu, 8 Jun 2023 02:29:27 -0700
-Subject: [PATCH 07/13] bus: mhi: host: pci_generic: Add support for Quectel
- EM160R-GL modem
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This modem is identical to the previous EM160R-GL modem with same product
-name. But this one is designed for a specific laptop usecase, hence Quectel
-got a new PID.
-
-Signed-off-by: Duke Xin(辛安文) <duke_xinanwen@163.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Link: https://lore.kernel.org/r/20230608092927.2893-1-duke_xinanwen@163.com
-[mani: modified the commit message and subject]
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -591,6 +591,8 @@ static const struct pci_device_id mhi_pc
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
-+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x100d), /* EM160R-GL (sdx24) */
-+ .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- /* T99W175 (sdx55), Both for eSIM and Non-eSIM */
diff --git a/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch b/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
deleted file mode 100644
index 5922207e29..0000000000
--- a/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 7e2f6cb11c24799b6851142c4a5ce69bdc630364 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Duke=20Xin=20=28=E8=BE=9B=E5=AE=89=E6=96=87=29?=
- <duke_xinanwen@163.com>
-Date: Thu, 29 Jun 2023 23:23:18 -0700
-Subject: [PATCH 08/13] bus: mhi: host: pci_generic: Add support for Quectel
- RM520N-GL modem
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add MHI interface definition for RM520 product based on Qualcomm SDX6X chip
-
-Signed-off-by: Duke Xin(辛安文) <duke_xinanwen@163.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Link: https://lore.kernel.org/r/20230630062318.12114-1-duke_xinanwen@163.com
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -352,6 +352,16 @@ static const struct mhi_pci_dev_info mhi
- .sideband_wake = true,
- };
-
-+static const struct mhi_pci_dev_info mhi_quectel_rm5xx_info = {
-+ .name = "quectel-rm5xx",
-+ .edl = "qcom/prog_firehose_sdx6x.elf",
-+ .config = &modem_quectel_em1xx_config,
-+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM,
-+ .dma_data_width = 32,
-+ .mru_default = 32768,
-+ .sideband_wake = true,
-+};
-+
- static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = {
- MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 32, 0),
- MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 32, 0),
-@@ -591,6 +601,9 @@ static const struct pci_device_id mhi_pc
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
-+ /* RM520N-GL (sdx6x), eSIM */
-+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1004),
-+ .driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x100d), /* EM160R-GL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */
diff --git a/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch b/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch
deleted file mode 100644
index bb7b3c3ffc..0000000000
--- a/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 5e20ac8e7d3221e079e87066c4e8f4b64bd58ccb Mon Sep 17 00:00:00 2001
-From: Slark Xiao <slark_xiao@163.com>
-Date: Wed, 12 Jul 2023 16:37:41 +0800
-Subject: [PATCH 09/13] bus: mhi: host: pci_generic: Add support for Dell
- DW5932e
-
-The DW5932e has 2 variants: eSIM(DW5932e-eSIM) and non-eSIM(DW5932e).
-Both of them are designed based on Qualcomm SDX62 and it will
-align with the Foxconn sdx65 settings.
-
-Signed-off-by: Slark Xiao <slark_xiao@163.com>
-Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Link: https://lore.kernel.org/r/20230712083741.7615-1-slark_xiao@163.com
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -638,6 +638,12 @@ static const struct pci_device_id mhi_pc
- /* T99W510 (sdx24), variant 3 */
- { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f2),
- .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info },
-+ /* DW5932e-eSIM (sdx62), With eSIM */
-+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f5),
-+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
-+ /* DW5932e (sdx62), Non-eSIM */
-+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f9),
-+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
- /* MV31-W (Cinterion) */
- { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3),
- .driver_data = (kernel_ulong_t) &mhi_mv31_info },
diff --git a/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch b/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
deleted file mode 100644
index c0dfe01e32..0000000000
--- a/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 8be9e92a2c8f26fd7482acc2323c6dc2a4ad43aa Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Duke=20Xin=20=28=E8=BE=9B=E5=AE=89=E6=96=87=29?=
- <duke_xinanwen@163.com>
-Date: Sun, 6 Aug 2023 20:04:54 -0700
-Subject: [PATCH 10/13] bus: mhi: host: pci_generic: Add support for Quectel
- RM520N-GL Lenovo variant
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Quectel's RM520N-GL Lenovo variant is same as that of the existing
-RM520N-GL modem and uses the same config. But this one is designed for
-Lenovo laptop usecase, hence Quectel got a new PID.
-
-Signed-off-by: Duke Xin(辛安文) <duke_xinanwen@163.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
-Link: https://lore.kernel.org/r/20230807030454.37255-1-duke_xinanwen@163.com
-[mani: tweaked subject and commit message a bit]
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -604,6 +604,9 @@ static const struct pci_device_id mhi_pc
- /* RM520N-GL (sdx6x), eSIM */
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1004),
- .driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info },
-+ /* RM520N-GL (sdx6x), Lenovo variant */
-+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1007),
-+ .driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x100d), /* EM160R-GL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */
diff --git a/target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch b/target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch
deleted file mode 100644
index 40fdfc613b..0000000000
--- a/target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 30001cf3a19a2f676a0e23c2c3a511c4a8903284 Mon Sep 17 00:00:00 2001
-From: Daniele Palmas <dnlplm@gmail.com>
-Date: Fri, 4 Aug 2023 11:40:39 +0200
-Subject: [PATCH 11/13] bus: mhi: host: pci_generic: add support for Telit
- FE990 modem
-
-Add support for Telit FE990 that has the same configuration as FN990:
-
-$ lspci -vv
-04:00.0 Unassigned class [ff00]: Qualcomm Device 0308
- Subsystem: Device 1c5d:2015
-
-Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Link: https://lore.kernel.org/r/20230804094039.365102-1-dnlplm@gmail.com
-[mani: minor update to commit subject and adjusted comment]
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -595,6 +595,9 @@ static const struct pci_device_id mhi_pc
- /* Telit FN990 */
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),
- .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
-+ /* Telit FE990 */
-+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),
-+ .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
- .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */
diff --git a/target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch b/target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch
deleted file mode 100644
index 30d833adff..0000000000
--- a/target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch
+++ /dev/null
@@ -1,175 +0,0 @@
-From 6ab3d50b106c9aea123a80551a6c9deace83b914 Mon Sep 17 00:00:00 2001
-From: Qiang Yu <quic_qianyu@quicinc.com>
-Date: Tue, 7 Nov 2023 16:14:49 +0800
-Subject: [PATCH] bus: mhi: host: Add a separate timeout parameter for waiting
- ready
-
-Some devices(eg. SDX75) take longer than expected (default, 8 seconds) to
-set ready after reboot. Hence add optional ready timeout parameter and pass
-the appropriate timeout value to mhi_poll_reg_field() to wait enough for
-device ready as part of power up sequence.
-
-Signed-off-by: Qiang Yu <quic_qianyu@quicinc.com>
-Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Link: https://lore.kernel.org/r/1699344890-87076-2-git-send-email-quic_qianyu@quicinc.com
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/init.c | 1 +
- drivers/bus/mhi/host/internal.h | 2 +-
- drivers/bus/mhi/host/main.c | 5 +++--
- drivers/bus/mhi/host/pm.c | 24 +++++++++++++++++-------
- include/linux/mhi.h | 4 ++++
- 5 files changed, 26 insertions(+), 10 deletions(-)
-
---- a/drivers/bus/mhi/host/init.c
-+++ b/drivers/bus/mhi/host/init.c
-@@ -882,6 +882,7 @@ static int parse_config(struct mhi_contr
- if (!mhi_cntrl->timeout_ms)
- mhi_cntrl->timeout_ms = MHI_TIMEOUT_MS;
-
-+ mhi_cntrl->ready_timeout_ms = config->ready_timeout_ms;
- mhi_cntrl->bounce_buf = config->use_bounce_buf;
- mhi_cntrl->buffer_len = config->buf_len;
- if (!mhi_cntrl->buffer_len)
---- a/drivers/bus/mhi/host/internal.h
-+++ b/drivers/bus/mhi/host/internal.h
-@@ -324,7 +324,7 @@ int __must_check mhi_read_reg_field(stru
- u32 *out);
- int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl,
- void __iomem *base, u32 offset, u32 mask,
-- u32 val, u32 delayus);
-+ u32 val, u32 delayus, u32 timeout_ms);
- void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base,
- u32 offset, u32 val);
- int __must_check mhi_write_reg_field(struct mhi_controller *mhi_cntrl,
---- a/drivers/bus/mhi/host/main.c
-+++ b/drivers/bus/mhi/host/main.c
-@@ -40,10 +40,11 @@ int __must_check mhi_read_reg_field(stru
-
- int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl,
- void __iomem *base, u32 offset,
-- u32 mask, u32 val, u32 delayus)
-+ u32 mask, u32 val, u32 delayus,
-+ u32 timeout_ms)
- {
- int ret;
-- u32 out, retry = (mhi_cntrl->timeout_ms * 1000) / delayus;
-+ u32 out, retry = (timeout_ms * 1000) / delayus;
-
- while (retry--) {
- ret = mhi_read_reg_field(mhi_cntrl, base, offset, mask, &out);
---- a/drivers/bus/mhi/host/pm.c
-+++ b/drivers/bus/mhi/host/pm.c
-@@ -171,6 +171,7 @@ int mhi_ready_state_transition(struct mh
- enum mhi_pm_state cur_state;
- struct device *dev = &mhi_cntrl->mhi_dev->dev;
- u32 interval_us = 25000; /* poll register field every 25 milliseconds */
-+ u32 timeout_ms;
- int ret, i;
-
- /* Check if device entered error state */
-@@ -181,14 +182,18 @@ int mhi_ready_state_transition(struct mh
-
- /* Wait for RESET to be cleared and READY bit to be set by the device */
- ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
-- MHICTRL_RESET_MASK, 0, interval_us);
-+ MHICTRL_RESET_MASK, 0, interval_us,
-+ mhi_cntrl->timeout_ms);
- if (ret) {
- dev_err(dev, "Device failed to clear MHI Reset\n");
- return ret;
- }
-
-+ timeout_ms = mhi_cntrl->ready_timeout_ms ?
-+ mhi_cntrl->ready_timeout_ms : mhi_cntrl->timeout_ms;
- ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS,
-- MHISTATUS_READY_MASK, 1, interval_us);
-+ MHISTATUS_READY_MASK, 1, interval_us,
-+ timeout_ms);
- if (ret) {
- dev_err(dev, "Device failed to enter MHI Ready\n");
- return ret;
-@@ -487,7 +492,7 @@ static void mhi_pm_disable_transition(st
-
- /* Wait for the reset bit to be cleared by the device */
- ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
-- MHICTRL_RESET_MASK, 0, 25000);
-+ MHICTRL_RESET_MASK, 0, 25000, mhi_cntrl->timeout_ms);
- if (ret)
- dev_err(dev, "Device failed to clear MHI Reset\n");
-
-@@ -500,8 +505,8 @@ static void mhi_pm_disable_transition(st
- if (!MHI_IN_PBL(mhi_get_exec_env(mhi_cntrl))) {
- /* wait for ready to be set */
- ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs,
-- MHISTATUS,
-- MHISTATUS_READY_MASK, 1, 25000);
-+ MHISTATUS, MHISTATUS_READY_MASK,
-+ 1, 25000, mhi_cntrl->timeout_ms);
- if (ret)
- dev_err(dev, "Device failed to enter READY state\n");
- }
-@@ -1125,7 +1130,8 @@ int mhi_async_power_up(struct mhi_contro
- if (state == MHI_STATE_SYS_ERR) {
- mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET);
- ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
-- MHICTRL_RESET_MASK, 0, interval_us);
-+ MHICTRL_RESET_MASK, 0, interval_us,
-+ mhi_cntrl->timeout_ms);
- if (ret) {
- dev_info(dev, "Failed to reset MHI due to syserr state\n");
- goto error_exit;
-@@ -1216,14 +1222,18 @@ EXPORT_SYMBOL_GPL(mhi_power_down);
- int mhi_sync_power_up(struct mhi_controller *mhi_cntrl)
- {
- int ret = mhi_async_power_up(mhi_cntrl);
-+ u32 timeout_ms;
-
- if (ret)
- return ret;
-
-+ /* Some devices need more time to set ready during power up */
-+ timeout_ms = mhi_cntrl->ready_timeout_ms ?
-+ mhi_cntrl->ready_timeout_ms : mhi_cntrl->timeout_ms;
- wait_event_timeout(mhi_cntrl->state_event,
- MHI_IN_MISSION_MODE(mhi_cntrl->ee) ||
- MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state),
-- msecs_to_jiffies(mhi_cntrl->timeout_ms));
-+ msecs_to_jiffies(timeout_ms));
-
- ret = (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) ? 0 : -ETIMEDOUT;
- if (ret)
---- a/include/linux/mhi.h
-+++ b/include/linux/mhi.h
-@@ -266,6 +266,7 @@ struct mhi_event_config {
- * struct mhi_controller_config - Root MHI controller configuration
- * @max_channels: Maximum number of channels supported
- * @timeout_ms: Timeout value for operations. 0 means use default
-+ * @ready_timeout_ms: Timeout value for waiting device to be ready (optional)
- * @buf_len: Size of automatically allocated buffers. 0 means use default
- * @num_channels: Number of channels defined in @ch_cfg
- * @ch_cfg: Array of defined channels
-@@ -277,6 +278,7 @@ struct mhi_event_config {
- struct mhi_controller_config {
- u32 max_channels;
- u32 timeout_ms;
-+ u32 ready_timeout_ms;
- u32 buf_len;
- u32 num_channels;
- const struct mhi_channel_config *ch_cfg;
-@@ -326,6 +328,7 @@ struct mhi_controller_config {
- * @pm_mutex: Mutex for suspend/resume operation
- * @pm_lock: Lock for protecting MHI power management state
- * @timeout_ms: Timeout in ms for state transitions
-+ * @ready_timeout_ms: Timeout in ms for waiting device to be ready (optional)
- * @pm_state: MHI power management state
- * @db_access: DB access states
- * @ee: MHI device execution environment
-@@ -413,6 +416,7 @@ struct mhi_controller {
- struct mutex pm_mutex;
- rwlock_t pm_lock;
- u32 timeout_ms;
-+ u32 ready_timeout_ms;
- u32 pm_state;
- u32 db_access;
- enum mhi_ee_type ee;
diff --git a/target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch b/target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch
deleted file mode 100644
index 944747ac56..0000000000
--- a/target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From b2f401efbff8878be31b2bce6e8d7bdad23e6f12 Mon Sep 17 00:00:00 2001
-From: Qiang Yu <quic_qianyu@quicinc.com>
-Date: Tue, 7 Nov 2023 16:14:50 +0800
-Subject: [PATCH 12/13] bus: mhi: host: pci_generic: Add SDX75 based modem
- support
-
-Add generic info for SDX75 based modems. SDX75 takes longer to set ready
-during power up. Hence use separate configuration.
-
-Signed-off-by: Qiang Yu <quic_qianyu@quicinc.com>
-Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Link: https://lore.kernel.org/r/1699344890-87076-3-git-send-email-quic_qianyu@quicinc.com
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -269,6 +269,16 @@ static struct mhi_event_config modem_qco
- MHI_EVENT_CONFIG_HW_DATA(5, 2048, 101)
- };
-
-+static const struct mhi_controller_config modem_qcom_v2_mhiv_config = {
-+ .max_channels = 128,
-+ .timeout_ms = 8000,
-+ .ready_timeout_ms = 50000,
-+ .num_channels = ARRAY_SIZE(modem_qcom_v1_mhi_channels),
-+ .ch_cfg = modem_qcom_v1_mhi_channels,
-+ .num_events = ARRAY_SIZE(modem_qcom_v1_mhi_events),
-+ .event_cfg = modem_qcom_v1_mhi_events,
-+};
-+
- static const struct mhi_controller_config modem_qcom_v1_mhiv_config = {
- .max_channels = 128,
- .timeout_ms = 8000,
-@@ -278,6 +288,16 @@ static const struct mhi_controller_confi
- .event_cfg = modem_qcom_v1_mhi_events,
- };
-
-+static const struct mhi_pci_dev_info mhi_qcom_sdx75_info = {
-+ .name = "qcom-sdx75m",
-+ .fw = "qcom/sdx75m/xbl.elf",
-+ .edl = "qcom/sdx75m/edl.mbn",
-+ .config = &modem_qcom_v2_mhiv_config,
-+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM,
-+ .dma_data_width = 32,
-+ .sideband_wake = false,
-+};
-+
- static const struct mhi_pci_dev_info mhi_qcom_sdx65_info = {
- .name = "qcom-sdx65m",
- .fw = "qcom/sdx65m/xbl.elf",
-@@ -600,6 +620,8 @@ static const struct pci_device_id mhi_pc
- .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
- .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
-+ { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309),
-+ .driver_data = (kernel_ulong_t) &mhi_qcom_sdx75_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */
- .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */
diff --git a/target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch b/target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch
deleted file mode 100644
index 085e8862ae..0000000000
--- a/target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 5f157aa89b876e82d6aafb2d009979118d0bdd2b Mon Sep 17 00:00:00 2001
-From: Jeff Johnson <quic_jjohnson@quicinc.com>
-Date: Thu, 22 Feb 2024 18:00:23 -0800
-Subject: [PATCH 13/13] bus: mhi: host: pci_generic: constify
- modem_telit_fn980_hw_v1_config
-
-MHI expects the controller configs to be const, and all of the other ones
-in this file already are, so constify modem_telit_fn980_hw_v1_config.
-
-Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Link: https://lore.kernel.org/r/20240222-mhi-const-bus-mhi-host-pci_generic-v1-1-d4c9b0b0a7a5@quicinc.com
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -538,7 +538,7 @@ static struct mhi_event_config mhi_telit
- MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101)
- };
-
--static struct mhi_controller_config modem_telit_fn980_hw_v1_config = {
-+static const struct mhi_controller_config modem_telit_fn980_hw_v1_config = {
- .max_channels = 128,
- .timeout_ms = 20000,
- .num_channels = ARRAY_SIZE(mhi_telit_fn980_hw_v1_channels),
diff --git a/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch b/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch
deleted file mode 100644
index 23681ba937..0000000000
--- a/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 8781ba7f45695af3ab8e8d1b55a31f527c9201a3 Mon Sep 17 00:00:00 2001
-From: Aren Moynihan <aren@peacevolution.org>
-Date: Thu, 8 Dec 2022 17:02:26 -0500
-Subject: [PATCH] mfd: axp20x: Fix order of pek rise and fall events
-
-The power button can get "stuck" if the rising edge and falling edge irq
-are read in the same pass. This can often be triggered when resuming
-from suspend if the power button is released before the kernel handles
-the interrupt.
-
-Swapping the order of the rise and fall events makes sure that the press
-event is handled first, which prevents this situation.
-
-Signed-off-by: Aren Moynihan <aren@peacevolution.org>
-Reviewed-by: Samuel Holland <samuel@sholland.org>
-Tested-by: Samuel Holland <samuel@sholland.org>
-Acked-by: Chen-Yu Tsai <wens@csie.org>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20221208220225.635414-1-aren@peacevolution.org
----
- include/linux/mfd/axp20x.h | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
---- a/include/linux/mfd/axp20x.h
-+++ b/include/linux/mfd/axp20x.h
-@@ -432,8 +432,9 @@ enum {
- AXP152_IRQ_PEK_SHORT,
- AXP152_IRQ_PEK_LONG,
- AXP152_IRQ_TIMER,
-- AXP152_IRQ_PEK_RIS_EDGE,
-+ /* out of bit order to make sure the press event is handled first */
- AXP152_IRQ_PEK_FAL_EDGE,
-+ AXP152_IRQ_PEK_RIS_EDGE,
- AXP152_IRQ_GPIO3_INPUT,
- AXP152_IRQ_GPIO2_INPUT,
- AXP152_IRQ_GPIO1_INPUT,
-@@ -472,8 +473,9 @@ enum {
- AXP20X_IRQ_LOW_PWR_LVL1,
- AXP20X_IRQ_LOW_PWR_LVL2,
- AXP20X_IRQ_TIMER,
-- AXP20X_IRQ_PEK_RIS_EDGE,
-+ /* out of bit order to make sure the press event is handled first */
- AXP20X_IRQ_PEK_FAL_EDGE,
-+ AXP20X_IRQ_PEK_RIS_EDGE,
- AXP20X_IRQ_GPIO3_INPUT,
- AXP20X_IRQ_GPIO2_INPUT,
- AXP20X_IRQ_GPIO1_INPUT,
-@@ -502,8 +504,9 @@ enum axp22x_irqs {
- AXP22X_IRQ_LOW_PWR_LVL1,
- AXP22X_IRQ_LOW_PWR_LVL2,
- AXP22X_IRQ_TIMER,
-- AXP22X_IRQ_PEK_RIS_EDGE,
-+ /* out of bit order to make sure the press event is handled first */
- AXP22X_IRQ_PEK_FAL_EDGE,
-+ AXP22X_IRQ_PEK_RIS_EDGE,
- AXP22X_IRQ_GPIO1_INPUT,
- AXP22X_IRQ_GPIO0_INPUT,
- };
-@@ -571,8 +574,9 @@ enum axp803_irqs {
- AXP803_IRQ_LOW_PWR_LVL1,
- AXP803_IRQ_LOW_PWR_LVL2,
- AXP803_IRQ_TIMER,
-- AXP803_IRQ_PEK_RIS_EDGE,
-+ /* out of bit order to make sure the press event is handled first */
- AXP803_IRQ_PEK_FAL_EDGE,
-+ AXP803_IRQ_PEK_RIS_EDGE,
- AXP803_IRQ_PEK_SHORT,
- AXP803_IRQ_PEK_LONG,
- AXP803_IRQ_PEK_OVER_OFF,
-@@ -623,8 +627,9 @@ enum axp809_irqs {
- AXP809_IRQ_LOW_PWR_LVL1,
- AXP809_IRQ_LOW_PWR_LVL2,
- AXP809_IRQ_TIMER,
-- AXP809_IRQ_PEK_RIS_EDGE,
-+ /* out of bit order to make sure the press event is handled first */
- AXP809_IRQ_PEK_FAL_EDGE,
-+ AXP809_IRQ_PEK_RIS_EDGE,
- AXP809_IRQ_PEK_SHORT,
- AXP809_IRQ_PEK_LONG,
- AXP809_IRQ_PEK_OVER_OFF,
diff --git a/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch b/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch
deleted file mode 100644
index b742276c8a..0000000000
--- a/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 1b1305e95e85624f538ec56db9acf88e2d3d7397 Mon Sep 17 00:00:00 2001
-From: Samuel Holland <samuel@sholland.org>
-Date: Wed, 28 Dec 2022 10:27:52 -0600
-Subject: [PATCH] mfd: axp20x: Switch to the sys-off handler API
-
-This removes a layer of indirection through pm_power_off() and allows
-the PMIC handler to be used as a fallback when firmware power off fails.
-This happens on boards like the Clockwork DevTerm R-01 where OpenSBI
-does not know how to use the PMIC to power off the board.
-
-Move the check for AXP288 to avoid registering a dummy handler.
-
-Signed-off-by: Samuel Holland <samuel@sholland.org>
-[Lee: Removed superfluous new line]
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20221228162752.14204-1-samuel@sholland.org
----
- drivers/mfd/axp20x.c | 27 +++++++++++----------------
- 1 file changed, 11 insertions(+), 16 deletions(-)
-
---- a/drivers/mfd/axp20x.c
-+++ b/drivers/mfd/axp20x.c
-@@ -23,7 +23,7 @@
- #include <linux/mfd/core.h>
- #include <linux/module.h>
- #include <linux/of_device.h>
--#include <linux/pm_runtime.h>
-+#include <linux/reboot.h>
- #include <linux/regmap.h>
- #include <linux/regulator/consumer.h>
-
-@@ -832,17 +832,16 @@ static const struct mfd_cell axp813_cell
- },
- };
-
--static struct axp20x_dev *axp20x_pm_power_off;
--static void axp20x_power_off(void)
-+static int axp20x_power_off(struct sys_off_data *data)
- {
-- if (axp20x_pm_power_off->variant == AXP288_ID)
-- return;
-+ struct axp20x_dev *axp20x = data->cb_data;
-
-- regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
-- AXP20X_OFF);
-+ regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
-
- /* Give capacitors etc. time to drain to avoid kernel panic msg. */
- mdelay(500);
-+
-+ return NOTIFY_DONE;
- }
-
- int axp20x_match_device(struct axp20x_dev *axp20x)
-@@ -1009,10 +1008,11 @@ int axp20x_device_probe(struct axp20x_de
- return ret;
- }
-
-- if (!pm_power_off) {
-- axp20x_pm_power_off = axp20x;
-- pm_power_off = axp20x_power_off;
-- }
-+ if (axp20x->variant != AXP288_ID)
-+ devm_register_sys_off_handler(axp20x->dev,
-+ SYS_OFF_MODE_POWER_OFF,
-+ SYS_OFF_PRIO_DEFAULT,
-+ axp20x_power_off, axp20x);
-
- dev_info(axp20x->dev, "AXP20X driver loaded\n");
-
-@@ -1022,11 +1022,6 @@ EXPORT_SYMBOL(axp20x_device_probe);
-
- void axp20x_device_remove(struct axp20x_dev *axp20x)
- {
-- if (axp20x == axp20x_pm_power_off) {
-- axp20x_pm_power_off = NULL;
-- pm_power_off = NULL;
-- }
--
- mfd_remove_devices(axp20x->dev);
- regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
- }
diff --git a/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch b/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch
deleted file mode 100644
index b84815e1a8..0000000000
--- a/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 2405fbfb384ef39e9560d76d3f6e4c90519f90aa Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Wed, 29 Mar 2023 22:55:44 +0200
-Subject: [PATCH] mfd: axp20x: Fix axp288 writable-ranges
-
-Register AXP288_POWER_REASON is writable and needs to be written
-to reset the reset- / power-on-reason bits.
-
-Add it to the axp288 writable-ranges so that the extcon-axp288
-driver can properly clear the reset- / power-on-reason bits.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/20230329205544.1051393-1-hdegoede@redhat.com
----
- drivers/mfd/axp20x.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mfd/axp20x.c
-+++ b/drivers/mfd/axp20x.c
-@@ -119,6 +119,7 @@ static const struct regmap_access_table
-
- /* AXP288 ranges are shared with the AXP803, as they cover the same range */
- static const struct regmap_range axp288_writeable_ranges[] = {
-+ regmap_reg_range(AXP288_POWER_REASON, AXP288_POWER_REASON),
- regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
- regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
- };
diff --git a/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch b/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch
deleted file mode 100644
index 83ef60aecd..0000000000
--- a/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch
+++ /dev/null
@@ -1,343 +0,0 @@
-From e0f8ad2a705367518b5c56bf9d6da89681467c02 Mon Sep 17 00:00:00 2001
-From: Shengyu Qu <wiagn233@outlook.com>
-Date: Fri, 21 Apr 2023 23:08:15 +0800
-Subject: [PATCH] mfd: axp20x: Add support for AXP15060 PMIC
-
-The AXP15060 is a PMIC chip produced by X-Powers, and could be connected
-via an I2C bus.
-
-Describe the regmap and the MFD bits, along with the registers exposed
-via I2C. Eventually advertise the device using a new compatible string
-and add support for power off the system.
-
-The driver would disable PEK function if IRQ is not configured in device
-tree, since some boards (For example, Starfive Visionfive 2) didn't
-connect IRQ line of PMIC to SOC.
-
-GPIO function isn't enabled in this commit, since its configuration
-operation is different from any existing AXP PMICs and needs
-logic modification on existing driver. GPIO support might come in later
-patches.
-
-Signed-off-by: Shengyu Qu <wiagn233@outlook.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Lee Jones <lee@kernel.org>
-Link: https://lore.kernel.org/r/TY3P286MB261162D57695AC8164ED50E298609@TY3P286MB2611.JPNP286.PROD.OUTLOOK.COM
----
- drivers/mfd/axp20x-i2c.c | 2 +
- drivers/mfd/axp20x.c | 107 +++++++++++++++++++++++++++++++++++++
- include/linux/mfd/axp20x.h | 85 +++++++++++++++++++++++++++++
- 3 files changed, 194 insertions(+)
-
---- a/drivers/mfd/axp20x-i2c.c
-+++ b/drivers/mfd/axp20x-i2c.c
-@@ -66,6 +66,7 @@ static const struct of_device_id axp20x_
- { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
- { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
- { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
-+ { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
- { },
- };
- MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
-@@ -79,6 +80,7 @@ static const struct i2c_device_id axp20x
- { "axp223", 0 },
- { "axp803", 0 },
- { "axp806", 0 },
-+ { "axp15060", 0 },
- { },
- };
- MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
---- a/drivers/mfd/axp20x.c
-+++ b/drivers/mfd/axp20x.c
-@@ -43,6 +43,7 @@ static const char * const axp20x_model_n
- "AXP806",
- "AXP809",
- "AXP813",
-+ "AXP15060",
- };
-
- static const struct regmap_range axp152_writeable_ranges[] = {
-@@ -169,6 +170,31 @@ static const struct regmap_access_table
- .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges),
- };
-
-+static const struct regmap_range axp15060_writeable_ranges[] = {
-+ regmap_reg_range(AXP15060_PWR_OUT_CTRL1, AXP15060_DCDC_MODE_CTRL2),
-+ regmap_reg_range(AXP15060_OUTPUT_MONITOR_DISCHARGE, AXP15060_CPUSLDO_V_CTRL),
-+ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
-+ regmap_reg_range(AXP15060_PEK_KEY, AXP15060_PEK_KEY),
-+ regmap_reg_range(AXP15060_IRQ1_EN, AXP15060_IRQ2_EN),
-+ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
-+};
-+
-+static const struct regmap_range axp15060_volatile_ranges[] = {
-+ regmap_reg_range(AXP15060_STARTUP_SRC, AXP15060_STARTUP_SRC),
-+ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
-+ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
-+};
-+
-+static const struct regmap_access_table axp15060_writeable_table = {
-+ .yes_ranges = axp15060_writeable_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(axp15060_writeable_ranges),
-+};
-+
-+static const struct regmap_access_table axp15060_volatile_table = {
-+ .yes_ranges = axp15060_volatile_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(axp15060_volatile_ranges),
-+};
-+
- static const struct resource axp152_pek_resources[] = {
- DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
-@@ -237,6 +263,11 @@ static const struct resource axp809_pek_
- DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- };
-
-+static const struct resource axp15060_pek_resources[] = {
-+ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
-+ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
-+};
-+
- static const struct regmap_config axp152_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-@@ -282,6 +313,15 @@ static const struct regmap_config axp806
- .cache_type = REGCACHE_RBTREE,
- };
-
-+static const struct regmap_config axp15060_regmap_config = {
-+ .reg_bits = 8,
-+ .val_bits = 8,
-+ .wr_table = &axp15060_writeable_table,
-+ .volatile_table = &axp15060_volatile_table,
-+ .max_register = AXP15060_IRQ2_STATE,
-+ .cache_type = REGCACHE_RBTREE,
-+};
-+
- #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \
- [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
-
-@@ -503,6 +543,23 @@ static const struct regmap_irq axp809_re
- INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0),
- };
-
-+static const struct regmap_irq axp15060_regmap_irqs[] = {
-+ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV1, 0, 0),
-+ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV2, 0, 1),
-+ INIT_REGMAP_IRQ(AXP15060, DCDC1_V_LOW, 0, 2),
-+ INIT_REGMAP_IRQ(AXP15060, DCDC2_V_LOW, 0, 3),
-+ INIT_REGMAP_IRQ(AXP15060, DCDC3_V_LOW, 0, 4),
-+ INIT_REGMAP_IRQ(AXP15060, DCDC4_V_LOW, 0, 5),
-+ INIT_REGMAP_IRQ(AXP15060, DCDC5_V_LOW, 0, 6),
-+ INIT_REGMAP_IRQ(AXP15060, DCDC6_V_LOW, 0, 7),
-+ INIT_REGMAP_IRQ(AXP15060, PEK_LONG, 1, 0),
-+ INIT_REGMAP_IRQ(AXP15060, PEK_SHORT, 1, 1),
-+ INIT_REGMAP_IRQ(AXP15060, GPIO1_INPUT, 1, 2),
-+ INIT_REGMAP_IRQ(AXP15060, PEK_FAL_EDGE, 1, 3),
-+ INIT_REGMAP_IRQ(AXP15060, PEK_RIS_EDGE, 1, 4),
-+ INIT_REGMAP_IRQ(AXP15060, GPIO2_INPUT, 1, 5),
-+};
-+
- static const struct regmap_irq_chip axp152_regmap_irq_chip = {
- .name = "axp152_irq_chip",
- .status_base = AXP152_IRQ1_STATE,
-@@ -589,6 +646,17 @@ static const struct regmap_irq_chip axp8
- .num_regs = 5,
- };
-
-+static const struct regmap_irq_chip axp15060_regmap_irq_chip = {
-+ .name = "axp15060",
-+ .status_base = AXP15060_IRQ1_STATE,
-+ .ack_base = AXP15060_IRQ1_STATE,
-+ .unmask_base = AXP15060_IRQ1_EN,
-+ .init_ack_masked = true,
-+ .irqs = axp15060_regmap_irqs,
-+ .num_irqs = ARRAY_SIZE(axp15060_regmap_irqs),
-+ .num_regs = 2,
-+};
-+
- static const struct mfd_cell axp20x_cells[] = {
- {
- .name = "axp20x-gpio",
-@@ -833,6 +901,23 @@ static const struct mfd_cell axp813_cell
- },
- };
-
-+static const struct mfd_cell axp15060_cells[] = {
-+ {
-+ .name = "axp221-pek",
-+ .num_resources = ARRAY_SIZE(axp15060_pek_resources),
-+ .resources = axp15060_pek_resources,
-+ }, {
-+ .name = "axp20x-regulator",
-+ },
-+};
-+
-+/* For boards that don't have IRQ line connected to SOC. */
-+static const struct mfd_cell axp_regulator_only_cells[] = {
-+ {
-+ .name = "axp20x-regulator",
-+ },
-+};
-+
- static int axp20x_power_off(struct sys_off_data *data)
- {
- struct axp20x_dev *axp20x = data->cb_data;
-@@ -942,6 +1027,28 @@ int axp20x_match_device(struct axp20x_de
- */
- axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
- break;
-+ case AXP15060_ID:
-+ /*
-+ * Don't register the power key part if there is no interrupt
-+ * line.
-+ *
-+ * Since most use cases of AXP PMICs are Allwinner SOCs, board
-+ * designers follow Allwinner's reference design and connects
-+ * IRQ line to SOC, there's no need for those variants to deal
-+ * with cases that IRQ isn't connected. However, AXP15660 is
-+ * used by some other vendors' SOCs that didn't connect IRQ
-+ * line, we need to deal with this case.
-+ */
-+ if (axp20x->irq > 0) {
-+ axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
-+ axp20x->cells = axp15060_cells;
-+ } else {
-+ axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
-+ axp20x->cells = axp_regulator_only_cells;
-+ }
-+ axp20x->regmap_cfg = &axp15060_regmap_config;
-+ axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip;
-+ break;
- default:
- dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
- return -EINVAL;
---- a/include/linux/mfd/axp20x.h
-+++ b/include/linux/mfd/axp20x.h
-@@ -21,6 +21,7 @@ enum axp20x_variants {
- AXP806_ID,
- AXP809_ID,
- AXP813_ID,
-+ AXP15060_ID,
- NR_AXP20X_VARIANTS,
- };
-
-@@ -131,6 +132,39 @@ enum axp20x_variants {
- /* Other DCDC regulator control registers are the same as AXP803 */
- #define AXP813_DCDC7_V_OUT 0x26
-
-+#define AXP15060_STARTUP_SRC 0x00
-+#define AXP15060_PWR_OUT_CTRL1 0x10
-+#define AXP15060_PWR_OUT_CTRL2 0x11
-+#define AXP15060_PWR_OUT_CTRL3 0x12
-+#define AXP15060_DCDC1_V_CTRL 0x13
-+#define AXP15060_DCDC2_V_CTRL 0x14
-+#define AXP15060_DCDC3_V_CTRL 0x15
-+#define AXP15060_DCDC4_V_CTRL 0x16
-+#define AXP15060_DCDC5_V_CTRL 0x17
-+#define AXP15060_DCDC6_V_CTRL 0x18
-+#define AXP15060_ALDO1_V_CTRL 0x19
-+#define AXP15060_DCDC_MODE_CTRL1 0x1a
-+#define AXP15060_DCDC_MODE_CTRL2 0x1b
-+#define AXP15060_OUTPUT_MONITOR_DISCHARGE 0x1e
-+#define AXP15060_IRQ_PWROK_VOFF 0x1f
-+#define AXP15060_ALDO2_V_CTRL 0x20
-+#define AXP15060_ALDO3_V_CTRL 0x21
-+#define AXP15060_ALDO4_V_CTRL 0x22
-+#define AXP15060_ALDO5_V_CTRL 0x23
-+#define AXP15060_BLDO1_V_CTRL 0x24
-+#define AXP15060_BLDO2_V_CTRL 0x25
-+#define AXP15060_BLDO3_V_CTRL 0x26
-+#define AXP15060_BLDO4_V_CTRL 0x27
-+#define AXP15060_BLDO5_V_CTRL 0x28
-+#define AXP15060_CLDO1_V_CTRL 0x29
-+#define AXP15060_CLDO2_V_CTRL 0x2a
-+#define AXP15060_CLDO3_V_CTRL 0x2b
-+#define AXP15060_CLDO4_V_CTRL 0x2d
-+#define AXP15060_CPUSLDO_V_CTRL 0x2e
-+#define AXP15060_PWR_WAKEUP_CTRL 0x31
-+#define AXP15060_PWR_DISABLE_DOWN_SEQ 0x32
-+#define AXP15060_PEK_KEY 0x36
-+
- /* Interrupt */
- #define AXP152_IRQ1_EN 0x40
- #define AXP152_IRQ2_EN 0x41
-@@ -152,6 +186,11 @@ enum axp20x_variants {
- #define AXP20X_IRQ5_STATE 0x4c
- #define AXP20X_IRQ6_STATE 0x4d
-
-+#define AXP15060_IRQ1_EN 0x40
-+#define AXP15060_IRQ2_EN 0x41
-+#define AXP15060_IRQ1_STATE 0x48
-+#define AXP15060_IRQ2_STATE 0x49
-+
- /* ADC */
- #define AXP20X_ACIN_V_ADC_H 0x56
- #define AXP20X_ACIN_V_ADC_L 0x57
-@@ -222,6 +261,8 @@ enum axp20x_variants {
- #define AXP22X_GPIO_STATE 0x94
- #define AXP22X_GPIO_PULL_DOWN 0x95
-
-+#define AXP15060_CLDO4_GPIO2_MODESET 0x2c
-+
- /* Battery */
- #define AXP20X_CHRG_CC_31_24 0xb0
- #define AXP20X_CHRG_CC_23_16 0xb1
-@@ -419,6 +460,33 @@ enum {
- AXP813_REG_ID_MAX,
- };
-
-+enum {
-+ AXP15060_DCDC1 = 0,
-+ AXP15060_DCDC2,
-+ AXP15060_DCDC3,
-+ AXP15060_DCDC4,
-+ AXP15060_DCDC5,
-+ AXP15060_DCDC6,
-+ AXP15060_ALDO1,
-+ AXP15060_ALDO2,
-+ AXP15060_ALDO3,
-+ AXP15060_ALDO4,
-+ AXP15060_ALDO5,
-+ AXP15060_BLDO1,
-+ AXP15060_BLDO2,
-+ AXP15060_BLDO3,
-+ AXP15060_BLDO4,
-+ AXP15060_BLDO5,
-+ AXP15060_CLDO1,
-+ AXP15060_CLDO2,
-+ AXP15060_CLDO3,
-+ AXP15060_CLDO4,
-+ AXP15060_CPUSLDO,
-+ AXP15060_SW,
-+ AXP15060_RTC_LDO,
-+ AXP15060_REG_ID_MAX,
-+};
-+
- /* IRQs */
- enum {
- AXP152_IRQ_LDO0IN_CONNECT = 1,
-@@ -637,6 +705,23 @@ enum axp809_irqs {
- AXP809_IRQ_GPIO0_INPUT,
- };
-
-+enum axp15060_irqs {
-+ AXP15060_IRQ_DIE_TEMP_HIGH_LV1 = 1,
-+ AXP15060_IRQ_DIE_TEMP_HIGH_LV2,
-+ AXP15060_IRQ_DCDC1_V_LOW,
-+ AXP15060_IRQ_DCDC2_V_LOW,
-+ AXP15060_IRQ_DCDC3_V_LOW,
-+ AXP15060_IRQ_DCDC4_V_LOW,
-+ AXP15060_IRQ_DCDC5_V_LOW,
-+ AXP15060_IRQ_DCDC6_V_LOW,
-+ AXP15060_IRQ_PEK_LONG,
-+ AXP15060_IRQ_PEK_SHORT,
-+ AXP15060_IRQ_GPIO1_INPUT,
-+ AXP15060_IRQ_PEK_FAL_EDGE,
-+ AXP15060_IRQ_PEK_RIS_EDGE,
-+ AXP15060_IRQ_GPIO2_INPUT,
-+};
-+
- struct axp20x_dev {
- struct device *dev;
- int irq;
diff --git a/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch b/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch
deleted file mode 100644
index c9470eacec..0000000000
--- a/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch
+++ /dev/null
@@ -1,256 +0,0 @@
-From 75c8cb2f4cb218aaf4ea68cab08d6dbc96eeae15 Mon Sep 17 00:00:00 2001
-From: Martin Botka <martin.botka@somainline.org>
-Date: Wed, 24 May 2023 01:00:10 +0100
-Subject: [PATCH] mfd: axp20x: Add support for AXP313a PMIC
-
-The AXP313a is a PMIC chip produced by X-Powers, it can be connected via
-an I2C bus.
-The name AXP1530 seems to appear as well, and this is what is used in
-the BSP driver. From all we know it's the same chip, just a different
-name. However we have only seen AXP313a chips in the wild, so go with
-this name.
-
-Compared to the other AXP PMICs it's a rather simple affair: just three
-DCDC converters, three LDOs, and no battery charging support.
-
-Describe the regmap and the MFD bits, along with the registers exposed
-via I2C. Aside from the various regulators, also describe the power key
-interrupts, and adjust the shutdown handler routine to use a different
-register than the other PMICs.
-Eventually advertise the device using the new compatible string.
-
-Signed-off-by: Martin Botka <martin.botka@somainline.org>
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Chen-Yu Tsai <wens@csie.org>
-Link: https://lore.kernel.org/r/20230524000012.15028-2-andre.przywara@arm.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/mfd/axp20x-i2c.c | 2 +
- drivers/mfd/axp20x.c | 78 +++++++++++++++++++++++++++++++++++++-
- include/linux/mfd/axp20x.h | 32 ++++++++++++++++
- 3 files changed, 111 insertions(+), 1 deletion(-)
-
---- a/drivers/mfd/axp20x-i2c.c
-+++ b/drivers/mfd/axp20x-i2c.c
-@@ -64,6 +64,7 @@ static const struct of_device_id axp20x_
- { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
- { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
- { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
-+ { .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID },
- { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
- { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
- { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
-@@ -78,6 +79,7 @@ static const struct i2c_device_id axp20x
- { "axp209", 0 },
- { "axp221", 0 },
- { "axp223", 0 },
-+ { "axp313a", 0 },
- { "axp803", 0 },
- { "axp806", 0 },
- { "axp15060", 0 },
---- a/drivers/mfd/axp20x.c
-+++ b/drivers/mfd/axp20x.c
-@@ -39,6 +39,7 @@ static const char * const axp20x_model_n
- "AXP221",
- "AXP223",
- "AXP288",
-+ "AXP313a",
- "AXP803",
- "AXP806",
- "AXP809",
-@@ -156,6 +157,25 @@ static const struct regmap_range axp806_
- regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
- };
-
-+static const struct regmap_range axp313a_writeable_ranges[] = {
-+ regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
-+};
-+
-+static const struct regmap_range axp313a_volatile_ranges[] = {
-+ regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
-+ regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
-+};
-+
-+static const struct regmap_access_table axp313a_writeable_table = {
-+ .yes_ranges = axp313a_writeable_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
-+};
-+
-+static const struct regmap_access_table axp313a_volatile_table = {
-+ .yes_ranges = axp313a_volatile_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
-+};
-+
- static const struct regmap_range axp806_volatile_ranges[] = {
- regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
- };
-@@ -248,6 +268,11 @@ static const struct resource axp288_fuel
- DEFINE_RES_IRQ(AXP288_IRQ_WL1),
- };
-
-+static const struct resource axp313a_pek_resources[] = {
-+ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
-+ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
-+};
-+
- static const struct resource axp803_pek_resources[] = {
- DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
-@@ -304,6 +329,15 @@ static const struct regmap_config axp288
- .cache_type = REGCACHE_RBTREE,
- };
-
-+static const struct regmap_config axp313a_regmap_config = {
-+ .reg_bits = 8,
-+ .val_bits = 8,
-+ .wr_table = &axp313a_writeable_table,
-+ .volatile_table = &axp313a_volatile_table,
-+ .max_register = AXP313A_IRQ_STATE,
-+ .cache_type = REGCACHE_RBTREE,
-+};
-+
- static const struct regmap_config axp806_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-@@ -456,6 +490,16 @@ static const struct regmap_irq axp288_re
- INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
- };
-
-+static const struct regmap_irq axp313a_regmap_irqs[] = {
-+ INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE, 0, 7),
-+ INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE, 0, 6),
-+ INIT_REGMAP_IRQ(AXP313A, PEK_SHORT, 0, 5),
-+ INIT_REGMAP_IRQ(AXP313A, PEK_LONG, 0, 4),
-+ INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW, 0, 3),
-+ INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW, 0, 2),
-+ INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH, 0, 0),
-+};
-+
- static const struct regmap_irq axp803_regmap_irqs[] = {
- INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7),
- INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6),
-@@ -610,6 +654,17 @@ static const struct regmap_irq_chip axp2
-
- };
-
-+static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
-+ .name = "axp313a_irq_chip",
-+ .status_base = AXP313A_IRQ_STATE,
-+ .ack_base = AXP313A_IRQ_STATE,
-+ .unmask_base = AXP313A_IRQ_EN,
-+ .init_ack_masked = true,
-+ .irqs = axp313a_regmap_irqs,
-+ .num_irqs = ARRAY_SIZE(axp313a_regmap_irqs),
-+ .num_regs = 1,
-+};
-+
- static const struct regmap_irq_chip axp803_regmap_irq_chip = {
- .name = "axp803",
- .status_base = AXP20X_IRQ1_STATE,
-@@ -752,6 +807,11 @@ static const struct mfd_cell axp152_cell
- },
- };
-
-+static struct mfd_cell axp313a_cells[] = {
-+ MFD_CELL_NAME("axp20x-regulator"),
-+ MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
-+};
-+
- static const struct resource axp288_adc_resources[] = {
- DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
- };
-@@ -921,8 +981,18 @@ static const struct mfd_cell axp_regulat
- static int axp20x_power_off(struct sys_off_data *data)
- {
- struct axp20x_dev *axp20x = data->cb_data;
-+ unsigned int shutdown_reg;
-
-- regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
-+ switch (axp20x->variant) {
-+ case AXP313A_ID:
-+ shutdown_reg = AXP313A_SHUTDOWN_CTRL;
-+ break;
-+ default:
-+ shutdown_reg = AXP20X_OFF_CTRL;
-+ break;
-+ }
-+
-+ regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
-
- /* Give capacitors etc. time to drain to avoid kernel panic msg. */
- mdelay(500);
-@@ -985,6 +1055,12 @@ int axp20x_match_device(struct axp20x_de
- axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
- axp20x->irq_flags = IRQF_TRIGGER_LOW;
- break;
-+ case AXP313A_ID:
-+ axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
-+ axp20x->cells = axp313a_cells;
-+ axp20x->regmap_cfg = &axp313a_regmap_config;
-+ axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
-+ break;
- case AXP803_ID:
- axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
- axp20x->cells = axp803_cells;
---- a/include/linux/mfd/axp20x.h
-+++ b/include/linux/mfd/axp20x.h
-@@ -17,6 +17,7 @@ enum axp20x_variants {
- AXP221_ID,
- AXP223_ID,
- AXP288_ID,
-+ AXP313A_ID,
- AXP803_ID,
- AXP806_ID,
- AXP809_ID,
-@@ -92,6 +93,17 @@ enum axp20x_variants {
- #define AXP22X_ALDO3_V_OUT 0x2a
- #define AXP22X_CHRG_CTRL3 0x35
-
-+#define AXP313A_ON_INDICATE 0x00
-+#define AXP313A_OUTPUT_CONTROL 0x10
-+#define AXP313A_DCDC1_CONRTOL 0x13
-+#define AXP313A_DCDC2_CONRTOL 0x14
-+#define AXP313A_DCDC3_CONRTOL 0x15
-+#define AXP313A_ALDO1_CONRTOL 0x16
-+#define AXP313A_DLDO1_CONRTOL 0x17
-+#define AXP313A_SHUTDOWN_CTRL 0x1a
-+#define AXP313A_IRQ_EN 0x20
-+#define AXP313A_IRQ_STATE 0x21
-+
- #define AXP806_STARTUP_SRC 0x00
- #define AXP806_CHIP_ID 0x03
- #define AXP806_PWR_OUT_CTRL1 0x10
-@@ -364,6 +376,16 @@ enum {
- };
-
- enum {
-+ AXP313A_DCDC1 = 0,
-+ AXP313A_DCDC2,
-+ AXP313A_DCDC3,
-+ AXP313A_ALDO1,
-+ AXP313A_DLDO1,
-+ AXP313A_RTC_LDO,
-+ AXP313A_REG_ID_MAX,
-+};
-+
-+enum {
- AXP806_DCDCA = 0,
- AXP806_DCDCB,
- AXP806_DCDCC,
-@@ -616,6 +638,16 @@ enum axp288_irqs {
- AXP288_IRQ_BC_USB_CHNG,
- };
-
-+enum axp313a_irqs {
-+ AXP313A_IRQ_DIE_TEMP_HIGH,
-+ AXP313A_IRQ_DCDC2_V_LOW = 2,
-+ AXP313A_IRQ_DCDC3_V_LOW,
-+ AXP313A_IRQ_PEK_LONG,
-+ AXP313A_IRQ_PEK_SHORT,
-+ AXP313A_IRQ_PEK_FAL_EDGE,
-+ AXP313A_IRQ_PEK_RIS_EDGE,
-+};
-+
- enum axp803_irqs {
- AXP803_IRQ_ACIN_OVER_V = 1,
- AXP803_IRQ_ACIN_PLUGIN,
diff --git a/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch b/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch
deleted file mode 100644
index 91f1b39824..0000000000
--- a/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 60fd7eb89670d2636ac3156881acbd103c6eba6a Mon Sep 17 00:00:00 2001
-From: Martin Botka <martin.botka@somainline.org>
-Date: Wed, 24 May 2023 01:00:11 +0100
-Subject: [PATCH] regulator: axp20x: Add support for AXP313a variant
-
-The AXP313a is your typical I2C controlled PMIC, although in a lighter
-fashion compared to the other X-Powers PMICs: it has only three DCDC
-rails, three LDOs, and no battery charging support.
-
-The AXP313a datasheet does not describe a register to change the DCDC
-switching frequency, and talks of it being fixed at 3 MHz. Check that
-the property allowing to change that frequency is absent from the DT,
-and bail out otherwise.
-
-The third LDO, RTCLDO, is fixed, and cannot even be turned on or off,
-programmatically. On top of that, its voltage is customisable (either
-1.8V or 3.3V), which we cannot describe easily using the existing
-regulator wrapper functions. This should be fixed properly, using
-regulator-{min,max}-microvolt in the DT, but this requires more changes
-to the code. As some other PMICs (AXP2xx, AXP803) seem to paper over the
-same problem as well, we follow suit here and pretend it's a fixed 1.8V
-regulator. A proper fix can follow later. The BSP code seems to ignore
-this regulator altogether.
-
-Describe the AXP313A's voltage settings and switch registers, how the
-voltages are encoded, and connect this to the MFD device via its
-regulator ID.
-
-Signed-off-by: Martin Botka <martin.botka@somainline.org>
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Chen-Yu Tsai <wens@csie.org>
-Reviewed-by: Mark Brown <broonie@kernel.org>
-Tested-by: Shengyu Qu <wiagn233@outlook.com>
-Link: https://lore.kernel.org/r/20230524000012.15028-3-andre.przywara@arm.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/regulator/axp20x-regulator.c | 60 ++++++++++++++++++++++++++++
- 1 file changed, 60 insertions(+)
-
---- a/drivers/regulator/axp20x-regulator.c
-+++ b/drivers/regulator/axp20x-regulator.c
-@@ -134,6 +134,11 @@
- #define AXP22X_PWR_OUT_DLDO4_MASK BIT_MASK(6)
- #define AXP22X_PWR_OUT_ALDO3_MASK BIT_MASK(7)
-
-+#define AXP313A_DCDC1_NUM_VOLTAGES 107
-+#define AXP313A_DCDC23_NUM_VOLTAGES 88
-+#define AXP313A_DCDC_V_OUT_MASK GENMASK(6, 0)
-+#define AXP313A_LDO_V_OUT_MASK GENMASK(4, 0)
-+
- #define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0)
- #define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1)
- #define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2)
-@@ -638,6 +643,48 @@ static const struct regulator_desc axp22
- .ops = &axp20x_ops_sw,
- };
-
-+static const struct linear_range axp313a_dcdc1_ranges[] = {
-+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
-+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
-+ REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
-+};
-+
-+static const struct linear_range axp313a_dcdc2_ranges[] = {
-+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
-+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
-+};
-+
-+/*
-+ * This is deviating from the datasheet. The values here are taken from the
-+ * BSP driver and have been confirmed by measurements.
-+ */
-+static const struct linear_range axp313a_dcdc3_ranges[] = {
-+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
-+ REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
-+};
-+
-+static const struct regulator_desc axp313a_regulators[] = {
-+ AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
-+ axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
-+ AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
-+ AXP313A_OUTPUT_CONTROL, BIT(0)),
-+ AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
-+ axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
-+ AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
-+ AXP313A_OUTPUT_CONTROL, BIT(1)),
-+ AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
-+ axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
-+ AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
-+ AXP313A_OUTPUT_CONTROL, BIT(2)),
-+ AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
-+ AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
-+ AXP313A_OUTPUT_CONTROL, BIT(3)),
-+ AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
-+ AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
-+ AXP313A_OUTPUT_CONTROL, BIT(4)),
-+ AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
-+};
-+
- /* DCDC ranges shared with AXP813 */
- static const struct linear_range axp803_dcdc234_ranges[] = {
- REGULATOR_LINEAR_RANGE(500000,
-@@ -1040,6 +1087,15 @@ static int axp20x_set_dcdc_freq(struct p
- def = 3000;
- step = 150;
- break;
-+ case AXP313A_ID:
-+ /* The DCDC PWM frequency seems to be fixed to 3 MHz. */
-+ if (dcdcfreq != 0) {
-+ dev_err(&pdev->dev,
-+ "DCDC frequency on AXP313a is fixed to 3 MHz.\n");
-+ return -EINVAL;
-+ }
-+
-+ return 0;
- default:
- dev_err(&pdev->dev,
- "Setting DCDC frequency for unsupported AXP variant\n");
-@@ -1232,6 +1288,10 @@ static int axp20x_regulator_probe(struct
- drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
- "x-powers,drive-vbus-en");
- break;
-+ case AXP313A_ID:
-+ regulators = axp313a_regulators;
-+ nregulators = AXP313A_REG_ID_MAX;
-+ break;
- case AXP803_ID:
- regulators = axp803_regulators;
- nregulators = AXP803_REG_ID_MAX;
diff --git a/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch b/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch
deleted file mode 100644
index 6af09204af..0000000000
--- a/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch
+++ /dev/null
@@ -1,367 +0,0 @@
-From 9e72869d0fe12aba8cd489e485d93912b3f5c248 Mon Sep 17 00:00:00 2001
-From: Shengyu Qu <wiagn233@outlook.com>
-Date: Wed, 24 May 2023 01:00:12 +0100
-Subject: [PATCH] regulator: axp20x: Add AXP15060 support
-
-The AXP15060 is a typical I2C-controlled PMIC, seen on multiple boards
-with different default register value. Current driver is tested on
-Starfive Visionfive 2.
-
-The RTCLDO is fixed, and cannot even be turned on or off. On top of
-that, its voltage is customisable (either 1.8V or 3.3V). We pretend it's
-a fixed 1.8V regulator since other AXP driver also do like this. Also,
-BSP code ignores this regulator and it's not used according to VF2
-schematic.
-
-Describe the AXP15060's voltage settings and switch registers, how the
-voltages are encoded, and connect this to the MFD device via its
-regulator ID.
-
-Signed-off-by: Shengyu Qu <wiagn233@outlook.com>
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Mark Brown <broonie@kernel.org>
-Tested-by: Shengyu Qu <wiagn233@outlook.com>
-Link: https://lore.kernel.org/r/20230524000012.15028-4-andre.przywara@arm.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/regulator/axp20x-regulator.c | 232 +++++++++++++++++++++++++--
- 1 file changed, 223 insertions(+), 9 deletions(-)
-
---- a/drivers/regulator/axp20x-regulator.c
-+++ b/drivers/regulator/axp20x-regulator.c
-@@ -275,6 +275,74 @@
-
- #define AXP813_PWR_OUT_DCDC7_MASK BIT_MASK(6)
-
-+#define AXP15060_DCDC1_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_DCDC2_V_CTRL_MASK GENMASK(6, 0)
-+#define AXP15060_DCDC3_V_CTRL_MASK GENMASK(6, 0)
-+#define AXP15060_DCDC4_V_CTRL_MASK GENMASK(6, 0)
-+#define AXP15060_DCDC5_V_CTRL_MASK GENMASK(6, 0)
-+#define AXP15060_DCDC6_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_ALDO1_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_ALDO2_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_ALDO3_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_ALDO4_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_ALDO5_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_BLDO1_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_BLDO2_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_BLDO3_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_BLDO4_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_BLDO5_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_CLDO1_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_CLDO2_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_CLDO3_V_CTRL_MASK GENMASK(4, 0)
-+#define AXP15060_CLDO4_V_CTRL_MASK GENMASK(5, 0)
-+#define AXP15060_CPUSLDO_V_CTRL_MASK GENMASK(3, 0)
-+
-+#define AXP15060_PWR_OUT_DCDC1_MASK BIT_MASK(0)
-+#define AXP15060_PWR_OUT_DCDC2_MASK BIT_MASK(1)
-+#define AXP15060_PWR_OUT_DCDC3_MASK BIT_MASK(2)
-+#define AXP15060_PWR_OUT_DCDC4_MASK BIT_MASK(3)
-+#define AXP15060_PWR_OUT_DCDC5_MASK BIT_MASK(4)
-+#define AXP15060_PWR_OUT_DCDC6_MASK BIT_MASK(5)
-+#define AXP15060_PWR_OUT_ALDO1_MASK BIT_MASK(0)
-+#define AXP15060_PWR_OUT_ALDO2_MASK BIT_MASK(1)
-+#define AXP15060_PWR_OUT_ALDO3_MASK BIT_MASK(2)
-+#define AXP15060_PWR_OUT_ALDO4_MASK BIT_MASK(3)
-+#define AXP15060_PWR_OUT_ALDO5_MASK BIT_MASK(4)
-+#define AXP15060_PWR_OUT_BLDO1_MASK BIT_MASK(5)
-+#define AXP15060_PWR_OUT_BLDO2_MASK BIT_MASK(6)
-+#define AXP15060_PWR_OUT_BLDO3_MASK BIT_MASK(7)
-+#define AXP15060_PWR_OUT_BLDO4_MASK BIT_MASK(0)
-+#define AXP15060_PWR_OUT_BLDO5_MASK BIT_MASK(1)
-+#define AXP15060_PWR_OUT_CLDO1_MASK BIT_MASK(2)
-+#define AXP15060_PWR_OUT_CLDO2_MASK BIT_MASK(3)
-+#define AXP15060_PWR_OUT_CLDO3_MASK BIT_MASK(4)
-+#define AXP15060_PWR_OUT_CLDO4_MASK BIT_MASK(5)
-+#define AXP15060_PWR_OUT_CPUSLDO_MASK BIT_MASK(6)
-+#define AXP15060_PWR_OUT_SW_MASK BIT_MASK(7)
-+
-+#define AXP15060_DCDC23_POLYPHASE_DUAL_MASK BIT_MASK(6)
-+#define AXP15060_DCDC46_POLYPHASE_DUAL_MASK BIT_MASK(7)
-+
-+#define AXP15060_DCDC234_500mV_START 0x00
-+#define AXP15060_DCDC234_500mV_STEPS 70
-+#define AXP15060_DCDC234_500mV_END \
-+ (AXP15060_DCDC234_500mV_START + AXP15060_DCDC234_500mV_STEPS)
-+#define AXP15060_DCDC234_1220mV_START 0x47
-+#define AXP15060_DCDC234_1220mV_STEPS 16
-+#define AXP15060_DCDC234_1220mV_END \
-+ (AXP15060_DCDC234_1220mV_START + AXP15060_DCDC234_1220mV_STEPS)
-+#define AXP15060_DCDC234_NUM_VOLTAGES 88
-+
-+#define AXP15060_DCDC5_800mV_START 0x00
-+#define AXP15060_DCDC5_800mV_STEPS 32
-+#define AXP15060_DCDC5_800mV_END \
-+ (AXP15060_DCDC5_800mV_START + AXP15060_DCDC5_800mV_STEPS)
-+#define AXP15060_DCDC5_1140mV_START 0x21
-+#define AXP15060_DCDC5_1140mV_STEPS 35
-+#define AXP15060_DCDC5_1140mV_END \
-+ (AXP15060_DCDC5_1140mV_START + AXP15060_DCDC5_1140mV_STEPS)
-+#define AXP15060_DCDC5_NUM_VOLTAGES 69
-+
- #define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
- _vmask, _ereg, _emask, _enable_val, _disable_val) \
- [_family##_##_id] = { \
-@@ -1048,6 +1116,104 @@ static const struct regulator_desc axp81
- AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
- };
-
-+static const struct linear_range axp15060_dcdc234_ranges[] = {
-+ REGULATOR_LINEAR_RANGE(500000,
-+ AXP15060_DCDC234_500mV_START,
-+ AXP15060_DCDC234_500mV_END,
-+ 10000),
-+ REGULATOR_LINEAR_RANGE(1220000,
-+ AXP15060_DCDC234_1220mV_START,
-+ AXP15060_DCDC234_1220mV_END,
-+ 20000),
-+};
-+
-+static const struct linear_range axp15060_dcdc5_ranges[] = {
-+ REGULATOR_LINEAR_RANGE(800000,
-+ AXP15060_DCDC5_800mV_START,
-+ AXP15060_DCDC5_800mV_END,
-+ 10000),
-+ REGULATOR_LINEAR_RANGE(1140000,
-+ AXP15060_DCDC5_1140mV_START,
-+ AXP15060_DCDC5_1140mV_END,
-+ 20000),
-+};
-+
-+static const struct regulator_desc axp15060_regulators[] = {
-+ AXP_DESC(AXP15060, DCDC1, "dcdc1", "vin1", 1500, 3400, 100,
-+ AXP15060_DCDC1_V_CTRL, AXP15060_DCDC1_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC1_MASK),
-+ AXP_DESC_RANGES(AXP15060, DCDC2, "dcdc2", "vin2",
-+ axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
-+ AXP15060_DCDC2_V_CTRL, AXP15060_DCDC2_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC2_MASK),
-+ AXP_DESC_RANGES(AXP15060, DCDC3, "dcdc3", "vin3",
-+ axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
-+ AXP15060_DCDC3_V_CTRL, AXP15060_DCDC3_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC3_MASK),
-+ AXP_DESC_RANGES(AXP15060, DCDC4, "dcdc4", "vin4",
-+ axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
-+ AXP15060_DCDC4_V_CTRL, AXP15060_DCDC4_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC4_MASK),
-+ AXP_DESC_RANGES(AXP15060, DCDC5, "dcdc5", "vin5",
-+ axp15060_dcdc5_ranges, AXP15060_DCDC5_NUM_VOLTAGES,
-+ AXP15060_DCDC5_V_CTRL, AXP15060_DCDC5_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC5_MASK),
-+ AXP_DESC(AXP15060, DCDC6, "dcdc6", "vin6", 500, 3400, 100,
-+ AXP15060_DCDC6_V_CTRL, AXP15060_DCDC6_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC6_MASK),
-+ AXP_DESC(AXP15060, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
-+ AXP15060_ALDO1_V_CTRL, AXP15060_ALDO1_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO1_MASK),
-+ AXP_DESC(AXP15060, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
-+ AXP15060_ALDO2_V_CTRL, AXP15060_ALDO2_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO2_MASK),
-+ AXP_DESC(AXP15060, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
-+ AXP15060_ALDO3_V_CTRL, AXP15060_ALDO3_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO3_MASK),
-+ AXP_DESC(AXP15060, ALDO4, "aldo4", "aldoin", 700, 3300, 100,
-+ AXP15060_ALDO4_V_CTRL, AXP15060_ALDO4_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO4_MASK),
-+ AXP_DESC(AXP15060, ALDO5, "aldo5", "aldoin", 700, 3300, 100,
-+ AXP15060_ALDO5_V_CTRL, AXP15060_ALDO5_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO5_MASK),
-+ AXP_DESC(AXP15060, BLDO1, "bldo1", "bldoin", 700, 3300, 100,
-+ AXP15060_BLDO1_V_CTRL, AXP15060_BLDO1_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO1_MASK),
-+ AXP_DESC(AXP15060, BLDO2, "bldo2", "bldoin", 700, 3300, 100,
-+ AXP15060_BLDO2_V_CTRL, AXP15060_BLDO2_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO2_MASK),
-+ AXP_DESC(AXP15060, BLDO3, "bldo3", "bldoin", 700, 3300, 100,
-+ AXP15060_BLDO3_V_CTRL, AXP15060_BLDO3_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO3_MASK),
-+ AXP_DESC(AXP15060, BLDO4, "bldo4", "bldoin", 700, 3300, 100,
-+ AXP15060_BLDO4_V_CTRL, AXP15060_BLDO4_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO4_MASK),
-+ AXP_DESC(AXP15060, BLDO5, "bldo5", "bldoin", 700, 3300, 100,
-+ AXP15060_BLDO5_V_CTRL, AXP15060_BLDO5_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO5_MASK),
-+ AXP_DESC(AXP15060, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
-+ AXP15060_CLDO1_V_CTRL, AXP15060_CLDO1_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO1_MASK),
-+ AXP_DESC(AXP15060, CLDO2, "cldo2", "cldoin", 700, 3300, 100,
-+ AXP15060_CLDO2_V_CTRL, AXP15060_CLDO2_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO2_MASK),
-+ AXP_DESC(AXP15060, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
-+ AXP15060_CLDO3_V_CTRL, AXP15060_CLDO3_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO3_MASK),
-+ AXP_DESC(AXP15060, CLDO4, "cldo4", "cldoin", 700, 4200, 100,
-+ AXP15060_CLDO4_V_CTRL, AXP15060_CLDO4_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO4_MASK),
-+ /* Supply comes from DCDC5 */
-+ AXP_DESC(AXP15060, CPUSLDO, "cpusldo", NULL, 700, 1400, 50,
-+ AXP15060_CPUSLDO_V_CTRL, AXP15060_CPUSLDO_V_CTRL_MASK,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CPUSLDO_MASK),
-+ /* Supply comes from DCDC1 */
-+ AXP_DESC_SW(AXP15060, SW, "sw", NULL,
-+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_SW_MASK),
-+ /* Supply comes from ALDO1 */
-+ AXP_DESC_FIXED(AXP15060, RTC_LDO, "rtc-ldo", NULL, 1800),
-+};
-+
- static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
- {
- struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
-@@ -1088,10 +1254,11 @@ static int axp20x_set_dcdc_freq(struct p
- step = 150;
- break;
- case AXP313A_ID:
-+ case AXP15060_ID:
- /* The DCDC PWM frequency seems to be fixed to 3 MHz. */
- if (dcdcfreq != 0) {
- dev_err(&pdev->dev,
-- "DCDC frequency on AXP313a is fixed to 3 MHz.\n");
-+ "DCDC frequency on this PMIC is fixed to 3 MHz.\n");
- return -EINVAL;
- }
-
-@@ -1201,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(stru
- workmode <<= id - AXP813_DCDC1;
- break;
-
-+ case AXP15060_ID:
-+ reg = AXP15060_DCDC_MODE_CTRL2;
-+ if (id < AXP15060_DCDC1 || id > AXP15060_DCDC6)
-+ return -EINVAL;
-+
-+ mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP15060_DCDC1);
-+ workmode <<= id - AXP15060_DCDC1;
-+ break;
-+
- default:
- /* should not happen */
- WARN_ON(1);
-@@ -1220,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(st
-
- /*
- * Currently in our supported AXP variants, only AXP803, AXP806,
-- * and AXP813 have polyphase regulators.
-+ * AXP813 and AXP15060 have polyphase regulators.
- */
- switch (axp20x->variant) {
- case AXP803_ID:
-@@ -1252,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(st
- }
- break;
-
-+ case AXP15060_ID:
-+ regmap_read(axp20x->regmap, AXP15060_DCDC_MODE_CTRL1, &reg);
-+
-+ switch (id) {
-+ case AXP15060_DCDC3:
-+ return !!(reg & AXP15060_DCDC23_POLYPHASE_DUAL_MASK);
-+ case AXP15060_DCDC6:
-+ return !!(reg & AXP15060_DCDC46_POLYPHASE_DUAL_MASK);
-+ }
-+ break;
-+
- default:
- return false;
- }
-@@ -1273,6 +1460,7 @@ static int axp20x_regulator_probe(struct
- u32 workmode;
- const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
- const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
-+ const char *aldo1_name = axp15060_regulators[AXP15060_ALDO1].name;
- bool drivevbus = false;
-
- switch (axp20x->variant) {
-@@ -1312,6 +1500,10 @@ static int axp20x_regulator_probe(struct
- drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
- "x-powers,drive-vbus-en");
- break;
-+ case AXP15060_ID:
-+ regulators = axp15060_regulators;
-+ nregulators = AXP15060_REG_ID_MAX;
-+ break;
- default:
- dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
- axp20x->variant);
-@@ -1338,8 +1530,9 @@ static int axp20x_regulator_probe(struct
- continue;
-
- /*
-- * Regulators DC1SW and DC5LDO are connected internally,
-- * so we have to handle their supply names separately.
-+ * Regulators DC1SW, DC5LDO and RTCLDO on AXP15060 are
-+ * connected internally, so we have to handle their supply
-+ * names separately.
- *
- * We always register the regulators in proper sequence,
- * so the supply names are correctly read. See the last
-@@ -1348,7 +1541,8 @@ static int axp20x_regulator_probe(struct
- */
- if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
- (regulators == axp803_regulators && i == AXP803_DC1SW) ||
-- (regulators == axp809_regulators && i == AXP809_DC1SW)) {
-+ (regulators == axp809_regulators && i == AXP809_DC1SW) ||
-+ (regulators == axp15060_regulators && i == AXP15060_SW)) {
- new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
- GFP_KERNEL);
- if (!new_desc)
-@@ -1360,7 +1554,8 @@ static int axp20x_regulator_probe(struct
- }
-
- if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
-- (regulators == axp809_regulators && i == AXP809_DC5LDO)) {
-+ (regulators == axp809_regulators && i == AXP809_DC5LDO) ||
-+ (regulators == axp15060_regulators && i == AXP15060_CPUSLDO)) {
- new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
- GFP_KERNEL);
- if (!new_desc)
-@@ -1371,6 +1566,18 @@ static int axp20x_regulator_probe(struct
- desc = new_desc;
- }
-
-+
-+ if (regulators == axp15060_regulators && i == AXP15060_RTC_LDO) {
-+ new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
-+ GFP_KERNEL);
-+ if (!new_desc)
-+ return -ENOMEM;
-+
-+ *new_desc = regulators[i];
-+ new_desc->supply_name = aldo1_name;
-+ desc = new_desc;
-+ }
-+
- rdev = devm_regulator_register(&pdev->dev, desc, &config);
- if (IS_ERR(rdev)) {
- dev_err(&pdev->dev, "Failed to register %s\n",
-@@ -1389,19 +1596,26 @@ static int axp20x_regulator_probe(struct
- }
-
- /*
-- * Save AXP22X DCDC1 / DCDC5 regulator names for later.
-+ * Save AXP22X DCDC1 / DCDC5 / AXP15060 ALDO1 regulator names for later.
- */
- if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) ||
-- (regulators == axp809_regulators && i == AXP809_DCDC1))
-+ (regulators == axp809_regulators && i == AXP809_DCDC1) ||
-+ (regulators == axp15060_regulators && i == AXP15060_DCDC1))
- of_property_read_string(rdev->dev.of_node,
- "regulator-name",
- &dcdc1_name);
-
- if ((regulators == axp22x_regulators && i == AXP22X_DCDC5) ||
-- (regulators == axp809_regulators && i == AXP809_DCDC5))
-+ (regulators == axp809_regulators && i == AXP809_DCDC5) ||
-+ (regulators == axp15060_regulators && i == AXP15060_DCDC5))
- of_property_read_string(rdev->dev.of_node,
- "regulator-name",
- &dcdc5_name);
-+
-+ if (regulators == axp15060_regulators && i == AXP15060_ALDO1)
-+ of_property_read_string(rdev->dev.of_node,
-+ "regulator-name",
-+ &aldo1_name);
- }
-
- if (drivevbus) {
diff --git a/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch b/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch
deleted file mode 100644
index d75b4e7453..0000000000
--- a/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch
+++ /dev/null
@@ -1,383 +0,0 @@
-From 63eeabbc9dbddd7381409feccd9082e5ffabfe59 Mon Sep 17 00:00:00 2001
-From: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
-Date: Thu, 11 May 2023 10:26:08 +0100
-Subject: [PATCH] mfd: axp20x: Add support for AXP192
-
-The AXP192 PMIC is similar to the AXP202/AXP209, but with different
-regulators, additional GPIOs, and a different IRQ register layout.
-
-Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
-Link: https://lore.kernel.org/r/20230511092609.76183-1-aidanmacdonald.0x0@gmail.com
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/mfd/axp20x-i2c.c | 2 +
- drivers/mfd/axp20x.c | 141 +++++++++++++++++++++++++++++++++++++
- include/linux/mfd/axp20x.h | 84 ++++++++++++++++++++++
- 3 files changed, 227 insertions(+)
-
---- a/drivers/mfd/axp20x-i2c.c
-+++ b/drivers/mfd/axp20x-i2c.c
-@@ -60,6 +60,7 @@ static void axp20x_i2c_remove(struct i2c
- #ifdef CONFIG_OF
- static const struct of_device_id axp20x_i2c_of_match[] = {
- { .compatible = "x-powers,axp152", .data = (void *)AXP152_ID },
-+ { .compatible = "x-powers,axp192", .data = (void *)AXP192_ID },
- { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
- { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
- { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
-@@ -75,6 +76,7 @@ MODULE_DEVICE_TABLE(of, axp20x_i2c_of_ma
-
- static const struct i2c_device_id axp20x_i2c_id[] = {
- { "axp152", 0 },
-+ { "axp192", 0 },
- { "axp202", 0 },
- { "axp209", 0 },
- { "axp221", 0 },
---- a/drivers/mfd/axp20x.c
-+++ b/drivers/mfd/axp20x.c
-@@ -34,6 +34,7 @@
-
- static const char * const axp20x_model_names[] = {
- "AXP152",
-+ "AXP192",
- "AXP202",
- "AXP209",
- "AXP221",
-@@ -94,6 +95,35 @@ static const struct regmap_access_table
- .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
- };
-
-+static const struct regmap_range axp192_writeable_ranges[] = {
-+ regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)),
-+ regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE),
-+ regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL),
-+ regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL),
-+};
-+
-+static const struct regmap_range axp192_volatile_ranges[] = {
-+ regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS),
-+ regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE),
-+ regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE),
-+ regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
-+ regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
-+ regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE),
-+ regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE),
-+ regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL),
-+ regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL),
-+};
-+
-+static const struct regmap_access_table axp192_writeable_table = {
-+ .yes_ranges = axp192_writeable_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(axp192_writeable_ranges),
-+};
-+
-+static const struct regmap_access_table axp192_volatile_table = {
-+ .yes_ranges = axp192_volatile_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(axp192_volatile_ranges),
-+};
-+
- /* AXP22x ranges are shared with the AXP809, as they cover the same range */
- static const struct regmap_range axp22x_writeable_ranges[] = {
- regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
-@@ -220,6 +250,19 @@ static const struct resource axp152_pek_
- DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- };
-
-+static const struct resource axp192_ac_power_supply_resources[] = {
-+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
-+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
-+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
-+};
-+
-+static const struct resource axp192_usb_power_supply_resources[] = {
-+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
-+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
-+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"),
-+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
-+};
-+
- static const struct resource axp20x_ac_power_supply_resources[] = {
- DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
- DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
-@@ -302,6 +345,15 @@ static const struct regmap_config axp152
- .cache_type = REGCACHE_RBTREE,
- };
-
-+static const struct regmap_config axp192_regmap_config = {
-+ .reg_bits = 8,
-+ .val_bits = 8,
-+ .wr_table = &axp192_writeable_table,
-+ .volatile_table = &axp192_volatile_table,
-+ .max_register = AXP20X_CC_CTRL,
-+ .cache_type = REGCACHE_RBTREE,
-+};
-+
- static const struct regmap_config axp20x_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-@@ -379,6 +431,42 @@ static const struct regmap_irq axp152_re
- INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0),
- };
-
-+static const struct regmap_irq axp192_regmap_irqs[] = {
-+ INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V, 0, 7),
-+ INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN, 0, 6),
-+ INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL, 0, 5),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V, 0, 4),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN, 0, 3),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL, 0, 2),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW, 0, 1),
-+ INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN, 1, 7),
-+ INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL, 1, 6),
-+ INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE, 1, 5),
-+ INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE, 1, 4),
-+ INIT_REGMAP_IRQ(AXP192, CHARG, 1, 3),
-+ INIT_REGMAP_IRQ(AXP192, CHARG_DONE, 1, 2),
-+ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH, 1, 1),
-+ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW, 1, 0),
-+ INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH, 2, 7),
-+ INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW, 2, 6),
-+ INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG, 2, 5),
-+ INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG, 2, 4),
-+ INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG, 2, 3),
-+ INIT_REGMAP_IRQ(AXP192, PEK_SHORT, 2, 1),
-+ INIT_REGMAP_IRQ(AXP192, PEK_LONG, 2, 0),
-+ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON, 3, 7),
-+ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF, 3, 6),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_VALID, 3, 5),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID, 3, 4),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID, 3, 3),
-+ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END, 3, 2),
-+ INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL, 3, 0),
-+ INIT_REGMAP_IRQ(AXP192, TIMER, 4, 7),
-+ INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT, 4, 2),
-+ INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT, 4, 1),
-+ INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT, 4, 0),
-+};
-+
- static const struct regmap_irq axp20x_regmap_irqs[] = {
- INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7),
- INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6),
-@@ -616,6 +704,32 @@ static const struct regmap_irq_chip axp1
- .num_regs = 3,
- };
-
-+static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data,
-+ unsigned int base, int index)
-+{
-+ /* linear mapping for IRQ1 to IRQ4 */
-+ if (index < 4)
-+ return base + index;
-+
-+ /* handle IRQ5 separately */
-+ if (base == AXP192_IRQ1_EN)
-+ return AXP192_IRQ5_EN;
-+
-+ return AXP192_IRQ5_STATE;
-+}
-+
-+static const struct regmap_irq_chip axp192_regmap_irq_chip = {
-+ .name = "axp192_irq_chip",
-+ .status_base = AXP192_IRQ1_STATE,
-+ .ack_base = AXP192_IRQ1_STATE,
-+ .unmask_base = AXP192_IRQ1_EN,
-+ .init_ack_masked = true,
-+ .irqs = axp192_regmap_irqs,
-+ .num_irqs = ARRAY_SIZE(axp192_regmap_irqs),
-+ .num_regs = 5,
-+ .get_irq_reg = axp192_get_irq_reg,
-+};
-+
- static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
- .name = "axp20x_irq_chip",
- .status_base = AXP20X_IRQ1_STATE,
-@@ -712,6 +826,27 @@ static const struct regmap_irq_chip axp1
- .num_regs = 2,
- };
-
-+static const struct mfd_cell axp192_cells[] = {
-+ {
-+ .name = "axp192-adc",
-+ .of_compatible = "x-powers,axp192-adc",
-+ }, {
-+ .name = "axp20x-battery-power-supply",
-+ .of_compatible = "x-powers,axp192-battery-power-supply",
-+ }, {
-+ .name = "axp20x-ac-power-supply",
-+ .of_compatible = "x-powers,axp202-ac-power-supply",
-+ .num_resources = ARRAY_SIZE(axp192_ac_power_supply_resources),
-+ .resources = axp192_ac_power_supply_resources,
-+ }, {
-+ .name = "axp20x-usb-power-supply",
-+ .of_compatible = "x-powers,axp192-usb-power-supply",
-+ .num_resources = ARRAY_SIZE(axp192_usb_power_supply_resources),
-+ .resources = axp192_usb_power_supply_resources,
-+ },
-+ { .name = "axp20x-regulator" },
-+};
-+
- static const struct mfd_cell axp20x_cells[] = {
- {
- .name = "axp20x-gpio",
-@@ -1029,6 +1164,12 @@ int axp20x_match_device(struct axp20x_de
- axp20x->regmap_cfg = &axp152_regmap_config;
- axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
- break;
-+ case AXP192_ID:
-+ axp20x->nr_cells = ARRAY_SIZE(axp192_cells);
-+ axp20x->cells = axp192_cells;
-+ axp20x->regmap_cfg = &axp192_regmap_config;
-+ axp20x->regmap_irq_chip = &axp192_regmap_irq_chip;
-+ break;
- case AXP202_ID:
- case AXP209_ID:
- axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
---- a/include/linux/mfd/axp20x.h
-+++ b/include/linux/mfd/axp20x.h
-@@ -12,6 +12,7 @@
-
- enum axp20x_variants {
- AXP152_ID = 0,
-+ AXP192_ID,
- AXP202_ID,
- AXP209_ID,
- AXP221_ID,
-@@ -26,6 +27,7 @@ enum axp20x_variants {
- NR_AXP20X_VARIANTS,
- };
-
-+#define AXP192_DATACACHE(m) (0x06 + (m))
- #define AXP20X_DATACACHE(m) (0x04 + (m))
-
- /* Power supply */
-@@ -47,6 +49,13 @@ enum axp20x_variants {
- #define AXP152_DCDC_FREQ 0x37
- #define AXP152_DCDC_MODE 0x80
-
-+#define AXP192_USB_OTG_STATUS 0x04
-+#define AXP192_PWR_OUT_CTRL 0x12
-+#define AXP192_DCDC2_V_OUT 0x23
-+#define AXP192_DCDC1_V_OUT 0x26
-+#define AXP192_DCDC3_V_OUT 0x27
-+#define AXP192_LDO2_3_V_OUT 0x28
-+
- #define AXP20X_PWR_INPUT_STATUS 0x00
- #define AXP20X_PWR_OP_MODE 0x01
- #define AXP20X_USB_OTG_STATUS 0x02
-@@ -185,6 +194,17 @@ enum axp20x_variants {
- #define AXP152_IRQ2_STATE 0x49
- #define AXP152_IRQ3_STATE 0x4a
-
-+#define AXP192_IRQ1_EN 0x40
-+#define AXP192_IRQ2_EN 0x41
-+#define AXP192_IRQ3_EN 0x42
-+#define AXP192_IRQ4_EN 0x43
-+#define AXP192_IRQ1_STATE 0x44
-+#define AXP192_IRQ2_STATE 0x45
-+#define AXP192_IRQ3_STATE 0x46
-+#define AXP192_IRQ4_STATE 0x47
-+#define AXP192_IRQ5_EN 0x4a
-+#define AXP192_IRQ5_STATE 0x4d
-+
- #define AXP20X_IRQ1_EN 0x40
- #define AXP20X_IRQ2_EN 0x41
- #define AXP20X_IRQ3_EN 0x42
-@@ -204,6 +224,11 @@ enum axp20x_variants {
- #define AXP15060_IRQ2_STATE 0x49
-
- /* ADC */
-+#define AXP192_GPIO2_V_ADC_H 0x68
-+#define AXP192_GPIO2_V_ADC_L 0x69
-+#define AXP192_GPIO3_V_ADC_H 0x6a
-+#define AXP192_GPIO3_V_ADC_L 0x6b
-+
- #define AXP20X_ACIN_V_ADC_H 0x56
- #define AXP20X_ACIN_V_ADC_L 0x57
- #define AXP20X_ACIN_I_ADC_H 0x58
-@@ -233,6 +258,8 @@ enum axp20x_variants {
- #define AXP20X_IPSOUT_V_HIGH_L 0x7f
-
- /* Power supply */
-+#define AXP192_GPIO30_IN_RANGE 0x85
-+
- #define AXP20X_DCDC_MODE 0x80
- #define AXP20X_ADC_EN1 0x82
- #define AXP20X_ADC_EN2 0x83
-@@ -261,6 +288,16 @@ enum axp20x_variants {
- #define AXP152_PWM1_FREQ_Y 0x9c
- #define AXP152_PWM1_DUTY_CYCLE 0x9d
-
-+#define AXP192_GPIO0_CTRL 0x90
-+#define AXP192_LDO_IO0_V_OUT 0x91
-+#define AXP192_GPIO1_CTRL 0x92
-+#define AXP192_GPIO2_CTRL 0x93
-+#define AXP192_GPIO2_0_STATE 0x94
-+#define AXP192_GPIO4_3_CTRL 0x95
-+#define AXP192_GPIO4_3_STATE 0x96
-+#define AXP192_GPIO2_0_PULL 0x97
-+#define AXP192_N_RSTO_CTRL 0x9e
-+
- #define AXP20X_GPIO0_CTRL 0x90
- #define AXP20X_LDO5_V_OUT 0x91
- #define AXP20X_GPIO1_CTRL 0x92
-@@ -341,6 +378,17 @@ enum axp20x_variants {
-
- /* Regulators IDs */
- enum {
-+ AXP192_DCDC1 = 0,
-+ AXP192_DCDC2,
-+ AXP192_DCDC3,
-+ AXP192_LDO1,
-+ AXP192_LDO2,
-+ AXP192_LDO3,
-+ AXP192_LDO_IO0,
-+ AXP192_REG_ID_MAX
-+};
-+
-+enum {
- AXP20X_LDO1 = 0,
- AXP20X_LDO2,
- AXP20X_LDO3,
-@@ -531,6 +579,42 @@ enum {
- AXP152_IRQ_GPIO0_INPUT,
- };
-
-+enum axp192_irqs {
-+ AXP192_IRQ_ACIN_OVER_V = 1,
-+ AXP192_IRQ_ACIN_PLUGIN,
-+ AXP192_IRQ_ACIN_REMOVAL,
-+ AXP192_IRQ_VBUS_OVER_V,
-+ AXP192_IRQ_VBUS_PLUGIN,
-+ AXP192_IRQ_VBUS_REMOVAL,
-+ AXP192_IRQ_VBUS_V_LOW,
-+ AXP192_IRQ_BATT_PLUGIN,
-+ AXP192_IRQ_BATT_REMOVAL,
-+ AXP192_IRQ_BATT_ENT_ACT_MODE,
-+ AXP192_IRQ_BATT_EXIT_ACT_MODE,
-+ AXP192_IRQ_CHARG,
-+ AXP192_IRQ_CHARG_DONE,
-+ AXP192_IRQ_BATT_TEMP_HIGH,
-+ AXP192_IRQ_BATT_TEMP_LOW,
-+ AXP192_IRQ_DIE_TEMP_HIGH,
-+ AXP192_IRQ_CHARG_I_LOW,
-+ AXP192_IRQ_DCDC1_V_LONG,
-+ AXP192_IRQ_DCDC2_V_LONG,
-+ AXP192_IRQ_DCDC3_V_LONG,
-+ AXP192_IRQ_PEK_SHORT = 22,
-+ AXP192_IRQ_PEK_LONG,
-+ AXP192_IRQ_N_OE_PWR_ON,
-+ AXP192_IRQ_N_OE_PWR_OFF,
-+ AXP192_IRQ_VBUS_VALID,
-+ AXP192_IRQ_VBUS_NOT_VALID,
-+ AXP192_IRQ_VBUS_SESS_VALID,
-+ AXP192_IRQ_VBUS_SESS_END,
-+ AXP192_IRQ_LOW_PWR_LVL = 31,
-+ AXP192_IRQ_TIMER,
-+ AXP192_IRQ_GPIO2_INPUT = 37,
-+ AXP192_IRQ_GPIO1_INPUT,
-+ AXP192_IRQ_GPIO0_INPUT,
-+};
-+
- enum {
- AXP20X_IRQ_ACIN_OVER_V = 1,
- AXP20X_IRQ_ACIN_PLUGIN,
diff --git a/target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch b/target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch
deleted file mode 100644
index 38fbc3a3d7..0000000000
--- a/target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From dbf70fc204d2fbb0d8ad8f42038a60846502efda Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Mon, 10 Oct 2022 13:51:09 +0300
-Subject: [PATCH] mtd: spinand: winbond: fix flash identification
-
-Winbond uses 3 bytes to identify flash: vendor_id, dev_id_0, dev_id_1,
-but current driver uses only first 2 bytes of it for devices
-identification. As result Winbond W25N02KV flash (id_bytes: EF, AA, 22)
-is identified as W25N01GV (id_bytes: EF, AA, 21).
-
-Fix this by adding missed identification bytes.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-1-mikhail.kshevetskiy@iopsys.eu
----
- drivers/mtd/nand/spi/winbond.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/nand/spi/winbond.c
-+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct
-
- static const struct spinand_info winbond_spinand_table[] = {
- SPINAND_INFO("W25M02GV",
-- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab),
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
- NAND_ECCREQ(1, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -86,7 +86,7 @@ static const struct spinand_info winbond
- SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
- SPINAND_SELECT_TARGET(w25m02gv_select_target)),
- SPINAND_INFO("W25N01GV",
-- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa),
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(1, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
diff --git a/target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch b/target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch
deleted file mode 100644
index d75a1acc57..0000000000
--- a/target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 6154c7a583483d7b69f53bea868efdc369edd563 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Mon, 10 Oct 2022 13:51:10 +0300
-Subject: [PATCH] mtd: spinand: winbond: add Winbond W25N02KV flash support
-
-Add support of Winbond W25N02KV flash
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-2-mikhail.kshevetskiy@iopsys.eu
----
- drivers/mtd/nand/spi/winbond.c | 75 ++++++++++++++++++++++++++++++++++
- 1 file changed, 75 insertions(+)
-
---- a/drivers/mtd/nand/spi/winbond.c
-+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -74,6 +74,72 @@ static int w25m02gv_select_target(struct
- return spi_mem_exec_op(spinand->spimem, &op);
- }
-
-+static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = 64 + (16 * section);
-+ region->length = 13;
-+
-+ return 0;
-+}
-+
-+static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = (16 * section) + 2;
-+ region->length = 14;
-+
-+ return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
-+ .ecc = w25n02kv_ooblayout_ecc,
-+ .free = w25n02kv_ooblayout_free,
-+};
-+
-+static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
-+ u8 status)
-+{
-+ struct nand_device *nand = spinand_to_nand(spinand);
-+ u8 mbf = 0;
-+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
-+
-+ switch (status & STATUS_ECC_MASK) {
-+ case STATUS_ECC_NO_BITFLIPS:
-+ return 0;
-+
-+ case STATUS_ECC_UNCOR_ERROR:
-+ return -EBADMSG;
-+
-+ case STATUS_ECC_HAS_BITFLIPS:
-+ /*
-+ * Let's try to retrieve the real maximum number of bitflips
-+ * in order to avoid forcing the wear-leveling layer to move
-+ * data around if it's not necessary.
-+ */
-+ if (spi_mem_exec_op(spinand->spimem, &op))
-+ return nanddev_get_ecc_conf(nand)->strength;
-+
-+ mbf >>= 4;
-+
-+ if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
-+ return nanddev_get_ecc_conf(nand)->strength;
-+
-+ return mbf;
-+
-+ default:
-+ break;
-+ }
-+
-+ return -EINVAL;
-+}
-+
- static const struct spinand_info winbond_spinand_table[] = {
- SPINAND_INFO("W25M02GV",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
-@@ -94,6 +160,15 @@ static const struct spinand_info winbond
- &update_cache_variants),
- 0,
- SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
-+ SPINAND_INFO("W25N02KV",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
- };
-
- static int winbond_spinand_init(struct spinand_device *spinand)
diff --git a/target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch b/target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch
deleted file mode 100644
index 2f408f5a30..0000000000
--- a/target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From f5a05060670a4d8d6523afc7963eb559c2e3615f Mon Sep 17 00:00:00 2001
-From: Olivier Maignial <olivier.maignial@hotmail.fr>
-Date: Fri, 23 Jun 2023 17:33:37 +0200
-Subject: [PATCH] mtd: spinand: winbond: Fix ecc_get_status
-
-Reading ECC status is failing.
-
-w25n02kv_ecc_get_status() is using on-stack buffer for
-SPINAND_GET_FEATURE_OP() output. It is not suitable for
-DMA needs of spi-mem.
-
-Fix this by using the spi-mem operations dedicated buffer
-spinand->scratchbuf.
-
-See
-spinand->scratchbuf:
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/mtd/spinand.h?h=v6.3#n418
-spi_mem_check_op():
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-mem.c?h=v6.3#n199
-
-Fixes: 6154c7a58348 ("mtd: spinand: winbond: add Winbond W25N02KV flash support")
-Cc: stable@vger.kernel.org
-Signed-off-by: Olivier Maignial <olivier.maignial@hotmail.fr>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/DB4P250MB1032EDB9E36B764A33769039FE23A@DB4P250MB1032.EURP250.PROD.OUTLOOK.COM
----
- drivers/mtd/nand/spi/winbond.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/nand/spi/winbond.c
-+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struc
- {
- struct nand_device *nand = spinand_to_nand(spinand);
- u8 mbf = 0;
-- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
-+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf);
-
- switch (status & STATUS_ECC_MASK) {
- case STATUS_ECC_NO_BITFLIPS:
-@@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(struc
- if (spi_mem_exec_op(spinand->spimem, &op))
- return nanddev_get_ecc_conf(nand)->strength;
-
-- mbf >>= 4;
-+ mbf = *(spinand->scratchbuf) >> 4;
-
- if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
- return nanddev_get_ecc_conf(nand)->strength;
diff --git a/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch b/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch
deleted file mode 100644
index 5094a6d774..0000000000
--- a/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From mboxrd@z Thu Jan 1 00:00:00 1970
-Authentication-Results: smtp.subspace.kernel.org;
- dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="sMUeie/T"
-Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84BB8D6D
- for <bpf@vger.kernel.org>; Wed, 6 Dec 2023 15:16:16 -0800 (PST)
-Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-db5416d0fccso403298276.1
- for <bpf@vger.kernel.org>; Wed, 06 Dec 2023 15:16:16 -0800 (PST)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=google.com; s=20230601; t=1701904575; x=1702509375; darn=vger.kernel.org;
- h=cc:to:from:subject:message-id:references:mime-version:in-reply-to
- :date:from:to:cc:subject:date:message-id:reply-to;
- bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=;
- b=sMUeie/TxdytzC0EyT11QWi1TqTtiv7KCTs1F2vLmUUvPKNA3+1MHFo8ECW+0gQuDE
- FGrgdZKGK5mXQgkF0N3JiSLvKO8tpQOIB57JLCG5IVy5dr2vVv0ExU3Dag2Cc4oBIBIO
- w/cH95O1oPlvluIpATmAsxenVr7mFomU63BqYiRGLaEhWeb2hJ636GO8lubtsDfdFFoi
- GPOL2tQwV93VnqmywBBpFaNAULN0UoCFhfkKv5prvpkXq19sWI7zyorVZ+rdTYem5m4T
- dXsDaLXPtC3Dh2JOad1duSQIah/wCHYYUcV3IoFhwj2y0Uk/TTCrnZPORweSADcEy6Ho
- vDrA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20230601; t=1701904575; x=1702509375;
- h=cc:to:from:subject:message-id:references:mime-version:in-reply-to
- :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
- bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=;
- b=Dmc6aSntxPlxAk72zVO1G9WoZnFtLolxENlLscYYAHG3VE+PQ8gGN2rPzcGoKb2Btb
- 4b0PvjOzSlPQyghahdhdlz04RtAeeGG/MkfNiYjFql5OifIoovb51kroiPYrVsa7Ps7Y
- +Pxug0+NPdTm5s9TNz940ZKl3GRME8UTmVxpWJRX03XMOqb6Wgsh2SK9ahXKc4yRsi62
- 3a3J72WmmSgvimxwM/99fXwvoUQpiv2J1xCoqc1Ng4q4qSuZvzmHN7ZTGaUhLxOqLeLK
- 3W4RKHW6rZ7UjppuB6I3NXW+D344By2rdKp1sRXpjdQ0GS3YUcvlRETcJBXJudHfQP5Y
- CLOw==
-X-Gm-Message-State: AOJu0YzdCTLdwny+N99zeMgyKqFsEZhfIhL2cbgKA6zC1U/OLkxxRLoM
- XrYVBC9DmxCGmP4o+M/Z/kHUew/9faHlCiLGxw==
-X-Google-Smtp-Source: AGHT+IFRXxBV6JuX5Cl/k2o1+WKkCwkR8j20MJSkmoGCedPAtqFttH8OVh1/6vdfnq8MPN++A2h89peZQhyG8OsJ8A==
-X-Received: from jstitt-linux1.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:23b5])
- (user=justinstitt job=sendgmr) by 2002:a25:dac7:0:b0:da0:3117:f35 with SMTP
- id n190-20020a25dac7000000b00da031170f35mr28652ybf.3.1701904575576; Wed, 06
- Dec 2023 15:16:15 -0800 (PST)
-Date: Wed, 06 Dec 2023 23:16:10 +0000
-In-Reply-To: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com>
-Precedence: bulk
-X-Mailing-List: bpf@vger.kernel.org
-List-Id: <bpf.vger.kernel.org>
-List-Subscribe: <mailto:bpf+subscribe@vger.kernel.org>
-List-Unsubscribe: <mailto:bpf+unsubscribe@vger.kernel.org>
-Mime-Version: 1.0
-References: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com>
-X-Developer-Key: i=justinstitt@google.com; a=ed25519; pk=tC3hNkJQTpNX/gLKxTNQKDmiQl6QjBNCGKJINqAdJsE=
-X-Developer-Signature: v=1; a=ed25519-sha256; t=1701904573; l=1840;
- i=justinstitt@google.com; s=20230717; h=from:subject:message-id;
- bh=UMdetIL2ZsPIkSodqhw2fM21NHJVjCu0lRImFuNhVoM=; b=a8rMnXfVVQ5gsxHWG4WRMwOLxZgflqXZtNuKx26vv4DwYvvCtCiYjl3f1frOjV/Ul2kaxq5g/
- b/UOv678JKCDASVokxG5GJifAnU7/kqRxdhcwfRkrD8RUfcsmiZOfyF
-X-Mailer: b4 0.12.3
-Message-ID: <20231206-ethtool_puts_impl-v5-1-5a2528e17bf8@google.com>
-Subject: [PATCH net-next v5 1/3] ethtool: Implement ethtool_puts()
-From: justinstitt@google.com
-To: "David S. Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Shay Agroskin <shayagr@amazon.com>,
- Arthur Kiyanovski <akiyano@amazon.com>, David Arinzon <darinzon@amazon.com>, Noam Dagan <ndagan@amazon.com>,
- Saeed Bishara <saeedb@amazon.com>, Rasesh Mody <rmody@marvell.com>,
- Sudarsana Kalluru <skalluru@marvell.com>, GR-Linux-NIC-Dev@marvell.com,
- Dimitris Michailidis <dmichail@fungible.com>, Yisen Zhuang <yisen.zhuang@huawei.com>,
- Salil Mehta <salil.mehta@huawei.com>, Jesse Brandeburg <jesse.brandeburg@intel.com>,
- Tony Nguyen <anthony.l.nguyen@intel.com>, Louis Peens <louis.peens@corigine.com>,
- Shannon Nelson <shannon.nelson@amd.com>, Brett Creeley <brett.creeley@amd.com>, drivers@pensando.io,
- "K. Y. Srinivasan" <kys@microsoft.com>, Haiyang Zhang <haiyangz@microsoft.com>, Wei Liu <wei.liu@kernel.org>,
- Dexuan Cui <decui@microsoft.com>, Ronak Doshi <doshir@vmware.com>,
- VMware PV-Drivers Reviewers <pv-drivers@vmware.com>, Andy Whitcroft <apw@canonical.com>, Joe Perches <joe@perches.com>,
- Dwaipayan Ray <dwaipayanray1@gmail.com>, Lukas Bulwahn <lukas.bulwahn@gmail.com>,
- Hauke Mehrtens <hauke@hauke-m.de>, Andrew Lunn <andrew@lunn.ch>,
- Florian Fainelli <f.fainelli@gmail.com>, Vladimir Oltean <olteanv@gmail.com>,
- "=?utf-8?q?Ar=C4=B1n=C3=A7_=C3=9CNAL?=" <arinc.unal@arinc9.com>, Daniel Golle <daniel@makrotopia.org>,
- Landen Chao <Landen.Chao@mediatek.com>, DENG Qingfang <dqfext@gmail.com>,
- Sean Wang <sean.wang@mediatek.com>, Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Linus Walleij <linus.walleij@linaro.org>,
- "=?utf-8?q?Alvin_=C5=A0ipraga?=" <alsi@bang-olufsen.dk>, Wei Fang <wei.fang@nxp.com>,
- Shenwei Wang <shenwei.wang@nxp.com>, Clark Wang <xiaoning.wang@nxp.com>,
- NXP Linux Team <linux-imx@nxp.com>, Lars Povlsen <lars.povlsen@microchip.com>,
- Steen Hegelund <Steen.Hegelund@microchip.com>, Daniel Machon <daniel.machon@microchip.com>,
- UNGLinuxDriver@microchip.com, Jiawen Wu <jiawenwu@trustnetic.com>,
- Mengyuan Lou <mengyuanlou@net-swift.com>, Heiner Kallweit <hkallweit1@gmail.com>,
- Russell King <linux@armlinux.org.uk>, Alexei Starovoitov <ast@kernel.org>,
- Daniel Borkmann <daniel@iogearbox.net>, Jesper Dangaard Brouer <hawk@kernel.org>,
- John Fastabend <john.fastabend@gmail.com>
-Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
- Nick Desaulniers <ndesaulniers@google.com>, Nathan Chancellor <nathan@kernel.org>,
- Kees Cook <keescook@chromium.org>, intel-wired-lan@lists.osuosl.org,
- oss-drivers@corigine.com, linux-hyperv@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org,
- bpf@vger.kernel.org, Justin Stitt <justinstitt@google.com>
-Content-Type: text/plain; charset="utf-8"
-
-Use strscpy() to implement ethtool_puts().
-
-Functionally the same as ethtool_sprintf() when it's used with two
-arguments or with just "%s" format specifier.
-
-Signed-off-by: Justin Stitt <justinstitt@google.com>
----
- include/linux/ethtool.h | 13 +++++++++++++
- net/ethtool/ioctl.c | 7 +++++++
- 2 files changed, 20 insertions(+)
-
---- a/include/linux/ethtool.h
-+++ b/include/linux/ethtool.h
-@@ -843,4 +843,17 @@ int ethtool_get_phc_vclocks(struct net_d
- * next string.
- */
- extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...);
-+
-+/**
-+ * ethtool_puts - Write string to ethtool string data
-+ * @data: Pointer to a pointer to the start of string to update
-+ * @str: String to write
-+ *
-+ * Write string to *data without a trailing newline. Update *data
-+ * to point at start of next string.
-+ *
-+ * Prefer this function to ethtool_sprintf() when given only
-+ * two arguments or if @fmt is just "%s".
-+ */
-+extern void ethtool_puts(u8 **data, const char *str);
- #endif /* _LINUX_ETHTOOL_H */
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -1974,6 +1974,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
- }
- EXPORT_SYMBOL(ethtool_sprintf);
-
-+void ethtool_puts(u8 **data, const char *str)
-+{
-+ strscpy(*data, str, ETH_GSTRING_LEN);
-+ *data += ETH_GSTRING_LEN;
-+}
-+EXPORT_SYMBOL(ethtool_puts);
-+
- static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
- {
- struct ethtool_value id;
diff --git a/target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch b/target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch
deleted file mode 100644
index 3a9b856a20..0000000000
--- a/target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 1a7aa058bc92f0edae7a0d1ef1a7b05aec0c643a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Nov 2023 12:27:52 +0000
-Subject: [PATCH 1/7] net: phy: add possible interfaces
-
-Add a possible_interfaces member to struct phy_device to indicate which
-interfaces a clause 45 PHY may switch between depending on the media.
-This must be populated by the PHY driver by the time the .config_init()
-method completes according to the PHYs host-side configuration.
-
-For example, the Marvell 88x3310 PHY can switch between 10GBASE-R,
-5GBASE-R, 2500BASE-X, and SGMII on the host side depending on the media
-side speed, so all these interface modes are set in the
-possible_interfaces member.
-
-This allows phylib users (such as phylink) to know in advance which
-interface modes to expect, which allows them to appropriately restrict
-the advertised link modes according to the capabilities of other parts
-of the link.
-
-Tested-by: Luo Jie <quic_luoj@quicinc.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/E1r6VHk-00DDLN-I7@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy_device.c | 2 ++
- include/linux/phy.h | 3 +++
- 2 files changed, 5 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1215,6 +1215,8 @@ int phy_init_hw(struct phy_device *phyde
- if (ret < 0)
- return ret;
-
-+ phy_interface_zero(phydev->possible_interfaces);
-+
- if (phydev->drv->config_init) {
- ret = phydev->drv->config_init(phydev);
- if (ret < 0)
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -600,6 +600,8 @@ struct macsec_ops;
- * @irq_rerun: Flag indicating interrupts occurred while PHY was suspended,
- * requiring a rerun of the interrupt handler after resume
- * @interface: enum phy_interface_t value
-+ * @possible_interfaces: bitmap if interface modes that the attached PHY
-+ * will switch between depending on media speed.
- * @skb: Netlink message for cable diagnostics
- * @nest: Netlink nest used for cable diagnostics
- * @ehdr: nNtlink header for cable diagnostics
-@@ -665,6 +667,7 @@ struct phy_device {
- u32 dev_flags;
-
- phy_interface_t interface;
-+ DECLARE_PHY_INTERFACE_MASK(possible_interfaces);
-
- /*
- * forced speed & duplex (no autoneg)
diff --git a/target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch b/target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch
deleted file mode 100644
index 155ec1c2d9..0000000000
--- a/target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 85631f5b33f2acce7d42dec1d0a062ab40de95b8 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sun, 19 Nov 2023 21:07:43 +0000
-Subject: [PATCH 2/7] net: phylink: use for_each_set_bit()
-
-Use for_each_set_bit() rather than open coding the for() test_bit()
-loop.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
-Link: https://lore.kernel.org/r/E1r4p15-00Cpxe-C7@rmk-PC.armlinux.org.uk
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/phylink.c | 18 ++++++++----------
- 1 file changed, 8 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -690,18 +690,16 @@ static int phylink_validate_mask(struct
- __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, };
- __ETHTOOL_DECLARE_LINK_MODE_MASK(s);
- struct phylink_link_state t;
-- int intf;
-+ int interface;
-
-- for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) {
-- if (test_bit(intf, interfaces)) {
-- linkmode_copy(s, supported);
-+ for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) {
-+ linkmode_copy(s, supported);
-
-- t = *state;
-- t.interface = intf;
-- if (!phylink_validate_mac_and_pcs(pl, s, &t)) {
-- linkmode_or(all_s, all_s, s);
-- linkmode_or(all_adv, all_adv, t.advertising);
-- }
-+ t = *state;
-+ t.interface = interface;
-+ if (!phylink_validate_mac_and_pcs(pl, s, &t)) {
-+ linkmode_or(all_s, all_s, s);
-+ linkmode_or(all_adv, all_adv, t.advertising);
- }
- }
-
diff --git a/target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch b/target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch
deleted file mode 100644
index 163cb953f7..0000000000
--- a/target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From d4788b4383ce5caeb4e68818357c81a02117a3f9 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Nov 2023 12:28:19 +0000
-Subject: [PATCH 3/7] net: phylink: split out per-interface validation
-
-Split out the internals of phylink_validate_mask() to make the code
-easier to read.
-
-Tested-by: Luo Jie <quic_luoj@quicinc.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/E1r6VIB-00DDLr-7g@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 42 ++++++++++++++++++++++++++++-----------
- 1 file changed, 30 insertions(+), 12 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -682,26 +682,44 @@ static int phylink_validate_mac_and_pcs(
- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
- }
-
-+static void phylink_validate_one(struct phylink *pl,
-+ const unsigned long *supported,
-+ const struct phylink_link_state *state,
-+ phy_interface_t interface,
-+ unsigned long *accum_supported,
-+ unsigned long *accum_advertising)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp_supported);
-+ struct phylink_link_state tmp_state;
-+
-+ linkmode_copy(tmp_supported, supported);
-+
-+ tmp_state = *state;
-+ tmp_state.interface = interface;
-+
-+ if (!phylink_validate_mac_and_pcs(pl, tmp_supported, &tmp_state)) {
-+ phylink_dbg(pl, " interface %u (%s) rate match %s supports %*pbl\n",
-+ interface, phy_modes(interface),
-+ phy_rate_matching_to_str(tmp_state.rate_matching),
-+ __ETHTOOL_LINK_MODE_MASK_NBITS, tmp_supported);
-+
-+ linkmode_or(accum_supported, accum_supported, tmp_supported);
-+ linkmode_or(accum_advertising, accum_advertising,
-+ tmp_state.advertising);
-+ }
-+}
-+
- static int phylink_validate_mask(struct phylink *pl, unsigned long *supported,
- struct phylink_link_state *state,
- const unsigned long *interfaces)
- {
- __ETHTOOL_DECLARE_LINK_MODE_MASK(all_adv) = { 0, };
- __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, };
-- __ETHTOOL_DECLARE_LINK_MODE_MASK(s);
-- struct phylink_link_state t;
- int interface;
-
-- for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) {
-- linkmode_copy(s, supported);
--
-- t = *state;
-- t.interface = interface;
-- if (!phylink_validate_mac_and_pcs(pl, s, &t)) {
-- linkmode_or(all_s, all_s, s);
-- linkmode_or(all_adv, all_adv, t.advertising);
-- }
-- }
-+ for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX)
-+ phylink_validate_one(pl, supported, state, interface,
-+ all_s, all_adv);
-
- linkmode_copy(supported, all_s);
- linkmode_copy(state->advertising, all_adv);
diff --git a/target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch b/target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch
deleted file mode 100644
index 5012020676..0000000000
--- a/target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From ce7273c31fadb3143fc80c96a72a42adc19c2757 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Nov 2023 12:28:24 +0000
-Subject: [PATCH 4/7] net: phylink: pass PHY into phylink_validate_one()
-
-Pass the phy (if any) into phylink_validate_one() so that we can
-validate each interface with its rate matching setting.
-
-Tested-by: Luo Jie <quic_luoj@quicinc.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/E1r6VIG-00DDLx-Cb@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -682,7 +682,7 @@ static int phylink_validate_mac_and_pcs(
- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
- }
-
--static void phylink_validate_one(struct phylink *pl,
-+static void phylink_validate_one(struct phylink *pl, struct phy_device *phy,
- const unsigned long *supported,
- const struct phylink_link_state *state,
- phy_interface_t interface,
-@@ -697,6 +697,9 @@ static void phylink_validate_one(struct
- tmp_state = *state;
- tmp_state.interface = interface;
-
-+ if (phy)
-+ tmp_state.rate_matching = phy_get_rate_matching(phy, interface);
-+
- if (!phylink_validate_mac_and_pcs(pl, tmp_supported, &tmp_state)) {
- phylink_dbg(pl, " interface %u (%s) rate match %s supports %*pbl\n",
- interface, phy_modes(interface),
-@@ -718,7 +721,7 @@ static int phylink_validate_mask(struct
- int interface;
-
- for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX)
-- phylink_validate_one(pl, supported, state, interface,
-+ phylink_validate_one(pl, NULL, supported, state, interface,
- all_s, all_adv);
-
- linkmode_copy(supported, all_s);
diff --git a/target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch b/target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch
deleted file mode 100644
index 997c74346c..0000000000
--- a/target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From c6fec66d3cd76d797f70b30f1511bed10ba45a96 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Nov 2023 12:28:29 +0000
-Subject: [PATCH 5/7] net: phylink: pass PHY into phylink_validate_mask()
-
-Pass the phy (if any) into phylink_validate_mask() so that we can
-validate each interface with its rate matching setting.
-
-Tested-by: Luo Jie <quic_luoj@quicinc.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/E1r6VIL-00DDM3-HJ@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -712,7 +712,8 @@ static void phylink_validate_one(struct
- }
- }
-
--static int phylink_validate_mask(struct phylink *pl, unsigned long *supported,
-+static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy,
-+ unsigned long *supported,
- struct phylink_link_state *state,
- const unsigned long *interfaces)
- {
-@@ -721,7 +722,7 @@ static int phylink_validate_mask(struct
- int interface;
-
- for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX)
-- phylink_validate_one(pl, NULL, supported, state, interface,
-+ phylink_validate_one(pl, phy, supported, state, interface,
- all_s, all_adv);
-
- linkmode_copy(supported, all_s);
-@@ -736,7 +737,8 @@ static int phylink_validate(struct phyli
- const unsigned long *interfaces = pl->config->supported_interfaces;
-
- if (state->interface == PHY_INTERFACE_MODE_NA)
-- return phylink_validate_mask(pl, supported, state, interfaces);
-+ return phylink_validate_mask(pl, NULL, supported, state,
-+ interfaces);
-
- if (!test_bit(state->interface, interfaces))
- return -EINVAL;
-@@ -3132,7 +3134,8 @@ static int phylink_sfp_config_optical(st
- /* For all the interfaces that are supported, reduce the sfp_support
- * mask to only those link modes that can be supported.
- */
-- ret = phylink_validate_mask(pl, pl->sfp_support, &config, interfaces);
-+ ret = phylink_validate_mask(pl, NULL, pl->sfp_support, &config,
-+ interfaces);
- if (ret) {
- phylink_err(pl, "unsupported SFP module: validation with support %*pb failed\n",
- __ETHTOOL_LINK_MODE_MASK_NBITS, support);
diff --git a/target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch b/target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch
deleted file mode 100644
index d3d24c58fb..0000000000
--- a/target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From ee0e0ddb910e7e989b65a19d72b6435baa641fc7 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Nov 2023 12:28:34 +0000
-Subject: [PATCH 6/7] net: phylink: split out PHY validation from
- phylink_bringup_phy()
-
-When bringing up a PHY, we need to work out which ethtool link modes it
-should support and advertise. Clause 22 PHYs operate in a single
-interface mode, which can be easily dealt with. However, clause 45 PHYs
-tend to switch interface mode depending on the media. We need more
-flexible validation at this point, so this patch splits out that code
-in preparation to changing it.
-
-Tested-by: Luo Jie <quic_luoj@quicinc.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/E1r6VIQ-00DDM9-LK@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 56 ++++++++++++++++++++++-----------------
- 1 file changed, 31 insertions(+), 25 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1738,6 +1738,35 @@ static void phylink_phy_change(struct ph
- phylink_pause_to_str(pl->phy_state.pause));
- }
-
-+static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ /* Check whether we would use rate matching for the proposed interface
-+ * mode.
-+ */
-+ state->rate_matching = phy_get_rate_matching(phy, state->interface);
-+
-+ /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R,
-+ * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching.
-+ * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching
-+ * their Serdes is either unnecessary or not reasonable.
-+ *
-+ * For these which switch interface modes, we really need to know which
-+ * interface modes the PHY supports to properly work out which ethtool
-+ * linkmodes can be supported. For now, as a work-around, we validate
-+ * against all interface modes, which may lead to more ethtool link
-+ * modes being advertised than are actually supported.
-+ */
-+ if (phy->is_c45 && state->rate_matching == RATE_MATCH_NONE &&
-+ state->interface != PHY_INTERFACE_MODE_RXAUI &&
-+ state->interface != PHY_INTERFACE_MODE_XAUI &&
-+ state->interface != PHY_INTERFACE_MODE_USXGMII)
-+ state->interface = PHY_INTERFACE_MODE_NA;
-+
-+ return phylink_validate(pl, supported, state);
-+}
-+
- static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
- phy_interface_t interface)
- {
-@@ -1758,32 +1787,9 @@ static int phylink_bringup_phy(struct ph
- memset(&config, 0, sizeof(config));
- linkmode_copy(supported, phy->supported);
- linkmode_copy(config.advertising, phy->advertising);
-+ config.interface = interface;
-
-- /* Check whether we would use rate matching for the proposed interface
-- * mode.
-- */
-- config.rate_matching = phy_get_rate_matching(phy, interface);
--
-- /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R,
-- * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching.
-- * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching
-- * their Serdes is either unnecessary or not reasonable.
-- *
-- * For these which switch interface modes, we really need to know which
-- * interface modes the PHY supports to properly work out which ethtool
-- * linkmodes can be supported. For now, as a work-around, we validate
-- * against all interface modes, which may lead to more ethtool link
-- * modes being advertised than are actually supported.
-- */
-- if (phy->is_c45 && config.rate_matching == RATE_MATCH_NONE &&
-- interface != PHY_INTERFACE_MODE_RXAUI &&
-- interface != PHY_INTERFACE_MODE_XAUI &&
-- interface != PHY_INTERFACE_MODE_USXGMII)
-- config.interface = PHY_INTERFACE_MODE_NA;
-- else
-- config.interface = interface;
--
-- ret = phylink_validate(pl, supported, &config);
-+ ret = phylink_validate_phy(pl, phy, supported, &config);
- if (ret) {
- phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %pe\n",
- phy_modes(config.interface),
diff --git a/target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch b/target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch
deleted file mode 100644
index 201afbb7cf..0000000000
--- a/target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From 8f7a9799c5949f94ecc3acfd71b36437a7ade73b Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 24 Nov 2023 12:28:39 +0000
-Subject: [PATCH 7/7] net: phylink: use the PHY's possible_interfaces if
- populated
-
-Some PHYs such as Aquantia, Broadcom 84881, and Marvell 88X33x0 can
-switch between a set of interface types depending on the negotiated
-media speed, or can use rate adaption for some or all of these
-interface types.
-
-We currently assume that these are Clause 45 PHYs that are configured
-not to use a specific set of interface modes, which has worked so far,
-but is just a work-around. In this workaround, we validate using all
-interfaces that the MAC supports, which can lead to extra modes being
-advertised that can not be supported.
-
-To properly address this, switch to using the newly introduced PHY
-possible_interfaces bitmap which indicates which interface modes will
-be used by the PHY as configured. We calculate the union of the PHY's
-possible interfaces and MACs supported interfaces, checking that is
-non-empty. If the PHY is on a SFP, we further reduce the set by those
-which can be used on a SFP module, again checking that is non-empty.
-Finally, we validate the subset of interfaces, taking account of
-whether rate matching will be used for each individual interface mode.
-
-This becomes independent of whether the PHY is clause 22 or clause 45.
-
-It is encouraged that all PHYs that switch interface modes or use
-rate matching should populate phydev->possible_interfaces.
-
-Tested-by: Luo Jie <quic_luoj@quicinc.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/E1r6VIV-00DDMF-Pi@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 67 +++++++++++++++++++++++++++++++--------
- 1 file changed, 54 insertions(+), 13 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -121,6 +121,19 @@ do { \
- })
- #endif
-
-+static const phy_interface_t phylink_sfp_interface_preference[] = {
-+ PHY_INTERFACE_MODE_25GBASER,
-+ PHY_INTERFACE_MODE_USXGMII,
-+ PHY_INTERFACE_MODE_10GBASER,
-+ PHY_INTERFACE_MODE_5GBASER,
-+ PHY_INTERFACE_MODE_2500BASEX,
-+ PHY_INTERFACE_MODE_SGMII,
-+ PHY_INTERFACE_MODE_1000BASEX,
-+ PHY_INTERFACE_MODE_100BASEX,
-+};
-+
-+static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces);
-+
- /**
- * phylink_set_port_modes() - set the port type modes in the ethtool mask
- * @mask: ethtool link mode mask
-@@ -1742,6 +1755,47 @@ static int phylink_validate_phy(struct p
- unsigned long *supported,
- struct phylink_link_state *state)
- {
-+ DECLARE_PHY_INTERFACE_MASK(interfaces);
-+
-+ /* If the PHY provides a bitmap of the interfaces it will be using
-+ * depending on the negotiated media speeds, use this to validate
-+ * which ethtool link modes can be used.
-+ */
-+ if (!phy_interface_empty(phy->possible_interfaces)) {
-+ /* We only care about the union of the PHY's interfaces and
-+ * those which the host supports.
-+ */
-+ phy_interface_and(interfaces, phy->possible_interfaces,
-+ pl->config->supported_interfaces);
-+
-+ if (phy_interface_empty(interfaces)) {
-+ phylink_err(pl, "PHY has no common interfaces\n");
-+ return -EINVAL;
-+ }
-+
-+ if (phy_on_sfp(phy)) {
-+ /* If the PHY is on a SFP, limit the interfaces to
-+ * those that can be used with a SFP module.
-+ */
-+ phy_interface_and(interfaces, interfaces,
-+ phylink_sfp_interfaces);
-+
-+ if (phy_interface_empty(interfaces)) {
-+ phylink_err(pl, "SFP PHY's possible interfaces becomes empty\n");
-+ return -EINVAL;
-+ }
-+ }
-+
-+ phylink_dbg(pl, "PHY %s uses interfaces %*pbl, validating %*pbl\n",
-+ phydev_name(phy),
-+ (int)PHY_INTERFACE_MODE_MAX,
-+ phy->possible_interfaces,
-+ (int)PHY_INTERFACE_MODE_MAX, interfaces);
-+
-+ return phylink_validate_mask(pl, phy, supported, state,
-+ interfaces);
-+ }
-+
- /* Check whether we would use rate matching for the proposed interface
- * mode.
- */
-@@ -2985,19 +3039,6 @@ static void phylink_sfp_detach(void *ups
- pl->netdev->sfp_bus = NULL;
- }
-
--static const phy_interface_t phylink_sfp_interface_preference[] = {
-- PHY_INTERFACE_MODE_25GBASER,
-- PHY_INTERFACE_MODE_USXGMII,
-- PHY_INTERFACE_MODE_10GBASER,
-- PHY_INTERFACE_MODE_5GBASER,
-- PHY_INTERFACE_MODE_2500BASEX,
-- PHY_INTERFACE_MODE_SGMII,
-- PHY_INTERFACE_MODE_1000BASEX,
-- PHY_INTERFACE_MODE_100BASEX,
--};
--
--static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces);
--
- static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl,
- const unsigned long *intf)
- {
diff --git a/target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch b/target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch
deleted file mode 100644
index a11e804958..0000000000
--- a/target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From f058b2dd70b1a5503dff899010aeb53b436091e5 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Wed, 28 Feb 2024 18:24:09 +0100
-Subject: [PATCH 1/2] net: phy: qcom: qca808x: add helper for checking for 1G
- only model
-
-There are 2 versions of QCA808x, one 2.5G capable and one 1G capable.
-Currently, this matter only in the .get_features call however, it will
-be required for filling supported interface modes so lets add a helper
-that can be reused.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/qca808x.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -156,6 +156,17 @@ static bool qca808x_has_fast_retrain_or_
- return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
- }
-
-+static bool qca808x_is_1g_only(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-+ if (ret < 0)
-+ return true;
-+
-+ return !!(QCA808X_PHY_CHIP_TYPE_1G & ret);
-+}
-+
- static int qca808x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -350,11 +361,7 @@ static int qca808x_get_features(struct p
- * existed in the bit0 of MMD1.21, we need to remove it manually if
- * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
- */
-- ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-- if (ret < 0)
-- return ret;
--
-- if (QCA808X_PHY_CHIP_TYPE_1G & ret)
-+ if (qca808x_is_1g_only(phydev))
- linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-
- return 0;
diff --git a/target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch b/target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch
deleted file mode 100644
index c162fc7348..0000000000
--- a/target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From cb28f702960695e26597c332b0e46776e825cc34 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Wed, 28 Feb 2024 18:24:10 +0100
-Subject: [PATCH 2/2] net: phy: qcom: qca808x: fill in possible_interfaces
-
-Currently QCA808x driver does not fill the possible_interfaces.
-2.5G QCA808x support SGMII and 2500Base-X while 1G model only supports
-SGMII, so fill the possible_interfaces accordingly.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/qcom/qca808x.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -167,6 +167,16 @@ static bool qca808x_is_1g_only(struct ph
- return !!(QCA808X_PHY_CHIP_TYPE_1G & ret);
- }
-
-+static void qca808x_fill_possible_interfaces(struct phy_device *phydev)
-+{
-+ unsigned long *possible = phydev->possible_interfaces;
-+
-+ __set_bit(PHY_INTERFACE_MODE_SGMII, possible);
-+
-+ if (!qca808x_is_1g_only(phydev))
-+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, possible);
-+}
-+
- static int qca808x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -231,6 +241,8 @@ static int qca808x_config_init(struct ph
- }
- }
-
-+ qca808x_fill_possible_interfaces(phydev);
-+
- /* Configure adc threshold as 100mv for the link 10M */
- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
- QCA808X_ADC_THRESHOLD_MASK,
diff --git a/target/linux/generic/backport-6.6/0080-v6.9-smp-Avoid-setup_max_cpus_namespace_collision_shadowing.patch b/target/linux/generic/backport-6.6/0080-v6.9-smp-Avoid-setup_max_cpus_namespace_collision_shadowing.patch
new file mode 100644
index 0000000000..54ebaa1a80
--- /dev/null
+++ b/target/linux/generic/backport-6.6/0080-v6.9-smp-Avoid-setup_max_cpus_namespace_collision_shadowing.patch
@@ -0,0 +1,56 @@
+From 4c8a49854130da0117a0fdb858551824919a2389 Mon Sep 17 00:00:00 2001
+From: Ingo Molnar <mingo@kernel.org>
+Date: Tue, 27 Feb 2024 09:58:15 +0100
+Subject: [PATCH] smp: Avoid 'setup_max_cpus' namespace collision/shadowing
+
+bringup_nonboot_cpus() gets passed the 'setup_max_cpus'
+variable in init/main.c - which is also the name of the parameter,
+shadowing the name.
+
+To reduce confusion and to allow the 'setup_max_cpus' value
+to be #defined in the <linux/smp.h> header, use the 'max_cpus'
+name for the function parameter name.
+
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-kernel@vger.kernel.org
+---
+ include/linux/cpu.h | 2 +-
+ kernel/cpu.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -109,7 +109,7 @@ void notify_cpu_starting(unsigned int cp
+ extern void cpu_maps_update_begin(void);
+ extern void cpu_maps_update_done(void);
+ int bringup_hibernate_cpu(unsigned int sleep_cpu);
+-void bringup_nonboot_cpus(unsigned int setup_max_cpus);
++void bringup_nonboot_cpus(unsigned int max_cpus);
+
+ #else /* CONFIG_SMP */
+ #define cpuhp_tasks_frozen 0
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -1905,17 +1905,17 @@ static bool __init cpuhp_bringup_cpus_pa
+ static inline bool cpuhp_bringup_cpus_parallel(unsigned int ncpus) { return false; }
+ #endif /* CONFIG_HOTPLUG_PARALLEL */
+
+-void __init bringup_nonboot_cpus(unsigned int setup_max_cpus)
++void __init bringup_nonboot_cpus(unsigned int max_cpus)
+ {
+- if (!setup_max_cpus)
++ if (!max_cpus)
+ return;
+
+ /* Try parallel bringup optimization if enabled */
+- if (cpuhp_bringup_cpus_parallel(setup_max_cpus))
++ if (cpuhp_bringup_cpus_parallel(max_cpus))
+ return;
+
+ /* Full per CPU serialized bringup */
+- cpuhp_bringup_mask(cpu_present_mask, setup_max_cpus, CPUHP_ONLINE);
++ cpuhp_bringup_mask(cpu_present_mask, max_cpus, CPUHP_ONLINE);
+ }
+
+ #ifdef CONFIG_PM_SLEEP_SMP
diff --git a/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch b/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch
index 99a6bfe638..6d3c7d04fe 100644
--- a/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch
+++ b/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch
@@ -134,7 +134,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
};
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
-@@ -392,7 +392,7 @@ static void cps_smp_finish(void)
+@@ -395,7 +395,7 @@ static void cps_smp_finish(void)
local_irq_enable();
}
@@ -143,7 +143,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
enum cpu_death {
CPU_DEATH_HALT,
-@@ -429,7 +429,7 @@ static void cps_shutdown_this_cpu(enum c
+@@ -432,7 +432,7 @@ static void cps_shutdown_this_cpu(enum c
}
}
@@ -152,7 +152,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
static void cps_kexec_nonboot_cpu(void)
{
-@@ -439,9 +439,9 @@ static void cps_kexec_nonboot_cpu(void)
+@@ -442,9 +442,9 @@ static void cps_kexec_nonboot_cpu(void)
cps_shutdown_this_cpu(CPU_DEATH_POWER);
}
@@ -164,7 +164,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
#ifdef CONFIG_HOTPLUG_CPU
-@@ -610,7 +610,7 @@ static const struct plat_smp_ops cps_smp
+@@ -613,7 +613,7 @@ static const struct plat_smp_ops cps_smp
.cpu_die = cps_cpu_die,
.cleanup_dead_cpu = cps_cleanup_dead_cpu,
#endif
@@ -175,8 +175,8 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
};
--- a/arch/mips/loongson64/reset.c
+++ b/arch/mips/loongson64/reset.c
-@@ -53,7 +53,7 @@ static void loongson_halt(void)
- }
+@@ -39,7 +39,7 @@ static int firmware_poweroff(struct sys_
+ return NOTIFY_DONE;
}
-#ifdef CONFIG_KEXEC
@@ -184,9 +184,9 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
/* 0X80000000~0X80200000 is safe */
#define MAX_ARGS 64
-@@ -158,7 +158,7 @@ static int __init mips_reboot_setup(void
- _machine_halt = loongson_halt;
- pm_power_off = loongson_poweroff;
+@@ -152,7 +152,7 @@ static int __init mips_reboot_setup(void
+ firmware_poweroff, NULL);
+ }
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC_CORE
@@ -195,7 +195,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
return -ENOMEM;
--- a/arch/mips/loongson64/smp.c
+++ b/arch/mips/loongson64/smp.c
-@@ -864,7 +864,7 @@ const struct plat_smp_ops loongson3_smp_
+@@ -883,7 +883,7 @@ const struct plat_smp_ops loongson3_smp_
.cpu_disable = loongson3_cpu_disable,
.cpu_die = loongson3_cpu_die,
#endif
diff --git a/target/linux/bmips/patches-6.6/020-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch b/target/linux/generic/backport-6.6/320-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch
index 21eaa3d6cb..21eaa3d6cb 100644
--- a/target/linux/bmips/patches-6.6/020-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch
+++ b/target/linux/generic/backport-6.6/320-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch
diff --git a/target/linux/bmips/patches-6.6/021-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch b/target/linux/generic/backport-6.6/321-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch
index 10a710a31d..10a710a31d 100644
--- a/target/linux/bmips/patches-6.6/021-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch
+++ b/target/linux/generic/backport-6.6/321-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch
diff --git a/target/linux/bmips/patches-6.6/022-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch b/target/linux/generic/backport-6.6/322-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch
index 2af45df259..2af45df259 100644
--- a/target/linux/bmips/patches-6.6/022-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch
+++ b/target/linux/generic/backport-6.6/322-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch
diff --git a/target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch b/target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch
new file mode 100644
index 0000000000..9a40ea4b90
--- /dev/null
+++ b/target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch
@@ -0,0 +1,30 @@
+From 6c06c88fa838fcc1b7e5380facd086f57fd9d1c4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Sun, 4 Feb 2024 15:16:46 +0100
+Subject: [PATCH] net: mdio: add 2.5g and 5g related PMA speed constants
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add constants indicating 2.5g and 5g ability in the MMD PMA speed
+register.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/98e15038-d96c-442f-93e4-410100d27866@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/uapi/linux/mdio.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/uapi/linux/mdio.h
++++ b/include/uapi/linux/mdio.h
+@@ -138,6 +138,8 @@
+ #define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */
+ #define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
+ #define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
++#define MDIO_PMA_SPEED_2_5G 0x2000 /* 2.5G capable */
++#define MDIO_PMA_SPEED_5G 0x4000 /* 5G capable */
+ #define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
+ #define MDIO_PCS_SPEED_2_5G 0x0040 /* 2.5G capable */
+ #define MDIO_PCS_SPEED_5G 0x0080 /* 5G capable */
diff --git a/target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch b/target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch
new file mode 100644
index 0000000000..4a71d1203a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch
@@ -0,0 +1,94 @@
+From: Jakub Sitnicki <jakub@cloudflare.com>
+Date: Wed, 26 Jun 2024 19:51:26 +0200
+Subject: [PATCH] udp: Allow GSO transmit from devices with no checksum offload
+
+Today sending a UDP GSO packet from a TUN device results in an EIO error:
+
+ import fcntl, os, struct
+ from socket import *
+
+ TUNSETIFF = 0x400454CA
+ IFF_TUN = 0x0001
+ IFF_NO_PI = 0x1000
+ UDP_SEGMENT = 103
+
+ tun_fd = os.open("/dev/net/tun", os.O_RDWR)
+ ifr = struct.pack("16sH", b"tun0", IFF_TUN | IFF_NO_PI)
+ fcntl.ioctl(tun_fd, TUNSETIFF, ifr)
+
+ os.system("ip addr add 192.0.2.1/24 dev tun0")
+ os.system("ip link set dev tun0 up")
+
+ s = socket(AF_INET, SOCK_DGRAM)
+ s.setsockopt(SOL_UDP, UDP_SEGMENT, 1200)
+ s.sendto(b"x" * 3000, ("192.0.2.2", 9)) # EIO
+
+This is due to a check in the udp stack if the egress device offers
+checksum offload. While TUN/TAP devices, by default, don't advertise this
+capability because it requires support from the TUN/TAP reader.
+
+However, the GSO stack has a software fallback for checksum calculation,
+which we can use. This way we don't force UDP_SEGMENT users to handle the
+EIO error and implement a segmentation fallback.
+
+Lift the restriction so that UDP_SEGMENT can be used with any egress
+device. We also need to adjust the UDP GSO code to match the GSO stack
+expectation about ip_summed field, as set in commit 8d63bee643f1 ("net:
+avoid skb_warn_bad_offload false positives on UFO"). Otherwise we will hit
+the bad offload check.
+
+Users should, however, expect a potential performance impact when
+batch-sending packets with UDP_SEGMENT without checksum offload on the
+egress device. In such case the packet payload is read twice: first during
+the sendmsg syscall when copying data from user memory, and then in the GSO
+stack for checksum computation. This double memory read can be less
+efficient than a regular sendmsg where the checksum is calculated during
+the initial data copy from user memory.
+
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20240626-linux-udpgso-v2-1-422dfcbd6b48@cloudflare.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -942,8 +942,7 @@ static int udp_send_skb(struct sk_buff *
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+- if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite ||
+- dst_xfrm(skb_dst(skb))) {
++ if (is_udplite || dst_xfrm(skb_dst(skb))) {
+ kfree_skb(skb);
+ return -EIO;
+ }
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -362,6 +362,14 @@ struct sk_buff *__udp_gso_segment(struct
+ else
+ uh->check = gso_make_checksum(seg, ~check) ? : CSUM_MANGLED_0;
+
++ /* On the TX path, CHECKSUM_NONE and CHECKSUM_UNNECESSARY have the same
++ * meaning. However, check for bad offloads in the GSO stack expects the
++ * latter, if the checksum was calculated in software. To vouch for the
++ * segment skbs we actually need to set it on the gso_skb.
++ */
++ if (gso_skb->ip_summed == CHECKSUM_NONE)
++ gso_skb->ip_summed = CHECKSUM_UNNECESSARY;
++
+ /* update refcount for the packet */
+ if (copy_dtor) {
+ int delta = sum_truesize - gso_skb->truesize;
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1261,8 +1261,7 @@ static int udp_v6_send_skb(struct sk_buf
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+- if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite ||
+- dst_xfrm(skb_dst(skb))) {
++ if (is_udplite || dst_xfrm(skb_dst(skb))) {
+ kfree_skb(skb);
+ return -EIO;
+ }
diff --git a/target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch b/target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch
new file mode 100644
index 0000000000..8eecb06304
--- /dev/null
+++ b/target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch
@@ -0,0 +1,69 @@
+From: Jakub Sitnicki <jakub@cloudflare.com>
+Date: Thu, 8 Aug 2024 11:56:21 +0200
+Subject: [PATCH] net: Make USO depend on CSUM offload
+
+UDP segmentation offload inherently depends on checksum offload. It should
+not be possible to disable checksum offload while leaving USO enabled.
+Enforce this dependency in code.
+
+There is a single tx-udp-segmentation feature flag to indicate support for
+both IPv4/6, hence the devices wishing to support USO must offer checksum
+offload for both IP versions.
+
+Fixes: 10154dbded6d ("udp: Allow GSO transmit from devices with no checksum offload")
+Suggested-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20240808-udp-gso-egress-from-tunnel-v4-1-f5c5b4149ab9@cloudflare.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -9751,6 +9751,15 @@ static void netdev_sync_lower_features(s
+ }
+ }
+
++static bool netdev_has_ip_or_hw_csum(netdev_features_t features)
++{
++ netdev_features_t ip_csum_mask = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
++ bool ip_csum = (features & ip_csum_mask) == ip_csum_mask;
++ bool hw_csum = features & NETIF_F_HW_CSUM;
++
++ return ip_csum || hw_csum;
++}
++
+ static netdev_features_t netdev_fix_features(struct net_device *dev,
+ netdev_features_t features)
+ {
+@@ -9832,15 +9841,9 @@ static netdev_features_t netdev_fix_feat
+ features &= ~NETIF_F_LRO;
+ }
+
+- if (features & NETIF_F_HW_TLS_TX) {
+- bool ip_csum = (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) ==
+- (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+- bool hw_csum = features & NETIF_F_HW_CSUM;
+-
+- if (!ip_csum && !hw_csum) {
+- netdev_dbg(dev, "Dropping TLS TX HW offload feature since no CSUM feature.\n");
+- features &= ~NETIF_F_HW_TLS_TX;
+- }
++ if ((features & NETIF_F_HW_TLS_TX) && !netdev_has_ip_or_hw_csum(features)) {
++ netdev_dbg(dev, "Dropping TLS TX HW offload feature since no CSUM feature.\n");
++ features &= ~NETIF_F_HW_TLS_TX;
+ }
+
+ if ((features & NETIF_F_HW_TLS_RX) && !(features & NETIF_F_RXCSUM)) {
+@@ -9848,6 +9851,11 @@ static netdev_features_t netdev_fix_feat
+ features &= ~NETIF_F_HW_TLS_RX;
+ }
+
++ if ((features & NETIF_F_GSO_UDP_L4) && !netdev_has_ip_or_hw_csum(features)) {
++ netdev_dbg(dev, "Dropping USO feature since no CSUM feature.\n");
++ features &= ~NETIF_F_GSO_UDP_L4;
++ }
++
+ return features;
+ }
+
diff --git a/target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch b/target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch
new file mode 100644
index 0000000000..e8eceb880c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch
@@ -0,0 +1,86 @@
+From: Jakub Sitnicki <jakub@cloudflare.com>
+Date: Thu, 8 Aug 2024 11:56:22 +0200
+Subject: [PATCH] udp: Fall back to software USO if IPv6 extension headers are
+ present
+
+In commit 10154dbded6d ("udp: Allow GSO transmit from devices with no
+checksum offload") we have intentionally allowed UDP GSO packets marked
+CHECKSUM_NONE to pass to the GSO stack, so that they can be segmented and
+checksummed by a software fallback when the egress device lacks these
+features.
+
+What was not taken into consideration is that a CHECKSUM_NONE skb can be
+handed over to the GSO stack also when the egress device advertises the
+tx-udp-segmentation / NETIF_F_GSO_UDP_L4 feature.
+
+This will happen when there are IPv6 extension headers present, which we
+check for in __ip6_append_data(). Syzbot has discovered this scenario,
+producing a warning as below:
+
+ ip6tnl0: caps=(0x00000006401d7869, 0x00000006401d7869)
+ WARNING: CPU: 0 PID: 5112 at net/core/dev.c:3293 skb_warn_bad_offload+0x166/0x1a0 net/core/dev.c:3291
+ Modules linked in:
+ CPU: 0 PID: 5112 Comm: syz-executor391 Not tainted 6.10.0-rc7-syzkaller-01603-g80ab5445da62 #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/07/2024
+ RIP: 0010:skb_warn_bad_offload+0x166/0x1a0 net/core/dev.c:3291
+ [...]
+ Call Trace:
+ <TASK>
+ __skb_gso_segment+0x3be/0x4c0 net/core/gso.c:127
+ skb_gso_segment include/net/gso.h:83 [inline]
+ validate_xmit_skb+0x585/0x1120 net/core/dev.c:3661
+ __dev_queue_xmit+0x17a4/0x3e90 net/core/dev.c:4415
+ neigh_output include/net/neighbour.h:542 [inline]
+ ip6_finish_output2+0xffa/0x1680 net/ipv6/ip6_output.c:137
+ ip6_finish_output+0x41e/0x810 net/ipv6/ip6_output.c:222
+ ip6_send_skb+0x112/0x230 net/ipv6/ip6_output.c:1958
+ udp_v6_send_skb+0xbf5/0x1870 net/ipv6/udp.c:1292
+ udpv6_sendmsg+0x23b3/0x3270 net/ipv6/udp.c:1588
+ sock_sendmsg_nosec net/socket.c:730 [inline]
+ __sock_sendmsg+0xef/0x270 net/socket.c:745
+ ____sys_sendmsg+0x525/0x7d0 net/socket.c:2585
+ ___sys_sendmsg net/socket.c:2639 [inline]
+ __sys_sendmmsg+0x3b2/0x740 net/socket.c:2725
+ __do_sys_sendmmsg net/socket.c:2754 [inline]
+ __se_sys_sendmmsg net/socket.c:2751 [inline]
+ __x64_sys_sendmmsg+0xa0/0xb0 net/socket.c:2751
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ [...]
+ </TASK>
+
+We are hitting the bad offload warning because when an egress device is
+capable of handling segmentation offload requested by
+skb_shinfo(skb)->gso_type, the chain of gso_segment callbacks won't produce
+any segment skbs and return NULL. See the skb_gso_ok() branch in
+{__udp,tcp,sctp}_gso_segment helpers.
+
+To fix it, force a fallback to software USO when processing a packet with
+IPv6 extension headers, since we don't know if these can checksummed by
+all devices which offer USO.
+
+Fixes: 10154dbded6d ("udp: Allow GSO transmit from devices with no checksum offload")
+Reported-by: syzbot+e15b7e15b8a751a91d9a@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/000000000000e1609a061d5330ce@google.com/
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://patch.msgid.link/20240808-udp-gso-egress-from-tunnel-v4-2-f5c5b4149ab9@cloudflare.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -283,6 +283,12 @@ struct sk_buff *__udp_gso_segment(struct
+ !(skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)))
+ return ERR_PTR(-EINVAL);
+
++ /* We don't know if egress device can segment and checksum the packet
++ * when IPv6 extension headers are present. Fall back to software GSO.
++ */
++ if (gso_skb->ip_summed != CHECKSUM_PARTIAL)
++ features &= ~(NETIF_F_GSO_UDP_L4 | NETIF_F_CSUM_MASK);
++
+ if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) {
+ /* Packet is from an untrusted source, reset gso_segs. */
+ skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh),
diff --git a/target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch b/target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
deleted file mode 100644
index c99e1334d4..0000000000
--- a/target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Sep 2023 10:28:00 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: check update_wo_rx_stats in
- mtk_wed_update_rx_stats()
-
-Check if update_wo_rx_stats function pointer is properly set in
-mtk_wed_update_rx_stats routine before accessing it.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/b0d233386e059bccb59f18f69afb79a7806e5ded.1694507226.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -68,6 +68,9 @@ mtk_wed_update_rx_stats(struct mtk_wed_d
- struct mtk_wed_wo_rx_stats *stats;
- int i;
-
-+ if (!wed->wlan.update_wo_rx_stats)
-+ return;
-+
- if (count * sizeof(*stats) > skb->len - sizeof(u32))
- return;
-
diff --git a/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch b/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
index 6d1d9a4069..323bc14c3e 100644
--- a/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
+++ b/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
@@ -168,7 +168,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
else
ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-@@ -1840,7 +1840,7 @@ mtk_wed_setup_tc(struct mtk_wed_device *
+@@ -1842,7 +1842,7 @@ mtk_wed_setup_tc(struct mtk_wed_device *
{
struct mtk_wed_hw *hw = wed->hw;
@@ -177,7 +177,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return -EOPNOTSUPP;
switch (type) {
-@@ -1914,9 +1914,9 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1916,9 +1916,9 @@ void mtk_wed_add_hw(struct device_node *
hw->wdma = wdma;
hw->index = index;
hw->irq = irq;
diff --git a/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch b/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
index 3e750ec1d4..6e2f8b1920 100644
--- a/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
+++ b/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
@@ -142,7 +142,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1928,7 +1935,12 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1930,7 +1937,12 @@ void mtk_wed_add_hw(struct device_node *
hw->irq = irq;
hw->version = eth->soc->version;
@@ -156,7 +156,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
"mediatek,pcie-mirror");
hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
-@@ -1942,6 +1954,8 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1944,6 +1956,8 @@ void mtk_wed_add_hw(struct device_node *
regmap_write(hw->mirror, 0, 0);
regmap_write(hw->mirror, 4, 0);
}
diff --git a/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch b/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
index 5a271a5628..f565b7631f 100644
--- a/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
+++ b/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
@@ -759,7 +759,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
val = wed_r32(dev, MTK_WED_EXT_INT_STATUS);
wed_w32(dev, MTK_WED_EXT_INT_STATUS, val);
-@@ -1939,6 +2130,9 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1941,6 +2132,9 @@ void mtk_wed_add_hw(struct device_node *
case 2:
hw->soc = &mt7986_data;
break;
diff --git a/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch b/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
index f035f8fc06..20befcc620 100644
--- a/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
+++ b/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
@@ -364,7 +364,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
{
int i;
-@@ -2212,6 +2503,10 @@ void mtk_wed_add_hw(struct device_node *
+@@ -2214,6 +2505,10 @@ void mtk_wed_add_hw(struct device_node *
.detach = mtk_wed_detach,
.ppe_check = mtk_wed_ppe_check,
.setup_tc = mtk_wed_setup_tc,
diff --git a/target/linux/generic/backport-6.6/752-28-v6.10-net-ethernet-mediatek-Allow-gaps-in-MAC-allocation.patch b/target/linux/generic/backport-6.6/752-28-v6.10-net-ethernet-mediatek-Allow-gaps-in-MAC-allocation.patch
new file mode 100644
index 0000000000..b62586b992
--- /dev/null
+++ b/target/linux/generic/backport-6.6/752-28-v6.10-net-ethernet-mediatek-Allow-gaps-in-MAC-allocation.patch
@@ -0,0 +1,32 @@
+From 3b2aef99221d395ce37efa426d7b50e7dcd621d6 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 1 Jul 2024 20:28:14 +0100
+Subject: [PATCH] net: ethernet: mediatek: Allow gaps in MAC allocation
+
+Some devices with MediaTek SoCs don't use the first but only the second
+MAC in the chip. Especially with MT7981 which got a built-in 1GE PHY
+connected to the second MAC this is quite common.
+Make sure to reset and enable PSE also in those cases by skipping gaps
+using 'continue' instead of aborting the loop using 'break'.
+
+Fixes: dee4dd10c79a ("net: ethernet: mtk_eth_soc: ppe: add support for multiple PPEs")
+Suggested-by: Elad Yifee <eladwf@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://patch.msgid.link/379ae584cea112db60f4ada79c7e5ba4f3364a64.1719862038.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3396,7 +3396,7 @@ static int mtk_open(struct net_device *d
+
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
+ if (!eth->netdev[i])
+- break;
++ continue;
+
+ target_mac = netdev_priv(eth->netdev[i]);
+ if (!soc->offload_version) {
diff --git a/target/linux/generic/backport-6.6/752-29-v6.10-net-ethernet-mtk_ppe-Change-PPE-entries-number-to-16.patch b/target/linux/generic/backport-6.6/752-29-v6.10-net-ethernet-mtk_ppe-Change-PPE-entries-number-to-16.patch
new file mode 100644
index 0000000000..c6b332f370
--- /dev/null
+++ b/target/linux/generic/backport-6.6/752-29-v6.10-net-ethernet-mtk_ppe-Change-PPE-entries-number-to-16.patch
@@ -0,0 +1,29 @@
+From ca18300e00d584d5693127eb60c108b84883b8ac Mon Sep 17 00:00:00 2001
+From: Shengyu Qu <wiagn233@outlook.com>
+Date: Fri, 5 Jul 2024 01:26:26 +0800
+Subject: [PATCH] net: ethernet: mtk_ppe: Change PPE entries number to 16K
+
+MT7981,7986 and 7988 all supports 32768 PPE entries, and MT7621/MT7620
+supports 16384 PPE entries, but only set to 8192 entries in driver. So
+incrase max entries to 16384 instead.
+
+Signed-off-by: Elad Yifee <eladwf@gmail.com>
+Signed-off-by: Shengyu Qu <wiagn233@outlook.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/TY3P286MB261103F937DE4EEB0F88437D98DE2@TY3P286MB2611.JPNP286.PROD.OUTLOOK.COM
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -8,7 +8,7 @@
+ #include <linux/bitfield.h>
+ #include <linux/rhashtable.h>
+
+-#define MTK_PPE_ENTRIES_SHIFT 3
++#define MTK_PPE_ENTRIES_SHIFT 4
+ #define MTK_PPE_ENTRIES (1024 << MTK_PPE_ENTRIES_SHIFT)
+ #define MTK_PPE_HASH_MASK (MTK_PPE_ENTRIES - 1)
+ #define MTK_PPE_WAIT_TIMEOUT_US 1000000
diff --git a/target/linux/generic/backport-6.6/752-30-v6.10-net-ethernet-mtk_eth_soc-implement-.-get-set-_pausep.patch b/target/linux/generic/backport-6.6/752-30-v6.10-net-ethernet-mtk_eth_soc-implement-.-get-set-_pausep.patch
new file mode 100644
index 0000000000..09d7054965
--- /dev/null
+++ b/target/linux/generic/backport-6.6/752-30-v6.10-net-ethernet-mtk_eth_soc-implement-.-get-set-_pausep.patch
@@ -0,0 +1,55 @@
+From 064fbc4e9b5a6dbda7fe7b67dc7e9e95d31f8d75 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 4 Jul 2024 11:14:55 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: implement .{get,set}_pauseparam
+ ethtool ops
+
+Implement operations to get and set flow-control link parameters.
+Both is done by simply calling phylink_ethtool_{get,set}_pauseparam().
+Fix whitespace in mtk_ethtool_ops while at it.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Tested-by: Rui Salvaterra <rsalvaterra@gmail.com>
+Link: https://patch.msgid.link/e3ece47323444631d6cb479f32af0dfd6d145be0.1720088047.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4462,6 +4462,20 @@ static int mtk_set_rxnfc(struct net_devi
+ return ret;
+ }
+
++static void mtk_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ phylink_ethtool_get_pauseparam(mac->phylink, pause);
++}
++
++static int mtk_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ return phylink_ethtool_set_pauseparam(mac->phylink, pause);
++}
++
+ static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb,
+ struct net_device *sb_dev)
+ {
+@@ -4490,8 +4504,10 @@ static const struct ethtool_ops mtk_etht
+ .get_strings = mtk_get_strings,
+ .get_sset_count = mtk_get_sset_count,
+ .get_ethtool_stats = mtk_get_ethtool_stats,
++ .get_pauseparam = mtk_get_pauseparam,
++ .set_pauseparam = mtk_set_pauseparam,
+ .get_rxnfc = mtk_get_rxnfc,
+- .set_rxnfc = mtk_set_rxnfc,
++ .set_rxnfc = mtk_set_rxnfc,
+ };
+
+ static const struct net_device_ops mtk_netdev_ops = {
diff --git a/target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch b/target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
deleted file mode 100644
index 3345ebf6c6..0000000000
--- a/target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
+++ /dev/null
@@ -1,319 +0,0 @@
-From 18764b883e157e28126b54e7d4ba9dd487d5bf54 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 16 Dec 2023 20:58:10 +0100
-Subject: [PATCH] r8169: add support for LED's on RTL8168/RTL8101
-
-This adds support for the LED's on most chip versions. Excluded are
-the old non-PCIe versions and RTL8125. RTL8125 has a different LED
-register layout, support for it will follow later.
-
-LED's can be controlled from userspace using the netdev LED trigger.
-
-Tested on RTL8168h.
-
-Note: The driver can't know which LED's are actually physically
-wired. Therefore not every LED device may represent a physically
-available LED.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/Makefile | 3 +
- drivers/net/ethernet/realtek/r8169.h | 7 +
- drivers/net/ethernet/realtek/r8169_leds.c | 157 ++++++++++++++++++++++
- drivers/net/ethernet/realtek/r8169_main.c | 65 +++++++++
- 4 files changed, 232 insertions(+)
- create mode 100644 drivers/net/ethernet/realtek/r8169_leds.c
-
---- a/drivers/net/ethernet/realtek/Makefile
-+++ b/drivers/net/ethernet/realtek/Makefile
-@@ -7,4 +7,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
- obj-$(CONFIG_8139TOO) += 8139too.o
- obj-$(CONFIG_ATP) += atp.o
- r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
-+ifdef CONFIG_LEDS_TRIGGER_NETDEV
-+r8169-objs += r8169_leds.o
-+endif
- obj-$(CONFIG_R8169) += r8169.o
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -8,6 +8,7 @@
- * See MAINTAINERS file for support contact information.
- */
-
-+#include <linux/netdevice.h>
- #include <linux/types.h>
- #include <linux/phy.h>
-
-@@ -77,3 +78,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
- u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
- void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
- enum mac_version ver);
-+
-+void r8169_get_led_name(struct rtl8169_private *tp, int idx,
-+ char *buf, int buf_len);
-+int rtl8168_get_led_mode(struct rtl8169_private *tp);
-+int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
-+void rtl8168_init_leds(struct net_device *ndev);
---- /dev/null
-+++ b/drivers/net/ethernet/realtek/r8169_leds.c
-@@ -0,0 +1,157 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver.
-+ *
-+ * Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com>
-+ *
-+ * See MAINTAINERS file for support contact information.
-+ */
-+
-+#include <linux/leds.h>
-+#include <linux/netdevice.h>
-+#include <uapi/linux/uleds.h>
-+
-+#include "r8169.h"
-+
-+#define RTL8168_LED_CTRL_OPTION2 BIT(15)
-+#define RTL8168_LED_CTRL_ACT BIT(3)
-+#define RTL8168_LED_CTRL_LINK_1000 BIT(2)
-+#define RTL8168_LED_CTRL_LINK_100 BIT(1)
-+#define RTL8168_LED_CTRL_LINK_10 BIT(0)
-+
-+#define RTL8168_NUM_LEDS 3
-+
-+#define RTL8168_SUPPORTED_MODES \
-+ (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \
-+ BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \
-+ BIT(TRIGGER_NETDEV_TX))
-+
-+struct r8169_led_classdev {
-+ struct led_classdev led;
-+ struct net_device *ndev;
-+ int index;
-+};
-+
-+#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
-+
-+static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int shift = ldev->index * 4;
-+ bool rx, tx;
-+
-+ if (flags & ~RTL8168_SUPPORTED_MODES)
-+ goto nosupp;
-+
-+ rx = flags & BIT(TRIGGER_NETDEV_RX);
-+ tx = flags & BIT(TRIGGER_NETDEV_TX);
-+ if (rx != tx)
-+ goto nosupp;
-+
-+ return 0;
-+
-+nosupp:
-+ /* Switch LED off to indicate that mode isn't supported */
-+ rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
-+ return -EOPNOTSUPP;
-+}
-+
-+static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int shift = ldev->index * 4;
-+ u16 mode = 0;
-+
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
-+ mode |= RTL8168_LED_CTRL_LINK_10;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
-+ mode |= RTL8168_LED_CTRL_LINK_100;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
-+ mode |= RTL8168_LED_CTRL_LINK_1000;
-+ if (flags & BIT(TRIGGER_NETDEV_TX))
-+ mode |= RTL8168_LED_CTRL_ACT;
-+
-+ return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift);
-+}
-+
-+static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev,
-+ unsigned long *flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int shift = ldev->index * 4;
-+ int mode;
-+
-+ mode = rtl8168_get_led_mode(tp);
-+ if (mode < 0)
-+ return mode;
-+
-+ if (mode & RTL8168_LED_CTRL_OPTION2) {
-+ rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0);
-+ netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n");
-+ }
-+
-+ mode = (mode >> shift) & 0x000f;
-+
-+ if (mode & RTL8168_LED_CTRL_ACT)
-+ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
-+
-+ if (mode & RTL8168_LED_CTRL_LINK_10)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
-+ if (mode & RTL8168_LED_CTRL_LINK_100)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
-+ if (mode & RTL8168_LED_CTRL_LINK_1000)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
-+
-+ return 0;
-+}
-+
-+static struct device *
-+ r8169_led_hw_control_get_device(struct led_classdev *led_cdev)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+
-+ return &ldev->ndev->dev;
-+}
-+
-+static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
-+ struct net_device *ndev, int index)
-+{
-+ struct rtl8169_private *tp = netdev_priv(ndev);
-+ struct led_classdev *led_cdev = &ldev->led;
-+ char led_name[LED_MAX_NAME_SIZE];
-+
-+ ldev->ndev = ndev;
-+ ldev->index = index;
-+
-+ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
-+ led_cdev->name = led_name;
-+ led_cdev->default_trigger = "netdev";
-+ led_cdev->hw_control_trigger = "netdev";
-+ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
-+ led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
-+ led_cdev->hw_control_set = rtl8168_led_hw_control_set;
-+ led_cdev->hw_control_get = rtl8168_led_hw_control_get;
-+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-+
-+ /* ignore errors */
-+ devm_led_classdev_register(&ndev->dev, led_cdev);
-+}
-+
-+void rtl8168_init_leds(struct net_device *ndev)
-+{
-+ /* bind resource mgmt to netdev */
-+ struct device *dev = &ndev->dev;
-+ struct r8169_led_classdev *leds;
-+ int i;
-+
-+ leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ if (!leds)
-+ return;
-+
-+ for (i = 0; i < RTL8168_NUM_LEDS; i++)
-+ rtl8168_setup_ldev(leds + i, ndev, i);
-+}
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -289,6 +289,7 @@ enum rtl8168_8101_registers {
- };
-
- enum rtl8168_registers {
-+ LED_CTRL = 0x18,
- LED_FREQ = 0x1a,
- EEE_LED = 0x1b,
- ERIDR = 0x70,
-@@ -620,6 +621,7 @@ struct rtl8169_private {
-
- raw_spinlock_t config25_lock;
- raw_spinlock_t mac_ocp_lock;
-+ struct mutex led_lock; /* serialize LED ctrl RMW access */
-
- raw_spinlock_t cfg9346_usage_lock;
- int cfg9346_usage_count;
-@@ -792,6 +794,62 @@ static const struct rtl_cond name = {
- \
- static bool name ## _check(struct rtl8169_private *tp)
-
-+int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val)
-+{
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ mutex_lock(&tp->led_lock);
-+ RTL_W16(tp, LED_CTRL, (RTL_R16(tp, LED_CTRL) & ~mask) | val);
-+ mutex_unlock(&tp->led_lock);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return 0;
-+}
-+
-+int rtl8168_get_led_mode(struct rtl8169_private *tp)
-+{
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = RTL_R16(tp, LED_CTRL);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return ret;
-+}
-+
-+void r8169_get_led_name(struct rtl8169_private *tp, int idx,
-+ char *buf, int buf_len)
-+{
-+ struct pci_dev *pdev = tp->pci_dev;
-+ char pdom[8], pfun[8];
-+ int domain;
-+
-+ domain = pci_domain_nr(pdev->bus);
-+ if (domain)
-+ snprintf(pdom, sizeof(pdom), "P%d", domain);
-+ else
-+ pdom[0] = '\0';
-+
-+ if (pdev->multifunction)
-+ snprintf(pfun, sizeof(pfun), "f%d", PCI_FUNC(pdev->devfn));
-+ else
-+ pfun[0] = '\0';
-+
-+ snprintf(buf, buf_len, "en%sp%ds%d%s-%d::lan", pdom, pdev->bus->number,
-+ PCI_SLOT(pdev->devfn), pfun, idx);
-+}
-+
- static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
- {
- /* based on RTL8168FP_OOBMAC_BASE in vendor driver */
-@@ -5258,6 +5316,7 @@ static int rtl_init_one(struct pci_dev *
- raw_spin_lock_init(&tp->cfg9346_usage_lock);
- raw_spin_lock_init(&tp->config25_lock);
- raw_spin_lock_init(&tp->mac_ocp_lock);
-+ mutex_init(&tp->led_lock);
-
- dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
- struct pcpu_sw_netstats);
-@@ -5414,6 +5473,12 @@ static int rtl_init_one(struct pci_dev *
- if (rc)
- return rc;
-
-+#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
-+ if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
-+ tp->mac_version < RTL_GIGA_MAC_VER_61)
-+ rtl8168_init_leds(dev);
-+#endif
-+
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
- rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
-
diff --git a/target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch b/target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch
new file mode 100644
index 0000000000..9a17fe4f78
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch
@@ -0,0 +1,173 @@
+From 055dd7511f675d26fa283b35bb3dadfc7f77ed97 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 13 Nov 2023 20:13:26 +0100
+Subject: [PATCH] r8169: improve RTL8411b phy-down fixup
+
+Mirsad proposed a patch to reduce the number of spinlock lock/unlock
+operations and the function code size. This can be further improved
+because the function sets a consecutive register block.
+
+Suggested-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 139 +++++-----------------
+ 1 file changed, 28 insertions(+), 111 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -3129,6 +3129,33 @@ static void rtl_hw_start_8168g_2(struct
+ rtl_ephy_init(tp, e_info_8168g_2);
+ }
+
++static void rtl8411b_fix_phy_down(struct rtl8169_private *tp)
++{
++ static const u16 fix_data[] = {
++/* 0xf800 */ 0xe008, 0xe00a, 0xe00c, 0xe00e, 0xe027, 0xe04f, 0xe05e, 0xe065,
++/* 0xf810 */ 0xc602, 0xbe00, 0x0000, 0xc502, 0xbd00, 0x074c, 0xc302, 0xbb00,
++/* 0xf820 */ 0x080a, 0x6420, 0x48c2, 0x8c20, 0xc516, 0x64a4, 0x49c0, 0xf009,
++/* 0xf830 */ 0x74a2, 0x8ca5, 0x74a0, 0xc50e, 0x9ca2, 0x1c11, 0x9ca0, 0xe006,
++/* 0xf840 */ 0x74f8, 0x48c4, 0x8cf8, 0xc404, 0xbc00, 0xc403, 0xbc00, 0x0bf2,
++/* 0xf850 */ 0x0c0a, 0xe434, 0xd3c0, 0x49d9, 0xf01f, 0xc526, 0x64a5, 0x1400,
++/* 0xf860 */ 0xf007, 0x0c01, 0x8ca5, 0x1c15, 0xc51b, 0x9ca0, 0xe013, 0xc519,
++/* 0xf870 */ 0x74a0, 0x48c4, 0x8ca0, 0xc516, 0x74a4, 0x48c8, 0x48ca, 0x9ca4,
++/* 0xf880 */ 0xc512, 0x1b00, 0x9ba0, 0x1b1c, 0x483f, 0x9ba2, 0x1b04, 0xc508,
++/* 0xf890 */ 0x9ba0, 0xc505, 0xbd00, 0xc502, 0xbd00, 0x0300, 0x051e, 0xe434,
++/* 0xf8a0 */ 0xe018, 0xe092, 0xde20, 0xd3c0, 0xc50f, 0x76a4, 0x49e3, 0xf007,
++/* 0xf8b0 */ 0x49c0, 0xf103, 0xc607, 0xbe00, 0xc606, 0xbe00, 0xc602, 0xbe00,
++/* 0xf8c0 */ 0x0c4c, 0x0c28, 0x0c2c, 0xdc00, 0xc707, 0x1d00, 0x8de2, 0x48c1,
++/* 0xf8d0 */ 0xc502, 0xbd00, 0x00aa, 0xe0c0, 0xc502, 0xbd00, 0x0132
++ };
++ unsigned long flags;
++ int i;
++
++ raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags);
++ for (i = 0; i < ARRAY_SIZE(fix_data); i++)
++ __r8168_mac_ocp_write(tp, 0xf800 + 2 * i, fix_data[i]);
++ raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
++}
++
+ static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
+ {
+ static const struct ephy_info e_info_8411_2[] = {
+@@ -3162,117 +3189,7 @@ static void rtl_hw_start_8411_2(struct r
+ mdelay(3);
+ r8168_mac_ocp_write(tp, 0xFC26, 0x0000);
+
+- r8168_mac_ocp_write(tp, 0xF800, 0xE008);
+- r8168_mac_ocp_write(tp, 0xF802, 0xE00A);
+- r8168_mac_ocp_write(tp, 0xF804, 0xE00C);
+- r8168_mac_ocp_write(tp, 0xF806, 0xE00E);
+- r8168_mac_ocp_write(tp, 0xF808, 0xE027);
+- r8168_mac_ocp_write(tp, 0xF80A, 0xE04F);
+- r8168_mac_ocp_write(tp, 0xF80C, 0xE05E);
+- r8168_mac_ocp_write(tp, 0xF80E, 0xE065);
+- r8168_mac_ocp_write(tp, 0xF810, 0xC602);
+- r8168_mac_ocp_write(tp, 0xF812, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF814, 0x0000);
+- r8168_mac_ocp_write(tp, 0xF816, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF818, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF81A, 0x074C);
+- r8168_mac_ocp_write(tp, 0xF81C, 0xC302);
+- r8168_mac_ocp_write(tp, 0xF81E, 0xBB00);
+- r8168_mac_ocp_write(tp, 0xF820, 0x080A);
+- r8168_mac_ocp_write(tp, 0xF822, 0x6420);
+- r8168_mac_ocp_write(tp, 0xF824, 0x48C2);
+- r8168_mac_ocp_write(tp, 0xF826, 0x8C20);
+- r8168_mac_ocp_write(tp, 0xF828, 0xC516);
+- r8168_mac_ocp_write(tp, 0xF82A, 0x64A4);
+- r8168_mac_ocp_write(tp, 0xF82C, 0x49C0);
+- r8168_mac_ocp_write(tp, 0xF82E, 0xF009);
+- r8168_mac_ocp_write(tp, 0xF830, 0x74A2);
+- r8168_mac_ocp_write(tp, 0xF832, 0x8CA5);
+- r8168_mac_ocp_write(tp, 0xF834, 0x74A0);
+- r8168_mac_ocp_write(tp, 0xF836, 0xC50E);
+- r8168_mac_ocp_write(tp, 0xF838, 0x9CA2);
+- r8168_mac_ocp_write(tp, 0xF83A, 0x1C11);
+- r8168_mac_ocp_write(tp, 0xF83C, 0x9CA0);
+- r8168_mac_ocp_write(tp, 0xF83E, 0xE006);
+- r8168_mac_ocp_write(tp, 0xF840, 0x74F8);
+- r8168_mac_ocp_write(tp, 0xF842, 0x48C4);
+- r8168_mac_ocp_write(tp, 0xF844, 0x8CF8);
+- r8168_mac_ocp_write(tp, 0xF846, 0xC404);
+- r8168_mac_ocp_write(tp, 0xF848, 0xBC00);
+- r8168_mac_ocp_write(tp, 0xF84A, 0xC403);
+- r8168_mac_ocp_write(tp, 0xF84C, 0xBC00);
+- r8168_mac_ocp_write(tp, 0xF84E, 0x0BF2);
+- r8168_mac_ocp_write(tp, 0xF850, 0x0C0A);
+- r8168_mac_ocp_write(tp, 0xF852, 0xE434);
+- r8168_mac_ocp_write(tp, 0xF854, 0xD3C0);
+- r8168_mac_ocp_write(tp, 0xF856, 0x49D9);
+- r8168_mac_ocp_write(tp, 0xF858, 0xF01F);
+- r8168_mac_ocp_write(tp, 0xF85A, 0xC526);
+- r8168_mac_ocp_write(tp, 0xF85C, 0x64A5);
+- r8168_mac_ocp_write(tp, 0xF85E, 0x1400);
+- r8168_mac_ocp_write(tp, 0xF860, 0xF007);
+- r8168_mac_ocp_write(tp, 0xF862, 0x0C01);
+- r8168_mac_ocp_write(tp, 0xF864, 0x8CA5);
+- r8168_mac_ocp_write(tp, 0xF866, 0x1C15);
+- r8168_mac_ocp_write(tp, 0xF868, 0xC51B);
+- r8168_mac_ocp_write(tp, 0xF86A, 0x9CA0);
+- r8168_mac_ocp_write(tp, 0xF86C, 0xE013);
+- r8168_mac_ocp_write(tp, 0xF86E, 0xC519);
+- r8168_mac_ocp_write(tp, 0xF870, 0x74A0);
+- r8168_mac_ocp_write(tp, 0xF872, 0x48C4);
+- r8168_mac_ocp_write(tp, 0xF874, 0x8CA0);
+- r8168_mac_ocp_write(tp, 0xF876, 0xC516);
+- r8168_mac_ocp_write(tp, 0xF878, 0x74A4);
+- r8168_mac_ocp_write(tp, 0xF87A, 0x48C8);
+- r8168_mac_ocp_write(tp, 0xF87C, 0x48CA);
+- r8168_mac_ocp_write(tp, 0xF87E, 0x9CA4);
+- r8168_mac_ocp_write(tp, 0xF880, 0xC512);
+- r8168_mac_ocp_write(tp, 0xF882, 0x1B00);
+- r8168_mac_ocp_write(tp, 0xF884, 0x9BA0);
+- r8168_mac_ocp_write(tp, 0xF886, 0x1B1C);
+- r8168_mac_ocp_write(tp, 0xF888, 0x483F);
+- r8168_mac_ocp_write(tp, 0xF88A, 0x9BA2);
+- r8168_mac_ocp_write(tp, 0xF88C, 0x1B04);
+- r8168_mac_ocp_write(tp, 0xF88E, 0xC508);
+- r8168_mac_ocp_write(tp, 0xF890, 0x9BA0);
+- r8168_mac_ocp_write(tp, 0xF892, 0xC505);
+- r8168_mac_ocp_write(tp, 0xF894, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF896, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF898, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF89A, 0x0300);
+- r8168_mac_ocp_write(tp, 0xF89C, 0x051E);
+- r8168_mac_ocp_write(tp, 0xF89E, 0xE434);
+- r8168_mac_ocp_write(tp, 0xF8A0, 0xE018);
+- r8168_mac_ocp_write(tp, 0xF8A2, 0xE092);
+- r8168_mac_ocp_write(tp, 0xF8A4, 0xDE20);
+- r8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0);
+- r8168_mac_ocp_write(tp, 0xF8A8, 0xC50F);
+- r8168_mac_ocp_write(tp, 0xF8AA, 0x76A4);
+- r8168_mac_ocp_write(tp, 0xF8AC, 0x49E3);
+- r8168_mac_ocp_write(tp, 0xF8AE, 0xF007);
+- r8168_mac_ocp_write(tp, 0xF8B0, 0x49C0);
+- r8168_mac_ocp_write(tp, 0xF8B2, 0xF103);
+- r8168_mac_ocp_write(tp, 0xF8B4, 0xC607);
+- r8168_mac_ocp_write(tp, 0xF8B6, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF8B8, 0xC606);
+- r8168_mac_ocp_write(tp, 0xF8BA, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF8BC, 0xC602);
+- r8168_mac_ocp_write(tp, 0xF8BE, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C);
+- r8168_mac_ocp_write(tp, 0xF8C2, 0x0C28);
+- r8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C);
+- r8168_mac_ocp_write(tp, 0xF8C6, 0xDC00);
+- r8168_mac_ocp_write(tp, 0xF8C8, 0xC707);
+- r8168_mac_ocp_write(tp, 0xF8CA, 0x1D00);
+- r8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2);
+- r8168_mac_ocp_write(tp, 0xF8CE, 0x48C1);
+- r8168_mac_ocp_write(tp, 0xF8D0, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF8D2, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF8D4, 0x00AA);
+- r8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0);
+- r8168_mac_ocp_write(tp, 0xF8D8, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF8DA, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF8DC, 0x0132);
++ rtl8411b_fix_phy_down(tp);
+
+ r8168_mac_ocp_write(tp, 0xFC26, 0x8000);
+
diff --git a/target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch b/target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
deleted file mode 100644
index cea88c042a..0000000000
--- a/target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From a2634a5ffcafc31c343c6153ae487eb184c433a6 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 3 Jan 2024 16:52:04 +0100
-Subject: [PATCH] r8169: fix building with CONFIG_LEDS_CLASS=m
-
-When r8169 is built-in but LED support is a loadable module, the new
-code to drive the LED causes a link failure:
-
-ld: drivers/net/ethernet/realtek/r8169_leds.o: in function `rtl8168_init_leds':
-r8169_leds.c:(.text+0x36c): undefined reference to `devm_led_classdev_register_ext'
-
-LED support is an optional feature, so fix this issue by adding a Kconfig
-symbol R8169_LEDS that is guaranteed to be false if r8169 is built-in
-and LED core support is a module. As a positive side effect of this change
-r8169_leds.o no longer is built under this configuration.
-
-Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
-Reported-by: kernel test robot <lkp@intel.com>
-Closes: https://lore.kernel.org/oe-kbuild-all/202312281159.9TPeXbNd-lkp@intel.com/
-Suggested-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Tested-by: Simon Horman <horms@kernel.org> # build-tested
-Tested-by: Arnd Bergmann <arnd@arndb.de>
-Link: https://lore.kernel.org/r/d055aeb5-fe5c-4ccf-987f-5af93a17537b@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/Kconfig | 7 +++++++
- drivers/net/ethernet/realtek/Makefile | 6 ++----
- drivers/net/ethernet/realtek/r8169_main.c | 5 ++---
- 3 files changed, 11 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/realtek/Kconfig
-+++ b/drivers/net/ethernet/realtek/Kconfig
-@@ -113,4 +113,11 @@ config R8169
- To compile this driver as a module, choose M here: the module
- will be called r8169. This is recommended.
-
-+config R8169_LEDS
-+ def_bool R8169 && LEDS_TRIGGER_NETDEV
-+ depends on !(R8169=y && LEDS_CLASS=m)
-+ help
-+ Optional support for controlling the NIC LED's with the netdev
-+ LED trigger.
-+
- endif # NET_VENDOR_REALTEK
---- a/drivers/net/ethernet/realtek/Makefile
-+++ b/drivers/net/ethernet/realtek/Makefile
-@@ -6,8 +6,6 @@
- obj-$(CONFIG_8139CP) += 8139cp.o
- obj-$(CONFIG_8139TOO) += 8139too.o
- obj-$(CONFIG_ATP) += atp.o
--r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
--ifdef CONFIG_LEDS_TRIGGER_NETDEV
--r8169-objs += r8169_leds.o
--endif
-+r8169-y += r8169_main.o r8169_firmware.o r8169_phy_config.o
-+r8169-$(CONFIG_R8169_LEDS) += r8169_leds.o
- obj-$(CONFIG_R8169) += r8169.o
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5473,11 +5473,10 @@ static int rtl_init_one(struct pci_dev *
- if (rc)
- return rc;
-
--#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
-- if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
-+ if (IS_ENABLED(CONFIG_R8169_LEDS) &&
-+ tp->mac_version > RTL_GIGA_MAC_VER_06 &&
- tp->mac_version < RTL_GIGA_MAC_VER_61)
- rtl8168_init_leds(dev);
--#endif
-
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
- rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch b/target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch
new file mode 100644
index 0000000000..de10d30e83
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch
@@ -0,0 +1,27 @@
+From 3a767b482cacd9bfeac786837fcac419af315995 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Thu, 23 Nov 2023 10:53:26 +0100
+Subject: [PATCH] r8169: remove not needed check in rtl_fw_write_firmware
+
+This check can never be true for a firmware file with a correct format.
+Existing checks in rtl_fw_data_ok() are sufficient, no problems with
+invalid firmware files are known.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169_firmware.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_firmware.c
++++ b/drivers/net/ethernet/realtek/r8169_firmware.c
+@@ -151,9 +151,6 @@ void rtl_fw_write_firmware(struct rtl816
+ u32 regno = (action & 0x0fff0000) >> 16;
+ enum rtl_fw_opcode opcode = action >> 28;
+
+- if (!action)
+- break;
+-
+ switch (opcode) {
+ case PHY_READ:
+ predata = fw_read(tp, regno);
diff --git a/target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch b/target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch
new file mode 100644
index 0000000000..4186e14e17
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch
@@ -0,0 +1,47 @@
+From cd04b44bf055c4cd6bcee2ebfa6932fb20ef369d Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 Nov 2023 21:16:10 +0100
+Subject: [PATCH] r8169: remove multicast filter limit
+
+Once upon a time, when r8169 was new, the multicast filter limit code
+was copied from RTL8139 driver. There the filter limit is even
+user-configurable.
+The filtering is hash-based and we don't have perfect filtering.
+Actually the mc filtering on RTL8125 still seems to be the same
+as used on 8390/NE2000. So it's not clear to me which benefit it
+should bring when switching to all-multi mode once a certain number
+of filter bits is set. More the opposite: Filtering out at least
+some unwanted mc traffic is better than no filtering.
+Also the available chip documentation doesn't mention any restriction.
+Therefore remove the filter limit.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/57076c05-3730-40d1-ab9a-5334b263e41a@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -56,10 +56,6 @@
+ #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
+ #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
+
+-/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+- The RTL chips use a 64 element hash table based on the Ethernet CRC. */
+-#define MC_FILTER_LIMIT 32
+-
+ #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
+ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
+
+@@ -2626,8 +2622,7 @@ static void rtl_set_rx_mode(struct net_d
+ rx_mode |= AcceptAllPhys;
+ } else if (!(dev->flags & IFF_MULTICAST)) {
+ rx_mode &= ~AcceptMulticast;
+- } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
+- dev->flags & IFF_ALLMULTI ||
++ } else if (dev->flags & IFF_ALLMULTI ||
+ tp->mac_version == RTL_GIGA_MAC_VER_35) {
+ /* accept all multicasts */
+ } else if (netdev_mc_empty(dev)) {
diff --git a/target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch
deleted file mode 100644
index 5ab160855a..0000000000
--- a/target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch
+++ /dev/null
@@ -1,355 +0,0 @@
-From 3907f1ffc0ecf466d5c04aadc44c4b9203f3ec9a Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 1 Feb 2024 22:38:01 +0100
-Subject: [PATCH] r8169: add support for RTL8126A
-
-This adds support for the RTL8126A found on Asus z790 Maximus Formula.
-It was successfully tested w/o the firmware at 1000Mbps. Firmware file
-has been provided by Realtek and submitted to linux-firmware.
-2.5G and 5G modes are untested.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/r8169.h | 1 +
- drivers/net/ethernet/realtek/r8169_main.c | 105 ++++++++++++++----
- .../net/ethernet/realtek/r8169_phy_config.c | 7 ++
- 3 files changed, 89 insertions(+), 24 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -68,6 +68,7 @@ enum mac_version {
- /* support for RTL_GIGA_MAC_VER_60 has been removed */
- RTL_GIGA_MAC_VER_61,
- RTL_GIGA_MAC_VER_63,
-+ RTL_GIGA_MAC_VER_65,
- RTL_GIGA_MAC_NONE
- };
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -55,6 +55,7 @@
- #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
- #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
- #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
-+#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
-
- /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
- The RTL chips use a 64 element hash table based on the Ethernet CRC. */
-@@ -140,6 +141,7 @@ static const struct {
- [RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
- /* reserve 62 for CFG_METHOD_4 in the vendor driver */
- [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
-+ [RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
- };
-
- static const struct pci_device_id rtl8169_pci_tbl[] = {
-@@ -162,6 +164,7 @@ static const struct pci_device_id rtl816
- { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
- { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
- { PCI_VDEVICE(REALTEK, 0x8125) },
-+ { PCI_VDEVICE(REALTEK, 0x8126) },
- { PCI_VDEVICE(REALTEK, 0x3000) },
- {}
- };
-@@ -331,8 +334,12 @@ enum rtl8168_registers {
- };
-
- enum rtl8125_registers {
-+ INT_CFG0_8125 = 0x34,
-+#define INT_CFG0_ENABLE_8125 BIT(0)
-+#define INT_CFG0_CLKREQEN BIT(3)
- IntrMask_8125 = 0x38,
- IntrStatus_8125 = 0x3c,
-+ INT_CFG1_8125 = 0x7a,
- TxPoll_8125 = 0x90,
- MAC0_BKP = 0x19e0,
- EEE_TXIDLE_TIMER_8125 = 0x6048,
-@@ -1144,7 +1151,7 @@ static void rtl_writephy(struct rtl8169_
- case RTL_GIGA_MAC_VER_31:
- r8168dp_2_mdio_write(tp, location, val);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- r8168g_mdio_write(tp, location, val);
- break;
- default:
-@@ -1159,7 +1166,7 @@ static int rtl_readphy(struct rtl8169_pr
- case RTL_GIGA_MAC_VER_28:
- case RTL_GIGA_MAC_VER_31:
- return r8168dp_2_mdio_read(tp, location);
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- return r8168g_mdio_read(tp, location);
- default:
- return r8169_mdio_read(tp, location);
-@@ -1368,7 +1375,7 @@ static void rtl_set_d3_pll_down(struct r
- case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
- case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
- case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
-- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
- if (enable)
- RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
- else
-@@ -1535,7 +1542,7 @@ static void __rtl8169_set_wol(struct rtl
- break;
- case RTL_GIGA_MAC_VER_34:
- case RTL_GIGA_MAC_VER_37:
-- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
- if (wolopts)
- rtl_mod_config2(tp, 0, PME_SIGNAL);
- else
-@@ -2122,6 +2129,9 @@ static enum mac_version rtl8169_get_mac_
- u16 val;
- enum mac_version ver;
- } mac_info[] = {
-+ /* 8126A family. */
-+ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
-+
- /* 8125B family. */
- { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
-
-@@ -2392,6 +2402,7 @@ static void rtl_init_rxcfg(struct rtl816
- RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
- break;
- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_65:
- RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
- RX_PAUSE_SLOT_ON);
- break;
-@@ -2578,7 +2589,7 @@ static void rtl_wait_txrx_fifo_empty(str
- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
- rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
- break;
-- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_65:
- RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
- rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
- rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
-@@ -2822,7 +2833,7 @@ static void rtl_enable_exit_l1(struct rt
- case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
- rtl_eri_set_bits(tp, 0xd4, 0x0c00);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
- break;
- default:
-@@ -2836,7 +2847,7 @@ static void rtl_disable_exit_l1(struct r
- case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
- rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
- break;
- default:
-@@ -2846,6 +2857,8 @@ static void rtl_disable_exit_l1(struct r
-
- static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
- {
-+ u8 val8;
-+
- if (tp->mac_version < RTL_GIGA_MAC_VER_32)
- return;
-
-@@ -2859,11 +2872,19 @@ static void rtl_hw_aspm_clkreq_enable(st
- return;
-
- rtl_mod_config5(tp, 0, ASPM_en);
-- rtl_mod_config2(tp, 0, ClkReqEn);
-+ switch (tp->mac_version) {
-+ case RTL_GIGA_MAC_VER_65:
-+ val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
-+ RTL_W8(tp, INT_CFG0_8125, val8);
-+ break;
-+ default:
-+ rtl_mod_config2(tp, 0, ClkReqEn);
-+ break;
-+ }
-
- switch (tp->mac_version) {
- case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
-- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- /* reset ephy tx/rx disable timer */
- r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
- /* chip can trigger L1.2 */
-@@ -2875,14 +2896,22 @@ static void rtl_hw_aspm_clkreq_enable(st
- } else {
- switch (tp->mac_version) {
- case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
-- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
- break;
- default:
- break;
- }
-
-- rtl_mod_config2(tp, ClkReqEn, 0);
-+ switch (tp->mac_version) {
-+ case RTL_GIGA_MAC_VER_65:
-+ val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
-+ RTL_W8(tp, INT_CFG0_8125, val8);
-+ break;
-+ default:
-+ rtl_mod_config2(tp, ClkReqEn, 0);
-+ break;
-+ }
- rtl_mod_config5(tp, ASPM_en, 0);
- }
- }
-@@ -3678,10 +3707,15 @@ static void rtl_hw_start_8125_common(str
- /* disable new tx descriptor format */
- r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
-
-- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
-+ RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
-+
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
-+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
-+ else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
- else
-- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
-+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0300);
-
- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
- r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000);
-@@ -3694,6 +3728,10 @@ static void rtl_hw_start_8125_common(str
- r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
- r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
- r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
-+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
-+ else
-+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
- r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403);
- r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0068);
- r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f);
-@@ -3708,10 +3746,10 @@ static void rtl_hw_start_8125_common(str
-
- rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10);
-
-- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
-- rtl8125b_config_eee_mac(tp);
-- else
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_61)
- rtl8125a_config_eee_mac(tp);
-+ else
-+ rtl8125b_config_eee_mac(tp);
-
- rtl_disable_rxdvgate(tp);
- }
-@@ -3755,6 +3793,12 @@ static void rtl_hw_start_8125b(struct rt
- rtl_hw_start_8125_common(tp);
- }
-
-+static void rtl_hw_start_8126a(struct rtl8169_private *tp)
-+{
-+ rtl_set_def_aspm_entry_latency(tp);
-+ rtl_hw_start_8125_common(tp);
-+}
-+
- static void rtl_hw_config(struct rtl8169_private *tp)
- {
- static const rtl_generic_fct hw_configs[] = {
-@@ -3797,6 +3841,7 @@ static void rtl_hw_config(struct rtl8169
- [RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
- [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
- [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
-+ [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
- };
-
- if (hw_configs[tp->mac_version])
-@@ -3807,9 +3852,23 @@ static void rtl_hw_start_8125(struct rtl
- {
- int i;
-
-+ RTL_W8(tp, INT_CFG0_8125, 0x00);
-+
- /* disable interrupt coalescing */
-- for (i = 0xa00; i < 0xb00; i += 4)
-- RTL_W32(tp, i, 0);
-+ switch (tp->mac_version) {
-+ case RTL_GIGA_MAC_VER_61:
-+ for (i = 0xa00; i < 0xb00; i += 4)
-+ RTL_W32(tp, i, 0);
-+ break;
-+ case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_65:
-+ for (i = 0xa00; i < 0xa80; i += 4)
-+ RTL_W32(tp, i, 0);
-+ RTL_W16(tp, INT_CFG1_8125, 0x0000);
-+ break;
-+ default:
-+ break;
-+ }
-
- rtl_hw_config(tp);
- }
-@@ -3887,8 +3946,7 @@ static int rtl8169_change_mtu(struct net
- rtl_jumbo_config(tp);
-
- switch (tp->mac_version) {
-- case RTL_GIGA_MAC_VER_61:
-- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- rtl8125_set_eee_txidle_timer(tp);
- break;
- default:
-@@ -4037,7 +4095,7 @@ static void rtl8169_cleanup(struct rtl81
- RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
- rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- rtl_enable_rxdvgate(tp);
- fsleep(2000);
- break;
-@@ -4188,8 +4246,7 @@ static unsigned int rtl_quirk_packet_pad
-
- switch (tp->mac_version) {
- case RTL_GIGA_MAC_VER_34:
-- case RTL_GIGA_MAC_VER_61:
-- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- padto = max_t(unsigned int, padto, ETH_ZLEN);
- break;
- default:
-@@ -5225,7 +5282,7 @@ static void rtl_hw_initialize(struct rtl
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
- rtl_hw_init_8168g(tp);
- break;
-- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- rtl_hw_init_8125(tp);
- break;
- default:
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1102,6 +1102,12 @@ static void rtl8125b_hw_phy_config(struc
- rtl8125b_config_eee_phy(phydev);
- }
-
-+static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
-+ struct phy_device *phydev)
-+{
-+ r8169_apply_firmware(tp);
-+}
-+
- void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
- enum mac_version ver)
- {
-@@ -1152,6 +1158,7 @@ void r8169_hw_phy_config(struct rtl8169_
- [RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
- [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
- [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
-+ [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
- };
-
- if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch b/target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch
new file mode 100644
index 0000000000..a809e8213a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch
@@ -0,0 +1,41 @@
+From 127532cd0f060ebc3c4cbca81b6438728ad5896e Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 Nov 2023 18:20:11 +0100
+Subject: [PATCH] r8169: improve handling task scheduling
+
+If we know that the task is going to be a no-op, don't even schedule it.
+And remove the check for netif_running() in the worker function, the
+check for flag RTL_FLAG_TASK_ENABLED is sufficient. Note that we can't
+remove the check for flag RTL_FLAG_TASK_ENABLED in the worker function
+because we have no guarantee when it will be executed.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://lore.kernel.org/r/c65873a3-7394-4107-99a7-83f20030779c@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2252,6 +2252,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
+
+ static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
+ {
++ if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
++ return;
++
+ set_bit(flag, tp->wk.flags);
+ schedule_work(&tp->wk.work);
+ }
+@@ -4491,8 +4494,7 @@ static void rtl_task(struct work_struct
+
+ rtnl_lock();
+
+- if (!netif_running(tp->dev) ||
+- !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
++ if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
+ goto out_unlock;
+
+ if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
diff --git a/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch b/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
new file mode 100644
index 0000000000..7a5d5a66a1
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
@@ -0,0 +1,319 @@
+From 18764b883e157e28126b54e7d4ba9dd487d5bf54 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sat, 16 Dec 2023 20:58:10 +0100
+Subject: [PATCH] r8169: add support for LED's on RTL8168/RTL8101
+
+This adds support for the LED's on most chip versions. Excluded are
+the old non-PCIe versions and RTL8125. RTL8125 has a different LED
+register layout, support for it will follow later.
+
+LED's can be controlled from userspace using the netdev LED trigger.
+
+Tested on RTL8168h.
+
+Note: The driver can't know which LED's are actually physically
+wired. Therefore not every LED device may represent a physically
+available LED.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/Makefile | 3 +
+ drivers/net/ethernet/realtek/r8169.h | 7 +
+ drivers/net/ethernet/realtek/r8169_leds.c | 157 ++++++++++++++++++++++
+ drivers/net/ethernet/realtek/r8169_main.c | 65 +++++++++
+ 4 files changed, 232 insertions(+)
+ create mode 100644 drivers/net/ethernet/realtek/r8169_leds.c
+
+--- a/drivers/net/ethernet/realtek/Makefile
++++ b/drivers/net/ethernet/realtek/Makefile
+@@ -7,4 +7,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
+ obj-$(CONFIG_8139TOO) += 8139too.o
+ obj-$(CONFIG_ATP) += atp.o
+ r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
++ifdef CONFIG_LEDS_TRIGGER_NETDEV
++r8169-objs += r8169_leds.o
++endif
+ obj-$(CONFIG_R8169) += r8169.o
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -8,6 +8,7 @@
+ * See MAINTAINERS file for support contact information.
+ */
+
++#include <linux/netdevice.h>
+ #include <linux/types.h>
+ #include <linux/phy.h>
+
+@@ -77,3 +78,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
+ u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
+ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
+ enum mac_version ver);
++
++void r8169_get_led_name(struct rtl8169_private *tp, int idx,
++ char *buf, int buf_len);
++int rtl8168_get_led_mode(struct rtl8169_private *tp);
++int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
++void rtl8168_init_leds(struct net_device *ndev);
+--- /dev/null
++++ b/drivers/net/ethernet/realtek/r8169_leds.c
+@@ -0,0 +1,157 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver.
++ *
++ * Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com>
++ *
++ * See MAINTAINERS file for support contact information.
++ */
++
++#include <linux/leds.h>
++#include <linux/netdevice.h>
++#include <uapi/linux/uleds.h>
++
++#include "r8169.h"
++
++#define RTL8168_LED_CTRL_OPTION2 BIT(15)
++#define RTL8168_LED_CTRL_ACT BIT(3)
++#define RTL8168_LED_CTRL_LINK_1000 BIT(2)
++#define RTL8168_LED_CTRL_LINK_100 BIT(1)
++#define RTL8168_LED_CTRL_LINK_10 BIT(0)
++
++#define RTL8168_NUM_LEDS 3
++
++#define RTL8168_SUPPORTED_MODES \
++ (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \
++ BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \
++ BIT(TRIGGER_NETDEV_TX))
++
++struct r8169_led_classdev {
++ struct led_classdev led;
++ struct net_device *ndev;
++ int index;
++};
++
++#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
++
++static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int shift = ldev->index * 4;
++ bool rx, tx;
++
++ if (flags & ~RTL8168_SUPPORTED_MODES)
++ goto nosupp;
++
++ rx = flags & BIT(TRIGGER_NETDEV_RX);
++ tx = flags & BIT(TRIGGER_NETDEV_TX);
++ if (rx != tx)
++ goto nosupp;
++
++ return 0;
++
++nosupp:
++ /* Switch LED off to indicate that mode isn't supported */
++ rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
++ return -EOPNOTSUPP;
++}
++
++static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int shift = ldev->index * 4;
++ u16 mode = 0;
++
++ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
++ mode |= RTL8168_LED_CTRL_LINK_10;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
++ mode |= RTL8168_LED_CTRL_LINK_100;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
++ mode |= RTL8168_LED_CTRL_LINK_1000;
++ if (flags & BIT(TRIGGER_NETDEV_TX))
++ mode |= RTL8168_LED_CTRL_ACT;
++
++ return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift);
++}
++
++static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev,
++ unsigned long *flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int shift = ldev->index * 4;
++ int mode;
++
++ mode = rtl8168_get_led_mode(tp);
++ if (mode < 0)
++ return mode;
++
++ if (mode & RTL8168_LED_CTRL_OPTION2) {
++ rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0);
++ netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n");
++ }
++
++ mode = (mode >> shift) & 0x000f;
++
++ if (mode & RTL8168_LED_CTRL_ACT)
++ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
++
++ if (mode & RTL8168_LED_CTRL_LINK_10)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
++ if (mode & RTL8168_LED_CTRL_LINK_100)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
++ if (mode & RTL8168_LED_CTRL_LINK_1000)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++ return 0;
++}
++
++static struct device *
++ r8169_led_hw_control_get_device(struct led_classdev *led_cdev)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++
++ return &ldev->ndev->dev;
++}
++
++static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
++ struct net_device *ndev, int index)
++{
++ struct rtl8169_private *tp = netdev_priv(ndev);
++ struct led_classdev *led_cdev = &ldev->led;
++ char led_name[LED_MAX_NAME_SIZE];
++
++ ldev->ndev = ndev;
++ ldev->index = index;
++
++ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
++ led_cdev->name = led_name;
++ led_cdev->default_trigger = "netdev";
++ led_cdev->hw_control_trigger = "netdev";
++ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
++ led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
++ led_cdev->hw_control_set = rtl8168_led_hw_control_set;
++ led_cdev->hw_control_get = rtl8168_led_hw_control_get;
++ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
++
++ /* ignore errors */
++ devm_led_classdev_register(&ndev->dev, led_cdev);
++}
++
++void rtl8168_init_leds(struct net_device *ndev)
++{
++ /* bind resource mgmt to netdev */
++ struct device *dev = &ndev->dev;
++ struct r8169_led_classdev *leds;
++ int i;
++
++ leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ if (!leds)
++ return;
++
++ for (i = 0; i < RTL8168_NUM_LEDS; i++)
++ rtl8168_setup_ldev(leds + i, ndev, i);
++}
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -285,6 +285,7 @@ enum rtl8168_8101_registers {
+ };
+
+ enum rtl8168_registers {
++ LED_CTRL = 0x18,
+ LED_FREQ = 0x1a,
+ EEE_LED = 0x1b,
+ ERIDR = 0x70,
+@@ -616,6 +617,7 @@ struct rtl8169_private {
+
+ raw_spinlock_t config25_lock;
+ raw_spinlock_t mac_ocp_lock;
++ struct mutex led_lock; /* serialize LED ctrl RMW access */
+
+ raw_spinlock_t cfg9346_usage_lock;
+ int cfg9346_usage_count;
+@@ -788,6 +790,62 @@ static const struct rtl_cond name = {
+ \
+ static bool name ## _check(struct rtl8169_private *tp)
+
++int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val)
++{
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ mutex_lock(&tp->led_lock);
++ RTL_W16(tp, LED_CTRL, (RTL_R16(tp, LED_CTRL) & ~mask) | val);
++ mutex_unlock(&tp->led_lock);
++
++ pm_runtime_put_sync(dev);
++
++ return 0;
++}
++
++int rtl8168_get_led_mode(struct rtl8169_private *tp)
++{
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ ret = RTL_R16(tp, LED_CTRL);
++
++ pm_runtime_put_sync(dev);
++
++ return ret;
++}
++
++void r8169_get_led_name(struct rtl8169_private *tp, int idx,
++ char *buf, int buf_len)
++{
++ struct pci_dev *pdev = tp->pci_dev;
++ char pdom[8], pfun[8];
++ int domain;
++
++ domain = pci_domain_nr(pdev->bus);
++ if (domain)
++ snprintf(pdom, sizeof(pdom), "P%d", domain);
++ else
++ pdom[0] = '\0';
++
++ if (pdev->multifunction)
++ snprintf(pfun, sizeof(pfun), "f%d", PCI_FUNC(pdev->devfn));
++ else
++ pfun[0] = '\0';
++
++ snprintf(buf, buf_len, "en%sp%ds%d%s-%d::lan", pdom, pdev->bus->number,
++ PCI_SLOT(pdev->devfn), pfun, idx);
++}
++
+ static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
+ {
+ /* based on RTL8168FP_OOBMAC_BASE in vendor driver */
+@@ -5168,6 +5226,7 @@ static int rtl_init_one(struct pci_dev *
+ raw_spin_lock_init(&tp->cfg9346_usage_lock);
+ raw_spin_lock_init(&tp->config25_lock);
+ raw_spin_lock_init(&tp->mac_ocp_lock);
++ mutex_init(&tp->led_lock);
+
+ dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
+ struct pcpu_sw_netstats);
+@@ -5324,6 +5383,12 @@ static int rtl_init_one(struct pci_dev *
+ if (rc)
+ return rc;
+
++#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
++ if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
++ tp->mac_version < RTL_GIGA_MAC_VER_61)
++ rtl8168_init_leds(dev);
++#endif
++
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
+ rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
+
diff --git a/target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch b/target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
deleted file mode 100644
index 742ee578b2..0000000000
--- a/target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From be51ed104ba9929c741afb718ef7198dbcecef94 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 12 Feb 2024 19:44:11 +0100
-Subject: [PATCH] r8169: add LED support for RTL8125/RTL8126
-
-This adds LED support for RTL8125/RTL8126.
-
-Note: Due to missing datasheets changing the 5Gbps link mode isn't
-supported for RTL8126.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/f982602c-9de3-4ca6-85a3-2c1d118dcb15@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h | 3 +
- drivers/net/ethernet/realtek/r8169_leds.c | 106 ++++++++++++++++++++++
- drivers/net/ethernet/realtek/r8169_main.c | 61 ++++++++++++-
- 3 files changed, 166 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -85,3 +85,6 @@ void r8169_get_led_name(struct rtl8169_p
- int rtl8168_get_led_mode(struct rtl8169_private *tp);
- int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
- void rtl8168_init_leds(struct net_device *ndev);
-+int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
-+int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
-+void rtl8125_init_leds(struct net_device *ndev);
---- a/drivers/net/ethernet/realtek/r8169_leds.c
-+++ b/drivers/net/ethernet/realtek/r8169_leds.c
-@@ -18,7 +18,14 @@
- #define RTL8168_LED_CTRL_LINK_100 BIT(1)
- #define RTL8168_LED_CTRL_LINK_10 BIT(0)
-
-+#define RTL8125_LED_CTRL_ACT BIT(9)
-+#define RTL8125_LED_CTRL_LINK_2500 BIT(5)
-+#define RTL8125_LED_CTRL_LINK_1000 BIT(3)
-+#define RTL8125_LED_CTRL_LINK_100 BIT(1)
-+#define RTL8125_LED_CTRL_LINK_10 BIT(0)
-+
- #define RTL8168_NUM_LEDS 3
-+#define RTL8125_NUM_LEDS 4
-
- struct r8169_led_classdev {
- struct led_classdev led;
-@@ -157,3 +164,102 @@ void rtl8168_init_leds(struct net_device
- for (i = 0; i < RTL8168_NUM_LEDS; i++)
- rtl8168_setup_ldev(leds + i, ndev, i);
- }
-+
-+static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+
-+ if (!r8169_trigger_mode_is_valid(flags)) {
-+ /* Switch LED off to indicate that mode isn't supported */
-+ rtl8125_set_led_mode(tp, ldev->index, 0);
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return 0;
-+}
-+
-+static int rtl8125_led_hw_control_set(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ u16 mode = 0;
-+
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
-+ mode |= RTL8125_LED_CTRL_LINK_10;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
-+ mode |= RTL8125_LED_CTRL_LINK_100;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
-+ mode |= RTL8125_LED_CTRL_LINK_1000;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_2500))
-+ mode |= RTL8125_LED_CTRL_LINK_2500;
-+ if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX)))
-+ mode |= RTL8125_LED_CTRL_ACT;
-+
-+ return rtl8125_set_led_mode(tp, ldev->index, mode);
-+}
-+
-+static int rtl8125_led_hw_control_get(struct led_classdev *led_cdev,
-+ unsigned long *flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int mode;
-+
-+ mode = rtl8125_get_led_mode(tp, ldev->index);
-+ if (mode < 0)
-+ return mode;
-+
-+ if (mode & RTL8125_LED_CTRL_LINK_10)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
-+ if (mode & RTL8125_LED_CTRL_LINK_100)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
-+ if (mode & RTL8125_LED_CTRL_LINK_1000)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
-+ if (mode & RTL8125_LED_CTRL_LINK_2500)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_2500);
-+ if (mode & RTL8125_LED_CTRL_ACT)
-+ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
-+
-+ return 0;
-+}
-+
-+static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev,
-+ struct net_device *ndev, int index)
-+{
-+ struct rtl8169_private *tp = netdev_priv(ndev);
-+ struct led_classdev *led_cdev = &ldev->led;
-+ char led_name[LED_MAX_NAME_SIZE];
-+
-+ ldev->ndev = ndev;
-+ ldev->index = index;
-+
-+ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
-+ led_cdev->name = led_name;
-+ led_cdev->hw_control_trigger = "netdev";
-+ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
-+ led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;
-+ led_cdev->hw_control_set = rtl8125_led_hw_control_set;
-+ led_cdev->hw_control_get = rtl8125_led_hw_control_get;
-+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-+
-+ /* ignore errors */
-+ devm_led_classdev_register(&ndev->dev, led_cdev);
-+}
-+
-+void rtl8125_init_leds(struct net_device *ndev)
-+{
-+ /* bind resource mgmt to netdev */
-+ struct device *dev = &ndev->dev;
-+ struct r8169_led_classdev *leds;
-+ int i;
-+
-+ leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ if (!leds)
-+ return;
-+
-+ for (i = 0; i < RTL8125_NUM_LEDS; i++)
-+ rtl8125_setup_led_ldev(leds + i, ndev, i);
-+}
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -334,17 +334,23 @@ enum rtl8168_registers {
- };
-
- enum rtl8125_registers {
-+ LEDSEL0 = 0x18,
- INT_CFG0_8125 = 0x34,
- #define INT_CFG0_ENABLE_8125 BIT(0)
- #define INT_CFG0_CLKREQEN BIT(3)
- IntrMask_8125 = 0x38,
- IntrStatus_8125 = 0x3c,
- INT_CFG1_8125 = 0x7a,
-+ LEDSEL2 = 0x84,
-+ LEDSEL1 = 0x86,
- TxPoll_8125 = 0x90,
-+ LEDSEL3 = 0x96,
- MAC0_BKP = 0x19e0,
- EEE_TXIDLE_TIMER_8125 = 0x6048,
- };
-
-+#define LEDSEL_MASK_8125 0x23f
-+
- #define RX_VLAN_INNER_8125 BIT(22)
- #define RX_VLAN_OUTER_8125 BIT(23)
- #define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125)
-@@ -835,6 +841,51 @@ int rtl8168_get_led_mode(struct rtl8169_
- return ret;
- }
-
-+static int rtl8125_get_led_reg(int index)
-+{
-+ static const int led_regs[] = { LEDSEL0, LEDSEL1, LEDSEL2, LEDSEL3 };
-+
-+ return led_regs[index];
-+}
-+
-+int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode)
-+{
-+ int reg = rtl8125_get_led_reg(index);
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+ u16 val;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ mutex_lock(&tp->led_lock);
-+ val = RTL_R16(tp, reg) & ~LEDSEL_MASK_8125;
-+ RTL_W16(tp, reg, val | mode);
-+ mutex_unlock(&tp->led_lock);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return 0;
-+}
-+
-+int rtl8125_get_led_mode(struct rtl8169_private *tp, int index)
-+{
-+ int reg = rtl8125_get_led_reg(index);
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = RTL_R16(tp, reg);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return ret;
-+}
-+
- void r8169_get_led_name(struct rtl8169_private *tp, int idx,
- char *buf, int buf_len)
- {
-@@ -5530,10 +5581,12 @@ static int rtl_init_one(struct pci_dev *
- if (rc)
- return rc;
-
-- if (IS_ENABLED(CONFIG_R8169_LEDS) &&
-- tp->mac_version > RTL_GIGA_MAC_VER_06 &&
-- tp->mac_version < RTL_GIGA_MAC_VER_61)
-- rtl8168_init_leds(dev);
-+ if (IS_ENABLED(CONFIG_R8169_LEDS)) {
-+ if (rtl_is_8125(tp))
-+ rtl8125_init_leds(dev);
-+ else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
-+ rtl8168_init_leds(dev);
-+ }
-
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
- rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch b/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
new file mode 100644
index 0000000000..67f215cadf
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
@@ -0,0 +1,75 @@
+From a2634a5ffcafc31c343c6153ae487eb184c433a6 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 3 Jan 2024 16:52:04 +0100
+Subject: [PATCH] r8169: fix building with CONFIG_LEDS_CLASS=m
+
+When r8169 is built-in but LED support is a loadable module, the new
+code to drive the LED causes a link failure:
+
+ld: drivers/net/ethernet/realtek/r8169_leds.o: in function `rtl8168_init_leds':
+r8169_leds.c:(.text+0x36c): undefined reference to `devm_led_classdev_register_ext'
+
+LED support is an optional feature, so fix this issue by adding a Kconfig
+symbol R8169_LEDS that is guaranteed to be false if r8169 is built-in
+and LED core support is a module. As a positive side effect of this change
+r8169_leds.o no longer is built under this configuration.
+
+Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202312281159.9TPeXbNd-lkp@intel.com/
+Suggested-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Simon Horman <horms@kernel.org> # build-tested
+Tested-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/d055aeb5-fe5c-4ccf-987f-5af93a17537b@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/Kconfig | 7 +++++++
+ drivers/net/ethernet/realtek/Makefile | 6 ++----
+ drivers/net/ethernet/realtek/r8169_main.c | 5 ++---
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/Kconfig
++++ b/drivers/net/ethernet/realtek/Kconfig
+@@ -113,4 +113,11 @@ config R8169
+ To compile this driver as a module, choose M here: the module
+ will be called r8169. This is recommended.
+
++config R8169_LEDS
++ def_bool R8169 && LEDS_TRIGGER_NETDEV
++ depends on !(R8169=y && LEDS_CLASS=m)
++ help
++ Optional support for controlling the NIC LED's with the netdev
++ LED trigger.
++
+ endif # NET_VENDOR_REALTEK
+--- a/drivers/net/ethernet/realtek/Makefile
++++ b/drivers/net/ethernet/realtek/Makefile
+@@ -6,8 +6,6 @@
+ obj-$(CONFIG_8139CP) += 8139cp.o
+ obj-$(CONFIG_8139TOO) += 8139too.o
+ obj-$(CONFIG_ATP) += atp.o
+-r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
+-ifdef CONFIG_LEDS_TRIGGER_NETDEV
+-r8169-objs += r8169_leds.o
+-endif
++r8169-y += r8169_main.o r8169_firmware.o r8169_phy_config.o
++r8169-$(CONFIG_R8169_LEDS) += r8169_leds.o
+ obj-$(CONFIG_R8169) += r8169.o
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5383,11 +5383,10 @@ static int rtl_init_one(struct pci_dev *
+ if (rc)
+ return rc;
+
+-#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
+- if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
++ if (IS_ENABLED(CONFIG_R8169_LEDS) &&
++ tp->mac_version > RTL_GIGA_MAC_VER_06 &&
+ tp->mac_version < RTL_GIGA_MAC_VER_61)
+ rtl8168_init_leds(dev);
+-#endif
+
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
+ rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
deleted file mode 100644
index a6175c824e..0000000000
--- a/target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From f4d3e595c0000ce39dec7e4799ea42ce42ab6867 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 17 Feb 2024 15:48:23 +0100
-Subject: [PATCH] r8169: add MODULE_FIRMWARE entry for RTL8126A
-
-Add the missing MODULE_FIRMWARE entry for RTL8126A.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/47ef79d2-59c4-4d44-9595-366c70c4ad87@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -680,6 +680,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
- MODULE_FIRMWARE(FIRMWARE_8107E_2);
- MODULE_FIRMWARE(FIRMWARE_8125A_3);
- MODULE_FIRMWARE(FIRMWARE_8125B_2);
-+MODULE_FIRMWARE(FIRMWARE_8126A_2);
-
- static inline struct device *tp_to_dev(struct rtl8169_private *tp)
- {
diff --git a/target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch b/target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch
deleted file mode 100644
index 557b8b1491..0000000000
--- a/target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 39f59c72ad3a1eaab9a60f0671bc94d2bc826d21 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sun, 7 Apr 2024 23:19:25 +0200
-Subject: [PATCH] r8169: add support for RTL8168M
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-A user reported an unknown chip version. According to the r8168 vendor
-driver it's called RTL8168M, but handling is identical to RTL8168H.
-So let's simply treat it as RTL8168H.
-
-Tested-by: Евгений <octobergun@gmail.com>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/r8169_main.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -2212,6 +2212,8 @@ static enum mac_version rtl8169_get_mac_
- * the wild. Let's disable detection.
- * { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 },
- */
-+ /* Realtek calls it RTL8168M, but it's handled like RTL8168H */
-+ { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46 },
-
- /* 8168G family. */
- { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 },
diff --git a/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch b/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch
new file mode 100644
index 0000000000..bdd3330580
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch
@@ -0,0 +1,96 @@
+From f5d59230ec26aa5e8b59e9f4a4d288703a737479 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 31 Jan 2024 21:31:01 +0100
+Subject: [PATCH] r8169: simplify EEE handling
+
+We don't have to store the EEE modes to be advertised in the driver,
+phylib does this for us and stores it in phydev->advertising_eee.
+phylib also takes care of properly handling the EEE advertisement.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/27c336a8-ea47-483d-815b-02c45ae41da2@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 32 +++--------------------
+ 1 file changed, 4 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -629,7 +629,6 @@ struct rtl8169_private {
+ struct rtl8169_counters *counters;
+ struct rtl8169_tc_offsets tc_offset;
+ u32 saved_wolopts;
+- int eee_adv;
+
+ const char *fw_name;
+ struct rtl_fw *rtl_fw;
+@@ -2010,17 +2009,11 @@ static int rtl8169_get_eee(struct net_de
+ static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+- int ret;
+
+ if (!rtl_supports_eee(tp))
+ return -EOPNOTSUPP;
+
+- ret = phy_ethtool_set_eee(tp->phydev, data);
+-
+- if (!ret)
+- tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN,
+- MDIO_AN_EEE_ADV);
+- return ret;
++ return phy_ethtool_set_eee(tp->phydev, data);
+ }
+
+ static void rtl8169_get_ringparam(struct net_device *dev,
+@@ -2085,21 +2078,6 @@ static const struct ethtool_ops rtl8169_
+ .set_pauseparam = rtl8169_set_pauseparam,
+ };
+
+-static void rtl_enable_eee(struct rtl8169_private *tp)
+-{
+- struct phy_device *phydev = tp->phydev;
+- int adv;
+-
+- /* respect EEE advertisement the user may have set */
+- if (tp->eee_adv >= 0)
+- adv = tp->eee_adv;
+- else
+- adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
+-
+- if (adv >= 0)
+- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
+-}
+-
+ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
+ {
+ /*
+@@ -2336,9 +2314,6 @@ static void rtl8169_init_phy(struct rtl8
+ /* We may have called phy_speed_down before */
+ phy_speed_up(tp->phydev);
+
+- if (rtl_supports_eee(tp))
+- rtl_enable_eee(tp);
+-
+ genphy_soft_reset(tp->phydev);
+ }
+
+@@ -5085,7 +5060,9 @@ static int r8169_mdio_register(struct rt
+ }
+
+ tp->phydev->mac_managed_pm = true;
+-
++ if (rtl_supports_eee(tp))
++ linkmode_copy(tp->phydev->advertising_eee,
++ tp->phydev->supported_eee);
+ phy_support_asym_pause(tp->phydev);
+
+ /* PHY will be woken up in rtl_open() */
+@@ -5220,7 +5197,6 @@ static int rtl_init_one(struct pci_dev *
+ tp->dev = dev;
+ tp->pci_dev = pdev;
+ tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
+- tp->eee_adv = -1;
+ tp->ocp_base = OCP_STD_PHY_BASE;
+
+ raw_spin_lock_init(&tp->cfg9346_usage_lock);
diff --git a/target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch b/target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch
deleted file mode 100644
index 52019869a8..0000000000
--- a/target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From 19fa4f2a85d777a8052e869c1b892a2f7556569d Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 8 Apr 2024 20:47:40 +0200
-Subject: [PATCH] r8169: fix LED-related deadlock on module removal
-
-Binding devm_led_classdev_register() to the netdev is problematic
-because on module removal we get a RTNL-related deadlock. Fix this
-by avoiding the device-managed LED functions.
-
-Note: We can safely call led_classdev_unregister() for a LED even
-if registering it failed, because led_classdev_unregister() detects
-this and is a no-op in this case.
-
-Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
-Cc: stable@vger.kernel.org
-Reported-by: Lukas Wunner <lukas@wunner.de>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/r8169.h | 6 ++--
- drivers/net/ethernet/realtek/r8169_leds.c | 35 +++++++++++++++--------
- drivers/net/ethernet/realtek/r8169_main.c | 8 ++++--
- 3 files changed, 33 insertions(+), 16 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -73,6 +73,7 @@ enum mac_version {
- };
-
- struct rtl8169_private;
-+struct r8169_led_classdev;
-
- void r8169_apply_firmware(struct rtl8169_private *tp);
- u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
-@@ -84,7 +85,8 @@ void r8169_get_led_name(struct rtl8169_p
- char *buf, int buf_len);
- int rtl8168_get_led_mode(struct rtl8169_private *tp);
- int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
--void rtl8168_init_leds(struct net_device *ndev);
-+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev);
- int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
- int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
--void rtl8125_init_leds(struct net_device *ndev);
-+struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev);
-+void r8169_remove_leds(struct r8169_led_classdev *leds);
---- a/drivers/net/ethernet/realtek/r8169_leds.c
-+++ b/drivers/net/ethernet/realtek/r8169_leds.c
-@@ -147,22 +147,22 @@ static void rtl8168_setup_ldev(struct r8
- led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-
- /* ignore errors */
-- devm_led_classdev_register(&ndev->dev, led_cdev);
-+ led_classdev_register(&ndev->dev, led_cdev);
- }
-
--void rtl8168_init_leds(struct net_device *ndev)
-+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev)
- {
-- /* bind resource mgmt to netdev */
-- struct device *dev = &ndev->dev;
- struct r8169_led_classdev *leds;
- int i;
-
-- leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
- if (!leds)
-- return;
-+ return NULL;
-
- for (i = 0; i < RTL8168_NUM_LEDS; i++)
- rtl8168_setup_ldev(leds + i, ndev, i);
-+
-+ return leds;
- }
-
- static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
-@@ -246,20 +246,31 @@ static void rtl8125_setup_led_ldev(struc
- led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-
- /* ignore errors */
-- devm_led_classdev_register(&ndev->dev, led_cdev);
-+ led_classdev_register(&ndev->dev, led_cdev);
- }
-
--void rtl8125_init_leds(struct net_device *ndev)
-+struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev)
- {
-- /* bind resource mgmt to netdev */
-- struct device *dev = &ndev->dev;
- struct r8169_led_classdev *leds;
- int i;
-
-- leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ leds = kcalloc(RTL8125_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
- if (!leds)
-- return;
-+ return NULL;
-
- for (i = 0; i < RTL8125_NUM_LEDS; i++)
- rtl8125_setup_led_ldev(leds + i, ndev, i);
-+
-+ return leds;
-+}
-+
-+void r8169_remove_leds(struct r8169_led_classdev *leds)
-+{
-+ if (!leds)
-+ return;
-+
-+ for (struct r8169_led_classdev *l = leds; l->ndev; l++)
-+ led_classdev_unregister(&l->led);
-+
-+ kfree(leds);
- }
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -651,6 +651,8 @@ struct rtl8169_private {
- const char *fw_name;
- struct rtl_fw *rtl_fw;
-
-+ struct r8169_led_classdev *leds;
-+
- u32 ocp_base;
- };
-
-@@ -5126,6 +5128,8 @@ static void rtl_remove_one(struct pci_de
-
- cancel_work_sync(&tp->wk.work);
-
-+ r8169_remove_leds(tp->leds);
-+
- unregister_netdev(tp->dev);
-
- if (tp->dash_type != RTL_DASH_NONE)
-@@ -5586,9 +5590,9 @@ static int rtl_init_one(struct pci_dev *
-
- if (IS_ENABLED(CONFIG_R8169_LEDS)) {
- if (rtl_is_8125(tp))
-- rtl8125_init_leds(dev);
-+ tp->leds = rtl8125_init_leds(dev);
- else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
-- rtl8168_init_leds(dev);
-+ tp->leds = rtl8168_init_leds(dev);
- }
-
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
diff --git a/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch
new file mode 100644
index 0000000000..65aa5449ec
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch
@@ -0,0 +1,355 @@
+From 3907f1ffc0ecf466d5c04aadc44c4b9203f3ec9a Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Thu, 1 Feb 2024 22:38:01 +0100
+Subject: [PATCH] r8169: add support for RTL8126A
+
+This adds support for the RTL8126A found on Asus z790 Maximus Formula.
+It was successfully tested w/o the firmware at 1000Mbps. Firmware file
+has been provided by Realtek and submitted to linux-firmware.
+2.5G and 5G modes are untested.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169.h | 1 +
+ drivers/net/ethernet/realtek/r8169_main.c | 105 ++++++++++++++----
+ .../net/ethernet/realtek/r8169_phy_config.c | 7 ++
+ 3 files changed, 89 insertions(+), 24 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -68,6 +68,7 @@ enum mac_version {
+ /* support for RTL_GIGA_MAC_VER_60 has been removed */
+ RTL_GIGA_MAC_VER_61,
+ RTL_GIGA_MAC_VER_63,
++ RTL_GIGA_MAC_VER_65,
+ RTL_GIGA_MAC_NONE
+ };
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -55,6 +55,7 @@
+ #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
+ #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
+ #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
++#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
+
+ #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
+ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
+@@ -136,6 +137,7 @@ static const struct {
+ [RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
+ /* reserve 62 for CFG_METHOD_4 in the vendor driver */
+ [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
++ [RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
+ };
+
+ static const struct pci_device_id rtl8169_pci_tbl[] = {
+@@ -158,6 +160,7 @@ static const struct pci_device_id rtl816
+ { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
+ { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
+ { PCI_VDEVICE(REALTEK, 0x8125) },
++ { PCI_VDEVICE(REALTEK, 0x8126) },
+ { PCI_VDEVICE(REALTEK, 0x3000) },
+ {}
+ };
+@@ -327,8 +330,12 @@ enum rtl8168_registers {
+ };
+
+ enum rtl8125_registers {
++ INT_CFG0_8125 = 0x34,
++#define INT_CFG0_ENABLE_8125 BIT(0)
++#define INT_CFG0_CLKREQEN BIT(3)
+ IntrMask_8125 = 0x38,
+ IntrStatus_8125 = 0x3c,
++ INT_CFG1_8125 = 0x7a,
+ TxPoll_8125 = 0x90,
+ MAC0_BKP = 0x19e0,
+ EEE_TXIDLE_TIMER_8125 = 0x6048,
+@@ -1139,7 +1146,7 @@ static void rtl_writephy(struct rtl8169_
+ case RTL_GIGA_MAC_VER_31:
+ r8168dp_2_mdio_write(tp, location, val);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ r8168g_mdio_write(tp, location, val);
+ break;
+ default:
+@@ -1154,7 +1161,7 @@ static int rtl_readphy(struct rtl8169_pr
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ return r8168dp_2_mdio_read(tp, location);
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ return r8168g_mdio_read(tp, location);
+ default:
+ return r8169_mdio_read(tp, location);
+@@ -1363,7 +1370,7 @@ static void rtl_set_d3_pll_down(struct r
+ case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
+ case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
+- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
+ if (enable)
+ RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
+ else
+@@ -1530,7 +1537,7 @@ static void __rtl8169_set_wol(struct rtl
+ break;
+ case RTL_GIGA_MAC_VER_34:
+ case RTL_GIGA_MAC_VER_37:
+- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
+ if (wolopts)
+ rtl_mod_config2(tp, 0, PME_SIGNAL);
+ else
+@@ -2096,6 +2103,9 @@ static enum mac_version rtl8169_get_mac_
+ u16 val;
+ enum mac_version ver;
+ } mac_info[] = {
++ /* 8126A family. */
++ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
++
+ /* 8125B family. */
+ { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
+
+@@ -2366,6 +2376,7 @@ static void rtl_init_rxcfg(struct rtl816
+ RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
+ break;
+ case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_65:
+ RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
+ RX_PAUSE_SLOT_ON);
+ break;
+@@ -2552,7 +2563,7 @@ static void rtl_wait_txrx_fifo_empty(str
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
+ break;
+- case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_65:
+ RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
+@@ -2795,7 +2806,7 @@ static void rtl_enable_exit_l1(struct rt
+ case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
+ rtl_eri_set_bits(tp, 0xd4, 0x0c00);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
+ break;
+ default:
+@@ -2809,7 +2820,7 @@ static void rtl_disable_exit_l1(struct r
+ case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
+ rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
+ break;
+ default:
+@@ -2819,6 +2830,8 @@ static void rtl_disable_exit_l1(struct r
+
+ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
+ {
++ u8 val8;
++
+ if (tp->mac_version < RTL_GIGA_MAC_VER_32)
+ return;
+
+@@ -2832,11 +2845,19 @@ static void rtl_hw_aspm_clkreq_enable(st
+ return;
+
+ rtl_mod_config5(tp, 0, ASPM_en);
+- rtl_mod_config2(tp, 0, ClkReqEn);
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_65:
++ val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
++ RTL_W8(tp, INT_CFG0_8125, val8);
++ break;
++ default:
++ rtl_mod_config2(tp, 0, ClkReqEn);
++ break;
++ }
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ /* reset ephy tx/rx disable timer */
+ r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
+ /* chip can trigger L1.2 */
+@@ -2848,14 +2869,22 @@ static void rtl_hw_aspm_clkreq_enable(st
+ } else {
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
+ break;
+ default:
+ break;
+ }
+
+- rtl_mod_config2(tp, ClkReqEn, 0);
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_65:
++ val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
++ RTL_W8(tp, INT_CFG0_8125, val8);
++ break;
++ default:
++ rtl_mod_config2(tp, ClkReqEn, 0);
++ break;
++ }
+ rtl_mod_config5(tp, ASPM_en, 0);
+ }
+ }
+@@ -3568,10 +3597,15 @@ static void rtl_hw_start_8125_common(str
+ /* disable new tx descriptor format */
+ r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
+
+- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
++
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
++ else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
+ else
+- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
++ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0300);
+
+ if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000);
+@@ -3584,6 +3618,10 @@ static void rtl_hw_start_8125_common(str
+ r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
+ r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
++ else
++ r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
+ r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403);
+ r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0068);
+ r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f);
+@@ -3598,10 +3636,10 @@ static void rtl_hw_start_8125_common(str
+
+ rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10);
+
+- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+- rtl8125b_config_eee_mac(tp);
+- else
++ if (tp->mac_version == RTL_GIGA_MAC_VER_61)
+ rtl8125a_config_eee_mac(tp);
++ else
++ rtl8125b_config_eee_mac(tp);
+
+ rtl_disable_rxdvgate(tp);
+ }
+@@ -3645,6 +3683,12 @@ static void rtl_hw_start_8125b(struct rt
+ rtl_hw_start_8125_common(tp);
+ }
+
++static void rtl_hw_start_8126a(struct rtl8169_private *tp)
++{
++ rtl_set_def_aspm_entry_latency(tp);
++ rtl_hw_start_8125_common(tp);
++}
++
+ static void rtl_hw_config(struct rtl8169_private *tp)
+ {
+ static const rtl_generic_fct hw_configs[] = {
+@@ -3687,6 +3731,7 @@ static void rtl_hw_config(struct rtl8169
+ [RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
+ [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
+ [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
++ [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
+ };
+
+ if (hw_configs[tp->mac_version])
+@@ -3697,9 +3742,23 @@ static void rtl_hw_start_8125(struct rtl
+ {
+ int i;
+
++ RTL_W8(tp, INT_CFG0_8125, 0x00);
++
+ /* disable interrupt coalescing */
+- for (i = 0xa00; i < 0xb00; i += 4)
+- RTL_W32(tp, i, 0);
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_61:
++ for (i = 0xa00; i < 0xb00; i += 4)
++ RTL_W32(tp, i, 0);
++ break;
++ case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_65:
++ for (i = 0xa00; i < 0xa80; i += 4)
++ RTL_W32(tp, i, 0);
++ RTL_W16(tp, INT_CFG1_8125, 0x0000);
++ break;
++ default:
++ break;
++ }
+
+ rtl_hw_config(tp);
+ }
+@@ -3777,8 +3836,7 @@ static int rtl8169_change_mtu(struct net
+ rtl_jumbo_config(tp);
+
+ switch (tp->mac_version) {
+- case RTL_GIGA_MAC_VER_61:
+- case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ rtl8125_set_eee_txidle_timer(tp);
+ break;
+ default:
+@@ -3927,7 +3985,7 @@ static void rtl8169_cleanup(struct rtl81
+ RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
+ rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ rtl_enable_rxdvgate(tp);
+ fsleep(2000);
+ break;
+@@ -4078,8 +4136,7 @@ static unsigned int rtl_quirk_packet_pad
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_34:
+- case RTL_GIGA_MAC_VER_61:
+- case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ padto = max_t(unsigned int, padto, ETH_ZLEN);
+ break;
+ default:
+@@ -5112,7 +5169,7 @@ static void rtl_hw_initialize(struct rtl
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
+ rtl_hw_init_8168g(tp);
+ break;
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ rtl_hw_init_8125(tp);
+ break;
+ default:
+--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
++++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
+@@ -1102,6 +1102,12 @@ static void rtl8125b_hw_phy_config(struc
+ rtl8125b_config_eee_phy(phydev);
+ }
+
++static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
++ struct phy_device *phydev)
++{
++ r8169_apply_firmware(tp);
++}
++
+ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
+ enum mac_version ver)
+ {
+@@ -1152,6 +1158,7 @@ void r8169_hw_phy_config(struct rtl8169_
+ [RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
+ [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
+ [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
++ [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
+ };
+
+ if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch b/target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch
deleted file mode 100644
index cfe552046e..0000000000
--- a/target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 97e176fcbbf3c0f2bd410c9b241177c051f57176 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 10 Apr 2024 15:11:28 +0200
-Subject: [PATCH] r8169: add missing conditional compiling for call to
- r8169_remove_leds
-
-Add missing dependency on CONFIG_R8169_LEDS. As-is a link error occurs
-if config option CONFIG_R8169_LEDS isn't enabled.
-
-Fixes: 19fa4f2a85d7 ("r8169: fix LED-related deadlock on module removal")
-Reported-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Tested-By: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
-Link: https://lore.kernel.org/r/d080038c-eb6b-45ac-9237-b8c1cdd7870f@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5128,7 +5128,8 @@ static void rtl_remove_one(struct pci_de
-
- cancel_work_sync(&tp->wk.work);
-
-- r8169_remove_leds(tp->leds);
-+ if (IS_ENABLED(CONFIG_R8169_LEDS))
-+ r8169_remove_leds(tp->leds);
-
- unregister_netdev(tp->dev);
-
diff --git a/target/linux/generic/backport-6.6/780-04-v6.9-r8169-improve-checking-for-valid-LED-modes.patch b/target/linux/generic/backport-6.6/780-09-v6.9-r8169-improve-checking-for-valid-LED-modes.patch
index ae0c821267..ae0c821267 100644
--- a/target/linux/generic/backport-6.6/780-04-v6.9-r8169-improve-checking-for-valid-LED-modes.patch
+++ b/target/linux/generic/backport-6.6/780-09-v6.9-r8169-improve-checking-for-valid-LED-modes.patch
diff --git a/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch b/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch
new file mode 100644
index 0000000000..510123767a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch
@@ -0,0 +1,39 @@
+From 400909df6e6543cb5cce3db9bbcd413d59125327 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sat, 10 Feb 2024 17:58:29 +0100
+Subject: [PATCH] r8169: simplify code by using core-provided pcpu stats
+ allocation
+
+Use core-provided pcpu stats allocation instead of open-coding it in
+the driver.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/03f5bb3b-d7f4-48be-ae8a-54862ec4566c@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5261,11 +5261,6 @@ static int rtl_init_one(struct pci_dev *
+ raw_spin_lock_init(&tp->mac_ocp_lock);
+ mutex_init(&tp->led_lock);
+
+- dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
+- struct pcpu_sw_netstats);
+- if (!dev->tstats)
+- return -ENOMEM;
+-
+ /* Get the *optional* external "ether_clk" used on some boards */
+ tp->clk = devm_clk_get_optional_enabled(&pdev->dev, "ether_clk");
+ if (IS_ERR(tp->clk))
+@@ -5380,6 +5375,8 @@ static int rtl_init_one(struct pci_dev *
+ dev->hw_features |= NETIF_F_RXALL;
+ dev->hw_features |= NETIF_F_RXFCS;
+
++ dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
++
+ netdev_sw_irq_coalesce_default_on(dev);
+
+ /* configure chip for default features */
diff --git a/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch b/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
new file mode 100644
index 0000000000..2059551b50
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
@@ -0,0 +1,244 @@
+From be51ed104ba9929c741afb718ef7198dbcecef94 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:44:11 +0100
+Subject: [PATCH] r8169: add LED support for RTL8125/RTL8126
+
+This adds LED support for RTL8125/RTL8126.
+
+Note: Due to missing datasheets changing the 5Gbps link mode isn't
+supported for RTL8126.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/f982602c-9de3-4ca6-85a3-2c1d118dcb15@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169.h | 3 +
+ drivers/net/ethernet/realtek/r8169_leds.c | 106 ++++++++++++++++++++++
+ drivers/net/ethernet/realtek/r8169_main.c | 61 ++++++++++++-
+ 3 files changed, 166 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -85,3 +85,6 @@ void r8169_get_led_name(struct rtl8169_p
+ int rtl8168_get_led_mode(struct rtl8169_private *tp);
+ int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
+ void rtl8168_init_leds(struct net_device *ndev);
++int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
++int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
++void rtl8125_init_leds(struct net_device *ndev);
+--- a/drivers/net/ethernet/realtek/r8169_leds.c
++++ b/drivers/net/ethernet/realtek/r8169_leds.c
+@@ -18,7 +18,14 @@
+ #define RTL8168_LED_CTRL_LINK_100 BIT(1)
+ #define RTL8168_LED_CTRL_LINK_10 BIT(0)
+
++#define RTL8125_LED_CTRL_ACT BIT(9)
++#define RTL8125_LED_CTRL_LINK_2500 BIT(5)
++#define RTL8125_LED_CTRL_LINK_1000 BIT(3)
++#define RTL8125_LED_CTRL_LINK_100 BIT(1)
++#define RTL8125_LED_CTRL_LINK_10 BIT(0)
++
+ #define RTL8168_NUM_LEDS 3
++#define RTL8125_NUM_LEDS 4
+
+ struct r8169_led_classdev {
+ struct led_classdev led;
+@@ -157,3 +164,102 @@ void rtl8168_init_leds(struct net_device
+ for (i = 0; i < RTL8168_NUM_LEDS; i++)
+ rtl8168_setup_ldev(leds + i, ndev, i);
+ }
++
++static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++
++ if (!r8169_trigger_mode_is_valid(flags)) {
++ /* Switch LED off to indicate that mode isn't supported */
++ rtl8125_set_led_mode(tp, ldev->index, 0);
++ return -EOPNOTSUPP;
++ }
++
++ return 0;
++}
++
++static int rtl8125_led_hw_control_set(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ u16 mode = 0;
++
++ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
++ mode |= RTL8125_LED_CTRL_LINK_10;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
++ mode |= RTL8125_LED_CTRL_LINK_100;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
++ mode |= RTL8125_LED_CTRL_LINK_1000;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_2500))
++ mode |= RTL8125_LED_CTRL_LINK_2500;
++ if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX)))
++ mode |= RTL8125_LED_CTRL_ACT;
++
++ return rtl8125_set_led_mode(tp, ldev->index, mode);
++}
++
++static int rtl8125_led_hw_control_get(struct led_classdev *led_cdev,
++ unsigned long *flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int mode;
++
++ mode = rtl8125_get_led_mode(tp, ldev->index);
++ if (mode < 0)
++ return mode;
++
++ if (mode & RTL8125_LED_CTRL_LINK_10)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
++ if (mode & RTL8125_LED_CTRL_LINK_100)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
++ if (mode & RTL8125_LED_CTRL_LINK_1000)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
++ if (mode & RTL8125_LED_CTRL_LINK_2500)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_2500);
++ if (mode & RTL8125_LED_CTRL_ACT)
++ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
++
++ return 0;
++}
++
++static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev,
++ struct net_device *ndev, int index)
++{
++ struct rtl8169_private *tp = netdev_priv(ndev);
++ struct led_classdev *led_cdev = &ldev->led;
++ char led_name[LED_MAX_NAME_SIZE];
++
++ ldev->ndev = ndev;
++ ldev->index = index;
++
++ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
++ led_cdev->name = led_name;
++ led_cdev->hw_control_trigger = "netdev";
++ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
++ led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;
++ led_cdev->hw_control_set = rtl8125_led_hw_control_set;
++ led_cdev->hw_control_get = rtl8125_led_hw_control_get;
++ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
++
++ /* ignore errors */
++ devm_led_classdev_register(&ndev->dev, led_cdev);
++}
++
++void rtl8125_init_leds(struct net_device *ndev)
++{
++ /* bind resource mgmt to netdev */
++ struct device *dev = &ndev->dev;
++ struct r8169_led_classdev *leds;
++ int i;
++
++ leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ if (!leds)
++ return;
++
++ for (i = 0; i < RTL8125_NUM_LEDS; i++)
++ rtl8125_setup_led_ldev(leds + i, ndev, i);
++}
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -330,17 +330,23 @@ enum rtl8168_registers {
+ };
+
+ enum rtl8125_registers {
++ LEDSEL0 = 0x18,
+ INT_CFG0_8125 = 0x34,
+ #define INT_CFG0_ENABLE_8125 BIT(0)
+ #define INT_CFG0_CLKREQEN BIT(3)
+ IntrMask_8125 = 0x38,
+ IntrStatus_8125 = 0x3c,
+ INT_CFG1_8125 = 0x7a,
++ LEDSEL2 = 0x84,
++ LEDSEL1 = 0x86,
+ TxPoll_8125 = 0x90,
++ LEDSEL3 = 0x96,
+ MAC0_BKP = 0x19e0,
+ EEE_TXIDLE_TIMER_8125 = 0x6048,
+ };
+
++#define LEDSEL_MASK_8125 0x23f
++
+ #define RX_VLAN_INNER_8125 BIT(22)
+ #define RX_VLAN_OUTER_8125 BIT(23)
+ #define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125)
+@@ -830,6 +836,51 @@ int rtl8168_get_led_mode(struct rtl8169_
+ return ret;
+ }
+
++static int rtl8125_get_led_reg(int index)
++{
++ static const int led_regs[] = { LEDSEL0, LEDSEL1, LEDSEL2, LEDSEL3 };
++
++ return led_regs[index];
++}
++
++int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode)
++{
++ int reg = rtl8125_get_led_reg(index);
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++ u16 val;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ mutex_lock(&tp->led_lock);
++ val = RTL_R16(tp, reg) & ~LEDSEL_MASK_8125;
++ RTL_W16(tp, reg, val | mode);
++ mutex_unlock(&tp->led_lock);
++
++ pm_runtime_put_sync(dev);
++
++ return 0;
++}
++
++int rtl8125_get_led_mode(struct rtl8169_private *tp, int index)
++{
++ int reg = rtl8125_get_led_reg(index);
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ ret = RTL_R16(tp, reg);
++
++ pm_runtime_put_sync(dev);
++
++ return ret;
++}
++
+ void r8169_get_led_name(struct rtl8169_private *tp, int idx,
+ char *buf, int buf_len)
+ {
+@@ -5413,10 +5464,12 @@ static int rtl_init_one(struct pci_dev *
+ if (rc)
+ return rc;
+
+- if (IS_ENABLED(CONFIG_R8169_LEDS) &&
+- tp->mac_version > RTL_GIGA_MAC_VER_06 &&
+- tp->mac_version < RTL_GIGA_MAC_VER_61)
+- rtl8168_init_leds(dev);
++ if (IS_ENABLED(CONFIG_R8169_LEDS)) {
++ if (rtl_is_8125(tp))
++ rtl8125_init_leds(dev);
++ else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
++ rtl8168_init_leds(dev);
++ }
+
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
+ rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch b/target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch
new file mode 100644
index 0000000000..1a7eed191f
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch
@@ -0,0 +1,91 @@
+From 2ce30993831041b9dcd31eb12896be6611e8b7e2 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:57:46 +0100
+Subject: [PATCH] r8169: add generic rtl_set_eee_txidle_timer function
+
+Add a generic setter for the EEE tx idle timer and use it with all
+RTL8125/RTL8126 chip versions, in line with the vendor driver.
+This prepares for adding EEE tx idle timer support for additional
+chip versions.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/39beed72-0dc4-4c45-8899-b72c43ab62a7@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 34 +++++++++++++----------
+ 1 file changed, 20 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -619,6 +619,7 @@ struct rtl8169_private {
+ struct page *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */
+ struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */
+ u16 cp_cmd;
++ u16 tx_lpi_timer;
+ u32 irq_mask;
+ int irq;
+ struct clk *clk;
+@@ -2054,6 +2055,22 @@ static int rtl_set_coalesce(struct net_d
+ return 0;
+ }
+
++static void rtl_set_eee_txidle_timer(struct rtl8169_private *tp)
++{
++ unsigned int timer_val = READ_ONCE(tp->dev->mtu) + ETH_HLEN + 0x20;
++
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_61:
++ case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_65:
++ tp->tx_lpi_timer = timer_val;
++ RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
++ break;
++ default:
++ break;
++ }
++}
++
+ static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+@@ -2312,14 +2329,8 @@ static void rtl8125a_config_eee_mac(stru
+ r8168_mac_ocp_modify(tp, 0xeb62, 0, BIT(2) | BIT(1));
+ }
+
+-static void rtl8125_set_eee_txidle_timer(struct rtl8169_private *tp)
+-{
+- RTL_W16(tp, EEE_TXIDLE_TIMER_8125, tp->dev->mtu + ETH_HLEN + 0x20);
+-}
+-
+ static void rtl8125b_config_eee_mac(struct rtl8169_private *tp)
+ {
+- rtl8125_set_eee_txidle_timer(tp);
+ r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0));
+ }
+
+@@ -3852,6 +3863,8 @@ static void rtl_hw_start(struct rtl8169
+ rtl_hw_aspm_clkreq_enable(tp, false);
+ RTL_W16(tp, CPlusCmd, tp->cp_cmd);
+
++ rtl_set_eee_txidle_timer(tp);
++
+ if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
+ rtl_hw_start_8169(tp);
+ else if (rtl_is_8125(tp))
+@@ -3885,14 +3898,7 @@ static int rtl8169_change_mtu(struct net
+ dev->mtu = new_mtu;
+ netdev_update_features(dev);
+ rtl_jumbo_config(tp);
+-
+- switch (tp->mac_version) {
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+- rtl8125_set_eee_txidle_timer(tp);
+- break;
+- default:
+- break;
+- }
++ rtl_set_eee_txidle_timer(tp);
+
+ return 0;
+ }
diff --git a/target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch b/target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch
new file mode 100644
index 0000000000..917c7c194f
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch
@@ -0,0 +1,30 @@
+From 57d2d2c8f132c830565058a5cdd8138350e068ec Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:58:47 +0100
+Subject: [PATCH] r8169: support setting the EEE tx idle timer on
+ RTL8168h
+
+Support setting the EEE tx idle timer also on RTL8168h.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/cfb69ec9-24c4-4aad-9909-fdae3088add4@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2060,6 +2060,11 @@ static void rtl_set_eee_txidle_timer(str
+ unsigned int timer_val = READ_ONCE(tp->dev->mtu) + ETH_HLEN + 0x20;
+
+ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_46:
++ case RTL_GIGA_MAC_VER_48:
++ tp->tx_lpi_timer = timer_val;
++ r8168_mac_ocp_write(tp, 0xe048, timer_val);
++ break;
+ case RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_63:
+ case RTL_GIGA_MAC_VER_65:
diff --git a/target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch b/target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch
new file mode 100644
index 0000000000..51477d0142
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch
@@ -0,0 +1,55 @@
+From 9c50139727265c088f936e496777bf588850e9f1 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:59:26 +0100
+Subject: [PATCH] r8169: add support for returning tx_lpi_timer in
+ ethtool get_eee
+
+Add support for returning the tx_lpi_timer value to userspace.
+This is supported by few chip versions only: RTL8168h/RTL8125/RTL8126
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/4eee9c34-c5d6-4c96-9b05-455896dea59a@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2076,14 +2076,34 @@ static void rtl_set_eee_txidle_timer(str
+ }
+ }
+
++static unsigned int r8169_get_tx_lpi_timer_us(struct rtl8169_private *tp)
++{
++ unsigned int speed = tp->phydev->speed;
++ unsigned int timer = tp->tx_lpi_timer;
++
++ if (!timer || speed == SPEED_UNKNOWN)
++ return 0;
++
++ /* tx_lpi_timer value is in bytes */
++ return DIV_ROUND_CLOSEST(timer * BITS_PER_BYTE, speed);
++}
++
+ static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
++ int ret;
+
+ if (!rtl_supports_eee(tp))
+ return -EOPNOTSUPP;
+
+- return phy_ethtool_get_eee(tp->phydev, data);
++ ret = phy_ethtool_get_eee(tp->phydev, data);
++ if (ret)
++ return ret;
++
++ data->tx_lpi_timer = r8169_get_tx_lpi_timer_us(tp);
++ data->tx_lpi_enabled = data->tx_lpi_timer ? data->eee_enabled : false;
++
++ return 0;
+ }
+
+ static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
diff --git a/target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
new file mode 100644
index 0000000000..6a7ebc885b
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
@@ -0,0 +1,25 @@
+From f4d3e595c0000ce39dec7e4799ea42ce42ab6867 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sat, 17 Feb 2024 15:48:23 +0100
+Subject: [PATCH] r8169: add MODULE_FIRMWARE entry for RTL8126A
+
+Add the missing MODULE_FIRMWARE entry for RTL8126A.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/47ef79d2-59c4-4d44-9595-366c70c4ad87@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -676,6 +676,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
+ MODULE_FIRMWARE(FIRMWARE_8107E_2);
+ MODULE_FIRMWARE(FIRMWARE_8125A_3);
+ MODULE_FIRMWARE(FIRMWARE_8125B_2);
++MODULE_FIRMWARE(FIRMWARE_8126A_2);
+
+ static inline struct device *tp_to_dev(struct rtl8169_private *tp)
+ {
diff --git a/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch b/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch
new file mode 100644
index 0000000000..d8e4a4f6ff
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch
@@ -0,0 +1,147 @@
+From 19fa4f2a85d777a8052e869c1b892a2f7556569d Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 8 Apr 2024 20:47:40 +0200
+Subject: [PATCH] r8169: fix LED-related deadlock on module removal
+
+Binding devm_led_classdev_register() to the netdev is problematic
+because on module removal we get a RTNL-related deadlock. Fix this
+by avoiding the device-managed LED functions.
+
+Note: We can safely call led_classdev_unregister() for a LED even
+if registering it failed, because led_classdev_unregister() detects
+this and is a no-op in this case.
+
+Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
+Cc: stable@vger.kernel.org
+Reported-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169.h | 6 ++--
+ drivers/net/ethernet/realtek/r8169_leds.c | 35 +++++++++++++++--------
+ drivers/net/ethernet/realtek/r8169_main.c | 8 ++++--
+ 3 files changed, 33 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -73,6 +73,7 @@ enum mac_version {
+ };
+
+ struct rtl8169_private;
++struct r8169_led_classdev;
+
+ void r8169_apply_firmware(struct rtl8169_private *tp);
+ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
+@@ -84,7 +85,8 @@ void r8169_get_led_name(struct rtl8169_p
+ char *buf, int buf_len);
+ int rtl8168_get_led_mode(struct rtl8169_private *tp);
+ int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
+-void rtl8168_init_leds(struct net_device *ndev);
++struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev);
+ int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
+ int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
+-void rtl8125_init_leds(struct net_device *ndev);
++struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev);
++void r8169_remove_leds(struct r8169_led_classdev *leds);
+--- a/drivers/net/ethernet/realtek/r8169_leds.c
++++ b/drivers/net/ethernet/realtek/r8169_leds.c
+@@ -147,22 +147,22 @@ static void rtl8168_setup_ldev(struct r8
+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
+
+ /* ignore errors */
+- devm_led_classdev_register(&ndev->dev, led_cdev);
++ led_classdev_register(&ndev->dev, led_cdev);
+ }
+
+-void rtl8168_init_leds(struct net_device *ndev)
++struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev)
+ {
+- /* bind resource mgmt to netdev */
+- struct device *dev = &ndev->dev;
+ struct r8169_led_classdev *leds;
+ int i;
+
+- leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
+ if (!leds)
+- return;
++ return NULL;
+
+ for (i = 0; i < RTL8168_NUM_LEDS; i++)
+ rtl8168_setup_ldev(leds + i, ndev, i);
++
++ return leds;
+ }
+
+ static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
+@@ -246,20 +246,31 @@ static void rtl8125_setup_led_ldev(struc
+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
+
+ /* ignore errors */
+- devm_led_classdev_register(&ndev->dev, led_cdev);
++ led_classdev_register(&ndev->dev, led_cdev);
+ }
+
+-void rtl8125_init_leds(struct net_device *ndev)
++struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev)
+ {
+- /* bind resource mgmt to netdev */
+- struct device *dev = &ndev->dev;
+ struct r8169_led_classdev *leds;
+ int i;
+
+- leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ leds = kcalloc(RTL8125_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
+ if (!leds)
+- return;
++ return NULL;
+
+ for (i = 0; i < RTL8125_NUM_LEDS; i++)
+ rtl8125_setup_led_ldev(leds + i, ndev, i);
++
++ return leds;
++}
++
++void r8169_remove_leds(struct r8169_led_classdev *leds)
++{
++ if (!leds)
++ return;
++
++ for (struct r8169_led_classdev *l = leds; l->ndev; l++)
++ led_classdev_unregister(&l->led);
++
++ kfree(leds);
+ }
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -647,6 +647,8 @@ struct rtl8169_private {
+ const char *fw_name;
+ struct rtl_fw *rtl_fw;
+
++ struct r8169_led_classdev *leds;
++
+ u32 ocp_base;
+ };
+
+@@ -5040,6 +5042,8 @@ static void rtl_remove_one(struct pci_de
+
+ cancel_work_sync(&tp->wk.work);
+
++ r8169_remove_leds(tp->leds);
++
+ unregister_netdev(tp->dev);
+
+ if (tp->dash_type != RTL_DASH_NONE)
+@@ -5498,9 +5502,9 @@ static int rtl_init_one(struct pci_dev *
+
+ if (IS_ENABLED(CONFIG_R8169_LEDS)) {
+ if (rtl_is_8125(tp))
+- rtl8125_init_leds(dev);
++ tp->leds = rtl8125_init_leds(dev);
+ else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
+- rtl8168_init_leds(dev);
++ tp->leds = rtl8168_init_leds(dev);
+ }
+
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
diff --git a/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch b/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch
new file mode 100644
index 0000000000..366ae803f9
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch
@@ -0,0 +1,31 @@
+From 97e176fcbbf3c0f2bd410c9b241177c051f57176 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 10 Apr 2024 15:11:28 +0200
+Subject: [PATCH] r8169: add missing conditional compiling for call to
+ r8169_remove_leds
+
+Add missing dependency on CONFIG_R8169_LEDS. As-is a link error occurs
+if config option CONFIG_R8169_LEDS isn't enabled.
+
+Fixes: 19fa4f2a85d7 ("r8169: fix LED-related deadlock on module removal")
+Reported-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Tested-By: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
+Link: https://lore.kernel.org/r/d080038c-eb6b-45ac-9237-b8c1cdd7870f@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5042,7 +5042,8 @@ static void rtl_remove_one(struct pci_de
+
+ cancel_work_sync(&tp->wk.work);
+
+- r8169_remove_leds(tp->leds);
++ if (IS_ENABLED(CONFIG_R8169_LEDS))
++ r8169_remove_leds(tp->leds);
+
+ unregister_netdev(tp->dev);
+
diff --git a/target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch b/target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch
new file mode 100644
index 0000000000..2abbe2ccf1
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch
@@ -0,0 +1,30 @@
+From 39f59c72ad3a1eaab9a60f0671bc94d2bc826d21 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sun, 7 Apr 2024 23:19:25 +0200
+Subject: [PATCH] r8169: add support for RTL8168M
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A user reported an unknown chip version. According to the r8168 vendor
+driver it's called RTL8168M, but handling is identical to RTL8168H.
+So let's simply treat it as RTL8168H.
+
+Tested-by: Евгений <octobergun@gmail.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2230,6 +2230,8 @@ static enum mac_version rtl8169_get_mac_
+ * the wild. Let's disable detection.
+ * { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 },
+ */
++ /* Realtek calls it RTL8168M, but it's handled like RTL8168H */
++ { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46 },
+
+ /* 8168G family. */
+ { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 },
diff --git a/target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch b/target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch
new file mode 100644
index 0000000000..cad1210e4d
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch
@@ -0,0 +1,60 @@
+From 1eb2cded45b35816085c1f962933c187d970f9dc Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 6 May 2024 10:28:12 +0000
+Subject: [PATCH] net: annotate writes on dev->mtu from ndo_change_mtu()
+
+Simon reported that ndo_change_mtu() methods were never
+updated to use WRITE_ONCE(dev->mtu, new_mtu) as hinted
+in commit 501a90c94510 ("inet: protect against too small
+mtu values.")
+
+We read dev->mtu without holding RTNL in many places,
+with READ_ONCE() annotations.
+
+It is time to take care of ndo_change_mtu() methods
+to use corresponding WRITE_ONCE()
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Simon Horman <horms@kernel.org>
+Closes: https://lore.kernel.org/netdev/20240505144608.GB67882@kernel.org/
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Shannon Nelson <shannon.nelson@amd.com>
+Link: https://lore.kernel.org/r/20240506102812.3025432-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/8139cp.c | 4 ++--
+ drivers/net/ethernet/realtek/r8169_main.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/8139cp.c
++++ b/drivers/net/ethernet/realtek/8139cp.c
+@@ -1277,14 +1277,14 @@ static int cp_change_mtu(struct net_devi
+
+ /* if network interface not up, no need for complexity */
+ if (!netif_running(dev)) {
+- dev->mtu = new_mtu;
++ WRITE_ONCE(dev->mtu, new_mtu);
+ cp_set_rxbufsize(cp); /* set new rx buf size */
+ return 0;
+ }
+
+ /* network IS up, close it, reset MTU, and come up again. */
+ cp_close(dev);
+- dev->mtu = new_mtu;
++ WRITE_ONCE(dev->mtu, new_mtu);
+ cp_set_rxbufsize(cp);
+ return cp_open(dev);
+ }
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -3925,7 +3925,7 @@ static int rtl8169_change_mtu(struct net
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+- dev->mtu = new_mtu;
++ WRITE_ONCE(dev->mtu, new_mtu);
+ netdev_update_features(dev);
+ rtl_jumbo_config(tp);
+ rtl_set_eee_txidle_timer(tp);
diff --git a/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch b/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch
new file mode 100644
index 0000000000..cef5d95252
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch
@@ -0,0 +1,34 @@
+From 6994520a332887f1688464f250c9ec8002a89a8e Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 May 2024 21:16:56 +0200
+Subject: [PATCH] r8169: disable interrupt source RxOverflow
+
+Vendor driver calls this bit RxDescUnavail. All we do in the interrupt
+handler in this case is scheduling NAPI. If we should be out of
+RX descriptors, then NAPI is scheduled anyway. Therefore remove this
+interrupt source. Tested on RTL8168h.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Sunil Goutham <sgoutham@marvell.com>
+Link: https://lore.kernel.org/r/9b2054b2-0548-4f48-bf91-b646572093b4@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5083,12 +5083,10 @@ static void rtl_set_irq_mask(struct rtl8
+ tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg;
+
+ if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
+- tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver;
++ tp->irq_mask |= SYSErr | RxFIFOOver;
+ else if (tp->mac_version == RTL_GIGA_MAC_VER_11)
+ /* special workaround needed */
+ tp->irq_mask |= RxFIFOOver;
+- else
+- tp->irq_mask |= RxOverflow;
+ }
+
+ static int rtl_alloc_irq(struct rtl8169_private *tp)
diff --git a/target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch b/target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch
new file mode 100644
index 0000000000..7f0f23fccb
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch
@@ -0,0 +1,32 @@
+From 982300c115d229565d7af8e8b38aa1ee7bb1f5bd Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 May 2024 21:20:16 +0200
+Subject: [PATCH] r8169: remove detection of chip version 11 (early
+ RTL8168b)
+
+This early RTL8168b version was the first PCIe chip version, and it's
+quite quirky. Last sign of life is from more than 15 yrs ago.
+Let's remove detection of this chip version, we'll see whether anybody
+complains. If not, support for this chip version can be removed a few
+kernel versions later.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/875cdcf4-843c-420a-ad5d-417447b68572@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2275,7 +2275,9 @@ static enum mac_version rtl8169_get_mac_
+
+ /* 8168B family. */
+ { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 },
+- { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 },
++ /* This one is very old and rare, let's see if anybody complains.
++ * { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 },
++ */
+
+ /* 8101 family. */
+ { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 },
diff --git a/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch b/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch
new file mode 100644
index 0000000000..a8ba1a5719
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch
@@ -0,0 +1,245 @@
+From 69cb89981c7a181d857b634c0740e914d5df79ea Mon Sep 17 00:00:00 2001
+From: ChunHao Lin <hau@realtek.com>
+Date: Fri, 30 Aug 2024 10:18:10 +0800
+Subject: [PATCH 43/47] r8169: add support for RTL8126A rev.b
+
+Add support for RTL8126A rev.b. Its XID is 0x64a. It is basically
+based on the one with XID 0x649, but with different firmware file.
+
+Signed-off-by: ChunHao Lin <hau@realtek.com>
+Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://patch.msgid.link/20240830021810.11993-1-hau@realtek.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169.h | 1 +
+ drivers/net/ethernet/realtek/r8169_main.c | 42 ++++++++++++-------
+ .../net/ethernet/realtek/r8169_phy_config.c | 1 +
+ 3 files changed, 29 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -69,6 +69,7 @@ enum mac_version {
+ RTL_GIGA_MAC_VER_61,
+ RTL_GIGA_MAC_VER_63,
+ RTL_GIGA_MAC_VER_65,
++ RTL_GIGA_MAC_VER_66,
+ RTL_GIGA_MAC_NONE
+ };
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -56,6 +56,7 @@
+ #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
+ #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
+ #define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
++#define FIRMWARE_8126A_3 "rtl_nic/rtl8126a-3.fw"
+
+ #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
+ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
+@@ -138,6 +139,7 @@ static const struct {
+ /* reserve 62 for CFG_METHOD_4 in the vendor driver */
+ [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
+ [RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
++ [RTL_GIGA_MAC_VER_66] = {"RTL8126A", FIRMWARE_8126A_3},
+ };
+
+ static const struct pci_device_id rtl8169_pci_tbl[] = {
+@@ -1201,7 +1203,7 @@ static void rtl_writephy(struct rtl8169_
+ case RTL_GIGA_MAC_VER_31:
+ r8168dp_2_mdio_write(tp, location, val);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
+ r8168g_mdio_write(tp, location, val);
+ break;
+ default:
+@@ -1216,7 +1218,7 @@ static int rtl_readphy(struct rtl8169_pr
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ return r8168dp_2_mdio_read(tp, location);
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
+ return r8168g_mdio_read(tp, location);
+ default:
+ return r8169_mdio_read(tp, location);
+@@ -1425,7 +1427,7 @@ static void rtl_set_d3_pll_down(struct r
+ case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
+ case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
+- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
+ if (enable)
+ RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
+ else
+@@ -1592,7 +1594,7 @@ static void __rtl8169_set_wol(struct rtl
+ break;
+ case RTL_GIGA_MAC_VER_34:
+ case RTL_GIGA_MAC_VER_37:
+- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
+ if (wolopts)
+ rtl_mod_config2(tp, 0, PME_SIGNAL);
+ else
+@@ -2071,6 +2073,7 @@ static void rtl_set_eee_txidle_timer(str
+ case RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_63:
+ case RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_66:
+ tp->tx_lpi_timer = timer_val;
+ RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
+ break;
+@@ -2200,6 +2203,7 @@ static enum mac_version rtl8169_get_mac_
+ enum mac_version ver;
+ } mac_info[] = {
+ /* 8126A family. */
++ { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_66 },
+ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
+
+ /* 8125B family. */
+@@ -2471,6 +2475,7 @@ static void rtl_init_rxcfg(struct rtl816
+ break;
+ case RTL_GIGA_MAC_VER_63:
+ case RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_66:
+ RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
+ RX_PAUSE_SLOT_ON);
+ break;
+@@ -2657,7 +2662,7 @@ static void rtl_wait_txrx_fifo_empty(str
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
+ break;
+- case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66:
+ RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
+@@ -2900,7 +2905,7 @@ static void rtl_enable_exit_l1(struct rt
+ case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
+ rtl_eri_set_bits(tp, 0xd4, 0x0c00);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
+ r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
+ break;
+ default:
+@@ -2914,7 +2919,7 @@ static void rtl_disable_exit_l1(struct r
+ case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
+ rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
+ r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
+ break;
+ default:
+@@ -2941,6 +2946,7 @@ static void rtl_hw_aspm_clkreq_enable(st
+ rtl_mod_config5(tp, 0, ASPM_en);
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_66:
+ val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
+ RTL_W8(tp, INT_CFG0_8125, val8);
+ break;
+@@ -2951,7 +2957,7 @@ static void rtl_hw_aspm_clkreq_enable(st
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
+ /* reset ephy tx/rx disable timer */
+ r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
+ /* chip can trigger L1.2 */
+@@ -2963,7 +2969,7 @@ static void rtl_hw_aspm_clkreq_enable(st
+ } else {
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
+ r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
+ break;
+ default:
+@@ -2972,6 +2978,7 @@ static void rtl_hw_aspm_clkreq_enable(st
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_66:
+ val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
+ RTL_W8(tp, INT_CFG0_8125, val8);
+ break;
+@@ -3691,10 +3698,12 @@ static void rtl_hw_start_8125_common(str
+ /* disable new tx descriptor format */
+ r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
+
+- if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
++ tp->mac_version == RTL_GIGA_MAC_VER_66)
+ RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
+
+- if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
++ tp->mac_version == RTL_GIGA_MAC_VER_66)
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
+ else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
+@@ -3712,7 +3721,8 @@ static void rtl_hw_start_8125_common(str
+ r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
+ r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
+- if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
++ tp->mac_version == RTL_GIGA_MAC_VER_66)
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
+ else
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
+@@ -3826,6 +3836,7 @@ static void rtl_hw_config(struct rtl8169
+ [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
+ [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
+ [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
++ [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8126a,
+ };
+
+ if (hw_configs[tp->mac_version])
+@@ -3846,6 +3857,7 @@ static void rtl_hw_start_8125(struct rtl
+ break;
+ case RTL_GIGA_MAC_VER_63:
+ case RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_66:
+ for (i = 0xa00; i < 0xa80; i += 4)
+ RTL_W32(tp, i, 0);
+ RTL_W16(tp, INT_CFG1_8125, 0x0000);
+@@ -4074,7 +4086,7 @@ static void rtl8169_cleanup(struct rtl81
+ RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
+ rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
+ rtl_enable_rxdvgate(tp);
+ fsleep(2000);
+ break;
+@@ -4225,7 +4237,7 @@ static unsigned int rtl_quirk_packet_pad
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_34:
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
+ padto = max_t(unsigned int, padto, ETH_ZLEN);
+ break;
+ default:
+@@ -5259,7 +5271,7 @@ static void rtl_hw_initialize(struct rtl
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
+ rtl_hw_init_8168g(tp);
+ break;
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
+ rtl_hw_init_8125(tp);
+ break;
+ default:
+--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
++++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
+@@ -1159,6 +1159,7 @@ void r8169_hw_phy_config(struct rtl8169_
+ [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
+ [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
+ [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
++ [RTL_GIGA_MAC_VER_66] = rtl8126a_hw_phy_config,
+ };
+
+ if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.6/780-23-v6.12-r8169-Fix-spelling-mistake-tx_underun-tx_underrun.patch b/target/linux/generic/backport-6.6/780-23-v6.12-r8169-Fix-spelling-mistake-tx_underun-tx_underrun.patch
new file mode 100644
index 0000000000..9d0992fcbb
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-23-v6.12-r8169-Fix-spelling-mistake-tx_underun-tx_underrun.patch
@@ -0,0 +1,38 @@
+From 8df9439389a44fb2cc4ef695e08d6a8870b1616c Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.i.king@gmail.com>
+Date: Mon, 9 Sep 2024 15:00:21 +0100
+Subject: [PATCH 44/47] r8169: Fix spelling mistake: "tx_underun" ->
+ "tx_underrun"
+
+There is a spelling mistake in the struct field tx_underun, rename
+it to tx_underrun.
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://patch.msgid.link/20240909140021.64884-1-colin.i.king@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -578,7 +578,7 @@ struct rtl8169_counters {
+ __le64 rx_broadcast;
+ __le32 rx_multicast;
+ __le16 tx_aborted;
+- __le16 tx_underun;
++ __le16 tx_underrun;
+ };
+
+ struct rtl8169_tc_offsets {
+@@ -1843,7 +1843,7 @@ static void rtl8169_get_ethtool_stats(st
+ data[9] = le64_to_cpu(counters->rx_broadcast);
+ data[10] = le32_to_cpu(counters->rx_multicast);
+ data[11] = le16_to_cpu(counters->tx_aborted);
+- data[12] = le16_to_cpu(counters->tx_underun);
++ data[12] = le16_to_cpu(counters->tx_underrun);
+ }
+
+ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
diff --git a/target/linux/generic/backport-6.6/780-24-v6.12-r8169-disable-ALDPS-per-default-for-RTL8125.patch b/target/linux/generic/backport-6.6/780-24-v6.12-r8169-disable-ALDPS-per-default-for-RTL8125.patch
new file mode 100644
index 0000000000..db37c484cf
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-24-v6.12-r8169-disable-ALDPS-per-default-for-RTL8125.patch
@@ -0,0 +1,41 @@
+From b9c7ac4fe22c608acf6153a3329df2b6b6cd416c Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 11 Sep 2024 15:51:11 +0200
+Subject: [PATCH 45/47] r8169: disable ALDPS per default for RTL8125
+
+En-Wei reported that traffic breaks if cable is unplugged for more
+than 3s and then re-plugged. This was supposed to be fixed by
+621735f59064 ("r8169: fix rare issue with broken rx after link-down on
+RTL8125"). But apparently this didn't fix the issue for everybody.
+The 3s threshold rang a bell, as this is the delay after which ALDPS
+kicks in. And indeed disabling ALDPS fixes the issue for this user.
+Maybe this fixes the issue in general. In a follow-up step we could
+remove the first fix attempt and see whether anybody complains.
+
+Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
+Tested-by: En-Wei WU <en-wei.wu@canonical.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://patch.msgid.link/778b9d86-05c4-4856-be59-cde4487b9e52@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_phy_config.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
++++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
+@@ -1060,6 +1060,7 @@ static void rtl8125a_2_hw_phy_config(str
+ phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000);
+ rtl8168g_enable_gphy_10m(phydev);
+
++ rtl8168g_disable_aldps(phydev);
+ rtl8125a_config_eee_phy(phydev);
+ }
+
+@@ -1099,6 +1100,7 @@ static void rtl8125b_hw_phy_config(struc
+ phy_modify_paged(phydev, 0xbf8, 0x12, 0xe000, 0xa000);
+
+ rtl8125_legacy_force_mode(phydev);
++ rtl8168g_disable_aldps(phydev);
+ rtl8125b_config_eee_phy(phydev);
+ }
+
diff --git a/target/linux/generic/backport-6.6/780-25-v6.12-r8169-add-tally-counter-fields-added-with-RTL8125.patch b/target/linux/generic/backport-6.6/780-25-v6.12-r8169-add-tally-counter-fields-added-with-RTL8125.patch
new file mode 100644
index 0000000000..3b1110fb67
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-25-v6.12-r8169-add-tally-counter-fields-added-with-RTL8125.patch
@@ -0,0 +1,56 @@
+From ced8e8b8f40accfcce4a2bbd8b150aa76d5eff9a Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Tue, 17 Sep 2024 23:04:46 +0200
+Subject: [PATCH 46/47] r8169: add tally counter fields added with RTL8125
+
+RTL8125 added fields to the tally counter, what may result in the chip
+dma'ing these new fields to unallocated memory. Therefore make sure
+that the allocated memory area is big enough to hold all of the
+tally counter values, even if we use only parts of it.
+
+Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/741d26a9-2b2b-485d-91d9-ecb302e345b5@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 27 +++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -579,6 +579,33 @@ struct rtl8169_counters {
+ __le32 rx_multicast;
+ __le16 tx_aborted;
+ __le16 tx_underrun;
++ /* new since RTL8125 */
++ __le64 tx_octets;
++ __le64 rx_octets;
++ __le64 rx_multicast64;
++ __le64 tx_unicast64;
++ __le64 tx_broadcast64;
++ __le64 tx_multicast64;
++ __le32 tx_pause_on;
++ __le32 tx_pause_off;
++ __le32 tx_pause_all;
++ __le32 tx_deferred;
++ __le32 tx_late_collision;
++ __le32 tx_all_collision;
++ __le32 tx_aborted32;
++ __le32 align_errors32;
++ __le32 rx_frame_too_long;
++ __le32 rx_runt;
++ __le32 rx_pause_on;
++ __le32 rx_pause_off;
++ __le32 rx_pause_all;
++ __le32 rx_unknown_opcode;
++ __le32 rx_mac_error;
++ __le32 tx_underrun32;
++ __le32 rx_mac_missed;
++ __le32 rx_tcam_dropped;
++ __le32 tdu;
++ __le32 rdu;
+ };
+
+ struct rtl8169_tc_offsets {
diff --git a/target/linux/generic/backport-6.6/780-26-v6.12-r8169-add-missing-MODULE_FIRMWARE-entry-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-26-v6.12-r8169-add-missing-MODULE_FIRMWARE-entry-for-RTL8126A.patch
new file mode 100644
index 0000000000..13bbc2ab11
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-26-v6.12-r8169-add-missing-MODULE_FIRMWARE-entry-for-RTL8126A.patch
@@ -0,0 +1,26 @@
+From 3b067536daa4842adbf685accf47c899a26367d3 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 18 Sep 2024 20:45:15 +0200
+Subject: [PATCH 47/47] r8169: add missing MODULE_FIRMWARE entry for RTL8126A
+ rev.b
+
+Add a missing MODULE_FIRMWARE entry.
+
+Fixes: 69cb89981c7a ("r8169: add support for RTL8126A rev.b")
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://patch.msgid.link/bb307611-d129-43f5-a7ff-bdb6b4044fce@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -708,6 +708,7 @@ MODULE_FIRMWARE(FIRMWARE_8107E_2);
+ MODULE_FIRMWARE(FIRMWARE_8125A_3);
+ MODULE_FIRMWARE(FIRMWARE_8125B_2);
+ MODULE_FIRMWARE(FIRMWARE_8126A_2);
++MODULE_FIRMWARE(FIRMWARE_8126A_3);
+
+ static inline struct device *tp_to_dev(struct rtl8169_private *tp)
+ {
diff --git a/target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch b/target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch
new file mode 100644
index 0000000000..723742e7fa
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch
@@ -0,0 +1,40 @@
+From 5befa3728b855e9f75b29bb0069a1ca7f5bab2f7 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 31 Jan 2024 21:24:29 +0100
+Subject: [PATCH] net: phy: realtek: add support for RTL8126A-integrated 5Gbps
+ PHY
+
+A user reported that first consumer mainboards show up with a RTL8126A
+5Gbps MAC/PHY. This adds support for the integrated PHY, which is also
+available stand-alone. From a PHY driver perspective it's treated the
+same as the 2.5Gbps PHY's, we just have to support the new PHY ID.
+
+Reported-by: Joe Salmeri <jmscdba@gmail.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Tested-by: Joe Salmeri <jmscdba@gmail.com>
+Link: https://lore.kernel.org/r/0c8e67ea-6505-43d1-bd51-94e7ecd6e222@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1050,6 +1050,16 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ PHY_ID_MATCH_EXACT(0x001cc862),
++ .name = "RTL8251B 5Gbps PHY",
++ .get_features = rtl822x_get_features,
++ .config_aneg = rtl822x_config_aneg,
++ .read_status = rtl822x_read_status,
++ .suspend = genphy_suspend,
++ .resume = rtlgen_resume,
++ .read_page = rtl821x_read_page,
++ .write_page = rtl821x_write_page,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc961),
+ .name = "RTL8366RB Gigabit Ethernet",
+ .config_init = &rtl8366rb_config_init,
diff --git a/target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch b/target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch
new file mode 100644
index 0000000000..6672aca9b8
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch
@@ -0,0 +1,93 @@
+From 2b9ec5dfb8255656ca731ab9d9bf59d94566d377 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Sun, 4 Feb 2024 15:17:53 +0100
+Subject: [PATCH] net: phy: realtek: use generic MDIO constants
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Drop the ad-hoc MDIO constants used in the driver and use generic
+constants instead.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/732a70d6-4191-4aae-8862-3716b062aa9e@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 30 +++++++++++++-----------------
+ 1 file changed, 13 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -57,14 +57,6 @@
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+-#define RTL_SUPPORTS_5000FULL BIT(14)
+-#define RTL_SUPPORTS_2500FULL BIT(13)
+-#define RTL_SUPPORTS_10000FULL BIT(0)
+-#define RTL_ADV_2500FULL BIT(7)
+-#define RTL_LPADV_10000FULL BIT(11)
+-#define RTL_LPADV_5000FULL BIT(6)
+-#define RTL_LPADV_2500FULL BIT(5)
+-
+ #define RTL9000A_GINMR 0x14
+ #define RTL9000A_GINMR_LINK_STATUS BIT(4)
+
+@@ -676,11 +668,11 @@ static int rtl822x_get_features(struct p
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_2500FULL);
++ phydev->supported, val & MDIO_PMA_SPEED_2_5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_5000FULL);
++ phydev->supported, val & MDIO_PMA_SPEED_5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_10000FULL);
++ phydev->supported, val & MDIO_SPEED_10G);
+
+ return genphy_read_abilities(phydev);
+ }
+@@ -694,10 +686,11 @@ static int rtl822x_config_aneg(struct ph
+
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->advertising))
+- adv2500 = RTL_ADV_2500FULL;
++ adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+- RTL_ADV_2500FULL, adv2500);
++ MDIO_AN_10GBT_CTRL_ADV2_5G,
++ adv2500);
+ if (ret < 0)
+ return ret;
+ }
+@@ -716,11 +709,14 @@ static int rtl822x_read_status(struct ph
+ return lpadv;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP10G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
+ }
+
+ ret = genphy_read_status(phydev);
+@@ -738,7 +734,7 @@ static bool rtlgen_supports_2_5gbps(stru
+ val = phy_read(phydev, 0x13);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
+
+- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
++ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
+ }
+
+ static int rtlgen_match_phy_device(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch b/target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch
new file mode 100644
index 0000000000..4b99a0eae6
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch
@@ -0,0 +1,42 @@
+From db1bb7741ff29bf2cefcbc0ca567644e9ed1caa9 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sun, 4 Feb 2024 15:18:50 +0100
+Subject: [PATCH] net: phy: realtek: add 5Gbps support to rtl822x_config_aneg()
+
+RTL8126 as an evolution of RTL8125 supports 5Gbps. rtl822x_config_aneg()
+is used by the PHY driver for the integrated PHY, therefore add 5Gbps
+support to it.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/5644ab50-e3e9-477c-96db-05cd5bdc2563@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -682,15 +682,19 @@ static int rtl822x_config_aneg(struct ph
+ int ret = 0;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+- u16 adv2500 = 0;
++ u16 adv = 0;
+
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->advertising))
+- adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
++ adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
++ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
++ phydev->advertising))
++ adv |= MDIO_AN_10GBT_CTRL_ADV5G;
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+- MDIO_AN_10GBT_CTRL_ADV2_5G,
+- adv2500);
++ MDIO_AN_10GBT_CTRL_ADV2_5G |
++ MDIO_AN_10GBT_CTRL_ADV5G,
++ adv);
+ if (ret < 0)
+ return ret;
+ }
diff --git a/target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch b/target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch
new file mode 100644
index 0000000000..86db2df76b
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch
@@ -0,0 +1,52 @@
+From b63cc73341e076961d564a74cc3d29b2fd444079 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Thu, 8 Feb 2024 07:59:18 +0100
+Subject: [PATCH] net: phy: realtek: use generic MDIO helpers to simplify the
+ code
+
+Use generic MDIO helpers to simplify the code.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/422ae70f-7305-45fd-ab3e-0dd604b9fd6c@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 20 +++-----------------
+ 1 file changed, 3 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -682,14 +682,7 @@ static int rtl822x_config_aneg(struct ph
+ int ret = 0;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+- u16 adv = 0;
+-
+- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->advertising))
+- adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
+- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->advertising))
+- adv |= MDIO_AN_10GBT_CTRL_ADV5G;
++ u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+ MDIO_AN_10GBT_CTRL_ADV2_5G |
+@@ -712,15 +705,8 @@ static int rtl822x_read_status(struct ph
+ if (lpadv < 0)
+ return lpadv;
+
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP10G);
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP5G);
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
++ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
++ lpadv);
+ }
+
+ ret = genphy_read_status(phydev);
diff --git a/target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch b/target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch
new file mode 100644
index 0000000000..ba24ca3a16
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch
@@ -0,0 +1,209 @@
+From deb8af5243504e379878ae3f9a091b21422d65b2 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Tue, 9 Apr 2024 09:30:11 +0200
+Subject: [PATCH] net: phy: realtek: configure SerDes mode for rtl822xb PHYs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The rtl8221b and rtl8226b series support switching SerDes mode between
+2500base-x and sgmii based on the negotiated copper speed.
+
+Configure this switching mode according to SerDes modes supported by
+host.
+
+There is an additional datasheet for RTL8226B/RTL8221B called
+"SERDES MODE SETTING FLOW APPLICATION NOTE" where a sequence is
+described to setup interface and rate adapter mode.
+
+However, there is no documentation about the meaning of registers
+and bits, it's literally just magic numbers and pseudo-code.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+[ refactored, dropped HiSGMII mode and changed commit message ]
+Signed-off-by: Marek Behún <kabel@kernel.org>
+[ changed rtl822x_update_interface() to use vendor register ]
+[ always fill in possible interfaces ]
+[ only apply to rtl8221b and rtl8226b phy's ]
+[ set phydev->rate_matching in .config_init() ]
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: should come before them, without any blank lines. As the
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 114 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 110 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -54,6 +54,16 @@
+ RTL8201F_ISR_LINK)
+ #define RTL8201F_IER 0x13
+
++#define RTL822X_VND1_SERDES_OPTION 0x697a
++#define RTL822X_VND1_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
++#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII 0
++#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX 2
++
++#define RTL822X_VND1_SERDES_CTRL3 0x7580
++#define RTL822X_VND1_SERDES_CTRL3_MODE_MASK GENMASK(5, 0)
++#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
++#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -659,6 +669,63 @@ static int rtl822x_write_mmd(struct phy_
+ return ret;
+ }
+
++static int rtl822xb_config_init(struct phy_device *phydev)
++{
++ bool has_2500, has_sgmii;
++ u16 mode;
++ int ret;
++
++ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
++ phydev->host_interfaces) ||
++ phydev->interface == PHY_INTERFACE_MODE_2500BASEX;
++
++ has_sgmii = test_bit(PHY_INTERFACE_MODE_SGMII,
++ phydev->host_interfaces) ||
++ phydev->interface == PHY_INTERFACE_MODE_SGMII;
++
++ /* fill in possible interfaces */
++ __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
++ has_2500);
++ __assign_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces,
++ has_sgmii);
++
++ if (!has_2500 && !has_sgmii)
++ return 0;
++
++ /* determine SerDes option mode */
++ if (has_2500 && !has_sgmii) {
++ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
++ phydev->rate_matching = RATE_MATCH_PAUSE;
++ } else {
++ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
++ phydev->rate_matching = RATE_MATCH_NONE;
++ }
++
++ /* the following sequence with magic numbers sets up the SerDes
++ * option mode
++ */
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
++ RTL822X_VND1_SERDES_OPTION,
++ RTL822X_VND1_SERDES_OPTION_MODE_MASK,
++ mode);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
++ if (ret < 0)
++ return ret;
++
++ return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++}
++
+ static int rtl822x_get_features(struct phy_device *phydev)
+ {
+ int val;
+@@ -695,6 +762,28 @@ static int rtl822x_config_aneg(struct ph
+ return __genphy_config_aneg(phydev, ret);
+ }
+
++static void rtl822xb_update_interface(struct phy_device *phydev)
++{
++ int val;
++
++ if (!phydev->link)
++ return;
++
++ /* Change interface according to serdes mode */
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CTRL3);
++ if (val < 0)
++ return;
++
++ switch (val & RTL822X_VND1_SERDES_CTRL3_MODE_MASK) {
++ case RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX:
++ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
++ break;
++ case RTL822X_VND1_SERDES_CTRL3_MODE_SGMII:
++ phydev->interface = PHY_INTERFACE_MODE_SGMII;
++ break;
++ }
++}
++
+ static int rtl822x_read_status(struct phy_device *phydev)
+ {
+ int ret;
+@@ -716,6 +805,19 @@ static int rtl822x_read_status(struct ph
+ return rtlgen_get_speed(phydev);
+ }
+
++static int rtl822xb_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = rtl822x_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ rtl822xb_update_interface(phydev);
++
++ return 0;
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ int val;
+@@ -988,7 +1090,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1010,7 +1113,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1020,7 +1124,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1030,7 +1135,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
diff --git a/target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch b/target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch
new file mode 100644
index 0000000000..609ae1a028
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch
@@ -0,0 +1,77 @@
+From c189dbd738243be6775bb6878366bf63e27bfd05 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:12 +0200
+Subject: [PATCH] net: phy: realtek: add get_rate_matching() for rtl822xb PHYs
+
+Uses vendor register to determine if SerDes is setup in rate-matching mode.
+
+Rate-matching only supported when SerDes is set to 2500base-x.
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -726,6 +726,27 @@ static int rtl822xb_config_init(struct p
+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
+ }
+
++static int rtl822xb_get_rate_matching(struct phy_device *phydev,
++ phy_interface_t iface)
++{
++ int val;
++
++ /* Only rate matching at 2500base-x */
++ if (iface != PHY_INTERFACE_MODE_2500BASEX)
++ return RATE_MATCH_NONE;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_OPTION);
++ if (val < 0)
++ return val;
++
++ if ((val & RTL822X_VND1_SERDES_OPTION_MODE_MASK) ==
++ RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX)
++ return RATE_MATCH_PAUSE;
++
++ /* RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII */
++ return RATE_MATCH_NONE;
++}
++
+ static int rtl822x_get_features(struct phy_device *phydev)
+ {
+ int val;
+@@ -1091,6 +1112,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1114,6 +1136,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1125,6 +1148,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1136,6 +1160,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
diff --git a/target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch b/target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch
new file mode 100644
index 0000000000..5366c72f9c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch
@@ -0,0 +1,218 @@
+From ad5ce743a6b0329f642d80be50ef7b534e908fba Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Tue, 9 Apr 2024 09:30:13 +0200
+Subject: [PATCH] net: phy: realtek: Add driver instances for rtl8221b via
+ Clause 45
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Collected from several commits in [PATCH net-next]
+"Realtek RTL822x PHY rework to c45 and SerDes interface switching"
+
+The instances are used by Clause 45 only accessible PHY's on several sfp
+modules, which are using RollBall protocol.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+[ Added matching functions to differentiate C45 instances ]
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 135 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 131 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -64,6 +64,13 @@
+ #define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
+ #define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
+
++/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
++ * is set, they cannot be accessed by C45-over-C22.
++ */
++#define RTL822X_VND2_GBCR 0xa412
++
++#define RTL822X_VND2_GANLPAR 0xa414
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -74,6 +81,9 @@
+
+ #define RTL_GENERIC_PHYID 0x001cc800
+ #define RTL_8211FVD_PHYID 0x001cc878
++#define RTL_8221B_VB_CG 0x001cc849
++#define RTL_8221B_VN_CG 0x001cc84a
++#define RTL_8251B 0x001cc862
+
+ MODULE_DESCRIPTION("Realtek PHY driver");
+ MODULE_AUTHOR("Johnson Leung");
+@@ -839,6 +849,67 @@ static int rtl822xb_read_status(struct p
+ return 0;
+ }
+
++static int rtl822x_c45_config_aneg(struct phy_device *phydev)
++{
++ bool changed = false;
++ int ret, val;
++
++ if (phydev->autoneg == AUTONEG_DISABLE)
++ return genphy_c45_pma_setup_forced(phydev);
++
++ ret = genphy_c45_an_config_aneg(phydev);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
++
++ /* Vendor register as C45 has no standardized support for 1000BaseT */
++ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
++ ADVERTISE_1000FULL, val);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ return genphy_c45_check_and_restart_aneg(phydev, changed);
++}
++
++static int rtl822x_c45_read_status(struct phy_device *phydev)
++{
++ int ret, val;
++
++ ret = genphy_c45_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ /* Vendor register as C45 has no standardized support for 1000BaseT */
++ if (phydev->autoneg == AUTONEG_ENABLE) {
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ RTL822X_VND2_GANLPAR);
++ if (val < 0)
++ return val;
++
++ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
++ }
++
++ return 0;
++}
++
++static int rtl822xb_c45_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = rtl822x_c45_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ rtl822xb_update_interface(phydev);
++
++ return 0;
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ int val;
+@@ -862,6 +933,35 @@ static int rtl8226_match_phy_device(stru
+ rtlgen_supports_2_5gbps(phydev);
+ }
+
++static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
++ bool is_c45)
++{
++ if (phydev->is_c45)
++ return is_c45 && (id == phydev->c45_ids.device_ids[1]);
++ else
++ return !is_c45 && (id == phydev->phy_id);
++}
++
++static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
++}
++
++static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
++}
++
++static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
++}
++
++static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
++}
++
+ static int rtlgen_resume(struct phy_device *phydev)
+ {
+ int ret = genphy_resume(phydev);
+@@ -872,6 +972,15 @@ static int rtlgen_resume(struct phy_devi
+ return ret;
+ }
+
++static int rtlgen_c45_resume(struct phy_device *phydev)
++{
++ int ret = genphy_c45_pma_resume(phydev);
++
++ msleep(20);
++
++ return ret;
++}
++
+ static int rtl9000a_config_init(struct phy_device *phydev)
+ {
+ phydev->autoneg = AUTONEG_DISABLE;
+@@ -1143,8 +1252,8 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
+- PHY_ID_MATCH_EXACT(0x001cc849),
+- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
++ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
++ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1155,8 +1264,17 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
+- PHY_ID_MATCH_EXACT(0x001cc84a),
+- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
++ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
++ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822xb_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
++ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
++ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1167,6 +1285,15 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
++ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822xb_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc862),
+ .name = "RTL8251B 5Gbps PHY",
+ .get_features = rtl822x_get_features,
diff --git a/target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch b/target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch
new file mode 100644
index 0000000000..5c7130d2e0
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch
@@ -0,0 +1,125 @@
+From 2e4ea707c7e04eb83e58c43e0e744bbdf6b23ff2 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:14 +0200
+Subject: [PATCH] net: phy: realtek: Change rtlgen_get_speed() to
+ rtlgen_decode_speed()
+
+The value of the register to determine the speed, is retrieved
+differently when using Clause 45 only. To use the rtlgen_get_speed()
+function in this case, pass the value of the register as argument to
+rtlgen_get_speed(). The function would then always return 0, so change it
+to void. A better name for this function now is rtlgen_decode_speed().
+
+Replace a call to genphy_read_status() followed by rtlgen_get_speed()
+with a call to rtlgen_read_status() in rtl822x_read_status().
+
+Add reading speed to rtl822x_c45_read_status().
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 46 +++++++++++++++++++++------------------
+ 1 file changed, 25 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -71,6 +71,8 @@
+
+ #define RTL822X_VND2_GANLPAR 0xa414
+
++#define RTL822X_VND2_PHYSR 0xa434
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -551,17 +553,8 @@ static int rtl8366rb_config_init(struct
+ }
+
+ /* get actual speed to cover the downshift case */
+-static int rtlgen_get_speed(struct phy_device *phydev)
++static void rtlgen_decode_speed(struct phy_device *phydev, int val)
+ {
+- int val;
+-
+- if (!phydev->link)
+- return 0;
+-
+- val = phy_read_paged(phydev, 0xa43, 0x12);
+- if (val < 0)
+- return val;
+-
+ switch (val & RTLGEN_SPEED_MASK) {
+ case 0x0000:
+ phydev->speed = SPEED_10;
+@@ -584,19 +577,26 @@ static int rtlgen_get_speed(struct phy_d
+ default:
+ break;
+ }
+-
+- return 0;
+ }
+
+ static int rtlgen_read_status(struct phy_device *phydev)
+ {
+- int ret;
++ int ret, val;
+
+ ret = genphy_read_status(phydev);
+ if (ret < 0)
+ return ret;
+
+- return rtlgen_get_speed(phydev);
++ if (!phydev->link)
++ return 0;
++
++ val = phy_read_paged(phydev, 0xa43, 0x12);
++ if (val < 0)
++ return val;
++
++ rtlgen_decode_speed(phydev, val);
++
++ return 0;
+ }
+
+ static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
+@@ -817,8 +817,6 @@ static void rtl822xb_update_interface(st
+
+ static int rtl822x_read_status(struct phy_device *phydev)
+ {
+- int ret;
+-
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+ int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
+
+@@ -829,11 +827,7 @@ static int rtl822x_read_status(struct ph
+ lpadv);
+ }
+
+- ret = genphy_read_status(phydev);
+- if (ret < 0)
+- return ret;
+-
+- return rtlgen_get_speed(phydev);
++ return rtlgen_read_status(phydev);
+ }
+
+ static int rtl822xb_read_status(struct phy_device *phydev)
+@@ -894,6 +888,16 @@ static int rtl822x_c45_read_status(struc
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
+ }
+
++ if (!phydev->link)
++ return 0;
++
++ /* Read actual speed from vendor register. */
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
++ if (val < 0)
++ return val;
++
++ rtlgen_decode_speed(phydev, val);
++
+ return 0;
+ }
+
diff --git a/target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch b/target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch
new file mode 100644
index 0000000000..ed29dcd3e6
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch
@@ -0,0 +1,48 @@
+From 2d9ce64862705b33397d54dafecc5f51d8b1bb06 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:15 +0200
+Subject: [PATCH] net: phy: realtek: add rtl822x_c45_get_features() to set
+ supported port
+
+Sets ETHTOOL_LINK_MODE_TP_BIT in phydev->supported.
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -843,6 +843,14 @@ static int rtl822xb_read_status(struct p
+ return 0;
+ }
+
++static int rtl822x_c45_get_features(struct phy_device *phydev)
++{
++ linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
++ phydev->supported);
++
++ return genphy_c45_pma_read_abilities(phydev);
++}
++
+ static int rtl822x_c45_config_aneg(struct phy_device *phydev)
+ {
+ bool changed = false;
+@@ -1272,6 +1280,7 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
++ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822xb_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
+@@ -1293,6 +1302,7 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
++ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822xb_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
diff --git a/target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch b/target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch
new file mode 100644
index 0000000000..13e1d883a3
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch
@@ -0,0 +1,33 @@
+From 9e42a2ea7f6703e2092c39171c2bf1fd7eec0bd3 Mon Sep 17 00:00:00 2001
+From: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Date: Tue, 11 Jun 2024 17:34:14 +1200
+Subject: [PATCH] net: phy: realtek: add support for rtl8224 2.5Gbps PHY
+
+The Realtek RTL8224 PHY is a 2.5Gbps capable PHY. It only uses the
+clause 45 MDIO interface and can leverage the support that has already
+been added for the other 822x PHYs.
+
+Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Link: https://lore.kernel.org/r/20240611053415.2111723-1-chris.packham@alliedtelesis.co.nz
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1318,6 +1318,14 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ PHY_ID_MATCH_EXACT(0x001ccad0),
++ .name = "RTL8224 2.5Gbps PHY",
++ .get_features = rtl822x_c45_get_features,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822x_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc961),
+ .name = "RTL8366RB Gigabit Ethernet",
+ .config_init = &rtl8366rb_config_init,
diff --git a/target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch b/target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch
new file mode 100644
index 0000000000..12c8ae66b5
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch
@@ -0,0 +1,151 @@
+From 17784801d888238571a0c4101b9ac4401fffeaa0 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Tue, 25 Jun 2024 22:42:17 +0200
+Subject: [PATCH] net: phy: realtek: Add support for PHY LEDs on RTL8211F
+
+Realtek RTL8211F Ethernet PHY supports 3 LED pins which are used to
+indicate link status and activity. Add minimal LED controller driver
+supporting the most common uses with the 'netdev' trigger.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 106 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 106 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -32,6 +32,15 @@
+ #define RTL8211F_PHYCR2 0x19
+ #define RTL8211F_INSR 0x1d
+
++#define RTL8211F_LEDCR 0x10
++#define RTL8211F_LEDCR_MODE BIT(15)
++#define RTL8211F_LEDCR_ACT_TXRX BIT(4)
++#define RTL8211F_LEDCR_LINK_1000 BIT(3)
++#define RTL8211F_LEDCR_LINK_100 BIT(1)
++#define RTL8211F_LEDCR_LINK_10 BIT(0)
++#define RTL8211F_LEDCR_MASK GENMASK(4, 0)
++#define RTL8211F_LEDCR_SHIFT 5
++
+ #define RTL8211F_TX_DELAY BIT(8)
+ #define RTL8211F_RX_DELAY BIT(3)
+
+@@ -87,6 +96,8 @@
+ #define RTL_8221B_VN_CG 0x001cc84a
+ #define RTL_8251B 0x001cc862
+
++#define RTL8211F_LED_COUNT 3
++
+ MODULE_DESCRIPTION("Realtek PHY driver");
+ MODULE_AUTHOR("Johnson Leung");
+ MODULE_LICENSE("GPL");
+@@ -476,6 +487,98 @@ static int rtl821x_resume(struct phy_dev
+ return 0;
+ }
+
++static int rtl8211f_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
++
++ /* The RTL8211F PHY supports these LED settings on up to three LEDs:
++ * - Link: Configurable subset of 10/100/1000 link rates
++ * - Active: Blink on activity, RX or TX is not differentiated
++ * The Active option has two modes, A and B:
++ * - A: Link and Active indication at configurable, but matching,
++ * subset of 10/100/1000 link rates
++ * - B: Link indication at configurable subset of 10/100/1000 link
++ * rates and Active indication always at all three 10+100+1000
++ * link rates.
++ * This code currently uses mode B only.
++ */
++
++ if (index >= RTL8211F_LED_COUNT)
++ return -EINVAL;
++
++ /* Filter out any other unsupported triggers. */
++ if (rules & ~mask)
++ return -EOPNOTSUPP;
++
++ /* RX and TX are not differentiated, either both are set or not set. */
++ if (!(rules & BIT(TRIGGER_NETDEV_RX)) ^ !(rules & BIT(TRIGGER_NETDEV_TX)))
++ return -EOPNOTSUPP;
++
++ return 0;
++}
++
++static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules)
++{
++ int val;
++
++ val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR);
++ if (val < 0)
++ return val;
++
++ val >>= RTL8211F_LEDCR_SHIFT * index;
++ val &= RTL8211F_LEDCR_MASK;
++
++ if (val & RTL8211F_LEDCR_LINK_10)
++ set_bit(TRIGGER_NETDEV_LINK_10, rules);
++
++ if (val & RTL8211F_LEDCR_LINK_100)
++ set_bit(TRIGGER_NETDEV_LINK_100, rules);
++
++ if (val & RTL8211F_LEDCR_LINK_1000)
++ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
++
++ if (val & RTL8211F_LEDCR_ACT_TXRX) {
++ set_bit(TRIGGER_NETDEV_RX, rules);
++ set_bit(TRIGGER_NETDEV_TX, rules);
++ }
++
++ return 0;
++}
++
++static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
++ u16 reg = RTL8211F_LEDCR_MODE; /* Mode B */
++
++ if (index >= RTL8211F_LED_COUNT)
++ return -EINVAL;
++
++ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
++ reg |= RTL8211F_LEDCR_LINK_10;
++
++ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
++ reg |= RTL8211F_LEDCR_LINK_100;
++
++ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
++ reg |= RTL8211F_LEDCR_LINK_1000;
++
++ if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
++ test_bit(TRIGGER_NETDEV_TX, &rules)) {
++ reg |= RTL8211F_LEDCR_ACT_TXRX;
++ }
++
++ reg <<= RTL8211F_LEDCR_SHIFT * index;
++
++ return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
++}
++
+ static int rtl8211e_config_init(struct phy_device *phydev)
+ {
+ int ret = 0, oldpage;
+@@ -1192,6 +1295,9 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .flags = PHY_ALWAYS_CALL_SUSPEND,
++ .led_hw_is_supported = rtl8211f_led_hw_is_supported,
++ .led_hw_control_get = rtl8211f_led_hw_control_get,
++ .led_hw_control_set = rtl8211f_led_hw_control_set,
+ }, {
+ PHY_ID_MATCH_EXACT(RTL_8211FVD_PHYID),
+ .name = "RTL8211F-VD Gigabit Ethernet",
diff --git a/target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch b/target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch
new file mode 100644
index 0000000000..5958fc929c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch
@@ -0,0 +1,42 @@
+From a2f5c505b4378cd6fc7c4a44ff3665ccef2037db Mon Sep 17 00:00:00 2001
+From: Sava Jakovljev <savaj@meyersound.com>
+Date: Wed, 21 Aug 2024 04:16:57 +0200
+Subject: [PATCH] net: phy: realtek: Fix setting of PHY LEDs Mode B bit on
+ RTL8211F
+
+The current implementation incorrectly sets the mode bit of the PHY chip.
+Bit 15 (RTL8211F_LEDCR_MODE) should not be shifted together with the
+configuration nibble of a LED- it should be set independently of the
+index of the LED being configured.
+As a consequence, the RTL8211F LED control is actually operating in Mode A.
+Fix the error by or-ing final register value to write with a const-value of
+RTL8211F_LEDCR_MODE, thus setting Mode bit explicitly.
+
+Fixes: 17784801d888 ("net: phy: realtek: Add support for PHY LEDs on RTL8211F")
+Signed-off-by: Sava Jakovljev <savaj@meyersound.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://patch.msgid.link/PAWP192MB21287372F30C4E55B6DF6158C38E2@PAWP192MB2128.EURP192.PROD.OUTLOOK.COM
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/phy/realtek.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -555,7 +555,7 @@ static int rtl8211f_led_hw_control_set(s
+ unsigned long rules)
+ {
+ const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
+- u16 reg = RTL8211F_LEDCR_MODE; /* Mode B */
++ u16 reg = 0;
+
+ if (index >= RTL8211F_LED_COUNT)
+ return -EINVAL;
+@@ -575,6 +575,7 @@ static int rtl8211f_led_hw_control_set(s
+ }
+
+ reg <<= RTL8211F_LEDCR_SHIFT * index;
++ reg |= RTL8211F_LEDCR_MODE; /* Mode B */
+
+ return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
+ }
diff --git a/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch b/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
index 39be82d4bf..36d15248b8 100644
--- a/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
+++ b/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
@@ -48,7 +48,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mtd->nvmem = nvmem_register(&config);
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -941,7 +941,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -940,7 +940,7 @@ struct nvmem_device *nvmem_register(cons
nvmem->nkeepout = config->nkeepout;
if (config->of_node)
nvmem->dev.of_node = config->of_node;
diff --git a/target/linux/generic/backport-6.6/817-v6.9-of-property-Make-no-port-node-found-output-a-debug.patch b/target/linux/generic/backport-6.6/817-v6.9-of-property-Make-no-port-node-found-output-a-debug.patch
new file mode 100644
index 0000000000..bc4e5e743f
--- /dev/null
+++ b/target/linux/generic/backport-6.6/817-v6.9-of-property-Make-no-port-node-found-output-a-debug.patch
@@ -0,0 +1,33 @@
+From e20cd62b1f1708a4dec7ff4beb9e748a0bdb5716 Mon Sep 17 00:00:00 2001
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+Date: Wed, 17 Jan 2024 09:32:06 +0100
+Subject: [PATCH] of: property: Make 'no port node found' output a debug
+ message
+
+There are cases where an unavailable port is not an error, making this
+error message a false-positive. Since commit d56de8c9a17d8 ("usb: typec:
+tcpm: try to get role switch from tcpc fwnode") the role switch is tried
+on the port dev first and tcpc fwnode afterwards. If using the latter
+bindings getting from port dev fails every time. The kernel log is flooded
+with the messages like:
+ OF: graph: no port node found in /soc@0/bus@42000000/i2c@42530000/usb-typec@50
+Silence this message by making it a debug message.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Link: https://lore.kernel.org/r/20240117083206.2901534-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ drivers/of/property.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/of/property.c
++++ b/drivers/of/property.c
+@@ -664,7 +664,7 @@ struct device_node *of_graph_get_next_en
+ of_node_put(node);
+
+ if (!port) {
+- pr_err("graph: no port node found in %pOF\n", parent);
++ pr_debug("graph: no port node found in %pOF\n", parent);
+ return NULL;
+ }
+ } else {
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch b/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
index 59175c8051..0290d64898 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -847,14 +847,6 @@ static int nvmem_add_cells_from_layout(s
+@@ -846,14 +846,6 @@ static int nvmem_add_cells_from_layout(s
}
#if IS_ENABLED(CONFIG_OF)
@@ -42,7 +42,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
-@@ -241,7 +241,6 @@ struct nvmem_cell *of_nvmem_cell_get(str
+@@ -242,7 +242,6 @@ struct nvmem_cell *of_nvmem_cell_get(str
const char *id);
struct nvmem_device *of_nvmem_device_get(struct device_node *np,
const char *name);
@@ -50,7 +50,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#else
static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
const char *id)
-@@ -254,12 +253,6 @@ static inline struct nvmem_device *of_nv
+@@ -255,12 +254,6 @@ static inline struct nvmem_device *of_nv
{
return ERR_PTR(-EOPNOTSUPP);
}
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch b/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
index 1f39dfea2f..dac691e117 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
@@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -816,7 +816,7 @@ static int nvmem_add_cells_from_layout(s
+@@ -815,7 +815,7 @@ static int nvmem_add_cells_from_layout(s
int ret;
if (layout && layout->add_cells) {
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch b/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
index d2c274033e..0a614fc13d 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -675,7 +675,6 @@ static int nvmem_validate_keepouts(struc
+@@ -674,7 +674,6 @@ static int nvmem_validate_keepouts(struc
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
@@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct device *dev = &nvmem->dev;
struct device_node *child;
const __be32 *addr;
-@@ -705,8 +704,8 @@ static int nvmem_add_cells_from_dt(struc
+@@ -704,8 +703,8 @@ static int nvmem_add_cells_from_dt(struc
info.np = of_node_get(child);
@@ -44,7 +44,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
ret = nvmem_add_one_cell(nvmem, &info);
kfree(info.name);
-@@ -895,6 +894,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -894,6 +893,7 @@ struct nvmem_device *nvmem_register(cons
kref_init(&nvmem->refcnt);
INIT_LIST_HEAD(&nvmem->cells);
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch b/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
index ce33b52328..c846c485e0 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
@@ -84,7 +84,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
void *val, size_t bytes)
{
-@@ -740,97 +737,22 @@ static int nvmem_add_cells_from_fixed_la
+@@ -739,97 +736,22 @@ static int nvmem_add_cells_from_fixed_la
return err;
}
@@ -189,7 +189,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
struct nvmem_layout *layout)
{
-@@ -838,7 +760,7 @@ const void *nvmem_layout_get_match_data(
+@@ -837,7 +759,7 @@ const void *nvmem_layout_get_match_data(
const struct of_device_id *match;
layout_np = of_nvmem_layout_get_container(nvmem);
@@ -198,7 +198,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return match ? match->data : NULL;
}
-@@ -950,19 +872,6 @@ struct nvmem_device *nvmem_register(cons
+@@ -949,19 +871,6 @@ struct nvmem_device *nvmem_register(cons
goto err_put_device;
}
@@ -218,7 +218,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->cells) {
rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
if (rval)
-@@ -983,24 +892,24 @@ struct nvmem_device *nvmem_register(cons
+@@ -982,24 +891,24 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
@@ -249,7 +249,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->compat)
nvmem_sysfs_remove_compat(nvmem, config);
err_put_device:
-@@ -1022,7 +931,7 @@ static void nvmem_device_release(struct
+@@ -1021,7 +930,7 @@ static void nvmem_device_release(struct
device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
nvmem_device_remove_all_cells(nvmem);
@@ -258,7 +258,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
device_unregister(&nvmem->dev);
}
-@@ -1324,6 +1233,12 @@ nvmem_cell_get_from_lookup(struct device
+@@ -1323,6 +1232,12 @@ nvmem_cell_get_from_lookup(struct device
return cell;
}
@@ -271,7 +271,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#if IS_ENABLED(CONFIG_OF)
static struct nvmem_cell_entry *
nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np)
-@@ -1342,6 +1257,18 @@ nvmem_find_cell_entry_by_node(struct nvm
+@@ -1341,6 +1256,18 @@ nvmem_find_cell_entry_by_node(struct nvm
return cell;
}
@@ -290,7 +290,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
/**
* of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
*
-@@ -1404,16 +1331,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
+@@ -1403,16 +1330,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
return ERR_CAST(nvmem);
}
@@ -322,7 +322,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return cell;
}
-@@ -1527,6 +1467,7 @@ void nvmem_cell_put(struct nvmem_cell *c
+@@ -1526,6 +1466,7 @@ void nvmem_cell_put(struct nvmem_cell *c
kfree(cell);
__nvmem_device_put(nvmem);
@@ -330,7 +330,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
}
EXPORT_SYMBOL_GPL(nvmem_cell_put);
-@@ -2104,11 +2045,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name);
+@@ -2116,11 +2057,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_size);
static int __init nvmem_init(void)
{
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch b/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
index 4a1f9aefc8..8442636b09 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
@@ -111,7 +111,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
.attr = {
.name = "eeprom",
-@@ -380,6 +427,68 @@ static void nvmem_sysfs_remove_compat(st
+@@ -379,6 +426,68 @@ static void nvmem_sysfs_remove_compat(st
device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
}
@@ -180,7 +180,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#else /* CONFIG_NVMEM_SYSFS */
static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
-@@ -739,11 +848,25 @@ static int nvmem_add_cells_from_fixed_la
+@@ -738,11 +847,25 @@ static int nvmem_add_cells_from_fixed_la
int nvmem_layout_register(struct nvmem_layout *layout)
{
@@ -207,7 +207,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
}
EXPORT_SYMBOL_GPL(nvmem_layout_register);
-@@ -902,10 +1025,20 @@ struct nvmem_device *nvmem_register(cons
+@@ -901,10 +1024,20 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_dev;
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch b/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
index 400004c617..a95770a059 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
@@ -44,7 +44,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -854,7 +854,7 @@ int nvmem_layout_register(struct nvmem_l
+@@ -853,7 +853,7 @@ int nvmem_layout_register(struct nvmem_l
return -EINVAL;
/* Populate the cells */
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch b/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
index 510f3dd841..291854bcb5 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
@@ -24,7 +24,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -876,19 +876,6 @@ void nvmem_layout_unregister(struct nvme
+@@ -875,19 +875,6 @@ void nvmem_layout_unregister(struct nvme
}
EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch b/target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
deleted file mode 100644
index ccdcc09736..0000000000
--- a/target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 33cf42e68efc8ff529a7eee08a4f0ba8c8d0a207 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:17 +0100
-Subject: [PATCH] nvmem: core: add nvmem_dev_size() helper
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is required by layouts that need to read whole NVMEM content. It's
-especially useful for NVMEM devices without hardcoded layout (like
-U-Boot environment data block).
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-2-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 13 +++++++++++++
- include/linux/nvmem-consumer.h | 1 +
- 2 files changed, 14 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -2163,6 +2163,19 @@ const char *nvmem_dev_name(struct nvmem_
- }
- EXPORT_SYMBOL_GPL(nvmem_dev_name);
-
-+/**
-+ * nvmem_dev_size() - Get the size of a given nvmem device.
-+ *
-+ * @nvmem: nvmem device.
-+ *
-+ * Return: size of the nvmem device.
-+ */
-+size_t nvmem_dev_size(struct nvmem_device *nvmem)
-+{
-+ return nvmem->size;
-+}
-+EXPORT_SYMBOL_GPL(nvmem_dev_size);
-+
- static int __init nvmem_init(void)
- {
- int ret;
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem
- struct nvmem_cell_info *info, void *buf);
-
- const char *nvmem_dev_name(struct nvmem_device *nvmem);
-+size_t nvmem_dev_size(struct nvmem_device *nvmem);
-
- void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries,
- size_t nentries);
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch b/target/linux/generic/backport-6.6/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch
deleted file mode 100644
index fc826f3f7e..0000000000
--- a/target/linux/generic/backport-6.6/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 7c8979b42b1a9c5604f431ba804928e55919263c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:18 +0100
-Subject: [PATCH] nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem
- helper
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Simplify adding NVMEM cells.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-3-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 55 +++++++++++++++-----------------------
- 1 file changed, 21 insertions(+), 34 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -23,13 +23,10 @@ enum u_boot_env_format {
-
- struct u_boot_env {
- struct device *dev;
-+ struct nvmem_device *nvmem;
- enum u_boot_env_format format;
-
- struct mtd_info *mtd;
--
-- /* Cells */
-- struct nvmem_cell_info *cells;
-- int ncells;
- };
-
- struct u_boot_env_image_single {
-@@ -94,43 +91,36 @@ static int u_boot_env_read_post_process_
- static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
- size_t data_offset, size_t data_len)
- {
-+ struct nvmem_device *nvmem = priv->nvmem;
- struct device *dev = priv->dev;
- char *data = buf + data_offset;
- char *var, *value, *eq;
-- int idx;
--
-- priv->ncells = 0;
-- for (var = data; var < data + data_len && *var; var += strlen(var) + 1)
-- priv->ncells++;
--
-- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
-- if (!priv->cells)
-- return -ENOMEM;
-
-- for (var = data, idx = 0;
-+ for (var = data;
- var < data + data_len && *var;
-- var = value + strlen(value) + 1, idx++) {
-+ var = value + strlen(value) + 1) {
-+ struct nvmem_cell_info info = {};
-+
- eq = strchr(var, '=');
- if (!eq)
- break;
- *eq = '\0';
- value = eq + 1;
-
-- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
-- if (!priv->cells[idx].name)
-+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
-+ if (!info.name)
- return -ENOMEM;
-- priv->cells[idx].offset = data_offset + value - data;
-- priv->cells[idx].bytes = strlen(value);
-- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-+ info.offset = data_offset + value - data;
-+ info.bytes = strlen(value);
-+ info.np = of_get_child_by_name(dev->of_node, info.name);
- if (!strcmp(var, "ethaddr")) {
-- priv->cells[idx].raw_len = strlen(value);
-- priv->cells[idx].bytes = ETH_ALEN;
-- priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
-+ info.raw_len = strlen(value);
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
- }
-- }
-
-- if (WARN_ON(idx != priv->ncells))
-- priv->ncells = idx;
-+ nvmem_add_one_cell(nvmem, &info);
-+ }
-
- return 0;
- }
-@@ -209,7 +199,6 @@ static int u_boot_env_probe(struct platf
- struct device *dev = &pdev->dev;
- struct device_node *np = dev->of_node;
- struct u_boot_env *priv;
-- int err;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
-@@ -224,17 +213,15 @@ static int u_boot_env_probe(struct platf
- return PTR_ERR(priv->mtd);
- }
-
-- err = u_boot_env_parse(priv);
-- if (err)
-- return err;
--
- config.dev = dev;
-- config.cells = priv->cells;
-- config.ncells = priv->ncells;
- config.priv = priv;
- config.size = priv->mtd->size;
-
-- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
-+ priv->nvmem = devm_nvmem_register(dev, &config);
-+ if (IS_ERR(priv->nvmem))
-+ return PTR_ERR(priv->nvmem);
-+
-+ return u_boot_env_parse(priv);
- }
-
- static const struct of_device_id u_boot_env_of_match_table[] = {
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch b/target/linux/generic/backport-6.6/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch
deleted file mode 100644
index 70abc7cf14..0000000000
--- a/target/linux/generic/backport-6.6/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From a832556d23c5a11115f300011a5874d6107a0d62 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:19 +0100
-Subject: [PATCH] nvmem: u-boot-env: use nvmem device helpers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use nvmem_dev_size() and nvmem_device_read() to make this driver less
-mtd dependent.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-4-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 23 +++++++++++++++--------
- 1 file changed, 15 insertions(+), 8 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -127,27 +127,34 @@ static int u_boot_env_add_cells(struct u
-
- static int u_boot_env_parse(struct u_boot_env *priv)
- {
-+ struct nvmem_device *nvmem = priv->nvmem;
- struct device *dev = priv->dev;
- size_t crc32_data_offset;
- size_t crc32_data_len;
- size_t crc32_offset;
- size_t data_offset;
- size_t data_len;
-+ size_t dev_size;
- uint32_t crc32;
- uint32_t calc;
-- size_t bytes;
- uint8_t *buf;
-+ int bytes;
- int err;
-
-- buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
-+ dev_size = nvmem_dev_size(nvmem);
-+
-+ buf = kcalloc(1, dev_size, GFP_KERNEL);
- if (!buf) {
- err = -ENOMEM;
- goto err_out;
- }
-
-- err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
-- if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
-- dev_err(dev, "Failed to read from mtd: %d\n", err);
-+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
-+ if (bytes < 0) {
-+ err = bytes;
-+ goto err_kfree;
-+ } else if (bytes != dev_size) {
-+ err = -EIO;
- goto err_kfree;
- }
-
-@@ -169,8 +176,8 @@ static int u_boot_env_parse(struct u_boo
- break;
- }
- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-- crc32_data_len = priv->mtd->size - crc32_data_offset;
-- data_len = priv->mtd->size - data_offset;
-+ crc32_data_len = dev_size - crc32_data_offset;
-+ data_len = dev_size - data_offset;
-
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
- if (calc != crc32) {
-@@ -179,7 +186,7 @@ static int u_boot_env_parse(struct u_boo
- goto err_kfree;
- }
-
-- buf[priv->mtd->size - 1] = '\0';
-+ buf[dev_size - 1] = '\0';
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
- if (err)
- dev_err(dev, "Failed to add cells: %d\n", err);
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch b/target/linux/generic/backport-6.6/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch
deleted file mode 100644
index 273cfed874..0000000000
--- a/target/linux/generic/backport-6.6/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 6bafe07c930676d6430be471310958070816a595 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 21 Dec 2023 18:34:20 +0100
-Subject: [PATCH] nvmem: u-boot-env: improve coding style
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Prefer kzalloc() over kcalloc()
- See memory-allocation.rst which says: "to be on the safe side it's
- best to use routines that set memory to zero, like kzalloc()"
-2. Drop dev_err() for u_boot_env_add_cells() fail
- It can fail only on -ENOMEM. We don't want to print error then.
-3. Add extra "crc32_addr" variable
- It makes code reading header's crc32 easier to understand / review.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/r/20231221173421.13737-5-zajec5@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/u-boot-env.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -132,6 +132,7 @@ static int u_boot_env_parse(struct u_boo
- size_t crc32_data_offset;
- size_t crc32_data_len;
- size_t crc32_offset;
-+ __le32 *crc32_addr;
- size_t data_offset;
- size_t data_len;
- size_t dev_size;
-@@ -143,7 +144,7 @@ static int u_boot_env_parse(struct u_boo
-
- dev_size = nvmem_dev_size(nvmem);
-
-- buf = kcalloc(1, dev_size, GFP_KERNEL);
-+ buf = kzalloc(dev_size, GFP_KERNEL);
- if (!buf) {
- err = -ENOMEM;
- goto err_out;
-@@ -175,7 +176,8 @@ static int u_boot_env_parse(struct u_boo
- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
- break;
- }
-- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-+ crc32_addr = (__le32 *)(buf + crc32_offset);
-+ crc32 = le32_to_cpu(*crc32_addr);
- crc32_data_len = dev_size - crc32_data_offset;
- data_len = dev_size - data_offset;
-
-@@ -188,8 +190,6 @@ static int u_boot_env_parse(struct u_boo
-
- buf[dev_size - 1] = '\0';
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
-- if (err)
-- dev_err(dev, "Failed to add cells: %d\n", err);
-
- err_kfree:
- kfree(buf);
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch b/target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
new file mode 100644
index 0000000000..8e7c8233e2
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
@@ -0,0 +1,69 @@
+From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001
+From: William-tw Lin <william-tw.lin@mediatek.com>
+Date: Sat, 24 Feb 2024 11:45:07 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse
+
+The socinfo driver reads chip information from eFuses and does not need
+any devicetree node. Register it from mtk-efuse.
+
+While at it, also add the name for this driver's nvmem_config.
+
+Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo
+ struct nvmem_config econfig = {};
+ struct mtk_efuse_priv *priv;
+ const struct mtk_efuse_pdata *pdata;
++ struct platform_device *socinfo;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
++ econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
++ if (IS_ERR(nvmem))
++ return PTR_ERR(nvmem);
+
+- return PTR_ERR_OR_ZERO(nvmem);
++ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo",
++ PLATFORM_DEVID_AUTO, NULL, 0);
++ if (IS_ERR(socinfo))
++ dev_info(dev, "MediaTek SoC Information will be unavailable\n");
++
++ platform_set_drvdata(pdev, socinfo);
++ return 0;
+ }
+
+ static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
+@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu
+ };
+ MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
+
++static void mtk_efuse_remove(struct platform_device *pdev)
++{
++ struct platform_device *socinfo = platform_get_drvdata(pdev);
++
++ if (!IS_ERR_OR_NULL(socinfo))
++ platform_device_unregister(socinfo);
++}
++
+ static struct platform_driver mtk_efuse_driver = {
+ .probe = mtk_efuse_probe,
++ .remove_new = mtk_efuse_remove,
+ .driver = {
+ .name = "mediatek,efuse",
+ .of_match_table = mtk_efuse_of_match,
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch b/target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
new file mode 100644
index 0000000000..0f90e548a2
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
@@ -0,0 +1,97 @@
+From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:11 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
+
+- Remove static nvmem_config declaration
+- Remove zynqmp_nvmem_data
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
+ 1 file changed, 12 insertions(+), 25 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ /*
+ * Copyright (C) 2019 Xilinx, Inc.
++ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
+ #include <linux/module.h>
+@@ -11,36 +12,25 @@
+
+ #define SILICON_REVISION_MASK 0xF
+
+-struct zynqmp_nvmem_data {
+- struct device *dev;
+- struct nvmem_device *nvmem;
+-};
+
+ static int zynqmp_nvmem_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+ {
++ struct device *dev = context;
+ int ret;
+- int idcode, version;
+- struct zynqmp_nvmem_data *priv = context;
++ int idcode;
++ int version;
+
+ ret = zynqmp_pm_get_chipid(&idcode, &version);
+ if (ret < 0)
+ return ret;
+
+- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+ *(int *)val = version & SILICON_REVISION_MASK;
+
+ return 0;
+ }
+
+-static struct nvmem_config econfig = {
+- .name = "zynqmp-nvmem",
+- .owner = THIS_MODULE,
+- .word_size = 1,
+- .size = 1,
+- .read_only = true,
+-};
+-
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+ { .compatible = "xlnx,zynqmp-nvmem-fw", },
+ { /* sentinel */ },
+@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat
+ static int zynqmp_nvmem_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct zynqmp_nvmem_data *priv;
++ struct nvmem_config econfig = {};
+
+- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- priv->dev = dev;
++ econfig.name = "zynqmp-nvmem";
++ econfig.owner = THIS_MODULE;
++ econfig.word_size = 1;
++ econfig.size = 1;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
++ econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
+- econfig.priv = priv;
+-
+- priv->nvmem = devm_nvmem_register(dev, &econfig);
+
+- return PTR_ERR_OR_ZERO(priv->nvmem);
++ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
+
+ static struct platform_driver zynqmp_nvmem_driver = {
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch b/target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
new file mode 100644
index 0000000000..39c2f17835
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
@@ -0,0 +1,243 @@
+From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:12 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse
+
+Add support to read/write efuse memory map of ZynqMP.
+Below are the offsets of ZynqMP efuse memory map
+ 0 - SOC version(read only)
+ 0xC - 0xFC -ZynqMP specific purpose efuses
+ 0x100 - 0x17F - Physical Unclonable Function(PUF)
+ efuses repurposed as user efuses
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 176 insertions(+), 10 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
++#include <linux/dma-mapping.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of.h>
+@@ -11,24 +12,189 @@
+ #include <linux/firmware/xlnx-zynqmp.h>
+
+ #define SILICON_REVISION_MASK 0xF
++#define P_USER_0_64_UPPER_MASK GENMASK(31, 16)
++#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
++#define WORD_INBYTES 4
++#define SOC_VER_SIZE 0x4
++#define EFUSE_MEMORY_SIZE 0x177
++#define UNUSED_SPACE 0x8
++#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \
++ EFUSE_MEMORY_SIZE)
++#define SOC_VERSION_OFFSET 0x0
++#define EFUSE_START_OFFSET 0xC
++#define EFUSE_END_OFFSET 0xFC
++#define EFUSE_PUF_START_OFFSET 0x100
++#define EFUSE_PUF_MID_OFFSET 0x140
++#define EFUSE_PUF_END_OFFSET 0x17F
++#define EFUSE_NOT_ENABLED 29
+
++/*
++ * efuse access type
++ */
++enum efuse_access {
++ EFUSE_READ = 0,
++ EFUSE_WRITE
++};
++
++/**
++ * struct xilinx_efuse - the basic structure
++ * @src: address of the buffer to store the data to be write/read
++ * @size: read/write word count
++ * @offset: read/write offset
++ * @flag: 0 - represents efuse read and 1- represents efuse write
++ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
++ * 1 - represents puf user fuse row number.
++ *
++ * this structure stores all the required details to
++ * read/write efuse memory.
++ */
++struct xilinx_efuse {
++ u64 src;
++ u32 size;
++ u32 offset;
++ enum efuse_access flag;
++ u32 pufuserfuse;
++};
++
++static int zynqmp_efuse_access(void *context, unsigned int offset,
++ void *val, size_t bytes, enum efuse_access flag,
++ unsigned int pufflag)
++{
++ struct device *dev = context;
++ struct xilinx_efuse *efuse;
++ dma_addr_t dma_addr;
++ dma_addr_t dma_buf;
++ size_t words = bytes / WORD_INBYTES;
++ int ret;
++ int value;
++ char *data;
+
+-static int zynqmp_nvmem_read(void *context, unsigned int offset,
+- void *val, size_t bytes)
++ if (bytes % WORD_INBYTES != 0) {
++ dev_err(dev, "Bytes requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 0 && offset % WORD_INBYTES) {
++ dev_err(dev, "Offset requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 1 && flag == EFUSE_WRITE) {
++ memcpy(&value, val, bytes);
++ if ((offset == EFUSE_PUF_START_OFFSET ||
++ offset == EFUSE_PUF_MID_OFFSET) &&
++ value & P_USER_0_64_UPPER_MASK) {
++ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (offset == EFUSE_PUF_END_OFFSET &&
++ (value & P_USER_127_LOWER_4_BIT_MASK)) {
++ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
++ return -EOPNOTSUPP;
++ }
++ }
++
++ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
++ &dma_addr, GFP_KERNEL);
++ if (!efuse)
++ return -ENOMEM;
++
++ data = dma_alloc_coherent(dev, sizeof(bytes),
++ &dma_buf, GFP_KERNEL);
++ if (!data) {
++ ret = -ENOMEM;
++ goto efuse_data_fail;
++ }
++
++ if (flag == EFUSE_WRITE) {
++ memcpy(data, val, bytes);
++ efuse->flag = EFUSE_WRITE;
++ } else {
++ efuse->flag = EFUSE_READ;
++ }
++
++ efuse->src = dma_buf;
++ efuse->size = words;
++ efuse->offset = offset;
++ efuse->pufuserfuse = pufflag;
++
++ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
++ if (ret != 0) {
++ if (ret == EFUSE_NOT_ENABLED) {
++ dev_err(dev, "efuse access is not enabled\n");
++ ret = -EOPNOTSUPP;
++ } else {
++ dev_err(dev, "Error in efuse read %x\n", ret);
++ ret = -EPERM;
++ }
++ goto efuse_access_err;
++ }
++
++ if (flag == EFUSE_READ)
++ memcpy(val, data, bytes);
++efuse_access_err:
++ dma_free_coherent(dev, sizeof(bytes),
++ data, dma_buf);
++efuse_data_fail:
++ dma_free_coherent(dev, sizeof(struct xilinx_efuse),
++ efuse, dma_addr);
++
++ return ret;
++}
++
++static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
+ {
+ struct device *dev = context;
+ int ret;
++ int pufflag = 0;
+ int idcode;
+ int version;
+
+- ret = zynqmp_pm_get_chipid(&idcode, &version);
+- if (ret < 0)
+- return ret;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
++
++ switch (offset) {
++ /* Soc version offset is zero */
++ case SOC_VERSION_OFFSET:
++ if (bytes != SOC_VER_SIZE)
++ return -EOPNOTSUPP;
++
++ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
++ *(int *)val = version & SILICON_REVISION_MASK;
++ break;
++ /* Efuse offset starts from 0xc */
++ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
++ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
++ ret = zynqmp_efuse_access(context, offset, val,
++ bytes, EFUSE_READ, pufflag);
++ break;
++ default:
++ *(u32 *)val = 0xDEADBEEF;
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static int zynqmp_nvmem_write(void *context,
++ unsigned int offset, void *val, size_t bytes)
++{
++ int pufflag = 0;
++
++ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
++ return -EOPNOTSUPP;
+
+- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+- *(int *)val = version & SILICON_REVISION_MASK;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
+
+- return 0;
++ return zynqmp_efuse_access(context, offset,
++ val, bytes, EFUSE_WRITE, pufflag);
+ }
+
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla
+ econfig.name = "zynqmp-nvmem";
+ econfig.owner = THIS_MODULE;
+ econfig.word_size = 1;
+- econfig.size = 1;
++ econfig.size = ZYNQMP_NVMEM_SIZE;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
+- econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
++ econfig.reg_write = zynqmp_nvmem_write;
+
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch b/target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
new file mode 100644
index 0000000000..c67399cb13
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
@@ -0,0 +1,35 @@
+From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wenst@chromium.org>
+Date: Sat, 24 Feb 2024 11:45:14 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The MT8183 has not one but two efuse devices. The static name and ID
+causes the second efuse device to fail to probe, due to duplicate sysfs
+entries.
+
+With the rework of the mtk-socinfo driver, lookup by name is no longer
+necessary. The custom name can simply be dropped.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
+- econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch b/target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch
new file mode 100644
index 0000000000..506092e359
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch
@@ -0,0 +1,33 @@
+From 8ec0faf2572216b4e25d6829cd41cf3ee2dab979 Mon Sep 17 00:00:00 2001
+From: "Ricardo B. Marliere" <ricardo@marliere.net>
+Date: Sat, 24 Feb 2024 11:45:15 +0000
+Subject: [PATCH] nvmem: core: make nvmem_layout_bus_type const
+
+Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type
+a const *"), the driver core can properly handle constant struct
+bus_type, move the nvmem_layout_bus_type variable to be a constant
+structure as well, placing it into read-only memory which can not be
+modified at runtime.
+
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: "Ricardo B. Marliere" <ricardo@marliere.net>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-11-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/layouts.c
++++ b/drivers/nvmem/layouts.c
+@@ -45,7 +45,7 @@ static void nvmem_layout_bus_remove(stru
+ return drv->remove(layout);
+ }
+
+-static struct bus_type nvmem_layout_bus_type = {
++static const struct bus_type nvmem_layout_bus_type = {
+ .name = "nvmem-layout",
+ .match = nvmem_layout_bus_match,
+ .probe = nvmem_layout_bus_probe,
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch b/target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
new file mode 100644
index 0000000000..aa4e0ab04a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
@@ -0,0 +1,32 @@
+From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+Date: Sat, 24 Feb 2024 11:45:16 +0000
+Subject: [PATCH] nvmem: core: Print error on wrong bits DT property
+
+The algorithms in nvmem core are built with the constraint that
+bit_offset < 8. If bit_offset is greater the results are wrong. Print an
+error if the devicetree 'bits' property is outside of the valid range
+and abort parsing.
+
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -805,6 +805,11 @@ static int nvmem_add_cells_from_dt(struc
+ if (addr && len == (2 * sizeof(u32))) {
+ info.bit_offset = be32_to_cpup(addr++);
+ info.nbits = be32_to_cpup(addr);
++ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
++ dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
++ of_node_put(child);
++ return -EINVAL;
++ }
+ }
+
+ info.np = of_node_get(child);
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch b/target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
new file mode 100644
index 0000000000..418d2c82b2
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
@@ -0,0 +1,61 @@
+From 6d0ca4a2a7e25f9ad07c1f335f20b4d9e048cdd5 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:11 +0100
+Subject: [PATCH] nvmem: layouts: store owner from modules with
+ nvmem_layout_driver_register()
+
+Modules registering driver with nvmem_layout_driver_register() might
+forget to set .owner field. The field is used by some of other kernel
+parts for reference counting (try_module_get()), so it is expected that
+drivers will set it.
+
+Solve the problem by moving this task away from the drivers to the core
+code, just like we did for platform_driver in
+commit 9447057eaff8 ("platform_device: use a macro instead of
+platform_driver_register").
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts.c | 6 ++++--
+ include/linux/nvmem-provider.h | 5 ++++-
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/layouts.c
++++ b/drivers/nvmem/layouts.c
+@@ -52,13 +52,15 @@ static const struct bus_type nvmem_layou
+ .remove = nvmem_layout_bus_remove,
+ };
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner)
+ {
+ drv->driver.bus = &nvmem_layout_bus_type;
++ drv->driver.owner = owner;
+
+ return driver_register(&drv->driver);
+ }
+-EXPORT_SYMBOL_GPL(nvmem_layout_driver_register);
++EXPORT_SYMBOL_GPL(__nvmem_layout_driver_register);
+
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv)
+ {
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -199,7 +199,10 @@ int nvmem_add_one_cell(struct nvmem_devi
+ int nvmem_layout_register(struct nvmem_layout *layout);
+ void nvmem_layout_unregister(struct nvmem_layout *layout);
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv);
++#define nvmem_layout_driver_register(drv) \
++ __nvmem_layout_driver_register(drv, THIS_MODULE)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner);
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv);
+ #define module_nvmem_layout_driver(__nvmem_layout_driver) \
+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch b/target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
new file mode 100644
index 0000000000..b483dd243b
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
@@ -0,0 +1,28 @@
+From 21833338eccb91194fec6ba7548d9c454824eca0 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:12 +0100
+Subject: [PATCH] nvmem: layouts: onie-tlv: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/onie-tlv.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/onie-tlv.c
++++ b/drivers/nvmem/layouts/onie-tlv.c
+@@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, onie_tlv_of_matc
+
+ static struct nvmem_layout_driver onie_tlv_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "onie-tlv-layout",
+ .of_match_table = onie_tlv_of_match_table,
+ },
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch b/target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
new file mode 100644
index 0000000000..472a65feca
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
@@ -0,0 +1,28 @@
+From 23fd602f21953c03c0714257d36685cd6b486f04 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:13 +0100
+Subject: [PATCH] nvmem: layouts: sl28vpd: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/sl28vpd.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/sl28vpd.c
++++ b/drivers/nvmem/layouts/sl28vpd.c
+@@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, sl28vpd_of_match
+
+ static struct nvmem_layout_driver sl28vpd_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "kontron-sl28vpd-layout",
+ .of_match_table = sl28vpd_of_match_table,
+ },
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch b/target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
new file mode 100644
index 0000000000..8f33f2ab61
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From dc3d88ade857ba3dca34f008e0b0aed3ef79cb15 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:14 +0100
+Subject: [PATCH] nvmem: sc27xx: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sc27xx-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sc27xx-efuse.c
++++ b/drivers/nvmem/sc27xx-efuse.c
+@@ -262,6 +262,7 @@ static const struct of_device_id sc27xx_
+ { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata},
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sc27xx_efuse_of_match);
+
+ static struct platform_driver sc27xx_efuse_driver = {
+ .probe = sc27xx_efuse_probe,
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch b/target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
new file mode 100644
index 0000000000..0953c92340
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From 154c1ec943e34f3188c9305b0c91d5e7dc1373b8 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:15 +0100
+Subject: [PATCH] nvmem: sprd: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sprd-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sprd-efuse.c
++++ b/drivers/nvmem/sprd-efuse.c
+@@ -426,6 +426,7 @@ static const struct of_device_id sprd_ef
+ { .compatible = "sprd,ums312-efuse", .data = &ums312_data },
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sprd_efuse_of_match);
+
+ static struct platform_driver sprd_efuse_driver = {
+ .probe = sprd_efuse_probe,
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch b/target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
new file mode 100644
index 0000000000..14baafc6b8
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
@@ -0,0 +1,32 @@
+From 8d8fc146dd7a0d6a6b37695747a524310dfb9d57 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 30 Apr 2024 09:49:16 +0100
+Subject: [PATCH] nvmem: core: switch to use device_add_groups()
+
+devm_device_add_groups() is being removed from the kernel, so move the
+nvmem driver to use device_add_groups() instead. The logic is
+identical, when the device is removed the driver core will properly
+clean up and remove the groups, and the memory used by the attribute
+groups will be freed because it was created with dev_* calls, so this is
+functionally identical overall.
+
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -476,7 +476,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch b/target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
new file mode 100644
index 0000000000..27d9270d31
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
@@ -0,0 +1,57 @@
+From 693d2f629962628ddefc88f4b6b453edda5ac32e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Tue, 30 Apr 2024 09:49:17 +0100
+Subject: [PATCH] nvmem: lpc18xx_eeprom: Convert to platform remove callback
+ returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Vladimir Zapolskiy <vz@mleia.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/lpc18xx_eeprom.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/nvmem/lpc18xx_eeprom.c
++++ b/drivers/nvmem/lpc18xx_eeprom.c
+@@ -249,13 +249,11 @@ err_clk:
+ return ret;
+ }
+
+-static int lpc18xx_eeprom_remove(struct platform_device *pdev)
++static void lpc18xx_eeprom_remove(struct platform_device *pdev)
+ {
+ struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(eeprom->clk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id lpc18xx_eeprom_of_match[] = {
+@@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_o
+
+ static struct platform_driver lpc18xx_eeprom_driver = {
+ .probe = lpc18xx_eeprom_probe,
+- .remove = lpc18xx_eeprom_remove,
++ .remove_new = lpc18xx_eeprom_remove,
+ .driver = {
+ .name = "lpc18xx-eeprom",
+ .of_match_table = lpc18xx_eeprom_of_match,
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch b/target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
new file mode 100644
index 0000000000..0b56ccc785
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
@@ -0,0 +1,50 @@
+From 2a1ad6b75292d38aa2f6ded7335979e0632521da Mon Sep 17 00:00:00 2001
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+Date: Tue, 30 Apr 2024 09:49:21 +0100
+Subject: [PATCH] nvmem: meson-mx-efuse: Remove nvmem_device from efuse struct
+
+nvmem_device is used at one place while registering nvmem
+device and it is not required to be present in efuse struct
+for just this purpose.
+
+Drop nvmem_device and manage with nvmem device stack variable.
+
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-mx-efuse.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-mx-efuse.c
++++ b/drivers/nvmem/meson-mx-efuse.c
+@@ -43,7 +43,6 @@ struct meson_mx_efuse_platform_data {
+ struct meson_mx_efuse {
+ void __iomem *base;
+ struct clk *core_clk;
+- struct nvmem_device *nvmem;
+ struct nvmem_config config;
+ };
+
+@@ -193,6 +192,7 @@ static int meson_mx_efuse_probe(struct p
+ {
+ const struct meson_mx_efuse_platform_data *drvdata;
+ struct meson_mx_efuse *efuse;
++ struct nvmem_device *nvmem;
+
+ drvdata = of_device_get_match_data(&pdev->dev);
+ if (!drvdata)
+@@ -223,9 +223,9 @@ static int meson_mx_efuse_probe(struct p
+ return PTR_ERR(efuse->core_clk);
+ }
+
+- efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
++ nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
+
+- return PTR_ERR_OR_ZERO(efuse->nvmem);
++ return PTR_ERR_OR_ZERO(nvmem);
+ }
+
+ static struct platform_driver meson_mx_efuse_driver = {
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch b/target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
new file mode 100644
index 0000000000..ec3fb14d60
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
@@ -0,0 +1,48 @@
+From c553bad4c5fc5ae44bd2fcaa73e1d6bedfb1c35c Mon Sep 17 00:00:00 2001
+From: Jeff Johnson <quic_jjohnson@quicinc.com>
+Date: Fri, 5 Jul 2024 08:48:38 +0100
+Subject: [PATCH] nvmem: add missing MODULE_DESCRIPTION() macros
+
+make allmodconfig && make W=1 C=1 reports:
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem-apple-efuses.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_brcm_nvram.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_u-boot-env.o
+
+Add the missing invocations of the MODULE_DESCRIPTION() macro.
+
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/apple-efuses.c | 1 +
+ drivers/nvmem/brcm_nvram.c | 1 +
+ drivers/nvmem/u-boot-env.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/drivers/nvmem/apple-efuses.c
++++ b/drivers/nvmem/apple-efuses.c
+@@ -78,4 +78,5 @@ static struct platform_driver apple_efus
+ module_platform_driver(apple_efuses_driver);
+
+ MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
++MODULE_DESCRIPTION("Apple SoC eFuse driver");
+ MODULE_LICENSE("GPL");
+--- a/drivers/nvmem/brcm_nvram.c
++++ b/drivers/nvmem/brcm_nvram.c
+@@ -253,5 +253,6 @@ static int __init brcm_nvram_init(void)
+ subsys_initcall_sync(brcm_nvram_init);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("Broadcom I/O-mapped NVRAM support driver");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table);
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -256,5 +256,6 @@ static struct platform_driver u_boot_env
+ module_platform_driver(u_boot_env_driver);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("U-Boot environment variables support module");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch b/target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
new file mode 100644
index 0000000000..05c82dbf6f
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
@@ -0,0 +1,48 @@
+From 5fecb932607d83d37a703c731268e9d9051457f5 Mon Sep 17 00:00:00 2001
+From: MarileneGarcia <marilene.agarcia@gmail.com>
+Date: Fri, 5 Jul 2024 08:48:40 +0100
+Subject: [PATCH] nvmem: meson-efuse: Replacing the use of of_node_put to
+ __free
+
+Use __free for device_node values, and thus drop calls to
+of_node_put.
+
+The goal is to reduce memory management issues by using this
+scope-based of_node_put() cleanup to simplify function exit
+handling. When using __free a resource is allocated within a
+block, it is automatically freed at the end of the block.
+
+Suggested-by: Julia Lawall <julia.lawall@inria.fr>
+Signed-off-by: MarileneGarcia <marilene.agarcia@gmail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-efuse.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -48,20 +48,19 @@ static int meson_efuse_probe(struct plat
+ {
+ struct device *dev = &pdev->dev;
+ struct meson_sm_firmware *fw;
+- struct device_node *sm_np;
+ struct nvmem_device *nvmem;
+ struct nvmem_config *econfig;
+ struct clk *clk;
+ unsigned int size;
++ struct device_node *sm_np __free(device_node) =
++ of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+
+- sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+ if (!sm_np) {
+ dev_err(&pdev->dev, "no secure-monitor node\n");
+ return -ENODEV;
+ }
+
+ fw = meson_sm_get(sm_np);
+- of_node_put(sm_np);
+ if (!fw)
+ return -EPROBE_DEFER;
+
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch b/target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
new file mode 100644
index 0000000000..8491eb3c9c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
@@ -0,0 +1,25 @@
+From 39f95600d8c53355b212a117e91a6ba15e0cac47 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:42 +0100
+Subject: [PATCH] nvmem: rockchip-otp: Set type to OTP
+
+The Rockchip OTP is obviously an OTP memory, so document this fact.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-otp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-otp.c
++++ b/drivers/nvmem/rockchip-otp.c
+@@ -256,6 +256,7 @@ static struct nvmem_config otp_config =
+ .name = "rockchip-otp",
+ .owner = THIS_MODULE,
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .read_only = true,
+ .stride = 1,
+ .word_size = 1,
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch b/target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
new file mode 100644
index 0000000000..260b03eb03
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
@@ -0,0 +1,26 @@
+From ba64a04474d2989f397982c48e405cfd785e2dd5 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:43 +0100
+Subject: [PATCH] nvmem: rockchip-efuse: set type to OTP
+
+This device currently reports an "Unknown" type in sysfs.
+Since it is an eFuse hardware device, set its type to OTP.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-efuse.c
++++ b/drivers/nvmem/rockchip-efuse.c
+@@ -206,6 +206,7 @@ static int rockchip_rk3399_efuse_read(vo
+ static struct nvmem_config econfig = {
+ .name = "rockchip-efuse",
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .stride = 1,
+ .word_size = 1,
+ .read_only = true,
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch b/target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
new file mode 100644
index 0000000000..eae06b2404
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
@@ -0,0 +1,42 @@
+From 6188f233161c6a5b2d1c396a221dfafc77dc9eec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:46 +0100
+Subject: [PATCH] nvmem: core: add single sysfs group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The sysfs core provides a function to easily register a single group.
+Use it and remove the now unnecessary nvmem_cells_groups array.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -367,11 +367,6 @@ static const struct attribute_group *nvm
+ NULL,
+ };
+
+-static const struct attribute_group *nvmem_cells_groups[] = {
+- &nvmem_cells_group,
+- NULL,
+-};
+-
+ static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
+ .attr = {
+ .name = "eeprom",
+@@ -476,7 +471,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch b/target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
new file mode 100644
index 0000000000..9ec523c3b0
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
@@ -0,0 +1,83 @@
+From 6839fed062b7898665983368c88269a6fb1fc10f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:47 +0100
+Subject: [PATCH] nvmem: core: remove global nvmem_cells_group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+nvmem_cells_groups is a global variable that is also mutated.
+This is complicated and error-prone.
+
+Instead use a normal stack variable.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-11-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -357,11 +357,6 @@ static const struct attribute_group nvme
+ .is_bin_visible = nvmem_bin_attr_is_visible,
+ };
+
+-/* Cell attributes will be dynamically allocated */
+-static struct attribute_group nvmem_cells_group = {
+- .name = "cells",
+-};
+-
+ static const struct attribute_group *nvmem_dev_groups[] = {
+ &nvmem_bin_group,
+ NULL,
+@@ -423,23 +418,24 @@ static void nvmem_sysfs_remove_compat(st
+
+ static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem)
+ {
+- struct bin_attribute **cells_attrs, *attrs;
++ struct attribute_group group = {
++ .name = "cells",
++ };
+ struct nvmem_cell_entry *entry;
++ struct bin_attribute *attrs;
+ unsigned int ncells = 0, i = 0;
+ int ret = 0;
+
+ mutex_lock(&nvmem_mutex);
+
+- if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) {
+- nvmem_cells_group.bin_attrs = NULL;
++ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated)
+ goto unlock_mutex;
+- }
+
+ /* Allocate an array of attributes with a sentinel */
+ ncells = list_count_nodes(&nvmem->cells);
+- cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
+- sizeof(struct bin_attribute *), GFP_KERNEL);
+- if (!cells_attrs) {
++ group.bin_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
++ sizeof(struct bin_attribute *), GFP_KERNEL);
++ if (!group.bin_attrs) {
+ ret = -ENOMEM;
+ goto unlock_mutex;
+ }
+@@ -465,13 +461,11 @@ static int nvmem_populate_sysfs_cells(st
+ goto unlock_mutex;
+ }
+
+- cells_attrs[i] = &attrs[i];
++ group.bin_attrs[i] = &attrs[i];
+ i++;
+ }
+
+- nvmem_cells_group.bin_attrs = cells_attrs;
+-
+- ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
++ ret = device_add_group(&nvmem->dev, &group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch b/target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
new file mode 100644
index 0000000000..22408e5295
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
@@ -0,0 +1,61 @@
+From 588773802c386d38f9c4e91acd47369e89d95a30 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:48 +0100
+Subject: [PATCH] nvmem: core: drop unnecessary range checks in sysfs callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The same checks have already been done in sysfs_kf_bin_write() and
+sysfs_kf_bin_read() just before the callbacks are invoked.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -203,19 +203,12 @@ static ssize_t bin_attr_nvmem_read(struc
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from reading */
+- if (pos >= nvmem->size)
+- return 0;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_read)
+@@ -243,19 +236,12 @@ static ssize_t bin_attr_nvmem_write(stru
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from writing */
+- if (pos >= nvmem->size)
+- return -EFBIG;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_write)
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch b/target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
new file mode 100644
index 0000000000..3159efbbe7
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
@@ -0,0 +1,30 @@
+From 08c367e45b6d322956878774f0b88bf5e52c6d54 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:51 +0100
+Subject: [PATCH] nvmem: Use sysfs_emit() for type attribute
+
+Use sysfs_emit() instead of sprintf() to follow best practice per
+Documentation/filesystems/sysfs.rst
+"
+show() should only use sysfs_emit()...
+"
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-15-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -179,7 +179,7 @@ static ssize_t type_show(struct device *
+ {
+ struct nvmem_device *nvmem = to_nvmem_device(dev);
+
+- return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]);
++ return sysfs_emit(buf, "%s\n", nvmem_type_str[nvmem->type]);
+ }
+
+ static DEVICE_ATTR_RO(type);
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch b/target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
new file mode 100644
index 0000000000..28fb544a04
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
@@ -0,0 +1,122 @@
+From 9d7eb234ac7a56b88aea8a52ed81553a730fe25c Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:52 +0100
+Subject: [PATCH] nvmem: core: Implement force_ro sysfs attribute
+
+Implement "force_ro" sysfs attribute to allow users to set read-write
+devices as read-only and back to read-write from userspace. The choice
+of the name is based on MMC core 'force_ro' attribute.
+
+This solves a situation where an AT24 I2C EEPROM with GPIO based nWP
+signal may have to be occasionally updated. Such I2C EEPROM device is
+usually set as read-only during most of the regular system operation,
+but in case it has to be updated in a controlled manner, it could be
+unlocked using this new "force_ro" sysfs attribute and then re-locked
+again.
+
+The "read-only" DT property and config->read_only configuration is
+respected and is used to set default state of the device, read-only
+or read-write, for devices which do implement .reg_write function.
+For devices which do not implement .reg_write function, the device
+is unconditionally read-only and the "force_ro" attribute is not
+visible.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-16-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/ABI/stable/sysfs-bus-nvmem | 17 ++++++++++
+ drivers/nvmem/core.c | 43 ++++++++++++++++++++++++
+ 2 files changed, 60 insertions(+)
+
+--- a/Documentation/ABI/stable/sysfs-bus-nvmem
++++ b/Documentation/ABI/stable/sysfs-bus-nvmem
+@@ -1,3 +1,20 @@
++What: /sys/bus/nvmem/devices/.../force_ro
++Date: June 2024
++KernelVersion: 6.11
++Contact: Marek Vasut <marex@denx.de>
++Description:
++ This read/write attribute allows users to set read-write
++ devices as read-only and back to read-write from userspace.
++ This can be used to unlock and relock write-protection of
++ devices which are generally locked, except during sporadic
++ programming operation.
++ Read returns '0' or '1' for read-write or read-only modes
++ respectively.
++ Write parses one of 'YyTt1NnFf0', or [oO][NnFf] for "on"
++ and "off", i.e. what kstrbool() supports.
++ Note: This file is only present if CONFIG_NVMEM_SYSFS
++ is enabled.
++
+ What: /sys/bus/nvmem/devices/.../nvmem
+ Date: July 2015
+ KernelVersion: 4.2
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -184,7 +184,30 @@ static ssize_t type_show(struct device *
+
+ static DEVICE_ATTR_RO(type);
+
++static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ return sysfs_emit(buf, "%d\n", nvmem->read_only);
++}
++
++static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++ int ret = kstrtobool(buf, &nvmem->read_only);
++
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++
++static DEVICE_ATTR_RW(force_ro);
++
+ static struct attribute *nvmem_attrs[] = {
++ &dev_attr_force_ro.attr,
+ &dev_attr_type.attr,
+ NULL,
+ };
+@@ -285,6 +308,25 @@ static umode_t nvmem_bin_attr_is_visible
+ return nvmem_bin_attr_get_umode(nvmem);
+ }
+
++static umode_t nvmem_attr_is_visible(struct kobject *kobj,
++ struct attribute *attr, int i)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ /*
++ * If the device has no .reg_write operation, do not allow
++ * configuration as read-write.
++ * If the device is set as read-only by configuration, it
++ * can be forced into read-write mode using the 'force_ro'
++ * attribute.
++ */
++ if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write)
++ return 0; /* Attribute not visible */
++
++ return attr->mode;
++}
++
+ static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
+ const char *id, int index);
+
+@@ -341,6 +383,7 @@ static const struct attribute_group nvme
+ .bin_attrs = nvmem_bin_attributes,
+ .attrs = nvmem_attrs,
+ .is_bin_visible = nvmem_bin_attr_is_visible,
++ .is_visible = nvmem_attr_is_visible,
+ };
+
+ static const struct attribute_group *nvmem_dev_groups[] = {
diff --git a/target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch b/target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
new file mode 100644
index 0000000000..c19931b3fa
--- /dev/null
+++ b/target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
@@ -0,0 +1,73 @@
+From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Mon, 2 Sep 2024 15:29:45 +0100
+Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95
+
+i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but
+some fuse has ECC feature, so only read out the lower 16bits for ECC fuses.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++---
+ 1 file changed, 29 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/imx-ocotp-ele.c
++++ b/drivers/nvmem/imx-ocotp-ele.c
+@@ -14,8 +14,9 @@
+ #include <linux/slab.h>
+
+ enum fuse_type {
+- FUSE_FSB = 1,
+- FUSE_ELE = 2,
++ FUSE_FSB = BIT(0),
++ FUSE_ELE = BIT(1),
++ FUSE_ECC = BIT(2),
+ FUSE_INVALID = -1
+ };
+
+@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont
+ continue;
+ }
+
+- *buf++ = readl_relaxed(reg + (i << 2));
++ if (type & FUSE_ECC)
++ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0);
++ else
++ *buf++ = readl_relaxed(reg + (i << 2));
+ }
+
+ memcpy(val, (u8 *)p, bytes);
+@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i
+ },
+ };
+
++static const struct ocotp_devtype_data imx95_ocotp_data = {
++ .reg_off = 0x8000,
++ .reg_read = imx_ocotp_reg_read,
++ .size = 2048,
++ .num_entry = 12,
++ .entry = {
++ { 0, 1, FUSE_FSB | FUSE_ECC },
++ { 7, 1, FUSE_FSB | FUSE_ECC },
++ { 9, 3, FUSE_FSB | FUSE_ECC },
++ { 12, 24, FUSE_FSB },
++ { 36, 2, FUSE_FSB | FUSE_ECC },
++ { 38, 14, FUSE_FSB },
++ { 63, 1, FUSE_ELE },
++ { 128, 16, FUSE_ELE },
++ { 188, 1, FUSE_ELE },
++ { 317, 2, FUSE_FSB | FUSE_ECC },
++ { 320, 7, FUSE_FSB },
++ { 328, 184, FUSE_FSB }
++ },
++};
++
+ static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
++ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
diff --git a/target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch b/target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
new file mode 100644
index 0000000000..13ef50b157
--- /dev/null
+++ b/target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
@@ -0,0 +1,44 @@
+From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001
+From: Zhang Zekun <zhangzekun11@huawei.com>
+Date: Mon, 2 Sep 2024 15:29:50 +0100
+Subject: [PATCH] nvmem: sunplus-ocotp: Use
+ devm_platform_ioremap_resource_byname() helper function
+
+platform_get_resource_byname() and devm_ioremap_resource() can be
+replaced by devm_platform_ioremap_resource_byname(), which can
+simplify the code logic a bit, No functional change here.
+
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sunplus-ocotp.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/nvmem/sunplus-ocotp.c
++++ b/drivers/nvmem/sunplus-ocotp.c
+@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor
+ struct device *dev = &pdev->dev;
+ struct nvmem_device *nvmem;
+ struct sp_ocotp_priv *otp;
+- struct resource *res;
+ int ret;
+
+ otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
+@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor
+
+ otp->dev = dev;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
+- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
++ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio");
+ if (IS_ERR(otp->base[HB_GPIO]))
+ return PTR_ERR(otp->base[HB_GPIO]);
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
+- otp->base[OTPRX] = devm_ioremap_resource(dev, res);
++ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx");
+ if (IS_ERR(otp->base[OTPRX]))
+ return PTR_ERR(otp->base[OTPRX]);
+
diff --git a/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
new file mode 100644
index 0000000000..15a0f77bb3
--- /dev/null
+++ b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
@@ -0,0 +1,525 @@
+From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 2 Sep 2024 15:29:47 +0100
+Subject: [PATCH] nvmem: layouts: add U-Boot env layout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+U-Boot environment variables are stored in a specific format. Actual
+data can be placed in various storage sources (MTD, UBI volume, EEPROM,
+NVRAM, etc.).
+
+Move all generic (NVMEM device independent) code from NVMEM device
+driver to an NVMEM layout driver. Then add a simple NVMEM layout code on
+top of it.
+
+This allows using NVMEM layout for parsing U-Boot env data stored in any
+kind of NVMEM device.
+
+The old NVMEM glue driver stays in place for handling bindings in the
+MTD context. To avoid code duplication it uses exported layout parsing
+function. Please note that handling MTD & NVMEM layout bindings may be
+refactored in the future.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS | 1 +
+ drivers/nvmem/Kconfig | 3 +-
+ drivers/nvmem/layouts/Kconfig | 11 ++
+ drivers/nvmem/layouts/Makefile | 1 +
+ drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++
+ drivers/nvmem/layouts/u-boot-env.h | 15 ++
+ drivers/nvmem/u-boot-env.c | 165 +---------------------
+ 7 files changed, 242 insertions(+), 165 deletions(-)
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.c
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -21988,6 +21988,7 @@ U-BOOT ENVIRONMENT VARIABLES
+ M: Rafał Miłecki <rafal@milecki.pl>
+ S: Maintained
+ F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
++F: drivers/nvmem/layouts/u-boot-env.c
+ F: drivers/nvmem/u-boot-env.c
+
+ UACCE ACCELERATOR FRAMEWORK
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID
+ config NVMEM_U_BOOT_ENV
+ tristate "U-Boot environment variables support"
+ depends on OF && MTD
+- select CRC32
+- select GENERIC_NET_UTILS
++ select NVMEM_LAYOUT_U_BOOT_ENV
+ help
+ U-Boot stores its setup as environment variables. This driver adds
+ support for verifying & exporting such data. It also exposes variables
+--- a/drivers/nvmem/layouts/Kconfig
++++ b/drivers/nvmem/layouts/Kconfig
+@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV
+
+ If unsure, say N.
+
++config NVMEM_LAYOUT_U_BOOT_ENV
++ tristate "U-Boot environment variables layout"
++ select CRC32
++ select GENERIC_NET_UTILS
++ help
++ U-Boot stores its setup as environment variables. This driver adds
++ support for verifying & exporting such data. It also exposes variables
++ as NVMEM cells so they can be referenced by other drivers.
++
++ If unsure, say N.
++
+ endmenu
+
+ endif
+--- a/drivers/nvmem/layouts/Makefile
++++ b/drivers/nvmem/layouts/Makefile
+@@ -5,3 +5,4 @@
+
+ obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
+ obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
++obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -0,0 +1,211 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2022 - 2023 Rafał Miłecki <rafal@milecki.pl>
++ */
++
++#include <linux/crc32.h>
++#include <linux/etherdevice.h>
++#include <linux/export.h>
++#include <linux/if_ether.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/nvmem-provider.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++
++#include "u-boot-env.h"
++
++struct u_boot_env_image_single {
++ __le32 crc32;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_redundant {
++ __le32 crc32;
++ u8 mark;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_broadcom {
++ __le32 magic;
++ __le32 len;
++ __le32 crc32;
++ DECLARE_FLEX_ARRAY(uint8_t, data);
++} __packed;
++
++static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
++ unsigned int offset, void *buf, size_t bytes)
++{
++ u8 mac[ETH_ALEN];
++
++ if (bytes != 3 * ETH_ALEN - 1)
++ return -EINVAL;
++
++ if (!mac_pton(buf, mac))
++ return -EINVAL;
++
++ if (index)
++ eth_addr_add(mac, index);
++
++ ether_addr_copy(buf, mac);
++
++ return 0;
++}
++
++static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
++ size_t data_offset, size_t data_len)
++{
++ char *data = buf + data_offset;
++ char *var, *value, *eq;
++
++ for (var = data;
++ var < data + data_len && *var;
++ var = value + strlen(value) + 1) {
++ struct nvmem_cell_info info = {};
++
++ eq = strchr(var, '=');
++ if (!eq)
++ break;
++ *eq = '\0';
++ value = eq + 1;
++
++ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
++ if (!info.name)
++ return -ENOMEM;
++ info.offset = data_offset + value - data;
++ info.bytes = strlen(value);
++ info.np = of_get_child_by_name(dev->of_node, info.name);
++ if (!strcmp(var, "ethaddr")) {
++ info.raw_len = strlen(value);
++ info.bytes = ETH_ALEN;
++ info.read_post_process = u_boot_env_read_post_process_ethaddr;
++ }
++
++ nvmem_add_one_cell(nvmem, &info);
++ }
++
++ return 0;
++}
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format)
++{
++ size_t crc32_data_offset;
++ size_t crc32_data_len;
++ size_t crc32_offset;
++ __le32 *crc32_addr;
++ size_t data_offset;
++ size_t data_len;
++ size_t dev_size;
++ uint32_t crc32;
++ uint32_t calc;
++ uint8_t *buf;
++ int bytes;
++ int err;
++
++ dev_size = nvmem_dev_size(nvmem);
++
++ buf = kzalloc(dev_size, GFP_KERNEL);
++ if (!buf) {
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
++ if (bytes < 0) {
++ err = bytes;
++ goto err_kfree;
++ } else if (bytes != dev_size) {
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ switch (format) {
++ case U_BOOT_FORMAT_SINGLE:
++ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
++ data_offset = offsetof(struct u_boot_env_image_single, data);
++ break;
++ case U_BOOT_FORMAT_REDUNDANT:
++ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ break;
++ case U_BOOT_FORMAT_BROADCOM:
++ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ break;
++ }
++
++ if (dev_size < data_offset) {
++ dev_err(dev, "Device too small for u-boot-env\n");
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ crc32_addr = (__le32 *)(buf + crc32_offset);
++ crc32 = le32_to_cpu(*crc32_addr);
++ crc32_data_len = dev_size - crc32_data_offset;
++ data_len = dev_size - data_offset;
++
++ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
++ if (calc != crc32) {
++ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
++ err = -EINVAL;
++ goto err_kfree;
++ }
++
++ buf[dev_size - 1] = '\0';
++ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
++
++err_kfree:
++ kfree(buf);
++err_out:
++ return err;
++}
++EXPORT_SYMBOL_GPL(u_boot_env_parse);
++
++static int u_boot_env_add_cells(struct nvmem_layout *layout)
++{
++ struct device *dev = &layout->dev;
++ enum u_boot_env_format format;
++
++ format = (uintptr_t)device_get_match_data(dev);
++
++ return u_boot_env_parse(dev, layout->nvmem, format);
++}
++
++static int u_boot_env_probe(struct nvmem_layout *layout)
++{
++ layout->add_cells = u_boot_env_add_cells;
++
++ return nvmem_layout_register(layout);
++}
++
++static void u_boot_env_remove(struct nvmem_layout *layout)
++{
++ nvmem_layout_unregister(layout);
++}
++
++static const struct of_device_id u_boot_env_of_match_table[] = {
++ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
++ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
++ {},
++};
++
++static struct nvmem_layout_driver u_boot_env_layout = {
++ .driver = {
++ .name = "u-boot-env-layout",
++ .of_match_table = u_boot_env_of_match_table,
++ },
++ .probe = u_boot_env_probe,
++ .remove = u_boot_env_remove,
++};
++module_nvmem_layout_driver(u_boot_env_layout);
++
++MODULE_AUTHOR("Rafał Miłecki");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
++MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables");
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.h
+@@ -0,0 +1,15 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++
++enum u_boot_env_format {
++ U_BOOT_FORMAT_SINGLE,
++ U_BOOT_FORMAT_REDUNDANT,
++ U_BOOT_FORMAT_BROADCOM,
++};
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format);
++
++#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -3,23 +3,15 @@
+ * Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+-#include <linux/crc32.h>
+-#include <linux/etherdevice.h>
+-#include <linux/if_ether.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/mtd/mtd.h>
+-#include <linux/nvmem-consumer.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
+
+-enum u_boot_env_format {
+- U_BOOT_FORMAT_SINGLE,
+- U_BOOT_FORMAT_REDUNDANT,
+- U_BOOT_FORMAT_BROADCOM,
+-};
++#include "layouts/u-boot-env.h"
+
+ struct u_boot_env {
+ struct device *dev;
+@@ -29,24 +21,6 @@ struct u_boot_env {
+ struct mtd_info *mtd;
+ };
+
+-struct u_boot_env_image_single {
+- __le32 crc32;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_redundant {
+- __le32 crc32;
+- u8 mark;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_broadcom {
+- __le32 magic;
+- __le32 len;
+- __le32 crc32;
+- DECLARE_FLEX_ARRAY(uint8_t, data);
+-} __packed;
+-
+ static int u_boot_env_read(void *context, unsigned int offset, void *val,
+ size_t bytes)
+ {
+@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context
+ return 0;
+ }
+
+-static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
+- unsigned int offset, void *buf, size_t bytes)
+-{
+- u8 mac[ETH_ALEN];
+-
+- if (bytes != 3 * ETH_ALEN - 1)
+- return -EINVAL;
+-
+- if (!mac_pton(buf, mac))
+- return -EINVAL;
+-
+- if (index)
+- eth_addr_add(mac, index);
+-
+- ether_addr_copy(buf, mac);
+-
+- return 0;
+-}
+-
+-static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
+- size_t data_offset, size_t data_len)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- char *data = buf + data_offset;
+- char *var, *value, *eq;
+-
+- for (var = data;
+- var < data + data_len && *var;
+- var = value + strlen(value) + 1) {
+- struct nvmem_cell_info info = {};
+-
+- eq = strchr(var, '=');
+- if (!eq)
+- break;
+- *eq = '\0';
+- value = eq + 1;
+-
+- info.name = devm_kstrdup(dev, var, GFP_KERNEL);
+- if (!info.name)
+- return -ENOMEM;
+- info.offset = data_offset + value - data;
+- info.bytes = strlen(value);
+- info.np = of_get_child_by_name(dev->of_node, info.name);
+- if (!strcmp(var, "ethaddr")) {
+- info.raw_len = strlen(value);
+- info.bytes = ETH_ALEN;
+- info.read_post_process = u_boot_env_read_post_process_ethaddr;
+- }
+-
+- nvmem_add_one_cell(nvmem, &info);
+- }
+-
+- return 0;
+-}
+-
+-static int u_boot_env_parse(struct u_boot_env *priv)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- size_t crc32_data_offset;
+- size_t crc32_data_len;
+- size_t crc32_offset;
+- __le32 *crc32_addr;
+- size_t data_offset;
+- size_t data_len;
+- size_t dev_size;
+- uint32_t crc32;
+- uint32_t calc;
+- uint8_t *buf;
+- int bytes;
+- int err;
+-
+- dev_size = nvmem_dev_size(nvmem);
+-
+- buf = kzalloc(dev_size, GFP_KERNEL);
+- if (!buf) {
+- err = -ENOMEM;
+- goto err_out;
+- }
+-
+- bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
+- if (bytes < 0) {
+- err = bytes;
+- goto err_kfree;
+- } else if (bytes != dev_size) {
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- switch (priv->format) {
+- case U_BOOT_FORMAT_SINGLE:
+- crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
+- data_offset = offsetof(struct u_boot_env_image_single, data);
+- break;
+- case U_BOOT_FORMAT_REDUNDANT:
+- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- break;
+- case U_BOOT_FORMAT_BROADCOM:
+- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- break;
+- }
+-
+- if (dev_size < data_offset) {
+- dev_err(dev, "Device too small for u-boot-env\n");
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- crc32_addr = (__le32 *)(buf + crc32_offset);
+- crc32 = le32_to_cpu(*crc32_addr);
+- crc32_data_len = dev_size - crc32_data_offset;
+- data_len = dev_size - data_offset;
+-
+- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
+- if (calc != crc32) {
+- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
+- err = -EINVAL;
+- goto err_kfree;
+- }
+-
+- buf[dev_size - 1] = '\0';
+- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
+-
+-err_kfree:
+- kfree(buf);
+-err_out:
+- return err;
+-}
+-
+ static int u_boot_env_probe(struct platform_device *pdev)
+ {
+ struct nvmem_config config = {
+@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf
+ if (IS_ERR(priv->nvmem))
+ return PTR_ERR(priv->nvmem);
+
+- return u_boot_env_parse(priv);
++ return u_boot_env_parse(dev, priv->nvmem, priv->format);
+ }
+
+ static const struct of_device_id u_boot_env_of_match_table[] = {
diff --git a/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch b/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
index 2ae209f9e1..4571d7d2bf 100644
--- a/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
+++ b/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
@@ -99,7 +99,7 @@ Signed-off-by: Lee Jones <lee@kernel.org>
interval = jiffies_to_msecs(
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
-@@ -588,6 +588,9 @@ enum led_trigger_netdev_modes {
+@@ -586,6 +586,9 @@ enum led_trigger_netdev_modes {
TRIGGER_NETDEV_LINK_10,
TRIGGER_NETDEV_LINK_100,
TRIGGER_NETDEV_LINK_1000,
diff --git a/target/linux/generic/backport-6.6/836-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch b/target/linux/generic/backport-6.6/836-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch
new file mode 100644
index 0000000000..8b54881ab0
--- /dev/null
+++ b/target/linux/generic/backport-6.6/836-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch
@@ -0,0 +1,103 @@
+From cffac22c9215f1883d3848c788f9b03656dced27 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robimarko@gmail.com>
+Date: Sun, 11 Feb 2024 18:39:19 +0100
+Subject: [PATCH] net: phy: aquantia: clear PMD Global Transmit Disable bit
+ during init
+
+PMD Global Transmit Disable bit should be cleared for normal operation.
+This should be HW default, however I found that on Asus RT-AX89X that uses
+AQR113C PHY and firmware 5.4 this bit is set by default.
+
+With this bit set the AQR cannot achieve a link with its link-partner and
+it took me multiple hours of digging through the vendor GPL source to find
+this out, so lets always clear this bit during .config_init() to avoid a
+situation like this in the future.
+
+aqr107_wait_processor_intensive_op() is moved up because datasheet notes
+that any changes to this bit are processor intensive.
+
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+---
+ drivers/net/phy/aquantia/aquantia_main.c | 57 ++++++++++++++----------
+ 1 file changed, 33 insertions(+), 24 deletions(-)
+
+--- a/drivers/net/phy/aquantia/aquantia_main.c
++++ b/drivers/net/phy/aquantia/aquantia_main.c
+@@ -473,6 +473,30 @@ static void aqr107_chip_info(struct phy_
+ fw_major, fw_minor, build_id, prov_id);
+ }
+
++static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
++{
++ int val, err;
++
++ /* The datasheet notes to wait at least 1ms after issuing a
++ * processor intensive operation before checking.
++ * We cannot use the 'sleep_before_read' parameter of read_poll_timeout
++ * because that just determines the maximum time slept, not the minimum.
++ */
++ usleep_range(1000, 5000);
++
++ err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
++ VEND1_GLOBAL_GEN_STAT2, val,
++ !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
++ AQR107_OP_IN_PROG_SLEEP,
++ AQR107_OP_IN_PROG_TIMEOUT, false);
++ if (err) {
++ phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
++ return err;
++ }
++
++ return 0;
++}
++
+ static int aqr107_config_init(struct phy_device *phydev)
+ {
+ struct aqr107_priv *priv = phydev->priv;
+@@ -498,6 +522,15 @@ static int aqr107_config_init(struct phy
+ if (!ret)
+ aqr107_chip_info(phydev);
+
++ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
++ MDIO_PMD_TXDIS_GLOBAL);
++ if (ret)
++ return ret;
++
++ ret = aqr107_wait_processor_intensive_op(phydev);
++ if (ret)
++ return ret;
++
+ ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
+ if (ret)
+ return ret;
+@@ -580,30 +613,6 @@ static void aqr107_link_change_notify(st
+ phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
+ }
+
+-static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
+-{
+- int val, err;
+-
+- /* The datasheet notes to wait at least 1ms after issuing a
+- * processor intensive operation before checking.
+- * We cannot use the 'sleep_before_read' parameter of read_poll_timeout
+- * because that just determines the maximum time slept, not the minimum.
+- */
+- usleep_range(1000, 5000);
+-
+- err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+- VEND1_GLOBAL_GEN_STAT2, val,
+- !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
+- AQR107_OP_IN_PROG_SLEEP,
+- AQR107_OP_IN_PROG_TIMEOUT, false);
+- if (err) {
+- phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
+- return err;
+- }
+-
+- return 0;
+-}
+-
+ static int aqr107_get_rate_matching(struct phy_device *phydev,
+ phy_interface_t iface)
+ {
diff --git a/target/linux/generic/backport-6.6/853-v6.10-bus-mhi-host-Add-mhi_power_down_keep_dev-API-to-supp.patch b/target/linux/generic/backport-6.6/853-v6.10-bus-mhi-host-Add-mhi_power_down_keep_dev-API-to-supp.patch
new file mode 100644
index 0000000000..826b39b518
--- /dev/null
+++ b/target/linux/generic/backport-6.6/853-v6.10-bus-mhi-host-Add-mhi_power_down_keep_dev-API-to-supp.patch
@@ -0,0 +1,140 @@
+--- a/drivers/bus/mhi/host/init.c
++++ b/drivers/bus/mhi/host/init.c
+@@ -43,6 +43,7 @@ const char * const dev_state_tran_str[DE
+ [DEV_ST_TRANSITION_FP] = "FLASH PROGRAMMER",
+ [DEV_ST_TRANSITION_SYS_ERR] = "SYS ERROR",
+ [DEV_ST_TRANSITION_DISABLE] = "DISABLE",
++ [DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE] = "DISABLE (DESTROY DEVICE)",
+ };
+
+ const char * const mhi_ch_state_type_str[MHI_CH_STATE_TYPE_MAX] = {
+--- a/drivers/bus/mhi/host/internal.h
++++ b/drivers/bus/mhi/host/internal.h
+@@ -69,6 +69,7 @@ enum dev_st_transition {
+ DEV_ST_TRANSITION_FP,
+ DEV_ST_TRANSITION_SYS_ERR,
+ DEV_ST_TRANSITION_DISABLE,
++ DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE,
+ DEV_ST_TRANSITION_MAX,
+ };
+
+--- a/drivers/bus/mhi/host/pm.c
++++ b/drivers/bus/mhi/host/pm.c
+@@ -466,7 +466,8 @@ error_mission_mode:
+ }
+
+ /* Handle shutdown transitions */
+-static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl)
++static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,
++ bool destroy_device)
+ {
+ enum mhi_pm_state cur_state;
+ struct mhi_event *mhi_event;
+@@ -528,8 +529,16 @@ skip_mhi_reset:
+ dev_dbg(dev, "Waiting for all pending threads to complete\n");
+ wake_up_all(&mhi_cntrl->state_event);
+
+- dev_dbg(dev, "Reset all active channels and remove MHI devices\n");
+- device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device);
++ /*
++ * Only destroy the 'struct device' for channels if indicated by the
++ * 'destroy_device' flag. Because, during system suspend or hibernation
++ * state, there is no need to destroy the 'struct device' as the endpoint
++ * device would still be physically attached to the machine.
++ */
++ if (destroy_device) {
++ dev_dbg(dev, "Reset all active channels and remove MHI devices\n");
++ device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device);
++ }
+
+ mutex_lock(&mhi_cntrl->pm_mutex);
+
+@@ -820,7 +829,10 @@ void mhi_pm_st_worker(struct work_struct
+ mhi_pm_sys_error_transition(mhi_cntrl);
+ break;
+ case DEV_ST_TRANSITION_DISABLE:
+- mhi_pm_disable_transition(mhi_cntrl);
++ mhi_pm_disable_transition(mhi_cntrl, false);
++ break;
++ case DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE:
++ mhi_pm_disable_transition(mhi_cntrl, true);
+ break;
+ default:
+ break;
+@@ -1174,7 +1186,8 @@ error_exit:
+ }
+ EXPORT_SYMBOL_GPL(mhi_async_power_up);
+
+-void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
++static void __mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful,
++ bool destroy_device)
+ {
+ enum mhi_pm_state cur_state, transition_state;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
+@@ -1210,15 +1223,32 @@ void mhi_power_down(struct mhi_controlle
+ write_unlock_irq(&mhi_cntrl->pm_lock);
+ mutex_unlock(&mhi_cntrl->pm_mutex);
+
+- mhi_queue_state_transition(mhi_cntrl, DEV_ST_TRANSITION_DISABLE);
++ if (destroy_device)
++ mhi_queue_state_transition(mhi_cntrl,
++ DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE);
++ else
++ mhi_queue_state_transition(mhi_cntrl,
++ DEV_ST_TRANSITION_DISABLE);
+
+ /* Wait for shutdown to complete */
+ flush_work(&mhi_cntrl->st_worker);
+
+ disable_irq(mhi_cntrl->irq[0]);
+ }
++
++void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
++{
++ __mhi_power_down(mhi_cntrl, graceful, true);
++}
+ EXPORT_SYMBOL_GPL(mhi_power_down);
+
++void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl,
++ bool graceful)
++{
++ __mhi_power_down(mhi_cntrl, graceful, false);
++}
++EXPORT_SYMBOL_GPL(mhi_power_down_keep_dev);
++
+ int mhi_sync_power_up(struct mhi_controller *mhi_cntrl)
+ {
+ int ret = mhi_async_power_up(mhi_cntrl);
+--- a/include/linux/mhi.h
++++ b/include/linux/mhi.h
+@@ -649,13 +649,29 @@ int mhi_async_power_up(struct mhi_contro
+ int mhi_sync_power_up(struct mhi_controller *mhi_cntrl);
+
+ /**
+- * mhi_power_down - Start MHI power down sequence
++ * mhi_power_down - Power down the MHI device and also destroy the
++ * 'struct device' for the channels associated with it.
++ * See also mhi_power_down_keep_dev() which is a variant
++ * of this API that keeps the 'struct device' for channels
++ * (useful during suspend/hibernation).
+ * @mhi_cntrl: MHI controller
+ * @graceful: Link is still accessible, so do a graceful shutdown process
+ */
+ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful);
+
+ /**
++ * mhi_power_down_keep_dev - Power down the MHI device but keep the 'struct
++ * device' for the channels associated with it.
++ * This is a variant of 'mhi_power_down()' and
++ * useful in scenarios such as suspend/hibernation
++ * where destroying of the 'struct device' is not
++ * needed.
++ * @mhi_cntrl: MHI controller
++ * @graceful: Link is still accessible, so do a graceful shutdown process
++ */
++void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl, bool graceful);
++
++/**
+ * mhi_unprepare_after_power_down - Free any allocated memory after power down
+ * @mhi_cntrl: MHI controller
+ */
diff --git a/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch b/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch
index 9c61ff27ab..8e57193ef1 100644
--- a/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch
+++ b/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch
@@ -123,7 +123,7 @@ Signed-off-by: Justin Stitt <justinstitt@google.com>
#endif /* _LINUX_ETHTOOL_H */
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
-@@ -1991,6 +1991,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
+@@ -1994,6 +1994,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
}
EXPORT_SYMBOL(ethtool_sprintf);
diff --git a/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch b/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch
index d9265cad10..48dd6ffb67 100644
--- a/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch
+++ b/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch
@@ -19,7 +19,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3668,7 +3668,7 @@ static int mv88e6xxx_mdio_register(struc
+@@ -3669,7 +3669,7 @@ static int mv88e6xxx_mdio_register(struc
if (external) {
mv88e6xxx_reg_lock(chip);
diff --git a/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch b/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch
index 5661d50adb..e5931573f7 100644
--- a/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch
+++ b/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch
@@ -27,7 +27,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3668,7 +3668,10 @@ static int mv88e6xxx_mdio_register(struc
+@@ -3669,7 +3669,10 @@ static int mv88e6xxx_mdio_register(struc
if (external) {
mv88e6xxx_reg_lock(chip);
diff --git a/target/linux/generic/backport-6.6/898-v6.7-mtd-spinand-winbond-add-support-for-serial-NAND-flash.patch b/target/linux/generic/backport-6.6/898-v6.7-mtd-spinand-winbond-add-support-for-serial-NAND-flash.patch
new file mode 100644
index 0000000000..b5aeaef835
--- /dev/null
+++ b/target/linux/generic/backport-6.6/898-v6.7-mtd-spinand-winbond-add-support-for-serial-NAND-flash.patch
@@ -0,0 +1,75 @@
+From 6a804fb72de56d6a99b799f565ae45f2cec7cd55 Mon Sep 17 00:00:00 2001
+From: Sridharan S N <quic_sridsn@quicinc.com>
+Date: Thu, 12 Oct 2023 12:11:34 +0530
+Subject: mtd: spinand: winbond: add support for serial NAND flash
+
+Add support for W25N01JW, W25N02JWZEIF, W25N512GW,
+W25N02KWZEIR and W25N01GWZEIG.
+
+W25N02KWZEIR has 8b/512b on-die ECC capability and other
+four has 4b/512b on-die ECC capability.
+
+Signed-off-by: Sridharan S N <quic_sridsn@quicinc.com>
+Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20231012064134.4068621-1-quic_sridsn@quicinc.com
+---
+ drivers/mtd/nand/spi/winbond.c | 45 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+(limited to 'drivers/mtd/nand/spi/winbond.c')
+
+--- a/drivers/mtd/nand/spi/winbond.c
++++ b/drivers/mtd/nand/spi/winbond.c
+@@ -169,6 +169,51 @@ static const struct spinand_info winbond
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
++ SPINAND_INFO("W25N01JW",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
++ SPINAND_INFO("W25N02JWZEIF",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
++ SPINAND_INFO("W25N512GW",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x20),
++ NAND_MEMORG(1, 2048, 64, 64, 512, 10, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
++ SPINAND_INFO("W25N02KWZEIR",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
++ SPINAND_INFO("W25N01GWZEIG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21),
++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
+ };
+
+ static int winbond_spinand_init(struct spinand_device *spinand)
diff --git a/target/linux/generic/backport-6.6/899-v6.9-mtd-spinand-winbond-add-W25N04KV.patch b/target/linux/generic/backport-6.6/899-v6.9-mtd-spinand-winbond-add-W25N04KV.patch
new file mode 100644
index 0000000000..3e5d918c61
--- /dev/null
+++ b/target/linux/generic/backport-6.6/899-v6.9-mtd-spinand-winbond-add-W25N04KV.patch
@@ -0,0 +1,53 @@
+From e0ccf861b80698a5cc6f97c89bf8d5761f465fce Mon Sep 17 00:00:00 2001
+From: Zhi-Jun You <hujy652@gmail.com>
+Date: Sun, 7 Jan 2024 14:41:20 +0000
+Subject: mtd: spinand: winbond: add support for W25N04KV
+
+Add support for W25N04KV.
+
+W25N04KV has 8-bit on-die ECC.
+
+Signed-off-by: Zhi-Jun You <hujy652@gmail.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20240107144120.532-1-hujy652@gmail.com
+---
+ drivers/mtd/nand/spi/winbond.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+(limited to 'drivers/mtd/nand/spi/winbond.c')
+
+--- a/drivers/mtd/nand/spi/winbond.c
++++ b/drivers/mtd/nand/spi/winbond.c
+@@ -15,6 +15,8 @@
+
+ #define WINBOND_CFG_BUF_READ BIT(3)
+
++#define W25N04KV_STATUS_ECC_5_8_BITFLIPS (3 << 4)
++
+ static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+@@ -118,6 +120,7 @@ static int w25n02kv_ecc_get_status(struc
+ return -EBADMSG;
+
+ case STATUS_ECC_HAS_BITFLIPS:
++ case W25N04KV_STATUS_ECC_5_8_BITFLIPS:
+ /*
+ * Let's try to retrieve the real maximum number of bitflips
+ * in order to avoid forcing the wear-leveling layer to move
+@@ -214,6 +217,15 @@ static const struct spinand_info winbond
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
++ SPINAND_INFO("W25N04KV",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
++ NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+ };
+
+ static int winbond_spinand_init(struct spinand_device *spinand)
diff --git a/target/linux/generic/backport-6.6/900-v6.11-net-free_netdev-exit-earlier-if-dummy.patch b/target/linux/generic/backport-6.6/900-v6.11-net-free_netdev-exit-earlier-if-dummy.patch
new file mode 100644
index 0000000000..31beb11d54
--- /dev/null
+++ b/target/linux/generic/backport-6.6/900-v6.11-net-free_netdev-exit-earlier-if-dummy.patch
@@ -0,0 +1,35 @@
+From f8d05679fb3faae478d604177b0c188b340371cd Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Mon, 22 Apr 2024 05:38:55 -0700
+Subject: [PATCH] net: free_netdev: exit earlier if dummy
+
+For dummy devices, exit earlier at free_netdev() instead of executing
+the whole function. This is necessary, because dummy devices are
+special, and shouldn't have the second part of the function executed.
+
+Otherwise reg_state, which is NETREG_DUMMY, will be overwritten and
+there will be no way to identify that this is a dummy device. Also, this
+device do not need the final put_device(), since dummy devices are not
+registered (through register_netdevice()), where the device reference is
+increased (at netdev_register_kobject()/device_add()).
+
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/core/dev.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -10966,7 +10966,8 @@ void free_netdev(struct net_device *dev)
+ dev->xdp_bulkq = NULL;
+
+ /* Compatibility with error handling in drivers */
+- if (dev->reg_state == NETREG_UNINITIALIZED) {
++ if (dev->reg_state == NETREG_UNINITIALIZED ||
++ dev->reg_state == NETREG_DUMMY) {
+ netdev_freemem(dev);
+ return;
+ }
diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15
deleted file mode 100644
index cba00711ca..0000000000
--- a/target/linux/generic/config-5.15
+++ /dev/null
@@ -1,7617 +0,0 @@
-# CONFIG_104_QUAD_8 is not set
-CONFIG_32BIT=y
-CONFIG_64BIT_TIME=y
-# CONFIG_6LOWPAN is not set
-# CONFIG_6LOWPAN_DEBUGFS is not set
-# CONFIG_6PACK is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_9P_FS is not set
-# CONFIG_AB3100_CORE is not set
-# CONFIG_AB8500_CORE is not set
-# CONFIG_ABP060MG is not set
-# CONFIG_ABX500_CORE is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_ACENIC is not set
-# CONFIG_ACERHDF is not set
-# CONFIG_ACER_WIRELESS is not set
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_ACPI_ALS is not set
-# CONFIG_ACPI_APEI is not set
-# CONFIG_ACPI_APEI_PCIEAER is not set
-# CONFIG_ACPI_BUTTON is not set
-# CONFIG_ACPI_CONFIGFS is not set
-# CONFIG_ACPI_CUSTOM_METHOD is not set
-# CONFIG_ACPI_EXTLOG is not set
-# CONFIG_ACPI_HED is not set
-# CONFIG_ACPI_NFIT is not set
-# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
-# CONFIG_ACPI_TABLE_UPGRADE is not set
-# CONFIG_ACPI_VIDEO is not set
-# CONFIG_AD2S1200 is not set
-# CONFIG_AD2S1210 is not set
-# CONFIG_AD2S90 is not set
-# CONFIG_AD5064 is not set
-# CONFIG_AD5110 is not set
-# CONFIG_AD525X_DPOT is not set
-# CONFIG_AD5272 is not set
-# CONFIG_AD5360 is not set
-# CONFIG_AD5380 is not set
-# CONFIG_AD5421 is not set
-# CONFIG_AD5446 is not set
-# CONFIG_AD5449 is not set
-# CONFIG_AD5504 is not set
-# CONFIG_AD5592R is not set
-# CONFIG_AD5593R is not set
-# CONFIG_AD5624R_SPI is not set
-# CONFIG_AD5686 is not set
-# CONFIG_AD5686_SPI is not set
-# CONFIG_AD5696_I2C is not set
-# CONFIG_AD5755 is not set
-# CONFIG_AD5758 is not set
-# CONFIG_AD5761 is not set
-# CONFIG_AD5764 is not set
-# CONFIG_AD5766 is not set
-# CONFIG_AD5770R is not set
-# CONFIG_AD5791 is not set
-# CONFIG_AD5933 is not set
-# CONFIG_AD7091R5 is not set
-# CONFIG_AD7124 is not set
-# CONFIG_AD7150 is not set
-# CONFIG_AD7152 is not set
-# CONFIG_AD7192 is not set
-# CONFIG_AD7266 is not set
-# CONFIG_AD7280 is not set
-# CONFIG_AD7291 is not set
-# CONFIG_AD7292 is not set
-# CONFIG_AD7298 is not set
-# CONFIG_AD7303 is not set
-# CONFIG_AD7476 is not set
-# CONFIG_AD7606 is not set
-# CONFIG_AD7606_IFACE_PARALLEL is not set
-# CONFIG_AD7606_IFACE_SPI is not set
-# CONFIG_AD7746 is not set
-# CONFIG_AD7766 is not set
-# CONFIG_AD7768_1 is not set
-# CONFIG_AD7780 is not set
-# CONFIG_AD7791 is not set
-# CONFIG_AD7793 is not set
-# CONFIG_AD7816 is not set
-# CONFIG_AD7887 is not set
-# CONFIG_AD7923 is not set
-# CONFIG_AD7949 is not set
-# CONFIG_AD799X is not set
-# CONFIG_AD8366 is not set
-# CONFIG_AD8801 is not set
-# CONFIG_AD9467 is not set
-# CONFIG_AD9523 is not set
-# CONFIG_AD9832 is not set
-# CONFIG_AD9834 is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ADE7854 is not set
-# CONFIG_ADF4350 is not set
-# CONFIG_ADF4371 is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADIN_PHY is not set
-# CONFIG_ADIS16080 is not set
-# CONFIG_ADIS16130 is not set
-# CONFIG_ADIS16136 is not set
-# CONFIG_ADIS16201 is not set
-# CONFIG_ADIS16203 is not set
-# CONFIG_ADIS16209 is not set
-# CONFIG_ADIS16240 is not set
-# CONFIG_ADIS16260 is not set
-# CONFIG_ADIS16400 is not set
-# CONFIG_ADIS16460 is not set
-# CONFIG_ADIS16475 is not set
-# CONFIG_ADIS16480 is not set
-# CONFIG_ADI_AXI_ADC is not set
-# CONFIG_ADJD_S311 is not set
-# CONFIG_ADM6996_PHY is not set
-# CONFIG_ADM8211 is not set
-# CONFIG_ADT7316 is not set
-# CONFIG_ADUX1020 is not set
-CONFIG_ADVISE_SYSCALLS=y
-# CONFIG_ADXL345_I2C is not set
-# CONFIG_ADXL345_SPI is not set
-# CONFIG_ADXL372_I2C is not set
-# CONFIG_ADXL372_SPI is not set
-# CONFIG_ADXRS290 is not set
-# CONFIG_ADXRS450 is not set
-CONFIG_AEABI=y
-# CONFIG_AFE4403 is not set
-# CONFIG_AFE4404 is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_AFS_DEBUG_CURSOR is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_AF_KCM is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_AF_RXRPC_INJECT_LOSS is not set
-# CONFIG_AF_RXRPC_IPV6 is not set
-CONFIG_AF_UNIX_OOB=y
-# CONFIG_AGP is not set
-# CONFIG_AHCI_BRCM is not set
-# CONFIG_AHCI_CEVA is not set
-# CONFIG_AHCI_IMX is not set
-# CONFIG_AHCI_MVEBU is not set
-# CONFIG_AHCI_QORIQ is not set
-# CONFIG_AHCI_XGENE is not set
-CONFIG_AIO=y
-# CONFIG_AIRO is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_AIX_PARTITION is not set
-# CONFIG_AK09911 is not set
-# CONFIG_AK8974 is not set
-# CONFIG_AK8975 is not set
-# CONFIG_AL3010 is not set
-# CONFIG_AL3320A is not set
-# CONFIG_ALIM7101_WDT is not set
-CONFIG_ALLOW_DEV_COREDUMP=y
-# CONFIG_ALTERA_MBOX is not set
-# CONFIG_ALTERA_MSGDMA is not set
-# CONFIG_ALTERA_STAPL is not set
-# CONFIG_ALTERA_TSE is not set
-# CONFIG_ALX is not set
-# CONFIG_AL_FIC is not set
-# CONFIG_AM2315 is not set
-# CONFIG_AM335X_PHY_USB is not set
-# CONFIG_AMBA_PL08X is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_AMD_MEM_ENCRYPT is not set
-# CONFIG_AMD_PHY is not set
-# CONFIG_AMD_XGBE is not set
-# CONFIG_AMD_XGBE_HAVE_ECC is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_AMILO_RFKILL is not set
-# CONFIG_ANDROID is not set
-CONFIG_ANON_INODES=y
-# CONFIG_APDS9300 is not set
-# CONFIG_APDS9802ALS is not set
-# CONFIG_APDS9960 is not set
-# CONFIG_APM8018X is not set
-# CONFIG_APM_EMULATION is not set
-# CONFIG_APPLE_GMUX is not set
-# CONFIG_APPLE_MFI_FASTCHARGE is not set
-# CONFIG_APPLE_PROPERTIES is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_AQTION is not set
-# CONFIG_AQUANTIA_PHY is not set
-# CONFIG_AR5523 is not set
-# CONFIG_AR7 is not set
-# CONFIG_AR8216_PHY is not set
-# CONFIG_AR8216_PHY_LEDS is not set
-# CONFIG_ARCH_ACTIONS is not set
-# CONFIG_ARCH_AGILEX is not set
-# CONFIG_ARCH_ALPINE is not set
-# CONFIG_ARCH_APPLE is not set
-# CONFIG_ARCH_ARTPEC is not set
-# CONFIG_ARCH_ASPEED is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_AXXIA is not set
-# CONFIG_ARCH_BCM is not set
-# CONFIG_ARCH_BCM2835 is not set
-# CONFIG_ARCH_BCM4908 is not set
-# CONFIG_ARCH_BCM_21664 is not set
-# CONFIG_ARCH_BCM_23550 is not set
-# CONFIG_ARCH_BCM_281XX is not set
-# CONFIG_ARCH_BCM_5301X is not set
-# CONFIG_ARCH_BCM_53573 is not set
-# CONFIG_ARCH_BCM_63XX is not set
-# CONFIG_ARCH_BCM_CYGNUS is not set
-# CONFIG_ARCH_BCM_IPROC is not set
-# CONFIG_ARCH_BCM_NSP is not set
-# CONFIG_ARCH_BERLIN is not set
-CONFIG_ARCH_BINFMT_ELF_STATE=y
-# CONFIG_ARCH_BITMAIN is not set
-# CONFIG_ARCH_BRCMSTB is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CNS3XXX is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_DIGICOLOR is not set
-# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
-# CONFIG_ARCH_DOVE is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_EXYNOS is not set
-CONFIG_ARCH_FLATMEM_ENABLE=y
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_HI3xxx is not set
-# CONFIG_ARCH_HIGHBANK is not set
-# CONFIG_ARCH_HISI is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_INTEL_SOCFPGA is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_K3 is not set
-# CONFIG_ARCH_KEEMBAY is not set
-# CONFIG_ARCH_KEYSTONE is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_LAYERSCAPE is not set
-# CONFIG_ARCH_LG1K is not set
-# CONFIG_ARCH_LPC32XX is not set
-# CONFIG_ARCH_MEDIATEK is not set
-# CONFIG_ARCH_MESON is not set
-# CONFIG_ARCH_MILBEAUT is not set
-CONFIG_ARCH_MMAP_RND_BITS=8
-CONFIG_ARCH_MMAP_RND_BITS_MAX=16
-CONFIG_ARCH_MMAP_RND_BITS_MIN=8
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_MSTARV7 is not set
-# CONFIG_ARCH_MULTIPLATFORM is not set
-# CONFIG_ARCH_MULTI_V6 is not set
-# CONFIG_ARCH_MULTI_V7 is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MVEBU is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_MXS is not set
-# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_NOMADIK is not set
-# CONFIG_ARCH_NPCM is not set
-# CONFIG_ARCH_NSPIRE is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_OMAP1 is not set
-# CONFIG_ARCH_OMAP2 is not set
-# CONFIG_ARCH_OMAP2PLUS is not set
-# CONFIG_ARCH_OMAP3 is not set
-# CONFIG_ARCH_OMAP4 is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_OXNAS is not set
-# CONFIG_ARCH_PICOXCELL is not set
-# CONFIG_ARCH_PRIMA2 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_QCOM is not set
-# CONFIG_ARCH_RANDOM is not set
-# CONFIG_ARCH_RDA is not set
-# CONFIG_ARCH_REALTEK is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_RENESAS is not set
-# CONFIG_ARCH_ROCKCHIP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_S32 is not set
-# CONFIG_ARCH_S3C24XX is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5PV210 is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SEATTLE is not set
-# CONFIG_ARCH_SHMOBILE is not set
-# CONFIG_ARCH_SIRF is not set
-# CONFIG_ARCH_SOCFPGA is not set
-# CONFIG_ARCH_SPARX5 is not set
-# CONFIG_ARCH_SPRD is not set
-# CONFIG_ARCH_STI is not set
-# CONFIG_ARCH_STM32 is not set
-# CONFIG_ARCH_STRATIX10 is not set
-# CONFIG_ARCH_SUNXI is not set
-# CONFIG_ARCH_SYNQUACER is not set
-# CONFIG_ARCH_TANGO is not set
-# CONFIG_ARCH_TEGRA is not set
-# CONFIG_ARCH_THUNDER is not set
-# CONFIG_ARCH_THUNDER2 is not set
-# CONFIG_ARCH_U300 is not set
-# CONFIG_ARCH_U8500 is not set
-# CONFIG_ARCH_UNIPHIER is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_VEXPRESS is not set
-# CONFIG_ARCH_VIRT is not set
-# CONFIG_ARCH_VISCONTI is not set
-# CONFIG_ARCH_VT8500 is not set
-# CONFIG_ARCH_VULCAN is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_WANTS_THP_SWAP is not set
-# CONFIG_ARCH_WM8505 is not set
-# CONFIG_ARCH_WM8750 is not set
-# CONFIG_ARCH_WM8850 is not set
-# CONFIG_ARCH_XGENE is not set
-# CONFIG_ARCH_ZX is not set
-# CONFIG_ARCH_ZYNQ is not set
-# CONFIG_ARCH_ZYNQMP is not set
-# CONFIG_ARCNET is not set
-# CONFIG_ARC_EMAC is not set
-# CONFIG_ARC_IRQ_NO_AUTOSAVE is not set
-# CONFIG_ARM64_16K_PAGES is not set
-# CONFIG_ARM64_64K_PAGES is not set
-# CONFIG_ARM64_AMU_EXTN is not set
-# CONFIG_ARM64_BTI is not set
-# CONFIG_ARM64_CRYPTO is not set
-# CONFIG_ARM64_E0PD is not set
-# CONFIG_ARM64_ERRATUM_1024718 is not set
-# CONFIG_ARM64_ERRATUM_1165522 is not set
-# CONFIG_ARM64_ERRATUM_1286807 is not set
-# CONFIG_ARM64_ERRATUM_1319367 is not set
-# CONFIG_ARM64_ERRATUM_1418040 is not set
-# CONFIG_ARM64_ERRATUM_1463225 is not set
-# CONFIG_ARM64_ERRATUM_1508412 is not set
-# CONFIG_ARM64_ERRATUM_1530923 is not set
-# CONFIG_ARM64_ERRATUM_1542419 is not set
-# CONFIG_ARM64_ERRATUM_1742098 is not set
-# CONFIG_ARM64_ERRATUM_2253138 is not set
-# CONFIG_ARM64_ERRATUM_2224489 is not set
-# CONFIG_ARM64_ERRATUM_2054223 is not set
-# CONFIG_ARM64_ERRATUM_2067961 is not set
-# CONFIG_ARM64_ERRATUM_2441007 is not set
-# CONFIG_ARM64_ERRATUM_2441009 is not set
-# CONFIG_ARM64_ERRATUM_819472 is not set
-# CONFIG_ARM64_ERRATUM_824069 is not set
-# CONFIG_ARM64_ERRATUM_826319 is not set
-# CONFIG_ARM64_ERRATUM_827319 is not set
-# CONFIG_ARM64_ERRATUM_832075 is not set
-# CONFIG_ARM64_ERRATUM_834220 is not set
-# CONFIG_ARM64_ERRATUM_843419 is not set
-# CONFIG_ARM64_ERRATUM_845719 is not set
-# CONFIG_ARM64_ERRATUM_858921 is not set
-# CONFIG_ARM64_HW_AFDBM is not set
-# CONFIG_ARM64_LSE_ATOMICS is not set
-CONFIG_ARM64_MODULE_PLTS=y
-# CONFIG_ARM64_MTE is not set
-# CONFIG_ARM64_PAN is not set
-# CONFIG_ARM64_PMEM is not set
-# CONFIG_ARM64_PSEUDO_NMI is not set
-# CONFIG_ARM64_PTDUMP_DEBUGFS is not set
-# CONFIG_ARM64_PTR_AUTH is not set
-# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set
-# CONFIG_ARM64_RAS_EXTN is not set
-# CONFIG_ARM64_RELOC_TEST is not set
-# CONFIG_ARM64_SVE is not set
-CONFIG_ARM64_SW_TTBR0_PAN=y
-# CONFIG_ARM64_TLB_RANGE is not set
-# CONFIG_ARM64_UAO is not set
-# CONFIG_ARM64_USE_LSE_ATOMICS is not set
-# CONFIG_ARM64_VA_BITS_48 is not set
-# CONFIG_ARM64_VHE is not set
-# CONFIG_ARM_APPENDED_DTB is not set
-# CONFIG_ARM_ARCH_TIMER is not set
-# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
-# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
-# CONFIG_ARM_CCI is not set
-# CONFIG_ARM_CCI400_PMU is not set
-# CONFIG_ARM_CCI5xx_PMU is not set
-# CONFIG_ARM_CCI_PMU is not set
-# CONFIG_ARM_CCN is not set
-# CONFIG_ARM_CMN is not set
-# CONFIG_ARM_CPUIDLE is not set
-CONFIG_ARM_CPU_TOPOLOGY=y
-# CONFIG_ARM_CRYPTO is not set
-CONFIG_ARM_DMA_MEM_BUFFERABLE=y
-# CONFIG_ARM_DSU_PMU is not set
-# CONFIG_ARM_ERRATA_326103 is not set
-# CONFIG_ARM_ERRATA_364296 is not set
-# CONFIG_ARM_ERRATA_411920 is not set
-# CONFIG_ARM_ERRATA_430973 is not set
-# CONFIG_ARM_ERRATA_458693 is not set
-# CONFIG_ARM_ERRATA_460075 is not set
-# CONFIG_ARM_ERRATA_643719 is not set
-# CONFIG_ARM_ERRATA_720789 is not set
-# CONFIG_ARM_ERRATA_742230 is not set
-# CONFIG_ARM_ERRATA_742231 is not set
-# CONFIG_ARM_ERRATA_743622 is not set
-# CONFIG_ARM_ERRATA_751472 is not set
-# CONFIG_ARM_ERRATA_754322 is not set
-# CONFIG_ARM_ERRATA_754327 is not set
-# CONFIG_ARM_ERRATA_764369 is not set
-# CONFIG_ARM_ERRATA_773022 is not set
-# CONFIG_ARM_ERRATA_775420 is not set
-# CONFIG_ARM_ERRATA_798181 is not set
-# CONFIG_ARM_ERRATA_814220 is not set
-# CONFIG_ARM_ERRATA_818325_852422 is not set
-# CONFIG_ARM_ERRATA_821420 is not set
-# CONFIG_ARM_ERRATA_825619 is not set
-# CONFIG_ARM_ERRATA_852421 is not set
-# CONFIG_ARM_ERRATA_852423 is not set
-# CONFIG_ARM_ERRATA_857271 is not set
-# CONFIG_ARM_ERRATA_857272 is not set
-# CONFIG_ARM_FFA_TRANSPORT is not set
-CONFIG_ARM_GIC_MAX_NR=1
-# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
-# CONFIG_ARM_KPROBES_TEST is not set
-# CONFIG_ARM_LPAE is not set
-# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set
-# CONFIG_ARM_MHU is not set
-CONFIG_ARM_MODULE_PLTS=y
-# CONFIG_ARM_PATCH_PHYS_VIRT is not set
-# CONFIG_ARM_PSCI is not set
-# CONFIG_ARM_PSCI_CHECKER is not set
-# CONFIG_ARM_PSCI_CPUIDLE is not set
-# CONFIG_ARM_PTDUMP_DEBUGFS is not set
-# CONFIG_ARM_SBSA_WATCHDOG is not set
-# CONFIG_ARM_SCMI_PROTOCOL is not set
-# CONFIG_ARM_SCPI_PROTOCOL is not set
-# CONFIG_ARM_SDE_INTERFACE is not set
-# CONFIG_ARM_SMCCC_SOC_ID is not set
-# CONFIG_ARM_SMC_WATCHDOG is not set
-# CONFIG_ARM_SP805_WATCHDOG is not set
-# CONFIG_ARM_SPE_PMU is not set
-# CONFIG_ARM_THUMBEE is not set
-# CONFIG_ARM_TIMER_SP804 is not set
-# CONFIG_ARM_UNWIND is not set
-# CONFIG_ARM_VIRT_EXT is not set
-# CONFIG_AS3935 is not set
-# CONFIG_AS73211 is not set
-# CONFIG_ASM9260_TIMER is not set
-# CONFIG_ASN1 is not set
-# CONFIG_ASUS_LAPTOP is not set
-# CONFIG_ASUS_WIRELESS is not set
-# CONFIG_ASYMMETRIC_KEY_TYPE is not set
-# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set
-# CONFIG_ASYNC_RAID6_TEST is not set
-# CONFIG_ASYNC_TX_DMA is not set
-# CONFIG_AT76C50X_USB is not set
-# CONFIG_AT803X_PHY is not set
-# CONFIG_AT91_SAMA5D2_ADC is not set
-# CONFIG_ATA is not set
-# CONFIG_ATAGS is not set
-CONFIG_ATAGS_PROC=y
-# CONFIG_ATALK is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_ATA_ACPI is not set
-CONFIG_ATA_BMDMA=y
-# CONFIG_ATA_FORCE is not set
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_ATA_LEDS is not set
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_ATA_PIIX is not set
-CONFIG_ATA_SFF=y
-# CONFIG_ATA_VERBOSE_ERROR is not set
-# CONFIG_ATH10K is not set
-# CONFIG_ATH25 is not set
-# CONFIG_ATH5K is not set
-# CONFIG_ATH6KL is not set
-# CONFIG_ATH79 is not set
-# CONFIG_ATH9K is not set
-# CONFIG_ATH9K_HTC is not set
-# CONFIG_ATH_DEBUG is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1C is not set
-# CONFIG_ATL1E is not set
-# CONFIG_ATL2 is not set
-# CONFIG_ATLAS_EZO_SENSOR is not set
-# CONFIG_ATLAS_PH_SENSOR is not set
-# CONFIG_ATM is not set
-# CONFIG_ATMEL is not set
-# CONFIG_ATMEL_PIT is not set
-# CONFIG_ATMEL_SSC is not set
-# CONFIG_ATM_AMBASSADOR is not set
-# CONFIG_ATM_BR2684 is not set
-CONFIG_ATM_BR2684_IPFILTER=y
-# CONFIG_ATM_CLIP is not set
-CONFIG_ATM_CLIP_NO_ICMP=y
-# CONFIG_ATM_DRIVERS is not set
-# CONFIG_ATM_DUMMY is not set
-# CONFIG_ATM_ENI is not set
-# CONFIG_ATM_FIRESTREAM is not set
-# CONFIG_ATM_FORE200E is not set
-# CONFIG_ATM_HE is not set
-# CONFIG_ATM_HORIZON is not set
-# CONFIG_ATM_IA is not set
-# CONFIG_ATM_IDT77252 is not set
-# CONFIG_ATM_LANAI is not set
-# CONFIG_ATM_LANE is not set
-# CONFIG_ATM_MPOA is not set
-# CONFIG_ATM_NICSTAR is not set
-# CONFIG_ATM_SOLOS is not set
-# CONFIG_ATM_TCP is not set
-# CONFIG_ATM_ZATM is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_ATP is not set
-# CONFIG_AUDIT is not set
-# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set
-# CONFIG_AURORA_NB8800 is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTO_ZRELADDR is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_AX25 is not set
-# CONFIG_AX25_DAMA_SLAVE is not set
-# CONFIG_AX88796 is not set
-# CONFIG_AX88796B_PHY is not set
-# CONFIG_AXP20X_ADC is not set
-# CONFIG_AXP20X_POWER is not set
-# CONFIG_AXP288_ADC is not set
-# CONFIG_AXP288_FUEL_GAUGE is not set
-# CONFIG_B43 is not set
-# CONFIG_B43LEGACY is not set
-# CONFIG_B44 is not set
-# CONFIG_B53 is not set
-# CONFIG_B53_MDIO_DRIVER is not set
-# CONFIG_B53_MMAP_DRIVER is not set
-# CONFIG_B53_SERDES is not set
-# CONFIG_B53_SPI_DRIVER is not set
-# CONFIG_B53_SRAB_DRIVER is not set
-# CONFIG_BACKLIGHT_ADP8860 is not set
-# CONFIG_BACKLIGHT_ADP8870 is not set
-# CONFIG_BACKLIGHT_APPLE is not set
-# CONFIG_BACKLIGHT_ARCXCNN is not set
-# CONFIG_BACKLIGHT_BD6107 is not set
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
-# CONFIG_BACKLIGHT_GENERIC is not set
-# CONFIG_BACKLIGHT_GPIO is not set
-# CONFIG_BACKLIGHT_KTD253 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-# CONFIG_BACKLIGHT_LED is not set
-# CONFIG_BACKLIGHT_LM3630A is not set
-# CONFIG_BACKLIGHT_LM3639 is not set
-# CONFIG_BACKLIGHT_LP855X is not set
-# CONFIG_BACKLIGHT_LV5207LP is not set
-# CONFIG_BACKLIGHT_PANDORA is not set
-# CONFIG_BACKLIGHT_PM8941_WLED is not set
-# CONFIG_BACKLIGHT_PWM is not set
-# CONFIG_BACKLIGHT_QCOM_WLED is not set
-# CONFIG_BACKLIGHT_RPI is not set
-# CONFIG_BACKLIGHT_SAHARA is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_BAREUDP is not set
-CONFIG_BASE_FULL=y
-CONFIG_BASE_SMALL=0
-# CONFIG_BATMAN_ADV is not set
-# CONFIG_BATTERY_BQ27XXX is not set
-# CONFIG_BATTERY_BQ27XXX_HDQ is not set
-# CONFIG_BATTERY_CW2015 is not set
-# CONFIG_BATTERY_DS2760 is not set
-# CONFIG_BATTERY_DS2780 is not set
-# CONFIG_BATTERY_DS2781 is not set
-# CONFIG_BATTERY_DS2782 is not set
-# CONFIG_BATTERY_GAUGE_LTC2941 is not set
-# CONFIG_BATTERY_GOLDFISH is not set
-# CONFIG_BATTERY_LEGO_EV3 is not set
-# CONFIG_BATTERY_MAX17040 is not set
-# CONFIG_BATTERY_MAX17042 is not set
-# CONFIG_BATTERY_MAX1721X is not set
-# CONFIG_BATTERY_RT5033 is not set
-# CONFIG_BATTERY_SBS is not set
-# CONFIG_BAYCOM_EPP is not set
-# CONFIG_BAYCOM_PAR is not set
-# CONFIG_BAYCOM_SER_FDX is not set
-# CONFIG_BAYCOM_SER_HDX is not set
-# CONFIG_BCACHE is not set
-# CONFIG_BCM47XX is not set
-# CONFIG_BCM54140_PHY is not set
-# CONFIG_BCM63XX is not set
-# CONFIG_BCM63XX_PHY is not set
-# CONFIG_BCM7038_WDT is not set
-# CONFIG_BCM7XXX_PHY is not set
-# CONFIG_BCM84881_PHY is not set
-# CONFIG_BCM87XX_PHY is not set
-# CONFIG_BCMA is not set
-# CONFIG_BCMA_DRIVER_GPIO is not set
-CONFIG_BCMA_POSSIBLE=y
-# CONFIG_BCMGENET is not set
-# CONFIG_BCM_IPROC_ADC is not set
-# CONFIG_BCM_KONA_USB2_PHY is not set
-# CONFIG_BCM_SBA_RAID is not set
-# CONFIG_BCM_VK is not set
-# CONFIG_BDI_SWITCH is not set
-# CONFIG_BE2ISCSI is not set
-# CONFIG_BE2NET is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_BGMAC is not set
-# CONFIG_BH1750 is not set
-# CONFIG_BH1780 is not set
-# CONFIG_BIG_KEYS is not set
-# CONFIG_BIG_LITTLE is not set
-CONFIG_BINARY_PRINTF=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_ELF_FDPIC is not set
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-CONFIG_BINFMT_SCRIPT=y
-CONFIG_BITREVERSE=y
-# CONFIG_BLK_CGROUP_IOCOST is not set
-# CONFIG_BLK_CGROUP_IOLATENCY is not set
-# CONFIG_BLK_CGROUP_IOPRIO is not set
-# CONFIG_BLK_CMDLINE_PARSER is not set
-# CONFIG_BLK_DEBUG_FS is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_BLK_DEV_4DRIVES is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI14XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_ATIIXP is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_BSGLIB is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_CS5535 is not set
-# CONFIG_BLK_DEV_CS5536 is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_DELKIN is not set
-# CONFIG_BLK_DEV_DM is not set
-# CONFIG_BLK_DEV_DRBD is not set
-# CONFIG_BLK_DEV_DTC2278 is not set
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_HT6560B is not set
-# CONFIG_BLK_DEV_IDEACPI is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDECS is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDE_AU1XXX is not set
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_BLK_DEV_IT8172 is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_NULL_BLK is not set
-# CONFIG_BLK_DEV_NVME is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_PLATFORM is not set
-# CONFIG_BLK_DEV_PMEM is not set
-# CONFIG_BLK_DEV_QD65XX is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_RBD is not set
-# CONFIG_BLK_DEV_RSXX is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_SD is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_SKD is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-# CONFIG_BLK_DEV_THROTTLING is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_UMC8672 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_ZONED is not set
-# CONFIG_BLK_INLINE_ENCRYPTION is not set
-# CONFIG_BLK_SED_OPAL is not set
-# CONFIG_BLK_WBT is not set
-CONFIG_BLOCK=y
-# CONFIG_BMA180 is not set
-# CONFIG_BMA220 is not set
-# CONFIG_BMA400 is not set
-# CONFIG_BMC150_ACCEL is not set
-# CONFIG_BMC150_MAGN is not set
-# CONFIG_BMC150_MAGN_I2C is not set
-# CONFIG_BMC150_MAGN_SPI is not set
-# CONFIG_BME680 is not set
-# CONFIG_BMG160 is not set
-# CONFIG_BMI088_ACCEL is not set
-# CONFIG_BMI160_I2C is not set
-# CONFIG_BMI160_SPI is not set
-# CONFIG_BMIPS_GENERIC is not set
-# CONFIG_BMP280 is not set
-# CONFIG_BNA is not set
-# CONFIG_BNX2 is not set
-# CONFIG_BNX2X is not set
-# CONFIG_BNX2X_SRIOV is not set
-# CONFIG_BNXT is not set
-# CONFIG_BONDING is not set
-# CONFIG_BOOKE_WDT is not set
-CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3
-# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-# CONFIG_BOOTTIME_TRACING is not set
-# CONFIG_BOOT_CONFIG is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-CONFIG_BOOT_RAW=y
-# CONFIG_BOUNCE is not set
-CONFIG_BPF=y
-# CONFIG_BPFILTER is not set
-CONFIG_BPF_JIT=y
-# CONFIG_BPF_JIT_ALWAYS_ON is not set
-CONFIG_BPF_JIT_DEFAULT_ON=y
-# CONFIG_BPF_PRELOAD is not set
-# CONFIG_BPF_STREAM_PARSER is not set
-CONFIG_BPF_SYSCALL=y
-CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
-# CONFIG_BPQETHER is not set
-CONFIG_BQL=y
-CONFIG_BRANCH_PROFILE_NONE=y
-# CONFIG_BRCMFMAC is not set
-# CONFIG_BRCMSMAC is not set
-# CONFIG_BRCMSTB_GISB_ARB is not set
-CONFIG_BRIDGE=y
-# CONFIG_BRIDGE_CFM is not set
-# CONFIG_BRIDGE_EBT_802_3 is not set
-# CONFIG_BRIDGE_EBT_AMONG is not set
-# CONFIG_BRIDGE_EBT_ARP is not set
-# CONFIG_BRIDGE_EBT_ARPREPLY is not set
-# CONFIG_BRIDGE_EBT_BROUTE is not set
-# CONFIG_BRIDGE_EBT_DNAT is not set
-# CONFIG_BRIDGE_EBT_IP is not set
-# CONFIG_BRIDGE_EBT_IP6 is not set
-# CONFIG_BRIDGE_EBT_LIMIT is not set
-# CONFIG_BRIDGE_EBT_LOG is not set
-# CONFIG_BRIDGE_EBT_MARK is not set
-# CONFIG_BRIDGE_EBT_MARK_T is not set
-# CONFIG_BRIDGE_EBT_NFLOG is not set
-# CONFIG_BRIDGE_EBT_PKTTYPE is not set
-# CONFIG_BRIDGE_EBT_REDIRECT is not set
-# CONFIG_BRIDGE_EBT_SNAT is not set
-# CONFIG_BRIDGE_EBT_STP is not set
-# CONFIG_BRIDGE_EBT_T_FILTER is not set
-# CONFIG_BRIDGE_EBT_T_NAT is not set
-# CONFIG_BRIDGE_EBT_VLAN is not set
-CONFIG_BRIDGE_IGMP_SNOOPING=y
-# CONFIG_BRIDGE_MRP is not set
-# CONFIG_BRIDGE_NETFILTER is not set
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_BRIDGE_VLAN_FILTERING=y
-# CONFIG_BROADCOM_PHY is not set
-CONFIG_BROKEN_ON_SMP=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_BT is not set
-# CONFIG_BTRFS_ASSERT is not set
-# CONFIG_BTRFS_DEBUG is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_BTRFS_FS_POSIX_ACL is not set
-# CONFIG_BTRFS_FS_REF_VERIFY is not set
-# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
-# CONFIG_BT_AOSPEXT is not set
-# CONFIG_BT_ATH3K is not set
-# CONFIG_BT_BNEP is not set
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-# CONFIG_BT_BREDR is not set
-# CONFIG_BT_CMTP is not set
-# CONFIG_BT_FEATURE_DEBUG is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBPA10X is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBTSDIO is not set
-# CONFIG_BT_HCIBTUSB is not set
-# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set
-# CONFIG_BT_HCIBTUSB_MTK is not set
-# CONFIG_BT_HCIBTUSB_RTL is not set
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIUART_3WIRE is not set
-# CONFIG_BT_HCIUART_AG6XX is not set
-# CONFIG_BT_HCIUART_ATH3K is not set
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_H4=y
-# CONFIG_BT_HCIUART_LL is not set
-# CONFIG_BT_HCIUART_MRVL is not set
-# CONFIG_BT_HCIUART_QCA is not set
-# CONFIG_BT_HCIUART_RTL is not set
-# CONFIG_BT_HCIVHCI is not set
-# CONFIG_BT_HIDP is not set
-# CONFIG_BT_HS is not set
-# CONFIG_BT_LE is not set
-# CONFIG_BT_LEDS is not set
-# CONFIG_BT_MRVL is not set
-# CONFIG_BT_MSFTEXT is not set
-# CONFIG_BT_MTKSDIO is not set
-# CONFIG_BT_MTKUART is not set
-# CONFIG_BT_RFCOMM is not set
-CONFIG_BT_RFCOMM_TTY=y
-# CONFIG_BT_SELFTEST is not set
-# CONFIG_BT_VIRTIO is not set
-CONFIG_BUG=y
-# CONFIG_BUG_ON_DATA_CORRUPTION is not set
-CONFIG_BUILDTIME_EXTABLE_SORT=y
-CONFIG_BUILDTIME_TABLE_SORT=y
-# CONFIG_BUILD_BIN2C is not set
-CONFIG_BUILD_SALT=""
-# CONFIG_C2PORT is not set
-CONFIG_CACHE_L2X0_PMU=y
-# CONFIG_CADENCE_WATCHDOG is not set
-# CONFIG_CAIF is not set
-# CONFIG_CAN is not set
-# CONFIG_CAN_BCM is not set
-# CONFIG_CAN_DEBUG_DEVICES is not set
-# CONFIG_CAN_DEV is not set
-# CONFIG_CAN_ETAS_ES58X is not set
-# CONFIG_CAN_GS_USB is not set
-# CONFIG_CAN_GW is not set
-# CONFIG_CAN_HI311X is not set
-# CONFIG_CAN_IFI_CANFD is not set
-# CONFIG_CAN_ISOTP is not set
-# CONFIG_CAN_J1939 is not set
-# CONFIG_CAN_KVASER_PCIEFD is not set
-# CONFIG_CAN_MCBA_USB is not set
-# CONFIG_CAN_MCP251XFD is not set
-# CONFIG_CAN_M_CAN is not set
-# CONFIG_CAN_PEAK_PCIEFD is not set
-# CONFIG_CAN_RAW is not set
-# CONFIG_CAN_RCAR is not set
-# CONFIG_CAN_RCAR_CANFD is not set
-# CONFIG_CAN_SLCAN is not set
-# CONFIG_CAN_SUN4I is not set
-# CONFIG_CAN_UCAN is not set
-# CONFIG_CAN_VCAN is not set
-# CONFIG_CAN_VXCAN is not set
-# CONFIG_CAPI_AVM is not set
-# CONFIG_CAPI_EICON is not set
-# CONFIG_CAPI_TRACE is not set
-CONFIG_CARDBUS=y
-# CONFIG_CARDMAN_4000 is not set
-# CONFIG_CARDMAN_4040 is not set
-# CONFIG_CARL9170 is not set
-# CONFIG_CASSINI is not set
-# CONFIG_CAVIUM_CPT is not set
-# CONFIG_CAVIUM_ERRATUM_22375 is not set
-# CONFIG_CAVIUM_ERRATUM_23144 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_OCTEON_SOC is not set
-# CONFIG_CAVIUM_PTP is not set
-# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set
-# CONFIG_CB710_CORE is not set
-# CONFIG_CC10001_ADC is not set
-# CONFIG_CCS811 is not set
-CONFIG_CC_CAN_LINK=y
-CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_CEPH_FS is not set
-# CONFIG_CEPH_LIB is not set
-# CONFIG_CFG80211 is not set
-# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
-# CONFIG_CGROUPS is not set
-# CONFIG_CGROUP_MISC is not set
-# CONFIG_CHARGER_ADP5061 is not set
-# CONFIG_CHARGER_BD99954 is not set
-# CONFIG_CHARGER_BQ2415X is not set
-# CONFIG_CHARGER_BQ24190 is not set
-# CONFIG_CHARGER_BQ24257 is not set
-# CONFIG_CHARGER_BQ24735 is not set
-# CONFIG_CHARGER_BQ2515X is not set
-# CONFIG_CHARGER_BQ256XX is not set
-# CONFIG_CHARGER_BQ25890 is not set
-# CONFIG_CHARGER_BQ25980 is not set
-# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
-# CONFIG_CHARGER_GPIO is not set
-# CONFIG_CHARGER_ISP1704 is not set
-# CONFIG_CHARGER_LP8727 is not set
-# CONFIG_CHARGER_LT3651 is not set
-# CONFIG_CHARGER_LTC3651 is not set
-# CONFIG_CHARGER_LTC4162L is not set
-# CONFIG_CHARGER_MANAGER is not set
-# CONFIG_CHARGER_MAX8903 is not set
-# CONFIG_CHARGER_QCOM_SMBB is not set
-# CONFIG_CHARGER_RT9455 is not set
-# CONFIG_CHARGER_SBS is not set
-# CONFIG_CHARGER_SMB347 is not set
-# CONFIG_CHARGER_TWL4030 is not set
-# CONFIG_CHARGER_UCS1002 is not set
-# CONFIG_CHASH_SELFTEST is not set
-# CONFIG_CHASH_STATS is not set
-# CONFIG_CHECKPOINT_RESTORE is not set
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_CHELSIO_T4 is not set
-# CONFIG_CHELSIO_T4VF is not set
-# CONFIG_CHROME_PLATFORMS is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_CHR_DEV_SCH is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_CIFS is not set
-# CONFIG_CIFS_ACL is not set
-CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
-# CONFIG_CIFS_DEBUG is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_FSCACHE is not set
-# CONFIG_CIFS_NFSD_EXPORT is not set
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_SMB2 is not set
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_STATS2 is not set
-# CONFIG_CIFS_SWN_UPCALL is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-CONFIG_CIFS_XATTR=y
-# CONFIG_CIO_DAC is not set
-# CONFIG_CLEANCACHE is not set
-# CONFIG_CLKSRC_PISTACHIO is not set
-# CONFIG_CLKSRC_VERSATILE is not set
-# CONFIG_CLK_GFM_LPASS_SM8250 is not set
-# CONFIG_CLK_HSDK is not set
-# CONFIG_CLK_QORIQ is not set
-# CONFIG_CLK_SP810 is not set
-# CONFIG_CLOCK_THERMAL is not set
-CONFIG_CLS_U32_MARK=y
-# CONFIG_CLS_U32_PERF is not set
-# CONFIG_CM32181 is not set
-# CONFIG_CM3232 is not set
-# CONFIG_CM3323 is not set
-# CONFIG_CM3605 is not set
-# CONFIG_CM36651 is not set
-# CONFIG_CMA is not set
-CONFIG_CMDLINE=""
-# CONFIG_CMDLINE_BOOL is not set
-# CONFIG_CMDLINE_EXTEND is not set
-# CONFIG_CMDLINE_FORCE is not set
-# CONFIG_CMDLINE_FROM_BOOTLOADER is not set
-# CONFIG_CMDLINE_PARTITION is not set
-# CONFIG_CNIC is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_CODE_PATCHING_SELFTEST is not set
-# CONFIG_COMEDI is not set
-# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
-# CONFIG_COMMON_CLK_BOSTON is not set
-# CONFIG_COMMON_CLK_CDCE706 is not set
-# CONFIG_COMMON_CLK_CDCE925 is not set
-# CONFIG_COMMON_CLK_CS2000_CP is not set
-# CONFIG_COMMON_CLK_FIXED_MMIO is not set
-# CONFIG_COMMON_CLK_IPROC is not set
-# CONFIG_COMMON_CLK_MAX9485 is not set
-# CONFIG_COMMON_CLK_MT6765 is not set
-# CONFIG_COMMON_CLK_MT8167 is not set
-# CONFIG_COMMON_CLK_MT8167_AUDSYS is not set
-# CONFIG_COMMON_CLK_MT8167_IMGSYS is not set
-# CONFIG_COMMON_CLK_MT8167_MFGCFG is not set
-# CONFIG_COMMON_CLK_MT8167_MMSYS is not set
-# CONFIG_COMMON_CLK_MT8167_VDECSYS is not set
-# CONFIG_COMMON_CLK_MT8192 is not set
-# CONFIG_COMMON_CLK_NXP is not set
-# CONFIG_COMMON_CLK_PIC32 is not set
-# CONFIG_COMMON_CLK_PISTACHIO is not set
-# CONFIG_COMMON_CLK_PWM is not set
-# CONFIG_COMMON_CLK_PXA is not set
-# CONFIG_COMMON_CLK_QCOM is not set
-# CONFIG_COMMON_CLK_SI514 is not set
-# CONFIG_COMMON_CLK_SI5341 is not set
-# CONFIG_COMMON_CLK_SI5351 is not set
-# CONFIG_COMMON_CLK_SI544 is not set
-# CONFIG_COMMON_CLK_SI570 is not set
-# CONFIG_COMMON_CLK_VC5 is not set
-# CONFIG_COMMON_CLK_XGENE is not set
-# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set
-CONFIG_COMPACTION=y
-# CONFIG_COMPAL_LAPTOP is not set
-# CONFIG_COMPAT is not set
-# CONFIG_COMPAT_BRK is not set
-# CONFIG_COMPILE_TEST is not set
-# CONFIG_CONFIGFS_FS is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
-CONFIG_CONSOLE_LOGLEVEL_QUIET=4
-CONFIG_CONSTRUCTORS=y
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_COPS is not set
-# CONFIG_CORDIC is not set
-# CONFIG_COREDUMP is not set
-# CONFIG_CORESIGHT is not set
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_CORTINA_PHY is not set
-# CONFIG_COUNTER is not set
-# CONFIG_CPA_DEBUG is not set
-# CONFIG_CPU_BIG_ENDIAN is not set
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_FREQ is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set
-# CONFIG_CPU_FREQ_STAT_DETAILS is not set
-# CONFIG_CPU_FREQ_THERMAL is not set
-# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set
-# CONFIG_CPU_IDLE is not set
-# CONFIG_CPU_IDLE_GOV_LADDER is not set
-# CONFIG_CPU_IDLE_GOV_MENU is not set
-# CONFIG_CPU_IDLE_GOV_TEO is not set
-# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
-# CONFIG_CPU_ISOLATION is not set
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-# CONFIG_CPU_NO_EFFICIENT_FFS is not set
-CONFIG_CPU_SW_DOMAIN_PAN=y
-# CONFIG_CPU_THERMAL is not set
-# CONFIG_CRAMFS is not set
-CONFIG_CRAMFS_BLOCKDEV=y
-# CONFIG_CRAMFS_MTD is not set
-# CONFIG_CRASH_DUMP is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_CRC32_BIT is not set
-CONFIG_CRC32_SARWATE=y
-# CONFIG_CRC32_SELFTEST is not set
-# CONFIG_CRC32_SLICEBY4 is not set
-# CONFIG_CRC32_SLICEBY8 is not set
-# CONFIG_CRC4 is not set
-# CONFIG_CRC64 is not set
-# CONFIG_CRC7 is not set
-# CONFIG_CRC8 is not set
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC_ITU_T is not set
-# CONFIG_CRC_T10DIF is not set
-CONFIG_CROSS_COMPILE=""
-# CONFIG_CROSS_MEMORY_ATTACH is not set
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_842 is not set
-CONFIG_CRYPTO_ACOMP2=y
-# CONFIG_CRYPTO_ADIANTUM is not set
-CONFIG_CRYPTO_AEAD=y
-CONFIG_CRYPTO_AEAD2=y
-# CONFIG_CRYPTO_AEGIS128 is not set
-# CONFIG_CRYPTO_AEGIS128L is not set
-# CONFIG_CRYPTO_AEGIS128L_AESNI_SSE2 is not set
-# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set
-# CONFIG_CRYPTO_AEGIS256 is not set
-# CONFIG_CRYPTO_AEGIS256_AESNI_SSE2 is not set
-CONFIG_CRYPTO_AES=y
-# CONFIG_CRYPTO_AES_586 is not set
-# CONFIG_CRYPTO_AES_ARM is not set
-# CONFIG_CRYPTO_AES_ARM64 is not set
-# CONFIG_CRYPTO_AES_ARM64_BS is not set
-# CONFIG_CRYPTO_AES_ARM64_CE is not set
-# CONFIG_CRYPTO_AES_ARM64_CE_BLK is not set
-# CONFIG_CRYPTO_AES_ARM64_CE_CCM is not set
-# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set
-# CONFIG_CRYPTO_AES_ARM_BS is not set
-# CONFIG_CRYPTO_AES_ARM_CE is not set
-# CONFIG_CRYPTO_AES_NI_INTEL is not set
-# CONFIG_CRYPTO_AES_TI is not set
-CONFIG_CRYPTO_AKCIPHER=y
-CONFIG_CRYPTO_AKCIPHER2=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_BLAKE2B is not set
-# CONFIG_CRYPTO_BLAKE2B_NEON is not set
-# CONFIG_CRYPTO_BLAKE2S_ARM is not set
-# CONFIG_CRYPTO_BLAKE2S_X86 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_CBC is not set
-CONFIG_CRYPTO_CCM=y
-# CONFIG_CRYPTO_CFB is not set
-# CONFIG_CRYPTO_CHACHA20 is not set
-# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
-# CONFIG_CRYPTO_CHACHA20_NEON is not set
-# CONFIG_CRYPTO_CHACHA20_X86_64 is not set
-# CONFIG_CRYPTO_CHACHA_MIPS is not set
-# CONFIG_CRYPTO_CMAC is not set
-# CONFIG_CRYPTO_CRC32 is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CRC32C_INTEL is not set
-# CONFIG_CRYPTO_CRC32_ARM_CE is not set
-# CONFIG_CRYPTO_CRCT10DIF is not set
-# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set
-# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_CTR=y
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_CURVE25519 is not set
-# CONFIG_CRYPTO_CURVE25519_NEON is not set
-# CONFIG_CRYPTO_CURVE25519_X86 is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set
-# CONFIG_CRYPTO_DEV_ATMEL_AES is not set
-# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set
-# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
-# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set
-# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
-# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set
-# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set
-# CONFIG_CRYPTO_DEV_CCP is not set
-# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set
-# CONFIG_CRYPTO_DEV_CCREE is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set
-# CONFIG_CRYPTO_DEV_HIFN_795X is not set
-# CONFIG_CRYPTO_DEV_HISI_SEC is not set
-# CONFIG_CRYPTO_DEV_HISI_ZIP is not set
-# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set
-# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set
-# CONFIG_CRYPTO_DEV_MEDIATEK is not set
-# CONFIG_CRYPTO_DEV_MV_CESA is not set
-# CONFIG_CRYPTO_DEV_MXC_SCC is not set
-# CONFIG_CRYPTO_DEV_MXS_DCP is not set
-# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set
-# CONFIG_CRYPTO_DEV_OCTEONTX_CPT is not set
-# CONFIG_CRYPTO_DEV_QAT_4XXX is not set
-# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set
-# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
-# CONFIG_CRYPTO_DEV_QAT_C62X is not set
-# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
-# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set
-# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set
-# CONFIG_CRYPTO_DEV_QCE is not set
-# CONFIG_CRYPTO_DEV_S5P is not set
-# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
-# CONFIG_CRYPTO_DEV_SAHARA is not set
-# CONFIG_CRYPTO_DEV_SP_PSP is not set
-# CONFIG_CRYPTO_DEV_TALITOS is not set
-# CONFIG_CRYPTO_DEV_VIRTIO is not set
-# CONFIG_CRYPTO_DH is not set
-# CONFIG_CRYPTO_DRBG_CTR is not set
-# CONFIG_CRYPTO_DRBG_HASH is not set
-# CONFIG_CRYPTO_DRBG_MENU is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_ECDH is not set
-# CONFIG_CRYPTO_ECDSA is not set
-# CONFIG_CRYPTO_ECHAINIV is not set
-# CONFIG_CRYPTO_ECRDSA is not set
-# CONFIG_CRYPTO_ESSIV is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_GCM=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_GHASH=y
-# CONFIG_CRYPTO_GHASH_ARM64_CE is not set
-# CONFIG_CRYPTO_GHASH_ARM_CE is not set
-# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_CRYPTO_JITTERENTROPY is not set
-# CONFIG_CRYPTO_KEYWRAP is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-CONFIG_CRYPTO_KPP=y
-CONFIG_CRYPTO_KPP2=y
-CONFIG_CRYPTO_LIB_AES=y
-CONFIG_CRYPTO_LIB_ARC4=y
-# CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC is not set
-# CONFIG_CRYPTO_LIB_CHACHA is not set
-# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
-# CONFIG_CRYPTO_LIB_CURVE25519 is not set
-# CONFIG_CRYPTO_LIB_POLY1305 is not set
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_LZ4 is not set
-# CONFIG_CRYPTO_LZ4HC is not set
-# CONFIG_CRYPTO_LZO is not set
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
-# CONFIG_CRYPTO_MCRYPTD is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_MORUS1280 is not set
-# CONFIG_CRYPTO_MORUS1280_AVX2 is not set
-# CONFIG_CRYPTO_MORUS1280_SSE2 is not set
-# CONFIG_CRYPTO_MORUS640 is not set
-# CONFIG_CRYPTO_MORUS640_SSE2 is not set
-# CONFIG_CRYPTO_NHPOLY1305_NEON is not set
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_NULL2=y
-# CONFIG_CRYPTO_OFB is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_PCOMP is not set
-# CONFIG_CRYPTO_PCOMP2 is not set
-CONFIG_CRYPTO_PCRYPT=y
-# CONFIG_CRYPTO_POLY1305 is not set
-# CONFIG_CRYPTO_POLY1305_ARM is not set
-# CONFIG_CRYPTO_POLY1305_MIPS is not set
-# CONFIG_CRYPTO_POLY1305_NEON is not set
-# CONFIG_CRYPTO_POLY1305_X86_64 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RNG is not set
-# CONFIG_CRYPTO_RSA is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SEQIV is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA1_ARM is not set
-# CONFIG_CRYPTO_SHA1_ARM64_CE is not set
-# CONFIG_CRYPTO_SHA1_ARM_CE is not set
-# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA256_ARM is not set
-# CONFIG_CRYPTO_SHA256_ARM64 is not set
-# CONFIG_CRYPTO_SHA2_ARM64_CE is not set
-# CONFIG_CRYPTO_SHA2_ARM_CE is not set
-# CONFIG_CRYPTO_SHA3 is not set
-# CONFIG_CRYPTO_SHA3_ARM64 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_SHA512_ARM is not set
-# CONFIG_CRYPTO_SHA512_ARM64 is not set
-# CONFIG_CRYPTO_SHA512_ARM64_CE is not set
-# CONFIG_CRYPTO_SIMD is not set
-CONFIG_CRYPTO_SKCIPHER=y
-CONFIG_CRYPTO_SKCIPHER2=y
-# CONFIG_CRYPTO_SM2 is not set
-# CONFIG_CRYPTO_SM3 is not set
-# CONFIG_CRYPTO_SM3_ARM64_CE is not set
-# CONFIG_CRYPTO_SM4 is not set
-# CONFIG_CRYPTO_SM4_ARM64_CE is not set
-# CONFIG_CRYPTO_SPECK is not set
-# CONFIG_CRYPTO_STATS is not set
-# CONFIG_CRYPTO_STREEBOG is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_TWOFISH_586 is not set
-# CONFIG_CRYPTO_TWOFISH_COMMON is not set
-# CONFIG_CRYPTO_USER is not set
-# CONFIG_CRYPTO_USER_API_AEAD is not set
-# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set
-# CONFIG_CRYPTO_USER_API_HASH is not set
-# CONFIG_CRYPTO_USER_API_RNG is not set
-# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set
-# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
-# CONFIG_CRYPTO_VMAC is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_XXHASH is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_ZSTD is not set
-# CONFIG_CS5535_MFGPT is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_CS89x0_PLATFORM is not set
-# CONFIG_CSD_LOCK_WAIT_DEBUG is not set
-# CONFIG_CUSE is not set
-# CONFIG_CW1200 is not set
-# CONFIG_CXD2880_SPI_DRV is not set
-# CONFIG_CXL_AFU_DRIVER_OPS is not set
-# CONFIG_CXL_BASE is not set
-# CONFIG_CXL_BUS is not set
-# CONFIG_CXL_EEH is not set
-# CONFIG_CXL_KERNEL_API is not set
-# CONFIG_CXL_LIB is not set
-# CONFIG_CYPRESS_FIRMWARE is not set
-# CONFIG_DA280 is not set
-# CONFIG_DA311 is not set
-# CONFIG_DAMON is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_DAX is not set
-# CONFIG_DCB is not set
-# CONFIG_DDR is not set
-# CONFIG_DEBUG_ALIGN_RODATA is not set
-# CONFIG_DEBUG_ATOMIC_SLEEP is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_CREDENTIALS is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_EFI is not set
-# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set
-# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set
-# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_FS_ALLOW_ALL=y
-# CONFIG_DEBUG_FS_ALLOW_NONE is not set
-# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_DEBUG_HIGHMEM is not set
-# CONFIG_DEBUG_ICEDCC is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_INFO_BTF is not set
-# CONFIG_DEBUG_INFO_COMPRESSED is not set
-# CONFIG_DEBUG_INFO_DWARF4 is not set
-# CONFIG_DEBUG_INFO_DWARF5 is not set
-CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
-# CONFIG_DEBUG_INFO_REDUCED is not set
-# CONFIG_DEBUG_INFO_SPLIT is not set
-# CONFIG_DEBUG_IRQFLAGS is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_KMAP_LOCAL is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_KOBJECT_RELEASE is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_LL_UART_8250 is not set
-# CONFIG_DEBUG_LL_UART_PL01X is not set
-# CONFIG_DEBUG_LOCKDEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_MISC is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_DEBUG_NX_TEST is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUG_PAGE_REF is not set
-# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
-# CONFIG_DEBUG_PER_CPU_MAPS is not set
-# CONFIG_DEBUG_PINCTRL is not set
-# CONFIG_DEBUG_PI_LIST is not set
-# CONFIG_DEBUG_PLIST is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_DEBUG_RODATA_TEST is not set
-# CONFIG_DEBUG_RSEQ is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
-# CONFIG_DEBUG_SECTION_MISMATCH is not set
-# CONFIG_DEBUG_SEMIHOSTING is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_SHIRQ is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
-# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
-# CONFIG_DEBUG_TIMEKEEPING is not set
-# CONFIG_DEBUG_UART_8250_PALMCHIP is not set
-# CONFIG_DEBUG_UART_8250_WORD is not set
-# CONFIG_DEBUG_UART_BCM63XX is not set
-# CONFIG_DEBUG_UART_FLOW_CONTROL is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_VIRTUAL is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_VM_PGFLAGS is not set
-# CONFIG_DEBUG_VM_PGTABLE is not set
-# CONFIG_DEBUG_VM_RB is not set
-# CONFIG_DEBUG_VM_VMACACHE is not set
-# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
-# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
-# CONFIG_DEBUG_WX is not set
-# CONFIG_DEBUG_ZBOOT is not set
-# CONFIG_DECNET is not set
-# CONFIG_DEFAULT_CODEL is not set
-CONFIG_DEFAULT_CUBIC=y
-CONFIG_DEFAULT_DEADLINE=y
-# CONFIG_DEFAULT_FQ is not set
-CONFIG_DEFAULT_FQ_CODEL=y
-# CONFIG_DEFAULT_FQ_PIE is not set
-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_NOOP is not set
-# CONFIG_DEFAULT_PFIFO_FAST is not set
-# CONFIG_DEFAULT_RENO is not set
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_DEFAULT_SECURITY_DAC=y
-# CONFIG_DEFAULT_SECURITY_SELINUX is not set
-# CONFIG_DEFAULT_SFQ is not set
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
-# CONFIG_DELL_LAPTOP is not set
-# CONFIG_DELL_RBTN is not set
-# CONFIG_DELL_SMBIOS is not set
-# CONFIG_DELL_SMO8800 is not set
-# CONFIG_DEPRECATED_PARAM_STRUCT is not set
-# CONFIG_DETECT_HUNG_TASK is not set
-# CONFIG_DEVKMEM is not set
-# CONFIG_DEVMEM is not set
-CONFIG_DEVPORT=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_DEVTMPFS is not set
-# CONFIG_DEVTMPFS_MOUNT is not set
-# CONFIG_DEV_DAX is not set
-# CONFIG_DGAP is not set
-# CONFIG_DGNC is not set
-# CONFIG_DHT11 is not set
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set
-# CONFIG_DISPLAY_CONNECTOR_DVI is not set
-# CONFIG_DISPLAY_CONNECTOR_HDMI is not set
-# CONFIG_DISPLAY_ENCODER_TFP410 is not set
-# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set
-# CONFIG_DISPLAY_PANEL_DPI is not set
-# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set
-# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set
-# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set
-# CONFIG_DL2K is not set
-# CONFIG_DLHL60D is not set
-# CONFIG_DLM is not set
-# CONFIG_DM9000 is not set
-# CONFIG_DMABUF_DEBUG is not set
-# CONFIG_DMABUF_HEAPS is not set
-# CONFIG_DMABUF_MOVE_NOTIFY is not set
-# CONFIG_DMABUF_SELFTESTS is not set
-# CONFIG_DMABUF_SYSFS_STATS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_DMADEVICES_DEBUG is not set
-# CONFIG_DMARD06 is not set
-# CONFIG_DMARD09 is not set
-# CONFIG_DMARD10 is not set
-# CONFIG_DMASCC is not set
-# CONFIG_DMATEST is not set
-# CONFIG_DMA_API_DEBUG is not set
-CONFIG_DMA_COHERENT_POOL=y
-CONFIG_DMA_DECLARE_COHERENT=y
-# CONFIG_DMA_ENGINE is not set
-# CONFIG_DMA_FENCE_TRACE is not set
-# CONFIG_DMA_JZ4780 is not set
-# CONFIG_DMA_MAP_BENCHMARK is not set
-CONFIG_DMA_NONCOHERENT_MMAP=y
-# CONFIG_DMA_NOOP_OPS is not set
-# CONFIG_DMA_PERNUMA_CMA is not set
-# CONFIG_DMA_RESTRICTED_POOL is not set
-# CONFIG_DMA_SHARED_BUFFER is not set
-# CONFIG_DMA_VIRT_OPS is not set
-# CONFIG_DM_CACHE is not set
-# CONFIG_DM_CLONE is not set
-# CONFIG_DM_DEBUG is not set
-# CONFIG_DM_DELAY is not set
-# CONFIG_DM_DUST is not set
-# CONFIG_DM_EBS is not set
-# CONFIG_DM_ERA is not set
-# CONFIG_DM_FLAKEY is not set
-# CONFIG_DM_INTEGRITY is not set
-# CONFIG_DM_LOG_USERSPACE is not set
-# CONFIG_DM_LOG_WRITES is not set
-# CONFIG_DM_MQ_DEFAULT is not set
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_RAID is not set
-# CONFIG_DM_SWITCH is not set
-# CONFIG_DM_THIN_PROVISIONING is not set
-# CONFIG_DM_UEVENT is not set
-# CONFIG_DM_UNSTRIPED is not set
-# CONFIG_DM_VERITY is not set
-# CONFIG_DM_WRITECACHE is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DNET is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_DNS_RESOLVER is not set
-CONFIG_DOUBLEFAULT=y
-# CONFIG_DP83640_PHY is not set
-# CONFIG_DP83822_PHY is not set
-# CONFIG_DP83848_PHY is not set
-# CONFIG_DP83867_PHY is not set
-# CONFIG_DP83869_PHY is not set
-# CONFIG_DP83TC811_PHY is not set
-# CONFIG_DPOT_DAC is not set
-# CONFIG_DPS310 is not set
-CONFIG_DQL=y
-# CONFIG_DRAGONRISE_FF is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_AMDGPU is not set
-# CONFIG_DRM_AMDGPU_CIK is not set
-# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set
-# CONFIG_DRM_AMDGPU_SI is not set
-# CONFIG_DRM_AMDGPU_USERPTR is not set
-# CONFIG_DRM_AMD_ACP is not set
-# CONFIG_DRM_AMD_DC_DCN2_0 is not set
-# CONFIG_DRM_AMD_DC_DCN3_0 is not set
-# CONFIG_DRM_AMD_DC_HDCP is not set
-# CONFIG_DRM_AMD_DC_SI is not set
-# CONFIG_DRM_AMD_SECURE_DISPLAY is not set
-# CONFIG_DRM_ANALOGIX_ANX6345 is not set
-# CONFIG_DRM_ANALOGIX_ANX7625 is not set
-# CONFIG_DRM_ANALOGIX_ANX78XX is not set
-# CONFIG_DRM_ARCPGU is not set
-# CONFIG_DRM_ARMADA is not set
-# CONFIG_DRM_AST is not set
-# CONFIG_DRM_ATMEL_HLCDC is not set
-# CONFIG_DRM_BOCHS is not set
-# CONFIG_DRM_CDNS_DSI is not set
-# CONFIG_DRM_CDNS_MHDP8546 is not set
-# CONFIG_DRM_CHIPONE_ICN6211 is not set
-# CONFIG_DRM_CHRONTEL_CH7033 is not set
-# CONFIG_DRM_CIRRUS_QEMU is not set
-# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set
-# CONFIG_DRM_DEBUG_MM is not set
-# CONFIG_DRM_DEBUG_SELFTEST is not set
-# CONFIG_DRM_DISPLAY_CONNECTOR is not set
-# CONFIG_DRM_DP_AUX_CHARDEV is not set
-# CONFIG_DRM_DP_CEC is not set
-# CONFIG_DRM_DUMB_VGA_DAC is not set
-# CONFIG_DRM_DW_HDMI_CEC is not set
-# CONFIG_DRM_ETNAVIV is not set
-# CONFIG_DRM_EXYNOS is not set
-# CONFIG_DRM_FBDEV_EMULATION is not set
-# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set
-# CONFIG_DRM_FSL_DCU is not set
-# CONFIG_DRM_GM12U320 is not set
-# CONFIG_DRM_GMA500 is not set
-# CONFIG_DRM_GUD is not set
-# CONFIG_DRM_HDLCD is not set
-# CONFIG_DRM_HISI_HIBMC is not set
-# CONFIG_DRM_HISI_KIRIN is not set
-# CONFIG_DRM_I2C_ADV7511 is not set
-# CONFIG_DRM_I2C_CH7006 is not set
-# CONFIG_DRM_I2C_NXP_TDA9950 is not set
-# CONFIG_DRM_I2C_NXP_TDA998X is not set
-# CONFIG_DRM_I2C_SIL164 is not set
-# CONFIG_DRM_I915 is not set
-# CONFIG_DRM_ITE_IT66121 is not set
-# CONFIG_DRM_KOMEDA is not set
-# CONFIG_DRM_LEGACY is not set
-# CONFIG_DRM_LIB_RANDOM is not set
-# CONFIG_DRM_LIMA is not set
-# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
-# CONFIG_DRM_LONTIUM_LT8912B is not set
-# CONFIG_DRM_LONTIUM_LT9611 is not set
-# CONFIG_DRM_LONTIUM_LT9611UXC is not set
-# CONFIG_DRM_LVDS_CODEC is not set
-# CONFIG_DRM_LVDS_ENCODER is not set
-# CONFIG_DRM_MALI_DISPLAY is not set
-# CONFIG_DRM_MCDE is not set
-# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
-# CONFIG_DRM_MGAG200 is not set
-# CONFIG_DRM_MXSFB is not set
-# CONFIG_DRM_NOUVEAU is not set
-# CONFIG_DRM_NWL_MIPI_DSI is not set
-# CONFIG_DRM_NXP_PTN3460 is not set
-# CONFIG_DRM_OMAP is not set
-# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set
-# CONFIG_DRM_PANEL_ARM_VERSATILE is not set
-# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set
-# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set
-# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set
-# CONFIG_DRM_PANEL_DSI_CM is not set
-# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set
-# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set
-# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set
-# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
-# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set
-# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set
-# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set
-# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set
-# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set
-# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
-# CONFIG_DRM_PANEL_KHADAS_TS050 is not set
-# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set
-# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set
-# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set
-# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
-# CONFIG_DRM_PANEL_LG_LG4573 is not set
-# CONFIG_DRM_PANEL_LVDS is not set
-# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set
-# CONFIG_DRM_PANEL_MIPI_DBI is not set
-# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
-# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
-# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set
-# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set
-# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set
-# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set
-# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set
-# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set
-# CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set
-# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set
-# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
-# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set
-# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set
-# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set
-# CONFIG_DRM_PANEL_SIMPLE is not set
-# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set
-# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set
-# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
-# CONFIG_DRM_PANEL_SONY_ACX424AKP is not set
-# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
-# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set
-# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
-# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
-# CONFIG_DRM_PANEL_TPO_TPG110 is not set
-# CONFIG_DRM_PANEL_TPO_Y17P is not set
-# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set
-# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set
-# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set
-# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set
-# CONFIG_DRM_PANFROST is not set
-# CONFIG_DRM_PARADE_PS8622 is not set
-# CONFIG_DRM_PARADE_PS8640 is not set
-# CONFIG_DRM_PL111 is not set
-# CONFIG_DRM_QXL is not set
-# CONFIG_DRM_RADEON is not set
-# CONFIG_DRM_RADEON_USERPTR is not set
-# CONFIG_DRM_RCAR_DW_HDMI is not set
-# CONFIG_DRM_RCAR_LVDS is not set
-# CONFIG_DRM_RCAR_USE_LVDS is not set
-# CONFIG_DRM_ROCKCHIP is not set
-# CONFIG_DRM_SII902X is not set
-# CONFIG_DRM_SII9234 is not set
-# CONFIG_DRM_SIL_SII8620 is not set
-# CONFIG_DRM_SIMPLEDRM is not set
-# CONFIG_DRM_SIMPLE_BRIDGE is not set
-# CONFIG_DRM_STI is not set
-# CONFIG_DRM_STM is not set
-# CONFIG_DRM_SUN4I is not set
-# CONFIG_DRM_THINE_THC63LVD1024 is not set
-# CONFIG_DRM_TIDSS is not set
-# CONFIG_DRM_TILCDC is not set
-# CONFIG_DRM_TINYDRM is not set
-# CONFIG_DRM_TI_SN65DSI83 is not set
-# CONFIG_DRM_TI_SN65DSI86 is not set
-# CONFIG_DRM_TI_TFP410 is not set
-# CONFIG_DRM_TI_TPD12S015 is not set
-# CONFIG_DRM_TOSHIBA_TC358762 is not set
-# CONFIG_DRM_TOSHIBA_TC358764 is not set
-# CONFIG_DRM_TOSHIBA_TC358767 is not set
-# CONFIG_DRM_TOSHIBA_TC358768 is not set
-# CONFIG_DRM_TOSHIBA_TC358775 is not set
-# CONFIG_DRM_TVE200 is not set
-# CONFIG_DRM_UDL is not set
-# CONFIG_DRM_VBOXVIDEO is not set
-# CONFIG_DRM_VC4_HDMI_CEC is not set
-# CONFIG_DRM_VGEM is not set
-# CONFIG_DRM_VIRTIO_GPU is not set
-# CONFIG_DRM_VKMS is not set
-# CONFIG_DRM_VMWGFX is not set
-# CONFIG_DRM_XEN is not set
-# CONFIG_DRM_XEN_FRONTEND is not set
-# CONFIG_DS1682 is not set
-# CONFIG_DS1803 is not set
-# CONFIG_DS4424 is not set
-# CONFIG_DST_CACHE is not set
-# CONFIG_DTLK is not set
-# CONFIG_DUMMY is not set
-CONFIG_DUMMY_CONSOLE_COLUMNS=80
-CONFIG_DUMMY_CONSOLE_ROWS=25
-# CONFIG_DUMMY_IRQ is not set
-# CONFIG_DVB_A8293 is not set
-# CONFIG_DVB_AF9013 is not set
-# CONFIG_DVB_AF9033 is not set
-# CONFIG_DVB_AS102 is not set
-# CONFIG_DVB_ASCOT2E is not set
-# CONFIG_DVB_ATBM8830 is not set
-# CONFIG_DVB_AU8522_DTV is not set
-# CONFIG_DVB_AU8522_V4L is not set
-# CONFIG_DVB_B2C2_FLEXCOP_PCI is not set
-# CONFIG_DVB_B2C2_FLEXCOP_USB is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_BUDGET_CORE is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_CX24117 is not set
-# CONFIG_DVB_CX24120 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_CXD2099 is not set
-# CONFIG_DVB_CXD2820R is not set
-# CONFIG_DVB_CXD2841ER is not set
-# CONFIG_DVB_CXD2880 is not set
-# CONFIG_DVB_DDBRIDGE is not set
-# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_DIB8000 is not set
-# CONFIG_DVB_DIB9000 is not set
-# CONFIG_DVB_DRX39XYJ is not set
-# CONFIG_DVB_DRXD is not set
-# CONFIG_DVB_DRXK is not set
-# CONFIG_DVB_DS3000 is not set
-# CONFIG_DVB_DUMMY_FE is not set
-# CONFIG_DVB_DYNAMIC_MINORS is not set
-# CONFIG_DVB_EC100 is not set
-# CONFIG_DVB_FIREDTV is not set
-# CONFIG_DVB_HELENE is not set
-# CONFIG_DVB_HORUS3A is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# CONFIG_DVB_ISL6423 is not set
-# CONFIG_DVB_IX2505V is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_LG2160 is not set
-# CONFIG_DVB_LGDT3305 is not set
-# CONFIG_DVB_LGDT3306A is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGS8GL5 is not set
-# CONFIG_DVB_LGS8GXX is not set
-# CONFIG_DVB_LNBH25 is not set
-# CONFIG_DVB_LNBH29 is not set
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_LNBP22 is not set
-# CONFIG_DVB_M88DS3103 is not set
-# CONFIG_DVB_M88RS2000 is not set
-CONFIG_DVB_MAX_ADAPTERS=16
-# CONFIG_DVB_MB86A16 is not set
-# CONFIG_DVB_MB86A20S is not set
-# CONFIG_DVB_MMAP is not set
-# CONFIG_DVB_MN88443X is not set
-# CONFIG_DVB_MN88472 is not set
-# CONFIG_DVB_MN88473 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_MXL5XX is not set
-# CONFIG_DVB_MXL692 is not set
-# CONFIG_DVB_NET is not set
-# CONFIG_DVB_NETUP_UNIDVB is not set
-# CONFIG_DVB_NGENE is not set
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_PLATFORM_DRIVERS is not set
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_PLUTO2 is not set
-# CONFIG_DVB_PT1 is not set
-# CONFIG_DVB_PT3 is not set
-# CONFIG_DVB_RTL2830 is not set
-# CONFIG_DVB_RTL2832 is not set
-# CONFIG_DVB_RTL2832_SDR is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_S5H1411 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_S5H1432 is not set
-# CONFIG_DVB_S921 is not set
-# CONFIG_DVB_SI2165 is not set
-# CONFIG_DVB_SI2168 is not set
-# CONFIG_DVB_SI21XX is not set
-# CONFIG_DVB_SP2 is not set
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_STB0899 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STB6100 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STV0297 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_STV0367 is not set
-# CONFIG_DVB_STV0900 is not set
-# CONFIG_DVB_STV090x is not set
-# CONFIG_DVB_STV0910 is not set
-# CONFIG_DVB_STV6110 is not set
-# CONFIG_DVB_STV6110x is not set
-# CONFIG_DVB_STV6111 is not set
-# CONFIG_DVB_TC90522 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_TDA10048 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_TDA10071 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA18271C2DD is not set
-# CONFIG_DVB_TDA665x is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TEST_DRIVERS is not set
-# CONFIG_DVB_TS2020 is not set
-# CONFIG_DVB_TTUSB_BUDGET is not set
-# CONFIG_DVB_TTUSB_DEC is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-# CONFIG_DVB_TUNER_DIB0090 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_ULE_DEBUG is not set
-# CONFIG_DVB_USB is not set
-# CONFIG_DVB_USB_V2 is not set
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_ZD1301_DEMOD is not set
-# CONFIG_DVB_ZL10036 is not set
-# CONFIG_DVB_ZL10039 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DWC_XLGMAC is not set
-# CONFIG_DWMAC_DWC_QOS_ETH is not set
-# CONFIG_DWMAC_INTEL_PLAT is not set
-# CONFIG_DWMAC_IPQ806X is not set
-# CONFIG_DWMAC_LOONGSON is not set
-# CONFIG_DWMAC_LPC18XX is not set
-# CONFIG_DWMAC_MESON is not set
-# CONFIG_DWMAC_ROCKCHIP is not set
-# CONFIG_DWMAC_SOCFPGA is not set
-# CONFIG_DWMAC_STI is not set
-# CONFIG_DW_AXI_DMAC is not set
-# CONFIG_DW_DMAC is not set
-# CONFIG_DW_DMAC_PCI is not set
-# CONFIG_DW_EDMA is not set
-# CONFIG_DW_EDMA_PCIE is not set
-# CONFIG_DW_WATCHDOG is not set
-# CONFIG_DW_XDATA_PCIE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_DYNAMIC_DEBUG_CORE is not set
-# CONFIG_E100 is not set
-# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_E1000E_HWTS is not set
-# CONFIG_EARLY_PRINTK_8250 is not set
-# CONFIG_EARLY_PRINTK_USB_XDBC is not set
-# CONFIG_EBC_C384_WDT is not set
-# CONFIG_ECHO is not set
-# CONFIG_ECRYPT_FS is not set
-# CONFIG_EDAC is not set
-# CONFIG_EEEPC_LAPTOP is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_EEPROM_93XX46 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_AT25 is not set
-# CONFIG_EEPROM_DIGSY_MTC_CFG is not set
-# CONFIG_EEPROM_EE1004 is not set
-# CONFIG_EEPROM_IDT_89HPESX is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_MAX6875 is not set
-# CONFIG_EFI is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_EFI_VARS_PSTORE is not set
-# CONFIG_EFS_FS is not set
-CONFIG_ELFCORE=y
-# CONFIG_ELF_CORE is not set
-# CONFIG_EMAC_ROCKCHIP is not set
-CONFIG_EMBEDDED=y
-# CONFIG_EM_TIMER_STI is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-# CONFIG_ENA_ETHERNET is not set
-# CONFIG_ENC28J60 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_ENCRYPTED_KEYS is not set
-# CONFIG_ENCX24J600 is not set
-# CONFIG_ENERGY_MODEL is not set
-# CONFIG_ENIC is not set
-# CONFIG_ENVELOPE_DETECTOR is not set
-# CONFIG_EPAPR_PARAVIRT is not set
-# CONFIG_EPIC100 is not set
-CONFIG_EPOLL=y
-# CONFIG_EQUALIZER is not set
-# CONFIG_EROFS_FS is not set
-# CONFIG_ET131X is not set
-CONFIG_ETHERNET=y
-# CONFIG_ETHOC is not set
-CONFIG_ETHTOOL_NETLINK=y
-CONFIG_EVENTFD=y
-# CONFIG_EVM is not set
-# CONFIG_EXFAT_FS is not set
-CONFIG_EXPERT=y
-CONFIG_EXPORTFS=y
-# CONFIG_EXPORTFS_BLOCK_OPS is not set
-# CONFIG_EXT2_FS is not set
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4_DEBUG is not set
-# CONFIG_EXT4_ENCRYPTION is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_EXT4_FS_POSIX_ACL is not set
-# CONFIG_EXT4_FS_SECURITY is not set
-CONFIG_EXT4_USE_FOR_EXT2=y
-# CONFIG_EXTCON is not set
-# CONFIG_EXTCON_ADC_JACK is not set
-# CONFIG_EXTCON_ARIZONA is not set
-# CONFIG_EXTCON_AXP288 is not set
-# CONFIG_EXTCON_FSA9480 is not set
-# CONFIG_EXTCON_GPIO is not set
-# CONFIG_EXTCON_INTEL_INT3496 is not set
-# CONFIG_EXTCON_MAX3355 is not set
-# CONFIG_EXTCON_PTN5150 is not set
-# CONFIG_EXTCON_QCOM_SPMI_MISC is not set
-# CONFIG_EXTCON_RT8973A is not set
-# CONFIG_EXTCON_SM5502 is not set
-# CONFIG_EXTCON_USBC_TUSB320 is not set
-# CONFIG_EXTCON_USB_GPIO is not set
-CONFIG_EXTRA_FIRMWARE=""
-CONFIG_EXTRA_TARGETS=""
-# CONFIG_EXYNOS_ADC is not set
-# CONFIG_EXYNOS_VIDEO is not set
-# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set
-# CONFIG_EZX_PCAP is not set
-# CONFIG_F2FS_CHECK_FS is not set
-# CONFIG_F2FS_FAULT_INJECTION is not set
-# CONFIG_F2FS_FS is not set
-# CONFIG_F2FS_FS_COMPRESSION is not set
-# CONFIG_F2FS_FS_ENCRYPTION is not set
-# CONFIG_F2FS_FS_POSIX_ACL is not set
-# CONFIG_F2FS_FS_SECURITY is not set
-CONFIG_F2FS_FS_XATTR=y
-# CONFIG_F2FS_IOSTAT is not set
-# CONFIG_F2FS_IO_TRACE is not set
-CONFIG_F2FS_STAT_FS=y
-# CONFIG_FAILOVER is not set
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_FANOTIFY is not set
-# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_FAT_DEFAULT_UTF8 is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_FB is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_ARC is not set
-# CONFIG_FB_ARK is not set
-# CONFIG_FB_ARMCLCD is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_ATMEL is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_AUO_K190X is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_BIG_ENDIAN is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-# CONFIG_FB_BOTH_ENDIAN is not set
-# CONFIG_FB_BROADSHEET is not set
-# CONFIG_FB_CARMINE is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_DA8XX is not set
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_FLEX is not set
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_FSL_DIU is not set
-# CONFIG_FB_GEODE is not set
-# CONFIG_FB_GOLDFISH is not set
-# CONFIG_FB_HGA is not set
-# CONFIG_FB_I740 is not set
-# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_IMX is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_LE80578 is not set
-# CONFIG_FB_LITTLE_ENDIAN is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_MB862XX is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_MXS is not set
-# CONFIG_FB_N411 is not set
-# CONFIG_FB_NEOMAGIC is not set
-CONFIG_FB_NOTIFY=y
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_OF is not set
-# CONFIG_FB_OMAP2 is not set
-# CONFIG_FB_OPENCORES is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_PM3 is not set
-# CONFIG_FB_PS3 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIMPLE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_SM712 is not set
-# CONFIG_FB_SM750 is not set
-# CONFIG_FB_SMSCUFX is not set
-# CONFIG_FB_SSD1307 is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_FOPS is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
-# CONFIG_FB_TFT is not set
-# CONFIG_FB_TFT_AGM1264K_FL is not set
-# CONFIG_FB_TFT_BD663474 is not set
-# CONFIG_FB_TFT_FBTFT_DEVICE is not set
-# CONFIG_FB_TFT_HX8340BN is not set
-# CONFIG_FB_TFT_HX8347D is not set
-# CONFIG_FB_TFT_HX8353D is not set
-# CONFIG_FB_TFT_HX8357D is not set
-# CONFIG_FB_TFT_ILI9163 is not set
-# CONFIG_FB_TFT_ILI9320 is not set
-# CONFIG_FB_TFT_ILI9325 is not set
-# CONFIG_FB_TFT_ILI9340 is not set
-# CONFIG_FB_TFT_ILI9341 is not set
-# CONFIG_FB_TFT_ILI9481 is not set
-# CONFIG_FB_TFT_ILI9486 is not set
-# CONFIG_FB_TFT_PCD8544 is not set
-# CONFIG_FB_TFT_RA8875 is not set
-# CONFIG_FB_TFT_S6D02A1 is not set
-# CONFIG_FB_TFT_S6D1121 is not set
-# CONFIG_FB_TFT_SEPS525 is not set
-# CONFIG_FB_TFT_SH1106 is not set
-# CONFIG_FB_TFT_SSD1289 is not set
-# CONFIG_FB_TFT_SSD1305 is not set
-# CONFIG_FB_TFT_SSD1306 is not set
-# CONFIG_FB_TFT_SSD1325 is not set
-# CONFIG_FB_TFT_SSD1331 is not set
-# CONFIG_FB_TFT_SSD1351 is not set
-# CONFIG_FB_TFT_ST7735R is not set
-# CONFIG_FB_TFT_ST7789V is not set
-# CONFIG_FB_TFT_TINYLCD is not set
-# CONFIG_FB_TFT_TLS8204 is not set
-# CONFIG_FB_TFT_UC1611 is not set
-# CONFIG_FB_TFT_UC1701 is not set
-# CONFIG_FB_TFT_UPD161704 is not set
-# CONFIG_FB_TFT_WATTEROTT is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_TMIO is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_UDL is not set
-# CONFIG_FB_UVESA is not set
-# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_VIA is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_VT8623 is not set
-# CONFIG_FB_XGI is not set
-# CONFIG_FCOE is not set
-# CONFIG_FCOE_FNIC is not set
-# CONFIG_FDDI is not set
-# CONFIG_FEALNX is not set
-# CONFIG_FENCE_TRACE is not set
-# CONFIG_FHANDLE is not set
-CONFIG_FIB_RULES=y
-# CONFIG_FIELDBUS_DEV is not set
-CONFIG_FILE_LOCKING=y
-# CONFIG_FIND_BIT_BENCHMARK is not set
-# CONFIG_FIREWIRE is not set
-# CONFIG_FIREWIRE_NOSY is not set
-# CONFIG_FIREWIRE_SERIAL is not set
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-# CONFIG_FIRMWARE_MEMMAP is not set
-# CONFIG_FIXED_PHY is not set
-CONFIG_FLATMEM=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_FM10K is not set
-# CONFIG_FMC is not set
-# CONFIG_FONTS is not set
-# CONFIG_FONT_6x8 is not set
-# CONFIG_FONT_TER16x32 is not set
-# CONFIG_FORCEDETH is not set
-CONFIG_FORCE_MAX_ZONEORDER=11
-CONFIG_FORTIFY_SOURCE=y
-# CONFIG_FPGA is not set
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_FREEZER is not set
-# CONFIG_FRONTSWAP is not set
-# CONFIG_FSCACHE is not set
-# CONFIG_FSI is not set
-# CONFIG_FSL_DPAA2_SWITCH is not set
-# CONFIG_FSL_EDMA is not set
-# CONFIG_FSL_ENETC is not set
-# CONFIG_FSL_ENETC_IERB is not set
-# CONFIG_FSL_ENETC_MDIO is not set
-# CONFIG_FSL_ENETC_VF is not set
-# CONFIG_FSL_ERRATUM_A008585 is not set
-# CONFIG_FSL_MC_BUS is not set
-# CONFIG_FSL_PQ_MDIO is not set
-# CONFIG_FSL_QDMA is not set
-# CONFIG_FSL_RCPM is not set
-# CONFIG_FSL_XGMAC_MDIO is not set
-CONFIG_FSNOTIFY=y
-# CONFIG_FS_DAX is not set
-# CONFIG_FS_ENCRYPTION is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_FS_VERITY is not set
-# CONFIG_FTGMAC100 is not set
-# CONFIG_FTL is not set
-# CONFIG_FTMAC100 is not set
-# CONFIG_FTRACE is not set
-# CONFIG_FTRACE_RECORD_RECURSION is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_FTR_FIXUP_SELFTEST is not set
-# CONFIG_FTWDT010_WATCHDOG is not set
-# CONFIG_FUJITSU_ERRATUM_010001 is not set
-# CONFIG_FUJITSU_ES is not set
-# CONFIG_FUJITSU_LAPTOP is not set
-# CONFIG_FUJITSU_TABLET is not set
-# CONFIG_FUNCTION_ERROR_INJECTION is not set
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_FUSE_FS is not set
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
-# CONFIG_FUSION_SPI is not set
-CONFIG_FUTEX=y
-CONFIG_FUTEX_PI=y
-# CONFIG_FW_CFG_SYSFS is not set
-CONFIG_FW_LOADER=y
-# CONFIG_FW_LOADER_COMPRESS is not set
-CONFIG_FW_LOADER_USER_HELPER=y
-CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
-# CONFIG_FXAS21002C is not set
-# CONFIG_FXLS8962AF_I2C is not set
-# CONFIG_FXLS8962AF_SPI is not set
-# CONFIG_FXOS8700_I2C is not set
-# CONFIG_FXOS8700_SPI is not set
-CONFIG_GACT_PROB=y
-# CONFIG_GADGET_UAC1 is not set
-# CONFIG_GAMEPORT is not set
-# CONFIG_GATEWORKS_GW16083 is not set
-# CONFIG_GCC_PLUGINS is not set
-# CONFIG_GCOV is not set
-# CONFIG_GCOV_KERNEL is not set
-# CONFIG_GDB_SCRIPTS is not set
-# CONFIG_GEMINI_ETHERNET is not set
-# CONFIG_GENERIC_ADC_BATTERY is not set
-# CONFIG_GENERIC_ADC_THERMAL is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-# CONFIG_GENERIC_CPU_DEVICES is not set
-CONFIG_GENERIC_HWEIGHT=y
-# CONFIG_GENERIC_IRQ_DEBUGFS is not set
-CONFIG_GENERIC_IRQ_IPI=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_NET_UTILS=y
-# CONFIG_GENERIC_PHY is not set
-CONFIG_GENERIC_PTDUMP=y
-CONFIG_GENERIC_VDSO_TIME_NS=y
-# CONFIG_GENEVE is not set
-# CONFIG_GENWQE is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_GIGASET_CAPI is not set
-# CONFIG_GIGASET_DEBUG is not set
-# CONFIG_GIGASET_DUMMYLL is not set
-# CONFIG_GLOB_SELFTEST is not set
-# CONFIG_GNSS is not set
-# CONFIG_GOLDFISH is not set
-# CONFIG_GOOGLE_FIRMWARE is not set
-# CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT is not set
-# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set
-# CONFIG_GOOGLE_SMI is not set
-# CONFIG_GP2AP002 is not set
-# CONFIG_GP2AP020A00F is not set
-# CONFIG_GPD_POCKET_FAN is not set
-CONFIG_GPIOLIB=y
-CONFIG_GPIOLIB_FASTPATH_LIMIT=512
-# CONFIG_GPIO_104_DIO_48E is not set
-# CONFIG_GPIO_104_IDIO_16 is not set
-# CONFIG_GPIO_104_IDI_48 is not set
-# CONFIG_GPIO_74X164 is not set
-# CONFIG_GPIO_74XX_MMIO is not set
-# CONFIG_GPIO_ADNP is not set
-# CONFIG_GPIO_ADP5588 is not set
-# CONFIG_GPIO_AGGREGATOR is not set
-# CONFIG_GPIO_ALTERA is not set
-# CONFIG_GPIO_AMD8111 is not set
-# CONFIG_GPIO_AMDPT is not set
-# CONFIG_GPIO_AMD_FCH is not set
-# CONFIG_GPIO_BCM_KONA is not set
-# CONFIG_GPIO_BT8XX is not set
-# CONFIG_GPIO_CADENCE is not set
-# CONFIG_GPIO_CASCADE is not set
-# CONFIG_GPIO_CDEV is not set
-# CONFIG_GPIO_CDEV_V1 is not set
-# CONFIG_GPIO_CS5535 is not set
-# CONFIG_GPIO_DWAPB is not set
-# CONFIG_GPIO_EM is not set
-# CONFIG_GPIO_EXAR is not set
-# CONFIG_GPIO_F7188X is not set
-# CONFIG_GPIO_FTGPIO010 is not set
-# CONFIG_GPIO_GENERIC_PLATFORM is not set
-# CONFIG_GPIO_GPIO_MM is not set
-# CONFIG_GPIO_GRGPIO is not set
-# CONFIG_GPIO_GW_PLD is not set
-# CONFIG_GPIO_HLWD is not set
-# CONFIG_GPIO_ICH is not set
-# CONFIG_GPIO_IT87 is not set
-# CONFIG_GPIO_LOGICVC is not set
-# CONFIG_GPIO_LYNXPOINT is not set
-# CONFIG_GPIO_MAX3191X is not set
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX7301 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_MB86S7X is not set
-# CONFIG_GPIO_MC33880 is not set
-# CONFIG_GPIO_ML_IOH is not set
-# CONFIG_GPIO_MOCKUP is not set
-# CONFIG_GPIO_MPC8XXX is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCA953X_IRQ is not set
-# CONFIG_GPIO_PCA9570 is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_PCH is not set
-# CONFIG_GPIO_PCIE_IDIO_24 is not set
-# CONFIG_GPIO_PCI_IDIO_16 is not set
-# CONFIG_GPIO_PISOSR is not set
-# CONFIG_GPIO_PL061 is not set
-# CONFIG_GPIO_PWM is not set
-# CONFIG_GPIO_RCAR is not set
-# CONFIG_GPIO_RDC321X is not set
-# CONFIG_GPIO_SAMA5D2_PIOBU is not set
-# CONFIG_GPIO_SCH is not set
-# CONFIG_GPIO_SCH311X is not set
-# CONFIG_GPIO_SIFIVE is not set
-# CONFIG_GPIO_SX150X is not set
-# CONFIG_GPIO_SYSCON is not set
-CONFIG_GPIO_SYSFS=y
-# CONFIG_GPIO_TPIC2810 is not set
-# CONFIG_GPIO_TS4900 is not set
-# CONFIG_GPIO_TS5500 is not set
-# CONFIG_GPIO_VIRTIO is not set
-# CONFIG_GPIO_VX855 is not set
-# CONFIG_GPIO_WATCHDOG is not set
-# CONFIG_GPIO_WINBOND is not set
-# CONFIG_GPIO_WS16C48 is not set
-# CONFIG_GPIO_XGENE is not set
-# CONFIG_GPIO_XILINX is not set
-# CONFIG_GPIO_XRA1403 is not set
-# CONFIG_GPIO_ZEVIO is not set
-# CONFIG_GPIO_ZX is not set
-# CONFIG_GREENASIA_FF is not set
-# CONFIG_GREYBUS is not set
-# CONFIG_GS_FPGABOOT is not set
-# CONFIG_GTP is not set
-# CONFIG_GUP_BENCHMARK is not set
-# CONFIG_GUP_TEST is not set
-# CONFIG_GVE is not set
-# CONFIG_HABANA_AI is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_HAPPYMEAL is not set
-CONFIG_HARDENED_USERCOPY=y
-# CONFIG_HARDENED_USERCOPY_FALLBACK is not set
-# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set
-CONFIG_HARDEN_BRANCH_HISTORY=y
-CONFIG_HARDEN_EL2_VECTORS=y
-# CONFIG_HARDLOCKUP_DETECTOR is not set
-# CONFIG_HAVE_ARM_ARCH_TIMER is not set
-# CONFIG_HCALL_STATS is not set
-# CONFIG_HDC100X is not set
-# CONFIG_HDC2010 is not set
-# CONFIG_HDLC is not set
-# CONFIG_HDLC_CISCO is not set
-# CONFIG_HDLC_FR is not set
-# CONFIG_HDLC_PPP is not set
-# CONFIG_HDLC_RAW is not set
-# CONFIG_HDLC_RAW_ETH is not set
-# CONFIG_HDMI_LPE_AUDIO is not set
-# CONFIG_HDQ_MASTER_OMAP is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_HEADERS_INSTALL is not set
-# CONFIG_HEADER_TEST is not set
-# CONFIG_HERMES is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_HFSPLUS_FS_POSIX_ACL is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFS_FS_POSIX_ACL is not set
-# CONFIG_HI6421V600_IRQ is not set
-# CONFIG_HI8435 is not set
-# CONFIG_HIBERNATION is not set
-# CONFIG_HID is not set
-# CONFIG_HIDRAW is not set
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_ACCUTOUCH is not set
-# CONFIG_HID_ACRUX is not set
-# CONFIG_HID_ACRUX_FF is not set
-# CONFIG_HID_ALPS is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_APPLEIR is not set
-# CONFIG_HID_ASUS is not set
-# CONFIG_HID_AUREAL is not set
-# CONFIG_HID_BATTERY_STRENGTH is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_BETOP_FF is not set
-# CONFIG_HID_BIGBEN_FF is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_CMEDIA is not set
-# CONFIG_HID_CORSAIR is not set
-# CONFIG_HID_COUGAR is not set
-# CONFIG_HID_CP2112 is not set
-# CONFIG_HID_CREATIVE_SB0540 is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_ELAN is not set
-# CONFIG_HID_ELECOM is not set
-# CONFIG_HID_ELO is not set
-# CONFIG_HID_EMS_FF is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_FT260 is not set
-# CONFIG_HID_GEMBIRD is not set
-# CONFIG_HID_GENERIC is not set
-# CONFIG_HID_GFRM is not set
-# CONFIG_HID_GLORIOUS is not set
-# CONFIG_HID_GOOGLE_HAMMER is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_GT683R is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_HOLTEK is not set
-# CONFIG_HID_ICADE is not set
-# CONFIG_HID_ITE is not set
-# CONFIG_HID_JABRA is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_KEYTOUCH is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_LCPOWER is not set
-# CONFIG_HID_LED is not set
-# CONFIG_HID_LENOVO is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_LOGITECH_DJ is not set
-# CONFIG_HID_LOGITECH_HIDPP is not set
-# CONFIG_HID_MACALLY is not set
-# CONFIG_HID_MAGICMOUSE is not set
-# CONFIG_HID_MALTRON is not set
-# CONFIG_HID_MAYFLASH is not set
-# CONFIG_HID_MCP2221 is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_MULTITOUCH is not set
-# CONFIG_HID_NTI is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_ORTEK is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PENMOUNT is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_PICOLCD is not set
-# CONFIG_HID_PID is not set
-# CONFIG_HID_PLANTRONICS is not set
-# CONFIG_HID_PLAYSTATION is not set
-# CONFIG_HID_PRIMAX is not set
-# CONFIG_HID_PRODIKEYS is not set
-# CONFIG_HID_REDRAGON is not set
-# CONFIG_HID_RETRODE is not set
-# CONFIG_HID_RMI is not set
-# CONFIG_HID_ROCCAT is not set
-# CONFIG_HID_SAITEK is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SEMITEK is not set
-# CONFIG_HID_SENSOR_HUB is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_SPEEDLINK is not set
-# CONFIG_HID_STEAM is not set
-# CONFIG_HID_STEELSERIES is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_THINGM is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_TIVO is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_U2FZERO is not set
-# CONFIG_HID_UCLOGIC is not set
-# CONFIG_HID_UDRAW_PS3 is not set
-# CONFIG_HID_VIEWSONIC is not set
-# CONFIG_HID_VIVALDI is not set
-# CONFIG_HID_WACOM is not set
-# CONFIG_HID_WALTOP is not set
-# CONFIG_HID_WIIMOTE is not set
-# CONFIG_HID_XINMO is not set
-# CONFIG_HID_ZEROPLUS is not set
-# CONFIG_HID_ZYDACRON is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_HIGH_RES_TIMERS=y
-# CONFIG_HINIC is not set
-# CONFIG_HIP04_ETH is not set
-# CONFIG_HIPPI is not set
-# CONFIG_HISILICON_ERRATUM_161010101 is not set
-# CONFIG_HISILICON_ERRATUM_161600802 is not set
-# CONFIG_HISI_DMA is not set
-# CONFIG_HISI_FEMAC is not set
-# CONFIG_HISI_HIKEY_USB is not set
-# CONFIG_HIST_TRIGGERS_DEBUG is not set
-# CONFIG_HIX5HD2_GMAC is not set
-# CONFIG_HMC425 is not set
-# CONFIG_HMC6352 is not set
-# CONFIG_HNS is not set
-# CONFIG_HNS3 is not set
-# CONFIG_HNS_DSAF is not set
-# CONFIG_HNS_ENET is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-# CONFIG_HOSTAP_PCI is not set
-# CONFIG_HOSTAP_PLX is not set
-# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ is not set
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_IBM is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-# CONFIG_HP03 is not set
-# CONFIG_HP100 is not set
-# CONFIG_HP206C is not set
-CONFIG_HPET_MMAP_DEFAULT=y
-# CONFIG_HPFS_FS is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_HP_WIRELESS is not set
-# CONFIG_HSA_AMD is not set
-# CONFIG_HSI is not set
-# CONFIG_HSR is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_I2CPLD is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HTS221 is not set
-# CONFIG_HTU21 is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_HVC_DCC is not set
-# CONFIG_HVC_UDBG is not set
-# CONFIG_HWLAT_TRACER is not set
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-# CONFIG_HWMON_VID is not set
-# CONFIG_HWSPINLOCK is not set
-# CONFIG_HWSPINLOCK_OMAP is not set
-CONFIG_HW_PERF_EVENTS=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HW_RANDOM_AMD is not set
-# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set
-# CONFIG_HW_RANDOM_ATMEL is not set
-# CONFIG_HW_RANDOM_BA431 is not set
-# CONFIG_HW_RANDOM_BCM2835 is not set
-# CONFIG_HW_RANDOM_CAVIUM is not set
-# CONFIG_HW_RANDOM_CCTRNG is not set
-# CONFIG_HW_RANDOM_EXYNOS is not set
-# CONFIG_HW_RANDOM_GEODE is not set
-# CONFIG_HW_RANDOM_INTEL is not set
-# CONFIG_HW_RANDOM_IPROC_RNG200 is not set
-# CONFIG_HW_RANDOM_MTK is not set
-# CONFIG_HW_RANDOM_OMAP is not set
-# CONFIG_HW_RANDOM_OMAP3_ROM is not set
-# CONFIG_HW_RANDOM_PPC4XX is not set
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-CONFIG_HW_RANDOM_TPM=y
-# CONFIG_HW_RANDOM_VIA is not set
-# CONFIG_HW_RANDOM_VIRTIO is not set
-# CONFIG_HW_RANDOM_XIPHERA is not set
-# CONFIG_HX711 is not set
-# CONFIG_HYPERV is not set
-# CONFIG_HYPERV_TSCPAGE is not set
-# CONFIG_HYSDN is not set
-CONFIG_HZ=100
-CONFIG_HZ_100=y
-# CONFIG_HZ_1000 is not set
-# CONFIG_HZ_1024 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_200 is not set
-# CONFIG_HZ_24 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_500 is not set
-# CONFIG_HZ_PERIODIC is not set
-# CONFIG_I2C is not set
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCA is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
-# CONFIG_I2C_AU1550 is not set
-# CONFIG_I2C_BCM2835 is not set
-# CONFIG_I2C_BCM_IPROC is not set
-# CONFIG_I2C_BRCMSTB is not set
-# CONFIG_I2C_CADENCE is not set
-# CONFIG_I2C_CBUS_GPIO is not set
-# CONFIG_I2C_CHARDEV is not set
-# CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_CP2615 is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEMUX_PINCTRL is not set
-# CONFIG_I2C_DESIGNWARE_PCI is not set
-# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
-# CONFIG_I2C_DESIGNWARE_SLAVE is not set
-# CONFIG_I2C_DIOLAN_U2C is not set
-# CONFIG_I2C_EG20T is not set
-# CONFIG_I2C_ELEKTOR is not set
-# CONFIG_I2C_EMEV2 is not set
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set
-# CONFIG_I2C_HELPER_AUTO is not set
-# CONFIG_I2C_HID is not set
-# CONFIG_I2C_HID_OF is not set
-# CONFIG_I2C_HID_OF_GOODIX is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_IBM_IIC is not set
-# CONFIG_I2C_IMG is not set
-# CONFIG_I2C_ISCH is not set
-# CONFIG_I2C_ISMT is not set
-# CONFIG_I2C_JZ4780 is not set
-# CONFIG_I2C_MLXCPLD is not set
-# CONFIG_I2C_MPC is not set
-# CONFIG_I2C_MT65XX is not set
-# CONFIG_I2C_MUX is not set
-# CONFIG_I2C_MUX_GPIO is not set
-# CONFIG_I2C_MUX_GPMUX is not set
-# CONFIG_I2C_MUX_LTC4306 is not set
-# CONFIG_I2C_MUX_MLXCPLD is not set
-# CONFIG_I2C_MUX_PCA9541 is not set
-# CONFIG_I2C_MUX_PCA954x is not set
-# CONFIG_I2C_MUX_PINCTRL is not set
-# CONFIG_I2C_MUX_REG is not set
-# CONFIG_I2C_MV64XXX is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_NOMADIK is not set
-# CONFIG_I2C_NVIDIA_GPU is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_OCTEON is not set
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PXA_PCI is not set
-# CONFIG_I2C_PXA_SLAVE is not set
-# CONFIG_I2C_RCAR is not set
-# CONFIG_I2C_RK3X is not set
-# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
-# CONFIG_I2C_S3C2410 is not set
-# CONFIG_I2C_SCMI is not set
-# CONFIG_I2C_SH_MOBILE is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_SLAVE is not set
-# CONFIG_I2C_SLAVE_EEPROM is not set
-# CONFIG_I2C_SMBUS is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_THUNDERX is not set
-# CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VERSATILE is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VIRTIO is not set
-# CONFIG_I2C_XILINX is not set
-# CONFIG_I3C is not set
-# CONFIG_I40E is not set
-# CONFIG_I40EVF is not set
-# CONFIG_I6300ESB_WDT is not set
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_IAQCORE is not set
-# CONFIG_IBM_ASM is not set
-# CONFIG_IBM_EMAC_DEBUG is not set
-# CONFIG_IBM_EMAC_EMAC4 is not set
-# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_EMAC_RGMII is not set
-# CONFIG_IBM_EMAC_TAH is not set
-# CONFIG_IBM_EMAC_ZMII is not set
-# CONFIG_ICE is not set
-# CONFIG_ICP10100 is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_ICS932S401 is not set
-# CONFIG_ICST is not set
-# CONFIG_IDE is not set
-# CONFIG_IDEAPAD_LAPTOP is not set
-# CONFIG_IDE_GD is not set
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDLE_PAGE_TRACKING is not set
-# CONFIG_IEEE802154 is not set
-# CONFIG_IEEE802154_ADF7242 is not set
-# CONFIG_IEEE802154_ATUSB is not set
-# CONFIG_IEEE802154_CA8210 is not set
-# CONFIG_IEEE802154_HWSIM is not set
-# CONFIG_IEEE802154_MCR20A is not set
-# CONFIG_IFB is not set
-# CONFIG_IGB is not set
-# CONFIG_IGBVF is not set
-# CONFIG_IGC is not set
-# CONFIG_IIO is not set
-# CONFIG_IIO_BUFFER is not set
-# CONFIG_IIO_BUFFER_CB is not set
-# CONFIG_IIO_BUFFER_DMA is not set
-# CONFIG_IIO_BUFFER_DMAENGINE is not set
-# CONFIG_IIO_BUFFER_HDC2010 is not set
-# CONFIG_IIO_BUFFER_HW_CONSUMER is not set
-# CONFIG_IIO_CONFIGFS is not set
-CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
-# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set
-# CONFIG_IIO_INTERRUPT_TRIGGER is not set
-# CONFIG_IIO_MUX is not set
-# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
-# CONFIG_IIO_RESCALE is not set
-# CONFIG_IIO_SIMPLE_DUMMY is not set
-# CONFIG_IIO_SSP_SENSORHUB is not set
-# CONFIG_IIO_ST_ACCEL_3AXIS is not set
-# CONFIG_IIO_ST_GYRO_3AXIS is not set
-# CONFIG_IIO_ST_LSM6DSX is not set
-# CONFIG_IIO_ST_LSM9DS0 is not set
-# CONFIG_IIO_ST_MAGN_3AXIS is not set
-# CONFIG_IIO_ST_PRESS is not set
-# CONFIG_IIO_SW_DEVICE is not set
-# CONFIG_IIO_SW_TRIGGER is not set
-# CONFIG_IIO_SYSFS_TRIGGER is not set
-# CONFIG_IIO_TRIGGER is not set
-# CONFIG_IIO_TRIGGERED_EVENT is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_IKCONFIG_PROC is not set
-# CONFIG_IKHEADERS is not set
-# CONFIG_IMA is not set
-# CONFIG_IMGPDC_WDT is not set
-# CONFIG_IMG_MDC_DMA is not set
-# CONFIG_IMX7D_ADC is not set
-# CONFIG_IMX_IPUV3_CORE is not set
-# CONFIG_IMX_THERMAL is not set
-# CONFIG_INA2XX_ADC is not set
-# CONFIG_INDIRECT_PIO is not set
-CONFIG_INET=y
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_ESPINTCP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_ESPINTCP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_LRO is not set
-CONFIG_INET_TABLE_PERTURB_ORDER=16
-# CONFIG_INET_TCP_DIAG is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_UDP_DIAG is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INFINIBAND is not set
-# CONFIG_INFTL is not set
-# CONFIG_INGENIC_ADC is not set
-# CONFIG_INGENIC_CGU_JZ4725B is not set
-# CONFIG_INGENIC_CGU_JZ4740 is not set
-# CONFIG_INGENIC_CGU_JZ4760 is not set
-# CONFIG_INGENIC_CGU_JZ4770 is not set
-# CONFIG_INGENIC_CGU_JZ4780 is not set
-# CONFIG_INGENIC_CGU_X1000 is not set
-# CONFIG_INGENIC_CGU_X1830 is not set
-# CONFIG_INGENIC_OST is not set
-# CONFIG_INGENIC_SYSOST is not set
-# CONFIG_INGENIC_TCU_CLK is not set
-# CONFIG_INGENIC_TCU_IRQ is not set
-# CONFIG_INGENIC_TIMER is not set
-CONFIG_INIT_ENV_ARG_LIMIT=32
-# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
-# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
-# CONFIG_INIT_STACK_ALL_PATTERN is not set
-# CONFIG_INIT_STACK_ALL_ZERO is not set
-CONFIG_INIT_STACK_NONE=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_AD714X is not set
-# CONFIG_INPUT_ADXL34X is not set
-# CONFIG_INPUT_APANEL is not set
-# CONFIG_INPUT_ATI_REMOTE2 is not set
-# CONFIG_INPUT_ATLAS_BTNS is not set
-# CONFIG_INPUT_ATMEL_CAPTOUCH is not set
-# CONFIG_INPUT_AXP20X_PEK is not set
-# CONFIG_INPUT_BMA150 is not set
-# CONFIG_INPUT_CM109 is not set
-# CONFIG_INPUT_CMA3000 is not set
-# CONFIG_INPUT_DA7280_HAPTICS is not set
-# CONFIG_INPUT_DRV260X_HAPTICS is not set
-# CONFIG_INPUT_DRV2665_HAPTICS is not set
-# CONFIG_INPUT_DRV2667_HAPTICS is not set
-# CONFIG_INPUT_E3X0_BUTTON is not set
-# CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_GP2A is not set
-# CONFIG_INPUT_GPIO_BEEPER is not set
-# CONFIG_INPUT_GPIO_DECODER is not set
-# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
-# CONFIG_INPUT_GPIO_TILT_POLLED is not set
-# CONFIG_INPUT_GPIO_VIBRA is not set
-# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set
-# CONFIG_INPUT_IMS_PCU is not set
-# CONFIG_INPUT_IQS269A is not set
-# CONFIG_INPUT_IQS626A is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_KEYSPAN_REMOTE is not set
-# CONFIG_INPUT_KXTJ9 is not set
-# CONFIG_INPUT_LEDS is not set
-# CONFIG_INPUT_MATRIXKMAP is not set
-# CONFIG_INPUT_MAX8997_HAPTIC is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_MMA8450 is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_MPU3050 is not set
-# CONFIG_INPUT_MSM_VIBRATOR is not set
-# CONFIG_INPUT_PALMAS_PWRBUTTON is not set
-# CONFIG_INPUT_PCF8574 is not set
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_PM8941_PWRKEY is not set
-# CONFIG_INPUT_PM8XXX_VIBRATOR is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_POWERMATE is not set
-# CONFIG_INPUT_PWM_BEEPER is not set
-# CONFIG_INPUT_PWM_VIBRA is not set
-# CONFIG_INPUT_REGULATOR_HAPTIC is not set
-# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_TPS65218_PWRBUTTON is not set
-# CONFIG_INPUT_TWL4030_PWRBUTTON is not set
-# CONFIG_INPUT_TWL4030_VIBRA is not set
-# CONFIG_INPUT_TWL6040_VIBRA is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_INPUT_WISTRON_BTNS is not set
-# CONFIG_INPUT_YEALINK is not set
-# CONFIG_INT340X_THERMAL is not set
-# CONFIG_INTEGRITY is not set
-# CONFIG_INTEGRITY_AUDIT is not set
-# CONFIG_INTEGRITY_SIGNATURE is not set
-# CONFIG_INTEL_ATOMISP2_LED is not set
-# CONFIG_INTEL_ATOMISP2_PM is not set
-# CONFIG_INTEL_CHT_INT33FE is not set
-# CONFIG_INTEL_HID_EVENT is not set
-# CONFIG_INTEL_IDLE is not set
-# CONFIG_INTEL_IDMA64 is not set
-# CONFIG_INTEL_IDXD is not set
-# CONFIG_INTEL_IDXD_COMPAT is not set
-# CONFIG_INTEL_INT0002_VGPIO is not set
-# CONFIG_INTEL_IOATDMA is not set
-# CONFIG_INTEL_ISH_HID is not set
-# CONFIG_INTEL_MEI is not set
-# CONFIG_INTEL_MEI_ME is not set
-# CONFIG_INTEL_MEI_TXE is not set
-# CONFIG_INTEL_MIC_CARD is not set
-# CONFIG_INTEL_MIC_HOST is not set
-# CONFIG_INTEL_MID_PTI is not set
-# CONFIG_INTEL_OAKTRAIL is not set
-# CONFIG_INTEL_PMC_CORE is not set
-# CONFIG_INTEL_PUNIT_IPC is not set
-# CONFIG_INTEL_RST is not set
-# CONFIG_INTEL_SMARTCONNECT is not set
-# CONFIG_INTEL_SOC_PMIC is not set
-# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set
-# CONFIG_INTEL_SOC_PMIC_CHTWC is not set
-# CONFIG_INTEL_TH is not set
-# CONFIG_INTEL_VBTN is not set
-# CONFIG_INTEL_XWAY_PHY is not set
-# CONFIG_INTERCONNECT is not set
-# CONFIG_INTERVAL_TREE_TEST is not set
-# CONFIG_INV_ICM42600_I2C is not set
-# CONFIG_INV_ICM42600_SPI is not set
-# CONFIG_INV_MPU6050_I2C is not set
-# CONFIG_INV_MPU6050_IIO is not set
-# CONFIG_INV_MPU6050_SPI is not set
-# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
-# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set
-# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_IONIC is not set
-# CONFIG_IOSCHED_BFQ is not set
-# CONFIG_IOSM is not set
-CONFIG_IO_STRICT_DEVMEM=y
-# CONFIG_IO_URING is not set
-CONFIG_IO_WQ=y
-# CONFIG_IP17XX_PHY is not set
-# CONFIG_IP6_NF_FILTER is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_IP6_NF_MATCH_AH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_MH is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_RPFILTER is not set
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_SRH is not set
-# CONFIG_IP6_NF_NAT is not set
-# CONFIG_IP6_NF_RAW is not set
-# CONFIG_IP6_NF_SECURITY is not set
-# CONFIG_IP6_NF_TARGET_HL is not set
-# CONFIG_IP6_NF_TARGET_MASQUERADE is not set
-# CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IP6_NF_TARGET_SYNPROXY is not set
-# CONFIG_IPACK_BUS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_IPMB_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPV6 is not set
-# CONFIG_IPV6_FOU is not set
-# CONFIG_IPV6_FOU_TUNNEL is not set
-# CONFIG_IPV6_ILA is not set
-# CONFIG_IPV6_IOAM6_LWTUNNEL is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_ROUTE_INFO is not set
-# CONFIG_IPV6_RPL_LWTUNNEL is not set
-# CONFIG_IPV6_SEG6_HMAC is not set
-# CONFIG_IPV6_SEG6_LWTUNNEL is not set
-# CONFIG_IPV6_SIT is not set
-# CONFIG_IPV6_SIT_6RD is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_VTI is not set
-# CONFIG_IPVLAN is not set
-# CONFIG_IPVTAP is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2100_DEBUG is not set
-CONFIG_IPW2100_MONITOR=y
-# CONFIG_IPW2200 is not set
-# CONFIG_IPW2200_DEBUG is not set
-CONFIG_IPW2200_MONITOR=y
-# CONFIG_IPW2200_PROMISCUOUS is not set
-# CONFIG_IPW2200_QOS is not set
-# CONFIG_IPW2200_RADIOTAP is not set
-# CONFIG_IPWIRELESS is not set
-# CONFIG_IPX is not set
-CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_FIB_TRIE_STATS is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_NF_ARPFILTER is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_ARP_MANGLE is not set
-# CONFIG_IP_NF_FILTER is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_MANGLE is not set
-# CONFIG_IP_NF_MATCH_AH is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_RPFILTER is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_RAW is not set
-# CONFIG_IP_NF_SECURITY is not set
-# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_MASQUERADE is not set
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_REDIRECT is not set
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_SYNPROXY is not set
-# CONFIG_IP_NF_TARGET_TTL is not set
-# CONFIG_IP_PIMSM_V1 is not set
-# CONFIG_IP_PIMSM_V2 is not set
-# CONFIG_IP_PNP is not set
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_IP_SET is not set
-# CONFIG_IP_SET_HASH_IPMAC is not set
-# CONFIG_IP_VS is not set
-# CONFIG_IP_VS_MH is not set
-CONFIG_IP_VS_MH_TAB_INDEX=10
-# CONFIG_IP_VS_TWOS is not set
-# CONFIG_IRDA is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_IRQ_ALL_CPUS is not set
-# CONFIG_IRQ_DOMAIN_DEBUG is not set
-# CONFIG_IRQ_POLL is not set
-# CONFIG_IRQ_TIME_ACCOUNTING is not set
-# CONFIG_IR_GPIO_CIR is not set
-# CONFIG_IR_HIX5HD2 is not set
-# CONFIG_IR_IGORPLUGUSB is not set
-# CONFIG_IR_IGUANA is not set
-# CONFIG_IR_IMG is not set
-# CONFIG_IR_IMON is not set
-# CONFIG_IR_IMON_RAW is not set
-# CONFIG_IR_JVC_DECODER is not set
-# CONFIG_IR_LIRC_CODEC is not set
-# CONFIG_IR_MCEUSB is not set
-# CONFIG_IR_NEC_DECODER is not set
-# CONFIG_IR_RC5_DECODER is not set
-# CONFIG_IR_RC6_DECODER is not set
-# CONFIG_IR_REDRAT3 is not set
-# CONFIG_IR_SERIAL is not set
-# CONFIG_IR_SIR is not set
-# CONFIG_IR_SONY_DECODER is not set
-# CONFIG_IR_STREAMZAP is not set
-# CONFIG_IR_TOY is not set
-# CONFIG_IR_TTUSBIR is not set
-# CONFIG_ISA_BUS is not set
-# CONFIG_ISA_BUS_API is not set
-# CONFIG_ISCSI_BOOT_SYSFS is not set
-# CONFIG_ISCSI_TCP is not set
-CONFIG_ISDN=y
-# CONFIG_ISDN_AUDIO is not set
-# CONFIG_ISDN_CAPI is not set
-# CONFIG_ISDN_CAPI_CAPIDRV is not set
-# CONFIG_ISDN_DIVERSION is not set
-# CONFIG_ISDN_DRV_ACT2000 is not set
-# CONFIG_ISDN_DRV_GIGASET is not set
-# CONFIG_ISDN_DRV_HISAX is not set
-# CONFIG_ISDN_DRV_ICN is not set
-# CONFIG_ISDN_DRV_LOOP is not set
-# CONFIG_ISDN_DRV_PCBIT is not set
-# CONFIG_ISDN_DRV_SC is not set
-# CONFIG_ISDN_I4L is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_ISL29020 is not set
-# CONFIG_ISL29125 is not set
-# CONFIG_ISL29501 is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_ISS4xx is not set
-# CONFIG_ITG3200 is not set
-# CONFIG_IWL3945 is not set
-# CONFIG_IWLWIFI is not set
-# CONFIG_IXGB is not set
-# CONFIG_IXGBE is not set
-# CONFIG_IXGBEVF is not set
-# CONFIG_JAILHOUSE_GUEST is not set
-# CONFIG_JBD2_DEBUG is not set
-# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_POSIX_ACL is not set
-# CONFIG_JFFS2_FS_SECURITY is not set
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_LZMA=y
-# CONFIG_JFFS2_LZO is not set
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_JFFS2_SUMMARY=y
-# CONFIG_JFFS2_ZLIB is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_POSIX_ACL is not set
-# CONFIG_JFS_SECURITY is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_JME is not set
-CONFIG_JOLIET=y
-# CONFIG_JSA1212 is not set
-# CONFIG_JUMP_LABEL is not set
-# CONFIG_JZ4740_WDT is not set
-# CONFIG_JZ4770_PHY is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set
-# CONFIG_KALLSYMS_ALL is not set
-CONFIG_KALLSYMS_BASE_RELATIVE=y
-# CONFIG_KALLSYMS_UNCOMPRESSED is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_KASAN is not set
-# CONFIG_KASAN_MODULE_TEST is not set
-CONFIG_KASAN_STACK=y
-# CONFIG_KCMP is not set
-# CONFIG_KCOV is not set
-CONFIG_KCOV_IRQ_AREA_SIZE=0x40000
-# CONFIG_KCSAN is not set
-# CONFIG_KERNEL_BZIP2 is not set
-# CONFIG_KERNEL_CAT is not set
-# CONFIG_KERNEL_GZIP is not set
-# CONFIG_KERNEL_LZ4 is not set
-# CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_LZO is not set
-CONFIG_KERNEL_MODE_NEON=y
-CONFIG_KERNEL_XZ=y
-# CONFIG_KERNEL_ZSTD is not set
-CONFIG_KERNFS=y
-# CONFIG_KEXEC is not set
-# CONFIG_KEXEC_FILE is not set
-# CONFIG_KEXEC_SIG is not set
-# CONFIG_KEYBOARD_ADC is not set
-# CONFIG_KEYBOARD_ADP5588 is not set
-# CONFIG_KEYBOARD_ADP5589 is not set
-# CONFIG_KEYBOARD_APPLESPI is not set
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_BCM is not set
-# CONFIG_KEYBOARD_CAP11XX is not set
-# CONFIG_KEYBOARD_DLINK_DIR685 is not set
-# CONFIG_KEYBOARD_GPIO is not set
-# CONFIG_KEYBOARD_GPIO_POLLED is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_LM8323 is not set
-# CONFIG_KEYBOARD_LM8333 is not set
-# CONFIG_KEYBOARD_MATRIX is not set
-# CONFIG_KEYBOARD_MAX7359 is not set
-# CONFIG_KEYBOARD_MCS is not set
-# CONFIG_KEYBOARD_MPR121 is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_OMAP4 is not set
-# CONFIG_KEYBOARD_OPENCORES is not set
-# CONFIG_KEYBOARD_PXA27x is not set
-# CONFIG_KEYBOARD_QT1050 is not set
-# CONFIG_KEYBOARD_QT1070 is not set
-# CONFIG_KEYBOARD_QT2160 is not set
-# CONFIG_KEYBOARD_SAMSUNG is not set
-# CONFIG_KEYBOARD_SH_KEYSC is not set
-# CONFIG_KEYBOARD_SNVS_PWRKEY is not set
-# CONFIG_KEYBOARD_STMPE is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_TCA6416 is not set
-# CONFIG_KEYBOARD_TCA8418 is not set
-# CONFIG_KEYBOARD_TEGRA is not set
-# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set
-# CONFIG_KEYBOARD_TWL4030 is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYS is not set
-# CONFIG_KEYS_REQUEST_CACHE is not set
-# CONFIG_KEY_DH_OPERATIONS is not set
-# CONFIG_KFENCE is not set
-# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
-# CONFIG_KMX61 is not set
-# CONFIG_KPC2000 is not set
-# CONFIG_KPROBES is not set
-# CONFIG_KPROBES_SANITY_TEST is not set
-# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set
-# CONFIG_KPROBE_EVENT_GEN_TEST is not set
-# CONFIG_KS7010 is not set
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851 is not set
-# CONFIG_KS8851_MLL is not set
-# CONFIG_KSM is not set
-# CONFIG_KSZ884X_PCI is not set
-# CONFIG_KUNIT is not set
-CONFIG_KUSER_HELPERS=y
-# CONFIG_KVM_AMD is not set
-# CONFIG_KVM_AMD_SEV is not set
-# CONFIG_KVM_GUEST is not set
-# CONFIG_KVM_INTEL is not set
-# CONFIG_KVM_WERROR is not set
-# CONFIG_KVM_XEN is not set
-# CONFIG_KXCJK1013 is not set
-# CONFIG_KXSD9 is not set
-# CONFIG_L2TP is not set
-# CONFIG_L2TP_ETH is not set
-# CONFIG_L2TP_IP is not set
-# CONFIG_L2TP_V3 is not set
-# CONFIG_LAN743X is not set
-# CONFIG_LANMEDIA is not set
-# CONFIG_LANTIQ is not set
-# CONFIG_LAPB is not set
-# CONFIG_LASAT is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_LATTICE_ECP3_CONFIG is not set
-CONFIG_LBDAF=y
-# CONFIG_LCD_AMS369FG06 is not set
-# CONFIG_LCD_CLASS_DEVICE is not set
-# CONFIG_LCD_HX8357 is not set
-# CONFIG_LCD_ILI922X is not set
-# CONFIG_LCD_ILI9320 is not set
-# CONFIG_LCD_L4F00242T03 is not set
-# CONFIG_LCD_LD9040 is not set
-# CONFIG_LCD_LMS283GF05 is not set
-# CONFIG_LCD_LMS501KF03 is not set
-# CONFIG_LCD_LTV350QV is not set
-# CONFIG_LCD_OTM3225A is not set
-# CONFIG_LCD_S6E63M0 is not set
-# CONFIG_LCD_TDO24M is not set
-# CONFIG_LCD_VGG2432A4 is not set
-CONFIG_LDISC_AUTOLOAD=y
-# CONFIG_LDM_PARTITION is not set
-CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
-# CONFIG_LD_HEAD_STUB_CATCH is not set
-# CONFIG_LEDS_AN30259A is not set
-# CONFIG_LEDS_APU is not set
-# CONFIG_LEDS_AW2013 is not set
-# CONFIG_LEDS_BCM6328 is not set
-# CONFIG_LEDS_BCM6358 is not set
-# CONFIG_LEDS_BD2802 is not set
-# CONFIG_LEDS_BLINKM is not set
-CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
-CONFIG_LEDS_CLASS=y
-# CONFIG_LEDS_CLASS_FLASH is not set
-CONFIG_LEDS_CLASS_MULTICOLOR=y
-# CONFIG_LEDS_CR0014114 is not set
-# CONFIG_LEDS_DAC124S085 is not set
-# CONFIG_LEDS_EL15203000 is not set
-# CONFIG_LEDS_GPIO is not set
-# CONFIG_LEDS_INTEL_SS4200 is not set
-# CONFIG_LEDS_IS31FL319X is not set
-# CONFIG_LEDS_IS31FL32XX is not set
-# CONFIG_LEDS_LM3530 is not set
-# CONFIG_LEDS_LM3532 is not set
-# CONFIG_LEDS_LM355x is not set
-# CONFIG_LEDS_LM3642 is not set
-# CONFIG_LEDS_LM3692X is not set
-# CONFIG_LEDS_LP3944 is not set
-# CONFIG_LEDS_LP3952 is not set
-# CONFIG_LEDS_LP50XX is not set
-# CONFIG_LEDS_LP5521 is not set
-# CONFIG_LEDS_LP5523 is not set
-# CONFIG_LEDS_LP5562 is not set
-# CONFIG_LEDS_LP55XX_COMMON is not set
-# CONFIG_LEDS_LP8501 is not set
-# CONFIG_LEDS_LP8860 is not set
-# CONFIG_LEDS_LT3593 is not set
-# CONFIG_LEDS_MLXCPLD is not set
-# CONFIG_LEDS_MLXREG is not set
-# CONFIG_LEDS_NIC78BX is not set
-# CONFIG_LEDS_NS2 is not set
-# CONFIG_LEDS_OT200 is not set
-# CONFIG_LEDS_PCA9532 is not set
-# CONFIG_LEDS_PCA955X is not set
-# CONFIG_LEDS_PCA963X is not set
-# CONFIG_LEDS_PWM is not set
-# CONFIG_LEDS_REGULATOR is not set
-# CONFIG_LEDS_SPI_BYTE is not set
-# CONFIG_LEDS_SYSCON is not set
-# CONFIG_LEDS_TCA6507 is not set
-# CONFIG_LEDS_TI_LMU_COMMON is not set
-# CONFIG_LEDS_TLC591XX is not set
-CONFIG_LEDS_TRIGGERS=y
-# CONFIG_LEDS_TRIGGER_ACTIVITY is not set
-# CONFIG_LEDS_TRIGGER_AUDIO is not set
-# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
-# CONFIG_LEDS_TRIGGER_CAMERA is not set
-# CONFIG_LEDS_TRIGGER_CPU is not set
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-# CONFIG_LEDS_TRIGGER_DISK is not set
-# CONFIG_LEDS_TRIGGER_GPIO is not set
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-# CONFIG_LEDS_TRIGGER_MTD is not set
-CONFIG_LEDS_TRIGGER_NETDEV=y
-# CONFIG_LEDS_TRIGGER_ONESHOT is not set
-# CONFIG_LEDS_TRIGGER_PANIC is not set
-# CONFIG_LEDS_TRIGGER_PATTERN is not set
-CONFIG_LEDS_TRIGGER_TIMER=y
-# CONFIG_LEDS_TRIGGER_TRANSIENT is not set
-# CONFIG_LEDS_TRIGGER_TTY is not set
-# CONFIG_LEDS_TURRIS_OMNIA is not set
-# CONFIG_LEDS_USER is not set
-# CONFIG_LED_TRIGGER_PHY is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_LGUEST is not set
-# CONFIG_LIB80211 is not set
-# CONFIG_LIB80211_CRYPT_CCMP is not set
-# CONFIG_LIB80211_CRYPT_TKIP is not set
-# CONFIG_LIB80211_CRYPT_WEP is not set
-# CONFIG_LIB80211_DEBUG is not set
-# CONFIG_LIBCRC32C is not set
-# CONFIG_LIBERTAS is not set
-# CONFIG_LIBERTAS_THINFIRM is not set
-# CONFIG_LIBERTAS_USB is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_LIBIPW_DEBUG is not set
-# CONFIG_LIBNVDIMM is not set
-CONFIG_LIB_MEMNEQ=y
-# CONFIG_LIDAR_LITE_V2 is not set
-CONFIG_LINEAR_RANGES=y
-# CONFIG_LIQUIDIO is not set
-# CONFIG_LIQUIDIO_VF is not set
-# CONFIG_LIRC is not set
-# CONFIG_LIS3L02DQ is not set
-# CONFIG_LITEX_LITEETH is not set
-# CONFIG_LITEX_SOC_CONTROLLER is not set
-# CONFIG_LIVEPATCH is not set
-# CONFIG_LKDTM is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_LMK04832 is not set
-# CONFIG_LMP91000 is not set
-# CONFIG_LNET is not set
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_LOCKD is not set
-CONFIG_LOCKDEP_BITS=15
-CONFIG_LOCKDEP_CHAINS_BITS=16
-CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
-CONFIG_LOCKDEP_STACK_TRACE_BITS=19
-CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_LOCKD_V4=y
-# CONFIG_LOCKUP_DETECTOR is not set
-# CONFIG_LOCK_EVENT_COUNTS is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_LOCK_TORTURE_TEST is not set
-# CONFIG_LOGFS is not set
-# CONFIG_LOGIG940_FF is not set
-# CONFIG_LOGIRUMBLEPAD2_FF is not set
-# CONFIG_LOGITECH_FF is not set
-# CONFIG_LOGIWHEELS_FF is not set
-# CONFIG_LOGO is not set
-CONFIG_LOG_BUF_SHIFT=17
-CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
-# CONFIG_LOONGSON_MC146818 is not set
-# CONFIG_LPC_ICH is not set
-# CONFIG_LPC_SCH is not set
-# CONFIG_LP_CONSOLE is not set
-CONFIG_LRU_GEN=y
-CONFIG_LRU_GEN_ENABLED=y
-# CONFIG_LRU_GEN_STATS is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity"
-CONFIG_LSM_MMAP_MIN_ADDR=65536
-# CONFIG_LTC1660 is not set
-# CONFIG_LTC2471 is not set
-# CONFIG_LTC2485 is not set
-# CONFIG_LTC2496 is not set
-# CONFIG_LTC2497 is not set
-# CONFIG_LTC2632 is not set
-# CONFIG_LTC2983 is not set
-# CONFIG_LTE_GDM724X is not set
-CONFIG_LTO_NONE=y
-# CONFIG_LTPC is not set
-# CONFIG_LTR501 is not set
-# CONFIG_LUSTRE_FS is not set
-# CONFIG_LV0104CS is not set
-# CONFIG_LWTUNNEL is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_LZ4HC_COMPRESS is not set
-# CONFIG_LZ4_COMPRESS is not set
-# CONFIG_LZ4_DECOMPRESS is not set
-CONFIG_LZMA_COMPRESS=y
-CONFIG_LZMA_DECOMPRESS=y
-# CONFIG_LZO_COMPRESS is not set
-# CONFIG_LZO_DECOMPRESS is not set
-# CONFIG_M62332 is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_MAC80211_MESSAGE_TRACING is not set
-CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
-# CONFIG_MACB is not set
-# CONFIG_MACH_ASM9260 is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MACH_INGENIC is not set
-# CONFIG_MACH_INGENIC_SOC is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_JZ4740 is not set
-# CONFIG_MACH_LOONGSON2EF is not set
-# CONFIG_MACH_LOONGSON32 is not set
-# CONFIG_MACH_LOONGSON64 is not set
-# CONFIG_MACH_NINTENDO64 is not set
-# CONFIG_MACH_PIC32 is not set
-# CONFIG_MACH_PISTACHIO is not set
-# CONFIG_MACH_REALTEK_RTL is not set
-# CONFIG_MACH_TX39XX is not set
-# CONFIG_MACH_TX49XX is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_MACH_XILFPGA is not set
-# CONFIG_MACINTOSH_DRIVERS is not set
-# CONFIG_MACSEC is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_MACVTAP is not set
-# CONFIG_MAC_EMUMOUSEBTN is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MAG3110 is not set
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
-# CONFIG_MAGIC_SYSRQ_SERIAL is not set
-CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
-# CONFIG_MAILBOX is not set
-# CONFIG_MANAGER_SBS is not set
-# CONFIG_MANDATORY_FILE_LOCKING is not set
-# CONFIG_MANGLE_BOOTARGS is not set
-# CONFIG_MARVELL_10G_PHY is not set
-# CONFIG_MARVELL_88X2222_PHY is not set
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_MAX1027 is not set
-# CONFIG_MAX11100 is not set
-# CONFIG_MAX1118 is not set
-# CONFIG_MAX1241 is not set
-# CONFIG_MAX1363 is not set
-# CONFIG_MAX30100 is not set
-# CONFIG_MAX30102 is not set
-# CONFIG_MAX31856 is not set
-# CONFIG_MAX44000 is not set
-# CONFIG_MAX44009 is not set
-# CONFIG_MAX517 is not set
-# CONFIG_MAX5432 is not set
-# CONFIG_MAX5481 is not set
-# CONFIG_MAX5487 is not set
-# CONFIG_MAX5821 is not set
-# CONFIG_MAX63XX_WATCHDOG is not set
-# CONFIG_MAX9611 is not set
-# CONFIG_MAXIM_THERMOCOUPLE is not set
-# CONFIG_MAXLINEAR_GPHY is not set
-CONFIG_MAY_USE_DEVLINK=y
-# CONFIG_MB1232 is not set
-# CONFIG_MC3230 is not set
-# CONFIG_MCB is not set
-# CONFIG_MCP320X is not set
-# CONFIG_MCP3422 is not set
-# CONFIG_MCP3911 is not set
-# CONFIG_MCP4018 is not set
-# CONFIG_MCP41010 is not set
-# CONFIG_MCP4131 is not set
-# CONFIG_MCP4531 is not set
-# CONFIG_MCP4725 is not set
-# CONFIG_MCP4922 is not set
-# CONFIG_MCPM is not set
-# CONFIG_MCTP is not set
-# CONFIG_MD is not set
-# CONFIG_MDIO_BCM_UNIMAC is not set
-# CONFIG_MDIO_BITBANG is not set
-# CONFIG_MDIO_BUS_MUX_GPIO is not set
-# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
-# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set
-# CONFIG_MDIO_DEVICE is not set
-# CONFIG_MDIO_DEVRES is not set
-# CONFIG_MDIO_HISI_FEMAC is not set
-# CONFIG_MDIO_IPQ4019 is not set
-# CONFIG_MDIO_IPQ8064 is not set
-# CONFIG_MDIO_MSCC_MIIM is not set
-# CONFIG_MDIO_MVUSB is not set
-# CONFIG_MDIO_OCTEON is not set
-# CONFIG_MDIO_THUNDER is not set
-# CONFIG_MDIO_XPCS is not set
-# CONFIG_MDM_GCC_9607 is not set
-# CONFIG_MD_FAULTY is not set
-# CONFIG_MEDIATEK_GE_PHY is not set
-# CONFIG_MEDIATEK_MT6577_AUXADC is not set
-# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
-# CONFIG_MEDIA_ATTACH is not set
-# CONFIG_MEDIA_CAMERA_SUPPORT is not set
-# CONFIG_MEDIA_CEC_SUPPORT is not set
-# CONFIG_MEDIA_CONTROLLER is not set
-# CONFIG_MEDIA_CONTROLLER_DVB is not set
-# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
-# CONFIG_MEDIA_PCI_SUPPORT is not set
-# CONFIG_MEDIA_PLATFORM_SUPPORT is not set
-# CONFIG_MEDIA_RADIO_SUPPORT is not set
-# CONFIG_MEDIA_RC_SUPPORT is not set
-# CONFIG_MEDIA_SDR_SUPPORT is not set
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
-# CONFIG_MEDIA_SUPPORT is not set
-# CONFIG_MEDIA_SUPPORT_FILTER is not set
-# CONFIG_MEDIA_TEST_SUPPORT is not set
-# CONFIG_MEDIA_TUNER_E4000 is not set
-# CONFIG_MEDIA_TUNER_FC0011 is not set
-# CONFIG_MEDIA_TUNER_FC0012 is not set
-# CONFIG_MEDIA_TUNER_FC0013 is not set
-# CONFIG_MEDIA_TUNER_FC2580 is not set
-# CONFIG_MEDIA_TUNER_IT913X is not set
-# CONFIG_MEDIA_TUNER_M88RS6000T is not set
-# CONFIG_MEDIA_TUNER_MAX2165 is not set
-# CONFIG_MEDIA_TUNER_MC44S803 is not set
-# CONFIG_MEDIA_TUNER_MSI001 is not set
-# CONFIG_MEDIA_TUNER_MT2060 is not set
-# CONFIG_MEDIA_TUNER_MT2063 is not set
-# CONFIG_MEDIA_TUNER_MT20XX is not set
-# CONFIG_MEDIA_TUNER_MT2131 is not set
-# CONFIG_MEDIA_TUNER_MT2266 is not set
-# CONFIG_MEDIA_TUNER_MXL301RF is not set
-# CONFIG_MEDIA_TUNER_MXL5005S is not set
-# CONFIG_MEDIA_TUNER_MXL5007T is not set
-# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set
-# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set
-# CONFIG_MEDIA_TUNER_QT1010 is not set
-# CONFIG_MEDIA_TUNER_R820T is not set
-# CONFIG_MEDIA_TUNER_SI2157 is not set
-# CONFIG_MEDIA_TUNER_SIMPLE is not set
-# CONFIG_MEDIA_TUNER_TDA18212 is not set
-# CONFIG_MEDIA_TUNER_TDA18218 is not set
-# CONFIG_MEDIA_TUNER_TDA18250 is not set
-# CONFIG_MEDIA_TUNER_TDA18271 is not set
-# CONFIG_MEDIA_TUNER_TDA827X is not set
-# CONFIG_MEDIA_TUNER_TDA8290 is not set
-# CONFIG_MEDIA_TUNER_TDA9887 is not set
-# CONFIG_MEDIA_TUNER_TEA5761 is not set
-# CONFIG_MEDIA_TUNER_TEA5767 is not set
-# CONFIG_MEDIA_TUNER_TUA9001 is not set
-# CONFIG_MEDIA_TUNER_XC2028 is not set
-# CONFIG_MEDIA_TUNER_XC4000 is not set
-# CONFIG_MEDIA_TUNER_XC5000 is not set
-# CONFIG_MEDIA_USB_SUPPORT is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_MELLANOX_PLATFORM is not set
-CONFIG_MEMBARRIER=y
-# CONFIG_MEMORY is not set
-# CONFIG_MEMORY_FAILURE is not set
-# CONFIG_MEMORY_HOTPLUG is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_MEMTEST is not set
-# CONFIG_MEN_A21_WDT is not set
-# CONFIG_MESON_SM is not set
-CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
-# CONFIG_MFD_88PM800 is not set
-# CONFIG_MFD_88PM805 is not set
-# CONFIG_MFD_88PM860X is not set
-# CONFIG_MFD_AAT2870_CORE is not set
-# CONFIG_MFD_AC100 is not set
-# CONFIG_MFD_ACT8945A is not set
-# CONFIG_MFD_ARIZONA_I2C is not set
-# CONFIG_MFD_ARIZONA_SPI is not set
-# CONFIG_MFD_AS3711 is not set
-# CONFIG_MFD_AS3722 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_MFD_ATC260X_I2C is not set
-# CONFIG_MFD_ATMEL_FLEXCOM is not set
-# CONFIG_MFD_ATMEL_HLCDC is not set
-# CONFIG_MFD_AXP20X is not set
-# CONFIG_MFD_AXP20X_I2C is not set
-# CONFIG_MFD_BCM590XX is not set
-# CONFIG_MFD_BD9571MWV is not set
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_CPCAP is not set
-# CONFIG_MFD_CROS_EC is not set
-# CONFIG_MFD_CS5535 is not set
-# CONFIG_MFD_DA9052_I2C is not set
-# CONFIG_MFD_DA9052_SPI is not set
-# CONFIG_MFD_DA9055 is not set
-# CONFIG_MFD_DA9062 is not set
-# CONFIG_MFD_DA9063 is not set
-# CONFIG_MFD_DA9150 is not set
-# CONFIG_MFD_DLN2 is not set
-# CONFIG_MFD_EXYNOS_LPASS is not set
-# CONFIG_MFD_GATEWORKS_GSC is not set
-# CONFIG_MFD_HI6421_PMIC is not set
-# CONFIG_MFD_INTEL_M10_BMC is not set
-# CONFIG_MFD_INTEL_PMT is not set
-# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set
-# CONFIG_MFD_IQS62X is not set
-# CONFIG_MFD_JANZ_CMODIO is not set
-# CONFIG_MFD_KEMPLD is not set
-# CONFIG_MFD_LM3533 is not set
-# CONFIG_MFD_LOCHNAGAR is not set
-# CONFIG_MFD_LP3943 is not set
-# CONFIG_MFD_LP8788 is not set
-# CONFIG_MFD_MADERA is not set
-# CONFIG_MFD_MAX14577 is not set
-# CONFIG_MFD_MAX77620 is not set
-# CONFIG_MFD_MAX77650 is not set
-# CONFIG_MFD_MAX77686 is not set
-# CONFIG_MFD_MAX77693 is not set
-# CONFIG_MFD_MAX77843 is not set
-# CONFIG_MFD_MAX8907 is not set
-# CONFIG_MFD_MAX8925 is not set
-# CONFIG_MFD_MAX8997 is not set
-# CONFIG_MFD_MAX8998 is not set
-# CONFIG_MFD_MC13XXX is not set
-# CONFIG_MFD_MC13XXX_I2C is not set
-# CONFIG_MFD_MC13XXX_SPI is not set
-# CONFIG_MFD_MENF21BMC is not set
-# CONFIG_MFD_MP2629 is not set
-# CONFIG_MFD_MT6360 is not set
-# CONFIG_MFD_MT6397 is not set
-# CONFIG_MFD_NTXEC is not set
-# CONFIG_MFD_OMAP_USB_HOST is not set
-# CONFIG_MFD_PALMAS is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_MFD_PM8921_CORE is not set
-# CONFIG_MFD_PM8XXX is not set
-# CONFIG_MFD_QCOM_PM8008 is not set
-# CONFIG_MFD_RC5T583 is not set
-# CONFIG_MFD_RDC321X is not set
-# CONFIG_MFD_RETU is not set
-# CONFIG_MFD_RK808 is not set
-# CONFIG_MFD_RN5T618 is not set
-# CONFIG_MFD_ROHM_BD70528 is not set
-# CONFIG_MFD_ROHM_BD71828 is not set
-# CONFIG_MFD_ROHM_BD718XX is not set
-# CONFIG_MFD_ROHM_BD957XMUF is not set
-# CONFIG_MFD_RSMU_I2C is not set
-# CONFIG_MFD_RSMU_SPI is not set
-# CONFIG_MFD_RT4831 is not set
-# CONFIG_MFD_RT5033 is not set
-# CONFIG_MFD_RTSX_PCI is not set
-# CONFIG_MFD_RTSX_USB is not set
-# CONFIG_MFD_SEC_CORE is not set
-# CONFIG_MFD_SI476X_CORE is not set
-# CONFIG_MFD_SKY81452 is not set
-# CONFIG_MFD_SL28CPLD is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_SMSC is not set
-# CONFIG_MFD_STMFX is not set
-# CONFIG_MFD_STMPE is not set
-# CONFIG_MFD_STPMIC1 is not set
-# CONFIG_MFD_SYSCON is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC3589X is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_MFD_TIMBERDALE is not set
-# CONFIG_MFD_TI_AM335X_TSCADC is not set
-# CONFIG_MFD_TI_LMU is not set
-# CONFIG_MFD_TI_LP873X is not set
-# CONFIG_MFD_TI_LP87565 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_TPS65086 is not set
-# CONFIG_MFD_TPS65090 is not set
-# CONFIG_MFD_TPS65217 is not set
-# CONFIG_MFD_TPS65218 is not set
-# CONFIG_MFD_TPS6586X is not set
-# CONFIG_MFD_TPS65910 is not set
-# CONFIG_MFD_TPS65912 is not set
-# CONFIG_MFD_TPS65912_I2C is not set
-# CONFIG_MFD_TPS65912_SPI is not set
-# CONFIG_MFD_TPS68470 is not set
-# CONFIG_MFD_TPS80031 is not set
-# CONFIG_MFD_TQMX86 is not set
-# CONFIG_MFD_VIPERBOARD is not set
-# CONFIG_MFD_VX855 is not set
-# CONFIG_MFD_WL1273_CORE is not set
-# CONFIG_MFD_WM831X is not set
-# CONFIG_MFD_WM831X_I2C is not set
-# CONFIG_MFD_WM831X_SPI is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8994 is not set
-# CONFIG_MG_DISK is not set
-# CONFIG_MHI_BUS is not set
-# CONFIG_MHI_BUS_DEBUG is not set
-# CONFIG_MHI_BUS_PCI_GENERIC is not set
-# CONFIG_MHI_NET is not set
-# CONFIG_MHI_WWAN_CTRL is not set
-# CONFIG_MHI_WWAN_MBIM is not set
-# CONFIG_MICREL_KS8995MA is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_MICROCHIP_KSZ is not set
-# CONFIG_MICROCHIP_PHY is not set
-# CONFIG_MICROCHIP_PIT64B is not set
-# CONFIG_MICROCHIP_T1_PHY is not set
-# CONFIG_MICROSEMI_PHY is not set
-# CONFIG_MIGRATION is not set
-CONFIG_MII=y
-# CONFIG_MIKROTIK is not set
-# CONFIG_MIKROTIK_RB532 is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_MIPS32_N32 is not set
-# CONFIG_MIPS32_O32 is not set
-# CONFIG_MIPS_ALCHEMY is not set
-# CONFIG_MIPS_CDMM is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_DTB is not set
-# CONFIG_MIPS_CMP is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MIPS_CPS is not set
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-# CONFIG_MIPS_FPU_EMULATOR is not set
-# CONFIG_MIPS_FP_SUPPORT is not set
-# CONFIG_MIPS_GENERIC is not set
-# CONFIG_MIPS_GENERIC_KERNEL is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_O32_FP64_SUPPORT is not set
-# CONFIG_MIPS_PARAVIRT is not set
-# CONFIG_MIPS_PLATFORM_DEVICES is not set
-# CONFIG_MIPS_RAW_APPENDED_DTB is not set
-# CONFIG_MIPS_SEAD3 is not set
-# CONFIG_MIPS_VA_BITS_48 is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_MISC_ALCOR_PCI is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_MISC_RTSX_PCI is not set
-# CONFIG_MISC_RTSX_USB is not set
-# CONFIG_MISDN is not set
-# CONFIG_MISDN_AVMFRITZ is not set
-# CONFIG_MISDN_HFCPCI is not set
-# CONFIG_MISDN_HFCUSB is not set
-# CONFIG_MISDN_INFINEON is not set
-# CONFIG_MISDN_NETJET is not set
-# CONFIG_MISDN_SPEEDFAX is not set
-# CONFIG_MISDN_W6692 is not set
-CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y
-# CONFIG_MKISS is not set
-# CONFIG_MLX4_CORE is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX5_CORE is not set
-# CONFIG_MLX5_SF is not set
-# CONFIG_MLX90614 is not set
-# CONFIG_MLX90632 is not set
-# CONFIG_MLXFW is not set
-# CONFIG_MLXSW_CORE is not set
-# CONFIG_MLX_CPLD_PLATFORM is not set
-# CONFIG_MLX_PLATFORM is not set
-# CONFIG_MMA7455_I2C is not set
-# CONFIG_MMA7455_SPI is not set
-# CONFIG_MMA7660 is not set
-# CONFIG_MMA8452 is not set
-# CONFIG_MMA9551 is not set
-# CONFIG_MMA9553 is not set
-# CONFIG_MMC is not set
-# CONFIG_MMC35240 is not set
-# CONFIG_MMC_ARMMMCI is not set
-# CONFIG_MMC_AU1X is not set
-# CONFIG_MMC_BLOCK is not set
-CONFIG_MMC_BLOCK_MINORS=8
-# CONFIG_MMC_CAVIUM_THUNDERX is not set
-# CONFIG_MMC_CB710 is not set
-# CONFIG_MMC_CQHCI is not set
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_DW is not set
-# CONFIG_MMC_HSQ is not set
-# CONFIG_MMC_JZ4740 is not set
-# CONFIG_MMC_MTK is not set
-# CONFIG_MMC_MVSDIO is not set
-# CONFIG_MMC_S3C is not set
-# CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_SDHCI_ACPI is not set
-# CONFIG_MMC_SDHCI_AM654 is not set
-# CONFIG_MMC_SDHCI_BCM_KONA is not set
-# CONFIG_MMC_SDHCI_BRCMSTB is not set
-# CONFIG_MMC_SDHCI_CADENCE is not set
-# CONFIG_MMC_SDHCI_F_SDH30 is not set
-# CONFIG_MMC_SDHCI_IPROC is not set
-# CONFIG_MMC_SDHCI_MILBEAUT is not set
-# CONFIG_MMC_SDHCI_MSM is not set
-# CONFIG_MMC_SDHCI_OF_ARASAN is not set
-# CONFIG_MMC_SDHCI_OF_ASPEED is not set
-# CONFIG_MMC_SDHCI_OF_AT91 is not set
-# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set
-# CONFIG_MMC_SDHCI_OF_ESDHC is not set
-# CONFIG_MMC_SDHCI_OF_HLWD is not set
-# CONFIG_MMC_SDHCI_OMAP is not set
-# CONFIG_MMC_SDHCI_PXAV2 is not set
-# CONFIG_MMC_SDHCI_PXAV3 is not set
-# CONFIG_MMC_SDHCI_S3C is not set
-# CONFIG_MMC_SDHCI_XENON is not set
-# CONFIG_MMC_SDRICOH_CS is not set
-# CONFIG_MMC_SPI is not set
-# CONFIG_MMC_STM32_SDMMC is not set
-# CONFIG_MMC_TEST is not set
-# CONFIG_MMC_TIFM_SD is not set
-# CONFIG_MMC_TOSHIBA_PCI is not set
-# CONFIG_MMC_USDHI6ROL0 is not set
-# CONFIG_MMC_USHC is not set
-# CONFIG_MMC_VIA_SDMMC is not set
-# CONFIG_MMC_VUB300 is not set
-# CONFIG_MMIOTRACE is not set
-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_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
-# CONFIG_MODULE_COMPRESS is not set
-# CONFIG_MODULE_COMPRESS_GZIP is not set
-CONFIG_MODULE_COMPRESS_NONE=y
-# CONFIG_MODULE_COMPRESS_XZ is not set
-# CONFIG_MODULE_COMPRESS_ZSTD is not set
-# CONFIG_MODULE_FORCE_LOAD is not set
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-# CONFIG_MODULE_SIG is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_MODULE_STRIPPED=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MOST is not set
-# CONFIG_MOTORCOMM_PHY is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_ELAN_I2C is not set
-# CONFIG_MOUSE_GPIO is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_PS2_FOCALTECH is not set
-# CONFIG_MOUSE_PS2_SENTELIC is not set
-# CONFIG_MOUSE_SYNAPTICS_I2C is not set
-# CONFIG_MOUSE_SYNAPTICS_USB is not set
-# CONFIG_MOXTET is not set
-# CONFIG_MPL115 is not set
-# CONFIG_MPL115_I2C is not set
-# CONFIG_MPL115_SPI is not set
-# CONFIG_MPL3115 is not set
-# CONFIG_MPLS is not set
-# CONFIG_MPLS_IPTUNNEL is not set
-# CONFIG_MPLS_ROUTING is not set
-# CONFIG_MPTCP is not set
-# CONFIG_MPU3050_I2C is not set
-# CONFIG_MQ_IOSCHED_DEADLINE is not set
-# CONFIG_MQ_IOSCHED_KYBER is not set
-# CONFIG_MS5611 is not set
-# CONFIG_MS5637 is not set
-# CONFIG_MSCC_OCELOT_SWITCH is not set
-# CONFIG_MSDOS_FS is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_MSI_BITMAP_SELFTEST is not set
-# CONFIG_MSI_LAPTOP is not set
-# CONFIG_MSM_GCC_8953 is not set
-# CONFIG_MSM_MMCC_8994 is not set
-# CONFIG_MST_IRQ is not set
-CONFIG_MTD=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_MTD_BLOCK2MTD is not set
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-# CONFIG_MTD_DATAFLASH is not set
-# CONFIG_MTD_DOCG3 is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_GPIO_ADDR is not set
-# CONFIG_MTD_HYPERBUS is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_INTEL_VR_NOR is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_LATCH_ADDR is not set
-# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_LPDDR2_NVM is not set
-# CONFIG_MTD_M25P80 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MCHP23K256 is not set
-# CONFIG_MTD_MCHP48L640 is not set
-# CONFIG_MTD_MT81xx_NOR is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MYLOADER_PARTS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_AMS_DELTA is not set
-# CONFIG_MTD_NAND_AR934X is not set
-# CONFIG_MTD_NAND_AR934X_HW_ECC is not set
-# CONFIG_MTD_NAND_ARASAN is not set
-# CONFIG_MTD_NAND_ATMEL is not set
-# CONFIG_MTD_NAND_AU1550 is not set
-# CONFIG_MTD_NAND_BCH is not set
-# CONFIG_MTD_NAND_BF5XX is not set
-# CONFIG_MTD_NAND_BRCMNAND is not set
-# CONFIG_MTD_NAND_CADENCE is not set
-# CONFIG_MTD_NAND_CAFE is not set
-# CONFIG_MTD_NAND_CM_X270 is not set
-# CONFIG_MTD_NAND_CS553X is not set
-# CONFIG_MTD_NAND_DAVINCI is not set
-# CONFIG_MTD_NAND_DENALI is not set
-# CONFIG_MTD_NAND_DENALI_DT is not set
-# CONFIG_MTD_NAND_DENALI_PCI is not set
-CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_DOCG4 is not set
-# CONFIG_MTD_NAND_ECC is not set
-# CONFIG_MTD_NAND_ECC_BCH is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
-# CONFIG_MTD_NAND_ECC_SW_BCH is not set
-# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set
-# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set
-# CONFIG_MTD_NAND_FSL_ELBC is not set
-# CONFIG_MTD_NAND_FSL_IFC is not set
-# CONFIG_MTD_NAND_FSL_UPM is not set
-# CONFIG_MTD_NAND_FSMC is not set
-# CONFIG_MTD_NAND_GPIO is not set
-# CONFIG_MTD_NAND_GPMI_NAND is not set
-# CONFIG_MTD_NAND_HISI504 is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_INTEL_LGM is not set
-# CONFIG_MTD_NAND_JZ4740 is not set
-# CONFIG_MTD_NAND_MPC5121_NFC is not set
-# CONFIG_MTD_NAND_MTK is not set
-# CONFIG_MTD_NAND_MTK_BMT is not set
-# CONFIG_MTD_NAND_MXC is not set
-# CONFIG_MTD_NAND_MXIC is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_NDFC is not set
-# CONFIG_MTD_NAND_NUC900 is not set
-# CONFIG_MTD_NAND_OMAP2 is not set
-# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set
-# CONFIG_MTD_NAND_ORION is not set
-# CONFIG_MTD_NAND_PASEMI is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_NAND_PXA3xx is not set
-# CONFIG_MTD_NAND_RB4XX is not set
-# CONFIG_MTD_NAND_RB750 is not set
-# CONFIG_MTD_NAND_RB91X is not set
-# CONFIG_MTD_NAND_RICOH is not set
-# CONFIG_MTD_NAND_S3C2410 is not set
-# CONFIG_MTD_NAND_SHARPSL is not set
-# CONFIG_MTD_NAND_SH_FLCTL is not set
-# CONFIG_MTD_NAND_SOCRATES is not set
-# CONFIG_MTD_NAND_TMIO is not set
-# CONFIG_MTD_NAND_TXX9NDFMC is not set
-CONFIG_MTD_OF_PARTS=y
-# CONFIG_MTD_ONENAND is not set
-# CONFIG_MTD_OOPS is not set
-# CONFIG_MTD_OTP is not set
-# CONFIG_MTD_PARSER_TRX is not set
-# CONFIG_MTD_PARTITIONED_MASTER is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PHYSMAP_COMPAT is not set
-# CONFIG_MTD_PHYSMAP_GEMINI is not set
-# CONFIG_MTD_PHYSMAP_GPIO_ADDR is not set
-# CONFIG_MTD_PHYSMAP_IXP4XX is not set
-CONFIG_MTD_PHYSMAP_OF=y
-# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set
-# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set
-# CONFIG_MTD_PHYSMAP_VERSATILE is not set
-# CONFIG_MTD_PLATRAM is not set
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_RAW_NAND is not set
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_ROM is not set
-CONFIG_MTD_ROOTFS_ROOT_DEV=y
-# CONFIG_MTD_ROUTERBOOT_PARTS is not set
-# CONFIG_MTD_SERCOMM_PARTS is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_SM_COMMON is not set
-# CONFIG_MTD_SPINAND_MT29F is not set
-# CONFIG_MTD_SPI_NAND is not set
-# CONFIG_MTD_SPI_NOR is not set
-# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
-CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
-# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
-# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
-# CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE is not set
-CONFIG_MTD_SPLIT=y
-# CONFIG_MTD_SPLIT_BCM63XX_FW is not set
-# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set
-# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
-# CONFIG_MTD_SPLIT_ELF_FW is not set
-# CONFIG_MTD_SPLIT_EVA_FW is not set
-# CONFIG_MTD_SPLIT_FIRMWARE is not set
-CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware"
-# CONFIG_MTD_SPLIT_FIT_FW is not set
-# CONFIG_MTD_SPLIT_H3C_VFS is not set
-# CONFIG_MTD_SPLIT_JIMAGE_FW is not set
-# CONFIG_MTD_SPLIT_LZMA_FW is not set
-# CONFIG_MTD_SPLIT_MINOR_FW is not set
-# CONFIG_MTD_SPLIT_SEAMA_FW is not set
-# CONFIG_MTD_SPLIT_SEIL_FW is not set
-CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y
-CONFIG_MTD_SPLIT_SUPPORT=y
-# CONFIG_MTD_SPLIT_TPLINK_FW is not set
-# CONFIG_MTD_SPLIT_TRX_FW is not set
-# CONFIG_MTD_SPLIT_UIMAGE_FW is not set
-# CONFIG_MTD_SPLIT_WRGG_FW is not set
-# CONFIG_MTD_SST25L is not set
-# CONFIG_MTD_SWAP is not set
-# CONFIG_MTD_TESTS is not set
-# CONFIG_MTD_UBI is not set
-# CONFIG_MTD_UBI_FASTMAP is not set
-# CONFIG_MTD_UBI_GLUEBI is not set
-# CONFIG_MTD_UIMAGE_SPLIT is not set
-# CONFIG_MTD_VIRT_CONCAT is not set
-# CONFIG_MTK_DEVAPC is not set
-# CONFIG_MTK_MMC is not set
-# CONFIG_MTK_MMSYS is not set
-# CONFIG_MTK_THERMAL is not set
-# CONFIG_MULTIPLEXER is not set
-CONFIG_MULTIUSER=y
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-# CONFIG_MUX_ADG792A is not set
-# CONFIG_MUX_ADGS1408 is not set
-# CONFIG_MUX_GPIO is not set
-# CONFIG_MUX_MMIO is not set
-# CONFIG_MV643XX_ETH is not set
-# CONFIG_MVMDIO is not set
-# CONFIG_MVNETA_BM is not set
-# CONFIG_MVSW61XX_PHY is not set
-# CONFIG_MV_XOR_V2 is not set
-# CONFIG_MWAVE is not set
-# CONFIG_MWL8K is not set
-# CONFIG_MXC4005 is not set
-# CONFIG_MXC6255 is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NAMESPACES is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NAU7802 is not set
-# CONFIG_NBPFAXI_DMA is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NE2000 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_NEC_MARKEINS is not set
-CONFIG_NET=y
-# CONFIG_NETCONSOLE is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NETDEVSIM is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_NETFILTER_ADVANCED is not set
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_NETFILTER_INGRESS is not set
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NETFILTER_NETLINK_ACCT is not set
-# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set
-# CONFIG_NETFILTER_NETLINK_HOOK is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NETFILTER_NETLINK_OSF is not set
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_XTABLES is not set
-# CONFIG_NETFILTER_XTABLES_COMPAT is not set
-# CONFIG_NETFILTER_XT_CONNMARK is not set
-# CONFIG_NETFILTER_XT_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_BPF is not set
-# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set
-# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
-# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
-# CONFIG_NETFILTER_XT_MATCH_CPU is not set
-# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
-# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
-# CONFIG_NETFILTER_XT_MATCH_ECN is not set
-# CONFIG_NETFILTER_XT_MATCH_ESP is not set
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
-# CONFIG_NETFILTER_XT_MATCH_HL is not set
-# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
-# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
-# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
-# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
-# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_MAC is not set
-# CONFIG_NETFILTER_XT_MATCH_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
-# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
-# CONFIG_NETFILTER_XT_MATCH_OSF is not set
-# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
-# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
-# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
-# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
-# CONFIG_NETFILTER_XT_MATCH_REALM is not set
-# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
-# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
-# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
-# CONFIG_NETFILTER_XT_MATCH_STATE is not set
-# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
-# CONFIG_NETFILTER_XT_MATCH_STRING is not set
-# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
-# CONFIG_NETFILTER_XT_MATCH_TIME is not set
-# CONFIG_NETFILTER_XT_MATCH_U32 is not set
-# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
-# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
-# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
-# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_CT is not set
-# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
-# CONFIG_NETFILTER_XT_TARGET_HL is not set
-# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
-# CONFIG_NETFILTER_XT_TARGET_LED is not set
-# CONFIG_NETFILTER_XT_TARGET_LOG is not set
-# CONFIG_NETFILTER_XT_TARGET_MARK is not set
-# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
-# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
-# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
-# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set
-# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
-# CONFIG_NETFILTER_XT_TARGET_TEE is not set
-# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
-# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
-# CONFIG_NETLABEL is not set
-# CONFIG_NETLINK_DIAG is not set
-# CONFIG_NETLINK_MMAP is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NETROM is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETXEN_NIC is not set
-# CONFIG_NET_9P is not set
-# CONFIG_NET_ACT_BPF is not set
-# CONFIG_NET_ACT_CSUM is not set
-# CONFIG_NET_ACT_CT is not set
-# CONFIG_NET_ACT_GACT is not set
-# CONFIG_NET_ACT_GATE is not set
-# CONFIG_NET_ACT_IFE is not set
-# CONFIG_NET_ACT_IPT is not set
-# CONFIG_NET_ACT_MIRRED is not set
-# CONFIG_NET_ACT_MPLS is not set
-# CONFIG_NET_ACT_NAT is not set
-# CONFIG_NET_ACT_PEDIT is not set
-# CONFIG_NET_ACT_POLICE is not set
-# CONFIG_NET_ACT_SAMPLE is not set
-# CONFIG_NET_ACT_SIMP is not set
-# CONFIG_NET_ACT_SKBEDIT is not set
-# CONFIG_NET_ACT_SKBMOD is not set
-# CONFIG_NET_ACT_TUNNEL_KEY is not set
-# CONFIG_NET_ACT_VLAN is not set
-CONFIG_NET_CADENCE=y
-# CONFIG_NET_CALXEDA_XGMAC is not set
-CONFIG_NET_CLS=y
-# CONFIG_NET_CLS_ACT is not set
-# CONFIG_NET_CLS_BASIC is not set
-# CONFIG_NET_CLS_BPF is not set
-# CONFIG_NET_CLS_FLOW is not set
-# CONFIG_NET_CLS_FLOWER is not set
-# CONFIG_NET_CLS_FW is not set
-CONFIG_NET_CLS_IND=y
-# CONFIG_NET_CLS_MATCHALL is not set
-# CONFIG_NET_CLS_ROUTE4 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_CLS_U32 is not set
-CONFIG_NET_CORE=y
-# CONFIG_NET_DEVLINK is not set
-# CONFIG_NET_DROP_MONITOR is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_NET_DSA_AR9331 is not set
-# CONFIG_NET_DSA_BCM_SF2 is not set
-# CONFIG_NET_DSA_LANTIQ_GSWIP is not set
-# CONFIG_NET_DSA_LEGACY is not set
-# CONFIG_NET_DSA_LOOP is not set
-# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set
-# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set
-# CONFIG_NET_DSA_MSCC_FELIX is not set
-# CONFIG_NET_DSA_MSCC_SEVILLE is not set
-# CONFIG_NET_DSA_MT7530 is not set
-# CONFIG_NET_DSA_MV88E6060 is not set
-# CONFIG_NET_DSA_MV88E6123_61_65 is not set
-# CONFIG_NET_DSA_MV88E6131 is not set
-# CONFIG_NET_DSA_MV88E6171 is not set
-# CONFIG_NET_DSA_MV88E6352 is not set
-# CONFIG_NET_DSA_MV88E6XXX is not set
-# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
-# CONFIG_NET_DSA_MV88E6XXX_PTP is not set
-# CONFIG_NET_DSA_QCA8K is not set
-# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set
-# CONFIG_NET_DSA_REALTEK_SMI is not set
-# CONFIG_NET_DSA_SJA1105 is not set
-# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set
-# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set
-# CONFIG_NET_DSA_TAG_8021Q is not set
-# CONFIG_NET_DSA_TAG_AR9331 is not set
-# CONFIG_NET_DSA_TAG_BRCM is not set
-# CONFIG_NET_DSA_TAG_BRCM_LEGACY is not set
-# CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set
-# CONFIG_NET_DSA_TAG_DSA is not set
-# CONFIG_NET_DSA_TAG_EDSA is not set
-# CONFIG_NET_DSA_TAG_GSWIP is not set
-# CONFIG_NET_DSA_TAG_HELLCREEK is not set
-# CONFIG_NET_DSA_TAG_KSZ is not set
-# CONFIG_NET_DSA_TAG_LAN9303 is not set
-# CONFIG_NET_DSA_TAG_MTK is not set
-# CONFIG_NET_DSA_TAG_OCELOT is not set
-# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set
-# CONFIG_NET_DSA_TAG_QCA is not set
-# CONFIG_NET_DSA_TAG_RTL4_A is not set
-# CONFIG_NET_DSA_TAG_SJA1105 is not set
-# CONFIG_NET_DSA_TAG_TRAILER is not set
-# CONFIG_NET_DSA_TAG_XRS700X is not set
-# CONFIG_NET_DSA_VITESSE_VSC73XX is not set
-# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set
-# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set
-# CONFIG_NET_DSA_XRS700X_I2C is not set
-# CONFIG_NET_DSA_XRS700X_MDIO is not set
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_EMATCH_CANID is not set
-# CONFIG_NET_EMATCH_CMP is not set
-# CONFIG_NET_EMATCH_IPT is not set
-# CONFIG_NET_EMATCH_META is not set
-# CONFIG_NET_EMATCH_NBYTE is not set
-CONFIG_NET_EMATCH_STACK=32
-# CONFIG_NET_EMATCH_TEXT is not set
-# CONFIG_NET_EMATCH_U32 is not set
-# CONFIG_NET_FAILOVER is not set
-# CONFIG_NET_FC is not set
-# CONFIG_NET_FOU is not set
-# CONFIG_NET_FOU_IP_TUNNELS is not set
-# CONFIG_NET_IFE is not set
-# CONFIG_NET_IPGRE is not set
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_NET_IPGRE_DEMUX is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPVTI is not set
-# CONFIG_NET_IP_TUNNEL is not set
-# CONFIG_NET_KEY is not set
-# CONFIG_NET_KEY_MIGRATE is not set
-# CONFIG_NET_L3_MASTER_DEV is not set
-# CONFIG_NET_MEDIATEK_STAR_EMAC is not set
-# CONFIG_NET_MPLS_GSO is not set
-# CONFIG_NET_NCSI is not set
-# CONFIG_NET_NSH is not set
-# CONFIG_NET_PACKET_ENGINE is not set
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_NET_PTP_CLASSIFY is not set
-CONFIG_NET_RX_BUSY_POLL=y
-# CONFIG_NET_SB1000 is not set
-CONFIG_NET_SCHED=y
-# CONFIG_NET_SCH_CAKE is not set
-# CONFIG_NET_SCH_CBS is not set
-# CONFIG_NET_SCH_CHOKE is not set
-# CONFIG_NET_SCH_CODEL is not set
-CONFIG_NET_SCH_DEFAULT=y
-# CONFIG_NET_SCH_DRR is not set
-# CONFIG_NET_SCH_ETF is not set
-# CONFIG_NET_SCH_ETS is not set
-CONFIG_NET_SCH_FIFO=y
-# CONFIG_NET_SCH_FQ is not set
-CONFIG_NET_SCH_FQ_CODEL=y
-# CONFIG_NET_SCH_FQ_PIE is not set
-# CONFIG_NET_SCH_GRED is not set
-# CONFIG_NET_SCH_HFSC is not set
-# CONFIG_NET_SCH_HHF is not set
-# CONFIG_NET_SCH_HTB is not set
-# CONFIG_NET_SCH_INGRESS is not set
-# CONFIG_NET_SCH_MQPRIO is not set
-# CONFIG_NET_SCH_MULTIQ is not set
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_PIE is not set
-# CONFIG_NET_SCH_PLUG is not set
-# CONFIG_NET_SCH_PRIO is not set
-# CONFIG_NET_SCH_QFQ is not set
-# CONFIG_NET_SCH_RED is not set
-# CONFIG_NET_SCH_SFB is not set
-# CONFIG_NET_SCH_SFQ is not set
-# CONFIG_NET_SCH_SKBPRIO is not set
-# CONFIG_NET_SCH_TAPRIO is not set
-# CONFIG_NET_SCH_TBF is not set
-# CONFIG_NET_SCH_TEQL is not set
-# CONFIG_NET_SCTPPROBE is not set
-# CONFIG_NET_SELFTESTS is not set
-CONFIG_NET_SOCK_MSG=y
-# CONFIG_NET_SWITCHDEV is not set
-# CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_TC_SKB_EXT is not set
-# CONFIG_NET_TEAM is not set
-# CONFIG_NET_TULIP is not set
-# CONFIG_NET_UDP_TUNNEL is not set
-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_LITEX is not set
-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_MICROSOFT is not set
-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_NET_VRF is not set
-# CONFIG_NET_XGENE is not set
-CONFIG_NEW_LEDS=y
-# CONFIG_NFC is not set
-# CONFIG_NFP is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V2 is not set
-# CONFIG_NFSD_V2_ACL is not set
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFS_ACL_SUPPORT is not set
-CONFIG_NFS_COMMON=y
-# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_FSCACHE is not set
-# CONFIG_NFS_SWAP is not set
-# CONFIG_NFS_V2 is not set
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_V4_1 is not set
-# CONFIG_NFTL is not set
-# CONFIG_NFT_BRIDGE_META is not set
-# CONFIG_NFT_BRIDGE_REJECT is not set
-# CONFIG_NFT_CONNLIMIT is not set
-# CONFIG_NFT_DUP_IPV4 is not set
-# CONFIG_NFT_DUP_IPV6 is not set
-# CONFIG_NFT_FIB_IPV4 is not set
-# CONFIG_NFT_FIB_IPV6 is not set
-# CONFIG_NFT_FIB_NETDEV is not set
-# CONFIG_NFT_FLOW_OFFLOAD is not set
-# CONFIG_NFT_OBJREF is not set
-# CONFIG_NFT_OSF is not set
-# CONFIG_NFT_REJECT_NETDEV is not set
-# CONFIG_NFT_RT is not set
-# CONFIG_NFT_SET_BITMAP is not set
-# CONFIG_NFT_SOCKET is not set
-# CONFIG_NFT_SYNPROXY is not set
-# CONFIG_NFT_TPROXY is not set
-# CONFIG_NFT_TUNNEL is not set
-# CONFIG_NFT_XFRM is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NF_CONNTRACK_AMANDA is not set
-# CONFIG_NF_CONNTRACK_BRIDGE is not set
-# CONFIG_NF_CONNTRACK_EVENTS is not set
-# CONFIG_NF_CONNTRACK_FTP is not set
-# CONFIG_NF_CONNTRACK_H323 is not set
-# CONFIG_NF_CONNTRACK_IRC is not set
-# CONFIG_NF_CONNTRACK_LABELS is not set
-# CONFIG_NF_CONNTRACK_MARK is not set
-# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
-# CONFIG_NF_CONNTRACK_PPTP is not set
-CONFIG_NF_CONNTRACK_PROCFS=y
-# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
-# CONFIG_NF_CONNTRACK_SANE is not set
-# CONFIG_NF_CONNTRACK_SECMARK is not set
-# CONFIG_NF_CONNTRACK_SIP is not set
-# CONFIG_NF_CONNTRACK_SNMP is not set
-# CONFIG_NF_CONNTRACK_TFTP is not set
-# CONFIG_NF_CONNTRACK_TIMEOUT is not set
-# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
-# CONFIG_NF_CONNTRACK_ZONES is not set
-# CONFIG_NF_CT_NETLINK is not set
-# CONFIG_NF_CT_NETLINK_HELPER is not set
-# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
-# CONFIG_NF_CT_PROTO_DCCP is not set
-# CONFIG_NF_CT_PROTO_GRE is not set
-# CONFIG_NF_CT_PROTO_SCTP is not set
-# CONFIG_NF_CT_PROTO_UDPLITE is not set
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_NF_DUP_IPV4 is not set
-# CONFIG_NF_DUP_IPV6 is not set
-# CONFIG_NF_FLOW_TABLE is not set
-# CONFIG_NF_FLOW_TABLE_PROCFS is not set
-# CONFIG_NF_LOG_ARP is not set
-# CONFIG_NF_LOG_BRIDGE is not set
-# CONFIG_NF_LOG_IPV4 is not set
-# CONFIG_NF_LOG_NETDEV is not set
-# CONFIG_NF_LOG_SYSLOG is not set
-# CONFIG_NF_NAT is not set
-# CONFIG_NF_NAT_AMANDA is not set
-# CONFIG_NF_NAT_FTP is not set
-# CONFIG_NF_NAT_H323 is not set
-# CONFIG_NF_NAT_IRC is not set
-# CONFIG_NF_NAT_NEEDED is not set
-# CONFIG_NF_NAT_PPTP is not set
-# CONFIG_NF_NAT_PROTO_GRE is not set
-# CONFIG_NF_NAT_SIP is not set
-# CONFIG_NF_NAT_SNMP_BASIC is not set
-# CONFIG_NF_NAT_TFTP is not set
-# CONFIG_NF_REJECT_IPV4 is not set
-# CONFIG_NF_REJECT_IPV6 is not set
-# CONFIG_NF_SOCKET_IPV4 is not set
-# CONFIG_NF_SOCKET_IPV6 is not set
-# CONFIG_NF_TABLES is not set
-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_NF_TABLES_SET is not set
-# CONFIG_NF_TPROXY_IPV4 is not set
-# CONFIG_NF_TPROXY_IPV6 is not set
-# CONFIG_NI65 is not set
-# CONFIG_NI903X_WDT is not set
-# CONFIG_NIC7018_WDT is not set
-# CONFIG_NILFS2_FS is not set
-# CONFIG_NIU is not set
-# CONFIG_NI_XGE_MANAGEMENT_ENET is not set
-CONFIG_NLATTR=y
-# CONFIG_NLMON is not set
-# CONFIG_NLM_XLP_BOARD is not set
-# CONFIG_NLM_XLR_BOARD is not set
-# CONFIG_NLS is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_MAC_CELTIC is not set
-# CONFIG_NLS_MAC_CENTEURO is not set
-# CONFIG_NLS_MAC_CROATIAN is not set
-# CONFIG_NLS_MAC_CYRILLIC is not set
-# CONFIG_NLS_MAC_GAELIC is not set
-# CONFIG_NLS_MAC_GREEK is not set
-# CONFIG_NLS_MAC_ICELAND is not set
-# CONFIG_NLS_MAC_INUIT is not set
-# CONFIG_NLS_MAC_ROMAN is not set
-# CONFIG_NLS_MAC_ROMANIAN is not set
-# CONFIG_NLS_MAC_TURKISH is not set
-# CONFIG_NLS_UTF8 is not set
-CONFIG_NMI_LOG_BUF_SHIFT=13
-# CONFIG_NOA1305 is not set
-# CONFIG_NOP_USB_XCEIV is not set
-# CONFIG_NORTEL_HERMES is not set
-# CONFIG_NOTIFIER_ERROR_INJECTION is not set
-# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set
-# CONFIG_NOZOMI is not set
-# CONFIG_NO_BOOTMEM is not set
-# CONFIG_NO_HZ is not set
-# CONFIG_NO_HZ_FULL is not set
-# CONFIG_NO_HZ_IDLE is not set
-# CONFIG_NS83820 is not set
-# CONFIG_NTB is not set
-# CONFIG_NTFS3_64BIT_CLUSTER is not set
-# CONFIG_NTFS3_FS is not set
-# CONFIG_NTFS3_FS_POSIX_ACL is not set
-# CONFIG_NTFS3_LZX_XPRESS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_NTP_PPS is not set
-# CONFIG_NULL_TTY is not set
-# CONFIG_NUMA is not set
-# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set
-# CONFIG_NVM is not set
-# CONFIG_NVMEM is not set
-# CONFIG_NVMEM_BCM_OCOTP is not set
-# CONFIG_NVMEM_IMX_OCOTP is not set
-# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
-# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
-# CONFIG_NVMEM_REBOOT_MODE is not set
-# CONFIG_NVMEM_RMEM is not set
-# CONFIG_NVMEM_SYSFS is not set
-# CONFIG_NVMEM_U_BOOT_ENV is not set
-# CONFIG_NVME_FC is not set
-# CONFIG_NVME_TARGET is not set
-# CONFIG_NVME_TCP is not set
-# CONFIG_NVRAM is not set
-# CONFIG_NV_TCO is not set
-# CONFIG_NXP_C45_TJA11XX_PHY is not set
-# CONFIG_NXP_STB220 is not set
-# CONFIG_NXP_STB225 is not set
-# CONFIG_NXP_TJA11XX_PHY is not set
-# CONFIG_N_GSM is not set
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_OBS600 is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_OCTEONTX2_AF is not set
-# CONFIG_OCTEONTX2_PF is not set
-# CONFIG_OF_OVERLAY is not set
-CONFIG_OF_RESERVED_MEM=y
-# CONFIG_OF_UNITTEST is not set
-# CONFIG_OID_REGISTRY is not set
-# CONFIG_OMAP2_DSS_DEBUG is not set
-# CONFIG_OMAP2_DSS_DEBUGFS is not set
-# CONFIG_OMAP2_DSS_SDI is not set
-# CONFIG_OMAP_OCP2SCP is not set
-# CONFIG_OMAP_USB2 is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_OPENVSWITCH is not set
-# CONFIG_OPROFILE is not set
-# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set
-# CONFIG_OPT3001 is not set
-CONFIG_OPTIMIZE_INLINING=y
-# CONFIG_ORANGEFS_FS is not set
-# CONFIG_ORION_WATCHDOG is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_OSNOISE_TRACER is not set
-CONFIG_OVERLAY_FS=y
-# CONFIG_OVERLAY_FS_INDEX is not set
-# CONFIG_OVERLAY_FS_METACOPY is not set
-CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
-# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
-CONFIG_OVERLAY_FS_XINO_AUTO=y
-# CONFIG_OWL_LOADER is not set
-# CONFIG_P54_COMMON is not set
-# CONFIG_PA12203001 is not set
-CONFIG_PACKET=y
-# CONFIG_PACKET_DIAG is not set
-# CONFIG_PACKING is not set
-# CONFIG_PAGE_EXTENSION is not set
-# CONFIG_PAGE_OWNER is not set
-# CONFIG_PAGE_POISONING is not set
-# CONFIG_PAGE_POOL is not set
-# CONFIG_PAGE_POOL_STATS is not set
-# CONFIG_PAGE_REPORTING is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_32KB is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_64KB is not set
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PALMAS_GPADC is not set
-# CONFIG_PANASONIC_LAPTOP is not set
-# CONFIG_PANEL is not set
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_PANIC_ON_OOPS_VALUE=1
-CONFIG_PANIC_TIMEOUT=1
-# CONFIG_PANTHERLORD_FF is not set
-# CONFIG_PARAVIRT is not set
-# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
-# CONFIG_PARPORT is not set
-# CONFIG_PARPORT_1284 is not set
-# CONFIG_PARPORT_AX88796 is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_PC is not set
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARASAN_CF is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_ATP867X is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CS5535 is not set
-# CONFIG_PATA_CS5536 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IMX is not set
-# CONFIG_PATA_ISAPNP is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_LEGACY is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OCTEON_CF is not set
-# CONFIG_PATA_OF_PLATFORM is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_PCMCIA is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_PLATFORM is not set
-# CONFIG_PATA_QDI is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RDC is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SCH is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_TOSHIBA is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-# CONFIG_PATA_WINBOND_VLB is not set
-# CONFIG_PC104 is not set
-# CONFIG_PC300TOO is not set
-# CONFIG_PCCARD is not set
-# CONFIG_PCH_DMA is not set
-# CONFIG_PCH_GBE is not set
-# CONFIG_PCH_PHUB is not set
-# CONFIG_PCI is not set
-# CONFIG_PCI200SYN is not set
-# CONFIG_PCIEAER is not set
-# CONFIG_PCIEAER_INJECT is not set
-# CONFIG_PCIEASPM is not set
-# CONFIG_PCIEPORTBUS is not set
-# CONFIG_PCIE_AL is not set
-# CONFIG_PCIE_ALTERA is not set
-# CONFIG_PCIE_ARMADA_8K is not set
-CONFIG_PCIE_BUS_DEFAULT=y
-# CONFIG_PCIE_BUS_PEER2PEER is not set
-# CONFIG_PCIE_BUS_PERFORMANCE is not set
-# CONFIG_PCIE_BUS_SAFE is not set
-# CONFIG_PCIE_BUS_TUNE_OFF is not set
-# CONFIG_PCIE_BW is not set
-# CONFIG_PCIE_CADENCE_HOST is not set
-# CONFIG_PCIE_CADENCE_PLAT_HOST is not set
-# CONFIG_PCIE_DPC is not set
-# CONFIG_PCIE_DW_PLAT is not set
-# CONFIG_PCIE_DW_PLAT_HOST is not set
-# CONFIG_PCIE_ECRC is not set
-# CONFIG_PCIE_IPROC is not set
-# CONFIG_PCIE_KIRIN is not set
-# CONFIG_PCIE_LAYERSCAPE_GEN4 is not set
-# CONFIG_PCIE_MEDIATEK_GEN3 is not set
-# CONFIG_PCIE_MICROCHIP_HOST is not set
-# CONFIG_PCIE_PTM is not set
-# CONFIG_PCIE_XILINX is not set
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_PCI_ATMEL is not set
-# CONFIG_PCI_CNB20LE_QUIRK is not set
-# CONFIG_PCI_DEBUG is not set
-# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
-# CONFIG_PCI_ENDPOINT is not set
-# CONFIG_PCI_ENDPOINT_TEST is not set
-# CONFIG_PCI_FTPCI100 is not set
-# CONFIG_PCI_HERMES is not set
-# CONFIG_PCI_HISI is not set
-# CONFIG_PCI_HOST_GENERIC is not set
-# CONFIG_PCI_HOST_THUNDER_ECAM is not set
-# CONFIG_PCI_HOST_THUNDER_PEM is not set
-# CONFIG_PCI_IOV is not set
-# CONFIG_PCI_J721E_HOST is not set
-# CONFIG_PCI_LAYERSCAPE is not set
-# CONFIG_PCI_MESON is not set
-# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_PASID is not set
-# CONFIG_PCI_PF_STUB is not set
-# CONFIG_PCI_PRI is not set
-CONFIG_PCI_QUIRKS=y
-# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
-# CONFIG_PCI_STUB is not set
-# CONFIG_PCI_SW_SWITCHTEC is not set
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCI_V3_SEMI is not set
-# CONFIG_PCI_XGENE is not set
-# CONFIG_PCMCIA is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_ATMEL is not set
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_SPECTRUM is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_PCMCIA_XIRCOM is not set
-# CONFIG_PCNET32 is not set
-# CONFIG_PCPU_DEV_REFCNT is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_PCS_XPCS is not set
-# CONFIG_PD6729 is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_PERCPU_STATS is not set
-# CONFIG_PERCPU_TEST is not set
-# CONFIG_PERF_EVENTS is not set
-# CONFIG_PERF_EVENTS_AMD_POWER is not set
-# CONFIG_PERSISTENT_KEYRINGS is not set
-# CONFIG_PHANTOM is not set
-# CONFIG_PHONET is not set
-# CONFIG_PHYLIB is not set
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-# CONFIG_PHY_CADENCE_DP is not set
-# CONFIG_PHY_CADENCE_DPHY is not set
-# CONFIG_PHY_CADENCE_SALVO is not set
-# CONFIG_PHY_CADENCE_SIERRA is not set
-# CONFIG_PHY_CADENCE_TORRENT is not set
-# CONFIG_PHY_CAN_TRANSCEIVER is not set
-# CONFIG_PHY_CPCAP_USB is not set
-# CONFIG_PHY_EXYNOS_DP_VIDEO is not set
-# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
-# CONFIG_PHY_FSL_IMX8MQ_USB is not set
-# CONFIG_PHY_INGENIC_USB is not set
-# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set
-# CONFIG_PHY_MAPPHONE_MDM6600 is not set
-# CONFIG_PHY_MIXEL_MIPI_DPHY is not set
-# CONFIG_PHY_MTK_HDMI is not set
-# CONFIG_PHY_MTK_MIPI_DSI is not set
-# CONFIG_PHY_MVEBU_CP110_UTMI is not set
-# CONFIG_PHY_OCELOT_SERDES is not set
-# CONFIG_PHY_PISTACHIO_USB is not set
-# CONFIG_PHY_PXA_28NM_HSIC is not set
-# CONFIG_PHY_PXA_28NM_USB2 is not set
-# CONFIG_PHY_QCOM_DWC3 is not set
-# CONFIG_PHY_QCOM_USB_HS is not set
-# CONFIG_PHY_QCOM_USB_HSIC is not set
-# CONFIG_PHY_SAMSUNG_USB2 is not set
-# CONFIG_PHY_TUSB1210 is not set
-# CONFIG_PHY_XGENE is not set
-# CONFIG_PI433 is not set
-# CONFIG_PID_IN_CONTEXTIDR is not set
-# CONFIG_PID_NS is not set
-CONFIG_PINCONF=y
-# CONFIG_PINCTRL is not set
-# CONFIG_PINCTRL_AMD is not set
-# CONFIG_PINCTRL_AXP209 is not set
-# CONFIG_PINCTRL_CEDARFORK is not set
-# CONFIG_PINCTRL_EXYNOS is not set
-# CONFIG_PINCTRL_EXYNOS5440 is not set
-# CONFIG_PINCTRL_ICELAKE is not set
-# CONFIG_PINCTRL_INGENIC is not set
-# CONFIG_PINCTRL_LPASS_LPI is not set
-# CONFIG_PINCTRL_MCP23S08 is not set
-# CONFIG_PINCTRL_MDM9607 is not set
-# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set
-# CONFIG_PINCTRL_MSM8953 is not set
-# CONFIG_PINCTRL_MSM8X74 is not set
-# CONFIG_PINCTRL_MT6779 is not set
-# CONFIG_PINCTRL_MT8167 is not set
-# CONFIG_PINCTRL_MT8192 is not set
-# CONFIG_PINCTRL_MT8195 is not set
-# CONFIG_PINCTRL_MT8365 is not set
-# CONFIG_PINCTRL_MTK_V2 is not set
-# CONFIG_PINCTRL_OCELOT is not set
-# CONFIG_PINCTRL_PISTACHIO is not set
-# CONFIG_PINCTRL_SC7280 is not set
-# CONFIG_PINCTRL_SC8180X is not set
-# CONFIG_PINCTRL_SDX55 is not set
-CONFIG_PINCTRL_SINGLE=y
-# CONFIG_PINCTRL_SM6115 is not set
-# CONFIG_PINCTRL_SM6125 is not set
-# CONFIG_PINCTRL_SM8350 is not set
-# CONFIG_PINCTRL_STMFX is not set
-# CONFIG_PINCTRL_SX150X is not set
-# CONFIG_PING is not set
-CONFIG_PINMUX=y
-# CONFIG_PKCS7_MESSAGE_PARSER is not set
-# CONFIG_PL310_ERRATA_588369 is not set
-# CONFIG_PL310_ERRATA_727915 is not set
-# CONFIG_PL310_ERRATA_753970 is not set
-# CONFIG_PL310_ERRATA_769419 is not set
-# CONFIG_PL320_MBOX is not set
-# CONFIG_PL330_DMA is not set
-# CONFIG_PLATFORM_MHU is not set
-# CONFIG_PLAT_SPEAR is not set
-# CONFIG_PLIP is not set
-# CONFIG_PLX_DMA is not set
-# CONFIG_PLX_HERMES is not set
-# CONFIG_PM is not set
-# CONFIG_PMBUS is not set
-# CONFIG_PMC_MSP is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PMS7003 is not set
-# CONFIG_PM_AUTOSLEEP is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_DEVFREQ is not set
-# CONFIG_PM_WAKELOCKS is not set
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_POSIX_TIMERS=y
-# CONFIG_POWERCAP is not set
-# CONFIG_POWER_AVS is not set
-# CONFIG_POWER_RESET is not set
-# CONFIG_POWER_RESET_BRCMKONA is not set
-# CONFIG_POWER_RESET_BRCMSTB is not set
-# CONFIG_POWER_RESET_GPIO is not set
-# CONFIG_POWER_RESET_GPIO_RESTART is not set
-# CONFIG_POWER_RESET_LINKSTATION is not set
-# CONFIG_POWER_RESET_LTC2952 is not set
-# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set
-# CONFIG_POWER_RESET_QNAP is not set
-# CONFIG_POWER_RESET_REGULATOR is not set
-# CONFIG_POWER_RESET_RESTART is not set
-# CONFIG_POWER_RESET_SYSCON is not set
-# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
-# CONFIG_POWER_RESET_VERSATILE is not set
-# CONFIG_POWER_RESET_XGENE is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_POWER_SUPPLY_HWMON is not set
-# CONFIG_PPC4xx_GPIO is not set
-# CONFIG_PPC_16K_PAGES is not set
-# CONFIG_PPC_256K_PAGES is not set
-CONFIG_PPC_4K_PAGES=y
-# CONFIG_PPC_64K_PAGES is not set
-# CONFIG_PPC_DISABLE_WERROR is not set
-# CONFIG_PPC_EMULATED_STATS is not set
-# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set
-# CONFIG_PPC_QUEUED_SPINLOCKS is not set
-# CONFIG_PPP is not set
-# CONFIG_PPPOATM is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPPOL2TP is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_FILTER=y
-# CONFIG_PPP_MPPE is not set
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPS is not set
-# CONFIG_PPS_CLIENT_GPIO is not set
-# CONFIG_PPS_CLIENT_KTIMER is not set
-# CONFIG_PPS_CLIENT_LDISC is not set
-# CONFIG_PPS_CLIENT_PARPORT is not set
-# CONFIG_PPS_DEBUG is not set
-# CONFIG_PPTP is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_PREEMPTIRQ_DELAY_TEST is not set
-# CONFIG_PREEMPTIRQ_EVENTS is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PRESTERA is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_PRIME_NUMBERS is not set
-CONFIG_PRINTK=y
-# CONFIG_PRINTK_CALLER is not set
-# CONFIG_PRINTK_INDEX is not set
-CONFIG_PRINTK_NMI=y
-CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
-# CONFIG_PRINTK_TIME is not set
-CONFIG_PRINT_STACK_DEPTH=64
-# CONFIG_PRISM2_USB is not set
-# CONFIG_PRISM54 is not set
-# CONFIG_PROC_CHILDREN is not set
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-# CONFIG_PROC_PAGE_MONITOR is not set
-# CONFIG_PROC_STRIPPED is not set
-CONFIG_PROC_SYSCTL=y
-# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILING is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_PROVE_RAW_LOCK_NESTING is not set
-# CONFIG_PROVE_RCU is not set
-# CONFIG_PROVE_RCU_LIST is not set
-# CONFIG_PROVE_RCU_REPEATEDLY is not set
-# CONFIG_PSAMPLE is not set
-# CONFIG_PSB6970_PHY is not set
-# CONFIG_PSI is not set
-# CONFIG_PSTORE is not set
-# CONFIG_PSTORE_842_COMPRESS is not set
-# CONFIG_PSTORE_BLK is not set
-# CONFIG_PSTORE_COMPRESS is not set
-# CONFIG_PSTORE_CONSOLE is not set
-CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
-# CONFIG_PSTORE_DEFLATE_COMPRESS is not set
-# CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT is not set
-# CONFIG_PSTORE_FTRACE is not set
-# CONFIG_PSTORE_LZ4HC_COMPRESS is not set
-# CONFIG_PSTORE_LZ4_COMPRESS is not set
-# CONFIG_PSTORE_LZO_COMPRESS is not set
-# CONFIG_PSTORE_PMSG is not set
-# CONFIG_PSTORE_RAM is not set
-# CONFIG_PSTORE_ZSTD_COMPRESS is not set
-# CONFIG_PTDUMP_DEBUGFS is not set
-# CONFIG_PTP_1588_CLOCK is not set
-# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set
-# CONFIG_PTP_1588_CLOCK_IDTCM is not set
-# CONFIG_PTP_1588_CLOCK_IXP46X is not set
-# CONFIG_PTP_1588_CLOCK_KVM is not set
-# CONFIG_PTP_1588_CLOCK_OCP is not set
-# CONFIG_PTP_1588_CLOCK_PCH is not set
-# CONFIG_PTP_1588_CLOCK_VMW is not set
-# CONFIG_PUBLIC_KEY_ALGO_RSA is not set
-# CONFIG_PVPANIC is not set
-# CONFIG_PWM is not set
-# CONFIG_PWM_ATMEL_TCB is not set
-# CONFIG_PWM_DEBUG is not set
-# CONFIG_PWM_DWC is not set
-# CONFIG_PWM_FSL_FTM is not set
-# CONFIG_PWM_IMG is not set
-# CONFIG_PWM_JZ4740 is not set
-# CONFIG_PWM_MEDIATEK is not set
-# CONFIG_PWM_PCA9685 is not set
-# CONFIG_PWM_RASPBERRYPI_POE is not set
-CONFIG_PWRSEQ_EMMC=y
-# CONFIG_PWRSEQ_SD8787 is not set
-CONFIG_PWRSEQ_SIMPLE=y
-# CONFIG_QCA7000 is not set
-# CONFIG_QCA7000_SPI is not set
-# CONFIG_QCA7000_UART is not set
-# CONFIG_QCOM_A7PLL is not set
-# CONFIG_QCOM_EMAC is not set
-# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
-# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
-# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
-# CONFIG_QCOM_GPI_DMA is not set
-# CONFIG_QCOM_HIDMA is not set
-# CONFIG_QCOM_HIDMA_MGMT is not set
-# CONFIG_QCOM_LMH is not set
-# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
-# CONFIG_QCOM_SPMI_ADC5 is not set
-# CONFIG_QCOM_SPMI_ADC_TM5 is not set
-# CONFIG_QCOM_SPMI_IADC is not set
-# CONFIG_QCOM_SPMI_TEMP_ALARM is not set
-# CONFIG_QCOM_SPMI_VADC is not set
-# CONFIG_QED is not set
-# CONFIG_QFMT_V1 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_QLCNIC is not set
-# CONFIG_QLGE is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX6FS_FS is not set
-# CONFIG_QORIQ_CPUFREQ is not set
-# CONFIG_QORIQ_THERMAL is not set
-# CONFIG_QRTR is not set
-# CONFIG_QRTR_MHI is not set
-# CONFIG_QRTR_TUN is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_QUEUED_LOCK_STAT is not set
-# CONFIG_QUICC_ENGINE is not set
-# CONFIG_QUOTA is not set
-# CONFIG_QUOTACTL is not set
-# CONFIG_QUOTA_DEBUG is not set
-# CONFIG_QUOTA_NETLINK_INTERFACE is not set
-# CONFIG_R3964 is not set
-# CONFIG_R6040 is not set
-# CONFIG_R8169 is not set
-# CONFIG_R8188EU is not set
-# CONFIG_R8712U is not set
-# CONFIG_R8723AU is not set
-# CONFIG_RADIO_ADAPTERS is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-# CONFIG_RAID6_PQ_BENCHMARK is not set
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_RALINK is not set
-# CONFIG_RANDOM32_SELFTEST is not set
-# CONFIG_RANDOMIZE_BASE is not set
-# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
-CONFIG_RANDOM_TRUST_BOOTLOADER=y
-CONFIG_RANDOM_TRUST_CPU=y
-# CONFIG_RAPIDIO is not set
-# CONFIG_RAS is not set
-# CONFIG_RBTREE_TEST is not set
-# CONFIG_RCU_BOOST is not set
-CONFIG_RCU_CPU_STALL_TIMEOUT=60
-# CONFIG_RCU_EQS_DEBUG is not set
-# CONFIG_RCU_EXPEDITE_BOOT is not set
-# CONFIG_RCU_EXPERT is not set
-CONFIG_RCU_KTHREAD_PRIO=0
-CONFIG_RCU_NEED_SEGCBLIST=y
-# CONFIG_RCU_PERF_TEST is not set
-# CONFIG_RCU_REF_SCALE_TEST is not set
-# CONFIG_RCU_SCALE_TEST is not set
-CONFIG_RCU_STALL_COMMON=y
-# CONFIG_RCU_STRICT_GRACE_PERIOD is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3
-# CONFIG_RCU_TRACE is not set
-# CONFIG_RC_ATI_REMOTE is not set
-# CONFIG_RC_CORE is not set
-# CONFIG_RC_DECODERS is not set
-# CONFIG_RC_LOOPBACK is not set
-# CONFIG_RC_MAP is not set
-# CONFIG_RC_XBOX_DVD is not set
-# CONFIG_RDS is not set
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_GZIP is not set
-# CONFIG_RD_LZ4 is not set
-# CONFIG_RD_LZMA is not set
-# CONFIG_RD_LZO is not set
-# CONFIG_RD_XZ is not set
-# CONFIG_RD_ZSTD is not set
-# CONFIG_READABLE_ASM is not set
-# CONFIG_READ_ONLY_THP_FOR_FS is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_REDWOOD is not set
-# CONFIG_REED_SOLOMON is not set
-# CONFIG_REED_SOLOMON_DEC8 is not set
-# CONFIG_REED_SOLOMON_ENC8 is not set
-# CONFIG_REED_SOLOMON_TEST is not set
-# CONFIG_REGMAP is not set
-# CONFIG_REGMAP_I2C is not set
-# CONFIG_REGMAP_MMIO is not set
-# CONFIG_REGMAP_SPI is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_88PG86X is not set
-# CONFIG_REGULATOR_ACT8865 is not set
-# CONFIG_REGULATOR_AD5398 is not set
-# CONFIG_REGULATOR_ANATOP is not set
-# CONFIG_REGULATOR_DA9121 is not set
-# CONFIG_REGULATOR_DA9210 is not set
-# CONFIG_REGULATOR_DA9211 is not set
-# CONFIG_REGULATOR_DEBUG is not set
-# CONFIG_REGULATOR_FAN53555 is not set
-# CONFIG_REGULATOR_FAN53880 is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_GPIO is not set
-# CONFIG_REGULATOR_ISL6271A is not set
-# CONFIG_REGULATOR_ISL9305 is not set
-# CONFIG_REGULATOR_LP3971 is not set
-# CONFIG_REGULATOR_LP3972 is not set
-# CONFIG_REGULATOR_LP872X is not set
-# CONFIG_REGULATOR_LP8755 is not set
-# CONFIG_REGULATOR_LTC3589 is not set
-# CONFIG_REGULATOR_LTC3676 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_MAX77620 is not set
-# CONFIG_REGULATOR_MAX77826 is not set
-# CONFIG_REGULATOR_MAX8649 is not set
-# CONFIG_REGULATOR_MAX8660 is not set
-# CONFIG_REGULATOR_MAX8893 is not set
-# CONFIG_REGULATOR_MAX8952 is not set
-# CONFIG_REGULATOR_MAX8973 is not set
-# CONFIG_REGULATOR_MCP16502 is not set
-# CONFIG_REGULATOR_MP5416 is not set
-# CONFIG_REGULATOR_MP8859 is not set
-# CONFIG_REGULATOR_MP886X is not set
-# CONFIG_REGULATOR_MPQ7920 is not set
-# CONFIG_REGULATOR_MT6311 is not set
-# CONFIG_REGULATOR_MT6315 is not set
-# CONFIG_REGULATOR_MT6359 is not set
-# CONFIG_REGULATOR_PCA9450 is not set
-# CONFIG_REGULATOR_PF8X00 is not set
-# CONFIG_REGULATOR_PFUZE100 is not set
-# CONFIG_REGULATOR_PV88060 is not set
-# CONFIG_REGULATOR_PV88080 is not set
-# CONFIG_REGULATOR_PV88090 is not set
-# CONFIG_REGULATOR_PWM is not set
-# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set
-# CONFIG_REGULATOR_RT4801 is not set
-# CONFIG_REGULATOR_RT6160 is not set
-# CONFIG_REGULATOR_RT6245 is not set
-# CONFIG_REGULATOR_RTMV20 is not set
-# CONFIG_REGULATOR_RTQ2134 is not set
-# CONFIG_REGULATOR_RTQ6752 is not set
-# CONFIG_REGULATOR_SLG51000 is not set
-# CONFIG_REGULATOR_SY8106A is not set
-# CONFIG_REGULATOR_SY8824X is not set
-# CONFIG_REGULATOR_SY8827N is not set
-# CONFIG_REGULATOR_TI_ABB is not set
-# CONFIG_REGULATOR_TPS51632 is not set
-# CONFIG_REGULATOR_TPS62360 is not set
-# CONFIG_REGULATOR_TPS65023 is not set
-# CONFIG_REGULATOR_TPS6507X is not set
-# CONFIG_REGULATOR_TPS65132 is not set
-# CONFIG_REGULATOR_TPS6524X is not set
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_REGULATOR_VCTRL is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_FS_POSIX_ACL is not set
-# CONFIG_REISERFS_FS_SECURITY is not set
-CONFIG_REISERFS_FS_XATTR=y
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_RELAY is not set
-# CONFIG_RELOCATABLE is not set
-# CONFIG_REMOTEPROC is not set
-# CONFIG_RENESAS_PHY is not set
-# CONFIG_RESET_ATH79 is not set
-# CONFIG_RESET_BERLIN is not set
-# CONFIG_RESET_BRCMSTB_RESCAL is not set
-# CONFIG_RESET_CONTROLLER is not set
-# CONFIG_RESET_IMX7 is not set
-# CONFIG_RESET_INTEL_GW is not set
-# CONFIG_RESET_LANTIQ is not set
-# CONFIG_RESET_LPC18XX is not set
-# CONFIG_RESET_MESON is not set
-# CONFIG_RESET_PISTACHIO is not set
-# CONFIG_RESET_SOCFPGA is not set
-# CONFIG_RESET_STM32 is not set
-# CONFIG_RESET_SUNXI is not set
-# CONFIG_RESET_TEGRA_BPMP is not set
-# CONFIG_RESET_TI_SYSCON is not set
-# CONFIG_RESET_ZYNQ is not set
-# CONFIG_RFD77402 is not set
-# CONFIG_RFD_FTL is not set
-CONFIG_RFKILL=y
-# CONFIG_RFKILL_FULL is not set
-# CONFIG_RFKILL_GPIO is not set
-# CONFIG_RFKILL_INPUT is not set
-# CONFIG_RFKILL_LEDS is not set
-# CONFIG_RFKILL_REGULATOR is not set
-# CONFIG_RING_BUFFER_BENCHMARK is not set
-# CONFIG_RING_BUFFER_STARTUP_TEST is not set
-# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set
-# CONFIG_RMI4_CORE is not set
-# CONFIG_RMNET is not set
-# CONFIG_ROCKCHIP_PHY is not set
-# CONFIG_ROCKER is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_ROSE is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
-# CONFIG_RPMSG_VIRTIO is not set
-# CONFIG_RPMSG_WWAN_CTRL is not set
-# CONFIG_RPR0521 is not set
-# CONFIG_RSEQ is not set
-# CONFIG_RT2X00 is not set
-# CONFIG_RTC_CLASS is not set
-# CONFIG_RTC_DEBUG is not set
-# CONFIG_RTC_DRV_ABB5ZES3 is not set
-# CONFIG_RTC_DRV_ABEOZ9 is not set
-# CONFIG_RTC_DRV_ABX80X is not set
-# CONFIG_RTC_DRV_ARMADA38X is not set
-# CONFIG_RTC_DRV_AU1XXX is not set
-# CONFIG_RTC_DRV_BQ32K is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-# CONFIG_RTC_DRV_CADENCE is not set
-CONFIG_RTC_DRV_CMOS=y
-# CONFIG_RTC_DRV_DS1286 is not set
-# CONFIG_RTC_DRV_DS1302 is not set
-# CONFIG_RTC_DRV_DS1305 is not set
-# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1307_CENTURY is not set
-# CONFIG_RTC_DRV_DS1307_HWMON is not set
-# CONFIG_RTC_DRV_DS1343 is not set
-# CONFIG_RTC_DRV_DS1347 is not set
-# CONFIG_RTC_DRV_DS1374 is not set
-# CONFIG_RTC_DRV_DS1390 is not set
-# CONFIG_RTC_DRV_DS1511 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1685_FAMILY is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_DS2404 is not set
-# CONFIG_RTC_DRV_DS3232 is not set
-# CONFIG_RTC_DRV_DS3234 is not set
-# CONFIG_RTC_DRV_EM3027 is not set
-# CONFIG_RTC_DRV_EP93XX is not set
-# CONFIG_RTC_DRV_FM3130 is not set
-# CONFIG_RTC_DRV_FTRTC010 is not set
-# CONFIG_RTC_DRV_GENERIC is not set
-# CONFIG_RTC_DRV_GOLDFISH is not set
-# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
-# CONFIG_RTC_DRV_HYM8563 is not set
-# CONFIG_RTC_DRV_ISL12022 is not set
-# CONFIG_RTC_DRV_ISL12026 is not set
-# CONFIG_RTC_DRV_ISL12057 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
-# CONFIG_RTC_DRV_JZ4740 is not set
-# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_M41T93 is not set
-# CONFIG_RTC_DRV_M41T94 is not set
-# CONFIG_RTC_DRV_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_MAX6900 is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_MAX6916 is not set
-# CONFIG_RTC_DRV_MAX77686 is not set
-# CONFIG_RTC_DRV_MCP795 is not set
-# CONFIG_RTC_DRV_MOXART is not set
-# CONFIG_RTC_DRV_MPC5121 is not set
-# CONFIG_RTC_DRV_MSM6242 is not set
-# CONFIG_RTC_DRV_MT2712 is not set
-# CONFIG_RTC_DRV_OMAP is not set
-# CONFIG_RTC_DRV_PCF2123 is not set
-# CONFIG_RTC_DRV_PCF2127 is not set
-# CONFIG_RTC_DRV_PCF85063 is not set
-# CONFIG_RTC_DRV_PCF8523 is not set
-# CONFIG_RTC_DRV_PCF85363 is not set
-# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
-# CONFIG_RTC_DRV_PL030 is not set
-# CONFIG_RTC_DRV_PL031 is not set
-# CONFIG_RTC_DRV_PS3 is not set
-# CONFIG_RTC_DRV_PT7C4338 is not set
-# CONFIG_RTC_DRV_R7301 is not set
-# CONFIG_RTC_DRV_R9701 is not set
-# CONFIG_RTC_DRV_RP5C01 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_RTC7301 is not set
-# CONFIG_RTC_DRV_RV3028 is not set
-# CONFIG_RTC_DRV_RV3029C2 is not set
-# CONFIG_RTC_DRV_RV3032 is not set
-# CONFIG_RTC_DRV_RV8803 is not set
-# CONFIG_RTC_DRV_RX4581 is not set
-# CONFIG_RTC_DRV_RX6110 is not set
-# CONFIG_RTC_DRV_RX8010 is not set
-# CONFIG_RTC_DRV_RX8025 is not set
-# CONFIG_RTC_DRV_RX8581 is not set
-# CONFIG_RTC_DRV_S35390A is not set
-# CONFIG_RTC_DRV_SD3078 is not set
-# CONFIG_RTC_DRV_SNVS is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_SUN6I is not set
-# CONFIG_RTC_DRV_TEGRA is not set
-# CONFIG_RTC_DRV_TEST is not set
-# CONFIG_RTC_DRV_V3020 is not set
-# CONFIG_RTC_DRV_X1205 is not set
-# CONFIG_RTC_DRV_XGENE is not set
-# CONFIG_RTC_DRV_ZYNQMP is not set
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-CONFIG_RTC_INTF_DEV=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_NVMEM is not set
-CONFIG_RTC_SYSTOHC=y
-CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
-# CONFIG_RTL8180 is not set
-# CONFIG_RTL8187 is not set
-# CONFIG_RTL8192E is not set
-# CONFIG_RTL8192U is not set
-# CONFIG_RTL8306_PHY is not set
-# CONFIG_RTL8366RB_PHY is not set
-# CONFIG_RTL8366S_PHY is not set
-# CONFIG_RTL8366_SMI is not set
-# CONFIG_RTL8366_SMI_DEBUG_FS is not set
-# CONFIG_RTL8367B_PHY is not set
-# CONFIG_RTL8367_PHY is not set
-# CONFIG_RTLLIB is not set
-# CONFIG_RTL_CARDS is not set
-# CONFIG_RTS5208 is not set
-CONFIG_RT_MUTEXES=y
-# CONFIG_RUNTIME_DEBUG is not set
-CONFIG_RUNTIME_TESTING_MENU=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_RXKAD=y
-# CONFIG_S2IO is not set
-# CONFIG_SAMPLES is not set
-# CONFIG_SAMSUNG_LAPTOP is not set
-# CONFIG_SATA_ACARD_AHCI is not set
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_AHCI_PLATFORM is not set
-# CONFIG_SATA_DWC is not set
-# CONFIG_SATA_DWC_DEBUG is not set
-# CONFIG_SATA_DWC_OLD_DMA is not set
-# CONFIG_SATA_FSL is not set
-# CONFIG_SATA_HIGHBANK is not set
-# CONFIG_SATA_HOST is not set
-# CONFIG_SATA_INIC162X is not set
-CONFIG_SATA_MOBILE_LPM_POLICY=0
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_SATA_PMP is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_RCAR is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_SVW is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SBC_FITPC2_WATCHDOG is not set
-CONFIG_SBITMAP=y
-# CONFIG_SC92031 is not set
-# CONFIG_SCA3000 is not set
-# CONFIG_SCA3300 is not set
-# CONFIG_SCACHE_DEBUGFS is not set
-# CONFIG_SCC is not set
-# CONFIG_SCD30_CORE is not set
-# CONFIG_SCF_TORTURE_TEST is not set
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_SCHED_AUTOGROUP is not set
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_SCHED_HRTICK=y
-# CONFIG_SCHED_MC is not set
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-# CONFIG_SCHED_SMT is not set
-CONFIG_SCHED_STACK_END_CHECK=y
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_SCR24X is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_3W_SAS is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_SCSI_BFA_FC is not set
-# CONFIG_SCSI_BNX2X_FCOE is not set
-# CONFIG_SCSI_BNX2_ISCSI is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CHELSIO_FCOE is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_CXGB3_ISCSI is not set
-# CONFIG_SCSI_CXGB4_ISCSI is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_ESAS2R is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_FDOMAIN_PCI is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_HISI_SAS is not set
-# CONFIG_SCSI_HPSA is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_ISCI is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
-# CONFIG_SCSI_LPFC is not set
-CONFIG_SCSI_MOD=y
-# CONFIG_SCSI_MPI3MR is not set
-# CONFIG_SCSI_MPT2SAS is not set
-# CONFIG_SCSI_MPT3SAS is not set
-# CONFIG_SCSI_MQ_DEFAULT is not set
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_MVSAS_DEBUG is not set
-# CONFIG_SCSI_MVUMI is not set
-# CONFIG_SCSI_MYRB is not set
-# CONFIG_SCSI_MYRS is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PM8001 is not set
-# CONFIG_SCSI_PMCRAID is not set
-CONFIG_SCSI_PROC_FS=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-# CONFIG_SCSI_SMARTPQI is not set
-# CONFIG_SCSI_SNIC is not set
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_UFSHCD is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_VIRTIO is not set
-# CONFIG_SCSI_WD719X is not set
-# CONFIG_SC_CAMCC_7180 is not set
-# CONFIG_SC_DISPCC_7280 is not set
-# CONFIG_SC_GCC_7280 is not set
-# CONFIG_SC_GCC_8180X is not set
-# CONFIG_SC_GPUCC_7280 is not set
-# CONFIG_SC_VIDEOCC_7280 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_SDIO_UART is not set
-# CONFIG_SDM_GPUCC_660 is not set
-# CONFIG_SDM_MMCC_660 is not set
-# CONFIG_SDR_MAX2175 is not set
-# CONFIG_SDR_PLATFORM_DRIVERS is not set
-# CONFIG_SDX_GCC_55 is not set
-# CONFIG_SD_ADC_MODULATOR is not set
-# CONFIG_SECCOMP is not set
-# CONFIG_SECCOMP_CACHE_DEBUG is not set
-CONFIG_SECTION_MISMATCH_WARN_ONLY=y
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_APPARMOR is not set
-CONFIG_SECURITY_DMESG_RESTRICT=y
-# CONFIG_SECURITY_LANDLOCK is not set
-# CONFIG_SECURITY_LOADPIN is not set
-# CONFIG_SECURITY_LOCKDOWN_LSM is not set
-# CONFIG_SECURITY_NETWORK_XFRM is not set
-# CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_SAFESETID is not set
-# CONFIG_SECURITY_SELINUX_AVC_STATS is not set
-# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set
-CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0
-# CONFIG_SECURITY_SELINUX_DEVELOP is not set
-# CONFIG_SECURITY_SELINUX_DISABLE is not set
-# CONFIG_SECURITY_SMACK is not set
-# CONFIG_SECURITY_TOMOYO is not set
-# CONFIG_SECURITY_YAMA is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_SENSIRION_SGP30 is not set
-# CONFIG_SENSIRION_SGP40 is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
-# CONFIG_SENSORS_ACPI_POWER is not set
-# CONFIG_SENSORS_AD7314 is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADC128D818 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM1177 is not set
-# CONFIG_SENSORS_ADM1266 is not set
-# CONFIG_SENSORS_ADM1275 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADS1015 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_ADS7871 is not set
-# CONFIG_SENSORS_ADT7310 is not set
-# CONFIG_SENSORS_ADT7410 is not set
-# CONFIG_SENSORS_ADT7411 is not set
-# CONFIG_SENSORS_ADT7462 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7475 is not set
-# CONFIG_SENSORS_AHT10 is not set
-# CONFIG_SENSORS_AMC6821 is not set
-# CONFIG_SENSORS_APDS990X is not set
-# CONFIG_SENSORS_APPLESMC is not set
-# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set
-# CONFIG_SENSORS_AS370 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ASC7621 is not set
-# CONFIG_SENSORS_ASPEED is not set
-# CONFIG_SENSORS_ATK0110 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_AXI_FAN_CONTROL is not set
-# CONFIG_SENSORS_BEL_PFE is not set
-# CONFIG_SENSORS_BH1770 is not set
-# CONFIG_SENSORS_BH1780 is not set
-# CONFIG_SENSORS_BPA_RS600 is not set
-# CONFIG_SENSORS_CORETEMP is not set
-# CONFIG_SENSORS_CORSAIR_CPRO is not set
-# CONFIG_SENSORS_CORSAIR_PSU is not set
-# CONFIG_SENSORS_DELL_SMM is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_DPS920AB is not set
-# CONFIG_SENSORS_DRIVETEMP is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_DS620 is not set
-# CONFIG_SENSORS_EMC1403 is not set
-# CONFIG_SENSORS_EMC2103 is not set
-# CONFIG_SENSORS_EMC2305 is not set
-# CONFIG_SENSORS_EMC6W201 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_FAM15H_POWER is not set
-# CONFIG_SENSORS_FSCHMD is not set
-# CONFIG_SENSORS_FSP_3Y is not set
-# CONFIG_SENSORS_FTSTEUTATES is not set
-# CONFIG_SENSORS_G760A is not set
-# CONFIG_SENSORS_G762 is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_GPIO_FAN is not set
-# CONFIG_SENSORS_GSC is not set
-# CONFIG_SENSORS_HDAPS is not set
-# CONFIG_SENSORS_HIH6130 is not set
-# CONFIG_SENSORS_HMC5843 is not set
-# CONFIG_SENSORS_HMC5843_I2C is not set
-# CONFIG_SENSORS_HMC5843_SPI is not set
-# CONFIG_SENSORS_HTU21 is not set
-# CONFIG_SENSORS_I5500 is not set
-# CONFIG_SENSORS_I5K_AMB is not set
-# CONFIG_SENSORS_IBM_CFFPS is not set
-# CONFIG_SENSORS_IIO_HWMON is not set
-# CONFIG_SENSORS_INA209 is not set
-# CONFIG_SENSORS_INA2XX is not set
-# CONFIG_SENSORS_INA3221 is not set
-# CONFIG_SENSORS_INSPUR_IPSPS is not set
-# CONFIG_SENSORS_IR35221 is not set
-# CONFIG_SENSORS_IR36021 is not set
-# CONFIG_SENSORS_IR38064 is not set
-# CONFIG_SENSORS_IRPS5401 is not set
-# CONFIG_SENSORS_ISL29018 is not set
-# CONFIG_SENSORS_ISL29028 is not set
-# CONFIG_SENSORS_ISL68137 is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_JC42 is not set
-# CONFIG_SENSORS_K10TEMP is not set
-# CONFIG_SENSORS_K8TEMP is not set
-# CONFIG_SENSORS_LINEAGE is not set
-# CONFIG_SENSORS_LIS3LV02D is not set
-# CONFIG_SENSORS_LIS3_I2C is not set
-# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_SENSORS_LM25066 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM73 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_LM95234 is not set
-# CONFIG_SENSORS_LM95241 is not set
-# CONFIG_SENSORS_LM95245 is not set
-# CONFIG_SENSORS_LTC2945 is not set
-# CONFIG_SENSORS_LTC2947_I2C is not set
-# CONFIG_SENSORS_LTC2947_SPI is not set
-# CONFIG_SENSORS_LTC2978 is not set
-# CONFIG_SENSORS_LTC2990 is not set
-# CONFIG_SENSORS_LTC2992 is not set
-# CONFIG_SENSORS_LTC3815 is not set
-# CONFIG_SENSORS_LTC4151 is not set
-# CONFIG_SENSORS_LTC4215 is not set
-# CONFIG_SENSORS_LTC4222 is not set
-# CONFIG_SENSORS_LTC4245 is not set
-# CONFIG_SENSORS_LTC4260 is not set
-# CONFIG_SENSORS_LTC4261 is not set
-# CONFIG_SENSORS_LTQ_CPUTEMP is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX127 is not set
-# CONFIG_SENSORS_MAX15301 is not set
-# CONFIG_SENSORS_MAX16064 is not set
-# CONFIG_SENSORS_MAX16065 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX16601 is not set
-# CONFIG_SENSORS_MAX1668 is not set
-# CONFIG_SENSORS_MAX197 is not set
-# CONFIG_SENSORS_MAX20730 is not set
-# CONFIG_SENSORS_MAX20751 is not set
-# CONFIG_SENSORS_MAX31722 is not set
-# CONFIG_SENSORS_MAX31730 is not set
-# CONFIG_SENSORS_MAX31785 is not set
-# CONFIG_SENSORS_MAX31790 is not set
-# CONFIG_SENSORS_MAX34440 is not set
-# CONFIG_SENSORS_MAX6621 is not set
-# CONFIG_SENSORS_MAX6639 is not set
-# CONFIG_SENSORS_MAX6642 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_MAX6697 is not set
-# CONFIG_SENSORS_MAX8688 is not set
-# CONFIG_SENSORS_MCP3021 is not set
-# CONFIG_SENSORS_MP2888 is not set
-# CONFIG_SENSORS_MP2975 is not set
-# CONFIG_SENSORS_MR75203 is not set
-# CONFIG_SENSORS_NCT6683 is not set
-# CONFIG_SENSORS_NCT6775 is not set
-# CONFIG_SENSORS_NCT7802 is not set
-# CONFIG_SENSORS_NCT7904 is not set
-# CONFIG_SENSORS_NPCM7XX is not set
-# CONFIG_SENSORS_NSA320 is not set
-# CONFIG_SENSORS_NTC_THERMISTOR is not set
-# CONFIG_SENSORS_NZXT_KRAKEN2 is not set
-# CONFIG_SENSORS_OCC_P8_I2C is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_PIM4328 is not set
-# CONFIG_SENSORS_PM6764TR is not set
-# CONFIG_SENSORS_PMBUS is not set
-# CONFIG_SENSORS_POWR1220 is not set
-# CONFIG_SENSORS_PWM_FAN is not set
-# CONFIG_SENSORS_PXE1610 is not set
-# CONFIG_SENSORS_Q54SJ108A2 is not set
-# CONFIG_SENSORS_RM3100_I2C is not set
-# CONFIG_SENSORS_RM3100_SPI is not set
-# CONFIG_SENSORS_SBRMI is not set
-# CONFIG_SENSORS_SBTSI is not set
-# CONFIG_SENSORS_SCH5627 is not set
-# CONFIG_SENSORS_SCH5636 is not set
-# CONFIG_SENSORS_SCH56XX_COMMON is not set
-# CONFIG_SENSORS_SHT15 is not set
-# CONFIG_SENSORS_SHT21 is not set
-# CONFIG_SENSORS_SHT3x is not set
-# CONFIG_SENSORS_SHT4x is not set
-# CONFIG_SENSORS_SHTC1 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMM665 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_STPDDC60 is not set
-# CONFIG_SENSORS_STTS751 is not set
-# CONFIG_SENSORS_TC654 is not set
-# CONFIG_SENSORS_TC74 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_TMP102 is not set
-# CONFIG_SENSORS_TMP103 is not set
-# CONFIG_SENSORS_TMP108 is not set
-# CONFIG_SENSORS_TMP401 is not set
-# CONFIG_SENSORS_TMP421 is not set
-# CONFIG_SENSORS_TMP513 is not set
-# CONFIG_SENSORS_TPS23861 is not set
-# CONFIG_SENSORS_TPS40422 is not set
-# CONFIG_SENSORS_TPS53679 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_SENSORS_TSL2563 is not set
-# CONFIG_SENSORS_UCD9000 is not set
-# CONFIG_SENSORS_UCD9200 is not set
-# CONFIG_SENSORS_VEXPRESS is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VIA_CPUTEMP is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83773G is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83795 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_XDPE122 is not set
-# CONFIG_SENSORS_XGENE is not set
-# CONFIG_SENSORS_ZL6100 is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_16550A_VARIANTS=y
-# CONFIG_SERIAL_8250_ACCENT is not set
-# CONFIG_SERIAL_8250_ASPEED_VUART is not set
-# CONFIG_SERIAL_8250_BOCA is not set
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
-# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-CONFIG_SERIAL_8250_DMA=y
-# CONFIG_SERIAL_8250_DW is not set
-# CONFIG_SERIAL_8250_EM is not set
-# CONFIG_SERIAL_8250_EXAR is not set
-# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_FINTEK is not set
-# CONFIG_SERIAL_8250_FOURPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-# CONFIG_SERIAL_8250_INGENIC is not set
-# CONFIG_SERIAL_8250_LPSS is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_MID is not set
-# CONFIG_SERIAL_8250_MOXA is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-# CONFIG_SERIAL_8250_PCI is not set
-# CONFIG_SERIAL_8250_RSA is not set
-# CONFIG_SERIAL_8250_RT288X is not set
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-# CONFIG_SERIAL_AMBA_PL010 is not set
-# CONFIG_SERIAL_AMBA_PL011 is not set
-# CONFIG_SERIAL_ARC is not set
-# CONFIG_SERIAL_BCM63XX is not set
-# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_DEV_BUS is not set
-CONFIG_SERIAL_EARLYCON=y
-# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
-# CONFIG_SERIAL_FSL_LINFLEXUART is not set
-# CONFIG_SERIAL_FSL_LPUART is not set
-# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
-# CONFIG_SERIAL_IFX6X60 is not set
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_MAX3100 is not set
-# CONFIG_SERIAL_MAX310X is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_OF_PLATFORM is not set
-# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
-# CONFIG_SERIAL_PCH_UART is not set
-# CONFIG_SERIAL_RP2 is not set
-# CONFIG_SERIAL_SC16IS7XX is not set
-# CONFIG_SERIAL_SCCNXP is not set
-# CONFIG_SERIAL_SH_SCI is not set
-# CONFIG_SERIAL_SIFIVE is not set
-# CONFIG_SERIAL_SPRD is not set
-# CONFIG_SERIAL_STM32 is not set
-# CONFIG_SERIAL_ST_ASC is not set
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_UARTLITE is not set
-# CONFIG_SERIAL_XILINX_PS_UART is not set
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_ALTERA_PS2 is not set
-# CONFIG_SERIO_AMBAKMI is not set
-# CONFIG_SERIO_APBPS2 is not set
-# CONFIG_SERIO_ARC_PS2 is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_GPIO_PS2 is not set
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_PS2MULT is not set
-# CONFIG_SERIO_RAW is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_SUN4I_PS2 is not set
-# CONFIG_SFC is not set
-# CONFIG_SFC_FALCON is not set
-# CONFIG_SFI is not set
-# CONFIG_SFP is not set
-# CONFIG_SF_PDMA is not set
-# CONFIG_SGETMASK_SYSCALL is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP28 is not set
-# CONFIG_SGI_IP30 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SGI_MFD_IOC3 is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SG_POOL is not set
-# CONFIG_SG_SPLIT is not set
-CONFIG_SHMEM=y
-# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
-# CONFIG_SH_ETH is not set
-# CONFIG_SH_TIMER_CMT is not set
-# CONFIG_SH_TIMER_MTU2 is not set
-# CONFIG_SH_TIMER_TMU is not set
-# CONFIG_SI1133 is not set
-# CONFIG_SI1145 is not set
-# CONFIG_SI7005 is not set
-# CONFIG_SI7020 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_SWARM is not set
-CONFIG_SIGNALFD=y
-# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set
-# CONFIG_SIMPLE_GPIO is not set
-# CONFIG_SIMPLE_PM_BUS is not set
-# CONFIG_SIOX is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SKY2_DEBUG is not set
-# CONFIG_SLAB is not set
-CONFIG_SLABINFO=y
-CONFIG_SLAB_FREELIST_HARDENED=y
-CONFIG_SLAB_FREELIST_RANDOM=y
-CONFIG_SLAB_MERGE_DEFAULT=y
-# CONFIG_SLHC is not set
-# CONFIG_SLICOSS is not set
-# CONFIG_SLIMBUS is not set
-# CONFIG_SLIP is not set
-# CONFIG_SLOB is not set
-CONFIG_SLUB=y
-CONFIG_SLUB_CPU_PARTIAL=y
-# CONFIG_SLUB_DEBUG is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_MEMCG_SYSFS_ON is not set
-# CONFIG_SLUB_STATS is not set
-# CONFIG_SMARTJOYPLUS_FF is not set
-# CONFIG_SMB_SERVER is not set
-# CONFIG_SMC911X is not set
-# CONFIG_SMC9194 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_SMP is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_SMSC9420 is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_SMS_SDIO_DRV is not set
-# CONFIG_SMS_USB_DRV is not set
-# CONFIG_SM_CAMCC_8250 is not set
-# CONFIG_SM_FTL is not set
-# CONFIG_SM_GCC_6115 is not set
-# CONFIG_SM_GCC_6125 is not set
-# CONFIG_SM_GCC_6350 is not set
-# CONFIG_SM_GCC_8350 is not set
-# CONFIG_SND is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-# CONFIG_SND_AD1816A is not set
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ADLIB is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ALOOP is not set
-# CONFIG_SND_ALS100 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_ARM is not set
-# CONFIG_SND_ASIHPI is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_ATMEL_AC97C is not set
-# CONFIG_SND_ATMEL_SOC is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AUDIO_GRAPH_CARD is not set
-# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT2320 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BCD2000 is not set
-# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_CS5530 is not set
-# CONFIG_SND_CS5535AUDIO is not set
-# CONFIG_SND_CTXFI is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_DEBUG is not set
-# CONFIG_SND_DESIGNWARE_I2S is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_EDMA_SOC is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_EMU10K1_SEQ is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FIREWIRE is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_HDA_CODEC_CS8409 is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set
-# CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM is not set
-CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
-CONFIG_SND_HDA_PREALLOC_SIZE=64
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_HWDEP is not set
-# CONFIG_SND_I2S_HI6210_I2S is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_INDIGODJX is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGOIOX is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_ISA is not set
-# CONFIG_SND_JZ4740_SOC_I2S is not set
-# CONFIG_SND_KIRKWOOD_SOC is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_LOLA is not set
-# CONFIG_SND_LX6464ES is not set
-# CONFIG_SND_MAESTRO3 is not set
-CONFIG_SND_MAX_CARDS=16
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_MIPS is not set
-# CONFIG_SND_MIRO is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MPC52xx_SOC_EFIKA is not set
-# CONFIG_SND_MPU401 is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_MTS64 is not set
-# CONFIG_SND_MXS_SOC is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_OPL3_LIB_SEQ is not set
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-CONFIG_SND_OSSEMUL=y
-# CONFIG_SND_OXYGEN is not set
-CONFIG_SND_PCI=y
-# CONFIG_SND_PCM is not set
-# CONFIG_SND_PCMCIA is not set
-# CONFIG_SND_PCM_OSS is not set
-CONFIG_SND_PCM_OSS_PLUGINS=y
-# CONFIG_SND_PCM_TIMER is not set
-# CONFIG_SND_PCM_XRUN_DEBUG is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_PDAUDIOCF is not set
-# CONFIG_SND_PORTMAN2X4 is not set
-# CONFIG_SND_POWERPC_SOC is not set
-# CONFIG_SND_PPC is not set
-CONFIG_SND_PROC_FS=y
-# CONFIG_SND_RAWMIDI is not set
-# CONFIG_SND_RAWMIDI_SEQ is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_RTCTIMER is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_SBAWE_SEQ is not set
-# CONFIG_SND_SE6X is not set
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_SIMPLE_CARD is not set
-# CONFIG_SND_SIMPLE_SCU_CARD is not set
-# CONFIG_SND_SIS7019 is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SND_SOC_AC97_CODEC is not set
-# CONFIG_SND_SOC_AD193X_I2C is not set
-# CONFIG_SND_SOC_AD193X_SPI is not set
-# CONFIG_SND_SOC_ADAU1372_I2C is not set
-# CONFIG_SND_SOC_ADAU1372_SPI is not set
-# CONFIG_SND_SOC_ADAU1701 is not set
-# CONFIG_SND_SOC_ADAU1761_I2C is not set
-# CONFIG_SND_SOC_ADAU1761_SPI is not set
-# CONFIG_SND_SOC_ADAU7002 is not set
-# CONFIG_SND_SOC_ADAU7118_HW is not set
-# CONFIG_SND_SOC_ADAU7118_I2C is not set
-# CONFIG_SND_SOC_ADI is not set
-# CONFIG_SND_SOC_AK4104 is not set
-# CONFIG_SND_SOC_AK4118 is not set
-# CONFIG_SND_SOC_AK4458 is not set
-# CONFIG_SND_SOC_AK4554 is not set
-# CONFIG_SND_SOC_AK4613 is not set
-# CONFIG_SND_SOC_AK4642 is not set
-# CONFIG_SND_SOC_AK5386 is not set
-# CONFIG_SND_SOC_AK5558 is not set
-# CONFIG_SND_SOC_ALC5623 is not set
-# CONFIG_SND_SOC_AMD_ACP is not set
-# CONFIG_SND_SOC_AMD_ACP3x is not set
-# CONFIG_SND_SOC_AMD_ACP5x is not set
-# CONFIG_SND_SOC_AMD_RENOIR is not set
-# CONFIG_SND_SOC_AU1XAUDIO is not set
-# CONFIG_SND_SOC_AU1XPSC is not set
-# CONFIG_SND_SOC_BD28623 is not set
-# CONFIG_SND_SOC_BT_SCO is not set
-# CONFIG_SND_SOC_CS35L32 is not set
-# CONFIG_SND_SOC_CS35L33 is not set
-# CONFIG_SND_SOC_CS35L34 is not set
-# CONFIG_SND_SOC_CS35L35 is not set
-# CONFIG_SND_SOC_CS35L36 is not set
-# CONFIG_SND_SOC_CS4234 is not set
-# CONFIG_SND_SOC_CS4265 is not set
-# CONFIG_SND_SOC_CS4270 is not set
-# CONFIG_SND_SOC_CS4271 is not set
-# CONFIG_SND_SOC_CS4271_I2C is not set
-# CONFIG_SND_SOC_CS4271_SPI is not set
-# CONFIG_SND_SOC_CS42L42 is not set
-# CONFIG_SND_SOC_CS42L51_I2C is not set
-# CONFIG_SND_SOC_CS42L52 is not set
-# CONFIG_SND_SOC_CS42L56 is not set
-# CONFIG_SND_SOC_CS42L73 is not set
-# CONFIG_SND_SOC_CS42XX8_I2C is not set
-# CONFIG_SND_SOC_CS43130 is not set
-# CONFIG_SND_SOC_CS4341 is not set
-# CONFIG_SND_SOC_CS4349 is not set
-# CONFIG_SND_SOC_CS53L30 is not set
-# CONFIG_SND_SOC_CX2072X is not set
-# CONFIG_SND_SOC_DA7213 is not set
-# CONFIG_SND_SOC_DIO2125 is not set
-# CONFIG_SND_SOC_DMIC is not set
-# CONFIG_SND_SOC_ES7134 is not set
-# CONFIG_SND_SOC_ES7241 is not set
-# CONFIG_SND_SOC_ES8316 is not set
-# CONFIG_SND_SOC_ES8328 is not set
-# CONFIG_SND_SOC_ES8328_I2C is not set
-# CONFIG_SND_SOC_ES8328_SPI is not set
-# CONFIG_SND_SOC_EUKREA_TLV320 is not set
-# CONFIG_SND_SOC_FSL_ASOC_CARD is not set
-# CONFIG_SND_SOC_FSL_ASRC is not set
-# CONFIG_SND_SOC_FSL_AUD2HTX is not set
-# CONFIG_SND_SOC_FSL_AUDMIX is not set
-# CONFIG_SND_SOC_FSL_ESAI is not set
-# CONFIG_SND_SOC_FSL_MICFIL is not set
-# CONFIG_SND_SOC_FSL_RPMSG is not set
-# CONFIG_SND_SOC_FSL_SAI is not set
-# CONFIG_SND_SOC_FSL_SPDIF is not set
-# CONFIG_SND_SOC_FSL_SSI is not set
-# CONFIG_SND_SOC_FSL_XCVR is not set
-# CONFIG_SND_SOC_GTM601 is not set
-# CONFIG_SND_SOC_ICS43432 is not set
-# CONFIG_SND_SOC_IMG is not set
-# CONFIG_SND_SOC_IMX_AUDMIX is not set
-# CONFIG_SND_SOC_IMX_AUDMUX is not set
-# CONFIG_SND_SOC_IMX_CARD is not set
-# CONFIG_SND_SOC_IMX_ES8328 is not set
-# CONFIG_SND_SOC_IMX_HDMI is not set
-# CONFIG_SND_SOC_IMX_RPMSG is not set
-# CONFIG_SND_SOC_IMX_SPDIF is not set
-# CONFIG_SND_SOC_IMX_WM8962 is not set
-# CONFIG_SND_SOC_INNO_RK3036 is not set
-# CONFIG_SND_SOC_INTEL_APL is not set
-# CONFIG_SND_SOC_INTEL_BAYTRAIL is not set
-# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set
-# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set
-# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set
-# CONFIG_SND_SOC_INTEL_CATPT is not set
-# CONFIG_SND_SOC_INTEL_CFL is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set
-# CONFIG_SND_SOC_INTEL_CML_H is not set
-# CONFIG_SND_SOC_INTEL_CML_LP is not set
-# CONFIG_SND_SOC_INTEL_CNL is not set
-# CONFIG_SND_SOC_INTEL_GLK is not set
-# CONFIG_SND_SOC_INTEL_HASWELL is not set
-# CONFIG_SND_SOC_INTEL_KBL is not set
-# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set
-# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set
-# CONFIG_SND_SOC_INTEL_KEEMBAY is not set
-# CONFIG_SND_SOC_INTEL_SKL is not set
-# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set
-# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set
-# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set
-# CONFIG_SND_SOC_INTEL_SKYLAKE is not set
-# CONFIG_SND_SOC_INTEL_SST is not set
-CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
-# CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES is not set
-# CONFIG_SND_SOC_JZ4725B_CODEC is not set
-# CONFIG_SND_SOC_JZ4740_CODEC is not set
-# CONFIG_SND_SOC_JZ4770_CODEC is not set
-# CONFIG_SND_SOC_LPASS_RX_MACRO is not set
-# CONFIG_SND_SOC_LPASS_TX_MACRO is not set
-# CONFIG_SND_SOC_LPASS_VA_MACRO is not set
-# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set
-# CONFIG_SND_SOC_MA120X0P is not set
-# CONFIG_SND_SOC_MAX9759 is not set
-# CONFIG_SND_SOC_MAX98088 is not set
-# CONFIG_SND_SOC_MAX98357A is not set
-# CONFIG_SND_SOC_MAX98373 is not set
-# CONFIG_SND_SOC_MAX98373_I2C is not set
-# CONFIG_SND_SOC_MAX98390 is not set
-# CONFIG_SND_SOC_MAX98504 is not set
-# CONFIG_SND_SOC_MAX9860 is not set
-# CONFIG_SND_SOC_MAX9867 is not set
-# CONFIG_SND_SOC_MAX98927 is not set
-# CONFIG_SND_SOC_MEDIATEK is not set
-# CONFIG_SND_SOC_MPC5200_AC97 is not set
-# CONFIG_SND_SOC_MPC5200_I2S is not set
-# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set
-# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set
-# CONFIG_SND_SOC_MT2701 is not set
-# CONFIG_SND_SOC_MT6351 is not set
-# CONFIG_SND_SOC_MT6358 is not set
-# CONFIG_SND_SOC_MT6359 is not set
-# CONFIG_SND_SOC_MT6359_ACCDET is not set
-# CONFIG_SND_SOC_MT6660 is not set
-# CONFIG_SND_SOC_MT6797 is not set
-# CONFIG_SND_SOC_MT8173 is not set
-# CONFIG_SND_SOC_MT8183 is not set
-# CONFIG_SND_SOC_MT8192 is not set
-# CONFIG_SND_SOC_MT8195 is not set
-# CONFIG_SND_SOC_MTK_BTCVSD is not set
-# CONFIG_SND_SOC_NAU8315 is not set
-# CONFIG_SND_SOC_NAU8540 is not set
-# CONFIG_SND_SOC_NAU8810 is not set
-# CONFIG_SND_SOC_NAU8822 is not set
-# CONFIG_SND_SOC_NAU8824 is not set
-# CONFIG_SND_SOC_PCM1681 is not set
-# CONFIG_SND_SOC_PCM1789_I2C is not set
-# CONFIG_SND_SOC_PCM1792A is not set
-# CONFIG_SND_SOC_PCM179X_I2C is not set
-# CONFIG_SND_SOC_PCM179X_SPI is not set
-# CONFIG_SND_SOC_PCM186X_I2C is not set
-# CONFIG_SND_SOC_PCM186X_SPI is not set
-# CONFIG_SND_SOC_PCM3060_I2C is not set
-# CONFIG_SND_SOC_PCM3060_SPI is not set
-# CONFIG_SND_SOC_PCM3168A_I2C is not set
-# CONFIG_SND_SOC_PCM3168A_SPI is not set
-# CONFIG_SND_SOC_PCM5102A is not set
-# CONFIG_SND_SOC_PCM512x_I2C is not set
-# CONFIG_SND_SOC_PCM512x_SPI is not set
-# CONFIG_SND_SOC_QCOM is not set
-# CONFIG_SND_SOC_RK3328 is not set
-# CONFIG_SND_SOC_RK817 is not set
-# CONFIG_SND_SOC_ROCKCHIP is not set
-# CONFIG_SND_SOC_RT5616 is not set
-# CONFIG_SND_SOC_RT5631 is not set
-# CONFIG_SND_SOC_RT5640 is not set
-# CONFIG_SND_SOC_RT5659 is not set
-# CONFIG_SND_SOC_RT5677_SPI is not set
-# CONFIG_SND_SOC_SGTL5000 is not set
-# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set
-# CONFIG_SND_SOC_SIMPLE_MUX is not set
-# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set
-# CONFIG_SND_SOC_SOF_TOPLEVEL is not set
-# CONFIG_SND_SOC_SPDIF is not set
-# CONFIG_SND_SOC_SSM2305 is not set
-# CONFIG_SND_SOC_SSM2518 is not set
-# CONFIG_SND_SOC_SSM2602_I2C is not set
-# CONFIG_SND_SOC_SSM2602_SPI is not set
-# CONFIG_SND_SOC_SSM4567 is not set
-# CONFIG_SND_SOC_STA32X is not set
-# CONFIG_SND_SOC_STA350 is not set
-# CONFIG_SND_SOC_STI_SAS is not set
-# CONFIG_SND_SOC_TAS2552 is not set
-# CONFIG_SND_SOC_TAS2562 is not set
-# CONFIG_SND_SOC_TAS2764 is not set
-# CONFIG_SND_SOC_TAS2770 is not set
-# CONFIG_SND_SOC_TAS5086 is not set
-# CONFIG_SND_SOC_TAS571X is not set
-# CONFIG_SND_SOC_TAS5720 is not set
-# CONFIG_SND_SOC_TAS6424 is not set
-# CONFIG_SND_SOC_TDA7419 is not set
-# CONFIG_SND_SOC_TFA9879 is not set
-# CONFIG_SND_SOC_TFA989X is not set
-# CONFIG_SND_SOC_TLV320ADCX140 is not set
-# CONFIG_SND_SOC_TLV320AIC23_I2C is not set
-# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
-# CONFIG_SND_SOC_TLV320AIC31XX is not set
-# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set
-# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set
-# CONFIG_SND_SOC_TLV320AIC3X is not set
-# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set
-# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set
-# CONFIG_SND_SOC_TPA6130A2 is not set
-# CONFIG_SND_SOC_TS3A227E is not set
-# CONFIG_SND_SOC_TSCS42XX is not set
-# CONFIG_SND_SOC_TSCS454 is not set
-# CONFIG_SND_SOC_UDA1334 is not set
-# CONFIG_SND_SOC_WM8510 is not set
-# CONFIG_SND_SOC_WM8523 is not set
-# CONFIG_SND_SOC_WM8524 is not set
-# CONFIG_SND_SOC_WM8580 is not set
-# CONFIG_SND_SOC_WM8711 is not set
-# CONFIG_SND_SOC_WM8728 is not set
-# CONFIG_SND_SOC_WM8731 is not set
-# CONFIG_SND_SOC_WM8737 is not set
-# CONFIG_SND_SOC_WM8741 is not set
-# CONFIG_SND_SOC_WM8750 is not set
-# CONFIG_SND_SOC_WM8753 is not set
-# CONFIG_SND_SOC_WM8770 is not set
-# CONFIG_SND_SOC_WM8776 is not set
-# CONFIG_SND_SOC_WM8782 is not set
-# CONFIG_SND_SOC_WM8804_I2C is not set
-# CONFIG_SND_SOC_WM8804_SPI is not set
-# CONFIG_SND_SOC_WM8903 is not set
-# CONFIG_SND_SOC_WM8904 is not set
-# CONFIG_SND_SOC_WM8960 is not set
-# CONFIG_SND_SOC_WM8962 is not set
-# CONFIG_SND_SOC_WM8974 is not set
-# CONFIG_SND_SOC_WM8978 is not set
-# CONFIG_SND_SOC_WM8985 is not set
-# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set
-# CONFIG_SND_SOC_XILINX_I2S is not set
-# CONFIG_SND_SOC_XILINX_SPDIF is not set
-# CONFIG_SND_SOC_XTFPGA_I2S is not set
-# CONFIG_SND_SOC_ZL38060 is not set
-# CONFIG_SND_SOC_ZX_AUD96P22 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_SPI is not set
-# CONFIG_SND_SSCAPE is not set
-# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI is not set
-# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set
-# CONFIG_SND_SUN4I_CODEC is not set
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_TIMER is not set
-# CONFIG_SND_TRIDENT is not set
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_6FIRE is not set
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_USB_HIFACE is not set
-# CONFIG_SND_USB_POD is not set
-# CONFIG_SND_USB_PODHD is not set
-# CONFIG_SND_USB_TONEPORT is not set
-# CONFIG_SND_USB_UA101 is not set
-# CONFIG_SND_USB_US122L is not set
-# CONFIG_SND_USB_USX2Y is not set
-# CONFIG_SND_USB_VARIAX is not set
-# CONFIG_SND_VERBOSE_PRINTK is not set
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTIO is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_WAVEFRONT is not set
-CONFIG_SND_X86=y
-# CONFIG_SND_XEN_FRONTEND is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
-# CONFIG_SOCK_CGROUP_DATA is not set
-# CONFIG_SOC_AM33XX is not set
-# CONFIG_SOC_AM43XX is not set
-# CONFIG_SOC_BRCMSTB is not set
-# CONFIG_SOC_CAMERA is not set
-# CONFIG_SOC_DRA7XX is not set
-# CONFIG_SOC_HAS_OMAP2_SDRC is not set
-# CONFIG_SOC_OMAP5 is not set
-# CONFIG_SOC_TI is not set
-# CONFIG_SOFTLOCKUP_DETECTOR is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_SONYPI is not set
-# CONFIG_SONY_LAPTOP is not set
-# CONFIG_SOUND is not set
-# CONFIG_SOUNDWIRE is not set
-# CONFIG_SOUND_OSS_CORE is not set
-# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_SP5100_TCO is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-# CONFIG_SPARSE_IRQ is not set
-# CONFIG_SPARSE_RCU_POINTER is not set
-# CONFIG_SPEAKUP is not set
-# CONFIG_SPI is not set
-# CONFIG_SPINLOCK_TEST is not set
-# CONFIG_SPI_ALTERA is not set
-# CONFIG_SPI_AMD is not set
-# CONFIG_SPI_AU1550 is not set
-# CONFIG_SPI_AXI_SPI_ENGINE is not set
-# CONFIG_SPI_BCM2835 is not set
-# CONFIG_SPI_BCM_QSPI is not set
-# CONFIG_SPI_BITBANG is not set
-# CONFIG_SPI_BUTTERFLY is not set
-# CONFIG_SPI_CADENCE is not set
-# CONFIG_SPI_CADENCE_QUADSPI is not set
-# CONFIG_SPI_DEBUG is not set
-# CONFIG_SPI_DESIGNWARE is not set
-# CONFIG_SPI_FSL_DSPI is not set
-# CONFIG_SPI_FSL_ESPI is not set
-# CONFIG_SPI_FSL_SPI is not set
-# CONFIG_SPI_GPIO is not set
-# CONFIG_SPI_GPIO_OLD is not set
-# CONFIG_SPI_IMG_SPFI is not set
-# CONFIG_SPI_LANTIQ_SSC is not set
-# CONFIG_SPI_LM70_LLP is not set
-# CONFIG_SPI_LOOPBACK_TEST is not set
-# CONFIG_SPI_MASTER is not set
-# CONFIG_SPI_MEM is not set
-# CONFIG_SPI_MPC52xx is not set
-# CONFIG_SPI_MPC52xx_PSC is not set
-# CONFIG_SPI_MTK_QUADSPI is not set
-# CONFIG_SPI_MUX is not set
-# CONFIG_SPI_MXIC is not set
-# CONFIG_SPI_NXP_FLEXSPI is not set
-# CONFIG_SPI_OCTEON is not set
-# CONFIG_SPI_OC_TINY is not set
-# CONFIG_SPI_ORION is not set
-# CONFIG_SPI_PL022 is not set
-# CONFIG_SPI_PPC4xx is not set
-# CONFIG_SPI_PXA2XX is not set
-# CONFIG_SPI_PXA2XX_PCI is not set
-# CONFIG_SPI_QCOM_QSPI is not set
-# CONFIG_SPI_ROCKCHIP is not set
-# CONFIG_SPI_S3C64XX is not set
-# CONFIG_SPI_SC18IS602 is not set
-# CONFIG_SPI_SIFIVE is not set
-# CONFIG_SPI_SLAVE is not set
-# CONFIG_SPI_SPIDEV is not set
-# CONFIG_SPI_THUNDERX is not set
-# CONFIG_SPI_TI_QSPI is not set
-# CONFIG_SPI_TLE62X0 is not set
-# CONFIG_SPI_TOPCLIFF_PCH is not set
-# CONFIG_SPI_XCOMM is not set
-# CONFIG_SPI_XILINX is not set
-# CONFIG_SPI_XWAY is not set
-# CONFIG_SPI_ZYNQMP_GQSPI is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_SPMI is not set
-# CONFIG_SPS30 is not set
-# CONFIG_SPS30_I2C is not set
-# CONFIG_SPS30_SERIAL is not set
-CONFIG_SQUASHFS=y
-# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
-# CONFIG_SQUASHFS_DECOMP_MULTI is not set
-CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
-# CONFIG_SQUASHFS_DECOMP_SINGLE is not set
-CONFIG_SQUASHFS_EMBEDDED=y
-# CONFIG_SQUASHFS_FILE_CACHE is not set
-CONFIG_SQUASHFS_FILE_DIRECT=y
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-# CONFIG_SQUASHFS_LZ4 is not set
-# CONFIG_SQUASHFS_LZO is not set
-# CONFIG_SQUASHFS_XATTR is not set
-CONFIG_SQUASHFS_XZ=y
-# CONFIG_SQUASHFS_ZLIB is not set
-# CONFIG_SQUASHFS_ZSTD is not set
-# CONFIG_SRAM is not set
-# CONFIG_SRF04 is not set
-# CONFIG_SRF08 is not set
-# CONFIG_SSB is not set
-# CONFIG_SSB_DEBUG is not set
-# CONFIG_SSB_DRIVER_GPIO is not set
-# CONFIG_SSB_HOST_SOC is not set
-# CONFIG_SSB_PCMCIAHOST is not set
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB_SDIOHOST is not set
-# CONFIG_SSB_SILENT is not set
-# CONFIG_SSFDC is not set
-# CONFIG_STACKPROTECTOR is not set
-# CONFIG_STACKPROTECTOR_STRONG is not set
-# CONFIG_STACKTRACE is not set
-# CONFIG_STACKTRACE_BUILD_ID is not set
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_STACK_HASH_ORDER=20
-# CONFIG_STACK_TRACER is not set
-# CONFIG_STACK_VALIDATION is not set
-CONFIG_STAGING=y
-# CONFIG_STAGING_BOARD is not set
-# CONFIG_STAGING_GASKET_FRAMEWORK is not set
-# CONFIG_STAGING_MEDIA is not set
-CONFIG_STANDALONE=y
-# CONFIG_STATIC_KEYS_SELFTEST is not set
-# CONFIG_STATIC_USERMODEHELPER is not set
-CONFIG_STDBINUTILS=y
-# CONFIG_STE10XP is not set
-# CONFIG_STE_MODEM_RPROC is not set
-# CONFIG_STK3310 is not set
-# CONFIG_STK8312 is not set
-# CONFIG_STK8BA50 is not set
-# CONFIG_STM is not set
-# CONFIG_STMMAC_ETH is not set
-# CONFIG_STMMAC_PCI is not set
-# CONFIG_STMMAC_PLATFORM is not set
-# CONFIG_STMMAC_SELFTESTS is not set
-# CONFIG_STM_DUMMY is not set
-# CONFIG_STM_SOURCE_CONSOLE is not set
-CONFIG_STP=y
-# CONFIG_STREAM_PARSER is not set
-# CONFIG_STRICT_DEVMEM is not set
-CONFIG_STRICT_KERNEL_RWX=y
-CONFIG_STRICT_MODULE_RWX=y
-# CONFIG_STRING_SELFTEST is not set
-CONFIG_STRIP_ASM_SYMS=y
-# CONFIG_STX104 is not set
-# CONFIG_ST_UVIS25 is not set
-# CONFIG_SUN4I_GPADC is not set
-# CONFIG_SUN50I_DE2_BUS is not set
-# CONFIG_SUN50I_ERRATUM_UNKNOWN1 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_SUNRPC_DEBUG is not set
-CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y
-# CONFIG_SUNRPC_GSS is not set
-# CONFIG_SUNXI_SRAM is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_SURFACE_3_BUTTON is not set
-# CONFIG_SUSPEND is not set
-# CONFIG_SUSPEND_SKIP_SYNC is not set
-CONFIG_SWAP=y
-# CONFIG_SWCONFIG is not set
-# CONFIG_SWCONFIG_B53 is not set
-# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set
-# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set
-# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set
-# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set
-# CONFIG_SWCONFIG_LEDS is not set
-# CONFIG_SW_SYNC is not set
-# CONFIG_SX9310 is not set
-# CONFIG_SX9500 is not set
-# CONFIG_SXGBE_ETH is not set
-CONFIG_SYMBOLIC_ERRNAME=y
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_SYNC_FILE is not set
-# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set
-# CONFIG_SYNTH_EVENTS is not set
-# CONFIG_SYNTH_EVENT_GEN_TEST is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_SYSCON_REBOOT_MODE is not set
-CONFIG_SYSCTL=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_SYSFS=y
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_SYSFS_DEPRECATED_V2 is not set
-# CONFIG_SYSFS_SYSCALL is not set
-# CONFIG_SYSTEMPORT is not set
-# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
-# CONFIG_SYSTEM_DATA_VERIFICATION is not set
-# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
-CONFIG_SYSTEM_TRUSTED_KEYS=""
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_T5403 is not set
-# CONFIG_TARGET_CORE is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_TASKS_RCU is not set
-# CONFIG_TASK_XACCT is not set
-# CONFIG_TC35815 is not set
-# CONFIG_TCG_ATMEL is not set
-# CONFIG_TCG_CRB is not set
-# CONFIG_TCG_FTPM_TEE is not set
-# CONFIG_TCG_INFINEON is not set
-# CONFIG_TCG_NSC is not set
-# CONFIG_TCG_ST33_I2C is not set
-# CONFIG_TCG_TIS is not set
-# CONFIG_TCG_TIS_I2C_ATMEL is not set
-# CONFIG_TCG_TIS_I2C_CR50 is not set
-# CONFIG_TCG_TIS_I2C_INFINEON is not set
-# CONFIG_TCG_TIS_I2C_NUVOTON is not set
-# CONFIG_TCG_TIS_SPI is not set
-# CONFIG_TCG_TIS_ST33ZP24_I2C is not set
-# CONFIG_TCG_TIS_ST33ZP24_SPI is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_TCG_VTPM_PROXY is not set
-# CONFIG_TCG_XEN is not set
-# CONFIG_TCIC is not set
-CONFIG_TCP_CONG_ADVANCED=y
-# CONFIG_TCP_CONG_BBR is not set
-# CONFIG_TCP_CONG_BIC is not set
-# CONFIG_TCP_CONG_CDG is not set
-CONFIG_TCP_CONG_CUBIC=y
-# CONFIG_TCP_CONG_DCTCP is not set
-# CONFIG_TCP_CONG_HSTCP is not set
-# CONFIG_TCP_CONG_HTCP is not set
-# CONFIG_TCP_CONG_HYBLA is not set
-# CONFIG_TCP_CONG_ILLINOIS is not set
-# CONFIG_TCP_CONG_LP is not set
-# CONFIG_TCP_CONG_NV is not set
-# CONFIG_TCP_CONG_SCALABLE is not set
-# CONFIG_TCP_CONG_VEGAS is not set
-# CONFIG_TCP_CONG_VENO is not set
-# CONFIG_TCP_CONG_WESTWOOD is not set
-# CONFIG_TCP_CONG_YEAH is not set
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_TCS3414 is not set
-# CONFIG_TCS3472 is not set
-# CONFIG_TEE is not set
-# CONFIG_TEGRA210_ADMA is not set
-# CONFIG_TEGRA_ACONNECT is not set
-# CONFIG_TEGRA_AHB is not set
-# CONFIG_TEGRA_HOST1X is not set
-# CONFIG_TEHUTI is not set
-# CONFIG_TERANETICS_PHY is not set
-# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
-# CONFIG_TEST_BITFIELD is not set
-# CONFIG_TEST_BITMAP is not set
-# CONFIG_TEST_BITOPS is not set
-# CONFIG_TEST_BLACKHOLE_DEV is not set
-# CONFIG_TEST_BPF is not set
-# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set
-# CONFIG_TEST_DEBUG_VIRTUAL is not set
-# CONFIG_TEST_DIV64 is not set
-# CONFIG_TEST_FIRMWARE is not set
-# CONFIG_TEST_FREE_PAGES is not set
-# CONFIG_TEST_HASH is not set
-# CONFIG_TEST_HEXDUMP is not set
-# CONFIG_TEST_IDA is not set
-# CONFIG_TEST_KASAN_MODULE is not set
-# CONFIG_TEST_KMOD is not set
-# CONFIG_TEST_KSTRTOX is not set
-# CONFIG_TEST_LIST_SORT is not set
-# CONFIG_TEST_LKM is not set
-# CONFIG_TEST_LOCKUP is not set
-# CONFIG_TEST_MEMCAT_P is not set
-# CONFIG_TEST_MEMINIT is not set
-# CONFIG_TEST_MIN_HEAP is not set
-# CONFIG_TEST_OVERFLOW is not set
-# CONFIG_TEST_POWER is not set
-# CONFIG_TEST_PRINTF is not set
-# CONFIG_TEST_RHASHTABLE is not set
-# CONFIG_TEST_SCANF is not set
-# CONFIG_TEST_SORT is not set
-# CONFIG_TEST_STACKINIT is not set
-# CONFIG_TEST_STATIC_KEYS is not set
-# CONFIG_TEST_STRING_HELPERS is not set
-# CONFIG_TEST_STRSCPY is not set
-# CONFIG_TEST_SYSCTL is not set
-# CONFIG_TEST_UBSAN is not set
-# CONFIG_TEST_UDELAY is not set
-# CONFIG_TEST_USER_COPY is not set
-# CONFIG_TEST_UUID is not set
-# CONFIG_TEST_VMALLOC is not set
-# CONFIG_TEST_XARRAY is not set
-CONFIG_TEXTSEARCH=y
-# CONFIG_TEXTSEARCH_BM is not set
-# CONFIG_TEXTSEARCH_FSM is not set
-# CONFIG_TEXTSEARCH_KMP is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
-# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set
-# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
-# CONFIG_THERMAL_EMULATION is not set
-# CONFIG_THERMAL_GOV_BANG_BANG is not set
-# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
-# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set
-# CONFIG_THERMAL_GOV_USER_SPACE is not set
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_THERMAL_MMIO is not set
-# CONFIG_THERMAL_NETLINK is not set
-# CONFIG_THERMAL_STATISTICS is not set
-# CONFIG_THERMAL_WRITABLE_TRIPS is not set
-# CONFIG_THINKPAD_ACPI is not set
-CONFIG_THIN_ARCHIVES=y
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_THUMB2_KERNEL is not set
-# CONFIG_THUNDERBOLT is not set
-# CONFIG_THUNDER_NIC_BGX is not set
-# CONFIG_THUNDER_NIC_PF is not set
-# CONFIG_THUNDER_NIC_RGX is not set
-# CONFIG_THUNDER_NIC_VF is not set
-# CONFIG_TICK_CPU_ACCOUNTING is not set
-CONFIG_TICK_ONESHOT=y
-# CONFIG_TIFM_CORE is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_TIMB_DMA is not set
-CONFIG_TIMERFD=y
-# CONFIG_TIMERLAT_TRACER is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_TIME_NS is not set
-# CONFIG_TINYDRM_HX8357D is not set
-# CONFIG_TINYDRM_ILI9225 is not set
-# CONFIG_TINYDRM_ILI9341 is not set
-# CONFIG_TINYDRM_ILI9486 is not set
-# CONFIG_TINYDRM_MI0283QT is not set
-# CONFIG_TINYDRM_REPAPER is not set
-# CONFIG_TINYDRM_ST7586 is not set
-# CONFIG_TINYDRM_ST7735R is not set
-CONFIG_TINY_RCU=y
-# CONFIG_TIPC is not set
-# CONFIG_TI_ADC081C is not set
-# CONFIG_TI_ADC0832 is not set
-# CONFIG_TI_ADC084S021 is not set
-# CONFIG_TI_ADC108S102 is not set
-# CONFIG_TI_ADC12138 is not set
-# CONFIG_TI_ADC128S052 is not set
-# CONFIG_TI_ADC161S626 is not set
-# CONFIG_TI_ADS1015 is not set
-# CONFIG_TI_ADS124S08 is not set
-# CONFIG_TI_ADS131E08 is not set
-# CONFIG_TI_ADS7950 is not set
-# CONFIG_TI_ADS8344 is not set
-# CONFIG_TI_ADS8688 is not set
-# CONFIG_TI_AM335X_ADC is not set
-# CONFIG_TI_CPSW is not set
-# CONFIG_TI_CPSW_ALE is not set
-# CONFIG_TI_CPSW_PHY_SEL is not set
-# CONFIG_TI_CPTS is not set
-# CONFIG_TI_DAC082S085 is not set
-# CONFIG_TI_DAC5571 is not set
-# CONFIG_TI_DAC7311 is not set
-# CONFIG_TI_DAC7512 is not set
-# CONFIG_TI_DAC7612 is not set
-# CONFIG_TI_DAVINCI_CPDMA is not set
-# CONFIG_TI_DAVINCI_MDIO is not set
-# CONFIG_TI_ST is not set
-# CONFIG_TI_SYSCON_RESET is not set
-# CONFIG_TI_TLC4541 is not set
-# CONFIG_TI_TSC2046 is not set
-# CONFIG_TLAN is not set
-# CONFIG_TLS is not set
-# CONFIG_TLS_DEVICE is not set
-# CONFIG_TLS_TOE is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_TMP006 is not set
-# CONFIG_TMP007 is not set
-# CONFIG_TMP117 is not set
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_INODE64 is not set
-# CONFIG_TMPFS_POSIX_ACL is not set
-CONFIG_TMPFS_XATTR=y
-# CONFIG_TOPSTAR_LAPTOP is not set
-# CONFIG_TORTURE_TEST is not set
-# CONFIG_TOSHIBA_HAPS is not set
-# CONFIG_TOUCHSCREEN_88PM860X is not set
-# CONFIG_TOUCHSCREEN_AD7877 is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
-# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
-# CONFIG_TOUCHSCREEN_ADC is not set
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
-# CONFIG_TOUCHSCREEN_AR1021_I2C is not set
-# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
-# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set
-# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
-# CONFIG_TOUCHSCREEN_BU21013 is not set
-# CONFIG_TOUCHSCREEN_BU21029 is not set
-# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set
-# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set
-# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
-# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
-# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set
-# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set
-# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
-# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set
-# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set
-# CONFIG_TOUCHSCREEN_DA9034 is not set
-# CONFIG_TOUCHSCREEN_DA9052 is not set
-# CONFIG_TOUCHSCREEN_DYNAPRO is not set
-# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
-# CONFIG_TOUCHSCREEN_EETI is not set
-# CONFIG_TOUCHSCREEN_EGALAX is not set
-# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set
-# CONFIG_TOUCHSCREEN_EKTF2127 is not set
-# CONFIG_TOUCHSCREEN_ELAN is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_EXC3000 is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GOODIX is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
-# CONFIG_TOUCHSCREEN_HIDEEP is not set
-# CONFIG_TOUCHSCREEN_HP600 is not set
-# CONFIG_TOUCHSCREEN_HP7XX is not set
-# CONFIG_TOUCHSCREEN_HTCPEN is not set
-# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set
-# CONFIG_TOUCHSCREEN_ILI210X is not set
-# CONFIG_TOUCHSCREEN_ILITEK is not set
-# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set
-# CONFIG_TOUCHSCREEN_IPROC is not set
-# CONFIG_TOUCHSCREEN_IQS5XX is not set
-# CONFIG_TOUCHSCREEN_LPC32XX is not set
-# CONFIG_TOUCHSCREEN_MAX11801 is not set
-# CONFIG_TOUCHSCREEN_MC13783 is not set
-# CONFIG_TOUCHSCREEN_MCS5000 is not set
-# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set
-# CONFIG_TOUCHSCREEN_MIGOR is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_MMS114 is not set
-# CONFIG_TOUCHSCREEN_MSG2638 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_MX25 is not set
-# CONFIG_TOUCHSCREEN_MXS_LRADC is not set
-# CONFIG_TOUCHSCREEN_PCAP is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_PIXCIR is not set
-# CONFIG_TOUCHSCREEN_PROPERTIES is not set
-# CONFIG_TOUCHSCREEN_RASPBERRYPI_FW is not set
-# CONFIG_TOUCHSCREEN_RM_TS is not set
-# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
-# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set
-# CONFIG_TOUCHSCREEN_S3C2410 is not set
-# CONFIG_TOUCHSCREEN_S6SY761 is not set
-# CONFIG_TOUCHSCREEN_SILEAD is not set
-# CONFIG_TOUCHSCREEN_SIS_I2C is not set
-# CONFIG_TOUCHSCREEN_ST1232 is not set
-# CONFIG_TOUCHSCREEN_STMFTS is not set
-# CONFIG_TOUCHSCREEN_STMPE is not set
-# CONFIG_TOUCHSCREEN_SUN4I is not set
-# CONFIG_TOUCHSCREEN_SUR40 is not set
-# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set
-# CONFIG_TOUCHSCREEN_SX8654 is not set
-# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_TPS6507X is not set
-# CONFIG_TOUCHSCREEN_TS4800 is not set
-# CONFIG_TOUCHSCREEN_TSC2004 is not set
-# CONFIG_TOUCHSCREEN_TSC2005 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set
-# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set
-# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
-# CONFIG_TOUCHSCREEN_USB_3M is not set
-# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
-# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set
-# CONFIG_TOUCHSCREEN_USB_E2I is not set
-# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set
-# CONFIG_TOUCHSCREEN_USB_EGALAX is not set
-# CONFIG_TOUCHSCREEN_USB_ELO is not set
-# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set
-# CONFIG_TOUCHSCREEN_USB_ETURBO is not set
-# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set
-# CONFIG_TOUCHSCREEN_USB_GOTOP is not set
-# CONFIG_TOUCHSCREEN_USB_GUNZE is not set
-# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set
-# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set
-# CONFIG_TOUCHSCREEN_USB_ITM is not set
-# CONFIG_TOUCHSCREEN_USB_JASTEC is not set
-# CONFIG_TOUCHSCREEN_USB_NEXIO is not set
-# CONFIG_TOUCHSCREEN_USB_PANJIT is not set
-# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set
-# CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set
-# CONFIG_TOUCHSCREEN_WM831X is not set
-# CONFIG_TOUCHSCREEN_WM9705 is not set
-# CONFIG_TOUCHSCREEN_WM9712 is not set
-# CONFIG_TOUCHSCREEN_WM9713 is not set
-# CONFIG_TOUCHSCREEN_WM97XX is not set
-# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
-# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set
-# CONFIG_TOUCHSCREEN_ZET6223 is not set
-# CONFIG_TOUCHSCREEN_ZFORCE is not set
-# CONFIG_TOUCHSCREEN_ZINITIX is not set
-# CONFIG_TPL0102 is not set
-# CONFIG_TPS6105X is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-# CONFIG_TRACEPOINT_BENCHMARK is not set
-# CONFIG_TRACER_SNAPSHOT is not set
-# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_TRACE_EVAL_MAP_FILE is not set
-# CONFIG_TRACE_EVENT_INJECT is not set
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_TRACE_SINK is not set
-# CONFIG_TRACING_EVENTS_GPIO is not set
-CONFIG_TRACING_SUPPORT=y
-CONFIG_TRAD_SIGNALS=y
-# CONFIG_TRANSPARENT_HUGEPAGE is not set
-# CONFIG_TREE_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_TRIM_UNUSED_KSYMS is not set
-# CONFIG_TRUSTED_FOUNDATIONS is not set
-# CONFIG_TRUSTED_KEYS is not set
-# CONFIG_TSL2583 is not set
-# CONFIG_TSL2591 is not set
-# CONFIG_TSL2772 is not set
-# CONFIG_TSL2x7x is not set
-# CONFIG_TSL4531 is not set
-# CONFIG_TSYS01 is not set
-# CONFIG_TSYS02D is not set
-# CONFIG_TTPCI_EEPROM is not set
-CONFIG_TTY=y
-# CONFIG_TTY_PRINTK is not set
-# CONFIG_TUN is not set
-# CONFIG_TUN_VNET_CROSS_LE is not set
-# CONFIG_TWL4030_CORE is not set
-# CONFIG_TWL4030_MADC is not set
-# CONFIG_TWL6030_GPADC is not set
-# CONFIG_TWL6040_CORE is not set
-# CONFIG_TYPEC is not set
-# CONFIG_TYPEC_TCPM is not set
-# CONFIG_TYPEC_UCSI is not set
-# CONFIG_TYPHOON is not set
-# CONFIG_UACCESS_WITH_MEMCPY is not set
-# CONFIG_UBIFS_ATIME_SUPPORT is not set
-# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
-# CONFIG_UBIFS_FS_AUTHENTICATION is not set
-# CONFIG_UBIFS_FS_ENCRYPTION is not set
-CONFIG_UBIFS_FS_LZO=y
-# CONFIG_UBIFS_FS_SECURITY is not set
-CONFIG_UBIFS_FS_XATTR=y
-CONFIG_UBIFS_FS_ZLIB=y
-CONFIG_UBIFS_FS_ZSTD=y
-# CONFIG_UBSAN is not set
-CONFIG_UBSAN_ALIGNMENT=y
-CONFIG_UBSAN_BOOL=y
-# CONFIG_UBSAN_DIV_ZERO is not set
-CONFIG_UBSAN_ENUM=y
-# CONFIG_UBSAN_MISC is not set
-CONFIG_UBSAN_SHIFT=y
-# CONFIG_UBSAN_UNREACHABLE is not set
-# CONFIG_UCB1400_CORE is not set
-# CONFIG_UCSI is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDMABUF is not set
-CONFIG_UEVENT_HELPER=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_UFS_FS is not set
-# CONFIG_UHID is not set
-CONFIG_UID16=y
-# CONFIG_UIO is not set
-# CONFIG_ULTRA is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_UNICODE is not set
-# CONFIG_UNISYSSPAR is not set
-# CONFIG_UNISYS_VISORBUS is not set
-CONFIG_UNIX=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_UNIX_DIAG is not set
-CONFIG_UNIX_SCM=y
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_UNWINDER_FRAME_POINTER is not set
-# CONFIG_UPROBES is not set
-# CONFIG_UPROBE_EVENTS is not set
-# CONFIG_US5182D is not set
-# CONFIG_USB is not set
-# CONFIG_USB4 is not set
-# CONFIG_USBIP_CORE is not set
-CONFIG_USBIP_VHCI_HC_PORTS=8
-CONFIG_USBIP_VHCI_NR_HCS=1
-# CONFIG_USBIP_VUDC is not set
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AIRSPY is not set
-CONFIG_USB_ALI_M5632=y
-# CONFIG_USB_AMD5536UDC is not set
-CONFIG_USB_AN2720=y
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARMLINUX=y
-# CONFIG_USB_ATM is not set
-# CONFIG_USB_AUDIO is not set
-CONFIG_USB_AUTOSUSPEND_DELAY=2
-# CONFIG_USB_BDC_UDC is not set
-CONFIG_USB_BELKIN=y
-# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_USB_CDNS3 is not set
-# CONFIG_USB_CDNS3_IMX is not set
-# CONFIG_USB_CDNS3_PCI_WRAP is not set
-# CONFIG_USB_CDNS_SUPPORT is not set
-# CONFIG_USB_CDNSP_PCI is not set
-# CONFIG_USB_CHAOSKEY is not set
-# CONFIG_USB_CHIPIDEA is not set
-# CONFIG_USB_CHIPIDEA_GENERIC is not set
-# CONFIG_USB_CHIPIDEA_IMX is not set
-# CONFIG_USB_CHIPIDEA_MSM is not set
-# CONFIG_USB_CHIPIDEA_PCI is not set
-# CONFIG_USB_CHIPIDEA_TEGRA is not set
-# CONFIG_USB_CONFIGFS is not set
-# CONFIG_USB_CONN_GPIO is not set
-# CONFIG_USB_CXACRU is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-CONFIG_USB_DEFAULT_PERSIST=y
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DUMMY_HCD is not set
-# CONFIG_USB_DWC2 is not set
-# CONFIG_USB_DWC2_DEBUG is not set
-# CONFIG_USB_DWC2_DUAL_ROLE is not set
-# CONFIG_USB_DWC2_HOST is not set
-# CONFIG_USB_DWC2_PERIPHERAL is not set
-# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set
-# CONFIG_USB_DWC3 is not set
-# CONFIG_USB_DWC3_EXYNOS is not set
-# CONFIG_USB_DWC3_HAPS is not set
-# CONFIG_USB_DWC3_KEYSTONE is not set
-# CONFIG_USB_DWC3_OF_SIMPLE is not set
-# CONFIG_USB_DWC3_PCI is not set
-# CONFIG_USB_DWC3_QCOM is not set
-# CONFIG_USB_DWC3_ULPI is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_EG20T is not set
-# CONFIG_USB_EHCI_ATH79 is not set
-# CONFIG_USB_EHCI_FSL is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_EHCI_HCD_AT91 is not set
-# CONFIG_USB_EHCI_HCD_OMAP is not set
-# CONFIG_USB_EHCI_HCD_PPC_OF is not set
-# CONFIG_USB_EHCI_MSM is not set
-# CONFIG_USB_EHCI_MV is not set
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-# CONFIG_USB_EHSET_TEST_FIXTURE is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EPSON2888 is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_EZUSB_FX2 is not set
-# CONFIG_USB_FEW_INIT_RETRIES is not set
-# CONFIG_USB_FOTG210_HCD is not set
-# CONFIG_USB_FOTG210_UDC is not set
-# CONFIG_USB_FSL_USB2 is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_FUNCTIONFS is not set
-# CONFIG_USB_FUSB300 is not set
-# CONFIG_USB_GADGET is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_GADGET_DEBUG is not set
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_DEBUG_FS is not set
-CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
-CONFIG_USB_GADGET_VBUS_DRAW=2
-# CONFIG_USB_GADGET_XILINX is not set
-# CONFIG_USB_GL860 is not set
-# CONFIG_USB_GOKU is not set
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_USB_GR_UDC is not set
-# CONFIG_USB_GSPCA is not set
-# CONFIG_USB_GSPCA_BENQ is not set
-# CONFIG_USB_GSPCA_CONEX is not set
-# CONFIG_USB_GSPCA_CPIA1 is not set
-# CONFIG_USB_GSPCA_DTCS033 is not set
-# CONFIG_USB_GSPCA_ETOMS is not set
-# CONFIG_USB_GSPCA_FINEPIX is not set
-# CONFIG_USB_GSPCA_JEILINJ is not set
-# CONFIG_USB_GSPCA_JL2005BCD is not set
-# CONFIG_USB_GSPCA_KINECT is not set
-# CONFIG_USB_GSPCA_KONICA is not set
-# CONFIG_USB_GSPCA_MARS is not set
-# CONFIG_USB_GSPCA_MR97310A is not set
-# CONFIG_USB_GSPCA_NW80X is not set
-# CONFIG_USB_GSPCA_OV519 is not set
-# CONFIG_USB_GSPCA_OV534 is not set
-# CONFIG_USB_GSPCA_OV534_9 is not set
-# CONFIG_USB_GSPCA_PAC207 is not set
-# CONFIG_USB_GSPCA_PAC7302 is not set
-# CONFIG_USB_GSPCA_PAC7311 is not set
-# CONFIG_USB_GSPCA_SE401 is not set
-# CONFIG_USB_GSPCA_SN9C2028 is not set
-# CONFIG_USB_GSPCA_SN9C20X is not set
-# CONFIG_USB_GSPCA_SONIXB is not set
-# CONFIG_USB_GSPCA_SONIXJ is not set
-# CONFIG_USB_GSPCA_SPCA1528 is not set
-# CONFIG_USB_GSPCA_SPCA500 is not set
-# CONFIG_USB_GSPCA_SPCA501 is not set
-# CONFIG_USB_GSPCA_SPCA505 is not set
-# CONFIG_USB_GSPCA_SPCA506 is not set
-# CONFIG_USB_GSPCA_SPCA508 is not set
-# CONFIG_USB_GSPCA_SPCA561 is not set
-# CONFIG_USB_GSPCA_SQ905 is not set
-# CONFIG_USB_GSPCA_SQ905C is not set
-# CONFIG_USB_GSPCA_SQ930X is not set
-# CONFIG_USB_GSPCA_STK014 is not set
-# CONFIG_USB_GSPCA_STK1135 is not set
-# CONFIG_USB_GSPCA_STV0680 is not set
-# CONFIG_USB_GSPCA_SUNPLUS is not set
-# CONFIG_USB_GSPCA_T613 is not set
-# CONFIG_USB_GSPCA_TOPRO is not set
-# CONFIG_USB_GSPCA_TOUPTEK is not set
-# CONFIG_USB_GSPCA_TV8532 is not set
-# CONFIG_USB_GSPCA_VC032X is not set
-# CONFIG_USB_GSPCA_VICAM is not set
-# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
-# CONFIG_USB_GSPCA_ZC3XX is not set
-# CONFIG_USB_G_ACM_MS is not set
-# CONFIG_USB_G_DBGP is not set
-# CONFIG_USB_G_HID is not set
-# CONFIG_USB_G_MULTI is not set
-# CONFIG_USB_G_NCM is not set
-# CONFIG_USB_G_NOKIA is not set
-# CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_G_WEBCAM is not set
-# CONFIG_USB_HACKRF is not set
-# CONFIG_USB_HCD_TEST_MODE is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_HSIC_USB3503 is not set
-# CONFIG_USB_HSIC_USB4604 is not set
-# CONFIG_USB_HSO is not set
-# CONFIG_USB_HUB_USB251XB is not set
-# CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_IMX21_HCD is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_IPHETH is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1301 is not set
-# CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_ISP1760 is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_KC2190 is not set
-# CONFIG_USB_LAN78XX is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set
-# CONFIG_USB_LED_TRIG is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LGM_PHY is not set
-# CONFIG_USB_LINK_LAYER_TEST is not set
-# CONFIG_USB_M5602 is not set
-# CONFIG_USB_M66592 is not set
-# CONFIG_USB_MASS_STORAGE is not set
-# CONFIG_USB_MAX3420_UDC is not set
-# CONFIG_USB_MAX3421_HCD is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_USB_MON is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_MSI2500 is not set
-# CONFIG_USB_MSM_OTG is not set
-# CONFIG_USB_MTU3 is not set
-# CONFIG_USB_MUSB_GADGET is not set
-# CONFIG_USB_MUSB_HDRC is not set
-# CONFIG_USB_MUSB_HOST is not set
-# CONFIG_USB_MV_U3D is not set
-# CONFIG_USB_MV_UDC is not set
-# CONFIG_USB_MXS_PHY is not set
-# CONFIG_USB_NET2272 is not set
-# CONFIG_USB_NET2280 is not set
-# CONFIG_USB_NET_AQC111 is not set
-# CONFIG_USB_NET_AX88179_178A is not set
-# CONFIG_USB_NET_AX8817X is not set
-# CONFIG_USB_NET_CDCETHER is not set
-# CONFIG_USB_NET_CDC_EEM is not set
-# CONFIG_USB_NET_CDC_MBIM is not set
-# CONFIG_USB_NET_CDC_NCM is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-# CONFIG_USB_NET_CH9200 is not set
-# CONFIG_USB_NET_CX82310_ETH is not set
-# CONFIG_USB_NET_DM9601 is not set
-# CONFIG_USB_NET_DRIVERS is not set
-# CONFIG_USB_NET_GL620A is not set
-# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
-# CONFIG_USB_NET_INT51X1 is not set
-# CONFIG_USB_NET_KALMIA is not set
-# CONFIG_USB_NET_MCS7830 is not set
-# CONFIG_USB_NET_NET1080 is not set
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_QMI_WWAN is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_USB_NET_SMSC75XX is not set
-# CONFIG_USB_NET_SMSC95XX is not set
-# CONFIG_USB_NET_SR9700 is not set
-# CONFIG_USB_NET_SR9800 is not set
-# CONFIG_USB_NET_ZAURUS is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_OHCI_HCD_PCI is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
-# CONFIG_USB_OHCI_HCD_SSB is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_OTG is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set
-# CONFIG_USB_OTG_FSM is not set
-# CONFIG_USB_OTG_PRODUCTLIST is not set
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_PCI is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_PHY is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_PWC_INPUT_EVDEV is not set
-# CONFIG_USB_PXA27X is not set
-# CONFIG_USB_R8A66597 is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_RAW_GADGET is not set
-# CONFIG_USB_RCAR_PHY is not set
-# CONFIG_USB_RENESAS_USBHS is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ROLES_INTEL_XHCI is not set
-# CONFIG_USB_ROLE_SWITCH is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_RTL8152 is not set
-# CONFIG_USB_RTL8153_ECM is not set
-# CONFIG_USB_S2255 is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_ARK3116 is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_CH341 is not set
-# CONFIG_USB_SERIAL_CP210X is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
-# CONFIG_USB_SERIAL_DEBUG is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_F81232 is not set
-# CONFIG_USB_SERIAL_F8153X is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_GARMIN is not set
-CONFIG_USB_SERIAL_GENERIC=y
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IPW is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_IUU is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-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_KLSI is not set
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_METRO is not set
-# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set
-# CONFIG_USB_SERIAL_MOS7720 is not set
-# CONFIG_USB_SERIAL_MOS7840 is not set
-# CONFIG_USB_SERIAL_MXUPORT is not set
-# CONFIG_USB_SERIAL_NAVMAN is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_SERIAL_OPTICON is not set
-# CONFIG_USB_SERIAL_OPTION is not set
-# CONFIG_USB_SERIAL_OTI6858 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_QCAUX is not set
-# CONFIG_USB_SERIAL_QT2 is not set
-# CONFIG_USB_SERIAL_QUALCOMM is not set
-# CONFIG_USB_SERIAL_SAFE is not set
-CONFIG_USB_SERIAL_SAFE_PADDED=y
-# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
-# CONFIG_USB_SERIAL_SIMPLE is not set
-# CONFIG_USB_SERIAL_SPCP8X5 is not set
-# CONFIG_USB_SERIAL_SSU100 is not set
-# CONFIG_USB_SERIAL_SYMBOL is not set
-# CONFIG_USB_SERIAL_TI is not set
-# CONFIG_USB_SERIAL_UPD78F0730 is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_WISHBONE is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_XR is not set
-# CONFIG_USB_SERIAL_XSENS_MT is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_SIERRA_NET is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_SNP_UDC_PLAT is not set
-# CONFIG_USB_SPEEDTOUCH is not set
-# CONFIG_USB_STKWEBCAM is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_ENE_UB6250 is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_REALTEK is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STV06XX is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_USB_SWITCH_FSA9480 is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_TMC is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_UAS is not set
-# CONFIG_USB_UEAGLEATM is not set
-# CONFIG_USB_ULPI is not set
-# CONFIG_USB_ULPI_BUS is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-# CONFIG_USB_VIDEO_CLASS is not set
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-# CONFIG_USB_VL600 is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-# CONFIG_USB_XHCI_DBGCAP is not set
-# CONFIG_USB_XHCI_HCD is not set
-# CONFIG_USB_XHCI_MVEBU is not set
-# CONFIG_USB_XHCI_PCI_RENESAS is not set
-# CONFIG_USB_XUSBATM is not set
-# CONFIG_USB_YUREX is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_ZERO is not set
-# CONFIG_USB_ZR364XX is not set
-# CONFIG_USELIB is not set
-# CONFIG_USERFAULTFD is not set
-# CONFIG_USERIO is not set
-# CONFIG_USE_OF is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_UWB is not set
-# CONFIG_U_SERIAL_CONSOLE is not set
-# CONFIG_V4L_MEM2MEM_DRIVERS is not set
-# CONFIG_V4L_PLATFORM_DRIVERS is not set
-# CONFIG_V4L_TEST_DRIVERS is not set
-# CONFIG_VALIDATE_FS_PARSER is not set
-# CONFIG_VBOXGUEST is not set
-# CONFIG_VCNL3020 is not set
-# CONFIG_VCNL4000 is not set
-# CONFIG_VCNL4035 is not set
-# CONFIG_VDPA is not set
-CONFIG_VDSO=y
-# CONFIG_VEML6030 is not set
-# CONFIG_VEML6070 is not set
-# CONFIG_VETH is not set
-# CONFIG_VEXPRESS_CONFIG is not set
-# CONFIG_VF610_ADC is not set
-# CONFIG_VF610_DAC is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_VFIO is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VGA_ARB is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_VGA_SWITCHEROO is not set
-# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set
-CONFIG_VHOST_MENU=y
-# CONFIG_VHOST_NET is not set
-# CONFIG_VHOST_VSOCK is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_VIDEO_AD5398 is not set
-# CONFIG_VIDEO_AD5820 is not set
-# CONFIG_VIDEO_AD9389B is not set
-# CONFIG_VIDEO_ADP1653 is not set
-# CONFIG_VIDEO_ADV7170 is not set
-# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_ADV7180 is not set
-# CONFIG_VIDEO_ADV7183 is not set
-# CONFIG_VIDEO_ADV7343 is not set
-# CONFIG_VIDEO_ADV7393 is not set
-# CONFIG_VIDEO_ADV748X is not set
-# CONFIG_VIDEO_ADV7511 is not set
-# CONFIG_VIDEO_ADV7604 is not set
-# CONFIG_VIDEO_ADV7842 is not set
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_AK7375 is not set
-# CONFIG_VIDEO_AK881X is not set
-# CONFIG_VIDEO_AM437X_VPFE is not set
-# CONFIG_VIDEO_ASPEED is not set
-# CONFIG_VIDEO_ATMEL_ISC is not set
-# CONFIG_VIDEO_ATMEL_ISI is not set
-# CONFIG_VIDEO_AU0828 is not set
-# CONFIG_VIDEO_BT819 is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_BT856 is not set
-# CONFIG_VIDEO_BT866 is not set
-# CONFIG_VIDEO_CADENCE is not set
-# CONFIG_VIDEO_CAFE_CCIC is not set
-# CONFIG_VIDEO_CCS is not set
-# CONFIG_VIDEO_COBALT is not set
-# CONFIG_VIDEO_CODA is not set
-# CONFIG_VIDEO_CS3308 is not set
-# CONFIG_VIDEO_CS5345 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_CX231XX is not set
-# CONFIG_VIDEO_CX2341X is not set
-# CONFIG_VIDEO_CX25821 is not set
-# CONFIG_VIDEO_CX25840 is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_DM6446_CCDC is not set
-# CONFIG_VIDEO_DT3155 is not set
-# CONFIG_VIDEO_DW9714 is not set
-# CONFIG_VIDEO_DW9768 is not set
-# CONFIG_VIDEO_DW9807_VCM is not set
-# CONFIG_VIDEO_EM28XX is not set
-# CONFIG_VIDEO_ET8EK8 is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-# CONFIG_VIDEO_GO7007 is not set
-# CONFIG_VIDEO_GS1662 is not set
-# CONFIG_VIDEO_HDPVR is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HI556 is not set
-# CONFIG_VIDEO_I2C is not set
-# CONFIG_VIDEO_IMX208 is not set
-# CONFIG_VIDEO_IMX214 is not set
-# CONFIG_VIDEO_IMX219 is not set
-# CONFIG_VIDEO_IMX258 is not set
-# CONFIG_VIDEO_IMX274 is not set
-# CONFIG_VIDEO_IMX290 is not set
-# CONFIG_VIDEO_IMX319 is not set
-# CONFIG_VIDEO_IMX334 is not set
-# CONFIG_VIDEO_IMX335 is not set
-# CONFIG_VIDEO_IMX355 is not set
-# CONFIG_VIDEO_IMX412 is not set
-# CONFIG_VIDEO_IMX477 is not set
-# CONFIG_VIDEO_IMX8_JPEG is not set
-# CONFIG_VIDEO_IMX_PXP is not set
-# CONFIG_VIDEO_IPU3_CIO2 is not set
-# CONFIG_VIDEO_IRS1125 is not set
-# CONFIG_VIDEO_IR_I2C is not set
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_LM3560 is not set
-# CONFIG_VIDEO_LM3646 is not set
-# CONFIG_VIDEO_M52790 is not set
-# CONFIG_VIDEO_M5MOLS is not set
-# CONFIG_VIDEO_MAX9286 is not set
-# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
-# CONFIG_VIDEO_ML86V7667 is not set
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_MT9M001 is not set
-# CONFIG_VIDEO_MT9M032 is not set
-# CONFIG_VIDEO_MT9M111 is not set
-# CONFIG_VIDEO_MT9P031 is not set
-# CONFIG_VIDEO_MT9T001 is not set
-# CONFIG_VIDEO_MT9T112 is not set
-# CONFIG_VIDEO_MT9V011 is not set
-# CONFIG_VIDEO_MT9V032 is not set
-# CONFIG_VIDEO_MT9V111 is not set
-# CONFIG_VIDEO_MUX is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_NOON010PC30 is not set
-# CONFIG_VIDEO_OMAP2_VOUT is not set
-# CONFIG_VIDEO_OV02A10 is not set
-# CONFIG_VIDEO_OV13858 is not set
-# CONFIG_VIDEO_OV2311 is not set
-# CONFIG_VIDEO_OV2640 is not set
-# CONFIG_VIDEO_OV2659 is not set
-# CONFIG_VIDEO_OV2680 is not set
-# CONFIG_VIDEO_OV2685 is not set
-# CONFIG_VIDEO_OV2740 is not set
-# CONFIG_VIDEO_OV5640 is not set
-# CONFIG_VIDEO_OV5645 is not set
-# CONFIG_VIDEO_OV5647 is not set
-# CONFIG_VIDEO_OV5648 is not set
-# CONFIG_VIDEO_OV5670 is not set
-# CONFIG_VIDEO_OV5675 is not set
-# CONFIG_VIDEO_OV5695 is not set
-# CONFIG_VIDEO_OV6650 is not set
-# CONFIG_VIDEO_OV7251 is not set
-# CONFIG_VIDEO_OV7640 is not set
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_OV772X is not set
-# CONFIG_VIDEO_OV7740 is not set
-# CONFIG_VIDEO_OV8856 is not set
-# CONFIG_VIDEO_OV8865 is not set
-# CONFIG_VIDEO_OV9281 is not set
-# CONFIG_VIDEO_OV9282 is not set
-# CONFIG_VIDEO_OV9640 is not set
-# CONFIG_VIDEO_OV9650 is not set
-# CONFIG_VIDEO_OV9734 is not set
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_RDACM20 is not set
-# CONFIG_VIDEO_RDACM21 is not set
-# CONFIG_VIDEO_RJ54N1 is not set
-# CONFIG_VIDEO_ROCKCHIP_ISP1 is not set
-# CONFIG_VIDEO_S5C73M3 is not set
-# CONFIG_VIDEO_S5K4ECGX is not set
-# CONFIG_VIDEO_S5K5BAF is not set
-# CONFIG_VIDEO_S5K6A3 is not set
-# CONFIG_VIDEO_S5K6AA is not set
-# CONFIG_VIDEO_SAA6588 is not set
-# CONFIG_VIDEO_SAA6752HS is not set
-# CONFIG_VIDEO_SAA7110 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_SAA7164 is not set
-# CONFIG_VIDEO_SAA717X is not set
-# CONFIG_VIDEO_SAA7185 is not set
-# CONFIG_VIDEO_SH_MOBILE_CEU is not set
-# CONFIG_VIDEO_SMIAPP is not set
-# CONFIG_VIDEO_SOLO6X10 is not set
-# CONFIG_VIDEO_SONY_BTF_MPX is not set
-# CONFIG_VIDEO_SR030PC30 is not set
-# CONFIG_VIDEO_STK1160_COMMON is not set
-# CONFIG_VIDEO_ST_MIPID02 is not set
-# CONFIG_VIDEO_TC358743 is not set
-# CONFIG_VIDEO_TDA1997X is not set
-# CONFIG_VIDEO_TDA7432 is not set
-# CONFIG_VIDEO_TDA9840 is not set
-# CONFIG_VIDEO_TEA6415C is not set
-# CONFIG_VIDEO_TEA6420 is not set
-# CONFIG_VIDEO_THS7303 is not set
-# CONFIG_VIDEO_THS8200 is not set
-# CONFIG_VIDEO_TIMBERDALE is not set
-# CONFIG_VIDEO_TLV320AIC23B is not set
-# CONFIG_VIDEO_TM6000 is not set
-# CONFIG_VIDEO_TVAUDIO is not set
-# CONFIG_VIDEO_TVP514X is not set
-# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_TVP7002 is not set
-# CONFIG_VIDEO_TW2804 is not set
-# CONFIG_VIDEO_TW5864 is not set
-# CONFIG_VIDEO_TW68 is not set
-# CONFIG_VIDEO_TW9903 is not set
-# CONFIG_VIDEO_TW9906 is not set
-# CONFIG_VIDEO_TW9910 is not set
-# CONFIG_VIDEO_UDA1342 is not set
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
-# CONFIG_VIDEO_USBTV is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_VIDEO_V4L2 is not set
-# CONFIG_VIDEO_VP27SMPX is not set
-# CONFIG_VIDEO_VPX3220 is not set
-# CONFIG_VIDEO_VS6624 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_XILINX is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIRTIO_BALLOON is not set
-# CONFIG_VIRTIO_BLK_SCSI is not set
-# CONFIG_VIRTIO_CONSOLE is not set
-# CONFIG_VIRTIO_FS is not set
-# CONFIG_VIRTIO_INPUT is not set
-# CONFIG_VIRTIO_IOMMU is not set
-CONFIG_VIRTIO_MENU=y
-# CONFIG_VIRTIO_MMIO is not set
-# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
-# CONFIG_VIRTIO_PCI is not set
-# CONFIG_VIRTUALIZATION is not set
-# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
-# CONFIG_VIRT_DRIVERS is not set
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_VL53L0X_I2C is not set
-# CONFIG_VL6180 is not set
-CONFIG_VLAN_8021Q=y
-# CONFIG_VLAN_8021Q_GVRP is not set
-# CONFIG_VLAN_8021Q_MVRP is not set
-# CONFIG_VME_BUS is not set
-# CONFIG_VMLINUX_MAP is not set
-# CONFIG_VMSPLIT_1G is not set
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_2G_OPT is not set
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_3G_OPT is not set
-# CONFIG_VMWARE_PVSCSI is not set
-# CONFIG_VMXNET3 is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_VOP_BUS is not set
-# CONFIG_VORTEX is not set
-# CONFIG_VSOCKETS is not set
-# CONFIG_VSOCKETS_DIAG is not set
-# CONFIG_VT is not set
-# CONFIG_VT6655 is not set
-# CONFIG_VT6656 is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_VXGE is not set
-# CONFIG_VXLAN is not set
-# CONFIG_VZ89X is not set
-# CONFIG_W1 is not set
-# CONFIG_W1_CON is not set
-# CONFIG_W1_MASTER_DS1WM is not set
-# CONFIG_W1_MASTER_DS2482 is not set
-# CONFIG_W1_MASTER_DS2490 is not set
-# CONFIG_W1_MASTER_GPIO is not set
-# CONFIG_W1_MASTER_MATROX is not set
-# CONFIG_W1_MASTER_SGI is not set
-# CONFIG_W1_SLAVE_DS2405 is not set
-# CONFIG_W1_SLAVE_DS2406 is not set
-# CONFIG_W1_SLAVE_DS2408 is not set
-# CONFIG_W1_SLAVE_DS2413 is not set
-# CONFIG_W1_SLAVE_DS2423 is not set
-# CONFIG_W1_SLAVE_DS2430 is not set
-# CONFIG_W1_SLAVE_DS2431 is not set
-# CONFIG_W1_SLAVE_DS2433 is not set
-# CONFIG_W1_SLAVE_DS2438 is not set
-# CONFIG_W1_SLAVE_DS250X is not set
-# CONFIG_W1_SLAVE_DS2780 is not set
-# CONFIG_W1_SLAVE_DS2781 is not set
-# CONFIG_W1_SLAVE_DS2805 is not set
-# CONFIG_W1_SLAVE_DS28E04 is not set
-# CONFIG_W1_SLAVE_DS28E17 is not set
-# CONFIG_W1_SLAVE_SMEM is not set
-# CONFIG_W1_SLAVE_THERM is not set
-# CONFIG_W83627HF_WDT is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_W83977F_WDT is not set
-# CONFIG_WAN is not set
-# CONFIG_WANXL is not set
-# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_CORE is not set
-CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
-# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-CONFIG_WATCHDOG_OPEN_TIMEOUT=0
-# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set
-# CONFIG_WATCHDOG_SYSFS is not set
-# CONFIG_WATCH_QUEUE is not set
-# CONFIG_WD80x3 is not set
-# CONFIG_WDAT_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_WERROR is not set
-# CONFIG_WEXT_CORE is not set
-# CONFIG_WEXT_PRIV is not set
-# CONFIG_WEXT_PROC is not set
-# CONFIG_WEXT_SPY is not set
-CONFIG_WILINK_PLATFORM_DATA=y
-# CONFIG_WIMAX is not set
-# CONFIG_WIREGUARD is not set
-CONFIG_WIRELESS=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_WIRELESS_WDS is not set
-# CONFIG_WIZNET_W5100 is not set
-# CONFIG_WIZNET_W5300 is not set
-# CONFIG_WL1251 is not set
-# CONFIG_WL12XX is not set
-# CONFIG_WL18XX is not set
-CONFIG_WLAN=y
-# CONFIG_WLAN_VENDOR_ADMTEK is not set
-# CONFIG_WLAN_VENDOR_ATH is not set
-# CONFIG_WLAN_VENDOR_ATMEL 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_MARVELL is not set
-# CONFIG_WLAN_VENDOR_MEDIATEK is not set
-# CONFIG_WLAN_VENDOR_MICROCHIP is not set
-# CONFIG_WLAN_VENDOR_QUANTENNA is not set
-# CONFIG_WLAN_VENDOR_RALINK is not set
-# CONFIG_WLAN_VENDOR_REALTEK 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_WLCORE is not set
-CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
-# CONFIG_WQ_WATCHDOG is not set
-# CONFIG_WWAN is not set
-# CONFIG_WWAN_HWSIM is not set
-# CONFIG_WW_MUTEX_SELFTEST is not set
-# CONFIG_X25 is not set
-# CONFIG_X509_CERTIFICATE_PARSER is not set
-# CONFIG_X86_PKG_TEMP_THERMAL is not set
-CONFIG_X86_SYSFB=y
-# CONFIG_XDP_SOCKETS is not set
-# CONFIG_XEN is not set
-# CONFIG_XEN_GRANT_DMA_ALLOC is not set
-# CONFIG_XEN_PVCALLS_FRONTEND is not set
-CONFIG_XEN_SCRUB_PAGES_DEFAULT=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_INTERFACE is not set
-# CONFIG_XFRM_IPCOMP is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_ONLINE_SCRUB is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_SUPPORT_V4 is not set
-# CONFIG_XFS_WARN is not set
-# CONFIG_XILINX_AXI_EMAC is not set
-# CONFIG_XILINX_DMA is not set
-# CONFIG_XILINX_EMACLITE is not set
-# CONFIG_XILINX_GMII2RGMII is not set
-# CONFIG_XILINX_LL_TEMAC is not set
-# CONFIG_XILINX_SDFEC is not set
-# CONFIG_XILINX_VCU is not set
-# CONFIG_XILINX_WATCHDOG is not set
-# CONFIG_XILINX_XADC is not set
-# CONFIG_XILINX_ZYNQMP_DMA is not set
-# CONFIG_XILINX_ZYNQMP_DPDMA is not set
-# CONFIG_XILLYBUS is not set
-# CONFIG_XILLYUSB is not set
-# CONFIG_XIL_AXIS_FIFO is not set
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_XMON is not set
-CONFIG_XZ_DEC=y
-# CONFIG_XZ_DEC_ARM is not set
-# CONFIG_XZ_DEC_ARMTHUMB is not set
-# CONFIG_XZ_DEC_BCJ is not set
-# CONFIG_XZ_DEC_IA64 is not set
-# CONFIG_XZ_DEC_POWERPC is not set
-# CONFIG_XZ_DEC_SPARC is not set
-# CONFIG_XZ_DEC_TEST is not set
-# CONFIG_XZ_DEC_X86 is not set
-# CONFIG_YAM is not set
-# CONFIG_YAMAHA_YAS530 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_YENTA is not set
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-# CONFIG_YENTA_TI is not set
-# CONFIG_YENTA_TOSHIBA is not set
-# CONFIG_ZBUD is not set
-# CONFIG_ZD1211RW is not set
-# CONFIG_ZD1211RW_DEBUG is not set
-# CONFIG_ZEROPLUS_FF is not set
-# CONFIG_ZERO_CALL_USED_REGS is not set
-# CONFIG_ZIIRAVE_WATCHDOG is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_ZLIB_DEFLATE is not set
-# CONFIG_ZLIB_INFLATE is not set
-CONFIG_ZONE_DMA=y
-# CONFIG_ZOPT2201 is not set
-# CONFIG_ZPA2326 is not set
-# CONFIG_ZPOOL is not set
-# CONFIG_ZRAM is not set
-# CONFIG_ZRAM_DEF_COMP_842 is not set
-# CONFIG_ZRAM_DEF_COMP_LZ4 is not set
-# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set
-# CONFIG_ZRAM_DEF_COMP_LZO is not set
-# CONFIG_ZRAM_DEF_COMP_LZORLE is not set
-# CONFIG_ZRAM_DEF_COMP_ZSTD is not set
-# CONFIG_ZRAM_MEMORY_TRACKING is not set
-# CONFIG_ZSMALLOC is not set
-# CONFIG_ZX_TDM is not set
diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1
deleted file mode 100644
index 70e87665b7..0000000000
--- a/target/linux/generic/config-6.1
+++ /dev/null
@@ -1,7947 +0,0 @@
-# CONFIG_104_QUAD_8 is not set
-CONFIG_32BIT=y
-CONFIG_64BIT_TIME=y
-# CONFIG_6LOWPAN is not set
-# CONFIG_6LOWPAN_DEBUGFS is not set
-# CONFIG_6PACK is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_9P_FS is not set
-# CONFIG_AB3100_CORE is not set
-# CONFIG_AB8500_CORE is not set
-# CONFIG_ABP060MG is not set
-# CONFIG_ABX500_CORE is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_ACENIC is not set
-# CONFIG_ACERHDF is not set
-# CONFIG_ACER_WIRELESS is not set
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_ACPI_ALS is not set
-# CONFIG_ACPI_APEI is not set
-# CONFIG_ACPI_APEI_PCIEAER is not set
-# CONFIG_ACPI_BUTTON is not set
-# CONFIG_ACPI_CONFIGFS is not set
-# CONFIG_ACPI_CUSTOM_METHOD is not set
-# CONFIG_ACPI_EXTLOG is not set
-# CONFIG_ACPI_HED is not set
-# CONFIG_ACPI_NFIT is not set
-# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
-# CONFIG_ACPI_TABLE_UPGRADE is not set
-# CONFIG_ACPI_VIDEO is not set
-# CONFIG_AD2S1200 is not set
-# CONFIG_AD2S1210 is not set
-# CONFIG_AD2S90 is not set
-# CONFIG_AD3552R is not set
-# CONFIG_AD5064 is not set
-# CONFIG_AD5110 is not set
-# CONFIG_AD525X_DPOT is not set
-# CONFIG_AD5272 is not set
-# CONFIG_AD5360 is not set
-# CONFIG_AD5380 is not set
-# CONFIG_AD5421 is not set
-# CONFIG_AD5446 is not set
-# CONFIG_AD5449 is not set
-# CONFIG_AD5504 is not set
-# CONFIG_AD5592R is not set
-# CONFIG_AD5593R is not set
-# CONFIG_AD5624R_SPI is not set
-# CONFIG_AD5686 is not set
-# CONFIG_AD5686_SPI is not set
-# CONFIG_AD5696_I2C is not set
-# CONFIG_AD5755 is not set
-# CONFIG_AD5758 is not set
-# CONFIG_AD5761 is not set
-# CONFIG_AD5764 is not set
-# CONFIG_AD5766 is not set
-# CONFIG_AD5770R is not set
-# CONFIG_AD5791 is not set
-# CONFIG_AD5933 is not set
-# CONFIG_AD7091R5 is not set
-# CONFIG_AD7124 is not set
-# CONFIG_AD7150 is not set
-# CONFIG_AD7152 is not set
-# CONFIG_AD7192 is not set
-# CONFIG_AD7266 is not set
-# CONFIG_AD7280 is not set
-# CONFIG_AD7291 is not set
-# CONFIG_AD7292 is not set
-# CONFIG_AD7293 is not set
-# CONFIG_AD7298 is not set
-# CONFIG_AD7303 is not set
-# CONFIG_AD74413R is not set
-# CONFIG_AD7476 is not set
-# CONFIG_AD7606 is not set
-# CONFIG_AD7606_IFACE_PARALLEL is not set
-# CONFIG_AD7606_IFACE_SPI is not set
-# CONFIG_AD7746 is not set
-# CONFIG_AD7766 is not set
-# CONFIG_AD7768_1 is not set
-# CONFIG_AD7780 is not set
-# CONFIG_AD7791 is not set
-# CONFIG_AD7793 is not set
-# CONFIG_AD7816 is not set
-# CONFIG_AD7887 is not set
-# CONFIG_AD7923 is not set
-# CONFIG_AD7949 is not set
-# CONFIG_AD799X is not set
-# CONFIG_AD8366 is not set
-# CONFIG_AD8801 is not set
-# CONFIG_AD9467 is not set
-# CONFIG_AD9523 is not set
-# CONFIG_AD9832 is not set
-# CONFIG_AD9834 is not set
-# CONFIG_ADA4250 is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ADE7854 is not set
-# CONFIG_ADF4350 is not set
-# CONFIG_ADF4371 is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADIN1100_PHY is not set
-# CONFIG_ADIN1110 is not set
-# CONFIG_ADIN_PHY is not set
-# CONFIG_ADIS16080 is not set
-# CONFIG_ADIS16130 is not set
-# CONFIG_ADIS16136 is not set
-# CONFIG_ADIS16201 is not set
-# CONFIG_ADIS16203 is not set
-# CONFIG_ADIS16209 is not set
-# CONFIG_ADIS16240 is not set
-# CONFIG_ADIS16260 is not set
-# CONFIG_ADIS16400 is not set
-# CONFIG_ADIS16460 is not set
-# CONFIG_ADIS16475 is not set
-# CONFIG_ADIS16480 is not set
-# CONFIG_ADI_AXI_ADC is not set
-# CONFIG_ADJD_S311 is not set
-# CONFIG_ADM6996_PHY is not set
-# CONFIG_ADM8211 is not set
-# CONFIG_ADMV1013 is not set
-# CONFIG_ADMV1014 is not set
-# CONFIG_ADMV4420 is not set
-# CONFIG_ADMV8818 is not set
-# CONFIG_ADRF6780 is not set
-# CONFIG_ADT7316 is not set
-# CONFIG_ADUX1020 is not set
-CONFIG_ADVISE_SYSCALLS=y
-# CONFIG_ADXL313_I2C is not set
-# CONFIG_ADXL313_SPI is not set
-# CONFIG_ADXL345_I2C is not set
-# CONFIG_ADXL345_SPI is not set
-# CONFIG_ADXL355_I2C is not set
-# CONFIG_ADXL355_SPI is not set
-# CONFIG_ADXL367_I2C is not set
-# CONFIG_ADXL367_SPI is not set
-# CONFIG_ADXL372_I2C is not set
-# CONFIG_ADXL372_SPI is not set
-# CONFIG_ADXRS290 is not set
-# CONFIG_ADXRS450 is not set
-CONFIG_AEABI=y
-# CONFIG_AFE4403 is not set
-# CONFIG_AFE4404 is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_AFS_DEBUG_CURSOR is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_AF_KCM is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_AF_RXRPC_INJECT_LOSS is not set
-# CONFIG_AF_RXRPC_IPV6 is not set
-CONFIG_AF_UNIX_OOB=y
-# CONFIG_AGP is not set
-# CONFIG_AHCI_BRCM is not set
-# CONFIG_AHCI_CEVA is not set
-# CONFIG_AHCI_DWC is not set
-# CONFIG_AHCI_IMX is not set
-# CONFIG_AHCI_MVEBU is not set
-# CONFIG_AHCI_QORIQ is not set
-# CONFIG_AHCI_XGENE is not set
-CONFIG_AIO=y
-# CONFIG_AIRO is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_AIR_EN8811H_PHY is not set
-# CONFIG_AIX_PARTITION is not set
-# CONFIG_AK09911 is not set
-# CONFIG_AK8974 is not set
-# CONFIG_AK8975 is not set
-# CONFIG_AL3010 is not set
-# CONFIG_AL3320A is not set
-# CONFIG_ALIM7101_WDT is not set
-CONFIG_ALLOW_DEV_COREDUMP=y
-# CONFIG_ALTERA_MBOX is not set
-# CONFIG_ALTERA_MSGDMA is not set
-# CONFIG_ALTERA_STAPL is not set
-# CONFIG_ALTERA_TSE is not set
-# CONFIG_ALX is not set
-# CONFIG_AL_FIC is not set
-# CONFIG_AM2315 is not set
-# CONFIG_AM335X_PHY_USB is not set
-# CONFIG_AMBA_PL08X is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_AMD_MEM_ENCRYPT is not set
-# CONFIG_AMD_PHY is not set
-# CONFIG_AMD_XGBE is not set
-# CONFIG_AMD_XGBE_HAVE_ECC is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_AMILO_RFKILL is not set
-# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set
-# CONFIG_AMT is not set
-# CONFIG_ANDROID is not set
-# CONFIG_ANDROID_BINDER_IPC is not set
-CONFIG_ANON_INODES=y
-# CONFIG_ANON_VMA_NAME is not set
-# CONFIG_APDS9300 is not set
-# CONFIG_APDS9802ALS is not set
-# CONFIG_APDS9960 is not set
-# CONFIG_APM8018X is not set
-# CONFIG_APM_EMULATION is not set
-# CONFIG_APPLE_GMUX is not set
-# CONFIG_APPLE_MFI_FASTCHARGE is not set
-# CONFIG_APPLE_PROPERTIES is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_AQTION is not set
-# CONFIG_AQUANTIA_PHY is not set
-# CONFIG_AR5523 is not set
-# CONFIG_AR7 is not set
-# CONFIG_AR8216_PHY is not set
-# CONFIG_AR8216_PHY_LEDS is not set
-# CONFIG_ARCH_ACTIONS is not set
-# CONFIG_ARCH_AGILEX is not set
-# CONFIG_ARCH_AIROHA is not set
-# CONFIG_ARCH_ALPINE is not set
-# CONFIG_ARCH_APPLE is not set
-# CONFIG_ARCH_ARTPEC is not set
-# CONFIG_ARCH_ASPEED is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_AXXIA is not set
-# CONFIG_ARCH_BCM is not set
-# CONFIG_ARCH_BCM2835 is not set
-# CONFIG_ARCH_BCM4908 is not set
-# CONFIG_ARCH_BCMBCA is not set
-# CONFIG_ARCH_BCM_21664 is not set
-# CONFIG_ARCH_BCM_23550 is not set
-# CONFIG_ARCH_BCM_281XX is not set
-# CONFIG_ARCH_BCM_5301X is not set
-# CONFIG_ARCH_BCM_53573 is not set
-# CONFIG_ARCH_BCM_63XX is not set
-# CONFIG_ARCH_BCM_CYGNUS is not set
-# CONFIG_ARCH_BCM_HR2 is not set
-# CONFIG_ARCH_BCM_IPROC is not set
-# CONFIG_ARCH_BCM_NSP is not set
-# CONFIG_ARCH_BERLIN is not set
-CONFIG_ARCH_BINFMT_ELF_STATE=y
-# CONFIG_ARCH_BITMAIN is not set
-# CONFIG_ARCH_BRCMSTB is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CNS3XXX is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_DIGICOLOR is not set
-# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
-# CONFIG_ARCH_DOVE is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_EXYNOS is not set
-CONFIG_ARCH_FLATMEM_ENABLE=y
-# CONFIG_ARCH_FOOTBRIDGE is not set
-CONFIG_ARCH_FORCE_MAX_ORDER=11
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_HI3xxx is not set
-# CONFIG_ARCH_HIGHBANK is not set
-# CONFIG_ARCH_HISI is not set
-# CONFIG_ARCH_HPE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_INTEL_SOCFPGA is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_K3 is not set
-# CONFIG_ARCH_KEEMBAY is not set
-# CONFIG_ARCH_KEYSTONE is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_LAYERSCAPE is not set
-# CONFIG_ARCH_LG1K is not set
-# CONFIG_ARCH_LPC32XX is not set
-# CONFIG_ARCH_MEDIATEK is not set
-# CONFIG_ARCH_MESON is not set
-# CONFIG_ARCH_MILBEAUT is not set
-CONFIG_ARCH_MMAP_RND_BITS=8
-CONFIG_ARCH_MMAP_RND_BITS_MAX=16
-CONFIG_ARCH_MMAP_RND_BITS_MIN=8
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_MSTARV7 is not set
-# CONFIG_ARCH_MULTIPLATFORM is not set
-# CONFIG_ARCH_MULTI_V6 is not set
-# CONFIG_ARCH_MULTI_V7 is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MVEBU is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_MXS is not set
-# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_NOMADIK is not set
-# CONFIG_ARCH_NPCM is not set
-# CONFIG_ARCH_NSPIRE is not set
-# CONFIG_ARCH_NXP is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_OMAP1 is not set
-# CONFIG_ARCH_OMAP2 is not set
-# CONFIG_ARCH_OMAP2PLUS is not set
-# CONFIG_ARCH_OMAP3 is not set
-# CONFIG_ARCH_OMAP4 is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_OXNAS is not set
-# CONFIG_ARCH_PICOXCELL is not set
-# CONFIG_ARCH_PRIMA2 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_QCOM is not set
-# CONFIG_ARCH_RANDOM is not set
-# CONFIG_ARCH_RDA is not set
-# CONFIG_ARCH_REALTEK is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_RENESAS is not set
-# CONFIG_ARCH_ROCKCHIP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_S32 is not set
-# CONFIG_ARCH_S3C24XX is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5PV210 is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SEATTLE is not set
-# CONFIG_ARCH_SHMOBILE is not set
-# CONFIG_ARCH_SIRF is not set
-# CONFIG_ARCH_SOCFPGA is not set
-# CONFIG_ARCH_SPARX5 is not set
-# CONFIG_ARCH_SPRD is not set
-# CONFIG_ARCH_STI is not set
-# CONFIG_ARCH_STM32 is not set
-# CONFIG_ARCH_STRATIX10 is not set
-# CONFIG_ARCH_SUNPLUS is not set
-# CONFIG_ARCH_SUNXI is not set
-# CONFIG_ARCH_SYNQUACER is not set
-# CONFIG_ARCH_TANGO is not set
-# CONFIG_ARCH_TEGRA is not set
-# CONFIG_ARCH_THUNDER is not set
-# CONFIG_ARCH_THUNDER2 is not set
-# CONFIG_ARCH_U300 is not set
-# CONFIG_ARCH_U8500 is not set
-# CONFIG_ARCH_UNIPHIER is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_VEXPRESS is not set
-# CONFIG_ARCH_VIRT is not set
-# CONFIG_ARCH_VISCONTI is not set
-# CONFIG_ARCH_VT8500 is not set
-# CONFIG_ARCH_VULCAN is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_WANTS_THP_SWAP is not set
-# CONFIG_ARCH_WM8505 is not set
-# CONFIG_ARCH_WM8750 is not set
-# CONFIG_ARCH_WM8850 is not set
-# CONFIG_ARCH_XGENE is not set
-# CONFIG_ARCH_ZX is not set
-# CONFIG_ARCH_ZYNQ is not set
-# CONFIG_ARCH_ZYNQMP is not set
-# CONFIG_ARCNET is not set
-# CONFIG_ARC_EMAC is not set
-# CONFIG_ARC_IRQ_NO_AUTOSAVE is not set
-# CONFIG_ARM64_16K_PAGES is not set
-# CONFIG_ARM64_64K_PAGES is not set
-# CONFIG_ARM64_AMU_EXTN is not set
-# CONFIG_ARM64_BTI is not set
-# CONFIG_ARM64_CRYPTO is not set
-# CONFIG_ARM64_E0PD is not set
-# CONFIG_ARM64_ERRATUM_1024718 is not set
-# CONFIG_ARM64_ERRATUM_1165522 is not set
-# CONFIG_ARM64_ERRATUM_1286807 is not set
-# CONFIG_ARM64_ERRATUM_1319367 is not set
-# CONFIG_ARM64_ERRATUM_1418040 is not set
-# CONFIG_ARM64_ERRATUM_1463225 is not set
-# CONFIG_ARM64_ERRATUM_1508412 is not set
-# CONFIG_ARM64_ERRATUM_1530923 is not set
-# CONFIG_ARM64_ERRATUM_1542419 is not set
-# CONFIG_ARM64_ERRATUM_1742098 is not set
-# CONFIG_ARM64_ERRATUM_2051678 is not set
-# CONFIG_ARM64_ERRATUM_2054223 is not set
-# CONFIG_ARM64_ERRATUM_2067961 is not set
-# CONFIG_ARM64_ERRATUM_2077057 is not set
-# CONFIG_ARM64_ERRATUM_2441007 is not set
-# CONFIG_ARM64_ERRATUM_2441009 is not set
-# CONFIG_ARM64_ERRATUM_2658417 is not set
-# CONFIG_ARM64_ERRATUM_2966298 is not set
-# CONFIG_ARM64_ERRATUM_819472 is not set
-# CONFIG_ARM64_ERRATUM_824069 is not set
-# CONFIG_ARM64_ERRATUM_826319 is not set
-# CONFIG_ARM64_ERRATUM_827319 is not set
-# CONFIG_ARM64_ERRATUM_832075 is not set
-# CONFIG_ARM64_ERRATUM_834220 is not set
-# CONFIG_ARM64_ERRATUM_843419 is not set
-# CONFIG_ARM64_ERRATUM_845719 is not set
-# CONFIG_ARM64_ERRATUM_858921 is not set
-# CONFIG_ARM64_HW_AFDBM is not set
-# CONFIG_ARM64_LSE_ATOMICS is not set
-CONFIG_ARM64_MODULE_PLTS=y
-# CONFIG_ARM64_MTE is not set
-# CONFIG_ARM64_PAN is not set
-# CONFIG_ARM64_PMEM is not set
-# CONFIG_ARM64_PSEUDO_NMI is not set
-# CONFIG_ARM64_PTDUMP_DEBUGFS is not set
-# CONFIG_ARM64_PTR_AUTH is not set
-# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set
-# CONFIG_ARM64_RAS_EXTN is not set
-# CONFIG_ARM64_RELOC_TEST is not set
-# CONFIG_ARM64_SME is not set
-# CONFIG_ARM64_SVE is not set
-CONFIG_ARM64_SW_TTBR0_PAN=y
-# CONFIG_ARM64_TLB_RANGE is not set
-# CONFIG_ARM64_UAO is not set
-# CONFIG_ARM64_USE_LSE_ATOMICS is not set
-# CONFIG_ARM64_VA_BITS_48 is not set
-# CONFIG_ARM64_VHE is not set
-# CONFIG_ARM_APPENDED_DTB is not set
-# CONFIG_ARM_ARCH_TIMER is not set
-# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
-# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
-# CONFIG_ARM_CCI is not set
-# CONFIG_ARM_CCI400_PMU is not set
-# CONFIG_ARM_CCI5xx_PMU is not set
-# CONFIG_ARM_CCI_PMU is not set
-# CONFIG_ARM_CCN is not set
-# CONFIG_ARM_CMN is not set
-# CONFIG_ARM_CPUIDLE is not set
-CONFIG_ARM_CPU_TOPOLOGY=y
-# CONFIG_ARM_CRYPTO is not set
-CONFIG_ARM_DMA_MEM_BUFFERABLE=y
-# CONFIG_ARM_DSU_PMU is not set
-# CONFIG_ARM_ERRATA_326103 is not set
-# CONFIG_ARM_ERRATA_364296 is not set
-# CONFIG_ARM_ERRATA_411920 is not set
-# CONFIG_ARM_ERRATA_430973 is not set
-# CONFIG_ARM_ERRATA_458693 is not set
-# CONFIG_ARM_ERRATA_460075 is not set
-# CONFIG_ARM_ERRATA_643719 is not set
-# CONFIG_ARM_ERRATA_720789 is not set
-# CONFIG_ARM_ERRATA_742230 is not set
-# CONFIG_ARM_ERRATA_742231 is not set
-# CONFIG_ARM_ERRATA_743622 is not set
-# CONFIG_ARM_ERRATA_751472 is not set
-# CONFIG_ARM_ERRATA_754322 is not set
-# CONFIG_ARM_ERRATA_754327 is not set
-# CONFIG_ARM_ERRATA_764319 is not set
-# CONFIG_ARM_ERRATA_764369 is not set
-# CONFIG_ARM_ERRATA_773022 is not set
-# CONFIG_ARM_ERRATA_775420 is not set
-# CONFIG_ARM_ERRATA_798181 is not set
-# CONFIG_ARM_ERRATA_814220 is not set
-# CONFIG_ARM_ERRATA_818325_852422 is not set
-# CONFIG_ARM_ERRATA_821420 is not set
-# CONFIG_ARM_ERRATA_825619 is not set
-# CONFIG_ARM_ERRATA_852421 is not set
-# CONFIG_ARM_ERRATA_852423 is not set
-# CONFIG_ARM_ERRATA_857271 is not set
-# CONFIG_ARM_ERRATA_857272 is not set
-# CONFIG_ARM_FFA_TRANSPORT is not set
-CONFIG_ARM_GIC_MAX_NR=1
-# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
-# CONFIG_ARM_KPROBES_TEST is not set
-# CONFIG_ARM_LPAE is not set
-# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set
-# CONFIG_ARM_MHU is not set
-CONFIG_ARM_MODULE_PLTS=y
-# CONFIG_ARM_PATCH_PHYS_VIRT is not set
-# CONFIG_ARM_PSCI is not set
-# CONFIG_ARM_PSCI_CHECKER is not set
-# CONFIG_ARM_PSCI_CPUIDLE is not set
-# CONFIG_ARM_PTDUMP_DEBUGFS is not set
-# CONFIG_ARM_SBSA_WATCHDOG is not set
-# CONFIG_ARM_SCMI_PROTOCOL is not set
-# CONFIG_ARM_SCPI_PROTOCOL is not set
-# CONFIG_ARM_SDE_INTERFACE is not set
-# CONFIG_ARM_SMCCC_SOC_ID is not set
-# CONFIG_ARM_SMC_WATCHDOG is not set
-# CONFIG_ARM_SP805_WATCHDOG is not set
-# CONFIG_ARM_SPE_PMU is not set
-# CONFIG_ARM_THUMBEE is not set
-# CONFIG_ARM_TIMER_SP804 is not set
-# CONFIG_ARM_UNWIND is not set
-# CONFIG_ARM_VIRT_EXT is not set
-# CONFIG_AS3935 is not set
-# CONFIG_AS73211 is not set
-# CONFIG_ASM9260_TIMER is not set
-# CONFIG_ASN1 is not set
-# CONFIG_ASUS_LAPTOP is not set
-# CONFIG_ASUS_WIRELESS is not set
-# CONFIG_ASYMMETRIC_KEY_TYPE is not set
-# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set
-# CONFIG_ASYNC_RAID6_TEST is not set
-# CONFIG_ASYNC_TX_DMA is not set
-# CONFIG_AT76C50X_USB is not set
-# CONFIG_AT803X_PHY is not set
-# CONFIG_AT91_SAMA5D2_ADC is not set
-# CONFIG_ATA is not set
-# CONFIG_ATAGS is not set
-CONFIG_ATAGS_PROC=y
-# CONFIG_ATALK is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_ATA_ACPI is not set
-CONFIG_ATA_BMDMA=y
-# CONFIG_ATA_FORCE is not set
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_ATA_LEDS is not set
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_ATA_PIIX is not set
-CONFIG_ATA_SFF=y
-# CONFIG_ATA_VERBOSE_ERROR is not set
-# CONFIG_ATH10K is not set
-# CONFIG_ATH25 is not set
-# CONFIG_ATH5K is not set
-# CONFIG_ATH6KL is not set
-# CONFIG_ATH79 is not set
-# CONFIG_ATH9K is not set
-# CONFIG_ATH9K_HTC is not set
-# CONFIG_ATH_DEBUG is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1C is not set
-# CONFIG_ATL1E is not set
-# CONFIG_ATL2 is not set
-# CONFIG_ATLAS_EZO_SENSOR is not set
-# CONFIG_ATLAS_PH_SENSOR is not set
-# CONFIG_ATM is not set
-# CONFIG_ATMEL is not set
-# CONFIG_ATMEL_PIT is not set
-# CONFIG_ATMEL_SSC is not set
-# CONFIG_ATM_AMBASSADOR is not set
-# CONFIG_ATM_BR2684 is not set
-CONFIG_ATM_BR2684_IPFILTER=y
-# CONFIG_ATM_CLIP is not set
-CONFIG_ATM_CLIP_NO_ICMP=y
-# CONFIG_ATM_DRIVERS is not set
-# CONFIG_ATM_DUMMY is not set
-# CONFIG_ATM_ENI is not set
-# CONFIG_ATM_FIRESTREAM is not set
-# CONFIG_ATM_FORE200E is not set
-# CONFIG_ATM_HE is not set
-# CONFIG_ATM_HORIZON is not set
-# CONFIG_ATM_IA is not set
-# CONFIG_ATM_IDT77252 is not set
-# CONFIG_ATM_LANAI is not set
-# CONFIG_ATM_LANE is not set
-# CONFIG_ATM_MPOA is not set
-# CONFIG_ATM_NICSTAR is not set
-# CONFIG_ATM_SOLOS is not set
-# CONFIG_ATM_TCP is not set
-# CONFIG_ATM_ZATM is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_ATP is not set
-# CONFIG_AUDIT is not set
-# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set
-# CONFIG_AURORA_NB8800 is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTO_ZRELADDR is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_AX25 is not set
-# CONFIG_AX25_DAMA_SLAVE is not set
-# CONFIG_AX88796 is not set
-# CONFIG_AX88796B_PHY is not set
-# CONFIG_AXP20X_ADC is not set
-# CONFIG_AXP20X_POWER is not set
-# CONFIG_AXP288_ADC is not set
-# CONFIG_AXP288_FUEL_GAUGE is not set
-# CONFIG_B43 is not set
-# CONFIG_B43LEGACY is not set
-# CONFIG_B44 is not set
-# CONFIG_B53 is not set
-# CONFIG_B53_MDIO_DRIVER is not set
-# CONFIG_B53_MMAP_DRIVER is not set
-# CONFIG_B53_SERDES is not set
-# CONFIG_B53_SPI_DRIVER is not set
-# CONFIG_B53_SRAB_DRIVER is not set
-# CONFIG_BACKLIGHT_ADP8860 is not set
-# CONFIG_BACKLIGHT_ADP8870 is not set
-# CONFIG_BACKLIGHT_APPLE is not set
-# CONFIG_BACKLIGHT_ARCXCNN is not set
-# CONFIG_BACKLIGHT_BD6107 is not set
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
-# CONFIG_BACKLIGHT_GENERIC is not set
-# CONFIG_BACKLIGHT_GPIO is not set
-# CONFIG_BACKLIGHT_KTD253 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-# CONFIG_BACKLIGHT_LED is not set
-# CONFIG_BACKLIGHT_LM3630A is not set
-# CONFIG_BACKLIGHT_LM3639 is not set
-# CONFIG_BACKLIGHT_LP855X is not set
-# CONFIG_BACKLIGHT_LV5207LP is not set
-# CONFIG_BACKLIGHT_PANDORA is not set
-# CONFIG_BACKLIGHT_PM8941_WLED is not set
-# CONFIG_BACKLIGHT_PWM is not set
-# CONFIG_BACKLIGHT_QCOM_WLED is not set
-# CONFIG_BACKLIGHT_RPI is not set
-# CONFIG_BACKLIGHT_SAHARA is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_BACKTRACE_VERBOSE is not set
-# CONFIG_BAREUDP is not set
-CONFIG_BASE_FULL=y
-CONFIG_BASE_SMALL=0
-# CONFIG_BATMAN_ADV is not set
-# CONFIG_BATTERY_BQ27XXX is not set
-# CONFIG_BATTERY_BQ27XXX_HDQ is not set
-# CONFIG_BATTERY_CW2015 is not set
-# CONFIG_BATTERY_DS2760 is not set
-# CONFIG_BATTERY_DS2780 is not set
-# CONFIG_BATTERY_DS2781 is not set
-# CONFIG_BATTERY_DS2782 is not set
-# CONFIG_BATTERY_GAUGE_LTC2941 is not set
-# CONFIG_BATTERY_GOLDFISH is not set
-# CONFIG_BATTERY_LEGO_EV3 is not set
-# CONFIG_BATTERY_MAX17040 is not set
-# CONFIG_BATTERY_MAX17042 is not set
-# CONFIG_BATTERY_MAX1721X is not set
-# CONFIG_BATTERY_RT5033 is not set
-# CONFIG_BATTERY_SAMSUNG_SDI is not set
-# CONFIG_BATTERY_SBS is not set
-# CONFIG_BATTERY_UG3105 is not set
-# CONFIG_BAYCOM_EPP is not set
-# CONFIG_BAYCOM_PAR is not set
-# CONFIG_BAYCOM_SER_FDX is not set
-# CONFIG_BAYCOM_SER_HDX is not set
-# CONFIG_BCACHE is not set
-# CONFIG_BCM2712_MIP is not set
-# CONFIG_BCM47XX is not set
-# CONFIG_BCM54140_PHY is not set
-# CONFIG_BCM63XX is not set
-# CONFIG_BCM63XX_PHY is not set
-# CONFIG_BCM7038_L1_IRQ is not set
-# CONFIG_BCM7038_WDT is not set
-# CONFIG_BCM7120_L2_IRQ is not set
-# CONFIG_BCM7XXX_PHY is not set
-# CONFIG_BCM84881_PHY is not set
-# CONFIG_BCM87XX_PHY is not set
-# CONFIG_BCMA is not set
-# CONFIG_BCMA_DRIVER_GPIO is not set
-CONFIG_BCMA_POSSIBLE=y
-# CONFIG_BCMGENET is not set
-# CONFIG_BCM_IPROC_ADC is not set
-# CONFIG_BCM_KONA_USB2_PHY is not set
-# CONFIG_BCM_SBA_RAID is not set
-# CONFIG_BCM_VK is not set
-# CONFIG_BDI_SWITCH is not set
-# CONFIG_BE2ISCSI is not set
-# CONFIG_BE2NET is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_BGMAC is not set
-# CONFIG_BH1750 is not set
-# CONFIG_BH1780 is not set
-# CONFIG_BIG_KEYS is not set
-# CONFIG_BIG_LITTLE is not set
-CONFIG_BINARY_PRINTF=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_ELF_FDPIC is not set
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-CONFIG_BINFMT_SCRIPT=y
-CONFIG_BITREVERSE=y
-# CONFIG_BLK_CGROUP_IOCOST is not set
-# CONFIG_BLK_CGROUP_IOLATENCY is not set
-# CONFIG_BLK_CGROUP_IOPRIO is not set
-# CONFIG_BLK_CMDLINE_PARSER is not set
-# CONFIG_BLK_DEBUG_FS is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_BLK_DEV_4DRIVES is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI14XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_ATIIXP is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_BSGLIB is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_CS5535 is not set
-# CONFIG_BLK_DEV_CS5536 is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_DELKIN is not set
-# CONFIG_BLK_DEV_DM is not set
-# CONFIG_BLK_DEV_DRBD is not set
-# CONFIG_BLK_DEV_DTC2278 is not set
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_HT6560B is not set
-# CONFIG_BLK_DEV_IDEACPI is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDECS is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDE_AU1XXX is not set
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_BLK_DEV_IT8172 is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_NULL_BLK is not set
-# CONFIG_BLK_DEV_NVME is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_PLATFORM is not set
-# CONFIG_BLK_DEV_PMEM is not set
-# CONFIG_BLK_DEV_QD65XX is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_RBD is not set
-# CONFIG_BLK_DEV_RSXX is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_SD is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_SKD is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-# CONFIG_BLK_DEV_THROTTLING is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_UBLK is not set
-# CONFIG_BLK_DEV_UMC8672 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_ZONED is not set
-# CONFIG_BLK_INLINE_ENCRYPTION is not set
-# CONFIG_BLK_NVMEM is not set
-# CONFIG_BLK_SED_OPAL is not set
-# CONFIG_BLK_WBT is not set
-CONFIG_BLOCK=y
-# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
-# CONFIG_BMA180 is not set
-# CONFIG_BMA220 is not set
-# CONFIG_BMA400 is not set
-# CONFIG_BMC150_ACCEL is not set
-# CONFIG_BMC150_MAGN is not set
-# CONFIG_BMC150_MAGN_I2C is not set
-# CONFIG_BMC150_MAGN_SPI is not set
-# CONFIG_BME680 is not set
-# CONFIG_BMG160 is not set
-# CONFIG_BMI088_ACCEL is not set
-# CONFIG_BMI160_I2C is not set
-# CONFIG_BMI160_SPI is not set
-# CONFIG_BMIPS_GENERIC is not set
-# CONFIG_BMP280 is not set
-# CONFIG_BNA is not set
-# CONFIG_BNX2 is not set
-# CONFIG_BNX2X is not set
-# CONFIG_BNX2X_SRIOV is not set
-# CONFIG_BNXT is not set
-# CONFIG_BONDING is not set
-# CONFIG_BOOKE_WDT is not set
-CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3
-# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-# CONFIG_BOOTTIME_TRACING is not set
-# CONFIG_BOOT_CONFIG is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-CONFIG_BOOT_RAW=y
-# CONFIG_BOSCH_BNO055_I2C is not set
-# CONFIG_BOSCH_BNO055_SERIAL is not set
-# CONFIG_BOUNCE is not set
-CONFIG_BPF=y
-# CONFIG_BPFILTER is not set
-CONFIG_BPF_JIT=y
-# CONFIG_BPF_JIT_ALWAYS_ON is not set
-CONFIG_BPF_JIT_DEFAULT_ON=y
-# CONFIG_BPF_PRELOAD is not set
-# CONFIG_BPF_STREAM_PARSER is not set
-CONFIG_BPF_SYSCALL=y
-CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
-# CONFIG_BPQETHER is not set
-CONFIG_BQL=y
-CONFIG_BRANCH_PROFILE_NONE=y
-# CONFIG_BRCMFMAC is not set
-# CONFIG_BRCMSMAC is not set
-# CONFIG_BRCMSTB_GISB_ARB is not set
-# CONFIG_BRCMSTB_L2_IRQ is not set
-CONFIG_BRIDGE=y
-# CONFIG_BRIDGE_CFM is not set
-# CONFIG_BRIDGE_EBT_802_3 is not set
-# CONFIG_BRIDGE_EBT_AMONG is not set
-# CONFIG_BRIDGE_EBT_ARP is not set
-# CONFIG_BRIDGE_EBT_ARPREPLY is not set
-# CONFIG_BRIDGE_EBT_BROUTE is not set
-# CONFIG_BRIDGE_EBT_DNAT is not set
-# CONFIG_BRIDGE_EBT_IP is not set
-# CONFIG_BRIDGE_EBT_IP6 is not set
-# CONFIG_BRIDGE_EBT_LIMIT is not set
-# CONFIG_BRIDGE_EBT_LOG is not set
-# CONFIG_BRIDGE_EBT_MARK is not set
-# CONFIG_BRIDGE_EBT_MARK_T is not set
-# CONFIG_BRIDGE_EBT_NFLOG is not set
-# CONFIG_BRIDGE_EBT_PKTTYPE is not set
-# CONFIG_BRIDGE_EBT_REDIRECT is not set
-# CONFIG_BRIDGE_EBT_SNAT is not set
-# CONFIG_BRIDGE_EBT_STP is not set
-# CONFIG_BRIDGE_EBT_T_FILTER is not set
-# CONFIG_BRIDGE_EBT_T_NAT is not set
-# CONFIG_BRIDGE_EBT_VLAN is not set
-CONFIG_BRIDGE_IGMP_SNOOPING=y
-# CONFIG_BRIDGE_MRP is not set
-# CONFIG_BRIDGE_NETFILTER is not set
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_BRIDGE_VLAN_FILTERING=y
-# CONFIG_BROADCOM_PHY is not set
-CONFIG_BROKEN_ON_SMP=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_BT is not set
-# CONFIG_BTRFS_ASSERT is not set
-# CONFIG_BTRFS_DEBUG is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_BTRFS_FS_POSIX_ACL is not set
-# CONFIG_BTRFS_FS_REF_VERIFY is not set
-# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
-# CONFIG_BT_AOSPEXT is not set
-# CONFIG_BT_ATH3K is not set
-# CONFIG_BT_BNEP is not set
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-# CONFIG_BT_BREDR is not set
-# CONFIG_BT_CMTP is not set
-# CONFIG_BT_FEATURE_DEBUG is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBPA10X is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBTSDIO is not set
-# CONFIG_BT_HCIBTUSB is not set
-# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set
-# CONFIG_BT_HCIBTUSB_MTK is not set
-# CONFIG_BT_HCIBTUSB_RTL is not set
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIUART_3WIRE is not set
-# CONFIG_BT_HCIUART_AG6XX is not set
-# CONFIG_BT_HCIUART_ATH3K is not set
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_H4=y
-# CONFIG_BT_HCIUART_LL is not set
-# CONFIG_BT_HCIUART_MRVL is not set
-# CONFIG_BT_HCIUART_QCA is not set
-# CONFIG_BT_HCIUART_RTL is not set
-# CONFIG_BT_HCIVHCI is not set
-# CONFIG_BT_HIDP is not set
-# CONFIG_BT_HS is not set
-# CONFIG_BT_LE is not set
-# CONFIG_BT_LEDS is not set
-# CONFIG_BT_MRVL is not set
-# CONFIG_BT_MSFTEXT is not set
-# CONFIG_BT_MTKSDIO is not set
-# CONFIG_BT_MTKUART is not set
-# CONFIG_BT_RFCOMM is not set
-CONFIG_BT_RFCOMM_TTY=y
-# CONFIG_BT_SELFTEST is not set
-# CONFIG_BT_VIRTIO is not set
-CONFIG_BUG=y
-# CONFIG_BUG_ON_DATA_CORRUPTION is not set
-CONFIG_BUILDTIME_EXTABLE_SORT=y
-CONFIG_BUILDTIME_TABLE_SORT=y
-# CONFIG_BUILD_BIN2C is not set
-CONFIG_BUILD_SALT=""
-# CONFIG_C2PORT is not set
-CONFIG_CACHE_L2X0_PMU=y
-# CONFIG_CADENCE_WATCHDOG is not set
-# CONFIG_CAIF is not set
-# CONFIG_CAN is not set
-# CONFIG_CAN_BCM is not set
-# CONFIG_CAN_CAN327 is not set
-# CONFIG_CAN_CTUCANFD_PCI is not set
-# CONFIG_CAN_CTUCANFD_PLATFORM is not set
-# CONFIG_CAN_DEBUG_DEVICES is not set
-# CONFIG_CAN_DEV is not set
-# CONFIG_CAN_ESD_USB is not set
-# CONFIG_CAN_ETAS_ES58X is not set
-# CONFIG_CAN_GS_USB is not set
-# CONFIG_CAN_GW is not set
-# CONFIG_CAN_HI311X is not set
-# CONFIG_CAN_IFI_CANFD is not set
-# CONFIG_CAN_ISOTP is not set
-# CONFIG_CAN_J1939 is not set
-# CONFIG_CAN_KVASER_PCIEFD is not set
-# CONFIG_CAN_MCBA_USB is not set
-# CONFIG_CAN_MCP251XFD is not set
-# CONFIG_CAN_M_CAN is not set
-# CONFIG_CAN_NETLINK is not set
-# CONFIG_CAN_PEAK_PCIEFD is not set
-# CONFIG_CAN_RAW is not set
-# CONFIG_CAN_RCAR is not set
-# CONFIG_CAN_RCAR_CANFD is not set
-# CONFIG_CAN_SLCAN is not set
-# CONFIG_CAN_SUN4I is not set
-# CONFIG_CAN_UCAN is not set
-# CONFIG_CAN_VCAN is not set
-# CONFIG_CAN_VXCAN is not set
-# CONFIG_CAPI_AVM is not set
-# CONFIG_CAPI_EICON is not set
-# CONFIG_CAPI_TRACE is not set
-CONFIG_CARDBUS=y
-# CONFIG_CARDMAN_4000 is not set
-# CONFIG_CARDMAN_4040 is not set
-# CONFIG_CARL9170 is not set
-# CONFIG_CASSINI is not set
-# CONFIG_CAVIUM_CPT is not set
-# CONFIG_CAVIUM_ERRATUM_22375 is not set
-# CONFIG_CAVIUM_ERRATUM_23144 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_OCTEON_SOC is not set
-# CONFIG_CAVIUM_PTP is not set
-# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set
-# CONFIG_CB710_CORE is not set
-# CONFIG_CC10001_ADC is not set
-# CONFIG_CCS811 is not set
-CONFIG_CC_CAN_LINK=y
-CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_CEPH_FS is not set
-# CONFIG_CEPH_LIB is not set
-# CONFIG_CFG80211 is not set
-# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
-CONFIG_CFG80211_HEADERS=y
-# CONFIG_CGROUPS is not set
-# CONFIG_CGROUP_FAVOR_DYNMODS is not set
-# CONFIG_CGROUP_MISC is not set
-# CONFIG_CHARGER_ADP5061 is not set
-# CONFIG_CHARGER_BD99954 is not set
-# CONFIG_CHARGER_BQ2415X is not set
-# CONFIG_CHARGER_BQ24190 is not set
-# CONFIG_CHARGER_BQ24257 is not set
-# CONFIG_CHARGER_BQ24735 is not set
-# CONFIG_CHARGER_BQ2515X is not set
-# CONFIG_CHARGER_BQ256XX is not set
-# CONFIG_CHARGER_BQ25890 is not set
-# CONFIG_CHARGER_BQ25980 is not set
-# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
-# CONFIG_CHARGER_GPIO is not set
-# CONFIG_CHARGER_ISP1704 is not set
-# CONFIG_CHARGER_LP8727 is not set
-# CONFIG_CHARGER_LT3651 is not set
-# CONFIG_CHARGER_LTC3651 is not set
-# CONFIG_CHARGER_LTC4162L is not set
-# CONFIG_CHARGER_MANAGER is not set
-# CONFIG_CHARGER_MAX77976 is not set
-# CONFIG_CHARGER_MAX8903 is not set
-# CONFIG_CHARGER_QCOM_SMBB is not set
-# CONFIG_CHARGER_RT9455 is not set
-# CONFIG_CHARGER_SBS is not set
-# CONFIG_CHARGER_SMB347 is not set
-# CONFIG_CHARGER_TWL4030 is not set
-# CONFIG_CHARGER_UCS1002 is not set
-# CONFIG_CHASH_SELFTEST is not set
-# CONFIG_CHASH_STATS is not set
-# CONFIG_CHECKPOINT_RESTORE is not set
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_CHELSIO_T4 is not set
-# CONFIG_CHELSIO_T4VF is not set
-# CONFIG_CHROME_PLATFORMS is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_CHR_DEV_SCH is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_CIFS is not set
-# CONFIG_CIFS_ACL is not set
-CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
-# CONFIG_CIFS_DEBUG is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_FSCACHE is not set
-# CONFIG_CIFS_NFSD_EXPORT is not set
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_SMB2 is not set
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_STATS2 is not set
-# CONFIG_CIFS_SWN_UPCALL is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-CONFIG_CIFS_XATTR=y
-# CONFIG_CIO_DAC is not set
-# CONFIG_CLEANCACHE is not set
-# CONFIG_CLKSRC_PISTACHIO is not set
-# CONFIG_CLKSRC_VERSATILE is not set
-# CONFIG_CLK_GFM_LPASS_SM8250 is not set
-# CONFIG_CLK_HSDK is not set
-# CONFIG_CLK_ICST is not set
-# CONFIG_CLK_QORIQ is not set
-# CONFIG_CLK_SP810 is not set
-# CONFIG_CLOCK_THERMAL is not set
-CONFIG_CLS_U32_MARK=y
-# CONFIG_CLS_U32_PERF is not set
-# CONFIG_CM32181 is not set
-# CONFIG_CM3232 is not set
-# CONFIG_CM3323 is not set
-# CONFIG_CM3605 is not set
-# CONFIG_CM36651 is not set
-# CONFIG_CMA is not set
-CONFIG_CMDLINE=""
-# CONFIG_CMDLINE_BOOL is not set
-# CONFIG_CMDLINE_EXTEND is not set
-# CONFIG_CMDLINE_FORCE is not set
-# CONFIG_CMDLINE_FROM_BOOTLOADER is not set
-# CONFIG_CMDLINE_PARTITION is not set
-# CONFIG_CNIC is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_CODE_PATCHING_SELFTEST is not set
-# CONFIG_COMEDI is not set
-# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
-# CONFIG_COMMON_CLK_BOSTON is not set
-# CONFIG_COMMON_CLK_CDCE706 is not set
-# CONFIG_COMMON_CLK_CDCE925 is not set
-# CONFIG_COMMON_CLK_CS2000_CP is not set
-# CONFIG_COMMON_CLK_FIXED_MMIO is not set
-# CONFIG_COMMON_CLK_IPROC is not set
-# CONFIG_COMMON_CLK_MAX9485 is not set
-# CONFIG_COMMON_CLK_MT6765 is not set
-# CONFIG_COMMON_CLK_MT8167 is not set
-# CONFIG_COMMON_CLK_MT8167_AUDSYS is not set
-# CONFIG_COMMON_CLK_MT8167_IMGSYS is not set
-# CONFIG_COMMON_CLK_MT8167_MFGCFG is not set
-# CONFIG_COMMON_CLK_MT8167_MMSYS is not set
-# CONFIG_COMMON_CLK_MT8167_VDECSYS is not set
-# CONFIG_COMMON_CLK_MT8192 is not set
-# CONFIG_COMMON_CLK_NXP is not set
-# CONFIG_COMMON_CLK_PIC32 is not set
-# CONFIG_COMMON_CLK_PISTACHIO is not set
-# CONFIG_COMMON_CLK_PWM is not set
-# CONFIG_COMMON_CLK_PXA is not set
-# CONFIG_COMMON_CLK_QCOM is not set
-# CONFIG_COMMON_CLK_RP1 is not set
-# CONFIG_COMMON_CLK_RP1_SDIO is not set
-# CONFIG_COMMON_CLK_RS9_PCIE is not set
-# CONFIG_COMMON_CLK_SI514 is not set
-# CONFIG_COMMON_CLK_SI5341 is not set
-# CONFIG_COMMON_CLK_SI5351 is not set
-# CONFIG_COMMON_CLK_SI544 is not set
-# CONFIG_COMMON_CLK_SI570 is not set
-# CONFIG_COMMON_CLK_VC5 is not set
-# CONFIG_COMMON_CLK_VC7 is not set
-# CONFIG_COMMON_CLK_XGENE is not set
-# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set
-CONFIG_COMPACTION=y
-# CONFIG_COMPAL_LAPTOP is not set
-# CONFIG_COMPAT is not set
-# CONFIG_COMPAT_BRK is not set
-# CONFIG_COMPILE_TEST is not set
-# CONFIG_CONFIGFS_FS is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
-CONFIG_CONSOLE_LOGLEVEL_QUIET=4
-CONFIG_CONSTRUCTORS=y
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_COPS is not set
-# CONFIG_CORDIC is not set
-# CONFIG_COREDUMP is not set
-# CONFIG_CORESIGHT is not set
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_CORTINA_PHY is not set
-# CONFIG_COUNTER is not set
-# CONFIG_CPA_DEBUG is not set
-# CONFIG_CPU_BIG_ENDIAN is not set
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_FREQ is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set
-# CONFIG_CPU_FREQ_STAT_DETAILS is not set
-# CONFIG_CPU_FREQ_THERMAL is not set
-# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set
-# CONFIG_CPU_IDLE is not set
-# CONFIG_CPU_IDLE_GOV_LADDER is not set
-# CONFIG_CPU_IDLE_GOV_MENU is not set
-# CONFIG_CPU_IDLE_GOV_TEO is not set
-# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
-# CONFIG_CPU_ISOLATION is not set
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-# CONFIG_CPU_NO_EFFICIENT_FFS is not set
-CONFIG_CPU_SW_DOMAIN_PAN=y
-# CONFIG_CPU_THERMAL is not set
-# CONFIG_CRAMFS is not set
-CONFIG_CRAMFS_BLOCKDEV=y
-# CONFIG_CRAMFS_MTD is not set
-# CONFIG_CRASH_DUMP is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_CRC32_BIT is not set
-CONFIG_CRC32_SARWATE=y
-# CONFIG_CRC32_SELFTEST is not set
-# CONFIG_CRC32_SLICEBY4 is not set
-# CONFIG_CRC32_SLICEBY8 is not set
-# CONFIG_CRC4 is not set
-# CONFIG_CRC64 is not set
-# CONFIG_CRC64_ROCKSOFT is not set
-# CONFIG_CRC7 is not set
-# CONFIG_CRC8 is not set
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC_ITU_T is not set
-# CONFIG_CRC_T10DIF is not set
-CONFIG_CROSS_COMPILE=""
-# CONFIG_CROSS_MEMORY_ATTACH is not set
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_842 is not set
-CONFIG_CRYPTO_ACOMP2=y
-# CONFIG_CRYPTO_ADIANTUM is not set
-CONFIG_CRYPTO_AEAD=y
-CONFIG_CRYPTO_AEAD2=y
-# CONFIG_CRYPTO_AEGIS128 is not set
-# CONFIG_CRYPTO_AEGIS128L is not set
-# CONFIG_CRYPTO_AEGIS128L_AESNI_SSE2 is not set
-# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set
-# CONFIG_CRYPTO_AEGIS256 is not set
-# CONFIG_CRYPTO_AEGIS256_AESNI_SSE2 is not set
-CONFIG_CRYPTO_AES=y
-# CONFIG_CRYPTO_AES_586 is not set
-# CONFIG_CRYPTO_AES_ARM is not set
-# CONFIG_CRYPTO_AES_ARM64 is not set
-# CONFIG_CRYPTO_AES_ARM64_BS is not set
-# CONFIG_CRYPTO_AES_ARM64_CE is not set
-# CONFIG_CRYPTO_AES_ARM64_CE_BLK is not set
-# CONFIG_CRYPTO_AES_ARM64_CE_CCM is not set
-# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set
-# CONFIG_CRYPTO_AES_ARM_BS is not set
-# CONFIG_CRYPTO_AES_ARM_CE is not set
-# CONFIG_CRYPTO_AES_NI_INTEL is not set
-# CONFIG_CRYPTO_AES_TI is not set
-CONFIG_CRYPTO_AKCIPHER=y
-CONFIG_CRYPTO_AKCIPHER2=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_ARIA is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_BLAKE2B is not set
-# CONFIG_CRYPTO_BLAKE2B_NEON is not set
-# CONFIG_CRYPTO_BLAKE2S_ARM is not set
-# CONFIG_CRYPTO_BLAKE2S_X86 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_CBC is not set
-CONFIG_CRYPTO_CCM=y
-# CONFIG_CRYPTO_CFB is not set
-# CONFIG_CRYPTO_CHACHA20 is not set
-# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
-# CONFIG_CRYPTO_CHACHA20_NEON is not set
-# CONFIG_CRYPTO_CHACHA20_X86_64 is not set
-# CONFIG_CRYPTO_CHACHA_MIPS is not set
-# CONFIG_CRYPTO_CMAC is not set
-# CONFIG_CRYPTO_CRC32 is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CRC32C_INTEL is not set
-# CONFIG_CRYPTO_CRC32_ARM_CE is not set
-# CONFIG_CRYPTO_CRCT10DIF is not set
-# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set
-# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_CTR=y
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_CURVE25519 is not set
-# CONFIG_CRYPTO_CURVE25519_NEON is not set
-# CONFIG_CRYPTO_CURVE25519_X86 is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set
-# CONFIG_CRYPTO_DEV_ATMEL_AES is not set
-# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set
-# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
-# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set
-# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
-# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set
-# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set
-# CONFIG_CRYPTO_DEV_CCP is not set
-# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set
-# CONFIG_CRYPTO_DEV_CCREE is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set
-# CONFIG_CRYPTO_DEV_HIFN_795X is not set
-# CONFIG_CRYPTO_DEV_HISI_SEC is not set
-# CONFIG_CRYPTO_DEV_HISI_ZIP is not set
-# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set
-# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set
-# CONFIG_CRYPTO_DEV_MEDIATEK is not set
-# CONFIG_CRYPTO_DEV_MV_CESA is not set
-# CONFIG_CRYPTO_DEV_MXC_SCC is not set
-# CONFIG_CRYPTO_DEV_MXS_DCP is not set
-# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set
-# CONFIG_CRYPTO_DEV_OCTEONTX_CPT is not set
-# CONFIG_CRYPTO_DEV_QAT_4XXX is not set
-# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set
-# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
-# CONFIG_CRYPTO_DEV_QAT_C62X is not set
-# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
-# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set
-# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set
-# CONFIG_CRYPTO_DEV_QCE is not set
-# CONFIG_CRYPTO_DEV_S5P is not set
-# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
-# CONFIG_CRYPTO_DEV_SAHARA is not set
-# CONFIG_CRYPTO_DEV_SP_PSP is not set
-# CONFIG_CRYPTO_DEV_TALITOS is not set
-# CONFIG_CRYPTO_DEV_VIRTIO is not set
-# CONFIG_CRYPTO_DH is not set
-# CONFIG_CRYPTO_DRBG_CTR is not set
-# CONFIG_CRYPTO_DRBG_HASH is not set
-# CONFIG_CRYPTO_DRBG_MENU is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_ECDH is not set
-# CONFIG_CRYPTO_ECDSA is not set
-# CONFIG_CRYPTO_ECHAINIV is not set
-# CONFIG_CRYPTO_ECRDSA is not set
-# CONFIG_CRYPTO_ESSIV is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_GCM=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_GHASH=y
-# CONFIG_CRYPTO_GHASH_ARM64_CE is not set
-# CONFIG_CRYPTO_GHASH_ARM_CE is not set
-# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-# CONFIG_CRYPTO_HCTR2 is not set
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_CRYPTO_JITTERENTROPY is not set
-# CONFIG_CRYPTO_KEYWRAP is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-CONFIG_CRYPTO_KPP=y
-CONFIG_CRYPTO_KPP2=y
-CONFIG_CRYPTO_LIB_AES=y
-CONFIG_CRYPTO_LIB_ARC4=y
-# CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC is not set
-# CONFIG_CRYPTO_LIB_CHACHA is not set
-# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
-# CONFIG_CRYPTO_LIB_CURVE25519 is not set
-# CONFIG_CRYPTO_LIB_POLY1305 is not set
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_LZ4 is not set
-# CONFIG_CRYPTO_LZ4HC is not set
-# CONFIG_CRYPTO_LZO is not set
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
-# CONFIG_CRYPTO_MCRYPTD is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_MORUS1280 is not set
-# CONFIG_CRYPTO_MORUS1280_AVX2 is not set
-# CONFIG_CRYPTO_MORUS1280_SSE2 is not set
-# CONFIG_CRYPTO_MORUS640 is not set
-# CONFIG_CRYPTO_MORUS640_SSE2 is not set
-# CONFIG_CRYPTO_NHPOLY1305_NEON is not set
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_NULL2=y
-# CONFIG_CRYPTO_OFB is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_PCOMP is not set
-# CONFIG_CRYPTO_PCOMP2 is not set
-CONFIG_CRYPTO_PCRYPT=y
-# CONFIG_CRYPTO_POLY1305 is not set
-# CONFIG_CRYPTO_POLY1305_ARM is not set
-# CONFIG_CRYPTO_POLY1305_MIPS is not set
-# CONFIG_CRYPTO_POLY1305_NEON is not set
-# CONFIG_CRYPTO_POLY1305_X86_64 is not set
-# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RNG is not set
-# CONFIG_CRYPTO_RSA is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SEQIV is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA1_ARM is not set
-# CONFIG_CRYPTO_SHA1_ARM64_CE is not set
-# CONFIG_CRYPTO_SHA1_ARM_CE is not set
-# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA256_ARM is not set
-# CONFIG_CRYPTO_SHA256_ARM64 is not set
-# CONFIG_CRYPTO_SHA2_ARM64_CE is not set
-# CONFIG_CRYPTO_SHA2_ARM_CE is not set
-# CONFIG_CRYPTO_SHA3 is not set
-# CONFIG_CRYPTO_SHA3_ARM64 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_SHA512_ARM is not set
-# CONFIG_CRYPTO_SHA512_ARM64 is not set
-# CONFIG_CRYPTO_SHA512_ARM64_CE is not set
-# CONFIG_CRYPTO_SIMD is not set
-CONFIG_CRYPTO_SKCIPHER=y
-CONFIG_CRYPTO_SKCIPHER2=y
-# CONFIG_CRYPTO_SM2 is not set
-# CONFIG_CRYPTO_SM3 is not set
-# CONFIG_CRYPTO_SM3_ARM64_CE is not set
-# CONFIG_CRYPTO_SM3_GENERIC is not set
-# CONFIG_CRYPTO_SM3_NEON is not set
-# CONFIG_CRYPTO_SM4 is not set
-# CONFIG_CRYPTO_SM4_ARM64_CE is not set
-# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set
-# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set
-# CONFIG_CRYPTO_SM4_GENERIC is not set
-# CONFIG_CRYPTO_SPECK is not set
-# CONFIG_CRYPTO_STATS is not set
-# CONFIG_CRYPTO_STREEBOG is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_TWOFISH_586 is not set
-# CONFIG_CRYPTO_TWOFISH_COMMON is not set
-# CONFIG_CRYPTO_USER is not set
-# CONFIG_CRYPTO_USER_API_AEAD is not set
-# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set
-# CONFIG_CRYPTO_USER_API_HASH is not set
-# CONFIG_CRYPTO_USER_API_RNG is not set
-# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set
-# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
-# CONFIG_CRYPTO_VMAC is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_XXHASH is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_ZSTD is not set
-# CONFIG_CS5535_MFGPT is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_CS89x0_PLATFORM is not set
-# CONFIG_CSD_LOCK_WAIT_DEBUG is not set
-# CONFIG_CUSE is not set
-# CONFIG_CW1200 is not set
-# CONFIG_CXD2880_SPI_DRV is not set
-# CONFIG_CXL_AFU_DRIVER_OPS is not set
-# CONFIG_CXL_BASE is not set
-# CONFIG_CXL_BUS is not set
-# CONFIG_CXL_EEH is not set
-# CONFIG_CXL_KERNEL_API is not set
-# CONFIG_CXL_LIB is not set
-# CONFIG_CYPRESS_FIRMWARE is not set
-# CONFIG_DA280 is not set
-# CONFIG_DA311 is not set
-# CONFIG_DAMON is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_DAX is not set
-# CONFIG_DCB is not set
-# CONFIG_DDR is not set
-# CONFIG_DEBUG_ALIGN_RODATA is not set
-# CONFIG_DEBUG_ATOMIC_SLEEP is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_CREDENTIALS is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_EFI is not set
-# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set
-# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set
-# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_FS_ALLOW_ALL=y
-# CONFIG_DEBUG_FS_ALLOW_NONE is not set
-# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_DEBUG_HIGHMEM is not set
-# CONFIG_DEBUG_ICEDCC is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_INFO_BTF is not set
-# CONFIG_DEBUG_INFO_COMPRESSED is not set
-# CONFIG_DEBUG_INFO_DWARF4 is not set
-# CONFIG_DEBUG_INFO_DWARF5 is not set
-CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
-# CONFIG_DEBUG_INFO_NONE is not set
-# CONFIG_DEBUG_INFO_REDUCED is not set
-# CONFIG_DEBUG_INFO_SPLIT is not set
-# CONFIG_DEBUG_IRQFLAGS is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_KMAP_LOCAL is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_KOBJECT_RELEASE is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_LL_UART_8250 is not set
-# CONFIG_DEBUG_LL_UART_PL01X is not set
-# CONFIG_DEBUG_LOCKDEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_DEBUG_MAPLE_TREE is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_MISC is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_NET is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_DEBUG_NX_TEST is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUG_PAGE_REF is not set
-# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
-# CONFIG_DEBUG_PER_CPU_MAPS is not set
-# CONFIG_DEBUG_PINCTRL is not set
-# CONFIG_DEBUG_PI_LIST is not set
-# CONFIG_DEBUG_PLIST is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_DEBUG_RODATA_TEST is not set
-# CONFIG_DEBUG_RSEQ is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
-# CONFIG_DEBUG_SECTION_MISMATCH is not set
-# CONFIG_DEBUG_SEMIHOSTING is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_SHIRQ is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
-# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
-# CONFIG_DEBUG_TIMEKEEPING is not set
-# CONFIG_DEBUG_UART_8250_PALMCHIP is not set
-# CONFIG_DEBUG_UART_8250_WORD is not set
-# CONFIG_DEBUG_UART_BCM63XX is not set
-# CONFIG_DEBUG_UART_FLOW_CONTROL is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_VIRTUAL is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_VM_PGFLAGS is not set
-# CONFIG_DEBUG_VM_PGTABLE is not set
-# CONFIG_DEBUG_VM_RB is not set
-# CONFIG_DEBUG_VM_VMACACHE is not set
-# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
-# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
-# CONFIG_DEBUG_WX is not set
-# CONFIG_DEBUG_ZBOOT is not set
-# CONFIG_DECNET is not set
-# CONFIG_DEFAULT_CODEL is not set
-CONFIG_DEFAULT_CUBIC=y
-CONFIG_DEFAULT_DEADLINE=y
-# CONFIG_DEFAULT_FQ is not set
-CONFIG_DEFAULT_FQ_CODEL=y
-# CONFIG_DEFAULT_FQ_PIE is not set
-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_NOOP is not set
-# CONFIG_DEFAULT_PFIFO_FAST is not set
-# CONFIG_DEFAULT_RENO is not set
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_DEFAULT_SECURITY_DAC=y
-# CONFIG_DEFAULT_SECURITY_SELINUX is not set
-# CONFIG_DEFAULT_SFQ is not set
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
-# CONFIG_DELL_LAPTOP is not set
-# CONFIG_DELL_RBTN is not set
-# CONFIG_DELL_SMBIOS is not set
-# CONFIG_DELL_SMO8800 is not set
-# CONFIG_DEPRECATED_PARAM_STRUCT is not set
-# CONFIG_DETECT_HUNG_TASK is not set
-# CONFIG_DEVKMEM is not set
-# CONFIG_DEVMEM is not set
-CONFIG_DEVPORT=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_DEVTMPFS is not set
-# CONFIG_DEVTMPFS_MOUNT is not set
-# CONFIG_DEVTMPFS_SAFE is not set
-# CONFIG_DEV_DAX is not set
-# CONFIG_DGAP is not set
-# CONFIG_DGNC is not set
-# CONFIG_DHT11 is not set
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set
-# CONFIG_DISPLAY_CONNECTOR_DVI is not set
-# CONFIG_DISPLAY_CONNECTOR_HDMI is not set
-# CONFIG_DISPLAY_ENCODER_TFP410 is not set
-# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set
-# CONFIG_DISPLAY_PANEL_DPI is not set
-# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set
-# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set
-# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set
-# CONFIG_DL2K is not set
-# CONFIG_DLHL60D is not set
-# CONFIG_DLM is not set
-# CONFIG_DM9000 is not set
-# CONFIG_DM9051 is not set
-# CONFIG_DMABUF_DEBUG is not set
-# CONFIG_DMABUF_HEAPS is not set
-# CONFIG_DMABUF_MOVE_NOTIFY is not set
-# CONFIG_DMABUF_SELFTESTS is not set
-# CONFIG_DMABUF_SYSFS_STATS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_DMADEVICES_DEBUG is not set
-# CONFIG_DMARD06 is not set
-# CONFIG_DMARD09 is not set
-# CONFIG_DMARD10 is not set
-# CONFIG_DMASCC is not set
-# CONFIG_DMATEST is not set
-# CONFIG_DMA_API_DEBUG is not set
-CONFIG_DMA_COHERENT_POOL=y
-CONFIG_DMA_DECLARE_COHERENT=y
-# CONFIG_DMA_ENGINE is not set
-# CONFIG_DMA_FENCE_TRACE is not set
-# CONFIG_DMA_JZ4780 is not set
-# CONFIG_DMA_MAP_BENCHMARK is not set
-CONFIG_DMA_NONCOHERENT_MMAP=y
-# CONFIG_DMA_NOOP_OPS is not set
-# CONFIG_DMA_PERNUMA_CMA is not set
-# CONFIG_DMA_RESTRICTED_POOL is not set
-# CONFIG_DMA_SHARED_BUFFER is not set
-# CONFIG_DMA_VIRT_OPS is not set
-# CONFIG_DM_CACHE is not set
-# CONFIG_DM_CLONE is not set
-# CONFIG_DM_DEBUG is not set
-# CONFIG_DM_DELAY is not set
-# CONFIG_DM_DUST is not set
-# CONFIG_DM_EBS is not set
-# CONFIG_DM_ERA is not set
-# CONFIG_DM_FLAKEY is not set
-# CONFIG_DM_INTEGRITY is not set
-# CONFIG_DM_LOG_USERSPACE is not set
-# CONFIG_DM_LOG_WRITES is not set
-# CONFIG_DM_MQ_DEFAULT is not set
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_RAID is not set
-# CONFIG_DM_SWITCH is not set
-# CONFIG_DM_THIN_PROVISIONING is not set
-# CONFIG_DM_UEVENT is not set
-# CONFIG_DM_UNSTRIPED is not set
-# CONFIG_DM_VERITY is not set
-# CONFIG_DM_WRITECACHE is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DNET is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_DNS_RESOLVER is not set
-CONFIG_DOUBLEFAULT=y
-# CONFIG_DP83640_PHY is not set
-# CONFIG_DP83822_PHY is not set
-# CONFIG_DP83848_PHY is not set
-# CONFIG_DP83867_PHY is not set
-# CONFIG_DP83869_PHY is not set
-# CONFIG_DP83TC811_PHY is not set
-# CONFIG_DP83TD510_PHY is not set
-# CONFIG_DPOT_DAC is not set
-# CONFIG_DPS310 is not set
-CONFIG_DQL=y
-# CONFIG_DRAGONRISE_FF is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_AMDGPU is not set
-# CONFIG_DRM_AMDGPU_CIK is not set
-# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set
-# CONFIG_DRM_AMDGPU_SI is not set
-# CONFIG_DRM_AMDGPU_USERPTR is not set
-# CONFIG_DRM_AMD_ACP is not set
-# CONFIG_DRM_AMD_DC_DCN2_0 is not set
-# CONFIG_DRM_AMD_DC_DCN3_0 is not set
-# CONFIG_DRM_AMD_DC_HDCP is not set
-# CONFIG_DRM_AMD_DC_SI is not set
-# CONFIG_DRM_AMD_SECURE_DISPLAY is not set
-# CONFIG_DRM_ANALOGIX_ANX6345 is not set
-# CONFIG_DRM_ANALOGIX_ANX7625 is not set
-# CONFIG_DRM_ANALOGIX_ANX78XX is not set
-# CONFIG_DRM_ARCPGU is not set
-# CONFIG_DRM_ARMADA is not set
-# CONFIG_DRM_AST is not set
-# CONFIG_DRM_ATMEL_HLCDC is not set
-# CONFIG_DRM_BOCHS is not set
-# CONFIG_DRM_CDNS_DSI is not set
-# CONFIG_DRM_CDNS_MHDP8546 is not set
-# CONFIG_DRM_CHIPONE_ICN6211 is not set
-# CONFIG_DRM_CHRONTEL_CH7033 is not set
-# CONFIG_DRM_CIRRUS_QEMU is not set
-# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set
-# CONFIG_DRM_DEBUG_MM is not set
-# CONFIG_DRM_DEBUG_MODESET_LOCK is not set
-# CONFIG_DRM_DEBUG_SELFTEST is not set
-# CONFIG_DRM_DISPLAY_CONNECTOR is not set
-# CONFIG_DRM_DP_AUX_CHARDEV is not set
-# CONFIG_DRM_DP_CEC is not set
-# CONFIG_DRM_DUMB_VGA_DAC is not set
-# CONFIG_DRM_DW_HDMI_CEC is not set
-# CONFIG_DRM_ETNAVIV is not set
-# CONFIG_DRM_EXYNOS is not set
-# CONFIG_DRM_FBDEV_EMULATION is not set
-# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set
-# CONFIG_DRM_FSL_DCU is not set
-# CONFIG_DRM_GM12U320 is not set
-# CONFIG_DRM_GMA500 is not set
-# CONFIG_DRM_GUD is not set
-# CONFIG_DRM_HDLCD is not set
-# CONFIG_DRM_HISI_HIBMC is not set
-# CONFIG_DRM_HISI_KIRIN is not set
-# CONFIG_DRM_I2C_ADV7511 is not set
-# CONFIG_DRM_I2C_CH7006 is not set
-# CONFIG_DRM_I2C_NXP_TDA9950 is not set
-# CONFIG_DRM_I2C_NXP_TDA998X is not set
-# CONFIG_DRM_I2C_SIL164 is not set
-# CONFIG_DRM_I915 is not set
-# CONFIG_DRM_IMX_LCDIF is not set
-# CONFIG_DRM_ITE_IT6505 is not set
-# CONFIG_DRM_ITE_IT66121 is not set
-# CONFIG_DRM_KOMEDA is not set
-# CONFIG_DRM_LEGACY is not set
-# CONFIG_DRM_LIB_RANDOM is not set
-# CONFIG_DRM_LIMA is not set
-# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
-# CONFIG_DRM_LOGICVC is not set
-# CONFIG_DRM_LONTIUM_LT8912B is not set
-# CONFIG_DRM_LONTIUM_LT9211 is not set
-# CONFIG_DRM_LONTIUM_LT9611 is not set
-# CONFIG_DRM_LONTIUM_LT9611UXC is not set
-# CONFIG_DRM_LVDS_CODEC is not set
-# CONFIG_DRM_LVDS_ENCODER is not set
-# CONFIG_DRM_MALI_DISPLAY is not set
-# CONFIG_DRM_MCDE is not set
-# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
-# CONFIG_DRM_MGAG200 is not set
-# CONFIG_DRM_MXSFB is not set
-# CONFIG_DRM_NOUVEAU is not set
-# CONFIG_DRM_NWL_MIPI_DSI is not set
-# CONFIG_DRM_NXP_PTN3460 is not set
-# CONFIG_DRM_OMAP is not set
-# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set
-# CONFIG_DRM_PANEL_ARM_VERSATILE is not set
-# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set
-# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set
-# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set
-# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set
-# CONFIG_DRM_PANEL_DSI_CM is not set
-# CONFIG_DRM_PANEL_EBBG_FT8719 is not set
-# CONFIG_DRM_PANEL_EDP is not set
-# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set
-# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set
-# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set
-# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
-# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set
-# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set
-# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set
-# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set
-# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set
-# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
-# CONFIG_DRM_PANEL_JDI_R63452 is not set
-# CONFIG_DRM_PANEL_KHADAS_TS050 is not set
-# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set
-# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set
-# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set
-# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
-# CONFIG_DRM_PANEL_LG_LG4573 is not set
-# CONFIG_DRM_PANEL_LVDS is not set
-# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set
-# CONFIG_DRM_PANEL_MIPI_DBI is not set
-# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
-# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set
-# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
-# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
-# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set
-# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set
-# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set
-# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set
-# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set
-# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set
-# CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set
-# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
-# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set
-# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
-# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set
-# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set
-# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set
-# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set
-# CONFIG_DRM_PANEL_SIMPLE is not set
-# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set
-# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set
-# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
-# CONFIG_DRM_PANEL_SONY_ACX424AKP is not set
-# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
-# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set
-# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set
-# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
-# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
-# CONFIG_DRM_PANEL_TPO_TPG110 is not set
-# CONFIG_DRM_PANEL_TPO_Y17P is not set
-# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set
-# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set
-# CONFIG_DRM_PANEL_WAVESHARE_TOUCHSCREEN is not set
-# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set
-# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set
-# CONFIG_DRM_PANFROST is not set
-# CONFIG_DRM_PARADE_PS8622 is not set
-# CONFIG_DRM_PARADE_PS8640 is not set
-# CONFIG_DRM_PL111 is not set
-# CONFIG_DRM_QXL is not set
-# CONFIG_DRM_RADEON is not set
-# CONFIG_DRM_RADEON_USERPTR is not set
-# CONFIG_DRM_RCAR_DW_HDMI is not set
-# CONFIG_DRM_RCAR_LVDS is not set
-# CONFIG_DRM_RCAR_USE_LVDS is not set
-# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set
-# CONFIG_DRM_ROCKCHIP is not set
-# CONFIG_DRM_RP1_DPI is not set
-# CONFIG_DRM_RP1_DSI is not set
-# CONFIG_DRM_RP1_VEC is not set
-# CONFIG_DRM_SII902X is not set
-# CONFIG_DRM_SII9234 is not set
-# CONFIG_DRM_SIL_SII8620 is not set
-# CONFIG_DRM_SIMPLEDRM is not set
-# CONFIG_DRM_SIMPLE_BRIDGE is not set
-# CONFIG_DRM_SSD130X is not set
-# CONFIG_DRM_STI is not set
-# CONFIG_DRM_STM is not set
-# CONFIG_DRM_SUN4I is not set
-# CONFIG_DRM_THINE_THC63LVD1024 is not set
-# CONFIG_DRM_TIDSS is not set
-# CONFIG_DRM_TILCDC is not set
-# CONFIG_DRM_TINYDRM is not set
-# CONFIG_DRM_TI_DLPC3433 is not set
-# CONFIG_DRM_TI_SN65DSI83 is not set
-# CONFIG_DRM_TI_SN65DSI86 is not set
-# CONFIG_DRM_TI_TFP410 is not set
-# CONFIG_DRM_TI_TPD12S015 is not set
-# CONFIG_DRM_TOSHIBA_TC358762 is not set
-# CONFIG_DRM_TOSHIBA_TC358764 is not set
-# CONFIG_DRM_TOSHIBA_TC358767 is not set
-# CONFIG_DRM_TOSHIBA_TC358768 is not set
-# CONFIG_DRM_TOSHIBA_TC358775 is not set
-# CONFIG_DRM_TVE200 is not set
-# CONFIG_DRM_UDL is not set
-# CONFIG_DRM_V3D is not set
-# CONFIG_DRM_VBOXVIDEO is not set
-# CONFIG_DRM_VC4_HDMI_CEC is not set
-# CONFIG_DRM_VGEM is not set
-# CONFIG_DRM_VIRTIO_GPU is not set
-# CONFIG_DRM_VKMS is not set
-# CONFIG_DRM_VMWGFX is not set
-# CONFIG_DRM_XEN is not set
-# CONFIG_DRM_XEN_FRONTEND is not set
-# CONFIG_DS1682 is not set
-# CONFIG_DS1803 is not set
-# CONFIG_DS4424 is not set
-# CONFIG_DST_CACHE is not set
-# CONFIG_DTLK is not set
-# CONFIG_DUMMY is not set
-CONFIG_DUMMY_CONSOLE_COLUMNS=80
-CONFIG_DUMMY_CONSOLE_ROWS=25
-# CONFIG_DUMMY_IRQ is not set
-# CONFIG_DVB_A8293 is not set
-# CONFIG_DVB_AF9013 is not set
-# CONFIG_DVB_AF9033 is not set
-# CONFIG_DVB_AS102 is not set
-# CONFIG_DVB_ASCOT2E is not set
-# CONFIG_DVB_ATBM8830 is not set
-# CONFIG_DVB_AU8522_DTV is not set
-# CONFIG_DVB_AU8522_V4L is not set
-# CONFIG_DVB_B2C2_FLEXCOP_PCI is not set
-# CONFIG_DVB_B2C2_FLEXCOP_USB is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_CX24117 is not set
-# CONFIG_DVB_CX24120 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_CXD2099 is not set
-# CONFIG_DVB_CXD2820R is not set
-# CONFIG_DVB_CXD2841ER is not set
-# CONFIG_DVB_CXD2880 is not set
-# CONFIG_DVB_DDBRIDGE is not set
-# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_DIB8000 is not set
-# CONFIG_DVB_DIB9000 is not set
-# CONFIG_DVB_DRX39XYJ is not set
-# CONFIG_DVB_DRXD is not set
-# CONFIG_DVB_DRXK is not set
-# CONFIG_DVB_DS3000 is not set
-# CONFIG_DVB_DUMMY_FE is not set
-# CONFIG_DVB_DYNAMIC_MINORS is not set
-# CONFIG_DVB_EC100 is not set
-# CONFIG_DVB_FIREDTV is not set
-# CONFIG_DVB_HELENE is not set
-# CONFIG_DVB_HORUS3A is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# CONFIG_DVB_ISL6423 is not set
-# CONFIG_DVB_IX2505V is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_LG2160 is not set
-# CONFIG_DVB_LGDT3305 is not set
-# CONFIG_DVB_LGDT3306A is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGS8GL5 is not set
-# CONFIG_DVB_LGS8GXX is not set
-# CONFIG_DVB_LNBH25 is not set
-# CONFIG_DVB_LNBH29 is not set
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_LNBP22 is not set
-# CONFIG_DVB_M88DS3103 is not set
-# CONFIG_DVB_M88RS2000 is not set
-CONFIG_DVB_MAX_ADAPTERS=16
-# CONFIG_DVB_MB86A16 is not set
-# CONFIG_DVB_MB86A20S is not set
-# CONFIG_DVB_MMAP is not set
-# CONFIG_DVB_MN88443X is not set
-# CONFIG_DVB_MN88472 is not set
-# CONFIG_DVB_MN88473 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_MXL5XX is not set
-# CONFIG_DVB_MXL692 is not set
-# CONFIG_DVB_NET is not set
-# CONFIG_DVB_NETUP_UNIDVB is not set
-# CONFIG_DVB_NGENE is not set
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_PLATFORM_DRIVERS is not set
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_PLUTO2 is not set
-# CONFIG_DVB_PT1 is not set
-# CONFIG_DVB_PT3 is not set
-# CONFIG_DVB_RTL2830 is not set
-# CONFIG_DVB_RTL2832 is not set
-# CONFIG_DVB_RTL2832_SDR is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_S5H1411 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_S5H1432 is not set
-# CONFIG_DVB_S921 is not set
-# CONFIG_DVB_SI2165 is not set
-# CONFIG_DVB_SI2168 is not set
-# CONFIG_DVB_SI21XX is not set
-# CONFIG_DVB_SP2 is not set
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_STB0899 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STB6100 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STV0297 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_STV0367 is not set
-# CONFIG_DVB_STV0900 is not set
-# CONFIG_DVB_STV090x is not set
-# CONFIG_DVB_STV0910 is not set
-# CONFIG_DVB_STV6110 is not set
-# CONFIG_DVB_STV6110x is not set
-# CONFIG_DVB_STV6111 is not set
-# CONFIG_DVB_TC90522 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_TDA10048 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_TDA10071 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA18271C2DD is not set
-# CONFIG_DVB_TDA665x is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TEST_DRIVERS is not set
-# CONFIG_DVB_TS2020 is not set
-# CONFIG_DVB_TTUSB_BUDGET is not set
-# CONFIG_DVB_TTUSB_DEC is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-# CONFIG_DVB_TUNER_DIB0090 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_ULE_DEBUG is not set
-# CONFIG_DVB_USB is not set
-# CONFIG_DVB_USB_V2 is not set
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_ZD1301_DEMOD is not set
-# CONFIG_DVB_ZL10036 is not set
-# CONFIG_DVB_ZL10039 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DWC_XLGMAC is not set
-# CONFIG_DWMAC_DWC_QOS_ETH is not set
-# CONFIG_DWMAC_INTEL_PLAT is not set
-# CONFIG_DWMAC_IPQ806X is not set
-# CONFIG_DWMAC_LOONGSON is not set
-# CONFIG_DWMAC_LPC18XX is not set
-# CONFIG_DWMAC_MESON is not set
-# CONFIG_DWMAC_ROCKCHIP is not set
-# CONFIG_DWMAC_SOCFPGA is not set
-# CONFIG_DWMAC_STI is not set
-# CONFIG_DW_AXI_DMAC is not set
-# CONFIG_DW_DMAC is not set
-# CONFIG_DW_DMAC_PCI is not set
-# CONFIG_DW_EDMA is not set
-# CONFIG_DW_EDMA_PCIE is not set
-# CONFIG_DW_WATCHDOG is not set
-# CONFIG_DW_XDATA_PCIE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_DYNAMIC_DEBUG_CORE is not set
-# CONFIG_E100 is not set
-# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_E1000E_HWTS is not set
-# CONFIG_EARLY_PRINTK_8250 is not set
-# CONFIG_EARLY_PRINTK_USB_XDBC is not set
-# CONFIG_EBC_C384_WDT is not set
-# CONFIG_ECHO is not set
-# CONFIG_ECRYPT_FS is not set
-# CONFIG_EDAC is not set
-# CONFIG_EEEPC_LAPTOP is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_EEPROM_93XX46 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_AT25 is not set
-# CONFIG_EEPROM_DIGSY_MTC_CFG is not set
-# CONFIG_EEPROM_EE1004 is not set
-# CONFIG_EEPROM_IDT_89HPESX is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_MAX6875 is not set
-# CONFIG_EFI is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_EFI_VARS_PSTORE is not set
-# CONFIG_EFS_FS is not set
-CONFIG_ELFCORE=y
-# CONFIG_ELF_CORE is not set
-# CONFIG_EMAC_ROCKCHIP is not set
-CONFIG_EMBEDDED=y
-# CONFIG_EM_TIMER_STI is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-# CONFIG_ENA_ETHERNET is not set
-# CONFIG_ENC28J60 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_ENCRYPTED_KEYS is not set
-# CONFIG_ENCX24J600 is not set
-# CONFIG_ENERGY_MODEL is not set
-# CONFIG_ENIC is not set
-# CONFIG_ENVELOPE_DETECTOR is not set
-# CONFIG_EPAPR_PARAVIRT is not set
-# CONFIG_EPIC100 is not set
-CONFIG_EPOLL=y
-# CONFIG_EQUALIZER is not set
-# CONFIG_EROFS_FS is not set
-# CONFIG_ET131X is not set
-CONFIG_ETHERNET=y
-# CONFIG_ETHOC is not set
-CONFIG_ETHTOOL_NETLINK=y
-CONFIG_EVENTFD=y
-# CONFIG_EVM is not set
-# CONFIG_EXFAT_FS is not set
-CONFIG_EXPERT=y
-CONFIG_EXPORTFS=y
-# CONFIG_EXPORTFS_BLOCK_OPS is not set
-# CONFIG_EXT2_FS is not set
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4_DEBUG is not set
-# CONFIG_EXT4_ENCRYPTION is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_EXT4_FS_POSIX_ACL is not set
-# CONFIG_EXT4_FS_SECURITY is not set
-CONFIG_EXT4_USE_FOR_EXT2=y
-# CONFIG_EXTCON is not set
-# CONFIG_EXTCON_ADC_JACK is not set
-# CONFIG_EXTCON_ARIZONA is not set
-# CONFIG_EXTCON_AXP288 is not set
-# CONFIG_EXTCON_FSA9480 is not set
-# CONFIG_EXTCON_GPIO is not set
-# CONFIG_EXTCON_INTEL_INT3496 is not set
-# CONFIG_EXTCON_MAX3355 is not set
-# CONFIG_EXTCON_PTN5150 is not set
-# CONFIG_EXTCON_QCOM_SPMI_MISC is not set
-# CONFIG_EXTCON_RT8973A is not set
-# CONFIG_EXTCON_SM5502 is not set
-# CONFIG_EXTCON_USBC_TUSB320 is not set
-# CONFIG_EXTCON_USB_GPIO is not set
-CONFIG_EXTRA_FIRMWARE=""
-CONFIG_EXTRA_TARGETS=""
-# CONFIG_EXYNOS_ADC is not set
-# CONFIG_EXYNOS_VIDEO is not set
-# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set
-# CONFIG_EZX_PCAP is not set
-# CONFIG_F2FS_CHECK_FS is not set
-# CONFIG_F2FS_FAULT_INJECTION is not set
-# CONFIG_F2FS_FS is not set
-# CONFIG_F2FS_FS_COMPRESSION is not set
-# CONFIG_F2FS_FS_ENCRYPTION is not set
-# CONFIG_F2FS_FS_POSIX_ACL is not set
-# CONFIG_F2FS_FS_SECURITY is not set
-CONFIG_F2FS_FS_XATTR=y
-# CONFIG_F2FS_IOSTAT is not set
-# CONFIG_F2FS_IO_TRACE is not set
-CONFIG_F2FS_STAT_FS=y
-# CONFIG_F2FS_UNFAIR_RWSEM is not set
-# CONFIG_FAILOVER is not set
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_FANOTIFY is not set
-# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_FAT_DEFAULT_UTF8 is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_FB is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_ARC is not set
-# CONFIG_FB_ARK is not set
-# CONFIG_FB_ARMCLCD is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_ATMEL is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_AUO_K190X is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_BIG_ENDIAN is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-# CONFIG_FB_BOTH_ENDIAN is not set
-# CONFIG_FB_BROADSHEET is not set
-# CONFIG_FB_CARMINE is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_DA8XX is not set
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_FLEX is not set
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_FSL_DIU is not set
-# CONFIG_FB_GEODE is not set
-# CONFIG_FB_GOLDFISH is not set
-# CONFIG_FB_HGA is not set
-# CONFIG_FB_I740 is not set
-# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_IMX is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_LE80578 is not set
-# CONFIG_FB_LITTLE_ENDIAN is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_MB862XX is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_MXS is not set
-# CONFIG_FB_N411 is not set
-# CONFIG_FB_NEOMAGIC is not set
-CONFIG_FB_NOTIFY=y
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_OF is not set
-# CONFIG_FB_OMAP2 is not set
-# CONFIG_FB_OPENCORES is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_PM3 is not set
-# CONFIG_FB_PS3 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_RPISENSE is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIMPLE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_SM712 is not set
-# CONFIG_FB_SM750 is not set
-# CONFIG_FB_SMSCUFX is not set
-# CONFIG_FB_SSD1307 is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_FOPS is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
-# CONFIG_FB_TFT is not set
-# CONFIG_FB_TFT_AGM1264K_FL is not set
-# CONFIG_FB_TFT_BD663474 is not set
-# CONFIG_FB_TFT_FBTFT_DEVICE is not set
-# CONFIG_FB_TFT_HX8340BN is not set
-# CONFIG_FB_TFT_HX8347D is not set
-# CONFIG_FB_TFT_HX8353D is not set
-# CONFIG_FB_TFT_HX8357D is not set
-# CONFIG_FB_TFT_ILI9163 is not set
-# CONFIG_FB_TFT_ILI9320 is not set
-# CONFIG_FB_TFT_ILI9325 is not set
-# CONFIG_FB_TFT_ILI9340 is not set
-# CONFIG_FB_TFT_ILI9341 is not set
-# CONFIG_FB_TFT_ILI9481 is not set
-# CONFIG_FB_TFT_ILI9486 is not set
-# CONFIG_FB_TFT_PCD8544 is not set
-# CONFIG_FB_TFT_RA8875 is not set
-# CONFIG_FB_TFT_S6D02A1 is not set
-# CONFIG_FB_TFT_S6D1121 is not set
-# CONFIG_FB_TFT_SEPS525 is not set
-# CONFIG_FB_TFT_SH1106 is not set
-# CONFIG_FB_TFT_SSD1289 is not set
-# CONFIG_FB_TFT_SSD1305 is not set
-# CONFIG_FB_TFT_SSD1306 is not set
-# CONFIG_FB_TFT_SSD1325 is not set
-# CONFIG_FB_TFT_SSD1331 is not set
-# CONFIG_FB_TFT_SSD1351 is not set
-# CONFIG_FB_TFT_ST7735R is not set
-# CONFIG_FB_TFT_ST7789V is not set
-# CONFIG_FB_TFT_TINYLCD is not set
-# CONFIG_FB_TFT_TLS8204 is not set
-# CONFIG_FB_TFT_UC1611 is not set
-# CONFIG_FB_TFT_UC1701 is not set
-# CONFIG_FB_TFT_UPD161704 is not set
-# CONFIG_FB_TFT_WATTEROTT is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_TMIO is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_UDL is not set
-# CONFIG_FB_UVESA is not set
-# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_VIA is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_VT8623 is not set
-# CONFIG_FB_XGI is not set
-# CONFIG_FCOE is not set
-# CONFIG_FCOE_FNIC is not set
-# CONFIG_FDDI is not set
-# CONFIG_FEALNX is not set
-# CONFIG_FENCE_TRACE is not set
-# CONFIG_FHANDLE is not set
-CONFIG_FIB_RULES=y
-# CONFIG_FIELDBUS_DEV is not set
-CONFIG_FILE_LOCKING=y
-# CONFIG_FIND_BIT_BENCHMARK is not set
-# CONFIG_FIREWIRE is not set
-# CONFIG_FIREWIRE_NOSY is not set
-# CONFIG_FIREWIRE_SERIAL is not set
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-# CONFIG_FIRMWARE_MEMMAP is not set
-# CONFIG_FIXED_PHY is not set
-CONFIG_FLATMEM=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_FM10K is not set
-# CONFIG_FMC is not set
-# CONFIG_FONTS is not set
-# CONFIG_FONT_6x8 is not set
-# CONFIG_FONT_TER16x32 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_FORCE_NR_CPUS is not set
-CONFIG_FORTIFY_SOURCE=y
-# CONFIG_FPGA is not set
-# CONFIG_FPROBE is not set
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_FREEZER is not set
-# CONFIG_FRONTSWAP is not set
-# CONFIG_FSCACHE is not set
-# CONFIG_FSI is not set
-# CONFIG_FSL_DPAA2_SWITCH is not set
-# CONFIG_FSL_EDMA is not set
-# CONFIG_FSL_ENETC is not set
-# CONFIG_FSL_ENETC_IERB is not set
-# CONFIG_FSL_ENETC_MDIO is not set
-# CONFIG_FSL_ENETC_VF is not set
-# CONFIG_FSL_ERRATUM_A008585 is not set
-# CONFIG_FSL_MC_BUS is not set
-# CONFIG_FSL_PQ_MDIO is not set
-# CONFIG_FSL_QDMA is not set
-# CONFIG_FSL_RCPM is not set
-# CONFIG_FSL_XGMAC_MDIO is not set
-CONFIG_FSNOTIFY=y
-# CONFIG_FS_DAX is not set
-# CONFIG_FS_ENCRYPTION is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_FS_VERITY is not set
-# CONFIG_FTGMAC100 is not set
-# CONFIG_FTL is not set
-# CONFIG_FTMAC100 is not set
-# CONFIG_FTRACE is not set
-# CONFIG_FTRACE_RECORD_RECURSION is not set
-# CONFIG_FTRACE_SORT_STARTUP_TEST is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_FTR_FIXUP_SELFTEST is not set
-# CONFIG_FTWDT010_WATCHDOG is not set
-# CONFIG_FUJITSU_ERRATUM_010001 is not set
-# CONFIG_FUJITSU_ES is not set
-# CONFIG_FUJITSU_LAPTOP is not set
-# CONFIG_FUJITSU_TABLET is not set
-# CONFIG_FUNCTION_ERROR_INJECTION is not set
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_FUN_ETH is not set
-# CONFIG_FUSE_FS is not set
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
-# CONFIG_FUSION_SPI is not set
-CONFIG_FUTEX=y
-CONFIG_FUTEX_PI=y
-# CONFIG_FW_CFG_SYSFS is not set
-CONFIG_FW_LOADER=y
-# CONFIG_FW_LOADER_COMPRESS is not set
-CONFIG_FW_LOADER_USER_HELPER=y
-CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
-# CONFIG_FW_UPLOAD is not set
-# CONFIG_FXAS21002C is not set
-# CONFIG_FXLS8962AF_I2C is not set
-# CONFIG_FXLS8962AF_SPI is not set
-# CONFIG_FXOS8700_I2C is not set
-# CONFIG_FXOS8700_SPI is not set
-CONFIG_GACT_PROB=y
-# CONFIG_GADGET_UAC1 is not set
-# CONFIG_GAMEPORT is not set
-# CONFIG_GATEWORKS_GW16083 is not set
-# CONFIG_GCC_PLUGINS is not set
-# CONFIG_GCOV is not set
-# CONFIG_GCOV_KERNEL is not set
-# CONFIG_GDB_SCRIPTS is not set
-# CONFIG_GEMINI_ETHERNET is not set
-# CONFIG_GENERIC_ADC_BATTERY is not set
-# CONFIG_GENERIC_ADC_THERMAL is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-# CONFIG_GENERIC_CPU_DEVICES is not set
-CONFIG_GENERIC_HWEIGHT=y
-# CONFIG_GENERIC_IRQ_DEBUGFS is not set
-CONFIG_GENERIC_IRQ_IPI=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_NET_UTILS=y
-# CONFIG_GENERIC_PHY is not set
-CONFIG_GENERIC_PTDUMP=y
-CONFIG_GENERIC_VDSO_TIME_NS=y
-# CONFIG_GENEVE is not set
-# CONFIG_GENWQE is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_GIGASET_CAPI is not set
-# CONFIG_GIGASET_DEBUG is not set
-# CONFIG_GIGASET_DUMMYLL is not set
-# CONFIG_GLOB_SELFTEST is not set
-# CONFIG_GNSS is not set
-# CONFIG_GOLDFISH is not set
-# CONFIG_GOOGLE_FIRMWARE is not set
-# CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT is not set
-# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set
-# CONFIG_GOOGLE_SMI is not set
-# CONFIG_GP2AP002 is not set
-# CONFIG_GP2AP020A00F is not set
-# CONFIG_GPD_POCKET_FAN is not set
-CONFIG_GPIOLIB=y
-CONFIG_GPIOLIB_FASTPATH_LIMIT=512
-# CONFIG_GPIO_104_DIO_48E is not set
-# CONFIG_GPIO_104_IDIO_16 is not set
-# CONFIG_GPIO_104_IDI_48 is not set
-# CONFIG_GPIO_74X164 is not set
-# CONFIG_GPIO_74XX_MMIO is not set
-# CONFIG_GPIO_ADNP is not set
-# CONFIG_GPIO_ADP5588 is not set
-# CONFIG_GPIO_AGGREGATOR is not set
-# CONFIG_GPIO_ALTERA is not set
-# CONFIG_GPIO_AMD8111 is not set
-# CONFIG_GPIO_AMDPT is not set
-# CONFIG_GPIO_AMD_FCH is not set
-# CONFIG_GPIO_BCM_KONA is not set
-# CONFIG_GPIO_BRCMSTB is not set
-# CONFIG_GPIO_BT8XX is not set
-# CONFIG_GPIO_CADENCE is not set
-# CONFIG_GPIO_CASCADE is not set
-# CONFIG_GPIO_CDEV is not set
-# CONFIG_GPIO_CDEV_V1 is not set
-# CONFIG_GPIO_CS5535 is not set
-# CONFIG_GPIO_DWAPB is not set
-# CONFIG_GPIO_EM is not set
-# CONFIG_GPIO_EXAR is not set
-# CONFIG_GPIO_F7188X is not set
-# CONFIG_GPIO_FTGPIO010 is not set
-# CONFIG_GPIO_GENERIC_PLATFORM is not set
-# CONFIG_GPIO_GPIO_MM is not set
-# CONFIG_GPIO_GRGPIO is not set
-# CONFIG_GPIO_GW_PLD is not set
-# CONFIG_GPIO_HLWD is not set
-# CONFIG_GPIO_ICH is not set
-# CONFIG_GPIO_IT87 is not set
-# CONFIG_GPIO_LOGICVC is not set
-# CONFIG_GPIO_LYNXPOINT is not set
-# CONFIG_GPIO_MAX3191X is not set
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX7301 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_MB86S7X is not set
-# CONFIG_GPIO_MC33880 is not set
-# CONFIG_GPIO_ML_IOH is not set
-# CONFIG_GPIO_MOCKUP is not set
-# CONFIG_GPIO_MPC8XXX is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCA953X_IRQ is not set
-# CONFIG_GPIO_PCA9570 is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_PCH is not set
-# CONFIG_GPIO_PCIE_IDIO_24 is not set
-# CONFIG_GPIO_PCI_IDIO_16 is not set
-# CONFIG_GPIO_PISOSR is not set
-# CONFIG_GPIO_PL061 is not set
-# CONFIG_GPIO_PWM is not set
-# CONFIG_GPIO_RCAR is not set
-# CONFIG_GPIO_RDC321X is not set
-# CONFIG_GPIO_SAMA5D2_PIOBU is not set
-# CONFIG_GPIO_SCH is not set
-# CONFIG_GPIO_SCH311X is not set
-# CONFIG_GPIO_SIFIVE is not set
-# CONFIG_GPIO_SIM is not set
-# CONFIG_GPIO_SX150X is not set
-# CONFIG_GPIO_SYSCON is not set
-CONFIG_GPIO_SYSFS=y
-# CONFIG_GPIO_TPIC2810 is not set
-# CONFIG_GPIO_TS4900 is not set
-# CONFIG_GPIO_TS5500 is not set
-# CONFIG_GPIO_VF610 is not set
-# CONFIG_GPIO_VIRTIO is not set
-# CONFIG_GPIO_VX855 is not set
-# CONFIG_GPIO_WATCHDOG is not set
-# CONFIG_GPIO_WINBOND is not set
-# CONFIG_GPIO_WS16C48 is not set
-# CONFIG_GPIO_XGENE is not set
-# CONFIG_GPIO_XILINX is not set
-# CONFIG_GPIO_XRA1403 is not set
-# CONFIG_GPIO_ZEVIO is not set
-# CONFIG_GPIO_ZX is not set
-# CONFIG_GP_PCI1XXXX is not set
-# CONFIG_GREENASIA_FF is not set
-# CONFIG_GREYBUS is not set
-# CONFIG_GS_FPGABOOT is not set
-# CONFIG_GTP is not set
-# CONFIG_GUP_BENCHMARK is not set
-# CONFIG_GUP_TEST is not set
-# CONFIG_GVE is not set
-# CONFIG_HABANA_AI is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_HAPPYMEAL is not set
-CONFIG_HARDENED_USERCOPY=y
-# CONFIG_HARDENED_USERCOPY_FALLBACK is not set
-# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set
-CONFIG_HARDEN_BRANCH_HISTORY=y
-CONFIG_HARDEN_EL2_VECTORS=y
-# CONFIG_HARDLOCKUP_DETECTOR is not set
-# CONFIG_HAVE_ARM_ARCH_TIMER is not set
-# CONFIG_HCALL_STATS is not set
-# CONFIG_HDC100X is not set
-# CONFIG_HDC2010 is not set
-# CONFIG_HDLC is not set
-# CONFIG_HDLC_CISCO is not set
-# CONFIG_HDLC_FR is not set
-# CONFIG_HDLC_PPP is not set
-# CONFIG_HDLC_RAW is not set
-# CONFIG_HDLC_RAW_ETH is not set
-# CONFIG_HDMI_LPE_AUDIO is not set
-# CONFIG_HDQ_MASTER_OMAP is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_HEADERS_INSTALL is not set
-# CONFIG_HEADER_TEST is not set
-# CONFIG_HERMES is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_HFSPLUS_FS_POSIX_ACL is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFS_FS_POSIX_ACL is not set
-# CONFIG_HI6421V600_IRQ is not set
-# CONFIG_HI8435 is not set
-# CONFIG_HIBERNATION is not set
-# CONFIG_HID is not set
-# CONFIG_HIDRAW is not set
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_ACCUTOUCH is not set
-# CONFIG_HID_ACRUX is not set
-# CONFIG_HID_ACRUX_FF is not set
-# CONFIG_HID_ALPS is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_APPLEIR is not set
-# CONFIG_HID_ASUS is not set
-# CONFIG_HID_AUREAL is not set
-# CONFIG_HID_BATTERY_STRENGTH is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_BETOP_FF is not set
-# CONFIG_HID_BIGBEN_FF is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_CMEDIA is not set
-# CONFIG_HID_CORSAIR is not set
-# CONFIG_HID_COUGAR is not set
-# CONFIG_HID_CP2112 is not set
-# CONFIG_HID_CREATIVE_SB0540 is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_ELAN is not set
-# CONFIG_HID_ELECOM is not set
-# CONFIG_HID_ELO is not set
-# CONFIG_HID_EMS_FF is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_FT260 is not set
-# CONFIG_HID_GEMBIRD is not set
-# CONFIG_HID_GENERIC is not set
-# CONFIG_HID_GFRM is not set
-# CONFIG_HID_GLORIOUS is not set
-# CONFIG_HID_GOOGLE_HAMMER is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_GT683R is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_HOLTEK is not set
-# CONFIG_HID_ICADE is not set
-# CONFIG_HID_ITE is not set
-# CONFIG_HID_JABRA is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_KEYTOUCH is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_LCPOWER is not set
-# CONFIG_HID_LED is not set
-# CONFIG_HID_LENOVO is not set
-# CONFIG_HID_LETSKETCH is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_LOGITECH_DJ is not set
-# CONFIG_HID_LOGITECH_HIDPP is not set
-# CONFIG_HID_MACALLY is not set
-# CONFIG_HID_MAGICMOUSE is not set
-# CONFIG_HID_MALTRON is not set
-# CONFIG_HID_MAYFLASH is not set
-# CONFIG_HID_MCP2221 is not set
-# CONFIG_HID_MEGAWORLD_FF is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_MULTITOUCH is not set
-# CONFIG_HID_NINTENDO is not set
-# CONFIG_HID_NTI is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_ORTEK is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PENMOUNT is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_PICOLCD is not set
-# CONFIG_HID_PID is not set
-# CONFIG_HID_PLANTRONICS is not set
-# CONFIG_HID_PLAYSTATION is not set
-# CONFIG_HID_PRIMAX is not set
-# CONFIG_HID_PRODIKEYS is not set
-# CONFIG_HID_PXRC is not set
-# CONFIG_HID_RAZER is not set
-# CONFIG_HID_REDRAGON is not set
-# CONFIG_HID_RETRODE is not set
-# CONFIG_HID_RMI is not set
-# CONFIG_HID_ROCCAT is not set
-# CONFIG_HID_SAITEK is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SEMITEK is not set
-# CONFIG_HID_SENSOR_HUB is not set
-# CONFIG_HID_SIGMAMICRO is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_SPEEDLINK is not set
-# CONFIG_HID_STEAM is not set
-# CONFIG_HID_STEELSERIES is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_THINGM is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_TIVO is not set
-# CONFIG_HID_TOPRE is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_U2FZERO is not set
-# CONFIG_HID_UCLOGIC is not set
-# CONFIG_HID_UDRAW_PS3 is not set
-# CONFIG_HID_VIEWSONIC is not set
-# CONFIG_HID_VIVALDI is not set
-# CONFIG_HID_VRC2 is not set
-# CONFIG_HID_WACOM is not set
-# CONFIG_HID_WALTOP is not set
-# CONFIG_HID_WIIMOTE is not set
-# CONFIG_HID_XIAOMI is not set
-# CONFIG_HID_XINMO is not set
-# CONFIG_HID_ZEROPLUS is not set
-# CONFIG_HID_ZYDACRON is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_HIGH_RES_TIMERS=y
-# CONFIG_HINIC is not set
-# CONFIG_HIP04_ETH is not set
-# CONFIG_HIPPI is not set
-# CONFIG_HISILICON_ERRATUM_161010101 is not set
-# CONFIG_HISILICON_ERRATUM_161600802 is not set
-# CONFIG_HISI_DMA is not set
-# CONFIG_HISI_FEMAC is not set
-# CONFIG_HISI_HIKEY_USB is not set
-# CONFIG_HISI_PCIE_PMU is not set
-# CONFIG_HISI_PTT is not set
-# CONFIG_HIST_TRIGGERS_DEBUG is not set
-# CONFIG_HIX5HD2_GMAC is not set
-# CONFIG_HMC425 is not set
-# CONFIG_HMC6352 is not set
-# CONFIG_HNS is not set
-# CONFIG_HNS3 is not set
-# CONFIG_HNS3_PMU is not set
-# CONFIG_HNS_DSAF is not set
-# CONFIG_HNS_ENET is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-# CONFIG_HOSTAP_PCI is not set
-# CONFIG_HOSTAP_PLX is not set
-# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HP03 is not set
-# CONFIG_HP100 is not set
-# CONFIG_HP206C is not set
-CONFIG_HPET_MMAP_DEFAULT=y
-# CONFIG_HPFS_FS is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_HP_WATCHDOG is not set
-# CONFIG_HP_WIRELESS is not set
-# CONFIG_HSA_AMD is not set
-# CONFIG_HSI is not set
-# CONFIG_HSR is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_I2CPLD is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HTE is not set
-# CONFIG_HTS221 is not set
-# CONFIG_HTU21 is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_HVC_DCC is not set
-# CONFIG_HVC_UDBG is not set
-# CONFIG_HWLAT_TRACER is not set
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-# CONFIG_HWMON_VID is not set
-# CONFIG_HWSPINLOCK is not set
-# CONFIG_HWSPINLOCK_OMAP is not set
-CONFIG_HW_PERF_EVENTS=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HW_RANDOM_AMD is not set
-# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set
-# CONFIG_HW_RANDOM_ATMEL is not set
-# CONFIG_HW_RANDOM_BA431 is not set
-# CONFIG_HW_RANDOM_BCM2835 is not set
-# CONFIG_HW_RANDOM_CAVIUM is not set
-# CONFIG_HW_RANDOM_CCTRNG is not set
-# CONFIG_HW_RANDOM_CN10K is not set
-# CONFIG_HW_RANDOM_EXYNOS is not set
-# CONFIG_HW_RANDOM_GEODE is not set
-# CONFIG_HW_RANDOM_INTEL is not set
-# CONFIG_HW_RANDOM_IPROC_RNG200 is not set
-# CONFIG_HW_RANDOM_MTK is not set
-# CONFIG_HW_RANDOM_OMAP is not set
-# CONFIG_HW_RANDOM_OMAP3_ROM is not set
-# CONFIG_HW_RANDOM_PPC4XX is not set
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-CONFIG_HW_RANDOM_TPM=y
-# CONFIG_HW_RANDOM_VIA is not set
-# CONFIG_HW_RANDOM_VIRTIO is not set
-# CONFIG_HW_RANDOM_XIPHERA is not set
-# CONFIG_HX711 is not set
-# CONFIG_HYPERV is not set
-# CONFIG_HYPERV_TSCPAGE is not set
-# CONFIG_HYSDN is not set
-CONFIG_HZ=100
-CONFIG_HZ_100=y
-# CONFIG_HZ_1000 is not set
-# CONFIG_HZ_1024 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_200 is not set
-# CONFIG_HZ_24 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_500 is not set
-# CONFIG_HZ_PERIODIC is not set
-# CONFIG_I2C is not set
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCA is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
-# CONFIG_I2C_AU1550 is not set
-# CONFIG_I2C_BCM2835 is not set
-# CONFIG_I2C_BCM_IPROC is not set
-# CONFIG_I2C_BRCMSTB is not set
-# CONFIG_I2C_CADENCE is not set
-# CONFIG_I2C_CBUS_GPIO is not set
-# CONFIG_I2C_CHARDEV is not set
-# CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_CP2615 is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEMUX_PINCTRL is not set
-# CONFIG_I2C_DESIGNWARE_PCI is not set
-# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
-# CONFIG_I2C_DESIGNWARE_SLAVE is not set
-# CONFIG_I2C_DIOLAN_U2C is not set
-# CONFIG_I2C_EG20T is not set
-# CONFIG_I2C_ELEKTOR is not set
-# CONFIG_I2C_EMEV2 is not set
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set
-# CONFIG_I2C_HELPER_AUTO is not set
-# CONFIG_I2C_HID is not set
-# CONFIG_I2C_HID_OF is not set
-# CONFIG_I2C_HID_OF_ELAN is not set
-# CONFIG_I2C_HID_OF_GOODIX is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_IBM_IIC is not set
-# CONFIG_I2C_IMG is not set
-# CONFIG_I2C_ISCH is not set
-# CONFIG_I2C_ISMT is not set
-# CONFIG_I2C_JZ4780 is not set
-# CONFIG_I2C_MLXCPLD is not set
-# CONFIG_I2C_MPC is not set
-# CONFIG_I2C_MT65XX is not set
-# CONFIG_I2C_MUX is not set
-# CONFIG_I2C_MUX_GPIO is not set
-# CONFIG_I2C_MUX_GPMUX is not set
-# CONFIG_I2C_MUX_LTC4306 is not set
-# CONFIG_I2C_MUX_MLXCPLD is not set
-# CONFIG_I2C_MUX_PCA9541 is not set
-# CONFIG_I2C_MUX_PCA954x is not set
-# CONFIG_I2C_MUX_PINCTRL is not set
-# CONFIG_I2C_MUX_REG is not set
-# CONFIG_I2C_MV64XXX is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_NOMADIK is not set
-# CONFIG_I2C_NVIDIA_GPU is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_OCTEON is not set
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_PCI1XXXX is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PXA_PCI is not set
-# CONFIG_I2C_PXA_SLAVE is not set
-# CONFIG_I2C_RCAR is not set
-# CONFIG_I2C_RK3X is not set
-# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
-# CONFIG_I2C_S3C2410 is not set
-# CONFIG_I2C_SCMI is not set
-# CONFIG_I2C_SH_MOBILE is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_SLAVE is not set
-# CONFIG_I2C_SLAVE_EEPROM is not set
-# CONFIG_I2C_SMBUS is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_THUNDERX is not set
-# CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VERSATILE is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VIRTIO is not set
-# CONFIG_I2C_XILINX is not set
-# CONFIG_I3C is not set
-# CONFIG_I40E is not set
-# CONFIG_I40EVF is not set
-# CONFIG_I6300ESB_WDT is not set
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_IAQCORE is not set
-# CONFIG_IBM_ASM is not set
-# CONFIG_IBM_EMAC_DEBUG is not set
-# CONFIG_IBM_EMAC_EMAC4 is not set
-# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_EMAC_RGMII is not set
-# CONFIG_IBM_EMAC_TAH is not set
-# CONFIG_IBM_EMAC_ZMII is not set
-# CONFIG_ICE is not set
-# CONFIG_ICP10100 is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_ICS932S401 is not set
-# CONFIG_ICST is not set
-# CONFIG_IDE is not set
-# CONFIG_IDEAPAD_LAPTOP is not set
-# CONFIG_IDE_GD is not set
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDLE_PAGE_TRACKING is not set
-# CONFIG_IEEE802154 is not set
-# CONFIG_IEEE802154_ADF7242 is not set
-# CONFIG_IEEE802154_ATUSB is not set
-# CONFIG_IEEE802154_CA8210 is not set
-# CONFIG_IEEE802154_HWSIM is not set
-# CONFIG_IEEE802154_MCR20A is not set
-# CONFIG_IFB is not set
-# CONFIG_IGB is not set
-# CONFIG_IGBVF is not set
-# CONFIG_IGC is not set
-# CONFIG_IIO is not set
-# CONFIG_IIO_BUFFER is not set
-# CONFIG_IIO_BUFFER_CB is not set
-# CONFIG_IIO_BUFFER_DMA is not set
-# CONFIG_IIO_BUFFER_DMAENGINE is not set
-# CONFIG_IIO_BUFFER_HDC2010 is not set
-# CONFIG_IIO_BUFFER_HW_CONSUMER is not set
-# CONFIG_IIO_CONFIGFS is not set
-CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
-# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set
-# CONFIG_IIO_INTERRUPT_TRIGGER is not set
-# CONFIG_IIO_MUX is not set
-# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
-# CONFIG_IIO_RESCALE is not set
-# CONFIG_IIO_SIMPLE_DUMMY is not set
-# CONFIG_IIO_SSP_SENSORHUB is not set
-# CONFIG_IIO_ST_ACCEL_3AXIS is not set
-# CONFIG_IIO_ST_GYRO_3AXIS is not set
-# CONFIG_IIO_ST_LSM6DSX is not set
-# CONFIG_IIO_ST_LSM9DS0 is not set
-# CONFIG_IIO_ST_MAGN_3AXIS is not set
-# CONFIG_IIO_ST_PRESS is not set
-# CONFIG_IIO_SW_DEVICE is not set
-# CONFIG_IIO_SW_TRIGGER is not set
-# CONFIG_IIO_SYSFS_TRIGGER is not set
-# CONFIG_IIO_TRIGGER is not set
-# CONFIG_IIO_TRIGGERED_EVENT is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_IKCONFIG_PROC is not set
-# CONFIG_IKHEADERS is not set
-# CONFIG_IMA is not set
-# CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMGPDC_WDT is not set
-# CONFIG_IMG_MDC_DMA is not set
-# CONFIG_IMX7D_ADC is not set
-# CONFIG_IMX8QXP_ADC is not set
-# CONFIG_IMX_IPUV3_CORE is not set
-# CONFIG_IMX_THERMAL is not set
-# CONFIG_INA2XX_ADC is not set
-# CONFIG_INDIRECT_PIO is not set
-CONFIG_INET=y
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_ESPINTCP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_ESPINTCP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_LRO is not set
-CONFIG_INET_TABLE_PERTURB_ORDER=16
-# CONFIG_INET_TCP_DIAG is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_UDP_DIAG is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INFINIBAND is not set
-# CONFIG_INFTL is not set
-# CONFIG_INGENIC_ADC is not set
-# CONFIG_INGENIC_CGU_JZ4725B is not set
-# CONFIG_INGENIC_CGU_JZ4740 is not set
-# CONFIG_INGENIC_CGU_JZ4760 is not set
-# CONFIG_INGENIC_CGU_JZ4770 is not set
-# CONFIG_INGENIC_CGU_JZ4780 is not set
-# CONFIG_INGENIC_CGU_X1000 is not set
-# CONFIG_INGENIC_CGU_X1830 is not set
-# CONFIG_INGENIC_OST is not set
-# CONFIG_INGENIC_SYSOST is not set
-# CONFIG_INGENIC_TCU_CLK is not set
-# CONFIG_INGENIC_TCU_IRQ is not set
-# CONFIG_INGENIC_TIMER is not set
-# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
-CONFIG_INIT_ENV_ARG_LIMIT=32
-# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
-# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
-# CONFIG_INIT_STACK_ALL_PATTERN is not set
-# CONFIG_INIT_STACK_ALL_ZERO is not set
-CONFIG_INIT_STACK_NONE=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_AD714X is not set
-# CONFIG_INPUT_ADXL34X is not set
-# CONFIG_INPUT_APANEL is not set
-# CONFIG_INPUT_ATI_REMOTE2 is not set
-# CONFIG_INPUT_ATLAS_BTNS is not set
-# CONFIG_INPUT_ATMEL_CAPTOUCH is not set
-# CONFIG_INPUT_AXP20X_PEK is not set
-# CONFIG_INPUT_BMA150 is not set
-# CONFIG_INPUT_CM109 is not set
-# CONFIG_INPUT_CMA3000 is not set
-# CONFIG_INPUT_DA7280_HAPTICS is not set
-# CONFIG_INPUT_DRV260X_HAPTICS is not set
-# CONFIG_INPUT_DRV2665_HAPTICS is not set
-# CONFIG_INPUT_DRV2667_HAPTICS is not set
-# CONFIG_INPUT_E3X0_BUTTON is not set
-# CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_GP2A is not set
-# CONFIG_INPUT_GPIO_BEEPER is not set
-# CONFIG_INPUT_GPIO_DECODER is not set
-# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
-# CONFIG_INPUT_GPIO_TILT_POLLED is not set
-# CONFIG_INPUT_GPIO_VIBRA is not set
-# CONFIG_INPUT_IBM_PANEL is not set
-# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set
-# CONFIG_INPUT_IMS_PCU is not set
-# CONFIG_INPUT_IQS269A is not set
-# CONFIG_INPUT_IQS626A is not set
-# CONFIG_INPUT_IQS7222 is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_KEYSPAN_REMOTE is not set
-# CONFIG_INPUT_KXTJ9 is not set
-# CONFIG_INPUT_LEDS is not set
-# CONFIG_INPUT_MATRIXKMAP is not set
-# CONFIG_INPUT_MAX8997_HAPTIC is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_MMA8450 is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_MPU3050 is not set
-# CONFIG_INPUT_MSM_VIBRATOR is not set
-# CONFIG_INPUT_PALMAS_PWRBUTTON is not set
-# CONFIG_INPUT_PCF8574 is not set
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_PM8941_PWRKEY is not set
-# CONFIG_INPUT_PM8XXX_VIBRATOR is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_POWERMATE is not set
-# CONFIG_INPUT_PWM_BEEPER is not set
-# CONFIG_INPUT_PWM_VIBRA is not set
-# CONFIG_INPUT_RASPBERRYPI_BUTTON is not set
-# CONFIG_INPUT_REGULATOR_HAPTIC is not set
-# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_TPS65218_PWRBUTTON is not set
-# CONFIG_INPUT_TWL4030_PWRBUTTON is not set
-# CONFIG_INPUT_TWL4030_VIBRA is not set
-# CONFIG_INPUT_TWL6040_VIBRA is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_INPUT_WISTRON_BTNS is not set
-# CONFIG_INPUT_YEALINK is not set
-# CONFIG_INT340X_THERMAL is not set
-# CONFIG_INTEGRITY is not set
-# CONFIG_INTEGRITY_AUDIT is not set
-# CONFIG_INTEGRITY_SIGNATURE is not set
-# CONFIG_INTEL_ATOMISP2_LED is not set
-# CONFIG_INTEL_ATOMISP2_PM is not set
-# CONFIG_INTEL_CHT_INT33FE is not set
-# CONFIG_INTEL_HID_EVENT is not set
-# CONFIG_INTEL_IDLE is not set
-# CONFIG_INTEL_IDMA64 is not set
-# CONFIG_INTEL_INT0002_VGPIO is not set
-# CONFIG_INTEL_IOATDMA is not set
-# CONFIG_INTEL_ISH_HID is not set
-# CONFIG_INTEL_MEI is not set
-# CONFIG_INTEL_MEI_ME is not set
-# CONFIG_INTEL_MEI_TXE is not set
-# CONFIG_INTEL_MIC_CARD is not set
-# CONFIG_INTEL_MIC_HOST is not set
-# CONFIG_INTEL_MID_PTI is not set
-# CONFIG_INTEL_OAKTRAIL is not set
-# CONFIG_INTEL_PMC_CORE is not set
-# CONFIG_INTEL_PUNIT_IPC is not set
-# CONFIG_INTEL_RST is not set
-# CONFIG_INTEL_SMARTCONNECT is not set
-# CONFIG_INTEL_SOC_PMIC is not set
-# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set
-# CONFIG_INTEL_SOC_PMIC_CHTWC is not set
-# CONFIG_INTEL_TH is not set
-# CONFIG_INTEL_VBTN is not set
-# CONFIG_INTEL_XWAY_PHY is not set
-# CONFIG_INTERCONNECT is not set
-# CONFIG_INTERVAL_TREE_TEST is not set
-# CONFIG_INV_ICM42600_I2C is not set
-# CONFIG_INV_ICM42600_SPI is not set
-# CONFIG_INV_MPU6050_I2C is not set
-# CONFIG_INV_MPU6050_IIO is not set
-# CONFIG_INV_MPU6050_SPI is not set
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_IONIC is not set
-# CONFIG_IOSCHED_BFQ is not set
-# CONFIG_IOSM is not set
-CONFIG_IO_STRICT_DEVMEM=y
-# CONFIG_IO_URING is not set
-CONFIG_IO_WQ=y
-# CONFIG_IP17XX_PHY is not set
-# CONFIG_IP5XXX_POWER is not set
-# CONFIG_IP6_NF_FILTER is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_IP6_NF_MATCH_AH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_MH is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_RPFILTER is not set
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_SRH is not set
-# CONFIG_IP6_NF_NAT is not set
-# CONFIG_IP6_NF_RAW is not set
-# CONFIG_IP6_NF_SECURITY is not set
-# CONFIG_IP6_NF_TARGET_HL is not set
-# CONFIG_IP6_NF_TARGET_MASQUERADE is not set
-# CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IP6_NF_TARGET_SYNPROXY is not set
-# CONFIG_IPACK_BUS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_IPMB_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPV6 is not set
-# CONFIG_IPV6_FOU is not set
-# CONFIG_IPV6_FOU_TUNNEL is not set
-# CONFIG_IPV6_ILA is not set
-# CONFIG_IPV6_IOAM6_LWTUNNEL is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_ROUTE_INFO is not set
-# CONFIG_IPV6_RPL_LWTUNNEL is not set
-# CONFIG_IPV6_SEG6_HMAC is not set
-# CONFIG_IPV6_SEG6_LWTUNNEL is not set
-# CONFIG_IPV6_SIT is not set
-# CONFIG_IPV6_SIT_6RD is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_VTI is not set
-# CONFIG_IPVLAN is not set
-# CONFIG_IPVTAP is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2100_DEBUG is not set
-CONFIG_IPW2100_MONITOR=y
-# CONFIG_IPW2200 is not set
-# CONFIG_IPW2200_DEBUG is not set
-CONFIG_IPW2200_MONITOR=y
-# CONFIG_IPW2200_PROMISCUOUS is not set
-# CONFIG_IPW2200_QOS is not set
-# CONFIG_IPW2200_RADIOTAP is not set
-# CONFIG_IPWIRELESS is not set
-# CONFIG_IPX is not set
-CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_FIB_TRIE_STATS is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_NF_ARPFILTER is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_ARP_MANGLE is not set
-# CONFIG_IP_NF_FILTER is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_MANGLE is not set
-# CONFIG_IP_NF_MATCH_AH is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_RPFILTER is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_RAW is not set
-# CONFIG_IP_NF_SECURITY is not set
-# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_MASQUERADE is not set
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_REDIRECT is not set
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_SYNPROXY is not set
-# CONFIG_IP_NF_TARGET_TTL is not set
-# CONFIG_IP_PIMSM_V1 is not set
-# CONFIG_IP_PIMSM_V2 is not set
-# CONFIG_IP_PNP is not set
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_IP_SET is not set
-# CONFIG_IP_SET_HASH_IPMAC is not set
-# CONFIG_IP_VS is not set
-# CONFIG_IP_VS_MH is not set
-CONFIG_IP_VS_MH_TAB_INDEX=10
-# CONFIG_IP_VS_TWOS is not set
-# CONFIG_IRDA is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_IRQ_ALL_CPUS is not set
-# CONFIG_IRQ_DOMAIN_DEBUG is not set
-# CONFIG_IRQ_POLL is not set
-# CONFIG_IRQ_TIME_ACCOUNTING is not set
-# CONFIG_IR_GPIO_CIR is not set
-# CONFIG_IR_HIX5HD2 is not set
-# CONFIG_IR_IGORPLUGUSB is not set
-# CONFIG_IR_IGUANA is not set
-# CONFIG_IR_IMG is not set
-# CONFIG_IR_IMON is not set
-# CONFIG_IR_IMON_RAW is not set
-# CONFIG_IR_JVC_DECODER is not set
-# CONFIG_IR_LIRC_CODEC is not set
-# CONFIG_IR_MCEUSB is not set
-# CONFIG_IR_NEC_DECODER is not set
-# CONFIG_IR_RC5_DECODER is not set
-# CONFIG_IR_RC6_DECODER is not set
-# CONFIG_IR_REDRAT3 is not set
-# CONFIG_IR_SERIAL is not set
-# CONFIG_IR_SIR is not set
-# CONFIG_IR_SONY_DECODER is not set
-# CONFIG_IR_STREAMZAP is not set
-# CONFIG_IR_TOY is not set
-# CONFIG_IR_TTUSBIR is not set
-# CONFIG_ISA_BUS is not set
-# CONFIG_ISA_BUS_API is not set
-# CONFIG_ISCSI_BOOT_SYSFS is not set
-# CONFIG_ISCSI_TCP is not set
-CONFIG_ISDN=y
-# CONFIG_ISDN_AUDIO is not set
-# CONFIG_ISDN_CAPI is not set
-# CONFIG_ISDN_CAPI_CAPIDRV is not set
-# CONFIG_ISDN_DIVERSION is not set
-# CONFIG_ISDN_DRV_ACT2000 is not set
-# CONFIG_ISDN_DRV_GIGASET is not set
-# CONFIG_ISDN_DRV_HISAX is not set
-# CONFIG_ISDN_DRV_ICN is not set
-# CONFIG_ISDN_DRV_LOOP is not set
-# CONFIG_ISDN_DRV_PCBIT is not set
-# CONFIG_ISDN_DRV_SC is not set
-# CONFIG_ISDN_I4L is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_ISL29020 is not set
-# CONFIG_ISL29125 is not set
-# CONFIG_ISL29501 is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_ISS4xx is not set
-# CONFIG_ITG3200 is not set
-# CONFIG_IWL3945 is not set
-# CONFIG_IWLWIFI is not set
-# CONFIG_IXGB is not set
-# CONFIG_IXGBE is not set
-# CONFIG_IXGBEVF is not set
-# CONFIG_JAILHOUSE_GUEST is not set
-# CONFIG_JBD2_DEBUG is not set
-# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_POSIX_ACL is not set
-# CONFIG_JFFS2_FS_SECURITY is not set
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_LZMA=y
-# CONFIG_JFFS2_LZO is not set
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_JFFS2_SUMMARY=y
-# CONFIG_JFFS2_ZLIB is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_POSIX_ACL is not set
-# CONFIG_JFS_SECURITY is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_JME is not set
-CONFIG_JOLIET=y
-# CONFIG_JSA1212 is not set
-# CONFIG_JUMP_LABEL is not set
-# CONFIG_JZ4740_WDT is not set
-# CONFIG_JZ4770_PHY is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set
-# CONFIG_KALLSYMS_ALL is not set
-CONFIG_KALLSYMS_BASE_RELATIVE=y
-# CONFIG_KALLSYMS_UNCOMPRESSED is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_KASAN is not set
-# CONFIG_KASAN_MODULE_TEST is not set
-CONFIG_KASAN_STACK=y
-# CONFIG_KCMP is not set
-# CONFIG_KCOV is not set
-CONFIG_KCOV_IRQ_AREA_SIZE=0x40000
-# CONFIG_KCSAN is not set
-# CONFIG_KERNEL_BZIP2 is not set
-# CONFIG_KERNEL_CAT is not set
-# CONFIG_KERNEL_GZIP is not set
-# CONFIG_KERNEL_LZ4 is not set
-# CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_LZO is not set
-CONFIG_KERNEL_MODE_NEON=y
-CONFIG_KERNEL_XZ=y
-# CONFIG_KERNEL_ZSTD is not set
-CONFIG_KERNFS=y
-# CONFIG_KEXEC is not set
-# CONFIG_KEXEC_FILE is not set
-# CONFIG_KEXEC_SIG is not set
-# CONFIG_KEYBOARD_ADC is not set
-# CONFIG_KEYBOARD_ADP5588 is not set
-# CONFIG_KEYBOARD_ADP5589 is not set
-# CONFIG_KEYBOARD_APPLESPI is not set
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_BCM is not set
-# CONFIG_KEYBOARD_CAP11XX is not set
-# CONFIG_KEYBOARD_CYPRESS_SF is not set
-# CONFIG_KEYBOARD_DLINK_DIR685 is not set
-# CONFIG_KEYBOARD_GPIO is not set
-# CONFIG_KEYBOARD_GPIO_POLLED is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_LM8323 is not set
-# CONFIG_KEYBOARD_LM8333 is not set
-# CONFIG_KEYBOARD_MATRIX is not set
-# CONFIG_KEYBOARD_MAX7359 is not set
-# CONFIG_KEYBOARD_MCS is not set
-# CONFIG_KEYBOARD_MPR121 is not set
-# CONFIG_KEYBOARD_MT6779 is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_OMAP4 is not set
-# CONFIG_KEYBOARD_OPENCORES is not set
-# CONFIG_KEYBOARD_PINEPHONE is not set
-# CONFIG_KEYBOARD_PXA27x is not set
-# CONFIG_KEYBOARD_QT1050 is not set
-# CONFIG_KEYBOARD_QT1070 is not set
-# CONFIG_KEYBOARD_QT2160 is not set
-# CONFIG_KEYBOARD_SAMSUNG is not set
-# CONFIG_KEYBOARD_SH_KEYSC is not set
-# CONFIG_KEYBOARD_SNVS_PWRKEY is not set
-# CONFIG_KEYBOARD_STMPE is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_TCA6416 is not set
-# CONFIG_KEYBOARD_TCA8418 is not set
-# CONFIG_KEYBOARD_TEGRA is not set
-# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set
-# CONFIG_KEYBOARD_TWL4030 is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYS is not set
-# CONFIG_KEYS_REQUEST_CACHE is not set
-# CONFIG_KEY_DH_OPERATIONS is not set
-# CONFIG_KFENCE is not set
-# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
-# CONFIG_KMX61 is not set
-# CONFIG_KPC2000 is not set
-# CONFIG_KPROBES is not set
-# CONFIG_KPROBES_SANITY_TEST is not set
-# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set
-# CONFIG_KPROBE_EVENT_GEN_TEST is not set
-# CONFIG_KS7010 is not set
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851 is not set
-# CONFIG_KS8851_MLL is not set
-# CONFIG_KSM is not set
-# CONFIG_KSZ884X_PCI is not set
-# CONFIG_KUNIT is not set
-CONFIG_KUSER_HELPERS=y
-# CONFIG_KVM_AMD is not set
-# CONFIG_KVM_AMD_SEV is not set
-# CONFIG_KVM_GUEST is not set
-# CONFIG_KVM_INTEL is not set
-# CONFIG_KVM_WERROR is not set
-# CONFIG_KVM_XEN is not set
-# CONFIG_KXCJK1013 is not set
-# CONFIG_KXSD9 is not set
-# CONFIG_L2TP is not set
-# CONFIG_L2TP_ETH is not set
-# CONFIG_L2TP_IP is not set
-# CONFIG_L2TP_V3 is not set
-# CONFIG_LAN743X is not set
-# CONFIG_LAN966X_SWITCH is not set
-# CONFIG_LANMEDIA is not set
-# CONFIG_LANTIQ is not set
-# CONFIG_LAPB is not set
-# CONFIG_LASAT is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_LATTICE_ECP3_CONFIG is not set
-CONFIG_LBDAF=y
-# CONFIG_LCD_AMS369FG06 is not set
-# CONFIG_LCD_CLASS_DEVICE is not set
-# CONFIG_LCD_HX8357 is not set
-# CONFIG_LCD_ILI922X is not set
-# CONFIG_LCD_ILI9320 is not set
-# CONFIG_LCD_L4F00242T03 is not set
-# CONFIG_LCD_LD9040 is not set
-# CONFIG_LCD_LMS283GF05 is not set
-# CONFIG_LCD_LMS501KF03 is not set
-# CONFIG_LCD_LTV350QV is not set
-# CONFIG_LCD_OTM3225A is not set
-# CONFIG_LCD_S6E63M0 is not set
-# CONFIG_LCD_TDO24M is not set
-# CONFIG_LCD_VGG2432A4 is not set
-CONFIG_LDISC_AUTOLOAD=y
-# CONFIG_LDM_PARTITION is not set
-CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
-# CONFIG_LD_HEAD_STUB_CATCH is not set
-# CONFIG_LEDS_AN30259A is not set
-# CONFIG_LEDS_APU is not set
-# CONFIG_LEDS_AW2013 is not set
-# CONFIG_LEDS_BCM6328 is not set
-# CONFIG_LEDS_BCM6358 is not set
-# CONFIG_LEDS_BD2802 is not set
-# CONFIG_LEDS_BLINKM is not set
-CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
-CONFIG_LEDS_CLASS=y
-# CONFIG_LEDS_CLASS_FLASH is not set
-CONFIG_LEDS_CLASS_MULTICOLOR=y
-# CONFIG_LEDS_CR0014114 is not set
-# CONFIG_LEDS_DAC124S085 is not set
-# CONFIG_LEDS_EL15203000 is not set
-# CONFIG_LEDS_GPIO is not set
-# CONFIG_LEDS_INTEL_SS4200 is not set
-# CONFIG_LEDS_IS31FL319X is not set
-# CONFIG_LEDS_IS31FL32XX is not set
-# CONFIG_LEDS_LM3530 is not set
-# CONFIG_LEDS_LM3532 is not set
-# CONFIG_LEDS_LM355x is not set
-# CONFIG_LEDS_LM3642 is not set
-# CONFIG_LEDS_LM3692X is not set
-# CONFIG_LEDS_LP3944 is not set
-# CONFIG_LEDS_LP3952 is not set
-# CONFIG_LEDS_LP50XX is not set
-# CONFIG_LEDS_LP5521 is not set
-# CONFIG_LEDS_LP5523 is not set
-# CONFIG_LEDS_LP5562 is not set
-# CONFIG_LEDS_LP55XX_COMMON is not set
-# CONFIG_LEDS_LP8501 is not set
-# CONFIG_LEDS_LP8860 is not set
-# CONFIG_LEDS_LT3593 is not set
-# CONFIG_LEDS_MLXCPLD is not set
-# CONFIG_LEDS_MLXREG is not set
-# CONFIG_LEDS_NIC78BX is not set
-# CONFIG_LEDS_NS2 is not set
-# CONFIG_LEDS_OT200 is not set
-# CONFIG_LEDS_PCA9532 is not set
-# CONFIG_LEDS_PCA955X is not set
-# CONFIG_LEDS_PCA963X is not set
-# CONFIG_LEDS_PWM is not set
-# CONFIG_LEDS_PWM_MULTICOLOR is not set
-# CONFIG_LEDS_REGULATOR is not set
-# CONFIG_LEDS_SPI_BYTE is not set
-# CONFIG_LEDS_SYSCON is not set
-# CONFIG_LEDS_TCA6507 is not set
-# CONFIG_LEDS_TI_LMU_COMMON is not set
-# CONFIG_LEDS_TLC591XX is not set
-CONFIG_LEDS_TRIGGERS=y
-# CONFIG_LEDS_TRIGGER_ACTIVITY is not set
-# CONFIG_LEDS_TRIGGER_AUDIO is not set
-# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
-# CONFIG_LEDS_TRIGGER_CAMERA is not set
-# CONFIG_LEDS_TRIGGER_CPU is not set
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-# CONFIG_LEDS_TRIGGER_DISK is not set
-# CONFIG_LEDS_TRIGGER_GPIO is not set
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-# CONFIG_LEDS_TRIGGER_MTD is not set
-CONFIG_LEDS_TRIGGER_NETDEV=y
-# CONFIG_LEDS_TRIGGER_ONESHOT is not set
-# CONFIG_LEDS_TRIGGER_PANIC is not set
-# CONFIG_LEDS_TRIGGER_PATTERN is not set
-CONFIG_LEDS_TRIGGER_TIMER=y
-# CONFIG_LEDS_TRIGGER_TRANSIENT is not set
-# CONFIG_LEDS_TRIGGER_TTY is not set
-# CONFIG_LEDS_TURRIS_OMNIA is not set
-# CONFIG_LEDS_USER is not set
-# CONFIG_LED_TRIGGER_PHY is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_LGUEST is not set
-# CONFIG_LIB80211 is not set
-# CONFIG_LIB80211_CRYPT_CCMP is not set
-# CONFIG_LIB80211_CRYPT_TKIP is not set
-# CONFIG_LIB80211_CRYPT_WEP is not set
-# CONFIG_LIB80211_DEBUG is not set
-# CONFIG_LIBCRC32C is not set
-# CONFIG_LIBERTAS is not set
-# CONFIG_LIBERTAS_THINFIRM is not set
-# CONFIG_LIBERTAS_USB is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_LIBIPW_DEBUG is not set
-# CONFIG_LIBNVDIMM is not set
-CONFIG_LIB_MEMNEQ=y
-# CONFIG_LIDAR_LITE_V2 is not set
-CONFIG_LINEAR_RANGES=y
-# CONFIG_LIQUIDIO is not set
-# CONFIG_LIQUIDIO_VF is not set
-# CONFIG_LIRC is not set
-# CONFIG_LIS3L02DQ is not set
-# CONFIG_LITEX_LITEETH is not set
-# CONFIG_LITEX_SOC_CONTROLLER is not set
-# CONFIG_LIVEPATCH is not set
-# CONFIG_LKDTM is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_LMK04832 is not set
-# CONFIG_LMP91000 is not set
-# CONFIG_LNET is not set
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_LOCKD is not set
-CONFIG_LOCKDEP_BITS=15
-CONFIG_LOCKDEP_CHAINS_BITS=16
-CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
-CONFIG_LOCKDEP_STACK_TRACE_BITS=19
-CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_LOCKD_V4=y
-# CONFIG_LOCKUP_DETECTOR is not set
-# CONFIG_LOCK_EVENT_COUNTS is not set
-CONFIG_LOCK_MM_AND_FIND_VMA=y
-# CONFIG_LOCK_STAT is not set
-# CONFIG_LOCK_TORTURE_TEST is not set
-# CONFIG_LOGFS is not set
-# CONFIG_LOGIG940_FF is not set
-# CONFIG_LOGIRUMBLEPAD2_FF is not set
-# CONFIG_LOGITECH_FF is not set
-# CONFIG_LOGIWHEELS_FF is not set
-# CONFIG_LOGO is not set
-CONFIG_LOG_BUF_SHIFT=17
-CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
-# CONFIG_LOONGSON_MC146818 is not set
-# CONFIG_LPC_ICH is not set
-# CONFIG_LPC_SCH is not set
-# CONFIG_LP_CONSOLE is not set
-CONFIG_LRU_GEN=y
-CONFIG_LRU_GEN_ENABLED=y
-# CONFIG_LRU_GEN_STATS is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity"
-CONFIG_LSM_MMAP_MIN_ADDR=65536
-# CONFIG_LTC1660 is not set
-# CONFIG_LTC2471 is not set
-# CONFIG_LTC2485 is not set
-# CONFIG_LTC2496 is not set
-# CONFIG_LTC2497 is not set
-# CONFIG_LTC2632 is not set
-# CONFIG_LTC2688 is not set
-# CONFIG_LTC2983 is not set
-# CONFIG_LTE_GDM724X is not set
-CONFIG_LTO_NONE=y
-# CONFIG_LTPC is not set
-# CONFIG_LTR501 is not set
-# CONFIG_LTRF216A is not set
-# CONFIG_LUSTRE_FS is not set
-# CONFIG_LV0104CS is not set
-# CONFIG_LWTUNNEL is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_LZ4HC_COMPRESS is not set
-# CONFIG_LZ4_COMPRESS is not set
-# CONFIG_LZ4_DECOMPRESS is not set
-CONFIG_LZMA_COMPRESS=y
-CONFIG_LZMA_DECOMPRESS=y
-# CONFIG_LZO_COMPRESS is not set
-# CONFIG_LZO_DECOMPRESS is not set
-# CONFIG_M62332 is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_MAC80211_MESSAGE_TRACING is not set
-CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
-# CONFIG_MACB is not set
-# CONFIG_MACH_ASM9260 is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MACH_INGENIC is not set
-# CONFIG_MACH_INGENIC_SOC is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_JZ4740 is not set
-# CONFIG_MACH_LOONGSON2EF is not set
-# CONFIG_MACH_LOONGSON32 is not set
-# CONFIG_MACH_LOONGSON64 is not set
-# CONFIG_MACH_NINTENDO64 is not set
-# CONFIG_MACH_PIC32 is not set
-# CONFIG_MACH_PISTACHIO is not set
-# CONFIG_MACH_REALTEK_RTL is not set
-# CONFIG_MACH_TX39XX is not set
-# CONFIG_MACH_TX49XX is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_MACH_XILFPGA is not set
-# CONFIG_MACINTOSH_DRIVERS is not set
-# CONFIG_MACSEC is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_MACVTAP is not set
-# CONFIG_MAC_EMUMOUSEBTN is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MAG3110 is not set
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
-# CONFIG_MAGIC_SYSRQ_SERIAL is not set
-CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
-# CONFIG_MAILBOX is not set
-# CONFIG_MANAGER_SBS is not set
-# CONFIG_MANDATORY_FILE_LOCKING is not set
-# CONFIG_MANGLE_BOOTARGS is not set
-# CONFIG_MARVELL_10G_PHY is not set
-# CONFIG_MARVELL_88X2222_PHY is not set
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_MAX1027 is not set
-# CONFIG_MAX11100 is not set
-# CONFIG_MAX1118 is not set
-# CONFIG_MAX11205 is not set
-# CONFIG_MAX1241 is not set
-# CONFIG_MAX1363 is not set
-# CONFIG_MAX30100 is not set
-# CONFIG_MAX30102 is not set
-# CONFIG_MAX31856 is not set
-# CONFIG_MAX31865 is not set
-# CONFIG_MAX44000 is not set
-# CONFIG_MAX44009 is not set
-# CONFIG_MAX517 is not set
-# CONFIG_MAX5432 is not set
-# CONFIG_MAX5481 is not set
-# CONFIG_MAX5487 is not set
-# CONFIG_MAX5821 is not set
-# CONFIG_MAX63XX_WATCHDOG is not set
-# CONFIG_MAX9611 is not set
-# CONFIG_MAXIM_THERMOCOUPLE is not set
-# CONFIG_MAXLINEAR_GPHY is not set
-CONFIG_MAY_USE_DEVLINK=y
-# CONFIG_MB1232 is not set
-# CONFIG_MC3230 is not set
-# CONFIG_MCB is not set
-# CONFIG_MCP320X is not set
-# CONFIG_MCP3422 is not set
-# CONFIG_MCP3911 is not set
-# CONFIG_MCP4018 is not set
-# CONFIG_MCP41010 is not set
-# CONFIG_MCP4131 is not set
-# CONFIG_MCP4531 is not set
-# CONFIG_MCP4725 is not set
-# CONFIG_MCP4922 is not set
-# CONFIG_MCPM is not set
-# CONFIG_MCTP is not set
-# CONFIG_MD is not set
-# CONFIG_MDIO_BCM_UNIMAC is not set
-# CONFIG_MDIO_BITBANG is not set
-# CONFIG_MDIO_BUS_MUX_GPIO is not set
-# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
-# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set
-# CONFIG_MDIO_DEVICE is not set
-# CONFIG_MDIO_DEVRES is not set
-# CONFIG_MDIO_HISI_FEMAC is not set
-# CONFIG_MDIO_IPQ4019 is not set
-# CONFIG_MDIO_IPQ8064 is not set
-# CONFIG_MDIO_MSCC_MIIM is not set
-# CONFIG_MDIO_MVUSB is not set
-# CONFIG_MDIO_OCTEON is not set
-# CONFIG_MDIO_THUNDER is not set
-# CONFIG_MDIO_XPCS is not set
-# CONFIG_MDM_GCC_9607 is not set
-# CONFIG_MD_FAULTY is not set
-# CONFIG_MEDIATEK_GE_PHY is not set
-# CONFIG_MEDIATEK_MT6577_AUXADC is not set
-# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
-# CONFIG_MEDIA_ATTACH is not set
-# CONFIG_MEDIA_CAMERA_SUPPORT is not set
-# CONFIG_MEDIA_CEC_SUPPORT is not set
-# CONFIG_MEDIA_CONTROLLER is not set
-# CONFIG_MEDIA_CONTROLLER_DVB is not set
-# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
-# CONFIG_MEDIA_PCI_SUPPORT is not set
-# CONFIG_MEDIA_PLATFORM_DRIVERS is not set
-# CONFIG_MEDIA_PLATFORM_SUPPORT is not set
-# CONFIG_MEDIA_RADIO_SUPPORT is not set
-# CONFIG_MEDIA_RC_SUPPORT is not set
-# CONFIG_MEDIA_SDR_SUPPORT is not set
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
-# CONFIG_MEDIA_SUPPORT is not set
-# CONFIG_MEDIA_SUPPORT_FILTER is not set
-# CONFIG_MEDIA_TEST_SUPPORT is not set
-# CONFIG_MEDIA_TUNER_E4000 is not set
-# CONFIG_MEDIA_TUNER_FC0011 is not set
-# CONFIG_MEDIA_TUNER_FC0012 is not set
-# CONFIG_MEDIA_TUNER_FC0013 is not set
-# CONFIG_MEDIA_TUNER_FC2580 is not set
-# CONFIG_MEDIA_TUNER_IT913X is not set
-# CONFIG_MEDIA_TUNER_M88RS6000T is not set
-# CONFIG_MEDIA_TUNER_MAX2165 is not set
-# CONFIG_MEDIA_TUNER_MC44S803 is not set
-# CONFIG_MEDIA_TUNER_MSI001 is not set
-# CONFIG_MEDIA_TUNER_MT2060 is not set
-# CONFIG_MEDIA_TUNER_MT2063 is not set
-# CONFIG_MEDIA_TUNER_MT20XX is not set
-# CONFIG_MEDIA_TUNER_MT2131 is not set
-# CONFIG_MEDIA_TUNER_MT2266 is not set
-# CONFIG_MEDIA_TUNER_MXL301RF is not set
-# CONFIG_MEDIA_TUNER_MXL5005S is not set
-# CONFIG_MEDIA_TUNER_MXL5007T is not set
-# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set
-# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set
-# CONFIG_MEDIA_TUNER_QT1010 is not set
-# CONFIG_MEDIA_TUNER_R820T is not set
-# CONFIG_MEDIA_TUNER_SI2157 is not set
-# CONFIG_MEDIA_TUNER_SIMPLE is not set
-# CONFIG_MEDIA_TUNER_TDA18212 is not set
-# CONFIG_MEDIA_TUNER_TDA18218 is not set
-# CONFIG_MEDIA_TUNER_TDA18250 is not set
-# CONFIG_MEDIA_TUNER_TDA18271 is not set
-# CONFIG_MEDIA_TUNER_TDA827X is not set
-# CONFIG_MEDIA_TUNER_TDA8290 is not set
-# CONFIG_MEDIA_TUNER_TDA9887 is not set
-# CONFIG_MEDIA_TUNER_TEA5761 is not set
-# CONFIG_MEDIA_TUNER_TEA5767 is not set
-# CONFIG_MEDIA_TUNER_TUA9001 is not set
-# CONFIG_MEDIA_TUNER_XC2028 is not set
-# CONFIG_MEDIA_TUNER_XC4000 is not set
-# CONFIG_MEDIA_TUNER_XC5000 is not set
-# CONFIG_MEDIA_USB_SUPPORT is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_MELLANOX_PLATFORM is not set
-CONFIG_MEMBARRIER=y
-# CONFIG_MEMORY is not set
-# CONFIG_MEMORY_FAILURE is not set
-# CONFIG_MEMORY_HOTPLUG is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_MEMTEST is not set
-# CONFIG_MEN_A21_WDT is not set
-# CONFIG_MESON_SM is not set
-CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
-# CONFIG_MFD_88PM800 is not set
-# CONFIG_MFD_88PM805 is not set
-# CONFIG_MFD_88PM860X is not set
-# CONFIG_MFD_AAT2870_CORE is not set
-# CONFIG_MFD_AC100 is not set
-# CONFIG_MFD_ACT8945A is not set
-# CONFIG_MFD_ARIZONA_I2C is not set
-# CONFIG_MFD_ARIZONA_SPI is not set
-# CONFIG_MFD_AS3711 is not set
-# CONFIG_MFD_AS3722 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_MFD_ATC260X_I2C is not set
-# CONFIG_MFD_ATMEL_FLEXCOM is not set
-# CONFIG_MFD_ATMEL_HLCDC is not set
-# CONFIG_MFD_AXP20X is not set
-# CONFIG_MFD_AXP20X_I2C is not set
-# CONFIG_MFD_BCM590XX is not set
-# CONFIG_MFD_BD9571MWV is not set
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_CPCAP is not set
-# CONFIG_MFD_CROS_EC is not set
-# CONFIG_MFD_CS5535 is not set
-# CONFIG_MFD_DA9052_I2C is not set
-# CONFIG_MFD_DA9052_SPI is not set
-# CONFIG_MFD_DA9055 is not set
-# CONFIG_MFD_DA9062 is not set
-# CONFIG_MFD_DA9063 is not set
-# CONFIG_MFD_DA9150 is not set
-# CONFIG_MFD_DLN2 is not set
-# CONFIG_MFD_EXYNOS_LPASS is not set
-# CONFIG_MFD_GATEWORKS_GSC is not set
-# CONFIG_MFD_HI6421_PMIC is not set
-# CONFIG_MFD_INTEL_M10_BMC is not set
-# CONFIG_MFD_INTEL_PMT is not set
-# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set
-# CONFIG_MFD_IQS62X is not set
-# CONFIG_MFD_JANZ_CMODIO is not set
-# CONFIG_MFD_KEMPLD is not set
-# CONFIG_MFD_LM3533 is not set
-# CONFIG_MFD_LOCHNAGAR is not set
-# CONFIG_MFD_LP3943 is not set
-# CONFIG_MFD_LP8788 is not set
-# CONFIG_MFD_MADERA is not set
-# CONFIG_MFD_MAX14577 is not set
-# CONFIG_MFD_MAX77620 is not set
-# CONFIG_MFD_MAX77650 is not set
-# CONFIG_MFD_MAX77686 is not set
-# CONFIG_MFD_MAX77693 is not set
-# CONFIG_MFD_MAX77714 is not set
-# CONFIG_MFD_MAX77843 is not set
-# CONFIG_MFD_MAX8907 is not set
-# CONFIG_MFD_MAX8925 is not set
-# CONFIG_MFD_MAX8997 is not set
-# CONFIG_MFD_MAX8998 is not set
-# CONFIG_MFD_MC13XXX is not set
-# CONFIG_MFD_MC13XXX_I2C is not set
-# CONFIG_MFD_MC13XXX_SPI is not set
-# CONFIG_MFD_MENF21BMC is not set
-# CONFIG_MFD_MP2629 is not set
-# CONFIG_MFD_MT6360 is not set
-# CONFIG_MFD_MT6370 is not set
-# CONFIG_MFD_MT6397 is not set
-# CONFIG_MFD_NTXEC is not set
-# CONFIG_MFD_OCELOT is not set
-# CONFIG_MFD_OMAP_USB_HOST is not set
-# CONFIG_MFD_PALMAS is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_MFD_PM8921_CORE is not set
-# CONFIG_MFD_PM8XXX is not set
-# CONFIG_MFD_QCOM_PM8008 is not set
-# CONFIG_MFD_RASPBERRYPI_POE_HAT is not set
-# CONFIG_MFD_RC5T583 is not set
-# CONFIG_MFD_RDC321X is not set
-# CONFIG_MFD_RETU is not set
-# CONFIG_MFD_RK808 is not set
-# CONFIG_MFD_RN5T618 is not set
-# CONFIG_MFD_ROHM_BD70528 is not set
-# CONFIG_MFD_ROHM_BD71828 is not set
-# CONFIG_MFD_ROHM_BD718XX is not set
-# CONFIG_MFD_ROHM_BD957XMUF is not set
-# CONFIG_MFD_RP1 is not set
-# CONFIG_MFD_RPISENSE_CORE is not set
-# CONFIG_MFD_RSMU_I2C is not set
-# CONFIG_MFD_RSMU_SPI is not set
-# CONFIG_MFD_RT4831 is not set
-# CONFIG_MFD_RT5033 is not set
-# CONFIG_MFD_RT5120 is not set
-# CONFIG_MFD_RTSX_PCI is not set
-# CONFIG_MFD_RTSX_USB is not set
-# CONFIG_MFD_SEC_CORE is not set
-# CONFIG_MFD_SI476X_CORE is not set
-# CONFIG_MFD_SKY81452 is not set
-# CONFIG_MFD_SL28CPLD is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_SMSC is not set
-# CONFIG_MFD_STMFX is not set
-# CONFIG_MFD_STMPE is not set
-# CONFIG_MFD_STPMIC1 is not set
-# CONFIG_MFD_SY7636A is not set
-# CONFIG_MFD_SYSCON is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC3589X is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_MFD_TIMBERDALE is not set
-# CONFIG_MFD_TI_AM335X_TSCADC is not set
-# CONFIG_MFD_TI_LMU is not set
-# CONFIG_MFD_TI_LP873X is not set
-# CONFIG_MFD_TI_LP87565 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_TPS65086 is not set
-# CONFIG_MFD_TPS65090 is not set
-# CONFIG_MFD_TPS65217 is not set
-# CONFIG_MFD_TPS65218 is not set
-# CONFIG_MFD_TPS6586X is not set
-# CONFIG_MFD_TPS65910 is not set
-# CONFIG_MFD_TPS65912 is not set
-# CONFIG_MFD_TPS65912_I2C is not set
-# CONFIG_MFD_TPS65912_SPI is not set
-# CONFIG_MFD_TPS68470 is not set
-# CONFIG_MFD_TPS80031 is not set
-# CONFIG_MFD_TQMX86 is not set
-# CONFIG_MFD_VIPERBOARD is not set
-# CONFIG_MFD_VX855 is not set
-# CONFIG_MFD_WL1273_CORE is not set
-# CONFIG_MFD_WM831X is not set
-# CONFIG_MFD_WM831X_I2C is not set
-# CONFIG_MFD_WM831X_SPI is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8994 is not set
-# CONFIG_MG_DISK is not set
-# CONFIG_MHI_BUS is not set
-# CONFIG_MHI_BUS_DEBUG is not set
-# CONFIG_MHI_BUS_EP is not set
-# CONFIG_MHI_BUS_PCI_GENERIC is not set
-# CONFIG_MHI_NET is not set
-# CONFIG_MHI_WWAN_CTRL is not set
-# CONFIG_MHI_WWAN_MBIM is not set
-# CONFIG_MICREL_KS8995MA is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_MICROCHIP_KSZ is not set
-# CONFIG_MICROCHIP_PHY is not set
-# CONFIG_MICROCHIP_PIT64B is not set
-# CONFIG_MICROCHIP_T1_PHY is not set
-# CONFIG_MICROSEMI_PHY is not set
-# CONFIG_MIGRATION is not set
-CONFIG_MII=y
-# CONFIG_MIKROTIK is not set
-# CONFIG_MIKROTIK_RB532 is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_MIPS32_N32 is not set
-# CONFIG_MIPS32_O32 is not set
-# CONFIG_MIPS_ALCHEMY is not set
-# CONFIG_MIPS_CDMM is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_DTB is not set
-# CONFIG_MIPS_CMP is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MIPS_CPS is not set
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-# CONFIG_MIPS_FPU_EMULATOR is not set
-# CONFIG_MIPS_FP_SUPPORT is not set
-# CONFIG_MIPS_GENERIC is not set
-# CONFIG_MIPS_GENERIC_KERNEL is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_O32_FP64_SUPPORT is not set
-# CONFIG_MIPS_PARAVIRT is not set
-# CONFIG_MIPS_PLATFORM_DEVICES is not set
-# CONFIG_MIPS_RAW_APPENDED_DTB is not set
-# CONFIG_MIPS_SEAD3 is not set
-# CONFIG_MIPS_VA_BITS_48 is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_MISC_ALCOR_PCI is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_MISC_RTSX_PCI is not set
-# CONFIG_MISC_RTSX_USB is not set
-# CONFIG_MISDN is not set
-# CONFIG_MISDN_AVMFRITZ is not set
-# CONFIG_MISDN_HFCPCI is not set
-# CONFIG_MISDN_HFCUSB is not set
-# CONFIG_MISDN_INFINEON is not set
-# CONFIG_MISDN_NETJET is not set
-# CONFIG_MISDN_SPEEDFAX is not set
-# CONFIG_MISDN_W6692 is not set
-CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y
-# CONFIG_MKISS is not set
-# CONFIG_MLX4_CORE is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX5_CORE is not set
-# CONFIG_MLX5_EN_MACSEC is not set
-# CONFIG_MLX5_SF is not set
-# CONFIG_MLX5_VFIO_PCI is not set
-# CONFIG_MLX90614 is not set
-# CONFIG_MLX90632 is not set
-# CONFIG_MLXFW is not set
-# CONFIG_MLXSW_CORE is not set
-# CONFIG_MLX_CPLD_PLATFORM is not set
-# CONFIG_MLX_PLATFORM is not set
-# CONFIG_MMA7455_I2C is not set
-# CONFIG_MMA7455_SPI is not set
-# CONFIG_MMA7660 is not set
-# CONFIG_MMA8452 is not set
-# CONFIG_MMA9551 is not set
-# CONFIG_MMA9553 is not set
-# CONFIG_MMC is not set
-# CONFIG_MMC35240 is not set
-# CONFIG_MMC_ARMMMCI is not set
-# CONFIG_MMC_AU1X is not set
-# CONFIG_MMC_BLOCK is not set
-CONFIG_MMC_BLOCK_BOUNCE=y
-CONFIG_MMC_BLOCK_MINORS=8
-# CONFIG_MMC_CAVIUM_THUNDERX is not set
-# CONFIG_MMC_CB710 is not set
-# CONFIG_MMC_CQHCI is not set
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_DW is not set
-# CONFIG_MMC_HSQ is not set
-# CONFIG_MMC_JZ4740 is not set
-# CONFIG_MMC_MTK is not set
-# CONFIG_MMC_MVSDIO is not set
-# CONFIG_MMC_S3C is not set
-# CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_SDHCI_ACPI is not set
-# CONFIG_MMC_SDHCI_AM654 is not set
-# CONFIG_MMC_SDHCI_BCM_KONA is not set
-# CONFIG_MMC_SDHCI_BRCMSTB is not set
-# CONFIG_MMC_SDHCI_CADENCE is not set
-# CONFIG_MMC_SDHCI_F_SDH30 is not set
-# CONFIG_MMC_SDHCI_IPROC is not set
-# CONFIG_MMC_SDHCI_MILBEAUT is not set
-# CONFIG_MMC_SDHCI_MSM is not set
-# CONFIG_MMC_SDHCI_OF_ARASAN is not set
-# CONFIG_MMC_SDHCI_OF_ASPEED is not set
-# CONFIG_MMC_SDHCI_OF_AT91 is not set
-# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set
-# CONFIG_MMC_SDHCI_OF_ESDHC is not set
-# CONFIG_MMC_SDHCI_OF_HLWD is not set
-# CONFIG_MMC_SDHCI_OMAP is not set
-# CONFIG_MMC_SDHCI_PXAV2 is not set
-# CONFIG_MMC_SDHCI_PXAV3 is not set
-# CONFIG_MMC_SDHCI_S3C is not set
-# CONFIG_MMC_SDHCI_XENON is not set
-# CONFIG_MMC_SDRICOH_CS is not set
-# CONFIG_MMC_SPI is not set
-# CONFIG_MMC_STM32_SDMMC is not set
-# CONFIG_MMC_TEST is not set
-# CONFIG_MMC_TIFM_SD is not set
-# CONFIG_MMC_TOSHIBA_PCI is not set
-# CONFIG_MMC_USDHI6ROL0 is not set
-# CONFIG_MMC_USHC is not set
-# CONFIG_MMC_VIA_SDMMC is not set
-# CONFIG_MMC_VUB300 is not set
-# CONFIG_MMIOTRACE is not set
-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_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
-# CONFIG_MODULE_COMPRESS is not set
-# CONFIG_MODULE_COMPRESS_GZIP is not set
-CONFIG_MODULE_COMPRESS_NONE=y
-# CONFIG_MODULE_COMPRESS_XZ is not set
-# CONFIG_MODULE_COMPRESS_ZSTD is not set
-# CONFIG_MODULE_FORCE_LOAD is not set
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-# CONFIG_MODULE_SIG is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_MODULE_STRIPPED=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MOST is not set
-# CONFIG_MOTORCOMM_PHY is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_ELAN_I2C is not set
-# CONFIG_MOUSE_GPIO is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_PS2_FOCALTECH is not set
-# CONFIG_MOUSE_PS2_SENTELIC is not set
-# CONFIG_MOUSE_SYNAPTICS_I2C is not set
-# CONFIG_MOUSE_SYNAPTICS_USB is not set
-# CONFIG_MOXTET is not set
-# CONFIG_MPL115 is not set
-# CONFIG_MPL115_I2C is not set
-# CONFIG_MPL115_SPI is not set
-# CONFIG_MPL3115 is not set
-# CONFIG_MPLS is not set
-# CONFIG_MPLS_IPTUNNEL is not set
-# CONFIG_MPLS_ROUTING is not set
-# CONFIG_MPTCP is not set
-# CONFIG_MPU3050_I2C is not set
-# CONFIG_MQ_IOSCHED_DEADLINE is not set
-# CONFIG_MQ_IOSCHED_KYBER is not set
-# CONFIG_MS5611 is not set
-# CONFIG_MS5637 is not set
-# CONFIG_MSA311 is not set
-# CONFIG_MSCC_OCELOT_SWITCH is not set
-# CONFIG_MSDOS_FS is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_MSE102X is not set
-# CONFIG_MSI_BITMAP_SELFTEST is not set
-# CONFIG_MSI_LAPTOP is not set
-# CONFIG_MSM_GCC_8953 is not set
-# CONFIG_MSM_MMCC_8994 is not set
-# CONFIG_MST_IRQ is not set
-CONFIG_MTD=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_MTD_BLOCK2MTD is not set
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-# CONFIG_MTD_DATAFLASH is not set
-# CONFIG_MTD_DOCG3 is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_GPIO_ADDR is not set
-# CONFIG_MTD_HYPERBUS is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_INTEL_VR_NOR is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_LATCH_ADDR is not set
-# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_LPDDR2_NVM is not set
-# CONFIG_MTD_M25P80 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MCHP23K256 is not set
-# CONFIG_MTD_MCHP48L640 is not set
-# CONFIG_MTD_MT81xx_NOR is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MYLOADER_PARTS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_AMS_DELTA is not set
-# CONFIG_MTD_NAND_AR934X is not set
-# CONFIG_MTD_NAND_AR934X_HW_ECC is not set
-# CONFIG_MTD_NAND_ARASAN is not set
-# CONFIG_MTD_NAND_ATMEL is not set
-# CONFIG_MTD_NAND_AU1550 is not set
-# CONFIG_MTD_NAND_BCH is not set
-# CONFIG_MTD_NAND_BF5XX is not set
-# CONFIG_MTD_NAND_BRCMNAND is not set
-# CONFIG_MTD_NAND_BRCMNAND_BCM63XX is not set
-# CONFIG_MTD_NAND_BRCMNAND_BCMBCA is not set
-# CONFIG_MTD_NAND_BRCMNAND_BRCMSTB is not set
-# CONFIG_MTD_NAND_BRCMNAND_IPROC is not set
-# CONFIG_MTD_NAND_CADENCE is not set
-# CONFIG_MTD_NAND_CAFE is not set
-# CONFIG_MTD_NAND_CM_X270 is not set
-# CONFIG_MTD_NAND_CS553X is not set
-# CONFIG_MTD_NAND_DAVINCI is not set
-# CONFIG_MTD_NAND_DENALI is not set
-# CONFIG_MTD_NAND_DENALI_DT is not set
-# CONFIG_MTD_NAND_DENALI_PCI is not set
-CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_DOCG4 is not set
-# CONFIG_MTD_NAND_ECC is not set
-# CONFIG_MTD_NAND_ECC_BCH is not set
-# CONFIG_MTD_NAND_ECC_MXIC is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
-# CONFIG_MTD_NAND_ECC_SW_BCH is not set
-# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set
-# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set
-# CONFIG_MTD_NAND_FSL_ELBC is not set
-# CONFIG_MTD_NAND_FSL_IFC is not set
-# CONFIG_MTD_NAND_FSL_UPM is not set
-# CONFIG_MTD_NAND_FSMC is not set
-# CONFIG_MTD_NAND_GPIO is not set
-# CONFIG_MTD_NAND_GPMI_NAND is not set
-# CONFIG_MTD_NAND_HISI504 is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_INTEL_LGM is not set
-# CONFIG_MTD_NAND_JZ4740 is not set
-# CONFIG_MTD_NAND_MPC5121_NFC is not set
-# CONFIG_MTD_NAND_MTK is not set
-# CONFIG_MTD_NAND_MTK_BMT is not set
-# CONFIG_MTD_NAND_MXC is not set
-# CONFIG_MTD_NAND_MXIC is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_NDFC is not set
-# CONFIG_MTD_NAND_NUC900 is not set
-# CONFIG_MTD_NAND_OMAP2 is not set
-# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set
-# CONFIG_MTD_NAND_ORION is not set
-# CONFIG_MTD_NAND_PASEMI is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_NAND_PXA3xx is not set
-# CONFIG_MTD_NAND_RB4XX is not set
-# CONFIG_MTD_NAND_RB750 is not set
-# CONFIG_MTD_NAND_RB91X is not set
-# CONFIG_MTD_NAND_RICOH is not set
-# CONFIG_MTD_NAND_S3C2410 is not set
-# CONFIG_MTD_NAND_SHARPSL is not set
-# CONFIG_MTD_NAND_SH_FLCTL is not set
-# CONFIG_MTD_NAND_SOCRATES is not set
-# CONFIG_MTD_NAND_TMIO is not set
-# CONFIG_MTD_NAND_TXX9NDFMC is not set
-CONFIG_MTD_OF_PARTS=y
-# CONFIG_MTD_ONENAND is not set
-# CONFIG_MTD_OOPS is not set
-# CONFIG_MTD_OTP is not set
-# CONFIG_MTD_PARSER_TRX is not set
-# CONFIG_MTD_PARTITIONED_MASTER is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PHYSMAP_COMPAT is not set
-# CONFIG_MTD_PHYSMAP_GEMINI is not set
-# CONFIG_MTD_PHYSMAP_GPIO_ADDR is not set
-# CONFIG_MTD_PHYSMAP_IXP4XX is not set
-CONFIG_MTD_PHYSMAP_OF=y
-# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set
-# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set
-# CONFIG_MTD_PHYSMAP_VERSATILE is not set
-# CONFIG_MTD_PLATRAM is not set
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_RAW_NAND is not set
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_ROM is not set
-CONFIG_MTD_ROOTFS_ROOT_DEV=y
-# CONFIG_MTD_ROUTERBOOT_PARTS is not set
-# CONFIG_MTD_SERCOMM_PARTS is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_SM_COMMON is not set
-# CONFIG_MTD_SPINAND_MT29F is not set
-# CONFIG_MTD_SPI_NAND is not set
-# CONFIG_MTD_SPI_NOR is not set
-# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
-CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
-# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
-# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
-# CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE is not set
-CONFIG_MTD_SPLIT=y
-# CONFIG_MTD_SPLIT_BCM63XX_FW is not set
-# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set
-# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
-# CONFIG_MTD_SPLIT_ELF_FW is not set
-# CONFIG_MTD_SPLIT_EVA_FW is not set
-# CONFIG_MTD_SPLIT_FIRMWARE is not set
-CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware"
-# CONFIG_MTD_SPLIT_FIT_FW is not set
-# CONFIG_MTD_SPLIT_H3C_VFS is not set
-# CONFIG_MTD_SPLIT_JIMAGE_FW is not set
-# CONFIG_MTD_SPLIT_LZMA_FW is not set
-# CONFIG_MTD_SPLIT_MINOR_FW is not set
-# CONFIG_MTD_SPLIT_SEAMA_FW is not set
-# CONFIG_MTD_SPLIT_SEIL_FW is not set
-CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y
-CONFIG_MTD_SPLIT_SUPPORT=y
-# CONFIG_MTD_SPLIT_TPLINK_FW is not set
-# CONFIG_MTD_SPLIT_TRX_FW is not set
-# CONFIG_MTD_SPLIT_UIMAGE_FW is not set
-# CONFIG_MTD_SPLIT_WRGG_FW is not set
-# CONFIG_MTD_SST25L is not set
-# CONFIG_MTD_SWAP is not set
-# CONFIG_MTD_TESTS is not set
-# CONFIG_MTD_UBI is not set
-# CONFIG_MTD_UBI_FASTMAP is not set
-# CONFIG_MTD_UBI_GLUEBI is not set
-# CONFIG_MTD_UBI_NVMEM is not set
-# CONFIG_MTD_UIMAGE_SPLIT is not set
-# CONFIG_MTD_VIRT_CONCAT is not set
-# CONFIG_MTK_DEVAPC is not set
-# CONFIG_MTK_MMC is not set
-# CONFIG_MTK_MMSYS is not set
-# CONFIG_MTK_T7XX is not set
-# CONFIG_MTK_THERMAL is not set
-# CONFIG_MULTIPLEXER is not set
-CONFIG_MULTIUSER=y
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-# CONFIG_MUX_ADG792A is not set
-# CONFIG_MUX_ADGS1408 is not set
-# CONFIG_MUX_GPIO is not set
-# CONFIG_MUX_MMIO is not set
-# CONFIG_MV643XX_ETH is not set
-# CONFIG_MVMDIO is not set
-# CONFIG_MVNETA_BM is not set
-# CONFIG_MVSW61XX_PHY is not set
-# CONFIG_MV_XOR_V2 is not set
-# CONFIG_MWAVE is not set
-# CONFIG_MWL8K is not set
-# CONFIG_MXC4005 is not set
-# CONFIG_MXC6255 is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NAMESPACES is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NAU7802 is not set
-# CONFIG_NBPFAXI_DMA is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NE2000 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_NEC_MARKEINS is not set
-CONFIG_NET=y
-# CONFIG_NETCONSOLE is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NETDEVSIM is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_NETFILTER_ADVANCED is not set
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_NETFILTER_EGRESS is not set
-# CONFIG_NETFILTER_INGRESS is not set
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NETFILTER_NETLINK_ACCT is not set
-# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set
-# CONFIG_NETFILTER_NETLINK_HOOK is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NETFILTER_NETLINK_OSF is not set
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_XTABLES is not set
-# CONFIG_NETFILTER_XTABLES_COMPAT is not set
-# CONFIG_NETFILTER_XT_CONNMARK is not set
-# CONFIG_NETFILTER_XT_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_BPF is not set
-# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set
-# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
-# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
-# CONFIG_NETFILTER_XT_MATCH_CPU is not set
-# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
-# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
-# CONFIG_NETFILTER_XT_MATCH_ECN is not set
-# CONFIG_NETFILTER_XT_MATCH_ESP is not set
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
-# CONFIG_NETFILTER_XT_MATCH_HL is not set
-# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
-# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
-# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
-# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
-# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_MAC is not set
-# CONFIG_NETFILTER_XT_MATCH_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
-# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
-# CONFIG_NETFILTER_XT_MATCH_OSF is not set
-# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
-# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
-# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
-# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
-# CONFIG_NETFILTER_XT_MATCH_REALM is not set
-# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
-# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
-# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
-# CONFIG_NETFILTER_XT_MATCH_STATE is not set
-# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
-# CONFIG_NETFILTER_XT_MATCH_STRING is not set
-# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
-# CONFIG_NETFILTER_XT_MATCH_TIME is not set
-# CONFIG_NETFILTER_XT_MATCH_U32 is not set
-# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
-# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
-# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
-# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_CT is not set
-# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
-# CONFIG_NETFILTER_XT_TARGET_HL is not set
-# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
-# CONFIG_NETFILTER_XT_TARGET_LED is not set
-# CONFIG_NETFILTER_XT_TARGET_LOG is not set
-# CONFIG_NETFILTER_XT_TARGET_MARK is not set
-# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
-# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
-# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
-# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set
-# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
-# CONFIG_NETFILTER_XT_TARGET_TEE is not set
-# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
-# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
-# CONFIG_NETFS_STATS is not set
-# CONFIG_NETLABEL is not set
-# CONFIG_NETLINK_DIAG is not set
-# CONFIG_NETLINK_MMAP is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NETROM is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETXEN_NIC is not set
-# CONFIG_NET_9P is not set
-# CONFIG_NET_ACT_BPF is not set
-# CONFIG_NET_ACT_CSUM is not set
-# CONFIG_NET_ACT_CT is not set
-# CONFIG_NET_ACT_GACT is not set
-# CONFIG_NET_ACT_GATE is not set
-# CONFIG_NET_ACT_IFE is not set
-# CONFIG_NET_ACT_IPT is not set
-# CONFIG_NET_ACT_MIRRED is not set
-# CONFIG_NET_ACT_MPLS is not set
-# CONFIG_NET_ACT_NAT is not set
-# CONFIG_NET_ACT_PEDIT is not set
-# CONFIG_NET_ACT_POLICE is not set
-# CONFIG_NET_ACT_SAMPLE is not set
-# CONFIG_NET_ACT_SIMP is not set
-# CONFIG_NET_ACT_SKBEDIT is not set
-# CONFIG_NET_ACT_SKBMOD is not set
-# CONFIG_NET_ACT_TUNNEL_KEY is not set
-# CONFIG_NET_ACT_VLAN is not set
-CONFIG_NET_CADENCE=y
-# CONFIG_NET_CALXEDA_XGMAC is not set
-CONFIG_NET_CLS=y
-# CONFIG_NET_CLS_ACT is not set
-# CONFIG_NET_CLS_BASIC is not set
-# CONFIG_NET_CLS_BPF is not set
-# CONFIG_NET_CLS_FLOW is not set
-# CONFIG_NET_CLS_FLOWER is not set
-# CONFIG_NET_CLS_FW is not set
-CONFIG_NET_CLS_IND=y
-# CONFIG_NET_CLS_MATCHALL is not set
-# CONFIG_NET_CLS_ROUTE4 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_CLS_U32 is not set
-CONFIG_NET_CORE=y
-# CONFIG_NET_DEVLINK is not set
-# CONFIG_NET_DEV_REFCNT_TRACKER is not set
-# CONFIG_NET_DROP_MONITOR is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_NET_DSA_AR9331 is not set
-# CONFIG_NET_DSA_BCM_SF2 is not set
-# CONFIG_NET_DSA_LANTIQ_GSWIP is not set
-# CONFIG_NET_DSA_LEGACY is not set
-# CONFIG_NET_DSA_LOOP is not set
-# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set
-# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set
-# CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON is not set
-# CONFIG_NET_DSA_MSCC_FELIX is not set
-# CONFIG_NET_DSA_MSCC_SEVILLE is not set
-# CONFIG_NET_DSA_MT7530 is not set
-# CONFIG_NET_DSA_MV88E6060 is not set
-# CONFIG_NET_DSA_MV88E6123_61_65 is not set
-# CONFIG_NET_DSA_MV88E6131 is not set
-# CONFIG_NET_DSA_MV88E6171 is not set
-# CONFIG_NET_DSA_MV88E6352 is not set
-# CONFIG_NET_DSA_MV88E6XXX is not set
-# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
-# CONFIG_NET_DSA_MV88E6XXX_PTP is not set
-# CONFIG_NET_DSA_QCA8K is not set
-# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set
-# CONFIG_NET_DSA_REALTEK is not set
-# CONFIG_NET_DSA_REALTEK_SMI is not set
-# CONFIG_NET_DSA_SJA1105 is not set
-# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set
-# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set
-# CONFIG_NET_DSA_TAG_8021Q is not set
-# CONFIG_NET_DSA_TAG_AR9331 is not set
-# CONFIG_NET_DSA_TAG_BRCM is not set
-# CONFIG_NET_DSA_TAG_BRCM_LEGACY is not set
-# CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set
-# CONFIG_NET_DSA_TAG_DSA is not set
-# CONFIG_NET_DSA_TAG_EDSA is not set
-# CONFIG_NET_DSA_TAG_GSWIP is not set
-# CONFIG_NET_DSA_TAG_HELLCREEK is not set
-# CONFIG_NET_DSA_TAG_KSZ is not set
-# CONFIG_NET_DSA_TAG_LAN9303 is not set
-# CONFIG_NET_DSA_TAG_MTK is not set
-# CONFIG_NET_DSA_TAG_OCELOT is not set
-# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set
-# CONFIG_NET_DSA_TAG_QCA is not set
-# CONFIG_NET_DSA_TAG_RTL4_A is not set
-# CONFIG_NET_DSA_TAG_RTL8_4 is not set
-# CONFIG_NET_DSA_TAG_RZN1_A5PSW is not set
-# CONFIG_NET_DSA_TAG_SJA1105 is not set
-# CONFIG_NET_DSA_TAG_TRAILER is not set
-# CONFIG_NET_DSA_TAG_XRS700X is not set
-# CONFIG_NET_DSA_VITESSE_VSC73XX is not set
-# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set
-# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set
-# CONFIG_NET_DSA_XRS700X_I2C is not set
-# CONFIG_NET_DSA_XRS700X_MDIO is not set
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_EMATCH_CANID is not set
-# CONFIG_NET_EMATCH_CMP is not set
-# CONFIG_NET_EMATCH_IPT is not set
-# CONFIG_NET_EMATCH_META is not set
-# CONFIG_NET_EMATCH_NBYTE is not set
-CONFIG_NET_EMATCH_STACK=32
-# CONFIG_NET_EMATCH_TEXT is not set
-# CONFIG_NET_EMATCH_U32 is not set
-# CONFIG_NET_FAILOVER is not set
-# CONFIG_NET_FC is not set
-# CONFIG_NET_FOU is not set
-# CONFIG_NET_FOU_IP_TUNNELS is not set
-# CONFIG_NET_IFE is not set
-# CONFIG_NET_IPGRE is not set
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_NET_IPGRE_DEMUX is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPVTI is not set
-# CONFIG_NET_IP_TUNNEL is not set
-# CONFIG_NET_KEY is not set
-# CONFIG_NET_KEY_MIGRATE is not set
-# CONFIG_NET_L3_MASTER_DEV is not set
-# CONFIG_NET_MEDIATEK_STAR_EMAC is not set
-# CONFIG_NET_MPLS_GSO is not set
-# CONFIG_NET_NCSI is not set
-# CONFIG_NET_NSH is not set
-# CONFIG_NET_NS_REFCNT_TRACKER is not set
-# CONFIG_NET_PACKET_ENGINE is not set
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_NET_PTP_CLASSIFY is not set
-CONFIG_NET_RX_BUSY_POLL=y
-# CONFIG_NET_SB1000 is not set
-CONFIG_NET_SCHED=y
-# CONFIG_NET_SCH_CAKE is not set
-# CONFIG_NET_SCH_CBS is not set
-# CONFIG_NET_SCH_CHOKE is not set
-# CONFIG_NET_SCH_CODEL is not set
-CONFIG_NET_SCH_DEFAULT=y
-# CONFIG_NET_SCH_DRR is not set
-# CONFIG_NET_SCH_ETF is not set
-# CONFIG_NET_SCH_ETS is not set
-CONFIG_NET_SCH_FIFO=y
-# CONFIG_NET_SCH_FQ is not set
-CONFIG_NET_SCH_FQ_CODEL=y
-# CONFIG_NET_SCH_FQ_PIE is not set
-# CONFIG_NET_SCH_GRED is not set
-# CONFIG_NET_SCH_HFSC is not set
-# CONFIG_NET_SCH_HHF is not set
-# CONFIG_NET_SCH_HTB is not set
-# CONFIG_NET_SCH_INGRESS is not set
-# CONFIG_NET_SCH_MQPRIO is not set
-# CONFIG_NET_SCH_MULTIQ is not set
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_PIE is not set
-# CONFIG_NET_SCH_PLUG is not set
-# CONFIG_NET_SCH_PRIO is not set
-# CONFIG_NET_SCH_QFQ is not set
-# CONFIG_NET_SCH_RED is not set
-# CONFIG_NET_SCH_SFB is not set
-# CONFIG_NET_SCH_SFQ is not set
-# CONFIG_NET_SCH_SKBPRIO is not set
-# CONFIG_NET_SCH_TAPRIO is not set
-# CONFIG_NET_SCH_TBF is not set
-# CONFIG_NET_SCH_TEQL is not set
-# CONFIG_NET_SCTPPROBE is not set
-# CONFIG_NET_SELFTESTS is not set
-CONFIG_NET_SOCK_MSG=y
-# CONFIG_NET_SWITCHDEV is not set
-# CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_TC_SKB_EXT is not set
-# CONFIG_NET_TEAM is not set
-# CONFIG_NET_TULIP is not set
-# CONFIG_NET_UDP_TUNNEL is not set
-CONFIG_NET_VENDOR_3COM=y
-CONFIG_NET_VENDOR_8390=y
-CONFIG_NET_VENDOR_ADAPTEC=y
-CONFIG_NET_VENDOR_ADI=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_ASIX is not set
-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_DAVICOM=y
-CONFIG_NET_VENDOR_DEC=y
-CONFIG_NET_VENDOR_DLINK=y
-CONFIG_NET_VENDOR_EMULEX=y
-# CONFIG_NET_VENDOR_ENGLEDER is not set
-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_FUNGIBLE is not set
-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_LITEX is not set
-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_MICROSOFT is not set
-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_VERTEXCOM is not set
-CONFIG_NET_VENDOR_VIA=y
-# CONFIG_NET_VENDOR_WANGXUN is not set
-CONFIG_NET_VENDOR_WIZNET=y
-CONFIG_NET_VENDOR_XILINX=y
-CONFIG_NET_VENDOR_XIRCOM=y
-# CONFIG_NET_VRF is not set
-# CONFIG_NET_XGENE is not set
-CONFIG_NEW_LEDS=y
-# CONFIG_NFC is not set
-# CONFIG_NFP is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V2 is not set
-# CONFIG_NFSD_V2_ACL is not set
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFS_ACL_SUPPORT is not set
-CONFIG_NFS_COMMON=y
-# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_FSCACHE is not set
-# CONFIG_NFS_SWAP is not set
-# CONFIG_NFS_V2 is not set
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_V4_1 is not set
-# CONFIG_NFTL is not set
-# CONFIG_NFT_BRIDGE_META is not set
-# CONFIG_NFT_BRIDGE_REJECT is not set
-# CONFIG_NFT_CONNLIMIT is not set
-# CONFIG_NFT_DUP_IPV4 is not set
-# CONFIG_NFT_DUP_IPV6 is not set
-# CONFIG_NFT_FIB_IPV4 is not set
-# CONFIG_NFT_FIB_IPV6 is not set
-# CONFIG_NFT_FIB_NETDEV is not set
-# CONFIG_NFT_FLOW_OFFLOAD is not set
-# CONFIG_NFT_OBJREF is not set
-# CONFIG_NFT_OSF is not set
-# CONFIG_NFT_REJECT_NETDEV is not set
-# CONFIG_NFT_RT is not set
-# CONFIG_NFT_SET_BITMAP is not set
-# CONFIG_NFT_SOCKET is not set
-# CONFIG_NFT_SYNPROXY is not set
-# CONFIG_NFT_TPROXY is not set
-# CONFIG_NFT_TUNNEL is not set
-# CONFIG_NFT_XFRM is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NF_CONNTRACK_AMANDA is not set
-# CONFIG_NF_CONNTRACK_BRIDGE is not set
-# CONFIG_NF_CONNTRACK_EVENTS is not set
-# CONFIG_NF_CONNTRACK_FTP is not set
-# CONFIG_NF_CONNTRACK_H323 is not set
-# CONFIG_NF_CONNTRACK_IRC is not set
-# CONFIG_NF_CONNTRACK_LABELS is not set
-# CONFIG_NF_CONNTRACK_MARK is not set
-# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
-# CONFIG_NF_CONNTRACK_PPTP is not set
-CONFIG_NF_CONNTRACK_PROCFS=y
-# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
-# CONFIG_NF_CONNTRACK_SANE is not set
-# CONFIG_NF_CONNTRACK_SECMARK is not set
-# CONFIG_NF_CONNTRACK_SIP is not set
-# CONFIG_NF_CONNTRACK_SNMP is not set
-# CONFIG_NF_CONNTRACK_TFTP is not set
-# CONFIG_NF_CONNTRACK_TIMEOUT is not set
-# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
-# CONFIG_NF_CONNTRACK_ZONES is not set
-# CONFIG_NF_CT_NETLINK is not set
-# CONFIG_NF_CT_NETLINK_HELPER is not set
-# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
-# CONFIG_NF_CT_PROTO_DCCP is not set
-# CONFIG_NF_CT_PROTO_GRE is not set
-# CONFIG_NF_CT_PROTO_SCTP is not set
-# CONFIG_NF_CT_PROTO_UDPLITE is not set
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_NF_DUP_IPV4 is not set
-# CONFIG_NF_DUP_IPV6 is not set
-# CONFIG_NF_FLOW_TABLE is not set
-# CONFIG_NF_FLOW_TABLE_PROCFS is not set
-# CONFIG_NF_LOG_ARP is not set
-# CONFIG_NF_LOG_BRIDGE is not set
-# CONFIG_NF_LOG_IPV4 is not set
-# CONFIG_NF_LOG_NETDEV is not set
-# CONFIG_NF_LOG_SYSLOG is not set
-# CONFIG_NF_NAT is not set
-# CONFIG_NF_NAT_AMANDA is not set
-# CONFIG_NF_NAT_FTP is not set
-# CONFIG_NF_NAT_H323 is not set
-# CONFIG_NF_NAT_IRC is not set
-# CONFIG_NF_NAT_NEEDED is not set
-# CONFIG_NF_NAT_PPTP is not set
-# CONFIG_NF_NAT_PROTO_GRE is not set
-# CONFIG_NF_NAT_SIP is not set
-# CONFIG_NF_NAT_SNMP_BASIC is not set
-# CONFIG_NF_NAT_TFTP is not set
-# CONFIG_NF_REJECT_IPV4 is not set
-# CONFIG_NF_REJECT_IPV6 is not set
-# CONFIG_NF_SOCKET_IPV4 is not set
-# CONFIG_NF_SOCKET_IPV6 is not set
-# CONFIG_NF_TABLES is not set
-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_NF_TABLES_SET is not set
-# CONFIG_NF_TPROXY_IPV4 is not set
-# CONFIG_NF_TPROXY_IPV6 is not set
-# CONFIG_NGBE is not set
-# CONFIG_NI65 is not set
-# CONFIG_NI903X_WDT is not set
-# CONFIG_NIC7018_WDT is not set
-# CONFIG_NILFS2_FS is not set
-# CONFIG_NIU is not set
-# CONFIG_NI_XGE_MANAGEMENT_ENET is not set
-CONFIG_NLATTR=y
-# CONFIG_NLMON is not set
-# CONFIG_NLM_XLP_BOARD is not set
-# CONFIG_NLM_XLR_BOARD is not set
-# CONFIG_NLS is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_MAC_CELTIC is not set
-# CONFIG_NLS_MAC_CENTEURO is not set
-# CONFIG_NLS_MAC_CROATIAN is not set
-# CONFIG_NLS_MAC_CYRILLIC is not set
-# CONFIG_NLS_MAC_GAELIC is not set
-# CONFIG_NLS_MAC_GREEK is not set
-# CONFIG_NLS_MAC_ICELAND is not set
-# CONFIG_NLS_MAC_INUIT is not set
-# CONFIG_NLS_MAC_ROMAN is not set
-# CONFIG_NLS_MAC_ROMANIAN is not set
-# CONFIG_NLS_MAC_TURKISH is not set
-# CONFIG_NLS_UTF8 is not set
-CONFIG_NMI_LOG_BUF_SHIFT=13
-# CONFIG_NOA1305 is not set
-# CONFIG_NOP_USB_XCEIV is not set
-# CONFIG_NORTEL_HERMES is not set
-# CONFIG_NOTIFIER_ERROR_INJECTION is not set
-# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set
-# CONFIG_NOZOMI is not set
-# CONFIG_NO_BOOTMEM is not set
-# CONFIG_NO_HZ is not set
-# CONFIG_NO_HZ_FULL is not set
-# CONFIG_NO_HZ_IDLE is not set
-# CONFIG_NS83820 is not set
-# CONFIG_NTB is not set
-# CONFIG_NTFS3_64BIT_CLUSTER is not set
-# CONFIG_NTFS3_FS is not set
-# CONFIG_NTFS3_FS_POSIX_ACL is not set
-# CONFIG_NTFS3_LZX_XPRESS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_NTP_PPS is not set
-# CONFIG_NULL_TTY is not set
-# CONFIG_NUMA is not set
-# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set
-# CONFIG_NVM is not set
-# CONFIG_NVMEM is not set
-# CONFIG_NVMEM_BCM_OCOTP is not set
-# CONFIG_NVMEM_IMX_OCOTP is not set
-# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
-# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
-# CONFIG_NVMEM_REBOOT_MODE is not set
-# CONFIG_NVMEM_RMEM is not set
-# CONFIG_NVMEM_SYSFS is not set
-# CONFIG_NVMEM_U_BOOT_ENV is not set
-# CONFIG_NVME_AUTH is not set
-# CONFIG_NVME_FC is not set
-# CONFIG_NVME_TARGET is not set
-# CONFIG_NVME_TCP is not set
-# CONFIG_NVME_VERBOSE_ERRORS is not set
-# CONFIG_NVRAM is not set
-# CONFIG_NV_TCO is not set
-# CONFIG_NXP_C45_TJA11XX_PHY is not set
-# CONFIG_NXP_STB220 is not set
-# CONFIG_NXP_STB225 is not set
-# CONFIG_NXP_TJA11XX_PHY is not set
-# CONFIG_N_GSM is not set
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_OBS600 is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_OCTEONTX2_AF is not set
-# CONFIG_OCTEONTX2_PF is not set
-# CONFIG_OCTEON_EP is not set
-# CONFIG_OF_OVERLAY is not set
-CONFIG_OF_RESERVED_MEM=y
-# CONFIG_OF_UNITTEST is not set
-# CONFIG_OID_REGISTRY is not set
-# CONFIG_OMAP2_DSS_DEBUG is not set
-# CONFIG_OMAP2_DSS_DEBUGFS is not set
-# CONFIG_OMAP2_DSS_SDI is not set
-# CONFIG_OMAP_OCP2SCP is not set
-# CONFIG_OMAP_USB2 is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_OPENVSWITCH is not set
-# CONFIG_OPEN_DICE is not set
-# CONFIG_OPROFILE is not set
-# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set
-# CONFIG_OPT3001 is not set
-CONFIG_OPTIMIZE_INLINING=y
-# CONFIG_ORANGEFS_FS is not set
-# CONFIG_ORION_WATCHDOG is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_OSNOISE_TRACER is not set
-CONFIG_OVERLAY_FS=y
-# CONFIG_OVERLAY_FS_INDEX is not set
-# CONFIG_OVERLAY_FS_METACOPY is not set
-CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
-# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
-CONFIG_OVERLAY_FS_XINO_AUTO=y
-# CONFIG_OWL_LOADER is not set
-# CONFIG_P54_COMMON is not set
-# CONFIG_PA12203001 is not set
-CONFIG_PACKET=y
-# CONFIG_PACKET_DIAG is not set
-# CONFIG_PACKING is not set
-# CONFIG_PAGE_EXTENSION is not set
-# CONFIG_PAGE_OWNER is not set
-# CONFIG_PAGE_POISONING is not set
-# CONFIG_PAGE_POOL is not set
-# CONFIG_PAGE_POOL_STATS is not set
-# CONFIG_PAGE_REPORTING is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_32KB is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_64KB is not set
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_TABLE_CHECK is not set
-# CONFIG_PALMAS_GPADC is not set
-# CONFIG_PANASONIC_LAPTOP is not set
-# CONFIG_PANEL is not set
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_PANIC_ON_OOPS_VALUE=1
-CONFIG_PANIC_TIMEOUT=1
-# CONFIG_PANTHERLORD_FF is not set
-# CONFIG_PARAVIRT is not set
-# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
-# CONFIG_PARPORT is not set
-# CONFIG_PARPORT_1284 is not set
-# CONFIG_PARPORT_AX88796 is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_PC is not set
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARASAN_CF is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_ATP867X is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CS5535 is not set
-# CONFIG_PATA_CS5536 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IMX is not set
-# CONFIG_PATA_ISAPNP is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_LEGACY is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OCTEON_CF is not set
-# CONFIG_PATA_OF_PLATFORM is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_PCMCIA is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_PLATFORM is not set
-# CONFIG_PATA_QDI is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RDC is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SCH is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_TOSHIBA is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-# CONFIG_PATA_WINBOND_VLB is not set
-# CONFIG_PC104 is not set
-# CONFIG_PC300TOO is not set
-# CONFIG_PCCARD is not set
-# CONFIG_PCH_DMA is not set
-# CONFIG_PCH_GBE is not set
-# CONFIG_PCH_PHUB is not set
-# CONFIG_PCI is not set
-# CONFIG_PCI200SYN is not set
-# CONFIG_PCIEAER is not set
-# CONFIG_PCIEAER_INJECT is not set
-# CONFIG_PCIEASPM is not set
-# CONFIG_PCIEPORTBUS is not set
-# CONFIG_PCIE_AL is not set
-# CONFIG_PCIE_ALTERA is not set
-# CONFIG_PCIE_ARMADA_8K is not set
-CONFIG_PCIE_BUS_DEFAULT=y
-# CONFIG_PCIE_BUS_PEER2PEER is not set
-# CONFIG_PCIE_BUS_PERFORMANCE is not set
-# CONFIG_PCIE_BUS_SAFE is not set
-# CONFIG_PCIE_BUS_TUNE_OFF is not set
-# CONFIG_PCIE_BW is not set
-# CONFIG_PCIE_CADENCE_HOST is not set
-# CONFIG_PCIE_CADENCE_PLAT_HOST is not set
-# CONFIG_PCIE_DPC is not set
-# CONFIG_PCIE_DW_PLAT is not set
-# CONFIG_PCIE_DW_PLAT_HOST is not set
-# CONFIG_PCIE_ECRC is not set
-# CONFIG_PCIE_IPROC is not set
-# CONFIG_PCIE_KIRIN is not set
-# CONFIG_PCIE_LAYERSCAPE_GEN4 is not set
-# CONFIG_PCIE_MEDIATEK_GEN3 is not set
-# CONFIG_PCIE_MICROCHIP_HOST is not set
-# CONFIG_PCIE_PTM is not set
-# CONFIG_PCIE_XILINX is not set
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_PCI_ATMEL is not set
-# CONFIG_PCI_CNB20LE_QUIRK is not set
-# CONFIG_PCI_DEBUG is not set
-# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
-# CONFIG_PCI_ENDPOINT is not set
-# CONFIG_PCI_ENDPOINT_TEST is not set
-# CONFIG_PCI_FTPCI100 is not set
-# CONFIG_PCI_HERMES is not set
-# CONFIG_PCI_HISI is not set
-# CONFIG_PCI_HOST_GENERIC is not set
-# CONFIG_PCI_HOST_THUNDER_ECAM is not set
-# CONFIG_PCI_HOST_THUNDER_PEM is not set
-# CONFIG_PCI_IOV is not set
-# CONFIG_PCI_J721E_HOST is not set
-# CONFIG_PCI_LAYERSCAPE is not set
-# CONFIG_PCI_MESON is not set
-# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_PASID is not set
-# CONFIG_PCI_PF_STUB is not set
-# CONFIG_PCI_PRI is not set
-CONFIG_PCI_QUIRKS=y
-# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
-# CONFIG_PCI_STUB is not set
-# CONFIG_PCI_SW_SWITCHTEC is not set
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCI_V3_SEMI is not set
-# CONFIG_PCI_XGENE is not set
-# CONFIG_PCMCIA is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_ATMEL is not set
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_SPECTRUM is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_PCMCIA_XIRCOM is not set
-# CONFIG_PCNET32 is not set
-# CONFIG_PCPU_DEV_REFCNT is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_PCS_MTK_USXGMII is not set
-# CONFIG_PCS_XPCS is not set
-# CONFIG_PD6729 is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_PECI is not set
-# CONFIG_PERCPU_STATS is not set
-# CONFIG_PERCPU_TEST is not set
-# CONFIG_PERF_EVENTS is not set
-# CONFIG_PERF_EVENTS_AMD_POWER is not set
-# CONFIG_PERSISTENT_KEYRINGS is not set
-# CONFIG_PHANTOM is not set
-# CONFIG_PHONET is not set
-# CONFIG_PHYLIB is not set
-# CONFIG_PHYLIB_LEDS is not set
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-# CONFIG_PHY_BRCM_USB is not set
-# CONFIG_PHY_CADENCE_DP is not set
-# CONFIG_PHY_CADENCE_DPHY is not set
-# CONFIG_PHY_CADENCE_DPHY_RX is not set
-# CONFIG_PHY_CADENCE_SALVO is not set
-# CONFIG_PHY_CADENCE_SIERRA is not set
-# CONFIG_PHY_CADENCE_TORRENT is not set
-# CONFIG_PHY_CAN_TRANSCEIVER is not set
-# CONFIG_PHY_CPCAP_USB is not set
-# CONFIG_PHY_EXYNOS_DP_VIDEO is not set
-# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
-# CONFIG_PHY_FSL_IMX8MQ_USB is not set
-# CONFIG_PHY_INGENIC_USB is not set
-# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set
-# CONFIG_PHY_LAN966X_SERDES is not set
-# CONFIG_PHY_MAPPHONE_MDM6600 is not set
-# CONFIG_PHY_MIXEL_MIPI_DPHY is not set
-# CONFIG_PHY_MTK_HDMI is not set
-# CONFIG_PHY_MTK_MIPI_DSI is not set
-# CONFIG_PHY_MTK_XFI_TPHY is not set
-# CONFIG_PHY_MVEBU_CP110_UTMI is not set
-# CONFIG_PHY_OCELOT_SERDES is not set
-# CONFIG_PHY_PISTACHIO_USB is not set
-# CONFIG_PHY_PXA_28NM_HSIC is not set
-# CONFIG_PHY_PXA_28NM_USB2 is not set
-# CONFIG_PHY_QCOM_DWC3 is not set
-# CONFIG_PHY_QCOM_USB_HS is not set
-# CONFIG_PHY_QCOM_USB_HSIC is not set
-# CONFIG_PHY_SAMSUNG_USB2 is not set
-# CONFIG_PHY_TUSB1210 is not set
-# CONFIG_PHY_XGENE is not set
-# CONFIG_PI433 is not set
-# CONFIG_PID_IN_CONTEXTIDR is not set
-# CONFIG_PID_NS is not set
-CONFIG_PINCONF=y
-# CONFIG_PINCTRL is not set
-# CONFIG_PINCTRL_AMD is not set
-# CONFIG_PINCTRL_AXP209 is not set
-# CONFIG_PINCTRL_BCM2712 is not set
-# CONFIG_PINCTRL_CEDARFORK is not set
-# CONFIG_PINCTRL_CY8C95X0 is not set
-# CONFIG_PINCTRL_EXYNOS is not set
-# CONFIG_PINCTRL_EXYNOS5440 is not set
-# CONFIG_PINCTRL_ICELAKE is not set
-# CONFIG_PINCTRL_INGENIC is not set
-# CONFIG_PINCTRL_LPASS_LPI is not set
-# CONFIG_PINCTRL_MCP23S08 is not set
-# CONFIG_PINCTRL_MDM9607 is not set
-# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set
-# CONFIG_PINCTRL_MSM8953 is not set
-# CONFIG_PINCTRL_MSM8X74 is not set
-# CONFIG_PINCTRL_MT6779 is not set
-# CONFIG_PINCTRL_MT8167 is not set
-# CONFIG_PINCTRL_MT8192 is not set
-# CONFIG_PINCTRL_MT8195 is not set
-# CONFIG_PINCTRL_MT8365 is not set
-# CONFIG_PINCTRL_MTK_V2 is not set
-# CONFIG_PINCTRL_OCELOT is not set
-# CONFIG_PINCTRL_PISTACHIO is not set
-# CONFIG_PINCTRL_RP1 is not set
-# CONFIG_PINCTRL_SC7280 is not set
-# CONFIG_PINCTRL_SC8180X is not set
-# CONFIG_PINCTRL_SDX55 is not set
-CONFIG_PINCTRL_SINGLE=y
-# CONFIG_PINCTRL_SM6115 is not set
-# CONFIG_PINCTRL_SM6125 is not set
-# CONFIG_PINCTRL_SM8350 is not set
-# CONFIG_PINCTRL_STMFX is not set
-# CONFIG_PINCTRL_SX150X is not set
-# CONFIG_PING is not set
-CONFIG_PINMUX=y
-# CONFIG_PKCS7_MESSAGE_PARSER is not set
-# CONFIG_PL310_ERRATA_588369 is not set
-# CONFIG_PL310_ERRATA_727915 is not set
-# CONFIG_PL310_ERRATA_753970 is not set
-# CONFIG_PL310_ERRATA_769419 is not set
-# CONFIG_PL320_MBOX is not set
-# CONFIG_PL330_DMA is not set
-# CONFIG_PLATFORM_MHU is not set
-# CONFIG_PLAT_SPEAR is not set
-# CONFIG_PLIP is not set
-# CONFIG_PLX_DMA is not set
-# CONFIG_PLX_HERMES is not set
-# CONFIG_PM is not set
-# CONFIG_PMBUS is not set
-# CONFIG_PMC_MSP is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PMS7003 is not set
-# CONFIG_PM_AUTOSLEEP is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_DEVFREQ is not set
-# CONFIG_PM_USERSPACE_AUTOSLEEP is not set
-# CONFIG_PM_WAKELOCKS is not set
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_POSIX_TIMERS=y
-# CONFIG_POWERCAP is not set
-# CONFIG_POWER_AVS is not set
-# CONFIG_POWER_RESET is not set
-# CONFIG_POWER_RESET_BRCMKONA is not set
-# CONFIG_POWER_RESET_BRCMSTB is not set
-# CONFIG_POWER_RESET_GPIO is not set
-# CONFIG_POWER_RESET_GPIO_RESTART is not set
-# CONFIG_POWER_RESET_LINKSTATION is not set
-# CONFIG_POWER_RESET_LTC2952 is not set
-# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set
-# CONFIG_POWER_RESET_QNAP is not set
-# CONFIG_POWER_RESET_REGULATOR is not set
-# CONFIG_POWER_RESET_RESTART is not set
-# CONFIG_POWER_RESET_SYSCON is not set
-# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
-# CONFIG_POWER_RESET_VERSATILE is not set
-# CONFIG_POWER_RESET_XGENE is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_POWER_SUPPLY_HWMON is not set
-# CONFIG_PPC4xx_GPIO is not set
-# CONFIG_PPC_16K_PAGES is not set
-# CONFIG_PPC_256K_PAGES is not set
-CONFIG_PPC_4K_PAGES=y
-# CONFIG_PPC_64K_PAGES is not set
-# CONFIG_PPC_DISABLE_WERROR is not set
-# CONFIG_PPC_EMULATED_STATS is not set
-# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set
-# CONFIG_PPC_QUEUED_SPINLOCKS is not set
-# CONFIG_PPP is not set
-# CONFIG_PPPOATM is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPPOL2TP is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_FILTER=y
-# CONFIG_PPP_MPPE is not set
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPS is not set
-# CONFIG_PPS_CLIENT_GPIO is not set
-# CONFIG_PPS_CLIENT_KTIMER is not set
-# CONFIG_PPS_CLIENT_LDISC is not set
-# CONFIG_PPS_CLIENT_PARPORT is not set
-# CONFIG_PPS_DEBUG is not set
-# CONFIG_PPTP is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_PREEMPTIRQ_DELAY_TEST is not set
-# CONFIG_PREEMPTIRQ_EVENTS is not set
-# CONFIG_PREEMPT_DYNAMIC is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PRESTERA is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_PRIME_NUMBERS is not set
-CONFIG_PRINTK=y
-# CONFIG_PRINTK_CALLER is not set
-# CONFIG_PRINTK_INDEX is not set
-CONFIG_PRINTK_NMI=y
-CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
-# CONFIG_PRINTK_TIME is not set
-CONFIG_PRINT_STACK_DEPTH=64
-# CONFIG_PRISM2_USB is not set
-# CONFIG_PRISM54 is not set
-# CONFIG_PROC_CHILDREN is not set
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-# CONFIG_PROC_PAGE_MONITOR is not set
-# CONFIG_PROC_STRIPPED is not set
-CONFIG_PROC_SYSCTL=y
-# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILING is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_PROVE_RAW_LOCK_NESTING is not set
-# CONFIG_PROVE_RCU is not set
-# CONFIG_PROVE_RCU_LIST is not set
-# CONFIG_PROVE_RCU_REPEATEDLY is not set
-# CONFIG_PSAMPLE is not set
-# CONFIG_PSB6970_PHY is not set
-# CONFIG_PSE_CONTROLLER is not set
-# CONFIG_PSI is not set
-# CONFIG_PSTORE is not set
-# CONFIG_PSTORE_842_COMPRESS is not set
-# CONFIG_PSTORE_BLK is not set
-# CONFIG_PSTORE_COMPRESS is not set
-# CONFIG_PSTORE_CONSOLE is not set
-CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
-# CONFIG_PSTORE_DEFLATE_COMPRESS is not set
-# CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT is not set
-# CONFIG_PSTORE_FTRACE is not set
-# CONFIG_PSTORE_LZ4HC_COMPRESS is not set
-# CONFIG_PSTORE_LZ4_COMPRESS is not set
-# CONFIG_PSTORE_LZO_COMPRESS is not set
-# CONFIG_PSTORE_PMSG is not set
-# CONFIG_PSTORE_RAM is not set
-# CONFIG_PSTORE_ZSTD_COMPRESS is not set
-# CONFIG_PTDUMP_DEBUGFS is not set
-# CONFIG_PTP_1588_CLOCK is not set
-# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set
-# CONFIG_PTP_1588_CLOCK_IDTCM is not set
-# CONFIG_PTP_1588_CLOCK_IXP46X is not set
-# CONFIG_PTP_1588_CLOCK_KVM is not set
-# CONFIG_PTP_1588_CLOCK_OCP is not set
-# CONFIG_PTP_1588_CLOCK_PCH is not set
-# CONFIG_PTP_1588_CLOCK_VMW is not set
-# CONFIG_PUBLIC_KEY_ALGO_RSA is not set
-# CONFIG_PVPANIC is not set
-# CONFIG_PWM is not set
-# CONFIG_PWM_ATMEL_TCB is not set
-# CONFIG_PWM_CLK is not set
-# CONFIG_PWM_DEBUG is not set
-# CONFIG_PWM_DWC is not set
-# CONFIG_PWM_FSL_FTM is not set
-# CONFIG_PWM_IMG is not set
-# CONFIG_PWM_JZ4740 is not set
-# CONFIG_PWM_MEDIATEK is not set
-# CONFIG_PWM_PCA9685 is not set
-# CONFIG_PWM_RASPBERRYPI_POE is not set
-# CONFIG_PWM_RP1 is not set
-# CONFIG_PWM_XILINX is not set
-CONFIG_PWRSEQ_EMMC=y
-# CONFIG_PWRSEQ_SD8787 is not set
-CONFIG_PWRSEQ_SIMPLE=y
-# CONFIG_QCA7000 is not set
-# CONFIG_QCA7000_SPI is not set
-# CONFIG_QCA7000_UART is not set
-# CONFIG_QCA807X_PHY is not set
-# CONFIG_QCA808X_PHY is not set
-# CONFIG_QCA83XX_PHY is not set
-# CONFIG_QCOM_A7PLL is not set
-# CONFIG_QCOM_BAM_DMUX is not set
-# CONFIG_QCOM_EMAC is not set
-# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
-# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
-# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
-# CONFIG_QCOM_GPI_DMA is not set
-# CONFIG_QCOM_HIDMA is not set
-# CONFIG_QCOM_HIDMA_MGMT is not set
-# CONFIG_QCOM_LMH is not set
-# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
-# CONFIG_QCOM_SPMI_ADC5 is not set
-# CONFIG_QCOM_SPMI_ADC_TM5 is not set
-# CONFIG_QCOM_SPMI_IADC is not set
-# CONFIG_QCOM_SPMI_TEMP_ALARM is not set
-# CONFIG_QCOM_SPMI_VADC is not set
-# CONFIG_QCOM_SSC_BLOCK_BUS is not set
-# CONFIG_QED is not set
-# CONFIG_QFMT_V1 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_QLCNIC is not set
-# CONFIG_QLGE is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX6FS_FS is not set
-# CONFIG_QORIQ_CPUFREQ is not set
-# CONFIG_QORIQ_THERMAL is not set
-# CONFIG_QRTR is not set
-# CONFIG_QRTR_MHI is not set
-# CONFIG_QRTR_TUN is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_QUEUED_LOCK_STAT is not set
-# CONFIG_QUICC_ENGINE is not set
-# CONFIG_QUOTA is not set
-# CONFIG_QUOTACTL is not set
-# CONFIG_QUOTA_DEBUG is not set
-# CONFIG_QUOTA_NETLINK_INTERFACE is not set
-# CONFIG_R3964 is not set
-# CONFIG_R6040 is not set
-# CONFIG_R8169 is not set
-# CONFIG_R8188EU is not set
-# CONFIG_R8712U is not set
-# CONFIG_R8723AU is not set
-# CONFIG_RADIO_ADAPTERS is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-# CONFIG_RAID6_PQ_BENCHMARK is not set
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_RALINK is not set
-# CONFIG_RANDOM32_SELFTEST is not set
-# CONFIG_RANDOMIZE_BASE is not set
-CONFIG_RANDOMIZE_KSTACK_OFFSET=y
-# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
-CONFIG_RANDOM_TRUST_BOOTLOADER=y
-CONFIG_RANDOM_TRUST_CPU=y
-# CONFIG_RANDSTRUCT_NONE is not set
-# CONFIG_RAPIDIO is not set
-# CONFIG_RAS is not set
-# CONFIG_RASPBERRYPI_GPIOMEM is not set
-# CONFIG_RBTREE_TEST is not set
-# CONFIG_RCU_BOOST is not set
-CONFIG_RCU_CPU_STALL_TIMEOUT=60
-# CONFIG_RCU_EQS_DEBUG is not set
-# CONFIG_RCU_EXPEDITE_BOOT is not set
-# CONFIG_RCU_EXPERT is not set
-CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0
-CONFIG_RCU_KTHREAD_PRIO=0
-CONFIG_RCU_NEED_SEGCBLIST=y
-# CONFIG_RCU_PERF_TEST is not set
-# CONFIG_RCU_REF_SCALE_TEST is not set
-# CONFIG_RCU_SCALE_TEST is not set
-CONFIG_RCU_STALL_COMMON=y
-# CONFIG_RCU_STRICT_GRACE_PERIOD is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3
-# CONFIG_RCU_TRACE is not set
-# CONFIG_RC_ATI_REMOTE is not set
-# CONFIG_RC_CORE is not set
-# CONFIG_RC_DECODERS is not set
-# CONFIG_RC_LOOPBACK is not set
-# CONFIG_RC_MAP is not set
-# CONFIG_RC_XBOX_DVD is not set
-# CONFIG_RDS is not set
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_GZIP is not set
-# CONFIG_RD_LZ4 is not set
-# CONFIG_RD_LZMA is not set
-# CONFIG_RD_LZO is not set
-# CONFIG_RD_XZ is not set
-# CONFIG_RD_ZSTD is not set
-# CONFIG_READABLE_ASM is not set
-# CONFIG_READ_ONLY_THP_FOR_FS is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_REDWOOD is not set
-# CONFIG_REED_SOLOMON is not set
-# CONFIG_REED_SOLOMON_DEC8 is not set
-# CONFIG_REED_SOLOMON_ENC8 is not set
-# CONFIG_REED_SOLOMON_TEST is not set
-# CONFIG_REGMAP is not set
-# CONFIG_REGMAP_I2C is not set
-# CONFIG_REGMAP_MMIO is not set
-# CONFIG_REGMAP_SPI is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_88PG86X is not set
-# CONFIG_REGULATOR_ACT8865 is not set
-# CONFIG_REGULATOR_AD5398 is not set
-# CONFIG_REGULATOR_ANATOP is not set
-# CONFIG_REGULATOR_DA9121 is not set
-# CONFIG_REGULATOR_DA9210 is not set
-# CONFIG_REGULATOR_DA9211 is not set
-# CONFIG_REGULATOR_DEBUG is not set
-# CONFIG_REGULATOR_FAN53555 is not set
-# CONFIG_REGULATOR_FAN53880 is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_GPIO is not set
-# CONFIG_REGULATOR_ISL6271A is not set
-# CONFIG_REGULATOR_ISL9305 is not set
-# CONFIG_REGULATOR_LP3971 is not set
-# CONFIG_REGULATOR_LP3972 is not set
-# CONFIG_REGULATOR_LP872X is not set
-# CONFIG_REGULATOR_LP8755 is not set
-# CONFIG_REGULATOR_LTC3589 is not set
-# CONFIG_REGULATOR_LTC3676 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_MAX20086 is not set
-# CONFIG_REGULATOR_MAX77620 is not set
-# CONFIG_REGULATOR_MAX77826 is not set
-# CONFIG_REGULATOR_MAX8649 is not set
-# CONFIG_REGULATOR_MAX8660 is not set
-# CONFIG_REGULATOR_MAX8893 is not set
-# CONFIG_REGULATOR_MAX8952 is not set
-# CONFIG_REGULATOR_MAX8973 is not set
-# CONFIG_REGULATOR_MCP16502 is not set
-# CONFIG_REGULATOR_MP5416 is not set
-# CONFIG_REGULATOR_MP8859 is not set
-# CONFIG_REGULATOR_MP886X is not set
-# CONFIG_REGULATOR_MPQ7920 is not set
-# CONFIG_REGULATOR_MT6311 is not set
-# CONFIG_REGULATOR_MT6315 is not set
-# CONFIG_REGULATOR_MT6359 is not set
-# CONFIG_REGULATOR_PCA9450 is not set
-# CONFIG_REGULATOR_PF8X00 is not set
-# CONFIG_REGULATOR_PFUZE100 is not set
-# CONFIG_REGULATOR_PV88060 is not set
-# CONFIG_REGULATOR_PV88080 is not set
-# CONFIG_REGULATOR_PV88090 is not set
-# CONFIG_REGULATOR_PWM is not set
-# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set
-# CONFIG_REGULATOR_RT4801 is not set
-# CONFIG_REGULATOR_RT5190A is not set
-# CONFIG_REGULATOR_RT5759 is not set
-# CONFIG_REGULATOR_RT6160 is not set
-# CONFIG_REGULATOR_RT6245 is not set
-# CONFIG_REGULATOR_RTMV20 is not set
-# CONFIG_REGULATOR_RTQ2134 is not set
-# CONFIG_REGULATOR_RTQ6752 is not set
-# CONFIG_REGULATOR_SLG51000 is not set
-# CONFIG_REGULATOR_SY8106A is not set
-# CONFIG_REGULATOR_SY8824X is not set
-# CONFIG_REGULATOR_SY8827N is not set
-# CONFIG_REGULATOR_TI_ABB is not set
-# CONFIG_REGULATOR_TPS51632 is not set
-# CONFIG_REGULATOR_TPS62360 is not set
-# CONFIG_REGULATOR_TPS6286X is not set
-# CONFIG_REGULATOR_TPS65023 is not set
-# CONFIG_REGULATOR_TPS6507X is not set
-# CONFIG_REGULATOR_TPS65132 is not set
-# CONFIG_REGULATOR_TPS6524X is not set
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_REGULATOR_VCTRL is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_FS_POSIX_ACL is not set
-# CONFIG_REISERFS_FS_SECURITY is not set
-CONFIG_REISERFS_FS_XATTR=y
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_RELAY is not set
-# CONFIG_RELOCATABLE is not set
-# CONFIG_REMOTEPROC is not set
-# CONFIG_RENESAS_PHY is not set
-# CONFIG_RESET_ATH79 is not set
-# CONFIG_RESET_BERLIN is not set
-# CONFIG_RESET_BRCMSTB is not set
-# CONFIG_RESET_BRCMSTB_RESCAL is not set
-# CONFIG_RESET_CONTROLLER is not set
-# CONFIG_RESET_IMX7 is not set
-# CONFIG_RESET_INTEL_GW is not set
-# CONFIG_RESET_LANTIQ is not set
-# CONFIG_RESET_LPC18XX is not set
-# CONFIG_RESET_MESON is not set
-# CONFIG_RESET_PISTACHIO is not set
-# CONFIG_RESET_SIMPLE is not set
-# CONFIG_RESET_SOCFPGA is not set
-# CONFIG_RESET_STM32 is not set
-# CONFIG_RESET_SUNXI is not set
-# CONFIG_RESET_TEGRA_BPMP is not set
-# CONFIG_RESET_TI_SYSCON is not set
-# CONFIG_RESET_TI_TPS380X is not set
-# CONFIG_RESET_ZYNQ is not set
-# CONFIG_RFD77402 is not set
-# CONFIG_RFD_FTL is not set
-CONFIG_RFKILL=y
-# CONFIG_RFKILL_FULL is not set
-# CONFIG_RFKILL_GPIO is not set
-# CONFIG_RFKILL_INPUT is not set
-# CONFIG_RFKILL_LEDS is not set
-# CONFIG_RFKILL_REGULATOR is not set
-# CONFIG_RICHTEK_RTQ6056 is not set
-# CONFIG_RING_BUFFER_BENCHMARK is not set
-# CONFIG_RING_BUFFER_STARTUP_TEST is not set
-# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set
-# CONFIG_RISCV_PMU is not set
-# CONFIG_RISCV_PMU_LEGACY is not set
-# CONFIG_RISCV_PMU_SBI is not set
-# CONFIG_RMI4_CORE is not set
-# CONFIG_RMNET is not set
-# CONFIG_ROCKCHIP_PHY is not set
-# CONFIG_ROCKER is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_ROSE is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
-# CONFIG_RPMSG_VIRTIO is not set
-# CONFIG_RPMSG_WWAN_CTRL is not set
-# CONFIG_RPR0521 is not set
-# CONFIG_RSEQ is not set
-# CONFIG_RT2X00 is not set
-# CONFIG_RTC_CLASS is not set
-# CONFIG_RTC_DEBUG is not set
-# CONFIG_RTC_DRV_ABB5ZES3 is not set
-# CONFIG_RTC_DRV_ABEOZ9 is not set
-# CONFIG_RTC_DRV_ABX80X is not set
-# CONFIG_RTC_DRV_ARMADA38X is not set
-# CONFIG_RTC_DRV_AU1XXX is not set
-# CONFIG_RTC_DRV_BQ32K is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-# CONFIG_RTC_DRV_CADENCE is not set
-CONFIG_RTC_DRV_CMOS=y
-# CONFIG_RTC_DRV_DS1286 is not set
-# CONFIG_RTC_DRV_DS1302 is not set
-# CONFIG_RTC_DRV_DS1305 is not set
-# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1307_CENTURY is not set
-# CONFIG_RTC_DRV_DS1307_HWMON is not set
-# CONFIG_RTC_DRV_DS1343 is not set
-# CONFIG_RTC_DRV_DS1347 is not set
-# CONFIG_RTC_DRV_DS1374 is not set
-# CONFIG_RTC_DRV_DS1390 is not set
-# CONFIG_RTC_DRV_DS1511 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1685_FAMILY is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_DS2404 is not set
-# CONFIG_RTC_DRV_DS3232 is not set
-# CONFIG_RTC_DRV_DS3234 is not set
-# CONFIG_RTC_DRV_EM3027 is not set
-# CONFIG_RTC_DRV_EP93XX is not set
-# CONFIG_RTC_DRV_FM3130 is not set
-# CONFIG_RTC_DRV_FTRTC010 is not set
-# CONFIG_RTC_DRV_GENERIC is not set
-# CONFIG_RTC_DRV_GOLDFISH is not set
-# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
-# CONFIG_RTC_DRV_HYM8563 is not set
-# CONFIG_RTC_DRV_ISL12022 is not set
-# CONFIG_RTC_DRV_ISL12026 is not set
-# CONFIG_RTC_DRV_ISL12057 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
-# CONFIG_RTC_DRV_JZ4740 is not set
-# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_M41T93 is not set
-# CONFIG_RTC_DRV_M41T94 is not set
-# CONFIG_RTC_DRV_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_MAX6900 is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_MAX6916 is not set
-# CONFIG_RTC_DRV_MAX77686 is not set
-# CONFIG_RTC_DRV_MCP795 is not set
-# CONFIG_RTC_DRV_MOXART is not set
-# CONFIG_RTC_DRV_MPC5121 is not set
-# CONFIG_RTC_DRV_MSM6242 is not set
-# CONFIG_RTC_DRV_MT2712 is not set
-# CONFIG_RTC_DRV_NCT3018Y is not set
-# CONFIG_RTC_DRV_OMAP is not set
-# CONFIG_RTC_DRV_PCF2123 is not set
-# CONFIG_RTC_DRV_PCF2127 is not set
-# CONFIG_RTC_DRV_PCF85063 is not set
-# CONFIG_RTC_DRV_PCF8523 is not set
-# CONFIG_RTC_DRV_PCF85363 is not set
-# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
-# CONFIG_RTC_DRV_PL030 is not set
-# CONFIG_RTC_DRV_PL031 is not set
-# CONFIG_RTC_DRV_PS3 is not set
-# CONFIG_RTC_DRV_PT7C4338 is not set
-# CONFIG_RTC_DRV_R7301 is not set
-# CONFIG_RTC_DRV_R9701 is not set
-# CONFIG_RTC_DRV_RP5C01 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_RTC7301 is not set
-# CONFIG_RTC_DRV_RV3028 is not set
-# CONFIG_RTC_DRV_RV3029C2 is not set
-# CONFIG_RTC_DRV_RV3032 is not set
-# CONFIG_RTC_DRV_RV8803 is not set
-# CONFIG_RTC_DRV_RX4581 is not set
-# CONFIG_RTC_DRV_RX6110 is not set
-# CONFIG_RTC_DRV_RX8010 is not set
-# CONFIG_RTC_DRV_RX8025 is not set
-# CONFIG_RTC_DRV_RX8581 is not set
-# CONFIG_RTC_DRV_S35390A is not set
-# CONFIG_RTC_DRV_SD3078 is not set
-# CONFIG_RTC_DRV_SNVS is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_SUN6I is not set
-# CONFIG_RTC_DRV_TEGRA is not set
-# CONFIG_RTC_DRV_TEST is not set
-# CONFIG_RTC_DRV_V3020 is not set
-# CONFIG_RTC_DRV_X1205 is not set
-# CONFIG_RTC_DRV_XGENE is not set
-# CONFIG_RTC_DRV_ZYNQMP is not set
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-CONFIG_RTC_INTF_DEV=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_NVMEM is not set
-CONFIG_RTC_SYSTOHC=y
-CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
-# CONFIG_RTL8180 is not set
-# CONFIG_RTL8187 is not set
-# CONFIG_RTL8192E is not set
-# CONFIG_RTL8192U is not set
-# CONFIG_RTL8306_PHY is not set
-# CONFIG_RTL8366RB_PHY is not set
-# CONFIG_RTL8366S_PHY is not set
-# CONFIG_RTL8366_SMI is not set
-# CONFIG_RTL8366_SMI_DEBUG_FS is not set
-# CONFIG_RTL8367B_PHY is not set
-# CONFIG_RTL8367_PHY is not set
-# CONFIG_RTLLIB is not set
-# CONFIG_RTL_CARDS is not set
-# CONFIG_RTS5208 is not set
-CONFIG_RT_MUTEXES=y
-# CONFIG_RUNTIME_DEBUG is not set
-CONFIG_RUNTIME_TESTING_MENU=y
-# CONFIG_RV is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_RXKAD=y
-# CONFIG_S2IO is not set
-# CONFIG_SAMPLES is not set
-# CONFIG_SAMSUNG_LAPTOP is not set
-# CONFIG_SATA_ACARD_AHCI is not set
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_AHCI_PLATFORM is not set
-# CONFIG_SATA_DWC is not set
-# CONFIG_SATA_DWC_OLD_DMA is not set
-# CONFIG_SATA_FSL is not set
-# CONFIG_SATA_HIGHBANK is not set
-# CONFIG_SATA_HOST is not set
-# CONFIG_SATA_INIC162X is not set
-CONFIG_SATA_MOBILE_LPM_POLICY=0
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_SATA_PMP is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_RCAR is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_SVW is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SBC_FITPC2_WATCHDOG is not set
-CONFIG_SBITMAP=y
-# CONFIG_SC92031 is not set
-# CONFIG_SCA3000 is not set
-# CONFIG_SCA3300 is not set
-# CONFIG_SCACHE_DEBUGFS is not set
-# CONFIG_SCC is not set
-# CONFIG_SCD30_CORE is not set
-# CONFIG_SCD4X is not set
-# CONFIG_SCF_TORTURE_TEST is not set
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_SCHED_AUTOGROUP is not set
-# CONFIG_SCHED_CLUSTER is not set
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_SCHED_HRTICK=y
-# CONFIG_SCHED_MC is not set
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-# CONFIG_SCHED_SMT is not set
-CONFIG_SCHED_STACK_END_CHECK=y
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_SCR24X is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_3W_SAS is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_SCSI_BFA_FC is not set
-# CONFIG_SCSI_BNX2X_FCOE is not set
-# CONFIG_SCSI_BNX2_ISCSI is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CHELSIO_FCOE is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_CXGB3_ISCSI is not set
-# CONFIG_SCSI_CXGB4_ISCSI is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_ESAS2R is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_FDOMAIN_PCI is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_HISI_SAS is not set
-# CONFIG_SCSI_HPSA is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_ISCI is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
-# CONFIG_SCSI_LPFC is not set
-CONFIG_SCSI_MOD=y
-# CONFIG_SCSI_MPI3MR is not set
-# CONFIG_SCSI_MPT2SAS is not set
-# CONFIG_SCSI_MPT3SAS is not set
-# CONFIG_SCSI_MQ_DEFAULT is not set
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_MVSAS_DEBUG is not set
-# CONFIG_SCSI_MVUMI is not set
-# CONFIG_SCSI_MYRB is not set
-# CONFIG_SCSI_MYRS is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PM8001 is not set
-# CONFIG_SCSI_PMCRAID is not set
-CONFIG_SCSI_PROC_FS=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-# CONFIG_SCSI_SMARTPQI is not set
-# CONFIG_SCSI_SNIC is not set
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_UFSHCD is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_VIRTIO is not set
-# CONFIG_SCSI_WD719X is not set
-# CONFIG_SC_CAMCC_7180 is not set
-# CONFIG_SC_DISPCC_7280 is not set
-# CONFIG_SC_GCC_7280 is not set
-# CONFIG_SC_GCC_8180X is not set
-# CONFIG_SC_GPUCC_7280 is not set
-# CONFIG_SC_GPUCC_8280XP is not set
-# CONFIG_SC_VIDEOCC_7280 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_SDIO_UART is not set
-# CONFIG_SDM_GPUCC_660 is not set
-# CONFIG_SDM_MMCC_660 is not set
-# CONFIG_SDR_MAX2175 is not set
-# CONFIG_SDR_PLATFORM_DRIVERS is not set
-# CONFIG_SDX_GCC_55 is not set
-# CONFIG_SD_ADC_MODULATOR is not set
-# CONFIG_SECCOMP is not set
-# CONFIG_SECCOMP_CACHE_DEBUG is not set
-CONFIG_SECTION_MISMATCH_WARN_ONLY=y
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_APPARMOR is not set
-CONFIG_SECURITY_DMESG_RESTRICT=y
-# CONFIG_SECURITY_LANDLOCK is not set
-# CONFIG_SECURITY_LOADPIN is not set
-# CONFIG_SECURITY_LOCKDOWN_LSM is not set
-# CONFIG_SECURITY_NETWORK_XFRM is not set
-# CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_SAFESETID is not set
-# CONFIG_SECURITY_SELINUX_AVC_STATS is not set
-# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set
-CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0
-# CONFIG_SECURITY_SELINUX_DEVELOP is not set
-# CONFIG_SECURITY_SELINUX_DISABLE is not set
-# CONFIG_SECURITY_SMACK is not set
-# CONFIG_SECURITY_TOMOYO is not set
-# CONFIG_SECURITY_YAMA is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_SENSEAIR_SUNRISE_CO2 is not set
-# CONFIG_SENSIRION_SGP30 is not set
-# CONFIG_SENSIRION_SGP40 is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
-# CONFIG_SENSORS_ACPI_POWER is not set
-# CONFIG_SENSORS_AD7314 is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADC128D818 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM1177 is not set
-# CONFIG_SENSORS_ADM1266 is not set
-# CONFIG_SENSORS_ADM1275 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADS1015 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_ADS7871 is not set
-# CONFIG_SENSORS_ADT7310 is not set
-# CONFIG_SENSORS_ADT7410 is not set
-# CONFIG_SENSORS_ADT7411 is not set
-# CONFIG_SENSORS_ADT7462 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7475 is not set
-# CONFIG_SENSORS_AHT10 is not set
-# CONFIG_SENSORS_AMC6821 is not set
-# CONFIG_SENSORS_APDS990X is not set
-# CONFIG_SENSORS_APPLESMC is not set
-# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set
-# CONFIG_SENSORS_AS370 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ASC7621 is not set
-# CONFIG_SENSORS_ASPEED is not set
-# CONFIG_SENSORS_ATK0110 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_AXI_FAN_CONTROL is not set
-# CONFIG_SENSORS_BEL_PFE is not set
-# CONFIG_SENSORS_BH1770 is not set
-# CONFIG_SENSORS_BH1780 is not set
-# CONFIG_SENSORS_BPA_RS600 is not set
-# CONFIG_SENSORS_CORETEMP is not set
-# CONFIG_SENSORS_CORSAIR_CPRO is not set
-# CONFIG_SENSORS_CORSAIR_PSU is not set
-# CONFIG_SENSORS_DELL_SMM is not set
-# CONFIG_SENSORS_DELTA_AHE50DC_FAN is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_DPS920AB is not set
-# CONFIG_SENSORS_DRIVETEMP is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_DS620 is not set
-# CONFIG_SENSORS_EMC1403 is not set
-# CONFIG_SENSORS_EMC2103 is not set
-# CONFIG_SENSORS_EMC2305 is not set
-# CONFIG_SENSORS_EMC6W201 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_FAM15H_POWER is not set
-# CONFIG_SENSORS_FSCHMD is not set
-# CONFIG_SENSORS_FSP_3Y is not set
-# CONFIG_SENSORS_FTSTEUTATES is not set
-# CONFIG_SENSORS_G760A is not set
-# CONFIG_SENSORS_G762 is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_GPIO_FAN is not set
-# CONFIG_SENSORS_GSC is not set
-# CONFIG_SENSORS_HDAPS is not set
-# CONFIG_SENSORS_HIH6130 is not set
-# CONFIG_SENSORS_HMC5843 is not set
-# CONFIG_SENSORS_HMC5843_I2C is not set
-# CONFIG_SENSORS_HMC5843_SPI is not set
-# CONFIG_SENSORS_HTU21 is not set
-# CONFIG_SENSORS_I5500 is not set
-# CONFIG_SENSORS_I5K_AMB is not set
-# CONFIG_SENSORS_IBM_CFFPS is not set
-# CONFIG_SENSORS_IIO_HWMON is not set
-# CONFIG_SENSORS_INA209 is not set
-# CONFIG_SENSORS_INA238 is not set
-# CONFIG_SENSORS_INA2XX is not set
-# CONFIG_SENSORS_INA3221 is not set
-# CONFIG_SENSORS_INSPUR_IPSPS is not set
-# CONFIG_SENSORS_IR35221 is not set
-# CONFIG_SENSORS_IR36021 is not set
-# CONFIG_SENSORS_IR38064 is not set
-# CONFIG_SENSORS_IRPS5401 is not set
-# CONFIG_SENSORS_ISL29018 is not set
-# CONFIG_SENSORS_ISL29028 is not set
-# CONFIG_SENSORS_ISL68137 is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_JC42 is not set
-# CONFIG_SENSORS_K10TEMP is not set
-# CONFIG_SENSORS_K8TEMP is not set
-# CONFIG_SENSORS_LINEAGE is not set
-# CONFIG_SENSORS_LIS3LV02D is not set
-# CONFIG_SENSORS_LIS3_I2C is not set
-# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_SENSORS_LM25066 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM73 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_LM95234 is not set
-# CONFIG_SENSORS_LM95241 is not set
-# CONFIG_SENSORS_LM95245 is not set
-# CONFIG_SENSORS_LT7182S is not set
-# CONFIG_SENSORS_LTC2945 is not set
-# CONFIG_SENSORS_LTC2947_I2C is not set
-# CONFIG_SENSORS_LTC2947_SPI is not set
-# CONFIG_SENSORS_LTC2978 is not set
-# CONFIG_SENSORS_LTC2990 is not set
-# CONFIG_SENSORS_LTC2992 is not set
-# CONFIG_SENSORS_LTC3815 is not set
-# CONFIG_SENSORS_LTC4151 is not set
-# CONFIG_SENSORS_LTC4215 is not set
-# CONFIG_SENSORS_LTC4222 is not set
-# CONFIG_SENSORS_LTC4245 is not set
-# CONFIG_SENSORS_LTC4260 is not set
-# CONFIG_SENSORS_LTC4261 is not set
-# CONFIG_SENSORS_LTQ_CPUTEMP is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX127 is not set
-# CONFIG_SENSORS_MAX15301 is not set
-# CONFIG_SENSORS_MAX16064 is not set
-# CONFIG_SENSORS_MAX16065 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX16601 is not set
-# CONFIG_SENSORS_MAX1668 is not set
-# CONFIG_SENSORS_MAX197 is not set
-# CONFIG_SENSORS_MAX20730 is not set
-# CONFIG_SENSORS_MAX20751 is not set
-# CONFIG_SENSORS_MAX31722 is not set
-# CONFIG_SENSORS_MAX31730 is not set
-# CONFIG_SENSORS_MAX31760 is not set
-# CONFIG_SENSORS_MAX31785 is not set
-# CONFIG_SENSORS_MAX31790 is not set
-# CONFIG_SENSORS_MAX34440 is not set
-# CONFIG_SENSORS_MAX6620 is not set
-# CONFIG_SENSORS_MAX6621 is not set
-# CONFIG_SENSORS_MAX6639 is not set
-# CONFIG_SENSORS_MAX6642 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_MAX6697 is not set
-# CONFIG_SENSORS_MAX8688 is not set
-# CONFIG_SENSORS_MCP3021 is not set
-# CONFIG_SENSORS_MP2888 is not set
-# CONFIG_SENSORS_MP2975 is not set
-# CONFIG_SENSORS_MP5023 is not set
-# CONFIG_SENSORS_MR75203 is not set
-# CONFIG_SENSORS_NCT6683 is not set
-# CONFIG_SENSORS_NCT6775 is not set
-# CONFIG_SENSORS_NCT6775_I2C is not set
-# CONFIG_SENSORS_NCT7802 is not set
-# CONFIG_SENSORS_NCT7904 is not set
-# CONFIG_SENSORS_NPCM7XX is not set
-# CONFIG_SENSORS_NSA320 is not set
-# CONFIG_SENSORS_NTC_THERMISTOR is not set
-# CONFIG_SENSORS_NZXT_KRAKEN2 is not set
-# CONFIG_SENSORS_NZXT_SMART2 is not set
-# CONFIG_SENSORS_OCC_P8_I2C is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_PIM4328 is not set
-# CONFIG_SENSORS_PLI1209BC is not set
-# CONFIG_SENSORS_PM6764TR is not set
-# CONFIG_SENSORS_PMBUS is not set
-# CONFIG_SENSORS_POWR1220 is not set
-# CONFIG_SENSORS_PWM_FAN is not set
-# CONFIG_SENSORS_PXE1610 is not set
-# CONFIG_SENSORS_Q54SJ108A2 is not set
-# CONFIG_SENSORS_RM3100_I2C is not set
-# CONFIG_SENSORS_RM3100_SPI is not set
-# CONFIG_SENSORS_RP1_ADC is not set
-# CONFIG_SENSORS_SBRMI is not set
-# CONFIG_SENSORS_SBTSI is not set
-# CONFIG_SENSORS_SCH5627 is not set
-# CONFIG_SENSORS_SCH5636 is not set
-# CONFIG_SENSORS_SCH56XX_COMMON is not set
-# CONFIG_SENSORS_SHT15 is not set
-# CONFIG_SENSORS_SHT21 is not set
-# CONFIG_SENSORS_SHT3x is not set
-# CONFIG_SENSORS_SHT4x is not set
-# CONFIG_SENSORS_SHTC1 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMM665 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_STPDDC60 is not set
-# CONFIG_SENSORS_STTS751 is not set
-# CONFIG_SENSORS_TC654 is not set
-# CONFIG_SENSORS_TC74 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_TMP102 is not set
-# CONFIG_SENSORS_TMP103 is not set
-# CONFIG_SENSORS_TMP108 is not set
-# CONFIG_SENSORS_TMP401 is not set
-# CONFIG_SENSORS_TMP421 is not set
-# CONFIG_SENSORS_TMP464 is not set
-# CONFIG_SENSORS_TMP513 is not set
-# CONFIG_SENSORS_TPS23861 is not set
-# CONFIG_SENSORS_TPS40422 is not set
-# CONFIG_SENSORS_TPS53679 is not set
-# CONFIG_SENSORS_TPS546D24 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_SENSORS_TSL2563 is not set
-# CONFIG_SENSORS_UCD9000 is not set
-# CONFIG_SENSORS_UCD9200 is not set
-# CONFIG_SENSORS_VEXPRESS is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VIA_CPUTEMP is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83773G is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83795 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_XDPE122 is not set
-# CONFIG_SENSORS_XDPE152 is not set
-# CONFIG_SENSORS_XGENE is not set
-# CONFIG_SENSORS_ZL6100 is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_16550A_VARIANTS=y
-# CONFIG_SERIAL_8250_ACCENT is not set
-# CONFIG_SERIAL_8250_ASPEED_VUART is not set
-# CONFIG_SERIAL_8250_BOCA is not set
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
-# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-CONFIG_SERIAL_8250_DMA=y
-# CONFIG_SERIAL_8250_DW is not set
-# CONFIG_SERIAL_8250_EM is not set
-# CONFIG_SERIAL_8250_EXAR is not set
-# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_FINTEK is not set
-# CONFIG_SERIAL_8250_FOURPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-# CONFIG_SERIAL_8250_INGENIC is not set
-# CONFIG_SERIAL_8250_LPSS is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_MID is not set
-# CONFIG_SERIAL_8250_MOXA is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-# CONFIG_SERIAL_8250_PCI is not set
-# CONFIG_SERIAL_8250_PERICOM is not set
-# CONFIG_SERIAL_8250_RSA is not set
-# CONFIG_SERIAL_8250_RT288X is not set
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-# CONFIG_SERIAL_AMBA_PL010 is not set
-# CONFIG_SERIAL_AMBA_PL011 is not set
-# CONFIG_SERIAL_ARC is not set
-# CONFIG_SERIAL_BCM63XX is not set
-# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_DEV_BUS is not set
-CONFIG_SERIAL_EARLYCON=y
-# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
-# CONFIG_SERIAL_FSL_LINFLEXUART is not set
-# CONFIG_SERIAL_FSL_LPUART is not set
-# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
-# CONFIG_SERIAL_IFX6X60 is not set
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_MAX3100 is not set
-# CONFIG_SERIAL_MAX310X is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_OF_PLATFORM is not set
-# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
-# CONFIG_SERIAL_PCH_UART is not set
-# CONFIG_SERIAL_RP2 is not set
-# CONFIG_SERIAL_SC16IS7XX is not set
-# CONFIG_SERIAL_SCCNXP is not set
-# CONFIG_SERIAL_SH_SCI is not set
-# CONFIG_SERIAL_SIFIVE is not set
-# CONFIG_SERIAL_SPRD is not set
-# CONFIG_SERIAL_STM32 is not set
-# CONFIG_SERIAL_ST_ASC is not set
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_UARTLITE is not set
-# CONFIG_SERIAL_XILINX_PS_UART is not set
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_ALTERA_PS2 is not set
-# CONFIG_SERIO_AMBAKMI is not set
-# CONFIG_SERIO_APBPS2 is not set
-# CONFIG_SERIO_ARC_PS2 is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_GPIO_PS2 is not set
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_PS2MULT is not set
-# CONFIG_SERIO_RAW is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_SUN4I_PS2 is not set
-# CONFIG_SFC is not set
-# CONFIG_SFC_FALCON is not set
-# CONFIG_SFC_SIENA is not set
-# CONFIG_SFI is not set
-# CONFIG_SFP is not set
-# CONFIG_SF_PDMA is not set
-# CONFIG_SGETMASK_SYSCALL is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP28 is not set
-# CONFIG_SGI_IP30 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SGI_MFD_IOC3 is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SG_POOL is not set
-# CONFIG_SG_SPLIT is not set
-# CONFIG_SHADOW_CALL_STACK is not set
-CONFIG_SHMEM=y
-# CONFIG_SHRINKER_DEBUG is not set
-# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
-# CONFIG_SH_ETH is not set
-# CONFIG_SH_TIMER_CMT is not set
-# CONFIG_SH_TIMER_MTU2 is not set
-# CONFIG_SH_TIMER_TMU is not set
-# CONFIG_SI1133 is not set
-# CONFIG_SI1145 is not set
-# CONFIG_SI7005 is not set
-# CONFIG_SI7020 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_SWARM is not set
-CONFIG_SIGNALFD=y
-# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set
-# CONFIG_SIMPLE_GPIO is not set
-# CONFIG_SIMPLE_PM_BUS is not set
-# CONFIG_SIOX is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SKY2_DEBUG is not set
-# CONFIG_SLAB is not set
-CONFIG_SLABINFO=y
-CONFIG_SLAB_FREELIST_HARDENED=y
-CONFIG_SLAB_FREELIST_RANDOM=y
-CONFIG_SLAB_MERGE_DEFAULT=y
-# CONFIG_SLHC is not set
-# CONFIG_SLICOSS is not set
-# CONFIG_SLIMBUS is not set
-# CONFIG_SLIP is not set
-# CONFIG_SLOB is not set
-CONFIG_SLUB=y
-CONFIG_SLUB_CPU_PARTIAL=y
-# CONFIG_SLUB_DEBUG is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_MEMCG_SYSFS_ON is not set
-# CONFIG_SLUB_STATS is not set
-# CONFIG_SMARTJOYPLUS_FF is not set
-# CONFIG_SMB_SERVER is not set
-# CONFIG_SMC911X is not set
-# CONFIG_SMC9194 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_SMP is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_SMSC9420 is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_SMS_SDIO_DRV is not set
-# CONFIG_SMS_USB_DRV is not set
-# CONFIG_SM_CAMCC_8250 is not set
-# CONFIG_SM_FTL is not set
-# CONFIG_SM_GCC_6115 is not set
-# CONFIG_SM_GCC_6125 is not set
-# CONFIG_SM_GCC_6350 is not set
-# CONFIG_SM_GCC_6375 is not set
-# CONFIG_SM_GCC_8350 is not set
-# CONFIG_SND is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-# CONFIG_SND_AD1816A is not set
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ADLIB is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ALOOP is not set
-# CONFIG_SND_ALS100 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_AMD_ACP_CONFIG is not set
-# CONFIG_SND_ARM is not set
-# CONFIG_SND_ASIHPI is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_ATMEL_AC97C is not set
-# CONFIG_SND_ATMEL_SOC is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AUDIO_GRAPH_CARD is not set
-# CONFIG_SND_AUDIO_GRAPH_CARD2 is not set
-# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT2320 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BCD2000 is not set
-# CONFIG_SND_BCM2835 is not set
-# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_CS5530 is not set
-# CONFIG_SND_CS5535AUDIO is not set
-# CONFIG_SND_CTL_FAST_LOOKUP is not set
-# CONFIG_SND_CTL_INPUT_VALIDATION is not set
-# CONFIG_SND_CTXFI is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_DEBUG is not set
-# CONFIG_SND_DESIGNWARE_I2S is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_EDMA_SOC is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_EMU10K1_SEQ is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FIREWIRE is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_HDA_CODEC_CS8409 is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set
-# CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM is not set
-CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
-CONFIG_SND_HDA_PREALLOC_SIZE=64
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_HWDEP is not set
-# CONFIG_SND_I2S_HI6210_I2S is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_INDIGODJX is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGOIOX is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_ISA is not set
-# CONFIG_SND_JZ4740_SOC_I2S is not set
-# CONFIG_SND_KIRKWOOD_SOC is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_LOLA is not set
-# CONFIG_SND_LX6464ES is not set
-# CONFIG_SND_MAESTRO3 is not set
-CONFIG_SND_MAX_CARDS=16
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_MIPS is not set
-# CONFIG_SND_MIRO is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MPC52xx_SOC_EFIKA is not set
-# CONFIG_SND_MPU401 is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_MTS64 is not set
-# CONFIG_SND_MXS_SOC is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_OPL3_LIB_SEQ is not set
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-CONFIG_SND_OSSEMUL=y
-# CONFIG_SND_OXYGEN is not set
-CONFIG_SND_PCI=y
-# CONFIG_SND_PCM is not set
-# CONFIG_SND_PCMCIA is not set
-# CONFIG_SND_PCM_OSS is not set
-CONFIG_SND_PCM_OSS_PLUGINS=y
-# CONFIG_SND_PCM_TIMER is not set
-# CONFIG_SND_PCM_XRUN_DEBUG is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_PDAUDIOCF is not set
-# CONFIG_SND_PORTMAN2X4 is not set
-# CONFIG_SND_POWERPC_SOC is not set
-# CONFIG_SND_PPC is not set
-CONFIG_SND_PROC_FS=y
-# CONFIG_SND_RAWMIDI is not set
-# CONFIG_SND_RAWMIDI_SEQ is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_RTCTIMER is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_SBAWE_SEQ is not set
-# CONFIG_SND_SE6X is not set
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_SERIAL_GENERIC is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_SIMPLE_CARD is not set
-# CONFIG_SND_SIMPLE_SCU_CARD is not set
-# CONFIG_SND_SIS7019 is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SND_SOC_AC97_CODEC is not set
-# CONFIG_SND_SOC_AD193X_I2C is not set
-# CONFIG_SND_SOC_AD193X_SPI is not set
-# CONFIG_SND_SOC_ADAU1372_I2C is not set
-# CONFIG_SND_SOC_ADAU1372_SPI is not set
-# CONFIG_SND_SOC_ADAU1701 is not set
-# CONFIG_SND_SOC_ADAU1761_I2C is not set
-# CONFIG_SND_SOC_ADAU1761_SPI is not set
-# CONFIG_SND_SOC_ADAU7002 is not set
-# CONFIG_SND_SOC_ADAU7118_HW is not set
-# CONFIG_SND_SOC_ADAU7118_I2C is not set
-# CONFIG_SND_SOC_ADI is not set
-# CONFIG_SND_SOC_AK4104 is not set
-# CONFIG_SND_SOC_AK4118 is not set
-# CONFIG_SND_SOC_AK4375 is not set
-# CONFIG_SND_SOC_AK4458 is not set
-# CONFIG_SND_SOC_AK4554 is not set
-# CONFIG_SND_SOC_AK4613 is not set
-# CONFIG_SND_SOC_AK4642 is not set
-# CONFIG_SND_SOC_AK5386 is not set
-# CONFIG_SND_SOC_AK5558 is not set
-# CONFIG_SND_SOC_ALC5623 is not set
-# CONFIG_SND_SOC_AMD_ACP is not set
-# CONFIG_SND_SOC_AMD_ACP3x is not set
-# CONFIG_SND_SOC_AMD_ACP5x is not set
-# CONFIG_SND_SOC_AMD_RENOIR is not set
-# CONFIG_SND_SOC_AU1XAUDIO is not set
-# CONFIG_SND_SOC_AU1XPSC is not set
-# CONFIG_SND_SOC_AW8738 is not set
-# CONFIG_SND_SOC_BD28623 is not set
-# CONFIG_SND_SOC_BT_SCO is not set
-# CONFIG_SND_SOC_CS35L32 is not set
-# CONFIG_SND_SOC_CS35L33 is not set
-# CONFIG_SND_SOC_CS35L34 is not set
-# CONFIG_SND_SOC_CS35L35 is not set
-# CONFIG_SND_SOC_CS35L36 is not set
-# CONFIG_SND_SOC_CS35L41_I2C is not set
-# CONFIG_SND_SOC_CS35L41_SPI is not set
-# CONFIG_SND_SOC_CS35L45_I2C is not set
-# CONFIG_SND_SOC_CS35L45_SPI is not set
-# CONFIG_SND_SOC_CS4234 is not set
-# CONFIG_SND_SOC_CS4265 is not set
-# CONFIG_SND_SOC_CS4270 is not set
-# CONFIG_SND_SOC_CS4271 is not set
-# CONFIG_SND_SOC_CS4271_I2C is not set
-# CONFIG_SND_SOC_CS4271_SPI is not set
-# CONFIG_SND_SOC_CS42L42 is not set
-# CONFIG_SND_SOC_CS42L51_I2C is not set
-# CONFIG_SND_SOC_CS42L52 is not set
-# CONFIG_SND_SOC_CS42L56 is not set
-# CONFIG_SND_SOC_CS42L73 is not set
-# CONFIG_SND_SOC_CS42L83 is not set
-# CONFIG_SND_SOC_CS42XX8_I2C is not set
-# CONFIG_SND_SOC_CS43130 is not set
-# CONFIG_SND_SOC_CS4341 is not set
-# CONFIG_SND_SOC_CS4349 is not set
-# CONFIG_SND_SOC_CS53L30 is not set
-# CONFIG_SND_SOC_CX2072X is not set
-# CONFIG_SND_SOC_DA7213 is not set
-# CONFIG_SND_SOC_DIO2125 is not set
-# CONFIG_SND_SOC_DMIC is not set
-# CONFIG_SND_SOC_ES7134 is not set
-# CONFIG_SND_SOC_ES7241 is not set
-# CONFIG_SND_SOC_ES8316 is not set
-# CONFIG_SND_SOC_ES8326 is not set
-# CONFIG_SND_SOC_ES8328 is not set
-# CONFIG_SND_SOC_ES8328_I2C is not set
-# CONFIG_SND_SOC_ES8328_SPI is not set
-# CONFIG_SND_SOC_EUKREA_TLV320 is not set
-# CONFIG_SND_SOC_FSL_ASOC_CARD is not set
-# CONFIG_SND_SOC_FSL_ASRC is not set
-# CONFIG_SND_SOC_FSL_AUD2HTX is not set
-# CONFIG_SND_SOC_FSL_AUDMIX is not set
-# CONFIG_SND_SOC_FSL_ESAI is not set
-# CONFIG_SND_SOC_FSL_MICFIL is not set
-# CONFIG_SND_SOC_FSL_RPMSG is not set
-# CONFIG_SND_SOC_FSL_SAI is not set
-# CONFIG_SND_SOC_FSL_SPDIF is not set
-# CONFIG_SND_SOC_FSL_SSI is not set
-# CONFIG_SND_SOC_FSL_XCVR is not set
-# CONFIG_SND_SOC_GTM601 is not set
-# CONFIG_SND_SOC_HDA is not set
-# CONFIG_SND_SOC_ICS43432 is not set
-# CONFIG_SND_SOC_IMG is not set
-# CONFIG_SND_SOC_IMX_AUDMIX is not set
-# CONFIG_SND_SOC_IMX_AUDMUX is not set
-# CONFIG_SND_SOC_IMX_CARD is not set
-# CONFIG_SND_SOC_IMX_ES8328 is not set
-# CONFIG_SND_SOC_IMX_HDMI is not set
-# CONFIG_SND_SOC_IMX_RPMSG is not set
-# CONFIG_SND_SOC_IMX_SPDIF is not set
-# CONFIG_SND_SOC_IMX_WM8962 is not set
-# CONFIG_SND_SOC_INNO_RK3036 is not set
-# CONFIG_SND_SOC_INTEL_APL is not set
-# CONFIG_SND_SOC_INTEL_BAYTRAIL is not set
-# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set
-# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set
-# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set
-# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set
-# CONFIG_SND_SOC_INTEL_CATPT is not set
-# CONFIG_SND_SOC_INTEL_CFL is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set
-# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set
-# CONFIG_SND_SOC_INTEL_CML_H is not set
-# CONFIG_SND_SOC_INTEL_CML_LP is not set
-# CONFIG_SND_SOC_INTEL_CNL is not set
-# CONFIG_SND_SOC_INTEL_GLK is not set
-# CONFIG_SND_SOC_INTEL_HASWELL is not set
-# CONFIG_SND_SOC_INTEL_KBL is not set
-# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set
-# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set
-# CONFIG_SND_SOC_INTEL_KEEMBAY is not set
-# CONFIG_SND_SOC_INTEL_SKL is not set
-# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set
-# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set
-# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set
-# CONFIG_SND_SOC_INTEL_SKYLAKE is not set
-# CONFIG_SND_SOC_INTEL_SST is not set
-CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
-# CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES is not set
-# CONFIG_SND_SOC_JZ4725B_CODEC is not set
-# CONFIG_SND_SOC_JZ4740_CODEC is not set
-# CONFIG_SND_SOC_JZ4770_CODEC is not set
-# CONFIG_SND_SOC_LPASS_RX_MACRO is not set
-# CONFIG_SND_SOC_LPASS_TX_MACRO is not set
-# CONFIG_SND_SOC_LPASS_VA_MACRO is not set
-# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set
-# CONFIG_SND_SOC_MA120X0P is not set
-# CONFIG_SND_SOC_MAX9759 is not set
-# CONFIG_SND_SOC_MAX98088 is not set
-# CONFIG_SND_SOC_MAX98357A is not set
-# CONFIG_SND_SOC_MAX98373 is not set
-# CONFIG_SND_SOC_MAX98373_I2C is not set
-# CONFIG_SND_SOC_MAX98390 is not set
-# CONFIG_SND_SOC_MAX98396 is not set
-# CONFIG_SND_SOC_MAX98504 is not set
-# CONFIG_SND_SOC_MAX98520 is not set
-# CONFIG_SND_SOC_MAX9860 is not set
-# CONFIG_SND_SOC_MAX9867 is not set
-# CONFIG_SND_SOC_MAX98927 is not set
-# CONFIG_SND_SOC_MEDIATEK is not set
-# CONFIG_SND_SOC_MPC5200_AC97 is not set
-# CONFIG_SND_SOC_MPC5200_I2S is not set
-# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set
-# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set
-# CONFIG_SND_SOC_MT2701 is not set
-# CONFIG_SND_SOC_MT6351 is not set
-# CONFIG_SND_SOC_MT6358 is not set
-# CONFIG_SND_SOC_MT6359 is not set
-# CONFIG_SND_SOC_MT6359_ACCDET is not set
-# CONFIG_SND_SOC_MT6660 is not set
-# CONFIG_SND_SOC_MT6797 is not set
-# CONFIG_SND_SOC_MT8173 is not set
-# CONFIG_SND_SOC_MT8183 is not set
-# CONFIG_SND_SOC_MT8186 is not set
-# CONFIG_SND_SOC_MT8192 is not set
-# CONFIG_SND_SOC_MT8195 is not set
-# CONFIG_SND_SOC_MTK_BTCVSD is not set
-# CONFIG_SND_SOC_NAU8315 is not set
-# CONFIG_SND_SOC_NAU8540 is not set
-# CONFIG_SND_SOC_NAU8810 is not set
-# CONFIG_SND_SOC_NAU8821 is not set
-# CONFIG_SND_SOC_NAU8822 is not set
-# CONFIG_SND_SOC_NAU8824 is not set
-# CONFIG_SND_SOC_PCM1681 is not set
-# CONFIG_SND_SOC_PCM1789_I2C is not set
-# CONFIG_SND_SOC_PCM1792A is not set
-# CONFIG_SND_SOC_PCM179X_I2C is not set
-# CONFIG_SND_SOC_PCM179X_SPI is not set
-# CONFIG_SND_SOC_PCM186X_I2C is not set
-# CONFIG_SND_SOC_PCM186X_SPI is not set
-# CONFIG_SND_SOC_PCM3060_I2C is not set
-# CONFIG_SND_SOC_PCM3060_SPI is not set
-# CONFIG_SND_SOC_PCM3168A_I2C is not set
-# CONFIG_SND_SOC_PCM3168A_SPI is not set
-# CONFIG_SND_SOC_PCM5102A is not set
-# CONFIG_SND_SOC_PCM512x_I2C is not set
-# CONFIG_SND_SOC_PCM512x_SPI is not set
-# CONFIG_SND_SOC_QCOM is not set
-# CONFIG_SND_SOC_RK3328 is not set
-# CONFIG_SND_SOC_RK817 is not set
-# CONFIG_SND_SOC_ROCKCHIP is not set
-# CONFIG_SND_SOC_RT5616 is not set
-# CONFIG_SND_SOC_RT5631 is not set
-# CONFIG_SND_SOC_RT5640 is not set
-# CONFIG_SND_SOC_RT5659 is not set
-# CONFIG_SND_SOC_RT5677_SPI is not set
-# CONFIG_SND_SOC_RT9120 is not set
-# CONFIG_SND_SOC_SGTL5000 is not set
-# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set
-# CONFIG_SND_SOC_SIMPLE_MUX is not set
-# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set
-# CONFIG_SND_SOC_SOF_TOPLEVEL is not set
-# CONFIG_SND_SOC_SPDIF is not set
-# CONFIG_SND_SOC_SRC4XXX_I2C is not set
-# CONFIG_SND_SOC_SSM2305 is not set
-# CONFIG_SND_SOC_SSM2518 is not set
-# CONFIG_SND_SOC_SSM2602_I2C is not set
-# CONFIG_SND_SOC_SSM2602_SPI is not set
-# CONFIG_SND_SOC_SSM4567 is not set
-# CONFIG_SND_SOC_STA32X is not set
-# CONFIG_SND_SOC_STA350 is not set
-# CONFIG_SND_SOC_STI_SAS is not set
-# CONFIG_SND_SOC_TAS2552 is not set
-# CONFIG_SND_SOC_TAS2562 is not set
-# CONFIG_SND_SOC_TAS2764 is not set
-# CONFIG_SND_SOC_TAS2770 is not set
-# CONFIG_SND_SOC_TAS2780 is not set
-# CONFIG_SND_SOC_TAS5086 is not set
-# CONFIG_SND_SOC_TAS571X is not set
-# CONFIG_SND_SOC_TAS5720 is not set
-# CONFIG_SND_SOC_TAS5805M is not set
-# CONFIG_SND_SOC_TAS6424 is not set
-# CONFIG_SND_SOC_TDA7419 is not set
-# CONFIG_SND_SOC_TFA9879 is not set
-# CONFIG_SND_SOC_TFA989X is not set
-# CONFIG_SND_SOC_TLV320ADC3XXX is not set
-# CONFIG_SND_SOC_TLV320ADCX140 is not set
-# CONFIG_SND_SOC_TLV320AIC23_I2C is not set
-# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
-# CONFIG_SND_SOC_TLV320AIC31XX is not set
-# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set
-# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set
-# CONFIG_SND_SOC_TLV320AIC3X is not set
-# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set
-# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set
-# CONFIG_SND_SOC_TPA6130A2 is not set
-# CONFIG_SND_SOC_TS3A227E is not set
-# CONFIG_SND_SOC_TSCS42XX is not set
-# CONFIG_SND_SOC_TSCS454 is not set
-# CONFIG_SND_SOC_UDA1334 is not set
-# CONFIG_SND_SOC_WM8510 is not set
-# CONFIG_SND_SOC_WM8523 is not set
-# CONFIG_SND_SOC_WM8524 is not set
-# CONFIG_SND_SOC_WM8580 is not set
-# CONFIG_SND_SOC_WM8711 is not set
-# CONFIG_SND_SOC_WM8728 is not set
-# CONFIG_SND_SOC_WM8731 is not set
-# CONFIG_SND_SOC_WM8731_I2C is not set
-# CONFIG_SND_SOC_WM8731_SPI is not set
-# CONFIG_SND_SOC_WM8737 is not set
-# CONFIG_SND_SOC_WM8741 is not set
-# CONFIG_SND_SOC_WM8750 is not set
-# CONFIG_SND_SOC_WM8753 is not set
-# CONFIG_SND_SOC_WM8770 is not set
-# CONFIG_SND_SOC_WM8776 is not set
-# CONFIG_SND_SOC_WM8782 is not set
-# CONFIG_SND_SOC_WM8804_I2C is not set
-# CONFIG_SND_SOC_WM8804_SPI is not set
-# CONFIG_SND_SOC_WM8903 is not set
-# CONFIG_SND_SOC_WM8904 is not set
-# CONFIG_SND_SOC_WM8940 is not set
-# CONFIG_SND_SOC_WM8960 is not set
-# CONFIG_SND_SOC_WM8962 is not set
-# CONFIG_SND_SOC_WM8974 is not set
-# CONFIG_SND_SOC_WM8978 is not set
-# CONFIG_SND_SOC_WM8985 is not set
-# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set
-# CONFIG_SND_SOC_XILINX_I2S is not set
-# CONFIG_SND_SOC_XILINX_SPDIF is not set
-# CONFIG_SND_SOC_XTFPGA_I2S is not set
-# CONFIG_SND_SOC_ZL38060 is not set
-# CONFIG_SND_SOC_ZX_AUD96P22 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_SPI is not set
-# CONFIG_SND_SSCAPE is not set
-# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI is not set
-# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set
-# CONFIG_SND_SUN4I_CODEC is not set
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_TEST_COMPONENT is not set
-# CONFIG_SND_TIMER is not set
-# CONFIG_SND_TRIDENT is not set
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_6FIRE is not set
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_USB_HIFACE is not set
-# CONFIG_SND_USB_POD is not set
-# CONFIG_SND_USB_PODHD is not set
-# CONFIG_SND_USB_TONEPORT is not set
-# CONFIG_SND_USB_UA101 is not set
-# CONFIG_SND_USB_US122L is not set
-# CONFIG_SND_USB_USX2Y is not set
-# CONFIG_SND_USB_VARIAX is not set
-# CONFIG_SND_VERBOSE_PRINTK is not set
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTIO is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_WAVEFRONT is not set
-CONFIG_SND_X86=y
-# CONFIG_SND_XEN_FRONTEND is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
-# CONFIG_SOCK_CGROUP_DATA is not set
-# CONFIG_SOC_AM33XX is not set
-# CONFIG_SOC_AM43XX is not set
-# CONFIG_SOC_BRCMSTB is not set
-# CONFIG_SOC_CAMERA is not set
-# CONFIG_SOC_DRA7XX is not set
-# CONFIG_SOC_HAS_OMAP2_SDRC is not set
-# CONFIG_SOC_OMAP5 is not set
-# CONFIG_SOC_TI is not set
-# CONFIG_SOFTLOCKUP_DETECTOR is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_SONYPI is not set
-# CONFIG_SONY_LAPTOP is not set
-# CONFIG_SOUND is not set
-# CONFIG_SOUNDWIRE is not set
-# CONFIG_SOUND_OSS_CORE is not set
-# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_SP5100_TCO is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-# CONFIG_SPARSE_IRQ is not set
-# CONFIG_SPARSE_RCU_POINTER is not set
-# CONFIG_SPEAKUP is not set
-# CONFIG_SPI is not set
-# CONFIG_SPINLOCK_TEST is not set
-# CONFIG_SPI_ALTERA is not set
-# CONFIG_SPI_AMD is not set
-# CONFIG_SPI_AU1550 is not set
-# CONFIG_SPI_AX88796C is not set
-# CONFIG_SPI_AXI_SPI_ENGINE is not set
-# CONFIG_SPI_BCM2835 is not set
-# CONFIG_SPI_BCM63XX_HSSPI is not set
-# CONFIG_SPI_BCM_QSPI is not set
-# CONFIG_SPI_BITBANG is not set
-# CONFIG_SPI_BUTTERFLY is not set
-# CONFIG_SPI_CADENCE is not set
-# CONFIG_SPI_CADENCE_QUADSPI is not set
-# CONFIG_SPI_CADENCE_XSPI is not set
-# CONFIG_SPI_DEBUG is not set
-# CONFIG_SPI_DESIGNWARE is not set
-# CONFIG_SPI_FSL_DSPI is not set
-# CONFIG_SPI_FSL_ESPI is not set
-# CONFIG_SPI_FSL_SPI is not set
-# CONFIG_SPI_GPIO is not set
-# CONFIG_SPI_GPIO_OLD is not set
-# CONFIG_SPI_IMG_SPFI is not set
-# CONFIG_SPI_LANTIQ_SSC is not set
-# CONFIG_SPI_LM70_LLP is not set
-# CONFIG_SPI_LOOPBACK_TEST is not set
-# CONFIG_SPI_MASTER is not set
-# CONFIG_SPI_MEM is not set
-# CONFIG_SPI_MICROCHIP_CORE is not set
-# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set
-# CONFIG_SPI_MPC52xx is not set
-# CONFIG_SPI_MPC52xx_PSC is not set
-# CONFIG_SPI_MTK_QUADSPI is not set
-# CONFIG_SPI_MUX is not set
-# CONFIG_SPI_MXIC is not set
-# CONFIG_SPI_NXP_FLEXSPI is not set
-# CONFIG_SPI_OCTEON is not set
-# CONFIG_SPI_OC_TINY is not set
-# CONFIG_SPI_ORION is not set
-# CONFIG_SPI_PL022 is not set
-# CONFIG_SPI_PPC4xx is not set
-# CONFIG_SPI_PXA2XX is not set
-# CONFIG_SPI_PXA2XX_PCI is not set
-# CONFIG_SPI_QCOM_QSPI is not set
-# CONFIG_SPI_ROCKCHIP is not set
-# CONFIG_SPI_S3C64XX is not set
-# CONFIG_SPI_SC18IS602 is not set
-# CONFIG_SPI_SIFIVE is not set
-# CONFIG_SPI_SLAVE is not set
-# CONFIG_SPI_SPIDEV is not set
-# CONFIG_SPI_THUNDERX is not set
-# CONFIG_SPI_TI_QSPI is not set
-# CONFIG_SPI_TLE62X0 is not set
-# CONFIG_SPI_TOPCLIFF_PCH is not set
-# CONFIG_SPI_XCOMM is not set
-# CONFIG_SPI_XILINX is not set
-# CONFIG_SPI_XWAY is not set
-# CONFIG_SPI_ZYNQMP_GQSPI is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_SPMI is not set
-# CONFIG_SPS30 is not set
-# CONFIG_SPS30_I2C is not set
-# CONFIG_SPS30_SERIAL is not set
-CONFIG_SQUASHFS=y
-# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
-# CONFIG_SQUASHFS_DECOMP_MULTI is not set
-CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
-# CONFIG_SQUASHFS_DECOMP_SINGLE is not set
-CONFIG_SQUASHFS_EMBEDDED=y
-# CONFIG_SQUASHFS_FILE_CACHE is not set
-CONFIG_SQUASHFS_FILE_DIRECT=y
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-# CONFIG_SQUASHFS_LZ4 is not set
-# CONFIG_SQUASHFS_LZO is not set
-# CONFIG_SQUASHFS_XATTR is not set
-CONFIG_SQUASHFS_XZ=y
-# CONFIG_SQUASHFS_ZLIB is not set
-# CONFIG_SQUASHFS_ZSTD is not set
-# CONFIG_SRAM is not set
-# CONFIG_SRF04 is not set
-# CONFIG_SRF08 is not set
-# CONFIG_SSB is not set
-# CONFIG_SSB_DEBUG is not set
-# CONFIG_SSB_DRIVER_GPIO is not set
-# CONFIG_SSB_HOST_SOC is not set
-# CONFIG_SSB_PCMCIAHOST is not set
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB_SDIOHOST is not set
-# CONFIG_SSB_SILENT is not set
-# CONFIG_SSFDC is not set
-# CONFIG_STACKPROTECTOR is not set
-# CONFIG_STACKPROTECTOR_PER_TASK is not set
-# CONFIG_STACKPROTECTOR_STRONG is not set
-# CONFIG_STACKTRACE is not set
-# CONFIG_STACKTRACE_BUILD_ID is not set
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_STACK_HASH_ORDER=20
-# CONFIG_STACK_TRACER is not set
-# CONFIG_STACK_VALIDATION is not set
-CONFIG_STAGING=y
-# CONFIG_STAGING_BOARD is not set
-# CONFIG_STAGING_GASKET_FRAMEWORK is not set
-# CONFIG_STAGING_MEDIA is not set
-CONFIG_STANDALONE=y
-# CONFIG_STATIC_KEYS_SELFTEST is not set
-# CONFIG_STATIC_USERMODEHELPER is not set
-CONFIG_STDBINUTILS=y
-# CONFIG_STE10XP is not set
-# CONFIG_STE_MODEM_RPROC is not set
-# CONFIG_STK3310 is not set
-# CONFIG_STK8312 is not set
-# CONFIG_STK8BA50 is not set
-# CONFIG_STM is not set
-# CONFIG_STMMAC_ETH is not set
-# CONFIG_STMMAC_PCI is not set
-# CONFIG_STMMAC_PLATFORM is not set
-# CONFIG_STMMAC_SELFTESTS is not set
-# CONFIG_STMPE_ADC is not set
-# CONFIG_STM_DUMMY is not set
-# CONFIG_STM_SOURCE_CONSOLE is not set
-CONFIG_STP=y
-# CONFIG_STREAM_PARSER is not set
-# CONFIG_STRICT_DEVMEM is not set
-CONFIG_STRICT_KERNEL_RWX=y
-CONFIG_STRICT_MODULE_RWX=y
-# CONFIG_STRING_SELFTEST is not set
-CONFIG_STRIP_ASM_SYMS=y
-# CONFIG_STX104 is not set
-# CONFIG_ST_UVIS25 is not set
-# CONFIG_SUN4I_GPADC is not set
-# CONFIG_SUN50I_DE2_BUS is not set
-# CONFIG_SUN50I_ERRATUM_UNKNOWN1 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_SUNRPC_DEBUG is not set
-CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y
-# CONFIG_SUNRPC_GSS is not set
-# CONFIG_SUNXI_SRAM is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_SURFACE_3_BUTTON is not set
-# CONFIG_SURFACE_PLATFORMS is not set
-# CONFIG_SUSPEND is not set
-# CONFIG_SUSPEND_SKIP_SYNC is not set
-CONFIG_SWAP=y
-# CONFIG_SWCONFIG is not set
-# CONFIG_SWCONFIG_B53 is not set
-# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set
-# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set
-# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set
-# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set
-# CONFIG_SWCONFIG_LEDS is not set
-# CONFIG_SW_SYNC is not set
-# CONFIG_SX9310 is not set
-# CONFIG_SX9324 is not set
-# CONFIG_SX9360 is not set
-# CONFIG_SX9500 is not set
-# CONFIG_SXGBE_ETH is not set
-CONFIG_SYMBOLIC_ERRNAME=y
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_SYNC_FILE is not set
-# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set
-# CONFIG_SYNTH_EVENTS is not set
-# CONFIG_SYNTH_EVENT_GEN_TEST is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_SYSCON_REBOOT_MODE is not set
-CONFIG_SYSCTL=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_SYSFS=y
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_SYSFS_DEPRECATED_V2 is not set
-# CONFIG_SYSFS_SYSCALL is not set
-# CONFIG_SYSTEMPORT is not set
-# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
-# CONFIG_SYSTEM_DATA_VERIFICATION is not set
-# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
-CONFIG_SYSTEM_TRUSTED_KEYS=""
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_T5403 is not set
-# CONFIG_TARGET_CORE is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_TASKS_RCU is not set
-# CONFIG_TASK_XACCT is not set
-# CONFIG_TC35815 is not set
-# CONFIG_TCG_ATMEL is not set
-# CONFIG_TCG_CRB is not set
-# CONFIG_TCG_FTPM_TEE is not set
-# CONFIG_TCG_INFINEON is not set
-# CONFIG_TCG_NSC is not set
-# CONFIG_TCG_ST33_I2C is not set
-# CONFIG_TCG_TIS is not set
-# CONFIG_TCG_TIS_I2C is not set
-# CONFIG_TCG_TIS_I2C_ATMEL is not set
-# CONFIG_TCG_TIS_I2C_CR50 is not set
-# CONFIG_TCG_TIS_I2C_INFINEON is not set
-# CONFIG_TCG_TIS_I2C_NUVOTON is not set
-# CONFIG_TCG_TIS_SPI is not set
-# CONFIG_TCG_TIS_ST33ZP24_I2C is not set
-# CONFIG_TCG_TIS_ST33ZP24_SPI is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_TCG_VTPM_PROXY is not set
-# CONFIG_TCG_XEN is not set
-# CONFIG_TCIC is not set
-CONFIG_TCP_CONG_ADVANCED=y
-# CONFIG_TCP_CONG_BBR is not set
-# CONFIG_TCP_CONG_BIC is not set
-# CONFIG_TCP_CONG_CDG is not set
-CONFIG_TCP_CONG_CUBIC=y
-# CONFIG_TCP_CONG_DCTCP is not set
-# CONFIG_TCP_CONG_HSTCP is not set
-# CONFIG_TCP_CONG_HTCP is not set
-# CONFIG_TCP_CONG_HYBLA is not set
-# CONFIG_TCP_CONG_ILLINOIS is not set
-# CONFIG_TCP_CONG_LP is not set
-# CONFIG_TCP_CONG_NV is not set
-# CONFIG_TCP_CONG_SCALABLE is not set
-# CONFIG_TCP_CONG_VEGAS is not set
-# CONFIG_TCP_CONG_VENO is not set
-# CONFIG_TCP_CONG_WESTWOOD is not set
-# CONFIG_TCP_CONG_YEAH is not set
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_TCS3414 is not set
-# CONFIG_TCS3472 is not set
-# CONFIG_TEE is not set
-# CONFIG_TEGRA210_ADMA is not set
-# CONFIG_TEGRA_ACONNECT is not set
-# CONFIG_TEGRA_AHB is not set
-# CONFIG_TEGRA_HOST1X is not set
-# CONFIG_TEHUTI is not set
-# CONFIG_TERANETICS_PHY is not set
-# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
-# CONFIG_TEST_BITFIELD is not set
-# CONFIG_TEST_BITMAP is not set
-# CONFIG_TEST_BITOPS is not set
-# CONFIG_TEST_BLACKHOLE_DEV is not set
-# CONFIG_TEST_BPF is not set
-# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set
-# CONFIG_TEST_DEBUG_VIRTUAL is not set
-# CONFIG_TEST_DIV64 is not set
-# CONFIG_TEST_DYNAMIC_DEBUG is not set
-# CONFIG_TEST_FIRMWARE is not set
-# CONFIG_TEST_FREE_PAGES is not set
-# CONFIG_TEST_HASH is not set
-# CONFIG_TEST_HEXDUMP is not set
-# CONFIG_TEST_IDA is not set
-# CONFIG_TEST_KASAN_MODULE is not set
-# CONFIG_TEST_KMOD is not set
-# CONFIG_TEST_KSTRTOX is not set
-# CONFIG_TEST_LIST_SORT is not set
-# CONFIG_TEST_LKM is not set
-# CONFIG_TEST_LOCKUP is not set
-# CONFIG_TEST_MAPLE_TREE is not set
-# CONFIG_TEST_MEMCAT_P is not set
-# CONFIG_TEST_MEMINIT is not set
-# CONFIG_TEST_MIN_HEAP is not set
-# CONFIG_TEST_OVERFLOW is not set
-# CONFIG_TEST_POWER is not set
-# CONFIG_TEST_PRINTF is not set
-# CONFIG_TEST_REF_TRACKER is not set
-# CONFIG_TEST_RHASHTABLE is not set
-# CONFIG_TEST_SCANF is not set
-# CONFIG_TEST_SIPHASH is not set
-# CONFIG_TEST_SORT is not set
-# CONFIG_TEST_STACKINIT is not set
-# CONFIG_TEST_STATIC_KEYS is not set
-# CONFIG_TEST_STRING_HELPERS is not set
-# CONFIG_TEST_STRSCPY is not set
-# CONFIG_TEST_SYSCTL is not set
-# CONFIG_TEST_UBSAN is not set
-# CONFIG_TEST_UDELAY is not set
-# CONFIG_TEST_USER_COPY is not set
-# CONFIG_TEST_UUID is not set
-# CONFIG_TEST_VMALLOC is not set
-# CONFIG_TEST_XARRAY is not set
-CONFIG_TEXTSEARCH=y
-# CONFIG_TEXTSEARCH_BM is not set
-# CONFIG_TEXTSEARCH_FSM is not set
-# CONFIG_TEXTSEARCH_KMP is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
-# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set
-# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
-# CONFIG_THERMAL_EMULATION is not set
-# CONFIG_THERMAL_GOV_BANG_BANG is not set
-# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
-# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set
-# CONFIG_THERMAL_GOV_USER_SPACE is not set
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_THERMAL_MMIO is not set
-# CONFIG_THERMAL_NETLINK is not set
-# CONFIG_THERMAL_STATISTICS is not set
-# CONFIG_THERMAL_WRITABLE_TRIPS is not set
-# CONFIG_THINKPAD_ACPI is not set
-CONFIG_THIN_ARCHIVES=y
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_THUMB2_KERNEL is not set
-# CONFIG_THUNDERBOLT is not set
-# CONFIG_THUNDER_NIC_BGX is not set
-# CONFIG_THUNDER_NIC_PF is not set
-# CONFIG_THUNDER_NIC_RGX is not set
-# CONFIG_THUNDER_NIC_VF is not set
-# CONFIG_TICK_CPU_ACCOUNTING is not set
-CONFIG_TICK_ONESHOT=y
-# CONFIG_TIFM_CORE is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_TIMB_DMA is not set
-CONFIG_TIMERFD=y
-# CONFIG_TIMERLAT_TRACER is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_TIME_NS is not set
-# CONFIG_TINYDRM_HX8357D is not set
-# CONFIG_TINYDRM_ILI9163 is not set
-# CONFIG_TINYDRM_ILI9225 is not set
-# CONFIG_TINYDRM_ILI9341 is not set
-# CONFIG_TINYDRM_ILI9486 is not set
-# CONFIG_TINYDRM_MI0283QT is not set
-# CONFIG_TINYDRM_REPAPER is not set
-# CONFIG_TINYDRM_ST7586 is not set
-# CONFIG_TINYDRM_ST7735R is not set
-CONFIG_TINY_RCU=y
-# CONFIG_TIPC is not set
-# CONFIG_TI_ADC081C is not set
-# CONFIG_TI_ADC0832 is not set
-# CONFIG_TI_ADC084S021 is not set
-# CONFIG_TI_ADC108S102 is not set
-# CONFIG_TI_ADC12138 is not set
-# CONFIG_TI_ADC128S052 is not set
-# CONFIG_TI_ADC161S626 is not set
-# CONFIG_TI_ADS1015 is not set
-# CONFIG_TI_ADS124S08 is not set
-# CONFIG_TI_ADS131E08 is not set
-# CONFIG_TI_ADS7950 is not set
-# CONFIG_TI_ADS8344 is not set
-# CONFIG_TI_ADS8688 is not set
-# CONFIG_TI_AM335X_ADC is not set
-# CONFIG_TI_CPSW is not set
-# CONFIG_TI_CPSW_ALE is not set
-# CONFIG_TI_CPSW_PHY_SEL is not set
-# CONFIG_TI_CPTS is not set
-# CONFIG_TI_DAC082S085 is not set
-# CONFIG_TI_DAC5571 is not set
-# CONFIG_TI_DAC7311 is not set
-# CONFIG_TI_DAC7512 is not set
-# CONFIG_TI_DAC7612 is not set
-# CONFIG_TI_DAVINCI_CPDMA is not set
-# CONFIG_TI_DAVINCI_MDIO is not set
-# CONFIG_TI_ST is not set
-# CONFIG_TI_SYSCON_RESET is not set
-# CONFIG_TI_TLC4541 is not set
-# CONFIG_TI_TSC2046 is not set
-# CONFIG_TLAN is not set
-# CONFIG_TLS is not set
-# CONFIG_TLS_DEVICE is not set
-# CONFIG_TLS_TOE is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_TMP006 is not set
-# CONFIG_TMP007 is not set
-# CONFIG_TMP117 is not set
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_INODE64 is not set
-# CONFIG_TMPFS_POSIX_ACL is not set
-CONFIG_TMPFS_XATTR=y
-# CONFIG_TOPSTAR_LAPTOP is not set
-# CONFIG_TORTURE_TEST is not set
-# CONFIG_TOSHIBA_HAPS is not set
-# CONFIG_TOUCHSCREEN_88PM860X is not set
-# CONFIG_TOUCHSCREEN_AD7877 is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
-# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
-# CONFIG_TOUCHSCREEN_ADC is not set
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
-# CONFIG_TOUCHSCREEN_AR1021_I2C is not set
-# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
-# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set
-# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
-# CONFIG_TOUCHSCREEN_BU21013 is not set
-# CONFIG_TOUCHSCREEN_BU21029 is not set
-# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set
-# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set
-# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
-# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
-# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set
-# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set
-# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
-# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set
-# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set
-# CONFIG_TOUCHSCREEN_DA9034 is not set
-# CONFIG_TOUCHSCREEN_DA9052 is not set
-# CONFIG_TOUCHSCREEN_DYNAPRO is not set
-# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
-# CONFIG_TOUCHSCREEN_EETI is not set
-# CONFIG_TOUCHSCREEN_EGALAX is not set
-# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set
-# CONFIG_TOUCHSCREEN_EKTF2127 is not set
-# CONFIG_TOUCHSCREEN_ELAN is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_EXC3000 is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GOODIX is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
-# CONFIG_TOUCHSCREEN_HIDEEP is not set
-# CONFIG_TOUCHSCREEN_HP600 is not set
-# CONFIG_TOUCHSCREEN_HP7XX is not set
-# CONFIG_TOUCHSCREEN_HTCPEN is not set
-# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set
-# CONFIG_TOUCHSCREEN_ILI210X is not set
-# CONFIG_TOUCHSCREEN_ILITEK is not set
-# CONFIG_TOUCHSCREEN_IMAGIS is not set
-# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set
-# CONFIG_TOUCHSCREEN_IPROC is not set
-# CONFIG_TOUCHSCREEN_IQS5XX is not set
-# CONFIG_TOUCHSCREEN_LPC32XX is not set
-# CONFIG_TOUCHSCREEN_MAX11801 is not set
-# CONFIG_TOUCHSCREEN_MC13783 is not set
-# CONFIG_TOUCHSCREEN_MCS5000 is not set
-# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set
-# CONFIG_TOUCHSCREEN_MIGOR is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_MMS114 is not set
-# CONFIG_TOUCHSCREEN_MSG2638 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_MX25 is not set
-# CONFIG_TOUCHSCREEN_MXS_LRADC is not set
-# CONFIG_TOUCHSCREEN_PCAP is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_PIXCIR is not set
-# CONFIG_TOUCHSCREEN_PROPERTIES is not set
-# CONFIG_TOUCHSCREEN_RASPBERRYPI_FW is not set
-# CONFIG_TOUCHSCREEN_RM_TS is not set
-# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
-# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set
-# CONFIG_TOUCHSCREEN_S3C2410 is not set
-# CONFIG_TOUCHSCREEN_S6SY761 is not set
-# CONFIG_TOUCHSCREEN_SILEAD is not set
-# CONFIG_TOUCHSCREEN_SIS_I2C is not set
-# CONFIG_TOUCHSCREEN_ST1232 is not set
-# CONFIG_TOUCHSCREEN_STMFTS is not set
-# CONFIG_TOUCHSCREEN_STMPE is not set
-# CONFIG_TOUCHSCREEN_SUN4I is not set
-# CONFIG_TOUCHSCREEN_SUR40 is not set
-# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set
-# CONFIG_TOUCHSCREEN_SX8654 is not set
-# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_TPS6507X is not set
-# CONFIG_TOUCHSCREEN_TS4800 is not set
-# CONFIG_TOUCHSCREEN_TSC2004 is not set
-# CONFIG_TOUCHSCREEN_TSC2005 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set
-# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set
-# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
-# CONFIG_TOUCHSCREEN_USB_3M is not set
-# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
-# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set
-# CONFIG_TOUCHSCREEN_USB_E2I is not set
-# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set
-# CONFIG_TOUCHSCREEN_USB_EGALAX is not set
-# CONFIG_TOUCHSCREEN_USB_ELO is not set
-# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set
-# CONFIG_TOUCHSCREEN_USB_ETURBO is not set
-# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set
-# CONFIG_TOUCHSCREEN_USB_GOTOP is not set
-# CONFIG_TOUCHSCREEN_USB_GUNZE is not set
-# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set
-# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set
-# CONFIG_TOUCHSCREEN_USB_ITM is not set
-# CONFIG_TOUCHSCREEN_USB_JASTEC is not set
-# CONFIG_TOUCHSCREEN_USB_NEXIO is not set
-# CONFIG_TOUCHSCREEN_USB_PANJIT is not set
-# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set
-# CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set
-# CONFIG_TOUCHSCREEN_WM831X is not set
-# CONFIG_TOUCHSCREEN_WM9705 is not set
-# CONFIG_TOUCHSCREEN_WM9712 is not set
-# CONFIG_TOUCHSCREEN_WM9713 is not set
-# CONFIG_TOUCHSCREEN_WM97XX is not set
-# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
-# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set
-# CONFIG_TOUCHSCREEN_ZET6223 is not set
-# CONFIG_TOUCHSCREEN_ZFORCE is not set
-# CONFIG_TOUCHSCREEN_ZINITIX is not set
-# CONFIG_TPL0102 is not set
-# CONFIG_TPS6105X is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-# CONFIG_TRACEPOINT_BENCHMARK is not set
-# CONFIG_TRACER_SNAPSHOT is not set
-# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_TRACE_EVAL_MAP_FILE is not set
-# CONFIG_TRACE_EVENT_INJECT is not set
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_TRACE_MMIO_ACCESS is not set
-# CONFIG_TRACE_SINK is not set
-# CONFIG_TRACING_EVENTS_GPIO is not set
-CONFIG_TRACING_SUPPORT=y
-CONFIG_TRAD_SIGNALS=y
-# CONFIG_TRANSPARENT_HUGEPAGE is not set
-# CONFIG_TREE_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_TRIM_UNUSED_KSYMS is not set
-# CONFIG_TRUSTED_FOUNDATIONS is not set
-# CONFIG_TRUSTED_KEYS is not set
-# CONFIG_TRUSTED_KEYS_CAAM is not set
-# CONFIG_TRUSTED_KEYS_TEE is not set
-# CONFIG_TRUSTED_KEYS_TPM is not set
-# CONFIG_TSL2583 is not set
-# CONFIG_TSL2591 is not set
-# CONFIG_TSL2772 is not set
-# CONFIG_TSL2x7x is not set
-# CONFIG_TSL4531 is not set
-# CONFIG_TSNEP is not set
-# CONFIG_TSYS01 is not set
-# CONFIG_TSYS02D is not set
-# CONFIG_TTPCI_EEPROM is not set
-CONFIG_TTY=y
-# CONFIG_TTY_PRINTK is not set
-# CONFIG_TUN is not set
-# CONFIG_TUN_VNET_CROSS_LE is not set
-# CONFIG_TWL4030_CORE is not set
-# CONFIG_TWL4030_MADC is not set
-# CONFIG_TWL6030_GPADC is not set
-# CONFIG_TWL6040_CORE is not set
-# CONFIG_TXGBE is not set
-# CONFIG_TYPEC is not set
-# CONFIG_TYPEC_DP_ALTMODE is not set
-# CONFIG_TYPEC_TCPM is not set
-# CONFIG_TYPEC_UCSI is not set
-# CONFIG_TYPHOON is not set
-# CONFIG_UACCESS_WITH_MEMCPY is not set
-# CONFIG_UBIFS_ATIME_SUPPORT is not set
-# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
-# CONFIG_UBIFS_FS_AUTHENTICATION is not set
-# CONFIG_UBIFS_FS_ENCRYPTION is not set
-CONFIG_UBIFS_FS_LZO=y
-# CONFIG_UBIFS_FS_SECURITY is not set
-CONFIG_UBIFS_FS_XATTR=y
-CONFIG_UBIFS_FS_ZLIB=y
-CONFIG_UBIFS_FS_ZSTD=y
-# CONFIG_UBSAN is not set
-CONFIG_UBSAN_ALIGNMENT=y
-CONFIG_UBSAN_BOOL=y
-# CONFIG_UBSAN_DIV_ZERO is not set
-CONFIG_UBSAN_ENUM=y
-# CONFIG_UBSAN_MISC is not set
-CONFIG_UBSAN_SHIFT=y
-# CONFIG_UBSAN_UNREACHABLE is not set
-# CONFIG_UCB1400_CORE is not set
-# CONFIG_UCSI is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDMABUF is not set
-CONFIG_UEVENT_HELPER=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_UFS_FS is not set
-# CONFIG_UHID is not set
-CONFIG_UID16=y
-# CONFIG_UIMAGE_FIT_BLK is not set
-# CONFIG_UIO is not set
-# CONFIG_ULTRA is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_UNICODE is not set
-# CONFIG_UNISYSSPAR is not set
-# CONFIG_UNISYS_VISORBUS is not set
-CONFIG_UNIX=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_UNIX_DIAG is not set
-CONFIG_UNIX_SCM=y
-# CONFIG_UNUSED_BOARD_FILES is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_UNWINDER_FRAME_POINTER is not set
-# CONFIG_UPROBES is not set
-# CONFIG_UPROBE_EVENTS is not set
-# CONFIG_US5182D is not set
-# CONFIG_USB is not set
-# CONFIG_USB4 is not set
-# CONFIG_USBIP_CORE is not set
-CONFIG_USBIP_VHCI_HC_PORTS=8
-CONFIG_USBIP_VHCI_NR_HCS=1
-# CONFIG_USBIP_VUDC is not set
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AIRSPY is not set
-CONFIG_USB_ALI_M5632=y
-# CONFIG_USB_AMD5536UDC is not set
-CONFIG_USB_AN2720=y
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARMLINUX=y
-# CONFIG_USB_ATM is not set
-# CONFIG_USB_AUDIO is not set
-CONFIG_USB_AUTOSUSPEND_DELAY=2
-# CONFIG_USB_BDC_UDC is not set
-CONFIG_USB_BELKIN=y
-# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_USB_CDNS3 is not set
-# CONFIG_USB_CDNS3_IMX is not set
-# CONFIG_USB_CDNS3_PCI_WRAP is not set
-# CONFIG_USB_CDNSP_PCI is not set
-# CONFIG_USB_CDNS_SUPPORT is not set
-# CONFIG_USB_CHAOSKEY is not set
-# CONFIG_USB_CHIPIDEA is not set
-# CONFIG_USB_CHIPIDEA_GENERIC is not set
-# CONFIG_USB_CHIPIDEA_IMX is not set
-# CONFIG_USB_CHIPIDEA_MSM is not set
-# CONFIG_USB_CHIPIDEA_PCI is not set
-# CONFIG_USB_CHIPIDEA_TEGRA is not set
-# CONFIG_USB_CONFIGFS is not set
-# CONFIG_USB_CONN_GPIO is not set
-# CONFIG_USB_CXACRU is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-CONFIG_USB_DEFAULT_PERSIST=y
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DUMMY_HCD is not set
-# CONFIG_USB_DWC2 is not set
-# CONFIG_USB_DWC2_DEBUG is not set
-# CONFIG_USB_DWC2_DUAL_ROLE is not set
-# CONFIG_USB_DWC2_HOST is not set
-# CONFIG_USB_DWC2_PERIPHERAL is not set
-# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set
-# CONFIG_USB_DWC3 is not set
-# CONFIG_USB_DWC3_EXYNOS is not set
-# CONFIG_USB_DWC3_HAPS is not set
-# CONFIG_USB_DWC3_KEYSTONE is not set
-# CONFIG_USB_DWC3_OF_SIMPLE is not set
-# CONFIG_USB_DWC3_PCI is not set
-# CONFIG_USB_DWC3_QCOM is not set
-# CONFIG_USB_DWC3_ULPI is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_EG20T is not set
-# CONFIG_USB_EHCI_ATH79 is not set
-# CONFIG_USB_EHCI_FSL is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_EHCI_HCD_AT91 is not set
-# CONFIG_USB_EHCI_HCD_OMAP is not set
-# CONFIG_USB_EHCI_HCD_PPC_OF is not set
-# CONFIG_USB_EHCI_MSM is not set
-# CONFIG_USB_EHCI_MV is not set
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-# CONFIG_USB_EHSET_TEST_FIXTURE is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EPSON2888 is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_EZUSB_FX2 is not set
-# CONFIG_USB_FEW_INIT_RETRIES is not set
-# CONFIG_USB_FOTG210_HCD is not set
-# CONFIG_USB_FOTG210_UDC is not set
-# CONFIG_USB_FSL_USB2 is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_FUNCTIONFS is not set
-# CONFIG_USB_FUSB300 is not set
-# CONFIG_USB_GADGET is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_GADGET_DEBUG is not set
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_DEBUG_FS is not set
-CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
-CONFIG_USB_GADGET_VBUS_DRAW=2
-# CONFIG_USB_GADGET_XILINX is not set
-# CONFIG_USB_GL860 is not set
-# CONFIG_USB_GOKU is not set
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_USB_GR_UDC is not set
-# CONFIG_USB_GSPCA is not set
-# CONFIG_USB_GSPCA_BENQ is not set
-# CONFIG_USB_GSPCA_CONEX is not set
-# CONFIG_USB_GSPCA_CPIA1 is not set
-# CONFIG_USB_GSPCA_DTCS033 is not set
-# CONFIG_USB_GSPCA_ETOMS is not set
-# CONFIG_USB_GSPCA_FINEPIX is not set
-# CONFIG_USB_GSPCA_JEILINJ is not set
-# CONFIG_USB_GSPCA_JL2005BCD is not set
-# CONFIG_USB_GSPCA_KINECT is not set
-# CONFIG_USB_GSPCA_KONICA is not set
-# CONFIG_USB_GSPCA_MARS is not set
-# CONFIG_USB_GSPCA_MR97310A is not set
-# CONFIG_USB_GSPCA_NW80X is not set
-# CONFIG_USB_GSPCA_OV519 is not set
-# CONFIG_USB_GSPCA_OV534 is not set
-# CONFIG_USB_GSPCA_OV534_9 is not set
-# CONFIG_USB_GSPCA_PAC207 is not set
-# CONFIG_USB_GSPCA_PAC7302 is not set
-# CONFIG_USB_GSPCA_PAC7311 is not set
-# CONFIG_USB_GSPCA_SE401 is not set
-# CONFIG_USB_GSPCA_SN9C2028 is not set
-# CONFIG_USB_GSPCA_SN9C20X is not set
-# CONFIG_USB_GSPCA_SONIXB is not set
-# CONFIG_USB_GSPCA_SONIXJ is not set
-# CONFIG_USB_GSPCA_SPCA1528 is not set
-# CONFIG_USB_GSPCA_SPCA500 is not set
-# CONFIG_USB_GSPCA_SPCA501 is not set
-# CONFIG_USB_GSPCA_SPCA505 is not set
-# CONFIG_USB_GSPCA_SPCA506 is not set
-# CONFIG_USB_GSPCA_SPCA508 is not set
-# CONFIG_USB_GSPCA_SPCA561 is not set
-# CONFIG_USB_GSPCA_SQ905 is not set
-# CONFIG_USB_GSPCA_SQ905C is not set
-# CONFIG_USB_GSPCA_SQ930X is not set
-# CONFIG_USB_GSPCA_STK014 is not set
-# CONFIG_USB_GSPCA_STK1135 is not set
-# CONFIG_USB_GSPCA_STV0680 is not set
-# CONFIG_USB_GSPCA_SUNPLUS is not set
-# CONFIG_USB_GSPCA_T613 is not set
-# CONFIG_USB_GSPCA_TOPRO is not set
-# CONFIG_USB_GSPCA_TOUPTEK is not set
-# CONFIG_USB_GSPCA_TV8532 is not set
-# CONFIG_USB_GSPCA_VC032X is not set
-# CONFIG_USB_GSPCA_VICAM is not set
-# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
-# CONFIG_USB_GSPCA_ZC3XX is not set
-# CONFIG_USB_G_ACM_MS is not set
-# CONFIG_USB_G_DBGP is not set
-# CONFIG_USB_G_HID is not set
-# CONFIG_USB_G_MULTI is not set
-# CONFIG_USB_G_NCM is not set
-# CONFIG_USB_G_NOKIA is not set
-# CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_G_WEBCAM is not set
-# CONFIG_USB_HACKRF is not set
-# CONFIG_USB_HCD_TEST_MODE is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_HSIC_USB3503 is not set
-# CONFIG_USB_HSIC_USB4604 is not set
-# CONFIG_USB_HSO is not set
-# CONFIG_USB_HUB_USB251XB is not set
-# CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_IMX21_HCD is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_IPHETH is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1301 is not set
-# CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_ISP1760 is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_KC2190 is not set
-# CONFIG_USB_LAN78XX is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set
-# CONFIG_USB_LED_TRIG is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LGM_PHY is not set
-# CONFIG_USB_LINK_LAYER_TEST is not set
-# CONFIG_USB_M5602 is not set
-# CONFIG_USB_M66592 is not set
-# CONFIG_USB_MASS_STORAGE is not set
-# CONFIG_USB_MAX3420_UDC is not set
-# CONFIG_USB_MAX3421_HCD is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_USB_MON is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_MSI2500 is not set
-# CONFIG_USB_MSM_OTG is not set
-# CONFIG_USB_MTU3 is not set
-# CONFIG_USB_MUSB_GADGET is not set
-# CONFIG_USB_MUSB_HDRC is not set
-# CONFIG_USB_MUSB_HOST is not set
-# CONFIG_USB_MV_U3D is not set
-# CONFIG_USB_MV_UDC is not set
-# CONFIG_USB_MXS_PHY is not set
-# CONFIG_USB_NET2272 is not set
-# CONFIG_USB_NET2280 is not set
-# CONFIG_USB_NET_AQC111 is not set
-# CONFIG_USB_NET_AX88179_178A is not set
-# CONFIG_USB_NET_AX8817X is not set
-# CONFIG_USB_NET_CDCETHER is not set
-# CONFIG_USB_NET_CDC_EEM is not set
-# CONFIG_USB_NET_CDC_MBIM is not set
-# CONFIG_USB_NET_CDC_NCM is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-# CONFIG_USB_NET_CH9200 is not set
-# CONFIG_USB_NET_CX82310_ETH is not set
-# CONFIG_USB_NET_DM9601 is not set
-# CONFIG_USB_NET_DRIVERS is not set
-# CONFIG_USB_NET_GL620A is not set
-# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
-# CONFIG_USB_NET_INT51X1 is not set
-# CONFIG_USB_NET_KALMIA is not set
-# CONFIG_USB_NET_MCS7830 is not set
-# CONFIG_USB_NET_NET1080 is not set
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_QMI_WWAN is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_USB_NET_SMSC75XX is not set
-# CONFIG_USB_NET_SMSC95XX is not set
-# CONFIG_USB_NET_SR9700 is not set
-# CONFIG_USB_NET_SR9800 is not set
-# CONFIG_USB_NET_ZAURUS is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_OHCI_HCD_PCI is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
-# CONFIG_USB_OHCI_HCD_SSB is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_ONBOARD_HUB is not set
-# CONFIG_USB_OTG is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set
-# CONFIG_USB_OTG_FSM is not set
-# CONFIG_USB_OTG_PRODUCTLIST is not set
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_PCI is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_PHY is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_PWC_INPUT_EVDEV is not set
-# CONFIG_USB_PXA27X is not set
-# CONFIG_USB_QCOM_EUD is not set
-# CONFIG_USB_R8A66597 is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_RAW_GADGET is not set
-# CONFIG_USB_RCAR_PHY is not set
-# CONFIG_USB_RENESAS_USBHS is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ROLES_INTEL_XHCI is not set
-# CONFIG_USB_ROLE_SWITCH is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_RTL8152 is not set
-# CONFIG_USB_RTL8153_ECM is not set
-# CONFIG_USB_S2255 is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_ARK3116 is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_CH341 is not set
-# CONFIG_USB_SERIAL_CP210X is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
-# CONFIG_USB_SERIAL_DEBUG is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_F81232 is not set
-# CONFIG_USB_SERIAL_F8153X is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_GARMIN is not set
-CONFIG_USB_SERIAL_GENERIC=y
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IPW is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_IUU is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-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_KLSI is not set
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_METRO is not set
-# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set
-# CONFIG_USB_SERIAL_MOS7720 is not set
-# CONFIG_USB_SERIAL_MOS7840 is not set
-# CONFIG_USB_SERIAL_MXUPORT is not set
-# CONFIG_USB_SERIAL_NAVMAN is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_SERIAL_OPTICON is not set
-# CONFIG_USB_SERIAL_OPTION is not set
-# CONFIG_USB_SERIAL_OTI6858 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_QCAUX is not set
-# CONFIG_USB_SERIAL_QT2 is not set
-# CONFIG_USB_SERIAL_QUALCOMM is not set
-# CONFIG_USB_SERIAL_SAFE is not set
-CONFIG_USB_SERIAL_SAFE_PADDED=y
-# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
-# CONFIG_USB_SERIAL_SIMPLE is not set
-# CONFIG_USB_SERIAL_SPCP8X5 is not set
-# CONFIG_USB_SERIAL_SSU100 is not set
-# CONFIG_USB_SERIAL_SYMBOL is not set
-# CONFIG_USB_SERIAL_TI is not set
-# CONFIG_USB_SERIAL_UPD78F0730 is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_WISHBONE is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_XR is not set
-# CONFIG_USB_SERIAL_XSENS_MT is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_SIERRA_NET is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_SNP_UDC_PLAT is not set
-# CONFIG_USB_SPEEDTOUCH is not set
-# CONFIG_USB_STKWEBCAM is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_ENE_UB6250 is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_REALTEK is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STV06XX is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_USB_SWITCH_FSA9480 is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_TMC is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_UAS is not set
-# CONFIG_USB_UEAGLEATM is not set
-# CONFIG_USB_ULPI is not set
-# CONFIG_USB_ULPI_BUS is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-# CONFIG_USB_VIDEO_CLASS is not set
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-# CONFIG_USB_VL600 is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-# CONFIG_USB_XEN_HCD is not set
-# CONFIG_USB_XHCI_DBGCAP is not set
-# CONFIG_USB_XHCI_HCD is not set
-# CONFIG_USB_XHCI_MVEBU is not set
-# CONFIG_USB_XHCI_PCI_RENESAS is not set
-# CONFIG_USB_XUSBATM is not set
-# CONFIG_USB_YUREX is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_ZERO is not set
-# CONFIG_USB_ZR364XX is not set
-# CONFIG_USELIB is not set
-# CONFIG_USERFAULTFD is not set
-# CONFIG_USERIO is not set
-# CONFIG_USER_DECRYPTED_DATA is not set
-# CONFIG_USE_OF is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_UWB is not set
-# CONFIG_U_SERIAL_CONSOLE is not set
-# CONFIG_V4L_MEM2MEM_DRIVERS is not set
-# CONFIG_V4L_PLATFORM_DRIVERS is not set
-# CONFIG_V4L_TEST_DRIVERS is not set
-# CONFIG_VALIDATE_FS_PARSER is not set
-# CONFIG_VBOXGUEST is not set
-# CONFIG_VCNL3020 is not set
-# CONFIG_VCNL4000 is not set
-# CONFIG_VCNL4035 is not set
-# CONFIG_VCPU_STALL_DETECTOR is not set
-# CONFIG_VDPA is not set
-CONFIG_VDSO=y
-# CONFIG_VEML6030 is not set
-# CONFIG_VEML6070 is not set
-# CONFIG_VETH is not set
-# CONFIG_VEXPRESS_CONFIG is not set
-# CONFIG_VF610_ADC is not set
-# CONFIG_VF610_DAC is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_VFIO is not set
-# CONFIG_VFIO_FSL_MC is not set
-# CONFIG_VFIO_PLATFORM is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VGA_ARB is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_VGA_SWITCHEROO is not set
-# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set
-CONFIG_VHOST_MENU=y
-# CONFIG_VHOST_NET is not set
-# CONFIG_VHOST_VSOCK is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_VIDEO_AD5398 is not set
-# CONFIG_VIDEO_AD5820 is not set
-# CONFIG_VIDEO_AD9389B is not set
-# CONFIG_VIDEO_ADP1653 is not set
-# CONFIG_VIDEO_ADV7170 is not set
-# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_ADV7180 is not set
-# CONFIG_VIDEO_ADV7183 is not set
-# CONFIG_VIDEO_ADV7343 is not set
-# CONFIG_VIDEO_ADV7393 is not set
-# CONFIG_VIDEO_ADV748X is not set
-# CONFIG_VIDEO_ADV7511 is not set
-# CONFIG_VIDEO_ADV7604 is not set
-# CONFIG_VIDEO_ADV7842 is not set
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_AK7375 is not set
-# CONFIG_VIDEO_AK881X is not set
-# CONFIG_VIDEO_AM437X_VPFE is not set
-# CONFIG_VIDEO_AR0521 is not set
-# CONFIG_VIDEO_ARDUCAM_64MP is not set
-# CONFIG_VIDEO_ARDUCAM_PIVARIETY is not set
-# CONFIG_VIDEO_ASPEED is not set
-# CONFIG_VIDEO_ATMEL_ISC is not set
-# CONFIG_VIDEO_ATMEL_ISI is not set
-# CONFIG_VIDEO_AU0828 is not set
-# CONFIG_VIDEO_BCM2835 is not set
-# CONFIG_VIDEO_BCM2835_UNICAM is not set
-# CONFIG_VIDEO_BT819 is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_BT856 is not set
-# CONFIG_VIDEO_BT866 is not set
-# CONFIG_VIDEO_BU64754 is not set
-# CONFIG_VIDEO_CADENCE is not set
-# CONFIG_VIDEO_CADENCE_CSI2RX is not set
-# CONFIG_VIDEO_CADENCE_CSI2TX is not set
-# CONFIG_VIDEO_CAFE_CCIC is not set
-# CONFIG_VIDEO_CAMERA_SENSOR is not set
-# CONFIG_VIDEO_CCS is not set
-# CONFIG_VIDEO_COBALT is not set
-# CONFIG_VIDEO_CODA is not set
-# CONFIG_VIDEO_CODEC_BCM2835 is not set
-# CONFIG_VIDEO_CS3308 is not set
-# CONFIG_VIDEO_CS5345 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_CX231XX is not set
-# CONFIG_VIDEO_CX2341X is not set
-# CONFIG_VIDEO_CX25821 is not set
-# CONFIG_VIDEO_CX25840 is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_DM6446_CCDC is not set
-# CONFIG_VIDEO_DT3155 is not set
-# CONFIG_VIDEO_DW9714 is not set
-# CONFIG_VIDEO_DW9768 is not set
-# CONFIG_VIDEO_DW9807_VCM is not set
-# CONFIG_VIDEO_EM28XX is not set
-# CONFIG_VIDEO_ET8EK8 is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-# CONFIG_VIDEO_GO7007 is not set
-# CONFIG_VIDEO_GS1662 is not set
-# CONFIG_VIDEO_HDPVR is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HI556 is not set
-# CONFIG_VIDEO_HI846 is not set
-# CONFIG_VIDEO_HI847 is not set
-# CONFIG_VIDEO_I2C is not set
-# CONFIG_VIDEO_IMX208 is not set
-# CONFIG_VIDEO_IMX214 is not set
-# CONFIG_VIDEO_IMX219 is not set
-# CONFIG_VIDEO_IMX258 is not set
-# CONFIG_VIDEO_IMX274 is not set
-# CONFIG_VIDEO_IMX290 is not set
-# CONFIG_VIDEO_IMX296 is not set
-# CONFIG_VIDEO_IMX319 is not set
-# CONFIG_VIDEO_IMX334 is not set
-# CONFIG_VIDEO_IMX335 is not set
-# CONFIG_VIDEO_IMX355 is not set
-# CONFIG_VIDEO_IMX412 is not set
-# CONFIG_VIDEO_IMX477 is not set
-# CONFIG_VIDEO_IMX519 is not set
-# CONFIG_VIDEO_IMX708 is not set
-# CONFIG_VIDEO_IMX8_JPEG is not set
-# CONFIG_VIDEO_IMX_MIPI_CSIS is not set
-# CONFIG_VIDEO_IMX_PXP is not set
-# CONFIG_VIDEO_IRS1125 is not set
-# CONFIG_VIDEO_IR_I2C is not set
-# CONFIG_VIDEO_ISL7998X is not set
-# CONFIG_VIDEO_ISP_BCM2835 is not set
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_LM3560 is not set
-# CONFIG_VIDEO_LM3646 is not set
-# CONFIG_VIDEO_M52790 is not set
-# CONFIG_VIDEO_M5MOLS is not set
-# CONFIG_VIDEO_MAX9286 is not set
-# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
-# CONFIG_VIDEO_ML86V7667 is not set
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_MT9M001 is not set
-# CONFIG_VIDEO_MT9M032 is not set
-# CONFIG_VIDEO_MT9M111 is not set
-# CONFIG_VIDEO_MT9P031 is not set
-# CONFIG_VIDEO_MT9T001 is not set
-# CONFIG_VIDEO_MT9T112 is not set
-# CONFIG_VIDEO_MT9V011 is not set
-# CONFIG_VIDEO_MT9V032 is not set
-# CONFIG_VIDEO_MT9V111 is not set
-# CONFIG_VIDEO_MUX is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_NOON010PC30 is not set
-# CONFIG_VIDEO_OG01A1B is not set
-# CONFIG_VIDEO_OMAP2_VOUT is not set
-# CONFIG_VIDEO_OV02A10 is not set
-# CONFIG_VIDEO_OV08D10 is not set
-# CONFIG_VIDEO_OV13858 is not set
-# CONFIG_VIDEO_OV13B10 is not set
-# CONFIG_VIDEO_OV2311 is not set
-# CONFIG_VIDEO_OV2640 is not set
-# CONFIG_VIDEO_OV2659 is not set
-# CONFIG_VIDEO_OV2680 is not set
-# CONFIG_VIDEO_OV2685 is not set
-# CONFIG_VIDEO_OV2740 is not set
-# CONFIG_VIDEO_OV5640 is not set
-# CONFIG_VIDEO_OV5645 is not set
-# CONFIG_VIDEO_OV5647 is not set
-# CONFIG_VIDEO_OV5648 is not set
-# CONFIG_VIDEO_OV5670 is not set
-# CONFIG_VIDEO_OV5675 is not set
-# CONFIG_VIDEO_OV5693 is not set
-# CONFIG_VIDEO_OV5695 is not set
-# CONFIG_VIDEO_OV64A40 is not set
-# CONFIG_VIDEO_OV6650 is not set
-# CONFIG_VIDEO_OV7251 is not set
-# CONFIG_VIDEO_OV7640 is not set
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_OV772X is not set
-# CONFIG_VIDEO_OV7740 is not set
-# CONFIG_VIDEO_OV8856 is not set
-# CONFIG_VIDEO_OV8865 is not set
-# CONFIG_VIDEO_OV9281 is not set
-# CONFIG_VIDEO_OV9282 is not set
-# CONFIG_VIDEO_OV9640 is not set
-# CONFIG_VIDEO_OV9650 is not set
-# CONFIG_VIDEO_OV9734 is not set
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_RASPBERRYPI_PISP_BE is not set
-# CONFIG_VIDEO_RCAR_CSI2 is not set
-# CONFIG_VIDEO_RCAR_ISP is not set
-# CONFIG_VIDEO_RCAR_VIN is not set
-# CONFIG_VIDEO_RDACM20 is not set
-# CONFIG_VIDEO_RDACM21 is not set
-# CONFIG_VIDEO_RJ54N1 is not set
-# CONFIG_VIDEO_ROCKCHIP_ISP1 is not set
-# CONFIG_VIDEO_RP1_CFE is not set
-# CONFIG_VIDEO_S5C73M3 is not set
-# CONFIG_VIDEO_S5K4ECGX is not set
-# CONFIG_VIDEO_S5K5BAF is not set
-# CONFIG_VIDEO_S5K6A3 is not set
-# CONFIG_VIDEO_S5K6AA is not set
-# CONFIG_VIDEO_SAA6588 is not set
-# CONFIG_VIDEO_SAA6752HS is not set
-# CONFIG_VIDEO_SAA7110 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_SAA7164 is not set
-# CONFIG_VIDEO_SAA717X is not set
-# CONFIG_VIDEO_SAA7185 is not set
-# CONFIG_VIDEO_SH_MOBILE_CEU is not set
-# CONFIG_VIDEO_SMIAPP is not set
-# CONFIG_VIDEO_SOLO6X10 is not set
-# CONFIG_VIDEO_SONY_BTF_MPX is not set
-# CONFIG_VIDEO_SR030PC30 is not set
-# CONFIG_VIDEO_STK1160_COMMON is not set
-# CONFIG_VIDEO_ST_MIPID02 is not set
-# CONFIG_VIDEO_SUN4I_CSI is not set
-# CONFIG_VIDEO_SUN6I_CSI is not set
-# CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2 is not set
-# CONFIG_VIDEO_TC358743 is not set
-# CONFIG_VIDEO_TDA1997X is not set
-# CONFIG_VIDEO_TDA7432 is not set
-# CONFIG_VIDEO_TDA9840 is not set
-# CONFIG_VIDEO_TEA6415C is not set
-# CONFIG_VIDEO_TEA6420 is not set
-# CONFIG_VIDEO_THS7303 is not set
-# CONFIG_VIDEO_THS8200 is not set
-# CONFIG_VIDEO_TIMBERDALE is not set
-# CONFIG_VIDEO_TLV320AIC23B is not set
-# CONFIG_VIDEO_TM6000 is not set
-# CONFIG_VIDEO_TVAUDIO is not set
-# CONFIG_VIDEO_TVP514X is not set
-# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_TVP7002 is not set
-# CONFIG_VIDEO_TW2804 is not set
-# CONFIG_VIDEO_TW5864 is not set
-# CONFIG_VIDEO_TW68 is not set
-# CONFIG_VIDEO_TW9903 is not set
-# CONFIG_VIDEO_TW9906 is not set
-# CONFIG_VIDEO_TW9910 is not set
-# CONFIG_VIDEO_UDA1342 is not set
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
-# CONFIG_VIDEO_USBTV is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_VIDEO_V4L2 is not set
-# CONFIG_VIDEO_VP27SMPX is not set
-# CONFIG_VIDEO_VPX3220 is not set
-# CONFIG_VIDEO_VS6624 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_XILINX is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIRTIO_BALLOON is not set
-# CONFIG_VIRTIO_BLK_SCSI is not set
-# CONFIG_VIRTIO_CONSOLE is not set
-# CONFIG_VIRTIO_FS is not set
-# CONFIG_VIRTIO_INPUT is not set
-CONFIG_VIRTIO_MENU=y
-# CONFIG_VIRTIO_MMIO is not set
-# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
-# CONFIG_VIRTIO_PCI is not set
-# CONFIG_VIRTUALIZATION is not set
-# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
-# CONFIG_VIRT_DRIVERS is not set
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_VL53L0X_I2C is not set
-# CONFIG_VL6180 is not set
-CONFIG_VLAN_8021Q=y
-# CONFIG_VLAN_8021Q_GVRP is not set
-# CONFIG_VLAN_8021Q_MVRP is not set
-# CONFIG_VMAP_STACK is not set
-# CONFIG_VME_BUS is not set
-# CONFIG_VMLINUX_MAP is not set
-# CONFIG_VMSPLIT_1G is not set
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_2G_OPT is not set
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_3G_OPT is not set
-# CONFIG_VMWARE_PVSCSI is not set
-# CONFIG_VMWARE_VMCI is not set
-# CONFIG_VMXNET3 is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_VOP_BUS is not set
-# CONFIG_VORTEX is not set
-# CONFIG_VSOCKETS is not set
-# CONFIG_VSOCKETS_DIAG is not set
-# CONFIG_VT is not set
-# CONFIG_VT6655 is not set
-# CONFIG_VT6656 is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_VXGE is not set
-# CONFIG_VXLAN is not set
-# CONFIG_VZ89X is not set
-# CONFIG_W1 is not set
-# CONFIG_W1_CON is not set
-# CONFIG_W1_MASTER_DS1WM is not set
-# CONFIG_W1_MASTER_DS2482 is not set
-# CONFIG_W1_MASTER_DS2490 is not set
-# CONFIG_W1_MASTER_GPIO is not set
-# CONFIG_W1_MASTER_MATROX is not set
-# CONFIG_W1_MASTER_SGI is not set
-# CONFIG_W1_SLAVE_DS2405 is not set
-# CONFIG_W1_SLAVE_DS2406 is not set
-# CONFIG_W1_SLAVE_DS2408 is not set
-# CONFIG_W1_SLAVE_DS2413 is not set
-# CONFIG_W1_SLAVE_DS2423 is not set
-# CONFIG_W1_SLAVE_DS2430 is not set
-# CONFIG_W1_SLAVE_DS2431 is not set
-# CONFIG_W1_SLAVE_DS2433 is not set
-# CONFIG_W1_SLAVE_DS2438 is not set
-# CONFIG_W1_SLAVE_DS250X is not set
-# CONFIG_W1_SLAVE_DS2780 is not set
-# CONFIG_W1_SLAVE_DS2781 is not set
-# CONFIG_W1_SLAVE_DS2805 is not set
-# CONFIG_W1_SLAVE_DS28E04 is not set
-# CONFIG_W1_SLAVE_DS28E17 is not set
-# CONFIG_W1_SLAVE_SMEM is not set
-# CONFIG_W1_SLAVE_THERM is not set
-# CONFIG_W83627HF_WDT is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_W83977F_WDT is not set
-# CONFIG_WAN is not set
-# CONFIG_WANXL is not set
-# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_CORE is not set
-CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
-# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-CONFIG_WATCHDOG_OPEN_TIMEOUT=0
-# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set
-# CONFIG_WATCHDOG_SYSFS is not set
-# CONFIG_WATCH_QUEUE is not set
-# CONFIG_WD80x3 is not set
-# CONFIG_WDAT_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_WERROR is not set
-# CONFIG_WEXT_CORE is not set
-# CONFIG_WEXT_PRIV is not set
-# CONFIG_WEXT_PROC is not set
-# CONFIG_WEXT_SPY is not set
-CONFIG_WILINK_PLATFORM_DATA=y
-# CONFIG_WIMAX is not set
-# CONFIG_WIREGUARD is not set
-CONFIG_WIRELESS=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_WIRELESS_WDS is not set
-# CONFIG_WIZNET_W5100 is not set
-# CONFIG_WIZNET_W5300 is not set
-# CONFIG_WL1251 is not set
-# CONFIG_WL12XX is not set
-# CONFIG_WL18XX is not set
-CONFIG_WLAN=y
-# CONFIG_WLAN_VENDOR_ADMTEK is not set
-# CONFIG_WLAN_VENDOR_ATH is not set
-# CONFIG_WLAN_VENDOR_ATMEL 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_MARVELL is not set
-# CONFIG_WLAN_VENDOR_MEDIATEK is not set
-# CONFIG_WLAN_VENDOR_MICROCHIP is not set
-# CONFIG_WLAN_VENDOR_PURELIFI is not set
-# CONFIG_WLAN_VENDOR_QUANTENNA is not set
-# CONFIG_WLAN_VENDOR_RALINK is not set
-# CONFIG_WLAN_VENDOR_REALTEK is not set
-# 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_WLAN_VENDOR_ZYDAS is not set
-# CONFIG_WLCORE is not set
-CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
-# CONFIG_WQ_WATCHDOG is not set
-# CONFIG_WWAN is not set
-# CONFIG_WWAN_HWSIM is not set
-# CONFIG_WW_MUTEX_SELFTEST is not set
-# CONFIG_X25 is not set
-# CONFIG_X509_CERTIFICATE_PARSER is not set
-# CONFIG_X86_PKG_TEMP_THERMAL is not set
-CONFIG_X86_SYSFB=y
-# CONFIG_XDP_SOCKETS is not set
-# CONFIG_XEN is not set
-# CONFIG_XEN_GRANT_DMA_ALLOC is not set
-# CONFIG_XEN_PVCALLS_FRONTEND is not set
-CONFIG_XEN_SCRUB_PAGES_DEFAULT=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_INTERFACE is not set
-# CONFIG_XFRM_IPCOMP is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_ONLINE_SCRUB is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_SUPPORT_V4 is not set
-# CONFIG_XFS_WARN is not set
-# CONFIG_XILINX_AXI_EMAC is not set
-# CONFIG_XILINX_DMA is not set
-# CONFIG_XILINX_EMACLITE is not set
-# CONFIG_XILINX_GMII2RGMII is not set
-# CONFIG_XILINX_INTC is not set
-# CONFIG_XILINX_LL_TEMAC is not set
-# CONFIG_XILINX_SDFEC is not set
-# CONFIG_XILINX_VCU is not set
-# CONFIG_XILINX_WATCHDOG is not set
-# CONFIG_XILINX_XADC is not set
-# CONFIG_XILINX_ZYNQMP_DMA is not set
-# CONFIG_XILINX_ZYNQMP_DPDMA is not set
-# CONFIG_XILLYBUS is not set
-# CONFIG_XILLYUSB is not set
-# CONFIG_XIL_AXIS_FIFO is not set
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_XMON is not set
-CONFIG_XZ_DEC=y
-# CONFIG_XZ_DEC_ARM is not set
-# CONFIG_XZ_DEC_ARMTHUMB is not set
-# CONFIG_XZ_DEC_BCJ is not set
-# CONFIG_XZ_DEC_IA64 is not set
-# CONFIG_XZ_DEC_MICROLZMA is not set
-# CONFIG_XZ_DEC_POWERPC is not set
-# CONFIG_XZ_DEC_SPARC is not set
-# CONFIG_XZ_DEC_TEST is not set
-# CONFIG_XZ_DEC_X86 is not set
-# CONFIG_YAM is not set
-# CONFIG_YAMAHA_YAS530 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_YENTA is not set
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-# CONFIG_YENTA_TI is not set
-# CONFIG_YENTA_TOSHIBA is not set
-# CONFIG_ZBUD is not set
-# CONFIG_ZD1211RW is not set
-# CONFIG_ZD1211RW_DEBUG is not set
-# CONFIG_ZEROPLUS_FF is not set
-# CONFIG_ZERO_CALL_USED_REGS is not set
-# CONFIG_ZIIRAVE_WATCHDOG is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_ZLIB_DEFLATE is not set
-# CONFIG_ZLIB_INFLATE is not set
-CONFIG_ZONE_DMA=y
-# CONFIG_ZOPT2201 is not set
-# CONFIG_ZPA2326 is not set
-# CONFIG_ZPOOL is not set
-# CONFIG_ZRAM is not set
-# CONFIG_ZRAM_DEF_COMP_842 is not set
-# CONFIG_ZRAM_DEF_COMP_LZ4 is not set
-# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set
-# CONFIG_ZRAM_DEF_COMP_LZO is not set
-# CONFIG_ZRAM_DEF_COMP_LZORLE is not set
-# CONFIG_ZRAM_DEF_COMP_ZSTD is not set
-# CONFIG_ZRAM_MEMORY_TRACKING is not set
-# CONFIG_ZSMALLOC is not set
-# CONFIG_ZSWAP is not set
-# CONFIG_ZX_TDM is not set
diff --git a/target/linux/generic/config-6.6 b/target/linux/generic/config-6.6
index 20fe98099f..c8bca0d0ff 100644
--- a/target/linux/generic/config-6.6
+++ b/target/linux/generic/config-6.6
@@ -179,6 +179,7 @@ CONFIG_ALLOW_DEV_COREDUMP=y
# CONFIG_AMD_MEM_ENCRYPT is not set
# CONFIG_AMD_PHY is not set
# CONFIG_AMD_XGBE is not set
+# CONFIG_AMD_XGBE_DCB is not set
# CONFIG_AMD_XGBE_HAVE_ECC is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_AMILO_RFKILL is not set
@@ -324,7 +325,9 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_64K_PAGES is not set
# CONFIG_ARM64_AMU_EXTN is not set
# CONFIG_ARM64_BTI is not set
+CONFIG_ARM64_CNP=y
# CONFIG_ARM64_E0PD is not set
+# CONFIG_ARM64_EPAN is not set
# CONFIG_ARM64_ERRATUM_1024718 is not set
# CONFIG_ARM64_ERRATUM_1165522 is not set
# CONFIG_ARM64_ERRATUM_1286807 is not set
@@ -345,6 +348,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_ERRATUM_2658417 is not set
# CONFIG_ARM64_ERRATUM_2966298 is not set
# CONFIG_ARM64_ERRATUM_3117295 is not set
+# CONFIG_ARM64_ERRATUM_3194386 is not set
# CONFIG_ARM64_ERRATUM_819472 is not set
# CONFIG_ARM64_ERRATUM_824069 is not set
# CONFIG_ARM64_ERRATUM_826319 is not set
@@ -357,7 +361,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_HW_AFDBM is not set
# CONFIG_ARM64_LSE_ATOMICS is not set
# CONFIG_ARM64_MTE is not set
-# CONFIG_ARM64_PAN is not set
+CONFIG_ARM64_PAN=y
# CONFIG_ARM64_PMEM is not set
# CONFIG_ARM64_PSEUDO_NMI is not set
# CONFIG_ARM64_PTR_AUTH is not set
@@ -635,11 +639,11 @@ CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_UBLK is not set
# CONFIG_BLK_DEV_ZONED is not set
# CONFIG_BLK_INLINE_ENCRYPTION is not set
-# CONFIG_BLOCK_NOTIFIERS is not set
# CONFIG_BLK_SED_OPAL is not set
# CONFIG_BLK_WBT is not set
CONFIG_BLOCK=y
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
+# CONFIG_BLOCK_NOTIFIERS is not set
# CONFIG_BMA180 is not set
# CONFIG_BMA220 is not set
# CONFIG_BMA400 is not set
@@ -725,6 +729,7 @@ CONFIG_BROKEN_ON_SMP=y
# CONFIG_BTRFS_ASSERT is not set
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
# CONFIG_BTRFS_FS_POSIX_ACL is not set
# CONFIG_BTRFS_FS_REF_VERIFY is not set
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
@@ -875,6 +880,7 @@ CONFIG_CFG80211_HEADERS=y
# CONFIG_CHELSIO_T4 is not set
# CONFIG_CHELSIO_T4VF is not set
# CONFIG_CHROME_PLATFORMS is not set
+# CONFIG_CZNIC_PLATFORMS is not set
# CONFIG_CHR_DEV_SCH is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_ST is not set
@@ -1003,10 +1009,10 @@ CONFIG_CRAMFS_BLOCKDEV=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_CRC32_BIT is not set
-CONFIG_CRC32_SARWATE=y
+# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_SELFTEST is not set
# CONFIG_CRC32_SLICEBY4 is not set
-# CONFIG_CRC32_SLICEBY8 is not set
+CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC4 is not set
# CONFIG_CRC64 is not set
# CONFIG_CRC64_ROCKSOFT is not set
@@ -1015,8 +1021,8 @@ CONFIG_CRC32_SARWATE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC_ITU_T is not set
# CONFIG_CRC_T10DIF is not set
-# CONFIG_CROS_HPS_I2C is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
+# CONFIG_CROS_HPS_I2C is not set
CONFIG_CRYPTO=y
# CONFIG_CRYPTO_842 is not set
CONFIG_CRYPTO_ACOMP2=y
@@ -1527,8 +1533,8 @@ CONFIG_DQL=y
# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set
# CONFIG_DRM_PANEL_MIPI_DBI is not set
# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
-# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set
# CONFIG_DRM_PANEL_NEWVISION_NV3051D is not set
+# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set
@@ -2521,6 +2527,7 @@ CONFIG_HZ_100=y
# CONFIG_I3C is not set
# CONFIG_I40E is not set
# CONFIG_I40EVF is not set
+# CONFIG_I40E_DCB is not set
# CONFIG_I6300ESB_WDT is not set
# CONFIG_I82092 is not set
# CONFIG_I82365 is not set
@@ -2869,6 +2876,7 @@ CONFIG_ISDN=y
# CONFIG_IWLWIFI is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
+# CONFIG_IXGBE_DCB is not set
# CONFIG_JAILHOUSE_GUEST is not set
# CONFIG_JBD2_DEBUG is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
@@ -3111,7 +3119,7 @@ CONFIG_LINEAR_RANGES=y
# CONFIG_LIQUIDIO is not set
# CONFIG_LIQUIDIO_VF is not set
# CONFIG_LIRC is not set
-# CONFIG_LIST_HARDENED is not set
+CONFIG_LIST_HARDENED=y
# CONFIG_LITEX_LITEETH is not set
# CONFIG_LITEX_SOC_CONTROLLER is not set
# CONFIG_LIVEPATCH is not set
@@ -4327,6 +4335,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NVMEM_IMX_OCOTP is not set
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
+# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
# CONFIG_NVMEM_REBOOT_MODE is not set
# CONFIG_NVMEM_RMEM is not set
# CONFIG_NVMEM_SYSFS is not set
@@ -4545,6 +4554,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCMCIA_XIRCOM is not set
# CONFIG_PCNET32 is not set
# CONFIG_PCPU_DEV_REFCNT is not set
+CONFIG_PCP_BATCH_SCALE_MAX=5
# CONFIG_PCSPKR_PLATFORM is not set
# CONFIG_PCS_MTK_USXGMII is not set
# CONFIG_PCS_XPCS is not set
@@ -4797,6 +4807,7 @@ CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_QFMT_V1 is not set
# CONFIG_QLA3XXX is not set
# CONFIG_QLCNIC is not set
+# CONFIG_QLCNIC_DCB is not set
# CONFIG_QLGE is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set
@@ -4966,6 +4977,7 @@ CONFIG_REISERFS_FS_XATTR=y
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_RELAY is not set
# CONFIG_RELOCATABLE is not set
+CONFIG_RELR=y
# CONFIG_REMOTEPROC is not set
# CONFIG_RENESAS_PHY is not set
# CONFIG_RESET_ATH79 is not set
@@ -5134,6 +5146,7 @@ CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
# CONFIG_RTL_CARDS is not set
# CONFIG_RTS5208 is not set
CONFIG_RT_MUTEXES=y
+# CONFIG_RUST is not set
CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_RV is not set
CONFIG_RXKAD=y
@@ -6182,8 +6195,8 @@ CONFIG_SND_X86=y
# CONFIG_SPI_AXI_SPI_ENGINE is not set
# CONFIG_SPI_BCM2835 is not set
# CONFIG_SPI_BCM63XX_HSSPI is not set
-# CONFIG_SPI_BCM_QSPI is not set
# CONFIG_SPI_BCMBCA_HSSPI is not set
+# CONFIG_SPI_BCM_QSPI is not set
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_BUTTERFLY is not set
# CONFIG_SPI_CADENCE is not set
@@ -6760,8 +6773,8 @@ CONFIG_USB_BELKIN=y
# CONFIG_USB_CDNS3 is not set
# CONFIG_USB_CDNS3_IMX is not set
# CONFIG_USB_CDNS3_PCI_WRAP is not set
-# CONFIG_USB_CDNS_SUPPORT is not set
# CONFIG_USB_CDNSP_PCI is not set
+# CONFIG_USB_CDNS_SUPPORT is not set
# CONFIG_USB_CHAOSKEY is not set
# CONFIG_USB_CHIPIDEA is not set
# CONFIG_USB_CHIPIDEA_GENERIC is not set
@@ -6787,6 +6800,7 @@ CONFIG_USB_DEFAULT_PERSIST=y
# CONFIG_USB_DWC3_EXYNOS is not set
# CONFIG_USB_DWC3_HAPS is not set
# CONFIG_USB_DWC3_KEYSTONE is not set
+# CONFIG_USB_DWC3_OCTEON is not set
# CONFIG_USB_DWC3_OF_SIMPLE is not set
# CONFIG_USB_DWC3_PCI is not set
# CONFIG_USB_DWC3_QCOM is not set
@@ -6991,6 +7005,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SERIAL_ARK3116 is not set
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_CH348 is not set
# CONFIG_USB_SERIAL_CP210X is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
index 3b71597d23..a271a676e1 100644
--- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
+++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
@@ -278,7 +278,7 @@ mtdsplit_fit_parse(struct mtd_info *mtd,
parts[0].name = KERNEL_PART_NAME;
parts[0].offset = fit_offset;
- parts[0].size = mtd_rounddown_to_eb(fit_size + offset_start, mtd) + mtd->erasesize;
+ parts[0].size = mtd_roundup_to_eb(fit_size + offset_start, mtd);
if (type == MTDSPLIT_PART_TYPE_UBI)
parts[1].name = UBI_PART_NAME;
@@ -327,7 +327,7 @@ mtdsplit_fit_parse(struct mtd_info *mtd,
return -ENOMEM;
parts[0].name = ROOTFS_SPLIT_NAME;
- parts[0].offset = fit_offset + mtd_rounddown_to_eb(max_size, mtd) + mtd->erasesize;
+ parts[0].offset = fit_offset + mtd_roundup_to_eb(max_size, mtd);
parts[0].size = mtd->size - parts[0].offset;
*pparts = parts;
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 850bcefb74..84b923ffc1 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -35,7 +35,6 @@
#include <linux/lockdep.h>
#include <linux/ar8216_platform.h>
#include <linux/workqueue.h>
-#include <linux/version.h>
#include "ar8216.h"
@@ -2458,11 +2457,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev)
/* VID fixup only needed on ar8216 */
if (chip_is_ar8216(priv)) {
dev->phy_ptr = priv;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
dev->priv_flags |= IFF_NO_IP_ALIGN;
-#else
- dev->extra_priv_flags |= IFF_NO_IP_ALIGN;
-#endif
dev->eth_mangle_rx = ar8216_mangle_rx;
dev->eth_mangle_tx = ar8216_mangle_tx;
}
@@ -2697,11 +2692,7 @@ ar8xxx_phy_detach(struct phy_device *phydev)
#ifdef CONFIG_ETHERNET_PACKET_MANGLE
dev->phy_ptr = NULL;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
dev->priv_flags &= ~IFF_NO_IP_ALIGN;
-#else
- dev->extra_priv_flags &= ~IFF_NO_IP_ALIGN;
-#endif
dev->eth_mangle_rx = NULL;
dev->eth_mangle_tx = NULL;
#endif
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
index 3fcae81fa4..2608240bb0 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
+++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
@@ -23,6 +23,18 @@ struct dentry;
struct inode;
struct file;
+typedef enum rtl8367b_chip_e {
+ RTL8367B_CHIP_UNKNOWN,
+ /* Family B */
+ RTL8367B_CHIP_RTL8367RB,
+ RTL8367B_CHIP_RTL8367R_VB, /* chip with exception in extif assignment */
+/* Family C */
+ RTL8367B_CHIP_RTL8367RB_VB,
+ RTL8367B_CHIP_RTL8367S,
+/* Family D */
+ RTL8367B_CHIP_RTL8367S_VB /* chip with exception in extif assignment */
+} rtl8367b_chip_t;
+
struct rtl8366_mib_counter {
unsigned base;
unsigned offset;
@@ -64,7 +76,9 @@ struct rtl8366_smi {
u8 dbg_vlan_4k_page;
#endif
u32 phy_id;
+ rtl8367b_chip_t rtl8367b_chip;
struct mii_bus *ext_mbus;
+ struct rtl8366_vlan_mc *emu_vlanmc;
};
struct rtl8366_vlan_mc {
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8367.c b/target/linux/generic/files/drivers/net/phy/rtl8367.c
index b14b63e036..0acfeb54bb 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8367.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8367.c
@@ -1077,21 +1077,37 @@ static int rtl8367_led_blinkrate_set(struct rtl8366_smi *smi, unsigned int rate)
}
#ifdef CONFIG_OF
-static int rtl8367_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
struct rtl8367_extif_config *cfg;
const __be32 *prop;
int size;
int err;
+ unsigned cpu_port;
+ unsigned id = UINT_MAX;
prop = of_get_property(smi->parent->of_node, name, &size);
- if (!prop)
- return rtl8367_extif_init(smi, id, NULL);
+ if (!prop || (size != (10 * sizeof(*prop)))) {
+ dev_err(smi->parent, "%s property is not defined or invalid\n", name);
+ err = -EINVAL;
+ goto err_init;
+ }
- if (size != (9 * sizeof(*prop))) {
- dev_err(smi->parent, "%s property is invalid\n", name);
- return -EINVAL;
+ cpu_port = be32_to_cpup(prop++);
+ switch (cpu_port) {
+ case RTL8367_CPU_PORT_NUM - 1:
+ case RTL8367_CPU_PORT_NUM:
+ id = RTL8367_CPU_PORT_NUM - cpu_port;
+ if (smi->cpu_port == UINT_MAX) {
+ dev_info(smi->parent, "cpu_port:%u, assigned to extif%u\n", cpu_port, id);
+ smi->cpu_port = cpu_port;
+ }
+ break;
+ default:
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
}
cfg = kzalloc(sizeof(struct rtl8367_extif_config), GFP_KERNEL);
@@ -1111,10 +1127,14 @@ static int rtl8367_extif_init_of(struct rtl8366_smi *smi, int id,
err = rtl8367_extif_init(smi, id, cfg);
kfree(cfg);
+err_init:
+ if (id != 0) rtl8367_extif_init(smi, 0, NULL);
+ if (id != 1) rtl8367_extif_init(smi, 1, NULL);
+
return err;
}
#else
-static int rtl8367_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
return -EINVAL;
@@ -1135,11 +1155,7 @@ static int rtl8367_setup(struct rtl8366_smi *smi)
/* initialize external interfaces */
if (smi->parent->of_node) {
- err = rtl8367_extif_init_of(smi, 0, "realtek,extif0");
- if (err)
- return err;
-
- err = rtl8367_extif_init_of(smi, 1, "realtek,extif1");
+ err = rtl8367_extif_init_of(smi, "realtek,extif");
if (err)
return err;
} else {
@@ -1722,11 +1738,6 @@ static int rtl8367_detect(struct rtl8366_smi *smi)
dev_info(smi->parent, "RTL%s ver. %u chip found\n",
chip_name, rtl_ver & RTL8367_RTL_VER_MASK);
- if (of_property_present(smi->parent->of_node, "realtek,extif1"))
- smi->cpu_port = RTL8367_CPU_PORT_NUM - 1;
-
- dev_info(smi->parent, "CPU port: %u\n", smi->cpu_port);
-
return 0;
}
@@ -1764,7 +1775,7 @@ static int rtl8367_probe(struct platform_device *pdev)
smi->cmd_read = 0xb9;
smi->cmd_write = 0xb8;
smi->ops = &rtl8367_smi_ops;
- smi->cpu_port = RTL8367_CPU_PORT_NUM;
+ smi->cpu_port = UINT_MAX; /* not defined yet */
smi->num_ports = RTL8367_NUM_PORTS;
smi->num_vlan_mc = RTL8367_NUM_VLANS;
smi->mib_counters = rtl8367_mib_counters;
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8367b.c b/target/linux/generic/files/drivers/net/phy/rtl8367b.c
index 04c790e924..4236912dd5 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8367b.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8367b.c
@@ -1,5 +1,7 @@
/*
- * Platform driver for the Realtek RTL8367R-VB ethernet switches
+ * Platform driver for Realtek RTL8367B family chips, i.e. RTL8367RB and RTL8367R-VB
+ * extended with support for RTL8367C family chips, i.e. RTL8367RB-VB and RTL8367S
+ * extended with support for RTL8367D family chips, i.e. RTL8367S-VB
*
* Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
*
@@ -266,6 +268,37 @@ struct rtl8367b_initval {
#define RTL8367B_MIB_RXB_ID 0 /* IfInOctets */
#define RTL8367B_MIB_TXB_ID 28 /* IfOutOctets */
+#define RTL8367D_PORT_STATUS_REG(_p) (0x12d0 + (_p))
+
+#define RTL8367D_PORT_STATUS_SPEED1_MASK 0x3000
+#define RTL8367D_PORT_STATUS_SPEED1_SHIFT 10 /*12-2*/
+
+#define RTL8367D_REG_MAC0_FORCE_SELECT 0x12c0
+#define RTL8367D_REG_MAC0_FORCE_SELECT_EN 0x12c8
+
+#define RTL8367D_VLAN_PVID_CTRL_REG(_p) (0x0700 + (_p))
+#define RTL8367D_VLAN_PVID_CTRL_MASK 0xfff
+#define RTL8367D_VLAN_PVID_CTRL_SHIFT(_p) 0
+
+#define RTL8367D_FIDMAX 3
+#define RTL8367D_FID_MASK 3
+#define RTL8367D_TA_VLAN1_FID_SHIFT 0
+#define RTL8367D_TA_VLAN1_FID_MASK RTL8367D_FID_MASK
+
+#define RTL8367D_VID_MASK 0xfff
+#define RTL8367D_TA_VLAN_VID_MASK RTL8367D_VID_MASK
+
+#define RTL8367D_REG_EXT_TXC_DLY 0x13f9
+#define RTL8367D_EXT1_RGMII_TX_DLY_MASK 0x38
+
+#define RTL8367D_REG_TOP_CON0 0x1d70
+#define RTL8367D_MAC7_SEL_EXT1_MASK 0x2000
+#define RTL8367D_MAC4_SEL_EXT1_MASK 0x1000
+
+#define RTL8367D_REG_SDS1_MISC0 0x1d78
+#define RTL8367D_SDS1_MODE_MASK 0x1f
+#define RTL8367D_PORT_SDS_MODE_DISABLE 0x1f
+
static struct rtl8366_mib_counter
rtl8367b_mib_counters[RTL8367B_NUM_MIB_COUNTERS] = {
{0, 0, 4, "ifInOctets" },
@@ -351,220 +384,7 @@ rtl8367b_mib_counters[RTL8367B_NUM_MIB_COUNTERS] = {
return err; \
} while (0)
-static const struct rtl8367b_initval rtl8367r_vb_initvals_0[] = {
- {0x1B03, 0x0876}, {0x1200, 0x7FC4}, {0x0301, 0x0026}, {0x1722, 0x0E14},
- {0x205F, 0x0002}, {0x2059, 0x1A00}, {0x205F, 0x0000}, {0x207F, 0x0002},
- {0x2077, 0x0000}, {0x2078, 0x0000}, {0x2079, 0x0000}, {0x207A, 0x0000},
- {0x207B, 0x0000}, {0x207F, 0x0000}, {0x205F, 0x0002}, {0x2053, 0x0000},
- {0x2054, 0x0000}, {0x2055, 0x0000}, {0x2056, 0x0000}, {0x2057, 0x0000},
- {0x205F, 0x0000}, {0x12A4, 0x110A}, {0x12A6, 0x150A}, {0x13F1, 0x0013},
- {0x13F4, 0x0010}, {0x13F5, 0x0000}, {0x0018, 0x0F00}, {0x0038, 0x0F00},
- {0x0058, 0x0F00}, {0x0078, 0x0F00}, {0x0098, 0x0F00}, {0x12B6, 0x0C02},
- {0x12B7, 0x030F}, {0x12B8, 0x11FF}, {0x12BC, 0x0004}, {0x1362, 0x0115},
- {0x1363, 0x0002}, {0x1363, 0x0000}, {0x133F, 0x0030}, {0x133E, 0x000E},
- {0x221F, 0x0007}, {0x221E, 0x002D}, {0x2218, 0xF030}, {0x221F, 0x0007},
- {0x221E, 0x0023}, {0x2216, 0x0005}, {0x2215, 0x00B9}, {0x2219, 0x0044},
- {0x2215, 0x00BA}, {0x2219, 0x0020}, {0x2215, 0x00BB}, {0x2219, 0x00C1},
- {0x2215, 0x0148}, {0x2219, 0x0096}, {0x2215, 0x016E}, {0x2219, 0x0026},
- {0x2216, 0x0000}, {0x2216, 0x0000}, {0x221E, 0x002D}, {0x2218, 0xF010},
- {0x221F, 0x0007}, {0x221E, 0x0020}, {0x2215, 0x0D00}, {0x221F, 0x0000},
- {0x221F, 0x0000}, {0x2217, 0x2160}, {0x221F, 0x0001}, {0x2210, 0xF25E},
- {0x221F, 0x0007}, {0x221E, 0x0042}, {0x2215, 0x0F00}, {0x2215, 0x0F00},
- {0x2216, 0x7408}, {0x2215, 0x0E00}, {0x2215, 0x0F00}, {0x2215, 0x0F01},
- {0x2216, 0x4000}, {0x2215, 0x0E01}, {0x2215, 0x0F01}, {0x2215, 0x0F02},
- {0x2216, 0x9400}, {0x2215, 0x0E02}, {0x2215, 0x0F02}, {0x2215, 0x0F03},
- {0x2216, 0x7408}, {0x2215, 0x0E03}, {0x2215, 0x0F03}, {0x2215, 0x0F04},
- {0x2216, 0x4008}, {0x2215, 0x0E04}, {0x2215, 0x0F04}, {0x2215, 0x0F05},
- {0x2216, 0x9400}, {0x2215, 0x0E05}, {0x2215, 0x0F05}, {0x2215, 0x0F06},
- {0x2216, 0x0803}, {0x2215, 0x0E06}, {0x2215, 0x0F06}, {0x2215, 0x0D00},
- {0x2215, 0x0100}, {0x221F, 0x0001}, {0x2210, 0xF05E}, {0x221F, 0x0000},
- {0x2217, 0x2100}, {0x221F, 0x0000}, {0x220D, 0x0003}, {0x220E, 0x0015},
- {0x220D, 0x4003}, {0x220E, 0x0006}, {0x221F, 0x0000}, {0x2200, 0x1340},
- {0x133F, 0x0010}, {0x12A0, 0x0058}, {0x12A1, 0x0058}, {0x133E, 0x000E},
- {0x133F, 0x0030}, {0x221F, 0x0000}, {0x2210, 0x0166}, {0x221F, 0x0000},
- {0x133E, 0x000E}, {0x133F, 0x0010}, {0x133F, 0x0030}, {0x133E, 0x000E},
- {0x221F, 0x0005}, {0x2205, 0xFFF6}, {0x2206, 0x0080}, {0x2205, 0x8B6E},
- {0x2206, 0x0000}, {0x220F, 0x0100}, {0x2205, 0x8000}, {0x2206, 0x0280},
- {0x2206, 0x28F7}, {0x2206, 0x00E0}, {0x2206, 0xFFF7}, {0x2206, 0xA080},
- {0x2206, 0x02AE}, {0x2206, 0xF602}, {0x2206, 0x0153}, {0x2206, 0x0201},
- {0x2206, 0x6602}, {0x2206, 0x80B9}, {0x2206, 0xE08B}, {0x2206, 0x8CE1},
- {0x2206, 0x8B8D}, {0x2206, 0x1E01}, {0x2206, 0xE18B}, {0x2206, 0x8E1E},
- {0x2206, 0x01A0}, {0x2206, 0x00E7}, {0x2206, 0xAEDB}, {0x2206, 0xEEE0},
- {0x2206, 0x120E}, {0x2206, 0xEEE0}, {0x2206, 0x1300}, {0x2206, 0xEEE0},
- {0x2206, 0x2001}, {0x2206, 0xEEE0}, {0x2206, 0x2166}, {0x2206, 0xEEE0},
- {0x2206, 0xC463}, {0x2206, 0xEEE0}, {0x2206, 0xC5E8}, {0x2206, 0xEEE0},
- {0x2206, 0xC699}, {0x2206, 0xEEE0}, {0x2206, 0xC7C2}, {0x2206, 0xEEE0},
- {0x2206, 0xC801}, {0x2206, 0xEEE0}, {0x2206, 0xC913}, {0x2206, 0xEEE0},
- {0x2206, 0xCA30}, {0x2206, 0xEEE0}, {0x2206, 0xCB3E}, {0x2206, 0xEEE0},
- {0x2206, 0xDCE1}, {0x2206, 0xEEE0}, {0x2206, 0xDD00}, {0x2206, 0xEEE2},
- {0x2206, 0x0001}, {0x2206, 0xEEE2}, {0x2206, 0x0100}, {0x2206, 0xEEE4},
- {0x2206, 0x8860}, {0x2206, 0xEEE4}, {0x2206, 0x8902}, {0x2206, 0xEEE4},
- {0x2206, 0x8C00}, {0x2206, 0xEEE4}, {0x2206, 0x8D30}, {0x2206, 0xEEEA},
- {0x2206, 0x1480}, {0x2206, 0xEEEA}, {0x2206, 0x1503}, {0x2206, 0xEEEA},
- {0x2206, 0xC600}, {0x2206, 0xEEEA}, {0x2206, 0xC706}, {0x2206, 0xEE85},
- {0x2206, 0xEE00}, {0x2206, 0xEE85}, {0x2206, 0xEF00}, {0x2206, 0xEE8B},
- {0x2206, 0x6750}, {0x2206, 0xEE8B}, {0x2206, 0x6632}, {0x2206, 0xEE8A},
- {0x2206, 0xD448}, {0x2206, 0xEE8A}, {0x2206, 0xD548}, {0x2206, 0xEE8A},
- {0x2206, 0xD649}, {0x2206, 0xEE8A}, {0x2206, 0xD7F8}, {0x2206, 0xEE8B},
- {0x2206, 0x85E2}, {0x2206, 0xEE8B}, {0x2206, 0x8700}, {0x2206, 0xEEFF},
- {0x2206, 0xF600}, {0x2206, 0xEEFF}, {0x2206, 0xF7FC}, {0x2206, 0x04F8},
- {0x2206, 0xE08B}, {0x2206, 0x8EAD}, {0x2206, 0x2023}, {0x2206, 0xF620},
- {0x2206, 0xE48B}, {0x2206, 0x8E02}, {0x2206, 0x2877}, {0x2206, 0x0225},
- {0x2206, 0xC702}, {0x2206, 0x26A1}, {0x2206, 0x0281}, {0x2206, 0xB302},
- {0x2206, 0x8496}, {0x2206, 0x0202}, {0x2206, 0xA102}, {0x2206, 0x27F1},
- {0x2206, 0x0228}, {0x2206, 0xF902}, {0x2206, 0x2AA0}, {0x2206, 0x0282},
- {0x2206, 0xB8E0}, {0x2206, 0x8B8E}, {0x2206, 0xAD21}, {0x2206, 0x08F6},
- {0x2206, 0x21E4}, {0x2206, 0x8B8E}, {0x2206, 0x0202}, {0x2206, 0x80E0},
- {0x2206, 0x8B8E}, {0x2206, 0xAD22}, {0x2206, 0x05F6}, {0x2206, 0x22E4},
- {0x2206, 0x8B8E}, {0x2206, 0xE08B}, {0x2206, 0x8EAD}, {0x2206, 0x2305},
- {0x2206, 0xF623}, {0x2206, 0xE48B}, {0x2206, 0x8EE0}, {0x2206, 0x8B8E},
- {0x2206, 0xAD24}, {0x2206, 0x08F6}, {0x2206, 0x24E4}, {0x2206, 0x8B8E},
- {0x2206, 0x0227}, {0x2206, 0x6AE0}, {0x2206, 0x8B8E}, {0x2206, 0xAD25},
- {0x2206, 0x05F6}, {0x2206, 0x25E4}, {0x2206, 0x8B8E}, {0x2206, 0xE08B},
- {0x2206, 0x8EAD}, {0x2206, 0x260B}, {0x2206, 0xF626}, {0x2206, 0xE48B},
- {0x2206, 0x8E02}, {0x2206, 0x830D}, {0x2206, 0x021D}, {0x2206, 0x6BE0},
- {0x2206, 0x8B8E}, {0x2206, 0xAD27}, {0x2206, 0x05F6}, {0x2206, 0x27E4},
- {0x2206, 0x8B8E}, {0x2206, 0x0281}, {0x2206, 0x4402}, {0x2206, 0x045C},
- {0x2206, 0xFC04}, {0x2206, 0xF8E0}, {0x2206, 0x8B83}, {0x2206, 0xAD23},
- {0x2206, 0x30E0}, {0x2206, 0xE022}, {0x2206, 0xE1E0}, {0x2206, 0x2359},
- {0x2206, 0x02E0}, {0x2206, 0x85EF}, {0x2206, 0xE585}, {0x2206, 0xEFAC},
- {0x2206, 0x2907}, {0x2206, 0x1F01}, {0x2206, 0x9E51}, {0x2206, 0xAD29},
- {0x2206, 0x20E0}, {0x2206, 0x8B83}, {0x2206, 0xAD21}, {0x2206, 0x06E1},
- {0x2206, 0x8B84}, {0x2206, 0xAD28}, {0x2206, 0x42E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD21}, {0x2206, 0x06E1}, {0x2206, 0x8B84}, {0x2206, 0xAD29},
- {0x2206, 0x36BF}, {0x2206, 0x34BF}, {0x2206, 0x022C}, {0x2206, 0x31AE},
- {0x2206, 0x2EE0}, {0x2206, 0x8B83}, {0x2206, 0xAD21}, {0x2206, 0x10E0},
- {0x2206, 0x8B84}, {0x2206, 0xF620}, {0x2206, 0xE48B}, {0x2206, 0x84EE},
- {0x2206, 0x8ADA}, {0x2206, 0x00EE}, {0x2206, 0x8ADB}, {0x2206, 0x00E0},
- {0x2206, 0x8B85}, {0x2206, 0xAD21}, {0x2206, 0x0CE0}, {0x2206, 0x8B84},
- {0x2206, 0xF621}, {0x2206, 0xE48B}, {0x2206, 0x84EE}, {0x2206, 0x8B72},
- {0x2206, 0xFFBF}, {0x2206, 0x34C2}, {0x2206, 0x022C}, {0x2206, 0x31FC},
- {0x2206, 0x04F8}, {0x2206, 0xFAEF}, {0x2206, 0x69E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD21}, {0x2206, 0x42E0}, {0x2206, 0xE022}, {0x2206, 0xE1E0},
- {0x2206, 0x2358}, {0x2206, 0xC059}, {0x2206, 0x021E}, {0x2206, 0x01E1},
- {0x2206, 0x8B72}, {0x2206, 0x1F10}, {0x2206, 0x9E2F}, {0x2206, 0xE48B},
- {0x2206, 0x72AD}, {0x2206, 0x2123}, {0x2206, 0xE18B}, {0x2206, 0x84F7},
- {0x2206, 0x29E5}, {0x2206, 0x8B84}, {0x2206, 0xAC27}, {0x2206, 0x10AC},
- {0x2206, 0x2605}, {0x2206, 0x0205}, {0x2206, 0x23AE}, {0x2206, 0x1602},
- {0x2206, 0x0535}, {0x2206, 0x0282}, {0x2206, 0x30AE}, {0x2206, 0x0E02},
- {0x2206, 0x056A}, {0x2206, 0x0282}, {0x2206, 0x75AE}, {0x2206, 0x0602},
- {0x2206, 0x04DC}, {0x2206, 0x0282}, {0x2206, 0x04EF}, {0x2206, 0x96FE},
- {0x2206, 0xFC04}, {0x2206, 0xF8F9}, {0x2206, 0xE08B}, {0x2206, 0x87AD},
- {0x2206, 0x2321}, {0x2206, 0xE0EA}, {0x2206, 0x14E1}, {0x2206, 0xEA15},
- {0x2206, 0xAD26}, {0x2206, 0x18F6}, {0x2206, 0x27E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15F6}, {0x2206, 0x26E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15F7}, {0x2206, 0x27E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15FD}, {0x2206, 0xFC04}, {0x2206, 0xF8F9},
- {0x2206, 0xE08B}, {0x2206, 0x87AD}, {0x2206, 0x233A}, {0x2206, 0xAD22},
- {0x2206, 0x37E0}, {0x2206, 0xE020}, {0x2206, 0xE1E0}, {0x2206, 0x21AC},
- {0x2206, 0x212E}, {0x2206, 0xE0EA}, {0x2206, 0x14E1}, {0x2206, 0xEA15},
- {0x2206, 0xF627}, {0x2206, 0xE4EA}, {0x2206, 0x14E5}, {0x2206, 0xEA15},
- {0x2206, 0xE2EA}, {0x2206, 0x12E3}, {0x2206, 0xEA13}, {0x2206, 0x5A8F},
- {0x2206, 0x6A20}, {0x2206, 0xE6EA}, {0x2206, 0x12E7}, {0x2206, 0xEA13},
- {0x2206, 0xF726}, {0x2206, 0xE4EA}, {0x2206, 0x14E5}, {0x2206, 0xEA15},
- {0x2206, 0xF727}, {0x2206, 0xE4EA}, {0x2206, 0x14E5}, {0x2206, 0xEA15},
- {0x2206, 0xFDFC}, {0x2206, 0x04F8}, {0x2206, 0xF9E0}, {0x2206, 0x8B87},
- {0x2206, 0xAD23}, {0x2206, 0x38AD}, {0x2206, 0x2135}, {0x2206, 0xE0E0},
- {0x2206, 0x20E1}, {0x2206, 0xE021}, {0x2206, 0xAC21}, {0x2206, 0x2CE0},
- {0x2206, 0xEA14}, {0x2206, 0xE1EA}, {0x2206, 0x15F6}, {0x2206, 0x27E4},
- {0x2206, 0xEA14}, {0x2206, 0xE5EA}, {0x2206, 0x15E2}, {0x2206, 0xEA12},
- {0x2206, 0xE3EA}, {0x2206, 0x135A}, {0x2206, 0x8FE6}, {0x2206, 0xEA12},
- {0x2206, 0xE7EA}, {0x2206, 0x13F7}, {0x2206, 0x26E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15F7}, {0x2206, 0x27E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15FD}, {0x2206, 0xFC04}, {0x2206, 0xF8FA},
- {0x2206, 0xEF69}, {0x2206, 0xE08B}, {0x2206, 0x86AD}, {0x2206, 0x2146},
- {0x2206, 0xE0E0}, {0x2206, 0x22E1}, {0x2206, 0xE023}, {0x2206, 0x58C0},
- {0x2206, 0x5902}, {0x2206, 0x1E01}, {0x2206, 0xE18B}, {0x2206, 0x651F},
- {0x2206, 0x109E}, {0x2206, 0x33E4}, {0x2206, 0x8B65}, {0x2206, 0xAD21},
- {0x2206, 0x22AD}, {0x2206, 0x272A}, {0x2206, 0xD400}, {0x2206, 0x01BF},
- {0x2206, 0x34F2}, {0x2206, 0x022C}, {0x2206, 0xA2BF}, {0x2206, 0x34F5},
- {0x2206, 0x022C}, {0x2206, 0xE0E0}, {0x2206, 0x8B67}, {0x2206, 0x1B10},
- {0x2206, 0xAA14}, {0x2206, 0xE18B}, {0x2206, 0x660D}, {0x2206, 0x1459},
- {0x2206, 0x0FAE}, {0x2206, 0x05E1}, {0x2206, 0x8B66}, {0x2206, 0x590F},
- {0x2206, 0xBF85}, {0x2206, 0x6102}, {0x2206, 0x2CA2}, {0x2206, 0xEF96},
- {0x2206, 0xFEFC}, {0x2206, 0x04F8}, {0x2206, 0xF9FA}, {0x2206, 0xFBEF},
- {0x2206, 0x79E2}, {0x2206, 0x8AD2}, {0x2206, 0xAC19}, {0x2206, 0x2DE0},
- {0x2206, 0xE036}, {0x2206, 0xE1E0}, {0x2206, 0x37EF}, {0x2206, 0x311F},
- {0x2206, 0x325B}, {0x2206, 0x019E}, {0x2206, 0x1F7A}, {0x2206, 0x0159},
- {0x2206, 0x019F}, {0x2206, 0x0ABF}, {0x2206, 0x348E}, {0x2206, 0x022C},
- {0x2206, 0x31F6}, {0x2206, 0x06AE}, {0x2206, 0x0FF6}, {0x2206, 0x0302},
- {0x2206, 0x0470}, {0x2206, 0xF703}, {0x2206, 0xF706}, {0x2206, 0xBF34},
- {0x2206, 0x9302}, {0x2206, 0x2C31}, {0x2206, 0xAC1A}, {0x2206, 0x25E0},
- {0x2206, 0xE022}, {0x2206, 0xE1E0}, {0x2206, 0x23EF}, {0x2206, 0x300D},
- {0x2206, 0x311F}, {0x2206, 0x325B}, {0x2206, 0x029E}, {0x2206, 0x157A},
- {0x2206, 0x0258}, {0x2206, 0xC4A0}, {0x2206, 0x0408}, {0x2206, 0xBF34},
- {0x2206, 0x9E02}, {0x2206, 0x2C31}, {0x2206, 0xAE06}, {0x2206, 0xBF34},
- {0x2206, 0x9C02}, {0x2206, 0x2C31}, {0x2206, 0xAC1B}, {0x2206, 0x4AE0},
- {0x2206, 0xE012}, {0x2206, 0xE1E0}, {0x2206, 0x13EF}, {0x2206, 0x300D},
- {0x2206, 0x331F}, {0x2206, 0x325B}, {0x2206, 0x1C9E}, {0x2206, 0x3AEF},
- {0x2206, 0x325B}, {0x2206, 0x1C9F}, {0x2206, 0x09BF}, {0x2206, 0x3498},
- {0x2206, 0x022C}, {0x2206, 0x3102}, {0x2206, 0x83C5}, {0x2206, 0x5A03},
- {0x2206, 0x0D03}, {0x2206, 0x581C}, {0x2206, 0x1E20}, {0x2206, 0x0207},
- {0x2206, 0xA0A0}, {0x2206, 0x000E}, {0x2206, 0x0284}, {0x2206, 0x17AD},
- {0x2206, 0x1817}, {0x2206, 0xBF34}, {0x2206, 0x9A02}, {0x2206, 0x2C31},
- {0x2206, 0xAE0F}, {0x2206, 0xBF34}, {0x2206, 0xC802}, {0x2206, 0x2C31},
- {0x2206, 0xBF34}, {0x2206, 0xC502}, {0x2206, 0x2C31}, {0x2206, 0x0284},
- {0x2206, 0x52E6}, {0x2206, 0x8AD2}, {0x2206, 0xEF97}, {0x2206, 0xFFFE},
- {0x2206, 0xFDFC}, {0x2206, 0x04F8}, {0x2206, 0xBF34}, {0x2206, 0xDA02},
- {0x2206, 0x2CE0}, {0x2206, 0xE58A}, {0x2206, 0xD3BF}, {0x2206, 0x34D4},
- {0x2206, 0x022C}, {0x2206, 0xE00C}, {0x2206, 0x1159}, {0x2206, 0x02E0},
- {0x2206, 0x8AD3}, {0x2206, 0x1E01}, {0x2206, 0xE48A}, {0x2206, 0xD3D1},
- {0x2206, 0x00BF}, {0x2206, 0x34DA}, {0x2206, 0x022C}, {0x2206, 0xA2D1},
- {0x2206, 0x01BF}, {0x2206, 0x34D4}, {0x2206, 0x022C}, {0x2206, 0xA2BF},
- {0x2206, 0x34CB}, {0x2206, 0x022C}, {0x2206, 0xE0E5}, {0x2206, 0x8ACE},
- {0x2206, 0xBF85}, {0x2206, 0x6702}, {0x2206, 0x2CE0}, {0x2206, 0xE58A},
- {0x2206, 0xCFBF}, {0x2206, 0x8564}, {0x2206, 0x022C}, {0x2206, 0xE0E5},
- {0x2206, 0x8AD0}, {0x2206, 0xBF85}, {0x2206, 0x6A02}, {0x2206, 0x2CE0},
- {0x2206, 0xE58A}, {0x2206, 0xD1FC}, {0x2206, 0x04F8}, {0x2206, 0xE18A},
- {0x2206, 0xD1BF}, {0x2206, 0x856A}, {0x2206, 0x022C}, {0x2206, 0xA2E1},
- {0x2206, 0x8AD0}, {0x2206, 0xBF85}, {0x2206, 0x6402}, {0x2206, 0x2CA2},
- {0x2206, 0xE18A}, {0x2206, 0xCFBF}, {0x2206, 0x8567}, {0x2206, 0x022C},
- {0x2206, 0xA2E1}, {0x2206, 0x8ACE}, {0x2206, 0xBF34}, {0x2206, 0xCB02},
- {0x2206, 0x2CA2}, {0x2206, 0xE18A}, {0x2206, 0xD3BF}, {0x2206, 0x34DA},
- {0x2206, 0x022C}, {0x2206, 0xA2E1}, {0x2206, 0x8AD3}, {0x2206, 0x0D11},
- {0x2206, 0xBF34}, {0x2206, 0xD402}, {0x2206, 0x2CA2}, {0x2206, 0xFC04},
- {0x2206, 0xF9A0}, {0x2206, 0x0405}, {0x2206, 0xE38A}, {0x2206, 0xD4AE},
- {0x2206, 0x13A0}, {0x2206, 0x0805}, {0x2206, 0xE38A}, {0x2206, 0xD5AE},
- {0x2206, 0x0BA0}, {0x2206, 0x0C05}, {0x2206, 0xE38A}, {0x2206, 0xD6AE},
- {0x2206, 0x03E3}, {0x2206, 0x8AD7}, {0x2206, 0xEF13}, {0x2206, 0xBF34},
- {0x2206, 0xCB02}, {0x2206, 0x2CA2}, {0x2206, 0xEF13}, {0x2206, 0x0D11},
- {0x2206, 0xBF85}, {0x2206, 0x6702}, {0x2206, 0x2CA2}, {0x2206, 0xEF13},
- {0x2206, 0x0D14}, {0x2206, 0xBF85}, {0x2206, 0x6402}, {0x2206, 0x2CA2},
- {0x2206, 0xEF13}, {0x2206, 0x0D17}, {0x2206, 0xBF85}, {0x2206, 0x6A02},
- {0x2206, 0x2CA2}, {0x2206, 0xFD04}, {0x2206, 0xF8E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD27}, {0x2206, 0x2DE0}, {0x2206, 0xE036}, {0x2206, 0xE1E0},
- {0x2206, 0x37E1}, {0x2206, 0x8B73}, {0x2206, 0x1F10}, {0x2206, 0x9E20},
- {0x2206, 0xE48B}, {0x2206, 0x73AC}, {0x2206, 0x200B}, {0x2206, 0xAC21},
- {0x2206, 0x0DAC}, {0x2206, 0x250F}, {0x2206, 0xAC27}, {0x2206, 0x0EAE},
- {0x2206, 0x0F02}, {0x2206, 0x84CC}, {0x2206, 0xAE0A}, {0x2206, 0x0284},
- {0x2206, 0xD1AE}, {0x2206, 0x05AE}, {0x2206, 0x0302}, {0x2206, 0x84D8},
- {0x2206, 0xFC04}, {0x2206, 0xEE8B}, {0x2206, 0x6800}, {0x2206, 0x0402},
- {0x2206, 0x84E5}, {0x2206, 0x0285}, {0x2206, 0x2804}, {0x2206, 0x0285},
- {0x2206, 0x4904}, {0x2206, 0xEE8B}, {0x2206, 0x6800}, {0x2206, 0xEE8B},
- {0x2206, 0x6902}, {0x2206, 0x04F8}, {0x2206, 0xF9E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD26}, {0x2206, 0x38D0}, {0x2206, 0x0B02}, {0x2206, 0x2B4D},
- {0x2206, 0x5882}, {0x2206, 0x7882}, {0x2206, 0x9F2D}, {0x2206, 0xE08B},
- {0x2206, 0x68E1}, {0x2206, 0x8B69}, {0x2206, 0x1F10}, {0x2206, 0x9EC8},
- {0x2206, 0x10E4}, {0x2206, 0x8B68}, {0x2206, 0xE0E0}, {0x2206, 0x00E1},
- {0x2206, 0xE001}, {0x2206, 0xF727}, {0x2206, 0xE4E0}, {0x2206, 0x00E5},
- {0x2206, 0xE001}, {0x2206, 0xE2E0}, {0x2206, 0x20E3}, {0x2206, 0xE021},
- {0x2206, 0xAD30}, {0x2206, 0xF7F6}, {0x2206, 0x27E4}, {0x2206, 0xE000},
- {0x2206, 0xE5E0}, {0x2206, 0x01FD}, {0x2206, 0xFC04}, {0x2206, 0xF8FA},
- {0x2206, 0xEF69}, {0x2206, 0xE08B}, {0x2206, 0x86AD}, {0x2206, 0x2212},
- {0x2206, 0xE0E0}, {0x2206, 0x14E1}, {0x2206, 0xE015}, {0x2206, 0xAD26},
- {0x2206, 0x9CE1}, {0x2206, 0x85E0}, {0x2206, 0xBF85}, {0x2206, 0x6D02},
- {0x2206, 0x2CA2}, {0x2206, 0xEF96}, {0x2206, 0xFEFC}, {0x2206, 0x04F8},
- {0x2206, 0xFAEF}, {0x2206, 0x69E0}, {0x2206, 0x8B86}, {0x2206, 0xAD22},
- {0x2206, 0x09E1}, {0x2206, 0x85E1}, {0x2206, 0xBF85}, {0x2206, 0x6D02},
- {0x2206, 0x2CA2}, {0x2206, 0xEF96}, {0x2206, 0xFEFC}, {0x2206, 0x0464},
- {0x2206, 0xE48C}, {0x2206, 0xFDE4}, {0x2206, 0x80CA}, {0x2206, 0xE480},
- {0x2206, 0x66E0}, {0x2206, 0x8E70}, {0x2206, 0xE076}, {0x2205, 0xE142},
- {0x2206, 0x0701}, {0x2205, 0xE140}, {0x2206, 0x0405}, {0x220F, 0x0000},
- {0x221F, 0x0000}, {0x2200, 0x1340}, {0x133E, 0x000E}, {0x133F, 0x0010},
- {0x13EB, 0x11BB}
-};
-
-static const struct rtl8367b_initval rtl8367r_vb_initvals_1[] = {
+static const struct rtl8367b_initval rtl8367b_initvals[] = {
{0x1B03, 0x0876}, {0x1200, 0x7FC4}, {0x1305, 0xC000}, {0x121E, 0x03CA},
{0x1233, 0x0352}, {0x1234, 0x0064}, {0x1237, 0x0096}, {0x1238, 0x0078},
{0x1239, 0x0084}, {0x123A, 0x0030}, {0x205F, 0x0002}, {0x2059, 0x1A00},
@@ -730,39 +550,28 @@ static int rtl8367b_write_phy_reg(struct rtl8366_smi *smi,
static int rtl8367b_init_regs(struct rtl8366_smi *smi)
{
const struct rtl8367b_initval *initvals;
- u32 chip_num;
- u32 chip_ver;
- u32 rlvid;
int count;
- int err;
- REG_WR(smi, RTL8367B_RTL_MAGIC_ID_REG, RTL8367B_RTL_MAGIC_ID_VAL);
- REG_RD(smi, RTL8367B_CHIP_NUMBER_REG, &chip_num);
- REG_RD(smi, RTL8367B_CHIP_VER_REG, &chip_ver);
-
- if ((chip_ver == 0x0020 || chip_ver == 0x00A0) && chip_num == 0x6367) {
+ switch (smi->rtl8367b_chip) {
+ case RTL8367B_CHIP_RTL8367RB:
+ case RTL8367B_CHIP_RTL8367R_VB:
+ initvals = rtl8367b_initvals;
+ count = ARRAY_SIZE(rtl8367b_initvals);
+ break;
+ case RTL8367B_CHIP_RTL8367RB_VB:
+ case RTL8367B_CHIP_RTL8367S:
+ case RTL8367B_CHIP_RTL8367S_VB:
initvals = rtl8367c_initvals;
count = ARRAY_SIZE(rtl8367c_initvals);
- } else {
- rlvid = (chip_ver >> RTL8367B_CHIP_VER_RLVID_SHIFT) &
- RTL8367B_CHIP_VER_RLVID_MASK;
- switch (rlvid) {
- case 0:
- initvals = rtl8367r_vb_initvals_0;
- count = ARRAY_SIZE(rtl8367r_vb_initvals_0);
- break;
- case 1:
- initvals = rtl8367r_vb_initvals_1;
- count = ARRAY_SIZE(rtl8367r_vb_initvals_1);
- break;
- default:
- dev_err(smi->parent, "unknow rlvid %u\n", rlvid);
- return -ENODEV;
+ if ((smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) && (smi->emu_vlanmc == NULL)) {
+ smi->emu_vlanmc = kzalloc(sizeof(struct rtl8366_vlan_mc) * smi->num_vlan_mc, GFP_KERNEL);
+ dev_info(smi->parent, "alloc vlan mc emulator");
}
+ break;
+ default:
+ return -ENODEV;
}
- /* TODO: disable RLTP */
-
return rtl8367b_write_initvals(smi, initvals, count);
}
@@ -795,6 +604,7 @@ static int rtl8367b_extif_set_mode(struct rtl8366_smi *smi, int id,
enum rtl8367_extif_mode mode)
{
int err;
+ u32 data;
/* set port mode */
switch (mode) {
@@ -814,6 +624,15 @@ static int rtl8367b_extif_set_mode(struct rtl8366_smi *smi, int id,
RTL8367B_DEBUG1_DP_MASK(id),
(7 << RTL8367B_DEBUG1_DN_SHIFT(id)) |
(7 << RTL8367B_DEBUG1_DP_SHIFT(id)));
+ if ((smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) && (id == 1)) {
+ REG_RMW(smi, RTL8367D_REG_EXT_TXC_DLY, RTL8367D_EXT1_RGMII_TX_DLY_MASK, 0);
+ /* Configure RGMII/MII mux to port 7 if UTP_PORT4 is not RGMII mode */
+ REG_RD(smi, RTL8367D_REG_TOP_CON0, &data);
+ data &= RTL8367D_MAC4_SEL_EXT1_MASK;
+ if (data == 0)
+ REG_RMW(smi, RTL8367D_REG_TOP_CON0, RTL8367D_MAC7_SEL_EXT1_MASK, RTL8367D_MAC7_SEL_EXT1_MASK);
+ REG_RMW(smi, RTL8367D_REG_SDS1_MISC0, RTL8367D_SDS1_MODE_MASK, RTL8367D_PORT_SDS_MODE_DISABLE);
+ }
} else {
REG_RMW(smi, RTL8367B_CHIP_DEBUG2_REG,
RTL8367B_DEBUG2_DRI_EXT2 |
@@ -872,23 +691,31 @@ static int rtl8367b_extif_set_force(struct rtl8366_smi *smi, int id,
u32 val;
int err;
- mask = (RTL8367B_DI_FORCE_MODE |
- RTL8367B_DI_FORCE_NWAY |
- RTL8367B_DI_FORCE_TXPAUSE |
- RTL8367B_DI_FORCE_RXPAUSE |
- RTL8367B_DI_FORCE_LINK |
- RTL8367B_DI_FORCE_DUPLEX |
- RTL8367B_DI_FORCE_SPEED_MASK);
-
- val = pa->speed;
- val |= pa->force_mode ? RTL8367B_DI_FORCE_MODE : 0;
+ val = pa->speed & RTL8367B_DI_FORCE_SPEED_MASK;
val |= pa->nway ? RTL8367B_DI_FORCE_NWAY : 0;
val |= pa->txpause ? RTL8367B_DI_FORCE_TXPAUSE : 0;
val |= pa->rxpause ? RTL8367B_DI_FORCE_RXPAUSE : 0;
val |= pa->link ? RTL8367B_DI_FORCE_LINK : 0;
val |= pa->duplex ? RTL8367B_DI_FORCE_DUPLEX : 0;
- REG_RMW(smi, RTL8367B_DI_FORCE_REG(id), mask, val);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */
+ val |= (pa->speed << RTL8367D_PORT_STATUS_SPEED1_SHIFT) & RTL8367D_PORT_STATUS_SPEED1_MASK;
+ if (smi->cpu_port != UINT_MAX) {
+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT + smi->cpu_port, val);
+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT_EN + smi->cpu_port, pa->force_mode ? 0xffff : 0x0000);
+ }
+ } else {
+ val |= pa->force_mode ? RTL8367B_DI_FORCE_MODE : 0;
+ mask = (RTL8367B_DI_FORCE_MODE |
+ RTL8367B_DI_FORCE_NWAY |
+ RTL8367B_DI_FORCE_TXPAUSE |
+ RTL8367B_DI_FORCE_RXPAUSE |
+ RTL8367B_DI_FORCE_LINK |
+ RTL8367B_DI_FORCE_DUPLEX |
+ RTL8367B_DI_FORCE_SPEED_MASK);
+
+ REG_RMW(smi, RTL8367B_DI_FORCE_REG(id), mask, val);
+ }
return 0;
}
@@ -939,21 +766,56 @@ static int rtl8367b_extif_init(struct rtl8366_smi *smi, int id,
}
#ifdef CONFIG_OF
-static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367b_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
struct rtl8367_extif_config *cfg;
const __be32 *prop;
int size;
int err;
+ unsigned cpu_port;
+ unsigned id = UINT_MAX;
prop = of_get_property(smi->parent->of_node, name, &size);
- if (!prop)
- return rtl8367b_extif_init(smi, id, NULL);
+ if (!prop || (size != (10 * sizeof(*prop)))) {
+ dev_err(smi->parent, "%s property is not defined or invalid\n", name);
+ err = -EINVAL;
+ goto err_init;
+ }
- if (size != (9 * sizeof(*prop))) {
- dev_err(smi->parent, "%s property is invalid\n", name);
- return -EINVAL;
+ cpu_port = be32_to_cpup(prop++);
+ switch (cpu_port) {
+ case RTL8367B_CPU_PORT_NUM:
+ case RTL8367B_CPU_PORT_NUM + 1:
+ case RTL8367B_CPU_PORT_NUM + 2:
+ if (smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367R_VB) { /* for the RTL8367R-VB chip, cpu_port 5 corresponds to extif1 */
+ if (cpu_port == RTL8367B_CPU_PORT_NUM)
+ id = 1;
+ else {
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
+ }
+ } else if (smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) { /* for the RTL8367S-VB chip, cpu_port 7 corresponds to extif1, cpu_port 6 corresponds to extif0 */
+ if (cpu_port != RTL8367B_CPU_PORT_NUM) {
+ id = cpu_port - RTL8367B_CPU_PORT_NUM - 1;
+ } else {
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
+ }
+ } else {
+ id = cpu_port - RTL8367B_CPU_PORT_NUM;
+ }
+ if (smi->cpu_port == UINT_MAX) {
+ dev_info(smi->parent, "cpu_port:%u, assigned to extif%u\n", cpu_port, id);
+ smi->cpu_port = cpu_port;
+ }
+ break;
+ default:
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
}
cfg = kzalloc(sizeof(struct rtl8367_extif_config), GFP_KERNEL);
@@ -973,10 +835,15 @@ static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, int id,
err = rtl8367b_extif_init(smi, id, cfg);
kfree(cfg);
+err_init:
+ if (id != 0) rtl8367b_extif_init(smi, 0, NULL);
+ if (id != 1) rtl8367b_extif_init(smi, 1, NULL);
+ if (id != 2) rtl8367b_extif_init(smi, 2, NULL);
+
return err;
}
#else
-static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367b_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
return -EINVAL;
@@ -997,15 +864,7 @@ static int rtl8367b_setup(struct rtl8366_smi *smi)
/* initialize external interfaces */
if (smi->parent->of_node) {
- err = rtl8367b_extif_init_of(smi, 0, "realtek,extif0");
- if (err)
- return err;
-
- err = rtl8367b_extif_init_of(smi, 1, "realtek,extif1");
- if (err)
- return err;
-
- err = rtl8367b_extif_init_of(smi, 2, "realtek,extif2");
+ err = rtl8367b_extif_init_of(smi, "realtek,extif");
if (err)
return err;
} else {
@@ -1115,8 +974,12 @@ static int rtl8367b_get_vlan_4k(struct rtl8366_smi *smi, u32 vid,
RTL8367B_TA_VLAN0_MEMBER_MASK;
vlan4k->untag = (data[0] >> RTL8367B_TA_VLAN0_UNTAG_SHIFT) &
RTL8367B_TA_VLAN0_UNTAG_MASK;
- vlan4k->fid = (data[1] >> RTL8367B_TA_VLAN1_FID_SHIFT) &
- RTL8367B_TA_VLAN1_FID_MASK;
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ vlan4k->fid = (data[1] >> RTL8367D_TA_VLAN1_FID_SHIFT) &
+ RTL8367D_TA_VLAN1_FID_MASK;
+ else
+ vlan4k->fid = (data[1] >> RTL8367B_TA_VLAN1_FID_SHIFT) &
+ RTL8367B_TA_VLAN1_FID_MASK;
return 0;
}
@@ -1131,7 +994,7 @@ static int rtl8367b_set_vlan_4k(struct rtl8366_smi *smi,
if (vlan4k->vid >= RTL8367B_NUM_VIDS ||
vlan4k->member > RTL8367B_TA_VLAN0_MEMBER_MASK ||
vlan4k->untag > RTL8367B_UNTAG_MASK ||
- vlan4k->fid > RTL8367B_FIDMAX)
+ vlan4k->fid > ((smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) ? RTL8367D_FIDMAX : RTL8367B_FIDMAX))
return -EINVAL;
memset(data, 0, sizeof(data));
@@ -1140,15 +1003,24 @@ static int rtl8367b_set_vlan_4k(struct rtl8366_smi *smi,
RTL8367B_TA_VLAN0_MEMBER_SHIFT;
data[0] |= (vlan4k->untag & RTL8367B_TA_VLAN0_UNTAG_MASK) <<
RTL8367B_TA_VLAN0_UNTAG_SHIFT;
- data[1] = (vlan4k->fid & RTL8367B_TA_VLAN1_FID_MASK) <<
- RTL8367B_TA_VLAN1_FID_SHIFT;
+
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ data[1] = ((vlan4k->fid & RTL8367D_TA_VLAN1_FID_MASK) <<
+ RTL8367D_TA_VLAN1_FID_SHIFT) | 12; /* ivl_svl - BIT(3), svlan_chek_ivl_svl - BIT(2) */
+ else
+ data[1] = (vlan4k->fid & RTL8367B_TA_VLAN1_FID_MASK) <<
+ RTL8367B_TA_VLAN1_FID_SHIFT;
for (i = 0; i < ARRAY_SIZE(data); i++)
REG_WR(smi, RTL8367B_TA_WRDATA_REG(i), data[i]);
/* write VID */
- REG_WR(smi, RTL8367B_TA_ADDR_REG,
- vlan4k->vid & RTL8367B_TA_VLAN_VID_MASK);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ REG_WR(smi, RTL8367B_TA_ADDR_REG,
+ vlan4k->vid & RTL8367D_TA_VLAN_VID_MASK);
+ else
+ REG_WR(smi, RTL8367B_TA_ADDR_REG,
+ vlan4k->vid & RTL8367B_TA_VLAN_VID_MASK);
/* write table access control word */
REG_WR(smi, RTL8367B_TA_CTRL_REG, RTL8367B_TA_CTRL_CVLAN_WRITE);
@@ -1168,6 +1040,14 @@ static int rtl8367b_get_vlan_mc(struct rtl8366_smi *smi, u32 index,
if (index >= RTL8367B_NUM_VLANS)
return -EINVAL;
+ if (smi->emu_vlanmc) { /* use vlan mc emulation */
+ vlanmc->vid = smi->emu_vlanmc[index].vid;
+ vlanmc->member = smi->emu_vlanmc[index].member;
+ vlanmc->fid = smi->emu_vlanmc[index].fid;
+ vlanmc->untag = smi->emu_vlanmc[index].untag;
+ return 0;
+ }
+
for (i = 0; i < ARRAY_SIZE(data); i++)
REG_RD(smi, RTL8367B_VLAN_MC_BASE(index) + i, &data[i]);
@@ -1193,9 +1073,17 @@ static int rtl8367b_set_vlan_mc(struct rtl8366_smi *smi, u32 index,
vlanmc->priority > RTL8367B_PRIORITYMAX ||
vlanmc->member > RTL8367B_VLAN_MC0_MEMBER_MASK ||
vlanmc->untag > RTL8367B_UNTAG_MASK ||
- vlanmc->fid > RTL8367B_FIDMAX)
+ vlanmc->fid > ((smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) ? RTL8367D_FIDMAX : RTL8367B_FIDMAX))
return -EINVAL;
+ if (smi->emu_vlanmc) { /* use vlanmc emulation */
+ smi->emu_vlanmc[index].vid = vlanmc->vid;
+ smi->emu_vlanmc[index].member = vlanmc->member;
+ smi->emu_vlanmc[index].fid = vlanmc->fid;
+ smi->emu_vlanmc[index].untag = vlanmc->untag;
+ return 0;
+ }
+
data[0] = (vlanmc->member & RTL8367B_VLAN_MC0_MEMBER_MASK) <<
RTL8367B_VLAN_MC0_MEMBER_SHIFT;
data[1] = (vlanmc->fid & RTL8367B_VLAN_MC1_FID_MASK) <<
@@ -1218,10 +1106,41 @@ static int rtl8367b_get_mc_index(struct rtl8366_smi *smi, int port, int *val)
if (port >= RTL8367B_NUM_PORTS)
return -EINVAL;
- REG_RD(smi, RTL8367B_VLAN_PVID_CTRL_REG(port), &data);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */
+ int i;
+ struct rtl8366_vlan_mc vlanmc;
- *val = (data >> RTL8367B_VLAN_PVID_CTRL_SHIFT(port)) &
- RTL8367B_VLAN_PVID_CTRL_MASK;
+ err = rtl8366_smi_read_reg(smi, RTL8367D_VLAN_PVID_CTRL_REG(port), &data);
+
+ if (err) {
+ dev_err(smi->parent, "read pvid register 0x%04x fail", RTL8367D_VLAN_PVID_CTRL_REG(port));
+ return err;
+ }
+
+ data &= RTL8367D_VLAN_PVID_CTRL_MASK;
+ for (i = 0; i < smi->num_vlan_mc; i++) {
+ err = rtl8367b_get_vlan_mc(smi, i, &vlanmc);
+
+ if (err) {
+ dev_err(smi->parent, "get vlan mc index %d fail", i);
+ return err;
+ }
+
+ if (data == vlanmc.vid) break;
+ }
+
+ if (i < smi->num_vlan_mc) {
+ *val = i;
+ } else {
+ dev_err(smi->parent, "vlan mc index for pvid %d not found", data);
+ return -EINVAL;
+ }
+ } else {
+ REG_RD(smi, RTL8367B_VLAN_PVID_CTRL_REG(port), &data);
+
+ *val = (data >> RTL8367B_VLAN_PVID_CTRL_SHIFT(port)) &
+ RTL8367B_VLAN_PVID_CTRL_MASK;
+ }
return 0;
}
@@ -1231,7 +1150,28 @@ static int rtl8367b_set_mc_index(struct rtl8366_smi *smi, int port, int index)
if (port >= RTL8367B_NUM_PORTS || index >= RTL8367B_NUM_VLANS)
return -EINVAL;
- return rtl8366_smi_rmwr(smi, RTL8367B_VLAN_PVID_CTRL_REG(port),
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */
+ int pvid, err;
+ struct rtl8366_vlan_mc vlanmc;
+
+ err = rtl8367b_get_vlan_mc(smi, index, &vlanmc);
+
+ if (err) {
+ dev_err(smi->parent, "get vlan mc index %d fail", index);
+ return err;
+ }
+
+ pvid = vlanmc.vid & RTL8367D_VLAN_PVID_CTRL_MASK;
+ err = rtl8366_smi_write_reg(smi, RTL8367D_VLAN_PVID_CTRL_REG(port), pvid);
+
+ if (err) {
+ dev_err(smi->parent, "set port %d pvid %d fail", port, pvid);
+ return err;
+ }
+
+ return 0;
+ } else
+ return rtl8366_smi_rmwr(smi, RTL8367B_VLAN_PVID_CTRL_REG(port),
RTL8367B_VLAN_PVID_CTRL_MASK <<
RTL8367B_VLAN_PVID_CTRL_SHIFT(port),
(index & RTL8367B_VLAN_PVID_CTRL_MASK) <<
@@ -1294,7 +1234,10 @@ static int rtl8367b_sw_get_port_link(struct switch_dev *dev,
if (port >= RTL8367B_NUM_PORTS)
return -EINVAL;
- rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ rtl8366_smi_read_reg(smi, RTL8367D_PORT_STATUS_REG(port), &data);
+ else
+ rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data);
link->link = !!(data & RTL8367B_PORT_STATUS_LINK);
if (!link->link)
@@ -1305,15 +1248,18 @@ static int rtl8367b_sw_get_port_link(struct switch_dev *dev,
link->tx_flow = !!(data & RTL8367B_PORT_STATUS_TXPAUSE);
link->aneg = !!(data & RTL8367B_PORT_STATUS_NWAY);
- speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK) | ((data & RTL8367D_PORT_STATUS_SPEED1_MASK) >> RTL8367D_PORT_STATUS_SPEED1_SHIFT);
+ else
+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK);
switch (speed) {
- case 0:
+ case RTL8367B_PORT_STATUS_SPEED_10:
link->speed = SWITCH_PORT_SPEED_10;
break;
- case 1:
+ case RTL8367B_PORT_STATUS_SPEED_100:
link->speed = SWITCH_PORT_SPEED_100;
break;
- case 2:
+ case RTL8367B_PORT_STATUS_SPEED_1000:
link->speed = SWITCH_PORT_SPEED_1000;
break;
default:
@@ -1530,10 +1476,11 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
const char *chip_name = NULL;
u32 chip_num;
u32 chip_ver;
- u32 chip_mode;
int ret;
- /* TODO: improve chip detection */
+ smi->emu_vlanmc = NULL;
+ smi->rtl8367b_chip = RTL8367B_CHIP_UNKNOWN;
+
rtl8366_smi_write_reg(smi, RTL8367B_RTL_MAGIC_ID_REG,
RTL8367B_RTL_MAGIC_ID_VAL);
@@ -1551,44 +1498,42 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
return ret;
}
- ret = rtl8366_smi_read_reg(smi, RTL8367B_CHIP_MODE_REG, &chip_mode);
- if (ret) {
- dev_err(smi->parent, "unable to read %s register\n",
- "chip mode");
- return ret;
- }
-
switch (chip_ver) {
+ case 0x0010:
+ if (chip_num == 0x6642) {
+ chip_name = "8367S-VB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367S_VB;
+ }
+ break;
case 0x0020:
- if (chip_num == 0x6367)
+ if (chip_num == 0x6367) {
chip_name = "8367RB-VB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB_VB;
+ }
break;
case 0x00A0:
- if (chip_num == 0x6367)
+ if (chip_num == 0x6367) {
chip_name = "8367S";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367S;
+ }
break;
case 0x1000:
chip_name = "8367RB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB;
break;
case 0x1010:
chip_name = "8367R-VB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367R_VB;
}
if (!chip_name) {
dev_err(smi->parent,
- "unknown chip num:%04x ver:%04x, mode:%04x\n",
- chip_num, chip_ver, chip_mode);
+ "unknown chip (num:%04x ver:%04x)\n",
+ chip_num, chip_ver);
return -ENODEV;
}
- dev_info(smi->parent, "RTL%s chip found\n", chip_name);
-
- if (of_property_present(smi->parent->of_node, "realtek,extif2"))
- smi->cpu_port = RTL8367B_CPU_PORT_NUM + 2;
- else if (of_property_present(smi->parent->of_node, "realtek,extif1") && (chip_ver != 0x1010)) /* for the RTL8367R-VB chip, extif1 corresponds to cpu_port 5 */
- smi->cpu_port = RTL8367B_CPU_PORT_NUM + 1;
-
- dev_info(smi->parent, "CPU port: %u\n", smi->cpu_port);
+ dev_info(smi->parent, "RTL%s chip found (num:%04x ver:%04x)\n", chip_name, chip_num, chip_ver);
return 0;
}
@@ -1628,7 +1573,7 @@ static int rtl8367b_probe(struct platform_device *pdev)
smi->cmd_write = 0xb8;
smi->ops = &rtl8367b_smi_ops;
smi->num_ports = RTL8367B_NUM_PORTS;
- smi->cpu_port = RTL8367B_CPU_PORT_NUM;
+ smi->cpu_port = UINT_MAX; /* not defined yet */
smi->num_vlan_mc = RTL8367B_NUM_VLANS;
smi->mib_counters = rtl8367b_mib_counters;
smi->num_mib_counters = ARRAY_SIZE(rtl8367b_mib_counters);
@@ -1649,6 +1594,8 @@ static int rtl8367b_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
rtl8366_smi_cleanup(smi);
err_free_smi:
+ if (smi->emu_vlanmc)
+ kfree(smi->emu_vlanmc);
kfree(smi);
return err;
}
diff --git a/target/linux/generic/files/drivers/net/phy/swconfig.c b/target/linux/generic/files/drivers/net/phy/swconfig.c
index 5fa2b147c6..10dc8d0607 100644
--- a/target/linux/generic/files/drivers/net/phy/swconfig.c
+++ b/target/linux/generic/files/drivers/net/phy/swconfig.c
@@ -24,7 +24,6 @@
#include <linux/skbuff.h>
#include <linux/switch.h>
#include <linux/of.h>
-#include <linux/version.h>
#include <uapi/linux/mii.h>
#define SWCONFIG_DEVNAME "switch%d"
@@ -1054,9 +1053,7 @@ static struct genl_family switch_fam = {
.module = THIS_MODULE,
.ops = swconfig_ops,
.n_ops = ARRAY_SIZE(swconfig_ops),
-#if LINUX_VERSION_CODE > KERNEL_VERSION(6,0,0)
.resv_start_op = SWITCH_CMD_SET_VLAN + 1,
-#endif
};
#ifdef CONFIG_OF
diff --git a/target/linux/generic/files/drivers/net/phy/swconfig_leds.c b/target/linux/generic/files/drivers/net/phy/swconfig_leds.c
index 1d309c046c..1fcd4432b5 100644
--- a/target/linux/generic/files/drivers/net/phy/swconfig_leds.c
+++ b/target/linux/generic/files/drivers/net/phy/swconfig_leds.c
@@ -85,11 +85,7 @@ swconfig_trig_update_port_mask(struct led_trigger *trigger)
sw_trig = (void *) trigger;
port_mask = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
spin_lock(&trigger->leddev_list_lock);
-#else
- read_lock(&trigger->leddev_list_lock);
-#endif
list_for_each(entry, &trigger->led_cdevs) {
struct led_classdev *led_cdev;
struct swconfig_trig_data *trig_data;
@@ -102,11 +98,7 @@ swconfig_trig_update_port_mask(struct led_trigger *trigger)
read_unlock(&trig_data->lock);
}
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
spin_unlock(&trigger->leddev_list_lock);
-#else
- read_unlock(&trigger->leddev_list_lock);
-#endif
sw_trig->port_mask = port_mask;
@@ -426,22 +418,14 @@ swconfig_trig_update_leds(struct switch_led_trigger *sw_trig)
struct led_trigger *trigger;
trigger = &sw_trig->trig;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
spin_lock(&trigger->leddev_list_lock);
-#else
- read_lock(&trigger->leddev_list_lock);
-#endif
list_for_each(entry, &trigger->led_cdevs) {
struct led_classdev *led_cdev;
led_cdev = list_entry(entry, struct led_classdev, trig_list);
swconfig_trig_led_event(sw_trig, led_cdev);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
spin_unlock(&trigger->leddev_list_lock);
-#else
- read_unlock(&trigger->leddev_list_lock);
-#endif
}
static void
diff --git a/target/linux/generic/hack-5.15/204-module_strip.patch b/target/linux/generic/hack-5.15/204-module_strip.patch
deleted file mode 100644
index e650c1b184..0000000000
--- a/target/linux/generic/hack-5.15/204-module_strip.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 16:56:48 +0200
-Subject: build: add a hack for removing non-essential module info
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/module.h | 13 ++++++++-----
- include/linux/moduleparam.h | 15 ++++++++++++---
- init/Kconfig | 7 +++++++
- kernel/module.c | 5 ++++-
- scripts/mod/modpost.c | 12 ++++++++++++
- 5 files changed, 43 insertions(+), 9 deletions(-)
-
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -164,6 +164,7 @@ extern void cleanup_module(void);
-
- /* Generic info of form tag = "info" */
- #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
-+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info)
-
- /* For userspace: you can also call me... */
- #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
-@@ -233,12 +234,12 @@ extern void cleanup_module(void);
- * Author(s), use "Name <email>" or just "Name", for multiple
- * authors use multiple MODULE_AUTHOR() statements/lines.
- */
--#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
-+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author)
-
- /* What your module does. */
--#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
-+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description)
-
--#ifdef MODULE
-+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED)
- /* Creates an alias so file2alias.c can find device table. */
- #define MODULE_DEVICE_TABLE(type, name) \
- extern typeof(name) __mod_##type##__##name##_device_table \
-@@ -265,7 +266,9 @@ extern typeof(name) __mod_##type##__##na
- */
-
- #if defined(MODULE) || !defined(CONFIG_SYSFS)
--#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version)
-+#elif defined(CONFIG_MODULE_STRIPPED)
-+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version)
- #else
- #define MODULE_VERSION(_version) \
- MODULE_INFO(version, _version); \
-@@ -288,7 +291,7 @@ extern typeof(name) __mod_##type##__##na
- /* Optional firmware file (or files) needed by the module
- * format is simply firmware file name. Multiple firmware
- * files require multiple MODULE_FIRMWARE() specifiers */
--#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
-+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware)
-
- #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns)
-
---- a/include/linux/moduleparam.h
-+++ b/include/linux/moduleparam.h
-@@ -20,6 +20,16 @@
- /* Chosen so that structs with an unsigned long line up. */
- #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
-
-+/* This struct is here for syntactic coherency, it is not used */
-+#define __MODULE_INFO_DISABLED(name) \
-+ struct __UNIQUE_ID(name) {}
-+
-+#ifdef CONFIG_MODULE_STRIPPED
-+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name)
-+#else
-+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info)
-+#endif
-+
- #define __MODULE_INFO(tag, name, info) \
- static const char __UNIQUE_ID(name)[] \
- __used __section(".modinfo") __aligned(1) \
-@@ -31,7 +41,7 @@
- /* One for each parameter, describing how to use it. Some files do
- multiple of these per line, so can't just use MODULE_INFO. */
- #define MODULE_PARM_DESC(_parm, desc) \
-- __MODULE_INFO(parm, _parm, #_parm ":" desc)
-+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc)
-
- struct kernel_param;
-
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -2356,6 +2356,13 @@ config UNUSED_KSYMS_WHITELIST
- one per line. The path can be absolute, or relative to the kernel
- source tree.
-
-+config MODULE_STRIPPED
-+ bool "Reduce module size"
-+ depends on MODULES
-+ help
-+ Remove module parameter descriptions, author info, version, aliases,
-+ device tables, etc.
-+
- endif # MODULES
-
- config MODULES_TREE_LOOKUP
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -1218,6 +1218,7 @@ static struct module_attribute *modinfo_
-
- static const char vermagic[] = VERMAGIC_STRING;
-
-+#if defined(CONFIG_MODVERSIONS) || !defined(CONFIG_MODULE_STRIPPED)
- static int try_to_force_load(struct module *mod, const char *reason)
- {
- #ifdef CONFIG_MODULE_FORCE_LOAD
-@@ -1229,6 +1230,7 @@ static int try_to_force_load(struct modu
- return -ENOEXEC;
- #endif
- }
-+#endif
-
- #ifdef CONFIG_MODVERSIONS
-
-@@ -3274,9 +3276,11 @@ static int setup_load_info(struct load_i
-
- static int check_modinfo(struct module *mod, struct load_info *info, int flags)
- {
-- const char *modmagic = get_modinfo(info, "vermagic");
- int err;
-
-+#ifndef CONFIG_MODULE_STRIPPED
-+ const char *modmagic = get_modinfo(info, "vermagic");
-+
- if (flags & MODULE_INIT_IGNORE_VERMAGIC)
- modmagic = NULL;
-
-@@ -3297,6 +3301,7 @@ static int check_modinfo(struct module *
- mod->name);
- add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
- }
-+#endif
-
- check_modinfo_retpoline(mod, info);
-
---- a/scripts/mod/modpost.c
-+++ b/scripts/mod/modpost.c
-@@ -2000,7 +2000,9 @@ static void read_symbols(const char *mod
- symname = remove_dot(info.strtab + sym->st_name);
-
- handle_symbol(mod, &info, sym, symname);
-+#ifndef CONFIG_MODULE_STRIPPED
- handle_moddevtable(mod, &info, sym, symname);
-+#endif
- }
-
- for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
-@@ -2179,8 +2181,10 @@ static void add_header(struct buffer *b,
- buf_printf(b, "BUILD_SALT;\n");
- buf_printf(b, "BUILD_LTO_INFO;\n");
- buf_printf(b, "\n");
-+#ifndef CONFIG_MODULE_STRIPPED
- buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
- buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
-+#endif
- buf_printf(b, "\n");
- buf_printf(b, "__visible struct module __this_module\n");
- buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
-@@ -2197,8 +2201,10 @@ static void add_header(struct buffer *b,
-
- static void add_intree_flag(struct buffer *b, int is_intree)
- {
-+#ifndef CONFIG_MODULE_STRIPPED
- if (is_intree)
- buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
-+#endif
- }
-
- /* Cannot check for assembler */
-@@ -2211,8 +2217,10 @@ static void add_retpoline(struct buffer
-
- static void add_staging_flag(struct buffer *b, const char *name)
- {
-+#ifndef CONFIG_MODULE_STRIPPED
- if (strstarts(name, "drivers/staging"))
- buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
-+#endif
- }
-
- /**
-@@ -2292,11 +2300,13 @@ static void add_depends(struct buffer *b
-
- static void add_srcversion(struct buffer *b, struct module *mod)
- {
-+#ifndef CONFIG_MODULE_STRIPPED
- if (mod->srcversion[0]) {
- buf_printf(b, "\n");
- buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
- mod->srcversion);
- }
-+#endif
- }
-
- static void write_buf(struct buffer *b, const char *fname)
-@@ -2545,7 +2555,9 @@ int main(int argc, char **argv)
- add_staging_flag(&buf, mod->name);
- add_versions(&buf, mod);
- add_depends(&buf, mod);
-+#ifndef CONFIG_MODULE_STRIPPED
- add_moddevtable(&buf, mod);
-+#endif
- add_srcversion(&buf, mod);
-
- sprintf(fname, "%s.mod.c", mod->name);
diff --git a/target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch b/target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch
deleted file mode 100644
index a87c7a5116..0000000000
--- a/target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 310e8e04a05d9eb43fa9dd7f00143300afcaa37a Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Fri, 11 Nov 2022 13:33:44 +0100
-Subject: [PATCH] kconfig: abort configuration on unset symbol
-
-When a target configuration has unset Kconfig symbols, the build will
-fail when OpenWrt is compiled with V=s and stdin is connected to a tty.
-
-In case OpenWrt is compiled without either of these preconditions, the
-build will succeed with the symbols in question being unset.
-
-Modify the kernel configuration in a way it fails on unset symbols
-regardless of the aforementioned preconditions.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- scripts/kconfig/conf.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/scripts/kconfig/conf.c
-+++ b/scripts/kconfig/conf.c
-@@ -341,6 +341,9 @@ static int conf_askvalue(struct symbol *
- }
- /* fall through */
- default:
-+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) {
-+ exit(1);
-+ }
- fflush(stdout);
- xfgets(line, sizeof(line), stdin);
- break;
-@@ -523,6 +526,9 @@ static int conf_choice(struct menu *menu
- }
- /* fall through */
- case oldaskconfig:
-+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) {
-+ exit(1);
-+ }
- fflush(stdout);
- xfgets(line, sizeof(line), stdin);
- strip(line);
diff --git a/target/linux/generic/hack-5.15/210-darwin_scripts_include.patch b/target/linux/generic/hack-5.15/210-darwin_scripts_include.patch
deleted file mode 100644
index be6adc0d11..0000000000
--- a/target/linux/generic/hack-5.15/210-darwin_scripts_include.patch
+++ /dev/null
@@ -1,3053 +0,0 @@
-From db7c30dcd9a0391bf13b62c9f91e144d762ef43a Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Fri, 7 Jul 2017 17:00:49 +0200
-Subject: Add an OSX specific patch to make the kernel be compiled
-
-lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- scripts/kconfig/Makefile | 3 +
- scripts/mod/elf.h | 3007 ++++++++++++++++++++++++++++++++++++++++++++
- scripts/mod/mk_elfconfig.c | 4 +
- scripts/mod/modpost.h | 4 +
- 4 files changed, 3018 insertions(+)
- create mode 100644 scripts/mod/elf.h
-
---- /dev/null
-+++ b/scripts/mod/elf.h
-@@ -0,0 +1,3007 @@
-+/* This file defines standard ELF types, structures, and macros.
-+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#ifndef _ELF_H
-+#define _ELF_H 1
-+
-+/* Standard ELF types. */
-+
-+#include <stdint.h>
-+
-+/* Type for a 16-bit quantity. */
-+typedef uint16_t Elf32_Half;
-+typedef uint16_t Elf64_Half;
-+
-+/* Types for signed and unsigned 32-bit quantities. */
-+typedef uint32_t Elf32_Word;
-+typedef int32_t Elf32_Sword;
-+typedef uint32_t Elf64_Word;
-+typedef int32_t Elf64_Sword;
-+
-+/* Types for signed and unsigned 64-bit quantities. */
-+typedef uint64_t Elf32_Xword;
-+typedef int64_t Elf32_Sxword;
-+typedef uint64_t Elf64_Xword;
-+typedef int64_t Elf64_Sxword;
-+
-+/* Type of addresses. */
-+typedef uint32_t Elf32_Addr;
-+typedef uint64_t Elf64_Addr;
-+
-+/* Type of file offsets. */
-+typedef uint32_t Elf32_Off;
-+typedef uint64_t Elf64_Off;
-+
-+/* Type for section indices, which are 16-bit quantities. */
-+typedef uint16_t Elf32_Section;
-+typedef uint16_t Elf64_Section;
-+
-+/* Type for version symbol information. */
-+typedef Elf32_Half Elf32_Versym;
-+typedef Elf64_Half Elf64_Versym;
-+
-+
-+/* The ELF file header. This appears at the start of every ELF file. */
-+
-+#define EI_NIDENT (16)
-+
-+typedef struct
-+{
-+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
-+ Elf32_Half e_type; /* Object file type */
-+ Elf32_Half e_machine; /* Architecture */
-+ Elf32_Word e_version; /* Object file version */
-+ Elf32_Addr e_entry; /* Entry point virtual address */
-+ Elf32_Off e_phoff; /* Program header table file offset */
-+ Elf32_Off e_shoff; /* Section header table file offset */
-+ Elf32_Word e_flags; /* Processor-specific flags */
-+ Elf32_Half e_ehsize; /* ELF header size in bytes */
-+ Elf32_Half e_phentsize; /* Program header table entry size */
-+ Elf32_Half e_phnum; /* Program header table entry count */
-+ Elf32_Half e_shentsize; /* Section header table entry size */
-+ Elf32_Half e_shnum; /* Section header table entry count */
-+ Elf32_Half e_shstrndx; /* Section header string table index */
-+} Elf32_Ehdr;
-+
-+typedef struct
-+{
-+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
-+ Elf64_Half e_type; /* Object file type */
-+ Elf64_Half e_machine; /* Architecture */
-+ Elf64_Word e_version; /* Object file version */
-+ Elf64_Addr e_entry; /* Entry point virtual address */
-+ Elf64_Off e_phoff; /* Program header table file offset */
-+ Elf64_Off e_shoff; /* Section header table file offset */
-+ Elf64_Word e_flags; /* Processor-specific flags */
-+ Elf64_Half e_ehsize; /* ELF header size in bytes */
-+ Elf64_Half e_phentsize; /* Program header table entry size */
-+ Elf64_Half e_phnum; /* Program header table entry count */
-+ Elf64_Half e_shentsize; /* Section header table entry size */
-+ Elf64_Half e_shnum; /* Section header table entry count */
-+ Elf64_Half e_shstrndx; /* Section header string table index */
-+} Elf64_Ehdr;
-+
-+/* Fields in the e_ident array. The EI_* macros are indices into the
-+ array. The macros under each EI_* macro are the values the byte
-+ may have. */
-+
-+#define EI_MAG0 0 /* File identification byte 0 index */
-+#define ELFMAG0 0x7f /* Magic number byte 0 */
-+
-+#define EI_MAG1 1 /* File identification byte 1 index */
-+#define ELFMAG1 'E' /* Magic number byte 1 */
-+
-+#define EI_MAG2 2 /* File identification byte 2 index */
-+#define ELFMAG2 'L' /* Magic number byte 2 */
-+
-+#define EI_MAG3 3 /* File identification byte 3 index */
-+#define ELFMAG3 'F' /* Magic number byte 3 */
-+
-+/* Conglomeration of the identification bytes, for easy testing as a word. */
-+#define ELFMAG "\177ELF"
-+#define SELFMAG 4
-+
-+#define EI_CLASS 4 /* File class byte index */
-+#define ELFCLASSNONE 0 /* Invalid class */
-+#define ELFCLASS32 1 /* 32-bit objects */
-+#define ELFCLASS64 2 /* 64-bit objects */
-+#define ELFCLASSNUM 3
-+
-+#define EI_DATA 5 /* Data encoding byte index */
-+#define ELFDATANONE 0 /* Invalid data encoding */
-+#define ELFDATA2LSB 1 /* 2's complement, little endian */
-+#define ELFDATA2MSB 2 /* 2's complement, big endian */
-+#define ELFDATANUM 3
-+
-+#define EI_VERSION 6 /* File version byte index */
-+ /* Value must be EV_CURRENT */
-+
-+#define EI_OSABI 7 /* OS ABI identification */
-+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
-+#define ELFOSABI_SYSV 0 /* Alias. */
-+#define ELFOSABI_HPUX 1 /* HP-UX */
-+#define ELFOSABI_NETBSD 2 /* NetBSD. */
-+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
-+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
-+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
-+#define ELFOSABI_AIX 7 /* IBM AIX. */
-+#define ELFOSABI_IRIX 8 /* SGI Irix. */
-+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
-+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
-+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
-+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
-+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
-+#define ELFOSABI_ARM 97 /* ARM */
-+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
-+
-+#define EI_ABIVERSION 8 /* ABI version */
-+
-+#define EI_PAD 9 /* Byte index of padding bytes */
-+
-+/* Legal values for e_type (object file type). */
-+
-+#define ET_NONE 0 /* No file type */
-+#define ET_REL 1 /* Relocatable file */
-+#define ET_EXEC 2 /* Executable file */
-+#define ET_DYN 3 /* Shared object file */
-+#define ET_CORE 4 /* Core file */
-+#define ET_NUM 5 /* Number of defined types */
-+#define ET_LOOS 0xfe00 /* OS-specific range start */
-+#define ET_HIOS 0xfeff /* OS-specific range end */
-+#define ET_LOPROC 0xff00 /* Processor-specific range start */
-+#define ET_HIPROC 0xffff /* Processor-specific range end */
-+
-+/* Legal values for e_machine (architecture). */
-+
-+#define EM_NONE 0 /* No machine */
-+#define EM_M32 1 /* AT&T WE 32100 */
-+#define EM_SPARC 2 /* SUN SPARC */
-+#define EM_386 3 /* Intel 80386 */
-+#define EM_68K 4 /* Motorola m68k family */
-+#define EM_88K 5 /* Motorola m88k family */
-+#define EM_860 7 /* Intel 80860 */
-+#define EM_MIPS 8 /* MIPS R3000 big-endian */
-+#define EM_S370 9 /* IBM System/370 */
-+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
-+
-+#define EM_PARISC 15 /* HPPA */
-+#define EM_VPP500 17 /* Fujitsu VPP500 */
-+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
-+#define EM_960 19 /* Intel 80960 */
-+#define EM_PPC 20 /* PowerPC */
-+#define EM_PPC64 21 /* PowerPC 64-bit */
-+#define EM_S390 22 /* IBM S390 */
-+
-+#define EM_V800 36 /* NEC V800 series */
-+#define EM_FR20 37 /* Fujitsu FR20 */
-+#define EM_RH32 38 /* TRW RH-32 */
-+#define EM_RCE 39 /* Motorola RCE */
-+#define EM_ARM 40 /* ARM */
-+#define EM_FAKE_ALPHA 41 /* Digital Alpha */
-+#define EM_SH 42 /* Hitachi SH */
-+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-+#define EM_TRICORE 44 /* Siemens Tricore */
-+#define EM_ARC 45 /* Argonaut RISC Core */
-+#define EM_H8_300 46 /* Hitachi H8/300 */
-+#define EM_H8_300H 47 /* Hitachi H8/300H */
-+#define EM_H8S 48 /* Hitachi H8S */
-+#define EM_H8_500 49 /* Hitachi H8/500 */
-+#define EM_IA_64 50 /* Intel Merced */
-+#define EM_MIPS_X 51 /* Stanford MIPS-X */
-+#define EM_COLDFIRE 52 /* Motorola Coldfire */
-+#define EM_68HC12 53 /* Motorola M68HC12 */
-+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
-+#define EM_PCP 55 /* Siemens PCP */
-+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
-+#define EM_NDR1 57 /* Denso NDR1 microprocessor */
-+#define EM_STARCORE 58 /* Motorola Start*Core processor */
-+#define EM_ME16 59 /* Toyota ME16 processor */
-+#define EM_ST100 60 /* STMicroelectronic ST100 processor */
-+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
-+#define EM_X86_64 62 /* AMD x86-64 architecture */
-+#define EM_PDSP 63 /* Sony DSP Processor */
-+
-+#define EM_FX66 66 /* Siemens FX66 microcontroller */
-+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
-+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
-+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
-+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
-+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
-+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
-+#define EM_SVX 73 /* Silicon Graphics SVx */
-+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
-+#define EM_VAX 75 /* Digital VAX */
-+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
-+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
-+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
-+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
-+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
-+#define EM_HUANY 81 /* Harvard University machine-independent object files */
-+#define EM_PRISM 82 /* SiTera Prism */
-+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
-+#define EM_FR30 84 /* Fujitsu FR30 */
-+#define EM_D10V 85 /* Mitsubishi D10V */
-+#define EM_D30V 86 /* Mitsubishi D30V */
-+#define EM_V850 87 /* NEC v850 */
-+#define EM_M32R 88 /* Mitsubishi M32R */
-+#define EM_MN10300 89 /* Matsushita MN10300 */
-+#define EM_MN10200 90 /* Matsushita MN10200 */
-+#define EM_PJ 91 /* picoJava */
-+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
-+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
-+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
-+#define EM_TILEPRO 188 /* Tilera TILEPro */
-+#define EM_TILEGX 191 /* Tilera TILE-Gx */
-+#define EM_NUM 192
-+
-+/* If it is necessary to assign new unofficial EM_* values, please
-+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
-+ chances of collision with official or non-GNU unofficial values. */
-+
-+#define EM_ALPHA 0x9026
-+
-+/* Legal values for e_version (version). */
-+
-+#define EV_NONE 0 /* Invalid ELF version */
-+#define EV_CURRENT 1 /* Current version */
-+#define EV_NUM 2
-+
-+/* Section header. */
-+
-+typedef struct
-+{
-+ Elf32_Word sh_name; /* Section name (string tbl index) */
-+ Elf32_Word sh_type; /* Section type */
-+ Elf32_Word sh_flags; /* Section flags */
-+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
-+ Elf32_Off sh_offset; /* Section file offset */
-+ Elf32_Word sh_size; /* Section size in bytes */
-+ Elf32_Word sh_link; /* Link to another section */
-+ Elf32_Word sh_info; /* Additional section information */
-+ Elf32_Word sh_addralign; /* Section alignment */
-+ Elf32_Word sh_entsize; /* Entry size if section holds table */
-+} Elf32_Shdr;
-+
-+typedef struct
-+{
-+ Elf64_Word sh_name; /* Section name (string tbl index) */
-+ Elf64_Word sh_type; /* Section type */
-+ Elf64_Xword sh_flags; /* Section flags */
-+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
-+ Elf64_Off sh_offset; /* Section file offset */
-+ Elf64_Xword sh_size; /* Section size in bytes */
-+ Elf64_Word sh_link; /* Link to another section */
-+ Elf64_Word sh_info; /* Additional section information */
-+ Elf64_Xword sh_addralign; /* Section alignment */
-+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
-+} Elf64_Shdr;
-+
-+/* Special section indices. */
-+
-+#define SHN_UNDEF 0 /* Undefined section */
-+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
-+#define SHN_LOPROC 0xff00 /* Start of processor-specific */
-+#define SHN_BEFORE 0xff00 /* Order section before all others
-+ (Solaris). */
-+#define SHN_AFTER 0xff01 /* Order section after all others
-+ (Solaris). */
-+#define SHN_HIPROC 0xff1f /* End of processor-specific */
-+#define SHN_LOOS 0xff20 /* Start of OS-specific */
-+#define SHN_HIOS 0xff3f /* End of OS-specific */
-+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
-+#define SHN_COMMON 0xfff2 /* Associated symbol is common */
-+#define SHN_XINDEX 0xffff /* Index is in extra table. */
-+#define SHN_HIRESERVE 0xffff /* End of reserved indices */
-+
-+/* Legal values for sh_type (section type). */
-+
-+#define SHT_NULL 0 /* Section header table entry unused */
-+#define SHT_PROGBITS 1 /* Program data */
-+#define SHT_SYMTAB 2 /* Symbol table */
-+#define SHT_STRTAB 3 /* String table */
-+#define SHT_RELA 4 /* Relocation entries with addends */
-+#define SHT_HASH 5 /* Symbol hash table */
-+#define SHT_DYNAMIC 6 /* Dynamic linking information */
-+#define SHT_NOTE 7 /* Notes */
-+#define SHT_NOBITS 8 /* Program space with no data (bss) */
-+#define SHT_REL 9 /* Relocation entries, no addends */
-+#define SHT_SHLIB 10 /* Reserved */
-+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
-+#define SHT_INIT_ARRAY 14 /* Array of constructors */
-+#define SHT_FINI_ARRAY 15 /* Array of destructors */
-+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
-+#define SHT_GROUP 17 /* Section group */
-+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
-+#define SHT_NUM 19 /* Number of defined types. */
-+#define SHT_LOOS 0x60000000 /* Start OS-specific. */
-+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
-+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
-+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
-+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
-+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
-+#define SHT_SUNW_move 0x6ffffffa
-+#define SHT_SUNW_COMDAT 0x6ffffffb
-+#define SHT_SUNW_syminfo 0x6ffffffc
-+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
-+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
-+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
-+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
-+#define SHT_HIOS 0x6fffffff /* End OS-specific type */
-+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
-+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
-+#define SHT_LOUSER 0x80000000 /* Start of application-specific */
-+#define SHT_HIUSER 0x8fffffff /* End of application-specific */
-+
-+/* Legal values for sh_flags (section flags). */
-+
-+#define SHF_WRITE (1 << 0) /* Writable */
-+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
-+#define SHF_EXECINSTR (1 << 2) /* Executable */
-+#define SHF_MERGE (1 << 4) /* Might be merged */
-+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
-+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
-+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
-+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
-+ required */
-+#define SHF_GROUP (1 << 9) /* Section is member of a group. */
-+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
-+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
-+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
-+#define SHF_ORDERED (1 << 30) /* Special ordering requirement
-+ (Solaris). */
-+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
-+ referenced or allocated (Solaris).*/
-+
-+/* Section group handling. */
-+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
-+
-+/* Symbol table entry. */
-+
-+typedef struct
-+{
-+ Elf32_Word st_name; /* Symbol name (string tbl index) */
-+ Elf32_Addr st_value; /* Symbol value */
-+ Elf32_Word st_size; /* Symbol size */
-+ unsigned char st_info; /* Symbol type and binding */
-+ unsigned char st_other; /* Symbol visibility */
-+ Elf32_Section st_shndx; /* Section index */
-+} Elf32_Sym;
-+
-+typedef struct
-+{
-+ Elf64_Word st_name; /* Symbol name (string tbl index) */
-+ unsigned char st_info; /* Symbol type and binding */
-+ unsigned char st_other; /* Symbol visibility */
-+ Elf64_Section st_shndx; /* Section index */
-+ Elf64_Addr st_value; /* Symbol value */
-+ Elf64_Xword st_size; /* Symbol size */
-+} Elf64_Sym;
-+
-+/* The syminfo section if available contains additional information about
-+ every dynamic symbol. */
-+
-+typedef struct
-+{
-+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */
-+ Elf32_Half si_flags; /* Per symbol flags */
-+} Elf32_Syminfo;
-+
-+typedef struct
-+{
-+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */
-+ Elf64_Half si_flags; /* Per symbol flags */
-+} Elf64_Syminfo;
-+
-+/* Possible values for si_boundto. */
-+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
-+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */
-+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */
-+
-+/* Possible bitmasks for si_flags. */
-+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */
-+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */
-+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */
-+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy
-+ loaded */
-+/* Syminfo version values. */
-+#define SYMINFO_NONE 0
-+#define SYMINFO_CURRENT 1
-+#define SYMINFO_NUM 2
-+
-+
-+/* How to extract and insert information held in the st_info field. */
-+
-+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
-+#define ELF32_ST_TYPE(val) ((val) & 0xf)
-+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
-+
-+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
-+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
-+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
-+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
-+
-+/* Legal values for ST_BIND subfield of st_info (symbol binding). */
-+
-+#define STB_LOCAL 0 /* Local symbol */
-+#define STB_GLOBAL 1 /* Global symbol */
-+#define STB_WEAK 2 /* Weak symbol */
-+#define STB_NUM 3 /* Number of defined types. */
-+#define STB_LOOS 10 /* Start of OS-specific */
-+#define STB_GNU_UNIQUE 10 /* Unique symbol. */
-+#define STB_HIOS 12 /* End of OS-specific */
-+#define STB_LOPROC 13 /* Start of processor-specific */
-+#define STB_HIPROC 15 /* End of processor-specific */
-+
-+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-+
-+#define STT_NOTYPE 0 /* Symbol type is unspecified */
-+#define STT_OBJECT 1 /* Symbol is a data object */
-+#define STT_FUNC 2 /* Symbol is a code object */
-+#define STT_SECTION 3 /* Symbol associated with a section */
-+#define STT_FILE 4 /* Symbol's name is file name */
-+#define STT_COMMON 5 /* Symbol is a common data object */
-+#define STT_TLS 6 /* Symbol is thread-local data object*/
-+#define STT_NUM 7 /* Number of defined types. */
-+#define STT_LOOS 10 /* Start of OS-specific */
-+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
-+#define STT_HIOS 12 /* End of OS-specific */
-+#define STT_LOPROC 13 /* Start of processor-specific */
-+#define STT_HIPROC 15 /* End of processor-specific */
-+
-+
-+/* Symbol table indices are found in the hash buckets and chain table
-+ of a symbol hash table section. This special index value indicates
-+ the end of a chain, meaning no further symbols are found in that bucket. */
-+
-+#define STN_UNDEF 0 /* End of a chain. */
-+
-+
-+/* How to extract and insert information held in the st_other field. */
-+
-+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
-+
-+/* For ELF64 the definitions are the same. */
-+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
-+
-+/* Symbol visibility specification encoded in the st_other field. */
-+#define STV_DEFAULT 0 /* Default symbol visibility rules */
-+#define STV_INTERNAL 1 /* Processor specific hidden class */
-+#define STV_HIDDEN 2 /* Sym unavailable in other modules */
-+#define STV_PROTECTED 3 /* Not preemptible, not exported */
-+
-+
-+/* Relocation table entry without addend (in section of type SHT_REL). */
-+
-+typedef struct
-+{
-+ Elf32_Addr r_offset; /* Address */
-+ Elf32_Word r_info; /* Relocation type and symbol index */
-+} Elf32_Rel;
-+
-+/* I have seen two different definitions of the Elf64_Rel and
-+ Elf64_Rela structures, so we'll leave them out until Novell (or
-+ whoever) gets their act together. */
-+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */
-+
-+typedef struct
-+{
-+ Elf64_Addr r_offset; /* Address */
-+ Elf64_Xword r_info; /* Relocation type and symbol index */
-+} Elf64_Rel;
-+
-+/* Relocation table entry with addend (in section of type SHT_RELA). */
-+
-+typedef struct
-+{
-+ Elf32_Addr r_offset; /* Address */
-+ Elf32_Word r_info; /* Relocation type and symbol index */
-+ Elf32_Sword r_addend; /* Addend */
-+} Elf32_Rela;
-+
-+typedef struct
-+{
-+ Elf64_Addr r_offset; /* Address */
-+ Elf64_Xword r_info; /* Relocation type and symbol index */
-+ Elf64_Sxword r_addend; /* Addend */
-+} Elf64_Rela;
-+
-+/* How to extract and insert information held in the r_info field. */
-+
-+#define ELF32_R_SYM(val) ((val) >> 8)
-+#define ELF32_R_TYPE(val) ((val) & 0xff)
-+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
-+
-+#define ELF64_R_SYM(i) ((i) >> 32)
-+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
-+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
-+
-+/* Program segment header. */
-+
-+typedef struct
-+{
-+ Elf32_Word p_type; /* Segment type */
-+ Elf32_Off p_offset; /* Segment file offset */
-+ Elf32_Addr p_vaddr; /* Segment virtual address */
-+ Elf32_Addr p_paddr; /* Segment physical address */
-+ Elf32_Word p_filesz; /* Segment size in file */
-+ Elf32_Word p_memsz; /* Segment size in memory */
-+ Elf32_Word p_flags; /* Segment flags */
-+ Elf32_Word p_align; /* Segment alignment */
-+} Elf32_Phdr;
-+
-+typedef struct
-+{
-+ Elf64_Word p_type; /* Segment type */
-+ Elf64_Word p_flags; /* Segment flags */
-+ Elf64_Off p_offset; /* Segment file offset */
-+ Elf64_Addr p_vaddr; /* Segment virtual address */
-+ Elf64_Addr p_paddr; /* Segment physical address */
-+ Elf64_Xword p_filesz; /* Segment size in file */
-+ Elf64_Xword p_memsz; /* Segment size in memory */
-+ Elf64_Xword p_align; /* Segment alignment */
-+} Elf64_Phdr;
-+
-+/* Special value for e_phnum. This indicates that the real number of
-+ program headers is too large to fit into e_phnum. Instead the real
-+ value is in the field sh_info of section 0. */
-+
-+#define PN_XNUM 0xffff
-+
-+/* Legal values for p_type (segment type). */
-+
-+#define PT_NULL 0 /* Program header table entry unused */
-+#define PT_LOAD 1 /* Loadable program segment */
-+#define PT_DYNAMIC 2 /* Dynamic linking information */
-+#define PT_INTERP 3 /* Program interpreter */
-+#define PT_NOTE 4 /* Auxiliary information */
-+#define PT_SHLIB 5 /* Reserved */
-+#define PT_PHDR 6 /* Entry for header table itself */
-+#define PT_TLS 7 /* Thread-local storage segment */
-+#define PT_NUM 8 /* Number of defined types */
-+#define PT_LOOS 0x60000000 /* Start of OS-specific */
-+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
-+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
-+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
-+#define PT_LOSUNW 0x6ffffffa
-+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
-+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
-+#define PT_HISUNW 0x6fffffff
-+#define PT_HIOS 0x6fffffff /* End of OS-specific */
-+#define PT_LOPROC 0x70000000 /* Start of processor-specific */
-+#define PT_HIPROC 0x7fffffff /* End of processor-specific */
-+
-+/* Legal values for p_flags (segment flags). */
-+
-+#define PF_X (1 << 0) /* Segment is executable */
-+#define PF_W (1 << 1) /* Segment is writable */
-+#define PF_R (1 << 2) /* Segment is readable */
-+#define PF_MASKOS 0x0ff00000 /* OS-specific */
-+#define PF_MASKPROC 0xf0000000 /* Processor-specific */
-+
-+/* Legal values for note segment descriptor types for core files. */
-+
-+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
-+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
-+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
-+#define NT_PRXREG 4 /* Contains copy of prxregset struct */
-+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */
-+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */
-+#define NT_AUXV 6 /* Contains copy of auxv array */
-+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */
-+#define NT_ASRS 8 /* Contains copy of asrset struct */
-+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */
-+#define NT_PSINFO 13 /* Contains copy of psinfo struct */
-+#define NT_PRCRED 14 /* Contains copy of prcred struct */
-+#define NT_UTSNAME 15 /* Contains copy of utsname struct */
-+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
-+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
-+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
-+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
-+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
-+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
-+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
-+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
-+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
-+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
-+
-+/* Legal values for the note segment descriptor types for object files. */
-+
-+#define NT_VERSION 1 /* Contains a version string. */
-+
-+
-+/* Dynamic section entry. */
-+
-+typedef struct
-+{
-+ Elf32_Sword d_tag; /* Dynamic entry type */
-+ union
-+ {
-+ Elf32_Word d_val; /* Integer value */
-+ Elf32_Addr d_ptr; /* Address value */
-+ } d_un;
-+} Elf32_Dyn;
-+
-+typedef struct
-+{
-+ Elf64_Sxword d_tag; /* Dynamic entry type */
-+ union
-+ {
-+ Elf64_Xword d_val; /* Integer value */
-+ Elf64_Addr d_ptr; /* Address value */
-+ } d_un;
-+} Elf64_Dyn;
-+
-+/* Legal values for d_tag (dynamic entry type). */
-+
-+#define DT_NULL 0 /* Marks end of dynamic section */
-+#define DT_NEEDED 1 /* Name of needed library */
-+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
-+#define DT_PLTGOT 3 /* Processor defined value */
-+#define DT_HASH 4 /* Address of symbol hash table */
-+#define DT_STRTAB 5 /* Address of string table */
-+#define DT_SYMTAB 6 /* Address of symbol table */
-+#define DT_RELA 7 /* Address of Rela relocs */
-+#define DT_RELASZ 8 /* Total size of Rela relocs */
-+#define DT_RELAENT 9 /* Size of one Rela reloc */
-+#define DT_STRSZ 10 /* Size of string table */
-+#define DT_SYMENT 11 /* Size of one symbol table entry */
-+#define DT_INIT 12 /* Address of init function */
-+#define DT_FINI 13 /* Address of termination function */
-+#define DT_SONAME 14 /* Name of shared object */
-+#define DT_RPATH 15 /* Library search path (deprecated) */
-+#define DT_SYMBOLIC 16 /* Start symbol search here */
-+#define DT_REL 17 /* Address of Rel relocs */
-+#define DT_RELSZ 18 /* Total size of Rel relocs */
-+#define DT_RELENT 19 /* Size of one Rel reloc */
-+#define DT_PLTREL 20 /* Type of reloc in PLT */
-+#define DT_DEBUG 21 /* For debugging; unspecified */
-+#define DT_TEXTREL 22 /* Reloc might modify .text */
-+#define DT_JMPREL 23 /* Address of PLT relocs */
-+#define DT_BIND_NOW 24 /* Process relocations of object */
-+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
-+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
-+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
-+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
-+#define DT_RUNPATH 29 /* Library search path */
-+#define DT_FLAGS 30 /* Flags for the object being loaded */
-+#define DT_ENCODING 32 /* Start of encoded range */
-+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
-+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
-+#define DT_NUM 34 /* Number used */
-+#define DT_LOOS 0x6000000d /* Start of OS-specific */
-+#define DT_HIOS 0x6ffff000 /* End of OS-specific */
-+#define DT_LOPROC 0x70000000 /* Start of processor-specific */
-+#define DT_HIPROC 0x7fffffff /* End of processor-specific */
-+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */
-+
-+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
-+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's
-+ approach. */
-+#define DT_VALRNGLO 0x6ffffd00
-+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */
-+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */
-+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */
-+#define DT_CHECKSUM 0x6ffffdf8
-+#define DT_PLTPADSZ 0x6ffffdf9
-+#define DT_MOVEENT 0x6ffffdfa
-+#define DT_MOVESZ 0x6ffffdfb
-+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */
-+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting
-+ the following DT_* entry. */
-+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */
-+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */
-+#define DT_VALRNGHI 0x6ffffdff
-+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */
-+#define DT_VALNUM 12
-+
-+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
-+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
-+
-+ If any adjustment is made to the ELF object after it has been
-+ built these entries will need to be adjusted. */
-+#define DT_ADDRRNGLO 0x6ffffe00
-+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */
-+#define DT_TLSDESC_PLT 0x6ffffef6
-+#define DT_TLSDESC_GOT 0x6ffffef7
-+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
-+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
-+#define DT_CONFIG 0x6ffffefa /* Configuration information. */
-+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */
-+#define DT_AUDIT 0x6ffffefc /* Object auditing. */
-+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */
-+#define DT_MOVETAB 0x6ffffefe /* Move table. */
-+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */
-+#define DT_ADDRRNGHI 0x6ffffeff
-+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */
-+#define DT_ADDRNUM 11
-+
-+/* The versioning entry types. The next are defined as part of the
-+ GNU extension. */
-+#define DT_VERSYM 0x6ffffff0
-+
-+#define DT_RELACOUNT 0x6ffffff9
-+#define DT_RELCOUNT 0x6ffffffa
-+
-+/* These were chosen by Sun. */
-+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */
-+#define DT_VERDEF 0x6ffffffc /* Address of version definition
-+ table */
-+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */
-+#define DT_VERNEED 0x6ffffffe /* Address of table with needed
-+ versions */
-+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */
-+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
-+#define DT_VERSIONTAGNUM 16
-+
-+/* Sun added these machine-independent extensions in the "processor-specific"
-+ range. Be compatible. */
-+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */
-+#define DT_FILTER 0x7fffffff /* Shared object to get values from */
-+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
-+#define DT_EXTRANUM 3
-+
-+/* Values of `d_un.d_val' in the DT_FLAGS entry. */
-+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */
-+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */
-+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */
-+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */
-+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
-+
-+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
-+ entry in the dynamic section. */
-+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */
-+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */
-+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */
-+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/
-+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/
-+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
-+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */
-+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */
-+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
-+#define DF_1_TRANS 0x00000200
-+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
-+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */
-+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */
-+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/
-+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */
-+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */
-+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */
-+
-+/* Flags for the feature selection in DT_FEATURE_1. */
-+#define DTF_1_PARINIT 0x00000001
-+#define DTF_1_CONFEXP 0x00000002
-+
-+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
-+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
-+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
-+ generally available. */
-+
-+/* Version definition sections. */
-+
-+typedef struct
-+{
-+ Elf32_Half vd_version; /* Version revision */
-+ Elf32_Half vd_flags; /* Version information */
-+ Elf32_Half vd_ndx; /* Version Index */
-+ Elf32_Half vd_cnt; /* Number of associated aux entries */
-+ Elf32_Word vd_hash; /* Version name hash value */
-+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */
-+ Elf32_Word vd_next; /* Offset in bytes to next verdef
-+ entry */
-+} Elf32_Verdef;
-+
-+typedef struct
-+{
-+ Elf64_Half vd_version; /* Version revision */
-+ Elf64_Half vd_flags; /* Version information */
-+ Elf64_Half vd_ndx; /* Version Index */
-+ Elf64_Half vd_cnt; /* Number of associated aux entries */
-+ Elf64_Word vd_hash; /* Version name hash value */
-+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */
-+ Elf64_Word vd_next; /* Offset in bytes to next verdef
-+ entry */
-+} Elf64_Verdef;
-+
-+
-+/* Legal values for vd_version (version revision). */
-+#define VER_DEF_NONE 0 /* No version */
-+#define VER_DEF_CURRENT 1 /* Current version */
-+#define VER_DEF_NUM 2 /* Given version number */
-+
-+/* Legal values for vd_flags (version information flags). */
-+#define VER_FLG_BASE 0x1 /* Version definition of file itself */
-+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
-+
-+/* Versym symbol index values. */
-+#define VER_NDX_LOCAL 0 /* Symbol is local. */
-+#define VER_NDX_GLOBAL 1 /* Symbol is global. */
-+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */
-+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */
-+
-+/* Auxialiary version information. */
-+
-+typedef struct
-+{
-+ Elf32_Word vda_name; /* Version or dependency names */
-+ Elf32_Word vda_next; /* Offset in bytes to next verdaux
-+ entry */
-+} Elf32_Verdaux;
-+
-+typedef struct
-+{
-+ Elf64_Word vda_name; /* Version or dependency names */
-+ Elf64_Word vda_next; /* Offset in bytes to next verdaux
-+ entry */
-+} Elf64_Verdaux;
-+
-+
-+/* Version dependency section. */
-+
-+typedef struct
-+{
-+ Elf32_Half vn_version; /* Version of structure */
-+ Elf32_Half vn_cnt; /* Number of associated aux entries */
-+ Elf32_Word vn_file; /* Offset of filename for this
-+ dependency */
-+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */
-+ Elf32_Word vn_next; /* Offset in bytes to next verneed
-+ entry */
-+} Elf32_Verneed;
-+
-+typedef struct
-+{
-+ Elf64_Half vn_version; /* Version of structure */
-+ Elf64_Half vn_cnt; /* Number of associated aux entries */
-+ Elf64_Word vn_file; /* Offset of filename for this
-+ dependency */
-+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */
-+ Elf64_Word vn_next; /* Offset in bytes to next verneed
-+ entry */
-+} Elf64_Verneed;
-+
-+
-+/* Legal values for vn_version (version revision). */
-+#define VER_NEED_NONE 0 /* No version */
-+#define VER_NEED_CURRENT 1 /* Current version */
-+#define VER_NEED_NUM 2 /* Given version number */
-+
-+/* Auxiliary needed version information. */
-+
-+typedef struct
-+{
-+ Elf32_Word vna_hash; /* Hash value of dependency name */
-+ Elf32_Half vna_flags; /* Dependency specific information */
-+ Elf32_Half vna_other; /* Unused */
-+ Elf32_Word vna_name; /* Dependency name string offset */
-+ Elf32_Word vna_next; /* Offset in bytes to next vernaux
-+ entry */
-+} Elf32_Vernaux;
-+
-+typedef struct
-+{
-+ Elf64_Word vna_hash; /* Hash value of dependency name */
-+ Elf64_Half vna_flags; /* Dependency specific information */
-+ Elf64_Half vna_other; /* Unused */
-+ Elf64_Word vna_name; /* Dependency name string offset */
-+ Elf64_Word vna_next; /* Offset in bytes to next vernaux
-+ entry */
-+} Elf64_Vernaux;
-+
-+
-+/* Legal values for vna_flags. */
-+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
-+
-+
-+/* Auxiliary vector. */
-+
-+/* This vector is normally only used by the program interpreter. The
-+ usual definition in an ABI supplement uses the name auxv_t. The
-+ vector is not usually defined in a standard <elf.h> file, but it
-+ can't hurt. We rename it to avoid conflicts. The sizes of these
-+ types are an arrangement between the exec server and the program
-+ interpreter, so we don't fully specify them here. */
-+
-+typedef struct
-+{
-+ uint32_t a_type; /* Entry type */
-+ union
-+ {
-+ uint32_t a_val; /* Integer value */
-+ /* We use to have pointer elements added here. We cannot do that,
-+ though, since it does not work when using 32-bit definitions
-+ on 64-bit platforms and vice versa. */
-+ } a_un;
-+} Elf32_auxv_t;
-+
-+typedef struct
-+{
-+ uint64_t a_type; /* Entry type */
-+ union
-+ {
-+ uint64_t a_val; /* Integer value */
-+ /* We use to have pointer elements added here. We cannot do that,
-+ though, since it does not work when using 32-bit definitions
-+ on 64-bit platforms and vice versa. */
-+ } a_un;
-+} Elf64_auxv_t;
-+
-+/* Legal values for a_type (entry type). */
-+
-+#define AT_NULL 0 /* End of vector */
-+#define AT_IGNORE 1 /* Entry should be ignored */
-+#define AT_EXECFD 2 /* File descriptor of program */
-+#define AT_PHDR 3 /* Program headers for program */
-+#define AT_PHENT 4 /* Size of program header entry */
-+#define AT_PHNUM 5 /* Number of program headers */
-+#define AT_PAGESZ 6 /* System page size */
-+#define AT_BASE 7 /* Base address of interpreter */
-+#define AT_FLAGS 8 /* Flags */
-+#define AT_ENTRY 9 /* Entry point of program */
-+#define AT_NOTELF 10 /* Program is not ELF */
-+#define AT_UID 11 /* Real uid */
-+#define AT_EUID 12 /* Effective uid */
-+#define AT_GID 13 /* Real gid */
-+#define AT_EGID 14 /* Effective gid */
-+#define AT_CLKTCK 17 /* Frequency of times() */
-+
-+/* Some more special a_type values describing the hardware. */
-+#define AT_PLATFORM 15 /* String identifying platform. */
-+#define AT_HWCAP 16 /* Machine dependent hints about
-+ processor capabilities. */
-+
-+/* This entry gives some information about the FPU initialization
-+ performed by the kernel. */
-+#define AT_FPUCW 18 /* Used FPU control word. */
-+
-+/* Cache block sizes. */
-+#define AT_DCACHEBSIZE 19 /* Data cache block size. */
-+#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */
-+#define AT_UCACHEBSIZE 21 /* Unified cache block size. */
-+
-+/* A special ignored value for PPC, used by the kernel to control the
-+ interpretation of the AUXV. Must be > 16. */
-+#define AT_IGNOREPPC 22 /* Entry should be ignored. */
-+
-+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */
-+
-+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/
-+
-+#define AT_RANDOM 25 /* Address of 16 random bytes. */
-+
-+#define AT_EXECFN 31 /* Filename of executable. */
-+
-+/* Pointer to the global system page used for system calls and other
-+ nice things. */
-+#define AT_SYSINFO 32
-+#define AT_SYSINFO_EHDR 33
-+
-+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains
-+ log2 of line size; mask those to get cache size. */
-+#define AT_L1I_CACHESHAPE 34
-+#define AT_L1D_CACHESHAPE 35
-+#define AT_L2_CACHESHAPE 36
-+#define AT_L3_CACHESHAPE 37
-+
-+/* Note section contents. Each entry in the note section begins with
-+ a header of a fixed form. */
-+
-+typedef struct
-+{
-+ Elf32_Word n_namesz; /* Length of the note's name. */
-+ Elf32_Word n_descsz; /* Length of the note's descriptor. */
-+ Elf32_Word n_type; /* Type of the note. */
-+} Elf32_Nhdr;
-+
-+typedef struct
-+{
-+ Elf64_Word n_namesz; /* Length of the note's name. */
-+ Elf64_Word n_descsz; /* Length of the note's descriptor. */
-+ Elf64_Word n_type; /* Type of the note. */
-+} Elf64_Nhdr;
-+
-+/* Known names of notes. */
-+
-+/* Solaris entries in the note section have this name. */
-+#define ELF_NOTE_SOLARIS "SUNW Solaris"
-+
-+/* Note entries for GNU systems have this name. */
-+#define ELF_NOTE_GNU "GNU"
-+
-+
-+/* Defined types of notes for Solaris. */
-+
-+/* Value of descriptor (one word) is desired pagesize for the binary. */
-+#define ELF_NOTE_PAGESIZE_HINT 1
-+
-+
-+/* Defined note types for GNU systems. */
-+
-+/* ABI information. The descriptor consists of words:
-+ word 0: OS descriptor
-+ word 1: major version of the ABI
-+ word 2: minor version of the ABI
-+ word 3: subminor version of the ABI
-+*/
-+#define NT_GNU_ABI_TAG 1
-+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */
-+
-+/* Known OSes. These values can appear in word 0 of an
-+ NT_GNU_ABI_TAG note section entry. */
-+#define ELF_NOTE_OS_LINUX 0
-+#define ELF_NOTE_OS_GNU 1
-+#define ELF_NOTE_OS_SOLARIS2 2
-+#define ELF_NOTE_OS_FREEBSD 3
-+
-+/* Synthetic hwcap information. The descriptor begins with two words:
-+ word 0: number of entries
-+ word 1: bitmask of enabled entries
-+ Then follow variable-length entries, one byte followed by a
-+ '\0'-terminated hwcap name string. The byte gives the bit
-+ number to test if enabled, (1U << bit) & bitmask. */
-+#define NT_GNU_HWCAP 2
-+
-+/* Build ID bits as generated by ld --build-id.
-+ The descriptor consists of any nonzero number of bytes. */
-+#define NT_GNU_BUILD_ID 3
-+
-+/* Version note generated by GNU gold containing a version string. */
-+#define NT_GNU_GOLD_VERSION 4
-+
-+
-+/* Move records. */
-+typedef struct
-+{
-+ Elf32_Xword m_value; /* Symbol value. */
-+ Elf32_Word m_info; /* Size and index. */
-+ Elf32_Word m_poffset; /* Symbol offset. */
-+ Elf32_Half m_repeat; /* Repeat count. */
-+ Elf32_Half m_stride; /* Stride info. */
-+} Elf32_Move;
-+
-+typedef struct
-+{
-+ Elf64_Xword m_value; /* Symbol value. */
-+ Elf64_Xword m_info; /* Size and index. */
-+ Elf64_Xword m_poffset; /* Symbol offset. */
-+ Elf64_Half m_repeat; /* Repeat count. */
-+ Elf64_Half m_stride; /* Stride info. */
-+} Elf64_Move;
-+
-+/* Macro to construct move records. */
-+#define ELF32_M_SYM(info) ((info) >> 8)
-+#define ELF32_M_SIZE(info) ((unsigned char) (info))
-+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
-+
-+#define ELF64_M_SYM(info) ELF32_M_SYM (info)
-+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info)
-+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
-+
-+
-+/* Motorola 68k specific definitions. */
-+
-+/* Values for Elf32_Ehdr.e_flags. */
-+#define EF_CPU32 0x00810000
-+
-+/* m68k relocs. */
-+
-+#define R_68K_NONE 0 /* No reloc */
-+#define R_68K_32 1 /* Direct 32 bit */
-+#define R_68K_16 2 /* Direct 16 bit */
-+#define R_68K_8 3 /* Direct 8 bit */
-+#define R_68K_PC32 4 /* PC relative 32 bit */
-+#define R_68K_PC16 5 /* PC relative 16 bit */
-+#define R_68K_PC8 6 /* PC relative 8 bit */
-+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
-+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
-+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
-+#define R_68K_GOT32O 10 /* 32 bit GOT offset */
-+#define R_68K_GOT16O 11 /* 16 bit GOT offset */
-+#define R_68K_GOT8O 12 /* 8 bit GOT offset */
-+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
-+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
-+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
-+#define R_68K_PLT32O 16 /* 32 bit PLT offset */
-+#define R_68K_PLT16O 17 /* 16 bit PLT offset */
-+#define R_68K_PLT8O 18 /* 8 bit PLT offset */
-+#define R_68K_COPY 19 /* Copy symbol at runtime */
-+#define R_68K_GLOB_DAT 20 /* Create GOT entry */
-+#define R_68K_JMP_SLOT 21 /* Create PLT entry */
-+#define R_68K_RELATIVE 22 /* Adjust by program base */
-+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */
-+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */
-+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */
-+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */
-+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */
-+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */
-+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */
-+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */
-+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */
-+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */
-+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */
-+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */
-+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to
-+ static TLS block */
-+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to
-+ static TLS block */
-+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to
-+ static TLS block */
-+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */
-+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */
-+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */
-+/* Keep this the last entry. */
-+#define R_68K_NUM 43
-+
-+/* Intel 80386 specific definitions. */
-+
-+/* i386 relocs. */
-+
-+#define R_386_NONE 0 /* No reloc */
-+#define R_386_32 1 /* Direct 32 bit */
-+#define R_386_PC32 2 /* PC relative 32 bit */
-+#define R_386_GOT32 3 /* 32 bit GOT entry */
-+#define R_386_PLT32 4 /* 32 bit PLT address */
-+#define R_386_COPY 5 /* Copy symbol at runtime */
-+#define R_386_GLOB_DAT 6 /* Create GOT entry */
-+#define R_386_JMP_SLOT 7 /* Create PLT entry */
-+#define R_386_RELATIVE 8 /* Adjust by program base */
-+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
-+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
-+#define R_386_32PLT 11
-+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */
-+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS
-+ block offset */
-+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block
-+ offset */
-+#define R_386_TLS_LE 17 /* Offset relative to static TLS
-+ block */
-+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of
-+ general dynamic thread local data */
-+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of
-+ local dynamic thread local data
-+ in LE code */
-+#define R_386_16 20
-+#define R_386_PC16 21
-+#define R_386_8 22
-+#define R_386_PC8 23
-+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic
-+ thread local data */
-+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */
-+#define R_386_TLS_GD_CALL 26 /* Relocation for call to
-+ __tls_get_addr() */
-+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */
-+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic
-+ thread local data in LE code */
-+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */
-+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to
-+ __tls_get_addr() in LDM code */
-+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */
-+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */
-+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS
-+ block offset */
-+#define R_386_TLS_LE_32 34 /* Negated offset relative to static
-+ TLS block */
-+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */
-+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */
-+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */
-+/* 38? */
-+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */
-+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS
-+ descriptor for
-+ relaxation. */
-+#define R_386_TLS_DESC 41 /* TLS descriptor containing
-+ pointer to code and to
-+ argument, returning the TLS
-+ offset for the symbol. */
-+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */
-+/* Keep this the last entry. */
-+#define R_386_NUM 43
-+
-+/* SUN SPARC specific definitions. */
-+
-+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-+
-+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */
-+
-+/* Values for Elf64_Ehdr.e_flags. */
-+
-+#define EF_SPARCV9_MM 3
-+#define EF_SPARCV9_TSO 0
-+#define EF_SPARCV9_PSO 1
-+#define EF_SPARCV9_RMO 2
-+#define EF_SPARC_LEDATA 0x800000 /* little endian data */
-+#define EF_SPARC_EXT_MASK 0xFFFF00
-+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */
-+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */
-+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */
-+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */
-+
-+/* SPARC relocs. */
-+
-+#define R_SPARC_NONE 0 /* No reloc */
-+#define R_SPARC_8 1 /* Direct 8 bit */
-+#define R_SPARC_16 2 /* Direct 16 bit */
-+#define R_SPARC_32 3 /* Direct 32 bit */
-+#define R_SPARC_DISP8 4 /* PC relative 8 bit */
-+#define R_SPARC_DISP16 5 /* PC relative 16 bit */
-+#define R_SPARC_DISP32 6 /* PC relative 32 bit */
-+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */
-+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */
-+#define R_SPARC_HI22 9 /* High 22 bit */
-+#define R_SPARC_22 10 /* Direct 22 bit */
-+#define R_SPARC_13 11 /* Direct 13 bit */
-+#define R_SPARC_LO10 12 /* Truncated 10 bit */
-+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */
-+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */
-+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */
-+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */
-+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */
-+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */
-+#define R_SPARC_COPY 19 /* Copy symbol at runtime */
-+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */
-+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */
-+#define R_SPARC_RELATIVE 22 /* Adjust by program base */
-+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */
-+
-+/* Additional Sparc64 relocs. */
-+
-+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */
-+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */
-+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */
-+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */
-+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */
-+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */
-+#define R_SPARC_10 30 /* Direct 10 bit */
-+#define R_SPARC_11 31 /* Direct 11 bit */
-+#define R_SPARC_64 32 /* Direct 64 bit */
-+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */
-+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */
-+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */
-+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */
-+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */
-+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */
-+#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */
-+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
-+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
-+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
-+#define R_SPARC_7 43 /* Direct 7 bit */
-+#define R_SPARC_5 44 /* Direct 5 bit */
-+#define R_SPARC_6 45 /* Direct 6 bit */
-+#define R_SPARC_DISP64 46 /* PC relative 64 bit */
-+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */
-+#define R_SPARC_HIX22 48 /* High 22 bit complemented */
-+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */
-+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */
-+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */
-+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */
-+#define R_SPARC_REGISTER 53 /* Global register usage */
-+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */
-+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */
-+#define R_SPARC_TLS_GD_HI22 56
-+#define R_SPARC_TLS_GD_LO10 57
-+#define R_SPARC_TLS_GD_ADD 58
-+#define R_SPARC_TLS_GD_CALL 59
-+#define R_SPARC_TLS_LDM_HI22 60
-+#define R_SPARC_TLS_LDM_LO10 61
-+#define R_SPARC_TLS_LDM_ADD 62
-+#define R_SPARC_TLS_LDM_CALL 63
-+#define R_SPARC_TLS_LDO_HIX22 64
-+#define R_SPARC_TLS_LDO_LOX10 65
-+#define R_SPARC_TLS_LDO_ADD 66
-+#define R_SPARC_TLS_IE_HI22 67
-+#define R_SPARC_TLS_IE_LO10 68
-+#define R_SPARC_TLS_IE_LD 69
-+#define R_SPARC_TLS_IE_LDX 70
-+#define R_SPARC_TLS_IE_ADD 71
-+#define R_SPARC_TLS_LE_HIX22 72
-+#define R_SPARC_TLS_LE_LOX10 73
-+#define R_SPARC_TLS_DTPMOD32 74
-+#define R_SPARC_TLS_DTPMOD64 75
-+#define R_SPARC_TLS_DTPOFF32 76
-+#define R_SPARC_TLS_DTPOFF64 77
-+#define R_SPARC_TLS_TPOFF32 78
-+#define R_SPARC_TLS_TPOFF64 79
-+#define R_SPARC_GOTDATA_HIX22 80
-+#define R_SPARC_GOTDATA_LOX10 81
-+#define R_SPARC_GOTDATA_OP_HIX22 82
-+#define R_SPARC_GOTDATA_OP_LOX10 83
-+#define R_SPARC_GOTDATA_OP 84
-+#define R_SPARC_H34 85
-+#define R_SPARC_SIZE32 86
-+#define R_SPARC_SIZE64 87
-+#define R_SPARC_WDISP10 88
-+#define R_SPARC_JMP_IREL 248
-+#define R_SPARC_IRELATIVE 249
-+#define R_SPARC_GNU_VTINHERIT 250
-+#define R_SPARC_GNU_VTENTRY 251
-+#define R_SPARC_REV32 252
-+/* Keep this the last entry. */
-+#define R_SPARC_NUM 253
-+
-+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
-+
-+#define DT_SPARC_REGISTER 0x70000001
-+#define DT_SPARC_NUM 2
-+
-+/* MIPS R3000 specific definitions. */
-+
-+/* Legal values for e_flags field of Elf32_Ehdr. */
-+
-+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */
-+#define EF_MIPS_PIC 2 /* Contains PIC code */
-+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */
-+#define EF_MIPS_XGOT 8
-+#define EF_MIPS_64BIT_WHIRL 16
-+#define EF_MIPS_ABI2 32
-+#define EF_MIPS_ABI_ON32 64
-+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */
-+
-+/* Legal values for MIPS architecture level. */
-+
-+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
-+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
-+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
-+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
-+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
-+#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */
-+#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */
-+
-+/* The following are non-official names and should not be used. */
-+
-+#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
-+#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
-+#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
-+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
-+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
-+#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */
-+#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */
-+
-+/* Special section indices. */
-+
-+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */
-+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
-+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
-+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
-+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
-+
-+/* Legal values for sh_type field of Elf32_Shdr. */
-+
-+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */
-+#define SHT_MIPS_MSYM 0x70000001
-+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */
-+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */
-+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
-+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/
-+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */
-+#define SHT_MIPS_PACKAGE 0x70000007
-+#define SHT_MIPS_PACKSYM 0x70000008
-+#define SHT_MIPS_RELD 0x70000009
-+#define SHT_MIPS_IFACE 0x7000000b
-+#define SHT_MIPS_CONTENT 0x7000000c
-+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */
-+#define SHT_MIPS_SHDR 0x70000010
-+#define SHT_MIPS_FDESC 0x70000011
-+#define SHT_MIPS_EXTSYM 0x70000012
-+#define SHT_MIPS_DENSE 0x70000013
-+#define SHT_MIPS_PDESC 0x70000014
-+#define SHT_MIPS_LOCSYM 0x70000015
-+#define SHT_MIPS_AUXSYM 0x70000016
-+#define SHT_MIPS_OPTSYM 0x70000017
-+#define SHT_MIPS_LOCSTR 0x70000018
-+#define SHT_MIPS_LINE 0x70000019
-+#define SHT_MIPS_RFDESC 0x7000001a
-+#define SHT_MIPS_DELTASYM 0x7000001b
-+#define SHT_MIPS_DELTAINST 0x7000001c
-+#define SHT_MIPS_DELTACLASS 0x7000001d
-+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */
-+#define SHT_MIPS_DELTADECL 0x7000001f
-+#define SHT_MIPS_SYMBOL_LIB 0x70000020
-+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */
-+#define SHT_MIPS_TRANSLATE 0x70000022
-+#define SHT_MIPS_PIXIE 0x70000023
-+#define SHT_MIPS_XLATE 0x70000024
-+#define SHT_MIPS_XLATE_DEBUG 0x70000025
-+#define SHT_MIPS_WHIRL 0x70000026
-+#define SHT_MIPS_EH_REGION 0x70000027
-+#define SHT_MIPS_XLATE_OLD 0x70000028
-+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
-+
-+/* Legal values for sh_flags field of Elf32_Shdr. */
-+
-+#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */
-+#define SHF_MIPS_MERGE 0x20000000
-+#define SHF_MIPS_ADDR 0x40000000
-+#define SHF_MIPS_STRINGS 0x80000000
-+#define SHF_MIPS_NOSTRIP 0x08000000
-+#define SHF_MIPS_LOCAL 0x04000000
-+#define SHF_MIPS_NAMES 0x02000000
-+#define SHF_MIPS_NODUPE 0x01000000
-+
-+
-+/* Symbol tables. */
-+
-+/* MIPS specific values for `st_other'. */
-+#define STO_MIPS_DEFAULT 0x0
-+#define STO_MIPS_INTERNAL 0x1
-+#define STO_MIPS_HIDDEN 0x2
-+#define STO_MIPS_PROTECTED 0x3
-+#define STO_MIPS_PLT 0x8
-+#define STO_MIPS_SC_ALIGN_UNUSED 0xff
-+
-+/* MIPS specific values for `st_info'. */
-+#define STB_MIPS_SPLIT_COMMON 13
-+
-+/* Entries found in sections of type SHT_MIPS_GPTAB. */
-+
-+typedef union
-+{
-+ struct
-+ {
-+ Elf32_Word gt_current_g_value; /* -G value used for compilation */
-+ Elf32_Word gt_unused; /* Not used */
-+ } gt_header; /* First entry in section */
-+ struct
-+ {
-+ Elf32_Word gt_g_value; /* If this value were used for -G */
-+ Elf32_Word gt_bytes; /* This many bytes would be used */
-+ } gt_entry; /* Subsequent entries in section */
-+} Elf32_gptab;
-+
-+/* Entry found in sections of type SHT_MIPS_REGINFO. */
-+
-+typedef struct
-+{
-+ Elf32_Word ri_gprmask; /* General registers used */
-+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */
-+ Elf32_Sword ri_gp_value; /* $gp register value */
-+} Elf32_RegInfo;
-+
-+/* Entries found in sections of type SHT_MIPS_OPTIONS. */
-+
-+typedef struct
-+{
-+ unsigned char kind; /* Determines interpretation of the
-+ variable part of descriptor. */
-+ unsigned char size; /* Size of descriptor, including header. */
-+ Elf32_Section section; /* Section header index of section affected,
-+ 0 for global options. */
-+ Elf32_Word info; /* Kind-specific information. */
-+} Elf_Options;
-+
-+/* Values for `kind' field in Elf_Options. */
-+
-+#define ODK_NULL 0 /* Undefined. */
-+#define ODK_REGINFO 1 /* Register usage information. */
-+#define ODK_EXCEPTIONS 2 /* Exception processing options. */
-+#define ODK_PAD 3 /* Section padding options. */
-+#define ODK_HWPATCH 4 /* Hardware workarounds performed */
-+#define ODK_FILL 5 /* record the fill value used by the linker. */
-+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */
-+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */
-+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */
-+
-+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */
-+
-+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */
-+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */
-+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */
-+#define OEX_SMM 0x20000 /* Force sequential memory mode? */
-+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */
-+#define OEX_PRECISEFP OEX_FPDBUG
-+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */
-+
-+#define OEX_FPU_INVAL 0x10
-+#define OEX_FPU_DIV0 0x08
-+#define OEX_FPU_OFLO 0x04
-+#define OEX_FPU_UFLO 0x02
-+#define OEX_FPU_INEX 0x01
-+
-+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */
-+
-+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */
-+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */
-+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */
-+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */
-+
-+#define OPAD_PREFIX 0x1
-+#define OPAD_POSTFIX 0x2
-+#define OPAD_SYMBOL 0x4
-+
-+/* Entry found in `.options' section. */
-+
-+typedef struct
-+{
-+ Elf32_Word hwp_flags1; /* Extra flags. */
-+ Elf32_Word hwp_flags2; /* Extra flags. */
-+} Elf_Options_Hw;
-+
-+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */
-+
-+#define OHWA0_R4KEOP_CHECKED 0x00000001
-+#define OHWA1_R4KEOP_CLEAN 0x00000002
-+
-+/* MIPS relocs. */
-+
-+#define R_MIPS_NONE 0 /* No reloc */
-+#define R_MIPS_16 1 /* Direct 16 bit */
-+#define R_MIPS_32 2 /* Direct 32 bit */
-+#define R_MIPS_REL32 3 /* PC relative 32 bit */
-+#define R_MIPS_26 4 /* Direct 26 bit shifted */
-+#define R_MIPS_HI16 5 /* High 16 bit */
-+#define R_MIPS_LO16 6 /* Low 16 bit */
-+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
-+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
-+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
-+#define R_MIPS_PC16 10 /* PC relative 16 bit */
-+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
-+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
-+
-+#define R_MIPS_SHIFT5 16
-+#define R_MIPS_SHIFT6 17
-+#define R_MIPS_64 18
-+#define R_MIPS_GOT_DISP 19
-+#define R_MIPS_GOT_PAGE 20
-+#define R_MIPS_GOT_OFST 21
-+#define R_MIPS_GOT_HI16 22
-+#define R_MIPS_GOT_LO16 23
-+#define R_MIPS_SUB 24
-+#define R_MIPS_INSERT_A 25
-+#define R_MIPS_INSERT_B 26
-+#define R_MIPS_DELETE 27
-+#define R_MIPS_HIGHER 28
-+#define R_MIPS_HIGHEST 29
-+#define R_MIPS_CALL_HI16 30
-+#define R_MIPS_CALL_LO16 31
-+#define R_MIPS_SCN_DISP 32
-+#define R_MIPS_REL16 33
-+#define R_MIPS_ADD_IMMEDIATE 34
-+#define R_MIPS_PJUMP 35
-+#define R_MIPS_RELGOT 36
-+#define R_MIPS_JALR 37
-+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
-+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
-+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
-+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
-+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
-+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
-+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
-+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
-+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
-+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
-+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
-+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
-+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
-+#define R_MIPS_GLOB_DAT 51
-+#define R_MIPS_COPY 126
-+#define R_MIPS_JUMP_SLOT 127
-+/* Keep this the last entry. */
-+#define R_MIPS_NUM 128
-+
-+/* Legal values for p_type field of Elf32_Phdr. */
-+
-+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
-+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
-+#define PT_MIPS_OPTIONS 0x70000002
-+
-+/* Special program header types. */
-+
-+#define PF_MIPS_LOCAL 0x10000000
-+
-+/* Legal values for d_tag field of Elf32_Dyn. */
-+
-+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */
-+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */
-+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */
-+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */
-+#define DT_MIPS_FLAGS 0x70000005 /* Flags */
-+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
-+#define DT_MIPS_MSYM 0x70000007
-+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */
-+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */
-+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */
-+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */
-+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */
-+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */
-+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
-+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */
-+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
-+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */
-+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */
-+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in
-+ DT_MIPS_DELTA_CLASS. */
-+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */
-+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
-+ DT_MIPS_DELTA_INSTANCE. */
-+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */
-+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
-+ DT_MIPS_DELTA_RELOC. */
-+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta
-+ relocations refer to. */
-+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
-+ DT_MIPS_DELTA_SYM. */
-+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
-+ class declaration. */
-+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
-+ DT_MIPS_DELTA_CLASSSYM. */
-+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */
-+#define DT_MIPS_PIXIE_INIT 0x70000023
-+#define DT_MIPS_SYMBOL_LIB 0x70000024
-+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
-+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
-+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
-+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
-+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */
-+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */
-+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
-+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
-+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
-+ function stored in GOT. */
-+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added
-+ by rld on dlopen() calls. */
-+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
-+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */
-+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */
-+/* The address of .got.plt in an executable using the new non-PIC ABI. */
-+#define DT_MIPS_PLTGOT 0x70000032
-+/* The base of the PLT in an executable using the new non-PIC ABI if that
-+ PLT is writable. For a non-writable PLT, this is omitted or has a zero
-+ value. */
-+#define DT_MIPS_RWPLT 0x70000034
-+#define DT_MIPS_NUM 0x35
-+
-+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
-+
-+#define RHF_NONE 0 /* No flags */
-+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */
-+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */
-+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */
-+#define RHF_NO_MOVE (1 << 3)
-+#define RHF_SGI_ONLY (1 << 4)
-+#define RHF_GUARANTEE_INIT (1 << 5)
-+#define RHF_DELTA_C_PLUS_PLUS (1 << 6)
-+#define RHF_GUARANTEE_START_INIT (1 << 7)
-+#define RHF_PIXIE (1 << 8)
-+#define RHF_DEFAULT_DELAY_LOAD (1 << 9)
-+#define RHF_REQUICKSTART (1 << 10)
-+#define RHF_REQUICKSTARTED (1 << 11)
-+#define RHF_CORD (1 << 12)
-+#define RHF_NO_UNRES_UNDEF (1 << 13)
-+#define RHF_RLD_ORDER_SAFE (1 << 14)
-+
-+/* Entries found in sections of type SHT_MIPS_LIBLIST. */
-+
-+typedef struct
-+{
-+ Elf32_Word l_name; /* Name (string table index) */
-+ Elf32_Word l_time_stamp; /* Timestamp */
-+ Elf32_Word l_checksum; /* Checksum */
-+ Elf32_Word l_version; /* Interface version */
-+ Elf32_Word l_flags; /* Flags */
-+} Elf32_Lib;
-+
-+typedef struct
-+{
-+ Elf64_Word l_name; /* Name (string table index) */
-+ Elf64_Word l_time_stamp; /* Timestamp */
-+ Elf64_Word l_checksum; /* Checksum */
-+ Elf64_Word l_version; /* Interface version */
-+ Elf64_Word l_flags; /* Flags */
-+} Elf64_Lib;
-+
-+
-+/* Legal values for l_flags. */
-+
-+#define LL_NONE 0
-+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */
-+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */
-+#define LL_REQUIRE_MINOR (1 << 2)
-+#define LL_EXPORTS (1 << 3)
-+#define LL_DELAY_LOAD (1 << 4)
-+#define LL_DELTA (1 << 5)
-+
-+/* Entries found in sections of type SHT_MIPS_CONFLICT. */
-+
-+typedef Elf32_Addr Elf32_Conflict;
-+
-+
-+/* HPPA specific definitions. */
-+
-+/* Legal values for e_flags field of Elf32_Ehdr. */
-+
-+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
-+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
-+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
-+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
-+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
-+ prediction. */
-+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
-+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
-+
-+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
-+
-+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
-+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
-+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
-+
-+/* Additional section indeces. */
-+
-+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
-+ symbols in ANSI C. */
-+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
-+
-+/* Legal values for sh_type field of Elf32_Shdr. */
-+
-+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
-+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
-+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
-+
-+/* Legal values for sh_flags field of Elf32_Shdr. */
-+
-+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
-+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
-+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
-+
-+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-+
-+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
-+
-+#define STT_HP_OPAQUE (STT_LOOS + 0x1)
-+#define STT_HP_STUB (STT_LOOS + 0x2)
-+
-+/* HPPA relocs. */
-+
-+#define R_PARISC_NONE 0 /* No reloc. */
-+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
-+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
-+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
-+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
-+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
-+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
-+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
-+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
-+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
-+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
-+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
-+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
-+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
-+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
-+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
-+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
-+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
-+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
-+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
-+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
-+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
-+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
-+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
-+#define R_PARISC_FPTR64 64 /* 64 bits function address. */
-+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
-+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */
-+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */
-+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
-+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
-+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
-+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
-+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
-+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
-+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
-+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
-+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
-+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
-+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
-+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
-+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
-+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
-+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
-+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
-+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
-+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
-+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
-+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
-+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
-+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
-+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
-+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
-+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
-+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
-+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
-+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
-+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
-+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
-+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
-+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
-+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
-+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
-+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
-+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
-+#define R_PARISC_LORESERVE 128
-+#define R_PARISC_COPY 128 /* Copy relocation. */
-+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
-+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
-+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
-+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
-+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
-+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
-+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
-+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
-+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
-+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
-+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
-+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
-+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
-+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
-+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
-+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
-+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
-+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
-+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
-+#define R_PARISC_GNU_VTENTRY 232
-+#define R_PARISC_GNU_VTINHERIT 233
-+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */
-+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */
-+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */
-+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */
-+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */
-+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */
-+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */
-+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */
-+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */
-+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */
-+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */
-+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */
-+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
-+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
-+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
-+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
-+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
-+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
-+#define R_PARISC_HIRESERVE 255
-+
-+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
-+
-+#define PT_HP_TLS (PT_LOOS + 0x0)
-+#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
-+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
-+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
-+#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
-+#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
-+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
-+#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
-+#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
-+#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
-+#define PT_HP_PARALLEL (PT_LOOS + 0x10)
-+#define PT_HP_FASTBIND (PT_LOOS + 0x11)
-+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
-+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
-+#define PT_HP_STACK (PT_LOOS + 0x14)
-+
-+#define PT_PARISC_ARCHEXT 0x70000000
-+#define PT_PARISC_UNWIND 0x70000001
-+
-+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
-+
-+#define PF_PARISC_SBP 0x08000000
-+
-+#define PF_HP_PAGE_SIZE 0x00100000
-+#define PF_HP_FAR_SHARED 0x00200000
-+#define PF_HP_NEAR_SHARED 0x00400000
-+#define PF_HP_CODE 0x01000000
-+#define PF_HP_MODIFY 0x02000000
-+#define PF_HP_LAZYSWAP 0x04000000
-+#define PF_HP_SBP 0x08000000
-+
-+
-+/* Alpha specific definitions. */
-+
-+/* Legal values for e_flags field of Elf64_Ehdr. */
-+
-+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */
-+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */
-+
-+/* Legal values for sh_type field of Elf64_Shdr. */
-+
-+/* These two are primerily concerned with ECOFF debugging info. */
-+#define SHT_ALPHA_DEBUG 0x70000001
-+#define SHT_ALPHA_REGINFO 0x70000002
-+
-+/* Legal values for sh_flags field of Elf64_Shdr. */
-+
-+#define SHF_ALPHA_GPREL 0x10000000
-+
-+/* Legal values for st_other field of Elf64_Sym. */
-+#define STO_ALPHA_NOPV 0x80 /* No PV required. */
-+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */
-+
-+/* Alpha relocs. */
-+
-+#define R_ALPHA_NONE 0 /* No reloc */
-+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
-+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
-+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
-+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
-+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
-+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
-+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
-+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
-+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
-+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
-+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
-+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
-+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
-+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
-+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
-+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
-+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
-+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
-+#define R_ALPHA_TLS_GD_HI 28
-+#define R_ALPHA_TLSGD 29
-+#define R_ALPHA_TLS_LDM 30
-+#define R_ALPHA_DTPMOD64 31
-+#define R_ALPHA_GOTDTPREL 32
-+#define R_ALPHA_DTPREL64 33
-+#define R_ALPHA_DTPRELHI 34
-+#define R_ALPHA_DTPRELLO 35
-+#define R_ALPHA_DTPREL16 36
-+#define R_ALPHA_GOTTPREL 37
-+#define R_ALPHA_TPREL64 38
-+#define R_ALPHA_TPRELHI 39
-+#define R_ALPHA_TPRELLO 40
-+#define R_ALPHA_TPREL16 41
-+/* Keep this the last entry. */
-+#define R_ALPHA_NUM 46
-+
-+/* Magic values of the LITUSE relocation addend. */
-+#define LITUSE_ALPHA_ADDR 0
-+#define LITUSE_ALPHA_BASE 1
-+#define LITUSE_ALPHA_BYTOFF 2
-+#define LITUSE_ALPHA_JSR 3
-+#define LITUSE_ALPHA_TLS_GD 4
-+#define LITUSE_ALPHA_TLS_LDM 5
-+
-+/* Legal values for d_tag of Elf64_Dyn. */
-+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
-+#define DT_ALPHA_NUM 1
-+
-+/* PowerPC specific declarations */
-+
-+/* Values for Elf32/64_Ehdr.e_flags. */
-+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
-+
-+/* Cygnus local bits below */
-+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
-+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
-+ flag */
-+
-+/* PowerPC relocations defined by the ABIs */
-+#define R_PPC_NONE 0
-+#define R_PPC_ADDR32 1 /* 32bit absolute address */
-+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-+#define R_PPC_ADDR16 3 /* 16bit absolute address */
-+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-+#define R_PPC_ADDR14_BRTAKEN 8
-+#define R_PPC_ADDR14_BRNTAKEN 9
-+#define R_PPC_REL24 10 /* PC relative 26 bit */
-+#define R_PPC_REL14 11 /* PC relative 16 bit */
-+#define R_PPC_REL14_BRTAKEN 12
-+#define R_PPC_REL14_BRNTAKEN 13
-+#define R_PPC_GOT16 14
-+#define R_PPC_GOT16_LO 15
-+#define R_PPC_GOT16_HI 16
-+#define R_PPC_GOT16_HA 17
-+#define R_PPC_PLTREL24 18
-+#define R_PPC_COPY 19
-+#define R_PPC_GLOB_DAT 20
-+#define R_PPC_JMP_SLOT 21
-+#define R_PPC_RELATIVE 22
-+#define R_PPC_LOCAL24PC 23
-+#define R_PPC_UADDR32 24
-+#define R_PPC_UADDR16 25
-+#define R_PPC_REL32 26
-+#define R_PPC_PLT32 27
-+#define R_PPC_PLTREL32 28
-+#define R_PPC_PLT16_LO 29
-+#define R_PPC_PLT16_HI 30
-+#define R_PPC_PLT16_HA 31
-+#define R_PPC_SDAREL16 32
-+#define R_PPC_SECTOFF 33
-+#define R_PPC_SECTOFF_LO 34
-+#define R_PPC_SECTOFF_HI 35
-+#define R_PPC_SECTOFF_HA 36
-+
-+/* PowerPC relocations defined for the TLS access ABI. */
-+#define R_PPC_TLS 67 /* none (sym+add)@tls */
-+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
-+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
-+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
-+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
-+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
-+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
-+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
-+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
-+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
-+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
-+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
-+
-+/* The remaining relocs are from the Embedded ELF ABI, and are not
-+ in the SVR4 ELF ABI. */
-+#define R_PPC_EMB_NADDR32 101
-+#define R_PPC_EMB_NADDR16 102
-+#define R_PPC_EMB_NADDR16_LO 103
-+#define R_PPC_EMB_NADDR16_HI 104
-+#define R_PPC_EMB_NADDR16_HA 105
-+#define R_PPC_EMB_SDAI16 106
-+#define R_PPC_EMB_SDA2I16 107
-+#define R_PPC_EMB_SDA2REL 108
-+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
-+#define R_PPC_EMB_MRKREF 110
-+#define R_PPC_EMB_RELSEC16 111
-+#define R_PPC_EMB_RELST_LO 112
-+#define R_PPC_EMB_RELST_HI 113
-+#define R_PPC_EMB_RELST_HA 114
-+#define R_PPC_EMB_BIT_FLD 115
-+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
-+
-+/* Diab tool relocations. */
-+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
-+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
-+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
-+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
-+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
-+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
-+
-+/* GNU extension to support local ifunc. */
-+#define R_PPC_IRELATIVE 248
-+
-+/* GNU relocs used in PIC code sequences. */
-+#define R_PPC_REL16 249 /* half16 (sym+add-.) */
-+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */
-+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */
-+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */
-+
-+/* This is a phony reloc to handle any old fashioned TOC16 references
-+ that may still be in object files. */
-+#define R_PPC_TOC16 255
-+
-+/* PowerPC specific values for the Dyn d_tag field. */
-+#define DT_PPC_GOT (DT_LOPROC + 0)
-+#define DT_PPC_NUM 1
-+
-+/* PowerPC64 relocations defined by the ABIs */
-+#define R_PPC64_NONE R_PPC_NONE
-+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */
-+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */
-+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */
-+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */
-+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */
-+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
-+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */
-+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
-+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
-+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
-+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */
-+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
-+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
-+#define R_PPC64_GOT16 R_PPC_GOT16
-+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
-+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
-+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
-+
-+#define R_PPC64_COPY R_PPC_COPY
-+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
-+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
-+#define R_PPC64_RELATIVE R_PPC_RELATIVE
-+
-+#define R_PPC64_UADDR32 R_PPC_UADDR32
-+#define R_PPC64_UADDR16 R_PPC_UADDR16
-+#define R_PPC64_REL32 R_PPC_REL32
-+#define R_PPC64_PLT32 R_PPC_PLT32
-+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
-+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
-+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
-+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
-+
-+#define R_PPC64_SECTOFF R_PPC_SECTOFF
-+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
-+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
-+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
-+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */
-+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */
-+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */
-+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */
-+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */
-+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */
-+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */
-+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */
-+#define R_PPC64_PLT64 45 /* doubleword64 L + A */
-+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */
-+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */
-+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */
-+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */
-+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */
-+#define R_PPC64_TOC 51 /* doubleword64 .TOC */
-+#define R_PPC64_PLTGOT16 52 /* half16* M + A */
-+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */
-+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */
-+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */
-+
-+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */
-+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */
-+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */
-+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */
-+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */
-+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */
-+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */
-+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */
-+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */
-+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */
-+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */
-+
-+/* PowerPC64 relocations defined for the TLS access ABI. */
-+#define R_PPC64_TLS 67 /* none (sym+add)@tls */
-+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
-+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
-+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
-+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
-+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
-+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
-+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
-+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
-+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
-+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
-+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
-+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
-+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
-+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
-+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
-+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
-+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
-+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
-+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
-+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
-+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
-+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
-+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
-+
-+/* GNU extension to support local ifunc. */
-+#define R_PPC64_JMP_IREL 247
-+#define R_PPC64_IRELATIVE 248
-+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */
-+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */
-+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */
-+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */
-+
-+/* PowerPC64 specific values for the Dyn d_tag field. */
-+#define DT_PPC64_GLINK (DT_LOPROC + 0)
-+#define DT_PPC64_OPD (DT_LOPROC + 1)
-+#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
-+#define DT_PPC64_NUM 3
-+
-+
-+/* ARM specific declarations */
-+
-+/* Processor specific flags for the ELF header e_flags field. */
-+#define EF_ARM_RELEXEC 0x01
-+#define EF_ARM_HASENTRY 0x02
-+#define EF_ARM_INTERWORK 0x04
-+#define EF_ARM_APCS_26 0x08
-+#define EF_ARM_APCS_FLOAT 0x10
-+#define EF_ARM_PIC 0x20
-+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
-+#define EF_ARM_NEW_ABI 0x80
-+#define EF_ARM_OLD_ABI 0x100
-+#define EF_ARM_SOFT_FLOAT 0x200
-+#define EF_ARM_VFP_FLOAT 0x400
-+#define EF_ARM_MAVERICK_FLOAT 0x800
-+
-+
-+/* Other constants defined in the ARM ELF spec. version B-01. */
-+/* NB. These conflict with values defined above. */
-+#define EF_ARM_SYMSARESORTED 0x04
-+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
-+#define EF_ARM_MAPSYMSFIRST 0x10
-+#define EF_ARM_EABIMASK 0XFF000000
-+
-+/* Constants defined in AAELF. */
-+#define EF_ARM_BE8 0x00800000
-+#define EF_ARM_LE8 0x00400000
-+
-+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
-+#define EF_ARM_EABI_UNKNOWN 0x00000000
-+#define EF_ARM_EABI_VER1 0x01000000
-+#define EF_ARM_EABI_VER2 0x02000000
-+#define EF_ARM_EABI_VER3 0x03000000
-+#define EF_ARM_EABI_VER4 0x04000000
-+#define EF_ARM_EABI_VER5 0x05000000
-+
-+/* Additional symbol types for Thumb. */
-+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
-+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
-+
-+/* ARM-specific values for sh_flags */
-+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
-+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
-+ in the input to a link step. */
-+
-+/* ARM-specific program header flags */
-+#define PF_ARM_SB 0x10000000 /* Segment contains the location
-+ addressed by the static base. */
-+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */
-+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */
-+
-+/* Processor specific values for the Phdr p_type field. */
-+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
-+
-+/* Processor specific values for the Shdr sh_type field. */
-+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
-+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
-+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
-+
-+
-+/* ARM relocs. */
-+
-+#define R_ARM_NONE 0 /* No reloc */
-+#define R_ARM_PC24 1 /* PC relative 26 bit branch */
-+#define R_ARM_ABS32 2 /* Direct 32 bit */
-+#define R_ARM_REL32 3 /* PC relative 32 bit */
-+#define R_ARM_PC13 4
-+#define R_ARM_ABS16 5 /* Direct 16 bit */
-+#define R_ARM_ABS12 6 /* Direct 12 bit */
-+#define R_ARM_THM_ABS5 7
-+#define R_ARM_ABS8 8 /* Direct 8 bit */
-+#define R_ARM_SBREL32 9
-+#define R_ARM_THM_PC22 10
-+#define R_ARM_THM_PC8 11
-+#define R_ARM_AMP_VCALL9 12
-+#define R_ARM_SWI24 13 /* Obsolete static relocation. */
-+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */
-+#define R_ARM_THM_SWI8 14
-+#define R_ARM_XPC25 15
-+#define R_ARM_THM_XPC22 16
-+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
-+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
-+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
-+#define R_ARM_COPY 20 /* Copy symbol at runtime */
-+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
-+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
-+#define R_ARM_RELATIVE 23 /* Adjust by program base */
-+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
-+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
-+#define R_ARM_GOT32 26 /* 32 bit GOT entry */
-+#define R_ARM_PLT32 27 /* 32 bit PLT address */
-+#define R_ARM_ALU_PCREL_7_0 32
-+#define R_ARM_ALU_PCREL_15_8 33
-+#define R_ARM_ALU_PCREL_23_15 34
-+#define R_ARM_LDR_SBREL_11_0 35
-+#define R_ARM_ALU_SBREL_19_12 36
-+#define R_ARM_ALU_SBREL_27_20 37
-+#define R_ARM_TLS_GOTDESC 90
-+#define R_ARM_TLS_CALL 91
-+#define R_ARM_TLS_DESCSEQ 92
-+#define R_ARM_THM_TLS_CALL 93
-+#define R_ARM_GNU_VTENTRY 100
-+#define R_ARM_GNU_VTINHERIT 101
-+#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
-+#define R_ARM_THM_PC9 103 /* thumb conditional branch */
-+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic
-+ thread local data */
-+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic
-+ thread local data */
-+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS
-+ block */
-+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of
-+ static TLS block offset */
-+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static
-+ TLS block */
-+#define R_ARM_THM_TLS_DESCSEQ 129
-+#define R_ARM_IRELATIVE 160
-+#define R_ARM_RXPC25 249
-+#define R_ARM_RSBREL32 250
-+#define R_ARM_THM_RPC22 251
-+#define R_ARM_RREL32 252
-+#define R_ARM_RABS22 253
-+#define R_ARM_RPC24 254
-+#define R_ARM_RBASE 255
-+/* Keep this the last entry. */
-+#define R_ARM_NUM 256
-+
-+/* IA-64 specific declarations. */
-+
-+/* Processor specific flags for the Ehdr e_flags field. */
-+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
-+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
-+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
-+
-+/* Processor specific values for the Phdr p_type field. */
-+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
-+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
-+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
-+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
-+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
-+
-+/* Processor specific flags for the Phdr p_flags field. */
-+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
-+
-+/* Processor specific values for the Shdr sh_type field. */
-+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
-+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
-+
-+/* Processor specific flags for the Shdr sh_flags field. */
-+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
-+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
-+
-+/* Processor specific values for the Dyn d_tag field. */
-+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
-+#define DT_IA_64_NUM 1
-+
-+/* IA-64 relocations. */
-+#define R_IA64_NONE 0x00 /* none */
-+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
-+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
-+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
-+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
-+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
-+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
-+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
-+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
-+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
-+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */
-+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */
-+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
-+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
-+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
-+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
-+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
-+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
-+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
-+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
-+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
-+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
-+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
-+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
-+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */
-+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
-+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
-+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
-+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
-+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
-+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
-+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
-+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
-+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */
-+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */
-+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */
-+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */
-+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
-+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
-+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
-+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
-+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
-+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
-+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
-+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
-+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
-+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
-+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
-+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
-+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
-+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
-+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
-+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
-+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */
-+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */
-+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */
-+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
-+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
-+#define R_IA64_COPY 0x84 /* copy relocation */
-+#define R_IA64_SUB 0x85 /* Addend and symbol difference */
-+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
-+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
-+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */
-+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */
-+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */
-+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */
-+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */
-+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */
-+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */
-+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */
-+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */
-+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */
-+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */
-+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */
-+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */
-+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
-+
-+/* SH specific declarations */
-+
-+/* Processor specific flags for the ELF header e_flags field. */
-+#define EF_SH_MACH_MASK 0x1f
-+#define EF_SH_UNKNOWN 0x0
-+#define EF_SH1 0x1
-+#define EF_SH2 0x2
-+#define EF_SH3 0x3
-+#define EF_SH_DSP 0x4
-+#define EF_SH3_DSP 0x5
-+#define EF_SH4AL_DSP 0x6
-+#define EF_SH3E 0x8
-+#define EF_SH4 0x9
-+#define EF_SH2E 0xb
-+#define EF_SH4A 0xc
-+#define EF_SH2A 0xd
-+#define EF_SH4_NOFPU 0x10
-+#define EF_SH4A_NOFPU 0x11
-+#define EF_SH4_NOMMU_NOFPU 0x12
-+#define EF_SH2A_NOFPU 0x13
-+#define EF_SH3_NOMMU 0x14
-+#define EF_SH2A_SH4_NOFPU 0x15
-+#define EF_SH2A_SH3_NOFPU 0x16
-+#define EF_SH2A_SH4 0x17
-+#define EF_SH2A_SH3E 0x18
-+
-+/* SH relocs. */
-+#define R_SH_NONE 0
-+#define R_SH_DIR32 1
-+#define R_SH_REL32 2
-+#define R_SH_DIR8WPN 3
-+#define R_SH_IND12W 4
-+#define R_SH_DIR8WPL 5
-+#define R_SH_DIR8WPZ 6
-+#define R_SH_DIR8BP 7
-+#define R_SH_DIR8W 8
-+#define R_SH_DIR8L 9
-+#define R_SH_SWITCH16 25
-+#define R_SH_SWITCH32 26
-+#define R_SH_USES 27
-+#define R_SH_COUNT 28
-+#define R_SH_ALIGN 29
-+#define R_SH_CODE 30
-+#define R_SH_DATA 31
-+#define R_SH_LABEL 32
-+#define R_SH_SWITCH8 33
-+#define R_SH_GNU_VTINHERIT 34
-+#define R_SH_GNU_VTENTRY 35
-+#define R_SH_TLS_GD_32 144
-+#define R_SH_TLS_LD_32 145
-+#define R_SH_TLS_LDO_32 146
-+#define R_SH_TLS_IE_32 147
-+#define R_SH_TLS_LE_32 148
-+#define R_SH_TLS_DTPMOD32 149
-+#define R_SH_TLS_DTPOFF32 150
-+#define R_SH_TLS_TPOFF32 151
-+#define R_SH_GOT32 160
-+#define R_SH_PLT32 161
-+#define R_SH_COPY 162
-+#define R_SH_GLOB_DAT 163
-+#define R_SH_JMP_SLOT 164
-+#define R_SH_RELATIVE 165
-+#define R_SH_GOTOFF 166
-+#define R_SH_GOTPC 167
-+/* Keep this the last entry. */
-+#define R_SH_NUM 256
-+
-+/* S/390 specific definitions. */
-+
-+/* Valid values for the e_flags field. */
-+
-+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */
-+
-+/* Additional s390 relocs */
-+
-+#define R_390_NONE 0 /* No reloc. */
-+#define R_390_8 1 /* Direct 8 bit. */
-+#define R_390_12 2 /* Direct 12 bit. */
-+#define R_390_16 3 /* Direct 16 bit. */
-+#define R_390_32 4 /* Direct 32 bit. */
-+#define R_390_PC32 5 /* PC relative 32 bit. */
-+#define R_390_GOT12 6 /* 12 bit GOT offset. */
-+#define R_390_GOT32 7 /* 32 bit GOT offset. */
-+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
-+#define R_390_COPY 9 /* Copy symbol at runtime. */
-+#define R_390_GLOB_DAT 10 /* Create GOT entry. */
-+#define R_390_JMP_SLOT 11 /* Create PLT entry. */
-+#define R_390_RELATIVE 12 /* Adjust by program base. */
-+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
-+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */
-+#define R_390_GOT16 15 /* 16 bit GOT offset. */
-+#define R_390_PC16 16 /* PC relative 16 bit. */
-+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
-+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
-+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
-+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
-+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
-+#define R_390_64 22 /* Direct 64 bit. */
-+#define R_390_PC64 23 /* PC relative 64 bit. */
-+#define R_390_GOT64 24 /* 64 bit GOT offset. */
-+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
-+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
-+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
-+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
-+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
-+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
-+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
-+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
-+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
-+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
-+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
-+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
-+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
-+#define R_390_TLS_GDCALL 38 /* Tag for function call in general
-+ dynamic TLS code. */
-+#define R_390_TLS_LDCALL 39 /* Tag for function call in local
-+ dynamic TLS code. */
-+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
-+ thread local data. */
-+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
-+ thread local data. */
-+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
-+ thread local data in LE code. */
-+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
-+ thread local data in LE code. */
-+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
-+ negated static TLS block offset. */
-+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
-+ negated static TLS block offset. */
-+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
-+ negated static TLS block offset. */
-+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
-+ static TLS block. */
-+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
-+ static TLS block. */
-+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
-+ block. */
-+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
-+ block. */
-+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
-+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
-+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
-+ block. */
-+#define R_390_20 57 /* Direct 20 bit. */
-+#define R_390_GOT20 58 /* 20 bit GOT offset. */
-+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
-+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */
-+/* Keep this the last entry. */
-+#define R_390_NUM 62
-+
-+
-+/* CRIS relocations. */
-+#define R_CRIS_NONE 0
-+#define R_CRIS_8 1
-+#define R_CRIS_16 2
-+#define R_CRIS_32 3
-+#define R_CRIS_8_PCREL 4
-+#define R_CRIS_16_PCREL 5
-+#define R_CRIS_32_PCREL 6
-+#define R_CRIS_GNU_VTINHERIT 7
-+#define R_CRIS_GNU_VTENTRY 8
-+#define R_CRIS_COPY 9
-+#define R_CRIS_GLOB_DAT 10
-+#define R_CRIS_JUMP_SLOT 11
-+#define R_CRIS_RELATIVE 12
-+#define R_CRIS_16_GOT 13
-+#define R_CRIS_32_GOT 14
-+#define R_CRIS_16_GOTPLT 15
-+#define R_CRIS_32_GOTPLT 16
-+#define R_CRIS_32_GOTREL 17
-+#define R_CRIS_32_PLT_GOTREL 18
-+#define R_CRIS_32_PLT_PCREL 19
-+
-+#define R_CRIS_NUM 20
-+
-+
-+/* AMD x86-64 relocations. */
-+#define R_X86_64_NONE 0 /* No reloc */
-+#define R_X86_64_64 1 /* Direct 64 bit */
-+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
-+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
-+#define R_X86_64_PLT32 4 /* 32 bit PLT address */
-+#define R_X86_64_COPY 5 /* Copy symbol at runtime */
-+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
-+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
-+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
-+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative
-+ offset to GOT */
-+#define R_X86_64_32 10 /* Direct 32 bit zero extended */
-+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
-+#define R_X86_64_16 12 /* Direct 16 bit zero extended */
-+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
-+#define R_X86_64_8 14 /* Direct 8 bit sign extended */
-+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
-+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
-+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
-+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
-+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset
-+ to two GOT entries for GD symbol */
-+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset
-+ to two GOT entries for LD symbol */
-+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
-+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
-+ to GOT entry for IE symbol */
-+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
-+#define R_X86_64_PC64 24 /* PC relative 64 bit */
-+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
-+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative
-+ offset to GOT */
-+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
-+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset
-+ to GOT entry */
-+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
-+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
-+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset
-+ to PLT entry */
-+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
-+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
-+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
-+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS
-+ descriptor. */
-+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
-+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
-+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
-+
-+#define R_X86_64_NUM 39
-+
-+
-+/* AM33 relocations. */
-+#define R_MN10300_NONE 0 /* No reloc. */
-+#define R_MN10300_32 1 /* Direct 32 bit. */
-+#define R_MN10300_16 2 /* Direct 16 bit. */
-+#define R_MN10300_8 3 /* Direct 8 bit. */
-+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */
-+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */
-+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */
-+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */
-+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */
-+#define R_MN10300_24 9 /* Direct 24 bit. */
-+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */
-+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */
-+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */
-+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */
-+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */
-+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */
-+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */
-+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */
-+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */
-+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */
-+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */
-+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */
-+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */
-+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */
-+
-+#define R_MN10300_NUM 24
-+
-+
-+/* M32R relocs. */
-+#define R_M32R_NONE 0 /* No reloc. */
-+#define R_M32R_16 1 /* Direct 16 bit. */
-+#define R_M32R_32 2 /* Direct 32 bit. */
-+#define R_M32R_24 3 /* Direct 24 bit. */
-+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */
-+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */
-+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */
-+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */
-+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */
-+#define R_M32R_LO16 9 /* Low 16 bit. */
-+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */
-+#define R_M32R_GNU_VTINHERIT 11
-+#define R_M32R_GNU_VTENTRY 12
-+/* M32R relocs use SHT_RELA. */
-+#define R_M32R_16_RELA 33 /* Direct 16 bit. */
-+#define R_M32R_32_RELA 34 /* Direct 32 bit. */
-+#define R_M32R_24_RELA 35 /* Direct 24 bit. */
-+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */
-+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */
-+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */
-+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */
-+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */
-+#define R_M32R_LO16_RELA 41 /* Low 16 bit */
-+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */
-+#define R_M32R_RELA_GNU_VTINHERIT 43
-+#define R_M32R_RELA_GNU_VTENTRY 44
-+#define R_M32R_REL32 45 /* PC relative 32 bit. */
-+
-+#define R_M32R_GOT24 48 /* 24 bit GOT entry */
-+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */
-+#define R_M32R_COPY 50 /* Copy symbol at runtime */
-+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */
-+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */
-+#define R_M32R_RELATIVE 53 /* Adjust by program base */
-+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */
-+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */
-+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned
-+ low */
-+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed
-+ low */
-+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */
-+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to
-+ GOT with unsigned low */
-+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to
-+ GOT with signed low */
-+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to
-+ GOT */
-+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT
-+ with unsigned low */
-+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT
-+ with signed low */
-+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */
-+#define R_M32R_NUM 256 /* Keep this the last entry. */
-+
-+
-+/* TILEPro relocations. */
-+#define R_TILEPRO_NONE 0 /* No reloc */
-+#define R_TILEPRO_32 1 /* Direct 32 bit */
-+#define R_TILEPRO_16 2 /* Direct 16 bit */
-+#define R_TILEPRO_8 3 /* Direct 8 bit */
-+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */
-+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */
-+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */
-+#define R_TILEPRO_LO16 7 /* Low 16 bit */
-+#define R_TILEPRO_HI16 8 /* High 16 bit */
-+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */
-+#define R_TILEPRO_COPY 10 /* Copy relocation */
-+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */
-+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */
-+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */
-+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */
-+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */
-+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */
-+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */
-+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */
-+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */
-+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */
-+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */
-+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */
-+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */
-+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */
-+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */
-+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */
-+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */
-+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */
-+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */
-+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */
-+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */
-+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */
-+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */
-+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */
-+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */
-+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */
-+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */
-+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */
-+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */
-+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */
-+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */
-+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */
-+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */
-+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */
-+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */
-+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */
-+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */
-+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */
-+/* Relocs 56-59 are currently not defined. */
-+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */
-+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */
-+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */
-+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */
-+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */
-+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */
-+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */
-+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */
-+
-+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
-+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
-+
-+#define R_TILEPRO_NUM 130
-+
-+
-+/* TILE-Gx relocations. */
-+#define R_TILEGX_NONE 0 /* No reloc */
-+#define R_TILEGX_64 1 /* Direct 64 bit */
-+#define R_TILEGX_32 2 /* Direct 32 bit */
-+#define R_TILEGX_16 3 /* Direct 16 bit */
-+#define R_TILEGX_8 4 /* Direct 8 bit */
-+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */
-+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */
-+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */
-+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */
-+#define R_TILEGX_HW0 9 /* hword 0 16-bit */
-+#define R_TILEGX_HW1 10 /* hword 1 16-bit */
-+#define R_TILEGX_HW2 11 /* hword 2 16-bit */
-+#define R_TILEGX_HW3 12 /* hword 3 16-bit */
-+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */
-+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */
-+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */
-+#define R_TILEGX_COPY 16 /* Copy relocation */
-+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */
-+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */
-+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */
-+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */
-+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */
-+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */
-+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */
-+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */
-+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */
-+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */
-+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */
-+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */
-+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */
-+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */
-+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */
-+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */
-+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */
-+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */
-+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */
-+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */
-+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */
-+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */
-+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */
-+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */
-+/* Relocs 66-71 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
-+/* Relocs 76-77 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
-+/* Relocs 90-91 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */
-+/* Relocs 94-99 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
-+/* Relocs 104-105 are currently not defined. */
-+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */
-+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */
-+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */
-+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */
-+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */
-+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */
-+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */
-+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */
-+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */
-+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */
-+
-+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
-+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
-+
-+#define R_TILEGX_NUM 130
-+
-+#endif /* elf.h */
---- a/scripts/mod/mk_elfconfig.c
-+++ b/scripts/mod/mk_elfconfig.c
-@@ -2,7 +2,11 @@
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-+#ifndef __APPLE__
- #include <elf.h>
-+#else
-+#include "elf.h"
-+#endif
-
- int
- main(int argc, char **argv)
---- a/scripts/mod/modpost.h
-+++ b/scripts/mod/modpost.h
-@@ -8,7 +8,11 @@
- #include <sys/mman.h>
- #include <fcntl.h>
- #include <unistd.h>
-+#if !(defined(__APPLE__) || defined(__CYGWIN__))
- #include <elf.h>
-+#else
-+#include "elf.h"
-+#endif
-
- #include "elfconfig.h"
-
diff --git a/target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch b/target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch
deleted file mode 100644
index 50a6227148..0000000000
--- a/target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001
-From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
-Date: Wed, 5 Feb 2020 18:36:43 +0000
-Subject: [PATCH] file2alias: build on macos
-
-Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
----
- scripts/mod/file2alias.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/scripts/mod/file2alias.c
-+++ b/scripts/mod/file2alias.c
-@@ -38,6 +38,9 @@ typedef struct {
- __u8 b[16];
- } guid_t;
-
-+#ifdef __APPLE__
-+#define uuid_t compat_uuid_t
-+#endif
- /* backwards compatibility, don't use in new code */
- typedef struct {
- __u8 b[16];
diff --git a/target/linux/generic/hack-5.15/212-tools_portability.patch b/target/linux/generic/hack-5.15/212-tools_portability.patch
deleted file mode 100644
index b488155f94..0000000000
--- a/target/linux/generic/hack-5.15/212-tools_portability.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:03:16 +0200
-Subject: fix portability of some includes files in tools/ used on the host
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- tools/include/tools/be_byteshift.h | 4 ++++
- tools/include/tools/le_byteshift.h | 4 ++++
- tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++
- 3 files changed, 30 insertions(+)
- create mode 100644 tools/include/tools/linux_types.h
-
---- a/tools/include/tools/be_byteshift.h
-+++ b/tools/include/tools/be_byteshift.h
-@@ -2,6 +2,10 @@
- #ifndef _TOOLS_BE_BYTESHIFT_H
- #define _TOOLS_BE_BYTESHIFT_H
-
-+#ifndef __linux__
-+#include "linux_types.h"
-+#endif
-+
- #include <stdint.h>
-
- static inline uint16_t __get_unaligned_be16(const uint8_t *p)
---- a/tools/include/tools/le_byteshift.h
-+++ b/tools/include/tools/le_byteshift.h
-@@ -2,6 +2,10 @@
- #ifndef _TOOLS_LE_BYTESHIFT_H
- #define _TOOLS_LE_BYTESHIFT_H
-
-+#ifndef __linux__
-+#include "linux_types.h"
-+#endif
-+
- #include <stdint.h>
-
- static inline uint16_t __get_unaligned_le16(const uint8_t *p)
---- /dev/null
-+++ b/tools/include/tools/linux_types.h
-@@ -0,0 +1,26 @@
-+#ifndef __LINUX_TYPES_H
-+#define __LINUX_TYPES_H
-+
-+#include <stdint.h>
-+
-+typedef int8_t __s8;
-+typedef uint8_t __u8;
-+typedef uint8_t __be8;
-+typedef uint8_t __le8;
-+
-+typedef int16_t __s16;
-+typedef uint16_t __u16;
-+typedef uint16_t __be16;
-+typedef uint16_t __le16;
-+
-+typedef int32_t __s32;
-+typedef uint32_t __u32;
-+typedef uint32_t __be32;
-+typedef uint32_t __le32;
-+
-+typedef int64_t __s64;
-+typedef uint64_t __u64;
-+typedef uint64_t __be64;
-+typedef uint64_t __le64;
-+
-+#endif
---- a/tools/include/linux/types.h
-+++ b/tools/include/linux/types.h
-@@ -10,8 +10,12 @@
- #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */
- #endif
-
-+#ifndef __linux__
-+#include <tools/linux_types.h>
-+#else
- #include <asm/types.h>
- #include <asm/posix_types.h>
-+#endif
-
- struct page;
- struct kmem_cache;
---- a/tools/perf/pmu-events/jevents.c
-+++ b/tools/perf/pmu-events/jevents.c
-@@ -1,4 +1,6 @@
-+#ifdef __linux__
- #define _XOPEN_SOURCE 500 /* needed for nftw() */
-+#endif
- #define _GNU_SOURCE /* needed for asprintf() */
-
- /* Parse event JSON files */
-@@ -35,6 +37,7 @@
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
-+#include <strings.h>
- #include <ctype.h>
- #include <unistd.h>
- #include <stdarg.h>
---- a/tools/perf/pmu-events/json.c
-+++ b/tools/perf/pmu-events/json.c
-@@ -38,7 +38,6 @@
- #include <unistd.h>
- #include "jsmn.h"
- #include "json.h"
--#include <linux/kernel.h>
-
-
- static char *mapfile(const char *fn, size_t *size)
diff --git a/target/linux/generic/hack-5.15/214-spidev_h_portability.patch b/target/linux/generic/hack-5.15/214-spidev_h_portability.patch
deleted file mode 100644
index db754a2903..0000000000
--- a/target/linux/generic/hack-5.15/214-spidev_h_portability.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:04:08 +0200
-Subject: kernel: fix linux/spi/spidev.h portability issues with musl
-
-Felix will try to get this define included into musl
-
-lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/uapi/linux/spi/spidev.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/uapi/linux/spi/spidev.h
-+++ b/include/uapi/linux/spi/spidev.h
-@@ -93,7 +93,7 @@ struct spi_ioc_transfer {
-
- /* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
- #define SPI_MSGSIZE(N) \
-- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
-+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \
- ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
- #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
-
diff --git a/target/linux/generic/hack-5.15/220-arm-gc_sections.patch b/target/linux/generic/hack-5.15/220-arm-gc_sections.patch
deleted file mode 100644
index dd6507c917..0000000000
--- a/target/linux/generic/hack-5.15/220-arm-gc_sections.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 15 Jul 2017 23:42:36 +0200
-Subject: use -ffunction-sections, -fdata-sections and --gc-sections
-
-In combination with kernel symbol export stripping this significantly reduces
-the kernel image size. Used on both ARM and MIPS architectures.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -118,6 +118,7 @@ config ARM
- select HAVE_UID16
- select HAVE_VIRT_CPU_ACCOUNTING_GEN
- select IRQ_FORCED_THREADING
-+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
- select MODULES_USE_ELF_REL
- select NEED_DMA_MAP_STATE
- select OF_EARLY_FLATTREE if OF
---- a/arch/arm/boot/compressed/Makefile
-+++ b/arch/arm/boot/compressed/Makefile
-@@ -92,6 +92,7 @@ endif
- ifeq ($(CONFIG_USE_OF),y)
- OBJS += $(libfdt_objs) fdt_check_mem_start.o
- endif
-+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL))
-
- # -fstack-protector-strong triggers protection checks in this code,
- # but it is being used too early to link to meaningful stack_chk logic.
---- a/arch/arm/kernel/vmlinux.lds.S
-+++ b/arch/arm/kernel/vmlinux.lds.S
-@@ -75,7 +75,7 @@ SECTIONS
- . = ALIGN(4);
- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
- __start___ex_table = .;
-- ARM_MMU_KEEP(*(__ex_table))
-+ KEEP(*(__ex_table))
- __stop___ex_table = .;
- }
-
-@@ -100,24 +100,24 @@ SECTIONS
- }
- .init.arch.info : {
- __arch_info_begin = .;
-- *(.arch.info.init)
-+ KEEP(*(.arch.info.init))
- __arch_info_end = .;
- }
- .init.tagtable : {
- __tagtable_begin = .;
-- *(.taglist.init)
-+ KEEP(*(.taglist.init))
- __tagtable_end = .;
- }
- #ifdef CONFIG_SMP_ON_UP
- .init.smpalt : {
- __smpalt_begin = .;
-- *(.alt.smp.init)
-+ KEEP(*(.alt.smp.init))
- __smpalt_end = .;
- }
- #endif
- .init.pv_table : {
- __pv_table_begin = .;
-- *(.pv_table)
-+ KEEP(*(.pv_table))
- __pv_table_end = .;
- }
-
---- a/arch/arm/include/asm/vmlinux.lds.h
-+++ b/arch/arm/include/asm/vmlinux.lds.h
-@@ -42,13 +42,13 @@
- #define PROC_INFO \
- . = ALIGN(4); \
- __proc_info_begin = .; \
-- *(.proc.info.init) \
-+ KEEP(*(.proc.info.init)) \
- __proc_info_end = .;
-
- #define IDMAP_TEXT \
- ALIGN_FUNCTION(); \
- __idmap_text_start = .; \
-- *(.idmap.text) \
-+ KEEP(*(.idmap.text)) \
- __idmap_text_end = .; \
-
- #define ARM_DISCARD \
-@@ -109,12 +109,12 @@
- . = ALIGN(8); \
- .ARM.unwind_idx : { \
- __start_unwind_idx = .; \
-- *(.ARM.exidx*) \
-+ KEEP(*(.ARM.exidx*)) \
- __stop_unwind_idx = .; \
- } \
- .ARM.unwind_tab : { \
- __start_unwind_tab = .; \
-- *(.ARM.extab*) \
-+ KEEP(*(.ARM.extab*)) \
- __stop_unwind_tab = .; \
- }
-
-@@ -126,7 +126,7 @@
- __vectors_lma = .; \
- OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
- .vectors { \
-- *(.vectors) \
-+ KEEP(*(.vectors)) \
- } \
- .vectors.bhb.loop8 { \
- *(.vectors.bhb.loop8) \
-@@ -144,7 +144,7 @@
- \
- __stubs_lma = .; \
- .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
-- *(.stubs) \
-+ KEEP(*(.stubs)) \
- } \
- ARM_LMA(__stubs, .stubs); \
- . = __stubs_lma + SIZEOF(.stubs); \
diff --git a/target/linux/generic/hack-5.15/221-module_exports.patch b/target/linux/generic/hack-5.15/221-module_exports.patch
deleted file mode 100644
index 8db0f7dac7..0000000000
--- a/target/linux/generic/hack-5.15/221-module_exports.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:05:53 +0200
-Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image
-
-lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++---
- include/linux/export.h | 9 ++++++++-
- scripts/Makefile.build | 2 +-
- 3 files changed, 24 insertions(+), 5 deletions(-)
-
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -81,6 +81,16 @@
- #define RO_EXCEPTION_TABLE
- #endif
-
-+#ifndef SYMTAB_KEEP
-+#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*)))
-+#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*)))
-+#endif
-+
-+#ifndef SYMTAB_DISCARD
-+#define SYMTAB_DISCARD
-+#define SYMTAB_DISCARD_GPL
-+#endif
-+
- /* Align . function alignment. */
- #define ALIGN_FUNCTION() . = ALIGN(CONFIG_FUNCTION_ALIGNMENT)
-
-@@ -485,14 +495,14 @@
- /* Kernel symbol table: Normal symbols */ \
- __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
- __start___ksymtab = .; \
-- KEEP(*(SORT(___ksymtab+*))) \
-+ SYMTAB_KEEP \
- __stop___ksymtab = .; \
- } \
- \
- /* Kernel symbol table: GPL-only symbols */ \
- __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
- __start___ksymtab_gpl = .; \
-- KEEP(*(SORT(___ksymtab_gpl+*))) \
-+ SYMTAB_KEEP_GPL \
- __stop___ksymtab_gpl = .; \
- } \
- \
-@@ -512,7 +522,7 @@
- \
- /* Kernel symbol table: strings */ \
- __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
-- *(__ksymtab_strings) \
-+ *(__ksymtab_strings+*) \
- } \
- \
- /* __*init sections */ \
-@@ -1022,6 +1032,8 @@
-
- #define COMMON_DISCARDS \
- SANITIZER_DISCARDS \
-+ SYMTAB_DISCARD \
-+ SYMTAB_DISCARD_GPL \
- *(.discard) \
- *(.discard.*) \
- *(.modinfo) \
---- a/include/linux/export.h
-+++ b/include/linux/export.h
-@@ -84,6 +84,12 @@ struct kernel_symbol {
-
- #else
-
-+#ifdef MODULE
-+#define __EXPORT_SUFFIX(sym)
-+#else
-+#define __EXPORT_SUFFIX(sym) "+" #sym
-+#endif
-+
- /*
- * For every exported symbol, do the following:
- *
-@@ -101,7 +107,7 @@ struct kernel_symbol {
- extern const char __kstrtab_##sym[]; \
- extern const char __kstrtabns_##sym[]; \
- __CRC_SYMBOL(sym, sec); \
-- asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
-+ asm(" .section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1 \n" \
- "__kstrtab_" #sym ": \n" \
- " .asciz \"" #sym "\" \n" \
- "__kstrtabns_" #sym ": \n" \
---- a/include/asm-generic/export.h
-+++ b/include/asm-generic/export.h
-@@ -26,6 +26,12 @@
- #endif
- .endm
-
-+#ifdef MODULE
-+#define __EXPORT_SUFFIX(name)
-+#else
-+#define __EXPORT_SUFFIX(name) + #name
-+#endif
-+
- /*
- * note on .section use: we specify progbits since usage of the "M" (SHF_MERGE)
- * section flag requires it. Use '%progbits' instead of '@progbits' since the
-@@ -39,7 +45,7 @@
- __ksymtab_\name:
- __put \val, __kstrtab_\name
- .previous
-- .section __ksymtab_strings,"aMS",%progbits,1
-+ .section __ksymtab_strings __EXPORT_SUFFIX(name),"aMS",%progbits,1
- __kstrtab_\name:
- .asciz "\name"
- .previous
---- a/scripts/Makefile.build
-+++ b/scripts/Makefile.build
-@@ -397,7 +397,7 @@ targets += $(real-dtb-y) $(lib-y) $(alwa
- # Linker scripts preprocessor (.lds.S -> .lds)
- # ---------------------------------------------------------------------------
- quiet_cmd_cpp_lds_S = LDS $@
-- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
-+ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \
- -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
-
- $(obj)/%.lds: $(src)/%.lds.S FORCE
diff --git a/target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch b/target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch
deleted file mode 100644
index f9361b060b..0000000000
--- a/target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001
-From: Imre Kaloz <kaloz@openwrt.org>
-Date: Fri, 7 Jul 2017 17:06:55 +0200
-Subject: use the openwrt lzma options for now
-
-lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- lib/decompress.c | 1 +
- scripts/Makefile.lib | 2 +-
- usr/gen_initramfs_list.sh | 10 +++++-----
- 3 files changed, 7 insertions(+), 6 deletions(-)
-
---- a/lib/decompress.c
-+++ b/lib/decompress.c
-@@ -53,6 +53,7 @@ static const struct compress_format comp
- { {0x1f, 0x9e}, "gzip", gunzip },
- { {0x42, 0x5a}, "bzip2", bunzip2 },
- { {0x5d, 0x00}, "lzma", unlzma },
-+ { {0x6d, 0x00}, "lzma-openwrt", unlzma },
- { {0xfd, 0x37}, "xz", unxz },
- { {0x89, 0x4c}, "lzo", unlzo },
- { {0x02, 0x21}, "lz4", unlz4 },
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -402,7 +402,7 @@ quiet_cmd_bzip2 = BZIP2 $@
- # ---------------------------------------------------------------------------
-
- quiet_cmd_lzma = LZMA $@
-- cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
-+ cmd_lzma = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@
-
- quiet_cmd_lzo = LZO $@
- cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
diff --git a/target/linux/generic/hack-5.15/250-netfilter_depends.patch b/target/linux/generic/hack-5.15/250-netfilter_depends.patch
deleted file mode 100644
index 1f8af6dbe8..0000000000
--- a/target/linux/generic/hack-5.15/250-netfilter_depends.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: hack: net: remove bogus netfilter dependencies
-
-lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/netfilter/Kconfig | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -242,7 +242,6 @@ config NF_CONNTRACK_FTP
-
- config NF_CONNTRACK_H323
- tristate "H.323 protocol support"
-- depends on IPV6 || IPV6=n
- depends on NETFILTER_ADVANCED
- help
- H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -1114,7 +1113,6 @@ config NETFILTER_XT_TARGET_SECMARK
-
- config NETFILTER_XT_TARGET_TCPMSS
- tristate '"TCPMSS" target support'
-- depends on IPV6 || IPV6=n
- default m if NETFILTER_ADVANCED=n
- help
- This option adds a `TCPMSS' target, which allows you to alter the
diff --git a/target/linux/generic/hack-5.15/251-kconfig.patch b/target/linux/generic/hack-5.15/251-kconfig.patch
deleted file mode 100644
index 00c23db955..0000000000
--- a/target/linux/generic/hack-5.15/251-kconfig.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 7 Jul 2017 17:09:21 +0200
-Subject: kconfig: owrt specifc dependencies
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- crypto/Kconfig | 10 +++++-----
- drivers/bcma/Kconfig | 1 +
- drivers/ssb/Kconfig | 3 ++-
- lib/Kconfig | 8 ++++----
- net/netfilter/Kconfig | 2 +-
- net/wireless/Kconfig | 17 ++++++++++-------
- sound/core/Kconfig | 4 ++--
- 7 files changed, 25 insertions(+), 20 deletions(-)
-
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -34,7 +34,7 @@ config CRYPTO_FIPS
- this is.
-
- config CRYPTO_ALGAPI
-- tristate
-+ tristate "ALGAPI"
- select CRYPTO_ALGAPI2
- help
- This option provides the API for cryptographic algorithms.
-@@ -43,7 +43,7 @@ config CRYPTO_ALGAPI2
- tristate
-
- config CRYPTO_AEAD
-- tristate
-+ tristate "AEAD"
- select CRYPTO_AEAD2
- select CRYPTO_ALGAPI
-
-@@ -54,7 +54,7 @@ config CRYPTO_AEAD2
- select CRYPTO_RNG2
-
- config CRYPTO_SKCIPHER
-- tristate
-+ tristate "SKCIPHER"
- select CRYPTO_SKCIPHER2
- select CRYPTO_ALGAPI
-
-@@ -64,7 +64,7 @@ config CRYPTO_SKCIPHER2
- select CRYPTO_RNG2
-
- config CRYPTO_HASH
-- tristate
-+ tristate "HASH"
- select CRYPTO_HASH2
- select CRYPTO_ALGAPI
-
-@@ -73,7 +73,7 @@ config CRYPTO_HASH2
- select CRYPTO_ALGAPI2
-
- config CRYPTO_RNG
-- tristate
-+ tristate "RNG"
- select CRYPTO_RNG2
- select CRYPTO_ALGAPI
-
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -16,6 +16,7 @@ if BCMA
- # Support for Block-I/O. SELECT this from the driver that needs it.
- config BCMA_BLOCKIO
- bool
-+ default y
-
- config BCMA_HOST_PCI_POSSIBLE
- bool
---- a/drivers/ssb/Kconfig
-+++ b/drivers/ssb/Kconfig
-@@ -29,6 +29,7 @@ config SSB_SPROM
- config SSB_BLOCKIO
- bool
- depends on SSB
-+ default y
-
- config SSB_PCIHOST_POSSIBLE
- bool
-@@ -49,7 +50,7 @@ config SSB_PCIHOST
- config SSB_B43_PCI_BRIDGE
- bool
- depends on SSB_PCIHOST
-- default n
-+ default y
-
- config SSB_PCMCIAHOST_POSSIBLE
- bool
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -443,16 +443,16 @@ config BCH_CONST_T
- # Textsearch support is select'ed if needed
- #
- config TEXTSEARCH
-- bool
-+ bool "Textsearch support"
-
- config TEXTSEARCH_KMP
-- tristate
-+ tristate "Textsearch KMP"
-
- config TEXTSEARCH_BM
-- tristate
-+ tristate "Textsearch BM"
-
- config TEXTSEARCH_FSM
-- tristate
-+ tristate "Textsearch FSM"
-
- config BTREE
- bool
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -11,7 +11,7 @@ config NETFILTER_INGRESS
- infrastructure.
-
- config NETFILTER_NETLINK
-- tristate
-+ tristate "Netfilter NFNETLINK interface"
-
- config NETFILTER_FAMILY_BRIDGE
- bool
---- a/sound/core/Kconfig
-+++ b/sound/core/Kconfig
-@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM
- tristate
-
- config SND_HWDEP
-- tristate
-+ tristate "Sound hardware support"
-
- config SND_SEQ_DEVICE
- tristate
-@@ -27,7 +27,7 @@ config SND_RAWMIDI
- select SND_SEQ_DEVICE if SND_SEQUENCER != n
-
- config SND_COMPRESS_OFFLOAD
-- tristate
-+ tristate "Compression offloading support"
-
- config SND_JACK
- bool
---- a/net/Kconfig
-+++ b/net/Kconfig
-@@ -430,7 +430,7 @@ config NET_DEVLINK
- default n
-
- config PAGE_POOL
-- bool
-+ bool "Page pool support"
-
- config PAGE_POOL_STATS
- default n
diff --git a/target/linux/generic/hack-5.15/253-ksmbd-config.patch b/target/linux/generic/hack-5.15/253-ksmbd-config.patch
deleted file mode 100644
index b8cb94f62b..0000000000
--- a/target/linux/generic/hack-5.15/253-ksmbd-config.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From dcd966fa7ca63f38cf7147e1184d13d66e2ca340 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:33:30 +0200
-Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
-
----
- init/Kconfig | 2 +-
- lib/Kconfig | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -2388,7 +2388,7 @@ config PADATA
- bool
-
- config ASN1
-- tristate
-+ tristate "ASN1"
- help
- Build a simple ASN.1 grammar compiler that produces a bytecode output
- that can be interpreted by the ASN.1 stream decoder and used to
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -614,7 +614,7 @@ config LIBFDT
- bool
-
- config OID_REGISTRY
-- tristate
-+ tristate "OID"
- help
- Enable fast lookup object identifier registry.
-
diff --git a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch b/target/linux/generic/hack-5.15/259-regmap_dynamic.patch
deleted file mode 100644
index ea06821c4b..0000000000
--- a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 15 Jul 2017 21:12:38 +0200
-Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules
-
-lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/base/regmap/Kconfig | 15 ++++++++++-----
- drivers/base/regmap/Makefile | 12 ++++++++----
- drivers/base/regmap/regmap.c | 3 +++
- include/linux/regmap.h | 2 +-
- 4 files changed, 22 insertions(+), 10 deletions(-)
-
---- a/drivers/base/regmap/Kconfig
-+++ b/drivers/base/regmap/Kconfig
-@@ -4,10 +4,9 @@
- # subsystems should select the appropriate symbols.
-
- config REGMAP
-- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO)
- select IRQ_DOMAIN if REGMAP_IRQ
- select MDIO_BUS if REGMAP_MDIO
-- bool
-+ tristate
-
- config REGCACHE_COMPRESSED
- select LZO_COMPRESS
-@@ -15,53 +14,67 @@ config REGCACHE_COMPRESSED
- bool
-
- config REGMAP_AC97
-+ select REGMAP
- tristate
-
- config REGMAP_I2C
-+ select REGMAP
- tristate
- depends on I2C
-
- config REGMAP_SLIMBUS
-+ select REGMAP
- tristate
- depends on SLIMBUS
-
- config REGMAP_SPI
-+ select REGMAP
- tristate
- depends on SPI
-
- config REGMAP_SPMI
-+ select REGMAP
- tristate
- depends on SPMI
-
- config REGMAP_W1
-+ select REGMAP
- tristate
- depends on W1
-
- config REGMAP_MDIO
-+ select REGMAP
- tristate
-
- config REGMAP_MMIO
-+ select REGMAP
- tristate
-
- config REGMAP_IRQ
-+ select REGMAP
- bool
-
- config REGMAP_SOUNDWIRE
-+ select REGMAP
- tristate
- depends on SOUNDWIRE
-
- config REGMAP_SOUNDWIRE_MBQ
-+ select REGMAP
- tristate
- depends on SOUNDWIRE
-
- config REGMAP_SCCB
-+ select REGMAP
- tristate
- depends on I2C
-
- config REGMAP_I3C
-+ select REGMAP
- tristate
- depends on I3C
-
- config REGMAP_SPI_AVMM
-+ select REGMAP
- tristate
- depends on SPI
---- a/drivers/base/regmap/Makefile
-+++ b/drivers/base/regmap/Makefile
-@@ -2,10 +2,14 @@
- # For include/trace/define_trace.h to include trace.h
- CFLAGS_regmap.o := -I$(src)
-
--obj-$(CONFIG_REGMAP) += regmap.o regcache.o
--obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o
--obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o
--obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
-+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o
-+ifdef CONFIG_DEBUG_FS
-+regmap-core-objs += regmap-debugfs.o
-+endif
-+ifdef CONFIG_REGCACHE_COMPRESSED
-+regmap-core-objs += regcache-lzo.o
-+endif
-+obj-$(CONFIG_REGMAP) += regmap-core.o
- obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
- obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
- obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
---- a/drivers/base/regmap/regmap.c
-+++ b/drivers/base/regmap/regmap.c
-@@ -9,6 +9,7 @@
- #include <linux/device.h>
- #include <linux/slab.h>
- #include <linux/export.h>
-+#include <linux/module.h>
- #include <linux/mutex.h>
- #include <linux/err.h>
- #include <linux/property.h>
-@@ -3364,3 +3365,5 @@ static int __init regmap_initcall(void)
- return 0;
- }
- postcore_initcall(regmap_initcall);
-+
-+MODULE_LICENSE("GPL");
---- a/include/linux/regmap.h
-+++ b/include/linux/regmap.h
-@@ -180,7 +180,7 @@ struct reg_sequence {
- __ret ?: __tmp; \
- })
-
--#ifdef CONFIG_REGMAP
-+#if IS_REACHABLE(CONFIG_REGMAP)
-
- enum regmap_endian {
- /* Unspecified -> 0 -> Backwards compatible default */
diff --git a/target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch b/target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch
deleted file mode 100644
index 64daa82743..0000000000
--- a/target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:12:51 +0200
-Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run
-
-Reduces kernel size after LZMA by about 5k on MIPS
-
-lede-commit: 044c316167e076479a344c59905e5b435b84a77f
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- crypto/Kconfig | 13 ++++++-------
- crypto/algboss.c | 4 ++++
- 2 files changed, 10 insertions(+), 7 deletions(-)
-
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -121,13 +121,13 @@ config CRYPTO_MANAGER
- cbc(aes).
-
- config CRYPTO_MANAGER2
-- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y)
-- select CRYPTO_AEAD2
-- select CRYPTO_HASH2
-- select CRYPTO_SKCIPHER2
-- select CRYPTO_AKCIPHER2
-- select CRYPTO_KPP2
-- select CRYPTO_ACOMP2
-+ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS)
-+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS
-
- config CRYPTO_USER
- tristate "Userspace cryptographic algorithm configuration"
---- a/crypto/algboss.c
-+++ b/crypto/algboss.c
-@@ -211,8 +211,12 @@ static int cryptomgr_schedule_test(struc
- type = alg->cra_flags;
-
- /* Do not test internal algorithms. */
-+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
-+ type |= CRYPTO_ALG_TESTED;
-+#else
- if (type & CRYPTO_ALG_INTERNAL)
- type |= CRYPTO_ALG_TESTED;
-+#endif
-
- param->type = type;
-
diff --git a/target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch b/target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch
deleted file mode 100644
index ee923c73f7..0000000000
--- a/target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 241e5d3f7b0dd3c01f8c7fa83cbc9a3882286d53 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:35:18 +0200
-Subject: [PATCH] lib/crypto: add tristate string for ARC4
-
-This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We
-need this to be able to compile this into the kernel and make use of it
-from backports.
-
----
- lib/crypto/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/lib/crypto/Kconfig
-+++ b/lib/crypto/Kconfig
-@@ -6,7 +6,7 @@ config CRYPTO_LIB_AES
- tristate
-
- config CRYPTO_LIB_ARC4
-- tristate
-+ tristate "ARC4 cipher library"
-
- config CRYPTO_ARCH_HAVE_LIB_BLAKE2S
- bool
diff --git a/target/linux/generic/hack-5.15/280-rfkill-stubs.patch b/target/linux/generic/hack-5.15/280-rfkill-stubs.patch
deleted file mode 100644
index ff6638f7a0..0000000000
--- a/target/linux/generic/hack-5.15/280-rfkill-stubs.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 7 Jul 2017 17:13:44 +0200
-Subject: rfkill: add fake rfkill support
-
-allow building of modules depending on RFKILL even if RFKILL is not enabled.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- include/linux/rfkill.h | 2 +-
- net/Makefile | 2 +-
- net/rfkill/Kconfig | 14 +++++++++-----
- net/rfkill/Makefile | 2 +-
- 4 files changed, 12 insertions(+), 8 deletions(-)
-
---- a/include/linux/rfkill.h
-+++ b/include/linux/rfkill.h
-@@ -64,7 +64,7 @@ struct rfkill_ops {
- int (*set_block)(void *data, bool blocked);
- };
-
--#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-+#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE)
- /**
- * rfkill_alloc - Allocate rfkill structure
- * @name: name of the struct -- the string is not copied internally
---- a/net/Makefile
-+++ b/net/Makefile
-@@ -51,7 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/
- obj-$(CONFIG_NETLABEL) += netlabel/
- obj-$(CONFIG_IUCV) += iucv/
- obj-$(CONFIG_SMC) += smc/
--obj-$(CONFIG_RFKILL) += rfkill/
-+obj-$(CONFIG_RFKILL_FULL) += rfkill/
- obj-$(CONFIG_NET_9P) += 9p/
- obj-$(CONFIG_CAIF) += caif/
- obj-$(CONFIG_DCB) += dcb/
---- a/net/rfkill/Kconfig
-+++ b/net/rfkill/Kconfig
-@@ -2,7 +2,11 @@
- #
- # RF switch subsystem configuration
- #
--menuconfig RFKILL
-+config RFKILL
-+ bool
-+ default y
-+
-+menuconfig RFKILL_FULL
- tristate "RF switch subsystem support"
- help
- Say Y here if you want to have control over RF switches
-@@ -14,19 +18,19 @@ menuconfig RFKILL
- # LED trigger support
- config RFKILL_LEDS
- bool
-- depends on RFKILL
-+ depends on RFKILL_FULL
- depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS
- default y
-
- config RFKILL_INPUT
- bool "RF switch input support" if EXPERT
-- depends on RFKILL
-+ depends on RFKILL_FULL
- depends on INPUT = y || RFKILL = INPUT
- default y if !EXPERT
-
- config RFKILL_GPIO
- tristate "GPIO RFKILL driver"
-- depends on RFKILL
-+ depends on RFKILL_FULL
- depends on GPIOLIB || COMPILE_TEST
- default n
- help
---- a/net/rfkill/Makefile
-+++ b/net/rfkill/Makefile
-@@ -5,5 +5,5 @@
-
- rfkill-y += core.o
- rfkill-$(CONFIG_RFKILL_INPUT) += input.o
--obj-$(CONFIG_RFKILL) += rfkill.o
-+obj-$(CONFIG_RFKILL_FULL) += rfkill.o
- obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o
diff --git a/target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch
deleted file mode 100644
index f21f200136..0000000000
--- a/target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
-Date: Fri, 7 Jun 2013 18:35:22 -0500
-Subject: MIPS: r4k_cache: use more efficient cache blast
-
-Optimize the compiler output for larger cache blast cases that are
-common for DMA-based networking.
-
-Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
---- a/arch/mips/include/asm/r4kcache.h
-+++ b/arch/mips/include/asm/r4kcache.h
-@@ -286,14 +286,46 @@ static inline void prot##extra##blast_##
- unsigned long end) \
- { \
- unsigned long lsize = cpu_##desc##_line_size(); \
-+ unsigned long lsize_2 = lsize * 2; \
-+ unsigned long lsize_3 = lsize * 3; \
-+ unsigned long lsize_4 = lsize * 4; \
-+ unsigned long lsize_5 = lsize * 5; \
-+ unsigned long lsize_6 = lsize * 6; \
-+ unsigned long lsize_7 = lsize * 7; \
-+ unsigned long lsize_8 = lsize * 8; \
- unsigned long addr = start & ~(lsize - 1); \
-- unsigned long aend = (end - 1) & ~(lsize - 1); \
-+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \
-+ int lines = (aend - addr) / lsize; \
- \
-- while (1) { \
-+ while (lines >= 8) { \
-+ prot##cache_op(hitop, addr); \
-+ prot##cache_op(hitop, addr + lsize); \
-+ prot##cache_op(hitop, addr + lsize_2); \
-+ prot##cache_op(hitop, addr + lsize_3); \
-+ prot##cache_op(hitop, addr + lsize_4); \
-+ prot##cache_op(hitop, addr + lsize_5); \
-+ prot##cache_op(hitop, addr + lsize_6); \
-+ prot##cache_op(hitop, addr + lsize_7); \
-+ addr += lsize_8; \
-+ lines -= 8; \
-+ } \
-+ \
-+ if (lines & 0x4) { \
-+ prot##cache_op(hitop, addr); \
-+ prot##cache_op(hitop, addr + lsize); \
-+ prot##cache_op(hitop, addr + lsize_2); \
-+ prot##cache_op(hitop, addr + lsize_3); \
-+ addr += lsize_4; \
-+ } \
-+ \
-+ if (lines & 0x2) { \
-+ prot##cache_op(hitop, addr); \
-+ prot##cache_op(hitop, addr + lsize); \
-+ addr += lsize_2; \
-+ } \
-+ \
-+ if (lines & 0x1) { \
- prot##cache_op(hitop, addr); \
-- if (addr == aend) \
-- break; \
-- addr += lsize; \
- } \
- }
-
diff --git a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch
deleted file mode 100644
index 1df6f2f18b..0000000000
--- a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 0bccc3722bdd88e8ae995e77ef9f7b77ee4cbdee Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 7 Apr 2021 22:45:54 +0100
-Subject: [PATCH 2/2] mtd: blktrans: call add disks after mtd device
-To: linux-mtd@lists.infradead.org
-Cc: Vignesh Raghavendra <vigneshr@ti.com>,
- Richard Weinberger <richard@nod.at>,
- Miquel Raynal <miquel.raynal@bootlin.com>,
- David Woodhouse <dwmw2@infradead.org>
-
-Calling device_add_disk while holding mtd_table_mutex leads
-to deadlock in case part_bits!=0 as block partition parsers
-will try to open the newly created disks, trying to acquire
-mutex once again.
-Move device_add_disk to additional function called after
-add partitions of an MTD device have been added and locks
-have been released.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/mtd_blkdevs.c | 33 ++++++++++++++++++++++++++-------
- drivers/mtd/mtdcore.c | 3 +++
- include/linux/mtd/blktrans.h | 1 +
- 3 files changed, 30 insertions(+), 7 deletions(-)
-
---- a/drivers/mtd/mtd_blkdevs.c
-+++ b/drivers/mtd/mtd_blkdevs.c
-@@ -384,13 +384,6 @@ int add_mtd_blktrans_dev(struct mtd_blkt
- if (new->readonly)
- set_disk_ro(gd, 1);
-
-- device_add_disk(&new->mtd->dev, gd, NULL);
--
-- if (new->disk_attributes) {
-- ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
-- new->disk_attributes);
-- WARN_ON(ret);
-- }
- return 0;
-
- out_free_tag_set:
-@@ -402,6 +395,27 @@ out_list_del:
- return ret;
- }
-
-+void register_mtd_blktrans_devs(void)
-+{
-+ struct mtd_blktrans_ops *tr;
-+ struct mtd_blktrans_dev *dev, *next;
-+ int ret;
-+
-+ list_for_each_entry(tr, &blktrans_majors, list) {
-+ list_for_each_entry_safe(dev, next, &tr->devs, list) {
-+ if (disk_live(dev->disk))
-+ continue;
-+
-+ device_add_disk(&dev->mtd->dev, dev->disk, NULL);
-+ if (dev->disk_attributes) {
-+ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj,
-+ dev->disk_attributes);
-+ WARN_ON(ret);
-+ }
-+ }
-+ }
-+}
-+
- int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
- {
- unsigned long flags;
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -32,6 +32,7 @@
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-+#include <linux/mtd/blktrans.h>
-
- #include "mtdcore.h"
-
-@@ -1106,6 +1107,8 @@ int mtd_device_parse_register(struct mtd
- register_reboot_notifier(&mtd->reboot_notifier);
- }
-
-+ register_mtd_blktrans_devs();
-+
- out:
- if (ret) {
- nvmem_unregister(mtd->otp_user_nvmem);
---- a/include/linux/mtd/blktrans.h
-+++ b/include/linux/mtd/blktrans.h
-@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc
- extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
- extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
- extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev);
-+extern void register_mtd_blktrans_devs(void);
-
- /**
- * module_mtd_blktrans() - Helper macro for registering a mtd blktrans driver
diff --git a/target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch b/target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch
deleted file mode 100644
index ed46301b0e..0000000000
--- a/target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 7 Nov 2022 23:48:24 +0100
-Subject: [PATCH] mtd: support OpenWrt's MTD_ROOTFS_ROOT_DEV
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows setting ROOT_DEV to MTD partition named "rootfs".
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -784,7 +784,8 @@ int add_mtd_device(struct mtd_info *mtd)
-
- mutex_unlock(&mtd_table_mutex);
-
-- if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) {
-+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL) ||
-+ (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && !strcmp(mtd->name, "rootfs") && ROOT_DEV == 0)) {
- if (IS_BUILTIN(CONFIG_MTD)) {
- pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name);
- ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
diff --git a/target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch b/target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch
deleted file mode 100644
index 965a331a19..0000000000
--- a/target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 6fa9e3678eb002246df1280322b6a024853950a5 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 11 Oct 2021 00:53:14 +0200
-Subject: [PATCH] drivers: mtd: parsers: add nvmem support to cmdlinepart
-
-Assuming cmdlinepart is only one level deep partition scheme and that
-static partition are also defined in DTS, we can assign an of_node for
-partition declared from bootargs. cmdlinepart have priority than
-fiexed-partition parser so in this specific case the parser doesn't
-assign an of_node. Fix this by searching a defined of_node using a
-similar fixed_partition parser and if a partition is found with the same
-label, check that it has the same offset and size and return the DT
-of_node to correctly use NVMEM cells.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
----
- drivers/mtd/parsers/cmdlinepart.c | 71 +++++++++++++++++++++++++++++++
- 1 file changed, 71 insertions(+)
-
---- a/drivers/mtd/parsers/cmdlinepart.c
-+++ b/drivers/mtd/parsers/cmdlinepart.c
-@@ -43,6 +43,7 @@
- #include <linux/mtd/partitions.h>
- #include <linux/module.h>
- #include <linux/err.h>
-+#include <linux/of.h>
-
- /* debug macro */
- #if 0
-@@ -323,6 +324,68 @@ static int mtdpart_setup_real(char *s)
- return 0;
- }
-
-+static int search_fixed_partition(struct mtd_info *master,
-+ struct mtd_partition *target_part,
-+ struct mtd_partition *fixed_part)
-+{
-+ struct device_node *mtd_node;
-+ struct device_node *ofpart_node;
-+ struct device_node *pp;
-+ struct mtd_partition part;
-+ const char *partname;
-+
-+ mtd_node = mtd_get_of_node(master);
-+ if (!mtd_node)
-+ return -EINVAL;
-+
-+ ofpart_node = of_get_child_by_name(mtd_node, "partitions");
-+
-+ for_each_child_of_node(ofpart_node, pp) {
-+ const __be32 *reg;
-+ int len;
-+ int a_cells, s_cells;
-+
-+ reg = of_get_property(pp, "reg", &len);
-+ if (!reg) {
-+ pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n",
-+ master->name, pp,
-+ mtd_node);
-+ continue;
-+ }
-+
-+ a_cells = of_n_addr_cells(pp);
-+ s_cells = of_n_size_cells(pp);
-+ if (len / 4 != a_cells + s_cells) {
-+ pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n",
-+ master->name, pp,
-+ mtd_node);
-+ continue;
-+ }
-+
-+ part.offset = of_read_number(reg, a_cells);
-+ part.size = of_read_number(reg + a_cells, s_cells);
-+ part.of_node = pp;
-+
-+ partname = of_get_property(pp, "label", &len);
-+ if (!partname)
-+ partname = of_get_property(pp, "name", &len);
-+ part.name = partname;
-+
-+ if (!strncmp(target_part->name, part.name, len)) {
-+ if (part.offset != target_part->offset)
-+ return -EINVAL;
-+
-+ if (part.size != target_part->size)
-+ return -EINVAL;
-+
-+ memcpy(fixed_part, &part, sizeof(struct mtd_partition));
-+ return 0;
-+ }
-+ }
-+
-+ return -EINVAL;
-+}
-+
- /*
- * Main function to be called from the MTD mapping driver/device to
- * obtain the partitioning information. At this point the command line
-@@ -338,6 +401,7 @@ static int parse_cmdline_partitions(stru
- int i, err;
- struct cmdline_mtd_partition *part;
- const char *mtd_id = master->name;
-+ struct mtd_partition fixed_part;
-
- /* parse command line */
- if (!cmdline_parsed) {
-@@ -382,6 +446,13 @@ static int parse_cmdline_partitions(stru
- sizeof(*part->parts) * (part->num_parts - i));
- i--;
- }
-+
-+ err = search_fixed_partition(master, &part->parts[i], &fixed_part);
-+ if (!err) {
-+ part->parts[i].of_node = fixed_part.of_node;
-+ pr_info("Found partition defined in DT for %s. Assigning OF node to support nvmem.",
-+ part->parts[i].name);
-+ }
- }
-
- *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
diff --git a/target/linux/generic/hack-5.15/430-mtk-bmt-support.patch b/target/linux/generic/hack-5.15/430-mtk-bmt-support.patch
deleted file mode 100644
index 2a83f46e0e..0000000000
--- a/target/linux/generic/hack-5.15/430-mtk-bmt-support.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From ac84397efb3b3868c71c10ad7521161773228a17 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:41:44 +0200
-Subject: [PATCH] mtd/nand: add MediaTek NAND bad block managment table
-
----
- drivers/mtd/nand/Kconfig | 4 ++++
- drivers/mtd/nand/Makefile | 1 +
- 2 files changed, 5 insertions(+)
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -46,6 +46,10 @@ config MTD_NAND_ECC_SW_BCH
- ECC codes. They are used with NAND devices requiring more than 1 bit
- of error correction.
-
-+config MTD_NAND_MTK_BMT
-+ bool "Support MediaTek NAND Bad-block Management Table"
-+ default n
-+
- endmenu
-
- endmenu
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -2,6 +2,7 @@
-
- nandcore-objs := core.o bbt.o
- obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
-+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o
-
- obj-y += onenand/
- obj-y += raw/
diff --git a/target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch
deleted file mode 100644
index c368c4ae3b..0000000000
--- a/target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch
+++ /dev/null
@@ -1,214 +0,0 @@
-From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001
-From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
-Date: Sat, 23 Mar 2019 09:29:49 +0000
-Subject: [PATCH] netfilter: connmark: introduce set-dscpmark
-
-set-dscpmark is a method of storing the DSCP of an ip packet into
-conntrack mark. In combination with a suitable tc filter action
-(act_ctinfo) DSCP values are able to be stored in the mark on egress and
-restored on ingress across links that otherwise alter or bleach DSCP.
-
-This is useful for qdiscs such as CAKE which are able to shape according
-to policies based on DSCP.
-
-Ingress classification is traditionally a challenging task since
-iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT
-lookups, hence are unable to see internal IPv4 addresses as used on the
-typical home masquerading gateway.
-
-x_tables CONNMARK set-dscpmark target solves the problem of storing the
-DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc
-action to restore.
-
-The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a
-32bit 'statemask'. The dscp mask must be 6 contiguous bits and
-represents the area where the DSCP will be stored in the connmark. The
-state mask is a minimum 1 bit length mask that must not overlap with the
-dscpmask. It represents a flag which is set when the DSCP has been
-stored in the conntrack mark. This is useful to implement a 'one shot'
-iptables based classification where the 'complicated' iptables rules are
-only run once to classify the connection on initial (egress) packet and
-subsequent packets are all marked/restored with the same DSCP. A state
-mask of zero disables the setting of a status bit/s.
-
-example syntax with a suitably modified iptables user space application:
-
-iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000
-
-Would store the DSCP in the top 6 bits of the 32bit mark field, and use
-the LSB of the top byte as the 'DSCP has been stored' marker.
-
-|----0xFC----conntrack mark----000000---|
-| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
-| DSCP | unused | flag |unused |
-|-----------------------0x01---000000---|
- ^ ^
- | |
- ---| Conditional flag
- | set this when dscp
-|-ip diffserv-| stored in mark
-| 6 bits |
-|-------------|
-
-an identically configured tc action to restore looks like:
-
-tc filter show dev eth0 ingress
-filter parent ffff: protocol all pref 10 u32 chain 0
-filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1
-filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw
- match 00000000/00000000 at 0
- action order 1: ctinfo zone 0 pipe
- index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000
-
- action order 2: mirred (Egress Redirect to device ifb4eth0) stolen
- index 1 ref 1 bind 1
-
-|----0xFC----conntrack mark----000000---|
-| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
-| DSCP | unused | flag |unused |
-|-----------------------0x01---000000---|
- | |
- | |
- ---| Conditional flag
- v only restore if set
-|-ip diffserv-|
-| 6 bits |
-|-------------|
-
-Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
----
- include/uapi/linux/netfilter/xt_connmark.h | 10 ++++
- net/netfilter/xt_connmark.c | 55 ++++++++++++++++++----
- 2 files changed, 57 insertions(+), 8 deletions(-)
-
---- a/include/uapi/linux/netfilter/xt_connmark.h
-+++ b/include/uapi/linux/netfilter/xt_connmark.h
-@@ -20,6 +20,11 @@ enum {
- };
-
- enum {
-+ XT_CONNMARK_VALUE = (1 << 0),
-+ XT_CONNMARK_DSCP = (1 << 1)
-+};
-+
-+enum {
- D_SHIFT_LEFT = 0,
- D_SHIFT_RIGHT,
- };
-@@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 {
- __u8 shift_dir, shift_bits, mode;
- };
-
-+struct xt_connmark_tginfo3 {
-+ __u32 ctmark, ctmask, nfmask;
-+ __u8 shift_dir, shift_bits, mode, func;
-+};
-+
- struct xt_connmark_mtinfo1 {
- __u32 mark, mask;
- __u8 invert;
---- a/net/netfilter/xt_connmark.c
-+++ b/net/netfilter/xt_connmark.c
-@@ -24,13 +24,13 @@ MODULE_ALIAS("ipt_connmark");
- MODULE_ALIAS("ip6t_connmark");
-
- static unsigned int
--connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
-+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info)
- {
- enum ip_conntrack_info ctinfo;
- u_int32_t new_targetmark;
- struct nf_conn *ct;
- u_int32_t newmark;
-- u_int32_t oldmark;
-+ u_int8_t dscp;
-
- ct = nf_ct_get(skb, &ctinfo);
- if (ct == NULL)
-@@ -38,13 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c
-
- switch (info->mode) {
- case XT_CONNMARK_SET:
-- oldmark = READ_ONCE(ct->mark);
-- newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
-- if (info->shift_dir == D_SHIFT_RIGHT)
-- newmark >>= info->shift_bits;
-- else
-- newmark <<= info->shift_bits;
-+ newmark = READ_ONCE(ct->mark);
-+ if (info->func & XT_CONNMARK_VALUE) {
-+ newmark = (newmark & ~info->ctmask) ^ info->ctmark;
-+ if (info->shift_dir == D_SHIFT_RIGHT)
-+ newmark >>= info->shift_bits;
-+ else
-+ newmark <<= info->shift_bits;
-+ } else if (info->func & XT_CONNMARK_DSCP) {
-+ if (skb->protocol == htons(ETH_P_IP))
-+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
-+ else if (skb->protocol == htons(ETH_P_IPV6))
-+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
-+ else /* protocol doesn't have diffserv */
-+ break;
-
-+ newmark = (newmark & ~info->ctmark) |
-+ (info->ctmask | (dscp << info->shift_bits));
-+ }
- if (READ_ONCE(ct->mark) != newmark) {
- WRITE_ONCE(ct->mark, newmark);
- nf_conntrack_event_cache(IPCT_MARK, ct);
-@@ -83,20 +94,36 @@ static unsigned int
- connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct xt_connmark_tginfo1 *info = par->targinfo;
-- const struct xt_connmark_tginfo2 info2 = {
-+ const struct xt_connmark_tginfo3 info3 = {
- .ctmark = info->ctmark,
- .ctmask = info->ctmask,
- .nfmask = info->nfmask,
- .mode = info->mode,
-+ .func = XT_CONNMARK_VALUE
- };
-
-- return connmark_tg_shift(skb, &info2);
-+ return connmark_tg_shift(skb, &info3);
- }
-
- static unsigned int
- connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct xt_connmark_tginfo2 *info = par->targinfo;
-+ const struct xt_connmark_tginfo3 info3 = {
-+ .ctmark = info->ctmark,
-+ .ctmask = info->ctmask,
-+ .nfmask = info->nfmask,
-+ .mode = info->mode,
-+ .func = XT_CONNMARK_VALUE
-+ };
-+
-+ return connmark_tg_shift(skb, &info3);
-+}
-+
-+static unsigned int
-+connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
-+{
-+ const struct xt_connmark_tginfo3 *info = par->targinfo;
-
- return connmark_tg_shift(skb, info);
- }
-@@ -167,6 +194,16 @@ static struct xt_target connmark_tg_reg[
- .targetsize = sizeof(struct xt_connmark_tginfo2),
- .destroy = connmark_tg_destroy,
- .me = THIS_MODULE,
-+ },
-+ {
-+ .name = "CONNMARK",
-+ .revision = 3,
-+ .family = NFPROTO_UNSPEC,
-+ .checkentry = connmark_tg_check,
-+ .target = connmark_tg_v3,
-+ .targetsize = sizeof(struct xt_connmark_tginfo3),
-+ .destroy = connmark_tg_destroy,
-+ .me = THIS_MODULE,
- }
- };
-
diff --git a/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
deleted file mode 100644
index d22b9f909b..0000000000
--- a/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
+++ /dev/null
@@ -1,865 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 20 Feb 2018 15:56:02 +0100
-Subject: [PATCH] netfilter: add xt_FLOWOFFLOAD target
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- create mode 100644 net/netfilter/xt_OFFLOAD.c
-
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -56,8 +56,6 @@ config NF_TABLES_ARP
- help
- This option enables the ARP support for nf_tables.
-
--endif # NF_TABLES
--
- config NF_FLOW_TABLE_IPV4
- tristate "Netfilter flow table IPv4 module"
- depends on NF_FLOW_TABLE
-@@ -66,6 +64,8 @@ config NF_FLOW_TABLE_IPV4
-
- To compile it as a module, choose M here.
-
-+endif # NF_TABLES
-+
- config NF_DUP_IPV4
- tristate "Netfilter IPv4 packet duplication to alternate destination"
- depends on !NF_CONNTRACK || NF_CONNTRACK
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -45,7 +45,6 @@ config NFT_FIB_IPV6
- multicast or blackhole.
-
- endif # NF_TABLES_IPV6
--endif # NF_TABLES
-
- config NF_FLOW_TABLE_IPV6
- tristate "Netfilter flow table IPv6 module"
-@@ -55,6 +54,8 @@ config NF_FLOW_TABLE_IPV6
-
- To compile it as a module, choose M here.
-
-+endif # NF_TABLES
-+
- config NF_DUP_IPV6
- tristate "Netfilter IPv6 packet duplication to alternate destination"
- depends on !NF_CONNTRACK || NF_CONNTRACK
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -707,8 +707,6 @@ config NFT_REJECT_NETDEV
-
- endif # NF_TABLES_NETDEV
-
--endif # NF_TABLES
--
- config NF_FLOW_TABLE_INET
- tristate "Netfilter flow table mixed IPv4/IPv6 module"
- depends on NF_FLOW_TABLE
-@@ -717,11 +715,12 @@ config NF_FLOW_TABLE_INET
-
- To compile it as a module, choose M here.
-
-+endif # NF_TABLES
-+
- config NF_FLOW_TABLE
- tristate "Netfilter flow table module"
- depends on NETFILTER_INGRESS
- depends on NF_CONNTRACK
-- depends on NF_TABLES
- help
- This option adds the flow table core infrastructure.
-
-@@ -1019,6 +1018,15 @@ config NETFILTER_XT_TARGET_NOTRACK
- depends on NETFILTER_ADVANCED
- select NETFILTER_XT_TARGET_CT
-
-+config NETFILTER_XT_TARGET_FLOWOFFLOAD
-+ tristate '"FLOWOFFLOAD" target support'
-+ depends on NF_FLOW_TABLE
-+ depends on NETFILTER_INGRESS
-+ help
-+ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload
-+ module to speed up processing of packets by bypassing the usual
-+ netfilter chains
-+
- config NETFILTER_XT_TARGET_RATEEST
- tristate '"RATEEST" target support'
- depends on NETFILTER_ADVANCED
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -144,6 +144,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
- obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
---- /dev/null
-+++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -0,0 +1,702 @@
-+/*
-+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
-+#include <linux/if_vlan.h>
-+#include <net/ip.h>
-+#include <net/netfilter/nf_conntrack.h>
-+#include <net/netfilter/nf_conntrack_extend.h>
-+#include <net/netfilter/nf_conntrack_helper.h>
-+#include <net/netfilter/nf_flow_table.h>
-+
-+struct xt_flowoffload_hook {
-+ struct hlist_node list;
-+ struct nf_hook_ops ops;
-+ struct net *net;
-+ bool registered;
-+ bool used;
-+};
-+
-+struct xt_flowoffload_table {
-+ struct nf_flowtable ft;
-+ struct hlist_head hooks;
-+ struct delayed_work work;
-+};
-+
-+struct nf_forward_info {
-+ const struct net_device *indev;
-+ const struct net_device *outdev;
-+ const struct net_device *hw_outdev;
-+ struct id {
-+ __u16 id;
-+ __be16 proto;
-+ } encap[NF_FLOW_TABLE_ENCAP_MAX];
-+ u8 num_encaps;
-+ u8 ingress_vlans;
-+ u8 h_source[ETH_ALEN];
-+ u8 h_dest[ETH_ALEN];
-+ enum flow_offload_xmit_type xmit_type;
-+};
-+
-+static DEFINE_SPINLOCK(hooks_lock);
-+
-+struct xt_flowoffload_table flowtable[2];
-+
-+static unsigned int
-+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
-+ const struct nf_hook_state *state)
-+{
-+ struct vlan_ethhdr *veth;
-+ __be16 proto;
-+
-+ switch (skb->protocol) {
-+ case htons(ETH_P_8021Q):
-+ veth = (struct vlan_ethhdr *)skb_mac_header(skb);
-+ proto = veth->h_vlan_encapsulated_proto;
-+ break;
-+ case htons(ETH_P_PPP_SES):
-+ if (!nf_flow_pppoe_proto(skb, &proto))
-+ return NF_ACCEPT;
-+ break;
-+ default:
-+ proto = skb->protocol;
-+ break;
-+ }
-+
-+ switch (proto) {
-+ case htons(ETH_P_IP):
-+ return nf_flow_offload_ip_hook(priv, skb, state);
-+ case htons(ETH_P_IPV6):
-+ return nf_flow_offload_ipv6_hook(priv, skb, state);
-+ }
-+
-+ return NF_ACCEPT;
-+}
-+
-+static int
-+xt_flowoffload_create_hook(struct xt_flowoffload_table *table,
-+ struct net_device *dev)
-+{
-+ struct xt_flowoffload_hook *hook;
-+ struct nf_hook_ops *ops;
-+
-+ hook = kzalloc(sizeof(*hook), GFP_ATOMIC);
-+ if (!hook)
-+ return -ENOMEM;
-+
-+ ops = &hook->ops;
-+ ops->pf = NFPROTO_NETDEV;
-+ ops->hooknum = NF_NETDEV_INGRESS;
-+ ops->priority = 10;
-+ ops->priv = &table->ft;
-+ ops->hook = xt_flowoffload_net_hook;
-+ ops->dev = dev;
-+
-+ hlist_add_head(&hook->list, &table->hooks);
-+ mod_delayed_work(system_power_efficient_wq, &table->work, 0);
-+
-+ return 0;
-+}
-+
-+static struct xt_flowoffload_hook *
-+flow_offload_lookup_hook(struct xt_flowoffload_table *table,
-+ struct net_device *dev)
-+{
-+ struct xt_flowoffload_hook *hook;
-+
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->ops.dev == dev)
-+ return hook;
-+ }
-+
-+ return NULL;
-+}
-+
-+static void
-+xt_flowoffload_check_device(struct xt_flowoffload_table *table,
-+ struct net_device *dev)
-+{
-+ struct xt_flowoffload_hook *hook;
-+
-+ if (!dev)
-+ return;
-+
-+ spin_lock_bh(&hooks_lock);
-+ hook = flow_offload_lookup_hook(table, dev);
-+ if (hook)
-+ hook->used = true;
-+ else
-+ xt_flowoffload_create_hook(table, dev);
-+ spin_unlock_bh(&hooks_lock);
-+}
-+
-+static void
-+xt_flowoffload_register_hooks(struct xt_flowoffload_table *table)
-+{
-+ struct xt_flowoffload_hook *hook;
-+
-+restart:
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->registered)
-+ continue;
-+
-+ hook->registered = true;
-+ hook->net = dev_net(hook->ops.dev);
-+ spin_unlock_bh(&hooks_lock);
-+ nf_register_net_hook(hook->net, &hook->ops);
-+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
-+ table->ft.type->setup(&table->ft, hook->ops.dev,
-+ FLOW_BLOCK_BIND);
-+ spin_lock_bh(&hooks_lock);
-+ goto restart;
-+ }
-+
-+}
-+
-+static bool
-+xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table)
-+{
-+ struct xt_flowoffload_hook *hook;
-+ bool active = false;
-+
-+restart:
-+ spin_lock_bh(&hooks_lock);
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->used || !hook->registered) {
-+ active = true;
-+ continue;
-+ }
-+
-+ hlist_del(&hook->list);
-+ spin_unlock_bh(&hooks_lock);
-+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
-+ table->ft.type->setup(&table->ft, hook->ops.dev,
-+ FLOW_BLOCK_UNBIND);
-+ nf_unregister_net_hook(hook->net, &hook->ops);
-+ kfree(hook);
-+ goto restart;
-+ }
-+ spin_unlock_bh(&hooks_lock);
-+
-+ return active;
-+}
-+
-+static void
-+xt_flowoffload_check_hook(struct nf_flowtable *flowtable,
-+ struct flow_offload *flow, void *data)
-+{
-+ struct xt_flowoffload_table *table;
-+ struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple;
-+ struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple;
-+ struct xt_flowoffload_hook *hook;
-+
-+ table = container_of(flowtable, struct xt_flowoffload_table, ft);
-+
-+ spin_lock_bh(&hooks_lock);
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->ops.dev->ifindex != tuple0->iifidx &&
-+ hook->ops.dev->ifindex != tuple1->iifidx)
-+ continue;
-+
-+ hook->used = true;
-+ }
-+ spin_unlock_bh(&hooks_lock);
-+}
-+
-+static void
-+xt_flowoffload_hook_work(struct work_struct *work)
-+{
-+ struct xt_flowoffload_table *table;
-+ struct xt_flowoffload_hook *hook;
-+ int err;
-+
-+ table = container_of(work, struct xt_flowoffload_table, work.work);
-+
-+ spin_lock_bh(&hooks_lock);
-+ xt_flowoffload_register_hooks(table);
-+ hlist_for_each_entry(hook, &table->hooks, list)
-+ hook->used = false;
-+ spin_unlock_bh(&hooks_lock);
-+
-+ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook,
-+ NULL);
-+ if (err && err != -EAGAIN)
-+ goto out;
-+
-+ if (!xt_flowoffload_cleanup_hooks(table))
-+ return;
-+
-+out:
-+ queue_delayed_work(system_power_efficient_wq, &table->work, HZ);
-+}
-+
-+static bool
-+xt_flowoffload_skip(struct sk_buff *skb, int family)
-+{
-+ if (skb_sec_path(skb))
-+ return true;
-+
-+ if (family == NFPROTO_IPV4) {
-+ const struct ip_options *opt = &(IPCB(skb)->opt);
-+
-+ if (unlikely(opt->optlen))
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static enum flow_offload_xmit_type nf_xmit_type(struct dst_entry *dst)
-+{
-+ if (dst_xfrm(dst))
-+ return FLOW_OFFLOAD_XMIT_XFRM;
-+
-+ return FLOW_OFFLOAD_XMIT_NEIGH;
-+}
-+
-+static void nf_default_forward_path(struct nf_flow_route *route,
-+ struct dst_entry *dst_cache,
-+ enum ip_conntrack_dir dir,
-+ struct net_device **dev)
-+{
-+ dev[!dir] = dst_cache->dev;
-+ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex;
-+ route->tuple[dir].dst = dst_cache;
-+ route->tuple[dir].xmit_type = nf_xmit_type(dst_cache);
-+}
-+
-+static bool nf_is_valid_ether_device(const struct net_device *dev)
-+{
-+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
-+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
-+ return false;
-+
-+ return true;
-+}
-+
-+static void nf_dev_path_info(const struct net_device_path_stack *stack,
-+ struct nf_forward_info *info,
-+ unsigned char *ha)
-+{
-+ const struct net_device_path *path;
-+ int i;
-+
-+ memcpy(info->h_dest, ha, ETH_ALEN);
-+
-+ for (i = 0; i < stack->num_paths; i++) {
-+ path = &stack->path[i];
-+ switch (path->type) {
-+ case DEV_PATH_ETHERNET:
-+ case DEV_PATH_DSA:
-+ case DEV_PATH_VLAN:
-+ case DEV_PATH_PPPOE:
-+ info->indev = path->dev;
-+ if (is_zero_ether_addr(info->h_source))
-+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
-+
-+ if (path->type == DEV_PATH_ETHERNET)
-+ break;
-+ if (path->type == DEV_PATH_DSA) {
-+ i = stack->num_paths;
-+ break;
-+ }
-+
-+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */
-+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
-+ info->indev = NULL;
-+ break;
-+ }
-+ if (!info->outdev)
-+ info->outdev = path->dev;
-+ info->encap[info->num_encaps].id = path->encap.id;
-+ info->encap[info->num_encaps].proto = path->encap.proto;
-+ info->num_encaps++;
-+ if (path->type == DEV_PATH_PPPOE)
-+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
-+ break;
-+ case DEV_PATH_BRIDGE:
-+ if (is_zero_ether_addr(info->h_source))
-+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
-+
-+ switch (path->bridge.vlan_mode) {
-+ case DEV_PATH_BR_VLAN_UNTAG_HW:
-+ info->ingress_vlans |= BIT(info->num_encaps - 1);
-+ break;
-+ case DEV_PATH_BR_VLAN_TAG:
-+ info->encap[info->num_encaps].id = path->bridge.vlan_id;
-+ info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
-+ info->num_encaps++;
-+ break;
-+ case DEV_PATH_BR_VLAN_UNTAG:
-+ info->num_encaps--;
-+ break;
-+ case DEV_PATH_BR_VLAN_KEEP:
-+ break;
-+ }
-+ break;
-+ default:
-+ info->indev = NULL;
-+ break;
-+ }
-+ }
-+ if (!info->outdev)
-+ info->outdev = info->indev;
-+
-+ info->hw_outdev = info->indev;
-+
-+ if (nf_is_valid_ether_device(info->indev))
-+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
-+}
-+
-+static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
-+ const struct dst_entry *dst_cache,
-+ const struct nf_conn *ct,
-+ enum ip_conntrack_dir dir, u8 *ha,
-+ struct net_device_path_stack *stack)
-+{
-+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
-+ struct net_device *dev = dst_cache->dev;
-+ struct neighbour *n;
-+ u8 nud_state;
-+
-+ if (!nf_is_valid_ether_device(dev))
-+ goto out;
-+
-+ n = dst_neigh_lookup(dst_cache, daddr);
-+ if (!n)
-+ return -1;
-+
-+ read_lock_bh(&n->lock);
-+ nud_state = n->nud_state;
-+ ether_addr_copy(ha, n->ha);
-+ read_unlock_bh(&n->lock);
-+ neigh_release(n);
-+
-+ if (!(nud_state & NUD_VALID))
-+ return -1;
-+
-+out:
-+ return dev_fill_forward_path(dev, ha, stack);
-+}
-+
-+static void nf_dev_forward_path(struct nf_flow_route *route,
-+ const struct nf_conn *ct,
-+ enum ip_conntrack_dir dir,
-+ struct net_device **devs)
-+{
-+ const struct dst_entry *dst = route->tuple[dir].dst;
-+ struct net_device_path_stack stack;
-+ struct nf_forward_info info = {};
-+ unsigned char ha[ETH_ALEN];
-+ int i;
-+
-+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
-+ nf_dev_path_info(&stack, &info, ha);
-+
-+ devs[!dir] = (struct net_device *)info.indev;
-+ if (!info.indev)
-+ return;
-+
-+ route->tuple[!dir].in.ifindex = info.indev->ifindex;
-+ for (i = 0; i < info.num_encaps; i++) {
-+ route->tuple[!dir].in.encap[i].id = info.encap[i].id;
-+ route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
-+ }
-+ route->tuple[!dir].in.num_encaps = info.num_encaps;
-+ route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
-+
-+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
-+ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
-+ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
-+ route->tuple[dir].out.ifindex = info.outdev->ifindex;
-+ route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
-+ route->tuple[dir].xmit_type = info.xmit_type;
-+ }
-+}
-+
-+static int
-+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
-+ const struct xt_action_param *par,
-+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
-+ struct net_device **devs)
-+{
-+ struct dst_entry *this_dst = skb_dst(skb);
-+ struct dst_entry *other_dst = NULL;
-+ struct flowi fl;
-+
-+ memset(&fl, 0, sizeof(fl));
-+ switch (xt_family(par)) {
-+ case NFPROTO_IPV4:
-+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
-+ fl.u.ip4.flowi4_oif = xt_in(par)->ifindex;
-+ break;
-+ case NFPROTO_IPV6:
-+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
-+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
-+ fl.u.ip6.flowi6_oif = xt_in(par)->ifindex;
-+ break;
-+ }
-+
-+ if (!dst_hold_safe(this_dst))
-+ return -ENOENT;
-+
-+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
-+ if (!other_dst) {
-+ dst_release(this_dst);
-+ return -ENOENT;
-+ }
-+
-+ nf_default_forward_path(route, this_dst, dir, devs);
-+ nf_default_forward_path(route, other_dst, !dir, devs);
-+
-+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
-+ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
-+ nf_dev_forward_path(route, ct, dir, devs);
-+ nf_dev_forward_path(route, ct, !dir, devs);
-+ }
-+
-+ return 0;
-+}
-+
-+static unsigned int
-+flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
-+{
-+ struct xt_flowoffload_table *table;
-+ const struct xt_flowoffload_target_info *info = par->targinfo;
-+ struct tcphdr _tcph, *tcph = NULL;
-+ enum ip_conntrack_info ctinfo;
-+ enum ip_conntrack_dir dir;
-+ struct nf_flow_route route = {};
-+ struct flow_offload *flow = NULL;
-+ struct net_device *devs[2] = {};
-+ struct nf_conn *ct;
-+ struct net *net;
-+
-+ if (xt_flowoffload_skip(skb, xt_family(par)))
-+ return XT_CONTINUE;
-+
-+ ct = nf_ct_get(skb, &ctinfo);
-+ if (ct == NULL)
-+ return XT_CONTINUE;
-+
-+ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) {
-+ case IPPROTO_TCP:
-+ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED)
-+ return XT_CONTINUE;
-+
-+ tcph = skb_header_pointer(skb, par->thoff,
-+ sizeof(_tcph), &_tcph);
-+ if (unlikely(!tcph || tcph->fin || tcph->rst))
-+ return XT_CONTINUE;
-+ break;
-+ case IPPROTO_UDP:
-+ break;
-+ default:
-+ return XT_CONTINUE;
-+ }
-+
-+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
-+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH))
-+ return XT_CONTINUE;
-+
-+ if (!nf_ct_is_confirmed(ct))
-+ return XT_CONTINUE;
-+
-+ dir = CTINFO2DIR(ctinfo);
-+
-+ devs[dir] = xt_out(par);
-+ devs[!dir] = xt_in(par);
-+
-+ if (!devs[dir] || !devs[!dir])
-+ return XT_CONTINUE;
-+
-+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
-+ return XT_CONTINUE;
-+
-+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0)
-+ goto err_flow_route;
-+
-+ flow = flow_offload_alloc(ct);
-+ if (!flow)
-+ goto err_flow_alloc;
-+
-+ flow_offload_route_init(flow, &route);
-+
-+ if (tcph) {
-+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
-+ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
-+ }
-+
-+ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)];
-+
-+ net = read_pnet(&table->ft.net);
-+ if (!net)
-+ write_pnet(&table->ft.net, xt_net(par));
-+
-+ if (flow_offload_add(&table->ft, flow) < 0)
-+ goto err_flow_add;
-+
-+ xt_flowoffload_check_device(table, devs[0]);
-+ xt_flowoffload_check_device(table, devs[1]);
-+
-+ return XT_CONTINUE;
-+
-+err_flow_add:
-+ flow_offload_free(flow);
-+err_flow_alloc:
-+ dst_release(route.tuple[dir].dst);
-+ dst_release(route.tuple[!dir].dst);
-+err_flow_route:
-+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
-+
-+ return XT_CONTINUE;
-+}
-+
-+static int flowoffload_chk(const struct xt_tgchk_param *par)
-+{
-+ struct xt_flowoffload_target_info *info = par->targinfo;
-+
-+ if (info->flags & ~XT_FLOWOFFLOAD_MASK)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static struct xt_target offload_tg_reg __read_mostly = {
-+ .family = NFPROTO_UNSPEC,
-+ .name = "FLOWOFFLOAD",
-+ .revision = 0,
-+ .targetsize = sizeof(struct xt_flowoffload_target_info),
-+ .usersize = sizeof(struct xt_flowoffload_target_info),
-+ .checkentry = flowoffload_chk,
-+ .target = flowoffload_tg,
-+ .me = THIS_MODULE,
-+};
-+
-+static int flow_offload_netdev_event(struct notifier_block *this,
-+ unsigned long event, void *ptr)
-+{
-+ struct xt_flowoffload_hook *hook0, *hook1;
-+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-+
-+ if (event != NETDEV_UNREGISTER)
-+ return NOTIFY_DONE;
-+
-+ spin_lock_bh(&hooks_lock);
-+ hook0 = flow_offload_lookup_hook(&flowtable[0], dev);
-+ if (hook0)
-+ hlist_del(&hook0->list);
-+
-+ hook1 = flow_offload_lookup_hook(&flowtable[1], dev);
-+ if (hook1)
-+ hlist_del(&hook1->list);
-+ spin_unlock_bh(&hooks_lock);
-+
-+ if (hook0) {
-+ nf_unregister_net_hook(hook0->net, &hook0->ops);
-+ kfree(hook0);
-+ }
-+
-+ if (hook1) {
-+ nf_unregister_net_hook(hook1->net, &hook1->ops);
-+ kfree(hook1);
-+ }
-+
-+ nf_flow_table_cleanup(dev);
-+
-+ return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block flow_offload_netdev_notifier = {
-+ .notifier_call = flow_offload_netdev_event,
-+};
-+
-+static int nf_flow_rule_route_inet(struct net *net,
-+ const struct flow_offload *flow,
-+ enum flow_offload_tuple_dir dir,
-+ struct nf_flow_rule *flow_rule)
-+{
-+ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
-+ int err;
-+
-+ switch (flow_tuple->l3proto) {
-+ case NFPROTO_IPV4:
-+ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule);
-+ break;
-+ case NFPROTO_IPV6:
-+ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule);
-+ break;
-+ default:
-+ err = -1;
-+ break;
-+ }
-+
-+ return err;
-+}
-+
-+static struct nf_flowtable_type flowtable_inet = {
-+ .family = NFPROTO_INET,
-+ .init = nf_flow_table_init,
-+ .setup = nf_flow_table_offload_setup,
-+ .action = nf_flow_rule_route_inet,
-+ .free = nf_flow_table_free,
-+ .hook = xt_flowoffload_net_hook,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int init_flowtable(struct xt_flowoffload_table *tbl)
-+{
-+ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work);
-+ tbl->ft.type = &flowtable_inet;
-+ tbl->ft.flags = NF_FLOWTABLE_COUNTER;
-+
-+ return nf_flow_table_init(&tbl->ft);
-+}
-+
-+static int __init xt_flowoffload_tg_init(void)
-+{
-+ int ret;
-+
-+ register_netdevice_notifier(&flow_offload_netdev_notifier);
-+
-+ ret = init_flowtable(&flowtable[0]);
-+ if (ret)
-+ return ret;
-+
-+ ret = init_flowtable(&flowtable[1]);
-+ if (ret)
-+ goto cleanup;
-+
-+ flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD;
-+
-+ ret = xt_register_target(&offload_tg_reg);
-+ if (ret)
-+ goto cleanup2;
-+
-+ return 0;
-+
-+cleanup2:
-+ nf_flow_table_free(&flowtable[1].ft);
-+cleanup:
-+ nf_flow_table_free(&flowtable[0].ft);
-+ return ret;
-+}
-+
-+static void __exit xt_flowoffload_tg_exit(void)
-+{
-+ xt_unregister_target(&offload_tg_reg);
-+ unregister_netdevice_notifier(&flow_offload_netdev_notifier);
-+ nf_flow_table_free(&flowtable[0].ft);
-+ nf_flow_table_free(&flowtable[1].ft);
-+}
-+
-+MODULE_LICENSE("GPL");
-+module_init(xt_flowoffload_tg_init);
-+module_exit(xt_flowoffload_tg_exit);
---- a/net/netfilter/nf_flow_table_core.c
-+++ b/net/netfilter/nf_flow_table_core.c
-@@ -7,7 +7,6 @@
- #include <linux/netdevice.h>
- #include <net/ip.h>
- #include <net/ip6_route.h>
--#include <net/netfilter/nf_tables.h>
- #include <net/netfilter/nf_flow_table.h>
- #include <net/netfilter/nf_conntrack.h>
- #include <net/netfilter/nf_conntrack_core.h>
-@@ -373,8 +372,7 @@ flow_offload_lookup(struct nf_flowtable
- }
- EXPORT_SYMBOL_GPL(flow_offload_lookup);
-
--static int
--nf_flow_table_iterate(struct nf_flowtable *flow_table,
-+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
- void (*iter)(struct nf_flowtable *flowtable,
- struct flow_offload *flow, void *data),
- void *data)
-@@ -428,6 +426,7 @@ static void nf_flow_offload_gc_step(stru
- nf_flow_offload_stats(flow_table, flow);
- }
- }
-+EXPORT_SYMBOL_GPL(nf_flow_table_iterate);
-
- void nf_flow_table_gc_run(struct nf_flowtable *flow_table)
- {
---- /dev/null
-+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-+#ifndef _XT_FLOWOFFLOAD_H
-+#define _XT_FLOWOFFLOAD_H
-+
-+#include <linux/types.h>
-+
-+enum {
-+ XT_FLOWOFFLOAD_HW = 1 << 0,
-+
-+ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW
-+};
-+
-+struct xt_flowoffload_target_info {
-+ __u32 flags;
-+};
-+
-+#endif /* _XT_FLOWOFFLOAD_H */
---- a/include/net/netfilter/nf_flow_table.h
-+++ b/include/net/netfilter/nf_flow_table.h
-@@ -276,6 +276,11 @@ void nf_flow_table_free(struct nf_flowta
-
- void flow_offload_teardown(struct flow_offload *flow);
-
-+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
-+ void (*iter)(struct nf_flowtable *flowtable,
-+ struct flow_offload *flow, void *data),
-+ void *data);
-+
- void nf_flow_snat_port(const struct flow_offload *flow,
- struct sk_buff *skb, unsigned int thoff,
- u8 protocol, enum flow_offload_tuple_dir dir);
diff --git a/target/linux/generic/hack-5.15/651-wireless_mesh_header.patch b/target/linux/generic/hack-5.15/651-wireless_mesh_header.patch
deleted file mode 100644
index 12a031ec84..0000000000
--- a/target/linux/generic/hack-5.15/651-wireless_mesh_header.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001
-From: Imre Kaloz <kaloz@openwrt.org>
-Date: Fri, 7 Jul 2017 17:21:05 +0200
-Subject: mac80211: increase wireless mesh header size
-
-lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- include/linux/netdevice.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -145,8 +145,8 @@ static inline bool dev_xmit_complete(int
-
- #if defined(CONFIG_HYPERV_NET)
- # define LL_MAX_HEADER 128
--#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
--# if defined(CONFIG_MAC80211_MESH)
-+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1
-+# if defined(CONFIG_MAC80211_MESH) || 1
- # define LL_MAX_HEADER 128
- # else
- # define LL_MAX_HEADER 96
diff --git a/target/linux/generic/hack-5.15/660-fq_codel_defaults.patch b/target/linux/generic/hack-5.15/660-fq_codel_defaults.patch
deleted file mode 100644
index a57a045f4a..0000000000
--- a/target/linux/generic/hack-5.15/660-fq_codel_defaults.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:21:53 +0200
-Subject: hack: net: fq_codel: tune defaults for small devices
-
-Assume that x86_64 devices always have a big memory and do not need this
-optimization compared to devices with only 32 MB or 64 MB RAM.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/sched/sch_fq_codel.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/net/sched/sch_fq_codel.c
-+++ b/net/sched/sch_fq_codel.c
-@@ -467,7 +467,11 @@ static int fq_codel_init(struct Qdisc *s
-
- sch->limit = 10*1024;
- q->flows_cnt = 1024;
-+#ifdef CONFIG_X86_64
- q->memory_limit = 32 << 20; /* 32 MBytes */
-+#else
-+ q->memory_limit = 4 << 20; /* 4 MBytes */
-+#endif
- q->drop_batch_size = 64;
- q->quantum = psched_mtu(qdisc_dev(sch));
- INIT_LIST_HEAD(&q->new_flows);
diff --git a/target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch b/target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch
deleted file mode 100644
index 89074d0a04..0000000000
--- a/target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 804fbb3f2ec9283f7b778e057a68bfff440a0be6 Mon Sep 17 00:00:00 2001
-From: Rui Salvaterra <rsalvaterra@gmail.com>
-Date: Wed, 30 Mar 2022 22:51:55 +0100
-Subject: [PATCH] kernel: ct: size the hashtable more adequately
-
-To set the default size of the connection tracking hash table, a divider of
-16384 becomes inadequate for a router handling lots of connections. Divide by
-2048 instead, making the default size scale better with the available RAM.
-
-Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
----
- net/netfilter/nf_conntrack_core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/net/netfilter/nf_conntrack_core.c
-+++ b/net/netfilter/nf_conntrack_core.c
-@@ -2737,7 +2737,7 @@ int nf_conntrack_init_start(void)
-
- if (!nf_conntrack_htable_size) {
- nf_conntrack_htable_size
-- = (((nr_pages << PAGE_SHIFT) / 16384)
-+ = (((nr_pages << PAGE_SHIFT) / 2048)
- / sizeof(struct hlist_head));
- if (BITS_PER_LONG >= 64 &&
- nr_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE)))
diff --git a/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch
deleted file mode 100644
index 9d77efaca6..0000000000
--- a/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:24:23 +0200
-Subject: net: swconfig: adds openwrt switch layer
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/phy/Makefile | 15 +++++++++
- include/uapi/linux/Kbuild | 1 +
- 3 files changed, 99 insertions(+)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -62,6 +62,80 @@ config SFP
- depends on HWMON || HWMON=n
- select MDIO_I2C
-
-+comment "Switch configuration API + drivers"
-+
-+config SWCONFIG
-+ tristate "Switch configuration API"
-+ help
-+ Switch configuration API using netlink. This allows
-+ you to configure the VLAN features of certain switches.
-+
-+config SWCONFIG_LEDS
-+ bool "Switch LED trigger support"
-+ depends on (SWCONFIG && LEDS_TRIGGERS)
-+
-+config ADM6996_PHY
-+ tristate "Driver for ADM6996 switches"
-+ select SWCONFIG
-+ help
-+ Currently supports the ADM6996FC and ADM6996M switches.
-+ Support for FC is very limited.
-+
-+config AR8216_PHY
-+ tristate "Driver for Atheros AR8216/8327 switches"
-+ select SWCONFIG
-+ select ETHERNET_PACKET_MANGLE
-+
-+config AR8216_PHY_LEDS
-+ bool "Atheros AR8216 switch LED support"
-+ depends on (AR8216_PHY && LEDS_CLASS)
-+
-+source "drivers/net/phy/b53/Kconfig"
-+
-+config IP17XX_PHY
-+ tristate "Driver for IC+ IP17xx switches"
-+ select SWCONFIG
-+
-+config PSB6970_PHY
-+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
-+ select SWCONFIG
-+
-+config RTL8306_PHY
-+ tristate "Driver for Realtek RTL8306S switches"
-+ select SWCONFIG
-+
-+config RTL8366_SMI
-+ tristate "Driver for the RTL8366 SMI interface"
-+ depends on GPIOLIB
-+ help
-+ This module implements the SMI interface protocol which is used
-+ by some RTL8366 ethernet switch devices via the generic GPIO API.
-+
-+if RTL8366_SMI
-+
-+config RTL8366_SMI_DEBUG_FS
-+ bool "RTL8366 SMI interface debugfs support"
-+ depends on DEBUG_FS
-+ default n
-+
-+config RTL8366S_PHY
-+ tristate "Driver for the Realtek RTL8366S switch"
-+ select SWCONFIG
-+
-+config RTL8366RB_PHY
-+ tristate "Driver for the Realtek RTL8366RB switch"
-+ select SWCONFIG
-+
-+config RTL8367_PHY
-+ tristate "Driver for the Realtek RTL8367R/M switches"
-+ select SWCONFIG
-+
-+config RTL8367B_PHY
-+ tristate "Driver fot the Realtek RTL8367R-VB switch"
-+ select SWCONFIG
-+
-+endif # RTL8366_SMI
-+
- comment "MII PHY device drivers"
-
- config AMD_PHY
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -24,6 +24,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_
- obj-$(CONFIG_PHYLINK) += phylink.o
- obj-$(CONFIG_PHYLIB) += libphy.o
-
-+obj-$(CONFIG_SWCONFIG) += swconfig.o
-+obj-$(CONFIG_ADM6996_PHY) += adm6996.o
-+obj-$(CONFIG_AR8216_PHY) += ar8xxx.o
-+ar8xxx-y += ar8216.o
-+ar8xxx-y += ar8327.o
-+obj-$(CONFIG_SWCONFIG_B53) += b53/
-+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
-+obj-$(CONFIG_PSB6970_PHY) += psb6970.o
-+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
-+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o
-+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o
-+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o
-+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o
-+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o
-+
- obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o
-
- obj-$(CONFIG_SFP) += sfp.o
---- a/include/linux/platform_data/b53.h
-+++ b/include/linux/platform_data/b53.h
-@@ -29,6 +29,9 @@ struct b53_platform_data {
- u32 chip_id;
- u16 enabled_ports;
-
-+ /* allow to specify an ethX alias */
-+ const char *alias;
-+
- /* only used by MMAP'd driver */
- unsigned big_endian:1;
- void __iomem *regs;
diff --git a/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch
deleted file mode 100644
index b2278069dd..0000000000
--- a/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From ebd924d773223593142d417c41d4ee6fa16f1805 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:45:56 +0200
-Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation
-
----
- drivers/net/dsa/mv88e6xxx/chip.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3017,6 +3017,9 @@ static int mv88e6xxx_setup_port(struct m
- else
- reg = 1 << port;
-
-+ /* Disable ATU member violation interrupt */
-+ reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG;
-+
- err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
- reg);
- if (err)
diff --git a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch
deleted file mode 100644
index b03b4a674f..0000000000
--- a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch
+++ /dev/null
@@ -1,178 +0,0 @@
-From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:25:00 +0200
-Subject: net: add packet mangeling
-
-ar8216 switches have a hardware bug, which renders normal 802.1q support
-unusable. Packet mangling is required to fix up the vlan for incoming
-packets.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/netdevice.h | 11 +++++++++++
- include/linux/skbuff.h | 14 ++++----------
- net/Kconfig | 6 ++++++
- net/core/dev.c | 20 +++++++++++++++-----
- net/core/skbuff.c | 17 +++++++++++++++++
- net/ethernet/eth.c | 6 ++++++
- 6 files changed, 59 insertions(+), 15 deletions(-)
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1682,6 +1682,10 @@ enum netdev_priv_flags {
- IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
- };
-
-+enum netdev_extra_priv_flags {
-+ IFF_NO_IP_ALIGN = 1<<0,
-+};
-+
- #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
- #define IFF_EBRIDGE IFF_EBRIDGE
- #define IFF_BONDING IFF_BONDING
-@@ -1713,6 +1717,7 @@ enum netdev_priv_flags {
- #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
- #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
- #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
-+#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
-
- /* Specifies the type of the struct net_device::ml_priv pointer */
- enum netdev_ml_priv_type {
-@@ -2013,6 +2018,7 @@ struct net_device {
- /* Read-mostly cache-line for fast-path access */
- unsigned int flags;
- unsigned int priv_flags;
-+ unsigned int extra_priv_flags;
- const struct net_device_ops *netdev_ops;
- int ifindex;
- unsigned short gflags;
-@@ -2073,6 +2079,11 @@ struct net_device {
- const struct tlsdev_ops *tlsdev_ops;
- #endif
-
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
-+ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
-+#endif
-+
- const struct header_ops *header_ops;
-
- unsigned char operstate;
-@@ -2144,6 +2155,10 @@ struct net_device {
- struct mctp_dev __rcu *mctp_ptr;
- #endif
-
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ void *phy_ptr; /* PHY device specific data */
-+#endif
-+
- /*
- * Cache lines mostly used on receive path (including eth_type_trans())
- */
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -2855,6 +2855,10 @@ static inline int pskb_trim(struct sk_bu
- return (len < skb->len) ? __pskb_trim(skb, len) : 0;
- }
-
-+extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
-+ unsigned int length, gfp_t gfp);
-+
-+
- /**
- * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
- * @skb: buffer to alter
-@@ -3005,16 +3009,6 @@ static inline struct sk_buff *dev_alloc_
- }
-
-
--static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
-- unsigned int length, gfp_t gfp)
--{
-- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
--
-- if (NET_IP_ALIGN && skb)
-- skb_reserve(skb, NET_IP_ALIGN);
-- return skb;
--}
--
- static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
- unsigned int length)
- {
---- a/net/Kconfig
-+++ b/net/Kconfig
-@@ -26,6 +26,12 @@ menuconfig NET
-
- if NET
-
-+config ETHERNET_PACKET_MANGLE
-+ bool
-+ help
-+ This option can be selected by phy drivers that need to mangle
-+ packets going in or out of an ethernet device.
-+
- config WANT_COMPAT_NETLINK_MESSAGES
- bool
- help
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -3600,6 +3600,11 @@ static int xmit_one(struct sk_buff *skb,
- if (dev_nit_active(dev))
- dev_queue_xmit_nit(skb, dev);
-
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb)))
-+ return NETDEV_TX_OK;
-+#endif
-+
- len = skb->len;
- PRANDOM_ADD_NOISE(skb, dev, txq, len + jiffies);
- trace_net_dev_start_xmit(skb, dev);
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -61,6 +61,7 @@
- #include <linux/if_vlan.h>
- #include <linux/mpls.h>
- #include <linux/kcov.h>
-+#include <linux/if.h>
-
- #include <net/protocol.h>
- #include <net/dst.h>
-@@ -602,6 +603,22 @@ skb_fail:
- }
- EXPORT_SYMBOL(__napi_alloc_skb);
-
-+struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
-+ unsigned int length, gfp_t gfp)
-+{
-+ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
-+
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ if (dev && (dev->extra_priv_flags & IFF_NO_IP_ALIGN))
-+ return skb;
-+#endif
-+
-+ if (NET_IP_ALIGN && skb)
-+ skb_reserve(skb, NET_IP_ALIGN);
-+ return skb;
-+}
-+EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
-+
- void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
- int size, unsigned int truesize)
- {
---- a/net/ethernet/eth.c
-+++ b/net/ethernet/eth.c
-@@ -170,6 +170,12 @@ __be16 eth_type_trans(struct sk_buff *sk
- const struct ethhdr *eth;
-
- skb->dev = dev;
-+
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ if (dev->eth_mangle_rx)
-+ dev->eth_mangle_rx(dev, skb);
-+#endif
-+
- skb_reset_mac_header(skb);
-
- eth = (struct ethhdr *)skb->data;
diff --git a/target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch
deleted file mode 100644
index d003291f75..0000000000
--- a/target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001
-From: Alex Marginean <alexandru.marginean@nxp.com>
-Date: Tue, 27 Aug 2019 15:16:56 +0300
-Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412
-
-Adds support for AQR112 and AQR412 which is mostly based on existing code
-with the addition of code configuring the protocol on system side.
-This allows changing the system side protocol without having to deploy a
-different firmware on the PHY.
-
-Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
----
- drivers/net/phy/aquantia/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 88 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -27,6 +27,8 @@
- #define PHY_ID_AQR113 0x31c31c40
- #define PHY_ID_AQR113C 0x31c31c12
- #define PHY_ID_AQR813 0x31c31cb2
-+#define PHY_ID_AQR112 0x03a1b662
-+#define PHY_ID_AQR412 0x03a1b712
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -99,6 +101,29 @@
- #define AQR107_OP_IN_PROG_SLEEP 1000
- #define AQR107_OP_IN_PROG_TIMEOUT 100000
-
-+/* registers in MDIO_MMD_VEND1 region */
-+#define AQUANTIA_VND1_GLOBAL_SC 0x000
-+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb)
-+
-+/* global start rate, the protocol associated with this speed is used by default
-+ * on SI.
-+ */
-+#define AQUANTIA_VND1_GSTART_RATE 0x31a
-+#define AQUANTIA_VND1_GSTART_RATE_OFF 0
-+#define AQUANTIA_VND1_GSTART_RATE_100M 1
-+#define AQUANTIA_VND1_GSTART_RATE_1G 2
-+#define AQUANTIA_VND1_GSTART_RATE_10G 3
-+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4
-+#define AQUANTIA_VND1_GSTART_RATE_5G 5
-+
-+/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */
-+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b
-+#define AQUANTIA_VND1_GSYSCFG_100M 0
-+#define AQUANTIA_VND1_GSYSCFG_1G 1
-+#define AQUANTIA_VND1_GSYSCFG_2_5G 2
-+#define AQUANTIA_VND1_GSYSCFG_5G 3
-+#define AQUANTIA_VND1_GSYSCFG_10G 4
-+
- struct aqr107_hw_stat {
- const char *name;
- int reg;
-@@ -230,6 +255,51 @@ static int aqr_config_aneg(struct phy_de
- return genphy_c45_check_and_restart_aneg(phydev, changed);
- }
-
-+static struct {
-+ u16 syscfg;
-+ int cnt;
-+ u16 start_rate;
-+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = {
-+ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G,
-+ AQUANTIA_VND1_GSTART_RATE_1G},
-+ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G,
-+ AQUANTIA_VND1_GSTART_RATE_2_5G},
-+ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G,
-+ AQUANTIA_VND1_GSTART_RATE_10G},
-+ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G,
-+ AQUANTIA_VND1_GSTART_RATE_10G},
-+};
-+
-+/* Sets up protocol on system side before calling aqr_config_aneg */
-+static int aqr_config_aneg_set_prot(struct phy_device *phydev)
-+{
-+ int if_type = phydev->interface;
-+ int i;
-+
-+ if (!aquantia_syscfg[if_type].cnt)
-+ return 0;
-+
-+ /* set PHY in low power mode so we can configure protocols */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC,
-+ AQUANTIA_VND1_GLOBAL_SC_LP);
-+ mdelay(10);
-+
-+ /* set the default rate to enable the SI link */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
-+ aquantia_syscfg[if_type].start_rate);
-+
-+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++)
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ AQUANTIA_VND1_GSYSCFG_BASE + i,
-+ aquantia_syscfg[if_type].syscfg);
-+
-+ /* wake PHY back up */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0);
-+ mdelay(10);
-+
-+ return aqr_config_aneg(phydev);
-+}
-+
- static int aqr_config_intr(struct phy_device *phydev)
- {
- bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
-@@ -858,6 +928,30 @@ static struct phy_driver aqr_driver[] =
- .get_stats = aqr107_get_stats,
- .link_change_notify = aqr107_link_change_notify,
- },
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112),
-+ .name = "Aquantia AQR112",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
-+ .name = "Aquantia AQR412",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
- };
-
- module_phy_driver(aqr_driver);
-@@ -875,6 +969,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
- { }
- };
-
diff --git a/target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch
deleted file mode 100644
index 72a70ebc14..0000000000
--- a/target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 5f008cb22f60da4e10375f22266c1a4e20b1252e Mon Sep 17 00:00:00 2001
-From: Alex Marginean <alexandru.marginean@nxp.com>
-Date: Fri, 20 Sep 2019 18:22:52 +0300
-Subject: [PATCH] drivers: net: phy: aquantia: fix system side protocol
- misconfiguration
-
-Do not set up protocols for speeds that are not supported by FW. Enabling
-these protocols leads to link issues on system side.
-
-Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
----
- drivers/net/phy/aquantia/aquantia_main.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -288,10 +288,16 @@ static int aqr_config_aneg_set_prot(stru
- phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
- aquantia_syscfg[if_type].start_rate);
-
-- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++)
-+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) {
-+ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1,
-+ AQUANTIA_VND1_GSYSCFG_BASE + i);
-+ if (!reg)
-+ continue;
-+
- phy_write_mmd(phydev, MDIO_MMD_VEND1,
- AQUANTIA_VND1_GSYSCFG_BASE + i,
- aquantia_syscfg[if_type].syscfg);
-+ }
-
- /* wake PHY back up */
- phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0);
diff --git a/target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch b/target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch
deleted file mode 100644
index 2193844e64..0000000000
--- a/target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 3b92ee7b7899b6beffb2b484c58326e36612a873 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 23 Dec 2021 14:52:56 +0000
-Subject: [PATCH] net: phy: aquantia: add PHY_ID for AQR112R
-
-As advised by Ian Chang this PHY is used in Puzzle devices.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/aquantia/aquantia_main.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -29,6 +29,8 @@
- #define PHY_ID_AQR813 0x31c31cb2
- #define PHY_ID_AQR112 0x03a1b662
- #define PHY_ID_AQR412 0x03a1b712
-+#define PHY_ID_AQR112C 0x03a1b790
-+#define PHY_ID_AQR112R 0x31c31d12
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -880,6 +882,30 @@ static struct phy_driver aqr_driver[] =
- .read_status = aqr_read_status,
- },
- {
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C),
-+ .name = "Aquantia AQR112C",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R),
-+ .name = "Aquantia AQR112R",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
-+{
- PHY_ID_MATCH_MODEL(PHY_ID_AQR113),
- .name = "Aquantia AQR113",
- .probe = aqr107_probe,
-@@ -977,6 +1003,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) },
- { }
- };
-
diff --git a/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch b/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch
deleted file mode 100644
index 8b7f2f0955..0000000000
--- a/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 880d1311335120f64447ca9d11933872d734e19a Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 27 Mar 2023 18:41:54 +0100
-Subject: [PATCH] generic: pcs-mtk-lynxi: add hack to use 2500Base-X without AN
-
-Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
-disabling auto-negotiation, e.g. using ethtool. While a proper fix
-using SFP quirks is being discussed upstream, bring a work-around to
-restore user experience to what it was before the switch to the
-dedicated SGMII PCS driver.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/drivers/net/pcs/pcs-mtk-lynxi.c
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(stru
- struct phylink_link_state *state)
- {
- struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-- unsigned int bm, adv;
-+ unsigned int bm, bmsr, adv;
-
- /* Read the BMSR and LPA */
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+ bmsr = FIELD_GET(SGMII_BMSR, bm);
-+
-+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
-+ state->link = !!(bmsr & BMSR_LSTATUS);
-+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
-+ state->speed = SPEED_2500;
-+ state->duplex = DUPLEX_FULL;
-
-- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-- FIELD_GET(SGMII_LPA, adv));
-+ return;
-+ }
-+
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
- }
-
- static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -134,7 +143,8 @@ static int mtk_pcs_lynxi_config(struct p
- /* 1000base-X or 2500base-X autoneg */
- sgm_mode = SGMII_REMOTE_FAULT_DIS;
- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-- advertising);
-+ advertising) &&
-+ !(interface == PHY_INTERFACE_MODE_2500BASEX);
- } else {
- /* 1000base-X or 2500base-X without autoneg */
- sgm_mode = 0;
diff --git a/target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch
deleted file mode 100644
index 5c5bd99b45..0000000000
--- a/target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 82985725e071f2a5735052f18e109a32aeac3a0b Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 26 Jul 2020 02:38:31 +0200
-Subject: [PATCH] net: usb: r8152: add LED configuration from OF
-
-This adds the ability to configure the LED configuration register using
-OF. This way, the correct value for board specific LED configuration can
-be determined.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -11,6 +11,7 @@
- #include <linux/mii.h>
- #include <linux/ethtool.h>
- #include <linux/usb.h>
-+#include <linux/of.h>
- #include <linux/crc32.h>
- #include <linux/if_vlan.h>
- #include <linux/uaccess.h>
-@@ -6994,6 +6995,22 @@ static void rtl_tally_reset(struct r8152
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data);
- }
-
-+static int r8152_led_configuration(struct r8152 *tp)
-+{
-+ u32 led_data;
-+ int ret;
-+
-+ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data",
-+ &led_data);
-+
-+ if (ret)
-+ return ret;
-+
-+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data);
-+
-+ return 0;
-+}
-+
- static void r8152b_init(struct r8152 *tp)
- {
- u32 ocp_data;
-@@ -7035,6 +7052,8 @@ static void r8152b_init(struct r8152 *tp
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN);
- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
-+
-+ r8152_led_configuration(tp);
- }
-
- static void r8153_init(struct r8152 *tp)
-@@ -7175,6 +7194,8 @@ static void r8153_init(struct r8152 *tp)
- tp->coalesce = COALESCE_SLOW;
- break;
- }
-+
-+ r8152_led_configuration(tp);
- }
-
- static void r8153b_init(struct r8152 *tp)
-@@ -7257,6 +7278,8 @@ static void r8153b_init(struct r8152 *tp
- rtl_tally_reset(tp);
-
- tp->coalesce = 15000; /* 15 us */
-+
-+ r8152_led_configuration(tp);
- }
-
- static void r8153c_init(struct r8152 *tp)
diff --git a/target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch b/target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch
deleted file mode 100644
index be262b993c..0000000000
--- a/target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 3ee05f4aa64fc86af3be5bc176ba5808de9260a7 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 26 Jul 2020 15:30:33 +0200
-Subject: [PATCH] dt-bindings: net: add RTL8152 binding documentation
-
-Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet
-adapters.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- .../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++
- 1 file changed, 36 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
-@@ -0,0 +1,36 @@
-+# SPDX-License-Identifier: GPL-2.0
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Realtek RTL8152/RTL8153 series USB ethernet
-+
-+maintainers:
-+ - David Bauer <mail@david-bauer.net>
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - items:
-+ - enum:
-+ - realtek,rtl8152
-+ - realtek,rtl8153
-+
-+ reg:
-+ description: The device number on the USB bus
-+
-+ realtek,led-data:
-+ description: Value to be written to the LED configuration register.
-+
-+required:
-+ - compatible
-+ - reg
-+
-+examples:
-+ - |
-+ usb-eth@2 {
-+ compatible = "realtek,rtl8153";
-+ reg = <2>;
-+ realtek,led-data = <0x87>;
-+ };
-\ No newline at end of file
diff --git a/target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch b/target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch
deleted file mode 100644
index 95e9749d91..0000000000
--- a/target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 94b90966095f3fa625897e8f53d215882f6e19b3 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sat, 11 Mar 2023 17:00:01 +0100
-Subject: [PATCH] mxl-gpy: control LED reg from DT
-
-Add dynamic configuration for the LED control registers on MXL PHYs.
-
-This patch has been tested with MaxLinear GPY211C. It is unlikely to be
-accepted upstream, as upstream plans on integrating their own framework
-for handling these LEDs.
-
-For the time being, use this hack to configure PHY driven device-LEDs to
-show the correct state.
-
-A possible alternative might be to expose the LEDs using the kernel LED
-framework and bind it to the netdevice. This might also be upstreamable,
-although it is a considerable extra amount of work.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/phy/mxl-gpy.c | 37 ++++++++++++++++++++++++++++++++++++-
- 1 file changed, 36 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -8,6 +8,7 @@
-
- #include <linux/module.h>
- #include <linux/bitfield.h>
-+#include <linux/of.h>
- #include <linux/phy.h>
- #include <linux/netdevice.h>
-
-@@ -30,6 +31,7 @@
- #define PHY_MIISTAT 0x18 /* MII state */
- #define PHY_IMASK 0x19 /* interrupt mask */
- #define PHY_ISTAT 0x1A /* interrupt status */
-+#define PHY_LED 0x1B /* LED control */
- #define PHY_FWV 0x1E /* firmware version */
-
- #define PHY_MIISTAT_SPD_MASK GENMASK(2, 0)
-@@ -53,10 +55,15 @@
- PHY_IMASK_ADSC | \
- PHY_IMASK_ANC)
-
-+#define PHY_LED_NUM_LEDS 4
-+
- #define PHY_FWV_REL_MASK BIT(15)
- #define PHY_FWV_TYPE_MASK GENMASK(11, 8)
- #define PHY_FWV_MINOR_MASK GENMASK(7, 0)
-
-+/* LED */
-+#define VSPEC1_LED(x) (0x1 + x)
-+
- /* SGMII */
- #define VSPEC1_SGMII_CTRL 0x08
- #define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */
-@@ -80,6 +87,35 @@ static const struct {
- {9, 0x73},
- };
-
-+static int gpy_led_write(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ u32 led_regs[PHY_LED_NUM_LEDS];
-+ int i, ret;
-+ u16 val = 0xff00;
-+
-+ if (!IS_ENABLED(CONFIG_OF_MDIO))
-+ return 0;
-+
-+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS))
-+ return 0;
-+
-+ if (of_property_read_bool(node, "mxl,led-drive-vdd"))
-+ val &= 0x0fff;
-+
-+ /* Enable LED function handling on all ports*/
-+ phy_write(phydev, PHY_LED, val);
-+
-+ /* Write LED register values */
-+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) {
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(i), (u16)led_regs[i]);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int gpy_config_init(struct phy_device *phydev)
- {
- int ret;
-@@ -91,7 +127,10 @@ static int gpy_config_init(struct phy_de
-
- /* Clear all pending interrupts */
- ret = phy_read(phydev, PHY_ISTAT);
-- return ret < 0 ? ret : 0;
-+ if (ret < 0)
-+ return ret;
-+
-+ return gpy_led_write(phydev);
- }
-
- static int gpy_probe(struct phy_device *phydev)
diff --git a/target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch b/target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch
deleted file mode 100644
index 3405d5c535..0000000000
--- a/target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From cc225d163b5a4f7a0d1968298bf7927306646a47 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Fri, 28 Apr 2023 01:53:01 +0200
-Subject: [PATCH] net: phy: mediatek-ge: add LED configuration interface
-
-This adds a small hack similar to the one used for ar8xxx switches to
-read a reg:value map for configuring the LED configuration registers.
-
-This allows OpenWrt to write device-specific LED action as well as blink
-configurations. It is unlikely to be accepted upstream, as upstream
-plans on integrating their own framework for handling these LEDs.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/phy/mediatek-ge.c | 33 +++++++++++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
---- a/drivers/net/phy/mediatek-ge.c
-+++ b/drivers/net/phy/mediatek-ge.c
-@@ -1,4 +1,5 @@
- // SPDX-License-Identifier: GPL-2.0+
-+#include <linux/of.h>
- #include <linux/bitfield.h>
- #include <linux/module.h>
- #include <linux/phy.h>
-@@ -53,6 +54,36 @@ static int mt7530_phy_config_init(struct
- return 0;
- }
-
-+static int mt7530_led_config_of(struct phy_device *phydev)
-+{
-+ struct device_node *np = phydev->mdio.dev.of_node;
-+ const __be32 *paddr;
-+ int len;
-+ int i;
-+
-+ paddr = of_get_property(np, "mediatek,led-config", &len);
-+ if (!paddr)
-+ return 0;
-+
-+ if (len < (2 * sizeof(*paddr)))
-+ return -EINVAL;
-+
-+ len /= sizeof(*paddr);
-+
-+ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len);
-+ for (i = 0; i < len - 1; i += 2) {
-+ u32 reg;
-+ u32 val;
-+
-+ reg = be32_to_cpup(paddr + i);
-+ val = be32_to_cpup(paddr + i + 1);
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val);
-+ }
-+
-+ return 0;
-+}
-+
- static int mt7531_phy_config_init(struct phy_device *phydev)
- {
- mtk_gephy_config_init(phydev);
-@@ -65,6 +96,9 @@ static int mt7531_phy_config_init(struct
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
-
-+ /* LED Config*/
-+ mt7530_led_config_of(phydev);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch
deleted file mode 100644
index 7127aa136c..0000000000
--- a/target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 7 Jul 2017 17:26:01 +0200
-Subject: bcm53xx: bgmac: use srab switch driver
-
-use the srab switch driver on these SoCs.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 +
- drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++
- drivers/net/ethernet/broadcom/bgmac.h | 4 ++++
- 3 files changed, 29 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_devic
- bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
- bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
- bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
-+ bgmac->feature_flags |= BGMAC_FEAT_SRAB;
- break;
- default:
- bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -12,6 +12,7 @@
- #include <linux/bcma/bcma.h>
- #include <linux/etherdevice.h>
- #include <linux/interrupt.h>
-+#include <linux/platform_data/b53.h>
- #include <linux/bcm47xx_nvram.h>
- #include <linux/phy.h>
- #include <linux/phy_fixed.h>
-@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et
- .set_link_ksettings = phy_ethtool_set_link_ksettings,
- };
-
-+static struct b53_platform_data bgmac_b53_pdata = {
-+};
-+
-+static struct platform_device bgmac_b53_dev = {
-+ .name = "b53-srab-switch",
-+ .id = -1,
-+ .dev = {
-+ .platform_data = &bgmac_b53_pdata,
-+ },
-+};
-+
- /**************************************************
- * MII
- **************************************************/
-@@ -1546,6 +1558,14 @@ int bgmac_enet_probe(struct bgmac *bgmac
-
- bgmac->in_init = false;
-
-+ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) {
-+ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000);
-+
-+ err = platform_device_register(&bgmac_b53_dev);
-+ if (!err)
-+ bgmac->b53_device = &bgmac_b53_dev;
-+ }
-+
- err = register_netdev(bgmac->net_dev);
- if (err) {
- dev_err(bgmac->dev, "Cannot register net device\n");
-@@ -1568,6 +1588,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe);
-
- void bgmac_enet_remove(struct bgmac *bgmac)
- {
-+ if (bgmac->b53_device)
-+ platform_device_unregister(&bgmac_b53_dev);
-+ bgmac->b53_device = NULL;
-+
- unregister_netdev(bgmac->net_dev);
- phy_disconnect(bgmac->net_dev->phydev);
- netif_napi_del(&bgmac->napi);
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -390,6 +390,7 @@
- #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18)
- #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19)
- #define BGMAC_FEAT_IDM_MASK BIT(20)
-+#define BGMAC_FEAT_SRAB BIT(21)
-
- struct bgmac_slot_info {
- union {
-@@ -497,6 +498,9 @@ struct bgmac {
- void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
- u32 set);
- int (*phy_connect)(struct bgmac *bgmac);
-+
-+ /* platform device for associated switch */
-+ struct platform_device *b53_device;
- };
-
- struct bgmac *bgmac_alloc(struct device *dev);
diff --git a/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch
deleted file mode 100644
index b4ed6c9910..0000000000
--- a/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From f81700b6bb2eda3756247bce472d8eaf6f466f61 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:49:26 +0200
-Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
-
----
- drivers/net/usb/qmi_wwan.c | 1 +
- drivers/usb/serial/option.c | 7 +++++++
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/usb/qmi_wwan.c
-+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1080,12 +1080,18 @@ static const struct usb_device_id produc
- USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
- .driver_info = (unsigned long)&qmi_wwan_info,
- },
-+ { /* Meiglink SGM828 */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, USB_CLASS_VENDOR_SPEC, 0x10, 0x05),
-+ .driver_info = (unsigned long)&qmi_wwan_info,
-+ },
-+
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */
-+ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* MeigLink SLM750 */
-
- /* 3. Combined interface devices matching on interface number */
- {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
---- a/drivers/usb/serial/option.c
-+++ b/drivers/usb/serial/option.c
-@@ -247,6 +247,11 @@ static void option_instat_callback(struc
- #define UBLOX_PRODUCT_R410M 0x90b2
- /* These Yuga products use Qualcomm's vendor ID */
- #define YUGA_PRODUCT_CLM920_NC5 0x9625
-+/* These MeigLink products use Qualcomm's vendor ID */
-+#define MEIGLINK_PRODUCT_SLM750 0xf601
-+
-+#define MEIGLINK_VENDOR_ID 0x2dee
-+#define MEIGLINK_PRODUCT_SLM828 0x4d49
-
- #define QUECTEL_VENDOR_ID 0x2c7c
- /* These Quectel products use Quectel's vendor ID */
-@@ -1156,6 +1161,11 @@ static const struct usb_device_id option
- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */
- .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) },
-+ /* MeiG */
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x01) },
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x02) },
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x03) },
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x04) },
- /* Quectel products using Qualcomm vendor ID */
- { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
- { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
-@@ -1197,6 +1207,11 @@ static const struct usb_device_id option
- .driver_info = ZLP },
- { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
- .driver_info = RSVD(4) },
-+ /* Meiglink products using Qualcomm vendor ID */
-+ // Works OK. In case of some issues check macros that are used by Quectel Products
-+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0xff, 0xff),
-+ .driver_info = NUMEP2 },
-+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0, 0) },
- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
- .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
diff --git a/target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch b/target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch
deleted file mode 100644
index 47339b6c22..0000000000
--- a/target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 9fabf60187f1fa19e6f6bb5441587d485bd534b0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 9 Apr 2024 17:06:38 +0100
-Subject: [PATCH] rndis_host: add a bunch of USB IDs
-
-Add a bunch of USB IDs found in various places online to the
-RNDIS USB network driver.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/usb/rndis_host.c | 40 ++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
---- a/drivers/net/usb/rndis_host.c
-+++ b/drivers/net/usb/rndis_host.c
-@@ -630,6 +630,16 @@ static const struct driver_info zte_rndi
- .tx_fixup = rndis_tx_fixup,
- };
-
-+static const struct driver_info asr_rndis_info = {
-+ .description = "Asr RNDIS device",
-+ .flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT | FLAG_NOARP,
-+ .bind = rndis_bind,
-+ .unbind = rndis_unbind,
-+ .status = rndis_status,
-+ .rx_fixup = rndis_rx_fixup,
-+ .tx_fixup = rndis_tx_fixup,
-+};
-+
- /*-------------------------------------------------------------------------*/
-
- static const struct usb_device_id products [] = {
-@@ -666,6 +676,36 @@ static const struct usb_device_id produc
- USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
- .driver_info = (unsigned long) &rndis_info,
- }, {
-+ /* Quectel EG060V rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6004,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Quectel EC200A rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6005,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Quectel EC200T rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6026,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Simcom A7906E rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x1e0e, 0x9011,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Meig SLM770A */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Meig SLM828 */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
- /* Novatel Verizon USB730L */
- USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
- .driver_info = (unsigned long) &rndis_info,
diff --git a/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch b/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch
deleted file mode 100644
index e7372b31d1..0000000000
--- a/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 7cc39a6bedbd85f3ff7e16845f310e4ce8d9833f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 6 Sep 2022 00:31:19 +0100
-Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
-To: netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- Russell King <linux@armlinux.org.uk>,
- Andrew Lunn <andrew@lunn.ch>,
- Heiner Kallweit <hkallweit1@gmail.com>
-Cc: David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Josef Schlehofer <pepe.schlehofer@gmail.com>
-
-This copper module comes with broken TX_FAULT indicator which must be
-ignored for it to work. Implement ignoring TX_FAULT state bit also
-during reset/insertion and mute the warning telling the user that the
-module indicates TX_FAULT.
-
-Co-authored-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/sfp.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -390,6 +390,11 @@ static const struct sfp_quirk sfp_quirks
- .modes = sfp_quirk_2500basex,
- .fixup = sfp_fixup_ignore_tx_fault,
- }, {
-+ // OEM SFP-GE-T is 1000Base-T module
-+ .vendor = "OEM",
-+ .part = "SFP-GE-T",
-+ .fixup = sfp_fixup_ignore_tx_fault,
-+ }, {
- // Lantech 8330-262D-E can operate at 2500base-X, but
- // incorrectly report 2500MBd NRZ in their EEPROM
- .vendor = "Lantech",
-@@ -2319,7 +2324,8 @@ static void sfp_sm_main(struct sfp *sfp,
- * or t_start_up, so assume there is a fault.
- */
- sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
-- sfp->sm_fault_retries == N_FAULT_INIT);
-+ !sfp->tx_fault_ignore &&
-+ (sfp->sm_fault_retries == N_FAULT_INIT));
- } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
- init_done:
- sfp->sm_phy_retries = R_PHY_RETRY;
-@@ -2542,10 +2548,12 @@ static void sfp_check_state(struct sfp *
- mutex_lock(&sfp->st_mutex);
- state = sfp_get_state(sfp);
- changed = state ^ sfp->state;
-- if (sfp->tx_fault_ignore)
-+ if (sfp->tx_fault_ignore) {
- changed &= SFP_F_PRESENT | SFP_F_LOS;
-- else
-+ state &= ~SFP_F_TX_FAULT;
-+ } else {
- changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
-+ }
-
- for (i = 0; i < GPIO_MAX; i++)
- if (changed & BIT(i))
diff --git a/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch b/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch
deleted file mode 100644
index f93d84c6a4..0000000000
--- a/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From 027586ae8ecacff49757ed854c020f35d24a599c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 11 Mar 2023 03:44:41 +0000
-Subject: [PATCH] generic: backport some phylink helper functions
-
-It isn't feasible to literally backport all upstream phylink_pcs changes
-down to Linux 5.15: It's just too many patches, and many downstream
-drivers and hacks are likely to break. We are too close to branching off
-to risk this, and it's also just too much work.
-Instead just add helper functions used by modern PCS drivers while keeping
-the original functions instact as well. While this may add a kilobyte or
-two of extra kernel size, it has the advantage that we get the best of both
-worlds: None of the existing codepaths are touched, but yet we have the
-option to backport singular improvements to Ethernet drivers where needed.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -600,10 +600,37 @@ int phylink_speed_up(struct phylink *pl)
- #define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
-
- void phylink_set_port_modes(unsigned long *bits);
-+
-+/**
-+ * phylink_get_link_timer_ns - return the PCS link timer value
-+ * @interface: link &typedef phy_interface_t mode
-+ *
-+ * Return the PCS link timer setting in nanoseconds for the PHY @interface
-+ * mode, or -EINVAL if not appropriate.
-+ */
-+static inline int phylink_get_link_timer_ns(phy_interface_t interface)
-+{
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_SGMII:
-+ return 1600000;
-+
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ return 10000000;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
- void phylink_helper_basex_speed(struct phylink_link_state *state);
-
-+void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
-+ u16 bmsr, u16 lpa);
- void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
- struct phylink_link_state *state);
-+int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
-+ const unsigned long *advertising);
- int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
- phy_interface_t interface,
- const unsigned long *advertising);
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -934,7 +934,6 @@ static int phylink_change_inband_advert(
-
- return 0;
- }
--
- static void phylink_mac_pcs_get_state(struct phylink *pl,
- struct phylink_link_state *state)
- {
-@@ -3019,6 +3018,52 @@ void phylink_mii_c22_pcs_get_state(struc
- EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
-
- /**
-+ * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
-+ * @state: a pointer to a &struct phylink_link_state.
-+ * @bmsr: The value of the %MII_BMSR register
-+ * @lpa: The value of the %MII_LPA register
-+ *
-+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for
-+ * clause 37 negotiation and/or SGMII control.
-+ *
-+ * Parse the Clause 37 or Cisco SGMII link partner negotiation word into
-+ * the phylink @state structure. This is suitable to be used for implementing
-+ * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if
-+ * accessing @bmsr and @lpa cannot be done with MDIO directly.
-+ */
-+void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
-+ u16 bmsr, u16 lpa)
-+{
-+ state->link = !!(bmsr & BMSR_LSTATUS);
-+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
-+ /* If there is no link or autonegotiation is disabled, the LP advertisement
-+ * data is not meaningful, so don't go any further.
-+ */
-+ if (!state->link || !state->an_enabled)
-+ return;
-+
-+ switch (state->interface) {
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ phylink_decode_c37_word(state, lpa, SPEED_1000);
-+ break;
-+
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ phylink_decode_c37_word(state, lpa, SPEED_2500);
-+ break;
-+
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ phylink_decode_sgmii_word(state, lpa);
-+ break;
-+
-+ default:
-+ state->link = false;
-+ break;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state);
-+
-+/**
- * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
- * advertisement
- * @pcs: a pointer to a &struct mdio_device.
-@@ -3090,6 +3135,46 @@ int phylink_mii_c22_pcs_set_advertisemen
- EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
-
- /**
-+ * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
-+ * advertisement
-+ * @interface: the PHY interface mode being configured
-+ * @advertising: the ethtool advertisement mask
-+ *
-+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for
-+ * clause 37 negotiation and/or SGMII control.
-+ *
-+ * Encode the clause 37 PCS advertisement as specified by @interface and
-+ * @advertising.
-+ *
-+ * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
-+ */
-+int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
-+ const unsigned long *advertising)
-+{
-+ u16 adv;
-+
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ adv = ADVERTISE_1000XFULL;
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ advertising))
-+ adv |= ADVERTISE_1000XPAUSE;
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ advertising))
-+ adv |= ADVERTISE_1000XPSE_ASYM;
-+ return adv;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_QSGMII:
-+ return 0x0001;
-+ default:
-+ /* Nothing to do for other modes */
-+ return -EINVAL;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement);
-+
-+/**
- * phylink_mii_c22_pcs_config() - configure clause 22 PCS
- * @pcs: a pointer to a &struct mdio_device.
- * @mode: link autonegotiation mode
diff --git a/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch
deleted file mode 100644
index 258a5fb33c..0000000000
--- a/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 12 Aug 2014 20:49:27 +0200
-Subject: [PATCH 30/36] GPIO: add named gpio exports
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
---- a/drivers/gpio/gpiolib-of.c
-+++ b/drivers/gpio/gpiolib-of.c
-@@ -19,6 +19,8 @@
- #include <linux/pinctrl/pinctrl.h>
- #include <linux/slab.h>
- #include <linux/gpio/machine.h>
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
-
- #include "gpiolib.h"
- #include "gpiolib-of.h"
-@@ -1059,3 +1061,100 @@ void of_gpio_dev_init(struct gpio_chip *
- else
- gc->of_node = gdev->dev.of_node;
- }
-+
-+#ifdef CONFIG_GPIO_SYSFS
-+
-+static struct of_device_id gpio_export_ids[] = {
-+ { .compatible = "gpio-export" },
-+ { /* sentinel */ }
-+};
-+
-+static int of_gpio_export_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct device_node *cnp;
-+ u32 val;
-+ int nb = 0;
-+
-+ for_each_child_of_node(np, cnp) {
-+ const char *name = NULL;
-+ int gpio;
-+ bool dmc;
-+ int max_gpio = 1;
-+ int i;
-+
-+ of_property_read_string(cnp, "gpio-export,name", &name);
-+
-+ if (!name)
-+ max_gpio = of_gpio_count(cnp);
-+
-+ for (i = 0; i < max_gpio; i++) {
-+ struct gpio_desc *desc;
-+ unsigned flags = 0;
-+ enum of_gpio_flags of_flags;
-+
-+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
-+ if (!gpio_is_valid(gpio))
-+ return gpio;
-+
-+ if (of_flags & OF_GPIO_ACTIVE_LOW)
-+ flags |= GPIOF_ACTIVE_LOW;
-+
-+ if (!of_property_read_u32(cnp, "gpio-export,output", &val)) {
-+ if (of_flags & OF_GPIO_SINGLE_ENDED) {
-+ /*
-+ * As gpiod_direction_output_raw() is used, we
-+ * need to emulate open drain or open source here.
-+ */
-+ if (of_flags & OF_GPIO_OPEN_DRAIN) {
-+ flags |= GPIOF_OPEN_DRAIN;
-+ flags |= val ? GPIOF_IN : GPIOF_OUT_INIT_LOW;
-+ } else {
-+ flags |= GPIOF_OPEN_SOURCE;
-+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_IN;
-+ }
-+ } else {
-+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-+ }
-+ } else {
-+ flags |= GPIOF_IN;
-+ }
-+
-+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
-+ continue;
-+
-+ /*
-+ * When emulating open-source or open-drain functionalities by not
-+ * actively driving the line (setting mode to input) we still need to
-+ * set the IS_OUT flag or otherwise we won't be able to set the line
-+ * value anymore.
-+ */
-+ if ((flags & GPIOF_IN) &&
-+ ((flags & GPIOF_OPEN_DRAIN) || (flags & GPIOF_OPEN_SOURCE))) {
-+ desc = gpio_to_desc(gpio);
-+ set_bit(FLAG_IS_OUT, &desc->flags);
-+ }
-+
-+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
-+ gpio_export_with_name(gpio, dmc, name);
-+ nb++;
-+ }
-+ }
-+
-+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver gpio_export_driver = {
-+ .driver = {
-+ .name = "gpio-export",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(gpio_export_ids),
-+ },
-+ .probe = of_gpio_export_probe,
-+};
-+
-+module_platform_driver(gpio_export_driver);
-+
-+#endif
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -125,6 +125,12 @@ static inline int gpio_export(unsigned g
- return gpiod_export(gpio_to_desc(gpio), direction_may_change);
- }
-
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
-+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
-+{
-+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
-+}
-+
- static inline int gpio_export_link(struct device *dev, const char *name,
- unsigned gpio)
- {
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -712,6 +712,7 @@ static inline void devm_acpi_dev_remove_
-
- #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
-
-+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
- int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
- int gpiod_export_link(struct device *dev, const char *name,
- struct gpio_desc *desc);
-@@ -719,6 +720,13 @@ void gpiod_unexport(struct gpio_desc *de
-
- #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
-
-+static inline int _gpiod_export(struct gpio_desc *desc,
-+ bool direction_may_change,
-+ const char *name)
-+{
-+ return -ENOSYS;
-+}
-+
- static inline int gpiod_export(struct gpio_desc *desc,
- bool direction_may_change)
- {
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -564,7 +564,7 @@ static struct class gpio_class = {
- *
- * Returns zero on success, else an error.
- */
--int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
- {
- struct gpio_chip *chip;
- struct gpio_device *gdev;
-@@ -626,6 +626,8 @@ int gpiod_export(struct gpio_desc *desc,
- offset = gpio_chip_hwgpio(desc);
- if (chip->names && chip->names[offset])
- ioname = chip->names[offset];
-+ if (name)
-+ ioname = name;
-
- dev = device_create_with_groups(&gpio_class, &gdev->dev,
- MKDEV(0, 0), data, gpio_groups,
-@@ -647,6 +649,12 @@ err_unlock:
- gpiod_dbg(desc, "%s: status %d\n", __func__, status);
- return status;
- }
-+EXPORT_SYMBOL_GPL(__gpiod_export);
-+
-+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+{
-+ return __gpiod_export(desc, direction_may_change, NULL);
-+}
- EXPORT_SYMBOL_GPL(gpiod_export);
-
- static int match_export(struct device *dev, const void *desc)
diff --git a/target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch b/target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch
deleted file mode 100644
index c581a512cb..0000000000
--- a/target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From e4d708702e6c98f2111e33201a264d6788564cb2 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Fri, 12 May 2023 11:08:43 +0200
-Subject: [PATCH] ssb_sprom: add generic kernel support for Broadcom Fallback SPROMs
-
----
- drivers/bcma/Kconfig | 4 ++++
- drivers/bcma/Makefile | 1 +
- drivers/bcma/bcma_private.h | 4 ++++
- drivers/bcma/main.c | 8 ++++++++
- drivers/bcma/sprom.c | 23 ++++++++++++++---------
- drivers/ssb/Kconfig | 5 +++++
- drivers/ssb/Makefile | 1 +
- drivers/ssb/main.c | 8 ++++++++
- drivers/ssb/sprom.c | 12 +++++++++++-
- drivers/ssb/ssb_private.h | 4 ++++
- 10 files changed, 60 insertions(+), 10 deletions(-)
-
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -18,6 +18,10 @@ config BCMA_BLOCKIO
- bool
- default y
-
-+config BCMA_FALLBACK_SPROM
-+ bool
-+ default y
-+
- config BCMA_HOST_PCI_POSSIBLE
- bool
- depends on PCI = y
---- a/drivers/bcma/Makefile
-+++ b/drivers/bcma/Makefile
-@@ -11,6 +11,7 @@ bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)
- bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
- bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o
- bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o
-+bcma-$(CONFIG_BCMA_FALLBACK_SPROM) += fallback-sprom.o
- bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
- bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
- obj-$(CONFIG_BCMA) += bcma.o
---- a/drivers/bcma/bcma_private.h
-+++ b/drivers/bcma/bcma_private.h
-@@ -38,6 +38,10 @@ int bcma_bus_resume(struct bcma_bus *bus
- void bcma_detect_chip(struct bcma_bus *bus);
- int bcma_bus_scan(struct bcma_bus *bus);
-
-+/* fallback-sprom.c */
-+int __init bcma_fbs_register(void);
-+int bcma_get_fallback_sprom(struct bcma_bus *dev, struct ssb_sprom *out);
-+
- /* sprom.c */
- int bcma_sprom_get(struct bcma_bus *bus);
-
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -668,6 +668,14 @@ static int __init bcma_modinit(void)
- {
- int err;
-
-+#ifdef CONFIG_BCMA_FALLBACK_SPROM
-+ err = bcma_fbs_register();
-+ if (err) {
-+ pr_err("Fallback SPROM initialization failed\n");
-+ err = 0;
-+ }
-+#endif /* CONFIG_BCMA_FALLBACK_SPROM */
-+
- err = bcma_init_bus_register();
- if (err)
- return err;
---- a/drivers/bcma/sprom.c
-+++ b/drivers/bcma/sprom.c
-@@ -51,21 +51,26 @@ static int bcma_fill_sprom_with_fallback
- {
- int err;
-
-- if (!get_fallback_sprom) {
-+ if (get_fallback_sprom)
-+ err = get_fallback_sprom(bus, out);
-+
-+#ifdef CONFIG_BCMA_FALLBACK_SPROM
-+ if (!get_fallback_sprom || err)
-+ err = bcma_get_fallback_sprom(bus, out);
-+#else
-+ if (!get_fallback_sprom)
- err = -ENOENT;
-- goto fail;
-- }
-+#endif /* CONFIG_BCMA_FALLBACK_SPROM */
-
-- err = get_fallback_sprom(bus, out);
-- if (err)
-- goto fail;
-+ if (err) {
-+ bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err);
-+ return err;
-+ }
-
- bcma_debug(bus, "Using SPROM revision %d provided by platform.\n",
- bus->sprom.revision);
-+
- return 0;
--fail:
-- bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err);
-- return err;
- }
-
- /**************************************************
---- a/drivers/ssb/Kconfig
-+++ b/drivers/ssb/Kconfig
-@@ -25,6 +25,11 @@ if SSB
- config SSB_SPROM
- bool
-
-+config SSB_FALLBACK_SPROM
-+ bool
-+ depends on SSB_PCIHOST
-+ default y
-+
- # Support for Block-I/O. SELECT this from the driver that needs it.
- config SSB_BLOCKIO
- bool
---- a/drivers/ssb/Makefile
-+++ b/drivers/ssb/Makefile
-@@ -2,6 +2,7 @@
- # core
- ssb-y += main.o scan.o
- ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o
-+ssb-$(CONFIG_SSB_FALLBACK_SPROM) += fallback-sprom.o
- ssb-$(CONFIG_SSB_SPROM) += sprom.o
-
- # host support
---- a/drivers/ssb/main.c
-+++ b/drivers/ssb/main.c
-@@ -1287,6 +1287,14 @@ static int __init ssb_modinit(void)
- {
- int err;
-
-+#ifdef CONFIG_SSB_FALLBACK_SPROM
-+ err = ssb_fbs_register();
-+ if (err) {
-+ pr_err("Fallback SPROM initialization failed\n");
-+ err = 0;
-+ }
-+#endif /* CONFIG_SSB_FALLBACK_SPROM */
-+
- /* See the comment at the ssb_is_early_boot definition */
- ssb_is_early_boot = 0;
- err = bus_register(&ssb_bustype);
---- a/drivers/ssb/sprom.c
-+++ b/drivers/ssb/sprom.c
-@@ -180,10 +180,20 @@ int ssb_arch_register_fallback_sprom(int
-
- int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
- {
-+ int err;
-+
-+ if (get_fallback_sprom)
-+ err = get_fallback_sprom(bus, out);
-+
-+#ifdef CONFIG_SSB_FALLBACK_SPROM
-+ if (!get_fallback_sprom || err)
-+ err = ssb_get_fallback_sprom(bus, out);
-+#else
- if (!get_fallback_sprom)
- return -ENOENT;
-+#endif /* CONFIG_SSB_FALLBACK_SPROM */
-
-- return get_fallback_sprom(bus, out);
-+ return err;
- }
-
- /* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
---- a/drivers/ssb/ssb_private.h
-+++ b/drivers/ssb/ssb_private.h
-@@ -143,6 +143,10 @@ extern int ssb_bus_scan(struct ssb_bus *
- extern void ssb_iounmap(struct ssb_bus *ssb);
-
-
-+/* fallback-sprom.c */
-+int __init ssb_fbs_register(void);
-+int ssb_get_fallback_sprom(struct ssb_bus *dev, struct ssb_sprom *out);
-+
- /* sprom.c */
- extern
- ssize_t ssb_attr_sprom_show(struct ssb_bus *bus, char *buf,
diff --git a/target/linux/generic/hack-5.15/901-debloat_sock_diag.patch b/target/linux/generic/hack-5.15/901-debloat_sock_diag.patch
deleted file mode 100644
index cf8ddea255..0000000000
--- a/target/linux/generic/hack-5.15/901-debloat_sock_diag.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 8 Jul 2017 08:16:31 +0200
-Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/Kconfig | 3 +++
- net/core/Makefile | 3 ++-
- net/core/sock.c | 2 ++
- net/ipv4/Kconfig | 1 +
- net/netlink/Kconfig | 1 +
- net/packet/Kconfig | 1 +
- net/unix/Kconfig | 1 +
- 7 files changed, 11 insertions(+), 1 deletion(-)
-
---- a/net/Kconfig
-+++ b/net/Kconfig
-@@ -104,6 +104,9 @@ source "net/mptcp/Kconfig"
-
- endif # if INET
-
-+config SOCK_DIAG
-+ bool
-+
- config NETWORK_SECMARK
- bool "Security Marking"
- help
---- a/net/core/Makefile
-+++ b/net/core/Makefile
-@@ -10,9 +10,10 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.
-
- obj-y += dev.o dev_addr_lists.o dst.o netevent.o \
- neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
-- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
-+ dev_ioctl.o tso.o sock_reuseport.o \
- fib_notifier.o xdp.o flow_offload.o
-
-+obj-$(CONFIG_SOCK_DIAG) += sock_diag.o
- obj-y += net-sysfs.o
- obj-$(CONFIG_PAGE_POOL) += page_pool.o
- obj-$(CONFIG_PROC_FS) += net-procfs.o
---- a/net/core/sock.c
-+++ b/net/core/sock.c
-@@ -114,6 +114,7 @@
- #include <linux/memcontrol.h>
- #include <linux/prefetch.h>
- #include <linux/compat.h>
-+#include <linux/cookie.h>
-
- #include <linux/uaccess.h>
-
-@@ -143,6 +144,7 @@
-
- static DEFINE_MUTEX(proto_list_mutex);
- static LIST_HEAD(proto_list);
-+DEFINE_COOKIE(sock_cookie);
-
- static void sock_inuse_add(struct net *net, int val);
-
-@@ -545,6 +547,18 @@ discard_and_relse:
- }
- EXPORT_SYMBOL(__sk_receive_skb);
-
-+u64 __sock_gen_cookie(struct sock *sk)
-+{
-+ while (1) {
-+ u64 res = atomic64_read(&sk->sk_cookie);
-+
-+ if (res)
-+ return res;
-+ res = gen_cookie_next(&sock_cookie);
-+ atomic64_cmpxchg(&sk->sk_cookie, 0, res);
-+ }
-+}
-+
- INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *,
- u32));
- INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *,
-@@ -2005,9 +2019,11 @@ static void __sk_free(struct sock *sk)
- if (likely(sk->sk_net_refcnt))
- sock_inuse_add(sock_net(sk), -1);
-
-+#ifdef CONFIG_SOCK_DIAG
- if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk)))
- sock_diag_broadcast_destroy(sk);
- else
-+#endif
- sk_destruct(sk);
- }
-
---- a/net/core/sock_diag.c
-+++ b/net/core/sock_diag.c
-@@ -11,7 +11,6 @@
- #include <linux/tcp.h>
- #include <linux/workqueue.h>
- #include <linux/nospec.h>
--#include <linux/cookie.h>
- #include <linux/inet_diag.h>
- #include <linux/sock_diag.h>
-
-@@ -20,20 +19,6 @@ static int (*inet_rcv_compat)(struct sk_
- static DEFINE_MUTEX(sock_diag_table_mutex);
- static struct workqueue_struct *broadcast_wq;
-
--DEFINE_COOKIE(sock_cookie);
--
--u64 __sock_gen_cookie(struct sock *sk)
--{
-- while (1) {
-- u64 res = atomic64_read(&sk->sk_cookie);
--
-- if (res)
-- return res;
-- res = gen_cookie_next(&sock_cookie);
-- atomic64_cmpxchg(&sk->sk_cookie, 0, res);
-- }
--}
--
- int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie)
- {
- u64 res;
---- a/net/ipv4/Kconfig
-+++ b/net/ipv4/Kconfig
-@@ -424,6 +424,7 @@ config INET_TUNNEL
-
- config INET_DIAG
- tristate "INET: socket monitoring interface"
-+ select SOCK_DIAG
- default y
- help
- Support for INET (TCP, DCCP, etc) socket monitoring interface used by
---- a/net/netlink/Kconfig
-+++ b/net/netlink/Kconfig
-@@ -5,6 +5,7 @@
-
- config NETLINK_DIAG
- tristate "NETLINK: socket monitoring interface"
-+ select SOCK_DIAG
- default n
- help
- Support for NETLINK socket monitoring interface used by the ss tool.
---- a/net/packet/Kconfig
-+++ b/net/packet/Kconfig
-@@ -19,6 +19,7 @@ config PACKET
- config PACKET_DIAG
- tristate "Packet: sockets monitoring interface"
- depends on PACKET
-+ select SOCK_DIAG
- default n
- help
- Support for PF_PACKET sockets monitoring interface used by the ss tool.
---- a/net/unix/Kconfig
-+++ b/net/unix/Kconfig
-@@ -33,6 +33,7 @@ config AF_UNIX_OOB
- config UNIX_DIAG
- tristate "UNIX: socket monitoring interface"
- depends on UNIX
-+ select SOCK_DIAG
- default n
- help
- Support for UNIX socket monitoring interface used by the ss tool.
---- a/net/xdp/Kconfig
-+++ b/net/xdp/Kconfig
-@@ -10,6 +10,7 @@ config XDP_SOCKETS
- config XDP_SOCKETS_DIAG
- tristate "XDP sockets: monitoring interface"
- depends on XDP_SOCKETS
-+ select SOCK_DIAG
- default n
- help
- Support for PF_XDP sockets monitoring interface used by the ss tool.
diff --git a/target/linux/generic/hack-5.15/902-debloat_proc.patch b/target/linux/generic/hack-5.15/902-debloat_proc.patch
deleted file mode 100644
index c7e40dfc6a..0000000000
--- a/target/linux/generic/hack-5.15/902-debloat_proc.patch
+++ /dev/null
@@ -1,408 +0,0 @@
-From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 8 Jul 2017 08:20:09 +0200
-Subject: debloat: procfs
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- fs/locks.c | 2 ++
- fs/proc/Kconfig | 5 +++++
- fs/proc/consoles.c | 3 +++
- fs/proc/proc_tty.c | 11 ++++++++++-
- include/net/snmp.h | 18 +++++++++++++++++-
- ipc/msg.c | 3 +++
- ipc/sem.c | 2 ++
- ipc/shm.c | 2 ++
- ipc/util.c | 3 +++
- kernel/exec_domain.c | 2 ++
- kernel/irq/proc.c | 9 +++++++++
- kernel/time/timer_list.c | 2 ++
- mm/vmalloc.c | 2 ++
- mm/vmstat.c | 8 +++++---
- net/8021q/vlanproc.c | 6 ++++++
- net/core/net-procfs.c | 18 ++++++++++++------
- net/core/sock.c | 2 ++
- net/ipv4/fib_trie.c | 18 ++++++++++++------
- net/ipv4/proc.c | 3 +++
- net/ipv4/route.c | 3 +++
- 20 files changed, 105 insertions(+), 17 deletions(-)
-
---- a/fs/locks.c
-+++ b/fs/locks.c
-@@ -3008,6 +3008,8 @@ static const struct seq_operations locks
-
- static int __init proc_locks_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- proc_create_seq_private("locks", 0, NULL, &locks_seq_operations,
- sizeof(struct locks_iterator), NULL);
- return 0;
---- a/fs/proc/Kconfig
-+++ b/fs/proc/Kconfig
-@@ -100,6 +100,11 @@ config PROC_CHILDREN
- Say Y if you are running any user-space software which takes benefit from
- this interface. For example, rkt is such a piece of software.
-
-+config PROC_STRIPPED
-+ default n
-+ depends on EXPERT
-+ bool "Strip non-essential /proc functionality to reduce code size"
-+
- config PROC_PID_ARCH_STATUS
- def_bool n
- depends on PROC_FS
---- a/fs/proc/consoles.c
-+++ b/fs/proc/consoles.c
-@@ -92,6 +92,9 @@ static const struct seq_operations conso
-
- static int __init proc_consoles_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- proc_create_seq("consoles", 0, NULL, &consoles_op);
- return 0;
- }
---- a/fs/proc/proc_tty.c
-+++ b/fs/proc/proc_tty.c
-@@ -133,7 +133,10 @@ static const struct seq_operations tty_d
- void proc_tty_register_driver(struct tty_driver *driver)
- {
- struct proc_dir_entry *ent;
--
-+
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- if (!driver->driver_name || driver->proc_entry ||
- !driver->ops->proc_show)
- return;
-@@ -150,6 +153,9 @@ void proc_tty_unregister_driver(struct t
- {
- struct proc_dir_entry *ent;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- ent = driver->proc_entry;
- if (!ent)
- return;
-@@ -164,6 +170,9 @@ void proc_tty_unregister_driver(struct t
- */
- void __init proc_tty_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- if (!proc_mkdir("tty", NULL))
- return;
- proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */
---- a/include/net/snmp.h
-+++ b/include/net/snmp.h
-@@ -124,6 +124,21 @@ struct linux_tls_mib {
- #define DECLARE_SNMP_STAT(type, name) \
- extern __typeof__(type) __percpu *name
-
-+#ifdef CONFIG_PROC_STRIPPED
-+#define __SNMP_STATS_DUMMY(mib) \
-+ do { (void) mib->mibs[0]; } while(0)
-+
-+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
-+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
-+
-+#else
-+
- #define __SNMP_INC_STATS(mib, field) \
- __this_cpu_inc(mib->mibs[field])
-
-@@ -154,8 +169,9 @@ struct linux_tls_mib {
- __this_cpu_add(ptr[basefield##OCTETS], addend); \
- } while (0)
-
-+#endif
-
--#if BITS_PER_LONG==32
-+#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED)
-
- #define __SNMP_ADD_STATS64(mib, field, addend) \
- do { \
---- a/ipc/msg.c
-+++ b/ipc/msg.c
-@@ -1350,6 +1350,9 @@ void __init msg_init(void)
- {
- msg_init_ns(&init_ipc_ns);
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- ipc_init_proc_interface("sysvipc/msg",
- " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
- IPC_MSG_IDS, sysvipc_msg_proc_show);
---- a/ipc/sem.c
-+++ b/ipc/sem.c
-@@ -268,6 +268,8 @@ void sem_exit_ns(struct ipc_namespace *n
- void __init sem_init(void)
- {
- sem_init_ns(&init_ipc_ns);
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
- ipc_init_proc_interface("sysvipc/sem",
- " key semid perms nsems uid gid cuid cgid otime ctime\n",
- IPC_SEM_IDS, sysvipc_sem_proc_show);
---- a/ipc/shm.c
-+++ b/ipc/shm.c
-@@ -154,6 +154,8 @@ pure_initcall(ipc_ns_init);
-
- void __init shm_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
- ipc_init_proc_interface("sysvipc/shm",
- #if BITS_PER_LONG <= 32
- " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
---- a/ipc/util.c
-+++ b/ipc/util.c
-@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons
- struct proc_dir_entry *pde;
- struct ipc_proc_iface *iface;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- iface = kmalloc(sizeof(*iface), GFP_KERNEL);
- if (!iface)
- return;
---- a/kernel/exec_domain.c
-+++ b/kernel/exec_domain.c
-@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct
-
- static int __init proc_execdomains_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- proc_create_single("execdomains", 0, NULL, execdomains_proc_show);
- return 0;
- }
---- a/kernel/irq/proc.c
-+++ b/kernel/irq/proc.c
-@@ -341,6 +341,9 @@ void register_irq_proc(unsigned int irq,
- void __maybe_unused *irqp = (void *)(unsigned long) irq;
- char name [MAX_NAMELEN];
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
-+ return;
-+
- if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
- return;
-
-@@ -394,6 +397,9 @@ void unregister_irq_proc(unsigned int ir
- {
- char name [MAX_NAMELEN];
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
-+ return;
-+
- if (!root_irq_dir || !desc->dir)
- return;
- #ifdef CONFIG_SMP
-@@ -432,6 +438,9 @@ void init_irq_proc(void)
- unsigned int irq;
- struct irq_desc *desc;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
-+ return;
-+
- /* create /proc/irq */
- root_irq_dir = proc_mkdir("irq", NULL);
- if (!root_irq_dir)
---- a/kernel/time/timer_list.c
-+++ b/kernel/time/timer_list.c
-@@ -350,6 +350,8 @@ static int __init init_timer_list_procfs
- {
- struct proc_dir_entry *pe;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops,
- sizeof(struct timer_list_iter), NULL);
- if (!pe)
---- a/mm/vmalloc.c
-+++ b/mm/vmalloc.c
-@@ -3986,6 +3986,8 @@ static const struct seq_operations vmall
-
- static int __init proc_vmalloc_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- if (IS_ENABLED(CONFIG_NUMA))
- proc_create_seq_private("vmallocinfo", 0400, NULL,
- &vmalloc_op,
---- a/mm/vmstat.c
-+++ b/mm/vmstat.c
-@@ -2083,10 +2083,12 @@ void __init init_mm_internals(void)
- start_shepherd_timer();
- #endif
- #ifdef CONFIG_PROC_FS
-- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
-- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
-+ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
-+ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
-+ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
-+ }
- proc_create_seq("vmstat", 0444, NULL, &vmstat_op);
-- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
- #endif
- }
-
---- a/net/8021q/vlanproc.c
-+++ b/net/8021q/vlanproc.c
-@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net)
- {
- struct vlan_net *vn = net_generic(net, vlan_net_id);
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- if (vn->proc_vlan_conf)
- remove_proc_entry(name_conf, vn->proc_vlan_dir);
-
-@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net
- {
- struct vlan_net *vn = net_generic(net, vlan_net_id);
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
- if (!vn->proc_vlan_dir)
- goto err;
---- a/net/core/net-procfs.c
-+++ b/net/core/net-procfs.c
-@@ -317,10 +317,12 @@ static int __net_init dev_proc_net_init(
- if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops,
- sizeof(struct seq_net_private)))
- goto out;
-- if (!proc_create_seq("softnet_stat", 0444, net->proc_net,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_seq("softnet_stat", 0444, net->proc_net,
- &softnet_seq_ops))
- goto out_dev;
-- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
- sizeof(struct seq_net_private)))
- goto out_softnet;
-
-@@ -330,9 +332,11 @@ static int __net_init dev_proc_net_init(
- out:
- return rc;
- out_ptype:
-- remove_proc_entry("ptype", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("ptype", net->proc_net);
- out_softnet:
-- remove_proc_entry("softnet_stat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("softnet_stat", net->proc_net);
- out_dev:
- remove_proc_entry("dev", net->proc_net);
- goto out;
-@@ -342,8 +346,10 @@ static void __net_exit dev_proc_net_exit
- {
- wext_proc_exit(net);
-
-- remove_proc_entry("ptype", net->proc_net);
-- remove_proc_entry("softnet_stat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
-+ remove_proc_entry("ptype", net->proc_net);
-+ remove_proc_entry("softnet_stat", net->proc_net);
-+ }
- remove_proc_entry("dev", net->proc_net);
- }
-
---- a/net/core/sock.c
-+++ b/net/core/sock.c
-@@ -3900,6 +3900,8 @@ static __net_initdata struct pernet_oper
-
- static int __init proto_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- return register_pernet_subsys(&proto_net_ops);
- }
-
---- a/net/ipv4/fib_trie.c
-+++ b/net/ipv4/fib_trie.c
-@@ -3029,11 +3029,13 @@ static const struct seq_operations fib_r
-
- int __net_init fib_proc_init(struct net *net)
- {
-- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
- sizeof(struct fib_trie_iter)))
- goto out1;
-
-- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_net_single("fib_triestat", 0444, net->proc_net,
- fib_triestat_seq_show, NULL))
- goto out2;
-
-@@ -3044,17 +3046,21 @@ int __net_init fib_proc_init(struct net
- return 0;
-
- out3:
-- remove_proc_entry("fib_triestat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("fib_triestat", net->proc_net);
- out2:
-- remove_proc_entry("fib_trie", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("fib_trie", net->proc_net);
- out1:
- return -ENOMEM;
- }
-
- void __net_exit fib_proc_exit(struct net *net)
- {
-- remove_proc_entry("fib_trie", net->proc_net);
-- remove_proc_entry("fib_triestat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
-+ remove_proc_entry("fib_trie", net->proc_net);
-+ remove_proc_entry("fib_triestat", net->proc_net);
-+ }
- remove_proc_entry("route", net->proc_net);
- }
-
---- a/net/ipv4/proc.c
-+++ b/net/ipv4/proc.c
-@@ -553,5 +553,8 @@ static __net_initdata struct pernet_oper
-
- int __init ip_misc_proc_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- return register_pernet_subsys(&ip_proc_ops);
- }
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -387,6 +387,9 @@ static struct pernet_operations ip_rt_pr
-
- static int __init ip_rt_proc_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- return register_pernet_subsys(&ip_rt_proc_ops);
- }
-
diff --git a/target/linux/generic/hack-5.15/904-debloat_dma_buf.patch b/target/linux/generic/hack-5.15/904-debloat_dma_buf.patch
deleted file mode 100644
index 71546bf942..0000000000
--- a/target/linux/generic/hack-5.15/904-debloat_dma_buf.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 8 Jul 2017 08:20:43 +0200
-Subject: debloat: dmabuf
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/base/Kconfig | 2 +-
- drivers/dma-buf/Makefile | 10 +++++++---
- drivers/dma-buf/dma-buf.c | 4 +++-
- kernel/sched/core.c | 1 +
- 4 files changed, 12 insertions(+), 5 deletions(-)
-
---- a/drivers/base/Kconfig
-+++ b/drivers/base/Kconfig
-@@ -187,7 +187,7 @@ config SOC_BUS
- source "drivers/base/regmap/Kconfig"
-
- config DMA_SHARED_BUFFER
-- bool
-+ tristate
- default n
- select IRQ_WORK
- help
---- a/drivers/dma-buf/heaps/Makefile
-+++ b/drivers/dma-buf/heaps/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
--obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
-+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
-+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
---- a/drivers/dma-buf/Makefile
-+++ b/drivers/dma-buf/Makefile
-@@ -1,16 +1,20 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
-+obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o
-+
-+dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
- dma-resv.o seqno-fence.o
--obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
--obj-$(CONFIG_DMABUF_HEAPS) += heaps/
--obj-$(CONFIG_SYNC_FILE) += sync_file.o
--obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
--obj-$(CONFIG_UDMABUF) += udmabuf.o
--obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o
-+dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
-+obj-$(CONFIG_DMABUF_HEAPS) += heaps/
-+dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o
-+dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
-+dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o
-+dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += udmabuf.o
-
- dmabuf_selftests-y := \
- selftest.o \
- st-dma-fence.o \
- st-dma-fence-chain.o
-
--obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
-+dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
-+
-+dma-shared-buffer-objs := $(dma-buf-objs-y)
---- a/drivers/dma-buf/dma-buf.c
-+++ b/drivers/dma-buf/dma-buf.c
-@@ -1513,4 +1513,5 @@ static void __exit dma_buf_deinit(void)
- kern_unmount(dma_buf_mnt);
- dma_buf_uninit_sysfs_statistics();
- }
--__exitcall(dma_buf_deinit);
-+module_exit(dma_buf_deinit);
-+MODULE_LICENSE("GPL");
---- a/kernel/sched/core.c
-+++ b/kernel/sched/core.c
-@@ -4220,6 +4220,7 @@ int wake_up_state(struct task_struct *p,
- {
- return try_to_wake_up(p, state, 0);
- }
-+EXPORT_SYMBOL_GPL(wake_up_state);
-
- /*
- * Perform scheduler related setup for a newly forked process p.
---- a/fs/d_path.c
-+++ b/fs/d_path.c
-@@ -316,6 +316,7 @@ char *dynamic_dname(struct dentry *dentr
- buffer += buflen - sz;
- return memcpy(buffer, temp, sz);
- }
-+EXPORT_SYMBOL_GPL(dynamic_dname);
-
- char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
- {
diff --git a/target/linux/generic/hack-5.15/910-kobject_uevent.patch b/target/linux/generic/hack-5.15/910-kobject_uevent.patch
deleted file mode 100644
index c4c41ca400..0000000000
--- a/target/linux/generic/hack-5.15/910-kobject_uevent.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/kobject.h | 5 +++++
- lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
- 2 files changed, 42 insertions(+)
-
---- a/lib/kobject_uevent.c
-+++ b/lib/kobject_uevent.c
-@@ -179,6 +179,18 @@ out:
- return r;
- }
-
-+u64 uevent_next_seqnum(void)
-+{
-+ u64 seq;
-+
-+ mutex_lock(&uevent_sock_mutex);
-+ seq = ++uevent_seqnum;
-+ mutex_unlock(&uevent_sock_mutex);
-+
-+ return seq;
-+}
-+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
-+
- /**
- * kobject_synth_uevent - send synthetic uevent with arguments
- *
diff --git a/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch
deleted file mode 100644
index a487d55193..0000000000
--- a/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/kobject.h | 5 +++++
- lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
- 2 files changed, 42 insertions(+)
-
---- a/include/linux/kobject.h
-+++ b/include/linux/kobject.h
-@@ -32,6 +32,8 @@
- #define UEVENT_NUM_ENVP 64 /* number of env pointers */
- #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
-
-+struct sk_buff;
-+
- #ifdef CONFIG_UEVENT_HELPER
- /* path to the userspace helper executed on an event */
- extern char uevent_helper[];
-@@ -244,4 +246,7 @@ int kobject_synth_uevent(struct kobject
- __printf(2, 3)
- int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
-
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+ gfp_t allocation);
-+
- #endif /* _KOBJECT_H_ */
---- a/lib/kobject_uevent.c
-+++ b/lib/kobject_uevent.c
-@@ -691,6 +691,43 @@ int add_uevent_var(struct kobj_uevent_en
- EXPORT_SYMBOL_GPL(add_uevent_var);
-
- #if defined(CONFIG_NET)
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+ gfp_t allocation)
-+{
-+ struct uevent_sock *ue_sk;
-+ int err = 0;
-+
-+ /* send netlink message */
-+ mutex_lock(&uevent_sock_mutex);
-+ list_for_each_entry(ue_sk, &uevent_sock_list, list) {
-+ struct sock *uevent_sock = ue_sk->sk;
-+ struct sk_buff *skb2;
-+
-+ skb2 = skb_clone(skb, allocation);
-+ if (!skb2)
-+ break;
-+
-+ err = netlink_broadcast(uevent_sock, skb2, pid, group,
-+ allocation);
-+ if (err)
-+ break;
-+ }
-+ mutex_unlock(&uevent_sock_mutex);
-+
-+ kfree_skb(skb);
-+ return err;
-+}
-+#else
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+ gfp_t allocation)
-+{
-+ kfree_skb(skb);
-+ return 0;
-+}
-+#endif
-+EXPORT_SYMBOL_GPL(broadcast_uevent);
-+
-+#if defined(CONFIG_NET)
- static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb,
- struct netlink_ext_ack *extack)
- {
diff --git a/target/linux/generic/hack-5.15/920-device_tree_cmdline.patch b/target/linux/generic/hack-5.15/920-device_tree_cmdline.patch
deleted file mode 100644
index d1f36e716e..0000000000
--- a/target/linux/generic/hack-5.15/920-device_tree_cmdline.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From e08bcbbaa52fcc41f02743fd2e62a33255ce52da Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:52:28 +0200
-Subject: [PATCH] of/ftd: add device tree cmdline
-
----
- drivers/of/fdt.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -1158,6 +1158,9 @@ int __init early_init_dt_scan_chosen(uns
- p = of_get_flat_dt_prop(node, "bootargs", &l);
- if (p != NULL && l > 0)
- strlcpy(data, p, min(l, COMMAND_LINE_SIZE));
-+ p = of_get_flat_dt_prop(node, "bootargs-append", &l);
-+ if (p != NULL && l > 0)
-+ strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE));
-
- /*
- * CONFIG_CMDLINE is meant to be a default in case nothing else
diff --git a/target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
deleted file mode 100644
index b4339e82d7..0000000000
--- a/target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 19 Jul 2022 06:17:48 +0200
-Subject: [PATCH] Revert "Revert "Revert "driver core: Set fw_devlink=on by
- default"""
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit ea718c699055c8566eb64432388a04974c43b2ea.
-
-With of_platform_populate() called for MTD partitions that commit breaks
-probing devices which reference MTD in device tree.
-
-Link: https://lore.kernel.org/all/696cb2da-20b9-b3dd-46d9-de4bf91a1506@gmail.com/T/#u
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/base/core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/base/core.c
-+++ b/drivers/base/core.c
-@@ -1577,7 +1577,7 @@ static void device_links_purge(struct de
- #define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
- DL_FLAG_PM_RUNTIME)
-
--static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON;
-+static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE;
- static int __init fw_devlink_setup(char *arg)
- {
- if (!arg)
diff --git a/target/linux/generic/hack-6.1/204-module_strip.patch b/target/linux/generic/hack-6.1/204-module_strip.patch
deleted file mode 100644
index 9fefd0bd6e..0000000000
--- a/target/linux/generic/hack-6.1/204-module_strip.patch
+++ /dev/null
@@ -1,210 +0,0 @@
-From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 16:56:48 +0200
-Subject: build: add a hack for removing non-essential module info
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/module.h | 13 ++++++++-----
- include/linux/moduleparam.h | 15 ++++++++++++---
- init/Kconfig | 7 +++++++
- kernel/module.c | 5 ++++-
- scripts/mod/modpost.c | 12 ++++++++++++
- 5 files changed, 43 insertions(+), 9 deletions(-)
-
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -163,6 +163,7 @@ extern void cleanup_module(void);
-
- /* Generic info of form tag = "info" */
- #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
-+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info)
-
- /* For userspace: you can also call me... */
- #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
-@@ -232,12 +233,12 @@ extern void cleanup_module(void);
- * Author(s), use "Name <email>" or just "Name", for multiple
- * authors use multiple MODULE_AUTHOR() statements/lines.
- */
--#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
-+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author)
-
- /* What your module does. */
--#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
-+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description)
-
--#ifdef MODULE
-+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED)
- /* Creates an alias so file2alias.c can find device table. */
- #define MODULE_DEVICE_TABLE(type, name) \
- extern typeof(name) __mod_##type##__##name##_device_table \
-@@ -264,7 +265,9 @@ extern typeof(name) __mod_##type##__##na
- */
-
- #if defined(MODULE) || !defined(CONFIG_SYSFS)
--#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version)
-+#elif defined(CONFIG_MODULE_STRIPPED)
-+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version)
- #else
- #define MODULE_VERSION(_version) \
- MODULE_INFO(version, _version); \
-@@ -287,7 +290,7 @@ extern typeof(name) __mod_##type##__##na
- /* Optional firmware file (or files) needed by the module
- * format is simply firmware file name. Multiple firmware
- * files require multiple MODULE_FIRMWARE() specifiers */
--#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
-+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware)
-
- #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, __stringify(ns))
-
---- a/include/linux/moduleparam.h
-+++ b/include/linux/moduleparam.h
-@@ -20,6 +20,16 @@
- /* Chosen so that structs with an unsigned long line up. */
- #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
-
-+/* This struct is here for syntactic coherency, it is not used */
-+#define __MODULE_INFO_DISABLED(name) \
-+ struct __UNIQUE_ID(name) {}
-+
-+#ifdef CONFIG_MODULE_STRIPPED
-+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name)
-+#else
-+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info)
-+#endif
-+
- #define __MODULE_INFO(tag, name, info) \
- static const char __UNIQUE_ID(name)[] \
- __used __section(".modinfo") __aligned(1) \
-@@ -31,7 +41,7 @@
- /* One for each parameter, describing how to use it. Some files do
- multiple of these per line, so can't just use MODULE_INFO. */
- #define MODULE_PARM_DESC(_parm, desc) \
-- __MODULE_INFO(parm, _parm, #_parm ":" desc)
-+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc)
-
- struct kernel_param;
-
---- a/kernel/module/Kconfig
-+++ b/kernel/module/Kconfig
-@@ -290,4 +290,11 @@ config MODULES_TREE_LOOKUP
- def_bool y
- depends on PERF_EVENTS || TRACING || CFI_CLANG
-
-+config MODULE_STRIPPED
-+ bool "Reduce module size"
-+ depends on MODULES
-+ help
-+ Remove module parameter descriptions, author info, version, aliases,
-+ device tables, etc.
-+
- endif # MODULES
---- a/kernel/module/main.c
-+++ b/kernel/module/main.c
-@@ -988,6 +988,7 @@ size_t modinfo_attrs_count = ARRAY_SIZE(
-
- static const char vermagic[] = VERMAGIC_STRING;
-
-+#if defined(CONFIG_MODVERSIONS) || !defined(CONFIG_MODULE_STRIPPED)
- int try_to_force_load(struct module *mod, const char *reason)
- {
- #ifdef CONFIG_MODULE_FORCE_LOAD
-@@ -999,6 +1000,7 @@ int try_to_force_load(struct module *mod
- return -ENOEXEC;
- #endif
- }
-+#endif
-
- static char *get_modinfo(const struct load_info *info, const char *tag);
- static char *get_next_modinfo(const struct load_info *info, const char *tag,
-@@ -1958,9 +1960,11 @@ static int setup_load_info(struct load_i
-
- static int check_modinfo(struct module *mod, struct load_info *info, int flags)
- {
-- const char *modmagic = get_modinfo(info, "vermagic");
- int err;
-
-+#ifndef CONFIG_MODULE_STRIPPED
-+ const char *modmagic = get_modinfo(info, "vermagic");
-+
- if (flags & MODULE_INIT_IGNORE_VERMAGIC)
- modmagic = NULL;
-
-@@ -1981,6 +1985,7 @@ static int check_modinfo(struct module *
- mod->name);
- add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
- }
-+#endif
-
- check_modinfo_retpoline(mod, info);
-
---- a/scripts/mod/modpost.c
-+++ b/scripts/mod/modpost.c
-@@ -1785,7 +1785,9 @@ static void read_symbols(const char *mod
- symname = remove_dot(info.strtab + sym->st_name);
-
- handle_symbol(mod, &info, sym, symname);
-+#ifndef CONFIG_MODULE_STRIPPED
- handle_moddevtable(mod, &info, sym, symname);
-+#endif
- }
-
- for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
-@@ -1948,8 +1950,10 @@ static void add_header(struct buffer *b,
- buf_printf(b, "BUILD_SALT;\n");
- buf_printf(b, "BUILD_LTO_INFO;\n");
- buf_printf(b, "\n");
-+#ifndef CONFIG_MODULE_STRIPPED
- buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
- buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
-+#endif
- buf_printf(b, "\n");
- buf_printf(b, "__visible struct module __this_module\n");
- buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
-@@ -1963,8 +1967,10 @@ static void add_header(struct buffer *b,
- buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
- buf_printf(b, "};\n");
-
-+#ifndef CONFIG_MODULE_STRIPPED
- if (!external_module)
- buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
-+#endif
-
- buf_printf(b,
- "\n"
-@@ -1972,8 +1978,10 @@ static void add_header(struct buffer *b,
- "MODULE_INFO(retpoline, \"Y\");\n"
- "#endif\n");
-
-+#ifndef CONFIG_MODULE_STRIPPED
- if (strstarts(mod->name, "drivers/staging"))
- buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
-+#endif
-
- if (strstarts(mod->name, "tools/testing"))
- buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n");
-@@ -2069,11 +2077,13 @@ static void add_depends(struct buffer *b
-
- static void add_srcversion(struct buffer *b, struct module *mod)
- {
-+#ifndef CONFIG_MODULE_STRIPPED
- if (mod->srcversion[0]) {
- buf_printf(b, "\n");
- buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
- mod->srcversion);
- }
-+#endif
- }
-
- static void write_buf(struct buffer *b, const char *fname)
-@@ -2159,7 +2169,9 @@ static void write_mod_c_file(struct modu
- add_exported_symbols(&buf, mod);
- add_versions(&buf, mod);
- add_depends(&buf, mod);
-+#ifndef CONFIG_MODULE_STRIPPED
- add_moddevtable(&buf, mod);
-+#endif
- add_srcversion(&buf, mod);
-
- ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);
diff --git a/target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch b/target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch
deleted file mode 100644
index df18507041..0000000000
--- a/target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 310e8e04a05d9eb43fa9dd7f00143300afcaa37a Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Fri, 11 Nov 2022 13:33:44 +0100
-Subject: [PATCH] kconfig: abort configuration on unset symbol
-
-When a target configuration has unset Kconfig symbols, the build will
-fail when OpenWrt is compiled with V=s and stdin is connected to a tty.
-
-In case OpenWrt is compiled without either of these preconditions, the
-build will succeed with the symbols in question being unset.
-
-Modify the kernel configuration in a way it fails on unset symbols
-regardless of the aforementioned preconditions.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- scripts/kconfig/conf.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/scripts/kconfig/conf.c
-+++ b/scripts/kconfig/conf.c
-@@ -338,6 +338,9 @@ static int conf_askvalue(struct symbol *
- }
- /* fall through */
- default:
-+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) {
-+ exit(1);
-+ }
- fflush(stdout);
- xfgets(line, sizeof(line), stdin);
- break;
-@@ -520,6 +523,9 @@ static int conf_choice(struct menu *menu
- }
- /* fall through */
- case oldaskconfig:
-+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) {
-+ exit(1);
-+ }
- fflush(stdout);
- xfgets(line, sizeof(line), stdin);
- strip(line);
diff --git a/target/linux/generic/hack-6.1/210-darwin_scripts_include.patch b/target/linux/generic/hack-6.1/210-darwin_scripts_include.patch
deleted file mode 100644
index c9612536de..0000000000
--- a/target/linux/generic/hack-6.1/210-darwin_scripts_include.patch
+++ /dev/null
@@ -1,3053 +0,0 @@
-From db7c30dcd9a0391bf13b62c9f91e144d762ef43a Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Fri, 7 Jul 2017 17:00:49 +0200
-Subject: Add an OSX specific patch to make the kernel be compiled
-
-lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- scripts/kconfig/Makefile | 3 +
- scripts/mod/elf.h | 3007 ++++++++++++++++++++++++++++++++++++++++++++
- scripts/mod/mk_elfconfig.c | 4 +
- scripts/mod/modpost.h | 4 +
- 4 files changed, 3018 insertions(+)
- create mode 100644 scripts/mod/elf.h
-
---- /dev/null
-+++ b/scripts/mod/elf.h
-@@ -0,0 +1,3007 @@
-+/* This file defines standard ELF types, structures, and macros.
-+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#ifndef _ELF_H
-+#define _ELF_H 1
-+
-+/* Standard ELF types. */
-+
-+#include <stdint.h>
-+
-+/* Type for a 16-bit quantity. */
-+typedef uint16_t Elf32_Half;
-+typedef uint16_t Elf64_Half;
-+
-+/* Types for signed and unsigned 32-bit quantities. */
-+typedef uint32_t Elf32_Word;
-+typedef int32_t Elf32_Sword;
-+typedef uint32_t Elf64_Word;
-+typedef int32_t Elf64_Sword;
-+
-+/* Types for signed and unsigned 64-bit quantities. */
-+typedef uint64_t Elf32_Xword;
-+typedef int64_t Elf32_Sxword;
-+typedef uint64_t Elf64_Xword;
-+typedef int64_t Elf64_Sxword;
-+
-+/* Type of addresses. */
-+typedef uint32_t Elf32_Addr;
-+typedef uint64_t Elf64_Addr;
-+
-+/* Type of file offsets. */
-+typedef uint32_t Elf32_Off;
-+typedef uint64_t Elf64_Off;
-+
-+/* Type for section indices, which are 16-bit quantities. */
-+typedef uint16_t Elf32_Section;
-+typedef uint16_t Elf64_Section;
-+
-+/* Type for version symbol information. */
-+typedef Elf32_Half Elf32_Versym;
-+typedef Elf64_Half Elf64_Versym;
-+
-+
-+/* The ELF file header. This appears at the start of every ELF file. */
-+
-+#define EI_NIDENT (16)
-+
-+typedef struct
-+{
-+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
-+ Elf32_Half e_type; /* Object file type */
-+ Elf32_Half e_machine; /* Architecture */
-+ Elf32_Word e_version; /* Object file version */
-+ Elf32_Addr e_entry; /* Entry point virtual address */
-+ Elf32_Off e_phoff; /* Program header table file offset */
-+ Elf32_Off e_shoff; /* Section header table file offset */
-+ Elf32_Word e_flags; /* Processor-specific flags */
-+ Elf32_Half e_ehsize; /* ELF header size in bytes */
-+ Elf32_Half e_phentsize; /* Program header table entry size */
-+ Elf32_Half e_phnum; /* Program header table entry count */
-+ Elf32_Half e_shentsize; /* Section header table entry size */
-+ Elf32_Half e_shnum; /* Section header table entry count */
-+ Elf32_Half e_shstrndx; /* Section header string table index */
-+} Elf32_Ehdr;
-+
-+typedef struct
-+{
-+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
-+ Elf64_Half e_type; /* Object file type */
-+ Elf64_Half e_machine; /* Architecture */
-+ Elf64_Word e_version; /* Object file version */
-+ Elf64_Addr e_entry; /* Entry point virtual address */
-+ Elf64_Off e_phoff; /* Program header table file offset */
-+ Elf64_Off e_shoff; /* Section header table file offset */
-+ Elf64_Word e_flags; /* Processor-specific flags */
-+ Elf64_Half e_ehsize; /* ELF header size in bytes */
-+ Elf64_Half e_phentsize; /* Program header table entry size */
-+ Elf64_Half e_phnum; /* Program header table entry count */
-+ Elf64_Half e_shentsize; /* Section header table entry size */
-+ Elf64_Half e_shnum; /* Section header table entry count */
-+ Elf64_Half e_shstrndx; /* Section header string table index */
-+} Elf64_Ehdr;
-+
-+/* Fields in the e_ident array. The EI_* macros are indices into the
-+ array. The macros under each EI_* macro are the values the byte
-+ may have. */
-+
-+#define EI_MAG0 0 /* File identification byte 0 index */
-+#define ELFMAG0 0x7f /* Magic number byte 0 */
-+
-+#define EI_MAG1 1 /* File identification byte 1 index */
-+#define ELFMAG1 'E' /* Magic number byte 1 */
-+
-+#define EI_MAG2 2 /* File identification byte 2 index */
-+#define ELFMAG2 'L' /* Magic number byte 2 */
-+
-+#define EI_MAG3 3 /* File identification byte 3 index */
-+#define ELFMAG3 'F' /* Magic number byte 3 */
-+
-+/* Conglomeration of the identification bytes, for easy testing as a word. */
-+#define ELFMAG "\177ELF"
-+#define SELFMAG 4
-+
-+#define EI_CLASS 4 /* File class byte index */
-+#define ELFCLASSNONE 0 /* Invalid class */
-+#define ELFCLASS32 1 /* 32-bit objects */
-+#define ELFCLASS64 2 /* 64-bit objects */
-+#define ELFCLASSNUM 3
-+
-+#define EI_DATA 5 /* Data encoding byte index */
-+#define ELFDATANONE 0 /* Invalid data encoding */
-+#define ELFDATA2LSB 1 /* 2's complement, little endian */
-+#define ELFDATA2MSB 2 /* 2's complement, big endian */
-+#define ELFDATANUM 3
-+
-+#define EI_VERSION 6 /* File version byte index */
-+ /* Value must be EV_CURRENT */
-+
-+#define EI_OSABI 7 /* OS ABI identification */
-+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
-+#define ELFOSABI_SYSV 0 /* Alias. */
-+#define ELFOSABI_HPUX 1 /* HP-UX */
-+#define ELFOSABI_NETBSD 2 /* NetBSD. */
-+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
-+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
-+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
-+#define ELFOSABI_AIX 7 /* IBM AIX. */
-+#define ELFOSABI_IRIX 8 /* SGI Irix. */
-+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
-+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
-+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
-+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
-+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
-+#define ELFOSABI_ARM 97 /* ARM */
-+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
-+
-+#define EI_ABIVERSION 8 /* ABI version */
-+
-+#define EI_PAD 9 /* Byte index of padding bytes */
-+
-+/* Legal values for e_type (object file type). */
-+
-+#define ET_NONE 0 /* No file type */
-+#define ET_REL 1 /* Relocatable file */
-+#define ET_EXEC 2 /* Executable file */
-+#define ET_DYN 3 /* Shared object file */
-+#define ET_CORE 4 /* Core file */
-+#define ET_NUM 5 /* Number of defined types */
-+#define ET_LOOS 0xfe00 /* OS-specific range start */
-+#define ET_HIOS 0xfeff /* OS-specific range end */
-+#define ET_LOPROC 0xff00 /* Processor-specific range start */
-+#define ET_HIPROC 0xffff /* Processor-specific range end */
-+
-+/* Legal values for e_machine (architecture). */
-+
-+#define EM_NONE 0 /* No machine */
-+#define EM_M32 1 /* AT&T WE 32100 */
-+#define EM_SPARC 2 /* SUN SPARC */
-+#define EM_386 3 /* Intel 80386 */
-+#define EM_68K 4 /* Motorola m68k family */
-+#define EM_88K 5 /* Motorola m88k family */
-+#define EM_860 7 /* Intel 80860 */
-+#define EM_MIPS 8 /* MIPS R3000 big-endian */
-+#define EM_S370 9 /* IBM System/370 */
-+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
-+
-+#define EM_PARISC 15 /* HPPA */
-+#define EM_VPP500 17 /* Fujitsu VPP500 */
-+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
-+#define EM_960 19 /* Intel 80960 */
-+#define EM_PPC 20 /* PowerPC */
-+#define EM_PPC64 21 /* PowerPC 64-bit */
-+#define EM_S390 22 /* IBM S390 */
-+
-+#define EM_V800 36 /* NEC V800 series */
-+#define EM_FR20 37 /* Fujitsu FR20 */
-+#define EM_RH32 38 /* TRW RH-32 */
-+#define EM_RCE 39 /* Motorola RCE */
-+#define EM_ARM 40 /* ARM */
-+#define EM_FAKE_ALPHA 41 /* Digital Alpha */
-+#define EM_SH 42 /* Hitachi SH */
-+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-+#define EM_TRICORE 44 /* Siemens Tricore */
-+#define EM_ARC 45 /* Argonaut RISC Core */
-+#define EM_H8_300 46 /* Hitachi H8/300 */
-+#define EM_H8_300H 47 /* Hitachi H8/300H */
-+#define EM_H8S 48 /* Hitachi H8S */
-+#define EM_H8_500 49 /* Hitachi H8/500 */
-+#define EM_IA_64 50 /* Intel Merced */
-+#define EM_MIPS_X 51 /* Stanford MIPS-X */
-+#define EM_COLDFIRE 52 /* Motorola Coldfire */
-+#define EM_68HC12 53 /* Motorola M68HC12 */
-+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
-+#define EM_PCP 55 /* Siemens PCP */
-+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
-+#define EM_NDR1 57 /* Denso NDR1 microprocessor */
-+#define EM_STARCORE 58 /* Motorola Start*Core processor */
-+#define EM_ME16 59 /* Toyota ME16 processor */
-+#define EM_ST100 60 /* STMicroelectronic ST100 processor */
-+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
-+#define EM_X86_64 62 /* AMD x86-64 architecture */
-+#define EM_PDSP 63 /* Sony DSP Processor */
-+
-+#define EM_FX66 66 /* Siemens FX66 microcontroller */
-+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
-+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
-+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
-+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
-+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
-+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
-+#define EM_SVX 73 /* Silicon Graphics SVx */
-+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
-+#define EM_VAX 75 /* Digital VAX */
-+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
-+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
-+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
-+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
-+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
-+#define EM_HUANY 81 /* Harvard University machine-independent object files */
-+#define EM_PRISM 82 /* SiTera Prism */
-+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
-+#define EM_FR30 84 /* Fujitsu FR30 */
-+#define EM_D10V 85 /* Mitsubishi D10V */
-+#define EM_D30V 86 /* Mitsubishi D30V */
-+#define EM_V850 87 /* NEC v850 */
-+#define EM_M32R 88 /* Mitsubishi M32R */
-+#define EM_MN10300 89 /* Matsushita MN10300 */
-+#define EM_MN10200 90 /* Matsushita MN10200 */
-+#define EM_PJ 91 /* picoJava */
-+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
-+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
-+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
-+#define EM_TILEPRO 188 /* Tilera TILEPro */
-+#define EM_TILEGX 191 /* Tilera TILE-Gx */
-+#define EM_NUM 192
-+
-+/* If it is necessary to assign new unofficial EM_* values, please
-+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
-+ chances of collision with official or non-GNU unofficial values. */
-+
-+#define EM_ALPHA 0x9026
-+
-+/* Legal values for e_version (version). */
-+
-+#define EV_NONE 0 /* Invalid ELF version */
-+#define EV_CURRENT 1 /* Current version */
-+#define EV_NUM 2
-+
-+/* Section header. */
-+
-+typedef struct
-+{
-+ Elf32_Word sh_name; /* Section name (string tbl index) */
-+ Elf32_Word sh_type; /* Section type */
-+ Elf32_Word sh_flags; /* Section flags */
-+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
-+ Elf32_Off sh_offset; /* Section file offset */
-+ Elf32_Word sh_size; /* Section size in bytes */
-+ Elf32_Word sh_link; /* Link to another section */
-+ Elf32_Word sh_info; /* Additional section information */
-+ Elf32_Word sh_addralign; /* Section alignment */
-+ Elf32_Word sh_entsize; /* Entry size if section holds table */
-+} Elf32_Shdr;
-+
-+typedef struct
-+{
-+ Elf64_Word sh_name; /* Section name (string tbl index) */
-+ Elf64_Word sh_type; /* Section type */
-+ Elf64_Xword sh_flags; /* Section flags */
-+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
-+ Elf64_Off sh_offset; /* Section file offset */
-+ Elf64_Xword sh_size; /* Section size in bytes */
-+ Elf64_Word sh_link; /* Link to another section */
-+ Elf64_Word sh_info; /* Additional section information */
-+ Elf64_Xword sh_addralign; /* Section alignment */
-+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
-+} Elf64_Shdr;
-+
-+/* Special section indices. */
-+
-+#define SHN_UNDEF 0 /* Undefined section */
-+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
-+#define SHN_LOPROC 0xff00 /* Start of processor-specific */
-+#define SHN_BEFORE 0xff00 /* Order section before all others
-+ (Solaris). */
-+#define SHN_AFTER 0xff01 /* Order section after all others
-+ (Solaris). */
-+#define SHN_HIPROC 0xff1f /* End of processor-specific */
-+#define SHN_LOOS 0xff20 /* Start of OS-specific */
-+#define SHN_HIOS 0xff3f /* End of OS-specific */
-+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
-+#define SHN_COMMON 0xfff2 /* Associated symbol is common */
-+#define SHN_XINDEX 0xffff /* Index is in extra table. */
-+#define SHN_HIRESERVE 0xffff /* End of reserved indices */
-+
-+/* Legal values for sh_type (section type). */
-+
-+#define SHT_NULL 0 /* Section header table entry unused */
-+#define SHT_PROGBITS 1 /* Program data */
-+#define SHT_SYMTAB 2 /* Symbol table */
-+#define SHT_STRTAB 3 /* String table */
-+#define SHT_RELA 4 /* Relocation entries with addends */
-+#define SHT_HASH 5 /* Symbol hash table */
-+#define SHT_DYNAMIC 6 /* Dynamic linking information */
-+#define SHT_NOTE 7 /* Notes */
-+#define SHT_NOBITS 8 /* Program space with no data (bss) */
-+#define SHT_REL 9 /* Relocation entries, no addends */
-+#define SHT_SHLIB 10 /* Reserved */
-+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
-+#define SHT_INIT_ARRAY 14 /* Array of constructors */
-+#define SHT_FINI_ARRAY 15 /* Array of destructors */
-+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
-+#define SHT_GROUP 17 /* Section group */
-+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
-+#define SHT_NUM 19 /* Number of defined types. */
-+#define SHT_LOOS 0x60000000 /* Start OS-specific. */
-+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
-+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
-+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
-+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
-+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
-+#define SHT_SUNW_move 0x6ffffffa
-+#define SHT_SUNW_COMDAT 0x6ffffffb
-+#define SHT_SUNW_syminfo 0x6ffffffc
-+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
-+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
-+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
-+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
-+#define SHT_HIOS 0x6fffffff /* End OS-specific type */
-+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
-+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
-+#define SHT_LOUSER 0x80000000 /* Start of application-specific */
-+#define SHT_HIUSER 0x8fffffff /* End of application-specific */
-+
-+/* Legal values for sh_flags (section flags). */
-+
-+#define SHF_WRITE (1 << 0) /* Writable */
-+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
-+#define SHF_EXECINSTR (1 << 2) /* Executable */
-+#define SHF_MERGE (1 << 4) /* Might be merged */
-+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
-+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
-+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
-+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
-+ required */
-+#define SHF_GROUP (1 << 9) /* Section is member of a group. */
-+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
-+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
-+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
-+#define SHF_ORDERED (1 << 30) /* Special ordering requirement
-+ (Solaris). */
-+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
-+ referenced or allocated (Solaris).*/
-+
-+/* Section group handling. */
-+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
-+
-+/* Symbol table entry. */
-+
-+typedef struct
-+{
-+ Elf32_Word st_name; /* Symbol name (string tbl index) */
-+ Elf32_Addr st_value; /* Symbol value */
-+ Elf32_Word st_size; /* Symbol size */
-+ unsigned char st_info; /* Symbol type and binding */
-+ unsigned char st_other; /* Symbol visibility */
-+ Elf32_Section st_shndx; /* Section index */
-+} Elf32_Sym;
-+
-+typedef struct
-+{
-+ Elf64_Word st_name; /* Symbol name (string tbl index) */
-+ unsigned char st_info; /* Symbol type and binding */
-+ unsigned char st_other; /* Symbol visibility */
-+ Elf64_Section st_shndx; /* Section index */
-+ Elf64_Addr st_value; /* Symbol value */
-+ Elf64_Xword st_size; /* Symbol size */
-+} Elf64_Sym;
-+
-+/* The syminfo section if available contains additional information about
-+ every dynamic symbol. */
-+
-+typedef struct
-+{
-+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */
-+ Elf32_Half si_flags; /* Per symbol flags */
-+} Elf32_Syminfo;
-+
-+typedef struct
-+{
-+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */
-+ Elf64_Half si_flags; /* Per symbol flags */
-+} Elf64_Syminfo;
-+
-+/* Possible values for si_boundto. */
-+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
-+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */
-+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */
-+
-+/* Possible bitmasks for si_flags. */
-+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */
-+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */
-+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */
-+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy
-+ loaded */
-+/* Syminfo version values. */
-+#define SYMINFO_NONE 0
-+#define SYMINFO_CURRENT 1
-+#define SYMINFO_NUM 2
-+
-+
-+/* How to extract and insert information held in the st_info field. */
-+
-+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
-+#define ELF32_ST_TYPE(val) ((val) & 0xf)
-+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
-+
-+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
-+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
-+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
-+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
-+
-+/* Legal values for ST_BIND subfield of st_info (symbol binding). */
-+
-+#define STB_LOCAL 0 /* Local symbol */
-+#define STB_GLOBAL 1 /* Global symbol */
-+#define STB_WEAK 2 /* Weak symbol */
-+#define STB_NUM 3 /* Number of defined types. */
-+#define STB_LOOS 10 /* Start of OS-specific */
-+#define STB_GNU_UNIQUE 10 /* Unique symbol. */
-+#define STB_HIOS 12 /* End of OS-specific */
-+#define STB_LOPROC 13 /* Start of processor-specific */
-+#define STB_HIPROC 15 /* End of processor-specific */
-+
-+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-+
-+#define STT_NOTYPE 0 /* Symbol type is unspecified */
-+#define STT_OBJECT 1 /* Symbol is a data object */
-+#define STT_FUNC 2 /* Symbol is a code object */
-+#define STT_SECTION 3 /* Symbol associated with a section */
-+#define STT_FILE 4 /* Symbol's name is file name */
-+#define STT_COMMON 5 /* Symbol is a common data object */
-+#define STT_TLS 6 /* Symbol is thread-local data object*/
-+#define STT_NUM 7 /* Number of defined types. */
-+#define STT_LOOS 10 /* Start of OS-specific */
-+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
-+#define STT_HIOS 12 /* End of OS-specific */
-+#define STT_LOPROC 13 /* Start of processor-specific */
-+#define STT_HIPROC 15 /* End of processor-specific */
-+
-+
-+/* Symbol table indices are found in the hash buckets and chain table
-+ of a symbol hash table section. This special index value indicates
-+ the end of a chain, meaning no further symbols are found in that bucket. */
-+
-+#define STN_UNDEF 0 /* End of a chain. */
-+
-+
-+/* How to extract and insert information held in the st_other field. */
-+
-+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
-+
-+/* For ELF64 the definitions are the same. */
-+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
-+
-+/* Symbol visibility specification encoded in the st_other field. */
-+#define STV_DEFAULT 0 /* Default symbol visibility rules */
-+#define STV_INTERNAL 1 /* Processor specific hidden class */
-+#define STV_HIDDEN 2 /* Sym unavailable in other modules */
-+#define STV_PROTECTED 3 /* Not preemptible, not exported */
-+
-+
-+/* Relocation table entry without addend (in section of type SHT_REL). */
-+
-+typedef struct
-+{
-+ Elf32_Addr r_offset; /* Address */
-+ Elf32_Word r_info; /* Relocation type and symbol index */
-+} Elf32_Rel;
-+
-+/* I have seen two different definitions of the Elf64_Rel and
-+ Elf64_Rela structures, so we'll leave them out until Novell (or
-+ whoever) gets their act together. */
-+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */
-+
-+typedef struct
-+{
-+ Elf64_Addr r_offset; /* Address */
-+ Elf64_Xword r_info; /* Relocation type and symbol index */
-+} Elf64_Rel;
-+
-+/* Relocation table entry with addend (in section of type SHT_RELA). */
-+
-+typedef struct
-+{
-+ Elf32_Addr r_offset; /* Address */
-+ Elf32_Word r_info; /* Relocation type and symbol index */
-+ Elf32_Sword r_addend; /* Addend */
-+} Elf32_Rela;
-+
-+typedef struct
-+{
-+ Elf64_Addr r_offset; /* Address */
-+ Elf64_Xword r_info; /* Relocation type and symbol index */
-+ Elf64_Sxword r_addend; /* Addend */
-+} Elf64_Rela;
-+
-+/* How to extract and insert information held in the r_info field. */
-+
-+#define ELF32_R_SYM(val) ((val) >> 8)
-+#define ELF32_R_TYPE(val) ((val) & 0xff)
-+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
-+
-+#define ELF64_R_SYM(i) ((i) >> 32)
-+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
-+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
-+
-+/* Program segment header. */
-+
-+typedef struct
-+{
-+ Elf32_Word p_type; /* Segment type */
-+ Elf32_Off p_offset; /* Segment file offset */
-+ Elf32_Addr p_vaddr; /* Segment virtual address */
-+ Elf32_Addr p_paddr; /* Segment physical address */
-+ Elf32_Word p_filesz; /* Segment size in file */
-+ Elf32_Word p_memsz; /* Segment size in memory */
-+ Elf32_Word p_flags; /* Segment flags */
-+ Elf32_Word p_align; /* Segment alignment */
-+} Elf32_Phdr;
-+
-+typedef struct
-+{
-+ Elf64_Word p_type; /* Segment type */
-+ Elf64_Word p_flags; /* Segment flags */
-+ Elf64_Off p_offset; /* Segment file offset */
-+ Elf64_Addr p_vaddr; /* Segment virtual address */
-+ Elf64_Addr p_paddr; /* Segment physical address */
-+ Elf64_Xword p_filesz; /* Segment size in file */
-+ Elf64_Xword p_memsz; /* Segment size in memory */
-+ Elf64_Xword p_align; /* Segment alignment */
-+} Elf64_Phdr;
-+
-+/* Special value for e_phnum. This indicates that the real number of
-+ program headers is too large to fit into e_phnum. Instead the real
-+ value is in the field sh_info of section 0. */
-+
-+#define PN_XNUM 0xffff
-+
-+/* Legal values for p_type (segment type). */
-+
-+#define PT_NULL 0 /* Program header table entry unused */
-+#define PT_LOAD 1 /* Loadable program segment */
-+#define PT_DYNAMIC 2 /* Dynamic linking information */
-+#define PT_INTERP 3 /* Program interpreter */
-+#define PT_NOTE 4 /* Auxiliary information */
-+#define PT_SHLIB 5 /* Reserved */
-+#define PT_PHDR 6 /* Entry for header table itself */
-+#define PT_TLS 7 /* Thread-local storage segment */
-+#define PT_NUM 8 /* Number of defined types */
-+#define PT_LOOS 0x60000000 /* Start of OS-specific */
-+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
-+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
-+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
-+#define PT_LOSUNW 0x6ffffffa
-+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
-+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
-+#define PT_HISUNW 0x6fffffff
-+#define PT_HIOS 0x6fffffff /* End of OS-specific */
-+#define PT_LOPROC 0x70000000 /* Start of processor-specific */
-+#define PT_HIPROC 0x7fffffff /* End of processor-specific */
-+
-+/* Legal values for p_flags (segment flags). */
-+
-+#define PF_X (1 << 0) /* Segment is executable */
-+#define PF_W (1 << 1) /* Segment is writable */
-+#define PF_R (1 << 2) /* Segment is readable */
-+#define PF_MASKOS 0x0ff00000 /* OS-specific */
-+#define PF_MASKPROC 0xf0000000 /* Processor-specific */
-+
-+/* Legal values for note segment descriptor types for core files. */
-+
-+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
-+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
-+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
-+#define NT_PRXREG 4 /* Contains copy of prxregset struct */
-+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */
-+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */
-+#define NT_AUXV 6 /* Contains copy of auxv array */
-+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */
-+#define NT_ASRS 8 /* Contains copy of asrset struct */
-+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */
-+#define NT_PSINFO 13 /* Contains copy of psinfo struct */
-+#define NT_PRCRED 14 /* Contains copy of prcred struct */
-+#define NT_UTSNAME 15 /* Contains copy of utsname struct */
-+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
-+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
-+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
-+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
-+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
-+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
-+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
-+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
-+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
-+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
-+
-+/* Legal values for the note segment descriptor types for object files. */
-+
-+#define NT_VERSION 1 /* Contains a version string. */
-+
-+
-+/* Dynamic section entry. */
-+
-+typedef struct
-+{
-+ Elf32_Sword d_tag; /* Dynamic entry type */
-+ union
-+ {
-+ Elf32_Word d_val; /* Integer value */
-+ Elf32_Addr d_ptr; /* Address value */
-+ } d_un;
-+} Elf32_Dyn;
-+
-+typedef struct
-+{
-+ Elf64_Sxword d_tag; /* Dynamic entry type */
-+ union
-+ {
-+ Elf64_Xword d_val; /* Integer value */
-+ Elf64_Addr d_ptr; /* Address value */
-+ } d_un;
-+} Elf64_Dyn;
-+
-+/* Legal values for d_tag (dynamic entry type). */
-+
-+#define DT_NULL 0 /* Marks end of dynamic section */
-+#define DT_NEEDED 1 /* Name of needed library */
-+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
-+#define DT_PLTGOT 3 /* Processor defined value */
-+#define DT_HASH 4 /* Address of symbol hash table */
-+#define DT_STRTAB 5 /* Address of string table */
-+#define DT_SYMTAB 6 /* Address of symbol table */
-+#define DT_RELA 7 /* Address of Rela relocs */
-+#define DT_RELASZ 8 /* Total size of Rela relocs */
-+#define DT_RELAENT 9 /* Size of one Rela reloc */
-+#define DT_STRSZ 10 /* Size of string table */
-+#define DT_SYMENT 11 /* Size of one symbol table entry */
-+#define DT_INIT 12 /* Address of init function */
-+#define DT_FINI 13 /* Address of termination function */
-+#define DT_SONAME 14 /* Name of shared object */
-+#define DT_RPATH 15 /* Library search path (deprecated) */
-+#define DT_SYMBOLIC 16 /* Start symbol search here */
-+#define DT_REL 17 /* Address of Rel relocs */
-+#define DT_RELSZ 18 /* Total size of Rel relocs */
-+#define DT_RELENT 19 /* Size of one Rel reloc */
-+#define DT_PLTREL 20 /* Type of reloc in PLT */
-+#define DT_DEBUG 21 /* For debugging; unspecified */
-+#define DT_TEXTREL 22 /* Reloc might modify .text */
-+#define DT_JMPREL 23 /* Address of PLT relocs */
-+#define DT_BIND_NOW 24 /* Process relocations of object */
-+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
-+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
-+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
-+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
-+#define DT_RUNPATH 29 /* Library search path */
-+#define DT_FLAGS 30 /* Flags for the object being loaded */
-+#define DT_ENCODING 32 /* Start of encoded range */
-+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
-+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
-+#define DT_NUM 34 /* Number used */
-+#define DT_LOOS 0x6000000d /* Start of OS-specific */
-+#define DT_HIOS 0x6ffff000 /* End of OS-specific */
-+#define DT_LOPROC 0x70000000 /* Start of processor-specific */
-+#define DT_HIPROC 0x7fffffff /* End of processor-specific */
-+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */
-+
-+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
-+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's
-+ approach. */
-+#define DT_VALRNGLO 0x6ffffd00
-+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */
-+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */
-+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */
-+#define DT_CHECKSUM 0x6ffffdf8
-+#define DT_PLTPADSZ 0x6ffffdf9
-+#define DT_MOVEENT 0x6ffffdfa
-+#define DT_MOVESZ 0x6ffffdfb
-+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */
-+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting
-+ the following DT_* entry. */
-+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */
-+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */
-+#define DT_VALRNGHI 0x6ffffdff
-+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */
-+#define DT_VALNUM 12
-+
-+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
-+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
-+
-+ If any adjustment is made to the ELF object after it has been
-+ built these entries will need to be adjusted. */
-+#define DT_ADDRRNGLO 0x6ffffe00
-+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */
-+#define DT_TLSDESC_PLT 0x6ffffef6
-+#define DT_TLSDESC_GOT 0x6ffffef7
-+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
-+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
-+#define DT_CONFIG 0x6ffffefa /* Configuration information. */
-+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */
-+#define DT_AUDIT 0x6ffffefc /* Object auditing. */
-+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */
-+#define DT_MOVETAB 0x6ffffefe /* Move table. */
-+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */
-+#define DT_ADDRRNGHI 0x6ffffeff
-+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */
-+#define DT_ADDRNUM 11
-+
-+/* The versioning entry types. The next are defined as part of the
-+ GNU extension. */
-+#define DT_VERSYM 0x6ffffff0
-+
-+#define DT_RELACOUNT 0x6ffffff9
-+#define DT_RELCOUNT 0x6ffffffa
-+
-+/* These were chosen by Sun. */
-+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */
-+#define DT_VERDEF 0x6ffffffc /* Address of version definition
-+ table */
-+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */
-+#define DT_VERNEED 0x6ffffffe /* Address of table with needed
-+ versions */
-+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */
-+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
-+#define DT_VERSIONTAGNUM 16
-+
-+/* Sun added these machine-independent extensions in the "processor-specific"
-+ range. Be compatible. */
-+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */
-+#define DT_FILTER 0x7fffffff /* Shared object to get values from */
-+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
-+#define DT_EXTRANUM 3
-+
-+/* Values of `d_un.d_val' in the DT_FLAGS entry. */
-+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */
-+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */
-+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */
-+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */
-+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
-+
-+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
-+ entry in the dynamic section. */
-+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */
-+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */
-+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */
-+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/
-+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/
-+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
-+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */
-+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */
-+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
-+#define DF_1_TRANS 0x00000200
-+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
-+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */
-+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */
-+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/
-+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */
-+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */
-+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */
-+
-+/* Flags for the feature selection in DT_FEATURE_1. */
-+#define DTF_1_PARINIT 0x00000001
-+#define DTF_1_CONFEXP 0x00000002
-+
-+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
-+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
-+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
-+ generally available. */
-+
-+/* Version definition sections. */
-+
-+typedef struct
-+{
-+ Elf32_Half vd_version; /* Version revision */
-+ Elf32_Half vd_flags; /* Version information */
-+ Elf32_Half vd_ndx; /* Version Index */
-+ Elf32_Half vd_cnt; /* Number of associated aux entries */
-+ Elf32_Word vd_hash; /* Version name hash value */
-+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */
-+ Elf32_Word vd_next; /* Offset in bytes to next verdef
-+ entry */
-+} Elf32_Verdef;
-+
-+typedef struct
-+{
-+ Elf64_Half vd_version; /* Version revision */
-+ Elf64_Half vd_flags; /* Version information */
-+ Elf64_Half vd_ndx; /* Version Index */
-+ Elf64_Half vd_cnt; /* Number of associated aux entries */
-+ Elf64_Word vd_hash; /* Version name hash value */
-+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */
-+ Elf64_Word vd_next; /* Offset in bytes to next verdef
-+ entry */
-+} Elf64_Verdef;
-+
-+
-+/* Legal values for vd_version (version revision). */
-+#define VER_DEF_NONE 0 /* No version */
-+#define VER_DEF_CURRENT 1 /* Current version */
-+#define VER_DEF_NUM 2 /* Given version number */
-+
-+/* Legal values for vd_flags (version information flags). */
-+#define VER_FLG_BASE 0x1 /* Version definition of file itself */
-+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
-+
-+/* Versym symbol index values. */
-+#define VER_NDX_LOCAL 0 /* Symbol is local. */
-+#define VER_NDX_GLOBAL 1 /* Symbol is global. */
-+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */
-+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */
-+
-+/* Auxialiary version information. */
-+
-+typedef struct
-+{
-+ Elf32_Word vda_name; /* Version or dependency names */
-+ Elf32_Word vda_next; /* Offset in bytes to next verdaux
-+ entry */
-+} Elf32_Verdaux;
-+
-+typedef struct
-+{
-+ Elf64_Word vda_name; /* Version or dependency names */
-+ Elf64_Word vda_next; /* Offset in bytes to next verdaux
-+ entry */
-+} Elf64_Verdaux;
-+
-+
-+/* Version dependency section. */
-+
-+typedef struct
-+{
-+ Elf32_Half vn_version; /* Version of structure */
-+ Elf32_Half vn_cnt; /* Number of associated aux entries */
-+ Elf32_Word vn_file; /* Offset of filename for this
-+ dependency */
-+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */
-+ Elf32_Word vn_next; /* Offset in bytes to next verneed
-+ entry */
-+} Elf32_Verneed;
-+
-+typedef struct
-+{
-+ Elf64_Half vn_version; /* Version of structure */
-+ Elf64_Half vn_cnt; /* Number of associated aux entries */
-+ Elf64_Word vn_file; /* Offset of filename for this
-+ dependency */
-+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */
-+ Elf64_Word vn_next; /* Offset in bytes to next verneed
-+ entry */
-+} Elf64_Verneed;
-+
-+
-+/* Legal values for vn_version (version revision). */
-+#define VER_NEED_NONE 0 /* No version */
-+#define VER_NEED_CURRENT 1 /* Current version */
-+#define VER_NEED_NUM 2 /* Given version number */
-+
-+/* Auxiliary needed version information. */
-+
-+typedef struct
-+{
-+ Elf32_Word vna_hash; /* Hash value of dependency name */
-+ Elf32_Half vna_flags; /* Dependency specific information */
-+ Elf32_Half vna_other; /* Unused */
-+ Elf32_Word vna_name; /* Dependency name string offset */
-+ Elf32_Word vna_next; /* Offset in bytes to next vernaux
-+ entry */
-+} Elf32_Vernaux;
-+
-+typedef struct
-+{
-+ Elf64_Word vna_hash; /* Hash value of dependency name */
-+ Elf64_Half vna_flags; /* Dependency specific information */
-+ Elf64_Half vna_other; /* Unused */
-+ Elf64_Word vna_name; /* Dependency name string offset */
-+ Elf64_Word vna_next; /* Offset in bytes to next vernaux
-+ entry */
-+} Elf64_Vernaux;
-+
-+
-+/* Legal values for vna_flags. */
-+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
-+
-+
-+/* Auxiliary vector. */
-+
-+/* This vector is normally only used by the program interpreter. The
-+ usual definition in an ABI supplement uses the name auxv_t. The
-+ vector is not usually defined in a standard <elf.h> file, but it
-+ can't hurt. We rename it to avoid conflicts. The sizes of these
-+ types are an arrangement between the exec server and the program
-+ interpreter, so we don't fully specify them here. */
-+
-+typedef struct
-+{
-+ uint32_t a_type; /* Entry type */
-+ union
-+ {
-+ uint32_t a_val; /* Integer value */
-+ /* We use to have pointer elements added here. We cannot do that,
-+ though, since it does not work when using 32-bit definitions
-+ on 64-bit platforms and vice versa. */
-+ } a_un;
-+} Elf32_auxv_t;
-+
-+typedef struct
-+{
-+ uint64_t a_type; /* Entry type */
-+ union
-+ {
-+ uint64_t a_val; /* Integer value */
-+ /* We use to have pointer elements added here. We cannot do that,
-+ though, since it does not work when using 32-bit definitions
-+ on 64-bit platforms and vice versa. */
-+ } a_un;
-+} Elf64_auxv_t;
-+
-+/* Legal values for a_type (entry type). */
-+
-+#define AT_NULL 0 /* End of vector */
-+#define AT_IGNORE 1 /* Entry should be ignored */
-+#define AT_EXECFD 2 /* File descriptor of program */
-+#define AT_PHDR 3 /* Program headers for program */
-+#define AT_PHENT 4 /* Size of program header entry */
-+#define AT_PHNUM 5 /* Number of program headers */
-+#define AT_PAGESZ 6 /* System page size */
-+#define AT_BASE 7 /* Base address of interpreter */
-+#define AT_FLAGS 8 /* Flags */
-+#define AT_ENTRY 9 /* Entry point of program */
-+#define AT_NOTELF 10 /* Program is not ELF */
-+#define AT_UID 11 /* Real uid */
-+#define AT_EUID 12 /* Effective uid */
-+#define AT_GID 13 /* Real gid */
-+#define AT_EGID 14 /* Effective gid */
-+#define AT_CLKTCK 17 /* Frequency of times() */
-+
-+/* Some more special a_type values describing the hardware. */
-+#define AT_PLATFORM 15 /* String identifying platform. */
-+#define AT_HWCAP 16 /* Machine dependent hints about
-+ processor capabilities. */
-+
-+/* This entry gives some information about the FPU initialization
-+ performed by the kernel. */
-+#define AT_FPUCW 18 /* Used FPU control word. */
-+
-+/* Cache block sizes. */
-+#define AT_DCACHEBSIZE 19 /* Data cache block size. */
-+#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */
-+#define AT_UCACHEBSIZE 21 /* Unified cache block size. */
-+
-+/* A special ignored value for PPC, used by the kernel to control the
-+ interpretation of the AUXV. Must be > 16. */
-+#define AT_IGNOREPPC 22 /* Entry should be ignored. */
-+
-+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */
-+
-+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/
-+
-+#define AT_RANDOM 25 /* Address of 16 random bytes. */
-+
-+#define AT_EXECFN 31 /* Filename of executable. */
-+
-+/* Pointer to the global system page used for system calls and other
-+ nice things. */
-+#define AT_SYSINFO 32
-+#define AT_SYSINFO_EHDR 33
-+
-+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains
-+ log2 of line size; mask those to get cache size. */
-+#define AT_L1I_CACHESHAPE 34
-+#define AT_L1D_CACHESHAPE 35
-+#define AT_L2_CACHESHAPE 36
-+#define AT_L3_CACHESHAPE 37
-+
-+/* Note section contents. Each entry in the note section begins with
-+ a header of a fixed form. */
-+
-+typedef struct
-+{
-+ Elf32_Word n_namesz; /* Length of the note's name. */
-+ Elf32_Word n_descsz; /* Length of the note's descriptor. */
-+ Elf32_Word n_type; /* Type of the note. */
-+} Elf32_Nhdr;
-+
-+typedef struct
-+{
-+ Elf64_Word n_namesz; /* Length of the note's name. */
-+ Elf64_Word n_descsz; /* Length of the note's descriptor. */
-+ Elf64_Word n_type; /* Type of the note. */
-+} Elf64_Nhdr;
-+
-+/* Known names of notes. */
-+
-+/* Solaris entries in the note section have this name. */
-+#define ELF_NOTE_SOLARIS "SUNW Solaris"
-+
-+/* Note entries for GNU systems have this name. */
-+#define ELF_NOTE_GNU "GNU"
-+
-+
-+/* Defined types of notes for Solaris. */
-+
-+/* Value of descriptor (one word) is desired pagesize for the binary. */
-+#define ELF_NOTE_PAGESIZE_HINT 1
-+
-+
-+/* Defined note types for GNU systems. */
-+
-+/* ABI information. The descriptor consists of words:
-+ word 0: OS descriptor
-+ word 1: major version of the ABI
-+ word 2: minor version of the ABI
-+ word 3: subminor version of the ABI
-+*/
-+#define NT_GNU_ABI_TAG 1
-+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */
-+
-+/* Known OSes. These values can appear in word 0 of an
-+ NT_GNU_ABI_TAG note section entry. */
-+#define ELF_NOTE_OS_LINUX 0
-+#define ELF_NOTE_OS_GNU 1
-+#define ELF_NOTE_OS_SOLARIS2 2
-+#define ELF_NOTE_OS_FREEBSD 3
-+
-+/* Synthetic hwcap information. The descriptor begins with two words:
-+ word 0: number of entries
-+ word 1: bitmask of enabled entries
-+ Then follow variable-length entries, one byte followed by a
-+ '\0'-terminated hwcap name string. The byte gives the bit
-+ number to test if enabled, (1U << bit) & bitmask. */
-+#define NT_GNU_HWCAP 2
-+
-+/* Build ID bits as generated by ld --build-id.
-+ The descriptor consists of any nonzero number of bytes. */
-+#define NT_GNU_BUILD_ID 3
-+
-+/* Version note generated by GNU gold containing a version string. */
-+#define NT_GNU_GOLD_VERSION 4
-+
-+
-+/* Move records. */
-+typedef struct
-+{
-+ Elf32_Xword m_value; /* Symbol value. */
-+ Elf32_Word m_info; /* Size and index. */
-+ Elf32_Word m_poffset; /* Symbol offset. */
-+ Elf32_Half m_repeat; /* Repeat count. */
-+ Elf32_Half m_stride; /* Stride info. */
-+} Elf32_Move;
-+
-+typedef struct
-+{
-+ Elf64_Xword m_value; /* Symbol value. */
-+ Elf64_Xword m_info; /* Size and index. */
-+ Elf64_Xword m_poffset; /* Symbol offset. */
-+ Elf64_Half m_repeat; /* Repeat count. */
-+ Elf64_Half m_stride; /* Stride info. */
-+} Elf64_Move;
-+
-+/* Macro to construct move records. */
-+#define ELF32_M_SYM(info) ((info) >> 8)
-+#define ELF32_M_SIZE(info) ((unsigned char) (info))
-+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
-+
-+#define ELF64_M_SYM(info) ELF32_M_SYM (info)
-+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info)
-+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
-+
-+
-+/* Motorola 68k specific definitions. */
-+
-+/* Values for Elf32_Ehdr.e_flags. */
-+#define EF_CPU32 0x00810000
-+
-+/* m68k relocs. */
-+
-+#define R_68K_NONE 0 /* No reloc */
-+#define R_68K_32 1 /* Direct 32 bit */
-+#define R_68K_16 2 /* Direct 16 bit */
-+#define R_68K_8 3 /* Direct 8 bit */
-+#define R_68K_PC32 4 /* PC relative 32 bit */
-+#define R_68K_PC16 5 /* PC relative 16 bit */
-+#define R_68K_PC8 6 /* PC relative 8 bit */
-+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
-+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
-+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
-+#define R_68K_GOT32O 10 /* 32 bit GOT offset */
-+#define R_68K_GOT16O 11 /* 16 bit GOT offset */
-+#define R_68K_GOT8O 12 /* 8 bit GOT offset */
-+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
-+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
-+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
-+#define R_68K_PLT32O 16 /* 32 bit PLT offset */
-+#define R_68K_PLT16O 17 /* 16 bit PLT offset */
-+#define R_68K_PLT8O 18 /* 8 bit PLT offset */
-+#define R_68K_COPY 19 /* Copy symbol at runtime */
-+#define R_68K_GLOB_DAT 20 /* Create GOT entry */
-+#define R_68K_JMP_SLOT 21 /* Create PLT entry */
-+#define R_68K_RELATIVE 22 /* Adjust by program base */
-+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */
-+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */
-+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */
-+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */
-+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */
-+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */
-+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */
-+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */
-+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */
-+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */
-+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */
-+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */
-+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to
-+ static TLS block */
-+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to
-+ static TLS block */
-+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to
-+ static TLS block */
-+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */
-+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */
-+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */
-+/* Keep this the last entry. */
-+#define R_68K_NUM 43
-+
-+/* Intel 80386 specific definitions. */
-+
-+/* i386 relocs. */
-+
-+#define R_386_NONE 0 /* No reloc */
-+#define R_386_32 1 /* Direct 32 bit */
-+#define R_386_PC32 2 /* PC relative 32 bit */
-+#define R_386_GOT32 3 /* 32 bit GOT entry */
-+#define R_386_PLT32 4 /* 32 bit PLT address */
-+#define R_386_COPY 5 /* Copy symbol at runtime */
-+#define R_386_GLOB_DAT 6 /* Create GOT entry */
-+#define R_386_JMP_SLOT 7 /* Create PLT entry */
-+#define R_386_RELATIVE 8 /* Adjust by program base */
-+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
-+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
-+#define R_386_32PLT 11
-+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */
-+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS
-+ block offset */
-+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block
-+ offset */
-+#define R_386_TLS_LE 17 /* Offset relative to static TLS
-+ block */
-+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of
-+ general dynamic thread local data */
-+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of
-+ local dynamic thread local data
-+ in LE code */
-+#define R_386_16 20
-+#define R_386_PC16 21
-+#define R_386_8 22
-+#define R_386_PC8 23
-+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic
-+ thread local data */
-+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */
-+#define R_386_TLS_GD_CALL 26 /* Relocation for call to
-+ __tls_get_addr() */
-+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */
-+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic
-+ thread local data in LE code */
-+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */
-+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to
-+ __tls_get_addr() in LDM code */
-+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */
-+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */
-+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS
-+ block offset */
-+#define R_386_TLS_LE_32 34 /* Negated offset relative to static
-+ TLS block */
-+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */
-+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */
-+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */
-+/* 38? */
-+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */
-+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS
-+ descriptor for
-+ relaxation. */
-+#define R_386_TLS_DESC 41 /* TLS descriptor containing
-+ pointer to code and to
-+ argument, returning the TLS
-+ offset for the symbol. */
-+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */
-+/* Keep this the last entry. */
-+#define R_386_NUM 43
-+
-+/* SUN SPARC specific definitions. */
-+
-+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-+
-+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */
-+
-+/* Values for Elf64_Ehdr.e_flags. */
-+
-+#define EF_SPARCV9_MM 3
-+#define EF_SPARCV9_TSO 0
-+#define EF_SPARCV9_PSO 1
-+#define EF_SPARCV9_RMO 2
-+#define EF_SPARC_LEDATA 0x800000 /* little endian data */
-+#define EF_SPARC_EXT_MASK 0xFFFF00
-+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */
-+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */
-+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */
-+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */
-+
-+/* SPARC relocs. */
-+
-+#define R_SPARC_NONE 0 /* No reloc */
-+#define R_SPARC_8 1 /* Direct 8 bit */
-+#define R_SPARC_16 2 /* Direct 16 bit */
-+#define R_SPARC_32 3 /* Direct 32 bit */
-+#define R_SPARC_DISP8 4 /* PC relative 8 bit */
-+#define R_SPARC_DISP16 5 /* PC relative 16 bit */
-+#define R_SPARC_DISP32 6 /* PC relative 32 bit */
-+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */
-+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */
-+#define R_SPARC_HI22 9 /* High 22 bit */
-+#define R_SPARC_22 10 /* Direct 22 bit */
-+#define R_SPARC_13 11 /* Direct 13 bit */
-+#define R_SPARC_LO10 12 /* Truncated 10 bit */
-+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */
-+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */
-+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */
-+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */
-+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */
-+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */
-+#define R_SPARC_COPY 19 /* Copy symbol at runtime */
-+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */
-+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */
-+#define R_SPARC_RELATIVE 22 /* Adjust by program base */
-+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */
-+
-+/* Additional Sparc64 relocs. */
-+
-+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */
-+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */
-+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */
-+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */
-+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */
-+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */
-+#define R_SPARC_10 30 /* Direct 10 bit */
-+#define R_SPARC_11 31 /* Direct 11 bit */
-+#define R_SPARC_64 32 /* Direct 64 bit */
-+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */
-+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */
-+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */
-+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */
-+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */
-+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */
-+#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */
-+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
-+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
-+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
-+#define R_SPARC_7 43 /* Direct 7 bit */
-+#define R_SPARC_5 44 /* Direct 5 bit */
-+#define R_SPARC_6 45 /* Direct 6 bit */
-+#define R_SPARC_DISP64 46 /* PC relative 64 bit */
-+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */
-+#define R_SPARC_HIX22 48 /* High 22 bit complemented */
-+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */
-+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */
-+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */
-+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */
-+#define R_SPARC_REGISTER 53 /* Global register usage */
-+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */
-+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */
-+#define R_SPARC_TLS_GD_HI22 56
-+#define R_SPARC_TLS_GD_LO10 57
-+#define R_SPARC_TLS_GD_ADD 58
-+#define R_SPARC_TLS_GD_CALL 59
-+#define R_SPARC_TLS_LDM_HI22 60
-+#define R_SPARC_TLS_LDM_LO10 61
-+#define R_SPARC_TLS_LDM_ADD 62
-+#define R_SPARC_TLS_LDM_CALL 63
-+#define R_SPARC_TLS_LDO_HIX22 64
-+#define R_SPARC_TLS_LDO_LOX10 65
-+#define R_SPARC_TLS_LDO_ADD 66
-+#define R_SPARC_TLS_IE_HI22 67
-+#define R_SPARC_TLS_IE_LO10 68
-+#define R_SPARC_TLS_IE_LD 69
-+#define R_SPARC_TLS_IE_LDX 70
-+#define R_SPARC_TLS_IE_ADD 71
-+#define R_SPARC_TLS_LE_HIX22 72
-+#define R_SPARC_TLS_LE_LOX10 73
-+#define R_SPARC_TLS_DTPMOD32 74
-+#define R_SPARC_TLS_DTPMOD64 75
-+#define R_SPARC_TLS_DTPOFF32 76
-+#define R_SPARC_TLS_DTPOFF64 77
-+#define R_SPARC_TLS_TPOFF32 78
-+#define R_SPARC_TLS_TPOFF64 79
-+#define R_SPARC_GOTDATA_HIX22 80
-+#define R_SPARC_GOTDATA_LOX10 81
-+#define R_SPARC_GOTDATA_OP_HIX22 82
-+#define R_SPARC_GOTDATA_OP_LOX10 83
-+#define R_SPARC_GOTDATA_OP 84
-+#define R_SPARC_H34 85
-+#define R_SPARC_SIZE32 86
-+#define R_SPARC_SIZE64 87
-+#define R_SPARC_WDISP10 88
-+#define R_SPARC_JMP_IREL 248
-+#define R_SPARC_IRELATIVE 249
-+#define R_SPARC_GNU_VTINHERIT 250
-+#define R_SPARC_GNU_VTENTRY 251
-+#define R_SPARC_REV32 252
-+/* Keep this the last entry. */
-+#define R_SPARC_NUM 253
-+
-+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
-+
-+#define DT_SPARC_REGISTER 0x70000001
-+#define DT_SPARC_NUM 2
-+
-+/* MIPS R3000 specific definitions. */
-+
-+/* Legal values for e_flags field of Elf32_Ehdr. */
-+
-+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */
-+#define EF_MIPS_PIC 2 /* Contains PIC code */
-+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */
-+#define EF_MIPS_XGOT 8
-+#define EF_MIPS_64BIT_WHIRL 16
-+#define EF_MIPS_ABI2 32
-+#define EF_MIPS_ABI_ON32 64
-+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */
-+
-+/* Legal values for MIPS architecture level. */
-+
-+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
-+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
-+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
-+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
-+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
-+#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */
-+#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */
-+
-+/* The following are non-official names and should not be used. */
-+
-+#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
-+#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
-+#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
-+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
-+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
-+#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */
-+#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */
-+
-+/* Special section indices. */
-+
-+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */
-+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
-+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
-+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
-+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
-+
-+/* Legal values for sh_type field of Elf32_Shdr. */
-+
-+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */
-+#define SHT_MIPS_MSYM 0x70000001
-+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */
-+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */
-+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
-+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/
-+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */
-+#define SHT_MIPS_PACKAGE 0x70000007
-+#define SHT_MIPS_PACKSYM 0x70000008
-+#define SHT_MIPS_RELD 0x70000009
-+#define SHT_MIPS_IFACE 0x7000000b
-+#define SHT_MIPS_CONTENT 0x7000000c
-+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */
-+#define SHT_MIPS_SHDR 0x70000010
-+#define SHT_MIPS_FDESC 0x70000011
-+#define SHT_MIPS_EXTSYM 0x70000012
-+#define SHT_MIPS_DENSE 0x70000013
-+#define SHT_MIPS_PDESC 0x70000014
-+#define SHT_MIPS_LOCSYM 0x70000015
-+#define SHT_MIPS_AUXSYM 0x70000016
-+#define SHT_MIPS_OPTSYM 0x70000017
-+#define SHT_MIPS_LOCSTR 0x70000018
-+#define SHT_MIPS_LINE 0x70000019
-+#define SHT_MIPS_RFDESC 0x7000001a
-+#define SHT_MIPS_DELTASYM 0x7000001b
-+#define SHT_MIPS_DELTAINST 0x7000001c
-+#define SHT_MIPS_DELTACLASS 0x7000001d
-+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */
-+#define SHT_MIPS_DELTADECL 0x7000001f
-+#define SHT_MIPS_SYMBOL_LIB 0x70000020
-+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */
-+#define SHT_MIPS_TRANSLATE 0x70000022
-+#define SHT_MIPS_PIXIE 0x70000023
-+#define SHT_MIPS_XLATE 0x70000024
-+#define SHT_MIPS_XLATE_DEBUG 0x70000025
-+#define SHT_MIPS_WHIRL 0x70000026
-+#define SHT_MIPS_EH_REGION 0x70000027
-+#define SHT_MIPS_XLATE_OLD 0x70000028
-+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
-+
-+/* Legal values for sh_flags field of Elf32_Shdr. */
-+
-+#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */
-+#define SHF_MIPS_MERGE 0x20000000
-+#define SHF_MIPS_ADDR 0x40000000
-+#define SHF_MIPS_STRINGS 0x80000000
-+#define SHF_MIPS_NOSTRIP 0x08000000
-+#define SHF_MIPS_LOCAL 0x04000000
-+#define SHF_MIPS_NAMES 0x02000000
-+#define SHF_MIPS_NODUPE 0x01000000
-+
-+
-+/* Symbol tables. */
-+
-+/* MIPS specific values for `st_other'. */
-+#define STO_MIPS_DEFAULT 0x0
-+#define STO_MIPS_INTERNAL 0x1
-+#define STO_MIPS_HIDDEN 0x2
-+#define STO_MIPS_PROTECTED 0x3
-+#define STO_MIPS_PLT 0x8
-+#define STO_MIPS_SC_ALIGN_UNUSED 0xff
-+
-+/* MIPS specific values for `st_info'. */
-+#define STB_MIPS_SPLIT_COMMON 13
-+
-+/* Entries found in sections of type SHT_MIPS_GPTAB. */
-+
-+typedef union
-+{
-+ struct
-+ {
-+ Elf32_Word gt_current_g_value; /* -G value used for compilation */
-+ Elf32_Word gt_unused; /* Not used */
-+ } gt_header; /* First entry in section */
-+ struct
-+ {
-+ Elf32_Word gt_g_value; /* If this value were used for -G */
-+ Elf32_Word gt_bytes; /* This many bytes would be used */
-+ } gt_entry; /* Subsequent entries in section */
-+} Elf32_gptab;
-+
-+/* Entry found in sections of type SHT_MIPS_REGINFO. */
-+
-+typedef struct
-+{
-+ Elf32_Word ri_gprmask; /* General registers used */
-+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */
-+ Elf32_Sword ri_gp_value; /* $gp register value */
-+} Elf32_RegInfo;
-+
-+/* Entries found in sections of type SHT_MIPS_OPTIONS. */
-+
-+typedef struct
-+{
-+ unsigned char kind; /* Determines interpretation of the
-+ variable part of descriptor. */
-+ unsigned char size; /* Size of descriptor, including header. */
-+ Elf32_Section section; /* Section header index of section affected,
-+ 0 for global options. */
-+ Elf32_Word info; /* Kind-specific information. */
-+} Elf_Options;
-+
-+/* Values for `kind' field in Elf_Options. */
-+
-+#define ODK_NULL 0 /* Undefined. */
-+#define ODK_REGINFO 1 /* Register usage information. */
-+#define ODK_EXCEPTIONS 2 /* Exception processing options. */
-+#define ODK_PAD 3 /* Section padding options. */
-+#define ODK_HWPATCH 4 /* Hardware workarounds performed */
-+#define ODK_FILL 5 /* record the fill value used by the linker. */
-+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */
-+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */
-+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */
-+
-+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */
-+
-+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */
-+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */
-+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */
-+#define OEX_SMM 0x20000 /* Force sequential memory mode? */
-+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */
-+#define OEX_PRECISEFP OEX_FPDBUG
-+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */
-+
-+#define OEX_FPU_INVAL 0x10
-+#define OEX_FPU_DIV0 0x08
-+#define OEX_FPU_OFLO 0x04
-+#define OEX_FPU_UFLO 0x02
-+#define OEX_FPU_INEX 0x01
-+
-+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */
-+
-+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */
-+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */
-+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */
-+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */
-+
-+#define OPAD_PREFIX 0x1
-+#define OPAD_POSTFIX 0x2
-+#define OPAD_SYMBOL 0x4
-+
-+/* Entry found in `.options' section. */
-+
-+typedef struct
-+{
-+ Elf32_Word hwp_flags1; /* Extra flags. */
-+ Elf32_Word hwp_flags2; /* Extra flags. */
-+} Elf_Options_Hw;
-+
-+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */
-+
-+#define OHWA0_R4KEOP_CHECKED 0x00000001
-+#define OHWA1_R4KEOP_CLEAN 0x00000002
-+
-+/* MIPS relocs. */
-+
-+#define R_MIPS_NONE 0 /* No reloc */
-+#define R_MIPS_16 1 /* Direct 16 bit */
-+#define R_MIPS_32 2 /* Direct 32 bit */
-+#define R_MIPS_REL32 3 /* PC relative 32 bit */
-+#define R_MIPS_26 4 /* Direct 26 bit shifted */
-+#define R_MIPS_HI16 5 /* High 16 bit */
-+#define R_MIPS_LO16 6 /* Low 16 bit */
-+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
-+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
-+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
-+#define R_MIPS_PC16 10 /* PC relative 16 bit */
-+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
-+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
-+
-+#define R_MIPS_SHIFT5 16
-+#define R_MIPS_SHIFT6 17
-+#define R_MIPS_64 18
-+#define R_MIPS_GOT_DISP 19
-+#define R_MIPS_GOT_PAGE 20
-+#define R_MIPS_GOT_OFST 21
-+#define R_MIPS_GOT_HI16 22
-+#define R_MIPS_GOT_LO16 23
-+#define R_MIPS_SUB 24
-+#define R_MIPS_INSERT_A 25
-+#define R_MIPS_INSERT_B 26
-+#define R_MIPS_DELETE 27
-+#define R_MIPS_HIGHER 28
-+#define R_MIPS_HIGHEST 29
-+#define R_MIPS_CALL_HI16 30
-+#define R_MIPS_CALL_LO16 31
-+#define R_MIPS_SCN_DISP 32
-+#define R_MIPS_REL16 33
-+#define R_MIPS_ADD_IMMEDIATE 34
-+#define R_MIPS_PJUMP 35
-+#define R_MIPS_RELGOT 36
-+#define R_MIPS_JALR 37
-+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
-+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
-+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
-+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
-+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
-+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
-+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
-+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
-+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
-+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
-+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
-+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
-+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
-+#define R_MIPS_GLOB_DAT 51
-+#define R_MIPS_COPY 126
-+#define R_MIPS_JUMP_SLOT 127
-+/* Keep this the last entry. */
-+#define R_MIPS_NUM 128
-+
-+/* Legal values for p_type field of Elf32_Phdr. */
-+
-+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
-+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
-+#define PT_MIPS_OPTIONS 0x70000002
-+
-+/* Special program header types. */
-+
-+#define PF_MIPS_LOCAL 0x10000000
-+
-+/* Legal values for d_tag field of Elf32_Dyn. */
-+
-+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */
-+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */
-+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */
-+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */
-+#define DT_MIPS_FLAGS 0x70000005 /* Flags */
-+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
-+#define DT_MIPS_MSYM 0x70000007
-+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */
-+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */
-+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */
-+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */
-+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */
-+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */
-+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
-+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */
-+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
-+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */
-+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */
-+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in
-+ DT_MIPS_DELTA_CLASS. */
-+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */
-+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
-+ DT_MIPS_DELTA_INSTANCE. */
-+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */
-+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
-+ DT_MIPS_DELTA_RELOC. */
-+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta
-+ relocations refer to. */
-+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
-+ DT_MIPS_DELTA_SYM. */
-+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
-+ class declaration. */
-+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
-+ DT_MIPS_DELTA_CLASSSYM. */
-+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */
-+#define DT_MIPS_PIXIE_INIT 0x70000023
-+#define DT_MIPS_SYMBOL_LIB 0x70000024
-+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
-+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
-+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
-+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
-+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */
-+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */
-+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
-+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
-+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
-+ function stored in GOT. */
-+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added
-+ by rld on dlopen() calls. */
-+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
-+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */
-+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */
-+/* The address of .got.plt in an executable using the new non-PIC ABI. */
-+#define DT_MIPS_PLTGOT 0x70000032
-+/* The base of the PLT in an executable using the new non-PIC ABI if that
-+ PLT is writable. For a non-writable PLT, this is omitted or has a zero
-+ value. */
-+#define DT_MIPS_RWPLT 0x70000034
-+#define DT_MIPS_NUM 0x35
-+
-+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
-+
-+#define RHF_NONE 0 /* No flags */
-+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */
-+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */
-+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */
-+#define RHF_NO_MOVE (1 << 3)
-+#define RHF_SGI_ONLY (1 << 4)
-+#define RHF_GUARANTEE_INIT (1 << 5)
-+#define RHF_DELTA_C_PLUS_PLUS (1 << 6)
-+#define RHF_GUARANTEE_START_INIT (1 << 7)
-+#define RHF_PIXIE (1 << 8)
-+#define RHF_DEFAULT_DELAY_LOAD (1 << 9)
-+#define RHF_REQUICKSTART (1 << 10)
-+#define RHF_REQUICKSTARTED (1 << 11)
-+#define RHF_CORD (1 << 12)
-+#define RHF_NO_UNRES_UNDEF (1 << 13)
-+#define RHF_RLD_ORDER_SAFE (1 << 14)
-+
-+/* Entries found in sections of type SHT_MIPS_LIBLIST. */
-+
-+typedef struct
-+{
-+ Elf32_Word l_name; /* Name (string table index) */
-+ Elf32_Word l_time_stamp; /* Timestamp */
-+ Elf32_Word l_checksum; /* Checksum */
-+ Elf32_Word l_version; /* Interface version */
-+ Elf32_Word l_flags; /* Flags */
-+} Elf32_Lib;
-+
-+typedef struct
-+{
-+ Elf64_Word l_name; /* Name (string table index) */
-+ Elf64_Word l_time_stamp; /* Timestamp */
-+ Elf64_Word l_checksum; /* Checksum */
-+ Elf64_Word l_version; /* Interface version */
-+ Elf64_Word l_flags; /* Flags */
-+} Elf64_Lib;
-+
-+
-+/* Legal values for l_flags. */
-+
-+#define LL_NONE 0
-+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */
-+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */
-+#define LL_REQUIRE_MINOR (1 << 2)
-+#define LL_EXPORTS (1 << 3)
-+#define LL_DELAY_LOAD (1 << 4)
-+#define LL_DELTA (1 << 5)
-+
-+/* Entries found in sections of type SHT_MIPS_CONFLICT. */
-+
-+typedef Elf32_Addr Elf32_Conflict;
-+
-+
-+/* HPPA specific definitions. */
-+
-+/* Legal values for e_flags field of Elf32_Ehdr. */
-+
-+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
-+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
-+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
-+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
-+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
-+ prediction. */
-+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
-+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
-+
-+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
-+
-+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
-+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
-+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
-+
-+/* Additional section indeces. */
-+
-+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
-+ symbols in ANSI C. */
-+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
-+
-+/* Legal values for sh_type field of Elf32_Shdr. */
-+
-+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
-+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
-+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
-+
-+/* Legal values for sh_flags field of Elf32_Shdr. */
-+
-+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
-+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
-+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
-+
-+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-+
-+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
-+
-+#define STT_HP_OPAQUE (STT_LOOS + 0x1)
-+#define STT_HP_STUB (STT_LOOS + 0x2)
-+
-+/* HPPA relocs. */
-+
-+#define R_PARISC_NONE 0 /* No reloc. */
-+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
-+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
-+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
-+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
-+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
-+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
-+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
-+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
-+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
-+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
-+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
-+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
-+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
-+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
-+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
-+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
-+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
-+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
-+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
-+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
-+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
-+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
-+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
-+#define R_PARISC_FPTR64 64 /* 64 bits function address. */
-+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
-+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */
-+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */
-+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
-+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
-+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
-+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
-+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
-+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
-+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
-+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
-+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
-+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
-+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
-+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
-+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
-+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
-+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
-+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
-+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
-+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
-+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
-+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
-+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
-+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
-+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
-+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
-+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
-+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
-+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
-+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
-+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
-+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
-+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
-+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
-+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
-+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
-+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
-+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
-+#define R_PARISC_LORESERVE 128
-+#define R_PARISC_COPY 128 /* Copy relocation. */
-+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
-+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
-+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
-+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
-+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
-+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
-+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
-+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
-+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
-+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
-+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
-+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
-+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
-+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
-+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
-+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
-+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
-+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
-+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
-+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
-+#define R_PARISC_GNU_VTENTRY 232
-+#define R_PARISC_GNU_VTINHERIT 233
-+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */
-+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */
-+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */
-+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */
-+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */
-+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */
-+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */
-+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */
-+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */
-+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */
-+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */
-+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */
-+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
-+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
-+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
-+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
-+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
-+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
-+#define R_PARISC_HIRESERVE 255
-+
-+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
-+
-+#define PT_HP_TLS (PT_LOOS + 0x0)
-+#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
-+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
-+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
-+#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
-+#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
-+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
-+#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
-+#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
-+#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
-+#define PT_HP_PARALLEL (PT_LOOS + 0x10)
-+#define PT_HP_FASTBIND (PT_LOOS + 0x11)
-+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
-+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
-+#define PT_HP_STACK (PT_LOOS + 0x14)
-+
-+#define PT_PARISC_ARCHEXT 0x70000000
-+#define PT_PARISC_UNWIND 0x70000001
-+
-+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
-+
-+#define PF_PARISC_SBP 0x08000000
-+
-+#define PF_HP_PAGE_SIZE 0x00100000
-+#define PF_HP_FAR_SHARED 0x00200000
-+#define PF_HP_NEAR_SHARED 0x00400000
-+#define PF_HP_CODE 0x01000000
-+#define PF_HP_MODIFY 0x02000000
-+#define PF_HP_LAZYSWAP 0x04000000
-+#define PF_HP_SBP 0x08000000
-+
-+
-+/* Alpha specific definitions. */
-+
-+/* Legal values for e_flags field of Elf64_Ehdr. */
-+
-+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */
-+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */
-+
-+/* Legal values for sh_type field of Elf64_Shdr. */
-+
-+/* These two are primerily concerned with ECOFF debugging info. */
-+#define SHT_ALPHA_DEBUG 0x70000001
-+#define SHT_ALPHA_REGINFO 0x70000002
-+
-+/* Legal values for sh_flags field of Elf64_Shdr. */
-+
-+#define SHF_ALPHA_GPREL 0x10000000
-+
-+/* Legal values for st_other field of Elf64_Sym. */
-+#define STO_ALPHA_NOPV 0x80 /* No PV required. */
-+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */
-+
-+/* Alpha relocs. */
-+
-+#define R_ALPHA_NONE 0 /* No reloc */
-+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
-+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
-+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
-+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
-+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
-+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
-+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
-+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
-+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
-+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
-+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
-+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
-+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
-+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
-+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
-+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
-+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
-+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
-+#define R_ALPHA_TLS_GD_HI 28
-+#define R_ALPHA_TLSGD 29
-+#define R_ALPHA_TLS_LDM 30
-+#define R_ALPHA_DTPMOD64 31
-+#define R_ALPHA_GOTDTPREL 32
-+#define R_ALPHA_DTPREL64 33
-+#define R_ALPHA_DTPRELHI 34
-+#define R_ALPHA_DTPRELLO 35
-+#define R_ALPHA_DTPREL16 36
-+#define R_ALPHA_GOTTPREL 37
-+#define R_ALPHA_TPREL64 38
-+#define R_ALPHA_TPRELHI 39
-+#define R_ALPHA_TPRELLO 40
-+#define R_ALPHA_TPREL16 41
-+/* Keep this the last entry. */
-+#define R_ALPHA_NUM 46
-+
-+/* Magic values of the LITUSE relocation addend. */
-+#define LITUSE_ALPHA_ADDR 0
-+#define LITUSE_ALPHA_BASE 1
-+#define LITUSE_ALPHA_BYTOFF 2
-+#define LITUSE_ALPHA_JSR 3
-+#define LITUSE_ALPHA_TLS_GD 4
-+#define LITUSE_ALPHA_TLS_LDM 5
-+
-+/* Legal values for d_tag of Elf64_Dyn. */
-+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
-+#define DT_ALPHA_NUM 1
-+
-+/* PowerPC specific declarations */
-+
-+/* Values for Elf32/64_Ehdr.e_flags. */
-+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
-+
-+/* Cygnus local bits below */
-+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
-+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
-+ flag */
-+
-+/* PowerPC relocations defined by the ABIs */
-+#define R_PPC_NONE 0
-+#define R_PPC_ADDR32 1 /* 32bit absolute address */
-+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-+#define R_PPC_ADDR16 3 /* 16bit absolute address */
-+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-+#define R_PPC_ADDR14_BRTAKEN 8
-+#define R_PPC_ADDR14_BRNTAKEN 9
-+#define R_PPC_REL24 10 /* PC relative 26 bit */
-+#define R_PPC_REL14 11 /* PC relative 16 bit */
-+#define R_PPC_REL14_BRTAKEN 12
-+#define R_PPC_REL14_BRNTAKEN 13
-+#define R_PPC_GOT16 14
-+#define R_PPC_GOT16_LO 15
-+#define R_PPC_GOT16_HI 16
-+#define R_PPC_GOT16_HA 17
-+#define R_PPC_PLTREL24 18
-+#define R_PPC_COPY 19
-+#define R_PPC_GLOB_DAT 20
-+#define R_PPC_JMP_SLOT 21
-+#define R_PPC_RELATIVE 22
-+#define R_PPC_LOCAL24PC 23
-+#define R_PPC_UADDR32 24
-+#define R_PPC_UADDR16 25
-+#define R_PPC_REL32 26
-+#define R_PPC_PLT32 27
-+#define R_PPC_PLTREL32 28
-+#define R_PPC_PLT16_LO 29
-+#define R_PPC_PLT16_HI 30
-+#define R_PPC_PLT16_HA 31
-+#define R_PPC_SDAREL16 32
-+#define R_PPC_SECTOFF 33
-+#define R_PPC_SECTOFF_LO 34
-+#define R_PPC_SECTOFF_HI 35
-+#define R_PPC_SECTOFF_HA 36
-+
-+/* PowerPC relocations defined for the TLS access ABI. */
-+#define R_PPC_TLS 67 /* none (sym+add)@tls */
-+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
-+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
-+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
-+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
-+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
-+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
-+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
-+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
-+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
-+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
-+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
-+
-+/* The remaining relocs are from the Embedded ELF ABI, and are not
-+ in the SVR4 ELF ABI. */
-+#define R_PPC_EMB_NADDR32 101
-+#define R_PPC_EMB_NADDR16 102
-+#define R_PPC_EMB_NADDR16_LO 103
-+#define R_PPC_EMB_NADDR16_HI 104
-+#define R_PPC_EMB_NADDR16_HA 105
-+#define R_PPC_EMB_SDAI16 106
-+#define R_PPC_EMB_SDA2I16 107
-+#define R_PPC_EMB_SDA2REL 108
-+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
-+#define R_PPC_EMB_MRKREF 110
-+#define R_PPC_EMB_RELSEC16 111
-+#define R_PPC_EMB_RELST_LO 112
-+#define R_PPC_EMB_RELST_HI 113
-+#define R_PPC_EMB_RELST_HA 114
-+#define R_PPC_EMB_BIT_FLD 115
-+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
-+
-+/* Diab tool relocations. */
-+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
-+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
-+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
-+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
-+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
-+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
-+
-+/* GNU extension to support local ifunc. */
-+#define R_PPC_IRELATIVE 248
-+
-+/* GNU relocs used in PIC code sequences. */
-+#define R_PPC_REL16 249 /* half16 (sym+add-.) */
-+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */
-+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */
-+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */
-+
-+/* This is a phony reloc to handle any old fashioned TOC16 references
-+ that may still be in object files. */
-+#define R_PPC_TOC16 255
-+
-+/* PowerPC specific values for the Dyn d_tag field. */
-+#define DT_PPC_GOT (DT_LOPROC + 0)
-+#define DT_PPC_NUM 1
-+
-+/* PowerPC64 relocations defined by the ABIs */
-+#define R_PPC64_NONE R_PPC_NONE
-+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */
-+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */
-+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */
-+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */
-+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */
-+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
-+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */
-+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
-+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
-+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
-+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */
-+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
-+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
-+#define R_PPC64_GOT16 R_PPC_GOT16
-+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
-+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
-+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
-+
-+#define R_PPC64_COPY R_PPC_COPY
-+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
-+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
-+#define R_PPC64_RELATIVE R_PPC_RELATIVE
-+
-+#define R_PPC64_UADDR32 R_PPC_UADDR32
-+#define R_PPC64_UADDR16 R_PPC_UADDR16
-+#define R_PPC64_REL32 R_PPC_REL32
-+#define R_PPC64_PLT32 R_PPC_PLT32
-+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
-+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
-+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
-+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
-+
-+#define R_PPC64_SECTOFF R_PPC_SECTOFF
-+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
-+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
-+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
-+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */
-+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */
-+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */
-+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */
-+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */
-+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */
-+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */
-+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */
-+#define R_PPC64_PLT64 45 /* doubleword64 L + A */
-+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */
-+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */
-+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */
-+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */
-+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */
-+#define R_PPC64_TOC 51 /* doubleword64 .TOC */
-+#define R_PPC64_PLTGOT16 52 /* half16* M + A */
-+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */
-+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */
-+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */
-+
-+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */
-+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */
-+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */
-+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */
-+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */
-+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */
-+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */
-+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */
-+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */
-+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */
-+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */
-+
-+/* PowerPC64 relocations defined for the TLS access ABI. */
-+#define R_PPC64_TLS 67 /* none (sym+add)@tls */
-+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
-+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
-+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
-+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
-+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
-+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
-+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
-+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
-+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
-+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
-+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
-+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
-+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
-+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
-+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
-+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
-+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
-+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
-+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
-+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
-+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
-+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
-+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
-+
-+/* GNU extension to support local ifunc. */
-+#define R_PPC64_JMP_IREL 247
-+#define R_PPC64_IRELATIVE 248
-+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */
-+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */
-+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */
-+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */
-+
-+/* PowerPC64 specific values for the Dyn d_tag field. */
-+#define DT_PPC64_GLINK (DT_LOPROC + 0)
-+#define DT_PPC64_OPD (DT_LOPROC + 1)
-+#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
-+#define DT_PPC64_NUM 3
-+
-+
-+/* ARM specific declarations */
-+
-+/* Processor specific flags for the ELF header e_flags field. */
-+#define EF_ARM_RELEXEC 0x01
-+#define EF_ARM_HASENTRY 0x02
-+#define EF_ARM_INTERWORK 0x04
-+#define EF_ARM_APCS_26 0x08
-+#define EF_ARM_APCS_FLOAT 0x10
-+#define EF_ARM_PIC 0x20
-+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
-+#define EF_ARM_NEW_ABI 0x80
-+#define EF_ARM_OLD_ABI 0x100
-+#define EF_ARM_SOFT_FLOAT 0x200
-+#define EF_ARM_VFP_FLOAT 0x400
-+#define EF_ARM_MAVERICK_FLOAT 0x800
-+
-+
-+/* Other constants defined in the ARM ELF spec. version B-01. */
-+/* NB. These conflict with values defined above. */
-+#define EF_ARM_SYMSARESORTED 0x04
-+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
-+#define EF_ARM_MAPSYMSFIRST 0x10
-+#define EF_ARM_EABIMASK 0XFF000000
-+
-+/* Constants defined in AAELF. */
-+#define EF_ARM_BE8 0x00800000
-+#define EF_ARM_LE8 0x00400000
-+
-+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
-+#define EF_ARM_EABI_UNKNOWN 0x00000000
-+#define EF_ARM_EABI_VER1 0x01000000
-+#define EF_ARM_EABI_VER2 0x02000000
-+#define EF_ARM_EABI_VER3 0x03000000
-+#define EF_ARM_EABI_VER4 0x04000000
-+#define EF_ARM_EABI_VER5 0x05000000
-+
-+/* Additional symbol types for Thumb. */
-+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
-+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
-+
-+/* ARM-specific values for sh_flags */
-+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
-+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
-+ in the input to a link step. */
-+
-+/* ARM-specific program header flags */
-+#define PF_ARM_SB 0x10000000 /* Segment contains the location
-+ addressed by the static base. */
-+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */
-+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */
-+
-+/* Processor specific values for the Phdr p_type field. */
-+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
-+
-+/* Processor specific values for the Shdr sh_type field. */
-+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
-+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
-+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
-+
-+
-+/* ARM relocs. */
-+
-+#define R_ARM_NONE 0 /* No reloc */
-+#define R_ARM_PC24 1 /* PC relative 26 bit branch */
-+#define R_ARM_ABS32 2 /* Direct 32 bit */
-+#define R_ARM_REL32 3 /* PC relative 32 bit */
-+#define R_ARM_PC13 4
-+#define R_ARM_ABS16 5 /* Direct 16 bit */
-+#define R_ARM_ABS12 6 /* Direct 12 bit */
-+#define R_ARM_THM_ABS5 7
-+#define R_ARM_ABS8 8 /* Direct 8 bit */
-+#define R_ARM_SBREL32 9
-+#define R_ARM_THM_PC22 10
-+#define R_ARM_THM_PC8 11
-+#define R_ARM_AMP_VCALL9 12
-+#define R_ARM_SWI24 13 /* Obsolete static relocation. */
-+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */
-+#define R_ARM_THM_SWI8 14
-+#define R_ARM_XPC25 15
-+#define R_ARM_THM_XPC22 16
-+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
-+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
-+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
-+#define R_ARM_COPY 20 /* Copy symbol at runtime */
-+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
-+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
-+#define R_ARM_RELATIVE 23 /* Adjust by program base */
-+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
-+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
-+#define R_ARM_GOT32 26 /* 32 bit GOT entry */
-+#define R_ARM_PLT32 27 /* 32 bit PLT address */
-+#define R_ARM_ALU_PCREL_7_0 32
-+#define R_ARM_ALU_PCREL_15_8 33
-+#define R_ARM_ALU_PCREL_23_15 34
-+#define R_ARM_LDR_SBREL_11_0 35
-+#define R_ARM_ALU_SBREL_19_12 36
-+#define R_ARM_ALU_SBREL_27_20 37
-+#define R_ARM_TLS_GOTDESC 90
-+#define R_ARM_TLS_CALL 91
-+#define R_ARM_TLS_DESCSEQ 92
-+#define R_ARM_THM_TLS_CALL 93
-+#define R_ARM_GNU_VTENTRY 100
-+#define R_ARM_GNU_VTINHERIT 101
-+#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
-+#define R_ARM_THM_PC9 103 /* thumb conditional branch */
-+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic
-+ thread local data */
-+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic
-+ thread local data */
-+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS
-+ block */
-+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of
-+ static TLS block offset */
-+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static
-+ TLS block */
-+#define R_ARM_THM_TLS_DESCSEQ 129
-+#define R_ARM_IRELATIVE 160
-+#define R_ARM_RXPC25 249
-+#define R_ARM_RSBREL32 250
-+#define R_ARM_THM_RPC22 251
-+#define R_ARM_RREL32 252
-+#define R_ARM_RABS22 253
-+#define R_ARM_RPC24 254
-+#define R_ARM_RBASE 255
-+/* Keep this the last entry. */
-+#define R_ARM_NUM 256
-+
-+/* IA-64 specific declarations. */
-+
-+/* Processor specific flags for the Ehdr e_flags field. */
-+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
-+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
-+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
-+
-+/* Processor specific values for the Phdr p_type field. */
-+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
-+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
-+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
-+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
-+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
-+
-+/* Processor specific flags for the Phdr p_flags field. */
-+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
-+
-+/* Processor specific values for the Shdr sh_type field. */
-+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
-+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
-+
-+/* Processor specific flags for the Shdr sh_flags field. */
-+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
-+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
-+
-+/* Processor specific values for the Dyn d_tag field. */
-+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
-+#define DT_IA_64_NUM 1
-+
-+/* IA-64 relocations. */
-+#define R_IA64_NONE 0x00 /* none */
-+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
-+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
-+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
-+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
-+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
-+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
-+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
-+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
-+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
-+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */
-+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */
-+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
-+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
-+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
-+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
-+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
-+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
-+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
-+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
-+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
-+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
-+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
-+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
-+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */
-+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
-+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
-+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
-+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
-+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
-+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
-+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
-+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
-+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */
-+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */
-+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */
-+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */
-+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
-+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
-+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
-+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
-+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
-+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
-+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
-+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
-+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
-+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
-+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
-+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
-+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
-+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
-+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
-+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
-+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */
-+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */
-+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */
-+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
-+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
-+#define R_IA64_COPY 0x84 /* copy relocation */
-+#define R_IA64_SUB 0x85 /* Addend and symbol difference */
-+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
-+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
-+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */
-+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */
-+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */
-+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */
-+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */
-+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */
-+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */
-+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */
-+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */
-+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */
-+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */
-+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */
-+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */
-+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
-+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
-+
-+/* SH specific declarations */
-+
-+/* Processor specific flags for the ELF header e_flags field. */
-+#define EF_SH_MACH_MASK 0x1f
-+#define EF_SH_UNKNOWN 0x0
-+#define EF_SH1 0x1
-+#define EF_SH2 0x2
-+#define EF_SH3 0x3
-+#define EF_SH_DSP 0x4
-+#define EF_SH3_DSP 0x5
-+#define EF_SH4AL_DSP 0x6
-+#define EF_SH3E 0x8
-+#define EF_SH4 0x9
-+#define EF_SH2E 0xb
-+#define EF_SH4A 0xc
-+#define EF_SH2A 0xd
-+#define EF_SH4_NOFPU 0x10
-+#define EF_SH4A_NOFPU 0x11
-+#define EF_SH4_NOMMU_NOFPU 0x12
-+#define EF_SH2A_NOFPU 0x13
-+#define EF_SH3_NOMMU 0x14
-+#define EF_SH2A_SH4_NOFPU 0x15
-+#define EF_SH2A_SH3_NOFPU 0x16
-+#define EF_SH2A_SH4 0x17
-+#define EF_SH2A_SH3E 0x18
-+
-+/* SH relocs. */
-+#define R_SH_NONE 0
-+#define R_SH_DIR32 1
-+#define R_SH_REL32 2
-+#define R_SH_DIR8WPN 3
-+#define R_SH_IND12W 4
-+#define R_SH_DIR8WPL 5
-+#define R_SH_DIR8WPZ 6
-+#define R_SH_DIR8BP 7
-+#define R_SH_DIR8W 8
-+#define R_SH_DIR8L 9
-+#define R_SH_SWITCH16 25
-+#define R_SH_SWITCH32 26
-+#define R_SH_USES 27
-+#define R_SH_COUNT 28
-+#define R_SH_ALIGN 29
-+#define R_SH_CODE 30
-+#define R_SH_DATA 31
-+#define R_SH_LABEL 32
-+#define R_SH_SWITCH8 33
-+#define R_SH_GNU_VTINHERIT 34
-+#define R_SH_GNU_VTENTRY 35
-+#define R_SH_TLS_GD_32 144
-+#define R_SH_TLS_LD_32 145
-+#define R_SH_TLS_LDO_32 146
-+#define R_SH_TLS_IE_32 147
-+#define R_SH_TLS_LE_32 148
-+#define R_SH_TLS_DTPMOD32 149
-+#define R_SH_TLS_DTPOFF32 150
-+#define R_SH_TLS_TPOFF32 151
-+#define R_SH_GOT32 160
-+#define R_SH_PLT32 161
-+#define R_SH_COPY 162
-+#define R_SH_GLOB_DAT 163
-+#define R_SH_JMP_SLOT 164
-+#define R_SH_RELATIVE 165
-+#define R_SH_GOTOFF 166
-+#define R_SH_GOTPC 167
-+/* Keep this the last entry. */
-+#define R_SH_NUM 256
-+
-+/* S/390 specific definitions. */
-+
-+/* Valid values for the e_flags field. */
-+
-+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */
-+
-+/* Additional s390 relocs */
-+
-+#define R_390_NONE 0 /* No reloc. */
-+#define R_390_8 1 /* Direct 8 bit. */
-+#define R_390_12 2 /* Direct 12 bit. */
-+#define R_390_16 3 /* Direct 16 bit. */
-+#define R_390_32 4 /* Direct 32 bit. */
-+#define R_390_PC32 5 /* PC relative 32 bit. */
-+#define R_390_GOT12 6 /* 12 bit GOT offset. */
-+#define R_390_GOT32 7 /* 32 bit GOT offset. */
-+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
-+#define R_390_COPY 9 /* Copy symbol at runtime. */
-+#define R_390_GLOB_DAT 10 /* Create GOT entry. */
-+#define R_390_JMP_SLOT 11 /* Create PLT entry. */
-+#define R_390_RELATIVE 12 /* Adjust by program base. */
-+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
-+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */
-+#define R_390_GOT16 15 /* 16 bit GOT offset. */
-+#define R_390_PC16 16 /* PC relative 16 bit. */
-+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
-+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
-+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
-+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
-+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
-+#define R_390_64 22 /* Direct 64 bit. */
-+#define R_390_PC64 23 /* PC relative 64 bit. */
-+#define R_390_GOT64 24 /* 64 bit GOT offset. */
-+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
-+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
-+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
-+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
-+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
-+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
-+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
-+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
-+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
-+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
-+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
-+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
-+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
-+#define R_390_TLS_GDCALL 38 /* Tag for function call in general
-+ dynamic TLS code. */
-+#define R_390_TLS_LDCALL 39 /* Tag for function call in local
-+ dynamic TLS code. */
-+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
-+ thread local data. */
-+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
-+ thread local data. */
-+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
-+ thread local data in LE code. */
-+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
-+ thread local data in LE code. */
-+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
-+ negated static TLS block offset. */
-+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
-+ negated static TLS block offset. */
-+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
-+ negated static TLS block offset. */
-+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
-+ static TLS block. */
-+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
-+ static TLS block. */
-+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
-+ block. */
-+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
-+ block. */
-+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
-+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
-+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
-+ block. */
-+#define R_390_20 57 /* Direct 20 bit. */
-+#define R_390_GOT20 58 /* 20 bit GOT offset. */
-+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
-+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
-+ block offset. */
-+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */
-+/* Keep this the last entry. */
-+#define R_390_NUM 62
-+
-+
-+/* CRIS relocations. */
-+#define R_CRIS_NONE 0
-+#define R_CRIS_8 1
-+#define R_CRIS_16 2
-+#define R_CRIS_32 3
-+#define R_CRIS_8_PCREL 4
-+#define R_CRIS_16_PCREL 5
-+#define R_CRIS_32_PCREL 6
-+#define R_CRIS_GNU_VTINHERIT 7
-+#define R_CRIS_GNU_VTENTRY 8
-+#define R_CRIS_COPY 9
-+#define R_CRIS_GLOB_DAT 10
-+#define R_CRIS_JUMP_SLOT 11
-+#define R_CRIS_RELATIVE 12
-+#define R_CRIS_16_GOT 13
-+#define R_CRIS_32_GOT 14
-+#define R_CRIS_16_GOTPLT 15
-+#define R_CRIS_32_GOTPLT 16
-+#define R_CRIS_32_GOTREL 17
-+#define R_CRIS_32_PLT_GOTREL 18
-+#define R_CRIS_32_PLT_PCREL 19
-+
-+#define R_CRIS_NUM 20
-+
-+
-+/* AMD x86-64 relocations. */
-+#define R_X86_64_NONE 0 /* No reloc */
-+#define R_X86_64_64 1 /* Direct 64 bit */
-+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
-+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
-+#define R_X86_64_PLT32 4 /* 32 bit PLT address */
-+#define R_X86_64_COPY 5 /* Copy symbol at runtime */
-+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
-+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
-+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
-+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative
-+ offset to GOT */
-+#define R_X86_64_32 10 /* Direct 32 bit zero extended */
-+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
-+#define R_X86_64_16 12 /* Direct 16 bit zero extended */
-+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
-+#define R_X86_64_8 14 /* Direct 8 bit sign extended */
-+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
-+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
-+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
-+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
-+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset
-+ to two GOT entries for GD symbol */
-+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset
-+ to two GOT entries for LD symbol */
-+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
-+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
-+ to GOT entry for IE symbol */
-+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
-+#define R_X86_64_PC64 24 /* PC relative 64 bit */
-+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
-+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative
-+ offset to GOT */
-+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
-+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset
-+ to GOT entry */
-+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
-+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
-+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset
-+ to PLT entry */
-+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
-+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
-+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
-+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS
-+ descriptor. */
-+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
-+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
-+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
-+
-+#define R_X86_64_NUM 39
-+
-+
-+/* AM33 relocations. */
-+#define R_MN10300_NONE 0 /* No reloc. */
-+#define R_MN10300_32 1 /* Direct 32 bit. */
-+#define R_MN10300_16 2 /* Direct 16 bit. */
-+#define R_MN10300_8 3 /* Direct 8 bit. */
-+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */
-+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */
-+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */
-+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */
-+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */
-+#define R_MN10300_24 9 /* Direct 24 bit. */
-+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */
-+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */
-+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */
-+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */
-+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */
-+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */
-+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */
-+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */
-+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */
-+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */
-+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */
-+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */
-+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */
-+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */
-+
-+#define R_MN10300_NUM 24
-+
-+
-+/* M32R relocs. */
-+#define R_M32R_NONE 0 /* No reloc. */
-+#define R_M32R_16 1 /* Direct 16 bit. */
-+#define R_M32R_32 2 /* Direct 32 bit. */
-+#define R_M32R_24 3 /* Direct 24 bit. */
-+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */
-+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */
-+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */
-+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */
-+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */
-+#define R_M32R_LO16 9 /* Low 16 bit. */
-+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */
-+#define R_M32R_GNU_VTINHERIT 11
-+#define R_M32R_GNU_VTENTRY 12
-+/* M32R relocs use SHT_RELA. */
-+#define R_M32R_16_RELA 33 /* Direct 16 bit. */
-+#define R_M32R_32_RELA 34 /* Direct 32 bit. */
-+#define R_M32R_24_RELA 35 /* Direct 24 bit. */
-+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */
-+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */
-+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */
-+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */
-+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */
-+#define R_M32R_LO16_RELA 41 /* Low 16 bit */
-+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */
-+#define R_M32R_RELA_GNU_VTINHERIT 43
-+#define R_M32R_RELA_GNU_VTENTRY 44
-+#define R_M32R_REL32 45 /* PC relative 32 bit. */
-+
-+#define R_M32R_GOT24 48 /* 24 bit GOT entry */
-+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */
-+#define R_M32R_COPY 50 /* Copy symbol at runtime */
-+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */
-+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */
-+#define R_M32R_RELATIVE 53 /* Adjust by program base */
-+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */
-+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */
-+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned
-+ low */
-+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed
-+ low */
-+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */
-+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to
-+ GOT with unsigned low */
-+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to
-+ GOT with signed low */
-+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to
-+ GOT */
-+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT
-+ with unsigned low */
-+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT
-+ with signed low */
-+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */
-+#define R_M32R_NUM 256 /* Keep this the last entry. */
-+
-+
-+/* TILEPro relocations. */
-+#define R_TILEPRO_NONE 0 /* No reloc */
-+#define R_TILEPRO_32 1 /* Direct 32 bit */
-+#define R_TILEPRO_16 2 /* Direct 16 bit */
-+#define R_TILEPRO_8 3 /* Direct 8 bit */
-+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */
-+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */
-+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */
-+#define R_TILEPRO_LO16 7 /* Low 16 bit */
-+#define R_TILEPRO_HI16 8 /* High 16 bit */
-+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */
-+#define R_TILEPRO_COPY 10 /* Copy relocation */
-+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */
-+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */
-+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */
-+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */
-+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */
-+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */
-+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */
-+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */
-+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */
-+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */
-+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */
-+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */
-+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */
-+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */
-+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */
-+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */
-+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */
-+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */
-+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */
-+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */
-+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */
-+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */
-+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */
-+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */
-+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */
-+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */
-+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */
-+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */
-+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */
-+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */
-+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */
-+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */
-+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */
-+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */
-+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */
-+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */
-+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */
-+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */
-+/* Relocs 56-59 are currently not defined. */
-+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */
-+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */
-+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */
-+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */
-+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */
-+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */
-+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */
-+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */
-+
-+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
-+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
-+
-+#define R_TILEPRO_NUM 130
-+
-+
-+/* TILE-Gx relocations. */
-+#define R_TILEGX_NONE 0 /* No reloc */
-+#define R_TILEGX_64 1 /* Direct 64 bit */
-+#define R_TILEGX_32 2 /* Direct 32 bit */
-+#define R_TILEGX_16 3 /* Direct 16 bit */
-+#define R_TILEGX_8 4 /* Direct 8 bit */
-+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */
-+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */
-+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */
-+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */
-+#define R_TILEGX_HW0 9 /* hword 0 16-bit */
-+#define R_TILEGX_HW1 10 /* hword 1 16-bit */
-+#define R_TILEGX_HW2 11 /* hword 2 16-bit */
-+#define R_TILEGX_HW3 12 /* hword 3 16-bit */
-+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */
-+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */
-+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */
-+#define R_TILEGX_COPY 16 /* Copy relocation */
-+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */
-+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */
-+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */
-+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */
-+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */
-+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */
-+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */
-+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */
-+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */
-+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */
-+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */
-+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */
-+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */
-+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */
-+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */
-+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */
-+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */
-+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */
-+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */
-+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */
-+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */
-+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */
-+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */
-+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */
-+/* Relocs 66-71 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
-+/* Relocs 76-77 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
-+/* Relocs 90-91 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */
-+/* Relocs 94-99 are currently not defined. */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
-+/* Relocs 104-105 are currently not defined. */
-+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */
-+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */
-+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */
-+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */
-+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */
-+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */
-+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */
-+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */
-+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */
-+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */
-+
-+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
-+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
-+
-+#define R_TILEGX_NUM 130
-+
-+#endif /* elf.h */
---- a/scripts/mod/mk_elfconfig.c
-+++ b/scripts/mod/mk_elfconfig.c
-@@ -2,7 +2,11 @@
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-+#ifndef __APPLE__
- #include <elf.h>
-+#else
-+#include "elf.h"
-+#endif
-
- int
- main(int argc, char **argv)
---- a/scripts/mod/modpost.h
-+++ b/scripts/mod/modpost.h
-@@ -9,7 +9,11 @@
- #include <sys/mman.h>
- #include <fcntl.h>
- #include <unistd.h>
-+#if !(defined(__APPLE__) || defined(__CYGWIN__))
- #include <elf.h>
-+#else
-+#include "elf.h"
-+#endif
-
- #include "list.h"
- #include "elfconfig.h"
diff --git a/target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch b/target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch
deleted file mode 100644
index 50a6227148..0000000000
--- a/target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001
-From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
-Date: Wed, 5 Feb 2020 18:36:43 +0000
-Subject: [PATCH] file2alias: build on macos
-
-Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
----
- scripts/mod/file2alias.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/scripts/mod/file2alias.c
-+++ b/scripts/mod/file2alias.c
-@@ -38,6 +38,9 @@ typedef struct {
- __u8 b[16];
- } guid_t;
-
-+#ifdef __APPLE__
-+#define uuid_t compat_uuid_t
-+#endif
- /* backwards compatibility, don't use in new code */
- typedef struct {
- __u8 b[16];
diff --git a/target/linux/generic/hack-6.1/212-tools_portability.patch b/target/linux/generic/hack-6.1/212-tools_portability.patch
deleted file mode 100644
index 3ee4393006..0000000000
--- a/target/linux/generic/hack-6.1/212-tools_portability.patch
+++ /dev/null
@@ -1,360 +0,0 @@
-From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:03:16 +0200
-Subject: fix portability of some includes files in tools/ used on the host
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- tools/include/tools/be_byteshift.h | 4 ++++
- tools/include/tools/le_byteshift.h | 4 ++++
- tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++
- 3 files changed, 30 insertions(+)
- create mode 100644 tools/include/tools/linux_types.h
-
---- a/tools/include/tools/be_byteshift.h
-+++ b/tools/include/tools/be_byteshift.h
-@@ -2,6 +2,10 @@
- #ifndef _TOOLS_BE_BYTESHIFT_H
- #define _TOOLS_BE_BYTESHIFT_H
-
-+#ifndef __linux__
-+#include "linux_types.h"
-+#endif
-+
- #include <stdint.h>
-
- static inline uint16_t __get_unaligned_be16(const uint8_t *p)
---- a/tools/include/tools/le_byteshift.h
-+++ b/tools/include/tools/le_byteshift.h
-@@ -2,6 +2,10 @@
- #ifndef _TOOLS_LE_BYTESHIFT_H
- #define _TOOLS_LE_BYTESHIFT_H
-
-+#ifndef __linux__
-+#include "linux_types.h"
-+#endif
-+
- #include <stdint.h>
-
- static inline uint16_t __get_unaligned_le16(const uint8_t *p)
---- /dev/null
-+++ b/tools/include/tools/linux_types.h
-@@ -0,0 +1,18 @@
-+#ifndef __LINUX_TYPES_H
-+#define __LINUX_TYPES_H
-+
-+#include <stdint.h>
-+
-+typedef int8_t __s8;
-+typedef uint8_t __u8;
-+
-+typedef int16_t __s16;
-+typedef uint16_t __u16;
-+
-+typedef int32_t __s32;
-+typedef uint32_t __u32;
-+
-+typedef int64_t __s64;
-+typedef uint64_t __u64;
-+
-+#endif
---- a/tools/include/linux/types.h
-+++ b/tools/include/linux/types.h
-@@ -10,8 +10,12 @@
- #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */
- #endif
-
-+#ifndef __linux__
-+#include <tools/linux_types.h>
-+#else
- #include <asm/types.h>
- #include <asm/posix_types.h>
-+#endif
-
- struct page;
- struct kmem_cache;
-@@ -51,7 +55,9 @@ typedef __s8 s8;
- #define __force
- #define __user
- #define __must_check
-+#ifndef __cold
- #define __cold
-+#endif
-
- typedef __u16 __bitwise __le16;
- typedef __u16 __bitwise __be16;
---- a/tools/perf/pmu-events/jevents.py
-+++ b/tools/perf/pmu-events/jevents.py
-@@ -684,6 +684,7 @@ def main() -> None:
- #include "util/header.h"
- #include "util/pmu.h"
- #include <string.h>
-+#include <strings.h>
- #include <stddef.h>
-
- struct compact_pmu_event {
---- a/tools/arch/x86/include/asm/insn.h
-+++ b/tools/arch/x86/include/asm/insn.h
-@@ -7,8 +7,8 @@
- * Copyright (C) IBM Corporation, 2009
- */
-
--#include <asm/byteorder.h>
- /* insn_attr_t is defined in inat.h */
-+#include <linux/kernel.h>
- #include "inat.h" /* __ignore_sync_check__ */
-
- #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
---- a/tools/arch/x86/include/asm/orc_types.h
-+++ b/tools/arch/x86/include/asm/orc_types.h
-@@ -40,7 +40,6 @@
- #define ORC_REG_MAX 15
-
- #ifndef __ASSEMBLY__
--#include <asm/byteorder.h>
-
- /*
- * This struct is more or less a vastly simplified version of the DWARF Call
-@@ -53,12 +52,12 @@
- struct orc_entry {
- s16 sp_offset;
- s16 bp_offset;
--#if defined(__LITTLE_ENDIAN_BITFIELD)
-+#if __BYTE_ORDER == __LITTLE_ENDIAN
- unsigned sp_reg:4;
- unsigned bp_reg:4;
- unsigned type:2;
- unsigned end:1;
--#elif defined(__BIG_ENDIAN_BITFIELD)
-+#elif __BYTE_ORDER == __BIG_ENDIAN
- unsigned bp_reg:4;
- unsigned sp_reg:4;
- unsigned unused:5;
---- a/tools/arch/x86/lib/insn.c
-+++ b/tools/arch/x86/lib/insn.c
-@@ -15,7 +15,11 @@
- #include "../include/asm/insn.h" /* __ignore_sync_check__ */
- #include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */
-
-+#ifdef __KERNEL__
- #include <linux/errno.h>
-+#else
-+#include <errno.h>
-+#endif
- #include <linux/kconfig.h>
-
- #include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */
---- a/tools/include/asm-generic/bitops/fls.h
-+++ b/tools/include/asm-generic/bitops/fls.h
-@@ -2,6 +2,8 @@
- #ifndef _ASM_GENERIC_BITOPS_FLS_H_
- #define _ASM_GENERIC_BITOPS_FLS_H_
-
-+#include <string.h>
-+
- /**
- * fls - find last (most-significant) bit set
- * @x: the word to search
-@@ -10,7 +12,7 @@
- * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
- */
-
--static __always_inline int fls(unsigned int x)
-+static __always_inline int __generic_fls(unsigned int x)
- {
- int r = 32;
-
-@@ -38,5 +40,6 @@ static __always_inline int fls(unsigned
- }
- return r;
- }
-+#define fls __generic_fls
-
- #endif /* _ASM_GENERIC_BITOPS_FLS_H_ */
---- a/tools/include/asm-generic/bitsperlong.h
-+++ b/tools/include/asm-generic/bitsperlong.h
-@@ -4,11 +4,13 @@
-
- #include <uapi/asm-generic/bitsperlong.h>
-
-+#ifndef BITS_PER_LONG
- #ifdef __SIZEOF_LONG__
- #define BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__)
- #else
- #define BITS_PER_LONG __WORDSIZE
- #endif
-+#endif
-
- #if BITS_PER_LONG != __BITS_PER_LONG
- #error Inconsistent word size. Check asm/bitsperlong.h
---- a/tools/include/linux/rbtree.h
-+++ b/tools/include/linux/rbtree.h
-@@ -18,7 +18,6 @@
- #define __TOOLS_LINUX_PERF_RBTREE_H
-
- #include <linux/kernel.h>
--#include <linux/stddef.h>
-
- struct rb_node {
- unsigned long __rb_parent_color;
---- a/tools/objtool/Makefile
-+++ b/tools/objtool/Makefile
-@@ -4,7 +4,7 @@ include ../scripts/Makefile.arch
-
- # always use the host compiler
- AR = $(HOSTAR)
--CC = $(HOSTCC)
-+CC = $(HOSTCC) $(HOST_EXTRACFLAGS)
- LD = $(HOSTLD)
-
- ifeq ($(srctree),)
-@@ -43,6 +43,7 @@ BUILD_ORC := n
-
- ifeq ($(SRCARCH),x86)
- BUILD_ORC := y
-+ CFLAGS += -DBUILD_ORC
- endif
-
- export BUILD_ORC
---- a/tools/objtool/check.c
-+++ b/tools/objtool/check.c
-@@ -1164,11 +1164,12 @@ static int add_ignore_alternatives(struc
- return 0;
- }
-
-+#ifndef BUILD_ORC
- /*
- * Symbols that replace INSN_CALL_DYNAMIC, every (tail) call to such a symbol
- * will be added to the .retpoline_sites section.
- */
--__weak bool arch_is_retpoline(struct symbol *sym)
-+bool arch_is_retpoline(struct symbol *sym)
- {
- return false;
- }
-@@ -1177,7 +1178,7 @@ __weak bool arch_is_retpoline(struct sym
- * Symbols that replace INSN_RETURN, every (tail) call to such a symbol
- * will be added to the .return_sites section.
- */
--__weak bool arch_is_rethunk(struct symbol *sym)
-+bool arch_is_rethunk(struct symbol *sym)
- {
- return false;
- }
-@@ -1186,10 +1187,11 @@ __weak bool arch_is_rethunk(struct symbo
- * Symbols that are embedded inside other instructions, because sometimes crazy
- * code exists. These are mostly ignored for validation purposes.
- */
--__weak bool arch_is_embedded_insn(struct symbol *sym)
-+bool arch_is_embedded_insn(struct symbol *sym)
- {
- return false;
- }
-+#endif
-
- #define NEGATIVE_RELOC ((void *)-1L)
-
---- a/tools/objtool/include/objtool/objtool.h
-+++ b/tools/objtool/include/objtool/objtool.h
-@@ -12,7 +12,9 @@
-
- #include <objtool/elf.h>
-
-+#ifndef __weak
- #define __weak __attribute__((weak))
-+#endif
-
- struct pv_state {
- bool clean;
---- a/tools/objtool/orc_dump.c
-+++ b/tools/objtool/orc_dump.c
-@@ -5,10 +5,10 @@
-
- #include <unistd.h>
- #include <linux/objtool.h>
--#include <asm/orc_types.h>
- #include <objtool/objtool.h>
- #include <objtool/warn.h>
- #include <objtool/endianness.h>
-+#include <asm/orc_types.h>
-
- static const char *reg_name(unsigned int reg)
- {
---- a/tools/objtool/orc_gen.c
-+++ b/tools/objtool/orc_gen.c
-@@ -7,11 +7,11 @@
- #include <string.h>
-
- #include <linux/objtool.h>
--#include <asm/orc_types.h>
-
- #include <objtool/check.h>
- #include <objtool/warn.h>
- #include <objtool/endianness.h>
-+#include <asm/orc_types.h>
-
- static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
- struct instruction *insn)
---- a/tools/objtool/special.c
-+++ b/tools/objtool/special.c
-@@ -54,9 +54,11 @@ struct special_entry entries[] = {
- {},
- };
-
--void __weak arch_handle_alternative(unsigned short feature, struct special_alt *alt)
-+#ifndef BUILD_ORC
-+void arch_handle_alternative(unsigned short feature, struct special_alt *alt)
- {
- }
-+#endif
-
- static void reloc_to_sec_off(struct reloc *reloc, struct section **sec,
- unsigned long *off)
---- a/tools/objtool/weak.c
-+++ b/tools/objtool/weak.c
-@@ -15,12 +15,14 @@
- return ENOSYS; \
- })
-
--int __weak orc_dump(const char *_objname)
-+#ifndef BUILD_ORC
-+int orc_dump(const char *_objname)
- {
- UNSUPPORTED("ORC");
- }
-
--int __weak orc_create(struct objtool_file *file)
-+int orc_create(struct objtool_file *file)
- {
- UNSUPPORTED("ORC");
- }
-+#endif
---- a/tools/scripts/Makefile.include
-+++ b/tools/scripts/Makefile.include
-@@ -92,7 +92,7 @@ LLVM_OBJCOPY ?= llvm-objcopy
- LLVM_STRIP ?= llvm-strip
-
- ifeq ($(CC_NO_CLANG), 1)
--EXTRA_WARNINGS += -Wstrict-aliasing=3
-+# EXTRA_WARNINGS += -Wstrict-aliasing=3
-
- else ifneq ($(CROSS_COMPILE),)
- # Allow userspace to override CLANG_CROSS_FLAGS to specify their own
---- a/tools/lib/string.c
-+++ b/tools/lib/string.c
-@@ -100,6 +100,7 @@ int strtobool(const char *s, bool *res)
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wignored-attributes"
- #endif
-+#ifndef __APPLE__
- size_t __weak strlcpy(char *dest, const char *src, size_t size)
- {
- size_t ret = strlen(src);
-@@ -111,6 +112,7 @@ size_t __weak strlcpy(char *dest, const
- }
- return ret;
- }
-+#endif
- #ifdef __clang__
- #pragma clang diagnostic pop
- #endif
diff --git a/target/linux/generic/hack-6.1/214-spidev_h_portability.patch b/target/linux/generic/hack-6.1/214-spidev_h_portability.patch
deleted file mode 100644
index db754a2903..0000000000
--- a/target/linux/generic/hack-6.1/214-spidev_h_portability.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:04:08 +0200
-Subject: kernel: fix linux/spi/spidev.h portability issues with musl
-
-Felix will try to get this define included into musl
-
-lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/uapi/linux/spi/spidev.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/uapi/linux/spi/spidev.h
-+++ b/include/uapi/linux/spi/spidev.h
-@@ -93,7 +93,7 @@ struct spi_ioc_transfer {
-
- /* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
- #define SPI_MSGSIZE(N) \
-- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
-+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \
- ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
- #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
-
diff --git a/target/linux/generic/hack-6.1/220-arm-gc_sections.patch b/target/linux/generic/hack-6.1/220-arm-gc_sections.patch
deleted file mode 100644
index a6a6c7cf2c..0000000000
--- a/target/linux/generic/hack-6.1/220-arm-gc_sections.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 15 Jul 2017 23:42:36 +0200
-Subject: use -ffunction-sections, -fdata-sections and --gc-sections
-
-In combination with kernel symbol export stripping this significantly reduces
-the kernel image size. Used on both ARM and MIPS architectures.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -124,6 +124,7 @@ config ARM
- select HAVE_VIRT_CPU_ACCOUNTING_GEN
- select IRQ_FORCED_THREADING
- select LOCK_MM_AND_FIND_VMA
-+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
- select MODULES_USE_ELF_REL
- select NEED_DMA_MAP_STATE
- select OF_EARLY_FLATTREE if OF
---- a/arch/arm/boot/compressed/Makefile
-+++ b/arch/arm/boot/compressed/Makefile
-@@ -91,6 +91,7 @@ endif
- ifeq ($(CONFIG_USE_OF),y)
- OBJS += $(libfdt_objs) fdt_check_mem_start.o
- endif
-+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL))
-
- OBJS += lib1funcs.o ashldi3.o bswapsdi2.o
-
---- a/arch/arm/kernel/vmlinux.lds.S
-+++ b/arch/arm/kernel/vmlinux.lds.S
-@@ -75,7 +75,7 @@ SECTIONS
- . = ALIGN(4);
- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
- __start___ex_table = .;
-- ARM_MMU_KEEP(*(__ex_table))
-+ KEEP(*(__ex_table))
- __stop___ex_table = .;
- }
-
-@@ -100,24 +100,24 @@ SECTIONS
- }
- .init.arch.info : {
- __arch_info_begin = .;
-- *(.arch.info.init)
-+ KEEP(*(.arch.info.init))
- __arch_info_end = .;
- }
- .init.tagtable : {
- __tagtable_begin = .;
-- *(.taglist.init)
-+ KEEP(*(.taglist.init))
- __tagtable_end = .;
- }
- #ifdef CONFIG_SMP_ON_UP
- .init.smpalt : {
- __smpalt_begin = .;
-- *(.alt.smp.init)
-+ KEEP(*(.alt.smp.init))
- __smpalt_end = .;
- }
- #endif
- .init.pv_table : {
- __pv_table_begin = .;
-- *(.pv_table)
-+ KEEP(*(.pv_table))
- __pv_table_end = .;
- }
-
---- a/arch/arm/include/asm/vmlinux.lds.h
-+++ b/arch/arm/include/asm/vmlinux.lds.h
-@@ -42,13 +42,13 @@
- #define PROC_INFO \
- . = ALIGN(4); \
- __proc_info_begin = .; \
-- *(.proc.info.init) \
-+ KEEP(*(.proc.info.init)) \
- __proc_info_end = .;
-
- #define IDMAP_TEXT \
- ALIGN_FUNCTION(); \
- __idmap_text_start = .; \
-- *(.idmap.text) \
-+ KEEP(*(.idmap.text)) \
- __idmap_text_end = .; \
-
- #define ARM_DISCARD \
-@@ -109,12 +109,12 @@
- . = ALIGN(8); \
- .ARM.unwind_idx : { \
- __start_unwind_idx = .; \
-- *(.ARM.exidx*) \
-+ KEEP(*(.ARM.exidx*)) \
- __stop_unwind_idx = .; \
- } \
- .ARM.unwind_tab : { \
- __start_unwind_tab = .; \
-- *(.ARM.extab*) \
-+ KEEP(*(.ARM.extab*)) \
- __stop_unwind_tab = .; \
- }
-
-@@ -126,7 +126,7 @@
- __vectors_lma = .; \
- OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
- .vectors { \
-- *(.vectors) \
-+ KEEP(*(.vectors)) \
- } \
- .vectors.bhb.loop8 { \
- *(.vectors.bhb.loop8) \
-@@ -144,7 +144,7 @@
- \
- __stubs_lma = .; \
- .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
-- *(.stubs) \
-+ KEEP(*(.stubs)) \
- } \
- ARM_LMA(__stubs, .stubs); \
- . = __stubs_lma + SIZEOF(.stubs); \
diff --git a/target/linux/generic/hack-6.1/221-module_exports.patch b/target/linux/generic/hack-6.1/221-module_exports.patch
deleted file mode 100644
index 573eeb15d7..0000000000
--- a/target/linux/generic/hack-6.1/221-module_exports.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:05:53 +0200
-Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image
-
-lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++---
- include/linux/export.h | 9 ++++++++-
- scripts/Makefile.build | 2 +-
- 3 files changed, 24 insertions(+), 5 deletions(-)
-
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -81,6 +81,16 @@
- #define RO_EXCEPTION_TABLE
- #endif
-
-+#ifndef SYMTAB_KEEP
-+#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*)))
-+#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*)))
-+#endif
-+
-+#ifndef SYMTAB_DISCARD
-+#define SYMTAB_DISCARD
-+#define SYMTAB_DISCARD_GPL
-+#endif
-+
- /* Align . to a 8 byte boundary equals to maximum function alignment. */
- #define ALIGN_FUNCTION() . = ALIGN(8)
-
-@@ -511,14 +521,14 @@
- /* Kernel symbol table: Normal symbols */ \
- __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
- __start___ksymtab = .; \
-- KEEP(*(SORT(___ksymtab+*))) \
-+ SYMTAB_KEEP \
- __stop___ksymtab = .; \
- } \
- \
- /* Kernel symbol table: GPL-only symbols */ \
- __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
- __start___ksymtab_gpl = .; \
-- KEEP(*(SORT(___ksymtab_gpl+*))) \
-+ SYMTAB_KEEP_GPL \
- __stop___ksymtab_gpl = .; \
- } \
- \
-@@ -538,7 +548,7 @@
- \
- /* Kernel symbol table: strings */ \
- __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
-- *(__ksymtab_strings) \
-+ *(__ksymtab_strings+*) \
- } \
- \
- /* __*init sections */ \
-@@ -1042,6 +1052,8 @@
- #define COMMON_DISCARDS \
- SANITIZER_DISCARDS \
- PATCHABLE_DISCARDS \
-+ SYMTAB_DISCARD \
-+ SYMTAB_DISCARD_GPL \
- *(.discard) \
- *(.discard.*) \
- *(.modinfo) \
---- a/include/linux/export.h
-+++ b/include/linux/export.h
-@@ -72,6 +72,12 @@ struct kernel_symbol {
-
- #else
-
-+#ifdef MODULE
-+#define __EXPORT_SUFFIX(sym)
-+#else
-+#define __EXPORT_SUFFIX(sym) "+" #sym
-+#endif
-+
- /*
- * For every exported symbol, do the following:
- *
-@@ -87,7 +93,7 @@ struct kernel_symbol {
- extern typeof(sym) sym; \
- extern const char __kstrtab_##sym[]; \
- extern const char __kstrtabns_##sym[]; \
-- asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
-+ asm(" .section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1 \n" \
- "__kstrtab_" #sym ": \n" \
- " .asciz \"" #sym "\" \n" \
- "__kstrtabns_" #sym ": \n" \
---- a/include/asm-generic/export.h
-+++ b/include/asm-generic/export.h
-@@ -31,6 +31,12 @@
- #endif
- .endm
-
-+#ifdef MODULE
-+#define __EXPORT_SUFFIX(name)
-+#else
-+#define __EXPORT_SUFFIX(name) + #name
-+#endif
-+
- /*
- * note on .section use: we specify progbits since usage of the "M" (SHF_MERGE)
- * section flag requires it. Use '%progbits' instead of '@progbits' since the
-@@ -44,7 +50,7 @@
- __ksymtab_\name:
- __put \val, __kstrtab_\name
- .previous
-- .section __ksymtab_strings,"aMS",%progbits,1
-+ .section __ksymtab_strings __EXPORT_SUFFIX(name),"aMS",%progbits,1
- __kstrtab_\name:
- .asciz "\name"
- .previous
---- a/scripts/Makefile.build
-+++ b/scripts/Makefile.build
-@@ -391,7 +391,7 @@ targets += $(real-dtb-y) $(lib-y) $(alwa
- # Linker scripts preprocessor (.lds.S -> .lds)
- # ---------------------------------------------------------------------------
- quiet_cmd_cpp_lds_S = LDS $@
-- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
-+ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \
- -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
-
- $(obj)/%.lds: $(src)/%.lds.S FORCE
diff --git a/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch b/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch
deleted file mode 100644
index 55530c5c7e..0000000000
--- a/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001
-From: Imre Kaloz <kaloz@openwrt.org>
-Date: Fri, 7 Jul 2017 17:06:55 +0200
-Subject: use the openwrt lzma options for now
-
-lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- lib/decompress.c | 1 +
- scripts/Makefile.lib | 2 +-
- usr/gen_initramfs_list.sh | 10 +++++-----
- 3 files changed, 7 insertions(+), 6 deletions(-)
-
---- a/lib/decompress.c
-+++ b/lib/decompress.c
-@@ -53,6 +53,7 @@ static const struct compress_format comp
- { {0x1f, 0x9e}, "gzip", gunzip },
- { {0x42, 0x5a}, "bzip2", bunzip2 },
- { {0x5d, 0x00}, "lzma", unlzma },
-+ { {0x6d, 0x00}, "lzma-openwrt", unlzma },
- { {0xfd, 0x37}, "xz", unxz },
- { {0x89, 0x4c}, "lzo", unlzo },
- { {0x02, 0x21}, "lz4", unlz4 },
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -443,10 +443,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
- # ---------------------------------------------------------------------------
-
- quiet_cmd_lzma = LZMA $@
-- cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@
-+ cmd_lzma = cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so > $@
-
- quiet_cmd_lzma_with_size = LZMA $@
-- cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
-+ cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@
-
- quiet_cmd_lzo = LZO $@
- cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@
diff --git a/target/linux/generic/hack-6.1/250-netfilter_depends.patch b/target/linux/generic/hack-6.1/250-netfilter_depends.patch
deleted file mode 100644
index fbb5a61157..0000000000
--- a/target/linux/generic/hack-6.1/250-netfilter_depends.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: hack: net: remove bogus netfilter dependencies
-
-lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/netfilter/Kconfig | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -253,7 +253,6 @@ config NF_CONNTRACK_FTP
-
- config NF_CONNTRACK_H323
- tristate "H.323 protocol support"
-- depends on IPV6 || IPV6=n
- depends on NETFILTER_ADVANCED
- help
- H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -1118,7 +1117,6 @@ config NETFILTER_XT_TARGET_SECMARK
-
- config NETFILTER_XT_TARGET_TCPMSS
- tristate '"TCPMSS" target support'
-- depends on IPV6 || IPV6=n
- default m if NETFILTER_ADVANCED=n
- help
- This option adds a `TCPMSS' target, which allows you to alter the
diff --git a/target/linux/generic/hack-6.1/251-kconfig.patch b/target/linux/generic/hack-6.1/251-kconfig.patch
deleted file mode 100644
index fcf4eaf6e8..0000000000
--- a/target/linux/generic/hack-6.1/251-kconfig.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 7 Jul 2017 17:09:21 +0200
-Subject: kconfig: owrt specifc dependencies
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- crypto/Kconfig | 10 +++++-----
- drivers/bcma/Kconfig | 1 +
- drivers/ssb/Kconfig | 3 ++-
- lib/Kconfig | 8 ++++----
- net/netfilter/Kconfig | 2 +-
- net/wireless/Kconfig | 17 ++++++++++-------
- sound/core/Kconfig | 4 ++--
- 7 files changed, 25 insertions(+), 20 deletions(-)
-
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -55,7 +55,7 @@ config CRYPTO_FIPS_VERSION
- By default the KERNELRELEASE value is used.
-
- config CRYPTO_ALGAPI
-- tristate
-+ tristate "ALGAPI"
- select CRYPTO_ALGAPI2
- help
- This option provides the API for cryptographic algorithms.
-@@ -64,7 +64,7 @@ config CRYPTO_ALGAPI2
- tristate
-
- config CRYPTO_AEAD
-- tristate
-+ tristate "AEAD"
- select CRYPTO_AEAD2
- select CRYPTO_ALGAPI
-
-@@ -75,7 +75,7 @@ config CRYPTO_AEAD2
- select CRYPTO_RNG2
-
- config CRYPTO_SKCIPHER
-- tristate
-+ tristate "SKCIPHER"
- select CRYPTO_SKCIPHER2
- select CRYPTO_ALGAPI
-
-@@ -85,7 +85,7 @@ config CRYPTO_SKCIPHER2
- select CRYPTO_RNG2
-
- config CRYPTO_HASH
-- tristate
-+ tristate "HASH"
- select CRYPTO_HASH2
- select CRYPTO_ALGAPI
-
-@@ -94,7 +94,7 @@ config CRYPTO_HASH2
- select CRYPTO_ALGAPI2
-
- config CRYPTO_RNG
-- tristate
-+ tristate "RNG"
- select CRYPTO_RNG2
- select CRYPTO_ALGAPI
-
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -16,6 +16,7 @@ if BCMA
- # Support for Block-I/O. SELECT this from the driver that needs it.
- config BCMA_BLOCKIO
- bool
-+ default y
-
- config BCMA_HOST_PCI_POSSIBLE
- bool
---- a/drivers/ssb/Kconfig
-+++ b/drivers/ssb/Kconfig
-@@ -29,6 +29,7 @@ config SSB_SPROM
- config SSB_BLOCKIO
- bool
- depends on SSB
-+ default y
-
- config SSB_PCIHOST_POSSIBLE
- bool
-@@ -49,7 +50,7 @@ config SSB_PCIHOST
- config SSB_B43_PCI_BRIDGE
- bool
- depends on SSB_PCIHOST
-- default n
-+ default y
-
- config SSB_PCMCIAHOST_POSSIBLE
- bool
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -457,16 +457,16 @@ config BCH_CONST_T
- # Textsearch support is select'ed if needed
- #
- config TEXTSEARCH
-- bool
-+ bool "Textsearch support"
-
- config TEXTSEARCH_KMP
-- tristate
-+ tristate "Textsearch KMP"
-
- config TEXTSEARCH_BM
-- tristate
-+ tristate "Textsearch BM"
-
- config TEXTSEARCH_FSM
-- tristate
-+ tristate "Textsearch FSM"
-
- config BTREE
- bool
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -22,7 +22,7 @@ config NETFILTER_SKIP_EGRESS
- def_bool NETFILTER_EGRESS && (NET_CLS_ACT || IFB)
-
- config NETFILTER_NETLINK
-- tristate
-+ tristate "Netfilter NFNETLINK interface"
-
- config NETFILTER_FAMILY_BRIDGE
- bool
---- a/sound/core/Kconfig
-+++ b/sound/core/Kconfig
-@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM
- tristate
-
- config SND_HWDEP
-- tristate
-+ tristate "Sound hardware support"
-
- config SND_SEQ_DEVICE
- tristate
-@@ -27,7 +27,7 @@ config SND_RAWMIDI
- select SND_SEQ_DEVICE if SND_SEQUENCER != n
-
- config SND_COMPRESS_OFFLOAD
-- tristate
-+ tristate "Compression offloading support"
-
- config SND_JACK
- bool
---- a/net/Kconfig
-+++ b/net/Kconfig
-@@ -430,7 +430,7 @@ config NET_DEVLINK
- default n
-
- config PAGE_POOL
-- bool
-+ bool "Page pool support"
-
- config PAGE_POOL_STATS
- default n
diff --git a/target/linux/generic/hack-6.1/253-ksmbd-config.patch b/target/linux/generic/hack-6.1/253-ksmbd-config.patch
deleted file mode 100644
index a57c914180..0000000000
--- a/target/linux/generic/hack-6.1/253-ksmbd-config.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From dcd966fa7ca63f38cf7147e1184d13d66e2ca340 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:33:30 +0200
-Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
-
----
- init/Kconfig | 2 +-
- lib/Kconfig | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -2013,7 +2013,7 @@ config PADATA
- bool
-
- config ASN1
-- tristate
-+ tristate "ASN1"
- help
- Build a simple ASN.1 grammar compiler that produces a bytecode output
- that can be interpreted by the ASN.1 stream decoder and used to
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -637,7 +637,7 @@ config LIBFDT
- bool
-
- config OID_REGISTRY
-- tristate
-+ tristate "OID"
- help
- Enable fast lookup object identifier registry.
-
diff --git a/target/linux/generic/hack-6.1/259-regmap_dynamic.patch b/target/linux/generic/hack-6.1/259-regmap_dynamic.patch
deleted file mode 100644
index 8d25f59ce2..0000000000
--- a/target/linux/generic/hack-6.1/259-regmap_dynamic.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 15 Jul 2017 21:12:38 +0200
-Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules
-
-lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/base/regmap/Kconfig | 15 ++++++++++-----
- drivers/base/regmap/Makefile | 12 ++++++++----
- drivers/base/regmap/regmap.c | 3 +++
- include/linux/regmap.h | 2 +-
- 4 files changed, 22 insertions(+), 10 deletions(-)
-
---- a/drivers/base/regmap/Kconfig
-+++ b/drivers/base/regmap/Kconfig
-@@ -4,10 +4,9 @@
- # subsystems should select the appropriate symbols.
-
- config REGMAP
-- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO)
- select IRQ_DOMAIN if REGMAP_IRQ
- select MDIO_BUS if REGMAP_MDIO
-- bool
-+ tristate
-
- config REGCACHE_COMPRESSED
- select LZO_COMPRESS
-@@ -15,53 +14,67 @@ config REGCACHE_COMPRESSED
- bool
-
- config REGMAP_AC97
-+ select REGMAP
- tristate
-
- config REGMAP_I2C
-+ select REGMAP
- tristate
- depends on I2C
-
- config REGMAP_SLIMBUS
-+ select REGMAP
- tristate
- depends on SLIMBUS
-
- config REGMAP_SPI
-+ select REGMAP
- tristate
- depends on SPI
-
- config REGMAP_SPMI
-+ select REGMAP
- tristate
- depends on SPMI
-
- config REGMAP_W1
-+ select REGMAP
- tristate
- depends on W1
-
- config REGMAP_MDIO
-+ select REGMAP
- tristate
-
- config REGMAP_MMIO
-+ select REGMAP
- tristate
-
- config REGMAP_IRQ
-+ select REGMAP
- bool
-
- config REGMAP_SOUNDWIRE
-+ select REGMAP
- tristate
- depends on SOUNDWIRE
-
- config REGMAP_SOUNDWIRE_MBQ
-+ select REGMAP
- tristate
- depends on SOUNDWIRE
-
- config REGMAP_SCCB
-+ select REGMAP
- tristate
- depends on I2C
-
- config REGMAP_I3C
-+ select REGMAP
- tristate
- depends on I3C
-
- config REGMAP_SPI_AVMM
-+ select REGMAP
- tristate
- depends on SPI
---- a/drivers/base/regmap/Makefile
-+++ b/drivers/base/regmap/Makefile
-@@ -2,10 +2,14 @@
- # For include/trace/define_trace.h to include trace.h
- CFLAGS_regmap.o := -I$(src)
-
--obj-$(CONFIG_REGMAP) += regmap.o regcache.o
--obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o
--obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o
--obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
-+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o
-+ifdef CONFIG_DEBUG_FS
-+regmap-core-objs += regmap-debugfs.o
-+endif
-+ifdef CONFIG_REGCACHE_COMPRESSED
-+regmap-core-objs += regcache-lzo.o
-+endif
-+obj-$(CONFIG_REGMAP) += regmap-core.o
- obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
- obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
- obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
---- a/drivers/base/regmap/regmap.c
-+++ b/drivers/base/regmap/regmap.c
-@@ -9,6 +9,7 @@
- #include <linux/device.h>
- #include <linux/slab.h>
- #include <linux/export.h>
-+#include <linux/module.h>
- #include <linux/mutex.h>
- #include <linux/err.h>
- #include <linux/property.h>
-@@ -3513,3 +3514,5 @@ static int __init regmap_initcall(void)
- return 0;
- }
- postcore_initcall(regmap_initcall);
-+
-+MODULE_LICENSE("GPL");
---- a/include/linux/regmap.h
-+++ b/include/linux/regmap.h
-@@ -180,7 +180,7 @@ struct reg_sequence {
- __ret ?: __tmp; \
- })
-
--#ifdef CONFIG_REGMAP
-+#if IS_REACHABLE(CONFIG_REGMAP)
-
- enum regmap_endian {
- /* Unspecified -> 0 -> Backwards compatible default */
diff --git a/target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch b/target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch
deleted file mode 100644
index 7ea517496e..0000000000
--- a/target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:12:51 +0200
-Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run
-
-Reduces kernel size after LZMA by about 5k on MIPS
-
-lede-commit: 044c316167e076479a344c59905e5b435b84a77f
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- crypto/Kconfig | 13 ++++++-------
- crypto/algboss.c | 4 ++++
- 2 files changed, 10 insertions(+), 7 deletions(-)
-
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -142,13 +142,13 @@ config CRYPTO_MANAGER
- cbc(aes).
-
- config CRYPTO_MANAGER2
-- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y)
-- select CRYPTO_AEAD2
-- select CRYPTO_HASH2
-- select CRYPTO_SKCIPHER2
-- select CRYPTO_AKCIPHER2
-- select CRYPTO_KPP2
-- select CRYPTO_ACOMP2
-+ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS)
-+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS
-+ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS
-
- config CRYPTO_USER
- tristate "Userspace cryptographic algorithm configuration"
---- a/crypto/algboss.c
-+++ b/crypto/algboss.c
-@@ -211,8 +211,12 @@ static int cryptomgr_schedule_test(struc
- type = alg->cra_flags;
-
- /* Do not test internal algorithms. */
-+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
-+ type |= CRYPTO_ALG_TESTED;
-+#else
- if (type & CRYPTO_ALG_INTERNAL)
- type |= CRYPTO_ALG_TESTED;
-+#endif
-
- param->type = type;
-
diff --git a/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch b/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch
deleted file mode 100644
index 01829b2d51..0000000000
--- a/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 241e5d3f7b0dd3c01f8c7fa83cbc9a3882286d53 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:35:18 +0200
-Subject: [PATCH] lib/crypto: add tristate string for ARC4
-
-This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We
-need this to be able to compile this into the kernel and make use of it
-from backports.
-
----
- lib/crypto/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/lib/crypto/Kconfig
-+++ b/lib/crypto/Kconfig
-@@ -9,7 +9,7 @@ config CRYPTO_LIB_AES
- tristate
-
- config CRYPTO_LIB_ARC4
-- tristate
-+ tristate "ARC4 cipher library"
-
- config CRYPTO_ARCH_HAVE_LIB_BLAKE2S
- bool
diff --git a/target/linux/generic/hack-6.1/280-rfkill-stubs.patch b/target/linux/generic/hack-6.1/280-rfkill-stubs.patch
deleted file mode 100644
index 7a650d132e..0000000000
--- a/target/linux/generic/hack-6.1/280-rfkill-stubs.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 7 Jul 2017 17:13:44 +0200
-Subject: rfkill: add fake rfkill support
-
-allow building of modules depending on RFKILL even if RFKILL is not enabled.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- include/linux/rfkill.h | 2 +-
- net/Makefile | 2 +-
- net/rfkill/Kconfig | 14 +++++++++-----
- net/rfkill/Makefile | 2 +-
- 4 files changed, 12 insertions(+), 8 deletions(-)
-
---- a/include/linux/rfkill.h
-+++ b/include/linux/rfkill.h
-@@ -64,7 +64,7 @@ struct rfkill_ops {
- int (*set_block)(void *data, bool blocked);
- };
-
--#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-+#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE)
- /**
- * rfkill_alloc - Allocate rfkill structure
- * @name: name of the struct -- the string is not copied internally
---- a/net/Makefile
-+++ b/net/Makefile
-@@ -52,7 +52,7 @@ obj-$(CONFIG_TIPC) += tipc/
- obj-$(CONFIG_NETLABEL) += netlabel/
- obj-$(CONFIG_IUCV) += iucv/
- obj-$(CONFIG_SMC) += smc/
--obj-$(CONFIG_RFKILL) += rfkill/
-+obj-$(CONFIG_RFKILL_FULL) += rfkill/
- obj-$(CONFIG_NET_9P) += 9p/
- obj-$(CONFIG_CAIF) += caif/
- obj-$(CONFIG_DCB) += dcb/
---- a/net/rfkill/Kconfig
-+++ b/net/rfkill/Kconfig
-@@ -2,7 +2,11 @@
- #
- # RF switch subsystem configuration
- #
--menuconfig RFKILL
-+config RFKILL
-+ bool
-+ default y
-+
-+menuconfig RFKILL_FULL
- tristate "RF switch subsystem support"
- help
- Say Y here if you want to have control over RF switches
-@@ -14,19 +18,19 @@ menuconfig RFKILL
- # LED trigger support
- config RFKILL_LEDS
- bool
-- depends on RFKILL
-+ depends on RFKILL_FULL
- depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS
- default y
-
- config RFKILL_INPUT
- bool "RF switch input support" if EXPERT
-- depends on RFKILL
-+ depends on RFKILL_FULL
- depends on INPUT = y || RFKILL = INPUT
- default y if !EXPERT
-
- config RFKILL_GPIO
- tristate "GPIO RFKILL driver"
-- depends on RFKILL
-+ depends on RFKILL_FULL
- depends on GPIOLIB || COMPILE_TEST
- default n
- help
---- a/net/rfkill/Makefile
-+++ b/net/rfkill/Makefile
-@@ -5,5 +5,5 @@
-
- rfkill-y += core.o
- rfkill-$(CONFIG_RFKILL_INPUT) += input.o
--obj-$(CONFIG_RFKILL) += rfkill.o
-+obj-$(CONFIG_RFKILL_FULL) += rfkill.o
- obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o
diff --git a/target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch
deleted file mode 100644
index f21f200136..0000000000
--- a/target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
-Date: Fri, 7 Jun 2013 18:35:22 -0500
-Subject: MIPS: r4k_cache: use more efficient cache blast
-
-Optimize the compiler output for larger cache blast cases that are
-common for DMA-based networking.
-
-Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
---- a/arch/mips/include/asm/r4kcache.h
-+++ b/arch/mips/include/asm/r4kcache.h
-@@ -286,14 +286,46 @@ static inline void prot##extra##blast_##
- unsigned long end) \
- { \
- unsigned long lsize = cpu_##desc##_line_size(); \
-+ unsigned long lsize_2 = lsize * 2; \
-+ unsigned long lsize_3 = lsize * 3; \
-+ unsigned long lsize_4 = lsize * 4; \
-+ unsigned long lsize_5 = lsize * 5; \
-+ unsigned long lsize_6 = lsize * 6; \
-+ unsigned long lsize_7 = lsize * 7; \
-+ unsigned long lsize_8 = lsize * 8; \
- unsigned long addr = start & ~(lsize - 1); \
-- unsigned long aend = (end - 1) & ~(lsize - 1); \
-+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \
-+ int lines = (aend - addr) / lsize; \
- \
-- while (1) { \
-+ while (lines >= 8) { \
-+ prot##cache_op(hitop, addr); \
-+ prot##cache_op(hitop, addr + lsize); \
-+ prot##cache_op(hitop, addr + lsize_2); \
-+ prot##cache_op(hitop, addr + lsize_3); \
-+ prot##cache_op(hitop, addr + lsize_4); \
-+ prot##cache_op(hitop, addr + lsize_5); \
-+ prot##cache_op(hitop, addr + lsize_6); \
-+ prot##cache_op(hitop, addr + lsize_7); \
-+ addr += lsize_8; \
-+ lines -= 8; \
-+ } \
-+ \
-+ if (lines & 0x4) { \
-+ prot##cache_op(hitop, addr); \
-+ prot##cache_op(hitop, addr + lsize); \
-+ prot##cache_op(hitop, addr + lsize_2); \
-+ prot##cache_op(hitop, addr + lsize_3); \
-+ addr += lsize_4; \
-+ } \
-+ \
-+ if (lines & 0x2) { \
-+ prot##cache_op(hitop, addr); \
-+ prot##cache_op(hitop, addr + lsize); \
-+ addr += lsize_2; \
-+ } \
-+ \
-+ if (lines & 0x1) { \
- prot##cache_op(hitop, addr); \
-- if (addr == aend) \
-- break; \
-- addr += lsize; \
- } \
- }
-
diff --git a/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch
deleted file mode 100644
index a87b41370e..0000000000
--- a/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 0bccc3722bdd88e8ae995e77ef9f7b77ee4cbdee Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 7 Apr 2021 22:45:54 +0100
-Subject: [PATCH 2/2] mtd: blktrans: call add disks after mtd device
-To: linux-mtd@lists.infradead.org
-Cc: Vignesh Raghavendra <vigneshr@ti.com>,
- Richard Weinberger <richard@nod.at>,
- Miquel Raynal <miquel.raynal@bootlin.com>,
- David Woodhouse <dwmw2@infradead.org>
-
-Calling device_add_disk while holding mtd_table_mutex leads
-to deadlock in case part_bits!=0 as block partition parsers
-will try to open the newly created disks, trying to acquire
-mutex once again.
-Move device_add_disk to additional function called after
-add partitions of an MTD device have been added and locks
-have been released.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/mtd_blkdevs.c | 33 ++++++++++++++++++++++++++-------
- drivers/mtd/mtdcore.c | 3 +++
- include/linux/mtd/blktrans.h | 1 +
- 3 files changed, 30 insertions(+), 7 deletions(-)
-
---- a/drivers/mtd/mtd_blkdevs.c
-+++ b/drivers/mtd/mtd_blkdevs.c
-@@ -386,19 +386,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt
- if (new->readonly)
- set_disk_ro(gd, 1);
-
-- ret = device_add_disk(&new->mtd->dev, gd, NULL);
-- if (ret)
-- goto out_cleanup_disk;
--
-- if (new->disk_attributes) {
-- ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
-- new->disk_attributes);
-- WARN_ON(ret);
-- }
- return 0;
-
--out_cleanup_disk:
-- put_disk(new->disk);
- out_free_tag_set:
- blk_mq_free_tag_set(new->tag_set);
- out_kfree_tag_set:
-@@ -408,6 +397,35 @@ out_list_del:
- return ret;
- }
-
-+void register_mtd_blktrans_devs(void)
-+{
-+ struct mtd_blktrans_ops *tr;
-+ struct mtd_blktrans_dev *dev, *next;
-+ int ret;
-+
-+ list_for_each_entry(tr, &blktrans_majors, list) {
-+ list_for_each_entry_safe(dev, next, &tr->devs, list) {
-+ if (disk_live(dev->disk))
-+ continue;
-+
-+ ret = device_add_disk(&dev->mtd->dev, dev->disk, NULL);
-+ if (ret)
-+ goto out_cleanup_disk;
-+
-+ if (dev->disk_attributes) {
-+ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj,
-+ dev->disk_attributes);
-+ WARN_ON(ret);
-+ }
-+ }
-+ }
-+
-+ return;
-+
-+out_cleanup_disk:
-+ put_disk(dev->disk);
-+}
-+
- int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
- {
- unsigned long flags;
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -32,6 +32,7 @@
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-+#include <linux/mtd/blktrans.h>
-
- #include "mtdcore.h"
-
-@@ -1100,6 +1101,8 @@ int mtd_device_parse_register(struct mtd
- register_reboot_notifier(&mtd->reboot_notifier);
- }
-
-+ register_mtd_blktrans_devs();
-+
- out:
- if (ret) {
- nvmem_unregister(mtd->otp_user_nvmem);
---- a/include/linux/mtd/blktrans.h
-+++ b/include/linux/mtd/blktrans.h
-@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc
- extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
- extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
- extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev);
-+extern void register_mtd_blktrans_devs(void);
-
- /**
- * module_mtd_blktrans() - Helper macro for registering a mtd blktrans driver
diff --git a/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch b/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch
deleted file mode 100644
index 7c7e4c814e..0000000000
--- a/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 7 Nov 2022 23:48:24 +0100
-Subject: [PATCH] mtd: support OpenWrt's MTD_ROOTFS_ROOT_DEV
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows setting ROOT_DEV to MTD partition named "rootfs".
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -773,7 +773,8 @@ int add_mtd_device(struct mtd_info *mtd)
-
- mutex_unlock(&mtd_table_mutex);
-
-- if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) {
-+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL) ||
-+ (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && !strcmp(mtd->name, "rootfs") && ROOT_DEV == 0)) {
- if (IS_BUILTIN(CONFIG_MTD)) {
- pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name);
- ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
diff --git a/target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch b/target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch
deleted file mode 100644
index 965a331a19..0000000000
--- a/target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 6fa9e3678eb002246df1280322b6a024853950a5 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Mon, 11 Oct 2021 00:53:14 +0200
-Subject: [PATCH] drivers: mtd: parsers: add nvmem support to cmdlinepart
-
-Assuming cmdlinepart is only one level deep partition scheme and that
-static partition are also defined in DTS, we can assign an of_node for
-partition declared from bootargs. cmdlinepart have priority than
-fiexed-partition parser so in this specific case the parser doesn't
-assign an of_node. Fix this by searching a defined of_node using a
-similar fixed_partition parser and if a partition is found with the same
-label, check that it has the same offset and size and return the DT
-of_node to correctly use NVMEM cells.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
----
- drivers/mtd/parsers/cmdlinepart.c | 71 +++++++++++++++++++++++++++++++
- 1 file changed, 71 insertions(+)
-
---- a/drivers/mtd/parsers/cmdlinepart.c
-+++ b/drivers/mtd/parsers/cmdlinepart.c
-@@ -43,6 +43,7 @@
- #include <linux/mtd/partitions.h>
- #include <linux/module.h>
- #include <linux/err.h>
-+#include <linux/of.h>
-
- /* debug macro */
- #if 0
-@@ -323,6 +324,68 @@ static int mtdpart_setup_real(char *s)
- return 0;
- }
-
-+static int search_fixed_partition(struct mtd_info *master,
-+ struct mtd_partition *target_part,
-+ struct mtd_partition *fixed_part)
-+{
-+ struct device_node *mtd_node;
-+ struct device_node *ofpart_node;
-+ struct device_node *pp;
-+ struct mtd_partition part;
-+ const char *partname;
-+
-+ mtd_node = mtd_get_of_node(master);
-+ if (!mtd_node)
-+ return -EINVAL;
-+
-+ ofpart_node = of_get_child_by_name(mtd_node, "partitions");
-+
-+ for_each_child_of_node(ofpart_node, pp) {
-+ const __be32 *reg;
-+ int len;
-+ int a_cells, s_cells;
-+
-+ reg = of_get_property(pp, "reg", &len);
-+ if (!reg) {
-+ pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n",
-+ master->name, pp,
-+ mtd_node);
-+ continue;
-+ }
-+
-+ a_cells = of_n_addr_cells(pp);
-+ s_cells = of_n_size_cells(pp);
-+ if (len / 4 != a_cells + s_cells) {
-+ pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n",
-+ master->name, pp,
-+ mtd_node);
-+ continue;
-+ }
-+
-+ part.offset = of_read_number(reg, a_cells);
-+ part.size = of_read_number(reg + a_cells, s_cells);
-+ part.of_node = pp;
-+
-+ partname = of_get_property(pp, "label", &len);
-+ if (!partname)
-+ partname = of_get_property(pp, "name", &len);
-+ part.name = partname;
-+
-+ if (!strncmp(target_part->name, part.name, len)) {
-+ if (part.offset != target_part->offset)
-+ return -EINVAL;
-+
-+ if (part.size != target_part->size)
-+ return -EINVAL;
-+
-+ memcpy(fixed_part, &part, sizeof(struct mtd_partition));
-+ return 0;
-+ }
-+ }
-+
-+ return -EINVAL;
-+}
-+
- /*
- * Main function to be called from the MTD mapping driver/device to
- * obtain the partitioning information. At this point the command line
-@@ -338,6 +401,7 @@ static int parse_cmdline_partitions(stru
- int i, err;
- struct cmdline_mtd_partition *part;
- const char *mtd_id = master->name;
-+ struct mtd_partition fixed_part;
-
- /* parse command line */
- if (!cmdline_parsed) {
-@@ -382,6 +446,13 @@ static int parse_cmdline_partitions(stru
- sizeof(*part->parts) * (part->num_parts - i));
- i--;
- }
-+
-+ err = search_fixed_partition(master, &part->parts[i], &fixed_part);
-+ if (!err) {
-+ part->parts[i].of_node = fixed_part.of_node;
-+ pr_info("Found partition defined in DT for %s. Assigning OF node to support nvmem.",
-+ part->parts[i].name);
-+ }
- }
-
- *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
diff --git a/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch b/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch
deleted file mode 100644
index 1e69ee6446..0000000000
--- a/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From ac84397efb3b3868c71c10ad7521161773228a17 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:41:44 +0200
-Subject: [PATCH] mtd/nand: add MediaTek NAND bad block managment table
-
----
- drivers/mtd/nand/Kconfig | 4 ++++
- drivers/mtd/nand/Makefile | 1 +
- 2 files changed, 5 insertions(+)
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -46,6 +46,10 @@ config MTD_NAND_ECC_SW_BCH
- ECC codes. They are used with NAND devices requiring more than 1 bit
- of error correction.
-
-+config MTD_NAND_MTK_BMT
-+ bool "Support MediaTek NAND Bad-block Management Table"
-+ default n
-+
- config MTD_NAND_ECC_MXIC
- bool "Macronix external hardware ECC engine"
- depends on HAS_IOMEM
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -3,6 +3,7 @@
- nandcore-objs := core.o bbt.o
- obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
- obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
-+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o
-
- obj-y += onenand/
- obj-y += raw/
diff --git a/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch b/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch
deleted file mode 100644
index 51f990039c..0000000000
--- a/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 23 Apr 2024 12:35:21 +0200
-Subject: [PATCH] net: enable fraglist GRO by default
-
-This can significantly improve performance for packet forwarding/bridging
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/netdev_features.h
-+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
- #define NETIF_F_UPPER_DISABLES NETIF_F_LRO
-
- /* changeable features with no special hardware requirements */
--#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)
-+#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST)
-
- /* Changeable features with no special hardware requirements that defaults to off. */
--#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD)
-+#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD)
-
- #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
- NETIF_F_HW_VLAN_CTAG_RX | \
diff --git a/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch
deleted file mode 100644
index 444f8edfea..0000000000
--- a/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch
+++ /dev/null
@@ -1,214 +0,0 @@
-From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001
-From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
-Date: Sat, 23 Mar 2019 09:29:49 +0000
-Subject: [PATCH] netfilter: connmark: introduce set-dscpmark
-
-set-dscpmark is a method of storing the DSCP of an ip packet into
-conntrack mark. In combination with a suitable tc filter action
-(act_ctinfo) DSCP values are able to be stored in the mark on egress and
-restored on ingress across links that otherwise alter or bleach DSCP.
-
-This is useful for qdiscs such as CAKE which are able to shape according
-to policies based on DSCP.
-
-Ingress classification is traditionally a challenging task since
-iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT
-lookups, hence are unable to see internal IPv4 addresses as used on the
-typical home masquerading gateway.
-
-x_tables CONNMARK set-dscpmark target solves the problem of storing the
-DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc
-action to restore.
-
-The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a
-32bit 'statemask'. The dscp mask must be 6 contiguous bits and
-represents the area where the DSCP will be stored in the connmark. The
-state mask is a minimum 1 bit length mask that must not overlap with the
-dscpmask. It represents a flag which is set when the DSCP has been
-stored in the conntrack mark. This is useful to implement a 'one shot'
-iptables based classification where the 'complicated' iptables rules are
-only run once to classify the connection on initial (egress) packet and
-subsequent packets are all marked/restored with the same DSCP. A state
-mask of zero disables the setting of a status bit/s.
-
-example syntax with a suitably modified iptables user space application:
-
-iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000
-
-Would store the DSCP in the top 6 bits of the 32bit mark field, and use
-the LSB of the top byte as the 'DSCP has been stored' marker.
-
-|----0xFC----conntrack mark----000000---|
-| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
-| DSCP | unused | flag |unused |
-|-----------------------0x01---000000---|
- ^ ^
- | |
- ---| Conditional flag
- | set this when dscp
-|-ip diffserv-| stored in mark
-| 6 bits |
-|-------------|
-
-an identically configured tc action to restore looks like:
-
-tc filter show dev eth0 ingress
-filter parent ffff: protocol all pref 10 u32 chain 0
-filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1
-filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw
- match 00000000/00000000 at 0
- action order 1: ctinfo zone 0 pipe
- index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000
-
- action order 2: mirred (Egress Redirect to device ifb4eth0) stolen
- index 1 ref 1 bind 1
-
-|----0xFC----conntrack mark----000000---|
-| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
-| DSCP | unused | flag |unused |
-|-----------------------0x01---000000---|
- | |
- | |
- ---| Conditional flag
- v only restore if set
-|-ip diffserv-|
-| 6 bits |
-|-------------|
-
-Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
----
- include/uapi/linux/netfilter/xt_connmark.h | 10 ++++
- net/netfilter/xt_connmark.c | 55 ++++++++++++++++++----
- 2 files changed, 57 insertions(+), 8 deletions(-)
-
---- a/include/uapi/linux/netfilter/xt_connmark.h
-+++ b/include/uapi/linux/netfilter/xt_connmark.h
-@@ -15,6 +15,11 @@ enum {
- };
-
- enum {
-+ XT_CONNMARK_VALUE = (1 << 0),
-+ XT_CONNMARK_DSCP = (1 << 1)
-+};
-+
-+enum {
- D_SHIFT_LEFT = 0,
- D_SHIFT_RIGHT,
- };
-@@ -29,6 +34,11 @@ struct xt_connmark_tginfo2 {
- __u8 shift_dir, shift_bits, mode;
- };
-
-+struct xt_connmark_tginfo3 {
-+ __u32 ctmark, ctmask, nfmask;
-+ __u8 shift_dir, shift_bits, mode, func;
-+};
-+
- struct xt_connmark_mtinfo1 {
- __u32 mark, mask;
- __u8 invert;
---- a/net/netfilter/xt_connmark.c
-+++ b/net/netfilter/xt_connmark.c
-@@ -24,13 +24,13 @@ MODULE_ALIAS("ipt_connmark");
- MODULE_ALIAS("ip6t_connmark");
-
- static unsigned int
--connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
-+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info)
- {
- enum ip_conntrack_info ctinfo;
- u_int32_t new_targetmark;
- struct nf_conn *ct;
- u_int32_t newmark;
-- u_int32_t oldmark;
-+ u_int8_t dscp;
-
- ct = nf_ct_get(skb, &ctinfo);
- if (ct == NULL)
-@@ -38,13 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c
-
- switch (info->mode) {
- case XT_CONNMARK_SET:
-- oldmark = READ_ONCE(ct->mark);
-- newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
-- if (info->shift_dir == D_SHIFT_RIGHT)
-- newmark >>= info->shift_bits;
-- else
-- newmark <<= info->shift_bits;
-+ newmark = READ_ONCE(ct->mark);
-+ if (info->func & XT_CONNMARK_VALUE) {
-+ newmark = (newmark & ~info->ctmask) ^ info->ctmark;
-+ if (info->shift_dir == D_SHIFT_RIGHT)
-+ newmark >>= info->shift_bits;
-+ else
-+ newmark <<= info->shift_bits;
-+ } else if (info->func & XT_CONNMARK_DSCP) {
-+ if (skb->protocol == htons(ETH_P_IP))
-+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
-+ else if (skb->protocol == htons(ETH_P_IPV6))
-+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
-+ else /* protocol doesn't have diffserv */
-+ break;
-
-+ newmark = (newmark & ~info->ctmark) |
-+ (info->ctmask | (dscp << info->shift_bits));
-+ }
- if (READ_ONCE(ct->mark) != newmark) {
- WRITE_ONCE(ct->mark, newmark);
- nf_conntrack_event_cache(IPCT_MARK, ct);
-@@ -83,20 +94,36 @@ static unsigned int
- connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct xt_connmark_tginfo1 *info = par->targinfo;
-- const struct xt_connmark_tginfo2 info2 = {
-+ const struct xt_connmark_tginfo3 info3 = {
- .ctmark = info->ctmark,
- .ctmask = info->ctmask,
- .nfmask = info->nfmask,
- .mode = info->mode,
-+ .func = XT_CONNMARK_VALUE
- };
-
-- return connmark_tg_shift(skb, &info2);
-+ return connmark_tg_shift(skb, &info3);
- }
-
- static unsigned int
- connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct xt_connmark_tginfo2 *info = par->targinfo;
-+ const struct xt_connmark_tginfo3 info3 = {
-+ .ctmark = info->ctmark,
-+ .ctmask = info->ctmask,
-+ .nfmask = info->nfmask,
-+ .mode = info->mode,
-+ .func = XT_CONNMARK_VALUE
-+ };
-+
-+ return connmark_tg_shift(skb, &info3);
-+}
-+
-+static unsigned int
-+connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
-+{
-+ const struct xt_connmark_tginfo3 *info = par->targinfo;
-
- return connmark_tg_shift(skb, info);
- }
-@@ -167,6 +194,16 @@ static struct xt_target connmark_tg_reg[
- .targetsize = sizeof(struct xt_connmark_tginfo2),
- .destroy = connmark_tg_destroy,
- .me = THIS_MODULE,
-+ },
-+ {
-+ .name = "CONNMARK",
-+ .revision = 3,
-+ .family = NFPROTO_UNSPEC,
-+ .checkentry = connmark_tg_check,
-+ .target = connmark_tg_v3,
-+ .targetsize = sizeof(struct xt_connmark_tginfo3),
-+ .destroy = connmark_tg_destroy,
-+ .me = THIS_MODULE,
- }
- };
-
diff --git a/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
deleted file mode 100644
index 0822b1a2dd..0000000000
--- a/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
+++ /dev/null
@@ -1,812 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 20 Feb 2018 15:56:02 +0100
-Subject: [PATCH] netfilter: add xt_FLOWOFFLOAD target
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- create mode 100644 net/netfilter/xt_OFFLOAD.c
-
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -726,7 +726,6 @@ config NF_FLOW_TABLE
- tristate "Netfilter flow table module"
- depends on NETFILTER_INGRESS
- depends on NF_CONNTRACK
-- depends on NF_TABLES
- help
- This option adds the flow table core infrastructure.
-
-@@ -1023,6 +1022,15 @@ config NETFILTER_XT_TARGET_NOTRACK
- depends on NETFILTER_ADVANCED
- select NETFILTER_XT_TARGET_CT
-
-+config NETFILTER_XT_TARGET_FLOWOFFLOAD
-+ tristate '"FLOWOFFLOAD" target support'
-+ depends on NF_FLOW_TABLE
-+ depends on NETFILTER_INGRESS
-+ help
-+ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload
-+ module to speed up processing of packets by bypassing the usual
-+ netfilter chains
-+
- config NETFILTER_XT_TARGET_RATEEST
- tristate '"RATEEST" target support'
- depends on NETFILTER_ADVANCED
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -154,6 +154,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
- obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
---- /dev/null
-+++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -0,0 +1,703 @@
-+/*
-+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
-+#include <linux/if_vlan.h>
-+#include <net/ip.h>
-+#include <net/netfilter/nf_conntrack.h>
-+#include <net/netfilter/nf_conntrack_extend.h>
-+#include <net/netfilter/nf_conntrack_helper.h>
-+#include <net/netfilter/nf_flow_table.h>
-+
-+struct xt_flowoffload_hook {
-+ struct hlist_node list;
-+ struct nf_hook_ops ops;
-+ struct net *net;
-+ bool registered;
-+ bool used;
-+};
-+
-+struct xt_flowoffload_table {
-+ struct nf_flowtable ft;
-+ struct hlist_head hooks;
-+ struct delayed_work work;
-+};
-+
-+struct nf_forward_info {
-+ const struct net_device *indev;
-+ const struct net_device *outdev;
-+ const struct net_device *hw_outdev;
-+ struct id {
-+ __u16 id;
-+ __be16 proto;
-+ } encap[NF_FLOW_TABLE_ENCAP_MAX];
-+ u8 num_encaps;
-+ u8 ingress_vlans;
-+ u8 h_source[ETH_ALEN];
-+ u8 h_dest[ETH_ALEN];
-+ enum flow_offload_xmit_type xmit_type;
-+};
-+
-+static DEFINE_SPINLOCK(hooks_lock);
-+
-+struct xt_flowoffload_table flowtable[2];
-+
-+static unsigned int
-+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
-+ const struct nf_hook_state *state)
-+{
-+ struct vlan_ethhdr *veth;
-+ __be16 proto;
-+
-+ switch (skb->protocol) {
-+ case htons(ETH_P_8021Q):
-+ veth = (struct vlan_ethhdr *)skb_mac_header(skb);
-+ proto = veth->h_vlan_encapsulated_proto;
-+ break;
-+ case htons(ETH_P_PPP_SES):
-+ if (!nf_flow_pppoe_proto(skb, &proto))
-+ return NF_ACCEPT;
-+ break;
-+ default:
-+ proto = skb->protocol;
-+ break;
-+ }
-+
-+ switch (proto) {
-+ case htons(ETH_P_IP):
-+ return nf_flow_offload_ip_hook(priv, skb, state);
-+ case htons(ETH_P_IPV6):
-+ return nf_flow_offload_ipv6_hook(priv, skb, state);
-+ }
-+
-+ return NF_ACCEPT;
-+}
-+
-+static int
-+xt_flowoffload_create_hook(struct xt_flowoffload_table *table,
-+ struct net_device *dev)
-+{
-+ struct xt_flowoffload_hook *hook;
-+ struct nf_hook_ops *ops;
-+
-+ hook = kzalloc(sizeof(*hook), GFP_ATOMIC);
-+ if (!hook)
-+ return -ENOMEM;
-+
-+ ops = &hook->ops;
-+ ops->pf = NFPROTO_NETDEV;
-+ ops->hooknum = NF_NETDEV_INGRESS;
-+ ops->priority = 10;
-+ ops->priv = &table->ft;
-+ ops->hook = xt_flowoffload_net_hook;
-+ ops->dev = dev;
-+
-+ hlist_add_head(&hook->list, &table->hooks);
-+ mod_delayed_work(system_power_efficient_wq, &table->work, 0);
-+
-+ return 0;
-+}
-+
-+static struct xt_flowoffload_hook *
-+flow_offload_lookup_hook(struct xt_flowoffload_table *table,
-+ struct net_device *dev)
-+{
-+ struct xt_flowoffload_hook *hook;
-+
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->ops.dev == dev)
-+ return hook;
-+ }
-+
-+ return NULL;
-+}
-+
-+static void
-+xt_flowoffload_check_device(struct xt_flowoffload_table *table,
-+ struct net_device *dev)
-+{
-+ struct xt_flowoffload_hook *hook;
-+
-+ if (!dev)
-+ return;
-+
-+ spin_lock_bh(&hooks_lock);
-+ hook = flow_offload_lookup_hook(table, dev);
-+ if (hook)
-+ hook->used = true;
-+ else
-+ xt_flowoffload_create_hook(table, dev);
-+ spin_unlock_bh(&hooks_lock);
-+}
-+
-+static void
-+xt_flowoffload_register_hooks(struct xt_flowoffload_table *table)
-+{
-+ struct xt_flowoffload_hook *hook;
-+
-+restart:
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->registered)
-+ continue;
-+
-+ hook->registered = true;
-+ hook->net = dev_net(hook->ops.dev);
-+ spin_unlock_bh(&hooks_lock);
-+ nf_register_net_hook(hook->net, &hook->ops);
-+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
-+ table->ft.type->setup(&table->ft, hook->ops.dev,
-+ FLOW_BLOCK_BIND);
-+ spin_lock_bh(&hooks_lock);
-+ goto restart;
-+ }
-+
-+}
-+
-+static bool
-+xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table)
-+{
-+ struct xt_flowoffload_hook *hook;
-+ bool active = false;
-+
-+restart:
-+ spin_lock_bh(&hooks_lock);
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->used || !hook->registered) {
-+ active = true;
-+ continue;
-+ }
-+
-+ hlist_del(&hook->list);
-+ spin_unlock_bh(&hooks_lock);
-+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
-+ table->ft.type->setup(&table->ft, hook->ops.dev,
-+ FLOW_BLOCK_UNBIND);
-+ nf_unregister_net_hook(hook->net, &hook->ops);
-+ kfree(hook);
-+ goto restart;
-+ }
-+ spin_unlock_bh(&hooks_lock);
-+
-+ return active;
-+}
-+
-+static void
-+xt_flowoffload_check_hook(struct nf_flowtable *flowtable,
-+ struct flow_offload *flow, void *data)
-+{
-+ struct xt_flowoffload_table *table;
-+ struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple;
-+ struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple;
-+ struct xt_flowoffload_hook *hook;
-+
-+ table = container_of(flowtable, struct xt_flowoffload_table, ft);
-+
-+ spin_lock_bh(&hooks_lock);
-+ hlist_for_each_entry(hook, &table->hooks, list) {
-+ if (hook->ops.dev->ifindex != tuple0->iifidx &&
-+ hook->ops.dev->ifindex != tuple1->iifidx)
-+ continue;
-+
-+ hook->used = true;
-+ }
-+ spin_unlock_bh(&hooks_lock);
-+}
-+
-+static void
-+xt_flowoffload_hook_work(struct work_struct *work)
-+{
-+ struct xt_flowoffload_table *table;
-+ struct xt_flowoffload_hook *hook;
-+ int err;
-+
-+ table = container_of(work, struct xt_flowoffload_table, work.work);
-+
-+ spin_lock_bh(&hooks_lock);
-+ xt_flowoffload_register_hooks(table);
-+ hlist_for_each_entry(hook, &table->hooks, list)
-+ hook->used = false;
-+ spin_unlock_bh(&hooks_lock);
-+
-+ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook,
-+ NULL);
-+ if (err && err != -EAGAIN)
-+ goto out;
-+
-+ if (!xt_flowoffload_cleanup_hooks(table))
-+ return;
-+
-+out:
-+ queue_delayed_work(system_power_efficient_wq, &table->work, HZ);
-+}
-+
-+static bool
-+xt_flowoffload_skip(struct sk_buff *skb, int family)
-+{
-+ if (skb_sec_path(skb))
-+ return true;
-+
-+ if (family == NFPROTO_IPV4) {
-+ const struct ip_options *opt = &(IPCB(skb)->opt);
-+
-+ if (unlikely(opt->optlen))
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static enum flow_offload_xmit_type nf_xmit_type(struct dst_entry *dst)
-+{
-+ if (dst_xfrm(dst))
-+ return FLOW_OFFLOAD_XMIT_XFRM;
-+
-+ return FLOW_OFFLOAD_XMIT_NEIGH;
-+}
-+
-+static void nf_default_forward_path(struct nf_flow_route *route,
-+ struct dst_entry *dst_cache,
-+ enum ip_conntrack_dir dir,
-+ struct net_device **dev)
-+{
-+ dev[!dir] = dst_cache->dev;
-+ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex;
-+ route->tuple[dir].dst = dst_cache;
-+ route->tuple[dir].xmit_type = nf_xmit_type(dst_cache);
-+}
-+
-+static bool nf_is_valid_ether_device(const struct net_device *dev)
-+{
-+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
-+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
-+ return false;
-+
-+ return true;
-+}
-+
-+static void nf_dev_path_info(const struct net_device_path_stack *stack,
-+ struct nf_forward_info *info,
-+ unsigned char *ha)
-+{
-+ const struct net_device_path *path;
-+ int i;
-+
-+ memcpy(info->h_dest, ha, ETH_ALEN);
-+
-+ for (i = 0; i < stack->num_paths; i++) {
-+ path = &stack->path[i];
-+ switch (path->type) {
-+ case DEV_PATH_ETHERNET:
-+ case DEV_PATH_DSA:
-+ case DEV_PATH_VLAN:
-+ case DEV_PATH_PPPOE:
-+ info->indev = path->dev;
-+ if (is_zero_ether_addr(info->h_source))
-+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
-+
-+ if (path->type == DEV_PATH_ETHERNET)
-+ break;
-+ if (path->type == DEV_PATH_DSA) {
-+ i = stack->num_paths;
-+ break;
-+ }
-+
-+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */
-+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
-+ info->indev = NULL;
-+ break;
-+ }
-+ if (!info->outdev)
-+ info->outdev = path->dev;
-+ info->encap[info->num_encaps].id = path->encap.id;
-+ info->encap[info->num_encaps].proto = path->encap.proto;
-+ info->num_encaps++;
-+ if (path->type == DEV_PATH_PPPOE)
-+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
-+ break;
-+ case DEV_PATH_BRIDGE:
-+ if (is_zero_ether_addr(info->h_source))
-+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
-+
-+ switch (path->bridge.vlan_mode) {
-+ case DEV_PATH_BR_VLAN_UNTAG_HW:
-+ info->ingress_vlans |= BIT(info->num_encaps - 1);
-+ break;
-+ case DEV_PATH_BR_VLAN_TAG:
-+ info->encap[info->num_encaps].id = path->bridge.vlan_id;
-+ info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
-+ info->num_encaps++;
-+ break;
-+ case DEV_PATH_BR_VLAN_UNTAG:
-+ info->num_encaps--;
-+ break;
-+ case DEV_PATH_BR_VLAN_KEEP:
-+ break;
-+ }
-+ break;
-+ default:
-+ info->indev = NULL;
-+ break;
-+ }
-+ }
-+ if (!info->outdev)
-+ info->outdev = info->indev;
-+
-+ info->hw_outdev = info->indev;
-+
-+ if (nf_is_valid_ether_device(info->indev))
-+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
-+}
-+
-+static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
-+ const struct dst_entry *dst_cache,
-+ const struct nf_conn *ct,
-+ enum ip_conntrack_dir dir, u8 *ha,
-+ struct net_device_path_stack *stack)
-+{
-+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
-+ struct net_device *dev = dst_cache->dev;
-+ struct neighbour *n;
-+ u8 nud_state;
-+
-+ if (!nf_is_valid_ether_device(dev))
-+ goto out;
-+
-+ n = dst_neigh_lookup(dst_cache, daddr);
-+ if (!n)
-+ return -1;
-+
-+ read_lock_bh(&n->lock);
-+ nud_state = n->nud_state;
-+ ether_addr_copy(ha, n->ha);
-+ read_unlock_bh(&n->lock);
-+ neigh_release(n);
-+
-+ if (!(nud_state & NUD_VALID))
-+ return -1;
-+
-+out:
-+ return dev_fill_forward_path(dev, ha, stack);
-+}
-+
-+static void nf_dev_forward_path(struct nf_flow_route *route,
-+ const struct nf_conn *ct,
-+ enum ip_conntrack_dir dir,
-+ struct net_device **devs)
-+{
-+ const struct dst_entry *dst = route->tuple[dir].dst;
-+ struct net_device_path_stack stack;
-+ struct nf_forward_info info = {};
-+ unsigned char ha[ETH_ALEN];
-+ int i;
-+
-+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
-+ nf_dev_path_info(&stack, &info, ha);
-+
-+ devs[!dir] = (struct net_device *)info.indev;
-+ if (!info.indev)
-+ return;
-+
-+ route->tuple[!dir].in.ifindex = info.indev->ifindex;
-+ for (i = 0; i < info.num_encaps; i++) {
-+ route->tuple[!dir].in.encap[i].id = info.encap[i].id;
-+ route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
-+ }
-+ route->tuple[!dir].in.num_encaps = info.num_encaps;
-+ route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
-+
-+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
-+ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
-+ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
-+ route->tuple[dir].out.ifindex = info.outdev->ifindex;
-+ route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
-+ route->tuple[dir].xmit_type = info.xmit_type;
-+ }
-+}
-+
-+static int
-+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
-+ const struct xt_action_param *par,
-+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
-+ struct net_device **devs)
-+{
-+ struct dst_entry *this_dst = skb_dst(skb);
-+ struct dst_entry *other_dst = NULL;
-+ struct flowi fl;
-+
-+ memset(&fl, 0, sizeof(fl));
-+ switch (xt_family(par)) {
-+ case NFPROTO_IPV4:
-+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
-+ fl.u.ip4.flowi4_oif = xt_in(par)->ifindex;
-+ break;
-+ case NFPROTO_IPV6:
-+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
-+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
-+ fl.u.ip6.flowi6_oif = xt_in(par)->ifindex;
-+ break;
-+ }
-+
-+ if (!dst_hold_safe(this_dst))
-+ return -ENOENT;
-+
-+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
-+ if (!other_dst) {
-+ dst_release(this_dst);
-+ return -ENOENT;
-+ }
-+
-+ nf_default_forward_path(route, this_dst, dir, devs);
-+ nf_default_forward_path(route, other_dst, !dir, devs);
-+
-+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
-+ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
-+ nf_dev_forward_path(route, ct, dir, devs);
-+ nf_dev_forward_path(route, ct, !dir, devs);
-+ }
-+
-+ return 0;
-+}
-+
-+static unsigned int
-+flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
-+{
-+ struct xt_flowoffload_table *table;
-+ const struct xt_flowoffload_target_info *info = par->targinfo;
-+ struct tcphdr _tcph, *tcph = NULL;
-+ enum ip_conntrack_info ctinfo;
-+ enum ip_conntrack_dir dir;
-+ struct nf_flow_route route = {};
-+ struct flow_offload *flow = NULL;
-+ struct net_device *devs[2] = {};
-+ struct nf_conn *ct;
-+ struct net *net;
-+
-+ if (xt_flowoffload_skip(skb, xt_family(par)))
-+ return XT_CONTINUE;
-+
-+ ct = nf_ct_get(skb, &ctinfo);
-+ if (ct == NULL)
-+ return XT_CONTINUE;
-+
-+ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) {
-+ case IPPROTO_TCP:
-+ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED)
-+ return XT_CONTINUE;
-+
-+ tcph = skb_header_pointer(skb, par->thoff,
-+ sizeof(_tcph), &_tcph);
-+ if (unlikely(!tcph || tcph->fin || tcph->rst))
-+ return XT_CONTINUE;
-+ break;
-+ case IPPROTO_UDP:
-+ break;
-+ default:
-+ return XT_CONTINUE;
-+ }
-+
-+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
-+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH))
-+ return XT_CONTINUE;
-+
-+ if (!nf_ct_is_confirmed(ct))
-+ return XT_CONTINUE;
-+
-+ dir = CTINFO2DIR(ctinfo);
-+
-+ devs[dir] = xt_out(par);
-+ devs[!dir] = xt_in(par);
-+
-+ if (!devs[dir] || !devs[!dir])
-+ return XT_CONTINUE;
-+
-+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
-+ return XT_CONTINUE;
-+
-+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0)
-+ goto err_flow_route;
-+
-+ flow = flow_offload_alloc(ct);
-+ if (!flow)
-+ goto err_flow_alloc;
-+
-+ flow_offload_route_init(flow, &route);
-+
-+ if (tcph) {
-+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
-+ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
-+ }
-+
-+ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)];
-+
-+ net = read_pnet(&table->ft.net);
-+ if (!net)
-+ write_pnet(&table->ft.net, xt_net(par));
-+
-+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags);
-+ if (flow_offload_add(&table->ft, flow) < 0)
-+ goto err_flow_add;
-+
-+ xt_flowoffload_check_device(table, devs[0]);
-+ xt_flowoffload_check_device(table, devs[1]);
-+
-+ return XT_CONTINUE;
-+
-+err_flow_add:
-+ flow_offload_free(flow);
-+err_flow_alloc:
-+ dst_release(route.tuple[dir].dst);
-+ dst_release(route.tuple[!dir].dst);
-+err_flow_route:
-+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
-+
-+ return XT_CONTINUE;
-+}
-+
-+static int flowoffload_chk(const struct xt_tgchk_param *par)
-+{
-+ struct xt_flowoffload_target_info *info = par->targinfo;
-+
-+ if (info->flags & ~XT_FLOWOFFLOAD_MASK)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static struct xt_target offload_tg_reg __read_mostly = {
-+ .family = NFPROTO_UNSPEC,
-+ .name = "FLOWOFFLOAD",
-+ .revision = 0,
-+ .targetsize = sizeof(struct xt_flowoffload_target_info),
-+ .usersize = sizeof(struct xt_flowoffload_target_info),
-+ .checkentry = flowoffload_chk,
-+ .target = flowoffload_tg,
-+ .me = THIS_MODULE,
-+};
-+
-+static int flow_offload_netdev_event(struct notifier_block *this,
-+ unsigned long event, void *ptr)
-+{
-+ struct xt_flowoffload_hook *hook0, *hook1;
-+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-+
-+ if (event != NETDEV_UNREGISTER)
-+ return NOTIFY_DONE;
-+
-+ spin_lock_bh(&hooks_lock);
-+ hook0 = flow_offload_lookup_hook(&flowtable[0], dev);
-+ if (hook0)
-+ hlist_del(&hook0->list);
-+
-+ hook1 = flow_offload_lookup_hook(&flowtable[1], dev);
-+ if (hook1)
-+ hlist_del(&hook1->list);
-+ spin_unlock_bh(&hooks_lock);
-+
-+ if (hook0) {
-+ nf_unregister_net_hook(hook0->net, &hook0->ops);
-+ kfree(hook0);
-+ }
-+
-+ if (hook1) {
-+ nf_unregister_net_hook(hook1->net, &hook1->ops);
-+ kfree(hook1);
-+ }
-+
-+ nf_flow_table_cleanup(dev);
-+
-+ return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block flow_offload_netdev_notifier = {
-+ .notifier_call = flow_offload_netdev_event,
-+};
-+
-+static int nf_flow_rule_route_inet(struct net *net,
-+ struct flow_offload *flow,
-+ enum flow_offload_tuple_dir dir,
-+ struct nf_flow_rule *flow_rule)
-+{
-+ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
-+ int err;
-+
-+ switch (flow_tuple->l3proto) {
-+ case NFPROTO_IPV4:
-+ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule);
-+ break;
-+ case NFPROTO_IPV6:
-+ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule);
-+ break;
-+ default:
-+ err = -1;
-+ break;
-+ }
-+
-+ return err;
-+}
-+
-+static struct nf_flowtable_type flowtable_inet = {
-+ .family = NFPROTO_INET,
-+ .init = nf_flow_table_init,
-+ .setup = nf_flow_table_offload_setup,
-+ .action = nf_flow_rule_route_inet,
-+ .free = nf_flow_table_free,
-+ .hook = xt_flowoffload_net_hook,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int init_flowtable(struct xt_flowoffload_table *tbl)
-+{
-+ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work);
-+ tbl->ft.type = &flowtable_inet;
-+ tbl->ft.flags = NF_FLOWTABLE_COUNTER;
-+
-+ return nf_flow_table_init(&tbl->ft);
-+}
-+
-+static int __init xt_flowoffload_tg_init(void)
-+{
-+ int ret;
-+
-+ register_netdevice_notifier(&flow_offload_netdev_notifier);
-+
-+ ret = init_flowtable(&flowtable[0]);
-+ if (ret)
-+ return ret;
-+
-+ ret = init_flowtable(&flowtable[1]);
-+ if (ret)
-+ goto cleanup;
-+
-+ flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD;
-+
-+ ret = xt_register_target(&offload_tg_reg);
-+ if (ret)
-+ goto cleanup2;
-+
-+ return 0;
-+
-+cleanup2:
-+ nf_flow_table_free(&flowtable[1].ft);
-+cleanup:
-+ nf_flow_table_free(&flowtable[0].ft);
-+ return ret;
-+}
-+
-+static void __exit xt_flowoffload_tg_exit(void)
-+{
-+ xt_unregister_target(&offload_tg_reg);
-+ unregister_netdevice_notifier(&flow_offload_netdev_notifier);
-+ nf_flow_table_free(&flowtable[0].ft);
-+ nf_flow_table_free(&flowtable[1].ft);
-+}
-+
-+MODULE_LICENSE("GPL");
-+module_init(xt_flowoffload_tg_init);
-+module_exit(xt_flowoffload_tg_exit);
---- a/net/netfilter/nf_flow_table_core.c
-+++ b/net/netfilter/nf_flow_table_core.c
-@@ -7,7 +7,6 @@
- #include <linux/netdevice.h>
- #include <net/ip.h>
- #include <net/ip6_route.h>
--#include <net/netfilter/nf_tables.h>
- #include <net/netfilter/nf_flow_table.h>
- #include <net/netfilter/nf_conntrack.h>
- #include <net/netfilter/nf_conntrack_core.h>
-@@ -374,8 +373,7 @@ flow_offload_lookup(struct nf_flowtable
- }
- EXPORT_SYMBOL_GPL(flow_offload_lookup);
-
--static int
--nf_flow_table_iterate(struct nf_flowtable *flow_table,
-+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
- void (*iter)(struct nf_flowtable *flowtable,
- struct flow_offload *flow, void *data),
- void *data)
-@@ -436,6 +434,7 @@ static void nf_flow_offload_gc_step(stru
- nf_flow_offload_stats(flow_table, flow);
- }
- }
-+EXPORT_SYMBOL_GPL(nf_flow_table_iterate);
-
- void nf_flow_table_gc_run(struct nf_flowtable *flow_table)
- {
---- /dev/null
-+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-+#ifndef _XT_FLOWOFFLOAD_H
-+#define _XT_FLOWOFFLOAD_H
-+
-+#include <linux/types.h>
-+
-+enum {
-+ XT_FLOWOFFLOAD_HW = 1 << 0,
-+
-+ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW
-+};
-+
-+struct xt_flowoffload_target_info {
-+ __u32 flags;
-+};
-+
-+#endif /* _XT_FLOWOFFLOAD_H */
---- a/include/net/netfilter/nf_flow_table.h
-+++ b/include/net/netfilter/nf_flow_table.h
-@@ -293,6 +293,11 @@ void nf_flow_table_free(struct nf_flowta
-
- void flow_offload_teardown(struct flow_offload *flow);
-
-+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
-+ void (*iter)(struct nf_flowtable *flowtable,
-+ struct flow_offload *flow, void *data),
-+ void *data);
-+
- void nf_flow_snat_port(const struct flow_offload *flow,
- struct sk_buff *skb, unsigned int thoff,
- u8 protocol, enum flow_offload_tuple_dir dir);
diff --git a/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch b/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch
deleted file mode 100644
index fd7d5346ad..0000000000
--- a/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001
-From: Imre Kaloz <kaloz@openwrt.org>
-Date: Fri, 7 Jul 2017 17:21:05 +0200
-Subject: mac80211: increase wireless mesh header size
-
-lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- include/linux/netdevice.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -149,8 +149,8 @@ static inline bool dev_xmit_complete(int
-
- #if defined(CONFIG_HYPERV_NET)
- # define LL_MAX_HEADER 128
--#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
--# if defined(CONFIG_MAC80211_MESH)
-+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1
-+# if defined(CONFIG_MAC80211_MESH) || 1
- # define LL_MAX_HEADER 128
- # else
- # define LL_MAX_HEADER 96
diff --git a/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch b/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch
deleted file mode 100644
index b923a2d206..0000000000
--- a/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:21:53 +0200
-Subject: hack: net: fq_codel: tune defaults for small devices
-
-Assume that x86_64 devices always have a big memory and do not need this
-optimization compared to devices with only 32 MB or 64 MB RAM.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/sched/sch_fq_codel.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/net/sched/sch_fq_codel.c
-+++ b/net/sched/sch_fq_codel.c
-@@ -471,7 +471,11 @@ static int fq_codel_init(struct Qdisc *s
-
- sch->limit = 10*1024;
- q->flows_cnt = 1024;
-+#ifdef CONFIG_X86_64
- q->memory_limit = 32 << 20; /* 32 MBytes */
-+#else
-+ q->memory_limit = 4 << 20; /* 4 MBytes */
-+#endif
- q->drop_batch_size = 64;
- q->quantum = psched_mtu(qdisc_dev(sch));
- INIT_LIST_HEAD(&q->new_flows);
diff --git a/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch b/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch
deleted file mode 100644
index fe94a9da0c..0000000000
--- a/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 804fbb3f2ec9283f7b778e057a68bfff440a0be6 Mon Sep 17 00:00:00 2001
-From: Rui Salvaterra <rsalvaterra@gmail.com>
-Date: Wed, 30 Mar 2022 22:51:55 +0100
-Subject: [PATCH] kernel: ct: size the hashtable more adequately
-
-To set the default size of the connection tracking hash table, a divider of
-16384 becomes inadequate for a router handling lots of connections. Divide by
-2048 instead, making the default size scale better with the available RAM.
-
-Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
----
- net/netfilter/nf_conntrack_core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/net/netfilter/nf_conntrack_core.c
-+++ b/net/netfilter/nf_conntrack_core.c
-@@ -2705,7 +2705,7 @@ int nf_conntrack_init_start(void)
-
- if (!nf_conntrack_htable_size) {
- nf_conntrack_htable_size
-- = (((nr_pages << PAGE_SHIFT) / 16384)
-+ = (((nr_pages << PAGE_SHIFT) / 2048)
- / sizeof(struct hlist_head));
- if (BITS_PER_LONG >= 64 &&
- nr_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE)))
diff --git a/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch
deleted file mode 100644
index 673082d840..0000000000
--- a/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:24:23 +0200
-Subject: net: swconfig: adds openwrt switch layer
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/phy/Makefile | 15 +++++++++
- include/uapi/linux/Kbuild | 1 +
- 3 files changed, 99 insertions(+)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -67,6 +67,80 @@ config SFP
- depends on HWMON || HWMON=n
- select MDIO_I2C
-
-+comment "Switch configuration API + drivers"
-+
-+config SWCONFIG
-+ tristate "Switch configuration API"
-+ help
-+ Switch configuration API using netlink. This allows
-+ you to configure the VLAN features of certain switches.
-+
-+config SWCONFIG_LEDS
-+ bool "Switch LED trigger support"
-+ depends on (SWCONFIG && LEDS_TRIGGERS)
-+
-+config ADM6996_PHY
-+ tristate "Driver for ADM6996 switches"
-+ select SWCONFIG
-+ help
-+ Currently supports the ADM6996FC and ADM6996M switches.
-+ Support for FC is very limited.
-+
-+config AR8216_PHY
-+ tristate "Driver for Atheros AR8216/8327 switches"
-+ select SWCONFIG
-+ select ETHERNET_PACKET_MANGLE
-+
-+config AR8216_PHY_LEDS
-+ bool "Atheros AR8216 switch LED support"
-+ depends on (AR8216_PHY && LEDS_CLASS)
-+
-+source "drivers/net/phy/b53/Kconfig"
-+
-+config IP17XX_PHY
-+ tristate "Driver for IC+ IP17xx switches"
-+ select SWCONFIG
-+
-+config PSB6970_PHY
-+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
-+ select SWCONFIG
-+
-+config RTL8306_PHY
-+ tristate "Driver for Realtek RTL8306S switches"
-+ select SWCONFIG
-+
-+config RTL8366_SMI
-+ tristate "Driver for the RTL8366 SMI interface"
-+ depends on GPIOLIB
-+ help
-+ This module implements the SMI interface protocol which is used
-+ by some RTL8366 ethernet switch devices via the generic GPIO API.
-+
-+if RTL8366_SMI
-+
-+config RTL8366_SMI_DEBUG_FS
-+ bool "RTL8366 SMI interface debugfs support"
-+ depends on DEBUG_FS
-+ default n
-+
-+config RTL8366S_PHY
-+ tristate "Driver for the Realtek RTL8366S switch"
-+ select SWCONFIG
-+
-+config RTL8366RB_PHY
-+ tristate "Driver for the Realtek RTL8366RB switch"
-+ select SWCONFIG
-+
-+config RTL8367_PHY
-+ tristate "Driver for the Realtek RTL8367R/M switches"
-+ select SWCONFIG
-+
-+config RTL8367B_PHY
-+ tristate "Driver fot the Realtek RTL8367R-VB switch"
-+ select SWCONFIG
-+
-+endif # RTL8366_SMI
-+
- comment "MII PHY device drivers"
-
- config AIR_EN8811H_PHY
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -24,6 +24,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_
- obj-$(CONFIG_PHYLINK) += phylink.o
- obj-$(CONFIG_PHYLIB) += libphy.o
-
-+obj-$(CONFIG_SWCONFIG) += swconfig.o
-+obj-$(CONFIG_ADM6996_PHY) += adm6996.o
-+obj-$(CONFIG_AR8216_PHY) += ar8xxx.o
-+ar8xxx-y += ar8216.o
-+ar8xxx-y += ar8327.o
-+obj-$(CONFIG_SWCONFIG_B53) += b53/
-+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
-+obj-$(CONFIG_PSB6970_PHY) += psb6970.o
-+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
-+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o
-+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o
-+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o
-+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o
-+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o
-+
- obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o
-
- obj-$(CONFIG_SFP) += sfp.o
---- a/include/linux/platform_data/b53.h
-+++ b/include/linux/platform_data/b53.h
-@@ -29,6 +29,9 @@ struct b53_platform_data {
- u32 chip_id;
- u16 enabled_ports;
-
-+ /* allow to specify an ethX alias */
-+ const char *alias;
-+
- /* only used by MMAP'd driver */
- unsigned big_endian:1;
- void __iomem *regs;
diff --git a/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch
deleted file mode 100644
index 75907bf472..0000000000
--- a/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From ebd924d773223593142d417c41d4ee6fa16f1805 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:45:56 +0200
-Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation
-
----
- drivers/net/dsa/mv88e6xxx/chip.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3510,6 +3510,9 @@ static int mv88e6xxx_setup_port(struct m
- else
- reg = 1 << port;
-
-+ /* Disable ATU member violation interrupt */
-+ reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG;
-+
- err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
- reg);
- if (err)
diff --git a/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch
deleted file mode 100644
index c6306c85cc..0000000000
--- a/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 7 Jul 2017 17:25:00 +0200
-Subject: net: add packet mangeling
-
-ar8216 switches have a hardware bug, which renders normal 802.1q support
-unusable. Packet mangling is required to fix up the vlan for incoming
-packets.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/netdevice.h | 11 +++++++++++
- include/linux/skbuff.h | 14 ++++----------
- net/Kconfig | 6 ++++++
- net/core/dev.c | 20 +++++++++++++++-----
- net/core/skbuff.c | 17 +++++++++++++++++
- net/ethernet/eth.c | 6 ++++++
- 6 files changed, 59 insertions(+), 15 deletions(-)
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1730,6 +1730,7 @@ enum netdev_priv_flags {
- /* was IFF_LIVE_RENAME_OK */
- IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
- IFF_CHANGE_PROTO_DOWN = BIT_ULL(32),
-+ IFF_NO_IP_ALIGN = BIT_ULL(33),
- };
-
- #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
-@@ -1763,6 +1764,7 @@ enum netdev_priv_flags {
- #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
- #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
- #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
-+#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
-
- /* Specifies the type of the struct net_device::ml_priv pointer */
- enum netdev_ml_priv_type {
-@@ -2131,6 +2133,11 @@ struct net_device {
- const struct tlsdev_ops *tlsdev_ops;
- #endif
-
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
-+ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
-+#endif
-+
- const struct header_ops *header_ops;
-
- unsigned char operstate;
-@@ -2204,6 +2211,10 @@ struct net_device {
- struct mctp_dev __rcu *mctp_ptr;
- #endif
-
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ void *phy_ptr; /* PHY device specific data */
-+#endif
-+
- /*
- * Cache lines mostly used on receive path (including eth_type_trans())
- */
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -3071,6 +3071,10 @@ static inline int pskb_trim(struct sk_bu
- return (len < skb->len) ? __pskb_trim(skb, len) : 0;
- }
-
-+extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
-+ unsigned int length, gfp_t gfp);
-+
-+
- /**
- * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
- * @skb: buffer to alter
-@@ -3220,16 +3224,6 @@ static inline struct sk_buff *dev_alloc_
- }
-
-
--static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
-- unsigned int length, gfp_t gfp)
--{
-- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
--
-- if (NET_IP_ALIGN && skb)
-- skb_reserve(skb, NET_IP_ALIGN);
-- return skb;
--}
--
- static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
- unsigned int length)
- {
---- a/net/Kconfig
-+++ b/net/Kconfig
-@@ -26,6 +26,12 @@ menuconfig NET
-
- if NET
-
-+config ETHERNET_PACKET_MANGLE
-+ bool
-+ help
-+ This option can be selected by phy drivers that need to mangle
-+ packets going in or out of an ethernet device.
-+
- config WANT_COMPAT_NETLINK_MESSAGES
- bool
- help
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -3607,6 +3607,11 @@ static int xmit_one(struct sk_buff *skb,
- if (dev_nit_active(dev))
- dev_queue_xmit_nit(skb, dev);
-
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb)))
-+ return NETDEV_TX_OK;
-+#endif
-+
- len = skb->len;
- trace_net_dev_start_xmit(skb, dev);
- rc = netdev_start_xmit(skb, dev, txq, more);
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -61,6 +61,7 @@
- #include <linux/if_vlan.h>
- #include <linux/mpls.h>
- #include <linux/kcov.h>
-+#include <linux/if.h>
-
- #include <net/protocol.h>
- #include <net/dst.h>
-@@ -709,6 +710,22 @@ skb_fail:
- }
- EXPORT_SYMBOL(__napi_alloc_skb);
-
-+struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
-+ unsigned int length, gfp_t gfp)
-+{
-+ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
-+
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
-+ return skb;
-+#endif
-+
-+ if (NET_IP_ALIGN && skb)
-+ skb_reserve(skb, NET_IP_ALIGN);
-+ return skb;
-+}
-+EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
-+
- void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
- int size, unsigned int truesize)
- {
---- a/net/ethernet/eth.c
-+++ b/net/ethernet/eth.c
-@@ -159,6 +159,12 @@ __be16 eth_type_trans(struct sk_buff *sk
- const struct ethhdr *eth;
-
- skb->dev = dev;
-+
-+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
-+ if (dev->eth_mangle_rx)
-+ dev->eth_mangle_rx(dev, skb);
-+#endif
-+
- skb_reset_mac_header(skb);
-
- eth = (struct ethhdr *)skb->data;
diff --git a/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch
deleted file mode 100644
index faaa40f9bd..0000000000
--- a/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001
-From: Alex Marginean <alexandru.marginean@nxp.com>
-Date: Tue, 27 Aug 2019 15:16:56 +0300
-Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412
-
-Adds support for AQR112 and AQR412 which is mostly based on existing code
-with the addition of code configuring the protocol on system side.
-This allows changing the system side protocol without having to deploy a
-different firmware on the PHY.
-
-Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
----
- drivers/net/phy/aquantia/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 88 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -27,6 +27,8 @@
- #define PHY_ID_AQR113 0x31c31c40
- #define PHY_ID_AQR113C 0x31c31c12
- #define PHY_ID_AQR813 0x31c31cb2
-+#define PHY_ID_AQR112 0x03a1b662
-+#define PHY_ID_AQR412 0x03a1b712
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -99,6 +101,29 @@
- #define AQR107_OP_IN_PROG_SLEEP 1000
- #define AQR107_OP_IN_PROG_TIMEOUT 100000
-
-+/* registers in MDIO_MMD_VEND1 region */
-+#define AQUANTIA_VND1_GLOBAL_SC 0x000
-+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb)
-+
-+/* global start rate, the protocol associated with this speed is used by default
-+ * on SI.
-+ */
-+#define AQUANTIA_VND1_GSTART_RATE 0x31a
-+#define AQUANTIA_VND1_GSTART_RATE_OFF 0
-+#define AQUANTIA_VND1_GSTART_RATE_100M 1
-+#define AQUANTIA_VND1_GSTART_RATE_1G 2
-+#define AQUANTIA_VND1_GSTART_RATE_10G 3
-+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4
-+#define AQUANTIA_VND1_GSTART_RATE_5G 5
-+
-+/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */
-+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b
-+#define AQUANTIA_VND1_GSYSCFG_100M 0
-+#define AQUANTIA_VND1_GSYSCFG_1G 1
-+#define AQUANTIA_VND1_GSYSCFG_2_5G 2
-+#define AQUANTIA_VND1_GSYSCFG_5G 3
-+#define AQUANTIA_VND1_GSYSCFG_10G 4
-+
- struct aqr107_hw_stat {
- const char *name;
- int reg;
-@@ -230,6 +255,51 @@ static int aqr_config_aneg(struct phy_de
- return genphy_c45_check_and_restart_aneg(phydev, changed);
- }
-
-+static struct {
-+ u16 syscfg;
-+ int cnt;
-+ u16 start_rate;
-+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = {
-+ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G,
-+ AQUANTIA_VND1_GSTART_RATE_1G},
-+ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G,
-+ AQUANTIA_VND1_GSTART_RATE_2_5G},
-+ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G,
-+ AQUANTIA_VND1_GSTART_RATE_10G},
-+ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G,
-+ AQUANTIA_VND1_GSTART_RATE_10G},
-+};
-+
-+/* Sets up protocol on system side before calling aqr_config_aneg */
-+static int aqr_config_aneg_set_prot(struct phy_device *phydev)
-+{
-+ int if_type = phydev->interface;
-+ int i;
-+
-+ if (!aquantia_syscfg[if_type].cnt)
-+ return 0;
-+
-+ /* set PHY in low power mode so we can configure protocols */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC,
-+ AQUANTIA_VND1_GLOBAL_SC_LP);
-+ mdelay(10);
-+
-+ /* set the default rate to enable the SI link */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
-+ aquantia_syscfg[if_type].start_rate);
-+
-+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++)
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+ AQUANTIA_VND1_GSYSCFG_BASE + i,
-+ aquantia_syscfg[if_type].syscfg);
-+
-+ /* wake PHY back up */
-+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0);
-+ mdelay(10);
-+
-+ return aqr_config_aneg(phydev);
-+}
-+
- static int aqr_config_intr(struct phy_device *phydev)
- {
- bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
-@@ -860,6 +930,30 @@ static struct phy_driver aqr_driver[] =
- .get_stats = aqr107_get_stats,
- .link_change_notify = aqr107_link_change_notify,
- },
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112),
-+ .name = "Aquantia AQR112",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
-+ .name = "Aquantia AQR412",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
- };
-
- module_phy_driver(aqr_driver);
-@@ -877,6 +971,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
- { }
- };
-
diff --git a/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch
deleted file mode 100644
index 72a70ebc14..0000000000
--- a/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 5f008cb22f60da4e10375f22266c1a4e20b1252e Mon Sep 17 00:00:00 2001
-From: Alex Marginean <alexandru.marginean@nxp.com>
-Date: Fri, 20 Sep 2019 18:22:52 +0300
-Subject: [PATCH] drivers: net: phy: aquantia: fix system side protocol
- misconfiguration
-
-Do not set up protocols for speeds that are not supported by FW. Enabling
-these protocols leads to link issues on system side.
-
-Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
----
- drivers/net/phy/aquantia/aquantia_main.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -288,10 +288,16 @@ static int aqr_config_aneg_set_prot(stru
- phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
- aquantia_syscfg[if_type].start_rate);
-
-- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++)
-+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) {
-+ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1,
-+ AQUANTIA_VND1_GSYSCFG_BASE + i);
-+ if (!reg)
-+ continue;
-+
- phy_write_mmd(phydev, MDIO_MMD_VEND1,
- AQUANTIA_VND1_GSYSCFG_BASE + i,
- aquantia_syscfg[if_type].syscfg);
-+ }
-
- /* wake PHY back up */
- phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0);
diff --git a/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch b/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch
deleted file mode 100644
index d83cc48a33..0000000000
--- a/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 3b92ee7b7899b6beffb2b484c58326e36612a873 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 23 Dec 2021 14:52:56 +0000
-Subject: [PATCH] net: phy: aquantia: add PHY_ID for AQR112R
-
-As advised by Ian Chang this PHY is used in Puzzle devices.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/aquantia/aquantia_main.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -29,6 +29,8 @@
- #define PHY_ID_AQR813 0x31c31cb2
- #define PHY_ID_AQR112 0x03a1b662
- #define PHY_ID_AQR412 0x03a1b712
-+#define PHY_ID_AQR112C 0x03a1b790
-+#define PHY_ID_AQR112R 0x31c31d12
-
- #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
- #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -960,6 +962,30 @@ static struct phy_driver aqr_driver[] =
- .get_strings = aqr107_get_strings,
- .get_stats = aqr107_get_stats,
- },
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C),
-+ .name = "Aquantia AQR112C",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
-+{
-+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R),
-+ .name = "Aquantia AQR112R",
-+ .probe = aqr107_probe,
-+ .config_aneg = aqr_config_aneg_set_prot,
-+ .config_intr = aqr_config_intr,
-+ .handle_interrupt = aqr_handle_interrupt,
-+ .read_status = aqr107_read_status,
-+ .get_sset_count = aqr107_get_sset_count,
-+ .get_strings = aqr107_get_strings,
-+ .get_stats = aqr107_get_stats,
-+},
- };
-
- module_phy_driver(aqr_driver);
-@@ -979,6 +1005,8 @@ static struct mdio_device_id __maybe_unu
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
- { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) },
-+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) },
- { }
- };
-
diff --git a/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch b/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch
deleted file mode 100644
index a2bd3a3dbb..0000000000
--- a/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 880d1311335120f64447ca9d11933872d734e19a Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 27 Mar 2023 18:41:54 +0100
-Subject: [PATCH] generic: pcs-mtk-lynxi: add hack to use 2500Base-X without AN
-
-Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
-disabling auto-negotiation, e.g. using ethtool. While a proper fix
-using SFP quirks is being discussed upstream, bring a work-around to
-restore user experience to what it was before the switch to the
-dedicated SGMII PCS driver.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/drivers/net/pcs/pcs-mtk-lynxi.c
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -114,14 +114,23 @@ static void mtk_pcs_lynxi_get_state(stru
- struct phylink_link_state *state)
- {
- struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-- unsigned int bm, adv;
-+ unsigned int bm, bmsr, adv;
-
- /* Read the BMSR and LPA */
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+ bmsr = FIELD_GET(SGMII_BMSR, bm);
-+
-+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
-+ state->link = !!(bmsr & BMSR_LSTATUS);
-+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
-+ state->speed = SPEED_2500;
-+ state->duplex = DUPLEX_FULL;
-
-- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-- FIELD_GET(SGMII_LPA, adv));
-+ return;
-+ }
-+
-+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
- }
-
- static void mtk_sgmii_reset(struct mtk_pcs_lynxi *mpcs)
-@@ -163,7 +172,8 @@ static int mtk_pcs_lynxi_config(struct p
- if (neg_mode & PHYLINK_PCS_NEG_INBAND)
- sgm_mode |= SGMII_REMOTE_FAULT_DIS;
-
-- if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
-+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
-+ interface != PHY_INTERFACE_MODE_2500BASEX) {
- if (interface == PHY_INTERFACE_MODE_SGMII)
- sgm_mode |= SGMII_SPEED_DUPLEX_AN;
- bmcr = BMCR_ANENABLE;
diff --git a/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch
deleted file mode 100644
index 48d4626ed6..0000000000
--- a/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 82985725e071f2a5735052f18e109a32aeac3a0b Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 26 Jul 2020 02:38:31 +0200
-Subject: [PATCH] net: usb: r8152: add LED configuration from OF
-
-This adds the ability to configure the LED configuration register using
-OF. This way, the correct value for board specific LED configuration can
-be determined.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
---- a/drivers/net/usb/r8152.c
-+++ b/drivers/net/usb/r8152.c
-@@ -11,6 +11,7 @@
- #include <linux/mii.h>
- #include <linux/ethtool.h>
- #include <linux/usb.h>
-+#include <linux/of.h>
- #include <linux/crc32.h>
- #include <linux/if_vlan.h>
- #include <linux/uaccess.h>
-@@ -7034,6 +7035,22 @@ static void rtl_tally_reset(struct r8152
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data);
- }
-
-+static int r8152_led_configuration(struct r8152 *tp)
-+{
-+ u32 led_data;
-+ int ret;
-+
-+ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data",
-+ &led_data);
-+
-+ if (ret)
-+ return ret;
-+
-+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data);
-+
-+ return 0;
-+}
-+
- static void r8152b_init(struct r8152 *tp)
- {
- u32 ocp_data;
-@@ -7075,6 +7092,8 @@ static void r8152b_init(struct r8152 *tp
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN);
- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
-+
-+ r8152_led_configuration(tp);
- }
-
- static void r8153_init(struct r8152 *tp)
-@@ -7215,6 +7234,8 @@ static void r8153_init(struct r8152 *tp)
- tp->coalesce = COALESCE_SLOW;
- break;
- }
-+
-+ r8152_led_configuration(tp);
- }
-
- static void r8153b_init(struct r8152 *tp)
-@@ -7297,6 +7318,8 @@ static void r8153b_init(struct r8152 *tp
- rtl_tally_reset(tp);
-
- tp->coalesce = 15000; /* 15 us */
-+
-+ r8152_led_configuration(tp);
- }
-
- static void r8153c_init(struct r8152 *tp)
diff --git a/target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch b/target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch
deleted file mode 100644
index be262b993c..0000000000
--- a/target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 3ee05f4aa64fc86af3be5bc176ba5808de9260a7 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 26 Jul 2020 15:30:33 +0200
-Subject: [PATCH] dt-bindings: net: add RTL8152 binding documentation
-
-Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet
-adapters.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- .../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++
- 1 file changed, 36 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
-@@ -0,0 +1,36 @@
-+# SPDX-License-Identifier: GPL-2.0
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Realtek RTL8152/RTL8153 series USB ethernet
-+
-+maintainers:
-+ - David Bauer <mail@david-bauer.net>
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - items:
-+ - enum:
-+ - realtek,rtl8152
-+ - realtek,rtl8153
-+
-+ reg:
-+ description: The device number on the USB bus
-+
-+ realtek,led-data:
-+ description: Value to be written to the LED configuration register.
-+
-+required:
-+ - compatible
-+ - reg
-+
-+examples:
-+ - |
-+ usb-eth@2 {
-+ compatible = "realtek,rtl8153";
-+ reg = <2>;
-+ realtek,led-data = <0x87>;
-+ };
-\ No newline at end of file
diff --git a/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch b/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch
deleted file mode 100644
index 2724efa15e..0000000000
--- a/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 94b90966095f3fa625897e8f53d215882f6e19b3 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sat, 11 Mar 2023 17:00:01 +0100
-Subject: [PATCH] mxl-gpy: control LED reg from DT
-
-Add dynamic configuration for the LED control registers on MXL PHYs.
-
-This patch has been tested with MaxLinear GPY211C. It is unlikely to be
-accepted upstream, as upstream plans on integrating their own framework
-for handling these LEDs.
-
-For the time being, use this hack to configure PHY driven device-LEDs to
-show the correct state.
-
-A possible alternative might be to expose the LEDs using the kernel LED
-framework and bind it to the netdevice. This might also be upstreamable,
-although it is a considerable extra amount of work.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/phy/mxl-gpy.c | 37 ++++++++++++++++++++++++++++++++++++-
- 1 file changed, 36 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -10,6 +10,7 @@
- #include <linux/bitfield.h>
- #include <linux/hwmon.h>
- #include <linux/mutex.h>
-+#include <linux/of.h>
- #include <linux/phy.h>
- #include <linux/polynomial.h>
- #include <linux/netdevice.h>
-@@ -33,6 +34,7 @@
- #define PHY_MIISTAT 0x18 /* MII state */
- #define PHY_IMASK 0x19 /* interrupt mask */
- #define PHY_ISTAT 0x1A /* interrupt status */
-+#define PHY_LED 0x1B /* LED control */
- #define PHY_FWV 0x1E /* firmware version */
-
- #define PHY_MIISTAT_SPD_MASK GENMASK(2, 0)
-@@ -56,10 +58,15 @@
- PHY_IMASK_ADSC | \
- PHY_IMASK_ANC)
-
-+#define PHY_LED_NUM_LEDS 4
-+
- #define PHY_FWV_REL_MASK BIT(15)
- #define PHY_FWV_MAJOR_MASK GENMASK(11, 8)
- #define PHY_FWV_MINOR_MASK GENMASK(7, 0)
-
-+/* LED */
-+#define VSPEC1_LED(x) (0x1 + x)
-+
- /* SGMII */
- #define VSPEC1_SGMII_CTRL 0x08
- #define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */
-@@ -241,6 +248,35 @@ out:
- return ret;
- }
-
-+static int gpy_led_write(struct phy_device *phydev)
-+{
-+ struct device_node *node = phydev->mdio.dev.of_node;
-+ u32 led_regs[PHY_LED_NUM_LEDS];
-+ int i, ret;
-+ u16 val = 0xff00;
-+
-+ if (!IS_ENABLED(CONFIG_OF_MDIO))
-+ return 0;
-+
-+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS))
-+ return 0;
-+
-+ if (of_property_read_bool(node, "mxl,led-drive-vdd"))
-+ val &= 0x0fff;
-+
-+ /* Enable LED function handling on all ports*/
-+ phy_write(phydev, PHY_LED, val);
-+
-+ /* Write LED register values */
-+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) {
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(i), (u16)led_regs[i]);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int gpy_config_init(struct phy_device *phydev)
- {
- int ret;
-@@ -252,7 +288,10 @@ static int gpy_config_init(struct phy_de
-
- /* Clear all pending interrupts */
- ret = phy_read(phydev, PHY_ISTAT);
-- return ret < 0 ? ret : 0;
-+ if (ret < 0)
-+ return ret;
-+
-+ return gpy_led_write(phydev);
- }
-
- static bool gpy_has_broken_mdint(struct phy_device *phydev)
diff --git a/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch b/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch
deleted file mode 100644
index 3405d5c535..0000000000
--- a/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From cc225d163b5a4f7a0d1968298bf7927306646a47 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Fri, 28 Apr 2023 01:53:01 +0200
-Subject: [PATCH] net: phy: mediatek-ge: add LED configuration interface
-
-This adds a small hack similar to the one used for ar8xxx switches to
-read a reg:value map for configuring the LED configuration registers.
-
-This allows OpenWrt to write device-specific LED action as well as blink
-configurations. It is unlikely to be accepted upstream, as upstream
-plans on integrating their own framework for handling these LEDs.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/phy/mediatek-ge.c | 33 +++++++++++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
---- a/drivers/net/phy/mediatek-ge.c
-+++ b/drivers/net/phy/mediatek-ge.c
-@@ -1,4 +1,5 @@
- // SPDX-License-Identifier: GPL-2.0+
-+#include <linux/of.h>
- #include <linux/bitfield.h>
- #include <linux/module.h>
- #include <linux/phy.h>
-@@ -53,6 +54,36 @@ static int mt7530_phy_config_init(struct
- return 0;
- }
-
-+static int mt7530_led_config_of(struct phy_device *phydev)
-+{
-+ struct device_node *np = phydev->mdio.dev.of_node;
-+ const __be32 *paddr;
-+ int len;
-+ int i;
-+
-+ paddr = of_get_property(np, "mediatek,led-config", &len);
-+ if (!paddr)
-+ return 0;
-+
-+ if (len < (2 * sizeof(*paddr)))
-+ return -EINVAL;
-+
-+ len /= sizeof(*paddr);
-+
-+ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len);
-+ for (i = 0; i < len - 1; i += 2) {
-+ u32 reg;
-+ u32 val;
-+
-+ reg = be32_to_cpup(paddr + i);
-+ val = be32_to_cpup(paddr + i + 1);
-+
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val);
-+ }
-+
-+ return 0;
-+}
-+
- static int mt7531_phy_config_init(struct phy_device *phydev)
- {
- mtk_gephy_config_init(phydev);
-@@ -65,6 +96,9 @@ static int mt7531_phy_config_init(struct
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
-
-+ /* LED Config*/
-+ mt7530_led_config_of(phydev);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch
deleted file mode 100644
index 633cacd1e7..0000000000
--- a/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 7 Jul 2017 17:26:01 +0200
-Subject: bcm53xx: bgmac: use srab switch driver
-
-use the srab switch driver on these SoCs.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 +
- drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++
- drivers/net/ethernet/broadcom/bgmac.h | 4 ++++
- 3 files changed, 29 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_devic
- bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
- bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
- bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
-+ bgmac->feature_flags |= BGMAC_FEAT_SRAB;
- break;
- default:
- bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -12,6 +12,7 @@
- #include <linux/bcma/bcma.h>
- #include <linux/etherdevice.h>
- #include <linux/interrupt.h>
-+#include <linux/platform_data/b53.h>
- #include <linux/bcm47xx_nvram.h>
- #include <linux/phy.h>
- #include <linux/phy_fixed.h>
-@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et
- .set_link_ksettings = phy_ethtool_set_link_ksettings,
- };
-
-+static struct b53_platform_data bgmac_b53_pdata = {
-+};
-+
-+static struct platform_device bgmac_b53_dev = {
-+ .name = "b53-srab-switch",
-+ .id = -1,
-+ .dev = {
-+ .platform_data = &bgmac_b53_pdata,
-+ },
-+};
-+
- /**************************************************
- * MII
- **************************************************/
-@@ -1546,6 +1558,14 @@ int bgmac_enet_probe(struct bgmac *bgmac
-
- bgmac->in_init = false;
-
-+ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) {
-+ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000);
-+
-+ err = platform_device_register(&bgmac_b53_dev);
-+ if (!err)
-+ bgmac->b53_device = &bgmac_b53_dev;
-+ }
-+
- err = register_netdev(bgmac->net_dev);
- if (err) {
- dev_err(bgmac->dev, "Cannot register net device\n");
-@@ -1568,6 +1588,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe);
-
- void bgmac_enet_remove(struct bgmac *bgmac)
- {
-+ if (bgmac->b53_device)
-+ platform_device_unregister(&bgmac_b53_dev);
-+ bgmac->b53_device = NULL;
-+
- unregister_netdev(bgmac->net_dev);
- phy_disconnect(bgmac->net_dev->phydev);
- netif_napi_del(&bgmac->napi);
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -388,6 +388,7 @@
- #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18)
- #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19)
- #define BGMAC_FEAT_IDM_MASK BIT(20)
-+#define BGMAC_FEAT_SRAB BIT(21)
-
- struct bgmac_slot_info {
- union {
-@@ -495,6 +496,9 @@ struct bgmac {
- void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
- u32 set);
- int (*phy_connect)(struct bgmac *bgmac);
-+
-+ /* platform device for associated switch */
-+ struct platform_device *b53_device;
- };
-
- struct bgmac *bgmac_alloc(struct device *dev);
diff --git a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch
deleted file mode 100644
index 2729a0ec38..0000000000
--- a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From f81700b6bb2eda3756247bce472d8eaf6f466f61 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:49:26 +0200
-Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
-
----
- drivers/net/usb/qmi_wwan.c | 1 +
- drivers/usb/serial/option.c | 7 +++++++
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/usb/qmi_wwan.c
-+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1082,12 +1082,18 @@ static const struct usb_device_id produc
- USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
- .driver_info = (unsigned long)&qmi_wwan_info,
- },
-+ { /* Meiglink SGM828 */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, USB_CLASS_VENDOR_SPEC, 0x10, 0x05),
-+ .driver_info = (unsigned long)&qmi_wwan_info,
-+ },
-+
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */
- {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */
-+ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* MeigLink SLM750 */
-
- /* 3. Combined interface devices matching on interface number */
- {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
---- a/drivers/usb/serial/option.c
-+++ b/drivers/usb/serial/option.c
-@@ -247,6 +247,11 @@ static void option_instat_callback(struc
- #define UBLOX_PRODUCT_R410M 0x90b2
- /* These Yuga products use Qualcomm's vendor ID */
- #define YUGA_PRODUCT_CLM920_NC5 0x9625
-+/* These MeigLink products use Qualcomm's vendor ID */
-+#define MEIGLINK_PRODUCT_SLM750 0xf601
-+
-+#define MEIGLINK_VENDOR_ID 0x2dee
-+#define MEIGLINK_PRODUCT_SLM828 0x4d49
-
- #define QUECTEL_VENDOR_ID 0x2c7c
- /* These Quectel products use Quectel's vendor ID */
-@@ -1156,6 +1161,11 @@ static const struct usb_device_id option
- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */
- .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) },
-+ /* MeiG */
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x01) },
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x02) },
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x03) },
-+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x04) },
- /* Quectel products using Qualcomm vendor ID */
- { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
- { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
-@@ -1197,6 +1207,11 @@ static const struct usb_device_id option
- .driver_info = ZLP },
- { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
- .driver_info = RSVD(4) },
-+ /* Meiglink products using Qualcomm vendor ID */
-+ // Works OK. In case of some issues check macros that are used by Quectel Products
-+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0xff, 0xff),
-+ .driver_info = NUMEP2 },
-+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0, 0) },
- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
- .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
diff --git a/target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch b/target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch
deleted file mode 100644
index 47339b6c22..0000000000
--- a/target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 9fabf60187f1fa19e6f6bb5441587d485bd534b0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 9 Apr 2024 17:06:38 +0100
-Subject: [PATCH] rndis_host: add a bunch of USB IDs
-
-Add a bunch of USB IDs found in various places online to the
-RNDIS USB network driver.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/usb/rndis_host.c | 40 ++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
---- a/drivers/net/usb/rndis_host.c
-+++ b/drivers/net/usb/rndis_host.c
-@@ -630,6 +630,16 @@ static const struct driver_info zte_rndi
- .tx_fixup = rndis_tx_fixup,
- };
-
-+static const struct driver_info asr_rndis_info = {
-+ .description = "Asr RNDIS device",
-+ .flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT | FLAG_NOARP,
-+ .bind = rndis_bind,
-+ .unbind = rndis_unbind,
-+ .status = rndis_status,
-+ .rx_fixup = rndis_rx_fixup,
-+ .tx_fixup = rndis_tx_fixup,
-+};
-+
- /*-------------------------------------------------------------------------*/
-
- static const struct usb_device_id products [] = {
-@@ -666,6 +676,36 @@ static const struct usb_device_id produc
- USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
- .driver_info = (unsigned long) &rndis_info,
- }, {
-+ /* Quectel EG060V rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6004,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Quectel EC200A rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6005,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Quectel EC200T rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6026,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Simcom A7906E rndis device */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x1e0e, 0x9011,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Meig SLM770A */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
-+ /* Meig SLM828 */
-+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49,
-+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
-+ .driver_info = (unsigned long) &asr_rndis_info,
-+}, {
- /* Novatel Verizon USB730L */
- USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
- .driver_info = (unsigned long) &rndis_info,
diff --git a/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch b/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch
deleted file mode 100644
index 53f199d09b..0000000000
--- a/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 7cc39a6bedbd85f3ff7e16845f310e4ce8d9833f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 6 Sep 2022 00:31:19 +0100
-Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
-To: netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- Russell King <linux@armlinux.org.uk>,
- Andrew Lunn <andrew@lunn.ch>,
- Heiner Kallweit <hkallweit1@gmail.com>
-Cc: David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Josef Schlehofer <pepe.schlehofer@gmail.com>
-
-This copper module comes with broken TX_FAULT indicator which must be
-ignored for it to work. Implement ignoring TX_FAULT state bit also
-during reset/insertion and mute the warning telling the user that the
-module indicates TX_FAULT.
-
-Co-authored-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/sfp.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -409,6 +409,9 @@ static const struct sfp_quirk sfp_quirks
- SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
- sfp_fixup_ignore_tx_fault),
-
-+ // OEM SFP-GE-T is 1000Base-T module
-+ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
-+
- // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
- // 2500MBd NRZ in their EEPROM
- SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
-@@ -2343,7 +2346,8 @@ static void sfp_sm_main(struct sfp *sfp,
- * or t_start_up, so assume there is a fault.
- */
- sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
-- sfp->sm_fault_retries == N_FAULT_INIT);
-+ !sfp->tx_fault_ignore &&
-+ (sfp->sm_fault_retries == N_FAULT_INIT));
- } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
- init_done:
- /* Create mdiobus and start trying for PHY */
-@@ -2577,10 +2581,12 @@ static void sfp_check_state(struct sfp *
- mutex_lock(&sfp->st_mutex);
- state = sfp_get_state(sfp);
- changed = state ^ sfp->state;
-- if (sfp->tx_fault_ignore)
-+ if (sfp->tx_fault_ignore) {
- changed &= SFP_F_PRESENT | SFP_F_LOS;
-- else
-+ state &= ~SFP_F_TX_FAULT;
-+ } else {
- changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
-+ }
-
- for (i = 0; i < GPIO_MAX; i++)
- if (changed & BIT(i))
diff --git a/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch
deleted file mode 100644
index b60b428dc8..0000000000
--- a/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 12 Aug 2014 20:49:27 +0200
-Subject: [PATCH 30/36] GPIO: add named gpio exports
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
---- a/drivers/gpio/gpiolib-of.c
-+++ b/drivers/gpio/gpiolib-of.c
-@@ -19,6 +19,8 @@
- #include <linux/pinctrl/pinctrl.h>
- #include <linux/slab.h>
- #include <linux/gpio/machine.h>
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
-
- #include "gpiolib.h"
- #include "gpiolib-of.h"
-@@ -1030,3 +1032,100 @@ void of_gpio_dev_init(struct gpio_chip *
- else
- gc->of_node = gdev->dev.of_node;
- }
-+
-+#ifdef CONFIG_GPIO_SYSFS
-+
-+static struct of_device_id gpio_export_ids[] = {
-+ { .compatible = "gpio-export" },
-+ { /* sentinel */ }
-+};
-+
-+static int of_gpio_export_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct device_node *cnp;
-+ u32 val;
-+ int nb = 0;
-+
-+ for_each_child_of_node(np, cnp) {
-+ const char *name = NULL;
-+ int gpio;
-+ bool dmc;
-+ int max_gpio = 1;
-+ int i;
-+
-+ of_property_read_string(cnp, "gpio-export,name", &name);
-+
-+ if (!name)
-+ max_gpio = of_gpio_count(cnp);
-+
-+ for (i = 0; i < max_gpio; i++) {
-+ struct gpio_desc *desc;
-+ unsigned flags = 0;
-+ enum of_gpio_flags of_flags;
-+
-+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
-+ if (!gpio_is_valid(gpio))
-+ return gpio;
-+
-+ if (of_flags & OF_GPIO_ACTIVE_LOW)
-+ flags |= GPIOF_ACTIVE_LOW;
-+
-+ if (!of_property_read_u32(cnp, "gpio-export,output", &val)) {
-+ if (of_flags & OF_GPIO_SINGLE_ENDED) {
-+ /*
-+ * As gpiod_direction_output_raw() is used, we
-+ * need to emulate open drain or open source here.
-+ */
-+ if (of_flags & OF_GPIO_OPEN_DRAIN) {
-+ flags |= GPIOF_OPEN_DRAIN;
-+ flags |= val ? GPIOF_IN : GPIOF_OUT_INIT_LOW;
-+ } else {
-+ flags |= GPIOF_OPEN_SOURCE;
-+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_IN;
-+ }
-+ } else {
-+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-+ }
-+ } else {
-+ flags |= GPIOF_IN;
-+ }
-+
-+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
-+ continue;
-+
-+ /*
-+ * When emulating open-source or open-drain functionalities by not
-+ * actively driving the line (setting mode to input) we still need to
-+ * set the IS_OUT flag or otherwise we won't be able to set the line
-+ * value anymore.
-+ */
-+ if ((flags & GPIOF_IN) &&
-+ ((flags & GPIOF_OPEN_DRAIN) || (flags & GPIOF_OPEN_SOURCE))) {
-+ desc = gpio_to_desc(gpio);
-+ set_bit(FLAG_IS_OUT, &desc->flags);
-+ }
-+
-+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
-+ gpio_export_with_name(gpio, dmc, name);
-+ nb++;
-+ }
-+ }
-+
-+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver gpio_export_driver = {
-+ .driver = {
-+ .name = "gpio-export",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(gpio_export_ids),
-+ },
-+ .probe = of_gpio_export_probe,
-+};
-+
-+module_platform_driver(gpio_export_driver);
-+
-+#endif
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -125,6 +125,12 @@ static inline int gpio_export(unsigned g
- return gpiod_export(gpio_to_desc(gpio), direction_may_change);
- }
-
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
-+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
-+{
-+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
-+}
-+
- static inline int gpio_export_link(struct device *dev, const char *name,
- unsigned gpio)
- {
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -715,6 +715,7 @@ static inline struct gpio_desc *acpi_get
-
- #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
-
-+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
- int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
- int gpiod_export_link(struct device *dev, const char *name,
- struct gpio_desc *desc);
-@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de
-
- #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
-
-+static inline int _gpiod_export(struct gpio_desc *desc,
-+ bool direction_may_change,
-+ const char *name)
-+{
-+ return -ENOSYS;
-+}
-+
- static inline int gpiod_export(struct gpio_desc *desc,
- bool direction_may_change)
- {
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -547,7 +547,7 @@ static struct class gpio_class = {
- *
- * Returns zero on success, else an error.
- */
--int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
- {
- struct gpio_chip *chip;
- struct gpio_device *gdev;
-@@ -609,6 +609,8 @@ int gpiod_export(struct gpio_desc *desc,
- offset = gpio_chip_hwgpio(desc);
- if (chip->names && chip->names[offset])
- ioname = chip->names[offset];
-+ if (name)
-+ ioname = name;
-
- dev = device_create_with_groups(&gpio_class, &gdev->dev,
- MKDEV(0, 0), data, gpio_groups,
-@@ -630,6 +632,12 @@ err_unlock:
- gpiod_dbg(desc, "%s: status %d\n", __func__, status);
- return status;
- }
-+EXPORT_SYMBOL_GPL(__gpiod_export);
-+
-+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+{
-+ return __gpiod_export(desc, direction_may_change, NULL);
-+}
- EXPORT_SYMBOL_GPL(gpiod_export);
-
- static int match_export(struct device *dev, const void *desc)
diff --git a/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch b/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch
deleted file mode 100644
index c581a512cb..0000000000
--- a/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From e4d708702e6c98f2111e33201a264d6788564cb2 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Fri, 12 May 2023 11:08:43 +0200
-Subject: [PATCH] ssb_sprom: add generic kernel support for Broadcom Fallback SPROMs
-
----
- drivers/bcma/Kconfig | 4 ++++
- drivers/bcma/Makefile | 1 +
- drivers/bcma/bcma_private.h | 4 ++++
- drivers/bcma/main.c | 8 ++++++++
- drivers/bcma/sprom.c | 23 ++++++++++++++---------
- drivers/ssb/Kconfig | 5 +++++
- drivers/ssb/Makefile | 1 +
- drivers/ssb/main.c | 8 ++++++++
- drivers/ssb/sprom.c | 12 +++++++++++-
- drivers/ssb/ssb_private.h | 4 ++++
- 10 files changed, 60 insertions(+), 10 deletions(-)
-
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -18,6 +18,10 @@ config BCMA_BLOCKIO
- bool
- default y
-
-+config BCMA_FALLBACK_SPROM
-+ bool
-+ default y
-+
- config BCMA_HOST_PCI_POSSIBLE
- bool
- depends on PCI = y
---- a/drivers/bcma/Makefile
-+++ b/drivers/bcma/Makefile
-@@ -11,6 +11,7 @@ bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)
- bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
- bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o
- bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o
-+bcma-$(CONFIG_BCMA_FALLBACK_SPROM) += fallback-sprom.o
- bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
- bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
- obj-$(CONFIG_BCMA) += bcma.o
---- a/drivers/bcma/bcma_private.h
-+++ b/drivers/bcma/bcma_private.h
-@@ -38,6 +38,10 @@ int bcma_bus_resume(struct bcma_bus *bus
- void bcma_detect_chip(struct bcma_bus *bus);
- int bcma_bus_scan(struct bcma_bus *bus);
-
-+/* fallback-sprom.c */
-+int __init bcma_fbs_register(void);
-+int bcma_get_fallback_sprom(struct bcma_bus *dev, struct ssb_sprom *out);
-+
- /* sprom.c */
- int bcma_sprom_get(struct bcma_bus *bus);
-
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -668,6 +668,14 @@ static int __init bcma_modinit(void)
- {
- int err;
-
-+#ifdef CONFIG_BCMA_FALLBACK_SPROM
-+ err = bcma_fbs_register();
-+ if (err) {
-+ pr_err("Fallback SPROM initialization failed\n");
-+ err = 0;
-+ }
-+#endif /* CONFIG_BCMA_FALLBACK_SPROM */
-+
- err = bcma_init_bus_register();
- if (err)
- return err;
---- a/drivers/bcma/sprom.c
-+++ b/drivers/bcma/sprom.c
-@@ -51,21 +51,26 @@ static int bcma_fill_sprom_with_fallback
- {
- int err;
-
-- if (!get_fallback_sprom) {
-+ if (get_fallback_sprom)
-+ err = get_fallback_sprom(bus, out);
-+
-+#ifdef CONFIG_BCMA_FALLBACK_SPROM
-+ if (!get_fallback_sprom || err)
-+ err = bcma_get_fallback_sprom(bus, out);
-+#else
-+ if (!get_fallback_sprom)
- err = -ENOENT;
-- goto fail;
-- }
-+#endif /* CONFIG_BCMA_FALLBACK_SPROM */
-
-- err = get_fallback_sprom(bus, out);
-- if (err)
-- goto fail;
-+ if (err) {
-+ bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err);
-+ return err;
-+ }
-
- bcma_debug(bus, "Using SPROM revision %d provided by platform.\n",
- bus->sprom.revision);
-+
- return 0;
--fail:
-- bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err);
-- return err;
- }
-
- /**************************************************
---- a/drivers/ssb/Kconfig
-+++ b/drivers/ssb/Kconfig
-@@ -25,6 +25,11 @@ if SSB
- config SSB_SPROM
- bool
-
-+config SSB_FALLBACK_SPROM
-+ bool
-+ depends on SSB_PCIHOST
-+ default y
-+
- # Support for Block-I/O. SELECT this from the driver that needs it.
- config SSB_BLOCKIO
- bool
---- a/drivers/ssb/Makefile
-+++ b/drivers/ssb/Makefile
-@@ -2,6 +2,7 @@
- # core
- ssb-y += main.o scan.o
- ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o
-+ssb-$(CONFIG_SSB_FALLBACK_SPROM) += fallback-sprom.o
- ssb-$(CONFIG_SSB_SPROM) += sprom.o
-
- # host support
---- a/drivers/ssb/main.c
-+++ b/drivers/ssb/main.c
-@@ -1287,6 +1287,14 @@ static int __init ssb_modinit(void)
- {
- int err;
-
-+#ifdef CONFIG_SSB_FALLBACK_SPROM
-+ err = ssb_fbs_register();
-+ if (err) {
-+ pr_err("Fallback SPROM initialization failed\n");
-+ err = 0;
-+ }
-+#endif /* CONFIG_SSB_FALLBACK_SPROM */
-+
- /* See the comment at the ssb_is_early_boot definition */
- ssb_is_early_boot = 0;
- err = bus_register(&ssb_bustype);
---- a/drivers/ssb/sprom.c
-+++ b/drivers/ssb/sprom.c
-@@ -180,10 +180,20 @@ int ssb_arch_register_fallback_sprom(int
-
- int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
- {
-+ int err;
-+
-+ if (get_fallback_sprom)
-+ err = get_fallback_sprom(bus, out);
-+
-+#ifdef CONFIG_SSB_FALLBACK_SPROM
-+ if (!get_fallback_sprom || err)
-+ err = ssb_get_fallback_sprom(bus, out);
-+#else
- if (!get_fallback_sprom)
- return -ENOENT;
-+#endif /* CONFIG_SSB_FALLBACK_SPROM */
-
-- return get_fallback_sprom(bus, out);
-+ return err;
- }
-
- /* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
---- a/drivers/ssb/ssb_private.h
-+++ b/drivers/ssb/ssb_private.h
-@@ -143,6 +143,10 @@ extern int ssb_bus_scan(struct ssb_bus *
- extern void ssb_iounmap(struct ssb_bus *ssb);
-
-
-+/* fallback-sprom.c */
-+int __init ssb_fbs_register(void);
-+int ssb_get_fallback_sprom(struct ssb_bus *dev, struct ssb_sprom *out);
-+
- /* sprom.c */
- extern
- ssize_t ssb_attr_sprom_show(struct ssb_bus *bus, char *buf,
diff --git a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch b/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch
deleted file mode 100644
index 09b59478aa..0000000000
--- a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 8 Jul 2017 08:16:31 +0200
-Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/Kconfig | 3 +++
- net/core/Makefile | 3 ++-
- net/core/sock.c | 2 ++
- net/ipv4/Kconfig | 1 +
- net/netlink/Kconfig | 1 +
- net/packet/Kconfig | 1 +
- net/unix/Kconfig | 1 +
- 7 files changed, 11 insertions(+), 1 deletion(-)
-
---- a/net/Kconfig
-+++ b/net/Kconfig
-@@ -104,6 +104,9 @@ source "net/mptcp/Kconfig"
-
- endif # if INET
-
-+config SOCK_DIAG
-+ bool
-+
- config NETWORK_SECMARK
- bool "Security Marking"
- help
---- a/net/core/Makefile
-+++ b/net/core/Makefile
-@@ -11,11 +11,12 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.
-
- obj-y += dev.o dev_addr_lists.o dst.o netevent.o \
- neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
-- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
-+ dev_ioctl.o tso.o sock_reuseport.o \
- fib_notifier.o xdp.o flow_offload.o gro.o
-
- obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
-
-+obj-$(CONFIG_SOCK_DIAG) += sock_diag.o
- obj-y += net-sysfs.o
- obj-$(CONFIG_PAGE_POOL) += page_pool.o
- obj-$(CONFIG_PROC_FS) += net-procfs.o
---- a/net/core/sock.c
-+++ b/net/core/sock.c
-@@ -115,6 +115,7 @@
- #include <linux/memcontrol.h>
- #include <linux/prefetch.h>
- #include <linux/compat.h>
-+#include <linux/cookie.h>
-
- #include <linux/uaccess.h>
-
-@@ -146,6 +147,7 @@
-
- static DEFINE_MUTEX(proto_list_mutex);
- static LIST_HEAD(proto_list);
-+DEFINE_COOKIE(sock_cookie);
-
- static void sock_def_write_space_wfree(struct sock *sk);
- static void sock_def_write_space(struct sock *sk);
-@@ -586,6 +588,18 @@ discard_and_relse:
- }
- EXPORT_SYMBOL(__sk_receive_skb);
-
-+u64 __sock_gen_cookie(struct sock *sk)
-+{
-+ while (1) {
-+ u64 res = atomic64_read(&sk->sk_cookie);
-+
-+ if (res)
-+ return res;
-+ res = gen_cookie_next(&sock_cookie);
-+ atomic64_cmpxchg(&sk->sk_cookie, 0, res);
-+ }
-+}
-+
- INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *,
- u32));
- INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *,
-@@ -2189,9 +2203,11 @@ static void __sk_free(struct sock *sk)
- if (likely(sk->sk_net_refcnt))
- sock_inuse_add(sock_net(sk), -1);
-
-+#ifdef CONFIG_SOCK_DIAG
- if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk)))
- sock_diag_broadcast_destroy(sk);
- else
-+#endif
- sk_destruct(sk);
- }
-
---- a/net/core/sock_diag.c
-+++ b/net/core/sock_diag.c
-@@ -12,7 +12,6 @@
- #include <linux/tcp.h>
- #include <linux/workqueue.h>
- #include <linux/nospec.h>
--#include <linux/cookie.h>
- #include <linux/inet_diag.h>
- #include <linux/sock_diag.h>
-
-@@ -21,20 +20,6 @@ static int (*inet_rcv_compat)(struct sk_
- static DEFINE_MUTEX(sock_diag_table_mutex);
- static struct workqueue_struct *broadcast_wq;
-
--DEFINE_COOKIE(sock_cookie);
--
--u64 __sock_gen_cookie(struct sock *sk)
--{
-- while (1) {
-- u64 res = atomic64_read(&sk->sk_cookie);
--
-- if (res)
-- return res;
-- res = gen_cookie_next(&sock_cookie);
-- atomic64_cmpxchg(&sk->sk_cookie, 0, res);
-- }
--}
--
- int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie)
- {
- u64 res;
---- a/net/ipv4/Kconfig
-+++ b/net/ipv4/Kconfig
-@@ -423,6 +423,7 @@ config INET_TUNNEL
-
- config INET_DIAG
- tristate "INET: socket monitoring interface"
-+ select SOCK_DIAG
- default y
- help
- Support for INET (TCP, DCCP, etc) socket monitoring interface used by
---- a/net/netlink/Kconfig
-+++ b/net/netlink/Kconfig
-@@ -5,6 +5,7 @@
-
- config NETLINK_DIAG
- tristate "NETLINK: socket monitoring interface"
-+ select SOCK_DIAG
- default n
- help
- Support for NETLINK socket monitoring interface used by the ss tool.
---- a/net/packet/Kconfig
-+++ b/net/packet/Kconfig
-@@ -19,6 +19,7 @@ config PACKET
- config PACKET_DIAG
- tristate "Packet: sockets monitoring interface"
- depends on PACKET
-+ select SOCK_DIAG
- default n
- help
- Support for PF_PACKET sockets monitoring interface used by the ss tool.
---- a/net/unix/Kconfig
-+++ b/net/unix/Kconfig
-@@ -33,6 +33,7 @@ config AF_UNIX_OOB
- config UNIX_DIAG
- tristate "UNIX: socket monitoring interface"
- depends on UNIX
-+ select SOCK_DIAG
- default n
- help
- Support for UNIX socket monitoring interface used by the ss tool.
---- a/net/xdp/Kconfig
-+++ b/net/xdp/Kconfig
-@@ -10,6 +10,7 @@ config XDP_SOCKETS
- config XDP_SOCKETS_DIAG
- tristate "XDP sockets: monitoring interface"
- depends on XDP_SOCKETS
-+ select SOCK_DIAG
- default n
- help
- Support for PF_XDP sockets monitoring interface used by the ss tool.
diff --git a/target/linux/generic/hack-6.1/902-debloat_proc.patch b/target/linux/generic/hack-6.1/902-debloat_proc.patch
deleted file mode 100644
index 06b3a04f7a..0000000000
--- a/target/linux/generic/hack-6.1/902-debloat_proc.patch
+++ /dev/null
@@ -1,419 +0,0 @@
-From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 8 Jul 2017 08:20:09 +0200
-Subject: debloat: procfs
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- fs/locks.c | 2 ++
- fs/proc/Kconfig | 5 +++++
- fs/proc/consoles.c | 3 +++
- fs/proc/proc_tty.c | 11 ++++++++++-
- include/net/snmp.h | 18 +++++++++++++++++-
- ipc/msg.c | 3 +++
- ipc/sem.c | 2 ++
- ipc/shm.c | 2 ++
- ipc/util.c | 3 +++
- kernel/exec_domain.c | 2 ++
- kernel/irq/proc.c | 9 +++++++++
- kernel/time/timer_list.c | 2 ++
- mm/vmalloc.c | 2 ++
- mm/vmstat.c | 8 +++++---
- net/8021q/vlanproc.c | 6 ++++++
- net/core/net-procfs.c | 18 ++++++++++++------
- net/core/sock.c | 2 ++
- net/ipv4/fib_trie.c | 18 ++++++++++++------
- net/ipv4/proc.c | 3 +++
- net/ipv4/route.c | 3 +++
- 20 files changed, 105 insertions(+), 17 deletions(-)
-
---- a/fs/locks.c
-+++ b/fs/locks.c
-@@ -2909,6 +2909,8 @@ static const struct seq_operations locks
-
- static int __init proc_locks_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- proc_create_seq_private("locks", 0, NULL, &locks_seq_operations,
- sizeof(struct locks_iterator), NULL);
- return 0;
---- a/fs/proc/Kconfig
-+++ b/fs/proc/Kconfig
-@@ -101,6 +101,11 @@ config PROC_CHILDREN
- Say Y if you are running any user-space software which takes benefit from
- this interface. For example, rkt is such a piece of software.
-
-+config PROC_STRIPPED
-+ default n
-+ depends on EXPERT
-+ bool "Strip non-essential /proc functionality to reduce code size"
-+
- config PROC_PID_ARCH_STATUS
- def_bool n
- depends on PROC_FS
---- a/fs/proc/consoles.c
-+++ b/fs/proc/consoles.c
-@@ -92,6 +92,9 @@ static const struct seq_operations conso
-
- static int __init proc_consoles_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- proc_create_seq("consoles", 0, NULL, &consoles_op);
- return 0;
- }
---- a/fs/proc/proc_tty.c
-+++ b/fs/proc/proc_tty.c
-@@ -131,7 +131,10 @@ static const struct seq_operations tty_d
- void proc_tty_register_driver(struct tty_driver *driver)
- {
- struct proc_dir_entry *ent;
--
-+
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- if (!driver->driver_name || driver->proc_entry ||
- !driver->ops->proc_show)
- return;
-@@ -148,6 +151,9 @@ void proc_tty_unregister_driver(struct t
- {
- struct proc_dir_entry *ent;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- ent = driver->proc_entry;
- if (!ent)
- return;
-@@ -162,6 +168,9 @@ void proc_tty_unregister_driver(struct t
- */
- void __init proc_tty_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- if (!proc_mkdir("tty", NULL))
- return;
- proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */
---- a/include/net/snmp.h
-+++ b/include/net/snmp.h
-@@ -124,6 +124,21 @@ struct linux_tls_mib {
- #define DECLARE_SNMP_STAT(type, name) \
- extern __typeof__(type) __percpu *name
-
-+#ifdef CONFIG_PROC_STRIPPED
-+#define __SNMP_STATS_DUMMY(mib) \
-+ do { (void) mib->mibs[0]; } while(0)
-+
-+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
-+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
-+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
-+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
-+
-+#else
-+
- #define __SNMP_INC_STATS(mib, field) \
- __this_cpu_inc(mib->mibs[field])
-
-@@ -154,8 +169,9 @@ struct linux_tls_mib {
- __this_cpu_add(ptr[basefield##OCTETS], addend); \
- } while (0)
-
-+#endif
-
--#if BITS_PER_LONG==32
-+#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED)
-
- #define __SNMP_ADD_STATS64(mib, field, addend) \
- do { \
---- a/ipc/msg.c
-+++ b/ipc/msg.c
-@@ -1370,6 +1370,9 @@ void __init msg_init(void)
- {
- msg_init_ns(&init_ipc_ns);
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- ipc_init_proc_interface("sysvipc/msg",
- " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
- IPC_MSG_IDS, sysvipc_msg_proc_show);
---- a/ipc/sem.c
-+++ b/ipc/sem.c
-@@ -268,6 +268,8 @@ void sem_exit_ns(struct ipc_namespace *n
- void __init sem_init(void)
- {
- sem_init_ns(&init_ipc_ns);
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
- ipc_init_proc_interface("sysvipc/sem",
- " key semid perms nsems uid gid cuid cgid otime ctime\n",
- IPC_SEM_IDS, sysvipc_sem_proc_show);
---- a/ipc/shm.c
-+++ b/ipc/shm.c
-@@ -154,6 +154,8 @@ pure_initcall(ipc_ns_init);
-
- void __init shm_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
- ipc_init_proc_interface("sysvipc/shm",
- #if BITS_PER_LONG <= 32
- " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
---- a/ipc/util.c
-+++ b/ipc/util.c
-@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons
- struct proc_dir_entry *pde;
- struct ipc_proc_iface *iface;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- iface = kmalloc(sizeof(*iface), GFP_KERNEL);
- if (!iface)
- return;
---- a/kernel/exec_domain.c
-+++ b/kernel/exec_domain.c
-@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct
-
- static int __init proc_execdomains_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- proc_create_single("execdomains", 0, NULL, execdomains_proc_show);
- return 0;
- }
---- a/kernel/irq/proc.c
-+++ b/kernel/irq/proc.c
-@@ -341,6 +341,9 @@ void register_irq_proc(unsigned int irq,
- void __maybe_unused *irqp = (void *)(unsigned long) irq;
- char name [MAX_NAMELEN];
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
-+ return;
-+
- if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
- return;
-
-@@ -394,6 +397,9 @@ void unregister_irq_proc(unsigned int ir
- {
- char name [MAX_NAMELEN];
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
-+ return;
-+
- if (!root_irq_dir || !desc->dir)
- return;
- #ifdef CONFIG_SMP
-@@ -432,6 +438,9 @@ void init_irq_proc(void)
- unsigned int irq;
- struct irq_desc *desc;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
-+ return;
-+
- /* create /proc/irq */
- root_irq_dir = proc_mkdir("irq", NULL);
- if (!root_irq_dir)
---- a/kernel/time/timer_list.c
-+++ b/kernel/time/timer_list.c
-@@ -350,6 +350,8 @@ static int __init init_timer_list_procfs
- {
- struct proc_dir_entry *pe;
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops,
- sizeof(struct timer_list_iter), NULL);
- if (!pe)
---- a/mm/vmalloc.c
-+++ b/mm/vmalloc.c
-@@ -4222,6 +4222,8 @@ static const struct seq_operations vmall
-
- static int __init proc_vmalloc_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- if (IS_ENABLED(CONFIG_NUMA))
- proc_create_seq_private("vmallocinfo", 0400, NULL,
- &vmalloc_op,
---- a/mm/vmstat.c
-+++ b/mm/vmstat.c
-@@ -2109,10 +2109,12 @@ void __init init_mm_internals(void)
- start_shepherd_timer();
- #endif
- #ifdef CONFIG_PROC_FS
-- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
-- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
-+ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
-+ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
-+ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
-+ }
- proc_create_seq("vmstat", 0444, NULL, &vmstat_op);
-- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
- #endif
- }
-
---- a/net/8021q/vlanproc.c
-+++ b/net/8021q/vlanproc.c
-@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net)
- {
- struct vlan_net *vn = net_generic(net, vlan_net_id);
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return;
-+
- if (vn->proc_vlan_conf)
- remove_proc_entry(name_conf, vn->proc_vlan_dir);
-
-@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net
- {
- struct vlan_net *vn = net_generic(net, vlan_net_id);
-
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
- if (!vn->proc_vlan_dir)
- goto err;
---- a/net/core/net-procfs.c
-+++ b/net/core/net-procfs.c
-@@ -319,10 +319,12 @@ static int __net_init dev_proc_net_init(
- if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops,
- sizeof(struct seq_net_private)))
- goto out;
-- if (!proc_create_seq("softnet_stat", 0444, net->proc_net,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_seq("softnet_stat", 0444, net->proc_net,
- &softnet_seq_ops))
- goto out_dev;
-- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
- sizeof(struct seq_net_private)))
- goto out_softnet;
-
-@@ -332,9 +334,11 @@ static int __net_init dev_proc_net_init(
- out:
- return rc;
- out_ptype:
-- remove_proc_entry("ptype", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("ptype", net->proc_net);
- out_softnet:
-- remove_proc_entry("softnet_stat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("softnet_stat", net->proc_net);
- out_dev:
- remove_proc_entry("dev", net->proc_net);
- goto out;
-@@ -344,8 +348,10 @@ static void __net_exit dev_proc_net_exit
- {
- wext_proc_exit(net);
-
-- remove_proc_entry("ptype", net->proc_net);
-- remove_proc_entry("softnet_stat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
-+ remove_proc_entry("ptype", net->proc_net);
-+ remove_proc_entry("softnet_stat", net->proc_net);
-+ }
- remove_proc_entry("dev", net->proc_net);
- }
-
---- a/net/core/sock.c
-+++ b/net/core/sock.c
-@@ -4115,6 +4115,8 @@ static __net_initdata struct pernet_oper
-
- static int __init proto_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
- return register_pernet_subsys(&proto_net_ops);
- }
-
---- a/net/ipv4/fib_trie.c
-+++ b/net/ipv4/fib_trie.c
-@@ -3036,11 +3036,13 @@ static const struct seq_operations fib_r
-
- int __net_init fib_proc_init(struct net *net)
- {
-- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
- sizeof(struct fib_trie_iter)))
- goto out1;
-
-- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net,
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
-+ !proc_create_net_single("fib_triestat", 0444, net->proc_net,
- fib_triestat_seq_show, NULL))
- goto out2;
-
-@@ -3051,17 +3053,21 @@ int __net_init fib_proc_init(struct net
- return 0;
-
- out3:
-- remove_proc_entry("fib_triestat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("fib_triestat", net->proc_net);
- out2:
-- remove_proc_entry("fib_trie", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ remove_proc_entry("fib_trie", net->proc_net);
- out1:
- return -ENOMEM;
- }
-
- void __net_exit fib_proc_exit(struct net *net)
- {
-- remove_proc_entry("fib_trie", net->proc_net);
-- remove_proc_entry("fib_triestat", net->proc_net);
-+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
-+ remove_proc_entry("fib_trie", net->proc_net);
-+ remove_proc_entry("fib_triestat", net->proc_net);
-+ }
- remove_proc_entry("route", net->proc_net);
- }
-
---- a/net/ipv4/proc.c
-+++ b/net/ipv4/proc.c
-@@ -553,5 +553,8 @@ static __net_initdata struct pernet_oper
-
- int __init ip_misc_proc_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- return register_pernet_subsys(&ip_proc_ops);
- }
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -381,6 +381,9 @@ static struct pernet_operations ip_rt_pr
-
- static int __init ip_rt_proc_init(void)
- {
-+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
-+ return 0;
-+
- return register_pernet_subsys(&ip_rt_proc_ops);
- }
-
---- a/net/ipv4/inet_timewait_sock.c
-+++ b/net/ipv4/inet_timewait_sock.c
-@@ -269,7 +269,7 @@ void __inet_twsk_schedule(struct inet_ti
- */
-
- if (!rearm) {
-- bool kill = timeo <= 4*HZ;
-+ bool __maybe_unused kill = timeo <= 4*HZ;
-
- __NET_INC_STATS(twsk_net(tw), kill ? LINUX_MIB_TIMEWAITKILLED :
- LINUX_MIB_TIMEWAITED);
diff --git a/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch b/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch
deleted file mode 100644
index 105eb3da4b..0000000000
--- a/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 8 Jul 2017 08:20:43 +0200
-Subject: debloat: dmabuf
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/base/Kconfig | 2 +-
- drivers/dma-buf/Makefile | 10 +++++++---
- drivers/dma-buf/dma-buf.c | 4 +++-
- kernel/sched/core.c | 1 +
- 4 files changed, 12 insertions(+), 5 deletions(-)
-
---- a/drivers/base/Kconfig
-+++ b/drivers/base/Kconfig
-@@ -198,7 +198,7 @@ config SOC_BUS
- source "drivers/base/regmap/Kconfig"
-
- config DMA_SHARED_BUFFER
-- bool
-+ tristate
- default n
- select IRQ_WORK
- help
---- a/drivers/dma-buf/heaps/Makefile
-+++ b/drivers/dma-buf/heaps/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
--obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
-+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
-+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
---- a/drivers/dma-buf/Makefile
-+++ b/drivers/dma-buf/Makefile
-@@ -1,12 +1,14 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
-+obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o
-+
-+dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
- dma-fence-unwrap.o dma-resv.o
--obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
--obj-$(CONFIG_DMABUF_HEAPS) += heaps/
--obj-$(CONFIG_SYNC_FILE) += sync_file.o
--obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
--obj-$(CONFIG_UDMABUF) += udmabuf.o
--obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o
-+dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
-+obj-$(CONFIG_DMABUF_HEAPS) += heaps/
-+dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o
-+dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
-+dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o
-+dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o
-
- dmabuf_selftests-y := \
- selftest.o \
-@@ -15,4 +17,6 @@ dmabuf_selftests-y := \
- st-dma-fence-unwrap.o \
- st-dma-resv.o
-
--obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
-+dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
-+
-+dma-shared-buffer-objs := $(dma-buf-objs-y)
---- a/drivers/dma-buf/dma-buf.c
-+++ b/drivers/dma-buf/dma-buf.c
-@@ -1636,4 +1636,5 @@ static void __exit dma_buf_deinit(void)
- kern_unmount(dma_buf_mnt);
- dma_buf_uninit_sysfs_statistics();
- }
--__exitcall(dma_buf_deinit);
-+module_exit(dma_buf_deinit);
-+MODULE_LICENSE("GPL");
---- a/kernel/sched/core.c
-+++ b/kernel/sched/core.c
-@@ -4367,6 +4367,7 @@ int wake_up_state(struct task_struct *p,
- {
- return try_to_wake_up(p, state, 0);
- }
-+EXPORT_SYMBOL_GPL(wake_up_state);
-
- /*
- * Perform scheduler related setup for a newly forked process p.
---- a/fs/d_path.c
-+++ b/fs/d_path.c
-@@ -313,6 +313,7 @@ char *dynamic_dname(char *buffer, int bu
- buffer += buflen - sz;
- return memcpy(buffer, temp, sz);
- }
-+EXPORT_SYMBOL_GPL(dynamic_dname);
-
- char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
- {
diff --git a/target/linux/generic/hack-6.1/910-kobject_uevent.patch b/target/linux/generic/hack-6.1/910-kobject_uevent.patch
deleted file mode 100644
index c4c41ca400..0000000000
--- a/target/linux/generic/hack-6.1/910-kobject_uevent.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/kobject.h | 5 +++++
- lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
- 2 files changed, 42 insertions(+)
-
---- a/lib/kobject_uevent.c
-+++ b/lib/kobject_uevent.c
-@@ -179,6 +179,18 @@ out:
- return r;
- }
-
-+u64 uevent_next_seqnum(void)
-+{
-+ u64 seq;
-+
-+ mutex_lock(&uevent_sock_mutex);
-+ seq = ++uevent_seqnum;
-+ mutex_unlock(&uevent_sock_mutex);
-+
-+ return seq;
-+}
-+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
-+
- /**
- * kobject_synth_uevent - send synthetic uevent with arguments
- *
diff --git a/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch
deleted file mode 100644
index 9854585d25..0000000000
--- a/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/kobject.h | 5 +++++
- lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
- 2 files changed, 42 insertions(+)
-
---- a/include/linux/kobject.h
-+++ b/include/linux/kobject.h
-@@ -32,6 +32,8 @@
- #define UEVENT_NUM_ENVP 64 /* number of env pointers */
- #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
-
-+struct sk_buff;
-+
- #ifdef CONFIG_UEVENT_HELPER
- /* path to the userspace helper executed on an event */
- extern char uevent_helper[];
-@@ -224,4 +226,7 @@ int kobject_synth_uevent(struct kobject
- __printf(2, 3)
- int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
-
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+ gfp_t allocation);
-+
- #endif /* _KOBJECT_H_ */
---- a/lib/kobject_uevent.c
-+++ b/lib/kobject_uevent.c
-@@ -691,6 +691,43 @@ int add_uevent_var(struct kobj_uevent_en
- EXPORT_SYMBOL_GPL(add_uevent_var);
-
- #if defined(CONFIG_NET)
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+ gfp_t allocation)
-+{
-+ struct uevent_sock *ue_sk;
-+ int err = 0;
-+
-+ /* send netlink message */
-+ mutex_lock(&uevent_sock_mutex);
-+ list_for_each_entry(ue_sk, &uevent_sock_list, list) {
-+ struct sock *uevent_sock = ue_sk->sk;
-+ struct sk_buff *skb2;
-+
-+ skb2 = skb_clone(skb, allocation);
-+ if (!skb2)
-+ break;
-+
-+ err = netlink_broadcast(uevent_sock, skb2, pid, group,
-+ allocation);
-+ if (err)
-+ break;
-+ }
-+ mutex_unlock(&uevent_sock_mutex);
-+
-+ kfree_skb(skb);
-+ return err;
-+}
-+#else
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+ gfp_t allocation)
-+{
-+ kfree_skb(skb);
-+ return 0;
-+}
-+#endif
-+EXPORT_SYMBOL_GPL(broadcast_uevent);
-+
-+#if defined(CONFIG_NET)
- static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb,
- struct netlink_ext_ack *extack)
- {
diff --git a/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch b/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch
deleted file mode 100644
index cc384bb553..0000000000
--- a/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From e08bcbbaa52fcc41f02743fd2e62a33255ce52da Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:52:28 +0200
-Subject: [PATCH] of/ftd: add device tree cmdline
-
----
- drivers/of/fdt.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -1183,6 +1183,9 @@ int __init early_init_dt_scan_chosen(cha
- p = of_get_flat_dt_prop(node, "bootargs", &l);
- if (p != NULL && l > 0)
- strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE));
-+ p = of_get_flat_dt_prop(node, "bootargs-append", &l);
-+ if (p != NULL && l > 0)
-+ strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE));
-
- handle_cmdline:
- /*
diff --git a/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
deleted file mode 100644
index f2ae028aa1..0000000000
--- a/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 19 Jul 2022 06:17:48 +0200
-Subject: [PATCH] Revert "Revert "Revert "driver core: Set fw_devlink=on by
- default"""
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit ea718c699055c8566eb64432388a04974c43b2ea.
-
-With of_platform_populate() called for MTD partitions that commit breaks
-probing devices which reference MTD in device tree.
-
-Link: https://lore.kernel.org/all/696cb2da-20b9-b3dd-46d9-de4bf91a1506@gmail.com/T/#u
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/base/core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/base/core.c
-+++ b/drivers/base/core.c
-@@ -1717,7 +1717,7 @@ static void device_links_purge(struct de
- #define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
- DL_FLAG_PM_RUNTIME)
-
--static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON;
-+static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE;
- static int __init fw_devlink_setup(char *arg)
- {
- if (!arg)
diff --git a/target/linux/generic/hack-6.6/200-tools_portability.patch b/target/linux/generic/hack-6.6/200-tools_portability.patch
index 5d2b20dcb7..f016e641c6 100644
--- a/target/linux/generic/hack-6.6/200-tools_portability.patch
+++ b/target/linux/generic/hack-6.6/200-tools_portability.patch
@@ -40,7 +40,20 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
# sysroots and flags or to avoid the GCC call in pure Clang builds.
--- a/tools/include/linux/types.h
+++ b/tools/include/linux/types.h
-@@ -56,6 +56,7 @@ typedef __s8 s8;
+@@ -10,8 +10,12 @@
+ #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */
+ #endif
+
++#ifndef __linux__
++#include <tools/linux_types.h>
++#else
+ #include <asm/types.h>
+ #include <asm/posix_types.h>
++#endif
+
+ struct page;
+ struct kmem_cache;
+@@ -56,6 +60,7 @@ typedef __s8 s8;
#define __user
#endif
#define __must_check
@@ -95,3 +108,150 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/**
* skip_spaces - Removes leading whitespace from @str.
+--- a/tools/arch/x86/include/asm/insn.h
++++ b/tools/arch/x86/include/asm/insn.h
+@@ -7,7 +7,7 @@
+ * Copyright (C) IBM Corporation, 2009
+ */
+
+-#include <asm/byteorder.h>
++#include <linux/kernel.h>
+ /* insn_attr_t is defined in inat.h */
+ #include "inat.h" /* __ignore_sync_check__ */
+
+--- a/tools/arch/x86/include/asm/orc_types.h
++++ b/tools/arch/x86/include/asm/orc_types.h
+@@ -46,7 +46,6 @@
+ #define ORC_TYPE_REGS_PARTIAL 4
+
+ #ifndef __ASSEMBLY__
+-#include <asm/byteorder.h>
+
+ /*
+ * This struct is more or less a vastly simplified version of the DWARF Call
+@@ -59,12 +58,12 @@
+ struct orc_entry {
+ s16 sp_offset;
+ s16 bp_offset;
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
++#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned sp_reg:4;
+ unsigned bp_reg:4;
+ unsigned type:3;
+ unsigned signal:1;
+-#elif defined(__BIG_ENDIAN_BITFIELD)
++#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned bp_reg:4;
+ unsigned sp_reg:4;
+ unsigned unused:4;
+--- a/tools/include/linux/rbtree.h
++++ b/tools/include/linux/rbtree.h
+@@ -18,7 +18,6 @@
+ #define __TOOLS_LINUX_PERF_RBTREE_H
+
+ #include <linux/kernel.h>
+-#include <linux/stddef.h>
+
+ struct rb_node {
+ unsigned long __rb_parent_color;
+--- a/tools/include/tools/be_byteshift.h
++++ b/tools/include/tools/be_byteshift.h
+@@ -2,6 +2,10 @@
+ #ifndef _TOOLS_BE_BYTESHIFT_H
+ #define _TOOLS_BE_BYTESHIFT_H
+
++#ifndef __linux__
++#include "linux_types.h"
++#endif
++
+ #include <stdint.h>
+
+ static inline uint16_t __get_unaligned_be16(const uint8_t *p)
+--- a/tools/include/tools/le_byteshift.h
++++ b/tools/include/tools/le_byteshift.h
+@@ -2,6 +2,10 @@
+ #ifndef _TOOLS_LE_BYTESHIFT_H
+ #define _TOOLS_LE_BYTESHIFT_H
+
++#ifndef __linux__
++#include "linux_types.h"
++#endif
++
+ #include <stdint.h>
+
+ static inline uint16_t __get_unaligned_le16(const uint8_t *p)
+--- /dev/null
++++ b/tools/include/tools/linux_types.h
+@@ -0,0 +1,18 @@
++#ifndef __LINUX_TYPES_H
++#define __LINUX_TYPES_H
++
++#include <stdint.h>
++
++typedef int8_t __s8;
++typedef uint8_t __u8;
++
++typedef int16_t __s16;
++typedef uint16_t __u16;
++
++typedef int32_t __s32;
++typedef uint32_t __u32;
++
++typedef int64_t __s64;
++typedef uint64_t __u64;
++
++#endif
+--- a/tools/objtool/Makefile
++++ b/tools/objtool/Makefile
+@@ -39,6 +39,8 @@ OBJTOOL_LDFLAGS := $(LIBELF_LIBS) $(LIBS
+ elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(HOSTCC) $(OBJTOOL_CFLAGS) -x c -E - | grep elf_getshdr)
+ OBJTOOL_CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)
+
++OBJTOOL_CFLAGS += $(HOST_EXTRACFLAGS)
++
+ # Always want host compilation.
+ HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)"
+
+--- a/tools/objtool/orc_dump.c
++++ b/tools/objtool/orc_dump.c
+@@ -4,10 +4,10 @@
+ */
+
+ #include <unistd.h>
+-#include <asm/orc_types.h>
+ #include <objtool/objtool.h>
+ #include <objtool/warn.h>
+ #include <objtool/endianness.h>
++#include <asm/orc_types.h>
+
+ static const char *reg_name(unsigned int reg)
+ {
+--- a/tools/objtool/orc_gen.c
++++ b/tools/objtool/orc_gen.c
+@@ -7,11 +7,11 @@
+ #include <string.h>
+
+ #include <linux/objtool_types.h>
+-#include <asm/orc_types.h>
+
+ #include <objtool/check.h>
+ #include <objtool/warn.h>
+ #include <objtool/endianness.h>
++#include <asm/orc_types.h>
+
+ static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
+ struct instruction *insn)
+--- a/tools/arch/x86/lib/insn.c
++++ b/tools/arch/x86/lib/insn.c
+@@ -15,7 +15,11 @@
+ #include "../include/asm/insn.h" /* __ignore_sync_check__ */
+ #include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */
+
++#ifdef __KERNEL__
+ #include <linux/errno.h>
++#else
++#include <errno.h>
++#endif
+ #include <linux/kconfig.h>
+
+ #include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */
diff --git a/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch b/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch
index a22acafea1..ca70da7e31 100644
--- a/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch
+++ b/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch
@@ -23,7 +23,7 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
{ {0x02, 0x21}, "lz4", unlz4 },
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
-@@ -456,10 +456,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
+@@ -460,10 +460,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
diff --git a/target/linux/generic/hack-6.6/253-ksmbd-config.patch b/target/linux/generic/hack-6.6/253-ksmbd-config.patch
index 298a0787b7..9079c66d42 100644
--- a/target/linux/generic/hack-6.6/253-ksmbd-config.patch
+++ b/target/linux/generic/hack-6.6/253-ksmbd-config.patch
@@ -10,7 +10,7 @@ Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
--- a/init/Kconfig
+++ b/init/Kconfig
-@@ -1989,7 +1989,7 @@ config PADATA
+@@ -1993,7 +1993,7 @@ config PADATA
bool
config ASN1
@@ -21,7 +21,7 @@ Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
that can be interpreted by the ASN.1 stream decoder and used to
--- a/lib/Kconfig
+++ b/lib/Kconfig
-@@ -647,7 +647,7 @@ config LIBFDT
+@@ -641,7 +641,7 @@ config LIBFDT
bool
config OID_REGISTRY
diff --git a/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch b/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch
index 51f990039c..9633525bc4 100644
--- a/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch
+++ b/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch
@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
+@@ -243,10 +243,10 @@ static inline int find_next_netdev_featu
#define NETIF_F_UPPER_DISABLES NETIF_F_LRO
/* changeable features with no special hardware requirements */
diff --git a/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch
index ea5c700702..4ebddb3b45 100644
--- a/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch
+++ b/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch
@@ -15,7 +15,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -90,6 +90,29 @@
+@@ -96,6 +96,29 @@
#define AQR107_OP_IN_PROG_SLEEP 1000
#define AQR107_OP_IN_PROG_TIMEOUT 100000
@@ -45,7 +45,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
static int aqr107_get_sset_count(struct phy_device *phydev)
{
return AQR107_SGMII_STAT_SZ;
-@@ -196,6 +219,51 @@ static int aqr_config_aneg(struct phy_de
+@@ -202,6 +225,51 @@ static int aqr_config_aneg(struct phy_de
return genphy_c45_check_and_restart_aneg(phydev, changed);
}
@@ -97,7 +97,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
static int aqr_config_intr(struct phy_device *phydev)
{
bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
-@@ -807,7 +875,7 @@ static struct phy_driver aqr_driver[] =
+@@ -848,7 +916,7 @@ static struct phy_driver aqr_driver[] =
PHY_ID_MATCH_MODEL(PHY_ID_AQR112),
.name = "Aquantia AQR112",
.probe = aqr107_probe,
@@ -106,7 +106,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
.get_tunable = aqr107_get_tunable,
-@@ -830,7 +898,7 @@ static struct phy_driver aqr_driver[] =
+@@ -871,7 +939,7 @@ static struct phy_driver aqr_driver[] =
PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
.name = "Aquantia AQR412",
.probe = aqr107_probe,
diff --git a/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch
index b5e35dfdd7..b0cd801601 100644
--- a/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch
+++ b/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch
@@ -14,7 +14,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -252,10 +252,16 @@ static int aqr_config_aneg_set_prot(stru
+@@ -258,10 +258,16 @@ static int aqr_config_aneg_set_prot(stru
phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
aquantia_syscfg[if_type].start_rate);
diff --git a/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch b/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch
index 66298b89ed..b3767f1346 100644
--- a/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch
+++ b/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch
@@ -12,7 +12,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -30,6 +30,8 @@
+@@ -31,6 +31,8 @@
#define PHY_ID_AQR113C 0x31c31c12
#define PHY_ID_AQR114C 0x31c31c22
#define PHY_ID_AQR813 0x31c31cb2
@@ -21,7 +21,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -1014,6 +1016,30 @@ static struct phy_driver aqr_driver[] =
+@@ -1055,6 +1057,30 @@ static struct phy_driver aqr_driver[] =
.led_hw_control_get = aqr_phy_led_hw_control_get,
.led_polarity_set = aqr_phy_led_polarity_set,
},
@@ -52,7 +52,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
};
module_phy_driver(aqr_driver);
-@@ -1034,6 +1060,8 @@ static struct mdio_device_id __maybe_unu
+@@ -1075,6 +1101,8 @@ static struct mdio_device_id __maybe_unu
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
diff --git a/target/linux/generic/hack-6.6/760-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/generic/hack-6.6/760-net-usb-r8152-add-LED-configuration-from-OF.patch
index 190dd3507c..069c682303 100644
--- a/target/linux/generic/hack-6.6/760-net-usb-r8152-add-LED-configuration-from-OF.patch
+++ b/target/linux/generic/hack-6.6/760-net-usb-r8152-add-LED-configuration-from-OF.patch
@@ -22,7 +22,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
#include <linux/crc32.h>
#include <linux/if_vlan.h>
#include <linux/uaccess.h>
-@@ -7035,6 +7036,22 @@ static void rtl_tally_reset(struct r8152
+@@ -7044,6 +7045,22 @@ static void rtl_tally_reset(struct r8152
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data);
}
@@ -45,7 +45,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
static void r8152b_init(struct r8152 *tp)
{
u32 ocp_data;
-@@ -7076,6 +7093,8 @@ static void r8152b_init(struct r8152 *tp
+@@ -7085,6 +7102,8 @@ static void r8152b_init(struct r8152 *tp
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN);
ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
@@ -54,7 +54,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
}
static void r8153_init(struct r8152 *tp)
-@@ -7216,6 +7235,8 @@ static void r8153_init(struct r8152 *tp)
+@@ -7225,6 +7244,8 @@ static void r8153_init(struct r8152 *tp)
tp->coalesce = COALESCE_SLOW;
break;
}
@@ -63,7 +63,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
}
static void r8153b_init(struct r8152 *tp)
-@@ -7298,6 +7319,8 @@ static void r8153b_init(struct r8152 *tp
+@@ -7307,6 +7328,8 @@ static void r8153b_init(struct r8152 *tp
rtl_tally_reset(tp);
tp->coalesce = 15000; /* 15 us */
diff --git a/target/linux/generic/hack-6.6/765-mxl-gpy-control-LED-reg-from-DT.patch b/target/linux/generic/hack-6.6/765-mxl-gpy-control-LED-reg-from-DT.patch
index 51a03be2ad..fd2a327811 100644
--- a/target/linux/generic/hack-6.6/765-mxl-gpy-control-LED-reg-from-DT.patch
+++ b/target/linux/generic/hack-6.6/765-mxl-gpy-control-LED-reg-from-DT.patch
@@ -55,7 +55,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
#define PHY_PMA_MGBT_POLARITY 0x82
#define PHY_MDI_MDI_X_MASK GENMASK(1, 0)
#define PHY_MDI_MDI_X_NORMAL 0x3
-@@ -260,6 +267,35 @@ out:
+@@ -270,10 +277,39 @@ out:
return ret;
}
@@ -90,15 +90,8 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
+
static int gpy_config_init(struct phy_device *phydev)
{
- int ret;
-@@ -271,7 +307,10 @@ static int gpy_config_init(struct phy_de
-
- /* Clear all pending interrupts */
- ret = phy_read(phydev, PHY_ISTAT);
-- return ret < 0 ? ret : 0;
-+ if (ret < 0)
-+ return ret;
-+
+ /* Nothing to configure. Configuration Requirement Placeholder */
+- return 0;
+ return gpy_led_write(phydev);
}
diff --git a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch
index d010231e49..73a27ef6e2 100644
--- a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch
+++ b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch
@@ -10,7 +10,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1083,12 +1083,18 @@ static const struct usb_device_id produc
+@@ -1084,12 +1084,18 @@ static const struct usb_device_id produc
USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
.driver_info = (unsigned long)&qmi_wwan_info,
},
@@ -43,7 +43,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
#define QUECTEL_VENDOR_ID 0x2c7c
/* These Quectel products use Quectel's vendor ID */
-@@ -1156,6 +1161,11 @@ static const struct usb_device_id option
+@@ -1158,6 +1163,11 @@ static const struct usb_device_id option
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */
.driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) },
@@ -55,7 +55,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
/* Quectel products using Qualcomm vendor ID */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
-@@ -1197,6 +1207,11 @@ static const struct usb_device_id option
+@@ -1199,6 +1209,11 @@ static const struct usb_device_id option
.driver_info = ZLP },
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
.driver_info = RSVD(4) },
diff --git a/target/linux/generic/hack-6.6/790-SFP-GE-T-ignore-TX_FAULT.patch b/target/linux/generic/hack-6.6/790-SFP-GE-T-ignore-TX_FAULT.patch
index a4d84f8b7d..7733b45520 100644
--- a/target/linux/generic/hack-6.6/790-SFP-GE-T-ignore-TX_FAULT.patch
+++ b/target/linux/generic/hack-6.6/790-SFP-GE-T-ignore-TX_FAULT.patch
@@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
// Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
// 2500MBd NRZ in their EEPROM
SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
-@@ -2586,7 +2589,8 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2589,7 +2592,8 @@ static void sfp_sm_main(struct sfp *sfp,
* or t_start_up, so assume there is a fault.
*/
sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
@@ -46,7 +46,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
init_done:
/* Create mdiobus and start trying for PHY */
-@@ -2840,10 +2844,12 @@ static void sfp_check_state(struct sfp *
+@@ -2843,10 +2847,12 @@ static void sfp_check_state(struct sfp *
mutex_lock(&sfp->st_mutex);
state = sfp_get_state(sfp);
changed = state ^ sfp->state;
diff --git a/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch
index 666dcfad4d..a1d787191c 100644
--- a/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch
+++ b/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch
@@ -15,7 +15,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
#include "gpiolib.h"
#include "gpiolib-of.h"
-@@ -1111,3 +1113,74 @@ void of_gpiochip_remove(struct gpio_chip
+@@ -1129,3 +1131,74 @@ void of_gpiochip_remove(struct gpio_chip
{
of_node_put(dev_of_node(&chip->gpiodev->dev));
}
@@ -131,7 +131,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
struct gpio_desc *desc)
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -557,7 +557,7 @@ static struct class gpio_class = {
+@@ -558,7 +558,7 @@ static struct class gpio_class = {
*
* Returns zero on success, else an error.
*/
@@ -140,7 +140,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
{
struct gpio_chip *chip;
struct gpio_device *gdev;
-@@ -619,6 +619,8 @@ int gpiod_export(struct gpio_desc *desc,
+@@ -620,6 +620,8 @@ int gpiod_export(struct gpio_desc *desc,
offset = gpio_chip_hwgpio(desc);
if (chip->names && chip->names[offset])
ioname = chip->names[offset];
@@ -149,7 +149,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
dev = device_create_with_groups(&gpio_class, &gdev->dev,
MKDEV(0, 0), data, gpio_groups,
-@@ -640,8 +642,21 @@ err_unlock:
+@@ -641,8 +643,21 @@ err_unlock:
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
return status;
}
diff --git a/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch b/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch
index 9375a721b5..a011cf8ffa 100644
--- a/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch
+++ b/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch
@@ -133,7 +133,7 @@ Subject: [PATCH] ssb_sprom: add generic kernel support for Broadcom Fallback SP
# host support
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
-@@ -1287,6 +1287,14 @@ static int __init ssb_modinit(void)
+@@ -1289,6 +1289,14 @@ static int __init ssb_modinit(void)
{
int err;
diff --git a/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch b/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch
index af000f76fc..acf72f4422 100644
--- a/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch
+++ b/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch
@@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *,
u32));
INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *,
-@@ -2247,9 +2264,11 @@ static void __sk_free(struct sock *sk)
+@@ -2239,9 +2256,11 @@ static void __sk_free(struct sock *sk)
if (likely(sk->sk_net_refcnt))
sock_inuse_add(sock_net(sk), -1);
diff --git a/target/linux/generic/hack-6.6/902-debloat_proc.patch b/target/linux/generic/hack-6.6/902-debloat_proc.patch
index 3b037a732c..691a60bcc0 100644
--- a/target/linux/generic/hack-6.6/902-debloat_proc.patch
+++ b/target/linux/generic/hack-6.6/902-debloat_proc.patch
@@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/fs/locks.c
+++ b/fs/locks.c
-@@ -2897,6 +2897,8 @@ static const struct seq_operations locks
+@@ -2895,6 +2895,8 @@ static const struct seq_operations locks
static int __init proc_locks_init(void)
{
@@ -235,7 +235,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!pe)
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
-@@ -4438,6 +4438,8 @@ static const struct seq_operations vmall
+@@ -4448,6 +4448,8 @@ static const struct seq_operations vmall
static int __init proc_vmalloc_init(void)
{
@@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/core/sock.c
+++ b/net/core/sock.c
-@@ -4145,6 +4145,8 @@ static __net_initdata struct pernet_oper
+@@ -4140,6 +4140,8 @@ static __net_initdata struct pernet_oper
static int __init proto_init(void)
{
@@ -341,7 +341,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -3036,11 +3036,13 @@ static const struct seq_operations fib_r
+@@ -3037,11 +3037,13 @@ static const struct seq_operations fib_r
int __net_init fib_proc_init(struct net *net)
{
@@ -357,7 +357,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
fib_triestat_seq_show, NULL))
goto out2;
-@@ -3051,17 +3053,21 @@ int __net_init fib_proc_init(struct net
+@@ -3052,17 +3054,21 @@ int __net_init fib_proc_init(struct net
return 0;
out3:
diff --git a/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch b/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch
index 8fdaab5ad6..355bd0d70c 100644
--- a/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch
+++ b/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch
@@ -73,7 +73,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+MODULE_LICENSE("GPL");
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
-@@ -4487,6 +4487,7 @@ int wake_up_state(struct task_struct *p,
+@@ -4483,6 +4483,7 @@ int wake_up_state(struct task_struct *p,
{
return try_to_wake_up(p, state, 0);
}
diff --git a/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch
index 7a21e73dae..372ac6fa7d 100644
--- a/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch
+++ b/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch
@@ -1,7 +1,7 @@
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
+Subject: lib: add broadcast_uevent()
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#endif /* _KOBJECT_H_ */
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
-@@ -691,6 +691,43 @@ int add_uevent_var(struct kobj_uevent_en
+@@ -706,6 +706,43 @@ int add_uevent_var(struct kobj_uevent_en
EXPORT_SYMBOL_GPL(add_uevent_var);
#if defined(CONFIG_NET)
diff --git a/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
index 1c5fb11ff5..85a19027fd 100644
--- a/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
+++ b/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
@@ -19,7 +19,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
-@@ -1657,7 +1657,7 @@ static void device_links_purge(struct de
+@@ -1658,7 +1658,7 @@ static void device_links_purge(struct de
#define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
DL_FLAG_PM_RUNTIME)
diff --git a/target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch b/target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch
deleted file mode 100644
index 22f52c1d46..0000000000
--- a/target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 22 Oct 2020 22:00:03 +0200
-Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code
-
-This header file is not in uapi, which makes any user space code that includes
-linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory'
-
-Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/compiler.h
-+++ b/include/linux/compiler.h
-@@ -220,6 +220,8 @@ void ftrace_likely_update(struct ftrace_
- #define function_nocfi(x) (x)
- #endif
-
-+#include <asm/rwonce.h>
-+
- #endif /* __KERNEL__ */
-
- /*
-@@ -252,6 +254,4 @@ static inline void *offset_to_ptr(const
- */
- #define prevent_tail_call_optimization() mb()
-
--#include <asm/rwonce.h>
--
- #endif /* __LINUX_COMPILER_H */
diff --git a/target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch
deleted file mode 100644
index 95a9656d26..0000000000
--- a/target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 18 Apr 2018 10:50:05 +0200
-Subject: [PATCH] MIPS: only process negative stack offsets on stack traces
-
-Fixes endless back traces in cases where the compiler emits a stack
-pointer increase in a branch delay slot (probably for some form of
-function return).
-
-[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low!
-[ 3.480070] turning off the locking correctness validator.
-[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0
-[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000
-[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f
-[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000
-[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000
-[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000
-[ 3.532942] ...
-[ 3.535362] Call Trace:
-[ 3.537818] [<80010a48>] show_stack+0x58/0x100
-[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170
-[ 3.546613] [<80079f90>] save_trace+0xf0/0x110
-[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c
-[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08
-[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c
-[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78
-[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/mips/kernel/process.c
-+++ b/arch/mips/kernel/process.c
-@@ -393,6 +393,8 @@ static inline int is_sp_move_ins(union m
-
- if (ip->i_format.opcode == addiu_op ||
- ip->i_format.opcode == daddiu_op) {
-+ if (ip->i_format.simmediate > 0)
-+ return 0;
- *frame_size = -ip->i_format.simmediate;
- return 1;
- }
diff --git a/target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch b/target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch
deleted file mode 100644
index 120b6e4cf8..0000000000
--- a/target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 9 Jul 2017 00:26:53 +0200
-Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/Makefile
-+++ b/Makefile
-@@ -534,7 +534,7 @@ KBUILD_LDFLAGS_MODULE :=
- KBUILD_LDFLAGS :=
- CLANG_FLAGS :=
-
--export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
-+export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
- export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
- export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
- export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
diff --git a/target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch b/target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch
deleted file mode 100644
index d6b10491f8..0000000000
--- a/target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From bd1b9f66d5134e518419f4c4dacf1884c1616983 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Thu, 28 Apr 2022 11:13:23 +0200
-Subject: [PATCH] watchdog: max63xx_wdt: Add support for specifying WDI logic
- via GPIO
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-On some boards is WDI logic of max6370 chip connected via GPIO.
-So extend max63xx_wdt driver to allow specifying WDI logic via GPIO.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
----
- drivers/watchdog/max63xx_wdt.c | 24 ++++++++++++++++++++++++
- 1 file changed, 24 insertions(+)
-
---- a/drivers/watchdog/max63xx_wdt.c
-+++ b/drivers/watchdog/max63xx_wdt.c
-@@ -27,6 +27,7 @@
- #include <linux/io.h>
- #include <linux/slab.h>
- #include <linux/property.h>
-+#include <linux/gpio/consumer.h>
-
- #define DEFAULT_HEARTBEAT 60
- #define MAX_HEARTBEAT 60
-@@ -53,6 +54,9 @@ struct max63xx_wdt {
- void __iomem *base;
- spinlock_t lock;
-
-+ /* GPIOs */
-+ struct gpio_desc *gpio_wdi;
-+
- /* WDI and WSET bits write access routines */
- void (*ping)(struct max63xx_wdt *wdt);
- void (*set)(struct max63xx_wdt *wdt, u8 set);
-@@ -158,6 +162,17 @@ static const struct watchdog_info max63x
- .identity = "max63xx Watchdog",
- };
-
-+static void max63xx_gpio_ping(struct max63xx_wdt *wdt)
-+{
-+ spin_lock(&wdt->lock);
-+
-+ gpiod_set_value(wdt->gpio_wdi, 1);
-+ udelay(1);
-+ gpiod_set_value(wdt->gpio_wdi, 0);
-+
-+ spin_unlock(&wdt->lock);
-+}
-+
- static void max63xx_mmap_ping(struct max63xx_wdt *wdt)
- {
- u8 val;
-@@ -225,10 +240,19 @@ static int max63xx_wdt_probe(struct plat
- return -EINVAL;
- }
-
-+ wdt->gpio_wdi = devm_gpiod_get(dev, NULL, GPIOD_FLAGS_BIT_DIR_OUT);
-+ if (IS_ERR(wdt->gpio_wdi) && PTR_ERR(wdt->gpio_wdi) != -ENOENT)
-+ return dev_err_probe(dev, PTR_ERR(wdt->gpio_wdi),
-+ "unable to request gpio: %ld\n",
-+ PTR_ERR(wdt->gpio_wdi));
-+
- err = max63xx_mmap_init(pdev, wdt);
- if (err)
- return err;
-
-+ if (!IS_ERR(wdt->gpio_wdi))
-+ wdt->ping = max63xx_gpio_ping;
-+
- platform_set_drvdata(pdev, &wdt->wdd);
- watchdog_set_drvdata(&wdt->wdd, wdt);
-
diff --git a/target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
deleted file mode 100644
index 42f5a8c246..0000000000
--- a/target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From: Tobias Wolf <dev-NTEO@vplace.de>
-Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation
-
-An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any
-kernel beyond version 4.3 resulting in:
-
-BUG: Bad page state in process swapper pfn:086ac
-
-bisect resulted in:
-
-a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit
-commit a1c34a3bf00af2cede839879502e12dc68491ad5
-Author: Laura Abbott <laura@labbott.name>
-Date: Thu Nov 5 18:48:46 2015 -0800
-
- mm: Don't offset memmap for flatmem
-
- Srinivas Kandagatla reported bad page messages when trying to remove the
- bottom 2MB on an ARM based IFC6410 board
-
- BUG: Bad page state in process swapper pfn:fffa8
- page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0
- flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked)
- page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set
- bad because of flags:
- flags: 0x200041(locked|active|mlocked)
- Modules linked in:
- CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty
-#816
- Hardware name: Qualcomm (Flattened Device Tree)
- unwind_backtrace
- show_stack
- dump_stack
- bad_page
- free_pages_prepare
- free_hot_cold_page
- __free_pages
- free_highmem_page
- mem_init
- start_kernel
- Disabling lock debugging due to kernel taint
- [...]
-:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4
-0a8156f848733dfa21e16c196dfb6c0a76290709 M mm
-
-This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by
-page_to_pfn anymore.
-
-The following output was generated with two hacked in printk statements:
-
-printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map -
-(pgdat->node_start_pfn - ARCH_PFN_OFFSET));
- if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
- mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
-printk("after %p\n", mem_map);
-
-Output:
-
-[ 0.000000] before 8861b280 vs. 8861b280 or 8851b280
-[ 0.000000] after 8851b280
-
-As seen in the first line mem_map with subtraction of offset does not equal the
-mem_map after subtraction of ARCH_PFN_OFFSET.
-
-After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the
-previously calculated offset is zero for the named platform it is able to boot
-4.4 and 4.9-rc7 again.
-
-Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
----
-
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -7622,7 +7622,7 @@ static void __init alloc_node_mem_map(st
- if (pgdat == NODE_DATA(0)) {
- mem_map = NODE_DATA(0)->node_mem_map;
- if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
-- mem_map -= offset;
-+ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
- }
- #endif
- }
diff --git a/target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch
deleted file mode 100644
index 8f40ae3ba2..0000000000
--- a/target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support
-
-It is required for renames on overlayfs
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/fs/jffs2/dir.c
-+++ b/fs/jffs2/dir.c
-@@ -614,8 +614,8 @@ static int jffs2_rmdir (struct inode *di
- return ret;
- }
-
--static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i,
-- struct dentry *dentry, umode_t mode, dev_t rdev)
-+static int __jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i,
-+ struct dentry *dentry, umode_t mode, dev_t rdev, bool whiteout)
- {
- struct jffs2_inode_info *f, *dir_f;
- struct jffs2_sb_info *c;
-@@ -754,7 +754,11 @@ static int jffs2_mknod (struct user_name
- mutex_unlock(&dir_f->sem);
- jffs2_complete_reservation(c);
-
-- d_instantiate_new(dentry, inode);
-+ if (!whiteout)
-+ d_instantiate_new(dentry, inode);
-+ else
-+ unlock_new_inode(inode);
-+
- return 0;
-
- fail:
-@@ -762,6 +766,19 @@ static int jffs2_mknod (struct user_name
- return ret;
- }
-
-+static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i,
-+ struct dentry *dentry, umode_t mode, dev_t rdev)
-+{
-+ return __jffs2_mknod(mnt_userns, dir_i, dentry, mode, rdev, false);
-+}
-+
-+static int jffs2_whiteout (struct user_namespace *mnt_userns, struct inode *old_dir,
-+ struct dentry *old_dentry)
-+{
-+ return __jffs2_mknod(mnt_userns, old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE,
-+ WHITEOUT_DEV, true);
-+}
-+
- static int jffs2_rename (struct user_namespace *mnt_userns,
- struct inode *old_dir_i, struct dentry *old_dentry,
- struct inode *new_dir_i, struct dentry *new_dentry,
-@@ -773,7 +790,7 @@ static int jffs2_rename (struct user_nam
- uint8_t type;
- uint32_t now;
-
-- if (flags & ~RENAME_NOREPLACE)
-+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
- return -EINVAL;
-
- /* The VFS will check for us and prevent trying to rename a
-@@ -839,9 +856,14 @@ static int jffs2_rename (struct user_nam
- if (d_is_dir(old_dentry) && !victim_f)
- inc_nlink(new_dir_i);
-
-- /* Unlink the original */
-- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
-+ if (flags & RENAME_WHITEOUT)
-+ /* Replace with whiteout */
-+ ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry);
-+ else
-+ /* Unlink the original */
-+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-+ old_dentry->d_name.name,
-+ old_dentry->d_name.len, NULL, now);
-
- /* We don't touch inode->i_nlink */
-
diff --git a/target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch
deleted file mode 100644
index f58fc791d2..0000000000
--- a/target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: jffs2: add RENAME_EXCHANGE support
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/fs/jffs2/dir.c
-+++ b/fs/jffs2/dir.c
-@@ -787,18 +787,31 @@ static int jffs2_rename (struct user_nam
- int ret;
- struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
- struct jffs2_inode_info *victim_f = NULL;
-+ struct inode *fst_inode = d_inode(old_dentry);
-+ struct inode *snd_inode = d_inode(new_dentry);
- uint8_t type;
- uint32_t now;
-
-- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
-+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE))
- return -EINVAL;
-
-+ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) {
-+ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) {
-+ inc_nlink(new_dir_i);
-+ drop_nlink(old_dir_i);
-+ }
-+ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) {
-+ drop_nlink(new_dir_i);
-+ inc_nlink(old_dir_i);
-+ }
-+ }
-+
- /* The VFS will check for us and prevent trying to rename a
- * file over a directory and vice versa, but if it's a directory,
- * the VFS can't check whether the victim is empty. The filesystem
- * needs to do that for itself.
- */
-- if (d_really_is_positive(new_dentry)) {
-+ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) {
- victim_f = JFFS2_INODE_INFO(d_inode(new_dentry));
- if (d_is_dir(new_dentry)) {
- struct jffs2_full_dirent *fd;
-@@ -833,7 +846,7 @@ static int jffs2_rename (struct user_nam
- if (ret)
- return ret;
-
-- if (victim_f) {
-+ if (victim_f && !(flags & RENAME_EXCHANGE)) {
- /* There was a victim. Kill it off nicely */
- if (d_is_dir(new_dentry))
- clear_nlink(d_inode(new_dentry));
-@@ -859,6 +872,12 @@ static int jffs2_rename (struct user_nam
- if (flags & RENAME_WHITEOUT)
- /* Replace with whiteout */
- ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry);
-+ else if (flags & RENAME_EXCHANGE)
-+ /* Replace the original */
-+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i),
-+ d_inode(new_dentry)->i_ino, type,
-+ old_dentry->d_name.name, old_dentry->d_name.len,
-+ now);
- else
- /* Unlink the original */
- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-@@ -890,7 +909,7 @@ static int jffs2_rename (struct user_nam
- return ret;
- }
-
-- if (d_is_dir(old_dentry))
-+ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE))
- drop_nlink(old_dir_i);
-
- new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
diff --git a/target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch b/target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch
deleted file mode 100644
index de847a1f5c..0000000000
--- a/target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: jffs2: add splice ops
-
-Add splice_read using generic_file_splice_read.
-Add splice_write using iter_file_splice_write
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/fs/jffs2/file.c
-+++ b/fs/jffs2/file.c
-@@ -53,6 +53,8 @@ const struct file_operations jffs2_file_
- .open = generic_file_open,
- .read_iter = generic_file_read_iter,
- .write_iter = generic_file_write_iter,
-+ .splice_read = generic_file_splice_read,
-+ .splice_write = iter_file_splice_write,
- .unlocked_ioctl=jffs2_ioctl,
- .mmap = generic_file_readonly_mmap,
- .fsync = jffs2_fsync,
diff --git a/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch
deleted file mode 100644
index a64d3021d4..0000000000
--- a/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Stephen Hemminger <stephen@networkplumber.org>
-Subject: bridge: allow receiption on disabled port
-
-When an ethernet device is enslaved to a bridge, and the bridge STP
-detects loss of carrier (or operational state down), then normally
-packet receiption is blocked.
-
-This breaks control applications like WPA which maybe expecting to
-receive packets to negotiate to bring link up. The bridge needs to
-block forwarding packets from these disabled ports, but there is no
-hard requirement to not allow local packet delivery.
-
-Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -209,6 +209,9 @@ static void __br_handle_local_finish(str
- /* note: already called with rcu_read_lock */
- static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
- {
-+ struct net_bridge_port *p = br_port_get_rcu(skb->dev);
-+
-+ if (p->state != BR_STATE_DISABLED)
- __br_handle_local_finish(skb);
-
- /* return 1 to signal the okfn() was called so it's ok to use the skb */
-@@ -376,6 +379,17 @@ static rx_handler_result_t br_handle_fra
-
- forward:
- switch (p->state) {
-+ case BR_STATE_DISABLED:
-+ if (ether_addr_equal(p->br->dev->dev_addr, dest))
-+ skb->pkt_type = PACKET_HOST;
-+
-+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING,
-+ dev_net(skb->dev), NULL, skb, skb->dev, NULL,
-+ br_handle_local_finish) == 1) {
-+ return RX_HANDLER_PASS;
-+ }
-+ break;
-+
- case BR_STATE_FORWARDING:
- case BR_STATE_LEARNING:
- if (ether_addr_equal(p->br->dev->dev_addr, dest))
diff --git a/target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch b/target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch
deleted file mode 100644
index f420d210c2..0000000000
--- a/target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 4 Jan 2024 15:21:21 +0100
-Subject: [PATCH] net: bridge: do not send arp replies if src and target hw
- addr is the same
-
-There are broken devices in the wild that handle duplicate IP address
-detection by sending out ARP requests for the IP that they received from a
-DHCP server and refuse the address if they get a reply.
-When proxyarp is enabled, they would go into a loop of requesting an address
-and then NAKing it again.
-
-Link: https://github.com/openwrt/openwrt/issues/14309
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/bridge/br_arp_nd_proxy.c
-+++ b/net/bridge/br_arp_nd_proxy.c
-@@ -204,7 +204,10 @@ void br_do_proxy_suppress_arp(struct sk_
- if ((p && (p->flags & BR_PROXYARP)) ||
- (f->dst && (f->dst->flags & (BR_PROXYARP_WIFI |
- BR_NEIGH_SUPPRESS)))) {
-- if (!vid)
-+ replied = true;
-+ if (!memcmp(n->ha, sha, dev->addr_len))
-+ replied = false;
-+ else if (!vid)
- br_arp_send(br, p, skb->dev, sip, tip,
- sha, n->ha, sha, 0, 0);
- else
-@@ -212,7 +215,6 @@ void br_do_proxy_suppress_arp(struct sk_
- sha, n->ha, sha,
- skb->vlan_proto,
- skb_vlan_tag_get(skb));
-- replied = true;
- }
-
- /* If we have replied or as long as we know the
diff --git a/target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch b/target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch
deleted file mode 100644
index 13b79b5c09..0000000000
--- a/target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From: Daniel González Cabanelas <dgcbueu@gmail.com>
-Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week
-
-The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week
-alarms.
-
-Read the "wday" alarm register and convert it to a date to support up 1
-week in our driver.
-
-Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
----
- drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++-----
- 1 file changed, 42 insertions(+), 6 deletions(-)
-
---- a/drivers/rtc/rtc-rs5c372.c
-+++ b/drivers/rtc/rtc-rs5c372.c
-@@ -393,7 +393,9 @@ static int rs5c_read_alarm(struct device
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct rs5c372 *rs5c = i2c_get_clientdata(client);
-- int status;
-+ int status, wday_offs;
-+ struct rtc_time rtc;
-+ unsigned long alarm_secs;
-
- status = rs5c_get_regs(rs5c);
- if (status < 0)
-@@ -403,6 +405,30 @@ static int rs5c_read_alarm(struct device
- t->time.tm_sec = 0;
- t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
- t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]);
-+ t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1;
-+
-+ /* determine the day, month and year based on alarm wday, taking as a
-+ * reference the current time from the rtc
-+ */
-+ status = rs5c372_rtc_read_time(dev, &rtc);
-+ if (status < 0)
-+ return status;
-+
-+ wday_offs = t->time.tm_wday - rtc.tm_wday;
-+ alarm_secs = mktime64(rtc.tm_year + 1900,
-+ rtc.tm_mon + 1,
-+ rtc.tm_mday + wday_offs,
-+ t->time.tm_hour,
-+ t->time.tm_min,
-+ t->time.tm_sec);
-+
-+ if (wday_offs < 0 || (wday_offs == 0 &&
-+ (t->time.tm_hour < rtc.tm_hour ||
-+ (t->time.tm_hour == rtc.tm_hour &&
-+ t->time.tm_min <= rtc.tm_min))))
-+ alarm_secs += 7 * 86400;
-+
-+ rtc_time64_to_tm(alarm_secs, &t->time);
-
- /* ... and status */
- t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE);
-@@ -417,12 +443,20 @@ static int rs5c_set_alarm(struct device
- struct rs5c372 *rs5c = i2c_get_clientdata(client);
- int status, addr, i;
- unsigned char buf[3];
-+ struct rtc_time rtc_tm;
-+ unsigned long rtc_secs, alarm_secs;
-
-- /* only handle up to 24 hours in the future, like RTC_ALM_SET */
-- if (t->time.tm_mday != -1
-- || t->time.tm_mon != -1
-- || t->time.tm_year != -1)
-+ /* chip only can handle alarms up to one week in the future*/
-+ status = rs5c372_rtc_read_time(dev, &rtc_tm);
-+ if (status)
-+ return status;
-+ rtc_secs = rtc_tm_to_time64(&rtc_tm);
-+ alarm_secs = rtc_tm_to_time64(&t->time);
-+ if (alarm_secs >= rtc_secs + 7 * 86400) {
-+ dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n",
-+ __func__, status);
- return -EINVAL;
-+ }
-
- /* REVISIT: round up tm_sec */
-
-@@ -443,7 +477,9 @@ static int rs5c_set_alarm(struct device
- /* set alarm */
- buf[0] = bin2bcd(t->time.tm_min);
- buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
-- buf[2] = 0x7f; /* any/all days */
-+ /* each bit is the day of the week, 0x7f means all days */
-+ buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ?
-+ BIT(t->time.tm_wday) : 0x7f;
-
- for (i = 0; i < sizeof(buf); i++) {
- addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
diff --git a/target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch b/target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch
deleted file mode 100644
index 7e9d0e66c0..0000000000
--- a/target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From: Daniel González Cabanelas <dgcbueu@gmail.com>
-Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source
-
-Currently there is no use for the interrupts on the rs5c372 RTC and the
-wakealarm isn't enabled. There are some devices like NASes which use this
-RTC to wake up from the power off state when the INTR pin is activated by
-the alarm clock.
-
-Enable the alarm and let to be used as a wakeup source.
-
-Tested on a Buffalo LS421DE NAS.
-
-Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
----
- drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/drivers/rtc/rtc-rs5c372.c
-+++ b/drivers/rtc/rtc-rs5c372.c
-@@ -654,6 +654,7 @@ static int rs5c372_probe(struct i2c_clie
- int err = 0;
- int smbus_mode = 0;
- struct rs5c372 *rs5c372;
-+ bool rs5c372_can_wakeup_device = false;
-
- dev_dbg(&client->dev, "%s\n", __func__);
-
-@@ -689,6 +690,12 @@ static int rs5c372_probe(struct i2c_clie
- else
- rs5c372->type = id->driver_data;
-
-+#ifdef CONFIG_OF
-+ if(of_property_read_bool(client->dev.of_node,
-+ "wakeup-source"))
-+ rs5c372_can_wakeup_device = true;
-+#endif
-+
- /* we read registers 0x0f then 0x00-0x0f; skip the first one */
- rs5c372->regs = &rs5c372->buf[1];
- rs5c372->smbus = smbus_mode;
-@@ -722,6 +729,8 @@ static int rs5c372_probe(struct i2c_clie
- goto exit;
- }
-
-+ rs5c372->has_irq = 1;
-+
- /* if the oscillator lost power and no other software (like
- * the bootloader) set it up, do it here.
- *
-@@ -748,6 +757,10 @@ static int rs5c372_probe(struct i2c_clie
- );
-
- /* REVISIT use client->irq to register alarm irq ... */
-+ if (rs5c372_can_wakeup_device) {
-+ device_init_wakeup(&client->dev, true);
-+ }
-+
- rs5c372->rtc = devm_rtc_device_register(&client->dev,
- rs5c372_driver.driver.name,
- &rs5c372_rtc_ops, THIS_MODULE);
-@@ -761,6 +774,9 @@ static int rs5c372_probe(struct i2c_clie
- if (err)
- goto exit;
-
-+ /* the rs5c372 alarm only supports a minute accuracy */
-+ rs5c372->rtc->uie_unsupported = 1;
-+
- return 0;
-
- exit:
diff --git a/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch
deleted file mode 100644
index fc4fe6d6b0..0000000000
--- a/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx
-
-[john@phrozen.org: added to my upstream queue 30.12.2016]
-lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- init/Kconfig | 11 +++++++++++
- kernel/kallsyms.c | 8 ++++++++
- scripts/kallsyms.c | 12 ++++++++++++
- scripts/link-vmlinux.sh | 4 ++++
- 4 files changed, 35 insertions(+)
-
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1447,6 +1447,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW
- the unaligned access emulation.
- see arch/parisc/kernel/unaligned.c for reference
-
-+config KALLSYMS_UNCOMPRESSED
-+ bool "Keep kallsyms uncompressed"
-+ depends on KALLSYMS
-+ help
-+ Normally kallsyms contains compressed symbols (using a token table),
-+ reducing the uncompressed kernel image size. Keeping the symbol table
-+ uncompressed significantly improves the size of this part in compressed
-+ kernel images.
-+
-+ Say N unless you need compressed kernel images to be small.
-+
- config HAVE_PCSPKR_PLATFORM
- bool
-
---- a/kernel/kallsyms.c
-+++ b/kernel/kallsyms.c
-@@ -88,6 +88,11 @@ static unsigned int kallsyms_expand_symb
- * For every byte on the compressed symbol data, copy the table
- * entry for that byte.
- */
-+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
-+ memcpy(result, data + 1, len - 1);
-+ result += len - 1;
-+ len = 0;
-+#endif
- while (len) {
- tptr = &kallsyms_token_table[kallsyms_token_index[*data]];
- data++;
-@@ -120,6 +125,9 @@ tail:
- */
- static char kallsyms_get_symbol_type(unsigned int off)
- {
-+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
-+ return kallsyms_names[off + 1];
-+#endif
- /*
- * Get just the first code, look it up in the token table,
- * and return the first char from this token.
---- a/scripts/kallsyms.c
-+++ b/scripts/kallsyms.c
-@@ -58,6 +58,7 @@ static struct addr_range percpu_range =
- static struct sym_entry **table;
- static unsigned int table_size, table_cnt;
- static int all_symbols;
-+static int uncompressed;
- static int absolute_percpu;
- static int base_relative;
-
-@@ -509,6 +510,9 @@ static void write_src(void)
-
- free(markers);
-
-+ if (uncompressed)
-+ return;
-+
- output_label("kallsyms_token_table");
- off = 0;
- for (i = 0; i < 256; i++) {
-@@ -560,6 +564,9 @@ static unsigned char *find_token(unsigne
- {
- int i;
-
-+ if (uncompressed)
-+ return NULL;
-+
- for (i = 0; i < len - 1; i++) {
- if (str[i] == token[0] && str[i+1] == token[1])
- return &str[i];
-@@ -632,6 +639,9 @@ static void optimize_result(void)
- {
- int i, best;
-
-+ if (uncompressed)
-+ return;
-+
- /* using the '\0' symbol last allows compress_symbols to use standard
- * fast string functions */
- for (i = 255; i >= 0; i--) {
-@@ -796,6 +806,8 @@ int main(int argc, char **argv)
- absolute_percpu = 1;
- else if (strcmp(argv[i], "--base-relative") == 0)
- base_relative = 1;
-+ else if (strcmp(argv[i], "--uncompressed") == 0)
-+ uncompressed = 1;
- else
- usage();
- }
---- a/scripts/link-vmlinux.sh
-+++ b/scripts/link-vmlinux.sh
-@@ -262,6 +262,10 @@ kallsyms()
- kallsymopt="${kallsymopt} --base-relative"
- fi
-
-+ if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then
-+ kallsymopt="${kallsymopt} --uncompressed"
-+ fi
-+
- info KSYMS ${2}
- ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2}
- }
diff --git a/target/linux/generic/pending-5.15/205-backtrace_module_info.patch b/target/linux/generic/pending-5.15/205-backtrace_module_info.patch
deleted file mode 100644
index 6379ce071d..0000000000
--- a/target/linux/generic/pending-5.15/205-backtrace_module_info.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries
-
-[john@phrozen.org: felix will add this to his upstream queue]
-
-lede-commit 53827cdc824556cda910b23ce5030c363b8f1461
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- lib/vsprintf.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
-
---- a/lib/vsprintf.c
-+++ b/lib/vsprintf.c
-@@ -1003,8 +1003,10 @@ char *symbol_string(char *buf, char *end
- struct printf_spec spec, const char *fmt)
- {
- unsigned long value;
--#ifdef CONFIG_KALLSYMS
- char sym[KSYM_SYMBOL_LEN];
-+#ifndef CONFIG_KALLSYMS
-+ struct module *mod;
-+ int len;
- #endif
-
- if (fmt[1] == 'R')
-@@ -1025,8 +1027,14 @@ char *symbol_string(char *buf, char *end
-
- return string_nocheck(buf, end, sym, spec);
- #else
-- return special_hex_number(buf, end, value, sizeof(void *));
-+ len = snprintf(sym, sizeof(sym), "0x%lx", value);
-+ mod = __module_address(value);
-+ if (mod)
-+ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]",
-+ mod->name, mod->core_layout.base,
-+ mod->core_layout.size);
- #endif
-+ return string(buf, end, sym, spec);
- }
-
- static const struct printf_spec default_str_spec = {
diff --git a/target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch
deleted file mode 100644
index 29cfade716..0000000000
--- a/target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: usr: sanitize deps_initramfs list
-
-If any filename in the intramfs dependency
-list contains a colon, that causes a kernel
-build error like this:
-
-/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop.
-make[5]: *** [usr] Error 2
-
-Fix it by removing such filenames from the
-deps_initramfs list.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- usr/Makefile | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/usr/Makefile
-+++ b/usr/Makefile
-@@ -61,6 +61,8 @@ hostprogs := gen_init_cpio
- # The dependency list is generated by gen_initramfs.sh -l
- -include $(obj)/.initramfs_data.cpio.d
-
-+deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v)))
-+
- # do not try to update files included in initramfs
- $(deps_initramfs): ;
-
diff --git a/target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch
deleted file mode 100644
index cd31f9d934..0000000000
--- a/target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Imre Kaloz <kaloz@openwrt.org>
-Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with
- compat-wireless, too
-
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- drivers/net/wireless/ti/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ti/Kconfig
-+++ b/drivers/net/wireless/ti/Kconfig
-@@ -20,7 +20,7 @@ source "drivers/net/wireless/ti/wlcore/K
-
- config WILINK_PLATFORM_DATA
- bool "TI WiLink platform data"
-- depends on WLCORE_SDIO || WL1251_SDIO
-+ depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS
- default y
- help
- Small platform data bit needed to pass data to the sdio modules.
diff --git a/target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch
deleted file mode 100644
index 99f83bb2c4..0000000000
--- a/target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
-Date: Sat, 28 Mar 2020 12:11:50 +0100
-Subject: [PATCH] generic: platform/mikrotik build bits (5.4)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch adds platform/mikrotik kernel build bits
-
-Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
----
- drivers/platform/Kconfig | 2 ++
- drivers/platform/Makefile | 1 +
- 2 files changed, 3 insertions(+)
-
---- a/drivers/platform/Kconfig
-+++ b/drivers/platform/Kconfig
-@@ -15,3 +15,5 @@ source "drivers/platform/mellanox/Kconfi
- source "drivers/platform/olpc/Kconfig"
-
- source "drivers/platform/surface/Kconfig"
-+
-+source "drivers/platform/mikrotik/Kconfig"
---- a/drivers/platform/Makefile
-+++ b/drivers/platform/Makefile
-@@ -10,3 +10,4 @@ obj-$(CONFIG_OLPC_EC) += olpc/
- obj-$(CONFIG_GOLDFISH) += goldfish/
- obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
- obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
-+obj-$(CONFIG_MIKROTIK) += mikrotik/
diff --git a/target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch
deleted file mode 100644
index be4dacf094..0000000000
--- a/target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Mark Miller <mark@mirell.org>
-Subject: mips: expose CONFIG_BOOT_RAW
-
-This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on
-certain Broadcom chipsets running CFE in order to load the kernel.
-
-Signed-off-by: Mark Miller <mark@mirell.org>
-Acked-by: Rob Landley <rob@landley.net>
----
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -1103,9 +1103,6 @@ config FW_ARC
- config ARCH_MAY_HAVE_PC_FDC
- bool
-
--config BOOT_RAW
-- bool
--
- config CEVT_BCM1480
- bool
-
-@@ -3186,6 +3183,18 @@ choice
- bool "Extend builtin kernel arguments with bootloader arguments"
- endchoice
-
-+config BOOT_RAW
-+ bool "Enable the kernel to be executed from the load address"
-+ default n
-+ help
-+ Allow the kernel to be executed from the load address for
-+ bootloaders which cannot read the ELF format. This places
-+ a jump to start_kernel at the load address.
-+
-+ If unsure, say N.
-+
-+
-+
- endmenu
-
- config LOCKDEP_SUPPORT
diff --git a/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch b/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
deleted file mode 100644
index 726c884027..0000000000
--- a/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001
-From: Paul Burton <paul.burton@imgtec.com>
-Date: Mon, 22 Feb 2016 18:09:44 +0000
-Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes
-
-Index-based cache operations may be arbitrarily reordered by out of
-order CPUs. Thus code which writes back the dcache & then invalidates
-the icache using indexed cache ops must include a barrier between
-operating on the 2 caches in order to prevent the scenario in which:
-
- - icache invalidation occurs.
-
- - icache fetch occurs, due to speculation.
-
- - dcache writeback occurs.
-
-If the above were allowed to happen then the icache would contain stale
-data. Forcing the dcache writeback to complete before the icache
-invalidation avoids this.
-
-Signed-off-by: Paul Burton <paul.burton@imgtec.com>
-Cc: James Hogan <james.hogan@imgtec.com>
----
- arch/mips/mm/c-r4k.c | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
---- a/arch/mips/mm/c-r4k.c
-+++ b/arch/mips/mm/c-r4k.c
-@@ -515,6 +515,7 @@ static inline void local_r4k___flush_cac
-
- default:
- r4k_blast_dcache();
-+ mb(); /* cache instructions may be reordered */
- r4k_blast_icache();
- break;
- }
-@@ -595,8 +596,10 @@ static inline void local_r4k_flush_cache
- if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
- r4k_blast_dcache();
- /* If executable, blast stale lines from icache */
-- if (exec)
-+ if (exec) {
-+ mb(); /* cache instructions may be reordered */
- r4k_blast_icache();
-+ }
- }
-
- static void r4k_flush_cache_range(struct vm_area_struct *vma,
-@@ -697,8 +700,13 @@ static inline void local_r4k_flush_cache
- if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
- vaddr ? r4k_blast_dcache_page(addr) :
- r4k_blast_dcache_user_page(addr);
-- if (exec && !cpu_icache_snoops_remote_store)
-+ if (exec)
-+ mb(); /* cache instructions may be reordered */
-+
-+ if (exec && !cpu_icache_snoops_remote_store) {
- r4k_blast_scache_page(addr);
-+ mb(); /* cache instructions may be reordered */
-+ }
- }
- if (exec) {
- if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
-@@ -765,6 +773,7 @@ static inline void __local_r4k_flush_ica
- else
- blast_dcache_range(start, end);
- }
-+ mb(); /* cache instructions may be reordered */
- }
-
- if (type == R4K_INDEX ||
diff --git a/target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch b/target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch
deleted file mode 100644
index 271923fca8..0000000000
--- a/target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: mips: use -mno-branch-likely for kernel and userspace
-
-saves ~11k kernel size after lzma and ~12k squashfs size in the
-
-lede-commit: 41a039f46450ffae9483d6216422098669da2900
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/mips/Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -95,7 +95,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
- # machines may also. Since BFD is incredibly buggy with respect to
- # crossformat linking we rely on the elf2ecoff tool for format conversion.
- #
--cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
-+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
- cflags-y += -msoft-float
- LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
- KBUILD_AFLAGS_MODULE += -mlong-calls
diff --git a/target/linux/generic/pending-5.15/305-mips_module_reloc.patch b/target/linux/generic/pending-5.15/305-mips_module_reloc.patch
deleted file mode 100644
index bbea1f61c1..0000000000
--- a/target/linux/generic/pending-5.15/305-mips_module_reloc.patch
+++ /dev/null
@@ -1,370 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to
-
-lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/mips/Makefile | 5 +
- arch/mips/include/asm/module.h | 5 +
- arch/mips/kernel/module.c | 279 ++++++++++++++++++++++++++++++++++++++++-
- 3 files changed, 284 insertions(+), 5 deletions(-)
-
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -98,8 +98,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
- cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
- cflags-y += -msoft-float
- LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
-+ifdef CONFIG_64BIT
- KBUILD_AFLAGS_MODULE += -mlong-calls
- KBUILD_CFLAGS_MODULE += -mlong-calls
-+else
-+ ifdef CONFIG_DYNAMIC_FTRACE
-+ KBUILD_AFLAGS_MODULE += -mlong-calls
-+ KBUILD_CFLAGS_MODULE += -mlong-calls
-+ else
-+ KBUILD_AFLAGS_MODULE += -mno-long-calls
-+ KBUILD_CFLAGS_MODULE += -mno-long-calls
-+ endif
-+endif
-
- ifeq ($(CONFIG_RELOCATABLE),y)
- LDFLAGS_vmlinux += --emit-relocs
---- a/arch/mips/include/asm/module.h
-+++ b/arch/mips/include/asm/module.h
-@@ -12,6 +12,11 @@ struct mod_arch_specific {
- const struct exception_table_entry *dbe_start;
- const struct exception_table_entry *dbe_end;
- struct mips_hi16 *r_mips_hi16_list;
-+
-+ void *phys_plt_tbl;
-+ void *virt_plt_tbl;
-+ unsigned int phys_plt_offset;
-+ unsigned int virt_plt_offset;
- };
-
- typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
---- a/arch/mips/kernel/module.c
-+++ b/arch/mips/kernel/module.c
-@@ -31,23 +31,261 @@ struct mips_hi16 {
- static LIST_HEAD(dbe_list);
- static DEFINE_SPINLOCK(dbe_lock);
-
--#ifdef MODULE_START
-+/*
-+ * Get the potential max trampolines size required of the init and
-+ * non-init sections. Only used if we cannot find enough contiguous
-+ * physically mapped memory to put the module into.
-+ */
-+static unsigned int
-+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
-+ const char *secstrings, unsigned int symindex, bool is_init)
-+{
-+ unsigned long ret = 0;
-+ unsigned int i, j;
-+ Elf_Sym *syms;
-+
-+ /* Everything marked ALLOC (this includes the exported symbols) */
-+ for (i = 1; i < hdr->e_shnum; ++i) {
-+ unsigned int info = sechdrs[i].sh_info;
-+
-+ if (sechdrs[i].sh_type != SHT_REL
-+ && sechdrs[i].sh_type != SHT_RELA)
-+ continue;
-+
-+ /* Not a valid relocation section? */
-+ if (info >= hdr->e_shnum)
-+ continue;
-+
-+ /* Don't bother with non-allocated sections */
-+ if (!(sechdrs[info].sh_flags & SHF_ALLOC))
-+ continue;
-+
-+ /* If it's called *.init*, and we're not init, we're
-+ not interested */
-+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
-+ != is_init)
-+ continue;
-+
-+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr;
-+ if (sechdrs[i].sh_type == SHT_REL) {
-+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr;
-+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel);
-+
-+ for (j = 0; j < size; ++j) {
-+ Elf_Sym *sym;
-+
-+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26)
-+ continue;
-+
-+ sym = syms + ELF_MIPS_R_SYM(rel[j]);
-+ if (!is_init && sym->st_shndx != SHN_UNDEF)
-+ continue;
-+
-+ ret += 4 * sizeof(int);
-+ }
-+ } else {
-+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr;
-+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela);
-+
-+ for (j = 0; j < size; ++j) {
-+ Elf_Sym *sym;
-+
-+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26)
-+ continue;
-+
-+ sym = syms + ELF_MIPS_R_SYM(rela[j]);
-+ if (!is_init && sym->st_shndx != SHN_UNDEF)
-+ continue;
-+
-+ ret += 4 * sizeof(int);
-+ }
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+#ifndef MODULE_START
-+static void *alloc_phys(unsigned long size)
-+{
-+ unsigned order;
-+ struct page *page;
-+ struct page *p;
-+
-+ size = PAGE_ALIGN(size);
-+ order = get_order(size);
-+
-+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN |
-+ __GFP_THISNODE, order);
-+ if (!page)
-+ return NULL;
-+
-+ split_page(page, order);
-+
-+ /* mark all pages except for the last one */
-+ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p)
-+ set_bit(PG_owner_priv_1, &p->flags);
-+
-+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p)
-+ __free_page(p);
-+
-+ return page_address(page);
-+}
-+#endif
-+
-+static void free_phys(void *ptr)
-+{
-+ struct page *page;
-+ bool free;
-+
-+ page = virt_to_page(ptr);
-+ do {
-+ free = test_and_clear_bit(PG_owner_priv_1, &page->flags);
-+ __free_page(page);
-+ page++;
-+ } while (free);
-+}
-+
-+
- void *module_alloc(unsigned long size)
- {
-+#ifdef MODULE_START
- return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
- GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-+#else
-+ void *ptr;
-+
-+ if (size == 0)
-+ return NULL;
-+
-+ ptr = alloc_phys(size);
-+
-+ /* If we failed to allocate physically contiguous memory,
-+ * fall back to regular vmalloc. The module loader code will
-+ * create jump tables to handle long jumps */
-+ if (!ptr)
-+ return vmalloc(size);
-+
-+ return ptr;
-+#endif
- }
-+
-+static inline bool is_phys_addr(void *ptr)
-+{
-+#ifdef CONFIG_64BIT
-+ return (KSEGX((unsigned long)ptr) == CKSEG0);
-+#else
-+ return (KSEGX(ptr) == KSEG0);
- #endif
-+}
-+
-+/* Free memory returned from module_alloc */
-+void module_memfree(void *module_region)
-+{
-+ if (is_phys_addr(module_region))
-+ free_phys(module_region);
-+ else
-+ vfree(module_region);
-+}
-+
-+static void *__module_alloc(int size, bool phys)
-+{
-+ void *ptr;
-+
-+ if (phys)
-+ ptr = kmalloc(size, GFP_KERNEL);
-+ else
-+ ptr = vmalloc(size);
-+ return ptr;
-+}
-+
-+static void __module_free(void *ptr)
-+{
-+ if (is_phys_addr(ptr))
-+ kfree(ptr);
-+ else
-+ vfree(ptr);
-+}
-+
-+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
-+ char *secstrings, struct module *mod)
-+{
-+ unsigned int symindex = 0;
-+ unsigned int core_size, init_size;
-+ int i;
-+
-+ mod->arch.phys_plt_offset = 0;
-+ mod->arch.virt_plt_offset = 0;
-+ mod->arch.phys_plt_tbl = NULL;
-+ mod->arch.virt_plt_tbl = NULL;
-+
-+ if (IS_ENABLED(CONFIG_64BIT))
-+ return 0;
-+
-+ for (i = 1; i < hdr->e_shnum; i++)
-+ if (sechdrs[i].sh_type == SHT_SYMTAB)
-+ symindex = i;
-+
-+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false);
-+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true);
-+
-+ if ((core_size + init_size) == 0)
-+ return 0;
-+
-+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1);
-+ if (!mod->arch.phys_plt_tbl)
-+ return -ENOMEM;
-+
-+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0);
-+ if (!mod->arch.virt_plt_tbl) {
-+ __module_free(mod->arch.phys_plt_tbl);
-+ mod->arch.phys_plt_tbl = NULL;
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-
- static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v)
- {
- *location = base + v;
- }
-
-+static Elf_Addr add_plt_entry_to(unsigned *plt_offset,
-+ void *start, Elf_Addr v)
-+{
-+ unsigned *tramp = start + *plt_offset;
-+ *plt_offset += 4 * sizeof(int);
-+
-+ /* adjust carry for addiu */
-+ if (v & 0x00008000)
-+ v += 0x10000;
-+
-+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */
-+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */
-+ tramp[2] = 0x03200008; /* jr t9 */
-+ tramp[3] = 0x00000000; /* nop */
-+
-+ return (Elf_Addr) tramp;
-+}
-+
-+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v)
-+{
-+ if (is_phys_addr(location))
-+ return add_plt_entry_to(&me->arch.phys_plt_offset,
-+ me->arch.phys_plt_tbl, v);
-+ else
-+ return add_plt_entry_to(&me->arch.virt_plt_offset,
-+ me->arch.virt_plt_tbl, v);
-+
-+}
-+
- static int apply_r_mips_26(struct module *me, u32 *location, u32 base,
- Elf_Addr v)
- {
-+ u32 ofs = base & 0x03ffffff;
-+
- if (v % 4) {
- pr_err("module %s: dangerous R_MIPS_26 relocation\n",
- me->name);
-@@ -55,13 +293,17 @@ static int apply_r_mips_26(struct module
- }
-
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
-- pr_err("module %s: relocation overflow\n",
-- me->name);
-- return -ENOEXEC;
-+ v = add_plt_entry(me, location, v + (ofs << 2));
-+ if (!v) {
-+ pr_err("module %s: relocation overflow\n",
-+ me->name);
-+ return -ENOEXEC;
-+ }
-+ ofs = 0;
- }
-
- *location = (*location & ~0x03ffffff) |
-- ((base + (v >> 2)) & 0x03ffffff);
-+ ((ofs + (v >> 2)) & 0x03ffffff);
-
- return 0;
- }
-@@ -441,9 +683,36 @@ int module_finalize(const Elf_Ehdr *hdr,
- list_add(&me->arch.dbe_list, &dbe_list);
- spin_unlock_irq(&dbe_lock);
- }
-+
-+ /* Get rid of the fixup trampoline if we're running the module
-+ * from physically mapped address space */
-+ if (me->arch.phys_plt_offset == 0) {
-+ __module_free(me->arch.phys_plt_tbl);
-+ me->arch.phys_plt_tbl = NULL;
-+ }
-+ if (me->arch.virt_plt_offset == 0) {
-+ __module_free(me->arch.virt_plt_tbl);
-+ me->arch.virt_plt_tbl = NULL;
-+ }
-+
- return 0;
- }
-
-+void module_arch_freeing_init(struct module *mod)
-+{
-+ if (mod->state == MODULE_STATE_LIVE)
-+ return;
-+
-+ if (mod->arch.phys_plt_tbl) {
-+ __module_free(mod->arch.phys_plt_tbl);
-+ mod->arch.phys_plt_tbl = NULL;
-+ }
-+ if (mod->arch.virt_plt_tbl) {
-+ __module_free(mod->arch.virt_plt_tbl);
-+ mod->arch.virt_plt_tbl = NULL;
-+ }
-+}
-+
- void module_arch_cleanup(struct module *mod)
- {
- spin_lock_irq(&dbe_lock);
diff --git a/target/linux/generic/pending-5.15/308-mips32r2_tune.patch b/target/linux/generic/pending-5.15/308-mips32r2_tune.patch
deleted file mode 100644
index ef92a5dfb6..0000000000
--- a/target/linux/generic/pending-5.15/308-mips32r2_tune.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2
-
-This provides a good tradeoff across at least 24Kc-74Kc, while also
-producing smaller code.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/mips/Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -175,7 +175,7 @@ cflags-$(CONFIG_CPU_VR41XX) += -march=r4
- cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
- cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
- cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap
--cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap
-+cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap
- cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg
- cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg
- cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap
diff --git a/target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch
deleted file mode 100644
index 191dc6ac3c..0000000000
--- a/target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: fix errors in unresolved weak symbols on arm
-
-lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/arm/kernel/module.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/kernel/module.c
-+++ b/arch/arm/kernel/module.c
-@@ -105,6 +105,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
- return -ENOEXEC;
- }
-
-+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) &&
-+ ELF_ST_BIND(sym->st_info) == STB_WEAK)
-+ continue;
-+
- loc = dstsec->sh_addr + rel->r_offset;
-
- switch (ELF32_R_TYPE(rel->r_info)) {
diff --git a/target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch
deleted file mode 100644
index 3f553b28b3..0000000000
--- a/target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch
+++ /dev/null
@@ -1,282 +0,0 @@
-From: Yousong Zhou <yszhou4tech@gmail.com>
-Subject: MIPS: kexec: Accept command line parameters from userspace.
-
-Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
----
- arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++-----
- arch/mips/kernel/machine_kexec.h | 20 +++++
- arch/mips/kernel/relocate_kernel.S | 21 +++--
- 3 files changed, 167 insertions(+), 27 deletions(-)
- create mode 100644 arch/mips/kernel/machine_kexec.h
-
---- a/arch/mips/kernel/machine_kexec.c
-+++ b/arch/mips/kernel/machine_kexec.c
-@@ -9,14 +9,11 @@
- #include <linux/delay.h>
- #include <linux/libfdt.h>
-
-+#include <asm/bootinfo.h>
- #include <asm/cacheflush.h>
- #include <asm/page.h>
--
--extern const unsigned char relocate_new_kernel[];
--extern const size_t relocate_new_kernel_size;
--
--extern unsigned long kexec_start_address;
--extern unsigned long kexec_indirection_page;
-+#include <linux/uaccess.h>
-+#include "machine_kexec.h"
-
- static unsigned long reboot_code_buffer;
-
-@@ -30,6 +27,101 @@ void (*_crash_smp_send_stop)(void) = NUL
- void (*_machine_kexec_shutdown)(void) = NULL;
- void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
-
-+static void machine_kexec_print_args(void)
-+{
-+ unsigned long argc = (int)kexec_args[0];
-+ int i;
-+
-+ pr_info("kexec_args[0] (argc): %lu\n", argc);
-+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
-+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
-+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
-+
-+ for (i = 0; i < argc; i++) {
-+ pr_info("kexec_argv[%d] = %p, %s\n",
-+ i, kexec_argv[i], kexec_argv[i]);
-+ }
-+}
-+
-+static void machine_kexec_init_argv(struct kimage *image)
-+{
-+ void __user *buf = NULL;
-+ size_t bufsz;
-+ size_t size;
-+ int i;
-+
-+ bufsz = 0;
-+ for (i = 0; i < image->nr_segments; i++) {
-+ struct kexec_segment *seg;
-+
-+ seg = &image->segment[i];
-+ if (seg->bufsz < 6)
-+ continue;
-+
-+ if (strncmp((char *) seg->buf, "kexec ", 6))
-+ continue;
-+
-+ buf = seg->buf;
-+ bufsz = seg->bufsz;
-+ break;
-+ }
-+
-+ if (!buf)
-+ return;
-+
-+ size = KEXEC_COMMAND_LINE_SIZE;
-+ size = min(size, bufsz);
-+ if (size < bufsz)
-+ pr_warn("kexec command line truncated to %zd bytes\n", size);
-+
-+ /* Copy to kernel space */
-+ if (copy_from_user(kexec_argv_buf, buf, size))
-+ pr_warn("kexec command line copy to kernel space failed\n");
-+
-+ kexec_argv_buf[size - 1] = 0;
-+}
-+
-+static void machine_kexec_parse_argv(struct kimage *image)
-+{
-+ char *reboot_code_buffer;
-+ int reloc_delta;
-+ char *ptr;
-+ int argc;
-+ int i;
-+
-+ ptr = kexec_argv_buf;
-+ argc = 0;
-+
-+ /*
-+ * convert command line string to array of parameters
-+ * (as bootloader does).
-+ */
-+ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) {
-+ if (*ptr == ' ') {
-+ *ptr++ = '\0';
-+ continue;
-+ }
-+
-+ kexec_argv[argc++] = ptr;
-+ ptr = strchr(ptr, ' ');
-+ }
-+
-+ if (!argc)
-+ return;
-+
-+ kexec_args[0] = argc;
-+ kexec_args[1] = (unsigned long)kexec_argv;
-+ kexec_args[2] = 0;
-+ kexec_args[3] = 0;
-+
-+ reboot_code_buffer = page_address(image->control_code_page);
-+ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel;
-+
-+ kexec_args[1] += reloc_delta;
-+ for (i = 0; i < argc; i++)
-+ kexec_argv[i] += reloc_delta;
-+}
-+
- static void kexec_image_info(const struct kimage *kimage)
- {
- unsigned long i;
-@@ -99,6 +191,18 @@ machine_kexec_prepare(struct kimage *kim
- #endif
-
- kexec_image_info(kimage);
-+ /*
-+ * Whenever arguments passed from kexec-tools, Init the arguments as
-+ * the original ones to try avoiding booting failure.
-+ */
-+
-+ kexec_args[0] = fw_arg0;
-+ kexec_args[1] = fw_arg1;
-+ kexec_args[2] = fw_arg2;
-+ kexec_args[3] = fw_arg3;
-+
-+ machine_kexec_init_argv(kimage);
-+ machine_kexec_parse_argv(kimage);
-
- if (_machine_kexec_prepare)
- return _machine_kexec_prepare(kimage);
-@@ -161,7 +265,7 @@ machine_crash_shutdown(struct pt_regs *r
- void kexec_nonboot_cpu_jump(void)
- {
- local_flush_icache_range((unsigned long)relocated_kexec_smp_wait,
-- reboot_code_buffer + relocate_new_kernel_size);
-+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
-
- relocated_kexec_smp_wait(NULL);
- }
-@@ -199,7 +303,7 @@ void kexec_reboot(void)
- * machine_kexec() CPU.
- */
- local_flush_icache_range(reboot_code_buffer,
-- reboot_code_buffer + relocate_new_kernel_size);
-+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
-
- do_kexec = (void *)reboot_code_buffer;
- do_kexec();
-@@ -212,10 +316,12 @@ machine_kexec(struct kimage *image)
- unsigned long *ptr;
-
- reboot_code_buffer =
-- (unsigned long)page_address(image->control_code_page);
-+ (unsigned long)page_address(image->control_code_page);
-+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer);
-
- kexec_start_address =
- (unsigned long) phys_to_virt(image->start);
-+ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address);
-
- if (image->type == KEXEC_TYPE_DEFAULT) {
- kexec_indirection_page =
-@@ -223,9 +329,19 @@ machine_kexec(struct kimage *image)
- } else {
- kexec_indirection_page = (unsigned long)&image->head;
- }
-+ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page);
-
-- memcpy((void*)reboot_code_buffer, relocate_new_kernel,
-- relocate_new_kernel_size);
-+ pr_info("Where is memcpy: %p\n", memcpy);
-+ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n",
-+ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end);
-+ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE,
-+ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer);
-+ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel,
-+ KEXEC_RELOCATE_NEW_KERNEL_SIZE);
-+
-+ pr_info("Before _print_args().\n");
-+ machine_kexec_print_args();
-+ pr_info("Before eval loop.\n");
-
- /*
- * The generic kexec code builds a page list with physical
-@@ -256,7 +372,7 @@ machine_kexec(struct kimage *image)
- #ifdef CONFIG_SMP
- /* All secondary cpus now may jump to kexec_wait cycle */
- relocated_kexec_smp_wait = reboot_code_buffer +
-- (void *)(kexec_smp_wait - relocate_new_kernel);
-+ (void *)(kexec_smp_wait - kexec_relocate_new_kernel);
- smp_wmb();
- atomic_set(&kexec_ready_to_reboot, 1);
- #endif
---- /dev/null
-+++ b/arch/mips/kernel/machine_kexec.h
-@@ -0,0 +1,20 @@
-+#ifndef _MACHINE_KEXEC_H
-+#define _MACHINE_KEXEC_H
-+
-+#ifndef __ASSEMBLY__
-+extern const unsigned char kexec_relocate_new_kernel[];
-+extern unsigned long kexec_relocate_new_kernel_end;
-+extern unsigned long kexec_start_address;
-+extern unsigned long kexec_indirection_page;
-+
-+extern char kexec_argv_buf[];
-+extern char *kexec_argv[];
-+
-+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel)
-+#endif /* !__ASSEMBLY__ */
-+
-+#define KEXEC_COMMAND_LINE_SIZE 256
-+#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16)
-+#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long))
-+
-+#endif
---- a/arch/mips/kernel/relocate_kernel.S
-+++ b/arch/mips/kernel/relocate_kernel.S
-@@ -10,10 +10,11 @@
- #include <asm/mipsregs.h>
- #include <asm/stackframe.h>
- #include <asm/addrspace.h>
-+#include "machine_kexec.h"
-
- #include <kernel-entry-init.h>
-
--LEAF(relocate_new_kernel)
-+LEAF(kexec_relocate_new_kernel)
- PTR_L a0, arg0
- PTR_L a1, arg1
- PTR_L a2, arg2
-@@ -98,7 +99,7 @@ done:
- #endif
- /* jump to kexec_start_address */
- j s1
-- END(relocate_new_kernel)
-+ END(kexec_relocate_new_kernel)
-
- #ifdef CONFIG_SMP
- /*
-@@ -177,8 +178,15 @@ EXPORT(kexec_indirection_page)
- PTR_WD 0
- .size kexec_indirection_page, PTRSIZE
-
--relocate_new_kernel_end:
-+kexec_argv_buf:
-+ EXPORT(kexec_argv_buf)
-+ .skip KEXEC_COMMAND_LINE_SIZE
-+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE
-+
-+kexec_argv:
-+ EXPORT(kexec_argv)
-+ .skip KEXEC_ARGV_SIZE
-+ .size kexec_argv, KEXEC_ARGV_SIZE
-
--EXPORT(relocate_new_kernel_size)
-- PTR_WD relocate_new_kernel_end - relocate_new_kernel
-- .size relocate_new_kernel_size, PTRSIZE
-+kexec_relocate_new_kernel_end:
-+ EXPORT(kexec_relocate_new_kernel_end)
diff --git a/target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch
deleted file mode 100644
index 30158cf399..0000000000
--- a/target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001
-From: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
-Date: Fri, 15 Mar 2019 18:53:38 +0300
-Subject: [PATCH] arc add OWRTDTB section
-
-This change allows OpenWRT to patch resulting kernel binary with
-external .dtb.
-
-That allows us to re-use exactky the same vmlinux on different boards
-given its ARC core configurations match (at least cache line sizes etc).
-
-""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external
-.dtb right after it, keeping the string in place.
-
-Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
-Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
-Signed-off-by: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
----
- arch/arc/kernel/head.S | 10 ++++++++++
- arch/arc/kernel/setup.c | 4 +++-
- arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++
- 3 files changed, 26 insertions(+), 1 deletion(-)
-
---- a/arch/arc/kernel/head.S
-+++ b/arch/arc/kernel/head.S
-@@ -88,6 +88,16 @@
- DSP_EARLY_INIT
- .endm
-
-+ ; Here "patch-dtb" will embed external .dtb
-+ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string
-+ ; and pastes .dtb right after it, hense the string precedes
-+ ; __image_dtb symbol.
-+ .section .owrt, "aw",@progbits
-+ .ascii "OWRTDTB:"
-+ENTRY(__image_dtb)
-+ .fill 0x4000
-+END(__image_dtb)
-+
- .section .init.text, "ax",@progbits
-
- ;----------------------------------------------------------------
---- a/arch/arc/kernel/setup.c
-+++ b/arch/arc/kernel/setup.c
-@@ -495,6 +495,8 @@ static inline bool uboot_arg_invalid(uns
- /* We always pass 0 as magic from U-boot */
- #define UBOOT_MAGIC_VALUE 0
-
-+extern struct boot_param_header __image_dtb;
-+
- void __init handle_uboot_args(void)
- {
- bool use_embedded_dtb = true;
-@@ -533,7 +535,7 @@ void __init handle_uboot_args(void)
- ignore_uboot_args:
-
- if (use_embedded_dtb) {
-- machine_desc = setup_machine_fdt(__dtb_start);
-+ machine_desc = setup_machine_fdt(&__image_dtb);
- if (!machine_desc)
- panic("Embedded DT invalid\n");
- }
---- a/arch/arc/kernel/vmlinux.lds.S
-+++ b/arch/arc/kernel/vmlinux.lds.S
-@@ -27,6 +27,19 @@ SECTIONS
-
- . = CONFIG_LINUX_LINK_BASE;
-
-+ /*
-+ * In OpenWRT we want to patch built binary embedding .dtb of choice.
-+ * This is implemented with "patch-dtb" utility which searches for
-+ * "OWRTDTB:" string in first 16k of image and if it is found
-+ * copies .dtb right after mentioned string.
-+ *
-+ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it.
-+ */
-+ .owrt : {
-+ *(.owrt)
-+ . = ALIGN(PAGE_SIZE);
-+ }
-+
- _int_vec_base_lds = .;
- .vector : {
- *(.vector)
diff --git a/target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch
deleted file mode 100644
index 1848a84cc4..0000000000
--- a/target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Alexey Brodkin <abrodkin@synopsys.com>
-Subject: arc: enable unaligned access in kernel mode
-
-This enables misaligned access handling even in kernel mode.
-Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses
-here and there and to cope with that without fixing stuff in the drivers
-we're just gracefully handling it on ARC.
-
-Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
----
- arch/arc/kernel/unaligned.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arc/kernel/unaligned.c
-+++ b/arch/arc/kernel/unaligned.c
-@@ -202,7 +202,7 @@ int misaligned_fixup(unsigned long addre
- char buf[TASK_COMM_LEN];
-
- /* handle user mode only and only if enabled by sysadmin */
-- if (!user_mode(regs) || !unaligned_enabled)
-+ if (!unaligned_enabled)
- return 1;
-
- if (no_unaligned_warning) {
diff --git a/target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch
deleted file mode 100644
index 082b122cb4..0000000000
--- a/target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Fri, 24 May 2019 17:56:19 +0200
-Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx
-
-Enable kernel XZ compression option on PPC_85xx. Tested with
-simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor).
-
-Suggested-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/powerpc/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -221,7 +221,7 @@ config PPC
- select HAVE_KERNEL_GZIP
- select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE
- select HAVE_KERNEL_LZO if DEFAULT_UIMAGE
-- select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x
-+ select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x || PPC_85xx
- select HAVE_KPROBES
- select HAVE_KPROBES_ON_FTRACE
- select HAVE_KRETPROBES
diff --git a/target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch b/target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch
deleted file mode 100644
index 91654cc294..0000000000
--- a/target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From patchwork Thu Mar 16 19:28:33 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13178238
-Return-Path: <linux-mips-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 5EF2AC6FD19
- for <linux-mips@archiver.kernel.org>; Thu, 16 Mar 2023 19:28:43 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230076AbjCPT2l (ORCPT <rfc822;linux-mips@archiver.kernel.org>);
- Thu, 16 Mar 2023 15:28:41 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56412 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230039AbjCPT2k (ORCPT
- <rfc822;linux-mips@vger.kernel.org>); Thu, 16 Mar 2023 15:28:40 -0400
-Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com
- [IPv6:2a00:1450:4864:20::42f])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7259B7D9F;
- Thu, 16 Mar 2023 12:28:38 -0700 (PDT)
-Received: by mail-wr1-x42f.google.com with SMTP id y14so2539231wrq.4;
- Thu, 16 Mar 2023 12:28:38 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1678994917;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=;
- b=FzMRr5ekh/fDiJqTlezNj6nLjzvn5z92FtYeB8MquVSMB8PuvarccnyqAzsXiccf+v
- uwRFIomnTWNLGVjzc1xrB2hGiCKD3jBo5n1u8p/yEV6rpolbxVjfM7eTHXyAHXGXz7ZJ
- TPeVbWfAlxiSD6+BPtXr/efehcdI64fIoL6G/U1WHNMo01Tzr/Obf3y5tug17N0fGcXg
- CH6E5a2HguZUtwrm26LcK9IOV/7xEx5eIE1cOvTLMxPbGWaZwEjjP16HylJr06xRLhaf
- RpiYBT3mXwwuOx0jLOhqavY/2kZ9GVbZRWMMwZrZv9xNO13SBwc1VUVgD4k3FntnSk7Z
- AaOQ==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1678994917;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=;
- b=OaA5DMgqalrfqO5iOtmmxFPsH90MkN7l4EJpyVnzuiO1Wd6rSCpqPOR7xpxZno8OPP
- tdfm4vzn9Ie4AUDbFKDTUlPG+tgkmIruo3K9C0VnY9DD2PRZMEYBbWaJKU1otqKt0NKu
- IAAHNvxvQvCESKzbXFLYwWbRKFScOSMGmGBTDfgThz51A18Ff1hJy/BmnuZk7M2TLgHO
- wQpy9t7oeB/Hkxl41y46emLc/nESsvwvAG/fx/zPzCe9UiaQLrdZq+BKeOwSBedktzK5
- U/ZTfgzU2UGSI67aGRqqGnI0uXq+MAJMK18qzM0VByxj6W+AXJ6BJr5P0quljeQ8upSg
- bEUg==
-X-Gm-Message-State: AO0yUKWnqTlccBDnqwCSRdqOBGc2FyfiLy1Tg7EjPENlISpzXuDYwW/R
- lJSI06rrfq+Vel/SigfpGJI=
-X-Google-Smtp-Source:
- AK7set/jYfYl9ttVzIXJO+ZQVfa6cE/yOsP8fx4teiTmGNNWyVlIJRzMAlF3IUGqRAXAmY3hAabIuQ==
-X-Received: by 2002:a5d:40ce:0:b0:2cd:ceab:df1a with SMTP id
- b14-20020a5d40ce000000b002cdceabdf1amr381006wrq.32.1678994916642;
- Thu, 16 Mar 2023 12:28:36 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- l10-20020a5d4bca000000b002cfea3c49d5sm180041wrt.52.2023.03.16.12.28.35
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Thu, 16 Mar 2023 12:28:35 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com,
- bcm-kernel-feedback-list@broadcom.com, tglx@linutronix.de,
- maz@kernel.org, linux-mips@vger.kernel.org,
- linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2] irqchip/bcm-6345-l1: request memory region
-Date: Thu, 16 Mar 2023 20:28:33 +0100
-Message-Id: <20230316192833.1603149-1-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230316180701.783785-1-noltari@gmail.com>
-References: <20230316180701.783785-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-mips.vger.kernel.org>
-X-Mailing-List: linux-mips@vger.kernel.org
-
-Request memory region in order to display it in /proc/iomem.
-Also stop printing the MMIO address since it just displays (ptrval).
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
----
- v2: request memory region and stop displaying MMIO address.
-
- drivers/irqchip/irq-bcm6345-l1.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/irqchip/irq-bcm6345-l1.c
-+++ b/drivers/irqchip/irq-bcm6345-l1.c
-@@ -257,6 +257,9 @@ static int __init bcm6345_l1_init_one(st
- if (!cpu->map_base)
- return -ENOMEM;
-
-+ if (!request_mem_region(res.start, sz, res.name))
-+ pr_err("failed to request intc memory");
-+
- for (i = 0; i < n_words; i++) {
- cpu->enable_cache[i] = 0;
- __raw_writel(0, cpu->map_base + reg_enable(intc, i));
-@@ -335,8 +338,7 @@ static int __init bcm6345_l1_of_init(str
- for_each_cpu(idx, &intc->cpumask) {
- struct bcm6345_l1_cpu *cpu = intc->cpus[idx];
-
-- pr_info(" CPU%u at MMIO 0x%p (irq = %d)\n", idx,
-- cpu->map_base, cpu->parent_irq);
-+ pr_info(" CPU%u (irq = %d)\n", idx, cpu->parent_irq);
- }
-
- return 0;
diff --git a/target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch
deleted file mode 100644
index 46ef15d127..0000000000
--- a/target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch
+++ /dev/null
@@ -1,328 +0,0 @@
-From 39717277d5c87bdb183cf2f258957b44ba99b4df Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 11:47:35 +0200
-Subject: [PATCH] mtd: mtdsplit support
-
----
- drivers/mtd/Kconfig | 19 ++++
- drivers/mtd/Makefile | 2 +
- drivers/mtd/mtdpart.c | 169 ++++++++++++++++++++++++++++-----
- include/linux/mtd/mtd.h | 25 +++++
- include/linux/mtd/partitions.h | 7 ++
- 5 files changed, 197 insertions(+), 25 deletions(-)
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -12,6 +12,25 @@ menuconfig MTD
-
- if MTD
-
-+menu "OpenWrt specific MTD options"
-+
-+config MTD_ROOTFS_ROOT_DEV
-+ bool "Automatically set 'rootfs' partition to be root filesystem"
-+ default y
-+
-+config MTD_SPLIT_FIRMWARE
-+ bool "Automatically split firmware partition for kernel+rootfs"
-+ default y
-+
-+config MTD_SPLIT_FIRMWARE_NAME
-+ string "Firmware partition name"
-+ depends on MTD_SPLIT_FIRMWARE
-+ default "firmware"
-+
-+source "drivers/mtd/mtdsplit/Kconfig"
-+
-+endmenu
-+
- config MTD_TESTS
- tristate "MTD tests support (DANGEROUS)"
- depends on m
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc
-
- obj-y += parsers/
-
-+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/
-+
- # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
- obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -15,11 +15,13 @@
- #include <linux/kmod.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-+#include <linux/magic.h>
- #include <linux/err.h>
- #include <linux/of.h>
- #include <linux/of_platform.h>
-
- #include "mtdcore.h"
-+#include "mtdsplit/mtdsplit.h"
-
- /*
- * MTD methods which simply translate the effective address and pass through
-@@ -236,6 +238,147 @@ static int mtd_add_partition_attrs(struc
- return ret;
- }
-
-+static DEFINE_SPINLOCK(part_parser_lock);
-+static LIST_HEAD(part_parsers);
-+
-+static struct mtd_part_parser *mtd_part_parser_get(const char *name)
-+{
-+ struct mtd_part_parser *p, *ret = NULL;
-+
-+ spin_lock(&part_parser_lock);
-+
-+ list_for_each_entry(p, &part_parsers, list)
-+ if (!strcmp(p->name, name) && try_module_get(p->owner)) {
-+ ret = p;
-+ break;
-+ }
-+
-+ spin_unlock(&part_parser_lock);
-+
-+ return ret;
-+}
-+
-+static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
-+{
-+ module_put(p->owner);
-+}
-+
-+static struct mtd_part_parser *
-+get_partition_parser_by_type(enum mtd_parser_type type,
-+ struct mtd_part_parser *start)
-+{
-+ struct mtd_part_parser *p, *ret = NULL;
-+
-+ spin_lock(&part_parser_lock);
-+
-+ p = list_prepare_entry(start, &part_parsers, list);
-+ if (start)
-+ mtd_part_parser_put(start);
-+
-+ list_for_each_entry_continue(p, &part_parsers, list) {
-+ if (p->type == type && try_module_get(p->owner)) {
-+ ret = p;
-+ break;
-+ }
-+ }
-+
-+ spin_unlock(&part_parser_lock);
-+
-+ return ret;
-+}
-+
-+static int parse_mtd_partitions_by_type(struct mtd_info *master,
-+ enum mtd_parser_type type,
-+ const struct mtd_partition **pparts,
-+ struct mtd_part_parser_data *data)
-+{
-+ struct mtd_part_parser *prev = NULL;
-+ int ret = 0;
-+
-+ while (1) {
-+ struct mtd_part_parser *parser;
-+
-+ parser = get_partition_parser_by_type(type, prev);
-+ if (!parser)
-+ break;
-+
-+ ret = (*parser->parse_fn)(master, pparts, data);
-+
-+ if (ret > 0) {
-+ mtd_part_parser_put(parser);
-+ printk(KERN_NOTICE
-+ "%d %s partitions found on MTD device %s\n",
-+ ret, parser->name, master->name);
-+ break;
-+ }
-+
-+ prev = parser;
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type)
-+{
-+ struct mtd_partition *parts;
-+ int nr_parts;
-+ int i;
-+
-+ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts,
-+ NULL);
-+ if (nr_parts <= 0)
-+ return nr_parts;
-+
-+ if (WARN_ON(!parts))
-+ return 0;
-+
-+ for (i = 0; i < nr_parts; i++) {
-+ /* adjust partition offsets */
-+ parts[i].offset += child->part.offset;
-+
-+ mtd_add_partition(child->parent,
-+ parts[i].name,
-+ parts[i].offset,
-+ parts[i].size);
-+ }
-+
-+ kfree(parts);
-+
-+ return nr_parts;
-+}
-+
-+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
-+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
-+#else
-+#define SPLIT_FIRMWARE_NAME "unused"
-+#endif
-+
-+static void split_firmware(struct mtd_info *master, struct mtd_info *part)
-+{
-+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE);
-+}
-+
-+static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part)
-+{
-+ static int rootfs_found = 0;
-+
-+ if (rootfs_found)
-+ return;
-+
-+ if (of_find_property(mtd_get_of_node(part), "linux,rootfs", NULL) ||
-+ !strcmp(part->name, "rootfs")) {
-+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS);
-+
-+ rootfs_found = 1;
-+ }
-+
-+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) &&
-+ !strcmp(part->name, SPLIT_FIRMWARE_NAME) &&
-+ !of_find_property(mtd_get_of_node(part), "compatible", NULL))
-+ split_firmware(master, part);
-+}
-+
- int mtd_add_partition(struct mtd_info *parent, const char *name,
- long long offset, long long length)
- {
-@@ -274,6 +417,7 @@ int mtd_add_partition(struct mtd_info *p
- if (ret)
- goto err_remove_part;
-
-+ mtd_partition_split(parent, child);
- mtd_add_partition_attrs(child);
-
- return 0;
-@@ -422,6 +566,7 @@ int add_mtd_partitions(struct mtd_info *
- goto err_del_partitions;
- }
-
-+ mtd_partition_split(master, child);
- mtd_add_partition_attrs(child);
-
- /* Look for subpartitions */
-@@ -438,31 +583,6 @@ err_del_partitions:
- return ret;
- }
-
--static DEFINE_SPINLOCK(part_parser_lock);
--static LIST_HEAD(part_parsers);
--
--static struct mtd_part_parser *mtd_part_parser_get(const char *name)
--{
-- struct mtd_part_parser *p, *ret = NULL;
--
-- spin_lock(&part_parser_lock);
--
-- list_for_each_entry(p, &part_parsers, list)
-- if (!strcmp(p->name, name) && try_module_get(p->owner)) {
-- ret = p;
-- break;
-- }
--
-- spin_unlock(&part_parser_lock);
--
-- return ret;
--}
--
--static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
--{
-- module_put(p->owner);
--}
--
- /*
- * Many partition parsers just expected the core to kfree() all their data in
- * one chunk. Do that by default.
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -620,6 +620,24 @@ static inline void mtd_align_erase_req(s
- req->len += mtd->erasesize - mod;
- }
-
-+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd)
-+{
-+ if (mtd_mod_by_eb(sz, mtd) == 0)
-+ return sz;
-+
-+ /* Round up to next erase block */
-+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize;
-+}
-+
-+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd)
-+{
-+ if (mtd_mod_by_eb(sz, mtd) == 0)
-+ return sz;
-+
-+ /* Round down to the start of the current erase block */
-+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize;
-+}
-+
- static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
- {
- if (mtd->writesize_shift)
-@@ -693,6 +711,13 @@ extern struct mtd_info *of_get_mtd_devic
- extern struct mtd_info *get_mtd_device_nm(const char *name);
- extern void put_mtd_device(struct mtd_info *mtd);
-
-+static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd)
-+{
-+ if (!mtd_is_partition(mtd))
-+ return 0;
-+
-+ return mtd->part.offset;
-+}
-
- struct mtd_notifier {
- void (*add)(struct mtd_info *mtd);
---- a/include/linux/mtd/partitions.h
-+++ b/include/linux/mtd/partitions.h
-@@ -75,6 +75,12 @@ struct mtd_part_parser_data {
- * Functions dealing with the various ways of partitioning the space
- */
-
-+enum mtd_parser_type {
-+ MTD_PARSER_TYPE_DEVICE = 0,
-+ MTD_PARSER_TYPE_ROOTFS,
-+ MTD_PARSER_TYPE_FIRMWARE,
-+};
-+
- struct mtd_part_parser {
- struct list_head list;
- struct module *owner;
-@@ -83,6 +89,7 @@ struct mtd_part_parser {
- int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
- struct mtd_part_parser_data *);
- void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
-+ enum mtd_parser_type type;
- };
-
- /* Container for passing around a set of parsed partitions */
diff --git a/target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch b/target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch
deleted file mode 100644
index 650e10a3a5..0000000000
--- a/target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 31 Oct 2023 15:51:01 +0100
-Subject: [PATCH] mtd: don't register NVMEM devices for partitions with custom
- drivers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes issue exposed by upstream commit f4cf4e5db331 ("Revert
-"nvmem: add new config option"").
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/mtd/mtdcore.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -537,6 +537,29 @@ static int mtd_nvmem_add(struct mtd_info
- struct device_node *node = mtd_get_of_node(mtd);
- struct nvmem_config config = {};
-
-+ /*
-+ * Do NOT register NVMEM device for any partition that is meant to be
-+ * handled by a U-Boot env driver. That would result in associating two
-+ * different NVMEM devices with the same OF node.
-+ *
-+ * An example of unwanted behaviour of above (forwardtrace):
-+ * of_get_mac_addr_nvmem()
-+ * of_nvmem_cell_get()
-+ * __nvmem_device_get()
-+ *
-+ * We can't have __nvmem_device_get() return "mtdX" NVMEM device instead
-+ * of U-Boot env NVMEM device. That would result in failing to find
-+ * NVMEM cell.
-+ *
-+ * This issue seems to affect U-Boot env case only and will go away with
-+ * switch to NVMEM layouts.
-+ */
-+ if (of_device_is_compatible(node, "u-boot,env") ||
-+ of_device_is_compatible(node, "u-boot,env-redundant-bool") ||
-+ of_device_is_compatible(node, "u-boot,env-redundant-count") ||
-+ of_device_is_compatible(node, "brcm,env"))
-+ return 0;
-+
- config.id = -1;
- config.dev = &mtd->dev;
- config.name = dev_name(&mtd->dev);
diff --git a/target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch b/target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch
deleted file mode 100644
index 0a12132de3..0000000000
--- a/target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch
+++ /dev/null
@@ -1,245 +0,0 @@
-From acacdac272927ae1d96e0bca51eb82899671eaea Mon Sep 17 00:00:00 2001
-From: John Thomson <git@johnthomson.fastmail.com.au>
-Date: Fri, 25 Dec 2020 18:50:08 +1000
-Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Do not prevent writing to mtd partitions where a partition boundary sits
-on a minor erasesize boundary.
-This addresses a FIXME that has been present since the start of the
-linux git history:
-/* Doesn't start on a boundary of major erase size */
-/* FIXME: Let it be writable if it is on a boundary of
- * _minor_ erase size though */
-
-Allow a uniform erase region spi-nor device to be configured
-to use the non-uniform erase regions code path for an erase with:
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-
-On supporting hardware (SECT_4K: majority of current SPI-NOR device)
-provide the facility for an erase to use the least number
-of SPI-NOR operations, as well as access to 4K erase without
-requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
-
-Introduce erasesize_minor to the mtd struct,
-the smallest erasesize supported by the device
-
-On existing devices, this is useful where write support is wanted
-for data on a 4K partition, such as some u-boot-env partitions,
-or RouterBoot soft_config, while still netting the performance
-benefits of using 64K sectors
-
-Performance:
-time mtd erase firmware
-OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length
-
-Without this patch
-MTD_SPI_NOR_USE_4K_SECTORS=y |n
-real 2m 11.66s |0m 50.86s
-user 0m 0.00s |0m 0.00s
-sys 1m 56.20s |0m 50.80s
-
-With this patch
-MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y
-real 0m 51.68s |0m 50.85s |2m 12.89s
-user 0m 0.00s |0m 0.00s |0m 0.01s
-sys 0m 46.94s |0m 50.38s |2m 12.46s
-
-Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
-Signed-off-by: Thibaut VARÈNE <hacks+kernel@slashdirt.org>
-
----
-
-checkpatch does not like the printk(KERN_WARNING
-these should be changed separately beforehand?
-
-Changes v1 -> v2:
-Added mtdcore sysfs for erasesize_minor
-Removed finding minor erasesize for variable erase regions device,
-as untested and no responses regarding it.
-Moved IF_ENABLED for SPINOR variable erase to guard setting
-erasesize_minor in spi-nor/core.c
-Removed setting erasesize to minor where partition boundaries require
-minor erase to be writable
-Simplified minor boundary check by relying on minor being a factor of
-major
-
-Changes RFC -> v1:
-Fix uninitialized variable smatch warning
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
----
- drivers/mtd/mtdcore.c | 10 ++++++++++
- drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++----------
- drivers/mtd/spi-nor/Kconfig | 10 ++++++++++
- drivers/mtd/spi-nor/core.c | 11 +++++++++--
- include/linux/mtd/mtd.h | 2 ++
- 5 files changed, 56 insertions(+), 12 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -169,6 +169,15 @@ static ssize_t mtd_erasesize_show(struct
- }
- MTD_DEVICE_ATTR_RO(erasesize);
-
-+static ssize_t mtd_erasesize_minor_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct mtd_info *mtd = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor);
-+}
-+MTD_DEVICE_ATTR_RO(erasesize_minor);
-+
- static ssize_t mtd_writesize_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -314,6 +323,7 @@ static struct attribute *mtd_attrs[] = {
- &dev_attr_flags.attr,
- &dev_attr_size.attr,
- &dev_attr_erasesize.attr,
-+ &dev_attr_erasesize_minor.attr,
- &dev_attr_writesize.attr,
- &dev_attr_subpagesize.attr,
- &dev_attr_oobsize.attr,
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -41,6 +41,7 @@ static struct mtd_info *allocate_partiti
- struct mtd_info *master = mtd_get_master(parent);
- int wr_alignment = (parent->flags & MTD_NO_ERASE) ?
- master->writesize : master->erasesize;
-+ int wr_alignment_minor = 0;
- u64 parent_size = mtd_is_partition(parent) ?
- parent->part.size : parent->size;
- struct mtd_info *child;
-@@ -165,6 +166,7 @@ static struct mtd_info *allocate_partiti
- } else {
- /* Single erase size */
- child->erasesize = master->erasesize;
-+ child->erasesize_minor = master->erasesize_minor;
- }
-
- /*
-@@ -172,26 +174,39 @@ static struct mtd_info *allocate_partiti
- * exposes several regions with different erasesize. Adjust
- * wr_alignment accordingly.
- */
-- if (!(child->flags & MTD_NO_ERASE))
-+ if (!(child->flags & MTD_NO_ERASE)) {
- wr_alignment = child->erasesize;
-+ wr_alignment_minor = child->erasesize_minor;
-+ }
-
- tmp = mtd_get_master_ofs(child, 0);
- remainder = do_div(tmp, wr_alignment);
- if ((child->flags & MTD_WRITEABLE) && remainder) {
-- /* Doesn't start on a boundary of major erase size */
-- /* FIXME: Let it be writable if it is on a boundary of
-- * _minor_ erase size though */
-- child->flags &= ~MTD_WRITEABLE;
-- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
-- part->name);
-+ if (wr_alignment_minor) {
-+ /* rely on minor being a factor of major erasesize */
-+ tmp = remainder;
-+ remainder = do_div(tmp, wr_alignment_minor);
-+ }
-+ if (remainder) {
-+ child->flags &= ~MTD_WRITEABLE;
-+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
-+ part->name);
-+ }
- }
-
- tmp = mtd_get_master_ofs(child, 0) + child->part.size;
- remainder = do_div(tmp, wr_alignment);
- if ((child->flags & MTD_WRITEABLE) && remainder) {
-- child->flags &= ~MTD_WRITEABLE;
-- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
-- part->name);
-+ if (wr_alignment_minor) {
-+ tmp = remainder;
-+ remainder = do_div(tmp, wr_alignment_minor);
-+ }
-+
-+ if (remainder) {
-+ child->flags &= ~MTD_WRITEABLE;
-+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
-+ part->name);
-+ }
- }
-
- child->size = child->part.size;
---- a/drivers/mtd/spi-nor/Kconfig
-+++ b/drivers/mtd/spi-nor/Kconfig
-@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR
-
- if MTD_SPI_NOR
-
-+config MTD_SPI_NOR_USE_VARIABLE_ERASE
-+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes"
-+ depends on !MTD_SPI_NOR_USE_4K_SECTORS
-+ default n
-+ help
-+ Allow mixed use of all hardware supported erasesizes,
-+ by forcing spi_nor to use the multiple eraseregions code path.
-+ For example: A 68K erase will use one 64K erase, and one 4K erase
-+ on supporting hardware.
-+
- config MTD_SPI_NOR_USE_4K_SECTORS
- bool "Use small 4096 B erase sectors"
- default y
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -1272,6 +1272,8 @@ static u8 spi_nor_convert_3to4_erase(u8
-
- static bool spi_nor_has_uniform_erase(const struct spi_nor *nor)
- {
-+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE))
-+ return false;
- return !!nor->params->erase_map.uniform_erase_type;
- }
-
-@@ -2401,6 +2403,7 @@ static int spi_nor_select_erase(struct s
- {
- struct spi_nor_erase_map *map = &nor->params->erase_map;
- const struct spi_nor_erase_type *erase = NULL;
-+ const struct spi_nor_erase_type *erase_minor = NULL;
- struct mtd_info *mtd = &nor->mtd;
- u32 wanted_size = nor->info->sector_size;
- int i;
-@@ -2433,8 +2436,9 @@ static int spi_nor_select_erase(struct s
- */
- for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) {
- if (map->erase_type[i].size) {
-- erase = &map->erase_type[i];
-- break;
-+ if (!erase)
-+ erase = &map->erase_type[i];
-+ erase_minor = &map->erase_type[i];
- }
- }
-
-@@ -2442,6 +2446,9 @@ static int spi_nor_select_erase(struct s
- return -EINVAL;
-
- mtd->erasesize = erase->size;
-+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) &&
-+ erase_minor && erase_minor->size < erase->size)
-+ mtd->erasesize_minor = erase_minor->size;
- return 0;
- }
-
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -250,6 +250,8 @@ struct mtd_info {
- * information below if they desire
- */
- uint32_t erasesize;
-+ /* "Minor" (smallest) erase size supported by the whole device */
-+ uint32_t erasesize_minor;
- /* Minimal writable flash unit size. In case of NOR flash it is 1 (even
- * though individual bits can be cleared), in case of NAND flash it is
- * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
diff --git a/target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch b/target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch
deleted file mode 100644
index 6363cb61af..0000000000
--- a/target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 52d14545d2fc276b1bf9ccf48d4612fab6edfb6a Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 6 May 2021 17:49:55 +0200
-Subject: [PATCH] mtd: spi-nor: Add support for BoHong bh25q128as
-
-Add MTD support for the BoHong bh25q128as SPI NOR chip.
-The chip has 16MB of total capacity, divided into a total of 256
-sectors, each 64KB sized. The chip also supports 4KB sectors.
-Additionally, it supports dual and quad read modes.
-
-Functionality was verified on an Tenbay WR1800K / MTK MT7621 board.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/mtd/spi-nor/Makefile | 1 +
- drivers/mtd/spi-nor/bohong.c | 21 +++++++++++++++++++++
- drivers/mtd/spi-nor/core.c | 1 +
- drivers/mtd/spi-nor/core.h | 1 +
- 4 files changed, 24 insertions(+)
- create mode 100644 drivers/mtd/spi-nor/bohong.c
-
---- a/drivers/mtd/spi-nor/Makefile
-+++ b/drivers/mtd/spi-nor/Makefile
-@@ -2,6 +2,7 @@
-
- spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o
- spi-nor-objs += atmel.o
-+spi-nor-objs += bohong.o
- spi-nor-objs += catalyst.o
- spi-nor-objs += eon.o
- spi-nor-objs += esmt.o
---- /dev/null
-+++ b/drivers/mtd/spi-nor/bohong.c
-@@ -0,0 +1,21 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2005, Intec Automation Inc.
-+ * Copyright (C) 2014, Freescale Semiconductor, Inc.
-+ */
-+
-+#include <linux/mtd/spi-nor.h>
-+
-+#include "core.h"
-+
-+static const struct flash_info bohong_parts[] = {
-+ /* BoHong Microelectronics */
-+ { "bh25q128as", INFO(0x684018, 0, 64 * 1024, 256,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+};
-+
-+const struct spi_nor_manufacturer spi_nor_bohong = {
-+ .name = "bohong",
-+ .parts = bohong_parts,
-+ .nparts = ARRAY_SIZE(bohong_parts),
-+};
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -1844,6 +1844,7 @@ int spi_nor_sr2_bit7_quad_enable(struct
-
- static const struct spi_nor_manufacturer *manufacturers[] = {
- &spi_nor_atmel,
-+ &spi_nor_bohong,
- &spi_nor_catalyst,
- &spi_nor_eon,
- &spi_nor_esmt,
---- a/drivers/mtd/spi-nor/core.h
-+++ b/drivers/mtd/spi-nor/core.h
-@@ -473,6 +473,7 @@ struct sfdp {
-
- /* Manufacturer drivers. */
- extern const struct spi_nor_manufacturer spi_nor_atmel;
-+extern const struct spi_nor_manufacturer spi_nor_bohong;
- extern const struct spi_nor_manufacturer spi_nor_catalyst;
- extern const struct spi_nor_manufacturer spi_nor_eon;
- extern const struct spi_nor_manufacturer spi_nor_esmt;
diff --git a/target/linux/generic/pending-5.15/420-mtd-redboot_space.patch b/target/linux/generic/pending-5.15/420-mtd-redboot_space.patch
deleted file mode 100644
index 5518ea71dd..0000000000
--- a/target/linux/generic/pending-5.15/420-mtd-redboot_space.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable)
-
-[john@phrozen.org: used by ixp and others]
-
-lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/redboot.c | 19 +++++++++++++------
- 1 file changed, 13 insertions(+), 6 deletions(-)
-
---- a/drivers/mtd/parsers/redboot.c
-+++ b/drivers/mtd/parsers/redboot.c
-@@ -278,14 +278,21 @@ nogood:
- #endif
- names += strlen(names) + 1;
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
- if (fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
-- i++;
-- parts[i].offset = parts[i - 1].size + parts[i - 1].offset;
-- parts[i].size = fl->next->img->flash_base - parts[i].offset;
-- parts[i].name = nullname;
-- }
-+ if (!strcmp(parts[i].name, "rootfs")) {
-+ parts[i].size = fl->next->img->flash_base;
-+ parts[i].size &= ~(master->erasesize - 1);
-+ parts[i].size -= parts[i].offset;
-+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
-+ nrparts--;
-+ } else {
-+ i++;
-+ parts[i].offset = parts[i-1].size + parts[i-1].offset;
-+ parts[i].size = fl->next->img->flash_base - parts[i].offset;
-+ parts[i].name = nullname;
- #endif
-+ }
-+ }
- tmp_fl = fl;
- fl = fl->next;
- kfree(tmp_fl);
diff --git a/target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch
deleted file mode 100644
index c7a8d9d7b7..0000000000
--- a/target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch
+++ /dev/null
@@ -1,229 +0,0 @@
-From: Florian Fainelli <f.fainelli@gmail.com>
-Subject: Add myloader partition table parser
-
-[john@phozen.org: shoud be upstreamable]
-
-lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-[adjust for kernel 5.4, add myloader.c to patch]
-Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -57,6 +57,22 @@ config MTD_CMDLINE_PARTS
-
- If unsure, say 'N'.
-
-+config MTD_MYLOADER_PARTS
-+ tristate "MyLoader partition parsing"
-+ depends on ADM5120 || ATH79
-+ help
-+ MyLoader is a bootloader which allows the user to define partitions
-+ in flash devices, by putting a table in the second erase block
-+ on the device, similar to a partition table. This table gives the
-+ offsets and lengths of the user defined partitions.
-+
-+ If you need code which can detect and parse these tables, and
-+ register MTD 'partitions' corresponding to each image detected,
-+ enable this option.
-+
-+ You will still need the parsing functions to be called by the driver
-+ for your particular device. It won't happen automatically.
-+
- config MTD_OF_PARTS
- tristate "OpenFirmware (device tree) partitioning parser"
- default y
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.
- obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
- obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
- obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
-+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
- obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
- ofpart-y += ofpart_core.o
- ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o
---- /dev/null
-+++ b/drivers/mtd/parsers/myloader.c
-@@ -0,0 +1,181 @@
-+/*
-+ * Parse MyLoader-style flash partition tables and produce a Linux partition
-+ * array to match.
-+ *
-+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
-+ *
-+ * This file was based on drivers/mtd/redboot.c
-+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/vmalloc.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/byteorder/generic.h>
-+#include <linux/myloader.h>
-+
-+#define BLOCK_LEN_MIN 0x10000
-+#define PART_NAME_LEN 32
-+
-+struct part_data {
-+ struct mylo_partition_table tab;
-+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
-+};
-+
-+static int myloader_parse_partitions(struct mtd_info *master,
-+ const struct mtd_partition **pparts,
-+ struct mtd_part_parser_data *data)
-+{
-+ struct part_data *buf;
-+ struct mylo_partition_table *tab;
-+ struct mylo_partition *part;
-+ struct mtd_partition *mtd_parts;
-+ struct mtd_partition *mtd_part;
-+ int num_parts;
-+ int ret, i;
-+ size_t retlen;
-+ char *names;
-+ unsigned long offset;
-+ unsigned long blocklen;
-+
-+ buf = vmalloc(sizeof(*buf));
-+ if (!buf) {
-+ return -ENOMEM;
-+ goto out;
-+ }
-+ tab = &buf->tab;
-+
-+ blocklen = master->erasesize;
-+ if (blocklen < BLOCK_LEN_MIN)
-+ blocklen = BLOCK_LEN_MIN;
-+
-+ offset = blocklen;
-+
-+ /* Find the partition table */
-+ for (i = 0; i < 4; i++, offset += blocklen) {
-+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
-+ " at offset 0x%lx\n", master->name, offset);
-+
-+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
-+ (void *)buf);
-+ if (ret)
-+ goto out_free_buf;
-+
-+ if (retlen != sizeof(*buf)) {
-+ ret = -EIO;
-+ goto out_free_buf;
-+ }
-+
-+ /* Check for Partition Table magic number */
-+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
-+ break;
-+
-+ }
-+
-+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
-+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
-+ master->name);
-+ ret = 0;
-+ goto out_free_buf;
-+ }
-+
-+ /* The MyLoader and the Partition Table is always present */
-+ num_parts = 2;
-+
-+ /* Detect number of used partitions */
-+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
-+ part = &tab->partitions[i];
-+
-+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
-+ continue;
-+
-+ num_parts++;
-+ }
-+
-+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
-+ num_parts * PART_NAME_LEN), GFP_KERNEL);
-+
-+ if (!mtd_parts) {
-+ ret = -ENOMEM;
-+ goto out_free_buf;
-+ }
-+
-+ mtd_part = mtd_parts;
-+ names = (char *)&mtd_parts[num_parts];
-+
-+ strncpy(names, "myloader", PART_NAME_LEN);
-+ mtd_part->name = names;
-+ mtd_part->offset = 0;
-+ mtd_part->size = offset;
-+ mtd_part->mask_flags = MTD_WRITEABLE;
-+ mtd_part++;
-+ names += PART_NAME_LEN;
-+
-+ strncpy(names, "partition_table", PART_NAME_LEN);
-+ mtd_part->name = names;
-+ mtd_part->offset = offset;
-+ mtd_part->size = blocklen;
-+ mtd_part->mask_flags = MTD_WRITEABLE;
-+ mtd_part++;
-+ names += PART_NAME_LEN;
-+
-+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
-+ part = &tab->partitions[i];
-+
-+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
-+ continue;
-+
-+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
-+ strncpy(names, buf->names[i], PART_NAME_LEN);
-+ else
-+ snprintf(names, PART_NAME_LEN, "partition%d", i);
-+
-+ mtd_part->offset = le32_to_cpu(part->addr);
-+ mtd_part->size = le32_to_cpu(part->size);
-+ mtd_part->name = names;
-+ mtd_part++;
-+ names += PART_NAME_LEN;
-+ }
-+
-+ *pparts = mtd_parts;
-+ ret = num_parts;
-+
-+ out_free_buf:
-+ vfree(buf);
-+ out:
-+ return ret;
-+}
-+
-+static struct mtd_part_parser myloader_mtd_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = myloader_parse_partitions,
-+ .name = "MyLoader",
-+};
-+
-+static int __init myloader_mtd_parser_init(void)
-+{
-+ register_mtd_parser(&myloader_mtd_parser);
-+
-+ return 0;
-+}
-+
-+static void __exit myloader_mtd_parser_exit(void)
-+{
-+ deregister_mtd_parser(&myloader_mtd_parser);
-+}
-+
-+module_init(myloader_mtd_parser_init);
-+module_exit(myloader_mtd_parser_exit);
-+
-+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
-+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
deleted file mode 100644
index bcea45d009..0000000000
--- a/target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/drivers/mtd/parsers/parser_trx.c
-+++ b/drivers/mtd/parsers/parser_trx.c
-@@ -25,6 +25,33 @@ struct trx_header {
- uint32_t offset[3];
- } __packed;
-
-+/*
-+ * Calculate real end offset (address) for a given amount of data. It checks
-+ * all blocks skipping bad ones.
-+ */
-+static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes)
-+{
-+ size_t real_offset = 0;
-+
-+ if (mtd_block_isbad(mtd, real_offset))
-+ pr_warn("Base offset shouldn't be at bad block");
-+
-+ while (bytes >= mtd->erasesize) {
-+ bytes -= mtd->erasesize;
-+ real_offset += mtd->erasesize;
-+ while (mtd_block_isbad(mtd, real_offset)) {
-+ real_offset += mtd->erasesize;
-+
-+ if (real_offset >= mtd->size)
-+ return real_offset - mtd->erasesize;
-+ }
-+ }
-+
-+ real_offset += bytes;
-+
-+ return real_offset;
-+}
-+
- static const char *parser_trx_data_part_name(struct mtd_info *master,
- size_t offset)
- {
-@@ -86,21 +113,21 @@ static int parser_trx_parse(struct mtd_i
- if (trx.offset[2]) {
- part = &parts[curr_part++];
- part->name = "loader";
-- part->offset = trx.offset[i];
-+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
- i++;
- }
-
- if (trx.offset[i]) {
- part = &parts[curr_part++];
- part->name = "linux";
-- part->offset = trx.offset[i];
-+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
- i++;
- }
-
- if (trx.offset[i]) {
- part = &parts[curr_part++];
-- part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
-- part->offset = trx.offset[i];
-+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
-+ part->name = parser_trx_data_part_name(mtd, part->offset);
- i++;
- }
-
diff --git a/target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
deleted file mode 100644
index 852654d924..0000000000
--- a/target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: mtd: bcm47xxpart: detect T_Meter partition
-
-It can be found on many Netgear devices. It consists of many 0x30 blocks
-starting with 4D 54.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/parsers/bcm47xxpart.c
-+++ b/drivers/mtd/parsers/bcm47xxpart.c
-@@ -35,6 +35,7 @@
- #define NVRAM_HEADER 0x48534C46 /* FLSH */
- #define POT_MAGIC1 0x54544f50 /* POTT */
- #define POT_MAGIC2 0x504f /* OP */
-+#define T_METER_MAGIC 0x4D540000 /* MT */
- #define ML_MAGIC1 0x39685a42
- #define ML_MAGIC2 0x26594131
- #define TRX_MAGIC 0x30524448
-@@ -178,6 +179,15 @@ static int bcm47xxpart_parse(struct mtd_
- MTD_WRITEABLE);
- continue;
- }
-+
-+ /* T_Meter */
-+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
-+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
-+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) {
-+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset,
-+ MTD_WRITEABLE);
-+ continue;
-+ }
-
- /* TRX */
- if (buf[0x000 / 4] == TRX_MAGIC) {
diff --git a/target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch
deleted file mode 100644
index ee949f73c0..0000000000
--- a/target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
-Date: Tue, 24 Mar 2020 11:45:07 +0100
-Subject: [PATCH] generic: routerboot partition build bits (5.4)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch adds routerbootpart kernel build bits
-
-Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
----
- drivers/mtd/parsers/Kconfig | 9 +++++++++
- drivers/mtd/parsers/Makefile | 1 +
- 2 files changed, 10 insertions(+)
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -226,3 +226,12 @@ config MTD_SERCOMM_PARTS
- partition map. This partition table contains real partition
- offsets, which may differ from device to device depending on the
- number and location of bad blocks on NAND.
-+
-+config MTD_ROUTERBOOT_PARTS
-+ tristate "RouterBoot flash partition parser"
-+ depends on MTD && OF
-+ help
-+ MikroTik RouterBoot is implemented as a multi segment system on the
-+ flash, some of which are fixed and some of which are located at
-+ variable offsets. This parser handles both cases via properly
-+ formatted DTS.
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpa
- obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
- obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
- obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o
-+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o
diff --git a/target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
deleted file mode 100644
index 0be74a5977..0000000000
--- a/target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: disable cfi cmdset 0002 erase suspend
-
-on some platforms, erase suspend leads to data corruption and lockups when write
-ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh.
-rather than play whack-a-mole with a hard to reproduce issue on a variety of devices,
-simply disable erase suspend, as it will usually not produce any useful gain on
-the small filesystems used on embedded hardware.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/chips/cfi_cmdset_0002.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -907,7 +907,7 @@ static int get_chip(struct map_info *map
- return 0;
-
- case FL_ERASING:
-- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
-+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
- !(mode == FL_READY || mode == FL_POINT ||
- (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
- goto sleep;
diff --git a/target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch
deleted file mode 100644
index ca56de8271..0000000000
--- a/target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-From: George Kashperko <george@znau.edu.ua>
-Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data.
-
-Signed-off-by: George Kashperko <george@znau.edu.ua>
----
- drivers/mtd/chips/cfi_cmdset_0002.c | 1 +
- 1 file changed, 1 insertion(+)
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -2051,6 +2051,7 @@ static int __xipram do_write_buffer(stru
-
- /* Write Buffer Load */
- map_write(map, CMD(0x25), cmd_adr);
-+ (void) map_read(map, cmd_adr);
-
- chip->state = FL_WRITING_TO_BUFFER;
-
diff --git a/target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch
deleted file mode 100644
index f58d5452ab..0000000000
--- a/target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: Disable software protection bits for Macronix flashes.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/spi-nor/spi-nor.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/macronix.c
-+++ b/drivers/mtd/spi-nor/macronix.c
-@@ -93,6 +93,7 @@ static void macronix_default_init(struct
- {
- nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
- nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
-+ nor->flags |= SNOR_F_HAS_LOCK;
- }
-
- static const struct spi_nor_fixups macronix_fixups = {
diff --git a/target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch
deleted file mode 100644
index 9383e48856..0000000000
--- a/target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From: Piotr Dymacz <pepe2k@gmail.com>
-Subject: kernel/mtd: add support for EON EN25Q128
-
-Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
----
- drivers/mtd/spi-nor/spi-nor.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/eon.c
-+++ b/drivers/mtd/spi-nor/eon.c
-@@ -25,6 +25,7 @@ static const struct flash_info eon_parts
- { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) },
- { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
- { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
-+ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) },
- { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16,
- SECT_4K | SPI_NOR_DUAL_READ) },
- { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32,
diff --git a/target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch b/target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch
deleted file mode 100644
index 3c579e55e3..0000000000
--- a/target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Christian Marangi <ansuelsmth@gmail.com>
-Subject: kernel/mtd: add support for EON EN25QX128A
-
-Add support for EON EN25QX128A with no flags as it does
-support SFDP parsing.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/mtd/spi-nor/spi-nor.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/eon.c
-+++ b/drivers/mtd/spi-nor/eon.c
-@@ -26,6 +26,7 @@ static const struct flash_info eon_parts
- { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
- { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
- { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) },
-+ { "en25qx128a", INFO(0x1c7118, 0, 64 * 1024, 256, 0) },
- { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16,
- SECT_4K | SPI_NOR_DUAL_READ) },
- { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32,
diff --git a/target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch
deleted file mode 100644
index 46471588ec..0000000000
--- a/target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From patchwork Thu Feb 6 17:19:41 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 1234465
-Date: Thu, 6 Feb 2020 19:19:41 +0200
-From: Daniel Golle <daniel@makrotopia.org>
-To: linux-mtd@lists.infradead.org
-Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip
-Message-ID: <20200206171941.GA2398@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>,
- <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>
-Cc: Eitan Cohen <eitan@neot-semadar.com>, Piotr Dymacz <pepe2k@gmail.com>,
- Tudor Ambarus <tudor.ambarus@microchip.com>
-Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org>
-Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org
-
-Add XT25F128B made by XTX Technology (Shenzhen) Limited.
-This chip supports dual and quad read and uniform 4K-byte erase.
-Verified on Teltonika RUT955 which comes with XT25F128B in recent
-versions of the device.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/spi-nor/spi-nor.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/spi-nor/Makefile
-+++ b/drivers/mtd/spi-nor/Makefile
-@@ -18,6 +18,7 @@ spi-nor-objs += sst.o
- spi-nor-objs += winbond.o
- spi-nor-objs += xilinx.o
- spi-nor-objs += xmc.o
-+spi-nor-objs += xtx.o
- obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o
-
- obj-$(CONFIG_MTD_SPI_NOR) += controllers/
---- /dev/null
-+++ b/drivers/mtd/spi-nor/xtx.c
-@@ -0,0 +1,15 @@
-+// SPDX-License-Identifier: GPL-2.0
-+#include <linux/mtd/spi-nor.h>
-+
-+#include "core.h"
-+
-+static const struct flash_info xtx_parts[] = {
-+ /* XTX Technology (Shenzhen) Limited */
-+ { "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+};
-+
-+const struct spi_nor_manufacturer spi_nor_xtx = {
-+ .name = "xtx",
-+ .parts = xtx_parts,
-+ .nparts = ARRAY_SIZE(xtx_parts),
-+};
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -1861,6 +1861,7 @@ static const struct spi_nor_manufacturer
- &spi_nor_winbond,
- &spi_nor_xilinx,
- &spi_nor_xmc,
-+ &spi_nor_xtx,
- };
-
- static const struct flash_info *
---- a/drivers/mtd/spi-nor/core.h
-+++ b/drivers/mtd/spi-nor/core.h
-@@ -490,6 +490,7 @@ extern const struct spi_nor_manufacturer
- extern const struct spi_nor_manufacturer spi_nor_winbond;
- extern const struct spi_nor_manufacturer spi_nor_xilinx;
- extern const struct spi_nor_manufacturer spi_nor_xmc;
-+extern const struct spi_nor_manufacturer spi_nor_xtx;
-
- extern const struct attribute_group *spi_nor_sysfs_groups[];
-
diff --git a/target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch
deleted file mode 100644
index c32cde559d..0000000000
--- a/target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001
-From: Koen Vandeputte <koen.vandeputte@ncentric.com>
-Date: Mon, 6 Jan 2020 13:07:56 +0100
-Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05
-
-Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
----
- drivers/mtd/spi-nor/spi-nor.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/mtd/spi-nor/gigadevice.c
-+++ b/drivers/mtd/spi-nor/gigadevice.c
-@@ -24,6 +24,9 @@ static struct spi_nor_fixups gd25q256_fi
- };
-
- static const struct flash_info gigadevice_parts[] = {
-+ { "gd25q05", INFO(0xc84010, 0, 64 * 1024, 1,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
- { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32,
- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
diff --git a/target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch b/target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch
deleted file mode 100644
index 7c8b686277..0000000000
--- a/target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From f8943df3beb0d3f9754bb35320c3a378727175a8 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Thu, 14 Jul 2022 08:38:07 +0200
-Subject: [PATCH] spi-nor/gigadevic: add gd25q512
-
----
- drivers/mtd/spi-nor/gigadevice.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/mtd/spi-nor/gigadevice.c
-+++ b/drivers/mtd/spi-nor/gigadevice.c
-@@ -53,6 +53,9 @@ static const struct flash_info gigadevic
- SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK |
- SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
- .fixups = &gd25q256_fixups },
-+ { "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES) },
- };
-
- const struct spi_nor_manufacturer spi_nor_gigadevice = {
diff --git a/target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch b/target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch
deleted file mode 100644
index ab402e622a..0000000000
--- a/target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 87363cc0e522de3294ea6ae10fb468d2a8d6fb2f Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:17:21 +0200
-Subject: [PATCH] spi-nor/esmt.c: add esmt f25l16pa
-
-This fixes support for Dongwon T&I DW02-412H which uses F25L16PA(2S)
-flash.
-
----
- drivers/mtd/spi-nor/esmt.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mtd/spi-nor/esmt.c
-+++ b/drivers/mtd/spi-nor/esmt.c
-@@ -10,6 +10,8 @@
-
- static const struct flash_info esmt_parts[] = {
- /* ESMT */
-+ { "f25l16pa-2s", INFO(0x8c2115, 0, 64 * 1024, 32,
-+ SECT_4K | SPI_NOR_HAS_LOCK) },
- { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64,
- SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) },
- { "f25l32qa", INFO(0x8c4116, 0, 64 * 1024, 64,
diff --git a/target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch b/target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch
deleted file mode 100644
index 68e373ea23..0000000000
--- a/target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From f6b33d850f7f12555df2fa0e3349b33427bf5890 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:19:01 +0200
-Subject: [PATCH] spi-nor/xmc.c: add xm25qh128c
-
-The XMC XM25QH128C is a 16MB SPI NOR chip. The patch is verified on
-Ruijie RG-EW3200GX PRO.
-Datasheet available at https://www.xmcwh.com/uploads/435/XM25QH128C.pdf
-
----
- drivers/mtd/spi-nor/xmc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mtd/spi-nor/xmc.c
-+++ b/drivers/mtd/spi-nor/xmc.c
-@@ -14,6 +14,8 @@ static const struct flash_info xmc_parts
- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256,
- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- };
-
- const struct spi_nor_manufacturer spi_nor_xmc = {
diff --git a/target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch b/target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch
deleted file mode 100644
index d117cfe0a3..0000000000
--- a/target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From a43b844cb40bf1b783055fdc81b7f991e21e7e76 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Wed, 13 Apr 2022 11:58:17 +0800
-Subject: [PATCH] mtd: spinand: add support for ESMT F50x1G41LB
-
-This patch adds support for ESMT F50L1G41LB and F50D1G41LB.
-It seems that ESMT likes to use random JEDEC ID from other vendors.
-Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from
-Micron. For this reason, the ESMT entry is named esmt_c8 with explicit
-JEDEC ID in variable name.
-
-Datasheets:
-https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf
-https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
----
- drivers/mtd/nand/spi/Makefile | 2 +-
- drivers/mtd/nand/spi/core.c | 1 +
- drivers/mtd/nand/spi/esmt.c | 89 +++++++++++++++++++++++++++++++++++
- include/linux/mtd/spinand.h | 1 +
- 4 files changed, 92 insertions(+), 1 deletion(-)
- create mode 100644 drivers/mtd/nand/spi/esmt.c
-
---- a/drivers/mtd/nand/spi/Makefile
-+++ b/drivers/mtd/nand/spi/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
-+spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
- obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -906,6 +906,7 @@ static const struct nand_ops spinand_ops
- };
-
- static const struct spinand_manufacturer *spinand_manufacturers[] = {
-+ &esmt_c8_spinand_manufacturer,
- &gigadevice_spinand_manufacturer,
- &macronix_spinand_manufacturer,
- &micron_spinand_manufacturer,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/esmt.c
-@@ -0,0 +1,89 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Author:
-+ * Chuanhong Guo <gch981213@gmail.com>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */
-+#define SPINAND_MFR_ESMT_C8 0xc8
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(write_cache_variants,
-+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(update_cache_variants,
-+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
-+
-+static int f50l1g41lb_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = 16 * section + 8;
-+ region->length = 8;
-+
-+ return 0;
-+}
-+
-+static int f50l1g41lb_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = 16 * section + 2;
-+ region->length = 6;
-+
-+ return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops f50l1g41lb_ooblayout = {
-+ .ecc = f50l1g41lb_ooblayout_ecc,
-+ .free = f50l1g41lb_ooblayout_free,
-+};
-+
-+static const struct spinand_info esmt_c8_spinand_table[] = {
-+ SPINAND_INFO("F50L1G41LB",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(1, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)),
-+ SPINAND_INFO("F50D1G41LB",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(1, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)),
-+};
-+
-+static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = {
-+};
-+
-+const struct spinand_manufacturer esmt_c8_spinand_manufacturer = {
-+ .id = SPINAND_MFR_ESMT_C8,
-+ .name = "ESMT",
-+ .chips = esmt_c8_spinand_table,
-+ .nchips = ARRAY_SIZE(esmt_c8_spinand_table),
-+ .ops = &esmt_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -260,6 +260,7 @@ struct spinand_manufacturer {
- };
-
- /* SPI NAND manufacturers */
-+extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
- extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
- extern const struct spinand_manufacturer macronix_spinand_manufacturer;
- extern const struct spinand_manufacturer micron_spinand_manufacturer;
diff --git a/target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch b/target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch
deleted file mode 100644
index 7e20e14bb6..0000000000
--- a/target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch
+++ /dev/null
@@ -1,168 +0,0 @@
-From f32085fc0b87049491b07e198d924d738a1a2834 Mon Sep 17 00:00:00 2001
-From: Daniel Danzberger <daniel@dd-wrt.com>
-Date: Wed, 3 Aug 2022 17:31:03 +0200
-Subject: [PATCH] mtd: spinand: Add support for Etron EM73D044VCx
-
-Airoha is a new ARM platform based on Cortex-A53 which has recently been
-merged into linux-next.
-
-Due to BootROM limitations on this platform, the Cortex-A53 can't run in
-Aarch64 mode and code must be compiled for 32-Bit ARM.
-
-This support is based mostly on those linux-next commits backported
-for kernel 5.15.
-
-Patches:
-1 - platform support = linux-next
-2 - clock driver = linux-next
-3 - gpio driver = linux-next
-4 - linux,usable-memory-range dts support = linux-next
-5 - mtd spinand driver
-6 - spi driver
-7 - pci driver (kconfig only, uses mediatek PCI) = linux-next
-
-Still missing:
-- Ethernet driver
-- Sysupgrade support
-
-A.t.m there exists one subtarget EN7523 with only one evaluation
-board.
-
-The initramfs can be run with the following commands from u-boot:
--
-u-boot> setenv bootfile \
- openwrt-airoha-airoha_en7523-evb-initramfs-kernel.bin
-u-boot> tftpboot
-u-boot> bootm 0x81800000
--
-
-Submitted-by: Daniel Danzberger <daniel@dd-wrt.com>
-
---- a/drivers/mtd/nand/spi/Makefile
-+++ b/drivers/mtd/nand/spi/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
-+spinand-objs := core.o esmt.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
- obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -908,6 +908,7 @@ static const struct nand_ops spinand_ops
- static const struct spinand_manufacturer *spinand_manufacturers[] = {
- &esmt_c8_spinand_manufacturer,
- &gigadevice_spinand_manufacturer,
-+ &etron_spinand_manufacturer,
- &macronix_spinand_manufacturer,
- &micron_spinand_manufacturer,
- &paragon_spinand_manufacturer,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/etron.c
-@@ -0,0 +1,98 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+#define SPINAND_MFR_ETRON 0xd5
-+
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(write_cache_variants,
-+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(update_cache_variants,
-+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
-+
-+static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ if (section)
-+ return -ERANGE;
-+
-+ oobregion->offset = 72;
-+ oobregion->length = 56;
-+
-+ return 0;
-+}
-+
-+static int etron_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ if (section)
-+ return -ERANGE;
-+
-+ oobregion->offset = 1;
-+ oobregion->length = 71;
-+
-+ return 0;
-+}
-+
-+static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
-+{
-+ switch (status & STATUS_ECC_MASK) {
-+ case STATUS_ECC_NO_BITFLIPS:
-+ return 0;
-+
-+ case STATUS_ECC_HAS_BITFLIPS:
-+ /* Between 1-7 bitflips were corrected */
-+ return 7;
-+
-+ case STATUS_ECC_MASK:
-+ /* Maximum bitflips were corrected */
-+ return 8;
-+
-+ case STATUS_ECC_UNCOR_ERROR:
-+ return -EBADMSG;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static const struct mtd_ooblayout_ops etron_ooblayout = {
-+ .ecc = etron_ooblayout_ecc,
-+ .free = etron_ooblayout_free,
-+};
-+
-+static const struct spinand_info etron_spinand_table[] = {
-+ SPINAND_INFO("EM73D044VCx",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f),
-+ // bpc, pagesize, oobsize, pagesperblock, bperlun, maxbadplun, ppl, lpt, #t
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
-+};
-+
-+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
-+};
-+
-+const struct spinand_manufacturer etron_spinand_manufacturer = {
-+ .id = SPINAND_MFR_ETRON,
-+ .name = "Etron",
-+ .chips = etron_spinand_table,
-+ .nchips = ARRAY_SIZE(etron_spinand_table),
-+ .ops = &etron_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -261,6 +261,7 @@ struct spinand_manufacturer {
-
- /* SPI NAND manufacturers */
- extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
-+extern const struct spinand_manufacturer etron_spinand_manufacturer;
- extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
- extern const struct spinand_manufacturer macronix_spinand_manufacturer;
- extern const struct spinand_manufacturer micron_spinand_manufacturer;
diff --git a/target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch b/target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch
deleted file mode 100644
index 236d1c2755..0000000000
--- a/target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Joe Mullally <jwmullally@gmail.com>
-Subject: mtd/spi-nor/xmc: add support for XMC XM25QH64C
-
-The XMC XM25QH64C is a 8MB SPI NOR chip. The patch is verified on TL-WPA8631P v3.
-Datasheet available at https://www.xmcwh.com/uploads/442/XM25QH64C.pdf
-
-Signed-off-by: Joe Mullally <jwmullally@gmail.com>
----
- drivers/mtd/spi-nor/xmc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mtd/spi-nor/xmc.c
-+++ b/drivers/mtd/spi-nor/xmc.c
-@@ -12,6 +12,8 @@ static const struct flash_info xmc_parts
- /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
- { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128,
- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ { "XM25QH64C", INFO(0x204017, 0, 64 * 1024, 128,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256,
- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256,
diff --git a/target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
deleted file mode 100644
index e8da36edba..0000000000
--- a/target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 36 insertions(+)
-
---- a/drivers/mtd/ubi/build.c
-+++ b/drivers/mtd/ubi/build.c
-@@ -1207,6 +1207,73 @@ static struct mtd_info * __init open_mtd
- return mtd;
- }
-
-+/*
-+ * This function tries attaching mtd partitions named either "ubi" or "data"
-+ * during boot.
-+ */
-+static void __init ubi_auto_attach(void)
-+{
-+ int err;
-+ struct mtd_info *mtd;
-+ loff_t offset = 0;
-+ size_t len;
-+ char magic[4];
-+
-+ /* try attaching mtd device named "ubi" or "data" */
-+ mtd = open_mtd_device("ubi");
-+ if (IS_ERR(mtd))
-+ mtd = open_mtd_device("data");
-+
-+ if (IS_ERR(mtd))
-+ return;
-+
-+ /* get the first not bad block */
-+ if (mtd_can_have_bb(mtd))
-+ while (mtd_block_isbad(mtd, offset)) {
-+ offset += mtd->erasesize;
-+
-+ if (offset > mtd->size) {
-+ pr_err("UBI error: Failed to find a non-bad "
-+ "block on mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+ }
-+
-+ /* check if the read from flash was successful */
-+ err = mtd_read(mtd, offset, 4, &len, (void *) magic);
-+ if ((err && !mtd_is_bitflip(err)) || len != 4) {
-+ pr_err("UBI error: unable to read from mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+
-+ /* check for a valid ubi magic */
-+ if (strncmp(magic, "UBI#", 4)) {
-+ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+
-+ /* don't auto-add media types where UBI doesn't makes sense */
-+ if (mtd->type != MTD_NANDFLASH &&
-+ mtd->type != MTD_NORFLASH &&
-+ mtd->type != MTD_DATAFLASH &&
-+ mtd->type != MTD_MLCNANDFLASH)
-+ goto cleanup;
-+
-+ mutex_lock(&ubi_devices_mutex);
-+ pr_notice("UBI: auto-attach mtd%d\n", mtd->index);
-+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0);
-+ mutex_unlock(&ubi_devices_mutex);
-+ if (err < 0) {
-+ pr_err("UBI error: cannot attach mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+
-+ return;
-+
-+cleanup:
-+ put_mtd_device(mtd);
-+}
-+
- static int __init ubi_init(void)
- {
- int err, i, k;
-@@ -1290,6 +1357,12 @@ static int __init ubi_init(void)
- }
- }
-
-+ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd
-+ * parameter was given */
-+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
-+ !ubi_is_module() && !mtd_devs)
-+ ubi_auto_attach();
-+
- err = ubiblock_init();
- if (err) {
- pr_err("UBI error: block: cannot initialize, error %d\n", err);
diff --git a/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
deleted file mode 100644
index ae53770c11..0000000000
--- a/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: ubi: auto-create ubiblock device for rootfs
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 42 insertions(+)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -642,6 +642,47 @@ static void __init ubiblock_create_from_
- }
- }
-
-+#define UBIFS_NODE_MAGIC 0x06101831
-+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc)
-+{
-+ int ret;
-+ uint32_t magic_of, magic;
-+ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4);
-+ if (ret)
-+ return 0;
-+ magic = le32_to_cpu(magic_of);
-+ return magic == UBIFS_NODE_MAGIC;
-+}
-+
-+static void __init ubiblock_create_auto_rootfs(void)
-+{
-+ int ubi_num, ret, is_ubifs;
-+ struct ubi_volume_desc *desc;
-+ struct ubi_volume_info vi;
-+
-+ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) {
-+ desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY);
-+ if (IS_ERR(desc))
-+ desc = ubi_open_volume_nm(ubi_num, "fit", UBI_READONLY);;
-+
-+ if (IS_ERR(desc))
-+ continue;
-+
-+ ubi_get_volume_info(desc, &vi);
-+ is_ubifs = ubi_vol_is_ubifs(desc);
-+ ubi_close_volume(desc);
-+ if (is_ubifs)
-+ break;
-+
-+ ret = ubiblock_create(&vi);
-+ if (ret)
-+ pr_err("UBI error: block: can't add '%s' volume, err=%d\n",
-+ vi.name, ret);
-+ /* always break if we get here */
-+ break;
-+ }
-+}
-+
- static void ubiblock_remove_all(void)
- {
- struct ubiblock *next;
-@@ -674,6 +715,10 @@ int __init ubiblock_init(void)
- */
- ubiblock_create_from_param();
-
-+ /* auto-attach "rootfs" volume if existing and non-ubifs */
-+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV))
-+ ubiblock_create_auto_rootfs();
-+
- /*
- * Block devices are only created upon user requests, so we ignore
- * existing volumes.
diff --git a/target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch
deleted file mode 100644
index cf41c8cad3..0000000000
--- a/target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- init/do_mounts.c | 26 +++++++++++++++++++++++++-
- 1 file changed, 25 insertions(+), 1 deletion(-)
-
---- a/init/do_mounts.c
-+++ b/init/do_mounts.c
-@@ -447,7 +447,30 @@ retry:
- out:
- put_page(page);
- }
--
-+
-+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
-+static int __init mount_ubi_rootfs(void)
-+{
-+ int flags = MS_SILENT;
-+ int err, tried = 0;
-+
-+ while (tried < 2) {
-+ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \
-+ root_mount_data);
-+ switch (err) {
-+ case -EACCES:
-+ flags |= MS_RDONLY;
-+ tried++;
-+ break;
-+ default:
-+ return err;
-+ }
-+ }
-+
-+ return -EINVAL;
-+}
-+#endif
-+
- #ifdef CONFIG_ROOT_NFS
-
- #define NFSROOT_TIMEOUT_MIN 5
-@@ -580,6 +603,10 @@ void __init mount_root(void)
- return;
- }
- #endif
-+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
-+ if (!mount_ubi_rootfs())
-+ return;
-+#endif
- if (ROOT_DEV == 0 && root_device_name && root_fs_names) {
- if (mount_nodev_root() == 0)
- return;
diff --git a/target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
deleted file mode 100644
index 266a6331c2..0000000000
--- a/target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -42,6 +42,7 @@
- #include <linux/scatterlist.h>
- #include <linux/idr.h>
- #include <asm/div64.h>
-+#include <linux/root_dev.h>
-
- #include "ubi-media.h"
- #include "ubi.h"
-@@ -451,6 +452,15 @@ int ubiblock_create(struct ubi_volume_in
- dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
- dev->ubi_num, dev->vol_id, vi->name);
- mutex_unlock(&devices_mutex);
-+
-+ if (!strcmp(vi->name, "rootfs") &&
-+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
-+ ROOT_DEV == 0) {
-+ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n",
-+ dev->ubi_num, dev->vol_id, vi->name);
-+ ROOT_DEV = MKDEV(gd->major, gd->first_minor);
-+ }
-+
- return 0;
-
- out_remove_minor:
diff --git a/target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch
deleted file mode 100644
index 413431755f..0000000000
--- a/target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: mtd: add EOF marker support to the UBI layer
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++---
- drivers/mtd/ubi/ubi.h | 1 +
- 2 files changed, 23 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/ubi/attach.c
-+++ b/drivers/mtd/ubi/attach.c
-@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id)
- #endif
- }
-
-+static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech)
-+{
-+ return ech->padding1[0] == 'E' &&
-+ ech->padding1[1] == 'O' &&
-+ ech->padding1[2] == 'F';
-+}
-+
- /**
- * scan_peb - scan and process UBI headers of a PEB.
- * @ubi: UBI device description object
-@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u
- return 0;
- }
-
-- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
-- if (err < 0)
-- return err;
-+ if (!ai->eof_found) {
-+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
-+ if (err < 0)
-+ return err;
-+
-+ if (ec_hdr_has_eof(ech)) {
-+ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n",
-+ pnum);
-+ ai->eof_found = true;
-+ }
-+ }
-+
-+ if (ai->eof_found)
-+ err = UBI_IO_FF_BITFLIPS;
-+
- switch (err) {
- case 0:
- break;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -778,6 +778,7 @@ struct ubi_attach_info {
- int mean_ec;
- uint64_t ec_sum;
- int ec_count;
-+ bool eof_found;
- struct kmem_cache *aeb_slab_cache;
- struct ubi_ec_hdr *ech;
- struct ubi_vid_io_buf *vidb;
diff --git a/target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch
deleted file mode 100644
index 01f3b9ec2d..0000000000
--- a/target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001
-From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
-Date: Wed, 5 Sep 2018 01:32:51 +0200
-Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices
-
-Document virtual mtd-concat device bindings.
-
-Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
----
- .../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++
- 1 file changed, 36 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt
-@@ -0,0 +1,36 @@
-+Virtual MTD concat device
-+
-+Requires properties:
-+- devices: list of phandles to mtd nodes that should be concatenated
-+
-+Example:
-+
-+&spi {
-+ flash0: flash@0 {
-+ ...
-+ };
-+ flash1: flash@1 {
-+ ...
-+ };
-+};
-+
-+flash {
-+ compatible = "mtd-concat";
-+
-+ devices = <&flash0 &flash1>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x0000000 0x0040000>;
-+ read-only;
-+ };
-+
-+ partition@40000 {
-+ label = "firmware";
-+ reg = <0x0040000 0x1fc0000>;
-+ };
-+ }
-+}
diff --git a/target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch
deleted file mode 100644
index e0cbc4508b..0000000000
--- a/target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch
+++ /dev/null
@@ -1,216 +0,0 @@
-From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001
-From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
-Date: Sat, 25 Aug 2018 12:35:22 +0200
-Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices
-
-Some mtd drivers like physmap variants have support for concatenating
-multiple mtd devices, but there is no generic way to define such a
-concat device from within the device tree.
-
-This is useful for some SoC boards that use multiple flash chips as
-memory banks of a single mtd device, with partitions spanning chip
-borders.
-
-This commit adds a driver for creating virtual mtd-concat devices. They
-must have a compatible = "mtd-concat" line, and define a list of devices
-to concat in the 'devices' property, for example:
-
-flash {
- compatible = "mtd-concat";
-
- devices = <&flash0 &flash1>;
-
- partitions {
- ...
- };
-};
-
-The driver is added to the very end of the mtd Makefile to increase the
-likelyhood of all child devices already being loaded at the time of
-probing, preventing unnecessary deferred probes.
-
-Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
----
- drivers/mtd/Kconfig | 2 +
- drivers/mtd/Makefile | 3 +
- drivers/mtd/composite/Kconfig | 12 +++
- drivers/mtd/composite/Makefile | 6 ++
- drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++
- 5 files changed, 151 insertions(+)
- create mode 100644 drivers/mtd/composite/Kconfig
- create mode 100644 drivers/mtd/composite/Makefile
- create mode 100644 drivers/mtd/composite/virt_concat.c
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -241,4 +241,6 @@ source "drivers/mtd/ubi/Kconfig"
-
- source "drivers/mtd/hyperbus/Kconfig"
-
-+source "drivers/mtd/composite/Kconfig"
-+
- endif # MTD
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -33,3 +33,6 @@ obj-y += chips/ lpddr/ maps/ devices/ n
- obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
- obj-$(CONFIG_MTD_UBI) += ubi/
- obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
-+
-+# Composite drivers must be loaded last
-+obj-y += composite/
---- /dev/null
-+++ b/drivers/mtd/composite/Kconfig
-@@ -0,0 +1,12 @@
-+menu "Composite MTD device drivers"
-+ depends on MTD!=n
-+
-+config MTD_VIRT_CONCAT
-+ tristate "Virtual concat MTD device"
-+ help
-+ This driver allows creation of a virtual MTD concat device, which
-+ concatenates multiple underlying MTD devices to a single device.
-+ This is required by some SoC boards where multiple memory banks are
-+ used as one device with partitions spanning across device boundaries.
-+
-+endmenu
---- /dev/null
-+++ b/drivers/mtd/composite/Makefile
-@@ -0,0 +1,6 @@
-+# SPDX-License-Identifier: GPL-2.0
-+#
-+# linux/drivers/mtd/composite/Makefile
-+#
-+
-+obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o
---- /dev/null
-+++ b/drivers/mtd/composite/virt_concat.c
-@@ -0,0 +1,128 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Virtual concat MTD device driver
-+ *
-+ * Copyright (C) 2018 Bernhard Frauendienst
-+ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/mtd/concat.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/slab.h>
-+
-+/*
-+ * struct of_virt_concat - platform device driver data.
-+ * @cmtd the final mtd_concat device
-+ * @num_devices the number of devices in @devices
-+ * @devices points to an array of devices already loaded
-+ */
-+struct of_virt_concat {
-+ struct mtd_info *cmtd;
-+ int num_devices;
-+ struct mtd_info **devices;
-+};
-+
-+static int virt_concat_remove(struct platform_device *pdev)
-+{
-+ struct of_virt_concat *info;
-+ int i;
-+
-+ info = platform_get_drvdata(pdev);
-+ if (!info)
-+ return 0;
-+
-+ // unset data for when this is called after a probe error
-+ platform_set_drvdata(pdev, NULL);
-+
-+ if (info->cmtd) {
-+ mtd_device_unregister(info->cmtd);
-+ mtd_concat_destroy(info->cmtd);
-+ }
-+
-+ if (info->devices) {
-+ for (i = 0; i < info->num_devices; i++)
-+ put_mtd_device(info->devices[i]);
-+ }
-+
-+ return 0;
-+}
-+
-+static int virt_concat_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ struct of_phandle_iterator it;
-+ struct of_virt_concat *info;
-+ struct mtd_info *mtd;
-+ int err = 0, count;
-+
-+ count = of_count_phandle_with_args(node, "devices", NULL);
-+ if (count <= 0)
-+ return -EINVAL;
-+
-+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return -ENOMEM;
-+ info->devices = devm_kcalloc(&pdev->dev, count,
-+ sizeof(*(info->devices)), GFP_KERNEL);
-+ if (!info->devices) {
-+ err = -ENOMEM;
-+ goto err_remove;
-+ }
-+
-+ platform_set_drvdata(pdev, info);
-+
-+ of_for_each_phandle(&it, err, node, "devices", NULL, 0) {
-+ mtd = of_get_mtd_device_by_node(it.node);
-+ if (IS_ERR(mtd)) {
-+ of_node_put(it.node);
-+ err = -EPROBE_DEFER;
-+ goto err_remove;
-+ }
-+
-+ info->devices[info->num_devices++] = mtd;
-+ }
-+
-+ info->cmtd = mtd_concat_create(info->devices, info->num_devices,
-+ dev_name(&pdev->dev));
-+ if (!info->cmtd) {
-+ err = -ENXIO;
-+ goto err_remove;
-+ }
-+
-+ info->cmtd->dev.parent = &pdev->dev;
-+ mtd_set_of_node(info->cmtd, node);
-+ mtd_device_register(info->cmtd, NULL, 0);
-+
-+ return 0;
-+
-+err_remove:
-+ virt_concat_remove(pdev);
-+
-+ return err;
-+}
-+
-+static const struct of_device_id virt_concat_of_match[] = {
-+ { .compatible = "mtd-concat", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, virt_concat_of_match);
-+
-+static struct platform_driver virt_concat_driver = {
-+ .probe = virt_concat_probe,
-+ .remove = virt_concat_remove,
-+ .driver = {
-+ .name = "virt-mtdconcat",
-+ .of_match_table = virt_concat_of_match,
-+ },
-+};
-+
-+module_platform_driver(virt_concat_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Bernhard Frauendienst <kernel@nospam.obeliks.de>");
-+MODULE_DESCRIPTION("Virtual concat MTD device driver");
diff --git a/target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch b/target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch
deleted file mode 100644
index 81de764876..0000000000
--- a/target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 8bf2ce6ea4ee840b70f55a27f80e1cd308051b13 Mon Sep 17 00:00:00 2001
-From: Nick Hainke <vincent@systemli.org>
-Date: Mon, 27 Dec 2021 00:38:13 +0100
-Subject: [PATCH 1/2] mtd: spi-nor: locking support for MX25L6405D
-
-Macronix MX25L6405D supports locking with four block-protection bits.
-Currently, the driver only sets three bits. If the bootloader does not
-sustain the flash chip in an unlocked state, the flash might be
-non-writeable. Add the corresponding flag to enable locking support with
-four bits in the status register.
-
-Tested on Nanostation M2 XM.
-
-Similar to commit 7ea40b54e83b ("mtd: spi-nor: enable locking support for
-MX25L12805D")
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Nick Hainke <vincent@systemli.org>
----
- drivers/mtd/spi-nor/macronix.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/spi-nor/macronix.c
-+++ b/drivers/mtd/spi-nor/macronix.c
-@@ -41,7 +41,8 @@ static const struct flash_info macronix_
- { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) },
- { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) },
- { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
-- { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
-+ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) },
- { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) },
- { "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64,
- SECT_4K | SPI_NOR_DUAL_READ |
diff --git a/target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch b/target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch
deleted file mode 100644
index ec14f6341c..0000000000
--- a/target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 245224608b5368c10407da07557e546743d3c489 Mon Sep 17 00:00:00 2001
-From: Nick Hainke <vincent@systemli.org>
-Date: Mon, 27 Dec 2021 09:33:13 +0100
-Subject: [PATCH 2/2] mtd: spi-nor: disable 16-bit-sr for macronix
-
-Macronix flash chips seem to consist of only one status register.
-These chips will not work with the "16-bit Write Status (01h) Command".
-Disable SNOR_F_HAS_16BIT_SR for all Macronix chips.
-
-Tested with MX25L6405D.
-
-Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on
-lock()/unlock()")
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Nick Hainke <vincent@systemli.org>
----
- drivers/mtd/spi-nor/macronix.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/macronix.c
-+++ b/drivers/mtd/spi-nor/macronix.c
-@@ -94,6 +94,7 @@ static void macronix_default_init(struct
- {
- nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
- nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
-+ nor->flags &= ~SNOR_F_HAS_16BIT_SR;
- nor->flags |= SNOR_F_HAS_LOCK;
- }
-
diff --git a/target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch b/target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch
deleted file mode 100644
index 2053c0fbe2..0000000000
--- a/target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From af7b91bcecce0eae24e90acd35d96ecee73e1407 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:21:15 +0200
-Subject: [PATCH] fs: add cdrom dependency
-
----
- fs/hfs/Kconfig | 1 +
- fs/hfsplus/Kconfig | 1 +
- fs/isofs/Kconfig | 1 +
- fs/udf/Kconfig | 1 +
- 4 files changed, 4 insertions(+)
-
---- a/fs/hfs/Kconfig
-+++ b/fs/hfs/Kconfig
-@@ -2,6 +2,7 @@
- config HFS_FS
- tristate "Apple Macintosh file system support"
- depends on BLOCK
-+ select CDROM
- select NLS
- help
- If you say Y here, you will be able to mount Macintosh-formatted
---- a/fs/hfsplus/Kconfig
-+++ b/fs/hfsplus/Kconfig
-@@ -2,6 +2,7 @@
- config HFSPLUS_FS
- tristate "Apple Extended HFS file system support"
- depends on BLOCK
-+ select CDROM
- select NLS
- select NLS_UTF8
- help
---- a/fs/isofs/Kconfig
-+++ b/fs/isofs/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- config ISO9660_FS
- tristate "ISO 9660 CDROM file system support"
-+ select CDROM
- help
- This is the standard file system used on CD-ROMs. It was previously
- known as "High Sierra File System" and is called "hsfs" on other
---- a/fs/udf/Kconfig
-+++ b/fs/udf/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- config UDF_FS
- tristate "UDF file system support"
-+ select CDROM
- select CRC_ITU_T
- select NLS
- help
diff --git a/target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch
deleted file mode 100644
index f236657b71..0000000000
--- a/target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch
+++ /dev/null
@@ -1,4581 +0,0 @@
-From: Alexandros C. Couloumbis <alex@ozo.com>
-Subject: fs: add jffs2/lzma support (not activated by default yet)
-
-lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2
-Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
----
- fs/jffs2/Kconfig | 9 +
- fs/jffs2/Makefile | 3 +
- fs/jffs2/compr.c | 6 +
- fs/jffs2/compr.h | 10 +-
- fs/jffs2/compr_lzma.c | 128 +++
- fs/jffs2/super.c | 33 +-
- include/linux/lzma.h | 62 ++
- include/linux/lzma/LzFind.h | 115 +++
- include/linux/lzma/LzHash.h | 54 +
- include/linux/lzma/LzmaDec.h | 231 +++++
- include/linux/lzma/LzmaEnc.h | 80 ++
- include/linux/lzma/Types.h | 226 +++++
- include/uapi/linux/jffs2.h | 1 +
- lib/Kconfig | 6 +
- lib/Makefile | 12 +
- lib/lzma/LzFind.c | 761 ++++++++++++++
- lib/lzma/LzmaDec.c | 999 +++++++++++++++++++
- lib/lzma/LzmaEnc.c | 2271 ++++++++++++++++++++++++++++++++++++++++++
- lib/lzma/Makefile | 7 +
- 19 files changed, 5008 insertions(+), 6 deletions(-)
- create mode 100644 fs/jffs2/compr_lzma.c
- create mode 100644 include/linux/lzma.h
- create mode 100644 include/linux/lzma/LzFind.h
- create mode 100644 include/linux/lzma/LzHash.h
- create mode 100644 include/linux/lzma/LzmaDec.h
- create mode 100644 include/linux/lzma/LzmaEnc.h
- create mode 100644 include/linux/lzma/Types.h
- create mode 100644 lib/lzma/LzFind.c
- create mode 100644 lib/lzma/LzmaDec.c
- create mode 100644 lib/lzma/LzmaEnc.c
- create mode 100644 lib/lzma/Makefile
-
---- a/fs/jffs2/Kconfig
-+++ b/fs/jffs2/Kconfig
-@@ -136,6 +136,15 @@ config JFFS2_LZO
- This feature was added in July, 2007. Say 'N' if you need
- compatibility with older bootloaders or kernels.
-
-+config JFFS2_LZMA
-+ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS
-+ select LZMA_COMPRESS
-+ select LZMA_DECOMPRESS
-+ depends on JFFS2_FS
-+ default n
-+ help
-+ JFFS2 wrapper to the LZMA C SDK
-+
- config JFFS2_RTIME
- bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
- depends on JFFS2_FS
---- a/fs/jffs2/Makefile
-+++ b/fs/jffs2/Makefile
-@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub
- jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
- jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
- jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o
-+jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o
- jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o
-+
-+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma
---- a/fs/jffs2/compr.c
-+++ b/fs/jffs2/compr.c
-@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void)
- #ifdef CONFIG_JFFS2_LZO
- jffs2_lzo_init();
- #endif
-+#ifdef CONFIG_JFFS2_LZMA
-+ jffs2_lzma_init();
-+#endif
- /* Setting default compression mode */
- #ifdef CONFIG_JFFS2_CMODE_NONE
- jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
-@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void)
- int jffs2_compressors_exit(void)
- {
- /* Unregistering compressors */
-+#ifdef CONFIG_JFFS2_LZMA
-+ jffs2_lzma_exit();
-+#endif
- #ifdef CONFIG_JFFS2_LZO
- jffs2_lzo_exit();
- #endif
---- a/fs/jffs2/compr.h
-+++ b/fs/jffs2/compr.h
-@@ -29,9 +29,9 @@
- #define JFFS2_DYNRUBIN_PRIORITY 20
- #define JFFS2_LZARI_PRIORITY 30
- #define JFFS2_RTIME_PRIORITY 50
--#define JFFS2_ZLIB_PRIORITY 60
--#define JFFS2_LZO_PRIORITY 80
--
-+#define JFFS2_LZMA_PRIORITY 70
-+#define JFFS2_ZLIB_PRIORITY 80
-+#define JFFS2_LZO_PRIORITY 90
-
- #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
- #define JFFS2_DYNRUBIN_DISABLED /* for decompression */
-@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void);
- int jffs2_lzo_init(void);
- void jffs2_lzo_exit(void);
- #endif
-+#ifdef CONFIG_JFFS2_LZMA
-+int jffs2_lzma_init(void);
-+void jffs2_lzma_exit(void);
-+#endif
-
- #endif /* __JFFS2_COMPR_H__ */
---- /dev/null
-+++ b/fs/jffs2/compr_lzma.c
-@@ -0,0 +1,128 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * JFFS2 wrapper to the LZMA C SDK
-+ *
-+ */
-+
-+#include <linux/lzma.h>
-+#include "compr.h"
-+
-+#ifdef __KERNEL__
-+ static DEFINE_MUTEX(deflate_mutex);
-+#endif
-+
-+CLzmaEncHandle *p;
-+Byte propsEncoded[LZMA_PROPS_SIZE];
-+SizeT propsSize = sizeof(propsEncoded);
-+
-+STATIC void lzma_free_workspace(void)
-+{
-+ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc);
-+}
-+
-+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props)
-+{
-+ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL)
-+ {
-+ PRINT_ERROR("Failed to allocate lzma deflate workspace\n");
-+ return -ENOMEM;
-+ }
-+
-+ if (LzmaEnc_SetProps(p, props) != SZ_OK)
-+ {
-+ lzma_free_workspace();
-+ return -1;
-+ }
-+
-+ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK)
-+ {
-+ lzma_free_workspace();
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
-+{
-+ SizeT compress_size = (SizeT)(*dstlen);
-+ int ret;
-+
-+ #ifdef __KERNEL__
-+ mutex_lock(&deflate_mutex);
-+ #endif
-+
-+ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen,
-+ 0, NULL, &lzma_alloc, &lzma_alloc);
-+
-+ #ifdef __KERNEL__
-+ mutex_unlock(&deflate_mutex);
-+ #endif
-+
-+ if (ret != SZ_OK)
-+ return -1;
-+
-+ *dstlen = (uint32_t)compress_size;
-+
-+ return 0;
-+}
-+
-+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t srclen, uint32_t destlen)
-+{
-+ int ret;
-+ SizeT dl = (SizeT)destlen;
-+ SizeT sl = (SizeT)srclen;
-+ ELzmaStatus status;
-+
-+ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded,
-+ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc);
-+
-+ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen)
-+ return -1;
-+
-+ return 0;
-+}
-+
-+static struct jffs2_compressor jffs2_lzma_comp = {
-+ .priority = JFFS2_LZMA_PRIORITY,
-+ .name = "lzma",
-+ .compr = JFFS2_COMPR_LZMA,
-+ .compress = &jffs2_lzma_compress,
-+ .decompress = &jffs2_lzma_decompress,
-+ .disabled = 0,
-+};
-+
-+int INIT jffs2_lzma_init(void)
-+{
-+ int ret;
-+ CLzmaEncProps props;
-+ LzmaEncProps_Init(&props);
-+
-+ props.dictSize = LZMA_BEST_DICT(0x2000);
-+ props.level = LZMA_BEST_LEVEL;
-+ props.lc = LZMA_BEST_LC;
-+ props.lp = LZMA_BEST_LP;
-+ props.pb = LZMA_BEST_PB;
-+ props.fb = LZMA_BEST_FB;
-+
-+ ret = lzma_alloc_workspace(&props);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = jffs2_register_compressor(&jffs2_lzma_comp);
-+ if (ret)
-+ lzma_free_workspace();
-+
-+ return ret;
-+}
-+
-+void jffs2_lzma_exit(void)
-+{
-+ jffs2_unregister_compressor(&jffs2_lzma_comp);
-+ lzma_free_workspace();
-+}
---- a/fs/jffs2/super.c
-+++ b/fs/jffs2/super.c
-@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void)
- BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
- BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
-
-- pr_info("version 2.2."
-+ pr_info("version 2.2"
- #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
- " (NAND)"
- #endif
- #ifdef CONFIG_JFFS2_SUMMARY
-- " (SUMMARY) "
-+ " (SUMMARY)"
- #endif
-- " © 2001-2006 Red Hat, Inc.\n");
-+#ifdef CONFIG_JFFS2_ZLIB
-+ " (ZLIB)"
-+#endif
-+#ifdef CONFIG_JFFS2_LZO
-+ " (LZO)"
-+#endif
-+#ifdef CONFIG_JFFS2_LZMA
-+ " (LZMA)"
-+#endif
-+#ifdef CONFIG_JFFS2_RTIME
-+ " (RTIME)"
-+#endif
-+#ifdef CONFIG_JFFS2_RUBIN
-+ " (RUBIN)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_NONE
-+ " (CMODE_NONE)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_PRIORITY
-+ " (CMODE_PRIORITY)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_SIZE
-+ " (CMODE_SIZE)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO
-+ " (CMODE_FAVOURLZO)"
-+#endif
-+ " (c) 2001-2006 Red Hat, Inc.\n");
-
- jffs2_inode_cachep = kmem_cache_create("jffs2_i",
- sizeof(struct jffs2_inode_info),
---- /dev/null
-+++ b/include/linux/lzma.h
-@@ -0,0 +1,62 @@
-+#ifndef __LZMA_H__
-+#define __LZMA_H__
-+
-+#ifdef __KERNEL__
-+ #include <linux/kernel.h>
-+ #include <linux/sched.h>
-+ #include <linux/slab.h>
-+ #include <linux/vmalloc.h>
-+ #include <linux/init.h>
-+ #define LZMA_MALLOC vmalloc
-+ #define LZMA_FREE vfree
-+ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg)
-+ #define INIT __init
-+ #define STATIC static
-+#else
-+ #include <stdint.h>
-+ #include <stdlib.h>
-+ #include <stdio.h>
-+ #include <unistd.h>
-+ #include <string.h>
-+ #include <asm/types.h>
-+ #include <errno.h>
-+ #include <linux/jffs2.h>
-+ #ifndef PAGE_SIZE
-+ extern int page_size;
-+ #define PAGE_SIZE page_size
-+ #endif
-+ #define LZMA_MALLOC malloc
-+ #define LZMA_FREE free
-+ #define PRINT_ERROR(msg) fprintf(stderr, msg)
-+ #define INIT
-+ #define STATIC
-+#endif
-+
-+#include "lzma/LzmaDec.h"
-+#include "lzma/LzmaEnc.h"
-+
-+#define LZMA_BEST_LEVEL (9)
-+#define LZMA_BEST_LC (0)
-+#define LZMA_BEST_LP (0)
-+#define LZMA_BEST_PB (0)
-+#define LZMA_BEST_FB (273)
-+
-+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2)
-+
-+static void *p_lzma_malloc(void *p, size_t size)
-+{
-+ if (size == 0)
-+ return NULL;
-+
-+ return LZMA_MALLOC(size);
-+}
-+
-+static void p_lzma_free(void *p, void *address)
-+{
-+ if (address != NULL)
-+ LZMA_FREE(address);
-+}
-+
-+static ISzAlloc lzma_alloc = { .Alloc = p_lzma_malloc, .Free = p_lzma_free };
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzFind.h
-@@ -0,0 +1,98 @@
-+/* LzFind.h -- Match finder for LZ algorithms
-+2009-04-22 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZ_FIND_H
-+#define __LZ_FIND_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef UInt32 CLzRef;
-+
-+typedef struct _CMatchFinder
-+{
-+ Byte *buffer;
-+ UInt32 pos;
-+ UInt32 posLimit;
-+ UInt32 streamPos;
-+ UInt32 lenLimit;
-+
-+ UInt32 cyclicBufferPos;
-+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
-+
-+ UInt32 matchMaxLen;
-+ CLzRef *hash;
-+ CLzRef *son;
-+ UInt32 hashMask;
-+ UInt32 cutValue;
-+
-+ Byte *bufferBase;
-+ ISeqInStream *stream;
-+ int streamEndWasReached;
-+
-+ UInt32 blockSize;
-+ UInt32 keepSizeBefore;
-+ UInt32 keepSizeAfter;
-+
-+ UInt32 numHashBytes;
-+ int directInput;
-+ size_t directInputRem;
-+ int btMode;
-+ int bigHash;
-+ UInt32 historySize;
-+ UInt32 fixedHashSize;
-+ UInt32 hashSizeSum;
-+ UInt32 numSons;
-+ SRes result;
-+ UInt32 crc[256];
-+} CMatchFinder;
-+
-+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
-+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
-+
-+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
-+
-+void MatchFinder_Construct(CMatchFinder *p);
-+
-+/* Conditions:
-+ historySize <= 3 GB
-+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
-+*/
-+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-+ ISzAlloc *alloc);
-+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-+
-+/*
-+Conditions:
-+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
-+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
-+*/
-+
-+typedef void (*Mf_Init_Func)(void *object);
-+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
-+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
-+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
-+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
-+typedef void (*Mf_Skip_Func)(void *object, UInt32);
-+
-+typedef struct _IMatchFinder
-+{
-+ Mf_Init_Func Init;
-+ Mf_GetIndexByte_Func GetIndexByte;
-+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
-+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
-+ Mf_GetMatches_Func GetMatches;
-+ Mf_Skip_Func Skip;
-+} IMatchFinder;
-+
-+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzHash.h
-@@ -0,0 +1,54 @@
-+/* LzHash.h -- HASH functions for LZ algorithms
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZ_HASH_H
-+#define __LZ_HASH_H
-+
-+#define kHash2Size (1 << 10)
-+#define kHash3Size (1 << 16)
-+#define kHash4Size (1 << 20)
-+
-+#define kFix3HashSize (kHash2Size)
-+#define kFix4HashSize (kHash2Size + kHash3Size)
-+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
-+
-+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
-+
-+#define HASH3_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
-+
-+#define HASH4_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
-+
-+#define HASH5_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
-+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
-+ hash4Value &= (kHash4Size - 1); }
-+
-+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
-+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
-+
-+
-+#define MT_HASH2_CALC \
-+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
-+
-+#define MT_HASH3_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
-+
-+#define MT_HASH4_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzmaDec.h
-@@ -0,0 +1,130 @@
-+/* LzmaDec.h -- LZMA Decoder
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZMA_DEC_H
-+#define __LZMA_DEC_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* #define _LZMA_PROB32 */
-+/* _LZMA_PROB32 can increase the speed on some CPUs,
-+ but memory usage for CLzmaDec::probs will be doubled in that case */
-+
-+#ifdef _LZMA_PROB32
-+#define CLzmaProb UInt32
-+#else
-+#define CLzmaProb UInt16
-+#endif
-+
-+
-+/* ---------- LZMA Properties ---------- */
-+
-+#define LZMA_PROPS_SIZE 5
-+
-+typedef struct _CLzmaProps
-+{
-+ unsigned lc, lp, pb;
-+ UInt32 dicSize;
-+} CLzmaProps;
-+
-+
-+/* ---------- LZMA Decoder state ---------- */
-+
-+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
-+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
-+
-+#define LZMA_REQUIRED_INPUT_MAX 20
-+
-+typedef struct
-+{
-+ CLzmaProps prop;
-+ CLzmaProb *probs;
-+ Byte *dic;
-+ const Byte *buf;
-+ UInt32 range, code;
-+ SizeT dicPos;
-+ SizeT dicBufSize;
-+ UInt32 processedPos;
-+ UInt32 checkDicSize;
-+ unsigned state;
-+ UInt32 reps[4];
-+ unsigned remainLen;
-+ int needFlush;
-+ int needInitState;
-+ UInt32 numProbs;
-+ unsigned tempBufSize;
-+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
-+} CLzmaDec;
-+
-+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
-+
-+/* There are two types of LZMA streams:
-+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
-+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
-+
-+typedef enum
-+{
-+ LZMA_FINISH_ANY, /* finish at any point */
-+ LZMA_FINISH_END /* block must be finished at the end */
-+} ELzmaFinishMode;
-+
-+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
-+
-+ You must use LZMA_FINISH_END, when you know that current output buffer
-+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
-+
-+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
-+ and output value of destLen will be less than output buffer size limit.
-+ You can check status result also.
-+
-+ You can use multiple checks to test data integrity after full decompression:
-+ 1) Check Result and "status" variable.
-+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
-+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
-+ You must use correct finish mode in that case. */
-+
-+typedef enum
-+{
-+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
-+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
-+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
-+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
-+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
-+} ELzmaStatus;
-+
-+/* ELzmaStatus is used only as output value for function call */
-+
-+/* ---------- One Call Interface ---------- */
-+
-+/* LzmaDecode
-+
-+finishMode:
-+ It has meaning only if the decoding reaches output limit (*destLen).
-+ LZMA_FINISH_ANY - Decode just destLen bytes.
-+ LZMA_FINISH_END - Stream must be finished after (*destLen).
-+
-+Returns:
-+ SZ_OK
-+ status:
-+ LZMA_STATUS_FINISHED_WITH_MARK
-+ LZMA_STATUS_NOT_FINISHED
-+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
-+ SZ_ERROR_DATA - Data error
-+ SZ_ERROR_MEM - Memory allocation error
-+ SZ_ERROR_UNSUPPORTED - Unsupported properties
-+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-+*/
-+
-+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-+ ELzmaStatus *status, ISzAlloc *alloc);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzmaEnc.h
-@@ -0,0 +1,60 @@
-+/* LzmaEnc.h -- LZMA Encoder
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZMA_ENC_H
-+#define __LZMA_ENC_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define LZMA_PROPS_SIZE 5
-+
-+typedef struct _CLzmaEncProps
-+{
-+ int level; /* 0 <= level <= 9 */
-+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
-+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
-+ default = (1 << 24) */
-+ int lc; /* 0 <= lc <= 8, default = 3 */
-+ int lp; /* 0 <= lp <= 4, default = 0 */
-+ int pb; /* 0 <= pb <= 4, default = 2 */
-+ int algo; /* 0 - fast, 1 - normal, default = 1 */
-+ int fb; /* 5 <= fb <= 273, default = 32 */
-+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
-+ int numHashBytes; /* 2, 3 or 4, default = 4 */
-+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
-+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
-+ int numThreads; /* 1 or 2, default = 2 */
-+} CLzmaEncProps;
-+
-+void LzmaEncProps_Init(CLzmaEncProps *p);
-+
-+/* ---------- CLzmaEncHandle Interface ---------- */
-+
-+/* LzmaEnc_* functions can return the following exit codes:
-+Returns:
-+ SZ_OK - OK
-+ SZ_ERROR_MEM - Memory allocation error
-+ SZ_ERROR_PARAM - Incorrect paramater in props
-+ SZ_ERROR_WRITE - Write callback error.
-+ SZ_ERROR_PROGRESS - some break from progress callback
-+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-+*/
-+
-+typedef void * CLzmaEncHandle;
-+
-+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
-+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
-+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
-+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
-+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/Types.h
-@@ -0,0 +1,226 @@
-+/* Types.h -- Basic types
-+2009-11-23 : Igor Pavlov : Public domain */
-+
-+#ifndef __7Z_TYPES_H
-+#define __7Z_TYPES_H
-+
-+#include <stddef.h>
-+
-+#ifdef _WIN32
-+#include <windows.h>
-+#endif
-+
-+#ifndef EXTERN_C_BEGIN
-+#ifdef __cplusplus
-+#define EXTERN_C_BEGIN extern "C" {
-+#define EXTERN_C_END }
-+#else
-+#define EXTERN_C_BEGIN
-+#define EXTERN_C_END
-+#endif
-+#endif
-+
-+EXTERN_C_BEGIN
-+
-+#define SZ_OK 0
-+
-+#define SZ_ERROR_DATA 1
-+#define SZ_ERROR_MEM 2
-+#define SZ_ERROR_CRC 3
-+#define SZ_ERROR_UNSUPPORTED 4
-+#define SZ_ERROR_PARAM 5
-+#define SZ_ERROR_INPUT_EOF 6
-+#define SZ_ERROR_OUTPUT_EOF 7
-+#define SZ_ERROR_READ 8
-+#define SZ_ERROR_WRITE 9
-+#define SZ_ERROR_PROGRESS 10
-+#define SZ_ERROR_FAIL 11
-+#define SZ_ERROR_THREAD 12
-+
-+#define SZ_ERROR_ARCHIVE 16
-+#define SZ_ERROR_NO_ARCHIVE 17
-+
-+typedef int SRes;
-+
-+#ifdef _WIN32
-+typedef DWORD WRes;
-+#else
-+typedef int WRes;
-+#endif
-+
-+#ifndef RINOK
-+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
-+#endif
-+
-+typedef unsigned char Byte;
-+typedef short Int16;
-+typedef unsigned short UInt16;
-+
-+#ifdef _LZMA_UINT32_IS_ULONG
-+typedef long Int32;
-+typedef unsigned long UInt32;
-+#else
-+typedef int Int32;
-+typedef unsigned int UInt32;
-+#endif
-+
-+#ifdef _SZ_NO_INT_64
-+
-+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
-+ NOTES: Some code will work incorrectly in that case! */
-+
-+typedef long Int64;
-+typedef unsigned long UInt64;
-+
-+#else
-+
-+#if defined(_MSC_VER) || defined(__BORLANDC__)
-+typedef __int64 Int64;
-+typedef unsigned __int64 UInt64;
-+#else
-+typedef long long int Int64;
-+typedef unsigned long long int UInt64;
-+#endif
-+
-+#endif
-+
-+#ifdef _LZMA_NO_SYSTEM_SIZE_T
-+typedef UInt32 SizeT;
-+#else
-+typedef size_t SizeT;
-+#endif
-+
-+typedef int Bool;
-+#define True 1
-+#define False 0
-+
-+
-+#ifdef _WIN32
-+#define MY_STD_CALL __stdcall
-+#else
-+#define MY_STD_CALL
-+#endif
-+
-+#ifdef _MSC_VER
-+
-+#if _MSC_VER >= 1300
-+#define MY_NO_INLINE __declspec(noinline)
-+#else
-+#define MY_NO_INLINE
-+#endif
-+
-+#define MY_CDECL __cdecl
-+#define MY_FAST_CALL __fastcall
-+
-+#else
-+
-+#define MY_CDECL
-+#define MY_FAST_CALL
-+
-+#endif
-+
-+
-+/* The following interfaces use first parameter as pointer to structure */
-+
-+typedef struct
-+{
-+ SRes (*Read)(void *p, void *buf, size_t *size);
-+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
-+ (output(*size) < input(*size)) is allowed */
-+} ISeqInStream;
-+
-+/* it can return SZ_ERROR_INPUT_EOF */
-+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
-+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
-+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
-+
-+typedef struct
-+{
-+ size_t (*Write)(void *p, const void *buf, size_t size);
-+ /* Returns: result - the number of actually written bytes.
-+ (result < size) means error */
-+} ISeqOutStream;
-+
-+typedef enum
-+{
-+ SZ_SEEK_SET = 0,
-+ SZ_SEEK_CUR = 1,
-+ SZ_SEEK_END = 2
-+} ESzSeek;
-+
-+typedef struct
-+{
-+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
-+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-+} ISeekInStream;
-+
-+typedef struct
-+{
-+ SRes (*Look)(void *p, void **buf, size_t *size);
-+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
-+ (output(*size) > input(*size)) is not allowed
-+ (output(*size) < input(*size)) is allowed */
-+ SRes (*Skip)(void *p, size_t offset);
-+ /* offset must be <= output(*size) of Look */
-+
-+ SRes (*Read)(void *p, void *buf, size_t *size);
-+ /* reads directly (without buffer). It's same as ISeqInStream::Read */
-+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-+} ILookInStream;
-+
-+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
-+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
-+
-+/* reads via ILookInStream::Read */
-+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
-+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
-+
-+#define LookToRead_BUF_SIZE (1 << 14)
-+
-+typedef struct
-+{
-+ ILookInStream s;
-+ ISeekInStream *realStream;
-+ size_t pos;
-+ size_t size;
-+ Byte buf[LookToRead_BUF_SIZE];
-+} CLookToRead;
-+
-+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
-+void LookToRead_Init(CLookToRead *p);
-+
-+typedef struct
-+{
-+ ISeqInStream s;
-+ ILookInStream *realStream;
-+} CSecToLook;
-+
-+void SecToLook_CreateVTable(CSecToLook *p);
-+
-+typedef struct
-+{
-+ ISeqInStream s;
-+ ILookInStream *realStream;
-+} CSecToRead;
-+
-+void SecToRead_CreateVTable(CSecToRead *p);
-+
-+typedef struct
-+{
-+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
-+ /* Returns: result. (result != SZ_OK) means break.
-+ Value (UInt64)(Int64)-1 for size means unknown value. */
-+} ICompressProgress;
-+
-+typedef struct
-+{
-+ void *(*Alloc)(void *p, size_t size);
-+ void (*Free)(void *p, void *address); /* address can be 0 */
-+} ISzAlloc;
-+
-+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-+#define IAlloc_Free(p, a) (p)->Free((p), a)
-+
-+EXTERN_C_END
-+
-+#endif
---- a/include/uapi/linux/jffs2.h
-+++ b/include/uapi/linux/jffs2.h
-@@ -46,6 +46,7 @@
- #define JFFS2_COMPR_DYNRUBIN 0x05
- #define JFFS2_COMPR_ZLIB 0x06
- #define JFFS2_COMPR_LZO 0x07
-+#define JFFS2_COMPR_LZMA 0x08
- /* Compatibility flags. */
- #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
- #define JFFS2_NODE_ACCURATE 0x2000
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -340,6 +340,12 @@ config ZSTD_DECOMPRESS
-
- source "lib/xz/Kconfig"
-
-+config LZMA_COMPRESS
-+ tristate
-+
-+config LZMA_DECOMPRESS
-+ tristate
-+
- #
- # These all provide a common interface (hence the apparent duplication with
- # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -135,6 +135,16 @@ CFLAGS_kobject.o += -DDEBUG
- CFLAGS_kobject_uevent.o += -DDEBUG
- endif
-
-+ifdef CONFIG_JFFS2_ZLIB
-+ CONFIG_ZLIB_INFLATE:=y
-+ CONFIG_ZLIB_DEFLATE:=y
-+endif
-+
-+ifdef CONFIG_JFFS2_LZMA
-+ CONFIG_LZMA_DECOMPRESS:=y
-+ CONFIG_LZMA_COMPRESS:=y
-+endif
-+
- obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o
- CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any)
-
-@@ -192,6 +202,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/
- obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/
- obj-$(CONFIG_XZ_DEC) += xz/
- obj-$(CONFIG_RAID6_PQ) += raid6/
-+obj-$(CONFIG_LZMA_COMPRESS) += lzma/
-+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/
-
- lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
- lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
---- /dev/null
-+++ b/lib/lzma/LzFind.c
-@@ -0,0 +1,522 @@
-+/* LzFind.c -- Match finder for LZ algorithms
-+2009-04-22 : Igor Pavlov : Public domain */
-+
-+#include <string.h>
-+
-+#include "LzFind.h"
-+#include "LzHash.h"
-+
-+#define kEmptyHashValue 0
-+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
-+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
-+#define kNormalizeMask (~(kNormalizeStepMin - 1))
-+#define kMaxHistorySize ((UInt32)3 << 30)
-+
-+#define kStartMaxLen 3
-+
-+#if 0
-+#define DIRECT_INPUT p->directInput
-+#else
-+#define DIRECT_INPUT 1
-+#endif
-+
-+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+ if (!DIRECT_INPUT)
-+ {
-+ alloc->Free(alloc, p->bufferBase);
-+ p->bufferBase = 0;
-+ }
-+}
-+
-+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
-+
-+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
-+{
-+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
-+ if (DIRECT_INPUT)
-+ {
-+ p->blockSize = blockSize;
-+ return 1;
-+ }
-+ if (p->bufferBase == 0 || p->blockSize != blockSize)
-+ {
-+ LzInWindow_Free(p, alloc);
-+ p->blockSize = blockSize;
-+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
-+ }
-+ return (p->bufferBase != 0);
-+}
-+
-+static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
-+
-+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
-+
-+static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
-+{
-+ p->posLimit -= subValue;
-+ p->pos -= subValue;
-+ p->streamPos -= subValue;
-+}
-+
-+static void MatchFinder_ReadBlock(CMatchFinder *p)
-+{
-+ if (p->streamEndWasReached || p->result != SZ_OK)
-+ return;
-+ if (DIRECT_INPUT)
-+ {
-+ UInt32 curSize = 0xFFFFFFFF - p->streamPos;
-+ if (curSize > p->directInputRem)
-+ curSize = (UInt32)p->directInputRem;
-+ p->directInputRem -= curSize;
-+ p->streamPos += curSize;
-+ if (p->directInputRem == 0)
-+ p->streamEndWasReached = 1;
-+ return;
-+ }
-+ for (;;)
-+ {
-+ Byte *dest = p->buffer + (p->streamPos - p->pos);
-+ size_t size = (p->bufferBase + p->blockSize - dest);
-+ if (size == 0)
-+ return;
-+ p->result = p->stream->Read(p->stream, dest, &size);
-+ if (p->result != SZ_OK)
-+ return;
-+ if (size == 0)
-+ {
-+ p->streamEndWasReached = 1;
-+ return;
-+ }
-+ p->streamPos += (UInt32)size;
-+ if (p->streamPos - p->pos > p->keepSizeAfter)
-+ return;
-+ }
-+}
-+
-+static void MatchFinder_MoveBlock(CMatchFinder *p)
-+{
-+ memmove(p->bufferBase,
-+ p->buffer - p->keepSizeBefore,
-+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
-+ p->buffer = p->bufferBase + p->keepSizeBefore;
-+}
-+
-+static int MatchFinder_NeedMove(CMatchFinder *p)
-+{
-+ if (DIRECT_INPUT)
-+ return 0;
-+ /* if (p->streamEndWasReached) return 0; */
-+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
-+}
-+
-+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
-+{
-+ if (MatchFinder_NeedMove(p))
-+ MatchFinder_MoveBlock(p);
-+ MatchFinder_ReadBlock(p);
-+}
-+
-+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
-+{
-+ p->cutValue = 32;
-+ p->btMode = 1;
-+ p->numHashBytes = 4;
-+ p->bigHash = 0;
-+}
-+
-+#define kCrcPoly 0xEDB88320
-+
-+void MatchFinder_Construct(CMatchFinder *p)
-+{
-+ UInt32 i;
-+ p->bufferBase = 0;
-+ p->directInput = 0;
-+ p->hash = 0;
-+ MatchFinder_SetDefaultSettings(p);
-+
-+ for (i = 0; i < 256; i++)
-+ {
-+ UInt32 r = i;
-+ int j;
-+ for (j = 0; j < 8; j++)
-+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
-+ p->crc[i] = r;
-+ }
-+}
-+
-+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->hash);
-+ p->hash = 0;
-+}
-+
-+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+ MatchFinder_FreeThisClassMemory(p, alloc);
-+ LzInWindow_Free(p, alloc);
-+}
-+
-+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
-+{
-+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
-+ if (sizeInBytes / sizeof(CLzRef) != num)
-+ return 0;
-+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
-+}
-+
-+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-+ ISzAlloc *alloc)
-+{
-+ UInt32 sizeReserv;
-+ if (historySize > kMaxHistorySize)
-+ {
-+ MatchFinder_Free(p, alloc);
-+ return 0;
-+ }
-+ sizeReserv = historySize >> 1;
-+ if (historySize > ((UInt32)2 << 30))
-+ sizeReserv = historySize >> 2;
-+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
-+
-+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
-+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
-+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
-+ if (LzInWindow_Create(p, sizeReserv, alloc))
-+ {
-+ UInt32 newCyclicBufferSize = historySize + 1;
-+ UInt32 hs;
-+ p->matchMaxLen = matchMaxLen;
-+ {
-+ p->fixedHashSize = 0;
-+ if (p->numHashBytes == 2)
-+ hs = (1 << 16) - 1;
-+ else
-+ {
-+ hs = historySize - 1;
-+ hs |= (hs >> 1);
-+ hs |= (hs >> 2);
-+ hs |= (hs >> 4);
-+ hs |= (hs >> 8);
-+ hs >>= 1;
-+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
-+ if (hs > (1 << 24))
-+ {
-+ if (p->numHashBytes == 3)
-+ hs = (1 << 24) - 1;
-+ else
-+ hs >>= 1;
-+ }
-+ }
-+ p->hashMask = hs;
-+ hs++;
-+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
-+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
-+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
-+ hs += p->fixedHashSize;
-+ }
-+
-+ {
-+ UInt32 prevSize = p->hashSizeSum + p->numSons;
-+ UInt32 newSize;
-+ p->historySize = historySize;
-+ p->hashSizeSum = hs;
-+ p->cyclicBufferSize = newCyclicBufferSize;
-+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
-+ newSize = p->hashSizeSum + p->numSons;
-+ if (p->hash != 0 && prevSize == newSize)
-+ return 1;
-+ MatchFinder_FreeThisClassMemory(p, alloc);
-+ p->hash = AllocRefs(newSize, alloc);
-+ if (p->hash != 0)
-+ {
-+ p->son = p->hash + p->hashSizeSum;
-+ return 1;
-+ }
-+ }
-+ }
-+ MatchFinder_Free(p, alloc);
-+ return 0;
-+}
-+
-+static void MatchFinder_SetLimits(CMatchFinder *p)
-+{
-+ UInt32 limit = kMaxValForNormalize - p->pos;
-+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
-+ if (limit2 < limit)
-+ limit = limit2;
-+ limit2 = p->streamPos - p->pos;
-+ if (limit2 <= p->keepSizeAfter)
-+ {
-+ if (limit2 > 0)
-+ limit2 = 1;
-+ }
-+ else
-+ limit2 -= p->keepSizeAfter;
-+ if (limit2 < limit)
-+ limit = limit2;
-+ {
-+ UInt32 lenLimit = p->streamPos - p->pos;
-+ if (lenLimit > p->matchMaxLen)
-+ lenLimit = p->matchMaxLen;
-+ p->lenLimit = lenLimit;
-+ }
-+ p->posLimit = p->pos + limit;
-+}
-+
-+static void MatchFinder_Init(CMatchFinder *p)
-+{
-+ UInt32 i;
-+ for (i = 0; i < p->hashSizeSum; i++)
-+ p->hash[i] = kEmptyHashValue;
-+ p->cyclicBufferPos = 0;
-+ p->buffer = p->bufferBase;
-+ p->pos = p->streamPos = p->cyclicBufferSize;
-+ p->result = SZ_OK;
-+ p->streamEndWasReached = 0;
-+ MatchFinder_ReadBlock(p);
-+ MatchFinder_SetLimits(p);
-+}
-+
-+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
-+{
-+ return (p->pos - p->historySize - 1) & kNormalizeMask;
-+}
-+
-+static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
-+{
-+ UInt32 i;
-+ for (i = 0; i < numItems; i++)
-+ {
-+ UInt32 value = items[i];
-+ if (value <= subValue)
-+ value = kEmptyHashValue;
-+ else
-+ value -= subValue;
-+ items[i] = value;
-+ }
-+}
-+
-+static void MatchFinder_Normalize(CMatchFinder *p)
-+{
-+ UInt32 subValue = MatchFinder_GetSubValue(p);
-+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
-+ MatchFinder_ReduceOffsets(p, subValue);
-+}
-+
-+static void MatchFinder_CheckLimits(CMatchFinder *p)
-+{
-+ if (p->pos == kMaxValForNormalize)
-+ MatchFinder_Normalize(p);
-+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
-+ MatchFinder_CheckAndMoveAndRead(p);
-+ if (p->cyclicBufferPos == p->cyclicBufferSize)
-+ p->cyclicBufferPos = 0;
-+ MatchFinder_SetLimits(p);
-+}
-+
-+static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-+ UInt32 *distances, UInt32 maxLen)
-+{
-+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-+ UInt32 len0 = 0, len1 = 0;
-+ for (;;)
-+ {
-+ UInt32 delta = pos - curMatch;
-+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+ {
-+ *ptr0 = *ptr1 = kEmptyHashValue;
-+ return distances;
-+ }
-+ {
-+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-+ const Byte *pb = cur - delta;
-+ UInt32 len = (len0 < len1 ? len0 : len1);
-+ if (pb[len] == cur[len])
-+ {
-+ if (++len != lenLimit && pb[len] == cur[len])
-+ while (++len != lenLimit)
-+ if (pb[len] != cur[len])
-+ break;
-+ if (maxLen < len)
-+ {
-+ *distances++ = maxLen = len;
-+ *distances++ = delta - 1;
-+ if (len == lenLimit)
-+ {
-+ *ptr1 = pair[0];
-+ *ptr0 = pair[1];
-+ return distances;
-+ }
-+ }
-+ }
-+ if (pb[len] < cur[len])
-+ {
-+ *ptr1 = curMatch;
-+ ptr1 = pair + 1;
-+ curMatch = *ptr1;
-+ len1 = len;
-+ }
-+ else
-+ {
-+ *ptr0 = curMatch;
-+ ptr0 = pair;
-+ curMatch = *ptr0;
-+ len0 = len;
-+ }
-+ }
-+ }
-+}
-+
-+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
-+{
-+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-+ UInt32 len0 = 0, len1 = 0;
-+ for (;;)
-+ {
-+ UInt32 delta = pos - curMatch;
-+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+ {
-+ *ptr0 = *ptr1 = kEmptyHashValue;
-+ return;
-+ }
-+ {
-+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-+ const Byte *pb = cur - delta;
-+ UInt32 len = (len0 < len1 ? len0 : len1);
-+ if (pb[len] == cur[len])
-+ {
-+ while (++len != lenLimit)
-+ if (pb[len] != cur[len])
-+ break;
-+ {
-+ if (len == lenLimit)
-+ {
-+ *ptr1 = pair[0];
-+ *ptr0 = pair[1];
-+ return;
-+ }
-+ }
-+ }
-+ if (pb[len] < cur[len])
-+ {
-+ *ptr1 = curMatch;
-+ ptr1 = pair + 1;
-+ curMatch = *ptr1;
-+ len1 = len;
-+ }
-+ else
-+ {
-+ *ptr0 = curMatch;
-+ ptr0 = pair;
-+ curMatch = *ptr0;
-+ len0 = len;
-+ }
-+ }
-+ }
-+}
-+
-+#define MOVE_POS \
-+ ++p->cyclicBufferPos; \
-+ p->buffer++; \
-+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
-+
-+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
-+
-+#define MOVE_POS_RET MatchFinder_MovePos(p); return offset;
-+
-+#define GET_MATCHES_HEADER2(minLen, ret_op) \
-+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
-+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
-+ cur = p->buffer;
-+
-+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
-+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
-+
-+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
-+
-+#define GET_MATCHES_FOOTER(offset, maxLen) \
-+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
-+ distances + offset, maxLen) - distances); MOVE_POS_RET;
-+
-+#define SKIP_FOOTER \
-+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MatchFinder_MovePos(p);
-+
-+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
-+ GET_MATCHES_HEADER(4)
-+
-+ HASH4_CALC;
-+
-+ delta2 = p->pos - p->hash[ hash2Value];
-+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
-+ curMatch = p->hash[kFix4HashSize + hashValue];
-+
-+ p->hash[ hash2Value] =
-+ p->hash[kFix3HashSize + hash3Value] =
-+ p->hash[kFix4HashSize + hashValue] = p->pos;
-+
-+ maxLen = 1;
-+ offset = 0;
-+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-+ {
-+ distances[0] = maxLen = 2;
-+ distances[1] = delta2 - 1;
-+ offset = 2;
-+ }
-+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
-+ {
-+ maxLen = 3;
-+ distances[offset + 1] = delta3 - 1;
-+ offset += 2;
-+ delta2 = delta3;
-+ }
-+ if (offset != 0)
-+ {
-+ for (; maxLen != lenLimit; maxLen++)
-+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-+ break;
-+ distances[offset - 2] = maxLen;
-+ if (maxLen == lenLimit)
-+ {
-+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
-+ MOVE_POS_RET;
-+ }
-+ }
-+ if (maxLen < 3)
-+ maxLen = 3;
-+ GET_MATCHES_FOOTER(offset, maxLen)
-+}
-+
-+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+ do
-+ {
-+ UInt32 hash2Value, hash3Value;
-+ SKIP_HEADER(4)
-+ HASH4_CALC;
-+ curMatch = p->hash[kFix4HashSize + hashValue];
-+ p->hash[ hash2Value] =
-+ p->hash[kFix3HashSize + hash3Value] = p->pos;
-+ p->hash[kFix4HashSize + hashValue] = p->pos;
-+ SKIP_FOOTER
-+ }
-+ while (--num != 0);
-+}
-+
-+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
-+{
-+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
-+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
-+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
-+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
-+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
-+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
-+}
---- /dev/null
-+++ b/lib/lzma/LzmaDec.c
-@@ -0,0 +1,925 @@
-+/* LzmaDec.c -- LZMA Decoder
-+2009-09-20 : Igor Pavlov : Public domain */
-+
-+#include "LzmaDec.h"
-+
-+#include <string.h>
-+
-+#define kNumTopBits 24
-+#define kTopValue ((UInt32)1 << kNumTopBits)
-+
-+#define kNumBitModelTotalBits 11
-+#define kBitModelTotal (1 << kNumBitModelTotalBits)
-+#define kNumMoveBits 5
-+
-+#define RC_INIT_SIZE 5
-+
-+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
-+
-+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
-+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
-+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
-+ { UPDATE_0(p); i = (i + i); A0; } else \
-+ { UPDATE_1(p); i = (i + i) + 1; A1; }
-+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
-+
-+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
-+#define TREE_DECODE(probs, limit, i) \
-+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
-+
-+/* #define _LZMA_SIZE_OPT */
-+
-+#ifdef _LZMA_SIZE_OPT
-+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
-+#else
-+#define TREE_6_DECODE(probs, i) \
-+ { i = 1; \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ i -= 0x40; }
-+#endif
-+
-+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
-+
-+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-+#define UPDATE_0_CHECK range = bound;
-+#define UPDATE_1_CHECK range -= bound; code -= bound;
-+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
-+ { UPDATE_0_CHECK; i = (i + i); A0; } else \
-+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
-+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
-+#define TREE_DECODE_CHECK(probs, limit, i) \
-+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
-+
-+
-+#define kNumPosBitsMax 4
-+#define kNumPosStatesMax (1 << kNumPosBitsMax)
-+
-+#define kLenNumLowBits 3
-+#define kLenNumLowSymbols (1 << kLenNumLowBits)
-+#define kLenNumMidBits 3
-+#define kLenNumMidSymbols (1 << kLenNumMidBits)
-+#define kLenNumHighBits 8
-+#define kLenNumHighSymbols (1 << kLenNumHighBits)
-+
-+#define LenChoice 0
-+#define LenChoice2 (LenChoice + 1)
-+#define LenLow (LenChoice2 + 1)
-+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-+
-+
-+#define kNumStates 12
-+#define kNumLitStates 7
-+
-+#define kStartPosModelIndex 4
-+#define kEndPosModelIndex 14
-+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-+
-+#define kNumPosSlotBits 6
-+#define kNumLenToPosStates 4
-+
-+#define kNumAlignBits 4
-+#define kAlignTableSize (1 << kNumAlignBits)
-+
-+#define kMatchMinLen 2
-+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-+
-+#define IsMatch 0
-+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-+#define IsRepG0 (IsRep + kNumStates)
-+#define IsRepG1 (IsRepG0 + kNumStates)
-+#define IsRepG2 (IsRepG1 + kNumStates)
-+#define IsRep0Long (IsRepG2 + kNumStates)
-+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-+#define LenCoder (Align + kAlignTableSize)
-+#define RepLenCoder (LenCoder + kNumLenProbs)
-+#define Literal (RepLenCoder + kNumLenProbs)
-+
-+#define LZMA_BASE_SIZE 1846
-+#define LZMA_LIT_SIZE 768
-+
-+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
-+
-+#if Literal != LZMA_BASE_SIZE
-+StopCompilingDueBUG
-+#endif
-+
-+#define LZMA_DIC_MIN (1 << 12)
-+
-+/* First LZMA-symbol is always decoded.
-+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
-+Out:
-+ Result:
-+ SZ_OK - OK
-+ SZ_ERROR_DATA - Error
-+ p->remainLen:
-+ < kMatchSpecLenStart : normal remain
-+ = kMatchSpecLenStart : finished
-+ = kMatchSpecLenStart + 1 : Flush marker
-+ = kMatchSpecLenStart + 2 : State Init Marker
-+*/
-+
-+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-+{
-+ CLzmaProb *probs = p->probs;
-+
-+ unsigned state = p->state;
-+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
-+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
-+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
-+ unsigned lc = p->prop.lc;
-+
-+ Byte *dic = p->dic;
-+ SizeT dicBufSize = p->dicBufSize;
-+ SizeT dicPos = p->dicPos;
-+
-+ UInt32 processedPos = p->processedPos;
-+ UInt32 checkDicSize = p->checkDicSize;
-+ unsigned len = 0;
-+
-+ const Byte *buf = p->buf;
-+ UInt32 range = p->range;
-+ UInt32 code = p->code;
-+
-+ do
-+ {
-+ CLzmaProb *prob;
-+ UInt32 bound;
-+ unsigned ttt;
-+ unsigned posState = processedPos & pbMask;
-+
-+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0(prob)
-+ {
-+ unsigned symbol;
-+ UPDATE_0(prob);
-+ prob = probs + Literal;
-+ if (checkDicSize != 0 || processedPos != 0)
-+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
-+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
-+
-+ if (state < kNumLitStates)
-+ {
-+ state -= (state < 4) ? state : 3;
-+ symbol = 1;
-+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
-+ }
-+ else
-+ {
-+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+ unsigned offs = 0x100;
-+ state -= (state < 10) ? 3 : 6;
-+ symbol = 1;
-+ do
-+ {
-+ unsigned bit;
-+ CLzmaProb *probLit;
-+ matchByte <<= 1;
-+ bit = (matchByte & offs);
-+ probLit = prob + offs + bit + symbol;
-+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
-+ }
-+ while (symbol < 0x100);
-+ }
-+ dic[dicPos++] = (Byte)symbol;
-+ processedPos++;
-+ continue;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ prob = probs + IsRep + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ state += kNumStates;
-+ prob = probs + LenCoder;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ if (checkDicSize == 0 && processedPos == 0)
-+ return SZ_ERROR_DATA;
-+ prob = probs + IsRepG0 + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+ dicPos++;
-+ processedPos++;
-+ state = state < kNumLitStates ? 9 : 11;
-+ continue;
-+ }
-+ UPDATE_1(prob);
-+ }
-+ else
-+ {
-+ UInt32 distance;
-+ UPDATE_1(prob);
-+ prob = probs + IsRepG1 + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ distance = rep1;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ prob = probs + IsRepG2 + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ distance = rep2;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ distance = rep3;
-+ rep3 = rep2;
-+ }
-+ rep2 = rep1;
-+ }
-+ rep1 = rep0;
-+ rep0 = distance;
-+ }
-+ state = state < kNumLitStates ? 8 : 11;
-+ prob = probs + RepLenCoder;
-+ }
-+ {
-+ unsigned limit, offset;
-+ CLzmaProb *probLen = prob + LenChoice;
-+ IF_BIT_0(probLen)
-+ {
-+ UPDATE_0(probLen);
-+ probLen = prob + LenLow + (posState << kLenNumLowBits);
-+ offset = 0;
-+ limit = (1 << kLenNumLowBits);
-+ }
-+ else
-+ {
-+ UPDATE_1(probLen);
-+ probLen = prob + LenChoice2;
-+ IF_BIT_0(probLen)
-+ {
-+ UPDATE_0(probLen);
-+ probLen = prob + LenMid + (posState << kLenNumMidBits);
-+ offset = kLenNumLowSymbols;
-+ limit = (1 << kLenNumMidBits);
-+ }
-+ else
-+ {
-+ UPDATE_1(probLen);
-+ probLen = prob + LenHigh;
-+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
-+ limit = (1 << kLenNumHighBits);
-+ }
-+ }
-+ TREE_DECODE(probLen, limit, len);
-+ len += offset;
-+ }
-+
-+ if (state >= kNumStates)
-+ {
-+ UInt32 distance;
-+ prob = probs + PosSlot +
-+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
-+ TREE_6_DECODE(prob, distance);
-+ if (distance >= kStartPosModelIndex)
-+ {
-+ unsigned posSlot = (unsigned)distance;
-+ int numDirectBits = (int)(((distance >> 1) - 1));
-+ distance = (2 | (distance & 1));
-+ if (posSlot < kEndPosModelIndex)
-+ {
-+ distance <<= numDirectBits;
-+ prob = probs + SpecPos + distance - posSlot - 1;
-+ {
-+ UInt32 mask = 1;
-+ unsigned i = 1;
-+ do
-+ {
-+ GET_BIT2(prob + i, i, ; , distance |= mask);
-+ mask <<= 1;
-+ }
-+ while (--numDirectBits != 0);
-+ }
-+ }
-+ else
-+ {
-+ numDirectBits -= kNumAlignBits;
-+ do
-+ {
-+ NORMALIZE
-+ range >>= 1;
-+
-+ {
-+ UInt32 t;
-+ code -= range;
-+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
-+ distance = (distance << 1) + (t + 1);
-+ code += range & t;
-+ }
-+ /*
-+ distance <<= 1;
-+ if (code >= range)
-+ {
-+ code -= range;
-+ distance |= 1;
-+ }
-+ */
-+ }
-+ while (--numDirectBits != 0);
-+ prob = probs + Align;
-+ distance <<= kNumAlignBits;
-+ {
-+ unsigned i = 1;
-+ GET_BIT2(prob + i, i, ; , distance |= 1);
-+ GET_BIT2(prob + i, i, ; , distance |= 2);
-+ GET_BIT2(prob + i, i, ; , distance |= 4);
-+ GET_BIT2(prob + i, i, ; , distance |= 8);
-+ }
-+ if (distance == (UInt32)0xFFFFFFFF)
-+ {
-+ len += kMatchSpecLenStart;
-+ state -= kNumStates;
-+ break;
-+ }
-+ }
-+ }
-+ rep3 = rep2;
-+ rep2 = rep1;
-+ rep1 = rep0;
-+ rep0 = distance + 1;
-+ if (checkDicSize == 0)
-+ {
-+ if (distance >= processedPos)
-+ return SZ_ERROR_DATA;
-+ }
-+ else if (distance >= checkDicSize)
-+ return SZ_ERROR_DATA;
-+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
-+ }
-+
-+ len += kMatchMinLen;
-+
-+ if (limit == dicPos)
-+ return SZ_ERROR_DATA;
-+ {
-+ SizeT rem = limit - dicPos;
-+ unsigned curLen = ((rem < len) ? (unsigned)rem : len);
-+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
-+
-+ processedPos += curLen;
-+
-+ len -= curLen;
-+ if (pos + curLen <= dicBufSize)
-+ {
-+ Byte *dest = dic + dicPos;
-+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
-+ const Byte *lim = dest + curLen;
-+ dicPos += curLen;
-+ do
-+ *(dest) = (Byte)*(dest + src);
-+ while (++dest != lim);
-+ }
-+ else
-+ {
-+ do
-+ {
-+ dic[dicPos++] = dic[pos];
-+ if (++pos == dicBufSize)
-+ pos = 0;
-+ }
-+ while (--curLen != 0);
-+ }
-+ }
-+ }
-+ }
-+ while (dicPos < limit && buf < bufLimit);
-+ NORMALIZE;
-+ p->buf = buf;
-+ p->range = range;
-+ p->code = code;
-+ p->remainLen = len;
-+ p->dicPos = dicPos;
-+ p->processedPos = processedPos;
-+ p->reps[0] = rep0;
-+ p->reps[1] = rep1;
-+ p->reps[2] = rep2;
-+ p->reps[3] = rep3;
-+ p->state = state;
-+
-+ return SZ_OK;
-+}
-+
-+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
-+{
-+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
-+ {
-+ Byte *dic = p->dic;
-+ SizeT dicPos = p->dicPos;
-+ SizeT dicBufSize = p->dicBufSize;
-+ unsigned len = p->remainLen;
-+ UInt32 rep0 = p->reps[0];
-+ if (limit - dicPos < len)
-+ len = (unsigned)(limit - dicPos);
-+
-+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
-+ p->checkDicSize = p->prop.dicSize;
-+
-+ p->processedPos += len;
-+ p->remainLen -= len;
-+ while (len-- != 0)
-+ {
-+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+ dicPos++;
-+ }
-+ p->dicPos = dicPos;
-+ }
-+}
-+
-+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-+{
-+ do
-+ {
-+ SizeT limit2 = limit;
-+ if (p->checkDicSize == 0)
-+ {
-+ UInt32 rem = p->prop.dicSize - p->processedPos;
-+ if (limit - p->dicPos > rem)
-+ limit2 = p->dicPos + rem;
-+ }
-+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
-+ if (p->processedPos >= p->prop.dicSize)
-+ p->checkDicSize = p->prop.dicSize;
-+ LzmaDec_WriteRem(p, limit);
-+ }
-+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
-+
-+ if (p->remainLen > kMatchSpecLenStart)
-+ {
-+ p->remainLen = kMatchSpecLenStart;
-+ }
-+ return 0;
-+}
-+
-+typedef enum
-+{
-+ DUMMY_ERROR, /* unexpected end of input stream */
-+ DUMMY_LIT,
-+ DUMMY_MATCH,
-+ DUMMY_REP
-+} ELzmaDummy;
-+
-+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
-+{
-+ UInt32 range = p->range;
-+ UInt32 code = p->code;
-+ const Byte *bufLimit = buf + inSize;
-+ CLzmaProb *probs = p->probs;
-+ unsigned state = p->state;
-+ ELzmaDummy res;
-+
-+ {
-+ CLzmaProb *prob;
-+ UInt32 bound;
-+ unsigned ttt;
-+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
-+
-+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK
-+
-+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
-+
-+ prob = probs + Literal;
-+ if (p->checkDicSize != 0 || p->processedPos != 0)
-+ prob += (LZMA_LIT_SIZE *
-+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
-+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
-+
-+ if (state < kNumLitStates)
-+ {
-+ unsigned symbol = 1;
-+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
-+ }
-+ else
-+ {
-+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
-+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
-+ unsigned offs = 0x100;
-+ unsigned symbol = 1;
-+ do
-+ {
-+ unsigned bit;
-+ CLzmaProb *probLit;
-+ matchByte <<= 1;
-+ bit = (matchByte & offs);
-+ probLit = prob + offs + bit + symbol;
-+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
-+ }
-+ while (symbol < 0x100);
-+ }
-+ res = DUMMY_LIT;
-+ }
-+ else
-+ {
-+ unsigned len;
-+ UPDATE_1_CHECK;
-+
-+ prob = probs + IsRep + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ state = 0;
-+ prob = probs + LenCoder;
-+ res = DUMMY_MATCH;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ res = DUMMY_REP;
-+ prob = probs + IsRepG0 + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ NORMALIZE_CHECK;
-+ return DUMMY_REP;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ }
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ prob = probs + IsRepG1 + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ prob = probs + IsRepG2 + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ }
-+ }
-+ }
-+ state = kNumStates;
-+ prob = probs + RepLenCoder;
-+ }
-+ {
-+ unsigned limit, offset;
-+ CLzmaProb *probLen = prob + LenChoice;
-+ IF_BIT_0_CHECK(probLen)
-+ {
-+ UPDATE_0_CHECK;
-+ probLen = prob + LenLow + (posState << kLenNumLowBits);
-+ offset = 0;
-+ limit = 1 << kLenNumLowBits;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ probLen = prob + LenChoice2;
-+ IF_BIT_0_CHECK(probLen)
-+ {
-+ UPDATE_0_CHECK;
-+ probLen = prob + LenMid + (posState << kLenNumMidBits);
-+ offset = kLenNumLowSymbols;
-+ limit = 1 << kLenNumMidBits;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ probLen = prob + LenHigh;
-+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
-+ limit = 1 << kLenNumHighBits;
-+ }
-+ }
-+ TREE_DECODE_CHECK(probLen, limit, len);
-+ len += offset;
-+ }
-+
-+ if (state < 4)
-+ {
-+ unsigned posSlot;
-+ prob = probs + PosSlot +
-+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
-+ kNumPosSlotBits);
-+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
-+ if (posSlot >= kStartPosModelIndex)
-+ {
-+ int numDirectBits = ((posSlot >> 1) - 1);
-+
-+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
-+
-+ if (posSlot < kEndPosModelIndex)
-+ {
-+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
-+ }
-+ else
-+ {
-+ numDirectBits -= kNumAlignBits;
-+ do
-+ {
-+ NORMALIZE_CHECK
-+ range >>= 1;
-+ code -= range & (((code - range) >> 31) - 1);
-+ /* if (code >= range) code -= range; */
-+ }
-+ while (--numDirectBits != 0);
-+ prob = probs + Align;
-+ numDirectBits = kNumAlignBits;
-+ }
-+ {
-+ unsigned i = 1;
-+ do
-+ {
-+ GET_BIT_CHECK(prob + i, i);
-+ }
-+ while (--numDirectBits != 0);
-+ }
-+ }
-+ }
-+ }
-+ }
-+ NORMALIZE_CHECK;
-+ return res;
-+}
-+
-+
-+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-+{
-+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
-+ p->range = 0xFFFFFFFF;
-+ p->needFlush = 0;
-+}
-+
-+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
-+{
-+ p->needFlush = 1;
-+ p->remainLen = 0;
-+ p->tempBufSize = 0;
-+
-+ if (initDic)
-+ {
-+ p->processedPos = 0;
-+ p->checkDicSize = 0;
-+ p->needInitState = 1;
-+ }
-+ if (initState)
-+ p->needInitState = 1;
-+}
-+
-+static void LzmaDec_Init(CLzmaDec *p)
-+{
-+ p->dicPos = 0;
-+ LzmaDec_InitDicAndState(p, True, True);
-+}
-+
-+static void LzmaDec_InitStateReal(CLzmaDec *p)
-+{
-+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
-+ UInt32 i;
-+ CLzmaProb *probs = p->probs;
-+ for (i = 0; i < numProbs; i++)
-+ probs[i] = kBitModelTotal >> 1;
-+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
-+ p->state = 0;
-+ p->needInitState = 0;
-+}
-+
-+static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
-+ ELzmaFinishMode finishMode, ELzmaStatus *status)
-+{
-+ SizeT inSize = *srcLen;
-+ (*srcLen) = 0;
-+ LzmaDec_WriteRem(p, dicLimit);
-+
-+ *status = LZMA_STATUS_NOT_SPECIFIED;
-+
-+ while (p->remainLen != kMatchSpecLenStart)
-+ {
-+ int checkEndMarkNow;
-+
-+ if (p->needFlush != 0)
-+ {
-+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
-+ p->tempBuf[p->tempBufSize++] = *src++;
-+ if (p->tempBufSize < RC_INIT_SIZE)
-+ {
-+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+ return SZ_OK;
-+ }
-+ if (p->tempBuf[0] != 0)
-+ return SZ_ERROR_DATA;
-+
-+ LzmaDec_InitRc(p, p->tempBuf);
-+ p->tempBufSize = 0;
-+ }
-+
-+ checkEndMarkNow = 0;
-+ if (p->dicPos >= dicLimit)
-+ {
-+ if (p->remainLen == 0 && p->code == 0)
-+ {
-+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
-+ return SZ_OK;
-+ }
-+ if (finishMode == LZMA_FINISH_ANY)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_OK;
-+ }
-+ if (p->remainLen != 0)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_ERROR_DATA;
-+ }
-+ checkEndMarkNow = 1;
-+ }
-+
-+ if (p->needInitState)
-+ LzmaDec_InitStateReal(p);
-+
-+ if (p->tempBufSize == 0)
-+ {
-+ SizeT processed;
-+ const Byte *bufLimit;
-+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-+ {
-+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
-+ if (dummyRes == DUMMY_ERROR)
-+ {
-+ memcpy(p->tempBuf, src, inSize);
-+ p->tempBufSize = (unsigned)inSize;
-+ (*srcLen) += inSize;
-+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+ return SZ_OK;
-+ }
-+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_ERROR_DATA;
-+ }
-+ bufLimit = src;
-+ }
-+ else
-+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
-+ p->buf = src;
-+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
-+ return SZ_ERROR_DATA;
-+ processed = (SizeT)(p->buf - src);
-+ (*srcLen) += processed;
-+ src += processed;
-+ inSize -= processed;
-+ }
-+ else
-+ {
-+ unsigned rem = p->tempBufSize, lookAhead = 0;
-+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
-+ p->tempBuf[rem++] = src[lookAhead++];
-+ p->tempBufSize = rem;
-+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-+ {
-+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
-+ if (dummyRes == DUMMY_ERROR)
-+ {
-+ (*srcLen) += lookAhead;
-+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+ return SZ_OK;
-+ }
-+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_ERROR_DATA;
-+ }
-+ }
-+ p->buf = p->tempBuf;
-+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
-+ return SZ_ERROR_DATA;
-+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
-+ (*srcLen) += lookAhead;
-+ src += lookAhead;
-+ inSize -= lookAhead;
-+ p->tempBufSize = 0;
-+ }
-+ }
-+ if (p->code == 0)
-+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
-+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
-+}
-+
-+static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->probs);
-+ p->probs = 0;
-+}
-+
-+static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
-+{
-+ UInt32 dicSize;
-+ Byte d;
-+
-+ if (size < LZMA_PROPS_SIZE)
-+ return SZ_ERROR_UNSUPPORTED;
-+ else
-+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
-+
-+ if (dicSize < LZMA_DIC_MIN)
-+ dicSize = LZMA_DIC_MIN;
-+ p->dicSize = dicSize;
-+
-+ d = data[0];
-+ if (d >= (9 * 5 * 5))
-+ return SZ_ERROR_UNSUPPORTED;
-+
-+ p->lc = d % 9;
-+ d /= 9;
-+ p->pb = d / 5;
-+ p->lp = d % 5;
-+
-+ return SZ_OK;
-+}
-+
-+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
-+{
-+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
-+ if (p->probs == 0 || numProbs != p->numProbs)
-+ {
-+ LzmaDec_FreeProbs(p, alloc);
-+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
-+ p->numProbs = numProbs;
-+ if (p->probs == 0)
-+ return SZ_ERROR_MEM;
-+ }
-+ return SZ_OK;
-+}
-+
-+static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-+{
-+ CLzmaProps propNew;
-+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-+ p->prop = propNew;
-+ return SZ_OK;
-+}
-+
-+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-+ ELzmaStatus *status, ISzAlloc *alloc)
-+{
-+ CLzmaDec p;
-+ SRes res;
-+ SizeT inSize = *srcLen;
-+ SizeT outSize = *destLen;
-+ *srcLen = *destLen = 0;
-+ if (inSize < RC_INIT_SIZE)
-+ return SZ_ERROR_INPUT_EOF;
-+
-+ LzmaDec_Construct(&p);
-+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
-+ if (res != 0)
-+ return res;
-+ p.dic = dest;
-+ p.dicBufSize = outSize;
-+
-+ LzmaDec_Init(&p);
-+
-+ *srcLen = inSize;
-+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
-+
-+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
-+ res = SZ_ERROR_INPUT_EOF;
-+
-+ (*destLen) = p.dicPos;
-+ LzmaDec_FreeProbs(&p, alloc);
-+ return res;
-+}
---- /dev/null
-+++ b/lib/lzma/LzmaEnc.c
-@@ -0,0 +1,2123 @@
-+/* LzmaEnc.c -- LZMA Encoder
-+2009-11-24 : Igor Pavlov : Public domain */
-+
-+#include <string.h>
-+
-+/* #define SHOW_STAT */
-+/* #define SHOW_STAT2 */
-+
-+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
-+#include <stdio.h>
-+#endif
-+
-+#include "LzmaEnc.h"
-+
-+/* disable MT */
-+#define _7ZIP_ST
-+
-+#include "LzFind.h"
-+#ifndef _7ZIP_ST
-+#include "LzFindMt.h"
-+#endif
-+
-+#ifdef SHOW_STAT
-+static int ttt = 0;
-+#endif
-+
-+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
-+
-+#define kBlockSize (9 << 10)
-+#define kUnpackBlockSize (1 << 18)
-+#define kMatchArraySize (1 << 21)
-+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
-+
-+#define kNumMaxDirectBits (31)
-+
-+#define kNumTopBits 24
-+#define kTopValue ((UInt32)1 << kNumTopBits)
-+
-+#define kNumBitModelTotalBits 11
-+#define kBitModelTotal (1 << kNumBitModelTotalBits)
-+#define kNumMoveBits 5
-+#define kProbInitValue (kBitModelTotal >> 1)
-+
-+#define kNumMoveReducingBits 4
-+#define kNumBitPriceShiftBits 4
-+#define kBitPrice (1 << kNumBitPriceShiftBits)
-+
-+void LzmaEncProps_Init(CLzmaEncProps *p)
-+{
-+ p->level = 5;
-+ p->dictSize = p->mc = 0;
-+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
-+ p->writeEndMark = 0;
-+}
-+
-+static void LzmaEncProps_Normalize(CLzmaEncProps *p)
-+{
-+ int level = p->level;
-+ if (level < 0) level = 5;
-+ p->level = level;
-+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
-+ if (p->lc < 0) p->lc = 3;
-+ if (p->lp < 0) p->lp = 0;
-+ if (p->pb < 0) p->pb = 2;
-+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
-+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
-+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
-+ if (p->numHashBytes < 0) p->numHashBytes = 4;
-+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
-+ if (p->numThreads < 0)
-+ p->numThreads =
-+ #ifndef _7ZIP_ST
-+ ((p->btMode && p->algo) ? 2 : 1);
-+ #else
-+ 1;
-+ #endif
-+}
-+
-+static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
-+{
-+ CLzmaEncProps props = *props2;
-+ LzmaEncProps_Normalize(&props);
-+ return props.dictSize;
-+}
-+
-+/* #define LZMA_LOG_BSR */
-+/* Define it for Intel's CPU */
-+
-+
-+#ifdef LZMA_LOG_BSR
-+
-+#define kDicLogSizeMaxCompress 30
-+
-+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
-+
-+static UInt32 GetPosSlot1(UInt32 pos)
-+{
-+ UInt32 res;
-+ BSR2_RET(pos, res);
-+ return res;
-+}
-+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
-+
-+#else
-+
-+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
-+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-+
-+static void LzmaEnc_FastPosInit(Byte *g_FastPos)
-+{
-+ int c = 2, slotFast;
-+ g_FastPos[0] = 0;
-+ g_FastPos[1] = 1;
-+
-+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
-+ {
-+ UInt32 k = (1 << ((slotFast >> 1) - 1));
-+ UInt32 j;
-+ for (j = 0; j < k; j++, c++)
-+ g_FastPos[c] = (Byte)slotFast;
-+ }
-+}
-+
-+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
-+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
-+ res = p->g_FastPos[pos >> i] + (i * 2); }
-+/*
-+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
-+ p->g_FastPos[pos >> 6] + 12 : \
-+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
-+*/
-+
-+#define GetPosSlot1(pos) p->g_FastPos[pos]
-+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
-+
-+#endif
-+
-+
-+#define LZMA_NUM_REPS 4
-+
-+typedef unsigned CState;
-+
-+typedef struct
-+{
-+ UInt32 price;
-+
-+ CState state;
-+ int prev1IsChar;
-+ int prev2;
-+
-+ UInt32 posPrev2;
-+ UInt32 backPrev2;
-+
-+ UInt32 posPrev;
-+ UInt32 backPrev;
-+ UInt32 backs[LZMA_NUM_REPS];
-+} COptimal;
-+
-+#define kNumOpts (1 << 12)
-+
-+#define kNumLenToPosStates 4
-+#define kNumPosSlotBits 6
-+#define kDicLogSizeMin 0
-+#define kDicLogSizeMax 32
-+#define kDistTableSizeMax (kDicLogSizeMax * 2)
-+
-+
-+#define kNumAlignBits 4
-+#define kAlignTableSize (1 << kNumAlignBits)
-+#define kAlignMask (kAlignTableSize - 1)
-+
-+#define kStartPosModelIndex 4
-+#define kEndPosModelIndex 14
-+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
-+
-+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-+
-+#ifdef _LZMA_PROB32
-+#define CLzmaProb UInt32
-+#else
-+#define CLzmaProb UInt16
-+#endif
-+
-+#define LZMA_PB_MAX 4
-+#define LZMA_LC_MAX 8
-+#define LZMA_LP_MAX 4
-+
-+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
-+
-+
-+#define kLenNumLowBits 3
-+#define kLenNumLowSymbols (1 << kLenNumLowBits)
-+#define kLenNumMidBits 3
-+#define kLenNumMidSymbols (1 << kLenNumMidBits)
-+#define kLenNumHighBits 8
-+#define kLenNumHighSymbols (1 << kLenNumHighBits)
-+
-+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-+
-+#define LZMA_MATCH_LEN_MIN 2
-+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
-+
-+#define kNumStates 12
-+
-+typedef struct
-+{
-+ CLzmaProb choice;
-+ CLzmaProb choice2;
-+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
-+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
-+ CLzmaProb high[kLenNumHighSymbols];
-+} CLenEnc;
-+
-+typedef struct
-+{
-+ CLenEnc p;
-+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
-+ UInt32 tableSize;
-+ UInt32 counters[LZMA_NUM_PB_STATES_MAX];
-+} CLenPriceEnc;
-+
-+typedef struct
-+{
-+ UInt32 range;
-+ Byte cache;
-+ UInt64 low;
-+ UInt64 cacheSize;
-+ Byte *buf;
-+ Byte *bufLim;
-+ Byte *bufBase;
-+ ISeqOutStream *outStream;
-+ UInt64 processed;
-+ SRes res;
-+} CRangeEnc;
-+
-+typedef struct
-+{
-+ CLzmaProb *litProbs;
-+
-+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+ CLzmaProb isRep[kNumStates];
-+ CLzmaProb isRepG0[kNumStates];
-+ CLzmaProb isRepG1[kNumStates];
-+ CLzmaProb isRepG2[kNumStates];
-+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+
-+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-+
-+ CLenPriceEnc lenEnc;
-+ CLenPriceEnc repLenEnc;
-+
-+ UInt32 reps[LZMA_NUM_REPS];
-+ UInt32 state;
-+} CSaveState;
-+
-+typedef struct
-+{
-+ IMatchFinder matchFinder;
-+ void *matchFinderObj;
-+
-+ #ifndef _7ZIP_ST
-+ Bool mtMode;
-+ CMatchFinderMt matchFinderMt;
-+ #endif
-+
-+ CMatchFinder matchFinderBase;
-+
-+ #ifndef _7ZIP_ST
-+ Byte pad[128];
-+ #endif
-+
-+ UInt32 optimumEndIndex;
-+ UInt32 optimumCurrentIndex;
-+
-+ UInt32 longestMatchLength;
-+ UInt32 numPairs;
-+ UInt32 numAvail;
-+ COptimal opt[kNumOpts];
-+
-+ #ifndef LZMA_LOG_BSR
-+ Byte g_FastPos[1 << kNumLogBits];
-+ #endif
-+
-+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
-+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
-+ UInt32 numFastBytes;
-+ UInt32 additionalOffset;
-+ UInt32 reps[LZMA_NUM_REPS];
-+ UInt32 state;
-+
-+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
-+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
-+ UInt32 alignPrices[kAlignTableSize];
-+ UInt32 alignPriceCount;
-+
-+ UInt32 distTableSize;
-+
-+ unsigned lc, lp, pb;
-+ unsigned lpMask, pbMask;
-+
-+ CLzmaProb *litProbs;
-+
-+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+ CLzmaProb isRep[kNumStates];
-+ CLzmaProb isRepG0[kNumStates];
-+ CLzmaProb isRepG1[kNumStates];
-+ CLzmaProb isRepG2[kNumStates];
-+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+
-+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-+
-+ CLenPriceEnc lenEnc;
-+ CLenPriceEnc repLenEnc;
-+
-+ unsigned lclp;
-+
-+ Bool fastMode;
-+
-+ CRangeEnc rc;
-+
-+ Bool writeEndMark;
-+ UInt64 nowPos64;
-+ UInt32 matchPriceCount;
-+ Bool finished;
-+ Bool multiThread;
-+
-+ SRes result;
-+ UInt32 dictSize;
-+ UInt32 matchFinderCycles;
-+
-+ int needInit;
-+
-+ CSaveState saveState;
-+} CLzmaEnc;
-+
-+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ CLzmaEncProps props = *props2;
-+ LzmaEncProps_Normalize(&props);
-+
-+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
-+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
-+ return SZ_ERROR_PARAM;
-+ p->dictSize = props.dictSize;
-+ p->matchFinderCycles = props.mc;
-+ {
-+ unsigned fb = props.fb;
-+ if (fb < 5)
-+ fb = 5;
-+ if (fb > LZMA_MATCH_LEN_MAX)
-+ fb = LZMA_MATCH_LEN_MAX;
-+ p->numFastBytes = fb;
-+ }
-+ p->lc = props.lc;
-+ p->lp = props.lp;
-+ p->pb = props.pb;
-+ p->fastMode = (props.algo == 0);
-+ p->matchFinderBase.btMode = props.btMode;
-+ {
-+ UInt32 numHashBytes = 4;
-+ if (props.btMode)
-+ {
-+ if (props.numHashBytes < 2)
-+ numHashBytes = 2;
-+ else if (props.numHashBytes < 4)
-+ numHashBytes = props.numHashBytes;
-+ }
-+ p->matchFinderBase.numHashBytes = numHashBytes;
-+ }
-+
-+ p->matchFinderBase.cutValue = props.mc;
-+
-+ p->writeEndMark = props.writeEndMark;
-+
-+ #ifndef _7ZIP_ST
-+ /*
-+ if (newMultiThread != _multiThread)
-+ {
-+ ReleaseMatchFinder();
-+ _multiThread = newMultiThread;
-+ }
-+ */
-+ p->multiThread = (props.numThreads > 1);
-+ #endif
-+
-+ return SZ_OK;
-+}
-+
-+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
-+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
-+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
-+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
-+
-+#define IsCharState(s) ((s) < 7)
-+
-+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
-+
-+#define kInfinityPrice (1 << 30)
-+
-+static void RangeEnc_Construct(CRangeEnc *p)
-+{
-+ p->outStream = 0;
-+ p->bufBase = 0;
-+}
-+
-+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
-+
-+#define RC_BUF_SIZE (1 << 16)
-+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
-+{
-+ if (p->bufBase == 0)
-+ {
-+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
-+ if (p->bufBase == 0)
-+ return 0;
-+ p->bufLim = p->bufBase + RC_BUF_SIZE;
-+ }
-+ return 1;
-+}
-+
-+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->bufBase);
-+ p->bufBase = 0;
-+}
-+
-+static void RangeEnc_Init(CRangeEnc *p)
-+{
-+ /* Stream.Init(); */
-+ p->low = 0;
-+ p->range = 0xFFFFFFFF;
-+ p->cacheSize = 1;
-+ p->cache = 0;
-+
-+ p->buf = p->bufBase;
-+
-+ p->processed = 0;
-+ p->res = SZ_OK;
-+}
-+
-+static void RangeEnc_FlushStream(CRangeEnc *p)
-+{
-+ size_t num;
-+ if (p->res != SZ_OK)
-+ return;
-+ num = p->buf - p->bufBase;
-+ if (num != p->outStream->Write(p->outStream, p->bufBase, num))
-+ p->res = SZ_ERROR_WRITE;
-+ p->processed += num;
-+ p->buf = p->bufBase;
-+}
-+
-+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
-+{
-+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
-+ {
-+ Byte temp = p->cache;
-+ do
-+ {
-+ Byte *buf = p->buf;
-+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
-+ p->buf = buf;
-+ if (buf == p->bufLim)
-+ RangeEnc_FlushStream(p);
-+ temp = 0xFF;
-+ }
-+ while (--p->cacheSize != 0);
-+ p->cache = (Byte)((UInt32)p->low >> 24);
-+ }
-+ p->cacheSize++;
-+ p->low = (UInt32)p->low << 8;
-+}
-+
-+static void RangeEnc_FlushData(CRangeEnc *p)
-+{
-+ int i;
-+ for (i = 0; i < 5; i++)
-+ RangeEnc_ShiftLow(p);
-+}
-+
-+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
-+{
-+ do
-+ {
-+ p->range >>= 1;
-+ p->low += p->range & (0 - ((value >> --numBits) & 1));
-+ if (p->range < kTopValue)
-+ {
-+ p->range <<= 8;
-+ RangeEnc_ShiftLow(p);
-+ }
-+ }
-+ while (numBits != 0);
-+}
-+
-+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
-+{
-+ UInt32 ttt = *prob;
-+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
-+ if (symbol == 0)
-+ {
-+ p->range = newBound;
-+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
-+ }
-+ else
-+ {
-+ p->low += newBound;
-+ p->range -= newBound;
-+ ttt -= ttt >> kNumMoveBits;
-+ }
-+ *prob = (CLzmaProb)ttt;
-+ if (p->range < kTopValue)
-+ {
-+ p->range <<= 8;
-+ RangeEnc_ShiftLow(p);
-+ }
-+}
-+
-+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
-+{
-+ symbol |= 0x100;
-+ do
-+ {
-+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ }
-+ while (symbol < 0x10000);
-+}
-+
-+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
-+{
-+ UInt32 offs = 0x100;
-+ symbol |= 0x100;
-+ do
-+ {
-+ matchByte <<= 1;
-+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ offs &= ~(matchByte ^ symbol);
-+ }
-+ while (symbol < 0x10000);
-+}
-+
-+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
-+{
-+ UInt32 i;
-+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
-+ {
-+ const int kCyclesBits = kNumBitPriceShiftBits;
-+ UInt32 w = i;
-+ UInt32 bitCount = 0;
-+ int j;
-+ for (j = 0; j < kCyclesBits; j++)
-+ {
-+ w = w * w;
-+ bitCount <<= 1;
-+ while (w >= ((UInt32)1 << 16))
-+ {
-+ w >>= 1;
-+ bitCount++;
-+ }
-+ }
-+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
-+ }
-+}
-+
-+
-+#define GET_PRICE(prob, symbol) \
-+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-+
-+#define GET_PRICEa(prob, symbol) \
-+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-+
-+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
-+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-+
-+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
-+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-+
-+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ symbol |= 0x100;
-+ do
-+ {
-+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ }
-+ while (symbol < 0x10000);
-+ return price;
-+}
-+
-+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ UInt32 offs = 0x100;
-+ symbol |= 0x100;
-+ do
-+ {
-+ matchByte <<= 1;
-+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ offs &= ~(matchByte ^ symbol);
-+ }
-+ while (symbol < 0x10000);
-+ return price;
-+}
-+
-+
-+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-+{
-+ UInt32 m = 1;
-+ int i;
-+ for (i = numBitLevels; i != 0;)
-+ {
-+ UInt32 bit;
-+ i--;
-+ bit = (symbol >> i) & 1;
-+ RangeEnc_EncodeBit(rc, probs + m, bit);
-+ m = (m << 1) | bit;
-+ }
-+}
-+
-+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-+{
-+ UInt32 m = 1;
-+ int i;
-+ for (i = 0; i < numBitLevels; i++)
-+ {
-+ UInt32 bit = symbol & 1;
-+ RangeEnc_EncodeBit(rc, probs + m, bit);
-+ m = (m << 1) | bit;
-+ symbol >>= 1;
-+ }
-+}
-+
-+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ symbol |= (1 << numBitLevels);
-+ while (symbol != 1)
-+ {
-+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
-+ symbol >>= 1;
-+ }
-+ return price;
-+}
-+
-+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ UInt32 m = 1;
-+ int i;
-+ for (i = numBitLevels; i != 0; i--)
-+ {
-+ UInt32 bit = symbol & 1;
-+ symbol >>= 1;
-+ price += GET_PRICEa(probs[m], bit);
-+ m = (m << 1) | bit;
-+ }
-+ return price;
-+}
-+
-+
-+static void LenEnc_Init(CLenEnc *p)
-+{
-+ unsigned i;
-+ p->choice = p->choice2 = kProbInitValue;
-+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
-+ p->low[i] = kProbInitValue;
-+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
-+ p->mid[i] = kProbInitValue;
-+ for (i = 0; i < kLenNumHighSymbols; i++)
-+ p->high[i] = kProbInitValue;
-+}
-+
-+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
-+{
-+ if (symbol < kLenNumLowSymbols)
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice, 0);
-+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
-+ }
-+ else
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice, 1);
-+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice2, 0);
-+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
-+ }
-+ else
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice2, 1);
-+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
-+ }
-+ }
-+}
-+
-+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
-+{
-+ UInt32 a0 = GET_PRICE_0a(p->choice);
-+ UInt32 a1 = GET_PRICE_1a(p->choice);
-+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
-+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
-+ UInt32 i = 0;
-+ for (i = 0; i < kLenNumLowSymbols; i++)
-+ {
-+ if (i >= numSymbols)
-+ return;
-+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
-+ }
-+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
-+ {
-+ if (i >= numSymbols)
-+ return;
-+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
-+ }
-+ for (; i < numSymbols; i++)
-+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
-+}
-+
-+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
-+{
-+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
-+ p->counters[posState] = p->tableSize;
-+}
-+
-+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
-+{
-+ UInt32 posState;
-+ for (posState = 0; posState < numPosStates; posState++)
-+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-+}
-+
-+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
-+{
-+ LenEnc_Encode(&p->p, rc, symbol, posState);
-+ if (updatePrice)
-+ if (--p->counters[posState] == 0)
-+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-+}
-+
-+
-+
-+
-+static void MovePos(CLzmaEnc *p, UInt32 num)
-+{
-+ #ifdef SHOW_STAT
-+ ttt += num;
-+ printf("\n MovePos %d", num);
-+ #endif
-+ if (num != 0)
-+ {
-+ p->additionalOffset += num;
-+ p->matchFinder.Skip(p->matchFinderObj, num);
-+ }
-+}
-+
-+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
-+{
-+ UInt32 lenRes = 0, numPairs;
-+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
-+ #ifdef SHOW_STAT
-+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
-+ ttt++;
-+ {
-+ UInt32 i;
-+ for (i = 0; i < numPairs; i += 2)
-+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
-+ }
-+ #endif
-+ if (numPairs > 0)
-+ {
-+ lenRes = p->matches[numPairs - 2];
-+ if (lenRes == p->numFastBytes)
-+ {
-+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ UInt32 distance = p->matches[numPairs - 1] + 1;
-+ UInt32 numAvail = p->numAvail;
-+ if (numAvail > LZMA_MATCH_LEN_MAX)
-+ numAvail = LZMA_MATCH_LEN_MAX;
-+ {
-+ const Byte *pby2 = pby - distance;
-+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
-+ }
-+ }
-+ }
-+ p->additionalOffset++;
-+ *numDistancePairsRes = numPairs;
-+ return lenRes;
-+}
-+
-+
-+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
-+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
-+#define IsShortRep(p) ((p)->backPrev == 0)
-+
-+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
-+{
-+ return
-+ GET_PRICE_0(p->isRepG0[state]) +
-+ GET_PRICE_0(p->isRep0Long[state][posState]);
-+}
-+
-+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
-+{
-+ UInt32 price;
-+ if (repIndex == 0)
-+ {
-+ price = GET_PRICE_0(p->isRepG0[state]);
-+ price += GET_PRICE_1(p->isRep0Long[state][posState]);
-+ }
-+ else
-+ {
-+ price = GET_PRICE_1(p->isRepG0[state]);
-+ if (repIndex == 1)
-+ price += GET_PRICE_0(p->isRepG1[state]);
-+ else
-+ {
-+ price += GET_PRICE_1(p->isRepG1[state]);
-+ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
-+ }
-+ }
-+ return price;
-+}
-+
-+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
-+{
-+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
-+ GetPureRepPrice(p, repIndex, state, posState);
-+}
-+
-+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
-+{
-+ UInt32 posMem = p->opt[cur].posPrev;
-+ UInt32 backMem = p->opt[cur].backPrev;
-+ p->optimumEndIndex = cur;
-+ do
-+ {
-+ if (p->opt[cur].prev1IsChar)
-+ {
-+ MakeAsChar(&p->opt[posMem])
-+ p->opt[posMem].posPrev = posMem - 1;
-+ if (p->opt[cur].prev2)
-+ {
-+ p->opt[posMem - 1].prev1IsChar = False;
-+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
-+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
-+ }
-+ }
-+ {
-+ UInt32 posPrev = posMem;
-+ UInt32 backCur = backMem;
-+
-+ backMem = p->opt[posPrev].backPrev;
-+ posMem = p->opt[posPrev].posPrev;
-+
-+ p->opt[posPrev].backPrev = backCur;
-+ p->opt[posPrev].posPrev = cur;
-+ cur = posPrev;
-+ }
-+ }
-+ while (cur != 0);
-+ *backRes = p->opt[0].backPrev;
-+ p->optimumCurrentIndex = p->opt[0].posPrev;
-+ return p->optimumCurrentIndex;
-+}
-+
-+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
-+
-+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-+{
-+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
-+ UInt32 matchPrice, repMatchPrice, normalMatchPrice;
-+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
-+ UInt32 *matches;
-+ const Byte *data;
-+ Byte curByte, matchByte;
-+ if (p->optimumEndIndex != p->optimumCurrentIndex)
-+ {
-+ const COptimal *opt = &p->opt[p->optimumCurrentIndex];
-+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
-+ *backRes = opt->backPrev;
-+ p->optimumCurrentIndex = opt->posPrev;
-+ return lenRes;
-+ }
-+ p->optimumCurrentIndex = p->optimumEndIndex = 0;
-+
-+ if (p->additionalOffset == 0)
-+ mainLen = ReadMatchDistances(p, &numPairs);
-+ else
-+ {
-+ mainLen = p->longestMatchLength;
-+ numPairs = p->numPairs;
-+ }
-+
-+ numAvail = p->numAvail;
-+ if (numAvail < 2)
-+ {
-+ *backRes = (UInt32)(-1);
-+ return 1;
-+ }
-+ if (numAvail > LZMA_MATCH_LEN_MAX)
-+ numAvail = LZMA_MATCH_LEN_MAX;
-+
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ repMaxIndex = 0;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 lenTest;
-+ const Byte *data2;
-+ reps[i] = p->reps[i];
-+ data2 = data - (reps[i] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ {
-+ repLens[i] = 0;
-+ continue;
-+ }
-+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
-+ repLens[i] = lenTest;
-+ if (lenTest > repLens[repMaxIndex])
-+ repMaxIndex = i;
-+ }
-+ if (repLens[repMaxIndex] >= p->numFastBytes)
-+ {
-+ UInt32 lenRes;
-+ *backRes = repMaxIndex;
-+ lenRes = repLens[repMaxIndex];
-+ MovePos(p, lenRes - 1);
-+ return lenRes;
-+ }
-+
-+ matches = p->matches;
-+ if (mainLen >= p->numFastBytes)
-+ {
-+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
-+ MovePos(p, mainLen - 1);
-+ return mainLen;
-+ }
-+ curByte = *data;
-+ matchByte = *(data - (reps[0] + 1));
-+
-+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
-+ {
-+ *backRes = (UInt32)-1;
-+ return 1;
-+ }
-+
-+ p->opt[0].state = (CState)p->state;
-+
-+ posState = (position & p->pbMask);
-+
-+ {
-+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
-+ (!IsCharState(p->state) ?
-+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
-+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
-+ }
-+
-+ MakeAsChar(&p->opt[1]);
-+
-+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
-+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
-+
-+ if (matchByte == curByte)
-+ {
-+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
-+ if (shortRepPrice < p->opt[1].price)
-+ {
-+ p->opt[1].price = shortRepPrice;
-+ MakeAsShortRep(&p->opt[1]);
-+ }
-+ }
-+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
-+
-+ if (lenEnd < 2)
-+ {
-+ *backRes = p->opt[1].backPrev;
-+ return 1;
-+ }
-+
-+ p->opt[1].posPrev = 0;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ p->opt[0].backs[i] = reps[i];
-+
-+ len = lenEnd;
-+ do
-+ p->opt[len--].price = kInfinityPrice;
-+ while (len >= 2);
-+
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 repLen = repLens[i];
-+ UInt32 price;
-+ if (repLen < 2)
-+ continue;
-+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
-+ do
-+ {
-+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
-+ COptimal *opt = &p->opt[repLen];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = 0;
-+ opt->backPrev = i;
-+ opt->prev1IsChar = False;
-+ }
-+ }
-+ while (--repLen >= 2);
-+ }
-+
-+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
-+
-+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
-+ if (len <= mainLen)
-+ {
-+ UInt32 offs = 0;
-+ while (len > matches[offs])
-+ offs += 2;
-+ for (; ; len++)
-+ {
-+ COptimal *opt;
-+ UInt32 distance = matches[offs + 1];
-+
-+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
-+ UInt32 lenToPosState = GetLenToPosState(len);
-+ if (distance < kNumFullDistances)
-+ curAndLenPrice += p->distancesPrices[lenToPosState][distance];
-+ else
-+ {
-+ UInt32 slot;
-+ GetPosSlot2(distance, slot);
-+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
-+ }
-+ opt = &p->opt[len];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = 0;
-+ opt->backPrev = distance + LZMA_NUM_REPS;
-+ opt->prev1IsChar = False;
-+ }
-+ if (len == matches[offs])
-+ {
-+ offs += 2;
-+ if (offs == numPairs)
-+ break;
-+ }
-+ }
-+ }
-+
-+ cur = 0;
-+
-+ #ifdef SHOW_STAT2
-+ if (position >= 0)
-+ {
-+ unsigned i;
-+ printf("\n pos = %4X", position);
-+ for (i = cur; i <= lenEnd; i++)
-+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
-+ }
-+ #endif
-+
-+ for (;;)
-+ {
-+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
-+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
-+ Bool nextIsChar;
-+ Byte curByte, matchByte;
-+ const Byte *data;
-+ COptimal *curOpt;
-+ COptimal *nextOpt;
-+
-+ cur++;
-+ if (cur == lenEnd)
-+ return Backward(p, backRes, cur);
-+
-+ newLen = ReadMatchDistances(p, &numPairs);
-+ if (newLen >= p->numFastBytes)
-+ {
-+ p->numPairs = numPairs;
-+ p->longestMatchLength = newLen;
-+ return Backward(p, backRes, cur);
-+ }
-+ position++;
-+ curOpt = &p->opt[cur];
-+ posPrev = curOpt->posPrev;
-+ if (curOpt->prev1IsChar)
-+ {
-+ posPrev--;
-+ if (curOpt->prev2)
-+ {
-+ state = p->opt[curOpt->posPrev2].state;
-+ if (curOpt->backPrev2 < LZMA_NUM_REPS)
-+ state = kRepNextStates[state];
-+ else
-+ state = kMatchNextStates[state];
-+ }
-+ else
-+ state = p->opt[posPrev].state;
-+ state = kLiteralNextStates[state];
-+ }
-+ else
-+ state = p->opt[posPrev].state;
-+ if (posPrev == cur - 1)
-+ {
-+ if (IsShortRep(curOpt))
-+ state = kShortRepNextStates[state];
-+ else
-+ state = kLiteralNextStates[state];
-+ }
-+ else
-+ {
-+ UInt32 pos;
-+ const COptimal *prevOpt;
-+ if (curOpt->prev1IsChar && curOpt->prev2)
-+ {
-+ posPrev = curOpt->posPrev2;
-+ pos = curOpt->backPrev2;
-+ state = kRepNextStates[state];
-+ }
-+ else
-+ {
-+ pos = curOpt->backPrev;
-+ if (pos < LZMA_NUM_REPS)
-+ state = kRepNextStates[state];
-+ else
-+ state = kMatchNextStates[state];
-+ }
-+ prevOpt = &p->opt[posPrev];
-+ if (pos < LZMA_NUM_REPS)
-+ {
-+ UInt32 i;
-+ reps[0] = prevOpt->backs[pos];
-+ for (i = 1; i <= pos; i++)
-+ reps[i] = prevOpt->backs[i - 1];
-+ for (; i < LZMA_NUM_REPS; i++)
-+ reps[i] = prevOpt->backs[i];
-+ }
-+ else
-+ {
-+ UInt32 i;
-+ reps[0] = (pos - LZMA_NUM_REPS);
-+ for (i = 1; i < LZMA_NUM_REPS; i++)
-+ reps[i] = prevOpt->backs[i - 1];
-+ }
-+ }
-+ curOpt->state = (CState)state;
-+
-+ curOpt->backs[0] = reps[0];
-+ curOpt->backs[1] = reps[1];
-+ curOpt->backs[2] = reps[2];
-+ curOpt->backs[3] = reps[3];
-+
-+ curPrice = curOpt->price;
-+ nextIsChar = False;
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ curByte = *data;
-+ matchByte = *(data - (reps[0] + 1));
-+
-+ posState = (position & p->pbMask);
-+
-+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
-+ {
-+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-+ curAnd1Price +=
-+ (!IsCharState(state) ?
-+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
-+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
-+ }
-+
-+ nextOpt = &p->opt[cur + 1];
-+
-+ if (curAnd1Price < nextOpt->price)
-+ {
-+ nextOpt->price = curAnd1Price;
-+ nextOpt->posPrev = cur;
-+ MakeAsChar(nextOpt);
-+ nextIsChar = True;
-+ }
-+
-+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
-+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
-+
-+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
-+ {
-+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
-+ if (shortRepPrice <= nextOpt->price)
-+ {
-+ nextOpt->price = shortRepPrice;
-+ nextOpt->posPrev = cur;
-+ MakeAsShortRep(nextOpt);
-+ nextIsChar = True;
-+ }
-+ }
-+ numAvailFull = p->numAvail;
-+ {
-+ UInt32 temp = kNumOpts - 1 - cur;
-+ if (temp < numAvailFull)
-+ numAvailFull = temp;
-+ }
-+
-+ if (numAvailFull < 2)
-+ continue;
-+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
-+
-+ if (!nextIsChar && matchByte != curByte) /* speed optimization */
-+ {
-+ /* try Literal + rep0 */
-+ UInt32 temp;
-+ UInt32 lenTest2;
-+ const Byte *data2 = data - (reps[0] + 1);
-+ UInt32 limit = p->numFastBytes + 1;
-+ if (limit > numAvailFull)
-+ limit = numAvailFull;
-+
-+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
-+ lenTest2 = temp - 1;
-+ if (lenTest2 >= 2)
-+ {
-+ UInt32 state2 = kLiteralNextStates[state];
-+ UInt32 posStateNext = (position + 1) & p->pbMask;
-+ UInt32 nextRepMatchPrice = curAnd1Price +
-+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+ GET_PRICE_1(p->isRep[state2]);
-+ /* for (; lenTest2 >= 2; lenTest2--) */
-+ {
-+ UInt32 curAndLenPrice;
-+ COptimal *opt;
-+ UInt32 offset = cur + 1 + lenTest2;
-+ while (lenEnd < offset)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+ opt = &p->opt[offset];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur + 1;
-+ opt->backPrev = 0;
-+ opt->prev1IsChar = True;
-+ opt->prev2 = False;
-+ }
-+ }
-+ }
-+ }
-+
-+ startLen = 2; /* speed optimization */
-+ {
-+ UInt32 repIndex;
-+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
-+ {
-+ UInt32 lenTest;
-+ UInt32 lenTestTemp;
-+ UInt32 price;
-+ const Byte *data2 = data - (reps[repIndex] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ continue;
-+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
-+ while (lenEnd < cur + lenTest)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ lenTestTemp = lenTest;
-+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
-+ do
-+ {
-+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
-+ COptimal *opt = &p->opt[cur + lenTest];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur;
-+ opt->backPrev = repIndex;
-+ opt->prev1IsChar = False;
-+ }
-+ }
-+ while (--lenTest >= 2);
-+ lenTest = lenTestTemp;
-+
-+ if (repIndex == 0)
-+ startLen = lenTest + 1;
-+
-+ /* if (_maxMode) */
-+ {
-+ UInt32 lenTest2 = lenTest + 1;
-+ UInt32 limit = lenTest2 + p->numFastBytes;
-+ UInt32 nextRepMatchPrice;
-+ if (limit > numAvailFull)
-+ limit = numAvailFull;
-+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-+ lenTest2 -= lenTest + 1;
-+ if (lenTest2 >= 2)
-+ {
-+ UInt32 state2 = kRepNextStates[state];
-+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
-+ UInt32 curAndLenCharPrice =
-+ price + p->repLenEnc.prices[posState][lenTest - 2] +
-+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-+ data[lenTest], data2[lenTest], p->ProbPrices);
-+ state2 = kLiteralNextStates[state2];
-+ posStateNext = (position + lenTest + 1) & p->pbMask;
-+ nextRepMatchPrice = curAndLenCharPrice +
-+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+ GET_PRICE_1(p->isRep[state2]);
-+
-+ /* for (; lenTest2 >= 2; lenTest2--) */
-+ {
-+ UInt32 curAndLenPrice;
-+ COptimal *opt;
-+ UInt32 offset = cur + lenTest + 1 + lenTest2;
-+ while (lenEnd < offset)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+ opt = &p->opt[offset];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur + lenTest + 1;
-+ opt->backPrev = 0;
-+ opt->prev1IsChar = True;
-+ opt->prev2 = True;
-+ opt->posPrev2 = cur;
-+ opt->backPrev2 = repIndex;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
-+ if (newLen > numAvail)
-+ {
-+ newLen = numAvail;
-+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
-+ matches[numPairs] = newLen;
-+ numPairs += 2;
-+ }
-+ if (newLen >= startLen)
-+ {
-+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
-+ UInt32 offs, curBack, posSlot;
-+ UInt32 lenTest;
-+ while (lenEnd < cur + newLen)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+
-+ offs = 0;
-+ while (startLen > matches[offs])
-+ offs += 2;
-+ curBack = matches[offs + 1];
-+ GetPosSlot2(curBack, posSlot);
-+ for (lenTest = /*2*/ startLen; ; lenTest++)
-+ {
-+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
-+ UInt32 lenToPosState = GetLenToPosState(lenTest);
-+ COptimal *opt;
-+ if (curBack < kNumFullDistances)
-+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
-+ else
-+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
-+
-+ opt = &p->opt[cur + lenTest];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur;
-+ opt->backPrev = curBack + LZMA_NUM_REPS;
-+ opt->prev1IsChar = False;
-+ }
-+
-+ if (/*_maxMode && */lenTest == matches[offs])
-+ {
-+ /* Try Match + Literal + Rep0 */
-+ const Byte *data2 = data - (curBack + 1);
-+ UInt32 lenTest2 = lenTest + 1;
-+ UInt32 limit = lenTest2 + p->numFastBytes;
-+ UInt32 nextRepMatchPrice;
-+ if (limit > numAvailFull)
-+ limit = numAvailFull;
-+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-+ lenTest2 -= lenTest + 1;
-+ if (lenTest2 >= 2)
-+ {
-+ UInt32 state2 = kMatchNextStates[state];
-+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
-+ UInt32 curAndLenCharPrice = curAndLenPrice +
-+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-+ data[lenTest], data2[lenTest], p->ProbPrices);
-+ state2 = kLiteralNextStates[state2];
-+ posStateNext = (posStateNext + 1) & p->pbMask;
-+ nextRepMatchPrice = curAndLenCharPrice +
-+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+ GET_PRICE_1(p->isRep[state2]);
-+
-+ /* for (; lenTest2 >= 2; lenTest2--) */
-+ {
-+ UInt32 offset = cur + lenTest + 1 + lenTest2;
-+ UInt32 curAndLenPrice;
-+ COptimal *opt;
-+ while (lenEnd < offset)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+ opt = &p->opt[offset];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur + lenTest + 1;
-+ opt->backPrev = 0;
-+ opt->prev1IsChar = True;
-+ opt->prev2 = True;
-+ opt->posPrev2 = cur;
-+ opt->backPrev2 = curBack + LZMA_NUM_REPS;
-+ }
-+ }
-+ }
-+ offs += 2;
-+ if (offs == numPairs)
-+ break;
-+ curBack = matches[offs + 1];
-+ if (curBack >= kNumFullDistances)
-+ GetPosSlot2(curBack, posSlot);
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
-+
-+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
-+{
-+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
-+ const Byte *data;
-+ const UInt32 *matches;
-+
-+ if (p->additionalOffset == 0)
-+ mainLen = ReadMatchDistances(p, &numPairs);
-+ else
-+ {
-+ mainLen = p->longestMatchLength;
-+ numPairs = p->numPairs;
-+ }
-+
-+ numAvail = p->numAvail;
-+ *backRes = (UInt32)-1;
-+ if (numAvail < 2)
-+ return 1;
-+ if (numAvail > LZMA_MATCH_LEN_MAX)
-+ numAvail = LZMA_MATCH_LEN_MAX;
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+
-+ repLen = repIndex = 0;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 len;
-+ const Byte *data2 = data - (p->reps[i] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ continue;
-+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
-+ if (len >= p->numFastBytes)
-+ {
-+ *backRes = i;
-+ MovePos(p, len - 1);
-+ return len;
-+ }
-+ if (len > repLen)
-+ {
-+ repIndex = i;
-+ repLen = len;
-+ }
-+ }
-+
-+ matches = p->matches;
-+ if (mainLen >= p->numFastBytes)
-+ {
-+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
-+ MovePos(p, mainLen - 1);
-+ return mainLen;
-+ }
-+
-+ mainDist = 0; /* for GCC */
-+ if (mainLen >= 2)
-+ {
-+ mainDist = matches[numPairs - 1];
-+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
-+ {
-+ if (!ChangePair(matches[numPairs - 3], mainDist))
-+ break;
-+ numPairs -= 2;
-+ mainLen = matches[numPairs - 2];
-+ mainDist = matches[numPairs - 1];
-+ }
-+ if (mainLen == 2 && mainDist >= 0x80)
-+ mainLen = 1;
-+ }
-+
-+ if (repLen >= 2 && (
-+ (repLen + 1 >= mainLen) ||
-+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
-+ (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
-+ {
-+ *backRes = repIndex;
-+ MovePos(p, repLen - 1);
-+ return repLen;
-+ }
-+
-+ if (mainLen < 2 || numAvail <= 2)
-+ return 1;
-+
-+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
-+ if (p->longestMatchLength >= 2)
-+ {
-+ UInt32 newDistance = matches[p->numPairs - 1];
-+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
-+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
-+ (p->longestMatchLength > mainLen + 1) ||
-+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
-+ return 1;
-+ }
-+
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 len, limit;
-+ const Byte *data2 = data - (p->reps[i] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ continue;
-+ limit = mainLen - 1;
-+ for (len = 2; len < limit && data[len] == data2[len]; len++);
-+ if (len >= limit)
-+ return 1;
-+ }
-+ *backRes = mainDist + LZMA_NUM_REPS;
-+ MovePos(p, mainLen - 2);
-+ return mainLen;
-+}
-+
-+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
-+{
-+ UInt32 len;
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-+ p->state = kMatchNextStates[p->state];
-+ len = LZMA_MATCH_LEN_MIN;
-+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
-+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
-+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
-+}
-+
-+static SRes CheckErrors(CLzmaEnc *p)
-+{
-+ if (p->result != SZ_OK)
-+ return p->result;
-+ if (p->rc.res != SZ_OK)
-+ p->result = SZ_ERROR_WRITE;
-+ if (p->matchFinderBase.result != SZ_OK)
-+ p->result = SZ_ERROR_READ;
-+ if (p->result != SZ_OK)
-+ p->finished = True;
-+ return p->result;
-+}
-+
-+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
-+{
-+ /* ReleaseMFStream(); */
-+ p->finished = True;
-+ if (p->writeEndMark)
-+ WriteEndMarker(p, nowPos & p->pbMask);
-+ RangeEnc_FlushData(&p->rc);
-+ RangeEnc_FlushStream(&p->rc);
-+ return CheckErrors(p);
-+}
-+
-+static void FillAlignPrices(CLzmaEnc *p)
-+{
-+ UInt32 i;
-+ for (i = 0; i < kAlignTableSize; i++)
-+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
-+ p->alignPriceCount = 0;
-+}
-+
-+static void FillDistancesPrices(CLzmaEnc *p)
-+{
-+ UInt32 tempPrices[kNumFullDistances];
-+ UInt32 i, lenToPosState;
-+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
-+ {
-+ UInt32 posSlot = GetPosSlot1(i);
-+ UInt32 footerBits = ((posSlot >> 1) - 1);
-+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
-+ }
-+
-+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
-+ {
-+ UInt32 posSlot;
-+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
-+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
-+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
-+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
-+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
-+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
-+
-+ {
-+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
-+ UInt32 i;
-+ for (i = 0; i < kStartPosModelIndex; i++)
-+ distancesPrices[i] = posSlotPrices[i];
-+ for (; i < kNumFullDistances; i++)
-+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
-+ }
-+ }
-+ p->matchPriceCount = 0;
-+}
-+
-+static void LzmaEnc_Construct(CLzmaEnc *p)
-+{
-+ RangeEnc_Construct(&p->rc);
-+ MatchFinder_Construct(&p->matchFinderBase);
-+ #ifndef _7ZIP_ST
-+ MatchFinderMt_Construct(&p->matchFinderMt);
-+ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
-+ #endif
-+
-+ {
-+ CLzmaEncProps props;
-+ LzmaEncProps_Init(&props);
-+ LzmaEnc_SetProps(p, &props);
-+ }
-+
-+ #ifndef LZMA_LOG_BSR
-+ LzmaEnc_FastPosInit(p->g_FastPos);
-+ #endif
-+
-+ LzmaEnc_InitPriceTables(p->ProbPrices);
-+ p->litProbs = 0;
-+ p->saveState.litProbs = 0;
-+}
-+
-+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
-+{
-+ void *p;
-+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
-+ if (p != 0)
-+ LzmaEnc_Construct((CLzmaEnc *)p);
-+ return p;
-+}
-+
-+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->litProbs);
-+ alloc->Free(alloc, p->saveState.litProbs);
-+ p->litProbs = 0;
-+ p->saveState.litProbs = 0;
-+}
-+
-+static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ #ifndef _7ZIP_ST
-+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
-+ #endif
-+ MatchFinder_Free(&p->matchFinderBase, allocBig);
-+ LzmaEnc_FreeLits(p, alloc);
-+ RangeEnc_Free(&p->rc, alloc);
-+}
-+
-+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
-+ alloc->Free(alloc, p);
-+}
-+
-+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
-+{
-+ UInt32 nowPos32, startPos32;
-+ if (p->needInit)
-+ {
-+ p->matchFinder.Init(p->matchFinderObj);
-+ p->needInit = 0;
-+ }
-+
-+ if (p->finished)
-+ return p->result;
-+ RINOK(CheckErrors(p));
-+
-+ nowPos32 = (UInt32)p->nowPos64;
-+ startPos32 = nowPos32;
-+
-+ if (p->nowPos64 == 0)
-+ {
-+ UInt32 numPairs;
-+ Byte curByte;
-+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-+ return Flush(p, nowPos32);
-+ ReadMatchDistances(p, &numPairs);
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
-+ p->state = kLiteralNextStates[p->state];
-+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
-+ LitEnc_Encode(&p->rc, p->litProbs, curByte);
-+ p->additionalOffset--;
-+ nowPos32++;
-+ }
-+
-+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
-+ for (;;)
-+ {
-+ UInt32 pos, len, posState;
-+
-+ if (p->fastMode)
-+ len = GetOptimumFast(p, &pos);
-+ else
-+ len = GetOptimum(p, nowPos32, &pos);
-+
-+ #ifdef SHOW_STAT2
-+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
-+ #endif
-+
-+ posState = nowPos32 & p->pbMask;
-+ if (len == 1 && pos == (UInt32)-1)
-+ {
-+ Byte curByte;
-+ CLzmaProb *probs;
-+ const Byte *data;
-+
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-+ curByte = *data;
-+ probs = LIT_PROBS(nowPos32, *(data - 1));
-+ if (IsCharState(p->state))
-+ LitEnc_Encode(&p->rc, probs, curByte);
-+ else
-+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
-+ p->state = kLiteralNextStates[p->state];
-+ }
-+ else
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-+ if (pos < LZMA_NUM_REPS)
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
-+ if (pos == 0)
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
-+ }
-+ else
-+ {
-+ UInt32 distance = p->reps[pos];
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
-+ if (pos == 1)
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
-+ else
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
-+ if (pos == 3)
-+ p->reps[3] = p->reps[2];
-+ p->reps[2] = p->reps[1];
-+ }
-+ p->reps[1] = p->reps[0];
-+ p->reps[0] = distance;
-+ }
-+ if (len == 1)
-+ p->state = kShortRepNextStates[p->state];
-+ else
-+ {
-+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+ p->state = kRepNextStates[p->state];
-+ }
-+ }
-+ else
-+ {
-+ UInt32 posSlot;
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-+ p->state = kMatchNextStates[p->state];
-+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+ pos -= LZMA_NUM_REPS;
-+ GetPosSlot(pos, posSlot);
-+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
-+
-+ if (posSlot >= kStartPosModelIndex)
-+ {
-+ UInt32 footerBits = ((posSlot >> 1) - 1);
-+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-+ UInt32 posReduced = pos - base;
-+
-+ if (posSlot < kEndPosModelIndex)
-+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
-+ else
-+ {
-+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
-+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
-+ p->alignPriceCount++;
-+ }
-+ }
-+ p->reps[3] = p->reps[2];
-+ p->reps[2] = p->reps[1];
-+ p->reps[1] = p->reps[0];
-+ p->reps[0] = pos;
-+ p->matchPriceCount++;
-+ }
-+ }
-+ p->additionalOffset -= len;
-+ nowPos32 += len;
-+ if (p->additionalOffset == 0)
-+ {
-+ UInt32 processed;
-+ if (!p->fastMode)
-+ {
-+ if (p->matchPriceCount >= (1 << 7))
-+ FillDistancesPrices(p);
-+ if (p->alignPriceCount >= kAlignTableSize)
-+ FillAlignPrices(p);
-+ }
-+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-+ break;
-+ processed = nowPos32 - startPos32;
-+ if (useLimits)
-+ {
-+ if (processed + kNumOpts + 300 >= maxUnpackSize ||
-+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
-+ break;
-+ }
-+ else if (processed >= (1 << 15))
-+ {
-+ p->nowPos64 += nowPos32 - startPos32;
-+ return CheckErrors(p);
-+ }
-+ }
-+ }
-+ p->nowPos64 += nowPos32 - startPos32;
-+ return Flush(p, nowPos32);
-+}
-+
-+#define kBigHashDicLimit ((UInt32)1 << 24)
-+
-+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ UInt32 beforeSize = kNumOpts;
-+ Bool btMode;
-+ if (!RangeEnc_Alloc(&p->rc, alloc))
-+ return SZ_ERROR_MEM;
-+ btMode = (p->matchFinderBase.btMode != 0);
-+ #ifndef _7ZIP_ST
-+ p->mtMode = (p->multiThread && !p->fastMode && btMode);
-+ #endif
-+
-+ {
-+ unsigned lclp = p->lc + p->lp;
-+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
-+ {
-+ LzmaEnc_FreeLits(p, alloc);
-+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-+ if (p->litProbs == 0 || p->saveState.litProbs == 0)
-+ {
-+ LzmaEnc_FreeLits(p, alloc);
-+ return SZ_ERROR_MEM;
-+ }
-+ p->lclp = lclp;
-+ }
-+ }
-+
-+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
-+
-+ if (beforeSize + p->dictSize < keepWindowSize)
-+ beforeSize = keepWindowSize - p->dictSize;
-+
-+ #ifndef _7ZIP_ST
-+ if (p->mtMode)
-+ {
-+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
-+ p->matchFinderObj = &p->matchFinderMt;
-+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
-+ }
-+ else
-+ #endif
-+ {
-+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
-+ return SZ_ERROR_MEM;
-+ p->matchFinderObj = &p->matchFinderBase;
-+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
-+ }
-+ return SZ_OK;
-+}
-+
-+static void LzmaEnc_Init(CLzmaEnc *p)
-+{
-+ UInt32 i;
-+ p->state = 0;
-+ for (i = 0 ; i < LZMA_NUM_REPS; i++)
-+ p->reps[i] = 0;
-+
-+ RangeEnc_Init(&p->rc);
-+
-+
-+ for (i = 0; i < kNumStates; i++)
-+ {
-+ UInt32 j;
-+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
-+ {
-+ p->isMatch[i][j] = kProbInitValue;
-+ p->isRep0Long[i][j] = kProbInitValue;
-+ }
-+ p->isRep[i] = kProbInitValue;
-+ p->isRepG0[i] = kProbInitValue;
-+ p->isRepG1[i] = kProbInitValue;
-+ p->isRepG2[i] = kProbInitValue;
-+ }
-+
-+ {
-+ UInt32 num = 0x300 << (p->lp + p->lc);
-+ for (i = 0; i < num; i++)
-+ p->litProbs[i] = kProbInitValue;
-+ }
-+
-+ {
-+ for (i = 0; i < kNumLenToPosStates; i++)
-+ {
-+ CLzmaProb *probs = p->posSlotEncoder[i];
-+ UInt32 j;
-+ for (j = 0; j < (1 << kNumPosSlotBits); j++)
-+ probs[j] = kProbInitValue;
-+ }
-+ }
-+ {
-+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
-+ p->posEncoders[i] = kProbInitValue;
-+ }
-+
-+ LenEnc_Init(&p->lenEnc.p);
-+ LenEnc_Init(&p->repLenEnc.p);
-+
-+ for (i = 0; i < (1 << kNumAlignBits); i++)
-+ p->posAlignEncoder[i] = kProbInitValue;
-+
-+ p->optimumEndIndex = 0;
-+ p->optimumCurrentIndex = 0;
-+ p->additionalOffset = 0;
-+
-+ p->pbMask = (1 << p->pb) - 1;
-+ p->lpMask = (1 << p->lp) - 1;
-+}
-+
-+static void LzmaEnc_InitPrices(CLzmaEnc *p)
-+{
-+ if (!p->fastMode)
-+ {
-+ FillDistancesPrices(p);
-+ FillAlignPrices(p);
-+ }
-+
-+ p->lenEnc.tableSize =
-+ p->repLenEnc.tableSize =
-+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
-+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
-+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
-+}
-+
-+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ UInt32 i;
-+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
-+ if (p->dictSize <= ((UInt32)1 << i))
-+ break;
-+ p->distTableSize = i * 2;
-+
-+ p->finished = False;
-+ p->result = SZ_OK;
-+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
-+ LzmaEnc_Init(p);
-+ LzmaEnc_InitPrices(p);
-+ p->nowPos64 = 0;
-+ return SZ_OK;
-+}
-+
-+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
-+{
-+ p->matchFinderBase.directInput = 1;
-+ p->matchFinderBase.bufferBase = (Byte *)src;
-+ p->matchFinderBase.directInputRem = srcLen;
-+}
-+
-+static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
-+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ LzmaEnc_SetInputBuf(p, src, srcLen);
-+ p->needInit = 1;
-+
-+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-+}
-+
-+static void LzmaEnc_Finish(CLzmaEncHandle pp)
-+{
-+ #ifndef _7ZIP_ST
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ if (p->mtMode)
-+ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
-+ #else
-+ pp = pp;
-+ #endif
-+}
-+
-+typedef struct
-+{
-+ ISeqOutStream funcTable;
-+ Byte *data;
-+ SizeT rem;
-+ Bool overflow;
-+} CSeqOutStreamBuf;
-+
-+static size_t MyWrite(void *pp, const void *data, size_t size)
-+{
-+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
-+ if (p->rem < size)
-+ {
-+ size = p->rem;
-+ p->overflow = True;
-+ }
-+ memcpy(p->data, data, size);
-+ p->rem -= size;
-+ p->data += size;
-+ return size;
-+}
-+
-+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
-+{
-+ SRes res = SZ_OK;
-+
-+ #ifndef _7ZIP_ST
-+ Byte allocaDummy[0x300];
-+ int i = 0;
-+ for (i = 0; i < 16; i++)
-+ allocaDummy[i] = (Byte)i;
-+ #endif
-+
-+ for (;;)
-+ {
-+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
-+ if (res != SZ_OK || p->finished != 0)
-+ break;
-+ if (progress != 0)
-+ {
-+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
-+ if (res != SZ_OK)
-+ {
-+ res = SZ_ERROR_PROGRESS;
-+ break;
-+ }
-+ }
-+ }
-+ LzmaEnc_Finish(p);
-+ return res;
-+}
-+
-+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ int i;
-+ UInt32 dictSize = p->dictSize;
-+ if (*size < LZMA_PROPS_SIZE)
-+ return SZ_ERROR_PARAM;
-+ *size = LZMA_PROPS_SIZE;
-+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
-+
-+ for (i = 11; i <= 30; i++)
-+ {
-+ if (dictSize <= ((UInt32)2 << i))
-+ {
-+ dictSize = (2 << i);
-+ break;
-+ }
-+ if (dictSize <= ((UInt32)3 << i))
-+ {
-+ dictSize = (3 << i);
-+ break;
-+ }
-+ }
-+
-+ for (i = 0; i < 4; i++)
-+ props[1 + i] = (Byte)(dictSize >> (8 * i));
-+ return SZ_OK;
-+}
-+
-+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ SRes res;
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+
-+ CSeqOutStreamBuf outStream;
-+
-+ LzmaEnc_SetInputBuf(p, src, srcLen);
-+
-+ outStream.funcTable.Write = MyWrite;
-+ outStream.data = dest;
-+ outStream.rem = *destLen;
-+ outStream.overflow = False;
-+
-+ p->writeEndMark = writeEndMark;
-+
-+ p->rc.outStream = &outStream.funcTable;
-+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
-+ if (res == SZ_OK)
-+ res = LzmaEnc_Encode2(p, progress);
-+
-+ *destLen -= outStream.rem;
-+ if (outStream.overflow)
-+ return SZ_ERROR_OUTPUT_EOF;
-+ return res;
-+}
---- /dev/null
-+++ b/lib/lzma/Makefile
-@@ -0,0 +1,7 @@
-+lzma_compress-objs := LzFind.o LzmaEnc.o
-+lzma_decompress-objs := LzmaDec.o
-+
-+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o
-+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o
-+
-+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h
diff --git a/target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch b/target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch
deleted file mode 100644
index 744fbd0e21..0000000000
--- a/target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: fs: jffs2: EOF marker
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- fs/jffs2/build.c | 10 ++++++++++
- fs/jffs2/scan.c | 21 +++++++++++++++++++--
- 2 files changed, 29 insertions(+), 2 deletions(-)
-
---- a/fs/jffs2/build.c
-+++ b/fs/jffs2/build.c
-@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct
- dbg_fsbuild("scanned flash completely\n");
- jffs2_dbg_dump_block_lists_nolock(c);
-
-+ if (c->flags & (1 << 7)) {
-+ printk("%s(): unlocking the mtd device... ", __func__);
-+ mtd_unlock(c->mtd, 0, c->mtd->size);
-+ printk("done.\n");
-+
-+ printk("%s(): erasing all blocks after the end marker... ", __func__);
-+ jffs2_erase_pending_blocks(c, -1);
-+ printk("done.\n");
-+ }
-+
- dbg_fsbuild("pass 1 starting\n");
- c->flags |= JFFS2_SB_FLAG_BUILDING;
- /* Now scan the directory tree, increasing nlink according to every dirent found. */
---- a/fs/jffs2/scan.c
-+++ b/fs/jffs2/scan.c
-@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in
- /* reset summary info for next eraseblock scan */
- jffs2_sum_reset_collected(s);
-
-- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
-- buf_size, s);
-+ if (c->flags & (1 << 7)) {
-+ if (mtd_block_isbad(c->mtd, jeb->offset))
-+ ret = BLK_STATE_BADBLOCK;
-+ else
-+ ret = BLK_STATE_ALLFF;
-+ } else
-+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
-+ buf_size, s);
-
- if (ret < 0)
- goto out;
-@@ -567,6 +573,17 @@ full_scan:
- return err;
- }
-
-+ if ((buf[0] == 0xde) &&
-+ (buf[1] == 0xad) &&
-+ (buf[2] == 0xc0) &&
-+ (buf[3] == 0xde)) {
-+ /* end of filesystem. erase everything after this point */
-+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
-+ c->flags |= (1 << 7);
-+
-+ return BLK_STATE_ALLFF;
-+ }
-+
- /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
- ofs = 0;
- max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
diff --git a/target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch
deleted file mode 100644
index a88e3d7d9a..0000000000
--- a/target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: netfilter: add support for flushing conntrack via /proc
-
-lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++-
- 1 file changed, 58 insertions(+), 1 deletion(-)
-
---- a/net/netfilter/nf_conntrack_standalone.c
-+++ b/net/netfilter/nf_conntrack_standalone.c
-@@ -9,6 +9,7 @@
- #include <linux/percpu.h>
- #include <linux/netdevice.h>
- #include <linux/security.h>
-+#include <linux/inet.h>
- #include <net/net_namespace.h>
- #ifdef CONFIG_SYSCTL
- #include <linux/sysctl.h>
-@@ -462,6 +463,56 @@ static int ct_cpu_seq_show(struct seq_fi
- return 0;
- }
-
-+struct kill_request {
-+ u16 family;
-+ union nf_inet_addr addr;
-+};
-+
-+static int kill_matching(struct nf_conn *i, void *data)
-+{
-+ struct kill_request *kr = data;
-+ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-+ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple;
-+
-+ if (!kr->family)
-+ return 1;
-+
-+ if (t1->src.l3num != kr->family)
-+ return 0;
-+
-+ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) ||
-+ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) ||
-+ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) ||
-+ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3));
-+}
-+
-+static int ct_file_write(struct file *file, char *buf, size_t count)
-+{
-+ struct seq_file *seq = file->private_data;
-+ struct net *net = seq_file_net(seq);
-+ struct kill_request kr = { };
-+
-+ if (count == 0)
-+ return 0;
-+
-+ if (count >= INET6_ADDRSTRLEN)
-+ count = INET6_ADDRSTRLEN - 1;
-+
-+ if (strnchr(buf, count, ':')) {
-+ kr.family = AF_INET6;
-+ if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL))
-+ return -EINVAL;
-+ } else if (strnchr(buf, count, '.')) {
-+ kr.family = AF_INET;
-+ if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL))
-+ return -EINVAL;
-+ }
-+
-+ nf_ct_iterate_cleanup_net(net, kill_matching, &kr, 0, 0);
-+
-+ return 0;
-+}
-+
- static const struct seq_operations ct_cpu_seq_ops = {
- .start = ct_cpu_seq_start,
- .next = ct_cpu_seq_next,
-@@ -475,8 +526,9 @@ static int nf_conntrack_standalone_init_
- kuid_t root_uid;
- kgid_t root_gid;
-
-- pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops,
-- sizeof(struct ct_iter_state));
-+ pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net,
-+ &ct_seq_ops, &ct_file_write,
-+ sizeof(struct ct_iter_state), NULL);
- if (!pde)
- goto out_nf_conntrack;
-
diff --git a/target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch
deleted file mode 100644
index 8b1e70bd0e..0000000000
--- a/target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 +
- net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++
- 2 files changed, 38 insertions(+)
-
---- a/include/uapi/linux/netfilter_ipv4/ip_tables.h
-+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
-@@ -89,6 +89,7 @@ struct ipt_ip {
- #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
- #define IPT_F_GOTO 0x02 /* Set if jump is a goto */
- #define IPT_F_MASK 0x03 /* All possible flag bits mask. */
-+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */
-
- /* Values for "inv" field in struct ipt_ip. */
- #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -50,6 +50,9 @@ ip_packet_match(const struct iphdr *ip,
- {
- unsigned long ret;
-
-+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
-+ return true;
-+
- if (NF_INVF(ipinfo, IPT_INV_SRCIP,
- (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
- NF_INVF(ipinfo, IPT_INV_DSTIP,
-@@ -80,6 +83,29 @@ ip_packet_match(const struct iphdr *ip,
- return true;
- }
-
-+static void
-+ip_checkdefault(struct ipt_ip *ip)
-+{
-+ static const char iface_mask[IFNAMSIZ] = {};
-+
-+ if (ip->invflags || ip->flags & IPT_F_FRAG)
-+ return;
-+
-+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
-+ return;
-+
-+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
-+ return;
-+
-+ if (ip->smsk.s_addr || ip->dmsk.s_addr)
-+ return;
-+
-+ if (ip->proto)
-+ return;
-+
-+ ip->flags |= IPT_F_NO_DEF_MATCH;
-+}
-+
- static bool
- ip_checkentry(const struct ipt_ip *ip)
- {
-@@ -524,6 +550,8 @@ find_check_entry(struct ipt_entry *e, st
- struct xt_mtchk_param mtpar;
- struct xt_entry_match *ematch;
-
-+ ip_checkdefault(&e->ip);
-+
- if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
- return -ENOMEM;
-
-@@ -818,6 +846,7 @@ copy_entries_to_user(unsigned int total_
- const struct xt_table_info *private = table->private;
- int ret = 0;
- const void *loc_cpu_entry;
-+ u8 flags;
-
- counters = alloc_counters(table);
- if (IS_ERR(counters))
-@@ -845,6 +874,14 @@ copy_entries_to_user(unsigned int total_
- goto free_counters;
- }
-
-+ flags = e->ip.flags & IPT_F_MASK;
-+ if (copy_to_user(userptr + off
-+ + offsetof(struct ipt_entry, ip.flags),
-+ &flags, sizeof(flags)) != 0) {
-+ ret = -EFAULT;
-+ goto free_counters;
-+ }
-+
- for (i = sizeof(struct ipt_entry);
- i < e->target_offset;
- i += m->u.match_size) {
-@@ -1226,12 +1263,15 @@ compat_copy_entry_to_user(struct ipt_ent
- compat_uint_t origsize;
- const struct xt_entry_match *ematch;
- int ret = 0;
-+ u8 flags = e->ip.flags & IPT_F_MASK;
-
- origsize = *size;
- ce = *dstptr;
- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
- copy_to_user(&ce->counters, &counters[i],
-- sizeof(counters[i])) != 0)
-+ sizeof(counters[i])) != 0 ||
-+ copy_to_user(&ce->ip.flags, &flags,
-+ sizeof(flags)) != 0)
- return -EFAULT;
-
- *dstptr += sizeof(struct compat_ipt_entry);
diff --git a/target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch
deleted file mode 100644
index baf738a8d2..0000000000
--- a/target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: netfilter: match bypass default table
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++-----------
- 1 file changed, 58 insertions(+), 21 deletions(-)
-
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -246,6 +246,33 @@ struct ipt_entry *ipt_next_entry(const s
- return (void *)entry + entry->next_offset;
- }
-
-+static bool
-+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
-+{
-+ struct xt_entry_target *t;
-+ struct xt_standard_target *st;
-+
-+ if (e->target_offset != sizeof(struct ipt_entry))
-+ return false;
-+
-+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
-+ return false;
-+
-+ t = ipt_get_target(e);
-+ if (t->u.kernel.target->target)
-+ return false;
-+
-+ st = (struct xt_standard_target *) t;
-+ if (st->verdict == XT_RETURN)
-+ return false;
-+
-+ if (st->verdict >= 0)
-+ return false;
-+
-+ *verdict = (unsigned)(-st->verdict) - 1;
-+ return true;
-+}
-+
- /* Returns one of the generic firewall policies, like NF_ACCEPT. */
- unsigned int
- ipt_do_table(struct sk_buff *skb,
-@@ -266,27 +293,28 @@ ipt_do_table(struct sk_buff *skb,
- unsigned int addend;
-
- /* Initialization */
-+ WARN_ON(!(table->valid_hooks & (1 << hook)));
-+ local_bh_disable();
-+ private = READ_ONCE(table->private); /* Address dependency. */
-+ cpu = smp_processor_id();
-+ table_base = private->entries;
-+
-+ e = get_entry(table_base, private->hook_entry[hook]);
-+ if (ipt_handle_default_rule(e, &verdict)) {
-+ struct xt_counters *counter;
-+
-+ counter = xt_get_this_cpu_counter(&e->counters);
-+ ADD_COUNTER(*counter, skb->len, 1);
-+ local_bh_enable();
-+ return verdict;
-+ }
-+
- stackidx = 0;
- ip = ip_hdr(skb);
- indev = state->in ? state->in->name : nulldevname;
- outdev = state->out ? state->out->name : nulldevname;
-- /* We handle fragments by dealing with the first fragment as
-- * if it was a normal packet. All other fragments are treated
-- * normally, except that they will NEVER match rules that ask
-- * things we don't know, ie. tcp syn flag or ports). If the
-- * rule is also a fragment-specific rule, non-fragments won't
-- * match it. */
-- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
-- acpar.thoff = ip_hdrlen(skb);
-- acpar.hotdrop = false;
-- acpar.state = state;
-
-- WARN_ON(!(table->valid_hooks & (1 << hook)));
-- local_bh_disable();
- addend = xt_write_recseq_begin();
-- private = READ_ONCE(table->private); /* Address dependency. */
-- cpu = smp_processor_id();
-- table_base = private->entries;
- jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
-
- /* Switch to alternate jumpstack if we're being invoked via TEE.
-@@ -299,7 +327,16 @@ ipt_do_table(struct sk_buff *skb,
- if (static_key_false(&xt_tee_enabled))
- jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
-
-- e = get_entry(table_base, private->hook_entry[hook]);
-+ /* We handle fragments by dealing with the first fragment as
-+ * if it was a normal packet. All other fragments are treated
-+ * normally, except that they will NEVER match rules that ask
-+ * things we don't know, ie. tcp syn flag or ports). If the
-+ * rule is also a fragment-specific rule, non-fragments won't
-+ * match it. */
-+ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
-+ acpar.thoff = ip_hdrlen(skb);
-+ acpar.hotdrop = false;
-+ acpar.state = state;
-
- do {
- const struct xt_entry_target *t;
diff --git a/target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch
deleted file mode 100644
index 79da6778b6..0000000000
--- a/target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: netfilter: reduce match memory access
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/ipv4/netfilter/ip_tables.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -53,9 +53,9 @@ ip_packet_match(const struct iphdr *ip,
- if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
- return true;
-
-- if (NF_INVF(ipinfo, IPT_INV_SRCIP,
-+ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr &&
- (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
-- NF_INVF(ipinfo, IPT_INV_DSTIP,
-+ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr &&
- (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr))
- return false;
-
diff --git a/target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch
deleted file mode 100644
index 4b4825ae3b..0000000000
--- a/target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
-Date: Mon, 21 Aug 2017 11:14:14 +0300
-Subject: [PATCH] net_sched/codel: do not defer queue length update
-
-When codel wants to drop last packet in ->dequeue() it cannot call
-qdisc_tree_reduce_backlog() right away - it will notify parent qdisc
-about zero qlen and HTB/HFSC will deactivate class. The same class will
-be deactivated second time by caller of ->dequeue(). Currently codel and
-fq_codel defer update. This triggers warning in HFSC when it's qlen != 0
-but there is no active classes.
-
-This patch update parent queue length immediately: just temporary increase
-qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation
-if we have skb to return.
-
-This might open another problem in HFSC - now operation peek could fail and
-deactivate parent class.
-
-Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581
----
-
---- a/net/sched/sch_codel.c
-+++ b/net/sched/sch_codel.c
-@@ -95,11 +95,17 @@ static struct sk_buff *codel_qdisc_deque
- &q->stats, qdisc_pkt_len, codel_get_enqueue_time,
- drop_func, dequeue_func);
-
-- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
-- * or HTB crashes. Defer it for next round.
-+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
-+ * parent class, dequeue in parent qdisc will do the same if we
-+ * return skb. Temporary increment qlen if we have skb.
- */
-- if (q->stats.drop_count && sch->q.qlen) {
-- qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
-+ if (q->stats.drop_count) {
-+ if (skb)
-+ sch->q.qlen++;
-+ qdisc_tree_reduce_backlog(sch, q->stats.drop_count,
-+ q->stats.drop_len);
-+ if (skb)
-+ sch->q.qlen--;
- q->stats.drop_count = 0;
- q->stats.drop_len = 0;
- }
---- a/net/sched/sch_fq_codel.c
-+++ b/net/sched/sch_fq_codel.c
-@@ -304,6 +304,21 @@ begin:
- &flow->cvars, &q->cstats, qdisc_pkt_len,
- codel_get_enqueue_time, drop_func, dequeue_func);
-
-+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
-+ * parent class, dequeue in parent qdisc will do the same if we
-+ * return skb. Temporary increment qlen if we have skb.
-+ */
-+ if (q->cstats.drop_count) {
-+ if (skb)
-+ sch->q.qlen++;
-+ qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
-+ q->cstats.drop_len);
-+ if (skb)
-+ sch->q.qlen--;
-+ q->cstats.drop_count = 0;
-+ q->cstats.drop_len = 0;
-+ }
-+
- if (!skb) {
- /* force a pass through old_flows to prevent starvation */
- if ((head == &q->new_flows) && !list_empty(&q->old_flows))
-@@ -314,15 +329,6 @@ begin:
- }
- qdisc_bstats_update(sch, skb);
- flow->deficit -= qdisc_pkt_len(skb);
-- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
-- * or HTB crashes. Defer it for next round.
-- */
-- if (q->cstats.drop_count && sch->q.qlen) {
-- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
-- q->cstats.drop_len);
-- q->cstats.drop_count = 0;
-- q->cstats.drop_len = 0;
-- }
- return skb;
- }
-
diff --git a/target/linux/generic/pending-5.15/630-packet_socket_type.patch b/target/linux/generic/pending-5.15/630-packet_socket_type.patch
deleted file mode 100644
index c36e9e9fbb..0000000000
--- a/target/linux/generic/pending-5.15/630-packet_socket_type.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: net: add an optimization for dealing with raw sockets
-
-lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/uapi/linux/if_packet.h | 3 +++
- net/packet/af_packet.c | 34 +++++++++++++++++++++++++++-------
- net/packet/internal.h | 1 +
- 3 files changed, 31 insertions(+), 7 deletions(-)
-
---- a/include/uapi/linux/if_packet.h
-+++ b/include/uapi/linux/if_packet.h
-@@ -33,6 +33,8 @@ struct sockaddr_ll {
- #define PACKET_KERNEL 7 /* To kernel space */
- /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
- #define PACKET_FASTROUTE 6 /* Fastrouted frame */
-+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
-+
-
- /* Packet socket options */
-
-@@ -59,6 +61,7 @@ struct sockaddr_ll {
- #define PACKET_ROLLOVER_STATS 21
- #define PACKET_FANOUT_DATA 22
- #define PACKET_IGNORE_OUTGOING 23
-+#define PACKET_RECV_TYPE 24
-
- #define PACKET_FANOUT_HASH 0
- #define PACKET_FANOUT_LB 1
---- a/net/packet/af_packet.c
-+++ b/net/packet/af_packet.c
-@@ -1830,6 +1830,7 @@ static int packet_rcv_spkt(struct sk_buf
- {
- struct sock *sk;
- struct sockaddr_pkt *spkt;
-+ struct packet_sock *po;
-
- /*
- * When we registered the protocol we saved the socket in the data
-@@ -1837,6 +1838,7 @@ static int packet_rcv_spkt(struct sk_buf
- */
-
- sk = pt->af_packet_priv;
-+ po = pkt_sk(sk);
-
- /*
- * Yank back the headers [hope the device set this
-@@ -1849,7 +1851,7 @@ static int packet_rcv_spkt(struct sk_buf
- * so that this procedure is noop.
- */
-
-- if (skb->pkt_type == PACKET_LOOPBACK)
-+ if (!(po->pkt_type & (1 << skb->pkt_type)))
- goto out;
-
- if (!net_eq(dev_net(dev), sock_net(sk)))
-@@ -2095,12 +2097,12 @@ static int packet_rcv(struct sk_buff *sk
- unsigned int snaplen, res;
- bool is_drop_n_account = false;
-
-- if (skb->pkt_type == PACKET_LOOPBACK)
-- goto drop;
--
- sk = pt->af_packet_priv;
- po = pkt_sk(sk);
-
-+ if (!(po->pkt_type & (1 << skb->pkt_type)))
-+ goto drop;
-+
- if (!net_eq(dev_net(dev), sock_net(sk)))
- goto drop;
-
-@@ -2226,12 +2228,12 @@ static int tpacket_rcv(struct sk_buff *s
- BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
- BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
-
-- if (skb->pkt_type == PACKET_LOOPBACK)
-- goto drop;
--
- sk = pt->af_packet_priv;
- po = pkt_sk(sk);
-
-+ if (!(po->pkt_type & (1 << skb->pkt_type)))
-+ goto drop;
-+
- if (!net_eq(dev_net(dev), sock_net(sk)))
- goto drop;
-
-@@ -3346,6 +3348,7 @@ static int packet_create(struct net *net
- mutex_init(&po->pg_vec_lock);
- po->rollover = NULL;
- po->prot_hook.func = packet_rcv;
-+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
-
- if (sock->type == SOCK_PACKET)
- po->prot_hook.func = packet_rcv_spkt;
-@@ -3983,6 +3986,16 @@ packet_setsockopt(struct socket *sock, i
- WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit);
- return 0;
- }
-+ case PACKET_RECV_TYPE:
-+ {
-+ unsigned int val;
-+ if (optlen != sizeof(val))
-+ return -EINVAL;
-+ if (copy_from_sockptr(&val, optval, sizeof(val)))
-+ return -EFAULT;
-+ po->pkt_type = val & ~BIT(PACKET_LOOPBACK);
-+ return 0;
-+ }
- default:
- return -ENOPROTOOPT;
- }
-@@ -4039,6 +4052,13 @@ static int packet_getsockopt(struct sock
- case PACKET_VNET_HDR:
- val = po->has_vnet_hdr;
- break;
-+ case PACKET_RECV_TYPE:
-+ if (len > sizeof(unsigned int))
-+ len = sizeof(unsigned int);
-+ val = po->pkt_type;
-+
-+ data = &val;
-+ break;
- case PACKET_VERSION:
- val = po->tp_version;
- break;
---- a/net/packet/internal.h
-+++ b/net/packet/internal.h
-@@ -136,6 +136,7 @@ struct packet_sock {
- int (*xmit)(struct sk_buff *skb);
- struct packet_type prot_hook ____cacheline_aligned_in_smp;
- atomic_t tp_drops ____cacheline_aligned_in_smp;
-+ unsigned int pkt_type;
- };
-
- static inline struct packet_sock *pkt_sk(struct sock *sk)
diff --git a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch b/target/linux/generic/pending-5.15/655-increase_skb_pad.patch
deleted file mode 100644
index 5d100270a9..0000000000
--- a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance
-
-lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/skbuff.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -2821,7 +2821,7 @@ static inline int pskb_network_may_pull(
- * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
- */
- #ifndef NET_SKB_PAD
--#define NET_SKB_PAD max(32, L1_CACHE_BYTES)
-+#define NET_SKB_PAD max(64, L1_CACHE_BYTES)
- #endif
-
- int ___pskb_trim(struct sk_buff *skb, unsigned int len);
diff --git a/target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
deleted file mode 100644
index 3931278a6d..0000000000
--- a/target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
+++ /dev/null
@@ -1,511 +0,0 @@
-From: Steven Barth <steven@midlink.org>
-Subject: Add support for MAP-E FMRs (mesh mode)
-
-MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication
-between MAP CEs (mesh mode) without the need to forward such data to a
-border relay. This is similar to how 6rd works but for IPv4 over IPv6.
-
-Signed-off-by: Steven Barth <cyrus@openwrt.org>
----
- include/net/ip6_tunnel.h | 13 ++
- include/uapi/linux/if_tunnel.h | 13 ++
- net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++--
- 3 files changed, 291 insertions(+), 11 deletions(-)
-
---- a/include/net/ip6_tunnel.h
-+++ b/include/net/ip6_tunnel.h
-@@ -18,6 +18,18 @@
- /* determine capability on a per-packet basis */
- #define IP6_TNL_F_CAP_PER_PACKET 0x40000
-
-+/* IPv6 tunnel FMR */
-+struct __ip6_tnl_fmr {
-+ struct __ip6_tnl_fmr *next; /* next fmr in list */
-+ struct in6_addr ip6_prefix;
-+ struct in_addr ip4_prefix;
-+
-+ __u8 ip6_prefix_len;
-+ __u8 ip4_prefix_len;
-+ __u8 ea_len;
-+ __u8 offset;
-+};
-+
- struct __ip6_tnl_parm {
- char name[IFNAMSIZ]; /* name of tunnel device */
- int link; /* ifindex of underlying L2 interface */
-@@ -29,6 +41,7 @@ struct __ip6_tnl_parm {
- __u32 flags; /* tunnel flags */
- struct in6_addr laddr; /* local tunnel end-point address */
- struct in6_addr raddr; /* remote tunnel end-point address */
-+ struct __ip6_tnl_fmr *fmrs; /* FMRs */
-
- __be16 i_flags;
- __be16 o_flags;
---- a/include/uapi/linux/if_tunnel.h
-+++ b/include/uapi/linux/if_tunnel.h
-@@ -77,10 +77,23 @@ enum {
- IFLA_IPTUN_ENCAP_DPORT,
- IFLA_IPTUN_COLLECT_METADATA,
- IFLA_IPTUN_FWMARK,
-+ IFLA_IPTUN_FMRS,
- __IFLA_IPTUN_MAX,
- };
- #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
-
-+enum {
-+ IFLA_IPTUN_FMR_UNSPEC,
-+ IFLA_IPTUN_FMR_IP6_PREFIX,
-+ IFLA_IPTUN_FMR_IP4_PREFIX,
-+ IFLA_IPTUN_FMR_IP6_PREFIX_LEN,
-+ IFLA_IPTUN_FMR_IP4_PREFIX_LEN,
-+ IFLA_IPTUN_FMR_EA_LEN,
-+ IFLA_IPTUN_FMR_OFFSET,
-+ __IFLA_IPTUN_FMR_MAX,
-+};
-+#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1)
-+
- enum tunnel_encap_types {
- TUNNEL_ENCAP_NONE,
- TUNNEL_ENCAP_FOU,
---- a/net/ipv6/ip6_tunnel.c
-+++ b/net/ipv6/ip6_tunnel.c
-@@ -11,6 +11,9 @@
- * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c
- *
- * RFC 2473
-+ *
-+ * Changes:
-+ * Steven Barth <cyrus@openwrt.org>: MAP-E FMR support
- */
-
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-@@ -67,9 +70,9 @@ static bool log_ecn_error = true;
- module_param(log_ecn_error, bool, 0644);
- MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
-
--static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
-+static u32 HASH(const struct in6_addr *addr)
- {
-- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2);
-+ u32 hash = ipv6_addr_hash(addr);
-
- return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT);
- }
-@@ -114,17 +117,33 @@ static struct ip6_tnl *
- ip6_tnl_lookup(struct net *net, int link,
- const struct in6_addr *remote, const struct in6_addr *local)
- {
-- unsigned int hash = HASH(remote, local);
-+ unsigned int hash = HASH(local);
- struct ip6_tnl *t, *cand = NULL;
- struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
- struct in6_addr any;
-
- for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
- if (!ipv6_addr_equal(local, &t->parms.laddr) ||
-- !ipv6_addr_equal(remote, &t->parms.raddr) ||
- !(t->dev->flags & IFF_UP))
- continue;
-
-+ if (!ipv6_addr_equal(remote, &t->parms.raddr)) {
-+ struct __ip6_tnl_fmr *fmr;
-+ bool found = false;
-+
-+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
-+ if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix,
-+ fmr->ip6_prefix_len))
-+ continue;
-+
-+ found = true;
-+ break;
-+ }
-+
-+ if (!found)
-+ continue;
-+ }
-+
- if (link == t->parms.link)
- return t;
- else
-@@ -132,7 +151,7 @@ ip6_tnl_lookup(struct net *net, int link
- }
-
- memset(&any, 0, sizeof(any));
-- hash = HASH(&any, local);
-+ hash = HASH(local);
- for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
- if (!ipv6_addr_equal(local, &t->parms.laddr) ||
- !ipv6_addr_any(&t->parms.raddr) ||
-@@ -145,7 +164,7 @@ ip6_tnl_lookup(struct net *net, int link
- cand = t;
- }
-
-- hash = HASH(remote, &any);
-+ hash = HASH(&any);
- for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
- if (!ipv6_addr_equal(remote, &t->parms.raddr) ||
- !ipv6_addr_any(&t->parms.laddr) ||
-@@ -194,7 +213,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n,
-
- if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) {
- prio = 1;
-- h = HASH(remote, local);
-+ h = HASH(local);
- }
- return &ip6n->tnls[prio][h];
- }
-@@ -378,6 +397,12 @@ ip6_tnl_dev_uninit(struct net_device *de
- struct net *net = t->net;
- struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
-
-+ while (t->parms.fmrs) {
-+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
-+ kfree(t->parms.fmrs);
-+ t->parms.fmrs = next;
-+ }
-+
- if (dev == ip6n->fb_tnl_dev)
- RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL);
- else
-@@ -790,6 +815,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
- }
- EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl);
-
-+/**
-+ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR
-+ * @dest: destination IPv6 address buffer
-+ * @skb: received socket buffer
-+ * @fmr: MAP FMR
-+ * @xmit: Calculate for xmit or rcv
-+ **/
-+static void ip4ip6_fmr_calc(struct in6_addr *dest,
-+ const struct iphdr *iph, const uint8_t *end,
-+ const struct __ip6_tnl_fmr *fmr, bool xmit)
-+{
-+ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len);
-+ u8 *portp = NULL;
-+ bool use_dest_addr;
-+ const struct iphdr *dsth = iph;
-+
-+ if ((u8*)dsth >= end)
-+ return;
-+
-+ /* find significant IP header */
-+ if (iph->protocol == IPPROTO_ICMP) {
-+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
-+ if (ih && ((u8*)&ih[1]) <= end && (
-+ ih->type == ICMP_DEST_UNREACH ||
-+ ih->type == ICMP_SOURCE_QUENCH ||
-+ ih->type == ICMP_TIME_EXCEEDED ||
-+ ih->type == ICMP_PARAMETERPROB ||
-+ ih->type == ICMP_REDIRECT))
-+ dsth = (const struct iphdr*)&ih[1];
-+ }
-+
-+ /* in xmit-path use dest port by default and source port only if
-+ this is an ICMP reply to something else; vice versa in rcv-path */
-+ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph);
-+
-+ /* get dst port */
-+ if (((u8*)&dsth[1]) <= end && (
-+ dsth->protocol == IPPROTO_UDP ||
-+ dsth->protocol == IPPROTO_TCP ||
-+ dsth->protocol == IPPROTO_SCTP ||
-+ dsth->protocol == IPPROTO_DCCP)) {
-+ /* for UDP, TCP, SCTP and DCCP source and dest port
-+ follow IPv4 header directly */
-+ portp = ((u8*)dsth) + dsth->ihl * 4;
-+
-+ if (use_dest_addr)
-+ portp += sizeof(u16);
-+ } else if (iph->protocol == IPPROTO_ICMP) {
-+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
-+
-+ /* use icmp identifier as port */
-+ if (((u8*)&ih) <= end && (
-+ (use_dest_addr && (
-+ ih->type == ICMP_ECHOREPLY ||
-+ ih->type == ICMP_TIMESTAMPREPLY ||
-+ ih->type == ICMP_INFO_REPLY ||
-+ ih->type == ICMP_ADDRESSREPLY)) ||
-+ (!use_dest_addr && (
-+ ih->type == ICMP_ECHO ||
-+ ih->type == ICMP_TIMESTAMP ||
-+ ih->type == ICMP_INFO_REQUEST ||
-+ ih->type == ICMP_ADDRESS)
-+ )))
-+ portp = (u8*)&ih->un.echo.id;
-+ }
-+
-+ if ((portp && &portp[2] <= end) || psidlen == 0) {
-+ int frombyte = fmr->ip6_prefix_len / 8;
-+ int fromrem = fmr->ip6_prefix_len % 8;
-+ int bytes = sizeof(struct in6_addr) - frombyte;
-+ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr;
-+ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len);
-+ u64 t = 0;
-+
-+ /* extract PSID from port and add it to eabits */
-+ u16 psidbits = 0;
-+ if (psidlen > 0) {
-+ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]);
-+ psidbits >>= 16 - psidlen - fmr->offset;
-+ psidbits = (u16)(psidbits << (16 - psidlen));
-+ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen));
-+ }
-+
-+ /* rewrite destination address */
-+ *dest = fmr->ip6_prefix;
-+ memcpy(&dest->s6_addr[10], addr, sizeof(*addr));
-+ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen));
-+
-+ if (bytes > sizeof(u64))
-+ bytes = sizeof(u64);
-+
-+ /* insert eabits */
-+ memcpy(&t, &dest->s6_addr[frombyte], bytes);
-+ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1)
-+ << (64 - fmr->ea_len - fromrem));
-+ t = cpu_to_be64(t | (eabits >> fromrem));
-+ memcpy(&dest->s6_addr[frombyte], &t, bytes);
-+ }
-+}
-+
-+
- static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
- const struct tnl_ptk_info *tpi,
- struct metadata_dst *tun_dst,
-@@ -857,6 +983,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl
-
- memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
-
-+ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs &&
-+ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) {
-+ /* Packet didn't come from BR, so lookup FMR */
-+ struct __ip6_tnl_fmr *fmr;
-+ struct in6_addr expected = tunnel->parms.raddr;
-+ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next)
-+ if (ipv6_prefix_equal(&ipv6h->saddr,
-+ &fmr->ip6_prefix, fmr->ip6_prefix_len))
-+ break;
-+
-+ /* Check that IPv6 matches IPv4 source to prevent spoofing */
-+ if (fmr)
-+ ip4ip6_fmr_calc(&expected, ip_hdr(skb),
-+ skb_tail_pointer(skb), fmr, false);
-+
-+ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) {
-+ rcu_read_unlock();
-+ goto drop;
-+ }
-+ }
-+
- __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
-
- err = dscp_ecn_decapsulate(tunnel, ipv6h, skb);
-@@ -1004,6 +1151,7 @@ static void init_tel_txopt(struct ipv6_t
- opt->ops.opt_nflen = 8;
- }
-
-+
- /**
- * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
- * @t: the outgoing tunnel device
-@@ -1284,6 +1432,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
- u8 protocol)
- {
- struct ip6_tnl *t = netdev_priv(dev);
-+ struct __ip6_tnl_fmr *fmr;
- struct ipv6hdr *ipv6h;
- const struct iphdr *iph;
- int encap_limit = -1;
-@@ -1383,6 +1532,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
- fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
- dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield);
-
-+ /* try to find matching FMR */
-+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
-+ unsigned mshift = 32 - fmr->ip4_prefix_len;
-+ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift ==
-+ ntohl(ip_hdr(skb)->daddr) >> mshift)
-+ break;
-+ }
-+
-+ /* change dstaddr according to FMR */
-+ if (fmr)
-+ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true);
-+
- if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
- return -1;
-
-@@ -1536,6 +1697,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
- t->parms.link = p->link;
- t->parms.proto = p->proto;
- t->parms.fwmark = p->fwmark;
-+
-+ while (t->parms.fmrs) {
-+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
-+ kfree(t->parms.fmrs);
-+ t->parms.fmrs = next;
-+ }
-+ t->parms.fmrs = p->fmrs;
-+
- dst_cache_reset(&t->dst_cache);
- ip6_tnl_link_config(t);
- return 0;
-@@ -1574,6 +1743,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
- p->flowinfo = u->flowinfo;
- p->link = u->link;
- p->proto = u->proto;
-+ p->fmrs = NULL;
- memcpy(p->name, u->name, sizeof(u->name));
- }
-
-@@ -1960,6 +2130,15 @@ static int ip6_tnl_validate(struct nlatt
- return 0;
- }
-
-+static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = {
-+ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) },
-+ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) },
-+ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 },
-+ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 },
-+ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 },
-+ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 }
-+};
-+
- static void ip6_tnl_netlink_parms(struct nlattr *data[],
- struct __ip6_tnl_parm *parms)
- {
-@@ -1997,6 +2176,46 @@ static void ip6_tnl_netlink_parms(struct
-
- if (data[IFLA_IPTUN_FWMARK])
- parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
-+
-+ if (data[IFLA_IPTUN_FMRS]) {
-+ unsigned rem;
-+ struct nlattr *fmr;
-+ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) {
-+ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c;
-+ struct __ip6_tnl_fmr *nfmr;
-+
-+ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX,
-+ fmr, ip6_tnl_fmr_policy, NULL);
-+
-+ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL)))
-+ continue;
-+
-+ nfmr->offset = 6;
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX]))
-+ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX],
-+ sizeof(nfmr->ip6_prefix));
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX]))
-+ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX],
-+ sizeof(nfmr->ip4_prefix));
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN]))
-+ nfmr->ip6_prefix_len = nla_get_u8(c);
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN]))
-+ nfmr->ip4_prefix_len = nla_get_u8(c);
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN]))
-+ nfmr->ea_len = nla_get_u8(c);
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET]))
-+ nfmr->offset = nla_get_u8(c);
-+
-+ nfmr->next = parms->fmrs;
-+ parms->fmrs = nfmr;
-+ }
-+ }
- }
-
- static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[],
-@@ -2112,6 +2331,12 @@ static void ip6_tnl_dellink(struct net_d
-
- static size_t ip6_tnl_get_size(const struct net_device *dev)
- {
-+ const struct ip6_tnl *t = netdev_priv(dev);
-+ struct __ip6_tnl_fmr *c;
-+ int fmrs = 0;
-+ for (c = t->parms.fmrs; c; c = c->next)
-+ ++fmrs;
-+
- return
- /* IFLA_IPTUN_LINK */
- nla_total_size(4) +
-@@ -2141,6 +2366,24 @@ static size_t ip6_tnl_get_size(const str
- nla_total_size(0) +
- /* IFLA_IPTUN_FWMARK */
- nla_total_size(4) +
-+ /* IFLA_IPTUN_FMRS */
-+ nla_total_size(0) +
-+ (
-+ /* nest */
-+ nla_total_size(0) +
-+ /* IFLA_IPTUN_FMR_IP6_PREFIX */
-+ nla_total_size(sizeof(struct in6_addr)) +
-+ /* IFLA_IPTUN_FMR_IP4_PREFIX */
-+ nla_total_size(sizeof(struct in_addr)) +
-+ /* IFLA_IPTUN_FMR_EA_LEN */
-+ nla_total_size(1) +
-+ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */
-+ nla_total_size(1) +
-+ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */
-+ nla_total_size(1) +
-+ /* IFLA_IPTUN_FMR_OFFSET */
-+ nla_total_size(1)
-+ ) * fmrs +
- 0;
- }
-
-@@ -2148,6 +2391,9 @@ static int ip6_tnl_fill_info(struct sk_b
- {
- struct ip6_tnl *tunnel = netdev_priv(dev);
- struct __ip6_tnl_parm *parm = &tunnel->parms;
-+ struct __ip6_tnl_fmr *c;
-+ int fmrcnt = 0;
-+ struct nlattr *fmrs;
-
- if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
- nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
-@@ -2157,9 +2403,27 @@ static int ip6_tnl_fill_info(struct sk_b
- nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
- nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
- nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) ||
-- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark))
-+ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) ||
-+ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS)))
- goto nla_put_failure;
-
-+ for (c = parm->fmrs; c; c = c->next) {
-+ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt);
-+ if (!fmr ||
-+ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX,
-+ sizeof(c->ip6_prefix), &c->ip6_prefix) ||
-+ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX,
-+ sizeof(c->ip4_prefix), &c->ip4_prefix) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset))
-+ goto nla_put_failure;
-+
-+ nla_nest_end(skb, fmr);
-+ }
-+ nla_nest_end(skb, fmrs);
-+
- if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
- nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
- nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
-@@ -2199,6 +2463,7 @@ static const struct nla_policy ip6_tnl_p
- [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
- [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
- [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
-+ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED },
- };
-
- static struct rtnl_link_ops ip6_link_ops __read_mostly = {
diff --git a/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
deleted file mode 100644
index 4c97d8b9ec..0000000000
--- a/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
+++ /dev/null
@@ -1,263 +0,0 @@
-From: Jonas Gorski <jogo@openwrt.org>
-Subject: ipv6: allow rejecting with "source address failed policy"
-
-RFC6204 L-14 requires rejecting traffic from invalid addresses with
-ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/
-egress policy) on the LAN side, so add an appropriate rule for that.
-
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
----
- include/net/netns/ipv6.h | 1 +
- include/uapi/linux/fib_rules.h | 4 +++
- include/uapi/linux/rtnetlink.h | 1 +
- net/ipv4/fib_semantics.c | 4 +++
- net/ipv4/fib_trie.c | 1 +
- net/ipv4/ipmr.c | 1 +
- net/ipv6/fib6_rules.c | 4 +++
- net/ipv6/ip6mr.c | 2 ++
- net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++-
- 9 files changed, 75 insertions(+), 1 deletion(-)
-
---- a/include/net/netns/ipv6.h
-+++ b/include/net/netns/ipv6.h
-@@ -85,6 +85,7 @@ struct netns_ipv6 {
- unsigned int fib6_routes_require_src;
- #endif
- struct rt6_info *ip6_prohibit_entry;
-+ struct rt6_info *ip6_policy_failed_entry;
- struct rt6_info *ip6_blk_hole_entry;
- struct fib6_table *fib6_local_tbl;
- struct fib_rules_ops *fib6_rules_ops;
---- a/include/uapi/linux/fib_rules.h
-+++ b/include/uapi/linux/fib_rules.h
-@@ -82,6 +82,10 @@ enum {
- FR_ACT_BLACKHOLE, /* Drop without notification */
- FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */
- FR_ACT_PROHIBIT, /* Drop with EACCES */
-+ FR_ACT_RES9,
-+ FR_ACT_RES10,
-+ FR_ACT_RES11,
-+ FR_ACT_POLICY_FAILED, /* Drop with EACCES */
- __FR_ACT_MAX,
- };
-
---- a/include/uapi/linux/rtnetlink.h
-+++ b/include/uapi/linux/rtnetlink.h
-@@ -256,6 +256,7 @@ enum {
- RTN_THROW, /* Not in this table */
- RTN_NAT, /* Translate this address */
- RTN_XRESOLVE, /* Use external resolver */
-+ RTN_POLICY_FAILED, /* Failed ingress/egress policy */
- __RTN_MAX
- };
-
---- a/net/ipv4/fib_semantics.c
-+++ b/net/ipv4/fib_semantics.c
-@@ -143,6 +143,10 @@ const struct fib_prop fib_props[RTN_MAX
- .error = -EINVAL,
- .scope = RT_SCOPE_NOWHERE,
- },
-+ [RTN_POLICY_FAILED] = {
-+ .error = -EACCES,
-+ .scope = RT_SCOPE_UNIVERSE,
-+ },
- };
-
- static void rt_fibinfo_free(struct rtable __rcu **rtp)
---- a/net/ipv4/fib_trie.c
-+++ b/net/ipv4/fib_trie.c
-@@ -2777,6 +2777,7 @@ static const char *const rtn_type_names[
- [RTN_THROW] = "THROW",
- [RTN_NAT] = "NAT",
- [RTN_XRESOLVE] = "XRESOLVE",
-+ [RTN_POLICY_FAILED] = "POLICY_FAILED",
- };
-
- static inline const char *rtn_type(char *buf, size_t len, unsigned int t)
---- a/net/ipv4/ipmr.c
-+++ b/net/ipv4/ipmr.c
-@@ -175,6 +175,7 @@ static int ipmr_rule_action(struct fib_r
- case FR_ACT_UNREACHABLE:
- return -ENETUNREACH;
- case FR_ACT_PROHIBIT:
-+ case FR_ACT_POLICY_FAILED:
- return -EACCES;
- case FR_ACT_BLACKHOLE:
- default:
---- a/net/ipv6/fib6_rules.c
-+++ b/net/ipv6/fib6_rules.c
-@@ -220,6 +220,10 @@ static int __fib6_rule_action(struct fib
- err = -EACCES;
- rt = net->ipv6.ip6_prohibit_entry;
- goto discard_pkt;
-+ case FR_ACT_POLICY_FAILED:
-+ err = -EACCES;
-+ rt = net->ipv6.ip6_policy_failed_entry;
-+ goto discard_pkt;
- }
-
- tb_id = fib_rule_get_table(rule, arg);
---- a/net/ipv6/ip6mr.c
-+++ b/net/ipv6/ip6mr.c
-@@ -163,6 +163,8 @@ static int ip6mr_rule_action(struct fib_
- return -ENETUNREACH;
- case FR_ACT_PROHIBIT:
- return -EACCES;
-+ case FR_ACT_POLICY_FAILED:
-+ return -EACCES;
- case FR_ACT_BLACKHOLE:
- default:
- return -EINVAL;
---- a/net/ipv6/route.c
-+++ b/net/ipv6/route.c
-@@ -97,6 +97,8 @@ static int ip6_pkt_discard(struct sk_bu
- static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
- static int ip6_pkt_prohibit(struct sk_buff *skb);
- static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb);
-+static int ip6_pkt_policy_failed(struct sk_buff *skb);
-+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb);
- static void ip6_link_failure(struct sk_buff *skb);
- static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
- struct sk_buff *skb, u32 mtu,
-@@ -312,6 +314,18 @@ static const struct rt6_info ip6_prohibi
- .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
- };
-
-+static const struct rt6_info ip6_policy_failed_entry_template = {
-+ .dst = {
-+ .__refcnt = ATOMIC_INIT(1),
-+ .__use = 1,
-+ .obsolete = DST_OBSOLETE_FORCE_CHK,
-+ .error = -EACCES,
-+ .input = ip6_pkt_policy_failed,
-+ .output = ip6_pkt_policy_failed_out,
-+ },
-+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
-+};
-+
- static const struct rt6_info ip6_blk_hole_entry_template = {
- .dst = {
- .__refcnt = ATOMIC_INIT(1),
-@@ -1033,6 +1047,7 @@ static const int fib6_prop[RTN_MAX + 1]
- [RTN_BLACKHOLE] = -EINVAL,
- [RTN_UNREACHABLE] = -EHOSTUNREACH,
- [RTN_PROHIBIT] = -EACCES,
-+ [RTN_POLICY_FAILED] = -EACCES,
- [RTN_THROW] = -EAGAIN,
- [RTN_NAT] = -EINVAL,
- [RTN_XRESOLVE] = -EINVAL,
-@@ -1068,6 +1083,10 @@ static void ip6_rt_init_dst_reject(struc
- rt->dst.output = ip6_pkt_prohibit_out;
- rt->dst.input = ip6_pkt_prohibit;
- break;
-+ case RTN_POLICY_FAILED:
-+ rt->dst.output = ip6_pkt_policy_failed_out;
-+ rt->dst.input = ip6_pkt_policy_failed;
-+ break;
- case RTN_THROW:
- case RTN_UNREACHABLE:
- default:
-@@ -4557,6 +4576,17 @@ static int ip6_pkt_prohibit_out(struct n
- return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
- }
-
-+static int ip6_pkt_policy_failed(struct sk_buff *skb)
-+{
-+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES);
-+}
-+
-+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb)
-+{
-+ skb->dev = skb_dst(skb)->dev;
-+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES);
-+}
-+
- /*
- * Allocate a dst for local (unicast / anycast) address.
- */
-@@ -5044,7 +5074,8 @@ static int rtm_to_fib6_config(struct sk_
- if (rtm->rtm_type == RTN_UNREACHABLE ||
- rtm->rtm_type == RTN_BLACKHOLE ||
- rtm->rtm_type == RTN_PROHIBIT ||
-- rtm->rtm_type == RTN_THROW)
-+ rtm->rtm_type == RTN_THROW ||
-+ rtm->rtm_type == RTN_POLICY_FAILED)
- cfg->fc_flags |= RTF_REJECT;
-
- if (rtm->rtm_type == RTN_LOCAL)
-@@ -6291,6 +6322,8 @@ static int ip6_route_dev_notify(struct n
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- net->ipv6.ip6_prohibit_entry->dst.dev = dev;
- net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
-+ net->ipv6.ip6_policy_failed_entry->dst.dev = dev;
-+ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev);
- net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
- net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
- #endif
-@@ -6302,6 +6335,7 @@ static int ip6_route_dev_notify(struct n
- in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
-+ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev);
- in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
- #endif
- }
-@@ -6493,6 +6527,8 @@ static int __net_init ip6_route_net_init
-
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- net->ipv6.fib6_has_custom_rules = false;
-+
-+
- net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
- sizeof(*net->ipv6.ip6_prohibit_entry),
- GFP_KERNEL);
-@@ -6503,11 +6539,21 @@ static int __net_init ip6_route_net_init
- ip6_template_metrics, true);
- INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached);
-
-+ net->ipv6.ip6_policy_failed_entry =
-+ kmemdup(&ip6_policy_failed_entry_template,
-+ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL);
-+ if (!net->ipv6.ip6_policy_failed_entry)
-+ goto out_ip6_prohibit_entry;
-+ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops;
-+ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst,
-+ ip6_template_metrics, true);
-+ INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->rt6i_uncached);
-+
- net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
- sizeof(*net->ipv6.ip6_blk_hole_entry),
- GFP_KERNEL);
- if (!net->ipv6.ip6_blk_hole_entry)
-- goto out_ip6_prohibit_entry;
-+ goto out_ip6_policy_failed_entry;
- net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
- dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
- ip6_template_metrics, true);
-@@ -6534,6 +6580,8 @@ out:
- return ret;
-
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
-+out_ip6_policy_failed_entry:
-+ kfree(net->ipv6.ip6_policy_failed_entry);
- out_ip6_prohibit_entry:
- kfree(net->ipv6.ip6_prohibit_entry);
- out_ip6_null_entry:
-@@ -6553,6 +6601,7 @@ static void __net_exit ip6_route_net_exi
- kfree(net->ipv6.ip6_null_entry);
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- kfree(net->ipv6.ip6_prohibit_entry);
-+ kfree(net->ipv6.ip6_policy_failed_entry);
- kfree(net->ipv6.ip6_blk_hole_entry);
- #endif
- dst_entries_destroy(&net->ipv6.ip6_dst_ops);
-@@ -6636,6 +6685,9 @@ void __init ip6_route_init_special_entri
- init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
- init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
- init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
-+ init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev;
-+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev =
-+ in6_dev_get(init_net.loopback_dev);
- #endif
- }
-
diff --git a/target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch
deleted file mode 100644
index bea43b2bad..0000000000
--- a/target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From: Jonas Gorski <jogo@openwrt.org>
-Subject: net: provide defines for _POLICY_FAILED until all code is updated
-
-Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination
-unreachable, conflicting with our name.
-
-Add appropriate defines to allow our code to build with the new
-name until we have updated our local patches for older kernels
-and userspace packages.
-
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
----
- include/uapi/linux/fib_rules.h | 2 ++
- include/uapi/linux/icmpv6.h | 2 ++
- include/uapi/linux/rtnetlink.h | 2 ++
- 3 files changed, 6 insertions(+)
-
---- a/include/uapi/linux/fib_rules.h
-+++ b/include/uapi/linux/fib_rules.h
-@@ -89,6 +89,8 @@ enum {
- __FR_ACT_MAX,
- };
-
-+#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED
-+
- #define FR_ACT_MAX (__FR_ACT_MAX - 1)
-
- #endif
---- a/include/uapi/linux/icmpv6.h
-+++ b/include/uapi/linux/icmpv6.h
-@@ -126,6 +126,8 @@ struct icmp6hdr {
- #define ICMPV6_POLICY_FAIL 5
- #define ICMPV6_REJECT_ROUTE 6
-
-+#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL
-+
- /*
- * Codes for Time Exceeded
- */
---- a/include/uapi/linux/rtnetlink.h
-+++ b/include/uapi/linux/rtnetlink.h
-@@ -260,6 +260,8 @@ enum {
- __RTN_MAX
- };
-
-+#define RTN_FAILED_POLICY RTN_POLICY_FAILED
-+
- #define RTN_MAX (__RTN_MAX - 1)
-
-
diff --git a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
deleted file mode 100644
index 6eb72abaa7..0000000000
--- a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/netdevice.h | 2 ++
- include/linux/skbuff.h | 3 ++-
- net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
- net/ethernet/eth.c | 18 +++++++++++++++++-
- 4 files changed, 69 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -2099,6 +2099,8 @@ struct net_device {
- struct netdev_hw_addr_list mc;
- struct netdev_hw_addr_list dev_addrs;
-
-+ unsigned char local_addr_mask[MAX_ADDR_LEN];
-+
- #ifdef CONFIG_SYSFS
- struct kset *queues_kset;
- #endif
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -893,6 +893,7 @@ struct sk_buff {
- #ifdef CONFIG_IPV6_NDISC_NODETYPE
- __u8 ndisc_nodetype:2;
- #endif
-+ __u8 gro_skip:1;
-
- __u8 ipvs_property:1;
- __u8 inner_protocol_type:1;
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -6077,6 +6077,9 @@ static enum gro_result dev_gro_receive(s
- int same_flow;
- int grow;
-
-+ if (skb->gro_skip)
-+ goto normal;
-+
- if (netif_elide_gro(skb->dev))
- goto normal;
-
-@@ -8094,6 +8097,48 @@ static void __netdev_adjacent_dev_unlink
- &upper_dev->adj_list.lower);
- }
-
-+static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr,
-+ struct net_device *dev)
-+{
-+ int i;
-+
-+ for (i = 0; i < dev->addr_len; i++)
-+ mask[i] |= addr[i] ^ dev->dev_addr[i];
-+}
-+
-+static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev,
-+ struct net_device *lower)
-+{
-+ struct net_device *cur;
-+ struct list_head *iter;
-+
-+ netdev_for_each_upper_dev_rcu(dev, cur, iter) {
-+ __netdev_addr_mask(mask, cur->dev_addr, lower);
-+ __netdev_upper_mask(mask, cur, lower);
-+ }
-+}
-+
-+static void __netdev_update_addr_mask(struct net_device *dev)
-+{
-+ unsigned char mask[MAX_ADDR_LEN];
-+ struct net_device *cur;
-+ struct list_head *iter;
-+
-+ memset(mask, 0, sizeof(mask));
-+ __netdev_upper_mask(mask, dev, dev);
-+ memcpy(dev->local_addr_mask, mask, dev->addr_len);
-+
-+ netdev_for_each_lower_dev(dev, cur, iter)
-+ __netdev_update_addr_mask(cur);
-+}
-+
-+static void netdev_update_addr_mask(struct net_device *dev)
-+{
-+ rcu_read_lock();
-+ __netdev_update_addr_mask(dev);
-+ rcu_read_unlock();
-+}
-+
- static int __netdev_upper_dev_link(struct net_device *dev,
- struct net_device *upper_dev, bool master,
- void *upper_priv, void *upper_info,
-@@ -8145,6 +8190,7 @@ static int __netdev_upper_dev_link(struc
- if (ret)
- return ret;
-
-+ netdev_update_addr_mask(dev);
- ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
- &changeupper_info.info);
- ret = notifier_to_errno(ret);
-@@ -8241,6 +8287,7 @@ static void __netdev_upper_dev_unlink(st
-
- __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
-
-+ netdev_update_addr_mask(dev);
- call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
- &changeupper_info.info);
-
-@@ -9060,6 +9107,7 @@ int dev_set_mac_address(struct net_devic
- if (err)
- return err;
- dev->addr_assign_type = NET_ADDR_SET;
-+ netdev_update_addr_mask(dev);
- call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
- add_device_randomness(dev->dev_addr, dev->addr_len);
- return 0;
---- a/net/ethernet/eth.c
-+++ b/net/ethernet/eth.c
-@@ -142,6 +142,18 @@ u32 eth_get_headlen(const struct net_dev
- }
- EXPORT_SYMBOL(eth_get_headlen);
-
-+static inline bool
-+eth_check_local_mask(const void *addr1, const void *addr2, const void *mask)
-+{
-+ const u16 *a1 = addr1;
-+ const u16 *a2 = addr2;
-+ const u16 *m = mask;
-+
-+ return (((a1[0] ^ a2[0]) & ~m[0]) |
-+ ((a1[1] ^ a2[1]) & ~m[1]) |
-+ ((a1[2] ^ a2[2]) & ~m[2]));
-+}
-+
- /**
- * eth_type_trans - determine the packet's protocol ID.
- * @skb: received socket data
-@@ -165,6 +177,10 @@ __be16 eth_type_trans(struct sk_buff *sk
-
- eth_skb_pkt_type(skb, dev);
-
-+ if (unlikely(!ether_addr_equal_64bits(eth->h_dest, dev->dev_addr)) &&
-+ eth_check_local_mask(eth->h_dest, dev->dev_addr, dev->local_addr_mask))
-+ skb->gro_skip = 1;
-+
- /*
- * Some variants of DSA tagging don't have an ethertype field
- * at all, so we check here whether one of those tagging
diff --git a/target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch b/target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch
deleted file mode 100644
index 03ee537fb8..0000000000
--- a/target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 8585756342caa6d27008d1ad0c18023e4211a40a Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:22:48 +0200
-Subject: [PATCH] of/of_net: write back netdev MAC-address to device-tree
-
-The label-mac logic relies on the mac-address property of a netdev
-devices of-node. However, the mac address can also be stored as a
-different property or read from e.g. an mtd device.
-
-Create this node when reading a mac-address from OF if it does not
-already exist and copy the mac-address used for the device to this
-property. This way, the MAC address can be accessed using procfs.
-
----
- net/core/of_net.c | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/net/core/of_net.c
-+++ b/net/core/of_net.c
-@@ -95,6 +95,27 @@ static int of_get_mac_addr_nvmem(struct
- return 0;
- }
-
-+static int of_add_mac_address(struct device_node *np, u8* addr)
-+{
-+ struct property *prop;
-+
-+ prop = kzalloc(sizeof(*prop), GFP_KERNEL);
-+ if (!prop)
-+ return -ENOMEM;
-+
-+ prop->name = "mac-address";
-+ prop->length = ETH_ALEN;
-+ prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL);
-+ if (!prop->value || of_update_property(np, prop))
-+ goto free;
-+
-+ return 0;
-+free:
-+ kfree(prop->value);
-+ kfree(prop);
-+ return -ENOMEM;
-+}
-+
- /**
- * of_get_mac_address()
- * @np: Caller's Device Node
-@@ -130,17 +151,23 @@ int of_get_mac_address(struct device_nod
-
- ret = of_get_mac_addr(np, "mac-address", addr);
- if (!ret)
-- return 0;
-+ goto found;
-
- ret = of_get_mac_addr(np, "local-mac-address", addr);
- if (!ret)
-- return 0;
-+ goto found;
-
- ret = of_get_mac_addr(np, "address", addr);
- if (!ret)
-- return 0;
-+ goto found;
-
-- return of_get_mac_addr_nvmem(np, addr);
-+ ret = of_get_mac_addr_nvmem(np, addr);
-+ if (ret)
-+ return ret;
-+
-+found:
-+ ret = of_add_mac_address(np, addr);
-+ return ret;
- }
- EXPORT_SYMBOL(of_get_mac_address);
-
diff --git a/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
deleted file mode 100644
index ba75e4a0f1..0000000000
--- a/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Thu, 25 Jan 2018 12:58:55 +0100
-Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from
- nf_flow_table
-
-Move the code that deals with device events to the core.
-
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
-
---- a/net/netfilter/nf_flow_table_core.c
-+++ b/net/netfilter/nf_flow_table_core.c
-@@ -651,6 +651,23 @@ static struct pernet_operations nf_flow_
- .exit_batch = nf_flow_table_pernet_exit,
- };
-
-+static int nf_flow_table_netdev_event(struct notifier_block *this,
-+ unsigned long event, void *ptr)
-+{
-+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-+
-+ if (event != NETDEV_DOWN)
-+ return NOTIFY_DONE;
-+
-+ nf_flow_table_cleanup(dev);
-+
-+ return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block flow_offload_netdev_notifier = {
-+ .notifier_call = nf_flow_table_netdev_event,
-+};
-+
- static int __init nf_flow_table_module_init(void)
- {
- int ret;
-@@ -663,8 +680,14 @@ static int __init nf_flow_table_module_i
- if (ret)
- goto out_offload;
-
-+ ret = register_netdevice_notifier(&flow_offload_netdev_notifier);
-+ if (ret)
-+ goto out_offload_init;
-+
- return 0;
-
-+out_offload_init:
-+ nf_flow_table_offload_exit();
- out_offload:
- unregister_pernet_subsys(&nf_flow_table_net_ops);
- return ret;
-@@ -672,6 +695,7 @@ out_offload:
-
- static void __exit nf_flow_table_module_exit(void)
- {
-+ unregister_netdevice_notifier(&flow_offload_netdev_notifier);
- nf_flow_table_offload_exit();
- unregister_pernet_subsys(&nf_flow_table_net_ops);
- }
---- a/net/netfilter/nft_flow_offload.c
-+++ b/net/netfilter/nft_flow_offload.c
-@@ -455,47 +455,14 @@ static struct nft_expr_type nft_flow_off
- .owner = THIS_MODULE,
- };
-
--static int flow_offload_netdev_event(struct notifier_block *this,
-- unsigned long event, void *ptr)
--{
-- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
--
-- if (event != NETDEV_DOWN)
-- return NOTIFY_DONE;
--
-- nf_flow_table_cleanup(dev);
--
-- return NOTIFY_DONE;
--}
--
--static struct notifier_block flow_offload_netdev_notifier = {
-- .notifier_call = flow_offload_netdev_event,
--};
--
- static int __init nft_flow_offload_module_init(void)
- {
-- int err;
--
-- err = register_netdevice_notifier(&flow_offload_netdev_notifier);
-- if (err)
-- goto err;
--
-- err = nft_register_expr(&nft_flow_offload_type);
-- if (err < 0)
-- goto register_expr;
--
-- return 0;
--
--register_expr:
-- unregister_netdevice_notifier(&flow_offload_netdev_notifier);
--err:
-- return err;
-+ return nft_register_expr(&nft_flow_offload_type);
- }
-
- static void __exit nft_flow_offload_module_exit(void)
- {
- nft_unregister_expr(&nft_flow_offload_type);
-- unregister_netdevice_notifier(&flow_offload_netdev_notifier);
- }
-
- module_init(nft_flow_offload_module_init);
diff --git a/target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
deleted file mode 100644
index 3037a724bf..0000000000
--- a/target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 31 Aug 2023 21:48:38 +0200
-Subject: [PATCH] netfilter: nf_tables: ignore -EOPNOTSUPP on flowtable device
- offload setup
-
-On many embedded devices, it is common to configure flowtable offloading for
-a mix of different devices, some of which have hardware offload support and
-some of which don't.
-The current code limits the ability of user space to properly set up such a
-configuration by only allowing adding devices with hardware offload support to
-a offload-enabled flowtable.
-Given that offload-enabled flowtables also imply fallback to pure software
-offloading, this limitation makes little sense.
-Fix it by not bailing out when the offload setup returns -EOPNOTSUPP
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/netfilter/nf_tables_api.c
-+++ b/net/netfilter/nf_tables_api.c
-@@ -7811,7 +7811,7 @@ static int nft_register_flowtable_net_ho
- err = flowtable->data.type->setup(&flowtable->data,
- hook->ops.dev,
- FLOW_BLOCK_BIND);
-- if (err < 0)
-+ if (err < 0 && err != -EOPNOTSUPP)
- goto err_unregister_net_hooks;
-
- err = nf_register_net_hook(net, &hook->ops);
diff --git a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
deleted file mode 100644
index 67cff4d22b..0000000000
--- a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 21 Mar 2022 20:39:59 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: enable threaded NAPI
-
-This can improve performance under load by ensuring that NAPI processing is
-not pinned on CPU 0.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3099,8 +3099,8 @@ static irqreturn_t mtk_handle_irq_rx(int
-
- eth->rx_events++;
- if (likely(napi_schedule_prep(&eth->rx_napi))) {
-- __napi_schedule(&eth->rx_napi);
- mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
-+ __napi_schedule(&eth->rx_napi);
- }
-
- return IRQ_HANDLED;
-@@ -3112,8 +3112,8 @@ static irqreturn_t mtk_handle_irq_tx(int
-
- eth->tx_events++;
- if (likely(napi_schedule_prep(&eth->tx_napi))) {
-- __napi_schedule(&eth->tx_napi);
- mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
-+ __napi_schedule(&eth->tx_napi);
- }
-
- return IRQ_HANDLED;
-@@ -4887,6 +4887,8 @@ static int mtk_probe(struct platform_dev
- * for NAPI to work
- */
- init_dummy_netdev(&eth->dummy_dev);
-+ eth->dummy_dev.threaded = 1;
-+ strcpy(eth->dummy_dev.name, "mtk_eth");
- netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx,
- NAPI_POLL_WEIGHT);
- netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx,
diff --git a/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch
deleted file mode 100644
index f93dca6814..0000000000
--- a/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: generic: add detach callback to struct phy_driver
-
-lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- drivers/net/phy/phy_device.c | 3 +++
- include/linux/phy.h | 6 ++++++
- 2 files changed, 9 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1751,6 +1751,9 @@ void phy_detach(struct phy_device *phyde
- struct module *ndev_owner = NULL;
- struct mii_bus *bus;
-
-+ if (phydev->drv && phydev->drv->detach)
-+ phydev->drv->detach(phydev);
-+
- if (phydev->sysfs_links) {
- if (dev)
- sysfs_remove_link(&dev->dev.kobj, "phydev");
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -868,6 +868,12 @@ struct phy_driver {
- /** @handle_interrupt: Override default interrupt handling */
- irqreturn_t (*handle_interrupt)(struct phy_device *phydev);
-
-+ /*
-+ * Called before an ethernet device is detached
-+ * from the PHY.
-+ */
-+ void (*detach)(struct phy_device *phydev);
-+
- /** @remove: Clears up any memory if needed */
- void (*remove)(struct phy_device *phydev);
-
diff --git a/target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch b/target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch
deleted file mode 100644
index 287728ba1d..0000000000
--- a/target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From d6d80269cf5c79f9dfe7d69f8b41a72015c89748 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 3 Apr 2023 19:30:20 +0100
-Subject: [PATCH 1/5] net: mvneta: fix transmit path dma-unmapping on error
-
-The transmit code assumes that the transmit descriptors that are used
-begin with the first descriptor in the ring, but this may not be the
-case. Fix this by providing a new function that dma-unmaps a range of
-numbered descriptor entries, and use that to do the unmapping.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/ethernet/marvell/mvneta.c | 53 +++++++++++++++++----------
- 1 file changed, 33 insertions(+), 20 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -2647,14 +2647,40 @@ mvneta_tso_put_data(struct net_device *d
- return 0;
- }
-
-+static void mvneta_release_descs(struct mvneta_port *pp,
-+ struct mvneta_tx_queue *txq,
-+ int first, int num)
-+{
-+ int desc_idx, i;
-+
-+ desc_idx = first + num;
-+ if (desc_idx >= txq->size)
-+ desc_idx -= txq->size;
-+
-+ for (i = num; i >= 0; i--) {
-+ struct mvneta_tx_desc *tx_desc = txq->descs + desc_idx;
-+
-+ if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr))
-+ dma_unmap_single(pp->dev->dev.parent,
-+ tx_desc->buf_phys_addr,
-+ tx_desc->data_size,
-+ DMA_TO_DEVICE);
-+
-+ mvneta_txq_desc_put(txq);
-+
-+ if (desc_idx == 0)
-+ desc_idx = txq->size;
-+ desc_idx -= 1;
-+ }
-+}
-+
- static int mvneta_tx_tso(struct sk_buff *skb, struct net_device *dev,
- struct mvneta_tx_queue *txq)
- {
- int hdr_len, total_len, data_left;
-- int desc_count = 0;
-+ int first_desc, desc_count = 0;
- struct mvneta_port *pp = netdev_priv(dev);
- struct tso_t tso;
-- int i;
-
- /* Count needed descriptors */
- if ((txq->count + tso_count_descs(skb)) >= txq->size)
-@@ -2665,6 +2691,8 @@ static int mvneta_tx_tso(struct sk_buff
- return 0;
- }
-
-+ first_desc = txq->txq_put_index;
-+
- /* Initialize the TSO handler, and prepare the first payload */
- hdr_len = tso_start(skb, &tso);
-
-@@ -2705,15 +2733,7 @@ err_release:
- /* Release all used data descriptors; header descriptors must not
- * be DMA-unmapped.
- */
-- for (i = desc_count - 1; i >= 0; i--) {
-- struct mvneta_tx_desc *tx_desc = txq->descs + i;
-- if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr))
-- dma_unmap_single(pp->dev->dev.parent,
-- tx_desc->buf_phys_addr,
-- tx_desc->data_size,
-- DMA_TO_DEVICE);
-- mvneta_txq_desc_put(txq);
-- }
-+ mvneta_release_descs(pp, txq, first_desc, desc_count - 1);
- return 0;
- }
-
-@@ -2723,6 +2743,7 @@ static int mvneta_tx_frag_process(struct
- {
- struct mvneta_tx_desc *tx_desc;
- int i, nr_frags = skb_shinfo(skb)->nr_frags;
-+ int first_desc = txq->txq_put_index;
-
- for (i = 0; i < nr_frags; i++) {
- struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
-@@ -2761,15 +2782,7 @@ error:
- /* Release all descriptors that were used to map fragments of
- * this packet, as well as the corresponding DMA mappings
- */
-- for (i = i - 1; i >= 0; i--) {
-- tx_desc = txq->descs + i;
-- dma_unmap_single(pp->dev->dev.parent,
-- tx_desc->buf_phys_addr,
-- tx_desc->data_size,
-- DMA_TO_DEVICE);
-- mvneta_txq_desc_put(txq);
-- }
--
-+ mvneta_release_descs(pp, txq, first_desc, i - 1);
- return -ENOMEM;
- }
-
diff --git a/target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch b/target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch
deleted file mode 100644
index 4db3ffe4e1..0000000000
--- a/target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From e3c77d0a1b635d114c147fd2078afb57ed558b81 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 3 Apr 2023 19:30:25 +0100
-Subject: [PATCH 2/5] net: mvneta: mark mapped and tso buffers separately
-
-Mark dma-mapped skbs and TSO buffers separately, so we can use
-buf->type to identify their differences.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/ethernet/marvell/mvneta.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -607,6 +607,7 @@ struct mvneta_rx_desc {
- #endif
-
- enum mvneta_tx_buf_type {
-+ MVNETA_TYPE_TSO,
- MVNETA_TYPE_SKB,
- MVNETA_TYPE_XDP_TX,
- MVNETA_TYPE_XDP_NDO,
-@@ -1852,7 +1853,8 @@ static void mvneta_txq_bufs_free(struct
- dma_unmap_single(pp->dev->dev.parent,
- tx_desc->buf_phys_addr,
- tx_desc->data_size, DMA_TO_DEVICE);
-- if (buf->type == MVNETA_TYPE_SKB && buf->skb) {
-+ if ((buf->type == MVNETA_TYPE_TSO ||
-+ buf->type == MVNETA_TYPE_SKB) && buf->skb) {
- bytes_compl += buf->skb->len;
- pkts_compl++;
- dev_kfree_skb_any(buf->skb);
-@@ -2607,7 +2609,7 @@ mvneta_tso_put_hdr(struct sk_buff *skb,
- tx_desc->command |= MVNETA_TXD_F_DESC;
- tx_desc->buf_phys_addr = txq->tso_hdrs_phys +
- txq->txq_put_index * TSO_HEADER_SIZE;
-- buf->type = MVNETA_TYPE_SKB;
-+ buf->type = MVNETA_TYPE_TSO;
- buf->skb = NULL;
-
- mvneta_txq_inc_put(txq);
diff --git a/target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch b/target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch
deleted file mode 100644
index 37511ff1dd..0000000000
--- a/target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From fe2abc1abc0dfc6c13fe8f189216f00dbbb33044 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 3 Apr 2023 19:30:30 +0100
-Subject: [PATCH 3/5] net: mvneta: use buf->type to determine whether to
- dma-unmap
-
-Now that we use a different buffer type for TSO headers, we can use
-buf->type to determine whether the original buffer was DMA-mapped or
-not. The rules are:
-
- MVNETA_TYPE_XDP_TX - from a DMA pool, no unmap is required
- MVNETA_TYPE_XDP_NDO - dma_map_single()'d
- MVNETA_TYPE_SKB - normal skbuff, dma_map_single()'d
- MVNETA_TYPE_TSO - from the TSO buffer area
-
-This means we only need to call dma_unmap_single() on the XDP_NDO and
-SKB types of buffer, and we no longer need the private IS_TSO_HEADER()
-which relies on the TSO region being contiguously allocated.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/ethernet/marvell/mvneta.c | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -334,10 +334,6 @@
- MVNETA_SKB_HEADROOM))
- #define MVNETA_MAX_RX_BUF_SIZE (PAGE_SIZE - MVNETA_SKB_PAD)
-
--#define IS_TSO_HEADER(txq, addr) \
-- ((addr >= txq->tso_hdrs_phys) && \
-- (addr < txq->tso_hdrs_phys + txq->size * TSO_HEADER_SIZE))
--
- #define MVNETA_RX_GET_BM_POOL_ID(rxd) \
- (((rxd)->status & MVNETA_RXD_BM_POOL_MASK) >> MVNETA_RXD_BM_POOL_SHIFT)
-
-@@ -1848,8 +1844,8 @@ static void mvneta_txq_bufs_free(struct
-
- mvneta_txq_inc_get(txq);
-
-- if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr) &&
-- buf->type != MVNETA_TYPE_XDP_TX)
-+ if (buf->type == MVNETA_TYPE_XDP_NDO ||
-+ buf->type == MVNETA_TYPE_SKB)
- dma_unmap_single(pp->dev->dev.parent,
- tx_desc->buf_phys_addr,
- tx_desc->data_size, DMA_TO_DEVICE);
-@@ -2661,8 +2657,9 @@ static void mvneta_release_descs(struct
-
- for (i = num; i >= 0; i--) {
- struct mvneta_tx_desc *tx_desc = txq->descs + desc_idx;
-+ struct mvneta_tx_buf *buf = &txq->buf[desc_idx];
-
-- if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr))
-+ if (buf->type == MVNETA_TYPE_SKB)
- dma_unmap_single(pp->dev->dev.parent,
- tx_desc->buf_phys_addr,
- tx_desc->data_size,
diff --git a/target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch b/target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch
deleted file mode 100644
index 444b60f151..0000000000
--- a/target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 210ca75d4949f1ace8ea53a75148806cc28224a0 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 3 Apr 2023 19:30:35 +0100
-Subject: [PATCH 4/5] net: mvneta: move tso_build_hdr() into
- mvneta_tso_put_hdr()
-
-Move tso_build_hdr() into mvneta_tso_put_hdr() so that all the TSO
-header building code is in one place.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/ethernet/marvell/mvneta.c | 22 +++++++++++-----------
- 1 file changed, 11 insertions(+), 11 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -2592,19 +2592,24 @@ err_drop_frame:
- return rx_done;
- }
-
--static inline void
--mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq)
-+static void mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq,
-+ struct tso_t *tso, int size, bool is_last)
- {
-- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-+ int tso_offset, hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
- struct mvneta_tx_desc *tx_desc;
-+ char *hdr;
-+
-+ tso_offset = txq->txq_put_index * TSO_HEADER_SIZE;
-+
-+ hdr = txq->tso_hdrs + tso_offset;
-+ tso_build_hdr(skb, hdr, tso, size, is_last);
-
- tx_desc = mvneta_txq_next_desc_get(txq);
- tx_desc->data_size = hdr_len;
- tx_desc->command = mvneta_skb_tx_csum(skb);
- tx_desc->command |= MVNETA_TXD_F_DESC;
-- tx_desc->buf_phys_addr = txq->tso_hdrs_phys +
-- txq->txq_put_index * TSO_HEADER_SIZE;
-+ tx_desc->buf_phys_addr = txq->tso_hdrs_phys + tso_offset;
- buf->type = MVNETA_TYPE_TSO;
- buf->skb = NULL;
-
-@@ -2697,17 +2702,12 @@ static int mvneta_tx_tso(struct sk_buff
-
- total_len = skb->len - hdr_len;
- while (total_len > 0) {
-- char *hdr;
--
- data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len);
- total_len -= data_left;
- desc_count++;
-
- /* prepare packet headers: MAC + IP + TCP */
-- hdr = txq->tso_hdrs + txq->txq_put_index * TSO_HEADER_SIZE;
-- tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0);
--
-- mvneta_tso_put_hdr(skb, txq);
-+ mvneta_tso_put_hdr(skb, txq, &tso, data_left, total_len == 0);
-
- while (data_left > 0) {
- int size;
diff --git a/target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch b/target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch
deleted file mode 100644
index 395a0bf5d2..0000000000
--- a/target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 58d50fb089da553023df5a05f5ae86feaacc7f24 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Mon, 3 Apr 2023 19:30:40 +0100
-Subject: [PATCH 5/5] net: mvneta: allocate TSO header DMA memory in chunks
-
-Now that we no longer need to check whether the DMA address is within
-the TSO header DMA memory range for the queue, we can allocate the TSO
-header DMA memory in chunks rather than one contiguous order-6 chunk,
-which can stress the kernel's memory subsystems to allocate.
-
-Instead, use order-1 (8k) allocations, which will result in 32 order-1
-pages containing 32 TSO headers.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/ethernet/marvell/mvneta.c | 88 +++++++++++++++++++++------
- 1 file changed, 70 insertions(+), 18 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -314,6 +314,15 @@
-
- #define MVNETA_MAX_SKB_DESCS (MVNETA_MAX_TSO_SEGS * 2 + MAX_SKB_FRAGS)
-
-+/* The size of a TSO header page */
-+#define MVNETA_TSO_PAGE_SIZE (2 * PAGE_SIZE)
-+
-+/* Number of TSO headers per page. This should be a power of 2 */
-+#define MVNETA_TSO_PER_PAGE (MVNETA_TSO_PAGE_SIZE / TSO_HEADER_SIZE)
-+
-+/* Maximum number of TSO header pages */
-+#define MVNETA_MAX_TSO_PAGES (MVNETA_MAX_TXD / MVNETA_TSO_PER_PAGE)
-+
- /* descriptor aligned size */
- #define MVNETA_DESC_ALIGNED_SIZE 32
-
-@@ -656,10 +665,10 @@ struct mvneta_tx_queue {
- int next_desc_to_proc;
-
- /* DMA buffers for TSO headers */
-- char *tso_hdrs;
-+ char *tso_hdrs[MVNETA_MAX_TSO_PAGES];
-
- /* DMA address of TSO headers */
-- dma_addr_t tso_hdrs_phys;
-+ dma_addr_t tso_hdrs_phys[MVNETA_MAX_TSO_PAGES];
-
- /* Affinity mask for CPUs*/
- cpumask_t affinity_mask;
-@@ -2592,24 +2601,71 @@ err_drop_frame:
- return rx_done;
- }
-
-+static void mvneta_free_tso_hdrs(struct mvneta_port *pp,
-+ struct mvneta_tx_queue *txq)
-+{
-+ struct device *dev = pp->dev->dev.parent;
-+ int i;
-+
-+ for (i = 0; i < MVNETA_MAX_TSO_PAGES; i++) {
-+ if (txq->tso_hdrs[i]) {
-+ dma_free_coherent(dev, MVNETA_TSO_PAGE_SIZE,
-+ txq->tso_hdrs[i],
-+ txq->tso_hdrs_phys[i]);
-+ txq->tso_hdrs[i] = NULL;
-+ }
-+ }
-+}
-+
-+static int mvneta_alloc_tso_hdrs(struct mvneta_port *pp,
-+ struct mvneta_tx_queue *txq)
-+{
-+ struct device *dev = pp->dev->dev.parent;
-+ int i, num;
-+
-+ num = DIV_ROUND_UP(txq->size, MVNETA_TSO_PER_PAGE);
-+ for (i = 0; i < num; i++) {
-+ txq->tso_hdrs[i] = dma_alloc_coherent(dev, MVNETA_TSO_PAGE_SIZE,
-+ &txq->tso_hdrs_phys[i],
-+ GFP_KERNEL);
-+ if (!txq->tso_hdrs[i]) {
-+ mvneta_free_tso_hdrs(pp, txq);
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static char *mvneta_get_tso_hdr(struct mvneta_tx_queue *txq, dma_addr_t *dma)
-+{
-+ int index, offset;
-+
-+ index = txq->txq_put_index / MVNETA_TSO_PER_PAGE;
-+ offset = (txq->txq_put_index % MVNETA_TSO_PER_PAGE) * TSO_HEADER_SIZE;
-+
-+ *dma = txq->tso_hdrs_phys[index] + offset;
-+
-+ return txq->tso_hdrs[index] + offset;
-+}
-+
- static void mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq,
- struct tso_t *tso, int size, bool is_last)
- {
-- int tso_offset, hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-+ int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
- struct mvneta_tx_desc *tx_desc;
-+ dma_addr_t hdr_phys;
- char *hdr;
-
-- tso_offset = txq->txq_put_index * TSO_HEADER_SIZE;
--
-- hdr = txq->tso_hdrs + tso_offset;
-+ hdr = mvneta_get_tso_hdr(txq, &hdr_phys);
- tso_build_hdr(skb, hdr, tso, size, is_last);
-
- tx_desc = mvneta_txq_next_desc_get(txq);
- tx_desc->data_size = hdr_len;
- tx_desc->command = mvneta_skb_tx_csum(skb);
- tx_desc->command |= MVNETA_TXD_F_DESC;
-- tx_desc->buf_phys_addr = txq->tso_hdrs_phys + tso_offset;
-+ tx_desc->buf_phys_addr = hdr_phys;
- buf->type = MVNETA_TYPE_TSO;
- buf->skb = NULL;
-
-@@ -3401,7 +3457,7 @@ static void mvneta_rxq_deinit(struct mvn
- static int mvneta_txq_sw_init(struct mvneta_port *pp,
- struct mvneta_tx_queue *txq)
- {
-- int cpu;
-+ int cpu, err;
-
- txq->size = pp->tx_ring_size;
-
-@@ -3426,11 +3482,9 @@ static int mvneta_txq_sw_init(struct mvn
- return -ENOMEM;
-
- /* Allocate DMA buffers for TSO MAC/IP/TCP headers */
-- txq->tso_hdrs = dma_alloc_coherent(pp->dev->dev.parent,
-- txq->size * TSO_HEADER_SIZE,
-- &txq->tso_hdrs_phys, GFP_KERNEL);
-- if (!txq->tso_hdrs)
-- return -ENOMEM;
-+ err = mvneta_alloc_tso_hdrs(pp, txq);
-+ if (err)
-+ return err;
-
- /* Setup XPS mapping */
- if (pp->neta_armada3700)
-@@ -3482,10 +3536,7 @@ static void mvneta_txq_sw_deinit(struct
-
- kfree(txq->buf);
-
-- if (txq->tso_hdrs)
-- dma_free_coherent(pp->dev->dev.parent,
-- txq->size * TSO_HEADER_SIZE,
-- txq->tso_hdrs, txq->tso_hdrs_phys);
-+ mvneta_free_tso_hdrs(pp, txq);
- if (txq->descs)
- dma_free_coherent(pp->dev->dev.parent,
- txq->size * MVNETA_DESC_ALIGNED_SIZE,
-@@ -3494,7 +3545,6 @@ static void mvneta_txq_sw_deinit(struct
- netdev_tx_reset_queue(nq);
-
- txq->buf = NULL;
-- txq->tso_hdrs = NULL;
- txq->descs = NULL;
- txq->last_desc = 0;
- txq->next_desc_to_proc = 0;
-@@ -5543,6 +5593,8 @@ static int __init mvneta_driver_init(voi
- {
- int ret;
-
-+ BUILD_BUG_ON_NOT_POWER_OF_2(MVNETA_TSO_PER_PAGE);
-+
- ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "net/mvneta:online",
- mvneta_cpu_online,
- mvneta_cpu_down_prepare);
diff --git a/target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch b/target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch
deleted file mode 100644
index d444b2027c..0000000000
--- a/target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 6 May 2022 21:38:42 +0200
-Subject: [PATCH] net: dsa: tag_mtk: add padding for tx packets
-
-Padding for transmitted packets needs to account for the special tag.
-With not enough padding, garbage bytes are inserted by the switch at the
-end of small packets.
-
-Fixes: 5cd8985a1909 ("net-next: dsa: add Mediatek tag RX/TX handler")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/dsa/tag_mtk.c
-+++ b/net/dsa/tag_mtk.c
-@@ -27,6 +27,13 @@ static struct sk_buff *mtk_tag_xmit(stru
-
- skb_set_queue_mapping(skb, dp->index);
-
-+ /* The Ethernet switch we are interfaced with needs packets to be at
-+ * least 64 bytes (including FCS) otherwise their padding might be
-+ * corrupted. With tags enabled, we need to make sure that packets are
-+ * at least 68 bytes (including FCS and tag).
-+ */
-+ eth_skb_pad(skb);
-+
- /* Build the special tag after the MAC Source Address. If VLAN header
- * is present, it's required that VLAN header and special tag is
- * being combined. Only in this way we can allow the switch can parse
diff --git a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch
deleted file mode 100644
index fd1b79cdfe..0000000000
--- a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 27 Aug 2021 12:22:32 +0200
-Subject: [PATCH] bridge: add knob for filtering rx/tx BPDU packets on a port
-
-Some devices (e.g. wireless APs) can't have devices behind them be part of
-a bridge topology with redundant links, due to address limitations.
-Additionally, broadcast traffic on these devices is somewhat expensive, due to
-the low data rate and wakeups of clients in powersave mode.
-This knob can be used to ensure that BPDU packets are never sent or forwarded
-to/from these devices
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/if_bridge.h
-+++ b/include/linux/if_bridge.h
-@@ -58,6 +58,7 @@ struct br_ip_list {
- #define BR_MRP_LOST_CONT BIT(18)
- #define BR_MRP_LOST_IN_CONT BIT(19)
- #define BR_TX_FWD_OFFLOAD BIT(20)
-+#define BR_BPDU_FILTER BIT(21)
-
- #define BR_DEFAULT_AGEING_TIME (300 * HZ)
-
---- a/net/bridge/br_forward.c
-+++ b/net/bridge/br_forward.c
-@@ -199,6 +199,7 @@ out:
- void br_flood(struct net_bridge *br, struct sk_buff *skb,
- enum br_pkt_type pkt_type, bool local_rcv, bool local_orig)
- {
-+ const unsigned char *dest = eth_hdr(skb)->h_dest;
- struct net_bridge_port *prev = NULL;
- struct net_bridge_port *p;
-
-@@ -214,6 +215,10 @@ void br_flood(struct net_bridge *br, str
- case BR_PKT_MULTICAST:
- if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev)
- continue;
-+ if ((p->flags & BR_BPDU_FILTER) &&
-+ unlikely(is_link_local_ether_addr(dest) &&
-+ dest[5] == 0))
-+ continue;
- break;
- case BR_PKT_BROADCAST:
- if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev)
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -331,6 +331,8 @@ static rx_handler_result_t br_handle_fra
- fwd_mask |= p->group_fwd_mask;
- switch (dest[5]) {
- case 0x00: /* Bridge Group Address */
-+ if (p->flags & BR_BPDU_FILTER)
-+ goto drop;
- /* If STP is turned off,
- then must forward to keep loop detection */
- if (p->br->stp_enabled == BR_NO_STP ||
---- a/net/bridge/br_sysfs_if.c
-+++ b/net/bridge/br_sysfs_if.c
-@@ -240,6 +240,7 @@ BRPORT_ATTR_FLAG(multicast_flood, BR_MCA
- BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
- BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS);
- BRPORT_ATTR_FLAG(isolated, BR_ISOLATED);
-+BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER);
-
- #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
- static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
-@@ -292,6 +293,7 @@ static const struct brport_attribute *br
- &brport_attr_group_fwd_mask,
- &brport_attr_neigh_suppress,
- &brport_attr_isolated,
-+ &brport_attr_bpdu_filter,
- &brport_attr_backup_port,
- NULL
- };
---- a/net/bridge/br_stp_bpdu.c
-+++ b/net/bridge/br_stp_bpdu.c
-@@ -80,7 +80,8 @@ void br_send_config_bpdu(struct net_brid
- {
- unsigned char buf[35];
-
-- if (p->br->stp_enabled != BR_KERNEL_STP)
-+ if (p->br->stp_enabled != BR_KERNEL_STP ||
-+ (p->flags & BR_BPDU_FILTER))
- return;
-
- buf[0] = 0;
-@@ -127,7 +128,8 @@ void br_send_tcn_bpdu(struct net_bridge_
- {
- unsigned char buf[4];
-
-- if (p->br->stp_enabled != BR_KERNEL_STP)
-+ if (p->br->stp_enabled != BR_KERNEL_STP ||
-+ (p->flags & BR_BPDU_FILTER))
- return;
-
- buf[0] = 0;
-@@ -172,6 +174,9 @@ void br_stp_rcv(const struct stp_proto *
- if (!(br->dev->flags & IFF_UP))
- goto out;
-
-+ if (p->flags & BR_BPDU_FILTER)
-+ goto out;
-+
- if (p->state == BR_STATE_DISABLED)
- goto out;
-
---- a/include/uapi/linux/if_link.h
-+++ b/include/uapi/linux/if_link.h
-@@ -536,6 +536,7 @@ enum {
- IFLA_BRPORT_MRP_IN_OPEN,
- IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
- IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
-+ IFLA_BRPORT_BPDU_FILTER,
- __IFLA_BRPORT_MAX
- };
- #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
---- a/net/bridge/br_netlink.c
-+++ b/net/bridge/br_netlink.c
-@@ -184,6 +184,7 @@ static inline size_t br_port_info_size(v
- + nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */
- + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */
- + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */
-+ + nla_total_size(1) /* IFLA_BRPORT_BPDU_FILTER */
- + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */
- + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */
- + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */
-@@ -269,7 +270,8 @@ static int br_port_fill_attrs(struct sk_
- BR_MRP_LOST_CONT)) ||
- nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN,
- !!(p->flags & BR_MRP_LOST_IN_CONT)) ||
-- nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)))
-+ nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) ||
-+ nla_put_u8(skb, IFLA_BRPORT_BPDU_FILTER, !!(p->flags & BR_BPDU_FILTER)))
- return -EMSGSIZE;
-
- timerval = br_timer_value(&p->message_age_timer);
-@@ -829,6 +831,7 @@ static const struct nla_policy br_port_p
- [IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 },
- [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 },
- [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 },
-+ [IFLA_BRPORT_BPDU_FILTER] = { .type = NLA_U8 },
- };
-
- /* Change the state of the port and notify spanning tree */
-@@ -893,6 +896,7 @@ static int br_setport(struct net_bridge_
- br_set_port_flag(p, tb, IFLA_BRPORT_VLAN_TUNNEL, BR_VLAN_TUNNEL);
- br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS);
- br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED);
-+ br_set_port_flag(p, tb, IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER);
-
- changed_mask = old_flags ^ p->flags;
-
---- a/net/core/rtnetlink.c
-+++ b/net/core/rtnetlink.c
-@@ -55,7 +55,7 @@
- #include <net/net_namespace.h>
-
- #define RTNL_MAX_TYPE 50
--#define RTNL_SLAVE_MAX_TYPE 40
-+#define RTNL_SLAVE_MAX_TYPE 41
-
- struct rtnl_link {
- rtnl_doit_func doit;
-@@ -4739,7 +4739,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu
- brport_nla_put_flag(skb, flags, mask,
- IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) ||
- brport_nla_put_flag(skb, flags, mask,
-- IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) {
-+ IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD) ||
-+ brport_nla_put_flag(skb, flags, mask,
-+ IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER)) {
- nla_nest_cancel(skb, protinfo);
- goto nla_put_failure;
- }
diff --git a/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
deleted file mode 100644
index c93fe42273..0000000000
--- a/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Sat, 13 Aug 2022 12:49:33 +0200
-Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
- mode
-
-The rtl8221 supports multiple SERDES modes:
-- SGMII
-- 2500base-x
-- HiSGMII
-
-Further it supports rate adaption on SERDES links to allow
-slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
-links without reducing the SERDES speed.
-
-When operating without rate adapters the SERDES link will follow the
-ethernet speed.
-
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
----
- drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -53,6 +53,15 @@
- RTL8201F_ISR_LINK)
- #define RTL8201F_IER 0x13
-
-+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1
-+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2
-+#define RTL8221B_SERDES_OPTION 0x697a
-+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -841,6 +850,48 @@ static irqreturn_t rtl9000a_handle_inter
- return IRQ_HANDLED;
- }
-
-+static int rtl8221b_config_init(struct phy_device *phydev)
-+{
-+ u16 option_mode;
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ if (!phydev->is_c45) {
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX;
-+ break;
-+ }
-+ fallthrough;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ 0x75f3, 0);
-+
-+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ RTL8221B_SERDES_OPTION,
-+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
-+ switch (option_mode) {
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -981,6 +1032,7 @@ static struct phy_driver realtek_drvs[]
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
-+ .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
-@@ -992,6 +1044,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .config_init = rtl8221b_config_init,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch b/target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
deleted file mode 100644
index 211a8ed297..0000000000
--- a/target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Wed, 8 Feb 2023 16:32:18 +0800
-Subject: [PATCH] net: phy: realtek: support switching between SGMII and
- 2500BASE-X for RTL822x series
-
-After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure
-SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes
-respectively. So add interface automatic switching for rtl8221 phy to
-match various wire speeds.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
----
- drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -676,6 +676,25 @@ static int rtl822x_config_aneg(struct ph
- return __genphy_config_aneg(phydev, ret);
- }
-
-+static void rtl822x_update_interface(struct phy_device *phydev)
-+{
-+ /* Automatically switch SERDES interface between
-+ * SGMII and 2500-BaseX according to speed.
-+ */
-+ switch (phydev->speed) {
-+ case SPEED_2500:
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ break;
-+ case SPEED_1000:
-+ case SPEED_100:
-+ case SPEED_10:
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
- static int rtl822x_read_status(struct phy_device *phydev)
- {
- int ret;
-@@ -694,11 +713,14 @@ static int rtl822x_read_status(struct ph
- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
- }
-
-- ret = genphy_read_status(phydev);
-+ ret = rtlgen_read_status(phydev);
- if (ret < 0)
- return ret;
-
-- return rtlgen_get_speed(phydev);
-+ if (phydev->is_c45 && phydev->link)
-+ rtl822x_update_interface(phydev);
-+
-+ return 0;
- }
-
- static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
diff --git a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch
deleted file mode 100644
index 792135b0d2..0000000000
--- a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 3fb8841513c4ec3a2e5d366df86230c45f239a57 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Sat, 13 Aug 2022 13:08:22 +0200
-Subject: [PATCH 03/10] net: mt7531: ensure all MACs are powered down before
- reset
-
-The datasheet [1] explicit describes it as requirement for a reset.
-
-[1] MT7531 Reference Manual for Development Board rev 1.0, page 735
-
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
----
- drivers/net/dsa/mt7530.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2680,6 +2680,10 @@ mt7531_setup(struct dsa_switch *ds)
- return -ENODEV;
- }
-
-+ /* all MACs must be forced link-down before sw reset */
-+ for (i = 0; i < MT7530_NUM_PORTS; i++)
-+ mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
-+
- /* Reset the switch through internal reset */
- mt7530_write(priv, MT7530_SYS_CTRL,
- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
diff --git a/target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
deleted file mode 100644
index 6941818351..0000000000
--- a/target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 2 Apr 2023 23:56:16 +0100
-Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
-
-Some vendor bootloaders do weird things with those PHYs which result in
-link modes being reported wrongly. Start from a clean sheet by resetting
-the PHY.
-
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1018,6 +1018,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc840),
- .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
-@@ -1030,6 +1031,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc838),
- .name = "RTL8226-CG 2.5Gbps PHY",
-@@ -1040,6 +1042,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc848),
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
-@@ -1050,6 +1053,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
-@@ -1061,6 +1065,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc84a),
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
-@@ -1072,6 +1077,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc961),
- .name = "RTL8366RB Gigabit Ethernet",
diff --git a/target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
deleted file mode 100644
index 1370c6324b..0000000000
--- a/target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 01:21:57 +0300
-Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs
-
-MAC drivers don't use SGMII in-band autonegotiation unless told to do so
-in device tree using 'managed = "in-band-status"'. When using MDIO to
-access a PHY, in-band-status is unneeded as we have link-status via
-MDIO. Switch off SGMII in-band autonegotiation using magic values.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -875,6 +875,7 @@ static irqreturn_t rtl9000a_handle_inter
- static int rtl8221b_config_init(struct phy_device *phydev)
- {
- u16 option_mode;
-+ int val;
-
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_2500BASEX:
-@@ -911,6 +912,13 @@ static int rtl8221b_config_init(struct p
- break;
- }
-
-+ /* Disable SGMII AN */
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3);
-+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587,
-+ val, !(val & BIT(0)), 500, 100000, false);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
deleted file mode 100644
index 31f0622327..0000000000
--- a/target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:21:14 +0100
-Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
-
-As we cannot rely on phy_read_paged function before the PHY is
-identified, the paged read in rtlgen_supports_2_5gbps needs to be open
-coded as it is being called by the match_phy_device function, ie. before
-.read_page and .write_page have been populated.
-
-Make sure it is also protected by the MDIO bus mutex and use
-rtl821x_write_page instead of 3 individually locked MDIO bus operations.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -727,9 +727,11 @@ static bool rtlgen_supports_2_5gbps(stru
- {
- int val;
-
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
-- val = phy_read(phydev, 0x13);
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
-+ mutex_lock(&phydev->mdio.bus->mdio_lock);
-+ rtl821x_write_page(phydev, 0xa61);
-+ val = __phy_read(phydev, 0x13);
-+ rtl821x_write_page(phydev, 0);
-+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
- }
diff --git a/target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
deleted file mode 100644
index a24b4dd79a..0000000000
--- a/target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:23:08 +0100
-Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
- advertisement
-
-Use existing generic inline functions to encode local advertisement
-of 10GbE link modes as well as to decode link-partner advertisement.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 22 +++++-----------------
- 1 file changed, 5 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -68,10 +68,6 @@
- #define RTL_SUPPORTS_5000FULL BIT(14)
- #define RTL_SUPPORTS_2500FULL BIT(13)
- #define RTL_SUPPORTS_10000FULL BIT(0)
--#define RTL_ADV_2500FULL BIT(7)
--#define RTL_LPADV_10000FULL BIT(11)
--#define RTL_LPADV_5000FULL BIT(6)
--#define RTL_LPADV_2500FULL BIT(5)
-
- #define RTL9000A_GINMR 0x14
- #define RTL9000A_GINMR_LINK_STATUS BIT(4)
-@@ -661,14 +657,11 @@ static int rtl822x_config_aneg(struct ph
- int ret = 0;
-
- if (phydev->autoneg == AUTONEG_ENABLE) {
-- u16 adv2500 = 0;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->advertising))
-- adv2500 = RTL_ADV_2500FULL;
--
- ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
-- RTL_ADV_2500FULL, adv2500);
-+ MDIO_AN_10GBT_CTRL_ADV10G |
-+ MDIO_AN_10GBT_CTRL_ADV5G |
-+ MDIO_AN_10GBT_CTRL_ADV2_5G,
-+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising));
- if (ret < 0)
- return ret;
- }
-@@ -705,12 +698,7 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
-+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
- ret = rtlgen_read_status(phydev);
diff --git a/target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
deleted file mode 100644
index 084ee4b645..0000000000
--- a/target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:25:39 +0100
-Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
- advertisement
-
-Only use link-partner advertisement bits for 10GbE modes if they are
-actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
-unless both of them are set.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -698,6 +698,10 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
-+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
-+ lpadv = 0;
-+
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
diff --git a/target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch
deleted file mode 100644
index cea3511b83..0000000000
--- a/target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 03:26:01 +0100
-Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
-
-Setup Link Down Power Saving Mode according the DTS property
-just like for RTL821x 1GE PHYs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -62,6 +62,10 @@
- #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
- #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-
-+#define RTL8221B_PHYCR1 0xa430
-+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
-+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -740,6 +744,25 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl822x_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1);
-+ if (val < 0)
-+ return val;
-+
-+ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
-+ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
-+ else
-+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val);
-+
-+ return 0;
-+}
-+
- static int rtlgen_resume(struct phy_device *phydev)
- {
- int ret = genphy_resume(phydev);
-@@ -1039,6 +1062,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1050,6 +1074,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1062,6 +1087,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1074,6 +1100,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl8221b_config_init,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
deleted file mode 100644
index e3edfa47c6..0000000000
--- a/target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 30 Apr 2023 00:15:41 +0100
-Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
-
-Early versions (?) of the RTL8221B PHY cannot be identified in a regular
-Clause-45 bus scan as the PHY doesn't report the implemented MMDs
-correctly but returns 0 instead.
-Implement custom identify function using the PKGID instead of iterating
-over the implemented MMDs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -79,6 +79,7 @@
- #define RTLGEN_SPEED_MASK 0x0630
-
- #define RTL_GENERIC_PHYID 0x001cc800
-+#define RTL_8221B_VB_CG_PHYID 0x001cc849
-
- MODULE_DESCRIPTION("Realtek PHY driver");
- MODULE_AUTHOR("Johnson Leung");
-@@ -744,6 +745,38 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev)
-+{
-+ int val;
-+ u32 id;
-+
-+ if (phydev->mdio.bus->probe_capabilities >= MDIOBUS_C45) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ } else {
-+ val = phy_read(phydev, MII_PHYSID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read(phydev, MII_PHYSID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ }
-+
-+ return (id == RTL_8221B_VB_CG_PHYID);
-+}
-+
- static int rtl822x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -1082,7 +1115,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .soft_reset = genphy_soft_reset,
- }, {
-- PHY_ID_MATCH_EXACT(0x001cc849),
-+ .match_phy_device = rtl8221b_vb_cg_match_phy_device,
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
diff --git a/target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch
deleted file mode 100644
index 07d46d8daa..0000000000
--- a/target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
-From: Jianhui Zhao <zhaojh329@gmail.com>
-Date: Sun, 24 Sep 2023 22:15:00 +0800
-Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
-
-This commit introduces interrupt support for RTL8221B.
-
-Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
----
- drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -972,6 +972,51 @@ static int rtl8221b_config_init(struct p
- return 0;
- }
-
-+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4);
-+
-+ return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8221b_config_intr(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff);
-+ } else {
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0);
-+ if (err)
-+ return err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ }
-+
-+ return err;
-+}
-+
-+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1120,6 +1165,8 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .config_intr = rtl8221b_config_intr,
-+ .handle_interrupt = rtl8221b_handle_interrupt,
- .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
diff --git a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
deleted file mode 100644
index 1d84ea9ced..0000000000
--- a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 23:39:52 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
- on mt7621
-
-Avoid some branches in the hot path on low-end devices with limited CPU power,
-and reduce code size
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1323,6 +1323,22 @@ 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[];
-
-+#ifdef CONFIG_SOC_MT7621
-+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
-+{
-+ return true;
-+}
-+
-+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
-+{
-+ return false;
-+}
-+
-+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
-+{
-+ return false;
-+}
-+#else
- static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
- {
- return eth->soc->version == 1;
-@@ -1337,6 +1353,7 @@ static inline bool mtk_is_netsys_v3_or_g
- {
- return eth->soc->version > 2;
- }
-+#endif
-
- static inline struct mtk_foe_entry *
- mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
diff --git a/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch
deleted file mode 100644
index 56edb63234..0000000000
--- a/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 3 Nov 2022 12:38:49 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: work around issue with sending
- small fragments
-
-When lots of frames are sent with a number of very small fragments, an
-internal FIFO can overflow, causing the DMA engine to lock up lock up and
-transmit attempts time out.
-
-Fix this on MT7986 by increasing the reserved FIFO space.
-Fix this on older chips by detecting the presence of small fragments and use
-skb_gso_segment + skb_linearize to deal with them.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1516,12 +1516,28 @@ static void mtk_wake_queue(struct mtk_et
- }
- }
-
-+static bool mtk_skb_has_small_frag(struct sk_buff *skb)
-+{
-+ int min_size = 16;
-+ int i;
-+
-+ if (skb_headlen(skb) < min_size)
-+ return true;
-+
-+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-+ if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size)
-+ return true;
-+
-+ return false;
-+}
-+
- static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct net_device_stats *stats = &dev->stats;
-+ struct sk_buff *segs, *next;
- bool gso = false;
- int tx_num;
-
-@@ -1543,6 +1559,18 @@ static netdev_tx_t mtk_start_xmit(struct
- return NETDEV_TX_BUSY;
- }
-
-+ if (mtk_is_netsys_v1(eth) &&
-+ skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) {
-+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO);
-+ if (IS_ERR(segs))
-+ goto drop;
-+
-+ if (segs) {
-+ consume_skb(skb);
-+ skb = segs;
-+ }
-+ }
-+
- /* TSO: fill MSS info in tcp checksum field */
- if (skb_is_gso(skb)) {
- if (skb_cow_head(skb, 0)) {
-@@ -1558,8 +1586,14 @@ static netdev_tx_t mtk_start_xmit(struct
- }
- }
-
-- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
-- goto drop;
-+ skb_list_walk_safe(skb, skb, next) {
-+ if ((mtk_is_netsys_v1(eth) &&
-+ mtk_skb_has_small_frag(skb) && skb_linearize(skb)) ||
-+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) {
-+ stats->tx_dropped++;
-+ dev_kfree_skb_any(skb);
-+ }
-+ }
-
- if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
- netif_tx_stop_all_queues(dev);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -268,7 +268,7 @@
- #define MTK_CHK_DDONE_EN BIT(28)
- #define MTK_DMAD_WR_WDONE BIT(26)
- #define MTK_WCOMP_EN BIT(24)
--#define MTK_RESV_BUF (0x40 << 16)
-+#define MTK_RESV_BUF (0x80 << 16)
- #define MTK_MUTLI_CNT (0x4 << 12)
- #define MTK_LEAKY_BUCKET_EN BIT(11)
-
diff --git a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
deleted file mode 100644
index 11a81dd0bf..0000000000
--- a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 12:54:48 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: set NETIF_F_ALL_TSO
-
-Significantly improves performance by avoiding unnecessary segmentation
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -47,8 +47,7 @@
- #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
- NETIF_F_RXCSUM | \
- NETIF_F_HW_VLAN_CTAG_TX | \
-- NETIF_F_SG | NETIF_F_TSO | \
-- NETIF_F_TSO6 | \
-+ NETIF_F_SG | NETIF_F_ALL_TSO | \
- NETIF_F_IPV6_CSUM |\
- NETIF_F_HW_TC)
- #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM)
diff --git a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch b/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch
deleted file mode 100644
index cc6c9e91bf..0000000000
--- a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 29 Mar 2023 16:02:54 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix remaining throughput
- regression
-
-Based on further tests, it seems that the QDMA shaper is not able to
-perform shaping close to the MAC link rate without throughput loss.
-This cannot be compensated by increasing the shaping rate, so it seems
-to be an internal limit.
-
-Fix the remaining throughput regression by detecting that condition and
-limiting shaping to ports with lower link speed.
-
-This patch intentionally ignores link speed gain from TRGMII, because
-even on such links, shaping to 1000 Mbit/s incurs some throughput
-degradation.
-
-Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues")
-Reported-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -723,6 +723,7 @@ static void mtk_mac_link_up(struct phyli
- MAC_MCR_FORCE_RX_FC);
-
- /* Configure speed */
-+ mac->speed = speed;
- switch (speed) {
- case SPEED_2500:
- case SPEED_1000:
-@@ -3292,6 +3293,9 @@ found:
- if (dp->index >= MTK_QDMA_NUM_QUEUES)
- return NOTIFY_DONE;
-
-+ if (mac->speed > 0 && mac->speed <= s.base.speed)
-+ s.base.speed = 0;
-+
- mtk_set_queue_speed(eth, dp->index + 3, s.base.speed);
-
- return NOTIFY_DONE;
diff --git a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch
deleted file mode 100644
index ed0a544228..0000000000
--- a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 27 Dec 2022 15:02:51 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: ppe: fix L2 offloading with DSA
- untagging offload enabled
-
-Check for skb metadata in order to detect the case where the DSA header is not
-present.
-
-Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -8,6 +8,7 @@
- #include <linux/platform_device.h>
- #include <linux/if_ether.h>
- #include <linux/if_vlan.h>
-+#include <net/dst_metadata.h>
- #include <net/dsa.h>
- #include "mtk_eth_soc.h"
- #include "mtk_ppe.h"
-@@ -835,7 +836,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK)
- goto out;
-
-- tag += 4;
-+ if (!skb_metadata_dst(skb))
-+ tag += 4;
-+
- if (get_unaligned_be16(tag) != ETH_P_8021Q)
- break;
-
diff --git a/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
deleted file mode 100644
index 61c23da821..0000000000
--- a/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
+++ /dev/null
@@ -1,1605 +0,0 @@
-From 1e25ca1147579bda8b941be1b9851f5911d44eb0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 22 Aug 2023 19:04:42 +0100
-Subject: [PATCH 098/125] net: ethernet: mtk_eth_soc: add paths and SerDes
- modes for MT7988
-
-MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes 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
-and the internal 2.5G PHY.
-
-Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
-setup the new PHYA on MT7988 to access the also still existing old
-LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
-modes.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/Kconfig | 16 +
- drivers/net/ethernet/mediatek/Makefile | 1 +
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 123 +++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 182 ++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 232 ++++++-
- drivers/net/ethernet/mediatek/mtk_usxgmii.c | 692 +++++++++++++++++++
- 6 files changed, 1215 insertions(+), 31 deletions(-)
- create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -24,6 +24,22 @@ config NET_MEDIATEK_SOC
- This driver supports the gigabit ethernet MACs in the
- MediaTek SoC family.
-
-+config NET_MEDIATEK_SOC_USXGMII
-+ bool "Support USXGMII SerDes on MT7988"
-+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-+ def_bool NET_MEDIATEK_SOC != n
-+ help
-+ Include support for 10GE SerDes which can be found on MT7988.
-+ If this kernel should run on SoCs with 10 GBit/s Ethernet you
-+ will need to select this option to use GMAC2 and GMAC3 with
-+ external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII
-+ interface modes.
-+
-+ Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS
-+ unit (MediaTek LynxI) in MT7988 is connected via the new 10GE
-+ SerDes, you will also need to select this option in case you
-+ want to use any of those SerDes modes.
-+
- config NET_MEDIATEK_STAR_EMAC
- tristate "MediaTek STAR Ethernet MAC support"
- select PHYLIB
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,6 +5,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-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.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
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64
- return "gmac2_rgmii";
- case MTK_ETH_PATH_GMAC2_SGMII:
- return "gmac2_sgmii";
-+ case MTK_ETH_PATH_GMAC2_2P5GPHY:
-+ 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";
- }
-@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru
- return 0;
- }
-
-+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
-+{
-+ int ret;
-+
-+ if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
-+ ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
-+ if (ret)
-+ return ret;
-+
-+ /* Setup mux to 2p5g PHY */
-+ ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
-+ if (ret)
-+ return ret;
-+
-+ dev_dbg(eth->dev, "path %s in %s updated\n",
-+ mtk_eth_path_name(path), __func__);
-+ }
-+
-+ return 0;
-+}
-+
- static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
-@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_
- 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;
-@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii
- 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;
- }
-@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth
- .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
- .set_path = set_mux_u3_gmac2_to_qphy,
- }, {
-+ .name = "mux_gmac2_to_2p5gphy",
-+ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
-+ .set_path = set_mux_gmac2_to_2p5gphy,
-+ }, {
- .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
- .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
- .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
- }, {
- .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,
- },
- };
-
-@@ -249,12 +336,39 @@ out:
- 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);
-+}
-+
-+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
-+{
-+ u64 path = 0;
-+
-+ if (mac_id == MTK_GMAC2_ID)
-+ path = MTK_ETH_PATH_GMAC2_2P5GPHY;
-+
-+ if (!path)
-+ return -EINVAL;
-
- /* Setup proper MUXes along the path */
- return mtk_eth_mux_setup(eth, path);
-@@ -284,4 +398,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk
- /* Setup proper MUXes along the path */
- return mtk_eth_mux_setup(eth, path);
- }
--
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -432,6 +432,30 @@ static void mtk_setup_bridge_switch(stru
- MTK_GSW_CFG);
- }
-
-+static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
-+{
-+ u32 mac_fsm, gdm_fsm;
-+
-+ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
-+
-+ 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;
-+ };
-+
-+ if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
-+ (gdm_fsm & 0xFFFF0000) == 0x00000000)
-+ return true;
-+
-+ return false;
-+}
-+
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
- phy_interface_t interface)
- {
-@@ -440,12 +464,20 @@ static struct phylink_pcs *mtk_mac_selec
- struct mtk_eth *eth = mac->hw;
- unsigned int sid;
-
-- 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;
--
-- return eth->sgmii_pcs[sid];
-+ if ((interface == PHY_INTERFACE_MODE_SGMII ||
-+ phy_interface_mode_is_8023z(interface)) &&
-+ MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
-+ sid = mtk_mac2xgmii_id(eth, mac->id);
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII))
-+ return mtk_sgmii_wrapper_select_pcs(eth, mac->id);
-+ else
-+ return eth->sgmii_pcs[sid];
-+ } else if ((interface == PHY_INTERFACE_MODE_USXGMII ||
-+ interface == PHY_INTERFACE_MODE_10GBASER ||
-+ interface == PHY_INTERFACE_MODE_5GBASER) &&
-+ MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII) &&
-+ mac->id != MTK_GMAC1_ID) {
-+ return mtk_usxgmii_select_pcs(eth, mac->id);
- }
-
- return NULL;
-@@ -501,7 +533,22 @@ static void mtk_mac_config(struct phylin
- 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)) {
-+ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
-+ if (err)
-+ goto init_err;
-+ }
- break;
- default:
- goto err_phy;
-@@ -556,8 +603,6 @@ static void mtk_mac_config(struct phylin
- 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 */
-@@ -574,21 +619,40 @@ static void mtk_mac_config(struct phylin
-
- /* 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;
- }
-
- /* Setup gmac */
-- if (mtk_is_netsys_v3_or_greater(eth) &&
-- mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
-- mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-- mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ if (mtk_interface_mode_is_xgmii(state->interface)) {
-+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+
-+ if (mac->id == MTK_GMAC1_ID)
-+ mtk_setup_bridge_switch(eth);
-+ } else {
-+ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
-
-- mtk_setup_bridge_switch(eth);
-+ /* 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(mac->interface) ||
-+ mac->interface == PHY_INTERFACE_MODE_NA) &&
-+ !mtk_check_gmac23_idle(mac) &&
-+ !test_bit(MTK_RESETTING, &eth->state))
-+ schedule_work(&eth->pending_work);
-+ }
- }
-
-+ mac->interface = state->interface;
-+
- return;
-
- err_phy:
-@@ -633,10 +697,14 @@ static void mtk_mac_link_down(struct phy
- {
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
- phylink_config);
-- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-
-- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
-- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-+ if (!mtk_interface_mode_is_xgmii(interface)) {
-+ 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(eth))
-+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
-+ } else if (mac->id != MTK_GMAC1_ID) {
-+ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
-+ }
- }
-
- static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-@@ -708,13 +776,11 @@ static void mtk_set_queue_speed(struct m
- mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
- }
-
--static void mtk_mac_link_up(struct phylink_config *config,
-- struct phy_device *phy,
-- unsigned int mode, phy_interface_t interface,
-- int speed, int duplex, bool tx_pause, bool rx_pause)
-+static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
- {
-- struct mtk_mac *mac = container_of(config, struct mtk_mac,
-- phylink_config);
- u32 mcr;
-
- mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-@@ -748,6 +814,55 @@ static void mtk_mac_link_up(struct phyli
- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-
-+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ u32 mcr, force_link = 0;
-+
-+ if (mac->id == MTK_GMAC1_ID)
-+ return;
-+
-+ /* Eliminate the interference(before link-up) caused by PHY noise */
-+ mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
-+ mdelay(20);
-+ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
-+
-+ if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
-+ force_link = MTK_XGMAC_FORCE_LINK(mac->id);
-+
-+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
-+
-+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
-+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
-+ /* Configure pause modes -
-+ * phylink will avoid these for half duplex
-+ */
-+ if (tx_pause)
-+ mcr |= XMAC_MCR_FORCE_TX_FC;
-+ if (rx_pause)
-+ mcr |= XMAC_MCR_FORCE_RX_FC;
-+
-+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
-+}
-+
-+static void mtk_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+ phylink_config);
-+
-+ if (mtk_interface_mode_is_xgmii(interface))
-+ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+ tx_pause, rx_pause);
-+ else
-+ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+ tx_pause, rx_pause);
-+}
-+
- static const struct phylink_mac_ops mtk_phylink_ops = {
- .validate = phylink_generic_validate,
- .mac_select_pcs = mtk_mac_select_pcs,
-@@ -4562,8 +4677,21 @@ static int mtk_add_mac(struct mtk_eth *e
- 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);
- }
-
-+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
-+ id == MTK_GMAC2_ID)
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ mac->phylink_config.supported_interfaces);
-+
- phylink = phylink_create(&mac->phylink_config,
- of_fwnode_handle(mac->of_node),
- phy_mode, &mtk_phylink_ops);
-@@ -4756,6 +4884,13 @@ static int mtk_probe(struct platform_dev
-
- if (err)
- return err;
-+ }
-+
-+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
-+ err = mtk_usxgmii_init(eth);
-+
-+ if (err)
-+ return err;
- }
-
- if (eth->soc->required_pctl) {
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -499,6 +499,21 @@
- #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
- #define INTF_MODE_RGMII_10_100 0
-
-+/* XFI Mac control registers */
-+#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000))
-+#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x))
-+#define XMAC_MCR_TRX_DISABLE 0xf
-+#define XMAC_MCR_FORCE_TX_FC BIT(5)
-+#define XMAC_MCR_FORCE_RX_FC BIT(4)
-+
-+/* XFI Mac logic reset registers */
-+#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10)
-+#define XMAC_LOGIC_RST BIT(0)
-+
-+/* XFI Mac count global control */
-+#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100)
-+#define XMAC_GLB_CNTCLR BIT(0)
-+
- /* GPIO port control registers for GMAC 2*/
- #define GPIO_OD33_CTRL8 0x4c0
- #define GPIO_BIAS_CTRL 0xed0
-@@ -524,6 +539,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 */
-@@ -556,12 +572,74 @@
- #define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
- #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-
-+/* 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_RX_MODE_10G 0
-+#define USXGMII_XFI_RX_MODE_5G 1
-+#define USXGMII_XFI_TX_MODE GENMASK(2, 0)
-+#define USXGMII_XFI_TX_MODE_10G 0
-+#define USXGMII_XFI_TX_MODE_5G 1
-+
-+/* 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_PCS_AN_WORD GENMASK(15, 0)
-+#define USXGMII_LPA_LATCH BIT(31)
-+
-+/* Register to control USXGMII XFI PLL digital */
-+#define XFI_PLL_DIG_GLB8 0x08
-+#define RG_XFI_PLL_EN BIT(31)
-+
-+/* Register to control USXGMII XFI PLL analog */
-+#define XFI_PLL_ANA_GLB8 0x108
-+#define RG_XFI_PLL_ANA_SWWA 0x02283248
-+
- /* Infrasys subsystem config registers */
- #define INFRA_MISC2 0x70c
- #define CO_QPHY_SEL BIT(0)
- #define GEPHY_MAC_SEL BIT(1)
-
-+/* Toprgu subsystem config registers */
-+#define TOPRGU_SWSYSRST 0x18
-+#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24)
-+#define SWSYSRST_XFI_PLL_GRST BIT(16)
-+#define SWSYSRST_XFI_PEXPT1_GRST BIT(15)
-+#define SWSYSRST_XFI_PEXPT0_GRST BIT(14)
-+#define SWSYSRST_XFI1_GRST BIT(13)
-+#define SWSYSRST_XFI0_GRST BIT(12)
-+#define SWSYSRST_SGMII1_GRST BIT(2)
-+#define SWSYSRST_SGMII0_GRST BIT(1)
-+#define TOPRGU_SWSYSRST_EN 0xFC
-+
- /* Top misc registers */
-+#define TOP_MISC_NETSYS_PCS_MUX 0x84
-+#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)
- #define SGMII_QPHY_SEL 0x2
-@@ -586,6 +664,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
-@@ -594,6 +674,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))
-
-@@ -940,6 +1025,8 @@ 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,
- MTK_MUX_BIT,
-@@ -960,8 +1047,11 @@ enum mkt_eth_capabilities {
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
- MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
- MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
-+ 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,
-@@ -969,14 +1059,21 @@ enum mkt_eth_capabilities {
- MTK_ETH_PATH_GMAC1_SGMII_BIT,
- MTK_ETH_PATH_GMAC2_RGMII_BIT,
- 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)
- #define MTK_MUX BIT_ULL(MTK_MUX_BIT)
-@@ -999,10 +1096,16 @@ enum mkt_eth_capabilities {
- BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
- BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \
-+ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
- 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)
-@@ -1010,8 +1113,13 @@ enum mkt_eth_capabilities {
- #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
- #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)
-@@ -1019,7 +1127,12 @@ enum mkt_eth_capabilities {
- #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
- #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 */
-@@ -1038,10 +1151,20 @@ enum mkt_eth_capabilities {
- (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
- MTK_SHARED_SGMII)
-
-+/* 2: GMAC2 -> XGMII */
-+#define MTK_MUX_GMAC2_TO_2P5GPHY \
-+ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
-+
- /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
- #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 | \
-@@ -1073,8 +1196,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_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;
-@@ -1184,6 +1311,24 @@ struct mtk_soc_data {
- /* currently no SoC has more than 3 macs */
- #define MTK_MAX_DEVS 3
-
-+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and
-+ * associated data
-+ * @regmap: The register map pointing at the range used to setup
-+ * USXGMII modes
-+ * @interface: Currently selected interface mode
-+ * @id: The element is used to record the index of PCS
-+ * @pcs: Phylink PCS structure
-+ */
-+struct mtk_usxgmii_pcs {
-+ struct mtk_eth *eth;
-+ struct regmap *regmap;
-+ struct phylink_pcs *wrapped_sgmii_pcs;
-+ phy_interface_t interface;
-+ u8 id;
-+ unsigned int mode;
-+ struct phylink_pcs pcs;
-+};
-+
- /* struct mtk_eth - This is the main datasructure for holding the state
- * of the driver
- * @dev: The device pointer
-@@ -1204,6 +1349,12 @@ struct mtk_soc_data {
- * @infra: The register map pointing at the range used to setup
- * SGMII and GePHY path
- * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances
-+ * @sgmii_wrapped_pcs: Pointers to NETSYSv3 wrapper PCS instances
-+ * @usxgmii_pll: The register map pointing at the range used to control
-+ * the USXGMII SerDes PLL
-+ * @regmap_pextp: The register map pointing at the range used to setup
-+ * PHYA
-+ * @usxgmii_pcs: Pointer to array of pointers to struct for USXGMII PCS
- * @pctl: The register map pointing at the range used to setup
- * GMAC port drive/slew values
- * @dma_refcnt: track how many netdevs are using the DMA engine
-@@ -1247,6 +1398,10 @@ struct mtk_eth {
- struct regmap *ethsys;
- struct regmap *infra;
- struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
-+ struct regmap *toprgu;
-+ struct regmap *usxgmii_pll;
-+ struct regmap *regmap_pextp[MTK_MAX_DEVS];
-+ struct mtk_usxgmii_pcs *usxgmii_pcs[MTK_MAX_DEVS];
- struct regmap *pctl;
- bool hwlro;
- refcount_t dma_refcnt;
-@@ -1434,6 +1589,19 @@ static inline u32 mtk_get_ib2_multicast_
- return MTK_FOE_IB2_MULTICAST;
- }
-
-+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
-+{
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_INTERNAL:
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ case PHY_INTERFACE_MODE_5GBASER:
-+ return true;
-+ default:
-+ return false;
-+ }
-+}
-+
- /* read the hardware status register */
- void mtk_stats_update_mac(struct mtk_mac *mac);
-
-@@ -1442,8 +1610,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
- u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
-
- 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);
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
-@@ -1453,5 +1623,63 @@ int mtk_flow_offload_cmd(struct mtk_eth
- void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
- void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
-
-+static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id)
-+{
-+ int xgmii_id = mac_id;
-+
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ switch (mac_id) {
-+ case MTK_GMAC1_ID:
-+ case MTK_GMAC2_ID:
-+ xgmii_id = 1;
-+ break;
-+ case MTK_GMAC3_ID:
-+ xgmii_id = 0;
-+ break;
-+ default:
-+ xgmii_id = -1;
-+ }
-+ }
-+
-+ return MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII) ? 0 : xgmii_id;
-+}
-+
-+static inline int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id)
-+{
-+ int mac_id = xgmii_id;
-+
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ switch (xgmii_id) {
-+ case 0:
-+ mac_id = 2;
-+ break;
-+ case 1:
-+ mac_id = 1;
-+ break;
-+ default:
-+ mac_id = -1;
-+ }
-+ }
-+
-+ return mac_id;
-+}
-+
-+#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII
-+struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id);
-+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id);
-+int mtk_usxgmii_init(struct mtk_eth *eth);
-+#else
-+static inline struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id)
-+{
-+ return NULL;
-+}
-+
-+static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id)
-+{
-+ return NULL;
-+}
-+
-+static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; }
-+#endif /* NET_MEDIATEK_SOC_USXGMII */
-
- #endif /* MTK_ETH_H */
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c
-@@ -0,0 +1,690 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Henry Yen <henry.yen@mediatek.com>
-+ * Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/mfd/syscon.h>
-+#include <linux/of.h>
-+#include <linux/regmap.h>
-+#include "mtk_eth_soc.h"
-+
-+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
-+{
-+ return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
-+}
-+
-+static int mtk_xfi_pextp_init(struct mtk_eth *eth)
-+{
-+ struct device *dev = eth->dev;
-+ struct device_node *r = dev->of_node;
-+ struct device_node *np;
-+ int i;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ np = of_parse_phandle(r, "mediatek,xfi-pextp", i);
-+ if (!np)
-+ break;
-+
-+ eth->regmap_pextp[i] = syscon_node_to_regmap(np);
-+ if (IS_ERR(eth->regmap_pextp[i]))
-+ return PTR_ERR(eth->regmap_pextp[i]);
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_xfi_pll_init(struct mtk_eth *eth)
-+{
-+ struct device_node *r = eth->dev->of_node;
-+ struct device_node *np;
-+
-+ np = of_parse_phandle(r, "mediatek,xfi-pll", 0);
-+ if (!np)
-+ return -1;
-+
-+ eth->usxgmii_pll = syscon_node_to_regmap(np);
-+ if (IS_ERR(eth->usxgmii_pll))
-+ return PTR_ERR(eth->usxgmii_pll);
-+
-+ return 0;
-+}
-+
-+static int mtk_toprgu_init(struct mtk_eth *eth)
-+{
-+ struct device_node *r = eth->dev->of_node;
-+ struct device_node *np;
-+
-+ np = of_parse_phandle(r, "mediatek,toprgu", 0);
-+ if (!np)
-+ return -1;
-+
-+ eth->toprgu = syscon_node_to_regmap(np);
-+ if (IS_ERR(eth->toprgu))
-+ return PTR_ERR(eth->toprgu);
-+
-+ return 0;
-+}
-+
-+static int mtk_xfi_pll_enable(struct mtk_eth *eth)
-+{
-+ u32 val = 0;
-+
-+ if (!eth->usxgmii_pll)
-+ return -EINVAL;
-+
-+ /* Add software workaround for USXGMII PLL TCL issue */
-+ regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA);
-+
-+ regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val);
-+ val |= RG_XFI_PLL_EN;
-+ regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val);
-+
-+ return 0;
-+}
-+
-+static void mtk_usxgmii_setup_phya(struct regmap *pextp, phy_interface_t interface, int id)
-+{
-+ bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
-+ interface == PHY_INTERFACE_MODE_USXGMII);
-+ bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
-+ bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
-+
-+ /* Setup operation mode */
-+ if (is_10g)
-+ regmap_write(pextp, 0x9024, 0x00C9071C);
-+ else
-+ regmap_write(pextp, 0x9024, 0x00D9071C);
-+
-+ if (is_5g)
-+ regmap_write(pextp, 0x2020, 0xAAA5A5AA);
-+ else
-+ regmap_write(pextp, 0x2020, 0xAA8585AA);
-+
-+ if (is_2p5g || is_5g || is_10g) {
-+ regmap_write(pextp, 0x2030, 0x0C020707);
-+ regmap_write(pextp, 0x2034, 0x0E050F0F);
-+ regmap_write(pextp, 0x2040, 0x00140032);
-+ } else {
-+ regmap_write(pextp, 0x2030, 0x0C020207);
-+ regmap_write(pextp, 0x2034, 0x0E05050F);
-+ regmap_write(pextp, 0x2040, 0x00200032);
-+ }
-+
-+ if (is_2p5g || is_10g)
-+ regmap_write(pextp, 0x50F0, 0x00C014AA);
-+ else if (is_5g)
-+ regmap_write(pextp, 0x50F0, 0x00C018AA);
-+ else
-+ regmap_write(pextp, 0x50F0, 0x00C014BA);
-+
-+ if (is_5g) {
-+ regmap_write(pextp, 0x50E0, 0x3777812B);
-+ regmap_write(pextp, 0x506C, 0x005C9CFF);
-+ regmap_write(pextp, 0x5070, 0x9DFAFAFA);
-+ regmap_write(pextp, 0x5074, 0x273F3F3F);
-+ regmap_write(pextp, 0x5078, 0xA8883868);
-+ regmap_write(pextp, 0x507C, 0x14661466);
-+ } else {
-+ regmap_write(pextp, 0x50E0, 0x3777C12B);
-+ regmap_write(pextp, 0x506C, 0x005F9CFF);
-+ regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+ regmap_write(pextp, 0x5074, 0x27273F3F);
-+ regmap_write(pextp, 0x5078, 0xA7883C68);
-+ regmap_write(pextp, 0x507C, 0x11661166);
-+ }
-+
-+ if (is_2p5g || is_10g) {
-+ regmap_write(pextp, 0x5080, 0x0E000AAF);
-+ regmap_write(pextp, 0x5084, 0x08080D0D);
-+ regmap_write(pextp, 0x5088, 0x02030909);
-+ } else if (is_5g) {
-+ regmap_write(pextp, 0x5080, 0x0E001ABF);
-+ regmap_write(pextp, 0x5084, 0x080B0D0D);
-+ regmap_write(pextp, 0x5088, 0x02050909);
-+ } else {
-+ regmap_write(pextp, 0x5080, 0x0E000EAF);
-+ regmap_write(pextp, 0x5084, 0x08080E0D);
-+ regmap_write(pextp, 0x5088, 0x02030B09);
-+ }
-+
-+ if (is_5g) {
-+ regmap_write(pextp, 0x50E4, 0x0C000000);
-+ regmap_write(pextp, 0x50E8, 0x04000000);
-+ } else {
-+ regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+ regmap_write(pextp, 0x50E8, 0x04040000);
-+ }
-+
-+ if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
-+ regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+ else
-+ regmap_write(pextp, 0x50EC, 0x0F0F0606);
-+
-+ if (is_5g) {
-+ regmap_write(pextp, 0x50A8, 0x50808C8C);
-+ regmap_write(pextp, 0x6004, 0x18000000);
-+ } else {
-+ regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+ regmap_write(pextp, 0x6004, 0x18190000);
-+ }
-+
-+ if (is_10g)
-+ regmap_write(pextp, 0x00F8, 0x01423342);
-+ else if (is_5g)
-+ regmap_write(pextp, 0x00F8, 0x00A132A1);
-+ else if (is_2p5g)
-+ regmap_write(pextp, 0x00F8, 0x009C329C);
-+ else
-+ regmap_write(pextp, 0x00F8, 0x00FA32FA);
-+
-+ /* Force SGDT_OUT off and select PCS */
-+ if (mtk_interface_mode_is_xgmii(interface))
-+ regmap_write(pextp, 0x00F4, 0x80201F20);
-+ else
-+ regmap_write(pextp, 0x00F4, 0x80201F21);
-+
-+ /* Force GLB_CKDET_OUT */
-+ regmap_write(pextp, 0x0030, 0x00050C00);
-+
-+ /* Force AEQ on */
-+ regmap_write(pextp, 0x0070, 0x02002800);
-+ ndelay(1020);
-+
-+ /* Setup DA default value */
-+ regmap_write(pextp, 0x30B0, 0x00000020);
-+ regmap_write(pextp, 0x3028, 0x00008A01);
-+ regmap_write(pextp, 0x302C, 0x0000A884);
-+ regmap_write(pextp, 0x3024, 0x00083002);
-+ if (mtk_interface_mode_is_xgmii(interface)) {
-+ regmap_write(pextp, 0x3010, 0x00022220);
-+ regmap_write(pextp, 0x5064, 0x0F020A01);
-+ regmap_write(pextp, 0x50B4, 0x06100600);
-+ if (interface == PHY_INTERFACE_MODE_USXGMII)
-+ regmap_write(pextp, 0x3048, 0x40704000);
-+ else
-+ regmap_write(pextp, 0x3048, 0x47684100);
-+ } else {
-+ regmap_write(pextp, 0x3010, 0x00011110);
-+ regmap_write(pextp, 0x3048, 0x40704000);
-+ }
-+
-+ if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
-+ regmap_write(pextp, 0x3064, 0x0000C000);
-+
-+ if (interface == PHY_INTERFACE_MODE_USXGMII) {
-+ regmap_write(pextp, 0x3050, 0xA8000000);
-+ regmap_write(pextp, 0x3054, 0x000000AA);
-+ } else if (mtk_interface_mode_is_xgmii(interface)) {
-+ regmap_write(pextp, 0x3050, 0x00000000);
-+ regmap_write(pextp, 0x3054, 0x00000000);
-+ } else {
-+ regmap_write(pextp, 0x3050, 0xA8000000);
-+ regmap_write(pextp, 0x3054, 0x000000AA);
-+ }
-+
-+ if (mtk_interface_mode_is_xgmii(interface))
-+ regmap_write(pextp, 0x306C, 0x00000F00);
-+ else if (is_2p5g)
-+ regmap_write(pextp, 0x306C, 0x22000F00);
-+ else
-+ regmap_write(pextp, 0x306C, 0x20200F00);
-+
-+ if (interface == PHY_INTERFACE_MODE_10GBASER && id == 0)
-+ regmap_write(pextp, 0xA008, 0x0007B400);
-+
-+ if (mtk_interface_mode_is_xgmii(interface))
-+ regmap_write(pextp, 0xA060, 0x00040000);
-+ else
-+ regmap_write(pextp, 0xA060, 0x00050000);
-+
-+ if (is_10g)
-+ regmap_write(pextp, 0x90D0, 0x00000001);
-+ else if (is_5g)
-+ regmap_write(pextp, 0x90D0, 0x00000003);
-+ else if (is_2p5g)
-+ regmap_write(pextp, 0x90D0, 0x00000005);
-+ else
-+ regmap_write(pextp, 0x90D0, 0x00000007);
-+
-+ /* Release reset */
-+ regmap_write(pextp, 0x0070, 0x0200E800);
-+ usleep_range(150, 500);
-+
-+ /* Switch to P0 */
-+ regmap_write(pextp, 0x0070, 0x0200C111);
-+ ndelay(1020);
-+ regmap_write(pextp, 0x0070, 0x0200C101);
-+ usleep_range(15, 50);
-+
-+ if (mtk_interface_mode_is_xgmii(interface)) {
-+ /* Switch to Gen3 */
-+ regmap_write(pextp, 0x0070, 0x0202C111);
-+ } else {
-+ /* Switch to Gen2 */
-+ regmap_write(pextp, 0x0070, 0x0201C111);
-+ }
-+ ndelay(1020);
-+ if (mtk_interface_mode_is_xgmii(interface))
-+ regmap_write(pextp, 0x0070, 0x0202C101);
-+ else
-+ regmap_write(pextp, 0x0070, 0x0201C101);
-+ usleep_range(100, 500);
-+ regmap_write(pextp, 0x30B0, 0x00000030);
-+ if (mtk_interface_mode_is_xgmii(interface))
-+ regmap_write(pextp, 0x00F4, 0x80201F00);
-+ else
-+ regmap_write(pextp, 0x00F4, 0x80201F01);
-+
-+ regmap_write(pextp, 0x3040, 0x30000000);
-+ usleep_range(400, 1000);
-+}
-+
-+static void mtk_usxgmii_reset(struct mtk_eth *eth, int id)
-+{
-+ u32 toggle, val;
-+
-+ if (id >= MTK_MAX_DEVS || !eth->toprgu)
-+ return;
-+
-+ switch (id) {
-+ case 0:
-+ toggle = SWSYSRST_XFI_PEXPT0_GRST | SWSYSRST_XFI0_GRST |
-+ SWSYSRST_SGMII0_GRST;
-+ break;
-+ case 1:
-+ toggle = SWSYSRST_XFI_PEXPT1_GRST | SWSYSRST_XFI1_GRST |
-+ SWSYSRST_SGMII1_GRST;
-+ break;
-+ default:
-+ return;
-+ }
-+
-+ /* Enable software reset */
-+ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
-+
-+ /* Assert USXGMII reset */
-+ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST,
-+ FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | toggle);
-+
-+ usleep_range(100, 500);
-+
-+ /* De-assert USXGMII reset */
-+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
-+ val &= ~toggle;
-+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+ /* Disable software reset */
-+ regmap_clear_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
-+
-+ mdelay(10);
-+}
-+
-+/* As the USXGMII PHYA is shared with the 1000Base-X/2500Base-X/Cisco SGMII unit
-+ * the psc-mtk-lynxi instance needs to be wrapped, so that calls to .pcs_config
-+ * also trigger an initial reset and subsequent configuration of the PHYA.
-+ */
-+struct mtk_sgmii_wrapper_pcs {
-+ struct mtk_eth *eth;
-+ struct phylink_pcs *wrapped_pcs;
-+ u8 id;
-+ struct phylink_pcs pcs;
-+};
-+
-+static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs,
-+ unsigned int mode,
-+ phy_interface_t interface,
-+ const unsigned long *advertising,
-+ bool permit_pause_to_mac)
-+{
-+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
-+ bool full_reconf;
-+ int ret;
-+
-+ full_reconf = interface != wp->eth->usxgmii_pcs[wp->id]->interface;
-+ if (full_reconf) {
-+ mtk_xfi_pll_enable(wp->eth);
-+ mtk_usxgmii_reset(wp->eth, wp->id);
-+ }
-+
-+ ret = wp->wrapped_pcs->ops->pcs_config(wp->wrapped_pcs, mode, interface,
-+ advertising, permit_pause_to_mac);
-+
-+ if (full_reconf)
-+ mtk_usxgmii_setup_phya(wp->eth->regmap_pextp[wp->id], interface, wp->id);
-+
-+ wp->eth->usxgmii_pcs[wp->id]->interface = interface;
-+
-+ return ret;
-+}
-+
-+static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
-+{
-+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
-+
-+ return wp->wrapped_pcs->ops->pcs_get_state(wp->wrapped_pcs, state);
-+}
-+
-+static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs)
-+{
-+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
-+
-+ wp->wrapped_pcs->ops->pcs_an_restart(wp->wrapped_pcs);
-+}
-+
-+static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs,
-+ unsigned int mode,
-+ phy_interface_t interface, int speed,
-+ int duplex)
-+{
-+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
-+
-+ wp->wrapped_pcs->ops->pcs_link_up(wp->wrapped_pcs, mode, interface, speed, duplex);
-+}
-+
-+static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs)
-+{
-+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
-+
-+ wp->wrapped_pcs->ops->pcs_disable(wp->wrapped_pcs);
-+
-+ wp->eth->usxgmii_pcs[wp->id]->interface = PHY_INTERFACE_MODE_NA;
-+}
-+
-+static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = {
-+ .pcs_get_state = mtk_sgmii_wrapped_pcs_get_state,
-+ .pcs_config = mtk_sgmii_wrapped_pcs_config,
-+ .pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart,
-+ .pcs_link_up = mtk_sgmii_wrapped_pcs_link_up,
-+ .pcs_disable = mtk_sgmii_wrapped_pcs_disable,
-+};
-+
-+static int mtk_sgmii_wrapper_init(struct mtk_eth *eth)
-+{
-+ struct mtk_sgmii_wrapper_pcs *wp;
-+ int i;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ if (!eth->sgmii_pcs[i])
-+ continue;
-+
-+ if (!eth->usxgmii_pcs[i])
-+ continue;
-+
-+ /* Make sure all PCS ops are supported by wrapped PCS */
-+ if (!eth->sgmii_pcs[i]->ops->pcs_get_state ||
-+ !eth->sgmii_pcs[i]->ops->pcs_config ||
-+ !eth->sgmii_pcs[i]->ops->pcs_an_restart ||
-+ !eth->sgmii_pcs[i]->ops->pcs_link_up ||
-+ !eth->sgmii_pcs[i]->ops->pcs_disable)
-+ return -EOPNOTSUPP;
-+
-+ wp = devm_kzalloc(eth->dev, sizeof(*wp), GFP_KERNEL);
-+ if (!wp)
-+ return -ENOMEM;
-+
-+ wp->wrapped_pcs = eth->sgmii_pcs[i];
-+ wp->id = i;
-+ wp->pcs.poll = true;
-+ wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops;
-+ wp->eth = eth;
-+
-+ eth->usxgmii_pcs[i]->wrapped_sgmii_pcs = &wp->pcs;
-+ }
-+
-+ return 0;
-+}
-+
-+struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int mac_id)
-+{
-+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
-+
-+ if (!eth->usxgmii_pcs[xgmii_id])
-+ return NULL;
-+
-+ return eth->usxgmii_pcs[xgmii_id]->wrapped_sgmii_pcs;
-+}
-+
-+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int 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);
-+ struct mtk_eth *eth = mpcs->eth;
-+ struct regmap *pextp = eth->regmap_pextp[mpcs->id];
-+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
-+ bool mode_changed = false;
-+
-+ if (!pextp)
-+ return -ENODEV;
-+
-+ 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_RX_MODE_10G) |
-+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_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_RX_MODE_10G) |
-+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_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_RX_MODE_5G) |
-+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_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;
-+ }
-+
-+ mtk_xfi_pll_enable(eth);
-+ mtk_usxgmii_reset(eth, mpcs->id);
-+
-+ /* Setup USXGMII AN ctrl */
-+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0,
-+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
-+ an_ctrl);
-+
-+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2,
-+ USXGMII_LINK_TIMER_IDLE_DETECT |
-+ USXGMII_LINK_TIMER_COMP_ACK_DETECT |
-+ USXGMII_LINK_TIMER_AN_RESTART,
-+ link_timer);
-+
-+ mpcs->mode = mode;
-+
-+ /* Gated MAC CK */
-+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
-+
-+ /* Enable interface force mode */
-+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
-+
-+ /* Setup USXGMII adapt mode */
-+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
-+ adapt_mode);
-+
-+ /* Setup USXGMII speed */
-+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
-+ xfi_mode);
-+
-+ usleep_range(1, 10);
-+
-+ /* Un-gated MAC CK */
-+ regmap_update_bits(mpcs->regmap, 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)
-+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+ USXGMII_IF_FORCE_EN, 0);
-+
-+ /* Setup USXGMIISYS with the determined property */
-+ mtk_usxgmii_setup_phya(pextp, interface, mpcs->id);
-+
-+ return mode_changed;
-+}
-+
-+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
-+ struct phylink_link_state *state)
-+{
-+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+ struct mtk_eth *eth = mpcs->eth;
-+ struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)];
-+ u32 val = 0;
-+
-+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
-+ if (FIELD_GET(USXGMII_AN_ENABLE, val)) {
-+ /* Refresh LPA by inverting LPA_LATCH */
-+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
-+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0,
-+ USXGMII_LPA_LATCH,
-+ !(val & USXGMII_LPA_LATCH));
-+
-+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
-+
-+ phylink_decode_usxgmii_word(state, FIELD_GET(USXGMII_PCS_AN_WORD,
-+ val));
-+
-+ state->interface = mpcs->interface;
-+ } else {
-+ val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-+
-+ if (mac->id == MTK_GMAC2_ID)
-+ val >>= 16;
-+
-+ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) {
-+ case 0:
-+ state->speed = SPEED_10000;
-+ break;
-+ case 1:
-+ state->speed = SPEED_5000;
-+ break;
-+ case 2:
-+ state->speed = SPEED_2500;
-+ break;
-+ case 3:
-+ state->speed = SPEED_1000;
-+ break;
-+ }
-+
-+ state->interface = mpcs->interface;
-+ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val);
-+ state->duplex = DUPLEX_FULL;
-+ }
-+
-+ /* Continuously repeat re-configuration sequence until link comes up */
-+ if (state->link == 0)
-+ mtk_usxgmii_pcs_config(pcs, mpcs->mode,
-+ state->interface, NULL, false);
-+}
-+
-+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
-+{
-+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+ unsigned int val = 0;
-+
-+ if (!mpcs->regmap)
-+ return;
-+
-+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
-+ val |= USXGMII_AN_RESTART;
-+ regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
-+}
-+
-+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+ phy_interface_t interface,
-+ int speed, int duplex)
-+{
-+ /* Reconfiguring USXGMII to ensure the quality of the RX signal
-+ * after the line side link up.
-+ */
-+ mtk_usxgmii_pcs_config(pcs, mode,
-+ interface, NULL, false);
-+}
-+
-+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
-+ .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,
-+};
-+
-+int mtk_usxgmii_init(struct mtk_eth *eth)
-+{
-+ struct device_node *r = eth->dev->of_node;
-+ struct device *dev = eth->dev;
-+ struct device_node *np;
-+ int i, ret;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ np = of_parse_phandle(r, "mediatek,usxgmiisys", i);
-+ if (!np)
-+ break;
-+
-+ eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs[i]), GFP_KERNEL);
-+ if (!eth->usxgmii_pcs[i])
-+ return -ENOMEM;
-+
-+ eth->usxgmii_pcs[i]->id = i;
-+ eth->usxgmii_pcs[i]->eth = eth;
-+ eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np);
-+ if (IS_ERR(eth->usxgmii_pcs[i]->regmap))
-+ return PTR_ERR(eth->usxgmii_pcs[i]->regmap);
-+
-+ eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops;
-+ eth->usxgmii_pcs[i]->pcs.poll = true;
-+ eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA;
-+ eth->usxgmii_pcs[i]->mode = -1;
-+
-+ of_node_put(np);
-+ }
-+
-+ ret = mtk_xfi_pextp_init(eth);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_xfi_pll_init(eth);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_toprgu_init(eth);
-+ if (ret)
-+ return ret;
-+
-+ return mtk_sgmii_wrapper_init(eth);
-+}
-+
-+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id)
-+{
-+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
-+
-+ if (!eth->usxgmii_pcs[xgmii_id]->regmap)
-+ return NULL;
-+
-+ return &eth->usxgmii_pcs[xgmii_id]->pcs;
-+}
diff --git a/target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch b/target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch
deleted file mode 100644
index dda864ab4d..0000000000
--- a/target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From dee3f591103910c8d8b2a6d57879ccd2a4be4b10 Mon Sep 17 00:00:00 2001
-Message-ID: <dee3f591103910c8d8b2a6d57879ccd2a4be4b10.1706067287.git.daniel@makrotopia.org>
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 24 Jan 2024 03:19:49 +0000
-Subject: [PATCH net] net: ethernet: mtk_eth_soc: set coherent mask to get PPE
- working
-To: Felix Fietkau <nbd@nbd.name>,
- Sean Wang <sean.wang@mediatek.com>,
- Mark Lee <Mark-MC.Lee@mediatek.com>,
- Lorenzo Bianconi <lorenzo@kernel.org>,
- David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Daniel Golle <daniel@makrotopia.org>,
- netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org
-
-Set DMA coherent mask to 32-bit which makes PPE offloading engine start
-working on BPi-R4 which got 4 GiB of RAM.
-
-Fixes: 2d75891ebc09 ("net: ethernet: mtk_eth_soc: support 36-bit DMA addressing on MT7988")
-Suggested-by: Elad Yifee <eladwf@users.github.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4832,7 +4832,10 @@ static int mtk_probe(struct platform_dev
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
-- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
-+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
-+ if (!err)
-+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-+
- if (err) {
- dev_err(&pdev->dev, "Wrong DMA config\n");
- return -EINVAL;
diff --git a/target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch b/target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch
deleted file mode 100644
index 2a1f908cfb..0000000000
--- a/target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 6f291aa7da199c6486cc229b055dcbcd5cee7a21 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sun, 21 May 2023 22:24:56 +0200
-Subject: [PATCH] net: phy: motorcomm: Add missing include
-
-Directly include linux/bitfield.h which provides FIELD_PREP.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/net/phy/motorcomm.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -6,6 +6,7 @@
- * Author: Frank <Frank.Sae@motor-comm.com>
- */
-
-+#include <linux/bitfield.h>
- #include <linux/etherdevice.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
diff --git a/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch b/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch
deleted file mode 100644
index 54c07f0022..0000000000
--- a/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From: Alexander Duyck <alexanderduyck@fb.com>
-Date: Thu, 26 Jan 2023 11:06:59 -0800
-Subject: [PATCH] skb: Do mix page pool and page referenced frags in GRO
-
-GSO should not merge page pool recycled frames with standard reference
-counted frames. Traditionally this didn't occur, at least not often.
-However as we start looking at adding support for wireless adapters there
-becomes the potential to mix the two due to A-MSDU repartitioning frames in
-the receive path. There are possibly other places where this may have
-occurred however I suspect they must be few and far between as we have not
-seen this issue until now.
-
-Fixes: 53e0961da1c7 ("page_pool: add frag page recycling support in page pool")
-Reported-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
----
-
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -4360,6 +4360,15 @@ int skb_gro_receive(struct sk_buff *p, s
- if (unlikely(p->len + len >= 65536 || NAPI_GRO_CB(skb)->flush))
- return -E2BIG;
-
-+ /* Do not splice page pool based packets w/ non-page pool
-+ * packets. This can result in reference count issues as page
-+ * pool pages will not decrement the reference count and will
-+ * instead be immediately returned to the pool or have frag
-+ * count decremented.
-+ */
-+ if (p->pp_recycle != skb->pp_recycle)
-+ return -ETOOMANYREFS;
-+
- lp = NAPI_GRO_CB(p)->last;
- pinfo = skb_shinfo(lp);
-
diff --git a/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch
deleted file mode 100644
index a10a867d60..0000000000
--- a/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch
+++ /dev/null
@@ -1,232 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 16 Feb 2023 18:39:04 +0100
-Subject: [PATCH] net/core: add optional threading for backlog processing
-
-When dealing with few flows or an imbalance on CPU utilization, static RPS
-CPU assignment can be too inflexible. Add support for enabling threaded NAPI
-for backlog processing in order to allow the scheduler to better balance
-processing. This helps better spread the load across idle CPUs.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -502,6 +502,7 @@ static inline bool napi_complete(struct
- }
-
- int dev_set_threaded(struct net_device *dev, bool threaded);
-+int backlog_set_threaded(bool threaded);
-
- /**
- * napi_disable - prevent NAPI from scheduling
-@@ -3364,6 +3365,7 @@ struct softnet_data {
- unsigned int processed;
- unsigned int time_squeeze;
- unsigned int received_rps;
-+ unsigned int process_queue_empty;
- #ifdef CONFIG_RPS
- struct softnet_data *rps_ipi_list;
- #endif
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -4586,7 +4586,7 @@ static int rps_ipi_queued(struct softnet
- #ifdef CONFIG_RPS
- struct softnet_data *mysd = this_cpu_ptr(&softnet_data);
-
-- if (sd != mysd) {
-+ if (sd != mysd && !test_bit(NAPI_STATE_THREADED, &sd->backlog.state)) {
- sd->rps_ipi_next = mysd->rps_ipi_list;
- mysd->rps_ipi_list = sd;
-
-@@ -5767,6 +5767,8 @@ static DEFINE_PER_CPU(struct work_struct
- /* Network device is going away, flush any packets still pending */
- static void flush_backlog(struct work_struct *work)
- {
-+ unsigned int process_queue_empty;
-+ bool threaded, flush_processq;
- struct sk_buff *skb, *tmp;
- struct softnet_data *sd;
-
-@@ -5782,9 +5784,18 @@ static void flush_backlog(struct work_st
- input_queue_head_incr(sd);
- }
- }
-+
-+ threaded = test_bit(NAPI_STATE_THREADED, &sd->backlog.state);
-+ flush_processq = threaded &&
-+ !skb_queue_empty_lockless(&sd->process_queue);
-+ if (flush_processq)
-+ process_queue_empty = sd->process_queue_empty;
- rps_unlock(sd);
- local_irq_enable();
-
-+ if (threaded)
-+ goto out;
-+
- skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
- if (skb->dev->reg_state == NETREG_UNREGISTERING) {
- __skb_unlink(skb, &sd->process_queue);
-@@ -5792,7 +5803,18 @@ static void flush_backlog(struct work_st
- input_queue_head_incr(sd);
- }
- }
-+
-+out:
- local_bh_enable();
-+
-+ while (flush_processq) {
-+ msleep(1);
-+ local_irq_disable();
-+ rps_lock(sd);
-+ flush_processq = process_queue_empty == sd->process_queue_empty;
-+ rps_unlock(sd);
-+ local_irq_enable();
-+ }
- }
-
- static bool flush_required(int cpu)
-@@ -6475,6 +6497,7 @@ static int process_backlog(struct napi_s
-
- local_irq_disable();
- rps_lock(sd);
-+ sd->process_queue_empty++;
- if (skb_queue_empty(&sd->input_pkt_queue)) {
- /*
- * Inline a custom version of __napi_complete().
-@@ -6484,7 +6507,8 @@ static int process_backlog(struct napi_s
- * We can use a plain write instead of clear_bit(),
- * and we dont need an smp_mb() memory barrier.
- */
-- napi->state = 0;
-+ napi->state &= ~(NAPIF_STATE_SCHED |
-+ NAPIF_STATE_SCHED_THREADED);
- again = false;
- } else {
- skb_queue_splice_tail_init(&sd->input_pkt_queue,
-@@ -6901,6 +6925,57 @@ int dev_set_threaded(struct net_device *
- }
- EXPORT_SYMBOL(dev_set_threaded);
-
-+int backlog_set_threaded(bool threaded)
-+{
-+ static bool backlog_threaded;
-+ int err = 0;
-+ int i;
-+
-+ if (backlog_threaded == threaded)
-+ return 0;
-+
-+ for_each_possible_cpu(i) {
-+ struct softnet_data *sd = &per_cpu(softnet_data, i);
-+ struct napi_struct *n = &sd->backlog;
-+
-+ if (n->thread)
-+ continue;
-+ n->thread = kthread_run(napi_threaded_poll, n, "napi/backlog-%d", i);
-+ if (IS_ERR(n->thread)) {
-+ err = PTR_ERR(n->thread);
-+ pr_err("kthread_run failed with err %d\n", err);
-+ n->thread = NULL;
-+ threaded = false;
-+ break;
-+ }
-+
-+ }
-+
-+ backlog_threaded = threaded;
-+
-+ /* Make sure kthread is created before THREADED bit
-+ * is set.
-+ */
-+ smp_mb__before_atomic();
-+
-+ for_each_possible_cpu(i) {
-+ struct softnet_data *sd = &per_cpu(softnet_data, i);
-+ struct napi_struct *n = &sd->backlog;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ rps_lock(sd);
-+ if (threaded)
-+ n->state |= NAPIF_STATE_THREADED;
-+ else
-+ n->state &= ~NAPIF_STATE_THREADED;
-+ rps_unlock(sd);
-+ local_irq_restore(flags);
-+ }
-+
-+ return err;
-+}
-+
- void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
- int (*poll)(struct napi_struct *, int), int weight)
- {
-@@ -11384,6 +11459,9 @@ static int dev_cpu_dead(unsigned int old
- raise_softirq_irqoff(NET_TX_SOFTIRQ);
- local_irq_enable();
-
-+ if (test_bit(NAPI_STATE_THREADED, &oldsd->backlog.state))
-+ return 0;
-+
- #ifdef CONFIG_RPS
- remsd = oldsd->rps_ipi_list;
- oldsd->rps_ipi_list = NULL;
-@@ -11723,6 +11801,7 @@ static int __init net_dev_init(void)
- sd->cpu = i;
- #endif
-
-+ INIT_LIST_HEAD(&sd->backlog.poll_list);
- init_gro_hash(&sd->backlog);
- sd->backlog.poll = process_backlog;
- sd->backlog.weight = weight_p;
---- a/net/core/sysctl_net_core.c
-+++ b/net/core/sysctl_net_core.c
-@@ -28,6 +28,7 @@ static int int_3600 = 3600;
- static int min_sndbuf = SOCK_MIN_SNDBUF;
- static int min_rcvbuf = SOCK_MIN_RCVBUF;
- static int max_skb_frags = MAX_SKB_FRAGS;
-+static int backlog_threaded;
- static long long_one __maybe_unused = 1;
- static long long_max __maybe_unused = LONG_MAX;
-
-@@ -114,6 +115,23 @@ static int rps_sock_flow_sysctl(struct c
- }
- #endif /* CONFIG_RPS */
-
-+static int backlog_threaded_sysctl(struct ctl_table *table, int write,
-+ void *buffer, size_t *lenp, loff_t *ppos)
-+{
-+ static DEFINE_MUTEX(backlog_threaded_mutex);
-+ int ret;
-+
-+ mutex_lock(&backlog_threaded_mutex);
-+
-+ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
-+ if (write && !ret)
-+ ret = backlog_set_threaded(backlog_threaded);
-+
-+ mutex_unlock(&backlog_threaded_mutex);
-+
-+ return ret;
-+}
-+
- #ifdef CONFIG_NET_FLOW_LIMIT
- static DEFINE_MUTEX(flow_limit_update_mutex);
-
-@@ -470,6 +488,15 @@ static struct ctl_table net_core_table[]
- .proc_handler = rps_sock_flow_sysctl
- },
- #endif
-+ {
-+ .procname = "backlog_threaded",
-+ .data = &backlog_threaded,
-+ .maxlen = sizeof(unsigned int),
-+ .mode = 0644,
-+ .proc_handler = backlog_threaded_sysctl,
-+ .extra1 = SYSCTL_ZERO,
-+ .extra2 = SYSCTL_ONE
-+ },
- #ifdef CONFIG_NET_FLOW_LIMIT
- {
- .procname = "flow_limit_cpu_bitmap",
diff --git a/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
deleted file mode 100644
index 092e7933b7..0000000000
--- a/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Tobias Waldekranz <tobias@waldekranz.com>
-Subject: [RFC net-next 7/7] net: dsa: mv88e6xxx: Request assisted learning on CPU port
-Date: Sat, 16 Jan 2021 02:25:15 +0100
-Archived-At: <https://lore.kernel.org/netdev/20210116012515.3152-8-tobias@waldekranz.com/>
-
-While the hardware is capable of performing learning on the CPU port,
-it requires alot of additions to the bridge's forwarding path in order
-to handle multi-destination traffic correctly.
-
-Until that is in place, opt for the next best thing and let DSA sync
-the relevant addresses down to the hardware FDB.
-
-Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -6393,6 +6393,7 @@ static int mv88e6xxx_register_switch(str
- ds->ops = &mv88e6xxx_switch_ops;
- ds->ageing_time_min = chip->info->age_time_coeff;
- ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
-+ ds->assisted_learning_on_cpu_port = true;
-
- /* Some chips support up to 32, but that requires enabling the
- * 5-bit port mode, which we do not support. 640k^W16 ought to
diff --git a/target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch b/target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch
deleted file mode 100644
index ca963d1260..0000000000
--- a/target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From patchwork Sun Mar 19 22:08:05 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13180645
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id A7A46C6FD1F
- for <netdev@archiver.kernel.org>; Sun, 19 Mar 2023 22:08:15 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230223AbjCSWIN (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Sun, 19 Mar 2023 18:08:13 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32878 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S229565AbjCSWIM (ORCPT
- <rfc822;netdev@vger.kernel.org>); Sun, 19 Mar 2023 18:08:12 -0400
-Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com
- [IPv6:2a00:1450:4864:20::42e])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 605D3E062;
- Sun, 19 Mar 2023 15:08:10 -0700 (PDT)
-Received: by mail-wr1-x42e.google.com with SMTP id h17so8695188wrt.8;
- Sun, 19 Mar 2023 15:08:10 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679263689;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=;
- b=PSdrywW48P4Lq8z9wOSPXFB/ZdO/JfuyiGlw3Gz1Iriy+Smo/cBnJ0Ve9zKkX3AKTO
- Tr7/g8xhSQX8sU5WAOEPC13uVjKpO4VZsamXHTmMKL4mmfII3K/piAsQcMQkkNpgouab
- Ci9yr+7ASSmqEUHIbYTM6sl6a47rPwqk3b3DcTIE2CwJsPPNXnpQ/aSVbJAcEdhcZICc
- X4rAmjrYjcsl8coFIGHHPlrMH9ShekQWxB84vEb6bO1nXOORNPizOHuY1vJ3wa3WgXsx
- YwlvutMFVIUXfgL2ZwCmQAKWJPiAaFk+CCk3oxSeOYoAzkjcbMyapz9VnooStfvR2aV3
- k+2g==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679263689;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=;
- b=NGjqrGERyaxRwINtevHaY97h9X9W+1UY62YYwotqwv5+cfvB8myjBbD3WH2WzaqMes
- o9MMER9RE8/arW3jIVlBv4ORDUuEZ7AeGgy5UbFyQZIPHlp+hJ/sxFrGvYUwamg4Qrr9
- ojargh8ORsEiMeqaf+5AkmEagNhrrV3ax0pUuWDzbJ3vXGoHjfCetHz5xyNL46dvXBfb
- l/OZqjv9IYob552uUoUmCy/TbEQDqvmjkFrROFK9gtBNxgxUJkwbyiWIOVsf6RR8OarP
- f7bbvSJYkvTvzx2u/g0Up7NW5ZyihMGBmDs377M3yW6AnSxW6jlfl30QmMU1aEigYXvy
- v3mA==
-X-Gm-Message-State: AO0yUKUm1PYmYa4xlHuVD23mZcZm83a+xbhcbs0Xryi3yF/+UnjM4Cho
- GAfqSh5MZ/rlOAm3Vnpn//9hOG5Lc8vLYg==
-X-Google-Smtp-Source:
- AK7set+5pTahGGgk1hF/mHGkGBhsMf0//oQjZd4QFHx+HaeSgP5f6q7g0bRUcTX8kRtgHH0T7l1/hQ==
-X-Received: by 2002:a5d:474f:0:b0:2d6:2ae8:70d with SMTP id
- o15-20020a5d474f000000b002d62ae8070dmr2382593wrs.39.1679263688549;
- Sun, 19 Mar 2023 15:08:08 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- d6-20020a5d6dc6000000b002c53f6c7599sm7354727wrz.29.2023.03.19.15.08.07
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Sun, 19 Mar 2023 15:08:07 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2] net: dsa: b53: add support for BCM63xx RGMIIs
-Date: Sun, 19 Mar 2023 23:08:05 +0100
-Message-Id: <20230319220805.124024-1-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230319183330.761251-1-noltari@gmail.com>
-References: <20230319183330.761251-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM63xx RGMII ports require additional configuration in order to work.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
----
- v2: add changes suggested by Andrew:
- - Use a switch statement.
- - Use dev_dbg() instead of dev_info().
-
- drivers/net/dsa/b53/b53_common.c | 46 ++++++++++++++++++++++++++++++++
- drivers/net/dsa/b53/b53_priv.h | 1 +
- 2 files changed, 47 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1209,6 +1209,46 @@ static void b53_force_port_config(struct
- b53_write8(dev, B53_CTRL_PAGE, off, reg);
- }
-
-+static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port,
-+ phy_interface_t interface)
-+{
-+ struct b53_device *dev = ds->priv;
-+ u8 rgmii_ctrl = 0, off;
-+
-+ if (port == dev->imp_port)
-+ off = B53_RGMII_CTRL_IMP;
-+ else
-+ off = B53_RGMII_CTRL_P(port);
-+
-+ b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
-+
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC);
-+ rgmii_ctrl |= RGMII_CTRL_DLL_RXC;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC);
-+ rgmii_ctrl |= RGMII_CTRL_DLL_TXC;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII:
-+ default:
-+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
-+ break;
-+ }
-+
-+ if (port != dev->imp_port)
-+ rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
-+
-+ b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
-+
-+ dev_dbg(ds->dev, "Configured port %d for %s\n", port,
-+ phy_modes(interface));
-+}
-+
- static void b53_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev)
- {
-@@ -1235,6 +1275,9 @@ static void b53_adjust_link(struct dsa_s
- tx_pause, rx_pause);
- b53_force_link(dev, port, phydev->link);
-
-+ if (is63xx(dev) && port >= B53_63XX_RGMII0)
-+ b53_adjust_63xx_rgmii(ds, port, phydev->interface);
-+
- if (is531x5(dev) && phy_interface_is_rgmii(phydev)) {
- if (port == dev->imp_port)
- off = B53_RGMII_CTRL_IMP;
-@@ -1419,6 +1462,9 @@ void b53_phylink_mac_link_up(struct dsa_
- {
- struct b53_device *dev = ds->priv;
-
-+ if (is63xx(dev) && port >= B53_63XX_RGMII0)
-+ b53_adjust_63xx_rgmii(ds, port, interface);
-+
- if (mode == MLO_AN_PHY)
- return;
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -206,6 +206,7 @@ static inline int is58xx(struct b53_devi
- dev->chip_id == BCM7278_DEVICE_ID;
- }
-
-+#define B53_63XX_RGMII0 4
- #define B53_CPU_PORT_25 5
- #define B53_CPU_PORT 8
-
diff --git a/target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch b/target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch
deleted file mode 100644
index e2da4e7f05..0000000000
--- a/target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From patchwork Tue Mar 21 17:33:57 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13183003
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 823A1C761AF
- for <netdev@archiver.kernel.org>; Tue, 21 Mar 2023 17:35:06 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230490AbjCURfE (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Tue, 21 Mar 2023 13:35:04 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47440 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230357AbjCURex (ORCPT
- <rfc822;netdev@vger.kernel.org>); Tue, 21 Mar 2023 13:34:53 -0400
-Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com
- [IPv6:2a00:1450:4864:20::430])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9A45559D8;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-Received: by mail-wr1-x430.google.com with SMTP id m2so14547588wrh.6;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679420063;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=;
- b=F0pa8JmQZ1FeXVtdpCygur8UmLrgKwxCcjaMn312u5zNvsXsEPeCAIDqP2tvNNTwv/
- UYjaNaoZ77HSvv/gSqeG808AXGyNs1PvLuHZYuUTJRNuLaMixKtkNFi4ypheCdk0WCiE
- IWz0DIm6ojmdwMqafDUKQ6Qwkv5R0vo8Wh5vpjimEmCelOyMvfuLZNqubsiGqpnCguBp
- uWlmKh95/VubCGgiGG2xK1IXQayL14ENuWseDds7nVpVK50NycrFgJbL17Bd6qJKYkbo
- m70IC+9jM0hjwKXpyi6ipCBNcW+1E6JIwILVC04Xi+BTpOGhbUAQ59Yn2hyq7tQM7dzs
- 4PLg==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679420063;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=;
- b=SCX78yTuGjdnE5nuL0p7+kxGnOzsCExsigLdaV+x/JswmwxSpZvxn223i1yM95klj9
- Rk0RnXqATLF1wZA7L1YmbeZ66zxUwW/osnCjJHPeEF8AGgjK/qawtLl/HJQHN67NaRNQ
- bDsRn2nWQ2GRTRFpvD+iGRy4uyQCDu9HFxLbn43fBsBmRnXWGPQP5cEb90tL83/Onp4D
- Lx/XcyZOh9QRfJNhj+G1BAeRCLRA/sdA0W3Ecu5SCFs+LtS6uvLVGWDKEDfnZhYY8Xqf
- Mx9evWzdW2OorEN2FI6+xTglvnEBcVhHIJ7XEGAhCG6ocgMZeck++774S8RWumWl8xpy
- /K9Q==
-X-Gm-Message-State: AO0yUKUORAlGfbkNwnYmQnTWcGPqW6sp4g9WfgQmRZGCV+9tCB0OebSP
- ICq6v4YPmUPNRl/WNnVCbps=
-X-Google-Smtp-Source:
- AK7set8pFDl8fHRwGPhAguqxIfqnQ4PY+b57IHEsybIaQ/HPNwdJ1cs1+IPBGHe3TL14dTS4aVNpHA==
-X-Received: by 2002:a5d:6991:0:b0:2ce:aab5:f96b with SMTP id
- g17-20020a5d6991000000b002ceaab5f96bmr2965175wru.67.1679420062764;
- Tue, 21 Mar 2023 10:34:22 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.21
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Tue, 21 Mar 2023 10:34:21 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2 2/4] net: dsa: b53: mmap: add more 63xx SoCs
-Date: Tue, 21 Mar 2023 18:33:57 +0100
-Message-Id: <20230321173359.251778-3-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230321173359.251778-1-noltari@gmail.com>
-References: <20230320155024.164523-1-noltari@gmail.com>
- <20230321173359.251778-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM6318, BCM6362 and BCM63268 are SoCs with a B53 MMAP switch.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
----
- v2: no changes.
-
- drivers/net/dsa/b53/b53_mmap.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -347,8 +347,11 @@ static void b53_mmap_shutdown(struct pla
-
- static const struct of_device_id b53_mmap_of_table[] = {
- { .compatible = "brcm,bcm3384-switch" },
-+ { .compatible = "brcm,bcm6318-switch" },
- { .compatible = "brcm,bcm6328-switch" },
-+ { .compatible = "brcm,bcm6362-switch" },
- { .compatible = "brcm,bcm6368-switch" },
-+ { .compatible = "brcm,bcm63268-switch" },
- { .compatible = "brcm,bcm63xx-switch" },
- { /* sentinel */ },
- };
diff --git a/target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch b/target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch
deleted file mode 100644
index 456643f05d..0000000000
--- a/target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch
+++ /dev/null
@@ -1,195 +0,0 @@
-From patchwork Tue Mar 21 17:33:58 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13183004
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id B2B12C74A5B
- for <netdev@archiver.kernel.org>; Tue, 21 Mar 2023 17:35:12 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230297AbjCURfK (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Tue, 21 Mar 2023 13:35:10 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47438 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230374AbjCURex (ORCPT
- <rfc822;netdev@vger.kernel.org>); Tue, 21 Mar 2023 13:34:53 -0400
-Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com
- [IPv6:2a00:1450:4864:20::432])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C906B5550A;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-Received: by mail-wr1-x432.google.com with SMTP id y14so14546846wrq.4;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679420064;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=;
- b=eFv+mwe94Y2YZMiJP5gydXVrGlbIAR5HCrY0rdcoGoMPzQUHLFckZeYCgEKudI55I7
- gMLZYCtLwvDXvKeHM2AUigsq2YuJSeF5QwICPrhTnMwUGBg4yyyltrc3+J0lSd6/4kQv
- h0yM1Oo4v0d8CuqjBU6bXienIk34AFVJfsPq+vWQTjAbUL7ht4WHZ2Ez2MFoTvZpkIJA
- 5iWMyVoMbugZl6eqNRjvDHFmtBtrZIv8AFs10r2Ca6+Yxm+aq0v33DRkbSVVqgFPNEzy
- q5QOXOeLBPL6BvyovOpmVSWGoHf1zFV7lrzcqi+uc+FuYxQ9dyN3ND73DrrhWSkLaSg9
- r8yA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679420064;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=;
- b=jIRB8pIlrLA/ovhnEoePs/6SX8fn6l7l4fY2CxX2pLrTbP1JI8AAetPavvrNVQTr2M
- Vm0iLbKyL/VpTq9+bSN1SMjaoi4lAMj0pgafoHrwABMVZpFauYvtCfSYTstZ2pw4Dr1j
- wYQGj3BUSpFIYHtSIDMkb5449WA3T3TONhaQLRFAUCBD6gAFyEky5fY+DIHrGaj352B6
- 9ST/tkqHgPpuFlmromr42KQWoTFU+Pj0Uhyp7ru4BsnF7tTshWroZZIHUJmSACudEadr
- fBPiuurX9jgp9zNqj8Oy0HjiVUnULFCapj8yICGp5s44uDAK/XFqFXpOuJ8ptS6uPazU
- xUwg==
-X-Gm-Message-State: AO0yUKX2w6QZfaGDHtlZAlY/U8F8VuJa3HwlgXbxgGChgdgvIoFThawv
- oDyFAhWbVfe4DxwXTwxgJ/I=
-X-Google-Smtp-Source:
- AK7set+sH60XiJYup7bqrZTzFJVNe1YGcX/UTfjWV9xfGwNyodc34cHvKpqNagw5J+vEpv6CKvNHaA==
-X-Received: by 2002:adf:f344:0:b0:2cd:de25:1c76 with SMTP id
- e4-20020adff344000000b002cdde251c76mr12989754wrp.17.1679420064464;
- Tue, 21 Mar 2023 10:34:24 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.22
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Tue, 21 Mar 2023 10:34:23 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2 3/4] net: dsa: b53: mmap: allow passing a chip ID
-Date: Tue, 21 Mar 2023 18:33:58 +0100
-Message-Id: <20230321173359.251778-4-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230321173359.251778-1-noltari@gmail.com>
-References: <20230320155024.164523-1-noltari@gmail.com>
- <20230321173359.251778-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM6318 and BCM63268 SoCs require a special handling for their RGMIIs, so we
-should be able to identify them as a special BCM63xx switch.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- v2:
- - Add missing chip to b53_switch_chips[].
- - Fix device_get_match_data() casting warning.
- - Add BCM63268_DEVICE_ID to BCM6318 too.
- - Add BCM6318 in commit description.
-
- drivers/net/dsa/b53/b53_common.c | 13 +++++++++++++
- drivers/net/dsa/b53/b53_mmap.c | 32 +++++++++++++++++++++++---------
- drivers/net/dsa/b53/b53_priv.h | 9 ++++++++-
- 3 files changed, 44 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2461,6 +2461,19 @@ static const struct b53_chip_data b53_sw
- .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
- },
- {
-+ .chip_id = BCM63268_DEVICE_ID,
-+ .dev_name = "BCM63268",
-+ .vlans = 4096,
-+ .enabled_ports = 0, /* pdata must provide them */
-+ .arl_bins = 4,
-+ .arl_buckets = 1024,
-+ .imp_port = 8,
-+ .vta_regs = B53_VTA_REGS_63XX,
-+ .duplex_reg = B53_DUPLEX_STAT_63XX,
-+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
-+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
-+ },
-+ {
- .chip_id = BCM53010_DEVICE_ID,
- .dev_name = "BCM53010",
- .vlans = 4096,
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -262,7 +262,7 @@ static int b53_mmap_probe_of(struct plat
- return -ENOMEM;
-
- pdata->regs = mem;
-- pdata->chip_id = BCM63XX_DEVICE_ID;
-+ pdata->chip_id = (u32)(unsigned long)device_get_match_data(dev);
- pdata->big_endian = of_property_read_bool(np, "big-endian");
-
- of_ports = of_get_child_by_name(np, "ports");
-@@ -346,14 +346,28 @@ static void b53_mmap_shutdown(struct pla
- }
-
- static const struct of_device_id b53_mmap_of_table[] = {
-- { .compatible = "brcm,bcm3384-switch" },
-- { .compatible = "brcm,bcm6318-switch" },
-- { .compatible = "brcm,bcm6328-switch" },
-- { .compatible = "brcm,bcm6362-switch" },
-- { .compatible = "brcm,bcm6368-switch" },
-- { .compatible = "brcm,bcm63268-switch" },
-- { .compatible = "brcm,bcm63xx-switch" },
-- { /* sentinel */ },
-+ {
-+ .compatible = "brcm,bcm3384-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6318-switch",
-+ .data = (void *)BCM63268_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6328-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6362-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6368-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm63268-switch",
-+ .data = (void *)BCM63268_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm63xx-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, { /* sentinel */ }
- };
- MODULE_DEVICE_TABLE(of, b53_mmap_of_table);
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -75,6 +75,7 @@ enum {
- BCM53125_DEVICE_ID = 0x53125,
- BCM53128_DEVICE_ID = 0x53128,
- BCM63XX_DEVICE_ID = 0x6300,
-+ BCM63268_DEVICE_ID = 0x63268,
- BCM53010_DEVICE_ID = 0x53010,
- BCM53011_DEVICE_ID = 0x53011,
- BCM53012_DEVICE_ID = 0x53012,
-@@ -186,7 +187,13 @@ static inline int is531x5(struct b53_dev
-
- static inline int is63xx(struct b53_device *dev)
- {
-- return dev->chip_id == BCM63XX_DEVICE_ID;
-+ return dev->chip_id == BCM63XX_DEVICE_ID ||
-+ dev->chip_id == BCM63268_DEVICE_ID;
-+}
-+
-+static inline int is63268(struct b53_device *dev)
-+{
-+ return dev->chip_id == BCM63268_DEVICE_ID;
- }
-
- static inline int is5301x(struct b53_device *dev)
diff --git a/target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch b/target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch
deleted file mode 100644
index d90d757fb2..0000000000
--- a/target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From patchwork Tue Mar 21 17:33:59 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13183005
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 31BE4C761A6
- for <netdev@archiver.kernel.org>; Tue, 21 Mar 2023 17:35:16 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S229674AbjCURfN (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Tue, 21 Mar 2023 13:35:13 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47684 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230327AbjCURfB (ORCPT
- <rfc822;netdev@vger.kernel.org>); Tue, 21 Mar 2023 13:35:01 -0400
-Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com
- [IPv6:2a00:1450:4864:20::436])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1D855507D;
- Tue, 21 Mar 2023 10:34:27 -0700 (PDT)
-Received: by mail-wr1-x436.google.com with SMTP id i9so14537769wrp.3;
- Tue, 21 Mar 2023 10:34:27 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679420066;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=;
- b=Cqj2C6aG5vEOlhh9N3ybvDA0CV38nhQODnfdnr7utNddd323iDagoJty1Wmi3MAzj1
- 5ORmYT5fQvUnild7C4RhcCNTBn+MoYZ+wDZwZYelu6BKHkW11YFK949ax5B50by+ASR2
- z+rGI3wR5fVXd4VDgmcsT6zF5x69wKyhbhqIfrhG9BVFTctfaBgDS/l+bX1C56kSqv82
- bQkKSSAehSLGpFoCU3q62OGoZVi3jDe6HDb5M1Dp2mgHhqsW19otZpJ57DjtZ1CmtPai
- o7T/ew6WoIYSl6whBmV36jeNaDJ3TItOBrKc4nMJBDWaCg4DNzUSe0ei5Xz7Oik5lb3p
- y9ew==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679420066;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=;
- b=UdI2iQNBYwRf40ivf3ROR132t95BU/p3RUzXdZLCyz6c6JWtECQ5byyGeEwoX10n5u
- HlepoNTJxMFLYrAHGvNLDPpWPuLXMa645S1mCVZ7NyWp8W96XzSynNZPeXHuJdb464QU
- A7UTRSW3mlvKe9OR3EcB2CfBZv0yHWR0ldbnxcxGUFw8z78PNqpOVnITtjBdfpGesJ9c
- VJw+fiM6hCcahor4nk9LLcAryPm8xmhDLxBKaLILO8wyTUiHY8G9hsXnFCtcpetnF5wS
- pW13beAE+odb7ZZaXZUYpWGYhCe/hLzNjbo8YpgzHwadZthxPrT5YvNIYwyrvoViLM0n
- KDRQ==
-X-Gm-Message-State: AO0yUKW+9H/kqcAUyWeZhZJhiJjsBcYn1THmZaSDrPrk/pNuGXJXGtJd
- NgsGZW8iSqLEv81yK+U5Os8=
-X-Google-Smtp-Source:
- AK7set/lzQZwCSxVaOe5dZ+7TR3xaQty/vg5xvZDpRW8TwTiPQblIbw5kJJTPLp67RySehrPIlCqSg==
-X-Received: by 2002:a5d:65c9:0:b0:2ce:ac31:54ff with SMTP id
- e9-20020a5d65c9000000b002ceac3154ffmr2776515wrw.2.1679420066191;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.24
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Tue, 21 Mar 2023 10:34:25 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>,
- Simon Horman <simon.horman@corigine.com>
-Subject: [PATCH v2 4/4] net: dsa: b53: add BCM63268 RGMII configuration
-Date: Tue, 21 Mar 2023 18:33:59 +0100
-Message-Id: <20230321173359.251778-5-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230321173359.251778-1-noltari@gmail.com>
-References: <20230320155024.164523-1-noltari@gmail.com>
- <20230321173359.251778-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM63268 requires special RGMII configuration to work.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
----
- v2: no changes.
-
- drivers/net/dsa/b53/b53_common.c | 6 +++++-
- drivers/net/dsa/b53/b53_regs.h | 1 +
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1240,8 +1240,12 @@ static void b53_adjust_63xx_rgmii(struct
- break;
- }
-
-- if (port != dev->imp_port)
-+ if (port != dev->imp_port) {
-+ if (is63268(dev))
-+ rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
-+
- rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
-+ }
-
- b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
-
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -138,6 +138,7 @@
-
- #define B53_RGMII_CTRL_IMP 0x60
- #define RGMII_CTRL_ENABLE_GMII BIT(7)
-+#define RGMII_CTRL_MII_OVERRIDE BIT(6)
- #define RGMII_CTRL_TIMING_SEL BIT(2)
- #define RGMII_CTRL_DLL_RXC BIT(1)
- #define RGMII_CTRL_DLL_TXC BIT(0)
diff --git a/target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch b/target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch
deleted file mode 100644
index 53494eca6e..0000000000
--- a/target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-From patchwork Fri Mar 24 08:41:38 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13186549
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id EF744C76195
- for <netdev@archiver.kernel.org>; Fri, 24 Mar 2023 08:42:01 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231807AbjCXImA (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Fri, 24 Mar 2023 04:42:00 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32956 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231272AbjCXIly (ORCPT
- <rfc822;netdev@vger.kernel.org>); Fri, 24 Mar 2023 04:41:54 -0400
-Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com
- [IPv6:2a00:1450:4864:20::535])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 113A517CF3;
- Fri, 24 Mar 2023 01:41:46 -0700 (PDT)
-Received: by mail-ed1-x535.google.com with SMTP id ek18so4877175edb.6;
- Fri, 24 Mar 2023 01:41:45 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679647304;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=;
- b=JMrl6Eay1FS0JZqgPHsbcVzuNAbFELc0SLNGyzYtOVQXcI+YwKDM9Ls7I9PsQVEPoZ
- CthomCTYoz5G9DU7uBuia207rnjOhssZJRu0syrCoU+O/ZiQyGLJDvq61z5oZJxC2S40
- kzRsUsC6MRjn64DKPWmxhsSTMKLzn2+P233LKNFbHtfi3NWF5Qu/85sUkxMurnfUgja0
- qQhl25qYY7ZIvmlFHYefaI5UkITQFuiybrqJW9tztCdHf/gS+f33YkkvQ8njmMQa1DW0
- ppedfOUotX+6kmHZGX1yea2V5ezEGGvRourZtYMoecTiD0E5d1J1bKhktKslVLIDm0ig
- oc2g==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679647304;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=;
- b=b3Gmga5ZDbnmQfnw1GCz+eU2JwgsVzfciZuSmfYAiVxpW4c6cur3MHbpzDPhi99wzA
- ZYAM7ryLv88rXl/tQB5g2Nte5rvMfxUeHXsT/JpsRcSSocFRbRrk0QJyiA/Xj86NiD5N
- C1sKz50Im190FmrvPcBh6OHQbv/3MQyE+1fQx+9q3jW5rQiAWQaYk4Ng8GlWA7gtG3jB
- fHO6Fuoenn32pgkveJbQLYL/2t2f53wGf3QLQ3IeKW7jdfIHNThwrwqBMxdHoIDaTBT9
- UWMeJuiYtylIibo/3zbORbWOgIERlWxZRf3BCOFpnzUn4eBzio4LgjtNxZ77ITRxsmbk
- 3+Hg==
-X-Gm-Message-State: AAQBX9dfyBfbR7Sdd5wqxMiAv3Yhk47pK1XzD87MZyAF3AxyoFyKcMaF
- EbwJLyRvTGQEFdVWCGw1eMU=
-X-Google-Smtp-Source:
- AKy350bpDVLq7k1FxG2Mek/VIobZL4KhufiKx8qfmpxpcWmLI3bLg8wfQKEAKJRNJBleo/7CZuCL5g==
-X-Received: by 2002:aa7:c711:0:b0:4a2:588f:b3c5 with SMTP id
- i17-20020aa7c711000000b004a2588fb3c5mr2261236edq.21.1679647304260;
- Fri, 24 Mar 2023 01:41:44 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- z21-20020a50cd15000000b004acbda55f6bsm10323728edi.27.2023.03.24.01.41.43
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Fri, 24 Mar 2023 01:41:43 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: paul.geurts@prodrive-technologies.com, f.fainelli@gmail.com,
- jonas.gorski@gmail.com, andrew@lunn.ch, olteanv@gmail.com,
- davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
- pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2 2/2] net: dsa: b53: mdio: add support for BCM53134
-Date: Fri, 24 Mar 2023 09:41:38 +0100
-Message-Id: <20230324084138.664285-3-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230324084138.664285-1-noltari@gmail.com>
-References: <20230323121804.2249605-1-noltari@gmail.com>
- <20230324084138.664285-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-From: Paul Geurts <paul.geurts@prodrive-technologies.com>
-
-Add support for the BCM53134 Ethernet switch in the existing b53 dsa driver.
-BCM53134 is very similar to the BCM58XX series.
-
-Signed-off-by: Paul Geurts <paul.geurts@prodrive-technologies.com>
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- v2: add BCM53134 to is531x5() and remove special RGMII config
-
- drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++
- drivers/net/dsa/b53/b53_mdio.c | 5 ++++-
- drivers/net/dsa/b53/b53_priv.h | 7 +++++--
- 3 files changed, 24 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2609,6 +2609,20 @@ static const struct b53_chip_data b53_sw
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
- .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
- },
-+ {
-+ .chip_id = BCM53134_DEVICE_ID,
-+ .dev_name = "BCM53134",
-+ .vlans = 4096,
-+ .enabled_ports = 0x12f,
-+ .imp_port = 8,
-+ .cpu_port = B53_CPU_PORT,
-+ .vta_regs = B53_VTA_REGS,
-+ .arl_bins = 4,
-+ .arl_buckets = 1024,
-+ .duplex_reg = B53_DUPLEX_STAT_GE,
-+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+ },
- };
-
- static int b53_switch_init(struct b53_device *dev)
-@@ -2785,6 +2799,7 @@ int b53_switch_detect(struct b53_device
- case BCM53012_DEVICE_ID:
- case BCM53018_DEVICE_ID:
- case BCM53019_DEVICE_ID:
-+ case BCM53134_DEVICE_ID:
- dev->chip_id = id32;
- break;
- default:
---- a/drivers/net/dsa/b53/b53_mdio.c
-+++ b/drivers/net/dsa/b53/b53_mdio.c
-@@ -286,6 +286,7 @@ static const struct b53_io_ops b53_mdio_
- #define B53_BRCM_OUI_2 0x03625c00
- #define B53_BRCM_OUI_3 0x00406000
- #define B53_BRCM_OUI_4 0x01410c00
-+#define B53_BRCM_OUI_5 0xae025000
-
- static int b53_mdio_probe(struct mdio_device *mdiodev)
- {
-@@ -313,7 +314,8 @@ static int b53_mdio_probe(struct mdio_de
- if ((phy_id & 0xfffffc00) != B53_BRCM_OUI_1 &&
- (phy_id & 0xfffffc00) != B53_BRCM_OUI_2 &&
- (phy_id & 0xfffffc00) != B53_BRCM_OUI_3 &&
-- (phy_id & 0xfffffc00) != B53_BRCM_OUI_4) {
-+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_4 &&
-+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_5) {
- dev_err(&mdiodev->dev, "Unsupported device: 0x%08x\n", phy_id);
- return -ENODEV;
- }
-@@ -377,6 +379,7 @@ static const struct of_device_id b53_of_
- { .compatible = "brcm,bcm53115" },
- { .compatible = "brcm,bcm53125" },
- { .compatible = "brcm,bcm53128" },
-+ { .compatible = "brcm,bcm53134" },
- { .compatible = "brcm,bcm5365" },
- { .compatible = "brcm,bcm5389" },
- { .compatible = "brcm,bcm5395" },
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -85,6 +85,7 @@ enum {
- BCM583XX_DEVICE_ID = 0x58300,
- BCM7445_DEVICE_ID = 0x7445,
- BCM7278_DEVICE_ID = 0x7278,
-+ BCM53134_DEVICE_ID = 0x5075,
- };
-
- #define B53_N_PORTS 9
-@@ -182,7 +183,8 @@ static inline int is531x5(struct b53_dev
- {
- return dev->chip_id == BCM53115_DEVICE_ID ||
- dev->chip_id == BCM53125_DEVICE_ID ||
-- dev->chip_id == BCM53128_DEVICE_ID;
-+ dev->chip_id == BCM53128_DEVICE_ID ||
-+ dev->chip_id == BCM53134_DEVICE_ID;
- }
-
- static inline int is63xx(struct b53_device *dev)
-@@ -210,7 +212,8 @@ static inline int is58xx(struct b53_devi
- return dev->chip_id == BCM58XX_DEVICE_ID ||
- dev->chip_id == BCM583XX_DEVICE_ID ||
- dev->chip_id == BCM7445_DEVICE_ID ||
-- dev->chip_id == BCM7278_DEVICE_ID;
-+ dev->chip_id == BCM7278_DEVICE_ID ||
-+ dev->chip_id == BCM53134_DEVICE_ID;
- }
-
- #define B53_63XX_RGMII0 4
diff --git a/target/linux/generic/pending-5.15/778-net-l2tp-drop-flow-hash-on-forward.patch b/target/linux/generic/pending-5.15/778-net-l2tp-drop-flow-hash-on-forward.patch
deleted file mode 100644
index a2c0edcbbf..0000000000
--- a/target/linux/generic/pending-5.15/778-net-l2tp-drop-flow-hash-on-forward.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 4a44a52f16ccd3d03e0cb5fb437a5eb31a5f9f05 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Mon, 26 Feb 2024 21:39:34 +0100
-Subject: [PATCH] net l2tp: drop flow hash on forward
-
-Drop the flow-hash of the skb when forwarding to the L2TP netdev.
-
-This avoids the L2TP qdisc from using the flow-hash from the outer
-packet, which is identical for every flow within the tunnel.
-
-This does not affect every platform but is specific for the ethernet
-driver. It depends on the platform including L4 information in the
-flow-hash.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- net/l2tp/l2tp_eth.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/net/l2tp/l2tp_eth.c
-+++ b/net/l2tp/l2tp_eth.c
-@@ -136,6 +136,9 @@ static void l2tp_eth_dev_recv(struct l2t
- /* checksums verified by L2TP */
- skb->ip_summed = CHECKSUM_NONE;
-
-+ /* drop outer flow-hash */
-+ skb_clear_hash(skb);
-+
- skb_dst_drop(skb);
- nf_reset_ct(skb);
-
diff --git a/target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch b/target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch
deleted file mode 100644
index 6c1f596759..0000000000
--- a/target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 3f1a227cb071f65f6ecc4db9f399649869735a7c Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sat, 17 Feb 2024 22:34:59 +0100
-Subject: [PATCH] net vxlan: don't learn non-unicast L2 destinations
-
-This patch avoids learning non-unicast targets in the vxlan FDB.
-They are non-unicast and thus should be sent to the broadcast-IPv6
-instead of a unicast address.
-
-Link: https://lore.kernel.org/netdev/15ee0cc7-9252-466b-8ce7-5225d605dde8@david-bauer.net/
-Link: https://github.com/freifunk-gluon/gluon/issues/3191
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/vxlan.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/vxlan/vxlan_core.c
-+++ b/drivers/net/vxlan/vxlan_core.c
-@@ -1493,6 +1493,10 @@ static bool vxlan_snoop(struct net_devic
- struct vxlan_fdb *f;
- u32 ifindex = 0;
-
-+ /* Don't learn broadcast packets */
-+ if (is_multicast_ether_addr(src_mac) || is_zero_ether_addr(src_mac))
-+ return false;
-+
- #if IS_ENABLED(CONFIG_IPV6)
- if (src_ip->sa.sa_family == AF_INET6 &&
- (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL))
diff --git a/target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch b/target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch
deleted file mode 100644
index 39ba71606e..0000000000
--- a/target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From patchwork Thu Aug 5 22:23:30 2021
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 12422209
-Date: Thu, 5 Aug 2021 23:23:30 +0100
-From: Daniel Golle <daniel@makrotopia.org>
-To: linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org
-Cc: "David S. Miller" <davem@davemloft.net>, Andrew Lunn <andrew@lunn.ch>,
- Michael Walle <michael@walle.cc>
-Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
-Message-ID: <YQxk4jrbm31NM1US@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-X-BeenThere: linux-arm-kernel@lists.infradead.org
-X-Mailman-Version: 2.1.34
-Precedence: list
-List-Id: <linux-arm-kernel.lists.infradead.org>
-List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
-Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
-
-After commit 83216e3988cd1 ("of: net: pass the dst buffer to
-of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not
-defined.
-
-arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup':
-arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared (first use in this function); did you mean 'ESTALE'?
- u8 tmpmac[ETH_ALEN];
- ^~~~~~~~
- ESTALE
-arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier is reported only once for each function it appears in
-arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac' [-Wunused-variable]
- u8 tmpmac[ETH_ALEN];
- ^~~~~~
-make[5]: *** [scripts/Makefile.build:262: arch/arm/mach-mvebu/kirkwood.o] Error 1
-make[5]: *** Waiting for unfinished jobs....
-
-Add missing #include <linux/if_ether.h> to fix this.
-
-Cc: David S. Miller <davem@davemloft.net>
-Cc: Andrew Lunn <andrew@lunn.ch>
-Cc: Michael Walle <michael@walle.cc>
-Reported-by: https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio
-Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to of_get_mac_address()")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- arch/arm/mach-mvebu/kirkwood.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/mach-mvebu/kirkwood.c
-+++ b/arch/arm/mach-mvebu/kirkwood.c
-@@ -11,6 +11,7 @@
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/mbus.h>
-+#include <linux/if_ether.h>
- #include <linux/of.h>
- #include <linux/of_address.h>
- #include <linux/of_net.h>
diff --git a/target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch b/target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch
deleted file mode 100644
index 6402dd9066..0000000000
--- a/target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 5f7c5e1c0d7a79be144e5efc1f24728ddd7fc25c Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Sat, 5 Nov 2022 20:02:56 +0100
-Subject: [PATCH 1/2] bus: mhi: core: add SBL state callback
-
-Add support for SBL state callback in MHI core.
-
-It is required for ath11k MHI devices in order to be able to set QRTR
-instance ID in the SBL state so that QRTR instance ID-s dont conflict in
-case of multiple PCI/MHI cards or AHB + PCI/MHI card.
-Setting QRTR instance ID is only possible in SBL state and there is
-currently no way to ensure that we are in that state, so provide a
-callback that the controller can trigger off.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
----
- drivers/bus/mhi/host/main.c | 1 +
- include/linux/mhi.h | 2 ++
- 2 files changed, 3 insertions(+)
-
---- a/drivers/bus/mhi/host/main.c
-+++ b/drivers/bus/mhi/host/main.c
-@@ -896,6 +896,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_
- switch (event) {
- case MHI_EE_SBL:
- st = DEV_ST_TRANSITION_SBL;
-+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_SBL_MODE);
- break;
- case MHI_EE_WFW:
- case MHI_EE_AMSS:
---- a/include/linux/mhi.h
-+++ b/include/linux/mhi.h
-@@ -34,6 +34,7 @@ struct mhi_buf_info;
- * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover)
- * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state
- * @MHI_CB_BW_REQ: Received a bandwidth switch request from device
-+ * @MHI_CB_EE_SBL_MODE: MHI device entered SBL mode
- */
- enum mhi_callback {
- MHI_CB_IDLE,
-@@ -45,6 +46,7 @@ enum mhi_callback {
- MHI_CB_SYS_ERROR,
- MHI_CB_FATAL_ERROR,
- MHI_CB_BW_REQ,
-+ MHI_CB_EE_SBL_MODE,
- };
-
- /**
diff --git a/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch b/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch
deleted file mode 100644
index 609e03d964..0000000000
--- a/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 1d81e51d6d79d9098013b2e8cdd677bae998c5d8 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Fri, 28 Apr 2023 02:22:59 +0200
-Subject: [PATCH 1/2] mt7530: register OF node for internal MDIO bus
-
-The MT753x switches provide a switch-internal MDIO bus for the embedded
-PHYs.
-
-Register a OF sub-node on the switch OF-node for this internal MDIO bus.
-This allows to configure the embedded PHYs using device-tree.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/net/dsa/mt7530.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2356,10 +2356,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
- {
- struct dsa_switch *ds = priv->ds;
- struct device *dev = priv->dev;
-+ struct device_node *np, *mnp;
- struct mii_bus *bus;
- static int idx;
- int ret;
-
-+ np = priv->dev->of_node;
-+
- bus = devm_mdiobus_alloc(dev);
- if (!bus)
- return -ENOMEM;
-@@ -2376,7 +2379,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
- if (priv->irq)
- mt7530_setup_mdio_irq(priv);
-
-- ret = devm_mdiobus_register(dev, bus);
-+ mnp = of_get_child_by_name(np, "mdio");
-+ ret = devm_of_mdiobus_register(dev, bus, mnp);
-+ of_node_put(mnp);
- if (ret) {
- dev_err(dev, "failed to register MDIO bus: %d\n", ret);
- if (priv->irq)
diff --git a/target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch b/target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch
deleted file mode 100644
index 1697347b53..0000000000
--- a/target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From a444877c10a665cd8a869e6d37facdb89fd95f79 Mon Sep 17 00:00:00 2001
-Message-ID: <a444877c10a665cd8a869e6d37facdb89fd95f79.1706070008.git.daniel@makrotopia.org>
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 24 Jan 2024 04:17:11 +0000
-Subject: [PATCH net] net: dsa: mt7530: fix 10M/100M speed on MT7988 switch
-To: Arınç ÜNAL <arinc.unal@arinc9.com>,
- Daniel Golle <daniel@makrotopia.org>,
- DENG Qingfang <dqfext@gmail.com>,
- Sean Wang <sean.wang@mediatek.com>,
- Andrew Lunn <andrew@lunn.ch>,
- Florian Fainelli <f.fainelli@gmail.com>,
- Vladimir Oltean <olteanv@gmail.com>,
- David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org
-
-Setup PMCR port register for actual speed and duplex on internally
-connected PHYs of the MT7988 built-in switch. This fixes links with
-speeds other than 1000M.
-
-Fixes: ("110c18bfed414 net: dsa: mt7530: introduce driver for MT7988 built-in switch")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/dsa/mt7530.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -3065,8 +3065,7 @@ static void mt753x_phylink_mac_link_up(s
- /* MT753x MAC works in 1G full duplex mode for all up-clocked
- * variants.
- */
-- if (interface == PHY_INTERFACE_MODE_INTERNAL ||
-- interface == PHY_INTERFACE_MODE_TRGMII ||
-+ if (interface == PHY_INTERFACE_MODE_TRGMII ||
- (phy_interface_mode_is_8023z(interface))) {
- speed = SPEED_1000;
- duplex = DUPLEX_FULL;
diff --git a/target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch b/target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch
deleted file mode 100644
index 478a2cb27d..0000000000
--- a/target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] bcma: get SoC device struct & copy its DMA params to the
- subdevices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-For bus devices to be fully usable it's required to set their DMA
-parameters.
-
-For years it has been missing and remained unnoticed because of
-mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask.
-Kernel 4.19 came with a lot of DMA changes and caused a regression on
-the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic
-dma noncoherent ops for simple noncoherent platforms") DMA coherent
-allocations just fail. Example:
-[ 1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed
-[ 1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA
-[ 1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12
-[ 1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded
-
-This change fixes above regression in addition to the MIPS bcm47xx
-commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC").
-
-It also fixes another *old* GPIO regression caused by a parent pointing
-to the NULL:
-[ 0.157054] missing gpiochip .dev parent pointer
-[ 0.157287] bcma: bus0: Error registering GPIO driver: -22
-introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to
-use GPIOLIB_IRQCHIP").
-
-Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms")
-Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP")
-Cc: linux-mips@linux-mips.org
-Cc: Christoph Hellwig <hch@lst.de>
-Cc: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/drivers/bcma/host_soc.c
-+++ b/drivers/bcma/host_soc.c
-@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcm
- struct bcma_bus *bus = &soc->bus;
- int err;
-
-+ bus->dev = soc->dev;
-+
- /* Scan bus and initialize it */
- err = bcma_bus_early_register(bus);
- if (err)
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -236,13 +236,17 @@ EXPORT_SYMBOL(bcma_core_irq);
-
- void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
- {
-- device_initialize(&core->dev);
-+ struct device *dev = &core->dev;
-+
-+ device_initialize(dev);
- core->dev.release = bcma_release_core_dev;
- core->dev.bus = &bcma_bus_type;
-- dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
-+ dev_set_name(dev, "bcma%d:%d", bus->num, core->core_index);
- core->dev.parent = bus->dev;
-- if (bus->dev)
-+ if (bus->dev) {
- bcma_of_fill_device(bus->dev, core);
-+ dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask);
-+ }
-
- switch (bus->hosttype) {
- case BCMA_HOSTTYPE_PCI:
diff --git a/target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch b/target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch
deleted file mode 100644
index c1e14b9271..0000000000
--- a/target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch
+++ /dev/null
@@ -1,222 +0,0 @@
-From fc23ea48ba52c24f201fe5ca0132ee1a3de5a70a Mon Sep 17 00:00:00 2001
-From: Mauri Sandberg <maukka@ext.kapsi.fi>
-Date: Thu, 25 Mar 2021 11:48:05 +0200
-Subject: [PATCH 2/2] gpio: gpio-cascade: add generic GPIO cascade
-
-Adds support for building cascades of GPIO lines. That is, it allows
-setups when there is one upstream line and multiple cascaded lines, out
-of which one can be chosen at a time. The status of the upstream line
-can be conveyed to the selected cascaded line or, vice versa, the status
-of the cascaded line can be conveyed to the upstream line.
-
-A multiplexer is being used to select, which cascaded GPIO line is being
-used at any given time.
-
-At the moment only input direction is supported. In future it should be
-possible to add support for output direction, too.
-
-Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
----
-v7 -> v8:
- - rearrange members in struct gpio_cascade
- - cosmetic changes in file header and in one function declaration
- - added Reviewed-by tags by Linus and Andy
-v6 -> v7:
- - In Kconfig add info about module name
- - adhere to new convention that allows lines longer than 80 chars
- - use dev_probe_err with upstream gpio line too
- - refactor for cleaner exit of probe function.
-v5 -> v6:
- - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
- - refactor code preferring one-liners
- - clean up prints, removing them from success-path.
- - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
- - use devm_gpiochip_add_data instead of gpiochip_add
-v4 -> v5:
- - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
- here and there and changed to use new bindings and compatible string
- - ambigious and vague 'pin' was rename to 'upstream_line'
- - dropped Tested-by and Reviewed-by due to changes in bindings
- - dropped Reported-by suggested by an automatic bot as it was not really
- appropriate to begin with
- - functionally it's the same as v4
-v3 -> v4:
- - Changed author email
- - Included Tested-by and Reviewed-by from Drew
-v2 -> v3:
- - use managed device resources
- - update Kconfig description
-v1 -> v2:
- - removed .owner from platform_driver as per test bot's instruction
- - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
- - added gpio_mux_input_get_direction as it's recommended for all chips
- - removed because this is input only chip: gpio_mux_input_set_value
- - removed because they are not needed for input/output only chips:
- gpio_mux_input_direction_input
- gpio_mux_input_direction_output
- - fixed typo in an error message
- - added info message about successful registration
- - removed can_sleep flag as this does not sleep while getting GPIO value
- like I2C or SPI do
- - Updated description in Kconfig
----
- drivers/gpio/Kconfig | 15 +++++
- drivers/gpio/Makefile | 1 +
- drivers/gpio/gpio-cascade.c | 117 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 133 insertions(+)
- create mode 100644 drivers/gpio/gpio-cascade.c
-
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -1683,4 +1683,19 @@ config GPIO_VIRTIO
-
- endmenu
-
-+comment "Other GPIO expanders"
-+
-+config GPIO_CASCADE
-+ tristate "General GPIO cascade"
-+ select MULTIPLEXER
-+ help
-+ Say yes here to enable support for generic GPIO cascade.
-+
-+ This allows building one-to-many cascades of GPIO lines using
-+ different types of multiplexers readily available. At the
-+ moment only input lines are supported.
-+
-+ To build the driver as a module choose 'm' and the resulting module
-+ will be called 'gpio-cascade'.
-+
- endif
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd
- obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
- obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
- obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o
-+obj-$(CONFIG_GPIO_CASCADE) += gpio-cascade.o
- obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
- obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o
- obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o
---- /dev/null
-+++ b/drivers/gpio/gpio-cascade.c
-@@ -0,0 +1,117 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * A generic GPIO cascade driver
-+ *
-+ * Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
-+ *
-+ * This allows building cascades of GPIO lines in a manner illustrated
-+ * below:
-+ *
-+ * /|---- Cascaded GPIO line 0
-+ * Upstream | |---- Cascaded GPIO line 1
-+ * GPIO line ----+ | .
-+ * | | .
-+ * \|---- Cascaded GPIO line n
-+ *
-+ * A multiplexer is being used to select, which cascaded line is being
-+ * addressed at any given time.
-+ *
-+ * At the moment only input mode is supported due to lack of means for
-+ * testing output functionality. At least theoretically output should be
-+ * possible with open drain constructions.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/platform_device.h>
-+#include <linux/mux/consumer.h>
-+
-+#include <linux/gpio/consumer.h>
-+#include <linux/gpio/driver.h>
-+
-+struct gpio_cascade {
-+ struct gpio_chip gpio_chip;
-+ struct device *parent;
-+ struct mux_control *mux_control;
-+ struct gpio_desc *upstream_line;
-+};
-+
-+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
-+{
-+ return container_of(gc, struct gpio_cascade, gpio_chip);
-+}
-+
-+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset)
-+{
-+ return GPIO_LINE_DIRECTION_IN;
-+}
-+
-+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
-+{
-+ struct gpio_cascade *cas = chip_to_cascade(gc);
-+ int ret;
-+
-+ ret = mux_control_select(cas->mux_control, offset);
-+ if (ret)
-+ return ret;
-+
-+ ret = gpiod_get_value(cas->upstream_line);
-+ mux_control_deselect(cas->mux_control);
-+ return ret;
-+}
-+
-+static int gpio_cascade_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct gpio_cascade *cas;
-+ struct mux_control *mc;
-+ struct gpio_desc *upstream;
-+ struct gpio_chip *gc;
-+
-+ cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
-+ if (!cas)
-+ return -ENOMEM;
-+
-+ mc = devm_mux_control_get(dev, NULL);
-+ if (IS_ERR(mc))
-+ return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
-+
-+ cas->mux_control = mc;
-+ upstream = devm_gpiod_get(dev, "upstream", GPIOD_IN);
-+ if (IS_ERR(upstream))
-+ return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
-+
-+ cas->upstream_line = upstream;
-+ cas->parent = dev;
-+
-+ gc = &cas->gpio_chip;
-+ gc->get = gpio_cascade_get_value;
-+ gc->get_direction = gpio_cascade_get_direction;
-+ gc->base = -1;
-+ gc->ngpio = mux_control_states(mc);
-+ gc->label = dev_name(cas->parent);
-+ gc->parent = cas->parent;
-+ gc->owner = THIS_MODULE;
-+
-+ platform_set_drvdata(pdev, cas);
-+ return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
-+}
-+
-+static const struct of_device_id gpio_cascade_id[] = {
-+ { .compatible = "gpio-cascade" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
-+
-+static struct platform_driver gpio_cascade_driver = {
-+ .driver = {
-+ .name = "gpio-cascade",
-+ .of_match_table = gpio_cascade_id,
-+ },
-+ .probe = gpio_cascade_probe,
-+};
-+module_platform_driver(gpio_cascade_driver);
-+
-+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
-+MODULE_DESCRIPTION("Generic GPIO cascade");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
deleted file mode 100644
index d07447bcba..0000000000
--- a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Thu, 13 Oct 2022 00:51:33 +0900
-Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch fixes crc32 error on Big-Endianness system by conversion of
-calculated crc32 value.
-
-Little-Endianness system:
-
- obtained crc32: Little
-calculated crc32: Little
-
-Big-Endianness system:
-
- obtained crc32: Little
-calculated crc32: Big
-
-log (APRESIA ApresiaLightGS120GT-SS, RTL8382M, Big-Endianness):
-
-[ 8.570000] u_boot_env 18001200.spi:flash@0:partitions:partition@c0000: Invalid calculated CRC32: 0x88cd6f09 (expected: 0x096fcd88)
-[ 8.580000] u_boot_env: probe of 18001200.spi:flash@0:partitions:partition@c0000 failed with error -22
-
-Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables")
-
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Tested-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
- crc32_data_len = dev_size - crc32_data_offset;
- data_len = dev_size - data_offset;
-
-- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
-+ calc = le32_to_cpu((__le32)crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L);
- if (calc != crc32) {
- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
- err = -EINVAL;
diff --git a/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
deleted file mode 100644
index 9bb94a28b5..0000000000
--- a/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 13 Jul 2023 18:29:19 +0200
-Subject: [PATCH] nvmem: core: support "mac-base" fixed layout cells
-
-Fixed layout binding allows specifying "mac-base" NVMEM cells. It's used
-for base MAC address (that can be used for calculating relative
-addresses). It can be stored in a raw binary format or as an ASCII
-string.
----
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- menuconfig NVMEM
- bool "NVMEM Support"
-+ select GENERIC_NET_UTILS
- imply NVMEM_LAYOUTS
- help
- Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES...
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -7,9 +7,12 @@
- */
-
- #include <linux/device.h>
-+#include <linux/ctype.h>
-+#include <linux/etherdevice.h>
- #include <linux/export.h>
- #include <linux/fs.h>
- #include <linux/idr.h>
-+#include <linux/if_ether.h>
- #include <linux/init.h>
- #include <linux/kref.h>
- #include <linux/module.h>
-@@ -780,6 +783,62 @@ static int nvmem_validate_keepouts(struc
- return 0;
- }
-
-+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ if (WARN_ON(bytes != ETH_ALEN))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(buf, index);
-+
-+ return 0;
-+}
-+
-+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN];
-+
-+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1))
-+ return -EINVAL;
-+
-+ if (!mac_pton(buf, mac))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
-+static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN], *hexstr;
-+ int i;
-+
-+ if (WARN_ON(bytes != 2 * ETH_ALEN))
-+ return -EINVAL;
-+
-+ hexstr = (u8 *)buf;
-+ for (i = 0; i < ETH_ALEN; i++) {
-+ if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1]))
-+ return -EINVAL;
-+
-+ mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]);
-+ }
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
- static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
- {
- struct device *dev = &nvmem->dev;
-@@ -814,6 +873,25 @@ static int nvmem_add_cells_from_dt(struc
- if (nvmem->fixup_dt_cell_info)
- nvmem->fixup_dt_cell_info(nvmem, &info);
-
-+ if (of_device_is_compatible(np, "fixed-layout")) {
-+ if (of_device_is_compatible(child, "mac-base")) {
-+ if (info.bytes == ETH_ALEN) {
-+ info.raw_len = info.bytes;
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = nvmem_mac_base_raw_read;
-+ } else if (info.bytes == 2 * ETH_ALEN) {
-+ info.raw_len = info.bytes;
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = nvmem_mac_base_hex_read;
-+ } else if (info.bytes == 3 * ETH_ALEN - 1) {
-+ info.raw_len = info.bytes;
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = nvmem_mac_base_ascii_read;
-+ }
-+
-+ }
-+ }
-+
- ret = nvmem_add_one_cell(nvmem, &info);
- kfree(info.name);
- if (ret) {
diff --git a/target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch
deleted file mode 100644
index 302051cc3b..0000000000
--- a/target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: debloat: add kernel config option to disabling common PCI quirks
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- drivers/pci/Kconfig | 6 ++++++
- drivers/pci/quirks.c | 6 ++++++
- 2 files changed, 12 insertions(+)
-
---- a/drivers/pci/Kconfig
-+++ b/drivers/pci/Kconfig
-@@ -118,6 +118,13 @@ config XEN_PCIDEV_FRONTEND
- The PCI device frontend driver allows the kernel to import arbitrary
- PCI devices from a PCI backend to support PCI driver domains.
-
-+config PCI_DISABLE_COMMON_QUIRKS
-+ bool "PCI disable common quirks"
-+ depends on PCI
-+ help
-+ If you don't know what to do here, say N.
-+
-+
- config PCI_ATS
- bool
-
---- a/drivers/pci/quirks.c
-+++ b/drivers/pci/quirks.c
-@@ -207,6 +207,7 @@ static void quirk_mmio_always_on(struct
- DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
- /*
- * The Mellanox Tavor device gives false positive parity errors. Disable
- * parity error reporting.
-@@ -3369,6 +3370,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
-
-+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
-+
- /*
- * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum.
- * To work around this, query the size it should be configured to by the
-@@ -3394,6 +3397,8 @@ static void quirk_intel_ntb(struct pci_d
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
-+
- /*
- * Some BIOS implementations leave the Intel GPU interrupts enabled, even
- * though no one is handling them (e.g., if the i915 driver is never
-@@ -3432,6 +3437,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
- DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
- DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq);
-
-+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
-+
- /*
- * PCI devices which are on Intel chips can skip the 10ms delay
- * before entering D3 mode.
diff --git a/target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch
deleted file mode 100644
index b498d9f700..0000000000
--- a/target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: debloat: disable common USB quirks
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/usb/host/pci-quirks.c | 16 ++++++++++++++++
- drivers/usb/host/pci-quirks.h | 18 +++++++++++++++++-
- include/linux/usb/hcd.h | 7 +++++++
- 3 files changed, 40 insertions(+), 1 deletion(-)
-
---- a/drivers/usb/host/pci-quirks.c
-+++ b/drivers/usb/host/pci-quirks.c
-@@ -128,6 +128,8 @@ struct amd_chipset_type {
- u8 rev;
- };
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
-+
- static struct amd_chipset_info {
- struct pci_dev *nb_dev;
- struct pci_dev *smbus_dev;
-@@ -633,6 +635,10 @@ bool usb_amd_pt_check_port(struct device
- }
- EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
-
-+#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */
-+
-+#if IS_ENABLED(CONFIG_USB_UHCI_HCD)
-+
- /*
- * Make sure the controller is completely inactive, unable to
- * generate interrupts or do DMA.
-@@ -712,8 +718,17 @@ reset_needed:
- uhci_reset_hc(pdev, base);
- return 1;
- }
-+#else
-+int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
-+{
-+ return 0;
-+}
-+
-+#endif
- EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
-+
- static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
- {
- u16 cmd;
-@@ -1285,3 +1300,4 @@ static void quirk_usb_early_handoff(stru
- }
- DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff);
-+#endif
---- a/drivers/usb/host/pci-quirks.h
-+++ b/drivers/usb/host/pci-quirks.h
-@@ -5,6 +5,9 @@
- #ifdef CONFIG_USB_PCI
- void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
- int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
-+#endif /* CONFIG_USB_PCI */
-+
-+#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS)
- int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev);
- bool usb_amd_hang_symptom_quirk(void);
- bool usb_amd_prefetch_quirk(void);
-@@ -19,6 +22,18 @@ void sb800_prefetch(struct device *dev,
- bool usb_amd_pt_check_port(struct device *device, int port);
- #else
- struct pci_dev;
-+static inline int usb_amd_quirk_pll_check(void)
-+{
-+ return 0;
-+}
-+static inline bool usb_amd_hang_symptom_quirk(void)
-+{
-+ return false;
-+}
-+static inline bool usb_amd_prefetch_quirk(void)
-+{
-+ return false;
-+}
- static inline void usb_amd_quirk_pll_disable(void) {}
- static inline void usb_amd_quirk_pll_enable(void) {}
- static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
-@@ -29,6 +44,11 @@ static inline bool usb_amd_pt_check_port
- {
- return false;
- }
-+static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {}
-+static inline bool usb_xhci_needs_pci_reset(struct pci_dev *pdev)
-+{
-+ return false;
-+}
- #endif /* CONFIG_USB_PCI */
-
- #endif /* __LINUX_USB_PCI_QUIRKS_H */
---- a/include/linux/usb/hcd.h
-+++ b/include/linux/usb/hcd.h
-@@ -498,7 +498,14 @@ extern int usb_hcd_pci_probe(struct pci_
- extern void usb_hcd_pci_remove(struct pci_dev *dev);
- extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
- extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev);
-+#else
-+static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev)
-+{
-+ return 0;
-+}
-+#endif
-
- #ifdef CONFIG_PM
- extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
diff --git a/target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
deleted file mode 100644
index 33eb34c913..0000000000
--- a/target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From d9c8bc8c1408f3e8529db6e4e04017b4c579c342 Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Sun, 18 Feb 2018 17:08:04 +0100
-Subject: [PATCH] w1: gpio: fix problem with platfom data in w1-gpio
-
-In devices, where fdt is used, is impossible to apply platform data
-without proper fdt node.
-
-This patch allow to use platform data in devices with fdt.
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- drivers/w1/masters/w1-gpio.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/drivers/w1/masters/w1-gpio.c
-+++ b/drivers/w1/masters/w1-gpio.c
-@@ -76,7 +76,7 @@ static int w1_gpio_probe(struct platform
- enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN;
- int err;
-
-- if (of_have_populated_dt()) {
-+ if (of_have_populated_dt() && !dev_get_platdata(&pdev->dev)) {
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
diff --git a/target/linux/generic/pending-5.15/834-ledtrig-libata.patch b/target/linux/generic/pending-5.15/834-ledtrig-libata.patch
deleted file mode 100644
index d61e28b4c3..0000000000
--- a/target/linux/generic/pending-5.15/834-ledtrig-libata.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: libata: add ledtrig support
-
-This adds a LED trigger for each ATA port indicating disk activity.
-
-As this is needed only on specific platforms (NAS SoCs and such),
-these platforms should define ARCH_WANTS_LIBATA_LEDS if there
-are boards with LED(s) intended to indicate ATA disk activity and
-need the OS to take care of that.
-In that way, if not selected, LED trigger support not will be
-included in libata-core and both, codepaths and structures remain
-untouched.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/ata/Kconfig | 16 ++++++++++++++++
- drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++
- include/linux/libata.h | 9 +++++++++
- 3 files changed, 66 insertions(+)
-
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -67,6 +67,22 @@ config ATA_FORCE
-
- If unsure, say Y.
-
-+config ARCH_WANT_LIBATA_LEDS
-+ bool
-+
-+config ATA_LEDS
-+ bool "support ATA port LED triggers"
-+ depends on ARCH_WANT_LIBATA_LEDS
-+ select NEW_LEDS
-+ select LEDS_CLASS
-+ select LEDS_TRIGGERS
-+ default y
-+ help
-+ This option adds a LED trigger for each registered ATA port.
-+ It is used to drive disk activity leds connected via GPIO.
-+
-+ If unsure, say N.
-+
- config ATA_ACPI
- bool "ATA ACPI Support"
- depends on ACPI
---- a/drivers/ata/libata-core.c
-+++ b/drivers/ata/libata-core.c
-@@ -656,6 +656,19 @@ u64 ata_tf_read_block(const struct ata_t
- return block;
- }
-
-+#ifdef CONFIG_ATA_LEDS
-+#define LIBATA_BLINK_DELAY 20 /* ms */
-+static inline void ata_led_act(struct ata_port *ap)
-+{
-+ unsigned long led_delay = LIBATA_BLINK_DELAY;
-+
-+ if (unlikely(!ap->ledtrig))
-+ return;
-+
-+ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0);
-+}
-+#endif
-+
- /**
- * ata_build_rw_tf - Build ATA taskfile for given read/write request
- * @tf: Target ATA taskfile
-@@ -4580,6 +4593,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
- if (tag < 0)
- return NULL;
- }
-+#ifdef CONFIG_ATA_LEDS
-+ ata_led_act(ap);
-+#endif
-
- qc = __ata_qc_from_tag(ap, tag);
- qc->tag = qc->hw_tag = tag;
-@@ -5358,6 +5374,9 @@ struct ata_port *ata_port_alloc(struct a
- ap->stats.unhandled_irq = 1;
- ap->stats.idle_irq = 1;
- #endif
-+#ifdef CONFIG_ATA_LEDS
-+ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
-+#endif
- ata_sff_port_init(ap);
-
- return ap;
-@@ -5393,6 +5412,12 @@ static void ata_host_release(struct kref
-
- kfree(ap->pmp_link);
- kfree(ap->slave_link);
-+#ifdef CONFIG_ATA_LEDS
-+ if (ap->ledtrig) {
-+ led_trigger_unregister(ap->ledtrig);
-+ kfree(ap->ledtrig);
-+ };
-+#endif
- kfree(ap);
- host->ports[i] = NULL;
- }
-@@ -5799,7 +5824,23 @@ int ata_host_register(struct ata_host *h
- host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
- host->ports[i]->local_port_no = i + 1;
- }
-+#ifdef CONFIG_ATA_LEDS
-+ for (i = 0; i < host->n_ports; i++) {
-+ if (unlikely(!host->ports[i]->ledtrig))
-+ continue;
-
-+ snprintf(host->ports[i]->ledtrig_name,
-+ sizeof(host->ports[i]->ledtrig_name), "ata%u",
-+ host->ports[i]->print_id);
-+
-+ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name;
-+
-+ if (led_trigger_register(host->ports[i]->ledtrig)) {
-+ kfree(host->ports[i]->ledtrig);
-+ host->ports[i]->ledtrig = NULL;
-+ }
-+ }
-+#endif
- /* Create associated sysfs transport objects */
- for (i = 0; i < host->n_ports; i++) {
- rc = ata_tport_add(host->dev,host->ports[i]);
---- a/include/linux/libata.h
-+++ b/include/linux/libata.h
-@@ -23,6 +23,9 @@
- #include <linux/cdrom.h>
- #include <linux/sched.h>
- #include <linux/async.h>
-+#ifdef CONFIG_ATA_LEDS
-+#include <linux/leds.h>
-+#endif
-
- /*
- * Define if arch has non-standard setup. This is a _PCI_ standard
-@@ -898,6 +901,12 @@ struct ata_port {
- #ifdef CONFIG_ATA_ACPI
- struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
- #endif
-+
-+#ifdef CONFIG_ATA_LEDS
-+ struct led_trigger *ledtrig;
-+ char ledtrig_name[8];
-+#endif
-+
- /* owned by EH */
- u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned;
- };
diff --git a/target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch b/target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch
deleted file mode 100644
index 5ca8933d6f..0000000000
--- a/target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From d6988cf1d16faac56899918bb2b1be8d85155e3f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 20 Feb 2021 18:36:38 +0100
-Subject: [PATCH] hwrng: bcm2835: set quality to 1000
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows devices without a high precission timer to reduce boot from >100s
-to <30s.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- drivers/char/hw_random/bcm2835-rng.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/char/hw_random/bcm2835-rng.c
-+++ b/drivers/char/hw_random/bcm2835-rng.c
-@@ -170,6 +170,7 @@ static int bcm2835_rng_probe(struct plat
- priv->rng.init = bcm2835_rng_init;
- priv->rng.read = bcm2835_rng_read;
- priv->rng.cleanup = bcm2835_rng_cleanup;
-+ priv->rng.quality = 1000;
-
- if (dev_of_node(dev)) {
- rng_id = of_match_node(bcm2835_rng_of_match, dev->of_node);
diff --git a/target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch b/target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch
deleted file mode 100644
index e180a385e1..0000000000
--- a/target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 663b9f99bb35dbc0c7b685f71ee3668a60d31320 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 10 Jan 2022 02:02:00 +0100
-Subject: [PATCH] PCI: aardvark: Make main irq_chip structure a static driver
- structure
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Marc Zyngier says [1] that we should use struct irq_chip as a global
-static struct in the driver. Even though the structure currently
-contains a dynamic member (parent_device), Marc says [2] that he plans
-to kill it and make the structure completely static.
-
-We have already converted others irq_chip structures in this driver in
-this way, but we omitted this one because the .name member is
-dynamically created from device's name, and the name is displayed in
-sysfs, so changing it would break sysfs ABI.
-
-The rationale for changing the name (to "advk-INT") in spite of sysfs
-ABI, and thus allowing to convert to a static structure, is that after
-the other changes we made in this series, the IRQ chip is basically
-something different: it no logner generates ERR and PME interrupts (they
-are generated by emulated bridge's rp_irq_chip).
-
-[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz@kernel.org/
-[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz@kernel.org/
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
----
- drivers/pci/controller/pci-aardvark.c | 25 +++++++------------------
- 1 file changed, 7 insertions(+), 18 deletions(-)
-
---- a/drivers/pci/controller/pci-aardvark.c
-+++ b/drivers/pci/controller/pci-aardvark.c
-@@ -275,7 +275,6 @@ struct advk_pcie {
- u8 wins_count;
- struct irq_domain *rp_irq_domain;
- struct irq_domain *irq_domain;
-- struct irq_chip irq_chip;
- raw_spinlock_t irq_lock;
- struct irq_domain *msi_domain;
- struct irq_domain *msi_inner_domain;
-@@ -1345,14 +1344,19 @@ static void advk_pcie_irq_unmask(struct
- raw_spin_unlock_irqrestore(&pcie->irq_lock, flags);
- }
-
-+static struct irq_chip advk_irq_chip = {
-+ .name = "advk-INT",
-+ .irq_mask = advk_pcie_irq_mask,
-+ .irq_unmask = advk_pcie_irq_unmask,
-+};
-+
- static int advk_pcie_irq_map(struct irq_domain *h,
- unsigned int virq, irq_hw_number_t hwirq)
- {
- struct advk_pcie *pcie = h->host_data;
-
- irq_set_status_flags(virq, IRQ_LEVEL);
-- irq_set_chip_and_handler(virq, &pcie->irq_chip,
-- handle_level_irq);
-+ irq_set_chip_and_handler(virq, &advk_irq_chip, handle_level_irq);
- irq_set_chip_data(virq, pcie);
-
- return 0;
-@@ -1411,7 +1415,6 @@ static int advk_pcie_init_irq_domain(str
- struct device *dev = &pcie->pdev->dev;
- struct device_node *node = dev->of_node;
- struct device_node *pcie_intc_node;
-- struct irq_chip *irq_chip;
- int ret = 0;
-
- raw_spin_lock_init(&pcie->irq_lock);
-@@ -1422,28 +1425,14 @@ static int advk_pcie_init_irq_domain(str
- return -ENODEV;
- }
-
-- irq_chip = &pcie->irq_chip;
--
-- irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq",
-- dev_name(dev));
-- if (!irq_chip->name) {
-- ret = -ENOMEM;
-- goto out_put_node;
-- }
--
-- irq_chip->irq_mask = advk_pcie_irq_mask;
-- irq_chip->irq_unmask = advk_pcie_irq_unmask;
--
- pcie->irq_domain =
- irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
- &advk_pcie_irq_domain_ops, pcie);
- if (!pcie->irq_domain) {
- dev_err(dev, "Failed to get a INTx IRQ domain\n");
- ret = -ENOMEM;
-- goto out_put_node;
- }
-
--out_put_node:
- of_node_put(pcie_intc_node);
- return ret;
- }
diff --git a/target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch b/target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch
deleted file mode 100644
index cc6f1e0d9d..0000000000
--- a/target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From patchwork Wed Mar 22 17:15:12 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13184389
-Return-Path: <linux-clk-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 73F2DC6FD1C
- for <linux-clk@archiver.kernel.org>; Wed, 22 Mar 2023 17:15:59 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231363AbjCVRP5 (ORCPT <rfc822;linux-clk@archiver.kernel.org>);
- Wed, 22 Mar 2023 13:15:57 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58824 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231408AbjCVRPy (ORCPT
- <rfc822;linux-clk@vger.kernel.org>); Wed, 22 Mar 2023 13:15:54 -0400
-Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com
- [IPv6:2a00:1450:4864:20::32d])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70E4C64B28;
- Wed, 22 Mar 2023 10:15:24 -0700 (PDT)
-Received: by mail-wm1-x32d.google.com with SMTP id n19so1740892wms.0;
- Wed, 22 Mar 2023 10:15:24 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679505322;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=;
- b=LTOQ75W3s5nYo+nEfiJAKqytSopONB4jCtU3zRygzPMasugVOrYFMsUR+WrpsAjuRT
- v4HgWpJxEsIWeRXrUN9W21mFXhGgJLJXSxRnrio0CsZZBNMdkebbNOphgKXIWAdm+2iM
- PzqAdGm5t38wT2mmm6V/9hCy90+12raHM82tNFdhhiezfg2cukVOKP3j/TeOVCwas0gQ
- iFc+CuZB6y73zYXvMUMUpTsqI5vev4xJsSMHIQJVmUxJAwqhOBhN9JCRo7Ao+wayjn2d
- Fxo6AV3A8v68nVfoQ0K0I+eWXG48nMCX45iWh/lVvVTOFcR99kn4va7NY1oVnPsh+WQz
- WcLA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679505322;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=;
- b=wv2NSR1B5RnsdoEE7mgJSHAfSs1JHZbQ1HPMldyaGWAk1dcucqh/uDzM3Flz+ADRi1
- 19NoaB2Ur7QaWZejbuplnIOK/nte3PnmqJ9ZNw8HejmuS4eU8mB1V1aJUSKSPGsfUi4a
- LYe3HSw87l0jrAC7ptdKvdUtzBoIkX0CeFvfguTQQkDhUTyAFIG144hY6uPXY9Mga96b
- gnNe2dLCzHQLbEJpaDaavT7FEEcLDxaq7jNcR2xqEEZaIwfcew+Q05t4xL/3i8GAj9Ru
- 6ivQjIbBKfYQF88o7KnOW9o1wjrGsk+Nd4Iy0OLZix3JQasCJGrKV7ib5awI9J39upYV
- fa4A==
-X-Gm-Message-State: AO0yUKWw75I1M5Vjrd4vXq4GTruQu0H84pycgyi2CT3bczTYRJpWmEWg
- +bHDhvp1n5IWW85GI9vKWpbclB13a/S0RQ==
-X-Google-Smtp-Source:
- AK7set9T/2oJsVetUb2L4mPEWu8YqDrnK8EzHK5bJf1ABIa1Et8f7BFJ7AA3j14ITZuf8cH0HqlRtg==
-X-Received: by 2002:a05:600c:2304:b0:3ed:2949:985b with SMTP id
- 4-20020a05600c230400b003ed2949985bmr206833wmo.23.1679505322457;
- Wed, 22 Mar 2023 10:15:22 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.21
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Wed, 22 Mar 2023 10:15:22 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de,
- f.fainelli@gmail.com, jonas.gorski@gmail.com,
- william.zhang@broadcom.com, linux-clk@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>,
- Rob Herring <robh@kernel.org>
-Subject: [PATCH v4 1/4] dt-bindings: clk: add BCM63268 timer clock definitions
-Date: Wed, 22 Mar 2023 18:15:12 +0100
-Message-Id: <20230322171515.120353-2-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230322171515.120353-1-noltari@gmail.com>
-References: <20230322171515.120353-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-clk.vger.kernel.org>
-X-Mailing-List: linux-clk@vger.kernel.org
-
-Add missing timer clock definitions for BCM63268.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Rob Herring <robh@kernel.org>
----
- v4: no changes
- v3: no changes
- v2: change commit title, as suggested by Stephen Boyd
-
- include/dt-bindings/clock/bcm63268-clock.h | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/include/dt-bindings/clock/bcm63268-clock.h
-+++ b/include/dt-bindings/clock/bcm63268-clock.h
-@@ -27,4 +27,17 @@
- #define BCM63268_CLK_TBUS 27
- #define BCM63268_CLK_ROBOSW250 31
-
-+#define BCM63268_TCLK_EPHY1 0
-+#define BCM63268_TCLK_EPHY2 1
-+#define BCM63268_TCLK_EPHY3 2
-+#define BCM63268_TCLK_GPHY1 3
-+#define BCM63268_TCLK_DSL 4
-+#define BCM63268_TCLK_WAKEON_EPHY 6
-+#define BCM63268_TCLK_WAKEON_DSL 7
-+#define BCM63268_TCLK_FAP1 11
-+#define BCM63268_TCLK_FAP2 15
-+#define BCM63268_TCLK_UTO_50 16
-+#define BCM63268_TCLK_UTO_EXTIN 17
-+#define BCM63268_TCLK_USB_REF 18
-+
- #endif /* __DT_BINDINGS_CLOCK_BCM63268_H */
diff --git a/target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch b/target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch
deleted file mode 100644
index 5f1be105ac..0000000000
--- a/target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From patchwork Wed Mar 22 17:15:13 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13184390
-Return-Path: <linux-clk-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id D0B1AC6FD1C
- for <linux-clk@archiver.kernel.org>; Wed, 22 Mar 2023 17:16:08 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231472AbjCVRQI (ORCPT <rfc822;linux-clk@archiver.kernel.org>);
- Wed, 22 Mar 2023 13:16:08 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58934 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231435AbjCVRP5 (ORCPT
- <rfc822;linux-clk@vger.kernel.org>); Wed, 22 Mar 2023 13:15:57 -0400
-Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com
- [IPv6:2a00:1450:4864:20::329])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9655064863;
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-Received: by mail-wm1-x329.google.com with SMTP id
- v4-20020a05600c470400b003ee4f06428fso2424553wmo.4;
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679505324;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=;
- b=WRZRU2SM9n1LfUj4SgTPfQczADC2pfvoIrOsNpBLTym2eOfmkTetb/WbGSla5kw2Wb
- SH5MIC2fFeScJg6T5FFAUOOLmRVW9xvl8Q3T3NKb3z/9wvPHO767nrdIbffRWMJFs7gW
- wT/kuTpn8GYdfY0sZ/dMTkq41DVusEkxfX6GxtG85O98ZP8xMHQog8aPs9fRfUvI5ZKB
- eGYcRz/Wn1cHhjey9jtWzQEEmZ/BT3b0HQTF9Tl88oofhiEgbyjFXr91+vRsLbsJpGXH
- /1FjjaLG5DnonKubV9rmbuCU8KzwH331gi2KuRjvLD2V+OMewqSa5i+GvgVv8x2zC8y+
- /mLQ==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679505324;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=;
- b=bhd0fNh0jDOMlGSC4F+p5igV8AUlGEPj2cXUwgdgqRfSSuUy9z+Li8cT0MbY/aWH5Z
- qInRVA+R1cWV3ubrDyKag6oEc0LDU234bnMFcP9b7MRlrM8Dpit9TFSyqJU4sDUWNDs5
- KOe2k/SNIdat6munC9VOuEBDO0eB/UDMN+repKwXNdHChp/Toq9qMvW4Uy8uHxosbQlD
- 8P88GbKFjynb1E8I8croGjfub7+y8PPsWB0xNUcafIv6xs3MnVOP1Mk4KwBCbqS509la
- mfjsriXtIybO8XFqtn100ungjvbFWdogEplLdSPVdgAqdfF5J8gHxAoApoeYejYkL5/R
- kOhQ==
-X-Gm-Message-State: AO0yUKWdzr3dMmjKhD8tF+ec4Dfdq9VGZ/WCU4d85npKQvxSwhNPZZ1J
- 5WYRIqivh0suFC1OqEidwenpiJYvXedYjw==
-X-Google-Smtp-Source:
- AK7set87ew2/mKWeShXTTW/YBbBJNR2zeGFV0CfuqLXhiJEU6tqFuyKcW+vFEoKHIbNUS8wRy1SzLA==
-X-Received: by 2002:a05:600c:290:b0:3ee:6d88:774a with SMTP id
- 16-20020a05600c029000b003ee6d88774amr160734wmk.14.1679505323514;
- Wed, 22 Mar 2023 10:15:23 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.22
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Wed, 22 Mar 2023 10:15:23 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de,
- f.fainelli@gmail.com, jonas.gorski@gmail.com,
- william.zhang@broadcom.com, linux-clk@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>,
- Rob Herring <robh@kernel.org>
-Subject: [PATCH v4 2/4] dt-bindings: reset: add BCM63268 timer reset
- definitions
-Date: Wed, 22 Mar 2023 18:15:13 +0100
-Message-Id: <20230322171515.120353-3-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230322171515.120353-1-noltari@gmail.com>
-References: <20230322171515.120353-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-clk.vger.kernel.org>
-X-Mailing-List: linux-clk@vger.kernel.org
-
-Add missing timer reset definitions for BCM63268.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Rob Herring <robh@kernel.org>
----
- v4: no changes
- v3: no changes
- v2: change commit title, as suggested by Stephen Boyd
-
- include/dt-bindings/reset/bcm63268-reset.h | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/include/dt-bindings/reset/bcm63268-reset.h
-+++ b/include/dt-bindings/reset/bcm63268-reset.h
-@@ -23,4 +23,8 @@
- #define BCM63268_RST_PCIE_HARD 17
- #define BCM63268_RST_GPHY 18
-
-+#define BCM63268_TRST_SW 29
-+#define BCM63268_TRST_HW 30
-+#define BCM63268_TRST_POR 31
-+
- #endif /* __DT_BINDINGS_RESET_BCM63268_H */
diff --git a/target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch b/target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch
deleted file mode 100644
index 7e500cd1b5..0000000000
--- a/target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch
+++ /dev/null
@@ -1,345 +0,0 @@
-From patchwork Wed Mar 22 17:15:15 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13184392
-Return-Path: <linux-clk-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 199D9C76196
- for <linux-clk@archiver.kernel.org>; Wed, 22 Mar 2023 17:16:11 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231512AbjCVRQJ (ORCPT <rfc822;linux-clk@archiver.kernel.org>);
- Wed, 22 Mar 2023 13:16:09 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58942 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231442AbjCVRP5 (ORCPT
- <rfc822;linux-clk@vger.kernel.org>); Wed, 22 Mar 2023 13:15:57 -0400
-Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com
- [IPv6:2a00:1450:4864:20::32c])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DDB36487D;
- Wed, 22 Mar 2023 10:15:27 -0700 (PDT)
-Received: by mail-wm1-x32c.google.com with SMTP id
- i5-20020a05600c354500b003edd24054e0so6717370wmq.4;
- Wed, 22 Mar 2023 10:15:27 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679505325;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=;
- b=Y1mva2Bt3sUbKxLgEUS331CJbGxUc4z8kTQW8qiHWGhYlFKtm+d5z4sT40E5BeZAnU
- zmTbCI7jbroe9NYBxGUmSli6LNVDPjND80ChbhWTqbqMQTmeQFWut9KmeBWK6Oze2lC/
- XMSOorUzowjcU2xtHNrzoq2KH2pstW573lsB8WnzFVfhMaRkE9DfRr6WNyA7zC8DyxM5
- ezxlCQtCmgPfCqlyksbIDKrgrRf3GiUR0yUd6xRU+MssyvH1FkYGDCerPctDto6lGHBz
- 8Y15jT3l6OnQMT6dkekgpPF5/XrSUY93u9g0B4U8+0dhNj+K7vmDen+jqdess+tpLnq/
- gFrA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679505325;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=;
- b=Ym4+u8bbTQGNkewUBrLf+89vE0EFJBQp2f1crwUxZFboKTROF9ltZonY1CGepo7b0B
- fkx3TbWQy5X65g3ScuieqtClCI8WanPeNBJ48+JipJYO3ODVNBxnVaTuW/0FOIcahfqe
- sG5GvggHhzRz+Yeybsbnupmzxnw8Ez0BpMl3p7zcjHL7BGZDdOOX2Zbw3zfyYa5sg2nX
- UXYJT36zy2h39gxUsy9QkhQ76CG3w6omniohZpYidpojpiDjbOy0nKFky4kUe+YyA1fF
- 4IBhjAm6mH+uh6wHSG1qj+NAXHs0xDDJps16PbJwAgL7Qt9K5WW+R/UAYPmHFgaRIHOw
- /seA==
-X-Gm-Message-State: AO0yUKXRtoYO8Nfus6Ca8lhM39P1Xn6TGkhatEfoISd1YNOkTJJN2hW+
- xRphLgxlzNfCLcVPlpGK9dk=
-X-Google-Smtp-Source:
- AK7set9VnMEykugk8ZYnkXuqK41bX1dzlvKsAXHEjr8i2NZBld0buKhQLcGYEcwxnBgVTtC7eRGfXw==
-X-Received: by 2002:a1c:7c0b:0:b0:3e2:1dac:b071 with SMTP id
- x11-20020a1c7c0b000000b003e21dacb071mr178053wmc.13.1679505325582;
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.24
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de,
- f.fainelli@gmail.com, jonas.gorski@gmail.com,
- william.zhang@broadcom.com, linux-clk@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v4 4/4] clk: bcm: Add BCM63268 timer clock and reset driver
-Date: Wed, 22 Mar 2023 18:15:15 +0100
-Message-Id: <20230322171515.120353-5-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230322171515.120353-1-noltari@gmail.com>
-References: <20230322171515.120353-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-clk.vger.kernel.org>
-X-Mailing-List: linux-clk@vger.kernel.org
-
-Add driver for BCM63268 timer clock and reset controller.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- v4: add changes suggested by Stephen Boyd:
- - Usage of of_device_get_match_data() isn't needed.
- - Use devm_clk_hw_register_gate().
- - Drop clk_hw_unregister_gate().
- v3: add missing <linux/io.h> include to fix build warning
- v2: add changes suggested by Stephen Boyd
-
- drivers/clk/bcm/Kconfig | 9 ++
- drivers/clk/bcm/Makefile | 1 +
- drivers/clk/bcm/clk-bcm63268-timer.c | 215 +++++++++++++++++++++++++++
- 3 files changed, 225 insertions(+)
- create mode 100644 drivers/clk/bcm/clk-bcm63268-timer.c
-
---- a/drivers/clk/bcm/Kconfig
-+++ b/drivers/clk/bcm/Kconfig
-@@ -37,6 +37,15 @@ config CLK_BCM_63XX_GATE
- Enable common clock framework support for Broadcom BCM63xx DSL SoCs
- based on the MIPS architecture
-
-+config CLK_BCM63268_TIMER
-+ bool "Broadcom BCM63268 timer clock and reset support"
-+ depends on BMIPS_GENERIC || COMPILE_TEST
-+ default BMIPS_GENERIC
-+ select RESET_CONTROLLER
-+ help
-+ Enable timer clock and reset support for Broadcom BCM63268 DSL SoCs
-+ based on the MIPS architecture.
-+
- config CLK_BCM_KONA
- bool "Broadcom Kona CCU clock support"
- depends on ARCH_BCM_MOBILE || COMPILE_TEST
---- a/drivers/clk/bcm/Makefile
-+++ b/drivers/clk/bcm/Makefile
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o
- obj-$(CONFIG_CLK_BCM_63XX_GATE) += clk-bcm63xx-gate.o
-+obj-$(CONFIG_CLK_BCM63268_TIMER) += clk-bcm63268-timer.o
- obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o
- obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o
- obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
---- /dev/null
-+++ b/drivers/clk/bcm/clk-bcm63268-timer.c
-@@ -0,0 +1,215 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * BCM63268 Timer Clock and Reset Controller Driver
-+ *
-+ * Copyright (C) 2023 Álvaro Fernández Rojas <noltari@gmail.com>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset-controller.h>
-+
-+#include <dt-bindings/clock/bcm63268-clock.h>
-+
-+#define BCM63268_TIMER_RESET_SLEEP_MIN_US 10000
-+#define BCM63268_TIMER_RESET_SLEEP_MAX_US 20000
-+
-+struct bcm63268_tclkrst_hw {
-+ void __iomem *regs;
-+ spinlock_t lock;
-+
-+ struct reset_controller_dev rcdev;
-+ struct clk_hw_onecell_data data;
-+};
-+
-+struct bcm63268_tclk_table_entry {
-+ const char * const name;
-+ u8 bit;
-+};
-+
-+static const struct bcm63268_tclk_table_entry bcm63268_timer_clocks[] = {
-+ {
-+ .name = "ephy1",
-+ .bit = BCM63268_TCLK_EPHY1,
-+ }, {
-+ .name = "ephy2",
-+ .bit = BCM63268_TCLK_EPHY2,
-+ }, {
-+ .name = "ephy3",
-+ .bit = BCM63268_TCLK_EPHY3,
-+ }, {
-+ .name = "gphy1",
-+ .bit = BCM63268_TCLK_GPHY1,
-+ }, {
-+ .name = "dsl",
-+ .bit = BCM63268_TCLK_DSL,
-+ }, {
-+ .name = "wakeon_ephy",
-+ .bit = BCM63268_TCLK_WAKEON_EPHY,
-+ }, {
-+ .name = "wakeon_dsl",
-+ .bit = BCM63268_TCLK_WAKEON_DSL,
-+ }, {
-+ .name = "fap1_pll",
-+ .bit = BCM63268_TCLK_FAP1,
-+ }, {
-+ .name = "fap2_pll",
-+ .bit = BCM63268_TCLK_FAP2,
-+ }, {
-+ .name = "uto_50",
-+ .bit = BCM63268_TCLK_UTO_50,
-+ }, {
-+ .name = "uto_extin",
-+ .bit = BCM63268_TCLK_UTO_EXTIN,
-+ }, {
-+ .name = "usb_ref",
-+ .bit = BCM63268_TCLK_USB_REF,
-+ }, {
-+ /* sentinel */
-+ }
-+};
-+
-+static inline struct bcm63268_tclkrst_hw *
-+to_bcm63268_timer_reset(struct reset_controller_dev *rcdev)
-+{
-+ return container_of(rcdev, struct bcm63268_tclkrst_hw, rcdev);
-+}
-+
-+static int bcm63268_timer_reset_update(struct reset_controller_dev *rcdev,
-+ unsigned long id, bool assert)
-+{
-+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev);
-+ unsigned long flags;
-+ uint32_t val;
-+
-+ spin_lock_irqsave(&reset->lock, flags);
-+ val = __raw_readl(reset->regs);
-+ if (assert)
-+ val &= ~BIT(id);
-+ else
-+ val |= BIT(id);
-+ __raw_writel(val, reset->regs);
-+ spin_unlock_irqrestore(&reset->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int bcm63268_timer_reset_assert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return bcm63268_timer_reset_update(rcdev, id, true);
-+}
-+
-+static int bcm63268_timer_reset_deassert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return bcm63268_timer_reset_update(rcdev, id, false);
-+}
-+
-+static int bcm63268_timer_reset_reset(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ bcm63268_timer_reset_update(rcdev, id, true);
-+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US,
-+ BCM63268_TIMER_RESET_SLEEP_MAX_US);
-+
-+ bcm63268_timer_reset_update(rcdev, id, false);
-+ /*
-+ * Ensure component is taken out reset state by sleeping also after
-+ * deasserting the reset. Otherwise, the component may not be ready
-+ * for operation.
-+ */
-+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US,
-+ BCM63268_TIMER_RESET_SLEEP_MAX_US);
-+
-+ return 0;
-+}
-+
-+static int bcm63268_timer_reset_status(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev);
-+
-+ return !(__raw_readl(reset->regs) & BIT(id));
-+}
-+
-+static struct reset_control_ops bcm63268_timer_reset_ops = {
-+ .assert = bcm63268_timer_reset_assert,
-+ .deassert = bcm63268_timer_reset_deassert,
-+ .reset = bcm63268_timer_reset_reset,
-+ .status = bcm63268_timer_reset_status,
-+};
-+
-+static int bcm63268_tclk_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ const struct bcm63268_tclk_table_entry *entry;
-+ struct bcm63268_tclkrst_hw *hw;
-+ struct clk_hw *clk;
-+ u8 maxbit = 0;
-+ int i, ret;
-+
-+ for (entry = bcm63268_timer_clocks; entry->name; entry++)
-+ maxbit = max(maxbit, entry->bit);
-+ maxbit++;
-+
-+ hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
-+ GFP_KERNEL);
-+ if (!hw)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, hw);
-+
-+ spin_lock_init(&hw->lock);
-+
-+ hw->data.num = maxbit;
-+ for (i = 0; i < maxbit; i++)
-+ hw->data.hws[i] = ERR_PTR(-ENODEV);
-+
-+ hw->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(hw->regs))
-+ return PTR_ERR(hw->regs);
-+
-+ for (entry = bcm63268_timer_clocks; entry->name; entry++) {
-+ clk = devm_clk_hw_register_gate(dev, entry->name, NULL, 0,
-+ hw->regs, entry->bit,
-+ CLK_GATE_BIG_ENDIAN,
-+ &hw->lock);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+
-+ hw->data.hws[entry->bit] = clk;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
-+ &hw->data);
-+ if (ret)
-+ return ret;
-+
-+ hw->rcdev.of_node = dev->of_node;
-+ hw->rcdev.ops = &bcm63268_timer_reset_ops;
-+
-+ ret = devm_reset_controller_register(dev, &hw->rcdev);
-+ if (ret)
-+ dev_err(dev, "Failed to register reset controller\n");
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id bcm63268_tclk_dt_ids[] = {
-+ { .compatible = "brcm,bcm63268-timer-clocks" },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver bcm63268_tclk = {
-+ .probe = bcm63268_tclk_probe,
-+ .driver = {
-+ .name = "bcm63268-timer-clock",
-+ .of_match_table = bcm63268_tclk_dt_ids,
-+ },
-+};
-+builtin_platform_driver(bcm63268_tclk);
diff --git a/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch b/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch
deleted file mode 100644
index c5db5d9491..0000000000
--- a/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 629c701fc39f1ada9416e0766a86729e83bde86c Mon Sep 17 00:00:00 2001
-Message-ID: <629c701fc39f1ada9416e0766a86729e83bde86c.1694465766.git.daniel@makrotopia.org>
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 11 Sep 2023 21:27:44 +0100
-Subject: [PATCH] serial: 8250_mtk: track busclk state to avoid bus error
-To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
- Jiri Slaby <jirislaby@kernel.org>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Daniel Golle <daniel@makrotopia.org>,
- John Ogness <john.ogness@linutronix.de>,
- Chen-Yu Tsai <wenst@chromium.org>,
- Changqi Hu <changqi.hu@mediatek.com>,
- linux-kernel@vger.kernel.org,
- linux-serial@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org
-
-Commit e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and
-clock management") introduced polling a debug register to make sure
-the UART is idle before disabling the bus clock. However, at least on
-some MediaTek SoCs access to that very debug register requires the bus
-clock being enabled. Hence calling the suspend function while already
-in suspended state results in that register access triggering a bus
-error. In order to avoid that, track the state of the bus clock and
-only poll the debug register if not already in suspended state.
-
-Fixes: e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and clock management")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/tty/serial/8250/8250_mtk.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
---- a/drivers/tty/serial/8250/8250_mtk.c
-+++ b/drivers/tty/serial/8250/8250_mtk.c
-@@ -32,7 +32,7 @@
- #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */
- #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */
- #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */
--#define MTK_UART_DEBUG0 0x18
-+#define MTK_UART_DEBUG0 0x18
- #define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */
- #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */
- #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */
-@@ -418,13 +418,12 @@ static int __maybe_unused mtk8250_runtim
- struct mtk8250_data *data = dev_get_drvdata(dev);
- struct uart_8250_port *up = serial8250_get_port(data->line);
-
-- /* wait until UART in idle status */
-- while
-- (serial_in(up, MTK_UART_DEBUG0));
--
- if (data->clk_count == 0U) {
- dev_dbg(dev, "%s clock count is 0\n", __func__);
- } else {
-+ /* wait until UART in idle status */
-+ while
-+ (serial_in(up, MTK_UART_DEBUG0));
- clk_disable_unprepare(data->bus_clk);
- data->clk_count--;
- }
diff --git a/target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch b/target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch
deleted file mode 100644
index 186b052d40..0000000000
--- a/target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 89a74fc5d367441bf4912e9158f0640ea3494b9e Mon Sep 17 00:00:00 2001
-From: Lech Perczak <lech.perczak@gmail.com>
-Date: Fri, 17 Nov 2023 21:33:04 +0100
-Subject: [PATCH] ARM: dts: nxp: imx7d-pico: add cpu-supply nodes
-
-The PICO-IMX7D SoM has the usual power supply configuration using
-output sw1a of PF3000 PMIC, which was defined in downstream derivative
-of linux-imx (see link) in the sources for "Android Things" devkit.
-It is required to support CPU frequency scaling.
-
-Map the respective "cpu-supply" nodes of each core to sw1a of the PMIC.
-
-Enabling them causes cpufreq-dt, and imx-thermal drivers to probe
-successfully, and CPU frequency scaling to function.
-
-Link: https://android.googlesource.com/platform/hardware/bsp/kernel/nxp/imx-v4.1/+/o-iot-preview-5/arch/arm/boot/dts/imx7d-pico.dtsi#849
-
-Cc: Fabio Estevam <festevam@gmail.com>
-Cc: Shawn Guo <shawnguo@kernel.org>
-Cc: Sascha Hauer <s.hauer@pengutronix.de>
-
-Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
----
- arch/arm/boot/dts/imx7d-pico.dtsi | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/imx7d-pico.dtsi
-+++ b/arch/arm/boot/dts/imx7d-pico.dtsi
-@@ -108,6 +108,14 @@
- assigned-clock-rates = <0>, <32768>;
- };
-
-+&cpu0 {
-+ cpu-supply = <&sw1a_reg>;
-+};
-+
-+&cpu1 {
-+ cpu-supply = <&sw1a_reg>;
-+};
-+
- &ecspi3 {
- cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>;
- pinctrl-names = "default";
diff --git a/target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch b/target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch
deleted file mode 100644
index 04c6efe3e8..0000000000
--- a/target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 38eb5b3370c29515d2ce92adac2d6eba96f276f5 Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Wed, 20 Mar 2024 15:32:18 +0900
-Subject: [PATCH v2 1/2] dt-bindings: leds: add LED_FUNCTION_MOBILE for mobile
- network
-
-Add LED_FUNCTION_MOBILE for LEDs that indicate status of mobile network
-connection. This is useful to distinguish those LEDs from LEDs that
-indicates status of wired "wan" connection.
-
-example (on stock fw):
-
-IIJ SA-W2 has "Mobile" LEDs that indicate status (no signal, too low,
-low, good) of mobile network connection via dongle connected to USB
-port.
-
-- no signal: (none, turned off)
-- too low: green:mobile & red:mobile (amber, blink)
-- low: green:mobile & red:mobile (amber, turned on)
-- good: green:mobile (turned on)
-
-Suggested-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- include/dt-bindings/leds/common.h | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -83,6 +83,7 @@
- #define LED_FUNCTION_INDICATOR "indicator"
- #define LED_FUNCTION_LAN "lan"
- #define LED_FUNCTION_MAIL "mail"
-+#define LED_FUNCTION_MOBILE "mobile"
- #define LED_FUNCTION_MTD "mtd"
- #define LED_FUNCTION_PANIC "panic"
- #define LED_FUNCTION_PROGRAMMING "programming"
diff --git a/target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch b/target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch
deleted file mode 100644
index e601481446..0000000000
--- a/target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From e22afe910afcfb51b6ba6a0ae776939959727f54 Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Wed, 20 Mar 2024 15:59:06 +0900
-Subject: [PATCH v2 2/2] dt-bindings: leds: add LED_FUNCTION_SPEED_* for link
- speed on LAN/WAN
-
-Add LED_FUNCTION_SPEED_LAN and LED_FUNCTION_SPEED_WAN for LEDs that
-indicate link speed of ethernet ports on LAN/WAN. This is useful to
-distinguish those LEDs from LEDs that indicate link status (up/down).
-
-example:
-
-Fortinet FortiGate 30E/50E have LEDs that indicate link speed on each
-of the ethernet ports in addition to LEDs that indicate link status
-(up/down).
-
-- 1000 Mbps: green:speed-(lan|wan)-N
-- 100 Mbps: amber:speed-(lan|wan)-N
-- 10 Mbps: (none, turned off)
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- include/dt-bindings/leds/common.h | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -89,6 +89,8 @@
- #define LED_FUNCTION_PROGRAMMING "programming"
- #define LED_FUNCTION_RX "rx"
- #define LED_FUNCTION_SD "sd"
-+#define LED_FUNCTION_SPEED_LAN "speed-lan"
-+#define LED_FUNCTION_SPEED_WAN "speed-wan"
- #define LED_FUNCTION_STANDBY "standby"
- #define LED_FUNCTION_TORCH "torch"
- #define LED_FUNCTION_TX "tx"
diff --git a/target/linux/generic/pending-5.15/920-mangle_bootargs.patch b/target/linux/generic/pending-5.15/920-mangle_bootargs.patch
deleted file mode 100644
index b127d76e00..0000000000
--- a/target/linux/generic/pending-5.15/920-mangle_bootargs.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Imre Kaloz <kaloz@openwrt.org>
-Subject: init: add CONFIG_MANGLE_BOOTARGS and disable it by default
-
-Enabling this option renames the bootloader supplied root=
-and rootfstype= variables, which might have to be know but
-would break the automatisms OpenWrt uses.
-
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- init/Kconfig | 9 +++++++++
- init/main.c | 24 ++++++++++++++++++++++++
- 2 files changed, 33 insertions(+)
-
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1814,6 +1814,15 @@ config EMBEDDED
- an embedded system so certain expert options are available
- for configuration.
-
-+config MANGLE_BOOTARGS
-+ bool "Rename offending bootargs"
-+ depends on EXPERT
-+ help
-+ Sometimes the bootloader passed bogus root= and rootfstype=
-+ parameters to the kernel, and while you want to ignore them,
-+ you need to know the values f.e. to support dual firmware
-+ layouts on the flash.
-+
- config HAVE_PERF_EVENTS
- bool
- help
---- a/init/main.c
-+++ b/init/main.c
-@@ -619,6 +619,29 @@ static inline void setup_nr_cpu_ids(void
- static inline void smp_prepare_cpus(unsigned int maxcpus) { }
- #endif
-
-+#ifdef CONFIG_MANGLE_BOOTARGS
-+static void __init mangle_bootargs(char *command_line)
-+{
-+ char *rootdev;
-+ char *rootfs;
-+
-+ rootdev = strstr(command_line, "root=/dev/mtdblock");
-+
-+ if (rootdev)
-+ strncpy(rootdev, "mangled_rootblock=", 18);
-+
-+ rootfs = strstr(command_line, "rootfstype");
-+
-+ if (rootfs)
-+ strncpy(rootfs, "mangled_fs", 10);
-+
-+}
-+#else
-+static void __init mangle_bootargs(char *command_line)
-+{
-+}
-+#endif
-+
- /*
- * We need to store the untouched command line for future reference.
- * We also need to store the touched command line since the parameter
-@@ -960,6 +983,7 @@ asmlinkage __visible void __init __no_sa
- pr_notice("%s", linux_banner);
- early_security_init();
- setup_arch(&command_line);
-+ mangle_bootargs(command_line);
- setup_boot_config();
- setup_command_line(command_line);
- setup_nr_cpu_ids();
diff --git a/target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch b/target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch
deleted file mode 100644
index 6a0a19987f..0000000000
--- a/target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From a7a94ca21ac0f347f683d33c72b4aab57ce5eec3 Mon Sep 17 00:00:00 2001
-From: Florian Eckert <fe@dev.tdt.de>
-Date: Mon, 20 Nov 2023 11:13:20 +0100
-Subject: [PATCH] tools/thermal/tmon: Fix compilation warning for wrong format
-
-The following warnings are shown during compilation:
-
-tui.c: In function 'show_cooling_device':
- tui.c:216:40: warning: format '%d' expects argument of type 'int', but
-argument 7 has type 'long unsigned int' [-Wformat=]
- 216 | "%02d %12.12s%6d %6d",
- | ~~^
- | |
- | int
- | %6ld
- ......
- 219 | ptdata.cdi[j].cur_state,
- | ~~~~~~~~~~~~~~~~~~~~~~~
- | |
- | long unsigned int
- tui.c:216:44: warning: format '%d' expects argument of type 'int', but
-argument 8 has type 'long unsigned int' [-Wformat=]
- 216 | "%02d %12.12s%6d %6d",
- | ~~^
- | |
- | int
- | %6ld
- ......
- 220 | ptdata.cdi[j].max_state);
- | ~~~~~~~~~~~~~~~~~~~~~~~
- | |
- | long unsigned int
-
-To fix this, the correct string format must be used for printing.
-
-Signed-off-by: Florian Eckert <fe@dev.tdt.de>
----
- tools/thermal/tmon/tui.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/tools/thermal/tmon/tui.c
-+++ b/tools/thermal/tmon/tui.c
-@@ -213,7 +213,7 @@ void show_cooling_device(void)
- * cooling device instances. skip unused idr.
- */
- mvwprintw(cooling_device_window, j + 2, 1,
-- "%02d %12.12s%6d %6d",
-+ "%02d %12.12s%6lu %6lu",
- ptdata.cdi[j].instance,
- ptdata.cdi[j].type,
- ptdata.cdi[j].cur_state,
diff --git a/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch b/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch
deleted file mode 100644
index 7b342e6962..0000000000
--- a/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 22 Oct 2020 22:00:03 +0200
-Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code
-
-This header file is not in uapi, which makes any user space code that includes
-linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory'
-
-Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/compiler.h
-+++ b/include/linux/compiler.h
-@@ -203,6 +203,8 @@ void ftrace_likely_update(struct ftrace_
- __v; \
- })
-
-+#include <asm/rwonce.h>
-+
- #endif /* __KERNEL__ */
-
- /*
-@@ -243,6 +245,4 @@ static inline void *offset_to_ptr(const
- */
- #define prevent_tail_call_optimization() mb()
-
--#include <asm/rwonce.h>
--
- #endif /* __LINUX_COMPILER_H */
diff --git a/target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch
deleted file mode 100644
index d79d03defb..0000000000
--- a/target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 18 Apr 2018 10:50:05 +0200
-Subject: [PATCH] MIPS: only process negative stack offsets on stack traces
-
-Fixes endless back traces in cases where the compiler emits a stack
-pointer increase in a branch delay slot (probably for some form of
-function return).
-
-[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low!
-[ 3.480070] turning off the locking correctness validator.
-[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0
-[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000
-[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f
-[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000
-[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000
-[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000
-[ 3.532942] ...
-[ 3.535362] Call Trace:
-[ 3.537818] [<80010a48>] show_stack+0x58/0x100
-[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170
-[ 3.546613] [<80079f90>] save_trace+0xf0/0x110
-[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c
-[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08
-[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c
-[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78
-[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac
-[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0
-[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/mips/kernel/process.c
-+++ b/arch/mips/kernel/process.c
-@@ -395,6 +395,8 @@ static inline int is_sp_move_ins(union m
-
- if (ip->i_format.opcode == addiu_op ||
- ip->i_format.opcode == daddiu_op) {
-+ if (ip->i_format.simmediate > 0)
-+ return 0;
- *frame_size = -ip->i_format.simmediate;
- return 1;
- }
diff --git a/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch b/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch
deleted file mode 100644
index c8c0efaecf..0000000000
--- a/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 9 Jul 2017 00:26:53 +0200
-Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/Makefile
-+++ b/Makefile
-@@ -605,7 +605,7 @@ endif
- # Allows the usage of unstable features in stable compilers.
- export RUSTC_BOOTSTRAP := 1
-
--export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
-+export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
- export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO
- export HOSTRUSTC KBUILD_HOSTRUSTFLAGS
- export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
diff --git a/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch b/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch
deleted file mode 100644
index d6b10491f8..0000000000
--- a/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From bd1b9f66d5134e518419f4c4dacf1884c1616983 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Thu, 28 Apr 2022 11:13:23 +0200
-Subject: [PATCH] watchdog: max63xx_wdt: Add support for specifying WDI logic
- via GPIO
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-On some boards is WDI logic of max6370 chip connected via GPIO.
-So extend max63xx_wdt driver to allow specifying WDI logic via GPIO.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
----
- drivers/watchdog/max63xx_wdt.c | 24 ++++++++++++++++++++++++
- 1 file changed, 24 insertions(+)
-
---- a/drivers/watchdog/max63xx_wdt.c
-+++ b/drivers/watchdog/max63xx_wdt.c
-@@ -27,6 +27,7 @@
- #include <linux/io.h>
- #include <linux/slab.h>
- #include <linux/property.h>
-+#include <linux/gpio/consumer.h>
-
- #define DEFAULT_HEARTBEAT 60
- #define MAX_HEARTBEAT 60
-@@ -53,6 +54,9 @@ struct max63xx_wdt {
- void __iomem *base;
- spinlock_t lock;
-
-+ /* GPIOs */
-+ struct gpio_desc *gpio_wdi;
-+
- /* WDI and WSET bits write access routines */
- void (*ping)(struct max63xx_wdt *wdt);
- void (*set)(struct max63xx_wdt *wdt, u8 set);
-@@ -158,6 +162,17 @@ static const struct watchdog_info max63x
- .identity = "max63xx Watchdog",
- };
-
-+static void max63xx_gpio_ping(struct max63xx_wdt *wdt)
-+{
-+ spin_lock(&wdt->lock);
-+
-+ gpiod_set_value(wdt->gpio_wdi, 1);
-+ udelay(1);
-+ gpiod_set_value(wdt->gpio_wdi, 0);
-+
-+ spin_unlock(&wdt->lock);
-+}
-+
- static void max63xx_mmap_ping(struct max63xx_wdt *wdt)
- {
- u8 val;
-@@ -225,10 +240,19 @@ static int max63xx_wdt_probe(struct plat
- return -EINVAL;
- }
-
-+ wdt->gpio_wdi = devm_gpiod_get(dev, NULL, GPIOD_FLAGS_BIT_DIR_OUT);
-+ if (IS_ERR(wdt->gpio_wdi) && PTR_ERR(wdt->gpio_wdi) != -ENOENT)
-+ return dev_err_probe(dev, PTR_ERR(wdt->gpio_wdi),
-+ "unable to request gpio: %ld\n",
-+ PTR_ERR(wdt->gpio_wdi));
-+
- err = max63xx_mmap_init(pdev, wdt);
- if (err)
- return err;
-
-+ if (!IS_ERR(wdt->gpio_wdi))
-+ wdt->ping = max63xx_gpio_ping;
-+
- platform_set_drvdata(pdev, &wdt->wdd);
- watchdog_set_drvdata(&wdt->wdd, wdt);
-
diff --git a/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
deleted file mode 100644
index a3d66c54b3..0000000000
--- a/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From: Tobias Wolf <dev-NTEO@vplace.de>
-Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation
-
-An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any
-kernel beyond version 4.3 resulting in:
-
-BUG: Bad page state in process swapper pfn:086ac
-
-bisect resulted in:
-
-a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit
-commit a1c34a3bf00af2cede839879502e12dc68491ad5
-Author: Laura Abbott <laura@labbott.name>
-Date: Thu Nov 5 18:48:46 2015 -0800
-
- mm: Don't offset memmap for flatmem
-
- Srinivas Kandagatla reported bad page messages when trying to remove the
- bottom 2MB on an ARM based IFC6410 board
-
- BUG: Bad page state in process swapper pfn:fffa8
- page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0
- flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked)
- page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set
- bad because of flags:
- flags: 0x200041(locked|active|mlocked)
- Modules linked in:
- CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty
-#816
- Hardware name: Qualcomm (Flattened Device Tree)
- unwind_backtrace
- show_stack
- dump_stack
- bad_page
- free_pages_prepare
- free_hot_cold_page
- __free_pages
- free_highmem_page
- mem_init
- start_kernel
- Disabling lock debugging due to kernel taint
- [...]
-:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4
-0a8156f848733dfa21e16c196dfb6c0a76290709 M mm
-
-This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by
-page_to_pfn anymore.
-
-The following output was generated with two hacked in printk statements:
-
-printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map -
-(pgdat->node_start_pfn - ARCH_PFN_OFFSET));
- if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
- mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
-printk("after %p\n", mem_map);
-
-Output:
-
-[ 0.000000] before 8861b280 vs. 8861b280 or 8851b280
-[ 0.000000] after 8851b280
-
-As seen in the first line mem_map with subtraction of offset does not equal the
-mem_map after subtraction of ARCH_PFN_OFFSET.
-
-After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the
-previously calculated offset is zero for the named platform it is able to boot
-4.4 and 4.9-rc7 again.
-
-Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
----
-
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -7899,7 +7899,7 @@ static void __init alloc_node_mem_map(st
- if (pgdat == NODE_DATA(0)) {
- mem_map = NODE_DATA(0)->node_mem_map;
- if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
-- mem_map -= offset;
-+ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
- }
- #endif
- }
diff --git a/target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch
deleted file mode 100644
index 8f40ae3ba2..0000000000
--- a/target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support
-
-It is required for renames on overlayfs
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/fs/jffs2/dir.c
-+++ b/fs/jffs2/dir.c
-@@ -614,8 +614,8 @@ static int jffs2_rmdir (struct inode *di
- return ret;
- }
-
--static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i,
-- struct dentry *dentry, umode_t mode, dev_t rdev)
-+static int __jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i,
-+ struct dentry *dentry, umode_t mode, dev_t rdev, bool whiteout)
- {
- struct jffs2_inode_info *f, *dir_f;
- struct jffs2_sb_info *c;
-@@ -754,7 +754,11 @@ static int jffs2_mknod (struct user_name
- mutex_unlock(&dir_f->sem);
- jffs2_complete_reservation(c);
-
-- d_instantiate_new(dentry, inode);
-+ if (!whiteout)
-+ d_instantiate_new(dentry, inode);
-+ else
-+ unlock_new_inode(inode);
-+
- return 0;
-
- fail:
-@@ -762,6 +766,19 @@ static int jffs2_mknod (struct user_name
- return ret;
- }
-
-+static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i,
-+ struct dentry *dentry, umode_t mode, dev_t rdev)
-+{
-+ return __jffs2_mknod(mnt_userns, dir_i, dentry, mode, rdev, false);
-+}
-+
-+static int jffs2_whiteout (struct user_namespace *mnt_userns, struct inode *old_dir,
-+ struct dentry *old_dentry)
-+{
-+ return __jffs2_mknod(mnt_userns, old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE,
-+ WHITEOUT_DEV, true);
-+}
-+
- static int jffs2_rename (struct user_namespace *mnt_userns,
- struct inode *old_dir_i, struct dentry *old_dentry,
- struct inode *new_dir_i, struct dentry *new_dentry,
-@@ -773,7 +790,7 @@ static int jffs2_rename (struct user_nam
- uint8_t type;
- uint32_t now;
-
-- if (flags & ~RENAME_NOREPLACE)
-+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
- return -EINVAL;
-
- /* The VFS will check for us and prevent trying to rename a
-@@ -839,9 +856,14 @@ static int jffs2_rename (struct user_nam
- if (d_is_dir(old_dentry) && !victim_f)
- inc_nlink(new_dir_i);
-
-- /* Unlink the original */
-- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
-+ if (flags & RENAME_WHITEOUT)
-+ /* Replace with whiteout */
-+ ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry);
-+ else
-+ /* Unlink the original */
-+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-+ old_dentry->d_name.name,
-+ old_dentry->d_name.len, NULL, now);
-
- /* We don't touch inode->i_nlink */
-
diff --git a/target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch
deleted file mode 100644
index f58fc791d2..0000000000
--- a/target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: jffs2: add RENAME_EXCHANGE support
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/fs/jffs2/dir.c
-+++ b/fs/jffs2/dir.c
-@@ -787,18 +787,31 @@ static int jffs2_rename (struct user_nam
- int ret;
- struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
- struct jffs2_inode_info *victim_f = NULL;
-+ struct inode *fst_inode = d_inode(old_dentry);
-+ struct inode *snd_inode = d_inode(new_dentry);
- uint8_t type;
- uint32_t now;
-
-- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
-+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE))
- return -EINVAL;
-
-+ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) {
-+ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) {
-+ inc_nlink(new_dir_i);
-+ drop_nlink(old_dir_i);
-+ }
-+ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) {
-+ drop_nlink(new_dir_i);
-+ inc_nlink(old_dir_i);
-+ }
-+ }
-+
- /* The VFS will check for us and prevent trying to rename a
- * file over a directory and vice versa, but if it's a directory,
- * the VFS can't check whether the victim is empty. The filesystem
- * needs to do that for itself.
- */
-- if (d_really_is_positive(new_dentry)) {
-+ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) {
- victim_f = JFFS2_INODE_INFO(d_inode(new_dentry));
- if (d_is_dir(new_dentry)) {
- struct jffs2_full_dirent *fd;
-@@ -833,7 +846,7 @@ static int jffs2_rename (struct user_nam
- if (ret)
- return ret;
-
-- if (victim_f) {
-+ if (victim_f && !(flags & RENAME_EXCHANGE)) {
- /* There was a victim. Kill it off nicely */
- if (d_is_dir(new_dentry))
- clear_nlink(d_inode(new_dentry));
-@@ -859,6 +872,12 @@ static int jffs2_rename (struct user_nam
- if (flags & RENAME_WHITEOUT)
- /* Replace with whiteout */
- ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry);
-+ else if (flags & RENAME_EXCHANGE)
-+ /* Replace the original */
-+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i),
-+ d_inode(new_dentry)->i_ino, type,
-+ old_dentry->d_name.name, old_dentry->d_name.len,
-+ now);
- else
- /* Unlink the original */
- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-@@ -890,7 +909,7 @@ static int jffs2_rename (struct user_nam
- return ret;
- }
-
-- if (d_is_dir(old_dentry))
-+ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE))
- drop_nlink(old_dir_i);
-
- new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
diff --git a/target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch b/target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch
deleted file mode 100644
index de847a1f5c..0000000000
--- a/target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: jffs2: add splice ops
-
-Add splice_read using generic_file_splice_read.
-Add splice_write using iter_file_splice_write
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/fs/jffs2/file.c
-+++ b/fs/jffs2/file.c
-@@ -53,6 +53,8 @@ const struct file_operations jffs2_file_
- .open = generic_file_open,
- .read_iter = generic_file_read_iter,
- .write_iter = generic_file_write_iter,
-+ .splice_read = generic_file_splice_read,
-+ .splice_write = iter_file_splice_write,
- .unlocked_ioctl=jffs2_ioctl,
- .mmap = generic_file_readonly_mmap,
- .fsync = jffs2_fsync,
diff --git a/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch
deleted file mode 100644
index ac4a3138a5..0000000000
--- a/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Stephen Hemminger <stephen@networkplumber.org>
-Subject: bridge: allow receiption on disabled port
-
-When an ethernet device is enslaved to a bridge, and the bridge STP
-detects loss of carrier (or operational state down), then normally
-packet receiption is blocked.
-
-This breaks control applications like WPA which maybe expecting to
-receive packets to negotiate to bring link up. The bridge needs to
-block forwarding packets from these disabled ports, but there is no
-hard requirement to not allow local packet delivery.
-
-Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -227,6 +227,9 @@ static void __br_handle_local_finish(str
- /* note: already called with rcu_read_lock */
- static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
- {
-+ struct net_bridge_port *p = br_port_get_rcu(skb->dev);
-+
-+ if (p->state != BR_STATE_DISABLED)
- __br_handle_local_finish(skb);
-
- /* return 1 to signal the okfn() was called so it's ok to use the skb */
-@@ -397,6 +400,17 @@ forward:
- goto defer_stp_filtering;
-
- switch (p->state) {
-+ case BR_STATE_DISABLED:
-+ if (ether_addr_equal(p->br->dev->dev_addr, dest))
-+ skb->pkt_type = PACKET_HOST;
-+
-+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING,
-+ dev_net(skb->dev), NULL, skb, skb->dev, NULL,
-+ br_handle_local_finish) == 1) {
-+ return RX_HANDLER_PASS;
-+ }
-+ break;
-+
- case BR_STATE_FORWARDING:
- case BR_STATE_LEARNING:
- defer_stp_filtering:
diff --git a/target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch b/target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch
deleted file mode 100644
index f420d210c2..0000000000
--- a/target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 4 Jan 2024 15:21:21 +0100
-Subject: [PATCH] net: bridge: do not send arp replies if src and target hw
- addr is the same
-
-There are broken devices in the wild that handle duplicate IP address
-detection by sending out ARP requests for the IP that they received from a
-DHCP server and refuse the address if they get a reply.
-When proxyarp is enabled, they would go into a loop of requesting an address
-and then NAKing it again.
-
-Link: https://github.com/openwrt/openwrt/issues/14309
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/bridge/br_arp_nd_proxy.c
-+++ b/net/bridge/br_arp_nd_proxy.c
-@@ -204,7 +204,10 @@ void br_do_proxy_suppress_arp(struct sk_
- if ((p && (p->flags & BR_PROXYARP)) ||
- (f->dst && (f->dst->flags & (BR_PROXYARP_WIFI |
- BR_NEIGH_SUPPRESS)))) {
-- if (!vid)
-+ replied = true;
-+ if (!memcmp(n->ha, sha, dev->addr_len))
-+ replied = false;
-+ else if (!vid)
- br_arp_send(br, p, skb->dev, sip, tip,
- sha, n->ha, sha, 0, 0);
- else
-@@ -212,7 +215,6 @@ void br_do_proxy_suppress_arp(struct sk_
- sha, n->ha, sha,
- skb->vlan_proto,
- skb_vlan_tag_get(skb));
-- replied = true;
- }
-
- /* If we have replied or as long as we know the
diff --git a/target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch b/target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch
deleted file mode 100644
index 2f5c2228c7..0000000000
--- a/target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From: Daniel González Cabanelas <dgcbueu@gmail.com>
-Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week
-
-The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week
-alarms.
-
-Read the "wday" alarm register and convert it to a date to support up 1
-week in our driver.
-
-Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
----
- drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++-----
- 1 file changed, 42 insertions(+), 6 deletions(-)
-
---- a/drivers/rtc/rtc-rs5c372.c
-+++ b/drivers/rtc/rtc-rs5c372.c
-@@ -399,7 +399,9 @@ static int rs5c_read_alarm(struct device
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct rs5c372 *rs5c = i2c_get_clientdata(client);
-- int status;
-+ int status, wday_offs;
-+ struct rtc_time rtc;
-+ unsigned long alarm_secs;
-
- status = rs5c_get_regs(rs5c);
- if (status < 0)
-@@ -409,6 +411,30 @@ static int rs5c_read_alarm(struct device
- t->time.tm_sec = 0;
- t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
- t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]);
-+ t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1;
-+
-+ /* determine the day, month and year based on alarm wday, taking as a
-+ * reference the current time from the rtc
-+ */
-+ status = rs5c372_rtc_read_time(dev, &rtc);
-+ if (status < 0)
-+ return status;
-+
-+ wday_offs = t->time.tm_wday - rtc.tm_wday;
-+ alarm_secs = mktime64(rtc.tm_year + 1900,
-+ rtc.tm_mon + 1,
-+ rtc.tm_mday + wday_offs,
-+ t->time.tm_hour,
-+ t->time.tm_min,
-+ t->time.tm_sec);
-+
-+ if (wday_offs < 0 || (wday_offs == 0 &&
-+ (t->time.tm_hour < rtc.tm_hour ||
-+ (t->time.tm_hour == rtc.tm_hour &&
-+ t->time.tm_min <= rtc.tm_min))))
-+ alarm_secs += 7 * 86400;
-+
-+ rtc_time64_to_tm(alarm_secs, &t->time);
-
- /* ... and status */
- t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE);
-@@ -423,12 +449,20 @@ static int rs5c_set_alarm(struct device
- struct rs5c372 *rs5c = i2c_get_clientdata(client);
- int status, addr, i;
- unsigned char buf[3];
-+ struct rtc_time rtc_tm;
-+ unsigned long rtc_secs, alarm_secs;
-
-- /* only handle up to 24 hours in the future, like RTC_ALM_SET */
-- if (t->time.tm_mday != -1
-- || t->time.tm_mon != -1
-- || t->time.tm_year != -1)
-+ /* chip only can handle alarms up to one week in the future*/
-+ status = rs5c372_rtc_read_time(dev, &rtc_tm);
-+ if (status)
-+ return status;
-+ rtc_secs = rtc_tm_to_time64(&rtc_tm);
-+ alarm_secs = rtc_tm_to_time64(&t->time);
-+ if (alarm_secs >= rtc_secs + 7 * 86400) {
-+ dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n",
-+ __func__, status);
- return -EINVAL;
-+ }
-
- /* REVISIT: round up tm_sec */
-
-@@ -449,7 +483,9 @@ static int rs5c_set_alarm(struct device
- /* set alarm */
- buf[0] = bin2bcd(t->time.tm_min);
- buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
-- buf[2] = 0x7f; /* any/all days */
-+ /* each bit is the day of the week, 0x7f means all days */
-+ buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ?
-+ BIT(t->time.tm_wday) : 0x7f;
-
- for (i = 0; i < sizeof(buf); i++) {
- addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
diff --git a/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch b/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch
deleted file mode 100644
index a9a5cdf8ba..0000000000
--- a/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Daniel González Cabanelas <dgcbueu@gmail.com>
-Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source
-
-Currently there is no use for the interrupts on the rs5c372 RTC and the
-wakealarm isn't enabled. There are some devices like NASes which use this
-RTC to wake up from the power off state when the INTR pin is activated by
-the alarm clock.
-
-Enable the alarm and let to be used as a wakeup source.
-
-Tested on a Buffalo LS421DE NAS.
-
-Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
----
- drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/drivers/rtc/rtc-rs5c372.c
-+++ b/drivers/rtc/rtc-rs5c372.c
-@@ -833,6 +833,7 @@ static int rs5c372_probe(struct i2c_clie
- int err = 0;
- int smbus_mode = 0;
- struct rs5c372 *rs5c372;
-+ bool rs5c372_can_wakeup_device = false;
-
- dev_dbg(&client->dev, "%s\n", __func__);
-
-@@ -868,6 +869,12 @@ static int rs5c372_probe(struct i2c_clie
- else
- rs5c372->type = id->driver_data;
-
-+#ifdef CONFIG_OF
-+ if(of_property_read_bool(client->dev.of_node,
-+ "wakeup-source"))
-+ rs5c372_can_wakeup_device = true;
-+#endif
-+
- /* we read registers 0x0f then 0x00-0x0f; skip the first one */
- rs5c372->regs = &rs5c372->buf[1];
- rs5c372->smbus = smbus_mode;
-@@ -901,6 +908,8 @@ static int rs5c372_probe(struct i2c_clie
- goto exit;
- }
-
-+ rs5c372->has_irq = 1;
-+
- /* if the oscillator lost power and no other software (like
- * the bootloader) set it up, do it here.
- *
-@@ -927,6 +936,10 @@ static int rs5c372_probe(struct i2c_clie
- );
-
- /* REVISIT use client->irq to register alarm irq ... */
-+ if (rs5c372_can_wakeup_device) {
-+ device_init_wakeup(&client->dev, true);
-+ }
-+
- rs5c372->rtc = devm_rtc_device_register(&client->dev,
- rs5c372_driver.driver.name,
- &rs5c372_rtc_ops, THIS_MODULE);
-@@ -940,6 +953,10 @@ static int rs5c372_probe(struct i2c_clie
- if (err)
- goto exit;
-
-+ /* the rs5c372 alarm only supports a minute accuracy */
-+ set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rs5c372->rtc->features);
-+ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rs5c372->rtc->features);
-+
- return 0;
-
- exit:
diff --git a/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch
deleted file mode 100644
index 78ed262b78..0000000000
--- a/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx
-
-[john@phrozen.org: added to my upstream queue 30.12.2016]
-lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- init/Kconfig | 11 +++++++++++
- kernel/kallsyms.c | 8 ++++++++
- scripts/kallsyms.c | 12 ++++++++++++
- scripts/link-vmlinux.sh | 4 ++++
- 4 files changed, 35 insertions(+)
-
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1491,6 +1491,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW
- the unaligned access emulation.
- see arch/parisc/kernel/unaligned.c for reference
-
-+config KALLSYMS_UNCOMPRESSED
-+ bool "Keep kallsyms uncompressed"
-+ depends on KALLSYMS
-+ help
-+ Normally kallsyms contains compressed symbols (using a token table),
-+ reducing the uncompressed kernel image size. Keeping the symbol table
-+ uncompressed significantly improves the size of this part in compressed
-+ kernel images.
-+
-+ Say N unless you need compressed kernel images to be small.
-+
- config HAVE_PCSPKR_PLATFORM
- bool
-
---- a/kernel/kallsyms.c
-+++ b/kernel/kallsyms.c
-@@ -69,6 +69,11 @@ static unsigned int kallsyms_expand_symb
- * For every byte on the compressed symbol data, copy the table
- * entry for that byte.
- */
-+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
-+ memcpy(result, data + 1, len - 1);
-+ result += len - 1;
-+ len = 0;
-+#endif
- while (len) {
- tptr = &kallsyms_token_table[kallsyms_token_index[*data]];
- data++;
-@@ -101,6 +106,9 @@ tail:
- */
- static char kallsyms_get_symbol_type(unsigned int off)
- {
-+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
-+ return kallsyms_names[off + 1];
-+#endif
- /*
- * Get just the first code, look it up in the token table,
- * and return the first char from this token.
---- a/scripts/kallsyms.c
-+++ b/scripts/kallsyms.c
-@@ -77,6 +77,7 @@ static struct addr_range percpu_range =
- static struct sym_entry **table;
- static unsigned int table_size, table_cnt;
- static int all_symbols;
-+static int uncompressed;
- static int absolute_percpu;
- static int base_relative;
- static int lto_clang;
-@@ -608,6 +609,9 @@ static void write_src(void)
- (unsigned char)(table[i]->seq >> 0));
- printf("\n");
-
-+ if (uncompressed)
-+ return;
-+
- output_label("kallsyms_token_table");
- off = 0;
- for (i = 0; i < 256; i++) {
-@@ -659,6 +663,9 @@ static unsigned char *find_token(unsigne
- {
- int i;
-
-+ if (uncompressed)
-+ return NULL;
-+
- for (i = 0; i < len - 1; i++) {
- if (str[i] == token[0] && str[i+1] == token[1])
- return &str[i];
-@@ -731,6 +738,9 @@ static void optimize_result(void)
- {
- int i, best;
-
-+ if (uncompressed)
-+ return;
-+
- /* using the '\0' symbol last allows compress_symbols to use standard
- * fast string functions */
- for (i = 255; i >= 0; i--) {
-@@ -892,6 +902,7 @@ int main(int argc, char **argv)
- {"absolute-percpu", no_argument, &absolute_percpu, 1},
- {"base-relative", no_argument, &base_relative, 1},
- {"lto-clang", no_argument, &lto_clang, 1},
-+ {"uncompressed", no_argument, &uncompressed, 1},
- {},
- };
-
---- a/scripts/link-vmlinux.sh
-+++ b/scripts/link-vmlinux.sh
-@@ -165,6 +165,10 @@ kallsyms()
- kallsymopt="${kallsymopt} --lto-clang"
- fi
-
-+ if is_enabled CONFIG_KALLSYMS_UNCOMPRESSED; then
-+ kallsymopt="${kallsymopt} --uncompressed"
-+ fi
-+
- info KSYMS ${2}
- scripts/kallsyms ${kallsymopt} ${1} > ${2}
- }
diff --git a/target/linux/generic/pending-6.1/205-backtrace_module_info.patch b/target/linux/generic/pending-6.1/205-backtrace_module_info.patch
deleted file mode 100644
index 27a1347981..0000000000
--- a/target/linux/generic/pending-6.1/205-backtrace_module_info.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries
-
-[john@phrozen.org: felix will add this to his upstream queue]
-
-lede-commit 53827cdc824556cda910b23ce5030c363b8f1461
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- lib/vsprintf.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
-
---- a/lib/vsprintf.c
-+++ b/lib/vsprintf.c
-@@ -985,8 +985,10 @@ char *symbol_string(char *buf, char *end
- struct printf_spec spec, const char *fmt)
- {
- unsigned long value;
--#ifdef CONFIG_KALLSYMS
- char sym[KSYM_SYMBOL_LEN];
-+#ifndef CONFIG_KALLSYMS
-+ struct module *mod;
-+ int len;
- #endif
-
- if (fmt[1] == 'R')
-@@ -1007,8 +1009,14 @@ char *symbol_string(char *buf, char *end
-
- return string_nocheck(buf, end, sym, spec);
- #else
-- return special_hex_number(buf, end, value, sizeof(void *));
-+ len = snprintf(sym, sizeof(sym), "0x%lx", value);
-+ mod = __module_address(value);
-+ if (mod)
-+ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]",
-+ mod->name, mod->core_layout.base,
-+ mod->core_layout.size);
- #endif
-+ return string(buf, end, sym, spec);
- }
-
- static const struct printf_spec default_str_spec = {
diff --git a/target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch
deleted file mode 100644
index 9e78284ecf..0000000000
--- a/target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: usr: sanitize deps_initramfs list
-
-If any filename in the intramfs dependency
-list contains a colon, that causes a kernel
-build error like this:
-
-/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop.
-make[5]: *** [usr] Error 2
-
-Fix it by removing such filenames from the
-deps_initramfs list.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- usr/Makefile | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/usr/Makefile
-+++ b/usr/Makefile
-@@ -56,6 +56,8 @@ hostprogs := gen_init_cpio
- # The dependency list is generated by gen_initramfs.sh -l
- -include $(obj)/.initramfs_data.cpio.d
-
-+deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v)))
-+
- # do not try to update files included in initramfs
- $(deps_initramfs): ;
-
diff --git a/target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch
deleted file mode 100644
index cd31f9d934..0000000000
--- a/target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Imre Kaloz <kaloz@openwrt.org>
-Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with
- compat-wireless, too
-
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- drivers/net/wireless/ti/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ti/Kconfig
-+++ b/drivers/net/wireless/ti/Kconfig
-@@ -20,7 +20,7 @@ source "drivers/net/wireless/ti/wlcore/K
-
- config WILINK_PLATFORM_DATA
- bool "TI WiLink platform data"
-- depends on WLCORE_SDIO || WL1251_SDIO
-+ depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS
- default y
- help
- Small platform data bit needed to pass data to the sdio modules.
diff --git a/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch
deleted file mode 100644
index 997e6142a7..0000000000
--- a/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
-Date: Sat, 28 Mar 2020 12:11:50 +0100
-Subject: [PATCH] generic: platform/mikrotik build bits (5.4)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch adds platform/mikrotik kernel build bits
-
-Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
----
- drivers/platform/Kconfig | 2 ++
- drivers/platform/Makefile | 1 +
- 2 files changed, 3 insertions(+)
-
---- a/drivers/platform/Kconfig
-+++ b/drivers/platform/Kconfig
-@@ -16,3 +16,5 @@ source "drivers/platform/olpc/Kconfig"
- source "drivers/platform/surface/Kconfig"
-
- source "drivers/platform/x86/Kconfig"
-+
-+source "drivers/platform/mikrotik/Kconfig"
---- a/drivers/platform/Makefile
-+++ b/drivers/platform/Makefile
-@@ -11,3 +11,4 @@ obj-$(CONFIG_OLPC_EC) += olpc/
- obj-$(CONFIG_GOLDFISH) += goldfish/
- obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
- obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
-+obj-$(CONFIG_MIKROTIK) += mikrotik/
diff --git a/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch
deleted file mode 100644
index d222ec060e..0000000000
--- a/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Mark Miller <mark@mirell.org>
-Subject: mips: expose CONFIG_BOOT_RAW
-
-This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on
-certain Broadcom chipsets running CFE in order to load the kernel.
-
-Signed-off-by: Mark Miller <mark@mirell.org>
-Acked-by: Rob Landley <rob@landley.net>
----
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -1035,9 +1035,6 @@ config FW_ARC
- config ARCH_MAY_HAVE_PC_FDC
- bool
-
--config BOOT_RAW
-- bool
--
- config CEVT_BCM1480
- bool
-
-@@ -3093,6 +3090,18 @@ choice
- bool "Extend builtin kernel arguments with bootloader arguments"
- endchoice
-
-+config BOOT_RAW
-+ bool "Enable the kernel to be executed from the load address"
-+ default n
-+ help
-+ Allow the kernel to be executed from the load address for
-+ bootloaders which cannot read the ELF format. This places
-+ a jump to start_kernel at the load address.
-+
-+ If unsure, say N.
-+
-+
-+
- endmenu
-
- config LOCKDEP_SUPPORT
diff --git a/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch b/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
deleted file mode 100644
index bd56adad3a..0000000000
--- a/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001
-From: Paul Burton <paul.burton@imgtec.com>
-Date: Mon, 22 Feb 2016 18:09:44 +0000
-Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes
-
-Index-based cache operations may be arbitrarily reordered by out of
-order CPUs. Thus code which writes back the dcache & then invalidates
-the icache using indexed cache ops must include a barrier between
-operating on the 2 caches in order to prevent the scenario in which:
-
- - icache invalidation occurs.
-
- - icache fetch occurs, due to speculation.
-
- - dcache writeback occurs.
-
-If the above were allowed to happen then the icache would contain stale
-data. Forcing the dcache writeback to complete before the icache
-invalidation avoids this.
-
-Signed-off-by: Paul Burton <paul.burton@imgtec.com>
-Cc: James Hogan <james.hogan@imgtec.com>
----
- arch/mips/mm/c-r4k.c | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
---- a/arch/mips/mm/c-r4k.c
-+++ b/arch/mips/mm/c-r4k.c
-@@ -514,6 +514,7 @@ static inline void local_r4k___flush_cac
-
- default:
- r4k_blast_dcache();
-+ mb(); /* cache instructions may be reordered */
- r4k_blast_icache();
- break;
- }
-@@ -594,8 +595,10 @@ static inline void local_r4k_flush_cache
- if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
- r4k_blast_dcache();
- /* If executable, blast stale lines from icache */
-- if (exec)
-+ if (exec) {
-+ mb(); /* cache instructions may be reordered */
- r4k_blast_icache();
-+ }
- }
-
- static void r4k_flush_cache_range(struct vm_area_struct *vma,
-@@ -696,8 +699,13 @@ static inline void local_r4k_flush_cache
- if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
- vaddr ? r4k_blast_dcache_page(addr) :
- r4k_blast_dcache_user_page(addr);
-- if (exec && !cpu_icache_snoops_remote_store)
-+ if (exec)
-+ mb(); /* cache instructions may be reordered */
-+
-+ if (exec && !cpu_icache_snoops_remote_store) {
- r4k_blast_scache_page(addr);
-+ mb(); /* cache instructions may be reordered */
-+ }
- }
- if (exec) {
- if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
-@@ -764,6 +772,7 @@ static inline void __local_r4k_flush_ica
- else
- blast_dcache_range(start, end);
- }
-+ mb(); /* cache instructions may be reordered */
- }
-
- if (type == R4K_INDEX ||
diff --git a/target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch b/target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch
deleted file mode 100644
index 542fba651f..0000000000
--- a/target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: mips: use -mno-branch-likely for kernel and userspace
-
-saves ~11k kernel size after lzma and ~12k squashfs size in the
-
-lede-commit: 41a039f46450ffae9483d6216422098669da2900
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/mips/Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -94,7 +94,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
- # machines may also. Since BFD is incredibly buggy with respect to
- # crossformat linking we rely on the elf2ecoff tool for format conversion.
- #
--cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
-+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
- cflags-y += -msoft-float
- LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
- KBUILD_AFLAGS_MODULE += -mlong-calls
diff --git a/target/linux/generic/pending-6.1/305-mips_module_reloc.patch b/target/linux/generic/pending-6.1/305-mips_module_reloc.patch
deleted file mode 100644
index 5de9019677..0000000000
--- a/target/linux/generic/pending-6.1/305-mips_module_reloc.patch
+++ /dev/null
@@ -1,370 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to
-
-lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/mips/Makefile | 5 +
- arch/mips/include/asm/module.h | 5 +
- arch/mips/kernel/module.c | 279 ++++++++++++++++++++++++++++++++++++++++-
- 3 files changed, 284 insertions(+), 5 deletions(-)
-
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -97,8 +97,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
- cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
- cflags-y += -msoft-float
- LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
-+ifdef CONFIG_64BIT
- KBUILD_AFLAGS_MODULE += -mlong-calls
- KBUILD_CFLAGS_MODULE += -mlong-calls
-+else
-+ ifdef CONFIG_DYNAMIC_FTRACE
-+ KBUILD_AFLAGS_MODULE += -mlong-calls
-+ KBUILD_CFLAGS_MODULE += -mlong-calls
-+ else
-+ KBUILD_AFLAGS_MODULE += -mno-long-calls
-+ KBUILD_CFLAGS_MODULE += -mno-long-calls
-+ endif
-+endif
-
- ifeq ($(CONFIG_RELOCATABLE),y)
- LDFLAGS_vmlinux += --emit-relocs
---- a/arch/mips/include/asm/module.h
-+++ b/arch/mips/include/asm/module.h
-@@ -12,6 +12,11 @@ struct mod_arch_specific {
- const struct exception_table_entry *dbe_start;
- const struct exception_table_entry *dbe_end;
- struct mips_hi16 *r_mips_hi16_list;
-+
-+ void *phys_plt_tbl;
-+ void *virt_plt_tbl;
-+ unsigned int phys_plt_offset;
-+ unsigned int virt_plt_offset;
- };
-
- typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
---- a/arch/mips/kernel/module.c
-+++ b/arch/mips/kernel/module.c
-@@ -32,23 +32,261 @@ struct mips_hi16 {
- static LIST_HEAD(dbe_list);
- static DEFINE_SPINLOCK(dbe_lock);
-
--#ifdef MODULE_START
-+/*
-+ * Get the potential max trampolines size required of the init and
-+ * non-init sections. Only used if we cannot find enough contiguous
-+ * physically mapped memory to put the module into.
-+ */
-+static unsigned int
-+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
-+ const char *secstrings, unsigned int symindex, bool is_init)
-+{
-+ unsigned long ret = 0;
-+ unsigned int i, j;
-+ Elf_Sym *syms;
-+
-+ /* Everything marked ALLOC (this includes the exported symbols) */
-+ for (i = 1; i < hdr->e_shnum; ++i) {
-+ unsigned int info = sechdrs[i].sh_info;
-+
-+ if (sechdrs[i].sh_type != SHT_REL
-+ && sechdrs[i].sh_type != SHT_RELA)
-+ continue;
-+
-+ /* Not a valid relocation section? */
-+ if (info >= hdr->e_shnum)
-+ continue;
-+
-+ /* Don't bother with non-allocated sections */
-+ if (!(sechdrs[info].sh_flags & SHF_ALLOC))
-+ continue;
-+
-+ /* If it's called *.init*, and we're not init, we're
-+ not interested */
-+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
-+ != is_init)
-+ continue;
-+
-+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr;
-+ if (sechdrs[i].sh_type == SHT_REL) {
-+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr;
-+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel);
-+
-+ for (j = 0; j < size; ++j) {
-+ Elf_Sym *sym;
-+
-+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26)
-+ continue;
-+
-+ sym = syms + ELF_MIPS_R_SYM(rel[j]);
-+ if (!is_init && sym->st_shndx != SHN_UNDEF)
-+ continue;
-+
-+ ret += 4 * sizeof(int);
-+ }
-+ } else {
-+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr;
-+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela);
-+
-+ for (j = 0; j < size; ++j) {
-+ Elf_Sym *sym;
-+
-+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26)
-+ continue;
-+
-+ sym = syms + ELF_MIPS_R_SYM(rela[j]);
-+ if (!is_init && sym->st_shndx != SHN_UNDEF)
-+ continue;
-+
-+ ret += 4 * sizeof(int);
-+ }
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+#ifndef MODULE_START
-+static void *alloc_phys(unsigned long size)
-+{
-+ unsigned order;
-+ struct page *page;
-+ struct page *p;
-+
-+ size = PAGE_ALIGN(size);
-+ order = get_order(size);
-+
-+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN |
-+ __GFP_THISNODE, order);
-+ if (!page)
-+ return NULL;
-+
-+ split_page(page, order);
-+
-+ /* mark all pages except for the last one */
-+ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p)
-+ set_bit(PG_owner_priv_1, &p->flags);
-+
-+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p)
-+ __free_page(p);
-+
-+ return page_address(page);
-+}
-+#endif
-+
-+static void free_phys(void *ptr)
-+{
-+ struct page *page;
-+ bool free;
-+
-+ page = virt_to_page(ptr);
-+ do {
-+ free = test_and_clear_bit(PG_owner_priv_1, &page->flags);
-+ __free_page(page);
-+ page++;
-+ } while (free);
-+}
-+
-+
- void *module_alloc(unsigned long size)
- {
-+#ifdef MODULE_START
- return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
- GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-+#else
-+ void *ptr;
-+
-+ if (size == 0)
-+ return NULL;
-+
-+ ptr = alloc_phys(size);
-+
-+ /* If we failed to allocate physically contiguous memory,
-+ * fall back to regular vmalloc. The module loader code will
-+ * create jump tables to handle long jumps */
-+ if (!ptr)
-+ return vmalloc(size);
-+
-+ return ptr;
-+#endif
- }
-+
-+static inline bool is_phys_addr(void *ptr)
-+{
-+#ifdef CONFIG_64BIT
-+ return (KSEGX((unsigned long)ptr) == CKSEG0);
-+#else
-+ return (KSEGX(ptr) == KSEG0);
- #endif
-+}
-+
-+/* Free memory returned from module_alloc */
-+void module_memfree(void *module_region)
-+{
-+ if (is_phys_addr(module_region))
-+ free_phys(module_region);
-+ else
-+ vfree(module_region);
-+}
-+
-+static void *__module_alloc(int size, bool phys)
-+{
-+ void *ptr;
-+
-+ if (phys)
-+ ptr = kmalloc(size, GFP_KERNEL);
-+ else
-+ ptr = vmalloc(size);
-+ return ptr;
-+}
-+
-+static void __module_free(void *ptr)
-+{
-+ if (is_phys_addr(ptr))
-+ kfree(ptr);
-+ else
-+ vfree(ptr);
-+}
-+
-+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
-+ char *secstrings, struct module *mod)
-+{
-+ unsigned int symindex = 0;
-+ unsigned int core_size, init_size;
-+ int i;
-+
-+ mod->arch.phys_plt_offset = 0;
-+ mod->arch.virt_plt_offset = 0;
-+ mod->arch.phys_plt_tbl = NULL;
-+ mod->arch.virt_plt_tbl = NULL;
-+
-+ if (IS_ENABLED(CONFIG_64BIT))
-+ return 0;
-+
-+ for (i = 1; i < hdr->e_shnum; i++)
-+ if (sechdrs[i].sh_type == SHT_SYMTAB)
-+ symindex = i;
-+
-+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false);
-+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true);
-+
-+ if ((core_size + init_size) == 0)
-+ return 0;
-+
-+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1);
-+ if (!mod->arch.phys_plt_tbl)
-+ return -ENOMEM;
-+
-+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0);
-+ if (!mod->arch.virt_plt_tbl) {
-+ __module_free(mod->arch.phys_plt_tbl);
-+ mod->arch.phys_plt_tbl = NULL;
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-
- static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v)
- {
- *location = base + v;
- }
-
-+static Elf_Addr add_plt_entry_to(unsigned *plt_offset,
-+ void *start, Elf_Addr v)
-+{
-+ unsigned *tramp = start + *plt_offset;
-+ *plt_offset += 4 * sizeof(int);
-+
-+ /* adjust carry for addiu */
-+ if (v & 0x00008000)
-+ v += 0x10000;
-+
-+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */
-+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */
-+ tramp[2] = 0x03200008; /* jr t9 */
-+ tramp[3] = 0x00000000; /* nop */
-+
-+ return (Elf_Addr) tramp;
-+}
-+
-+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v)
-+{
-+ if (is_phys_addr(location))
-+ return add_plt_entry_to(&me->arch.phys_plt_offset,
-+ me->arch.phys_plt_tbl, v);
-+ else
-+ return add_plt_entry_to(&me->arch.virt_plt_offset,
-+ me->arch.virt_plt_tbl, v);
-+
-+}
-+
- static int apply_r_mips_26(struct module *me, u32 *location, u32 base,
- Elf_Addr v)
- {
-+ u32 ofs = base & 0x03ffffff;
-+
- if (v % 4) {
- pr_err("module %s: dangerous R_MIPS_26 relocation\n",
- me->name);
-@@ -56,13 +294,17 @@ static int apply_r_mips_26(struct module
- }
-
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
-- pr_err("module %s: relocation overflow\n",
-- me->name);
-- return -ENOEXEC;
-+ v = add_plt_entry(me, location, v + (ofs << 2));
-+ if (!v) {
-+ pr_err("module %s: relocation overflow\n",
-+ me->name);
-+ return -ENOEXEC;
-+ }
-+ ofs = 0;
- }
-
- *location = (*location & ~0x03ffffff) |
-- ((base + (v >> 2)) & 0x03ffffff);
-+ ((ofs + (v >> 2)) & 0x03ffffff);
-
- return 0;
- }
-@@ -442,9 +684,36 @@ int module_finalize(const Elf_Ehdr *hdr,
- list_add(&me->arch.dbe_list, &dbe_list);
- spin_unlock_irq(&dbe_lock);
- }
-+
-+ /* Get rid of the fixup trampoline if we're running the module
-+ * from physically mapped address space */
-+ if (me->arch.phys_plt_offset == 0) {
-+ __module_free(me->arch.phys_plt_tbl);
-+ me->arch.phys_plt_tbl = NULL;
-+ }
-+ if (me->arch.virt_plt_offset == 0) {
-+ __module_free(me->arch.virt_plt_tbl);
-+ me->arch.virt_plt_tbl = NULL;
-+ }
-+
- return 0;
- }
-
-+void module_arch_freeing_init(struct module *mod)
-+{
-+ if (mod->state == MODULE_STATE_LIVE)
-+ return;
-+
-+ if (mod->arch.phys_plt_tbl) {
-+ __module_free(mod->arch.phys_plt_tbl);
-+ mod->arch.phys_plt_tbl = NULL;
-+ }
-+ if (mod->arch.virt_plt_tbl) {
-+ __module_free(mod->arch.virt_plt_tbl);
-+ mod->arch.virt_plt_tbl = NULL;
-+ }
-+}
-+
- void module_arch_cleanup(struct module *mod)
- {
- spin_lock_irq(&dbe_lock);
diff --git a/target/linux/generic/pending-6.1/308-mips32r2_tune.patch b/target/linux/generic/pending-6.1/308-mips32r2_tune.patch
deleted file mode 100644
index db410a6bc0..0000000000
--- a/target/linux/generic/pending-6.1/308-mips32r2_tune.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2
-
-This provides a good tradeoff across at least 24Kc-74Kc, while also
-producing smaller code.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/mips/Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -172,7 +172,7 @@ cflags-$(CONFIG_CPU_R4300) += -march=r43
- cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
- cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
- cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap
--cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap
-+cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap
- cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg
- cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg
- cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap
diff --git a/target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch
deleted file mode 100644
index 54cc9ba647..0000000000
--- a/target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: fix errors in unresolved weak symbols on arm
-
-lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- arch/arm/kernel/module.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/kernel/module.c
-+++ b/arch/arm/kernel/module.c
-@@ -146,6 +146,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
- return -ENOEXEC;
- }
-
-+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) &&
-+ ELF_ST_BIND(sym->st_info) == STB_WEAK)
-+ continue;
-+
- loc = dstsec->sh_addr + rel->r_offset;
-
- switch (ELF32_R_TYPE(rel->r_info)) {
diff --git a/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch
deleted file mode 100644
index 3f553b28b3..0000000000
--- a/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch
+++ /dev/null
@@ -1,282 +0,0 @@
-From: Yousong Zhou <yszhou4tech@gmail.com>
-Subject: MIPS: kexec: Accept command line parameters from userspace.
-
-Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
----
- arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++-----
- arch/mips/kernel/machine_kexec.h | 20 +++++
- arch/mips/kernel/relocate_kernel.S | 21 +++--
- 3 files changed, 167 insertions(+), 27 deletions(-)
- create mode 100644 arch/mips/kernel/machine_kexec.h
-
---- a/arch/mips/kernel/machine_kexec.c
-+++ b/arch/mips/kernel/machine_kexec.c
-@@ -9,14 +9,11 @@
- #include <linux/delay.h>
- #include <linux/libfdt.h>
-
-+#include <asm/bootinfo.h>
- #include <asm/cacheflush.h>
- #include <asm/page.h>
--
--extern const unsigned char relocate_new_kernel[];
--extern const size_t relocate_new_kernel_size;
--
--extern unsigned long kexec_start_address;
--extern unsigned long kexec_indirection_page;
-+#include <linux/uaccess.h>
-+#include "machine_kexec.h"
-
- static unsigned long reboot_code_buffer;
-
-@@ -30,6 +27,101 @@ void (*_crash_smp_send_stop)(void) = NUL
- void (*_machine_kexec_shutdown)(void) = NULL;
- void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
-
-+static void machine_kexec_print_args(void)
-+{
-+ unsigned long argc = (int)kexec_args[0];
-+ int i;
-+
-+ pr_info("kexec_args[0] (argc): %lu\n", argc);
-+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
-+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
-+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
-+
-+ for (i = 0; i < argc; i++) {
-+ pr_info("kexec_argv[%d] = %p, %s\n",
-+ i, kexec_argv[i], kexec_argv[i]);
-+ }
-+}
-+
-+static void machine_kexec_init_argv(struct kimage *image)
-+{
-+ void __user *buf = NULL;
-+ size_t bufsz;
-+ size_t size;
-+ int i;
-+
-+ bufsz = 0;
-+ for (i = 0; i < image->nr_segments; i++) {
-+ struct kexec_segment *seg;
-+
-+ seg = &image->segment[i];
-+ if (seg->bufsz < 6)
-+ continue;
-+
-+ if (strncmp((char *) seg->buf, "kexec ", 6))
-+ continue;
-+
-+ buf = seg->buf;
-+ bufsz = seg->bufsz;
-+ break;
-+ }
-+
-+ if (!buf)
-+ return;
-+
-+ size = KEXEC_COMMAND_LINE_SIZE;
-+ size = min(size, bufsz);
-+ if (size < bufsz)
-+ pr_warn("kexec command line truncated to %zd bytes\n", size);
-+
-+ /* Copy to kernel space */
-+ if (copy_from_user(kexec_argv_buf, buf, size))
-+ pr_warn("kexec command line copy to kernel space failed\n");
-+
-+ kexec_argv_buf[size - 1] = 0;
-+}
-+
-+static void machine_kexec_parse_argv(struct kimage *image)
-+{
-+ char *reboot_code_buffer;
-+ int reloc_delta;
-+ char *ptr;
-+ int argc;
-+ int i;
-+
-+ ptr = kexec_argv_buf;
-+ argc = 0;
-+
-+ /*
-+ * convert command line string to array of parameters
-+ * (as bootloader does).
-+ */
-+ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) {
-+ if (*ptr == ' ') {
-+ *ptr++ = '\0';
-+ continue;
-+ }
-+
-+ kexec_argv[argc++] = ptr;
-+ ptr = strchr(ptr, ' ');
-+ }
-+
-+ if (!argc)
-+ return;
-+
-+ kexec_args[0] = argc;
-+ kexec_args[1] = (unsigned long)kexec_argv;
-+ kexec_args[2] = 0;
-+ kexec_args[3] = 0;
-+
-+ reboot_code_buffer = page_address(image->control_code_page);
-+ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel;
-+
-+ kexec_args[1] += reloc_delta;
-+ for (i = 0; i < argc; i++)
-+ kexec_argv[i] += reloc_delta;
-+}
-+
- static void kexec_image_info(const struct kimage *kimage)
- {
- unsigned long i;
-@@ -99,6 +191,18 @@ machine_kexec_prepare(struct kimage *kim
- #endif
-
- kexec_image_info(kimage);
-+ /*
-+ * Whenever arguments passed from kexec-tools, Init the arguments as
-+ * the original ones to try avoiding booting failure.
-+ */
-+
-+ kexec_args[0] = fw_arg0;
-+ kexec_args[1] = fw_arg1;
-+ kexec_args[2] = fw_arg2;
-+ kexec_args[3] = fw_arg3;
-+
-+ machine_kexec_init_argv(kimage);
-+ machine_kexec_parse_argv(kimage);
-
- if (_machine_kexec_prepare)
- return _machine_kexec_prepare(kimage);
-@@ -161,7 +265,7 @@ machine_crash_shutdown(struct pt_regs *r
- void kexec_nonboot_cpu_jump(void)
- {
- local_flush_icache_range((unsigned long)relocated_kexec_smp_wait,
-- reboot_code_buffer + relocate_new_kernel_size);
-+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
-
- relocated_kexec_smp_wait(NULL);
- }
-@@ -199,7 +303,7 @@ void kexec_reboot(void)
- * machine_kexec() CPU.
- */
- local_flush_icache_range(reboot_code_buffer,
-- reboot_code_buffer + relocate_new_kernel_size);
-+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
-
- do_kexec = (void *)reboot_code_buffer;
- do_kexec();
-@@ -212,10 +316,12 @@ machine_kexec(struct kimage *image)
- unsigned long *ptr;
-
- reboot_code_buffer =
-- (unsigned long)page_address(image->control_code_page);
-+ (unsigned long)page_address(image->control_code_page);
-+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer);
-
- kexec_start_address =
- (unsigned long) phys_to_virt(image->start);
-+ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address);
-
- if (image->type == KEXEC_TYPE_DEFAULT) {
- kexec_indirection_page =
-@@ -223,9 +329,19 @@ machine_kexec(struct kimage *image)
- } else {
- kexec_indirection_page = (unsigned long)&image->head;
- }
-+ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page);
-
-- memcpy((void*)reboot_code_buffer, relocate_new_kernel,
-- relocate_new_kernel_size);
-+ pr_info("Where is memcpy: %p\n", memcpy);
-+ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n",
-+ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end);
-+ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE,
-+ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer);
-+ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel,
-+ KEXEC_RELOCATE_NEW_KERNEL_SIZE);
-+
-+ pr_info("Before _print_args().\n");
-+ machine_kexec_print_args();
-+ pr_info("Before eval loop.\n");
-
- /*
- * The generic kexec code builds a page list with physical
-@@ -256,7 +372,7 @@ machine_kexec(struct kimage *image)
- #ifdef CONFIG_SMP
- /* All secondary cpus now may jump to kexec_wait cycle */
- relocated_kexec_smp_wait = reboot_code_buffer +
-- (void *)(kexec_smp_wait - relocate_new_kernel);
-+ (void *)(kexec_smp_wait - kexec_relocate_new_kernel);
- smp_wmb();
- atomic_set(&kexec_ready_to_reboot, 1);
- #endif
---- /dev/null
-+++ b/arch/mips/kernel/machine_kexec.h
-@@ -0,0 +1,20 @@
-+#ifndef _MACHINE_KEXEC_H
-+#define _MACHINE_KEXEC_H
-+
-+#ifndef __ASSEMBLY__
-+extern const unsigned char kexec_relocate_new_kernel[];
-+extern unsigned long kexec_relocate_new_kernel_end;
-+extern unsigned long kexec_start_address;
-+extern unsigned long kexec_indirection_page;
-+
-+extern char kexec_argv_buf[];
-+extern char *kexec_argv[];
-+
-+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel)
-+#endif /* !__ASSEMBLY__ */
-+
-+#define KEXEC_COMMAND_LINE_SIZE 256
-+#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16)
-+#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long))
-+
-+#endif
---- a/arch/mips/kernel/relocate_kernel.S
-+++ b/arch/mips/kernel/relocate_kernel.S
-@@ -10,10 +10,11 @@
- #include <asm/mipsregs.h>
- #include <asm/stackframe.h>
- #include <asm/addrspace.h>
-+#include "machine_kexec.h"
-
- #include <kernel-entry-init.h>
-
--LEAF(relocate_new_kernel)
-+LEAF(kexec_relocate_new_kernel)
- PTR_L a0, arg0
- PTR_L a1, arg1
- PTR_L a2, arg2
-@@ -98,7 +99,7 @@ done:
- #endif
- /* jump to kexec_start_address */
- j s1
-- END(relocate_new_kernel)
-+ END(kexec_relocate_new_kernel)
-
- #ifdef CONFIG_SMP
- /*
-@@ -177,8 +178,15 @@ EXPORT(kexec_indirection_page)
- PTR_WD 0
- .size kexec_indirection_page, PTRSIZE
-
--relocate_new_kernel_end:
-+kexec_argv_buf:
-+ EXPORT(kexec_argv_buf)
-+ .skip KEXEC_COMMAND_LINE_SIZE
-+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE
-+
-+kexec_argv:
-+ EXPORT(kexec_argv)
-+ .skip KEXEC_ARGV_SIZE
-+ .size kexec_argv, KEXEC_ARGV_SIZE
-
--EXPORT(relocate_new_kernel_size)
-- PTR_WD relocate_new_kernel_end - relocate_new_kernel
-- .size relocate_new_kernel_size, PTRSIZE
-+kexec_relocate_new_kernel_end:
-+ EXPORT(kexec_relocate_new_kernel_end)
diff --git a/target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch
deleted file mode 100644
index 30158cf399..0000000000
--- a/target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001
-From: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
-Date: Fri, 15 Mar 2019 18:53:38 +0300
-Subject: [PATCH] arc add OWRTDTB section
-
-This change allows OpenWRT to patch resulting kernel binary with
-external .dtb.
-
-That allows us to re-use exactky the same vmlinux on different boards
-given its ARC core configurations match (at least cache line sizes etc).
-
-""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external
-.dtb right after it, keeping the string in place.
-
-Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
-Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
-Signed-off-by: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
----
- arch/arc/kernel/head.S | 10 ++++++++++
- arch/arc/kernel/setup.c | 4 +++-
- arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++
- 3 files changed, 26 insertions(+), 1 deletion(-)
-
---- a/arch/arc/kernel/head.S
-+++ b/arch/arc/kernel/head.S
-@@ -88,6 +88,16 @@
- DSP_EARLY_INIT
- .endm
-
-+ ; Here "patch-dtb" will embed external .dtb
-+ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string
-+ ; and pastes .dtb right after it, hense the string precedes
-+ ; __image_dtb symbol.
-+ .section .owrt, "aw",@progbits
-+ .ascii "OWRTDTB:"
-+ENTRY(__image_dtb)
-+ .fill 0x4000
-+END(__image_dtb)
-+
- .section .init.text, "ax",@progbits
-
- ;----------------------------------------------------------------
---- a/arch/arc/kernel/setup.c
-+++ b/arch/arc/kernel/setup.c
-@@ -495,6 +495,8 @@ static inline bool uboot_arg_invalid(uns
- /* We always pass 0 as magic from U-boot */
- #define UBOOT_MAGIC_VALUE 0
-
-+extern struct boot_param_header __image_dtb;
-+
- void __init handle_uboot_args(void)
- {
- bool use_embedded_dtb = true;
-@@ -533,7 +535,7 @@ void __init handle_uboot_args(void)
- ignore_uboot_args:
-
- if (use_embedded_dtb) {
-- machine_desc = setup_machine_fdt(__dtb_start);
-+ machine_desc = setup_machine_fdt(&__image_dtb);
- if (!machine_desc)
- panic("Embedded DT invalid\n");
- }
---- a/arch/arc/kernel/vmlinux.lds.S
-+++ b/arch/arc/kernel/vmlinux.lds.S
-@@ -27,6 +27,19 @@ SECTIONS
-
- . = CONFIG_LINUX_LINK_BASE;
-
-+ /*
-+ * In OpenWRT we want to patch built binary embedding .dtb of choice.
-+ * This is implemented with "patch-dtb" utility which searches for
-+ * "OWRTDTB:" string in first 16k of image and if it is found
-+ * copies .dtb right after mentioned string.
-+ *
-+ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it.
-+ */
-+ .owrt : {
-+ *(.owrt)
-+ . = ALIGN(PAGE_SIZE);
-+ }
-+
- _int_vec_base_lds = .;
- .vector : {
- *(.vector)
diff --git a/target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch
deleted file mode 100644
index 1848a84cc4..0000000000
--- a/target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Alexey Brodkin <abrodkin@synopsys.com>
-Subject: arc: enable unaligned access in kernel mode
-
-This enables misaligned access handling even in kernel mode.
-Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses
-here and there and to cope with that without fixing stuff in the drivers
-we're just gracefully handling it on ARC.
-
-Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
----
- arch/arc/kernel/unaligned.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arc/kernel/unaligned.c
-+++ b/arch/arc/kernel/unaligned.c
-@@ -202,7 +202,7 @@ int misaligned_fixup(unsigned long addre
- char buf[TASK_COMM_LEN];
-
- /* handle user mode only and only if enabled by sysadmin */
-- if (!user_mode(regs) || !unaligned_enabled)
-+ if (!unaligned_enabled)
- return 1;
-
- if (no_unaligned_warning) {
diff --git a/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch
deleted file mode 100644
index e9b47d185d..0000000000
--- a/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Fri, 24 May 2019 17:56:19 +0200
-Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx
-
-Enable kernel XZ compression option on PPC_85xx. Tested with
-simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor).
-
-Suggested-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/powerpc/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -229,7 +229,7 @@ config PPC
- select HAVE_KERNEL_GZIP
- select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE
- select HAVE_KERNEL_LZO if DEFAULT_UIMAGE
-- select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x
-+ select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x || PPC_85xx
- select HAVE_KPROBES
- select HAVE_KPROBES_ON_FTRACE
- select HAVE_KRETPROBES
diff --git a/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch b/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch
deleted file mode 100644
index 3bf7ae98bf..0000000000
--- a/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Wed, 13 Mar 2024 20:28:37 +0800
-Subject: [PATCH] mips: kernel: fix detect_memory_region() function
-
-1. Do not use memcmp() on unallocated memory, as the new introduced
- fortify dynamic object size check[1] will report unexpected result.
-2. Use a fixed pattern instead of a random function pointer as the
- magic value.
-3. Flip magic value and double check it.
-4. Enable this feature only for 32-bit CPUs. Currently, only ath79 and
- ralink CPUs are using it.
-
-[1] 439a1bcac648 ("fortify: Use __builtin_dynamic_object_size() when available")
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
----
- arch/mips/include/asm/bootinfo.h | 2 ++
- arch/mips/kernel/setup.c | 17 ++++++++++++-----
- 2 files changed, 14 insertions(+), 5 deletions(-)
-
---- a/arch/mips/include/asm/bootinfo.h
-+++ b/arch/mips/include/asm/bootinfo.h
-@@ -93,7 +93,9 @@ const char *get_system_type(void);
-
- extern unsigned long mips_machtype;
-
-+#ifndef CONFIG_64BIT
- extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max);
-+#endif
-
- extern void prom_init(void);
- extern void prom_free_prom_memory(void);
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -90,21 +90,27 @@ static struct resource bss_resource = {
- unsigned long __kaslr_offset __ro_after_init;
- EXPORT_SYMBOL(__kaslr_offset);
-
--static void *detect_magic __initdata = detect_memory_region;
--
- #ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
- unsigned long ARCH_PFN_OFFSET;
- EXPORT_SYMBOL(ARCH_PFN_OFFSET);
- #endif
-
-+#ifndef CONFIG_64BIT
-+static u32 detect_magic __initdata;
-+#define MIPS_MEM_TEST_PATTERN 0xaa5555aa
-+
- void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
- {
-- void *dm = &detect_magic;
-+ void *dm = (void *)KSEG1ADDR(&detect_magic);
- phys_addr_t size;
-
- for (size = sz_min; size < sz_max; size <<= 1) {
-- if (!memcmp(dm, dm + size, sizeof(detect_magic)))
-- break;
-+ __raw_writel(MIPS_MEM_TEST_PATTERN, dm);
-+ if (__raw_readl(dm) == __raw_readl(dm + size)) {
-+ __raw_writel(~MIPS_MEM_TEST_PATTERN, dm);
-+ if (__raw_readl(dm) == __raw_readl(dm + size))
-+ break;
-+ }
- }
-
- pr_debug("Memory: %lluMB of RAM detected at 0x%llx (min: %lluMB, max: %lluMB)\n",
-@@ -115,6 +121,7 @@ void __init detect_memory_region(phys_ad
-
- memblock_add(start, size);
- }
-+#endif /* CONFIG_64BIT */
-
- /*
- * Manage initrd
diff --git a/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch b/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch
deleted file mode 100644
index 2675ca4791..0000000000
--- a/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From patchwork Thu Mar 16 19:28:33 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13178238
-Return-Path: <linux-mips-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 5EF2AC6FD19
- for <linux-mips@archiver.kernel.org>; Thu, 16 Mar 2023 19:28:43 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230076AbjCPT2l (ORCPT <rfc822;linux-mips@archiver.kernel.org>);
- Thu, 16 Mar 2023 15:28:41 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56412 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230039AbjCPT2k (ORCPT
- <rfc822;linux-mips@vger.kernel.org>); Thu, 16 Mar 2023 15:28:40 -0400
-Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com
- [IPv6:2a00:1450:4864:20::42f])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7259B7D9F;
- Thu, 16 Mar 2023 12:28:38 -0700 (PDT)
-Received: by mail-wr1-x42f.google.com with SMTP id y14so2539231wrq.4;
- Thu, 16 Mar 2023 12:28:38 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1678994917;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=;
- b=FzMRr5ekh/fDiJqTlezNj6nLjzvn5z92FtYeB8MquVSMB8PuvarccnyqAzsXiccf+v
- uwRFIomnTWNLGVjzc1xrB2hGiCKD3jBo5n1u8p/yEV6rpolbxVjfM7eTHXyAHXGXz7ZJ
- TPeVbWfAlxiSD6+BPtXr/efehcdI64fIoL6G/U1WHNMo01Tzr/Obf3y5tug17N0fGcXg
- CH6E5a2HguZUtwrm26LcK9IOV/7xEx5eIE1cOvTLMxPbGWaZwEjjP16HylJr06xRLhaf
- RpiYBT3mXwwuOx0jLOhqavY/2kZ9GVbZRWMMwZrZv9xNO13SBwc1VUVgD4k3FntnSk7Z
- AaOQ==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1678994917;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=;
- b=OaA5DMgqalrfqO5iOtmmxFPsH90MkN7l4EJpyVnzuiO1Wd6rSCpqPOR7xpxZno8OPP
- tdfm4vzn9Ie4AUDbFKDTUlPG+tgkmIruo3K9C0VnY9DD2PRZMEYBbWaJKU1otqKt0NKu
- IAAHNvxvQvCESKzbXFLYwWbRKFScOSMGmGBTDfgThz51A18Ff1hJy/BmnuZk7M2TLgHO
- wQpy9t7oeB/Hkxl41y46emLc/nESsvwvAG/fx/zPzCe9UiaQLrdZq+BKeOwSBedktzK5
- U/ZTfgzU2UGSI67aGRqqGnI0uXq+MAJMK18qzM0VByxj6W+AXJ6BJr5P0quljeQ8upSg
- bEUg==
-X-Gm-Message-State: AO0yUKWnqTlccBDnqwCSRdqOBGc2FyfiLy1Tg7EjPENlISpzXuDYwW/R
- lJSI06rrfq+Vel/SigfpGJI=
-X-Google-Smtp-Source:
- AK7set/jYfYl9ttVzIXJO+ZQVfa6cE/yOsP8fx4teiTmGNNWyVlIJRzMAlF3IUGqRAXAmY3hAabIuQ==
-X-Received: by 2002:a5d:40ce:0:b0:2cd:ceab:df1a with SMTP id
- b14-20020a5d40ce000000b002cdceabdf1amr381006wrq.32.1678994916642;
- Thu, 16 Mar 2023 12:28:36 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- l10-20020a5d4bca000000b002cfea3c49d5sm180041wrt.52.2023.03.16.12.28.35
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Thu, 16 Mar 2023 12:28:35 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com,
- bcm-kernel-feedback-list@broadcom.com, tglx@linutronix.de,
- maz@kernel.org, linux-mips@vger.kernel.org,
- linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2] irqchip/bcm-6345-l1: request memory region
-Date: Thu, 16 Mar 2023 20:28:33 +0100
-Message-Id: <20230316192833.1603149-1-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230316180701.783785-1-noltari@gmail.com>
-References: <20230316180701.783785-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-mips.vger.kernel.org>
-X-Mailing-List: linux-mips@vger.kernel.org
-
-Request memory region in order to display it in /proc/iomem.
-Also stop printing the MMIO address since it just displays (ptrval).
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
----
- v2: request memory region and stop displaying MMIO address.
-
- drivers/irqchip/irq-bcm6345-l1.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/irqchip/irq-bcm6345-l1.c
-+++ b/drivers/irqchip/irq-bcm6345-l1.c
-@@ -253,6 +253,9 @@ static int __init bcm6345_l1_init_one(st
- if (!cpu->map_base)
- return -ENOMEM;
-
-+ if (!request_mem_region(res.start, sz, res.name))
-+ pr_err("failed to request intc memory");
-+
- for (i = 0; i < n_words; i++) {
- cpu->enable_cache[i] = 0;
- __raw_writel(0, cpu->map_base + reg_enable(intc, i));
-@@ -331,8 +334,7 @@ static int __init bcm6345_l1_of_init(str
- for_each_cpu(idx, &intc->cpumask) {
- struct bcm6345_l1_cpu *cpu = intc->cpus[idx];
-
-- pr_info(" CPU%u at MMIO 0x%p (irq = %d)\n", idx,
-- cpu->map_base, cpu->parent_irq);
-+ pr_info(" CPU%u (irq = %d)\n", idx, cpu->parent_irq);
- }
-
- return 0;
diff --git a/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch
deleted file mode 100644
index c619d12ce5..0000000000
--- a/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch
+++ /dev/null
@@ -1,328 +0,0 @@
-From 39717277d5c87bdb183cf2f258957b44ba99b4df Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 11:47:35 +0200
-Subject: [PATCH] mtd: mtdsplit support
-
----
- drivers/mtd/Kconfig | 19 ++++
- drivers/mtd/Makefile | 2 +
- drivers/mtd/mtdpart.c | 169 ++++++++++++++++++++++++++++-----
- include/linux/mtd/mtd.h | 25 +++++
- include/linux/mtd/partitions.h | 7 ++
- 5 files changed, 197 insertions(+), 25 deletions(-)
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -12,6 +12,25 @@ menuconfig MTD
-
- if MTD
-
-+menu "OpenWrt specific MTD options"
-+
-+config MTD_ROOTFS_ROOT_DEV
-+ bool "Automatically set 'rootfs' partition to be root filesystem"
-+ default y
-+
-+config MTD_SPLIT_FIRMWARE
-+ bool "Automatically split firmware partition for kernel+rootfs"
-+ default y
-+
-+config MTD_SPLIT_FIRMWARE_NAME
-+ string "Firmware partition name"
-+ depends on MTD_SPLIT_FIRMWARE
-+ default "firmware"
-+
-+source "drivers/mtd/mtdsplit/Kconfig"
-+
-+endmenu
-+
- config MTD_TESTS
- tristate "MTD tests support (DANGEROUS)"
- depends on m
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc
-
- obj-y += parsers/
-
-+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/
-+
- # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
- obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -15,11 +15,13 @@
- #include <linux/kmod.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-+#include <linux/magic.h>
- #include <linux/err.h>
- #include <linux/of.h>
- #include <linux/of_platform.h>
-
- #include "mtdcore.h"
-+#include "mtdsplit/mtdsplit.h"
-
- /*
- * MTD methods which simply translate the effective address and pass through
-@@ -236,6 +238,147 @@ static int mtd_add_partition_attrs(struc
- return ret;
- }
-
-+static DEFINE_SPINLOCK(part_parser_lock);
-+static LIST_HEAD(part_parsers);
-+
-+static struct mtd_part_parser *mtd_part_parser_get(const char *name)
-+{
-+ struct mtd_part_parser *p, *ret = NULL;
-+
-+ spin_lock(&part_parser_lock);
-+
-+ list_for_each_entry(p, &part_parsers, list)
-+ if (!strcmp(p->name, name) && try_module_get(p->owner)) {
-+ ret = p;
-+ break;
-+ }
-+
-+ spin_unlock(&part_parser_lock);
-+
-+ return ret;
-+}
-+
-+static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
-+{
-+ module_put(p->owner);
-+}
-+
-+static struct mtd_part_parser *
-+get_partition_parser_by_type(enum mtd_parser_type type,
-+ struct mtd_part_parser *start)
-+{
-+ struct mtd_part_parser *p, *ret = NULL;
-+
-+ spin_lock(&part_parser_lock);
-+
-+ p = list_prepare_entry(start, &part_parsers, list);
-+ if (start)
-+ mtd_part_parser_put(start);
-+
-+ list_for_each_entry_continue(p, &part_parsers, list) {
-+ if (p->type == type && try_module_get(p->owner)) {
-+ ret = p;
-+ break;
-+ }
-+ }
-+
-+ spin_unlock(&part_parser_lock);
-+
-+ return ret;
-+}
-+
-+static int parse_mtd_partitions_by_type(struct mtd_info *master,
-+ enum mtd_parser_type type,
-+ const struct mtd_partition **pparts,
-+ struct mtd_part_parser_data *data)
-+{
-+ struct mtd_part_parser *prev = NULL;
-+ int ret = 0;
-+
-+ while (1) {
-+ struct mtd_part_parser *parser;
-+
-+ parser = get_partition_parser_by_type(type, prev);
-+ if (!parser)
-+ break;
-+
-+ ret = (*parser->parse_fn)(master, pparts, data);
-+
-+ if (ret > 0) {
-+ mtd_part_parser_put(parser);
-+ printk(KERN_NOTICE
-+ "%d %s partitions found on MTD device %s\n",
-+ ret, parser->name, master->name);
-+ break;
-+ }
-+
-+ prev = parser;
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type)
-+{
-+ struct mtd_partition *parts;
-+ int nr_parts;
-+ int i;
-+
-+ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts,
-+ NULL);
-+ if (nr_parts <= 0)
-+ return nr_parts;
-+
-+ if (WARN_ON(!parts))
-+ return 0;
-+
-+ for (i = 0; i < nr_parts; i++) {
-+ /* adjust partition offsets */
-+ parts[i].offset += child->part.offset;
-+
-+ mtd_add_partition(child->parent,
-+ parts[i].name,
-+ parts[i].offset,
-+ parts[i].size);
-+ }
-+
-+ kfree(parts);
-+
-+ return nr_parts;
-+}
-+
-+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
-+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
-+#else
-+#define SPLIT_FIRMWARE_NAME "unused"
-+#endif
-+
-+static void split_firmware(struct mtd_info *master, struct mtd_info *part)
-+{
-+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE);
-+}
-+
-+static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part)
-+{
-+ static int rootfs_found = 0;
-+
-+ if (rootfs_found)
-+ return;
-+
-+ if (of_find_property(mtd_get_of_node(part), "linux,rootfs", NULL) ||
-+ !strcmp(part->name, "rootfs")) {
-+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS);
-+
-+ rootfs_found = 1;
-+ }
-+
-+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) &&
-+ !strcmp(part->name, SPLIT_FIRMWARE_NAME) &&
-+ !of_find_property(mtd_get_of_node(part), "compatible", NULL))
-+ split_firmware(master, part);
-+}
-+
- int mtd_add_partition(struct mtd_info *parent, const char *name,
- long long offset, long long length)
- {
-@@ -274,6 +417,7 @@ int mtd_add_partition(struct mtd_info *p
- if (ret)
- goto err_remove_part;
-
-+ mtd_partition_split(parent, child);
- mtd_add_partition_attrs(child);
-
- return 0;
-@@ -422,6 +566,7 @@ int add_mtd_partitions(struct mtd_info *
- goto err_del_partitions;
- }
-
-+ mtd_partition_split(master, child);
- mtd_add_partition_attrs(child);
-
- /* Look for subpartitions */
-@@ -438,31 +583,6 @@ err_del_partitions:
- return ret;
- }
-
--static DEFINE_SPINLOCK(part_parser_lock);
--static LIST_HEAD(part_parsers);
--
--static struct mtd_part_parser *mtd_part_parser_get(const char *name)
--{
-- struct mtd_part_parser *p, *ret = NULL;
--
-- spin_lock(&part_parser_lock);
--
-- list_for_each_entry(p, &part_parsers, list)
-- if (!strcmp(p->name, name) && try_module_get(p->owner)) {
-- ret = p;
-- break;
-- }
--
-- spin_unlock(&part_parser_lock);
--
-- return ret;
--}
--
--static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
--{
-- module_put(p->owner);
--}
--
- /*
- * Many partition parsers just expected the core to kfree() all their data in
- * one chunk. Do that by default.
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -615,6 +615,24 @@ static inline void mtd_align_erase_req(s
- req->len += mtd->erasesize - mod;
- }
-
-+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd)
-+{
-+ if (mtd_mod_by_eb(sz, mtd) == 0)
-+ return sz;
-+
-+ /* Round up to next erase block */
-+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize;
-+}
-+
-+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd)
-+{
-+ if (mtd_mod_by_eb(sz, mtd) == 0)
-+ return sz;
-+
-+ /* Round down to the start of the current erase block */
-+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize;
-+}
-+
- static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
- {
- if (mtd->writesize_shift)
-@@ -688,6 +706,13 @@ extern struct mtd_info *of_get_mtd_devic
- extern struct mtd_info *get_mtd_device_nm(const char *name);
- extern void put_mtd_device(struct mtd_info *mtd);
-
-+static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd)
-+{
-+ if (!mtd_is_partition(mtd))
-+ return 0;
-+
-+ return mtd->part.offset;
-+}
-
- struct mtd_notifier {
- void (*add)(struct mtd_info *mtd);
---- a/include/linux/mtd/partitions.h
-+++ b/include/linux/mtd/partitions.h
-@@ -75,6 +75,12 @@ struct mtd_part_parser_data {
- * Functions dealing with the various ways of partitioning the space
- */
-
-+enum mtd_parser_type {
-+ MTD_PARSER_TYPE_DEVICE = 0,
-+ MTD_PARSER_TYPE_ROOTFS,
-+ MTD_PARSER_TYPE_FIRMWARE,
-+};
-+
- struct mtd_part_parser {
- struct list_head list;
- struct module *owner;
-@@ -83,6 +89,7 @@ struct mtd_part_parser {
- int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
- struct mtd_part_parser_data *);
- void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
-+ enum mtd_parser_type type;
- };
-
- /* Container for passing around a set of parsed partitions */
diff --git a/target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch b/target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch
deleted file mode 100644
index 42b5a564b1..0000000000
--- a/target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 31 Oct 2023 15:51:01 +0100
-Subject: [PATCH] mtd: don't register NVMEM devices for partitions with custom
- drivers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes issue exposed by upstream commit f4cf4e5db331 ("Revert
-"nvmem: add new config option"").
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/mtd/mtdcore.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -519,6 +519,29 @@ static int mtd_nvmem_add(struct mtd_info
- struct device_node *node = mtd_get_of_node(mtd);
- struct nvmem_config config = {};
-
-+ /*
-+ * Do NOT register NVMEM device for any partition that is meant to be
-+ * handled by a U-Boot env driver. That would result in associating two
-+ * different NVMEM devices with the same OF node.
-+ *
-+ * An example of unwanted behaviour of above (forwardtrace):
-+ * of_get_mac_addr_nvmem()
-+ * of_nvmem_cell_get()
-+ * __nvmem_device_get()
-+ *
-+ * We can't have __nvmem_device_get() return "mtdX" NVMEM device instead
-+ * of U-Boot env NVMEM device. That would result in failing to find
-+ * NVMEM cell.
-+ *
-+ * This issue seems to affect U-Boot env case only and will go away with
-+ * switch to NVMEM layouts.
-+ */
-+ if (of_device_is_compatible(node, "u-boot,env") ||
-+ of_device_is_compatible(node, "u-boot,env-redundant-bool") ||
-+ of_device_is_compatible(node, "u-boot,env-redundant-count") ||
-+ of_device_is_compatible(node, "brcm,env"))
-+ return 0;
-+
- config.id = -1;
- config.dev = &mtd->dev;
- config.name = dev_name(&mtd->dev);
diff --git a/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch b/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch
deleted file mode 100644
index 66a6feff60..0000000000
--- a/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch
+++ /dev/null
@@ -1,245 +0,0 @@
-From acacdac272927ae1d96e0bca51eb82899671eaea Mon Sep 17 00:00:00 2001
-From: John Thomson <git@johnthomson.fastmail.com.au>
-Date: Fri, 25 Dec 2020 18:50:08 +1000
-Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Do not prevent writing to mtd partitions where a partition boundary sits
-on a minor erasesize boundary.
-This addresses a FIXME that has been present since the start of the
-linux git history:
-/* Doesn't start on a boundary of major erase size */
-/* FIXME: Let it be writable if it is on a boundary of
- * _minor_ erase size though */
-
-Allow a uniform erase region spi-nor device to be configured
-to use the non-uniform erase regions code path for an erase with:
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-
-On supporting hardware (SECT_4K: majority of current SPI-NOR device)
-provide the facility for an erase to use the least number
-of SPI-NOR operations, as well as access to 4K erase without
-requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
-
-Introduce erasesize_minor to the mtd struct,
-the smallest erasesize supported by the device
-
-On existing devices, this is useful where write support is wanted
-for data on a 4K partition, such as some u-boot-env partitions,
-or RouterBoot soft_config, while still netting the performance
-benefits of using 64K sectors
-
-Performance:
-time mtd erase firmware
-OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length
-
-Without this patch
-MTD_SPI_NOR_USE_4K_SECTORS=y |n
-real 2m 11.66s |0m 50.86s
-user 0m 0.00s |0m 0.00s
-sys 1m 56.20s |0m 50.80s
-
-With this patch
-MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y
-real 0m 51.68s |0m 50.85s |2m 12.89s
-user 0m 0.00s |0m 0.00s |0m 0.01s
-sys 0m 46.94s |0m 50.38s |2m 12.46s
-
-Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
-Signed-off-by: Thibaut VARÈNE <hacks+kernel@slashdirt.org>
-
----
-
-checkpatch does not like the printk(KERN_WARNING
-these should be changed separately beforehand?
-
-Changes v1 -> v2:
-Added mtdcore sysfs for erasesize_minor
-Removed finding minor erasesize for variable erase regions device,
-as untested and no responses regarding it.
-Moved IF_ENABLED for SPINOR variable erase to guard setting
-erasesize_minor in spi-nor/core.c
-Removed setting erasesize to minor where partition boundaries require
-minor erase to be writable
-Simplified minor boundary check by relying on minor being a factor of
-major
-
-Changes RFC -> v1:
-Fix uninitialized variable smatch warning
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
----
- drivers/mtd/mtdcore.c | 10 ++++++++++
- drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++----------
- drivers/mtd/spi-nor/Kconfig | 10 ++++++++++
- drivers/mtd/spi-nor/core.c | 11 +++++++++--
- include/linux/mtd/mtd.h | 2 ++
- 5 files changed, 56 insertions(+), 12 deletions(-)
-
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -169,6 +169,15 @@ static ssize_t mtd_erasesize_show(struct
- }
- MTD_DEVICE_ATTR_RO(erasesize);
-
-+static ssize_t mtd_erasesize_minor_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct mtd_info *mtd = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor);
-+}
-+MTD_DEVICE_ATTR_RO(erasesize_minor);
-+
- static ssize_t mtd_writesize_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -314,6 +323,7 @@ static struct attribute *mtd_attrs[] = {
- &dev_attr_flags.attr,
- &dev_attr_size.attr,
- &dev_attr_erasesize.attr,
-+ &dev_attr_erasesize_minor.attr,
- &dev_attr_writesize.attr,
- &dev_attr_subpagesize.attr,
- &dev_attr_oobsize.attr,
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -41,6 +41,7 @@ static struct mtd_info *allocate_partiti
- struct mtd_info *master = mtd_get_master(parent);
- int wr_alignment = (parent->flags & MTD_NO_ERASE) ?
- master->writesize : master->erasesize;
-+ int wr_alignment_minor = 0;
- u64 parent_size = mtd_is_partition(parent) ?
- parent->part.size : parent->size;
- struct mtd_info *child;
-@@ -165,6 +166,7 @@ static struct mtd_info *allocate_partiti
- } else {
- /* Single erase size */
- child->erasesize = master->erasesize;
-+ child->erasesize_minor = master->erasesize_minor;
- }
-
- /*
-@@ -172,26 +174,39 @@ static struct mtd_info *allocate_partiti
- * exposes several regions with different erasesize. Adjust
- * wr_alignment accordingly.
- */
-- if (!(child->flags & MTD_NO_ERASE))
-+ if (!(child->flags & MTD_NO_ERASE)) {
- wr_alignment = child->erasesize;
-+ wr_alignment_minor = child->erasesize_minor;
-+ }
-
- tmp = mtd_get_master_ofs(child, 0);
- remainder = do_div(tmp, wr_alignment);
- if ((child->flags & MTD_WRITEABLE) && remainder) {
-- /* Doesn't start on a boundary of major erase size */
-- /* FIXME: Let it be writable if it is on a boundary of
-- * _minor_ erase size though */
-- child->flags &= ~MTD_WRITEABLE;
-- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
-- part->name);
-+ if (wr_alignment_minor) {
-+ /* rely on minor being a factor of major erasesize */
-+ tmp = remainder;
-+ remainder = do_div(tmp, wr_alignment_minor);
-+ }
-+ if (remainder) {
-+ child->flags &= ~MTD_WRITEABLE;
-+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
-+ part->name);
-+ }
- }
-
- tmp = mtd_get_master_ofs(child, 0) + child->part.size;
- remainder = do_div(tmp, wr_alignment);
- if ((child->flags & MTD_WRITEABLE) && remainder) {
-- child->flags &= ~MTD_WRITEABLE;
-- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
-- part->name);
-+ if (wr_alignment_minor) {
-+ tmp = remainder;
-+ remainder = do_div(tmp, wr_alignment_minor);
-+ }
-+
-+ if (remainder) {
-+ child->flags &= ~MTD_WRITEABLE;
-+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
-+ part->name);
-+ }
- }
-
- child->size = child->part.size;
---- a/drivers/mtd/spi-nor/Kconfig
-+++ b/drivers/mtd/spi-nor/Kconfig
-@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR
-
- if MTD_SPI_NOR
-
-+config MTD_SPI_NOR_USE_VARIABLE_ERASE
-+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes"
-+ depends on !MTD_SPI_NOR_USE_4K_SECTORS
-+ default n
-+ help
-+ Allow mixed use of all hardware supported erasesizes,
-+ by forcing spi_nor to use the multiple eraseregions code path.
-+ For example: A 68K erase will use one 64K erase, and one 4K erase
-+ on supporting hardware.
-+
- config MTD_SPI_NOR_USE_4K_SECTORS
- bool "Use small 4096 B erase sectors"
- default y
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -1050,6 +1050,8 @@ static u8 spi_nor_convert_3to4_erase(u8
-
- static bool spi_nor_has_uniform_erase(const struct spi_nor *nor)
- {
-+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE))
-+ return false;
- return !!nor->params->erase_map.uniform_erase_type;
- }
-
-@@ -2180,6 +2182,7 @@ static int spi_nor_select_erase(struct s
- {
- struct spi_nor_erase_map *map = &nor->params->erase_map;
- const struct spi_nor_erase_type *erase = NULL;
-+ const struct spi_nor_erase_type *erase_minor = NULL;
- struct mtd_info *mtd = &nor->mtd;
- u32 wanted_size = nor->info->sector_size;
- int i;
-@@ -2212,8 +2215,9 @@ static int spi_nor_select_erase(struct s
- */
- for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) {
- if (map->erase_type[i].size) {
-- erase = &map->erase_type[i];
-- break;
-+ if (!erase)
-+ erase = &map->erase_type[i];
-+ erase_minor = &map->erase_type[i];
- }
- }
-
-@@ -2221,6 +2225,9 @@ static int spi_nor_select_erase(struct s
- return -EINVAL;
-
- mtd->erasesize = erase->size;
-+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) &&
-+ erase_minor && erase_minor->size < erase->size)
-+ mtd->erasesize_minor = erase_minor->size;
- return 0;
- }
-
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -245,6 +245,8 @@ struct mtd_info {
- * information below if they desire
- */
- uint32_t erasesize;
-+ /* "Minor" (smallest) erase size supported by the whole device */
-+ uint32_t erasesize_minor;
- /* Minimal writable flash unit size. In case of NOR flash it is 1 (even
- * though individual bits can be cleared), in case of NAND flash it is
- * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
diff --git a/target/linux/generic/pending-6.1/420-mtd-redboot_space.patch b/target/linux/generic/pending-6.1/420-mtd-redboot_space.patch
deleted file mode 100644
index 5518ea71dd..0000000000
--- a/target/linux/generic/pending-6.1/420-mtd-redboot_space.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable)
-
-[john@phrozen.org: used by ixp and others]
-
-lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/redboot.c | 19 +++++++++++++------
- 1 file changed, 13 insertions(+), 6 deletions(-)
-
---- a/drivers/mtd/parsers/redboot.c
-+++ b/drivers/mtd/parsers/redboot.c
-@@ -278,14 +278,21 @@ nogood:
- #endif
- names += strlen(names) + 1;
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
- if (fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
-- i++;
-- parts[i].offset = parts[i - 1].size + parts[i - 1].offset;
-- parts[i].size = fl->next->img->flash_base - parts[i].offset;
-- parts[i].name = nullname;
-- }
-+ if (!strcmp(parts[i].name, "rootfs")) {
-+ parts[i].size = fl->next->img->flash_base;
-+ parts[i].size &= ~(master->erasesize - 1);
-+ parts[i].size -= parts[i].offset;
-+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
-+ nrparts--;
-+ } else {
-+ i++;
-+ parts[i].offset = parts[i-1].size + parts[i-1].offset;
-+ parts[i].size = fl->next->img->flash_base - parts[i].offset;
-+ parts[i].name = nullname;
- #endif
-+ }
-+ }
- tmp_fl = fl;
- fl = fl->next;
- kfree(tmp_fl);
diff --git a/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch
deleted file mode 100644
index 35e80d6dcc..0000000000
--- a/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch
+++ /dev/null
@@ -1,229 +0,0 @@
-From: Florian Fainelli <f.fainelli@gmail.com>
-Subject: Add myloader partition table parser
-
-[john@phozen.org: shoud be upstreamable]
-
-lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-[adjust for kernel 5.4, add myloader.c to patch]
-Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -67,6 +67,22 @@ config MTD_CMDLINE_PARTS
-
- If unsure, say 'N'.
-
-+config MTD_MYLOADER_PARTS
-+ tristate "MyLoader partition parsing"
-+ depends on ADM5120 || ATH79
-+ help
-+ MyLoader is a bootloader which allows the user to define partitions
-+ in flash devices, by putting a table in the second erase block
-+ on the device, similar to a partition table. This table gives the
-+ offsets and lengths of the user defined partitions.
-+
-+ If you need code which can detect and parse these tables, and
-+ register MTD 'partitions' corresponding to each image detected,
-+ enable this option.
-+
-+ You will still need the parsing functions to be called by the driver
-+ for your particular device. It won't happen automatically.
-+
- config MTD_OF_PARTS
- tristate "OpenFirmware (device tree) partitioning parser"
- default y
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -4,6 +4,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm4
- obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
- obj-$(CONFIG_MTD_BRCM_U_BOOT) += brcm_u-boot.o
- obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
-+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
- obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
- ofpart-y += ofpart_core.o
- ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o
---- /dev/null
-+++ b/drivers/mtd/parsers/myloader.c
-@@ -0,0 +1,181 @@
-+/*
-+ * Parse MyLoader-style flash partition tables and produce a Linux partition
-+ * array to match.
-+ *
-+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
-+ *
-+ * This file was based on drivers/mtd/redboot.c
-+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/vmalloc.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/byteorder/generic.h>
-+#include <linux/myloader.h>
-+
-+#define BLOCK_LEN_MIN 0x10000
-+#define PART_NAME_LEN 32
-+
-+struct part_data {
-+ struct mylo_partition_table tab;
-+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
-+};
-+
-+static int myloader_parse_partitions(struct mtd_info *master,
-+ const struct mtd_partition **pparts,
-+ struct mtd_part_parser_data *data)
-+{
-+ struct part_data *buf;
-+ struct mylo_partition_table *tab;
-+ struct mylo_partition *part;
-+ struct mtd_partition *mtd_parts;
-+ struct mtd_partition *mtd_part;
-+ int num_parts;
-+ int ret, i;
-+ size_t retlen;
-+ char *names;
-+ unsigned long offset;
-+ unsigned long blocklen;
-+
-+ buf = vmalloc(sizeof(*buf));
-+ if (!buf) {
-+ return -ENOMEM;
-+ goto out;
-+ }
-+ tab = &buf->tab;
-+
-+ blocklen = master->erasesize;
-+ if (blocklen < BLOCK_LEN_MIN)
-+ blocklen = BLOCK_LEN_MIN;
-+
-+ offset = blocklen;
-+
-+ /* Find the partition table */
-+ for (i = 0; i < 4; i++, offset += blocklen) {
-+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
-+ " at offset 0x%lx\n", master->name, offset);
-+
-+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
-+ (void *)buf);
-+ if (ret)
-+ goto out_free_buf;
-+
-+ if (retlen != sizeof(*buf)) {
-+ ret = -EIO;
-+ goto out_free_buf;
-+ }
-+
-+ /* Check for Partition Table magic number */
-+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
-+ break;
-+
-+ }
-+
-+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
-+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
-+ master->name);
-+ ret = 0;
-+ goto out_free_buf;
-+ }
-+
-+ /* The MyLoader and the Partition Table is always present */
-+ num_parts = 2;
-+
-+ /* Detect number of used partitions */
-+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
-+ part = &tab->partitions[i];
-+
-+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
-+ continue;
-+
-+ num_parts++;
-+ }
-+
-+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
-+ num_parts * PART_NAME_LEN), GFP_KERNEL);
-+
-+ if (!mtd_parts) {
-+ ret = -ENOMEM;
-+ goto out_free_buf;
-+ }
-+
-+ mtd_part = mtd_parts;
-+ names = (char *)&mtd_parts[num_parts];
-+
-+ strncpy(names, "myloader", PART_NAME_LEN);
-+ mtd_part->name = names;
-+ mtd_part->offset = 0;
-+ mtd_part->size = offset;
-+ mtd_part->mask_flags = MTD_WRITEABLE;
-+ mtd_part++;
-+ names += PART_NAME_LEN;
-+
-+ strncpy(names, "partition_table", PART_NAME_LEN);
-+ mtd_part->name = names;
-+ mtd_part->offset = offset;
-+ mtd_part->size = blocklen;
-+ mtd_part->mask_flags = MTD_WRITEABLE;
-+ mtd_part++;
-+ names += PART_NAME_LEN;
-+
-+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
-+ part = &tab->partitions[i];
-+
-+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
-+ continue;
-+
-+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
-+ strncpy(names, buf->names[i], PART_NAME_LEN);
-+ else
-+ snprintf(names, PART_NAME_LEN, "partition%d", i);
-+
-+ mtd_part->offset = le32_to_cpu(part->addr);
-+ mtd_part->size = le32_to_cpu(part->size);
-+ mtd_part->name = names;
-+ mtd_part++;
-+ names += PART_NAME_LEN;
-+ }
-+
-+ *pparts = mtd_parts;
-+ ret = num_parts;
-+
-+ out_free_buf:
-+ vfree(buf);
-+ out:
-+ return ret;
-+}
-+
-+static struct mtd_part_parser myloader_mtd_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = myloader_parse_partitions,
-+ .name = "MyLoader",
-+};
-+
-+static int __init myloader_mtd_parser_init(void)
-+{
-+ register_mtd_parser(&myloader_mtd_parser);
-+
-+ return 0;
-+}
-+
-+static void __exit myloader_mtd_parser_exit(void)
-+{
-+ deregister_mtd_parser(&myloader_mtd_parser);
-+}
-+
-+module_init(myloader_mtd_parser_init);
-+module_exit(myloader_mtd_parser_exit);
-+
-+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
-+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
deleted file mode 100644
index bcea45d009..0000000000
--- a/target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/drivers/mtd/parsers/parser_trx.c
-+++ b/drivers/mtd/parsers/parser_trx.c
-@@ -25,6 +25,33 @@ struct trx_header {
- uint32_t offset[3];
- } __packed;
-
-+/*
-+ * Calculate real end offset (address) for a given amount of data. It checks
-+ * all blocks skipping bad ones.
-+ */
-+static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes)
-+{
-+ size_t real_offset = 0;
-+
-+ if (mtd_block_isbad(mtd, real_offset))
-+ pr_warn("Base offset shouldn't be at bad block");
-+
-+ while (bytes >= mtd->erasesize) {
-+ bytes -= mtd->erasesize;
-+ real_offset += mtd->erasesize;
-+ while (mtd_block_isbad(mtd, real_offset)) {
-+ real_offset += mtd->erasesize;
-+
-+ if (real_offset >= mtd->size)
-+ return real_offset - mtd->erasesize;
-+ }
-+ }
-+
-+ real_offset += bytes;
-+
-+ return real_offset;
-+}
-+
- static const char *parser_trx_data_part_name(struct mtd_info *master,
- size_t offset)
- {
-@@ -86,21 +113,21 @@ static int parser_trx_parse(struct mtd_i
- if (trx.offset[2]) {
- part = &parts[curr_part++];
- part->name = "loader";
-- part->offset = trx.offset[i];
-+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
- i++;
- }
-
- if (trx.offset[i]) {
- part = &parts[curr_part++];
- part->name = "linux";
-- part->offset = trx.offset[i];
-+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
- i++;
- }
-
- if (trx.offset[i]) {
- part = &parts[curr_part++];
-- part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
-- part->offset = trx.offset[i];
-+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
-+ part->name = parser_trx_data_part_name(mtd, part->offset);
- i++;
- }
-
diff --git a/target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
deleted file mode 100644
index 852654d924..0000000000
--- a/target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: mtd: bcm47xxpart: detect T_Meter partition
-
-It can be found on many Netgear devices. It consists of many 0x30 blocks
-starting with 4D 54.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/parsers/bcm47xxpart.c
-+++ b/drivers/mtd/parsers/bcm47xxpart.c
-@@ -35,6 +35,7 @@
- #define NVRAM_HEADER 0x48534C46 /* FLSH */
- #define POT_MAGIC1 0x54544f50 /* POTT */
- #define POT_MAGIC2 0x504f /* OP */
-+#define T_METER_MAGIC 0x4D540000 /* MT */
- #define ML_MAGIC1 0x39685a42
- #define ML_MAGIC2 0x26594131
- #define TRX_MAGIC 0x30524448
-@@ -178,6 +179,15 @@ static int bcm47xxpart_parse(struct mtd_
- MTD_WRITEABLE);
- continue;
- }
-+
-+ /* T_Meter */
-+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
-+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
-+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) {
-+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset,
-+ MTD_WRITEABLE);
-+ continue;
-+ }
-
- /* TRX */
- if (buf[0x000 / 4] == TRX_MAGIC) {
diff --git a/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch
deleted file mode 100644
index a42dcc868f..0000000000
--- a/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
-Date: Tue, 24 Mar 2020 11:45:07 +0100
-Subject: [PATCH] generic: routerboot partition build bits (5.4)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch adds routerbootpart kernel build bits
-
-Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
----
- drivers/mtd/parsers/Kconfig | 9 +++++++++
- drivers/mtd/parsers/Makefile | 1 +
- 2 files changed, 10 insertions(+)
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -236,3 +236,12 @@ config MTD_SERCOMM_PARTS
- partition map. This partition table contains real partition
- offsets, which may differ from device to device depending on the
- number and location of bad blocks on NAND.
-+
-+config MTD_ROUTERBOOT_PARTS
-+ tristate "RouterBoot flash partition parser"
-+ depends on MTD && OF
-+ help
-+ MikroTik RouterBoot is implemented as a multi segment system on the
-+ flash, some of which are fixed and some of which are located at
-+ variable offsets. This parser handles both cases via properly
-+ formatted DTS.
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -17,3 +17,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpa
- obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
- obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
- obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o
-+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o
diff --git a/target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch b/target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch
deleted file mode 100644
index 063d3fa79c..0000000000
--- a/target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From ffbbe7d66872ff8957dad2136133e28a1fd5d437 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 7 Aug 2023 22:51:05 +0100
-Subject: [PATCH 01/15] dt-bindings: mtd: add basic bindings for UBI
-
-Add basic bindings for UBI devices and volumes.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- .../bindings/mtd/partitions/linux,ubi.yaml | 65 +++++++++++++++++++
- .../bindings/mtd/partitions/ubi-volume.yaml | 35 ++++++++++
- 2 files changed, 100 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
- create mode 100644 Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
-@@ -0,0 +1,65 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mtd/partitions/linux,ubi.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Unsorted Block Images
-+
-+description: |
-+ UBI ("Unsorted Block Images") is a volume management system for raw
-+ flash devices which manages multiple logical volumes on a single
-+ physical flash device and spreads the I/O load (i.e wear-leveling)
-+ across the whole flash chip.
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+allOf:
-+ - $ref: partition.yaml#
-+
-+properties:
-+ compatible:
-+ const: linux,ubi
-+
-+ volumes:
-+ type: object
-+ description: UBI Volumes
-+
-+ patternProperties:
-+ "^ubi-volume-.*$":
-+ $ref: /schemas/mtd/partitions/ubi-volume.yaml#
-+
-+ unevaluatedProperties: false
-+
-+required:
-+ - compatible
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ reg = <0x0 0x100000>;
-+ label = "bootloader";
-+ read-only;
-+ };
-+
-+ partition@100000 {
-+ reg = <0x100000 0x1ff00000>;
-+ label = "ubi";
-+ compatible = "linux,ubi";
-+
-+ volumes {
-+ ubi-volume-caldata {
-+ volid = <2>;
-+ volname = "rf";
-+ };
-+ };
-+ };
-+ };
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-@@ -0,0 +1,35 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mtd/partitions/ubi-volume.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: UBI volume
-+
-+description: |
-+ This binding describes a single UBI volume. Volumes can be matches either
-+ by their ID or their name, or both.
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+properties:
-+ volid:
-+ $ref: "/schemas/types.yaml#/definitions/uint32"
-+ description:
-+ Match UBI volume ID
-+
-+ volname:
-+ $ref: "/schemas/types.yaml#/definitions/string"
-+ description:
-+ Match UBI volume ID
-+
-+anyOf:
-+ - required:
-+ - volid
-+
-+ - required:
-+ - volname
-+
-+# This is a generic file other binding inherit from and extend
-+additionalProperties: true
diff --git a/target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch b/target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch
deleted file mode 100644
index 823c8e83b7..0000000000
--- a/target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From e4dad3aa5c3ab9c553555dd23c0b85f725f2eb51 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 7 Aug 2023 22:53:01 +0100
-Subject: [PATCH 02/15] dt-bindings: mtd: ubi-volume: allow UBI volumes to
- provide NVMEM
-
-UBI volumes may be used to contain NVMEM bits, typically device MAC
-addresses or wireless radio calibration data.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- .../devicetree/bindings/mtd/partitions/linux,ubi.yaml | 10 ++++++++++
- .../devicetree/bindings/mtd/partitions/ubi-volume.yaml | 5 +++++
- 2 files changed, 15 insertions(+)
-
---- a/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
-+++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
-@@ -59,6 +59,16 @@ examples:
- ubi-volume-caldata {
- volid = <2>;
- volname = "rf";
-+
-+ nvmem-layout {
-+ compatible = "fixed-layout";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ eeprom@0 {
-+ reg = <0x0 0x1000>;
-+ };
-+ };
- };
- };
- };
---- a/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-+++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-@@ -24,6 +24,11 @@ properties:
- description:
- Match UBI volume ID
-
-+ nvmem-layout:
-+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml#
-+ description:
-+ This container may reference an NVMEM layout parser.
-+
- anyOf:
- - required:
- - volid
diff --git a/target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch b/target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch
deleted file mode 100644
index eda3b108da..0000000000
--- a/target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch
+++ /dev/null
@@ -1,225 +0,0 @@
-From e5cf19bd8204925f3bd2067df9e867313eac388b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 1 May 2023 11:57:51 +0100
-Subject: [PATCH 03/15] mtd: ubi: block: use notifier to create ubiblock from
- parameter
-
-Use UBI_VOLUME_ADDED notification to create ubiblock device specified
-on kernel cmdline or module parameter.
-This makes thing more simple and has the advantage that ubiblock devices
-on volumes which are not present at the time the ubi module is probed
-will still be created.
-
-Suggested-by: Zhihao Cheng <chengzhihao1@huawei.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 154 ++++++++++++++++++++++------------------
- 1 file changed, 85 insertions(+), 69 deletions(-)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -33,6 +33,7 @@
- #include <linux/kernel.h>
- #include <linux/list.h>
- #include <linux/mutex.h>
-+#include <linux/namei.h>
- #include <linux/slab.h>
- #include <linux/mtd/ubi.h>
- #include <linux/workqueue.h>
-@@ -67,10 +68,10 @@ struct ubiblock_pdu {
- };
-
- /* Numbers of elements set in the @ubiblock_param array */
--static int ubiblock_devs __initdata;
-+static int ubiblock_devs;
-
- /* MTD devices specification parameters */
--static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES] __initdata;
-+static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES];
-
- struct ubiblock {
- struct ubi_volume_desc *desc;
-@@ -504,7 +505,7 @@ int ubiblock_remove(struct ubi_volume_in
- }
-
- /* Found a device, let's lock it so we can check if it's busy */
-- mutex_lock(&dev->dev_mutex);
-+ mutex_lock_nested(&dev->dev_mutex, SINGLE_DEPTH_NESTING);
- if (dev->refcnt > 0) {
- ret = -EBUSY;
- goto out_unlock_dev;
-@@ -567,6 +568,85 @@ static int ubiblock_resize(struct ubi_vo
- return 0;
- }
-
-+static bool
-+match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id)
-+{
-+ int err, len;
-+ struct path path;
-+ struct kstat stat;
-+
-+ if (ubi_num == -1) {
-+ /* No ubi num, name must be a vol device path */
-+ err = kern_path(name, LOOKUP_FOLLOW, &path);
-+ if (err)
-+ return false;
-+
-+ err = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
-+ path_put(&path);
-+ if (err)
-+ return false;
-+
-+ if (!S_ISCHR(stat.mode))
-+ return false;
-+
-+ if (vi->ubi_num != ubi_major2num(MAJOR(stat.rdev)))
-+ return false;
-+
-+ if (vi->vol_id != MINOR(stat.rdev) - 1)
-+ return false;
-+
-+ return true;
-+ }
-+
-+ if (vol_id == -1) {
-+ if (vi->ubi_num != ubi_num)
-+ return false;
-+
-+ len = strnlen(name, UBI_VOL_NAME_MAX + 1);
-+ if (len < 1 || vi->name_len != len)
-+ return false;
-+
-+ if (strcmp(name, vi->name))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ if (vi->ubi_num != ubi_num)
-+ return false;
-+
-+ if (vi->vol_id != vol_id)
-+ return false;
-+
-+ return true;
-+}
-+
-+static void
-+ubiblock_create_from_param(struct ubi_volume_info *vi)
-+{
-+ int i, ret = 0;
-+ struct ubiblock_param *p;
-+
-+ /*
-+ * Iterate over ubiblock cmdline parameters. If a parameter matches the
-+ * newly added volume create the ubiblock device for it.
-+ */
-+ for (i = 0; i < ubiblock_devs; i++) {
-+ p = &ubiblock_param[i];
-+
-+ if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id))
-+ continue;
-+
-+ ret = ubiblock_create(vi);
-+ if (ret) {
-+ pr_err(
-+ "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n",
-+ vi->name, p->ubi_num, p->vol_id, ret);
-+ }
-+ break;
-+ }
-+}
-+
- static int ubiblock_notify(struct notifier_block *nb,
- unsigned long notification_type, void *ns_ptr)
- {
-@@ -574,10 +654,7 @@ static int ubiblock_notify(struct notifi
-
- switch (notification_type) {
- case UBI_VOLUME_ADDED:
-- /*
-- * We want to enforce explicit block device creation for
-- * volumes, so when a volume is added we do nothing.
-- */
-+ ubiblock_create_from_param(&nt->vi);
- break;
- case UBI_VOLUME_REMOVED:
- ubiblock_remove(&nt->vi);
-@@ -603,56 +680,6 @@ static struct notifier_block ubiblock_no
- .notifier_call = ubiblock_notify,
- };
-
--static struct ubi_volume_desc * __init
--open_volume_desc(const char *name, int ubi_num, int vol_id)
--{
-- if (ubi_num == -1)
-- /* No ubi num, name must be a vol device path */
-- return ubi_open_volume_path(name, UBI_READONLY);
-- else if (vol_id == -1)
-- /* No vol_id, must be vol_name */
-- return ubi_open_volume_nm(ubi_num, name, UBI_READONLY);
-- else
-- return ubi_open_volume(ubi_num, vol_id, UBI_READONLY);
--}
--
--static void __init ubiblock_create_from_param(void)
--{
-- int i, ret = 0;
-- struct ubiblock_param *p;
-- struct ubi_volume_desc *desc;
-- struct ubi_volume_info vi;
--
-- /*
-- * If there is an error creating one of the ubiblocks, continue on to
-- * create the following ubiblocks. This helps in a circumstance where
-- * the kernel command-line specifies multiple block devices and some
-- * may be broken, but we still want the working ones to come up.
-- */
-- for (i = 0; i < ubiblock_devs; i++) {
-- p = &ubiblock_param[i];
--
-- desc = open_volume_desc(p->name, p->ubi_num, p->vol_id);
-- if (IS_ERR(desc)) {
-- pr_err(
-- "UBI: block: can't open volume on ubi%d_%d, err=%ld\n",
-- p->ubi_num, p->vol_id, PTR_ERR(desc));
-- continue;
-- }
--
-- ubi_get_volume_info(desc, &vi);
-- ubi_close_volume(desc);
--
-- ret = ubiblock_create(&vi);
-- if (ret) {
-- pr_err(
-- "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n",
-- vi.name, p->ubi_num, p->vol_id, ret);
-- continue;
-- }
-- }
--}
--
- static void ubiblock_remove_all(void)
- {
- struct ubiblock *next;
-@@ -678,18 +705,7 @@ int __init ubiblock_init(void)
- if (ubiblock_major < 0)
- return ubiblock_major;
-
-- /*
-- * Attach block devices from 'block=' module param.
-- * Even if one block device in the param list fails to come up,
-- * still allow the module to load and leave any others up.
-- */
-- ubiblock_create_from_param();
--
-- /*
-- * Block devices are only created upon user requests, so we ignore
-- * existing volumes.
-- */
-- ret = ubi_register_volume_notifier(&ubiblock_notifier, 1);
-+ ret = ubi_register_volume_notifier(&ubiblock_notifier, 0);
- if (ret)
- goto err_unreg;
- return 0;
diff --git a/target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch b/target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch
deleted file mode 100644
index 6e10e5ebed..0000000000
--- a/target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch
+++ /dev/null
@@ -1,264 +0,0 @@
-From 471a17d8d1b838092d1a76e48cdce8b5b67ff809 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 27 Nov 2023 01:54:28 +0000
-Subject: [PATCH 04/15] mtd: ubi: attach from device tree
-
-Introduce device tree compatible 'linux,ubi' and attach compatible MTD
-devices using the MTD add notifier. This is needed for a UBI device to
-be available early at boot (and not only after late_initcall), so
-volumes on them can be used eg. as NVMEM providers for other drivers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/build.c | 146 ++++++++++++++++++++++++++++------------
- drivers/mtd/ubi/cdev.c | 2 +-
- drivers/mtd/ubi/ubi.h | 2 +-
- 3 files changed, 106 insertions(+), 44 deletions(-)
-
---- a/drivers/mtd/ubi/build.c
-+++ b/drivers/mtd/ubi/build.c
-@@ -27,6 +27,7 @@
- #include <linux/log2.h>
- #include <linux/kthread.h>
- #include <linux/kernel.h>
-+#include <linux/of.h>
- #include <linux/slab.h>
- #include <linux/major.h>
- #include "ubi.h"
-@@ -1071,6 +1072,7 @@ out_free:
- * ubi_detach_mtd_dev - detach an MTD device.
- * @ubi_num: UBI device number to detach from
- * @anyway: detach MTD even if device reference count is not zero
-+ * @have_lock: called by MTD notifier holding mtd_table_mutex
- *
- * This function destroys an UBI device number @ubi_num and detaches the
- * underlying MTD device. Returns zero in case of success and %-EBUSY if the
-@@ -1080,7 +1082,7 @@ out_free:
- * Note, the invocations of this function has to be serialized by the
- * @ubi_devices_mutex.
- */
--int ubi_detach_mtd_dev(int ubi_num, int anyway)
-+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock)
- {
- struct ubi_device *ubi;
-
-@@ -1136,7 +1138,11 @@ int ubi_detach_mtd_dev(int ubi_num, int
- vfree(ubi->peb_buf);
- vfree(ubi->fm_buf);
- ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index);
-- put_mtd_device(ubi->mtd);
-+ if (have_lock)
-+ __put_mtd_device(ubi->mtd);
-+ else
-+ put_mtd_device(ubi->mtd);
-+
- put_device(&ubi->dev);
- return 0;
- }
-@@ -1213,43 +1219,43 @@ static struct mtd_info * __init open_mtd
- return mtd;
- }
-
--static int __init ubi_init(void)
-+static void ubi_notify_add(struct mtd_info *mtd)
- {
-- int err, i, k;
-+ struct device_node *np = mtd_get_of_node(mtd);
-+ int err;
-
-- /* Ensure that EC and VID headers have correct size */
-- BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
-- BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
-+ if (!of_device_is_compatible(np, "linux,ubi"))
-+ return;
-
-- if (mtd_devs > UBI_MAX_DEVICES) {
-- pr_err("UBI error: too many MTD devices, maximum is %d\n",
-- UBI_MAX_DEVICES);
-- return -EINVAL;
-- }
-+ /*
-+ * we are already holding &mtd_table_mutex, but still need
-+ * to bump refcount
-+ */
-+ err = __get_mtd_device(mtd);
-+ if (err)
-+ return;
-
-- /* Create base sysfs directory and sysfs files */
-- err = class_register(&ubi_class);
-+ /* called while holding mtd_table_mutex */
-+ mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING);
-+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false);
-+ mutex_unlock(&ubi_devices_mutex);
- if (err < 0)
-- return err;
--
-- err = misc_register(&ubi_ctrl_cdev);
-- if (err) {
-- pr_err("UBI error: cannot register device\n");
-- goto out;
-- }
-+ __put_mtd_device(mtd);
-+}
-
-- ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
-- sizeof(struct ubi_wl_entry),
-- 0, 0, NULL);
-- if (!ubi_wl_entry_slab) {
-- err = -ENOMEM;
-- goto out_dev_unreg;
-- }
-+static void ubi_notify_remove(struct mtd_info *mtd)
-+{
-+ WARN(1, "mtd%d removed despite UBI still being attached", mtd->index);
-+}
-
-- err = ubi_debugfs_init();
-- if (err)
-- goto out_slab;
-+static struct mtd_notifier ubi_mtd_notifier = {
-+ .add = ubi_notify_add,
-+ .remove = ubi_notify_remove,
-+};
-
-+static int __init ubi_init_attach(void)
-+{
-+ int err, i, k;
-
- /* Attach MTD devices */
- for (i = 0; i < mtd_devs; i++) {
-@@ -1297,25 +1303,79 @@ static int __init ubi_init(void)
- }
- }
-
-+ return 0;
-+
-+out_detach:
-+ for (k = 0; k < i; k++)
-+ if (ubi_devices[k]) {
-+ mutex_lock(&ubi_devices_mutex);
-+ ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1, false);
-+ mutex_unlock(&ubi_devices_mutex);
-+ }
-+ return err;
-+}
-+#ifndef CONFIG_MTD_UBI_MODULE
-+late_initcall(ubi_init_attach);
-+#endif
-+
-+static int __init ubi_init(void)
-+{
-+ int err;
-+
-+ /* Ensure that EC and VID headers have correct size */
-+ BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
-+ BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
-+
-+ if (mtd_devs > UBI_MAX_DEVICES) {
-+ pr_err("UBI error: too many MTD devices, maximum is %d\n",
-+ UBI_MAX_DEVICES);
-+ return -EINVAL;
-+ }
-+
-+ /* Create base sysfs directory and sysfs files */
-+ err = class_register(&ubi_class);
-+ if (err < 0)
-+ return err;
-+
-+ err = misc_register(&ubi_ctrl_cdev);
-+ if (err) {
-+ pr_err("UBI error: cannot register device\n");
-+ goto out;
-+ }
-+
-+ ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
-+ sizeof(struct ubi_wl_entry),
-+ 0, 0, NULL);
-+ if (!ubi_wl_entry_slab) {
-+ err = -ENOMEM;
-+ goto out_dev_unreg;
-+ }
-+
-+ err = ubi_debugfs_init();
-+ if (err)
-+ goto out_slab;
-+
- err = ubiblock_init();
- if (err) {
- pr_err("UBI error: block: cannot initialize, error %d\n", err);
-
- /* See comment above re-ubi_is_module(). */
- if (ubi_is_module())
-- goto out_detach;
-+ goto out_slab;
-+ }
-+
-+ register_mtd_user(&ubi_mtd_notifier);
-+
-+ if (ubi_is_module()) {
-+ err = ubi_init_attach();
-+ if (err)
-+ goto out_mtd_notifier;
- }
-
- return 0;
-
--out_detach:
-- for (k = 0; k < i; k++)
-- if (ubi_devices[k]) {
-- mutex_lock(&ubi_devices_mutex);
-- ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
-- mutex_unlock(&ubi_devices_mutex);
-- }
-- ubi_debugfs_exit();
-+out_mtd_notifier:
-+ unregister_mtd_user(&ubi_mtd_notifier);
- out_slab:
- kmem_cache_destroy(ubi_wl_entry_slab);
- out_dev_unreg:
-@@ -1325,18 +1385,20 @@ out:
- pr_err("UBI error: cannot initialize UBI, error %d\n", err);
- return err;
- }
--late_initcall(ubi_init);
-+device_initcall(ubi_init);
-+
-
- static void __exit ubi_exit(void)
- {
- int i;
-
- ubiblock_exit();
-+ unregister_mtd_user(&ubi_mtd_notifier);
-
- for (i = 0; i < UBI_MAX_DEVICES; i++)
- if (ubi_devices[i]) {
- mutex_lock(&ubi_devices_mutex);
-- ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1);
-+ ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1, false);
- mutex_unlock(&ubi_devices_mutex);
- }
- ubi_debugfs_exit();
---- a/drivers/mtd/ubi/cdev.c
-+++ b/drivers/mtd/ubi/cdev.c
-@@ -1065,7 +1065,7 @@ static long ctrl_cdev_ioctl(struct file
- }
-
- mutex_lock(&ubi_devices_mutex);
-- err = ubi_detach_mtd_dev(ubi_num, 0);
-+ err = ubi_detach_mtd_dev(ubi_num, 0, false);
- mutex_unlock(&ubi_devices_mutex);
- break;
- }
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -939,7 +939,7 @@ int ubi_io_write_vid_hdr(struct ubi_devi
- int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
- int vid_hdr_offset, int max_beb_per1024,
- bool disable_fm);
--int ubi_detach_mtd_dev(int ubi_num, int anyway);
-+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock);
- struct ubi_device *ubi_get_device(int ubi_num);
- void ubi_put_device(struct ubi_device *ubi);
- struct ubi_device *ubi_get_by_major(int major);
diff --git a/target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch b/target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch
deleted file mode 100644
index d5da37b856..0000000000
--- a/target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch
+++ /dev/null
@@ -1,226 +0,0 @@
-From 2d664266cfdd114cc7a1fa28dd64275e99222455 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 8 Jun 2023 17:18:09 +0100
-Subject: [PATCH 05/15] mtd: ubi: introduce pre-removal notification for UBI
- volumes
-
-Introduce a new notification type UBI_VOLUME_SHUTDOWN to inform users
-that a volume is just about to be removed.
-This is needed because users (such as the NVMEM subsystem) expect that
-at the time their removal function is called, the parenting device is
-still available (for removal of sysfs nodes, for example, in case of
-NVMEM which otherwise WARNs on volume removal).
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 26 ++++++++++++++++++++++++++
- drivers/mtd/ubi/build.c | 20 +++++++++++++++-----
- drivers/mtd/ubi/kapi.c | 2 +-
- drivers/mtd/ubi/ubi.h | 2 ++
- drivers/mtd/ubi/vmt.c | 17 +++++++++++++++--
- include/linux/mtd/ubi.h | 2 ++
- 6 files changed, 61 insertions(+), 8 deletions(-)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -568,6 +568,29 @@ static int ubiblock_resize(struct ubi_vo
- return 0;
- }
-
-+static int ubiblock_shutdown(struct ubi_volume_info *vi)
-+{
-+ struct ubiblock *dev;
-+ struct gendisk *disk;
-+ int ret = 0;
-+
-+ mutex_lock(&devices_mutex);
-+ dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
-+ if (!dev) {
-+ ret = -ENODEV;
-+ goto out_unlock;
-+ }
-+ disk = dev->gd;
-+
-+out_unlock:
-+ mutex_unlock(&devices_mutex);
-+
-+ if (!ret)
-+ blk_mark_disk_dead(disk);
-+
-+ return ret;
-+};
-+
- static bool
- match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id)
- {
-@@ -659,6 +682,9 @@ static int ubiblock_notify(struct notifi
- case UBI_VOLUME_REMOVED:
- ubiblock_remove(&nt->vi);
- break;
-+ case UBI_VOLUME_SHUTDOWN:
-+ ubiblock_shutdown(&nt->vi);
-+ break;
- case UBI_VOLUME_RESIZED:
- ubiblock_resize(&nt->vi);
- break;
---- a/drivers/mtd/ubi/build.c
-+++ b/drivers/mtd/ubi/build.c
-@@ -89,7 +89,7 @@ static struct ubi_device *ubi_devices[UB
- /* Serializes UBI devices creations and removals */
- DEFINE_MUTEX(ubi_devices_mutex);
-
--/* Protects @ubi_devices and @ubi->ref_count */
-+/* Protects @ubi_devices, @ubi->ref_count and @ubi->is_dead */
- static DEFINE_SPINLOCK(ubi_devices_lock);
-
- /* "Show" method for files in '/<sysfs>/class/ubi/' */
-@@ -258,6 +258,9 @@ struct ubi_device *ubi_get_device(int ub
-
- spin_lock(&ubi_devices_lock);
- ubi = ubi_devices[ubi_num];
-+ if (ubi && ubi->is_dead)
-+ ubi = NULL;
-+
- if (ubi) {
- ubi_assert(ubi->ref_count >= 0);
- ubi->ref_count += 1;
-@@ -295,7 +298,7 @@ struct ubi_device *ubi_get_by_major(int
- spin_lock(&ubi_devices_lock);
- for (i = 0; i < UBI_MAX_DEVICES; i++) {
- ubi = ubi_devices[i];
-- if (ubi && MAJOR(ubi->cdev.dev) == major) {
-+ if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) {
- ubi_assert(ubi->ref_count >= 0);
- ubi->ref_count += 1;
- get_device(&ubi->dev);
-@@ -324,7 +327,7 @@ int ubi_major2num(int major)
- for (i = 0; i < UBI_MAX_DEVICES; i++) {
- struct ubi_device *ubi = ubi_devices[i];
-
-- if (ubi && MAJOR(ubi->cdev.dev) == major) {
-+ if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) {
- ubi_num = ubi->ubi_num;
- break;
- }
-@@ -511,7 +514,7 @@ static void ubi_free_volumes_from(struct
- int i;
-
- for (i = from; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
-- if (!ubi->volumes[i])
-+ if (!ubi->volumes[i] || ubi->volumes[i]->is_dead)
- continue;
- ubi_eba_replace_table(ubi->volumes[i], NULL);
- ubi_fastmap_destroy_checkmap(ubi->volumes[i]);
-@@ -1094,10 +1097,10 @@ int ubi_detach_mtd_dev(int ubi_num, int
- return -EINVAL;
-
- spin_lock(&ubi_devices_lock);
-- put_device(&ubi->dev);
- ubi->ref_count -= 1;
- if (ubi->ref_count) {
- if (!anyway) {
-+ ubi->ref_count += 1;
- spin_unlock(&ubi_devices_lock);
- return -EBUSY;
- }
-@@ -1105,6 +1108,13 @@ int ubi_detach_mtd_dev(int ubi_num, int
- ubi_err(ubi, "%s reference count %d, destroy anyway",
- ubi->ubi_name, ubi->ref_count);
- }
-+ ubi->is_dead = true;
-+ spin_unlock(&ubi_devices_lock);
-+
-+ ubi_notify_all(ubi, UBI_VOLUME_SHUTDOWN, NULL);
-+
-+ spin_lock(&ubi_devices_lock);
-+ put_device(&ubi->dev);
- ubi_devices[ubi_num] = NULL;
- spin_unlock(&ubi_devices_lock);
-
---- a/drivers/mtd/ubi/kapi.c
-+++ b/drivers/mtd/ubi/kapi.c
-@@ -152,7 +152,7 @@ struct ubi_volume_desc *ubi_open_volume(
-
- spin_lock(&ubi->volumes_lock);
- vol = ubi->volumes[vol_id];
-- if (!vol)
-+ if (!vol || vol->is_dead)
- goto out_unlock;
-
- err = -EBUSY;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -345,6 +345,7 @@ struct ubi_volume {
- int writers;
- int exclusive;
- int metaonly;
-+ bool is_dead;
-
- int reserved_pebs;
- int vol_type;
-@@ -564,6 +565,7 @@ struct ubi_device {
- spinlock_t volumes_lock;
- int ref_count;
- int image_seq;
-+ bool is_dead;
-
- int rsvd_pebs;
- int avail_pebs;
---- a/drivers/mtd/ubi/vmt.c
-+++ b/drivers/mtd/ubi/vmt.c
-@@ -59,7 +59,7 @@ static ssize_t vol_attribute_show(struct
- struct ubi_device *ubi = vol->ubi;
-
- spin_lock(&ubi->volumes_lock);
-- if (!ubi->volumes[vol->vol_id]) {
-+ if (!ubi->volumes[vol->vol_id] || ubi->volumes[vol->vol_id]->is_dead) {
- spin_unlock(&ubi->volumes_lock);
- return -ENODEV;
- }
-@@ -189,7 +189,7 @@ int ubi_create_volume(struct ubi_device
-
- /* Ensure that the name is unique */
- for (i = 0; i < ubi->vtbl_slots; i++)
-- if (ubi->volumes[i] &&
-+ if (ubi->volumes[i] && !ubi->volumes[i]->is_dead &&
- ubi->volumes[i]->name_len == req->name_len &&
- !strcmp(ubi->volumes[i]->name, req->name)) {
- ubi_err(ubi, "volume \"%s\" exists (ID %d)",
-@@ -352,6 +352,19 @@ int ubi_remove_volume(struct ubi_volume_
- err = -EBUSY;
- goto out_unlock;
- }
-+
-+ /*
-+ * Mark volume as dead at this point to prevent that anyone
-+ * can take a reference to the volume from now on.
-+ * This is necessary as we have to release the spinlock before
-+ * calling ubi_volume_notify.
-+ */
-+ vol->is_dead = true;
-+ spin_unlock(&ubi->volumes_lock);
-+
-+ ubi_volume_notify(ubi, vol, UBI_VOLUME_SHUTDOWN);
-+
-+ spin_lock(&ubi->volumes_lock);
- ubi->volumes[vol_id] = NULL;
- spin_unlock(&ubi->volumes_lock);
-
---- a/include/linux/mtd/ubi.h
-+++ b/include/linux/mtd/ubi.h
-@@ -192,6 +192,7 @@ struct ubi_device_info {
- * or a volume was removed)
- * @UBI_VOLUME_RESIZED: a volume has been re-sized
- * @UBI_VOLUME_RENAMED: a volume has been re-named
-+ * @UBI_VOLUME_SHUTDOWN: a volume is going to removed, shutdown users
- * @UBI_VOLUME_UPDATED: data has been written to a volume
- *
- * These constants define which type of event has happened when a volume
-@@ -202,6 +203,7 @@ enum {
- UBI_VOLUME_REMOVED,
- UBI_VOLUME_RESIZED,
- UBI_VOLUME_RENAMED,
-+ UBI_VOLUME_SHUTDOWN,
- UBI_VOLUME_UPDATED,
- };
-
diff --git a/target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch b/target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch
deleted file mode 100644
index 1322766965..0000000000
--- a/target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 3a041ee543cdf2e707a1dd72946cd6a583509b28 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 21 Jul 2023 19:26:37 +0100
-Subject: [PATCH 06/15] mtd: ubi: populate ubi volume fwnode
-
-Look for the 'volumes' subnode of an MTD partition attached to a UBI
-device and attach matching child nodes to UBI volumes.
-This allows UBI volumes to be referenced in device tree, e.g. for use
-as NVMEM providers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/vmt.c | 27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
---- a/drivers/mtd/ubi/vmt.c
-+++ b/drivers/mtd/ubi/vmt.c
-@@ -124,6 +124,31 @@ static void vol_release(struct device *d
- kfree(vol);
- }
-
-+static struct fwnode_handle *find_volume_fwnode(struct ubi_volume *vol)
-+{
-+ struct fwnode_handle *fw_vols, *fw_vol;
-+ const char *volname;
-+ u32 volid;
-+
-+ fw_vols = device_get_named_child_node(vol->dev.parent->parent, "volumes");
-+ if (!fw_vols)
-+ return NULL;
-+
-+ fwnode_for_each_child_node(fw_vols, fw_vol) {
-+ if (!fwnode_property_read_string(fw_vol, "volname", &volname) &&
-+ strncmp(volname, vol->name, vol->name_len))
-+ continue;
-+
-+ if (!fwnode_property_read_u32(fw_vol, "volid", &volid) &&
-+ vol->vol_id != volid)
-+ continue;
-+
-+ return fw_vol;
-+ }
-+
-+ return NULL;
-+}
-+
- /**
- * ubi_create_volume - create volume.
- * @ubi: UBI device description object
-@@ -223,6 +248,7 @@ int ubi_create_volume(struct ubi_device
- vol->name_len = req->name_len;
- memcpy(vol->name, req->name, vol->name_len);
- vol->ubi = ubi;
-+ device_set_node(&vol->dev, find_volume_fwnode(vol));
-
- /*
- * Finish all pending erases because there may be some LEBs belonging
-@@ -605,6 +631,7 @@ int ubi_add_volume(struct ubi_device *ub
- vol->dev.class = &ubi_class;
- vol->dev.groups = volume_dev_groups;
- dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
-+ device_set_node(&vol->dev, find_volume_fwnode(vol));
- err = device_register(&vol->dev);
- if (err) {
- cdev_del(&vol->cdev);
diff --git a/target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch b/target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch
deleted file mode 100644
index 59a1eb9374..0000000000
--- a/target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch
+++ /dev/null
@@ -1,246 +0,0 @@
-From 7eb6666348f3f2d1f7308c712fa5903cbe189401 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 8 Jun 2023 17:22:04 +0100
-Subject: [PATCH 07/15] mtd: ubi: provide NVMEM layer over UBI volumes
-
-In an ideal world we would like UBI to be used where ever possible on a
-NAND chip. And with UBI support in ARM Trusted Firmware and U-Boot it
-is possible to achieve an (almost-)all-UBI flash layout. Hence the need
-for a way to also use UBI volumes to store board-level constants, such
-as MAC addresses and calibration data of wireless interfaces.
-
-Add UBI volume NVMEM driver module exposing UBI volumes as NVMEM
-providers. Allow UBI devices to have a "volumes" firmware subnode with
-volumes which may be compatible with "nvmem-cells".
-Access to UBI volumes via the NVMEM interface at this point is
-read-only, and it is slow, opening and closing the UBI volume for each
-access due to limitations of the NVMEM provider API.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/Kconfig | 12 +++
- drivers/mtd/ubi/Makefile | 1 +
- drivers/mtd/ubi/nvmem.c | 188 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 201 insertions(+)
- create mode 100644 drivers/mtd/ubi/nvmem.c
-
---- a/drivers/mtd/ubi/Kconfig
-+++ b/drivers/mtd/ubi/Kconfig
-@@ -104,4 +104,16 @@ config MTD_UBI_BLOCK
-
- If in doubt, say "N".
-
-+config MTD_UBI_NVMEM
-+ tristate "UBI virtual NVMEM"
-+ default n
-+ depends on NVMEM
-+ help
-+ This option enabled an additional driver exposing UBI volumes as NVMEM
-+ providers, intended for platforms where UBI is part of the firmware
-+ specification and used to store also e.g. MAC addresses or board-
-+ specific Wi-Fi calibration data.
-+
-+ If in doubt, say "N".
-+
- endif # MTD_UBI
---- a/drivers/mtd/ubi/Makefile
-+++ b/drivers/mtd/ubi/Makefile
-@@ -7,3 +7,4 @@ ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap
- ubi-$(CONFIG_MTD_UBI_BLOCK) += block.o
-
- obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o
-+obj-$(CONFIG_MTD_UBI_NVMEM) += nvmem.o
---- /dev/null
-+++ b/drivers/mtd/ubi/nvmem.c
-@@ -0,0 +1,191 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+/* UBI NVMEM provider */
-+#include "ubi.h"
-+#include <linux/nvmem-provider.h>
-+#include <asm/div64.h>
-+
-+/* List of all NVMEM devices */
-+static LIST_HEAD(nvmem_devices);
-+static DEFINE_MUTEX(devices_mutex);
-+
-+struct ubi_nvmem {
-+ struct nvmem_device *nvmem;
-+ int ubi_num;
-+ int vol_id;
-+ int usable_leb_size;
-+ struct list_head list;
-+};
-+
-+static int ubi_nvmem_reg_read(void *priv, unsigned int from,
-+ void *val, size_t bytes)
-+{
-+ uint32_t offs, to_read, bytes_left;
-+ struct ubi_nvmem *unv = priv;
-+ struct ubi_volume_desc *desc;
-+ uint64_t lnum = from;
-+ int err = 0;
-+
-+ desc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY);
-+ if (IS_ERR(desc))
-+ return PTR_ERR(desc);
-+
-+ bytes_left = bytes;
-+ offs = do_div(lnum, unv->usable_leb_size);
-+ while (bytes_left) {
-+ to_read = unv->usable_leb_size - offs;
-+
-+ if (to_read > bytes_left)
-+ to_read = bytes_left;
-+
-+ err = ubi_read(desc, lnum, val, offs, to_read);
-+ if (err)
-+ break;
-+
-+ lnum += 1;
-+ offs = 0;
-+ bytes_left -= to_read;
-+ val += to_read;
-+ }
-+ ubi_close_volume(desc);
-+
-+ if (err)
-+ return err;
-+
-+ return bytes_left == 0 ? 0 : -EIO;
-+}
-+
-+static int ubi_nvmem_add(struct ubi_volume_info *vi)
-+{
-+ struct device_node *np = dev_of_node(vi->dev);
-+ struct nvmem_config config = {};
-+ struct ubi_nvmem *unv;
-+ int ret;
-+
-+ if (!np)
-+ return 0;
-+
-+ if (!of_get_child_by_name(np, "nvmem-layout"))
-+ return 0;
-+
-+ if (WARN_ON_ONCE(vi->usable_leb_size <= 0) ||
-+ WARN_ON_ONCE(vi->size <= 0))
-+ return -EINVAL;
-+
-+ unv = kzalloc(sizeof(struct ubi_nvmem), GFP_KERNEL);
-+ if (!unv)
-+ return -ENOMEM;
-+
-+ config.id = NVMEM_DEVID_NONE;
-+ config.dev = vi->dev;
-+ config.name = dev_name(vi->dev);
-+ config.owner = THIS_MODULE;
-+ config.priv = unv;
-+ config.reg_read = ubi_nvmem_reg_read;
-+ config.size = vi->usable_leb_size * vi->size;
-+ config.word_size = 1;
-+ config.stride = 1;
-+ config.read_only = true;
-+ config.root_only = true;
-+ config.ignore_wp = true;
-+ config.of_node = np;
-+
-+ unv->ubi_num = vi->ubi_num;
-+ unv->vol_id = vi->vol_id;
-+ unv->usable_leb_size = vi->usable_leb_size;
-+ unv->nvmem = nvmem_register(&config);
-+ if (IS_ERR(unv->nvmem)) {
-+ ret = dev_err_probe(vi->dev, PTR_ERR(unv->nvmem),
-+ "Failed to register NVMEM device\n");
-+ kfree(unv);
-+ return ret;
-+ }
-+
-+ mutex_lock(&devices_mutex);
-+ list_add_tail(&unv->list, &nvmem_devices);
-+ mutex_unlock(&devices_mutex);
-+
-+ return 0;
-+}
-+
-+static void ubi_nvmem_remove(struct ubi_volume_info *vi)
-+{
-+ struct ubi_nvmem *unv_c, *unv = NULL;
-+
-+ mutex_lock(&devices_mutex);
-+ list_for_each_entry(unv_c, &nvmem_devices, list)
-+ if (unv_c->ubi_num == vi->ubi_num && unv_c->vol_id == vi->vol_id) {
-+ unv = unv_c;
-+ break;
-+ }
-+
-+ if (!unv) {
-+ mutex_unlock(&devices_mutex);
-+ return;
-+ }
-+
-+ list_del(&unv->list);
-+ mutex_unlock(&devices_mutex);
-+ nvmem_unregister(unv->nvmem);
-+ kfree(unv);
-+}
-+
-+/**
-+ * nvmem_notify - UBI notification handler.
-+ * @nb: registered notifier block
-+ * @l: notification type
-+ * @ns_ptr: pointer to the &struct ubi_notification object
-+ */
-+static int nvmem_notify(struct notifier_block *nb, unsigned long l,
-+ void *ns_ptr)
-+{
-+ struct ubi_notification *nt = ns_ptr;
-+
-+ switch (l) {
-+ case UBI_VOLUME_RESIZED:
-+ ubi_nvmem_remove(&nt->vi);
-+ fallthrough;
-+ case UBI_VOLUME_ADDED:
-+ ubi_nvmem_add(&nt->vi);
-+ break;
-+ case UBI_VOLUME_SHUTDOWN:
-+ ubi_nvmem_remove(&nt->vi);
-+ break;
-+ default:
-+ break;
-+ }
-+ return NOTIFY_OK;
-+}
-+
-+static struct notifier_block nvmem_notifier = {
-+ .notifier_call = nvmem_notify,
-+};
-+
-+static int __init ubi_nvmem_init(void)
-+{
-+ return ubi_register_volume_notifier(&nvmem_notifier, 0);
-+}
-+
-+static void __exit ubi_nvmem_exit(void)
-+{
-+ struct ubi_nvmem *unv, *tmp;
-+
-+ mutex_lock(&devices_mutex);
-+ list_for_each_entry_safe(unv, tmp, &nvmem_devices, list) {
-+ nvmem_unregister(unv->nvmem);
-+ list_del(&unv->list);
-+ kfree(unv);
-+ }
-+ mutex_unlock(&devices_mutex);
-+
-+ ubi_unregister_volume_notifier(&nvmem_notifier);
-+}
-+
-+module_init(ubi_nvmem_init);
-+module_exit(ubi_nvmem_exit);
-+MODULE_DESCRIPTION("NVMEM layer over UBI volumes");
-+MODULE_AUTHOR("Daniel Golle");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch b/target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch
deleted file mode 100644
index d0727faf3d..0000000000
--- a/target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 9ffc1d7d73609a89eb264d6066340f8b7b3b0ebe Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 7 Aug 2023 21:19:45 +0100
-Subject: [PATCH 08/15] dt-bindings: block: add basic bindings for block
- devices
-
-Add bindings for block devices which are used to allow referencing
-nvmem bits on them.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- .../bindings/block/block-device.yaml | 22 ++++++++
- .../devicetree/bindings/block/partition.yaml | 50 +++++++++++++++++++
- .../devicetree/bindings/block/partitions.yaml | 20 ++++++++
- 3 files changed, 92 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/block/block-device.yaml
- create mode 100644 Documentation/devicetree/bindings/block/partition.yaml
- create mode 100644 Documentation/devicetree/bindings/block/partitions.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/block/block-device.yaml
-@@ -0,0 +1,22 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/block/block-device.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: block storage device
-+
-+description: |
-+ This binding is generic and describes a block-oriented storage device.
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+properties:
-+ partitions:
-+ $ref: /schemas/block/partitions.yaml
-+
-+ nvmem-layout:
-+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml#
-+
-+unevaluatedProperties: false
---- /dev/null
-+++ b/Documentation/devicetree/bindings/block/partition.yaml
-@@ -0,0 +1,50 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/block/partition.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Partition on a block device
-+
-+description: |
-+ This binding describes a partition on a block device.
-+ Partitions may be matched by a combination of partition number, name,
-+ and UUID.
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+properties:
-+ $nodename:
-+ pattern: '^block-partition-.+$'
-+
-+ partnum:
-+ description:
-+ Matches partition by number if present.
-+
-+ partname:
-+ "$ref": "/schemas/types.yaml#/definitions/string"
-+ description:
-+ Matches partition by PARTNAME if present.
-+
-+ uuid:
-+ "$ref": "/schemas/types.yaml#/definitions/string"
-+ description:
-+ Matches partition by PARTUUID if present.
-+
-+ nvmem-layout:
-+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml#
-+ description:
-+ This container may reference an NVMEM layout parser.
-+
-+anyOf:
-+ - required:
-+ - partnum
-+
-+ - required:
-+ - partname
-+
-+ - required:
-+ - uuid
-+
-+unevaluatedProperties: false
---- /dev/null
-+++ b/Documentation/devicetree/bindings/block/partitions.yaml
-@@ -0,0 +1,20 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/block/partitions.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Partitions on block devices
-+
-+description: |
-+ This binding is generic and describes the content of the partitions container
-+ node.
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+patternProperties:
-+ "^block-partition-.+$":
-+ $ref: partition.yaml
-+
-+unevaluatedProperties: false
diff --git a/target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch b/target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch
deleted file mode 100644
index 8aa5cba678..0000000000
--- a/target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 614f4f6fdda09e30ecf7ef6c8091579db15018cb Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 21 Jul 2023 17:51:03 +0100
-Subject: [PATCH 09/15] block: partitions: populate fwnode
-
-Let block partitions to be represented by a firmware node and hence
-allow them to being referenced e.g. for use with blk-nvmem.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- block/partitions/core.c | 41 +++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
-
---- a/block/partitions/core.c
-+++ b/block/partitions/core.c
-@@ -10,6 +10,8 @@
- #include <linux/ctype.h>
- #include <linux/vmalloc.h>
- #include <linux/raid/detect.h>
-+#include <linux/property.h>
-+
- #include "check.h"
-
- static int (*check_part[])(struct parsed_partitions *) = {
-@@ -298,6 +300,43 @@ static ssize_t whole_disk_show(struct de
- }
- static DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL);
-
-+static struct fwnode_handle *find_partition_fwnode(struct block_device *bdev)
-+{
-+ struct fwnode_handle *fw_parts, *fw_part;
-+ struct device *ddev = disk_to_dev(bdev->bd_disk);
-+ const char *partname, *uuid;
-+ u32 partno;
-+
-+ fw_parts = device_get_named_child_node(ddev, "partitions");
-+ if (!fw_parts)
-+ fw_parts = device_get_named_child_node(ddev->parent, "partitions");
-+
-+ if (!fw_parts)
-+ return NULL;
-+
-+ fwnode_for_each_child_node(fw_parts, fw_part) {
-+ if (!fwnode_property_read_string(fw_part, "uuid", &uuid) &&
-+ (!bdev->bd_meta_info || strncmp(uuid,
-+ bdev->bd_meta_info->uuid,
-+ PARTITION_META_INFO_UUIDLTH)))
-+ continue;
-+
-+ if (!fwnode_property_read_string(fw_part, "partname", &partname) &&
-+ (!bdev->bd_meta_info || strncmp(partname,
-+ bdev->bd_meta_info->volname,
-+ PARTITION_META_INFO_VOLNAMELTH)))
-+ continue;
-+
-+ if (!fwnode_property_read_u32(fw_part, "partno", &partno) &&
-+ bdev->bd_partno != partno)
-+ continue;
-+
-+ return fw_part;
-+ }
-+
-+ return NULL;
-+}
-+
- /*
- * Must be called either with open_mutex held, before a disk can be opened or
- * after all disk users are gone.
-@@ -380,6 +419,8 @@ static struct block_device *add_partitio
- goto out_put;
- }
-
-+ device_set_node(pdev, find_partition_fwnode(bdev));
-+
- /* delay uevent until 'holders' subdir is created */
- dev_set_uevent_suppress(pdev, 1);
- err = device_add(pdev);
diff --git a/target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
deleted file mode 100644
index 4cbec14f5c..0000000000
--- a/target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 65f3ff9672ccd5ee78937047e7a2fc696eee1c8f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 13 Jul 2023 04:07:16 +0100
-Subject: [PATCH 10/15] block: add new genhd flag GENHD_FL_NVMEM
-
-Add new flag to destinguish block devices which may act as an NVMEM
-provider.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- include/linux/blkdev.h | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/include/linux/blkdev.h
-+++ b/include/linux/blkdev.h
-@@ -87,11 +87,13 @@ struct partition_meta_info {
- * ``GENHD_FL_NO_PART``: partition support is disabled. The kernel will not
- * scan for partitions from add_disk, and users can't add partitions manually.
- *
-+ * ``GENHD_FL_NVMEM``: the block device should be considered as NVMEM provider.
- */
- enum {
- GENHD_FL_REMOVABLE = 1 << 0,
- GENHD_FL_HIDDEN = 1 << 1,
- GENHD_FL_NO_PART = 1 << 2,
-+ GENHD_FL_NVMEM = 1 << 3,
- };
-
- enum {
diff --git a/target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch b/target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch
deleted file mode 100644
index e18b0c3a5c..0000000000
--- a/target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch
+++ /dev/null
@@ -1,235 +0,0 @@
-From b9936aa8a3775c2027f655d91a206d0e6e1c7ec0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 11 Jul 2023 00:17:31 +0100
-Subject: [PATCH 11/15] block: implement NVMEM provider
-
-On embedded devices using an eMMC it is common that one or more partitions
-on the eMMC are used to store MAC addresses and Wi-Fi calibration EEPROM
-data. Allow referencing the partition in device tree for the kernel and
-Wi-Fi drivers accessing it via the NVMEM layer.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- block/Kconfig | 9 +++
- block/Makefile | 1 +
- block/blk-nvmem.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 196 insertions(+)
- create mode 100644 block/blk-nvmem.c
-
---- a/block/Kconfig
-+++ b/block/Kconfig
-@@ -203,6 +203,15 @@ config BLK_INLINE_ENCRYPTION_FALLBACK
- by falling back to the kernel crypto API when inline
- encryption hardware is not present.
-
-+config BLK_NVMEM
-+ bool "Block device NVMEM provider"
-+ depends on OF
-+ depends on NVMEM
-+ help
-+ Allow block devices (or partitions) to act as NVMEM prodivers,
-+ typically used with eMMC to store MAC addresses or Wi-Fi
-+ calibration data on embedded devices.
-+
- source "block/partitions/Kconfig"
-
- config BLOCK_COMPAT
---- a/block/Makefile
-+++ b/block/Makefile
-@@ -35,6 +35,7 @@ obj-$(CONFIG_BLK_DEV_ZONED) += blk-zoned
- obj-$(CONFIG_BLK_WBT) += blk-wbt.o
- obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o
- obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o
-+obj-$(CONFIG_BLK_NVMEM) += blk-nvmem.o
- obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o
- obj-$(CONFIG_BLK_PM) += blk-pm.o
- obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += blk-crypto.o blk-crypto-profile.o \
---- /dev/null
-+++ b/block/blk-nvmem.c
-@@ -0,0 +1,186 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * block device NVMEM provider
-+ *
-+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
-+ *
-+ * Useful on devices using a partition on an eMMC for MAC addresses or
-+ * Wi-Fi calibration EEPROM data.
-+ */
-+
-+#include "blk.h"
-+#include <linux/nvmem-provider.h>
-+#include <linux/of.h>
-+#include <linux/pagemap.h>
-+#include <linux/property.h>
-+
-+/* List of all NVMEM devices */
-+static LIST_HEAD(nvmem_devices);
-+static DEFINE_MUTEX(devices_mutex);
-+
-+struct blk_nvmem {
-+ struct nvmem_device *nvmem;
-+ struct block_device *bdev;
-+ struct list_head list;
-+};
-+
-+static int blk_nvmem_reg_read(void *priv, unsigned int from,
-+ void *val, size_t bytes)
-+{
-+ unsigned long offs = from & ~PAGE_MASK, to_read;
-+ pgoff_t f_index = from >> PAGE_SHIFT;
-+ struct address_space *mapping;
-+ struct blk_nvmem *bnv = priv;
-+ size_t bytes_left = bytes;
-+ struct folio *folio;
-+ void *p;
-+ int ret;
-+
-+ if (!bnv->bdev)
-+ return -ENODEV;
-+
-+ if (!bnv->bdev->bd_disk)
-+ return -EINVAL;
-+
-+ if (!bnv->bdev->bd_disk->fops)
-+ return -EIO;
-+
-+ if (!bnv->bdev->bd_disk->fops->open)
-+ return -EIO;
-+
-+ ret = bnv->bdev->bd_disk->fops->open(bnv->bdev, FMODE_READ);
-+ if (ret)
-+ return ret;
-+
-+ mapping = bnv->bdev->bd_inode->i_mapping;
-+
-+ while (bytes_left) {
-+ folio = read_mapping_folio(mapping, f_index++, NULL);
-+ if (IS_ERR(folio)) {
-+ ret = PTR_ERR(folio);
-+ goto err_release_bdev;
-+ }
-+ to_read = min_t(unsigned long, bytes_left, PAGE_SIZE - offs);
-+ p = folio_address(folio) + offset_in_folio(folio, offs);
-+ memcpy(val, p, to_read);
-+ offs = 0;
-+ bytes_left -= to_read;
-+ val += to_read;
-+ folio_put(folio);
-+ }
-+
-+err_release_bdev:
-+ bnv->bdev->bd_disk->fops->release(bnv->bdev->bd_disk, FMODE_READ);
-+
-+ return ret;
-+}
-+
-+static int blk_nvmem_register(struct device *dev, struct class_interface *iface)
-+{
-+ struct device_node *np = dev_of_node(dev);
-+ struct block_device *bdev = dev_to_bdev(dev);
-+ struct nvmem_config config = {};
-+ struct blk_nvmem *bnv;
-+
-+ /* skip devices which do not have a device tree node */
-+ if (!np)
-+ return 0;
-+
-+ /* skip devices without an nvmem layout defined */
-+ if (!of_get_child_by_name(np, "nvmem-layout"))
-+ return 0;
-+
-+ /*
-+ * skip devices which don't have GENHD_FL_NVMEM set
-+ *
-+ * This flag is used for mtdblock and ubiblock devices because
-+ * both, MTD and UBI already implement their own NVMEM provider.
-+ * To avoid registering multiple NVMEM providers for the same
-+ * device node, don't register the block NVMEM provider for them.
-+ */
-+ if (!(bdev->bd_disk->flags & GENHD_FL_NVMEM))
-+ return 0;
-+
-+ /*
-+ * skip block device too large to be represented as NVMEM devices
-+ * which are using an 'int' as address
-+ */
-+ if (bdev_nr_bytes(bdev) > INT_MAX)
-+ return -EFBIG;
-+
-+ bnv = kzalloc(sizeof(struct blk_nvmem), GFP_KERNEL);
-+ if (!bnv)
-+ return -ENOMEM;
-+
-+ config.id = NVMEM_DEVID_NONE;
-+ config.dev = &bdev->bd_device;
-+ config.name = dev_name(&bdev->bd_device);
-+ config.owner = THIS_MODULE;
-+ config.priv = bnv;
-+ config.reg_read = blk_nvmem_reg_read;
-+ config.size = bdev_nr_bytes(bdev);
-+ config.word_size = 1;
-+ config.stride = 1;
-+ config.read_only = true;
-+ config.root_only = true;
-+ config.ignore_wp = true;
-+ config.of_node = to_of_node(dev->fwnode);
-+
-+ bnv->bdev = bdev;
-+ bnv->nvmem = nvmem_register(&config);
-+ if (IS_ERR(bnv->nvmem)) {
-+ dev_err_probe(&bdev->bd_device, PTR_ERR(bnv->nvmem),
-+ "Failed to register NVMEM device\n");
-+
-+ kfree(bnv);
-+ return PTR_ERR(bnv->nvmem);
-+ }
-+
-+ mutex_lock(&devices_mutex);
-+ list_add_tail(&bnv->list, &nvmem_devices);
-+ mutex_unlock(&devices_mutex);
-+
-+ return 0;
-+}
-+
-+static void blk_nvmem_unregister(struct device *dev, struct class_interface *iface)
-+{
-+ struct block_device *bdev = dev_to_bdev(dev);
-+ struct blk_nvmem *bnv_c, *bnv = NULL;
-+
-+ mutex_lock(&devices_mutex);
-+ list_for_each_entry(bnv_c, &nvmem_devices, list) {
-+ if (bnv_c->bdev == bdev) {
-+ bnv = bnv_c;
-+ break;
-+ }
-+ }
-+
-+ if (!bnv) {
-+ mutex_unlock(&devices_mutex);
-+ return;
-+ }
-+
-+ list_del(&bnv->list);
-+ mutex_unlock(&devices_mutex);
-+ nvmem_unregister(bnv->nvmem);
-+ kfree(bnv);
-+}
-+
-+static struct class_interface blk_nvmem_bus_interface __refdata = {
-+ .class = &block_class,
-+ .add_dev = &blk_nvmem_register,
-+ .remove_dev = &blk_nvmem_unregister,
-+};
-+
-+static int __init blk_nvmem_init(void)
-+{
-+ int ret;
-+
-+ ret = class_interface_register(&blk_nvmem_bus_interface);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+device_initcall(blk_nvmem_init);
diff --git a/target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch b/target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch
deleted file mode 100644
index 77c9bf91a5..0000000000
--- a/target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 86864bf8f40e84dc881c197ef470a88668329dbf Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 7 Aug 2023 21:21:45 +0100
-Subject: [PATCH 12/15] dt-bindings: mmc: mmc-card: add block device nodes
-
-Add nodes representing the block devices exposed by an MMC device
-including an example involving nvmem-cells.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- .../devicetree/bindings/mmc/mmc-card.yaml | 45 +++++++++++++++++++
- 1 file changed, 45 insertions(+)
-
---- a/Documentation/devicetree/bindings/mmc/mmc-card.yaml
-+++ b/Documentation/devicetree/bindings/mmc/mmc-card.yaml
-@@ -26,6 +26,18 @@ properties:
- Use this to indicate that the mmc-card has a broken hpi
- implementation, and that hpi should not be used.
-
-+ block:
-+ $ref: /schemas/block/block-device.yaml#
-+ description:
-+ Represents the block storage provided by an SD card or the
-+ main hardware partition of an eMMC.
-+
-+patternProperties:
-+ '^boot[0-9]+':
-+ $ref: /schemas/block/block-device.yaml#
-+ description:
-+ Represents a boot hardware partition on an eMMC.
-+
- required:
- - compatible
- - reg
-@@ -42,6 +54,39 @@ examples:
- compatible = "mmc-card";
- reg = <0>;
- broken-hpi;
-+
-+ block {
-+ partitions {
-+ cal_data: block-partition-rf {
-+ partnum = <3>;
-+ partname = "rf";
-+
-+ nvmem-layout {
-+ compatible = "fixed-layout";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ eeprom@0 {
-+ reg = <0x0 0x1000>;
-+ };
-+ };
-+ };
-+ };
-+ };
-+
-+ boot1 {
-+ nvmem-layout {
-+ compatible = "fixed-layout";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ macaddr: macaddr@a {
-+ compatible = "mac-base";
-+ reg = <0xa 0x6>;
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+ };
- };
- };
-
diff --git a/target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch b/target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch
deleted file mode 100644
index fada280437..0000000000
--- a/target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 644942a31719de674e2aa68f83d66bd8ae7e4fb7 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 13 Jul 2023 04:12:21 +0100
-Subject: [PATCH 13/15] mmc: core: set card fwnode_handle
-
-Set fwnode in case it isn't set yet and of_node is present.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mmc/core/bus.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mmc/core/bus.c
-+++ b/drivers/mmc/core/bus.c
-@@ -363,6 +363,8 @@ int mmc_add_card(struct mmc_card *card)
- mmc_add_card_debugfs(card);
- #endif
- card->dev.of_node = mmc_of_find_child_device(card->host, 0);
-+ if (card->dev.of_node && !card->dev.fwnode)
-+ card->dev.fwnode = &card->dev.of_node->fwnode;
-
- device_enable_async_suspend(&card->dev);
-
diff --git a/target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch b/target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch
deleted file mode 100644
index 386282459b..0000000000
--- a/target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From d9143f86330dd038fc48878558dd287ceee5d3d4 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 13 Jul 2023 04:13:04 +0100
-Subject: [PATCH 14/15] mmc: block: set fwnode of disk devices
-
-Set fwnode of disk devices to 'block', 'boot0' and 'boot1' subnodes of
-the mmc-card. This is done in preparation for having the eMMC act as
-NVMEM provider.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mmc/core/block.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/mmc/core/block.c
-+++ b/drivers/mmc/core/block.c
-@@ -2486,6 +2486,8 @@ static struct mmc_blk_data *mmc_blk_allo
- int area_type,
- unsigned int part_type)
- {
-+ struct fwnode_handle *fwnode;
-+ struct device *ddev;
- struct mmc_blk_data *md;
- int devidx, ret;
- char cap_str[10];
-@@ -2582,6 +2584,13 @@ static struct mmc_blk_data *mmc_blk_allo
-
- blk_queue_write_cache(md->queue.queue, cache_enabled, fua_enabled);
-
-+ ddev = disk_to_dev(md->disk);
-+ fwnode = device_get_named_child_node(subname ? md->parent->parent :
-+ md->parent,
-+ subname ? subname : "block");
-+ if (fwnode)
-+ device_set_node(ddev, fwnode);
-+
- string_get_size((u64)size, 512, STRING_UNITS_2,
- cap_str, sizeof(cap_str));
- pr_info("%s: %s %s %s %s\n",
diff --git a/target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch
deleted file mode 100644
index 41c257cdeb..0000000000
--- a/target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 322035ab2b0113d98b6c0ea788d971e0df2952a4 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 20 Jul 2023 17:36:44 +0100
-Subject: [PATCH 15/15] mmc: block: set GENHD_FL_NVMEM
-
-Set flag to consider MMC block devices as NVMEM providers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mmc/core/block.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mmc/core/block.c
-+++ b/drivers/mmc/core/block.c
-@@ -2540,6 +2540,7 @@ static struct mmc_blk_data *mmc_blk_allo
- md->disk->major = MMC_BLOCK_MAJOR;
- md->disk->minors = perdev_minors;
- md->disk->first_minor = devidx * perdev_minors;
-+ md->disk->flags = GENHD_FL_NVMEM;
- md->disk->fops = &mmc_bdops;
- md->disk->private_data = md;
- md->parent = parent;
diff --git a/target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
deleted file mode 100644
index 1b653fb735..0000000000
--- a/target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: disable cfi cmdset 0002 erase suspend
-
-on some platforms, erase suspend leads to data corruption and lockups when write
-ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh.
-rather than play whack-a-mole with a hard to reproduce issue on a variety of devices,
-simply disable erase suspend, as it will usually not produce any useful gain on
-the small filesystems used on embedded hardware.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/chips/cfi_cmdset_0002.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -908,7 +908,7 @@ static int get_chip(struct map_info *map
- return 0;
-
- case FL_ERASING:
-- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
-+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
- !(mode == FL_READY || mode == FL_POINT ||
- (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
- goto sleep;
diff --git a/target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch
deleted file mode 100644
index f2788c5214..0000000000
--- a/target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-From: George Kashperko <george@znau.edu.ua>
-Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data.
-
-Signed-off-by: George Kashperko <george@znau.edu.ua>
----
- drivers/mtd/chips/cfi_cmdset_0002.c | 1 +
- 1 file changed, 1 insertion(+)
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -2052,6 +2052,7 @@ static int __xipram do_write_buffer(stru
-
- /* Write Buffer Load */
- map_write(map, CMD(0x25), cmd_adr);
-+ (void) map_read(map, cmd_adr);
-
- chip->state = FL_WRITING_TO_BUFFER;
-
diff --git a/target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch
deleted file mode 100644
index 1e28077338..0000000000
--- a/target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: Disable software protection bits for Macronix flashes.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/spi-nor/spi-nor.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/macronix.c
-+++ b/drivers/mtd/spi-nor/macronix.c
-@@ -106,6 +106,7 @@ static void macronix_nor_default_init(st
- {
- nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
- nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
-+ nor->flags |= SNOR_F_HAS_LOCK;
- }
-
- static const struct spi_nor_fixups macronix_nor_fixups = {
diff --git a/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch
deleted file mode 100644
index 303e488433..0000000000
--- a/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From: Piotr Dymacz <pepe2k@gmail.com>
-Subject: kernel/mtd: add support for EON EN25Q128
-
-Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
----
- drivers/mtd/spi-nor/spi-nor.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/eon.c
-+++ b/drivers/mtd/spi-nor/eon.c
-@@ -17,6 +17,8 @@ static const struct flash_info eon_nor_p
- { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128) },
- { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128)
- NO_SFDP_FLAGS(SECT_4K) },
-+ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256)
-+ NO_SFDP_FLAGS(SECT_4K) },
- { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16)
- NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
- { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32)
diff --git a/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch b/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch
deleted file mode 100644
index 6740d1d7be..0000000000
--- a/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Christian Marangi <ansuelsmth@gmail.com>
-Subject: kernel/mtd: add support for EON EN25QX128A
-
-Add support for EON EN25QX128A with no flags as it does
-support SFDP parsing.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/mtd/spi-nor/spi-nor.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/eon.c
-+++ b/drivers/mtd/spi-nor/eon.c
-@@ -19,6 +19,7 @@ static const struct flash_info eon_nor_p
- NO_SFDP_FLAGS(SECT_4K) },
- { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256)
- NO_SFDP_FLAGS(SECT_4K) },
-+ { "en25qx128a", INFO(0x1c7118, 0, 64 * 1024, 256) },
- { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16)
- NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
- { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32)
diff --git a/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch
deleted file mode 100644
index 371f1a7276..0000000000
--- a/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From patchwork Thu Feb 6 17:19:41 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 1234465
-Date: Thu, 6 Feb 2020 19:19:41 +0200
-From: Daniel Golle <daniel@makrotopia.org>
-To: linux-mtd@lists.infradead.org
-Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip
-Message-ID: <20200206171941.GA2398@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>,
- <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>
-Cc: Eitan Cohen <eitan@neot-semadar.com>, Piotr Dymacz <pepe2k@gmail.com>,
- Tudor Ambarus <tudor.ambarus@microchip.com>
-Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org>
-Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org
-
-Add XT25F128B made by XTX Technology (Shenzhen) Limited.
-This chip supports dual and quad read and uniform 4K-byte erase.
-Verified on Teltonika RUT955 which comes with XT25F128B in recent
-versions of the device.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/mtd/spi-nor/spi-nor.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/spi-nor/Makefile
-+++ b/drivers/mtd/spi-nor/Makefile
-@@ -17,6 +17,7 @@ spi-nor-objs += sst.o
- spi-nor-objs += winbond.o
- spi-nor-objs += xilinx.o
- spi-nor-objs += xmc.o
-+spi-nor-objs += xtx.o
- spi-nor-$(CONFIG_DEBUG_FS) += debugfs.o
- obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o
-
---- /dev/null
-+++ b/drivers/mtd/spi-nor/xtx.c
-@@ -0,0 +1,17 @@
-+// SPDX-License-Identifier: GPL-2.0
-+#include <linux/mtd/spi-nor.h>
-+
-+#include "core.h"
-+
-+static const struct flash_info xtx_parts[] = {
-+ /* XTX Technology (Shenzhen) Limited */
-+ { "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256)
-+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
-+ SPI_NOR_QUAD_READ) },
-+};
-+
-+const struct spi_nor_manufacturer spi_nor_xtx = {
-+ .name = "xtx",
-+ .parts = xtx_parts,
-+ .nparts = ARRAY_SIZE(xtx_parts),
-+};
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -1636,6 +1636,7 @@ static const struct spi_nor_manufacturer
- &spi_nor_winbond,
- &spi_nor_xilinx,
- &spi_nor_xmc,
-+ &spi_nor_xtx,
- };
-
- static const struct flash_info spi_nor_generic_flash = {
---- a/drivers/mtd/spi-nor/core.h
-+++ b/drivers/mtd/spi-nor/core.h
-@@ -633,6 +633,7 @@ extern const struct spi_nor_manufacturer
- extern const struct spi_nor_manufacturer spi_nor_winbond;
- extern const struct spi_nor_manufacturer spi_nor_xilinx;
- extern const struct spi_nor_manufacturer spi_nor_xmc;
-+extern const struct spi_nor_manufacturer spi_nor_xtx;
-
- extern const struct attribute_group *spi_nor_sysfs_groups[];
-
diff --git a/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch
deleted file mode 100644
index 581e06190b..0000000000
--- a/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001
-From: Koen Vandeputte <koen.vandeputte@ncentric.com>
-Date: Mon, 6 Jan 2020 13:07:56 +0100
-Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05
-
-Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
----
- drivers/mtd/spi-nor/spi-nor.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/mtd/spi-nor/gigadevice.c
-+++ b/drivers/mtd/spi-nor/gigadevice.c
-@@ -34,6 +34,10 @@ static const struct spi_nor_fixups gd25q
- };
-
- static const struct flash_info gigadevice_nor_parts[] = {
-+ { "gd25q05", INFO(0xc84010, 0, 64 * 1024, 1)
-+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
-+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
-+ SPI_NOR_QUAD_READ) },
- { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32)
- FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
- NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
diff --git a/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch b/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch
deleted file mode 100644
index ddd3405ae7..0000000000
--- a/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From f8943df3beb0d3f9754bb35320c3a378727175a8 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Thu, 14 Jul 2022 08:38:07 +0200
-Subject: [PATCH] spi-nor/gigadevic: add gd25q512
-
----
- drivers/mtd/spi-nor/gigadevice.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/mtd/spi-nor/gigadevice.c
-+++ b/drivers/mtd/spi-nor/gigadevice.c
-@@ -71,6 +71,11 @@ static const struct flash_info gigadevic
- FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
- FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
- .fixups = &gd25q256_fixups },
-+ { "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024)
-+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
-+ FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
-+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
-+ SPI_NOR_QUAD_READ) },
- };
-
- const struct spi_nor_manufacturer spi_nor_gigadevice = {
diff --git a/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch b/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch
deleted file mode 100644
index d5ebe20309..0000000000
--- a/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 87363cc0e522de3294ea6ae10fb468d2a8d6fb2f Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:17:21 +0200
-Subject: [PATCH] spi-nor/esmt.c: add esmt f25l16pa
-
-This fixes support for Dongwon T&I DW02-412H which uses F25L16PA(2S)
-flash.
-
----
- drivers/mtd/spi-nor/esmt.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mtd/spi-nor/esmt.c
-+++ b/drivers/mtd/spi-nor/esmt.c
-@@ -10,6 +10,9 @@
-
- static const struct flash_info esmt_nor_parts[] = {
- /* ESMT */
-+ { "f25l16pa-2s", INFO(0x8c2115, 0, 64 * 1024, 32)
-+ FLAGS(SPI_NOR_HAS_LOCK)
-+ NO_SFDP_FLAGS(SECT_4K) },
- { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64)
- FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
- NO_SFDP_FLAGS(SECT_4K) },
diff --git a/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch b/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch
deleted file mode 100644
index e8583cc257..0000000000
--- a/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From f6b33d850f7f12555df2fa0e3349b33427bf5890 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:19:01 +0200
-Subject: [PATCH] spi-nor/xmc.c: add xm25qh128c
-
-The XMC XM25QH128C is a 16MB SPI NOR chip. The patch is verified on
-Ruijie RG-EW3200GX PRO.
-Datasheet available at https://www.xmcwh.com/uploads/435/XM25QH128C.pdf
-
----
- drivers/mtd/spi-nor/xmc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mtd/spi-nor/xmc.c
-+++ b/drivers/mtd/spi-nor/xmc.c
-@@ -16,6 +16,9 @@ static const struct flash_info xmc_nor_p
- { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256)
- NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ) },
-+ { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256)
-+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
-+ SPI_NOR_QUAD_READ) },
- };
-
- const struct spi_nor_manufacturer spi_nor_xmc = {
diff --git a/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch b/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch
deleted file mode 100644
index b8116db842..0000000000
--- a/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From a43b844cb40bf1b783055fdc81b7f991e21e7e76 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Wed, 13 Apr 2022 11:58:17 +0800
-Subject: [PATCH] mtd: spinand: add support for ESMT F50x1G41LB
-
-This patch adds support for ESMT F50L1G41LB and F50D1G41LB.
-It seems that ESMT likes to use random JEDEC ID from other vendors.
-Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from
-Micron. For this reason, the ESMT entry is named esmt_c8 with explicit
-JEDEC ID in variable name.
-
-Datasheets:
-https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf
-https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
----
- drivers/mtd/nand/spi/Makefile | 2 +-
- drivers/mtd/nand/spi/core.c | 1 +
- drivers/mtd/nand/spi/esmt.c | 89 +++++++++++++++++++++++++++++++++++
- include/linux/mtd/spinand.h | 1 +
- 4 files changed, 92 insertions(+), 1 deletion(-)
- create mode 100644 drivers/mtd/nand/spi/esmt.c
-
---- a/drivers/mtd/nand/spi/Makefile
-+++ b/drivers/mtd/nand/spi/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--spinand-objs := core.o ato.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
-+spinand-objs := core.o ato.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
- obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -938,6 +938,7 @@ static const struct nand_ops spinand_ops
-
- static const struct spinand_manufacturer *spinand_manufacturers[] = {
- &ato_spinand_manufacturer,
-+ &esmt_c8_spinand_manufacturer,
- &gigadevice_spinand_manufacturer,
- &macronix_spinand_manufacturer,
- &micron_spinand_manufacturer,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/esmt.c
-@@ -0,0 +1,89 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Author:
-+ * Chuanhong Guo <gch981213@gmail.com>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */
-+#define SPINAND_MFR_ESMT_C8 0xc8
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(write_cache_variants,
-+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(update_cache_variants,
-+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
-+
-+static int f50l1g41lb_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = 16 * section + 8;
-+ region->length = 8;
-+
-+ return 0;
-+}
-+
-+static int f50l1g41lb_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *region)
-+{
-+ if (section > 3)
-+ return -ERANGE;
-+
-+ region->offset = 16 * section + 2;
-+ region->length = 6;
-+
-+ return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops f50l1g41lb_ooblayout = {
-+ .ecc = f50l1g41lb_ooblayout_ecc,
-+ .free = f50l1g41lb_ooblayout_free,
-+};
-+
-+static const struct spinand_info esmt_c8_spinand_table[] = {
-+ SPINAND_INFO("F50L1G41LB",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(1, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)),
-+ SPINAND_INFO("F50D1G41LB",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(1, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)),
-+};
-+
-+static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = {
-+};
-+
-+const struct spinand_manufacturer esmt_c8_spinand_manufacturer = {
-+ .id = SPINAND_MFR_ESMT_C8,
-+ .name = "ESMT",
-+ .chips = esmt_c8_spinand_table,
-+ .nchips = ARRAY_SIZE(esmt_c8_spinand_table),
-+ .ops = &esmt_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -261,6 +261,7 @@ struct spinand_manufacturer {
-
- /* SPI NAND manufacturers */
- extern const struct spinand_manufacturer ato_spinand_manufacturer;
-+extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
- extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
- extern const struct spinand_manufacturer macronix_spinand_manufacturer;
- extern const struct spinand_manufacturer micron_spinand_manufacturer;
diff --git a/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch b/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch
deleted file mode 100644
index 81378fba86..0000000000
--- a/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch
+++ /dev/null
@@ -1,168 +0,0 @@
-From f32085fc0b87049491b07e198d924d738a1a2834 Mon Sep 17 00:00:00 2001
-From: Daniel Danzberger <daniel@dd-wrt.com>
-Date: Wed, 3 Aug 2022 17:31:03 +0200
-Subject: [PATCH] mtd: spinand: Add support for Etron EM73D044VCx
-
-Airoha is a new ARM platform based on Cortex-A53 which has recently been
-merged into linux-next.
-
-Due to BootROM limitations on this platform, the Cortex-A53 can't run in
-Aarch64 mode and code must be compiled for 32-Bit ARM.
-
-This support is based mostly on those linux-next commits backported
-for kernel 5.15.
-
-Patches:
-1 - platform support = linux-next
-2 - clock driver = linux-next
-3 - gpio driver = linux-next
-4 - linux,usable-memory-range dts support = linux-next
-5 - mtd spinand driver
-6 - spi driver
-7 - pci driver (kconfig only, uses mediatek PCI) = linux-next
-
-Still missing:
-- Ethernet driver
-- Sysupgrade support
-
-A.t.m there exists one subtarget EN7523 with only one evaluation
-board.
-
-The initramfs can be run with the following commands from u-boot:
--
-u-boot> setenv bootfile \
- openwrt-airoha-airoha_en7523-evb-initramfs-kernel.bin
-u-boot> tftpboot
-u-boot> bootm 0x81800000
--
-
-Submitted-by: Daniel Danzberger <daniel@dd-wrt.com>
-
---- a/drivers/mtd/nand/spi/Makefile
-+++ b/drivers/mtd/nand/spi/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--spinand-objs := core.o ato.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
-+spinand-objs := core.o ato.o esmt.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
- obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -939,6 +939,7 @@ static const struct nand_ops spinand_ops
- static const struct spinand_manufacturer *spinand_manufacturers[] = {
- &ato_spinand_manufacturer,
- &esmt_c8_spinand_manufacturer,
-+ &etron_spinand_manufacturer,
- &gigadevice_spinand_manufacturer,
- &macronix_spinand_manufacturer,
- &micron_spinand_manufacturer,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/etron.c
-@@ -0,0 +1,98 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+#define SPINAND_MFR_ETRON 0xd5
-+
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(write_cache_variants,
-+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(update_cache_variants,
-+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
-+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
-+
-+static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ if (section)
-+ return -ERANGE;
-+
-+ oobregion->offset = 72;
-+ oobregion->length = 56;
-+
-+ return 0;
-+}
-+
-+static int etron_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ if (section)
-+ return -ERANGE;
-+
-+ oobregion->offset = 1;
-+ oobregion->length = 71;
-+
-+ return 0;
-+}
-+
-+static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
-+{
-+ switch (status & STATUS_ECC_MASK) {
-+ case STATUS_ECC_NO_BITFLIPS:
-+ return 0;
-+
-+ case STATUS_ECC_HAS_BITFLIPS:
-+ /* Between 1-7 bitflips were corrected */
-+ return 7;
-+
-+ case STATUS_ECC_MASK:
-+ /* Maximum bitflips were corrected */
-+ return 8;
-+
-+ case STATUS_ECC_UNCOR_ERROR:
-+ return -EBADMSG;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static const struct mtd_ooblayout_ops etron_ooblayout = {
-+ .ecc = etron_ooblayout_ecc,
-+ .free = etron_ooblayout_free,
-+};
-+
-+static const struct spinand_info etron_spinand_table[] = {
-+ SPINAND_INFO("EM73D044VCx",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f),
-+ // bpc, pagesize, oobsize, pagesperblock, bperlun, maxbadplun, ppl, lpt, #t
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
-+};
-+
-+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
-+};
-+
-+const struct spinand_manufacturer etron_spinand_manufacturer = {
-+ .id = SPINAND_MFR_ETRON,
-+ .name = "Etron",
-+ .chips = etron_spinand_table,
-+ .nchips = ARRAY_SIZE(etron_spinand_table),
-+ .ops = &etron_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -262,6 +262,7 @@ struct spinand_manufacturer {
- /* SPI NAND manufacturers */
- extern const struct spinand_manufacturer ato_spinand_manufacturer;
- extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
-+extern const struct spinand_manufacturer etron_spinand_manufacturer;
- extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
- extern const struct spinand_manufacturer macronix_spinand_manufacturer;
- extern const struct spinand_manufacturer micron_spinand_manufacturer;
diff --git a/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch b/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch
deleted file mode 100644
index e1e4f25e11..0000000000
--- a/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From: Joe Mullally <jwmullally@gmail.com>
-Subject: mtd/spi-nor/xmc: add support for XMC XM25QH64C
-
-The XMC XM25QH64C is a 8MB SPI NOR chip. The patch is verified on TL-WPA8631P v3.
-Datasheet available at https://www.xmcwh.com/uploads/442/XM25QH64C.pdf
-
-Signed-off-by: Joe Mullally <jwmullally@gmail.com>
----
- drivers/mtd/spi-nor/xmc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/mtd/spi-nor/xmc.c
-+++ b/drivers/mtd/spi-nor/xmc.c
-@@ -13,6 +13,9 @@ static const struct flash_info xmc_nor_p
- { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128)
- NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ) },
-+ { "XM25QH64C", INFO(0x204017, 0, 64 * 1024, 128)
-+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
-+ SPI_NOR_QUAD_READ) },
- { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256)
- NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ) },
diff --git a/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
deleted file mode 100644
index 2eccb9d3bb..0000000000
--- a/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 36 insertions(+)
-
---- a/drivers/mtd/ubi/build.c
-+++ b/drivers/mtd/ubi/build.c
-@@ -1263,6 +1263,74 @@ static struct mtd_notifier ubi_mtd_notif
- .remove = ubi_notify_remove,
- };
-
-+
-+/*
-+ * This function tries attaching mtd partitions named either "ubi" or "data"
-+ * during boot.
-+ */
-+static void __init ubi_auto_attach(void)
-+{
-+ int err;
-+ struct mtd_info *mtd;
-+ loff_t offset = 0;
-+ size_t len;
-+ char magic[4];
-+
-+ /* try attaching mtd device named "ubi" or "data" */
-+ mtd = open_mtd_device("ubi");
-+ if (IS_ERR(mtd))
-+ mtd = open_mtd_device("data");
-+
-+ if (IS_ERR(mtd))
-+ return;
-+
-+ /* get the first not bad block */
-+ if (mtd_can_have_bb(mtd))
-+ while (mtd_block_isbad(mtd, offset)) {
-+ offset += mtd->erasesize;
-+
-+ if (offset > mtd->size) {
-+ pr_err("UBI error: Failed to find a non-bad "
-+ "block on mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+ }
-+
-+ /* check if the read from flash was successful */
-+ err = mtd_read(mtd, offset, 4, &len, (void *) magic);
-+ if ((err && !mtd_is_bitflip(err)) || len != 4) {
-+ pr_err("UBI error: unable to read from mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+
-+ /* check for a valid ubi magic */
-+ if (strncmp(magic, "UBI#", 4)) {
-+ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+
-+ /* don't auto-add media types where UBI doesn't makes sense */
-+ if (mtd->type != MTD_NANDFLASH &&
-+ mtd->type != MTD_NORFLASH &&
-+ mtd->type != MTD_DATAFLASH &&
-+ mtd->type != MTD_MLCNANDFLASH)
-+ goto cleanup;
-+
-+ mutex_lock(&ubi_devices_mutex);
-+ pr_notice("UBI: auto-attach mtd%d\n", mtd->index);
-+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false);
-+ mutex_unlock(&ubi_devices_mutex);
-+ if (err < 0) {
-+ pr_err("UBI error: cannot attach mtd%d\n", mtd->index);
-+ goto cleanup;
-+ }
-+
-+ return;
-+
-+cleanup:
-+ put_mtd_device(mtd);
-+}
-+
- static int __init ubi_init_attach(void)
- {
- int err, i, k;
-@@ -1313,6 +1381,12 @@ static int __init ubi_init_attach(void)
- }
- }
-
-+ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd
-+ * parameter was given */
-+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
-+ !ubi_is_module() && !mtd_devs)
-+ ubi_auto_attach();
-+
- return 0;
-
- out_detach:
diff --git a/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
deleted file mode 100644
index a43da2a572..0000000000
--- a/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: ubi: auto-create ubiblock device for rootfs
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 42 insertions(+)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -644,10 +644,47 @@ match_volume_desc(struct ubi_volume_info
- return true;
- }
-
-+#define UBIFS_NODE_MAGIC 0x06101831
-+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc)
-+{
-+ int ret;
-+ uint32_t magic_of, magic;
-+ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4);
-+ if (ret)
-+ return 0;
-+ magic = le32_to_cpu(magic_of);
-+ return magic == UBIFS_NODE_MAGIC;
-+}
-+
-+static void __init ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
-+{
-+ int ret, is_ubifs;
-+ struct ubi_volume_desc *desc;
-+
-+ if (strcmp(vi->name, "rootfs") &&
-+ strcmp(vi->name, "fit"))
-+ return;
-+
-+ desc = ubi_open_volume(vi->ubi_num, vi->vol_id, UBI_READONLY);
-+ if (IS_ERR(desc))
-+ return;
-+
-+ is_ubifs = ubi_vol_is_ubifs(desc);
-+ ubi_close_volume(desc);
-+ if (is_ubifs)
-+ return;
-+
-+ ret = ubiblock_create(vi);
-+ if (ret)
-+ pr_err("UBI error: block: can't add '%s' volume, err=%d\n",
-+ vi->name, ret);
-+}
-+
- static void
- ubiblock_create_from_param(struct ubi_volume_info *vi)
- {
- int i, ret = 0;
-+ bool got_param = false;
- struct ubiblock_param *p;
-
- /*
-@@ -660,6 +697,7 @@ ubiblock_create_from_param(struct ubi_vo
- if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id))
- continue;
-
-+ got_param = true;
- ret = ubiblock_create(vi);
- if (ret) {
- pr_err(
-@@ -668,6 +706,10 @@ ubiblock_create_from_param(struct ubi_vo
- }
- break;
- }
-+
-+ /* auto-attach "rootfs" volume if existing and non-ubifs */
-+ if (!got_param && IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV))
-+ ubiblock_create_auto_rootfs(vi);
- }
-
- static int ubiblock_notify(struct notifier_block *nb,
diff --git a/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch
deleted file mode 100644
index f95ec46f14..0000000000
--- a/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- init/do_mounts.c | 26 +++++++++++++++++++++++++-
- 1 file changed, 25 insertions(+), 1 deletion(-)
-
---- a/init/do_mounts.c
-+++ b/init/do_mounts.c
-@@ -446,7 +446,30 @@ retry:
- out:
- put_page(page);
- }
--
-+
-+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
-+static int __init mount_ubi_rootfs(void)
-+{
-+ int flags = MS_SILENT;
-+ int err, tried = 0;
-+
-+ while (tried < 2) {
-+ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \
-+ root_mount_data);
-+ switch (err) {
-+ case -EACCES:
-+ flags |= MS_RDONLY;
-+ tried++;
-+ break;
-+ default:
-+ return err;
-+ }
-+ }
-+
-+ return -EINVAL;
-+}
-+#endif
-+
- #ifdef CONFIG_ROOT_NFS
-
- #define NFSROOT_TIMEOUT_MIN 5
-@@ -579,6 +602,10 @@ void __init mount_root(void)
- return;
- }
- #endif
-+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
-+ if (!mount_ubi_rootfs())
-+ return;
-+#endif
- if (ROOT_DEV == 0 && root_device_name && root_fs_names) {
- if (mount_nodev_root() == 0)
- return;
diff --git a/target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
deleted file mode 100644
index 5357c7e15d..0000000000
--- a/target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -43,6 +43,7 @@
- #include <linux/scatterlist.h>
- #include <linux/idr.h>
- #include <asm/div64.h>
-+#include <linux/root_dev.h>
-
- #include "ubi-media.h"
- #include "ubi.h"
-@@ -460,6 +461,15 @@ int ubiblock_create(struct ubi_volume_in
- dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
- dev->ubi_num, dev->vol_id, vi->name);
- mutex_unlock(&devices_mutex);
-+
-+ if (!strcmp(vi->name, "rootfs") &&
-+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
-+ ROOT_DEV == 0) {
-+ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n",
-+ dev->ubi_num, dev->vol_id, vi->name);
-+ ROOT_DEV = MKDEV(gd->major, gd->first_minor);
-+ }
-+
- return 0;
-
- out_destroy_wq:
diff --git a/target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch
deleted file mode 100644
index fc48146221..0000000000
--- a/target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: mtd: add EOF marker support to the UBI layer
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++---
- drivers/mtd/ubi/ubi.h | 1 +
- 2 files changed, 23 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/ubi/attach.c
-+++ b/drivers/mtd/ubi/attach.c
-@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id)
- #endif
- }
-
-+static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech)
-+{
-+ return ech->padding1[0] == 'E' &&
-+ ech->padding1[1] == 'O' &&
-+ ech->padding1[2] == 'F';
-+}
-+
- /**
- * scan_peb - scan and process UBI headers of a PEB.
- * @ubi: UBI device description object
-@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u
- return 0;
- }
-
-- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
-- if (err < 0)
-- return err;
-+ if (!ai->eof_found) {
-+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
-+ if (err < 0)
-+ return err;
-+
-+ if (ec_hdr_has_eof(ech)) {
-+ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n",
-+ pnum);
-+ ai->eof_found = true;
-+ }
-+ }
-+
-+ if (ai->eof_found)
-+ err = UBI_IO_FF_BITFLIPS;
-+
- switch (err) {
- case 0:
- break;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -780,6 +780,7 @@ struct ubi_attach_info {
- int mean_ec;
- uint64_t ec_sum;
- int ec_count;
-+ bool eof_found;
- struct kmem_cache *aeb_slab_cache;
- struct ubi_ec_hdr *ech;
- struct ubi_vid_io_buf *vidb;
diff --git a/target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch
deleted file mode 100644
index 01f3b9ec2d..0000000000
--- a/target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001
-From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
-Date: Wed, 5 Sep 2018 01:32:51 +0200
-Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices
-
-Document virtual mtd-concat device bindings.
-
-Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
----
- .../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++
- 1 file changed, 36 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt
-@@ -0,0 +1,36 @@
-+Virtual MTD concat device
-+
-+Requires properties:
-+- devices: list of phandles to mtd nodes that should be concatenated
-+
-+Example:
-+
-+&spi {
-+ flash0: flash@0 {
-+ ...
-+ };
-+ flash1: flash@1 {
-+ ...
-+ };
-+};
-+
-+flash {
-+ compatible = "mtd-concat";
-+
-+ devices = <&flash0 &flash1>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x0000000 0x0040000>;
-+ read-only;
-+ };
-+
-+ partition@40000 {
-+ label = "firmware";
-+ reg = <0x0040000 0x1fc0000>;
-+ };
-+ }
-+}
diff --git a/target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch
deleted file mode 100644
index e0cbc4508b..0000000000
--- a/target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch
+++ /dev/null
@@ -1,216 +0,0 @@
-From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001
-From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
-Date: Sat, 25 Aug 2018 12:35:22 +0200
-Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices
-
-Some mtd drivers like physmap variants have support for concatenating
-multiple mtd devices, but there is no generic way to define such a
-concat device from within the device tree.
-
-This is useful for some SoC boards that use multiple flash chips as
-memory banks of a single mtd device, with partitions spanning chip
-borders.
-
-This commit adds a driver for creating virtual mtd-concat devices. They
-must have a compatible = "mtd-concat" line, and define a list of devices
-to concat in the 'devices' property, for example:
-
-flash {
- compatible = "mtd-concat";
-
- devices = <&flash0 &flash1>;
-
- partitions {
- ...
- };
-};
-
-The driver is added to the very end of the mtd Makefile to increase the
-likelyhood of all child devices already being loaded at the time of
-probing, preventing unnecessary deferred probes.
-
-Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
----
- drivers/mtd/Kconfig | 2 +
- drivers/mtd/Makefile | 3 +
- drivers/mtd/composite/Kconfig | 12 +++
- drivers/mtd/composite/Makefile | 6 ++
- drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++
- 5 files changed, 151 insertions(+)
- create mode 100644 drivers/mtd/composite/Kconfig
- create mode 100644 drivers/mtd/composite/Makefile
- create mode 100644 drivers/mtd/composite/virt_concat.c
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -241,4 +241,6 @@ source "drivers/mtd/ubi/Kconfig"
-
- source "drivers/mtd/hyperbus/Kconfig"
-
-+source "drivers/mtd/composite/Kconfig"
-+
- endif # MTD
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -33,3 +33,6 @@ obj-y += chips/ lpddr/ maps/ devices/ n
- obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
- obj-$(CONFIG_MTD_UBI) += ubi/
- obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
-+
-+# Composite drivers must be loaded last
-+obj-y += composite/
---- /dev/null
-+++ b/drivers/mtd/composite/Kconfig
-@@ -0,0 +1,12 @@
-+menu "Composite MTD device drivers"
-+ depends on MTD!=n
-+
-+config MTD_VIRT_CONCAT
-+ tristate "Virtual concat MTD device"
-+ help
-+ This driver allows creation of a virtual MTD concat device, which
-+ concatenates multiple underlying MTD devices to a single device.
-+ This is required by some SoC boards where multiple memory banks are
-+ used as one device with partitions spanning across device boundaries.
-+
-+endmenu
---- /dev/null
-+++ b/drivers/mtd/composite/Makefile
-@@ -0,0 +1,6 @@
-+# SPDX-License-Identifier: GPL-2.0
-+#
-+# linux/drivers/mtd/composite/Makefile
-+#
-+
-+obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o
---- /dev/null
-+++ b/drivers/mtd/composite/virt_concat.c
-@@ -0,0 +1,128 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Virtual concat MTD device driver
-+ *
-+ * Copyright (C) 2018 Bernhard Frauendienst
-+ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/mtd/concat.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/slab.h>
-+
-+/*
-+ * struct of_virt_concat - platform device driver data.
-+ * @cmtd the final mtd_concat device
-+ * @num_devices the number of devices in @devices
-+ * @devices points to an array of devices already loaded
-+ */
-+struct of_virt_concat {
-+ struct mtd_info *cmtd;
-+ int num_devices;
-+ struct mtd_info **devices;
-+};
-+
-+static int virt_concat_remove(struct platform_device *pdev)
-+{
-+ struct of_virt_concat *info;
-+ int i;
-+
-+ info = platform_get_drvdata(pdev);
-+ if (!info)
-+ return 0;
-+
-+ // unset data for when this is called after a probe error
-+ platform_set_drvdata(pdev, NULL);
-+
-+ if (info->cmtd) {
-+ mtd_device_unregister(info->cmtd);
-+ mtd_concat_destroy(info->cmtd);
-+ }
-+
-+ if (info->devices) {
-+ for (i = 0; i < info->num_devices; i++)
-+ put_mtd_device(info->devices[i]);
-+ }
-+
-+ return 0;
-+}
-+
-+static int virt_concat_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ struct of_phandle_iterator it;
-+ struct of_virt_concat *info;
-+ struct mtd_info *mtd;
-+ int err = 0, count;
-+
-+ count = of_count_phandle_with_args(node, "devices", NULL);
-+ if (count <= 0)
-+ return -EINVAL;
-+
-+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return -ENOMEM;
-+ info->devices = devm_kcalloc(&pdev->dev, count,
-+ sizeof(*(info->devices)), GFP_KERNEL);
-+ if (!info->devices) {
-+ err = -ENOMEM;
-+ goto err_remove;
-+ }
-+
-+ platform_set_drvdata(pdev, info);
-+
-+ of_for_each_phandle(&it, err, node, "devices", NULL, 0) {
-+ mtd = of_get_mtd_device_by_node(it.node);
-+ if (IS_ERR(mtd)) {
-+ of_node_put(it.node);
-+ err = -EPROBE_DEFER;
-+ goto err_remove;
-+ }
-+
-+ info->devices[info->num_devices++] = mtd;
-+ }
-+
-+ info->cmtd = mtd_concat_create(info->devices, info->num_devices,
-+ dev_name(&pdev->dev));
-+ if (!info->cmtd) {
-+ err = -ENXIO;
-+ goto err_remove;
-+ }
-+
-+ info->cmtd->dev.parent = &pdev->dev;
-+ mtd_set_of_node(info->cmtd, node);
-+ mtd_device_register(info->cmtd, NULL, 0);
-+
-+ return 0;
-+
-+err_remove:
-+ virt_concat_remove(pdev);
-+
-+ return err;
-+}
-+
-+static const struct of_device_id virt_concat_of_match[] = {
-+ { .compatible = "mtd-concat", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, virt_concat_of_match);
-+
-+static struct platform_driver virt_concat_driver = {
-+ .probe = virt_concat_probe,
-+ .remove = virt_concat_remove,
-+ .driver = {
-+ .name = "virt-mtdconcat",
-+ .of_match_table = virt_concat_of_match,
-+ },
-+};
-+
-+module_platform_driver(virt_concat_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Bernhard Frauendienst <kernel@nospam.obeliks.de>");
-+MODULE_DESCRIPTION("Virtual concat MTD device driver");
diff --git a/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch b/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch
deleted file mode 100644
index 1a4d5a766f..0000000000
--- a/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 8bf2ce6ea4ee840b70f55a27f80e1cd308051b13 Mon Sep 17 00:00:00 2001
-From: Nick Hainke <vincent@systemli.org>
-Date: Mon, 27 Dec 2021 00:38:13 +0100
-Subject: [PATCH 1/2] mtd: spi-nor: locking support for MX25L6405D
-
-Macronix MX25L6405D supports locking with four block-protection bits.
-Currently, the driver only sets three bits. If the bootloader does not
-sustain the flash chip in an unlocked state, the flash might be
-non-writeable. Add the corresponding flag to enable locking support with
-four bits in the status register.
-
-Tested on Nanostation M2 XM.
-
-Similar to commit 7ea40b54e83b ("mtd: spi-nor: enable locking support for
-MX25L12805D")
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Nick Hainke <vincent@systemli.org>
----
- drivers/mtd/spi-nor/macronix.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/spi-nor/macronix.c
-+++ b/drivers/mtd/spi-nor/macronix.c
-@@ -48,6 +48,7 @@ static const struct flash_info macronix_
- { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64)
- NO_SFDP_FLAGS(SECT_4K) },
- { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128)
-+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP)
- NO_SFDP_FLAGS(SECT_4K) },
- { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4)
- NO_SFDP_FLAGS(SECT_4K) },
diff --git a/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch b/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch
deleted file mode 100644
index 99e0fc72bf..0000000000
--- a/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 245224608b5368c10407da07557e546743d3c489 Mon Sep 17 00:00:00 2001
-From: Nick Hainke <vincent@systemli.org>
-Date: Mon, 27 Dec 2021 09:33:13 +0100
-Subject: [PATCH 2/2] mtd: spi-nor: disable 16-bit-sr for macronix
-
-Macronix flash chips seem to consist of only one status register.
-These chips will not work with the "16-bit Write Status (01h) Command".
-Disable SNOR_F_HAS_16BIT_SR for all Macronix chips.
-
-Tested with MX25L6405D.
-
-Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on
-lock()/unlock()")
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Nick Hainke <vincent@systemli.org>
----
- drivers/mtd/spi-nor/macronix.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mtd/spi-nor/macronix.c
-+++ b/drivers/mtd/spi-nor/macronix.c
-@@ -107,6 +107,7 @@ static void macronix_nor_default_init(st
- {
- nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
- nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
-+ nor->flags &= ~SNOR_F_HAS_16BIT_SR;
- nor->flags |= SNOR_F_HAS_LOCK;
- }
-
diff --git a/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch b/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch
deleted file mode 100644
index 2053c0fbe2..0000000000
--- a/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From af7b91bcecce0eae24e90acd35d96ecee73e1407 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:21:15 +0200
-Subject: [PATCH] fs: add cdrom dependency
-
----
- fs/hfs/Kconfig | 1 +
- fs/hfsplus/Kconfig | 1 +
- fs/isofs/Kconfig | 1 +
- fs/udf/Kconfig | 1 +
- 4 files changed, 4 insertions(+)
-
---- a/fs/hfs/Kconfig
-+++ b/fs/hfs/Kconfig
-@@ -2,6 +2,7 @@
- config HFS_FS
- tristate "Apple Macintosh file system support"
- depends on BLOCK
-+ select CDROM
- select NLS
- help
- If you say Y here, you will be able to mount Macintosh-formatted
---- a/fs/hfsplus/Kconfig
-+++ b/fs/hfsplus/Kconfig
-@@ -2,6 +2,7 @@
- config HFSPLUS_FS
- tristate "Apple Extended HFS file system support"
- depends on BLOCK
-+ select CDROM
- select NLS
- select NLS_UTF8
- help
---- a/fs/isofs/Kconfig
-+++ b/fs/isofs/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- config ISO9660_FS
- tristate "ISO 9660 CDROM file system support"
-+ select CDROM
- help
- This is the standard file system used on CD-ROMs. It was previously
- known as "High Sierra File System" and is called "hsfs" on other
---- a/fs/udf/Kconfig
-+++ b/fs/udf/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- config UDF_FS
- tristate "UDF file system support"
-+ select CDROM
- select CRC_ITU_T
- select NLS
- help
diff --git a/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch b/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch
deleted file mode 100644
index f88136541f..0000000000
--- a/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch
+++ /dev/null
@@ -1,733 +0,0 @@
-From 6173a065cb395d4a9528c4e49810af127db68141 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 16 Nov 2022 12:49:52 +0000
-Subject: [PATCH 1/2] block: add uImage.FIT subimage block driver
-
-Add a small block driver which exposes filesystem sub-images contained
-in U-Boot uImage.FIT images as block devices.
-
-The uImage.FIT image has to be stored directly on a block device or
-partition, MTD device or partition, or UBI volume.
-
-The driver is intended for systems using the U-Boot bootloader and
-uses the root device hint left by the bootloader (or the user) in
-the 'chosen' section of the device-tree.
-
-Example:
-/dts-v1/;
-/ {
- chosen {
- rootdisk = <&mmc0_part3>;
- };
-};
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- MAINTAINERS | 6 +
- drivers/block/Kconfig | 12 +
- drivers/block/Makefile | 2 +
- drivers/block/fitblk.c | 658 ++++++++++++++++++++++++++++++++++++
- drivers/block/open | 4 +
- include/uapi/linux/fitblk.h | 10 +
- 6 files changed, 692 insertions(+)
- create mode 100644 drivers/block/fitblk.c
- create mode 100644 drivers/block/open
- create mode 100644 include/uapi/linux/fitblk.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -21059,6 +21059,12 @@ F: Documentation/filesystems/ubifs-authe
- F: Documentation/filesystems/ubifs.rst
- F: fs/ubifs/
-
-+U-BOOT UIMAGE.FIT PARSER
-+M: Daniel Golle <daniel@makrotopia.org>
-+L: linux-block@vger.kernel.org
-+S: Maintained
-+F: drivers/block/fitblk.c
-+
- UBLK USERSPACE BLOCK DRIVER
- M: Ming Lei <ming.lei@redhat.com>
- L: linux-block@vger.kernel.org
---- a/drivers/block/Kconfig
-+++ b/drivers/block/Kconfig
-@@ -383,6 +383,18 @@ config VIRTIO_BLK
- This is the virtual block driver for virtio. It can be used with
- QEMU based VMMs (like KVM or Xen). Say Y or M.
-
-+config UIMAGE_FIT_BLK
-+ bool "uImage.FIT block driver"
-+ help
-+ This driver allows using filesystems contained in uImage.FIT images
-+ by mapping them as block devices.
-+
-+ It can currently not be built as a module due to libfdt symbols not
-+ being exported.
-+
-+ Say Y if you want to mount filesystems sub-images of a uImage.FIT
-+ stored in a block device partition, mtdblock or ubiblock device.
-+
- config BLK_DEV_RBD
- tristate "Rados block device (RBD)"
- depends on INET && BLOCK
---- a/drivers/block/Makefile
-+++ b/drivers/block/Makefile
-@@ -39,4 +39,6 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_b
-
- obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o
-
-+obj-$(CONFIG_UIMAGE_FIT_BLK) += fitblk.o
-+
- swim_mod-y := swim.o swim_asm.o
---- /dev/null
-+++ b/drivers/block/fitblk.c
-@@ -0,0 +1,636 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * uImage.FIT virtual block device driver.
-+ *
-+ * Copyright (C) 2023 Daniel Golle
-+ * Copyright (C) 2007 Nick Piggin
-+ * Copyright (C) 2007 Novell Inc.
-+ *
-+ * Initially derived from drivers/block/brd.c which is in parts derived from
-+ * drivers/block/rd.c, and drivers/block/loop.c, copyright of their respective
-+ * owners.
-+ *
-+ * uImage.FIT headers extracted from Das U-Boot
-+ * (C) Copyright 2008 Semihalf
-+ * (C) Copyright 2000-2005
-+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/initrd.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/major.h>
-+#include <linux/blkdev.h>
-+#include <linux/blkpg.h>
-+#include <linux/blk-mq.h>
-+#include <linux/ctype.h>
-+#include <linux/hdreg.h>
-+#include <linux/list.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/of_fdt.h>
-+#include <linux/pagemap.h>
-+#include <linux/platform_device.h>
-+#include <linux/property.h>
-+#include <linux/refcount.h>
-+#include <linux/task_work.h>
-+#include <linux/types.h>
-+#include <linux/libfdt.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/root_dev.h>
-+#include <uapi/linux/fitblk.h>
-+
-+#define FIT_DEVICE_PREFIX "fit"
-+
-+/* maximum number of pages used for the uImage.FIT index structure */
-+#define FIT_MAX_PAGES 1024
-+
-+/* minimum free sectors to map as read-write "remainder" volume */
-+#define MIN_FREE_SECT 16
-+
-+/* maximum number of mapped loadables */
-+#define MAX_FIT_LOADABLES 16
-+
-+/* constants for uImage.FIT structrure traversal */
-+#define FIT_IMAGES_PATH "/images"
-+#define FIT_CONFS_PATH "/configurations"
-+
-+/* hash/signature/key node */
-+#define FIT_HASH_NODENAME "hash"
-+#define FIT_ALGO_PROP "algo"
-+#define FIT_VALUE_PROP "value"
-+#define FIT_IGNORE_PROP "uboot-ignore"
-+#define FIT_SIG_NODENAME "signature"
-+#define FIT_KEY_REQUIRED "required"
-+#define FIT_KEY_HINT "key-name-hint"
-+
-+/* cipher node */
-+#define FIT_CIPHER_NODENAME "cipher"
-+#define FIT_ALGO_PROP "algo"
-+
-+/* image node */
-+#define FIT_DATA_PROP "data"
-+#define FIT_DATA_POSITION_PROP "data-position"
-+#define FIT_DATA_OFFSET_PROP "data-offset"
-+#define FIT_DATA_SIZE_PROP "data-size"
-+#define FIT_TIMESTAMP_PROP "timestamp"
-+#define FIT_DESC_PROP "description"
-+#define FIT_ARCH_PROP "arch"
-+#define FIT_TYPE_PROP "type"
-+#define FIT_OS_PROP "os"
-+#define FIT_COMP_PROP "compression"
-+#define FIT_ENTRY_PROP "entry"
-+#define FIT_LOAD_PROP "load"
-+
-+/* configuration node */
-+#define FIT_KERNEL_PROP "kernel"
-+#define FIT_FILESYSTEM_PROP "filesystem"
-+#define FIT_RAMDISK_PROP "ramdisk"
-+#define FIT_FDT_PROP "fdt"
-+#define FIT_LOADABLE_PROP "loadables"
-+#define FIT_DEFAULT_PROP "default"
-+#define FIT_SETUP_PROP "setup"
-+#define FIT_FPGA_PROP "fpga"
-+#define FIT_FIRMWARE_PROP "firmware"
-+#define FIT_STANDALONE_PROP "standalone"
-+
-+/* fitblk driver data */
-+static const char *_fitblk_claim_ptr = "I belong to fitblk";
-+static const char *ubootver;
-+struct device_node *rootdisk;
-+static struct platform_device *pdev;
-+static LIST_HEAD(fitblk_devices);
-+static DEFINE_MUTEX(devices_mutex);
-+refcount_t num_devs;
-+
-+struct fitblk {
-+ struct platform_device *pdev;
-+ struct block_device *lower_bdev;
-+ sector_t start_sect;
-+ struct gendisk *disk;
-+ struct work_struct remove_work;
-+ struct list_head list;
-+ bool dead;
-+};
-+
-+static int fitblk_open(struct block_device *bdev, fmode_t mode)
-+{
-+ struct fitblk *fitblk = bdev->bd_disk->private_data;
-+
-+ if (fitblk->dead)
-+ return -ENOENT;
-+
-+ return 0;
-+}
-+
-+static void fitblk_release(struct gendisk *disk, fmode_t mode)
-+{
-+ return;
-+}
-+
-+static void fitblk_submit_bio(struct bio *orig_bio)
-+{
-+ struct bio *bio = orig_bio;
-+ struct fitblk *fitblk = bio->bi_bdev->bd_disk->private_data;
-+
-+ if (fitblk->dead)
-+ return;
-+
-+ /* mangle bio and re-submit */
-+ while (bio) {
-+ bio->bi_iter.bi_sector += fitblk->start_sect;
-+ bio->bi_bdev = fitblk->lower_bdev;
-+ bio = bio->bi_next;
-+ }
-+ submit_bio(orig_bio);
-+}
-+
-+static void fitblk_remove(struct fitblk *fitblk)
-+{
-+ blk_mark_disk_dead(fitblk->disk);
-+ mutex_lock(&devices_mutex);
-+ fitblk->dead = true;
-+ list_del(&fitblk->list);
-+ mutex_unlock(&devices_mutex);
-+
-+ schedule_work(&fitblk->remove_work);
-+}
-+
-+static int fitblk_ioctl(struct block_device *bdev, fmode_t mode,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct fitblk *fitblk = bdev->bd_disk->private_data;
-+
-+ if (!capable(CAP_SYS_ADMIN))
-+ return -EACCES;
-+
-+ if (fitblk->dead)
-+ return -ENOENT;
-+
-+ switch (cmd) {
-+ case FITBLK_RELEASE:
-+ fitblk_remove(fitblk);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct block_device_operations fitblk_fops = {
-+ .owner = THIS_MODULE,
-+ .ioctl = fitblk_ioctl,
-+ .open = fitblk_open,
-+ .release = fitblk_release,
-+ .submit_bio = fitblk_submit_bio,
-+};
-+
-+static void fitblk_purge(struct work_struct *work)
-+{
-+ struct fitblk *fitblk = container_of(work, struct fitblk, remove_work);
-+
-+ //del_gendisk(fitblk->disk); // causes crash, not doing it doesn't matter
-+ refcount_dec(&num_devs);
-+ platform_device_del(fitblk->pdev);
-+ platform_device_put(fitblk->pdev);
-+
-+ if (refcount_dec_if_one(&num_devs)) {
-+ sysfs_remove_link(&pdev->dev.kobj, "lower_dev");
-+ blkdev_put(fitblk->lower_bdev, FMODE_READ | FMODE_EXCL);
-+ }
-+
-+ kfree(fitblk);
-+}
-+
-+static int add_fit_subimage_device(struct block_device *lower_bdev,
-+ unsigned int slot, sector_t start_sect,
-+ sector_t nr_sect, bool readonly)
-+{
-+ struct fitblk *fitblk;
-+ struct gendisk *disk;
-+ int err;
-+
-+ mutex_lock(&devices_mutex);
-+ if (!refcount_inc_not_zero(&num_devs))
-+ return -EBADF;
-+
-+ fitblk = kzalloc(sizeof(struct fitblk), GFP_KERNEL);
-+ if (!fitblk) {
-+ err = -ENOMEM;
-+ goto out_unlock;
-+ }
-+
-+ fitblk->lower_bdev = lower_bdev;
-+ fitblk->start_sect = start_sect;
-+ INIT_WORK(&fitblk->remove_work, fitblk_purge);
-+
-+ disk = blk_alloc_disk(NUMA_NO_NODE);
-+ if (!disk) {
-+ err = -ENOMEM;
-+ goto out_free_fitblk;
-+ }
-+
-+ disk->first_minor = 0;
-+ disk->flags = lower_bdev->bd_disk->flags | GENHD_FL_NO_PART;
-+ disk->fops = &fitblk_fops;
-+ disk->private_data = fitblk;
-+ if (readonly) {
-+ set_disk_ro(disk, 1);
-+ snprintf(disk->disk_name, sizeof(disk->disk_name), FIT_DEVICE_PREFIX "%u", slot);
-+ } else {
-+ strcpy(disk->disk_name, FIT_DEVICE_PREFIX "rw");
-+ }
-+
-+ set_capacity(disk, nr_sect);
-+
-+ disk->queue->queue_flags = lower_bdev->bd_disk->queue->queue_flags;
-+ memcpy(&disk->queue->limits, &lower_bdev->bd_disk->queue->limits,
-+ sizeof(struct queue_limits));
-+
-+ fitblk->disk = disk;
-+ fitblk->pdev = platform_device_alloc(disk->disk_name, PLATFORM_DEVID_NONE);
-+ if (!fitblk->pdev) {
-+ err = -ENOMEM;
-+ goto out_cleanup_disk;
-+ }
-+
-+ fitblk->pdev->dev.parent = &pdev->dev;
-+ err = platform_device_add(fitblk->pdev);
-+ if (err)
-+ goto out_put_pdev;
-+
-+ err = device_add_disk(&fitblk->pdev->dev, disk, NULL);
-+ if (err)
-+ goto out_del_pdev;
-+
-+ if (!ROOT_DEV)
-+ ROOT_DEV = disk->part0->bd_dev;
-+
-+ list_add_tail(&fitblk->list, &fitblk_devices);
-+
-+ mutex_unlock(&devices_mutex);
-+
-+ return 0;
-+
-+out_del_pdev:
-+ platform_device_del(fitblk->pdev);
-+out_put_pdev:
-+ platform_device_put(fitblk->pdev);
-+out_cleanup_disk:
-+ put_disk(disk);
-+out_free_fitblk:
-+ kfree(fitblk);
-+out_unlock:
-+ refcount_dec(&num_devs);
-+ mutex_unlock(&devices_mutex);
-+ return err;
-+}
-+
-+static int parse_fit_on_dev(struct device *dev)
-+{
-+ struct block_device *bdev;
-+ struct address_space *mapping;
-+ struct folio *folio;
-+ pgoff_t f_index = 0;
-+ size_t bytes_left, bytes_to_copy;
-+ void *pre_fit, *fit, *fit_c;
-+ u64 dsize, dsectors, imgmaxsect = 0;
-+ u32 size, image_pos, image_len;
-+ const __be32 *image_offset_be, *image_len_be, *image_pos_be;
-+ int ret = 0, node, images, config;
-+ const char *image_name, *image_type, *image_description,
-+ *config_default, *config_description, *config_loadables;
-+ u32 image_name_len, image_type_len, image_description_len,
-+ bootconf_len, config_default_len, config_description_len,
-+ config_loadables_len;
-+ sector_t start_sect, nr_sects;
-+ struct device_node *np = NULL;
-+ const char *bootconf_c;
-+ const char *loadable;
-+ char *bootconf = NULL, *bootconf_term;
-+ bool found;
-+ int loadables_rem_len, loadable_len;
-+ u16 loadcnt;
-+ unsigned int slot = 0;
-+
-+ /* Exclusive open the block device to receive holder notifications */
-+ bdev = blkdev_get_by_dev(dev->devt, FMODE_READ | FMODE_EXCL, &_fitblk_claim_ptr);
-+ if (!bdev)
-+ return -ENODEV;
-+
-+ if (IS_ERR(bdev))
-+ return PTR_ERR(bdev);
-+
-+ mapping = bdev->bd_inode->i_mapping;
-+
-+ /* map first page */
-+ folio = read_mapping_folio(mapping, f_index++, NULL);
-+ if (IS_ERR(folio)) {
-+ ret = PTR_ERR(folio);
-+ goto out_blkdev;
-+ }
-+ pre_fit = folio_address(folio) + offset_in_folio(folio, 0);
-+
-+ /* uImage.FIT is based on flattened device tree structure */
-+ if (fdt_check_header(pre_fit)) {
-+ ret = -EINVAL;
-+ folio_put(folio);
-+ goto out_blkdev;
-+ }
-+
-+ size = fdt_totalsize(pre_fit);
-+
-+ if (size > PAGE_SIZE * FIT_MAX_PAGES) {
-+ ret = -EOPNOTSUPP;
-+ folio_put(folio);
-+ goto out_blkdev;
-+ }
-+
-+ /* acquire disk size */
-+ dsectors = bdev_nr_sectors(bdev);
-+ dsize = dsectors << SECTOR_SHIFT;
-+
-+ /* abort if FIT structure is larger than disk or partition size */
-+ if (size >= dsize) {
-+ ret = -EFBIG;
-+ folio_put(folio);
-+ goto out_blkdev;
-+ }
-+
-+ fit = kmalloc(size, GFP_KERNEL);
-+ if (!fit) {
-+ ret = -ENOMEM;
-+ folio_put(folio);
-+ goto out_blkdev;
-+ }
-+
-+ bytes_left = size;
-+ fit_c = fit;
-+ while (bytes_left > 0) {
-+ bytes_to_copy = min_t(size_t, bytes_left,
-+ folio_size(folio) - offset_in_folio(folio, 0));
-+ memcpy(fit_c, pre_fit, bytes_to_copy);
-+ fit_c += bytes_to_copy;
-+ bytes_left -= bytes_to_copy;
-+ if (bytes_left) {
-+ folio_put(folio);
-+ folio = read_mapping_folio(mapping, f_index++, NULL);
-+ if (IS_ERR(folio)) {
-+ ret = PTR_ERR(folio);
-+ goto out_blkdev;
-+ };
-+ pre_fit = folio_address(folio) + offset_in_folio(folio, 0);
-+ }
-+ }
-+ folio_put(folio);
-+
-+ /* set boot config node name U-Boot may have added to the device tree */
-+ np = of_find_node_by_path("/chosen");
-+ if (np) {
-+ bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len);
-+ if (bootconf_c && bootconf_len)
-+ bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL);
-+ }
-+
-+ if (bootconf) {
-+ bootconf_term = strchr(bootconf, '#');
-+ if (bootconf_term)
-+ *bootconf_term = '\0';
-+ }
-+
-+ /* find configuration path in uImage.FIT */
-+ config = fdt_path_offset(fit, FIT_CONFS_PATH);
-+ if (config < 0) {
-+ pr_err("FIT: Cannot find %s node: %d\n",
-+ FIT_CONFS_PATH, config);
-+ ret = -ENOENT;
-+ goto out_bootconf;
-+ }
-+
-+ /* get default configuration node name */
-+ config_default =
-+ fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len);
-+
-+ /* make sure we got either default or selected boot config node name */
-+ if (!config_default && !bootconf) {
-+ pr_err("FIT: Cannot find default configuration\n");
-+ ret = -ENOENT;
-+ goto out_bootconf;
-+ }
-+
-+ /* find selected boot config node, fallback on default config node */
-+ node = fdt_subnode_offset(fit, config, bootconf ?: config_default);
-+ if (node < 0) {
-+ pr_err("FIT: Cannot find %s node: %d\n",
-+ bootconf ?: config_default, node);
-+ ret = -ENOENT;
-+ goto out_bootconf;
-+ }
-+
-+ pr_info("FIT: Detected U-Boot %s\n", ubootver);
-+
-+ /* get selected configuration data */
-+ config_description =
-+ fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
-+ config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP,
-+ &config_loadables_len);
-+
-+ pr_info("FIT: %s configuration: \"%.*s\"%s%.*s%s\n",
-+ bootconf ? "Selected" : "Default",
-+ bootconf ? bootconf_len : config_default_len,
-+ bootconf ?: config_default,
-+ config_description ? " (" : "",
-+ config_description ? config_description_len : 0,
-+ config_description ?: "",
-+ config_description ? ")" : "");
-+
-+ if (!config_loadables || !config_loadables_len) {
-+ pr_err("FIT: No loadables configured in \"%s\"\n",
-+ bootconf ?: config_default);
-+ ret = -ENOENT;
-+ goto out_bootconf;
-+ }
-+
-+ /* get images path in uImage.FIT */
-+ images = fdt_path_offset(fit, FIT_IMAGES_PATH);
-+ if (images < 0) {
-+ pr_err("FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images);
-+ ret = -EINVAL;
-+ goto out_bootconf;
-+ }
-+
-+ /* iterate over images in uImage.FIT */
-+ fdt_for_each_subnode(node, fit, images) {
-+ image_name = fdt_get_name(fit, node, &image_name_len);
-+ image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len);
-+ image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL);
-+ image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL);
-+ image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL);
-+
-+ if (!image_name || !image_type || !image_len_be ||
-+ !image_name_len || !image_type_len)
-+ continue;
-+
-+ image_len = be32_to_cpu(*image_len_be);
-+ if (!image_len)
-+ continue;
-+
-+ if (image_offset_be)
-+ image_pos = be32_to_cpu(*image_offset_be) + size;
-+ else if (image_pos_be)
-+ image_pos = be32_to_cpu(*image_pos_be);
-+ else
-+ continue;
-+
-+ image_description = fdt_getprop(fit, node, FIT_DESC_PROP,
-+ &image_description_len);
-+
-+ pr_info("FIT: %16s sub-image 0x%08x..0x%08x \"%.*s\"%s%.*s%s\n",
-+ image_type, image_pos, image_pos + image_len - 1,
-+ image_name_len, image_name, image_description ? " (" : "",
-+ image_description ? image_description_len : 0,
-+ image_description ?: "", image_description ? ") " : "");
-+
-+ /* only 'filesystem' images should be mapped as partitions */
-+ if (strncmp(image_type, FIT_FILESYSTEM_PROP, image_type_len))
-+ continue;
-+
-+ /* check if sub-image is part of configured loadables */
-+ found = false;
-+ loadable = config_loadables;
-+ loadables_rem_len = config_loadables_len;
-+ for (loadcnt = 0; loadables_rem_len > 1 &&
-+ loadcnt < MAX_FIT_LOADABLES; ++loadcnt) {
-+ loadable_len =
-+ strnlen(loadable, loadables_rem_len - 1) + 1;
-+ loadables_rem_len -= loadable_len;
-+ if (!strncmp(image_name, loadable, loadable_len)) {
-+ found = true;
-+ break;
-+ }
-+ loadable += loadable_len;
-+ }
-+ if (!found)
-+ continue;
-+
-+ if (image_pos % (1 << PAGE_SHIFT)) {
-+ dev_err(dev, "FIT: image %.*s start not aligned to page boundaries, skipping\n",
-+ image_name_len, image_name);
-+ continue;
-+ }
-+
-+ if (image_len % (1 << PAGE_SHIFT)) {
-+ dev_err(dev, "FIT: sub-image %.*s end not aligned to page boundaries, skipping\n",
-+ image_name_len, image_name);
-+ continue;
-+ }
-+
-+ start_sect = image_pos >> SECTOR_SHIFT;
-+ nr_sects = image_len >> SECTOR_SHIFT;
-+ imgmaxsect = max_t(sector_t, imgmaxsect, start_sect + nr_sects);
-+
-+ if (start_sect + nr_sects > dsectors) {
-+ dev_err(dev, "FIT: sub-image %.*s disk access beyond EOD\n",
-+ image_name_len, image_name);
-+ continue;
-+ }
-+
-+ if (!slot) {
-+ ret = sysfs_create_link_nowarn(&pdev->dev.kobj, bdev_kobj(bdev), "lower_dev");
-+ if (ret && ret != -EEXIST)
-+ goto out_bootconf;
-+
-+ ret = 0;
-+ }
-+
-+ add_fit_subimage_device(bdev, slot++, start_sect, nr_sects, true);
-+ }
-+
-+ if (!found || !slot)
-+ goto out_bootconf;
-+
-+ dev_info(dev, "mapped %u uImage.FIT filesystem sub-image%s as /dev/fit%s%u%s\n",
-+ slot, (slot > 1)?"s":"", (slot > 1)?"[0...":"", slot - 1,
-+ (slot > 1)?"]":"");
-+
-+ /* in case uImage.FIT is stored in a partition, map the remaining space */
-+ if (!bdev->bd_read_only && bdev_is_partition(bdev) &&
-+ (imgmaxsect + MIN_FREE_SECT) < dsectors) {
-+ add_fit_subimage_device(bdev, slot++, imgmaxsect,
-+ dsectors - imgmaxsect, false);
-+ dev_info(dev, "mapped remaing space as /dev/fitrw\n");
-+ }
-+
-+out_bootconf:
-+ kfree(bootconf);
-+ kfree(fit);
-+out_blkdev:
-+ if (!found || ret)
-+ blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
-+
-+ return ret;
-+}
-+
-+static int fitblk_match_of_node(struct device *dev, const void *np)
-+{
-+ int ret;
-+
-+ ret = device_match_of_node(dev, np);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * To match ubiblock and mtdblock devices by their parent ubi
-+ * or mtd device, also consider block device parent
-+ */
-+ if (!dev->parent)
-+ return 0;
-+
-+ return device_match_of_node(dev->parent, np);
-+}
-+
-+static int fitblk_probe(struct platform_device *pdev)
-+{
-+ struct device *dev;
-+
-+ dev = class_find_device(&block_class, NULL, rootdisk, fitblk_match_of_node);
-+ if (!dev)
-+ return -EPROBE_DEFER;
-+
-+ return parse_fit_on_dev(dev);
-+}
-+
-+static struct platform_driver fitblk_driver = {
-+ .probe = fitblk_probe,
-+ .driver = {
-+ .name = "fitblk",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __init fitblk_init(void)
-+{
-+ /* detect U-Boot firmware */
-+ ubootver = of_get_property(of_chosen, "u-boot,version", NULL);
-+ if (!ubootver)
-+ return 0;
-+
-+ /* parse 'rootdisk' property phandle */
-+ rootdisk = of_parse_phandle(of_chosen, "rootdisk", 0);
-+ if (!rootdisk)
-+ return 0;
-+
-+ if (platform_driver_register(&fitblk_driver))
-+ return -ENODEV;
-+
-+ refcount_set(&num_devs, 1);
-+ pdev = platform_device_register_simple("fitblk", -1, NULL, 0);
-+ if (IS_ERR(pdev))
-+ return PTR_ERR(pdev);
-+
-+ return 0;
-+}
-+device_initcall(fitblk_init);
---- /dev/null
-+++ b/include/uapi/linux/fitblk.h
-@@ -0,0 +1,10 @@
-+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
-+#ifndef _UAPI_LINUX_FITBLK_H
-+#define _UAPI_LINUX_FITBLK_H
-+
-+/*
-+ * IOCTL commands --- we will commandeer 0x46 ('F')
-+ */
-+#define FITBLK_RELEASE 0x4600
-+
-+#endif /* _UAPI_LINUX_FITBLK_H */
diff --git a/target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch b/target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch
deleted file mode 100644
index 685a5f9da5..0000000000
--- a/target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 5ede3f8aed9a1a579bf7304142600d1f3500add9 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 12 Jun 2023 03:58:42 +0100
-Subject: [PATCH 2/2] init: bypass device lookup for /dev/fit* rootfs
-
-Allow 'rootwait' as /dev/fit* can show up late if the underlaying
-device is probed late.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- init/do_mounts.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/init/do_mounts.c
-+++ b/init/do_mounts.c
-@@ -645,7 +645,8 @@ void __init prepare_namespace(void)
-
- if (saved_root_name[0]) {
- root_device_name = saved_root_name;
-- if (!strncmp(root_device_name, "mtd", 3) ||
-+ if (!strncmp(root_device_name, "fit", 3) ||
-+ !strncmp(root_device_name, "mtd", 3) ||
- !strncmp(root_device_name, "ubi", 3)) {
- mount_block_root(root_device_name, root_mountflags);
- goto out;
diff --git a/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch
deleted file mode 100644
index 27a673399a..0000000000
--- a/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch
+++ /dev/null
@@ -1,5180 +0,0 @@
-From: Alexandros C. Couloumbis <alex@ozo.com>
-Subject: fs: add jffs2/lzma support (not activated by default yet)
-
-lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2
-Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
----
- fs/jffs2/Kconfig | 9 +
- fs/jffs2/Makefile | 3 +
- fs/jffs2/compr.c | 6 +
- fs/jffs2/compr.h | 10 +-
- fs/jffs2/compr_lzma.c | 128 +++
- fs/jffs2/super.c | 33 +-
- include/linux/lzma.h | 62 ++
- include/linux/lzma/LzFind.h | 115 +++
- include/linux/lzma/LzHash.h | 54 +
- include/linux/lzma/LzmaDec.h | 231 +++++
- include/linux/lzma/LzmaEnc.h | 80 ++
- include/linux/lzma/Types.h | 226 +++++
- include/uapi/linux/jffs2.h | 1 +
- lib/Kconfig | 6 +
- lib/Makefile | 12 +
- lib/lzma/LzFind.c | 761 ++++++++++++++
- lib/lzma/LzmaDec.c | 999 +++++++++++++++++++
- lib/lzma/LzmaEnc.c | 2271 ++++++++++++++++++++++++++++++++++++++++++
- lib/lzma/Makefile | 7 +
- 19 files changed, 5008 insertions(+), 6 deletions(-)
- create mode 100644 fs/jffs2/compr_lzma.c
- create mode 100644 include/linux/lzma.h
- create mode 100644 include/linux/lzma/LzFind.h
- create mode 100644 include/linux/lzma/LzHash.h
- create mode 100644 include/linux/lzma/LzmaDec.h
- create mode 100644 include/linux/lzma/LzmaEnc.h
- create mode 100644 include/linux/lzma/Types.h
- create mode 100644 lib/lzma/LzFind.c
- create mode 100644 lib/lzma/LzmaDec.c
- create mode 100644 lib/lzma/LzmaEnc.c
- create mode 100644 lib/lzma/Makefile
-
---- a/fs/jffs2/Kconfig
-+++ b/fs/jffs2/Kconfig
-@@ -136,6 +136,15 @@ config JFFS2_LZO
- This feature was added in July, 2007. Say 'N' if you need
- compatibility with older bootloaders or kernels.
-
-+config JFFS2_LZMA
-+ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS
-+ select LZMA_COMPRESS
-+ select LZMA_DECOMPRESS
-+ depends on JFFS2_FS
-+ default n
-+ help
-+ JFFS2 wrapper to the LZMA C SDK
-+
- config JFFS2_RTIME
- bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
- depends on JFFS2_FS
---- a/fs/jffs2/Makefile
-+++ b/fs/jffs2/Makefile
-@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub
- jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
- jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
- jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o
-+jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o
- jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o
-+
-+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma
---- a/fs/jffs2/compr.c
-+++ b/fs/jffs2/compr.c
-@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void)
- #ifdef CONFIG_JFFS2_LZO
- jffs2_lzo_init();
- #endif
-+#ifdef CONFIG_JFFS2_LZMA
-+ jffs2_lzma_init();
-+#endif
- /* Setting default compression mode */
- #ifdef CONFIG_JFFS2_CMODE_NONE
- jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
-@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void)
- int jffs2_compressors_exit(void)
- {
- /* Unregistering compressors */
-+#ifdef CONFIG_JFFS2_LZMA
-+ jffs2_lzma_exit();
-+#endif
- #ifdef CONFIG_JFFS2_LZO
- jffs2_lzo_exit();
- #endif
---- a/fs/jffs2/compr.h
-+++ b/fs/jffs2/compr.h
-@@ -29,9 +29,9 @@
- #define JFFS2_DYNRUBIN_PRIORITY 20
- #define JFFS2_LZARI_PRIORITY 30
- #define JFFS2_RTIME_PRIORITY 50
--#define JFFS2_ZLIB_PRIORITY 60
--#define JFFS2_LZO_PRIORITY 80
--
-+#define JFFS2_LZMA_PRIORITY 70
-+#define JFFS2_ZLIB_PRIORITY 80
-+#define JFFS2_LZO_PRIORITY 90
-
- #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
- #define JFFS2_DYNRUBIN_DISABLED /* for decompression */
-@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void);
- int jffs2_lzo_init(void);
- void jffs2_lzo_exit(void);
- #endif
-+#ifdef CONFIG_JFFS2_LZMA
-+int jffs2_lzma_init(void);
-+void jffs2_lzma_exit(void);
-+#endif
-
- #endif /* __JFFS2_COMPR_H__ */
---- /dev/null
-+++ b/fs/jffs2/compr_lzma.c
-@@ -0,0 +1,128 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * JFFS2 wrapper to the LZMA C SDK
-+ *
-+ */
-+
-+#include <linux/lzma.h>
-+#include "compr.h"
-+
-+#ifdef __KERNEL__
-+ static DEFINE_MUTEX(deflate_mutex);
-+#endif
-+
-+CLzmaEncHandle *p;
-+Byte propsEncoded[LZMA_PROPS_SIZE];
-+SizeT propsSize = sizeof(propsEncoded);
-+
-+STATIC void lzma_free_workspace(void)
-+{
-+ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc);
-+}
-+
-+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props)
-+{
-+ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL)
-+ {
-+ PRINT_ERROR("Failed to allocate lzma deflate workspace\n");
-+ return -ENOMEM;
-+ }
-+
-+ if (LzmaEnc_SetProps(p, props) != SZ_OK)
-+ {
-+ lzma_free_workspace();
-+ return -1;
-+ }
-+
-+ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK)
-+ {
-+ lzma_free_workspace();
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
-+{
-+ SizeT compress_size = (SizeT)(*dstlen);
-+ int ret;
-+
-+ #ifdef __KERNEL__
-+ mutex_lock(&deflate_mutex);
-+ #endif
-+
-+ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen,
-+ 0, NULL, &lzma_alloc, &lzma_alloc);
-+
-+ #ifdef __KERNEL__
-+ mutex_unlock(&deflate_mutex);
-+ #endif
-+
-+ if (ret != SZ_OK)
-+ return -1;
-+
-+ *dstlen = (uint32_t)compress_size;
-+
-+ return 0;
-+}
-+
-+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t srclen, uint32_t destlen)
-+{
-+ int ret;
-+ SizeT dl = (SizeT)destlen;
-+ SizeT sl = (SizeT)srclen;
-+ ELzmaStatus status;
-+
-+ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded,
-+ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc);
-+
-+ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen)
-+ return -1;
-+
-+ return 0;
-+}
-+
-+static struct jffs2_compressor jffs2_lzma_comp = {
-+ .priority = JFFS2_LZMA_PRIORITY,
-+ .name = "lzma",
-+ .compr = JFFS2_COMPR_LZMA,
-+ .compress = &jffs2_lzma_compress,
-+ .decompress = &jffs2_lzma_decompress,
-+ .disabled = 0,
-+};
-+
-+int INIT jffs2_lzma_init(void)
-+{
-+ int ret;
-+ CLzmaEncProps props;
-+ LzmaEncProps_Init(&props);
-+
-+ props.dictSize = LZMA_BEST_DICT(0x2000);
-+ props.level = LZMA_BEST_LEVEL;
-+ props.lc = LZMA_BEST_LC;
-+ props.lp = LZMA_BEST_LP;
-+ props.pb = LZMA_BEST_PB;
-+ props.fb = LZMA_BEST_FB;
-+
-+ ret = lzma_alloc_workspace(&props);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = jffs2_register_compressor(&jffs2_lzma_comp);
-+ if (ret)
-+ lzma_free_workspace();
-+
-+ return ret;
-+}
-+
-+void jffs2_lzma_exit(void)
-+{
-+ jffs2_unregister_compressor(&jffs2_lzma_comp);
-+ lzma_free_workspace();
-+}
---- a/fs/jffs2/super.c
-+++ b/fs/jffs2/super.c
-@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void)
- BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
- BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
-
-- pr_info("version 2.2."
-+ pr_info("version 2.2"
- #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
- " (NAND)"
- #endif
- #ifdef CONFIG_JFFS2_SUMMARY
-- " (SUMMARY) "
-+ " (SUMMARY)"
- #endif
-- " © 2001-2006 Red Hat, Inc.\n");
-+#ifdef CONFIG_JFFS2_ZLIB
-+ " (ZLIB)"
-+#endif
-+#ifdef CONFIG_JFFS2_LZO
-+ " (LZO)"
-+#endif
-+#ifdef CONFIG_JFFS2_LZMA
-+ " (LZMA)"
-+#endif
-+#ifdef CONFIG_JFFS2_RTIME
-+ " (RTIME)"
-+#endif
-+#ifdef CONFIG_JFFS2_RUBIN
-+ " (RUBIN)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_NONE
-+ " (CMODE_NONE)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_PRIORITY
-+ " (CMODE_PRIORITY)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_SIZE
-+ " (CMODE_SIZE)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO
-+ " (CMODE_FAVOURLZO)"
-+#endif
-+ " (c) 2001-2006 Red Hat, Inc.\n");
-
- jffs2_inode_cachep = kmem_cache_create("jffs2_i",
- sizeof(struct jffs2_inode_info),
---- /dev/null
-+++ b/include/linux/lzma.h
-@@ -0,0 +1,62 @@
-+#ifndef __LZMA_H__
-+#define __LZMA_H__
-+
-+#ifdef __KERNEL__
-+ #include <linux/kernel.h>
-+ #include <linux/sched.h>
-+ #include <linux/slab.h>
-+ #include <linux/vmalloc.h>
-+ #include <linux/init.h>
-+ #define LZMA_MALLOC vmalloc
-+ #define LZMA_FREE vfree
-+ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg)
-+ #define INIT __init
-+ #define STATIC static
-+#else
-+ #include <stdint.h>
-+ #include <stdlib.h>
-+ #include <stdio.h>
-+ #include <unistd.h>
-+ #include <string.h>
-+ #include <asm/types.h>
-+ #include <errno.h>
-+ #include <linux/jffs2.h>
-+ #ifndef PAGE_SIZE
-+ extern int page_size;
-+ #define PAGE_SIZE page_size
-+ #endif
-+ #define LZMA_MALLOC malloc
-+ #define LZMA_FREE free
-+ #define PRINT_ERROR(msg) fprintf(stderr, msg)
-+ #define INIT
-+ #define STATIC
-+#endif
-+
-+#include "lzma/LzmaDec.h"
-+#include "lzma/LzmaEnc.h"
-+
-+#define LZMA_BEST_LEVEL (9)
-+#define LZMA_BEST_LC (0)
-+#define LZMA_BEST_LP (0)
-+#define LZMA_BEST_PB (0)
-+#define LZMA_BEST_FB (273)
-+
-+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2)
-+
-+static void *p_lzma_malloc(void *p, size_t size)
-+{
-+ if (size == 0)
-+ return NULL;
-+
-+ return LZMA_MALLOC(size);
-+}
-+
-+static void p_lzma_free(void *p, void *address)
-+{
-+ if (address != NULL)
-+ LZMA_FREE(address);
-+}
-+
-+static ISzAlloc lzma_alloc = { .Alloc = p_lzma_malloc, .Free = p_lzma_free };
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzFind.h
-@@ -0,0 +1,115 @@
-+/* LzFind.h -- Match finder for LZ algorithms
-+2009-04-22 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZ_FIND_H
-+#define __LZ_FIND_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef UInt32 CLzRef;
-+
-+typedef struct _CMatchFinder
-+{
-+ Byte *buffer;
-+ UInt32 pos;
-+ UInt32 posLimit;
-+ UInt32 streamPos;
-+ UInt32 lenLimit;
-+
-+ UInt32 cyclicBufferPos;
-+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
-+
-+ UInt32 matchMaxLen;
-+ CLzRef *hash;
-+ CLzRef *son;
-+ UInt32 hashMask;
-+ UInt32 cutValue;
-+
-+ Byte *bufferBase;
-+ ISeqInStream *stream;
-+ int streamEndWasReached;
-+
-+ UInt32 blockSize;
-+ UInt32 keepSizeBefore;
-+ UInt32 keepSizeAfter;
-+
-+ UInt32 numHashBytes;
-+ int directInput;
-+ size_t directInputRem;
-+ int btMode;
-+ int bigHash;
-+ UInt32 historySize;
-+ UInt32 fixedHashSize;
-+ UInt32 hashSizeSum;
-+ UInt32 numSons;
-+ SRes result;
-+ UInt32 crc[256];
-+} CMatchFinder;
-+
-+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
-+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
-+
-+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
-+
-+int MatchFinder_NeedMove(CMatchFinder *p);
-+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
-+void MatchFinder_MoveBlock(CMatchFinder *p);
-+void MatchFinder_ReadIfRequired(CMatchFinder *p);
-+
-+void MatchFinder_Construct(CMatchFinder *p);
-+
-+/* Conditions:
-+ historySize <= 3 GB
-+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
-+*/
-+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-+ ISzAlloc *alloc);
-+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
-+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
-+
-+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
-+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
-+ UInt32 *distances, UInt32 maxLen);
-+
-+/*
-+Conditions:
-+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
-+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
-+*/
-+
-+typedef void (*Mf_Init_Func)(void *object);
-+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
-+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
-+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
-+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
-+typedef void (*Mf_Skip_Func)(void *object, UInt32);
-+
-+typedef struct _IMatchFinder
-+{
-+ Mf_Init_Func Init;
-+ Mf_GetIndexByte_Func GetIndexByte;
-+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
-+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
-+ Mf_GetMatches_Func GetMatches;
-+ Mf_Skip_Func Skip;
-+} IMatchFinder;
-+
-+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
-+
-+void MatchFinder_Init(CMatchFinder *p);
-+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzHash.h
-@@ -0,0 +1,54 @@
-+/* LzHash.h -- HASH functions for LZ algorithms
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZ_HASH_H
-+#define __LZ_HASH_H
-+
-+#define kHash2Size (1 << 10)
-+#define kHash3Size (1 << 16)
-+#define kHash4Size (1 << 20)
-+
-+#define kFix3HashSize (kHash2Size)
-+#define kFix4HashSize (kHash2Size + kHash3Size)
-+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
-+
-+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
-+
-+#define HASH3_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
-+
-+#define HASH4_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
-+
-+#define HASH5_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
-+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
-+ hash4Value &= (kHash4Size - 1); }
-+
-+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
-+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
-+
-+
-+#define MT_HASH2_CALC \
-+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
-+
-+#define MT_HASH3_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
-+
-+#define MT_HASH4_CALC { \
-+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+ hash2Value = temp & (kHash2Size - 1); \
-+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzmaDec.h
-@@ -0,0 +1,231 @@
-+/* LzmaDec.h -- LZMA Decoder
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZMA_DEC_H
-+#define __LZMA_DEC_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* #define _LZMA_PROB32 */
-+/* _LZMA_PROB32 can increase the speed on some CPUs,
-+ but memory usage for CLzmaDec::probs will be doubled in that case */
-+
-+#ifdef _LZMA_PROB32
-+#define CLzmaProb UInt32
-+#else
-+#define CLzmaProb UInt16
-+#endif
-+
-+
-+/* ---------- LZMA Properties ---------- */
-+
-+#define LZMA_PROPS_SIZE 5
-+
-+typedef struct _CLzmaProps
-+{
-+ unsigned lc, lp, pb;
-+ UInt32 dicSize;
-+} CLzmaProps;
-+
-+/* LzmaProps_Decode - decodes properties
-+Returns:
-+ SZ_OK
-+ SZ_ERROR_UNSUPPORTED - Unsupported properties
-+*/
-+
-+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
-+
-+
-+/* ---------- LZMA Decoder state ---------- */
-+
-+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
-+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
-+
-+#define LZMA_REQUIRED_INPUT_MAX 20
-+
-+typedef struct
-+{
-+ CLzmaProps prop;
-+ CLzmaProb *probs;
-+ Byte *dic;
-+ const Byte *buf;
-+ UInt32 range, code;
-+ SizeT dicPos;
-+ SizeT dicBufSize;
-+ UInt32 processedPos;
-+ UInt32 checkDicSize;
-+ unsigned state;
-+ UInt32 reps[4];
-+ unsigned remainLen;
-+ int needFlush;
-+ int needInitState;
-+ UInt32 numProbs;
-+ unsigned tempBufSize;
-+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
-+} CLzmaDec;
-+
-+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
-+
-+void LzmaDec_Init(CLzmaDec *p);
-+
-+/* There are two types of LZMA streams:
-+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
-+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
-+
-+typedef enum
-+{
-+ LZMA_FINISH_ANY, /* finish at any point */
-+ LZMA_FINISH_END /* block must be finished at the end */
-+} ELzmaFinishMode;
-+
-+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
-+
-+ You must use LZMA_FINISH_END, when you know that current output buffer
-+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
-+
-+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
-+ and output value of destLen will be less than output buffer size limit.
-+ You can check status result also.
-+
-+ You can use multiple checks to test data integrity after full decompression:
-+ 1) Check Result and "status" variable.
-+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
-+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
-+ You must use correct finish mode in that case. */
-+
-+typedef enum
-+{
-+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
-+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
-+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
-+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
-+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
-+} ELzmaStatus;
-+
-+/* ELzmaStatus is used only as output value for function call */
-+
-+
-+/* ---------- Interfaces ---------- */
-+
-+/* There are 3 levels of interfaces:
-+ 1) Dictionary Interface
-+ 2) Buffer Interface
-+ 3) One Call Interface
-+ You can select any of these interfaces, but don't mix functions from different
-+ groups for same object. */
-+
-+
-+/* There are two variants to allocate state for Dictionary Interface:
-+ 1) LzmaDec_Allocate / LzmaDec_Free
-+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
-+ You can use variant 2, if you set dictionary buffer manually.
-+ For Buffer Interface you must always use variant 1.
-+
-+LzmaDec_Allocate* can return:
-+ SZ_OK
-+ SZ_ERROR_MEM - Memory allocation error
-+ SZ_ERROR_UNSUPPORTED - Unsupported properties
-+*/
-+
-+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
-+
-+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
-+
-+/* ---------- Dictionary Interface ---------- */
-+
-+/* You can use it, if you want to eliminate the overhead for data copying from
-+ dictionary to some other external buffer.
-+ You must work with CLzmaDec variables directly in this interface.
-+
-+ STEPS:
-+ LzmaDec_Constr()
-+ LzmaDec_Allocate()
-+ for (each new stream)
-+ {
-+ LzmaDec_Init()
-+ while (it needs more decompression)
-+ {
-+ LzmaDec_DecodeToDic()
-+ use data from CLzmaDec::dic and update CLzmaDec::dicPos
-+ }
-+ }
-+ LzmaDec_Free()
-+*/
-+
-+/* LzmaDec_DecodeToDic
-+
-+ The decoding to internal dictionary buffer (CLzmaDec::dic).
-+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
-+
-+finishMode:
-+ It has meaning only if the decoding reaches output limit (dicLimit).
-+ LZMA_FINISH_ANY - Decode just dicLimit bytes.
-+ LZMA_FINISH_END - Stream must be finished after dicLimit.
-+
-+Returns:
-+ SZ_OK
-+ status:
-+ LZMA_STATUS_FINISHED_WITH_MARK
-+ LZMA_STATUS_NOT_FINISHED
-+ LZMA_STATUS_NEEDS_MORE_INPUT
-+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
-+ SZ_ERROR_DATA - Data error
-+*/
-+
-+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
-+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-+
-+
-+/* ---------- Buffer Interface ---------- */
-+
-+/* It's zlib-like interface.
-+ See LzmaDec_DecodeToDic description for information about STEPS and return results,
-+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
-+ to work with CLzmaDec variables manually.
-+
-+finishMode:
-+ It has meaning only if the decoding reaches output limit (*destLen).
-+ LZMA_FINISH_ANY - Decode just destLen bytes.
-+ LZMA_FINISH_END - Stream must be finished after (*destLen).
-+*/
-+
-+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
-+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-+
-+
-+/* ---------- One Call Interface ---------- */
-+
-+/* LzmaDecode
-+
-+finishMode:
-+ It has meaning only if the decoding reaches output limit (*destLen).
-+ LZMA_FINISH_ANY - Decode just destLen bytes.
-+ LZMA_FINISH_END - Stream must be finished after (*destLen).
-+
-+Returns:
-+ SZ_OK
-+ status:
-+ LZMA_STATUS_FINISHED_WITH_MARK
-+ LZMA_STATUS_NOT_FINISHED
-+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
-+ SZ_ERROR_DATA - Data error
-+ SZ_ERROR_MEM - Memory allocation error
-+ SZ_ERROR_UNSUPPORTED - Unsupported properties
-+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-+*/
-+
-+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-+ ELzmaStatus *status, ISzAlloc *alloc);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzmaEnc.h
-@@ -0,0 +1,80 @@
-+/* LzmaEnc.h -- LZMA Encoder
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZMA_ENC_H
-+#define __LZMA_ENC_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define LZMA_PROPS_SIZE 5
-+
-+typedef struct _CLzmaEncProps
-+{
-+ int level; /* 0 <= level <= 9 */
-+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
-+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
-+ default = (1 << 24) */
-+ int lc; /* 0 <= lc <= 8, default = 3 */
-+ int lp; /* 0 <= lp <= 4, default = 0 */
-+ int pb; /* 0 <= pb <= 4, default = 2 */
-+ int algo; /* 0 - fast, 1 - normal, default = 1 */
-+ int fb; /* 5 <= fb <= 273, default = 32 */
-+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
-+ int numHashBytes; /* 2, 3 or 4, default = 4 */
-+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
-+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
-+ int numThreads; /* 1 or 2, default = 2 */
-+} CLzmaEncProps;
-+
-+void LzmaEncProps_Init(CLzmaEncProps *p);
-+void LzmaEncProps_Normalize(CLzmaEncProps *p);
-+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
-+
-+
-+/* ---------- CLzmaEncHandle Interface ---------- */
-+
-+/* LzmaEnc_* functions can return the following exit codes:
-+Returns:
-+ SZ_OK - OK
-+ SZ_ERROR_MEM - Memory allocation error
-+ SZ_ERROR_PARAM - Incorrect paramater in props
-+ SZ_ERROR_WRITE - Write callback error.
-+ SZ_ERROR_PROGRESS - some break from progress callback
-+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-+*/
-+
-+typedef void * CLzmaEncHandle;
-+
-+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
-+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
-+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
-+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
-+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
-+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-+
-+/* ---------- One Call Interface ---------- */
-+
-+/* LzmaEncode
-+Return code:
-+ SZ_OK - OK
-+ SZ_ERROR_MEM - Memory allocation error
-+ SZ_ERROR_PARAM - Incorrect paramater
-+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
-+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-+*/
-+
-+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/Types.h
-@@ -0,0 +1,226 @@
-+/* Types.h -- Basic types
-+2009-11-23 : Igor Pavlov : Public domain */
-+
-+#ifndef __7Z_TYPES_H
-+#define __7Z_TYPES_H
-+
-+#include <stddef.h>
-+
-+#ifdef _WIN32
-+#include <windows.h>
-+#endif
-+
-+#ifndef EXTERN_C_BEGIN
-+#ifdef __cplusplus
-+#define EXTERN_C_BEGIN extern "C" {
-+#define EXTERN_C_END }
-+#else
-+#define EXTERN_C_BEGIN
-+#define EXTERN_C_END
-+#endif
-+#endif
-+
-+EXTERN_C_BEGIN
-+
-+#define SZ_OK 0
-+
-+#define SZ_ERROR_DATA 1
-+#define SZ_ERROR_MEM 2
-+#define SZ_ERROR_CRC 3
-+#define SZ_ERROR_UNSUPPORTED 4
-+#define SZ_ERROR_PARAM 5
-+#define SZ_ERROR_INPUT_EOF 6
-+#define SZ_ERROR_OUTPUT_EOF 7
-+#define SZ_ERROR_READ 8
-+#define SZ_ERROR_WRITE 9
-+#define SZ_ERROR_PROGRESS 10
-+#define SZ_ERROR_FAIL 11
-+#define SZ_ERROR_THREAD 12
-+
-+#define SZ_ERROR_ARCHIVE 16
-+#define SZ_ERROR_NO_ARCHIVE 17
-+
-+typedef int SRes;
-+
-+#ifdef _WIN32
-+typedef DWORD WRes;
-+#else
-+typedef int WRes;
-+#endif
-+
-+#ifndef RINOK
-+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
-+#endif
-+
-+typedef unsigned char Byte;
-+typedef short Int16;
-+typedef unsigned short UInt16;
-+
-+#ifdef _LZMA_UINT32_IS_ULONG
-+typedef long Int32;
-+typedef unsigned long UInt32;
-+#else
-+typedef int Int32;
-+typedef unsigned int UInt32;
-+#endif
-+
-+#ifdef _SZ_NO_INT_64
-+
-+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
-+ NOTES: Some code will work incorrectly in that case! */
-+
-+typedef long Int64;
-+typedef unsigned long UInt64;
-+
-+#else
-+
-+#if defined(_MSC_VER) || defined(__BORLANDC__)
-+typedef __int64 Int64;
-+typedef unsigned __int64 UInt64;
-+#else
-+typedef long long int Int64;
-+typedef unsigned long long int UInt64;
-+#endif
-+
-+#endif
-+
-+#ifdef _LZMA_NO_SYSTEM_SIZE_T
-+typedef UInt32 SizeT;
-+#else
-+typedef size_t SizeT;
-+#endif
-+
-+typedef int Bool;
-+#define True 1
-+#define False 0
-+
-+
-+#ifdef _WIN32
-+#define MY_STD_CALL __stdcall
-+#else
-+#define MY_STD_CALL
-+#endif
-+
-+#ifdef _MSC_VER
-+
-+#if _MSC_VER >= 1300
-+#define MY_NO_INLINE __declspec(noinline)
-+#else
-+#define MY_NO_INLINE
-+#endif
-+
-+#define MY_CDECL __cdecl
-+#define MY_FAST_CALL __fastcall
-+
-+#else
-+
-+#define MY_CDECL
-+#define MY_FAST_CALL
-+
-+#endif
-+
-+
-+/* The following interfaces use first parameter as pointer to structure */
-+
-+typedef struct
-+{
-+ SRes (*Read)(void *p, void *buf, size_t *size);
-+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
-+ (output(*size) < input(*size)) is allowed */
-+} ISeqInStream;
-+
-+/* it can return SZ_ERROR_INPUT_EOF */
-+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
-+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
-+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
-+
-+typedef struct
-+{
-+ size_t (*Write)(void *p, const void *buf, size_t size);
-+ /* Returns: result - the number of actually written bytes.
-+ (result < size) means error */
-+} ISeqOutStream;
-+
-+typedef enum
-+{
-+ SZ_SEEK_SET = 0,
-+ SZ_SEEK_CUR = 1,
-+ SZ_SEEK_END = 2
-+} ESzSeek;
-+
-+typedef struct
-+{
-+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
-+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-+} ISeekInStream;
-+
-+typedef struct
-+{
-+ SRes (*Look)(void *p, void **buf, size_t *size);
-+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
-+ (output(*size) > input(*size)) is not allowed
-+ (output(*size) < input(*size)) is allowed */
-+ SRes (*Skip)(void *p, size_t offset);
-+ /* offset must be <= output(*size) of Look */
-+
-+ SRes (*Read)(void *p, void *buf, size_t *size);
-+ /* reads directly (without buffer). It's same as ISeqInStream::Read */
-+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-+} ILookInStream;
-+
-+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
-+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
-+
-+/* reads via ILookInStream::Read */
-+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
-+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
-+
-+#define LookToRead_BUF_SIZE (1 << 14)
-+
-+typedef struct
-+{
-+ ILookInStream s;
-+ ISeekInStream *realStream;
-+ size_t pos;
-+ size_t size;
-+ Byte buf[LookToRead_BUF_SIZE];
-+} CLookToRead;
-+
-+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
-+void LookToRead_Init(CLookToRead *p);
-+
-+typedef struct
-+{
-+ ISeqInStream s;
-+ ILookInStream *realStream;
-+} CSecToLook;
-+
-+void SecToLook_CreateVTable(CSecToLook *p);
-+
-+typedef struct
-+{
-+ ISeqInStream s;
-+ ILookInStream *realStream;
-+} CSecToRead;
-+
-+void SecToRead_CreateVTable(CSecToRead *p);
-+
-+typedef struct
-+{
-+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
-+ /* Returns: result. (result != SZ_OK) means break.
-+ Value (UInt64)(Int64)-1 for size means unknown value. */
-+} ICompressProgress;
-+
-+typedef struct
-+{
-+ void *(*Alloc)(void *p, size_t size);
-+ void (*Free)(void *p, void *address); /* address can be 0 */
-+} ISzAlloc;
-+
-+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-+#define IAlloc_Free(p, a) (p)->Free((p), a)
-+
-+EXTERN_C_END
-+
-+#endif
---- a/include/uapi/linux/jffs2.h
-+++ b/include/uapi/linux/jffs2.h
-@@ -46,6 +46,7 @@
- #define JFFS2_COMPR_DYNRUBIN 0x05
- #define JFFS2_COMPR_ZLIB 0x06
- #define JFFS2_COMPR_LZO 0x07
-+#define JFFS2_COMPR_LZMA 0x08
- /* Compatibility flags. */
- #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
- #define JFFS2_NODE_ACCURATE 0x2000
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -354,6 +354,12 @@ config ZSTD_DECOMPRESS
-
- source "lib/xz/Kconfig"
-
-+config LZMA_COMPRESS
-+ tristate
-+
-+config LZMA_DECOMPRESS
-+ tristate
-+
- #
- # These all provide a common interface (hence the apparent duplication with
- # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -140,6 +140,16 @@ CFLAGS_kobject.o += -DDEBUG
- CFLAGS_kobject_uevent.o += -DDEBUG
- endif
-
-+ifdef CONFIG_JFFS2_ZLIB
-+ CONFIG_ZLIB_INFLATE:=y
-+ CONFIG_ZLIB_DEFLATE:=y
-+endif
-+
-+ifdef CONFIG_JFFS2_LZMA
-+ CONFIG_LZMA_DECOMPRESS:=y
-+ CONFIG_LZMA_COMPRESS:=y
-+endif
-+
- obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o
- CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any)
-
-@@ -200,6 +210,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/
- obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/
- obj-$(CONFIG_XZ_DEC) += xz/
- obj-$(CONFIG_RAID6_PQ) += raid6/
-+obj-$(CONFIG_LZMA_COMPRESS) += lzma/
-+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/
-
- lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
- lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
---- /dev/null
-+++ b/lib/lzma/LzFind.c
-@@ -0,0 +1,761 @@
-+/* LzFind.c -- Match finder for LZ algorithms
-+2009-04-22 : Igor Pavlov : Public domain */
-+
-+#include <string.h>
-+
-+#include "LzFind.h"
-+#include "LzHash.h"
-+
-+#define kEmptyHashValue 0
-+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
-+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
-+#define kNormalizeMask (~(kNormalizeStepMin - 1))
-+#define kMaxHistorySize ((UInt32)3 << 30)
-+
-+#define kStartMaxLen 3
-+
-+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+ if (!p->directInput)
-+ {
-+ alloc->Free(alloc, p->bufferBase);
-+ p->bufferBase = 0;
-+ }
-+}
-+
-+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
-+
-+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
-+{
-+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
-+ if (p->directInput)
-+ {
-+ p->blockSize = blockSize;
-+ return 1;
-+ }
-+ if (p->bufferBase == 0 || p->blockSize != blockSize)
-+ {
-+ LzInWindow_Free(p, alloc);
-+ p->blockSize = blockSize;
-+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
-+ }
-+ return (p->bufferBase != 0);
-+}
-+
-+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
-+
-+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
-+
-+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
-+{
-+ p->posLimit -= subValue;
-+ p->pos -= subValue;
-+ p->streamPos -= subValue;
-+}
-+
-+static void MatchFinder_ReadBlock(CMatchFinder *p)
-+{
-+ if (p->streamEndWasReached || p->result != SZ_OK)
-+ return;
-+ if (p->directInput)
-+ {
-+ UInt32 curSize = 0xFFFFFFFF - p->streamPos;
-+ if (curSize > p->directInputRem)
-+ curSize = (UInt32)p->directInputRem;
-+ p->directInputRem -= curSize;
-+ p->streamPos += curSize;
-+ if (p->directInputRem == 0)
-+ p->streamEndWasReached = 1;
-+ return;
-+ }
-+ for (;;)
-+ {
-+ Byte *dest = p->buffer + (p->streamPos - p->pos);
-+ size_t size = (p->bufferBase + p->blockSize - dest);
-+ if (size == 0)
-+ return;
-+ p->result = p->stream->Read(p->stream, dest, &size);
-+ if (p->result != SZ_OK)
-+ return;
-+ if (size == 0)
-+ {
-+ p->streamEndWasReached = 1;
-+ return;
-+ }
-+ p->streamPos += (UInt32)size;
-+ if (p->streamPos - p->pos > p->keepSizeAfter)
-+ return;
-+ }
-+}
-+
-+void MatchFinder_MoveBlock(CMatchFinder *p)
-+{
-+ memmove(p->bufferBase,
-+ p->buffer - p->keepSizeBefore,
-+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
-+ p->buffer = p->bufferBase + p->keepSizeBefore;
-+}
-+
-+int MatchFinder_NeedMove(CMatchFinder *p)
-+{
-+ if (p->directInput)
-+ return 0;
-+ /* if (p->streamEndWasReached) return 0; */
-+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
-+}
-+
-+void MatchFinder_ReadIfRequired(CMatchFinder *p)
-+{
-+ if (p->streamEndWasReached)
-+ return;
-+ if (p->keepSizeAfter >= p->streamPos - p->pos)
-+ MatchFinder_ReadBlock(p);
-+}
-+
-+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
-+{
-+ if (MatchFinder_NeedMove(p))
-+ MatchFinder_MoveBlock(p);
-+ MatchFinder_ReadBlock(p);
-+}
-+
-+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
-+{
-+ p->cutValue = 32;
-+ p->btMode = 1;
-+ p->numHashBytes = 4;
-+ p->bigHash = 0;
-+}
-+
-+#define kCrcPoly 0xEDB88320
-+
-+void MatchFinder_Construct(CMatchFinder *p)
-+{
-+ UInt32 i;
-+ p->bufferBase = 0;
-+ p->directInput = 0;
-+ p->hash = 0;
-+ MatchFinder_SetDefaultSettings(p);
-+
-+ for (i = 0; i < 256; i++)
-+ {
-+ UInt32 r = i;
-+ int j;
-+ for (j = 0; j < 8; j++)
-+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
-+ p->crc[i] = r;
-+ }
-+}
-+
-+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->hash);
-+ p->hash = 0;
-+}
-+
-+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+ MatchFinder_FreeThisClassMemory(p, alloc);
-+ LzInWindow_Free(p, alloc);
-+}
-+
-+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
-+{
-+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
-+ if (sizeInBytes / sizeof(CLzRef) != num)
-+ return 0;
-+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
-+}
-+
-+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-+ ISzAlloc *alloc)
-+{
-+ UInt32 sizeReserv;
-+ if (historySize > kMaxHistorySize)
-+ {
-+ MatchFinder_Free(p, alloc);
-+ return 0;
-+ }
-+ sizeReserv = historySize >> 1;
-+ if (historySize > ((UInt32)2 << 30))
-+ sizeReserv = historySize >> 2;
-+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
-+
-+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
-+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
-+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
-+ if (LzInWindow_Create(p, sizeReserv, alloc))
-+ {
-+ UInt32 newCyclicBufferSize = historySize + 1;
-+ UInt32 hs;
-+ p->matchMaxLen = matchMaxLen;
-+ {
-+ p->fixedHashSize = 0;
-+ if (p->numHashBytes == 2)
-+ hs = (1 << 16) - 1;
-+ else
-+ {
-+ hs = historySize - 1;
-+ hs |= (hs >> 1);
-+ hs |= (hs >> 2);
-+ hs |= (hs >> 4);
-+ hs |= (hs >> 8);
-+ hs >>= 1;
-+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
-+ if (hs > (1 << 24))
-+ {
-+ if (p->numHashBytes == 3)
-+ hs = (1 << 24) - 1;
-+ else
-+ hs >>= 1;
-+ }
-+ }
-+ p->hashMask = hs;
-+ hs++;
-+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
-+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
-+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
-+ hs += p->fixedHashSize;
-+ }
-+
-+ {
-+ UInt32 prevSize = p->hashSizeSum + p->numSons;
-+ UInt32 newSize;
-+ p->historySize = historySize;
-+ p->hashSizeSum = hs;
-+ p->cyclicBufferSize = newCyclicBufferSize;
-+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
-+ newSize = p->hashSizeSum + p->numSons;
-+ if (p->hash != 0 && prevSize == newSize)
-+ return 1;
-+ MatchFinder_FreeThisClassMemory(p, alloc);
-+ p->hash = AllocRefs(newSize, alloc);
-+ if (p->hash != 0)
-+ {
-+ p->son = p->hash + p->hashSizeSum;
-+ return 1;
-+ }
-+ }
-+ }
-+ MatchFinder_Free(p, alloc);
-+ return 0;
-+}
-+
-+static void MatchFinder_SetLimits(CMatchFinder *p)
-+{
-+ UInt32 limit = kMaxValForNormalize - p->pos;
-+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
-+ if (limit2 < limit)
-+ limit = limit2;
-+ limit2 = p->streamPos - p->pos;
-+ if (limit2 <= p->keepSizeAfter)
-+ {
-+ if (limit2 > 0)
-+ limit2 = 1;
-+ }
-+ else
-+ limit2 -= p->keepSizeAfter;
-+ if (limit2 < limit)
-+ limit = limit2;
-+ {
-+ UInt32 lenLimit = p->streamPos - p->pos;
-+ if (lenLimit > p->matchMaxLen)
-+ lenLimit = p->matchMaxLen;
-+ p->lenLimit = lenLimit;
-+ }
-+ p->posLimit = p->pos + limit;
-+}
-+
-+void MatchFinder_Init(CMatchFinder *p)
-+{
-+ UInt32 i;
-+ for (i = 0; i < p->hashSizeSum; i++)
-+ p->hash[i] = kEmptyHashValue;
-+ p->cyclicBufferPos = 0;
-+ p->buffer = p->bufferBase;
-+ p->pos = p->streamPos = p->cyclicBufferSize;
-+ p->result = SZ_OK;
-+ p->streamEndWasReached = 0;
-+ MatchFinder_ReadBlock(p);
-+ MatchFinder_SetLimits(p);
-+}
-+
-+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
-+{
-+ return (p->pos - p->historySize - 1) & kNormalizeMask;
-+}
-+
-+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
-+{
-+ UInt32 i;
-+ for (i = 0; i < numItems; i++)
-+ {
-+ UInt32 value = items[i];
-+ if (value <= subValue)
-+ value = kEmptyHashValue;
-+ else
-+ value -= subValue;
-+ items[i] = value;
-+ }
-+}
-+
-+static void MatchFinder_Normalize(CMatchFinder *p)
-+{
-+ UInt32 subValue = MatchFinder_GetSubValue(p);
-+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
-+ MatchFinder_ReduceOffsets(p, subValue);
-+}
-+
-+static void MatchFinder_CheckLimits(CMatchFinder *p)
-+{
-+ if (p->pos == kMaxValForNormalize)
-+ MatchFinder_Normalize(p);
-+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
-+ MatchFinder_CheckAndMoveAndRead(p);
-+ if (p->cyclicBufferPos == p->cyclicBufferSize)
-+ p->cyclicBufferPos = 0;
-+ MatchFinder_SetLimits(p);
-+}
-+
-+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-+ UInt32 *distances, UInt32 maxLen)
-+{
-+ son[_cyclicBufferPos] = curMatch;
-+ for (;;)
-+ {
-+ UInt32 delta = pos - curMatch;
-+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+ return distances;
-+ {
-+ const Byte *pb = cur - delta;
-+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
-+ if (pb[maxLen] == cur[maxLen] && *pb == *cur)
-+ {
-+ UInt32 len = 0;
-+ while (++len != lenLimit)
-+ if (pb[len] != cur[len])
-+ break;
-+ if (maxLen < len)
-+ {
-+ *distances++ = maxLen = len;
-+ *distances++ = delta - 1;
-+ if (len == lenLimit)
-+ return distances;
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-+ UInt32 *distances, UInt32 maxLen)
-+{
-+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-+ UInt32 len0 = 0, len1 = 0;
-+ for (;;)
-+ {
-+ UInt32 delta = pos - curMatch;
-+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+ {
-+ *ptr0 = *ptr1 = kEmptyHashValue;
-+ return distances;
-+ }
-+ {
-+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-+ const Byte *pb = cur - delta;
-+ UInt32 len = (len0 < len1 ? len0 : len1);
-+ if (pb[len] == cur[len])
-+ {
-+ if (++len != lenLimit && pb[len] == cur[len])
-+ while (++len != lenLimit)
-+ if (pb[len] != cur[len])
-+ break;
-+ if (maxLen < len)
-+ {
-+ *distances++ = maxLen = len;
-+ *distances++ = delta - 1;
-+ if (len == lenLimit)
-+ {
-+ *ptr1 = pair[0];
-+ *ptr0 = pair[1];
-+ return distances;
-+ }
-+ }
-+ }
-+ if (pb[len] < cur[len])
-+ {
-+ *ptr1 = curMatch;
-+ ptr1 = pair + 1;
-+ curMatch = *ptr1;
-+ len1 = len;
-+ }
-+ else
-+ {
-+ *ptr0 = curMatch;
-+ ptr0 = pair;
-+ curMatch = *ptr0;
-+ len0 = len;
-+ }
-+ }
-+ }
-+}
-+
-+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
-+{
-+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-+ UInt32 len0 = 0, len1 = 0;
-+ for (;;)
-+ {
-+ UInt32 delta = pos - curMatch;
-+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+ {
-+ *ptr0 = *ptr1 = kEmptyHashValue;
-+ return;
-+ }
-+ {
-+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-+ const Byte *pb = cur - delta;
-+ UInt32 len = (len0 < len1 ? len0 : len1);
-+ if (pb[len] == cur[len])
-+ {
-+ while (++len != lenLimit)
-+ if (pb[len] != cur[len])
-+ break;
-+ {
-+ if (len == lenLimit)
-+ {
-+ *ptr1 = pair[0];
-+ *ptr0 = pair[1];
-+ return;
-+ }
-+ }
-+ }
-+ if (pb[len] < cur[len])
-+ {
-+ *ptr1 = curMatch;
-+ ptr1 = pair + 1;
-+ curMatch = *ptr1;
-+ len1 = len;
-+ }
-+ else
-+ {
-+ *ptr0 = curMatch;
-+ ptr0 = pair;
-+ curMatch = *ptr0;
-+ len0 = len;
-+ }
-+ }
-+ }
-+}
-+
-+#define MOVE_POS \
-+ ++p->cyclicBufferPos; \
-+ p->buffer++; \
-+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
-+
-+#define MOVE_POS_RET MOVE_POS return offset;
-+
-+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
-+
-+#define GET_MATCHES_HEADER2(minLen, ret_op) \
-+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
-+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
-+ cur = p->buffer;
-+
-+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
-+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
-+
-+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
-+
-+#define GET_MATCHES_FOOTER(offset, maxLen) \
-+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
-+ distances + offset, maxLen) - distances); MOVE_POS_RET;
-+
-+#define SKIP_FOOTER \
-+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
-+
-+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+ UInt32 offset;
-+ GET_MATCHES_HEADER(2)
-+ HASH2_CALC;
-+ curMatch = p->hash[hashValue];
-+ p->hash[hashValue] = p->pos;
-+ offset = 0;
-+ GET_MATCHES_FOOTER(offset, 1)
-+}
-+
-+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+ UInt32 offset;
-+ GET_MATCHES_HEADER(3)
-+ HASH_ZIP_CALC;
-+ curMatch = p->hash[hashValue];
-+ p->hash[hashValue] = p->pos;
-+ offset = 0;
-+ GET_MATCHES_FOOTER(offset, 2)
-+}
-+
-+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+ UInt32 hash2Value, delta2, maxLen, offset;
-+ GET_MATCHES_HEADER(3)
-+
-+ HASH3_CALC;
-+
-+ delta2 = p->pos - p->hash[hash2Value];
-+ curMatch = p->hash[kFix3HashSize + hashValue];
-+
-+ p->hash[hash2Value] =
-+ p->hash[kFix3HashSize + hashValue] = p->pos;
-+
-+
-+ maxLen = 2;
-+ offset = 0;
-+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-+ {
-+ for (; maxLen != lenLimit; maxLen++)
-+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-+ break;
-+ distances[0] = maxLen;
-+ distances[1] = delta2 - 1;
-+ offset = 2;
-+ if (maxLen == lenLimit)
-+ {
-+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
-+ MOVE_POS_RET;
-+ }
-+ }
-+ GET_MATCHES_FOOTER(offset, maxLen)
-+}
-+
-+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
-+ GET_MATCHES_HEADER(4)
-+
-+ HASH4_CALC;
-+
-+ delta2 = p->pos - p->hash[ hash2Value];
-+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
-+ curMatch = p->hash[kFix4HashSize + hashValue];
-+
-+ p->hash[ hash2Value] =
-+ p->hash[kFix3HashSize + hash3Value] =
-+ p->hash[kFix4HashSize + hashValue] = p->pos;
-+
-+ maxLen = 1;
-+ offset = 0;
-+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-+ {
-+ distances[0] = maxLen = 2;
-+ distances[1] = delta2 - 1;
-+ offset = 2;
-+ }
-+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
-+ {
-+ maxLen = 3;
-+ distances[offset + 1] = delta3 - 1;
-+ offset += 2;
-+ delta2 = delta3;
-+ }
-+ if (offset != 0)
-+ {
-+ for (; maxLen != lenLimit; maxLen++)
-+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-+ break;
-+ distances[offset - 2] = maxLen;
-+ if (maxLen == lenLimit)
-+ {
-+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
-+ MOVE_POS_RET;
-+ }
-+ }
-+ if (maxLen < 3)
-+ maxLen = 3;
-+ GET_MATCHES_FOOTER(offset, maxLen)
-+}
-+
-+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
-+ GET_MATCHES_HEADER(4)
-+
-+ HASH4_CALC;
-+
-+ delta2 = p->pos - p->hash[ hash2Value];
-+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
-+ curMatch = p->hash[kFix4HashSize + hashValue];
-+
-+ p->hash[ hash2Value] =
-+ p->hash[kFix3HashSize + hash3Value] =
-+ p->hash[kFix4HashSize + hashValue] = p->pos;
-+
-+ maxLen = 1;
-+ offset = 0;
-+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-+ {
-+ distances[0] = maxLen = 2;
-+ distances[1] = delta2 - 1;
-+ offset = 2;
-+ }
-+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
-+ {
-+ maxLen = 3;
-+ distances[offset + 1] = delta3 - 1;
-+ offset += 2;
-+ delta2 = delta3;
-+ }
-+ if (offset != 0)
-+ {
-+ for (; maxLen != lenLimit; maxLen++)
-+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-+ break;
-+ distances[offset - 2] = maxLen;
-+ if (maxLen == lenLimit)
-+ {
-+ p->son[p->cyclicBufferPos] = curMatch;
-+ MOVE_POS_RET;
-+ }
-+ }
-+ if (maxLen < 3)
-+ maxLen = 3;
-+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
-+ distances + offset, maxLen) - (distances));
-+ MOVE_POS_RET
-+}
-+
-+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+ UInt32 offset;
-+ GET_MATCHES_HEADER(3)
-+ HASH_ZIP_CALC;
-+ curMatch = p->hash[hashValue];
-+ p->hash[hashValue] = p->pos;
-+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
-+ distances, 2) - (distances));
-+ MOVE_POS_RET
-+}
-+
-+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+ do
-+ {
-+ SKIP_HEADER(2)
-+ HASH2_CALC;
-+ curMatch = p->hash[hashValue];
-+ p->hash[hashValue] = p->pos;
-+ SKIP_FOOTER
-+ }
-+ while (--num != 0);
-+}
-+
-+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+ do
-+ {
-+ SKIP_HEADER(3)
-+ HASH_ZIP_CALC;
-+ curMatch = p->hash[hashValue];
-+ p->hash[hashValue] = p->pos;
-+ SKIP_FOOTER
-+ }
-+ while (--num != 0);
-+}
-+
-+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+ do
-+ {
-+ UInt32 hash2Value;
-+ SKIP_HEADER(3)
-+ HASH3_CALC;
-+ curMatch = p->hash[kFix3HashSize + hashValue];
-+ p->hash[hash2Value] =
-+ p->hash[kFix3HashSize + hashValue] = p->pos;
-+ SKIP_FOOTER
-+ }
-+ while (--num != 0);
-+}
-+
-+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+ do
-+ {
-+ UInt32 hash2Value, hash3Value;
-+ SKIP_HEADER(4)
-+ HASH4_CALC;
-+ curMatch = p->hash[kFix4HashSize + hashValue];
-+ p->hash[ hash2Value] =
-+ p->hash[kFix3HashSize + hash3Value] = p->pos;
-+ p->hash[kFix4HashSize + hashValue] = p->pos;
-+ SKIP_FOOTER
-+ }
-+ while (--num != 0);
-+}
-+
-+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+ do
-+ {
-+ UInt32 hash2Value, hash3Value;
-+ SKIP_HEADER(4)
-+ HASH4_CALC;
-+ curMatch = p->hash[kFix4HashSize + hashValue];
-+ p->hash[ hash2Value] =
-+ p->hash[kFix3HashSize + hash3Value] =
-+ p->hash[kFix4HashSize + hashValue] = p->pos;
-+ p->son[p->cyclicBufferPos] = curMatch;
-+ MOVE_POS
-+ }
-+ while (--num != 0);
-+}
-+
-+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+ do
-+ {
-+ SKIP_HEADER(3)
-+ HASH_ZIP_CALC;
-+ curMatch = p->hash[hashValue];
-+ p->hash[hashValue] = p->pos;
-+ p->son[p->cyclicBufferPos] = curMatch;
-+ MOVE_POS
-+ }
-+ while (--num != 0);
-+}
-+
-+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
-+{
-+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
-+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
-+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
-+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
-+ if (!p->btMode)
-+ {
-+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
-+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
-+ }
-+ else if (p->numHashBytes == 2)
-+ {
-+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
-+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
-+ }
-+ else if (p->numHashBytes == 3)
-+ {
-+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
-+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
-+ }
-+ else
-+ {
-+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
-+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
-+ }
-+}
---- /dev/null
-+++ b/lib/lzma/LzmaDec.c
-@@ -0,0 +1,999 @@
-+/* LzmaDec.c -- LZMA Decoder
-+2009-09-20 : Igor Pavlov : Public domain */
-+
-+#include "LzmaDec.h"
-+
-+#include <string.h>
-+
-+#define kNumTopBits 24
-+#define kTopValue ((UInt32)1 << kNumTopBits)
-+
-+#define kNumBitModelTotalBits 11
-+#define kBitModelTotal (1 << kNumBitModelTotalBits)
-+#define kNumMoveBits 5
-+
-+#define RC_INIT_SIZE 5
-+
-+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
-+
-+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
-+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
-+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
-+ { UPDATE_0(p); i = (i + i); A0; } else \
-+ { UPDATE_1(p); i = (i + i) + 1; A1; }
-+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
-+
-+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
-+#define TREE_DECODE(probs, limit, i) \
-+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
-+
-+/* #define _LZMA_SIZE_OPT */
-+
-+#ifdef _LZMA_SIZE_OPT
-+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
-+#else
-+#define TREE_6_DECODE(probs, i) \
-+ { i = 1; \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ TREE_GET_BIT(probs, i); \
-+ i -= 0x40; }
-+#endif
-+
-+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
-+
-+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-+#define UPDATE_0_CHECK range = bound;
-+#define UPDATE_1_CHECK range -= bound; code -= bound;
-+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
-+ { UPDATE_0_CHECK; i = (i + i); A0; } else \
-+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
-+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
-+#define TREE_DECODE_CHECK(probs, limit, i) \
-+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
-+
-+
-+#define kNumPosBitsMax 4
-+#define kNumPosStatesMax (1 << kNumPosBitsMax)
-+
-+#define kLenNumLowBits 3
-+#define kLenNumLowSymbols (1 << kLenNumLowBits)
-+#define kLenNumMidBits 3
-+#define kLenNumMidSymbols (1 << kLenNumMidBits)
-+#define kLenNumHighBits 8
-+#define kLenNumHighSymbols (1 << kLenNumHighBits)
-+
-+#define LenChoice 0
-+#define LenChoice2 (LenChoice + 1)
-+#define LenLow (LenChoice2 + 1)
-+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-+
-+
-+#define kNumStates 12
-+#define kNumLitStates 7
-+
-+#define kStartPosModelIndex 4
-+#define kEndPosModelIndex 14
-+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-+
-+#define kNumPosSlotBits 6
-+#define kNumLenToPosStates 4
-+
-+#define kNumAlignBits 4
-+#define kAlignTableSize (1 << kNumAlignBits)
-+
-+#define kMatchMinLen 2
-+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-+
-+#define IsMatch 0
-+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-+#define IsRepG0 (IsRep + kNumStates)
-+#define IsRepG1 (IsRepG0 + kNumStates)
-+#define IsRepG2 (IsRepG1 + kNumStates)
-+#define IsRep0Long (IsRepG2 + kNumStates)
-+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-+#define LenCoder (Align + kAlignTableSize)
-+#define RepLenCoder (LenCoder + kNumLenProbs)
-+#define Literal (RepLenCoder + kNumLenProbs)
-+
-+#define LZMA_BASE_SIZE 1846
-+#define LZMA_LIT_SIZE 768
-+
-+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
-+
-+#if Literal != LZMA_BASE_SIZE
-+StopCompilingDueBUG
-+#endif
-+
-+#define LZMA_DIC_MIN (1 << 12)
-+
-+/* First LZMA-symbol is always decoded.
-+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
-+Out:
-+ Result:
-+ SZ_OK - OK
-+ SZ_ERROR_DATA - Error
-+ p->remainLen:
-+ < kMatchSpecLenStart : normal remain
-+ = kMatchSpecLenStart : finished
-+ = kMatchSpecLenStart + 1 : Flush marker
-+ = kMatchSpecLenStart + 2 : State Init Marker
-+*/
-+
-+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-+{
-+ CLzmaProb *probs = p->probs;
-+
-+ unsigned state = p->state;
-+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
-+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
-+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
-+ unsigned lc = p->prop.lc;
-+
-+ Byte *dic = p->dic;
-+ SizeT dicBufSize = p->dicBufSize;
-+ SizeT dicPos = p->dicPos;
-+
-+ UInt32 processedPos = p->processedPos;
-+ UInt32 checkDicSize = p->checkDicSize;
-+ unsigned len = 0;
-+
-+ const Byte *buf = p->buf;
-+ UInt32 range = p->range;
-+ UInt32 code = p->code;
-+
-+ do
-+ {
-+ CLzmaProb *prob;
-+ UInt32 bound;
-+ unsigned ttt;
-+ unsigned posState = processedPos & pbMask;
-+
-+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0(prob)
-+ {
-+ unsigned symbol;
-+ UPDATE_0(prob);
-+ prob = probs + Literal;
-+ if (checkDicSize != 0 || processedPos != 0)
-+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
-+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
-+
-+ if (state < kNumLitStates)
-+ {
-+ state -= (state < 4) ? state : 3;
-+ symbol = 1;
-+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
-+ }
-+ else
-+ {
-+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+ unsigned offs = 0x100;
-+ state -= (state < 10) ? 3 : 6;
-+ symbol = 1;
-+ do
-+ {
-+ unsigned bit;
-+ CLzmaProb *probLit;
-+ matchByte <<= 1;
-+ bit = (matchByte & offs);
-+ probLit = prob + offs + bit + symbol;
-+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
-+ }
-+ while (symbol < 0x100);
-+ }
-+ dic[dicPos++] = (Byte)symbol;
-+ processedPos++;
-+ continue;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ prob = probs + IsRep + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ state += kNumStates;
-+ prob = probs + LenCoder;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ if (checkDicSize == 0 && processedPos == 0)
-+ return SZ_ERROR_DATA;
-+ prob = probs + IsRepG0 + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+ dicPos++;
-+ processedPos++;
-+ state = state < kNumLitStates ? 9 : 11;
-+ continue;
-+ }
-+ UPDATE_1(prob);
-+ }
-+ else
-+ {
-+ UInt32 distance;
-+ UPDATE_1(prob);
-+ prob = probs + IsRepG1 + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ distance = rep1;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ prob = probs + IsRepG2 + state;
-+ IF_BIT_0(prob)
-+ {
-+ UPDATE_0(prob);
-+ distance = rep2;
-+ }
-+ else
-+ {
-+ UPDATE_1(prob);
-+ distance = rep3;
-+ rep3 = rep2;
-+ }
-+ rep2 = rep1;
-+ }
-+ rep1 = rep0;
-+ rep0 = distance;
-+ }
-+ state = state < kNumLitStates ? 8 : 11;
-+ prob = probs + RepLenCoder;
-+ }
-+ {
-+ unsigned limit, offset;
-+ CLzmaProb *probLen = prob + LenChoice;
-+ IF_BIT_0(probLen)
-+ {
-+ UPDATE_0(probLen);
-+ probLen = prob + LenLow + (posState << kLenNumLowBits);
-+ offset = 0;
-+ limit = (1 << kLenNumLowBits);
-+ }
-+ else
-+ {
-+ UPDATE_1(probLen);
-+ probLen = prob + LenChoice2;
-+ IF_BIT_0(probLen)
-+ {
-+ UPDATE_0(probLen);
-+ probLen = prob + LenMid + (posState << kLenNumMidBits);
-+ offset = kLenNumLowSymbols;
-+ limit = (1 << kLenNumMidBits);
-+ }
-+ else
-+ {
-+ UPDATE_1(probLen);
-+ probLen = prob + LenHigh;
-+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
-+ limit = (1 << kLenNumHighBits);
-+ }
-+ }
-+ TREE_DECODE(probLen, limit, len);
-+ len += offset;
-+ }
-+
-+ if (state >= kNumStates)
-+ {
-+ UInt32 distance;
-+ prob = probs + PosSlot +
-+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
-+ TREE_6_DECODE(prob, distance);
-+ if (distance >= kStartPosModelIndex)
-+ {
-+ unsigned posSlot = (unsigned)distance;
-+ int numDirectBits = (int)(((distance >> 1) - 1));
-+ distance = (2 | (distance & 1));
-+ if (posSlot < kEndPosModelIndex)
-+ {
-+ distance <<= numDirectBits;
-+ prob = probs + SpecPos + distance - posSlot - 1;
-+ {
-+ UInt32 mask = 1;
-+ unsigned i = 1;
-+ do
-+ {
-+ GET_BIT2(prob + i, i, ; , distance |= mask);
-+ mask <<= 1;
-+ }
-+ while (--numDirectBits != 0);
-+ }
-+ }
-+ else
-+ {
-+ numDirectBits -= kNumAlignBits;
-+ do
-+ {
-+ NORMALIZE
-+ range >>= 1;
-+
-+ {
-+ UInt32 t;
-+ code -= range;
-+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
-+ distance = (distance << 1) + (t + 1);
-+ code += range & t;
-+ }
-+ /*
-+ distance <<= 1;
-+ if (code >= range)
-+ {
-+ code -= range;
-+ distance |= 1;
-+ }
-+ */
-+ }
-+ while (--numDirectBits != 0);
-+ prob = probs + Align;
-+ distance <<= kNumAlignBits;
-+ {
-+ unsigned i = 1;
-+ GET_BIT2(prob + i, i, ; , distance |= 1);
-+ GET_BIT2(prob + i, i, ; , distance |= 2);
-+ GET_BIT2(prob + i, i, ; , distance |= 4);
-+ GET_BIT2(prob + i, i, ; , distance |= 8);
-+ }
-+ if (distance == (UInt32)0xFFFFFFFF)
-+ {
-+ len += kMatchSpecLenStart;
-+ state -= kNumStates;
-+ break;
-+ }
-+ }
-+ }
-+ rep3 = rep2;
-+ rep2 = rep1;
-+ rep1 = rep0;
-+ rep0 = distance + 1;
-+ if (checkDicSize == 0)
-+ {
-+ if (distance >= processedPos)
-+ return SZ_ERROR_DATA;
-+ }
-+ else if (distance >= checkDicSize)
-+ return SZ_ERROR_DATA;
-+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
-+ }
-+
-+ len += kMatchMinLen;
-+
-+ if (limit == dicPos)
-+ return SZ_ERROR_DATA;
-+ {
-+ SizeT rem = limit - dicPos;
-+ unsigned curLen = ((rem < len) ? (unsigned)rem : len);
-+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
-+
-+ processedPos += curLen;
-+
-+ len -= curLen;
-+ if (pos + curLen <= dicBufSize)
-+ {
-+ Byte *dest = dic + dicPos;
-+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
-+ const Byte *lim = dest + curLen;
-+ dicPos += curLen;
-+ do
-+ *(dest) = (Byte)*(dest + src);
-+ while (++dest != lim);
-+ }
-+ else
-+ {
-+ do
-+ {
-+ dic[dicPos++] = dic[pos];
-+ if (++pos == dicBufSize)
-+ pos = 0;
-+ }
-+ while (--curLen != 0);
-+ }
-+ }
-+ }
-+ }
-+ while (dicPos < limit && buf < bufLimit);
-+ NORMALIZE;
-+ p->buf = buf;
-+ p->range = range;
-+ p->code = code;
-+ p->remainLen = len;
-+ p->dicPos = dicPos;
-+ p->processedPos = processedPos;
-+ p->reps[0] = rep0;
-+ p->reps[1] = rep1;
-+ p->reps[2] = rep2;
-+ p->reps[3] = rep3;
-+ p->state = state;
-+
-+ return SZ_OK;
-+}
-+
-+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
-+{
-+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
-+ {
-+ Byte *dic = p->dic;
-+ SizeT dicPos = p->dicPos;
-+ SizeT dicBufSize = p->dicBufSize;
-+ unsigned len = p->remainLen;
-+ UInt32 rep0 = p->reps[0];
-+ if (limit - dicPos < len)
-+ len = (unsigned)(limit - dicPos);
-+
-+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
-+ p->checkDicSize = p->prop.dicSize;
-+
-+ p->processedPos += len;
-+ p->remainLen -= len;
-+ while (len-- != 0)
-+ {
-+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+ dicPos++;
-+ }
-+ p->dicPos = dicPos;
-+ }
-+}
-+
-+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-+{
-+ do
-+ {
-+ SizeT limit2 = limit;
-+ if (p->checkDicSize == 0)
-+ {
-+ UInt32 rem = p->prop.dicSize - p->processedPos;
-+ if (limit - p->dicPos > rem)
-+ limit2 = p->dicPos + rem;
-+ }
-+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
-+ if (p->processedPos >= p->prop.dicSize)
-+ p->checkDicSize = p->prop.dicSize;
-+ LzmaDec_WriteRem(p, limit);
-+ }
-+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
-+
-+ if (p->remainLen > kMatchSpecLenStart)
-+ {
-+ p->remainLen = kMatchSpecLenStart;
-+ }
-+ return 0;
-+}
-+
-+typedef enum
-+{
-+ DUMMY_ERROR, /* unexpected end of input stream */
-+ DUMMY_LIT,
-+ DUMMY_MATCH,
-+ DUMMY_REP
-+} ELzmaDummy;
-+
-+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
-+{
-+ UInt32 range = p->range;
-+ UInt32 code = p->code;
-+ const Byte *bufLimit = buf + inSize;
-+ CLzmaProb *probs = p->probs;
-+ unsigned state = p->state;
-+ ELzmaDummy res;
-+
-+ {
-+ CLzmaProb *prob;
-+ UInt32 bound;
-+ unsigned ttt;
-+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
-+
-+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK
-+
-+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
-+
-+ prob = probs + Literal;
-+ if (p->checkDicSize != 0 || p->processedPos != 0)
-+ prob += (LZMA_LIT_SIZE *
-+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
-+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
-+
-+ if (state < kNumLitStates)
-+ {
-+ unsigned symbol = 1;
-+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
-+ }
-+ else
-+ {
-+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
-+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
-+ unsigned offs = 0x100;
-+ unsigned symbol = 1;
-+ do
-+ {
-+ unsigned bit;
-+ CLzmaProb *probLit;
-+ matchByte <<= 1;
-+ bit = (matchByte & offs);
-+ probLit = prob + offs + bit + symbol;
-+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
-+ }
-+ while (symbol < 0x100);
-+ }
-+ res = DUMMY_LIT;
-+ }
-+ else
-+ {
-+ unsigned len;
-+ UPDATE_1_CHECK;
-+
-+ prob = probs + IsRep + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ state = 0;
-+ prob = probs + LenCoder;
-+ res = DUMMY_MATCH;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ res = DUMMY_REP;
-+ prob = probs + IsRepG0 + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ NORMALIZE_CHECK;
-+ return DUMMY_REP;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ }
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ prob = probs + IsRepG1 + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ prob = probs + IsRepG2 + state;
-+ IF_BIT_0_CHECK(prob)
-+ {
-+ UPDATE_0_CHECK;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ }
-+ }
-+ }
-+ state = kNumStates;
-+ prob = probs + RepLenCoder;
-+ }
-+ {
-+ unsigned limit, offset;
-+ CLzmaProb *probLen = prob + LenChoice;
-+ IF_BIT_0_CHECK(probLen)
-+ {
-+ UPDATE_0_CHECK;
-+ probLen = prob + LenLow + (posState << kLenNumLowBits);
-+ offset = 0;
-+ limit = 1 << kLenNumLowBits;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ probLen = prob + LenChoice2;
-+ IF_BIT_0_CHECK(probLen)
-+ {
-+ UPDATE_0_CHECK;
-+ probLen = prob + LenMid + (posState << kLenNumMidBits);
-+ offset = kLenNumLowSymbols;
-+ limit = 1 << kLenNumMidBits;
-+ }
-+ else
-+ {
-+ UPDATE_1_CHECK;
-+ probLen = prob + LenHigh;
-+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
-+ limit = 1 << kLenNumHighBits;
-+ }
-+ }
-+ TREE_DECODE_CHECK(probLen, limit, len);
-+ len += offset;
-+ }
-+
-+ if (state < 4)
-+ {
-+ unsigned posSlot;
-+ prob = probs + PosSlot +
-+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
-+ kNumPosSlotBits);
-+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
-+ if (posSlot >= kStartPosModelIndex)
-+ {
-+ int numDirectBits = ((posSlot >> 1) - 1);
-+
-+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
-+
-+ if (posSlot < kEndPosModelIndex)
-+ {
-+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
-+ }
-+ else
-+ {
-+ numDirectBits -= kNumAlignBits;
-+ do
-+ {
-+ NORMALIZE_CHECK
-+ range >>= 1;
-+ code -= range & (((code - range) >> 31) - 1);
-+ /* if (code >= range) code -= range; */
-+ }
-+ while (--numDirectBits != 0);
-+ prob = probs + Align;
-+ numDirectBits = kNumAlignBits;
-+ }
-+ {
-+ unsigned i = 1;
-+ do
-+ {
-+ GET_BIT_CHECK(prob + i, i);
-+ }
-+ while (--numDirectBits != 0);
-+ }
-+ }
-+ }
-+ }
-+ }
-+ NORMALIZE_CHECK;
-+ return res;
-+}
-+
-+
-+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-+{
-+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
-+ p->range = 0xFFFFFFFF;
-+ p->needFlush = 0;
-+}
-+
-+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
-+{
-+ p->needFlush = 1;
-+ p->remainLen = 0;
-+ p->tempBufSize = 0;
-+
-+ if (initDic)
-+ {
-+ p->processedPos = 0;
-+ p->checkDicSize = 0;
-+ p->needInitState = 1;
-+ }
-+ if (initState)
-+ p->needInitState = 1;
-+}
-+
-+void LzmaDec_Init(CLzmaDec *p)
-+{
-+ p->dicPos = 0;
-+ LzmaDec_InitDicAndState(p, True, True);
-+}
-+
-+static void LzmaDec_InitStateReal(CLzmaDec *p)
-+{
-+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
-+ UInt32 i;
-+ CLzmaProb *probs = p->probs;
-+ for (i = 0; i < numProbs; i++)
-+ probs[i] = kBitModelTotal >> 1;
-+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
-+ p->state = 0;
-+ p->needInitState = 0;
-+}
-+
-+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
-+ ELzmaFinishMode finishMode, ELzmaStatus *status)
-+{
-+ SizeT inSize = *srcLen;
-+ (*srcLen) = 0;
-+ LzmaDec_WriteRem(p, dicLimit);
-+
-+ *status = LZMA_STATUS_NOT_SPECIFIED;
-+
-+ while (p->remainLen != kMatchSpecLenStart)
-+ {
-+ int checkEndMarkNow;
-+
-+ if (p->needFlush != 0)
-+ {
-+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
-+ p->tempBuf[p->tempBufSize++] = *src++;
-+ if (p->tempBufSize < RC_INIT_SIZE)
-+ {
-+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+ return SZ_OK;
-+ }
-+ if (p->tempBuf[0] != 0)
-+ return SZ_ERROR_DATA;
-+
-+ LzmaDec_InitRc(p, p->tempBuf);
-+ p->tempBufSize = 0;
-+ }
-+
-+ checkEndMarkNow = 0;
-+ if (p->dicPos >= dicLimit)
-+ {
-+ if (p->remainLen == 0 && p->code == 0)
-+ {
-+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
-+ return SZ_OK;
-+ }
-+ if (finishMode == LZMA_FINISH_ANY)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_OK;
-+ }
-+ if (p->remainLen != 0)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_ERROR_DATA;
-+ }
-+ checkEndMarkNow = 1;
-+ }
-+
-+ if (p->needInitState)
-+ LzmaDec_InitStateReal(p);
-+
-+ if (p->tempBufSize == 0)
-+ {
-+ SizeT processed;
-+ const Byte *bufLimit;
-+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-+ {
-+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
-+ if (dummyRes == DUMMY_ERROR)
-+ {
-+ memcpy(p->tempBuf, src, inSize);
-+ p->tempBufSize = (unsigned)inSize;
-+ (*srcLen) += inSize;
-+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+ return SZ_OK;
-+ }
-+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_ERROR_DATA;
-+ }
-+ bufLimit = src;
-+ }
-+ else
-+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
-+ p->buf = src;
-+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
-+ return SZ_ERROR_DATA;
-+ processed = (SizeT)(p->buf - src);
-+ (*srcLen) += processed;
-+ src += processed;
-+ inSize -= processed;
-+ }
-+ else
-+ {
-+ unsigned rem = p->tempBufSize, lookAhead = 0;
-+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
-+ p->tempBuf[rem++] = src[lookAhead++];
-+ p->tempBufSize = rem;
-+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-+ {
-+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
-+ if (dummyRes == DUMMY_ERROR)
-+ {
-+ (*srcLen) += lookAhead;
-+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+ return SZ_OK;
-+ }
-+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-+ {
-+ *status = LZMA_STATUS_NOT_FINISHED;
-+ return SZ_ERROR_DATA;
-+ }
-+ }
-+ p->buf = p->tempBuf;
-+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
-+ return SZ_ERROR_DATA;
-+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
-+ (*srcLen) += lookAhead;
-+ src += lookAhead;
-+ inSize -= lookAhead;
-+ p->tempBufSize = 0;
-+ }
-+ }
-+ if (p->code == 0)
-+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
-+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
-+}
-+
-+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
-+{
-+ SizeT outSize = *destLen;
-+ SizeT inSize = *srcLen;
-+ *srcLen = *destLen = 0;
-+ for (;;)
-+ {
-+ SizeT inSizeCur = inSize, outSizeCur, dicPos;
-+ ELzmaFinishMode curFinishMode;
-+ SRes res;
-+ if (p->dicPos == p->dicBufSize)
-+ p->dicPos = 0;
-+ dicPos = p->dicPos;
-+ if (outSize > p->dicBufSize - dicPos)
-+ {
-+ outSizeCur = p->dicBufSize;
-+ curFinishMode = LZMA_FINISH_ANY;
-+ }
-+ else
-+ {
-+ outSizeCur = dicPos + outSize;
-+ curFinishMode = finishMode;
-+ }
-+
-+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
-+ src += inSizeCur;
-+ inSize -= inSizeCur;
-+ *srcLen += inSizeCur;
-+ outSizeCur = p->dicPos - dicPos;
-+ memcpy(dest, p->dic + dicPos, outSizeCur);
-+ dest += outSizeCur;
-+ outSize -= outSizeCur;
-+ *destLen += outSizeCur;
-+ if (res != 0)
-+ return res;
-+ if (outSizeCur == 0 || outSize == 0)
-+ return SZ_OK;
-+ }
-+}
-+
-+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->probs);
-+ p->probs = 0;
-+}
-+
-+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->dic);
-+ p->dic = 0;
-+}
-+
-+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
-+{
-+ LzmaDec_FreeProbs(p, alloc);
-+ LzmaDec_FreeDict(p, alloc);
-+}
-+
-+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
-+{
-+ UInt32 dicSize;
-+ Byte d;
-+
-+ if (size < LZMA_PROPS_SIZE)
-+ return SZ_ERROR_UNSUPPORTED;
-+ else
-+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
-+
-+ if (dicSize < LZMA_DIC_MIN)
-+ dicSize = LZMA_DIC_MIN;
-+ p->dicSize = dicSize;
-+
-+ d = data[0];
-+ if (d >= (9 * 5 * 5))
-+ return SZ_ERROR_UNSUPPORTED;
-+
-+ p->lc = d % 9;
-+ d /= 9;
-+ p->pb = d / 5;
-+ p->lp = d % 5;
-+
-+ return SZ_OK;
-+}
-+
-+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
-+{
-+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
-+ if (p->probs == 0 || numProbs != p->numProbs)
-+ {
-+ LzmaDec_FreeProbs(p, alloc);
-+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
-+ p->numProbs = numProbs;
-+ if (p->probs == 0)
-+ return SZ_ERROR_MEM;
-+ }
-+ return SZ_OK;
-+}
-+
-+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-+{
-+ CLzmaProps propNew;
-+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-+ p->prop = propNew;
-+ return SZ_OK;
-+}
-+
-+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-+{
-+ CLzmaProps propNew;
-+ SizeT dicBufSize;
-+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-+ dicBufSize = propNew.dicSize;
-+ if (p->dic == 0 || dicBufSize != p->dicBufSize)
-+ {
-+ LzmaDec_FreeDict(p, alloc);
-+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
-+ if (p->dic == 0)
-+ {
-+ LzmaDec_FreeProbs(p, alloc);
-+ return SZ_ERROR_MEM;
-+ }
-+ }
-+ p->dicBufSize = dicBufSize;
-+ p->prop = propNew;
-+ return SZ_OK;
-+}
-+
-+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-+ ELzmaStatus *status, ISzAlloc *alloc)
-+{
-+ CLzmaDec p;
-+ SRes res;
-+ SizeT inSize = *srcLen;
-+ SizeT outSize = *destLen;
-+ *srcLen = *destLen = 0;
-+ if (inSize < RC_INIT_SIZE)
-+ return SZ_ERROR_INPUT_EOF;
-+
-+ LzmaDec_Construct(&p);
-+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
-+ if (res != 0)
-+ return res;
-+ p.dic = dest;
-+ p.dicBufSize = outSize;
-+
-+ LzmaDec_Init(&p);
-+
-+ *srcLen = inSize;
-+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
-+
-+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
-+ res = SZ_ERROR_INPUT_EOF;
-+
-+ (*destLen) = p.dicPos;
-+ LzmaDec_FreeProbs(&p, alloc);
-+ return res;
-+}
---- /dev/null
-+++ b/lib/lzma/LzmaEnc.c
-@@ -0,0 +1,2271 @@
-+/* LzmaEnc.c -- LZMA Encoder
-+2009-11-24 : Igor Pavlov : Public domain */
-+
-+#include <string.h>
-+
-+/* #define SHOW_STAT */
-+/* #define SHOW_STAT2 */
-+
-+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
-+#include <stdio.h>
-+#endif
-+
-+#include "LzmaEnc.h"
-+
-+/* disable MT */
-+#define _7ZIP_ST
-+
-+#include "LzFind.h"
-+#ifndef _7ZIP_ST
-+#include "LzFindMt.h"
-+#endif
-+
-+#ifdef SHOW_STAT
-+static int ttt = 0;
-+#endif
-+
-+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
-+
-+#define kBlockSize (9 << 10)
-+#define kUnpackBlockSize (1 << 18)
-+#define kMatchArraySize (1 << 21)
-+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
-+
-+#define kNumMaxDirectBits (31)
-+
-+#define kNumTopBits 24
-+#define kTopValue ((UInt32)1 << kNumTopBits)
-+
-+#define kNumBitModelTotalBits 11
-+#define kBitModelTotal (1 << kNumBitModelTotalBits)
-+#define kNumMoveBits 5
-+#define kProbInitValue (kBitModelTotal >> 1)
-+
-+#define kNumMoveReducingBits 4
-+#define kNumBitPriceShiftBits 4
-+#define kBitPrice (1 << kNumBitPriceShiftBits)
-+
-+void LzmaEncProps_Init(CLzmaEncProps *p)
-+{
-+ p->level = 5;
-+ p->dictSize = p->mc = 0;
-+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
-+ p->writeEndMark = 0;
-+}
-+
-+void LzmaEncProps_Normalize(CLzmaEncProps *p)
-+{
-+ int level = p->level;
-+ if (level < 0) level = 5;
-+ p->level = level;
-+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
-+ if (p->lc < 0) p->lc = 3;
-+ if (p->lp < 0) p->lp = 0;
-+ if (p->pb < 0) p->pb = 2;
-+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
-+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
-+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
-+ if (p->numHashBytes < 0) p->numHashBytes = 4;
-+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
-+ if (p->numThreads < 0)
-+ p->numThreads =
-+ #ifndef _7ZIP_ST
-+ ((p->btMode && p->algo) ? 2 : 1);
-+ #else
-+ 1;
-+ #endif
-+}
-+
-+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
-+{
-+ CLzmaEncProps props = *props2;
-+ LzmaEncProps_Normalize(&props);
-+ return props.dictSize;
-+}
-+
-+/* #define LZMA_LOG_BSR */
-+/* Define it for Intel's CPU */
-+
-+
-+#ifdef LZMA_LOG_BSR
-+
-+#define kDicLogSizeMaxCompress 30
-+
-+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
-+
-+UInt32 GetPosSlot1(UInt32 pos)
-+{
-+ UInt32 res;
-+ BSR2_RET(pos, res);
-+ return res;
-+}
-+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
-+
-+#else
-+
-+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
-+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-+
-+void LzmaEnc_FastPosInit(Byte *g_FastPos)
-+{
-+ int c = 2, slotFast;
-+ g_FastPos[0] = 0;
-+ g_FastPos[1] = 1;
-+
-+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
-+ {
-+ UInt32 k = (1 << ((slotFast >> 1) - 1));
-+ UInt32 j;
-+ for (j = 0; j < k; j++, c++)
-+ g_FastPos[c] = (Byte)slotFast;
-+ }
-+}
-+
-+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
-+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
-+ res = p->g_FastPos[pos >> i] + (i * 2); }
-+/*
-+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
-+ p->g_FastPos[pos >> 6] + 12 : \
-+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
-+*/
-+
-+#define GetPosSlot1(pos) p->g_FastPos[pos]
-+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
-+
-+#endif
-+
-+
-+#define LZMA_NUM_REPS 4
-+
-+typedef unsigned CState;
-+
-+typedef struct
-+{
-+ UInt32 price;
-+
-+ CState state;
-+ int prev1IsChar;
-+ int prev2;
-+
-+ UInt32 posPrev2;
-+ UInt32 backPrev2;
-+
-+ UInt32 posPrev;
-+ UInt32 backPrev;
-+ UInt32 backs[LZMA_NUM_REPS];
-+} COptimal;
-+
-+#define kNumOpts (1 << 12)
-+
-+#define kNumLenToPosStates 4
-+#define kNumPosSlotBits 6
-+#define kDicLogSizeMin 0
-+#define kDicLogSizeMax 32
-+#define kDistTableSizeMax (kDicLogSizeMax * 2)
-+
-+
-+#define kNumAlignBits 4
-+#define kAlignTableSize (1 << kNumAlignBits)
-+#define kAlignMask (kAlignTableSize - 1)
-+
-+#define kStartPosModelIndex 4
-+#define kEndPosModelIndex 14
-+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
-+
-+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-+
-+#ifdef _LZMA_PROB32
-+#define CLzmaProb UInt32
-+#else
-+#define CLzmaProb UInt16
-+#endif
-+
-+#define LZMA_PB_MAX 4
-+#define LZMA_LC_MAX 8
-+#define LZMA_LP_MAX 4
-+
-+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
-+
-+
-+#define kLenNumLowBits 3
-+#define kLenNumLowSymbols (1 << kLenNumLowBits)
-+#define kLenNumMidBits 3
-+#define kLenNumMidSymbols (1 << kLenNumMidBits)
-+#define kLenNumHighBits 8
-+#define kLenNumHighSymbols (1 << kLenNumHighBits)
-+
-+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-+
-+#define LZMA_MATCH_LEN_MIN 2
-+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
-+
-+#define kNumStates 12
-+
-+typedef struct
-+{
-+ CLzmaProb choice;
-+ CLzmaProb choice2;
-+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
-+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
-+ CLzmaProb high[kLenNumHighSymbols];
-+} CLenEnc;
-+
-+typedef struct
-+{
-+ CLenEnc p;
-+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
-+ UInt32 tableSize;
-+ UInt32 counters[LZMA_NUM_PB_STATES_MAX];
-+} CLenPriceEnc;
-+
-+typedef struct
-+{
-+ UInt32 range;
-+ Byte cache;
-+ UInt64 low;
-+ UInt64 cacheSize;
-+ Byte *buf;
-+ Byte *bufLim;
-+ Byte *bufBase;
-+ ISeqOutStream *outStream;
-+ UInt64 processed;
-+ SRes res;
-+} CRangeEnc;
-+
-+typedef struct
-+{
-+ CLzmaProb *litProbs;
-+
-+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+ CLzmaProb isRep[kNumStates];
-+ CLzmaProb isRepG0[kNumStates];
-+ CLzmaProb isRepG1[kNumStates];
-+ CLzmaProb isRepG2[kNumStates];
-+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+
-+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-+
-+ CLenPriceEnc lenEnc;
-+ CLenPriceEnc repLenEnc;
-+
-+ UInt32 reps[LZMA_NUM_REPS];
-+ UInt32 state;
-+} CSaveState;
-+
-+typedef struct
-+{
-+ IMatchFinder matchFinder;
-+ void *matchFinderObj;
-+
-+ #ifndef _7ZIP_ST
-+ Bool mtMode;
-+ CMatchFinderMt matchFinderMt;
-+ #endif
-+
-+ CMatchFinder matchFinderBase;
-+
-+ #ifndef _7ZIP_ST
-+ Byte pad[128];
-+ #endif
-+
-+ UInt32 optimumEndIndex;
-+ UInt32 optimumCurrentIndex;
-+
-+ UInt32 longestMatchLength;
-+ UInt32 numPairs;
-+ UInt32 numAvail;
-+ COptimal opt[kNumOpts];
-+
-+ #ifndef LZMA_LOG_BSR
-+ Byte g_FastPos[1 << kNumLogBits];
-+ #endif
-+
-+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
-+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
-+ UInt32 numFastBytes;
-+ UInt32 additionalOffset;
-+ UInt32 reps[LZMA_NUM_REPS];
-+ UInt32 state;
-+
-+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
-+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
-+ UInt32 alignPrices[kAlignTableSize];
-+ UInt32 alignPriceCount;
-+
-+ UInt32 distTableSize;
-+
-+ unsigned lc, lp, pb;
-+ unsigned lpMask, pbMask;
-+
-+ CLzmaProb *litProbs;
-+
-+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+ CLzmaProb isRep[kNumStates];
-+ CLzmaProb isRepG0[kNumStates];
-+ CLzmaProb isRepG1[kNumStates];
-+ CLzmaProb isRepG2[kNumStates];
-+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+
-+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-+
-+ CLenPriceEnc lenEnc;
-+ CLenPriceEnc repLenEnc;
-+
-+ unsigned lclp;
-+
-+ Bool fastMode;
-+
-+ CRangeEnc rc;
-+
-+ Bool writeEndMark;
-+ UInt64 nowPos64;
-+ UInt32 matchPriceCount;
-+ Bool finished;
-+ Bool multiThread;
-+
-+ SRes result;
-+ UInt32 dictSize;
-+ UInt32 matchFinderCycles;
-+
-+ int needInit;
-+
-+ CSaveState saveState;
-+} CLzmaEnc;
-+
-+void LzmaEnc_SaveState(CLzmaEncHandle pp)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ CSaveState *dest = &p->saveState;
-+ int i;
-+ dest->lenEnc = p->lenEnc;
-+ dest->repLenEnc = p->repLenEnc;
-+ dest->state = p->state;
-+
-+ for (i = 0; i < kNumStates; i++)
-+ {
-+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
-+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
-+ }
-+ for (i = 0; i < kNumLenToPosStates; i++)
-+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
-+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
-+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
-+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
-+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
-+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
-+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
-+ memcpy(dest->reps, p->reps, sizeof(p->reps));
-+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
-+}
-+
-+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
-+{
-+ CLzmaEnc *dest = (CLzmaEnc *)pp;
-+ const CSaveState *p = &dest->saveState;
-+ int i;
-+ dest->lenEnc = p->lenEnc;
-+ dest->repLenEnc = p->repLenEnc;
-+ dest->state = p->state;
-+
-+ for (i = 0; i < kNumStates; i++)
-+ {
-+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
-+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
-+ }
-+ for (i = 0; i < kNumLenToPosStates; i++)
-+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
-+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
-+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
-+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
-+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
-+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
-+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
-+ memcpy(dest->reps, p->reps, sizeof(p->reps));
-+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
-+}
-+
-+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ CLzmaEncProps props = *props2;
-+ LzmaEncProps_Normalize(&props);
-+
-+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
-+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
-+ return SZ_ERROR_PARAM;
-+ p->dictSize = props.dictSize;
-+ p->matchFinderCycles = props.mc;
-+ {
-+ unsigned fb = props.fb;
-+ if (fb < 5)
-+ fb = 5;
-+ if (fb > LZMA_MATCH_LEN_MAX)
-+ fb = LZMA_MATCH_LEN_MAX;
-+ p->numFastBytes = fb;
-+ }
-+ p->lc = props.lc;
-+ p->lp = props.lp;
-+ p->pb = props.pb;
-+ p->fastMode = (props.algo == 0);
-+ p->matchFinderBase.btMode = props.btMode;
-+ {
-+ UInt32 numHashBytes = 4;
-+ if (props.btMode)
-+ {
-+ if (props.numHashBytes < 2)
-+ numHashBytes = 2;
-+ else if (props.numHashBytes < 4)
-+ numHashBytes = props.numHashBytes;
-+ }
-+ p->matchFinderBase.numHashBytes = numHashBytes;
-+ }
-+
-+ p->matchFinderBase.cutValue = props.mc;
-+
-+ p->writeEndMark = props.writeEndMark;
-+
-+ #ifndef _7ZIP_ST
-+ /*
-+ if (newMultiThread != _multiThread)
-+ {
-+ ReleaseMatchFinder();
-+ _multiThread = newMultiThread;
-+ }
-+ */
-+ p->multiThread = (props.numThreads > 1);
-+ #endif
-+
-+ return SZ_OK;
-+}
-+
-+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
-+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
-+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
-+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
-+
-+#define IsCharState(s) ((s) < 7)
-+
-+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
-+
-+#define kInfinityPrice (1 << 30)
-+
-+static void RangeEnc_Construct(CRangeEnc *p)
-+{
-+ p->outStream = 0;
-+ p->bufBase = 0;
-+}
-+
-+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
-+
-+#define RC_BUF_SIZE (1 << 16)
-+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
-+{
-+ if (p->bufBase == 0)
-+ {
-+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
-+ if (p->bufBase == 0)
-+ return 0;
-+ p->bufLim = p->bufBase + RC_BUF_SIZE;
-+ }
-+ return 1;
-+}
-+
-+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->bufBase);
-+ p->bufBase = 0;
-+}
-+
-+static void RangeEnc_Init(CRangeEnc *p)
-+{
-+ /* Stream.Init(); */
-+ p->low = 0;
-+ p->range = 0xFFFFFFFF;
-+ p->cacheSize = 1;
-+ p->cache = 0;
-+
-+ p->buf = p->bufBase;
-+
-+ p->processed = 0;
-+ p->res = SZ_OK;
-+}
-+
-+static void RangeEnc_FlushStream(CRangeEnc *p)
-+{
-+ size_t num;
-+ if (p->res != SZ_OK)
-+ return;
-+ num = p->buf - p->bufBase;
-+ if (num != p->outStream->Write(p->outStream, p->bufBase, num))
-+ p->res = SZ_ERROR_WRITE;
-+ p->processed += num;
-+ p->buf = p->bufBase;
-+}
-+
-+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
-+{
-+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
-+ {
-+ Byte temp = p->cache;
-+ do
-+ {
-+ Byte *buf = p->buf;
-+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
-+ p->buf = buf;
-+ if (buf == p->bufLim)
-+ RangeEnc_FlushStream(p);
-+ temp = 0xFF;
-+ }
-+ while (--p->cacheSize != 0);
-+ p->cache = (Byte)((UInt32)p->low >> 24);
-+ }
-+ p->cacheSize++;
-+ p->low = (UInt32)p->low << 8;
-+}
-+
-+static void RangeEnc_FlushData(CRangeEnc *p)
-+{
-+ int i;
-+ for (i = 0; i < 5; i++)
-+ RangeEnc_ShiftLow(p);
-+}
-+
-+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
-+{
-+ do
-+ {
-+ p->range >>= 1;
-+ p->low += p->range & (0 - ((value >> --numBits) & 1));
-+ if (p->range < kTopValue)
-+ {
-+ p->range <<= 8;
-+ RangeEnc_ShiftLow(p);
-+ }
-+ }
-+ while (numBits != 0);
-+}
-+
-+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
-+{
-+ UInt32 ttt = *prob;
-+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
-+ if (symbol == 0)
-+ {
-+ p->range = newBound;
-+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
-+ }
-+ else
-+ {
-+ p->low += newBound;
-+ p->range -= newBound;
-+ ttt -= ttt >> kNumMoveBits;
-+ }
-+ *prob = (CLzmaProb)ttt;
-+ if (p->range < kTopValue)
-+ {
-+ p->range <<= 8;
-+ RangeEnc_ShiftLow(p);
-+ }
-+}
-+
-+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
-+{
-+ symbol |= 0x100;
-+ do
-+ {
-+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ }
-+ while (symbol < 0x10000);
-+}
-+
-+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
-+{
-+ UInt32 offs = 0x100;
-+ symbol |= 0x100;
-+ do
-+ {
-+ matchByte <<= 1;
-+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ offs &= ~(matchByte ^ symbol);
-+ }
-+ while (symbol < 0x10000);
-+}
-+
-+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
-+{
-+ UInt32 i;
-+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
-+ {
-+ const int kCyclesBits = kNumBitPriceShiftBits;
-+ UInt32 w = i;
-+ UInt32 bitCount = 0;
-+ int j;
-+ for (j = 0; j < kCyclesBits; j++)
-+ {
-+ w = w * w;
-+ bitCount <<= 1;
-+ while (w >= ((UInt32)1 << 16))
-+ {
-+ w >>= 1;
-+ bitCount++;
-+ }
-+ }
-+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
-+ }
-+}
-+
-+
-+#define GET_PRICE(prob, symbol) \
-+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-+
-+#define GET_PRICEa(prob, symbol) \
-+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-+
-+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
-+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-+
-+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
-+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-+
-+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ symbol |= 0x100;
-+ do
-+ {
-+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ }
-+ while (symbol < 0x10000);
-+ return price;
-+}
-+
-+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ UInt32 offs = 0x100;
-+ symbol |= 0x100;
-+ do
-+ {
-+ matchByte <<= 1;
-+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
-+ symbol <<= 1;
-+ offs &= ~(matchByte ^ symbol);
-+ }
-+ while (symbol < 0x10000);
-+ return price;
-+}
-+
-+
-+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-+{
-+ UInt32 m = 1;
-+ int i;
-+ for (i = numBitLevels; i != 0;)
-+ {
-+ UInt32 bit;
-+ i--;
-+ bit = (symbol >> i) & 1;
-+ RangeEnc_EncodeBit(rc, probs + m, bit);
-+ m = (m << 1) | bit;
-+ }
-+}
-+
-+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-+{
-+ UInt32 m = 1;
-+ int i;
-+ for (i = 0; i < numBitLevels; i++)
-+ {
-+ UInt32 bit = symbol & 1;
-+ RangeEnc_EncodeBit(rc, probs + m, bit);
-+ m = (m << 1) | bit;
-+ symbol >>= 1;
-+ }
-+}
-+
-+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ symbol |= (1 << numBitLevels);
-+ while (symbol != 1)
-+ {
-+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
-+ symbol >>= 1;
-+ }
-+ return price;
-+}
-+
-+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+ UInt32 price = 0;
-+ UInt32 m = 1;
-+ int i;
-+ for (i = numBitLevels; i != 0; i--)
-+ {
-+ UInt32 bit = symbol & 1;
-+ symbol >>= 1;
-+ price += GET_PRICEa(probs[m], bit);
-+ m = (m << 1) | bit;
-+ }
-+ return price;
-+}
-+
-+
-+static void LenEnc_Init(CLenEnc *p)
-+{
-+ unsigned i;
-+ p->choice = p->choice2 = kProbInitValue;
-+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
-+ p->low[i] = kProbInitValue;
-+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
-+ p->mid[i] = kProbInitValue;
-+ for (i = 0; i < kLenNumHighSymbols; i++)
-+ p->high[i] = kProbInitValue;
-+}
-+
-+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
-+{
-+ if (symbol < kLenNumLowSymbols)
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice, 0);
-+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
-+ }
-+ else
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice, 1);
-+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice2, 0);
-+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
-+ }
-+ else
-+ {
-+ RangeEnc_EncodeBit(rc, &p->choice2, 1);
-+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
-+ }
-+ }
-+}
-+
-+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
-+{
-+ UInt32 a0 = GET_PRICE_0a(p->choice);
-+ UInt32 a1 = GET_PRICE_1a(p->choice);
-+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
-+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
-+ UInt32 i = 0;
-+ for (i = 0; i < kLenNumLowSymbols; i++)
-+ {
-+ if (i >= numSymbols)
-+ return;
-+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
-+ }
-+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
-+ {
-+ if (i >= numSymbols)
-+ return;
-+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
-+ }
-+ for (; i < numSymbols; i++)
-+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
-+}
-+
-+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
-+{
-+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
-+ p->counters[posState] = p->tableSize;
-+}
-+
-+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
-+{
-+ UInt32 posState;
-+ for (posState = 0; posState < numPosStates; posState++)
-+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-+}
-+
-+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
-+{
-+ LenEnc_Encode(&p->p, rc, symbol, posState);
-+ if (updatePrice)
-+ if (--p->counters[posState] == 0)
-+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-+}
-+
-+
-+
-+
-+static void MovePos(CLzmaEnc *p, UInt32 num)
-+{
-+ #ifdef SHOW_STAT
-+ ttt += num;
-+ printf("\n MovePos %d", num);
-+ #endif
-+ if (num != 0)
-+ {
-+ p->additionalOffset += num;
-+ p->matchFinder.Skip(p->matchFinderObj, num);
-+ }
-+}
-+
-+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
-+{
-+ UInt32 lenRes = 0, numPairs;
-+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
-+ #ifdef SHOW_STAT
-+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
-+ ttt++;
-+ {
-+ UInt32 i;
-+ for (i = 0; i < numPairs; i += 2)
-+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
-+ }
-+ #endif
-+ if (numPairs > 0)
-+ {
-+ lenRes = p->matches[numPairs - 2];
-+ if (lenRes == p->numFastBytes)
-+ {
-+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ UInt32 distance = p->matches[numPairs - 1] + 1;
-+ UInt32 numAvail = p->numAvail;
-+ if (numAvail > LZMA_MATCH_LEN_MAX)
-+ numAvail = LZMA_MATCH_LEN_MAX;
-+ {
-+ const Byte *pby2 = pby - distance;
-+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
-+ }
-+ }
-+ }
-+ p->additionalOffset++;
-+ *numDistancePairsRes = numPairs;
-+ return lenRes;
-+}
-+
-+
-+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
-+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
-+#define IsShortRep(p) ((p)->backPrev == 0)
-+
-+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
-+{
-+ return
-+ GET_PRICE_0(p->isRepG0[state]) +
-+ GET_PRICE_0(p->isRep0Long[state][posState]);
-+}
-+
-+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
-+{
-+ UInt32 price;
-+ if (repIndex == 0)
-+ {
-+ price = GET_PRICE_0(p->isRepG0[state]);
-+ price += GET_PRICE_1(p->isRep0Long[state][posState]);
-+ }
-+ else
-+ {
-+ price = GET_PRICE_1(p->isRepG0[state]);
-+ if (repIndex == 1)
-+ price += GET_PRICE_0(p->isRepG1[state]);
-+ else
-+ {
-+ price += GET_PRICE_1(p->isRepG1[state]);
-+ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
-+ }
-+ }
-+ return price;
-+}
-+
-+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
-+{
-+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
-+ GetPureRepPrice(p, repIndex, state, posState);
-+}
-+
-+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
-+{
-+ UInt32 posMem = p->opt[cur].posPrev;
-+ UInt32 backMem = p->opt[cur].backPrev;
-+ p->optimumEndIndex = cur;
-+ do
-+ {
-+ if (p->opt[cur].prev1IsChar)
-+ {
-+ MakeAsChar(&p->opt[posMem])
-+ p->opt[posMem].posPrev = posMem - 1;
-+ if (p->opt[cur].prev2)
-+ {
-+ p->opt[posMem - 1].prev1IsChar = False;
-+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
-+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
-+ }
-+ }
-+ {
-+ UInt32 posPrev = posMem;
-+ UInt32 backCur = backMem;
-+
-+ backMem = p->opt[posPrev].backPrev;
-+ posMem = p->opt[posPrev].posPrev;
-+
-+ p->opt[posPrev].backPrev = backCur;
-+ p->opt[posPrev].posPrev = cur;
-+ cur = posPrev;
-+ }
-+ }
-+ while (cur != 0);
-+ *backRes = p->opt[0].backPrev;
-+ p->optimumCurrentIndex = p->opt[0].posPrev;
-+ return p->optimumCurrentIndex;
-+}
-+
-+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
-+
-+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-+{
-+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
-+ UInt32 matchPrice, repMatchPrice, normalMatchPrice;
-+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
-+ UInt32 *matches;
-+ const Byte *data;
-+ Byte curByte, matchByte;
-+ if (p->optimumEndIndex != p->optimumCurrentIndex)
-+ {
-+ const COptimal *opt = &p->opt[p->optimumCurrentIndex];
-+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
-+ *backRes = opt->backPrev;
-+ p->optimumCurrentIndex = opt->posPrev;
-+ return lenRes;
-+ }
-+ p->optimumCurrentIndex = p->optimumEndIndex = 0;
-+
-+ if (p->additionalOffset == 0)
-+ mainLen = ReadMatchDistances(p, &numPairs);
-+ else
-+ {
-+ mainLen = p->longestMatchLength;
-+ numPairs = p->numPairs;
-+ }
-+
-+ numAvail = p->numAvail;
-+ if (numAvail < 2)
-+ {
-+ *backRes = (UInt32)(-1);
-+ return 1;
-+ }
-+ if (numAvail > LZMA_MATCH_LEN_MAX)
-+ numAvail = LZMA_MATCH_LEN_MAX;
-+
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ repMaxIndex = 0;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 lenTest;
-+ const Byte *data2;
-+ reps[i] = p->reps[i];
-+ data2 = data - (reps[i] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ {
-+ repLens[i] = 0;
-+ continue;
-+ }
-+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
-+ repLens[i] = lenTest;
-+ if (lenTest > repLens[repMaxIndex])
-+ repMaxIndex = i;
-+ }
-+ if (repLens[repMaxIndex] >= p->numFastBytes)
-+ {
-+ UInt32 lenRes;
-+ *backRes = repMaxIndex;
-+ lenRes = repLens[repMaxIndex];
-+ MovePos(p, lenRes - 1);
-+ return lenRes;
-+ }
-+
-+ matches = p->matches;
-+ if (mainLen >= p->numFastBytes)
-+ {
-+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
-+ MovePos(p, mainLen - 1);
-+ return mainLen;
-+ }
-+ curByte = *data;
-+ matchByte = *(data - (reps[0] + 1));
-+
-+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
-+ {
-+ *backRes = (UInt32)-1;
-+ return 1;
-+ }
-+
-+ p->opt[0].state = (CState)p->state;
-+
-+ posState = (position & p->pbMask);
-+
-+ {
-+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
-+ (!IsCharState(p->state) ?
-+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
-+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
-+ }
-+
-+ MakeAsChar(&p->opt[1]);
-+
-+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
-+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
-+
-+ if (matchByte == curByte)
-+ {
-+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
-+ if (shortRepPrice < p->opt[1].price)
-+ {
-+ p->opt[1].price = shortRepPrice;
-+ MakeAsShortRep(&p->opt[1]);
-+ }
-+ }
-+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
-+
-+ if (lenEnd < 2)
-+ {
-+ *backRes = p->opt[1].backPrev;
-+ return 1;
-+ }
-+
-+ p->opt[1].posPrev = 0;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ p->opt[0].backs[i] = reps[i];
-+
-+ len = lenEnd;
-+ do
-+ p->opt[len--].price = kInfinityPrice;
-+ while (len >= 2);
-+
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 repLen = repLens[i];
-+ UInt32 price;
-+ if (repLen < 2)
-+ continue;
-+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
-+ do
-+ {
-+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
-+ COptimal *opt = &p->opt[repLen];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = 0;
-+ opt->backPrev = i;
-+ opt->prev1IsChar = False;
-+ }
-+ }
-+ while (--repLen >= 2);
-+ }
-+
-+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
-+
-+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
-+ if (len <= mainLen)
-+ {
-+ UInt32 offs = 0;
-+ while (len > matches[offs])
-+ offs += 2;
-+ for (; ; len++)
-+ {
-+ COptimal *opt;
-+ UInt32 distance = matches[offs + 1];
-+
-+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
-+ UInt32 lenToPosState = GetLenToPosState(len);
-+ if (distance < kNumFullDistances)
-+ curAndLenPrice += p->distancesPrices[lenToPosState][distance];
-+ else
-+ {
-+ UInt32 slot;
-+ GetPosSlot2(distance, slot);
-+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
-+ }
-+ opt = &p->opt[len];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = 0;
-+ opt->backPrev = distance + LZMA_NUM_REPS;
-+ opt->prev1IsChar = False;
-+ }
-+ if (len == matches[offs])
-+ {
-+ offs += 2;
-+ if (offs == numPairs)
-+ break;
-+ }
-+ }
-+ }
-+
-+ cur = 0;
-+
-+ #ifdef SHOW_STAT2
-+ if (position >= 0)
-+ {
-+ unsigned i;
-+ printf("\n pos = %4X", position);
-+ for (i = cur; i <= lenEnd; i++)
-+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
-+ }
-+ #endif
-+
-+ for (;;)
-+ {
-+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
-+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
-+ Bool nextIsChar;
-+ Byte curByte, matchByte;
-+ const Byte *data;
-+ COptimal *curOpt;
-+ COptimal *nextOpt;
-+
-+ cur++;
-+ if (cur == lenEnd)
-+ return Backward(p, backRes, cur);
-+
-+ newLen = ReadMatchDistances(p, &numPairs);
-+ if (newLen >= p->numFastBytes)
-+ {
-+ p->numPairs = numPairs;
-+ p->longestMatchLength = newLen;
-+ return Backward(p, backRes, cur);
-+ }
-+ position++;
-+ curOpt = &p->opt[cur];
-+ posPrev = curOpt->posPrev;
-+ if (curOpt->prev1IsChar)
-+ {
-+ posPrev--;
-+ if (curOpt->prev2)
-+ {
-+ state = p->opt[curOpt->posPrev2].state;
-+ if (curOpt->backPrev2 < LZMA_NUM_REPS)
-+ state = kRepNextStates[state];
-+ else
-+ state = kMatchNextStates[state];
-+ }
-+ else
-+ state = p->opt[posPrev].state;
-+ state = kLiteralNextStates[state];
-+ }
-+ else
-+ state = p->opt[posPrev].state;
-+ if (posPrev == cur - 1)
-+ {
-+ if (IsShortRep(curOpt))
-+ state = kShortRepNextStates[state];
-+ else
-+ state = kLiteralNextStates[state];
-+ }
-+ else
-+ {
-+ UInt32 pos;
-+ const COptimal *prevOpt;
-+ if (curOpt->prev1IsChar && curOpt->prev2)
-+ {
-+ posPrev = curOpt->posPrev2;
-+ pos = curOpt->backPrev2;
-+ state = kRepNextStates[state];
-+ }
-+ else
-+ {
-+ pos = curOpt->backPrev;
-+ if (pos < LZMA_NUM_REPS)
-+ state = kRepNextStates[state];
-+ else
-+ state = kMatchNextStates[state];
-+ }
-+ prevOpt = &p->opt[posPrev];
-+ if (pos < LZMA_NUM_REPS)
-+ {
-+ UInt32 i;
-+ reps[0] = prevOpt->backs[pos];
-+ for (i = 1; i <= pos; i++)
-+ reps[i] = prevOpt->backs[i - 1];
-+ for (; i < LZMA_NUM_REPS; i++)
-+ reps[i] = prevOpt->backs[i];
-+ }
-+ else
-+ {
-+ UInt32 i;
-+ reps[0] = (pos - LZMA_NUM_REPS);
-+ for (i = 1; i < LZMA_NUM_REPS; i++)
-+ reps[i] = prevOpt->backs[i - 1];
-+ }
-+ }
-+ curOpt->state = (CState)state;
-+
-+ curOpt->backs[0] = reps[0];
-+ curOpt->backs[1] = reps[1];
-+ curOpt->backs[2] = reps[2];
-+ curOpt->backs[3] = reps[3];
-+
-+ curPrice = curOpt->price;
-+ nextIsChar = False;
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ curByte = *data;
-+ matchByte = *(data - (reps[0] + 1));
-+
-+ posState = (position & p->pbMask);
-+
-+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
-+ {
-+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-+ curAnd1Price +=
-+ (!IsCharState(state) ?
-+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
-+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
-+ }
-+
-+ nextOpt = &p->opt[cur + 1];
-+
-+ if (curAnd1Price < nextOpt->price)
-+ {
-+ nextOpt->price = curAnd1Price;
-+ nextOpt->posPrev = cur;
-+ MakeAsChar(nextOpt);
-+ nextIsChar = True;
-+ }
-+
-+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
-+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
-+
-+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
-+ {
-+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
-+ if (shortRepPrice <= nextOpt->price)
-+ {
-+ nextOpt->price = shortRepPrice;
-+ nextOpt->posPrev = cur;
-+ MakeAsShortRep(nextOpt);
-+ nextIsChar = True;
-+ }
-+ }
-+ numAvailFull = p->numAvail;
-+ {
-+ UInt32 temp = kNumOpts - 1 - cur;
-+ if (temp < numAvailFull)
-+ numAvailFull = temp;
-+ }
-+
-+ if (numAvailFull < 2)
-+ continue;
-+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
-+
-+ if (!nextIsChar && matchByte != curByte) /* speed optimization */
-+ {
-+ /* try Literal + rep0 */
-+ UInt32 temp;
-+ UInt32 lenTest2;
-+ const Byte *data2 = data - (reps[0] + 1);
-+ UInt32 limit = p->numFastBytes + 1;
-+ if (limit > numAvailFull)
-+ limit = numAvailFull;
-+
-+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
-+ lenTest2 = temp - 1;
-+ if (lenTest2 >= 2)
-+ {
-+ UInt32 state2 = kLiteralNextStates[state];
-+ UInt32 posStateNext = (position + 1) & p->pbMask;
-+ UInt32 nextRepMatchPrice = curAnd1Price +
-+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+ GET_PRICE_1(p->isRep[state2]);
-+ /* for (; lenTest2 >= 2; lenTest2--) */
-+ {
-+ UInt32 curAndLenPrice;
-+ COptimal *opt;
-+ UInt32 offset = cur + 1 + lenTest2;
-+ while (lenEnd < offset)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+ opt = &p->opt[offset];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur + 1;
-+ opt->backPrev = 0;
-+ opt->prev1IsChar = True;
-+ opt->prev2 = False;
-+ }
-+ }
-+ }
-+ }
-+
-+ startLen = 2; /* speed optimization */
-+ {
-+ UInt32 repIndex;
-+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
-+ {
-+ UInt32 lenTest;
-+ UInt32 lenTestTemp;
-+ UInt32 price;
-+ const Byte *data2 = data - (reps[repIndex] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ continue;
-+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
-+ while (lenEnd < cur + lenTest)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ lenTestTemp = lenTest;
-+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
-+ do
-+ {
-+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
-+ COptimal *opt = &p->opt[cur + lenTest];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur;
-+ opt->backPrev = repIndex;
-+ opt->prev1IsChar = False;
-+ }
-+ }
-+ while (--lenTest >= 2);
-+ lenTest = lenTestTemp;
-+
-+ if (repIndex == 0)
-+ startLen = lenTest + 1;
-+
-+ /* if (_maxMode) */
-+ {
-+ UInt32 lenTest2 = lenTest + 1;
-+ UInt32 limit = lenTest2 + p->numFastBytes;
-+ UInt32 nextRepMatchPrice;
-+ if (limit > numAvailFull)
-+ limit = numAvailFull;
-+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-+ lenTest2 -= lenTest + 1;
-+ if (lenTest2 >= 2)
-+ {
-+ UInt32 state2 = kRepNextStates[state];
-+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
-+ UInt32 curAndLenCharPrice =
-+ price + p->repLenEnc.prices[posState][lenTest - 2] +
-+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-+ data[lenTest], data2[lenTest], p->ProbPrices);
-+ state2 = kLiteralNextStates[state2];
-+ posStateNext = (position + lenTest + 1) & p->pbMask;
-+ nextRepMatchPrice = curAndLenCharPrice +
-+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+ GET_PRICE_1(p->isRep[state2]);
-+
-+ /* for (; lenTest2 >= 2; lenTest2--) */
-+ {
-+ UInt32 curAndLenPrice;
-+ COptimal *opt;
-+ UInt32 offset = cur + lenTest + 1 + lenTest2;
-+ while (lenEnd < offset)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+ opt = &p->opt[offset];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur + lenTest + 1;
-+ opt->backPrev = 0;
-+ opt->prev1IsChar = True;
-+ opt->prev2 = True;
-+ opt->posPrev2 = cur;
-+ opt->backPrev2 = repIndex;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
-+ if (newLen > numAvail)
-+ {
-+ newLen = numAvail;
-+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
-+ matches[numPairs] = newLen;
-+ numPairs += 2;
-+ }
-+ if (newLen >= startLen)
-+ {
-+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
-+ UInt32 offs, curBack, posSlot;
-+ UInt32 lenTest;
-+ while (lenEnd < cur + newLen)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+
-+ offs = 0;
-+ while (startLen > matches[offs])
-+ offs += 2;
-+ curBack = matches[offs + 1];
-+ GetPosSlot2(curBack, posSlot);
-+ for (lenTest = /*2*/ startLen; ; lenTest++)
-+ {
-+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
-+ UInt32 lenToPosState = GetLenToPosState(lenTest);
-+ COptimal *opt;
-+ if (curBack < kNumFullDistances)
-+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
-+ else
-+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
-+
-+ opt = &p->opt[cur + lenTest];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur;
-+ opt->backPrev = curBack + LZMA_NUM_REPS;
-+ opt->prev1IsChar = False;
-+ }
-+
-+ if (/*_maxMode && */lenTest == matches[offs])
-+ {
-+ /* Try Match + Literal + Rep0 */
-+ const Byte *data2 = data - (curBack + 1);
-+ UInt32 lenTest2 = lenTest + 1;
-+ UInt32 limit = lenTest2 + p->numFastBytes;
-+ UInt32 nextRepMatchPrice;
-+ if (limit > numAvailFull)
-+ limit = numAvailFull;
-+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-+ lenTest2 -= lenTest + 1;
-+ if (lenTest2 >= 2)
-+ {
-+ UInt32 state2 = kMatchNextStates[state];
-+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
-+ UInt32 curAndLenCharPrice = curAndLenPrice +
-+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-+ data[lenTest], data2[lenTest], p->ProbPrices);
-+ state2 = kLiteralNextStates[state2];
-+ posStateNext = (posStateNext + 1) & p->pbMask;
-+ nextRepMatchPrice = curAndLenCharPrice +
-+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+ GET_PRICE_1(p->isRep[state2]);
-+
-+ /* for (; lenTest2 >= 2; lenTest2--) */
-+ {
-+ UInt32 offset = cur + lenTest + 1 + lenTest2;
-+ UInt32 curAndLenPrice;
-+ COptimal *opt;
-+ while (lenEnd < offset)
-+ p->opt[++lenEnd].price = kInfinityPrice;
-+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+ opt = &p->opt[offset];
-+ if (curAndLenPrice < opt->price)
-+ {
-+ opt->price = curAndLenPrice;
-+ opt->posPrev = cur + lenTest + 1;
-+ opt->backPrev = 0;
-+ opt->prev1IsChar = True;
-+ opt->prev2 = True;
-+ opt->posPrev2 = cur;
-+ opt->backPrev2 = curBack + LZMA_NUM_REPS;
-+ }
-+ }
-+ }
-+ offs += 2;
-+ if (offs == numPairs)
-+ break;
-+ curBack = matches[offs + 1];
-+ if (curBack >= kNumFullDistances)
-+ GetPosSlot2(curBack, posSlot);
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
-+
-+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
-+{
-+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
-+ const Byte *data;
-+ const UInt32 *matches;
-+
-+ if (p->additionalOffset == 0)
-+ mainLen = ReadMatchDistances(p, &numPairs);
-+ else
-+ {
-+ mainLen = p->longestMatchLength;
-+ numPairs = p->numPairs;
-+ }
-+
-+ numAvail = p->numAvail;
-+ *backRes = (UInt32)-1;
-+ if (numAvail < 2)
-+ return 1;
-+ if (numAvail > LZMA_MATCH_LEN_MAX)
-+ numAvail = LZMA_MATCH_LEN_MAX;
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+
-+ repLen = repIndex = 0;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 len;
-+ const Byte *data2 = data - (p->reps[i] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ continue;
-+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
-+ if (len >= p->numFastBytes)
-+ {
-+ *backRes = i;
-+ MovePos(p, len - 1);
-+ return len;
-+ }
-+ if (len > repLen)
-+ {
-+ repIndex = i;
-+ repLen = len;
-+ }
-+ }
-+
-+ matches = p->matches;
-+ if (mainLen >= p->numFastBytes)
-+ {
-+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
-+ MovePos(p, mainLen - 1);
-+ return mainLen;
-+ }
-+
-+ mainDist = 0; /* for GCC */
-+ if (mainLen >= 2)
-+ {
-+ mainDist = matches[numPairs - 1];
-+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
-+ {
-+ if (!ChangePair(matches[numPairs - 3], mainDist))
-+ break;
-+ numPairs -= 2;
-+ mainLen = matches[numPairs - 2];
-+ mainDist = matches[numPairs - 1];
-+ }
-+ if (mainLen == 2 && mainDist >= 0x80)
-+ mainLen = 1;
-+ }
-+
-+ if (repLen >= 2 && (
-+ (repLen + 1 >= mainLen) ||
-+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
-+ (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
-+ {
-+ *backRes = repIndex;
-+ MovePos(p, repLen - 1);
-+ return repLen;
-+ }
-+
-+ if (mainLen < 2 || numAvail <= 2)
-+ return 1;
-+
-+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
-+ if (p->longestMatchLength >= 2)
-+ {
-+ UInt32 newDistance = matches[p->numPairs - 1];
-+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
-+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
-+ (p->longestMatchLength > mainLen + 1) ||
-+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
-+ return 1;
-+ }
-+
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+ for (i = 0; i < LZMA_NUM_REPS; i++)
-+ {
-+ UInt32 len, limit;
-+ const Byte *data2 = data - (p->reps[i] + 1);
-+ if (data[0] != data2[0] || data[1] != data2[1])
-+ continue;
-+ limit = mainLen - 1;
-+ for (len = 2; len < limit && data[len] == data2[len]; len++);
-+ if (len >= limit)
-+ return 1;
-+ }
-+ *backRes = mainDist + LZMA_NUM_REPS;
-+ MovePos(p, mainLen - 2);
-+ return mainLen;
-+}
-+
-+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
-+{
-+ UInt32 len;
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-+ p->state = kMatchNextStates[p->state];
-+ len = LZMA_MATCH_LEN_MIN;
-+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
-+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
-+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
-+}
-+
-+static SRes CheckErrors(CLzmaEnc *p)
-+{
-+ if (p->result != SZ_OK)
-+ return p->result;
-+ if (p->rc.res != SZ_OK)
-+ p->result = SZ_ERROR_WRITE;
-+ if (p->matchFinderBase.result != SZ_OK)
-+ p->result = SZ_ERROR_READ;
-+ if (p->result != SZ_OK)
-+ p->finished = True;
-+ return p->result;
-+}
-+
-+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
-+{
-+ /* ReleaseMFStream(); */
-+ p->finished = True;
-+ if (p->writeEndMark)
-+ WriteEndMarker(p, nowPos & p->pbMask);
-+ RangeEnc_FlushData(&p->rc);
-+ RangeEnc_FlushStream(&p->rc);
-+ return CheckErrors(p);
-+}
-+
-+static void FillAlignPrices(CLzmaEnc *p)
-+{
-+ UInt32 i;
-+ for (i = 0; i < kAlignTableSize; i++)
-+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
-+ p->alignPriceCount = 0;
-+}
-+
-+static void FillDistancesPrices(CLzmaEnc *p)
-+{
-+ UInt32 tempPrices[kNumFullDistances];
-+ UInt32 i, lenToPosState;
-+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
-+ {
-+ UInt32 posSlot = GetPosSlot1(i);
-+ UInt32 footerBits = ((posSlot >> 1) - 1);
-+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
-+ }
-+
-+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
-+ {
-+ UInt32 posSlot;
-+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
-+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
-+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
-+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
-+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
-+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
-+
-+ {
-+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
-+ UInt32 i;
-+ for (i = 0; i < kStartPosModelIndex; i++)
-+ distancesPrices[i] = posSlotPrices[i];
-+ for (; i < kNumFullDistances; i++)
-+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
-+ }
-+ }
-+ p->matchPriceCount = 0;
-+}
-+
-+void LzmaEnc_Construct(CLzmaEnc *p)
-+{
-+ RangeEnc_Construct(&p->rc);
-+ MatchFinder_Construct(&p->matchFinderBase);
-+ #ifndef _7ZIP_ST
-+ MatchFinderMt_Construct(&p->matchFinderMt);
-+ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
-+ #endif
-+
-+ {
-+ CLzmaEncProps props;
-+ LzmaEncProps_Init(&props);
-+ LzmaEnc_SetProps(p, &props);
-+ }
-+
-+ #ifndef LZMA_LOG_BSR
-+ LzmaEnc_FastPosInit(p->g_FastPos);
-+ #endif
-+
-+ LzmaEnc_InitPriceTables(p->ProbPrices);
-+ p->litProbs = 0;
-+ p->saveState.litProbs = 0;
-+}
-+
-+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
-+{
-+ void *p;
-+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
-+ if (p != 0)
-+ LzmaEnc_Construct((CLzmaEnc *)p);
-+ return p;
-+}
-+
-+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
-+{
-+ alloc->Free(alloc, p->litProbs);
-+ alloc->Free(alloc, p->saveState.litProbs);
-+ p->litProbs = 0;
-+ p->saveState.litProbs = 0;
-+}
-+
-+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ #ifndef _7ZIP_ST
-+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
-+ #endif
-+ MatchFinder_Free(&p->matchFinderBase, allocBig);
-+ LzmaEnc_FreeLits(p, alloc);
-+ RangeEnc_Free(&p->rc, alloc);
-+}
-+
-+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
-+ alloc->Free(alloc, p);
-+}
-+
-+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
-+{
-+ UInt32 nowPos32, startPos32;
-+ if (p->needInit)
-+ {
-+ p->matchFinder.Init(p->matchFinderObj);
-+ p->needInit = 0;
-+ }
-+
-+ if (p->finished)
-+ return p->result;
-+ RINOK(CheckErrors(p));
-+
-+ nowPos32 = (UInt32)p->nowPos64;
-+ startPos32 = nowPos32;
-+
-+ if (p->nowPos64 == 0)
-+ {
-+ UInt32 numPairs;
-+ Byte curByte;
-+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-+ return Flush(p, nowPos32);
-+ ReadMatchDistances(p, &numPairs);
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
-+ p->state = kLiteralNextStates[p->state];
-+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
-+ LitEnc_Encode(&p->rc, p->litProbs, curByte);
-+ p->additionalOffset--;
-+ nowPos32++;
-+ }
-+
-+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
-+ for (;;)
-+ {
-+ UInt32 pos, len, posState;
-+
-+ if (p->fastMode)
-+ len = GetOptimumFast(p, &pos);
-+ else
-+ len = GetOptimum(p, nowPos32, &pos);
-+
-+ #ifdef SHOW_STAT2
-+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
-+ #endif
-+
-+ posState = nowPos32 & p->pbMask;
-+ if (len == 1 && pos == (UInt32)-1)
-+ {
-+ Byte curByte;
-+ CLzmaProb *probs;
-+ const Byte *data;
-+
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
-+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-+ curByte = *data;
-+ probs = LIT_PROBS(nowPos32, *(data - 1));
-+ if (IsCharState(p->state))
-+ LitEnc_Encode(&p->rc, probs, curByte);
-+ else
-+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
-+ p->state = kLiteralNextStates[p->state];
-+ }
-+ else
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-+ if (pos < LZMA_NUM_REPS)
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
-+ if (pos == 0)
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
-+ }
-+ else
-+ {
-+ UInt32 distance = p->reps[pos];
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
-+ if (pos == 1)
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
-+ else
-+ {
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
-+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
-+ if (pos == 3)
-+ p->reps[3] = p->reps[2];
-+ p->reps[2] = p->reps[1];
-+ }
-+ p->reps[1] = p->reps[0];
-+ p->reps[0] = distance;
-+ }
-+ if (len == 1)
-+ p->state = kShortRepNextStates[p->state];
-+ else
-+ {
-+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+ p->state = kRepNextStates[p->state];
-+ }
-+ }
-+ else
-+ {
-+ UInt32 posSlot;
-+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-+ p->state = kMatchNextStates[p->state];
-+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+ pos -= LZMA_NUM_REPS;
-+ GetPosSlot(pos, posSlot);
-+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
-+
-+ if (posSlot >= kStartPosModelIndex)
-+ {
-+ UInt32 footerBits = ((posSlot >> 1) - 1);
-+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-+ UInt32 posReduced = pos - base;
-+
-+ if (posSlot < kEndPosModelIndex)
-+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
-+ else
-+ {
-+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
-+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
-+ p->alignPriceCount++;
-+ }
-+ }
-+ p->reps[3] = p->reps[2];
-+ p->reps[2] = p->reps[1];
-+ p->reps[1] = p->reps[0];
-+ p->reps[0] = pos;
-+ p->matchPriceCount++;
-+ }
-+ }
-+ p->additionalOffset -= len;
-+ nowPos32 += len;
-+ if (p->additionalOffset == 0)
-+ {
-+ UInt32 processed;
-+ if (!p->fastMode)
-+ {
-+ if (p->matchPriceCount >= (1 << 7))
-+ FillDistancesPrices(p);
-+ if (p->alignPriceCount >= kAlignTableSize)
-+ FillAlignPrices(p);
-+ }
-+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-+ break;
-+ processed = nowPos32 - startPos32;
-+ if (useLimits)
-+ {
-+ if (processed + kNumOpts + 300 >= maxUnpackSize ||
-+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
-+ break;
-+ }
-+ else if (processed >= (1 << 15))
-+ {
-+ p->nowPos64 += nowPos32 - startPos32;
-+ return CheckErrors(p);
-+ }
-+ }
-+ }
-+ p->nowPos64 += nowPos32 - startPos32;
-+ return Flush(p, nowPos32);
-+}
-+
-+#define kBigHashDicLimit ((UInt32)1 << 24)
-+
-+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ UInt32 beforeSize = kNumOpts;
-+ Bool btMode;
-+ if (!RangeEnc_Alloc(&p->rc, alloc))
-+ return SZ_ERROR_MEM;
-+ btMode = (p->matchFinderBase.btMode != 0);
-+ #ifndef _7ZIP_ST
-+ p->mtMode = (p->multiThread && !p->fastMode && btMode);
-+ #endif
-+
-+ {
-+ unsigned lclp = p->lc + p->lp;
-+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
-+ {
-+ LzmaEnc_FreeLits(p, alloc);
-+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-+ if (p->litProbs == 0 || p->saveState.litProbs == 0)
-+ {
-+ LzmaEnc_FreeLits(p, alloc);
-+ return SZ_ERROR_MEM;
-+ }
-+ p->lclp = lclp;
-+ }
-+ }
-+
-+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
-+
-+ if (beforeSize + p->dictSize < keepWindowSize)
-+ beforeSize = keepWindowSize - p->dictSize;
-+
-+ #ifndef _7ZIP_ST
-+ if (p->mtMode)
-+ {
-+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
-+ p->matchFinderObj = &p->matchFinderMt;
-+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
-+ }
-+ else
-+ #endif
-+ {
-+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
-+ return SZ_ERROR_MEM;
-+ p->matchFinderObj = &p->matchFinderBase;
-+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
-+ }
-+ return SZ_OK;
-+}
-+
-+void LzmaEnc_Init(CLzmaEnc *p)
-+{
-+ UInt32 i;
-+ p->state = 0;
-+ for (i = 0 ; i < LZMA_NUM_REPS; i++)
-+ p->reps[i] = 0;
-+
-+ RangeEnc_Init(&p->rc);
-+
-+
-+ for (i = 0; i < kNumStates; i++)
-+ {
-+ UInt32 j;
-+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
-+ {
-+ p->isMatch[i][j] = kProbInitValue;
-+ p->isRep0Long[i][j] = kProbInitValue;
-+ }
-+ p->isRep[i] = kProbInitValue;
-+ p->isRepG0[i] = kProbInitValue;
-+ p->isRepG1[i] = kProbInitValue;
-+ p->isRepG2[i] = kProbInitValue;
-+ }
-+
-+ {
-+ UInt32 num = 0x300 << (p->lp + p->lc);
-+ for (i = 0; i < num; i++)
-+ p->litProbs[i] = kProbInitValue;
-+ }
-+
-+ {
-+ for (i = 0; i < kNumLenToPosStates; i++)
-+ {
-+ CLzmaProb *probs = p->posSlotEncoder[i];
-+ UInt32 j;
-+ for (j = 0; j < (1 << kNumPosSlotBits); j++)
-+ probs[j] = kProbInitValue;
-+ }
-+ }
-+ {
-+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
-+ p->posEncoders[i] = kProbInitValue;
-+ }
-+
-+ LenEnc_Init(&p->lenEnc.p);
-+ LenEnc_Init(&p->repLenEnc.p);
-+
-+ for (i = 0; i < (1 << kNumAlignBits); i++)
-+ p->posAlignEncoder[i] = kProbInitValue;
-+
-+ p->optimumEndIndex = 0;
-+ p->optimumCurrentIndex = 0;
-+ p->additionalOffset = 0;
-+
-+ p->pbMask = (1 << p->pb) - 1;
-+ p->lpMask = (1 << p->lp) - 1;
-+}
-+
-+void LzmaEnc_InitPrices(CLzmaEnc *p)
-+{
-+ if (!p->fastMode)
-+ {
-+ FillDistancesPrices(p);
-+ FillAlignPrices(p);
-+ }
-+
-+ p->lenEnc.tableSize =
-+ p->repLenEnc.tableSize =
-+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
-+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
-+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
-+}
-+
-+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ UInt32 i;
-+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
-+ if (p->dictSize <= ((UInt32)1 << i))
-+ break;
-+ p->distTableSize = i * 2;
-+
-+ p->finished = False;
-+ p->result = SZ_OK;
-+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
-+ LzmaEnc_Init(p);
-+ LzmaEnc_InitPrices(p);
-+ p->nowPos64 = 0;
-+ return SZ_OK;
-+}
-+
-+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
-+ ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ p->matchFinderBase.stream = inStream;
-+ p->needInit = 1;
-+ p->rc.outStream = outStream;
-+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
-+}
-+
-+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
-+ ISeqInStream *inStream, UInt32 keepWindowSize,
-+ ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ p->matchFinderBase.stream = inStream;
-+ p->needInit = 1;
-+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-+}
-+
-+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
-+{
-+ p->matchFinderBase.directInput = 1;
-+ p->matchFinderBase.bufferBase = (Byte *)src;
-+ p->matchFinderBase.directInputRem = srcLen;
-+}
-+
-+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
-+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ LzmaEnc_SetInputBuf(p, src, srcLen);
-+ p->needInit = 1;
-+
-+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-+}
-+
-+void LzmaEnc_Finish(CLzmaEncHandle pp)
-+{
-+ #ifndef _7ZIP_ST
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ if (p->mtMode)
-+ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
-+ #else
-+ pp = pp;
-+ #endif
-+}
-+
-+typedef struct
-+{
-+ ISeqOutStream funcTable;
-+ Byte *data;
-+ SizeT rem;
-+ Bool overflow;
-+} CSeqOutStreamBuf;
-+
-+static size_t MyWrite(void *pp, const void *data, size_t size)
-+{
-+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
-+ if (p->rem < size)
-+ {
-+ size = p->rem;
-+ p->overflow = True;
-+ }
-+ memcpy(p->data, data, size);
-+ p->rem -= size;
-+ p->data += size;
-+ return size;
-+}
-+
-+
-+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
-+{
-+ const CLzmaEnc *p = (CLzmaEnc *)pp;
-+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-+}
-+
-+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
-+{
-+ const CLzmaEnc *p = (CLzmaEnc *)pp;
-+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-+}
-+
-+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
-+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ UInt64 nowPos64;
-+ SRes res;
-+ CSeqOutStreamBuf outStream;
-+
-+ outStream.funcTable.Write = MyWrite;
-+ outStream.data = dest;
-+ outStream.rem = *destLen;
-+ outStream.overflow = False;
-+
-+ p->writeEndMark = False;
-+ p->finished = False;
-+ p->result = SZ_OK;
-+
-+ if (reInit)
-+ LzmaEnc_Init(p);
-+ LzmaEnc_InitPrices(p);
-+ nowPos64 = p->nowPos64;
-+ RangeEnc_Init(&p->rc);
-+ p->rc.outStream = &outStream.funcTable;
-+
-+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
-+
-+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
-+ *destLen -= outStream.rem;
-+ if (outStream.overflow)
-+ return SZ_ERROR_OUTPUT_EOF;
-+
-+ return res;
-+}
-+
-+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
-+{
-+ SRes res = SZ_OK;
-+
-+ #ifndef _7ZIP_ST
-+ Byte allocaDummy[0x300];
-+ int i = 0;
-+ for (i = 0; i < 16; i++)
-+ allocaDummy[i] = (Byte)i;
-+ #endif
-+
-+ for (;;)
-+ {
-+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
-+ if (res != SZ_OK || p->finished != 0)
-+ break;
-+ if (progress != 0)
-+ {
-+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
-+ if (res != SZ_OK)
-+ {
-+ res = SZ_ERROR_PROGRESS;
-+ break;
-+ }
-+ }
-+ }
-+ LzmaEnc_Finish(p);
-+ return res;
-+}
-+
-+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
-+ ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
-+ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
-+}
-+
-+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+ int i;
-+ UInt32 dictSize = p->dictSize;
-+ if (*size < LZMA_PROPS_SIZE)
-+ return SZ_ERROR_PARAM;
-+ *size = LZMA_PROPS_SIZE;
-+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
-+
-+ for (i = 11; i <= 30; i++)
-+ {
-+ if (dictSize <= ((UInt32)2 << i))
-+ {
-+ dictSize = (2 << i);
-+ break;
-+ }
-+ if (dictSize <= ((UInt32)3 << i))
-+ {
-+ dictSize = (3 << i);
-+ break;
-+ }
-+ }
-+
-+ for (i = 0; i < 4; i++)
-+ props[1 + i] = (Byte)(dictSize >> (8 * i));
-+ return SZ_OK;
-+}
-+
-+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ SRes res;
-+ CLzmaEnc *p = (CLzmaEnc *)pp;
-+
-+ CSeqOutStreamBuf outStream;
-+
-+ LzmaEnc_SetInputBuf(p, src, srcLen);
-+
-+ outStream.funcTable.Write = MyWrite;
-+ outStream.data = dest;
-+ outStream.rem = *destLen;
-+ outStream.overflow = False;
-+
-+ p->writeEndMark = writeEndMark;
-+
-+ p->rc.outStream = &outStream.funcTable;
-+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
-+ if (res == SZ_OK)
-+ res = LzmaEnc_Encode2(p, progress);
-+
-+ *destLen -= outStream.rem;
-+ if (outStream.overflow)
-+ return SZ_ERROR_OUTPUT_EOF;
-+ return res;
-+}
-+
-+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
-+ SRes res;
-+ if (p == 0)
-+ return SZ_ERROR_MEM;
-+
-+ res = LzmaEnc_SetProps(p, props);
-+ if (res == SZ_OK)
-+ {
-+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
-+ if (res == SZ_OK)
-+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
-+ writeEndMark, progress, alloc, allocBig);
-+ }
-+
-+ LzmaEnc_Destroy(p, alloc, allocBig);
-+ return res;
-+}
---- /dev/null
-+++ b/lib/lzma/Makefile
-@@ -0,0 +1,7 @@
-+lzma_compress-objs := LzFind.o LzmaEnc.o
-+lzma_decompress-objs := LzmaDec.o
-+
-+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o
-+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o
-+
-+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h
diff --git a/target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch b/target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch
deleted file mode 100644
index 744fbd0e21..0000000000
--- a/target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: fs: jffs2: EOF marker
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- fs/jffs2/build.c | 10 ++++++++++
- fs/jffs2/scan.c | 21 +++++++++++++++++++--
- 2 files changed, 29 insertions(+), 2 deletions(-)
-
---- a/fs/jffs2/build.c
-+++ b/fs/jffs2/build.c
-@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct
- dbg_fsbuild("scanned flash completely\n");
- jffs2_dbg_dump_block_lists_nolock(c);
-
-+ if (c->flags & (1 << 7)) {
-+ printk("%s(): unlocking the mtd device... ", __func__);
-+ mtd_unlock(c->mtd, 0, c->mtd->size);
-+ printk("done.\n");
-+
-+ printk("%s(): erasing all blocks after the end marker... ", __func__);
-+ jffs2_erase_pending_blocks(c, -1);
-+ printk("done.\n");
-+ }
-+
- dbg_fsbuild("pass 1 starting\n");
- c->flags |= JFFS2_SB_FLAG_BUILDING;
- /* Now scan the directory tree, increasing nlink according to every dirent found. */
---- a/fs/jffs2/scan.c
-+++ b/fs/jffs2/scan.c
-@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in
- /* reset summary info for next eraseblock scan */
- jffs2_sum_reset_collected(s);
-
-- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
-- buf_size, s);
-+ if (c->flags & (1 << 7)) {
-+ if (mtd_block_isbad(c->mtd, jeb->offset))
-+ ret = BLK_STATE_BADBLOCK;
-+ else
-+ ret = BLK_STATE_ALLFF;
-+ } else
-+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
-+ buf_size, s);
-
- if (ret < 0)
- goto out;
-@@ -567,6 +573,17 @@ full_scan:
- return err;
- }
-
-+ if ((buf[0] == 0xde) &&
-+ (buf[1] == 0xad) &&
-+ (buf[2] == 0xc0) &&
-+ (buf[3] == 0xde)) {
-+ /* end of filesystem. erase everything after this point */
-+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
-+ c->flags |= (1 << 7);
-+
-+ return BLK_STATE_ALLFF;
-+ }
-+
- /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
- ofs = 0;
- max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
diff --git a/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch
deleted file mode 100644
index d7548c1419..0000000000
--- a/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: netfilter: add support for flushing conntrack via /proc
-
-lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++-
- 1 file changed, 58 insertions(+), 1 deletion(-)
-
---- a/net/netfilter/nf_conntrack_standalone.c
-+++ b/net/netfilter/nf_conntrack_standalone.c
-@@ -9,6 +9,7 @@
- #include <linux/percpu.h>
- #include <linux/netdevice.h>
- #include <linux/security.h>
-+#include <linux/inet.h>
- #include <net/net_namespace.h>
- #ifdef CONFIG_SYSCTL
- #include <linux/sysctl.h>
-@@ -465,6 +466,58 @@ static int ct_cpu_seq_show(struct seq_fi
- return 0;
- }
-
-+struct kill_request {
-+ u16 family;
-+ union nf_inet_addr addr;
-+};
-+
-+static int kill_matching(struct nf_conn *i, void *data)
-+{
-+ struct kill_request *kr = data;
-+ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-+ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple;
-+
-+ if (!kr->family)
-+ return 1;
-+
-+ if (t1->src.l3num != kr->family)
-+ return 0;
-+
-+ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) ||
-+ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) ||
-+ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) ||
-+ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3));
-+}
-+
-+static int ct_file_write(struct file *file, char *buf, size_t count)
-+{
-+ struct seq_file *seq = file->private_data;
-+ struct nf_ct_iter_data iter_data;
-+ struct kill_request kr = { };
-+
-+ if (count == 0)
-+ return 0;
-+
-+ if (count >= INET6_ADDRSTRLEN)
-+ count = INET6_ADDRSTRLEN - 1;
-+
-+ if (strnchr(buf, count, ':')) {
-+ kr.family = AF_INET6;
-+ if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL))
-+ return -EINVAL;
-+ } else if (strnchr(buf, count, '.')) {
-+ kr.family = AF_INET;
-+ if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL))
-+ return -EINVAL;
-+ }
-+
-+ iter_data.net = seq_file_net(seq);
-+ iter_data.data = &kr;
-+ nf_ct_iterate_cleanup_net(kill_matching, &iter_data);
-+
-+ return 0;
-+}
-+
- static const struct seq_operations ct_cpu_seq_ops = {
- .start = ct_cpu_seq_start,
- .next = ct_cpu_seq_next,
-@@ -478,8 +531,9 @@ static int nf_conntrack_standalone_init_
- kuid_t root_uid;
- kgid_t root_gid;
-
-- pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops,
-- sizeof(struct ct_iter_state));
-+ pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net,
-+ &ct_seq_ops, &ct_file_write,
-+ sizeof(struct ct_iter_state), NULL);
- if (!pde)
- goto out_nf_conntrack;
-
diff --git a/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch
deleted file mode 100644
index 0ab89564ee..0000000000
--- a/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 +
- net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++
- 2 files changed, 38 insertions(+)
-
---- a/include/uapi/linux/netfilter_ipv4/ip_tables.h
-+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
-@@ -89,6 +89,7 @@ struct ipt_ip {
- #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
- #define IPT_F_GOTO 0x02 /* Set if jump is a goto */
- #define IPT_F_MASK 0x03 /* All possible flag bits mask. */
-+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */
-
- /* Values for "inv" field in struct ipt_ip. */
- #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -50,6 +50,9 @@ ip_packet_match(const struct iphdr *ip,
- {
- unsigned long ret;
-
-+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
-+ return true;
-+
- if (NF_INVF(ipinfo, IPT_INV_SRCIP,
- (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
- NF_INVF(ipinfo, IPT_INV_DSTIP,
-@@ -80,6 +83,29 @@ ip_packet_match(const struct iphdr *ip,
- return true;
- }
-
-+static void
-+ip_checkdefault(struct ipt_ip *ip)
-+{
-+ static const char iface_mask[IFNAMSIZ] = {};
-+
-+ if (ip->invflags || ip->flags & IPT_F_FRAG)
-+ return;
-+
-+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
-+ return;
-+
-+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
-+ return;
-+
-+ if (ip->smsk.s_addr || ip->dmsk.s_addr)
-+ return;
-+
-+ if (ip->proto)
-+ return;
-+
-+ ip->flags |= IPT_F_NO_DEF_MATCH;
-+}
-+
- static bool
- ip_checkentry(const struct ipt_ip *ip)
- {
-@@ -525,6 +551,8 @@ find_check_entry(struct ipt_entry *e, st
- struct xt_mtchk_param mtpar;
- struct xt_entry_match *ematch;
-
-+ ip_checkdefault(&e->ip);
-+
- if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
- return -ENOMEM;
-
-@@ -819,6 +847,7 @@ copy_entries_to_user(unsigned int total_
- const struct xt_table_info *private = table->private;
- int ret = 0;
- const void *loc_cpu_entry;
-+ u8 flags;
-
- counters = alloc_counters(table);
- if (IS_ERR(counters))
-@@ -846,6 +875,14 @@ copy_entries_to_user(unsigned int total_
- goto free_counters;
- }
-
-+ flags = e->ip.flags & IPT_F_MASK;
-+ if (copy_to_user(userptr + off
-+ + offsetof(struct ipt_entry, ip.flags),
-+ &flags, sizeof(flags)) != 0) {
-+ ret = -EFAULT;
-+ goto free_counters;
-+ }
-+
- for (i = sizeof(struct ipt_entry);
- i < e->target_offset;
- i += m->u.match_size) {
-@@ -1227,12 +1264,15 @@ compat_copy_entry_to_user(struct ipt_ent
- compat_uint_t origsize;
- const struct xt_entry_match *ematch;
- int ret = 0;
-+ u8 flags = e->ip.flags & IPT_F_MASK;
-
- origsize = *size;
- ce = *dstptr;
- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
- copy_to_user(&ce->counters, &counters[i],
-- sizeof(counters[i])) != 0)
-+ sizeof(counters[i])) != 0 ||
-+ copy_to_user(&ce->ip.flags, &flags,
-+ sizeof(flags)) != 0)
- return -EFAULT;
-
- *dstptr += sizeof(struct compat_ipt_entry);
diff --git a/target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch
deleted file mode 100644
index dd557fd3ea..0000000000
--- a/target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: netfilter: match bypass default table
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++-----------
- 1 file changed, 58 insertions(+), 21 deletions(-)
-
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -246,6 +246,33 @@ struct ipt_entry *ipt_next_entry(const s
- return (void *)entry + entry->next_offset;
- }
-
-+static bool
-+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
-+{
-+ struct xt_entry_target *t;
-+ struct xt_standard_target *st;
-+
-+ if (e->target_offset != sizeof(struct ipt_entry))
-+ return false;
-+
-+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
-+ return false;
-+
-+ t = ipt_get_target(e);
-+ if (t->u.kernel.target->target)
-+ return false;
-+
-+ st = (struct xt_standard_target *) t;
-+ if (st->verdict == XT_RETURN)
-+ return false;
-+
-+ if (st->verdict >= 0)
-+ return false;
-+
-+ *verdict = (unsigned)(-st->verdict) - 1;
-+ return true;
-+}
-+
- /* Returns one of the generic firewall policies, like NF_ACCEPT. */
- unsigned int
- ipt_do_table(void *priv,
-@@ -267,27 +294,28 @@ ipt_do_table(void *priv,
- unsigned int addend;
-
- /* Initialization */
-+ WARN_ON(!(table->valid_hooks & (1 << hook)));
-+ local_bh_disable();
-+ private = READ_ONCE(table->private); /* Address dependency. */
-+ cpu = smp_processor_id();
-+ table_base = private->entries;
-+
-+ e = get_entry(table_base, private->hook_entry[hook]);
-+ if (ipt_handle_default_rule(e, &verdict)) {
-+ struct xt_counters *counter;
-+
-+ counter = xt_get_this_cpu_counter(&e->counters);
-+ ADD_COUNTER(*counter, skb->len, 1);
-+ local_bh_enable();
-+ return verdict;
-+ }
-+
- stackidx = 0;
- ip = ip_hdr(skb);
- indev = state->in ? state->in->name : nulldevname;
- outdev = state->out ? state->out->name : nulldevname;
-- /* We handle fragments by dealing with the first fragment as
-- * if it was a normal packet. All other fragments are treated
-- * normally, except that they will NEVER match rules that ask
-- * things we don't know, ie. tcp syn flag or ports). If the
-- * rule is also a fragment-specific rule, non-fragments won't
-- * match it. */
-- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
-- acpar.thoff = ip_hdrlen(skb);
-- acpar.hotdrop = false;
-- acpar.state = state;
-
-- WARN_ON(!(table->valid_hooks & (1 << hook)));
-- local_bh_disable();
- addend = xt_write_recseq_begin();
-- private = READ_ONCE(table->private); /* Address dependency. */
-- cpu = smp_processor_id();
-- table_base = private->entries;
- jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
-
- /* Switch to alternate jumpstack if we're being invoked via TEE.
-@@ -300,7 +328,16 @@ ipt_do_table(void *priv,
- if (static_key_false(&xt_tee_enabled))
- jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
-
-- e = get_entry(table_base, private->hook_entry[hook]);
-+ /* We handle fragments by dealing with the first fragment as
-+ * if it was a normal packet. All other fragments are treated
-+ * normally, except that they will NEVER match rules that ask
-+ * things we don't know, ie. tcp syn flag or ports). If the
-+ * rule is also a fragment-specific rule, non-fragments won't
-+ * match it. */
-+ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
-+ acpar.thoff = ip_hdrlen(skb);
-+ acpar.hotdrop = false;
-+ acpar.state = state;
-
- do {
- const struct xt_entry_target *t;
diff --git a/target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch
deleted file mode 100644
index 79da6778b6..0000000000
--- a/target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: netfilter: reduce match memory access
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- net/ipv4/netfilter/ip_tables.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -53,9 +53,9 @@ ip_packet_match(const struct iphdr *ip,
- if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
- return true;
-
-- if (NF_INVF(ipinfo, IPT_INV_SRCIP,
-+ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr &&
- (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
-- NF_INVF(ipinfo, IPT_INV_DSTIP,
-+ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr &&
- (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr))
- return false;
-
diff --git a/target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch
deleted file mode 100644
index 4b4825ae3b..0000000000
--- a/target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
-Date: Mon, 21 Aug 2017 11:14:14 +0300
-Subject: [PATCH] net_sched/codel: do not defer queue length update
-
-When codel wants to drop last packet in ->dequeue() it cannot call
-qdisc_tree_reduce_backlog() right away - it will notify parent qdisc
-about zero qlen and HTB/HFSC will deactivate class. The same class will
-be deactivated second time by caller of ->dequeue(). Currently codel and
-fq_codel defer update. This triggers warning in HFSC when it's qlen != 0
-but there is no active classes.
-
-This patch update parent queue length immediately: just temporary increase
-qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation
-if we have skb to return.
-
-This might open another problem in HFSC - now operation peek could fail and
-deactivate parent class.
-
-Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581
----
-
---- a/net/sched/sch_codel.c
-+++ b/net/sched/sch_codel.c
-@@ -95,11 +95,17 @@ static struct sk_buff *codel_qdisc_deque
- &q->stats, qdisc_pkt_len, codel_get_enqueue_time,
- drop_func, dequeue_func);
-
-- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
-- * or HTB crashes. Defer it for next round.
-+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
-+ * parent class, dequeue in parent qdisc will do the same if we
-+ * return skb. Temporary increment qlen if we have skb.
- */
-- if (q->stats.drop_count && sch->q.qlen) {
-- qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
-+ if (q->stats.drop_count) {
-+ if (skb)
-+ sch->q.qlen++;
-+ qdisc_tree_reduce_backlog(sch, q->stats.drop_count,
-+ q->stats.drop_len);
-+ if (skb)
-+ sch->q.qlen--;
- q->stats.drop_count = 0;
- q->stats.drop_len = 0;
- }
---- a/net/sched/sch_fq_codel.c
-+++ b/net/sched/sch_fq_codel.c
-@@ -304,6 +304,21 @@ begin:
- &flow->cvars, &q->cstats, qdisc_pkt_len,
- codel_get_enqueue_time, drop_func, dequeue_func);
-
-+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
-+ * parent class, dequeue in parent qdisc will do the same if we
-+ * return skb. Temporary increment qlen if we have skb.
-+ */
-+ if (q->cstats.drop_count) {
-+ if (skb)
-+ sch->q.qlen++;
-+ qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
-+ q->cstats.drop_len);
-+ if (skb)
-+ sch->q.qlen--;
-+ q->cstats.drop_count = 0;
-+ q->cstats.drop_len = 0;
-+ }
-+
- if (!skb) {
- /* force a pass through old_flows to prevent starvation */
- if ((head == &q->new_flows) && !list_empty(&q->old_flows))
-@@ -314,15 +329,6 @@ begin:
- }
- qdisc_bstats_update(sch, skb);
- flow->deficit -= qdisc_pkt_len(skb);
-- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
-- * or HTB crashes. Defer it for next round.
-- */
-- if (q->cstats.drop_count && sch->q.qlen) {
-- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
-- q->cstats.drop_len);
-- q->cstats.drop_count = 0;
-- q->cstats.drop_len = 0;
-- }
- return skb;
- }
-
diff --git a/target/linux/generic/pending-6.1/630-packet_socket_type.patch b/target/linux/generic/pending-6.1/630-packet_socket_type.patch
deleted file mode 100644
index 9c8be72745..0000000000
--- a/target/linux/generic/pending-6.1/630-packet_socket_type.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: net: add an optimization for dealing with raw sockets
-
-lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/uapi/linux/if_packet.h | 3 +++
- net/packet/af_packet.c | 34 +++++++++++++++++++++++++++-------
- net/packet/internal.h | 1 +
- 3 files changed, 31 insertions(+), 7 deletions(-)
-
---- a/include/uapi/linux/if_packet.h
-+++ b/include/uapi/linux/if_packet.h
-@@ -33,6 +33,8 @@ struct sockaddr_ll {
- #define PACKET_KERNEL 7 /* To kernel space */
- /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
- #define PACKET_FASTROUTE 6 /* Fastrouted frame */
-+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
-+
-
- /* Packet socket options */
-
-@@ -59,6 +61,7 @@ struct sockaddr_ll {
- #define PACKET_ROLLOVER_STATS 21
- #define PACKET_FANOUT_DATA 22
- #define PACKET_IGNORE_OUTGOING 23
-+#define PACKET_RECV_TYPE 24
-
- #define PACKET_FANOUT_HASH 0
- #define PACKET_FANOUT_LB 1
---- a/net/packet/af_packet.c
-+++ b/net/packet/af_packet.c
-@@ -1866,6 +1866,7 @@ static int packet_rcv_spkt(struct sk_buf
- {
- struct sock *sk;
- struct sockaddr_pkt *spkt;
-+ struct packet_sock *po;
-
- /*
- * When we registered the protocol we saved the socket in the data
-@@ -1873,6 +1874,7 @@ static int packet_rcv_spkt(struct sk_buf
- */
-
- sk = pt->af_packet_priv;
-+ po = pkt_sk(sk);
-
- /*
- * Yank back the headers [hope the device set this
-@@ -1885,7 +1887,7 @@ static int packet_rcv_spkt(struct sk_buf
- * so that this procedure is noop.
- */
-
-- if (skb->pkt_type == PACKET_LOOPBACK)
-+ if (!(po->pkt_type & (1 << skb->pkt_type)))
- goto out;
-
- if (!net_eq(dev_net(dev), sock_net(sk)))
-@@ -2131,12 +2133,12 @@ static int packet_rcv(struct sk_buff *sk
- unsigned int snaplen, res;
- bool is_drop_n_account = false;
-
-- if (skb->pkt_type == PACKET_LOOPBACK)
-- goto drop;
--
- sk = pt->af_packet_priv;
- po = pkt_sk(sk);
-
-+ if (!(po->pkt_type & (1 << skb->pkt_type)))
-+ goto drop;
-+
- if (!net_eq(dev_net(dev), sock_net(sk)))
- goto drop;
-
-@@ -2263,12 +2265,12 @@ static int tpacket_rcv(struct sk_buff *s
- BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
- BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
-
-- if (skb->pkt_type == PACKET_LOOPBACK)
-- goto drop;
--
- sk = pt->af_packet_priv;
- po = pkt_sk(sk);
-
-+ if (!(po->pkt_type & (1 << skb->pkt_type)))
-+ goto drop;
-+
- if (!net_eq(dev_net(dev), sock_net(sk)))
- goto drop;
-
-@@ -3377,6 +3379,7 @@ static int packet_create(struct net *net
- mutex_init(&po->pg_vec_lock);
- po->rollover = NULL;
- po->prot_hook.func = packet_rcv;
-+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
-
- if (sock->type == SOCK_PACKET)
- po->prot_hook.func = packet_rcv_spkt;
-@@ -4012,6 +4015,16 @@ packet_setsockopt(struct socket *sock, i
- WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit);
- return 0;
- }
-+ case PACKET_RECV_TYPE:
-+ {
-+ unsigned int val;
-+ if (optlen != sizeof(val))
-+ return -EINVAL;
-+ if (copy_from_sockptr(&val, optval, sizeof(val)))
-+ return -EFAULT;
-+ po->pkt_type = val & ~BIT(PACKET_LOOPBACK);
-+ return 0;
-+ }
- default:
- return -ENOPROTOOPT;
- }
-@@ -4068,6 +4081,13 @@ static int packet_getsockopt(struct sock
- case PACKET_VNET_HDR:
- val = po->has_vnet_hdr;
- break;
-+ case PACKET_RECV_TYPE:
-+ if (len > sizeof(unsigned int))
-+ len = sizeof(unsigned int);
-+ val = po->pkt_type;
-+
-+ data = &val;
-+ break;
- case PACKET_VERSION:
- val = po->tp_version;
- break;
---- a/net/packet/internal.h
-+++ b/net/packet/internal.h
-@@ -136,6 +136,7 @@ struct packet_sock {
- int (*xmit)(struct sk_buff *skb);
- struct packet_type prot_hook ____cacheline_aligned_in_smp;
- atomic_t tp_drops ____cacheline_aligned_in_smp;
-+ unsigned int pkt_type;
- };
-
- static inline struct packet_sock *pkt_sk(struct sock *sk)
diff --git a/target/linux/generic/pending-6.1/655-increase_skb_pad.patch b/target/linux/generic/pending-6.1/655-increase_skb_pad.patch
deleted file mode 100644
index 22c479311a..0000000000
--- a/target/linux/generic/pending-6.1/655-increase_skb_pad.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance
-
-lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/skbuff.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -3038,7 +3038,7 @@ static inline int pskb_network_may_pull(
- * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
- */
- #ifndef NET_SKB_PAD
--#define NET_SKB_PAD max(32, L1_CACHE_BYTES)
-+#define NET_SKB_PAD max(64, L1_CACHE_BYTES)
- #endif
-
- int ___pskb_trim(struct sk_buff *skb, unsigned int len);
diff --git a/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
deleted file mode 100644
index b799c6fc9c..0000000000
--- a/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
+++ /dev/null
@@ -1,511 +0,0 @@
-From: Steven Barth <steven@midlink.org>
-Subject: Add support for MAP-E FMRs (mesh mode)
-
-MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication
-between MAP CEs (mesh mode) without the need to forward such data to a
-border relay. This is similar to how 6rd works but for IPv4 over IPv6.
-
-Signed-off-by: Steven Barth <cyrus@openwrt.org>
----
- include/net/ip6_tunnel.h | 13 ++
- include/uapi/linux/if_tunnel.h | 13 ++
- net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++--
- 3 files changed, 291 insertions(+), 11 deletions(-)
-
---- a/include/net/ip6_tunnel.h
-+++ b/include/net/ip6_tunnel.h
-@@ -18,6 +18,18 @@
- /* determine capability on a per-packet basis */
- #define IP6_TNL_F_CAP_PER_PACKET 0x40000
-
-+/* IPv6 tunnel FMR */
-+struct __ip6_tnl_fmr {
-+ struct __ip6_tnl_fmr *next; /* next fmr in list */
-+ struct in6_addr ip6_prefix;
-+ struct in_addr ip4_prefix;
-+
-+ __u8 ip6_prefix_len;
-+ __u8 ip4_prefix_len;
-+ __u8 ea_len;
-+ __u8 offset;
-+};
-+
- struct __ip6_tnl_parm {
- char name[IFNAMSIZ]; /* name of tunnel device */
- int link; /* ifindex of underlying L2 interface */
-@@ -29,6 +41,7 @@ struct __ip6_tnl_parm {
- __u32 flags; /* tunnel flags */
- struct in6_addr laddr; /* local tunnel end-point address */
- struct in6_addr raddr; /* remote tunnel end-point address */
-+ struct __ip6_tnl_fmr *fmrs; /* FMRs */
-
- __be16 i_flags;
- __be16 o_flags;
---- a/include/uapi/linux/if_tunnel.h
-+++ b/include/uapi/linux/if_tunnel.h
-@@ -77,10 +77,23 @@ enum {
- IFLA_IPTUN_ENCAP_DPORT,
- IFLA_IPTUN_COLLECT_METADATA,
- IFLA_IPTUN_FWMARK,
-+ IFLA_IPTUN_FMRS,
- __IFLA_IPTUN_MAX,
- };
- #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
-
-+enum {
-+ IFLA_IPTUN_FMR_UNSPEC,
-+ IFLA_IPTUN_FMR_IP6_PREFIX,
-+ IFLA_IPTUN_FMR_IP4_PREFIX,
-+ IFLA_IPTUN_FMR_IP6_PREFIX_LEN,
-+ IFLA_IPTUN_FMR_IP4_PREFIX_LEN,
-+ IFLA_IPTUN_FMR_EA_LEN,
-+ IFLA_IPTUN_FMR_OFFSET,
-+ __IFLA_IPTUN_FMR_MAX,
-+};
-+#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1)
-+
- enum tunnel_encap_types {
- TUNNEL_ENCAP_NONE,
- TUNNEL_ENCAP_FOU,
---- a/net/ipv6/ip6_tunnel.c
-+++ b/net/ipv6/ip6_tunnel.c
-@@ -11,6 +11,9 @@
- * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c
- *
- * RFC 2473
-+ *
-+ * Changes:
-+ * Steven Barth <cyrus@openwrt.org>: MAP-E FMR support
- */
-
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-@@ -67,9 +70,9 @@ static bool log_ecn_error = true;
- module_param(log_ecn_error, bool, 0644);
- MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
-
--static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
-+static u32 HASH(const struct in6_addr *addr)
- {
-- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2);
-+ u32 hash = ipv6_addr_hash(addr);
-
- return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT);
- }
-@@ -114,17 +117,33 @@ static struct ip6_tnl *
- ip6_tnl_lookup(struct net *net, int link,
- const struct in6_addr *remote, const struct in6_addr *local)
- {
-- unsigned int hash = HASH(remote, local);
-+ unsigned int hash = HASH(local);
- struct ip6_tnl *t, *cand = NULL;
- struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
- struct in6_addr any;
-
- for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
- if (!ipv6_addr_equal(local, &t->parms.laddr) ||
-- !ipv6_addr_equal(remote, &t->parms.raddr) ||
- !(t->dev->flags & IFF_UP))
- continue;
-
-+ if (!ipv6_addr_equal(remote, &t->parms.raddr)) {
-+ struct __ip6_tnl_fmr *fmr;
-+ bool found = false;
-+
-+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
-+ if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix,
-+ fmr->ip6_prefix_len))
-+ continue;
-+
-+ found = true;
-+ break;
-+ }
-+
-+ if (!found)
-+ continue;
-+ }
-+
- if (link == t->parms.link)
- return t;
- else
-@@ -132,7 +151,7 @@ ip6_tnl_lookup(struct net *net, int link
- }
-
- memset(&any, 0, sizeof(any));
-- hash = HASH(&any, local);
-+ hash = HASH(local);
- for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
- if (!ipv6_addr_equal(local, &t->parms.laddr) ||
- !ipv6_addr_any(&t->parms.raddr) ||
-@@ -145,7 +164,7 @@ ip6_tnl_lookup(struct net *net, int link
- cand = t;
- }
-
-- hash = HASH(remote, &any);
-+ hash = HASH(&any);
- for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
- if (!ipv6_addr_equal(remote, &t->parms.raddr) ||
- !ipv6_addr_any(&t->parms.laddr) ||
-@@ -194,7 +213,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n,
-
- if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) {
- prio = 1;
-- h = HASH(remote, local);
-+ h = HASH(local);
- }
- return &ip6n->tnls[prio][h];
- }
-@@ -376,6 +395,12 @@ ip6_tnl_dev_uninit(struct net_device *de
- struct net *net = t->net;
- struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
-
-+ while (t->parms.fmrs) {
-+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
-+ kfree(t->parms.fmrs);
-+ t->parms.fmrs = next;
-+ }
-+
- if (dev == ip6n->fb_tnl_dev)
- RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL);
- else
-@@ -788,6 +813,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
- }
- EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl);
-
-+/**
-+ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR
-+ * @dest: destination IPv6 address buffer
-+ * @skb: received socket buffer
-+ * @fmr: MAP FMR
-+ * @xmit: Calculate for xmit or rcv
-+ **/
-+static void ip4ip6_fmr_calc(struct in6_addr *dest,
-+ const struct iphdr *iph, const uint8_t *end,
-+ const struct __ip6_tnl_fmr *fmr, bool xmit)
-+{
-+ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len);
-+ u8 *portp = NULL;
-+ bool use_dest_addr;
-+ const struct iphdr *dsth = iph;
-+
-+ if ((u8*)dsth >= end)
-+ return;
-+
-+ /* find significant IP header */
-+ if (iph->protocol == IPPROTO_ICMP) {
-+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
-+ if (ih && ((u8*)&ih[1]) <= end && (
-+ ih->type == ICMP_DEST_UNREACH ||
-+ ih->type == ICMP_SOURCE_QUENCH ||
-+ ih->type == ICMP_TIME_EXCEEDED ||
-+ ih->type == ICMP_PARAMETERPROB ||
-+ ih->type == ICMP_REDIRECT))
-+ dsth = (const struct iphdr*)&ih[1];
-+ }
-+
-+ /* in xmit-path use dest port by default and source port only if
-+ this is an ICMP reply to something else; vice versa in rcv-path */
-+ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph);
-+
-+ /* get dst port */
-+ if (((u8*)&dsth[1]) <= end && (
-+ dsth->protocol == IPPROTO_UDP ||
-+ dsth->protocol == IPPROTO_TCP ||
-+ dsth->protocol == IPPROTO_SCTP ||
-+ dsth->protocol == IPPROTO_DCCP)) {
-+ /* for UDP, TCP, SCTP and DCCP source and dest port
-+ follow IPv4 header directly */
-+ portp = ((u8*)dsth) + dsth->ihl * 4;
-+
-+ if (use_dest_addr)
-+ portp += sizeof(u16);
-+ } else if (iph->protocol == IPPROTO_ICMP) {
-+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
-+
-+ /* use icmp identifier as port */
-+ if (((u8*)&ih) <= end && (
-+ (use_dest_addr && (
-+ ih->type == ICMP_ECHOREPLY ||
-+ ih->type == ICMP_TIMESTAMPREPLY ||
-+ ih->type == ICMP_INFO_REPLY ||
-+ ih->type == ICMP_ADDRESSREPLY)) ||
-+ (!use_dest_addr && (
-+ ih->type == ICMP_ECHO ||
-+ ih->type == ICMP_TIMESTAMP ||
-+ ih->type == ICMP_INFO_REQUEST ||
-+ ih->type == ICMP_ADDRESS)
-+ )))
-+ portp = (u8*)&ih->un.echo.id;
-+ }
-+
-+ if ((portp && &portp[2] <= end) || psidlen == 0) {
-+ int frombyte = fmr->ip6_prefix_len / 8;
-+ int fromrem = fmr->ip6_prefix_len % 8;
-+ int bytes = sizeof(struct in6_addr) - frombyte;
-+ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr;
-+ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len);
-+ u64 t = 0;
-+
-+ /* extract PSID from port and add it to eabits */
-+ u16 psidbits = 0;
-+ if (psidlen > 0) {
-+ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]);
-+ psidbits >>= 16 - psidlen - fmr->offset;
-+ psidbits = (u16)(psidbits << (16 - psidlen));
-+ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen));
-+ }
-+
-+ /* rewrite destination address */
-+ *dest = fmr->ip6_prefix;
-+ memcpy(&dest->s6_addr[10], addr, sizeof(*addr));
-+ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen));
-+
-+ if (bytes > sizeof(u64))
-+ bytes = sizeof(u64);
-+
-+ /* insert eabits */
-+ memcpy(&t, &dest->s6_addr[frombyte], bytes);
-+ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1)
-+ << (64 - fmr->ea_len - fromrem));
-+ t = cpu_to_be64(t | (eabits >> fromrem));
-+ memcpy(&dest->s6_addr[frombyte], &t, bytes);
-+ }
-+}
-+
-+
- static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
- const struct tnl_ptk_info *tpi,
- struct metadata_dst *tun_dst,
-@@ -855,6 +981,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl
-
- memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
-
-+ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs &&
-+ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) {
-+ /* Packet didn't come from BR, so lookup FMR */
-+ struct __ip6_tnl_fmr *fmr;
-+ struct in6_addr expected = tunnel->parms.raddr;
-+ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next)
-+ if (ipv6_prefix_equal(&ipv6h->saddr,
-+ &fmr->ip6_prefix, fmr->ip6_prefix_len))
-+ break;
-+
-+ /* Check that IPv6 matches IPv4 source to prevent spoofing */
-+ if (fmr)
-+ ip4ip6_fmr_calc(&expected, ip_hdr(skb),
-+ skb_tail_pointer(skb), fmr, false);
-+
-+ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) {
-+ rcu_read_unlock();
-+ goto drop;
-+ }
-+ }
-+
- __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
-
- err = dscp_ecn_decapsulate(tunnel, ipv6h, skb);
-@@ -1002,6 +1149,7 @@ static void init_tel_txopt(struct ipv6_t
- opt->ops.opt_nflen = 8;
- }
-
-+
- /**
- * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
- * @t: the outgoing tunnel device
-@@ -1293,6 +1441,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
- u8 protocol)
- {
- struct ip6_tnl *t = netdev_priv(dev);
-+ struct __ip6_tnl_fmr *fmr;
- struct ipv6hdr *ipv6h;
- const struct iphdr *iph;
- int encap_limit = -1;
-@@ -1392,6 +1541,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
- fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
- dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield);
-
-+ /* try to find matching FMR */
-+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
-+ unsigned mshift = 32 - fmr->ip4_prefix_len;
-+ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift ==
-+ ntohl(ip_hdr(skb)->daddr) >> mshift)
-+ break;
-+ }
-+
-+ /* change dstaddr according to FMR */
-+ if (fmr)
-+ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true);
-+
- if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
- return -1;
-
-@@ -1545,6 +1706,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
- t->parms.link = p->link;
- t->parms.proto = p->proto;
- t->parms.fwmark = p->fwmark;
-+
-+ while (t->parms.fmrs) {
-+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
-+ kfree(t->parms.fmrs);
-+ t->parms.fmrs = next;
-+ }
-+ t->parms.fmrs = p->fmrs;
-+
- dst_cache_reset(&t->dst_cache);
- ip6_tnl_link_config(t);
- }
-@@ -1579,6 +1748,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
- p->flowinfo = u->flowinfo;
- p->link = u->link;
- p->proto = u->proto;
-+ p->fmrs = NULL;
- memcpy(p->name, u->name, sizeof(u->name));
- }
-
-@@ -1965,6 +2135,15 @@ static int ip6_tnl_validate(struct nlatt
- return 0;
- }
-
-+static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = {
-+ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) },
-+ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) },
-+ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 },
-+ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 },
-+ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 },
-+ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 }
-+};
-+
- static void ip6_tnl_netlink_parms(struct nlattr *data[],
- struct __ip6_tnl_parm *parms)
- {
-@@ -2002,6 +2181,46 @@ static void ip6_tnl_netlink_parms(struct
-
- if (data[IFLA_IPTUN_FWMARK])
- parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
-+
-+ if (data[IFLA_IPTUN_FMRS]) {
-+ unsigned rem;
-+ struct nlattr *fmr;
-+ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) {
-+ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c;
-+ struct __ip6_tnl_fmr *nfmr;
-+
-+ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX,
-+ fmr, ip6_tnl_fmr_policy, NULL);
-+
-+ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL)))
-+ continue;
-+
-+ nfmr->offset = 6;
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX]))
-+ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX],
-+ sizeof(nfmr->ip6_prefix));
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX]))
-+ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX],
-+ sizeof(nfmr->ip4_prefix));
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN]))
-+ nfmr->ip6_prefix_len = nla_get_u8(c);
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN]))
-+ nfmr->ip4_prefix_len = nla_get_u8(c);
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN]))
-+ nfmr->ea_len = nla_get_u8(c);
-+
-+ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET]))
-+ nfmr->offset = nla_get_u8(c);
-+
-+ nfmr->next = parms->fmrs;
-+ parms->fmrs = nfmr;
-+ }
-+ }
- }
-
- static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
-@@ -2085,6 +2304,12 @@ static void ip6_tnl_dellink(struct net_d
-
- static size_t ip6_tnl_get_size(const struct net_device *dev)
- {
-+ const struct ip6_tnl *t = netdev_priv(dev);
-+ struct __ip6_tnl_fmr *c;
-+ int fmrs = 0;
-+ for (c = t->parms.fmrs; c; c = c->next)
-+ ++fmrs;
-+
- return
- /* IFLA_IPTUN_LINK */
- nla_total_size(4) +
-@@ -2114,6 +2339,24 @@ static size_t ip6_tnl_get_size(const str
- nla_total_size(0) +
- /* IFLA_IPTUN_FWMARK */
- nla_total_size(4) +
-+ /* IFLA_IPTUN_FMRS */
-+ nla_total_size(0) +
-+ (
-+ /* nest */
-+ nla_total_size(0) +
-+ /* IFLA_IPTUN_FMR_IP6_PREFIX */
-+ nla_total_size(sizeof(struct in6_addr)) +
-+ /* IFLA_IPTUN_FMR_IP4_PREFIX */
-+ nla_total_size(sizeof(struct in_addr)) +
-+ /* IFLA_IPTUN_FMR_EA_LEN */
-+ nla_total_size(1) +
-+ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */
-+ nla_total_size(1) +
-+ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */
-+ nla_total_size(1) +
-+ /* IFLA_IPTUN_FMR_OFFSET */
-+ nla_total_size(1)
-+ ) * fmrs +
- 0;
- }
-
-@@ -2121,6 +2364,9 @@ static int ip6_tnl_fill_info(struct sk_b
- {
- struct ip6_tnl *tunnel = netdev_priv(dev);
- struct __ip6_tnl_parm *parm = &tunnel->parms;
-+ struct __ip6_tnl_fmr *c;
-+ int fmrcnt = 0;
-+ struct nlattr *fmrs;
-
- if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
- nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
-@@ -2130,9 +2376,27 @@ static int ip6_tnl_fill_info(struct sk_b
- nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
- nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
- nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) ||
-- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark))
-+ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) ||
-+ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS)))
- goto nla_put_failure;
-
-+ for (c = parm->fmrs; c; c = c->next) {
-+ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt);
-+ if (!fmr ||
-+ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX,
-+ sizeof(c->ip6_prefix), &c->ip6_prefix) ||
-+ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX,
-+ sizeof(c->ip4_prefix), &c->ip4_prefix) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) ||
-+ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset))
-+ goto nla_put_failure;
-+
-+ nla_nest_end(skb, fmr);
-+ }
-+ nla_nest_end(skb, fmrs);
-+
- if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
- nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
- nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
-@@ -2172,6 +2436,7 @@ static const struct nla_policy ip6_tnl_p
- [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
- [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
- [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
-+ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED },
- };
-
- static struct rtnl_link_ops ip6_link_ops __read_mostly = {
diff --git a/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
deleted file mode 100644
index 7ffb6dd1d1..0000000000
--- a/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
+++ /dev/null
@@ -1,263 +0,0 @@
-From: Jonas Gorski <jogo@openwrt.org>
-Subject: ipv6: allow rejecting with "source address failed policy"
-
-RFC6204 L-14 requires rejecting traffic from invalid addresses with
-ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/
-egress policy) on the LAN side, so add an appropriate rule for that.
-
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
----
- include/net/netns/ipv6.h | 1 +
- include/uapi/linux/fib_rules.h | 4 +++
- include/uapi/linux/rtnetlink.h | 1 +
- net/ipv4/fib_semantics.c | 4 +++
- net/ipv4/fib_trie.c | 1 +
- net/ipv4/ipmr.c | 1 +
- net/ipv6/fib6_rules.c | 4 +++
- net/ipv6/ip6mr.c | 2 ++
- net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++-
- 9 files changed, 75 insertions(+), 1 deletion(-)
-
---- a/include/net/netns/ipv6.h
-+++ b/include/net/netns/ipv6.h
-@@ -85,6 +85,7 @@ struct netns_ipv6 {
- unsigned int fib6_routes_require_src;
- #endif
- struct rt6_info *ip6_prohibit_entry;
-+ struct rt6_info *ip6_policy_failed_entry;
- struct rt6_info *ip6_blk_hole_entry;
- struct fib6_table *fib6_local_tbl;
- struct fib_rules_ops *fib6_rules_ops;
---- a/include/uapi/linux/fib_rules.h
-+++ b/include/uapi/linux/fib_rules.h
-@@ -82,6 +82,10 @@ enum {
- FR_ACT_BLACKHOLE, /* Drop without notification */
- FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */
- FR_ACT_PROHIBIT, /* Drop with EACCES */
-+ FR_ACT_RES9,
-+ FR_ACT_RES10,
-+ FR_ACT_RES11,
-+ FR_ACT_POLICY_FAILED, /* Drop with EACCES */
- __FR_ACT_MAX,
- };
-
---- a/include/uapi/linux/rtnetlink.h
-+++ b/include/uapi/linux/rtnetlink.h
-@@ -265,6 +265,7 @@ enum {
- RTN_THROW, /* Not in this table */
- RTN_NAT, /* Translate this address */
- RTN_XRESOLVE, /* Use external resolver */
-+ RTN_POLICY_FAILED, /* Failed ingress/egress policy */
- __RTN_MAX
- };
-
---- a/net/ipv4/fib_semantics.c
-+++ b/net/ipv4/fib_semantics.c
-@@ -145,6 +145,10 @@ const struct fib_prop fib_props[RTN_MAX
- .error = -EINVAL,
- .scope = RT_SCOPE_NOWHERE,
- },
-+ [RTN_POLICY_FAILED] = {
-+ .error = -EACCES,
-+ .scope = RT_SCOPE_UNIVERSE,
-+ },
- };
-
- static void rt_fibinfo_free(struct rtable __rcu **rtp)
---- a/net/ipv4/fib_trie.c
-+++ b/net/ipv4/fib_trie.c
-@@ -2783,6 +2783,7 @@ static const char *const rtn_type_names[
- [RTN_THROW] = "THROW",
- [RTN_NAT] = "NAT",
- [RTN_XRESOLVE] = "XRESOLVE",
-+ [RTN_POLICY_FAILED] = "POLICY_FAILED",
- };
-
- static inline const char *rtn_type(char *buf, size_t len, unsigned int t)
---- a/net/ipv4/ipmr.c
-+++ b/net/ipv4/ipmr.c
-@@ -180,6 +180,7 @@ static int ipmr_rule_action(struct fib_r
- case FR_ACT_UNREACHABLE:
- return -ENETUNREACH;
- case FR_ACT_PROHIBIT:
-+ case FR_ACT_POLICY_FAILED:
- return -EACCES;
- case FR_ACT_BLACKHOLE:
- default:
---- a/net/ipv6/fib6_rules.c
-+++ b/net/ipv6/fib6_rules.c
-@@ -221,6 +221,10 @@ static int __fib6_rule_action(struct fib
- err = -EACCES;
- rt = net->ipv6.ip6_prohibit_entry;
- goto discard_pkt;
-+ case FR_ACT_POLICY_FAILED:
-+ err = -EACCES;
-+ rt = net->ipv6.ip6_policy_failed_entry;
-+ goto discard_pkt;
- }
-
- tb_id = fib_rule_get_table(rule, arg);
---- a/net/ipv6/ip6mr.c
-+++ b/net/ipv6/ip6mr.c
-@@ -170,6 +170,8 @@ static int ip6mr_rule_action(struct fib_
- return -ENETUNREACH;
- case FR_ACT_PROHIBIT:
- return -EACCES;
-+ case FR_ACT_POLICY_FAILED:
-+ return -EACCES;
- case FR_ACT_BLACKHOLE:
- default:
- return -EINVAL;
---- a/net/ipv6/route.c
-+++ b/net/ipv6/route.c
-@@ -98,6 +98,8 @@ static int ip6_pkt_discard(struct sk_bu
- static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
- static int ip6_pkt_prohibit(struct sk_buff *skb);
- static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb);
-+static int ip6_pkt_policy_failed(struct sk_buff *skb);
-+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb);
- static void ip6_link_failure(struct sk_buff *skb);
- static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
- struct sk_buff *skb, u32 mtu,
-@@ -318,6 +320,18 @@ static const struct rt6_info ip6_prohibi
- .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
- };
-
-+static const struct rt6_info ip6_policy_failed_entry_template = {
-+ .dst = {
-+ .__refcnt = ATOMIC_INIT(1),
-+ .__use = 1,
-+ .obsolete = DST_OBSOLETE_FORCE_CHK,
-+ .error = -EACCES,
-+ .input = ip6_pkt_policy_failed,
-+ .output = ip6_pkt_policy_failed_out,
-+ },
-+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
-+};
-+
- static const struct rt6_info ip6_blk_hole_entry_template = {
- .dst = {
- .__refcnt = ATOMIC_INIT(1),
-@@ -1040,6 +1054,7 @@ static const int fib6_prop[RTN_MAX + 1]
- [RTN_BLACKHOLE] = -EINVAL,
- [RTN_UNREACHABLE] = -EHOSTUNREACH,
- [RTN_PROHIBIT] = -EACCES,
-+ [RTN_POLICY_FAILED] = -EACCES,
- [RTN_THROW] = -EAGAIN,
- [RTN_NAT] = -EINVAL,
- [RTN_XRESOLVE] = -EINVAL,
-@@ -1075,6 +1090,10 @@ static void ip6_rt_init_dst_reject(struc
- rt->dst.output = ip6_pkt_prohibit_out;
- rt->dst.input = ip6_pkt_prohibit;
- break;
-+ case RTN_POLICY_FAILED:
-+ rt->dst.output = ip6_pkt_policy_failed_out;
-+ rt->dst.input = ip6_pkt_policy_failed;
-+ break;
- case RTN_THROW:
- case RTN_UNREACHABLE:
- default:
-@@ -4545,6 +4564,17 @@ static int ip6_pkt_prohibit_out(struct n
- return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
- }
-
-+static int ip6_pkt_policy_failed(struct sk_buff *skb)
-+{
-+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES);
-+}
-+
-+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb)
-+{
-+ skb->dev = skb_dst(skb)->dev;
-+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES);
-+}
-+
- /*
- * Allocate a dst for local (unicast / anycast) address.
- */
-@@ -5038,7 +5068,8 @@ static int rtm_to_fib6_config(struct sk_
- if (rtm->rtm_type == RTN_UNREACHABLE ||
- rtm->rtm_type == RTN_BLACKHOLE ||
- rtm->rtm_type == RTN_PROHIBIT ||
-- rtm->rtm_type == RTN_THROW)
-+ rtm->rtm_type == RTN_THROW ||
-+ rtm->rtm_type == RTN_POLICY_FAILED)
- cfg->fc_flags |= RTF_REJECT;
-
- if (rtm->rtm_type == RTN_LOCAL)
-@@ -6285,6 +6316,8 @@ static int ip6_route_dev_notify(struct n
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- net->ipv6.ip6_prohibit_entry->dst.dev = dev;
- net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
-+ net->ipv6.ip6_policy_failed_entry->dst.dev = dev;
-+ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev);
- net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
- net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
- #endif
-@@ -6296,6 +6329,7 @@ static int ip6_route_dev_notify(struct n
- in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
-+ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev);
- in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
- #endif
- }
-@@ -6487,6 +6521,8 @@ static int __net_init ip6_route_net_init
-
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- net->ipv6.fib6_has_custom_rules = false;
-+
-+
- net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
- sizeof(*net->ipv6.ip6_prohibit_entry),
- GFP_KERNEL);
-@@ -6497,11 +6533,21 @@ static int __net_init ip6_route_net_init
- ip6_template_metrics, true);
- INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached);
-
-+ net->ipv6.ip6_policy_failed_entry =
-+ kmemdup(&ip6_policy_failed_entry_template,
-+ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL);
-+ if (!net->ipv6.ip6_policy_failed_entry)
-+ goto out_ip6_prohibit_entry;
-+ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops;
-+ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst,
-+ ip6_template_metrics, true);
-+ INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->rt6i_uncached);
-+
- net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
- sizeof(*net->ipv6.ip6_blk_hole_entry),
- GFP_KERNEL);
- if (!net->ipv6.ip6_blk_hole_entry)
-- goto out_ip6_prohibit_entry;
-+ goto out_ip6_policy_failed_entry;
- net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
- dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
- ip6_template_metrics, true);
-@@ -6528,6 +6574,8 @@ out:
- return ret;
-
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
-+out_ip6_policy_failed_entry:
-+ kfree(net->ipv6.ip6_policy_failed_entry);
- out_ip6_prohibit_entry:
- kfree(net->ipv6.ip6_prohibit_entry);
- out_ip6_null_entry:
-@@ -6547,6 +6595,7 @@ static void __net_exit ip6_route_net_exi
- kfree(net->ipv6.ip6_null_entry);
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- kfree(net->ipv6.ip6_prohibit_entry);
-+ kfree(net->ipv6.ip6_policy_failed_entry);
- kfree(net->ipv6.ip6_blk_hole_entry);
- #endif
- dst_entries_destroy(&net->ipv6.ip6_dst_ops);
-@@ -6630,6 +6679,9 @@ void __init ip6_route_init_special_entri
- init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
- init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
- init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
-+ init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev;
-+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev =
-+ in6_dev_get(init_net.loopback_dev);
- #endif
- }
-
diff --git a/target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch
deleted file mode 100644
index 94416a5d70..0000000000
--- a/target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From: Jonas Gorski <jogo@openwrt.org>
-Subject: net: provide defines for _POLICY_FAILED until all code is updated
-
-Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination
-unreachable, conflicting with our name.
-
-Add appropriate defines to allow our code to build with the new
-name until we have updated our local patches for older kernels
-and userspace packages.
-
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
----
- include/uapi/linux/fib_rules.h | 2 ++
- include/uapi/linux/icmpv6.h | 2 ++
- include/uapi/linux/rtnetlink.h | 2 ++
- 3 files changed, 6 insertions(+)
-
---- a/include/uapi/linux/fib_rules.h
-+++ b/include/uapi/linux/fib_rules.h
-@@ -89,6 +89,8 @@ enum {
- __FR_ACT_MAX,
- };
-
-+#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED
-+
- #define FR_ACT_MAX (__FR_ACT_MAX - 1)
-
- #endif
---- a/include/uapi/linux/icmpv6.h
-+++ b/include/uapi/linux/icmpv6.h
-@@ -126,6 +126,8 @@ struct icmp6hdr {
- #define ICMPV6_POLICY_FAIL 5
- #define ICMPV6_REJECT_ROUTE 6
-
-+#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL
-+
- /*
- * Codes for Time Exceeded
- */
---- a/include/uapi/linux/rtnetlink.h
-+++ b/include/uapi/linux/rtnetlink.h
-@@ -269,6 +269,8 @@ enum {
- __RTN_MAX
- };
-
-+#define RTN_FAILED_POLICY RTN_POLICY_FAILED
-+
- #define RTN_MAX (__RTN_MAX - 1)
-
-
diff --git a/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch
deleted file mode 100644
index f52233fe90..0000000000
--- a/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch
+++ /dev/null
@@ -1,627 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 23 Apr 2024 11:23:03 +0200
-Subject: [PATCH] net: add TCP fraglist GRO support
-
-When forwarding TCP after GRO, software segmentation is very expensive,
-especially when the checksum needs to be recalculated.
-One case where that's currently unavoidable is when routing packets over
-PPPoE. Performance improves significantly when using fraglist GRO
-implemented in the same way as for UDP.
-
-Here's a measurement of running 2 TCP streams through a MediaTek MT7622
-device (2-core Cortex-A53), which runs NAT with flow offload enabled from
-one ethernet port to PPPoE on another ethernet port + cake qdisc set to
-1Gbps.
-
-rx-gro-list off: 630 Mbit/s, CPU 35% idle
-rx-gro-list on: 770 Mbit/s, CPU 40% idle
-
-Signe-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/gro.h
-+++ b/include/net/gro.h
-@@ -424,6 +424,7 @@ static inline __wsum ip6_gro_compute_pse
- }
-
- int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb);
-+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb);
-
- /* Pass the currently batched GRO_NORMAL SKBs up to the stack. */
- static inline void gro_normal_list(struct napi_struct *napi)
-@@ -446,5 +447,48 @@ static inline void gro_normal_one(struct
- gro_normal_list(napi);
- }
-
-+/* This function is the alternative of 'inet_iif' and 'inet_sdif'
-+ * functions in case we can not rely on fields of IPCB.
-+ *
-+ * The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized.
-+ * The caller must hold the RCU read lock.
-+ */
-+static inline void inet_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif)
-+{
-+ *iif = inet_iif(skb) ?: skb->dev->ifindex;
-+ *sdif = 0;
-+
-+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
-+ if (netif_is_l3_slave(skb->dev)) {
-+ struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev);
-+
-+ *sdif = *iif;
-+ *iif = master ? master->ifindex : 0;
-+ }
-+#endif
-+}
-+
-+/* This function is the alternative of 'inet6_iif' and 'inet6_sdif'
-+ * functions in case we can not rely on fields of IP6CB.
-+ *
-+ * The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized.
-+ * The caller must hold the RCU read lock.
-+ */
-+static inline void inet6_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif)
-+{
-+ /* using skb->dev->ifindex because skb_dst(skb) is not initialized */
-+ *iif = skb->dev->ifindex;
-+ *sdif = 0;
-+
-+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
-+ if (netif_is_l3_slave(skb->dev)) {
-+ struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev);
-+
-+ *sdif = *iif;
-+ *iif = master ? master->ifindex : 0;
-+ }
-+#endif
-+}
-+
-
- #endif /* _NET_IPV6_GRO_H */
---- a/include/net/tcp.h
-+++ b/include/net/tcp.h
-@@ -2057,7 +2057,10 @@ void tcp_v4_destroy_sock(struct sock *sk
-
- struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
- netdev_features_t features);
--struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb);
-+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb);
-+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th);
-+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
-+ struct tcphdr *th);
- INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff));
- INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb));
- INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff));
---- a/net/core/gro.c
-+++ b/net/core/gro.c
-@@ -290,6 +290,33 @@ done:
- return 0;
- }
-
-+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
-+{
-+ if (unlikely(p->len + skb->len >= 65536))
-+ return -E2BIG;
-+
-+ if (NAPI_GRO_CB(p)->last == p)
-+ skb_shinfo(p)->frag_list = skb;
-+ else
-+ NAPI_GRO_CB(p)->last->next = skb;
-+
-+ skb_pull(skb, skb_gro_offset(skb));
-+
-+ NAPI_GRO_CB(p)->last = skb;
-+ NAPI_GRO_CB(p)->count++;
-+ p->data_len += skb->len;
-+
-+ /* sk ownership - if any - completely transferred to the aggregated packet */
-+ skb->destructor = NULL;
-+ skb->sk = NULL;
-+ p->truesize += skb->truesize;
-+ p->len += skb->len;
-+
-+ NAPI_GRO_CB(skb)->same_flow = 1;
-+
-+ return 0;
-+}
-+
-
- static void napi_gro_complete(struct napi_struct *napi, struct sk_buff *skb)
- {
---- a/net/ipv4/tcp_offload.c
-+++ b/net/ipv4/tcp_offload.c
-@@ -27,6 +27,70 @@ static void tcp_gso_tstamp(struct sk_buf
- }
- }
-
-+static void __tcpv4_gso_segment_csum(struct sk_buff *seg,
-+ __be32 *oldip, __be32 newip,
-+ __be16 *oldport, __be16 newport)
-+{
-+ struct tcphdr *th;
-+ struct iphdr *iph;
-+
-+ if (*oldip == newip && *oldport == newport)
-+ return;
-+
-+ th = tcp_hdr(seg);
-+ iph = ip_hdr(seg);
-+
-+ inet_proto_csum_replace4(&th->check, seg, *oldip, newip, true);
-+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
-+ *oldport = newport;
-+
-+ csum_replace4(&iph->check, *oldip, newip);
-+ *oldip = newip;
-+}
-+
-+static struct sk_buff *__tcpv4_gso_segment_list_csum(struct sk_buff *segs)
-+{
-+ const struct tcphdr *th;
-+ const struct iphdr *iph;
-+ struct sk_buff *seg;
-+ struct tcphdr *th2;
-+ struct iphdr *iph2;
-+
-+ seg = segs;
-+ th = tcp_hdr(seg);
-+ iph = ip_hdr(seg);
-+ th2 = tcp_hdr(seg->next);
-+ iph2 = ip_hdr(seg->next);
-+
-+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
-+ iph->daddr == iph2->daddr && iph->saddr == iph2->saddr)
-+ return segs;
-+
-+ while ((seg = seg->next)) {
-+ th2 = tcp_hdr(seg);
-+ iph2 = ip_hdr(seg);
-+
-+ __tcpv4_gso_segment_csum(seg,
-+ &iph2->saddr, iph->saddr,
-+ &th2->source, th->source);
-+ __tcpv4_gso_segment_csum(seg,
-+ &iph2->daddr, iph->daddr,
-+ &th2->dest, th->dest);
-+ }
-+
-+ return segs;
-+}
-+
-+static struct sk_buff *__tcp4_gso_segment_list(struct sk_buff *skb,
-+ netdev_features_t features)
-+{
-+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb));
-+ if (IS_ERR(skb))
-+ return skb;
-+
-+ return __tcpv4_gso_segment_list_csum(skb);
-+}
-+
- static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb,
- netdev_features_t features)
- {
-@@ -36,6 +100,9 @@ static struct sk_buff *tcp4_gso_segment(
- if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
- return ERR_PTR(-EINVAL);
-
-+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
-+ return __tcp4_gso_segment_list(skb, features);
-+
- if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
- const struct iphdr *iph = ip_hdr(skb);
- struct tcphdr *th = tcp_hdr(skb);
-@@ -177,61 +244,76 @@ out:
- return segs;
- }
-
--struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb)
-+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th)
- {
-- struct sk_buff *pp = NULL;
-+ struct tcphdr *th2;
- struct sk_buff *p;
-+
-+ list_for_each_entry(p, head, list) {
-+ if (!NAPI_GRO_CB(p)->same_flow)
-+ continue;
-+
-+ th2 = tcp_hdr(p);
-+ if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
-+ NAPI_GRO_CB(p)->same_flow = 0;
-+ continue;
-+ }
-+
-+ return p;
-+ }
-+
-+ return NULL;
-+}
-+
-+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb)
-+{
-+ unsigned int thlen, hlen, off;
- struct tcphdr *th;
-- struct tcphdr *th2;
-- unsigned int len;
-- unsigned int thlen;
-- __be32 flags;
-- unsigned int mss = 1;
-- unsigned int hlen;
-- unsigned int off;
-- int flush = 1;
-- int i;
-
- off = skb_gro_offset(skb);
- hlen = off + sizeof(*th);
- th = skb_gro_header(skb, hlen, off);
- if (unlikely(!th))
-- goto out;
-+ return NULL;
-
- thlen = th->doff * 4;
- if (thlen < sizeof(*th))
-- goto out;
-+ return NULL;
-
- hlen = off + thlen;
- if (skb_gro_header_hard(skb, hlen)) {
- th = skb_gro_header_slow(skb, hlen, off);
- if (unlikely(!th))
-- goto out;
-+ return NULL;
- }
-
- skb_gro_pull(skb, thlen);
-
-- len = skb_gro_len(skb);
-- flags = tcp_flag_word(th);
--
-- list_for_each_entry(p, head, list) {
-- if (!NAPI_GRO_CB(p)->same_flow)
-- continue;
-+ return th;
-+}
-
-- th2 = tcp_hdr(p);
-+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
-+ struct tcphdr *th)
-+{
-+ unsigned int thlen = th->doff * 4;
-+ struct sk_buff *pp = NULL;
-+ struct sk_buff *p;
-+ struct tcphdr *th2;
-+ unsigned int len;
-+ __be32 flags;
-+ unsigned int mss = 1;
-+ int flush = 1;
-+ int i;
-
-- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
-- NAPI_GRO_CB(p)->same_flow = 0;
-- continue;
-- }
-+ len = skb_gro_len(skb);
-+ flags = tcp_flag_word(th);
-
-- goto found;
-- }
-- p = NULL;
-- goto out_check_final;
-+ p = tcp_gro_lookup(head, th);
-+ if (!p)
-+ goto out_check_final;
-
--found:
- /* Include the IP ID check below from the inner most IP hdr */
-+ th2 = tcp_hdr(p);
- flush = NAPI_GRO_CB(p)->flush;
- flush |= (__force int)(flags & TCP_FLAG_CWR);
- flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
-@@ -268,6 +350,19 @@ found:
- flush |= p->decrypted ^ skb->decrypted;
- #endif
-
-+ if (unlikely(NAPI_GRO_CB(p)->is_flist)) {
-+ flush |= (__force int)(flags ^ tcp_flag_word(th2));
-+ flush |= skb->ip_summed != p->ip_summed;
-+ flush |= skb->csum_level != p->csum_level;
-+ flush |= !pskb_may_pull(skb, skb_gro_offset(skb));
-+ flush |= NAPI_GRO_CB(p)->count >= 64;
-+
-+ if (flush || skb_gro_receive_list(p, skb))
-+ mss = 1;
-+
-+ goto out_check_final;
-+ }
-+
- if (flush || skb_gro_receive(p, skb)) {
- mss = 1;
- goto out_check_final;
-@@ -289,7 +384,6 @@ out_check_final:
- if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
- pp = p;
-
--out:
- NAPI_GRO_CB(skb)->flush |= (flush != 0);
-
- return pp;
-@@ -315,18 +409,58 @@ int tcp_gro_complete(struct sk_buff *skb
- }
- EXPORT_SYMBOL(tcp_gro_complete);
-
-+static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
-+ struct tcphdr *th)
-+{
-+ const struct iphdr *iph;
-+ struct sk_buff *p;
-+ struct sock *sk;
-+ struct net *net;
-+ int iif, sdif;
-+
-+ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST))
-+ return;
-+
-+ p = tcp_gro_lookup(head, th);
-+ if (p) {
-+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
-+ return;
-+ }
-+
-+ inet_get_iif_sdif(skb, &iif, &sdif);
-+ iph = skb_gro_network_header(skb);
-+ net = dev_net(skb->dev);
-+ sk = __inet_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
-+ iph->saddr, th->source,
-+ iph->daddr, ntohs(th->dest),
-+ iif, sdif);
-+ NAPI_GRO_CB(skb)->is_flist = !sk;
-+ if (sk)
-+ sock_put(sk);
-+}
-+
- INDIRECT_CALLABLE_SCOPE
- struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)
- {
-+ struct tcphdr *th;
-+
- /* Don't bother verifying checksum if we're going to flush anyway. */
- if (!NAPI_GRO_CB(skb)->flush &&
- skb_gro_checksum_validate(skb, IPPROTO_TCP,
-- inet_gro_compute_pseudo)) {
-- NAPI_GRO_CB(skb)->flush = 1;
-- return NULL;
-- }
-+ inet_gro_compute_pseudo))
-+ goto flush;
-+
-+ th = tcp_gro_pull_header(skb);
-+ if (!th)
-+ goto flush;
-
-- return tcp_gro_receive(head, skb);
-+ tcp4_check_fraglist_gro(head, skb, th);
-+
-+ return tcp_gro_receive(head, skb, th);
-+
-+flush:
-+ NAPI_GRO_CB(skb)->flush = 1;
-+ return NULL;
- }
-
- INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
-@@ -334,6 +468,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
- const struct iphdr *iph = ip_hdr(skb);
- struct tcphdr *th = tcp_hdr(skb);
-
-+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) {
-+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV4;
-+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
-+
-+ __skb_incr_checksum_unnecessary(skb);
-+
-+ return 0;
-+ }
-+
- th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr,
- iph->daddr, 0);
- skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
---- a/net/ipv4/udp_offload.c
-+++ b/net/ipv4/udp_offload.c
-@@ -425,33 +425,6 @@ out:
- return segs;
- }
-
--static int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
--{
-- if (unlikely(p->len + skb->len >= 65536))
-- return -E2BIG;
--
-- if (NAPI_GRO_CB(p)->last == p)
-- skb_shinfo(p)->frag_list = skb;
-- else
-- NAPI_GRO_CB(p)->last->next = skb;
--
-- skb_pull(skb, skb_gro_offset(skb));
--
-- NAPI_GRO_CB(p)->last = skb;
-- NAPI_GRO_CB(p)->count++;
-- p->data_len += skb->len;
--
-- /* sk ownership - if any - completely transferred to the aggregated packet */
-- skb->destructor = NULL;
-- skb->sk = NULL;
-- p->truesize += skb->truesize;
-- p->len += skb->len;
--
-- NAPI_GRO_CB(skb)->same_flow = 1;
--
-- return 0;
--}
--
-
- #define UDP_GRO_CNT_MAX 64
- static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
---- a/net/ipv6/tcpv6_offload.c
-+++ b/net/ipv6/tcpv6_offload.c
-@@ -7,24 +7,67 @@
- */
- #include <linux/indirect_call_wrapper.h>
- #include <linux/skbuff.h>
-+#include <net/inet6_hashtables.h>
- #include <net/gro.h>
- #include <net/protocol.h>
- #include <net/tcp.h>
- #include <net/ip6_checksum.h>
- #include "ip6_offload.h"
-
-+static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
-+ struct tcphdr *th)
-+{
-+#if IS_ENABLED(CONFIG_IPV6)
-+ const struct ipv6hdr *hdr;
-+ struct sk_buff *p;
-+ struct sock *sk;
-+ struct net *net;
-+ int iif, sdif;
-+
-+ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST))
-+ return;
-+
-+ p = tcp_gro_lookup(head, th);
-+ if (p) {
-+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
-+ return;
-+ }
-+
-+ inet6_get_iif_sdif(skb, &iif, &sdif);
-+ hdr = skb_gro_network_header(skb);
-+ net = dev_net(skb->dev);
-+ sk = __inet6_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
-+ &hdr->saddr, th->source,
-+ &hdr->daddr, ntohs(th->dest),
-+ iif, sdif);
-+ NAPI_GRO_CB(skb)->is_flist = !sk;
-+ if (sk)
-+ sock_put(sk);
-+#endif /* IS_ENABLED(CONFIG_IPV6) */
-+}
-+
- INDIRECT_CALLABLE_SCOPE
- struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb)
- {
-+ struct tcphdr *th;
-+
- /* Don't bother verifying checksum if we're going to flush anyway. */
- if (!NAPI_GRO_CB(skb)->flush &&
- skb_gro_checksum_validate(skb, IPPROTO_TCP,
-- ip6_gro_compute_pseudo)) {
-- NAPI_GRO_CB(skb)->flush = 1;
-- return NULL;
-- }
-+ ip6_gro_compute_pseudo))
-+ goto flush;
-
-- return tcp_gro_receive(head, skb);
-+ th = tcp_gro_pull_header(skb);
-+ if (!th)
-+ goto flush;
-+
-+ tcp6_check_fraglist_gro(head, skb, th);
-+
-+ return tcp_gro_receive(head, skb, th);
-+
-+flush:
-+ NAPI_GRO_CB(skb)->flush = 1;
-+ return NULL;
- }
-
- INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff)
-@@ -32,6 +75,15 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com
- const struct ipv6hdr *iph = ipv6_hdr(skb);
- struct tcphdr *th = tcp_hdr(skb);
-
-+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) {
-+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV6;
-+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
-+
-+ __skb_incr_checksum_unnecessary(skb);
-+
-+ return 0;
-+ }
-+
- th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr,
- &iph->daddr, 0);
- skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;
-@@ -39,6 +91,61 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com
- return tcp_gro_complete(skb);
- }
-
-+static void __tcpv6_gso_segment_csum(struct sk_buff *seg,
-+ __be16 *oldport, __be16 newport)
-+{
-+ struct tcphdr *th;
-+
-+ if (*oldport == newport)
-+ return;
-+
-+ th = tcp_hdr(seg);
-+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
-+ *oldport = newport;
-+}
-+
-+static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs)
-+{
-+ const struct tcphdr *th;
-+ const struct ipv6hdr *iph;
-+ struct sk_buff *seg;
-+ struct tcphdr *th2;
-+ struct ipv6hdr *iph2;
-+
-+ seg = segs;
-+ th = tcp_hdr(seg);
-+ iph = ipv6_hdr(seg);
-+ th2 = tcp_hdr(seg->next);
-+ iph2 = ipv6_hdr(seg->next);
-+
-+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
-+ ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
-+ ipv6_addr_equal(&iph->daddr, &iph2->daddr))
-+ return segs;
-+
-+ while ((seg = seg->next)) {
-+ th2 = tcp_hdr(seg);
-+ iph2 = ipv6_hdr(seg);
-+
-+ iph2->saddr = iph->saddr;
-+ iph2->daddr = iph->daddr;
-+ __tcpv6_gso_segment_csum(seg, &th2->source, th->source);
-+ __tcpv6_gso_segment_csum(seg, &th2->dest, th->dest);
-+ }
-+
-+ return segs;
-+}
-+
-+static struct sk_buff *__tcp6_gso_segment_list(struct sk_buff *skb,
-+ netdev_features_t features)
-+{
-+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb));
-+ if (IS_ERR(skb))
-+ return skb;
-+
-+ return __tcpv6_gso_segment_list_csum(skb);
-+}
-+
- static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb,
- netdev_features_t features)
- {
-@@ -50,6 +157,9 @@ static struct sk_buff *tcp6_gso_segment(
- if (!pskb_may_pull(skb, sizeof(*th)))
- return ERR_PTR(-EINVAL);
-
-+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
-+ return __tcp6_gso_segment_list(skb, features);
-+
- if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
- const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
- struct tcphdr *th = tcp_hdr(skb);
diff --git a/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch b/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch
deleted file mode 100644
index 03ee537fb8..0000000000
--- a/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 8585756342caa6d27008d1ad0c18023e4211a40a Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 12:22:48 +0200
-Subject: [PATCH] of/of_net: write back netdev MAC-address to device-tree
-
-The label-mac logic relies on the mac-address property of a netdev
-devices of-node. However, the mac address can also be stored as a
-different property or read from e.g. an mtd device.
-
-Create this node when reading a mac-address from OF if it does not
-already exist and copy the mac-address used for the device to this
-property. This way, the MAC address can be accessed using procfs.
-
----
- net/core/of_net.c | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/net/core/of_net.c
-+++ b/net/core/of_net.c
-@@ -95,6 +95,27 @@ static int of_get_mac_addr_nvmem(struct
- return 0;
- }
-
-+static int of_add_mac_address(struct device_node *np, u8* addr)
-+{
-+ struct property *prop;
-+
-+ prop = kzalloc(sizeof(*prop), GFP_KERNEL);
-+ if (!prop)
-+ return -ENOMEM;
-+
-+ prop->name = "mac-address";
-+ prop->length = ETH_ALEN;
-+ prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL);
-+ if (!prop->value || of_update_property(np, prop))
-+ goto free;
-+
-+ return 0;
-+free:
-+ kfree(prop->value);
-+ kfree(prop);
-+ return -ENOMEM;
-+}
-+
- /**
- * of_get_mac_address()
- * @np: Caller's Device Node
-@@ -130,17 +151,23 @@ int of_get_mac_address(struct device_nod
-
- ret = of_get_mac_addr(np, "mac-address", addr);
- if (!ret)
-- return 0;
-+ goto found;
-
- ret = of_get_mac_addr(np, "local-mac-address", addr);
- if (!ret)
-- return 0;
-+ goto found;
-
- ret = of_get_mac_addr(np, "address", addr);
- if (!ret)
-- return 0;
-+ goto found;
-
-- return of_get_mac_addr_nvmem(np, addr);
-+ ret = of_get_mac_addr_nvmem(np, addr);
-+ if (ret)
-+ return ret;
-+
-+found:
-+ ret = of_add_mac_address(np, addr);
-+ return ret;
- }
- EXPORT_SYMBOL(of_get_mac_address);
-
diff --git a/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
deleted file mode 100644
index b335748705..0000000000
--- a/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Thu, 25 Jan 2018 12:58:55 +0100
-Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from
- nf_flow_table
-
-Move the code that deals with device events to the core.
-
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
-
---- a/net/netfilter/nf_flow_table_core.c
-+++ b/net/netfilter/nf_flow_table_core.c
-@@ -659,6 +659,23 @@ static struct pernet_operations nf_flow_
- .exit_batch = nf_flow_table_pernet_exit,
- };
-
-+static int nf_flow_table_netdev_event(struct notifier_block *this,
-+ unsigned long event, void *ptr)
-+{
-+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-+
-+ if (event != NETDEV_DOWN)
-+ return NOTIFY_DONE;
-+
-+ nf_flow_table_cleanup(dev);
-+
-+ return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block flow_offload_netdev_notifier = {
-+ .notifier_call = nf_flow_table_netdev_event,
-+};
-+
- static int __init nf_flow_table_module_init(void)
- {
- int ret;
-@@ -671,8 +688,14 @@ static int __init nf_flow_table_module_i
- if (ret)
- goto out_offload;
-
-+ ret = register_netdevice_notifier(&flow_offload_netdev_notifier);
-+ if (ret)
-+ goto out_offload_init;
-+
- return 0;
-
-+out_offload_init:
-+ nf_flow_table_offload_exit();
- out_offload:
- unregister_pernet_subsys(&nf_flow_table_net_ops);
- return ret;
-@@ -680,6 +703,7 @@ out_offload:
-
- static void __exit nf_flow_table_module_exit(void)
- {
-+ unregister_netdevice_notifier(&flow_offload_netdev_notifier);
- nf_flow_table_offload_exit();
- unregister_pernet_subsys(&nf_flow_table_net_ops);
- }
---- a/net/netfilter/nft_flow_offload.c
-+++ b/net/netfilter/nft_flow_offload.c
-@@ -479,47 +479,14 @@ static struct nft_expr_type nft_flow_off
- .owner = THIS_MODULE,
- };
-
--static int flow_offload_netdev_event(struct notifier_block *this,
-- unsigned long event, void *ptr)
--{
-- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
--
-- if (event != NETDEV_DOWN)
-- return NOTIFY_DONE;
--
-- nf_flow_table_cleanup(dev);
--
-- return NOTIFY_DONE;
--}
--
--static struct notifier_block flow_offload_netdev_notifier = {
-- .notifier_call = flow_offload_netdev_event,
--};
--
- static int __init nft_flow_offload_module_init(void)
- {
-- int err;
--
-- err = register_netdevice_notifier(&flow_offload_netdev_notifier);
-- if (err)
-- goto err;
--
-- err = nft_register_expr(&nft_flow_offload_type);
-- if (err < 0)
-- goto register_expr;
--
-- return 0;
--
--register_expr:
-- unregister_netdevice_notifier(&flow_offload_netdev_notifier);
--err:
-- return err;
-+ return nft_register_expr(&nft_flow_offload_type);
- }
-
- static void __exit nft_flow_offload_module_exit(void)
- {
- nft_unregister_expr(&nft_flow_offload_type);
-- unregister_netdevice_notifier(&flow_offload_netdev_notifier);
- }
-
- module_init(nft_flow_offload_module_init);
diff --git a/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
deleted file mode 100644
index 9f8c3d6ff5..0000000000
--- a/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 31 Aug 2023 21:48:38 +0200
-Subject: [PATCH] netfilter: nf_tables: ignore -EOPNOTSUPP on flowtable device
- offload setup
-
-On many embedded devices, it is common to configure flowtable offloading for
-a mix of different devices, some of which have hardware offload support and
-some of which don't.
-The current code limits the ability of user space to properly set up such a
-configuration by only allowing adding devices with hardware offload support to
-a offload-enabled flowtable.
-Given that offload-enabled flowtables also imply fallback to pure software
-offloading, this limitation makes little sense.
-Fix it by not bailing out when the offload setup returns -EOPNOTSUPP
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/netfilter/nf_tables_api.c
-+++ b/net/netfilter/nf_tables_api.c
-@@ -7959,7 +7959,7 @@ static int nft_register_flowtable_net_ho
- err = flowtable->data.type->setup(&flowtable->data,
- hook->ops.dev,
- FLOW_BLOCK_BIND);
-- if (err < 0)
-+ if (err < 0 && err != -EOPNOTSUPP)
- goto err_unregister_net_hooks;
-
- err = nf_register_net_hook(net, &hook->ops);
diff --git a/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
deleted file mode 100644
index 90b60def6b..0000000000
--- a/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 21 Mar 2022 20:39:59 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: enable threaded NAPI
-
-This can improve performance under load by ensuring that NAPI processing is
-not pinned on CPU 0.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4940,6 +4940,8 @@ static int mtk_probe(struct platform_dev
- * for NAPI to work
- */
- init_dummy_netdev(&eth->dummy_dev);
-+ eth->dummy_dev.threaded = 1;
-+ strcpy(eth->dummy_dev.name, "mtk_eth");
- netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx);
- netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx);
-
diff --git a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch
deleted file mode 100644
index d50bc9cd4c..0000000000
--- a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: generic: add detach callback to struct phy_driver
-
-lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- drivers/net/phy/phy_device.c | 3 +++
- include/linux/phy.h | 6 ++++++
- 2 files changed, 9 insertions(+)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1852,6 +1852,9 @@ void phy_detach(struct phy_device *phyde
- struct module *ndev_owner = NULL;
- struct mii_bus *bus;
-
-+ if (phydev->drv && phydev->drv->detach)
-+ phydev->drv->detach(phydev);
-+
- if (phydev->sysfs_links) {
- if (dev)
- sysfs_remove_link(&dev->dev.kobj, "phydev");
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -903,6 +903,12 @@ struct phy_driver {
- /** @handle_interrupt: Override default interrupt handling */
- irqreturn_t (*handle_interrupt)(struct phy_device *phydev);
-
-+ /*
-+ * Called before an ethernet device is detached
-+ * from the PHY.
-+ */
-+ void (*detach)(struct phy_device *phydev);
-+
- /** @remove: Clears up any memory if needed */
- void (*remove)(struct phy_device *phydev);
-
diff --git a/target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch b/target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch
deleted file mode 100644
index d1d6fa3fe1..0000000000
--- a/target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 14 Feb 2024 15:24:41 +0100
-Subject: [PATCH] netfilter: nf_tables: fix bidirectional offload regression
-
-Commit 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
-made unidirectional flow offload possible, while completely ignoring (and
-breaking) bidirectional flow offload for nftables.
-Add the missing flag that was left out as an exercise for the reader :)
-
-Cc: Vlad Buslov <vladbu@nvidia.com>
-Fixes: 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/netfilter/nft_flow_offload.c
-+++ b/net/netfilter/nft_flow_offload.c
-@@ -361,6 +361,7 @@ static void nft_flow_offload_eval(const
- ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
- }
-
-+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags);
- ret = flow_offload_add(flowtable, flow);
- if (ret < 0)
- goto err_flow_add;
diff --git a/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch b/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch
deleted file mode 100644
index d444b2027c..0000000000
--- a/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 6 May 2022 21:38:42 +0200
-Subject: [PATCH] net: dsa: tag_mtk: add padding for tx packets
-
-Padding for transmitted packets needs to account for the special tag.
-With not enough padding, garbage bytes are inserted by the switch at the
-end of small packets.
-
-Fixes: 5cd8985a1909 ("net-next: dsa: add Mediatek tag RX/TX handler")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/dsa/tag_mtk.c
-+++ b/net/dsa/tag_mtk.c
-@@ -27,6 +27,13 @@ static struct sk_buff *mtk_tag_xmit(stru
-
- skb_set_queue_mapping(skb, dp->index);
-
-+ /* The Ethernet switch we are interfaced with needs packets to be at
-+ * least 64 bytes (including FCS) otherwise their padding might be
-+ * corrupted. With tags enabled, we need to make sure that packets are
-+ * at least 68 bytes (including FCS and tag).
-+ */
-+ eth_skb_pad(skb);
-+
- /* Build the special tag after the MAC Source Address. If VLAN header
- * is present, it's required that VLAN header and special tag is
- * being combined. Only in this way we can allow the switch can parse
diff --git a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch
deleted file mode 100644
index 367c41bff0..0000000000
--- a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 27 Aug 2021 12:22:32 +0200
-Subject: [PATCH] bridge: add knob for filtering rx/tx BPDU packets on a port
-
-Some devices (e.g. wireless APs) can't have devices behind them be part of
-a bridge topology with redundant links, due to address limitations.
-Additionally, broadcast traffic on these devices is somewhat expensive, due to
-the low data rate and wakeups of clients in powersave mode.
-This knob can be used to ensure that BPDU packets are never sent or forwarded
-to/from these devices
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/if_bridge.h
-+++ b/include/linux/if_bridge.h
-@@ -59,6 +59,7 @@ struct br_ip_list {
- #define BR_MRP_LOST_IN_CONT BIT(19)
- #define BR_TX_FWD_OFFLOAD BIT(20)
- #define BR_PORT_LOCKED BIT(21)
-+#define BR_BPDU_FILTER BIT(22)
-
- #define BR_DEFAULT_AGEING_TIME (300 * HZ)
-
---- a/net/bridge/br_forward.c
-+++ b/net/bridge/br_forward.c
-@@ -199,6 +199,7 @@ out:
- void br_flood(struct net_bridge *br, struct sk_buff *skb,
- enum br_pkt_type pkt_type, bool local_rcv, bool local_orig)
- {
-+ const unsigned char *dest = eth_hdr(skb)->h_dest;
- struct net_bridge_port *prev = NULL;
- struct net_bridge_port *p;
-
-@@ -214,6 +215,10 @@ void br_flood(struct net_bridge *br, str
- case BR_PKT_MULTICAST:
- if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev)
- continue;
-+ if ((p->flags & BR_BPDU_FILTER) &&
-+ unlikely(is_link_local_ether_addr(dest) &&
-+ dest[5] == 0))
-+ continue;
- break;
- case BR_PKT_BROADCAST:
- if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev)
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -349,6 +349,8 @@ static rx_handler_result_t br_handle_fra
- fwd_mask |= p->group_fwd_mask;
- switch (dest[5]) {
- case 0x00: /* Bridge Group Address */
-+ if (p->flags & BR_BPDU_FILTER)
-+ goto drop;
- /* If STP is turned off,
- then must forward to keep loop detection */
- if (p->br->stp_enabled == BR_NO_STP ||
---- a/net/bridge/br_sysfs_if.c
-+++ b/net/bridge/br_sysfs_if.c
-@@ -240,6 +240,7 @@ BRPORT_ATTR_FLAG(multicast_flood, BR_MCA
- BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
- BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS);
- BRPORT_ATTR_FLAG(isolated, BR_ISOLATED);
-+BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER);
-
- #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
- static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
-@@ -292,6 +293,7 @@ static const struct brport_attribute *br
- &brport_attr_group_fwd_mask,
- &brport_attr_neigh_suppress,
- &brport_attr_isolated,
-+ &brport_attr_bpdu_filter,
- &brport_attr_backup_port,
- NULL
- };
---- a/net/bridge/br_stp_bpdu.c
-+++ b/net/bridge/br_stp_bpdu.c
-@@ -80,7 +80,8 @@ void br_send_config_bpdu(struct net_brid
- {
- unsigned char buf[35];
-
-- if (p->br->stp_enabled != BR_KERNEL_STP)
-+ if (p->br->stp_enabled != BR_KERNEL_STP ||
-+ (p->flags & BR_BPDU_FILTER))
- return;
-
- buf[0] = 0;
-@@ -127,7 +128,8 @@ void br_send_tcn_bpdu(struct net_bridge_
- {
- unsigned char buf[4];
-
-- if (p->br->stp_enabled != BR_KERNEL_STP)
-+ if (p->br->stp_enabled != BR_KERNEL_STP ||
-+ (p->flags & BR_BPDU_FILTER))
- return;
-
- buf[0] = 0;
-@@ -172,6 +174,9 @@ void br_stp_rcv(const struct stp_proto *
- if (!(br->dev->flags & IFF_UP))
- goto out;
-
-+ if (p->flags & BR_BPDU_FILTER)
-+ goto out;
-+
- if (p->state == BR_STATE_DISABLED)
- goto out;
-
---- a/include/uapi/linux/if_link.h
-+++ b/include/uapi/linux/if_link.h
-@@ -561,6 +561,7 @@ enum {
- IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
- IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
- IFLA_BRPORT_LOCKED,
-+ IFLA_BRPORT_BPDU_FILTER,
- __IFLA_BRPORT_MAX
- };
- #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
---- a/net/bridge/br_netlink.c
-+++ b/net/bridge/br_netlink.c
-@@ -188,6 +188,7 @@ static inline size_t br_port_info_size(v
- + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */
- + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */
- + nla_total_size(1) /* IFLA_BRPORT_LOCKED */
-+ + nla_total_size(1) /* IFLA_BRPORT_BPDU_FILTER */
- + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */
- + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */
- + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */
-@@ -274,7 +275,8 @@ static int br_port_fill_attrs(struct sk_
- nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN,
- !!(p->flags & BR_MRP_LOST_IN_CONT)) ||
- nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) ||
-- nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)))
-+ nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) ||
-+ nla_put_u8(skb, IFLA_BRPORT_BPDU_FILTER, !!(p->flags & BR_BPDU_FILTER)))
- return -EMSGSIZE;
-
- timerval = br_timer_value(&p->message_age_timer);
-@@ -879,6 +881,7 @@ static const struct nla_policy br_port_p
- [IFLA_BRPORT_LOCKED] = { .type = NLA_U8 },
- [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 },
- [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 },
-+ [IFLA_BRPORT_BPDU_FILTER] = { .type = NLA_U8 },
- };
-
- /* Change the state of the port and notify spanning tree */
-@@ -944,6 +947,7 @@ static int br_setport(struct net_bridge_
- br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS);
- br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED);
- br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED);
-+ br_set_port_flag(p, tb, IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER);
-
- changed_mask = old_flags ^ p->flags;
-
---- a/net/core/rtnetlink.c
-+++ b/net/core/rtnetlink.c
-@@ -57,7 +57,7 @@
- #include "dev.h"
-
- #define RTNL_MAX_TYPE 50
--#define RTNL_SLAVE_MAX_TYPE 40
-+#define RTNL_SLAVE_MAX_TYPE 41
-
- struct rtnl_link {
- rtnl_doit_func doit;
-@@ -4840,7 +4840,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu
- brport_nla_put_flag(skb, flags, mask,
- IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) ||
- brport_nla_put_flag(skb, flags, mask,
-- IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) {
-+ IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD) ||
-+ brport_nla_put_flag(skb, flags, mask,
-+ IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER)) {
- nla_nest_cancel(skb, protinfo);
- goto nla_put_failure;
- }
diff --git a/target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch b/target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch
deleted file mode 100644
index 629b141572..0000000000
--- a/target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 3b4329230db8750bea7a56ef07f07cbbf5fc6c5a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 4 Jul 2023 22:50:12 +0200
-Subject: [PATCH 19/20] net: dsa: qca8k: implement lag_fdb_add/del ops
-
-Implement lag_fdb_add/del ops to correctly support using LAG interface.
-Qca8k switch supports declaring fdb entry for link aggregation by simply
-setting the DES_PORT bits to all the LAG member.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 2 ++
- drivers/net/dsa/qca/qca8k-common.c | 48 ++++++++++++++++++++++++++++++
- drivers/net/dsa/qca/qca8k.h | 6 ++++
- 3 files changed, 56 insertions(+)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -2015,6 +2015,8 @@ static const struct dsa_switch_ops qca8k
- .port_fdb_add = qca8k_port_fdb_add,
- .port_fdb_del = qca8k_port_fdb_del,
- .port_fdb_dump = qca8k_port_fdb_dump,
-+ .lag_fdb_add = qca8k_lag_fdb_add,
-+ .lag_fdb_del = qca8k_lag_fdb_del,
- .port_mdb_add = qca8k_port_mdb_add,
- .port_mdb_del = qca8k_port_mdb_del,
- .port_mirror_add = qca8k_port_mirror_add,
---- a/drivers/net/dsa/qca/qca8k-common.c
-+++ b/drivers/net/dsa/qca/qca8k-common.c
-@@ -1215,6 +1215,42 @@ int qca8k_port_lag_leave(struct dsa_swit
- return qca8k_lag_refresh_portmap(ds, port, lag, true);
- }
-
-+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,
-+ const unsigned char *addr, u16 vid,
-+ struct dsa_db db)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ struct dsa_port *dp;
-+ u16 port_mask = 0;
-+
-+ /* Set the vid to the port vlan id if no vid is set */
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ dsa_lag_foreach_port(dp, ds->dst, &lag)
-+ port_mask |= BIT(dp->index);
-+
-+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
-+}
-+
-+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,
-+ const unsigned char *addr, u16 vid,
-+ struct dsa_db db)
-+{
-+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-+ struct dsa_port *dp;
-+ u16 port_mask = 0;
-+
-+ /* Set the vid to the port vlan id if no vid is set */
-+ if (!vid)
-+ vid = QCA8K_PORT_VID_DEF;
-+
-+ dsa_lag_foreach_port(dp, ds->dst, &lag)
-+ port_mask |= BIT(dp->index);
-+
-+ return qca8k_fdb_del(priv, addr, port_mask, vid);
-+}
-+
- int qca8k_read_switch_id(struct qca8k_priv *priv)
- {
- u32 val;
---- a/drivers/net/dsa/qca/qca8k.h
-+++ b/drivers/net/dsa/qca/qca8k.h
-@@ -590,5 +590,11 @@ int qca8k_port_lag_join(struct dsa_switc
- struct netlink_ext_ack *extack);
- int qca8k_port_lag_leave(struct dsa_switch *ds, int port,
- struct dsa_lag lag);
-+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,
-+ const unsigned char *addr, u16 vid,
-+ struct dsa_db db);
-+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,
-+ const unsigned char *addr, u16 vid,
-+ struct dsa_db db);
-
- #endif /* __QCA8K_H */
diff --git a/target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch b/target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch
deleted file mode 100644
index 24243468a8..0000000000
--- a/target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From b954d61d9ecfa64450fc178586719dc2a95b92a7 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 20 Jun 2023 21:48:24 +0200
-Subject: [PATCH 3/4] net: dsa: qca8k: enable flooding to both CPU port
-
-To permit a multi-CPU setup, flood all unknown frames to all CPU ports.
-Each CPU port should have correct LOOKUP MEMBER configuration to
-prevent receiving duplicate packets from user ports.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 13 +++++--------
- 1 file changed, 5 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1904,15 +1904,12 @@ qca8k_setup(struct dsa_switch *ds)
- }
- }
-
-- /* Forward all unknown frames to CPU port for Linux processing
-- * Notice that in multi-cpu config only one port should be set
-- * for igmp, unknown, multicast and broadcast packet
-- */
-+ /* Forward all unknown frames to CPU port for Linux processing */
- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
-- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, dsa_cpu_ports(ds)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, dsa_cpu_ports(ds)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, dsa_cpu_ports(ds)) |
-+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, dsa_cpu_ports(ds)));
- if (ret)
- return ret;
-
diff --git a/target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch b/target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch
deleted file mode 100644
index 8a58e0f76e..0000000000
--- a/target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From b2d6ebf2f92f8695c83fa6979f4ab579c588df76 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 20 Jun 2023 07:57:38 +0200
-Subject: [PATCH 4/4] net: dsa: qca8k: add support for port_change_master
-
-Add support for port_change_master to permit assigning an alternative
-CPU port if the switch have both CPU port connected or create a LAG on
-both CPU port and assign the LAG as DSA master.
-
-On port change master request, we check if the master is a LAG.
-With LAG we compose the cpu_port_mask with the CPU port in the LAG, if
-master is a simple dsa_port, we derive the index.
-
-Finally we apply the new cpu_port_mask to the LOOKUP MEMBER to permit
-the port to receive packet by the new CPU port setup for the port and we
-refresh the CPU ports LOOKUP MEMBER configuration to reflect the new
-user port state.
-
-port_lag_join/leave is updated to refresh the user ports if we detect
-that the LAG is a DSA master and we have user port using it as a master.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 116 ++++++++++++++++++++++++++++++-
- 1 file changed, 114 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -1741,6 +1741,117 @@ qca8k_get_tag_protocol(struct dsa_switch
- return DSA_TAG_PROTO_QCA;
- }
-
-+static int qca8k_port_change_master(struct dsa_switch *ds, int port,
-+ struct net_device *master,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct dsa_switch_tree *dst = ds->dst;
-+ struct qca8k_priv *priv = ds->priv;
-+ u8 cpu_port_mask = 0;
-+ struct dsa_port *dp;
-+ u32 val;
-+ int ret;
-+
-+ /* With LAG of CPU port, compose the mask for port LOOKUP MEMBER */
-+ if (netif_is_lag_master(master)) {
-+ struct dsa_lag *lag;
-+ int id;
-+
-+ id = dsa_lag_id(dst, master);
-+ lag = dsa_lag_by_id(dst, id);
-+
-+ dsa_lag_foreach_port(dp, dst, lag)
-+ if (dsa_port_is_cpu(dp))
-+ cpu_port_mask |= BIT(dp->index);
-+ } else {
-+ dp = master->dsa_ptr;
-+ cpu_port_mask |= BIT(dp->index);
-+ }
-+
-+ /* Connect port to new cpu port */
-+ ret = regmap_read(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), &val);
-+ if (ret)
-+ return ret;
-+
-+ /* Reset connected CPU port in port LOOKUP MEMBER */
-+ val &= ~dsa_cpu_ports(ds);
-+ /* Assign the new CPU port in port LOOKUP MEMBER */
-+ val |= cpu_port_mask;
-+
-+ ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port),
-+ QCA8K_PORT_LOOKUP_MEMBER,
-+ val);
-+ if (ret)
-+ return ret;
-+
-+ /* Refresh CPU port LOOKUP MEMBER with new port */
-+ dsa_tree_for_each_cpu_port(dp, ds->dst) {
-+ u32 reg = QCA8K_PORT_LOOKUP_CTRL(dp->index);
-+
-+ /* If CPU port in mask assign port, else remove port */
-+ if (BIT(dp->index) & cpu_port_mask)
-+ ret = regmap_set_bits(priv->regmap, reg, BIT(port));
-+ else
-+ ret = regmap_clear_bits(priv->regmap, reg, BIT(port));
-+
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca8k_port_lag_refresh_user_ports(struct dsa_switch *ds,
-+ struct dsa_lag lag)
-+{
-+ struct net_device *lag_dev = lag.dev;
-+ struct dsa_port *dp;
-+ int ret;
-+
-+ /* Ignore if LAG is not a DSA master */
-+ if (!netif_is_lag_master(lag_dev))
-+ return 0;
-+
-+ dsa_switch_for_each_user_port(dp, ds) {
-+ /* Skip if assigned master is not the LAG */
-+ if (dsa_port_to_master(dp) != lag_dev)
-+ continue;
-+
-+ ret = qca8k_port_change_master(ds, dp->index,
-+ lag_dev, NULL);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int qca8xxx_port_lag_join(struct dsa_switch *ds, int port,
-+ struct dsa_lag lag,
-+ struct netdev_lag_upper_info *info,
-+ struct netlink_ext_ack *extack)
-+{
-+ int ret;
-+
-+ ret = qca8k_port_lag_join(ds, port, lag, info, extack);
-+ if (ret)
-+ return ret;
-+
-+ return qca8k_port_lag_refresh_user_ports(ds, lag);
-+}
-+
-+static int qca8xxx_port_lag_leave(struct dsa_switch *ds, int port,
-+ struct dsa_lag lag)
-+{
-+ int ret;
-+
-+ ret = qca8k_port_lag_leave(ds, port, lag);
-+ if (ret)
-+ return ret;
-+
-+ return qca8k_port_lag_refresh_user_ports(ds, lag);
-+}
-+
- static void
- qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
- bool operational)
-@@ -2027,8 +2138,9 @@ static const struct dsa_switch_ops qca8k
- .phylink_mac_link_down = qca8k_phylink_mac_link_down,
- .phylink_mac_link_up = qca8k_phylink_mac_link_up,
- .get_phy_flags = qca8k_get_phy_flags,
-- .port_lag_join = qca8k_port_lag_join,
-- .port_lag_leave = qca8k_port_lag_leave,
-+ .port_lag_join = qca8xxx_port_lag_join,
-+ .port_lag_leave = qca8xxx_port_lag_leave,
-+ .port_change_master = qca8k_port_change_master,
- .master_state_change = qca8k_master_change,
- .connect_tag_protocol = qca8k_connect_tag_protocol,
- };
diff --git a/target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch
deleted file mode 100644
index 23816fe366..0000000000
--- a/target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 0f6599167c126ce32c85d4f8a1f3d1775a268572 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 6 Oct 2023 12:44:00 +0200
-Subject: [PATCH] net: dsa: qca8k: enable assisted learning on CPU port
-
-Enable assisted learning on CPU port.
-
-It has been verified that there is a problem in packet roaming
-from one BSS to another in the same security settings from one
-physical R7800 to another physical R7800 where they are in the
-same L2 broadcast domain backhauled/linked together via one
-of the ethernet ports.
-DHCP will fail to complete and traffic cannot flow for around 300
-seconds.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/dsa/qca/qca8k-8xxx.c | 14 +++++++++-----
- 1 file changed, 9 insertions(+), 5 deletions(-)
-
---- a/drivers/net/dsa/qca/qca8k-8xxx.c
-+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
-@@ -2013,6 +2013,12 @@ qca8k_setup(struct dsa_switch *ds)
- dev_err(priv->dev, "failed enabling QCA header mode on port %d", dp->index);
- return ret;
- }
-+
-+ /* Disable learning by default on all ports */
-+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(dp->index),
-+ QCA8K_PORT_LOOKUP_LEARN);
-+ if (ret)
-+ return ret;
- }
-
- /* Forward all unknown frames to CPU port for Linux processing */
-@@ -2042,11 +2048,6 @@ qca8k_setup(struct dsa_switch *ds)
- if (ret)
- return ret;
-
-- ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port),
-- QCA8K_PORT_LOOKUP_LEARN);
-- if (ret)
-- return ret;
--
- /* For port based vlans to work we need to set the
- * default egress vid
- */
-@@ -2098,6 +2099,9 @@ qca8k_setup(struct dsa_switch *ds)
- /* Set max number of LAGs supported */
- ds->num_lag_ids = QCA8K_NUM_LAGS;
-
-+ /* HW learn on CPU port is limited and require manual setting */
-+ ds->assisted_learning_on_cpu_port = true;
-+
- return 0;
- }
-
diff --git a/target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch b/target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch
deleted file mode 100644
index 55f116ec5f..0000000000
--- a/target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 3b5a603bf66236b956287909556fd7ad4904450c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 24 Jan 2024 19:38:01 +0100
-Subject: [PATCH 3/3] arm64: dts: qcom: ipq8074: add clock-frequency to MDIO
- node
-
-Add clock-frequency to MDIO node to set the MDC rate to 6.25Mhz instead
-of using the default value of 390KHz from MDIO default divider.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-@@ -263,6 +263,8 @@
- clocks = <&gcc GCC_MDIO_AHB_CLK>;
- clock-names = "gcc_mdio_ahb_clk";
-
-+ clock-frequency = <6250000>;
-+
- status = "disabled";
- };
-
diff --git a/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
deleted file mode 100644
index ed13b004e4..0000000000
--- a/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Sat, 13 Aug 2022 12:49:33 +0200
-Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
- mode
-
-The rtl8221 supports multiple SERDES modes:
-- SGMII
-- 2500base-x
-- HiSGMII
-
-Further it supports rate adaption on SERDES links to allow
-slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
-links without reducing the SERDES speed.
-
-When operating without rate adapters the SERDES link will follow the
-ethernet speed.
-
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
----
- drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -53,6 +53,15 @@
- RTL8201F_ISR_LINK)
- #define RTL8201F_IER 0x13
-
-+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1
-+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2
-+#define RTL8221B_SERDES_OPTION 0x697a
-+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -851,6 +860,48 @@ static irqreturn_t rtl9000a_handle_inter
- return IRQ_HANDLED;
- }
-
-+static int rtl8221b_config_init(struct phy_device *phydev)
-+{
-+ u16 option_mode;
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ if (!phydev->is_c45) {
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX;
-+ break;
-+ }
-+ fallthrough;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ 0x75f3, 0);
-+
-+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ RTL8221B_SERDES_OPTION,
-+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
-+ switch (option_mode) {
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1003,6 +1054,7 @@ static struct phy_driver realtek_drvs[]
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
-+ .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
-@@ -1014,6 +1066,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .config_init = rtl8221b_config_init,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch b/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
deleted file mode 100644
index abe31e66af..0000000000
--- a/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Wed, 8 Feb 2023 16:32:18 +0800
-Subject: [PATCH] net: phy: realtek: support switching between SGMII and
- 2500BASE-X for RTL822x series
-
-After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure
-SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes
-respectively. So add interface automatic switching for rtl8221 phy to
-match various wire speeds.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
----
- drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -686,6 +686,25 @@ static int rtl822x_config_aneg(struct ph
- return __genphy_config_aneg(phydev, ret);
- }
-
-+static void rtl822x_update_interface(struct phy_device *phydev)
-+{
-+ /* Automatically switch SERDES interface between
-+ * SGMII and 2500-BaseX according to speed.
-+ */
-+ switch (phydev->speed) {
-+ case SPEED_2500:
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ break;
-+ case SPEED_1000:
-+ case SPEED_100:
-+ case SPEED_10:
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
- static int rtl822x_read_status(struct phy_device *phydev)
- {
- int ret;
-@@ -704,11 +723,14 @@ static int rtl822x_read_status(struct ph
- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
- }
-
-- ret = genphy_read_status(phydev);
-+ ret = rtlgen_read_status(phydev);
- if (ret < 0)
- return ret;
-
-- return rtlgen_get_speed(phydev);
-+ if (phydev->is_c45 && phydev->link)
-+ rtl822x_update_interface(phydev);
-+
-+ return 0;
- }
-
- static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
diff --git a/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
deleted file mode 100644
index 8e0e4b1fdd..0000000000
--- a/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 2 Apr 2023 23:56:16 +0100
-Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
-
-Some vendor bootloaders do weird things with those PHYs which result in
-link modes being reported wrongly. Start from a clean sheet by resetting
-the PHY.
-
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1040,6 +1040,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc840),
- .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
-@@ -1052,6 +1053,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc838),
- .name = "RTL8226-CG 2.5Gbps PHY",
-@@ -1062,6 +1064,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc848),
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
-@@ -1072,6 +1075,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
-@@ -1083,6 +1087,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc84a),
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
-@@ -1094,6 +1099,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc961),
- .name = "RTL8366RB Gigabit Ethernet",
diff --git a/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
deleted file mode 100644
index babaa47aed..0000000000
--- a/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 01:21:57 +0300
-Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs
-
-MAC drivers don't use SGMII in-band autonegotiation unless told to do so
-in device tree using 'managed = "in-band-status"'. When using MDIO to
-access a PHY, in-band-status is unneeded as we have link-status via
-MDIO. Switch off SGMII in-band autonegotiation using magic values.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -885,6 +885,7 @@ static irqreturn_t rtl9000a_handle_inter
- static int rtl8221b_config_init(struct phy_device *phydev)
- {
- u16 option_mode;
-+ int val;
-
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_2500BASEX:
-@@ -921,6 +922,13 @@ static int rtl8221b_config_init(struct p
- break;
- }
-
-+ /* Disable SGMII AN */
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3);
-+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587,
-+ val, !(val & BIT(0)), 500, 100000, false);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
deleted file mode 100644
index 6e338d9474..0000000000
--- a/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:21:14 +0100
-Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
-
-As we cannot rely on phy_read_paged function before the PHY is
-identified, the paged read in rtlgen_supports_2_5gbps needs to be open
-coded as it is being called by the match_phy_device function, ie. before
-.read_page and .write_page have been populated.
-
-Make sure it is also protected by the MDIO bus mutex and use
-rtl821x_write_page instead of 3 individually locked MDIO bus operations.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -737,9 +737,11 @@ static bool rtlgen_supports_2_5gbps(stru
- {
- int val;
-
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
-- val = phy_read(phydev, 0x13);
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
-+ mutex_lock(&phydev->mdio.bus->mdio_lock);
-+ rtl821x_write_page(phydev, 0xa61);
-+ val = __phy_read(phydev, 0x13);
-+ rtl821x_write_page(phydev, 0);
-+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
- }
diff --git a/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
deleted file mode 100644
index cafaefd3bf..0000000000
--- a/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:23:08 +0100
-Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
- advertisement
-
-Use existing generic inline functions to encode local advertisement
-of 10GbE link modes as well as to decode link-partner advertisement.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 22 +++++-----------------
- 1 file changed, 5 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -68,10 +68,6 @@
- #define RTL_SUPPORTS_5000FULL BIT(14)
- #define RTL_SUPPORTS_2500FULL BIT(13)
- #define RTL_SUPPORTS_10000FULL BIT(0)
--#define RTL_ADV_2500FULL BIT(7)
--#define RTL_LPADV_10000FULL BIT(11)
--#define RTL_LPADV_5000FULL BIT(6)
--#define RTL_LPADV_2500FULL BIT(5)
-
- #define RTL9000A_GINMR 0x14
- #define RTL9000A_GINMR_LINK_STATUS BIT(4)
-@@ -671,14 +667,11 @@ static int rtl822x_config_aneg(struct ph
- int ret = 0;
-
- if (phydev->autoneg == AUTONEG_ENABLE) {
-- u16 adv2500 = 0;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->advertising))
-- adv2500 = RTL_ADV_2500FULL;
--
- ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
-- RTL_ADV_2500FULL, adv2500);
-+ MDIO_AN_10GBT_CTRL_ADV10G |
-+ MDIO_AN_10GBT_CTRL_ADV5G |
-+ MDIO_AN_10GBT_CTRL_ADV2_5G,
-+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising));
- if (ret < 0)
- return ret;
- }
-@@ -715,12 +708,7 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
-+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
- ret = rtlgen_read_status(phydev);
diff --git a/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
deleted file mode 100644
index 8be1af6e50..0000000000
--- a/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:25:39 +0100
-Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
- advertisement
-
-Only use link-partner advertisement bits for 10GbE modes if they are
-actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
-unless both of them are set.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -708,6 +708,10 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
-+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
-+ lpadv = 0;
-+
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
diff --git a/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch
deleted file mode 100644
index 92e7a8742a..0000000000
--- a/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 03:26:01 +0100
-Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
-
-Setup Link Down Power Saving Mode according the DTS property
-just like for RTL821x 1GE PHYs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -62,6 +62,10 @@
- #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
- #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-
-+#define RTL8221B_PHYCR1 0xa430
-+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
-+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -750,6 +754,25 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl822x_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1);
-+ if (val < 0)
-+ return val;
-+
-+ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
-+ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
-+ else
-+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val);
-+
-+ return 0;
-+}
-+
- static int rtlgen_resume(struct phy_device *phydev)
- {
- int ret = genphy_resume(phydev);
-@@ -1061,6 +1084,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1072,6 +1096,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1084,6 +1109,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1096,6 +1122,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl8221b_config_init,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
deleted file mode 100644
index 05edcc8bf4..0000000000
--- a/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 30 Apr 2023 00:15:41 +0100
-Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
-
-Early versions (?) of the RTL8221B PHY cannot be identified in a regular
-Clause-45 bus scan as the PHY doesn't report the implemented MMDs
-correctly but returns 0 instead.
-Implement custom identify function using the PKGID instead of iterating
-over the implemented MMDs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -80,6 +80,7 @@
-
- #define RTL_GENERIC_PHYID 0x001cc800
- #define RTL_8211FVD_PHYID 0x001cc878
-+#define RTL_8221B_VB_CG_PHYID 0x001cc849
-
- MODULE_DESCRIPTION("Realtek PHY driver");
- MODULE_AUTHOR("Johnson Leung");
-@@ -754,6 +755,38 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev)
-+{
-+ int val;
-+ u32 id;
-+
-+ if (phydev->mdio.bus->probe_capabilities >= MDIOBUS_C45) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ } else {
-+ val = phy_read(phydev, MII_PHYSID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read(phydev, MII_PHYSID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ }
-+
-+ return (id == RTL_8221B_VB_CG_PHYID);
-+}
-+
- static int rtl822x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -1104,7 +1137,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .soft_reset = genphy_soft_reset,
- }, {
-- PHY_ID_MATCH_EXACT(0x001cc849),
-+ .match_phy_device = rtl8221b_vb_cg_match_phy_device,
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
diff --git a/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch b/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch
deleted file mode 100644
index f3725bf7d3..0000000000
--- a/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 686c603f67ae87bf21a61b5e4b1564443f41c3ee Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 20 Oct 2022 03:34:43 +0200
-Subject: [PATCH] net: permit ieee80211_ptr even with no CFG82111 support
-
-Introduce a new flag CONFIG_CFG80211_HEADERS to compile in ieee80211_ptr
-even if CFG80211 support is not compiled in. This is needed for the
-backports project and for any downstream wireless driver that loads in
-the kernel dynamically.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- include/linux/netdevice.h | 2 +-
- net/batman-adv/hard-interface.c | 2 +-
- net/wireless/Kconfig | 4 ++++
- 3 files changed, 6 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -2190,7 +2190,7 @@ struct net_device {
- #if IS_ENABLED(CONFIG_AX25)
- void *ax25_ptr;
- #endif
--#if IS_ENABLED(CONFIG_CFG80211)
-+#if IS_ENABLED(CONFIG_CFG80211_HEADERS)
- struct wireless_dev *ieee80211_ptr;
- #endif
- #if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN)
---- a/net/batman-adv/hard-interface.c
-+++ b/net/batman-adv/hard-interface.c
-@@ -308,7 +308,7 @@ static bool batadv_is_cfg80211_netdev(st
- if (!net_device)
- return false;
-
--#if IS_ENABLED(CONFIG_CFG80211)
-+#if IS_ENABLED(CONFIG_CFG80211_HEADERS)
- /* cfg80211 drivers have to set ieee80211_ptr */
- if (net_device->ieee80211_ptr)
- return true;
---- a/net/wireless/Kconfig
-+++ b/net/wireless/Kconfig
-@@ -26,6 +26,7 @@ config CFG80211
- # using a different algorithm, though right now they shouldn't
- # (this is here rather than below to allow it to be a module)
- select CRYPTO_SHA256 if CFG80211_USE_KERNEL_REGDB_KEYS
-+ select CFG80211_HEADERS
- help
- cfg80211 is the Linux wireless LAN (802.11) configuration API.
- Enable this if you have a wireless device.
-@@ -36,6 +37,9 @@ config CFG80211
-
- When built as a module it will be called cfg80211.
-
-+config CFG80211_HEADERS
-+ bool "cfg80211 - headers support"
-+
- if CFG80211
-
- config NL80211_TESTMODE
diff --git a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
deleted file mode 100644
index decf647bce..0000000000
--- a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 23:39:52 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
- on mt7621
-
-Avoid some branches in the hot path on low-end devices with limited CPU power,
-and reduce code size
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1326,6 +1326,22 @@ 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[];
-
-+#ifdef CONFIG_SOC_MT7621
-+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
-+{
-+ return true;
-+}
-+
-+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
-+{
-+ return false;
-+}
-+
-+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
-+{
-+ return false;
-+}
-+#else
- static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
- {
- return eth->soc->version == 1;
-@@ -1340,6 +1356,7 @@ static inline bool mtk_is_netsys_v3_or_g
- {
- return eth->soc->version > 2;
- }
-+#endif
-
- static inline struct mtk_foe_entry *
- mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
diff --git a/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch
deleted file mode 100644
index 600109a950..0000000000
--- a/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 3 Nov 2022 12:38:49 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: work around issue with sending
- small fragments
-
-When lots of frames are sent with a number of very small fragments, an
-internal FIFO can overflow, causing the DMA engine to lock up lock up and
-transmit attempts time out.
-
-Fix this on MT7986 by increasing the reserved FIFO space.
-Fix this on older chips by detecting the presence of small fragments and use
-skb_gso_segment + skb_linearize to deal with them.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1561,12 +1561,28 @@ static void mtk_wake_queue(struct mtk_et
- }
- }
-
-+static bool mtk_skb_has_small_frag(struct sk_buff *skb)
-+{
-+ int min_size = 16;
-+ int i;
-+
-+ if (skb_headlen(skb) < min_size)
-+ return true;
-+
-+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-+ if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size)
-+ return true;
-+
-+ return false;
-+}
-+
- static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
- struct mtk_tx_ring *ring = &eth->tx_ring;
- struct net_device_stats *stats = &dev->stats;
-+ struct sk_buff *segs, *next;
- bool gso = false;
- int tx_num;
-
-@@ -1588,6 +1604,18 @@ static netdev_tx_t mtk_start_xmit(struct
- return NETDEV_TX_BUSY;
- }
-
-+ if (mtk_is_netsys_v1(eth) &&
-+ skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) {
-+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO);
-+ if (IS_ERR(segs))
-+ goto drop;
-+
-+ if (segs) {
-+ consume_skb(skb);
-+ skb = segs;
-+ }
-+ }
-+
- /* TSO: fill MSS info in tcp checksum field */
- if (skb_is_gso(skb)) {
- if (skb_cow_head(skb, 0)) {
-@@ -1603,8 +1631,14 @@ static netdev_tx_t mtk_start_xmit(struct
- }
- }
-
-- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
-- goto drop;
-+ skb_list_walk_safe(skb, skb, next) {
-+ if ((mtk_is_netsys_v1(eth) &&
-+ mtk_skb_has_small_frag(skb) && skb_linearize(skb)) ||
-+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) {
-+ stats->tx_dropped++;
-+ dev_kfree_skb_any(skb);
-+ }
-+ }
-
- if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
- netif_tx_stop_all_queues(dev);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -268,7 +268,7 @@
- #define MTK_CHK_DDONE_EN BIT(28)
- #define MTK_DMAD_WR_WDONE BIT(26)
- #define MTK_WCOMP_EN BIT(24)
--#define MTK_RESV_BUF (0x40 << 16)
-+#define MTK_RESV_BUF (0x80 << 16)
- #define MTK_MUTLI_CNT (0x4 << 12)
- #define MTK_LEAKY_BUCKET_EN BIT(11)
-
diff --git a/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
deleted file mode 100644
index 11a81dd0bf..0000000000
--- a/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 12:54:48 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: set NETIF_F_ALL_TSO
-
-Significantly improves performance by avoiding unnecessary segmentation
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -47,8 +47,7 @@
- #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
- NETIF_F_RXCSUM | \
- NETIF_F_HW_VLAN_CTAG_TX | \
-- NETIF_F_SG | NETIF_F_TSO | \
-- NETIF_F_TSO6 | \
-+ NETIF_F_SG | NETIF_F_ALL_TSO | \
- NETIF_F_IPV6_CSUM |\
- NETIF_F_HW_TC)
- #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM)
diff --git a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch
deleted file mode 100644
index aa86075417..0000000000
--- a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 29 Mar 2023 16:02:54 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix remaining throughput
- regression
-
-Based on further tests, it seems that the QDMA shaper is not able to
-perform shaping close to the MAC link rate without throughput loss.
-This cannot be compensated by increasing the shaping rate, so it seems
-to be an internal limit.
-
-Fix the remaining throughput regression by detecting that condition and
-limiting shaping to ports with lower link speed.
-
-This patch intentionally ignores link speed gain from TRGMII, because
-even on such links, shaping to 1000 Mbit/s incurs some throughput
-degradation.
-
-Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues")
-Reported-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -766,6 +766,7 @@ static void mtk_mac_link_up(struct phyli
- MAC_MCR_FORCE_RX_FC);
-
- /* Configure speed */
-+ mac->speed = speed;
- switch (speed) {
- case SPEED_2500:
- case SPEED_1000:
-@@ -3347,6 +3348,9 @@ found:
- if (dp->index >= MTK_QDMA_NUM_QUEUES)
- return NOTIFY_DONE;
-
-+ if (mac->speed > 0 && mac->speed <= s.base.speed)
-+ s.base.speed = 0;
-+
- mtk_set_queue_speed(eth, dp->index + 3, s.base.speed);
-
- return NOTIFY_DONE;
diff --git a/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch
deleted file mode 100644
index 61042c1ad0..0000000000
--- a/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 27 Dec 2022 15:02:51 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: ppe: fix L2 offloading with DSA
- untagging offload enabled
-
-Check for skb metadata in order to detect the case where the DSA header is not
-present.
-
-Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -8,6 +8,7 @@
- #include <linux/platform_device.h>
- #include <linux/if_ether.h>
- #include <linux/if_vlan.h>
-+#include <net/dst_metadata.h>
- #include <net/dsa.h>
- #include "mtk_eth_soc.h"
- #include "mtk_ppe.h"
-@@ -829,7 +830,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe
- skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK)
- goto out;
-
-- tag += 4;
-+ if (!skb_metadata_dst(skb))
-+ tag += 4;
-+
- if (get_unaligned_be16(tag) != ETH_P_8021Q)
- break;
-
diff --git a/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
deleted file mode 100644
index 2b379c9158..0000000000
--- a/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
+++ /dev/null
@@ -1,936 +0,0 @@
-From d5e337e7aecc2e1cc9e96768062610adb95f8f72 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 12 Dec 2023 03:51:14 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add paths and SerDes modes for
- MT7988
-
-MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes 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
-and the internal 2.5G PHY.
-
-Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
-setup the new PHYA on MT7988 to access the also still existing old
-LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
-modes.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 122 +++++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 292 +++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 107 ++++++-
- 3 files changed, 470 insertions(+), 51 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64
- return "gmac2_rgmii";
- case MTK_ETH_PATH_GMAC2_SGMII:
- return "gmac2_sgmii";
-+ case MTK_ETH_PATH_GMAC2_2P5GPHY:
-+ 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";
- }
-@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru
- return 0;
- }
-
-+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
-+{
-+ int ret;
-+
-+ if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
-+ ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
-+ if (ret)
-+ return ret;
-+
-+ /* Setup mux to 2p5g PHY */
-+ ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
-+ if (ret)
-+ return ret;
-+
-+ dev_dbg(eth->dev, "path %s in %s updated\n",
-+ mtk_eth_path_name(path), __func__);
-+ }
-+
-+ return 0;
-+}
-+
- static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
- unsigned int val = 0;
-@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_
- 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;
-@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii
- 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;
- }
-@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth
- .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
- .set_path = set_mux_u3_gmac2_to_qphy,
- }, {
-+ .name = "mux_gmac2_to_2p5gphy",
-+ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
-+ .set_path = set_mux_gmac2_to_2p5gphy,
-+ }, {
- .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
- .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
- .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
- }, {
- .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,
- },
- };
-
-@@ -249,12 +336,39 @@ out:
- 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);
-+}
-+
-+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
-+{
-+ u64 path = 0;
-+
-+ if (mac_id == MTK_GMAC2_ID)
-+ path = MTK_ETH_PATH_GMAC2_2P5GPHY;
-+
-+ if (!path)
-+ return -EINVAL;
-
- /* Setup proper MUXes along the path */
- return mtk_eth_mux_setup(eth, path);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -21,6 +21,8 @@
- #include <linux/pinctrl/devinfo.h>
- #include <linux/phylink.h>
- #include <linux/pcs/pcs-mtk-lynxi.h>
-+#include <linux/pcs/pcs-mtk-usxgmii.h>
-+#include <linux/phy/phy.h>
- #include <linux/jhash.h>
- #include <linux/bitfield.h>
- #include <net/dsa.h>
-@@ -258,12 +260,8 @@ static const char * const mtk_clks_sourc
- "ethwarp_wocpu2",
- "ethwarp_wocpu1",
- "ethwarp_wocpu0",
-- "top_usxgmii0_sel",
-- "top_usxgmii1_sel",
- "top_sgm0_sel",
- "top_sgm1_sel",
-- "top_xfi_phy0_xtal_sel",
-- "top_xfi_phy1_xtal_sel",
- "top_eth_gmii_sel",
- "top_eth_refck_50m_sel",
- "top_eth_sys_200m_sel",
-@@ -475,6 +473,30 @@ static void mtk_setup_bridge_switch(stru
- MTK_GSW_CFG);
- }
-
-+static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
-+{
-+ u32 mac_fsm, gdm_fsm;
-+
-+ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
-+
-+ 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;
-+ };
-+
-+ if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
-+ (gdm_fsm & 0xFFFF0000) == 0x00000000)
-+ return true;
-+
-+ return false;
-+}
-+
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
- phy_interface_t interface)
- {
-@@ -483,6 +505,21 @@ static struct phylink_pcs *mtk_mac_selec
- struct mtk_eth *eth = mac->hw;
- unsigned int sid;
-
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ case PHY_INTERFACE_MODE_SGMII:
-+ return mac->sgmii_pcs;
-+ case PHY_INTERFACE_MODE_5GBASER:
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ return mac->usxgmii_pcs;
-+ default:
-+ return NULL;
-+ }
-+ }
-+
- if (interface == PHY_INTERFACE_MODE_SGMII ||
- phy_interface_mode_is_8023z(interface)) {
- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
-@@ -544,7 +581,22 @@ static void mtk_mac_config(struct phylin
- 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)) {
-+ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
-+ if (err)
-+ goto init_err;
-+ }
- break;
- default:
- goto err_phy;
-@@ -599,8 +651,6 @@ static void mtk_mac_config(struct phylin
- 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 */
-@@ -617,21 +667,40 @@ static void mtk_mac_config(struct phylin
-
- /* 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;
- }
-
- /* Setup gmac */
-- if (mtk_is_netsys_v3_or_greater(eth) &&
-- mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
-- mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-- mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
-+ if (mtk_interface_mode_is_xgmii(state->interface)) {
-+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+
-+ if (mac->id == MTK_GMAC1_ID)
-+ mtk_setup_bridge_switch(eth);
-+ } else {
-+ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
-
-- mtk_setup_bridge_switch(eth);
-+ /* 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(mac->interface) ||
-+ mac->interface == PHY_INTERFACE_MODE_NA) &&
-+ !mtk_check_gmac23_idle(mac) &&
-+ !test_bit(MTK_RESETTING, &eth->state))
-+ schedule_work(&eth->pending_work);
-+ }
- }
-
-+ mac->interface = state->interface;
-+
- return;
-
- err_phy:
-@@ -644,6 +713,18 @@ init_err:
- mac->id, phy_modes(state->interface), err);
- }
-
-+static int mtk_mac_prepare(struct phylink_config *config, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+ phylink_config);
-+
-+ if (mac->pextp && mac->interface != interface)
-+ phy_reset(mac->pextp);
-+
-+ return 0;
-+}
-+
- static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
- phy_interface_t interface)
- {
-@@ -652,6 +733,10 @@ static int mtk_mac_finish(struct phylink
- struct mtk_eth *eth = mac->hw;
- u32 mcr_cur, mcr_new;
-
-+ /* Setup PMA/PMD */
-+ if (mac->pextp)
-+ phy_set_mode_ext(mac->pextp, PHY_MODE_ETHERNET, interface);
-+
- /* Enable SGMII */
- if (interface == PHY_INTERFACE_MODE_SGMII ||
- phy_interface_mode_is_8023z(interface))
-@@ -676,10 +761,14 @@ static void mtk_mac_link_down(struct phy
- {
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
- phylink_config);
-- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-
-- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
-- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-+ if (!mtk_interface_mode_is_xgmii(interface)) {
-+ 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 (mtk_is_netsys_v3_or_greater(mac->hw) && mac->id != MTK_GMAC1_ID) {
-+ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
-+ }
- }
-
- static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-@@ -751,13 +840,11 @@ static void mtk_set_queue_speed(struct m
- mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
- }
-
--static void mtk_mac_link_up(struct phylink_config *config,
-- struct phy_device *phy,
-- unsigned int mode, phy_interface_t interface,
-- int speed, int duplex, bool tx_pause, bool rx_pause)
-+static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
- {
-- struct mtk_mac *mac = container_of(config, struct mtk_mac,
-- phylink_config);
- u32 mcr;
-
- mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-@@ -791,9 +878,63 @@ static void mtk_mac_link_up(struct phyli
- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-
-+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ u32 mcr, force_link = 0;
-+
-+ if (mac->id == MTK_GMAC1_ID)
-+ return;
-+
-+ /* Eliminate the interference(before link-up) caused by PHY noise */
-+ mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
-+ mdelay(20);
-+ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
-+
-+ if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
-+ force_link = MTK_XGMAC_FORCE_LINK(mac->id);
-+
-+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
-+
-+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
-+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
-+ /* Configure pause modes -
-+ * phylink will avoid these for half duplex
-+ */
-+ if (tx_pause)
-+ mcr |= XMAC_MCR_FORCE_TX_FC;
-+ if (rx_pause)
-+ mcr |= XMAC_MCR_FORCE_RX_FC;
-+
-+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
-+}
-+
-+static void mtk_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+ struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+ phylink_config);
-+
-+ if (mtk_is_netsys_v3_or_greater(mac->hw) && mtk_interface_mode_is_xgmii(interface))
-+ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+ tx_pause, rx_pause);
-+ else
-+ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+ tx_pause, rx_pause);
-+
-+ /* Repeat pextp setup to tune link */
-+ if (mac->pextp)
-+ phy_set_mode_ext(mac->pextp, PHY_MODE_ETHERNET, interface);
-+}
-+
- static const struct phylink_mac_ops mtk_phylink_ops = {
- .mac_select_pcs = mtk_mac_select_pcs,
- .mac_config = mtk_mac_config,
-+ .mac_prepare = mtk_mac_prepare,
- .mac_finish = mtk_mac_finish,
- .mac_link_down = mtk_mac_link_down,
- .mac_link_up = mtk_mac_link_up,
-@@ -3372,6 +3513,9 @@ static int mtk_open(struct net_device *d
- struct mtk_eth *eth = mac->hw;
- int i, err;
-
-+ if (mac->pextp)
-+ phy_power_on(mac->pextp);
-+
- err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
- if (err) {
- netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3500,6 +3644,9 @@ static int mtk_stop(struct net_device *d
- for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
- mtk_ppe_stop(eth->ppe[i]);
-
-+ if (mac->pextp)
-+ phy_power_off(mac->pextp);
-+
- return 0;
- }
-
-@@ -4497,6 +4644,7 @@ static const struct net_device_ops mtk_n
- static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
- {
- const __be32 *_id = of_get_property(np, "reg", NULL);
-+ struct device_node *pcs_np;
- phy_interface_t phy_mode;
- struct phylink *phylink;
- struct mtk_mac *mac;
-@@ -4532,16 +4680,41 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->id = id;
- mac->hw = eth;
- mac->of_node = np;
-+ pcs_np = of_parse_phandle(mac->of_node, "pcs-handle", 0);
-+ if (pcs_np) {
-+ mac->sgmii_pcs = mtk_pcs_lynxi_get(eth->dev, pcs_np);
-+ if (IS_ERR(mac->sgmii_pcs)) {
-+ if (PTR_ERR(mac->sgmii_pcs) == -EPROBE_DEFER)
-+ return -EPROBE_DEFER;
-
-- err = of_get_ethdev_address(mac->of_node, eth->netdev[id]);
-- if (err == -EPROBE_DEFER)
-- return err;
-+ dev_err(eth->dev, "cannot select SGMII PCS, error %ld\n",
-+ PTR_ERR(mac->sgmii_pcs));
-+ return PTR_ERR(mac->sgmii_pcs);
-+ }
-+ }
-
-- if (err) {
-- /* If the mac address is invalid, use random mac address */
-- eth_hw_addr_random(eth->netdev[id]);
-- dev_err(eth->dev, "generated random MAC address %pM\n",
-- eth->netdev[id]->dev_addr);
-+ pcs_np = of_parse_phandle(mac->of_node, "pcs-handle", 1);
-+ if (pcs_np) {
-+ mac->usxgmii_pcs = mtk_usxgmii_pcs_get(eth->dev, pcs_np);
-+ if (IS_ERR(mac->usxgmii_pcs)) {
-+ if (PTR_ERR(mac->usxgmii_pcs) == -EPROBE_DEFER)
-+ return -EPROBE_DEFER;
-+
-+ dev_err(eth->dev, "cannot select USXGMII PCS, error %ld\n",
-+ PTR_ERR(mac->usxgmii_pcs));
-+ return PTR_ERR(mac->usxgmii_pcs);
-+ }
-+ }
-+
-+ if (mtk_is_netsys_v3_or_greater(eth) && (mac->sgmii_pcs || mac->usxgmii_pcs)) {
-+ mac->pextp = devm_of_phy_get(eth->dev, mac->of_node, NULL);
-+ if (IS_ERR(mac->pextp)) {
-+ if (PTR_ERR(mac->pextp) != -EPROBE_DEFER)
-+ dev_err(eth->dev, "cannot get PHY, error %ld\n",
-+ PTR_ERR(mac->pextp));
-+
-+ return PTR_ERR(mac->pextp);
-+ }
- }
-
- memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
-@@ -4615,8 +4788,21 @@ static int mtk_add_mac(struct mtk_eth *e
- 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);
- }
-
-+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
-+ id == MTK_GMAC2_ID)
-+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+ mac->phylink_config.supported_interfaces);
-+
- phylink = phylink_create(&mac->phylink_config,
- of_fwnode_handle(mac->of_node),
- phy_mode, &mtk_phylink_ops);
-@@ -4661,6 +4847,26 @@ free_netdev:
- return err;
- }
-
-+static int mtk_mac_assign_address(struct mtk_eth *eth, int i, bool test_defer_only)
-+{
-+ int err = of_get_ethdev_address(eth->mac[i]->of_node, eth->netdev[i]);
-+
-+ if (err == -EPROBE_DEFER)
-+ return err;
-+
-+ if (test_defer_only)
-+ return 0;
-+
-+ if (err) {
-+ /* If the mac address is invalid, use random mac address */
-+ eth_hw_addr_random(eth->netdev[i]);
-+ dev_err(eth->dev, "generated random MAC address %pM\n",
-+ eth->netdev[i]);
-+ }
-+
-+ return 0;
-+}
-+
- void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
- {
- struct net_device *dev, *tmp;
-@@ -4804,7 +5010,8 @@ static int mtk_probe(struct platform_dev
- 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)
-@@ -4915,6 +5122,24 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+
-+ err = mtk_mac_assign_address(eth, i, true);
-+ if (err)
-+ goto err_deinit_hw;
-+ }
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+
-+ err = mtk_mac_assign_address(eth, i, false);
-+ if (err)
-+ goto err_deinit_hw;
-+ }
-+
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
- err = devm_request_irq(eth->dev, eth->irq[0],
- mtk_handle_irq, 0,
-@@ -5017,6 +5242,11 @@ static int mtk_remove(struct platform_de
- mtk_stop(eth->netdev[i]);
- mac = netdev_priv(eth->netdev[i]);
- phylink_disconnect_phy(mac->phylink);
-+ if (mac->sgmii_pcs)
-+ mtk_pcs_lynxi_put(mac->sgmii_pcs);
-+
-+ if (mac->usxgmii_pcs)
-+ mtk_usxgmii_pcs_put(mac->usxgmii_pcs);
- }
-
- mtk_wed_exit();
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -15,6 +15,7 @@
- #include <linux/u64_stats_sync.h>
- #include <linux/refcount.h>
- #include <linux/phylink.h>
-+#include <linux/reset.h>
- #include <linux/rhashtable.h>
- #include <linux/dim.h>
- #include <linux/bitfield.h>
-@@ -502,6 +503,21 @@
- #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
- #define INTF_MODE_RGMII_10_100 0
-
-+/* XFI Mac control registers */
-+#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000))
-+#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x))
-+#define XMAC_MCR_TRX_DISABLE 0xf
-+#define XMAC_MCR_FORCE_TX_FC BIT(5)
-+#define XMAC_MCR_FORCE_RX_FC BIT(4)
-+
-+/* XFI Mac logic reset registers */
-+#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10)
-+#define XMAC_LOGIC_RST BIT(0)
-+
-+/* XFI Mac count global control */
-+#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100)
-+#define XMAC_GLB_CNTCLR BIT(0)
-+
- /* GPIO port control registers for GMAC 2*/
- #define GPIO_OD33_CTRL8 0x4c0
- #define GPIO_BIAS_CTRL 0xed0
-@@ -527,6 +543,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 */
-@@ -565,6 +582,11 @@
- #define GEPHY_MAC_SEL BIT(1)
-
- /* Top misc registers */
-+#define TOP_MISC_NETSYS_PCS_MUX 0x84
-+#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)
- #define SGMII_QPHY_SEL 0x2
-@@ -589,6 +611,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
-@@ -597,6 +621,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))
-
-@@ -721,12 +750,8 @@ enum mtk_clks_map {
- MTK_CLK_ETHWARP_WOCPU2,
- MTK_CLK_ETHWARP_WOCPU1,
- MTK_CLK_ETHWARP_WOCPU0,
-- MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-- MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
- MTK_CLK_TOP_SGM_0_SEL,
- MTK_CLK_TOP_SGM_1_SEL,
-- MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-- MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
- MTK_CLK_TOP_ETH_GMII_SEL,
- MTK_CLK_TOP_ETH_REFCK_50M_SEL,
- MTK_CLK_TOP_ETH_SYS_200M_SEL,
-@@ -797,19 +822,9 @@ enum mtk_clks_map {
- BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
- BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
- BIT_ULL(MTK_CLK_CRYPTO) | \
-- BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-- BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-- BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-- BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
- BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
- BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
- BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-- BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-- BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-- BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-- BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-- BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-- BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
- BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
- BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
- BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
-@@ -943,6 +958,8 @@ 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,
- MTK_MUX_BIT,
-@@ -963,8 +980,11 @@ enum mkt_eth_capabilities {
- MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
- MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
- MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
-+ 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,
-@@ -972,14 +992,21 @@ enum mkt_eth_capabilities {
- MTK_ETH_PATH_GMAC1_SGMII_BIT,
- MTK_ETH_PATH_GMAC2_RGMII_BIT,
- 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)
- #define MTK_MUX BIT_ULL(MTK_MUX_BIT)
-@@ -1002,10 +1029,16 @@ enum mkt_eth_capabilities {
- BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
- BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \
-+ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
- 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)
-@@ -1013,8 +1046,13 @@ enum mkt_eth_capabilities {
- #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
- #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)
-@@ -1022,7 +1060,12 @@ enum mkt_eth_capabilities {
- #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
- #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 */
-@@ -1041,10 +1084,20 @@ enum mkt_eth_capabilities {
- (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
- MTK_SHARED_SGMII)
-
-+/* 2: GMAC2 -> XGMII */
-+#define MTK_MUX_GMAC2_TO_2P5GPHY \
-+ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
-+
- /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
- #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 | \
-@@ -1076,8 +1129,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_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;
-@@ -1314,6 +1371,9 @@ struct mtk_mac {
- struct device_node *of_node;
- struct phylink *phylink;
- struct phylink_config phylink_config;
-+ struct phylink_pcs *sgmii_pcs;
-+ struct phylink_pcs *usxgmii_pcs;
-+ struct phy *pextp;
- struct mtk_eth *hw;
- struct mtk_hw_stats *hw_stats;
- __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
-@@ -1437,6 +1497,19 @@ static inline u32 mtk_get_ib2_multicast_
- return MTK_FOE_IB2_MULTICAST;
- }
-
-+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
-+{
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_INTERNAL:
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ case PHY_INTERFACE_MODE_5GBASER:
-+ return true;
-+ default:
-+ return false;
-+ }
-+}
-+
- /* read the hardware status register */
- void mtk_stats_update_mac(struct mtk_mac *mac);
-
-@@ -1445,8 +1518,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
- u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
-
- 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);
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
diff --git a/target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch b/target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch
deleted file mode 100644
index b598d15866..0000000000
--- a/target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From dee3f591103910c8d8b2a6d57879ccd2a4be4b10 Mon Sep 17 00:00:00 2001
-Message-ID: <dee3f591103910c8d8b2a6d57879ccd2a4be4b10.1706067287.git.daniel@makrotopia.org>
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 24 Jan 2024 03:19:49 +0000
-Subject: [PATCH net] net: ethernet: mtk_eth_soc: set coherent mask to get PPE
- working
-To: Felix Fietkau <nbd@nbd.name>,
- Sean Wang <sean.wang@mediatek.com>,
- Mark Lee <Mark-MC.Lee@mediatek.com>,
- Lorenzo Bianconi <lorenzo@kernel.org>,
- David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Daniel Golle <daniel@makrotopia.org>,
- netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org
-
-Set DMA coherent mask to 32-bit which makes PPE offloading engine start
-working on BPi-R4 which got 4 GiB of RAM.
-
-Fixes: 2d75891ebc09 ("net: ethernet: mtk_eth_soc: support 36-bit DMA addressing on MT7988")
-Suggested-by: Elad Yifee <eladwf@users.github.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4963,7 +4963,10 @@ static int mtk_probe(struct platform_dev
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
-- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
-+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
-+ if (!err)
-+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-+
- if (err) {
- dev_err(&pdev->dev, "Wrong DMA config\n");
- return -EINVAL;
diff --git a/target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch b/target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch
deleted file mode 100644
index 1f1c40b1d9..0000000000
--- a/target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From patchwork Thu Feb 1 21:52:20 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 13541842
-Date: Thu, 1 Feb 2024 21:52:20 +0000
-From: Daniel Golle <daniel@makrotopia.org>
-To: Bc-bocun Chen <bc-bocun.chen@mediatek.com>,
- Steven Liu <steven.liu@mediatek.com>,
- John Crispin <john@phrozen.org>,
- Chunfeng Yun <chunfeng.yun@mediatek.com>,
- Vinod Koul <vkoul@kernel.org>,
- Kishon Vijay Abraham I <kishon@kernel.org>,
- Rob Herring <robh@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Conor Dooley <conor+dt@kernel.org>,
- Daniel Golle <daniel@makrotopia.org>,
- Qingfang Deng <dqfext@gmail.com>,
- SkyLake Huang <SkyLake.Huang@mediatek.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Philipp Zabel <p.zabel@pengutronix.de>,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings
-Message-ID:
- <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-List-Id: Linux Phy Mailing list <linux-phy.lists.infradead.org>
-
-Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found in the
-MediaTek MT7988 SoC which can operate at various interfaces modes:
-
-via USXGMII PCS:
- * USXGMII
- * 10GBase-R
- * 5GBase-R
-
-via LynxI SGMII PCS:
- * 2500Base-X
- * 1000Base-X
- * Cisco SGMII (MAC side)
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- .../bindings/phy/mediatek,xfi-tphy.yaml | 80 +++++++++++++++++++
- 1 file changed, 80 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
-@@ -0,0 +1,80 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek XFI T-PHY
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+description:
-+ The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
-+ used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
-+ MediaTek's 10G-capabale SoCs.
-+
-+properties:
-+ $nodename:
-+ pattern: "^phy@[0-9a-f]+$"
-+
-+ compatible:
-+ const: mediatek,mt7988-xfi-tphy
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: XFI PHY clock
-+ - description: XFI register clock
-+
-+ clock-names:
-+ items:
-+ - const: xfipll
-+ - const: topxtal
-+
-+ resets:
-+ items:
-+ - description: PEXTP reset
-+
-+ mediatek,usxgmii-performance-errata:
-+ $ref: /schemas/types.yaml#/definitions/flag
-+ description:
-+ One instance of the T-PHY on MT7988 suffers from a performance
-+ problem in 10GBase-R mode which needs a work-around in the driver.
-+ The work-around is enabled using this flag.
-+
-+ "#phy-cells":
-+ const: 0
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - "#phy-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/mediatek,mt7988-clk.h>
-+ soc {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+
-+ 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>;
-+ };
-+ };
-+
-+...
diff --git a/target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch b/target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch
deleted file mode 100644
index 1aa36fcd3d..0000000000
--- a/target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch
+++ /dev/null
@@ -1,498 +0,0 @@
-From patchwork Thu Feb 1 21:53:06 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 13541843
-Date: Thu, 1 Feb 2024 21:53:06 +0000
-From: Daniel Golle <daniel@makrotopia.org>
-To: Bc-bocun Chen <bc-bocun.chen@mediatek.com>,
- Chunfeng Yun <chunfeng.yun@mediatek.com>,
- Vinod Koul <vkoul@kernel.org>,
- Kishon Vijay Abraham I <kishon@kernel.org>,
- Rob Herring <robh@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Conor Dooley <conor+dt@kernel.org>,
- Daniel Golle <daniel@makrotopia.org>,
- Qingfang Deng <dqfext@gmail.com>,
- SkyLake Huang <SkyLake.Huang@mediatek.com>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Philipp Zabel <p.zabel@pengutronix.de>,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
-Message-ID:
- <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
-References:
- <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-In-Reply-To:
- <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
-List-Id: Linux Phy Mailing list <linux-phy.lists.infradead.org>
-
-Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes PHY
-which can be found in the MT7988 SoC.
-
-The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
-PHY_INTERFACE_MODE_* corresponding to the supported modes:
-
- * USXGMII \
- * 10GBase-R }- USXGMII PCS - XGDM \
- * 5GBase-R / \
- }- Ethernet MAC
- * 2500Base-X \ /
- * 1000Base-X }- LynxI PCS - GDM /
- * Cisco SGMII (MAC side) /
-
-In order to work-around a performance issue present on the first of
-two XFI T-PHYs present in MT7988, special tuning is applied which can be
-selected by adding the 'mediatek,usxgmii-performance-errata' property to
-the device tree node.
-
-There is no documentation for most registers used for the
-analog/tuning part, however, most of the registers have been partially
-reverse-engineered from MediaTek's SDK implementation (an opaque
-sequence of 32-bit register writes) and descriptions for all relevant
-digital registers and bits such as resets and muxes have been supplied
-by MediaTek.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- MAINTAINERS | 1 +
- drivers/phy/mediatek/Kconfig | 12 +
- drivers/phy/mediatek/Makefile | 1 +
- drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392 ++++++++++++++++++++++++
- 4 files changed, 406 insertions(+)
- create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
-
---- a/drivers/phy/mediatek/Kconfig
-+++ b/drivers/phy/mediatek/Kconfig
-@@ -13,6 +13,18 @@ config PHY_MTK_PCIE
- callback for PCIe GEN3 port, it supports software efuse
- initialization.
-
-+config PHY_MTK_XFI_TPHY
-+ tristate "MediaTek XFI T-PHY Driver"
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ depends on OF && OF_ADDRESS
-+ depends on HAS_IOMEM
-+ select GENERIC_PHY
-+ help
-+ Say 'Y' here to add support for MediaTek XFI T-PHY driver.
-+ The driver provides access to the Ethernet SerDes T-PHY supporting
-+ 1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
-+ via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
-+
- config PHY_MTK_TPHY
- tristate "MediaTek T-PHY Driver"
- depends on ARCH_MEDIATEK || COMPILE_TEST
---- a/drivers/phy/mediatek/Makefile
-+++ b/drivers/phy/mediatek/Makefile
-@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-p
- obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
- obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o
- obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o
-+obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o
-
- phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
- phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
---- /dev/null
-+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
-@@ -0,0 +1,393 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/* MediaTek 10GE SerDes PHY driver
-+ *
-+ * Copyright (c) 2024 Daniel Golle <daniel@makrotopia.org>
-+ * Bc-bocun Chen <bc-bocun.chen@mediatek.com>
-+ * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
-+ * Copyright (c) 2022 MediaTek Inc.
-+ * Author: Henry Yen <henry.yen@mediatek.com>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/io.h>
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <linux/phy.h>
-+#include <linux/phy/phy.h>
-+
-+#define MTK_XFI_TPHY_NUM_CLOCKS 2
-+
-+#define REG_DIG_GLB_70 0x0070
-+#define XTP_PCS_RX_EQ_IN_PROGRESS(x) FIELD_PREP(GENMASK(25, 24), (x))
-+#define XTP_PCS_MODE_MASK GENMASK(17, 16)
-+#define XTP_PCS_MODE(x) FIELD_PREP(GENMASK(17, 16), (x))
-+#define XTP_PCS_RST_B BIT(15)
-+#define XTP_FRC_PCS_RST_B BIT(14)
-+#define XTP_PCS_PWD_SYNC_MASK GENMASK(13, 12)
-+#define XTP_PCS_PWD_SYNC(x) FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
-+#define XTP_PCS_PWD_ASYNC_MASK GENMASK(11, 10)
-+#define XTP_PCS_PWD_ASYNC(x) FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
-+#define XTP_FRC_PCS_PWD_ASYNC BIT(8)
-+#define XTP_PCS_UPDT BIT(4)
-+#define XTP_PCS_IN_FR_RG BIT(0)
-+
-+#define REG_DIG_GLB_F4 0x00f4
-+#define XFI_DPHY_PCS_SEL BIT(0)
-+#define XFI_DPHY_PCS_SEL_SGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
-+#define XFI_DPHY_PCS_SEL_USXGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
-+#define XFI_DPHY_AD_SGDT_FRC_EN BIT(5)
-+
-+#define REG_DIG_LN_TRX_40 0x3040
-+#define XTP_LN_FRC_TX_DATA_EN BIT(29)
-+#define XTP_LN_TX_DATA_EN BIT(28)
-+
-+#define REG_DIG_LN_TRX_B0 0x30b0
-+#define XTP_LN_FRC_TX_MACCK_EN BIT(5)
-+#define XTP_LN_TX_MACCK_EN BIT(4)
-+
-+#define REG_ANA_GLB_D0 0x90d0
-+#define XTP_GLB_USXGMII_SEL_MASK GENMASK(3, 1)
-+#define XTP_GLB_USXGMII_SEL(x) FIELD_PREP(GENMASK(3, 1), (x))
-+#define XTP_GLB_USXGMII_EN BIT(0)
-+
-+struct mtk_xfi_tphy {
-+ void __iomem *base;
-+ struct device *dev;
-+ struct reset_control *reset;
-+ struct clk_bulk_data clocks[MTK_XFI_TPHY_NUM_CLOCKS];
-+ bool da_war;
-+};
-+
-+static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
-+ u32 value)
-+{
-+ iowrite32(value, xfi_tphy->base + reg);
-+}
-+
-+static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
-+ u32 clr, u32 set)
-+{
-+ u32 val;
-+
-+ val = ioread32(xfi_tphy->base + reg);
-+ val &= ~clr;
-+ val |= set;
-+ iowrite32(val, xfi_tphy->base + reg);
-+}
-+
-+static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
-+ u32 set)
-+{
-+ mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
-+}
-+
-+static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
-+ u32 clr)
-+{
-+ mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
-+}
-+
-+static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
-+ phy_interface_t interface)
-+{
-+ bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
-+ bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
-+ interface == PHY_INTERFACE_MODE_SGMII);
-+ bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
-+ interface == PHY_INTERFACE_MODE_USXGMII);
-+ bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
-+ bool is_xgmii = (is_10g || is_5g);
-+
-+ dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
-+
-+ /* Setup PLL setting */
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
-+ 0x140000);
-+
-+ /* Setup RXFE BW setting */
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
-+ is_5g ? 0x800 : 0x400);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
-+
-+ /* Setup RX CDR setting */
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
-+ 0x7000400);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
-+ 0x1000100);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
-+ is_5g ? 0x1010 : 0x0);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
-+ is_5g ? 0x30100 :
-+ 0x100);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
-+ is_5g ? 0x40000 :
-+ 0x20000);
-+
-+ /* Setting RXFE adaptation range setting */
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
-+ 0x6e0000);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
-+ if (is_10g)
-+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
-+ else if (is_5g)
-+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
-+ else if (is_2p5g)
-+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
-+ else
-+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
-+
-+ /* Force SGDT_OUT off and select PCS */
-+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4,
-+ XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
-+ XFI_DPHY_AD_SGDT_FRC_EN |
-+ (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII :
-+ XFI_DPHY_PCS_SEL_SGMII));
-+
-+
-+ /* Force GLB_CKDET_OUT */
-+ mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00);
-+
-+ /* Force AEQ on */
-+ mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70,
-+ XTP_PCS_RX_EQ_IN_PROGRESS(2) |
-+ XTP_PCS_PWD_SYNC(2) |
-+ XTP_PCS_PWD_ASYNC(2));
-+
-+ usleep_range(1, 5);
-+ writel(XTP_LN_FRC_TX_DATA_EN, xfi_tphy->base + REG_DIG_LN_TRX_40);
-+
-+ /* Setup TX DA default value */
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20);
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01);
-+ mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884);
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002);
-+
-+ /* Setup RG default value */
-+ if (is_xgmii) {
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220);
-+ mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01);
-+ mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600);
-+ if (interface == PHY_INTERFACE_MODE_USXGMII)
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
-+ else
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100);
-+ } else {
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110);
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
-+ }
-+
-+ if (is_1g)
-+ mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000);
-+
-+ /* Setup RX EQ initial value */
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000,
-+ (interface != PHY_INTERFACE_MODE_10GBASER) ?
-+ 0xa8000000 : 0x0);
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa,
-+ (interface != PHY_INTERFACE_MODE_10GBASER) ?
-+ 0xaa : 0x0);
-+
-+ if (is_xgmii)
-+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00);
-+ else if (is_2p5g)
-+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00);
-+ else
-+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00);
-+
-+ if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war)
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000);
-+
-+ mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 :
-+ 0x50000);
-+
-+ /* Setup PHYA speed */
-+ mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0,
-+ XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
-+ is_10g ? XTP_GLB_USXGMII_SEL(0) :
-+ is_5g ? XTP_GLB_USXGMII_SEL(1) :
-+ is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
-+ XTP_GLB_USXGMII_SEL(3));
-+ mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
-+
-+ /* Release reset */
-+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70,
-+ XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
-+ usleep_range(150, 500);
-+
-+ /* Switch to P0 */
-+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
-+ XTP_PCS_PWD_SYNC_MASK |
-+ XTP_PCS_PWD_ASYNC_MASK,
-+ XTP_FRC_PCS_PWD_ASYNC |
-+ XTP_PCS_UPDT | XTP_PCS_IN_FR_RG);
-+ usleep_range(1, 5);
-+
-+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
-+ usleep_range(15, 50);
-+
-+ if (is_xgmii) {
-+ /* Switch to Gen3 */
-+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
-+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
-+ XTP_PCS_MODE(2) | XTP_PCS_UPDT);
-+ } else {
-+ /* Switch to Gen2 */
-+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
-+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
-+ XTP_PCS_MODE(1) | XTP_PCS_UPDT);
-+ }
-+ usleep_range(1, 5);
-+
-+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
-+
-+ usleep_range(100, 500);
-+
-+ /* Enable MAC CK */
-+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
-+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
-+
-+ /* Enable TX data */
-+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40,
-+ XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
-+ usleep_range(400, 1000);
-+}
-+
-+static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
-+ submode)
-+{
-+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
-+
-+ if (mode != PHY_MODE_ETHERNET)
-+ return -EINVAL;
-+
-+ switch (submode) {
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_5GBASER:
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ mtk_xfi_tphy_setup(xfi_tphy, submode);
-+ return 0;
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int mtk_xfi_tphy_reset(struct phy *phy)
-+{
-+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
-+
-+ reset_control_assert(xfi_tphy->reset);
-+ usleep_range(100, 500);
-+ reset_control_deassert(xfi_tphy->reset);
-+ usleep_range(1, 10);
-+
-+ return 0;
-+}
-+
-+static int mtk_xfi_tphy_power_on(struct phy *phy)
-+{
-+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
-+
-+ return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
-+}
-+
-+static int mtk_xfi_tphy_power_off(struct phy *phy)
-+{
-+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
-+
-+ clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
-+
-+ return 0;
-+}
-+
-+static const struct phy_ops mtk_xfi_tphy_ops = {
-+ .power_on = mtk_xfi_tphy_power_on,
-+ .power_off = mtk_xfi_tphy_power_off,
-+ .set_mode = mtk_xfi_tphy_set_mode,
-+ .reset = mtk_xfi_tphy_reset,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int mtk_xfi_tphy_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct phy_provider *phy_provider;
-+ struct mtk_xfi_tphy *xfi_tphy;
-+ struct phy *phy;
-+
-+ if (!np)
-+ return -ENODEV;
-+
-+ xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
-+ if (!xfi_tphy)
-+ return -ENOMEM;
-+
-+ xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
-+ if (!xfi_tphy->base)
-+ return -EIO;
-+
-+ xfi_tphy->dev = &pdev->dev;
-+
-+ xfi_tphy->clocks[0].id = "topxtal";
-+ xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[0].id);
-+ if (IS_ERR(xfi_tphy->clocks[0].clk))
-+ return PTR_ERR(xfi_tphy->clocks[0].clk);
-+
-+ xfi_tphy->clocks[1].id = "xfipll";
-+ xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[1].id);
-+ if (IS_ERR(xfi_tphy->clocks[1].clk))
-+ return PTR_ERR(xfi_tphy->clocks[1].clk);
-+
-+ xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
-+ if (IS_ERR(xfi_tphy->reset))
-+ return PTR_ERR(xfi_tphy->reset);
-+
-+ xfi_tphy->da_war = of_property_read_bool(np,
-+ "mediatek,usxgmii-performance-errata");
-+
-+ phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
-+ if (IS_ERR(phy))
-+ return PTR_ERR(phy);
-+
-+ phy_set_drvdata(phy, xfi_tphy);
-+
-+ phy_provider = devm_of_phy_provider_register(&pdev->dev,
-+ of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct of_device_id mtk_xfi_tphy_match[] = {
-+ { .compatible = "mediatek,mt7988-xfi-tphy", },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
-+
-+static struct platform_driver mtk_xfi_tphy_driver = {
-+ .probe = mtk_xfi_tphy_probe,
-+ .driver = {
-+ .name = "mtk-xfi-tphy",
-+ .of_match_table = mtk_xfi_tphy_match,
-+ },
-+};
-+module_platform_driver(mtk_xfi_tphy_driver);
-+
-+MODULE_DESCRIPTION("MediaTek XFI T-PHY driver");
-+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
-+MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen@mediatek.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch b/target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch
deleted file mode 100644
index adb95e9587..0000000000
--- a/target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch
+++ /dev/null
@@ -1,371 +0,0 @@
-From 4b1a2716299c0e96a698044aebf3f80513509ae7 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 12 Dec 2023 03:47:18 +0000
-Subject: [PATCH 3/5] net: pcs: pcs-mtk-lynxi: add platform driver for MT7988
-
-Introduce a proper 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 <daniel@makrotopia.org>
----
- drivers/net/pcs/pcs-mtk-lynxi.c | 227 ++++++++++++++++++++++++++++--
- include/linux/pcs/pcs-mtk-lynxi.h | 11 ++
- 2 files changed, 227 insertions(+), 11 deletions(-)
-
---- 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 <sean.wang@mediatek.com>
- * Author: Alexander Couzens <lynxis@fe80.eu>
-@@ -8,11 +8,17 @@
- *
- */
-
-+#include <linux/clk.h>
- #include <linux/mdio.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/mutex.h>
- #include <linux/of.h>
-+#include <linux/of_platform.h>
- #include <linux/pcs/pcs-mtk-lynxi.h>
- #include <linux/phylink.h>
-+#include <linux/platform_device.h>
- #include <linux/regmap.h>
-+#include <linux/reset.h>
-
- /* SGMII subsystem config registers */
- /* BMCR (low 16) BMSR (high 16) */
-@@ -65,6 +71,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,15 +82,29 @@
- * @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;
-+ struct reset_control *rstc;
-+ struct clk *sgmii_sel;
-+ struct clk *sgmii_rx;
-+ struct clk *sgmii_tx;
-+ struct list_head node;
- };
-
-+static LIST_HEAD(mtk_pcs_lynxi_instances);
-+static DEFINE_MUTEX(instance_mutex);
-+
- static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
- {
- return container_of(pcs, struct mtk_pcs_lynxi, pcs);
-@@ -102,6 +124,17 @@ static void mtk_pcs_lynxi_get_state(stru
- 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,
-@@ -148,6 +181,7 @@ static int mtk_pcs_lynxi_config(struct p
- SGMII_PHYA_PWD);
-
- /* Reset SGMII PCS state */
-+ mtk_sgmii_reset(mpcs);
- regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
- SGMII_SW_RESET);
-
-@@ -234,10 +268,29 @@ static void mtk_pcs_lynxi_link_up(struct
- }
- }
-
-+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);
-+ }
-+
-+ 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;
- }
-
-@@ -247,11 +300,12 @@ static const struct phylink_pcs_ops mtk_
- .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;
-@@ -259,29 +313,33 @@ struct phylink_pcs *mtk_pcs_lynxi_create
-
- 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;
-@@ -292,6 +350,13 @@ struct phylink_pcs *mtk_pcs_lynxi_create
- mpcs->interface = PHY_INTERFACE_MODE_NA;
-
- 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);
-
-@@ -304,4 +369,144 @@ void mtk_pcs_lynxi_destroy(struct phylin
- }
- EXPORT_SYMBOL(mtk_pcs_lynxi_destroy);
-
-+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);
-+
-+ 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);
-+
-+ mutex_lock(&instance_mutex);
-+ list_add_tail(&mpcs->node, &mtk_pcs_lynxi_instances);
-+ mutex_unlock(&instance_mutex);
-+
-+ return 0;
-+}
-+
-+static int mtk_pcs_lynxi_remove(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct mtk_pcs_lynxi *cur, *tmp;
-+
-+ mutex_lock(&instance_mutex);
-+ list_for_each_entry_safe(cur, tmp, &mtk_pcs_lynxi_instances, node)
-+ if (cur->dev == dev) {
-+ list_del(&cur->node);
-+ kfree(cur);
-+ break;
-+ }
-+ mutex_unlock(&instance_mutex);
-+
-+ return 0;
-+}
-+
-+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);
-+
-+struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np)
-+{
-+ struct platform_device *pdev;
-+ struct mtk_pcs_lynxi *mpcs;
-+
-+ if (!np)
-+ return NULL;
-+
-+ if (!of_device_is_available(np))
-+ return ERR_PTR(-ENODEV);
-+
-+ if (!of_match_node(mtk_pcs_lynxi_of_match, np))
-+ return ERR_PTR(-EINVAL);
-+
-+ pdev = of_find_device_by_node(np);
-+ if (!pdev || !platform_get_drvdata(pdev)) {
-+ if (pdev)
-+ put_device(&pdev->dev);
-+ return ERR_PTR(-EPROBE_DEFER);
-+ }
-+
-+ mpcs = platform_get_drvdata(pdev);
-+ device_link_add(dev, mpcs->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
-+
-+ return &mpcs->pcs;
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_get);
-+
-+void mtk_pcs_lynxi_put(struct phylink_pcs *pcs)
-+{
-+ struct mtk_pcs_lynxi *cur, *mpcs = NULL;
-+
-+ if (!pcs)
-+ return;
-+
-+ mutex_lock(&instance_mutex);
-+ list_for_each_entry(cur, &mtk_pcs_lynxi_instances, node)
-+ if (pcs == &cur->pcs) {
-+ mpcs = cur;
-+ break;
-+ }
-+ mutex_unlock(&instance_mutex);
-+
-+ if (WARN_ON(!mpcs))
-+ return;
-+
-+ put_device(mpcs->dev);
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_put);
-+
-+static struct platform_driver mtk_pcs_lynxi_driver = {
-+ .driver = {
-+ .name = "mtk-pcs-lynxi",
-+ .suppress_bind_attrs = true,
-+ .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);
-+
-+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
-+MODULE_DESCRIPTION("MediaTek LynxI HSGMII PCS");
- MODULE_LICENSE("GPL");
---- a/include/linux/pcs/pcs-mtk-lynxi.h
-+++ b/include/linux/pcs/pcs-mtk-lynxi.h
-@@ -10,4 +10,15 @@ struct phylink_pcs *mtk_pcs_lynxi_create
- struct regmap *regmap,
- u32 ana_rgc3, u32 flags);
- void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
-+
-+#if IS_ENABLED(CONFIG_PCS_MTK_LYNXI)
-+struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np);
-+void mtk_pcs_lynxi_put(struct phylink_pcs *pcs);
-+#else
-+static inline struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np)
-+{
-+ return NULL;
-+}
-+static inline void mtk_pcs_lynxi_put(struct phylink_pcs *pcs) { }
-+#endif /* IS_ENABLED(CONFIG_PCS_MTK_LYNXI) */
- #endif
diff --git a/target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch b/target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch
deleted file mode 100644
index 215bd2ca2e..0000000000
--- a/target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 7d88d79c0f65b27a92754d7547f7af098b3de67b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 12 Dec 2023 03:47:31 +0000
-Subject: [PATCH 4/5] 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 <daniel@makrotopia.org>
----
- .../bindings/net/pcs/mediatek,usxgmii.yaml | 60 +++++++++++++++++++
- 1 file changed, 60 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
-
---- /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 <daniel@makrotopia.org>
-+
-+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 <dt-bindings/clock/mediatek,mt7988-clk.h>
-+ #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>;
-+ };
-+ };
diff --git a/target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch b/target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch
deleted file mode 100644
index fd1bba3089..0000000000
--- a/target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch
+++ /dev/null
@@ -1,547 +0,0 @@
-From dde0e95fff92e9f5009f3bea75278e0e34a48822 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 12 Dec 2023 03:47:47 +0000
-Subject: [PATCH 5/5] 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 <daniel@makrotopia.org>
----
- MAINTAINERS | 2 +
- drivers/net/pcs/Kconfig | 11 +
- drivers/net/pcs/Makefile | 1 +
- drivers/net/pcs/pcs-mtk-usxgmii.c | 456 ++++++++++++++++++++++++++++
- include/linux/pcs/pcs-mtk-usxgmii.h | 27 ++
- 5 files changed, 497 insertions(+)
- create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
- create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -12941,7 +12941,9 @@ M: Daniel Golle <daniel@makrotopia.org>
- 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 I2C CONTROLLER DRIVER
- M: Qii Wang <qii.wang@mediatek.com>
---- a/drivers/net/pcs/Kconfig
-+++ b/drivers/net/pcs/Kconfig
-@@ -18,6 +18,17 @@ config PCS_LYNX
- This module provides helpers to phylink for managing the Lynx PCS
- which is part of the Layerscape and QorIQ Ethernet SERDES.
-
-+config PCS_MTK_USXGMII
-+ tristate "MediaTek USXGMII 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)
---- a/drivers/net/pcs/Makefile
-+++ b/drivers/net/pcs/Makefile
-@@ -8,3 +8,4 @@ obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
- obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o
- obj-$(CONFIG_PCS_ALTERA_TSE) += pcs-altera-tse.o
- obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
-+obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o
---- /dev/null
-+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
-@@ -0,0 +1,456 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Henry Yen <henry.yen@mediatek.com>
-+ * Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/mdio.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/reset.h>
-+#include <linux/pcs/pcs-mtk-usxgmii.h>
-+#include <linux/platform_device.h>
-+
-+/* 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;
-+ phy_interface_t interface;
-+ unsigned int neg_mode;
-+ struct list_head node;
-+};
-+
-+static LIST_HEAD(mtk_usxgmii_pcs_instances);
-+static DEFINE_MUTEX(instance_mutex);
-+
-+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;
-+ }
-+
-+ 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);
-+
-+ 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,
-+ 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)
-+{
-+ /* 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);
-+}
-+
-+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;
-+}
-+
-+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
-+ .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_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->pcs.neg_mode = true;
-+ mpcs->interface = PHY_INTERFACE_MODE_NA;
-+ mpcs->neg_mode = -1;
-+
-+ mpcs->clk = devm_clk_get_enabled(mpcs->dev, NULL);
-+ if (IS_ERR(mpcs->clk))
-+ return PTR_ERR(mpcs->clk);
-+
-+ 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);
-+
-+ mutex_lock(&instance_mutex);
-+ list_add_tail(&mpcs->node, &mtk_usxgmii_pcs_instances);
-+ mutex_unlock(&instance_mutex);
-+
-+ return 0;
-+}
-+
-+static int mtk_usxgmii_remove(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct mtk_usxgmii_pcs *cur, *tmp;
-+
-+ mutex_lock(&instance_mutex);
-+ list_for_each_entry_safe(cur, tmp, &mtk_usxgmii_pcs_instances, node)
-+ if (cur->dev == dev) {
-+ list_del(&cur->node);
-+ break;
-+ }
-+ mutex_unlock(&instance_mutex);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mtk_usxgmii_of_mtable[] = {
-+ { .compatible = "mediatek,mt7988-usxgmiisys" },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable);
-+
-+struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np)
-+{
-+ struct platform_device *pdev;
-+ struct mtk_usxgmii_pcs *mpcs;
-+
-+ if (!np)
-+ return NULL;
-+
-+ if (!of_device_is_available(np))
-+ return ERR_PTR(-ENODEV);
-+
-+ if (!of_match_node(mtk_usxgmii_of_mtable, np))
-+ return ERR_PTR(-EINVAL);
-+
-+ pdev = of_find_device_by_node(np);
-+ if (!pdev || !platform_get_drvdata(pdev)) {
-+ if (pdev)
-+ put_device(&pdev->dev);
-+ return ERR_PTR(-EPROBE_DEFER);
-+ }
-+
-+ mpcs = platform_get_drvdata(pdev);
-+ device_link_add(dev, mpcs->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
-+
-+ return &mpcs->pcs;
-+}
-+EXPORT_SYMBOL(mtk_usxgmii_pcs_get);
-+
-+void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs)
-+{
-+ struct mtk_usxgmii_pcs *cur, *mpcs = NULL;
-+
-+ if (!pcs)
-+ return;
-+
-+ mutex_lock(&instance_mutex);
-+ list_for_each_entry(cur, &mtk_usxgmii_pcs_instances, node)
-+ if (pcs == &cur->pcs) {
-+ mpcs = cur;
-+ break;
-+ }
-+ mutex_unlock(&instance_mutex);
-+
-+ if (WARN_ON(!mpcs))
-+ return;
-+
-+ put_device(mpcs->dev);
-+}
-+EXPORT_SYMBOL(mtk_usxgmii_pcs_put);
-+
-+static struct platform_driver mtk_usxgmii_driver = {
-+ .driver = {
-+ .name = "mtk_usxgmii",
-+ .suppress_bind_attrs = true,
-+ .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 <daniel@makrotopia.org>");
---- /dev/null
-+++ b/include/linux/pcs/pcs-mtk-usxgmii.h
-@@ -0,0 +1,27 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __LINUX_PCS_MTK_USXGMII_H
-+#define __LINUX_PCS_MTK_USXGMII_H
-+
-+#include <linux/phylink.h>
-+
-+/**
-+ * mtk_usxgmii_select_pcs() - Get MediaTek PCS instance
-+ * @np: Pointer to device node indentifying a MediaTek USXGMII PCS
-+ * @mode: Ethernet PHY interface mode
-+ *
-+ * Return PCS identified by a device node and the PHY interface mode in use
-+ *
-+ * Return: Pointer to phylink PCS instance of NULL
-+ */
-+#if IS_ENABLED(CONFIG_PCS_MTK_USXGMII)
-+struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np);
-+void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs);
-+#else
-+static inline struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np)
-+{
-+ return NULL;
-+}
-+static inline void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs) { }
-+#endif /* IS_ENABLED(CONFIG_PCS_MTK_USXGMII) */
-+
-+#endif /* __LINUX_PCS_MTK_USXGMII_H */
diff --git a/target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch b/target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch
deleted file mode 100644
index 2a1f908cfb..0000000000
--- a/target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 6f291aa7da199c6486cc229b055dcbcd5cee7a21 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sun, 21 May 2023 22:24:56 +0200
-Subject: [PATCH] net: phy: motorcomm: Add missing include
-
-Directly include linux/bitfield.h which provides FIELD_PREP.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/net/phy/motorcomm.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -6,6 +6,7 @@
- * Author: Frank <Frank.Sae@motor-comm.com>
- */
-
-+#include <linux/bitfield.h>
- #include <linux/etherdevice.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
diff --git a/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch
deleted file mode 100644
index 249ba5c496..0000000000
--- a/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
-From: Jianhui Zhao <zhaojh329@gmail.com>
-Date: Sun, 24 Sep 2023 22:15:00 +0800
-Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
-
-This commit introduces interrupt support for RTL8221B.
-
-Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
----
- drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -982,6 +982,51 @@ static int rtl8221b_config_init(struct p
- return 0;
- }
-
-+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4);
-+
-+ return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8221b_config_intr(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff);
-+ } else {
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0);
-+ if (err)
-+ return err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ }
-+
-+ return err;
-+}
-+
-+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1142,6 +1187,8 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .config_intr = rtl8221b_config_intr,
-+ .handle_interrupt = rtl8221b_handle_interrupt,
- .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
diff --git a/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch b/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch
deleted file mode 100644
index 500567b4ed..0000000000
--- a/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 9be9a00adfac8118b6d685e71696f83187308c66 Mon Sep 17 00:00:00 2001
-Message-ID: <9be9a00adfac8118b6d685e71696f83187308c66.1715125851.git.daniel@makrotopia.org>
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 7 May 2024 22:43:30 +0100
-Subject: [PATCH net] net: phy: air_en8811h: reset netdev rules when LED is set
- manually
-To: Andrew Lunn <andrew@lunn.ch>,
- Heiner Kallweit <hkallweit1@gmail.com>,
- Russell King <linux@armlinux.org.uk>,
- David S. Miller <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- SkyLake Huang <skylake.huang@mediatek.com>,
- Eric Woudstra <ericwouds@gmail.com>,
- netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org
-
-Setting LED_OFF via the brightness_set should deactivate hw control,
-so make sure netdev trigger rules also get cleared in that case.
-
-Fixes: 71e79430117d ("net: phy: air_en8811h: Add the Airoha EN8811H PHY driver")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-This is basically a stop-gap measure until unified LED handling has
-been implemented accross all MediaTek and Airoha PHYs.
-See also
-https://patchwork.kernel.org/project/netdevbpf/patch/20240425023325.15586-3-SkyLake.Huang@mediatek.com/
-
- drivers/net/phy/air_en8811h.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/phy/air_en8811h.c
-+++ b/drivers/net/phy/air_en8811h.c
-@@ -544,6 +544,10 @@ static int air_hw_led_on_set(struct phy_
-
- changed |= (priv->led[index].rules != 0);
-
-+ /* clear netdev trigger rules in case LED_OFF has been set */
-+ if (!on)
-+ priv->led[index].rules = 0;
-+
- if (changed)
- return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
- AIR_PHY_LED_ON(index),
diff --git a/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch
deleted file mode 100644
index 7d5727bda6..0000000000
--- a/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 16 Feb 2023 18:39:04 +0100
-Subject: [PATCH] net/core: add optional threading for backlog processing
-
-When dealing with few flows or an imbalance on CPU utilization, static RPS
-CPU assignment can be too inflexible. Add support for enabling threaded NAPI
-for backlog processing in order to allow the scheduler to better balance
-processing. This helps better spread the load across idle CPUs.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -543,6 +543,7 @@ static inline bool napi_complete(struct
- }
-
- int dev_set_threaded(struct net_device *dev, bool threaded);
-+int backlog_set_threaded(bool threaded);
-
- /**
- * napi_disable - prevent NAPI from scheduling
-@@ -3150,6 +3151,7 @@ struct softnet_data {
- unsigned int processed;
- unsigned int time_squeeze;
- unsigned int received_rps;
-+ unsigned int process_queue_empty;
- #ifdef CONFIG_RPS
- struct softnet_data *rps_ipi_list;
- #endif
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -4625,7 +4625,7 @@ static int napi_schedule_rps(struct soft
- struct softnet_data *mysd = this_cpu_ptr(&softnet_data);
-
- #ifdef CONFIG_RPS
-- if (sd != mysd) {
-+ if (sd != mysd && !test_bit(NAPI_STATE_THREADED, &sd->backlog.state)) {
- sd->rps_ipi_next = mysd->rps_ipi_list;
- mysd->rps_ipi_list = sd;
-
-@@ -5806,6 +5806,8 @@ static DEFINE_PER_CPU(struct work_struct
- /* Network device is going away, flush any packets still pending */
- static void flush_backlog(struct work_struct *work)
- {
-+ unsigned int process_queue_empty;
-+ bool threaded, flush_processq;
- struct sk_buff *skb, *tmp;
- struct softnet_data *sd;
-
-@@ -5820,8 +5822,17 @@ static void flush_backlog(struct work_st
- input_queue_head_incr(sd);
- }
- }
-+
-+ threaded = test_bit(NAPI_STATE_THREADED, &sd->backlog.state);
-+ flush_processq = threaded &&
-+ !skb_queue_empty_lockless(&sd->process_queue);
-+ if (flush_processq)
-+ process_queue_empty = sd->process_queue_empty;
- rps_unlock_irq_enable(sd);
-
-+ if (threaded)
-+ goto out;
-+
- skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
- if (skb->dev->reg_state == NETREG_UNREGISTERING) {
- __skb_unlink(skb, &sd->process_queue);
-@@ -5829,7 +5840,16 @@ static void flush_backlog(struct work_st
- input_queue_head_incr(sd);
- }
- }
-+
-+out:
- local_bh_enable();
-+
-+ while (flush_processq) {
-+ msleep(1);
-+ rps_lock_irq_disable(sd);
-+ flush_processq = process_queue_empty == sd->process_queue_empty;
-+ rps_unlock_irq_enable(sd);
-+ }
- }
-
- static bool flush_required(int cpu)
-@@ -5961,6 +5981,7 @@ static int process_backlog(struct napi_s
- }
-
- rps_lock_irq_disable(sd);
-+ sd->process_queue_empty++;
- if (skb_queue_empty(&sd->input_pkt_queue)) {
- /*
- * Inline a custom version of __napi_complete().
-@@ -5970,7 +5991,8 @@ static int process_backlog(struct napi_s
- * We can use a plain write instead of clear_bit(),
- * and we dont need an smp_mb() memory barrier.
- */
-- napi->state = 0;
-+ napi->state &= ~(NAPIF_STATE_SCHED |
-+ NAPIF_STATE_SCHED_THREADED);
- again = false;
- } else {
- skb_queue_splice_tail_init(&sd->input_pkt_queue,
-@@ -6386,6 +6408,55 @@ int dev_set_threaded(struct net_device *
- }
- EXPORT_SYMBOL(dev_set_threaded);
-
-+int backlog_set_threaded(bool threaded)
-+{
-+ static bool backlog_threaded;
-+ int err = 0;
-+ int i;
-+
-+ if (backlog_threaded == threaded)
-+ return 0;
-+
-+ for_each_possible_cpu(i) {
-+ struct softnet_data *sd = &per_cpu(softnet_data, i);
-+ struct napi_struct *n = &sd->backlog;
-+
-+ if (n->thread)
-+ continue;
-+ n->thread = kthread_run(napi_threaded_poll, n, "napi/backlog-%d", i);
-+ if (IS_ERR(n->thread)) {
-+ err = PTR_ERR(n->thread);
-+ pr_err("kthread_run failed with err %d\n", err);
-+ n->thread = NULL;
-+ threaded = false;
-+ break;
-+ }
-+
-+ }
-+
-+ backlog_threaded = threaded;
-+
-+ /* Make sure kthread is created before THREADED bit
-+ * is set.
-+ */
-+ smp_mb__before_atomic();
-+
-+ for_each_possible_cpu(i) {
-+ struct softnet_data *sd = &per_cpu(softnet_data, i);
-+ struct napi_struct *n = &sd->backlog;
-+ unsigned long flags;
-+
-+ rps_lock_irqsave(sd, &flags);
-+ if (threaded)
-+ n->state |= NAPIF_STATE_THREADED;
-+ else
-+ n->state &= ~NAPIF_STATE_THREADED;
-+ rps_unlock_irq_restore(sd, &flags);
-+ }
-+
-+ return err;
-+}
-+
- void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi,
- int (*poll)(struct napi_struct *, int), int weight)
- {
-@@ -11127,6 +11198,9 @@ static int dev_cpu_dead(unsigned int old
- raise_softirq_irqoff(NET_TX_SOFTIRQ);
- local_irq_enable();
-
-+ if (test_bit(NAPI_STATE_THREADED, &oldsd->backlog.state))
-+ return 0;
-+
- #ifdef CONFIG_RPS
- remsd = oldsd->rps_ipi_list;
- oldsd->rps_ipi_list = NULL;
-@@ -11439,6 +11513,7 @@ static int __init net_dev_init(void)
- INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd);
- spin_lock_init(&sd->defer_lock);
-
-+ INIT_LIST_HEAD(&sd->backlog.poll_list);
- init_gro_hash(&sd->backlog);
- sd->backlog.poll = process_backlog;
- sd->backlog.weight = weight_p;
---- a/net/core/sysctl_net_core.c
-+++ b/net/core/sysctl_net_core.c
-@@ -30,6 +30,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF;
- static int min_rcvbuf = SOCK_MIN_RCVBUF;
- static int max_skb_frags = MAX_SKB_FRAGS;
- static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE;
-+static int backlog_threaded;
-
- static int net_msg_warn; /* Unused, but still a sysctl */
-
-@@ -113,6 +114,23 @@ static int rps_sock_flow_sysctl(struct c
- }
- #endif /* CONFIG_RPS */
-
-+static int backlog_threaded_sysctl(struct ctl_table *table, int write,
-+ void *buffer, size_t *lenp, loff_t *ppos)
-+{
-+ static DEFINE_MUTEX(backlog_threaded_mutex);
-+ int ret;
-+
-+ mutex_lock(&backlog_threaded_mutex);
-+
-+ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
-+ if (write && !ret)
-+ ret = backlog_set_threaded(backlog_threaded);
-+
-+ mutex_unlock(&backlog_threaded_mutex);
-+
-+ return ret;
-+}
-+
- #ifdef CONFIG_NET_FLOW_LIMIT
- static DEFINE_MUTEX(flow_limit_update_mutex);
-
-@@ -482,6 +500,15 @@ static struct ctl_table net_core_table[]
- .proc_handler = rps_sock_flow_sysctl
- },
- #endif
-+ {
-+ .procname = "backlog_threaded",
-+ .data = &backlog_threaded,
-+ .maxlen = sizeof(unsigned int),
-+ .mode = 0644,
-+ .proc_handler = backlog_threaded_sysctl,
-+ .extra1 = SYSCTL_ZERO,
-+ .extra2 = SYSCTL_ONE
-+ },
- #ifdef CONFIG_NET_FLOW_LIMIT
- {
- .procname = "flow_limit_cpu_bitmap",
diff --git a/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
deleted file mode 100644
index 13a4d190ee..0000000000
--- a/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Tobias Waldekranz <tobias@waldekranz.com>
-Subject: [RFC net-next 7/7] net: dsa: mv88e6xxx: Request assisted learning on CPU port
-Date: Sat, 16 Jan 2021 02:25:15 +0100
-Archived-At: <https://lore.kernel.org/netdev/20210116012515.3152-8-tobias@waldekranz.com/>
-
-While the hardware is capable of performing learning on the CPU port,
-it requires alot of additions to the bridge's forwarding path in order
-to handle multi-destination traffic correctly.
-
-Until that is in place, opt for the next best thing and let DSA sync
-the relevant addresses down to the hardware FDB.
-
-Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -7079,6 +7079,7 @@ static int mv88e6xxx_register_switch(str
- ds->ops = &mv88e6xxx_switch_ops;
- ds->ageing_time_min = chip->info->age_time_coeff;
- ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
-+ ds->assisted_learning_on_cpu_port = true;
-
- /* Some chips support up to 32, but that requires enabling the
- * 5-bit port mode, which we do not support. 640k^W16 ought to
diff --git a/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch b/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch
deleted file mode 100644
index 23859816fa..0000000000
--- a/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From patchwork Sun Mar 19 22:08:05 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13180645
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id A7A46C6FD1F
- for <netdev@archiver.kernel.org>; Sun, 19 Mar 2023 22:08:15 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230223AbjCSWIN (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Sun, 19 Mar 2023 18:08:13 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32878 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S229565AbjCSWIM (ORCPT
- <rfc822;netdev@vger.kernel.org>); Sun, 19 Mar 2023 18:08:12 -0400
-Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com
- [IPv6:2a00:1450:4864:20::42e])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 605D3E062;
- Sun, 19 Mar 2023 15:08:10 -0700 (PDT)
-Received: by mail-wr1-x42e.google.com with SMTP id h17so8695188wrt.8;
- Sun, 19 Mar 2023 15:08:10 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679263689;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=;
- b=PSdrywW48P4Lq8z9wOSPXFB/ZdO/JfuyiGlw3Gz1Iriy+Smo/cBnJ0Ve9zKkX3AKTO
- Tr7/g8xhSQX8sU5WAOEPC13uVjKpO4VZsamXHTmMKL4mmfII3K/piAsQcMQkkNpgouab
- Ci9yr+7ASSmqEUHIbYTM6sl6a47rPwqk3b3DcTIE2CwJsPPNXnpQ/aSVbJAcEdhcZICc
- X4rAmjrYjcsl8coFIGHHPlrMH9ShekQWxB84vEb6bO1nXOORNPizOHuY1vJ3wa3WgXsx
- YwlvutMFVIUXfgL2ZwCmQAKWJPiAaFk+CCk3oxSeOYoAzkjcbMyapz9VnooStfvR2aV3
- k+2g==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679263689;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=;
- b=NGjqrGERyaxRwINtevHaY97h9X9W+1UY62YYwotqwv5+cfvB8myjBbD3WH2WzaqMes
- o9MMER9RE8/arW3jIVlBv4ORDUuEZ7AeGgy5UbFyQZIPHlp+hJ/sxFrGvYUwamg4Qrr9
- ojargh8ORsEiMeqaf+5AkmEagNhrrV3ax0pUuWDzbJ3vXGoHjfCetHz5xyNL46dvXBfb
- l/OZqjv9IYob552uUoUmCy/TbEQDqvmjkFrROFK9gtBNxgxUJkwbyiWIOVsf6RR8OarP
- f7bbvSJYkvTvzx2u/g0Up7NW5ZyihMGBmDs377M3yW6AnSxW6jlfl30QmMU1aEigYXvy
- v3mA==
-X-Gm-Message-State: AO0yUKUm1PYmYa4xlHuVD23mZcZm83a+xbhcbs0Xryi3yF/+UnjM4Cho
- GAfqSh5MZ/rlOAm3Vnpn//9hOG5Lc8vLYg==
-X-Google-Smtp-Source:
- AK7set+5pTahGGgk1hF/mHGkGBhsMf0//oQjZd4QFHx+HaeSgP5f6q7g0bRUcTX8kRtgHH0T7l1/hQ==
-X-Received: by 2002:a5d:474f:0:b0:2d6:2ae8:70d with SMTP id
- o15-20020a5d474f000000b002d62ae8070dmr2382593wrs.39.1679263688549;
- Sun, 19 Mar 2023 15:08:08 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- d6-20020a5d6dc6000000b002c53f6c7599sm7354727wrz.29.2023.03.19.15.08.07
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Sun, 19 Mar 2023 15:08:07 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2] net: dsa: b53: add support for BCM63xx RGMIIs
-Date: Sun, 19 Mar 2023 23:08:05 +0100
-Message-Id: <20230319220805.124024-1-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230319183330.761251-1-noltari@gmail.com>
-References: <20230319183330.761251-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM63xx RGMII ports require additional configuration in order to work.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
----
- v2: add changes suggested by Andrew:
- - Use a switch statement.
- - Use dev_dbg() instead of dev_info().
-
- drivers/net/dsa/b53/b53_common.c | 46 ++++++++++++++++++++++++++++++++
- drivers/net/dsa/b53/b53_priv.h | 1 +
- 2 files changed, 47 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1209,6 +1209,46 @@ static void b53_force_port_config(struct
- b53_write8(dev, B53_CTRL_PAGE, off, reg);
- }
-
-+static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port,
-+ phy_interface_t interface)
-+{
-+ struct b53_device *dev = ds->priv;
-+ u8 rgmii_ctrl = 0, off;
-+
-+ if (port == dev->imp_port)
-+ off = B53_RGMII_CTRL_IMP;
-+ else
-+ off = B53_RGMII_CTRL_P(port);
-+
-+ b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
-+
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC);
-+ rgmii_ctrl |= RGMII_CTRL_DLL_RXC;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC);
-+ rgmii_ctrl |= RGMII_CTRL_DLL_TXC;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII:
-+ default:
-+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
-+ break;
-+ }
-+
-+ if (port != dev->imp_port)
-+ rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
-+
-+ b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
-+
-+ dev_dbg(ds->dev, "Configured port %d for %s\n", port,
-+ phy_modes(interface));
-+}
-+
- static void b53_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev)
- {
-@@ -1235,6 +1275,9 @@ static void b53_adjust_link(struct dsa_s
- tx_pause, rx_pause);
- b53_force_link(dev, port, phydev->link);
-
-+ if (is63xx(dev) && port >= B53_63XX_RGMII0)
-+ b53_adjust_63xx_rgmii(ds, port, phydev->interface);
-+
- if (is531x5(dev) && phy_interface_is_rgmii(phydev)) {
- if (port == dev->imp_port)
- off = B53_RGMII_CTRL_IMP;
-@@ -1402,6 +1445,9 @@ void b53_phylink_mac_link_up(struct dsa_
- {
- struct b53_device *dev = ds->priv;
-
-+ if (is63xx(dev) && port >= B53_63XX_RGMII0)
-+ b53_adjust_63xx_rgmii(ds, port, interface);
-+
- if (mode == MLO_AN_PHY)
- return;
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -211,6 +211,7 @@ static inline int is58xx(struct b53_devi
- dev->chip_id == BCM7278_DEVICE_ID;
- }
-
-+#define B53_63XX_RGMII0 4
- #define B53_CPU_PORT_25 5
- #define B53_CPU_PORT 8
-
diff --git a/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch b/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch
deleted file mode 100644
index 8ab701ef56..0000000000
--- a/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From patchwork Tue Mar 21 17:33:57 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13183003
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 823A1C761AF
- for <netdev@archiver.kernel.org>; Tue, 21 Mar 2023 17:35:06 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230490AbjCURfE (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Tue, 21 Mar 2023 13:35:04 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47440 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230357AbjCURex (ORCPT
- <rfc822;netdev@vger.kernel.org>); Tue, 21 Mar 2023 13:34:53 -0400
-Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com
- [IPv6:2a00:1450:4864:20::430])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9A45559D8;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-Received: by mail-wr1-x430.google.com with SMTP id m2so14547588wrh.6;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679420063;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=;
- b=F0pa8JmQZ1FeXVtdpCygur8UmLrgKwxCcjaMn312u5zNvsXsEPeCAIDqP2tvNNTwv/
- UYjaNaoZ77HSvv/gSqeG808AXGyNs1PvLuHZYuUTJRNuLaMixKtkNFi4ypheCdk0WCiE
- IWz0DIm6ojmdwMqafDUKQ6Qwkv5R0vo8Wh5vpjimEmCelOyMvfuLZNqubsiGqpnCguBp
- uWlmKh95/VubCGgiGG2xK1IXQayL14ENuWseDds7nVpVK50NycrFgJbL17Bd6qJKYkbo
- m70IC+9jM0hjwKXpyi6ipCBNcW+1E6JIwILVC04Xi+BTpOGhbUAQ59Yn2hyq7tQM7dzs
- 4PLg==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679420063;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=;
- b=SCX78yTuGjdnE5nuL0p7+kxGnOzsCExsigLdaV+x/JswmwxSpZvxn223i1yM95klj9
- Rk0RnXqATLF1wZA7L1YmbeZ66zxUwW/osnCjJHPeEF8AGgjK/qawtLl/HJQHN67NaRNQ
- bDsRn2nWQ2GRTRFpvD+iGRy4uyQCDu9HFxLbn43fBsBmRnXWGPQP5cEb90tL83/Onp4D
- Lx/XcyZOh9QRfJNhj+G1BAeRCLRA/sdA0W3Ecu5SCFs+LtS6uvLVGWDKEDfnZhYY8Xqf
- Mx9evWzdW2OorEN2FI6+xTglvnEBcVhHIJ7XEGAhCG6ocgMZeck++774S8RWumWl8xpy
- /K9Q==
-X-Gm-Message-State: AO0yUKUORAlGfbkNwnYmQnTWcGPqW6sp4g9WfgQmRZGCV+9tCB0OebSP
- ICq6v4YPmUPNRl/WNnVCbps=
-X-Google-Smtp-Source:
- AK7set8pFDl8fHRwGPhAguqxIfqnQ4PY+b57IHEsybIaQ/HPNwdJ1cs1+IPBGHe3TL14dTS4aVNpHA==
-X-Received: by 2002:a5d:6991:0:b0:2ce:aab5:f96b with SMTP id
- g17-20020a5d6991000000b002ceaab5f96bmr2965175wru.67.1679420062764;
- Tue, 21 Mar 2023 10:34:22 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.21
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Tue, 21 Mar 2023 10:34:21 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2 2/4] net: dsa: b53: mmap: add more 63xx SoCs
-Date: Tue, 21 Mar 2023 18:33:57 +0100
-Message-Id: <20230321173359.251778-3-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230321173359.251778-1-noltari@gmail.com>
-References: <20230320155024.164523-1-noltari@gmail.com>
- <20230321173359.251778-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM6318, BCM6362 and BCM63268 are SoCs with a B53 MMAP switch.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
----
- v2: no changes.
-
- drivers/net/dsa/b53/b53_mmap.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -345,8 +345,11 @@ static void b53_mmap_shutdown(struct pla
-
- static const struct of_device_id b53_mmap_of_table[] = {
- { .compatible = "brcm,bcm3384-switch" },
-+ { .compatible = "brcm,bcm6318-switch" },
- { .compatible = "brcm,bcm6328-switch" },
-+ { .compatible = "brcm,bcm6362-switch" },
- { .compatible = "brcm,bcm6368-switch" },
-+ { .compatible = "brcm,bcm63268-switch" },
- { .compatible = "brcm,bcm63xx-switch" },
- { /* sentinel */ },
- };
diff --git a/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch b/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch
deleted file mode 100644
index de237374af..0000000000
--- a/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch
+++ /dev/null
@@ -1,195 +0,0 @@
-From patchwork Tue Mar 21 17:33:58 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13183004
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id B2B12C74A5B
- for <netdev@archiver.kernel.org>; Tue, 21 Mar 2023 17:35:12 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S230297AbjCURfK (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Tue, 21 Mar 2023 13:35:10 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47438 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230374AbjCURex (ORCPT
- <rfc822;netdev@vger.kernel.org>); Tue, 21 Mar 2023 13:34:53 -0400
-Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com
- [IPv6:2a00:1450:4864:20::432])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C906B5550A;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-Received: by mail-wr1-x432.google.com with SMTP id y14so14546846wrq.4;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679420064;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=;
- b=eFv+mwe94Y2YZMiJP5gydXVrGlbIAR5HCrY0rdcoGoMPzQUHLFckZeYCgEKudI55I7
- gMLZYCtLwvDXvKeHM2AUigsq2YuJSeF5QwICPrhTnMwUGBg4yyyltrc3+J0lSd6/4kQv
- h0yM1Oo4v0d8CuqjBU6bXienIk34AFVJfsPq+vWQTjAbUL7ht4WHZ2Ez2MFoTvZpkIJA
- 5iWMyVoMbugZl6eqNRjvDHFmtBtrZIv8AFs10r2Ca6+Yxm+aq0v33DRkbSVVqgFPNEzy
- q5QOXOeLBPL6BvyovOpmVSWGoHf1zFV7lrzcqi+uc+FuYxQ9dyN3ND73DrrhWSkLaSg9
- r8yA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679420064;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=;
- b=jIRB8pIlrLA/ovhnEoePs/6SX8fn6l7l4fY2CxX2pLrTbP1JI8AAetPavvrNVQTr2M
- Vm0iLbKyL/VpTq9+bSN1SMjaoi4lAMj0pgafoHrwABMVZpFauYvtCfSYTstZ2pw4Dr1j
- wYQGj3BUSpFIYHtSIDMkb5449WA3T3TONhaQLRFAUCBD6gAFyEky5fY+DIHrGaj352B6
- 9ST/tkqHgPpuFlmromr42KQWoTFU+Pj0Uhyp7ru4BsnF7tTshWroZZIHUJmSACudEadr
- fBPiuurX9jgp9zNqj8Oy0HjiVUnULFCapj8yICGp5s44uDAK/XFqFXpOuJ8ptS6uPazU
- xUwg==
-X-Gm-Message-State: AO0yUKX2w6QZfaGDHtlZAlY/U8F8VuJa3HwlgXbxgGChgdgvIoFThawv
- oDyFAhWbVfe4DxwXTwxgJ/I=
-X-Google-Smtp-Source:
- AK7set+sH60XiJYup7bqrZTzFJVNe1YGcX/UTfjWV9xfGwNyodc34cHvKpqNagw5J+vEpv6CKvNHaA==
-X-Received: by 2002:adf:f344:0:b0:2cd:de25:1c76 with SMTP id
- e4-20020adff344000000b002cdde251c76mr12989754wrp.17.1679420064464;
- Tue, 21 Mar 2023 10:34:24 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.22
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Tue, 21 Mar 2023 10:34:23 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2 3/4] net: dsa: b53: mmap: allow passing a chip ID
-Date: Tue, 21 Mar 2023 18:33:58 +0100
-Message-Id: <20230321173359.251778-4-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230321173359.251778-1-noltari@gmail.com>
-References: <20230320155024.164523-1-noltari@gmail.com>
- <20230321173359.251778-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM6318 and BCM63268 SoCs require a special handling for their RGMIIs, so we
-should be able to identify them as a special BCM63xx switch.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- v2:
- - Add missing chip to b53_switch_chips[].
- - Fix device_get_match_data() casting warning.
- - Add BCM63268_DEVICE_ID to BCM6318 too.
- - Add BCM6318 in commit description.
-
- drivers/net/dsa/b53/b53_common.c | 13 +++++++++++++
- drivers/net/dsa/b53/b53_mmap.c | 32 +++++++++++++++++++++++---------
- drivers/net/dsa/b53/b53_priv.h | 9 ++++++++-
- 3 files changed, 44 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2466,6 +2466,19 @@ static const struct b53_chip_data b53_sw
- .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
- },
- {
-+ .chip_id = BCM63268_DEVICE_ID,
-+ .dev_name = "BCM63268",
-+ .vlans = 4096,
-+ .enabled_ports = 0, /* pdata must provide them */
-+ .arl_bins = 4,
-+ .arl_buckets = 1024,
-+ .imp_port = 8,
-+ .vta_regs = B53_VTA_REGS_63XX,
-+ .duplex_reg = B53_DUPLEX_STAT_63XX,
-+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
-+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
-+ },
-+ {
- .chip_id = BCM53010_DEVICE_ID,
- .dev_name = "BCM53010",
- .vlans = 4096,
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -262,7 +262,7 @@ static int b53_mmap_probe_of(struct plat
- return -ENOMEM;
-
- pdata->regs = mem;
-- pdata->chip_id = BCM63XX_DEVICE_ID;
-+ pdata->chip_id = (u32)(unsigned long)device_get_match_data(dev);
- pdata->big_endian = of_property_read_bool(np, "big-endian");
-
- of_ports = of_get_child_by_name(np, "ports");
-@@ -344,14 +344,28 @@ static void b53_mmap_shutdown(struct pla
- }
-
- static const struct of_device_id b53_mmap_of_table[] = {
-- { .compatible = "brcm,bcm3384-switch" },
-- { .compatible = "brcm,bcm6318-switch" },
-- { .compatible = "brcm,bcm6328-switch" },
-- { .compatible = "brcm,bcm6362-switch" },
-- { .compatible = "brcm,bcm6368-switch" },
-- { .compatible = "brcm,bcm63268-switch" },
-- { .compatible = "brcm,bcm63xx-switch" },
-- { /* sentinel */ },
-+ {
-+ .compatible = "brcm,bcm3384-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6318-switch",
-+ .data = (void *)BCM63268_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6328-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6362-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm6368-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm63268-switch",
-+ .data = (void *)BCM63268_DEVICE_ID,
-+ }, {
-+ .compatible = "brcm,bcm63xx-switch",
-+ .data = (void *)BCM63XX_DEVICE_ID,
-+ }, { /* sentinel */ }
- };
- MODULE_DEVICE_TABLE(of, b53_mmap_of_table);
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -70,6 +70,7 @@ enum {
- BCM53125_DEVICE_ID = 0x53125,
- BCM53128_DEVICE_ID = 0x53128,
- BCM63XX_DEVICE_ID = 0x6300,
-+ BCM63268_DEVICE_ID = 0x63268,
- BCM53010_DEVICE_ID = 0x53010,
- BCM53011_DEVICE_ID = 0x53011,
- BCM53012_DEVICE_ID = 0x53012,
-@@ -191,7 +192,13 @@ static inline int is531x5(struct b53_dev
-
- static inline int is63xx(struct b53_device *dev)
- {
-- return dev->chip_id == BCM63XX_DEVICE_ID;
-+ return dev->chip_id == BCM63XX_DEVICE_ID ||
-+ dev->chip_id == BCM63268_DEVICE_ID;
-+}
-+
-+static inline int is63268(struct b53_device *dev)
-+{
-+ return dev->chip_id == BCM63268_DEVICE_ID;
- }
-
- static inline int is5301x(struct b53_device *dev)
diff --git a/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch b/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch
deleted file mode 100644
index d90d757fb2..0000000000
--- a/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From patchwork Tue Mar 21 17:33:59 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13183005
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 31BE4C761A6
- for <netdev@archiver.kernel.org>; Tue, 21 Mar 2023 17:35:16 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S229674AbjCURfN (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Tue, 21 Mar 2023 13:35:13 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47684 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S230327AbjCURfB (ORCPT
- <rfc822;netdev@vger.kernel.org>); Tue, 21 Mar 2023 13:35:01 -0400
-Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com
- [IPv6:2a00:1450:4864:20::436])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1D855507D;
- Tue, 21 Mar 2023 10:34:27 -0700 (PDT)
-Received: by mail-wr1-x436.google.com with SMTP id i9so14537769wrp.3;
- Tue, 21 Mar 2023 10:34:27 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679420066;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=;
- b=Cqj2C6aG5vEOlhh9N3ybvDA0CV38nhQODnfdnr7utNddd323iDagoJty1Wmi3MAzj1
- 5ORmYT5fQvUnild7C4RhcCNTBn+MoYZ+wDZwZYelu6BKHkW11YFK949ax5B50by+ASR2
- z+rGI3wR5fVXd4VDgmcsT6zF5x69wKyhbhqIfrhG9BVFTctfaBgDS/l+bX1C56kSqv82
- bQkKSSAehSLGpFoCU3q62OGoZVi3jDe6HDb5M1Dp2mgHhqsW19otZpJ57DjtZ1CmtPai
- o7T/ew6WoIYSl6whBmV36jeNaDJ3TItOBrKc4nMJBDWaCg4DNzUSe0ei5Xz7Oik5lb3p
- y9ew==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679420066;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=;
- b=UdI2iQNBYwRf40ivf3ROR132t95BU/p3RUzXdZLCyz6c6JWtECQ5byyGeEwoX10n5u
- HlepoNTJxMFLYrAHGvNLDPpWPuLXMa645S1mCVZ7NyWp8W96XzSynNZPeXHuJdb464QU
- A7UTRSW3mlvKe9OR3EcB2CfBZv0yHWR0ldbnxcxGUFw8z78PNqpOVnITtjBdfpGesJ9c
- VJw+fiM6hCcahor4nk9LLcAryPm8xmhDLxBKaLILO8wyTUiHY8G9hsXnFCtcpetnF5wS
- pW13beAE+odb7ZZaXZUYpWGYhCe/hLzNjbo8YpgzHwadZthxPrT5YvNIYwyrvoViLM0n
- KDRQ==
-X-Gm-Message-State: AO0yUKW+9H/kqcAUyWeZhZJhiJjsBcYn1THmZaSDrPrk/pNuGXJXGtJd
- NgsGZW8iSqLEv81yK+U5Os8=
-X-Google-Smtp-Source:
- AK7set/lzQZwCSxVaOe5dZ+7TR3xaQty/vg5xvZDpRW8TwTiPQblIbw5kJJTPLp67RySehrPIlCqSg==
-X-Received: by 2002:a5d:65c9:0:b0:2ce:ac31:54ff with SMTP id
- e9-20020a5d65c9000000b002ceac3154ffmr2776515wrw.2.1679420066191;
- Tue, 21 Mar 2023 10:34:26 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.24
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Tue, 21 Mar 2023 10:34:25 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch,
- olteanv@gmail.com, davem@davemloft.net, edumazet@google.com,
- kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>,
- Simon Horman <simon.horman@corigine.com>
-Subject: [PATCH v2 4/4] net: dsa: b53: add BCM63268 RGMII configuration
-Date: Tue, 21 Mar 2023 18:33:59 +0100
-Message-Id: <20230321173359.251778-5-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230321173359.251778-1-noltari@gmail.com>
-References: <20230320155024.164523-1-noltari@gmail.com>
- <20230321173359.251778-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-BCM63268 requires special RGMII configuration to work.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
----
- v2: no changes.
-
- drivers/net/dsa/b53/b53_common.c | 6 +++++-
- drivers/net/dsa/b53/b53_regs.h | 1 +
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1240,8 +1240,12 @@ static void b53_adjust_63xx_rgmii(struct
- break;
- }
-
-- if (port != dev->imp_port)
-+ if (port != dev->imp_port) {
-+ if (is63268(dev))
-+ rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
-+
- rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
-+ }
-
- b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
-
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -138,6 +138,7 @@
-
- #define B53_RGMII_CTRL_IMP 0x60
- #define RGMII_CTRL_ENABLE_GMII BIT(7)
-+#define RGMII_CTRL_MII_OVERRIDE BIT(6)
- #define RGMII_CTRL_TIMING_SEL BIT(2)
- #define RGMII_CTRL_DLL_RXC BIT(1)
- #define RGMII_CTRL_DLL_TXC BIT(0)
diff --git a/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch b/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch
deleted file mode 100644
index f0ae2defce..0000000000
--- a/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-From patchwork Fri Mar 24 08:41:38 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13186549
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id EF744C76195
- for <netdev@archiver.kernel.org>; Fri, 24 Mar 2023 08:42:01 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231807AbjCXImA (ORCPT <rfc822;netdev@archiver.kernel.org>);
- Fri, 24 Mar 2023 04:42:00 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32956 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231272AbjCXIly (ORCPT
- <rfc822;netdev@vger.kernel.org>); Fri, 24 Mar 2023 04:41:54 -0400
-Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com
- [IPv6:2a00:1450:4864:20::535])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 113A517CF3;
- Fri, 24 Mar 2023 01:41:46 -0700 (PDT)
-Received: by mail-ed1-x535.google.com with SMTP id ek18so4877175edb.6;
- Fri, 24 Mar 2023 01:41:45 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679647304;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=;
- b=JMrl6Eay1FS0JZqgPHsbcVzuNAbFELc0SLNGyzYtOVQXcI+YwKDM9Ls7I9PsQVEPoZ
- CthomCTYoz5G9DU7uBuia207rnjOhssZJRu0syrCoU+O/ZiQyGLJDvq61z5oZJxC2S40
- kzRsUsC6MRjn64DKPWmxhsSTMKLzn2+P233LKNFbHtfi3NWF5Qu/85sUkxMurnfUgja0
- qQhl25qYY7ZIvmlFHYefaI5UkITQFuiybrqJW9tztCdHf/gS+f33YkkvQ8njmMQa1DW0
- ppedfOUotX+6kmHZGX1yea2V5ezEGGvRourZtYMoecTiD0E5d1J1bKhktKslVLIDm0ig
- oc2g==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679647304;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=;
- b=b3Gmga5ZDbnmQfnw1GCz+eU2JwgsVzfciZuSmfYAiVxpW4c6cur3MHbpzDPhi99wzA
- ZYAM7ryLv88rXl/tQB5g2Nte5rvMfxUeHXsT/JpsRcSSocFRbRrk0QJyiA/Xj86NiD5N
- C1sKz50Im190FmrvPcBh6OHQbv/3MQyE+1fQx+9q3jW5rQiAWQaYk4Ng8GlWA7gtG3jB
- fHO6Fuoenn32pgkveJbQLYL/2t2f53wGf3QLQ3IeKW7jdfIHNThwrwqBMxdHoIDaTBT9
- UWMeJuiYtylIibo/3zbORbWOgIERlWxZRf3BCOFpnzUn4eBzio4LgjtNxZ77ITRxsmbk
- 3+Hg==
-X-Gm-Message-State: AAQBX9dfyBfbR7Sdd5wqxMiAv3Yhk47pK1XzD87MZyAF3AxyoFyKcMaF
- EbwJLyRvTGQEFdVWCGw1eMU=
-X-Google-Smtp-Source:
- AKy350bpDVLq7k1FxG2Mek/VIobZL4KhufiKx8qfmpxpcWmLI3bLg8wfQKEAKJRNJBleo/7CZuCL5g==
-X-Received: by 2002:aa7:c711:0:b0:4a2:588f:b3c5 with SMTP id
- i17-20020aa7c711000000b004a2588fb3c5mr2261236edq.21.1679647304260;
- Fri, 24 Mar 2023 01:41:44 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- z21-20020a50cd15000000b004acbda55f6bsm10323728edi.27.2023.03.24.01.41.43
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Fri, 24 Mar 2023 01:41:43 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: paul.geurts@prodrive-technologies.com, f.fainelli@gmail.com,
- jonas.gorski@gmail.com, andrew@lunn.ch, olteanv@gmail.com,
- davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
- pabeni@redhat.com, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v2 2/2] net: dsa: b53: mdio: add support for BCM53134
-Date: Fri, 24 Mar 2023 09:41:38 +0100
-Message-Id: <20230324084138.664285-3-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230324084138.664285-1-noltari@gmail.com>
-References: <20230323121804.2249605-1-noltari@gmail.com>
- <20230324084138.664285-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-From: Paul Geurts <paul.geurts@prodrive-technologies.com>
-
-Add support for the BCM53134 Ethernet switch in the existing b53 dsa driver.
-BCM53134 is very similar to the BCM58XX series.
-
-Signed-off-by: Paul Geurts <paul.geurts@prodrive-technologies.com>
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- v2: add BCM53134 to is531x5() and remove special RGMII config
-
- drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++
- drivers/net/dsa/b53/b53_mdio.c | 5 ++++-
- drivers/net/dsa/b53/b53_priv.h | 7 +++++--
- 3 files changed, 24 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2613,6 +2613,20 @@ static const struct b53_chip_data b53_sw
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
- .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
- },
-+ {
-+ .chip_id = BCM53134_DEVICE_ID,
-+ .dev_name = "BCM53134",
-+ .vlans = 4096,
-+ .enabled_ports = 0x12f,
-+ .imp_port = 8,
-+ .cpu_port = B53_CPU_PORT,
-+ .vta_regs = B53_VTA_REGS,
-+ .arl_bins = 4,
-+ .arl_buckets = 1024,
-+ .duplex_reg = B53_DUPLEX_STAT_GE,
-+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+ },
- };
-
- static int b53_switch_init(struct b53_device *dev)
-@@ -2790,6 +2804,7 @@ int b53_switch_detect(struct b53_device
- case BCM53012_DEVICE_ID:
- case BCM53018_DEVICE_ID:
- case BCM53019_DEVICE_ID:
-+ case BCM53134_DEVICE_ID:
- dev->chip_id = id32;
- break;
- default:
---- a/drivers/net/dsa/b53/b53_mdio.c
-+++ b/drivers/net/dsa/b53/b53_mdio.c
-@@ -286,6 +286,7 @@ static const struct b53_io_ops b53_mdio_
- #define B53_BRCM_OUI_2 0x03625c00
- #define B53_BRCM_OUI_3 0x00406000
- #define B53_BRCM_OUI_4 0x01410c00
-+#define B53_BRCM_OUI_5 0xae025000
-
- static int b53_mdio_probe(struct mdio_device *mdiodev)
- {
-@@ -313,7 +314,8 @@ static int b53_mdio_probe(struct mdio_de
- if ((phy_id & 0xfffffc00) != B53_BRCM_OUI_1 &&
- (phy_id & 0xfffffc00) != B53_BRCM_OUI_2 &&
- (phy_id & 0xfffffc00) != B53_BRCM_OUI_3 &&
-- (phy_id & 0xfffffc00) != B53_BRCM_OUI_4) {
-+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_4 &&
-+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_5) {
- dev_err(&mdiodev->dev, "Unsupported device: 0x%08x\n", phy_id);
- return -ENODEV;
- }
-@@ -375,6 +377,7 @@ static const struct of_device_id b53_of_
- { .compatible = "brcm,bcm53115" },
- { .compatible = "brcm,bcm53125" },
- { .compatible = "brcm,bcm53128" },
-+ { .compatible = "brcm,bcm53134" },
- { .compatible = "brcm,bcm5365" },
- { .compatible = "brcm,bcm5389" },
- { .compatible = "brcm,bcm5395" },
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -80,6 +80,7 @@ enum {
- BCM583XX_DEVICE_ID = 0x58300,
- BCM7445_DEVICE_ID = 0x7445,
- BCM7278_DEVICE_ID = 0x7278,
-+ BCM53134_DEVICE_ID = 0x5075,
- };
-
- struct b53_pcs {
-@@ -187,7 +188,8 @@ static inline int is531x5(struct b53_dev
- {
- return dev->chip_id == BCM53115_DEVICE_ID ||
- dev->chip_id == BCM53125_DEVICE_ID ||
-- dev->chip_id == BCM53128_DEVICE_ID;
-+ dev->chip_id == BCM53128_DEVICE_ID ||
-+ dev->chip_id == BCM53134_DEVICE_ID;
- }
-
- static inline int is63xx(struct b53_device *dev)
-@@ -215,7 +217,8 @@ static inline int is58xx(struct b53_devi
- return dev->chip_id == BCM58XX_DEVICE_ID ||
- dev->chip_id == BCM583XX_DEVICE_ID ||
- dev->chip_id == BCM7445_DEVICE_ID ||
-- dev->chip_id == BCM7278_DEVICE_ID;
-+ dev->chip_id == BCM7278_DEVICE_ID ||
-+ dev->chip_id == BCM53134_DEVICE_ID;
- }
-
- #define B53_63XX_RGMII0 4
diff --git a/target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch b/target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch
deleted file mode 100644
index 39ba71606e..0000000000
--- a/target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From patchwork Thu Aug 5 22:23:30 2021
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 12422209
-Date: Thu, 5 Aug 2021 23:23:30 +0100
-From: Daniel Golle <daniel@makrotopia.org>
-To: linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org
-Cc: "David S. Miller" <davem@davemloft.net>, Andrew Lunn <andrew@lunn.ch>,
- Michael Walle <michael@walle.cc>
-Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
-Message-ID: <YQxk4jrbm31NM1US@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-X-BeenThere: linux-arm-kernel@lists.infradead.org
-X-Mailman-Version: 2.1.34
-Precedence: list
-List-Id: <linux-arm-kernel.lists.infradead.org>
-List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
-Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
-
-After commit 83216e3988cd1 ("of: net: pass the dst buffer to
-of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not
-defined.
-
-arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup':
-arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared (first use in this function); did you mean 'ESTALE'?
- u8 tmpmac[ETH_ALEN];
- ^~~~~~~~
- ESTALE
-arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier is reported only once for each function it appears in
-arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac' [-Wunused-variable]
- u8 tmpmac[ETH_ALEN];
- ^~~~~~
-make[5]: *** [scripts/Makefile.build:262: arch/arm/mach-mvebu/kirkwood.o] Error 1
-make[5]: *** Waiting for unfinished jobs....
-
-Add missing #include <linux/if_ether.h> to fix this.
-
-Cc: David S. Miller <davem@davemloft.net>
-Cc: Andrew Lunn <andrew@lunn.ch>
-Cc: Michael Walle <michael@walle.cc>
-Reported-by: https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio
-Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to of_get_mac_address()")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- arch/arm/mach-mvebu/kirkwood.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/mach-mvebu/kirkwood.c
-+++ b/arch/arm/mach-mvebu/kirkwood.c
-@@ -11,6 +11,7 @@
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/mbus.h>
-+#include <linux/if_ether.h>
- #include <linux/of.h>
- #include <linux/of_address.h>
- #include <linux/of_net.h>
diff --git a/target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch b/target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch
deleted file mode 100644
index fe0f260ae3..0000000000
--- a/target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 5f7c5e1c0d7a79be144e5efc1f24728ddd7fc25c Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Sat, 5 Nov 2022 20:02:56 +0100
-Subject: [PATCH 1/2] bus: mhi: core: add SBL state callback
-
-Add support for SBL state callback in MHI core.
-
-It is required for ath11k MHI devices in order to be able to set QRTR
-instance ID in the SBL state so that QRTR instance ID-s dont conflict in
-case of multiple PCI/MHI cards or AHB + PCI/MHI card.
-Setting QRTR instance ID is only possible in SBL state and there is
-currently no way to ensure that we are in that state, so provide a
-callback that the controller can trigger off.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
----
- drivers/bus/mhi/host/main.c | 1 +
- include/linux/mhi.h | 2 ++
- 2 files changed, 3 insertions(+)
-
---- a/drivers/bus/mhi/host/main.c
-+++ b/drivers/bus/mhi/host/main.c
-@@ -906,6 +906,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_
- switch (event) {
- case MHI_EE_SBL:
- st = DEV_ST_TRANSITION_SBL;
-+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_SBL_MODE);
- break;
- case MHI_EE_WFW:
- case MHI_EE_AMSS:
---- a/include/linux/mhi.h
-+++ b/include/linux/mhi.h
-@@ -34,6 +34,7 @@ struct mhi_buf_info;
- * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover)
- * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state
- * @MHI_CB_BW_REQ: Received a bandwidth switch request from device
-+ * @MHI_CB_EE_SBL_MODE: MHI device entered SBL mode
- */
- enum mhi_callback {
- MHI_CB_IDLE,
-@@ -45,6 +46,7 @@ enum mhi_callback {
- MHI_CB_SYS_ERROR,
- MHI_CB_FATAL_ERROR,
- MHI_CB_BW_REQ,
-+ MHI_CB_EE_SBL_MODE,
- };
-
- /**
diff --git a/target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch b/target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch
deleted file mode 100644
index 478a2cb27d..0000000000
--- a/target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] bcma: get SoC device struct & copy its DMA params to the
- subdevices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-For bus devices to be fully usable it's required to set their DMA
-parameters.
-
-For years it has been missing and remained unnoticed because of
-mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask.
-Kernel 4.19 came with a lot of DMA changes and caused a regression on
-the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic
-dma noncoherent ops for simple noncoherent platforms") DMA coherent
-allocations just fail. Example:
-[ 1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed
-[ 1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA
-[ 1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12
-[ 1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded
-
-This change fixes above regression in addition to the MIPS bcm47xx
-commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC").
-
-It also fixes another *old* GPIO regression caused by a parent pointing
-to the NULL:
-[ 0.157054] missing gpiochip .dev parent pointer
-[ 0.157287] bcma: bus0: Error registering GPIO driver: -22
-introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to
-use GPIOLIB_IRQCHIP").
-
-Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms")
-Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP")
-Cc: linux-mips@linux-mips.org
-Cc: Christoph Hellwig <hch@lst.de>
-Cc: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/drivers/bcma/host_soc.c
-+++ b/drivers/bcma/host_soc.c
-@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcm
- struct bcma_bus *bus = &soc->bus;
- int err;
-
-+ bus->dev = soc->dev;
-+
- /* Scan bus and initialize it */
- err = bcma_bus_early_register(bus);
- if (err)
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -236,13 +236,17 @@ EXPORT_SYMBOL(bcma_core_irq);
-
- void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
- {
-- device_initialize(&core->dev);
-+ struct device *dev = &core->dev;
-+
-+ device_initialize(dev);
- core->dev.release = bcma_release_core_dev;
- core->dev.bus = &bcma_bus_type;
-- dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
-+ dev_set_name(dev, "bcma%d:%d", bus->num, core->core_index);
- core->dev.parent = bus->dev;
-- if (bus->dev)
-+ if (bus->dev) {
- bcma_of_fill_device(bus->dev, core);
-+ dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask);
-+ }
-
- switch (bus->hosttype) {
- case BCMA_HOSTTYPE_PCI:
diff --git a/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch b/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch
deleted file mode 100644
index 815231973d..0000000000
--- a/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch
+++ /dev/null
@@ -1,222 +0,0 @@
-From fc23ea48ba52c24f201fe5ca0132ee1a3de5a70a Mon Sep 17 00:00:00 2001
-From: Mauri Sandberg <maukka@ext.kapsi.fi>
-Date: Thu, 25 Mar 2021 11:48:05 +0200
-Subject: [PATCH 2/2] gpio: gpio-cascade: add generic GPIO cascade
-
-Adds support for building cascades of GPIO lines. That is, it allows
-setups when there is one upstream line and multiple cascaded lines, out
-of which one can be chosen at a time. The status of the upstream line
-can be conveyed to the selected cascaded line or, vice versa, the status
-of the cascaded line can be conveyed to the upstream line.
-
-A multiplexer is being used to select, which cascaded GPIO line is being
-used at any given time.
-
-At the moment only input direction is supported. In future it should be
-possible to add support for output direction, too.
-
-Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
----
-v7 -> v8:
- - rearrange members in struct gpio_cascade
- - cosmetic changes in file header and in one function declaration
- - added Reviewed-by tags by Linus and Andy
-v6 -> v7:
- - In Kconfig add info about module name
- - adhere to new convention that allows lines longer than 80 chars
- - use dev_probe_err with upstream gpio line too
- - refactor for cleaner exit of probe function.
-v5 -> v6:
- - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
- - refactor code preferring one-liners
- - clean up prints, removing them from success-path.
- - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
- - use devm_gpiochip_add_data instead of gpiochip_add
-v4 -> v5:
- - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
- here and there and changed to use new bindings and compatible string
- - ambigious and vague 'pin' was rename to 'upstream_line'
- - dropped Tested-by and Reviewed-by due to changes in bindings
- - dropped Reported-by suggested by an automatic bot as it was not really
- appropriate to begin with
- - functionally it's the same as v4
-v3 -> v4:
- - Changed author email
- - Included Tested-by and Reviewed-by from Drew
-v2 -> v3:
- - use managed device resources
- - update Kconfig description
-v1 -> v2:
- - removed .owner from platform_driver as per test bot's instruction
- - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
- - added gpio_mux_input_get_direction as it's recommended for all chips
- - removed because this is input only chip: gpio_mux_input_set_value
- - removed because they are not needed for input/output only chips:
- gpio_mux_input_direction_input
- gpio_mux_input_direction_output
- - fixed typo in an error message
- - added info message about successful registration
- - removed can_sleep flag as this does not sleep while getting GPIO value
- like I2C or SPI do
- - Updated description in Kconfig
----
- drivers/gpio/Kconfig | 15 +++++
- drivers/gpio/Makefile | 1 +
- drivers/gpio/gpio-cascade.c | 117 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 133 insertions(+)
- create mode 100644 drivers/gpio/gpio-cascade.c
-
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -1712,4 +1712,19 @@ config GPIO_SIM
-
- endmenu
-
-+comment "Other GPIO expanders"
-+
-+config GPIO_CASCADE
-+ tristate "General GPIO cascade"
-+ select MULTIPLEXER
-+ help
-+ Say yes here to enable support for generic GPIO cascade.
-+
-+ This allows building one-to-many cascades of GPIO lines using
-+ different types of multiplexers readily available. At the
-+ moment only input lines are supported.
-+
-+ To build the driver as a module choose 'm' and the resulting module
-+ will be called 'gpio-cascade'.
-+
- endif
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -43,6 +43,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd
- obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
- obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
- obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o
-+obj-$(CONFIG_GPIO_CASCADE) += gpio-cascade.o
- obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
- obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o
- obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o
---- /dev/null
-+++ b/drivers/gpio/gpio-cascade.c
-@@ -0,0 +1,117 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * A generic GPIO cascade driver
-+ *
-+ * Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
-+ *
-+ * This allows building cascades of GPIO lines in a manner illustrated
-+ * below:
-+ *
-+ * /|---- Cascaded GPIO line 0
-+ * Upstream | |---- Cascaded GPIO line 1
-+ * GPIO line ----+ | .
-+ * | | .
-+ * \|---- Cascaded GPIO line n
-+ *
-+ * A multiplexer is being used to select, which cascaded line is being
-+ * addressed at any given time.
-+ *
-+ * At the moment only input mode is supported due to lack of means for
-+ * testing output functionality. At least theoretically output should be
-+ * possible with open drain constructions.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/platform_device.h>
-+#include <linux/mux/consumer.h>
-+
-+#include <linux/gpio/consumer.h>
-+#include <linux/gpio/driver.h>
-+
-+struct gpio_cascade {
-+ struct gpio_chip gpio_chip;
-+ struct device *parent;
-+ struct mux_control *mux_control;
-+ struct gpio_desc *upstream_line;
-+};
-+
-+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
-+{
-+ return container_of(gc, struct gpio_cascade, gpio_chip);
-+}
-+
-+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset)
-+{
-+ return GPIO_LINE_DIRECTION_IN;
-+}
-+
-+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
-+{
-+ struct gpio_cascade *cas = chip_to_cascade(gc);
-+ int ret;
-+
-+ ret = mux_control_select(cas->mux_control, offset);
-+ if (ret)
-+ return ret;
-+
-+ ret = gpiod_get_value(cas->upstream_line);
-+ mux_control_deselect(cas->mux_control);
-+ return ret;
-+}
-+
-+static int gpio_cascade_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct gpio_cascade *cas;
-+ struct mux_control *mc;
-+ struct gpio_desc *upstream;
-+ struct gpio_chip *gc;
-+
-+ cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
-+ if (!cas)
-+ return -ENOMEM;
-+
-+ mc = devm_mux_control_get(dev, NULL);
-+ if (IS_ERR(mc))
-+ return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
-+
-+ cas->mux_control = mc;
-+ upstream = devm_gpiod_get(dev, "upstream", GPIOD_IN);
-+ if (IS_ERR(upstream))
-+ return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
-+
-+ cas->upstream_line = upstream;
-+ cas->parent = dev;
-+
-+ gc = &cas->gpio_chip;
-+ gc->get = gpio_cascade_get_value;
-+ gc->get_direction = gpio_cascade_get_direction;
-+ gc->base = -1;
-+ gc->ngpio = mux_control_states(mc);
-+ gc->label = dev_name(cas->parent);
-+ gc->parent = cas->parent;
-+ gc->owner = THIS_MODULE;
-+
-+ platform_set_drvdata(pdev, cas);
-+ return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
-+}
-+
-+static const struct of_device_id gpio_cascade_id[] = {
-+ { .compatible = "gpio-cascade" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
-+
-+static struct platform_driver gpio_cascade_driver = {
-+ .driver = {
-+ .name = "gpio-cascade",
-+ .of_match_table = gpio_cascade_id,
-+ },
-+ .probe = gpio_cascade_probe,
-+};
-+module_platform_driver(gpio_cascade_driver);
-+
-+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
-+MODULE_DESCRIPTION("Generic GPIO cascade");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch b/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch
deleted file mode 100644
index 2b3e4bbf71..0000000000
--- a/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From fd59b838dd90452f61a17dc9e5ff175205003068 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 15 Sep 2022 18:49:43 +0200
-Subject: [PATCH] OPP: Provide old opp to config_clks on _set_opp
-
-With the target opp, also pass the old opp to config_clks function.
-This can be useful when a driver needs to take decision on what fequency
-to set based on what is the current frequency without using a
-clk_get_freq call.
-Update the only user of custom config_clks (tegra30 devfreq driver) to
-this new implementation.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/devfreq/tegra30-devfreq.c | 5 +++--
- drivers/opp/core.c | 11 ++++++-----
- include/linux/pm_opp.h | 11 ++++++-----
- 3 files changed, 15 insertions(+), 12 deletions(-)
-
---- a/drivers/devfreq/tegra30-devfreq.c
-+++ b/drivers/devfreq/tegra30-devfreq.c
-@@ -823,8 +823,9 @@ static int devm_tegra_devfreq_init_hw(st
-
- static int tegra_devfreq_config_clks_nop(struct device *dev,
- struct opp_table *opp_table,
-- struct dev_pm_opp *opp, void *data,
-- bool scaling_down)
-+ struct dev_pm_opp *old_opp,
-+ struct dev_pm_opp *opp,
-+ void *data, bool scaling_down)
- {
- /* We want to skip clk configuration via dev_pm_opp_set_opp() */
- return 0;
---- a/drivers/opp/core.c
-+++ b/drivers/opp/core.c
-@@ -816,7 +816,8 @@ static int _set_opp_voltage(struct devic
-
- static int
- _opp_config_clk_single(struct device *dev, struct opp_table *opp_table,
-- struct dev_pm_opp *opp, void *data, bool scaling_down)
-+ struct dev_pm_opp *old_opp, struct dev_pm_opp *opp,
-+ void *data, bool scaling_down)
- {
- unsigned long *target = data;
- unsigned long freq;
-@@ -848,8 +849,8 @@ _opp_config_clk_single(struct device *de
- * the order in which they are present in the array while scaling up.
- */
- int dev_pm_opp_config_clks_simple(struct device *dev,
-- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data,
-- bool scaling_down)
-+ struct opp_table *opp_table, struct dev_pm_opp *old_opp,
-+ struct dev_pm_opp *opp, void *data, bool scaling_down)
- {
- int ret, i;
-
-@@ -1121,7 +1122,7 @@ static int _set_opp(struct device *dev,
- }
-
- if (opp_table->config_clks) {
-- ret = opp_table->config_clks(dev, opp_table, opp, clk_data, scaling_down);
-+ ret = opp_table->config_clks(dev, opp_table, old_opp, opp, clk_data, scaling_down);
- if (ret)
- return ret;
- }
-@@ -1196,7 +1197,7 @@ int dev_pm_opp_set_rate(struct device *d
- * equivalent to a clk_set_rate()
- */
- if (!_get_opp_count(opp_table)) {
-- ret = opp_table->config_clks(dev, opp_table, NULL,
-+ ret = opp_table->config_clks(dev, opp_table, NULL, NULL,
- &target_freq, false);
- goto put_opp_table;
- }
---- a/include/linux/pm_opp.h
-+++ b/include/linux/pm_opp.h
-@@ -61,7 +61,8 @@ typedef int (*config_regulators_t)(struc
- struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp,
- struct regulator **regulators, unsigned int count);
-
--typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table,
-+typedef int (*config_clks_t)(struct device *dev,
-+ struct opp_table *opp_table, struct dev_pm_opp *old_opp,
- struct dev_pm_opp *opp, void *data, bool scaling_down);
-
- /**
-@@ -160,8 +161,8 @@ int dev_pm_opp_set_config(struct device
- int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config);
- void dev_pm_opp_clear_config(int token);
- int dev_pm_opp_config_clks_simple(struct device *dev,
-- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data,
-- bool scaling_down);
-+ struct opp_table *opp_table, struct dev_pm_opp *old_opp,
-+ struct dev_pm_opp *opp, void *data, bool scaling_down);
-
- struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp);
- int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
-@@ -346,8 +347,8 @@ static inline int devm_pm_opp_set_config
- static inline void dev_pm_opp_clear_config(int token) {}
-
- static inline int dev_pm_opp_config_clks_simple(struct device *dev,
-- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data,
-- bool scaling_down)
-+ struct opp_table *opp_table, struct dev_pm_opp *old_opp,
-+ struct dev_pm_opp *opp, void *data, bool scaling_down)
- {
- return -EOPNOTSUPP;
- }
diff --git a/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
deleted file mode 100644
index d07447bcba..0000000000
--- a/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Thu, 13 Oct 2022 00:51:33 +0900
-Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch fixes crc32 error on Big-Endianness system by conversion of
-calculated crc32 value.
-
-Little-Endianness system:
-
- obtained crc32: Little
-calculated crc32: Little
-
-Big-Endianness system:
-
- obtained crc32: Little
-calculated crc32: Big
-
-log (APRESIA ApresiaLightGS120GT-SS, RTL8382M, Big-Endianness):
-
-[ 8.570000] u_boot_env 18001200.spi:flash@0:partitions:partition@c0000: Invalid calculated CRC32: 0x88cd6f09 (expected: 0x096fcd88)
-[ 8.580000] u_boot_env: probe of 18001200.spi:flash@0:partitions:partition@c0000 failed with error -22
-
-Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables")
-
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Tested-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
- crc32_data_len = dev_size - crc32_data_offset;
- data_len = dev_size - data_offset;
-
-- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
-+ calc = le32_to_cpu((__le32)crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L);
- if (calc != crc32) {
- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
- err = -EINVAL;
diff --git a/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
deleted file mode 100644
index 9bb94a28b5..0000000000
--- a/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 13 Jul 2023 18:29:19 +0200
-Subject: [PATCH] nvmem: core: support "mac-base" fixed layout cells
-
-Fixed layout binding allows specifying "mac-base" NVMEM cells. It's used
-for base MAC address (that can be used for calculating relative
-addresses). It can be stored in a raw binary format or as an ASCII
-string.
----
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- menuconfig NVMEM
- bool "NVMEM Support"
-+ select GENERIC_NET_UTILS
- imply NVMEM_LAYOUTS
- help
- Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES...
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -7,9 +7,12 @@
- */
-
- #include <linux/device.h>
-+#include <linux/ctype.h>
-+#include <linux/etherdevice.h>
- #include <linux/export.h>
- #include <linux/fs.h>
- #include <linux/idr.h>
-+#include <linux/if_ether.h>
- #include <linux/init.h>
- #include <linux/kref.h>
- #include <linux/module.h>
-@@ -780,6 +783,62 @@ static int nvmem_validate_keepouts(struc
- return 0;
- }
-
-+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ if (WARN_ON(bytes != ETH_ALEN))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(buf, index);
-+
-+ return 0;
-+}
-+
-+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN];
-+
-+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1))
-+ return -EINVAL;
-+
-+ if (!mac_pton(buf, mac))
-+ return -EINVAL;
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
-+static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset,
-+ void *buf, size_t bytes)
-+{
-+ u8 mac[ETH_ALEN], *hexstr;
-+ int i;
-+
-+ if (WARN_ON(bytes != 2 * ETH_ALEN))
-+ return -EINVAL;
-+
-+ hexstr = (u8 *)buf;
-+ for (i = 0; i < ETH_ALEN; i++) {
-+ if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1]))
-+ return -EINVAL;
-+
-+ mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]);
-+ }
-+
-+ if (index)
-+ eth_addr_add(mac, index);
-+
-+ ether_addr_copy(buf, mac);
-+
-+ return 0;
-+}
-+
- static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
- {
- struct device *dev = &nvmem->dev;
-@@ -814,6 +873,25 @@ static int nvmem_add_cells_from_dt(struc
- if (nvmem->fixup_dt_cell_info)
- nvmem->fixup_dt_cell_info(nvmem, &info);
-
-+ if (of_device_is_compatible(np, "fixed-layout")) {
-+ if (of_device_is_compatible(child, "mac-base")) {
-+ if (info.bytes == ETH_ALEN) {
-+ info.raw_len = info.bytes;
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = nvmem_mac_base_raw_read;
-+ } else if (info.bytes == 2 * ETH_ALEN) {
-+ info.raw_len = info.bytes;
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = nvmem_mac_base_hex_read;
-+ } else if (info.bytes == 3 * ETH_ALEN - 1) {
-+ info.raw_len = info.bytes;
-+ info.bytes = ETH_ALEN;
-+ info.read_post_process = nvmem_mac_base_ascii_read;
-+ }
-+
-+ }
-+ }
-+
- ret = nvmem_add_one_cell(nvmem, &info);
- kfree(info.name);
- if (ret) {
diff --git a/target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch
deleted file mode 100644
index ba06196f7c..0000000000
--- a/target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From: Gabor Juhos <juhosg@openwrt.org>
-Subject: debloat: add kernel config option to disabling common PCI quirks
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- drivers/pci/Kconfig | 6 ++++++
- drivers/pci/quirks.c | 6 ++++++
- 2 files changed, 12 insertions(+)
-
---- a/drivers/pci/Kconfig
-+++ b/drivers/pci/Kconfig
-@@ -118,6 +118,13 @@ config XEN_PCIDEV_FRONTEND
- The PCI device frontend driver allows the kernel to import arbitrary
- PCI devices from a PCI backend to support PCI driver domains.
-
-+config PCI_DISABLE_COMMON_QUIRKS
-+ bool "PCI disable common quirks"
-+ depends on PCI
-+ help
-+ If you don't know what to do here, say N.
-+
-+
- config PCI_ATS
- bool
-
---- a/drivers/pci/quirks.c
-+++ b/drivers/pci/quirks.c
-@@ -207,6 +207,7 @@ static void quirk_mmio_always_on(struct
- DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
- /*
- * The Mellanox Tavor device gives false positive parity errors. Disable
- * parity error reporting.
-@@ -3393,6 +3394,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
-
-+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
-+
- /*
- * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum.
- * To work around this, query the size it should be configured to by the
-@@ -3418,6 +3421,8 @@ static void quirk_intel_ntb(struct pci_d
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
-+
- /*
- * Some BIOS implementations leave the Intel GPU interrupts enabled, even
- * though no one is handling them (e.g., if the i915 driver is never
-@@ -3456,6 +3461,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
- DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
- DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq);
-
-+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
-+
- /*
- * PCI devices which are on Intel chips can skip the 10ms delay
- * before entering D3 mode.
diff --git a/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch
deleted file mode 100644
index fcb77e5174..0000000000
--- a/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: debloat: disable common USB quirks
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- drivers/usb/host/pci-quirks.c | 16 ++++++++++++++++
- drivers/usb/host/pci-quirks.h | 18 +++++++++++++++++-
- include/linux/usb/hcd.h | 7 +++++++
- 3 files changed, 40 insertions(+), 1 deletion(-)
-
---- a/drivers/usb/host/pci-quirks.c
-+++ b/drivers/usb/host/pci-quirks.c
-@@ -128,6 +128,8 @@ struct amd_chipset_type {
- u8 rev;
- };
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
-+
- static struct amd_chipset_info {
- struct pci_dev *nb_dev;
- struct pci_dev *smbus_dev;
-@@ -631,6 +633,10 @@ bool usb_amd_pt_check_port(struct device
- }
- EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
-
-+#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */
-+
-+#if IS_ENABLED(CONFIG_USB_UHCI_HCD)
-+
- /*
- * Make sure the controller is completely inactive, unable to
- * generate interrupts or do DMA.
-@@ -710,8 +716,17 @@ reset_needed:
- uhci_reset_hc(pdev, base);
- return 1;
- }
-+#else
-+int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
-+{
-+ return 0;
-+}
-+
-+#endif
- EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
-+
- static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
- {
- u16 cmd;
-@@ -1283,3 +1298,4 @@ static void quirk_usb_early_handoff(stru
- }
- DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff);
-+#endif
---- a/drivers/usb/host/pci-quirks.h
-+++ b/drivers/usb/host/pci-quirks.h
-@@ -5,6 +5,9 @@
- #ifdef CONFIG_USB_PCI
- void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
- int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
-+#endif /* CONFIG_USB_PCI */
-+
-+#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS)
- int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev);
- bool usb_amd_hang_symptom_quirk(void);
- bool usb_amd_prefetch_quirk(void);
-@@ -19,6 +22,18 @@ void sb800_prefetch(struct device *dev,
- bool usb_amd_pt_check_port(struct device *device, int port);
- #else
- struct pci_dev;
-+static inline int usb_amd_quirk_pll_check(void)
-+{
-+ return 0;
-+}
-+static inline bool usb_amd_hang_symptom_quirk(void)
-+{
-+ return false;
-+}
-+static inline bool usb_amd_prefetch_quirk(void)
-+{
-+ return false;
-+}
- static inline void usb_amd_quirk_pll_disable(void) {}
- static inline void usb_amd_quirk_pll_enable(void) {}
- static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
-@@ -29,6 +44,11 @@ static inline bool usb_amd_pt_check_port
- {
- return false;
- }
-+static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {}
-+static inline bool usb_xhci_needs_pci_reset(struct pci_dev *pdev)
-+{
-+ return false;
-+}
- #endif /* CONFIG_USB_PCI */
-
- #endif /* __LINUX_USB_PCI_QUIRKS_H */
---- a/include/linux/usb/hcd.h
-+++ b/include/linux/usb/hcd.h
-@@ -484,7 +484,14 @@ extern int usb_hcd_pci_probe(struct pci_
- extern void usb_hcd_pci_remove(struct pci_dev *dev);
- extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
-
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
- extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev);
-+#else
-+static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev)
-+{
-+ return 0;
-+}
-+#endif
-
- #ifdef CONFIG_PM
- extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
diff --git a/target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
deleted file mode 100644
index 33eb34c913..0000000000
--- a/target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From d9c8bc8c1408f3e8529db6e4e04017b4c579c342 Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Sun, 18 Feb 2018 17:08:04 +0100
-Subject: [PATCH] w1: gpio: fix problem with platfom data in w1-gpio
-
-In devices, where fdt is used, is impossible to apply platform data
-without proper fdt node.
-
-This patch allow to use platform data in devices with fdt.
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- drivers/w1/masters/w1-gpio.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/drivers/w1/masters/w1-gpio.c
-+++ b/drivers/w1/masters/w1-gpio.c
-@@ -76,7 +76,7 @@ static int w1_gpio_probe(struct platform
- enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN;
- int err;
-
-- if (of_have_populated_dt()) {
-+ if (of_have_populated_dt() && !dev_get_platdata(&pdev->dev)) {
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
diff --git a/target/linux/generic/pending-6.1/834-ledtrig-libata.patch b/target/linux/generic/pending-6.1/834-ledtrig-libata.patch
deleted file mode 100644
index 39960bc090..0000000000
--- a/target/linux/generic/pending-6.1/834-ledtrig-libata.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Subject: libata: add ledtrig support
-
-This adds a LED trigger for each ATA port indicating disk activity.
-
-As this is needed only on specific platforms (NAS SoCs and such),
-these platforms should define ARCH_WANTS_LIBATA_LEDS if there
-are boards with LED(s) intended to indicate ATA disk activity and
-need the OS to take care of that.
-In that way, if not selected, LED trigger support not will be
-included in libata-core and both, codepaths and structures remain
-untouched.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/ata/Kconfig | 16 ++++++++++++++++
- drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++
- include/linux/libata.h | 9 +++++++++
- 3 files changed, 66 insertions(+)
-
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -67,6 +67,22 @@ config ATA_FORCE
-
- If unsure, say Y.
-
-+config ARCH_WANT_LIBATA_LEDS
-+ bool
-+
-+config ATA_LEDS
-+ bool "support ATA port LED triggers"
-+ depends on ARCH_WANT_LIBATA_LEDS
-+ select NEW_LEDS
-+ select LEDS_CLASS
-+ select LEDS_TRIGGERS
-+ default y
-+ help
-+ This option adds a LED trigger for each registered ATA port.
-+ It is used to drive disk activity leds connected via GPIO.
-+
-+ If unsure, say N.
-+
- config ATA_ACPI
- bool "ATA ACPI Support"
- depends on ACPI
---- a/drivers/ata/libata-core.c
-+++ b/drivers/ata/libata-core.c
-@@ -663,6 +663,19 @@ u64 ata_tf_read_block(const struct ata_t
- return block;
- }
-
-+#ifdef CONFIG_ATA_LEDS
-+#define LIBATA_BLINK_DELAY 20 /* ms */
-+static inline void ata_led_act(struct ata_port *ap)
-+{
-+ unsigned long led_delay = LIBATA_BLINK_DELAY;
-+
-+ if (unlikely(!ap->ledtrig))
-+ return;
-+
-+ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0);
-+}
-+#endif
-+
- /**
- * ata_build_rw_tf - Build ATA taskfile for given read/write request
- * @qc: Metadata associated with the taskfile to build
-@@ -4716,6 +4729,9 @@ void __ata_qc_complete(struct ata_queued
- link->active_tag = ATA_TAG_POISON;
- ap->nr_active_links--;
- }
-+#ifdef CONFIG_ATA_LEDS
-+ ata_led_act(ap);
-+#endif
-
- /* clear exclusive status */
- if (unlikely(qc->flags & ATA_QCFLAG_CLEAR_EXCL &&
-@@ -5438,6 +5454,9 @@ struct ata_port *ata_port_alloc(struct a
- ap->stats.unhandled_irq = 1;
- ap->stats.idle_irq = 1;
- #endif
-+#ifdef CONFIG_ATA_LEDS
-+ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
-+#endif
- ata_sff_port_init(ap);
-
- return ap;
-@@ -5473,6 +5492,12 @@ static void ata_host_release(struct kref
-
- kfree(ap->pmp_link);
- kfree(ap->slave_link);
-+#ifdef CONFIG_ATA_LEDS
-+ if (ap->ledtrig) {
-+ led_trigger_unregister(ap->ledtrig);
-+ kfree(ap->ledtrig);
-+ };
-+#endif
- kfree(ap);
- host->ports[i] = NULL;
- }
-@@ -5875,7 +5900,23 @@ int ata_host_register(struct ata_host *h
- host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
- host->ports[i]->local_port_no = i + 1;
- }
-+#ifdef CONFIG_ATA_LEDS
-+ for (i = 0; i < host->n_ports; i++) {
-+ if (unlikely(!host->ports[i]->ledtrig))
-+ continue;
-
-+ snprintf(host->ports[i]->ledtrig_name,
-+ sizeof(host->ports[i]->ledtrig_name), "ata%u",
-+ host->ports[i]->print_id);
-+
-+ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name;
-+
-+ if (led_trigger_register(host->ports[i]->ledtrig)) {
-+ kfree(host->ports[i]->ledtrig);
-+ host->ports[i]->ledtrig = NULL;
-+ }
-+ }
-+#endif
- /* Create associated sysfs transport objects */
- for (i = 0; i < host->n_ports; i++) {
- rc = ata_tport_add(host->dev,host->ports[i]);
---- a/include/linux/libata.h
-+++ b/include/linux/libata.h
-@@ -23,6 +23,9 @@
- #include <linux/cdrom.h>
- #include <linux/sched.h>
- #include <linux/async.h>
-+#ifdef CONFIG_ATA_LEDS
-+#include <linux/leds.h>
-+#endif
-
- /*
- * Define if arch has non-standard setup. This is a _PCI_ standard
-@@ -865,6 +868,12 @@ struct ata_port {
- #ifdef CONFIG_ATA_ACPI
- struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
- #endif
-+
-+#ifdef CONFIG_ATA_LEDS
-+ struct led_trigger *ledtrig;
-+ char ledtrig_name[8];
-+#endif
-+
- /* owned by EH */
- u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned;
- };
diff --git a/target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch b/target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch
deleted file mode 100644
index 5ca8933d6f..0000000000
--- a/target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From d6988cf1d16faac56899918bb2b1be8d85155e3f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 20 Feb 2021 18:36:38 +0100
-Subject: [PATCH] hwrng: bcm2835: set quality to 1000
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows devices without a high precission timer to reduce boot from >100s
-to <30s.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- drivers/char/hw_random/bcm2835-rng.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/char/hw_random/bcm2835-rng.c
-+++ b/drivers/char/hw_random/bcm2835-rng.c
-@@ -170,6 +170,7 @@ static int bcm2835_rng_probe(struct plat
- priv->rng.init = bcm2835_rng_init;
- priv->rng.read = bcm2835_rng_read;
- priv->rng.cleanup = bcm2835_rng_cleanup;
-+ priv->rng.quality = 1000;
-
- if (dev_of_node(dev)) {
- rng_id = of_match_node(bcm2835_rng_of_match, dev->of_node);
diff --git a/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch b/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch
deleted file mode 100644
index fc61ee202a..0000000000
--- a/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 663b9f99bb35dbc0c7b685f71ee3668a60d31320 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Mon, 10 Jan 2022 02:02:00 +0100
-Subject: [PATCH] PCI: aardvark: Make main irq_chip structure a static driver
- structure
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Marc Zyngier says [1] that we should use struct irq_chip as a global
-static struct in the driver. Even though the structure currently
-contains a dynamic member (parent_device), Marc says [2] that he plans
-to kill it and make the structure completely static.
-
-We have already converted others irq_chip structures in this driver in
-this way, but we omitted this one because the .name member is
-dynamically created from device's name, and the name is displayed in
-sysfs, so changing it would break sysfs ABI.
-
-The rationale for changing the name (to "advk-INT") in spite of sysfs
-ABI, and thus allowing to convert to a static structure, is that after
-the other changes we made in this series, the IRQ chip is basically
-something different: it no logner generates ERR and PME interrupts (they
-are generated by emulated bridge's rp_irq_chip).
-
-[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz@kernel.org/
-[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz@kernel.org/
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
----
- drivers/pci/controller/pci-aardvark.c | 25 +++++++------------------
- 1 file changed, 7 insertions(+), 18 deletions(-)
-
---- a/drivers/pci/controller/pci-aardvark.c
-+++ b/drivers/pci/controller/pci-aardvark.c
-@@ -277,7 +277,6 @@ struct advk_pcie {
- u8 wins_count;
- struct irq_domain *rp_irq_domain;
- struct irq_domain *irq_domain;
-- struct irq_chip irq_chip;
- raw_spinlock_t irq_lock;
- struct irq_domain *msi_domain;
- struct irq_domain *msi_inner_domain;
-@@ -1426,14 +1425,19 @@ static void advk_pcie_irq_unmask(struct
- raw_spin_unlock_irqrestore(&pcie->irq_lock, flags);
- }
-
-+static struct irq_chip advk_irq_chip = {
-+ .name = "advk-INT",
-+ .irq_mask = advk_pcie_irq_mask,
-+ .irq_unmask = advk_pcie_irq_unmask,
-+};
-+
- static int advk_pcie_irq_map(struct irq_domain *h,
- unsigned int virq, irq_hw_number_t hwirq)
- {
- struct advk_pcie *pcie = h->host_data;
-
- irq_set_status_flags(virq, IRQ_LEVEL);
-- irq_set_chip_and_handler(virq, &pcie->irq_chip,
-- handle_level_irq);
-+ irq_set_chip_and_handler(virq, &advk_irq_chip, handle_level_irq);
- irq_set_chip_data(virq, pcie);
-
- return 0;
-@@ -1492,7 +1496,6 @@ static int advk_pcie_init_irq_domain(str
- struct device *dev = &pcie->pdev->dev;
- struct device_node *node = dev->of_node;
- struct device_node *pcie_intc_node;
-- struct irq_chip *irq_chip;
- int ret = 0;
-
- raw_spin_lock_init(&pcie->irq_lock);
-@@ -1503,28 +1506,14 @@ static int advk_pcie_init_irq_domain(str
- return -ENODEV;
- }
-
-- irq_chip = &pcie->irq_chip;
--
-- irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq",
-- dev_name(dev));
-- if (!irq_chip->name) {
-- ret = -ENOMEM;
-- goto out_put_node;
-- }
--
-- irq_chip->irq_mask = advk_pcie_irq_mask;
-- irq_chip->irq_unmask = advk_pcie_irq_unmask;
--
- pcie->irq_domain =
- irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
- &advk_pcie_irq_domain_ops, pcie);
- if (!pcie->irq_domain) {
- dev_err(dev, "Failed to get a INTx IRQ domain\n");
- ret = -ENOMEM;
-- goto out_put_node;
- }
-
--out_put_node:
- of_node_put(pcie_intc_node);
- return ret;
- }
diff --git a/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch b/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch
deleted file mode 100644
index cc6f1e0d9d..0000000000
--- a/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From patchwork Wed Mar 22 17:15:12 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13184389
-Return-Path: <linux-clk-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 73F2DC6FD1C
- for <linux-clk@archiver.kernel.org>; Wed, 22 Mar 2023 17:15:59 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231363AbjCVRP5 (ORCPT <rfc822;linux-clk@archiver.kernel.org>);
- Wed, 22 Mar 2023 13:15:57 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58824 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231408AbjCVRPy (ORCPT
- <rfc822;linux-clk@vger.kernel.org>); Wed, 22 Mar 2023 13:15:54 -0400
-Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com
- [IPv6:2a00:1450:4864:20::32d])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70E4C64B28;
- Wed, 22 Mar 2023 10:15:24 -0700 (PDT)
-Received: by mail-wm1-x32d.google.com with SMTP id n19so1740892wms.0;
- Wed, 22 Mar 2023 10:15:24 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679505322;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=;
- b=LTOQ75W3s5nYo+nEfiJAKqytSopONB4jCtU3zRygzPMasugVOrYFMsUR+WrpsAjuRT
- v4HgWpJxEsIWeRXrUN9W21mFXhGgJLJXSxRnrio0CsZZBNMdkebbNOphgKXIWAdm+2iM
- PzqAdGm5t38wT2mmm6V/9hCy90+12raHM82tNFdhhiezfg2cukVOKP3j/TeOVCwas0gQ
- iFc+CuZB6y73zYXvMUMUpTsqI5vev4xJsSMHIQJVmUxJAwqhOBhN9JCRo7Ao+wayjn2d
- Fxo6AV3A8v68nVfoQ0K0I+eWXG48nMCX45iWh/lVvVTOFcR99kn4va7NY1oVnPsh+WQz
- WcLA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679505322;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=;
- b=wv2NSR1B5RnsdoEE7mgJSHAfSs1JHZbQ1HPMldyaGWAk1dcucqh/uDzM3Flz+ADRi1
- 19NoaB2Ur7QaWZejbuplnIOK/nte3PnmqJ9ZNw8HejmuS4eU8mB1V1aJUSKSPGsfUi4a
- LYe3HSw87l0jrAC7ptdKvdUtzBoIkX0CeFvfguTQQkDhUTyAFIG144hY6uPXY9Mga96b
- gnNe2dLCzHQLbEJpaDaavT7FEEcLDxaq7jNcR2xqEEZaIwfcew+Q05t4xL/3i8GAj9Ru
- 6ivQjIbBKfYQF88o7KnOW9o1wjrGsk+Nd4Iy0OLZix3JQasCJGrKV7ib5awI9J39upYV
- fa4A==
-X-Gm-Message-State: AO0yUKWw75I1M5Vjrd4vXq4GTruQu0H84pycgyi2CT3bczTYRJpWmEWg
- +bHDhvp1n5IWW85GI9vKWpbclB13a/S0RQ==
-X-Google-Smtp-Source:
- AK7set9T/2oJsVetUb2L4mPEWu8YqDrnK8EzHK5bJf1ABIa1Et8f7BFJ7AA3j14ITZuf8cH0HqlRtg==
-X-Received: by 2002:a05:600c:2304:b0:3ed:2949:985b with SMTP id
- 4-20020a05600c230400b003ed2949985bmr206833wmo.23.1679505322457;
- Wed, 22 Mar 2023 10:15:22 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.21
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Wed, 22 Mar 2023 10:15:22 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de,
- f.fainelli@gmail.com, jonas.gorski@gmail.com,
- william.zhang@broadcom.com, linux-clk@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>,
- Rob Herring <robh@kernel.org>
-Subject: [PATCH v4 1/4] dt-bindings: clk: add BCM63268 timer clock definitions
-Date: Wed, 22 Mar 2023 18:15:12 +0100
-Message-Id: <20230322171515.120353-2-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230322171515.120353-1-noltari@gmail.com>
-References: <20230322171515.120353-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-clk.vger.kernel.org>
-X-Mailing-List: linux-clk@vger.kernel.org
-
-Add missing timer clock definitions for BCM63268.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Rob Herring <robh@kernel.org>
----
- v4: no changes
- v3: no changes
- v2: change commit title, as suggested by Stephen Boyd
-
- include/dt-bindings/clock/bcm63268-clock.h | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/include/dt-bindings/clock/bcm63268-clock.h
-+++ b/include/dt-bindings/clock/bcm63268-clock.h
-@@ -27,4 +27,17 @@
- #define BCM63268_CLK_TBUS 27
- #define BCM63268_CLK_ROBOSW250 31
-
-+#define BCM63268_TCLK_EPHY1 0
-+#define BCM63268_TCLK_EPHY2 1
-+#define BCM63268_TCLK_EPHY3 2
-+#define BCM63268_TCLK_GPHY1 3
-+#define BCM63268_TCLK_DSL 4
-+#define BCM63268_TCLK_WAKEON_EPHY 6
-+#define BCM63268_TCLK_WAKEON_DSL 7
-+#define BCM63268_TCLK_FAP1 11
-+#define BCM63268_TCLK_FAP2 15
-+#define BCM63268_TCLK_UTO_50 16
-+#define BCM63268_TCLK_UTO_EXTIN 17
-+#define BCM63268_TCLK_USB_REF 18
-+
- #endif /* __DT_BINDINGS_CLOCK_BCM63268_H */
diff --git a/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch b/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch
deleted file mode 100644
index 5f1be105ac..0000000000
--- a/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From patchwork Wed Mar 22 17:15:13 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13184390
-Return-Path: <linux-clk-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id D0B1AC6FD1C
- for <linux-clk@archiver.kernel.org>; Wed, 22 Mar 2023 17:16:08 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231472AbjCVRQI (ORCPT <rfc822;linux-clk@archiver.kernel.org>);
- Wed, 22 Mar 2023 13:16:08 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58934 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231435AbjCVRP5 (ORCPT
- <rfc822;linux-clk@vger.kernel.org>); Wed, 22 Mar 2023 13:15:57 -0400
-Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com
- [IPv6:2a00:1450:4864:20::329])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9655064863;
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-Received: by mail-wm1-x329.google.com with SMTP id
- v4-20020a05600c470400b003ee4f06428fso2424553wmo.4;
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679505324;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=;
- b=WRZRU2SM9n1LfUj4SgTPfQczADC2pfvoIrOsNpBLTym2eOfmkTetb/WbGSla5kw2Wb
- SH5MIC2fFeScJg6T5FFAUOOLmRVW9xvl8Q3T3NKb3z/9wvPHO767nrdIbffRWMJFs7gW
- wT/kuTpn8GYdfY0sZ/dMTkq41DVusEkxfX6GxtG85O98ZP8xMHQog8aPs9fRfUvI5ZKB
- eGYcRz/Wn1cHhjey9jtWzQEEmZ/BT3b0HQTF9Tl88oofhiEgbyjFXr91+vRsLbsJpGXH
- /1FjjaLG5DnonKubV9rmbuCU8KzwH331gi2KuRjvLD2V+OMewqSa5i+GvgVv8x2zC8y+
- /mLQ==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679505324;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=;
- b=bhd0fNh0jDOMlGSC4F+p5igV8AUlGEPj2cXUwgdgqRfSSuUy9z+Li8cT0MbY/aWH5Z
- qInRVA+R1cWV3ubrDyKag6oEc0LDU234bnMFcP9b7MRlrM8Dpit9TFSyqJU4sDUWNDs5
- KOe2k/SNIdat6munC9VOuEBDO0eB/UDMN+repKwXNdHChp/Toq9qMvW4Uy8uHxosbQlD
- 8P88GbKFjynb1E8I8croGjfub7+y8PPsWB0xNUcafIv6xs3MnVOP1Mk4KwBCbqS509la
- mfjsriXtIybO8XFqtn100ungjvbFWdogEplLdSPVdgAqdfF5J8gHxAoApoeYejYkL5/R
- kOhQ==
-X-Gm-Message-State: AO0yUKWdzr3dMmjKhD8tF+ec4Dfdq9VGZ/WCU4d85npKQvxSwhNPZZ1J
- 5WYRIqivh0suFC1OqEidwenpiJYvXedYjw==
-X-Google-Smtp-Source:
- AK7set87ew2/mKWeShXTTW/YBbBJNR2zeGFV0CfuqLXhiJEU6tqFuyKcW+vFEoKHIbNUS8wRy1SzLA==
-X-Received: by 2002:a05:600c:290:b0:3ee:6d88:774a with SMTP id
- 16-20020a05600c029000b003ee6d88774amr160734wmk.14.1679505323514;
- Wed, 22 Mar 2023 10:15:23 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.22
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Wed, 22 Mar 2023 10:15:23 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de,
- f.fainelli@gmail.com, jonas.gorski@gmail.com,
- william.zhang@broadcom.com, linux-clk@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>,
- Rob Herring <robh@kernel.org>
-Subject: [PATCH v4 2/4] dt-bindings: reset: add BCM63268 timer reset
- definitions
-Date: Wed, 22 Mar 2023 18:15:13 +0100
-Message-Id: <20230322171515.120353-3-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230322171515.120353-1-noltari@gmail.com>
-References: <20230322171515.120353-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-clk.vger.kernel.org>
-X-Mailing-List: linux-clk@vger.kernel.org
-
-Add missing timer reset definitions for BCM63268.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Rob Herring <robh@kernel.org>
----
- v4: no changes
- v3: no changes
- v2: change commit title, as suggested by Stephen Boyd
-
- include/dt-bindings/reset/bcm63268-reset.h | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/include/dt-bindings/reset/bcm63268-reset.h
-+++ b/include/dt-bindings/reset/bcm63268-reset.h
-@@ -23,4 +23,8 @@
- #define BCM63268_RST_PCIE_HARD 17
- #define BCM63268_RST_GPHY 18
-
-+#define BCM63268_TRST_SW 29
-+#define BCM63268_TRST_HW 30
-+#define BCM63268_TRST_POR 31
-+
- #endif /* __DT_BINDINGS_RESET_BCM63268_H */
diff --git a/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch b/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch
deleted file mode 100644
index 7e500cd1b5..0000000000
--- a/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch
+++ /dev/null
@@ -1,345 +0,0 @@
-From patchwork Wed Mar 22 17:15:15 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?=
- <noltari@gmail.com>
-X-Patchwork-Id: 13184392
-Return-Path: <linux-clk-owner@vger.kernel.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by smtp.lore.kernel.org (Postfix) with ESMTP id 199D9C76196
- for <linux-clk@archiver.kernel.org>; Wed, 22 Mar 2023 17:16:11 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S231512AbjCVRQJ (ORCPT <rfc822;linux-clk@archiver.kernel.org>);
- Wed, 22 Mar 2023 13:16:09 -0400
-Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58942 "EHLO
- lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S231442AbjCVRP5 (ORCPT
- <rfc822;linux-clk@vger.kernel.org>); Wed, 22 Mar 2023 13:15:57 -0400
-Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com
- [IPv6:2a00:1450:4864:20::32c])
- by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DDB36487D;
- Wed, 22 Mar 2023 10:15:27 -0700 (PDT)
-Received: by mail-wm1-x32c.google.com with SMTP id
- i5-20020a05600c354500b003edd24054e0so6717370wmq.4;
- Wed, 22 Mar 2023 10:15:27 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20210112; t=1679505325;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=;
- b=Y1mva2Bt3sUbKxLgEUS331CJbGxUc4z8kTQW8qiHWGhYlFKtm+d5z4sT40E5BeZAnU
- zmTbCI7jbroe9NYBxGUmSli6LNVDPjND80ChbhWTqbqMQTmeQFWut9KmeBWK6Oze2lC/
- XMSOorUzowjcU2xtHNrzoq2KH2pstW573lsB8WnzFVfhMaRkE9DfRr6WNyA7zC8DyxM5
- ezxlCQtCmgPfCqlyksbIDKrgrRf3GiUR0yUd6xRU+MssyvH1FkYGDCerPctDto6lGHBz
- 8Y15jT3l6OnQMT6dkekgpPF5/XrSUY93u9g0B4U8+0dhNj+K7vmDen+jqdess+tpLnq/
- gFrA==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20210112; t=1679505325;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=;
- b=Ym4+u8bbTQGNkewUBrLf+89vE0EFJBQp2f1crwUxZFboKTROF9ltZonY1CGepo7b0B
- fkx3TbWQy5X65g3ScuieqtClCI8WanPeNBJ48+JipJYO3ODVNBxnVaTuW/0FOIcahfqe
- sG5GvggHhzRz+Yeybsbnupmzxnw8Ez0BpMl3p7zcjHL7BGZDdOOX2Zbw3zfyYa5sg2nX
- UXYJT36zy2h39gxUsy9QkhQ76CG3w6omniohZpYidpojpiDjbOy0nKFky4kUe+YyA1fF
- 4IBhjAm6mH+uh6wHSG1qj+NAXHs0xDDJps16PbJwAgL7Qt9K5WW+R/UAYPmHFgaRIHOw
- /seA==
-X-Gm-Message-State: AO0yUKXRtoYO8Nfus6Ca8lhM39P1Xn6TGkhatEfoISd1YNOkTJJN2hW+
- xRphLgxlzNfCLcVPlpGK9dk=
-X-Google-Smtp-Source:
- AK7set9VnMEykugk8ZYnkXuqK41bX1dzlvKsAXHEjr8i2NZBld0buKhQLcGYEcwxnBgVTtC7eRGfXw==
-X-Received: by 2002:a1c:7c0b:0:b0:3e2:1dac:b071 with SMTP id
- x11-20020a1c7c0b000000b003e21dacb071mr178053wmc.13.1679505325582;
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net.
- [79.146.124.255])
- by smtp.gmail.com with ESMTPSA id
- v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.24
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Wed, 22 Mar 2023 10:15:25 -0700 (PDT)
-From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org,
- krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de,
- f.fainelli@gmail.com, jonas.gorski@gmail.com,
- william.zhang@broadcom.com, linux-clk@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>
-Subject: [PATCH v4 4/4] clk: bcm: Add BCM63268 timer clock and reset driver
-Date: Wed, 22 Mar 2023 18:15:15 +0100
-Message-Id: <20230322171515.120353-5-noltari@gmail.com>
-X-Mailer: git-send-email 2.30.2
-In-Reply-To: <20230322171515.120353-1-noltari@gmail.com>
-References: <20230322171515.120353-1-noltari@gmail.com>
-MIME-Version: 1.0
-Precedence: bulk
-List-ID: <linux-clk.vger.kernel.org>
-X-Mailing-List: linux-clk@vger.kernel.org
-
-Add driver for BCM63268 timer clock and reset controller.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- v4: add changes suggested by Stephen Boyd:
- - Usage of of_device_get_match_data() isn't needed.
- - Use devm_clk_hw_register_gate().
- - Drop clk_hw_unregister_gate().
- v3: add missing <linux/io.h> include to fix build warning
- v2: add changes suggested by Stephen Boyd
-
- drivers/clk/bcm/Kconfig | 9 ++
- drivers/clk/bcm/Makefile | 1 +
- drivers/clk/bcm/clk-bcm63268-timer.c | 215 +++++++++++++++++++++++++++
- 3 files changed, 225 insertions(+)
- create mode 100644 drivers/clk/bcm/clk-bcm63268-timer.c
-
---- a/drivers/clk/bcm/Kconfig
-+++ b/drivers/clk/bcm/Kconfig
-@@ -37,6 +37,15 @@ config CLK_BCM_63XX_GATE
- Enable common clock framework support for Broadcom BCM63xx DSL SoCs
- based on the MIPS architecture
-
-+config CLK_BCM63268_TIMER
-+ bool "Broadcom BCM63268 timer clock and reset support"
-+ depends on BMIPS_GENERIC || COMPILE_TEST
-+ default BMIPS_GENERIC
-+ select RESET_CONTROLLER
-+ help
-+ Enable timer clock and reset support for Broadcom BCM63268 DSL SoCs
-+ based on the MIPS architecture.
-+
- config CLK_BCM_KONA
- bool "Broadcom Kona CCU clock support"
- depends on ARCH_BCM_MOBILE || COMPILE_TEST
---- a/drivers/clk/bcm/Makefile
-+++ b/drivers/clk/bcm/Makefile
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o
- obj-$(CONFIG_CLK_BCM_63XX_GATE) += clk-bcm63xx-gate.o
-+obj-$(CONFIG_CLK_BCM63268_TIMER) += clk-bcm63268-timer.o
- obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o
- obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o
- obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
---- /dev/null
-+++ b/drivers/clk/bcm/clk-bcm63268-timer.c
-@@ -0,0 +1,215 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * BCM63268 Timer Clock and Reset Controller Driver
-+ *
-+ * Copyright (C) 2023 Álvaro Fernández Rojas <noltari@gmail.com>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset-controller.h>
-+
-+#include <dt-bindings/clock/bcm63268-clock.h>
-+
-+#define BCM63268_TIMER_RESET_SLEEP_MIN_US 10000
-+#define BCM63268_TIMER_RESET_SLEEP_MAX_US 20000
-+
-+struct bcm63268_tclkrst_hw {
-+ void __iomem *regs;
-+ spinlock_t lock;
-+
-+ struct reset_controller_dev rcdev;
-+ struct clk_hw_onecell_data data;
-+};
-+
-+struct bcm63268_tclk_table_entry {
-+ const char * const name;
-+ u8 bit;
-+};
-+
-+static const struct bcm63268_tclk_table_entry bcm63268_timer_clocks[] = {
-+ {
-+ .name = "ephy1",
-+ .bit = BCM63268_TCLK_EPHY1,
-+ }, {
-+ .name = "ephy2",
-+ .bit = BCM63268_TCLK_EPHY2,
-+ }, {
-+ .name = "ephy3",
-+ .bit = BCM63268_TCLK_EPHY3,
-+ }, {
-+ .name = "gphy1",
-+ .bit = BCM63268_TCLK_GPHY1,
-+ }, {
-+ .name = "dsl",
-+ .bit = BCM63268_TCLK_DSL,
-+ }, {
-+ .name = "wakeon_ephy",
-+ .bit = BCM63268_TCLK_WAKEON_EPHY,
-+ }, {
-+ .name = "wakeon_dsl",
-+ .bit = BCM63268_TCLK_WAKEON_DSL,
-+ }, {
-+ .name = "fap1_pll",
-+ .bit = BCM63268_TCLK_FAP1,
-+ }, {
-+ .name = "fap2_pll",
-+ .bit = BCM63268_TCLK_FAP2,
-+ }, {
-+ .name = "uto_50",
-+ .bit = BCM63268_TCLK_UTO_50,
-+ }, {
-+ .name = "uto_extin",
-+ .bit = BCM63268_TCLK_UTO_EXTIN,
-+ }, {
-+ .name = "usb_ref",
-+ .bit = BCM63268_TCLK_USB_REF,
-+ }, {
-+ /* sentinel */
-+ }
-+};
-+
-+static inline struct bcm63268_tclkrst_hw *
-+to_bcm63268_timer_reset(struct reset_controller_dev *rcdev)
-+{
-+ return container_of(rcdev, struct bcm63268_tclkrst_hw, rcdev);
-+}
-+
-+static int bcm63268_timer_reset_update(struct reset_controller_dev *rcdev,
-+ unsigned long id, bool assert)
-+{
-+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev);
-+ unsigned long flags;
-+ uint32_t val;
-+
-+ spin_lock_irqsave(&reset->lock, flags);
-+ val = __raw_readl(reset->regs);
-+ if (assert)
-+ val &= ~BIT(id);
-+ else
-+ val |= BIT(id);
-+ __raw_writel(val, reset->regs);
-+ spin_unlock_irqrestore(&reset->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int bcm63268_timer_reset_assert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return bcm63268_timer_reset_update(rcdev, id, true);
-+}
-+
-+static int bcm63268_timer_reset_deassert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return bcm63268_timer_reset_update(rcdev, id, false);
-+}
-+
-+static int bcm63268_timer_reset_reset(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ bcm63268_timer_reset_update(rcdev, id, true);
-+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US,
-+ BCM63268_TIMER_RESET_SLEEP_MAX_US);
-+
-+ bcm63268_timer_reset_update(rcdev, id, false);
-+ /*
-+ * Ensure component is taken out reset state by sleeping also after
-+ * deasserting the reset. Otherwise, the component may not be ready
-+ * for operation.
-+ */
-+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US,
-+ BCM63268_TIMER_RESET_SLEEP_MAX_US);
-+
-+ return 0;
-+}
-+
-+static int bcm63268_timer_reset_status(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev);
-+
-+ return !(__raw_readl(reset->regs) & BIT(id));
-+}
-+
-+static struct reset_control_ops bcm63268_timer_reset_ops = {
-+ .assert = bcm63268_timer_reset_assert,
-+ .deassert = bcm63268_timer_reset_deassert,
-+ .reset = bcm63268_timer_reset_reset,
-+ .status = bcm63268_timer_reset_status,
-+};
-+
-+static int bcm63268_tclk_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ const struct bcm63268_tclk_table_entry *entry;
-+ struct bcm63268_tclkrst_hw *hw;
-+ struct clk_hw *clk;
-+ u8 maxbit = 0;
-+ int i, ret;
-+
-+ for (entry = bcm63268_timer_clocks; entry->name; entry++)
-+ maxbit = max(maxbit, entry->bit);
-+ maxbit++;
-+
-+ hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
-+ GFP_KERNEL);
-+ if (!hw)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, hw);
-+
-+ spin_lock_init(&hw->lock);
-+
-+ hw->data.num = maxbit;
-+ for (i = 0; i < maxbit; i++)
-+ hw->data.hws[i] = ERR_PTR(-ENODEV);
-+
-+ hw->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(hw->regs))
-+ return PTR_ERR(hw->regs);
-+
-+ for (entry = bcm63268_timer_clocks; entry->name; entry++) {
-+ clk = devm_clk_hw_register_gate(dev, entry->name, NULL, 0,
-+ hw->regs, entry->bit,
-+ CLK_GATE_BIG_ENDIAN,
-+ &hw->lock);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+
-+ hw->data.hws[entry->bit] = clk;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
-+ &hw->data);
-+ if (ret)
-+ return ret;
-+
-+ hw->rcdev.of_node = dev->of_node;
-+ hw->rcdev.ops = &bcm63268_timer_reset_ops;
-+
-+ ret = devm_reset_controller_register(dev, &hw->rcdev);
-+ if (ret)
-+ dev_err(dev, "Failed to register reset controller\n");
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id bcm63268_tclk_dt_ids[] = {
-+ { .compatible = "brcm,bcm63268-timer-clocks" },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver bcm63268_tclk = {
-+ .probe = bcm63268_tclk_probe,
-+ .driver = {
-+ .name = "bcm63268-timer-clock",
-+ .of_match_table = bcm63268_tclk_dt_ids,
-+ },
-+};
-+builtin_platform_driver(bcm63268_tclk);
diff --git a/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch b/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch
deleted file mode 100644
index 013261cb8f..0000000000
--- a/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 629c701fc39f1ada9416e0766a86729e83bde86c Mon Sep 17 00:00:00 2001
-Message-ID: <629c701fc39f1ada9416e0766a86729e83bde86c.1694465766.git.daniel@makrotopia.org>
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 11 Sep 2023 21:27:44 +0100
-Subject: [PATCH] serial: 8250_mtk: track busclk state to avoid bus error
-To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
- Jiri Slaby <jirislaby@kernel.org>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- Daniel Golle <daniel@makrotopia.org>,
- John Ogness <john.ogness@linutronix.de>,
- Chen-Yu Tsai <wenst@chromium.org>,
- Changqi Hu <changqi.hu@mediatek.com>,
- linux-kernel@vger.kernel.org,
- linux-serial@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org
-
-Commit e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and
-clock management") introduced polling a debug register to make sure
-the UART is idle before disabling the bus clock. However, at least on
-some MediaTek SoCs access to that very debug register requires the bus
-clock being enabled. Hence calling the suspend function while already
-in suspended state results in that register access triggering a bus
-error. In order to avoid that, track the state of the bus clock and
-only poll the debug register if not already in suspended state.
-
-Fixes: e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and clock management")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/tty/serial/8250/8250_mtk.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
---- a/drivers/tty/serial/8250/8250_mtk.c
-+++ b/drivers/tty/serial/8250/8250_mtk.c
-@@ -32,7 +32,7 @@
- #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */
- #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */
- #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */
--#define MTK_UART_DEBUG0 0x18
-+#define MTK_UART_DEBUG0 0x18
- #define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */
- #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */
- #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */
-@@ -422,13 +422,12 @@ static int __maybe_unused mtk8250_runtim
- struct mtk8250_data *data = dev_get_drvdata(dev);
- struct uart_8250_port *up = serial8250_get_port(data->line);
-
-- /* wait until UART in idle status */
-- while
-- (serial_in(up, MTK_UART_DEBUG0));
--
- if (data->clk_count == 0U) {
- dev_dbg(dev, "%s clock count is 0\n", __func__);
- } else {
-+ /* wait until UART in idle status */
-+ while
-+ (serial_in(up, MTK_UART_DEBUG0));
- clk_disable_unprepare(data->bus_clk);
- data->clk_count--;
- }
diff --git a/target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch b/target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch
deleted file mode 100644
index e25389363f..0000000000
--- a/target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From d0562705bcd4cb9849156f095b2af0ec1bb53b56 Mon Sep 17 00:00:00 2001
-From: Lech Perczak <lech.perczak@gmail.com>
-Date: Fri, 17 Nov 2023 21:33:04 +0100
-Subject: [PATCH] ARM: dts: nxp: imx7d-pico: add cpu-supply nodes
-
-The PICO-IMX7D SoM has the usual power supply configuration using
-output sw1a of PF3000 PMIC, which was defined in downstream derivative
-of linux-imx (see link) in the sources for "Android Things" devkit.
-It is required to support CPU frequency scaling.
-
-Map the respective "cpu-supply" nodes of each core to sw1a of the PMIC.
-
-Enabling them causes cpufreq-dt, and imx-thermal drivers to probe
-successfully, and CPU frequency scaling to function.
-
-Link: https://android.googlesource.com/platform/hardware/bsp/kernel/nxp/imx-v4.1/+/o-iot-preview-5/arch/arm/boot/dts/imx7d-pico.dtsi#849
-
-Cc: Fabio Estevam <festevam@gmail.com>
-Cc: Shawn Guo <shawnguo@kernel.org>
-Cc: Sascha Hauer <s.hauer@pengutronix.de>
-
-Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
----
- arch/arm/boot/dts/imx7d-pico.dtsi | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/imx7d-pico.dtsi
-+++ b/arch/arm/boot/dts/imx7d-pico.dtsi
-@@ -108,6 +108,14 @@
- assigned-clock-rates = <0>, <32768>;
- };
-
-+&cpu0 {
-+ cpu-supply = <&sw1a_reg>;
-+};
-+
-+&cpu1 {
-+ cpu-supply = <&sw1a_reg>;
-+};
-+
- &ecspi3 {
- cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>;
- pinctrl-names = "default";
diff --git a/target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch b/target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch
deleted file mode 100644
index 3321b03f28..0000000000
--- a/target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 38eb5b3370c29515d2ce92adac2d6eba96f276f5 Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Wed, 20 Mar 2024 15:32:18 +0900
-Subject: [PATCH v2 1/2] dt-bindings: leds: add LED_FUNCTION_MOBILE for mobile
- network
-
-Add LED_FUNCTION_MOBILE for LEDs that indicate status of mobile network
-connection. This is useful to distinguish those LEDs from LEDs that
-indicates status of wired "wan" connection.
-
-example (on stock fw):
-
-IIJ SA-W2 has "Mobile" LEDs that indicate status (no signal, too low,
-low, good) of mobile network connection via dongle connected to USB
-port.
-
-- no signal: (none, turned off)
-- too low: green:mobile & red:mobile (amber, blink)
-- low: green:mobile & red:mobile (amber, turned on)
-- good: green:mobile (turned on)
-
-Suggested-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- include/dt-bindings/leds/common.h | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -90,6 +90,7 @@
- #define LED_FUNCTION_INDICATOR "indicator"
- #define LED_FUNCTION_LAN "lan"
- #define LED_FUNCTION_MAIL "mail"
-+#define LED_FUNCTION_MOBILE "mobile"
- #define LED_FUNCTION_MTD "mtd"
- #define LED_FUNCTION_PANIC "panic"
- #define LED_FUNCTION_PROGRAMMING "programming"
diff --git a/target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch b/target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch
deleted file mode 100644
index ab27cd3399..0000000000
--- a/target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From e22afe910afcfb51b6ba6a0ae776939959727f54 Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Wed, 20 Mar 2024 15:59:06 +0900
-Subject: [PATCH v2 2/2] dt-bindings: leds: add LED_FUNCTION_SPEED_* for link
- speed on LAN/WAN
-
-Add LED_FUNCTION_SPEED_LAN and LED_FUNCTION_SPEED_WAN for LEDs that
-indicate link speed of ethernet ports on LAN/WAN. This is useful to
-distinguish those LEDs from LEDs that indicate link status (up/down).
-
-example:
-
-Fortinet FortiGate 30E/50E have LEDs that indicate link speed on each
-of the ethernet ports in addition to LEDs that indicate link status
-(up/down).
-
-- 1000 Mbps: green:speed-(lan|wan)-N
-- 100 Mbps: amber:speed-(lan|wan)-N
-- 10 Mbps: (none, turned off)
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- include/dt-bindings/leds/common.h | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/include/dt-bindings/leds/common.h
-+++ b/include/dt-bindings/leds/common.h
-@@ -96,6 +96,8 @@
- #define LED_FUNCTION_PROGRAMMING "programming"
- #define LED_FUNCTION_RX "rx"
- #define LED_FUNCTION_SD "sd"
-+#define LED_FUNCTION_SPEED_LAN "speed-lan"
-+#define LED_FUNCTION_SPEED_WAN "speed-wan"
- #define LED_FUNCTION_STANDBY "standby"
- #define LED_FUNCTION_TORCH "torch"
- #define LED_FUNCTION_TX "tx"
diff --git a/target/linux/generic/pending-6.1/920-mangle_bootargs.patch b/target/linux/generic/pending-6.1/920-mangle_bootargs.patch
deleted file mode 100644
index f239c5824f..0000000000
--- a/target/linux/generic/pending-6.1/920-mangle_bootargs.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Imre Kaloz <kaloz@openwrt.org>
-Subject: init: add CONFIG_MANGLE_BOOTARGS and disable it by default
-
-Enabling this option renames the bootloader supplied root=
-and rootfstype= variables, which might have to be know but
-would break the automatisms OpenWrt uses.
-
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
- init/Kconfig | 9 +++++++++
- init/main.c | 24 ++++++++++++++++++++++++
- 2 files changed, 33 insertions(+)
-
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1836,6 +1836,15 @@ config EMBEDDED
- an embedded system so certain expert options are available
- for configuration.
-
-+config MANGLE_BOOTARGS
-+ bool "Rename offending bootargs"
-+ depends on EXPERT
-+ help
-+ Sometimes the bootloader passed bogus root= and rootfstype=
-+ parameters to the kernel, and while you want to ignore them,
-+ you need to know the values f.e. to support dual firmware
-+ layouts on the flash.
-+
- config HAVE_PERF_EVENTS
- bool
- help
---- a/init/main.c
-+++ b/init/main.c
-@@ -611,6 +611,29 @@ static inline void setup_nr_cpu_ids(void
- static inline void smp_prepare_cpus(unsigned int maxcpus) { }
- #endif
-
-+#ifdef CONFIG_MANGLE_BOOTARGS
-+static void __init mangle_bootargs(char *command_line)
-+{
-+ char *rootdev;
-+ char *rootfs;
-+
-+ rootdev = strstr(command_line, "root=/dev/mtdblock");
-+
-+ if (rootdev)
-+ strncpy(rootdev, "mangled_rootblock=", 18);
-+
-+ rootfs = strstr(command_line, "rootfstype");
-+
-+ if (rootfs)
-+ strncpy(rootfs, "mangled_fs", 10);
-+
-+}
-+#else
-+static void __init mangle_bootargs(char *command_line)
-+{
-+}
-+#endif
-+
- /*
- * We need to store the untouched command line for future reference.
- * We also need to store the touched command line since the parameter
-@@ -960,6 +983,7 @@ asmlinkage __visible void __init __no_sa
- pr_notice("%s", linux_banner);
- early_security_init();
- setup_arch(&command_line);
-+ mangle_bootargs(command_line);
- setup_boot_config();
- setup_command_line(command_line);
- setup_nr_cpu_ids();
diff --git a/target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch b/target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch
deleted file mode 100644
index 6a0a19987f..0000000000
--- a/target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From a7a94ca21ac0f347f683d33c72b4aab57ce5eec3 Mon Sep 17 00:00:00 2001
-From: Florian Eckert <fe@dev.tdt.de>
-Date: Mon, 20 Nov 2023 11:13:20 +0100
-Subject: [PATCH] tools/thermal/tmon: Fix compilation warning for wrong format
-
-The following warnings are shown during compilation:
-
-tui.c: In function 'show_cooling_device':
- tui.c:216:40: warning: format '%d' expects argument of type 'int', but
-argument 7 has type 'long unsigned int' [-Wformat=]
- 216 | "%02d %12.12s%6d %6d",
- | ~~^
- | |
- | int
- | %6ld
- ......
- 219 | ptdata.cdi[j].cur_state,
- | ~~~~~~~~~~~~~~~~~~~~~~~
- | |
- | long unsigned int
- tui.c:216:44: warning: format '%d' expects argument of type 'int', but
-argument 8 has type 'long unsigned int' [-Wformat=]
- 216 | "%02d %12.12s%6d %6d",
- | ~~^
- | |
- | int
- | %6ld
- ......
- 220 | ptdata.cdi[j].max_state);
- | ~~~~~~~~~~~~~~~~~~~~~~~
- | |
- | long unsigned int
-
-To fix this, the correct string format must be used for printing.
-
-Signed-off-by: Florian Eckert <fe@dev.tdt.de>
----
- tools/thermal/tmon/tui.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/tools/thermal/tmon/tui.c
-+++ b/tools/thermal/tmon/tui.c
-@@ -213,7 +213,7 @@ void show_cooling_device(void)
- * cooling device instances. skip unused idr.
- */
- mvwprintw(cooling_device_window, j + 2, 1,
-- "%02d %12.12s%6d %6d",
-+ "%02d %12.12s%6lu %6lu",
- ptdata.cdi[j].instance,
- ptdata.cdi[j].type,
- ptdata.cdi[j].cur_state,
diff --git a/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch
new file mode 100644
index 0000000000..aeac79c023
--- /dev/null
+++ b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch
@@ -0,0 +1,63 @@
+From patchwork Mon Aug 12 01:56:41 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 1971406
+Return-Path:
+ <linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>
+X-Original-To: incoming@patchwork.ozlabs.org
+Delivered-To: patchwork-incoming@legolas.ozlabs.org
+Date: Mon, 12 Aug 2024 02:56:41 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+To: Miquel Raynal <miquel.raynal@bootlin.com>,
+ Richard Weinberger <richard@nod.at>,
+ Vignesh Raghavendra <vigneshr@ti.com>,
+ Tudor Ambarus <tudor.ambarus@linaro.org>,
+ Daniel Golle <daniel@makrotopia.org>,
+ Mika Westerberg <mika.westerberg@linux.intel.com>,
+ Chia-Lin Kao <acelan.kao@canonical.com>,
+ Martin Kurbanov <mmkurbanov@salutedevices.com>,
+ linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org
+Subject: [PATCH] mtd: spinand: set bitflip_threshold to 75% of ECC strength
+Message-ID:
+ <2117e387260b0a96f95b8e1652ff79e0e2d71d53.1723427450.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+X-BeenThere: linux-mtd@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mtd>,
+ <mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-mtd/>
+List-Post: <mailto:linux-mtd@lists.infradead.org>
+List-Help: <mailto:linux-mtd-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>,
+ <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>
+Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org>
+Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org
+
+Reporting an unclean read from SPI-NAND only when the maximum number
+of correctable bitflip errors has been hit seems a bit late.
+UBI LEB scrubbing, which depends on the lower MTD device reporting
+correctable bitflips, then only kicks in when it's almost too late.
+
+Set bitflip_threshold to 75% of the ECC strength, which is also the
+default for raw NAND.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/mtd/nand/spi/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1286,6 +1286,7 @@ static int spinand_init(struct spinand_d
+ /* Propagate ECC information to mtd_info */
+ mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
+ mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;
++ mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4);
+
+ ret = spinand_create_dirmaps(spinand);
+ if (ret) {
diff --git a/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch b/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch
index 2aef22879d..e279b71173 100644
--- a/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch
+++ b/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch
@@ -1,15 +1,42 @@
-From 7f4c9c534aabe1315669e076d3fe0af0fd374cda Mon Sep 17 00:00:00 2001
+From patchwork Tue Jul 30 19:25:59 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13747816
+Date: Tue, 30 Jul 2024 20:25:59 +0100
From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 30 May 2024 03:13:19 +0100
-Subject: [PATCH 2/9] block: partitions: populate fwnode
+To: Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
+ Conor Dooley <conor+dt@kernel.org>, Jens Axboe <axboe@kernel.dk>,
+ Daniel Golle <daniel@makrotopia.org>, Christian Brauner <brauner@kernel.org>,
+ Al Viro <viro@zeniv.linux.org.uk>, Li Lingfeng <lilingfeng3@huawei.com>,
+ Ming Lei <ming.lei@redhat.com>, Christian Heusel <christian@heusel.eu>,
+ =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= <rafal@milecki.pl>,
+ Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
+ Chad Monroe <chad.monroe@adtran.com>, Yangyu Chen <cyy@cyyself.name>,
+ Tianling Shen <cnsztl@immortalwrt.org>, Chuanhong Guo <gch981213@gmail.com>,
+ Chen Minqiang <ptpt52@gmail.com>, devicetree@vger.kernel.org,
+ linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
+Subject: [PATCH v5 2/4] block: partitions: populate fwnode
+Message-ID:
+ <3051ac090ad3b3e2f5adb6b67c923261ead729a5.1722365899.git.daniel@makrotopia.org>
+References: <cover.1722365899.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: linux-block@vger.kernel.org
+List-Id: <linux-block.vger.kernel.org>
+List-Subscribe: <mailto:linux-block+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-block+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1722365899.git.daniel@makrotopia.org>
-Let block partitions to be represented by a firmware node and hence
-allow them to being referenced e.g. for use with blk-nvmem.
+Assign matching firmware nodes to block partitions in order to allow
+them to be referenced e.g. as NVMEM providers.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
- block/partitions/core.c | 41 +++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
+ block/partitions/core.c | 72 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -22,36 +49,70 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#include "check.h"
static int (*const check_part[])(struct parsed_partitions *) = {
-@@ -292,6 +294,40 @@ static ssize_t whole_disk_show(struct de
+@@ -292,6 +294,74 @@ static ssize_t whole_disk_show(struct de
}
static const DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL);
++static bool part_meta_match(const char *attr, const char *member, size_t length)
++{
++ /* check if length of attr exceeds specified maximum length */
++ if (strnlen(attr, length) == length)
++ return false;
++
++ /* return true if strings match */
++ return !strncmp(attr, member, length);
++}
++
+static struct fwnode_handle *find_partition_fwnode(struct block_device *bdev)
+{
+ struct fwnode_handle *fw_parts, *fw_part;
+ struct device *ddev = disk_to_dev(bdev->bd_disk);
+ const char *partname, *uuid;
+ u32 partno;
++ bool got_uuid, got_partname, got_partno;
+
+ fw_parts = device_get_named_child_node(ddev, "partitions");
+ if (!fw_parts)
+ return NULL;
+
+ fwnode_for_each_child_node(fw_parts, fw_part) {
-+ if (!fwnode_property_read_string(fw_part, "uuid", &uuid) &&
-+ (!bdev->bd_meta_info || strncmp(uuid,
-+ bdev->bd_meta_info->uuid,
-+ PARTITION_META_INFO_UUIDLTH)))
++ got_uuid = false;
++ got_partname = false;
++ got_partno = false;
++ /*
++ * In case 'uuid' is defined in the partitions firmware node
++ * require partition meta info being present and the specified
++ * uuid to match.
++ */
++ got_uuid = !fwnode_property_read_string(fw_part, "uuid", &uuid);
++ if (got_uuid && (!bdev->bd_meta_info ||
++ !part_meta_match(uuid, bdev->bd_meta_info->uuid,
++ PARTITION_META_INFO_UUIDLTH)))
++ continue;
++
++ /*
++ * In case 'partname' is defined in the partitions firmware node
++ * require partition meta info being present and the specified
++ * volname to match.
++ */
++ got_partname = !fwnode_property_read_string(fw_part, "partname",
++ &partname);
++ if (got_partname && (!bdev->bd_meta_info ||
++ !part_meta_match(partname,
++ bdev->bd_meta_info->volname,
++ PARTITION_META_INFO_VOLNAMELTH)))
+ continue;
+
-+ if (!fwnode_property_read_string(fw_part, "partname", &partname) &&
-+ (!bdev->bd_meta_info || strncmp(partname,
-+ bdev->bd_meta_info->volname,
-+ PARTITION_META_INFO_VOLNAMELTH)))
++ /*
++ * In case 'partno' is defined in the partitions firmware node
++ * the specified partno needs to match.
++ */
++ got_partno = !fwnode_property_read_u32(fw_part, "partno", &partno);
++ if (got_partno && bdev->bd_partno != partno)
+ continue;
+
-+ if (!fwnode_property_read_u32(fw_part, "partno", &partno) &&
-+ bdev->bd_partno != partno)
++ /* Skip if no matching criteria is present in firmware node */
++ if (!got_uuid && !got_partname && !got_partno)
+ continue;
+
+ return fw_part;
@@ -63,7 +124,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/*
* Must be called either with open_mutex held, before a disk can be opened or
* after all disk users are gone.
-@@ -374,6 +410,8 @@ static struct block_device *add_partitio
+@@ -374,6 +444,8 @@ static struct block_device *add_partitio
goto out_put;
}
diff --git a/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch b/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch
index c5a3391e45..cad3fbfa90 100644
--- a/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch
+++ b/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch
@@ -1,7 +1,34 @@
-From e07ace307ce598847074a096f408bec0e3a392ed Mon Sep 17 00:00:00 2001
+From patchwork Tue Jul 30 19:26:42 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13747817
+Date: Tue, 30 Jul 2024 20:26:42 +0100
From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 30 May 2024 03:14:34 +0100
-Subject: [PATCH 3/9] block: add support for notifications
+To: Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
+ Conor Dooley <conor+dt@kernel.org>, Jens Axboe <axboe@kernel.dk>,
+ Daniel Golle <daniel@makrotopia.org>, Christian Brauner <brauner@kernel.org>,
+ Al Viro <viro@zeniv.linux.org.uk>, Li Lingfeng <lilingfeng3@huawei.com>,
+ Ming Lei <ming.lei@redhat.com>, Christian Heusel <christian@heusel.eu>,
+ =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= <rafal@milecki.pl>,
+ Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
+ Chad Monroe <chad.monroe@adtran.com>, Yangyu Chen <cyy@cyyself.name>,
+ Tianling Shen <cnsztl@immortalwrt.org>, Chuanhong Guo <gch981213@gmail.com>,
+ Chen Minqiang <ptpt52@gmail.com>, devicetree@vger.kernel.org,
+ linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
+Subject: [PATCH v5 3/4] block: add support for notifications
+Message-ID:
+ <ca0022886e8f211a323a716653a1396a3bc91653.1722365899.git.daniel@makrotopia.org>
+References: <cover.1722365899.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: linux-block@vger.kernel.org
+List-Id: <linux-block.vger.kernel.org>
+List-Subscribe: <mailto:linux-block+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-block+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1722365899.git.daniel@makrotopia.org>
Add notifier block to notify other subsystems about the addition or
removal of block devices.
@@ -10,9 +37,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
block/Kconfig | 6 +++
block/Makefile | 1 +
- block/blk-notify.c | 88 ++++++++++++++++++++++++++++++++++++++++++
- include/linux/blkdev.h | 8 ++++
- 4 files changed, 103 insertions(+)
+ block/blk-notify.c | 87 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/blkdev.h | 11 ++++++
+ 4 files changed, 105 insertions(+)
create mode 100644 block/blk-notify.c
--- a/block/Kconfig
@@ -39,7 +66,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+obj-$(CONFIG_BLOCK_NOTIFIERS) += blk-notify.o
--- /dev/null
+++ b/block/blk-notify.c
-@@ -0,0 +1,88 @@
+@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Notifiers for addition and removal of block devices
@@ -97,7 +124,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ list_add_tail(&new_blkdev->list, &blk_devices);
+ raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_ADD, dev);
+ mutex_unlock(&blk_notifier_lock);
-+
+ return 0;
+}
+
@@ -130,16 +156,19 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+device_initcall(blk_notifications_init);
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
-@@ -1564,4 +1564,12 @@ struct io_comp_batch {
+@@ -1564,4 +1564,15 @@ struct io_comp_batch {
#define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
+
-+#ifdef CONFIG_BLOCK_NOTIFIERS
+#define BLK_DEVICE_ADD 1
+#define BLK_DEVICE_REMOVE 2
++#if defined(CONFIG_BLOCK_NOTIFIERS)
+void blk_register_notify(struct notifier_block *nb);
+void blk_unregister_notify(struct notifier_block *nb);
++#else
++static inline void blk_register_notify(struct notifier_block *nb) { };
++static inline void blk_unregister_notify(struct notifier_block *nb) { };
+#endif
+
#endif /* _LINUX_BLKDEV_H */
diff --git a/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
index 5997680e47..79abcd0e6b 100644
--- a/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
+++ b/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
@@ -1,7 +1,34 @@
-From f4487fa1cb7e55b3c17a33f41b9c9d66f4f853b7 Mon Sep 17 00:00:00 2001
+From patchwork Tue Jul 30 19:27:07 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13747818
+Date: Tue, 30 Jul 2024 20:27:07 +0100
From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 30 May 2024 03:14:49 +0100
-Subject: [PATCH 4/9] block: add new genhd flag GENHD_FL_NVMEM
+To: Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
+ Conor Dooley <conor+dt@kernel.org>, Jens Axboe <axboe@kernel.dk>,
+ Daniel Golle <daniel@makrotopia.org>, Christian Brauner <brauner@kernel.org>,
+ Al Viro <viro@zeniv.linux.org.uk>, Li Lingfeng <lilingfeng3@huawei.com>,
+ Ming Lei <ming.lei@redhat.com>, Christian Heusel <christian@heusel.eu>,
+ =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= <rafal@milecki.pl>,
+ Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
+ Chad Monroe <chad.monroe@adtran.com>, Yangyu Chen <cyy@cyyself.name>,
+ Tianling Shen <cnsztl@immortalwrt.org>, Chuanhong Guo <gch981213@gmail.com>,
+ Chen Minqiang <ptpt52@gmail.com>, devicetree@vger.kernel.org,
+ linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
+Subject: [PATCH v5 4/4] block: add new genhd flag GENHD_FL_NVMEM
+Message-ID:
+ <311ea569c23ce14e2896cd3b069dc494c58c49c2.1722365899.git.daniel@makrotopia.org>
+References: <cover.1722365899.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: linux-block@vger.kernel.org
+List-Id: <linux-block.vger.kernel.org>
+List-Subscribe: <mailto:linux-block+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-block+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1722365899.git.daniel@makrotopia.org>
Add new flag to destinguish block devices which may act as an NVMEM
provider.
diff --git a/target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch b/target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch
new file mode 100644
index 0000000000..b72e28a3dd
--- /dev/null
+++ b/target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch
@@ -0,0 +1,63 @@
+From 446daf20b0a6790751459cdde0ff9fc8813e54d1 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robimarko@gmail.com>
+Date: Mon, 29 Jul 2024 14:09:16 +0200
+Subject: [PATCH] mtd: spinand: winbond: add support for W25N01KV
+
+Add support for Winbond W25N01KV 1Gbit SPI-NAND.
+
+It has 4-bit on-die ECC.
+
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+---
+ drivers/mtd/nand/spi/winbond.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/drivers/mtd/nand/spi/winbond.c
++++ b/drivers/mtd/nand/spi/winbond.c
+@@ -76,6 +76,18 @@ static int w25m02gv_select_target(struct
+ return spi_mem_exec_op(spinand->spimem, &op);
+ }
+
++static int w25n01kv_ooblayout_ecc(struct mtd_info *mtd, int section,
++ struct mtd_oob_region *region)
++{
++ if (section > 3)
++ return -ERANGE;
++
++ region->offset = 64 + (8 * section);
++ region->length = 7;
++
++ return 0;
++}
++
+ static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+ {
+@@ -100,6 +112,11 @@ static int w25n02kv_ooblayout_free(struc
+ return 0;
+ }
+
++static const struct mtd_ooblayout_ops w25n01kv_ooblayout = {
++ .ecc = w25n01kv_ooblayout_ecc,
++ .free = w25n02kv_ooblayout_free,
++};
++
+ static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
+ .ecc = w25n02kv_ooblayout_ecc,
+ .free = w25n02kv_ooblayout_free,
+@@ -163,6 +180,15 @@ static const struct spinand_info winbond
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
++ SPINAND_INFO("W25N01KV",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
++ NAND_MEMORG(1, 2048, 96, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)),
+ SPINAND_INFO("W25N02KV",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
diff --git a/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
index 6081d1d9e5..0b607faa5e 100644
--- a/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
+++ b/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ return magic == UBIFS_NODE_MAGIC;
+}
+
-+static void __init ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
++static void ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
+{
+ int ret, is_ubifs;
+ struct ubi_volume_desc *desc;
diff --git a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch
index 26ef29ca87..ff38964ece 100644
--- a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch
+++ b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch
@@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -22014,6 +22014,12 @@ F: Documentation/filesystems/ubifs-authe
+@@ -22015,6 +22015,12 @@ F: Documentation/filesystems/ubifs-authe
F: Documentation/filesystems/ubifs.rst
F: fs/ubifs/
@@ -668,7 +668,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ (imgmaxsect + MIN_FREE_SECT) < dsectors) {
+ add_fit_subimage_device(bdev, slot++, imgmaxsect,
+ dsectors - imgmaxsect, false);
-+ dev_info(dev, "mapped remaing space as /dev/fitrw\n");
++ dev_info(dev, "mapped remaining space as /dev/fitrw\n");
+ }
+
+out_bootconf:
diff --git a/target/linux/generic/pending-6.6/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-6.6/530-jffs2_make_lzma_available.patch
index 3be6c8eb9d..66c458d7e6 100644
--- a/target/linux/generic/pending-6.6/530-jffs2_make_lzma_available.patch
+++ b/target/linux/generic/pending-6.6/530-jffs2_make_lzma_available.patch
@@ -254,7 +254,7 @@ Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
+}
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
-@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void)
+@@ -375,14 +375,41 @@ static int __init init_jffs2_fs(void)
BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
diff --git a/target/linux/generic/pending-6.6/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-6.6/600-netfilter_conntrack_flush.patch
index f6c3783219..52e97e46ef 100644
--- a/target/linux/generic/pending-6.6/600-netfilter_conntrack_flush.patch
+++ b/target/linux/generic/pending-6.6/600-netfilter_conntrack_flush.patch
@@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#include <net/net_namespace.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
-@@ -461,6 +462,58 @@ static int ct_cpu_seq_show(struct seq_fi
+@@ -458,6 +459,58 @@ static int ct_cpu_seq_show(struct seq_fi
return 0;
}
@@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static const struct seq_operations ct_cpu_seq_ops = {
.start = ct_cpu_seq_start,
.next = ct_cpu_seq_next,
-@@ -474,8 +527,9 @@ static int nf_conntrack_standalone_init_
+@@ -471,8 +524,9 @@ static int nf_conntrack_standalone_init_
kuid_t root_uid;
kgid_t root_gid;
diff --git a/target/linux/generic/pending-6.6/630-packet_socket_type.patch b/target/linux/generic/pending-6.6/630-packet_socket_type.patch
index 10a312776f..2b753efa67 100644
--- a/target/linux/generic/pending-6.6/630-packet_socket_type.patch
+++ b/target/linux/generic/pending-6.6/630-packet_socket_type.patch
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#define PACKET_FANOUT_LB 1
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
-@@ -1864,6 +1864,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1925,6 +1925,7 @@ static int packet_rcv_spkt(struct sk_buf
{
struct sock *sk;
struct sockaddr_pkt *spkt;
@@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/*
* When we registered the protocol we saved the socket in the data
-@@ -1871,6 +1872,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1932,6 +1933,7 @@ static int packet_rcv_spkt(struct sk_buf
*/
sk = pt->af_packet_priv;
@@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/*
* Yank back the headers [hope the device set this
-@@ -1883,7 +1885,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1944,7 +1946,7 @@ static int packet_rcv_spkt(struct sk_buf
* so that this procedure is noop.
*/
@@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
goto out;
if (!net_eq(dev_net(dev), sock_net(sk)))
-@@ -2129,12 +2131,12 @@ static int packet_rcv(struct sk_buff *sk
+@@ -2190,12 +2192,12 @@ static int packet_rcv(struct sk_buff *sk
unsigned int snaplen, res;
bool is_drop_n_account = false;
@@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -2261,12 +2263,12 @@ static int tpacket_rcv(struct sk_buff *s
+@@ -2322,12 +2324,12 @@ static int tpacket_rcv(struct sk_buff *s
BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
@@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -3385,6 +3387,7 @@ static int packet_create(struct net *net
+@@ -3451,6 +3453,7 @@ static int packet_create(struct net *net
mutex_init(&po->pg_vec_lock);
po->rollover = NULL;
po->prot_hook.func = packet_rcv;
@@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
-@@ -4034,6 +4037,16 @@ packet_setsockopt(struct socket *sock, i
+@@ -4118,6 +4121,16 @@ packet_setsockopt(struct socket *sock, i
packet_sock_flag_set(po, PACKET_SOCK_QDISC_BYPASS, val);
return 0;
}
@@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
default:
return -ENOPROTOOPT;
}
-@@ -4093,6 +4106,13 @@ static int packet_getsockopt(struct sock
+@@ -4177,6 +4190,13 @@ static int packet_getsockopt(struct sock
case PACKET_VNET_HDR_SZ:
val = READ_ONCE(po->vnet_hdr_sz);
break;
diff --git a/target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch b/target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch
new file mode 100644
index 0000000000..cf55c6a3fb
--- /dev/null
+++ b/target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch
@@ -0,0 +1,42 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 22 Aug 2024 18:02:17 +0200
+Subject: [PATCH] net: bridge: fix switchdev host mdb entry updates
+
+When a mdb entry is removed, the bridge switchdev code can issue a
+switchdev_port_obj_del call for a port that was not offloaded.
+
+This leads to an imbalance in switchdev_port_obj_add/del calls, since
+br_switchdev_mdb_replay has not been called for the port before.
+
+This can lead to potential multicast forwarding issues and messages such as:
+mt7915e 0000:01:00.0 wl1-ap0: Failed to del Host Multicast Database entry
+ (object id=3) with error: -ENOENT (-2).
+
+Fix this issue by checking the port offload status when iterating over
+lower devs.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/bridge/br_switchdev.c
++++ b/net/bridge/br_switchdev.c
+@@ -568,10 +568,18 @@ static void br_switchdev_host_mdb(struct
+ struct net_bridge_mdb_entry *mp, int type)
+ {
+ struct net_device *lower_dev;
++ struct net_bridge_port *port;
+ struct list_head *iter;
+
+- netdev_for_each_lower_dev(dev, lower_dev, iter)
++ rcu_read_lock();
++ netdev_for_each_lower_dev(dev, lower_dev, iter) {
++ port = br_port_get_rcu(lower_dev);
++ if (!port || !port->offload_count)
++ continue;
++
+ br_switchdev_host_mdb_one(dev, lower_dev, mp, type);
++ }
++ rcu_read_unlock();
+ }
+
+ static int
diff --git a/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
index 0d65fa7272..863372ea87 100644
--- a/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
+++ b/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
@@ -338,7 +338,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
return -1;
-@@ -1543,6 +1704,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
+@@ -1544,6 +1705,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
t->parms.link = p->link;
t->parms.proto = p->proto;
t->parms.fwmark = p->fwmark;
@@ -353,7 +353,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
dst_cache_reset(&t->dst_cache);
ip6_tnl_link_config(t);
}
-@@ -1577,6 +1746,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
+@@ -1578,6 +1747,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
p->flowinfo = u->flowinfo;
p->link = u->link;
p->proto = u->proto;
@@ -361,7 +361,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
memcpy(p->name, u->name, sizeof(u->name));
}
-@@ -1964,6 +2134,15 @@ static int ip6_tnl_validate(struct nlatt
+@@ -1966,6 +2136,15 @@ static int ip6_tnl_validate(struct nlatt
return 0;
}
@@ -377,7 +377,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
static void ip6_tnl_netlink_parms(struct nlattr *data[],
struct __ip6_tnl_parm *parms)
{
-@@ -2001,6 +2180,46 @@ static void ip6_tnl_netlink_parms(struct
+@@ -2003,6 +2182,46 @@ static void ip6_tnl_netlink_parms(struct
if (data[IFLA_IPTUN_FWMARK])
parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
@@ -424,7 +424,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
}
static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
-@@ -2084,6 +2303,12 @@ static void ip6_tnl_dellink(struct net_d
+@@ -2086,6 +2305,12 @@ static void ip6_tnl_dellink(struct net_d
static size_t ip6_tnl_get_size(const struct net_device *dev)
{
@@ -437,7 +437,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
return
/* IFLA_IPTUN_LINK */
nla_total_size(4) +
-@@ -2113,6 +2338,24 @@ static size_t ip6_tnl_get_size(const str
+@@ -2115,6 +2340,24 @@ static size_t ip6_tnl_get_size(const str
nla_total_size(0) +
/* IFLA_IPTUN_FWMARK */
nla_total_size(4) +
@@ -462,7 +462,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
0;
}
-@@ -2120,6 +2363,9 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -2122,6 +2365,9 @@ static int ip6_tnl_fill_info(struct sk_b
{
struct ip6_tnl *tunnel = netdev_priv(dev);
struct __ip6_tnl_parm *parm = &tunnel->parms;
@@ -472,7 +472,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
-@@ -2129,9 +2375,27 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -2131,9 +2377,27 @@ static int ip6_tnl_fill_info(struct sk_b
nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) ||
@@ -501,7 +501,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
-@@ -2171,6 +2435,7 @@ static const struct nla_policy ip6_tnl_p
+@@ -2173,6 +2437,7 @@ static const struct nla_policy ip6_tnl_p
[IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
[IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
[IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
diff --git a/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
index 77a16bad9a..f754705dc6 100644
--- a/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
+++ b/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
@@ -66,7 +66,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
static void rt_fibinfo_free(struct rtable __rcu **rtp)
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -2783,6 +2783,7 @@ static const char *const rtn_type_names[
+@@ -2784,6 +2784,7 @@ static const char *const rtn_type_names[
[RTN_THROW] = "THROW",
[RTN_NAT] = "NAT",
[RTN_XRESOLVE] = "XRESOLVE",
@@ -138,7 +138,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
static const struct rt6_info ip6_blk_hole_entry_template = {
.dst = {
.__rcuref = RCUREF_INIT(1),
-@@ -1038,6 +1052,7 @@ static const int fib6_prop[RTN_MAX + 1]
+@@ -1040,6 +1054,7 @@ static const int fib6_prop[RTN_MAX + 1]
[RTN_BLACKHOLE] = -EINVAL,
[RTN_UNREACHABLE] = -EHOSTUNREACH,
[RTN_PROHIBIT] = -EACCES,
@@ -146,7 +146,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
[RTN_THROW] = -EAGAIN,
[RTN_NAT] = -EINVAL,
[RTN_XRESOLVE] = -EINVAL,
-@@ -1073,6 +1088,10 @@ static void ip6_rt_init_dst_reject(struc
+@@ -1075,6 +1090,10 @@ static void ip6_rt_init_dst_reject(struc
rt->dst.output = ip6_pkt_prohibit_out;
rt->dst.input = ip6_pkt_prohibit;
break;
@@ -157,7 +157,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
case RTN_THROW:
case RTN_UNREACHABLE:
default:
-@@ -4544,6 +4563,17 @@ static int ip6_pkt_prohibit_out(struct n
+@@ -4546,6 +4565,17 @@ static int ip6_pkt_prohibit_out(struct n
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
}
@@ -175,7 +175,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
/*
* Allocate a dst for local (unicast / anycast) address.
*/
-@@ -5035,7 +5065,8 @@ static int rtm_to_fib6_config(struct sk_
+@@ -5037,7 +5067,8 @@ static int rtm_to_fib6_config(struct sk_
if (rtm->rtm_type == RTN_UNREACHABLE ||
rtm->rtm_type == RTN_BLACKHOLE ||
rtm->rtm_type == RTN_PROHIBIT ||
@@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
cfg->fc_flags |= RTF_REJECT;
if (rtm->rtm_type == RTN_LOCAL)
-@@ -6282,6 +6313,8 @@ static int ip6_route_dev_notify(struct n
+@@ -6284,6 +6315,8 @@ static int ip6_route_dev_notify(struct n
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
@@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
#endif
-@@ -6293,6 +6326,7 @@ static int ip6_route_dev_notify(struct n
+@@ -6295,6 +6328,7 @@ static int ip6_route_dev_notify(struct n
in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
@@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
#endif
}
-@@ -6493,6 +6527,8 @@ static int __net_init ip6_route_net_init
+@@ -6495,6 +6529,8 @@ static int __net_init ip6_route_net_init
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.fib6_has_custom_rules = false;
@@ -211,7 +211,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
sizeof(*net->ipv6.ip6_prohibit_entry),
GFP_KERNEL);
-@@ -6503,11 +6539,21 @@ static int __net_init ip6_route_net_init
+@@ -6505,11 +6541,21 @@ static int __net_init ip6_route_net_init
ip6_template_metrics, true);
INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->dst.rt_uncached);
@@ -234,7 +234,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
ip6_template_metrics, true);
-@@ -6534,6 +6580,8 @@ out:
+@@ -6536,6 +6582,8 @@ out:
return ret;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -243,7 +243,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
out_ip6_prohibit_entry:
kfree(net->ipv6.ip6_prohibit_entry);
out_ip6_null_entry:
-@@ -6553,6 +6601,7 @@ static void __net_exit ip6_route_net_exi
+@@ -6555,6 +6603,7 @@ static void __net_exit ip6_route_net_exi
kfree(net->ipv6.ip6_null_entry);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
kfree(net->ipv6.ip6_prohibit_entry);
@@ -251,7 +251,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
kfree(net->ipv6.ip6_blk_hole_entry);
#endif
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
-@@ -6636,6 +6685,9 @@ void __init ip6_route_init_special_entri
+@@ -6638,6 +6687,9 @@ void __init ip6_route_init_special_entri
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
diff --git a/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch
index 7672f46d20..68ebf4e68a 100644
--- a/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch
+++ b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch
@@ -31,7 +31,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
static inline void gro_normal_list(struct napi_struct *napi)
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
-@@ -2083,7 +2083,10 @@ void tcp_v4_destroy_sock(struct sock *sk
+@@ -2084,7 +2084,10 @@ void tcp_v4_destroy_sock(struct sock *sk
struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
netdev_features_t features);
@@ -162,7 +162,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
-@@ -178,61 +245,76 @@ out:
+@@ -181,61 +248,76 @@ out:
return segs;
}
@@ -269,7 +269,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
flush = NAPI_GRO_CB(p)->flush;
flush |= (__force int)(flags & TCP_FLAG_CWR);
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
-@@ -269,6 +351,19 @@ found:
+@@ -272,6 +354,19 @@ found:
flush |= p->decrypted ^ skb->decrypted;
#endif
@@ -289,7 +289,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
if (flush || skb_gro_receive(p, skb)) {
mss = 1;
goto out_check_final;
-@@ -290,7 +385,6 @@ out_check_final:
+@@ -293,7 +388,6 @@ out_check_final:
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
pp = p;
@@ -297,7 +297,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
NAPI_GRO_CB(skb)->flush |= (flush != 0);
return pp;
-@@ -314,18 +408,58 @@ void tcp_gro_complete(struct sk_buff *sk
+@@ -317,18 +411,58 @@ void tcp_gro_complete(struct sk_buff *sk
}
EXPORT_SYMBOL(tcp_gro_complete);
@@ -361,7 +361,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
}
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
-@@ -333,6 +467,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
+@@ -336,6 +470,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
@@ -379,7 +379,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
-@@ -433,33 +433,6 @@ out:
+@@ -452,33 +452,6 @@ out:
return segs;
}
diff --git a/target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch b/target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch
new file mode 100644
index 0000000000..97e321bfec
--- /dev/null
+++ b/target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch
@@ -0,0 +1,129 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 15 Aug 2024 21:15:13 +0200
+Subject: [PATCH] net: remove NETIF_F_GSO_FRAGLIST from NETIF_F_GSO_SOFTWARE
+
+Several drivers set NETIF_F_GSO_SOFTWARE, but mangle fraglist GRO packets
+in a way that they can't be properly segmented anymore.
+In order to properly deal with this, remove fraglist GSO from
+NETIF_F_GSO_SOFTWARE and switch to NETIF_F_GSO_SOFTWARE_ALL (which includes
+fraglist GSO) in places where it's safe to add.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/dummy.c
++++ b/drivers/net/dummy.c
+@@ -118,7 +118,7 @@ static void dummy_setup(struct net_devic
+ dev->flags &= ~IFF_MULTICAST;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
+ dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST;
+- dev->features |= NETIF_F_GSO_SOFTWARE;
++ dev->features |= NETIF_F_GSO_SOFTWARE_ALL;
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
+ dev->features |= NETIF_F_GSO_ENCAP_ALL;
+ dev->hw_features |= dev->features;
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -176,7 +176,7 @@ static void gen_lo_setup(struct net_devi
+ dev->flags = IFF_LOOPBACK;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
+ netif_keep_dst(dev);
+- dev->hw_features = NETIF_F_GSO_SOFTWARE;
++ dev->hw_features = NETIF_F_GSO_SOFTWARE_ALL;
+ dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+ | NETIF_F_GSO_SOFTWARE
+ | NETIF_F_HW_CSUM
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -896,7 +896,7 @@ static int macvlan_hwtstamp_set(struct n
+ static struct lock_class_key macvlan_netdev_addr_lock_key;
+
+ #define ALWAYS_ON_OFFLOADS \
+- (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \
++ (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE_ALL | \
+ NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL)
+
+ #define ALWAYS_ON_FEATURES (ALWAYS_ON_OFFLOADS | NETIF_F_LLTX)
+--- a/include/linux/netdev_features.h
++++ b/include/linux/netdev_features.h
+@@ -219,13 +219,14 @@ static inline int find_next_netdev_featu
+
+ /* List of features with software fallbacks. */
+ #define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | NETIF_F_GSO_SCTP | \
+- NETIF_F_GSO_UDP_L4 | NETIF_F_GSO_FRAGLIST)
++ NETIF_F_GSO_UDP_L4)
++#define NETIF_F_GSO_SOFTWARE_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_FRAGLIST)
+
+ /*
+ * If one device supports one of these features, then enable them
+ * for all in netdev_increment_features.
+ */
+-#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
++#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE_ALL | NETIF_F_GSO_ROBUST | \
+ NETIF_F_SG | NETIF_F_HIGHDMA | \
+ NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED)
+
+--- a/net/8021q/vlan.h
++++ b/net/8021q/vlan.h
+@@ -108,7 +108,7 @@ static inline netdev_features_t vlan_tnl
+ netdev_features_t ret;
+
+ ret = real_dev->hw_enc_features &
+- (NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE |
++ (NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE_ALL |
+ NETIF_F_GSO_ENCAP_ALL);
+
+ if ((ret & NETIF_F_GSO_ENCAP_ALL) && (ret & NETIF_F_CSUM_MASK))
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -583,7 +583,7 @@ static int vlan_dev_init(struct net_devi
+ dev->state |= (1 << __LINK_STATE_NOCARRIER);
+
+ dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG |
+- NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
++ NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE_ALL |
+ NETIF_F_GSO_ENCAP_ALL |
+ NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC |
+ NETIF_F_ALL_FCOE;
+@@ -676,7 +676,7 @@ static netdev_features_t vlan_dev_fix_fe
+ if (lower_features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
+ lower_features |= NETIF_F_HW_CSUM;
+ features = netdev_intersect_features(features, lower_features);
+- features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE);
++ features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE_ALL);
+ features |= NETIF_F_LLTX;
+
+ return features;
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2441,7 +2441,7 @@ void sk_setup_caps(struct sock *sk, stru
+ if (sk_is_tcp(sk))
+ sk->sk_route_caps |= NETIF_F_GSO;
+ if (sk->sk_route_caps & NETIF_F_GSO)
+- sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
++ sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE_ALL;
+ if (unlikely(sk->sk_gso_disabled))
+ sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
+ if (sk_can_gso(sk)) {
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1996,7 +1996,7 @@ void ieee80211_color_collision_detection
+ /* interface handling */
+ #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
+ NETIF_F_HW_CSUM | NETIF_F_SG | \
+- NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \
++ NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE_ALL | \
+ NETIF_F_HW_TC)
+ #define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM)
+ #define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \
+--- a/net/openvswitch/vport-internal_dev.c
++++ b/net/openvswitch/vport-internal_dev.c
+@@ -110,7 +110,7 @@ static void do_setup(struct net_device *
+
+ netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
+ NETIF_F_HIGHDMA | NETIF_F_HW_CSUM |
+- NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
++ NETIF_F_GSO_SOFTWARE_ALL | NETIF_F_GSO_ENCAP_ALL;
+
+ netdev->vlan_features = netdev->features;
+ netdev->hw_enc_features = netdev->features;
diff --git a/target/linux/generic/pending-6.6/684-gso-fix-gso-fraglist-segmentation-after-pull-from-fr.patch b/target/linux/generic/pending-6.6/684-gso-fix-gso-fraglist-segmentation-after-pull-from-fr.patch
new file mode 100644
index 0000000000..5a7ba07fd0
--- /dev/null
+++ b/target/linux/generic/pending-6.6/684-gso-fix-gso-fraglist-segmentation-after-pull-from-fr.patch
@@ -0,0 +1,53 @@
+From: Willem de Bruijn <willemb@google.com>
+Date: Sun, 22 Sep 2024 11:03:45 -0400
+Subject: [PATCH] gso: fix gso fraglist segmentation after pull from
+ frag_list
+
+Detect gso fraglist skbs with corrupted geometry (see below) and
+pass these to skb_segment instead of skb_segment_list, as the first
+can segment them correctly.
+
+Valid SKB_GSO_FRAGLIST skbs
+- consist of two or more segments
+- the head_skb holds the protocol headers plus first gso_size
+- one or more frag_list skbs hold exactly one segment
+- all but the last must be gso_size
+
+Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can
+modify these skbs, breaking these invariants.
+
+In extreme cases they pull all data into skb linear. For UDP, this
+causes a NULL ptr deref in __udpv4_gso_segment_list_csum at
+udp_hdr(seg->next)->dest.
+
+Detect invalid geometry due to pull, by checking head_skb size.
+Don't just drop, as this may blackhole a destination. Convert to be
+able to pass to regular skb_segment.
+
+Link: https://lore.kernel.org/netdev/20240428142913.18666-1-shiming.cheng@mediatek.com/
+Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Cc: stable@vger.kernel.org
+---
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -296,8 +296,16 @@ struct sk_buff *__udp_gso_segment(struct
+ return NULL;
+ }
+
+- if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)
+- return __udp_gso_segment_list(gso_skb, features, is_ipv6);
++ if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) {
++ /* Detect modified geometry and pass these to skb_segment. */
++ if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size)
++ return __udp_gso_segment_list(gso_skb, features, is_ipv6);
++
++ /* Setup csum, as fraglist skips this in udp4_gro_receive. */
++ gso_skb->csum_start = skb_transport_header(gso_skb) - gso_skb->head;
++ gso_skb->csum_offset = offsetof(struct udphdr, check);
++ gso_skb->ip_summed = CHECKSUM_PARTIAL;
++ }
+
+ skb_pull(gso_skb, sizeof(*uh));
+
diff --git a/target/linux/generic/pending-6.6/685-net-gso-fix-tcp-fraglist-segmentation-after-pull-fro.patch b/target/linux/generic/pending-6.6/685-net-gso-fix-tcp-fraglist-segmentation-after-pull-fro.patch
new file mode 100644
index 0000000000..235762b5c0
--- /dev/null
+++ b/target/linux/generic/pending-6.6/685-net-gso-fix-tcp-fraglist-segmentation-after-pull-fro.patch
@@ -0,0 +1,74 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 26 Sep 2024 10:41:30 +0200
+Subject: [PATCH] net: gso: fix tcp fraglist segmentation after pull from
+ frag_list
+
+Detect tcp gso fraglist skbs with corrupted geometry (see below) and
+pass these to skb_segment instead of skb_segment_list, as the first
+can segment them correctly.
+
+Valid SKB_GSO_FRAGLIST skbs
+- consist of two or more segments
+- the head_skb holds the protocol headers plus first gso_size
+- one or more frag_list skbs hold exactly one segment
+- all but the last must be gso_size
+
+Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can
+modify these skbs, breaking these invariants.
+
+In extreme cases they pull all data into skb linear. For TCP, this
+causes a NULL ptr deref in __tcpv4_gso_segment_list_csum at
+tcp_hdr(seg->next).
+
+Detect invalid geometry due to pull, by checking head_skb size.
+Don't just drop, as this may blackhole a destination. Convert to be
+able to pass to regular skb_segment.
+
+Approach and description based on a patch by Willem de Bruijn.
+
+Link: https://lore.kernel.org/netdev/20240428142913.18666-1-shiming.cheng@mediatek.com/
+Link: https://lore.kernel.org/netdev/20240922150450.3873767-1-willemdebruijn.kernel@gmail.com/
+Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
+Cc: stable@vger.kernel.org
+Cc: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -101,8 +101,14 @@ static struct sk_buff *tcp4_gso_segment(
+ if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
+ return ERR_PTR(-EINVAL);
+
+- if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
+- return __tcp4_gso_segment_list(skb, features);
++ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
++ struct tcphdr *th = tcp_hdr(skb);
++
++ if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
++ return __tcp4_gso_segment_list(skb, features);
++
++ skb->ip_summed = CHECKSUM_NONE;
++ }
+
+ if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
+ const struct iphdr *iph = ip_hdr(skb);
+--- a/net/ipv6/tcpv6_offload.c
++++ b/net/ipv6/tcpv6_offload.c
+@@ -158,8 +158,14 @@ static struct sk_buff *tcp6_gso_segment(
+ if (!pskb_may_pull(skb, sizeof(*th)))
+ return ERR_PTR(-EINVAL);
+
+- if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
+- return __tcp6_gso_segment_list(skb, features);
++ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
++ struct tcphdr *th = tcp_hdr(skb);
++
++ if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
++ return __tcp6_gso_segment_list(skb, features);
++
++ skb->ip_summed = CHECKSUM_NONE;
++ }
+
+ if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
+ const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
diff --git a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
index 07e923b69e..be7405c1a2 100644
--- a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
+++ b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
@@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
-@@ -8268,7 +8268,7 @@ static int nft_register_flowtable_net_ho
+@@ -8327,7 +8327,7 @@ static int nft_register_flowtable_net_ho
err = flowtable->data.type->setup(&flowtable->data,
hook->ops.dev,
FLOW_BLOCK_BIND);
diff --git a/target/linux/generic/pending-6.6/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-6.6/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
index 4fbf6288c8..5563bf1f93 100644
--- a/target/linux/generic/pending-6.6/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
+++ b/target/linux/generic/pending-6.6/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5020,6 +5020,8 @@ static int mtk_probe(struct platform_dev
+@@ -5036,6 +5036,8 @@ static int mtk_probe(struct platform_dev
* for NAPI to work
*/
init_dummy_netdev(&eth->dummy_dev);
diff --git a/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
new file mode 100644
index 0000000000..fe8ee7b5fa
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
@@ -0,0 +1,81 @@
+From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 2 Apr 2023 23:56:16 +0100
+Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
+
+Some vendor bootloaders do weird things with those PHYs which result in
+link modes being reported wrongly. Start from a clean sheet by resetting
+the PHY.
+
+Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1325,6 +1325,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .name = "RTL8226 2.5Gbps PHY",
+ .match_phy_device = rtl8226_match_phy_device,
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1337,6 +1338,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc840),
+ .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1351,6 +1353,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc838),
+ .name = "RTL8226-CG 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1361,6 +1364,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc848),
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1373,6 +1377,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1385,6 +1390,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
+@@ -1395,6 +1401,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1407,6 +1414,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
diff --git a/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
new file mode 100644
index 0000000000..0c729acb7f
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
@@ -0,0 +1,63 @@
+From d54ef6aea00e7a6ace439baade6ad0aa38ee4b04 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 3 Apr 2023 01:21:57 +0300
+Subject: [PATCH 287/326] net: phy: realtek: disable SGMII in-band AN for 2.5G
+ PHYs
+
+MAC drivers don't use SGMII in-band autonegotiation unless told to do so
+in device tree using 'managed = "in-band-status"'. When using MDIO to
+access a PHY, in-band-status is unneeded as we have link-status via
+MDIO. Switch off SGMII in-band autonegotiation using magic values.
+
+Reported-by: Chen Minqiang <ptpt52@gmail.com>
+Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
+Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -786,8 +786,8 @@ static int rtl822x_write_mmd(struct phy_
+ static int rtl822xb_config_init(struct phy_device *phydev)
+ {
+ bool has_2500, has_sgmii;
++ int ret, val;
+ u16 mode;
+- int ret;
+
+ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
+ phydev->host_interfaces) ||
+@@ -837,7 +837,29 @@ static int rtl822xb_config_init(struct p
+ if (ret < 0)
+ return ret;
+
+- return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ if (ret < 0)
++ return ret;
++
++ /* Disable SGMII AN */
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587,
++ val, !(val & BIT(0)), 500, 100000, false);
++ if (ret < 0)
++ return ret;
++
++ return 0;
+ }
+
+ static int rtl822xb_get_rate_matching(struct phy_device *phydev,
diff --git a/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
new file mode 100644
index 0000000000..8b8dca8f27
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
@@ -0,0 +1,35 @@
+From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 01:21:14 +0100
+Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
+
+As we cannot rely on phy_read_paged function before the PHY is
+identified, the paged read in rtlgen_supports_2_5gbps needs to be open
+coded as it is being called by the match_phy_device function, ie. before
+.read_page and .write_page have been populated.
+
+Make sure it is also protected by the MDIO bus mutex and use
+rtl821x_write_page instead of 3 individually locked MDIO bus operations.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1052,9 +1052,11 @@ static bool rtlgen_supports_2_5gbps(stru
+ {
+ int val;
+
+- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
+- val = phy_read(phydev, 0x13);
+- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
++ mutex_lock(&phydev->mdio.bus->mdio_lock);
++ rtl821x_write_page(phydev, 0xa61);
++ val = __phy_read(phydev, 0x13);
++ rtl821x_write_page(phydev, 0);
++ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
+ }
diff --git a/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
new file mode 100644
index 0000000000..8b20451979
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
@@ -0,0 +1,26 @@
+From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 01:23:08 +0100
+Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
+ advertisement
+
+Use existing generic inline functions to encode local advertisement
+of 10GbE link modes as well as to decode link-partner advertisement.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 22 +++++-----------------
+ 1 file changed, 5 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -910,7 +910,8 @@ static int rtl822x_config_aneg(struct ph
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+ MDIO_AN_10GBT_CTRL_ADV2_5G |
+- MDIO_AN_10GBT_CTRL_ADV5G,
++ MDIO_AN_10GBT_CTRL_ADV5G |
++ MDIO_AN_10GBT_CTRL_ADV10G,
+ adv);
+ if (ret < 0)
+ return ret;
diff --git a/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
new file mode 100644
index 0000000000..1ba3353f19
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
@@ -0,0 +1,28 @@
+From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 01:25:39 +0100
+Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
+ advertisement
+
+Only use link-partner advertisement bits for 10GbE modes if they are
+actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
+unless both of them are set.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -950,6 +950,10 @@ static int rtl822x_read_status(struct ph
+ if (lpadv < 0)
+ return lpadv;
+
++ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
++ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
++ lpadv = 0;
++
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
+ lpadv);
+ }
diff --git a/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch
new file mode 100644
index 0000000000..ee4de599ab
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch
@@ -0,0 +1,100 @@
+From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 03:26:01 +0100
+Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
+
+Setup Link Down Power Saving Mode according the DTS property
+just like for RTL821x 1GE PHYs.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -82,6 +82,10 @@
+
+ #define RTL822X_VND2_PHYSR 0xa434
+
++#define RTL8221B_PHYCR1 0xa430
++#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
++#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -1107,6 +1111,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
+ }
+
++static int rtl822x_probe(struct phy_device *phydev)
++{
++ struct device *dev = &phydev->mdio.dev;
++ int val;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1);
++ if (val < 0)
++ return val;
++
++ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
++ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
++ else
++ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
++
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, val);
++
++ return 0;
++}
++
+ static int rtlgen_resume(struct phy_device *phydev)
+ {
+ int ret = genphy_resume(phydev);
+@@ -1382,6 +1405,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc838),
+ .name = "RTL8226-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1393,6 +1417,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc848),
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1406,6 +1431,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1419,6 +1445,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+@@ -1430,6 +1457,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1443,6 +1471,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch
new file mode 100644
index 0000000000..cca5da0e13
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch
@@ -0,0 +1,52 @@
+From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 30 Apr 2023 00:15:41 +0100
+Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
+
+Early versions (?) of the RTL8221B PHY cannot be identified in a regular
+Clause-45 bus scan as the PHY doesn't report the implemented MMDs
+correctly but returns 0 instead.
+Implement custom identify function using the PKGID instead of iterating
+over the implemented MMDs.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+[forward-port by @namiltd]
+Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1085,10 +1085,32 @@ static int rtl8226_match_phy_device(stru
+ static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
+ bool is_c45)
+ {
+- if (phydev->is_c45)
+- return is_c45 && (id == phydev->c45_ids.device_ids[1]);
+- else
++ if (phydev->is_c45) {
++ u32 rid;
++
++ if (!is_c45)
++ return 0;
++
++ rid = phydev->c45_ids.device_ids[1];
++ if ((rid == 0xffffffff) && phydev->mdio.bus->read_c45) {
++ int val;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
++ if (val < 0)
++ return 0;
++
++ rid = val << 16;
++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
++ if (val < 0)
++ return 0;
++
++ rid |= val;
++ }
++
++ return (id == rid);
++ } else {
+ return !is_c45 && (id == phydev->phy_id);
++ }
+ }
+
+ static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
diff --git a/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch
new file mode 100644
index 0000000000..ee28bfbcfc
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch
@@ -0,0 +1,102 @@
+From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
+From: Jianhui Zhao <zhaojh329@gmail.com>
+Date: Sun, 24 Sep 2023 22:15:00 +0800
+Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
+
+This commit introduces interrupt support for RTL8221B.
+
+Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
+---
+ drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1287,6 +1287,51 @@ static irqreturn_t rtl9000a_handle_inter
+ return IRQ_HANDLED;
+ }
+
++static int rtl8221b_ack_interrupt(struct phy_device *phydev)
++{
++ int err;
++
++ err = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa4d4);
++
++ return (err < 0) ? err : 0;
++}
++
++static int rtl8221b_config_intr(struct phy_device *phydev)
++{
++ int err;
++
++ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
++ err = rtl8221b_ack_interrupt(phydev);
++ if (err)
++ return err;
++
++ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff);
++ } else {
++ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0);
++ if (err)
++ return err;
++
++ err = rtl8221b_ack_interrupt(phydev);
++ }
++
++ return err;
++}
++
++static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
++{
++ int err;
++
++ err = rtl8221b_ack_interrupt(phydev);
++ if (err) {
++ phy_error(phydev);
++ return IRQ_NONE;
++ }
++
++ phy_trigger_machine(phydev);
++
++ return IRQ_HANDLED;
++}
++
+ static struct phy_driver realtek_drvs[] = {
+ {
+ PHY_ID_MATCH_EXACT(0x00008201),
+@@ -1453,6 +1498,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+@@ -1467,6 +1514,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+@@ -1479,6 +1528,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+@@ -1493,6 +1544,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
diff --git a/target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
deleted file mode 100644
index 7e9b3660d5..0000000000
--- a/target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Sat, 13 Aug 2022 12:49:33 +0200
-Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
- mode
-
-The rtl8221 supports multiple SERDES modes:
-- SGMII
-- 2500base-x
-- HiSGMII
-
-Further it supports rate adaption on SERDES links to allow
-slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
-links without reducing the SERDES speed.
-
-When operating without rate adapters the SERDES link will follow the
-ethernet speed.
-
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
----
- drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -54,6 +54,15 @@
- RTL8201F_ISR_LINK)
- #define RTL8201F_IER 0x13
-
-+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1
-+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2
-+#define RTL8221B_SERDES_OPTION 0x697a
-+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -879,6 +888,48 @@ static irqreturn_t rtl9000a_handle_inter
- return IRQ_HANDLED;
- }
-
-+static int rtl8221b_config_init(struct phy_device *phydev)
-+{
-+ u16 option_mode;
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ if (!phydev->is_c45) {
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX;
-+ break;
-+ }
-+ fallthrough;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ 0x75f3, 0);
-+
-+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ RTL8221B_SERDES_OPTION,
-+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
-+ switch (option_mode) {
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1033,6 +1084,7 @@ static struct phy_driver realtek_drvs[]
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
-+ .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
-@@ -1044,6 +1096,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .config_init = rtl8221b_config_init,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch b/target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
deleted file mode 100644
index 58bd259198..0000000000
--- a/target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Wed, 8 Feb 2023 16:32:18 +0800
-Subject: [PATCH] net: phy: realtek: support switching between SGMII and
- 2500BASE-X for RTL822x series
-
-After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure
-SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes
-respectively. So add interface automatic switching for rtl8221 phy to
-match various wire speeds.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
----
- drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -714,6 +714,25 @@ static int rtl822x_config_aneg(struct ph
- return __genphy_config_aneg(phydev, ret);
- }
-
-+static void rtl822x_update_interface(struct phy_device *phydev)
-+{
-+ /* Automatically switch SERDES interface between
-+ * SGMII and 2500-BaseX according to speed.
-+ */
-+ switch (phydev->speed) {
-+ case SPEED_2500:
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ break;
-+ case SPEED_1000:
-+ case SPEED_100:
-+ case SPEED_10:
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
- static int rtl822x_read_status(struct phy_device *phydev)
- {
- int ret;
-@@ -732,11 +751,14 @@ static int rtl822x_read_status(struct ph
- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
- }
-
-- ret = genphy_read_status(phydev);
-+ ret = rtlgen_read_status(phydev);
- if (ret < 0)
- return ret;
-
-- return rtlgen_get_speed(phydev);
-+ if (phydev->is_c45 && phydev->link)
-+ rtl822x_update_interface(phydev);
-+
-+ return 0;
- }
-
- static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
diff --git a/target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
deleted file mode 100644
index 8efedd3a11..0000000000
--- a/target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 2 Apr 2023 23:56:16 +0100
-Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
-
-Some vendor bootloaders do weird things with those PHYs which result in
-link modes being reported wrongly. Start from a clean sheet by resetting
-the PHY.
-
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1070,6 +1070,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc840),
- .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
-@@ -1082,6 +1083,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc838),
- .name = "RTL8226-CG 2.5Gbps PHY",
-@@ -1092,6 +1094,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc848),
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
-@@ -1102,6 +1105,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
-@@ -1113,6 +1117,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc84a),
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
-@@ -1124,6 +1129,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc961),
- .name = "RTL8366RB Gigabit Ethernet",
diff --git a/target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
deleted file mode 100644
index 43cf35ab77..0000000000
--- a/target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 01:21:57 +0300
-Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs
-
-MAC drivers don't use SGMII in-band autonegotiation unless told to do so
-in device tree using 'managed = "in-band-status"'. When using MDIO to
-access a PHY, in-band-status is unneeded as we have link-status via
-MDIO. Switch off SGMII in-band autonegotiation using magic values.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -913,6 +913,7 @@ static irqreturn_t rtl9000a_handle_inter
- static int rtl8221b_config_init(struct phy_device *phydev)
- {
- u16 option_mode;
-+ int val;
-
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_2500BASEX:
-@@ -949,6 +950,13 @@ static int rtl8221b_config_init(struct p
- break;
- }
-
-+ /* Disable SGMII AN */
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3);
-+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587,
-+ val, !(val & BIT(0)), 500, 100000, false);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
deleted file mode 100644
index be86a774ea..0000000000
--- a/target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:21:14 +0100
-Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
-
-As we cannot rely on phy_read_paged function before the PHY is
-identified, the paged read in rtlgen_supports_2_5gbps needs to be open
-coded as it is being called by the match_phy_device function, ie. before
-.read_page and .write_page have been populated.
-
-Make sure it is also protected by the MDIO bus mutex and use
-rtl821x_write_page instead of 3 individually locked MDIO bus operations.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -765,9 +765,11 @@ static bool rtlgen_supports_2_5gbps(stru
- {
- int val;
-
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
-- val = phy_read(phydev, 0x13);
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
-+ mutex_lock(&phydev->mdio.bus->mdio_lock);
-+ rtl821x_write_page(phydev, 0xa61);
-+ val = __phy_read(phydev, 0x13);
-+ rtl821x_write_page(phydev, 0);
-+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
- }
diff --git a/target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
deleted file mode 100644
index e6cbfbe649..0000000000
--- a/target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:23:08 +0100
-Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
- advertisement
-
-Use existing generic inline functions to encode local advertisement
-of 10GbE link modes as well as to decode link-partner advertisement.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 22 +++++-----------------
- 1 file changed, 5 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -69,10 +69,6 @@
- #define RTL_SUPPORTS_5000FULL BIT(14)
- #define RTL_SUPPORTS_2500FULL BIT(13)
- #define RTL_SUPPORTS_10000FULL BIT(0)
--#define RTL_ADV_2500FULL BIT(7)
--#define RTL_LPADV_10000FULL BIT(11)
--#define RTL_LPADV_5000FULL BIT(6)
--#define RTL_LPADV_2500FULL BIT(5)
-
- #define RTL9000A_GINMR 0x14
- #define RTL9000A_GINMR_LINK_STATUS BIT(4)
-@@ -699,14 +695,11 @@ static int rtl822x_config_aneg(struct ph
- int ret = 0;
-
- if (phydev->autoneg == AUTONEG_ENABLE) {
-- u16 adv2500 = 0;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->advertising))
-- adv2500 = RTL_ADV_2500FULL;
--
- ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
-- RTL_ADV_2500FULL, adv2500);
-+ MDIO_AN_10GBT_CTRL_ADV10G |
-+ MDIO_AN_10GBT_CTRL_ADV5G |
-+ MDIO_AN_10GBT_CTRL_ADV2_5G,
-+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising));
- if (ret < 0)
- return ret;
- }
-@@ -743,12 +736,7 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
-+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
- ret = rtlgen_read_status(phydev);
diff --git a/target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
deleted file mode 100644
index 329415bab5..0000000000
--- a/target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:25:39 +0100
-Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
- advertisement
-
-Only use link-partner advertisement bits for 10GbE modes if they are
-actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
-unless both of them are set.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -736,6 +736,10 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
-+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
-+ lpadv = 0;
-+
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
diff --git a/target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch
deleted file mode 100644
index 7098fa6b28..0000000000
--- a/target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 03:26:01 +0100
-Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
-
-Setup Link Down Power Saving Mode according the DTS property
-just like for RTL821x 1GE PHYs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -63,6 +63,10 @@
- #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
- #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-
-+#define RTL8221B_PHYCR1 0xa430
-+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
-+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -778,6 +782,25 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl822x_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1);
-+ if (val < 0)
-+ return val;
-+
-+ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
-+ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
-+ else
-+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val);
-+
-+ return 0;
-+}
-+
- static int rtlgen_resume(struct phy_device *phydev)
- {
- int ret = genphy_resume(phydev);
-@@ -1091,6 +1114,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1102,6 +1126,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1114,6 +1139,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1126,6 +1152,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl8221b_config_init,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch b/target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch
new file mode 100644
index 0000000000..67d0ab4537
--- /dev/null
+++ b/target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch
@@ -0,0 +1,49 @@
+From 7d41a5a8e9c91cc6bb011dd953570738583dd091 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 18 Sep 2024 02:01:01 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: reset all TX queues on DMA free
+
+The purpose of resetting the TX queue is to reset the
+byte and packet count as well as to clear the software
+flow control XOFF bit.
+
+MediaTek developers pointed out that netdev_reset_queue would only
+resets queue 0 of the network device.
+Queues that are not reset may cause unexpected issues.
+
+Packets may stop being sent after reset and "transmit timeout" log may
+be displayed.
+
+Import fix from MediaTek's SDK to resolve this issue.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3135,11 +3135,19 @@ static int mtk_dma_init(struct mtk_eth *
+ static void mtk_dma_free(struct mtk_eth *eth)
+ {
+ const struct mtk_soc_data *soc = eth->soc;
+- int i;
++ int i, j, txqs = 1;
++
++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
++ txqs = MTK_QDMA_NUM_QUEUES;
++
++ for (i = 0; i < MTK_MAX_DEVS; i++) {
++ if (!eth->netdev[i])
++ continue;
++
++ for (j = 0; j < txqs; j++)
++ netdev_tx_reset_queue(netdev_get_tx_queue(eth->netdev[i], j));
++ }
+
+- for (i = 0; i < MTK_MAX_DEVS; i++)
+- if (eth->netdev[i])
+- netdev_reset_queue(eth->netdev[i]);
+ 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,
diff --git a/target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
deleted file mode 100644
index 0e9affd16a..0000000000
--- a/target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 30 Apr 2023 00:15:41 +0100
-Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
-
-Early versions (?) of the RTL8221B PHY cannot be identified in a regular
-Clause-45 bus scan as the PHY doesn't report the implemented MMDs
-correctly but returns 0 instead.
-Implement custom identify function using the PKGID instead of iterating
-over the implemented MMDs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -81,6 +81,7 @@
-
- #define RTL_GENERIC_PHYID 0x001cc800
- #define RTL_8211FVD_PHYID 0x001cc878
-+#define RTL_8221B_VB_CG_PHYID 0x001cc849
-
- MODULE_DESCRIPTION("Realtek PHY driver");
- MODULE_AUTHOR("Johnson Leung");
-@@ -782,6 +783,38 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev)
-+{
-+ int val;
-+ u32 id;
-+
-+ if (phydev->mdio.bus->read_c45) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ } else {
-+ val = phy_read(phydev, MII_PHYSID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read(phydev, MII_PHYSID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ }
-+
-+ return (id == RTL_8221B_VB_CG_PHYID);
-+}
-+
- static int rtl822x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -1134,7 +1167,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .soft_reset = genphy_soft_reset,
- }, {
-- PHY_ID_MATCH_EXACT(0x001cc849),
-+ .match_phy_device = rtl8221b_vb_cg_match_phy_device,
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
diff --git a/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch b/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch
new file mode 100644
index 0000000000..d786b462c2
--- /dev/null
+++ b/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch
@@ -0,0 +1,44 @@
+From: Chad Monroe <chad@monroe.io>
+Date: Mon, 16 Sep 2024 19:29:03 -0700
+Subject: [PATCH] net: ethernet: mediatek: increase QDMA RESV_BUF size
+
+Increase QDMA RESV_BUF from 2K to 3K for netsys v2 to match Mediatek SDK[1].
+This helps reduce the possibility of Ethernet transmit timeouts.
+
+[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/19d8456c3051e5f6dabf42fa770916a2126ea4bf
+
+Signed-off-by: Chad Monroe <chad@monroe.io>
+---
+ 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(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -271,6 +271,7 @@
+ #define MTK_WCOMP_EN BIT(24)
+ #define MTK_RESV_BUF (0x80 << 16)
+ #define MTK_MUTLI_CNT (0x4 << 12)
++#define MTK_RESV_BUF_MASK (0xff << 16)
+ #define MTK_LEAKY_BUCKET_EN BIT(11)
+
+ /* QDMA Flow Control Register */
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3309,12 +3309,14 @@ static int mtk_start_dma(struct mtk_eth
+ MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
+ MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
+
+- if (mtk_is_netsys_v2_or_greater(eth))
++ if (mtk_is_netsys_v2_or_greater(eth)) {
++ val &= ~MTK_RESV_BUF_MASK;
+ val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
+ MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
+ MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
+- else
++ } else {
+ val |= MTK_RX_BT_32DWORDS;
++ }
+ mtk_w32(eth, val, reg_map->qdma.glo_cfg);
+
+ mtk_w32(eth,
diff --git a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
index 89dc87e1a2..f4e12ca63a 100644
--- a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
+++ b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
@@ -490,7 +490,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
.mac_finish = mtk_mac_finish,
.mac_link_down = mtk_mac_link_down,
.mac_link_up = mtk_mac_link_up,
-@@ -3407,6 +3548,9 @@ static int mtk_open(struct net_device *d
+@@ -3417,6 +3558,9 @@ static int mtk_open(struct net_device *d
ppe_num = eth->soc->ppe_num;
@@ -500,7 +500,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
if (err) {
netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3557,6 +3701,9 @@ static int mtk_stop(struct net_device *d
+@@ -3567,6 +3711,9 @@ static int mtk_stop(struct net_device *d
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
mtk_ppe_stop(eth->ppe[i]);
@@ -510,7 +510,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
return 0;
}
-@@ -4554,6 +4701,7 @@ static const struct net_device_ops mtk_n
+@@ -4580,6 +4727,7 @@ static const struct net_device_ops mtk_n
static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
{
const __be32 *_id = of_get_property(np, "reg", NULL);
@@ -518,7 +518,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phy_interface_t phy_mode;
struct phylink *phylink;
struct mtk_mac *mac;
-@@ -4590,16 +4738,41 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4616,16 +4764,41 @@ static int mtk_add_mac(struct mtk_eth *e
mac->id = id;
mac->hw = eth;
mac->of_node = np;
@@ -568,7 +568,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
}
memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
-@@ -4682,8 +4855,21 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4708,8 +4881,21 @@ static int mtk_add_mac(struct mtk_eth *e
phy_interface_zero(mac->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
mac->phylink_config.supported_interfaces);
@@ -590,7 +590,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(mac->of_node),
phy_mode, &mtk_phylink_ops);
-@@ -4734,6 +4920,26 @@ free_netdev:
+@@ -4760,6 +4946,26 @@ free_netdev:
return err;
}
@@ -617,7 +617,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
{
struct net_device *dev, *tmp;
-@@ -4880,7 +5086,8 @@ static int mtk_probe(struct platform_dev
+@@ -4906,7 +5112,8 @@ static int mtk_probe(struct platform_dev
regmap_write(cci, 0, 3);
}
@@ -627,7 +627,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = mtk_sgmii_init(eth);
if (err)
-@@ -4991,6 +5198,24 @@ static int mtk_probe(struct platform_dev
+@@ -5017,6 +5224,24 @@ static int mtk_probe(struct platform_dev
}
}
@@ -652,7 +652,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
err = devm_request_irq(eth->dev, eth->irq[0],
mtk_handle_irq, 0,
-@@ -5094,6 +5319,11 @@ static int mtk_remove(struct platform_de
+@@ -5120,6 +5345,11 @@ static int mtk_remove(struct platform_de
mtk_stop(eth->netdev[i]);
mac = netdev_priv(eth->netdev[i]);
phylink_disconnect_phy(mac->phylink);
@@ -674,7 +674,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#include <linux/rhashtable.h>
#include <linux/dim.h>
#include <linux/bitfield.h>
-@@ -504,6 +505,21 @@
+@@ -505,6 +506,21 @@
#define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
#define INTF_MODE_RGMII_10_100 0
@@ -696,7 +696,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* GPIO port control registers for GMAC 2*/
#define GPIO_OD33_CTRL8 0x4c0
#define GPIO_BIAS_CTRL 0xed0
-@@ -529,6 +545,7 @@
+@@ -530,6 +546,7 @@
#define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK)
#define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
#define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
@@ -704,7 +704,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* ethernet subsystem clock register */
-@@ -567,6 +584,11 @@
+@@ -568,6 +585,11 @@
#define GEPHY_MAC_SEL BIT(1)
/* Top misc registers */
@@ -716,7 +716,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define USB_PHY_SWITCH_REG 0x218
#define QPHY_SEL_MASK GENMASK(1, 0)
#define SGMII_QPHY_SEL 0x2
-@@ -591,6 +613,8 @@
+@@ -592,6 +614,8 @@
#define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c)
#define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110)
@@ -725,7 +725,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MTK_FE_CDM1_FSM 0x220
#define MTK_FE_CDM2_FSM 0x224
#define MTK_FE_CDM3_FSM 0x238
-@@ -599,6 +623,11 @@
+@@ -600,6 +624,11 @@
#define MTK_FE_CDM6_FSM 0x328
#define MTK_FE_GDM1_FSM 0x228
#define MTK_FE_GDM2_FSM 0x22C
@@ -737,7 +737,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100))
-@@ -723,12 +752,8 @@ enum mtk_clks_map {
+@@ -724,12 +753,8 @@ enum mtk_clks_map {
MTK_CLK_ETHWARP_WOCPU2,
MTK_CLK_ETHWARP_WOCPU1,
MTK_CLK_ETHWARP_WOCPU0,
@@ -750,7 +750,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
MTK_CLK_TOP_ETH_GMII_SEL,
MTK_CLK_TOP_ETH_REFCK_50M_SEL,
MTK_CLK_TOP_ETH_SYS_200M_SEL,
-@@ -799,19 +824,9 @@ enum mtk_clks_map {
+@@ -800,19 +825,9 @@ enum mtk_clks_map {
BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
BIT_ULL(MTK_CLK_CRYPTO) | \
@@ -770,7 +770,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
-@@ -945,6 +960,8 @@ enum mkt_eth_capabilities {
+@@ -946,6 +961,8 @@ enum mkt_eth_capabilities {
MTK_RGMII_BIT = 0,
MTK_TRGMII_BIT,
MTK_SGMII_BIT,
@@ -779,7 +779,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
MTK_ESW_BIT,
MTK_GEPHY_BIT,
MTK_MUX_BIT,
-@@ -965,8 +982,11 @@ enum mkt_eth_capabilities {
+@@ -966,8 +983,11 @@ enum mkt_eth_capabilities {
MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
@@ -791,7 +791,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* PATH BITS */
MTK_ETH_PATH_GMAC1_RGMII_BIT,
-@@ -974,14 +994,21 @@ enum mkt_eth_capabilities {
+@@ -975,14 +995,21 @@ enum mkt_eth_capabilities {
MTK_ETH_PATH_GMAC1_SGMII_BIT,
MTK_ETH_PATH_GMAC2_RGMII_BIT,
MTK_ETH_PATH_GMAC2_SGMII_BIT,
@@ -813,7 +813,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
-@@ -1004,10 +1031,16 @@ enum mkt_eth_capabilities {
+@@ -1005,10 +1032,16 @@ enum mkt_eth_capabilities {
BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
#define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
@@ -830,7 +830,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* Supported path present on SoCs */
#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-@@ -1015,8 +1048,13 @@ enum mkt_eth_capabilities {
+@@ -1016,8 +1049,13 @@ enum mkt_eth_capabilities {
#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
@@ -844,7 +844,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -1024,7 +1062,12 @@ enum mkt_eth_capabilities {
+@@ -1025,7 +1063,12 @@ enum mkt_eth_capabilities {
#define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
#define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
#define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
@@ -857,7 +857,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* MUXes present on SoCs */
/* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
-@@ -1043,10 +1086,20 @@ enum mkt_eth_capabilities {
+@@ -1044,10 +1087,20 @@ enum mkt_eth_capabilities {
(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
MTK_SHARED_SGMII)
@@ -878,7 +878,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
-@@ -1078,8 +1131,12 @@ enum mkt_eth_capabilities {
+@@ -1079,8 +1132,12 @@ enum mkt_eth_capabilities {
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_RSTCTRL_PPE1 | MTK_SRAM)
@@ -893,7 +893,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
struct mtk_tx_dma_desc_info {
dma_addr_t addr;
-@@ -1324,6 +1381,9 @@ struct mtk_mac {
+@@ -1325,6 +1382,9 @@ struct mtk_mac {
struct device_node *of_node;
struct phylink *phylink;
struct phylink_config phylink_config;
@@ -903,7 +903,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
struct mtk_eth *hw;
struct mtk_hw_stats *hw_stats;
__be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
-@@ -1447,6 +1507,19 @@ static inline u32 mtk_get_ib2_multicast_
+@@ -1448,6 +1508,19 @@ static inline u32 mtk_get_ib2_multicast_
return MTK_FOE_IB2_MULTICAST;
}
@@ -923,7 +923,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* read the hardware status register */
void mtk_stats_update_mac(struct mtk_mac *mac);
-@@ -1455,8 +1528,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+@@ -1456,8 +1529,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
diff --git a/target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch
deleted file mode 100644
index 726f66cf64..0000000000
--- a/target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
-From: Jianhui Zhao <zhaojh329@gmail.com>
-Date: Sun, 24 Sep 2023 22:15:00 +0800
-Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
-
-This commit introduces interrupt support for RTL8221B.
-
-Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
----
- drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1010,6 +1010,51 @@ static int rtl8221b_config_init(struct p
- return 0;
- }
-
-+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4);
-+
-+ return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8221b_config_intr(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff);
-+ } else {
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0);
-+ if (err)
-+ return err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ }
-+
-+ return err;
-+}
-+
-+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1172,6 +1217,8 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .config_intr = rtl8221b_config_intr,
-+ .handle_interrupt = rtl8221b_handle_interrupt,
- .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
diff --git a/target/linux/generic/pending-6.6/750-net-phy-aquantia-fix-setting-active_low-bit.patch b/target/linux/generic/pending-6.6/750-net-phy-aquantia-fix-setting-active_low-bit.patch
new file mode 100644
index 0000000000..6072e02fd4
--- /dev/null
+++ b/target/linux/generic/pending-6.6/750-net-phy-aquantia-fix-setting-active_low-bit.patch
@@ -0,0 +1,55 @@
+From patchwork Tue Sep 17 13:49:40 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13806176
+X-Patchwork-Delegate: kuba@kernel.org
+Date: Tue, 17 Sep 2024 14:49:40 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+To: Andrew Lunn <andrew@lunn.ch>, Heiner Kallweit <hkallweit1@gmail.com>,
+ Russell King <linux@armlinux.org.uk>,
+ "David S. Miller" <davem@davemloft.net>,
+ Eric Dumazet <edumazet@google.com>,
+ Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
+ Daniel Golle <daniel@makrotopia.org>,
+ Christian Marangi <ansuelsmth@gmail.com>,
+ Bartosz Golaszewski <bartosz.golaszewski@linaro.org>,
+ Robert Marko <robimarko@gmail.com>,
+ Russell King <rmk+kernel@armlinux.org.uk>, netdev@vger.kernel.org,
+ linux-kernel@vger.kernel.org
+Subject: [PATCH net 1/2] net: phy: aquantia: fix setting active_low bit
+Message-ID:
+ <ab963584b0a7e3b4dac39472a4b82ca264d79630.1726580902.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: netdev@vger.kernel.org
+List-Id: <netdev.vger.kernel.org>
+List-Subscribe: <mailto:netdev+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:netdev+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+X-Patchwork-Delegate: kuba@kernel.org
+
+phy_modify_mmd was used wrongly in aqr_phy_led_active_low_set() resulting
+in a no-op instead of setting the VEND1_GLOBAL_LED_DRIVE_VDD bit.
+Correctly set VEND1_GLOBAL_LED_DRIVE_VDD bit.
+
+Fixes: 61578f679378 ("net: phy: aquantia: add support for PHY LEDs")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/phy/aquantia/aquantia_leds.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/aquantia/aquantia_leds.c
++++ b/drivers/net/phy/aquantia/aquantia_leds.c
+@@ -120,7 +120,8 @@ int aqr_phy_led_hw_control_set(struct ph
+ int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable)
+ {
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_DRIVE(index),
+- VEND1_GLOBAL_LED_DRIVE_VDD, enable);
++ VEND1_GLOBAL_LED_DRIVE_VDD,
++ enable ? VEND1_GLOBAL_LED_DRIVE_VDD : 0);
+ }
+
+ int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long modes)
diff --git a/target/linux/generic/pending-6.6/751-net-phy-aquantia-fix-applying-active_low-bit-after-reset.patch b/target/linux/generic/pending-6.6/751-net-phy-aquantia-fix-applying-active_low-bit-after-reset.patch
new file mode 100644
index 0000000000..5c3494ae33
--- /dev/null
+++ b/target/linux/generic/pending-6.6/751-net-phy-aquantia-fix-applying-active_low-bit-after-reset.patch
@@ -0,0 +1,72 @@
+From patchwork Tue Sep 17 13:49:55 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13806177
+X-Patchwork-Delegate: kuba@kernel.org
+Date: Tue, 17 Sep 2024 14:49:55 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+To: Andrew Lunn <andrew@lunn.ch>, Heiner Kallweit <hkallweit1@gmail.com>,
+ Russell King <linux@armlinux.org.uk>,
+ "David S. Miller" <davem@davemloft.net>,
+ Eric Dumazet <edumazet@google.com>,
+ Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
+ Daniel Golle <daniel@makrotopia.org>,
+ Christian Marangi <ansuelsmth@gmail.com>,
+ Bartosz Golaszewski <bartosz.golaszewski@linaro.org>,
+ Robert Marko <robimarko@gmail.com>,
+ Russell King <rmk+kernel@armlinux.org.uk>, netdev@vger.kernel.org,
+ linux-kernel@vger.kernel.org
+Subject: [PATCH net 2/2] net: phy: aquantia: fix applying active_low bit
+ after reset
+Message-ID:
+ <9b1f0cd91f4cda54c8be56b4fe780480baf4aa0f.1726580902.git.daniel@makrotopia.org>
+References:
+ <ab963584b0a7e3b4dac39472a4b82ca264d79630.1726580902.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: netdev@vger.kernel.org
+List-Id: <netdev.vger.kernel.org>
+List-Subscribe: <mailto:netdev+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:netdev+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To:
+ <ab963584b0a7e3b4dac39472a4b82ca264d79630.1726580902.git.daniel@makrotopia.org>
+X-Patchwork-Delegate: kuba@kernel.org
+
+for_each_set_bit was used wrongly in aqr107_config_init() when iterating
+over LEDs. Drop misleading 'index' variable and call
+aqr_phy_led_active_low_set() for each set bit representing an LED which
+is driven by VDD instead of GND pin.
+
+Fixes: 61578f679378 ("net: phy: aquantia: add support for PHY LEDs")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/phy/aquantia/aquantia_main.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/aquantia/aquantia_main.c
++++ b/drivers/net/phy/aquantia/aquantia_main.c
+@@ -501,7 +501,7 @@ static int aqr107_config_init(struct phy
+ {
+ struct aqr107_priv *priv = phydev->priv;
+ u32 led_active_low;
+- int ret, index = 0;
++ int ret;
+
+ /* Check that the PHY interface type is compatible */
+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
+@@ -537,10 +537,9 @@ static int aqr107_config_init(struct phy
+
+ /* Restore LED polarity state after reset */
+ for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
+- ret = aqr_phy_led_active_low_set(phydev, index, led_active_low);
++ ret = aqr_phy_led_active_low_set(phydev, led_active_low, true);
+ if (ret)
+ return ret;
+- index++;
+ }
+
+ return 0;
diff --git a/target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch b/target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch
new file mode 100644
index 0000000000..f3ae893b32
--- /dev/null
+++ b/target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch
@@ -0,0 +1,104 @@
+From 49d46df79404a37685e0f32deb36506f5723e3a0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 28 Aug 2024 23:52:09 +0100
+Subject: [PATCH] net: phy: aquantia: allow forcing order of MDI pairs
+
+Despite supporting Auto MDI-X, it looks like Aquantia only supports
+swapping pair (1,2) with pair (3,6) like it used to be for MDI-X on
+100MBit/s networks.
+
+When all 4 pairs are in use (for 1000MBit/s or faster) the link does not
+come up with pair order is not configured correctly, either using
+MDI_CFG pin or using the "PMA Receive Reserved Vendor Provisioning 1"
+register.
+
+Normally, the order of MDI pairs being either ABCD or DCBA is configured
+by pulling the MDI_CFG pin.
+
+However, some hardware designs require overriding the value configured
+by that bootstrap pin. The PHY allows doing that by setting a bit in
+"PMA Receive Reserved Vendor Provisioning 1" register which allows
+ignoring the state of the MDI_CFG pin and another bit configuring
+whether the order of MDI pairs should be normal (ABCD) or reverse
+(DCBA). Pair polarity is not affected and remains identical in both
+settings.
+
+Introduce property "marvell,mdi-cfg-order" which allows forcing either
+normal or reverse order of the MDI pairs from DT.
+
+If the property isn't present, the behavior is unchanged and MDI pair
+order configuration is untouched (ie. either the result of MDI_CFG pin
+pull-up/pull-down, or pair order override already configured by the
+bootloader before Linux is started).
+
+Forcing normal pair order is required on the Adtran SDG-8733A Wi-Fi 7
+residential gateway.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/aquantia/aquantia_main.c | 33 ++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+--- a/drivers/net/phy/aquantia/aquantia_main.c
++++ b/drivers/net/phy/aquantia/aquantia_main.c
+@@ -11,6 +11,7 @@
+ #include <linux/module.h>
+ #include <linux/delay.h>
+ #include <linux/bitfield.h>
++#include <linux/of.h>
+ #include <linux/phy.h>
+
+ #include "aquantia.h"
+@@ -70,6 +71,11 @@
+ #define MDIO_AN_TX_VEND_INT_MASK2 0xd401
+ #define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0)
+
++#define PMAPMD_RSVD_VEND_PROV 0xe400
++#define PMAPMD_RSVD_VEND_PROV_MDI_CONF GENMASK(1, 0)
++#define PMAPMD_RSVD_VEND_PROV_MDI_REVERSE BIT(0)
++#define PMAPMD_RSVD_VEND_PROV_MDI_FORCE BIT(1)
++
+ #define MDIO_AN_RX_LP_STAT1 0xe820
+ #define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15)
+ #define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14)
+@@ -497,6 +503,29 @@ static int aqr107_wait_processor_intensi
+ return 0;
+ }
+
++static int aqr107_config_mdi(struct phy_device *phydev)
++{
++ struct device_node *np = phydev->mdio.dev.of_node;
++ u32 mdi_conf;
++ int ret;
++
++ ret = of_property_read_u32(np, "marvell,mdi-cfg-order", &mdi_conf);
++
++ /* Do nothing in case property "marvell,mdi-cfg-order" is not present */
++ if (ret == -EINVAL)
++ return 0;
++
++ if (ret)
++ return ret;
++
++ if (mdi_conf & ~PMAPMD_RSVD_VEND_PROV_MDI_REVERSE)
++ return -EINVAL;
++
++ return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV,
++ PMAPMD_RSVD_VEND_PROV_MDI_CONF,
++ mdi_conf | PMAPMD_RSVD_VEND_PROV_MDI_FORCE);
++}
++
+ static int aqr107_config_init(struct phy_device *phydev)
+ {
+ struct aqr107_priv *priv = phydev->priv;
+@@ -535,6 +564,10 @@ static int aqr107_config_init(struct phy
+ if (ret)
+ return ret;
+
++ ret = aqr107_config_mdi(phydev);
++ if (ret)
++ return ret;
++
+ /* Restore LED polarity state after reset */
+ for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
+ ret = aqr_phy_led_active_low_set(phydev, led_active_low, true);
diff --git a/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
index 15d385c5fd..3f3d7572e0 100644
--- a/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
+++ b/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
@@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -6992,6 +6992,7 @@ static int mv88e6xxx_register_switch(str
+@@ -6993,6 +6993,7 @@ static int mv88e6xxx_register_switch(str
ds->ops = &mv88e6xxx_switch_ops;
ds->ageing_time_min = chip->info->age_time_coeff;
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
diff --git a/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
index d07447bcba..29fe668f8d 100644
--- a/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
+++ b/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
@@ -1,7 +1,7 @@
From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
From: INAGAKI Hiroshi <musashino.open@gmail.com>
Date: Thu, 13 Oct 2022 00:51:33 +0900
-Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
+Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@@ -31,12 +31,10 @@ Acked-by: Rafał Miłecki <rafal@milecki.pl>
Tested-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
+--- a/drivers/nvmem/layouts/u-boot-env.c
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev,
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
diff --git a/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
index d08ed63eaa..241ff77a7b 100644
--- a/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
+++ b/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
@@ -33,7 +33,7 @@ string.
#include <linux/init.h>
#include <linux/kref.h>
#include <linux/module.h>
-@@ -779,6 +782,62 @@ static int nvmem_validate_keepouts(struc
+@@ -796,6 +799,62 @@ static int nvmem_validate_keepouts(struc
return 0;
}
@@ -96,7 +96,7 @@ string.
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
struct device *dev = &nvmem->dev;
-@@ -813,6 +872,25 @@ static int nvmem_add_cells_from_dt(struc
+@@ -835,6 +894,25 @@ static int nvmem_add_cells_from_dt(struc
if (nvmem->fixup_dt_cell_info)
nvmem->fixup_dt_cell_info(nvmem, &info);
diff --git a/target/linux/generic/pending-6.6/834-ledtrig-libata.patch b/target/linux/generic/pending-6.6/834-ledtrig-libata.patch
index f5cd5e4a56..672d0d54cf 100644
--- a/target/linux/generic/pending-6.6/834-ledtrig-libata.patch
+++ b/target/linux/generic/pending-6.6/834-ledtrig-libata.patch
@@ -83,20 +83,20 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
ata_sff_port_init(ap);
return ap;
-@@ -5530,6 +5547,12 @@ static void ata_host_release(struct kref
- kfree(ap->pmp_link);
- kfree(ap->slave_link);
- kfree(ap->ncq_sense_buf);
+@@ -5507,6 +5524,12 @@ void ata_port_free(struct ata_port *ap)
+ kfree(ap->pmp_link);
+ kfree(ap->slave_link);
+ kfree(ap->ncq_sense_buf);
+#ifdef CONFIG_ATA_LEDS
-+ if (ap->ledtrig) {
-+ led_trigger_unregister(ap->ledtrig);
-+ kfree(ap->ledtrig);
-+ };
++ if (ap->ledtrig) {
++ led_trigger_unregister(ap->ledtrig);
++ kfree(ap->ledtrig);
++ };
+#endif
- kfree(ap);
- host->ports[i] = NULL;
- }
-@@ -5920,7 +5943,23 @@ int ata_host_register(struct ata_host *h
+ kfree(ap);
+ }
+ EXPORT_SYMBOL_GPL(ata_port_free);
+@@ -5929,7 +5952,23 @@ int ata_host_register(struct ata_host *h
host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
host->ports[i]->local_port_no = i + 1;
}
diff --git a/target/linux/generic/pending-6.6/900-net-ag71xx-fix-qca9530-and-qca9550-mdio-probe.patch b/target/linux/generic/pending-6.6/900-net-ag71xx-fix-qca9530-and-qca9550-mdio-probe.patch
new file mode 100644
index 0000000000..f2c197d4f1
--- /dev/null
+++ b/target/linux/generic/pending-6.6/900-net-ag71xx-fix-qca9530-and-qca9550-mdio-probe.patch
@@ -0,0 +1,25 @@
+From 440415703692af4548e836832ef0434e87fbc357 Mon Sep 17 00:00:00 2001
+From: Oskari Lemmela <oskari@lemmela.net>
+Date: Sat, 13 Jul 2024 18:56:59 +0300
+Subject: [PATCH] net: ag71xx: fix qca9530 and qca9550 mdio probe
+
+Newer QCA9530 and QCA9550 devices should use same div table as AR933X.
+
+Fixes: d51b6ce441d3 ("net: ethernet: add ag71xx driver")
+Signed-off-by: Oskari Lemmela <oskari@lemmela.net>
+---
+ drivers/net/ethernet/atheros/ag71xx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -638,7 +638,8 @@ static int ag71xx_mdio_get_divider(struc
+ if (!ref_clock)
+ return -EINVAL;
+
+- if (ag71xx_is(ag, AR9330) || ag71xx_is(ag, AR9340)) {
++ if (ag71xx_is(ag, AR9330) || ag71xx_is(ag, AR9340) ||
++ ag71xx_is(ag, QCA9530) || ag71xx_is(ag, QCA9550)) {
+ table = ar933x_mdio_div_table;
+ ndivs = ARRAY_SIZE(ar933x_mdio_div_table);
+ } else if (ag71xx_is(ag, AR7240)) {
diff --git a/target/linux/imx/Makefile b/target/linux/imx/Makefile
index 2d3f35e4b4..2eb12943c3 100644
--- a/target/linux/imx/Makefile
+++ b/target/linux/imx/Makefile
@@ -9,8 +9,7 @@ BOARDNAME:=NXP i.MX
FEATURES:=audio display fpu gpio pcie rtc usb usbgadget squashfs targz nand ubifs boot-part rootfs-part
SUBTARGETS:=cortexa7 cortexa9 cortexa53
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/imx/config-6.1 b/target/linux/imx/config-6.1
deleted file mode 100644
index 837bab909a..0000000000
--- a/target/linux/imx/config-6.1
+++ /dev/null
@@ -1,486 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_MXC=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_ERRATA_814220=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-# CONFIG_ARM_IMX6Q_CPUFREQ is not set
-# CONFIG_ARM_IMX_CPUFREQ_DT is not set
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ASN1=y
-CONFIG_ASSOCIATIVE_ARRAY=y
-CONFIG_ATA=y
-CONFIG_ATAGS=y
-# CONFIG_ATA_SFF is not set
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_PM=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_IMX_GPT=y
-CONFIG_CLKSRC_MMIO=y
-# CONFIG_CLK_IMX8MM is not set
-# CONFIG_CLK_IMX8MN is not set
-# CONFIG_CLK_IMX8MP is not set
-# CONFIG_CLK_IMX8MQ is not set
-# CONFIG_CLK_IMX8ULP is not set
-# CONFIG_CLK_IMX93 is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=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_FREQ_THERMAL=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_AES_ARM=y
-CONFIG_CRYPTO_AES_ARM_BS=y
-CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y
-CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_BLAKE2S_ARM=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_CHACHA20=y
-CONFIG_CRYPTO_CHACHA20_NEON=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRC32_ARM_CE=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_CTS=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DEV_FSL_CAAM=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y
-# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set
-CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
-CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ENGINE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SEQIV=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA1_ARM=y
-CONFIG_CRYPTO_SHA1_ARM_NEON=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA256_ARM=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_SHA512_ARM=y
-CONFIG_CRYPTO_SIMD=y
-CONFIG_CRYPTO_XTS=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_LZO=y
-CONFIG_DECOMPRESS_XZ=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-# CONFIG_DRM_FSL_LDB is not set
-# CONFIG_DRM_IMX8QM_LDB is not set
-# CONFIG_DRM_IMX8QXP_LDB is not set
-# CONFIG_DRM_IMX8QXP_PIXEL_COMBINER is not set
-# CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI is not set
-# CONFIG_DRM_DW_HDMI_GP_AUDIO is not set
-# CONFIG_VIDEO_IMX_MIPI_CSIS is not set
-# CONFIG_VIDEO_DW100 is not set
-# CONFIG_VIDEO_ROCKCHIP_ISP1 is not set
-# CONFIG_VIDEO_HANTRO is not set
-CONFIG_DTC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_ENCRYPTED_KEYS=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXTCON=y
-CONFIG_F2FS_FS=y
-CONFIG_FEC=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-# CONFIG_FSL_DPAA2_SWITCH is not set
-CONFIG_FSL_GUTS=y
-CONFIG_FS_ENCRYPTION=y
-CONFIG_FS_ENCRYPTION_ALGS=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=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_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_GENERIC_VDSO_32=y
-# CONFIG_GIANFAR is not set
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_MXC=y
-CONFIG_GPIO_VF610=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_IMX=y
-# CONFIG_I2C_IMX_LPI2C is not set
-CONFIG_I2C_SLAVE=y
-# CONFIG_I2C_SLAVE_TESTUNIT is not set
-CONFIG_IMX2_WDT=y
-# CONFIG_IMX7ULP_WDT is not set
-# CONFIG_IMX8MM_THERMAL is not set
-CONFIG_IMX_DMA=y
-# CONFIG_IMX_GPCV2_PM_DOMAINS is not set
-CONFIG_IMX_INTMUX=y
-CONFIG_IMX_IRQSTEER=y
-CONFIG_IMX_MU_MSI=m
-CONFIG_IMX_SDMA=y
-CONFIG_IMX_THERMAL=y
-# CONFIG_IMX_WEIM is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-# CONFIG_JFFS2_FS is not set
-CONFIG_KEYS=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CQHCI=y
-# CONFIG_MMC_MXC is not set
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_ESDHC_IMX=y
-CONFIG_MMC_SDHCI_IO_ACCESSORS=y
-CONFIG_MMC_SDHCI_OF_ESDHC=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MPILIB=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_GPMI_NAND=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-# CONFIG_MX3_IPU is not set
-CONFIG_MXC_CLK=y
-CONFIG_MXS_DMA=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEON=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_TAG_DSA=y
-CONFIG_NET_DSA_TAG_DSA_COMMON=y
-CONFIG_NET_DSA_TAG_EDSA=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-# CONFIG_NVMEM_IMX_IIM is not set
-CONFIG_NVMEM_IMX_OCOTP=y
-# CONFIG_NVMEM_IMX_OCOTP_ELE is not set
-CONFIG_NVMEM_LAYOUTS=y
-# CONFIG_NVMEM_SNVS_LPGPR is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0x80000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IMX8ULP is not set
-# CONFIG_PINCTRL_IMX93 is not set
-# CONFIG_PINCTRL_IMXRT1050 is not set
-# CONFIG_PINCTRL_IMXRT1170 is not set
-CONFIG_PL310_ERRATA_769419=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_OPP=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-# CONFIG_PWM_IMX1 is not set
-CONFIG_PWM_IMX27=y
-# CONFIG_PWM_IMX_TPM is not set
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_GZIP=y
-CONFIG_RD_LZO=y
-CONFIG_RD_XZ=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_ANATOP=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_PFUZE100=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_IMXDI is not set
-# CONFIG_RTC_DRV_MXC is not set
-# CONFIG_RTC_DRV_MXC_V2 is not set
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_THERMAL_PRESSURE=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_IMX_EARLYCON=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-# CONFIG_SOC_IMX50 is not set
-# CONFIG_SOC_IMX51 is not set
-# CONFIG_SOC_IMX53 is not set
-# CONFIG_SOC_IMX6Q is not set
-# CONFIG_SOC_IMX6SL is not set
-# CONFIG_SOC_IMX6SLL is not set
-# CONFIG_SOC_IMX6SX is not set
-# CONFIG_SOC_IMX6UL is not set
-# CONFIG_SOC_IMX7D is not set
-# CONFIG_SOC_IMX7ULP is not set
-# CONFIG_SOC_IMX8M is not set
-# CONFIG_SOC_IMX9 is not set
-# CONFIG_SOC_LS1021A is not set
-# CONFIG_SOC_VF610 is not set
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-# CONFIG_SPI_FSL_LPSPI is not set
-# CONFIG_SPI_FSL_QUADSPI is not set
-CONFIG_SPI_IMX=y
-CONFIG_SPI_MASTER=y
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-CONFIG_STMP_DEVICE=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=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_UCLAMP_TASK is not set
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_CHIPIDEA=y
-CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_IMX=y
-CONFIG_USB_CHIPIDEA_UDC=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_MXS_PHY=y
-CONFIG_USB_OTG=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ULPI_BUS=y
-CONFIG_USE_OF=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VMSPLIT_2G=y
-# CONFIG_VMSPLIT_3G is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/imx/config-6.6 b/target/linux/imx/config-6.6
index 6edc3560b4..6cb1d8a8f6 100644
--- a/target/linux/imx/config-6.6
+++ b/target/linux/imx/config-6.6
@@ -186,8 +186,6 @@ CONFIG_EDAC_SUPPORT=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FEC=y
@@ -199,7 +197,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
diff --git a/target/linux/imx/image/cortexa7.mk b/target/linux/imx/image/cortexa7.mk
index 3f89a99a83..6d2d0ab778 100644
--- a/target/linux/imx/image/cortexa7.mk
+++ b/target/linux/imx/image/cortexa7.mk
@@ -10,9 +10,7 @@ define Device/Default
KERNEL_NAME := zImage
KERNEL := kernel-bin | uImage none
KERNEL_LOADADDR := 0x80008000
-ifdef CONFIG_LINUX_6_6
DTS_DIR := $(DTS_DIR)/nxp/imx
-endif
IMAGES :=
endef
diff --git a/target/linux/imx/image/cortexa9.mk b/target/linux/imx/image/cortexa9.mk
index 1ff5bcb8a7..5f087c83ed 100644
--- a/target/linux/imx/image/cortexa9.mk
+++ b/target/linux/imx/image/cortexa9.mk
@@ -84,9 +84,7 @@ define Device/Default
KERNEL_NAME := zImage
KERNEL := kernel-bin | uImage none
KERNEL_LOADADDR := 0x10008000
-ifdef CONFIG_LINUX_6_6
DTS_DIR := $(DTS_DIR)/nxp/imx
-endif
IMAGES :=
endef
diff --git a/target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch b/target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch
deleted file mode 100644
index 01731755df..0000000000
--- a/target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From ffcbb4ccd357eeb649036e379a34bf5fb8d4f47c Mon Sep 17 00:00:00 2001
-From: Richard Zhu <hongxing.zhu@nxp.com>
-Date: Thu, 13 Oct 2022 09:47:00 +0800
-Subject: [PATCH 1/3] phy: freescale: imx8m-pcie: Refine register definitions
-
-No function changes, refine PHY register definitions.
-- Keep align with other CMN PHY registers, refine the definitions of
- PHY_CMN_REG75.
-- Remove two BIT definitions that are not used at all.
-
-Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
-Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-Tested-by: Marek Vasut <marex@denx.de>
-Tested-by: Richard Leitner <richard.leitner@skidata.com>
-Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
----
- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
---- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-@@ -32,12 +32,10 @@
- #define IMX8MM_PCIE_PHY_CMN_REG065 0x194
- #define ANA_AUX_RX_TERM (BIT(7) | BIT(4))
- #define ANA_AUX_TX_LVL GENMASK(3, 0)
--#define IMX8MM_PCIE_PHY_CMN_REG75 0x1D4
--#define PCIE_PHY_CMN_REG75_PLL_DONE 0x3
-+#define IMX8MM_PCIE_PHY_CMN_REG075 0x1D4
-+#define ANA_PLL_DONE 0x3
- #define PCIE_PHY_TRSV_REG5 0x414
--#define PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
- #define PCIE_PHY_TRSV_REG6 0x418
--#define PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
-
- #define IMX8MM_GPR_PCIE_REF_CLK_SEL GENMASK(25, 24)
- #define IMX8MM_GPR_PCIE_REF_CLK_PLL FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3)
-@@ -152,9 +150,8 @@ static int imx8_pcie_phy_power_on(struct
- }
-
- /* Polling to check the phy is ready or not. */
-- ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG75,
-- val, val == PCIE_PHY_CMN_REG75_PLL_DONE,
-- 10, 20000);
-+ ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075,
-+ val, val == ANA_PLL_DONE, 10, 20000);
- return ret;
- }
-
diff --git a/target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch b/target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch
deleted file mode 100644
index dbcfd40e57..0000000000
--- a/target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From bf03b9281b119bcdc167b2dd6ac98294587eb5ff Mon Sep 17 00:00:00 2001
-From: Richard Zhu <hongxing.zhu@nxp.com>
-Date: Thu, 13 Oct 2022 09:47:02 +0800
-Subject: [PATCH 3/3] phy: freescale: imx8m-pcie: Add i.MX8MP PCIe PHY support
-
-Add i.MX8MP PCIe PHY support.
-
-Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
-Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-Tested-by: Marek Vasut <marex@denx.de>
-Tested-by: Richard Leitner <richard.leitner@skidata.com>
-Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
-Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
----
- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 25 ++++++++++++++++++++--
- 1 file changed, 23 insertions(+), 2 deletions(-)
-
---- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-@@ -48,6 +48,7 @@
-
- enum imx8_pcie_phy_type {
- IMX8MM,
-+ IMX8MP,
- };
-
- struct imx8_pcie_phy_drvdata {
-@@ -60,6 +61,7 @@ struct imx8_pcie_phy {
- struct clk *clk;
- struct phy *phy;
- struct regmap *iomuxc_gpr;
-+ struct reset_control *perst;
- struct reset_control *reset;
- u32 refclk_pad_mode;
- u32 tx_deemph_gen1;
-@@ -74,11 +76,11 @@ static int imx8_pcie_phy_power_on(struct
- u32 val, pad_mode;
- struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
-
-- reset_control_assert(imx8_phy->reset);
--
- pad_mode = imx8_phy->refclk_pad_mode;
- switch (imx8_phy->drvdata->variant) {
- case IMX8MM:
-+ reset_control_assert(imx8_phy->reset);
-+
- /* Tune PHY de-emphasis setting to pass PCIe compliance. */
- if (imx8_phy->tx_deemph_gen1)
- writel(imx8_phy->tx_deemph_gen1,
-@@ -87,6 +89,8 @@ static int imx8_pcie_phy_power_on(struct
- writel(imx8_phy->tx_deemph_gen2,
- imx8_phy->base + PCIE_PHY_TRSV_REG6);
- break;
-+ case IMX8MP: /* Do nothing. */
-+ break;
- }
-
- if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ||
-@@ -143,6 +147,9 @@ static int imx8_pcie_phy_power_on(struct
- IMX8MM_GPR_PCIE_CMN_RST);
-
- switch (imx8_phy->drvdata->variant) {
-+ case IMX8MP:
-+ reset_control_deassert(imx8_phy->perst);
-+ fallthrough;
- case IMX8MM:
- reset_control_deassert(imx8_phy->reset);
- usleep_range(200, 500);
-@@ -183,8 +190,14 @@ static const struct imx8_pcie_phy_drvdat
- .variant = IMX8MM,
- };
-
-+static const struct imx8_pcie_phy_drvdata imx8mp_drvdata = {
-+ .gpr = "fsl,imx8mp-iomuxc-gpr",
-+ .variant = IMX8MP,
-+};
-+
- static const struct of_device_id imx8_pcie_phy_of_match[] = {
- {.compatible = "fsl,imx8mm-pcie-phy", .data = &imx8mm_drvdata, },
-+ {.compatible = "fsl,imx8mp-pcie-phy", .data = &imx8mp_drvdata, },
- { },
- };
- MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
-@@ -240,6 +253,14 @@ static int imx8_pcie_phy_probe(struct pl
- return PTR_ERR(imx8_phy->reset);
- }
-
-+ if (imx8_phy->drvdata->variant == IMX8MP) {
-+ imx8_phy->perst =
-+ devm_reset_control_get_exclusive(dev, "perst");
-+ if (IS_ERR(imx8_phy->perst))
-+ dev_err_probe(dev, PTR_ERR(imx8_phy->perst),
-+ "Failed to get PCIE PHY PERST control\n");
-+ }
-+
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- imx8_phy->base = devm_ioremap_resource(dev, res);
- if (IS_ERR(imx8_phy->base))
diff --git a/target/linux/imx/patches-6.1/100-bootargs.patch b/target/linux/imx/patches-6.1/100-bootargs.patch
deleted file mode 100644
index cf63a3bdb1..0000000000
--- a/target/linux/imx/patches-6.1/100-bootargs.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/arch/arm/boot/dts/imx6dl-wandboard.dts
-+++ b/arch/arm/boot/dts/imx6dl-wandboard.dts
-@@ -16,4 +16,8 @@
- device_type = "memory";
- reg = <0x10000000 0x40000000>;
- };
-+
-+ chosen {
-+ bootargs = "console=ttymxc0,115200";
-+ };
- };
diff --git a/target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch b/target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch
deleted file mode 100644
index 9db7098aaf..0000000000
--- a/target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 68604e89335ccb3e893b5a05b2c0d5cd2eaaf6ec Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
-Date: Tue, 3 Mar 2020 15:14:40 +0100
-Subject: [PATCH] ARM: dts: imx6q-apalis: ixora: add status LEDs aliases
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Petr Štetiar <ynezz@true.cz>
----
- arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts | 16 ++++++++++------
- arch/arm/boot/dts/imx6q-apalis-ixora.dts | 12 ++++++++----
- 2 files changed, 18 insertions(+), 10 deletions(-)
-
---- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-@@ -24,6 +24,10 @@
- i2c2 = &i2c2;
- rtc0 = &rtc_i2c;
- rtc1 = &snvs_rtc;
-+ led-boot = &led_boot;
-+ led-failsafe = &led_failsafe;
-+ led-running = &led_running;
-+ led-upgrade = &led_upgrade;
- };
-
- chosen {
-@@ -35,22 +39,22 @@
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_leds_ixora>;
-
-- led4-green {
-+ led_running: led4-green {
- gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
- label = "LED_4_GREEN";
- };
-
-- led4-red {
-+ led_upgrade: led4-red {
- gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
- label = "LED_4_RED";
- };
-
-- led5-green {
-+ led_boot: led5-green {
- gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
- label = "LED_5_GREEN";
- };
-
-- led5-red {
-+ led_failsafe: led5-red {
- gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
- label = "LED_5_RED";
- };
---- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-@@ -24,6 +24,10 @@
- i2c2 = &i2c2;
- rtc0 = &rtc_i2c;
- rtc1 = &snvs_rtc;
-+ led-boot = &led_boot;
-+ led-failsafe = &led_failsafe;
-+ led-running = &led_running;
-+ led-upgrade = &led_upgrade;
- };
-
- chosen {
-@@ -36,22 +40,22 @@
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_leds_ixora>;
-
-- led4-green {
-- gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
-+ led_running: led4-green {
-+ gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
- label = "LED_4_GREEN";
- };
-
-- led4-red {
-- gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
-+ led_upgrade: led4-red {
-+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
- label = "LED_4_RED";
- };
-
-- led5-green {
-+ led_boot: led5-green {
- gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
- label = "LED_5_GREEN";
- };
-
-- led5-red {
-+ led_failsafe: led5-red {
- gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
- label = "LED_5_RED";
- };
diff --git a/target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch b/target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch
deleted file mode 100644
index 95f572f35e..0000000000
--- a/target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From b6764bb27c819cdcf854371db485a43d71f579f3 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
-Date: Tue, 3 Mar 2020 15:15:57 +0100
-Subject: [PATCH] ARM: dts: imx6q-apalis: ixora: make switch3 reset button
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Petr Štetiar <ynezz@true.cz>
----
- arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts | 15 ++++++++++++++-
- arch/arm/boot/dts/imx6q-apalis-ixora.dts | 15 ++++++++++++++-
- 2 files changed, 28 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-@@ -59,6 +59,17 @@
- label = "LED_5_RED";
- };
- };
-+
-+ gpio-keys {
-+ pinctrl-0 = <&pinctrl_gpio_keys &pinctrl_switch3_ixora>;
-+
-+ reset {
-+ label = "reset";
-+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
-+ linux,code = <KEY_RESTART>;
-+ debounce-interval = <10>;
-+ };
-+ };
- };
-
- &can1 {
-@@ -181,4 +192,10 @@
- MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
- >;
- };
-+
-+ pinctrl_switch3_ixora: switch3ixora {
-+ fsl,pins = <
-+ MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x1b0b0
-+ >;
-+ };
- };
---- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-@@ -61,6 +61,17 @@
- };
- };
-
-+ gpio-keys {
-+ pinctrl-0 = <&pinctrl_gpio_keys &pinctrl_switch3_ixora>;
-+
-+ reset {
-+ label = "reset";
-+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
-+ linux,code = <KEY_RESTART>;
-+ debounce-interval = <10>;
-+ };
-+ };
-+
- reg_3v3_vmmc: regulator-3v3-vmmc {
- compatible = "regulator-fixed";
- enable-active-high;
-@@ -262,6 +273,12 @@
- >;
- };
-
-+ pinctrl_switch3_ixora: switch3ixora {
-+ fsl,pins = <
-+ MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x1b0b0
-+ >;
-+ };
-+
- pinctrl_mmc_cd_sleep: mmccdslpgrp {
- fsl,pins = <
- /* MMC1 CD */
diff --git a/target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch b/target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch
deleted file mode 100644
index f50199cdfc..0000000000
--- a/target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/arch/arm/boot/dts/imx7d-pico-pi.dts
-+++ b/arch/arm/boot/dts/imx7d-pico-pi.dts
-@@ -8,12 +8,20 @@
- model = "TechNexion PICO-IMX7D Board and PI baseboard";
- compatible = "technexion,imx7d-pico-pi", "fsl,imx7d";
-
-+ aliases {
-+ led-boot = &led_system;
-+ led-failsafe = &led_system;
-+ led-running = &led_system;
-+ led-upgrade = &led_system;
-+ label-mac-device = &fec1;
-+ };
-+
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_leds>;
-
-- led {
-+ led_system: led {
- label = "gpio-led";
- gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch b/target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch
deleted file mode 100644
index 5248e8c74c..0000000000
--- a/target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 6e8e5ccfbee7a531b035ffce3f95f3901946fa9d Mon Sep 17 00:00:00 2001
-From: Robert Nelson <robertcnelson@gmail.com>
-Date: Wed, 9 Jan 2019 14:33:24 -0600
-Subject: [PATCH] ARM: imx7d-pico-pi.dts: add default stdout-path
-
-Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
----
- arch/arm/boot/dts/imx7d-pico-pi.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/boot/dts/imx7d-pico-pi.dts
-+++ b/arch/arm/boot/dts/imx7d-pico-pi.dts
-@@ -16,6 +16,10 @@
- label-mac-device = &fec1;
- };
-
-+ chosen {
-+ stdout-path = "serial4:115200n8";
-+ };
-+
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
diff --git a/target/linux/ipq40xx/Makefile b/target/linux/ipq40xx/Makefile
index 30091e5d29..68a47c9082 100644
--- a/target/linux/ipq40xx/Makefile
+++ b/target/linux/ipq40xx/Makefile
@@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=ipq40xx
BOARDNAME:=Qualcomm Atheros IPQ40XX
-FEATURES:=squashfs fpu ramdisk nand
+FEATURES:=squashfs fpu ramdisk
CPU_TYPE:=cortex-a7
CPU_SUBTYPE:=neon-vfpv4
SUBTARGETS:=generic chromium mikrotik
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches b/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches
index 226785d46c..43ed32fc2b 100644
--- a/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches
+++ b/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches
@@ -6,6 +6,9 @@ board_config_update
board=$(board_name)
case "$board" in
+aruba,ap-303h)
+ ucidef_add_gpio_switch "poe_passtrough" "POE passtrough disable" "546" "1"
+ ;;
cellc,rtl30vw)
ucidef_add_gpio_switch "w_disable" "W_DISABLE mPCIE pin" "398" "1"
ucidef_add_gpio_switch "pmd_resin_n" "PMD_RESIN_N pin" "399" "1"
diff --git a/target/linux/ipq40xx/config-6.6 b/target/linux/ipq40xx/config-6.6
index 3049efc3d6..683463628f 100644
--- a/target/linux/ipq40xx/config-6.6
+++ b/target/linux/ipq40xx/config-6.6
@@ -306,11 +306,6 @@ CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_SPLIT_WRGG_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_NVMEM=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEON=y
@@ -532,7 +527,6 @@ CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNWINDER_ARM=y
diff --git a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts
index f8e24ca53d..957ccb306c 100644
--- a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts
+++ b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts
@@ -8,7 +8,7 @@
#include <dt-bindings/soc/qcom,tcsr.h>
/ {
- model = "ZyXEL NBG6617";
+ model = "Zyxel NBG6617";
compatible = "zyxel,nbg6617";
chosen {
@@ -239,7 +239,7 @@
partition12@6a0000 {
label = "not_root_data";
/*
- * for some strange reason, someone at ZyXEL
+ * for some strange reason, someone at Zyxel
* had the "great" idea to put the rootfs_data
* in front of rootfs... Don't do that!
* As a result this one, full MebiByte remains
diff --git a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts
index d59c41fab1..83ae05c626 100644
--- a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts
+++ b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts
@@ -22,7 +22,7 @@
#include <dt-bindings/soc/qcom,tcsr.h>
/ {
- model = "ZyXEL WRE6606";
+ model = "Zyxel WRE6606";
compatible = "zyxel,wre6606";
aliases {
diff --git a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4019-habanero-dvk.dts b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4019-habanero-dvk.dts
index c25b9ecf5b..94be4d976e 100644
--- a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4019-habanero-dvk.dts
+++ b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4019-habanero-dvk.dts
@@ -16,7 +16,6 @@
led-failsafe = &led_status;
led-running = &led_status;
led-upgrade = &led_upgrade;
- ethernet1 = &swport5;
};
soc {
@@ -266,6 +265,14 @@
#address-cells = <1>;
#size-cells = <1>;
+ macaddr_lan: macaddr@0 {
+ reg = <0x0 0x6>;
+ };
+
+ macaddr_wan: macaddr@6 {
+ reg = <0x6 0x6>;
+ };
+
precal_art_1000: precal@1000 {
reg = <0x1000 0x2f20>;
};
@@ -330,6 +337,9 @@
&gmac {
status = "okay";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_wan>;
};
&switch {
@@ -338,22 +348,37 @@
&swport1 {
status = "okay";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_lan>;
};
&swport2 {
status = "okay";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_lan>;
};
&swport3 {
status = "okay";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_lan>;
};
&swport4 {
status = "okay";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_lan>;
};
&swport5 {
status = "okay";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_wan>;
};
&wifi0 {
diff --git a/target/linux/ipq40xx/generic/config-default b/target/linux/ipq40xx/generic/config-default
new file mode 100644
index 0000000000..bd9876a0b6
--- /dev/null
+++ b/target/linux/ipq40xx/generic/config-default
@@ -0,0 +1,6 @@
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_NVMEM=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_UBIFS_FS=y
diff --git a/target/linux/ipq40xx/generic/target.mk b/target/linux/ipq40xx/generic/target.mk
index 90c1b762af..4ff40dea2b 100644
--- a/target/linux/ipq40xx/generic/target.mk
+++ b/target/linux/ipq40xx/generic/target.mk
@@ -1,3 +1,3 @@
BOARDNAME:=Generic
-FEATURES+=emmc
+FEATURES+=emmc nand
DEFAULT_PACKAGES += ath10k-board-qca4019
diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk
index 5f8082c99f..a2931ff01e 100644
--- a/target/linux/ipq40xx/image/generic.mk
+++ b/target/linux/ipq40xx/image/generic.mk
@@ -179,12 +179,14 @@ endef
define Device/aruba_ap-303
$(call Device/aruba_glenmorangie)
DEVICE_MODEL := AP-303
+ DEVICE_DTS_CONFIG := Glenmorangie@1
endef
TARGET_DEVICES += aruba_ap-303
define Device/aruba_ap-303h
$(call Device/aruba_glenmorangie)
DEVICE_MODEL := AP-303H
+ DEVICE_DTS_CONFIG := Aberlour@1
endef
TARGET_DEVICES += aruba_ap-303h
@@ -192,6 +194,7 @@ define Device/aruba_ap-365
$(call Device/aruba_glenmorangie)
DEVICE_MODEL := AP-365
DEVICE_PACKAGES := kmod-hwmon-ad7418
+ DEVICE_DTS_CONFIG := Bunker@1
endef
TARGET_DEVICES += aruba_ap-365
@@ -739,7 +742,7 @@ define Device/linksys_whw03
IMAGES += factory.bin
IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | linksys-image type=WHW03
DEVICE_PACKAGES := ath10k-firmware-qca9888-ct kmod-leds-pca963x kmod-spi-dev kmod-bluetooth \
- kmod-fs-ext4 e2fsprogs kmod-fs-f2fs mkf2fs losetup
+ kmod-fs-ext4 e2fsprogs kmod-fs-f2fs mkf2fs losetup ipq-wifi-linksys_whw03
endef
TARGET_DEVICES += linksys_whw03
@@ -1279,7 +1282,7 @@ TARGET_DEVICES += zte_mf289f
define Device/zyxel_nbg6617
$(call Device/FitImageLzma)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6617
SOC := qcom-ipq4018
KERNEL_SIZE := 4096k
@@ -1289,7 +1292,7 @@ define Device/zyxel_nbg6617
RAS_VERSION := "$(VERSION_DIST) $(REVISION)"
IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
IMAGES += factory.bin
-# The ZyXEL firmware allows flashing thru the web-gui only when the rootfs is
+# The Zyxel firmware allows flashing thru the web-gui only when the rootfs is
# at least as large as the one of the initial firmware image (not the current
# one on the device). This only applies to the Web-UI, the bootlaoder ignores
# this minimum-size. However, the larger image can be flashed both ways.
@@ -1301,7 +1304,7 @@ TARGET_DEVICES += zyxel_nbg6617
define Device/zyxel_wre6606
$(call Device/FitImage)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := WRE6606
DEVICE_DTS_CONFIG := config@4
SOC := qcom-ipq4018
diff --git a/target/linux/ipq40xx/mikrotik/config-default b/target/linux/ipq40xx/mikrotik/config-default
index ab470ecb41..805e6db23b 100644
--- a/target/linux/ipq40xx/mikrotik/config-default
+++ b/target/linux/ipq40xx/mikrotik/config-default
@@ -4,3 +4,9 @@ CONFIG_MTD_ROUTERBOOT_PARTS=y
CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
CONFIG_MTD_SPLIT_MINOR_FW=y
# CONFIG_NVMEM_LAYOUT_MIKROTIK is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_NVMEM=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_UBIFS_FS=y
diff --git a/target/linux/ipq40xx/mikrotik/target.mk b/target/linux/ipq40xx/mikrotik/target.mk
index 4530a90985..12bf8a4cd3 100644
--- a/target/linux/ipq40xx/mikrotik/target.mk
+++ b/target/linux/ipq40xx/mikrotik/target.mk
@@ -1,4 +1,4 @@
BOARDNAME:=MikroTik
-FEATURES += minor
+FEATURES += minor nand
KERNEL_IMAGES:=vmlinux
IMAGES_DIR:=compressed
diff --git a/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch b/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch
index 4910307c88..d9ecf4b640 100644
--- a/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch
+++ b/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch
@@ -996,7 +996,7 @@ Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+ .ndo_uninit = ipqess_uninit,
+ .ndo_open = ipqess_open,
+ .ndo_stop = ipqess_stop,
-+ .ndo_do_ioctl = ipqess_do_ioctl,
++ .ndo_eth_ioctl = ipqess_do_ioctl,
+ .ndo_start_xmit = ipqess_xmit,
+ .ndo_get_stats = ipqess_get_stats,
+ .ndo_set_mac_address = ipqess_set_mac_address,
diff --git a/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch b/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch
index 3d5b7afe8c..eab26ccb11 100644
--- a/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch
+++ b/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] UGW_SW-29163: ATM oam support
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
-@@ -2953,6 +2953,22 @@ char *ppp_dev_name(struct ppp_channel *c
+@@ -2968,6 +2968,22 @@ char *ppp_dev_name(struct ppp_channel *c
return name;
}
@@ -27,7 +27,7 @@ Subject: [PATCH] UGW_SW-29163: ATM oam support
/*
* Disconnect a channel from the generic layer.
-@@ -3599,6 +3615,7 @@ EXPORT_SYMBOL(ppp_unregister_channel);
+@@ -3614,6 +3630,7 @@ EXPORT_SYMBOL(ppp_unregister_channel);
EXPORT_SYMBOL(ppp_channel_index);
EXPORT_SYMBOL(ppp_unit_number);
EXPORT_SYMBOL(ppp_dev_name);
diff --git a/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts b/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts
index 7d22b4f541..9a9251e9b9 100644
--- a/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts
+++ b/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts
@@ -4,7 +4,7 @@
#include <dt-bindings/leds/common.h>
/ {
- model = "ZyXEL NBG6817";
+ model = "Zyxel NBG6817";
compatible = "zyxel,nbg6817", "qcom,ipq8065", "qcom,ipq8064";
memory@0 {
diff --git a/target/linux/ipq806x/image/generic.mk b/target/linux/ipq806x/image/generic.mk
index b5bf8898ab..112793d5fd 100644
--- a/target/linux/ipq806x/image/generic.mk
+++ b/target/linux/ipq806x/image/generic.mk
@@ -74,7 +74,7 @@ define Device/TpSafeImage
tplink-safeloader sysupgrade | append-metadata
endef
-define Device/ZyXELImage
+define Device/ZyxelImage
KERNEL_SUFFIX := -uImage
KERNEL = kernel-bin | append-dtb | uImage none | \
pad-to $$(KERNEL_SIZE)
@@ -578,7 +578,7 @@ TARGET_DEVICES += ubnt_unifi-ac-hd
define Device/zyxel_nbg6817
$(Device/dsa-migration)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6817
SOC := qcom-ipq8065
KERNEL_SIZE := 4096k
@@ -590,6 +590,6 @@ define Device/zyxel_nbg6817
SUPPORTED_DEVICES += nbg6817
DEVICE_PACKAGES := ath10k-firmware-qca9984-ct e2fsprogs \
kmod-fs-ext4 losetup
- $(call Device/ZyXELImage)
+ $(call Device/ZyxelImage)
endef
TARGET_DEVICES += zyxel_nbg6817
diff --git a/target/linux/kirkwood/Makefile b/target/linux/kirkwood/Makefile
index 44eaf925a1..2010f9a812 100644
--- a/target/linux/kirkwood/Makefile
+++ b/target/linux/kirkwood/Makefile
@@ -11,8 +11,7 @@ FEATURES:=rtc usb nand squashfs ramdisk
CPU_TYPE:=xscale
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/kirkwood/config-6.1 b/target/linux/kirkwood/config-6.1
deleted file mode 100644
index 6d21143e96..0000000000
--- a/target/linux/kirkwood/config-6.1
+++ /dev/null
@@ -1,309 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_CPU_AUTO=y
-# CONFIG_ARCH_MULTI_V4 is not set
-# CONFIG_ARCH_MULTI_V4T is not set
-CONFIG_ARCH_MULTI_V4_V5=y
-CONFIG_ARCH_MULTI_V5=y
-CONFIG_ARCH_MVEBU=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-# CONFIG_ARMADA_37XX_WATCHDOG is not set
-# CONFIG_ARMADA_THERMAL is not set
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-# CONFIG_ARM_KIRKWOOD_CPUIDLE is not set
-CONFIG_ARM_L1_CACHE_SHIFT=5
-# CONFIG_ARM_MVEBU_V7_CPUIDLE is not set
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_ATA=y
-CONFIG_ATAGS=y
-CONFIG_ATA_LEDS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CACHE_FEROCEON_L2=y
-# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_FEROCEON=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FEROCEON=y
-# CONFIG_CPU_FEROCEON_OLD_ID is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_LEGACY=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_FEROCEON=y
-CONFIG_CPU_USE_DOMAINS=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_MARVELL=y
-CONFIG_CRYPTO_DEV_MARVELL_CESA=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MVEBU_UART0_ALTERNATE=y
-# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=2
-CONFIG_DEBUG_UART_PHYS=0xf1012000
-CONFIG_DEBUG_UART_VIRT=0xfed12000
-CONFIG_DMA_OPS=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-# CONFIG_EARLY_PRINTK is not set
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FORCE_PCI=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_MVEBU=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_OMAP=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MV64XXX=y
-# CONFIG_I2C_PXA is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KIRKWOOD_CLK=y
-CONFIG_KIRKWOOD_THERMAL=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_NETXBIG=y
-CONFIG_LEDS_NS2=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACH_KIRKWOOD=y
-CONFIG_MACH_MVEBU_ANY=y
-CONFIG_MANGLE_BOOTARGS=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD_CFI is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-# CONFIG_MTD_NAND_MARVELL is not set
-CONFIG_MTD_NAND_ORION=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MV643XX_ETH=y
-CONFIG_MVEBU_CLK_COMMON=y
-CONFIG_MVEBU_MBUS=y
-CONFIG_MVMDIO=y
-# CONFIG_MVNETA is not set
-# CONFIG_MVPP2 is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_KUSER_HELPERS=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MV88E6XXX=y
-CONFIG_NET_DSA_TAG_DSA=y
-CONFIG_NET_DSA_TAG_DSA_COMMON=y
-CONFIG_NET_DSA_TAG_EDSA=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_ORION_IRQCHIP=y
-CONFIG_ORION_TIMER=y
-CONFIG_ORION_WATCHDOG=y
-CONFIG_OUTER_CACHE=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCI_BRIDGE_EMUL=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MVEBU=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_MVEBU_A3700_UTMI is not set
-# CONFIG_PHY_MVEBU_A38X_COMPHY is not set
-CONFIG_PHY_MVEBU_SATA=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_KIRKWOOD=y
-CONFIG_PINCTRL_MVEBU=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_SX150X=y
-CONFIG_PLAT_ORION=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_RESET_LINKSTATION=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_MV=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-# CONFIG_SERIAL_MVEBU_UART is not set
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SOC_BUS=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-# CONFIG_SPI_ARMADA_3700 is not set
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_ORION=y
-CONFIG_SPLIT_PTLOCK_CPUS=999999
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_LED_TRIG=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WAN=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts
deleted file mode 100644
index afeb76d5ff..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Device Tree file for DLINK DNS-320L
- *
- * Copyright (C) 2024, Zoltan HERPAI <wigyori@uid0.hu>
- * Copyright (C) 2015, Sunke Schlüters <sunke-dev@schlueters.de>
- *
- * 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 file is based on the works of:
- * - Sunke Schlüters <sunke-dev@schlueters.de>
- * - https://github.com/scus1/dns320l/blob/master/kernel/dts/kirkwood-dns320l.dts
- * - Andreas Böhler <dev@aboehler.at>:
- * - http://www.aboehler.at/doku/doku.php/projects:dns320l
- * - http://www.aboehler.at/hg/linux-dns320l/file/ba7a60ad7687/linux-3.12/kirkwood-dns320l.dts
- */
-
-/dts-v1/;
-
-#include "kirkwood.dtsi"
-#include "kirkwood-6281.dtsi"
-
-/ {
- model = "D-Link DNS-320L";
- compatible = "dlink,dns320l", "marvell,kirkwood-88f6702", "marvell,kirkwood";
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
- };
-
- gpio-keys {
- compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-0 = <&pmx_buttons>;
- pinctrl-names = "default";
-
- button@1 {
- label = "Reset push button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio0 28 1>;
- };
-
- button@2 {
- label = "USB unmount button";
- linux,code = <KEY_EJECTCD>;
- gpios = <&gpio0 27 1>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
- pinctrl-0 = <&pmx_leds>;
- pinctrl-names = "default";
-
- blue-usb {
- label = "dns320l:usb:blue";
- gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "usbport";
- };
-
- orange-usb {
- label = "dns320l:usb:orange";
- gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
- };
-
- orange-l-hdd {
- label = "dns320l:orange:l_hdd";
- gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
- };
-
- orange-r-hdd {
- label = "dns320l:orange:r_hdd";
- gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
- };
- };
-
- ocp@f1000000 {
- sata@80000 {
- status = "okay";
- nr-ports = <2>;
- };
-
- serial@12000 {
- status = "okay";
- };
-
- serial@12100 {
- pinctrl-0 = <&pmx_uart1>;
- pinctrl-names = "default";
- status = "okay";
- };
- };
-
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-0 = <&pmx_power_sata>;
- pinctrl-names = "default";
-
- sata_power: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "SATA Power";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpios = <&gpio0 24 0>;
- };
- };
-};
-
-&nand {
- pinctrl-0 = <&pmx_nand>;
- pinctrl-names = "default";
- chip-delay = <40>;
- status = "okay";
-
- partition@0 {
- label = "u-boot";
- reg = <0x0000000 0x100000>;
- };
-
- partition@100000 {
- label = "ubootenv";
- reg = <0x100000 0x20000>;
- };
-
- partition@120000 {
- label = "ubi";
- reg = <0x120000 0x6de0000>;
- };
-
- partition@6f00000 {
- label = "mini firmware";
- reg = <0x6f00000 0xa00000>;
- };
-
- partition@7900000 {
- label = "config";
- reg = <0x7900000 0x500000>;
- };
-
- partition@7e00000 {
- label = "my-dlink";
- reg = <0x7e00000 0x200000>;
- };
-};
-
-&mdio {
- status = "okay";
-
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
-};
-
-&pinctrl {
- pmx_sata1: pmx-sata1 {
- marvell,pins = "mpp20";
- marvell,function = "sata1";
- };
-
- pmx_sata0: pmx-sata0 {
- marvell,pins = "mpp21";
- marvell,function = "sata0";
- };
-
- pmx_power_sata: pmx-power-sata {
- marvell,pins = "mpp24";
- marvell,function = "gpio";
- };
-
- pmx_leds: pmx-leds {
- marvell,pins = "mpp22", "mpp23", "mpp25", "mpp26";
- marvell,function = "gpio";
- };
-
- pmx_buttons: pmx-buttons {
- marvell,pins = "mpp27", "mpp28", "mpp29";
- marvell,function = "gpio";
- };
-};
-
-&eth0 {
- status = "okay";
- ethernet0-port@0 {
- phy-handle = <&ethphy0>;
- };
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts
deleted file mode 100644
index bfd708a677..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "kirkwood-linksys-viper.dts"
-
-/ {
- model = "Linksys E4200 v2 (Viper)";
- compatible = "linksys,e4200-v2", "linksys,viper", "marvell,kirkwood-88f6282", "marvell,kirkwood";
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts
deleted file mode 100644
index e9f9e30bb4..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts
+++ /dev/null
@@ -1,243 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * kirkwood-linksys-audi.dts - Device Tree file for Linksys EA3500
- *
- * (c) 2013 Jonas Gorski <jogo@openwrt.org>
- * (c) 2013 Deutsche Telekom Innovation Laboratories
- * (c) 2014 Luka Perkov <luka@openwrt.org>
- * (c) 2014 Dan Walters <dan@walters.io>
- *
- */
-
-/dts-v1/;
-
-#include "kirkwood.dtsi"
-#include "kirkwood-6282.dtsi"
-
-/ {
- model = "Linksys EA3500 (Audi)";
- compatible = "linksys,ea3500", "linksys,audi", "marvell,kirkwood-88f6282", "marvell,kirkwood";
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x4000000>;
- };
-
- aliases {
- led-boot = &led_power;
- led-failsafe = &led_power;
- led-running = &led_power;
- led-upgrade = &led_power;
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- pinctrl-0 = <&pmx_btn_wps &pmx_btn_reset>;
- pinctrl-names = "default";
-
- wps {
- label = "WPS Button";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-
- reset {
- label = "Reset Button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- pinctrl-0 = <&pmx_led_green_power>;
- pinctrl-names = "default";
-
- led_power: power {
- label = "audi:green:power";
- gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
- };
-};
-
-&pinctrl {
- pmx_led_green_power: pmx-led-green-power {
- marvell,pins = "mpp7";
- marvell,function = "gpo";
- };
-
- pmx_btn_wps: pmx-btn-wps {
- marvell,pins = "mpp47";
- marvell,function = "gpio";
- };
-
- pmx_btn_reset: pmx-btn-reset {
- marvell,pins = "mpp48";
- marvell,function = "gpio";
- };
-};
-
-&mdio {
- status = "okay";
-
- switch@10 {
- compatible = "marvell,mv88e6085";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <16>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "ethernet1";
- };
-
- port@1 {
- reg = <1>;
- label = "ethernet2";
- };
-
- port@2 {
- reg = <2>;
- label = "ethernet3";
- };
-
- port@3 {
- reg = <3>;
- label = "ethernet4";
- };
-
- port@4 {
- reg = <4>;
- label = "internet";
- };
-
- port@5 {
- reg = <5>;
- phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
- };
-};
-
-&nand {
- status = "okay";
-
- pinctrl-0 = <&pmx_nand>;
- pinctrl-names = "default";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0 0x80000>;
- read-only;
- };
-
- partition@80000 {
- label = "u_env";
- reg = <0x80000 0x4000>;
- };
-
- partition@84000 {
- label = "s_env";
- reg = <0x84000 0x4000>;
- };
-
- partition@200000 {
- label = "kernel1";
- reg = <0x200000 0x1400000>;
- };
-
- partition@600000 {
- label = "rootfs1";
- reg = <0x600000 0x1000000>;
- };
-
- partition@1600000 {
- label = "kernel2";
- reg = <0x1600000 0x1400000>;
- };
-
- partition@1a00000 {
- label = "rootfs2";
- reg = <0x1a00000 0x1000000>;
- };
-
- partition@2a00000 {
- label = "syscfg";
- reg = <0x2a00000 0x1600000>;
- };
-
- partition@88000 {
- label = "unused";
- reg = <0x88000 0x178000>;
- };
- };
-};
-
-&pciec {
- status = "okay";
-};
-
-&pcie0 {
- status = "okay";
-};
-
-&pcie1 {
- status = "okay";
-};
-
-&mdio {
- status = "okay";
-};
-
-&uart0 {
- status = "okay";
-};
-
-/* eth0 is connected to a Marvell 88E6171 switch, without a PHY. So set
- * fixed speed and duplex.
- */
-&eth0 {
- status = "okay";
-
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
- phy-mode = "rgmii";
- };
-};
-
-/* eth1 is connected to the switch at port 6. However DSA only supports a
- * single CPU port. This port is disabled to avoid confusion.
- */
-&eth1 {
- status = "disabled";
-};
-
-/* There is no battery on the board, so the RTC does not keep
- * time when there is no power, making it useless.
- */
-&rtc {
- status = "disabled";
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts
deleted file mode 100644
index 495cff34a4..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "kirkwood-linksys-viper.dts"
-
-/ {
- model = "Linksys EA4500 (Viper)";
- compatible = "linksys,ea4500", "linksys,viper", "marvell,kirkwood-88f6282", "marvell,kirkwood";
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts
deleted file mode 100644
index 2f4109fe63..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts
+++ /dev/null
@@ -1,135 +0,0 @@
-/dts-v1/;
-
-#include "kirkwood.dtsi"
-#include "kirkwood-6281.dtsi"
-
-/ {
- model = "Seagate GoFlex Home";
- compatible = "seagate,goflexhome", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
- aliases {
- led-boot = &led_health;
- led-failsafe = &led_fault;
- led-running = &led_health;
- led-upgrade = &led_fault;
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10";
- stdout-path = &uart0;
- };
-
- ocp@f1000000 {
- pinctrl: pin-controller@10000 {
- pmx_usb_power_enable: pmx-usb-power-enable {
- marvell,pins = "mpp29";
- marvell,function = "gpio";
- };
-
- pmx_led_white: pmx-led-white {
- marvell,pins = "mpp40";
- marvell,function = "gpio";
- };
-
- pmx_led_green: pmx-led_green {
- marvell,pins = "mpp46";
- marvell,function = "gpio";
- };
-
- pmx_led_orange: pmx-led-orange {
- marvell,pins = "mpp47";
- marvell,function = "gpio";
- };
- };
-
- serial@12000 {
- status = "okay";
- };
-
- sata@80000 {
- status = "okay";
- nr-ports = <2>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- led_health: health {
- label = "status:green:health";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
- led_fault: fault {
- label = "status:orange:fault";
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-
- misc {
- label = "status:white:misc";
- gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "disk-activity";
- };
- };
-
- regulators {
- compatible = "simple-bus";
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- pinctrl-0 = <&pmx_usb_power_enable>;
- pinctrl-names = "default";
-
- usb_power: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "USB Power";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
- };
- };
-};
-
-&nand {
- status = "okay";
-
- chip-delay = <40>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0000000 0x0100000>;
- read-only;
- };
-
- partition@100000 {
- label = "ubi";
- reg = <0x0100000 0xff00000>;
- };
-};
-
-&mdio {
- status = "okay";
-
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
-};
-
-&eth0 {
- status = "okay";
-
- ethernet0-port@0 {
- phy-handle = <&ethphy0>;
- };
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts
deleted file mode 100644
index 6220fbf137..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts
+++ /dev/null
@@ -1,199 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/dts-v1/;
-
-#include "kirkwood.dtsi"
-#include "kirkwood-6281.dtsi"
-#include <dt-bindings/leds/common.h>
-
-/ {
- model = "Iomega ix4-200d";
- compatible = "iom,ix4-200d", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
- aliases {
- led-boot = &led_status_white;
- led-failsafe = &led_status_red;
- led-running = &led_power_white;
- led-upgrade = &led_status_red;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x20000000>;
- };
-
- ocp@f1000000 {
- i2c@11000 {
- status = "okay";
-
- adt7473@2e {
- compatible = "adi,adt7473";
- reg = <0x2e>;
- };
- };
-
- pinctrl: pin-controller@10000 {
- pmx_spi: pmx-spi {
- marvell,pins = "mpp12", "mpp13", "mpp14";
- marvell,function = "gpio";
- };
-
- pmx_keys: pmx-keys {
- marvell,pins = "mpp16", "mpp29", "mpp47", "mpp49";
- marvell,function = "gpio";
- };
- };
-
- sata@80000 {
- status = "okay";
- nr-ports = <2>;
- };
-
- serial@12000 {
- status = "okay";
- };
-
- spi3 {
- compatible = "spi-gpio";
- #address-cells = <0x1>;
- ranges;
- status = "okay";
- sck-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
- mosi-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
- cs-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
- num-chipselects = <1>;
- #size-cells = <0>;
-
- gpio_spi: gpio_spi@0 {
- compatible = "fairchild,74hc595";
- reg = <0>;
- gpio-controller;
- #gpio-cells = <2>;
- registers-number = <1>;
- spi-max-frequency = <100000>;
- };
- };
-
- gpio-keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&pmx_keys>;
- pinctrl-names = "default";
-
- button-0 {
- label = "Next Button";
- linux,code = <BTN_0>;
- gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
- };
-
- button-1 {
- label = "Reset Button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
- };
-
- button-2 {
- label = "Cancel Button";
- linux,code = <BTN_1>;
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-
- button-3 {
- label = "Power Button";
- linux,code = <KEY_POWER2>;
- gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- led_status_white: led-0 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio_spi 4 GPIO_ACTIVE_LOW>;
- };
-
- led_status_red: led-1 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio_spi 5 GPIO_ACTIVE_LOW>;
- };
-
- led_power_white: led-2 {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio_spi 7 GPIO_ACTIVE_HIGH>;
- };
- };
- };
-};
-
-&eth0 {
- status = "okay";
- ethernet0-port@0 {
- phy-handle = <&ethphy0>;
- };
-};
-
-&eth1 {
- status = "okay";
- ethernet1-port@0 {
- phy-handle = <&ethphy1>;
- };
-};
-
-&mdio {
- status = "okay";
-
- ethphy0: ethernet-phy@8 {
- reg = <8>;
- };
-
- ethphy1: ethernet-phy@9 {
- reg = <9>;
- };
-};
-
-&nand {
- status = "okay";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0000000 0x100000>;
- read-only;
- };
-
- partition@a0000 {
- label = "u-boot environment";
- reg = <0xa0000 0x20000>;
- read-only;
- };
-
- partition@100000 {
- label = "kernel";
- reg = <0x100000 0x400000>;
- };
-
- partition@500000 {
- label = "ubi";
- reg = <0x500000 0x1B00000>;
- };
- };
-};
-
-&pciec {
- status = "okay";
-};
-
-&pcie0 {
- status = "okay";
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts
deleted file mode 100644
index 0ceddb0d64..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts
+++ /dev/null
@@ -1,234 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/dts-v1/;
-
-#include <dt-bindings/leds/common.h>
-
-#include "kirkwood.dtsi"
-#include "kirkwood-6281.dtsi"
-
-/ {
- model = "ipTIME NAS1";
- compatible = "iptime,nas1", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
- aliases {
- serial0 = &uart0;
- led-boot = &led_ready;
- led-failsafe = &led_ready;
- led-running = &led_ready;
- led-upgrade = &led_ready;
- };
-
- chosen {
- /*
- * "root" argument from the stock bootloader should be ignored
- * as it'll prevent the kernel from finding the correct rootfs.
- */
- bootargs-append = " console=ttyS0,115200 root=";
- stdout-path = "serial0:115200n8";
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- pinctrl-0 = <&pmx_led>;
- pinctrl-names = "default";
-
- hdd {
- label = "blue:hdd";
- gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ata1";
- };
-
- usb {
- function = LED_FUNCTION_USB;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
- led_ready: ready {
- label = "blue:ready";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- pinctrl-0 = <&pmx_button>;
- pinctrl-names = "default";
-
- reset-copy {
- label = "Reset/Copy Button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
- };
-
- power {
- label = "Power Button";
- linux,code = <KEY_POWER>;
- gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
- };
- };
-
- gpio-fan {
- compatible = "gpio-fan";
-
- pinctrl-0 = <&pmx_fan>;
- pinctrl-names = "default";
- gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>,
- <&gpio1 10 GPIO_ACTIVE_HIGH>;
- /* We don't know the exact rpm, just use dummy values here. */
- gpio-fan,speed-map = <0 0>, <1 1>, <2 2>;
- #cooling-cells = <2>;
- };
-
- gpio-poweroff {
- compatible = "gpio-poweroff";
- gpios = <&pca9536 0 GPIO_ACTIVE_LOW>;
- };
-
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
-
- pinctrl-0 = <&pmx_usb_vbus>;
- pinctrl-names = "default";
-
- regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "USB Power";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- regulator-always-on;
- gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
- };
- };
-};
-
-&pinctrl {
- pmx_led: pmx-led {
- marvell,pins = "mpp35", "mpp45", "mpp46";
- marvell,function = "gpio";
- };
-
- pmx_fan: pmx-fan {
- marvell,pins = "mpp41", "mpp42";
- marvell,function = "gpio";
- };
-
- pmx_usb_vbus: pmx-usb-vbus {
- marvell,pins = "mpp43";
- marvell,function = "gpio";
- };
-
- pmx_button: pmx-button {
- marvell,pins = "mpp44", "mpp48";
- marvell,function = "gpio";
- };
-};
-
-&spi0 {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <20000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0 0x40000>;
- read-only;
- };
-
- partition@40000 {
- compatible = "openwrt,uimage", "denx,uimage";
- openwrt,offset = <0x400>;
- label = "firmware";
- reg = <0x40000 0xf80000>;
- };
-
- partition@fc0000 {
- label = "config";
- reg = <0xfc0000 0x40000>;
- read-only;
- };
- };
- };
-};
-
-&rtc {
- status = "disabled";
-};
-
-&i2c0 {
- status = "okay";
-
- pca9536: gpio@41 {
- compatible = "nxp,pca9536";
- reg = <0x41>;
- gpio-controller;
- #gpio-cells = <2>;
- };
-};
-
-&uart0 {
- status = "okay";
-};
-
-&usb0 {
- status = "okay";
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- ehci_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-};
-
-&mdio {
- status = "okay";
-
- ethphyb: ethernet-phy@b {
- reg = <0x0b>;
- };
-};
-
-&eth1 {
- status = "okay";
-};
-
-&eth1port {
- phy-handle = <&ethphyb>;
- phy-connection-type = "rgmii-id";
-};
-
-&sata {
- status = "okay";
-
- #address-cells = <1>;
- #size-cells = <0>;
- nr-ports = <1>;
-
- sata-port@0 {
- reg = <0>;
- #thermal-sensor-cells = <0>;
- };
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts
deleted file mode 100644
index 12e51d6656..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts
+++ /dev/null
@@ -1,144 +0,0 @@
-/dts-v1/;
-
-#include "kirkwood-nsa3x0-common.dtsi"
-
-/*
- * There are at least two different NSA310 designs. This variant has
- * a red/green USB Led (same as nsa310) and a lm85 temp/fan controller.
- */
-
-/ {
- model = "ZyXEL NSA310b";
- compatible = "zyxel,nsa310b", "zyxel,nsa310", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
- aliases {
- led-boot = &led_green_sys;
- led-failsafe = &led_red_sys;
- led-running = &led_green_sys;
- led-upgrade = &led_red_sys;
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &uart0;
- };
-
- ocp@f1000000 {
- pinctrl: pin-controller@10000 {
- pinctrl-names = "default";
-
- pmx_led_esata_green: pmx-led-esata-green {
- marvell,pins = "mpp12";
- marvell,function = "gpio";
- };
-
- pmx_led_esata_red: pmx-led-esata-red {
- marvell,pins = "mpp13";
- marvell,function = "gpio";
- };
-
- pmx_led_usb_green: pmx-led-usb-green {
- marvell,pins = "mpp15";
- marvell,function = "gpio";
- };
-
- pmx_led_usb_red: pmx-led-usb-red {
- marvell,pins = "mpp16";
- marvell,function = "gpio";
- };
-
- pmx_led_sys_green: pmx-led-sys-green {
- marvell,pins = "mpp28";
- marvell,function = "gpio";
- };
-
- pmx_led_sys_red: pmx-led-sys-red {
- marvell,pins = "mpp29";
- marvell,function = "gpio";
- };
-
- pmx_led_hdd_green: pmx-led-hdd-green {
- marvell,pins = "mpp41";
- marvell,function = "gpio";
- };
-
- pmx_led_hdd_red: pmx-led-hdd-red {
- marvell,pins = "mpp42";
- marvell,function = "gpio";
- };
-
- };
-
- i2c@11000 {
- status = "okay";
-
- lm85: lm85@2e {
- compatible = "national,lm85";
- reg = <0x2e>;
- };
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- led_green_sys: green-sys {
- label = "nsa310:green:sys";
- gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
-
- led_red_sys: red-sys {
- label = "nsa310:red:sys";
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
- };
-
- green-hdd {
- label = "nsa310:green:hdd";
- gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ata1";
- };
-
- red-hdd {
- label = "nsa310:red:hdd";
- gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
- };
-
- green-esata {
- label = "nsa310:green:esata";
- gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ata2";
- };
-
- red-esata {
- label = "nsa310:red:esata";
- gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
- };
-
- green-usb {
- label = "nsa310:green:usb";
- gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "usb-host";
- };
-
- red-usb {
- label = "nsa310:red:usb";
- gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
- };
-
- green-copy {
- label = "nsa310:green:copy";
- gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
- };
-
- red-copy {
- label = "nsa310:red:copy";
- gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
- };
- };
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts
deleted file mode 100644
index 5ae66ede2f..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts
+++ /dev/null
@@ -1,165 +0,0 @@
-/dts-v1/;
-
-#include "kirkwood.dtsi"
-#include "kirkwood-6282.dtsi"
-
-/ {
- model = "Cisco Systems ON100";
- compatible = "cisco,on100", "marvell,kirkwood-88f6282", "marvell,kirkwood";
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x20000000>;
- };
-
- aliases {
- led-boot = &led_health_green;
- led-failsafe = &led_health_red;
- led-running = &led_health_green;
- led-upgrade = &led_health_red;
- serial0 = &uart0;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = "serial0:115200n8";
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- pinctrl-0 = <&pmx_btn_reset>;
- pinctrl-names = "default";
-
- reset {
- label = "Reset Button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- pinctrl-0 = <&pmx_led_health_red &pmx_led_health_green>;
- pinctrl-names = "default";
-
- led_health_green: health-green {
- label = "on100:green:health";
- gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
- led_health_red: health-red {
- label = "on100:red:health";
- gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
- };
-
- health2-green {
- label = "on100:green:health2";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
- };
-
- health2-red {
- label = "on100:red:health2";
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&eth0 {
- status = "okay";
-
- ethernet0-port@0 {
- phy-handle = <&ethphy0>;
- phy-connection-type = "rgmii-id";
- };
-};
-
-&eth1 {
- status = "okay";
-
- ethernet1-port@0 {
- phy-handle = <&ethphy1>;
- phy-connection-type = "rgmii-id";
- };
-};
-
-&mdio {
- status = "okay";
-
- ethphy0: ethernet-phy@0 {
- /* Marvell 88E1121R */
- compatible = "ethernet-phy-id0141.0cb0",
- "ethernet-phy-ieee802.3-c22";
- reg = <0>;
- };
-
- ethphy1: ethernet-phy@1 {
- /* Marvell 88E1121R */
- compatible = "ethernet-phy-id0141.0cb0",
- "ethernet-phy-ieee802.3-c22";
- reg = <1>;
- };
-};
-
-&nand {
- status = "okay";
-
- partition@0 {
- label = "u-boot";
- reg = <0x00000000 0x000a0000>;
- read-only;
- };
-
- partition@a0000 {
- label = "u-boot environment";
- reg = <0x000a0000 0x00020000>;
- read-only;
- };
-
- partition@c0000 {
- label = "kernel";
- reg = <0x000c0000 0x00540000>;
- };
-
- partition@600000 {
- label = "ubi";
- reg = <0x00600000 0x1fa00000>;
- };
-};
-
-&pinctrl {
- pmx_led_health_red: pmx-led-health-red {
- marvell,pins = "mpp45";
- marvell,function = "gpio";
- };
-
- pmx_led_health_green: pmx-led-health-green {
- marvell,pins = "mpp44";
- marvell,function = "gpio";
- };
-
- pmx_led_health2_red: pmx-led-health2-red {
- marvell,pins = "mpp47";
- marvell,function = "gpio";
- };
-
- pmx_led_health2_green: pmx-led-health2-green {
- marvell,pins = "mpp46";
- marvell,function = "gpio";
- };
-
- pmx_btn_reset: pmx-btn-reset {
- marvell,pins = "mpp31";
- marvell,function = "gpio";
- };
-};
-
-&sdio {
- status = "okay";
-};
-
-&uart0 {
- status = "okay";
-};
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts
deleted file mode 100644
index 577c009144..0000000000
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts
+++ /dev/null
@@ -1,227 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Device Tree file for NETGEAR Stora (MS2000/2110)
- *
- * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
- * Copyright (C) 2021, Zoltan HERPAI <wigyori@uid0.hu>
- */
-
-/dts-v1/;
-
-#include "kirkwood.dtsi"
-#include "kirkwood-6281.dtsi"
-
-/ {
- model = "NETGEAR Stora (MS2000/2110)";
- compatible = "netgear,stora", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
- memory { /* 128 MB */
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
- };
-
- aliases {
- led-boot = &led_power;
- led-failsafe = &led_power;
- led-running = &led_power;
- led-upgrade = &led_power;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
- };
-
- ocp@f1000000 {
- pinctrl: pin-controller@10000 {
- pmx_button_power: pmx-button-power {
- marvell,pins = "mpp36";
- marvell,function = "gpio";
- };
-
- pmx_button_reset: pmx-button-reset {
- marvell,pins = "mpp38";
- marvell,function = "gpio";
- };
-
- pmx_led_blue_power: pmx-led-blue-power {
- marvell,pins = "mpp31";
- marvell,function = "gpio";
- };
-
- pmx_led_green_disk1: pmx-led-green-disk1 {
- marvell,pins = "mpp21";
- marvell,function = "gpio";
- };
-
- pmx_led_green_disk2: pmx-led-green-disk2 {
- marvell,pins = "mpp20";
- marvell,function = "gpio";
- };
-
- pmx_led_red_disk1: pmx-led-red-disk1 {
- marvell,pins = "mpp23";
- marvell,function = "gpio";
- };
-
- pmx_led_red_disk2: pmx-led-red-disk2 {
- marvell,pins = "mpp22";
- marvell,function = "gpio";
- };
-
- pmx_poweroff: pmx-poweroff {
- marvell,pins = "mpp40";
- marvell,function = "gpio";
- };
-
- pmx_fan_tacho: pmx-fan-tacho {
- marvell,pins = "mpp41";
- marvell,function = "gpio";
- };
- };
-
- clocks {
- pcf8563_clk: pcf8563-oscillator {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <2048>;
- };
- };
-
- i2c@11000 {
- status = "okay";
-
- tc654@1b {
- compatible = "microchip,tc654";
- reg = <0x1b>;
- };
-
- lm75@48 {
- compatible = "national,lm75";
- reg = <0x48>;
- };
-
- pcf8563@51 {
- compatible = "nxp,pcf8563";
- reg = <0x51>;
- };
- };
-
- serial@12000 {
- status = "okay";
- };
-
- sata@80000 {
- status = "okay";
- phy-names = "port0", "port1";
- nr-ports = <2>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
- pinctrl-0 = < &pmx_led_blue_power
- &pmx_led_green_disk1 &pmx_led_green_disk2
- &pmx_led_red_disk1 &pmx_led_red_disk2 >;
- pinctrl-names = "default";
-
- led_power: power {
- label = "blue:power";
- gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
- disk1 {
- label = "green:disk1";
- gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "ata1";
- };
-
- disk2 {
- label = "green:disk2";
- gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "ata2";
- };
-
- disk1_fail {
- label = "red:disk1_fail";
- gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
- };
-
- disk2_fail {
- label = "red:disk2_fail";
- gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&pmx_button_power &pmx_button_reset >;
- pinctrl-names = "default";
-
- power {
- label = "Power Button";
- linux,code = <KEY_POWER>;
- gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
- };
-
- reset {
- label = "Reset Button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-poweroff {
- compatible = "gpio-poweroff";
- pinctrl-0 = <&pmx_poweroff>;
- pinctrl-names = "default";
- gpios = <&gpio0 40 GPIO_ACTIVE_LOW>;
- };
-};
-
-&nand {
- status = "okay";
- chip-delay = <40>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0000000 0x0e0000>;
- read-only;
- };
-
- partition@e0000 {
- label = "u-boot-env";
- reg = <0x0e00000 0x020000>;
- };
-
- partition@100000 {
- label = "ubi";
- reg = <0x0100000 0xff00000>;
- };
-};
-
-&mdio {
- status = "okay";
-
- ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
- compatible = "marvell,88e1116";
- reg = <8>;
- };
-};
-
-&eth0 {
- status = "okay";
-
- ethernet0-port@0 {
- phy-handle = <&ethphy0>;
- };
-};
-
-&pciec {
- status = "okay";
-};
-
-&pcie0 {
- status = "okay";
-};
diff --git a/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts b/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts
index 12e51d6656..594be97929 100644
--- a/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts
+++ b/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts
@@ -8,7 +8,7 @@
*/
/ {
- model = "ZyXEL NSA310b";
+ model = "Zyxel NSA310b";
compatible = "zyxel,nsa310b", "zyxel,nsa310", "marvell,kirkwood-88f6281", "marvell,kirkwood";
aliases {
diff --git a/target/linux/kirkwood/image/Makefile b/target/linux/kirkwood/image/Makefile
index 2bd2f64159..eaced92657 100644
--- a/target/linux/kirkwood/image/Makefile
+++ b/target/linux/kirkwood/image/Makefile
@@ -112,9 +112,7 @@ endef
define Device/Default
PROFILES := Default
-ifdef CONFIG_LINUX_6_6
DEVICE_DTS_DIR := $(DTS_DIR)/marvell
-endif
DEVICE_DTS = kirkwood-$(lastword $(subst _, ,$(1)))
KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
KERNEL := kernel-bin | append-dtb | uImage none
@@ -375,7 +373,7 @@ endef
TARGET_DEVICES += seagate_goflexhome
define Device/zyxel_nsa310b
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NSA310b
DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-r8169 kmod-fs-ext4 \
kmod-gpio-button-hotplug kmod-hwmon-lm85 kmod-rtc-mv
@@ -384,7 +382,7 @@ endef
TARGET_DEVICES += zyxel_nsa310b
define Device/zyxel_nsa310s
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NSA310S
DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
kmod-gpio-button-hotplug kmod-rtc-mv
@@ -392,7 +390,7 @@ endef
TARGET_DEVICES += zyxel_nsa310s
define Device/zyxel_nsa325
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NSA325
DEVICE_VARIANT := v1/v2
DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
diff --git a/target/linux/kirkwood/image/generic.mk b/target/linux/kirkwood/image/generic.mk
deleted file mode 100644
index fff46be172..0000000000
--- a/target/linux/kirkwood/image/generic.mk
+++ /dev/null
@@ -1,177 +0,0 @@
-define Device/checkpoint_l-50
- DEVICE_VENDOR := Check Point
- DEVICE_MODEL := L-50
- DEVICE_PACKAGES := kmod-ath9k kmod-gpio-button-hotplug kmod-mvsdio \
- kmod-rtc-s35390a kmod-usb-ledtrig-usbport wpad-basic-mbedtls
- IMAGES := sysupgrade.bin
-endef
-TARGET_DEVICES += checkpoint_l-50
-
-define Device/cisco_on100
- DEVICE_VENDOR := Cisco Systems
- DEVICE_MODEL := ON100
- KERNEL_SIZE := 5376k
- KERNEL_IN_UBI :=
- UBINIZE_OPTS := -E 5
- IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
- DEVICE_PACKAGES := kmod-mvsdio kmod-rtc-mv
- SUPPORTED_DEVICES += on100
-endef
-TARGET_DEVICES += cisco_on100
-
-define Device/cloudengines_pogoe02
- DEVICE_VENDOR := Cloud Engines
- DEVICE_MODEL := Pogoplug E02
- DEVICE_DTS := kirkwood-pogo_e02
- DEVICE_PACKAGES := kmod-rtc-mv
- SUPPORTED_DEVICES += pogo_e02
-endef
-TARGET_DEVICES += cloudengines_pogoe02
-
-define Device/cloudengines_pogoplugv4
- DEVICE_VENDOR := Cloud Engines
- DEVICE_MODEL := Pogoplug V4
- DEVICE_DTS := kirkwood-pogoplug-series-4
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-mvsdio kmod-usb3 \
- kmod-gpio-button-hotplug kmod-rtc-mv
-endef
-TARGET_DEVICES += cloudengines_pogoplugv4
-
-define Device/ctera_c200-v1
- DEVICE_VENDOR := Ctera
- DEVICE_MODEL := C200
- DEVICE_VARIANT := V1
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-gpio-button-hotplug \
- kmod-hwmon-lm63 kmod-rtc-s35390a kmod-usb-ledtrig-usbport
- KERNEL := kernel-bin | append-dtb | uImage none | ctera-firmware
- KERNEL_IN_UBI :=
- KERNEL_SUFFIX := -factory.firm
- IMAGES := sysupgrade.bin
-endef
-TARGET_DEVICES += ctera_c200-v1
-
-define Device/endian_4i-edge-200
- DEVICE_VENDOR := Endian
- DEVICE_MODEL := 4i Edge 200
- DEVICE_ALT0_VENDOR := Endian
- DEVICE_ALT0_MODEL := UTM Mini Firewall
- DEVICE_PACKAGES := kmod-ath9k kmod-mvsdio wpad-basic-mbedtls kmod-rtc-mv
- KERNEL_SIZE := 4096k
- IMAGES := sysupgrade.bin
-endef
-TARGET_DEVICES += endian_4i-edge-200
-
-define Device/globalscale_sheevaplug
- DEVICE_VENDOR := Globalscale
- DEVICE_MODEL := Sheevaplug
- DEVICE_PACKAGES := kmod-mvsdio kmod-rtc-mv
-endef
-TARGET_DEVICES += globalscale_sheevaplug
-
-define Device/iom_iconnect-1.1
- DEVICE_VENDOR := Iomega
- DEVICE_MODEL := Iconnect
- DEVICE_PACKAGES := kmod-rtc-mv
- DEVICE_DTS := kirkwood-iconnect
- SUPPORTED_DEVICES += iconnect
-endef
-TARGET_DEVICES += iom_iconnect-1.1
-
-define Device/iptime_nas1
- DEVICE_VENDOR := ipTIME
- DEVICE_MODEL := NAS1
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-gpio-pca953x kmod-hwmon-drivetemp \
- kmod-hwmon-gpiofan kmod-usb-ledtrig-usbport kmod-rtc-mv kmod-thermal \
- -uboot-envtools
- KERNEL := $$(KERNEL) | iptime-naspkg nas1
- BLOCKSIZE := 256k
- IMAGE_SIZE := 15872k
- IMAGES := sysupgrade.bin
- IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | \
- check-size | append-metadata
-endef
-TARGET_DEVICES += iptime_nas1
-
-define Device/netgear_readynas-duo-v2
- DEVICE_VENDOR := NETGEAR
- DEVICE_MODEL := ReadyNAS Duo
- DEVICE_VARIANT := v2
- DEVICE_DTS := kirkwood-netgear_readynas_duo_v2
- KERNEL_IN_UBI :=
- IMAGES := sysupgrade.bin
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-hwmon-g762 kmod-rtc-rs5c372a kmod-usb3
-endef
-TARGET_DEVICES += netgear_readynas-duo-v2
-
-define Device/raidsonic_ib-nas62x0
- DEVICE_VENDOR := RaidSonic
- DEVICE_MODEL := ICY BOX IB-NAS62x0
- DEVICE_DTS := kirkwood-ib62x0
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-rtc-mv
- SUPPORTED_DEVICES += ib62x0
-endef
-TARGET_DEVICES += raidsonic_ib-nas62x0
-
-define Device/seagate_blackarmor-nas220
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := Blackarmor NAS220
- DEVICE_PACKAGES := kmod-hwmon-adt7475 kmod-fs-ext4 kmod-ata-marvell-sata \
- mdadm kmod-gpio-button-hotplug kmod-rtc-mv
- PAGESIZE := 512
- SUBPAGESIZE := 256
- BLOCKSIZE := 16k
- UBINIZE_OPTS := -e 1
-endef
-TARGET_DEVICES += seagate_blackarmor-nas220
-
-define Device/seagate_dockstar
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := FreeAgent Dockstar
- DEVICE_PACKAGES := kmod-rtc-mv
- SUPPORTED_DEVICES += dockstar
-endef
-TARGET_DEVICES += seagate_dockstar
-
-define Device/seagate_goflexnet
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := GoFlexNet
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-rtc-mv
- SUPPORTED_DEVICES += goflexnet
-endef
-TARGET_DEVICES += seagate_goflexnet
-
-define Device/seagate_goflexhome
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := GoFlexHome
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-rtc-mv
- SUPPORTED_DEVICES += goflexhome
-endef
-TARGET_DEVICES += seagate_goflexhome
-
-define Device/zyxel_nsa310b
- DEVICE_VENDOR := ZyXEL
- DEVICE_MODEL := NSA310b
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-r8169 kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-hwmon-lm85 kmod-rtc-mv
- SUPPORTED_DEVICES += nsa310b
-endef
-TARGET_DEVICES += zyxel_nsa310b
-
-define Device/zyxel_nsa310s
- DEVICE_VENDOR := ZyXEL
- DEVICE_MODEL := NSA310S
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-gpio-button-hotplug
-endef
-TARGET_DEVICES += zyxel_nsa310s
-
-define Device/zyxel_nsa325
- DEVICE_VENDOR := ZyXEL
- DEVICE_MODEL := NSA325
- DEVICE_VARIANT := v1/v2
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-rtc-pcf8563 kmod-usb3
- SUPPORTED_DEVICES += nsa325
-endef
-TARGET_DEVICES += zyxel_nsa325
diff --git a/target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch b/target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch
deleted file mode 100644
index 6a8e8e8c9b..0000000000
--- a/target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch
+++ /dev/null
@@ -1,301 +0,0 @@
-From e977a103840c57d72b52cbc8c17f87f86ef9aa8d Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Sat, 29 Oct 2022 22:57:38 +0200
-Subject: [PATCH] ARM: dts: kirkwood: Add Zyxel NSA310S board
-
-Zyxel NSA310S is a NAS based on Marvell kirkwood SoC.
-
-Specification:
- - Processor Marvell 88F6702 1 GHz
- - 256MB RAM
- - 128MB NAND
- - 1x GBE LAN port (PHY: Marvell 88E1318)
- - 2x USB 2.0
- - 1x SATA
- - 3x button
- - 7x leds
- - serial on J1 connector (115200 8N1) (GND-NOPIN-RX-TX-VCC)
-
-Tested-by: Tony Dinh <mibodhi@gmail.com>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
-Acked-by: Adam Baker <linux@baker-net.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/kirkwood-nsa310s.dts | 259 +++++++++++++++++++++++++
- 2 files changed, 260 insertions(+)
- create mode 100644 arch/arm/boot/dts/kirkwood-nsa310s.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -356,6 +356,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
- kirkwood-ns2mini.dtb \
- kirkwood-nsa310.dtb \
- kirkwood-nsa310a.dtb \
-+ kirkwood-nsa310s.dtb \
- kirkwood-nsa320.dtb \
- kirkwood-nsa325.dtb \
- kirkwood-openblocks_a6.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/kirkwood-nsa310s.dts
-@@ -0,0 +1,259 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * ZyXEL NSA310S Board Description
-+ * Copyright 2020-2022 Pawel Dembicki <paweldembicki@gmail.com>
-+ * Copyright (c) 2015-2021, Tony Dinh <mibodhi@gmail.com>
-+ * Copyright (c) 2014, Adam Baker <linux@baker-net.org.uk>
-+ * Based upon the board setup file created by Peter Schildmann
-+ */
-+/dts-v1/;
-+
-+#include "kirkwood.dtsi"
-+#include "kirkwood-6281.dtsi"
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ model = "ZyXEL NSA310S";
-+ compatible = "zyxel,nsa310s", "marvell,kirkwood-88f6702", "marvell,kirkwood";
-+
-+ memory {
-+ device_type = "memory";
-+ reg = <0x00000000 0x10000000>;
-+ };
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200n8 earlyprintk";
-+ stdout-path = &uart0;
-+ };
-+
-+ gpio_poweroff {
-+ compatible = "gpio-poweroff";
-+ pinctrl-0 = <&pmx_pwr_off>;
-+ pinctrl-names = "default";
-+ gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ keys {
-+ compatible = "gpio-keys";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ pinctrl-0 = <&pmx_buttons>;
-+ pinctrl-names = "default";
-+
-+ power {
-+ label = "Power Button";
-+ linux,code = <KEY_POWER>;
-+ gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ copy {
-+ label = "Copy Button";
-+ linux,code = <KEY_COPY>;
-+ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ reset {
-+ label = "Reset Button";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+ pinctrl-0 = <&pmx_leds>;
-+ pinctrl-names = "default";
-+
-+ led-1 {
-+ function = LED_FUNCTION_DISK_ERR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-2 {
-+ function = LED_FUNCTION_USB;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "usb-host";
-+ };
-+
-+ led-3 {
-+ function = LED_FUNCTION_DISK;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "ata1";
-+ };
-+
-+ led-4 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-5 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-6 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ led-7 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ usb0_power: regulator@1 {
-+ compatible = "regulator-fixed";
-+ regulator-name = "USB Power";
-+
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ regulator-always-on;
-+ regulator-boot-on;
-+ gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ sata1_power: regulator@2 {
-+ compatible = "regulator-fixed";
-+ regulator-name = "SATA1 Power";
-+
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ regulator-always-on;
-+ regulator-boot-on;
-+ gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ thermal-zones {
-+ disk-thermal {
-+ polling-delay = <20000>;
-+ polling-delay-passive = <2000>;
-+
-+ thermal-sensors = <&hdd_temp>;
-+
-+ trips {
-+ disk_alert: disk-alert {
-+ temperature = <40000>;
-+ hysteresis = <5000>;
-+ type = "active";
-+ };
-+ disk_crit: disk-crit {
-+ temperature = <60000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+
-+&eth0 {
-+ status = "okay";
-+
-+ ethernet0-port@0 {
-+ phy-handle = <&ethphy0>;
-+ };
-+};
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ rtc@68 {
-+ compatible = "htk,ht1382";
-+ reg = <0x68>;
-+ };
-+};
-+
-+&mdio {
-+ status = "okay";
-+
-+ ethphy0: ethernet-phy@1 {
-+ reg = <1>;
-+ phy-mode = "rgmii-id";
-+ marvell,reg-init = <0x1 0x16 0x0 0x3>,
-+ <0x1 0x10 0x0 0x1017>,
-+ <0x1 0x11 0x0 0x4408>,
-+ <0x1 0x16 0x0 0x0>;
-+ };
-+};
-+
-+&nand {
-+ status = "okay";
-+ chip-delay = <35>;
-+
-+ partition@0 {
-+ label = "uboot";
-+ reg = <0x0000000 0x00c0000>;
-+ read-only;
-+ };
-+ partition@c0000 {
-+ label = "uboot_env";
-+ reg = <0x00c0000 0x0080000>;
-+ };
-+ partition@140000 {
-+ label = "ubi";
-+ reg = <0x0140000 0x7ec0000>;
-+ };
-+};
-+
-+&pciec {
-+ status = "okay";
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ pinctrl-names = "default";
-+
-+ pmx_buttons: pmx-buttons {
-+ marvell,pins = "mpp24", "mpp25", "mpp26";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_leds: pmx-leds {
-+ marvell,pins = "mpp13", "mpp15", "mpp16", "mpp22", "mpp23",
-+ "mpp28", "mpp29";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_power: pmx-power {
-+ marvell,pins = "mpp21", "mpp33";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_pwr_off: pmx-pwr-off {
-+ marvell,pins = "mpp27";
-+ marvell,function = "gpio";
-+ };
-+};
-+
-+&rtc {
-+ status = "disabled";
-+};
-+
-+&sata {
-+ status = "okay";
-+ nr-ports = <1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ hdd_temp: sata-port@0 {
-+ reg = <0>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
diff --git a/target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch b/target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch
deleted file mode 100644
index cde281526b..0000000000
--- a/target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From 5668d088ee4ea05db9daaae0645d1d1f579b20f9 Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Mon, 3 Oct 2022 09:34:43 +0200
-Subject: ARM: dts: kirkwood: Add Endian 4i Edge 200 board
-
-Add Endian 4i Edge 200 is 5-port firewall.
-It have also clone: Endian UTM Mini (The same hardware, with added WLAN
-card).
-
-Hardware:
- - SoC: Marvell 88F6281-A1 ARMv5TE Processor 1.2GHz
- - Ram: 512MB (4x Nanya NT5TU128M8GE-AC)
- - NAND Flash: 512MB (Micron 29F4G08AAC)
- - Lan 1-4: 4x GBE (Marvell 88E6171R-TFJ2)
- - Lan 5: 1x GBE (Marvell 88E1116R-NNC1)
- - Storage: MicroSD Slot
- - MCPIE: MiniPCIe Slot present [fitted with SparkLan WPEA-110N/E
- (Atheros AR9280 chipset) in Endian UTM Mini WLAN only]
- - USB: 1x USB 2.0 port
- - Console: RJ-45 port
- - LEDs: 3x GPIO controlled
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/kirkwood-4i-edge-200.dts | 205 +++++++++++++++++++++++++++++
- 2 files changed, 206 insertions(+)
- create mode 100644 arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -300,6 +300,7 @@ dtb-$(CONFIG_ARCH_KEYSTONE) += \
- keystone-k2g-evm.dtb \
- keystone-k2g-ice.dtb
- dtb-$(CONFIG_MACH_KIRKWOOD) += \
-+ kirkwood-4i-edge-200.dtb \
- kirkwood-b3.dtb \
- kirkwood-blackarmor-nas220.dtb \
- kirkwood-c200-v1.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-@@ -0,0 +1,205 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * Endian 4i Edge 200 Board Description
-+ * Note: Endian UTM Mini is hardware clone of Endian Edge 200
-+ * Copyright 2021-2022 Pawel Dembicki <paweldembicki@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "kirkwood.dtsi"
-+#include "kirkwood-6281.dtsi"
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ model = "Endian 4i Edge 200";
-+ compatible = "endian,4i-edge-200", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-+
-+ memory {
-+ device_type = "memory";
-+ reg = <0x00000000 0x20000000>;
-+ };
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200n8";
-+ stdout-path = &uart0;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+ pinctrl-0 = <&pmx_led>;
-+ pinctrl-names = "default";
-+
-+ led-1 {
-+ function = LED_FUNCTION_SD;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "mmc0";
-+ };
-+
-+ led-2 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-3 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&eth0 {
-+ status = "okay";
-+};
-+
-+&eth0port {
-+ speed = <1000>;
-+ duplex = <1>;
-+};
-+
-+&eth1 {
-+ status = "okay";
-+};
-+
-+&eth1port {
-+ phy-handle = <&ethphyb>;
-+};
-+
-+&mdio {
-+ status = "okay";
-+
-+ ethphyb: ethernet-phy@b {
-+ reg = <0x0b>;
-+
-+ marvell,reg-init =
-+ /* link-activity, bi-color mode 4 */
-+ <3 0x10 0xfff0 0xf>; /* Reg 3,16 <- 0xzzzf */
-+ };
-+
-+ switch0: switch@11 {
-+ compatible = "marvell,mv88e6085";
-+ reg = <0x11>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "port1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "port2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "port3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "port4";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ phy-mode = "rgmii-id";
-+ ethernet = <&eth0port>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+&nand {
-+ status = "okay";
-+ pinctrl-0 = <&pmx_nand>;
-+ pinctrl-names = "default";
-+
-+ partition@0 {
-+ label = "u-boot";
-+ reg = <0x00000000 0x000a0000>;
-+ read-only;
-+ };
-+
-+ partition@a0000 {
-+ label = "u-boot-env";
-+ reg = <0x000a0000 0x00060000>;
-+ read-only;
-+ };
-+
-+ partition@100000 {
-+ label = "kernel";
-+ reg = <0x00100000 0x00400000>;
-+ };
-+
-+ partition@500000 {
-+ label = "ubi";
-+ reg = <0x00500000 0x1fb00000>;
-+ };
-+};
-+
-+&pciec {
-+ status = "okay";
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ pinctrl-0 = <&pmx_sysrst>;
-+ pinctrl-names = "default";
-+
-+ pmx_sysrst: pmx-sysrst {
-+ marvell,pins = "mpp6";
-+ marvell,function = "sysrst";
-+ };
-+
-+ pmx_sdio_cd: pmx-sdio-cd {
-+ marvell,pins = "mpp28";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_led: pmx-led {
-+ marvell,pins = "mpp34", "mpp35", "mpp49";
-+ marvell,function = "gpio";
-+ };
-+};
-+
-+&rtc {
-+ status = "okay";
-+};
-+
-+&sata_phy0 {
-+ status = "disabled";
-+};
-+
-+&sata_phy1 {
-+ status = "disabled";
-+};
-+
-+&sdio {
-+ pinctrl-0 = <&pmx_sdio_cd>;
-+ pinctrl-names = "default";
-+ status = "okay";
-+ cd-gpios = <&gpio0 28 9>;
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&usb0 {
-+ status = "okay";
-+};
diff --git a/target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch b/target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch
deleted file mode 100644
index fd7adc3584..0000000000
--- a/target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 8aea8659a5f3ae8dc63c9f632ce1f676a1483556 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Fri, 7 Apr 2023 17:17:20 +0200
-Subject: [PATCH] ARM: dts: kirkwood: Add missing phy-mode and fixed links
-
-The DSA framework has got more picky about always having a phy-mode
-for the CPU port. The Kirkwood Ethernet is an RGMII port. Set the
-switch to impose the RGMII delays.
-
-Additionally, the cpu label has never actually been used in the
-binding, so remove it.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
----
- arch/arm/boot/dts/kirkwood-dir665.dts | 3 ++-
- arch/arm/boot/dts/kirkwood-l-50.dts | 2 +-
- arch/arm/boot/dts/kirkwood-linksys-viper.dts | 3 ++-
- arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 3 ++-
- arch/arm/boot/dts/kirkwood-rd88f6281.dtsi | 2 +-
- 5 files changed, 8 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/kirkwood-dir665.dts
-+++ b/arch/arm/boot/dts/kirkwood-dir665.dts
-@@ -232,7 +232,7 @@
-
- port@6 {
- reg = <6>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
-@@ -251,6 +251,7 @@
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-l-50.dts
-+++ b/arch/arm/boot/dts/kirkwood-l-50.dts
-@@ -254,7 +254,6 @@
-
- port@6 {
- reg = <6>;
-- label = "cpu";
- phy-mode = "rgmii-id";
- ethernet = <&eth1port>;
- fixed-link {
-@@ -330,6 +329,7 @@
- ethernet1-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-+++ b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-@@ -198,7 +198,7 @@
-
- port@5 {
- reg = <5>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
-@@ -221,6 +221,7 @@
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
-+++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
-@@ -149,7 +149,7 @@
-
- port@5 {
- reg = <5>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
-@@ -166,6 +166,7 @@
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
-+++ b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
-@@ -105,7 +105,7 @@
-
- port@5 {
- reg = <5>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/kirkwood/patches-6.1/100-ib62x0.patch b/target/linux/kirkwood/patches-6.1/100-ib62x0.patch
deleted file mode 100644
index 0637c24b63..0000000000
--- a/target/linux/kirkwood/patches-6.1/100-ib62x0.patch
+++ /dev/null
@@ -1,53 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-ib62x0.dts
-+++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
-@@ -6,7 +6,14 @@
-
- / {
- model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)";
-- compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-+ compatible = "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-+
-+ aliases {
-+ led-boot = &led_green_os;
-+ led-failsafe = &led_red_os;
-+ led-running = &led_green_os;
-+ led-upgrade = &led_red_os;
-+ };
-
- memory {
- device_type = "memory";
-@@ -81,12 +88,12 @@
- &pmx_led_usb_transfer>;
- pinctrl-names = "default";
-
-- green-os {
-+ led_green_os: green-os {
- label = "ib62x0:green:os";
- gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- red-os {
-+ led_red_os: red-os {
- label = "ib62x0:red:os";
- gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
- };
-@@ -118,13 +125,13 @@
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x600000>;
-+ label = "second stage u-boot";
-+ reg = <0x100000 0x200000>;
- };
-
-- partition@700000 {
-- label = "root";
-- reg = <0x0700000 0xf900000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0xfe00000>;
- };
-
- };
diff --git a/target/linux/kirkwood/patches-6.1/101-iconnect.patch b/target/linux/kirkwood/patches-6.1/101-iconnect.patch
deleted file mode 100644
index 935e2dfcf5..0000000000
--- a/target/linux/kirkwood/patches-6.1/101-iconnect.patch
+++ /dev/null
@@ -1,80 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-iconnect.dts
-+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
-@@ -8,6 +8,13 @@
- model = "Iomega Iconnect";
- compatible = "iom,iconnect-1.1", "iom,iconnect", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_power_blue;
-+ led-failsafe = &led_power_red;
-+ led-running = &led_power_blue;
-+ led-upgrade = &led_power_red;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -16,8 +23,6 @@
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
-- linux,initrd-start = <0x4500040>;
-- linux,initrd-end = <0x4800000>;
- };
-
- ocp@f1000000 {
-@@ -89,12 +94,12 @@
- gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
-- power-blue {
-+ led_power_blue: power-blue {
- label = "power:blue";
- gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- power-red {
-+ led_power_red: power-red {
- label = "power:red";
- gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
- };
-@@ -146,28 +151,23 @@
- status = "okay";
-
- partition@0 {
-- label = "uboot";
-- reg = <0x0000000 0xc0000>;
-+ label = "u-boot";
-+ reg = <0x0000000 0xe0000>;
- };
-
-- partition@a0000 {
-- label = "env";
-- reg = <0xa0000 0x20000>;
-+ partition@e0000 {
-+ label = "u-boot environment";
-+ reg = <0xe0000 0x100000>;
- };
-
- partition@100000 {
-- label = "zImage";
-- reg = <0x100000 0x300000>;
-- };
--
-- partition@540000 {
-- label = "initrd";
-- reg = <0x540000 0x300000>;
-+ label = "second stage u-boot";
-+ reg = <0x100000 0x200000>;
- };
-
-- partition@980000 {
-- label = "boot";
-- reg = <0x980000 0x1f400000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0x1fe00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/102-dockstar.patch b/target/linux/kirkwood/patches-6.1/102-dockstar.patch
deleted file mode 100644
index 127f84962c..0000000000
--- a/target/linux/kirkwood/patches-6.1/102-dockstar.patch
+++ /dev/null
@@ -1,62 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-dockstar.dts
-+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
-@@ -8,6 +8,13 @@
- model = "Seagate FreeAgent Dockstar";
- compatible = "seagate,dockstar", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
-@@ -42,12 +49,12 @@
- pinctrl-0 = <&pmx_led_green &pmx_led_orange>;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "status:green:health";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "status:orange:fault";
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-@@ -78,18 +85,22 @@
-
- partition@0 {
- label = "u-boot";
-- reg = <0x0000000 0x100000>;
-- read-only;
-+ reg = <0x0000000 0xe0000>;
-+ };
-+
-+ partition@e0000 {
-+ label = "u-boot environment";
-+ reg = <0xe0000 0x100000>;
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-+ label = "second stage u-boot";
-+ reg = <0x100000 0x200000>;
- };
-
-- partition@500000 {
-- label = "data";
-- reg = <0x0500000 0xfb00000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0xfe00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch b/target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch
deleted file mode 100644
index db04c09f76..0000000000
--- a/target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch
+++ /dev/null
@@ -1,71 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
-+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
-@@ -8,6 +8,13 @@
- model = "Iomega StorCenter ix2-200";
- compatible = "iom,ix2-200", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_power;
-+ led-failsafe = &led_health;
-+ led-running = &led_power;
-+ led-upgrade = &led_health;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -127,16 +134,16 @@
- &pmx_led_rebuild &pmx_led_health >;
- pinctrl-names = "default";
-
-- power_led {
-+ led_power: power_led {
- label = "status:white:power_led";
- gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
-- default-state = "keep";
-+ default-state = "on";
- };
- rebuild_led {
- label = "status:white:rebuild_led";
- gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
- };
-- health_led {
-+ led_health: health_led {
- label = "status:red:health_led";
- gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
- };
-@@ -186,19 +193,19 @@
- };
-
- partition@a0000 {
-- label = "env";
-+ label = "u-boot environment";
- reg = <0xa0000 0x20000>;
- read-only;
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x100000 0x300000>;
-+ label = "kernel";
-+ reg = <0x100000 0x400000>;
- };
-
-- partition@400000 {
-- label = "rootfs";
-- reg = <0x400000 0x1C00000>;
-+ partition@500000 {
-+ label = "ubi";
-+ reg = <0x500000 0x1C00000>;
- };
- };
-
-@@ -211,7 +218,7 @@
- };
-
- &eth0 {
-- status = "okay";
-+ status = "disabled";
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
diff --git a/target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch b/target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch
deleted file mode 100644
index b1604ec92c..0000000000
--- a/target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch
+++ /dev/null
@@ -1,59 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-+++ b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-@@ -24,6 +24,10 @@
- };
-
- aliases {
-+ led-boot = &led_white_health;
-+ led-failsafe = &led_white_health;
-+ led-running = &led_white_health;
-+ led-upgrade = &led_white_health;
- serial0 = &uart0;
- };
-
-@@ -56,9 +60,10 @@
- pinctrl-0 = < &pmx_led_white_health &pmx_led_white_pulse >;
- pinctrl-names = "default";
-
-- white-health {
-+ led_white_health: white-health {
- label = "viper:white:health";
- gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
-+ default-state = "on";
- };
-
- white-pulse {
-@@ -114,23 +119,23 @@
- };
-
- partition@200000 {
-- label = "kernel";
-- reg = <0x200000 0x2A0000>;
-+ label = "kernel1";
-+ reg = <0x200000 0x1A00000>;
- };
-
-- partition@4a0000 {
-- label = "rootfs";
-- reg = <0x4A0000 0x1760000>;
-+ partition@600000 {
-+ label = "rootfs1";
-+ reg = <0x600000 0x1600000>;
- };
-
- partition@1c00000 {
-- label = "alt_kernel";
-- reg = <0x1C00000 0x2A0000>;
-+ label = "kernel2";
-+ reg = <0x1C00000 0x1A00000>;
- };
-
-- partition@1ea0000 {
-- label = "alt_rootfs";
-- reg = <0x1EA0000 0x1760000>;
-+ partition@2000000 {
-+ label = "rootfs2";
-+ reg = <0x2000000 0x1600000>;
- };
-
- partition@3600000 {
diff --git a/target/linux/kirkwood/patches-6.1/106-goflexnet.patch b/target/linux/kirkwood/patches-6.1/106-goflexnet.patch
deleted file mode 100644
index 82cf90841e..0000000000
--- a/target/linux/kirkwood/patches-6.1/106-goflexnet.patch
+++ /dev/null
@@ -1,53 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-goflexnet.dts
-+++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
-@@ -8,6 +8,13 @@
- model = "Seagate GoFlex Net";
- compatible = "seagate,goflexnet", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
-@@ -85,12 +92,12 @@
- >;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "status:green:health";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "status:orange:fault";
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-@@ -159,18 +166,8 @@
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-- };
--
-- partition@500000 {
-- label = "pogoplug";
-- reg = <0x0500000 0x2000000>;
-- };
--
-- partition@2500000 {
-- label = "root";
-- reg = <0x02500000 0xd800000>;
-+ label = "ubi";
-+ reg = <0x0100000 0x0ff00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch b/target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch
deleted file mode 100644
index df654033fd..0000000000
--- a/target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch
+++ /dev/null
@@ -1,48 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi
-+++ b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi
-@@ -112,40 +112,16 @@
-
- partition@0 {
- label = "uboot";
-- reg = <0x0000000 0x0100000>;
-+ reg = <0x0000000 0x00c0000>;
- read-only;
- };
- partition@100000 {
- label = "uboot_env";
-- reg = <0x0100000 0x0080000>;
-+ reg = <0x00c0000 0x0080000>;
- };
-- partition@180000 {
-- label = "key_store";
-- reg = <0x0180000 0x0080000>;
-- };
-- partition@200000 {
-- label = "info";
-- reg = <0x0200000 0x0080000>;
-- };
-- partition@280000 {
-- label = "etc";
-- reg = <0x0280000 0x0a00000>;
-- };
-- partition@c80000 {
-- label = "kernel_1";
-- reg = <0x0c80000 0x0a00000>;
-- };
-- partition@1680000 {
-- label = "rootfs1";
-- reg = <0x1680000 0x2fc0000>;
-- };
-- partition@4640000 {
-- label = "kernel_2";
-- reg = <0x4640000 0x0a00000>;
-- };
-- partition@5040000 {
-- label = "rootfs2";
-- reg = <0x5040000 0x2fc0000>;
-+ partition@140000 {
-+ label = "ubi";
-+ reg = <0x0140000 0x7ec0000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/107-03-nsa325.patch b/target/linux/kirkwood/patches-6.1/107-03-nsa325.patch
deleted file mode 100644
index 374c0895a9..0000000000
--- a/target/linux/kirkwood/patches-6.1/107-03-nsa325.patch
+++ /dev/null
@@ -1,54 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-nsa325.dts
-+++ b/arch/arm/boot/dts/kirkwood-nsa325.dts
-@@ -15,6 +15,13 @@
- model = "ZyXEL NSA325";
- compatible = "zyxel,nsa325", "marvell,kirkwood-88f6282", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_green_sys;
-+ led-failsafe = &led_orange_sys;
-+ led-running = &led_green_sys;
-+ led-upgrade = &led_orange_sys;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x20000000>;
-@@ -162,17 +169,19 @@
- &pmx_led_hdd1_green &pmx_led_hdd1_red>;
- pinctrl-names = "default";
-
-- green-sys {
-+ led_green_sys: green-sys {
- label = "nsa325:green:sys";
- gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
-+ default-state = "on";
- };
-- orange-sys {
-+ led_orange_sys: orange-sys {
- label = "nsa325:orange:sys";
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
- };
- green-hdd1 {
- label = "nsa325:green:hdd1";
- gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "ata1";
- };
- red-hdd1 {
- label = "nsa325:red:hdd1";
-@@ -181,6 +190,7 @@
- green-hdd2 {
- label = "nsa325:green:hdd2";
- gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "ata2";
- };
- red-hdd2 {
- label = "nsa325:red:hdd2";
-@@ -189,6 +199,7 @@
- green-usb {
- label = "nsa325:green:usb";
- gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "usb-host";
- };
- green-copy {
- label = "nsa325:green:copy";
diff --git a/target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch b/target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch
deleted file mode 100644
index 4273eb9af1..0000000000
--- a/target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch
+++ /dev/null
@@ -1,87 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
-+++ b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
-@@ -18,12 +18,20 @@
- compatible = "cloudengines,pogoplugv4", "marvell,kirkwood-88f6192",
- "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x08000000>;
- };
-
- chosen {
-+ bootargs = "console=ttyS0,115200";
- stdout-path = "uart0:115200n8";
- };
-
-@@ -37,8 +45,8 @@
- eject {
- debounce-interval = <50>;
- wakeup-source;
-- linux,code = <KEY_EJECTCD>;
-- label = "Eject Button";
-+ linux,code = <KEY_RESTART>;
-+ label = "Reset";
- gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
- };
- };
-@@ -48,12 +56,12 @@
- pinctrl-0 = <&pmx_led_green &pmx_led_red>;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "pogoplugv4:green:health";
- gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "pogoplugv4:red:fault";
- gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
- };
-@@ -137,29 +145,19 @@
- #size-cells = <1>;
-
- partition@0 {
-- label = "u-boot";
-- reg = <0x00000000 0x200000>;
-+ label = "uboot";
-+ reg = <0x00000000 0x1c0000>;
- read-only;
- };
-
-- partition@200000 {
-- label = "uImage";
-- reg = <0x00200000 0x300000>;
-- };
--
-- partition@500000 {
-- label = "uImage2";
-- reg = <0x00500000 0x300000>;
-- };
--
-- partition@800000 {
-- label = "failsafe";
-- reg = <0x00800000 0x800000>;
-+ partition@1c0000 {
-+ label = "uboot_env";
-+ reg = <0x001c0000 0x40000>;
- };
-
-- partition@1000000 {
-- label = "root";
-- reg = <0x01000000 0x7000000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x00200000 0x7e00000>;
- };
- };
- };
diff --git a/target/linux/kirkwood/patches-6.1/110-pogo_e02.patch b/target/linux/kirkwood/patches-6.1/110-pogo_e02.patch
deleted file mode 100644
index fc384d3521..0000000000
--- a/target/linux/kirkwood/patches-6.1/110-pogo_e02.patch
+++ /dev/null
@@ -1,68 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-pogo_e02.dts
-+++ b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
-@@ -20,6 +20,13 @@
- compatible = "cloudengines,pogoe02", "marvell,kirkwood-88f6281",
- "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -33,12 +40,12 @@
- gpio-leds {
- compatible = "gpio-leds";
-
-- health {
-+ led_health: health {
- label = "pogo_e02:green:health";
- gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "pogo_e02:orange:fault";
- gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
- };
-@@ -95,24 +102,24 @@
- status = "okay";
-
- partition@0 {
-- label = "u-boot";
-- reg = <0x0000000 0x100000>;
-+ label = "uboot";
-+ reg = <0x0 0xe0000>;
- read-only;
- };
-
-- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-+ partition@e0000 {
-+ label = "uboot_env";
-+ reg = <0xe0000 0x20000>;
- };
-
-- partition@500000 {
-- label = "pogoplug";
-- reg = <0x0500000 0x2000000>;
-+ partition@100000 {
-+ label = "second_stage_uboot";
-+ reg = <0x100000 0x100000>;
- };
-
-- partition@2500000 {
-- label = "root";
-- reg = <0x02500000 0x5b00000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0x7e00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/111-l-50.patch b/target/linux/kirkwood/patches-6.1/111-l-50.patch
deleted file mode 100644
index bc933cb610..0000000000
--- a/target/linux/kirkwood/patches-6.1/111-l-50.patch
+++ /dev/null
@@ -1,47 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-l-50.dts
-+++ b/arch/arm/boot/dts/kirkwood-l-50.dts
-@@ -18,6 +18,13 @@
- reg = <0x00000000 0x20000000>;
- };
-
-+ aliases {
-+ led-boot = &led_status_green;
-+ led-failsafe = &led_status_red;
-+ led-running = &led_status_green;
-+ led-upgrade = &led_status_red;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8";
- stdout-path = &uart0;
-@@ -95,12 +102,12 @@
- leds {
- compatible = "gpio-leds";
-
-- status_green {
-+ led_status_green: status_green {
- label = "l-50:green:status";
- gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
- };
-
-- status_red {
-+ led_status_red: status_red {
- label = "l-50:red:status";
- gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
- };
-@@ -349,13 +356,8 @@
- };
-
- partition@100000 {
-- label = "kernel-1";
-- reg = <0x00100000 0x00800000>;
-- };
--
-- partition@900000 {
-- label = "rootfs-1";
-- reg = <0x00900000 0x07100000>;
-+ label = "ubi";
-+ reg = <0x00100000 0x07900000>;
- };
-
- partition@7a00000 {
diff --git a/target/linux/kirkwood/patches-6.1/112-sheevaplug.patch b/target/linux/kirkwood/patches-6.1/112-sheevaplug.patch
deleted file mode 100644
index d1ff9884a0..0000000000
--- a/target/linux/kirkwood/patches-6.1/112-sheevaplug.patch
+++ /dev/null
@@ -1,47 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
-+++ b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
-@@ -78,13 +78,8 @@
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-- };
--
-- partition@500000 {
-- label = "root";
-- reg = <0x0500000 0x1fb00000>;
-+ label = "ubi";
-+ reg = <0x0100000 0x1ff00000>;
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-sheevaplug.dts
-+++ b/arch/arm/boot/dts/kirkwood-sheevaplug.dts
-@@ -13,6 +13,13 @@
- model = "Globalscale Technologies SheevaPlug";
- compatible = "globalscale,sheevaplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_health;
-+ led-running = &led_health;
-+ led-upgrade = &led_health;
-+ };
-+
- ocp@f1000000 {
- mvsdio@90000 {
- pinctrl-0 = <&pmx_sdio>;
-@@ -28,10 +35,10 @@
- pinctrl-0 = <&pmx_led_blue &pmx_led_red>;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "sheevaplug:blue:health";
- gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-
- misc {
diff --git a/target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch b/target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch
deleted file mode 100644
index c6452c55a3..0000000000
--- a/target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch
+++ /dev/null
@@ -1,76 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
-+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
-@@ -19,6 +19,13 @@
- reg = <0x00000000 0x10000000>;
- };
-
-+ aliases {
-+ led-boot = &led_power;
-+ led-failsafe = &led_power;
-+ led-running = &led_power;
-+ led-upgrade = &led_power;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
-@@ -115,7 +122,7 @@
- &pmx_led_blue_backup >;
- pinctrl-names = "default";
-
-- power_led {
-+ led_power: power_led {
- label = "status:blue:power_led";
- gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
- default-state = "keep";
-@@ -129,11 +136,13 @@
- disk1_led {
- label = "status:blue:disk1_led";
- gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata1";
- };
-
- disk2_led {
- label = "status:blue:disk2_led";
- gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata2";
- };
-
- backup_led {
-@@ -150,7 +159,13 @@
-
- power-button {
- label = "Power Button";
-- linux,code = <KEY_POWER>;
-+ /* Power button and INT pin from PHY are both connected
-+ * to this GPIO. Every network restart causes PHY restart
-+ * and button is pressed. It's difficult to use it as
-+ * KEY_POWER without changes in kernel (or netifd) so
-+ * the button is configured as regular one.
-+ */
-+ linux,code = <BTN_1>;
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-
-@@ -208,18 +223,13 @@
- };
-
- partition@200000 {
-- label = "uImage";
-+ label = "kernel";
- reg = <0x0200000 0x600000>;
- };
-
- partition@800000 {
-- label = "minirootfs";
-- reg = <0x0800000 0x1000000>;
-- };
--
-- partition@1800000 {
-- label = "jffs2";
-- reg = <0x1800000 0x6800000>;
-+ label = "ubi";
-+ reg = <0x0800000 0x7800000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch b/target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch
deleted file mode 100644
index eb62e1a5ed..0000000000
--- a/target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch
+++ /dev/null
@@ -1,58 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-c200-v1.dts
-+++ b/arch/arm/boot/dts/kirkwood-c200-v1.dts
-@@ -14,6 +14,14 @@
- model = "Ctera C200 V1";
- compatible = "ctera,c200-v1", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+
-+ aliases {
-+ led-boot = &led_status_green;
-+ led-failsafe = &led_status_red;
-+ led-running = &led_status_green;
-+ led-upgrade = &led_status_red;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &uart0;
-@@ -78,6 +86,7 @@
- function-enumerator = <1>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata1";
- };
-
- led-2 {
-@@ -85,6 +94,7 @@
- function-enumerator = <2>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata2";
- };
-
- led-3 {
-@@ -94,13 +104,13 @@
- gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
- };
-
-- led-4 {
-+ led_status_red: led-4 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
- };
-
-- led-5 {
-+ led_status_green: led-5 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
-@@ -240,7 +250,7 @@
- };
-
- partition@7a00000 {
-- label = "rootfs";
-+ label = "ubi";
- reg = <0x7a00000 0x8600000>;
- };
- };
diff --git a/target/linux/kirkwood/patches-6.1/115-nsa310s.patch b/target/linux/kirkwood/patches-6.1/115-nsa310s.patch
deleted file mode 100644
index 4c6e08f49c..0000000000
--- a/target/linux/kirkwood/patches-6.1/115-nsa310s.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-nsa310s.dts
-+++ b/arch/arm/boot/dts/kirkwood-nsa310s.dts
-@@ -16,6 +16,13 @@
- model = "ZyXEL NSA310S";
- compatible = "zyxel,nsa310s", "marvell,kirkwood-88f6702", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_green_sys;
-+ led-failsafe = &led_red_sys;
-+ led-running = &led_green_sys;
-+ led-upgrade = &led_red_sys;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -96,14 +103,16 @@
- gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
- };
-
-- led-6 {
-+ led_green_sys: led-6 {
-+ label = "nsa310s:green:sys";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- led-7 {
-+ led_red_sys: led-7 {
-+ label = "nsa310s:red:sys";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch b/target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch
deleted file mode 100644
index ffc46c29dc..0000000000
--- a/target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-+++ b/arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-@@ -20,6 +20,13 @@
- reg = <0x00000000 0x20000000>;
- };
-
-+ aliases {
-+ led-boot = &led_status_green;
-+ led-failsafe = &led_status_orange;
-+ led-running = &led_status_green;
-+ led-upgrade = &led_status_orange;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8";
- stdout-path = &uart0;
-@@ -37,13 +44,15 @@
- linux,default-trigger = "mmc0";
- };
-
-- led-2 {
-+ led_status_orange: led-2 {
-+ label = "orange:status";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
- };
-
-- led-3 {
-+ led_status_green: led-3 {
-+ label = "green:status";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/kirkwood/patches-6.1/117-netgear_stora.patch b/target/linux/kirkwood/patches-6.1/117-netgear_stora.patch
deleted file mode 100644
index c7518933b2..0000000000
--- a/target/linux/kirkwood/patches-6.1/117-netgear_stora.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -375,6 +375,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
- kirkwood-rs411.dtb \
- kirkwood-sheevaplug.dtb \
- kirkwood-sheevaplug-esata.dtb \
-+ kirkwood-stora.dtb \
- kirkwood-t5325.dtb \
- kirkwood-topkick.dtb \
- kirkwood-ts219-6281.dtb \
diff --git a/target/linux/kirkwood/patches-6.1/118-dns-320l.patch b/target/linux/kirkwood/patches-6.1/118-dns-320l.patch
deleted file mode 100644
index d6c84e2c59..0000000000
--- a/target/linux/kirkwood/patches-6.1/118-dns-320l.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -310,6 +310,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
- kirkwood-db-88f6282.dtb \
- kirkwood-dir665.dtb \
- kirkwood-dns320.dtb \
-+ kirkwood-dns320l.dtb \
- kirkwood-dns325.dtb \
- kirkwood-dockstar.dtb \
- kirkwood-dreamplug.dtb \
---- a/arch/arm/boot/dts/kirkwood-dns320l.dts
-+++ b/arch/arm/boot/dts/kirkwood-dns320l.dts
-@@ -32,6 +32,13 @@
- reg = <0x00000000 0x10000000>;
- };
-
-+ aliases {
-+ led-boot = &led_orange_usb;
-+ led-failsafe = &led_orange_usb;
-+ led-running = &led_orange_usb;
-+ led-upgrade = &led_orange_usb;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
-@@ -68,7 +75,7 @@
- linux,default-trigger = "usbport";
- };
-
-- orange-usb {
-+ led_orange_usb: orange-usb {
- label = "dns320l:usb:orange";
- gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch b/target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch
deleted file mode 100644
index 3db362de9f..0000000000
--- a/target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/arm/mach-mvebu/Kconfig
-+++ b/arch/arm/mach-mvebu/Kconfig
-@@ -115,6 +115,7 @@ config MACH_DOVE
- config MACH_KIRKWOOD
- bool "Marvell Kirkwood boards"
- depends on ARCH_MULTI_V5
-+ select ARCH_WANT_LIBATA_LEDS
- select CPU_FEROCEON
- select GPIOLIB
- select KIRKWOOD_CLK
diff --git a/target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch b/target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch
deleted file mode 100644
index 5029b1791c..0000000000
--- a/target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-The WRT1900AC among other Linksys routers uses a dual-firmware layout.
-Dynamically rename the active partition to "ubi".
-
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
---- a/drivers/mtd/parsers/ofpart_core.c
-+++ b/drivers/mtd/parsers/ofpart_core.c
-@@ -38,6 +38,8 @@ static bool node_has_compatible(struct d
- return of_get_property(pp, "compatible", NULL);
- }
-
-+static int mangled_rootblock;
-+
- static int parse_fixed_partitions(struct mtd_info *master,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -47,6 +49,7 @@ static int parse_fixed_partitions(struct
- struct mtd_partition *parts;
- struct device_node *mtd_node;
- struct device_node *ofpart_node;
-+ const char *owrtpart = "ubi";
- const char *partname;
- struct device_node *pp;
- int nr_parts, i, ret = 0;
-@@ -152,9 +155,15 @@ static int parse_fixed_partitions(struct
- parts[i].size = of_read_number(reg + a_cells, s_cells);
- parts[i].of_node = pp;
-
-- partname = of_get_property(pp, "label", &len);
-- if (!partname)
-- partname = of_get_property(pp, "name", &len);
-+ if (mangled_rootblock && (i == mangled_rootblock)) {
-+ partname = owrtpart;
-+ } else {
-+ partname = of_get_property(pp, "label", &len);
-+
-+ if (!partname)
-+ partname = of_get_property(pp, "name", &len);
-+ }
-+
- parts[i].name = partname;
-
- if (of_get_property(pp, "read-only", &len))
-@@ -271,6 +280,18 @@ static int __init ofpart_parser_init(voi
- return 0;
- }
-
-+static int __init active_root(char *str)
-+{
-+ get_option(&str, &mangled_rootblock);
-+
-+ if (!mangled_rootblock)
-+ return 1;
-+
-+ return 1;
-+}
-+
-+__setup("mangled_rootblock=", active_root);
-+
- static void __exit ofpart_parser_exit(void)
- {
- deregister_mtd_parser(&ofpart_parser);
diff --git a/target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch b/target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch
deleted file mode 100644
index e04a28206a..0000000000
--- a/target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch
+++ /dev/null
@@ -1,99 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
-+++ b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
-@@ -17,6 +17,13 @@
- compatible = "seagate,blackarmor-nas220","marvell,kirkwood-88f6192",
- "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_status_amber;
-+ led-failsafe = &led_status_amber;
-+ led-running = &led_status_blue;
-+ led-upgrade = &led_status_amber;
-+ };
-+
- memory { /* 128 MB */
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
-@@ -36,14 +43,14 @@
- compatible = "gpio-keys";
-
- reset {
-- label = "Reset";
-- linux,code = <KEY_POWER>;
-+ label = "Reset Button";
-+ linux,code = <KEY_RESTART>;
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
- };
-
-- button {
-- label = "Power";
-- linux,code = <KEY_SLEEP>;
-+ power {
-+ label = "Power Button";
-+ linux,code = <KEY_POWER>;
- gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
- };
- };
-@@ -51,11 +58,27 @@
- gpio-leds {
- compatible = "gpio-leds";
-
-- blue-power {
-+ led_power_blue: power_blue {
- label = "nas220:blue:power";
- gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-+
-+ disk_blue {
-+ label = "nas220:blue:disk";
-+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "disk-activity";
-+ };
-+
-+ led_status_blue: status_blue {
-+ label = "nas220:blue:status";
-+ gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led_status_amber: status_amber {
-+ label = "nas220:amber:status";
-+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
-+ };
- };
-
- regulators {
-@@ -153,6 +176,33 @@
-
- &nand {
- status = "okay";
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+
-+ partition@0 {
-+ label = "uboot";
-+ reg = <0x0 0xa0000>;
-+ read-only;
-+ };
-+
-+ partition@a0000 {
-+ label = "uboot-env";
-+ reg = <0xa0000 0x10000>;
-+ read-only;
-+ };
-+
-+ partition@b0000 {
-+ label = "reserved";
-+ reg = <0xb0000 0x10000>;
-+ read-only;
-+ };
-+
-+ partition@c0000 {
-+ label = "ubi";
-+ reg = <0xc0000 0x1e80000>;
-+ };
-+ };
- };
-
- &mdio {
diff --git a/target/linux/lantiq/Makefile b/target/linux/lantiq/Makefile
index 3474ebe462..69fa8276e7 100644
--- a/target/linux/lantiq/Makefile
+++ b/target/linux/lantiq/Makefile
@@ -9,8 +9,7 @@ BOARDNAME:=Lantiq
FEATURES:=squashfs
SUBTARGETS:=xrx200 xway xway_legacy falcon ase
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Lantiq SoC
diff --git a/target/linux/lantiq/ase/config-5.15 b/target/linux/lantiq/ase/config-5.15
deleted file mode 100644
index c4d8e575eb..0000000000
--- a/target/linux/lantiq/ase/config-5.15
+++ /dev/null
@@ -1,24 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_CPU_MIPS32_R1=y
-# CONFIG_CPU_MIPS32_R2 is not set
-CONFIG_CPU_MIPSR1=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_FIRMWARE_MEMMAP=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_HW_RANDOM=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_NLS=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SOC_AMAZON_SE=y
-# CONFIG_SOC_XWAY is not set
-CONFIG_SWCONFIG=y
-CONFIG_TARGET_ISA_REV=1
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/lantiq/ase/config-6.1 b/target/linux/lantiq/ase/config-6.1
deleted file mode 100644
index c4d8e575eb..0000000000
--- a/target/linux/lantiq/ase/config-6.1
+++ /dev/null
@@ -1,24 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_CPU_MIPS32_R1=y
-# CONFIG_CPU_MIPS32_R2 is not set
-CONFIG_CPU_MIPSR1=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_FIRMWARE_MEMMAP=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_HW_RANDOM=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_NLS=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SOC_AMAZON_SE=y
-# CONFIG_SOC_XWAY is not set
-CONFIG_SWCONFIG=y
-CONFIG_TARGET_ISA_REV=1
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/lantiq/config-5.15 b/target/linux/lantiq/config-5.15
deleted file mode 100644
index 39862948e2..0000000000
--- a/target/linux/lantiq/config-5.15
+++ /dev/null
@@ -1,172 +0,0 @@
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MITIGATIONS=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DTC=y
-# CONFIG_DT_EASY50712 is not set
-CONFIG_EARLY_PRINTK=y
-CONFIG_FIXED_PHY=y
-CONFIG_FUNCTION_ALIGNMENT=0
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_MM_LANTIQ=y
-CONFIG_GPIO_STP_XWAY=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LANTIQ=y
-CONFIG_LANTIQ_DT_NONE=y
-# CONFIG_LANTIQ_ETOP is not set
-CONFIG_LANTIQ_WDT=y
-# CONFIG_LANTIQ_XRX200 is not set
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-CONFIG_MIPS_EBPF_JIT=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_LANTIQ=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
-CONFIG_MTD_SPLIT_EVA_FW=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHY_LANTIQ_RCU_USB2=y
-# CONFIG_PHY_LANTIQ_VRX200_PCIE is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_LANTIQ=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_XWAY=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_LANTIQ=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_LANTIQ=y
-CONFIG_SERIAL_LANTIQ_CONSOLE=y
-# CONFIG_SOC_AMAZON_SE is not set
-# CONFIG_SOC_FALCON is not set
-CONFIG_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
-CONFIG_SPI=y
-CONFIG_SPI_LANTIQ_SSC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_SYS_SUPPORTS_VPE_LOADER=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
diff --git a/target/linux/lantiq/config-6.1 b/target/linux/lantiq/config-6.1
deleted file mode 100644
index e037a63068..0000000000
--- a/target/linux/lantiq/config-6.1
+++ /dev/null
@@ -1,182 +0,0 @@
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DTC=y
-# CONFIG_DT_EASY50712 is not set
-CONFIG_EARLY_PRINTK=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_FIXED_PHY=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_MM_LANTIQ=y
-CONFIG_GPIO_STP_XWAY=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LANTIQ=y
-CONFIG_LANTIQ_DT_NONE=y
-# CONFIG_LANTIQ_ETOP is not set
-CONFIG_LANTIQ_WDT=y
-# CONFIG_LANTIQ_XRX200 is not set
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_LANTIQ=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
-CONFIG_MTD_SPLIT_EVA_FW=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHY_LANTIQ_RCU_USB2=y
-# CONFIG_PHY_LANTIQ_VRX200_PCIE is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_LANTIQ=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_XWAY=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_LANTIQ=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_LANTIQ=y
-CONFIG_SERIAL_LANTIQ_CONSOLE=y
-# CONFIG_SOC_AMAZON_SE is not set
-# CONFIG_SOC_FALCON is not set
-CONFIG_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
-CONFIG_SPI=y
-CONFIG_SPI_LANTIQ_SSC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_SYS_SUPPORTS_VPE_LOADER=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
diff --git a/target/linux/lantiq/falcon/config-5.15 b/target/linux/lantiq/falcon/config-5.15
deleted file mode 100644
index d5c5c61505..0000000000
--- a/target/linux/lantiq/falcon/config-5.15
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPLIT_FIRMWARE_NAME="linux"
-CONFIG_PINCTRL_FALCON=y
-CONFIG_SOC_FALCON=y
-# CONFIG_SOC_XWAY is not set
-CONFIG_SPI_FALCON=y
diff --git a/target/linux/lantiq/falcon/config-6.1 b/target/linux/lantiq/falcon/config-6.1
deleted file mode 100644
index d5c5c61505..0000000000
--- a/target/linux/lantiq/falcon/config-6.1
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPLIT_FIRMWARE_NAME="linux"
-CONFIG_PINCTRL_FALCON=y
-CONFIG_SOC_FALCON=y
-# CONFIG_SOC_XWAY is not set
-CONFIG_SPI_FALCON=y
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts
index 760bced2d2..cf850ad5d9 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts
@@ -5,7 +5,7 @@
/ {
compatible = "zyxel,p-2601hn", "lantiq,xway", "lantiq,ar9";
- model = "ZyXEL P-2601HN-Fx";
+ model = "Zyxel P-2601HN-Fx";
chosen {
bootargs = "console=ttyLTQ0,115200";
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts
index 890eac972d..5315f3723e 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts
@@ -135,6 +135,10 @@
macaddr_boardconfig_16: macaddr@16 {
reg = <0x16 0x6>;
};
+
+ eeprom_boardconfig_410: eeprom@410 {
+ reg = <0x410 0x200>;
+ };
};
};
};
@@ -152,7 +156,8 @@
wifi@0,0 {
compatible = "pci0,0";
reg = <0x7000 0 0 0 0>;
- ralink,mtd-eeprom = <&boardconfig 0x410>;
+ nvmem-cells = <&eeprom_boardconfig_410>;
+ nvmem-cell-names = "eeprom";
};
};
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi
index daf115088b..5ef6a4cc9e 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi
@@ -169,6 +169,9 @@
label = "wan";
phy-mode = "mii";
phy-handle = <&phy1>;
+
+ nvmem-cells = <&macaddr_boardconfig_16 2>;
+ nvmem-cell-names = "mac-address";
};
port@2 {
reg = <2>;
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts
index 4a7f63b177..247b811b4f 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts
@@ -2,7 +2,7 @@
/ {
compatible = "zyxel,p-2812hnu-f1", "zyxel,p-2812hnu", "lantiq,xway", "lantiq,vr9";
- model = "ZyXEL P-2812HNU-F1";
+ model = "Zyxel P-2812HNU-F1";
leds {
usb1 {
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts
index 376cdaeb61..a7fd3d3ec8 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts
@@ -2,7 +2,7 @@
/ {
compatible = "zyxel,p-2812hnu-f3", "zyxel,p-2812hnu", "lantiq,xway", "lantiq,vr9";
- model = "ZyXEL P-2812HNU-F3";
+ model = "Zyxel P-2812HNU-F3";
};
&pci0 {
diff --git a/target/linux/lantiq/image/ar9.mk b/target/linux/lantiq/image/ar9.mk
index 3a301f3655..f4a15cfb3e 100644
--- a/target/linux/lantiq/image/ar9.mk
+++ b/target/linux/lantiq/image/ar9.mk
@@ -159,7 +159,7 @@ endef
TARGET_DEVICES += zte_h201l
define Device/zyxel_p-2601hn
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := P-2601HN
DEVICE_VARIANT := F1/F3
IMAGE_SIZE := 15616k
diff --git a/target/linux/lantiq/image/vr9.mk b/target/linux/lantiq/image/vr9.mk
index dc307e1ee4..d4bded9cae 100644
--- a/target/linux/lantiq/image/vr9.mk
+++ b/target/linux/lantiq/image/vr9.mk
@@ -370,7 +370,7 @@ TARGET_DEVICES += netgear_dm200
define Device/zyxel_p-2812hnu-f1
$(Device/dsa-migration)
$(Device/NAND)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := P-2812HNU
DEVICE_VARIANT := F1
BOARD_NAME := P2812HNUF1
@@ -384,7 +384,7 @@ TARGET_DEVICES += zyxel_p-2812hnu-f1
define Device/zyxel_p-2812hnu-f3
$(Device/dsa-migration)
$(Device/NAND)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := P-2812HNU
DEVICE_VARIANT := F3
BOARD_NAME := P2812HNUF3
diff --git a/target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch
deleted file mode 100644
index 6454240014..0000000000
--- a/target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch
+++ /dev/null
@@ -1,5550 +0,0 @@
-From 6f933347d0b4ed02d9534f5fa07f7b99f13eeaa1 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:12:28 +0200
-Subject: [PATCH 01/36] MIPS: lantiq: add pcie driver
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/lantiq/Kconfig | 10 +
- arch/mips/lantiq/xway/sysctrl.c | 2 +
- arch/mips/pci/Makefile | 2 +
- arch/mips/pci/fixup-lantiq-pcie.c | 82 +++
- arch/mips/pci/fixup-lantiq.c | 5 +-
- arch/mips/pci/ifxmips_pci_common.h | 57 ++
- arch/mips/pci/ifxmips_pcie.c | 1099 ++++++++++++++++++++++++++++++
- arch/mips/pci/ifxmips_pcie.h | 135 ++++
- arch/mips/pci/ifxmips_pcie_ar10.h | 290 ++++++++
- arch/mips/pci/ifxmips_pcie_msi.c | 392 +++++++++++
- arch/mips/pci/ifxmips_pcie_phy.c | 478 +++++++++++++
- arch/mips/pci/ifxmips_pcie_pm.c | 176 +++++
- arch/mips/pci/ifxmips_pcie_pm.h | 36 +
- arch/mips/pci/ifxmips_pcie_reg.h | 1001 +++++++++++++++++++++++++++
- arch/mips/pci/ifxmips_pcie_vr9.h | 271 ++++++++
- arch/mips/pci/pci.c | 25 +
- arch/mips/pci/pcie-lantiq.h | 1305 ++++++++++++++++++++++++++++++++++++
- drivers/pci/pcie/aer/Kconfig | 2 +-
- include/linux/pci.h | 2 +
- include/linux/pci_ids.h | 6 +
- 20 files changed, 5374 insertions(+), 2 deletions(-)
- create mode 100644 arch/mips/pci/fixup-lantiq-pcie.c
- create mode 100644 arch/mips/pci/ifxmips_pci_common.h
- create mode 100644 arch/mips/pci/ifxmips_pcie.c
- create mode 100644 arch/mips/pci/ifxmips_pcie.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_ar10.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_msi.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_phy.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_pm.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_pm.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_reg.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_vr9.h
- create mode 100644 arch/mips/pci/pcie-lantiq.h
-
---- a/arch/mips/lantiq/Kconfig
-+++ b/arch/mips/lantiq/Kconfig
-@@ -20,6 +20,7 @@ config SOC_XWAY
- bool "XWAY"
- select SOC_TYPE_XWAY
- select HAVE_PCI
-+ select ARCH_SUPPORTS_MSI
- select MFD_SYSCON
- select MFD_CORE
-
-@@ -52,4 +53,13 @@ config PCI_LANTIQ
- bool "PCI Support"
- depends on SOC_XWAY && PCI
-
-+config PCIE_LANTIQ
-+ bool "PCIE Support"
-+ depends on SOC_XWAY && PCI
-+
-+config PCIE_LANTIQ_MSI
-+ bool
-+ depends on PCIE_LANTIQ && PCI_MSI
-+ default y
-+
- endif
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -43,6 +43,8 @@ obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o
- obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
- obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
- obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
-+obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
-+obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
- obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
- obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
- obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
---- /dev/null
-+++ b/arch/mips/pci/fixup-lantiq-pcie.c
-@@ -0,0 +1,74 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_fixup_pcie.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_fixup_pcie.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe Fixup functions source file
-+*/
-+#include <linux/pci.h>
-+#include <linux/pci_regs.h>
-+#include <linux/pci_ids.h>
-+
-+#include <lantiq_soc.h>
-+
-+#include "pcie-lantiq.h"
-+
-+static void
-+ifx_pcie_fixup_resource(struct pci_dev *dev)
-+{
-+ u32 reg;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
-+
-+ printk("%s: fixup host controller %s (%04x:%04x)\n",
-+ __func__, pci_name(dev), dev->vendor, dev->device);
-+
-+ /* Setup COMMAND register */
-+ reg = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER /* |
-+ PCI_COMMAND_INTX_DISABLE */| PCI_COMMAND_SERR;
-+ pci_write_config_word(dev, PCI_COMMAND, reg);
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
-+}
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE, ifx_pcie_fixup_resource);
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_VENDOR_ID_LANTIQ, ifx_pcie_fixup_resource);
-+
-+static void
-+ifx_pcie_rc_class_early_fixup(struct pci_dev *dev)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
-+
-+ if (dev->devfn == PCI_DEVFN(0, 0) &&
-+ (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
-+
-+ dev->class = (PCI_CLASS_BRIDGE_PCI << 8) | (dev->class & 0xff);
-+
-+ printk(KERN_INFO "%s: fixed pcie host bridge to pci-pci bridge\n", __func__);
-+ }
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
-+ mdelay(10);
-+}
-+
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE,
-+ ifx_pcie_rc_class_early_fixup);
-+
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_DEVICE_ID_LANTIQ_PCIE,
-+ ifx_pcie_rc_class_early_fixup);
---- a/arch/mips/pci/fixup-lantiq.c
-+++ b/arch/mips/pci/fixup-lantiq.c
-@@ -6,12 +6,19 @@
-
- #include <linux/of_irq.h>
- #include <linux/of_pci.h>
-+#include <linux/pci.h>
-+#include "ifxmips_pci_common.h"
-
- int (*ltq_pci_plat_arch_init)(struct pci_dev *dev) = NULL;
- int (*ltq_pci_plat_dev_init)(struct pci_dev *dev) = NULL;
-
- int pcibios_plat_dev_init(struct pci_dev *dev)
- {
-+#ifdef CONFIG_PCIE_LANTIQ
-+ if (pci_find_capability(dev, PCI_CAP_ID_EXP))
-+ ifx_pcie_bios_plat_dev_init(dev);
-+#endif
-+
- if (ltq_pci_plat_arch_init)
- return ltq_pci_plat_arch_init(dev);
-
-@@ -23,5 +30,10 @@ int pcibios_plat_dev_init(struct pci_dev
-
- int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
- {
-+#ifdef CONFIG_PCIE_LANTIQ
-+ if (pci_find_capability((struct pci_dev *)dev, PCI_CAP_ID_EXP))
-+ return ifx_pcie_bios_map_irq(dev, slot, pin);
-+#endif
-+
- return of_irq_parse_and_map_pci(dev, slot, pin);
- }
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pci_common.h
-@@ -0,0 +1,53 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pci_common.h
-+** PROJECT : IFX UEIP
-+** MODULES : PCI subsystem
-+**
-+** DATE : 30 June 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 30 June,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+
-+#ifndef IFXMIPS_PCI_COMMON_H
-+#define IFXMIPS_PCI_COMMON_H
-+#include <linux/version.h>
-+/*!
-+ \defgroup IFX_PCI_COM IFX PCI/PCIe common parts for OS integration
-+ \brief PCI/PCIe common parts
-+*/
-+
-+/*!
-+ \defgroup IFX_PCI_COM_OS OS APIs
-+ \ingroup IFX_PCI_COM
-+ \brief PCI/PCIe bus driver OS interface functions
-+*/
-+/*!
-+ \file ifxmips_pci_common.h
-+ \ingroup IFX_PCI_COM
-+ \brief PCI/PCIe bus driver common OS header file
-+*/
-+#define IFX_PCI_CONST const
-+#ifdef CONFIG_IFX_PCI
-+extern int ifx_pci_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
-+extern int ifx_pci_bios_plat_dev_init(struct pci_dev *dev);
-+#endif /* COFNIG_IFX_PCI */
-+
-+#ifdef CONFIG_PCIE_LANTIQ
-+extern int ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
-+extern int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev);
-+#endif
-+
-+#endif /* IFXMIPS_PCI_COMMON_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie.c
-@@ -0,0 +1,1091 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ * Copyright (C) 2009 Lei Chuanhua <chuanhua.lei@infineon.com>
-+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/mm.h>
-+#include <asm/paccess.h>
-+#include <linux/pci.h>
-+#include <linux/pci_regs.h>
-+#include <linux/module.h>
-+
-+#include "ifxmips_pcie.h"
-+#include "ifxmips_pcie_reg.h"
-+
-+/* Enable 32bit io due to its mem mapped io nature */
-+#define IFX_PCIE_ERROR_INT
-+#define IFX_PCIE_IO_32BIT
-+
-+#define IFX_PCIE_IR (INT_NUM_IM4_IRL0 + 25)
-+#define IFX_PCIE_INTA (INT_NUM_IM4_IRL0 + 8)
-+#define IFX_PCIE_INTB (INT_NUM_IM4_IRL0 + 9)
-+#define IFX_PCIE_INTC (INT_NUM_IM4_IRL0 + 10)
-+#define IFX_PCIE_INTD (INT_NUM_IM4_IRL0 + 11)
-+#define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
-+#define SM(_v, _f) (((_v) << _f##_S) & (_f))
-+#define IFX_REG_SET_BIT(_f, _r) \
-+ IFX_REG_W32((IFX_REG_R32((_r)) &~ (_f)) | (_f), (_r))
-+
-+#define IFX_PCIE_LTSSM_ENABLE_TIMEOUT 10
-+
-+static DEFINE_SPINLOCK(ifx_pcie_lock);
-+
-+u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
-+
-+static ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
-+ {
-+ .ir_irq = {
-+ .irq = IFX_PCIE_IR,
-+ .name = "ifx_pcie_rc0",
-+ },
-+
-+ .legacy_irq = {
-+ {
-+ .irq_bit = PCIE_IRN_INTA,
-+ .irq = IFX_PCIE_INTA,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTB,
-+ .irq = IFX_PCIE_INTB,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTC,
-+ .irq = IFX_PCIE_INTC,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTD,
-+ .irq = IFX_PCIE_INTD,
-+ },
-+ },
-+ },
-+
-+};
-+
-+void ifx_pcie_debug(const char *fmt, ...)
-+{
-+ static char buf[256] = {0}; /* XXX */
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ vsnprintf(buf, sizeof(buf), fmt, ap);
-+ va_end(ap);
-+
-+ printk("%s", buf);
-+}
-+
-+
-+static inline int pcie_ltssm_enable(int pcie_port)
-+{
-+ int i;
-+
-+ /* Enable LTSSM */
-+ IFX_REG_W32(PCIE_RC_CCR_LTSSM_ENABLE, PCIE_RC_CCR(pcie_port));
-+
-+ /* Wait for the link to come up */
-+ for (i = 0; i < IFX_PCIE_LTSSM_ENABLE_TIMEOUT; i++) {
-+ if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_RETRAIN_PENDING))
-+ return 0;
-+ udelay(10);
-+ }
-+
-+ printk("%s link timeout!!!!!\n", __func__);
-+ return -1;
-+}
-+
-+static inline void pcie_status_register_clear(int pcie_port)
-+{
-+ IFX_REG_W32(0, PCIE_RC_DR(pcie_port));
-+ IFX_REG_W32(0, PCIE_PCICMDSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_DCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_LCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_SLCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_RSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_UES_R(pcie_port));
-+ IFX_REG_W32(0, PCIE_UEMR(pcie_port));
-+ IFX_REG_W32(0, PCIE_UESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_CESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_CEMR(pcie_port));
-+ IFX_REG_W32(0, PCIE_RESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_PVCCRSR(pcie_port));
-+ IFX_REG_W32(0, PCIE_VC0_RSR0(pcie_port));
-+ IFX_REG_W32(0, PCIE_TPFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_TNPFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_TCFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_QSR(pcie_port));
-+ IFX_REG_W32(0, PCIE_IOBLSECS(pcie_port));
-+}
-+
-+static inline int ifx_pcie_link_up(int pcie_port)
-+{
-+ return (IFX_REG_R32(PCIE_PHY_SR(pcie_port)) & PCIE_PHY_SR_PHY_LINK_UP) ? 1 : 0;
-+}
-+
-+
-+static inline void pcie_mem_io_setup(int pcie_port)
-+{
-+ u32 reg;
-+ /*
-+ * BAR[0:1] readonly register
-+ * RC contains only minimal BARs for packets mapped to this device
-+ * Mem/IO filters defines a range of memory occupied by memory mapped IO devices that
-+ * reside on the downstream side fo the bridge.
-+ */
-+ reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_MBML_MEM_LIMIT_ADDR)
-+ | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_MBML_MEM_BASE_ADDR);
-+
-+ IFX_REG_W32(reg, PCIE_MBML(pcie_port));
-+
-+
-+#ifdef IFX_PCIE_PREFETCH_MEM_64BIT
-+ reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_PMBL_END_ADDR)
-+ | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_PMBL_UPPER_12BIT)
-+ | PCIE_PMBL_64BIT_ADDR;
-+ IFX_REG_W32(reg, PCIE_PMBL(pcie_port));
-+
-+ /* Must configure upper 32bit */
-+ IFX_REG_W32(0, PCIE_PMBU32(pcie_port));
-+ IFX_REG_W32(0, PCIE_PMLU32(pcie_port));
-+#else
-+ /* PCIe_PBML, same as MBML */
-+ IFX_REG_W32(IFX_REG_R32(PCIE_MBML(pcie_port)), PCIE_PMBL(pcie_port));
-+#endif
-+
-+ /* IO Address Range */
-+ reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 12), PCIE_IOBLSECS_IO_LIMIT_ADDR)
-+ | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 12), PCIE_IOBLSECS_IO_BASE_ADDR);
-+#ifdef IFX_PCIE_IO_32BIT
-+ reg |= PCIE_IOBLSECS_32BIT_IO_ADDR;
-+#endif /* IFX_PCIE_IO_32BIT */
-+ IFX_REG_W32(reg, PCIE_IOBLSECS(pcie_port));
-+
-+#ifdef IFX_PCIE_IO_32BIT
-+ reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT)
-+ | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_BASE);
-+ IFX_REG_W32(reg, PCIE_IO_BANDL(pcie_port));
-+
-+#endif /* IFX_PCIE_IO_32BIT */
-+}
-+
-+static inline void
-+pcie_device_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Device capability register, set up Maximum payload size */
-+ reg = IFX_REG_R32(PCIE_DCAP(pcie_port));
-+ reg |= PCIE_DCAP_ROLE_BASE_ERR_REPORT;
-+ reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCAP_MAX_PAYLOAD_SIZE);
-+
-+ /* Only available for EP */
-+ reg &= ~(PCIE_DCAP_EP_L0S_LATENCY | PCIE_DCAP_EP_L1_LATENCY);
-+ IFX_REG_W32(reg, PCIE_DCAP(pcie_port));
-+
-+ /* Device control and status register */
-+ /* Set Maximum Read Request size for the device as a Requestor */
-+ reg = IFX_REG_R32(PCIE_DCTLSTS(pcie_port));
-+
-+ /*
-+ * Request size can be larger than the MPS used, but the completions returned
-+ * for the read will be bounded by the MPS size.
-+ * In our system, Max request size depends on AHB burst size. It is 64 bytes.
-+ * but we set it as 128 as minimum one.
-+ */
-+ reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_READ_SIZE)
-+ | SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_PAYLOAD_SIZE);
-+
-+ /* Enable relaxed ordering, no snoop, and all kinds of errors */
-+ reg |= PCIE_DCTLSTS_RELAXED_ORDERING_EN | PCIE_DCTLSTS_ERR_EN | PCIE_DCTLSTS_NO_SNOOP_EN;
-+
-+ IFX_REG_W32(reg, PCIE_DCTLSTS(pcie_port));
-+}
-+
-+static inline void
-+pcie_link_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /*
-+ * XXX, Link capability register, bit 18 for EP CLKREQ# dynamic clock management for L1, L2/3 CPM
-+ * L0s is reported during link training via TS1 order set by N_FTS
-+ */
-+ reg = IFX_REG_R32(PCIE_LCAP(pcie_port));
-+ reg &= ~PCIE_LCAP_L0S_EIXT_LATENCY;
-+ reg |= SM(3, PCIE_LCAP_L0S_EIXT_LATENCY);
-+ IFX_REG_W32(reg, PCIE_LCAP(pcie_port));
-+
-+ /* Link control and status register */
-+ reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
-+
-+ /* Link Enable, ASPM enabled */
-+ reg &= ~PCIE_LCTLSTS_LINK_DISABLE;
-+
-+#ifdef CONFIG_PCIEASPM
-+ /*
-+ * We use the same physical reference clock that the platform provides on the connector
-+ * It paved the way for ASPM to calculate the new exit Latency
-+ */
-+ reg |= PCIE_LCTLSTS_SLOT_CLK_CFG;
-+ reg |= PCIE_LCTLSTS_COM_CLK_CFG;
-+ /*
-+ * We should disable ASPM by default except that we have dedicated power management support
-+ * Enable ASPM will cause the system hangup/instability, performance degration
-+ */
-+ reg |= PCIE_LCTLSTS_ASPM_ENABLE;
-+#else
-+ reg &= ~PCIE_LCTLSTS_ASPM_ENABLE;
-+#endif /* CONFIG_PCIEASPM */
-+
-+ /*
-+ * The maximum size of any completion with data packet is bounded by the MPS setting
-+ * in device control register
-+ */
-+
-+ /* RCB may cause multiple split transactions, two options available, we use 64 byte RCB */
-+ reg &= ~ PCIE_LCTLSTS_RCB128;
-+
-+ IFX_REG_W32(reg, PCIE_LCTLSTS(pcie_port));
-+}
-+
-+static inline void pcie_error_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /*
-+ * Forward ERR_COR, ERR_NONFATAL, ERR_FATAL to the backbone
-+ * Poisoned write TLPs and completions indicating poisoned TLPs will set the PCIe_PCICMDSTS.MDPE
-+ */
-+ reg = IFX_REG_R32(PCIE_INTRBCTRL(pcie_port));
-+ reg |= PCIE_INTRBCTRL_SERR_ENABLE | PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE;
-+
-+ IFX_REG_W32(reg, PCIE_INTRBCTRL(pcie_port));
-+
-+ /* Uncorrectable Error Mask Register, Unmask <enable> all bits in PCIE_UESR */
-+ reg = IFX_REG_R32(PCIE_UEMR(pcie_port));
-+ reg &= ~PCIE_ALL_UNCORRECTABLE_ERR;
-+ IFX_REG_W32(reg, PCIE_UEMR(pcie_port));
-+
-+ /* Uncorrectable Error Severity Register, ALL errors are FATAL */
-+ IFX_REG_W32(PCIE_ALL_UNCORRECTABLE_ERR, PCIE_UESR(pcie_port));
-+
-+ /* Correctable Error Mask Register, unmask <enable> all bits */
-+ reg = IFX_REG_R32(PCIE_CEMR(pcie_port));
-+ reg &= ~PCIE_CORRECTABLE_ERR;
-+ IFX_REG_W32(reg, PCIE_CEMR(pcie_port));
-+
-+ /* Advanced Error Capabilities and Control Registr */
-+ reg = IFX_REG_R32(PCIE_AECCR(pcie_port));
-+ reg |= PCIE_AECCR_ECRC_CHECK_EN | PCIE_AECCR_ECRC_GEN_EN;
-+ IFX_REG_W32(reg, PCIE_AECCR(pcie_port));
-+
-+ /* Root Error Command Register, Report all types of errors */
-+ reg = IFX_REG_R32(PCIE_RECR(pcie_port));
-+ reg |= PCIE_RECR_ERR_REPORT_EN;
-+ IFX_REG_W32(reg, PCIE_RECR(pcie_port));
-+
-+ /* Clear the Root status register */
-+ reg = IFX_REG_R32(PCIE_RESR(pcie_port));
-+ IFX_REG_W32(reg, PCIE_RESR(pcie_port));
-+}
-+
-+static inline void pcie_port_logic_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* FTS number, default 12, increase to 63, may increase time from/to L0s to L0 */
-+ reg = IFX_REG_R32(PCIE_AFR(pcie_port));
-+ reg &= ~(PCIE_AFR_FTS_NUM | PCIE_AFR_COM_FTS_NUM);
-+ reg |= SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_FTS_NUM)
-+ | SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_COM_FTS_NUM);
-+ /* L0s and L1 entry latency */
-+ reg &= ~(PCIE_AFR_L0S_ENTRY_LATENCY | PCIE_AFR_L1_ENTRY_LATENCY);
-+ reg |= SM(PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L0S_ENTRY_LATENCY)
-+ | SM(PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L1_ENTRY_LATENCY);
-+ IFX_REG_W32(reg, PCIE_AFR(pcie_port));
-+
-+
-+ /* Port Link Control Register */
-+ reg = IFX_REG_R32(PCIE_PLCR(pcie_port));
-+ reg |= PCIE_PLCR_DLL_LINK_EN; /* Enable the DLL link */
-+ IFX_REG_W32(reg, PCIE_PLCR(pcie_port));
-+
-+ /* Lane Skew Register */
-+ reg = IFX_REG_R32(PCIE_LSR(pcie_port));
-+ /* Enable ACK/NACK and FC */
-+ reg &= ~(PCIE_LSR_ACKNAK_DISABLE | PCIE_LSR_FC_DISABLE);
-+ IFX_REG_W32(reg, PCIE_LSR(pcie_port));
-+
-+ /* Symbol Timer Register and Filter Mask Register 1 */
-+ reg = IFX_REG_R32(PCIE_STRFMR(pcie_port));
-+
-+ /* Default SKP interval is very accurate already, 5us */
-+ /* Enable IO/CFG transaction */
-+ reg |= PCIE_STRFMR_RX_CFG_TRANS_ENABLE | PCIE_STRFMR_RX_IO_TRANS_ENABLE;
-+ /* Disable FC WDT */
-+ reg &= ~PCIE_STRFMR_FC_WDT_DISABLE;
-+ IFX_REG_W32(reg, PCIE_STRFMR(pcie_port));
-+
-+ /* Filter Masker Register 2 */
-+ reg = IFX_REG_R32(PCIE_FMR2(pcie_port));
-+ reg |= PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 | PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1;
-+ IFX_REG_W32(reg, PCIE_FMR2(pcie_port));
-+
-+ /* VC0 Completion Receive Queue Control Register */
-+ reg = IFX_REG_R32(PCIE_VC0_CRQCR(pcie_port));
-+ reg &= ~PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE;
-+ reg |= SM(PCIE_VC0_TLP_QUEUE_MODE_BYPASS, PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE);
-+ IFX_REG_W32(reg, PCIE_VC0_CRQCR(pcie_port));
-+}
-+
-+static inline void pcie_rc_cfg_reg_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Disable LTSSM */
-+ IFX_REG_W32(0, PCIE_RC_CCR(pcie_port)); /* Disable LTSSM */
-+
-+ pcie_mem_io_setup(pcie_port);
-+
-+ /* XXX, MSI stuff should only apply to EP */
-+ /* MSI Capability: Only enable 32-bit addresses */
-+ reg = IFX_REG_R32(PCIE_MCAPR(pcie_port));
-+ reg &= ~PCIE_MCAPR_ADDR64_CAP;
-+
-+ reg |= PCIE_MCAPR_MSI_ENABLE;
-+
-+ /* Disable multiple message */
-+ reg &= ~(PCIE_MCAPR_MULTI_MSG_CAP | PCIE_MCAPR_MULTI_MSG_ENABLE);
-+ IFX_REG_W32(reg, PCIE_MCAPR(pcie_port));
-+
-+
-+ /* Enable PME, Soft reset enabled */
-+ reg = IFX_REG_R32(PCIE_PM_CSR(pcie_port));
-+ reg |= PCIE_PM_CSR_PME_ENABLE | PCIE_PM_CSR_SW_RST;
-+ IFX_REG_W32(reg, PCIE_PM_CSR(pcie_port));
-+
-+ /* setup the bus */
-+ reg = SM(0, PCIE_BNR_PRIMARY_BUS_NUM) | SM(1, PCIE_PNR_SECONDARY_BUS_NUM) | SM(0xFF, PCIE_PNR_SUB_BUS_NUM);
-+ IFX_REG_W32(reg, PCIE_BNR(pcie_port));
-+
-+
-+ pcie_device_setup(pcie_port);
-+ pcie_link_setup(pcie_port);
-+ pcie_error_setup(pcie_port);
-+
-+ /* Root control and capabilities register */
-+ reg = IFX_REG_R32(PCIE_RCTLCAP(pcie_port));
-+ reg |= PCIE_RCTLCAP_SERR_ENABLE | PCIE_RCTLCAP_PME_INT_EN;
-+ IFX_REG_W32(reg, PCIE_RCTLCAP(pcie_port));
-+
-+ /* Port VC Capability Register 2 */
-+ reg = IFX_REG_R32(PCIE_PVC2(pcie_port));
-+ reg &= ~PCIE_PVC2_VC_ARB_WRR;
-+ reg |= PCIE_PVC2_VC_ARB_16P_FIXED_WRR;
-+ IFX_REG_W32(reg, PCIE_PVC2(pcie_port));
-+
-+ /* VC0 Resource Capability Register */
-+ reg = IFX_REG_R32(PCIE_VC0_RC(pcie_port));
-+ reg &= ~PCIE_VC0_RC_REJECT_SNOOP;
-+ IFX_REG_W32(reg, PCIE_VC0_RC(pcie_port));
-+
-+ pcie_port_logic_setup(pcie_port);
-+}
-+
-+static int ifx_pcie_wait_phy_link_up(int pcie_port)
-+{
-+#define IFX_PCIE_PHY_LINK_UP_TIMEOUT 1000 /* XXX, tunable */
-+ int i;
-+
-+ /* Wait for PHY link is up */
-+ for (i = 0; i < IFX_PCIE_PHY_LINK_UP_TIMEOUT; i++) {
-+ if (ifx_pcie_link_up(pcie_port)) {
-+ break;
-+ }
-+ udelay(100);
-+ }
-+ if (i >= IFX_PCIE_PHY_LINK_UP_TIMEOUT) {
-+ printk(KERN_ERR "%s timeout\n", __func__);
-+ return -1;
-+ }
-+
-+ /* Check data link up or not */
-+ if (!(IFX_REG_R32(PCIE_RC_DR(pcie_port)) & PCIE_RC_DR_DLL_UP)) {
-+ printk(KERN_ERR "%s DLL link is still down\n", __func__);
-+ return -1;
-+ }
-+
-+ /* Check Data link active or not */
-+ if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_DLL_ACTIVE)) {
-+ printk(KERN_ERR "%s DLL is not active\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static inline int pcie_app_loigc_setup(int pcie_port)
-+{
-+ /* supress ahb bus errrors */
-+ IFX_REG_W32(PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS, PCIE_AHB_CTRL(pcie_port));
-+
-+ /* Pull PCIe EP out of reset */
-+ pcie_device_rst_deassert(pcie_port);
-+
-+ /* Start LTSSM training between RC and EP */
-+ pcie_ltssm_enable(pcie_port);
-+
-+ /* Check PHY status after enabling LTSSM */
-+ if (ifx_pcie_wait_phy_link_up(pcie_port) != 0)
-+ return -1;
-+
-+ return 0;
-+}
-+
-+/*
-+ * The numbers below are directly from the PCIe spec table 3-4/5.
-+ */
-+static inline void pcie_replay_time_update(int pcie_port)
-+{
-+ u32 reg;
-+ int nlw;
-+ int rtl;
-+
-+ reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
-+
-+ nlw = MS(reg, PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH);
-+ switch (nlw) {
-+ case PCIE_MAX_LENGTH_WIDTH_X1:
-+ rtl = 1677;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X2:
-+ rtl = 867;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X4:
-+ rtl = 462;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X8:
-+ rtl = 258;
-+ break;
-+ default:
-+ rtl = 1677;
-+ break;
-+ }
-+ reg = IFX_REG_R32(PCIE_ALTRT(pcie_port));
-+ reg &= ~PCIE_ALTRT_REPLAY_TIME_LIMIT;
-+ reg |= SM(rtl, PCIE_ALTRT_REPLAY_TIME_LIMIT);
-+ IFX_REG_W32(reg, PCIE_ALTRT(pcie_port));
-+}
-+
-+/*
-+ * Table 359 Enhanced Configuration Address Mapping1)
-+ * 1) This table is defined in Table 7-1, page 341, PCI Express Base Specification v1.1
-+ * Memory Address PCI Express Configuration Space
-+ * A[(20+n-1):20] Bus Number 1 < n < 8
-+ * A[19:15] Device Number
-+ * A[14:12] Function Number
-+ * A[11:8] Extended Register Number
-+ * A[7:2] Register Number
-+ * A[1:0] Along with size of the access, used to generate Byte Enables
-+ * For VR9, only the address bits [22:0] are mapped to the configuration space:
-+ * . Address bits [22:20] select the target bus (1-of-8)1)
-+ * . Address bits [19:15] select the target device (1-of-32) on the bus
-+ * . Address bits [14:12] select the target function (1-of-8) within the device.
-+ * . Address bits [11:2] selects the target dword (1-of-1024) within the selected function.s configuration space
-+ * . Address bits [1:0] define the start byte location within the selected dword.
-+ */
-+static inline u32 pcie_bus_addr(u8 bus_num, u16 devfn, int where)
-+{
-+ u32 addr;
-+ u8 bus;
-+
-+ if (!bus_num) {
-+ /* type 0 */
-+ addr = ((PCI_SLOT(devfn) & 0x1F) << 15) | ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF)& ~3);
-+ } else {
-+ bus = bus_num;
-+ /* type 1, only support 8 buses */
-+ addr = ((bus & 0x7) << 20) | ((PCI_SLOT(devfn) & 0x1F) << 15) |
-+ ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF) & ~3);
-+ }
-+ return addr;
-+}
-+
-+static int pcie_valid_config(int pcie_port, int bus, int dev)
-+{
-+ /* RC itself */
-+ if ((bus == 0) && (dev == 0)) {
-+ return 1;
-+ }
-+
-+ /* No physical link */
-+ if (!ifx_pcie_link_up(pcie_port)) {
-+ return 0;
-+ }
-+
-+ /* Bus zero only has RC itself
-+ * XXX, check if EP will be integrated
-+ */
-+ if ((bus == 0) && (dev != 0)) {
-+ return 0;
-+ }
-+
-+ /* Maximum 8 buses supported for VRX */
-+ if (bus > 9) {
-+ return 0;
-+ }
-+
-+ /*
-+ * PCIe is PtP link, one bus only supports only one device
-+ * except bus zero and PCIe switch which is virtual bus device
-+ * The following two conditions really depends on the system design
-+ * and attached the device.
-+ * XXX, how about more new switch
-+ */
-+ if ((bus == 1) && (dev != 0)) {
-+ return 0;
-+ }
-+
-+ if ((bus >= 3) && (dev != 0)) {
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+static inline u32 ifx_pcie_cfg_rd(int pcie_port, u32 reg)
-+{
-+ return IFX_REG_R32((volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline void ifx_pcie_cfg_wr(int pcie_port, unsigned int reg, u32 val)
-+{
-+ IFX_REG_W32( val, (volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline u32 ifx_pcie_rc_cfg_rd(int pcie_port, u32 reg)
-+{
-+ return IFX_REG_R32((volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline void ifx_pcie_rc_cfg_wr(int pcie_port, unsigned int reg, u32 val)
-+{
-+ IFX_REG_W32(val, (volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+u32 ifx_pcie_bus_enum_read_hack(int where, u32 value)
-+{
-+ u32 tvalue = value;
-+
-+ if (where == PCI_PRIMARY_BUS) {
-+ u8 primary, secondary, subordinate;
-+
-+ primary = tvalue & 0xFF;
-+ secondary = (tvalue >> 8) & 0xFF;
-+ subordinate = (tvalue >> 16) & 0xFF;
-+ primary += pcibios_1st_host_bus_nr();
-+ secondary += pcibios_1st_host_bus_nr();
-+ subordinate += pcibios_1st_host_bus_nr();
-+ tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
-+ }
-+ return tvalue;
-+}
-+
-+u32 ifx_pcie_bus_enum_write_hack(int where, u32 value)
-+{
-+ u32 tvalue = value;
-+
-+ if (where == PCI_PRIMARY_BUS) {
-+ u8 primary, secondary, subordinate;
-+
-+ primary = tvalue & 0xFF;
-+ secondary = (tvalue >> 8) & 0xFF;
-+ subordinate = (tvalue >> 16) & 0xFF;
-+ if (primary > 0 && primary != 0xFF) {
-+ primary -= pcibios_1st_host_bus_nr();
-+ }
-+
-+ if (secondary > 0 && secondary != 0xFF) {
-+ secondary -= pcibios_1st_host_bus_nr();
-+ }
-+ if (subordinate > 0 && subordinate != 0xFF) {
-+ subordinate -= pcibios_1st_host_bus_nr();
-+ }
-+ tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
-+ }
-+ else if (where == PCI_SUBORDINATE_BUS) {
-+ u8 subordinate = tvalue & 0xFF;
-+
-+ subordinate = subordinate > 0 ? subordinate - pcibios_1st_host_bus_nr() : 0;
-+ tvalue = subordinate;
-+ }
-+ return tvalue;
-+}
-+
-+static int ifx_pcie_read_config(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 *value)
-+{
-+ u32 data = 0;
-+ int bus_number = bus->number;
-+ static const u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
-+ int ret = PCIBIOS_SUCCESSFUL;
-+ struct ifx_pci_controller *ctrl = bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ if (unlikely(size != 1 && size != 2 && size != 4)){
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+
-+ /* Make sure the address is aligned to natural boundary */
-+ if (unlikely(((size - 1) & where))) {
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+
-+ /*
-+ * If we are second controller, we have to cheat OS so that it assume
-+ * its bus number starts from 0 in host controller
-+ */
-+ bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
-+
-+ /*
-+ * We need to force the bus number to be zero on the root
-+ * bus. Linux numbers the 2nd root bus to start after all
-+ * busses on root 0.
-+ */
-+ if (bus->parent == NULL) {
-+ bus_number = 0;
-+ }
-+
-+ /*
-+ * PCIe only has a single device connected to it. It is
-+ * always device ID 0. Don't bother doing reads for other
-+ * device IDs on the first segment.
-+ */
-+ if ((bus_number == 0) && (PCI_SLOT(devfn) != 0)) {
-+ ret = PCIBIOS_FUNC_NOT_SUPPORTED;
-+ goto out;
-+ }
-+
-+ if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
-+ *value = 0xffffffff;
-+ ret = PCIBIOS_DEVICE_NOT_FOUND;
-+ goto out;
-+ }
-+
-+ PCIE_IRQ_LOCK(ifx_pcie_lock);
-+ if (bus_number == 0) { /* RC itself */
-+ u32 t;
-+
-+ t = (where & ~3);
-+ data = ifx_pcie_rc_cfg_rd(pcie_port, t);
-+ } else {
-+ u32 addr = pcie_bus_addr(bus_number, devfn, where);
-+
-+ data = ifx_pcie_cfg_rd(pcie_port, addr);
-+ #ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = le32_to_cpu(data);
-+ #endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ }
-+ /* To get a correct PCI topology, we have to restore the bus number to OS */
-+ data = ifx_pcie_bus_enum_hack(bus, devfn, where, data, pcie_port, 1);
-+
-+ PCIE_IRQ_UNLOCK(ifx_pcie_lock);
-+
-+ *value = (data >> (8 * (where & 3))) & mask[size & 7];
-+out:
-+ return ret;
-+}
-+
-+static u32 ifx_pcie_size_to_value(int where, int size, u32 data, u32 value)
-+{
-+ u32 shift;
-+ u32 tdata = data;
-+
-+ switch (size) {
-+ case 1:
-+ shift = (where & 0x3) << 3;
-+ tdata &= ~(0xffU << shift);
-+ tdata |= ((value & 0xffU) << shift);
-+ break;
-+ case 2:
-+ shift = (where & 3) << 3;
-+ tdata &= ~(0xffffU << shift);
-+ tdata |= ((value & 0xffffU) << shift);
-+ break;
-+ case 4:
-+ tdata = value;
-+ break;
-+ }
-+ return tdata;
-+}
-+
-+static int ifx_pcie_write_config(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 value)
-+{
-+ int bus_number = bus->number;
-+ int ret = PCIBIOS_SUCCESSFUL;
-+ struct ifx_pci_controller *ctrl = bus->sysdata;
-+ int pcie_port = ctrl->port;
-+ u32 tvalue = value;
-+ u32 data;
-+
-+ /* Make sure the address is aligned to natural boundary */
-+ if (unlikely(((size - 1) & where))) {
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+ /*
-+ * If we are second controller, we have to cheat OS so that it assume
-+ * its bus number starts from 0 in host controller
-+ */
-+ bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
-+
-+ /*
-+ * We need to force the bus number to be zero on the root
-+ * bus. Linux numbers the 2nd root bus to start after all
-+ * busses on root 0.
-+ */
-+ if (bus->parent == NULL) {
-+ bus_number = 0;
-+ }
-+
-+ if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
-+ ret = PCIBIOS_DEVICE_NOT_FOUND;
-+ goto out;
-+ }
-+
-+ /* XXX, some PCIe device may need some delay */
-+ PCIE_IRQ_LOCK(ifx_pcie_lock);
-+
-+ /*
-+ * To configure the correct bus topology using native way, we have to cheat Os so that
-+ * it can configure the PCIe hardware correctly.
-+ */
-+ tvalue = ifx_pcie_bus_enum_hack(bus, devfn, where, value, pcie_port, 0);
-+
-+ if (bus_number == 0) { /* RC itself */
-+ u32 t;
-+
-+ t = (where & ~3);
-+ data = ifx_pcie_rc_cfg_rd(pcie_port, t);
-+
-+ data = ifx_pcie_size_to_value(where, size, data, tvalue);
-+
-+ ifx_pcie_rc_cfg_wr(pcie_port, t, data);
-+ } else {
-+ u32 addr = pcie_bus_addr(bus_number, devfn, where);
-+
-+ data = ifx_pcie_cfg_rd(pcie_port, addr);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = le32_to_cpu(data);
-+#endif
-+
-+ data = ifx_pcie_size_to_value(where, size, data, tvalue);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = cpu_to_le32(data);
-+#endif
-+ ifx_pcie_cfg_wr(pcie_port, addr, data);
-+ }
-+ PCIE_IRQ_UNLOCK(ifx_pcie_lock);
-+out:
-+ return ret;
-+}
-+
-+static struct resource ifx_pcie_io_resource = {
-+ .name = "PCIe0 I/O space",
-+ .start = PCIE_IO_PHY_BASE,
-+ .end = PCIE_IO_PHY_END,
-+ .flags = IORESOURCE_IO,
-+};
-+
-+static struct resource ifx_pcie_mem_resource = {
-+ .name = "PCIe0 Memory space",
-+ .start = PCIE_MEM_PHY_BASE,
-+ .end = PCIE_MEM_PHY_END,
-+ .flags = IORESOURCE_MEM,
-+};
-+
-+static struct pci_ops ifx_pcie_ops = {
-+ .read = ifx_pcie_read_config,
-+ .write = ifx_pcie_write_config,
-+};
-+
-+static struct ifx_pci_controller ifx_pcie_controller[IFX_PCIE_CORE_NR] = {
-+ {
-+ .pcic = {
-+ .pci_ops = &ifx_pcie_ops,
-+ .mem_resource = &ifx_pcie_mem_resource,
-+ .io_resource = &ifx_pcie_io_resource,
-+ },
-+ .port = IFX_PCIE_PORT0,
-+ },
-+};
-+
-+#ifdef IFX_PCIE_ERROR_INT
-+
-+static irqreturn_t pcie_rc_core_isr(int irq, void *dev_id)
-+{
-+ struct ifx_pci_controller *ctrl = (struct ifx_pci_controller *)dev_id;
-+ int pcie_port = ctrl->port;
-+ u32 reg;
-+
-+ pr_debug("PCIe RC error intr %d\n", irq);
-+ reg = IFX_REG_R32(PCIE_IRNCR(pcie_port));
-+ reg &= PCIE_RC_CORE_COMBINED_INT;
-+ IFX_REG_W32(reg, PCIE_IRNCR(pcie_port));
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int
-+pcie_rc_core_int_init(int pcie_port)
-+{
-+ int ret;
-+
-+ /* Enable core interrupt */
-+ IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNEN(pcie_port));
-+
-+ /* Clear it first */
-+ IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNCR(pcie_port));
-+ ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
-+ pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
-+ if (ret)
-+ printk(KERN_ERR "%s request irq %d failed\n", __func__, IFX_PCIE_IR);
-+
-+ return ret;
-+}
-+#endif
-+
-+int ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+ u32 irq_bit = 0;
-+ int irq = 0;
-+ struct ifx_pci_controller *ctrl = dev->bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ printk("%s port %d dev %s slot %d pin %d \n", __func__, pcie_port, pci_name(dev), slot, pin);
-+
-+ if ((pin == PCIE_LEGACY_DISABLE) || (pin > PCIE_LEGACY_INT_MAX)) {
-+ printk(KERN_WARNING "WARNING: dev %s: invalid interrupt pin %d\n", pci_name(dev), pin);
-+ return -1;
-+ }
-+
-+ /* Pin index so minus one */
-+ irq_bit = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq_bit;
-+ irq = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq;
-+ IFX_REG_SET_BIT(irq_bit, PCIE_IRNEN(pcie_port));
-+ IFX_REG_SET_BIT(irq_bit, PCIE_IRNCR(pcie_port));
-+ printk("%s dev %s irq %d assigned\n", __func__, pci_name(dev), irq);
-+ return irq;
-+}
-+
-+int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev)
-+{
-+ u16 config;
-+#ifdef IFX_PCIE_ERROR_INT
-+ u32 dconfig;
-+ int pos;
-+#endif
-+
-+ /* Enable reporting System errors and parity errors on all devices */
-+ /* Enable parity checking and error reporting */
-+ pci_read_config_word(dev, PCI_COMMAND, &config);
-+ config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR /*| PCI_COMMAND_INVALIDATE |
-+ PCI_COMMAND_FAST_BACK*/;
-+ pci_write_config_word(dev, PCI_COMMAND, config);
-+
-+ if (dev->subordinate) {
-+ /* Set latency timers on sub bridges */
-+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40); /* XXX, */
-+ /* More bridge error detection */
-+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
-+ config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
-+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
-+ }
-+#ifdef IFX_PCIE_ERROR_INT
-+ /* Enable the PCIe normal error reporting */
-+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-+ if (pos) {
-+
-+ /* Disable system error generation in response to error messages */
-+ pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &config);
-+ config &= ~(PCI_EXP_RTCTL_SECEE | PCI_EXP_RTCTL_SENFEE | PCI_EXP_RTCTL_SEFEE);
-+ pci_write_config_word(dev, pos + PCI_EXP_RTCTL, config);
-+
-+ /* Clear PCIE Capability's Device Status */
-+ pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &config);
-+ pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, config);
-+
-+ /* Update Device Control */
-+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
-+ /* Correctable Error Reporting */
-+ config |= PCI_EXP_DEVCTL_CERE;
-+ /* Non-Fatal Error Reporting */
-+ config |= PCI_EXP_DEVCTL_NFERE;
-+ /* Fatal Error Reporting */
-+ config |= PCI_EXP_DEVCTL_FERE;
-+ /* Unsupported Request */
-+ config |= PCI_EXP_DEVCTL_URRE;
-+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
-+ }
-+
-+ /* Find the Advanced Error Reporting capability */
-+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-+ if (pos) {
-+ /* Clear Uncorrectable Error Status */
-+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, dconfig);
-+ /* Enable reporting of all uncorrectable errors */
-+ /* Uncorrectable Error Mask - turned on bits disable errors */
-+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
-+ /*
-+ * Leave severity at HW default. This only controls if
-+ * errors are reported as uncorrectable or
-+ * correctable, not if the error is reported.
-+ */
-+ /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
-+ /* Clear Correctable Error Status */
-+ pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
-+ /* Enable reporting of all correctable errors */
-+ /* Correctable Error Mask - turned on bits disable errors */
-+ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
-+ /* Advanced Error Capabilities */
-+ pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
-+ /* ECRC Generation Enable */
-+ if (dconfig & PCI_ERR_CAP_ECRC_GENC) {
-+ dconfig |= PCI_ERR_CAP_ECRC_GENE;
-+ }
-+ /* ECRC Check Enable */
-+ if (dconfig & PCI_ERR_CAP_ECRC_CHKC) {
-+ dconfig |= PCI_ERR_CAP_ECRC_CHKE;
-+ }
-+ pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
-+
-+ /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
-+ /* Enable Root Port's interrupt in response to error messages */
-+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
-+ PCI_ERR_ROOT_CMD_COR_EN |
-+ PCI_ERR_ROOT_CMD_NONFATAL_EN |
-+ PCI_ERR_ROOT_CMD_FATAL_EN);
-+ /* Clear the Root status register */
-+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
-+ }
-+#endif /* IFX_PCIE_ERROR_INT */
-+ /* WAR, only 128 MRRS is supported, force all EPs to support this value */
-+ pcie_set_readrq(dev, 128);
-+ return 0;
-+}
-+
-+static int
-+pcie_rc_initialize(int pcie_port)
-+{
-+ int i;
-+#define IFX_PCIE_PHY_LOOP_CNT 5
-+
-+ pcie_rcu_endian_setup(pcie_port);
-+
-+ pcie_ep_gpio_rst_init(pcie_port);
-+
-+ /*
-+ * XXX, PCIe elastic buffer bug will cause not to be detected. One more
-+ * reset PCIe PHY will solve this issue
-+ */
-+ for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
-+ /* Disable PCIe PHY Analog part for sanity check */
-+ pcie_phy_pmu_disable(pcie_port);
-+
-+ pcie_phy_rst_assert(pcie_port);
-+ pcie_phy_rst_deassert(pcie_port);
-+
-+ /* Make sure PHY PLL is stable */
-+ udelay(20);
-+
-+ /* PCIe Core reset enabled, low active, sw programmed */
-+ pcie_core_rst_assert(pcie_port);
-+
-+ /* Put PCIe EP in reset status */
-+ pcie_device_rst_assert(pcie_port);
-+
-+ /* PCI PHY & Core reset disabled, high active, sw programmed */
-+ pcie_core_rst_deassert(pcie_port);
-+
-+ /* Already in a quiet state, program PLL, enable PHY, check ready bit */
-+ pcie_phy_clock_mode_setup(pcie_port);
-+
-+ /* Enable PCIe PHY and Clock */
-+ pcie_core_pmu_setup(pcie_port);
-+
-+ /* Clear status registers */
-+ pcie_status_register_clear(pcie_port);
-+
-+#ifdef CONFIG_PCI_MSI
-+ pcie_msi_init(pcie_port);
-+#endif /* CONFIG_PCI_MSI */
-+ pcie_rc_cfg_reg_setup(pcie_port);
-+
-+ /* Once link is up, break out */
-+ if (pcie_app_loigc_setup(pcie_port) == 0)
-+ break;
-+ }
-+ if (i >= IFX_PCIE_PHY_LOOP_CNT) {
-+ printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
-+ return -EIO;
-+ }
-+ /* NB, don't increase ACK/NACK timer timeout value, which will cause a lot of COR errors */
-+ pcie_replay_time_update(pcie_port);
-+ return 0;
-+}
-+
-+static int __init ifx_pcie_bios_init(void)
-+{
-+ void __iomem *io_map_base;
-+ int pcie_port;
-+ int startup_port;
-+
-+ /* Enable AHB Master/ Slave */
-+ pcie_ahb_pmu_setup();
-+
-+ startup_port = IFX_PCIE_PORT0;
-+
-+ for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
-+ if (pcie_rc_initialize(pcie_port) == 0) {
-+ IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
-+ __func__, PCIE_CFG_PORT_TO_BASE(pcie_port));
-+ /* Otherwise, warning will pop up */
-+ io_map_base = ioremap(PCIE_IO_PHY_PORT_TO_BASE(pcie_port), PCIE_IO_SIZE);
-+ if (io_map_base == NULL) {
-+ IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
-+ return -ENOMEM;
-+ }
-+ ifx_pcie_controller[pcie_port].pcic.io_map_base = (unsigned long)io_map_base;
-+
-+ register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
-+ /* XXX, clear error status */
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: mem_resource 0x%p, io_resource 0x%p\n",
-+ __func__, &ifx_pcie_controller[pcie_port].pcic.mem_resource,
-+ &ifx_pcie_controller[pcie_port].pcic.io_resource);
-+
-+ #ifdef IFX_PCIE_ERROR_INT
-+ pcie_rc_core_int_init(pcie_port);
-+ #endif /* IFX_PCIE_ERROR_INT */
-+ }
-+ }
-+
-+ return 0;
-+}
-+arch_initcall(ifx_pcie_bios_init);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
-+MODULE_DESCRIPTION("Infineon builtin PCIe RC driver");
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie.h
-@@ -0,0 +1,131 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_H
-+#define IFXMIPS_PCIE_H
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+#include "ifxmips_pci_common.h"
-+#include "ifxmips_pcie_reg.h"
-+
-+/*!
-+ \defgroup IFX_PCIE PCI Express bus driver module
-+ \brief PCI Express IP module support VRX200
-+*/
-+
-+/*!
-+ \defgroup IFX_PCIE_OS OS APIs
-+ \ingroup IFX_PCIE
-+ \brief PCIe bus driver OS interface functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module common header file
-+*/
-+#define PCIE_IRQ_LOCK(lock) do { \
-+ unsigned long flags; \
-+ spin_lock_irqsave(&(lock), flags);
-+#define PCIE_IRQ_UNLOCK(lock) \
-+ spin_unlock_irqrestore(&(lock), flags); \
-+} while (0)
-+
-+#define PCIE_MSG_MSI 0x00000001
-+#define PCIE_MSG_ISR 0x00000002
-+#define PCIE_MSG_FIXUP 0x00000004
-+#define PCIE_MSG_READ_CFG 0x00000008
-+#define PCIE_MSG_WRITE_CFG 0x00000010
-+#define PCIE_MSG_CFG (PCIE_MSG_READ_CFG | PCIE_MSG_WRITE_CFG)
-+#define PCIE_MSG_REG 0x00000020
-+#define PCIE_MSG_INIT 0x00000040
-+#define PCIE_MSG_ERR 0x00000080
-+#define PCIE_MSG_PHY 0x00000100
-+#define PCIE_MSG_ANY 0x000001ff
-+
-+#define IFX_PCIE_PORT0 0
-+#define IFX_PCIE_PORT1 1
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+#define IFX_PCIE_CORE_NR 2
-+#else
-+#define IFX_PCIE_CORE_NR 1
-+#endif
-+
-+#define IFX_PCIE_ERROR_INT
-+
-+//#define IFX_PCIE_DBG
-+
-+#if defined(IFX_PCIE_DBG)
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) do { \
-+ ifx_pcie_debug((_fmt), ##args); \
-+} while (0)
-+
-+#define INLINE
-+#else
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) \
-+ do {} while(0)
-+#define INLINE inline
-+#endif
-+
-+struct ifx_pci_controller {
-+ struct pci_controller pcic;
-+
-+ /* RC specific, per host bus information */
-+ u32 port; /* Port index, 0 -- 1st core, 1 -- 2nd core */
-+};
-+
-+typedef struct ifx_pcie_ir_irq {
-+ const unsigned int irq;
-+ const char name[16];
-+}ifx_pcie_ir_irq_t;
-+
-+typedef struct ifx_pcie_legacy_irq{
-+ const u32 irq_bit;
-+ const int irq;
-+}ifx_pcie_legacy_irq_t;
-+
-+typedef struct ifx_pcie_irq {
-+ ifx_pcie_ir_irq_t ir_irq;
-+ ifx_pcie_legacy_irq_t legacy_irq[PCIE_LEGACY_INT_MAX];
-+}ifx_pcie_irq_t;
-+
-+extern u32 g_pcie_debug_flag;
-+extern void ifx_pcie_debug(const char *fmt, ...);
-+extern void pcie_phy_clock_mode_setup(int pcie_port);
-+extern void pcie_msi_pic_init(int pcie_port);
-+extern u32 ifx_pcie_bus_enum_read_hack(int where, u32 value);
-+extern u32 ifx_pcie_bus_enum_write_hack(int where, u32 value);
-+
-+#define CONFIG_VR9
-+
-+#ifdef CONFIG_VR9
-+#include "ifxmips_pcie_vr9.h"
-+#elif defined (CONFIG_AR10)
-+#include "ifxmips_pcie_ar10.h"
-+#else
-+#error "PCIE: platform not defined"
-+#endif /* CONFIG_VR9 */
-+
-+#endif /* IFXMIPS_PCIE_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_ar10.h
-@@ -0,0 +1,305 @@
-+/****************************************************************************
-+ Copyright (c) 2010
-+ Lantiq Deutschland GmbH
-+ Am Campeon 3; 85579 Neubiberg, Germany
-+
-+ For licensing information, see the file 'LICENSE' in the root folder of
-+ this software module.
-+
-+ *****************************************************************************/
-+/*!
-+ \file ifxmips_pcie_ar10.h
-+ \ingroup IFX_PCIE
-+ \brief PCIe RC driver ar10 specific file
-+*/
-+
-+#ifndef IFXMIPS_PCIE_AR10_H
-+#define IFXMIPS_PCIE_AR10_H
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+
-+/* Project header file */
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_pmu.h>
-+#include <asm/ifx/ifx_gpio.h>
-+#include <asm/ifx/ifx_ebu_led.h>
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+ ifx_ebu_led_enable();
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 1);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 1);
-+ }
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ /* XXX, moved to CGU to control AHBM */
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Inbound, big endian */
-+ reg |= IFX_RCU_BE_AHB4S;
-+ if (pcie_port == 0) {
-+ reg |= IFX_RCU_BE_PCIE0M;
-+
-+ #ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ /* Outbound, software swap needed */
-+ reg |= IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE0S;
-+ #else
-+ /* Outbound little endian */
-+ reg &= ~IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE0S;
-+ #endif
-+ }
-+ else {
-+ reg |= IFX_RCU_BE_PCIE1M;
-+ #ifdef CONFIG_IFX_PCIE1_HW_SWAP
-+ /* Outbound, software swap needed */
-+ reg |= IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE1S;
-+ #else
-+ /* Outbound little endian */
-+ reg &= ~IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE1S;
-+ #endif
-+ }
-+
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ if (pcie_port == 0) { /* XXX, should use macro*/
-+ PCIE0_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PCIE1_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ if (pcie_port == 0) { /* XXX, should use macro*/
-+ PCIE0_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+ }
-+ else {
-+ PCIE1_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+ }
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ if (pcie_port == 0) {
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_BE_PCIE0_PDI;
-+ }
-+ else {
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_BE_PCIE1_PDI;
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ /* Enable PDI to access PCIe PHY register */
-+ PDI0_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PDI1_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset Core, bit 22 */
-+ if (pcie_port == 0) {
-+ reg |= 0x00400000;
-+ }
-+ else {
-+ reg |= 0x08000000; /* Bit 27 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg &= ~0x00400000; /* bit 22 */
-+ }
-+ else {
-+ reg &= ~0x08000000; /* Bit 27 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg |= 0x00001000; /* Bit 12 */
-+ }
-+ else {
-+ reg |= 0x00002000; /* Bit 13 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg &= ~0x00001000; /* Bit 12 */
-+ }
-+ else {
-+ reg &= ~0x00002000; /* Bit 13 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 0);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 0);
-+ }
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 1);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 1);
-+ }
-+ ifx_ebu_led_disable();
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ PCIE0_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PCIE1_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ pcie_msi_pic_init(pcie_port);
-+ if (pcie_port == 0) {
-+ MSI0_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ MSI1_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+ }
-+#endif /* CONFIG_IFX_PCI */
-+ return tbus_number;
-+}
-+
-+static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ }
-+ #endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_AR10_H */
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_msi.c
-@@ -0,0 +1,391 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_msi.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCI MSI sub module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe MSI Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Date $Author $Comment
-+** 02 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \defgroup IFX_PCIE_MSI MSI OS APIs
-+ \ingroup IFX_PCIE
-+ \brief PCIe bus driver OS interface functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie_msi.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe MSI OS interface file
-+*/
-+
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/pci.h>
-+#include <linux/msi.h>
-+#include <linux/module.h>
-+#include <asm/bootinfo.h>
-+#include <asm/irq.h>
-+#include <asm/traps.h>
-+
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_regs.h>
-+#include <asm/ifx/common_routines.h>
-+#include <asm/ifx/irq.h>
-+
-+#include "ifxmips_pcie_reg.h"
-+#include "ifxmips_pcie.h"
-+
-+#define IFX_MSI_IRQ_NUM 16
-+
-+enum {
-+ IFX_PCIE_MSI_IDX0 = 0,
-+ IFX_PCIE_MSI_IDX1,
-+ IFX_PCIE_MSI_IDX2,
-+ IFX_PCIE_MSI_IDX3,
-+};
-+
-+typedef struct ifx_msi_irq_idx {
-+ const int irq;
-+ const int idx;
-+}ifx_msi_irq_idx_t;
-+
-+struct ifx_msi_pic {
-+ volatile u32 pic_table[IFX_MSI_IRQ_NUM];
-+ volatile u32 pic_endian; /* 0x40 */
-+};
-+typedef struct ifx_msi_pic *ifx_msi_pic_t;
-+
-+typedef struct ifx_msi_irq {
-+ const volatile ifx_msi_pic_t msi_pic_p;
-+ const u32 msi_phy_base;
-+ const ifx_msi_irq_idx_t msi_irq_idx[IFX_MSI_IRQ_NUM];
-+ /*
-+ * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
-+ * in use.
-+ */
-+ u16 msi_free_irq_bitmask;
-+
-+ /*
-+ * Each bit in msi_multiple_irq_bitmask tells that the device using
-+ * this bit in msi_free_irq_bitmask is also using the next bit. This
-+ * is used so we can disable all of the MSI interrupts when a device
-+ * uses multiple.
-+ */
-+ u16 msi_multiple_irq_bitmask;
-+}ifx_msi_irq_t;
-+
-+static ifx_msi_irq_t msi_irqs[IFX_PCIE_CORE_NR] = {
-+ {
-+ .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI_PIC_REG_BASE,
-+ .msi_phy_base = PCIE_MSI_PHY_BASE,
-+ .msi_irq_idx = {
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ },
-+ .msi_free_irq_bitmask = 0,
-+ .msi_multiple_irq_bitmask= 0,
-+ },
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ {
-+ .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI1_PIC_REG_BASE,
-+ .msi_phy_base = PCIE1_MSI_PHY_BASE,
-+ .msi_irq_idx = {
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ },
-+ .msi_free_irq_bitmask = 0,
-+ .msi_multiple_irq_bitmask= 0,
-+
-+ },
-+#endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+};
-+
-+/*
-+ * This lock controls updates to msi_free_irq_bitmask,
-+ * msi_multiple_irq_bitmask and pic register settting
-+ */
-+static DEFINE_SPINLOCK(ifx_pcie_msi_lock);
-+
-+void pcie_msi_pic_init(int pcie_port)
-+{
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_pic_p->pic_endian = IFX_MSI_PIC_BIG_ENDIAN;
-+ spin_unlock(&ifx_pcie_msi_lock);
-+}
-+
-+/**
-+ * \fn int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-+ * \brief Called when a driver request MSI interrupts instead of the
-+ * legacy INT A-D. This routine will allocate multiple interrupts
-+ * for MSI devices that support them. A device can override this by
-+ * programming the MSI control bits [6:4] before calling
-+ * pci_enable_msi().
-+ *
-+ * \param[in] pdev Device requesting MSI interrupts
-+ * \param[in] desc MSI descriptor
-+ *
-+ * \return -EINVAL Invalid pcie root port or invalid msi bit
-+ * \return 0 OK
-+ * \ingroup IFX_PCIE_MSI
-+ */
-+int
-+arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-+{
-+ int irq, pos;
-+ u16 control;
-+ int irq_idx;
-+ int irq_step;
-+ int configured_private_bits;
-+ int request_private_bits;
-+ struct msi_msg msg;
-+ u16 search_mask;
-+ struct ifx_pci_controller *ctrl = pdev->bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s %s enter\n", __func__, pci_name(pdev));
-+
-+ /* XXX, skip RC MSI itself */
-+ if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s RC itself doesn't use MSI interrupt\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ /*
-+ * Read the MSI config to figure out how many IRQs this device
-+ * wants. Most devices only want 1, which will give
-+ * configured_private_bits and request_private_bits equal 0.
-+ */
-+ pci_read_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &control);
-+
-+ /*
-+ * If the number of private bits has been configured then use
-+ * that value instead of the requested number. This gives the
-+ * driver the chance to override the number of interrupts
-+ * before calling pci_enable_msi().
-+ */
-+ configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
-+ if (configured_private_bits == 0) {
-+ /* Nothing is configured, so use the hardware requested size */
-+ request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
-+ }
-+ else {
-+ /*
-+ * Use the number of configured bits, assuming the
-+ * driver wanted to override the hardware request
-+ * value.
-+ */
-+ request_private_bits = configured_private_bits;
-+ }
-+
-+ /*
-+ * The PCI 2.3 spec mandates that there are at most 32
-+ * interrupts. If this device asks for more, only give it one.
-+ */
-+ if (request_private_bits > 5) {
-+ request_private_bits = 0;
-+ }
-+again:
-+ /*
-+ * The IRQs have to be aligned on a power of two based on the
-+ * number being requested.
-+ */
-+ irq_step = (1 << request_private_bits);
-+
-+ /* Mask with one bit for each IRQ */
-+ search_mask = (1 << irq_step) - 1;
-+
-+ /*
-+ * We're going to search msi_free_irq_bitmask_lock for zero
-+ * bits. This represents an MSI interrupt number that isn't in
-+ * use.
-+ */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos += irq_step) {
-+ if ((msi_irqs[pcie_port].msi_free_irq_bitmask & (search_mask << pos)) == 0) {
-+ msi_irqs[pcie_port].msi_free_irq_bitmask |= search_mask << pos;
-+ msi_irqs[pcie_port].msi_multiple_irq_bitmask |= (search_mask >> 1) << pos;
-+ break;
-+ }
-+ }
-+ spin_unlock(&ifx_pcie_msi_lock);
-+
-+ /* Make sure the search for available interrupts didn't fail */
-+ if (pos >= IFX_MSI_IRQ_NUM) {
-+ if (request_private_bits) {
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s: Unable to find %d free "
-+ "interrupts, trying just one", __func__, 1 << request_private_bits);
-+ request_private_bits = 0;
-+ goto again;
-+ }
-+ else {
-+ printk(KERN_ERR "%s: Unable to find a free MSI interrupt\n", __func__);
-+ return -EINVAL;
-+ }
-+ }
-+ irq = msi_irqs[pcie_port].msi_irq_idx[pos].irq;
-+ irq_idx = msi_irqs[pcie_port].msi_irq_idx[pos].idx;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "pos %d, irq %d irq_idx %d\n", pos, irq, irq_idx);
-+
-+ /*
-+ * Initialize MSI. This has to match the memory-write endianess from the device
-+ * Address bits [23:12]
-+ */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] = SM(irq_idx, IFX_MSI_PIC_INT_LINE) |
-+ SM((msi_irqs[pcie_port].msi_phy_base >> 12), IFX_MSI_PIC_MSG_ADDR) |
-+ SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
-+
-+ /* Enable this entry */
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~IFX_MSI_PCI_INT_DISABLE;
-+ spin_unlock(&ifx_pcie_msi_lock);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "pic_table[%d]: 0x%08x\n",
-+ pos, msi_irqs[pcie_port].msi_pic_p->pic_table[pos]);
-+
-+ /* Update the number of IRQs the device has available to it */
-+ control &= ~PCI_MSI_FLAGS_QSIZE;
-+ control |= (request_private_bits << 4);
-+ pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control);
-+
-+ set_irq_msi(irq, desc);
-+ msg.address_hi = 0x0;
-+ msg.address_lo = msi_irqs[pcie_port].msi_phy_base;
-+ msg.data = SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "msi_data: pos %d 0x%08x\n", pos, msg.data);
-+
-+ write_msi_msg(irq, &msg);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
-+ return 0;
-+}
-+
-+static int
-+pcie_msi_irq_to_port(unsigned int irq, int *port)
-+{
-+ int ret = 0;
-+
-+ if (irq == IFX_PCIE_MSI_IR0 || irq == IFX_PCIE_MSI_IR1 ||
-+ irq == IFX_PCIE_MSI_IR2 || irq == IFX_PCIE_MSI_IR3) {
-+ *port = IFX_PCIE_PORT0;
-+ }
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ else if (irq == IFX_PCIE1_MSI_IR0 || irq == IFX_PCIE1_MSI_IR1 ||
-+ irq == IFX_PCIE1_MSI_IR2 || irq == IFX_PCIE1_MSI_IR3) {
-+ *port = IFX_PCIE_PORT1;
-+ }
-+#endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+ else {
-+ printk(KERN_ERR "%s: Attempted to teardown illegal "
-+ "MSI interrupt (%d)\n", __func__, irq);
-+ ret = -EINVAL;
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * \fn void arch_teardown_msi_irq(unsigned int irq)
-+ * \brief Called when a device no longer needs its MSI interrupts. All
-+ * MSI interrupts for the device are freed.
-+ *
-+ * \param irq The devices first irq number. There may be multple in sequence.
-+ * \return none
-+ * \ingroup IFX_PCIE_MSI
-+ */
-+void
-+arch_teardown_msi_irq(unsigned int irq)
-+{
-+ int pos;
-+ int number_irqs;
-+ u16 bitmask;
-+ int pcie_port;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s enter\n", __func__);
-+
-+ BUG_ON(irq > INT_NUM_IM4_IRL31);
-+
-+ if (pcie_msi_irq_to_port(irq, &pcie_port) != 0) {
-+ return;
-+ }
-+
-+ /* Shift the mask to the correct bit location, not always correct
-+ * Probally, the first match will be chosen.
-+ */
-+ for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos++) {
-+ if ((msi_irqs[pcie_port].msi_irq_idx[pos].irq == irq)
-+ && (msi_irqs[pcie_port].msi_free_irq_bitmask & ( 1 << pos))) {
-+ break;
-+ }
-+ }
-+ if (pos >= IFX_MSI_IRQ_NUM) {
-+ printk(KERN_ERR "%s: Unable to find a matched MSI interrupt\n", __func__);
-+ return;
-+ }
-+ spin_lock(&ifx_pcie_msi_lock);
-+ /* Disable this entry */
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] |= IFX_MSI_PCI_INT_DISABLE;
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~(IFX_MSI_PIC_INT_LINE | IFX_MSI_PIC_MSG_ADDR | IFX_MSI_PIC_MSG_DATA);
-+ spin_unlock(&ifx_pcie_msi_lock);
-+ /*
-+ * Count the number of IRQs we need to free by looking at the
-+ * msi_multiple_irq_bitmask. Each bit set means that the next
-+ * IRQ is also owned by this device.
-+ */
-+ number_irqs = 0;
-+ while (((pos + number_irqs) < IFX_MSI_IRQ_NUM) &&
-+ (msi_irqs[pcie_port].msi_multiple_irq_bitmask & (1 << (pos + number_irqs)))) {
-+ number_irqs++;
-+ }
-+ number_irqs++;
-+
-+ /* Mask with one bit for each IRQ */
-+ bitmask = (1 << number_irqs) - 1;
-+
-+ bitmask <<= pos;
-+ if ((msi_irqs[pcie_port].msi_free_irq_bitmask & bitmask) != bitmask) {
-+ printk(KERN_ERR "%s: Attempted to teardown MSI "
-+ "interrupt (%d) not in use\n", __func__, irq);
-+ return;
-+ }
-+ /* Checks are done, update the in use bitmask */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_free_irq_bitmask &= ~bitmask;
-+ msi_irqs[pcie_port].msi_multiple_irq_bitmask &= ~(bitmask >> 1);
-+ spin_unlock(&ifx_pcie_msi_lock);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
-+}
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
-+MODULE_DESCRIPTION("Infineon PCIe IP builtin MSI PIC driver");
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_phy.c
-@@ -0,0 +1,478 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_phy.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe PHY sub module
-+**
-+** DATE : 14 May 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 14 May,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_pcie_phy.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe PHY PLL register programming source file
-+*/
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/paccess.h>
-+#include <linux/delay.h>
-+
-+#include "ifxmips_pcie_reg.h"
-+#include "ifxmips_pcie.h"
-+
-+/* PCIe PDI only supports 16 bit operation */
-+
-+#define IFX_PCIE_PHY_REG_WRITE16(__addr, __data) \
-+ ((*(volatile u16 *) (__addr)) = (__data))
-+
-+#define IFX_PCIE_PHY_REG_READ16(__addr) \
-+ (*(volatile u16 *) (__addr))
-+
-+#define IFX_PCIE_PHY_REG16(__addr) \
-+ (*(volatile u16 *) (__addr))
-+
-+#define IFX_PCIE_PHY_REG(__reg, __value, __mask) do { \
-+ u16 read_data; \
-+ u16 write_data; \
-+ read_data = IFX_PCIE_PHY_REG_READ16((__reg)); \
-+ write_data = (read_data & ((u16)~(__mask))) | (((u16)(__value)) & ((u16)(__mask)));\
-+ IFX_PCIE_PHY_REG_WRITE16((__reg), write_data); \
-+} while (0)
-+
-+#define IFX_PCIE_PLL_TIMEOUT 1000 /* Tunnable */
-+
-+//#define IFX_PCI_PHY_REG_DUMP
-+
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+static void
-+pcie_phy_reg_dump(int pcie_port)
-+{
-+ printk("PLL REGFILE\n");
-+ printk("PCIE_PHY_PLL_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL4 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL4(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL5 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL5(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL6 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL6(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL7 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL7(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_PLL_STATUS 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)));
-+
-+ printk("TX1 REGFILE\n");
-+ printk("PCIE_PHY_TX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX1_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_TX1_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX1_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD1(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD2(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD3(pcie_port)));
-+
-+ printk("TX2 REGFILE\n");
-+ printk("PCIE_PHY_TX2_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX2_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX2_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX2_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD1(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD2(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD3(pcie_port)));
-+
-+ printk("RX1 REGFILE\n");
-+ printk("PCIE_PHY_RX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_RX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_RX1_CDR 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CDR(pcie_port)));
-+ printk("PCIE_PHY_RX1_EI 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_EI(pcie_port)));
-+ printk("PCIE_PHY_RX1_A_CTRL 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_A_CTRL(pcie_port)));
-+}
-+#endif /* IFX_PCI_PHY_REG_DUMP */
-+
-+static void
-+pcie_phy_comm_setup(int pcie_port)
-+{
-+ /* PLL Setting */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
-+
-+ /* increase the bias reference voltage */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
-+
-+ /* Endcnt */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
-+
-+ /* force */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
-+
-+ /* ctrl_lim */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
-+
-+ /* ctrl */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
-+
-+ /* RTERM*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
-+
-+ /* Improved 100MHz clock output */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
-+
-+ /* Reduced CDR BW to avoid glitches */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
-+}
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+static void
-+pcie_phy_36mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE
-+static void
-+pcie_phy_36mhz_ssc_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+
-+ /* PLL Setting */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
-+
-+ /* Increase the bias reference voltage */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
-+
-+ /* Endcnt */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
-+
-+ /* Force */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
-+
-+ /* Predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
-+
-+ /* ctrl_lim */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
-+
-+ /* ctrl */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
-+
-+ /* RTERM*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
-+
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0400, 0x0400);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0100);
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1c72, 0xFFFF);
-+
-+ /* improved 100MHz clock output */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
-+
-+ /* reduced CDR BW to avoid glitches */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_25MHZ_MODE
-+static void
-+pcie_phy_25mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0200);
-+
-+ /* en_ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0002, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0040, 0x0070);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x6000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x4000, 0x4000);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_25MHZ_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_100MHZ_MODE
-+static void
-+pcie_phy_100mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_100MHZ_MODE */
-+
-+static int
-+pcie_phy_wait_startup_ready(int pcie_port)
-+{
-+ int i;
-+
-+ for (i = 0; i < IFX_PCIE_PLL_TIMEOUT; i++) {
-+ if ((IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)) & 0x0040) != 0) {
-+ break;
-+ }
-+ udelay(10);
-+ }
-+ if (i >= IFX_PCIE_PLL_TIMEOUT) {
-+ printk(KERN_ERR "%s PLL Link timeout\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static void
-+pcie_phy_load_enable(int pcie_port, int slice)
-+{
-+ /* Set the load_en of tx/rx slice to '1' */
-+ switch (slice) {
-+ case 1:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0010, 0x0010);
-+ break;
-+ case 2:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0010, 0x0010);
-+ break;
-+ case 3:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0002, 0x0002);
-+ break;
-+ }
-+}
-+
-+static void
-+pcie_phy_load_disable(int pcie_port, int slice)
-+{
-+ /* set the load_en of tx/rx slice to '0' */
-+ switch (slice) {
-+ case 1:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0000, 0x0010);
-+ break;
-+ case 2:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0000, 0x0010);
-+ break;
-+ case 3:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0000, 0x0002);
-+ break;
-+ }
-+}
-+
-+static void
-+pcie_phy_load_war(int pcie_port)
-+{
-+ int slice;
-+
-+ for (slice = 1; slice < 4; slice++) {
-+ pcie_phy_load_enable(pcie_port, slice);
-+ udelay(1);
-+ pcie_phy_load_disable(pcie_port, slice);
-+ }
-+}
-+
-+static void
-+pcie_phy_tx2_modulation(int pcie_port)
-+{
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD1(pcie_port), 0x1FFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD2(pcie_port), 0xFFFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0601, 0xFFFF);
-+ mdelay(1);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0001, 0xFFFF);
-+}
-+
-+static void
-+pcie_phy_tx1_modulation(int pcie_port)
-+{
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD1(pcie_port), 0x1FFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD2(pcie_port), 0xFFFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0601, 0xFFFF);
-+ mdelay(1);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0001, 0xFFFF);
-+}
-+
-+static void
-+pcie_phy_tx_modulation_war(int pcie_port)
-+{
-+ int i;
-+
-+#define PCIE_PHY_MODULATION_NUM 5
-+ for (i = 0; i < PCIE_PHY_MODULATION_NUM; i++) {
-+ pcie_phy_tx2_modulation(pcie_port);
-+ pcie_phy_tx1_modulation(pcie_port);
-+ }
-+#undef PCIE_PHY_MODULATION_NUM
-+}
-+
-+void
-+pcie_phy_clock_mode_setup(int pcie_port)
-+{
-+ pcie_pdi_big_endian(pcie_port);
-+
-+ /* Enable PDI to access PCIe PHY register */
-+ pcie_pdi_pmu_enable(pcie_port);
-+
-+ /* Configure PLL and PHY clock */
-+ pcie_phy_comm_setup(pcie_port);
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+ pcie_phy_36mhz_mode_setup(pcie_port);
-+#elif defined(CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE)
-+ pcie_phy_36mhz_ssc_mode_setup(pcie_port);
-+#elif defined(CONFIG_IFX_PCIE_PHY_25MHZ_MODE)
-+ pcie_phy_25mhz_mode_setup(pcie_port);
-+#elif defined (CONFIG_IFX_PCIE_PHY_100MHZ_MODE)
-+ pcie_phy_100mhz_mode_setup(pcie_port);
-+#else
-+ #error "PCIE PHY Clock Mode must be chosen first!!!!"
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
-+
-+ /* Enable PCIe PHY and make PLL setting take effect */
-+ pcie_phy_pmu_enable(pcie_port);
-+
-+ /* Check if we are in startup_ready status */
-+ pcie_phy_wait_startup_ready(pcie_port);
-+
-+ pcie_phy_load_war(pcie_port);
-+
-+ /* Apply TX modulation workarounds */
-+ pcie_phy_tx_modulation_war(pcie_port);
-+
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Modified PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+}
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_pm.c
-@@ -0,0 +1,176 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_pm.c
-+** PROJECT : IFX UEIP
-+** MODULES : PCIE Root Complex Driver
-+**
-+** DATE : 21 Dec 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIE Root Complex Driver Power Managment
-+** COPYRIGHT : Copyright (c) 2009
-+** Lantiq Deutschland GmbH
-+** Am Campeon 3, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 21 Dec,2009 Lei Chuanhua First UEIP release
-+*******************************************************************************/
-+/*!
-+ \defgroup IFX_PCIE_PM Power Management functions
-+ \ingroup IFX_PCIE
-+ \brief IFX PCIE Root Complex Driver power management functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie_pm.c
-+ \ingroup IFX_PCIE
-+ \brief source file for PCIE Root Complex Driver Power Management
-+*/
-+
-+#ifndef EXPORT_SYMTAB
-+#define EXPORT_SYMTAB
-+#endif
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/system.h>
-+
-+/* Project header */
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_regs.h>
-+#include <asm/ifx/common_routines.h>
-+#include <asm/ifx/ifx_pmcu.h>
-+#include "ifxmips_pcie_pm.h"
-+
-+/**
-+ * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
-+ * \brief the callback function to request pmcu state in the power management hardware-dependent module
-+ *
-+ * \param pmcuState This parameter is a PMCU state.
-+ *
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
-+{
-+ switch(pmcuState)
-+ {
-+ case IFX_PMCU_STATE_D0:
-+ return IFX_PMCU_RETURN_SUCCESS;
-+ case IFX_PMCU_STATE_D1: // Not Applicable
-+ return IFX_PMCU_RETURN_DENIED;
-+ case IFX_PMCU_STATE_D2: // Not Applicable
-+ return IFX_PMCU_RETURN_DENIED;
-+ case IFX_PMCU_STATE_D3: // Module clock gating and Power gating
-+ return IFX_PMCU_RETURN_SUCCESS;
-+ default:
-+ return IFX_PMCU_RETURN_DENIED;
-+ }
-+}
-+
-+/**
-+ * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
-+ * \brief the callback function to get pmcu state in the power management hardware-dependent module
-+
-+ * \param pmcuState Pointer to return power state.
-+ *
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+ * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
-+ *
-+ * \param pmcuModule Module
-+ * \param newState New state
-+ * \param oldState Old state
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+ * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
-+ *
-+ * \param pmcuModule Module
-+ * \param newState New state
-+ * \param oldState Old state
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn static void ifx_pcie_pmcu_init(void)
-+ * \brief Register with central PMCU module
-+ * \return none
-+ * \ingroup IFX_PCIE_PM
-+ */
-+void
-+ifx_pcie_pmcu_init(void)
-+{
-+ IFX_PMCU_REGISTER_t pmcuRegister;
-+
-+ /* XXX, hook driver context */
-+
-+ /* State function register */
-+ memset(&pmcuRegister, 0, sizeof(IFX_PMCU_REGISTER_t));
-+ pmcuRegister.pmcuModule = IFX_PMCU_MODULE_PCIE;
-+ pmcuRegister.pmcuModuleNr = 0;
-+ pmcuRegister.ifx_pmcu_state_change = ifx_pcie_pmcu_state_change;
-+ pmcuRegister.ifx_pmcu_state_get = ifx_pcie_pmcu_state_get;
-+ pmcuRegister.pre = ifx_pcie_pmcu_prechange;
-+ pmcuRegister.post= ifx_pcie_pmcu_postchange;
-+ ifx_pmcu_register(&pmcuRegister);
-+}
-+
-+/**
-+ * \fn static void ifx_pcie_pmcu_exit(void)
-+ * \brief Unregister with central PMCU module
-+ *
-+ * \return none
-+ * \ingroup IFX_PCIE_PM
-+ */
-+void
-+ifx_pcie_pmcu_exit(void)
-+{
-+ IFX_PMCU_REGISTER_t pmcuUnRegister;
-+
-+ /* XXX, hook driver context */
-+
-+ pmcuUnRegister.pmcuModule = IFX_PMCU_MODULE_PCIE;
-+ pmcuUnRegister.pmcuModuleNr = 0;
-+ ifx_pmcu_unregister(&pmcuUnRegister);
-+}
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_pm.h
-@@ -0,0 +1,36 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_pm.h
-+** PROJECT : IFX UEIP
-+** MODULES : PCIe Root Complex Driver
-+**
-+** DATE : 21 Dec 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver Power Managment
-+** COPYRIGHT : Copyright (c) 2009
-+** Lantiq Deutschland GmbH
-+** Am Campeon 3, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 21 Dec,2009 Lei Chuanhua First UEIP release
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_pcie_pm.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe Root Complex Driver Power Management
-+*/
-+
-+#ifndef IFXMIPS_PCIE_PM_H
-+#define IFXMIPS_PCIE_PM_H
-+
-+void ifx_pcie_pmcu_init(void);
-+void ifx_pcie_pmcu_exit(void);
-+
-+#endif /* IFXMIPS_PCIE_PM_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_reg.h
-@@ -0,0 +1,1001 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_reg.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_REG_H
-+#define IFXMIPS_PCIE_REG_H
-+/*!
-+ \file ifxmips_pcie_reg.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module register definition
-+*/
-+/* PCIe Address Mapping Base */
-+#define PCIE_CFG_PHY_BASE 0x1D000000UL
-+#define PCIE_CFG_BASE (KSEG1 + PCIE_CFG_PHY_BASE)
-+#define PCIE_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE_MEM_PHY_BASE 0x1C000000UL
-+#define PCIE_MEM_BASE (KSEG1 + PCIE_MEM_PHY_BASE)
-+#define PCIE_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE_MEM_PHY_END (PCIE_MEM_PHY_BASE + PCIE_MEM_SIZE - 1)
-+
-+#define PCIE_IO_PHY_BASE 0x1D800000UL
-+#define PCIE_IO_BASE (KSEG1 + PCIE_IO_PHY_BASE)
-+#define PCIE_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE_IO_PHY_END (PCIE_IO_PHY_BASE + PCIE_IO_SIZE - 1)
-+
-+#define PCIE_RC_CFG_BASE (KSEG1 + 0x1D900000)
-+#define PCIE_APP_LOGIC_REG (KSEG1 + 0x1E100900)
-+#define PCIE_MSI_PHY_BASE 0x1F600000UL
-+
-+#define PCIE_PDI_PHY_BASE 0x1F106800UL
-+#define PCIE_PDI_BASE (KSEG1 + PCIE_PDI_PHY_BASE)
-+#define PCIE_PDI_SIZE 0x400
-+
-+#define PCIE1_CFG_PHY_BASE 0x19000000UL
-+#define PCIE1_CFG_BASE (KSEG1 + PCIE1_CFG_PHY_BASE)
-+#define PCIE1_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE1_MEM_PHY_BASE 0x18000000UL
-+#define PCIE1_MEM_BASE (KSEG1 + PCIE1_MEM_PHY_BASE)
-+#define PCIE1_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE1_MEM_PHY_END (PCIE1_MEM_PHY_BASE + PCIE1_MEM_SIZE - 1)
-+
-+#define PCIE1_IO_PHY_BASE 0x19800000UL
-+#define PCIE1_IO_BASE (KSEG1 + PCIE1_IO_PHY_BASE)
-+#define PCIE1_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE1_IO_PHY_END (PCIE1_IO_PHY_BASE + PCIE1_IO_SIZE - 1)
-+
-+#define PCIE1_RC_CFG_BASE (KSEG1 + 0x19900000)
-+#define PCIE1_APP_LOGIC_REG (KSEG1 + 0x1E100700)
-+#define PCIE1_MSI_PHY_BASE 0x1F400000UL
-+
-+#define PCIE1_PDI_PHY_BASE 0x1F700400UL
-+#define PCIE1_PDI_BASE (KSEG1 + PCIE1_PDI_PHY_BASE)
-+#define PCIE1_PDI_SIZE 0x400
-+
-+#define PCIE_CFG_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_CFG_BASE) : (PCIE_CFG_BASE))
-+#define PCIE_MEM_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_BASE) : (PCIE_MEM_BASE))
-+#define PCIE_IO_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_BASE) : (PCIE_IO_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_PHY_BASE) : (PCIE_MEM_PHY_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_MEM_PHY_END) : (PCIE_MEM_PHY_END))
-+#define PCIE_IO_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_PHY_BASE) : (PCIE_IO_PHY_BASE))
-+#define PCIE_IO_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_IO_PHY_END) : (PCIE_IO_PHY_END))
-+#define PCIE_APP_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_APP_LOGIC_REG) : (PCIE_APP_LOGIC_REG))
-+#define PCIE_RC_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_RC_CFG_BASE) : (PCIE_RC_CFG_BASE))
-+#define PCIE_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_PDI_BASE) : (PCIE_PDI_BASE))
-+
-+/* PCIe Application Logic Register */
-+/* RC Core Control Register */
-+#define PCIE_RC_CCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x10)
-+/* This should be enabled after initializing configuratin registers
-+ * Also should check link status retraining bit
-+ */
-+#define PCIE_RC_CCR_LTSSM_ENABLE 0x00000001 /* Enable LTSSM to continue link establishment */
-+
-+/* RC Core Debug Register */
-+#define PCIE_RC_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x14)
-+#define PCIE_RC_DR_DLL_UP 0x00000001 /* Data Link Layer Up */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE 0x0000000E /* Current Power State */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE_S 1
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE 0x000001F0 /* Current LTSSM State */
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE_S 4
-+
-+#define PCIE_RC_DR_PM_DEV_STATE 0x00000E00 /* Power Management D-State */
-+#define PCIE_RC_DR_PM_DEV_STATE_S 9
-+
-+#define PCIE_RC_DR_PM_ENABLED 0x00001000 /* Power Management State from PMU */
-+#define PCIE_RC_DR_PME_EVENT_ENABLED 0x00002000 /* Power Management Event Enable State */
-+#define PCIE_RC_DR_AUX_POWER_ENABLED 0x00004000 /* Auxiliary Power Enable */
-+
-+/* Current Power State Definition */
-+enum {
-+ PCIE_RC_DR_D0 = 0,
-+ PCIE_RC_DR_D1, /* Not supported */
-+ PCIE_RC_DR_D2, /* Not supported */
-+ PCIE_RC_DR_D3,
-+ PCIE_RC_DR_UN,
-+};
-+
-+/* PHY Link Status Register */
-+#define PCIE_PHY_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x18)
-+#define PCIE_PHY_SR_PHY_LINK_UP 0x00000001 /* PHY Link Up/Down Indicator */
-+
-+/* Electromechanical Control Register */
-+#define PCIE_EM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x1C)
-+#define PCIE_EM_CR_CARD_IS_PRESENT 0x00000001 /* Card Presence Detect State */
-+#define PCIE_EM_CR_MRL_OPEN 0x00000002 /* MRL Sensor State */
-+#define PCIE_EM_CR_POWER_FAULT_SET 0x00000004 /* Power Fault Detected */
-+#define PCIE_EM_CR_MRL_SENSOR_SET 0x00000008 /* MRL Sensor Changed */
-+#define PCIE_EM_CR_PRESENT_DETECT_SET 0x00000010 /* Card Presense Detect Changed */
-+#define PCIE_EM_CR_CMD_CPL_INT_SET 0x00000020 /* Command Complete Interrupt */
-+#define PCIE_EM_CR_SYS_INTERLOCK_SET 0x00000040 /* System Electromechanical IterLock Engaged */
-+#define PCIE_EM_CR_ATTENTION_BUTTON_SET 0x00000080 /* Attention Button Pressed */
-+
-+/* Interrupt Status Register */
-+#define PCIE_IR_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x20)
-+#define PCIE_IR_SR_PME_CAUSE_MSI 0x00000002 /* MSI caused by PME */
-+#define PCIE_IR_SR_HP_PME_WAKE_GEN 0x00000004 /* Hotplug PME Wake Generation */
-+#define PCIE_IR_SR_HP_MSI 0x00000008 /* Hotplug MSI */
-+#define PCIE_IR_SR_AHB_LU_ERR 0x00000030 /* AHB Bridge Lookup Error Signals */
-+#define PCIE_IR_SR_AHB_LU_ERR_S 4
-+#define PCIE_IR_SR_INT_MSG_NUM 0x00003E00 /* Interrupt Message Number */
-+#define PCIE_IR_SR_INT_MSG_NUM_S 9
-+#define PCIE_IR_SR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_IR_SR_AER_INT_MSG_NUM_S 27
-+
-+/* Message Control Register */
-+#define PCIE_MSG_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x30)
-+#define PCIE_MSG_CR_GEN_PME_TURN_OFF_MSG 0x00000001 /* Generate PME Turn Off Message */
-+#define PCIE_MSG_CR_GEN_UNLOCK_MSG 0x00000002 /* Generate Unlock Message */
-+
-+#define PCIE_VDM_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x34)
-+
-+/* Vendor-Defined Message Requester ID Register */
-+#define PCIE_VDM_RID(X) (PCIE_APP_PORT_TO_BASE (X) + 0x38)
-+#define PCIE_VDM_RID_VENROR_MSG_REQ_ID 0x0000FFFF
-+#define PCIE_VDM_RID_VDMRID_S 0
-+
-+/* ASPM Control Register */
-+#define PCIE_ASPM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x40)
-+#define PCIE_ASPM_CR_HOT_RST 0x00000001 /* Hot Reset Request to the downstream device */
-+#define PCIE_ASPM_CR_REQ_EXIT_L1 0x00000002 /* Request to Exit L1 */
-+#define PCIE_ASPM_CR_REQ_ENTER_L1 0x00000004 /* Request to Enter L1 */
-+
-+/* Vendor Message DW0 Register */
-+#define PCIE_VM_MSG_DW0(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x50)
-+#define PCIE_VM_MSG_DW0_TYPE 0x0000001F /* Message type */
-+#define PCIE_VM_MSG_DW0_TYPE_S 0
-+#define PCIE_VM_MSG_DW0_FORMAT 0x00000060 /* Format */
-+#define PCIE_VM_MSG_DW0_FORMAT_S 5
-+#define PCIE_VM_MSG_DW0_TC 0x00007000 /* Traffic Class */
-+#define PCIE_VM_MSG_DW0_TC_S 12
-+#define PCIE_VM_MSG_DW0_ATTR 0x000C0000 /* Atrributes */
-+#define PCIE_VM_MSG_DW0_ATTR_S 18
-+#define PCIE_VM_MSG_DW0_EP_TLP 0x00100000 /* Poisoned TLP */
-+#define PCIE_VM_MSG_DW0_TD 0x00200000 /* TLP Digest */
-+#define PCIE_VM_MSG_DW0_LEN 0xFFC00000 /* Length */
-+#define PCIE_VM_MSG_DW0_LEN_S 22
-+
-+/* Format Definition */
-+enum {
-+ PCIE_VM_MSG_FORMAT_00 = 0, /* 3DW Hdr, no data*/
-+ PCIE_VM_MSG_FORMAT_01, /* 4DW Hdr, no data */
-+ PCIE_VM_MSG_FORMAT_10, /* 3DW Hdr, with data */
-+ PCIE_VM_MSG_FORMAT_11, /* 4DW Hdr, with data */
-+};
-+
-+/* Traffic Class Definition */
-+enum {
-+ PCIE_VM_MSG_TC0 = 0,
-+ PCIE_VM_MSG_TC1,
-+ PCIE_VM_MSG_TC2,
-+ PCIE_VM_MSG_TC3,
-+ PCIE_VM_MSG_TC4,
-+ PCIE_VM_MSG_TC5,
-+ PCIE_VM_MSG_TC6,
-+ PCIE_VM_MSG_TC7,
-+};
-+
-+/* Attributes Definition */
-+enum {
-+ PCIE_VM_MSG_ATTR_00 = 0, /* RO and No Snoop cleared */
-+ PCIE_VM_MSG_ATTR_01, /* RO cleared , No Snoop set */
-+ PCIE_VM_MSG_ATTR_10, /* RO set, No Snoop cleared*/
-+ PCIE_VM_MSG_ATTR_11, /* RO and No Snoop set */
-+};
-+
-+/* Payload Size Definition */
-+#define PCIE_VM_MSG_LEN_MIN 0
-+#define PCIE_VM_MSG_LEN_MAX 1024
-+
-+/* Vendor Message DW1 Register */
-+#define PCIE_VM_MSG_DW1(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x54)
-+#define PCIE_VM_MSG_DW1_FUNC_NUM 0x00000070 /* Function Number */
-+#define PCIE_VM_MSG_DW1_FUNC_NUM_S 8
-+#define PCIE_VM_MSG_DW1_CODE 0x00FF0000 /* Message Code */
-+#define PCIE_VM_MSG_DW1_CODE_S 16
-+#define PCIE_VM_MSG_DW1_TAG 0xFF000000 /* Tag */
-+#define PCIE_VM_MSG_DW1_TAG_S 24
-+
-+#define PCIE_VM_MSG_DW2(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x58)
-+#define PCIE_VM_MSG_DW3(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x5C)
-+
-+/* Vendor Message Request Register */
-+#define PCIE_VM_MSG_REQR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x60)
-+#define PCIE_VM_MSG_REQR_REQ 0x00000001 /* Vendor Message Request */
-+
-+
-+/* AHB Slave Side Band Control Register */
-+#define PCIE_AHB_SSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x70)
-+#define PCIE_AHB_SSB_REQ_BCM 0x00000001 /* Slave Reques BCM filed */
-+#define PCIE_AHB_SSB_REQ_EP 0x00000002 /* Slave Reques EP filed */
-+#define PCIE_AHB_SSB_REQ_TD 0x00000004 /* Slave Reques TD filed */
-+#define PCIE_AHB_SSB_REQ_ATTR 0x00000018 /* Slave Reques Attribute number */
-+#define PCIE_AHB_SSB_REQ_ATTR_S 3
-+#define PCIE_AHB_SSB_REQ_TC 0x000000E0 /* Slave Request TC Field */
-+#define PCIE_AHB_SSB_REQ_TC_S 5
-+
-+/* AHB Master SideBand Ctrl Register */
-+#define PCIE_AHB_MSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x74)
-+#define PCIE_AHB_MSB_RESP_ATTR 0x00000003 /* Master Response Attribute number */
-+#define PCIE_AHB_MSB_RESP_ATTR_S 0
-+#define PCIE_AHB_MSB_RESP_BAD_EOT 0x00000004 /* Master Response Badeot filed */
-+#define PCIE_AHB_MSB_RESP_BCM 0x00000008 /* Master Response BCM filed */
-+#define PCIE_AHB_MSB_RESP_EP 0x00000010 /* Master Response EP filed */
-+#define PCIE_AHB_MSB_RESP_TD 0x00000020 /* Master Response TD filed */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM 0x000003C0 /* Master Response Function number */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM_S 6
-+
-+/* AHB Control Register, fixed bus enumeration exception */
-+#define PCIE_AHB_CTRL(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x78)
-+#define PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS 0x00000001
-+
-+/* Interrupt Enalbe Register */
-+#define PCIE_IRNEN(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF4)
-+#define PCIE_IRNCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF8)
-+#define PCIE_IRNICR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xFC)
-+
-+/* PCIe interrupt enable/control/capture register definition */
-+#define PCIE_IRN_AER_REPORT 0x00000001 /* AER Interrupt */
-+#define PCIE_IRN_AER_MSIX 0x00000002 /* Advanced Error MSI-X Interrupt */
-+#define PCIE_IRN_PME 0x00000004 /* PME Interrupt */
-+#define PCIE_IRN_HOTPLUG 0x00000008 /* Hotplug Interrupt */
-+#define PCIE_IRN_RX_VDM_MSG 0x00000010 /* Vendor-Defined Message Interrupt */
-+#define PCIE_IRN_RX_CORRECTABLE_ERR_MSG 0x00000020 /* Correctable Error Message Interrupt */
-+#define PCIE_IRN_RX_NON_FATAL_ERR_MSG 0x00000040 /* Non-fatal Error Message */
-+#define PCIE_IRN_RX_FATAL_ERR_MSG 0x00000080 /* Fatal Error Message */
-+#define PCIE_IRN_RX_PME_MSG 0x00000100 /* PME Message Interrupt */
-+#define PCIE_IRN_RX_PME_TURNOFF_ACK 0x00000200 /* PME Turnoff Ack Message Interrupt */
-+#define PCIE_IRN_AHB_BR_FATAL_ERR 0x00000400 /* AHB Fatal Error Interrupt */
-+#define PCIE_IRN_LINK_AUTO_BW_STATUS 0x00000800 /* Link Auto Bandwidth Status Interrupt */
-+#define PCIE_IRN_BW_MGT 0x00001000 /* Bandwidth Managment Interrupt */
-+#define PCIE_IRN_INTA 0x00002000 /* INTA */
-+#define PCIE_IRN_INTB 0x00004000 /* INTB */
-+#define PCIE_IRN_INTC 0x00008000 /* INTC */
-+#define PCIE_IRN_INTD 0x00010000 /* INTD */
-+#define PCIE_IRN_WAKEUP 0x00020000 /* Wake up Interrupt */
-+
-+#define PCIE_RC_CORE_COMBINED_INT (PCIE_IRN_AER_REPORT | PCIE_IRN_AER_MSIX | PCIE_IRN_PME | \
-+ PCIE_IRN_HOTPLUG | PCIE_IRN_RX_VDM_MSG | PCIE_IRN_RX_CORRECTABLE_ERR_MSG |\
-+ PCIE_IRN_RX_NON_FATAL_ERR_MSG | PCIE_IRN_RX_FATAL_ERR_MSG | \
-+ PCIE_IRN_RX_PME_MSG | PCIE_IRN_RX_PME_TURNOFF_ACK | PCIE_IRN_AHB_BR_FATAL_ERR | \
-+ PCIE_IRN_LINK_AUTO_BW_STATUS | PCIE_IRN_BW_MGT)
-+/* PCIe RC Configuration Register */
-+#define PCIE_VDID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x00)
-+
-+/* Bit definition from pci_reg.h */
-+#define PCIE_PCICMDSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x04)
-+#define PCIE_CCRID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x08)
-+#define PCIE_CLSLTHTBR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x0C) /* EP only */
-+/* BAR0, BAR1,Only necessary if the bridges implements a device-specific register set or memory buffer */
-+#define PCIE_BAR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10) /* Not used*/
-+#define PCIE_BAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14) /* Not used */
-+
-+#define PCIE_BNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x18) /* Mandatory */
-+/* Bus Number Register bits */
-+#define PCIE_BNR_PRIMARY_BUS_NUM 0x000000FF
-+#define PCIE_BNR_PRIMARY_BUS_NUM_S 0
-+#define PCIE_PNR_SECONDARY_BUS_NUM 0x0000FF00
-+#define PCIE_PNR_SECONDARY_BUS_NUM_S 8
-+#define PCIE_PNR_SUB_BUS_NUM 0x00FF0000
-+#define PCIE_PNR_SUB_BUS_NUM_S 16
-+
-+/* IO Base/Limit Register bits */
-+#define PCIE_IOBLSECS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x1C) /* RC only */
-+#define PCIE_IOBLSECS_32BIT_IO_ADDR 0x00000001
-+#define PCIE_IOBLSECS_IO_BASE_ADDR 0x000000F0
-+#define PCIE_IOBLSECS_IO_BASE_ADDR_S 4
-+#define PCIE_IOBLSECS_32BIT_IOLIMT 0x00000100
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR 0x0000F000
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR_S 12
-+
-+/* Non-prefetchable Memory Base/Limit Register bit */
-+#define PCIE_MBML(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x20) /* RC only */
-+#define PCIE_MBML_MEM_BASE_ADDR 0x0000FFF0
-+#define PCIE_MBML_MEM_BASE_ADDR_S 4
-+#define PCIE_MBML_MEM_LIMIT_ADDR 0xFFF00000
-+#define PCIE_MBML_MEM_LIMIT_ADDR_S 20
-+
-+/* Prefetchable Memory Base/Limit Register bit */
-+#define PCIE_PMBL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x24) /* RC only */
-+#define PCIE_PMBL_64BIT_ADDR 0x00000001
-+#define PCIE_PMBL_UPPER_12BIT 0x0000FFF0
-+#define PCIE_PMBL_UPPER_12BIT_S 4
-+#define PCIE_PMBL_E64MA 0x00010000
-+#define PCIE_PMBL_END_ADDR 0xFFF00000
-+#define PCIE_PMBL_END_ADDR_S 20
-+#define PCIE_PMBU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x28) /* RC only */
-+#define PCIE_PMLU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x2C) /* RC only */
-+
-+/* I/O Base/Limit Upper 16 bits register */
-+#define PCIE_IO_BANDL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x30) /* RC only */
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE 0x0000FFFF
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE_S 0
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT 0xFFFF0000
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT_S 16
-+
-+#define PCIE_CPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x34)
-+#define PCIE_EBBAR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x38)
-+
-+/* Interrupt and Secondary Bridge Control Register */
-+#define PCIE_INTRBCTRL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x3C)
-+
-+#define PCIE_INTRBCTRL_INT_LINE 0x000000FF
-+#define PCIE_INTRBCTRL_INT_LINE_S 0
-+#define PCIE_INTRBCTRL_INT_PIN 0x0000FF00
-+#define PCIE_INTRBCTRL_INT_PIN_S 8
-+#define PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE 0x00010000 /* #PERR */
-+#define PCIE_INTRBCTRL_SERR_ENABLE 0x00020000 /* #SERR */
-+#define PCIE_INTRBCTRL_ISA_ENABLE 0x00040000 /* ISA enable, IO 64KB only */
-+#define PCIE_INTRBCTRL_VGA_ENABLE 0x00080000 /* VGA enable */
-+#define PCIE_INTRBCTRL_VGA_16BIT_DECODE 0x00100000 /* VGA 16bit decode */
-+#define PCIE_INTRBCTRL_RST_SECONDARY_BUS 0x00400000 /* Secondary bus rest, hot rest, 1ms */
-+/* Others are read only */
-+enum {
-+ PCIE_INTRBCTRL_INT_NON = 0,
-+ PCIE_INTRBCTRL_INTA,
-+ PCIE_INTRBCTRL_INTB,
-+ PCIE_INTRBCTRL_INTC,
-+ PCIE_INTRBCTRL_INTD,
-+};
-+
-+#define PCIE_PM_CAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x40)
-+
-+/* Power Management Control and Status Register */
-+#define PCIE_PM_CSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x44)
-+
-+#define PCIE_PM_CSR_POWER_STATE 0x00000003 /* Power State */
-+#define PCIE_PM_CSR_POWER_STATE_S 0
-+#define PCIE_PM_CSR_SW_RST 0x00000008 /* Soft Reset Enabled */
-+#define PCIE_PM_CSR_PME_ENABLE 0x00000100 /* PME Enable */
-+#define PCIE_PM_CSR_PME_STATUS 0x00008000 /* PME status */
-+
-+/* MSI Capability Register for EP */
-+#define PCIE_MCAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x50)
-+
-+#define PCIE_MCAPR_MSI_CAP_ID 0x000000FF /* MSI Capability ID */
-+#define PCIE_MCAPR_MSI_CAP_ID_S 0
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR_S 8
-+#define PCIE_MCAPR_MSI_ENABLE 0x00010000 /* MSI Enable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP 0x000E0000 /* Multiple Message Capable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP_S 17
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE 0x00700000 /* Multiple Message Enable */
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE_S 20
-+#define PCIE_MCAPR_ADDR64_CAP 0X00800000 /* 64-bit Address Capable */
-+
-+/* MSI Message Address Register */
-+#define PCIE_MA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x54)
-+
-+#define PCIE_MA_ADDR_MASK 0xFFFFFFFC /* Message Address */
-+
-+/* MSI Message Upper Address Register */
-+#define PCIE_MUA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x58)
-+
-+/* MSI Message Data Register */
-+#define PCIE_MD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x5C)
-+
-+#define PCIE_MD_DATA 0x0000FFFF /* Message Data */
-+#define PCIE_MD_DATA_S 0
-+
-+/* PCI Express Capability Register */
-+#define PCIE_XCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70)
-+
-+#define PCIE_XCAP_ID 0x000000FF /* PCI Express Capability ID */
-+#define PCIE_XCAP_ID_S 0
-+#define PCIE_XCAP_NEXT_CAP 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_XCAP_NEXT_CAP_S 8
-+#define PCIE_XCAP_VER 0x000F0000 /* PCI Express Capability Version */
-+#define PCIE_XCAP_VER_S 16
-+#define PCIE_XCAP_DEV_PORT_TYPE 0x00F00000 /* Device Port Type */
-+#define PCIE_XCAP_DEV_PORT_TYPE_S 20
-+#define PCIE_XCAP_SLOT_IMPLEMENTED 0x01000000 /* Slot Implemented */
-+#define PCIE_XCAP_MSG_INT_NUM 0x3E000000 /* Interrupt Message Number */
-+#define PCIE_XCAP_MSG_INT_NUM_S 25
-+
-+/* Device Capability Register */
-+#define PCIE_DCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74)
-+
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE 0x00000007 /* Max Payload size */
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE_S 0
-+#define PCIE_DCAP_PHANTOM_FUNC 0x00000018 /* Phanton Function, not supported */
-+#define PCIE_DCAP_PHANTOM_FUNC_S 3
-+#define PCIE_DCAP_EXT_TAG 0x00000020 /* Extended Tag Field */
-+#define PCIE_DCAP_EP_L0S_LATENCY 0x000001C0 /* EP L0s latency only */
-+#define PCIE_DCAP_EP_L0S_LATENCY_S 6
-+#define PCIE_DCAP_EP_L1_LATENCY 0x00000E00 /* EP L1 latency only */
-+#define PCIE_DCAP_EP_L1_LATENCY_S 9
-+#define PCIE_DCAP_ROLE_BASE_ERR_REPORT 0x00008000 /* Role Based ERR */
-+
-+/* Maximum payload size supported */
-+enum {
-+ PCIE_MAX_PAYLOAD_128 = 0,
-+ PCIE_MAX_PAYLOAD_256,
-+ PCIE_MAX_PAYLOAD_512,
-+ PCIE_MAX_PAYLOAD_1024,
-+ PCIE_MAX_PAYLOAD_2048,
-+ PCIE_MAX_PAYLOAD_4096,
-+};
-+
-+/* Device Control and Status Register */
-+#define PCIE_DCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x78)
-+
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR_EN 0x00000001 /* COR-ERR */
-+#define PCIE_DCTLSTS_NONFATAL_ERR_EN 0x00000002 /* Non-fatal ERR */
-+#define PCIE_DCTLSTS_FATAL_ERR_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_DCTLSYS_UR_REQ_EN 0x00000008 /* UR ERR */
-+#define PCIE_DCTLSTS_RELAXED_ORDERING_EN 0x00000010 /* Enable relaxing ordering */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE 0x000000E0 /* Max payload mask */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE_S 5
-+#define PCIE_DCTLSTS_EXT_TAG_EN 0x00000100 /* Extended tag field */
-+#define PCIE_DCTLSTS_PHANTOM_FUNC_EN 0x00000200 /* Phantom Function Enable */
-+#define PCIE_DCTLSTS_AUX_PM_EN 0x00000400 /* AUX Power PM Enable */
-+#define PCIE_DCTLSTS_NO_SNOOP_EN 0x00000800 /* Enable no snoop, except root port*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE 0x00007000 /* Max Read Request size*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE_S 12
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR 0x00010000 /* COR-ERR Detected */
-+#define PCIE_DCTLSTS_NONFATAL_ERR 0x00020000 /* Non-Fatal ERR Detected */
-+#define PCIE_DCTLSTS_FATAL_ER 0x00040000 /* Fatal ERR Detected */
-+#define PCIE_DCTLSTS_UNSUPPORTED_REQ 0x00080000 /* UR Detected */
-+#define PCIE_DCTLSTS_AUX_POWER 0x00100000 /* Aux Power Detected */
-+#define PCIE_DCTLSTS_TRANSACT_PENDING 0x00200000 /* Transaction pending */
-+
-+#define PCIE_DCTLSTS_ERR_EN (PCIE_DCTLSTS_CORRECTABLE_ERR_EN | \
-+ PCIE_DCTLSTS_NONFATAL_ERR_EN | PCIE_DCTLSTS_FATAL_ERR_EN | \
-+ PCIE_DCTLSYS_UR_REQ_EN)
-+
-+/* Link Capability Register */
-+#define PCIE_LCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7C)
-+#define PCIE_LCAP_MAX_LINK_SPEED 0x0000000F /* Max link speed, 0x1 by default */
-+#define PCIE_LCAP_MAX_LINK_SPEED_S 0
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH 0x000003F0 /* Maxium Length Width */
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH_S 4
-+#define PCIE_LCAP_ASPM_LEVEL 0x00000C00 /* Active State Link PM Support */
-+#define PCIE_LCAP_ASPM_LEVEL_S 10
-+#define PCIE_LCAP_L0S_EIXT_LATENCY 0x00007000 /* L0s Exit Latency */
-+#define PCIE_LCAP_L0S_EIXT_LATENCY_S 12
-+#define PCIE_LCAP_L1_EXIT_LATENCY 0x00038000 /* L1 Exit Latency */
-+#define PCIE_LCAP_L1_EXIT_LATENCY_S 15
-+#define PCIE_LCAP_CLK_PM 0x00040000 /* Clock Power Management */
-+#define PCIE_LCAP_SDER 0x00080000 /* Surprise Down Error Reporting */
-+#define PCIE_LCAP_DLL_ACTIVE_REPROT 0x00100000 /* Data Link Layer Active Reporting Capable */
-+#define PCIE_LCAP_PORT_NUM 0xFF0000000 /* Port number */
-+#define PCIE_LCAP_PORT_NUM_S 24
-+
-+/* Maximum Length width definition */
-+#define PCIE_MAX_LENGTH_WIDTH_RES 0x00
-+#define PCIE_MAX_LENGTH_WIDTH_X1 0x01 /* Default */
-+#define PCIE_MAX_LENGTH_WIDTH_X2 0x02
-+#define PCIE_MAX_LENGTH_WIDTH_X4 0x04
-+#define PCIE_MAX_LENGTH_WIDTH_X8 0x08
-+#define PCIE_MAX_LENGTH_WIDTH_X12 0x0C
-+#define PCIE_MAX_LENGTH_WIDTH_X16 0x10
-+#define PCIE_MAX_LENGTH_WIDTH_X32 0x20
-+
-+/* Active State Link PM definition */
-+enum {
-+ PCIE_ASPM_RES0 = 0,
-+ PCIE_ASPM_L0S_ENTRY_SUPPORT, /* L0s */
-+ PCIE_ASPM_RES1,
-+ PCIE_ASPM_L0S_L1_ENTRY_SUPPORT, /* L0s and L1, default */
-+};
-+
-+/* L0s Exit Latency definition */
-+enum {
-+ PCIE_L0S_EIXT_LATENCY_L64NS = 0, /* < 64 ns */
-+ PCIE_L0S_EIXT_LATENCY_B64A128, /* > 64 ns < 128 ns */
-+ PCIE_L0S_EIXT_LATENCY_B128A256, /* > 128 ns < 256 ns */
-+ PCIE_L0S_EIXT_LATENCY_B256A512, /* > 256 ns < 512 ns */
-+ PCIE_L0S_EIXT_LATENCY_B512TO1U, /* > 512 ns < 1 us */
-+ PCIE_L0S_EIXT_LATENCY_B1A2U, /* > 1 us < 2 us */
-+ PCIE_L0S_EIXT_LATENCY_B2A4U, /* > 2 us < 4 us */
-+ PCIE_L0S_EIXT_LATENCY_M4US, /* > 4 us */
-+};
-+
-+/* L1 Exit Latency definition */
-+enum {
-+ PCIE_L1_EXIT_LATENCY_L1US = 0, /* < 1 us */
-+ PCIE_L1_EXIT_LATENCY_B1A2, /* > 1 us < 2 us */
-+ PCIE_L1_EXIT_LATENCY_B2A4, /* > 2 us < 4 us */
-+ PCIE_L1_EXIT_LATENCY_B4A8, /* > 4 us < 8 us */
-+ PCIE_L1_EXIT_LATENCY_B8A16, /* > 8 us < 16 us */
-+ PCIE_L1_EXIT_LATENCY_B16A32, /* > 16 us < 32 us */
-+ PCIE_L1_EXIT_LATENCY_B32A64, /* > 32 us < 64 us */
-+ PCIE_L1_EXIT_LATENCY_M64US, /* > 64 us */
-+};
-+
-+/* Link Control and Status Register */
-+#define PCIE_LCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x80)
-+#define PCIE_LCTLSTS_ASPM_ENABLE 0x00000003 /* Active State Link PM Control */
-+#define PCIE_LCTLSTS_ASPM_ENABLE_S 0
-+#define PCIE_LCTLSTS_RCB128 0x00000008 /* Read Completion Boundary 128*/
-+#define PCIE_LCTLSTS_LINK_DISABLE 0x00000010 /* Link Disable */
-+#define PCIE_LCTLSTS_RETRIAN_LINK 0x00000020 /* Retrain Link */
-+#define PCIE_LCTLSTS_COM_CLK_CFG 0x00000040 /* Common Clock Configuration */
-+#define PCIE_LCTLSTS_EXT_SYNC 0x00000080 /* Extended Synch */
-+#define PCIE_LCTLSTS_CLK_PM_EN 0x00000100 /* Enable Clock Powerm Management */
-+#define PCIE_LCTLSTS_LINK_SPEED 0x000F0000 /* Link Speed */
-+#define PCIE_LCTLSTS_LINK_SPEED_S 16
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH 0x03F00000 /* Negotiated Link Width */
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH_S 20
-+#define PCIE_LCTLSTS_RETRAIN_PENDING 0x08000000 /* Link training is ongoing */
-+#define PCIE_LCTLSTS_SLOT_CLK_CFG 0x10000000 /* Slot Clock Configuration */
-+#define PCIE_LCTLSTS_DLL_ACTIVE 0x20000000 /* Data Link Layer Active */
-+
-+/* Slot Capabilities Register */
-+#define PCIE_SLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x84)
-+
-+/* Slot Capabilities */
-+#define PCIE_SLCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x88)
-+
-+/* Root Control and Capability Register */
-+#define PCIE_RCTLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x8C)
-+#define PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR 0x00000001 /* #SERR on COR-ERR */
-+#define PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR 0x00000002 /* #SERR on Non-Fatal ERR */
-+#define PCIE_RCTLCAP_SERR_ON_FATAL_ERR 0x00000004 /* #SERR on Fatal ERR */
-+#define PCIE_RCTLCAP_PME_INT_EN 0x00000008 /* PME Interrupt Enable */
-+#define PCIE_RCTLCAP_SERR_ENABLE (PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR | \
-+ PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR | PCIE_RCTLCAP_SERR_ON_FATAL_ERR)
-+/* Root Status Register */
-+#define PCIE_RSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x90)
-+#define PCIE_RSTS_PME_REQ_ID 0x0000FFFF /* PME Request ID */
-+#define PCIE_RSTS_PME_REQ_ID_S 0
-+#define PCIE_RSTS_PME_STATUS 0x00010000 /* PME Status */
-+#define PCIE_RSTS_PME_PENDING 0x00020000 /* PME Pending */
-+
-+/* PCI Express Enhanced Capability Header */
-+#define PCIE_ENHANCED_CAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x100)
-+#define PCIE_ENHANCED_CAP_ID 0x0000FFFF /* PCI Express Extended Capability ID */
-+#define PCIE_ENHANCED_CAP_ID_S 0
-+#define PCIE_ENHANCED_CAP_VER 0x000F0000 /* Capability Version */
-+#define PCIE_ENHANCED_CAP_VER_S 16
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET 0xFFF00000 /* Next Capability Offset */
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET_S 20
-+
-+/* Uncorrectable Error Status Register */
-+#define PCIE_UES_R(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x104)
-+#define PCIE_DATA_LINK_PROTOCOL_ERR 0x00000010 /* Data Link Protocol Error Status */
-+#define PCIE_SURPRISE_DOWN_ERROR 0x00000020 /* Surprise Down Error Status */
-+#define PCIE_POISONED_TLP 0x00001000 /* Poisoned TLP Status */
-+#define PCIE_FC_PROTOCOL_ERR 0x00002000 /* Flow Control Protocol Error Status */
-+#define PCIE_COMPLETION_TIMEOUT 0x00004000 /* Completion Timeout Status */
-+#define PCIE_COMPLETOR_ABORT 0x00008000 /* Completer Abort Error */
-+#define PCIE_UNEXPECTED_COMPLETION 0x00010000 /* Unexpected Completion Status */
-+#define PCIE_RECEIVER_OVERFLOW 0x00020000 /* Receive Overflow Status */
-+#define PCIE_MALFORNED_TLP 0x00040000 /* Malformed TLP Stauts */
-+#define PCIE_ECRC_ERR 0x00080000 /* ECRC Error Stauts */
-+#define PCIE_UR_REQ 0x00100000 /* Unsupported Request Error Status */
-+#define PCIE_ALL_UNCORRECTABLE_ERR (PCIE_DATA_LINK_PROTOCOL_ERR | PCIE_SURPRISE_DOWN_ERROR | \
-+ PCIE_POISONED_TLP | PCIE_FC_PROTOCOL_ERR | PCIE_COMPLETION_TIMEOUT | \
-+ PCIE_COMPLETOR_ABORT | PCIE_UNEXPECTED_COMPLETION | PCIE_RECEIVER_OVERFLOW |\
-+ PCIE_MALFORNED_TLP | PCIE_ECRC_ERR | PCIE_UR_REQ)
-+
-+/* Uncorrectable Error Mask Register, Mask means no report */
-+#define PCIE_UEMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x108)
-+
-+/* Uncorrectable Error Severity Register */
-+#define PCIE_UESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10C)
-+
-+/* Correctable Error Status Register */
-+#define PCIE_CESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x110)
-+#define PCIE_RX_ERR 0x00000001 /* Receive Error Status */
-+#define PCIE_BAD_TLP 0x00000040 /* Bad TLP Status */
-+#define PCIE_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-+#define PCIE_REPLAY_NUM_ROLLOVER 0x00000100 /* Replay Number Rollover Status */
-+#define PCIE_REPLAY_TIMER_TIMEOUT_ERR 0x00001000 /* Reply Timer Timeout Status */
-+#define PCIE_ADVISORY_NONFTAL_ERR 0x00002000 /* Advisory Non-Fatal Error Status */
-+#define PCIE_CORRECTABLE_ERR (PCIE_RX_ERR | PCIE_BAD_TLP | PCIE_BAD_DLLP | PCIE_REPLAY_NUM_ROLLOVER |\
-+ PCIE_REPLAY_TIMER_TIMEOUT_ERR | PCIE_ADVISORY_NONFTAL_ERR)
-+
-+/* Correctable Error Mask Register */
-+#define PCIE_CEMR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x114)
-+
-+/* Advanced Error Capabilities and Control Register */
-+#define PCIE_AECCR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x118)
-+#define PCIE_AECCR_FIRST_ERR_PTR 0x0000001F /* First Error Pointer */
-+#define PCIE_AECCR_FIRST_ERR_PTR_S 0
-+#define PCIE_AECCR_ECRC_GEN_CAP 0x00000020 /* ECRC Generation Capable */
-+#define PCIE_AECCR_ECRC_GEN_EN 0x00000040 /* ECRC Generation Enable */
-+#define PCIE_AECCR_ECRC_CHECK_CAP 0x00000080 /* ECRC Check Capable */
-+#define PCIE_AECCR_ECRC_CHECK_EN 0x00000100 /* ECRC Check Enable */
-+
-+/* Header Log Register 1 */
-+#define PCIE_HLR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x11C)
-+
-+/* Header Log Register 2 */
-+#define PCIE_HLR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x120)
-+
-+/* Header Log Register 3 */
-+#define PCIE_HLR3(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x124)
-+
-+/* Header Log Register 4 */
-+#define PCIE_HLR4(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x128)
-+
-+/* Root Error Command Register */
-+#define PCIE_RECR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x12C)
-+#define PCIE_RECR_CORRECTABLE_ERR_REPORT_EN 0x00000001 /* COR-ERR */
-+#define PCIE_RECR_NONFATAL_ERR_REPORT_EN 0x00000002 /* Non-Fatal ERR */
-+#define PCIE_RECR_FATAL_ERR_REPORT_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_RECR_ERR_REPORT_EN (PCIE_RECR_CORRECTABLE_ERR_REPORT_EN | \
-+ PCIE_RECR_NONFATAL_ERR_REPORT_EN | PCIE_RECR_FATAL_ERR_REPORT_EN)
-+
-+/* Root Error Status Register */
-+#define PCIE_RESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x130)
-+#define PCIE_RESR_CORRECTABLE_ERR 0x00000001 /* COR-ERR Receveid */
-+#define PCIE_RESR_MULTI_CORRECTABLE_ERR 0x00000002 /* Multiple COR-ERR Received */
-+#define PCIE_RESR_FATAL_NOFATAL_ERR 0x00000004 /* ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_MULTI_FATAL_NOFATAL_ERR 0x00000008 /* Multiple ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_FIRST_UNCORRECTABLE_FATAL_ERR 0x00000010 /* First UN-COR Fatal */
-+#define PCIR_RESR_NON_FATAL_ERR 0x00000020 /* Non-Fatal Error Message Received */
-+#define PCIE_RESR_FATAL_ERR 0x00000040 /* Fatal Message Received */
-+#define PCIE_RESR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_RESR_AER_INT_MSG_NUM_S 27
-+
-+/* Error Source Indentification Register */
-+#define PCIE_ESIR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x134)
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID 0x0000FFFF
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID_S 0
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID 0xFFFF0000
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID_S 16
-+
-+/* VC Enhanced Capability Header */
-+#define PCIE_VC_ECH(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x140)
-+
-+/* Port VC Capability Register */
-+#define PCIE_PVC1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x144)
-+#define PCIE_PVC1_EXT_VC_CNT 0x00000007 /* Extended VC Count */
-+#define PCIE_PVC1_EXT_VC_CNT_S 0
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT 0x00000070 /* Low Priority Extended VC Count */
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT_S 4
-+#define PCIE_PVC1_REF_CLK 0x00000300 /* Reference Clock */
-+#define PCIE_PVC1_REF_CLK_S 8
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE 0x00000C00 /* Port Arbitration Table Entry Size */
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE_S 10
-+
-+/* Extended Virtual Channel Count Defintion */
-+#define PCIE_EXT_VC_CNT_MIN 0
-+#define PCIE_EXT_VC_CNT_MAX 7
-+
-+/* Port Arbitration Table Entry Size Definition */
-+enum {
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S1BIT = 0,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S2BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S4BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S8BIT,
-+};
-+
-+/* Port VC Capability Register 2 */
-+#define PCIE_PVC2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x148)
-+#define PCIE_PVC2_VC_ARB_16P_FIXED_WRR 0x00000001 /* HW Fixed arbitration, 16 phase WRR */
-+#define PCIE_PVC2_VC_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_PVC2_VC_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_PVC2_VC_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_PVC2_VC_ARB_WRR 0x0000000F
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET 0xFF000000 /* VC arbitration table offset, not support */
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET_S 24
-+
-+/* Port VC Control and Status Register */
-+#define PCIE_PVCCRSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14C)
-+#define PCIE_PVCCRSR_LOAD_VC_ARB_TAB 0x00000001 /* Load VC Arbitration Table */
-+#define PCIE_PVCCRSR_VC_ARB_SEL 0x0000000E /* VC Arbitration Select */
-+#define PCIE_PVCCRSR_VC_ARB_SEL_S 1
-+#define PCIE_PVCCRSR_VC_ARB_TAB_STATUS 0x00010000 /* Arbitration Status */
-+
-+/* VC0 Resource Capability Register */
-+#define PCIE_VC0_RC(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x150)
-+#define PCIE_VC0_RC_PORT_ARB_HW_FIXED 0x00000001 /* HW Fixed arbitration */
-+#define PCIE_VC0_RC_PORT_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_128P_WRR 0x00000010 /* Time-based 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_256P_WRR 0x00000020 /* Time-based 256 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB (PCIE_VC0_RC_PORT_ARB_HW_FIXED | PCIE_VC0_RC_PORT_ARB_32P_WRR |\
-+ PCIE_VC0_RC_PORT_ARB_64P_WRR | PCIE_VC0_RC_PORT_ARB_128P_WRR | \
-+ PCIE_VC0_RC_PORT_ARB_TM_128P_WRR | PCIE_VC0_RC_PORT_ARB_TM_256P_WRR)
-+
-+#define PCIE_VC0_RC_REJECT_SNOOP 0x00008000 /* Reject Snoop Transactioin */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS 0x007F0000 /* Maximum time Slots */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS_S 16
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET 0xFF000000 /* Port Arbitration Table Offset */
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET_S 24
-+
-+/* VC0 Resource Control Register */
-+#define PCIE_VC0_RC0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x154)
-+#define PCIE_VC0_RC0_TVM0 0x00000001 /* TC0 and VC0 */
-+#define PCIE_VC0_RC0_TVM1 0x00000002 /* TC1 and VC1 */
-+#define PCIE_VC0_RC0_TVM2 0x00000004 /* TC2 and VC2 */
-+#define PCIE_VC0_RC0_TVM3 0x00000008 /* TC3 and VC3 */
-+#define PCIE_VC0_RC0_TVM4 0x00000010 /* TC4 and VC4 */
-+#define PCIE_VC0_RC0_TVM5 0x00000020 /* TC5 and VC5 */
-+#define PCIE_VC0_RC0_TVM6 0x00000040 /* TC6 and VC6 */
-+#define PCIE_VC0_RC0_TVM7 0x00000080 /* TC7 and VC7 */
-+#define PCIE_VC0_RC0_TC_VC 0x000000FF /* TC/VC mask */
-+
-+#define PCIE_VC0_RC0_LOAD_PORT_ARB_TAB 0x00010000 /* Load Port Arbitration Table */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL 0x000E0000 /* Port Arbitration Select */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL_S 17
-+#define PCIE_VC0_RC0_VC_ID 0x07000000 /* VC ID */
-+#define PCIE_VC0_RC0_VC_ID_S 24
-+#define PCIE_VC0_RC0_VC_EN 0x80000000 /* VC Enable */
-+
-+/* VC0 Resource Status Register */
-+#define PCIE_VC0_RSR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x158)
-+#define PCIE_VC0_RSR0_PORT_ARB_TAB_STATUS 0x00010000 /* Port Arbitration Table Status,not used */
-+#define PCIE_VC0_RSR0_VC_NEG_PENDING 0x00020000 /* VC Negotiation Pending */
-+
-+/* Ack Latency Timer and Replay Timer Register */
-+#define PCIE_ALTRT(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x700)
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT 0x0000FFFF /* Round Trip Latency Time Limit */
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT_S 0
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT 0xFFFF0000 /* Replay Time Limit */
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT_S 16
-+
-+/* Other Message Register */
-+#define PCIE_OMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x704)
-+
-+/* Port Force Link Register */
-+#define PCIE_PFLR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x708)
-+#define PCIE_PFLR_LINK_NUM 0x000000FF /* Link Number */
-+#define PCIE_PFLR_LINK_NUM_S 0
-+#define PCIE_PFLR_FORCE_LINK 0x00008000 /* Force link */
-+#define PCIE_PFLR_LINK_STATE 0x003F0000 /* Link State */
-+#define PCIE_PFLR_LINK_STATE_S 16
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT 0xFF000000 /* Low Power Entrance Count, only for EP */
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT_S 24
-+
-+/* Ack Frequency Register */
-+#define PCIE_AFR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70C)
-+#define PCIE_AFR_AF 0x000000FF /* Ack Frequency */
-+#define PCIE_AFR_AF_S 0
-+#define PCIE_AFR_FTS_NUM 0x0000FF00 /* The number of Fast Training Sequence from L0S to L0 */
-+#define PCIE_AFR_FTS_NUM_S 8
-+#define PCIE_AFR_COM_FTS_NUM 0x00FF0000 /* N_FTS; when common clock is used*/
-+#define PCIE_AFR_COM_FTS_NUM_S 16
-+#define PCIE_AFR_L0S_ENTRY_LATENCY 0x07000000 /* L0s Entrance Latency */
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_S 24
-+#define PCIE_AFR_L1_ENTRY_LATENCY 0x38000000 /* L1 Entrance Latency */
-+#define PCIE_AFR_L1_ENTRY_LATENCY_S 27
-+#define PCIE_AFR_FTS_NUM_DEFAULT 32
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT 7
-+#define PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT 5
-+
-+/* Port Link Control Register */
-+#define PCIE_PLCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x710)
-+#define PCIE_PLCR_OTHER_MSG_REQ 0x00000001 /* Other Message Request */
-+#define PCIE_PLCR_SCRAMBLE_DISABLE 0x00000002 /* Scramble Disable */
-+#define PCIE_PLCR_LOOPBACK_EN 0x00000004 /* Loopback Enable */
-+#define PCIE_PLCR_LTSSM_HOT_RST 0x00000008 /* Force LTSSM to the hot reset */
-+#define PCIE_PLCR_DLL_LINK_EN 0x00000020 /* Enable Link initialization */
-+#define PCIE_PLCR_FAST_LINK_SIM_EN 0x00000080 /* Sets all internal timers to fast mode for simulation purposes */
-+#define PCIE_PLCR_LINK_MODE 0x003F0000 /* Link Mode Enable Mask */
-+#define PCIE_PLCR_LINK_MODE_S 16
-+#define PCIE_PLCR_CORRUPTED_CRC_EN 0x02000000 /* Enabled Corrupt CRC */
-+
-+/* Lane Skew Register */
-+#define PCIE_LSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x714)
-+#define PCIE_LSR_LANE_SKEW_NUM 0x00FFFFFF /* Insert Lane Skew for Transmit, not applicable */
-+#define PCIE_LSR_LANE_SKEW_NUM_S 0
-+#define PCIE_LSR_FC_DISABLE 0x01000000 /* Disable of Flow Control */
-+#define PCIE_LSR_ACKNAK_DISABLE 0x02000000 /* Disable of Ack/Nak */
-+#define PCIE_LSR_LANE_DESKEW_DISABLE 0x80000000 /* Disable of Lane-to-Lane Skew */
-+
-+/* Symbol Number Register */
-+#define PCIE_SNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x718)
-+#define PCIE_SNR_TS 0x0000000F /* Number of TS Symbol */
-+#define PCIE_SNR_TS_S 0
-+#define PCIE_SNR_SKP 0x00000700 /* Number of SKP Symbol */
-+#define PCIE_SNR_SKP_S 8
-+#define PCIE_SNR_REPLAY_TIMER 0x0007C000 /* Timer Modifier for Replay Timer */
-+#define PCIE_SNR_REPLAY_TIMER_S 14
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER 0x00F80000 /* Timer Modifier for Ack/Nak Latency Timer */
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER_S 19
-+#define PCIE_SNR_FC_TIMER 0x1F000000 /* Timer Modifier for Flow Control Watchdog Timer */
-+#define PCIE_SNR_FC_TIMER_S 28
-+
-+/* Symbol Timer Register and Filter Mask Register 1 */
-+#define PCIE_STRFMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x71C)
-+#define PCIE_STRFMR_SKP_INTERVAL 0x000007FF /* SKP lnterval Value */
-+#define PCIE_STRFMR_SKP_INTERVAL_S 0
-+#define PCIE_STRFMR_FC_WDT_DISABLE 0x00008000 /* Disable of FC Watchdog Timer */
-+#define PCIE_STRFMR_TLP_FUNC_MISMATCH_OK 0x00010000 /* Mask Function Mismatch Filtering for Incoming Requests */
-+#define PCIE_STRFMR_POISONED_TLP_OK 0x00020000 /* Mask Poisoned TLP Filtering */
-+#define PCIE_STRFMR_BAR_MATCH_OK 0x00040000 /* Mask BAR Match Filtering */
-+#define PCIE_STRFMR_TYPE1_CFG_REQ_OK 0x00080000 /* Mask Type 1 Configuration Request Filtering */
-+#define PCIE_STRFMR_LOCKED_REQ_OK 0x00100000 /* Mask Locked Request Filtering */
-+#define PCIE_STRFMR_CPL_TAG_ERR_RULES_OK 0x00200000 /* Mask Tag Error Rules for Received Completions */
-+#define PCIE_STRFMR_CPL_REQUESTOR_ID_MISMATCH_OK 0x00400000 /* Mask Requester ID Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_FUNC_MISMATCH_OK 0x00800000 /* Mask Function Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_TC_MISMATCH_OK 0x01000000 /* Mask Traffic Class Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_ATTR_MISMATCH_OK 0x02000000 /* Mask Attribute Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_LENGTH_MISMATCH_OK 0x04000000 /* Mask Length Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_TLP_ECRC_ERR_OK 0x08000000 /* Mask ECRC Error Filtering */
-+#define PCIE_STRFMR_CPL_TLP_ECRC_OK 0x10000000 /* Mask ECRC Error Filtering for Completions */
-+#define PCIE_STRFMR_RX_TLP_MSG_NO_DROP 0x20000000 /* Send Message TLPs */
-+#define PCIE_STRFMR_RX_IO_TRANS_ENABLE 0x40000000 /* Mask Filtering of received I/O Requests */
-+#define PCIE_STRFMR_RX_CFG_TRANS_ENABLE 0x80000000 /* Mask Filtering of Received Configuration Requests */
-+
-+#define PCIE_DEF_SKP_INTERVAL 700 /* 1180 ~1538 , 125MHz * 2, 250MHz * 1 */
-+
-+/* Filter Masker Register 2 */
-+#define PCIE_FMR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x720)
-+#define PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1 0x00000001 /* Mask RADM Filtering and Error Handling Rules */
-+#define PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 0x00000002 /* Mask RADM Filtering and Error Handling Rules */
-+
-+/* Debug Register 0 */
-+#define PCIE_DBR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x728)
-+
-+/* Debug Register 1 */
-+#define PCIE_DBR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x72C)
-+
-+/* Transmit Posted FC Credit Status Register */
-+#define PCIE_TPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x730)
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS 0x00000FFF /* Transmit Posted Data FC Credits */
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS_S 0
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS 0x000FF000 /* Transmit Posted Header FC Credits */
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Non-Posted FC Credit Status */
-+#define PCIE_TNPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x734)
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS 0x00000FFF /* Transmit Non-Posted Data FC Credits */
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS_S 0
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS 0x000FF000 /* Transmit Non-Posted Header FC Credits */
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Complete FC Credit Status Register */
-+#define PCIE_TCFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x738)
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS 0x00000FFF /* Transmit Completion Data FC Credits */
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS_S 0
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS 0x000FF000 /* Transmit Completion Header FC Credits */
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS_S 12
-+
-+/* Queue Status Register */
-+#define PCIE_QSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x73C)
-+#define PCIE_QSR_WAIT_UPDATE_FC_DLL 0x00000001 /* Received TLP FC Credits Not Returned */
-+#define PCIE_QSR_TX_RETRY_BUF_NOT_EMPTY 0x00000002 /* Transmit Retry Buffer Not Empty */
-+#define PCIE_QSR_RX_QUEUE_NOT_EMPTY 0x00000004 /* Received Queue Not Empty */
-+
-+/* VC Transmit Arbitration Register 1 */
-+#define PCIE_VCTAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x740)
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC0 0x000000FF /* WRR Weight for VC0 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC1 0x0000FF00 /* WRR Weight for VC1 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC2 0x00FF0000 /* WRR Weight for VC2 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC3 0xFF000000 /* WRR Weight for VC3 */
-+
-+/* VC Transmit Arbitration Register 2 */
-+#define PCIE_VCTAR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x744)
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC4 0x000000FF /* WRR Weight for VC4 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC5 0x0000FF00 /* WRR Weight for VC5 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC6 0x00FF0000 /* WRR Weight for VC6 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC7 0xFF000000 /* WRR Weight for VC7 */
-+
-+/* VC0 Posted Receive Queue Control Register */
-+#define PCIE_VC0_PRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x748)
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS 0x00000FFF /* VC0 Posted Data Credits */
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS_S 0
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS 0x000FF000 /* VC0 Posted Header Credits */
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS_S 12
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE 0x00E00000 /* VC0 Posted TLP Queue Mode */
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE_S 20
-+#define PCIE_VC0_PRQCR_TLP_RELAX_ORDER 0x40000000 /* TLP Type Ordering for VC0 */
-+#define PCIE_VC0_PRQCR_VC_STRICT_ORDER 0x80000000 /* VC0 Ordering for Receive Queues */
-+
-+/* VC0 Non-Posted Receive Queue Control */
-+#define PCIE_VC0_NPRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74C)
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS 0x00000FFF /* VC0 Non-Posted Data Credits */
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS_S 0
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS 0x000FF000 /* VC0 Non-Posted Header Credits */
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS_S 12
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE 0x00E00000 /* VC0 Non-Posted TLP Queue Mode */
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE_S 20
-+
-+/* VC0 Completion Receive Queue Control */
-+#define PCIE_VC0_CRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x750)
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS 0x00000FFF /* VC0 Completion TLP Queue Mode */
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS_S 0
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS 0x000FF000 /* VC0 Completion Header Credits */
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS_S 12
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE 0x00E00000 /* VC0 Completion Data Credits */
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE_S 21
-+
-+/* Applicable to the above three registers */
-+enum {
-+ PCIE_VC0_TLP_QUEUE_MODE_STORE_FORWARD = 1,
-+ PCIE_VC0_TLP_QUEUE_MODE_CUT_THROUGH = 2,
-+ PCIE_VC0_TLP_QUEUE_MODE_BYPASS = 4,
-+};
-+
-+/* VC0 Posted Buffer Depth Register */
-+#define PCIE_VC0_PBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7A8)
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Posted Data Queue Depth */
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Posted Header Queue Depth */
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Non-Posted Buffer Depth Register */
-+#define PCIE_VC0_NPBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7AC)
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Non-Posted Data Queue Depth */
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Non-Posted Header Queue Depth */
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Completion Buffer Depth Register */
-+#define PCIE_VC0_CBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7B0)
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES 0x00003FFF /* C0 Completion Data Queue Depth */
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Completion Header Queue Depth */
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES_S 16
-+
-+/* PHY Status Register, all zeros in VR9 */
-+#define PCIE_PHYSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x810)
-+
-+/* PHY Control Register, all zeros in VR9 */
-+#define PCIE_PHYCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x814)
-+
-+/*
-+ * PCIe PDI PHY register definition, suppose all the following
-+ * stuff is confidential.
-+ * XXX, detailed bit definition
-+ */
-+#define PCIE_PHY_PLL_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x22 << 1))
-+#define PCIE_PHY_PLL_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x23 << 1))
-+#define PCIE_PHY_PLL_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x24 << 1))
-+#define PCIE_PHY_PLL_CTRL4(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x25 << 1))
-+#define PCIE_PHY_PLL_CTRL5(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x26 << 1))
-+#define PCIE_PHY_PLL_CTRL6(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x27 << 1))
-+#define PCIE_PHY_PLL_CTRL7(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x28 << 1))
-+#define PCIE_PHY_PLL_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x29 << 1))
-+#define PCIE_PHY_PLL_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2A << 1))
-+#define PCIE_PHY_PLL_A_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2B << 1))
-+#define PCIE_PHY_PLL_STATUS(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2C << 1))
-+
-+#define PCIE_PHY_TX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x30 << 1))
-+#define PCIE_PHY_TX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x31 << 1))
-+#define PCIE_PHY_TX1_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x32 << 1))
-+#define PCIE_PHY_TX1_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x33 << 1))
-+#define PCIE_PHY_TX1_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x34 << 1))
-+#define PCIE_PHY_TX1_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x35 << 1))
-+#define PCIE_PHY_TX1_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x36 << 1))
-+#define PCIE_PHY_TX1_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x37 << 1))
-+
-+#define PCIE_PHY_TX2_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x38 << 1))
-+#define PCIE_PHY_TX2_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x39 << 1))
-+#define PCIE_PHY_TX2_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3B << 1))
-+#define PCIE_PHY_TX2_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3C << 1))
-+#define PCIE_PHY_TX2_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3D << 1))
-+#define PCIE_PHY_TX2_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3E << 1))
-+#define PCIE_PHY_TX2_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3F << 1))
-+
-+#define PCIE_PHY_RX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x50 << 1))
-+#define PCIE_PHY_RX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x51 << 1))
-+#define PCIE_PHY_RX1_CDR(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x52 << 1))
-+#define PCIE_PHY_RX1_EI(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x53 << 1))
-+#define PCIE_PHY_RX1_A_CTRL(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x55 << 1))
-+
-+/* Interrupt related stuff */
-+#define PCIE_LEGACY_DISABLE 0
-+#define PCIE_LEGACY_INTA 1
-+#define PCIE_LEGACY_INTB 2
-+#define PCIE_LEGACY_INTC 3
-+#define PCIE_LEGACY_INTD 4
-+#define PCIE_LEGACY_INT_MAX PCIE_LEGACY_INTD
-+
-+#endif /* IFXMIPS_PCIE_REG_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_vr9.h
-@@ -0,0 +1,284 @@
-+/****************************************************************************
-+ Copyright (c) 2010
-+ Lantiq Deutschland GmbH
-+ Am Campeon 3; 85579 Neubiberg, Germany
-+
-+ For licensing information, see the file 'LICENSE' in the root folder of
-+ this software module.
-+
-+ *****************************************************************************/
-+/*!
-+ \file ifxmips_pcie_vr9.h
-+ \ingroup IFX_PCIE
-+ \brief PCIe RC driver vr9 specific file
-+*/
-+
-+#ifndef IFXMIPS_PCIE_VR9_H
-+#define IFXMIPS_PCIE_VR9_H
-+
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+
-+#include <linux/gpio.h>
-+#include <lantiq_soc.h>
-+
-+#define IFX_PCIE_GPIO_RESET 494
-+
-+#define IFX_REG_R32 ltq_r32
-+#define IFX_REG_W32 ltq_w32
-+#define CONFIG_IFX_PCIE_HW_SWAP
-+#define IFX_RCU_AHB_ENDIAN ((volatile u32*)(IFX_RCU + 0x004C))
-+#define IFX_RCU_RST_REQ ((volatile u32*)(IFX_RCU + 0x0010))
-+#define IFX_RCU_AHB_BE_PCIE_PDI 0x00000080 /* Configure PCIE PDI module in big endian*/
-+
-+#define IFX_RCU (KSEG1 | 0x1F203000)
-+#define IFX_RCU_AHB_BE_PCIE_M 0x00000001 /* Configure AHB master port that connects to PCIe RC in big endian */
-+#define IFX_RCU_AHB_BE_PCIE_S 0x00000010 /* Configure AHB slave port that connects to PCIe RC in little endian */
-+#define IFX_RCU_AHB_BE_XBAR_M 0x00000002 /* Configure AHB master port that connects to XBAR in big endian */
-+#define IFX_RCU_AHB_BE_XBAR_S 0x00000008 /* Configure AHB slave port that connects to XBAR in big endian */
-+#define CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+
-+#define IFX_PMU1_MODULE_PCIE_PHY (0)
-+#define IFX_PMU1_MODULE_PCIE_CTRL (1)
-+#define IFX_PMU1_MODULE_PDI (4)
-+#define IFX_PMU1_MODULE_MSI (5)
-+
-+#define IFX_PMU_MODULE_PCIE_L0_CLK (31)
-+
-+
-+#define IFX_GPIO (KSEG1 | 0x1E100B00)
-+#define ALT0 ((volatile u32*)(IFX_GPIO + 0x007c))
-+#define ALT1 ((volatile u32*)(IFX_GPIO + 0x0080))
-+#define OD ((volatile u32*)(IFX_GPIO + 0x0084))
-+#define DIR ((volatile u32*)(IFX_GPIO + 0x0078))
-+#define OUT ((volatile u32*)(IFX_GPIO + 0x0070))
-+
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+
-+ gpio_request(IFX_PCIE_GPIO_RESET, "pcie-reset");
-+ gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+
-+/* ifx_gpio_pin_reserve(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_dir_out_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_altsel0_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_altsel1_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_open_drain_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);*/
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ /* Enable AHB bus master/slave */
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "ahb");
-+ clk_enable(clk);
-+
-+ //AHBM_PMU_SETUP(IFX_PMU_ENABLE);
-+ //AHBS_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg |= IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#else
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "phy");
-+ clk_enable(clk);
-+
-+ //PCIE_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "phy");
-+ clk_disable(clk);
-+
-+// PCIE_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* SRAM2PDI endianness control. */
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ /* Enable PDI to access PCIe PHY register */
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "pdi");
-+ clk_enable(clk);
-+ //PDI_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-+ reg |= 0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ /* Reset PCIe PHY & Core, bit 22 */
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg |= 0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
-+// ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-+// gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+ //ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "ctl");
-+ clk_enable(clk);
-+ clk = clk_get_sys("1d900000.pcie", "bus");
-+ clk_enable(clk);
-+
-+ /* PCIe Core controller enabled */
-+// PCIE_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+
-+ /* Enable PCIe L0 Clock */
-+// PCIE_L0_CLK_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ struct clk *clk;
-+ pcie_msi_pic_init(pcie_port);
-+ clk = clk_get_sys("ltq_pcie", "msi");
-+ clk_enable(clk);
-+// MSI_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+#endif /* CONFIG_PCI_LANTIQ */
-+ return tbus_number;
-+}
-+
-+static inline struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ #endif /* CONFIG_PCI_LANTIQ */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_VR9_H */
---- a/arch/mips/pci/pci-legacy.c
-+++ b/arch/mips/pci/pci-legacy.c
-@@ -305,3 +305,30 @@ char *__init pcibios_setup(char *str)
- return pcibios_plat_setup(str);
- return str;
- }
-+
-+int pcibios_host_nr(void)
-+{
-+ int count = 0;
-+ struct pci_controller *hose;
-+ list_for_each_entry(hose, &controllers, list) {
-+ count++;
-+ }
-+ return count;
-+}
-+EXPORT_SYMBOL(pcibios_host_nr);
-+
-+int pcibios_1st_host_bus_nr(void)
-+{
-+ int bus_nr = 0;
-+ struct pci_controller *hose;
-+
-+ hose = list_first_entry_or_null(&controllers, struct pci_controller, list);
-+
-+ if (hose != NULL) {
-+ if (hose->bus != NULL) {
-+ bus_nr = hose->bus->number + 1;
-+ }
-+ }
-+ return bus_nr;
-+}
-+EXPORT_SYMBOL(pcibios_1st_host_bus_nr);
---- /dev/null
-+++ b/arch/mips/pci/pcie-lantiq.h
-@@ -0,0 +1,1316 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_reg.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_REG_H
-+#define IFXMIPS_PCIE_REG_H
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+/*!
-+ \file ifxmips_pcie_reg.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module register definition
-+*/
-+/* PCIe Address Mapping Base */
-+#define PCIE_CFG_PHY_BASE 0x1D000000UL
-+#define PCIE_CFG_BASE (KSEG1 + PCIE_CFG_PHY_BASE)
-+#define PCIE_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE_MEM_PHY_BASE 0x1C000000UL
-+#define PCIE_MEM_BASE (KSEG1 + PCIE_MEM_PHY_BASE)
-+#define PCIE_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE_MEM_PHY_END (PCIE_MEM_PHY_BASE + PCIE_MEM_SIZE - 1)
-+
-+#define PCIE_IO_PHY_BASE 0x1D800000UL
-+#define PCIE_IO_BASE (KSEG1 + PCIE_IO_PHY_BASE)
-+#define PCIE_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE_IO_PHY_END (PCIE_IO_PHY_BASE + PCIE_IO_SIZE - 1)
-+
-+#define PCIE_RC_CFG_BASE (KSEG1 + 0x1D900000)
-+#define PCIE_APP_LOGIC_REG (KSEG1 + 0x1E100900)
-+#define PCIE_MSI_PHY_BASE 0x1F600000UL
-+
-+#define PCIE_PDI_PHY_BASE 0x1F106800UL
-+#define PCIE_PDI_BASE (KSEG1 + PCIE_PDI_PHY_BASE)
-+#define PCIE_PDI_SIZE 0x400
-+
-+#define PCIE1_CFG_PHY_BASE 0x19000000UL
-+#define PCIE1_CFG_BASE (KSEG1 + PCIE1_CFG_PHY_BASE)
-+#define PCIE1_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE1_MEM_PHY_BASE 0x18000000UL
-+#define PCIE1_MEM_BASE (KSEG1 + PCIE1_MEM_PHY_BASE)
-+#define PCIE1_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE1_MEM_PHY_END (PCIE1_MEM_PHY_BASE + PCIE1_MEM_SIZE - 1)
-+
-+#define PCIE1_IO_PHY_BASE 0x19800000UL
-+#define PCIE1_IO_BASE (KSEG1 + PCIE1_IO_PHY_BASE)
-+#define PCIE1_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE1_IO_PHY_END (PCIE1_IO_PHY_BASE + PCIE1_IO_SIZE - 1)
-+
-+#define PCIE1_RC_CFG_BASE (KSEG1 + 0x19900000)
-+#define PCIE1_APP_LOGIC_REG (KSEG1 + 0x1E100700)
-+#define PCIE1_MSI_PHY_BASE 0x1F400000UL
-+
-+#define PCIE1_PDI_PHY_BASE 0x1F700400UL
-+#define PCIE1_PDI_BASE (KSEG1 + PCIE1_PDI_PHY_BASE)
-+#define PCIE1_PDI_SIZE 0x400
-+
-+#define PCIE_CFG_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_CFG_BASE) : (PCIE_CFG_BASE))
-+#define PCIE_MEM_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_BASE) : (PCIE_MEM_BASE))
-+#define PCIE_IO_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_BASE) : (PCIE_IO_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_PHY_BASE) : (PCIE_MEM_PHY_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_MEM_PHY_END) : (PCIE_MEM_PHY_END))
-+#define PCIE_IO_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_PHY_BASE) : (PCIE_IO_PHY_BASE))
-+#define PCIE_IO_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_IO_PHY_END) : (PCIE_IO_PHY_END))
-+#define PCIE_APP_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_APP_LOGIC_REG) : (PCIE_APP_LOGIC_REG))
-+#define PCIE_RC_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_RC_CFG_BASE) : (PCIE_RC_CFG_BASE))
-+#define PCIE_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_PDI_BASE) : (PCIE_PDI_BASE))
-+
-+/* PCIe Application Logic Register */
-+/* RC Core Control Register */
-+#define PCIE_RC_CCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x10)
-+/* This should be enabled after initializing configuratin registers
-+ * Also should check link status retraining bit
-+ */
-+#define PCIE_RC_CCR_LTSSM_ENABLE 0x00000001 /* Enable LTSSM to continue link establishment */
-+
-+/* RC Core Debug Register */
-+#define PCIE_RC_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x14)
-+#define PCIE_RC_DR_DLL_UP 0x00000001 /* Data Link Layer Up */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE 0x0000000E /* Current Power State */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE_S 1
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE 0x000001F0 /* Current LTSSM State */
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE_S 4
-+
-+#define PCIE_RC_DR_PM_DEV_STATE 0x00000E00 /* Power Management D-State */
-+#define PCIE_RC_DR_PM_DEV_STATE_S 9
-+
-+#define PCIE_RC_DR_PM_ENABLED 0x00001000 /* Power Management State from PMU */
-+#define PCIE_RC_DR_PME_EVENT_ENABLED 0x00002000 /* Power Management Event Enable State */
-+#define PCIE_RC_DR_AUX_POWER_ENABLED 0x00004000 /* Auxiliary Power Enable */
-+
-+/* Current Power State Definition */
-+enum {
-+ PCIE_RC_DR_D0 = 0,
-+ PCIE_RC_DR_D1, /* Not supported */
-+ PCIE_RC_DR_D2, /* Not supported */
-+ PCIE_RC_DR_D3,
-+ PCIE_RC_DR_UN,
-+};
-+
-+/* PHY Link Status Register */
-+#define PCIE_PHY_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x18)
-+#define PCIE_PHY_SR_PHY_LINK_UP 0x00000001 /* PHY Link Up/Down Indicator */
-+
-+/* Electromechanical Control Register */
-+#define PCIE_EM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x1C)
-+#define PCIE_EM_CR_CARD_IS_PRESENT 0x00000001 /* Card Presence Detect State */
-+#define PCIE_EM_CR_MRL_OPEN 0x00000002 /* MRL Sensor State */
-+#define PCIE_EM_CR_POWER_FAULT_SET 0x00000004 /* Power Fault Detected */
-+#define PCIE_EM_CR_MRL_SENSOR_SET 0x00000008 /* MRL Sensor Changed */
-+#define PCIE_EM_CR_PRESENT_DETECT_SET 0x00000010 /* Card Presense Detect Changed */
-+#define PCIE_EM_CR_CMD_CPL_INT_SET 0x00000020 /* Command Complete Interrupt */
-+#define PCIE_EM_CR_SYS_INTERLOCK_SET 0x00000040 /* System Electromechanical IterLock Engaged */
-+#define PCIE_EM_CR_ATTENTION_BUTTON_SET 0x00000080 /* Attention Button Pressed */
-+
-+/* Interrupt Status Register */
-+#define PCIE_IR_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x20)
-+#define PCIE_IR_SR_PME_CAUSE_MSI 0x00000002 /* MSI caused by PME */
-+#define PCIE_IR_SR_HP_PME_WAKE_GEN 0x00000004 /* Hotplug PME Wake Generation */
-+#define PCIE_IR_SR_HP_MSI 0x00000008 /* Hotplug MSI */
-+#define PCIE_IR_SR_AHB_LU_ERR 0x00000030 /* AHB Bridge Lookup Error Signals */
-+#define PCIE_IR_SR_AHB_LU_ERR_S 4
-+#define PCIE_IR_SR_INT_MSG_NUM 0x00003E00 /* Interrupt Message Number */
-+#define PCIE_IR_SR_INT_MSG_NUM_S 9
-+#define PCIE_IR_SR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_IR_SR_AER_INT_MSG_NUM_S 27
-+
-+/* Message Control Register */
-+#define PCIE_MSG_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x30)
-+#define PCIE_MSG_CR_GEN_PME_TURN_OFF_MSG 0x00000001 /* Generate PME Turn Off Message */
-+#define PCIE_MSG_CR_GEN_UNLOCK_MSG 0x00000002 /* Generate Unlock Message */
-+
-+#define PCIE_VDM_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x34)
-+
-+/* Vendor-Defined Message Requester ID Register */
-+#define PCIE_VDM_RID(X) (PCIE_APP_PORT_TO_BASE (X) + 0x38)
-+#define PCIE_VDM_RID_VENROR_MSG_REQ_ID 0x0000FFFF
-+#define PCIE_VDM_RID_VDMRID_S 0
-+
-+/* ASPM Control Register */
-+#define PCIE_ASPM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x40)
-+#define PCIE_ASPM_CR_HOT_RST 0x00000001 /* Hot Reset Request to the downstream device */
-+#define PCIE_ASPM_CR_REQ_EXIT_L1 0x00000002 /* Request to Exit L1 */
-+#define PCIE_ASPM_CR_REQ_ENTER_L1 0x00000004 /* Request to Enter L1 */
-+
-+/* Vendor Message DW0 Register */
-+#define PCIE_VM_MSG_DW0(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x50)
-+#define PCIE_VM_MSG_DW0_TYPE 0x0000001F /* Message type */
-+#define PCIE_VM_MSG_DW0_TYPE_S 0
-+#define PCIE_VM_MSG_DW0_FORMAT 0x00000060 /* Format */
-+#define PCIE_VM_MSG_DW0_FORMAT_S 5
-+#define PCIE_VM_MSG_DW0_TC 0x00007000 /* Traffic Class */
-+#define PCIE_VM_MSG_DW0_TC_S 12
-+#define PCIE_VM_MSG_DW0_ATTR 0x000C0000 /* Atrributes */
-+#define PCIE_VM_MSG_DW0_ATTR_S 18
-+#define PCIE_VM_MSG_DW0_EP_TLP 0x00100000 /* Poisoned TLP */
-+#define PCIE_VM_MSG_DW0_TD 0x00200000 /* TLP Digest */
-+#define PCIE_VM_MSG_DW0_LEN 0xFFC00000 /* Length */
-+#define PCIE_VM_MSG_DW0_LEN_S 22
-+
-+/* Format Definition */
-+enum {
-+ PCIE_VM_MSG_FORMAT_00 = 0, /* 3DW Hdr, no data*/
-+ PCIE_VM_MSG_FORMAT_01, /* 4DW Hdr, no data */
-+ PCIE_VM_MSG_FORMAT_10, /* 3DW Hdr, with data */
-+ PCIE_VM_MSG_FORMAT_11, /* 4DW Hdr, with data */
-+};
-+
-+/* Traffic Class Definition */
-+enum {
-+ PCIE_VM_MSG_TC0 = 0,
-+ PCIE_VM_MSG_TC1,
-+ PCIE_VM_MSG_TC2,
-+ PCIE_VM_MSG_TC3,
-+ PCIE_VM_MSG_TC4,
-+ PCIE_VM_MSG_TC5,
-+ PCIE_VM_MSG_TC6,
-+ PCIE_VM_MSG_TC7,
-+};
-+
-+/* Attributes Definition */
-+enum {
-+ PCIE_VM_MSG_ATTR_00 = 0, /* RO and No Snoop cleared */
-+ PCIE_VM_MSG_ATTR_01, /* RO cleared , No Snoop set */
-+ PCIE_VM_MSG_ATTR_10, /* RO set, No Snoop cleared*/
-+ PCIE_VM_MSG_ATTR_11, /* RO and No Snoop set */
-+};
-+
-+/* Payload Size Definition */
-+#define PCIE_VM_MSG_LEN_MIN 0
-+#define PCIE_VM_MSG_LEN_MAX 1024
-+
-+/* Vendor Message DW1 Register */
-+#define PCIE_VM_MSG_DW1(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x54)
-+#define PCIE_VM_MSG_DW1_FUNC_NUM 0x00000070 /* Function Number */
-+#define PCIE_VM_MSG_DW1_FUNC_NUM_S 8
-+#define PCIE_VM_MSG_DW1_CODE 0x00FF0000 /* Message Code */
-+#define PCIE_VM_MSG_DW1_CODE_S 16
-+#define PCIE_VM_MSG_DW1_TAG 0xFF000000 /* Tag */
-+#define PCIE_VM_MSG_DW1_TAG_S 24
-+
-+#define PCIE_VM_MSG_DW2(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x58)
-+#define PCIE_VM_MSG_DW3(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x5C)
-+
-+/* Vendor Message Request Register */
-+#define PCIE_VM_MSG_REQR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x60)
-+#define PCIE_VM_MSG_REQR_REQ 0x00000001 /* Vendor Message Request */
-+
-+
-+/* AHB Slave Side Band Control Register */
-+#define PCIE_AHB_SSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x70)
-+#define PCIE_AHB_SSB_REQ_BCM 0x00000001 /* Slave Reques BCM filed */
-+#define PCIE_AHB_SSB_REQ_EP 0x00000002 /* Slave Reques EP filed */
-+#define PCIE_AHB_SSB_REQ_TD 0x00000004 /* Slave Reques TD filed */
-+#define PCIE_AHB_SSB_REQ_ATTR 0x00000018 /* Slave Reques Attribute number */
-+#define PCIE_AHB_SSB_REQ_ATTR_S 3
-+#define PCIE_AHB_SSB_REQ_TC 0x000000E0 /* Slave Request TC Field */
-+#define PCIE_AHB_SSB_REQ_TC_S 5
-+
-+/* AHB Master SideBand Ctrl Register */
-+#define PCIE_AHB_MSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x74)
-+#define PCIE_AHB_MSB_RESP_ATTR 0x00000003 /* Master Response Attribute number */
-+#define PCIE_AHB_MSB_RESP_ATTR_S 0
-+#define PCIE_AHB_MSB_RESP_BAD_EOT 0x00000004 /* Master Response Badeot filed */
-+#define PCIE_AHB_MSB_RESP_BCM 0x00000008 /* Master Response BCM filed */
-+#define PCIE_AHB_MSB_RESP_EP 0x00000010 /* Master Response EP filed */
-+#define PCIE_AHB_MSB_RESP_TD 0x00000020 /* Master Response TD filed */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM 0x000003C0 /* Master Response Function number */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM_S 6
-+
-+/* AHB Control Register, fixed bus enumeration exception */
-+#define PCIE_AHB_CTRL(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x78)
-+#define PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS 0x00000001
-+
-+/* Interrupt Enalbe Register */
-+#define PCIE_IRNEN(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF4)
-+#define PCIE_IRNCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF8)
-+#define PCIE_IRNICR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xFC)
-+
-+/* PCIe interrupt enable/control/capture register definition */
-+#define PCIE_IRN_AER_REPORT 0x00000001 /* AER Interrupt */
-+#define PCIE_IRN_AER_MSIX 0x00000002 /* Advanced Error MSI-X Interrupt */
-+#define PCIE_IRN_PME 0x00000004 /* PME Interrupt */
-+#define PCIE_IRN_HOTPLUG 0x00000008 /* Hotplug Interrupt */
-+#define PCIE_IRN_RX_VDM_MSG 0x00000010 /* Vendor-Defined Message Interrupt */
-+#define PCIE_IRN_RX_CORRECTABLE_ERR_MSG 0x00000020 /* Correctable Error Message Interrupt */
-+#define PCIE_IRN_RX_NON_FATAL_ERR_MSG 0x00000040 /* Non-fatal Error Message */
-+#define PCIE_IRN_RX_FATAL_ERR_MSG 0x00000080 /* Fatal Error Message */
-+#define PCIE_IRN_RX_PME_MSG 0x00000100 /* PME Message Interrupt */
-+#define PCIE_IRN_RX_PME_TURNOFF_ACK 0x00000200 /* PME Turnoff Ack Message Interrupt */
-+#define PCIE_IRN_AHB_BR_FATAL_ERR 0x00000400 /* AHB Fatal Error Interrupt */
-+#define PCIE_IRN_LINK_AUTO_BW_STATUS 0x00000800 /* Link Auto Bandwidth Status Interrupt */
-+#define PCIE_IRN_BW_MGT 0x00001000 /* Bandwidth Managment Interrupt */
-+#define PCIE_IRN_INTA 0x00002000 /* INTA */
-+#define PCIE_IRN_INTB 0x00004000 /* INTB */
-+#define PCIE_IRN_INTC 0x00008000 /* INTC */
-+#define PCIE_IRN_INTD 0x00010000 /* INTD */
-+#define PCIE_IRN_WAKEUP 0x00020000 /* Wake up Interrupt */
-+
-+#define PCIE_RC_CORE_COMBINED_INT (PCIE_IRN_AER_REPORT | PCIE_IRN_AER_MSIX | PCIE_IRN_PME | \
-+ PCIE_IRN_HOTPLUG | PCIE_IRN_RX_VDM_MSG | PCIE_IRN_RX_CORRECTABLE_ERR_MSG |\
-+ PCIE_IRN_RX_NON_FATAL_ERR_MSG | PCIE_IRN_RX_FATAL_ERR_MSG | \
-+ PCIE_IRN_RX_PME_MSG | PCIE_IRN_RX_PME_TURNOFF_ACK | PCIE_IRN_AHB_BR_FATAL_ERR | \
-+ PCIE_IRN_LINK_AUTO_BW_STATUS | PCIE_IRN_BW_MGT)
-+/* PCIe RC Configuration Register */
-+#define PCIE_VDID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x00)
-+
-+/* Bit definition from pci_reg.h */
-+#define PCIE_PCICMDSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x04)
-+#define PCIE_CCRID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x08)
-+#define PCIE_CLSLTHTBR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x0C) /* EP only */
-+/* BAR0, BAR1,Only necessary if the bridges implements a device-specific register set or memory buffer */
-+#define PCIE_BAR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10) /* Not used*/
-+#define PCIE_BAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14) /* Not used */
-+
-+#define PCIE_BNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x18) /* Mandatory */
-+/* Bus Number Register bits */
-+#define PCIE_BNR_PRIMARY_BUS_NUM 0x000000FF
-+#define PCIE_BNR_PRIMARY_BUS_NUM_S 0
-+#define PCIE_PNR_SECONDARY_BUS_NUM 0x0000FF00
-+#define PCIE_PNR_SECONDARY_BUS_NUM_S 8
-+#define PCIE_PNR_SUB_BUS_NUM 0x00FF0000
-+#define PCIE_PNR_SUB_BUS_NUM_S 16
-+
-+/* IO Base/Limit Register bits */
-+#define PCIE_IOBLSECS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x1C) /* RC only */
-+#define PCIE_IOBLSECS_32BIT_IO_ADDR 0x00000001
-+#define PCIE_IOBLSECS_IO_BASE_ADDR 0x000000F0
-+#define PCIE_IOBLSECS_IO_BASE_ADDR_S 4
-+#define PCIE_IOBLSECS_32BIT_IOLIMT 0x00000100
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR 0x0000F000
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR_S 12
-+
-+/* Non-prefetchable Memory Base/Limit Register bit */
-+#define PCIE_MBML(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x20) /* RC only */
-+#define PCIE_MBML_MEM_BASE_ADDR 0x0000FFF0
-+#define PCIE_MBML_MEM_BASE_ADDR_S 4
-+#define PCIE_MBML_MEM_LIMIT_ADDR 0xFFF00000
-+#define PCIE_MBML_MEM_LIMIT_ADDR_S 20
-+
-+/* Prefetchable Memory Base/Limit Register bit */
-+#define PCIE_PMBL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x24) /* RC only */
-+#define PCIE_PMBL_64BIT_ADDR 0x00000001
-+#define PCIE_PMBL_UPPER_12BIT 0x0000FFF0
-+#define PCIE_PMBL_UPPER_12BIT_S 4
-+#define PCIE_PMBL_E64MA 0x00010000
-+#define PCIE_PMBL_END_ADDR 0xFFF00000
-+#define PCIE_PMBL_END_ADDR_S 20
-+#define PCIE_PMBU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x28) /* RC only */
-+#define PCIE_PMLU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x2C) /* RC only */
-+
-+/* I/O Base/Limit Upper 16 bits register */
-+#define PCIE_IO_BANDL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x30) /* RC only */
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE 0x0000FFFF
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE_S 0
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT 0xFFFF0000
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT_S 16
-+
-+#define PCIE_CPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x34)
-+#define PCIE_EBBAR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x38)
-+
-+/* Interrupt and Secondary Bridge Control Register */
-+#define PCIE_INTRBCTRL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x3C)
-+
-+#define PCIE_INTRBCTRL_INT_LINE 0x000000FF
-+#define PCIE_INTRBCTRL_INT_LINE_S 0
-+#define PCIE_INTRBCTRL_INT_PIN 0x0000FF00
-+#define PCIE_INTRBCTRL_INT_PIN_S 8
-+#define PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE 0x00010000 /* #PERR */
-+#define PCIE_INTRBCTRL_SERR_ENABLE 0x00020000 /* #SERR */
-+#define PCIE_INTRBCTRL_ISA_ENABLE 0x00040000 /* ISA enable, IO 64KB only */
-+#define PCIE_INTRBCTRL_VGA_ENABLE 0x00080000 /* VGA enable */
-+#define PCIE_INTRBCTRL_VGA_16BIT_DECODE 0x00100000 /* VGA 16bit decode */
-+#define PCIE_INTRBCTRL_RST_SECONDARY_BUS 0x00400000 /* Secondary bus rest, hot rest, 1ms */
-+/* Others are read only */
-+enum {
-+ PCIE_INTRBCTRL_INT_NON = 0,
-+ PCIE_INTRBCTRL_INTA,
-+ PCIE_INTRBCTRL_INTB,
-+ PCIE_INTRBCTRL_INTC,
-+ PCIE_INTRBCTRL_INTD,
-+};
-+
-+#define PCIE_PM_CAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x40)
-+
-+/* Power Management Control and Status Register */
-+#define PCIE_PM_CSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x44)
-+
-+#define PCIE_PM_CSR_POWER_STATE 0x00000003 /* Power State */
-+#define PCIE_PM_CSR_POWER_STATE_S 0
-+#define PCIE_PM_CSR_SW_RST 0x00000008 /* Soft Reset Enabled */
-+#define PCIE_PM_CSR_PME_ENABLE 0x00000100 /* PME Enable */
-+#define PCIE_PM_CSR_PME_STATUS 0x00008000 /* PME status */
-+
-+/* MSI Capability Register for EP */
-+#define PCIE_MCAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x50)
-+
-+#define PCIE_MCAPR_MSI_CAP_ID 0x000000FF /* MSI Capability ID */
-+#define PCIE_MCAPR_MSI_CAP_ID_S 0
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR_S 8
-+#define PCIE_MCAPR_MSI_ENABLE 0x00010000 /* MSI Enable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP 0x000E0000 /* Multiple Message Capable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP_S 17
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE 0x00700000 /* Multiple Message Enable */
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE_S 20
-+#define PCIE_MCAPR_ADDR64_CAP 0X00800000 /* 64-bit Address Capable */
-+
-+/* MSI Message Address Register */
-+#define PCIE_MA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x54)
-+
-+#define PCIE_MA_ADDR_MASK 0xFFFFFFFC /* Message Address */
-+
-+/* MSI Message Upper Address Register */
-+#define PCIE_MUA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x58)
-+
-+/* MSI Message Data Register */
-+#define PCIE_MD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x5C)
-+
-+#define PCIE_MD_DATA 0x0000FFFF /* Message Data */
-+#define PCIE_MD_DATA_S 0
-+
-+/* PCI Express Capability Register */
-+#define PCIE_XCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70)
-+
-+#define PCIE_XCAP_ID 0x000000FF /* PCI Express Capability ID */
-+#define PCIE_XCAP_ID_S 0
-+#define PCIE_XCAP_NEXT_CAP 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_XCAP_NEXT_CAP_S 8
-+#define PCIE_XCAP_VER 0x000F0000 /* PCI Express Capability Version */
-+#define PCIE_XCAP_VER_S 16
-+#define PCIE_XCAP_DEV_PORT_TYPE 0x00F00000 /* Device Port Type */
-+#define PCIE_XCAP_DEV_PORT_TYPE_S 20
-+#define PCIE_XCAP_SLOT_IMPLEMENTED 0x01000000 /* Slot Implemented */
-+#define PCIE_XCAP_MSG_INT_NUM 0x3E000000 /* Interrupt Message Number */
-+#define PCIE_XCAP_MSG_INT_NUM_S 25
-+
-+/* Device Capability Register */
-+#define PCIE_DCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74)
-+
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE 0x00000007 /* Max Payload size */
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE_S 0
-+#define PCIE_DCAP_PHANTOM_FUNC 0x00000018 /* Phanton Function, not supported */
-+#define PCIE_DCAP_PHANTOM_FUNC_S 3
-+#define PCIE_DCAP_EXT_TAG 0x00000020 /* Extended Tag Field */
-+#define PCIE_DCAP_EP_L0S_LATENCY 0x000001C0 /* EP L0s latency only */
-+#define PCIE_DCAP_EP_L0S_LATENCY_S 6
-+#define PCIE_DCAP_EP_L1_LATENCY 0x00000E00 /* EP L1 latency only */
-+#define PCIE_DCAP_EP_L1_LATENCY_S 9
-+#define PCIE_DCAP_ROLE_BASE_ERR_REPORT 0x00008000 /* Role Based ERR */
-+
-+/* Maximum payload size supported */
-+enum {
-+ PCIE_MAX_PAYLOAD_128 = 0,
-+ PCIE_MAX_PAYLOAD_256,
-+ PCIE_MAX_PAYLOAD_512,
-+ PCIE_MAX_PAYLOAD_1024,
-+ PCIE_MAX_PAYLOAD_2048,
-+ PCIE_MAX_PAYLOAD_4096,
-+};
-+
-+/* Device Control and Status Register */
-+#define PCIE_DCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x78)
-+
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR_EN 0x00000001 /* COR-ERR */
-+#define PCIE_DCTLSTS_NONFATAL_ERR_EN 0x00000002 /* Non-fatal ERR */
-+#define PCIE_DCTLSTS_FATAL_ERR_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_DCTLSYS_UR_REQ_EN 0x00000008 /* UR ERR */
-+#define PCIE_DCTLSTS_RELAXED_ORDERING_EN 0x00000010 /* Enable relaxing ordering */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE 0x000000E0 /* Max payload mask */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE_S 5
-+#define PCIE_DCTLSTS_EXT_TAG_EN 0x00000100 /* Extended tag field */
-+#define PCIE_DCTLSTS_PHANTOM_FUNC_EN 0x00000200 /* Phantom Function Enable */
-+#define PCIE_DCTLSTS_AUX_PM_EN 0x00000400 /* AUX Power PM Enable */
-+#define PCIE_DCTLSTS_NO_SNOOP_EN 0x00000800 /* Enable no snoop, except root port*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE 0x00007000 /* Max Read Request size*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE_S 12
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR 0x00010000 /* COR-ERR Detected */
-+#define PCIE_DCTLSTS_NONFATAL_ERR 0x00020000 /* Non-Fatal ERR Detected */
-+#define PCIE_DCTLSTS_FATAL_ER 0x00040000 /* Fatal ERR Detected */
-+#define PCIE_DCTLSTS_UNSUPPORTED_REQ 0x00080000 /* UR Detected */
-+#define PCIE_DCTLSTS_AUX_POWER 0x00100000 /* Aux Power Detected */
-+#define PCIE_DCTLSTS_TRANSACT_PENDING 0x00200000 /* Transaction pending */
-+
-+#define PCIE_DCTLSTS_ERR_EN (PCIE_DCTLSTS_CORRECTABLE_ERR_EN | \
-+ PCIE_DCTLSTS_NONFATAL_ERR_EN | PCIE_DCTLSTS_FATAL_ERR_EN | \
-+ PCIE_DCTLSYS_UR_REQ_EN)
-+
-+/* Link Capability Register */
-+#define PCIE_LCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7C)
-+#define PCIE_LCAP_MAX_LINK_SPEED 0x0000000F /* Max link speed, 0x1 by default */
-+#define PCIE_LCAP_MAX_LINK_SPEED_S 0
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH 0x000003F0 /* Maxium Length Width */
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH_S 4
-+#define PCIE_LCAP_ASPM_LEVEL 0x00000C00 /* Active State Link PM Support */
-+#define PCIE_LCAP_ASPM_LEVEL_S 10
-+#define PCIE_LCAP_L0S_EIXT_LATENCY 0x00007000 /* L0s Exit Latency */
-+#define PCIE_LCAP_L0S_EIXT_LATENCY_S 12
-+#define PCIE_LCAP_L1_EXIT_LATENCY 0x00038000 /* L1 Exit Latency */
-+#define PCIE_LCAP_L1_EXIT_LATENCY_S 15
-+#define PCIE_LCAP_CLK_PM 0x00040000 /* Clock Power Management */
-+#define PCIE_LCAP_SDER 0x00080000 /* Surprise Down Error Reporting */
-+#define PCIE_LCAP_DLL_ACTIVE_REPROT 0x00100000 /* Data Link Layer Active Reporting Capable */
-+#define PCIE_LCAP_PORT_NUM 0xFF0000000 /* Port number */
-+#define PCIE_LCAP_PORT_NUM_S 24
-+
-+/* Maximum Length width definition */
-+#define PCIE_MAX_LENGTH_WIDTH_RES 0x00
-+#define PCIE_MAX_LENGTH_WIDTH_X1 0x01 /* Default */
-+#define PCIE_MAX_LENGTH_WIDTH_X2 0x02
-+#define PCIE_MAX_LENGTH_WIDTH_X4 0x04
-+#define PCIE_MAX_LENGTH_WIDTH_X8 0x08
-+#define PCIE_MAX_LENGTH_WIDTH_X12 0x0C
-+#define PCIE_MAX_LENGTH_WIDTH_X16 0x10
-+#define PCIE_MAX_LENGTH_WIDTH_X32 0x20
-+
-+/* Active State Link PM definition */
-+enum {
-+ PCIE_ASPM_RES0 = 0,
-+ PCIE_ASPM_L0S_ENTRY_SUPPORT, /* L0s */
-+ PCIE_ASPM_RES1,
-+ PCIE_ASPM_L0S_L1_ENTRY_SUPPORT, /* L0s and L1, default */
-+};
-+
-+/* L0s Exit Latency definition */
-+enum {
-+ PCIE_L0S_EIXT_LATENCY_L64NS = 0, /* < 64 ns */
-+ PCIE_L0S_EIXT_LATENCY_B64A128, /* > 64 ns < 128 ns */
-+ PCIE_L0S_EIXT_LATENCY_B128A256, /* > 128 ns < 256 ns */
-+ PCIE_L0S_EIXT_LATENCY_B256A512, /* > 256 ns < 512 ns */
-+ PCIE_L0S_EIXT_LATENCY_B512TO1U, /* > 512 ns < 1 us */
-+ PCIE_L0S_EIXT_LATENCY_B1A2U, /* > 1 us < 2 us */
-+ PCIE_L0S_EIXT_LATENCY_B2A4U, /* > 2 us < 4 us */
-+ PCIE_L0S_EIXT_LATENCY_M4US, /* > 4 us */
-+};
-+
-+/* L1 Exit Latency definition */
-+enum {
-+ PCIE_L1_EXIT_LATENCY_L1US = 0, /* < 1 us */
-+ PCIE_L1_EXIT_LATENCY_B1A2, /* > 1 us < 2 us */
-+ PCIE_L1_EXIT_LATENCY_B2A4, /* > 2 us < 4 us */
-+ PCIE_L1_EXIT_LATENCY_B4A8, /* > 4 us < 8 us */
-+ PCIE_L1_EXIT_LATENCY_B8A16, /* > 8 us < 16 us */
-+ PCIE_L1_EXIT_LATENCY_B16A32, /* > 16 us < 32 us */
-+ PCIE_L1_EXIT_LATENCY_B32A64, /* > 32 us < 64 us */
-+ PCIE_L1_EXIT_LATENCY_M64US, /* > 64 us */
-+};
-+
-+/* Link Control and Status Register */
-+#define PCIE_LCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x80)
-+#define PCIE_LCTLSTS_ASPM_ENABLE 0x00000003 /* Active State Link PM Control */
-+#define PCIE_LCTLSTS_ASPM_ENABLE_S 0
-+#define PCIE_LCTLSTS_RCB128 0x00000008 /* Read Completion Boundary 128*/
-+#define PCIE_LCTLSTS_LINK_DISABLE 0x00000010 /* Link Disable */
-+#define PCIE_LCTLSTS_RETRIAN_LINK 0x00000020 /* Retrain Link */
-+#define PCIE_LCTLSTS_COM_CLK_CFG 0x00000040 /* Common Clock Configuration */
-+#define PCIE_LCTLSTS_EXT_SYNC 0x00000080 /* Extended Synch */
-+#define PCIE_LCTLSTS_CLK_PM_EN 0x00000100 /* Enable Clock Powerm Management */
-+#define PCIE_LCTLSTS_LINK_SPEED 0x000F0000 /* Link Speed */
-+#define PCIE_LCTLSTS_LINK_SPEED_S 16
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH 0x03F00000 /* Negotiated Link Width */
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH_S 20
-+#define PCIE_LCTLSTS_RETRAIN_PENDING 0x08000000 /* Link training is ongoing */
-+#define PCIE_LCTLSTS_SLOT_CLK_CFG 0x10000000 /* Slot Clock Configuration */
-+#define PCIE_LCTLSTS_DLL_ACTIVE 0x20000000 /* Data Link Layer Active */
-+
-+/* Slot Capabilities Register */
-+#define PCIE_SLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x84)
-+
-+/* Slot Capabilities */
-+#define PCIE_SLCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x88)
-+
-+/* Root Control and Capability Register */
-+#define PCIE_RCTLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x8C)
-+#define PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR 0x00000001 /* #SERR on COR-ERR */
-+#define PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR 0x00000002 /* #SERR on Non-Fatal ERR */
-+#define PCIE_RCTLCAP_SERR_ON_FATAL_ERR 0x00000004 /* #SERR on Fatal ERR */
-+#define PCIE_RCTLCAP_PME_INT_EN 0x00000008 /* PME Interrupt Enable */
-+#define PCIE_RCTLCAP_SERR_ENABLE (PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR | \
-+ PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR | PCIE_RCTLCAP_SERR_ON_FATAL_ERR)
-+/* Root Status Register */
-+#define PCIE_RSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x90)
-+#define PCIE_RSTS_PME_REQ_ID 0x0000FFFF /* PME Request ID */
-+#define PCIE_RSTS_PME_REQ_ID_S 0
-+#define PCIE_RSTS_PME_STATUS 0x00010000 /* PME Status */
-+#define PCIE_RSTS_PME_PENDING 0x00020000 /* PME Pending */
-+
-+/* PCI Express Enhanced Capability Header */
-+#define PCIE_ENHANCED_CAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x100)
-+#define PCIE_ENHANCED_CAP_ID 0x0000FFFF /* PCI Express Extended Capability ID */
-+#define PCIE_ENHANCED_CAP_ID_S 0
-+#define PCIE_ENHANCED_CAP_VER 0x000F0000 /* Capability Version */
-+#define PCIE_ENHANCED_CAP_VER_S 16
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET 0xFFF00000 /* Next Capability Offset */
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET_S 20
-+
-+/* Uncorrectable Error Status Register */
-+#define PCIE_UES_R(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x104)
-+#define PCIE_DATA_LINK_PROTOCOL_ERR 0x00000010 /* Data Link Protocol Error Status */
-+#define PCIE_SURPRISE_DOWN_ERROR 0x00000020 /* Surprise Down Error Status */
-+#define PCIE_POISONED_TLP 0x00001000 /* Poisoned TLP Status */
-+#define PCIE_FC_PROTOCOL_ERR 0x00002000 /* Flow Control Protocol Error Status */
-+#define PCIE_COMPLETION_TIMEOUT 0x00004000 /* Completion Timeout Status */
-+#define PCIE_COMPLETOR_ABORT 0x00008000 /* Completer Abort Error */
-+#define PCIE_UNEXPECTED_COMPLETION 0x00010000 /* Unexpected Completion Status */
-+#define PCIE_RECEIVER_OVERFLOW 0x00020000 /* Receive Overflow Status */
-+#define PCIE_MALFORNED_TLP 0x00040000 /* Malformed TLP Stauts */
-+#define PCIE_ECRC_ERR 0x00080000 /* ECRC Error Stauts */
-+#define PCIE_UR_REQ 0x00100000 /* Unsupported Request Error Status */
-+#define PCIE_ALL_UNCORRECTABLE_ERR (PCIE_DATA_LINK_PROTOCOL_ERR | PCIE_SURPRISE_DOWN_ERROR | \
-+ PCIE_POISONED_TLP | PCIE_FC_PROTOCOL_ERR | PCIE_COMPLETION_TIMEOUT | \
-+ PCIE_COMPLETOR_ABORT | PCIE_UNEXPECTED_COMPLETION | PCIE_RECEIVER_OVERFLOW |\
-+ PCIE_MALFORNED_TLP | PCIE_ECRC_ERR | PCIE_UR_REQ)
-+
-+/* Uncorrectable Error Mask Register, Mask means no report */
-+#define PCIE_UEMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x108)
-+
-+/* Uncorrectable Error Severity Register */
-+#define PCIE_UESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10C)
-+
-+/* Correctable Error Status Register */
-+#define PCIE_CESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x110)
-+#define PCIE_RX_ERR 0x00000001 /* Receive Error Status */
-+#define PCIE_BAD_TLP 0x00000040 /* Bad TLP Status */
-+#define PCIE_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-+#define PCIE_REPLAY_NUM_ROLLOVER 0x00000100 /* Replay Number Rollover Status */
-+#define PCIE_REPLAY_TIMER_TIMEOUT_ERR 0x00001000 /* Reply Timer Timeout Status */
-+#define PCIE_ADVISORY_NONFTAL_ERR 0x00002000 /* Advisory Non-Fatal Error Status */
-+#define PCIE_CORRECTABLE_ERR (PCIE_RX_ERR | PCIE_BAD_TLP | PCIE_BAD_DLLP | PCIE_REPLAY_NUM_ROLLOVER |\
-+ PCIE_REPLAY_TIMER_TIMEOUT_ERR | PCIE_ADVISORY_NONFTAL_ERR)
-+
-+/* Correctable Error Mask Register */
-+#define PCIE_CEMR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x114)
-+
-+/* Advanced Error Capabilities and Control Register */
-+#define PCIE_AECCR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x118)
-+#define PCIE_AECCR_FIRST_ERR_PTR 0x0000001F /* First Error Pointer */
-+#define PCIE_AECCR_FIRST_ERR_PTR_S 0
-+#define PCIE_AECCR_ECRC_GEN_CAP 0x00000020 /* ECRC Generation Capable */
-+#define PCIE_AECCR_ECRC_GEN_EN 0x00000040 /* ECRC Generation Enable */
-+#define PCIE_AECCR_ECRC_CHECK_CAP 0x00000080 /* ECRC Check Capable */
-+#define PCIE_AECCR_ECRC_CHECK_EN 0x00000100 /* ECRC Check Enable */
-+
-+/* Header Log Register 1 */
-+#define PCIE_HLR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x11C)
-+
-+/* Header Log Register 2 */
-+#define PCIE_HLR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x120)
-+
-+/* Header Log Register 3 */
-+#define PCIE_HLR3(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x124)
-+
-+/* Header Log Register 4 */
-+#define PCIE_HLR4(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x128)
-+
-+/* Root Error Command Register */
-+#define PCIE_RECR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x12C)
-+#define PCIE_RECR_CORRECTABLE_ERR_REPORT_EN 0x00000001 /* COR-ERR */
-+#define PCIE_RECR_NONFATAL_ERR_REPORT_EN 0x00000002 /* Non-Fatal ERR */
-+#define PCIE_RECR_FATAL_ERR_REPORT_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_RECR_ERR_REPORT_EN (PCIE_RECR_CORRECTABLE_ERR_REPORT_EN | \
-+ PCIE_RECR_NONFATAL_ERR_REPORT_EN | PCIE_RECR_FATAL_ERR_REPORT_EN)
-+
-+/* Root Error Status Register */
-+#define PCIE_RESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x130)
-+#define PCIE_RESR_CORRECTABLE_ERR 0x00000001 /* COR-ERR Receveid */
-+#define PCIE_RESR_MULTI_CORRECTABLE_ERR 0x00000002 /* Multiple COR-ERR Received */
-+#define PCIE_RESR_FATAL_NOFATAL_ERR 0x00000004 /* ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_MULTI_FATAL_NOFATAL_ERR 0x00000008 /* Multiple ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_FIRST_UNCORRECTABLE_FATAL_ERR 0x00000010 /* First UN-COR Fatal */
-+#define PCIR_RESR_NON_FATAL_ERR 0x00000020 /* Non-Fatal Error Message Received */
-+#define PCIE_RESR_FATAL_ERR 0x00000040 /* Fatal Message Received */
-+#define PCIE_RESR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_RESR_AER_INT_MSG_NUM_S 27
-+
-+/* Error Source Indentification Register */
-+#define PCIE_ESIR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x134)
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID 0x0000FFFF
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID_S 0
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID 0xFFFF0000
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID_S 16
-+
-+/* VC Enhanced Capability Header */
-+#define PCIE_VC_ECH(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x140)
-+
-+/* Port VC Capability Register */
-+#define PCIE_PVC1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x144)
-+#define PCIE_PVC1_EXT_VC_CNT 0x00000007 /* Extended VC Count */
-+#define PCIE_PVC1_EXT_VC_CNT_S 0
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT 0x00000070 /* Low Priority Extended VC Count */
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT_S 4
-+#define PCIE_PVC1_REF_CLK 0x00000300 /* Reference Clock */
-+#define PCIE_PVC1_REF_CLK_S 8
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE 0x00000C00 /* Port Arbitration Table Entry Size */
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE_S 10
-+
-+/* Extended Virtual Channel Count Defintion */
-+#define PCIE_EXT_VC_CNT_MIN 0
-+#define PCIE_EXT_VC_CNT_MAX 7
-+
-+/* Port Arbitration Table Entry Size Definition */
-+enum {
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S1BIT = 0,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S2BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S4BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S8BIT,
-+};
-+
-+/* Port VC Capability Register 2 */
-+#define PCIE_PVC2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x148)
-+#define PCIE_PVC2_VC_ARB_16P_FIXED_WRR 0x00000001 /* HW Fixed arbitration, 16 phase WRR */
-+#define PCIE_PVC2_VC_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_PVC2_VC_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_PVC2_VC_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_PVC2_VC_ARB_WRR 0x0000000F
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET 0xFF000000 /* VC arbitration table offset, not support */
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET_S 24
-+
-+/* Port VC Control and Status Register */
-+#define PCIE_PVCCRSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14C)
-+#define PCIE_PVCCRSR_LOAD_VC_ARB_TAB 0x00000001 /* Load VC Arbitration Table */
-+#define PCIE_PVCCRSR_VC_ARB_SEL 0x0000000E /* VC Arbitration Select */
-+#define PCIE_PVCCRSR_VC_ARB_SEL_S 1
-+#define PCIE_PVCCRSR_VC_ARB_TAB_STATUS 0x00010000 /* Arbitration Status */
-+
-+/* VC0 Resource Capability Register */
-+#define PCIE_VC0_RC(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x150)
-+#define PCIE_VC0_RC_PORT_ARB_HW_FIXED 0x00000001 /* HW Fixed arbitration */
-+#define PCIE_VC0_RC_PORT_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_128P_WRR 0x00000010 /* Time-based 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_256P_WRR 0x00000020 /* Time-based 256 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB (PCIE_VC0_RC_PORT_ARB_HW_FIXED | PCIE_VC0_RC_PORT_ARB_32P_WRR |\
-+ PCIE_VC0_RC_PORT_ARB_64P_WRR | PCIE_VC0_RC_PORT_ARB_128P_WRR | \
-+ PCIE_VC0_RC_PORT_ARB_TM_128P_WRR | PCIE_VC0_RC_PORT_ARB_TM_256P_WRR)
-+
-+#define PCIE_VC0_RC_REJECT_SNOOP 0x00008000 /* Reject Snoop Transactioin */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS 0x007F0000 /* Maximum time Slots */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS_S 16
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET 0xFF000000 /* Port Arbitration Table Offset */
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET_S 24
-+
-+/* VC0 Resource Control Register */
-+#define PCIE_VC0_RC0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x154)
-+#define PCIE_VC0_RC0_TVM0 0x00000001 /* TC0 and VC0 */
-+#define PCIE_VC0_RC0_TVM1 0x00000002 /* TC1 and VC1 */
-+#define PCIE_VC0_RC0_TVM2 0x00000004 /* TC2 and VC2 */
-+#define PCIE_VC0_RC0_TVM3 0x00000008 /* TC3 and VC3 */
-+#define PCIE_VC0_RC0_TVM4 0x00000010 /* TC4 and VC4 */
-+#define PCIE_VC0_RC0_TVM5 0x00000020 /* TC5 and VC5 */
-+#define PCIE_VC0_RC0_TVM6 0x00000040 /* TC6 and VC6 */
-+#define PCIE_VC0_RC0_TVM7 0x00000080 /* TC7 and VC7 */
-+#define PCIE_VC0_RC0_TC_VC 0x000000FF /* TC/VC mask */
-+
-+#define PCIE_VC0_RC0_LOAD_PORT_ARB_TAB 0x00010000 /* Load Port Arbitration Table */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL 0x000E0000 /* Port Arbitration Select */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL_S 17
-+#define PCIE_VC0_RC0_VC_ID 0x07000000 /* VC ID */
-+#define PCIE_VC0_RC0_VC_ID_S 24
-+#define PCIE_VC0_RC0_VC_EN 0x80000000 /* VC Enable */
-+
-+/* VC0 Resource Status Register */
-+#define PCIE_VC0_RSR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x158)
-+#define PCIE_VC0_RSR0_PORT_ARB_TAB_STATUS 0x00010000 /* Port Arbitration Table Status,not used */
-+#define PCIE_VC0_RSR0_VC_NEG_PENDING 0x00020000 /* VC Negotiation Pending */
-+
-+/* Ack Latency Timer and Replay Timer Register */
-+#define PCIE_ALTRT(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x700)
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT 0x0000FFFF /* Round Trip Latency Time Limit */
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT_S 0
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT 0xFFFF0000 /* Replay Time Limit */
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT_S 16
-+
-+/* Other Message Register */
-+#define PCIE_OMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x704)
-+
-+/* Port Force Link Register */
-+#define PCIE_PFLR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x708)
-+#define PCIE_PFLR_LINK_NUM 0x000000FF /* Link Number */
-+#define PCIE_PFLR_LINK_NUM_S 0
-+#define PCIE_PFLR_FORCE_LINK 0x00008000 /* Force link */
-+#define PCIE_PFLR_LINK_STATE 0x003F0000 /* Link State */
-+#define PCIE_PFLR_LINK_STATE_S 16
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT 0xFF000000 /* Low Power Entrance Count, only for EP */
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT_S 24
-+
-+/* Ack Frequency Register */
-+#define PCIE_AFR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70C)
-+#define PCIE_AFR_AF 0x000000FF /* Ack Frequency */
-+#define PCIE_AFR_AF_S 0
-+#define PCIE_AFR_FTS_NUM 0x0000FF00 /* The number of Fast Training Sequence from L0S to L0 */
-+#define PCIE_AFR_FTS_NUM_S 8
-+#define PCIE_AFR_COM_FTS_NUM 0x00FF0000 /* N_FTS; when common clock is used*/
-+#define PCIE_AFR_COM_FTS_NUM_S 16
-+#define PCIE_AFR_L0S_ENTRY_LATENCY 0x07000000 /* L0s Entrance Latency */
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_S 24
-+#define PCIE_AFR_L1_ENTRY_LATENCY 0x38000000 /* L1 Entrance Latency */
-+#define PCIE_AFR_L1_ENTRY_LATENCY_S 27
-+#define PCIE_AFR_FTS_NUM_DEFAULT 32
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT 7
-+#define PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT 5
-+
-+/* Port Link Control Register */
-+#define PCIE_PLCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x710)
-+#define PCIE_PLCR_OTHER_MSG_REQ 0x00000001 /* Other Message Request */
-+#define PCIE_PLCR_SCRAMBLE_DISABLE 0x00000002 /* Scramble Disable */
-+#define PCIE_PLCR_LOOPBACK_EN 0x00000004 /* Loopback Enable */
-+#define PCIE_PLCR_LTSSM_HOT_RST 0x00000008 /* Force LTSSM to the hot reset */
-+#define PCIE_PLCR_DLL_LINK_EN 0x00000020 /* Enable Link initialization */
-+#define PCIE_PLCR_FAST_LINK_SIM_EN 0x00000080 /* Sets all internal timers to fast mode for simulation purposes */
-+#define PCIE_PLCR_LINK_MODE 0x003F0000 /* Link Mode Enable Mask */
-+#define PCIE_PLCR_LINK_MODE_S 16
-+#define PCIE_PLCR_CORRUPTED_CRC_EN 0x02000000 /* Enabled Corrupt CRC */
-+
-+/* Lane Skew Register */
-+#define PCIE_LSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x714)
-+#define PCIE_LSR_LANE_SKEW_NUM 0x00FFFFFF /* Insert Lane Skew for Transmit, not applicable */
-+#define PCIE_LSR_LANE_SKEW_NUM_S 0
-+#define PCIE_LSR_FC_DISABLE 0x01000000 /* Disable of Flow Control */
-+#define PCIE_LSR_ACKNAK_DISABLE 0x02000000 /* Disable of Ack/Nak */
-+#define PCIE_LSR_LANE_DESKEW_DISABLE 0x80000000 /* Disable of Lane-to-Lane Skew */
-+
-+/* Symbol Number Register */
-+#define PCIE_SNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x718)
-+#define PCIE_SNR_TS 0x0000000F /* Number of TS Symbol */
-+#define PCIE_SNR_TS_S 0
-+#define PCIE_SNR_SKP 0x00000700 /* Number of SKP Symbol */
-+#define PCIE_SNR_SKP_S 8
-+#define PCIE_SNR_REPLAY_TIMER 0x0007C000 /* Timer Modifier for Replay Timer */
-+#define PCIE_SNR_REPLAY_TIMER_S 14
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER 0x00F80000 /* Timer Modifier for Ack/Nak Latency Timer */
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER_S 19
-+#define PCIE_SNR_FC_TIMER 0x1F000000 /* Timer Modifier for Flow Control Watchdog Timer */
-+#define PCIE_SNR_FC_TIMER_S 28
-+
-+/* Symbol Timer Register and Filter Mask Register 1 */
-+#define PCIE_STRFMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x71C)
-+#define PCIE_STRFMR_SKP_INTERVAL 0x000007FF /* SKP lnterval Value */
-+#define PCIE_STRFMR_SKP_INTERVAL_S 0
-+#define PCIE_STRFMR_FC_WDT_DISABLE 0x00008000 /* Disable of FC Watchdog Timer */
-+#define PCIE_STRFMR_TLP_FUNC_MISMATCH_OK 0x00010000 /* Mask Function Mismatch Filtering for Incoming Requests */
-+#define PCIE_STRFMR_POISONED_TLP_OK 0x00020000 /* Mask Poisoned TLP Filtering */
-+#define PCIE_STRFMR_BAR_MATCH_OK 0x00040000 /* Mask BAR Match Filtering */
-+#define PCIE_STRFMR_TYPE1_CFG_REQ_OK 0x00080000 /* Mask Type 1 Configuration Request Filtering */
-+#define PCIE_STRFMR_LOCKED_REQ_OK 0x00100000 /* Mask Locked Request Filtering */
-+#define PCIE_STRFMR_CPL_TAG_ERR_RULES_OK 0x00200000 /* Mask Tag Error Rules for Received Completions */
-+#define PCIE_STRFMR_CPL_REQUESTOR_ID_MISMATCH_OK 0x00400000 /* Mask Requester ID Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_FUNC_MISMATCH_OK 0x00800000 /* Mask Function Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_TC_MISMATCH_OK 0x01000000 /* Mask Traffic Class Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_ATTR_MISMATCH_OK 0x02000000 /* Mask Attribute Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_LENGTH_MISMATCH_OK 0x04000000 /* Mask Length Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_TLP_ECRC_ERR_OK 0x08000000 /* Mask ECRC Error Filtering */
-+#define PCIE_STRFMR_CPL_TLP_ECRC_OK 0x10000000 /* Mask ECRC Error Filtering for Completions */
-+#define PCIE_STRFMR_RX_TLP_MSG_NO_DROP 0x20000000 /* Send Message TLPs */
-+#define PCIE_STRFMR_RX_IO_TRANS_ENABLE 0x40000000 /* Mask Filtering of received I/O Requests */
-+#define PCIE_STRFMR_RX_CFG_TRANS_ENABLE 0x80000000 /* Mask Filtering of Received Configuration Requests */
-+
-+#define PCIE_DEF_SKP_INTERVAL 700 /* 1180 ~1538 , 125MHz * 2, 250MHz * 1 */
-+
-+/* Filter Masker Register 2 */
-+#define PCIE_FMR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x720)
-+#define PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1 0x00000001 /* Mask RADM Filtering and Error Handling Rules */
-+#define PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 0x00000002 /* Mask RADM Filtering and Error Handling Rules */
-+
-+/* Debug Register 0 */
-+#define PCIE_DBR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x728)
-+
-+/* Debug Register 1 */
-+#define PCIE_DBR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x72C)
-+
-+/* Transmit Posted FC Credit Status Register */
-+#define PCIE_TPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x730)
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS 0x00000FFF /* Transmit Posted Data FC Credits */
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS_S 0
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS 0x000FF000 /* Transmit Posted Header FC Credits */
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Non-Posted FC Credit Status */
-+#define PCIE_TNPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x734)
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS 0x00000FFF /* Transmit Non-Posted Data FC Credits */
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS_S 0
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS 0x000FF000 /* Transmit Non-Posted Header FC Credits */
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Complete FC Credit Status Register */
-+#define PCIE_TCFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x738)
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS 0x00000FFF /* Transmit Completion Data FC Credits */
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS_S 0
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS 0x000FF000 /* Transmit Completion Header FC Credits */
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS_S 12
-+
-+/* Queue Status Register */
-+#define PCIE_QSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x73C)
-+#define PCIE_QSR_WAIT_UPDATE_FC_DLL 0x00000001 /* Received TLP FC Credits Not Returned */
-+#define PCIE_QSR_TX_RETRY_BUF_NOT_EMPTY 0x00000002 /* Transmit Retry Buffer Not Empty */
-+#define PCIE_QSR_RX_QUEUE_NOT_EMPTY 0x00000004 /* Received Queue Not Empty */
-+
-+/* VC Transmit Arbitration Register 1 */
-+#define PCIE_VCTAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x740)
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC0 0x000000FF /* WRR Weight for VC0 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC1 0x0000FF00 /* WRR Weight for VC1 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC2 0x00FF0000 /* WRR Weight for VC2 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC3 0xFF000000 /* WRR Weight for VC3 */
-+
-+/* VC Transmit Arbitration Register 2 */
-+#define PCIE_VCTAR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x744)
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC4 0x000000FF /* WRR Weight for VC4 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC5 0x0000FF00 /* WRR Weight for VC5 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC6 0x00FF0000 /* WRR Weight for VC6 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC7 0xFF000000 /* WRR Weight for VC7 */
-+
-+/* VC0 Posted Receive Queue Control Register */
-+#define PCIE_VC0_PRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x748)
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS 0x00000FFF /* VC0 Posted Data Credits */
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS_S 0
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS 0x000FF000 /* VC0 Posted Header Credits */
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS_S 12
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE 0x00E00000 /* VC0 Posted TLP Queue Mode */
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE_S 20
-+#define PCIE_VC0_PRQCR_TLP_RELAX_ORDER 0x40000000 /* TLP Type Ordering for VC0 */
-+#define PCIE_VC0_PRQCR_VC_STRICT_ORDER 0x80000000 /* VC0 Ordering for Receive Queues */
-+
-+/* VC0 Non-Posted Receive Queue Control */
-+#define PCIE_VC0_NPRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74C)
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS 0x00000FFF /* VC0 Non-Posted Data Credits */
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS_S 0
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS 0x000FF000 /* VC0 Non-Posted Header Credits */
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS_S 12
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE 0x00E00000 /* VC0 Non-Posted TLP Queue Mode */
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE_S 20
-+
-+/* VC0 Completion Receive Queue Control */
-+#define PCIE_VC0_CRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x750)
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS 0x00000FFF /* VC0 Completion TLP Queue Mode */
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS_S 0
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS 0x000FF000 /* VC0 Completion Header Credits */
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS_S 12
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE 0x00E00000 /* VC0 Completion Data Credits */
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE_S 21
-+
-+/* Applicable to the above three registers */
-+enum {
-+ PCIE_VC0_TLP_QUEUE_MODE_STORE_FORWARD = 1,
-+ PCIE_VC0_TLP_QUEUE_MODE_CUT_THROUGH = 2,
-+ PCIE_VC0_TLP_QUEUE_MODE_BYPASS = 4,
-+};
-+
-+/* VC0 Posted Buffer Depth Register */
-+#define PCIE_VC0_PBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7A8)
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Posted Data Queue Depth */
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Posted Header Queue Depth */
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Non-Posted Buffer Depth Register */
-+#define PCIE_VC0_NPBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7AC)
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Non-Posted Data Queue Depth */
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Non-Posted Header Queue Depth */
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Completion Buffer Depth Register */
-+#define PCIE_VC0_CBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7B0)
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES 0x00003FFF /* C0 Completion Data Queue Depth */
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Completion Header Queue Depth */
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES_S 16
-+
-+/* PHY Status Register, all zeros in VR9 */
-+#define PCIE_PHYSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x810)
-+
-+/* PHY Control Register, all zeros in VR9 */
-+#define PCIE_PHYCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x814)
-+
-+/*
-+ * PCIe PDI PHY register definition, suppose all the following
-+ * stuff is confidential.
-+ * XXX, detailed bit definition
-+ */
-+#define PCIE_PHY_PLL_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x22 << 1))
-+#define PCIE_PHY_PLL_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x23 << 1))
-+#define PCIE_PHY_PLL_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x24 << 1))
-+#define PCIE_PHY_PLL_CTRL4(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x25 << 1))
-+#define PCIE_PHY_PLL_CTRL5(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x26 << 1))
-+#define PCIE_PHY_PLL_CTRL6(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x27 << 1))
-+#define PCIE_PHY_PLL_CTRL7(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x28 << 1))
-+#define PCIE_PHY_PLL_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x29 << 1))
-+#define PCIE_PHY_PLL_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2A << 1))
-+#define PCIE_PHY_PLL_A_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2B << 1))
-+#define PCIE_PHY_PLL_STATUS(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2C << 1))
-+
-+#define PCIE_PHY_TX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x30 << 1))
-+#define PCIE_PHY_TX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x31 << 1))
-+#define PCIE_PHY_TX1_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x32 << 1))
-+#define PCIE_PHY_TX1_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x33 << 1))
-+#define PCIE_PHY_TX1_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x34 << 1))
-+#define PCIE_PHY_TX1_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x35 << 1))
-+#define PCIE_PHY_TX1_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x36 << 1))
-+#define PCIE_PHY_TX1_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x37 << 1))
-+
-+#define PCIE_PHY_TX2_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x38 << 1))
-+#define PCIE_PHY_TX2_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x39 << 1))
-+#define PCIE_PHY_TX2_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3B << 1))
-+#define PCIE_PHY_TX2_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3C << 1))
-+#define PCIE_PHY_TX2_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3D << 1))
-+#define PCIE_PHY_TX2_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3E << 1))
-+#define PCIE_PHY_TX2_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3F << 1))
-+
-+#define PCIE_PHY_RX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x50 << 1))
-+#define PCIE_PHY_RX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x51 << 1))
-+#define PCIE_PHY_RX1_CDR(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x52 << 1))
-+#define PCIE_PHY_RX1_EI(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x53 << 1))
-+#define PCIE_PHY_RX1_A_CTRL(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x55 << 1))
-+
-+/* Interrupt related stuff */
-+#define PCIE_LEGACY_DISABLE 0
-+#define PCIE_LEGACY_INTA 1
-+#define PCIE_LEGACY_INTB 2
-+#define PCIE_LEGACY_INTC 3
-+#define PCIE_LEGACY_INTD 4
-+#define PCIE_LEGACY_INT_MAX PCIE_LEGACY_INTD
-+
-+#define PCIE_IRQ_LOCK(lock) do { \
-+ unsigned long flags; \
-+ spin_lock_irqsave(&(lock), flags);
-+#define PCIE_IRQ_UNLOCK(lock) \
-+ spin_unlock_irqrestore(&(lock), flags); \
-+} while (0)
-+
-+#define PCIE_MSG_MSI 0x00000001
-+#define PCIE_MSG_ISR 0x00000002
-+#define PCIE_MSG_FIXUP 0x00000004
-+#define PCIE_MSG_READ_CFG 0x00000008
-+#define PCIE_MSG_WRITE_CFG 0x00000010
-+#define PCIE_MSG_CFG (PCIE_MSG_READ_CFG | PCIE_MSG_WRITE_CFG)
-+#define PCIE_MSG_REG 0x00000020
-+#define PCIE_MSG_INIT 0x00000040
-+#define PCIE_MSG_ERR 0x00000080
-+#define PCIE_MSG_PHY 0x00000100
-+#define PCIE_MSG_ANY 0x000001ff
-+
-+#define IFX_PCIE_PORT0 0
-+#define IFX_PCIE_PORT1 1
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+#define IFX_PCIE_CORE_NR 2
-+#else
-+#define IFX_PCIE_CORE_NR 1
-+#endif
-+
-+//#define IFX_PCIE_ERROR_INT
-+
-+//#define IFX_PCIE_DBG
-+
-+#if defined(IFX_PCIE_DBG)
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) do { \
-+ if (g_pcie_debug_flag & (_m)) { \
-+ ifx_pcie_debug((_fmt), ##args); \
-+ } \
-+} while (0)
-+
-+#define INLINE
-+#else
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) \
-+ do {} while(0)
-+#define INLINE inline
-+#endif
-+
-+struct ifx_pci_controller {
-+ struct pci_controller pcic;
-+
-+ /* RC specific, per host bus information */
-+ u32 port; /* Port index, 0 -- 1st core, 1 -- 2nd core */
-+};
-+
-+typedef struct ifx_pcie_ir_irq {
-+ const unsigned int irq;
-+ const char name[16];
-+}ifx_pcie_ir_irq_t;
-+
-+typedef struct ifx_pcie_legacy_irq{
-+ const u32 irq_bit;
-+ const int irq;
-+}ifx_pcie_legacy_irq_t;
-+
-+typedef struct ifx_pcie_irq {
-+ ifx_pcie_ir_irq_t ir_irq;
-+ ifx_pcie_legacy_irq_t legacy_irq[PCIE_LEGACY_INT_MAX];
-+}ifx_pcie_irq_t;
-+
-+extern u32 g_pcie_debug_flag;
-+extern void ifx_pcie_debug(const char *fmt, ...);
-+extern void pcie_phy_clock_mode_setup(int pcie_port);
-+extern void pcie_msi_pic_init(int pcie_port);
-+extern u32 ifx_pcie_bus_enum_read_hack(int where, u32 value);
-+extern u32 ifx_pcie_bus_enum_write_hack(int where, u32 value);
-+
-+
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+#include <linux/gpio.h>
-+#include <linux/clk.h>
-+
-+#include <lantiq_soc.h>
-+
-+#define IFX_PCIE_GPIO_RESET 38
-+#define IFX_REG_R32 ltq_r32
-+#define IFX_REG_W32 ltq_w32
-+#define CONFIG_IFX_PCIE_HW_SWAP
-+#define IFX_RCU_AHB_ENDIAN ((volatile u32*)(IFX_RCU + 0x004C))
-+#define IFX_RCU_RST_REQ ((volatile u32*)(IFX_RCU + 0x0010))
-+#define IFX_RCU_AHB_BE_PCIE_PDI 0x00000080 /* Configure PCIE PDI module in big endian*/
-+
-+#define IFX_RCU (KSEG1 | 0x1F203000)
-+#define IFX_RCU_AHB_BE_PCIE_M 0x00000001 /* Configure AHB master port that connects to PCIe RC in big endian */
-+#define IFX_RCU_AHB_BE_PCIE_S 0x00000010 /* Configure AHB slave port that connects to PCIe RC in little endian */
-+#define IFX_RCU_AHB_BE_XBAR_M 0x00000002 /* Configure AHB master port that connects to XBAR in big endian */
-+#define CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+
-+#define IFX_PMU1_MODULE_PCIE_PHY (0)
-+#define IFX_PMU1_MODULE_PCIE_CTRL (1)
-+#define IFX_PMU1_MODULE_PDI (4)
-+#define IFX_PMU1_MODULE_MSI (5)
-+
-+#define IFX_PMU_MODULE_PCIE_L0_CLK (31)
-+
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "ahb");
-+ clk_enable(clk);
-+ //ltq_pmu_enable(PMU_AHBM | PMU_AHBS);
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg |= IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#else
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "phy");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1<<IFX_PMU1_MODULE_PCIE_PHY);
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "phy");
-+ clk_disable(clk);
-+ //ltq_pmu1_disable(1<<IFX_PMU1_MODULE_PCIE_PHY);
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* SRAM2PDI endianness control. */
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "pdi");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1<<IFX_PMU1_MODULE_PDI);
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-+ reg |= 0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ /* Reset PCIe PHY & Core, bit 22 */
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg |= 0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
-+ // ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+// ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "ctl");
-+ clk_enable(clk);
-+ clk = clk_get_sys("ltq_pcie", "bus");
-+ clk_enable(clk);
-+
-+ //ltq_pmu1_enable(1 << IFX_PMU1_MODULE_PCIE_CTRL);
-+ //ltq_pmu_enable(1 << IFX_PMU_MODULE_PCIE_L0_CLK);
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ struct clk *clk;
-+ pcie_msi_pic_init(pcie_port);
-+ clk = clk_get_sys("ltq_pcie", "msi");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1 << IFX_PMU1_MODULE_MSI);
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+#endif /* CONFIG_PCI_LANTIQ */
-+ return tbus_number;
-+}
-+
-+static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ #endif /* CONFIG_PCI_LANTIQ */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_VR9_H */
-+
---- a/drivers/pci/pcie/Kconfig
-+++ b/drivers/pci/pcie/Kconfig
-@@ -51,6 +51,7 @@ config PCIEAER_INJECT
- config PCIE_ECRC
- bool "PCI Express ECRC settings control"
- depends on PCIEAER
-+ default n
- help
- Used to override firmware/bios settings for PCI Express ECRC
- (transaction layer end-to-end CRC checking).
---- a/include/linux/pci.h
-+++ b/include/linux/pci.h
-@@ -1483,6 +1483,8 @@ void pci_walk_bus(struct pci_bus *top, i
- void *userdata);
- int pci_cfg_space_size(struct pci_dev *dev);
- unsigned char pci_bus_max_busnr(struct pci_bus *bus);
-+int pcibios_host_nr(void);
-+int pcibios_1st_host_bus_nr(void);
- void pci_setup_bridge(struct pci_bus *bus);
- resource_size_t pcibios_window_alignment(struct pci_bus *bus,
- unsigned long type);
---- a/include/linux/pci_ids.h
-+++ b/include/linux/pci_ids.h
-@@ -1086,6 +1086,12 @@
- #define PCI_DEVICE_ID_SGI_IOC3 0x0003
- #define PCI_DEVICE_ID_SGI_LITHIUM 0x1002
-
-+#define PCI_VENDOR_ID_INFINEON 0x15D1
-+#define PCI_DEVICE_ID_INFINEON_DANUBE 0x000F
-+#define PCI_DEVICE_ID_INFINEON_PCIE 0x0011
-+#define PCI_VENDOR_ID_LANTIQ 0x1BEF
-+#define PCI_DEVICE_ID_LANTIQ_PCIE 0x0011
-+
- #define PCI_VENDOR_ID_WINBOND 0x10ad
- #define PCI_DEVICE_ID_WINBOND_82C105 0x0105
- #define PCI_DEVICE_ID_WINBOND_83C553 0x0565
diff --git a/target/linux/lantiq/patches-5.15/0004-MIPS-lantiq-add-atm-hack.patch b/target/linux/lantiq/patches-5.15/0004-MIPS-lantiq-add-atm-hack.patch
deleted file mode 100644
index e32e4e2daa..0000000000
--- a/target/linux/lantiq/patches-5.15/0004-MIPS-lantiq-add-atm-hack.patch
+++ /dev/null
@@ -1,482 +0,0 @@
-From 9afadf01b1be371ee88491819aa67364684461f9 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 3 Aug 2012 10:27:25 +0200
-Subject: [PATCH 04/36] MIPS: lantiq: add atm hack
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/include/asm/mach-lantiq/lantiq_atm.h | 196 +++++++++++++++++++++++
- arch/mips/include/asm/mach-lantiq/lantiq_ptm.h | 203 ++++++++++++++++++++++++
- arch/mips/lantiq/irq.c | 2 +
- arch/mips/mm/cache.c | 4 +
- include/uapi/linux/atm.h | 6 +
- net/atm/common.c | 6 +
- net/atm/proc.c | 2 +-
- 7 files changed, 416 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_atm.h
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_atm.h
-@@ -0,0 +1,196 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifx_atm.h
-+** PROJECT : UEIP
-+** MODULES : ATM
-+**
-+** DATE : 17 Jun 2009
-+** AUTHOR : Xu Liang
-+** DESCRIPTION : Global ATM driver header file
-+** COPYRIGHT : Copyright (c) 2006
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 07 JUL 2009 Xu Liang Init Version
-+*******************************************************************************/
-+
-+#ifndef IFX_ATM_H
-+#define IFX_ATM_H
-+
-+
-+
-+/*!
-+ \defgroup IFX_ATM UEIP Project - ATM driver module
-+ \brief UEIP Project - ATM driver module, support Danube, Amazon-SE, AR9, VR9.
-+ */
-+
-+/*!
-+ \defgroup IFX_ATM_IOCTL IOCTL Commands
-+ \ingroup IFX_ATM
-+ \brief IOCTL Commands used by user application.
-+ */
-+
-+/*!
-+ \defgroup IFX_ATM_STRUCT Structures
-+ \ingroup IFX_ATM
-+ \brief Structures used by user application.
-+ */
-+
-+/*!
-+ \file ifx_atm.h
-+ \ingroup IFX_ATM
-+ \brief ATM driver header file
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_ATM_STRUCT
-+ */
-+/*@{*/
-+
-+/*
-+ * ATM MIB
-+ */
-+
-+/*!
-+ \struct atm_cell_ifEntry_t
-+ \brief Structure used for Cell Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_CELL".
-+ */
-+typedef struct {
-+ __u32 ifHCInOctets_h; /*!< byte counter of ingress cells (upper 32 bits, total 64 bits) */
-+ __u32 ifHCInOctets_l; /*!< byte counter of ingress cells (lower 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_h; /*!< byte counter of egress cells (upper 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_l; /*!< byte counter of egress cells (lower 32 bits, total 64 bits) */
-+ __u32 ifInErrors; /*!< counter of error ingress cells */
-+ __u32 ifInUnknownProtos; /*!< counter of unknown ingress cells */
-+ __u32 ifOutErrors; /*!< counter of error egress cells */
-+} atm_cell_ifEntry_t;
-+
-+/*!
-+ \struct atm_aal5_ifEntry_t
-+ \brief Structure used for AAL5 Frame Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_AAL5".
-+ */
-+typedef struct {
-+ __u32 ifHCInOctets_h; /*!< byte counter of ingress packets (upper 32 bits, total 64 bits) */
-+ __u32 ifHCInOctets_l; /*!< byte counter of ingress packets (lower 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_h; /*!< byte counter of egress packets (upper 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_l; /*!< byte counter of egress packets (lower 32 bits, total 64 bits) */
-+ __u32 ifInUcastPkts; /*!< counter of ingress packets */
-+ __u32 ifOutUcastPkts; /*!< counter of egress packets */
-+ __u32 ifInErrors; /*!< counter of error ingress packets */
-+ __u32 ifInDiscards; /*!< counter of dropped ingress packets */
-+ __u32 ifOutErros; /*!< counter of error egress packets */
-+ __u32 ifOutDiscards; /*!< counter of dropped egress packets */
-+} atm_aal5_ifEntry_t;
-+
-+/*!
-+ \struct atm_aal5_vcc_t
-+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
-+
-+ This structure is a part of structure "atm_aal5_vcc_x_t".
-+ */
-+typedef struct {
-+ __u32 aal5VccCrcErrors; /*!< counter of ingress packets with CRC error */
-+ __u32 aal5VccSarTimeOuts; /*!< counter of ingress packets with Re-assemble timeout */ //no timer support yet
-+ __u32 aal5VccOverSizedSDUs; /*!< counter of oversized ingress packets */
-+} atm_aal5_vcc_t;
-+
-+/*!
-+ \struct atm_aal5_vcc_x_t
-+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_VCC".
-+ */
-+typedef struct {
-+ int vpi; /*!< VPI of the VCC to get MIB counters */
-+ int vci; /*!< VCI of the VCC to get MIB counters */
-+ atm_aal5_vcc_t mib_vcc; /*!< structure to get MIB counters */
-+} atm_aal5_vcc_x_t;
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * IOCTL
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_ATM_IOCTL
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Command
-+ */
-+/*!
-+ \brief ATM IOCTL Magic Number
-+ */
-+#define PPE_ATM_IOC_MAGIC 'o'
-+/*!
-+ \brief ATM IOCTL Command - Get Cell Level MIB Counters
-+
-+ This command is obsolete. User can get cell level MIB from DSL API.
-+ This command uses structure "atm_cell_ifEntry_t" as parameter for output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_CELL _IOW(PPE_ATM_IOC_MAGIC, 0, atm_cell_ifEntry_t)
-+/*!
-+ \brief ATM IOCTL Command - Get AAL5 Level MIB Counters
-+
-+ Get AAL5 packet counters.
-+ This command uses structure "atm_aal5_ifEntry_t" as parameter for output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_AAL5 _IOW(PPE_ATM_IOC_MAGIC, 1, atm_aal5_ifEntry_t)
-+/*!
-+ \brief ATM IOCTL Command - Get Per PVC MIB Counters
-+
-+ Get AAL5 packet counters for each PVC.
-+ This command uses structure "atm_aal5_vcc_x_t" as parameter for input of VPI/VCI information and output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_VCC _IOWR(PPE_ATM_IOC_MAGIC, 2, atm_aal5_vcc_x_t)
-+/*!
-+ \brief Total Number of ATM IOCTL Commands
-+ */
-+#define PPE_ATM_IOC_MAXNR 3
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * API
-+ * ####################################
-+ */
-+
-+#ifdef __KERNEL__
-+struct port_cell_info {
-+ unsigned int port_num;
-+ unsigned int tx_link_rate[2];
-+};
-+#endif
-+
-+
-+
-+#endif // IFX_ATM_H
-+
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
-@@ -0,0 +1,203 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifx_ptm.h
-+** PROJECT : UEIP
-+** MODULES : PTM
-+**
-+** DATE : 17 Jun 2009
-+** AUTHOR : Xu Liang
-+** DESCRIPTION : Global PTM driver header file
-+** COPYRIGHT : Copyright (c) 2006
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 07 JUL 2009 Xu Liang Init Version
-+*******************************************************************************/
-+
-+#ifndef IFX_PTM_H
-+#define IFX_PTM_H
-+
-+
-+
-+/*!
-+ \defgroup IFX_PTM UEIP Project - PTM driver module
-+ \brief UEIP Project - PTM driver module, support Danube, Amazon-SE, AR9, VR9.
-+ */
-+
-+/*!
-+ \defgroup IFX_PTM_IOCTL IOCTL Commands
-+ \ingroup IFX_PTM
-+ \brief IOCTL Commands used by user application.
-+ */
-+
-+/*!
-+ \defgroup IFX_PTM_STRUCT Structures
-+ \ingroup IFX_PTM
-+ \brief Structures used by user application.
-+ */
-+
-+/*!
-+ \file ifx_ptm.h
-+ \ingroup IFX_PTM
-+ \brief PTM driver header file
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * IOCTL
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_PTM_IOCTL
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Command
-+ */
-+/*!
-+ \brief PTM IOCTL Command - Get codeword MIB counters.
-+
-+ This command uses structure "PTM_CW_IF_ENTRY_T" to get codeword level MIB counters.
-+ */
-+#define IFX_PTM_MIB_CW_GET SIOCDEVPRIVATE + 1
-+/*!
-+ \brief PTM IOCTL Command - Get packet MIB counters.
-+
-+ This command uses structure "PTM_FRAME_MIB_T" to get packet level MIB counters.
-+ */
-+#define IFX_PTM_MIB_FRAME_GET SIOCDEVPRIVATE + 2
-+/*!
-+ \brief PTM IOCTL Command - Get firmware configuration (CRC).
-+
-+ This command uses structure "IFX_PTM_CFG_T" to get firmware configuration (CRC).
-+ */
-+#define IFX_PTM_CFG_GET SIOCDEVPRIVATE + 3
-+/*!
-+ \brief PTM IOCTL Command - Set firmware configuration (CRC).
-+
-+ This command uses structure "IFX_PTM_CFG_T" to set firmware configuration (CRC).
-+ */
-+#define IFX_PTM_CFG_SET SIOCDEVPRIVATE + 4
-+/*!
-+ \brief PTM IOCTL Command - Program priority value to TX queue mapping.
-+
-+ This command uses structure "IFX_PTM_PRIO_Q_MAP_T" to program priority value to TX queue mapping.
-+ */
-+#define IFX_PTM_MAP_PKT_PRIO_TO_Q SIOCDEVPRIVATE + 14
-+
-+/*@}*/
-+
-+
-+/*!
-+ \addtogroup IFX_PTM_STRUCT
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Data Type
-+ */
-+
-+/*!
-+ \typedef PTM_CW_IF_ENTRY_T
-+ \brief Wrapping of structure "ptm_cw_ifEntry_t".
-+ */
-+/*!
-+ \struct ptm_cw_ifEntry_t
-+ \brief Structure used for CodeWord level MIB counters.
-+ */
-+typedef struct ptm_cw_ifEntry_t {
-+ uint32_t ifRxNoIdleCodewords; /*!< output, number of ingress user codeword */
-+ uint32_t ifRxIdleCodewords; /*!< output, number of ingress idle codeword */
-+ uint32_t ifRxCodingViolation; /*!< output, number of error ingress codeword */
-+ uint32_t ifTxNoIdleCodewords; /*!< output, number of egress user codeword */
-+ uint32_t ifTxIdleCodewords; /*!< output, number of egress idle codeword */
-+} PTM_CW_IF_ENTRY_T;
-+
-+/*!
-+ \typedef PTM_FRAME_MIB_T
-+ \brief Wrapping of structure "ptm_frame_mib_t".
-+ */
-+/*!
-+ \struct ptm_frame_mib_t
-+ \brief Structure used for packet level MIB counters.
-+ */
-+typedef struct ptm_frame_mib_t {
-+ uint32_t RxCorrect; /*!< output, number of ingress packet */
-+ uint32_t TC_CrcError; /*!< output, number of egress packet with CRC error */
-+ uint32_t RxDropped; /*!< output, number of dropped ingress packet */
-+ uint32_t TxSend; /*!< output, number of egress packet */
-+} PTM_FRAME_MIB_T;
-+
-+/*!
-+ \typedef IFX_PTM_CFG_T
-+ \brief Wrapping of structure "ptm_cfg_t".
-+ */
-+/*!
-+ \struct ptm_cfg_t
-+ \brief Structure used for ETH/TC CRC configuration.
-+ */
-+typedef struct ptm_cfg_t {
-+ uint32_t RxEthCrcPresent; /*!< input/output, ingress packet has ETH CRC */
-+ uint32_t RxEthCrcCheck; /*!< input/output, check ETH CRC of ingress packet */
-+ uint32_t RxTcCrcCheck; /*!< input/output, check TC CRC of ingress codeword */
-+ uint32_t RxTcCrcLen; /*!< input/output, length of TC CRC of ingress codeword */
-+ uint32_t TxEthCrcGen; /*!< input/output, generate ETH CRC for egress packet */
-+ uint32_t TxTcCrcGen; /*!< input/output, generate TC CRC for egress codeword */
-+ uint32_t TxTcCrcLen; /*!< input/output, length of TC CRC of egress codeword */
-+} IFX_PTM_CFG_T;
-+
-+/*!
-+ \typedef IFX_PTM_PRIO_Q_MAP_T
-+ \brief Wrapping of structure "ppe_prio_q_map".
-+ */
-+/*!
-+ \struct ppe_prio_q_map
-+ \brief Structure used for Priority Value to TX Queue mapping.
-+ */
-+typedef struct ppe_prio_q_map {
-+ int pkt_prio;
-+ int qid;
-+ int vpi; // ignored in eth interface
-+ int vci; // ignored in eth interface
-+} IFX_PTM_PRIO_Q_MAP_T;
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * API
-+ * ####################################
-+ */
-+
-+#ifdef __KERNEL__
-+struct port_cell_info {
-+ unsigned int port_num;
-+ unsigned int tx_link_rate[2];
-+};
-+#endif
-+
-+
-+
-+#endif // IFX_PTM_H
-+
---- a/arch/mips/lantiq/irq.c
-+++ b/arch/mips/lantiq/irq.c
-@@ -13,6 +13,7 @@
- #include <linux/of_platform.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
-+#include <linux/module.h>
-
- #include <asm/bootinfo.h>
- #include <asm/irq_cpu.h>
-@@ -92,6 +93,7 @@ void ltq_disable_irq(struct irq_data *d)
- }
- raw_spin_unlock_irqrestore(&ltq_icu_lock, flags);
- }
-+EXPORT_SYMBOL(ltq_mask_and_ack_irq);
-
- void ltq_mask_and_ack_irq(struct irq_data *d)
- {
---- a/arch/mips/mm/cache.c
-+++ b/arch/mips/mm/cache.c
-@@ -63,6 +63,10 @@ void (*_dma_cache_wback_inv)(unsigned lo
- void (*_dma_cache_wback)(unsigned long start, unsigned long size);
- void (*_dma_cache_inv)(unsigned long start, unsigned long size);
-
-+EXPORT_SYMBOL(_dma_cache_wback_inv);
-+EXPORT_SYMBOL(_dma_cache_wback);
-+EXPORT_SYMBOL(_dma_cache_inv);
-+
- #endif /* CONFIG_DMA_NONCOHERENT */
-
- /*
---- a/include/uapi/linux/atm.h
-+++ b/include/uapi/linux/atm.h
-@@ -131,8 +131,14 @@
- #define ATM_ABR 4
- #define ATM_ANYCLASS 5 /* compatible with everything */
-
-+#define ATM_VBR_NRT ATM_VBR
-+#define ATM_VBR_RT 6
-+#define ATM_UBR_PLUS 7
-+#define ATM_GFR 8
-+
- #define ATM_MAX_PCR -1 /* maximum available PCR */
-
-+
- struct atm_trafprm {
- unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */
- int max_pcr; /* maximum PCR in cells per second */
---- a/net/atm/proc.c
-+++ b/net/atm/proc.c
-@@ -141,7 +141,7 @@ static void *vcc_seq_next(struct seq_fil
- static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
- {
- static const char *const class_name[] = {
-- "off", "UBR", "CBR", "VBR", "ABR"};
-+ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"};
- static const char *const aal_name[] = {
- "---", "1", "2", "3/4", /* 0- 3 */
- "???", "5", "???", "???", /* 4- 7 */
diff --git a/target/linux/lantiq/patches-5.15/0008-MIPS-lantiq-backport-old-timer-code.patch b/target/linux/lantiq/patches-5.15/0008-MIPS-lantiq-backport-old-timer-code.patch
deleted file mode 100644
index 3e6c267685..0000000000
--- a/target/linux/lantiq/patches-5.15/0008-MIPS-lantiq-backport-old-timer-code.patch
+++ /dev/null
@@ -1,1076 +0,0 @@
-From 94800350cb8d2f29dda2206b5e9a3772024ee168 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:30:56 +0200
-Subject: [PATCH 08/36] MIPS: lantiq: backport old timer code
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/include/asm/mach-lantiq/lantiq_timer.h | 155 ++++
- arch/mips/lantiq/xway/Makefile | 2 +-
- arch/mips/lantiq/xway/timer.c | 845 ++++++++++++++++++++++
- 3 files changed, 1001 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_timer.h
- create mode 100644 arch/mips/lantiq/xway/timer.c
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_timer.h
-@@ -0,0 +1,155 @@
-+#ifndef __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
-+#define __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
-+
-+
-+/******************************************************************************
-+ Copyright (c) 2002, Infineon Technologies. All rights reserved.
-+
-+ No Warranty
-+ 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.
-+
-+ 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.
-+******************************************************************************/
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+/*
-+ * Available Timer/Counter Index
-+ */
-+#define TIMER(n, X) (n * 2 + (X ? 1 : 0))
-+#define TIMER_ANY 0x00
-+#define TIMER1A TIMER(1, 0)
-+#define TIMER1B TIMER(1, 1)
-+#define TIMER2A TIMER(2, 0)
-+#define TIMER2B TIMER(2, 1)
-+#define TIMER3A TIMER(3, 0)
-+#define TIMER3B TIMER(3, 1)
-+
-+/*
-+ * Flag of Timer/Counter
-+ * These flags specify the way in which timer is configured.
-+ */
-+/* Bit size of timer/counter. */
-+#define TIMER_FLAG_16BIT 0x0000
-+#define TIMER_FLAG_32BIT 0x0001
-+/* Switch between timer and counter. */
-+#define TIMER_FLAG_TIMER 0x0000
-+#define TIMER_FLAG_COUNTER 0x0002
-+/* Stop or continue when overflowing/underflowing. */
-+#define TIMER_FLAG_ONCE 0x0000
-+#define TIMER_FLAG_CYCLIC 0x0004
-+/* Count up or counter down. */
-+#define TIMER_FLAG_UP 0x0000
-+#define TIMER_FLAG_DOWN 0x0008
-+/* Count on specific level or edge. */
-+#define TIMER_FLAG_HIGH_LEVEL_SENSITIVE 0x0000
-+#define TIMER_FLAG_LOW_LEVEL_SENSITIVE 0x0040
-+#define TIMER_FLAG_RISE_EDGE 0x0010
-+#define TIMER_FLAG_FALL_EDGE 0x0020
-+#define TIMER_FLAG_ANY_EDGE 0x0030
-+/* Signal is syncronous to module clock or not. */
-+#define TIMER_FLAG_UNSYNC 0x0000
-+#define TIMER_FLAG_SYNC 0x0080
-+/* Different interrupt handle type. */
-+#define TIMER_FLAG_NO_HANDLE 0x0000
-+#if defined(__KERNEL__)
-+ #define TIMER_FLAG_CALLBACK_IN_IRQ 0x0100
-+#endif // defined(__KERNEL__)
-+#define TIMER_FLAG_SIGNAL 0x0300
-+/* Internal clock source or external clock source */
-+#define TIMER_FLAG_INT_SRC 0x0000
-+#define TIMER_FLAG_EXT_SRC 0x1000
-+
-+
-+/*
-+ * ioctl Command
-+ */
-+#define GPTU_REQUEST_TIMER 0x01 /* General method to setup timer/counter. */
-+#define GPTU_FREE_TIMER 0x02 /* Free timer/counter. */
-+#define GPTU_START_TIMER 0x03 /* Start or resume timer/counter. */
-+#define GPTU_STOP_TIMER 0x04 /* Suspend timer/counter. */
-+#define GPTU_GET_COUNT_VALUE 0x05 /* Get current count value. */
-+#define GPTU_CALCULATE_DIVIDER 0x06 /* Calculate timer divider from given freq.*/
-+#define GPTU_SET_TIMER 0x07 /* Simplified method to setup timer. */
-+#define GPTU_SET_COUNTER 0x08 /* Simplified method to setup counter. */
-+
-+/*
-+ * Data Type Used to Call ioctl
-+ */
-+struct gptu_ioctl_param {
-+ unsigned int timer; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
-+ * GPTU_SET_COUNTER, this field is ID of expected *
-+ * timer/counter. If it's zero, a timer/counter would *
-+ * be dynamically allocated and ID would be stored in *
-+ * this field. *
-+ * In command GPTU_GET_COUNT_VALUE, this field is *
-+ * ignored. *
-+ * In other command, this field is ID of timer/counter *
-+ * allocated. */
-+ unsigned int flag; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
-+ * GPTU_SET_COUNTER, this field contains flags to *
-+ * specify how to configure timer/counter. *
-+ * In command GPTU_START_TIMER, zero indicate start *
-+ * and non-zero indicate resume timer/counter. *
-+ * In other command, this field is ignored. */
-+ unsigned long value; /* In command GPTU_REQUEST_TIMER, this field contains *
-+ * init/reload value. *
-+ * In command GPTU_SET_TIMER, this field contains *
-+ * frequency (0.001Hz) of timer. *
-+ * In command GPTU_GET_COUNT_VALUE, current count *
-+ * value would be stored in this field. *
-+ * In command GPTU_CALCULATE_DIVIDER, this field *
-+ * contains frequency wanted, and after calculation, *
-+ * divider would be stored in this field to overwrite *
-+ * the frequency. *
-+ * In other command, this field is ignored. */
-+ int pid; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
-+ * if signal is required, this field contains process *
-+ * ID to which signal would be sent. *
-+ * In other command, this field is ignored. */
-+ int sig; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
-+ * if signal is required, this field contains signal *
-+ * number which would be sent. *
-+ * In other command, this field is ignored. */
-+};
-+
-+/*
-+ * ####################################
-+ * Data Type
-+ * ####################################
-+ */
-+typedef void (*timer_callback)(unsigned long arg);
-+
-+extern int lq_request_timer(unsigned int, unsigned int, unsigned long, unsigned long, unsigned long);
-+extern int lq_free_timer(unsigned int);
-+extern int lq_start_timer(unsigned int, int);
-+extern int lq_stop_timer(unsigned int);
-+extern int lq_reset_counter_flags(u32 timer, u32 flags);
-+extern int lq_get_count_value(unsigned int, unsigned long *);
-+extern u32 lq_cal_divider(unsigned long);
-+extern int lq_set_timer(unsigned int, unsigned int, int, int, unsigned int, unsigned long, unsigned long);
-+extern int lq_set_counter(unsigned int timer, unsigned int flag,
-+ u32 reload, unsigned long arg1, unsigned long arg2);
-+
-+#endif /* __DANUBE_GPTU_DEV_H__2005_07_26__10_19__ */
---- a/arch/mips/lantiq/xway/Makefile
-+++ b/arch/mips/lantiq/xway/Makefile
-@@ -1,4 +1,10 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o
-+obj-y := prom.o sysctrl.o clk.o dma.o dcdc.o
-+
-+ifdef CONFIG_SOC_AMAZON_SE
-+obj-y += gptu.o
-+else
-+obj-y += timer.o
-+endif
-
- obj-y += vmmc.o
---- /dev/null
-+++ b/arch/mips/lantiq/xway/timer.c
-@@ -0,0 +1,887 @@
-+#ifndef CONFIG_SOC_AMAZON_SE
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/uaccess.h>
-+#include <linux/unistd.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/sched/signal.h>
-+
-+#include <linux/of_platform.h>
-+
-+#include <asm/irq.h>
-+#include <asm/div64.h>
-+#include "../clk.h"
-+
-+#include <lantiq_soc.h>
-+#include <lantiq_irq.h>
-+#include <lantiq_timer.h>
-+
-+#define MAX_NUM_OF_32BIT_TIMER_BLOCKS 6
-+
-+#ifdef TIMER1A
-+#define FIRST_TIMER TIMER1A
-+#else
-+#define FIRST_TIMER 2
-+#endif
-+
-+/*
-+ * GPTC divider is set or not.
-+ */
-+#define GPTU_CLC_RMC_IS_SET 0
-+
-+/*
-+ * Timer Interrupt (IRQ)
-+ */
-+/* Must be adjusted when ICU driver is available */
-+#define TIMER_INTERRUPT (INT_NUM_IM3_IRL0 + 22)
-+
-+/*
-+ * Bits Operation
-+ */
-+#define GET_BITS(x, msb, lsb) \
-+ (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
-+#define SET_BITS(x, msb, lsb, value) \
-+ (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | \
-+ (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
-+
-+/*
-+ * GPTU Register Mapping
-+ */
-+#define LQ_GPTU (KSEG1 + 0x1E100A00)
-+#define LQ_GPTU_CLC ((volatile u32 *)(LQ_GPTU + 0x0000))
-+#define LQ_GPTU_ID ((volatile u32 *)(LQ_GPTU + 0x0008))
-+#define LQ_GPTU_CON(n, X) ((volatile u32 *)(LQ_GPTU + 0x0010 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_RUN(n, X) ((volatile u32 *)(LQ_GPTU + 0x0018 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_RELOAD(n, X) ((volatile u32 *)(LQ_GPTU + 0x0020 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_COUNT(n, X) ((volatile u32 *)(LQ_GPTU + 0x0028 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_IRNEN ((volatile u32 *)(LQ_GPTU + 0x00F4))
-+#define LQ_GPTU_IRNICR ((volatile u32 *)(LQ_GPTU + 0x00F8))
-+#define LQ_GPTU_IRNCR ((volatile u32 *)(LQ_GPTU + 0x00FC))
-+
-+/*
-+ * Clock Control Register
-+ */
-+#define GPTU_CLC_SMC GET_BITS(*LQ_GPTU_CLC, 23, 16)
-+#define GPTU_CLC_RMC GET_BITS(*LQ_GPTU_CLC, 15, 8)
-+#define GPTU_CLC_FSOE (*LQ_GPTU_CLC & (1 << 5))
-+#define GPTU_CLC_EDIS (*LQ_GPTU_CLC & (1 << 3))
-+#define GPTU_CLC_SPEN (*LQ_GPTU_CLC & (1 << 2))
-+#define GPTU_CLC_DISS (*LQ_GPTU_CLC & (1 << 1))
-+#define GPTU_CLC_DISR (*LQ_GPTU_CLC & (1 << 0))
-+
-+#define GPTU_CLC_SMC_SET(value) SET_BITS(0, 23, 16, (value))
-+#define GPTU_CLC_RMC_SET(value) SET_BITS(0, 15, 8, (value))
-+#define GPTU_CLC_FSOE_SET(value) ((value) ? (1 << 5) : 0)
-+#define GPTU_CLC_SBWE_SET(value) ((value) ? (1 << 4) : 0)
-+#define GPTU_CLC_EDIS_SET(value) ((value) ? (1 << 3) : 0)
-+#define GPTU_CLC_SPEN_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_CLC_DISR_SET(value) ((value) ? (1 << 0) : 0)
-+
-+/*
-+ * ID Register
-+ */
-+#define GPTU_ID_ID GET_BITS(*LQ_GPTU_ID, 15, 8)
-+#define GPTU_ID_CFG GET_BITS(*LQ_GPTU_ID, 7, 5)
-+#define GPTU_ID_REV GET_BITS(*LQ_GPTU_ID, 4, 0)
-+
-+/*
-+ * Control Register of Timer/Counter nX
-+ * n is the index of block (1 based index)
-+ * X is either A or B
-+ */
-+#define GPTU_CON_SRC_EG(n, X) (*LQ_GPTU_CON(n, X) & (1 << 10))
-+#define GPTU_CON_SRC_EXT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 9))
-+#define GPTU_CON_SYNC(n, X) (*LQ_GPTU_CON(n, X) & (1 << 8))
-+#define GPTU_CON_EDGE(n, X) GET_BITS(*LQ_GPTU_CON(n, X), 7, 6)
-+#define GPTU_CON_INV(n, X) (*LQ_GPTU_CON(n, X) & (1 << 5))
-+#define GPTU_CON_EXT(n, X) (*LQ_GPTU_CON(n, A) & (1 << 4)) /* Timer/Counter B does not have this bit */
-+#define GPTU_CON_STP(n, X) (*LQ_GPTU_CON(n, X) & (1 << 3))
-+#define GPTU_CON_CNT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 2))
-+#define GPTU_CON_DIR(n, X) (*LQ_GPTU_CON(n, X) & (1 << 1))
-+#define GPTU_CON_EN(n, X) (*LQ_GPTU_CON(n, X) & (1 << 0))
-+
-+#define GPTU_CON_SRC_EG_SET(value) ((value) ? 0 : (1 << 10))
-+#define GPTU_CON_SRC_EXT_SET(value) ((value) ? (1 << 9) : 0)
-+#define GPTU_CON_SYNC_SET(value) ((value) ? (1 << 8) : 0)
-+#define GPTU_CON_EDGE_SET(value) SET_BITS(0, 7, 6, (value))
-+#define GPTU_CON_INV_SET(value) ((value) ? (1 << 5) : 0)
-+#define GPTU_CON_EXT_SET(value) ((value) ? (1 << 4) : 0)
-+#define GPTU_CON_STP_SET(value) ((value) ? (1 << 3) : 0)
-+#define GPTU_CON_CNT_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_CON_DIR_SET(value) ((value) ? (1 << 1) : 0)
-+
-+#define GPTU_RUN_RL_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_RUN_CEN_SET(value) ((value) ? (1 << 1) : 0)
-+#define GPTU_RUN_SEN_SET(value) ((value) ? (1 << 0) : 0)
-+
-+#define GPTU_IRNEN_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
-+#define GPTU_IRNCR_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
-+
-+#define TIMER_FLAG_MASK_SIZE(x) (x & 0x0001)
-+#define TIMER_FLAG_MASK_TYPE(x) (x & 0x0002)
-+#define TIMER_FLAG_MASK_STOP(x) (x & 0x0004)
-+#define TIMER_FLAG_MASK_DIR(x) (x & 0x0008)
-+#define TIMER_FLAG_NONE_EDGE 0x0000
-+#define TIMER_FLAG_MASK_EDGE(x) (x & 0x0030)
-+#define TIMER_FLAG_REAL 0x0000
-+#define TIMER_FLAG_INVERT 0x0040
-+#define TIMER_FLAG_MASK_INVERT(x) (x & 0x0040)
-+#define TIMER_FLAG_MASK_TRIGGER(x) (x & 0x0070)
-+#define TIMER_FLAG_MASK_SYNC(x) (x & 0x0080)
-+#define TIMER_FLAG_CALLBACK_IN_HB 0x0200
-+#define TIMER_FLAG_MASK_HANDLE(x) (x & 0x0300)
-+#define TIMER_FLAG_MASK_SRC(x) (x & 0x1000)
-+
-+struct timer_dev_timer {
-+ unsigned int f_irq_on;
-+ unsigned int irq;
-+ unsigned int flag;
-+ unsigned long arg1;
-+ unsigned long arg2;
-+};
-+
-+struct timer_dev {
-+ struct mutex gptu_mutex;
-+ unsigned int number_of_timers;
-+ unsigned int occupation;
-+ unsigned int f_gptu_on;
-+ struct timer_dev_timer timer[MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2];
-+};
-+
-+
-+unsigned int ltq_get_fpi_bus_clock(int fpi) {
-+ struct clk *clk = clk_get_fpi();
-+ return clk_get_rate(clk);
-+}
-+
-+
-+static long gptu_ioctl(struct file *, unsigned int, unsigned long);
-+static int gptu_open(struct inode *, struct file *);
-+static int gptu_release(struct inode *, struct file *);
-+
-+static struct file_operations gptu_fops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = gptu_ioctl,
-+ .open = gptu_open,
-+ .release = gptu_release
-+};
-+
-+static struct miscdevice gptu_miscdev = {
-+ .minor = MISC_DYNAMIC_MINOR,
-+ .name = "gptu",
-+ .fops = &gptu_fops,
-+};
-+
-+static struct timer_dev timer_dev;
-+
-+static irqreturn_t timer_irq_handler(int irq, void *p)
-+{
-+ unsigned int timer;
-+ unsigned int flag;
-+ struct timer_dev_timer *dev_timer = (struct timer_dev_timer *)p;
-+
-+ timer = irq - TIMER_INTERRUPT;
-+ if (timer < timer_dev.number_of_timers
-+ && dev_timer == &timer_dev.timer[timer]) {
-+ /* Clear interrupt. */
-+ ltq_w32(1 << timer, LQ_GPTU_IRNCR);
-+
-+ /* Call user hanler or signal. */
-+ flag = dev_timer->flag;
-+ if (!(timer & 0x01)
-+ || TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
-+ /* 16-bit timer or timer A of 32-bit timer */
-+ switch (TIMER_FLAG_MASK_HANDLE(flag)) {
-+ case TIMER_FLAG_CALLBACK_IN_IRQ:
-+ case TIMER_FLAG_CALLBACK_IN_HB:
-+ if (dev_timer->arg1)
-+ (*(timer_callback)dev_timer->arg1)(dev_timer->arg2);
-+ break;
-+ case TIMER_FLAG_SIGNAL:
-+ send_sig((int)dev_timer->arg2, (struct task_struct *)dev_timer->arg1, 0);
-+ break;
-+ }
-+ }
-+ }
-+ return IRQ_HANDLED;
-+}
-+
-+static inline void lq_enable_gptu(void)
-+{
-+ struct clk *clk = clk_get_sys("1e100a00.gptu", NULL);
-+ clk_enable(clk);
-+
-+ //ltq_pmu_enable(PMU_GPT);
-+
-+ /* Set divider as 1, disable write protection for SPEN, enable module. */
-+ *LQ_GPTU_CLC =
-+ GPTU_CLC_SMC_SET(0x00) |
-+ GPTU_CLC_RMC_SET(0x01) |
-+ GPTU_CLC_FSOE_SET(0) |
-+ GPTU_CLC_SBWE_SET(1) |
-+ GPTU_CLC_EDIS_SET(0) |
-+ GPTU_CLC_SPEN_SET(0) |
-+ GPTU_CLC_DISR_SET(0);
-+}
-+
-+static inline void lq_disable_gptu(void)
-+{
-+ struct clk *clk = clk_get_sys("1e100a00.gptu", NULL);
-+ ltq_w32(0x00, LQ_GPTU_IRNEN);
-+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
-+
-+ /* Set divider as 0, enable write protection for SPEN, disable module. */
-+ *LQ_GPTU_CLC =
-+ GPTU_CLC_SMC_SET(0x00) |
-+ GPTU_CLC_RMC_SET(0x00) |
-+ GPTU_CLC_FSOE_SET(0) |
-+ GPTU_CLC_SBWE_SET(0) |
-+ GPTU_CLC_EDIS_SET(0) |
-+ GPTU_CLC_SPEN_SET(0) |
-+ GPTU_CLC_DISR_SET(1);
-+
-+ clk_enable(clk);
-+}
-+
-+int lq_request_timer(unsigned int timer, unsigned int flag,
-+ unsigned long value, unsigned long arg1, unsigned long arg2)
-+{
-+ int ret = 0;
-+ unsigned int con_reg, irnen_reg;
-+ int n, X;
-+
-+ if (timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ printk(KERN_INFO "request_timer(%d, 0x%08X, %lu)...",
-+ timer, flag, value);
-+
-+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT)
-+ value &= 0xFFFF;
-+ else
-+ timer &= ~0x01;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ /*
-+ * Allocate timer.
-+ */
-+ if (timer < FIRST_TIMER) {
-+ unsigned int mask;
-+ unsigned int shift;
-+ /* This takes care of TIMER1B which is the only choice for Voice TAPI system */
-+ unsigned int offset = TIMER2A;
-+
-+ /*
-+ * Pick up a free timer.
-+ */
-+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
-+ mask = 1 << offset;
-+ shift = 1;
-+ } else {
-+ mask = 3 << offset;
-+ shift = 2;
-+ }
-+ for (timer = offset;
-+ timer < offset + timer_dev.number_of_timers;
-+ timer += shift, mask <<= shift)
-+ if (!(timer_dev.occupation & mask)) {
-+ timer_dev.occupation |= mask;
-+ break;
-+ }
-+ if (timer >= offset + timer_dev.number_of_timers) {
-+ printk("failed![%d]\n", __LINE__);
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ } else
-+ ret = timer;
-+ } else {
-+ register unsigned int mask;
-+
-+ /*
-+ * Check if the requested timer is free.
-+ */
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if ((timer_dev.occupation & mask)) {
-+ printk("failed![%d] mask %#x, timer_dev.occupation %#x\n",
-+ __LINE__, mask, timer_dev.occupation);
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EBUSY;
-+ } else {
-+ timer_dev.occupation |= mask;
-+ ret = 0;
-+ }
-+ }
-+
-+ /*
-+ * Prepare control register value.
-+ */
-+ switch (TIMER_FLAG_MASK_EDGE(flag)) {
-+ default:
-+ case TIMER_FLAG_NONE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x00);
-+ break;
-+ case TIMER_FLAG_RISE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x01);
-+ break;
-+ case TIMER_FLAG_FALL_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x02);
-+ break;
-+ case TIMER_FLAG_ANY_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x03);
-+ break;
-+ }
-+ if (TIMER_FLAG_MASK_TYPE(flag) == TIMER_FLAG_TIMER)
-+ con_reg |=
-+ TIMER_FLAG_MASK_SRC(flag) ==
-+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) :
-+ GPTU_CON_SRC_EXT_SET(0);
-+ else
-+ con_reg |=
-+ TIMER_FLAG_MASK_SRC(flag) ==
-+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) :
-+ GPTU_CON_SRC_EG_SET(0);
-+ con_reg |=
-+ TIMER_FLAG_MASK_SYNC(flag) ==
-+ TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) :
-+ GPTU_CON_SYNC_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_INVERT(flag) ==
-+ TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_SIZE(flag) ==
-+ TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) :
-+ GPTU_CON_EXT_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_STOP(flag) ==
-+ TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
-+ con_reg |=
-+ TIMER_FLAG_MASK_TYPE(flag) ==
-+ TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) :
-+ GPTU_CON_CNT_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_DIR(flag) ==
-+ TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
-+
-+ /*
-+ * Fill up running data.
-+ */
-+ timer_dev.timer[timer - FIRST_TIMER].flag = flag;
-+ timer_dev.timer[timer - FIRST_TIMER].arg1 = arg1;
-+ timer_dev.timer[timer - FIRST_TIMER].arg2 = arg2;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flag;
-+
-+ /*
-+ * Enable GPTU module.
-+ */
-+ if (!timer_dev.f_gptu_on) {
-+ lq_enable_gptu();
-+ timer_dev.f_gptu_on = 1;
-+ }
-+
-+ /*
-+ * Enable IRQ.
-+ */
-+ if (TIMER_FLAG_MASK_HANDLE(flag) != TIMER_FLAG_NO_HANDLE) {
-+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL)
-+ timer_dev.timer[timer - FIRST_TIMER].arg1 =
-+ (unsigned long) find_task_by_vpid((int) arg1);
-+
-+ irnen_reg = 1 << (timer - FIRST_TIMER);
-+
-+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL
-+ || (TIMER_FLAG_MASK_HANDLE(flag) ==
-+ TIMER_FLAG_CALLBACK_IN_IRQ
-+ && timer_dev.timer[timer - FIRST_TIMER].arg1)) {
-+ enable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
-+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 1;
-+ }
-+ } else
-+ irnen_reg = 0;
-+
-+ /*
-+ * Write config register, reload value and enable interrupt.
-+ */
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+ *LQ_GPTU_CON(n, X) = con_reg;
-+ *LQ_GPTU_RELOAD(n, X) = value;
-+ /* printk("reload value = %d\n", (u32)value); */
-+ *LQ_GPTU_IRNEN |= irnen_reg;
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ printk("successful!\n");
-+ return ret;
-+}
-+EXPORT_SYMBOL(lq_request_timer);
-+
-+int lq_free_timer(unsigned int timer)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ if (GPTU_CON_EN(n, X))
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
-+
-+ *LQ_GPTU_IRNEN &= ~GPTU_IRNEN_TC_SET(n, X, 1);
-+ *LQ_GPTU_IRNCR |= GPTU_IRNCR_TC_SET(n, X, 1);
-+
-+ if (timer_dev.timer[timer - FIRST_TIMER].f_irq_on) {
-+ disable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
-+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 0;
-+ }
-+
-+ timer_dev.occupation &= ~mask;
-+ if (!timer_dev.occupation && timer_dev.f_gptu_on) {
-+ lq_disable_gptu();
-+ timer_dev.f_gptu_on = 0;
-+ }
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_free_timer);
-+
-+int lq_start_timer(unsigned int timer, int is_resume)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) ==
-+ TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_RL_SET(!is_resume) | GPTU_RUN_SEN_SET(1);
-+
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_start_timer);
-+
-+int lq_stop_timer(unsigned int timer)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER
-+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_stop_timer);
-+
-+int lq_reset_counter_flags(u32 timer, u32 flags)
-+{
-+ unsigned int oflag;
-+ unsigned int mask, con_reg;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ oflag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(oflag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(oflag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ switch (TIMER_FLAG_MASK_EDGE(flags)) {
-+ default:
-+ case TIMER_FLAG_NONE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x00);
-+ break;
-+ case TIMER_FLAG_RISE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x01);
-+ break;
-+ case TIMER_FLAG_FALL_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x02);
-+ break;
-+ case TIMER_FLAG_ANY_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x03);
-+ break;
-+ }
-+ if (TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER)
-+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) : GPTU_CON_SRC_EXT_SET(0);
-+ else
-+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) : GPTU_CON_SRC_EG_SET(0);
-+ con_reg |= TIMER_FLAG_MASK_SYNC(flags) == TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) : GPTU_CON_SYNC_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_INVERT(flags) == TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_SIZE(flags) == TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) : GPTU_CON_EXT_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_STOP(flags) == TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
-+ con_reg |= TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) : GPTU_CON_CNT_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_DIR(flags) == TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
-+
-+ timer_dev.timer[timer - FIRST_TIMER].flag = flags;
-+ if (TIMER_FLAG_MASK_SIZE(flags) != TIMER_FLAG_16BIT)
-+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flags;
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_CON(n, X) = con_reg;
-+ smp_wmb();
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_reset_counter_flags);
-+
-+int lq_get_count_value(unsigned int timer, unsigned long *value)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER
-+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *value = *LQ_GPTU_COUNT(n, X);
-+
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_get_count_value);
-+
-+u32 lq_cal_divider(unsigned long freq)
-+{
-+ u64 module_freq, fpi = ltq_get_fpi_bus_clock(2);
-+ u32 clock_divider = 1;
-+ module_freq = fpi * 1000;
-+ do_div(module_freq, clock_divider * freq);
-+ return module_freq;
-+}
-+EXPORT_SYMBOL(lq_cal_divider);
-+
-+int lq_set_timer(unsigned int timer, unsigned int freq, int is_cyclic,
-+ int is_ext_src, unsigned int handle_flag, unsigned long arg1,
-+ unsigned long arg2)
-+{
-+ unsigned long divider;
-+ unsigned int flag;
-+
-+ divider = lq_cal_divider(freq);
-+ if (divider == 0)
-+ return -EINVAL;
-+ flag = ((divider & ~0xFFFF) ? TIMER_FLAG_32BIT : TIMER_FLAG_16BIT)
-+ | (is_cyclic ? TIMER_FLAG_CYCLIC : TIMER_FLAG_ONCE)
-+ | (is_ext_src ? TIMER_FLAG_EXT_SRC : TIMER_FLAG_INT_SRC)
-+ | TIMER_FLAG_TIMER | TIMER_FLAG_DOWN
-+ | TIMER_FLAG_MASK_HANDLE(handle_flag);
-+
-+ printk(KERN_INFO "lq_set_timer(%d, %d), divider = %lu\n",
-+ timer, freq, divider);
-+ return lq_request_timer(timer, flag, divider, arg1, arg2);
-+}
-+EXPORT_SYMBOL(lq_set_timer);
-+
-+int lq_set_counter(unsigned int timer, unsigned int flag, u32 reload,
-+ unsigned long arg1, unsigned long arg2)
-+{
-+ printk(KERN_INFO "lq_set_counter(%d, %#x, %d)\n", timer, flag, reload);
-+ return lq_request_timer(timer, flag, reload, arg1, arg2);
-+}
-+EXPORT_SYMBOL(lq_set_counter);
-+
-+static long gptu_ioctl(struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ int ret;
-+ struct gptu_ioctl_param param;
-+
-+ if (!access_ok((void __user *)arg, sizeof(struct gptu_ioctl_param)))
-+ return -EFAULT;
-+ if (copy_from_user(&param, (void __user *)arg, sizeof(param)))
-+ return -EFAULT;
-+
-+ if ((((cmd == GPTU_REQUEST_TIMER || cmd == GPTU_SET_TIMER
-+ || GPTU_SET_COUNTER) && param.timer < 2)
-+ || cmd == GPTU_GET_COUNT_VALUE || cmd == GPTU_CALCULATE_DIVIDER)
-+ && !access_ok((void __user *)arg,
-+ sizeof(struct gptu_ioctl_param)))
-+ return -EFAULT;
-+
-+ switch (cmd) {
-+ case GPTU_REQUEST_TIMER:
-+ ret = lq_request_timer(param.timer, param.flag, param.value,
-+ (unsigned long) param.pid,
-+ (unsigned long) param.sig);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ case GPTU_FREE_TIMER:
-+ ret = lq_free_timer(param.timer);
-+ break;
-+ case GPTU_START_TIMER:
-+ ret = lq_start_timer(param.timer, param.flag);
-+ break;
-+ case GPTU_STOP_TIMER:
-+ ret = lq_stop_timer(param.timer);
-+ break;
-+ case GPTU_GET_COUNT_VALUE:
-+ ret = lq_get_count_value(param.timer, &param.value);
-+ if (!ret && copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ value, &param.value,sizeof(param.value)))
-+ ret = -EFAULT;
-+ break;
-+ case GPTU_CALCULATE_DIVIDER:
-+ param.value = lq_cal_divider(param.value);
-+ if (param.value == 0)
-+ ret = -EINVAL;
-+ else if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ value, &param.value,
-+ sizeof(param.value)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ break;
-+ case GPTU_SET_TIMER:
-+ ret = lq_set_timer(param.timer, param.value,
-+ TIMER_FLAG_MASK_STOP(param.flag) !=
-+ TIMER_FLAG_ONCE ? 1 : 0,
-+ TIMER_FLAG_MASK_SRC(param.flag) ==
-+ TIMER_FLAG_EXT_SRC ? 1 : 0,
-+ TIMER_FLAG_MASK_HANDLE(param.flag) ==
-+ TIMER_FLAG_SIGNAL ? TIMER_FLAG_SIGNAL :
-+ TIMER_FLAG_NO_HANDLE,
-+ (unsigned long) param.pid,
-+ (unsigned long) param.sig);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ case GPTU_SET_COUNTER:
-+ lq_set_counter(param.timer, param.flag, param.value, 0, 0);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ default:
-+ ret = -ENOTTY;
-+ }
-+
-+ return ret;
-+}
-+
-+static int gptu_open(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int gptu_release(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int gptu_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int i;
-+
-+ ltq_w32(0, LQ_GPTU_IRNEN);
-+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
-+
-+ memset(&timer_dev, 0, sizeof(timer_dev));
-+ mutex_init(&timer_dev.gptu_mutex);
-+
-+ lq_enable_gptu();
-+ timer_dev.number_of_timers = GPTU_ID_CFG * 2;
-+ lq_disable_gptu();
-+ if (timer_dev.number_of_timers > MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2)
-+ timer_dev.number_of_timers = MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2;
-+ printk(KERN_INFO "gptu: totally %d 16-bit timers/counters\n", timer_dev.number_of_timers);
-+
-+ ret = misc_register(&gptu_miscdev);
-+ if (ret) {
-+ printk(KERN_ERR "gptu: can't misc_register, get error %d\n", -ret);
-+ return ret;
-+ } else {
-+ printk(KERN_INFO "gptu: misc_register on minor %d\n", gptu_miscdev.minor);
-+ }
-+
-+ for (i = 0; i < timer_dev.number_of_timers; i++) {
-+ int irq = platform_get_irq(pdev, i);
-+ if (irq < 0) {
-+ printk(KERN_ERR "gptu: failed in getting irq (%d), get error %d\n", i, irq);
-+ for (i--; i >= 0; i--)
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ misc_deregister(&gptu_miscdev);
-+ return irq;
-+ }
-+
-+ ret = request_irq(irq, timer_irq_handler, IRQF_TIMER, gptu_miscdev.name, &timer_dev.timer[i]);
-+ if (ret) {
-+ printk(KERN_ERR "gptu: failed in requesting irq (%d), get error %d\n", i, -ret);
-+ for (i--; i >= 0; i--)
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ misc_deregister(&gptu_miscdev);
-+ return ret;
-+ } else {
-+ timer_dev.timer[i].irq = irq;
-+ disable_irq(timer_dev.timer[i].irq);
-+ printk(KERN_INFO "gptu: succeeded to request irq %d\n", timer_dev.timer[i].irq);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id gptu_match[] = {
-+ { .compatible = "lantiq,gptu-xway" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, gptu_match);
-+
-+static struct platform_driver gptu_driver = {
-+ .probe = gptu_probe,
-+ .driver = {
-+ .name = "gptu-xway",
-+ .owner = THIS_MODULE,
-+ .of_match_table = gptu_match,
-+ },
-+};
-+
-+int __init lq_gptu_init(void)
-+{
-+ int ret = platform_driver_register(&gptu_driver);
-+
-+ if (ret)
-+ pr_info("gptu: Error registering platform driver\n");
-+ return ret;
-+}
-+
-+void __exit lq_gptu_exit(void)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < timer_dev.number_of_timers; i++) {
-+ if (timer_dev.timer[i].f_irq_on)
-+ disable_irq(timer_dev.timer[i].irq);
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ }
-+ lq_disable_gptu();
-+ misc_deregister(&gptu_miscdev);
-+}
-+
-+module_init(lq_gptu_init);
-+module_exit(lq_gptu_exit);
-+
-+#endif
diff --git a/target/linux/lantiq/patches-5.15/0018-MTD-nand-lots-of-xrx200-fixes.patch b/target/linux/lantiq/patches-5.15/0018-MTD-nand-lots-of-xrx200-fixes.patch
deleted file mode 100644
index 35f656da6e..0000000000
--- a/target/linux/lantiq/patches-5.15/0018-MTD-nand-lots-of-xrx200-fixes.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 997a8965db8417266bea3fbdcfa3e5655a1b52fa Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 9 Sep 2014 23:12:15 +0200
-Subject: [PATCH 18/36] MTD: nand: lots of xrx200 fixes
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mtd/nand/raw/xway_nand.c | 63 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 63 insertions(+)
-
---- a/drivers/mtd/nand/raw/xway_nand.c
-+++ b/drivers/mtd/nand/raw/xway_nand.c
-@@ -61,6 +61,24 @@
- #define NAND_CON_CSMUX (1 << 1)
- #define NAND_CON_NANDM 1
-
-+#define DANUBE_PCI_REG32( addr ) (*(volatile u32 *)(addr))
-+#define PCI_CR_PR_OFFSET (KSEG1+0x1E105400)
-+#define PCI_CR_PC_ARB (PCI_CR_PR_OFFSET + 0x0080)
-+
-+/*
-+ * req_mask provides a mechanism to prevent interference between
-+ * nand and pci (probably only relevant for the BT Home Hub 2B).
-+ * Setting it causes the corresponding pci req pins to be masked
-+ * during nand access, and also moves ebu locking from the read/write
-+ * functions to the chip select function to ensure that the whole
-+ * operation runs with interrupts disabled.
-+ * In addition it switches on some extra waiting in xway_cmd_ctrl().
-+ * This seems to be necessary if the ebu_cs1 pin has open-drain disabled,
-+ * which in turn seems to be necessary for the nor chip to be recognised
-+ * reliably, on a board (Home Hub 2B again) which has both nor and nand.
-+ */
-+static __be32 req_mask = 0;
-+
- struct xway_nand_data {
- struct nand_controller controller;
- struct nand_chip chip;
-@@ -92,10 +110,22 @@ static void xway_select_chip(struct nand
- case -1:
- ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
- ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
-+
-+ if (req_mask) {
-+ /* Unmask all external PCI request */
-+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) &= ~(req_mask << 16);
-+ }
-+
- spin_unlock_irqrestore(&ebu_lock, data->csflags);
- break;
- case 0:
- spin_lock_irqsave(&ebu_lock, data->csflags);
-+
-+ if (req_mask) {
-+ /* Mask all external PCI request */
-+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) |= (req_mask << 16);
-+ }
-+
- ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
- ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
- break;
-@@ -108,6 +138,11 @@ static void xway_cmd_ctrl(struct nand_ch
- {
- struct mtd_info *mtd = nand_to_mtd(chip);
-
-+ if (req_mask) {
-+ if (cmd != NAND_CMD_STATUS)
-+ ltq_ebu_w32(0, EBU_NAND_WAIT); /* Clear nand ready */
-+ }
-+
- if (cmd == NAND_CMD_NONE)
- return;
-
-@@ -118,6 +153,24 @@ static void xway_cmd_ctrl(struct nand_ch
-
- while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
- ;
-+
-+ if (req_mask) {
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (cmd) {
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_SEQIN:
-+ case NAND_CMD_STATUS:
-+ case NAND_CMD_READID:
-+ return;
-+ }
-+
-+ /* wait until command is processed */
-+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
-+ ;
-+ }
- }
-
- static int xway_dev_ready(struct nand_chip *chip)
-@@ -170,6 +223,7 @@ static int xway_nand_probe(struct platfo
- int err;
- u32 cs;
- u32 cs_flag = 0;
-+ const __be32 *req_mask_ptr;
-
- /* Allocate memory for the device structure (and zero it) */
- data = devm_kzalloc(&pdev->dev, sizeof(struct xway_nand_data),
-@@ -206,6 +260,15 @@ static int xway_nand_probe(struct platfo
- if (!err && cs == 1)
- cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
-
-+ req_mask_ptr = of_get_property(pdev->dev.of_node,
-+ "req-mask", NULL);
-+
-+ /*
-+ * Load the PCI req lines to mask from the device tree. If the
-+ * property is not present, setting req_mask to 0 disables masking.
-+ */
-+ req_mask = (req_mask_ptr ? *req_mask_ptr : 0);
-+
- /* setup the EBU to run in NAND mode on our base addr */
- ltq_ebu_w32(CPHYSADDR(data->nandaddr)
- | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
diff --git a/target/linux/lantiq/patches-5.15/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch b/target/linux/lantiq/patches-5.15/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch
deleted file mode 100644
index c1fc59487a..0000000000
--- a/target/linux/lantiq/patches-5.15/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From e3b20f04e9f9cae1babe091fdc1d08d7703ae344 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:18:00 +0200
-Subject: [PATCH 20/36] MTD: lantiq: handle NO_XIP on cfi0001 flash
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mtd/maps/lantiq-flash.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/maps/lantiq-flash.c
-+++ b/drivers/mtd/maps/lantiq-flash.c
-@@ -129,7 +129,11 @@ ltq_mtd_probe(struct platform_device *pd
- if (!ltq_mtd->map)
- return -ENOMEM;
-
-- ltq_mtd->map->phys = ltq_mtd->res->start;
-+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-+ ltq_mtd->map->phys = NO_XIP;
-+ else
-+ ltq_mtd->map->phys = ltq_mtd->res->start;
-+ ltq_mtd->res->start;
- ltq_mtd->map->size = resource_size(ltq_mtd->res);
- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
- if (IS_ERR(ltq_mtd->map->virt))
diff --git a/target/linux/lantiq/patches-5.15/0023-NET-PHY-add-led-support-for-intel-xway.patch b/target/linux/lantiq/patches-5.15/0023-NET-PHY-add-led-support-for-intel-xway.patch
deleted file mode 100644
index fcc760b911..0000000000
--- a/target/linux/lantiq/patches-5.15/0023-NET-PHY-add-led-support-for-intel-xway.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From 0a63ab263725c427051a8bbaa0732b749627da27 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:15:36 +0200
-Subject: [PATCH 23/36] NET: PHY: adds driver for lantiq PHY11G
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/phy/Kconfig | 5 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/lantiq.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 237 insertions(+)
- create mode 100644 drivers/net/phy/lantiq.c
-
---- a/drivers/net/phy/intel-xway.c
-+++ b/drivers/net/phy/intel-xway.c
-@@ -229,6 +229,51 @@ static int xway_gphy_rgmii_init(struct p
- XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
- }
-
-+#if IS_ENABLED(CONFIG_OF_MDIO)
-+static int vr9_gphy_of_reg_init(struct phy_device *phydev)
-+{
-+ u32 tmp;
-+
-+ /* store the led values if one was passed by the devicetree */
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,ledch", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,ledcl", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCL, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led0h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led0l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led1h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led1l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led2h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led2l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led3h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED3H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led3l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED3L, tmp);
-+
-+ return 0;
-+}
-+#else
-+static int vr9_gphy_of_reg_init(struct phy_device *phydev)
-+{
-+ return 0;
-+}
-+#endif /* CONFIG_OF_MDIO */
-+
- static int xway_gphy_config_init(struct phy_device *phydev)
- {
- int err;
-@@ -280,6 +325,7 @@ static int xway_gphy_config_init(struct
- if (err)
- return err;
-
-+ vr9_gphy_of_reg_init(phydev);
- return 0;
- }
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/phy-lanitq.txt
-@@ -0,0 +1,216 @@
-+Lanitq PHY binding
-+============================================
-+
-+This devicetree binding controls the lantiq ethernet phys led functionality.
-+
-+Example:
-+ mdio@0 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "lantiq,xrx200-mdio";
-+ phy5: ethernet-phy@5 {
-+ reg = <0x1>;
-+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
-+ };
-+ phy11: ethernet-phy@11 {
-+ reg = <0x11>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led2h = <0x00>;
-+ lantiq,led2l = <0x03>;
-+ };
-+ phy12: ethernet-phy@12 {
-+ reg = <0x12>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led1h = <0x00>;
-+ lantiq,led1l = <0x03>;
-+ };
-+ phy13: ethernet-phy@13 {
-+ reg = <0x13>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led2h = <0x00>;
-+ lantiq,led2l = <0x03>;
-+ };
-+ phy14: ethernet-phy@14 {
-+ reg = <0x14>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led1h = <0x00>;
-+ lantiq,led1l = <0x03>;
-+ };
-+ };
-+
-+Register Description
-+============================================
-+
-+LEDCH:
-+
-+Name Hardware Reset Value
-+LEDCH 0x00C5
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| FBF | SBF |RES | NACS |
-+=========================================
-+
-+Field Bits Type Description
-+FBF 7:6 RW Fast Blink Frequency
-+ ---
-+ 0x0 (00b) F02HZ 2 Hz blinking frequency
-+ 0x1 (01b) F04HZ 4 Hz blinking frequency
-+ 0x2 (10b) F08HZ 8 Hz blinking frequency
-+ 0x3 (11b) F16HZ 16 Hz blinking frequency
-+
-+SBF 5:4 RW Slow Blink Frequency
-+ ---
-+ 0x0 (00b) F02HZ 2 Hz blinking frequency
-+ 0x1 (01b) F04HZ 4 Hz blinking frequency
-+ 0x2 (10b) F08HZ 8 Hz blinking frequency
-+ 0x3 (11b) F16HZ 16 Hz blinking frequency
-+
-+NACS 2:0 RW Inverse of Scan Function
-+ ---
-+ 0x0 (000b) NONE No Function
-+ 0x1 (001b) LINK Complex function enabled when link is up
-+ 0x2 (010b) PDOWN Complex function enabled when device is powered-down
-+ 0x3 (011b) EEE Complex function enabled when device is in EEE mode
-+ 0x4 (100b) ANEG Complex function enabled when auto-negotiation is running
-+ 0x5 (101b) ABIST Complex function enabled when analog self-test is running
-+ 0x6 (110b) CDIAG Complex function enabled when cable diagnostics are running
-+ 0x7 (111b) TEST Complex function enabled when test mode is running
-+
-+LEDCL:
-+
-+Name Hardware Reset Value
-+LEDCL 0x0067
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+|RES | SCAN |RES | CBLINK |
-+=========================================
-+
-+Field Bits Type Description
-+SCAN 6:4 RW Complex Scan Configuration
-+ ---
-+ 000 B NONE No Function
-+ 001 B LINK Complex function enabled when link is up
-+ 010 B PDOWN Complex function enabled when device is powered-down
-+ 011 B EEE Complex function enabled when device is in EEE mode
-+ 100 B ANEG Complex function enabled when auto-negotiation is running
-+ 101 B ABIST Complex function enabled when analog self-test is running
-+ 110 B CDIAG Complex function enabled when cable diagnostics are running
-+ 111 B TEST Complex function enabled when test mode is running
-+
-+CBLINK 2:0 RW Complex Blinking Configuration
-+ ---
-+ 000 B NONE No Function
-+ 001 B LINK Complex function enabled when link is up
-+ 010 B PDOWN Complex function enabled when device is powered-down
-+ 011 B EEE Complex function enabled when device is in EEE mode
-+ 100 B ANEG Complex function enabled when auto-negotiation is running
-+ 101 B ABIST Complex function enabled when analog self-test is running
-+ 110 B CDIAG Complex function enabled when cable diagnostics are running
-+ 111 B TEST Complex function enabled when test mode is running
-+
-+LEDxH:
-+
-+Name Hardware Reset Value
-+LED0H 0x0070
-+LED1H 0x0020
-+LED2H 0x0040
-+LED3H 0x0040
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| CON | BLINKF |
-+=========================================
-+
-+Field Bits Type Description
-+CON 7:4 RW Constant On Configuration
-+ ---
-+ 0x0 (0000b) NONE LED does not light up constantly
-+ 0x1 (0001b) LINK10 LED is on when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 LED is on when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X LED is on when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 LED is on when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 LED is on when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X LED is on when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX LED is on when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN LED is on when device is powered-down
-+ 0x9 (1001b) EEE LED is on when device is in EEE mode
-+ 0xA (1010b) ANEG LED is on when auto-negotiation is running
-+ 0xB (1011b) ABIST LED is on when analog self-test is running
-+ 0xC (1100b) CDIAG LED is on when cable diagnostics are running
-+
-+BLINKF 3:0 RW Fast Blinking Configuration
-+ ---
-+ 0x0 (0000b) NONE No Blinking
-+ 0x1 (0001b) LINK10 Blink when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 Blink when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X Blink when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 Blink when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 Blink when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X Blink when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX Blink when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN Blink when device is powered-down
-+ 0x9 (1001b) EEE Blink when device is in EEE mode
-+ 0xA (1010b) ANEG Blink when auto-negotiation is running
-+ 0xB (1011b) ABIST Blink when analog self-test is running
-+ 0xC (1100b) CDIAG Blink when cable diagnostics are running
-+
-+LEDxL:
-+
-+Name Hardware Reset Value
-+LED0L 0x0003
-+LED1L 0x0000
-+LED2L 0x0000
-+LED3L 0x0020
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| BLINKS | PULSE |
-+=========================================
-+
-+Field Bits Type Description
-+BLINKS 7:4 RW Slow Blinkin Configuration
-+ ---
-+ 0x0 (0000b) NONE No Blinking
-+ 0x1 (0001b) LINK10 Blink when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 Blink when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X Blink when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 Blink when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 Blink when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X Blink when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX Blink when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN Blink when device is powered-down
-+ 0x9 (1001b) EEE Blink when device is in EEE mode
-+ 0xA (1010b) ANEG Blink when auto-negotiation is running
-+ 0xB (1011b) ABIST Blink when analog self-test is running
-+ 0xC (1100b) CDIAG Blink when cable diagnostics are runningning
-+
-+PULSE 3:0 RW Pulsing Configuration
-+ The pulse field is a mask field by which certain events can be combined
-+ ---
-+ 0x0 (0000b) NONE No pulsing
-+ 0x1 (0001b) TXACT Transmit activity
-+ 0x2 (0010b) RXACT Receive activity
-+ 0x4 (0100b) COL Collision
-+ 0x8 (1000b) RES Reserved
diff --git a/target/linux/lantiq/patches-5.15/0028-NET-lantiq-various-etop-fixes.patch b/target/linux/lantiq/patches-5.15/0028-NET-lantiq-various-etop-fixes.patch
deleted file mode 100644
index e9f3ee473b..0000000000
--- a/target/linux/lantiq/patches-5.15/0028-NET-lantiq-various-etop-fixes.patch
+++ /dev/null
@@ -1,864 +0,0 @@
-From 870ed9cae083ff8a60a739ef7e74c5a1800533be Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 9 Sep 2014 22:45:34 +0200
-Subject: [PATCH 28/36] NET: lantiq: various etop fixes
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -1,7 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- *
-- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
-+ * Copyright (C) 2011-12 John Crispin <blogic@openwrt.org>
- */
-
- #include <linux/kernel.h>
-@@ -20,11 +20,16 @@
- #include <linux/mm.h>
- #include <linux/platform_device.h>
- #include <linux/ethtool.h>
-+#include <linux/if_vlan.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/io.h>
- #include <linux/dma-mapping.h>
- #include <linux/module.h>
-+#include <linux/clk.h>
-+#include <linux/of_net.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_platform.h>
-
- #include <asm/checksum.h>
-
-@@ -32,7 +37,7 @@
- #include <xway_dma.h>
- #include <lantiq_platform.h>
-
--#define LTQ_ETOP_MDIO 0x11804
-+#define LTQ_ETOP_MDIO_ACC 0x11804
- #define MDIO_REQUEST 0x80000000
- #define MDIO_READ 0x40000000
- #define MDIO_ADDR_MASK 0x1f
-@@ -41,44 +46,91 @@
- #define MDIO_REG_OFFSET 0x10
- #define MDIO_VAL_MASK 0xffff
-
--#define PPE32_CGEN 0x800
--#define LQ_PPE32_ENET_MAC_CFG 0x1840
-+#define LTQ_ETOP_MDIO_CFG 0x11800
-+#define MDIO_CFG_MASK 0x6
-+
-+#define LTQ_ETOP_CFG 0x11808
-+#define LTQ_ETOP_IGPLEN 0x11820
-+#define LTQ_ETOP_MAC_CFG 0x11840
-
- #define LTQ_ETOP_ENETS0 0x11850
- #define LTQ_ETOP_MAC_DA0 0x1186C
- #define LTQ_ETOP_MAC_DA1 0x11870
--#define LTQ_ETOP_CFG 0x16020
--#define LTQ_ETOP_IGPLEN 0x16080
-+
-+#define MAC_CFG_MASK 0xfff
-+#define MAC_CFG_CGEN (1 << 11)
-+#define MAC_CFG_DUPLEX (1 << 2)
-+#define MAC_CFG_SPEED (1 << 1)
-+#define MAC_CFG_LINK (1 << 0)
-
- #define MAX_DMA_CHAN 0x8
- #define MAX_DMA_CRC_LEN 0x4
- #define MAX_DMA_DATA_LEN 0x600
-
- #define ETOP_FTCU BIT(28)
--#define ETOP_MII_MASK 0xf
--#define ETOP_MII_NORMAL 0xd
--#define ETOP_MII_REVERSE 0xe
- #define ETOP_PLEN_UNDER 0x40
--#define ETOP_CGEN 0x800
-+#define ETOP_CFG_MII0 0x01
-
--/* use 2 static channels for TX/RX */
--#define LTQ_ETOP_TX_CHANNEL 1
--#define LTQ_ETOP_RX_CHANNEL 6
--#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
--#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
-+#define ETOP_CFG_MASK 0xfff
-+#define ETOP_CFG_FEN0 (1 << 8)
-+#define ETOP_CFG_SEN0 (1 << 6)
-+#define ETOP_CFG_OFF1 (1 << 3)
-+#define ETOP_CFG_REMII0 (1 << 1)
-+#define ETOP_CFG_OFF0 (1 << 0)
-+
-+#define LTQ_GBIT_MDIO_CTL 0xCC
-+#define LTQ_GBIT_MDIO_DATA 0xd0
-+#define LTQ_GBIT_GCTL0 0x68
-+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
-+#define LTQ_GBIT_P0_CTL 0x4
-+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
-+#define LTQ_GBIT_RGMII_CTL 0x78
-+
-+#define PMAC_HD_CTL_AS (1 << 19)
-+#define PMAC_HD_CTL_RXSH (1 << 22)
-+
-+/* Switch Enable (0=disable, 1=enable) */
-+#define GCTL0_SE 0x80000000
-+/* Disable MDIO auto polling (0=disable, 1=enable) */
-+#define PX_CTL_DMDIO 0x00400000
-+
-+/* MDC clock divider, clock = 25MHz/((MDC_CLOCK + 1) * 2) */
-+#define MDC_CLOCK_MASK 0xff000000
-+#define MDC_CLOCK_OFFSET 24
-+
-+/* register information for the gbit's MDIO bus */
-+#define MDIO_XR9_REQUEST 0x00008000
-+#define MDIO_XR9_READ 0x00000800
-+#define MDIO_XR9_WRITE 0x00000400
-+#define MDIO_XR9_REG_MASK 0x1f
-+#define MDIO_XR9_ADDR_MASK 0x1f
-+#define MDIO_XR9_RD_MASK 0xffff
-+#define MDIO_XR9_REG_OFFSET 0
-+#define MDIO_XR9_ADDR_OFFSET 5
-+#define MDIO_XR9_WR_OFFSET 16
-
-+#define LTQ_DMA_ETOP ((of_machine_is_compatible("lantiq,ase")) ? \
-+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
-+
-+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
- #define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
- #define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
- #define ltq_etop_w32_mask(x, y, z) \
- ltq_w32_mask(x, y, ltq_etop_membase + (z))
-
--#define DRV_VERSION "1.0"
-+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
-+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
-+#define ltq_gbit_w32_mask(x, y, z) \
-+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
-+
-+#define DRV_VERSION "1.2"
-
- static void __iomem *ltq_etop_membase;
-+static void __iomem *ltq_gbit_membase;
-
- struct ltq_etop_chan {
-- int idx;
- int tx_free;
-+ int irq;
- struct net_device *netdev;
- struct napi_struct napi;
- struct ltq_dma_channel dma;
-@@ -88,23 +140,36 @@ struct ltq_etop_chan {
- struct ltq_etop_priv {
- struct net_device *netdev;
- struct platform_device *pdev;
-- struct ltq_eth_data *pldata;
- struct resource *res;
-
- struct mii_bus *mii_bus;
-
-- struct ltq_etop_chan ch[MAX_DMA_CHAN];
-- int tx_free[MAX_DMA_CHAN >> 1];
-+ struct ltq_etop_chan txch;
-+ struct ltq_etop_chan rxch;
-
-- spinlock_t lock;
-+ int tx_irq;
-+ int rx_irq;
-+
-+ unsigned char mac[6];
-+ phy_interface_t mii_mode;
-+
-+ spinlock_t lock;
-+
-+ struct clk *clk_ppe;
-+ struct clk *clk_switch;
-+ struct clk *clk_ephy;
-+ struct clk *clk_ephycgu;
- };
-
-+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data);
-+
- static int
- ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
- {
- struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
-
-- ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN);
-+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
- if (!ch->skb[ch->dma.desc])
- return -ENOMEM;
- ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(&priv->pdev->dev,
-@@ -139,8 +204,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan
- spin_unlock_irqrestore(&priv->lock, flags);
-
- skb_put(skb, len);
-+ skb->dev = ch->netdev;
- skb->protocol = eth_type_trans(skb, ch->netdev);
- netif_receive_skb(skb);
-+ ch->netdev->stats.rx_packets++;
-+ ch->netdev->stats.rx_bytes += len;
- }
-
- static int
-@@ -148,7 +216,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
- {
- struct ltq_etop_chan *ch = container_of(napi,
- struct ltq_etop_chan, napi);
-+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
- int work_done = 0;
-+ unsigned long flags;
-
- while (work_done < budget) {
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-@@ -160,7 +230,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
- }
- if (work_done < budget) {
- napi_complete_done(&ch->napi, work_done);
-+ spin_lock_irqsave(&priv->lock, flags);
- ltq_dma_ack_irq(&ch->dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
- }
- return work_done;
- }
-@@ -172,12 +244,14 @@ ltq_etop_poll_tx(struct napi_struct *nap
- container_of(napi, struct ltq_etop_chan, napi);
- struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
- struct netdev_queue *txq =
-- netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
-+ netdev_get_tx_queue(ch->netdev, ch->dma.nr >> 1);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- while ((ch->dma.desc_base[ch->tx_free].ctl &
- (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
-+ ch->netdev->stats.tx_packets++;
-+ ch->netdev->stats.tx_bytes += ch->skb[ch->tx_free]->len;
- dev_kfree_skb_any(ch->skb[ch->tx_free]);
- ch->skb[ch->tx_free] = NULL;
- memset(&ch->dma.desc_base[ch->tx_free], 0,
-@@ -190,7 +264,9 @@ ltq_etop_poll_tx(struct napi_struct *nap
- if (netif_tx_queue_stopped(txq))
- netif_tx_start_queue(txq);
- napi_complete(&ch->napi);
-+ spin_lock_irqsave(&priv->lock, flags);
- ltq_dma_ack_irq(&ch->dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
- return 1;
- }
-
-@@ -198,9 +274,10 @@ static irqreturn_t
- ltq_etop_dma_irq(int irq, void *_priv)
- {
- struct ltq_etop_priv *priv = _priv;
-- int ch = irq - LTQ_DMA_CH0_INT;
--
-- napi_schedule(&priv->ch[ch].napi);
-+ if (irq == priv->txch.dma.irq)
-+ napi_schedule(&priv->txch.napi);
-+ else
-+ napi_schedule(&priv->rxch.napi);
- return IRQ_HANDLED;
- }
-
-@@ -212,7 +289,7 @@ ltq_etop_free_channel(struct net_device
- ltq_dma_free(&ch->dma);
- if (ch->dma.irq)
- free_irq(ch->dma.irq, priv);
-- if (IS_RX(ch->idx)) {
-+ if (ch == &priv->txch) {
- int desc;
- for (desc = 0; desc < LTQ_DESC_NUM; desc++)
- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
-@@ -223,66 +300,135 @@ static void
- ltq_etop_hw_exit(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-
-- ltq_pmu_disable(PMU_PPE);
-- for (i = 0; i < MAX_DMA_CHAN; i++)
-- if (IS_TX(i) || IS_RX(i))
-- ltq_etop_free_channel(dev, &priv->ch[i]);
-+ clk_disable(priv->clk_ppe);
-+
-+ if (of_machine_is_compatible("lantiq,ar9"))
-+ clk_disable(priv->clk_switch);
-+
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ clk_disable(priv->clk_ephy);
-+ clk_disable(priv->clk_ephycgu);
-+ }
-+
-+ ltq_etop_free_channel(dev, &priv->txch);
-+ ltq_etop_free_channel(dev, &priv->rxch);
-+}
-+
-+static void
-+ltq_etop_gbit_init(struct net_device *dev)
-+{
-+ struct ltq_etop_priv *priv = netdev_priv(dev);
-+
-+ clk_enable(priv->clk_switch);
-+
-+ /* enable gbit port0 on the SoC */
-+ ltq_gbit_w32_mask((1 << 17), (1 << 18), LTQ_GBIT_P0_CTL);
-+
-+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
-+ /* disable MDIO auto polling mode */
-+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
-+ /* set 1522 packet size */
-+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
-+ /* disable pmac & dmac headers */
-+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
-+ LTQ_GBIT_PMAC_HD_CTL);
-+ /* Due to traffic halt when burst length 8,
-+ replace default IPG value with 0x3B */
-+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
-+ /* set mdc clock to 2.5 MHz */
-+ ltq_gbit_w32_mask(MDC_CLOCK_MASK, 4 << MDC_CLOCK_OFFSET,
-+ LTQ_GBIT_RGMII_CTL);
- }
-
- static int
- ltq_etop_hw_init(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ phy_interface_t mii_mode = priv->mii_mode;
-
-- ltq_pmu_enable(PMU_PPE);
-+ clk_enable(priv->clk_ppe);
-
-- switch (priv->pldata->mii_mode) {
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ ltq_etop_gbit_init(dev);
-+ /* force the etops link to the gbit to MII */
-+ mii_mode = PHY_INTERFACE_MODE_MII;
-+ }
-+ ltq_etop_w32_mask(MDIO_CFG_MASK, 0, LTQ_ETOP_MDIO_CFG);
-+ ltq_etop_w32_mask(MAC_CFG_MASK, MAC_CFG_CGEN | MAC_CFG_DUPLEX |
-+ MAC_CFG_SPEED | MAC_CFG_LINK, LTQ_ETOP_MAC_CFG);
-+
-+ switch (mii_mode) {
- case PHY_INTERFACE_MODE_RMII:
-- ltq_etop_w32_mask(ETOP_MII_MASK,
-- ETOP_MII_REVERSE, LTQ_ETOP_CFG);
-+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_REMII0 | ETOP_CFG_OFF1 |
-+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
- break;
-
- case PHY_INTERFACE_MODE_MII:
-- ltq_etop_w32_mask(ETOP_MII_MASK,
-- ETOP_MII_NORMAL, LTQ_ETOP_CFG);
-+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_OFF1 |
-+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
- break;
-
- default:
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ clk_enable(priv->clk_ephy);
-+ /* disable external MII */
-+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
-+ /* enable clock for internal PHY */
-+ clk_enable(priv->clk_ephycgu);
-+ /* we need to write this magic to the internal phy to
-+ make it work */
-+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
-+ pr_info("Selected EPHY mode\n");
-+ break;
-+ }
- netdev_err(dev, "unknown mii mode %d\n",
-- priv->pldata->mii_mode);
-+ mii_mode);
- return -ENOTSUPP;
- }
-
-- /* enable crc generation */
-- ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
-+ return 0;
-+}
-+
-+static int
-+ltq_etop_dma_init(struct net_device *dev)
-+{
-+ struct ltq_etop_priv *priv = netdev_priv(dev);
-+ int tx = priv->tx_irq - LTQ_DMA_ETOP;
-+ int rx = priv->rx_irq - LTQ_DMA_ETOP;
-+ int err;
-
- ltq_dma_init_port(DMA_PORT_ETOP);
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- int irq = LTQ_DMA_CH0_INT + i;
-- struct ltq_etop_chan *ch = &priv->ch[i];
--
-- ch->idx = ch->dma.nr = i;
-- ch->dma.dev = &priv->pdev->dev;
--
-- if (IS_TX(i)) {
-- ltq_dma_alloc_tx(&ch->dma);
-- request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv);
-- } else if (IS_RX(i)) {
-- ltq_dma_alloc_rx(&ch->dma);
-- for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
-- ch->dma.desc++)
-- if (ltq_etop_alloc_skb(ch))
-- return -ENOMEM;
-- ch->dma.desc = 0;
-- request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv);
-+ priv->txch.dma.nr = tx;
-+ priv->txch.dma.dev = &priv->pdev->dev;
-+ ltq_dma_alloc_tx(&priv->txch.dma);
-+ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, 0, "eth_tx", priv);
-+ if (err) {
-+ netdev_err(dev, "failed to allocate tx irq\n");
-+ goto err_out;
-+ }
-+ priv->txch.dma.irq = priv->tx_irq;
-+
-+ priv->rxch.dma.nr = rx;
-+ priv->rxch.dma.dev = &priv->pdev->dev;
-+ ltq_dma_alloc_rx(&priv->rxch.dma);
-+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM;
-+ priv->rxch.dma.desc++) {
-+ if (ltq_etop_alloc_skb(&priv->rxch)) {
-+ netdev_err(dev, "failed to allocate skbs\n");
-+ err = -ENOMEM;
-+ goto err_out;
- }
-- ch->dma.irq = irq;
- }
-- return 0;
-+ priv->rxch.dma.desc = 0;
-+ err = request_irq(priv->rx_irq, ltq_etop_dma_irq, 0, "eth_rx", priv);
-+ if (err)
-+ netdev_err(dev, "failed to allocate rx irq\n");
-+ else
-+ priv->rxch.dma.irq = priv->rx_irq;
-+err_out:
-+ return err;
- }
-
- static void
-@@ -301,6 +447,39 @@ static const struct ethtool_ops ltq_etop
- };
-
- static int
-+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data)
-+{
-+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
-+ (phy_data << MDIO_XR9_WR_OFFSET) |
-+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
-+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
-+
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ return 0;
-+}
-+
-+static int
-+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
-+{
-+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
-+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
-+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
-+
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
-+ return val;
-+}
-+
-+static int
- ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
- {
- u32 val = MDIO_REQUEST |
-@@ -308,9 +487,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
- ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
- phy_data;
-
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- ltq_etop_w32(val, LTQ_ETOP_MDIO);
-+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
- return 0;
- }
-
-@@ -321,12 +500,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
- ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
- ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
-
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- ltq_etop_w32(val, LTQ_ETOP_MDIO);
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
-+ val = ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_VAL_MASK;
- return val;
- }
-
-@@ -342,7 +521,10 @@ ltq_etop_mdio_probe(struct net_device *d
- struct ltq_etop_priv *priv = netdev_priv(dev);
- struct phy_device *phydev;
-
-- phydev = phy_find_first(priv->mii_bus);
-+ if (of_machine_is_compatible("lantiq,ase"))
-+ phydev = mdiobus_get_phy(priv->mii_bus, 8);
-+ else
-+ phydev = mdiobus_get_phy(priv->mii_bus, 0);
-
- if (!phydev) {
- netdev_err(dev, "no PHY found\n");
-@@ -350,14 +532,17 @@ ltq_etop_mdio_probe(struct net_device *d
- }
-
- phydev = phy_connect(dev, phydev_name(phydev),
-- &ltq_etop_mdio_link, priv->pldata->mii_mode);
-+ &ltq_etop_mdio_link, priv->mii_mode);
-
- if (IS_ERR(phydev)) {
- netdev_err(dev, "Could not attach to PHY\n");
- return PTR_ERR(phydev);
- }
-
-- phy_set_max_speed(phydev, SPEED_100);
-+ if (of_machine_is_compatible("lantiq,ar9"))
-+ phy_set_max_speed(phydev, SPEED_1000);
-+ else
-+ phy_set_max_speed(phydev, SPEED_100);
-
- phy_attached_info(phydev);
-
-@@ -378,8 +563,13 @@ ltq_etop_mdio_init(struct net_device *de
- }
-
- priv->mii_bus->priv = dev;
-- priv->mii_bus->read = ltq_etop_mdio_rd;
-- priv->mii_bus->write = ltq_etop_mdio_wr;
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
-+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
-+ } else {
-+ priv->mii_bus->read = ltq_etop_mdio_rd;
-+ priv->mii_bus->write = ltq_etop_mdio_wr;
-+ }
- priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- priv->pdev->name, priv->pdev->id);
-@@ -416,18 +606,21 @@ static int
- ltq_etop_open(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ unsigned long flags;
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- struct ltq_etop_chan *ch = &priv->ch[i];
-+ napi_enable(&priv->txch.napi);
-+ napi_enable(&priv->rxch.napi);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ ltq_dma_open(&priv->txch.dma);
-+ ltq_dma_enable_irq(&priv->txch.dma);
-+ ltq_dma_open(&priv->rxch.dma);
-+ ltq_dma_enable_irq(&priv->rxch.dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ if (dev->phydev)
-+ phy_start(dev->phydev);
-
-- if (!IS_TX(i) && (!IS_RX(i)))
-- continue;
-- ltq_dma_open(&ch->dma);
-- ltq_dma_enable_irq(&ch->dma);
-- napi_enable(&ch->napi);
-- }
-- phy_start(dev->phydev);
- netif_tx_start_all_queues(dev);
- return 0;
- }
-@@ -436,18 +629,19 @@ static int
- ltq_etop_stop(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ unsigned long flags;
-
- netif_tx_stop_all_queues(dev);
-- phy_stop(dev->phydev);
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- struct ltq_etop_chan *ch = &priv->ch[i];
--
-- if (!IS_RX(i) && !IS_TX(i))
-- continue;
-- napi_disable(&ch->napi);
-- ltq_dma_close(&ch->dma);
-- }
-+ if (dev->phydev)
-+ phy_stop(dev->phydev);
-+ napi_disable(&priv->txch.napi);
-+ napi_disable(&priv->rxch.napi);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ ltq_dma_close(&priv->txch.dma);
-+ ltq_dma_close(&priv->rxch.dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
- return 0;
- }
-
-@@ -457,15 +651,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
- int queue = skb_get_queue_mapping(skb);
- struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
-- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-- int len;
-+ struct ltq_dma_desc *desc =
-+ &priv->txch.dma.desc_base[priv->txch.dma.desc];
- unsigned long flags;
- u32 byte_offset;
-+ int len;
-
- len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
-
-- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
-+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
-+ priv->txch.skb[priv->txch.dma.desc]) {
- netdev_err(dev, "tx ring full\n");
- netif_tx_stop_queue(txq);
- return NETDEV_TX_BUSY;
-@@ -473,7 +668,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
-
- /* dma needs to start on a 16 byte aligned address */
- byte_offset = CPHYSADDR(skb->data) % 16;
-- ch->skb[ch->dma.desc] = skb;
-+ priv->txch.skb[priv->txch.dma.desc] = skb;
-
- netif_trans_update(dev);
-
-@@ -483,11 +678,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
- wmb();
- desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
- LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
-- ch->dma.desc++;
-- ch->dma.desc %= LTQ_DESC_NUM;
-+ priv->txch.dma.desc++;
-+ priv->txch.dma.desc %= LTQ_DESC_NUM;
- spin_unlock_irqrestore(&priv->lock, flags);
-
-- if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
-+ if (priv->txch.dma.desc_base[priv->txch.dma.desc].ctl & LTQ_DMA_OWN)
- netif_tx_stop_queue(txq);
-
- return NETDEV_TX_OK;
-@@ -498,11 +693,14 @@ ltq_etop_change_mtu(struct net_device *d
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
- unsigned long flags;
-+ int max;
-
- dev->mtu = new_mtu;
-
-+ max = ETH_HLEN + VLAN_HLEN + new_mtu + ETH_FCS_LEN;
-+
- spin_lock_irqsave(&priv->lock, flags);
-- ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu, LTQ_ETOP_IGPLEN);
-+ ltq_etop_w32((ETOP_PLEN_UNDER << 16) | max, LTQ_ETOP_IGPLEN);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-@@ -555,6 +753,9 @@ ltq_etop_init(struct net_device *dev)
- if (err)
- goto err_hw;
- ltq_etop_change_mtu(dev, 1500);
-+ err = ltq_etop_dma_init(dev);
-+ if (err)
-+ goto err_hw;
-
- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
- if (!is_valid_ether_addr(mac.sa_data)) {
-@@ -572,9 +773,10 @@ ltq_etop_init(struct net_device *dev)
- dev->addr_assign_type = NET_ADDR_RANDOM;
-
- ltq_etop_set_multicast_list(dev);
-- err = ltq_etop_mdio_init(dev);
-- if (err)
-- goto err_netdev;
-+ if (!ltq_etop_mdio_init(dev))
-+ dev->ethtool_ops = &ltq_etop_ethtool_ops;
-+ else
-+ pr_warn("etop: mdio probe failed\n");;
- return 0;
-
- err_netdev:
-@@ -594,6 +796,9 @@ ltq_etop_tx_timeout(struct net_device *d
- err = ltq_etop_hw_init(dev);
- if (err)
- goto err_hw;
-+ err = ltq_etop_dma_init(dev);
-+ if (err)
-+ goto err_hw;
- netif_trans_update(dev);
- netif_wake_queue(dev);
- return;
-@@ -617,14 +822,18 @@ static const struct net_device_ops ltq_e
- .ndo_tx_timeout = ltq_etop_tx_timeout,
- };
-
--static int __init
--ltq_etop_probe(struct platform_device *pdev)
-+static int ltq_etop_probe(struct platform_device *pdev)
- {
- struct net_device *dev;
- struct ltq_etop_priv *priv;
-- struct resource *res;
-+ struct resource *res, *gbit_res, irqres[2];
- int err;
-- int i;
-+
-+ err = of_irq_to_resource_table(pdev->dev.of_node, irqres, 2);
-+ if (err != 2) {
-+ dev_err(&pdev->dev, "failed to get etop irqs\n");
-+ return -EINVAL;
-+ }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
-@@ -650,31 +859,62 @@ ltq_etop_probe(struct platform_device *p
- goto err_out;
- }
-
-- dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
-- if (!dev) {
-- err = -ENOMEM;
-- goto err_out;
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+ if (!gbit_res) {
-+ dev_err(&pdev->dev, "failed to get gbit resource\n");
-+ err = -ENOENT;
-+ goto err_out;
-+ }
-+ ltq_gbit_membase = devm_ioremap(&pdev->dev,
-+ gbit_res->start, resource_size(gbit_res));
-+ if (!ltq_gbit_membase) {
-+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
-+ pdev->id);
-+ err = -ENOMEM;
-+ goto err_out;
-+ }
- }
-+
-+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
- strcpy(dev->name, "eth%d");
- dev->netdev_ops = &ltq_eth_netdev_ops;
-- dev->ethtool_ops = &ltq_etop_ethtool_ops;
- priv = netdev_priv(dev);
- priv->res = res;
- priv->pdev = pdev;
-- priv->pldata = dev_get_platdata(&pdev->dev);
- priv->netdev = dev;
-+ priv->tx_irq = irqres[0].start;
-+ priv->rx_irq = irqres[1].start;
-+ err = of_get_phy_mode(pdev->dev.of_node, &priv->mii_mode);
-+ if (err)
-+ pr_err("Can't find phy-mode for port\n");
-+
-+ of_get_mac_address(pdev->dev.of_node, priv->mac);
-+
-+ priv->clk_ppe = clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->clk_ppe))
-+ return PTR_ERR(priv->clk_ppe);
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ priv->clk_switch = clk_get(&pdev->dev, "switch");
-+ if (IS_ERR(priv->clk_switch))
-+ return PTR_ERR(priv->clk_switch);
-+ }
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ priv->clk_ephy = clk_get(&pdev->dev, "ephy");
-+ if (IS_ERR(priv->clk_ephy))
-+ return PTR_ERR(priv->clk_ephy);
-+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu");
-+ if (IS_ERR(priv->clk_ephycgu))
-+ return PTR_ERR(priv->clk_ephycgu);
-+ }
-+
- spin_lock_init(&priv->lock);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- if (IS_TX(i))
-- netif_napi_add(dev, &priv->ch[i].napi,
-- ltq_etop_poll_tx, 8);
-- else if (IS_RX(i))
-- netif_napi_add(dev, &priv->ch[i].napi,
-- ltq_etop_poll_rx, 32);
-- priv->ch[i].netdev = dev;
-- }
-+ netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
-+ netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
-+ priv->txch.netdev = dev;
-+ priv->rxch.netdev = dev;
-
- err = register_netdev(dev);
- if (err)
-@@ -703,31 +943,22 @@ ltq_etop_remove(struct platform_device *
- return 0;
- }
-
-+static const struct of_device_id ltq_etop_match[] = {
-+ { .compatible = "lantiq,etop-xway" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ltq_etop_match);
-+
- static struct platform_driver ltq_mii_driver = {
-+ .probe = ltq_etop_probe,
- .remove = ltq_etop_remove,
- .driver = {
- .name = "ltq_etop",
-+ .of_match_table = ltq_etop_match,
- },
- };
-
--int __init
--init_ltq_etop(void)
--{
-- int ret = platform_driver_probe(&ltq_mii_driver, ltq_etop_probe);
--
-- if (ret)
-- pr_err("ltq_etop: Error registering platform driver!");
-- return ret;
--}
--
--static void __exit
--exit_ltq_etop(void)
--{
-- platform_driver_unregister(&ltq_mii_driver);
--}
--
--module_init(init_ltq_etop);
--module_exit(exit_ltq_etop);
-+module_platform_driver(ltq_mii_driver);
-
- MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
- MODULE_DESCRIPTION("Lantiq SoC ETOP");
diff --git a/target/linux/lantiq/patches-5.15/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch b/target/linux/lantiq/patches-5.15/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch
deleted file mode 100644
index 2d3b4e2996..0000000000
--- a/target/linux/lantiq/patches-5.15/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch
+++ /dev/null
@@ -1,1034 +0,0 @@
-From f17e50f67fa3c77624edf2ca03fae0d50f0ce39b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:26:42 +0200
-Subject: [PATCH 31/36] I2C: MIPS: lantiq: add FALC-ON i2c bus master
-
-This patch adds the driver needed to make the I2C bus work on FALC-ON SoCs.
-
-Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/i2c/busses/Kconfig | 10 +
- drivers/i2c/busses/Makefile | 1 +
- drivers/i2c/busses/i2c-lantiq.c | 747 +++++++++++++++++++++++++++++++++++++++
- drivers/i2c/busses/i2c-lantiq.h | 234 ++++++++++++
- 4 files changed, 992 insertions(+)
- create mode 100644 drivers/i2c/busses/i2c-lantiq.c
- create mode 100644 drivers/i2c/busses/i2c-lantiq.h
-
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -757,6 +757,16 @@ config I2C_MESON
- If you say yes to this option, support will be included for the
- I2C interface on the Amlogic Meson family of SoCs.
-
-+config I2C_LANTIQ
-+ tristate "Lantiq I2C interface"
-+ depends on LANTIQ && SOC_FALCON
-+ help
-+ If you say yes to this option, support will be included for the
-+ Lantiq I2C core.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called i2c-lantiq.
-+
- config I2C_MPC
- tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
- depends on PPC
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -72,6 +72,7 @@ obj-$(CONFIG_I2C_IMX_LPI2C) += i2c-imx-l
- obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
- obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
- obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
-+obj-$(CONFIG_I2C_LANTIQ) += i2c-lantiq.o
- obj-$(CONFIG_I2C_LPC2K) += i2c-lpc2k.o
- obj-$(CONFIG_I2C_MESON) += i2c-meson.o
- obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-lantiq.c
-@@ -0,0 +1,747 @@
-+
-+/*
-+ * Lantiq I2C bus adapter
-+ *
-+ * Parts based on i2c-designware.c and other i2c drivers from Linux 2.6.33
-+ *
-+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h> /* for kzalloc, kfree */
-+#include <linux/i2c.h>
-+#include <linux/errno.h>
-+#include <linux/completion.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/of_irq.h>
-+
-+#include <lantiq_soc.h>
-+#include "i2c-lantiq.h"
-+
-+/*
-+ * CURRENT ISSUES:
-+ * - no high speed support
-+ * - ten bit mode is not tested (no slave devices)
-+ */
-+
-+/* access macros */
-+#define i2c_r32(reg) \
-+ __raw_readl(&(priv->membase)->reg)
-+#define i2c_w32(val, reg) \
-+ __raw_writel(val, &(priv->membase)->reg)
-+#define i2c_w32_mask(clear, set, reg) \
-+ i2c_w32((i2c_r32(reg) & ~(clear)) | (set), reg)
-+
-+#define DRV_NAME "i2c-lantiq"
-+#define DRV_VERSION "1.00"
-+
-+#define LTQ_I2C_BUSY_TIMEOUT 20 /* ms */
-+
-+#ifdef DEBUG
-+#define LTQ_I2C_XFER_TIMEOUT (25*HZ)
-+#else
-+#define LTQ_I2C_XFER_TIMEOUT HZ
-+#endif
-+
-+#define LTQ_I2C_IMSC_DEFAULT_MASK (I2C_IMSC_I2C_P_INT_EN | \
-+ I2C_IMSC_I2C_ERR_INT_EN)
-+
-+#define LTQ_I2C_ARB_LOST (1 << 0)
-+#define LTQ_I2C_NACK (1 << 1)
-+#define LTQ_I2C_RX_UFL (1 << 2)
-+#define LTQ_I2C_RX_OFL (1 << 3)
-+#define LTQ_I2C_TX_UFL (1 << 4)
-+#define LTQ_I2C_TX_OFL (1 << 5)
-+
-+struct ltq_i2c {
-+ struct mutex mutex;
-+
-+
-+ /* active clock settings */
-+ unsigned int input_clock; /* clock input for i2c hardware block */
-+ unsigned int i2c_clock; /* approximated bus clock in kHz */
-+
-+ struct clk *clk_gate;
-+ struct clk *clk_input;
-+
-+
-+ /* resources (memory and interrupts) */
-+ int irq_lb; /* last burst irq */
-+
-+ struct lantiq_reg_i2c __iomem *membase; /* base of mapped registers */
-+
-+ struct i2c_adapter adap;
-+ struct device *dev;
-+
-+ struct completion cmd_complete;
-+
-+
-+ /* message transfer data */
-+ struct i2c_msg *current_msg; /* current message */
-+ int msgs_num; /* number of messages to handle */
-+ u8 *msg_buf; /* current buffer */
-+ u32 msg_buf_len; /* remaining length of current buffer */
-+ int msg_err; /* error status of the current transfer */
-+
-+
-+ /* master status codes */
-+ enum {
-+ STATUS_IDLE,
-+ STATUS_ADDR, /* address phase */
-+ STATUS_WRITE,
-+ STATUS_READ,
-+ STATUS_READ_END,
-+ STATUS_STOP
-+ } status;
-+};
-+
-+static irqreturn_t ltq_i2c_isr(int irq, void *dev_id);
-+
-+static inline void enable_burst_irq(struct ltq_i2c *priv)
-+{
-+ i2c_w32_mask(0, I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, imsc);
-+}
-+static inline void disable_burst_irq(struct ltq_i2c *priv)
-+{
-+ i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, 0, imsc);
-+}
-+
-+static void prepare_msg_send_addr(struct ltq_i2c *priv)
-+{
-+ struct i2c_msg *msg = priv->current_msg;
-+ int rd = !!(msg->flags & I2C_M_RD); /* extends to 0 or 1 */
-+ u16 addr = msg->addr;
-+
-+ /* new i2c_msg */
-+ priv->msg_buf = msg->buf;
-+ priv->msg_buf_len = msg->len;
-+ if (rd)
-+ priv->status = STATUS_READ;
-+ else
-+ priv->status = STATUS_WRITE;
-+
-+ /* send slave address */
-+ if (msg->flags & I2C_M_TEN) {
-+ i2c_w32(0xf0 | ((addr & 0x300) >> 7) | rd, txd);
-+ i2c_w32(addr & 0xff, txd);
-+ } else {
-+ i2c_w32((addr & 0x7f) << 1 | rd, txd);
-+ }
-+}
-+
-+static void ltq_i2c_set_tx_len(struct ltq_i2c *priv)
-+{
-+ struct i2c_msg *msg = priv->current_msg;
-+ int len = (msg->flags & I2C_M_TEN) ? 2 : 1;
-+
-+ pr_debug("set_tx_len %cX\n", (msg->flags & I2C_M_RD) ? 'R' : 'T');
-+
-+ priv->status = STATUS_ADDR;
-+
-+ if (!(msg->flags & I2C_M_RD))
-+ len += msg->len;
-+ else
-+ /* set maximum received packet size (before rx int!) */
-+ i2c_w32(msg->len, mrps_ctrl);
-+ i2c_w32(len, tps_ctrl);
-+ enable_burst_irq(priv);
-+}
-+
-+static int ltq_i2c_hw_set_clock(struct i2c_adapter *adap)
-+{
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+ unsigned int input_clock = clk_get_rate(priv->clk_input);
-+ u32 dec, inc = 1;
-+
-+ /* clock changed? */
-+ if (priv->input_clock == input_clock)
-+ return 0;
-+
-+ /*
-+ * this formula is only an approximation, found by the recommended
-+ * values in the "I2C Architecture Specification 1.7.1"
-+ */
-+ dec = input_clock / (priv->i2c_clock * 2);
-+ if (dec <= 6)
-+ return -ENXIO;
-+
-+ i2c_w32(0, fdiv_high_cfg);
-+ i2c_w32((inc << I2C_FDIV_CFG_INC_OFFSET) |
-+ (dec << I2C_FDIV_CFG_DEC_OFFSET),
-+ fdiv_cfg);
-+
-+ dev_info(priv->dev, "setup clocks (in %d kHz, bus %d kHz, dec=%d)\n",
-+ input_clock, priv->i2c_clock, dec);
-+
-+ priv->input_clock = input_clock;
-+ return 0;
-+}
-+
-+static int ltq_i2c_hw_init(struct i2c_adapter *adap)
-+{
-+ int ret = 0;
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+
-+ /* disable bus */
-+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
-+
-+#ifndef DEBUG
-+ /* set normal operation clock divider */
-+ i2c_w32(1 << I2C_CLC_RMC_OFFSET, clc);
-+#else
-+ /* for debugging a higher divider value! */
-+ i2c_w32(0xF0 << I2C_CLC_RMC_OFFSET, clc);
-+#endif
-+
-+ /* setup clock */
-+ ret = ltq_i2c_hw_set_clock(adap);
-+ if (ret != 0) {
-+ dev_warn(priv->dev, "invalid clock settings\n");
-+ return ret;
-+ }
-+
-+ /* configure fifo */
-+ i2c_w32(I2C_FIFO_CFG_TXFC | /* tx fifo as flow controller */
-+ I2C_FIFO_CFG_RXFC | /* rx fifo as flow controller */
-+ I2C_FIFO_CFG_TXFA_TXFA2 | /* tx fifo 4-byte aligned */
-+ I2C_FIFO_CFG_RXFA_RXFA2 | /* rx fifo 4-byte aligned */
-+ I2C_FIFO_CFG_TXBS_TXBS0 | /* tx fifo burst size is 1 word */
-+ I2C_FIFO_CFG_RXBS_RXBS0, /* rx fifo burst size is 1 word */
-+ fifo_cfg);
-+
-+ /* configure address */
-+ i2c_w32(I2C_ADDR_CFG_SOPE_EN | /* generate stop when no more data in
-+ the fifo */
-+ I2C_ADDR_CFG_SONA_EN | /* generate stop when NA received */
-+ I2C_ADDR_CFG_MnS_EN | /* we are master device */
-+ 0, /* our slave address (not used!) */
-+ addr_cfg);
-+
-+ /* enable bus */
-+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
-+
-+ return 0;
-+}
-+
-+static int ltq_i2c_wait_bus_not_busy(struct ltq_i2c *priv)
-+{
-+ unsigned long timeout;
-+
-+ timeout = jiffies + msecs_to_jiffies(LTQ_I2C_BUSY_TIMEOUT);
-+
-+ do {
-+ u32 stat = i2c_r32(bus_stat);
-+
-+ if ((stat & I2C_BUS_STAT_BS_MASK) == I2C_BUS_STAT_BS_FREE)
-+ return 0;
-+
-+ cond_resched();
-+ } while (!time_after_eq(jiffies, timeout));
-+
-+ dev_err(priv->dev, "timeout waiting for bus ready\n");
-+ return -ETIMEDOUT;
-+}
-+
-+static void ltq_i2c_tx(struct ltq_i2c *priv, int last)
-+{
-+ if (priv->msg_buf_len && priv->msg_buf) {
-+ i2c_w32(*priv->msg_buf, txd);
-+
-+ if (--priv->msg_buf_len)
-+ priv->msg_buf++;
-+ else
-+ priv->msg_buf = NULL;
-+ } else {
-+ last = 1;
-+ }
-+
-+ if (last)
-+ disable_burst_irq(priv);
-+}
-+
-+static void ltq_i2c_rx(struct ltq_i2c *priv, int last)
-+{
-+ u32 fifo_stat, timeout;
-+ if (priv->msg_buf_len && priv->msg_buf) {
-+ timeout = 5000000;
-+ do {
-+ fifo_stat = i2c_r32(ffs_stat);
-+ } while (!fifo_stat && --timeout);
-+ if (!timeout) {
-+ last = 1;
-+ pr_debug("\nrx timeout\n");
-+ goto err;
-+ }
-+ while (fifo_stat) {
-+ *priv->msg_buf = i2c_r32(rxd);
-+ if (--priv->msg_buf_len) {
-+ priv->msg_buf++;
-+ } else {
-+ priv->msg_buf = NULL;
-+ last = 1;
-+ break;
-+ }
-+ /*
-+ * do not read more than burst size, otherwise no "last
-+ * burst" is generated and the transaction is blocked!
-+ */
-+ fifo_stat = 0;
-+ }
-+ } else {
-+ last = 1;
-+ }
-+err:
-+ if (last) {
-+ disable_burst_irq(priv);
-+
-+ if (priv->status == STATUS_READ_END) {
-+ /*
-+ * do the STATUS_STOP and complete() here, as sometimes
-+ * the tx_end is already seen before this is finished
-+ */
-+ priv->status = STATUS_STOP;
-+ complete(&priv->cmd_complete);
-+ } else {
-+ i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
-+ priv->status = STATUS_READ_END;
-+ }
-+ }
-+}
-+
-+static void ltq_i2c_xfer_init(struct ltq_i2c *priv)
-+{
-+ /* enable interrupts */
-+ i2c_w32(LTQ_I2C_IMSC_DEFAULT_MASK, imsc);
-+
-+ /* trigger transfer of first msg */
-+ ltq_i2c_set_tx_len(priv);
-+}
-+
-+static void dump_msgs(struct i2c_msg msgs[], int num, int rx)
-+{
-+#if defined(DEBUG)
-+ int i, j;
-+ pr_debug("Messages %d %s\n", num, rx ? "out" : "in");
-+ for (i = 0; i < num; i++) {
-+ pr_debug("%2d %cX Msg(%d) addr=0x%X: ", i,
-+ (msgs[i].flags & I2C_M_RD) ? 'R' : 'T',
-+ msgs[i].len, msgs[i].addr);
-+ if (!(msgs[i].flags & I2C_M_RD) || rx) {
-+ for (j = 0; j < msgs[i].len; j++)
-+ pr_debug("%02X ", msgs[i].buf[j]);
-+ }
-+ pr_debug("\n");
-+ }
-+#endif
-+}
-+
-+static void ltq_i2c_release_bus(struct ltq_i2c *priv)
-+{
-+ if ((i2c_r32(bus_stat) & I2C_BUS_STAT_BS_MASK) == I2C_BUS_STAT_BS_BM)
-+ i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
-+}
-+
-+static int ltq_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
-+ int num)
-+{
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+ int ret;
-+
-+ dev_dbg(priv->dev, "xfer %u messages\n", num);
-+ dump_msgs(msgs, num, 0);
-+
-+ mutex_lock(&priv->mutex);
-+
-+ init_completion(&priv->cmd_complete);
-+ priv->current_msg = msgs;
-+ priv->msgs_num = num;
-+ priv->msg_err = 0;
-+ priv->status = STATUS_IDLE;
-+
-+ /* wait for the bus to become ready */
-+ ret = ltq_i2c_wait_bus_not_busy(priv);
-+ if (ret)
-+ goto done;
-+
-+ while (priv->msgs_num) {
-+ /* start the transfers */
-+ ltq_i2c_xfer_init(priv);
-+
-+ /* wait for transfers to complete */
-+ ret = wait_for_completion_interruptible_timeout(
-+ &priv->cmd_complete, LTQ_I2C_XFER_TIMEOUT);
-+ if (ret == 0) {
-+ dev_err(priv->dev, "controller timed out\n");
-+ ltq_i2c_hw_init(adap);
-+ ret = -ETIMEDOUT;
-+ goto done;
-+ } else if (ret < 0)
-+ goto done;
-+
-+ if (priv->msg_err) {
-+ if (priv->msg_err & LTQ_I2C_NACK)
-+ ret = -ENXIO;
-+ else
-+ ret = -EREMOTEIO;
-+ goto done;
-+ }
-+ if (--priv->msgs_num)
-+ priv->current_msg++;
-+ }
-+ /* no error? */
-+ ret = num;
-+
-+done:
-+ ltq_i2c_release_bus(priv);
-+
-+ mutex_unlock(&priv->mutex);
-+
-+ if (ret >= 0)
-+ dump_msgs(msgs, num, 1);
-+
-+ pr_debug("XFER ret %d\n", ret);
-+ return ret;
-+}
-+
-+static irqreturn_t ltq_i2c_isr_burst(int irq, void *dev_id)
-+{
-+ struct ltq_i2c *priv = dev_id;
-+ struct i2c_msg *msg = priv->current_msg;
-+ int last = (irq == priv->irq_lb);
-+
-+ if (last)
-+ pr_debug("LB ");
-+ else
-+ pr_debug("B ");
-+
-+ if (msg->flags & I2C_M_RD) {
-+ switch (priv->status) {
-+ case STATUS_ADDR:
-+ pr_debug("X");
-+ prepare_msg_send_addr(priv);
-+ disable_burst_irq(priv);
-+ break;
-+ case STATUS_READ:
-+ case STATUS_READ_END:
-+ pr_debug("R");
-+ ltq_i2c_rx(priv, last);
-+ break;
-+ default:
-+ disable_burst_irq(priv);
-+ pr_warn("Status R %d\n", priv->status);
-+ break;
-+ }
-+ } else {
-+ switch (priv->status) {
-+ case STATUS_ADDR:
-+ pr_debug("x");
-+ prepare_msg_send_addr(priv);
-+ break;
-+ case STATUS_WRITE:
-+ pr_debug("w");
-+ ltq_i2c_tx(priv, last);
-+ break;
-+ default:
-+ disable_burst_irq(priv);
-+ pr_warn("Status W %d\n", priv->status);
-+ break;
-+ }
-+ }
-+
-+ i2c_w32(I2C_ICR_BREQ_INT_CLR | I2C_ICR_LBREQ_INT_CLR, icr);
-+ return IRQ_HANDLED;
-+}
-+
-+static void ltq_i2c_isr_prot(struct ltq_i2c *priv)
-+{
-+ u32 i_pro = i2c_r32(p_irqss);
-+
-+ pr_debug("i2c-p");
-+
-+ /* not acknowledge */
-+ if (i_pro & I2C_P_IRQSS_NACK) {
-+ priv->msg_err |= LTQ_I2C_NACK;
-+ pr_debug(" nack");
-+ }
-+
-+ /* arbitration lost */
-+ if (i_pro & I2C_P_IRQSS_AL) {
-+ priv->msg_err |= LTQ_I2C_ARB_LOST;
-+ pr_debug(" arb-lost");
-+ }
-+ /* tx -> rx switch */
-+ if (i_pro & I2C_P_IRQSS_RX)
-+ pr_debug(" rx");
-+
-+ /* tx end */
-+ if (i_pro & I2C_P_IRQSS_TX_END)
-+ pr_debug(" txend");
-+ pr_debug("\n");
-+
-+ if (!priv->msg_err) {
-+ /* tx -> rx switch */
-+ if (i_pro & I2C_P_IRQSS_RX) {
-+ priv->status = STATUS_READ;
-+ enable_burst_irq(priv);
-+ }
-+ if (i_pro & I2C_P_IRQSS_TX_END) {
-+ if (priv->status == STATUS_READ)
-+ priv->status = STATUS_READ_END;
-+ else {
-+ disable_burst_irq(priv);
-+ priv->status = STATUS_STOP;
-+ }
-+ }
-+ }
-+
-+ i2c_w32(i_pro, p_irqsc);
-+}
-+
-+static irqreturn_t ltq_i2c_isr(int irq, void *dev_id)
-+{
-+ u32 i_raw, i_err = 0;
-+ struct ltq_i2c *priv = dev_id;
-+
-+ i_raw = i2c_r32(mis);
-+ pr_debug("i_raw 0x%08X\n", i_raw);
-+
-+ /* error interrupt */
-+ if (i_raw & I2C_RIS_I2C_ERR_INT_INTOCC) {
-+ i_err = i2c_r32(err_irqss);
-+ pr_debug("i_err 0x%08X bus_stat 0x%04X\n",
-+ i_err, i2c_r32(bus_stat));
-+
-+ /* tx fifo overflow (8) */
-+ if (i_err & I2C_ERR_IRQSS_TXF_OFL)
-+ priv->msg_err |= LTQ_I2C_TX_OFL;
-+
-+ /* tx fifo underflow (4) */
-+ if (i_err & I2C_ERR_IRQSS_TXF_UFL)
-+ priv->msg_err |= LTQ_I2C_TX_UFL;
-+
-+ /* rx fifo overflow (2) */
-+ if (i_err & I2C_ERR_IRQSS_RXF_OFL)
-+ priv->msg_err |= LTQ_I2C_RX_OFL;
-+
-+ /* rx fifo underflow (1) */
-+ if (i_err & I2C_ERR_IRQSS_RXF_UFL)
-+ priv->msg_err |= LTQ_I2C_RX_UFL;
-+
-+ i2c_w32(i_err, err_irqsc);
-+ }
-+
-+ /* protocol interrupt */
-+ if (i_raw & I2C_RIS_I2C_P_INT_INTOCC)
-+ ltq_i2c_isr_prot(priv);
-+
-+ if ((priv->msg_err) || (priv->status == STATUS_STOP))
-+ complete(&priv->cmd_complete);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static u32 ltq_i2c_functionality(struct i2c_adapter *adap)
-+{
-+ return I2C_FUNC_I2C |
-+ I2C_FUNC_10BIT_ADDR |
-+ I2C_FUNC_SMBUS_EMUL;
-+}
-+
-+static struct i2c_algorithm ltq_i2c_algorithm = {
-+ .master_xfer = ltq_i2c_xfer,
-+ .functionality = ltq_i2c_functionality,
-+};
-+
-+static int ltq_i2c_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ struct ltq_i2c *priv;
-+ struct i2c_adapter *adap;
-+ struct resource *mmres, irqres[4];
-+ int ret = 0;
-+
-+ dev_dbg(&pdev->dev, "probing\n");
-+
-+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ ret = of_irq_to_resource_table(node, irqres, 4);
-+ if (!mmres || (ret != 4)) {
-+ dev_err(&pdev->dev, "no resources\n");
-+ return -ENODEV;
-+ }
-+
-+ /* allocate private data */
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv) {
-+ dev_err(&pdev->dev, "can't allocate private data\n");
-+ return -ENOMEM;
-+ }
-+
-+ adap = &priv->adap;
-+ i2c_set_adapdata(adap, priv);
-+ adap->owner = THIS_MODULE;
-+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
-+ strlcpy(adap->name, DRV_NAME "-adapter", sizeof(adap->name));
-+ adap->algo = &ltq_i2c_algorithm;
-+ adap->dev.parent = &pdev->dev;
-+ adap->dev.of_node = pdev->dev.of_node;
-+
-+ if (of_property_read_u32(node, "clock-frequency", &priv->i2c_clock)) {
-+ dev_warn(&pdev->dev, "No I2C speed selected, using 100kHz\n");
-+ priv->i2c_clock = 100000;
-+ }
-+
-+ init_completion(&priv->cmd_complete);
-+ mutex_init(&priv->mutex);
-+
-+ priv->membase = devm_ioremap_resource(&pdev->dev, mmres);
-+ if (IS_ERR(priv->membase))
-+ return PTR_ERR(priv->membase);
-+
-+ priv->dev = &pdev->dev;
-+ priv->irq_lb = irqres[0].start;
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[0].start, ltq_i2c_isr_burst,
-+ 0x0, "i2c lb", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get last burst IRQ %d\n",
-+ irqres[0].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[1].start, ltq_i2c_isr_burst,
-+ 0x0, "i2c b", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get burst IRQ %d\n",
-+ irqres[1].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[2].start, ltq_i2c_isr,
-+ 0x0, "i2c err", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get error IRQ %d\n",
-+ irqres[2].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[3].start, ltq_i2c_isr,
-+ 0x0, "i2c p", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get protocol IRQ %d\n",
-+ irqres[3].start);
-+ return -ENODEV;
-+ }
-+
-+ dev_dbg(&pdev->dev, "mapped io-space to %p\n", priv->membase);
-+ dev_dbg(&pdev->dev, "use IRQs %d, %d, %d, %d\n", irqres[0].start,
-+ irqres[1].start, irqres[2].start, irqres[3].start);
-+
-+ priv->clk_gate = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->clk_gate)) {
-+ dev_err(&pdev->dev, "failed to get i2c clk\n");
-+ return -ENOENT;
-+ }
-+
-+ /* this is a static clock, which has no refcounting */
-+ priv->clk_input = clk_get_fpi();
-+ if (IS_ERR(priv->clk_input)) {
-+ dev_err(&pdev->dev, "failed to get fpi clk\n");
-+ return -ENOENT;
-+ }
-+
-+ clk_activate(priv->clk_gate);
-+
-+ /* add our adapter to the i2c stack */
-+ ret = i2c_add_numbered_adapter(adap);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't register I2C adapter\n");
-+ goto out;
-+ }
-+
-+ platform_set_drvdata(pdev, priv);
-+ i2c_set_adapdata(adap, priv);
-+
-+ /* print module version information */
-+ dev_dbg(&pdev->dev, "module id=%u revision=%u\n",
-+ (i2c_r32(id) & I2C_ID_ID_MASK) >> I2C_ID_ID_OFFSET,
-+ (i2c_r32(id) & I2C_ID_REV_MASK) >> I2C_ID_REV_OFFSET);
-+
-+ /* initialize HW */
-+ ret = ltq_i2c_hw_init(adap);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't configure adapter\n");
-+ i2c_del_adapter(adap);
-+ platform_set_drvdata(pdev, NULL);
-+ goto out;
-+ } else {
-+ dev_info(&pdev->dev, "version %s\n", DRV_VERSION);
-+ }
-+
-+out:
-+ /* if init failed, we need to deactivate the clock gate */
-+ if (ret)
-+ clk_deactivate(priv->clk_gate);
-+
-+ return ret;
-+}
-+
-+static int ltq_i2c_remove(struct platform_device *pdev)
-+{
-+ struct ltq_i2c *priv = platform_get_drvdata(pdev);
-+
-+ /* disable bus */
-+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
-+
-+ /* power down the core */
-+ clk_deactivate(priv->clk_gate);
-+
-+ /* remove driver */
-+ i2c_del_adapter(&priv->adap);
-+ kfree(priv);
-+
-+ dev_dbg(&pdev->dev, "removed\n");
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+static const struct of_device_id ltq_i2c_match[] = {
-+ { .compatible = "lantiq,lantiq-i2c" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ltq_i2c_match);
-+
-+static struct platform_driver ltq_i2c_driver = {
-+ .probe = ltq_i2c_probe,
-+ .remove = ltq_i2c_remove,
-+ .driver = {
-+ .name = DRV_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = ltq_i2c_match,
-+ },
-+};
-+
-+module_platform_driver(ltq_i2c_driver);
-+
-+MODULE_DESCRIPTION("Lantiq I2C bus adapter");
-+MODULE_AUTHOR("Thomas Langer <thomas.langer@lantiq.com>");
-+MODULE_ALIAS("platform:" DRV_NAME);
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-lantiq.h
-@@ -0,0 +1,234 @@
-+#ifndef I2C_LANTIQ_H
-+#define I2C_LANTIQ_H
-+
-+/* I2C register structure */
-+struct lantiq_reg_i2c {
-+ /* I2C Kernel Clock Control Register */
-+ unsigned int clc; /* 0x00000000 */
-+ /* Reserved */
-+ unsigned int res_0; /* 0x00000004 */
-+ /* I2C Identification Register */
-+ unsigned int id; /* 0x00000008 */
-+ /* Reserved */
-+ unsigned int res_1; /* 0x0000000C */
-+ /*
-+ * I2C RUN Control Register
-+ * This register enables and disables the I2C peripheral. Before
-+ * enabling, the I2C has to be configured properly. After enabling
-+ * no configuration is possible
-+ */
-+ unsigned int run_ctrl; /* 0x00000010 */
-+ /*
-+ * I2C End Data Control Register
-+ * This register is used to either turn around the data transmission
-+ * direction or to address another slave without sending a stop
-+ * condition. Also the software can stop the slave-transmitter by
-+ * sending a not-accolade when working as master-receiver or even
-+ * stop data transmission immediately when operating as
-+ * master-transmitter. The writing to the bits of this control
-+ * register is only effective when in MASTER RECEIVES BYTES, MASTER
-+ * TRANSMITS BYTES, MASTER RESTART or SLAVE RECEIVE BYTES state
-+ */
-+ unsigned int endd_ctrl; /* 0x00000014 */
-+ /*
-+ * I2C Fractional Divider Configuration Register
-+ * These register is used to program the fractional divider of the I2C
-+ * bus. Before the peripheral is switched on by setting the RUN-bit the
-+ * two (fixed) values for the two operating frequencies are programmed
-+ * into these (configuration) registers. The Register FDIV_HIGH_CFG has
-+ * the same layout as I2C_FDIV_CFG.
-+ */
-+ unsigned int fdiv_cfg; /* 0x00000018 */
-+ /*
-+ * I2C Fractional Divider (highspeed mode) Configuration Register
-+ * These register is used to program the fractional divider of the I2C
-+ * bus. Before the peripheral is switched on by setting the RUN-bit the
-+ * two (fixed) values for the two operating frequencies are programmed
-+ * into these (configuration) registers. The Register FDIV_CFG has the
-+ * same layout as I2C_FDIV_CFG.
-+ */
-+ unsigned int fdiv_high_cfg; /* 0x0000001C */
-+ /* I2C Address Configuration Register */
-+ unsigned int addr_cfg; /* 0x00000020 */
-+ /* I2C Bus Status Register
-+ * This register gives a status information of the I2C. This additional
-+ * information can be used by the software to start proper actions.
-+ */
-+ unsigned int bus_stat; /* 0x00000024 */
-+ /* I2C FIFO Configuration Register */
-+ unsigned int fifo_cfg; /* 0x00000028 */
-+ /* I2C Maximum Received Packet Size Register */
-+ unsigned int mrps_ctrl; /* 0x0000002C */
-+ /* I2C Received Packet Size Status Register */
-+ unsigned int rps_stat; /* 0x00000030 */
-+ /* I2C Transmit Packet Size Register */
-+ unsigned int tps_ctrl; /* 0x00000034 */
-+ /* I2C Filled FIFO Stages Status Register */
-+ unsigned int ffs_stat; /* 0x00000038 */
-+ /* Reserved */
-+ unsigned int res_2; /* 0x0000003C */
-+ /* I2C Timing Configuration Register */
-+ unsigned int tim_cfg; /* 0x00000040 */
-+ /* Reserved */
-+ unsigned int res_3[7]; /* 0x00000044 */
-+ /* I2C Error Interrupt Request Source Mask Register */
-+ unsigned int err_irqsm; /* 0x00000060 */
-+ /* I2C Error Interrupt Request Source Status Register */
-+ unsigned int err_irqss; /* 0x00000064 */
-+ /* I2C Error Interrupt Request Source Clear Register */
-+ unsigned int err_irqsc; /* 0x00000068 */
-+ /* Reserved */
-+ unsigned int res_4; /* 0x0000006C */
-+ /* I2C Protocol Interrupt Request Source Mask Register */
-+ unsigned int p_irqsm; /* 0x00000070 */
-+ /* I2C Protocol Interrupt Request Source Status Register */
-+ unsigned int p_irqss; /* 0x00000074 */
-+ /* I2C Protocol Interrupt Request Source Clear Register */
-+ unsigned int p_irqsc; /* 0x00000078 */
-+ /* Reserved */
-+ unsigned int res_5; /* 0x0000007C */
-+ /* I2C Raw Interrupt Status Register */
-+ unsigned int ris; /* 0x00000080 */
-+ /* I2C Interrupt Mask Control Register */
-+ unsigned int imsc; /* 0x00000084 */
-+ /* I2C Masked Interrupt Status Register */
-+ unsigned int mis; /* 0x00000088 */
-+ /* I2C Interrupt Clear Register */
-+ unsigned int icr; /* 0x0000008C */
-+ /* I2C Interrupt Set Register */
-+ unsigned int isr; /* 0x00000090 */
-+ /* I2C DMA Enable Register */
-+ unsigned int dmae; /* 0x00000094 */
-+ /* Reserved */
-+ unsigned int res_6[8154]; /* 0x00000098 */
-+ /* I2C Transmit Data Register */
-+ unsigned int txd; /* 0x00008000 */
-+ /* Reserved */
-+ unsigned int res_7[4095]; /* 0x00008004 */
-+ /* I2C Receive Data Register */
-+ unsigned int rxd; /* 0x0000C000 */
-+ /* Reserved */
-+ unsigned int res_8[4095]; /* 0x0000C004 */
-+};
-+
-+/*
-+ * Clock Divider for Normal Run Mode
-+ * Max 8-bit divider value. IF RMC is 0 the module is disabled. Note: As long
-+ * as the new divider value RMC is not valid, the register returns 0x0000 00xx
-+ * on reading.
-+ */
-+#define I2C_CLC_RMC_MASK 0x0000FF00
-+/* field offset */
-+#define I2C_CLC_RMC_OFFSET 8
-+
-+/* Fields of "I2C Identification Register" */
-+/* Module ID */
-+#define I2C_ID_ID_MASK 0x0000FF00
-+/* field offset */
-+#define I2C_ID_ID_OFFSET 8
-+/* Revision */
-+#define I2C_ID_REV_MASK 0x000000FF
-+/* field offset */
-+#define I2C_ID_REV_OFFSET 0
-+
-+/* Fields of "I2C Interrupt Mask Control Register" */
-+/* Enable */
-+#define I2C_IMSC_BREQ_INT_EN 0x00000008
-+/* Enable */
-+#define I2C_IMSC_LBREQ_INT_EN 0x00000004
-+
-+/* Fields of "I2C Fractional Divider Configuration Register" */
-+/* field offset */
-+#define I2C_FDIV_CFG_INC_OFFSET 16
-+
-+/* Fields of "I2C Interrupt Mask Control Register" */
-+/* Enable */
-+#define I2C_IMSC_I2C_P_INT_EN 0x00000020
-+/* Enable */
-+#define I2C_IMSC_I2C_ERR_INT_EN 0x00000010
-+
-+/* Fields of "I2C Error Interrupt Request Source Status Register" */
-+/* TXF_OFL */
-+#define I2C_ERR_IRQSS_TXF_OFL 0x00000008
-+/* TXF_UFL */
-+#define I2C_ERR_IRQSS_TXF_UFL 0x00000004
-+/* RXF_OFL */
-+#define I2C_ERR_IRQSS_RXF_OFL 0x00000002
-+/* RXF_UFL */
-+#define I2C_ERR_IRQSS_RXF_UFL 0x00000001
-+
-+/* Fields of "I2C Raw Interrupt Status Register" */
-+/* Read: Interrupt occurred. */
-+#define I2C_RIS_I2C_ERR_INT_INTOCC 0x00000010
-+/* Read: Interrupt occurred. */
-+#define I2C_RIS_I2C_P_INT_INTOCC 0x00000020
-+
-+/* Fields of "I2C FIFO Configuration Register" */
-+/* TX FIFO Flow Control */
-+#define I2C_FIFO_CFG_TXFC 0x00020000
-+/* RX FIFO Flow Control */
-+#define I2C_FIFO_CFG_RXFC 0x00010000
-+/* Word aligned (character alignment of four characters) */
-+#define I2C_FIFO_CFG_TXFA_TXFA2 0x00002000
-+/* Word aligned (character alignment of four characters) */
-+#define I2C_FIFO_CFG_RXFA_RXFA2 0x00000200
-+/* 1 word */
-+#define I2C_FIFO_CFG_TXBS_TXBS0 0x00000000
-+
-+/* Fields of "I2C FIFO Configuration Register" */
-+/* 1 word */
-+#define I2C_FIFO_CFG_RXBS_RXBS0 0x00000000
-+/* Stop on Packet End Enable */
-+#define I2C_ADDR_CFG_SOPE_EN 0x00200000
-+/* Stop on Not Acknowledge Enable */
-+#define I2C_ADDR_CFG_SONA_EN 0x00100000
-+/* Enable */
-+#define I2C_ADDR_CFG_MnS_EN 0x00080000
-+
-+/* Fields of "I2C Interrupt Clear Register" */
-+/* Clear */
-+#define I2C_ICR_BREQ_INT_CLR 0x00000008
-+/* Clear */
-+#define I2C_ICR_LBREQ_INT_CLR 0x00000004
-+
-+/* Fields of "I2C Fractional Divider Configuration Register" */
-+/* field offset */
-+#define I2C_FDIV_CFG_DEC_OFFSET 0
-+
-+/* Fields of "I2C Bus Status Register" */
-+/* Bus Status */
-+#define I2C_BUS_STAT_BS_MASK 0x00000003
-+/* Read from I2C Bus. */
-+#define I2C_BUS_STAT_RNW_READ 0x00000004
-+/* I2C Bus is free. */
-+#define I2C_BUS_STAT_BS_FREE 0x00000000
-+/*
-+ * The device is working as master and has claimed the control on the
-+ * I2C-bus (busy master).
-+ */
-+#define I2C_BUS_STAT_BS_BM 0x00000002
-+
-+/* Fields of "I2C RUN Control Register" */
-+/* Enable */
-+#define I2C_RUN_CTRL_RUN_EN 0x00000001
-+
-+/* Fields of "I2C End Data Control Register" */
-+/*
-+ * Set End of Transmission
-+ * Note:Do not write '1' to this bit when bus is free. This will cause an
-+ * abort after the first byte when a new transfer is started.
-+ */
-+#define I2C_ENDD_CTRL_SETEND 0x00000002
-+
-+/* Fields of "I2C Protocol Interrupt Request Source Status Register" */
-+/* NACK */
-+#define I2C_P_IRQSS_NACK 0x00000010
-+/* AL */
-+#define I2C_P_IRQSS_AL 0x00000008
-+/* RX */
-+#define I2C_P_IRQSS_RX 0x00000040
-+/* TX_END */
-+#define I2C_P_IRQSS_TX_END 0x00000020
-+
-+
-+#endif /* I2C_LANTIQ_H */
diff --git a/target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch b/target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
deleted file mode 100644
index be0f0bfccd..0000000000
--- a/target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
+++ /dev/null
@@ -1,218 +0,0 @@
-From f8c5db89e793a4bc6c1e87bd7b3a5cec16b75bc3 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 10 Sep 2014 22:42:14 +0200
-Subject: [PATCH 35/36] owrt: lantiq: wifi and ethernet eeprom handling
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +
- arch/mips/lantiq/xway/Makefile | 3 +
- arch/mips/lantiq/xway/ath5k_eep.c | 136 +++++++++++++++++++++
- arch/mips/lantiq/xway/eth_mac.c | 25 ++++
- drivers/net/ethernet/lantiq_etop.c | 6 +-
- 5 files changed, 172 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/lantiq/xway/ath5k_eep.c
- create mode 100644 arch/mips/lantiq/xway/eth_mac.c
-
---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
-+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
-@@ -102,5 +102,8 @@ int xrx200_gphy_boot(struct device *dev,
- extern void ltq_pmu_enable(unsigned int module);
- extern void ltq_pmu_disable(unsigned int module);
-
-+/* allow the ethernet driver to load a flash mapped mac addr */
-+const u8* ltq_get_eth_mac(void);
-+
- #endif /* CONFIG_SOC_TYPE_XWAY */
- #endif /* _LTQ_XWAY_H__ */
---- a/arch/mips/lantiq/xway/Makefile
-+++ b/arch/mips/lantiq/xway/Makefile
-@@ -8,3 +8,6 @@ obj-y += timer.o
- endif
-
- obj-y += vmmc.o
-+
-+obj-y += eth_mac.o
-+obj-$(CONFIG_PCI) += ath5k_eep.o
---- /dev/null
-+++ b/arch/mips/lantiq/xway/ath5k_eep.c
-@@ -0,0 +1,136 @@
-+/*
-+ * Copyright (C) 2011 Luca Olivetti <luca@ventoso.org>
-+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
-+ * Copyright (C) 2011 Andrej Vlašić <andrej.vlasic0@gmail.com>
-+ * Copyright (C) 2013 Álvaro Fernández Rojas <noltari@gmail.com>
-+ * Copyright (C) 2013 Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
-+ * Copyright (C) 2015 Vittorio Gambaletta <openwrt@vittgam.net>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ath5k_platform.h>
-+#include <linux/pci.h>
-+#include <linux/err.h>
-+#include <linux/mtd/mtd.h>
-+#include <lantiq_soc.h>
-+
-+extern int (*ltq_pci_plat_dev_init)(struct pci_dev *dev);
-+struct ath5k_platform_data ath5k_pdata;
-+static u8 athxk_eeprom_mac[6];
-+
-+static int ath5k_pci_plat_dev_init(struct pci_dev *dev)
-+{
-+ dev->dev.platform_data = &ath5k_pdata;
-+ return 0;
-+}
-+
-+static int ath5k_eep_load;
-+int __init of_ath5k_eeprom_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node, *mtd_np = NULL;
-+ int mac_offset;
-+ u32 mac_inc = 0;
-+ int i;
-+ struct mtd_info *the_mtd;
-+ size_t flash_readlen;
-+ const __be32 *list;
-+ const char *part;
-+ phandle phandle;
-+
-+ list = of_get_property(np, "ath,eep-flash", &i);
-+ if (!list || (i != (2 * sizeof(*list))))
-+ return -ENODEV;
-+
-+ phandle = be32_to_cpup(list++);
-+ if (phandle)
-+ mtd_np = of_find_node_by_phandle(phandle);
-+
-+ if (!mtd_np)
-+ return -ENODEV;
-+
-+ part = of_get_property(mtd_np, "label", NULL);
-+ if (!part)
-+ part = mtd_np->name;
-+
-+ the_mtd = get_mtd_device_nm(part);
-+ if (IS_ERR(the_mtd))
-+ return -ENODEV;
-+
-+ ath5k_pdata.eeprom_data = kmalloc(ATH5K_PLAT_EEP_MAX_WORDS<<1, GFP_KERNEL);
-+
-+ i = mtd_read(the_mtd, be32_to_cpup(list), ATH5K_PLAT_EEP_MAX_WORDS << 1,
-+ &flash_readlen, (void *) ath5k_pdata.eeprom_data);
-+
-+ if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
-+ size_t mac_readlen;
-+ mtd_read(the_mtd, mac_offset, 6, &mac_readlen,
-+ (void *) athxk_eeprom_mac);
-+ }
-+ put_mtd_device(the_mtd);
-+
-+ if (((ATH5K_PLAT_EEP_MAX_WORDS<<1) != flash_readlen) || i) {
-+ dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
-+ return -ENODEV;
-+ }
-+
-+ if (of_find_property(np, "ath,eep-swap", NULL))
-+ for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS; i++)
-+ ath5k_pdata.eeprom_data[i] = swab16(ath5k_pdata.eeprom_data[i]);
-+
-+ if (!is_valid_ether_addr(athxk_eeprom_mac) && ltq_get_eth_mac())
-+ ether_addr_copy(athxk_eeprom_mac, ltq_get_eth_mac());
-+
-+ if (!is_valid_ether_addr(athxk_eeprom_mac)) {
-+ dev_warn(&pdev->dev, "using random mac\n");
-+ eth_random_addr(athxk_eeprom_mac);
-+ }
-+
-+ if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
-+ athxk_eeprom_mac[5] += mac_inc;
-+
-+ ath5k_pdata.macaddr = athxk_eeprom_mac;
-+ ltq_pci_plat_dev_init = ath5k_pci_plat_dev_init;
-+
-+ dev_info(&pdev->dev, "loaded ath5k eeprom\n");
-+
-+ return 0;
-+}
-+
-+static struct of_device_id ath5k_eeprom_ids[] = {
-+ { .compatible = "ath5k,eeprom" },
-+ { }
-+};
-+
-+static struct platform_driver ath5k_eeprom_driver = {
-+ .driver = {
-+ .name = "ath5k,eeprom",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(ath5k_eeprom_ids),
-+ },
-+};
-+
-+static int __init of_ath5k_eeprom_init(void)
-+{
-+ int ret = platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
-+
-+ if (ret)
-+ ath5k_eep_load = 1;
-+
-+ return ret;
-+}
-+
-+static int __init of_ath5k_eeprom_init_late(void)
-+{
-+ if (!ath5k_eep_load)
-+ return 0;
-+
-+ return platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
-+}
-+late_initcall(of_ath5k_eeprom_init_late);
-+subsys_initcall(of_ath5k_eeprom_init);
---- /dev/null
-+++ b/arch/mips/lantiq/xway/eth_mac.c
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/if_ether.h>
-+
-+static u8 eth_mac[6];
-+static int eth_mac_set;
-+
-+const u8* ltq_get_eth_mac(void)
-+{
-+ return eth_mac;
-+}
-+
-+static int __init setup_ethaddr(char *str)
-+{
-+ eth_mac_set = mac_pton(str, eth_mac);
-+ return !eth_mac_set;
-+}
-+early_param("ethaddr", setup_ethaddr);
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -757,7 +757,11 @@ ltq_etop_init(struct net_device *dev)
- if (err)
- goto err_hw;
-
-- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
-+ memcpy(&mac.sa_data, ltq_get_eth_mac(), ETH_ALEN);
-+
-+ if (!is_valid_ether_addr(mac.sa_data))
-+ memcpy(&mac.sa_data, priv->mac, ETH_ALEN);
-+
- if (!is_valid_ether_addr(mac.sa_data)) {
- pr_warn("etop: invalid MAC, using random\n");
- eth_random_addr(mac.sa_data);
diff --git a/target/linux/lantiq/patches-5.15/0042-arch-mips-increase-io_space_limit.patch b/target/linux/lantiq/patches-5.15/0042-arch-mips-increase-io_space_limit.patch
deleted file mode 100644
index c81222af57..0000000000
--- a/target/linux/lantiq/patches-5.15/0042-arch-mips-increase-io_space_limit.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 9807eb80a1b3bad7a4a89aa6566497bb1cadd6ef Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 3 Jun 2016 13:12:20 +0200
-Subject: [PATCH] arch: mips: increase io_space_limit
-
-this value comes from x86 and breaks some pci devices
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/mips/include/asm/mach-lantiq/spaces.h | 8 ++++++++
- 1 file changed, 8 insertions(+)
- create mode 100644 arch/mips/include/asm/mach-lantiq/spaces.h
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/spaces.h
-@@ -0,0 +1,8 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __ASM_MACH_LANTIQ_SPACES_H_
-+#define __ASM_MACH_LANTIQ_SPACES_H_
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+#include <asm/mach-generic/spaces.h>
-+#endif
diff --git a/target/linux/lantiq/patches-5.15/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch b/target/linux/lantiq/patches-5.15/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch
deleted file mode 100644
index 6615a9edbf..0000000000
--- a/target/linux/lantiq/patches-5.15/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From de2cad82c4d0872066f83ce59462603852b47f03 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:55:24 +0100
-Subject: [PATCH 2/2] usb: dwc2: add support for other Lantiq SoCs
-
-The size of the internal RAM of the DesignWare USB controller changed
-between the different Lantiq SoCs. We have the following sizes:
-
-Amazon + Danube: 8 KByte
-Amazon SE + arx100: 2 KByte
-xrx200 + xrx300: 2.5 KByte
-
-For Danube SoC we do not provide the params and let the driver decide
-to use sane defaults, for the Amazon SE and arx100 we use small fifos
-and for the xrx200 and xrx300 SCs a little bit bigger periodic fifo.
-The auto detection of max_transfer_size and max_packet_count should
-work, so remove it.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/usb/dwc2/platform.c | 46 ++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 39 insertions(+), 7 deletions(-)
-
---- a/drivers/usb/dwc2/params.c
-+++ b/drivers/usb/dwc2/params.c
-@@ -93,7 +93,14 @@ static void dwc2_set_rk_params(struct dw
- p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
- }
-
--static void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg)
-+static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
-+}
-+
-+static void dwc2_set_ltq_ase_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-
-@@ -101,12 +108,20 @@ static void dwc2_set_ltq_params(struct d
- p->host_rx_fifo_size = 288;
- p->host_nperio_tx_fifo_size = 128;
- p->host_perio_tx_fifo_size = 96;
-- p->max_transfer_size = 65535;
-- p->max_packet_count = 511;
- p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
- GAHBCFG_HBSTLEN_SHIFT;
- }
-
-+static void dwc2_set_ltq_xrx200_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
-+ p->host_rx_fifo_size = 288;
-+ p->host_nperio_tx_fifo_size = 128;
-+ p->host_perio_tx_fifo_size = 136;
-+}
-+
- static void dwc2_set_amlogic_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-@@ -205,8 +220,11 @@ const struct of_device_id dwc2_of_match_
- { .compatible = "brcm,bcm2835-usb", .data = dwc2_set_bcm_params },
- { .compatible = "hisilicon,hi6220-usb", .data = dwc2_set_his_params },
- { .compatible = "rockchip,rk3066-usb", .data = dwc2_set_rk_params },
-- { .compatible = "lantiq,arx100-usb", .data = dwc2_set_ltq_params },
-- { .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params },
-+ { .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 },
-+ { .compatible = "lantiq,xrx200-usb", .data = &dwc2_set_ltq_xrx200_params },
-+ { .compatible = "lantiq,xrx300-usb", .data = &dwc2_set_ltq_xrx200_params },
- { .compatible = "snps,dwc2" },
- { .compatible = "samsung,s3c6400-hsotg",
- .data = dwc2_set_s3c6400_params },
diff --git a/target/linux/lantiq/patches-5.15/0051-MIPS-lantiq-improve-USB-initialization.patch b/target/linux/lantiq/patches-5.15/0051-MIPS-lantiq-improve-USB-initialization.patch
deleted file mode 100644
index 9d62892b56..0000000000
--- a/target/linux/lantiq/patches-5.15/0051-MIPS-lantiq-improve-USB-initialization.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 14909c4e4e836925668e74fc6e0e85ba0283cbf9 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:40:12 +0100
-Subject: [PATCH 2/2] MIPS: lantiq: improve USB initialization
-
-This adds code to initialize the USB controller and PHY also on Danube,
-Amazon SE and AR10. This code is based on the Vendor driver from
-different UGW versions and compared to the hardware documentation.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- arch/mips/lantiq/xway/sysctrl.c | 20 +++++++
- 2 files changed, 110 insertions(+), 30 deletions(-)
-
-
---- a/arch/mips/lantiq/xway/sysctrl.c
-+++ b/arch/mips/lantiq/xway/sysctrl.c
-@@ -248,6 +248,25 @@ static void pmu_disable(struct clk *clk)
- pr_warn("deactivating PMU module failed!");
- }
-
-+static void usb_set_clock(void)
-+{
-+ unsigned int val = ltq_cgu_r32(ifccr);
-+
-+ if (of_machine_is_compatible("lantiq,ar10") ||
-+ of_machine_is_compatible("lantiq,grx390")) {
-+ val &= ~0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ar9") ||
-+ of_machine_is_compatible("lantiq,vr9")) {
-+ /* TODO: this depends on the XTAL frequency */
-+ val |= 0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ase")) {
-+ val |= 0x20; /* from XTAL */
-+ } else if (of_machine_is_compatible("lantiq,danube")) {
-+ val |= 0x30; /* 12 MHz, generated from 36 MHz */
-+ }
-+ ltq_cgu_w32(val, ifccr);
-+}
-+
- /* the pci enable helper */
- static int pci_enable(struct clk *clk)
- {
-@@ -585,4 +604,5 @@ void __init ltq_soc_init(void)
- clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
- clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
- }
-+ usb_set_clock();
- }
diff --git a/target/linux/lantiq/patches-5.15/0101-find_active_root.patch b/target/linux/lantiq/patches-5.15/0101-find_active_root.patch
deleted file mode 100644
index 14dc83f1f7..0000000000
--- a/target/linux/lantiq/patches-5.15/0101-find_active_root.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 2c82524000cca691c89c9fda251b55ef04eabcb6 Mon Sep 17 00:00:00 2001
-From: Mathias Kresin <openwrt@kresin.me>
-Date: Mon, 2 May 2016 18:50:00 +0000
-Subject: [PATCH] find active root
-
-Signed-off-by: Mathias Kresin <openwrt@kresin.me>
----
- drivers/mtd/parsers/ofpart_core.c | 49 ++++++++++++++++++++++++++++++-
- 1 file changed, 48 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/parsers/ofpart_core.c
-+++ b/drivers/mtd/parsers/ofpart_core.c
-@@ -38,6 +38,38 @@ static bool node_has_compatible(struct d
- return of_get_property(pp, "compatible", NULL);
- }
-
-+static uint8_t * brnboot_get_selected_root_part(struct mtd_info *master,
-+ loff_t offset)
-+{
-+ static uint8_t root_id;
-+ int err, len;
-+
-+ err = mtd_read(master, offset, 0x01, &len, &root_id);
-+
-+ if (mtd_is_bitflip(err) || !err)
-+ return &root_id;
-+
-+ return NULL;
-+}
-+
-+static void brnboot_set_active_root_part(struct mtd_partition *pparts,
-+ struct device_node **part_nodes,
-+ int nr_parts,
-+ uint8_t *root_id)
-+{
-+ int i;
-+
-+ for (i = 0; i < nr_parts; i++) {
-+ int part_root_id;
-+
-+ if (!of_property_read_u32(part_nodes[i], "brnboot,root-id", &part_root_id)
-+ && part_root_id == *root_id) {
-+ pparts[i].name = "firmware";
-+ break;
-+ }
-+ }
-+}
-+
- static int parse_fixed_partitions(struct mtd_info *master,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -51,6 +83,8 @@ static int parse_fixed_partitions(struct
- struct device_node *pp;
- int nr_parts, i, ret = 0;
- bool dedicated = true;
-+ uint8_t *proot_id = NULL;
-+ struct device_node **part_nodes;
-
- /* Pull of_node from the master device node */
- mtd_node = mtd_get_of_node(master);
-@@ -95,7 +129,9 @@ static int parse_fixed_partitions(struct
- return 0;
-
- parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
-- if (!parts)
-+ part_nodes = kcalloc(nr_parts, sizeof(*part_nodes), GFP_KERNEL);
-+
-+ if (!parts || !part_nodes)
- return -ENOMEM;
-
- i = 0;
-@@ -147,6 +183,11 @@ static int parse_fixed_partitions(struct
- if (of_property_read_bool(pp, "slc-mode"))
- parts[i].add_flags |= MTD_SLC_ON_MLC_EMULATION;
-
-+ if (!proot_id && of_device_is_compatible(pp, "brnboot,root-selector"))
-+ proot_id = brnboot_get_selected_root_part(master, parts[i].offset);
-+
-+ part_nodes[i] = pp;
-+
- i++;
- }
-
-@@ -156,6 +197,11 @@ static int parse_fixed_partitions(struct
- if (quirks && quirks->post_parse)
- quirks->post_parse(master, parts, nr_parts);
-
-+ if (proot_id)
-+ brnboot_set_active_root_part(parts, part_nodes, nr_parts, proot_id);
-+
-+ kfree(part_nodes);
-+
- *pparts = parts;
- return nr_parts;
-
-@@ -166,6 +212,7 @@ ofpart_fail:
- ofpart_none:
- of_node_put(pp);
- kfree(parts);
-+ kfree(part_nodes);
- return ret;
- }
-
diff --git a/target/linux/lantiq/patches-5.15/0151-lantiq-ifxmips_pcie-use-of.patch b/target/linux/lantiq/patches-5.15/0151-lantiq-ifxmips_pcie-use-of.patch
deleted file mode 100644
index 93108cac3a..0000000000
--- a/target/linux/lantiq/patches-5.15/0151-lantiq-ifxmips_pcie-use-of.patch
+++ /dev/null
@@ -1,486 +0,0 @@
-From 1d1885f4a7abd7272f47b835b03d8662fb981d19 Mon Sep 17 00:00:00 2001
-From: Eddi De Pieri <eddi@depieri.net>
-Date: Tue, 14 Oct 2014 11:04:00 +0000
-Subject: [PATCH] MIPS: lantiq: ifxmips_pcie: use of
-
-Signed-off-by: Eddi De Pieri <eddi@depieri.net>
----
- arch/mips/pci/Makefile | 2 +-
- arch/mips/pci/ifxmips_pcie.c | 151 +++++++++++++++++++++++++++----
- arch/mips/pci/ifxmips_pcie_vr9.h | 105 ---------------------
- 3 files changed, 133 insertions(+), 125 deletions(-)
-
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -43,7 +43,7 @@ obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o
- obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
- obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
- obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
--obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
-+obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie.o fixup-lantiq-pcie.o
- obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
- obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
- obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
---- a/arch/mips/pci/ifxmips_pcie.c
-+++ b/arch/mips/pci/ifxmips_pcie.c
-@@ -16,8 +16,15 @@
- #include <asm/paccess.h>
- #include <linux/pci.h>
- #include <linux/pci_regs.h>
-+#include <linux/phy/phy.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
-
-+#include <linux/of_gpio.h>
-+#include <linux/of_platform.h>
-+
- #include "ifxmips_pcie.h"
- #include "ifxmips_pcie_reg.h"
-
-@@ -25,11 +32,6 @@
- #define IFX_PCIE_ERROR_INT
- #define IFX_PCIE_IO_32BIT
-
--#define IFX_PCIE_IR (INT_NUM_IM4_IRL0 + 25)
--#define IFX_PCIE_INTA (INT_NUM_IM4_IRL0 + 8)
--#define IFX_PCIE_INTB (INT_NUM_IM4_IRL0 + 9)
--#define IFX_PCIE_INTC (INT_NUM_IM4_IRL0 + 10)
--#define IFX_PCIE_INTD (INT_NUM_IM4_IRL0 + 11)
- #define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
- #define SM(_v, _f) (((_v) << _f##_S) & (_f))
- #define IFX_REG_SET_BIT(_f, _r) \
-@@ -40,30 +42,30 @@
- static DEFINE_SPINLOCK(ifx_pcie_lock);
-
- u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
-+static int pcie_reset_gpio;
-+static struct phy *ltq_pcie_phy;
-+static struct reset_control *ltq_pcie_reset;
-+static struct regmap *ltq_rcu_regmap;
-+static bool switch_pcie_endianess;
-
- static ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
- {
- .ir_irq = {
-- .irq = IFX_PCIE_IR,
- .name = "ifx_pcie_rc0",
- },
-
- .legacy_irq = {
- {
- .irq_bit = PCIE_IRN_INTA,
-- .irq = IFX_PCIE_INTA,
- },
- {
- .irq_bit = PCIE_IRN_INTB,
-- .irq = IFX_PCIE_INTB,
- },
- {
- .irq_bit = PCIE_IRN_INTC,
-- .irq = IFX_PCIE_INTC,
- },
- {
- .irq_bit = PCIE_IRN_INTD,
-- .irq = IFX_PCIE_INTD,
- },
- },
- },
-@@ -82,6 +84,22 @@ void ifx_pcie_debug(const char *fmt, ...
- printk("%s", buf);
- }
-
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+ gpio_set_value(pcie_reset_gpio, 1);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(pcie_reset_gpio, 0);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+}
-
- static inline int pcie_ltssm_enable(int pcie_port)
- {
-@@ -857,7 +875,8 @@ pcie_rc_core_int_init(int pcie_port)
- ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
- pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
- if (ret)
-- printk(KERN_ERR "%s request irq %d failed\n", __func__, IFX_PCIE_IR);
-+ printk(KERN_ERR "%s request irq %d failed\n", __func__,
-+ pcie_irqs[pcie_port].ir_irq.irq);
-
- return ret;
- }
-@@ -988,10 +1007,26 @@ int ifx_pcie_bios_plat_dev_init(struct
- static int
- pcie_rc_initialize(int pcie_port)
- {
-- int i;
-+ int i, ret;
- #define IFX_PCIE_PHY_LOOP_CNT 5
-
-- pcie_rcu_endian_setup(pcie_port);
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_M,
-+ IFX_RCU_AHB_BE_PCIE_M);
-+
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_S,
-+ IFX_RCU_AHB_BE_PCIE_S);
-+ if (switch_pcie_endianess) {
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_XBAR_S,
-+ IFX_RCU_AHB_BE_XBAR_S);
-+ }
-+#else
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_S,
-+ 0x0);
-+#endif
-+
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_XBAR_M,
-+ 0x0);
-
- pcie_ep_gpio_rst_init(pcie_port);
-
-@@ -1000,26 +1035,21 @@ pcie_rc_initialize(int pcie_port)
- * reset PCIe PHY will solve this issue
- */
- for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
-- /* Disable PCIe PHY Analog part for sanity check */
-- pcie_phy_pmu_disable(pcie_port);
--
-- pcie_phy_rst_assert(pcie_port);
-- pcie_phy_rst_deassert(pcie_port);
--
-- /* Make sure PHY PLL is stable */
-- udelay(20);
--
-- /* PCIe Core reset enabled, low active, sw programmed */
-- pcie_core_rst_assert(pcie_port);
-+ ret = phy_init(ltq_pcie_phy);
-+ if (ret)
-+ continue;
-
- /* Put PCIe EP in reset status */
- pcie_device_rst_assert(pcie_port);
-
-- /* PCI PHY & Core reset disabled, high active, sw programmed */
-- pcie_core_rst_deassert(pcie_port);
-+ udelay(1);
-+ reset_control_deassert(ltq_pcie_reset);
-
-- /* Already in a quiet state, program PLL, enable PHY, check ready bit */
-- pcie_phy_clock_mode_setup(pcie_port);
-+ ret = phy_power_on(ltq_pcie_phy);
-+ if (ret) {
-+ phy_exit(ltq_pcie_phy);
-+ continue;
-+ }
-
- /* Enable PCIe PHY and Clock */
- pcie_core_pmu_setup(pcie_port);
-@@ -1035,6 +1065,10 @@ pcie_rc_initialize(int pcie_port)
- /* Once link is up, break out */
- if (pcie_app_loigc_setup(pcie_port) == 0)
- break;
-+
-+ phy_power_off(ltq_pcie_phy);
-+ reset_control_assert(ltq_pcie_reset);
-+ phy_exit(ltq_pcie_phy);
- }
- if (i >= IFX_PCIE_PHY_LOOP_CNT) {
- printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
-@@ -1045,17 +1079,73 @@ pcie_rc_initialize(int pcie_port)
- return 0;
- }
-
--static int __init ifx_pcie_bios_init(void)
-+static int ifx_pcie_bios_probe(struct platform_device *pdev)
- {
-+ struct device_node *node = pdev->dev.of_node;
- void __iomem *io_map_base;
- int pcie_port;
- int startup_port;
-+ struct device_node *np;
-+ struct pci_bus *bus;
-+
-+ /*
-+ * In case a PCI device is physical present, the Lantiq PCI driver need
-+ * to be loaded prior to the Lantiq PCIe driver. Otherwise none of them
-+ * will work.
-+ *
-+ * In case the lantiq PCI driver is enabled in the device tree, check if
-+ * a PCI bus (hopefully the one of the Lantiq PCI driver one) is already
-+ * registered.
-+ *
-+ * It will fail if there is another PCI controller, this controller is
-+ * registered before the Lantiq PCIe driver is probe and the lantiq PCI
-+ */
-+ np = of_find_compatible_node(NULL, NULL, "lantiq,pci-xway");
-+
-+ if (of_device_is_available(np)) {
-+ bus = pci_find_next_bus(bus);
-+
-+ if (!bus)
-+ return -EPROBE_DEFER;
-+ }
-
- /* Enable AHB Master/ Slave */
- pcie_ahb_pmu_setup();
-
- startup_port = IFX_PCIE_PORT0;
--
-+
-+ ltq_pcie_phy = devm_phy_get(&pdev->dev, "pcie");
-+ if (IS_ERR(ltq_pcie_phy))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(ltq_pcie_phy),
-+ "failed to get the PCIe PHY\n");
-+
-+ ltq_pcie_reset = devm_reset_control_get_shared(&pdev->dev, NULL);
-+ if (IS_ERR(ltq_pcie_reset)) {
-+ dev_err(&pdev->dev, "failed to get the PCIe reset line\n");
-+ return PTR_ERR(ltq_pcie_reset);
-+ }
-+
-+ if (of_property_read_bool(node, "lantiq,switch-pcie-endianess")) {
-+ switch_pcie_endianess = true;
-+ dev_info(&pdev->dev, "switch pcie endianess requested\n");
-+ } else {
-+ switch_pcie_endianess = false;
-+ }
-+
-+ ltq_rcu_regmap = syscon_regmap_lookup_by_phandle(node, "lantiq,rcu");
-+ if (IS_ERR(ltq_rcu_regmap))
-+ return PTR_ERR(ltq_rcu_regmap);
-+
-+ pcie_reset_gpio = of_get_named_gpio(node, "gpio-reset", 0);
-+ if (gpio_is_valid(pcie_reset_gpio)) {
-+ int ret = devm_gpio_request(&pdev->dev, pcie_reset_gpio, "pcie-reset");
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to request gpio %d\n", pcie_reset_gpio);
-+ return ret;
-+ }
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+ }
-+
- for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
- if (pcie_rc_initialize(pcie_port) == 0) {
- IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
-@@ -1066,7 +1156,19 @@ static int __init ifx_pcie_bios_init(voi
- IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
- return -ENOMEM;
- }
-+ pcie_irqs[pcie_port].ir_irq.irq = platform_get_irq(pdev, 0);
-+ if (pcie_irqs[pcie_port].ir_irq.irq < 0)
-+ return pcie_irqs[pcie_port].ir_irq.irq;
-+
-+ for (int i = 0; i <= 3; i++){
-+ pcie_irqs[pcie_port].legacy_irq[i].irq = platform_get_irq(pdev, i + 1);
-+
-+ if (pcie_irqs[pcie_port].legacy_irq[i].irq < 0)
-+ return pcie_irqs[pcie_port].legacy_irq[i].irq;
-+ }
-+
- ifx_pcie_controller[pcie_port].pcic.io_map_base = (unsigned long)io_map_base;
-+ pci_load_of_ranges(&ifx_pcie_controller[pcie_port].pcic, node);
-
- register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
- /* XXX, clear error status */
-@@ -1083,6 +1185,30 @@ static int __init ifx_pcie_bios_init(voi
-
- return 0;
- }
-+
-+static const struct of_device_id ifxmips_pcie_match[] = {
-+ { .compatible = "lantiq,pcie-xrx200" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ifxmips_pcie_match);
-+
-+static struct platform_driver ltq_pci_driver = {
-+ .probe = ifx_pcie_bios_probe,
-+ .driver = {
-+ .name = "pcie-xrx200",
-+ .owner = THIS_MODULE,
-+ .of_match_table = ifxmips_pcie_match,
-+ },
-+};
-+
-+int __init ifx_pcie_bios_init(void)
-+{
-+ int ret = platform_driver_register(&ltq_pci_driver);
-+ if (ret)
-+ pr_info("pcie-xrx200: Error registering platform driver!");
-+ return ret;
-+}
-+
- arch_initcall(ifx_pcie_bios_init);
-
- MODULE_LICENSE("GPL");
---- a/arch/mips/pci/ifxmips_pcie_vr9.h
-+++ b/arch/mips/pci/ifxmips_pcie_vr9.h
-@@ -22,8 +22,6 @@
- #include <linux/gpio.h>
- #include <lantiq_soc.h>
-
--#define IFX_PCIE_GPIO_RESET 494
--
- #define IFX_REG_R32 ltq_r32
- #define IFX_REG_W32 ltq_w32
- #define CONFIG_IFX_PCIE_HW_SWAP
-@@ -54,21 +52,6 @@
- #define OUT ((volatile u32*)(IFX_GPIO + 0x0070))
-
-
--static inline void pcie_ep_gpio_rst_init(int pcie_port)
--{
--
-- gpio_request(IFX_PCIE_GPIO_RESET, "pcie-reset");
-- gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-- gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
--
--/* ifx_gpio_pin_reserve(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_dir_out_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_altsel0_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_altsel1_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_open_drain_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);*/
--}
--
- static inline void pcie_ahb_pmu_setup(void)
- {
- /* Enable AHB bus master/slave */
-@@ -80,24 +63,6 @@ static inline void pcie_ahb_pmu_setup(vo
- //AHBS_PMU_SETUP(IFX_PMU_ENABLE);
- }
-
--static inline void pcie_rcu_endian_setup(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
--#ifdef CONFIG_IFX_PCIE_HW_SWAP
-- reg |= IFX_RCU_AHB_BE_PCIE_M;
-- reg |= IFX_RCU_AHB_BE_PCIE_S;
-- reg &= ~IFX_RCU_AHB_BE_XBAR_M;
--#else
-- reg |= IFX_RCU_AHB_BE_PCIE_M;
-- reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-- reg &= ~IFX_RCU_AHB_BE_XBAR_M;
--#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-- IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-- IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
--}
--
- static inline void pcie_phy_pmu_enable(int pcie_port)
- {
- struct clk *clk;
-@@ -116,17 +81,6 @@ static inline void pcie_phy_pmu_disable(
- // PCIE_PHY_PMU_SETUP(IFX_PMU_DISABLE);
- }
-
--static inline void pcie_pdi_big_endian(int pcie_port)
--{
-- u32 reg;
--
-- /* SRAM2PDI endianness control. */
-- reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-- /* Config AHB->PCIe and PDI endianness */
-- reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-- IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
--}
--
- static inline void pcie_pdi_pmu_enable(int pcie_port)
- {
- /* Enable PDI to access PCIe PHY register */
-@@ -136,65 +90,6 @@ static inline void pcie_pdi_pmu_enable(i
- //PDI_PMU_SETUP(IFX_PMU_ENABLE);
- }
-
--static inline void pcie_core_rst_assert(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
--
-- /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-- reg |= 0x00400000;
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_core_rst_deassert(int pcie_port)
--{
-- u32 reg;
--
-- /* Make sure one micro-second delay */
-- udelay(1);
--
-- /* Reset PCIe PHY & Core, bit 22 */
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg &= ~0x00400000;
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_phy_rst_assert(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg |= 0x00001000; /* Bit 12 */
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_phy_rst_deassert(int pcie_port)
--{
-- u32 reg;
--
-- /* Make sure one micro-second delay */
-- udelay(1);
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg &= ~0x00001000; /* Bit 12 */
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_device_rst_assert(int pcie_port)
--{
-- gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
--// ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
--}
--
--static inline void pcie_device_rst_deassert(int pcie_port)
--{
-- mdelay(100);
-- gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
--// gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-- //ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
--}
--
- static inline void pcie_core_pmu_setup(int pcie_port)
- {
- struct clk *clk;
---- a/arch/mips/pci/ifxmips_pcie.h
-+++ b/arch/mips/pci/ifxmips_pcie.h
-@@ -96,13 +96,13 @@ struct ifx_pci_controller {
- };
-
- typedef struct ifx_pcie_ir_irq {
-- const unsigned int irq;
-+ unsigned int irq;
- const char name[16];
- }ifx_pcie_ir_irq_t;
-
- typedef struct ifx_pcie_legacy_irq{
- const u32 irq_bit;
-- const int irq;
-+ int irq;
- }ifx_pcie_legacy_irq_t;
-
- typedef struct ifx_pcie_irq {
diff --git a/target/linux/lantiq/patches-5.15/0152-lantiq-VPE.patch b/target/linux/lantiq/patches-5.15/0152-lantiq-VPE.patch
deleted file mode 100644
index 2395261ff1..0000000000
--- a/target/linux/lantiq/patches-5.15/0152-lantiq-VPE.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From 4d48a3d1ef6f8d036bd926e3c1f70b56fcc679b2 Mon Sep 17 00:00:00 2001
-From: Stefan Koch <stefan.koch10@gmail.com>
-Date: Thu, 20 Oct 2016 21:32:00 +0200
-Subject: [PATCH] lantiq: vpe
-
-Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
----
- arch/mips/Kconfig | 6 ++++
- arch/mips/include/asm/mipsmtregs.h | 5 ++++
- arch/mips/include/asm/vpe.h | 9 ++++++
- arch/mips/kernel/vpe-mt.c | 47 ++++++++++++++++++++++++++++++
- arch/mips/kernel/vpe.c | 35 ++++++++++++++++++++++
- arch/mips/lantiq/prom.c | 4 +++
- 6 files changed, 106 insertions(+)
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -2433,6 +2433,12 @@ config MIPS_VPE_LOADER
- Includes a loader for loading an elf relocatable object
- onto another VPE and running it.
-
-+config IFX_VPE_EXT
-+ bool "IFX APRP Extensions"
-+ depends on MIPS_VPE_LOADER
-+ help
-+ IFX included extensions in APRP
-+
- config MIPS_VPE_LOADER_CMP
- bool
- default "y"
---- a/arch/mips/include/asm/mipsmtregs.h
-+++ b/arch/mips/include/asm/mipsmtregs.h
-@@ -32,6 +32,9 @@
- #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3)
- #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val)
-
-+#define read_c0_vpeopt() __read_32bit_c0_register($1, 7)
-+#define write_c0_vpeopt(val) __write_32bit_c0_register($1, 7, val)
-+
- #define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
- #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
-
-@@ -378,6 +381,8 @@ do { \
- #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
- #define read_vpe_c0_vpeconf1() mftc0(1, 3)
- #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val)
-+#define read_vpe_c0_vpeopt() mftc0(1, 7)
-+#define write_vpe_c0_vpeopt(val) mttc0(1, 7, val)
- #define read_vpe_c0_count() mftc0(9, 0)
- #define write_vpe_c0_count(val) mttc0(9, 0, val)
- #define read_vpe_c0_status() mftc0(12, 0)
---- a/arch/mips/include/asm/vpe.h
-+++ b/arch/mips/include/asm/vpe.h
-@@ -123,4 +123,13 @@ void cleanup_tc(struct tc *tc);
-
- int __init vpe_module_init(void);
- void __exit vpe_module_exit(void);
-+
-+/* For the explanation of the APIs please refer the section "MT APRP Kernel
-+ * Programming" in AR9 SW Architecture Specification
-+ */
-+int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags);
-+int32_t vpe1_sw_stop(uint32_t flags);
-+uint32_t vpe1_get_load_addr(uint32_t flags);
-+uint32_t vpe1_get_max_mem(uint32_t flags);
-+
- #endif /* _ASM_VPE_H */
---- a/arch/mips/kernel/vpe-mt.c
-+++ b/arch/mips/kernel/vpe-mt.c
-@@ -415,6 +415,8 @@ int __init vpe_module_init(void)
- }
-
- v->ntcs = hw_tcs - aprp_cpu_index();
-+ write_tc_c0_tcbind((read_tc_c0_tcbind() &
-+ ~TCBIND_CURVPE) | 1);
-
- /* add the tc to the list of this vpe's tc's. */
- list_add(&t->tc, &v->tc);
-@@ -518,3 +520,47 @@ void __exit vpe_module_exit(void)
- release_vpe(v);
- }
- }
-+
-+#ifdef CONFIG_IFX_VPE_EXT
-+int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags)
-+{
-+ enum vpe_state state;
-+ struct vpe *v = get_vpe(tclimit);
-+ struct vpe_notifications *not;
-+
-+ if (tcmask || flags) {
-+ pr_warn("Currently tcmask and flags should be 0. Other values are not supported\n");
-+ return -1;
-+ }
-+
-+ state = xchg(&v->state, VPE_STATE_INUSE);
-+ if (state != VPE_STATE_UNUSED) {
-+ vpe_stop(v);
-+
-+ list_for_each_entry(not, &v->notify, list) {
-+ not->stop(tclimit);
-+ }
-+ }
-+
-+ v->__start = (unsigned long)sw_start_addr;
-+
-+ if (!vpe_run(v)) {
-+ pr_debug("VPE loader: VPE1 running successfully\n");
-+ return 0;
-+ }
-+ return -1;
-+}
-+EXPORT_SYMBOL(vpe1_sw_start);
-+
-+int32_t vpe1_sw_stop(uint32_t flags)
-+{
-+ struct vpe *v = get_vpe(tclimit);
-+
-+ if (!vpe_free(v)) {
-+ pr_debug("RP Stopped\n");
-+ return 0;
-+ } else
-+ return -1;
-+}
-+EXPORT_SYMBOL(vpe1_sw_stop);
-+#endif
---- a/arch/mips/kernel/vpe.c
-+++ b/arch/mips/kernel/vpe.c
-@@ -49,6 +49,41 @@ struct vpe_control vpecontrol = {
- .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
- };
-
-+#ifdef CONFIG_IFX_VPE_EXT
-+unsigned int vpe1_load_addr;
-+
-+static int __init load_address(char *str)
-+{
-+ get_option(&str, &vpe1_load_addr);
-+ return 1;
-+}
-+__setup("vpe1_load_addr=", load_address);
-+
-+static unsigned int vpe1_mem;
-+static int __init vpe1mem(char *str)
-+{
-+ vpe1_mem = memparse(str, &str);
-+ return 1;
-+}
-+__setup("vpe1_mem=", vpe1mem);
-+
-+uint32_t vpe1_get_load_addr(uint32_t flags)
-+{
-+ return vpe1_load_addr;
-+}
-+EXPORT_SYMBOL(vpe1_get_load_addr);
-+
-+uint32_t vpe1_get_max_mem(uint32_t flags)
-+{
-+ if (!vpe1_mem)
-+ return P_SIZE;
-+ else
-+ return vpe1_mem;
-+}
-+EXPORT_SYMBOL(vpe1_get_max_mem);
-+
-+#endif
-+
- /* get the vpe associated with this minor */
- struct vpe *get_vpe(int minor)
- {
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -28,10 +28,14 @@ EXPORT_SYMBOL_GPL(ebu_lock);
- */
- static struct ltq_soc_info soc_info;
-
-+/* for Multithreading (APRP), vpe.c will use it */
-+unsigned long cp0_memsize;
-+
- const char *get_system_type(void)
- {
- return soc_info.sys_type;
- }
-+EXPORT_SYMBOL(ltq_soc_type);
-
- int ltq_soc_type(void)
- {
diff --git a/target/linux/lantiq/patches-5.15/0154-lantiq-pci-bar11mask-fix.patch b/target/linux/lantiq/patches-5.15/0154-lantiq-pci-bar11mask-fix.patch
deleted file mode 100644
index 9214f786d7..0000000000
--- a/target/linux/lantiq/patches-5.15/0154-lantiq-pci-bar11mask-fix.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3c92a781de062064e36b867c0ab22f9aba48f3d3 Mon Sep 17 00:00:00 2001
-From: Eddi De Pieri <eddi@depieri.net>
-Date: Tue, 8 Nov 2016 17:38:00 +0100
-Subject: [PATCH] lantiq: pci: bar11mask fix
-
-Signed-off-by: Eddi De Pieri <eddi@depieri.net>
----
- arch/mips/pci/pci-lantiq.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/arch/mips/pci/pci-lantiq.c
-+++ b/arch/mips/pci/pci-lantiq.c
-@@ -59,6 +59,8 @@
- #define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y))
- #define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x))
-
-+extern u32 max_low_pfn;
-+
- __iomem void *ltq_pci_mapped_cfg;
- static __iomem void *ltq_pci_membase;
-
-@@ -84,8 +86,8 @@ static inline u32 ltq_calc_bar11mask(voi
- u32 mem, bar11mask;
-
- /* BAR11MASK value depends on available memory on system. */
-- mem = get_num_physpages() * PAGE_SIZE;
-- bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
-+ mem = max_low_pfn << PAGE_SHIFT;
-+ bar11mask = ((-roundup_pow_of_two(mem)) & 0x0F000000) | 8;
-
- return bar11mask;
- }
diff --git a/target/linux/lantiq/patches-5.15/0155-lantiq-VPE-nosmp.patch b/target/linux/lantiq/patches-5.15/0155-lantiq-VPE-nosmp.patch
deleted file mode 100644
index 6426ee717b..0000000000
--- a/target/linux/lantiq/patches-5.15/0155-lantiq-VPE-nosmp.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 07ce9e9bc4dcd5ac4728e587901112eef95bbe7b Mon Sep 17 00:00:00 2001
-From: Stefan Koch <stefan.koch10@gmail.com>
-Date: Mon, 13 Mar 2017 23:42:00 +0100
-Subject: [PATCH] lantiq: vpe nosmp
-
-Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
----
- arch/mips/kernel/vpe-mt.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/arch/mips/kernel/vpe-mt.c
-+++ b/arch/mips/kernel/vpe-mt.c
-@@ -130,7 +130,10 @@ int vpe_run(struct vpe *v)
- * kernels need to turn it on, even if that wasn't the pre-dvpe() state.
- */
- #ifdef CONFIG_SMP
-- evpe(vpeflags);
-+ if (!setup_max_cpus) /* nosmp is set */
-+ evpe(EVPE_ENABLE);
-+ else
-+ evpe(vpeflags);
- #else
- evpe(EVPE_ENABLE);
- #endif
diff --git a/target/linux/lantiq/patches-5.15/0160-owrt-lantiq-multiple-flash.patch b/target/linux/lantiq/patches-5.15/0160-owrt-lantiq-multiple-flash.patch
deleted file mode 100644
index a83325c094..0000000000
--- a/target/linux/lantiq/patches-5.15/0160-owrt-lantiq-multiple-flash.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-From ebaae1cd68cd79c7eee67c9c5c0fa45809e84525 Mon Sep 17 00:00:00 2001
-From: Maikel Bloemendal <openwrt@maikelenyvonne.nl>
-Date: Fri, 14 Nov 2014 17:06:00 +0000
-Subject: [PATCH] owrt: lantiq: multiple flash
-
-Signed-off-by: Maikel Bloemendal <openwrt@maikelenyvonne.nl>
----
- drivers/mtd/maps/lantiq-flash.c | 168 +++++++++++++++++++++-----------
- 1 file changed, 109 insertions(+), 59 deletions(-)
-
---- a/drivers/mtd/maps/lantiq-flash.c
-+++ b/drivers/mtd/maps/lantiq-flash.c
-@@ -17,6 +17,7 @@
- #include <linux/mtd/cfi.h>
- #include <linux/platform_device.h>
- #include <linux/mtd/physmap.h>
-+#include <linux/mtd/concat.h>
- #include <linux/of.h>
-
- #include <lantiq_soc.h>
-@@ -36,13 +37,16 @@ enum {
- LTQ_NOR_NORMAL
- };
-
-+#define MAX_RESOURCES 4
-+
- struct ltq_mtd {
-- struct resource *res;
-- struct mtd_info *mtd;
-- struct map_info *map;
-+ struct mtd_info *mtd[MAX_RESOURCES];
-+ struct mtd_info *cmtd;
-+ struct map_info map[MAX_RESOURCES];
- };
-
- static const char ltq_map_name[] = "ltq_nor";
-+static const char * const ltq_probe_types[] = { "cmdlinepart", "ofpart", NULL };
-
- static map_word
- ltq_read16(struct map_info *map, unsigned long adr)
-@@ -106,11 +110,43 @@ ltq_copy_to(struct map_info *map, unsign
- }
-
- static int
-+ltq_mtd_remove(struct platform_device *pdev)
-+{
-+ struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
-+ int i;
-+
-+ if (ltq_mtd == NULL)
-+ return 0;
-+
-+ if (ltq_mtd->cmtd) {
-+ mtd_device_unregister(ltq_mtd->cmtd);
-+ if (ltq_mtd->cmtd != ltq_mtd->mtd[0])
-+ mtd_concat_destroy(ltq_mtd->cmtd);
-+ }
-+
-+ for (i = 0; i < MAX_RESOURCES; i++) {
-+ if (ltq_mtd->mtd[i] != NULL)
-+ map_destroy(ltq_mtd->mtd[i]);
-+ }
-+
-+ kfree(ltq_mtd);
-+
-+ return 0;
-+}
-+
-+static int
- ltq_mtd_probe(struct platform_device *pdev)
- {
- struct ltq_mtd *ltq_mtd;
- struct cfi_private *cfi;
-- int err;
-+ int err = 0;
-+ int i;
-+ int devices_found = 0;
-+
-+ static const char *rom_probe_types[] = {
-+ "cfi_probe", "jedec_probe", NULL
-+ };
-+ const char **type;
-
- ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL);
- if (!ltq_mtd)
-@@ -118,75 +154,89 @@ ltq_mtd_probe(struct platform_device *pd
-
- platform_set_drvdata(pdev, ltq_mtd);
-
-- ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!ltq_mtd->res) {
-- dev_err(&pdev->dev, "failed to get memory resource\n");
-- return -ENOENT;
-+ for (i = 0; i < pdev->num_resources; i++) {
-+ printk(KERN_NOTICE "lantiq nor flash device: %.8llx at %.8llx\n",
-+ (unsigned long long)resource_size(&pdev->resource[i]),
-+ (unsigned long long)pdev->resource[i].start);
-+
-+ if (!devm_request_mem_region(&pdev->dev,
-+ pdev->resource[i].start,
-+ resource_size(&pdev->resource[i]),
-+ dev_name(&pdev->dev))) {
-+ dev_err(&pdev->dev, "Could not reserve memory region\n");
-+ return -ENOMEM;
-+ }
-+
-+ ltq_mtd->map[i].name = ltq_map_name;
-+ ltq_mtd->map[i].bankwidth = 2;
-+ ltq_mtd->map[i].read = ltq_read16;
-+ ltq_mtd->map[i].write = ltq_write16;
-+ ltq_mtd->map[i].copy_from = ltq_copy_from;
-+ ltq_mtd->map[i].copy_to = ltq_copy_to;
-+
-+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-+ ltq_mtd->map[i].phys = NO_XIP;
-+ else
-+ ltq_mtd->map[i].phys = pdev->resource[i].start;
-+ ltq_mtd->map[i].size = resource_size(&pdev->resource[i]);
-+ ltq_mtd->map[i].virt = devm_ioremap(&pdev->dev, pdev->resource[i].start,
-+ ltq_mtd->map[i].size);
-+ if (IS_ERR(ltq_mtd->map[i].virt))
-+ return PTR_ERR(ltq_mtd->map[i].virt);
-+
-+ if (ltq_mtd->map[i].virt == NULL) {
-+ dev_err(&pdev->dev, "Failed to ioremap flash region\n");
-+ err = PTR_ERR(ltq_mtd->map[i].virt);
-+ goto err_out;
-+ }
-+
-+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_PROBING;
-+ for (type = rom_probe_types; !ltq_mtd->mtd[i] && *type; type++)
-+ ltq_mtd->mtd[i] = do_map_probe(*type, &ltq_mtd->map[i]);
-+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_NORMAL;
-+
-+ if (!ltq_mtd->mtd[i]) {
-+ dev_err(&pdev->dev, "probing failed\n");
-+ return -ENXIO;
-+ } else {
-+ devices_found++;
-+ }
-+
-+ ltq_mtd->mtd[i]->owner = THIS_MODULE;
-+ ltq_mtd->mtd[i]->dev.parent = &pdev->dev;
-+
-+ cfi = ltq_mtd->map[i].fldrv_priv;
-+ cfi->addr_unlock1 ^= 1;
-+ cfi->addr_unlock2 ^= 1;
- }
-
-- ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
-- GFP_KERNEL);
-- if (!ltq_mtd->map)
-- return -ENOMEM;
--
-- if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-- ltq_mtd->map->phys = NO_XIP;
-- else
-- ltq_mtd->map->phys = ltq_mtd->res->start;
-- ltq_mtd->res->start;
-- ltq_mtd->map->size = resource_size(ltq_mtd->res);
-- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
-- if (IS_ERR(ltq_mtd->map->virt))
-- return PTR_ERR(ltq_mtd->map->virt);
--
-- ltq_mtd->map->name = ltq_map_name;
-- ltq_mtd->map->bankwidth = 2;
-- ltq_mtd->map->read = ltq_read16;
-- ltq_mtd->map->write = ltq_write16;
-- ltq_mtd->map->copy_from = ltq_copy_from;
-- ltq_mtd->map->copy_to = ltq_copy_to;
--
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
-- ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
--
-- if (!ltq_mtd->mtd) {
-- dev_err(&pdev->dev, "probing failed\n");
-- return -ENXIO;
-+ if (devices_found == 1) {
-+ ltq_mtd->cmtd = ltq_mtd->mtd[0];
-+ } else if (devices_found > 1) {
-+ /*
-+ * We detected multiple devices. Concatenate them together.
-+ */
-+ ltq_mtd->cmtd = mtd_concat_create(ltq_mtd->mtd, devices_found, dev_name(&pdev->dev));
-+ if (ltq_mtd->cmtd == NULL)
-+ err = -ENXIO;
- }
-
-- ltq_mtd->mtd->dev.parent = &pdev->dev;
-- mtd_set_of_node(ltq_mtd->mtd, pdev->dev.of_node);
--
-- cfi = ltq_mtd->map->fldrv_priv;
-- cfi->addr_unlock1 ^= 1;
-- cfi->addr_unlock2 ^= 1;
-+ ltq_mtd->cmtd->dev.parent = &pdev->dev;
-+ mtd_set_of_node(ltq_mtd->cmtd, pdev->dev.of_node);
-
-- err = mtd_device_register(ltq_mtd->mtd, NULL, 0);
-+ err = mtd_device_register(ltq_mtd->cmtd, NULL, 0);
- if (err) {
- dev_err(&pdev->dev, "failed to add partitions\n");
-- goto err_destroy;
-+ goto err_out;
- }
-
- return 0;
-
--err_destroy:
-- map_destroy(ltq_mtd->mtd);
-+err_out:
-+ ltq_mtd_remove(pdev);
- return err;
- }
-
--static int
--ltq_mtd_remove(struct platform_device *pdev)
--{
-- struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
--
-- if (ltq_mtd && ltq_mtd->mtd) {
-- mtd_device_unregister(ltq_mtd->mtd);
-- map_destroy(ltq_mtd->mtd);
-- }
-- return 0;
--}
--
- static const struct of_device_id ltq_mtd_match[] = {
- { .compatible = "lantiq,nor" },
- {},
diff --git a/target/linux/lantiq/patches-5.15/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch b/target/linux/lantiq/patches-5.15/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch
deleted file mode 100644
index 472a24e66b..0000000000
--- a/target/linux/lantiq/patches-5.15/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 2b873c59fd313aee57864f96d64a228f2ea7c208 Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Mon, 13 May 2024 10:42:24 +0200
-Subject: [PATCH] MIPS: lantiq: xway: vmmc: use platform_get_irq to get irqs
- from dts
-
-Let's fetch the irqs from the dts here and expose them to the voice
-driver like it is done for the cp1 base memory.
-
-ToDo:
-Maybe it is possible to drop this driver completely and merge this
-handling to the voice driver.
-
-Signed-off-by: Martin Schiller <ms@dev.tdt.de>
----
- arch/mips/lantiq/xway/vmmc.c | 53 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 53 insertions(+)
-
---- a/arch/mips/lantiq/xway/vmmc.c
-+++ b/arch/mips/lantiq/xway/vmmc.c
-@@ -13,6 +13,10 @@
-
- static unsigned int *cp1_base;
-
-+static int ad0_irq;
-+static int ad1_irq;
-+static int vc_irq[4];
-+
- unsigned int *ltq_get_cp1_base(void)
- {
- if (!cp1_base)
-@@ -22,16 +26,65 @@ unsigned int *ltq_get_cp1_base(void)
- }
- EXPORT_SYMBOL(ltq_get_cp1_base);
-
-+unsigned int ltq_get_mps_ad0_irq(void)
-+{
-+ if (!ad0_irq)
-+ panic("no ad0 irq was set\n");
-+
-+ return ad0_irq;
-+}
-+EXPORT_SYMBOL(ltq_get_mps_ad0_irq);
-+
-+unsigned int ltq_get_mps_ad1_irq(void)
-+{
-+ if (!ad1_irq)
-+ panic("no ad1 irq was set\n");
-+
-+ return ad1_irq;
-+}
-+EXPORT_SYMBOL(ltq_get_mps_ad1_irq);
-+
-+unsigned int ltq_get_mps_vc_irq(int idx)
-+{
-+ if (!vc_irq[idx])
-+ panic("no vc%d irq was set\n", idx);
-+
-+ return vc_irq[idx];
-+}
-+EXPORT_SYMBOL(ltq_get_mps_vc_irq);
-+
- static int vmmc_probe(struct platform_device *pdev)
- {
- #define CP1_SIZE (1 << 20)
- int gpio_count;
- dma_addr_t dma;
-+ int i;
-
- cp1_base =
- (void *) CPHYSADDR(dma_alloc_coherent(&pdev->dev, CP1_SIZE,
- &dma, GFP_KERNEL));
-
-+ ad0_irq = platform_get_irq(pdev, 4);
-+ if (ad0_irq < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS AD0 irq: %d\n", ad0_irq);
-+ return ad0_irq;
-+ }
-+
-+ ad1_irq = platform_get_irq(pdev, 5);
-+ if (ad1_irq < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS AD1 irq: %d\n", ad1_irq);
-+ return ad1_irq;
-+ }
-+
-+ for (i = 0; i < 4; i++) {
-+ vc_irq[i] = platform_get_irq(pdev, i);
-+ if (vc_irq[i] < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS VC%d irq: %d\n",
-+ i, vc_irq[i]);
-+ return vc_irq[i];
-+ }
-+ }
-+
- gpio_count = of_gpio_count(pdev->dev.of_node);
- while (gpio_count > 0) {
- enum of_gpio_flags flags;
diff --git a/target/linux/lantiq/patches-5.15/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch b/target/linux/lantiq/patches-5.15/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch
deleted file mode 100644
index f62d167078..0000000000
--- a/target/linux/lantiq/patches-5.15/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 5e93c85ac3e5626d1aa7e7f9c0a008b2a4224f04 Mon Sep 17 00:00:00 2001
-From: Matti Laakso <malaakso@elisanet.fi>
-Date: Sat, 14 Feb 2015 20:48:00 +0000
-Subject: [PATCH] MTD: cfi_cmdset_0001: disable buffered writes
-
-Signed-off-by: Matti Laakso <malaakso@elisanet.fi>
----
- drivers/mtd/chips/cfi_cmdset_0001.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/chips/cfi_cmdset_0001.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
-@@ -39,7 +39,7 @@
- /* #define CMDSET0001_DISABLE_WRITE_SUSPEND */
-
- // debugging, turns off buffer write mode if set to 1
--#define FORCE_WORD_WRITE 0
-+#define FORCE_WORD_WRITE 1
-
- /* Intel chips */
- #define I82802AB 0x00ad
diff --git a/target/linux/lantiq/patches-5.15/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch b/target/linux/lantiq/patches-5.15/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch
deleted file mode 100644
index 6dacba56d5..0000000000
--- a/target/linux/lantiq/patches-5.15/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 5502ef9d40ab20b2ac683660d1565a7c4968bcc8 Mon Sep 17 00:00:00 2001
-From: Mathias Kresin <openwrt@kresin.me>
-Date: Mon, 2 May 2016 18:50:00 +0000
-Subject: [PATCH] xrx200: add gphy clk src device tree binding
-
-Signed-off-by: Mathias Kresin <openwrt@kresin.me>
----
- arch/mips/lantiq/xway/sysctrl.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/arch/mips/lantiq/xway/sysctrl.c
-+++ b/arch/mips/lantiq/xway/sysctrl.c
-@@ -440,6 +440,20 @@ static void clkdev_add_clkout(void)
- }
- }
-
-+static void set_phy_clock_source(struct device_node *np_cgu)
-+{
-+ u32 phy_clk_src, ifcc;
-+
-+ if (!np_cgu)
-+ return;
-+
-+ if (of_property_read_u32(np_cgu, "lantiq,phy-clk-src", &phy_clk_src))
-+ return;
-+
-+ ifcc = ltq_cgu_r32(ifccr) & ~(0x1c);
-+ ltq_cgu_w32(ifcc | (phy_clk_src << 2), ifccr);
-+}
-+
- /* bring up all register ranges that we need for basic system control */
- void __init ltq_soc_init(void)
- {
-@@ -605,4 +619,6 @@ void __init ltq_soc_init(void)
- clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
- }
- usb_set_clock();
-+
-+ set_phy_clock_source(np_cgu);
- }
diff --git a/target/linux/lantiq/patches-5.15/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch b/target/linux/lantiq/patches-5.15/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch
deleted file mode 100644
index c43d9d4b35..0000000000
--- a/target/linux/lantiq/patches-5.15/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 118fe2c88b35482711adeee0d8758bddfe958701 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Sat, 6 May 2023 14:32:00 +0200
-Subject: [PATCH] mtd: cfi_cmdset_0001: Disable write buffer functions if
- FORCE_WORD_WRITE is 1
-
-Some write buffer functions are not used when FORCE_WORD_WRITE is set to 1.
-So the compile warning messages are output if FORCE_WORD_WRITE is 1. To
-resolve this disable the write buffer functions if FORCE_WORD_WRITE is 1.
-
-This is similar fix to: 557c759036fc3976a5358cef23e65a263853b93f.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
----
- drivers/mtd/chips/cfi_cmdset_0001.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/mtd/chips/cfi_cmdset_0001.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
-@@ -61,8 +61,10 @@
-
- static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-+#if !FORCE_WORD_WRITE
- static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
- static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
-+#endif
- static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
- static void cfi_intelext_sync (struct mtd_info *);
- static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
-@@ -304,6 +306,7 @@ static void fixup_use_point(struct mtd_i
- }
- }
-
-+#if !FORCE_WORD_WRITE
- static void fixup_use_write_buffers(struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -314,6 +317,7 @@ static void fixup_use_write_buffers(stru
- mtd->_writev = cfi_intelext_writev;
- }
- }
-+#endif /* !FORCE_WORD_WRITE */
-
- /*
- * Some chips power-up with all sectors locked by default.
-@@ -1719,6 +1723,7 @@ static int cfi_intelext_write_words (str
- }
-
-
-+#if !FORCE_WORD_WRITE
- static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
- unsigned long adr, const struct kvec **pvec,
- unsigned long *pvec_seek, int len)
-@@ -1947,6 +1952,7 @@ static int cfi_intelext_write_buffers (s
-
- return cfi_intelext_writev(mtd, &vec, 1, to, retlen);
- }
-+#endif /* !FORCE_WORD_WRITE */
-
- static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
- unsigned long adr, int len, void *thunk)
diff --git a/target/linux/lantiq/patches-5.15/0310-v5.16-MIPS-lantiq-dma-make-the-burst-length-configurable-b.patch b/target/linux/lantiq/patches-5.15/0310-v5.16-MIPS-lantiq-dma-make-the-burst-length-configurable-b.patch
deleted file mode 100644
index 4f3210a6c3..0000000000
--- a/target/linux/lantiq/patches-5.15/0310-v5.16-MIPS-lantiq-dma-make-the-burst-length-configurable-b.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 49293bbc50cb7d44223eb49e0f7cb38e7dac2361 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 14 Sep 2021 23:21:01 +0200
-Subject: [PATCH 4/5] MIPS: lantiq: dma: make the burst length configurable by
- the drivers
-
-Make the burst length configurable by the drivers.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../include/asm/mach-lantiq/xway/xway_dma.h | 2 +-
- arch/mips/lantiq/xway/dma.c | 38 ++++++++++++++++---
- 2 files changed, 34 insertions(+), 6 deletions(-)
-
---- a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-@@ -45,6 +45,6 @@ extern void ltq_dma_close(struct ltq_dma
- extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch);
- extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch);
- extern void ltq_dma_free(struct ltq_dma_channel *ch);
--extern void ltq_dma_init_port(int p);
-+extern void ltq_dma_init_port(int p, int tx_burst, int rx_burst);
-
- #endif
---- a/arch/mips/lantiq/xway/dma.c
-+++ b/arch/mips/lantiq/xway/dma.c
-@@ -182,7 +182,7 @@ ltq_dma_free(struct ltq_dma_channel *ch)
- EXPORT_SYMBOL_GPL(ltq_dma_free);
-
- void
--ltq_dma_init_port(int p)
-+ltq_dma_init_port(int p, int tx_burst, int rx_burst)
- {
- ltq_dma_w32(p, LTQ_DMA_PS);
- switch (p) {
-@@ -191,16 +191,44 @@ ltq_dma_init_port(int p)
- * Tell the DMA engine to swap the endianness of data frames and
- * drop packets if the channel arbitration fails.
- */
-- ltq_dma_w32_mask(0, DMA_ETOP_ENDIANNESS | DMA_PDEN,
-+ ltq_dma_w32_mask(0, (DMA_ETOP_ENDIANNESS | DMA_PDEN),
- LTQ_DMA_PCTRL);
- break;
-
-- case DMA_PORT_DEU:
-- ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) |
-- (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT),
-+ default:
-+ break;
-+ }
-+
-+ switch (rx_burst) {
-+ case 8:
-+ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_8W_BURST << DMA_RX_BURST_SHIFT),
- LTQ_DMA_PCTRL);
- break;
-+ case 4:
-+ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_4W_BURST << DMA_RX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ case 2:
-+ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ default:
-+ break;
-+ }
-
-+ switch (tx_burst) {
-+ case 8:
-+ ltq_dma_w32_mask(0x30, (DMA_PCTRL_8W_BURST << DMA_TX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ case 4:
-+ ltq_dma_w32_mask(0x30, (DMA_PCTRL_4W_BURST << DMA_TX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ case 2:
-+ ltq_dma_w32_mask(0x30, (DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
- default:
- break;
- }
diff --git a/target/linux/lantiq/patches-5.15/0320-v6.1-MIPS-lantiq-enable-all-hardware-interrupts-on-second.patch b/target/linux/lantiq/patches-5.15/0320-v6.1-MIPS-lantiq-enable-all-hardware-interrupts-on-second.patch
deleted file mode 100644
index d98664c478..0000000000
--- a/target/linux/lantiq/patches-5.15/0320-v6.1-MIPS-lantiq-enable-all-hardware-interrupts-on-second.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From 730320fd770d4114a2ecb6fb223dcc8c3cecdc5b Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 21 Sep 2022 22:59:44 +0200
-Subject: [PATCH] MIPS: lantiq: enable all hardware interrupts on second VPE
-
-This patch is needed to handle interrupts by the second VPE on the Lantiq
-ARX100, xRX200, xRX300 and xRX330 SoCs. Switching some ICU interrupts to
-the second VPE results in a hang. Currently, the vsmp_init_secondary()
-function is responsible for enabling these interrupts. It only enables
-Malta-specific interrupts (SW0, SW1, HW4 and HW5).
-
-The MIPS core has 8 interrupts defined. On Lantiq SoCs, hardware
-interrupts are wired to an ICU instance. Each VPE has an independent
-instance of the ICU. The mapping of the ICU interrupts is shown below:
-SW0(IP0) - IPI call,
-SW1(IP1) - IPI resched,
-HW0(IP2) - ICU 0-31,
-HW1(IP3) - ICU 32-63,
-HW2(IP4) - ICU 64-95,
-HW3(IP5) - ICU 96-127,
-HW4(IP6) - ICU 128-159,
-HW5(IP7) - timer.
-
-This patch enables all interrupt lines on the second VPE.
-
-This problem affects multithreaded SoCs with a custom interrupt controller.
-SOCs with 1004Kc core and newer use the MIPS GIC. At this point, I am aware
-that the Realtek RTL839x and RTL930x SoCs may need a similar fix. In the
-future, this may be replaced with some generic solution.
-
-Tested on Lantiq xRX200.
-
-Suggested-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/lantiq/prom.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
-
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -31,6 +31,14 @@ static struct ltq_soc_info soc_info;
- /* for Multithreading (APRP), vpe.c will use it */
- unsigned long cp0_memsize;
-
-+/*
-+ * These structs are used to override vsmp_init_secondary()
-+ */
-+#if defined(CONFIG_MIPS_MT_SMP)
-+extern const struct plat_smp_ops vsmp_smp_ops;
-+static struct plat_smp_ops lantiq_smp_ops;
-+#endif
-+
- const char *get_system_type(void)
- {
- return soc_info.sys_type;
-@@ -87,6 +95,17 @@ void __init device_tree_init(void)
- unflatten_and_copy_device_tree();
- }
-
-+#if defined(CONFIG_MIPS_MT_SMP)
-+static void lantiq_init_secondary(void)
-+{
-+ /*
-+ * MIPS CPU startup function vsmp_init_secondary() will only
-+ * enable some of the interrupts for the second CPU/VPE.
-+ */
-+ set_c0_status(ST0_IM);
-+}
-+#endif
-+
- void __init prom_init(void)
- {
- /* call the soc specific detetcion code and get it to fill soc_info */
-@@ -98,7 +117,10 @@ void __init prom_init(void)
- prom_init_cmdline();
-
- #if defined(CONFIG_MIPS_MT_SMP)
-- if (register_vsmp_smp_ops())
-- panic("failed to register_vsmp_smp_ops()");
-+ if (cpu_has_mipsmt) {
-+ lantiq_smp_ops = vsmp_smp_ops;
-+ lantiq_smp_ops.init_secondary = lantiq_init_secondary;
-+ register_smp_ops(&lantiq_smp_ops);
-+ }
- #endif
- }
diff --git a/target/linux/lantiq/patches-5.15/0321-v6.8-MIPS-lantiq-register-smp_ops-on-non-smp-platforms.patch b/target/linux/lantiq/patches-5.15/0321-v6.8-MIPS-lantiq-register-smp_ops-on-non-smp-platforms.patch
deleted file mode 100644
index 1acf73b2d5..0000000000
--- a/target/linux/lantiq/patches-5.15/0321-v6.8-MIPS-lantiq-register-smp_ops-on-non-smp-platforms.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 4bf2a626dc4bb46f0754d8ac02ec8584ff114ad5 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Mon, 22 Jan 2024 19:47:09 +0100
-Subject: [PATCH] MIPS: lantiq: register smp_ops on non-smp platforms
-
-Lantiq uses a common kernel config for devices with 24Kc and 34Kc cores.
-The changes made previously to add support for interrupts on all cores
-work on 24Kc platforms with SMP disabled and 34Kc platforms with SMP
-enabled. This patch fixes boot issues on Danube (single core 24Kc) with
-SMP enabled.
-
-Fixes: 730320fd770d ("MIPS: lantiq: enable all hardware interrupts on second VPE")
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/lantiq/prom.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -117,10 +117,9 @@ void __init prom_init(void)
- prom_init_cmdline();
-
- #if defined(CONFIG_MIPS_MT_SMP)
-- if (cpu_has_mipsmt) {
-- lantiq_smp_ops = vsmp_smp_ops;
-+ lantiq_smp_ops = vsmp_smp_ops;
-+ if (cpu_has_mipsmt)
- lantiq_smp_ops.init_secondary = lantiq_init_secondary;
-- register_smp_ops(&lantiq_smp_ops);
-- }
-+ register_smp_ops(&lantiq_smp_ops);
- #endif
- }
diff --git a/target/linux/lantiq/patches-5.15/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch b/target/linux/lantiq/patches-5.15/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch
deleted file mode 100644
index edf0626860..0000000000
--- a/target/linux/lantiq/patches-5.15/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 416f25a948d11ef15733f2e31658d31b5cc7bef6 Mon Sep 17 00:00:00 2001
-From: Thomas Nixon <tom@tomn.co.uk>
-Date: Sun, 26 Mar 2023 11:08:49 +0100
-Subject: [PATCH] mtd: rawnand: xway: don't yield while holding spinlock
-
-The nand driver normally while waiting for the device to become ready;
-this is normally fine, but xway_nand holds the ebu_lock spinlock, and
-this can cause lockups if other threads which use ebu_lock are
-interleaved. Fix this by waiting instead of polling.
-
-This mainly showed up as crashes in ath9k_pci_owl_loader (see
-https://github.com/openwrt/openwrt/issues/9829 ), but turning on
-spinlock debugging shows this happening in other places too.
-
-This doesn't seem to measurably impact boot time.
-
-Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
----
- drivers/mtd/nand/raw/xway_nand.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/raw/xway_nand.c
-+++ b/drivers/mtd/nand/raw/xway_nand.c
-@@ -175,7 +175,13 @@ static void xway_cmd_ctrl(struct nand_ch
-
- static int xway_dev_ready(struct nand_chip *chip)
- {
-- return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD;
-+ /*
-+ * wait until ready, as otherwise the driver will yield in nand_wait or
-+ * nand_wait_ready, which is a bad idea when we're holding ebu_lock
-+ */
-+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
-+ cpu_relax();
-+ return 1;
- }
-
- static unsigned char xway_read_byte(struct nand_chip *chip)
diff --git a/target/linux/lantiq/patches-5.15/0701-NET-lantiq-etop-of-mido.patch b/target/linux/lantiq/patches-5.15/0701-NET-lantiq-etop-of-mido.patch
deleted file mode 100644
index 7e49b47e02..0000000000
--- a/target/linux/lantiq/patches-5.15/0701-NET-lantiq-etop-of-mido.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 870ed9cae083ff8a60a739ef7e74c5a1800533be Mon Sep 17 00:00:00 2001
-From: Johann Neuhauser <johann@it-neuhauser.de>
-Date: Thu, 17 May 2018 19:12:35 +0200
-Subject: [PATCH] net: lantiq_etop: of mdio
-
-Signed-off-by: Johann Neuhauser <johann@it-neuhauser.de>
----
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -30,6 +30,7 @@
- #include <linux/of_net.h>
- #include <linux/of_irq.h>
- #include <linux/of_platform.h>
-+#include <linux/of_mdio.h>
-
- #include <asm/checksum.h>
-
-@@ -553,7 +554,8 @@ static int
- ltq_etop_mdio_init(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int err;
-+ struct device_node *mdio_np = NULL;
-+ int err, ret;
-
- priv->mii_bus = mdiobus_alloc();
- if (!priv->mii_bus) {
-@@ -573,7 +575,15 @@ ltq_etop_mdio_init(struct net_device *de
- priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- priv->pdev->name, priv->pdev->id);
-- if (mdiobus_register(priv->mii_bus)) {
-+
-+ mdio_np = of_get_child_by_name(priv->pdev->dev.of_node, "mdio-bus");
-+
-+ if (mdio_np)
-+ ret = of_mdiobus_register(priv->mii_bus, mdio_np);
-+ else
-+ ret = mdiobus_register(priv->mii_bus);
-+
-+ if (ret) {
- err = -ENXIO;
- goto err_out_free_mdiobus;
- }
diff --git a/target/linux/lantiq/patches-5.15/0702-v5.16-net-lantiq-add-support-for-jumbo-frames.patch b/target/linux/lantiq/patches-5.15/0702-v5.16-net-lantiq-add-support-for-jumbo-frames.patch
deleted file mode 100644
index 4a4109c772..0000000000
--- a/target/linux/lantiq/patches-5.15/0702-v5.16-net-lantiq-add-support-for-jumbo-frames.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 998ac358019e491217e752bc6dcbb3afb2a6fa3e Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Sun, 19 Sep 2021 20:24:28 +0200
-Subject: [PATCH] net: lantiq: add support for jumbo frames
-
-Add support for jumbo frames. Full support for jumbo frames requires
-changes in the DSA switch driver (lantiq_gswip.c).
-
-Tested on BT Hone Hub 5A.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 64 +++++++++++++++++++++++++---
- 1 file changed, 57 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -14,13 +14,15 @@
- #include <linux/clk.h>
- #include <linux/delay.h>
-
-+#include <linux/if_vlan.h>
-+
- #include <linux/of_net.h>
- #include <linux/of_platform.h>
-
- #include <xway_dma.h>
-
- /* DMA */
--#define XRX200_DMA_DATA_LEN 0x600
-+#define XRX200_DMA_DATA_LEN (SZ_64K - 1)
- #define XRX200_DMA_RX 0
- #define XRX200_DMA_TX 1
-
-@@ -106,7 +108,8 @@ static void xrx200_flush_dma(struct xrx2
- break;
-
- desc->ctl = LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
-- XRX200_DMA_DATA_LEN;
-+ (ch->priv->net_dev->mtu + VLAN_ETH_HLEN +
-+ ETH_FCS_LEN);
- ch->dma.desc++;
- ch->dma.desc %= LTQ_DESC_NUM;
- }
-@@ -154,19 +157,20 @@ static int xrx200_close(struct net_devic
-
- static int xrx200_alloc_skb(struct xrx200_chan *ch)
- {
-+ int len = ch->priv->net_dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
- struct sk_buff *skb = ch->skb[ch->dma.desc];
- dma_addr_t mapping;
- int ret = 0;
-
- ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev,
-- XRX200_DMA_DATA_LEN);
-+ len);
- if (!ch->skb[ch->dma.desc]) {
- ret = -ENOMEM;
- goto skip;
- }
-
- mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data,
-- XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE);
-+ len, DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) {
- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
- ch->skb[ch->dma.desc] = skb;
-@@ -179,8 +183,7 @@ static int xrx200_alloc_skb(struct xrx20
- wmb();
- skip:
- ch->dma.desc_base[ch->dma.desc].ctl =
-- LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
-- XRX200_DMA_DATA_LEN;
-+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | len;
-
- return ret;
- }
-@@ -340,10 +343,57 @@ err_drop:
- return NETDEV_TX_OK;
- }
-
-+static int
-+xrx200_change_mtu(struct net_device *net_dev, int new_mtu)
-+{
-+ struct xrx200_priv *priv = netdev_priv(net_dev);
-+ struct xrx200_chan *ch_rx = &priv->chan_rx;
-+ int old_mtu = net_dev->mtu;
-+ bool running = false;
-+ struct sk_buff *skb;
-+ int curr_desc;
-+ int ret = 0;
-+
-+ net_dev->mtu = new_mtu;
-+
-+ if (new_mtu <= old_mtu)
-+ return ret;
-+
-+ running = netif_running(net_dev);
-+ if (running) {
-+ napi_disable(&ch_rx->napi);
-+ ltq_dma_close(&ch_rx->dma);
-+ }
-+
-+ xrx200_poll_rx(&ch_rx->napi, LTQ_DESC_NUM);
-+ curr_desc = ch_rx->dma.desc;
-+
-+ for (ch_rx->dma.desc = 0; ch_rx->dma.desc < LTQ_DESC_NUM;
-+ ch_rx->dma.desc++) {
-+ skb = ch_rx->skb[ch_rx->dma.desc];
-+ ret = xrx200_alloc_skb(ch_rx);
-+ if (ret) {
-+ net_dev->mtu = old_mtu;
-+ break;
-+ }
-+ dev_kfree_skb_any(skb);
-+ }
-+
-+ ch_rx->dma.desc = curr_desc;
-+ if (running) {
-+ napi_enable(&ch_rx->napi);
-+ ltq_dma_open(&ch_rx->dma);
-+ ltq_dma_enable_irq(&ch_rx->dma);
-+ }
-+
-+ return ret;
-+}
-+
- static const struct net_device_ops xrx200_netdev_ops = {
- .ndo_open = xrx200_open,
- .ndo_stop = xrx200_close,
- .ndo_start_xmit = xrx200_start_xmit,
-+ .ndo_change_mtu = xrx200_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- };
-@@ -453,7 +503,7 @@ static int xrx200_probe(struct platform_
- net_dev->netdev_ops = &xrx200_netdev_ops;
- SET_NETDEV_DEV(net_dev, dev);
- net_dev->min_mtu = ETH_ZLEN;
-- net_dev->max_mtu = XRX200_DMA_DATA_LEN;
-+ net_dev->max_mtu = XRX200_DMA_DATA_LEN - VLAN_ETH_HLEN - ETH_FCS_LEN;
-
- /* load the memory ranges */
- priv->pmac_reg = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
diff --git a/target/linux/lantiq/patches-5.15/0703-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch b/target/linux/lantiq/patches-5.15/0703-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch
deleted file mode 100644
index c197b1a1c9..0000000000
--- a/target/linux/lantiq/patches-5.15/0703-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 1488fc204568f707fe2a42a913788c00a95af30e Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Fri, 17 Dec 2021 01:07:40 +0100
-Subject: [PATCH] net: lantiq_xrx200: increase buffer reservation
-
-If the user sets a lower mtu on the CPU port than on the switch,
-then DMA inserts a few more bytes into the buffer than expected.
-In the worst case, it may exceed the size of the buffer. The
-experiments showed that the buffer should be a multiple of the
-burst length value. This patch rounds the length of the rx buffer
-upwards and fixes this bug. The reservation of FCS space in the
-buffer has been removed as PMAC strips the FCS.
-
-Fixes: 998ac358019e ("net: lantiq: add support for jumbo frames")
-Reported-by: Thomas Nixon <tom@tomn.co.uk>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 34 ++++++++++++++++++++--------
- 1 file changed, 24 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -70,6 +70,8 @@ struct xrx200_priv {
- struct xrx200_chan chan_tx;
- struct xrx200_chan chan_rx;
-
-+ u16 rx_buf_size;
-+
- struct net_device *net_dev;
- struct device *dev;
-
-@@ -96,6 +98,16 @@ static void xrx200_pmac_mask(struct xrx2
- xrx200_pmac_w32(priv, val, offset);
- }
-
-+static int xrx200_max_frame_len(int mtu)
-+{
-+ return VLAN_ETH_HLEN + mtu;
-+}
-+
-+static int xrx200_buffer_size(int mtu)
-+{
-+ return round_up(xrx200_max_frame_len(mtu), 4 * XRX200_DMA_BURST_LEN);
-+}
-+
- /* drop all the packets from the DMA ring */
- static void xrx200_flush_dma(struct xrx200_chan *ch)
- {
-@@ -108,8 +120,7 @@ static void xrx200_flush_dma(struct xrx2
- break;
-
- desc->ctl = LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
-- (ch->priv->net_dev->mtu + VLAN_ETH_HLEN +
-- ETH_FCS_LEN);
-+ ch->priv->rx_buf_size;
- ch->dma.desc++;
- ch->dma.desc %= LTQ_DESC_NUM;
- }
-@@ -157,21 +168,21 @@ static int xrx200_close(struct net_devic
-
- static int xrx200_alloc_skb(struct xrx200_chan *ch)
- {
-- int len = ch->priv->net_dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
- struct sk_buff *skb = ch->skb[ch->dma.desc];
-+ struct xrx200_priv *priv = ch->priv;
- dma_addr_t mapping;
- int ret = 0;
-
-- ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev,
-- len);
-+ ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(priv->net_dev,
-+ priv->rx_buf_size);
- if (!ch->skb[ch->dma.desc]) {
- ret = -ENOMEM;
- goto skip;
- }
-
-- mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data,
-- len, DMA_FROM_DEVICE);
-- if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) {
-+ mapping = dma_map_single(priv->dev, ch->skb[ch->dma.desc]->data,
-+ priv->rx_buf_size, DMA_FROM_DEVICE);
-+ if (unlikely(dma_mapping_error(priv->dev, mapping))) {
- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
- ch->skb[ch->dma.desc] = skb;
- ret = -ENOMEM;
-@@ -183,7 +194,7 @@ static int xrx200_alloc_skb(struct xrx20
- wmb();
- skip:
- ch->dma.desc_base[ch->dma.desc].ctl =
-- LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | len;
-+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | priv->rx_buf_size;
-
- return ret;
- }
-@@ -355,6 +366,7 @@ xrx200_change_mtu(struct net_device *net
- int ret = 0;
-
- net_dev->mtu = new_mtu;
-+ priv->rx_buf_size = xrx200_buffer_size(new_mtu);
-
- if (new_mtu <= old_mtu)
- return ret;
-@@ -374,6 +386,7 @@ xrx200_change_mtu(struct net_device *net
- ret = xrx200_alloc_skb(ch_rx);
- if (ret) {
- net_dev->mtu = old_mtu;
-+ priv->rx_buf_size = xrx200_buffer_size(old_mtu);
- break;
- }
- dev_kfree_skb_any(skb);
-@@ -503,7 +516,8 @@ static int xrx200_probe(struct platform_
- net_dev->netdev_ops = &xrx200_netdev_ops;
- SET_NETDEV_DEV(net_dev, dev);
- net_dev->min_mtu = ETH_ZLEN;
-- net_dev->max_mtu = XRX200_DMA_DATA_LEN - VLAN_ETH_HLEN - ETH_FCS_LEN;
-+ net_dev->max_mtu = XRX200_DMA_DATA_LEN - xrx200_max_frame_len(0);
-+ priv->rx_buf_size = xrx200_buffer_size(ETH_DATA_LEN);
-
- /* load the memory ranges */
- priv->pmac_reg = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
diff --git a/target/linux/lantiq/patches-5.15/0704-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch b/target/linux/lantiq/patches-5.15/0704-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch
deleted file mode 100644
index f2c36952fc..0000000000
--- a/target/linux/lantiq/patches-5.15/0704-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From c3e6b2c35b34214c58c1e90d65dab5f5393608e7 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Mon, 3 Jan 2022 20:43:16 +0100
-Subject: [PATCH] net: lantiq_xrx200: add ingress SG DMA support
-
-This patch adds support for scatter gather DMA. DMA in PMAC splits
-the packet into several buffers when the MTU on the CPU port is
-less than the MTU of the switch. The first buffer starts at an
-offset of NET_IP_ALIGN. In subsequent buffers, dma ignores the
-offset. Thanks to this patch, the user can still connect to the
-device in such a situation. For normal configurations, the patch
-has no effect on performance.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 47 +++++++++++++++++++++++-----
- 1 file changed, 40 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -26,6 +26,9 @@
- #define XRX200_DMA_RX 0
- #define XRX200_DMA_TX 1
-
-+#define XRX200_DMA_PACKET_COMPLETE 0
-+#define XRX200_DMA_PACKET_IN_PROGRESS 1
-+
- /* cpu port mac */
- #define PMAC_RX_IPG 0x0024
- #define PMAC_RX_IPG_MASK 0xf
-@@ -61,6 +64,9 @@ struct xrx200_chan {
- struct ltq_dma_channel dma;
- struct sk_buff *skb[LTQ_DESC_NUM];
-
-+ struct sk_buff *skb_head;
-+ struct sk_buff *skb_tail;
-+
- struct xrx200_priv *priv;
- };
-
-@@ -204,7 +210,8 @@ static int xrx200_hw_receive(struct xrx2
- struct xrx200_priv *priv = ch->priv;
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
- struct sk_buff *skb = ch->skb[ch->dma.desc];
-- int len = (desc->ctl & LTQ_DMA_SIZE_MASK);
-+ u32 ctl = desc->ctl;
-+ int len = (ctl & LTQ_DMA_SIZE_MASK);
- struct net_device *net_dev = priv->net_dev;
- int ret;
-
-@@ -220,12 +227,36 @@ static int xrx200_hw_receive(struct xrx2
- }
-
- skb_put(skb, len);
-- skb->protocol = eth_type_trans(skb, net_dev);
-- netif_receive_skb(skb);
-- net_dev->stats.rx_packets++;
-- net_dev->stats.rx_bytes += len;
-
-- return 0;
-+ /* add buffers to skb via skb->frag_list */
-+ if (ctl & LTQ_DMA_SOP) {
-+ ch->skb_head = skb;
-+ ch->skb_tail = skb;
-+ } else if (ch->skb_head) {
-+ if (ch->skb_head == ch->skb_tail)
-+ skb_shinfo(ch->skb_tail)->frag_list = skb;
-+ else
-+ ch->skb_tail->next = skb;
-+ ch->skb_tail = skb;
-+ skb_reserve(ch->skb_tail, -NET_IP_ALIGN);
-+ ch->skb_head->len += skb->len;
-+ ch->skb_head->data_len += skb->len;
-+ ch->skb_head->truesize += skb->truesize;
-+ }
-+
-+ if (ctl & LTQ_DMA_EOP) {
-+ ch->skb_head->protocol = eth_type_trans(ch->skb_head, net_dev);
-+ netif_receive_skb(ch->skb_head);
-+ net_dev->stats.rx_packets++;
-+ net_dev->stats.rx_bytes += ch->skb_head->len;
-+ ch->skb_head = NULL;
-+ ch->skb_tail = NULL;
-+ ret = XRX200_DMA_PACKET_COMPLETE;
-+ } else {
-+ ret = XRX200_DMA_PACKET_IN_PROGRESS;
-+ }
-+
-+ return ret;
- }
-
- static int xrx200_poll_rx(struct napi_struct *napi, int budget)
-@@ -240,7 +271,9 @@ static int xrx200_poll_rx(struct napi_st
-
- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
- ret = xrx200_hw_receive(ch);
-- if (ret)
-+ if (ret == XRX200_DMA_PACKET_IN_PROGRESS)
-+ continue;
-+ if (ret != XRX200_DMA_PACKET_COMPLETE)
- return ret;
- rx++;
- } else {
diff --git a/target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch b/target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
deleted file mode 100644
index 22aa2eea6e..0000000000
--- a/target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From c40bb4fedcd6b8b6a714da5dd466eb88ed2652d1 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 9 Mar 2022 00:04:57 +0100
-Subject: net: dsa: lantiq_gswip: enable jumbo frames on GSWIP
-
-This enables non-standard MTUs on a per-port basis, with the overall
-frame size set based on the CPU port.
-
-When the MTU is not changed, this should have no effect.
-
-Long packets crash the switch with MTUs of greater than 2526, so the
-maximum is limited for now. Medium packets are sometimes dropped (e.g.
-TCP over 2477, UDP over 2516-2519, ICMP over 2526), Hence an MTU value
-of 2400 seems safe.
-
-Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Link: https://lore.kernel.org/r/20220308230457.1599237-1-olek2@wp.pl
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++++++++++++++++++++++++----
- 1 file changed, 49 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -213,6 +213,7 @@
- #define GSWIP_MAC_CTRL_0_GMII_MII 0x0001
- #define GSWIP_MAC_CTRL_0_GMII_RGMII 0x0002
- #define GSWIP_MAC_CTRL_2p(p) (0x905 + ((p) * 0xC))
-+#define GSWIP_MAC_CTRL_2_LCHKL BIT(2) /* Frame Length Check Long Enable */
- #define GSWIP_MAC_CTRL_2_MLEN BIT(3) /* Maximum Untagged Frame Lnegth */
-
- /* Ethernet Switch Fetch DMA Port Control Register */
-@@ -239,6 +240,15 @@
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-+/* Maximum packet size supported by the switch. In theory this should be 10240,
-+ * but long packets currently cause lock-ups with an MTU of over 2526. Medium
-+ * packets are sometimes dropped (e.g. TCP over 2477, UDP over 2516-2519, ICMP
-+ * over 2526), hence an MTU value of 2400 seems safe. This issue only affects
-+ * packet reception. This is probably caused by the PPA engine, which is on the
-+ * RX part of the device. Packet transmission works properly up to 10240.
-+ */
-+#define GSWIP_MAX_PACKET_LENGTH 2400
-+
- struct gswip_hw_info {
- int max_ports;
- int cpu_port;
-@@ -846,10 +856,6 @@ static int gswip_setup(struct dsa_switch
- gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
- GSWIP_PCE_PCTRL_0p(cpu_port));
-
-- gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
-- GSWIP_MAC_CTRL_2p(cpu_port));
-- gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8 + ETH_FCS_LEN,
-- GSWIP_MAC_FLEN);
- gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD,
- GSWIP_BM_QUEUE_GCTRL);
-
-@@ -866,6 +872,8 @@ static int gswip_setup(struct dsa_switch
- return err;
- }
-
-+ ds->mtu_enforcement_ingress = true;
-+
- gswip_port_enable(ds, cpu_port, NULL);
-
- ds->configure_vlan_while_not_filtering = false;
-@@ -1456,6 +1464,39 @@ static void gswip_phylink_set_capab(unsi
- linkmode_and(state->advertising, state->advertising, mask);
- }
-
-+static int gswip_port_max_mtu(struct dsa_switch *ds, int port)
-+{
-+ /* Includes 8 bytes for special header. */
-+ return GSWIP_MAX_PACKET_LENGTH - VLAN_ETH_HLEN - ETH_FCS_LEN;
-+}
-+
-+static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
-+{
-+ struct gswip_priv *priv = ds->priv;
-+ int cpu_port = priv->hw_info->cpu_port;
-+
-+ /* CPU port always has maximum mtu of user ports, so use it to set
-+ * switch frame size, including 8 byte special header.
-+ */
-+ if (port == cpu_port) {
-+ new_mtu += 8;
-+ gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
-+ GSWIP_MAC_FLEN);
-+ }
-+
-+ /* Enable MLEN for ports with non-standard MTUs, including the special
-+ * header on the CPU port added above.
-+ */
-+ if (new_mtu != ETH_DATA_LEN)
-+ gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
-+ GSWIP_MAC_CTRL_2p(port));
-+ else
-+ gswip_switch_mask(priv, GSWIP_MAC_CTRL_2_MLEN, 0,
-+ GSWIP_MAC_CTRL_2p(port));
-+
-+ return 0;
-+}
-+
- static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state)
-@@ -1812,6 +1853,8 @@ static const struct dsa_switch_ops gswip
- .port_fdb_add = gswip_port_fdb_add,
- .port_fdb_del = gswip_port_fdb_del,
- .port_fdb_dump = gswip_port_fdb_dump,
-+ .port_change_mtu = gswip_port_change_mtu,
-+ .port_max_mtu = gswip_port_max_mtu,
- .phylink_validate = gswip_xrx200_phylink_validate,
- .phylink_mac_config = gswip_phylink_mac_config,
- .phylink_mac_link_down = gswip_phylink_mac_link_down,
-@@ -1836,6 +1879,8 @@ static const struct dsa_switch_ops gswip
- .port_fdb_add = gswip_port_fdb_add,
- .port_fdb_del = gswip_port_fdb_del,
- .port_fdb_dump = gswip_port_fdb_dump,
-+ .port_change_mtu = gswip_port_change_mtu,
-+ .port_max_mtu = gswip_port_max_mtu,
- .phylink_validate = gswip_xrx300_phylink_validate,
- .phylink_mac_config = gswip_phylink_mac_config,
- .phylink_mac_link_down = gswip_phylink_mac_link_down,
diff --git a/target/linux/lantiq/patches-5.15/0710-v5.16-net-lantiq-configure-the-burst-length-in-ethernet-dr.patch b/target/linux/lantiq/patches-5.15/0710-v5.16-net-lantiq-configure-the-burst-length-in-ethernet-dr.patch
deleted file mode 100644
index 818fa811e9..0000000000
--- a/target/linux/lantiq/patches-5.15/0710-v5.16-net-lantiq-configure-the-burst-length-in-ethernet-dr.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 14d4e308e0aa0b78dc7a059716861a4380de3535 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 14 Sep 2021 23:21:02 +0200
-Subject: [PATCH 5/5] net: lantiq: configure the burst length in ethernet
- drivers
-
-Configure the burst length in Ethernet drivers. This improves
-Ethernet performance by 58%. According to the vendor BSP,
-8W burst length is supported by ar9 and newer SoCs.
-
-The NAT benchmark results on xRX200 (Down/Up):
-* 2W: 330 Mb/s
-* 4W: 432 Mb/s 372 Mb/s
-* 8W: 520 Mb/s 389 Mb/s
-
-Tested on xRX200 and xRX330.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_etop.c | 21 ++++++++++++++++++---
- drivers/net/ethernet/lantiq_xrx200.c | 21 ++++++++++++++++++---
- 2 files changed, 36 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -148,6 +148,9 @@ struct ltq_etop_priv {
- struct ltq_etop_chan txch;
- struct ltq_etop_chan rxch;
-
-+ int tx_burst_len;
-+ int rx_burst_len;
-+
- int tx_irq;
- int rx_irq;
-
-@@ -399,7 +402,7 @@ ltq_etop_dma_init(struct net_device *dev
- int rx = priv->rx_irq - LTQ_DMA_ETOP;
- int err;
-
-- ltq_dma_init_port(DMA_PORT_ETOP);
-+ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-
- priv->txch.dma.nr = tx;
- priv->txch.dma.dev = &priv->pdev->dev;
-@@ -676,8 +679,8 @@ ltq_etop_tx(struct sk_buff *skb, struct
- return NETDEV_TX_BUSY;
- }
-
-- /* dma needs to start on a 16 byte aligned address */
-- byte_offset = CPHYSADDR(skb->data) % 16;
-+ /* dma needs to start on a burst length value aligned address */
-+ byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4);
- priv->txch.skb[priv->txch.dma.desc] = skb;
-
- netif_trans_update(dev);
-@@ -925,6 +928,18 @@ static int ltq_etop_probe(struct platfor
- spin_lock_init(&priv->lock);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
-+ err = device_property_read_u32(&pdev->dev, "lantiq,tx-burst-length", &priv->tx_burst_len);
-+ if (err < 0) {
-+ dev_err(&pdev->dev, "unable to read tx-burst-length property\n");
-+ return err;
-+ }
-+
-+ err = device_property_read_u32(&pdev->dev, "lantiq,rx-burst-length", &priv->rx_burst_len);
-+ if (err < 0) {
-+ dev_err(&pdev->dev, "unable to read rx-burst-length property\n");
-+ return err;
-+ }
-+
- netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
- netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
- priv->txch.netdev = dev;
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -81,6 +81,9 @@ struct xrx200_priv {
- struct net_device *net_dev;
- struct device *dev;
-
-+ int tx_burst_len;
-+ int rx_burst_len;
-+
- __iomem void *pmac_reg;
- };
-
-@@ -363,8 +366,8 @@ static netdev_tx_t xrx200_start_xmit(str
- if (unlikely(dma_mapping_error(priv->dev, mapping)))
- goto err_drop;
-
-- /* dma needs to start on a 16 byte aligned address */
-- byte_offset = mapping % 16;
-+ /* dma needs to start on a burst length value aligned address */
-+ byte_offset = mapping % (priv->tx_burst_len * 4);
-
- desc->addr = mapping - byte_offset;
- /* Make sure the address is written before we give it to HW */
-@@ -465,7 +468,7 @@ static int xrx200_dma_init(struct xrx200
- int ret = 0;
- int i;
-
-- ltq_dma_init_port(DMA_PORT_ETOP);
-+ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-
- ch_rx->dma.nr = XRX200_DMA_RX;
- ch_rx->dma.dev = priv->dev;
-@@ -575,6 +578,18 @@ static int xrx200_probe(struct platform_
- if (err)
- eth_hw_addr_random(net_dev);
-
-+ err = device_property_read_u32(dev, "lantiq,tx-burst-length", &priv->tx_burst_len);
-+ if (err < 0) {
-+ dev_err(dev, "unable to read tx-burst-length property\n");
-+ return err;
-+ }
-+
-+ err = device_property_read_u32(dev, "lantiq,rx-burst-length", &priv->rx_burst_len);
-+ if (err < 0) {
-+ dev_err(dev, "unable to read rx-burst-length property\n");
-+ return err;
-+ }
-+
- /* bring up the dma engine and IP core */
- err = xrx200_dma_init(priv);
- if (err)
diff --git a/target/linux/lantiq/patches-5.15/0711-v5.16-net-lantiq_xrx200-Hardcode-the-burst-length-value.patch b/target/linux/lantiq/patches-5.15/0711-v5.16-net-lantiq_xrx200-Hardcode-the-burst-length-value.patch
deleted file mode 100644
index e002f81d5a..0000000000
--- a/target/linux/lantiq/patches-5.15/0711-v5.16-net-lantiq_xrx200-Hardcode-the-burst-length-value.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 7e553c44f09a8f536090904c6db5b8c9dbafa03b Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 26 Oct 2021 22:59:01 +0200
-Subject: [PATCH] net: lantiq_xrx200: Hardcode the burst length value
-
-All SoCs with this IP core support 8 burst length. Hauke
-suggested to hardcode this value and simplify the driver.
-
-Link: https://lkml.org/lkml/2021/9/14/1533
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 21 ++++-----------------
- 1 file changed, 4 insertions(+), 17 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -25,6 +25,7 @@
- #define XRX200_DMA_DATA_LEN (SZ_64K - 1)
- #define XRX200_DMA_RX 0
- #define XRX200_DMA_TX 1
-+#define XRX200_DMA_BURST_LEN 8
-
- #define XRX200_DMA_PACKET_COMPLETE 0
- #define XRX200_DMA_PACKET_IN_PROGRESS 1
-@@ -81,9 +82,6 @@ struct xrx200_priv {
- struct net_device *net_dev;
- struct device *dev;
-
-- int tx_burst_len;
-- int rx_burst_len;
--
- __iomem void *pmac_reg;
- };
-
-@@ -367,7 +365,7 @@ static netdev_tx_t xrx200_start_xmit(str
- goto err_drop;
-
- /* dma needs to start on a burst length value aligned address */
-- byte_offset = mapping % (priv->tx_burst_len * 4);
-+ byte_offset = mapping % (XRX200_DMA_BURST_LEN * 4);
-
- desc->addr = mapping - byte_offset;
- /* Make sure the address is written before we give it to HW */
-@@ -468,7 +466,8 @@ static int xrx200_dma_init(struct xrx200
- int ret = 0;
- int i;
-
-- ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-+ ltq_dma_init_port(DMA_PORT_ETOP, XRX200_DMA_BURST_LEN,
-+ XRX200_DMA_BURST_LEN);
-
- ch_rx->dma.nr = XRX200_DMA_RX;
- ch_rx->dma.dev = priv->dev;
-@@ -578,18 +577,6 @@ static int xrx200_probe(struct platform_
- if (err)
- eth_hw_addr_random(net_dev);
-
-- err = device_property_read_u32(dev, "lantiq,tx-burst-length", &priv->tx_burst_len);
-- if (err < 0) {
-- dev_err(dev, "unable to read tx-burst-length property\n");
-- return err;
-- }
--
-- err = device_property_read_u32(dev, "lantiq,rx-burst-length", &priv->rx_burst_len);
-- if (err < 0) {
-- dev_err(dev, "unable to read rx-burst-length property\n");
-- return err;
-- }
--
- /* bring up the dma engine and IP core */
- err = xrx200_dma_init(priv);
- if (err)
diff --git a/target/linux/lantiq/patches-5.15/0712-v5.16-net-ethernet-lantiq_etop-Fix-compilation-error.patch b/target/linux/lantiq/patches-5.15/0712-v5.16-net-ethernet-lantiq_etop-Fix-compilation-error.patch
deleted file mode 100644
index 06f4bc2eee..0000000000
--- a/target/linux/lantiq/patches-5.15/0712-v5.16-net-ethernet-lantiq_etop-Fix-compilation-error.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 68eabc348148ae051631e8dab13c3b1a85c82896 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 9 Nov 2021 23:23:54 +0100
-Subject: [PATCH] net: ethernet: lantiq_etop: Fix compilation error
-
-This fixes the error detected when compiling the driver.
-
-Fixes: 14d4e308e0aa ("net: lantiq: configure the burst length in ethernet drivers")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_etop.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -402,7 +402,7 @@ ltq_etop_dma_init(struct net_device *dev
- int rx = priv->rx_irq - LTQ_DMA_ETOP;
- int err;
-
-- ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-+ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len);
-
- priv->txch.dma.nr = tx;
- priv->txch.dma.dev = &priv->pdev->dev;
diff --git a/target/linux/lantiq/patches-5.15/0713-v5.17-MIPS-lantiq-dma-increase-descritor-count.patch b/target/linux/lantiq/patches-5.15/0713-v5.17-MIPS-lantiq-dma-increase-descritor-count.patch
deleted file mode 100644
index 37ed1d4f31..0000000000
--- a/target/linux/lantiq/patches-5.15/0713-v5.17-MIPS-lantiq-dma-increase-descritor-count.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 5112e9234bbb89f8dd15c983206bd9107b8436d5 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 4 Jan 2022 16:11:42 +0100
-Subject: [PATCH 713/715] MIPS: lantiq: dma: increase descritor count
-
-NAT Performance results on BT Home Hub 5A (kernel 5.10.89, mtu 1500):
-
- Down Up
-Before 539 Mbps 599 Mbps
-After 545 Mbps 625 Mbps
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- arch/mips/include/asm/mach-lantiq/xway/xway_dma.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-@@ -8,7 +8,7 @@
- #define LTQ_DMA_H__
-
- #define LTQ_DESC_SIZE 0x08 /* each descriptor is 64bit */
--#define LTQ_DESC_NUM 0x40 /* 64 descriptors / channel */
-+#define LTQ_DESC_NUM 0xC0 /* 192 descriptors / channel */
-
- #define LTQ_DMA_OWN BIT(31) /* owner bit */
- #define LTQ_DMA_C BIT(30) /* complete bit */
diff --git a/target/linux/lantiq/patches-5.15/0714-v5.17-net-lantiq_xrx200-increase-napi-poll-weigth.patch b/target/linux/lantiq/patches-5.15/0714-v5.17-net-lantiq_xrx200-increase-napi-poll-weigth.patch
deleted file mode 100644
index 10791f9d53..0000000000
--- a/target/linux/lantiq/patches-5.15/0714-v5.17-net-lantiq_xrx200-increase-napi-poll-weigth.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 768818d772d5d4ddc0c7eb2e62848929270ab7a3 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 4 Jan 2022 16:11:43 +0100
-Subject: [PATCH 714/715] net: lantiq_xrx200: increase napi poll weigth
-
-NAT Performance results on BT Home Hub 5A (kernel 5.10.89, mtu 1500):
-
- Down Up
-Before 545 Mbps 625 Mbps
-After 577 Mbps 648 Mbps
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -597,8 +597,10 @@ static int xrx200_probe(struct platform_
- PMAC_HD_CTL);
-
- /* setup NAPI */
-- netif_napi_add(net_dev, &priv->chan_rx.napi, xrx200_poll_rx, 32);
-- netif_tx_napi_add(net_dev, &priv->chan_tx.napi, xrx200_tx_housekeeping, 32);
-+ netif_napi_add(net_dev, &priv->chan_rx.napi, xrx200_poll_rx,
-+ NAPI_POLL_WEIGHT);
-+ netif_tx_napi_add(net_dev, &priv->chan_tx.napi, xrx200_tx_housekeeping,
-+ NAPI_POLL_WEIGHT);
-
- platform_set_drvdata(pdev, priv);
-
diff --git a/target/linux/lantiq/patches-5.15/0715-v5.17-net-lantiq_xrx200-convert-to-build_skb.patch b/target/linux/lantiq/patches-5.15/0715-v5.17-net-lantiq_xrx200-convert-to-build_skb.patch
deleted file mode 100644
index 6613d0bbd7..0000000000
--- a/target/linux/lantiq/patches-5.15/0715-v5.17-net-lantiq_xrx200-convert-to-build_skb.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From e015593573b3e3f74bd8a63c05fa92902194a354 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 4 Jan 2022 16:11:44 +0100
-Subject: [PATCH 715/715] net: lantiq_xrx200: convert to build_skb
-
-We can increase the efficiency of rx path by using buffers to receive
-packets then build SKBs around them just before passing into the network
-stack. In contrast, preallocating SKBs too early reduces CPU cache
-efficiency.
-
-NAT Performance results on BT Home Hub 5A (kernel 5.10.89, mtu 1500):
-
- Down Up
-Before 577 Mbps 648 Mbps
-After 624 Mbps 695 Mbps
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 56 ++++++++++++++++++----------
- 1 file changed, 36 insertions(+), 20 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -63,7 +63,11 @@ struct xrx200_chan {
-
- struct napi_struct napi;
- struct ltq_dma_channel dma;
-- struct sk_buff *skb[LTQ_DESC_NUM];
-+
-+ union {
-+ struct sk_buff *skb[LTQ_DESC_NUM];
-+ void *rx_buff[LTQ_DESC_NUM];
-+ };
-
- struct sk_buff *skb_head;
- struct sk_buff *skb_tail;
-@@ -78,6 +82,7 @@ struct xrx200_priv {
- struct xrx200_chan chan_rx;
-
- u16 rx_buf_size;
-+ u16 rx_skb_size;
-
- struct net_device *net_dev;
- struct device *dev;
-@@ -115,6 +120,12 @@ static int xrx200_buffer_size(int mtu)
- return round_up(xrx200_max_frame_len(mtu), 4 * XRX200_DMA_BURST_LEN);
- }
-
-+static int xrx200_skb_size(u16 buf_size)
-+{
-+ return SKB_DATA_ALIGN(buf_size + NET_SKB_PAD + NET_IP_ALIGN) +
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+}
-+
- /* drop all the packets from the DMA ring */
- static void xrx200_flush_dma(struct xrx200_chan *ch)
- {
-@@ -173,30 +184,29 @@ static int xrx200_close(struct net_devic
- return 0;
- }
-
--static int xrx200_alloc_skb(struct xrx200_chan *ch)
-+static int xrx200_alloc_buf(struct xrx200_chan *ch, void *(*alloc)(unsigned int size))
- {
-- struct sk_buff *skb = ch->skb[ch->dma.desc];
-+ void *buf = ch->rx_buff[ch->dma.desc];
- struct xrx200_priv *priv = ch->priv;
- dma_addr_t mapping;
- int ret = 0;
-
-- ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(priv->net_dev,
-- priv->rx_buf_size);
-- if (!ch->skb[ch->dma.desc]) {
-+ ch->rx_buff[ch->dma.desc] = alloc(priv->rx_skb_size);
-+ if (!ch->rx_buff[ch->dma.desc]) {
- ret = -ENOMEM;
- goto skip;
- }
-
-- mapping = dma_map_single(priv->dev, ch->skb[ch->dma.desc]->data,
-+ mapping = dma_map_single(priv->dev, ch->rx_buff[ch->dma.desc],
- priv->rx_buf_size, DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(priv->dev, mapping))) {
-- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
-- ch->skb[ch->dma.desc] = skb;
-+ skb_free_frag(ch->rx_buff[ch->dma.desc]);
-+ ch->rx_buff[ch->dma.desc] = buf;
- ret = -ENOMEM;
- goto skip;
- }
-
-- ch->dma.desc_base[ch->dma.desc].addr = mapping;
-+ ch->dma.desc_base[ch->dma.desc].addr = mapping + NET_SKB_PAD + NET_IP_ALIGN;
- /* Make sure the address is written before we give it to HW */
- wmb();
- skip:
-@@ -210,13 +220,14 @@ static int xrx200_hw_receive(struct xrx2
- {
- struct xrx200_priv *priv = ch->priv;
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-- struct sk_buff *skb = ch->skb[ch->dma.desc];
-+ void *buf = ch->rx_buff[ch->dma.desc];
- u32 ctl = desc->ctl;
- int len = (ctl & LTQ_DMA_SIZE_MASK);
- struct net_device *net_dev = priv->net_dev;
-+ struct sk_buff *skb;
- int ret;
-
-- ret = xrx200_alloc_skb(ch);
-+ ret = xrx200_alloc_buf(ch, napi_alloc_frag);
-
- ch->dma.desc++;
- ch->dma.desc %= LTQ_DESC_NUM;
-@@ -227,19 +238,21 @@ static int xrx200_hw_receive(struct xrx2
- return ret;
- }
-
-+ skb = build_skb(buf, priv->rx_skb_size);
-+ skb_reserve(skb, NET_SKB_PAD);
- skb_put(skb, len);
-
- /* add buffers to skb via skb->frag_list */
- if (ctl & LTQ_DMA_SOP) {
- ch->skb_head = skb;
- ch->skb_tail = skb;
-+ skb_reserve(skb, NET_IP_ALIGN);
- } else if (ch->skb_head) {
- if (ch->skb_head == ch->skb_tail)
- skb_shinfo(ch->skb_tail)->frag_list = skb;
- else
- ch->skb_tail->next = skb;
- ch->skb_tail = skb;
-- skb_reserve(ch->skb_tail, -NET_IP_ALIGN);
- ch->skb_head->len += skb->len;
- ch->skb_head->data_len += skb->len;
- ch->skb_head->truesize += skb->truesize;
-@@ -395,12 +408,13 @@ xrx200_change_mtu(struct net_device *net
- struct xrx200_chan *ch_rx = &priv->chan_rx;
- int old_mtu = net_dev->mtu;
- bool running = false;
-- struct sk_buff *skb;
-+ void *buff;
- int curr_desc;
- int ret = 0;
-
- net_dev->mtu = new_mtu;
- priv->rx_buf_size = xrx200_buffer_size(new_mtu);
-+ priv->rx_skb_size = xrx200_skb_size(priv->rx_buf_size);
-
- if (new_mtu <= old_mtu)
- return ret;
-@@ -416,14 +430,15 @@ xrx200_change_mtu(struct net_device *net
-
- for (ch_rx->dma.desc = 0; ch_rx->dma.desc < LTQ_DESC_NUM;
- ch_rx->dma.desc++) {
-- skb = ch_rx->skb[ch_rx->dma.desc];
-- ret = xrx200_alloc_skb(ch_rx);
-+ buff = ch_rx->rx_buff[ch_rx->dma.desc];
-+ ret = xrx200_alloc_buf(ch_rx, netdev_alloc_frag);
- if (ret) {
- net_dev->mtu = old_mtu;
- priv->rx_buf_size = xrx200_buffer_size(old_mtu);
-+ priv->rx_skb_size = xrx200_skb_size(priv->rx_buf_size);
- break;
- }
-- dev_kfree_skb_any(skb);
-+ skb_free_frag(buff);
- }
-
- ch_rx->dma.desc = curr_desc;
-@@ -476,7 +491,7 @@ static int xrx200_dma_init(struct xrx200
- ltq_dma_alloc_rx(&ch_rx->dma);
- for (ch_rx->dma.desc = 0; ch_rx->dma.desc < LTQ_DESC_NUM;
- ch_rx->dma.desc++) {
-- ret = xrx200_alloc_skb(ch_rx);
-+ ret = xrx200_alloc_buf(ch_rx, netdev_alloc_frag);
- if (ret)
- goto rx_free;
- }
-@@ -511,7 +526,7 @@ rx_ring_free:
- /* free the allocated RX ring */
- for (i = 0; i < LTQ_DESC_NUM; i++) {
- if (priv->chan_rx.skb[i])
-- dev_kfree_skb_any(priv->chan_rx.skb[i]);
-+ skb_free_frag(priv->chan_rx.rx_buff[i]);
- }
-
- rx_free:
-@@ -528,7 +543,7 @@ static void xrx200_hw_cleanup(struct xrx
-
- /* free the allocated RX ring */
- for (i = 0; i < LTQ_DESC_NUM; i++)
-- dev_kfree_skb_any(priv->chan_rx.skb[i]);
-+ skb_free_frag(priv->chan_rx.rx_buff[i]);
- }
-
- static int xrx200_probe(struct platform_device *pdev)
-@@ -553,6 +568,7 @@ static int xrx200_probe(struct platform_
- net_dev->min_mtu = ETH_ZLEN;
- net_dev->max_mtu = XRX200_DMA_DATA_LEN - xrx200_max_frame_len(0);
- priv->rx_buf_size = xrx200_buffer_size(ETH_DATA_LEN);
-+ priv->rx_skb_size = xrx200_skb_size(priv->rx_buf_size);
-
- /* load the memory ranges */
- priv->pmac_reg = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
diff --git a/target/linux/lantiq/patches-5.15/0716-v5.17-net-lantiq_xrx200-fix-use-after-free-bug.patch b/target/linux/lantiq/patches-5.15/0716-v5.17-net-lantiq_xrx200-fix-use-after-free-bug.patch
deleted file mode 100644
index 090b7e3111..0000000000
--- a/target/linux/lantiq/patches-5.15/0716-v5.17-net-lantiq_xrx200-fix-use-after-free-bug.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From dd830aed23c6e07cd8e2a163742bf3d63c9add08 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Sat, 5 Mar 2022 12:20:39 +0100
-Subject: net: lantiq_xrx200: fix use after free bug
-
-The skb->len field is read after the packet is sent to the network
-stack. In the meantime, skb can be freed. This patch fixes this bug.
-
-Fixes: c3e6b2c35b34 ("net: lantiq_xrx200: add ingress SG DMA support")
-Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -260,9 +260,9 @@ static int xrx200_hw_receive(struct xrx2
-
- if (ctl & LTQ_DMA_EOP) {
- ch->skb_head->protocol = eth_type_trans(ch->skb_head, net_dev);
-- netif_receive_skb(ch->skb_head);
- net_dev->stats.rx_packets++;
- net_dev->stats.rx_bytes += ch->skb_head->len;
-+ netif_receive_skb(ch->skb_head);
- ch->skb_head = NULL;
- ch->skb_tail = NULL;
- ret = XRX200_DMA_PACKET_COMPLETE;
diff --git a/target/linux/lantiq/patches-5.15/0717-v6.0-net-lantiq_xrx200-confirm-skb-is-allocated-before-us.patch b/target/linux/lantiq/patches-5.15/0717-v6.0-net-lantiq_xrx200-confirm-skb-is-allocated-before-us.patch
deleted file mode 100644
index 9eaec58033..0000000000
--- a/target/linux/lantiq/patches-5.15/0717-v6.0-net-lantiq_xrx200-confirm-skb-is-allocated-before-us.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c8b043702dc0894c07721c5b019096cebc8c798f Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 24 Aug 2022 23:54:06 +0200
-Subject: [PATCH] net: lantiq_xrx200: confirm skb is allocated before using
-
-xrx200_hw_receive() assumes build_skb() always works and goes straight
-to skb_reserve(). However, build_skb() can fail under memory pressure.
-
-Add a check in case build_skb() failed to allocate and return NULL.
-
-Fixes: e015593573b3 ("net: lantiq_xrx200: convert to build_skb")
-Reported-by: Eric Dumazet <edumazet@google.com>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -239,6 +239,12 @@ static int xrx200_hw_receive(struct xrx2
- }
-
- skb = build_skb(buf, priv->rx_skb_size);
-+ if (!skb) {
-+ skb_free_frag(buf);
-+ net_dev->stats.rx_dropped++;
-+ return -ENOMEM;
-+ }
-+
- skb_reserve(skb, NET_SKB_PAD);
- skb_put(skb, len);
-
diff --git a/target/linux/lantiq/patches-5.15/0718-v6.0-net-lantiq_xrx200-fix-lock-under-memory-pressure.patch b/target/linux/lantiq/patches-5.15/0718-v6.0-net-lantiq_xrx200-fix-lock-under-memory-pressure.patch
deleted file mode 100644
index 929ae57ace..0000000000
--- a/target/linux/lantiq/patches-5.15/0718-v6.0-net-lantiq_xrx200-fix-lock-under-memory-pressure.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c4b6e9341f930e4dd089231c0414758f5f1f9dbd Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 24 Aug 2022 23:54:07 +0200
-Subject: [PATCH] net: lantiq_xrx200: fix lock under memory pressure
-
-When the xrx200_hw_receive() function returns -ENOMEM, the NAPI poll
-function immediately returns an error.
-This is incorrect for two reasons:
-* the function terminates without enabling interrupts or scheduling NAPI,
-* the error code (-ENOMEM) is returned instead of the number of received
-packets.
-
-After the first memory allocation failure occurs, packet reception is
-locked due to disabled interrupts from DMA..
-
-Fixes: fe1a56420cf2 ("net: lantiq: Add Lantiq / Intel VRX200 Ethernet driver")
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -294,7 +294,7 @@ static int xrx200_poll_rx(struct napi_st
- if (ret == XRX200_DMA_PACKET_IN_PROGRESS)
- continue;
- if (ret != XRX200_DMA_PACKET_COMPLETE)
-- return ret;
-+ break;
- rx++;
- } else {
- break;
diff --git a/target/linux/lantiq/patches-5.15/0719-v6.0-net-lantiq_xrx200-restore-buffer-if-memory-allocatio.patch b/target/linux/lantiq/patches-5.15/0719-v6.0-net-lantiq_xrx200-restore-buffer-if-memory-allocatio.patch
deleted file mode 100644
index 182da58ed9..0000000000
--- a/target/linux/lantiq/patches-5.15/0719-v6.0-net-lantiq_xrx200-restore-buffer-if-memory-allocatio.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From c9c3b1775f80fa21f5bff874027d2ccb10f5d90c Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 24 Aug 2022 23:54:08 +0200
-Subject: [PATCH] net: lantiq_xrx200: restore buffer if memory allocation
- failed
-
-In a situation where memory allocation fails, an invalid buffer address
-is stored. When this descriptor is used again, the system panics in the
-build_skb() function when accessing memory.
-
-Fixes: 7ea6cd16f159 ("lantiq: net: fix duplicated skb in rx descriptor ring")
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -193,6 +193,7 @@ static int xrx200_alloc_buf(struct xrx20
-
- ch->rx_buff[ch->dma.desc] = alloc(priv->rx_skb_size);
- if (!ch->rx_buff[ch->dma.desc]) {
-+ ch->rx_buff[ch->dma.desc] = buf;
- ret = -ENOMEM;
- goto skip;
- }
diff --git a/target/linux/lantiq/patches-5.15/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch b/target/linux/lantiq/patches-5.15/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch
deleted file mode 100644
index c6befe05e5..0000000000
--- a/target/linux/lantiq/patches-5.15/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 82ea7c7fb4e90620beba8b6436fc12df2379ef8d Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:52:25 +0200
-Subject: [PATCH 731/768] dt-bindings: net: dsa: lantiq_gswip: Add missing
- phy-mode and fixed-link
-
-The CPU port has to specify a phy-mode and either a phy or a fixed-link.
-Since GSWIP is connected using a SoC internal protocol there's no PHY
-involved. Add phy-mode = "internal" and a fixed-link to describe the
-communication between the PMAC (Ethernet controller) and GSWIP switch.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-@@ -97,7 +97,13 @@ switch@e108000 {
- port@6 {
- reg = <0x6>;
- label = "cpu";
-+ phy-mode = "internal";
- ethernet = <&eth0>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
- };
-
diff --git a/target/linux/lantiq/patches-5.15/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch b/target/linux/lantiq/patches-5.15/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch
deleted file mode 100644
index cc94a41cf3..0000000000
--- a/target/linux/lantiq/patches-5.15/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From a55b9d802e11baceb35bd312419ad82086065b08 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:59:35 +0200
-Subject: [PATCH 732/768] net: dsa: lantiq_gswip: Only allow phy-mode =
- "internal" on the CPU port
-
-Add the CPU port to gswip_xrx200_phylink_get_caps() and
-gswip_xrx300_phylink_get_caps(). It connects through a SoC-internal bus,
-so the only allowed phy-mode is PHY_INTERFACE_MODE_INTERNAL.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1513,6 +1513,7 @@ static void gswip_xrx200_phylink_validat
- case 2:
- case 3:
- case 4:
-+ case 6:
- if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
- goto unsupported;
- break;
-@@ -1552,6 +1553,7 @@ static void gswip_xrx300_phylink_validat
- case 2:
- case 3:
- case 4:
-+ case 6:
- if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
- goto unsupported;
- break;
diff --git a/target/linux/lantiq/patches-5.15/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch b/target/linux/lantiq/patches-5.15/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
deleted file mode 100644
index b1658e15d8..0000000000
--- a/target/linux/lantiq/patches-5.15/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 4d3dd68a1c56674ff666d0622b545992fac31754 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Sun, 31 Jul 2022 22:54:52 +0200
-Subject: [PATCH 733/768] net: dsa: lantiq_gswip: Use dev_err_probe where
- appropriate
-
-dev_err_probe() can be used to simplify the existing code. Also it means
-we get rid of the following warning which is seen whenever the PMAC
-(Ethernet controller which connects to GSWIP's CPU port) has not been
-probed yet:
- gswip 1e108000.switch: dsa switch register failed: -517
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++------------------
- 1 file changed, 25 insertions(+), 28 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1939,11 +1939,9 @@ static int gswip_gphy_fw_load(struct gsw
- msleep(200);
-
- ret = request_firmware(&fw, gphy_fw->fw_name, dev);
-- if (ret) {
-- dev_err(dev, "failed to load firmware: %s, error: %i\n",
-- gphy_fw->fw_name, ret);
-- return ret;
-- }
-+ if (ret)
-+ return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
-+ gphy_fw->fw_name);
-
- /* GPHY cores need the firmware code in a persistent and contiguous
- * memory area with a 16 kB boundary aligned start address.
-@@ -1956,9 +1954,9 @@ static int gswip_gphy_fw_load(struct gsw
- dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
- memcpy(fw_addr, fw->data, fw->size);
- } else {
-- dev_err(dev, "failed to alloc firmware memory\n");
- release_firmware(fw);
-- return -ENOMEM;
-+ return dev_err_probe(dev, -ENOMEM,
-+ "failed to alloc firmware memory\n");
- }
-
- release_firmware(fw);
-@@ -1985,8 +1983,8 @@ static int gswip_gphy_fw_probe(struct gs
-
- gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
- if (IS_ERR(gphy_fw->clk_gate)) {
-- dev_err(dev, "Failed to lookup gate clock\n");
-- return PTR_ERR(gphy_fw->clk_gate);
-+ return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
-+ "Failed to lookup gate clock\n");
- }
-
- ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
-@@ -2006,8 +2004,8 @@ static int gswip_gphy_fw_probe(struct gs
- gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
- break;
- default:
-- dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
-- return -EINVAL;
-+ return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
-+ gphy_mode);
- }
-
- gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
-@@ -2060,8 +2058,9 @@ static int gswip_gphy_fw_list(struct gsw
- priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x",
-+ version);
- }
- }
-
-@@ -2069,10 +2068,9 @@ static int gswip_gphy_fw_list(struct gsw
- if (match && match->data)
- priv->gphy_fw_name_cfg = match->data;
-
-- if (!priv->gphy_fw_name_cfg) {
-- dev_err(dev, "GPHY compatible type not supported");
-- return -ENOENT;
-- }
-+ if (!priv->gphy_fw_name_cfg)
-+ return dev_err_probe(dev, -ENOENT,
-+ "GPHY compatible type not supported");
-
- priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
- if (!priv->num_gphy_fw)
-@@ -2171,8 +2169,8 @@ static int gswip_probe(struct platform_d
- return -EINVAL;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x", version);
- }
-
- /* bring up the mdio bus */
-@@ -2180,10 +2178,9 @@ static int gswip_probe(struct platform_d
- if (gphy_fw_np) {
- err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
- of_node_put(gphy_fw_np);
-- if (err) {
-- dev_err(dev, "gphy fw probe failed\n");
-- return err;
-- }
-+ if (err)
-+ return dev_err_probe(dev, err,
-+ "gphy fw probe failed\n");
- }
-
- /* bring up the mdio bus */
-@@ -2191,20 +2188,20 @@ static int gswip_probe(struct platform_d
- if (mdio_np) {
- err = gswip_mdio(priv, mdio_np);
- if (err) {
-- dev_err(dev, "mdio probe failed\n");
-+ dev_err_probe(dev, err, "mdio probe failed\n");
- goto put_mdio_node;
- }
- }
-
- err = dsa_register_switch(priv->ds);
- if (err) {
-- dev_err(dev, "dsa switch register failed: %i\n", err);
-+ dev_err_probe(dev, err, "dsa switch registration failed\n");
- goto mdio_bus;
- }
- if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
-- dev_err(dev, "wrong CPU port defined, HW only supports port: %i",
-- priv->hw_info->cpu_port);
-- err = -EINVAL;
-+ err = dev_err_probe(dev, -EINVAL,
-+ "wrong CPU port defined, HW only supports port: %i",
-+ priv->hw_info->cpu_port);
- goto disable_switch;
- }
-
diff --git a/target/linux/lantiq/patches-5.15/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch b/target/linux/lantiq/patches-5.15/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
deleted file mode 100644
index 1493826c53..0000000000
--- a/target/linux/lantiq/patches-5.15/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 8cf0b680abc157adeec3fb93a10354c470694535 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Thu, 28 Jul 2022 22:37:11 +0200
-Subject: [PATCH 734/768] net: dsa: lantiq_gswip: Don't manually call
- gswip_port_enable()
-
-We don't need to manually call gswip_port_enable() from within
-gswip_setup() for the CPU port. DSA does this automatically for us.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -874,8 +874,6 @@ static int gswip_setup(struct dsa_switch
-
- ds->mtu_enforcement_ingress = true;
-
-- gswip_port_enable(ds, cpu_port, NULL);
--
- ds->configure_vlan_while_not_filtering = false;
-
- return 0;
diff --git a/target/linux/lantiq/patches-5.15/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch b/target/linux/lantiq/patches-5.15/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
deleted file mode 100644
index 2d95b37358..0000000000
--- a/target/linux/lantiq/patches-5.15/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 54a2f7f2c134738bd3f4ea0a213138d169f2726e Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Fri, 10 May 2024 13:52:10 +0200
-Subject: [PATCH] net: dsa: lantiq_gswip: do also enable or disable cpu port
-
-Before commit 74be4babe72f ("net: dsa: do not enable or disable non user
-ports"), gswip_port_enable/disable() were also executed for the cpu port
-in gswip_setup() which disabled the cpu port during initialization.
-
-Let's restore this by removing the dsa_is_user_port checks. Also, let's
-clean up the gswip_port_enable() function so that we only have to check
-for the cpu port once.
-
-Fixes: 74be4babe72f ("net: dsa: do not enable or disable non user ports")
-Signed-off-by: Martin Schiller <ms@dev.tdt.de>
----
- drivers/net/dsa/lantiq_gswip.c | 24 ++++++++----------------
- 1 file changed, 8 insertions(+), 16 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -671,13 +671,18 @@ static int gswip_port_enable(struct dsa_
- struct gswip_priv *priv = ds->priv;
- int err;
-
-- if (!dsa_is_user_port(ds, port))
-- return 0;
--
- if (!dsa_is_cpu_port(ds, port)) {
-+ u32 mdio_phy = 0;
-+
- err = gswip_add_single_port_br(priv, port, true);
- if (err)
- return err;
-+
-+ if (phydev)
-+ mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
-+
-+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-+ GSWIP_MDIO_PHYp(port));
- }
-
- /* RMON Counter Enable for port */
-@@ -690,16 +695,6 @@ static int gswip_port_enable(struct dsa_
- gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
- GSWIP_SDMA_PCTRLp(port));
-
-- if (!dsa_is_cpu_port(ds, port)) {
-- u32 mdio_phy = 0;
--
-- if (phydev)
-- mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
--
-- gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-- GSWIP_MDIO_PHYp(port));
-- }
--
- return 0;
- }
-
-@@ -707,9 +702,6 @@ static void gswip_port_disable(struct ds
- {
- 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,
diff --git a/target/linux/lantiq/patches-5.15/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch b/target/linux/lantiq/patches-5.15/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
deleted file mode 100644
index 26f7c0f414..0000000000
--- a/target/linux/lantiq/patches-5.15/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8ab55ac9678ca1f50f786c84484599dd675c5a9f Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Wed, 18 May 2022 23:53:09 +0200
-Subject: [PATCH 736/768] net: dsa: lantiq_gswip: Use dsa_is_cpu_port() in
- gswip_port_change_mtu()
-
-Make the check for the CPU port in gswip_port_change_mtu() consistent
-with other areas of the driver by using dsa_is_cpu_port().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1463,12 +1463,11 @@ static int gswip_port_max_mtu(struct dsa
- static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct gswip_priv *priv = ds->priv;
-- int cpu_port = priv->hw_info->cpu_port;
-
- /* CPU port always has maximum mtu of user ports, so use it to set
- * switch frame size, including 8 byte special header.
- */
-- if (port == cpu_port) {
-+ if (dsa_is_cpu_port(ds, port)) {
- new_mtu += 8;
- gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
- GSWIP_MAC_FLEN);
diff --git a/target/linux/lantiq/patches-5.15/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch b/target/linux/lantiq/patches-5.15/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
deleted file mode 100644
index 0a17d14759..0000000000
--- a/target/linux/lantiq/patches-5.15/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From ef98b183d8fc7187a2efcc21c8f54f3cf061d556 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Tue, 17 May 2022 22:39:58 +0200
-Subject: [PATCH 737/768] net: dsa: lantiq_gswip: Change literal 6 to ETH_ALEN
-
-The addr variable in gswip_port_fdb_dump() stores a mac address. Use
-ETH_ALEN to make this consistent across other drivers.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1383,7 +1383,7 @@ static int gswip_port_fdb_dump(struct ds
- {
- struct gswip_priv *priv = ds->priv;
- struct gswip_pce_table_entry mac_bridge = {0,};
-- unsigned char addr[6];
-+ unsigned char addr[ETH_ALEN];
- int i;
- int err;
-
diff --git a/target/linux/lantiq/patches-5.15/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch b/target/linux/lantiq/patches-5.15/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
deleted file mode 100644
index 87382876c2..0000000000
--- a/target/linux/lantiq/patches-5.15/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 61e9b19f6e6174afa7540f0b468a69bc940b91d4 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 21:23:49 +0200
-Subject: [PATCH 738/768] net: dsa: lantiq_gswip: Consistently use macros for
- the mac bridge table
-
-Introduce a new GSWIP_TABLE_MAC_BRIDGE_PORT macro and use it throughout
-the driver. Also update GSWIP_TABLE_MAC_BRIDGE_STATIC to use the BIT()
-macro. This makes the driver code easier to understand.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -236,7 +236,8 @@
- #define GSWIP_TABLE_ACTIVE_VLAN 0x01
- #define GSWIP_TABLE_VLAN_MAPPING 0x02
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
--#define GSWIP_TABLE_MAC_BRIDGE_STATIC 0x01 /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1279,7 +1280,8 @@ static void gswip_port_fast_age(struct d
- if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC)
- continue;
-
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port)
-+ if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0]))
- continue;
-
- mac_bridge.valid = false;
-@@ -1414,7 +1416,8 @@ static int gswip_port_fdb_dump(struct ds
- return err;
- }
- } else {
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) {
-+ if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0])) {
- err = cb(addr, 0, false, data);
- if (err)
- return err;
diff --git a/target/linux/lantiq/patches-5.15/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch b/target/linux/lantiq/patches-5.15/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch
deleted file mode 100644
index aafea1ec2e..0000000000
--- a/target/linux/lantiq/patches-5.15/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 7a9e185075ababa827d1d3a33b787ad6d718c8ec Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:24:24 +0200
-Subject: [PATCH 739/768] net: dsa: lantiq_gswip: Forbid
- gswip_add_single_port_br on the CPU port
-
-Calling gswip_add_single_port_br() with the CPU port would be a bug
-because then only the CPU port could talk to itself. Add the CPU port to
-the validation at the beginning of gswip_add_single_port_br().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -633,7 +633,7 @@ static int gswip_add_single_port_br(stru
- unsigned int max_ports = priv->hw_info->max_ports;
- int err;
-
-- if (port >= max_ports) {
-+ if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
- dev_err(priv->dev, "single port for %i supported\n", port);
- return -EIO;
- }
diff --git a/target/linux/lantiq/patches-5.15/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch b/target/linux/lantiq/patches-5.15/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch
deleted file mode 100644
index ef8302fe80..0000000000
--- a/target/linux/lantiq/patches-5.15/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 28be6bfb735d851e646abb05b8e24eb6764596f5 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:26:20 +0200
-Subject: [PATCH 740/768] net: dsa: lantiq_gswip: Fix error message in
- gswip_add_single_port_br()
-
-The error message is printed when the port cannot be used. Update the
-error message to reflect that.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -634,7 +634,8 @@ static int gswip_add_single_port_br(stru
- int err;
-
- if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
-- dev_err(priv->dev, "single port for %i supported\n", port);
-+ dev_err(priv->dev, "single port for %i is not supported\n",
-+ port);
- return -EIO;
- }
-
diff --git a/target/linux/lantiq/patches-5.15/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch b/target/linux/lantiq/patches-5.15/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch
deleted file mode 100644
index 6eeed5b27a..0000000000
--- a/target/linux/lantiq/patches-5.15/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 45a0371568b1f050d787564875653f41a1f6fb98 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:06:40 +0200
-Subject: [PATCH 741/768] net: dsa: lantiq_gswip: Fix comments in
- gswip_port_vlan_filtering()
-
-Update the comments in gswip_port_vlan_filtering() so it's clear that
-there are two separate cases, one for "tag based VLAN" and another one
-for "port based VLAN".
-
-Suggested-by: Martin Schiller <ms@dev.tdt.de>
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -762,7 +762,7 @@ static int gswip_port_vlan_filtering(str
- }
-
- if (vlan_filtering) {
-- /* Use port based VLAN tag */
-+ /* Use tag based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_VSR,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
-@@ -771,7 +771,7 @@ static int gswip_port_vlan_filtering(str
- gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0,
- GSWIP_PCE_PCTRL_0p(port));
- } else {
-- /* Use port based VLAN tag */
-+ /* Use port based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
- GSWIP_PCE_VCTRL_VEMR,
diff --git a/target/linux/lantiq/patches-5.15/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch b/target/linux/lantiq/patches-5.15/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch
deleted file mode 100644
index b9912e8735..0000000000
--- a/target/linux/lantiq/patches-5.15/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 4775f9543e691d9a2f5dd9aa5d46c66d37928250 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:19:05 +0200
-Subject: [PATCH 742/768] net: dsa: lantiq_gswip: Add and use a
- GSWIP_TABLE_MAC_BRIDGE_FID macro
-
-Only bits [5:0] in mac_bridge.key[3] are reserved for the FID. Add a
-macro so this becomes obvious when reading the driver code.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -238,6 +238,7 @@
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
- #define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
- #define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-+#define GSWIP_TABLE_MAC_BRIDGE_FID GENMASK(5, 0) /* Filtering identifier */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1357,7 +1358,7 @@ static int gswip_port_fdb(struct dsa_swi
- mac_bridge.key[0] = addr[5] | (addr[4] << 8);
- mac_bridge.key[1] = addr[3] | (addr[2] << 8);
- mac_bridge.key[2] = addr[1] | (addr[0] << 8);
-- mac_bridge.key[3] = fid;
-+ mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_FID, fid);
- mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */
- mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_STATIC;
- mac_bridge.valid = add;
diff --git a/target/linux/lantiq/patches-5.15/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch b/target/linux/lantiq/patches-5.15/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
deleted file mode 100644
index 2538a4c856..0000000000
--- a/target/linux/lantiq/patches-5.15/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 00b5121435ccd4ce54f79179dd9ee3e2610d7dcf Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 16:31:57 +0200
-Subject: [PATCH 743/768] net: dsa: lantiq_gswip: Improve error message in
- gswip_port_fdb()
-
-Print the port which is not found to be part of a bridge so it's easier
-to investigate the underlying issue.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1349,7 +1349,8 @@ static int gswip_port_fdb(struct dsa_swi
- }
-
- if (fid == -1) {
-- dev_err(priv->dev, "Port not part of a bridge\n");
-+ dev_err(priv->dev,
-+ "Port %d is not known to be part of bridge\n", port);
- return -EINVAL;
- }
-
diff --git a/target/linux/lantiq/patches-6.1/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-6.1/0001-MIPS-lantiq-add-pcie-driver.patch
deleted file mode 100644
index b8f3116bb4..0000000000
--- a/target/linux/lantiq/patches-6.1/0001-MIPS-lantiq-add-pcie-driver.patch
+++ /dev/null
@@ -1,5550 +0,0 @@
-From 6f933347d0b4ed02d9534f5fa07f7b99f13eeaa1 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:12:28 +0200
-Subject: [PATCH 01/36] MIPS: lantiq: add pcie driver
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/lantiq/Kconfig | 10 +
- arch/mips/lantiq/xway/sysctrl.c | 2 +
- arch/mips/pci/Makefile | 2 +
- arch/mips/pci/fixup-lantiq-pcie.c | 82 +++
- arch/mips/pci/fixup-lantiq.c | 5 +-
- arch/mips/pci/ifxmips_pci_common.h | 57 ++
- arch/mips/pci/ifxmips_pcie.c | 1099 ++++++++++++++++++++++++++++++
- arch/mips/pci/ifxmips_pcie.h | 135 ++++
- arch/mips/pci/ifxmips_pcie_ar10.h | 290 ++++++++
- arch/mips/pci/ifxmips_pcie_msi.c | 392 +++++++++++
- arch/mips/pci/ifxmips_pcie_phy.c | 478 +++++++++++++
- arch/mips/pci/ifxmips_pcie_pm.c | 176 +++++
- arch/mips/pci/ifxmips_pcie_pm.h | 36 +
- arch/mips/pci/ifxmips_pcie_reg.h | 1001 +++++++++++++++++++++++++++
- arch/mips/pci/ifxmips_pcie_vr9.h | 271 ++++++++
- arch/mips/pci/pci.c | 25 +
- arch/mips/pci/pcie-lantiq.h | 1305 ++++++++++++++++++++++++++++++++++++
- drivers/pci/pcie/aer/Kconfig | 2 +-
- include/linux/pci.h | 2 +
- include/linux/pci_ids.h | 6 +
- 20 files changed, 5374 insertions(+), 2 deletions(-)
- create mode 100644 arch/mips/pci/fixup-lantiq-pcie.c
- create mode 100644 arch/mips/pci/ifxmips_pci_common.h
- create mode 100644 arch/mips/pci/ifxmips_pcie.c
- create mode 100644 arch/mips/pci/ifxmips_pcie.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_ar10.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_msi.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_phy.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_pm.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_pm.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_reg.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_vr9.h
- create mode 100644 arch/mips/pci/pcie-lantiq.h
-
---- a/arch/mips/lantiq/Kconfig
-+++ b/arch/mips/lantiq/Kconfig
-@@ -20,6 +20,7 @@ config SOC_XWAY
- bool "XWAY"
- select SOC_TYPE_XWAY
- select HAVE_PCI
-+ select ARCH_SUPPORTS_MSI
- select MFD_SYSCON
- select MFD_CORE
-
-@@ -52,4 +53,13 @@ config PCI_LANTIQ
- bool "PCI Support"
- depends on SOC_XWAY && PCI
-
-+config PCIE_LANTIQ
-+ bool "PCIE Support"
-+ depends on SOC_XWAY && PCI
-+
-+config PCIE_LANTIQ_MSI
-+ bool
-+ depends on PCIE_LANTIQ && PCI_MSI
-+ default y
-+
- endif
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -41,6 +41,8 @@ obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o
- obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
- obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
- obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
-+obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
-+obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
- obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o
- obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o
- obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o
---- /dev/null
-+++ b/arch/mips/pci/fixup-lantiq-pcie.c
-@@ -0,0 +1,74 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_fixup_pcie.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_fixup_pcie.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe Fixup functions source file
-+*/
-+#include <linux/pci.h>
-+#include <linux/pci_regs.h>
-+#include <linux/pci_ids.h>
-+
-+#include <lantiq_soc.h>
-+
-+#include "pcie-lantiq.h"
-+
-+static void
-+ifx_pcie_fixup_resource(struct pci_dev *dev)
-+{
-+ u32 reg;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
-+
-+ printk("%s: fixup host controller %s (%04x:%04x)\n",
-+ __func__, pci_name(dev), dev->vendor, dev->device);
-+
-+ /* Setup COMMAND register */
-+ reg = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER /* |
-+ PCI_COMMAND_INTX_DISABLE */| PCI_COMMAND_SERR;
-+ pci_write_config_word(dev, PCI_COMMAND, reg);
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
-+}
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE, ifx_pcie_fixup_resource);
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_VENDOR_ID_LANTIQ, ifx_pcie_fixup_resource);
-+
-+static void
-+ifx_pcie_rc_class_early_fixup(struct pci_dev *dev)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
-+
-+ if (dev->devfn == PCI_DEVFN(0, 0) &&
-+ (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
-+
-+ dev->class = (PCI_CLASS_BRIDGE_PCI << 8) | (dev->class & 0xff);
-+
-+ printk(KERN_INFO "%s: fixed pcie host bridge to pci-pci bridge\n", __func__);
-+ }
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
-+ mdelay(10);
-+}
-+
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE,
-+ ifx_pcie_rc_class_early_fixup);
-+
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_DEVICE_ID_LANTIQ_PCIE,
-+ ifx_pcie_rc_class_early_fixup);
---- a/arch/mips/pci/fixup-lantiq.c
-+++ b/arch/mips/pci/fixup-lantiq.c
-@@ -6,12 +6,19 @@
-
- #include <linux/of_irq.h>
- #include <linux/of_pci.h>
-+#include <linux/pci.h>
-+#include "ifxmips_pci_common.h"
-
- int (*ltq_pci_plat_arch_init)(struct pci_dev *dev) = NULL;
- int (*ltq_pci_plat_dev_init)(struct pci_dev *dev) = NULL;
-
- int pcibios_plat_dev_init(struct pci_dev *dev)
- {
-+#ifdef CONFIG_PCIE_LANTIQ
-+ if (pci_find_capability(dev, PCI_CAP_ID_EXP))
-+ ifx_pcie_bios_plat_dev_init(dev);
-+#endif
-+
- if (ltq_pci_plat_arch_init)
- return ltq_pci_plat_arch_init(dev);
-
-@@ -23,5 +30,10 @@ int pcibios_plat_dev_init(struct pci_dev
-
- int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
- {
-+#ifdef CONFIG_PCIE_LANTIQ
-+ if (pci_find_capability((struct pci_dev *)dev, PCI_CAP_ID_EXP))
-+ return ifx_pcie_bios_map_irq(dev, slot, pin);
-+#endif
-+
- return of_irq_parse_and_map_pci(dev, slot, pin);
- }
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pci_common.h
-@@ -0,0 +1,53 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pci_common.h
-+** PROJECT : IFX UEIP
-+** MODULES : PCI subsystem
-+**
-+** DATE : 30 June 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 30 June,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+
-+#ifndef IFXMIPS_PCI_COMMON_H
-+#define IFXMIPS_PCI_COMMON_H
-+#include <linux/version.h>
-+/*!
-+ \defgroup IFX_PCI_COM IFX PCI/PCIe common parts for OS integration
-+ \brief PCI/PCIe common parts
-+*/
-+
-+/*!
-+ \defgroup IFX_PCI_COM_OS OS APIs
-+ \ingroup IFX_PCI_COM
-+ \brief PCI/PCIe bus driver OS interface functions
-+*/
-+/*!
-+ \file ifxmips_pci_common.h
-+ \ingroup IFX_PCI_COM
-+ \brief PCI/PCIe bus driver common OS header file
-+*/
-+#define IFX_PCI_CONST const
-+#ifdef CONFIG_IFX_PCI
-+extern int ifx_pci_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
-+extern int ifx_pci_bios_plat_dev_init(struct pci_dev *dev);
-+#endif /* COFNIG_IFX_PCI */
-+
-+#ifdef CONFIG_PCIE_LANTIQ
-+extern int ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
-+extern int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev);
-+#endif
-+
-+#endif /* IFXMIPS_PCI_COMMON_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie.c
-@@ -0,0 +1,1091 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ * Copyright (C) 2009 Lei Chuanhua <chuanhua.lei@infineon.com>
-+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/mm.h>
-+#include <asm/paccess.h>
-+#include <linux/pci.h>
-+#include <linux/pci_regs.h>
-+#include <linux/module.h>
-+
-+#include "ifxmips_pcie.h"
-+#include "ifxmips_pcie_reg.h"
-+
-+/* Enable 32bit io due to its mem mapped io nature */
-+#define IFX_PCIE_ERROR_INT
-+#define IFX_PCIE_IO_32BIT
-+
-+#define IFX_PCIE_IR (INT_NUM_IM4_IRL0 + 25)
-+#define IFX_PCIE_INTA (INT_NUM_IM4_IRL0 + 8)
-+#define IFX_PCIE_INTB (INT_NUM_IM4_IRL0 + 9)
-+#define IFX_PCIE_INTC (INT_NUM_IM4_IRL0 + 10)
-+#define IFX_PCIE_INTD (INT_NUM_IM4_IRL0 + 11)
-+#define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
-+#define SM(_v, _f) (((_v) << _f##_S) & (_f))
-+#define IFX_REG_SET_BIT(_f, _r) \
-+ IFX_REG_W32((IFX_REG_R32((_r)) &~ (_f)) | (_f), (_r))
-+
-+#define IFX_PCIE_LTSSM_ENABLE_TIMEOUT 10
-+
-+static DEFINE_SPINLOCK(ifx_pcie_lock);
-+
-+u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
-+
-+static ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
-+ {
-+ .ir_irq = {
-+ .irq = IFX_PCIE_IR,
-+ .name = "ifx_pcie_rc0",
-+ },
-+
-+ .legacy_irq = {
-+ {
-+ .irq_bit = PCIE_IRN_INTA,
-+ .irq = IFX_PCIE_INTA,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTB,
-+ .irq = IFX_PCIE_INTB,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTC,
-+ .irq = IFX_PCIE_INTC,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTD,
-+ .irq = IFX_PCIE_INTD,
-+ },
-+ },
-+ },
-+
-+};
-+
-+void ifx_pcie_debug(const char *fmt, ...)
-+{
-+ static char buf[256] = {0}; /* XXX */
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ vsnprintf(buf, sizeof(buf), fmt, ap);
-+ va_end(ap);
-+
-+ printk("%s", buf);
-+}
-+
-+
-+static inline int pcie_ltssm_enable(int pcie_port)
-+{
-+ int i;
-+
-+ /* Enable LTSSM */
-+ IFX_REG_W32(PCIE_RC_CCR_LTSSM_ENABLE, PCIE_RC_CCR(pcie_port));
-+
-+ /* Wait for the link to come up */
-+ for (i = 0; i < IFX_PCIE_LTSSM_ENABLE_TIMEOUT; i++) {
-+ if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_RETRAIN_PENDING))
-+ return 0;
-+ udelay(10);
-+ }
-+
-+ printk("%s link timeout!!!!!\n", __func__);
-+ return -1;
-+}
-+
-+static inline void pcie_status_register_clear(int pcie_port)
-+{
-+ IFX_REG_W32(0, PCIE_RC_DR(pcie_port));
-+ IFX_REG_W32(0, PCIE_PCICMDSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_DCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_LCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_SLCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_RSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_UES_R(pcie_port));
-+ IFX_REG_W32(0, PCIE_UEMR(pcie_port));
-+ IFX_REG_W32(0, PCIE_UESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_CESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_CEMR(pcie_port));
-+ IFX_REG_W32(0, PCIE_RESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_PVCCRSR(pcie_port));
-+ IFX_REG_W32(0, PCIE_VC0_RSR0(pcie_port));
-+ IFX_REG_W32(0, PCIE_TPFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_TNPFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_TCFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_QSR(pcie_port));
-+ IFX_REG_W32(0, PCIE_IOBLSECS(pcie_port));
-+}
-+
-+static inline int ifx_pcie_link_up(int pcie_port)
-+{
-+ return (IFX_REG_R32(PCIE_PHY_SR(pcie_port)) & PCIE_PHY_SR_PHY_LINK_UP) ? 1 : 0;
-+}
-+
-+
-+static inline void pcie_mem_io_setup(int pcie_port)
-+{
-+ u32 reg;
-+ /*
-+ * BAR[0:1] readonly register
-+ * RC contains only minimal BARs for packets mapped to this device
-+ * Mem/IO filters defines a range of memory occupied by memory mapped IO devices that
-+ * reside on the downstream side fo the bridge.
-+ */
-+ reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_MBML_MEM_LIMIT_ADDR)
-+ | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_MBML_MEM_BASE_ADDR);
-+
-+ IFX_REG_W32(reg, PCIE_MBML(pcie_port));
-+
-+
-+#ifdef IFX_PCIE_PREFETCH_MEM_64BIT
-+ reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_PMBL_END_ADDR)
-+ | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_PMBL_UPPER_12BIT)
-+ | PCIE_PMBL_64BIT_ADDR;
-+ IFX_REG_W32(reg, PCIE_PMBL(pcie_port));
-+
-+ /* Must configure upper 32bit */
-+ IFX_REG_W32(0, PCIE_PMBU32(pcie_port));
-+ IFX_REG_W32(0, PCIE_PMLU32(pcie_port));
-+#else
-+ /* PCIe_PBML, same as MBML */
-+ IFX_REG_W32(IFX_REG_R32(PCIE_MBML(pcie_port)), PCIE_PMBL(pcie_port));
-+#endif
-+
-+ /* IO Address Range */
-+ reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 12), PCIE_IOBLSECS_IO_LIMIT_ADDR)
-+ | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 12), PCIE_IOBLSECS_IO_BASE_ADDR);
-+#ifdef IFX_PCIE_IO_32BIT
-+ reg |= PCIE_IOBLSECS_32BIT_IO_ADDR;
-+#endif /* IFX_PCIE_IO_32BIT */
-+ IFX_REG_W32(reg, PCIE_IOBLSECS(pcie_port));
-+
-+#ifdef IFX_PCIE_IO_32BIT
-+ reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT)
-+ | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_BASE);
-+ IFX_REG_W32(reg, PCIE_IO_BANDL(pcie_port));
-+
-+#endif /* IFX_PCIE_IO_32BIT */
-+}
-+
-+static inline void
-+pcie_device_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Device capability register, set up Maximum payload size */
-+ reg = IFX_REG_R32(PCIE_DCAP(pcie_port));
-+ reg |= PCIE_DCAP_ROLE_BASE_ERR_REPORT;
-+ reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCAP_MAX_PAYLOAD_SIZE);
-+
-+ /* Only available for EP */
-+ reg &= ~(PCIE_DCAP_EP_L0S_LATENCY | PCIE_DCAP_EP_L1_LATENCY);
-+ IFX_REG_W32(reg, PCIE_DCAP(pcie_port));
-+
-+ /* Device control and status register */
-+ /* Set Maximum Read Request size for the device as a Requestor */
-+ reg = IFX_REG_R32(PCIE_DCTLSTS(pcie_port));
-+
-+ /*
-+ * Request size can be larger than the MPS used, but the completions returned
-+ * for the read will be bounded by the MPS size.
-+ * In our system, Max request size depends on AHB burst size. It is 64 bytes.
-+ * but we set it as 128 as minimum one.
-+ */
-+ reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_READ_SIZE)
-+ | SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_PAYLOAD_SIZE);
-+
-+ /* Enable relaxed ordering, no snoop, and all kinds of errors */
-+ reg |= PCIE_DCTLSTS_RELAXED_ORDERING_EN | PCIE_DCTLSTS_ERR_EN | PCIE_DCTLSTS_NO_SNOOP_EN;
-+
-+ IFX_REG_W32(reg, PCIE_DCTLSTS(pcie_port));
-+}
-+
-+static inline void
-+pcie_link_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /*
-+ * XXX, Link capability register, bit 18 for EP CLKREQ# dynamic clock management for L1, L2/3 CPM
-+ * L0s is reported during link training via TS1 order set by N_FTS
-+ */
-+ reg = IFX_REG_R32(PCIE_LCAP(pcie_port));
-+ reg &= ~PCIE_LCAP_L0S_EIXT_LATENCY;
-+ reg |= SM(3, PCIE_LCAP_L0S_EIXT_LATENCY);
-+ IFX_REG_W32(reg, PCIE_LCAP(pcie_port));
-+
-+ /* Link control and status register */
-+ reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
-+
-+ /* Link Enable, ASPM enabled */
-+ reg &= ~PCIE_LCTLSTS_LINK_DISABLE;
-+
-+#ifdef CONFIG_PCIEASPM
-+ /*
-+ * We use the same physical reference clock that the platform provides on the connector
-+ * It paved the way for ASPM to calculate the new exit Latency
-+ */
-+ reg |= PCIE_LCTLSTS_SLOT_CLK_CFG;
-+ reg |= PCIE_LCTLSTS_COM_CLK_CFG;
-+ /*
-+ * We should disable ASPM by default except that we have dedicated power management support
-+ * Enable ASPM will cause the system hangup/instability, performance degration
-+ */
-+ reg |= PCIE_LCTLSTS_ASPM_ENABLE;
-+#else
-+ reg &= ~PCIE_LCTLSTS_ASPM_ENABLE;
-+#endif /* CONFIG_PCIEASPM */
-+
-+ /*
-+ * The maximum size of any completion with data packet is bounded by the MPS setting
-+ * in device control register
-+ */
-+
-+ /* RCB may cause multiple split transactions, two options available, we use 64 byte RCB */
-+ reg &= ~ PCIE_LCTLSTS_RCB128;
-+
-+ IFX_REG_W32(reg, PCIE_LCTLSTS(pcie_port));
-+}
-+
-+static inline void pcie_error_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /*
-+ * Forward ERR_COR, ERR_NONFATAL, ERR_FATAL to the backbone
-+ * Poisoned write TLPs and completions indicating poisoned TLPs will set the PCIe_PCICMDSTS.MDPE
-+ */
-+ reg = IFX_REG_R32(PCIE_INTRBCTRL(pcie_port));
-+ reg |= PCIE_INTRBCTRL_SERR_ENABLE | PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE;
-+
-+ IFX_REG_W32(reg, PCIE_INTRBCTRL(pcie_port));
-+
-+ /* Uncorrectable Error Mask Register, Unmask <enable> all bits in PCIE_UESR */
-+ reg = IFX_REG_R32(PCIE_UEMR(pcie_port));
-+ reg &= ~PCIE_ALL_UNCORRECTABLE_ERR;
-+ IFX_REG_W32(reg, PCIE_UEMR(pcie_port));
-+
-+ /* Uncorrectable Error Severity Register, ALL errors are FATAL */
-+ IFX_REG_W32(PCIE_ALL_UNCORRECTABLE_ERR, PCIE_UESR(pcie_port));
-+
-+ /* Correctable Error Mask Register, unmask <enable> all bits */
-+ reg = IFX_REG_R32(PCIE_CEMR(pcie_port));
-+ reg &= ~PCIE_CORRECTABLE_ERR;
-+ IFX_REG_W32(reg, PCIE_CEMR(pcie_port));
-+
-+ /* Advanced Error Capabilities and Control Registr */
-+ reg = IFX_REG_R32(PCIE_AECCR(pcie_port));
-+ reg |= PCIE_AECCR_ECRC_CHECK_EN | PCIE_AECCR_ECRC_GEN_EN;
-+ IFX_REG_W32(reg, PCIE_AECCR(pcie_port));
-+
-+ /* Root Error Command Register, Report all types of errors */
-+ reg = IFX_REG_R32(PCIE_RECR(pcie_port));
-+ reg |= PCIE_RECR_ERR_REPORT_EN;
-+ IFX_REG_W32(reg, PCIE_RECR(pcie_port));
-+
-+ /* Clear the Root status register */
-+ reg = IFX_REG_R32(PCIE_RESR(pcie_port));
-+ IFX_REG_W32(reg, PCIE_RESR(pcie_port));
-+}
-+
-+static inline void pcie_port_logic_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* FTS number, default 12, increase to 63, may increase time from/to L0s to L0 */
-+ reg = IFX_REG_R32(PCIE_AFR(pcie_port));
-+ reg &= ~(PCIE_AFR_FTS_NUM | PCIE_AFR_COM_FTS_NUM);
-+ reg |= SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_FTS_NUM)
-+ | SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_COM_FTS_NUM);
-+ /* L0s and L1 entry latency */
-+ reg &= ~(PCIE_AFR_L0S_ENTRY_LATENCY | PCIE_AFR_L1_ENTRY_LATENCY);
-+ reg |= SM(PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L0S_ENTRY_LATENCY)
-+ | SM(PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L1_ENTRY_LATENCY);
-+ IFX_REG_W32(reg, PCIE_AFR(pcie_port));
-+
-+
-+ /* Port Link Control Register */
-+ reg = IFX_REG_R32(PCIE_PLCR(pcie_port));
-+ reg |= PCIE_PLCR_DLL_LINK_EN; /* Enable the DLL link */
-+ IFX_REG_W32(reg, PCIE_PLCR(pcie_port));
-+
-+ /* Lane Skew Register */
-+ reg = IFX_REG_R32(PCIE_LSR(pcie_port));
-+ /* Enable ACK/NACK and FC */
-+ reg &= ~(PCIE_LSR_ACKNAK_DISABLE | PCIE_LSR_FC_DISABLE);
-+ IFX_REG_W32(reg, PCIE_LSR(pcie_port));
-+
-+ /* Symbol Timer Register and Filter Mask Register 1 */
-+ reg = IFX_REG_R32(PCIE_STRFMR(pcie_port));
-+
-+ /* Default SKP interval is very accurate already, 5us */
-+ /* Enable IO/CFG transaction */
-+ reg |= PCIE_STRFMR_RX_CFG_TRANS_ENABLE | PCIE_STRFMR_RX_IO_TRANS_ENABLE;
-+ /* Disable FC WDT */
-+ reg &= ~PCIE_STRFMR_FC_WDT_DISABLE;
-+ IFX_REG_W32(reg, PCIE_STRFMR(pcie_port));
-+
-+ /* Filter Masker Register 2 */
-+ reg = IFX_REG_R32(PCIE_FMR2(pcie_port));
-+ reg |= PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 | PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1;
-+ IFX_REG_W32(reg, PCIE_FMR2(pcie_port));
-+
-+ /* VC0 Completion Receive Queue Control Register */
-+ reg = IFX_REG_R32(PCIE_VC0_CRQCR(pcie_port));
-+ reg &= ~PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE;
-+ reg |= SM(PCIE_VC0_TLP_QUEUE_MODE_BYPASS, PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE);
-+ IFX_REG_W32(reg, PCIE_VC0_CRQCR(pcie_port));
-+}
-+
-+static inline void pcie_rc_cfg_reg_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Disable LTSSM */
-+ IFX_REG_W32(0, PCIE_RC_CCR(pcie_port)); /* Disable LTSSM */
-+
-+ pcie_mem_io_setup(pcie_port);
-+
-+ /* XXX, MSI stuff should only apply to EP */
-+ /* MSI Capability: Only enable 32-bit addresses */
-+ reg = IFX_REG_R32(PCIE_MCAPR(pcie_port));
-+ reg &= ~PCIE_MCAPR_ADDR64_CAP;
-+
-+ reg |= PCIE_MCAPR_MSI_ENABLE;
-+
-+ /* Disable multiple message */
-+ reg &= ~(PCIE_MCAPR_MULTI_MSG_CAP | PCIE_MCAPR_MULTI_MSG_ENABLE);
-+ IFX_REG_W32(reg, PCIE_MCAPR(pcie_port));
-+
-+
-+ /* Enable PME, Soft reset enabled */
-+ reg = IFX_REG_R32(PCIE_PM_CSR(pcie_port));
-+ reg |= PCIE_PM_CSR_PME_ENABLE | PCIE_PM_CSR_SW_RST;
-+ IFX_REG_W32(reg, PCIE_PM_CSR(pcie_port));
-+
-+ /* setup the bus */
-+ reg = SM(0, PCIE_BNR_PRIMARY_BUS_NUM) | SM(1, PCIE_PNR_SECONDARY_BUS_NUM) | SM(0xFF, PCIE_PNR_SUB_BUS_NUM);
-+ IFX_REG_W32(reg, PCIE_BNR(pcie_port));
-+
-+
-+ pcie_device_setup(pcie_port);
-+ pcie_link_setup(pcie_port);
-+ pcie_error_setup(pcie_port);
-+
-+ /* Root control and capabilities register */
-+ reg = IFX_REG_R32(PCIE_RCTLCAP(pcie_port));
-+ reg |= PCIE_RCTLCAP_SERR_ENABLE | PCIE_RCTLCAP_PME_INT_EN;
-+ IFX_REG_W32(reg, PCIE_RCTLCAP(pcie_port));
-+
-+ /* Port VC Capability Register 2 */
-+ reg = IFX_REG_R32(PCIE_PVC2(pcie_port));
-+ reg &= ~PCIE_PVC2_VC_ARB_WRR;
-+ reg |= PCIE_PVC2_VC_ARB_16P_FIXED_WRR;
-+ IFX_REG_W32(reg, PCIE_PVC2(pcie_port));
-+
-+ /* VC0 Resource Capability Register */
-+ reg = IFX_REG_R32(PCIE_VC0_RC(pcie_port));
-+ reg &= ~PCIE_VC0_RC_REJECT_SNOOP;
-+ IFX_REG_W32(reg, PCIE_VC0_RC(pcie_port));
-+
-+ pcie_port_logic_setup(pcie_port);
-+}
-+
-+static int ifx_pcie_wait_phy_link_up(int pcie_port)
-+{
-+#define IFX_PCIE_PHY_LINK_UP_TIMEOUT 1000 /* XXX, tunable */
-+ int i;
-+
-+ /* Wait for PHY link is up */
-+ for (i = 0; i < IFX_PCIE_PHY_LINK_UP_TIMEOUT; i++) {
-+ if (ifx_pcie_link_up(pcie_port)) {
-+ break;
-+ }
-+ udelay(100);
-+ }
-+ if (i >= IFX_PCIE_PHY_LINK_UP_TIMEOUT) {
-+ printk(KERN_ERR "%s timeout\n", __func__);
-+ return -1;
-+ }
-+
-+ /* Check data link up or not */
-+ if (!(IFX_REG_R32(PCIE_RC_DR(pcie_port)) & PCIE_RC_DR_DLL_UP)) {
-+ printk(KERN_ERR "%s DLL link is still down\n", __func__);
-+ return -1;
-+ }
-+
-+ /* Check Data link active or not */
-+ if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_DLL_ACTIVE)) {
-+ printk(KERN_ERR "%s DLL is not active\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static inline int pcie_app_loigc_setup(int pcie_port)
-+{
-+ /* supress ahb bus errrors */
-+ IFX_REG_W32(PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS, PCIE_AHB_CTRL(pcie_port));
-+
-+ /* Pull PCIe EP out of reset */
-+ pcie_device_rst_deassert(pcie_port);
-+
-+ /* Start LTSSM training between RC and EP */
-+ pcie_ltssm_enable(pcie_port);
-+
-+ /* Check PHY status after enabling LTSSM */
-+ if (ifx_pcie_wait_phy_link_up(pcie_port) != 0)
-+ return -1;
-+
-+ return 0;
-+}
-+
-+/*
-+ * The numbers below are directly from the PCIe spec table 3-4/5.
-+ */
-+static inline void pcie_replay_time_update(int pcie_port)
-+{
-+ u32 reg;
-+ int nlw;
-+ int rtl;
-+
-+ reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
-+
-+ nlw = MS(reg, PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH);
-+ switch (nlw) {
-+ case PCIE_MAX_LENGTH_WIDTH_X1:
-+ rtl = 1677;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X2:
-+ rtl = 867;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X4:
-+ rtl = 462;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X8:
-+ rtl = 258;
-+ break;
-+ default:
-+ rtl = 1677;
-+ break;
-+ }
-+ reg = IFX_REG_R32(PCIE_ALTRT(pcie_port));
-+ reg &= ~PCIE_ALTRT_REPLAY_TIME_LIMIT;
-+ reg |= SM(rtl, PCIE_ALTRT_REPLAY_TIME_LIMIT);
-+ IFX_REG_W32(reg, PCIE_ALTRT(pcie_port));
-+}
-+
-+/*
-+ * Table 359 Enhanced Configuration Address Mapping1)
-+ * 1) This table is defined in Table 7-1, page 341, PCI Express Base Specification v1.1
-+ * Memory Address PCI Express Configuration Space
-+ * A[(20+n-1):20] Bus Number 1 < n < 8
-+ * A[19:15] Device Number
-+ * A[14:12] Function Number
-+ * A[11:8] Extended Register Number
-+ * A[7:2] Register Number
-+ * A[1:0] Along with size of the access, used to generate Byte Enables
-+ * For VR9, only the address bits [22:0] are mapped to the configuration space:
-+ * . Address bits [22:20] select the target bus (1-of-8)1)
-+ * . Address bits [19:15] select the target device (1-of-32) on the bus
-+ * . Address bits [14:12] select the target function (1-of-8) within the device.
-+ * . Address bits [11:2] selects the target dword (1-of-1024) within the selected function.s configuration space
-+ * . Address bits [1:0] define the start byte location within the selected dword.
-+ */
-+static inline u32 pcie_bus_addr(u8 bus_num, u16 devfn, int where)
-+{
-+ u32 addr;
-+ u8 bus;
-+
-+ if (!bus_num) {
-+ /* type 0 */
-+ addr = ((PCI_SLOT(devfn) & 0x1F) << 15) | ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF)& ~3);
-+ } else {
-+ bus = bus_num;
-+ /* type 1, only support 8 buses */
-+ addr = ((bus & 0x7) << 20) | ((PCI_SLOT(devfn) & 0x1F) << 15) |
-+ ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF) & ~3);
-+ }
-+ return addr;
-+}
-+
-+static int pcie_valid_config(int pcie_port, int bus, int dev)
-+{
-+ /* RC itself */
-+ if ((bus == 0) && (dev == 0)) {
-+ return 1;
-+ }
-+
-+ /* No physical link */
-+ if (!ifx_pcie_link_up(pcie_port)) {
-+ return 0;
-+ }
-+
-+ /* Bus zero only has RC itself
-+ * XXX, check if EP will be integrated
-+ */
-+ if ((bus == 0) && (dev != 0)) {
-+ return 0;
-+ }
-+
-+ /* Maximum 8 buses supported for VRX */
-+ if (bus > 9) {
-+ return 0;
-+ }
-+
-+ /*
-+ * PCIe is PtP link, one bus only supports only one device
-+ * except bus zero and PCIe switch which is virtual bus device
-+ * The following two conditions really depends on the system design
-+ * and attached the device.
-+ * XXX, how about more new switch
-+ */
-+ if ((bus == 1) && (dev != 0)) {
-+ return 0;
-+ }
-+
-+ if ((bus >= 3) && (dev != 0)) {
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+static inline u32 ifx_pcie_cfg_rd(int pcie_port, u32 reg)
-+{
-+ return IFX_REG_R32((volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline void ifx_pcie_cfg_wr(int pcie_port, unsigned int reg, u32 val)
-+{
-+ IFX_REG_W32( val, (volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline u32 ifx_pcie_rc_cfg_rd(int pcie_port, u32 reg)
-+{
-+ return IFX_REG_R32((volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline void ifx_pcie_rc_cfg_wr(int pcie_port, unsigned int reg, u32 val)
-+{
-+ IFX_REG_W32(val, (volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+u32 ifx_pcie_bus_enum_read_hack(int where, u32 value)
-+{
-+ u32 tvalue = value;
-+
-+ if (where == PCI_PRIMARY_BUS) {
-+ u8 primary, secondary, subordinate;
-+
-+ primary = tvalue & 0xFF;
-+ secondary = (tvalue >> 8) & 0xFF;
-+ subordinate = (tvalue >> 16) & 0xFF;
-+ primary += pcibios_1st_host_bus_nr();
-+ secondary += pcibios_1st_host_bus_nr();
-+ subordinate += pcibios_1st_host_bus_nr();
-+ tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
-+ }
-+ return tvalue;
-+}
-+
-+u32 ifx_pcie_bus_enum_write_hack(int where, u32 value)
-+{
-+ u32 tvalue = value;
-+
-+ if (where == PCI_PRIMARY_BUS) {
-+ u8 primary, secondary, subordinate;
-+
-+ primary = tvalue & 0xFF;
-+ secondary = (tvalue >> 8) & 0xFF;
-+ subordinate = (tvalue >> 16) & 0xFF;
-+ if (primary > 0 && primary != 0xFF) {
-+ primary -= pcibios_1st_host_bus_nr();
-+ }
-+
-+ if (secondary > 0 && secondary != 0xFF) {
-+ secondary -= pcibios_1st_host_bus_nr();
-+ }
-+ if (subordinate > 0 && subordinate != 0xFF) {
-+ subordinate -= pcibios_1st_host_bus_nr();
-+ }
-+ tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
-+ }
-+ else if (where == PCI_SUBORDINATE_BUS) {
-+ u8 subordinate = tvalue & 0xFF;
-+
-+ subordinate = subordinate > 0 ? subordinate - pcibios_1st_host_bus_nr() : 0;
-+ tvalue = subordinate;
-+ }
-+ return tvalue;
-+}
-+
-+static int ifx_pcie_read_config(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 *value)
-+{
-+ u32 data = 0;
-+ int bus_number = bus->number;
-+ static const u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
-+ int ret = PCIBIOS_SUCCESSFUL;
-+ struct ifx_pci_controller *ctrl = bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ if (unlikely(size != 1 && size != 2 && size != 4)){
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+
-+ /* Make sure the address is aligned to natural boundary */
-+ if (unlikely(((size - 1) & where))) {
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+
-+ /*
-+ * If we are second controller, we have to cheat OS so that it assume
-+ * its bus number starts from 0 in host controller
-+ */
-+ bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
-+
-+ /*
-+ * We need to force the bus number to be zero on the root
-+ * bus. Linux numbers the 2nd root bus to start after all
-+ * busses on root 0.
-+ */
-+ if (bus->parent == NULL) {
-+ bus_number = 0;
-+ }
-+
-+ /*
-+ * PCIe only has a single device connected to it. It is
-+ * always device ID 0. Don't bother doing reads for other
-+ * device IDs on the first segment.
-+ */
-+ if ((bus_number == 0) && (PCI_SLOT(devfn) != 0)) {
-+ ret = PCIBIOS_FUNC_NOT_SUPPORTED;
-+ goto out;
-+ }
-+
-+ if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
-+ *value = 0xffffffff;
-+ ret = PCIBIOS_DEVICE_NOT_FOUND;
-+ goto out;
-+ }
-+
-+ PCIE_IRQ_LOCK(ifx_pcie_lock);
-+ if (bus_number == 0) { /* RC itself */
-+ u32 t;
-+
-+ t = (where & ~3);
-+ data = ifx_pcie_rc_cfg_rd(pcie_port, t);
-+ } else {
-+ u32 addr = pcie_bus_addr(bus_number, devfn, where);
-+
-+ data = ifx_pcie_cfg_rd(pcie_port, addr);
-+ #ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = le32_to_cpu(data);
-+ #endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ }
-+ /* To get a correct PCI topology, we have to restore the bus number to OS */
-+ data = ifx_pcie_bus_enum_hack(bus, devfn, where, data, pcie_port, 1);
-+
-+ PCIE_IRQ_UNLOCK(ifx_pcie_lock);
-+
-+ *value = (data >> (8 * (where & 3))) & mask[size & 7];
-+out:
-+ return ret;
-+}
-+
-+static u32 ifx_pcie_size_to_value(int where, int size, u32 data, u32 value)
-+{
-+ u32 shift;
-+ u32 tdata = data;
-+
-+ switch (size) {
-+ case 1:
-+ shift = (where & 0x3) << 3;
-+ tdata &= ~(0xffU << shift);
-+ tdata |= ((value & 0xffU) << shift);
-+ break;
-+ case 2:
-+ shift = (where & 3) << 3;
-+ tdata &= ~(0xffffU << shift);
-+ tdata |= ((value & 0xffffU) << shift);
-+ break;
-+ case 4:
-+ tdata = value;
-+ break;
-+ }
-+ return tdata;
-+}
-+
-+static int ifx_pcie_write_config(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 value)
-+{
-+ int bus_number = bus->number;
-+ int ret = PCIBIOS_SUCCESSFUL;
-+ struct ifx_pci_controller *ctrl = bus->sysdata;
-+ int pcie_port = ctrl->port;
-+ u32 tvalue = value;
-+ u32 data;
-+
-+ /* Make sure the address is aligned to natural boundary */
-+ if (unlikely(((size - 1) & where))) {
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+ /*
-+ * If we are second controller, we have to cheat OS so that it assume
-+ * its bus number starts from 0 in host controller
-+ */
-+ bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
-+
-+ /*
-+ * We need to force the bus number to be zero on the root
-+ * bus. Linux numbers the 2nd root bus to start after all
-+ * busses on root 0.
-+ */
-+ if (bus->parent == NULL) {
-+ bus_number = 0;
-+ }
-+
-+ if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
-+ ret = PCIBIOS_DEVICE_NOT_FOUND;
-+ goto out;
-+ }
-+
-+ /* XXX, some PCIe device may need some delay */
-+ PCIE_IRQ_LOCK(ifx_pcie_lock);
-+
-+ /*
-+ * To configure the correct bus topology using native way, we have to cheat Os so that
-+ * it can configure the PCIe hardware correctly.
-+ */
-+ tvalue = ifx_pcie_bus_enum_hack(bus, devfn, where, value, pcie_port, 0);
-+
-+ if (bus_number == 0) { /* RC itself */
-+ u32 t;
-+
-+ t = (where & ~3);
-+ data = ifx_pcie_rc_cfg_rd(pcie_port, t);
-+
-+ data = ifx_pcie_size_to_value(where, size, data, tvalue);
-+
-+ ifx_pcie_rc_cfg_wr(pcie_port, t, data);
-+ } else {
-+ u32 addr = pcie_bus_addr(bus_number, devfn, where);
-+
-+ data = ifx_pcie_cfg_rd(pcie_port, addr);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = le32_to_cpu(data);
-+#endif
-+
-+ data = ifx_pcie_size_to_value(where, size, data, tvalue);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = cpu_to_le32(data);
-+#endif
-+ ifx_pcie_cfg_wr(pcie_port, addr, data);
-+ }
-+ PCIE_IRQ_UNLOCK(ifx_pcie_lock);
-+out:
-+ return ret;
-+}
-+
-+static struct resource ifx_pcie_io_resource = {
-+ .name = "PCIe0 I/O space",
-+ .start = PCIE_IO_PHY_BASE,
-+ .end = PCIE_IO_PHY_END,
-+ .flags = IORESOURCE_IO,
-+};
-+
-+static struct resource ifx_pcie_mem_resource = {
-+ .name = "PCIe0 Memory space",
-+ .start = PCIE_MEM_PHY_BASE,
-+ .end = PCIE_MEM_PHY_END,
-+ .flags = IORESOURCE_MEM,
-+};
-+
-+static struct pci_ops ifx_pcie_ops = {
-+ .read = ifx_pcie_read_config,
-+ .write = ifx_pcie_write_config,
-+};
-+
-+static struct ifx_pci_controller ifx_pcie_controller[IFX_PCIE_CORE_NR] = {
-+ {
-+ .pcic = {
-+ .pci_ops = &ifx_pcie_ops,
-+ .mem_resource = &ifx_pcie_mem_resource,
-+ .io_resource = &ifx_pcie_io_resource,
-+ },
-+ .port = IFX_PCIE_PORT0,
-+ },
-+};
-+
-+#ifdef IFX_PCIE_ERROR_INT
-+
-+static irqreturn_t pcie_rc_core_isr(int irq, void *dev_id)
-+{
-+ struct ifx_pci_controller *ctrl = (struct ifx_pci_controller *)dev_id;
-+ int pcie_port = ctrl->port;
-+ u32 reg;
-+
-+ pr_debug("PCIe RC error intr %d\n", irq);
-+ reg = IFX_REG_R32(PCIE_IRNCR(pcie_port));
-+ reg &= PCIE_RC_CORE_COMBINED_INT;
-+ IFX_REG_W32(reg, PCIE_IRNCR(pcie_port));
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int
-+pcie_rc_core_int_init(int pcie_port)
-+{
-+ int ret;
-+
-+ /* Enable core interrupt */
-+ IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNEN(pcie_port));
-+
-+ /* Clear it first */
-+ IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNCR(pcie_port));
-+ ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
-+ pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
-+ if (ret)
-+ printk(KERN_ERR "%s request irq %d failed\n", __func__, IFX_PCIE_IR);
-+
-+ return ret;
-+}
-+#endif
-+
-+int ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+ u32 irq_bit = 0;
-+ int irq = 0;
-+ struct ifx_pci_controller *ctrl = dev->bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ printk("%s port %d dev %s slot %d pin %d \n", __func__, pcie_port, pci_name(dev), slot, pin);
-+
-+ if ((pin == PCIE_LEGACY_DISABLE) || (pin > PCIE_LEGACY_INT_MAX)) {
-+ printk(KERN_WARNING "WARNING: dev %s: invalid interrupt pin %d\n", pci_name(dev), pin);
-+ return -1;
-+ }
-+
-+ /* Pin index so minus one */
-+ irq_bit = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq_bit;
-+ irq = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq;
-+ IFX_REG_SET_BIT(irq_bit, PCIE_IRNEN(pcie_port));
-+ IFX_REG_SET_BIT(irq_bit, PCIE_IRNCR(pcie_port));
-+ printk("%s dev %s irq %d assigned\n", __func__, pci_name(dev), irq);
-+ return irq;
-+}
-+
-+int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev)
-+{
-+ u16 config;
-+#ifdef IFX_PCIE_ERROR_INT
-+ u32 dconfig;
-+ int pos;
-+#endif
-+
-+ /* Enable reporting System errors and parity errors on all devices */
-+ /* Enable parity checking and error reporting */
-+ pci_read_config_word(dev, PCI_COMMAND, &config);
-+ config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR /*| PCI_COMMAND_INVALIDATE |
-+ PCI_COMMAND_FAST_BACK*/;
-+ pci_write_config_word(dev, PCI_COMMAND, config);
-+
-+ if (dev->subordinate) {
-+ /* Set latency timers on sub bridges */
-+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40); /* XXX, */
-+ /* More bridge error detection */
-+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
-+ config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
-+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
-+ }
-+#ifdef IFX_PCIE_ERROR_INT
-+ /* Enable the PCIe normal error reporting */
-+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-+ if (pos) {
-+
-+ /* Disable system error generation in response to error messages */
-+ pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &config);
-+ config &= ~(PCI_EXP_RTCTL_SECEE | PCI_EXP_RTCTL_SENFEE | PCI_EXP_RTCTL_SEFEE);
-+ pci_write_config_word(dev, pos + PCI_EXP_RTCTL, config);
-+
-+ /* Clear PCIE Capability's Device Status */
-+ pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &config);
-+ pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, config);
-+
-+ /* Update Device Control */
-+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
-+ /* Correctable Error Reporting */
-+ config |= PCI_EXP_DEVCTL_CERE;
-+ /* Non-Fatal Error Reporting */
-+ config |= PCI_EXP_DEVCTL_NFERE;
-+ /* Fatal Error Reporting */
-+ config |= PCI_EXP_DEVCTL_FERE;
-+ /* Unsupported Request */
-+ config |= PCI_EXP_DEVCTL_URRE;
-+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
-+ }
-+
-+ /* Find the Advanced Error Reporting capability */
-+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-+ if (pos) {
-+ /* Clear Uncorrectable Error Status */
-+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, dconfig);
-+ /* Enable reporting of all uncorrectable errors */
-+ /* Uncorrectable Error Mask - turned on bits disable errors */
-+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
-+ /*
-+ * Leave severity at HW default. This only controls if
-+ * errors are reported as uncorrectable or
-+ * correctable, not if the error is reported.
-+ */
-+ /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
-+ /* Clear Correctable Error Status */
-+ pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
-+ /* Enable reporting of all correctable errors */
-+ /* Correctable Error Mask - turned on bits disable errors */
-+ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
-+ /* Advanced Error Capabilities */
-+ pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
-+ /* ECRC Generation Enable */
-+ if (dconfig & PCI_ERR_CAP_ECRC_GENC) {
-+ dconfig |= PCI_ERR_CAP_ECRC_GENE;
-+ }
-+ /* ECRC Check Enable */
-+ if (dconfig & PCI_ERR_CAP_ECRC_CHKC) {
-+ dconfig |= PCI_ERR_CAP_ECRC_CHKE;
-+ }
-+ pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
-+
-+ /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
-+ /* Enable Root Port's interrupt in response to error messages */
-+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
-+ PCI_ERR_ROOT_CMD_COR_EN |
-+ PCI_ERR_ROOT_CMD_NONFATAL_EN |
-+ PCI_ERR_ROOT_CMD_FATAL_EN);
-+ /* Clear the Root status register */
-+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
-+ }
-+#endif /* IFX_PCIE_ERROR_INT */
-+ /* WAR, only 128 MRRS is supported, force all EPs to support this value */
-+ pcie_set_readrq(dev, 128);
-+ return 0;
-+}
-+
-+static int
-+pcie_rc_initialize(int pcie_port)
-+{
-+ int i;
-+#define IFX_PCIE_PHY_LOOP_CNT 5
-+
-+ pcie_rcu_endian_setup(pcie_port);
-+
-+ pcie_ep_gpio_rst_init(pcie_port);
-+
-+ /*
-+ * XXX, PCIe elastic buffer bug will cause not to be detected. One more
-+ * reset PCIe PHY will solve this issue
-+ */
-+ for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
-+ /* Disable PCIe PHY Analog part for sanity check */
-+ pcie_phy_pmu_disable(pcie_port);
-+
-+ pcie_phy_rst_assert(pcie_port);
-+ pcie_phy_rst_deassert(pcie_port);
-+
-+ /* Make sure PHY PLL is stable */
-+ udelay(20);
-+
-+ /* PCIe Core reset enabled, low active, sw programmed */
-+ pcie_core_rst_assert(pcie_port);
-+
-+ /* Put PCIe EP in reset status */
-+ pcie_device_rst_assert(pcie_port);
-+
-+ /* PCI PHY & Core reset disabled, high active, sw programmed */
-+ pcie_core_rst_deassert(pcie_port);
-+
-+ /* Already in a quiet state, program PLL, enable PHY, check ready bit */
-+ pcie_phy_clock_mode_setup(pcie_port);
-+
-+ /* Enable PCIe PHY and Clock */
-+ pcie_core_pmu_setup(pcie_port);
-+
-+ /* Clear status registers */
-+ pcie_status_register_clear(pcie_port);
-+
-+#ifdef CONFIG_PCI_MSI
-+ pcie_msi_init(pcie_port);
-+#endif /* CONFIG_PCI_MSI */
-+ pcie_rc_cfg_reg_setup(pcie_port);
-+
-+ /* Once link is up, break out */
-+ if (pcie_app_loigc_setup(pcie_port) == 0)
-+ break;
-+ }
-+ if (i >= IFX_PCIE_PHY_LOOP_CNT) {
-+ printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
-+ return -EIO;
-+ }
-+ /* NB, don't increase ACK/NACK timer timeout value, which will cause a lot of COR errors */
-+ pcie_replay_time_update(pcie_port);
-+ return 0;
-+}
-+
-+static int __init ifx_pcie_bios_init(void)
-+{
-+ void __iomem *io_map_base;
-+ int pcie_port;
-+ int startup_port;
-+
-+ /* Enable AHB Master/ Slave */
-+ pcie_ahb_pmu_setup();
-+
-+ startup_port = IFX_PCIE_PORT0;
-+
-+ for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
-+ if (pcie_rc_initialize(pcie_port) == 0) {
-+ IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
-+ __func__, PCIE_CFG_PORT_TO_BASE(pcie_port));
-+ /* Otherwise, warning will pop up */
-+ io_map_base = ioremap(PCIE_IO_PHY_PORT_TO_BASE(pcie_port), PCIE_IO_SIZE);
-+ if (io_map_base == NULL) {
-+ IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
-+ return -ENOMEM;
-+ }
-+ ifx_pcie_controller[pcie_port].pcic.io_map_base = (unsigned long)io_map_base;
-+
-+ register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
-+ /* XXX, clear error status */
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: mem_resource 0x%p, io_resource 0x%p\n",
-+ __func__, &ifx_pcie_controller[pcie_port].pcic.mem_resource,
-+ &ifx_pcie_controller[pcie_port].pcic.io_resource);
-+
-+ #ifdef IFX_PCIE_ERROR_INT
-+ pcie_rc_core_int_init(pcie_port);
-+ #endif /* IFX_PCIE_ERROR_INT */
-+ }
-+ }
-+
-+ return 0;
-+}
-+arch_initcall(ifx_pcie_bios_init);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
-+MODULE_DESCRIPTION("Infineon builtin PCIe RC driver");
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie.h
-@@ -0,0 +1,131 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_H
-+#define IFXMIPS_PCIE_H
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+#include "ifxmips_pci_common.h"
-+#include "ifxmips_pcie_reg.h"
-+
-+/*!
-+ \defgroup IFX_PCIE PCI Express bus driver module
-+ \brief PCI Express IP module support VRX200
-+*/
-+
-+/*!
-+ \defgroup IFX_PCIE_OS OS APIs
-+ \ingroup IFX_PCIE
-+ \brief PCIe bus driver OS interface functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module common header file
-+*/
-+#define PCIE_IRQ_LOCK(lock) do { \
-+ unsigned long flags; \
-+ spin_lock_irqsave(&(lock), flags);
-+#define PCIE_IRQ_UNLOCK(lock) \
-+ spin_unlock_irqrestore(&(lock), flags); \
-+} while (0)
-+
-+#define PCIE_MSG_MSI 0x00000001
-+#define PCIE_MSG_ISR 0x00000002
-+#define PCIE_MSG_FIXUP 0x00000004
-+#define PCIE_MSG_READ_CFG 0x00000008
-+#define PCIE_MSG_WRITE_CFG 0x00000010
-+#define PCIE_MSG_CFG (PCIE_MSG_READ_CFG | PCIE_MSG_WRITE_CFG)
-+#define PCIE_MSG_REG 0x00000020
-+#define PCIE_MSG_INIT 0x00000040
-+#define PCIE_MSG_ERR 0x00000080
-+#define PCIE_MSG_PHY 0x00000100
-+#define PCIE_MSG_ANY 0x000001ff
-+
-+#define IFX_PCIE_PORT0 0
-+#define IFX_PCIE_PORT1 1
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+#define IFX_PCIE_CORE_NR 2
-+#else
-+#define IFX_PCIE_CORE_NR 1
-+#endif
-+
-+#define IFX_PCIE_ERROR_INT
-+
-+//#define IFX_PCIE_DBG
-+
-+#if defined(IFX_PCIE_DBG)
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) do { \
-+ ifx_pcie_debug((_fmt), ##args); \
-+} while (0)
-+
-+#define INLINE
-+#else
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) \
-+ do {} while(0)
-+#define INLINE inline
-+#endif
-+
-+struct ifx_pci_controller {
-+ struct pci_controller pcic;
-+
-+ /* RC specific, per host bus information */
-+ u32 port; /* Port index, 0 -- 1st core, 1 -- 2nd core */
-+};
-+
-+typedef struct ifx_pcie_ir_irq {
-+ const unsigned int irq;
-+ const char name[16];
-+}ifx_pcie_ir_irq_t;
-+
-+typedef struct ifx_pcie_legacy_irq{
-+ const u32 irq_bit;
-+ const int irq;
-+}ifx_pcie_legacy_irq_t;
-+
-+typedef struct ifx_pcie_irq {
-+ ifx_pcie_ir_irq_t ir_irq;
-+ ifx_pcie_legacy_irq_t legacy_irq[PCIE_LEGACY_INT_MAX];
-+}ifx_pcie_irq_t;
-+
-+extern u32 g_pcie_debug_flag;
-+extern void ifx_pcie_debug(const char *fmt, ...);
-+extern void pcie_phy_clock_mode_setup(int pcie_port);
-+extern void pcie_msi_pic_init(int pcie_port);
-+extern u32 ifx_pcie_bus_enum_read_hack(int where, u32 value);
-+extern u32 ifx_pcie_bus_enum_write_hack(int where, u32 value);
-+
-+#define CONFIG_VR9
-+
-+#ifdef CONFIG_VR9
-+#include "ifxmips_pcie_vr9.h"
-+#elif defined (CONFIG_AR10)
-+#include "ifxmips_pcie_ar10.h"
-+#else
-+#error "PCIE: platform not defined"
-+#endif /* CONFIG_VR9 */
-+
-+#endif /* IFXMIPS_PCIE_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_ar10.h
-@@ -0,0 +1,305 @@
-+/****************************************************************************
-+ Copyright (c) 2010
-+ Lantiq Deutschland GmbH
-+ Am Campeon 3; 85579 Neubiberg, Germany
-+
-+ For licensing information, see the file 'LICENSE' in the root folder of
-+ this software module.
-+
-+ *****************************************************************************/
-+/*!
-+ \file ifxmips_pcie_ar10.h
-+ \ingroup IFX_PCIE
-+ \brief PCIe RC driver ar10 specific file
-+*/
-+
-+#ifndef IFXMIPS_PCIE_AR10_H
-+#define IFXMIPS_PCIE_AR10_H
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+
-+/* Project header file */
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_pmu.h>
-+#include <asm/ifx/ifx_gpio.h>
-+#include <asm/ifx/ifx_ebu_led.h>
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+ ifx_ebu_led_enable();
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 1);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 1);
-+ }
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ /* XXX, moved to CGU to control AHBM */
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Inbound, big endian */
-+ reg |= IFX_RCU_BE_AHB4S;
-+ if (pcie_port == 0) {
-+ reg |= IFX_RCU_BE_PCIE0M;
-+
-+ #ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ /* Outbound, software swap needed */
-+ reg |= IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE0S;
-+ #else
-+ /* Outbound little endian */
-+ reg &= ~IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE0S;
-+ #endif
-+ }
-+ else {
-+ reg |= IFX_RCU_BE_PCIE1M;
-+ #ifdef CONFIG_IFX_PCIE1_HW_SWAP
-+ /* Outbound, software swap needed */
-+ reg |= IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE1S;
-+ #else
-+ /* Outbound little endian */
-+ reg &= ~IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE1S;
-+ #endif
-+ }
-+
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ if (pcie_port == 0) { /* XXX, should use macro*/
-+ PCIE0_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PCIE1_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ if (pcie_port == 0) { /* XXX, should use macro*/
-+ PCIE0_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+ }
-+ else {
-+ PCIE1_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+ }
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ if (pcie_port == 0) {
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_BE_PCIE0_PDI;
-+ }
-+ else {
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_BE_PCIE1_PDI;
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ /* Enable PDI to access PCIe PHY register */
-+ PDI0_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PDI1_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset Core, bit 22 */
-+ if (pcie_port == 0) {
-+ reg |= 0x00400000;
-+ }
-+ else {
-+ reg |= 0x08000000; /* Bit 27 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg &= ~0x00400000; /* bit 22 */
-+ }
-+ else {
-+ reg &= ~0x08000000; /* Bit 27 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg |= 0x00001000; /* Bit 12 */
-+ }
-+ else {
-+ reg |= 0x00002000; /* Bit 13 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg &= ~0x00001000; /* Bit 12 */
-+ }
-+ else {
-+ reg &= ~0x00002000; /* Bit 13 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 0);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 0);
-+ }
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 1);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 1);
-+ }
-+ ifx_ebu_led_disable();
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ PCIE0_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PCIE1_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ pcie_msi_pic_init(pcie_port);
-+ if (pcie_port == 0) {
-+ MSI0_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ MSI1_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+ }
-+#endif /* CONFIG_IFX_PCI */
-+ return tbus_number;
-+}
-+
-+static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ }
-+ #endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_AR10_H */
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_msi.c
-@@ -0,0 +1,391 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_msi.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCI MSI sub module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe MSI Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Date $Author $Comment
-+** 02 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \defgroup IFX_PCIE_MSI MSI OS APIs
-+ \ingroup IFX_PCIE
-+ \brief PCIe bus driver OS interface functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie_msi.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe MSI OS interface file
-+*/
-+
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/pci.h>
-+#include <linux/msi.h>
-+#include <linux/module.h>
-+#include <asm/bootinfo.h>
-+#include <asm/irq.h>
-+#include <asm/traps.h>
-+
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_regs.h>
-+#include <asm/ifx/common_routines.h>
-+#include <asm/ifx/irq.h>
-+
-+#include "ifxmips_pcie_reg.h"
-+#include "ifxmips_pcie.h"
-+
-+#define IFX_MSI_IRQ_NUM 16
-+
-+enum {
-+ IFX_PCIE_MSI_IDX0 = 0,
-+ IFX_PCIE_MSI_IDX1,
-+ IFX_PCIE_MSI_IDX2,
-+ IFX_PCIE_MSI_IDX3,
-+};
-+
-+typedef struct ifx_msi_irq_idx {
-+ const int irq;
-+ const int idx;
-+}ifx_msi_irq_idx_t;
-+
-+struct ifx_msi_pic {
-+ volatile u32 pic_table[IFX_MSI_IRQ_NUM];
-+ volatile u32 pic_endian; /* 0x40 */
-+};
-+typedef struct ifx_msi_pic *ifx_msi_pic_t;
-+
-+typedef struct ifx_msi_irq {
-+ const volatile ifx_msi_pic_t msi_pic_p;
-+ const u32 msi_phy_base;
-+ const ifx_msi_irq_idx_t msi_irq_idx[IFX_MSI_IRQ_NUM];
-+ /*
-+ * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
-+ * in use.
-+ */
-+ u16 msi_free_irq_bitmask;
-+
-+ /*
-+ * Each bit in msi_multiple_irq_bitmask tells that the device using
-+ * this bit in msi_free_irq_bitmask is also using the next bit. This
-+ * is used so we can disable all of the MSI interrupts when a device
-+ * uses multiple.
-+ */
-+ u16 msi_multiple_irq_bitmask;
-+}ifx_msi_irq_t;
-+
-+static ifx_msi_irq_t msi_irqs[IFX_PCIE_CORE_NR] = {
-+ {
-+ .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI_PIC_REG_BASE,
-+ .msi_phy_base = PCIE_MSI_PHY_BASE,
-+ .msi_irq_idx = {
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ },
-+ .msi_free_irq_bitmask = 0,
-+ .msi_multiple_irq_bitmask= 0,
-+ },
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ {
-+ .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI1_PIC_REG_BASE,
-+ .msi_phy_base = PCIE1_MSI_PHY_BASE,
-+ .msi_irq_idx = {
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ },
-+ .msi_free_irq_bitmask = 0,
-+ .msi_multiple_irq_bitmask= 0,
-+
-+ },
-+#endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+};
-+
-+/*
-+ * This lock controls updates to msi_free_irq_bitmask,
-+ * msi_multiple_irq_bitmask and pic register settting
-+ */
-+static DEFINE_SPINLOCK(ifx_pcie_msi_lock);
-+
-+void pcie_msi_pic_init(int pcie_port)
-+{
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_pic_p->pic_endian = IFX_MSI_PIC_BIG_ENDIAN;
-+ spin_unlock(&ifx_pcie_msi_lock);
-+}
-+
-+/**
-+ * \fn int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-+ * \brief Called when a driver request MSI interrupts instead of the
-+ * legacy INT A-D. This routine will allocate multiple interrupts
-+ * for MSI devices that support them. A device can override this by
-+ * programming the MSI control bits [6:4] before calling
-+ * pci_enable_msi().
-+ *
-+ * \param[in] pdev Device requesting MSI interrupts
-+ * \param[in] desc MSI descriptor
-+ *
-+ * \return -EINVAL Invalid pcie root port or invalid msi bit
-+ * \return 0 OK
-+ * \ingroup IFX_PCIE_MSI
-+ */
-+int
-+arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-+{
-+ int irq, pos;
-+ u16 control;
-+ int irq_idx;
-+ int irq_step;
-+ int configured_private_bits;
-+ int request_private_bits;
-+ struct msi_msg msg;
-+ u16 search_mask;
-+ struct ifx_pci_controller *ctrl = pdev->bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s %s enter\n", __func__, pci_name(pdev));
-+
-+ /* XXX, skip RC MSI itself */
-+ if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s RC itself doesn't use MSI interrupt\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ /*
-+ * Read the MSI config to figure out how many IRQs this device
-+ * wants. Most devices only want 1, which will give
-+ * configured_private_bits and request_private_bits equal 0.
-+ */
-+ pci_read_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &control);
-+
-+ /*
-+ * If the number of private bits has been configured then use
-+ * that value instead of the requested number. This gives the
-+ * driver the chance to override the number of interrupts
-+ * before calling pci_enable_msi().
-+ */
-+ configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
-+ if (configured_private_bits == 0) {
-+ /* Nothing is configured, so use the hardware requested size */
-+ request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
-+ }
-+ else {
-+ /*
-+ * Use the number of configured bits, assuming the
-+ * driver wanted to override the hardware request
-+ * value.
-+ */
-+ request_private_bits = configured_private_bits;
-+ }
-+
-+ /*
-+ * The PCI 2.3 spec mandates that there are at most 32
-+ * interrupts. If this device asks for more, only give it one.
-+ */
-+ if (request_private_bits > 5) {
-+ request_private_bits = 0;
-+ }
-+again:
-+ /*
-+ * The IRQs have to be aligned on a power of two based on the
-+ * number being requested.
-+ */
-+ irq_step = (1 << request_private_bits);
-+
-+ /* Mask with one bit for each IRQ */
-+ search_mask = (1 << irq_step) - 1;
-+
-+ /*
-+ * We're going to search msi_free_irq_bitmask_lock for zero
-+ * bits. This represents an MSI interrupt number that isn't in
-+ * use.
-+ */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos += irq_step) {
-+ if ((msi_irqs[pcie_port].msi_free_irq_bitmask & (search_mask << pos)) == 0) {
-+ msi_irqs[pcie_port].msi_free_irq_bitmask |= search_mask << pos;
-+ msi_irqs[pcie_port].msi_multiple_irq_bitmask |= (search_mask >> 1) << pos;
-+ break;
-+ }
-+ }
-+ spin_unlock(&ifx_pcie_msi_lock);
-+
-+ /* Make sure the search for available interrupts didn't fail */
-+ if (pos >= IFX_MSI_IRQ_NUM) {
-+ if (request_private_bits) {
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s: Unable to find %d free "
-+ "interrupts, trying just one", __func__, 1 << request_private_bits);
-+ request_private_bits = 0;
-+ goto again;
-+ }
-+ else {
-+ printk(KERN_ERR "%s: Unable to find a free MSI interrupt\n", __func__);
-+ return -EINVAL;
-+ }
-+ }
-+ irq = msi_irqs[pcie_port].msi_irq_idx[pos].irq;
-+ irq_idx = msi_irqs[pcie_port].msi_irq_idx[pos].idx;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "pos %d, irq %d irq_idx %d\n", pos, irq, irq_idx);
-+
-+ /*
-+ * Initialize MSI. This has to match the memory-write endianess from the device
-+ * Address bits [23:12]
-+ */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] = SM(irq_idx, IFX_MSI_PIC_INT_LINE) |
-+ SM((msi_irqs[pcie_port].msi_phy_base >> 12), IFX_MSI_PIC_MSG_ADDR) |
-+ SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
-+
-+ /* Enable this entry */
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~IFX_MSI_PCI_INT_DISABLE;
-+ spin_unlock(&ifx_pcie_msi_lock);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "pic_table[%d]: 0x%08x\n",
-+ pos, msi_irqs[pcie_port].msi_pic_p->pic_table[pos]);
-+
-+ /* Update the number of IRQs the device has available to it */
-+ control &= ~PCI_MSI_FLAGS_QSIZE;
-+ control |= (request_private_bits << 4);
-+ pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control);
-+
-+ set_irq_msi(irq, desc);
-+ msg.address_hi = 0x0;
-+ msg.address_lo = msi_irqs[pcie_port].msi_phy_base;
-+ msg.data = SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "msi_data: pos %d 0x%08x\n", pos, msg.data);
-+
-+ write_msi_msg(irq, &msg);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
-+ return 0;
-+}
-+
-+static int
-+pcie_msi_irq_to_port(unsigned int irq, int *port)
-+{
-+ int ret = 0;
-+
-+ if (irq == IFX_PCIE_MSI_IR0 || irq == IFX_PCIE_MSI_IR1 ||
-+ irq == IFX_PCIE_MSI_IR2 || irq == IFX_PCIE_MSI_IR3) {
-+ *port = IFX_PCIE_PORT0;
-+ }
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ else if (irq == IFX_PCIE1_MSI_IR0 || irq == IFX_PCIE1_MSI_IR1 ||
-+ irq == IFX_PCIE1_MSI_IR2 || irq == IFX_PCIE1_MSI_IR3) {
-+ *port = IFX_PCIE_PORT1;
-+ }
-+#endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+ else {
-+ printk(KERN_ERR "%s: Attempted to teardown illegal "
-+ "MSI interrupt (%d)\n", __func__, irq);
-+ ret = -EINVAL;
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * \fn void arch_teardown_msi_irq(unsigned int irq)
-+ * \brief Called when a device no longer needs its MSI interrupts. All
-+ * MSI interrupts for the device are freed.
-+ *
-+ * \param irq The devices first irq number. There may be multple in sequence.
-+ * \return none
-+ * \ingroup IFX_PCIE_MSI
-+ */
-+void
-+arch_teardown_msi_irq(unsigned int irq)
-+{
-+ int pos;
-+ int number_irqs;
-+ u16 bitmask;
-+ int pcie_port;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s enter\n", __func__);
-+
-+ BUG_ON(irq > INT_NUM_IM4_IRL31);
-+
-+ if (pcie_msi_irq_to_port(irq, &pcie_port) != 0) {
-+ return;
-+ }
-+
-+ /* Shift the mask to the correct bit location, not always correct
-+ * Probally, the first match will be chosen.
-+ */
-+ for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos++) {
-+ if ((msi_irqs[pcie_port].msi_irq_idx[pos].irq == irq)
-+ && (msi_irqs[pcie_port].msi_free_irq_bitmask & ( 1 << pos))) {
-+ break;
-+ }
-+ }
-+ if (pos >= IFX_MSI_IRQ_NUM) {
-+ printk(KERN_ERR "%s: Unable to find a matched MSI interrupt\n", __func__);
-+ return;
-+ }
-+ spin_lock(&ifx_pcie_msi_lock);
-+ /* Disable this entry */
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] |= IFX_MSI_PCI_INT_DISABLE;
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~(IFX_MSI_PIC_INT_LINE | IFX_MSI_PIC_MSG_ADDR | IFX_MSI_PIC_MSG_DATA);
-+ spin_unlock(&ifx_pcie_msi_lock);
-+ /*
-+ * Count the number of IRQs we need to free by looking at the
-+ * msi_multiple_irq_bitmask. Each bit set means that the next
-+ * IRQ is also owned by this device.
-+ */
-+ number_irqs = 0;
-+ while (((pos + number_irqs) < IFX_MSI_IRQ_NUM) &&
-+ (msi_irqs[pcie_port].msi_multiple_irq_bitmask & (1 << (pos + number_irqs)))) {
-+ number_irqs++;
-+ }
-+ number_irqs++;
-+
-+ /* Mask with one bit for each IRQ */
-+ bitmask = (1 << number_irqs) - 1;
-+
-+ bitmask <<= pos;
-+ if ((msi_irqs[pcie_port].msi_free_irq_bitmask & bitmask) != bitmask) {
-+ printk(KERN_ERR "%s: Attempted to teardown MSI "
-+ "interrupt (%d) not in use\n", __func__, irq);
-+ return;
-+ }
-+ /* Checks are done, update the in use bitmask */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_free_irq_bitmask &= ~bitmask;
-+ msi_irqs[pcie_port].msi_multiple_irq_bitmask &= ~(bitmask >> 1);
-+ spin_unlock(&ifx_pcie_msi_lock);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
-+}
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
-+MODULE_DESCRIPTION("Infineon PCIe IP builtin MSI PIC driver");
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_phy.c
-@@ -0,0 +1,478 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_phy.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe PHY sub module
-+**
-+** DATE : 14 May 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 14 May,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_pcie_phy.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe PHY PLL register programming source file
-+*/
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/paccess.h>
-+#include <linux/delay.h>
-+
-+#include "ifxmips_pcie_reg.h"
-+#include "ifxmips_pcie.h"
-+
-+/* PCIe PDI only supports 16 bit operation */
-+
-+#define IFX_PCIE_PHY_REG_WRITE16(__addr, __data) \
-+ ((*(volatile u16 *) (__addr)) = (__data))
-+
-+#define IFX_PCIE_PHY_REG_READ16(__addr) \
-+ (*(volatile u16 *) (__addr))
-+
-+#define IFX_PCIE_PHY_REG16(__addr) \
-+ (*(volatile u16 *) (__addr))
-+
-+#define IFX_PCIE_PHY_REG(__reg, __value, __mask) do { \
-+ u16 read_data; \
-+ u16 write_data; \
-+ read_data = IFX_PCIE_PHY_REG_READ16((__reg)); \
-+ write_data = (read_data & ((u16)~(__mask))) | (((u16)(__value)) & ((u16)(__mask)));\
-+ IFX_PCIE_PHY_REG_WRITE16((__reg), write_data); \
-+} while (0)
-+
-+#define IFX_PCIE_PLL_TIMEOUT 1000 /* Tunnable */
-+
-+//#define IFX_PCI_PHY_REG_DUMP
-+
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+static void
-+pcie_phy_reg_dump(int pcie_port)
-+{
-+ printk("PLL REGFILE\n");
-+ printk("PCIE_PHY_PLL_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL4 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL4(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL5 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL5(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL6 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL6(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL7 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL7(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_PLL_STATUS 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)));
-+
-+ printk("TX1 REGFILE\n");
-+ printk("PCIE_PHY_TX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX1_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_TX1_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX1_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD1(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD2(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD3(pcie_port)));
-+
-+ printk("TX2 REGFILE\n");
-+ printk("PCIE_PHY_TX2_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX2_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX2_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX2_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD1(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD2(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD3(pcie_port)));
-+
-+ printk("RX1 REGFILE\n");
-+ printk("PCIE_PHY_RX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_RX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_RX1_CDR 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CDR(pcie_port)));
-+ printk("PCIE_PHY_RX1_EI 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_EI(pcie_port)));
-+ printk("PCIE_PHY_RX1_A_CTRL 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_A_CTRL(pcie_port)));
-+}
-+#endif /* IFX_PCI_PHY_REG_DUMP */
-+
-+static void
-+pcie_phy_comm_setup(int pcie_port)
-+{
-+ /* PLL Setting */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
-+
-+ /* increase the bias reference voltage */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
-+
-+ /* Endcnt */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
-+
-+ /* force */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
-+
-+ /* ctrl_lim */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
-+
-+ /* ctrl */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
-+
-+ /* RTERM*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
-+
-+ /* Improved 100MHz clock output */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
-+
-+ /* Reduced CDR BW to avoid glitches */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
-+}
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+static void
-+pcie_phy_36mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE
-+static void
-+pcie_phy_36mhz_ssc_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+
-+ /* PLL Setting */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
-+
-+ /* Increase the bias reference voltage */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
-+
-+ /* Endcnt */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
-+
-+ /* Force */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
-+
-+ /* Predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
-+
-+ /* ctrl_lim */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
-+
-+ /* ctrl */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
-+
-+ /* RTERM*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
-+
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0400, 0x0400);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0100);
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1c72, 0xFFFF);
-+
-+ /* improved 100MHz clock output */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
-+
-+ /* reduced CDR BW to avoid glitches */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_25MHZ_MODE
-+static void
-+pcie_phy_25mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0200);
-+
-+ /* en_ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0002, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0040, 0x0070);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x6000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x4000, 0x4000);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_25MHZ_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_100MHZ_MODE
-+static void
-+pcie_phy_100mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_100MHZ_MODE */
-+
-+static int
-+pcie_phy_wait_startup_ready(int pcie_port)
-+{
-+ int i;
-+
-+ for (i = 0; i < IFX_PCIE_PLL_TIMEOUT; i++) {
-+ if ((IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)) & 0x0040) != 0) {
-+ break;
-+ }
-+ udelay(10);
-+ }
-+ if (i >= IFX_PCIE_PLL_TIMEOUT) {
-+ printk(KERN_ERR "%s PLL Link timeout\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static void
-+pcie_phy_load_enable(int pcie_port, int slice)
-+{
-+ /* Set the load_en of tx/rx slice to '1' */
-+ switch (slice) {
-+ case 1:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0010, 0x0010);
-+ break;
-+ case 2:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0010, 0x0010);
-+ break;
-+ case 3:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0002, 0x0002);
-+ break;
-+ }
-+}
-+
-+static void
-+pcie_phy_load_disable(int pcie_port, int slice)
-+{
-+ /* set the load_en of tx/rx slice to '0' */
-+ switch (slice) {
-+ case 1:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0000, 0x0010);
-+ break;
-+ case 2:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0000, 0x0010);
-+ break;
-+ case 3:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0000, 0x0002);
-+ break;
-+ }
-+}
-+
-+static void
-+pcie_phy_load_war(int pcie_port)
-+{
-+ int slice;
-+
-+ for (slice = 1; slice < 4; slice++) {
-+ pcie_phy_load_enable(pcie_port, slice);
-+ udelay(1);
-+ pcie_phy_load_disable(pcie_port, slice);
-+ }
-+}
-+
-+static void
-+pcie_phy_tx2_modulation(int pcie_port)
-+{
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD1(pcie_port), 0x1FFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD2(pcie_port), 0xFFFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0601, 0xFFFF);
-+ mdelay(1);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0001, 0xFFFF);
-+}
-+
-+static void
-+pcie_phy_tx1_modulation(int pcie_port)
-+{
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD1(pcie_port), 0x1FFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD2(pcie_port), 0xFFFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0601, 0xFFFF);
-+ mdelay(1);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0001, 0xFFFF);
-+}
-+
-+static void
-+pcie_phy_tx_modulation_war(int pcie_port)
-+{
-+ int i;
-+
-+#define PCIE_PHY_MODULATION_NUM 5
-+ for (i = 0; i < PCIE_PHY_MODULATION_NUM; i++) {
-+ pcie_phy_tx2_modulation(pcie_port);
-+ pcie_phy_tx1_modulation(pcie_port);
-+ }
-+#undef PCIE_PHY_MODULATION_NUM
-+}
-+
-+void
-+pcie_phy_clock_mode_setup(int pcie_port)
-+{
-+ pcie_pdi_big_endian(pcie_port);
-+
-+ /* Enable PDI to access PCIe PHY register */
-+ pcie_pdi_pmu_enable(pcie_port);
-+
-+ /* Configure PLL and PHY clock */
-+ pcie_phy_comm_setup(pcie_port);
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+ pcie_phy_36mhz_mode_setup(pcie_port);
-+#elif defined(CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE)
-+ pcie_phy_36mhz_ssc_mode_setup(pcie_port);
-+#elif defined(CONFIG_IFX_PCIE_PHY_25MHZ_MODE)
-+ pcie_phy_25mhz_mode_setup(pcie_port);
-+#elif defined (CONFIG_IFX_PCIE_PHY_100MHZ_MODE)
-+ pcie_phy_100mhz_mode_setup(pcie_port);
-+#else
-+ #error "PCIE PHY Clock Mode must be chosen first!!!!"
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
-+
-+ /* Enable PCIe PHY and make PLL setting take effect */
-+ pcie_phy_pmu_enable(pcie_port);
-+
-+ /* Check if we are in startup_ready status */
-+ pcie_phy_wait_startup_ready(pcie_port);
-+
-+ pcie_phy_load_war(pcie_port);
-+
-+ /* Apply TX modulation workarounds */
-+ pcie_phy_tx_modulation_war(pcie_port);
-+
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Modified PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+}
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_pm.c
-@@ -0,0 +1,176 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_pm.c
-+** PROJECT : IFX UEIP
-+** MODULES : PCIE Root Complex Driver
-+**
-+** DATE : 21 Dec 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIE Root Complex Driver Power Managment
-+** COPYRIGHT : Copyright (c) 2009
-+** Lantiq Deutschland GmbH
-+** Am Campeon 3, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 21 Dec,2009 Lei Chuanhua First UEIP release
-+*******************************************************************************/
-+/*!
-+ \defgroup IFX_PCIE_PM Power Management functions
-+ \ingroup IFX_PCIE
-+ \brief IFX PCIE Root Complex Driver power management functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie_pm.c
-+ \ingroup IFX_PCIE
-+ \brief source file for PCIE Root Complex Driver Power Management
-+*/
-+
-+#ifndef EXPORT_SYMTAB
-+#define EXPORT_SYMTAB
-+#endif
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/system.h>
-+
-+/* Project header */
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_regs.h>
-+#include <asm/ifx/common_routines.h>
-+#include <asm/ifx/ifx_pmcu.h>
-+#include "ifxmips_pcie_pm.h"
-+
-+/**
-+ * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
-+ * \brief the callback function to request pmcu state in the power management hardware-dependent module
-+ *
-+ * \param pmcuState This parameter is a PMCU state.
-+ *
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
-+{
-+ switch(pmcuState)
-+ {
-+ case IFX_PMCU_STATE_D0:
-+ return IFX_PMCU_RETURN_SUCCESS;
-+ case IFX_PMCU_STATE_D1: // Not Applicable
-+ return IFX_PMCU_RETURN_DENIED;
-+ case IFX_PMCU_STATE_D2: // Not Applicable
-+ return IFX_PMCU_RETURN_DENIED;
-+ case IFX_PMCU_STATE_D3: // Module clock gating and Power gating
-+ return IFX_PMCU_RETURN_SUCCESS;
-+ default:
-+ return IFX_PMCU_RETURN_DENIED;
-+ }
-+}
-+
-+/**
-+ * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
-+ * \brief the callback function to get pmcu state in the power management hardware-dependent module
-+
-+ * \param pmcuState Pointer to return power state.
-+ *
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+ * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
-+ *
-+ * \param pmcuModule Module
-+ * \param newState New state
-+ * \param oldState Old state
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+ * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
-+ *
-+ * \param pmcuModule Module
-+ * \param newState New state
-+ * \param oldState Old state
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn static void ifx_pcie_pmcu_init(void)
-+ * \brief Register with central PMCU module
-+ * \return none
-+ * \ingroup IFX_PCIE_PM
-+ */
-+void
-+ifx_pcie_pmcu_init(void)
-+{
-+ IFX_PMCU_REGISTER_t pmcuRegister;
-+
-+ /* XXX, hook driver context */
-+
-+ /* State function register */
-+ memset(&pmcuRegister, 0, sizeof(IFX_PMCU_REGISTER_t));
-+ pmcuRegister.pmcuModule = IFX_PMCU_MODULE_PCIE;
-+ pmcuRegister.pmcuModuleNr = 0;
-+ pmcuRegister.ifx_pmcu_state_change = ifx_pcie_pmcu_state_change;
-+ pmcuRegister.ifx_pmcu_state_get = ifx_pcie_pmcu_state_get;
-+ pmcuRegister.pre = ifx_pcie_pmcu_prechange;
-+ pmcuRegister.post= ifx_pcie_pmcu_postchange;
-+ ifx_pmcu_register(&pmcuRegister);
-+}
-+
-+/**
-+ * \fn static void ifx_pcie_pmcu_exit(void)
-+ * \brief Unregister with central PMCU module
-+ *
-+ * \return none
-+ * \ingroup IFX_PCIE_PM
-+ */
-+void
-+ifx_pcie_pmcu_exit(void)
-+{
-+ IFX_PMCU_REGISTER_t pmcuUnRegister;
-+
-+ /* XXX, hook driver context */
-+
-+ pmcuUnRegister.pmcuModule = IFX_PMCU_MODULE_PCIE;
-+ pmcuUnRegister.pmcuModuleNr = 0;
-+ ifx_pmcu_unregister(&pmcuUnRegister);
-+}
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_pm.h
-@@ -0,0 +1,36 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_pm.h
-+** PROJECT : IFX UEIP
-+** MODULES : PCIe Root Complex Driver
-+**
-+** DATE : 21 Dec 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver Power Managment
-+** COPYRIGHT : Copyright (c) 2009
-+** Lantiq Deutschland GmbH
-+** Am Campeon 3, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 21 Dec,2009 Lei Chuanhua First UEIP release
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_pcie_pm.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe Root Complex Driver Power Management
-+*/
-+
-+#ifndef IFXMIPS_PCIE_PM_H
-+#define IFXMIPS_PCIE_PM_H
-+
-+void ifx_pcie_pmcu_init(void);
-+void ifx_pcie_pmcu_exit(void);
-+
-+#endif /* IFXMIPS_PCIE_PM_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_reg.h
-@@ -0,0 +1,1001 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_reg.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_REG_H
-+#define IFXMIPS_PCIE_REG_H
-+/*!
-+ \file ifxmips_pcie_reg.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module register definition
-+*/
-+/* PCIe Address Mapping Base */
-+#define PCIE_CFG_PHY_BASE 0x1D000000UL
-+#define PCIE_CFG_BASE (KSEG1 + PCIE_CFG_PHY_BASE)
-+#define PCIE_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE_MEM_PHY_BASE 0x1C000000UL
-+#define PCIE_MEM_BASE (KSEG1 + PCIE_MEM_PHY_BASE)
-+#define PCIE_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE_MEM_PHY_END (PCIE_MEM_PHY_BASE + PCIE_MEM_SIZE - 1)
-+
-+#define PCIE_IO_PHY_BASE 0x1D800000UL
-+#define PCIE_IO_BASE (KSEG1 + PCIE_IO_PHY_BASE)
-+#define PCIE_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE_IO_PHY_END (PCIE_IO_PHY_BASE + PCIE_IO_SIZE - 1)
-+
-+#define PCIE_RC_CFG_BASE (KSEG1 + 0x1D900000)
-+#define PCIE_APP_LOGIC_REG (KSEG1 + 0x1E100900)
-+#define PCIE_MSI_PHY_BASE 0x1F600000UL
-+
-+#define PCIE_PDI_PHY_BASE 0x1F106800UL
-+#define PCIE_PDI_BASE (KSEG1 + PCIE_PDI_PHY_BASE)
-+#define PCIE_PDI_SIZE 0x400
-+
-+#define PCIE1_CFG_PHY_BASE 0x19000000UL
-+#define PCIE1_CFG_BASE (KSEG1 + PCIE1_CFG_PHY_BASE)
-+#define PCIE1_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE1_MEM_PHY_BASE 0x18000000UL
-+#define PCIE1_MEM_BASE (KSEG1 + PCIE1_MEM_PHY_BASE)
-+#define PCIE1_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE1_MEM_PHY_END (PCIE1_MEM_PHY_BASE + PCIE1_MEM_SIZE - 1)
-+
-+#define PCIE1_IO_PHY_BASE 0x19800000UL
-+#define PCIE1_IO_BASE (KSEG1 + PCIE1_IO_PHY_BASE)
-+#define PCIE1_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE1_IO_PHY_END (PCIE1_IO_PHY_BASE + PCIE1_IO_SIZE - 1)
-+
-+#define PCIE1_RC_CFG_BASE (KSEG1 + 0x19900000)
-+#define PCIE1_APP_LOGIC_REG (KSEG1 + 0x1E100700)
-+#define PCIE1_MSI_PHY_BASE 0x1F400000UL
-+
-+#define PCIE1_PDI_PHY_BASE 0x1F700400UL
-+#define PCIE1_PDI_BASE (KSEG1 + PCIE1_PDI_PHY_BASE)
-+#define PCIE1_PDI_SIZE 0x400
-+
-+#define PCIE_CFG_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_CFG_BASE) : (PCIE_CFG_BASE))
-+#define PCIE_MEM_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_BASE) : (PCIE_MEM_BASE))
-+#define PCIE_IO_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_BASE) : (PCIE_IO_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_PHY_BASE) : (PCIE_MEM_PHY_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_MEM_PHY_END) : (PCIE_MEM_PHY_END))
-+#define PCIE_IO_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_PHY_BASE) : (PCIE_IO_PHY_BASE))
-+#define PCIE_IO_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_IO_PHY_END) : (PCIE_IO_PHY_END))
-+#define PCIE_APP_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_APP_LOGIC_REG) : (PCIE_APP_LOGIC_REG))
-+#define PCIE_RC_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_RC_CFG_BASE) : (PCIE_RC_CFG_BASE))
-+#define PCIE_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_PDI_BASE) : (PCIE_PDI_BASE))
-+
-+/* PCIe Application Logic Register */
-+/* RC Core Control Register */
-+#define PCIE_RC_CCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x10)
-+/* This should be enabled after initializing configuratin registers
-+ * Also should check link status retraining bit
-+ */
-+#define PCIE_RC_CCR_LTSSM_ENABLE 0x00000001 /* Enable LTSSM to continue link establishment */
-+
-+/* RC Core Debug Register */
-+#define PCIE_RC_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x14)
-+#define PCIE_RC_DR_DLL_UP 0x00000001 /* Data Link Layer Up */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE 0x0000000E /* Current Power State */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE_S 1
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE 0x000001F0 /* Current LTSSM State */
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE_S 4
-+
-+#define PCIE_RC_DR_PM_DEV_STATE 0x00000E00 /* Power Management D-State */
-+#define PCIE_RC_DR_PM_DEV_STATE_S 9
-+
-+#define PCIE_RC_DR_PM_ENABLED 0x00001000 /* Power Management State from PMU */
-+#define PCIE_RC_DR_PME_EVENT_ENABLED 0x00002000 /* Power Management Event Enable State */
-+#define PCIE_RC_DR_AUX_POWER_ENABLED 0x00004000 /* Auxiliary Power Enable */
-+
-+/* Current Power State Definition */
-+enum {
-+ PCIE_RC_DR_D0 = 0,
-+ PCIE_RC_DR_D1, /* Not supported */
-+ PCIE_RC_DR_D2, /* Not supported */
-+ PCIE_RC_DR_D3,
-+ PCIE_RC_DR_UN,
-+};
-+
-+/* PHY Link Status Register */
-+#define PCIE_PHY_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x18)
-+#define PCIE_PHY_SR_PHY_LINK_UP 0x00000001 /* PHY Link Up/Down Indicator */
-+
-+/* Electromechanical Control Register */
-+#define PCIE_EM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x1C)
-+#define PCIE_EM_CR_CARD_IS_PRESENT 0x00000001 /* Card Presence Detect State */
-+#define PCIE_EM_CR_MRL_OPEN 0x00000002 /* MRL Sensor State */
-+#define PCIE_EM_CR_POWER_FAULT_SET 0x00000004 /* Power Fault Detected */
-+#define PCIE_EM_CR_MRL_SENSOR_SET 0x00000008 /* MRL Sensor Changed */
-+#define PCIE_EM_CR_PRESENT_DETECT_SET 0x00000010 /* Card Presense Detect Changed */
-+#define PCIE_EM_CR_CMD_CPL_INT_SET 0x00000020 /* Command Complete Interrupt */
-+#define PCIE_EM_CR_SYS_INTERLOCK_SET 0x00000040 /* System Electromechanical IterLock Engaged */
-+#define PCIE_EM_CR_ATTENTION_BUTTON_SET 0x00000080 /* Attention Button Pressed */
-+
-+/* Interrupt Status Register */
-+#define PCIE_IR_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x20)
-+#define PCIE_IR_SR_PME_CAUSE_MSI 0x00000002 /* MSI caused by PME */
-+#define PCIE_IR_SR_HP_PME_WAKE_GEN 0x00000004 /* Hotplug PME Wake Generation */
-+#define PCIE_IR_SR_HP_MSI 0x00000008 /* Hotplug MSI */
-+#define PCIE_IR_SR_AHB_LU_ERR 0x00000030 /* AHB Bridge Lookup Error Signals */
-+#define PCIE_IR_SR_AHB_LU_ERR_S 4
-+#define PCIE_IR_SR_INT_MSG_NUM 0x00003E00 /* Interrupt Message Number */
-+#define PCIE_IR_SR_INT_MSG_NUM_S 9
-+#define PCIE_IR_SR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_IR_SR_AER_INT_MSG_NUM_S 27
-+
-+/* Message Control Register */
-+#define PCIE_MSG_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x30)
-+#define PCIE_MSG_CR_GEN_PME_TURN_OFF_MSG 0x00000001 /* Generate PME Turn Off Message */
-+#define PCIE_MSG_CR_GEN_UNLOCK_MSG 0x00000002 /* Generate Unlock Message */
-+
-+#define PCIE_VDM_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x34)
-+
-+/* Vendor-Defined Message Requester ID Register */
-+#define PCIE_VDM_RID(X) (PCIE_APP_PORT_TO_BASE (X) + 0x38)
-+#define PCIE_VDM_RID_VENROR_MSG_REQ_ID 0x0000FFFF
-+#define PCIE_VDM_RID_VDMRID_S 0
-+
-+/* ASPM Control Register */
-+#define PCIE_ASPM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x40)
-+#define PCIE_ASPM_CR_HOT_RST 0x00000001 /* Hot Reset Request to the downstream device */
-+#define PCIE_ASPM_CR_REQ_EXIT_L1 0x00000002 /* Request to Exit L1 */
-+#define PCIE_ASPM_CR_REQ_ENTER_L1 0x00000004 /* Request to Enter L1 */
-+
-+/* Vendor Message DW0 Register */
-+#define PCIE_VM_MSG_DW0(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x50)
-+#define PCIE_VM_MSG_DW0_TYPE 0x0000001F /* Message type */
-+#define PCIE_VM_MSG_DW0_TYPE_S 0
-+#define PCIE_VM_MSG_DW0_FORMAT 0x00000060 /* Format */
-+#define PCIE_VM_MSG_DW0_FORMAT_S 5
-+#define PCIE_VM_MSG_DW0_TC 0x00007000 /* Traffic Class */
-+#define PCIE_VM_MSG_DW0_TC_S 12
-+#define PCIE_VM_MSG_DW0_ATTR 0x000C0000 /* Atrributes */
-+#define PCIE_VM_MSG_DW0_ATTR_S 18
-+#define PCIE_VM_MSG_DW0_EP_TLP 0x00100000 /* Poisoned TLP */
-+#define PCIE_VM_MSG_DW0_TD 0x00200000 /* TLP Digest */
-+#define PCIE_VM_MSG_DW0_LEN 0xFFC00000 /* Length */
-+#define PCIE_VM_MSG_DW0_LEN_S 22
-+
-+/* Format Definition */
-+enum {
-+ PCIE_VM_MSG_FORMAT_00 = 0, /* 3DW Hdr, no data*/
-+ PCIE_VM_MSG_FORMAT_01, /* 4DW Hdr, no data */
-+ PCIE_VM_MSG_FORMAT_10, /* 3DW Hdr, with data */
-+ PCIE_VM_MSG_FORMAT_11, /* 4DW Hdr, with data */
-+};
-+
-+/* Traffic Class Definition */
-+enum {
-+ PCIE_VM_MSG_TC0 = 0,
-+ PCIE_VM_MSG_TC1,
-+ PCIE_VM_MSG_TC2,
-+ PCIE_VM_MSG_TC3,
-+ PCIE_VM_MSG_TC4,
-+ PCIE_VM_MSG_TC5,
-+ PCIE_VM_MSG_TC6,
-+ PCIE_VM_MSG_TC7,
-+};
-+
-+/* Attributes Definition */
-+enum {
-+ PCIE_VM_MSG_ATTR_00 = 0, /* RO and No Snoop cleared */
-+ PCIE_VM_MSG_ATTR_01, /* RO cleared , No Snoop set */
-+ PCIE_VM_MSG_ATTR_10, /* RO set, No Snoop cleared*/
-+ PCIE_VM_MSG_ATTR_11, /* RO and No Snoop set */
-+};
-+
-+/* Payload Size Definition */
-+#define PCIE_VM_MSG_LEN_MIN 0
-+#define PCIE_VM_MSG_LEN_MAX 1024
-+
-+/* Vendor Message DW1 Register */
-+#define PCIE_VM_MSG_DW1(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x54)
-+#define PCIE_VM_MSG_DW1_FUNC_NUM 0x00000070 /* Function Number */
-+#define PCIE_VM_MSG_DW1_FUNC_NUM_S 8
-+#define PCIE_VM_MSG_DW1_CODE 0x00FF0000 /* Message Code */
-+#define PCIE_VM_MSG_DW1_CODE_S 16
-+#define PCIE_VM_MSG_DW1_TAG 0xFF000000 /* Tag */
-+#define PCIE_VM_MSG_DW1_TAG_S 24
-+
-+#define PCIE_VM_MSG_DW2(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x58)
-+#define PCIE_VM_MSG_DW3(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x5C)
-+
-+/* Vendor Message Request Register */
-+#define PCIE_VM_MSG_REQR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x60)
-+#define PCIE_VM_MSG_REQR_REQ 0x00000001 /* Vendor Message Request */
-+
-+
-+/* AHB Slave Side Band Control Register */
-+#define PCIE_AHB_SSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x70)
-+#define PCIE_AHB_SSB_REQ_BCM 0x00000001 /* Slave Reques BCM filed */
-+#define PCIE_AHB_SSB_REQ_EP 0x00000002 /* Slave Reques EP filed */
-+#define PCIE_AHB_SSB_REQ_TD 0x00000004 /* Slave Reques TD filed */
-+#define PCIE_AHB_SSB_REQ_ATTR 0x00000018 /* Slave Reques Attribute number */
-+#define PCIE_AHB_SSB_REQ_ATTR_S 3
-+#define PCIE_AHB_SSB_REQ_TC 0x000000E0 /* Slave Request TC Field */
-+#define PCIE_AHB_SSB_REQ_TC_S 5
-+
-+/* AHB Master SideBand Ctrl Register */
-+#define PCIE_AHB_MSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x74)
-+#define PCIE_AHB_MSB_RESP_ATTR 0x00000003 /* Master Response Attribute number */
-+#define PCIE_AHB_MSB_RESP_ATTR_S 0
-+#define PCIE_AHB_MSB_RESP_BAD_EOT 0x00000004 /* Master Response Badeot filed */
-+#define PCIE_AHB_MSB_RESP_BCM 0x00000008 /* Master Response BCM filed */
-+#define PCIE_AHB_MSB_RESP_EP 0x00000010 /* Master Response EP filed */
-+#define PCIE_AHB_MSB_RESP_TD 0x00000020 /* Master Response TD filed */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM 0x000003C0 /* Master Response Function number */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM_S 6
-+
-+/* AHB Control Register, fixed bus enumeration exception */
-+#define PCIE_AHB_CTRL(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x78)
-+#define PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS 0x00000001
-+
-+/* Interrupt Enalbe Register */
-+#define PCIE_IRNEN(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF4)
-+#define PCIE_IRNCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF8)
-+#define PCIE_IRNICR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xFC)
-+
-+/* PCIe interrupt enable/control/capture register definition */
-+#define PCIE_IRN_AER_REPORT 0x00000001 /* AER Interrupt */
-+#define PCIE_IRN_AER_MSIX 0x00000002 /* Advanced Error MSI-X Interrupt */
-+#define PCIE_IRN_PME 0x00000004 /* PME Interrupt */
-+#define PCIE_IRN_HOTPLUG 0x00000008 /* Hotplug Interrupt */
-+#define PCIE_IRN_RX_VDM_MSG 0x00000010 /* Vendor-Defined Message Interrupt */
-+#define PCIE_IRN_RX_CORRECTABLE_ERR_MSG 0x00000020 /* Correctable Error Message Interrupt */
-+#define PCIE_IRN_RX_NON_FATAL_ERR_MSG 0x00000040 /* Non-fatal Error Message */
-+#define PCIE_IRN_RX_FATAL_ERR_MSG 0x00000080 /* Fatal Error Message */
-+#define PCIE_IRN_RX_PME_MSG 0x00000100 /* PME Message Interrupt */
-+#define PCIE_IRN_RX_PME_TURNOFF_ACK 0x00000200 /* PME Turnoff Ack Message Interrupt */
-+#define PCIE_IRN_AHB_BR_FATAL_ERR 0x00000400 /* AHB Fatal Error Interrupt */
-+#define PCIE_IRN_LINK_AUTO_BW_STATUS 0x00000800 /* Link Auto Bandwidth Status Interrupt */
-+#define PCIE_IRN_BW_MGT 0x00001000 /* Bandwidth Managment Interrupt */
-+#define PCIE_IRN_INTA 0x00002000 /* INTA */
-+#define PCIE_IRN_INTB 0x00004000 /* INTB */
-+#define PCIE_IRN_INTC 0x00008000 /* INTC */
-+#define PCIE_IRN_INTD 0x00010000 /* INTD */
-+#define PCIE_IRN_WAKEUP 0x00020000 /* Wake up Interrupt */
-+
-+#define PCIE_RC_CORE_COMBINED_INT (PCIE_IRN_AER_REPORT | PCIE_IRN_AER_MSIX | PCIE_IRN_PME | \
-+ PCIE_IRN_HOTPLUG | PCIE_IRN_RX_VDM_MSG | PCIE_IRN_RX_CORRECTABLE_ERR_MSG |\
-+ PCIE_IRN_RX_NON_FATAL_ERR_MSG | PCIE_IRN_RX_FATAL_ERR_MSG | \
-+ PCIE_IRN_RX_PME_MSG | PCIE_IRN_RX_PME_TURNOFF_ACK | PCIE_IRN_AHB_BR_FATAL_ERR | \
-+ PCIE_IRN_LINK_AUTO_BW_STATUS | PCIE_IRN_BW_MGT)
-+/* PCIe RC Configuration Register */
-+#define PCIE_VDID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x00)
-+
-+/* Bit definition from pci_reg.h */
-+#define PCIE_PCICMDSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x04)
-+#define PCIE_CCRID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x08)
-+#define PCIE_CLSLTHTBR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x0C) /* EP only */
-+/* BAR0, BAR1,Only necessary if the bridges implements a device-specific register set or memory buffer */
-+#define PCIE_BAR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10) /* Not used*/
-+#define PCIE_BAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14) /* Not used */
-+
-+#define PCIE_BNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x18) /* Mandatory */
-+/* Bus Number Register bits */
-+#define PCIE_BNR_PRIMARY_BUS_NUM 0x000000FF
-+#define PCIE_BNR_PRIMARY_BUS_NUM_S 0
-+#define PCIE_PNR_SECONDARY_BUS_NUM 0x0000FF00
-+#define PCIE_PNR_SECONDARY_BUS_NUM_S 8
-+#define PCIE_PNR_SUB_BUS_NUM 0x00FF0000
-+#define PCIE_PNR_SUB_BUS_NUM_S 16
-+
-+/* IO Base/Limit Register bits */
-+#define PCIE_IOBLSECS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x1C) /* RC only */
-+#define PCIE_IOBLSECS_32BIT_IO_ADDR 0x00000001
-+#define PCIE_IOBLSECS_IO_BASE_ADDR 0x000000F0
-+#define PCIE_IOBLSECS_IO_BASE_ADDR_S 4
-+#define PCIE_IOBLSECS_32BIT_IOLIMT 0x00000100
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR 0x0000F000
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR_S 12
-+
-+/* Non-prefetchable Memory Base/Limit Register bit */
-+#define PCIE_MBML(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x20) /* RC only */
-+#define PCIE_MBML_MEM_BASE_ADDR 0x0000FFF0
-+#define PCIE_MBML_MEM_BASE_ADDR_S 4
-+#define PCIE_MBML_MEM_LIMIT_ADDR 0xFFF00000
-+#define PCIE_MBML_MEM_LIMIT_ADDR_S 20
-+
-+/* Prefetchable Memory Base/Limit Register bit */
-+#define PCIE_PMBL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x24) /* RC only */
-+#define PCIE_PMBL_64BIT_ADDR 0x00000001
-+#define PCIE_PMBL_UPPER_12BIT 0x0000FFF0
-+#define PCIE_PMBL_UPPER_12BIT_S 4
-+#define PCIE_PMBL_E64MA 0x00010000
-+#define PCIE_PMBL_END_ADDR 0xFFF00000
-+#define PCIE_PMBL_END_ADDR_S 20
-+#define PCIE_PMBU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x28) /* RC only */
-+#define PCIE_PMLU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x2C) /* RC only */
-+
-+/* I/O Base/Limit Upper 16 bits register */
-+#define PCIE_IO_BANDL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x30) /* RC only */
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE 0x0000FFFF
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE_S 0
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT 0xFFFF0000
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT_S 16
-+
-+#define PCIE_CPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x34)
-+#define PCIE_EBBAR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x38)
-+
-+/* Interrupt and Secondary Bridge Control Register */
-+#define PCIE_INTRBCTRL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x3C)
-+
-+#define PCIE_INTRBCTRL_INT_LINE 0x000000FF
-+#define PCIE_INTRBCTRL_INT_LINE_S 0
-+#define PCIE_INTRBCTRL_INT_PIN 0x0000FF00
-+#define PCIE_INTRBCTRL_INT_PIN_S 8
-+#define PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE 0x00010000 /* #PERR */
-+#define PCIE_INTRBCTRL_SERR_ENABLE 0x00020000 /* #SERR */
-+#define PCIE_INTRBCTRL_ISA_ENABLE 0x00040000 /* ISA enable, IO 64KB only */
-+#define PCIE_INTRBCTRL_VGA_ENABLE 0x00080000 /* VGA enable */
-+#define PCIE_INTRBCTRL_VGA_16BIT_DECODE 0x00100000 /* VGA 16bit decode */
-+#define PCIE_INTRBCTRL_RST_SECONDARY_BUS 0x00400000 /* Secondary bus rest, hot rest, 1ms */
-+/* Others are read only */
-+enum {
-+ PCIE_INTRBCTRL_INT_NON = 0,
-+ PCIE_INTRBCTRL_INTA,
-+ PCIE_INTRBCTRL_INTB,
-+ PCIE_INTRBCTRL_INTC,
-+ PCIE_INTRBCTRL_INTD,
-+};
-+
-+#define PCIE_PM_CAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x40)
-+
-+/* Power Management Control and Status Register */
-+#define PCIE_PM_CSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x44)
-+
-+#define PCIE_PM_CSR_POWER_STATE 0x00000003 /* Power State */
-+#define PCIE_PM_CSR_POWER_STATE_S 0
-+#define PCIE_PM_CSR_SW_RST 0x00000008 /* Soft Reset Enabled */
-+#define PCIE_PM_CSR_PME_ENABLE 0x00000100 /* PME Enable */
-+#define PCIE_PM_CSR_PME_STATUS 0x00008000 /* PME status */
-+
-+/* MSI Capability Register for EP */
-+#define PCIE_MCAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x50)
-+
-+#define PCIE_MCAPR_MSI_CAP_ID 0x000000FF /* MSI Capability ID */
-+#define PCIE_MCAPR_MSI_CAP_ID_S 0
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR_S 8
-+#define PCIE_MCAPR_MSI_ENABLE 0x00010000 /* MSI Enable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP 0x000E0000 /* Multiple Message Capable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP_S 17
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE 0x00700000 /* Multiple Message Enable */
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE_S 20
-+#define PCIE_MCAPR_ADDR64_CAP 0X00800000 /* 64-bit Address Capable */
-+
-+/* MSI Message Address Register */
-+#define PCIE_MA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x54)
-+
-+#define PCIE_MA_ADDR_MASK 0xFFFFFFFC /* Message Address */
-+
-+/* MSI Message Upper Address Register */
-+#define PCIE_MUA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x58)
-+
-+/* MSI Message Data Register */
-+#define PCIE_MD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x5C)
-+
-+#define PCIE_MD_DATA 0x0000FFFF /* Message Data */
-+#define PCIE_MD_DATA_S 0
-+
-+/* PCI Express Capability Register */
-+#define PCIE_XCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70)
-+
-+#define PCIE_XCAP_ID 0x000000FF /* PCI Express Capability ID */
-+#define PCIE_XCAP_ID_S 0
-+#define PCIE_XCAP_NEXT_CAP 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_XCAP_NEXT_CAP_S 8
-+#define PCIE_XCAP_VER 0x000F0000 /* PCI Express Capability Version */
-+#define PCIE_XCAP_VER_S 16
-+#define PCIE_XCAP_DEV_PORT_TYPE 0x00F00000 /* Device Port Type */
-+#define PCIE_XCAP_DEV_PORT_TYPE_S 20
-+#define PCIE_XCAP_SLOT_IMPLEMENTED 0x01000000 /* Slot Implemented */
-+#define PCIE_XCAP_MSG_INT_NUM 0x3E000000 /* Interrupt Message Number */
-+#define PCIE_XCAP_MSG_INT_NUM_S 25
-+
-+/* Device Capability Register */
-+#define PCIE_DCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74)
-+
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE 0x00000007 /* Max Payload size */
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE_S 0
-+#define PCIE_DCAP_PHANTOM_FUNC 0x00000018 /* Phanton Function, not supported */
-+#define PCIE_DCAP_PHANTOM_FUNC_S 3
-+#define PCIE_DCAP_EXT_TAG 0x00000020 /* Extended Tag Field */
-+#define PCIE_DCAP_EP_L0S_LATENCY 0x000001C0 /* EP L0s latency only */
-+#define PCIE_DCAP_EP_L0S_LATENCY_S 6
-+#define PCIE_DCAP_EP_L1_LATENCY 0x00000E00 /* EP L1 latency only */
-+#define PCIE_DCAP_EP_L1_LATENCY_S 9
-+#define PCIE_DCAP_ROLE_BASE_ERR_REPORT 0x00008000 /* Role Based ERR */
-+
-+/* Maximum payload size supported */
-+enum {
-+ PCIE_MAX_PAYLOAD_128 = 0,
-+ PCIE_MAX_PAYLOAD_256,
-+ PCIE_MAX_PAYLOAD_512,
-+ PCIE_MAX_PAYLOAD_1024,
-+ PCIE_MAX_PAYLOAD_2048,
-+ PCIE_MAX_PAYLOAD_4096,
-+};
-+
-+/* Device Control and Status Register */
-+#define PCIE_DCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x78)
-+
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR_EN 0x00000001 /* COR-ERR */
-+#define PCIE_DCTLSTS_NONFATAL_ERR_EN 0x00000002 /* Non-fatal ERR */
-+#define PCIE_DCTLSTS_FATAL_ERR_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_DCTLSYS_UR_REQ_EN 0x00000008 /* UR ERR */
-+#define PCIE_DCTLSTS_RELAXED_ORDERING_EN 0x00000010 /* Enable relaxing ordering */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE 0x000000E0 /* Max payload mask */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE_S 5
-+#define PCIE_DCTLSTS_EXT_TAG_EN 0x00000100 /* Extended tag field */
-+#define PCIE_DCTLSTS_PHANTOM_FUNC_EN 0x00000200 /* Phantom Function Enable */
-+#define PCIE_DCTLSTS_AUX_PM_EN 0x00000400 /* AUX Power PM Enable */
-+#define PCIE_DCTLSTS_NO_SNOOP_EN 0x00000800 /* Enable no snoop, except root port*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE 0x00007000 /* Max Read Request size*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE_S 12
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR 0x00010000 /* COR-ERR Detected */
-+#define PCIE_DCTLSTS_NONFATAL_ERR 0x00020000 /* Non-Fatal ERR Detected */
-+#define PCIE_DCTLSTS_FATAL_ER 0x00040000 /* Fatal ERR Detected */
-+#define PCIE_DCTLSTS_UNSUPPORTED_REQ 0x00080000 /* UR Detected */
-+#define PCIE_DCTLSTS_AUX_POWER 0x00100000 /* Aux Power Detected */
-+#define PCIE_DCTLSTS_TRANSACT_PENDING 0x00200000 /* Transaction pending */
-+
-+#define PCIE_DCTLSTS_ERR_EN (PCIE_DCTLSTS_CORRECTABLE_ERR_EN | \
-+ PCIE_DCTLSTS_NONFATAL_ERR_EN | PCIE_DCTLSTS_FATAL_ERR_EN | \
-+ PCIE_DCTLSYS_UR_REQ_EN)
-+
-+/* Link Capability Register */
-+#define PCIE_LCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7C)
-+#define PCIE_LCAP_MAX_LINK_SPEED 0x0000000F /* Max link speed, 0x1 by default */
-+#define PCIE_LCAP_MAX_LINK_SPEED_S 0
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH 0x000003F0 /* Maxium Length Width */
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH_S 4
-+#define PCIE_LCAP_ASPM_LEVEL 0x00000C00 /* Active State Link PM Support */
-+#define PCIE_LCAP_ASPM_LEVEL_S 10
-+#define PCIE_LCAP_L0S_EIXT_LATENCY 0x00007000 /* L0s Exit Latency */
-+#define PCIE_LCAP_L0S_EIXT_LATENCY_S 12
-+#define PCIE_LCAP_L1_EXIT_LATENCY 0x00038000 /* L1 Exit Latency */
-+#define PCIE_LCAP_L1_EXIT_LATENCY_S 15
-+#define PCIE_LCAP_CLK_PM 0x00040000 /* Clock Power Management */
-+#define PCIE_LCAP_SDER 0x00080000 /* Surprise Down Error Reporting */
-+#define PCIE_LCAP_DLL_ACTIVE_REPROT 0x00100000 /* Data Link Layer Active Reporting Capable */
-+#define PCIE_LCAP_PORT_NUM 0xFF0000000 /* Port number */
-+#define PCIE_LCAP_PORT_NUM_S 24
-+
-+/* Maximum Length width definition */
-+#define PCIE_MAX_LENGTH_WIDTH_RES 0x00
-+#define PCIE_MAX_LENGTH_WIDTH_X1 0x01 /* Default */
-+#define PCIE_MAX_LENGTH_WIDTH_X2 0x02
-+#define PCIE_MAX_LENGTH_WIDTH_X4 0x04
-+#define PCIE_MAX_LENGTH_WIDTH_X8 0x08
-+#define PCIE_MAX_LENGTH_WIDTH_X12 0x0C
-+#define PCIE_MAX_LENGTH_WIDTH_X16 0x10
-+#define PCIE_MAX_LENGTH_WIDTH_X32 0x20
-+
-+/* Active State Link PM definition */
-+enum {
-+ PCIE_ASPM_RES0 = 0,
-+ PCIE_ASPM_L0S_ENTRY_SUPPORT, /* L0s */
-+ PCIE_ASPM_RES1,
-+ PCIE_ASPM_L0S_L1_ENTRY_SUPPORT, /* L0s and L1, default */
-+};
-+
-+/* L0s Exit Latency definition */
-+enum {
-+ PCIE_L0S_EIXT_LATENCY_L64NS = 0, /* < 64 ns */
-+ PCIE_L0S_EIXT_LATENCY_B64A128, /* > 64 ns < 128 ns */
-+ PCIE_L0S_EIXT_LATENCY_B128A256, /* > 128 ns < 256 ns */
-+ PCIE_L0S_EIXT_LATENCY_B256A512, /* > 256 ns < 512 ns */
-+ PCIE_L0S_EIXT_LATENCY_B512TO1U, /* > 512 ns < 1 us */
-+ PCIE_L0S_EIXT_LATENCY_B1A2U, /* > 1 us < 2 us */
-+ PCIE_L0S_EIXT_LATENCY_B2A4U, /* > 2 us < 4 us */
-+ PCIE_L0S_EIXT_LATENCY_M4US, /* > 4 us */
-+};
-+
-+/* L1 Exit Latency definition */
-+enum {
-+ PCIE_L1_EXIT_LATENCY_L1US = 0, /* < 1 us */
-+ PCIE_L1_EXIT_LATENCY_B1A2, /* > 1 us < 2 us */
-+ PCIE_L1_EXIT_LATENCY_B2A4, /* > 2 us < 4 us */
-+ PCIE_L1_EXIT_LATENCY_B4A8, /* > 4 us < 8 us */
-+ PCIE_L1_EXIT_LATENCY_B8A16, /* > 8 us < 16 us */
-+ PCIE_L1_EXIT_LATENCY_B16A32, /* > 16 us < 32 us */
-+ PCIE_L1_EXIT_LATENCY_B32A64, /* > 32 us < 64 us */
-+ PCIE_L1_EXIT_LATENCY_M64US, /* > 64 us */
-+};
-+
-+/* Link Control and Status Register */
-+#define PCIE_LCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x80)
-+#define PCIE_LCTLSTS_ASPM_ENABLE 0x00000003 /* Active State Link PM Control */
-+#define PCIE_LCTLSTS_ASPM_ENABLE_S 0
-+#define PCIE_LCTLSTS_RCB128 0x00000008 /* Read Completion Boundary 128*/
-+#define PCIE_LCTLSTS_LINK_DISABLE 0x00000010 /* Link Disable */
-+#define PCIE_LCTLSTS_RETRIAN_LINK 0x00000020 /* Retrain Link */
-+#define PCIE_LCTLSTS_COM_CLK_CFG 0x00000040 /* Common Clock Configuration */
-+#define PCIE_LCTLSTS_EXT_SYNC 0x00000080 /* Extended Synch */
-+#define PCIE_LCTLSTS_CLK_PM_EN 0x00000100 /* Enable Clock Powerm Management */
-+#define PCIE_LCTLSTS_LINK_SPEED 0x000F0000 /* Link Speed */
-+#define PCIE_LCTLSTS_LINK_SPEED_S 16
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH 0x03F00000 /* Negotiated Link Width */
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH_S 20
-+#define PCIE_LCTLSTS_RETRAIN_PENDING 0x08000000 /* Link training is ongoing */
-+#define PCIE_LCTLSTS_SLOT_CLK_CFG 0x10000000 /* Slot Clock Configuration */
-+#define PCIE_LCTLSTS_DLL_ACTIVE 0x20000000 /* Data Link Layer Active */
-+
-+/* Slot Capabilities Register */
-+#define PCIE_SLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x84)
-+
-+/* Slot Capabilities */
-+#define PCIE_SLCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x88)
-+
-+/* Root Control and Capability Register */
-+#define PCIE_RCTLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x8C)
-+#define PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR 0x00000001 /* #SERR on COR-ERR */
-+#define PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR 0x00000002 /* #SERR on Non-Fatal ERR */
-+#define PCIE_RCTLCAP_SERR_ON_FATAL_ERR 0x00000004 /* #SERR on Fatal ERR */
-+#define PCIE_RCTLCAP_PME_INT_EN 0x00000008 /* PME Interrupt Enable */
-+#define PCIE_RCTLCAP_SERR_ENABLE (PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR | \
-+ PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR | PCIE_RCTLCAP_SERR_ON_FATAL_ERR)
-+/* Root Status Register */
-+#define PCIE_RSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x90)
-+#define PCIE_RSTS_PME_REQ_ID 0x0000FFFF /* PME Request ID */
-+#define PCIE_RSTS_PME_REQ_ID_S 0
-+#define PCIE_RSTS_PME_STATUS 0x00010000 /* PME Status */
-+#define PCIE_RSTS_PME_PENDING 0x00020000 /* PME Pending */
-+
-+/* PCI Express Enhanced Capability Header */
-+#define PCIE_ENHANCED_CAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x100)
-+#define PCIE_ENHANCED_CAP_ID 0x0000FFFF /* PCI Express Extended Capability ID */
-+#define PCIE_ENHANCED_CAP_ID_S 0
-+#define PCIE_ENHANCED_CAP_VER 0x000F0000 /* Capability Version */
-+#define PCIE_ENHANCED_CAP_VER_S 16
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET 0xFFF00000 /* Next Capability Offset */
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET_S 20
-+
-+/* Uncorrectable Error Status Register */
-+#define PCIE_UES_R(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x104)
-+#define PCIE_DATA_LINK_PROTOCOL_ERR 0x00000010 /* Data Link Protocol Error Status */
-+#define PCIE_SURPRISE_DOWN_ERROR 0x00000020 /* Surprise Down Error Status */
-+#define PCIE_POISONED_TLP 0x00001000 /* Poisoned TLP Status */
-+#define PCIE_FC_PROTOCOL_ERR 0x00002000 /* Flow Control Protocol Error Status */
-+#define PCIE_COMPLETION_TIMEOUT 0x00004000 /* Completion Timeout Status */
-+#define PCIE_COMPLETOR_ABORT 0x00008000 /* Completer Abort Error */
-+#define PCIE_UNEXPECTED_COMPLETION 0x00010000 /* Unexpected Completion Status */
-+#define PCIE_RECEIVER_OVERFLOW 0x00020000 /* Receive Overflow Status */
-+#define PCIE_MALFORNED_TLP 0x00040000 /* Malformed TLP Stauts */
-+#define PCIE_ECRC_ERR 0x00080000 /* ECRC Error Stauts */
-+#define PCIE_UR_REQ 0x00100000 /* Unsupported Request Error Status */
-+#define PCIE_ALL_UNCORRECTABLE_ERR (PCIE_DATA_LINK_PROTOCOL_ERR | PCIE_SURPRISE_DOWN_ERROR | \
-+ PCIE_POISONED_TLP | PCIE_FC_PROTOCOL_ERR | PCIE_COMPLETION_TIMEOUT | \
-+ PCIE_COMPLETOR_ABORT | PCIE_UNEXPECTED_COMPLETION | PCIE_RECEIVER_OVERFLOW |\
-+ PCIE_MALFORNED_TLP | PCIE_ECRC_ERR | PCIE_UR_REQ)
-+
-+/* Uncorrectable Error Mask Register, Mask means no report */
-+#define PCIE_UEMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x108)
-+
-+/* Uncorrectable Error Severity Register */
-+#define PCIE_UESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10C)
-+
-+/* Correctable Error Status Register */
-+#define PCIE_CESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x110)
-+#define PCIE_RX_ERR 0x00000001 /* Receive Error Status */
-+#define PCIE_BAD_TLP 0x00000040 /* Bad TLP Status */
-+#define PCIE_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-+#define PCIE_REPLAY_NUM_ROLLOVER 0x00000100 /* Replay Number Rollover Status */
-+#define PCIE_REPLAY_TIMER_TIMEOUT_ERR 0x00001000 /* Reply Timer Timeout Status */
-+#define PCIE_ADVISORY_NONFTAL_ERR 0x00002000 /* Advisory Non-Fatal Error Status */
-+#define PCIE_CORRECTABLE_ERR (PCIE_RX_ERR | PCIE_BAD_TLP | PCIE_BAD_DLLP | PCIE_REPLAY_NUM_ROLLOVER |\
-+ PCIE_REPLAY_TIMER_TIMEOUT_ERR | PCIE_ADVISORY_NONFTAL_ERR)
-+
-+/* Correctable Error Mask Register */
-+#define PCIE_CEMR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x114)
-+
-+/* Advanced Error Capabilities and Control Register */
-+#define PCIE_AECCR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x118)
-+#define PCIE_AECCR_FIRST_ERR_PTR 0x0000001F /* First Error Pointer */
-+#define PCIE_AECCR_FIRST_ERR_PTR_S 0
-+#define PCIE_AECCR_ECRC_GEN_CAP 0x00000020 /* ECRC Generation Capable */
-+#define PCIE_AECCR_ECRC_GEN_EN 0x00000040 /* ECRC Generation Enable */
-+#define PCIE_AECCR_ECRC_CHECK_CAP 0x00000080 /* ECRC Check Capable */
-+#define PCIE_AECCR_ECRC_CHECK_EN 0x00000100 /* ECRC Check Enable */
-+
-+/* Header Log Register 1 */
-+#define PCIE_HLR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x11C)
-+
-+/* Header Log Register 2 */
-+#define PCIE_HLR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x120)
-+
-+/* Header Log Register 3 */
-+#define PCIE_HLR3(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x124)
-+
-+/* Header Log Register 4 */
-+#define PCIE_HLR4(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x128)
-+
-+/* Root Error Command Register */
-+#define PCIE_RECR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x12C)
-+#define PCIE_RECR_CORRECTABLE_ERR_REPORT_EN 0x00000001 /* COR-ERR */
-+#define PCIE_RECR_NONFATAL_ERR_REPORT_EN 0x00000002 /* Non-Fatal ERR */
-+#define PCIE_RECR_FATAL_ERR_REPORT_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_RECR_ERR_REPORT_EN (PCIE_RECR_CORRECTABLE_ERR_REPORT_EN | \
-+ PCIE_RECR_NONFATAL_ERR_REPORT_EN | PCIE_RECR_FATAL_ERR_REPORT_EN)
-+
-+/* Root Error Status Register */
-+#define PCIE_RESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x130)
-+#define PCIE_RESR_CORRECTABLE_ERR 0x00000001 /* COR-ERR Receveid */
-+#define PCIE_RESR_MULTI_CORRECTABLE_ERR 0x00000002 /* Multiple COR-ERR Received */
-+#define PCIE_RESR_FATAL_NOFATAL_ERR 0x00000004 /* ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_MULTI_FATAL_NOFATAL_ERR 0x00000008 /* Multiple ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_FIRST_UNCORRECTABLE_FATAL_ERR 0x00000010 /* First UN-COR Fatal */
-+#define PCIR_RESR_NON_FATAL_ERR 0x00000020 /* Non-Fatal Error Message Received */
-+#define PCIE_RESR_FATAL_ERR 0x00000040 /* Fatal Message Received */
-+#define PCIE_RESR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_RESR_AER_INT_MSG_NUM_S 27
-+
-+/* Error Source Indentification Register */
-+#define PCIE_ESIR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x134)
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID 0x0000FFFF
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID_S 0
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID 0xFFFF0000
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID_S 16
-+
-+/* VC Enhanced Capability Header */
-+#define PCIE_VC_ECH(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x140)
-+
-+/* Port VC Capability Register */
-+#define PCIE_PVC1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x144)
-+#define PCIE_PVC1_EXT_VC_CNT 0x00000007 /* Extended VC Count */
-+#define PCIE_PVC1_EXT_VC_CNT_S 0
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT 0x00000070 /* Low Priority Extended VC Count */
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT_S 4
-+#define PCIE_PVC1_REF_CLK 0x00000300 /* Reference Clock */
-+#define PCIE_PVC1_REF_CLK_S 8
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE 0x00000C00 /* Port Arbitration Table Entry Size */
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE_S 10
-+
-+/* Extended Virtual Channel Count Defintion */
-+#define PCIE_EXT_VC_CNT_MIN 0
-+#define PCIE_EXT_VC_CNT_MAX 7
-+
-+/* Port Arbitration Table Entry Size Definition */
-+enum {
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S1BIT = 0,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S2BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S4BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S8BIT,
-+};
-+
-+/* Port VC Capability Register 2 */
-+#define PCIE_PVC2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x148)
-+#define PCIE_PVC2_VC_ARB_16P_FIXED_WRR 0x00000001 /* HW Fixed arbitration, 16 phase WRR */
-+#define PCIE_PVC2_VC_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_PVC2_VC_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_PVC2_VC_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_PVC2_VC_ARB_WRR 0x0000000F
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET 0xFF000000 /* VC arbitration table offset, not support */
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET_S 24
-+
-+/* Port VC Control and Status Register */
-+#define PCIE_PVCCRSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14C)
-+#define PCIE_PVCCRSR_LOAD_VC_ARB_TAB 0x00000001 /* Load VC Arbitration Table */
-+#define PCIE_PVCCRSR_VC_ARB_SEL 0x0000000E /* VC Arbitration Select */
-+#define PCIE_PVCCRSR_VC_ARB_SEL_S 1
-+#define PCIE_PVCCRSR_VC_ARB_TAB_STATUS 0x00010000 /* Arbitration Status */
-+
-+/* VC0 Resource Capability Register */
-+#define PCIE_VC0_RC(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x150)
-+#define PCIE_VC0_RC_PORT_ARB_HW_FIXED 0x00000001 /* HW Fixed arbitration */
-+#define PCIE_VC0_RC_PORT_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_128P_WRR 0x00000010 /* Time-based 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_256P_WRR 0x00000020 /* Time-based 256 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB (PCIE_VC0_RC_PORT_ARB_HW_FIXED | PCIE_VC0_RC_PORT_ARB_32P_WRR |\
-+ PCIE_VC0_RC_PORT_ARB_64P_WRR | PCIE_VC0_RC_PORT_ARB_128P_WRR | \
-+ PCIE_VC0_RC_PORT_ARB_TM_128P_WRR | PCIE_VC0_RC_PORT_ARB_TM_256P_WRR)
-+
-+#define PCIE_VC0_RC_REJECT_SNOOP 0x00008000 /* Reject Snoop Transactioin */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS 0x007F0000 /* Maximum time Slots */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS_S 16
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET 0xFF000000 /* Port Arbitration Table Offset */
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET_S 24
-+
-+/* VC0 Resource Control Register */
-+#define PCIE_VC0_RC0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x154)
-+#define PCIE_VC0_RC0_TVM0 0x00000001 /* TC0 and VC0 */
-+#define PCIE_VC0_RC0_TVM1 0x00000002 /* TC1 and VC1 */
-+#define PCIE_VC0_RC0_TVM2 0x00000004 /* TC2 and VC2 */
-+#define PCIE_VC0_RC0_TVM3 0x00000008 /* TC3 and VC3 */
-+#define PCIE_VC0_RC0_TVM4 0x00000010 /* TC4 and VC4 */
-+#define PCIE_VC0_RC0_TVM5 0x00000020 /* TC5 and VC5 */
-+#define PCIE_VC0_RC0_TVM6 0x00000040 /* TC6 and VC6 */
-+#define PCIE_VC0_RC0_TVM7 0x00000080 /* TC7 and VC7 */
-+#define PCIE_VC0_RC0_TC_VC 0x000000FF /* TC/VC mask */
-+
-+#define PCIE_VC0_RC0_LOAD_PORT_ARB_TAB 0x00010000 /* Load Port Arbitration Table */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL 0x000E0000 /* Port Arbitration Select */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL_S 17
-+#define PCIE_VC0_RC0_VC_ID 0x07000000 /* VC ID */
-+#define PCIE_VC0_RC0_VC_ID_S 24
-+#define PCIE_VC0_RC0_VC_EN 0x80000000 /* VC Enable */
-+
-+/* VC0 Resource Status Register */
-+#define PCIE_VC0_RSR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x158)
-+#define PCIE_VC0_RSR0_PORT_ARB_TAB_STATUS 0x00010000 /* Port Arbitration Table Status,not used */
-+#define PCIE_VC0_RSR0_VC_NEG_PENDING 0x00020000 /* VC Negotiation Pending */
-+
-+/* Ack Latency Timer and Replay Timer Register */
-+#define PCIE_ALTRT(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x700)
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT 0x0000FFFF /* Round Trip Latency Time Limit */
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT_S 0
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT 0xFFFF0000 /* Replay Time Limit */
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT_S 16
-+
-+/* Other Message Register */
-+#define PCIE_OMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x704)
-+
-+/* Port Force Link Register */
-+#define PCIE_PFLR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x708)
-+#define PCIE_PFLR_LINK_NUM 0x000000FF /* Link Number */
-+#define PCIE_PFLR_LINK_NUM_S 0
-+#define PCIE_PFLR_FORCE_LINK 0x00008000 /* Force link */
-+#define PCIE_PFLR_LINK_STATE 0x003F0000 /* Link State */
-+#define PCIE_PFLR_LINK_STATE_S 16
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT 0xFF000000 /* Low Power Entrance Count, only for EP */
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT_S 24
-+
-+/* Ack Frequency Register */
-+#define PCIE_AFR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70C)
-+#define PCIE_AFR_AF 0x000000FF /* Ack Frequency */
-+#define PCIE_AFR_AF_S 0
-+#define PCIE_AFR_FTS_NUM 0x0000FF00 /* The number of Fast Training Sequence from L0S to L0 */
-+#define PCIE_AFR_FTS_NUM_S 8
-+#define PCIE_AFR_COM_FTS_NUM 0x00FF0000 /* N_FTS; when common clock is used*/
-+#define PCIE_AFR_COM_FTS_NUM_S 16
-+#define PCIE_AFR_L0S_ENTRY_LATENCY 0x07000000 /* L0s Entrance Latency */
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_S 24
-+#define PCIE_AFR_L1_ENTRY_LATENCY 0x38000000 /* L1 Entrance Latency */
-+#define PCIE_AFR_L1_ENTRY_LATENCY_S 27
-+#define PCIE_AFR_FTS_NUM_DEFAULT 32
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT 7
-+#define PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT 5
-+
-+/* Port Link Control Register */
-+#define PCIE_PLCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x710)
-+#define PCIE_PLCR_OTHER_MSG_REQ 0x00000001 /* Other Message Request */
-+#define PCIE_PLCR_SCRAMBLE_DISABLE 0x00000002 /* Scramble Disable */
-+#define PCIE_PLCR_LOOPBACK_EN 0x00000004 /* Loopback Enable */
-+#define PCIE_PLCR_LTSSM_HOT_RST 0x00000008 /* Force LTSSM to the hot reset */
-+#define PCIE_PLCR_DLL_LINK_EN 0x00000020 /* Enable Link initialization */
-+#define PCIE_PLCR_FAST_LINK_SIM_EN 0x00000080 /* Sets all internal timers to fast mode for simulation purposes */
-+#define PCIE_PLCR_LINK_MODE 0x003F0000 /* Link Mode Enable Mask */
-+#define PCIE_PLCR_LINK_MODE_S 16
-+#define PCIE_PLCR_CORRUPTED_CRC_EN 0x02000000 /* Enabled Corrupt CRC */
-+
-+/* Lane Skew Register */
-+#define PCIE_LSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x714)
-+#define PCIE_LSR_LANE_SKEW_NUM 0x00FFFFFF /* Insert Lane Skew for Transmit, not applicable */
-+#define PCIE_LSR_LANE_SKEW_NUM_S 0
-+#define PCIE_LSR_FC_DISABLE 0x01000000 /* Disable of Flow Control */
-+#define PCIE_LSR_ACKNAK_DISABLE 0x02000000 /* Disable of Ack/Nak */
-+#define PCIE_LSR_LANE_DESKEW_DISABLE 0x80000000 /* Disable of Lane-to-Lane Skew */
-+
-+/* Symbol Number Register */
-+#define PCIE_SNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x718)
-+#define PCIE_SNR_TS 0x0000000F /* Number of TS Symbol */
-+#define PCIE_SNR_TS_S 0
-+#define PCIE_SNR_SKP 0x00000700 /* Number of SKP Symbol */
-+#define PCIE_SNR_SKP_S 8
-+#define PCIE_SNR_REPLAY_TIMER 0x0007C000 /* Timer Modifier for Replay Timer */
-+#define PCIE_SNR_REPLAY_TIMER_S 14
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER 0x00F80000 /* Timer Modifier for Ack/Nak Latency Timer */
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER_S 19
-+#define PCIE_SNR_FC_TIMER 0x1F000000 /* Timer Modifier for Flow Control Watchdog Timer */
-+#define PCIE_SNR_FC_TIMER_S 28
-+
-+/* Symbol Timer Register and Filter Mask Register 1 */
-+#define PCIE_STRFMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x71C)
-+#define PCIE_STRFMR_SKP_INTERVAL 0x000007FF /* SKP lnterval Value */
-+#define PCIE_STRFMR_SKP_INTERVAL_S 0
-+#define PCIE_STRFMR_FC_WDT_DISABLE 0x00008000 /* Disable of FC Watchdog Timer */
-+#define PCIE_STRFMR_TLP_FUNC_MISMATCH_OK 0x00010000 /* Mask Function Mismatch Filtering for Incoming Requests */
-+#define PCIE_STRFMR_POISONED_TLP_OK 0x00020000 /* Mask Poisoned TLP Filtering */
-+#define PCIE_STRFMR_BAR_MATCH_OK 0x00040000 /* Mask BAR Match Filtering */
-+#define PCIE_STRFMR_TYPE1_CFG_REQ_OK 0x00080000 /* Mask Type 1 Configuration Request Filtering */
-+#define PCIE_STRFMR_LOCKED_REQ_OK 0x00100000 /* Mask Locked Request Filtering */
-+#define PCIE_STRFMR_CPL_TAG_ERR_RULES_OK 0x00200000 /* Mask Tag Error Rules for Received Completions */
-+#define PCIE_STRFMR_CPL_REQUESTOR_ID_MISMATCH_OK 0x00400000 /* Mask Requester ID Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_FUNC_MISMATCH_OK 0x00800000 /* Mask Function Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_TC_MISMATCH_OK 0x01000000 /* Mask Traffic Class Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_ATTR_MISMATCH_OK 0x02000000 /* Mask Attribute Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_LENGTH_MISMATCH_OK 0x04000000 /* Mask Length Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_TLP_ECRC_ERR_OK 0x08000000 /* Mask ECRC Error Filtering */
-+#define PCIE_STRFMR_CPL_TLP_ECRC_OK 0x10000000 /* Mask ECRC Error Filtering for Completions */
-+#define PCIE_STRFMR_RX_TLP_MSG_NO_DROP 0x20000000 /* Send Message TLPs */
-+#define PCIE_STRFMR_RX_IO_TRANS_ENABLE 0x40000000 /* Mask Filtering of received I/O Requests */
-+#define PCIE_STRFMR_RX_CFG_TRANS_ENABLE 0x80000000 /* Mask Filtering of Received Configuration Requests */
-+
-+#define PCIE_DEF_SKP_INTERVAL 700 /* 1180 ~1538 , 125MHz * 2, 250MHz * 1 */
-+
-+/* Filter Masker Register 2 */
-+#define PCIE_FMR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x720)
-+#define PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1 0x00000001 /* Mask RADM Filtering and Error Handling Rules */
-+#define PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 0x00000002 /* Mask RADM Filtering and Error Handling Rules */
-+
-+/* Debug Register 0 */
-+#define PCIE_DBR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x728)
-+
-+/* Debug Register 1 */
-+#define PCIE_DBR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x72C)
-+
-+/* Transmit Posted FC Credit Status Register */
-+#define PCIE_TPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x730)
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS 0x00000FFF /* Transmit Posted Data FC Credits */
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS_S 0
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS 0x000FF000 /* Transmit Posted Header FC Credits */
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Non-Posted FC Credit Status */
-+#define PCIE_TNPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x734)
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS 0x00000FFF /* Transmit Non-Posted Data FC Credits */
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS_S 0
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS 0x000FF000 /* Transmit Non-Posted Header FC Credits */
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Complete FC Credit Status Register */
-+#define PCIE_TCFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x738)
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS 0x00000FFF /* Transmit Completion Data FC Credits */
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS_S 0
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS 0x000FF000 /* Transmit Completion Header FC Credits */
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS_S 12
-+
-+/* Queue Status Register */
-+#define PCIE_QSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x73C)
-+#define PCIE_QSR_WAIT_UPDATE_FC_DLL 0x00000001 /* Received TLP FC Credits Not Returned */
-+#define PCIE_QSR_TX_RETRY_BUF_NOT_EMPTY 0x00000002 /* Transmit Retry Buffer Not Empty */
-+#define PCIE_QSR_RX_QUEUE_NOT_EMPTY 0x00000004 /* Received Queue Not Empty */
-+
-+/* VC Transmit Arbitration Register 1 */
-+#define PCIE_VCTAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x740)
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC0 0x000000FF /* WRR Weight for VC0 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC1 0x0000FF00 /* WRR Weight for VC1 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC2 0x00FF0000 /* WRR Weight for VC2 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC3 0xFF000000 /* WRR Weight for VC3 */
-+
-+/* VC Transmit Arbitration Register 2 */
-+#define PCIE_VCTAR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x744)
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC4 0x000000FF /* WRR Weight for VC4 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC5 0x0000FF00 /* WRR Weight for VC5 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC6 0x00FF0000 /* WRR Weight for VC6 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC7 0xFF000000 /* WRR Weight for VC7 */
-+
-+/* VC0 Posted Receive Queue Control Register */
-+#define PCIE_VC0_PRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x748)
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS 0x00000FFF /* VC0 Posted Data Credits */
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS_S 0
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS 0x000FF000 /* VC0 Posted Header Credits */
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS_S 12
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE 0x00E00000 /* VC0 Posted TLP Queue Mode */
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE_S 20
-+#define PCIE_VC0_PRQCR_TLP_RELAX_ORDER 0x40000000 /* TLP Type Ordering for VC0 */
-+#define PCIE_VC0_PRQCR_VC_STRICT_ORDER 0x80000000 /* VC0 Ordering for Receive Queues */
-+
-+/* VC0 Non-Posted Receive Queue Control */
-+#define PCIE_VC0_NPRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74C)
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS 0x00000FFF /* VC0 Non-Posted Data Credits */
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS_S 0
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS 0x000FF000 /* VC0 Non-Posted Header Credits */
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS_S 12
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE 0x00E00000 /* VC0 Non-Posted TLP Queue Mode */
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE_S 20
-+
-+/* VC0 Completion Receive Queue Control */
-+#define PCIE_VC0_CRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x750)
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS 0x00000FFF /* VC0 Completion TLP Queue Mode */
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS_S 0
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS 0x000FF000 /* VC0 Completion Header Credits */
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS_S 12
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE 0x00E00000 /* VC0 Completion Data Credits */
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE_S 21
-+
-+/* Applicable to the above three registers */
-+enum {
-+ PCIE_VC0_TLP_QUEUE_MODE_STORE_FORWARD = 1,
-+ PCIE_VC0_TLP_QUEUE_MODE_CUT_THROUGH = 2,
-+ PCIE_VC0_TLP_QUEUE_MODE_BYPASS = 4,
-+};
-+
-+/* VC0 Posted Buffer Depth Register */
-+#define PCIE_VC0_PBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7A8)
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Posted Data Queue Depth */
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Posted Header Queue Depth */
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Non-Posted Buffer Depth Register */
-+#define PCIE_VC0_NPBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7AC)
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Non-Posted Data Queue Depth */
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Non-Posted Header Queue Depth */
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Completion Buffer Depth Register */
-+#define PCIE_VC0_CBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7B0)
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES 0x00003FFF /* C0 Completion Data Queue Depth */
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Completion Header Queue Depth */
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES_S 16
-+
-+/* PHY Status Register, all zeros in VR9 */
-+#define PCIE_PHYSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x810)
-+
-+/* PHY Control Register, all zeros in VR9 */
-+#define PCIE_PHYCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x814)
-+
-+/*
-+ * PCIe PDI PHY register definition, suppose all the following
-+ * stuff is confidential.
-+ * XXX, detailed bit definition
-+ */
-+#define PCIE_PHY_PLL_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x22 << 1))
-+#define PCIE_PHY_PLL_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x23 << 1))
-+#define PCIE_PHY_PLL_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x24 << 1))
-+#define PCIE_PHY_PLL_CTRL4(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x25 << 1))
-+#define PCIE_PHY_PLL_CTRL5(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x26 << 1))
-+#define PCIE_PHY_PLL_CTRL6(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x27 << 1))
-+#define PCIE_PHY_PLL_CTRL7(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x28 << 1))
-+#define PCIE_PHY_PLL_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x29 << 1))
-+#define PCIE_PHY_PLL_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2A << 1))
-+#define PCIE_PHY_PLL_A_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2B << 1))
-+#define PCIE_PHY_PLL_STATUS(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2C << 1))
-+
-+#define PCIE_PHY_TX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x30 << 1))
-+#define PCIE_PHY_TX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x31 << 1))
-+#define PCIE_PHY_TX1_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x32 << 1))
-+#define PCIE_PHY_TX1_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x33 << 1))
-+#define PCIE_PHY_TX1_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x34 << 1))
-+#define PCIE_PHY_TX1_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x35 << 1))
-+#define PCIE_PHY_TX1_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x36 << 1))
-+#define PCIE_PHY_TX1_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x37 << 1))
-+
-+#define PCIE_PHY_TX2_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x38 << 1))
-+#define PCIE_PHY_TX2_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x39 << 1))
-+#define PCIE_PHY_TX2_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3B << 1))
-+#define PCIE_PHY_TX2_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3C << 1))
-+#define PCIE_PHY_TX2_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3D << 1))
-+#define PCIE_PHY_TX2_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3E << 1))
-+#define PCIE_PHY_TX2_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3F << 1))
-+
-+#define PCIE_PHY_RX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x50 << 1))
-+#define PCIE_PHY_RX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x51 << 1))
-+#define PCIE_PHY_RX1_CDR(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x52 << 1))
-+#define PCIE_PHY_RX1_EI(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x53 << 1))
-+#define PCIE_PHY_RX1_A_CTRL(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x55 << 1))
-+
-+/* Interrupt related stuff */
-+#define PCIE_LEGACY_DISABLE 0
-+#define PCIE_LEGACY_INTA 1
-+#define PCIE_LEGACY_INTB 2
-+#define PCIE_LEGACY_INTC 3
-+#define PCIE_LEGACY_INTD 4
-+#define PCIE_LEGACY_INT_MAX PCIE_LEGACY_INTD
-+
-+#endif /* IFXMIPS_PCIE_REG_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_vr9.h
-@@ -0,0 +1,284 @@
-+/****************************************************************************
-+ Copyright (c) 2010
-+ Lantiq Deutschland GmbH
-+ Am Campeon 3; 85579 Neubiberg, Germany
-+
-+ For licensing information, see the file 'LICENSE' in the root folder of
-+ this software module.
-+
-+ *****************************************************************************/
-+/*!
-+ \file ifxmips_pcie_vr9.h
-+ \ingroup IFX_PCIE
-+ \brief PCIe RC driver vr9 specific file
-+*/
-+
-+#ifndef IFXMIPS_PCIE_VR9_H
-+#define IFXMIPS_PCIE_VR9_H
-+
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+
-+#include <linux/gpio.h>
-+#include <lantiq_soc.h>
-+
-+#define IFX_PCIE_GPIO_RESET 494
-+
-+#define IFX_REG_R32 ltq_r32
-+#define IFX_REG_W32 ltq_w32
-+#define CONFIG_IFX_PCIE_HW_SWAP
-+#define IFX_RCU_AHB_ENDIAN ((volatile u32*)(IFX_RCU + 0x004C))
-+#define IFX_RCU_RST_REQ ((volatile u32*)(IFX_RCU + 0x0010))
-+#define IFX_RCU_AHB_BE_PCIE_PDI 0x00000080 /* Configure PCIE PDI module in big endian*/
-+
-+#define IFX_RCU (KSEG1 | 0x1F203000)
-+#define IFX_RCU_AHB_BE_PCIE_M 0x00000001 /* Configure AHB master port that connects to PCIe RC in big endian */
-+#define IFX_RCU_AHB_BE_PCIE_S 0x00000010 /* Configure AHB slave port that connects to PCIe RC in little endian */
-+#define IFX_RCU_AHB_BE_XBAR_M 0x00000002 /* Configure AHB master port that connects to XBAR in big endian */
-+#define IFX_RCU_AHB_BE_XBAR_S 0x00000008 /* Configure AHB slave port that connects to XBAR in big endian */
-+#define CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+
-+#define IFX_PMU1_MODULE_PCIE_PHY (0)
-+#define IFX_PMU1_MODULE_PCIE_CTRL (1)
-+#define IFX_PMU1_MODULE_PDI (4)
-+#define IFX_PMU1_MODULE_MSI (5)
-+
-+#define IFX_PMU_MODULE_PCIE_L0_CLK (31)
-+
-+
-+#define IFX_GPIO (KSEG1 | 0x1E100B00)
-+#define ALT0 ((volatile u32*)(IFX_GPIO + 0x007c))
-+#define ALT1 ((volatile u32*)(IFX_GPIO + 0x0080))
-+#define OD ((volatile u32*)(IFX_GPIO + 0x0084))
-+#define DIR ((volatile u32*)(IFX_GPIO + 0x0078))
-+#define OUT ((volatile u32*)(IFX_GPIO + 0x0070))
-+
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+
-+ gpio_request(IFX_PCIE_GPIO_RESET, "pcie-reset");
-+ gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+
-+/* ifx_gpio_pin_reserve(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_dir_out_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_altsel0_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_altsel1_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_open_drain_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);*/
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ /* Enable AHB bus master/slave */
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "ahb");
-+ clk_enable(clk);
-+
-+ //AHBM_PMU_SETUP(IFX_PMU_ENABLE);
-+ //AHBS_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg |= IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#else
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "phy");
-+ clk_enable(clk);
-+
-+ //PCIE_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "phy");
-+ clk_disable(clk);
-+
-+// PCIE_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* SRAM2PDI endianness control. */
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ /* Enable PDI to access PCIe PHY register */
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "pdi");
-+ clk_enable(clk);
-+ //PDI_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-+ reg |= 0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ /* Reset PCIe PHY & Core, bit 22 */
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg |= 0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
-+// ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-+// gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+ //ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "ctl");
-+ clk_enable(clk);
-+ clk = clk_get_sys("1d900000.pcie", "bus");
-+ clk_enable(clk);
-+
-+ /* PCIe Core controller enabled */
-+// PCIE_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+
-+ /* Enable PCIe L0 Clock */
-+// PCIE_L0_CLK_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ struct clk *clk;
-+ pcie_msi_pic_init(pcie_port);
-+ clk = clk_get_sys("ltq_pcie", "msi");
-+ clk_enable(clk);
-+// MSI_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+#endif /* CONFIG_PCI_LANTIQ */
-+ return tbus_number;
-+}
-+
-+static inline struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ #endif /* CONFIG_PCI_LANTIQ */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_VR9_H */
---- a/arch/mips/pci/pci-legacy.c
-+++ b/arch/mips/pci/pci-legacy.c
-@@ -305,3 +305,30 @@ char *__init pcibios_setup(char *str)
- return pcibios_plat_setup(str);
- return str;
- }
-+
-+int pcibios_host_nr(void)
-+{
-+ int count = 0;
-+ struct pci_controller *hose;
-+ list_for_each_entry(hose, &controllers, list) {
-+ count++;
-+ }
-+ return count;
-+}
-+EXPORT_SYMBOL(pcibios_host_nr);
-+
-+int pcibios_1st_host_bus_nr(void)
-+{
-+ int bus_nr = 0;
-+ struct pci_controller *hose;
-+
-+ hose = list_first_entry_or_null(&controllers, struct pci_controller, list);
-+
-+ if (hose != NULL) {
-+ if (hose->bus != NULL) {
-+ bus_nr = hose->bus->number + 1;
-+ }
-+ }
-+ return bus_nr;
-+}
-+EXPORT_SYMBOL(pcibios_1st_host_bus_nr);
---- /dev/null
-+++ b/arch/mips/pci/pcie-lantiq.h
-@@ -0,0 +1,1316 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_reg.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_REG_H
-+#define IFXMIPS_PCIE_REG_H
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+/*!
-+ \file ifxmips_pcie_reg.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module register definition
-+*/
-+/* PCIe Address Mapping Base */
-+#define PCIE_CFG_PHY_BASE 0x1D000000UL
-+#define PCIE_CFG_BASE (KSEG1 + PCIE_CFG_PHY_BASE)
-+#define PCIE_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE_MEM_PHY_BASE 0x1C000000UL
-+#define PCIE_MEM_BASE (KSEG1 + PCIE_MEM_PHY_BASE)
-+#define PCIE_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE_MEM_PHY_END (PCIE_MEM_PHY_BASE + PCIE_MEM_SIZE - 1)
-+
-+#define PCIE_IO_PHY_BASE 0x1D800000UL
-+#define PCIE_IO_BASE (KSEG1 + PCIE_IO_PHY_BASE)
-+#define PCIE_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE_IO_PHY_END (PCIE_IO_PHY_BASE + PCIE_IO_SIZE - 1)
-+
-+#define PCIE_RC_CFG_BASE (KSEG1 + 0x1D900000)
-+#define PCIE_APP_LOGIC_REG (KSEG1 + 0x1E100900)
-+#define PCIE_MSI_PHY_BASE 0x1F600000UL
-+
-+#define PCIE_PDI_PHY_BASE 0x1F106800UL
-+#define PCIE_PDI_BASE (KSEG1 + PCIE_PDI_PHY_BASE)
-+#define PCIE_PDI_SIZE 0x400
-+
-+#define PCIE1_CFG_PHY_BASE 0x19000000UL
-+#define PCIE1_CFG_BASE (KSEG1 + PCIE1_CFG_PHY_BASE)
-+#define PCIE1_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE1_MEM_PHY_BASE 0x18000000UL
-+#define PCIE1_MEM_BASE (KSEG1 + PCIE1_MEM_PHY_BASE)
-+#define PCIE1_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE1_MEM_PHY_END (PCIE1_MEM_PHY_BASE + PCIE1_MEM_SIZE - 1)
-+
-+#define PCIE1_IO_PHY_BASE 0x19800000UL
-+#define PCIE1_IO_BASE (KSEG1 + PCIE1_IO_PHY_BASE)
-+#define PCIE1_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE1_IO_PHY_END (PCIE1_IO_PHY_BASE + PCIE1_IO_SIZE - 1)
-+
-+#define PCIE1_RC_CFG_BASE (KSEG1 + 0x19900000)
-+#define PCIE1_APP_LOGIC_REG (KSEG1 + 0x1E100700)
-+#define PCIE1_MSI_PHY_BASE 0x1F400000UL
-+
-+#define PCIE1_PDI_PHY_BASE 0x1F700400UL
-+#define PCIE1_PDI_BASE (KSEG1 + PCIE1_PDI_PHY_BASE)
-+#define PCIE1_PDI_SIZE 0x400
-+
-+#define PCIE_CFG_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_CFG_BASE) : (PCIE_CFG_BASE))
-+#define PCIE_MEM_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_BASE) : (PCIE_MEM_BASE))
-+#define PCIE_IO_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_BASE) : (PCIE_IO_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_PHY_BASE) : (PCIE_MEM_PHY_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_MEM_PHY_END) : (PCIE_MEM_PHY_END))
-+#define PCIE_IO_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_PHY_BASE) : (PCIE_IO_PHY_BASE))
-+#define PCIE_IO_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_IO_PHY_END) : (PCIE_IO_PHY_END))
-+#define PCIE_APP_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_APP_LOGIC_REG) : (PCIE_APP_LOGIC_REG))
-+#define PCIE_RC_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_RC_CFG_BASE) : (PCIE_RC_CFG_BASE))
-+#define PCIE_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_PDI_BASE) : (PCIE_PDI_BASE))
-+
-+/* PCIe Application Logic Register */
-+/* RC Core Control Register */
-+#define PCIE_RC_CCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x10)
-+/* This should be enabled after initializing configuratin registers
-+ * Also should check link status retraining bit
-+ */
-+#define PCIE_RC_CCR_LTSSM_ENABLE 0x00000001 /* Enable LTSSM to continue link establishment */
-+
-+/* RC Core Debug Register */
-+#define PCIE_RC_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x14)
-+#define PCIE_RC_DR_DLL_UP 0x00000001 /* Data Link Layer Up */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE 0x0000000E /* Current Power State */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE_S 1
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE 0x000001F0 /* Current LTSSM State */
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE_S 4
-+
-+#define PCIE_RC_DR_PM_DEV_STATE 0x00000E00 /* Power Management D-State */
-+#define PCIE_RC_DR_PM_DEV_STATE_S 9
-+
-+#define PCIE_RC_DR_PM_ENABLED 0x00001000 /* Power Management State from PMU */
-+#define PCIE_RC_DR_PME_EVENT_ENABLED 0x00002000 /* Power Management Event Enable State */
-+#define PCIE_RC_DR_AUX_POWER_ENABLED 0x00004000 /* Auxiliary Power Enable */
-+
-+/* Current Power State Definition */
-+enum {
-+ PCIE_RC_DR_D0 = 0,
-+ PCIE_RC_DR_D1, /* Not supported */
-+ PCIE_RC_DR_D2, /* Not supported */
-+ PCIE_RC_DR_D3,
-+ PCIE_RC_DR_UN,
-+};
-+
-+/* PHY Link Status Register */
-+#define PCIE_PHY_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x18)
-+#define PCIE_PHY_SR_PHY_LINK_UP 0x00000001 /* PHY Link Up/Down Indicator */
-+
-+/* Electromechanical Control Register */
-+#define PCIE_EM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x1C)
-+#define PCIE_EM_CR_CARD_IS_PRESENT 0x00000001 /* Card Presence Detect State */
-+#define PCIE_EM_CR_MRL_OPEN 0x00000002 /* MRL Sensor State */
-+#define PCIE_EM_CR_POWER_FAULT_SET 0x00000004 /* Power Fault Detected */
-+#define PCIE_EM_CR_MRL_SENSOR_SET 0x00000008 /* MRL Sensor Changed */
-+#define PCIE_EM_CR_PRESENT_DETECT_SET 0x00000010 /* Card Presense Detect Changed */
-+#define PCIE_EM_CR_CMD_CPL_INT_SET 0x00000020 /* Command Complete Interrupt */
-+#define PCIE_EM_CR_SYS_INTERLOCK_SET 0x00000040 /* System Electromechanical IterLock Engaged */
-+#define PCIE_EM_CR_ATTENTION_BUTTON_SET 0x00000080 /* Attention Button Pressed */
-+
-+/* Interrupt Status Register */
-+#define PCIE_IR_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x20)
-+#define PCIE_IR_SR_PME_CAUSE_MSI 0x00000002 /* MSI caused by PME */
-+#define PCIE_IR_SR_HP_PME_WAKE_GEN 0x00000004 /* Hotplug PME Wake Generation */
-+#define PCIE_IR_SR_HP_MSI 0x00000008 /* Hotplug MSI */
-+#define PCIE_IR_SR_AHB_LU_ERR 0x00000030 /* AHB Bridge Lookup Error Signals */
-+#define PCIE_IR_SR_AHB_LU_ERR_S 4
-+#define PCIE_IR_SR_INT_MSG_NUM 0x00003E00 /* Interrupt Message Number */
-+#define PCIE_IR_SR_INT_MSG_NUM_S 9
-+#define PCIE_IR_SR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_IR_SR_AER_INT_MSG_NUM_S 27
-+
-+/* Message Control Register */
-+#define PCIE_MSG_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x30)
-+#define PCIE_MSG_CR_GEN_PME_TURN_OFF_MSG 0x00000001 /* Generate PME Turn Off Message */
-+#define PCIE_MSG_CR_GEN_UNLOCK_MSG 0x00000002 /* Generate Unlock Message */
-+
-+#define PCIE_VDM_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x34)
-+
-+/* Vendor-Defined Message Requester ID Register */
-+#define PCIE_VDM_RID(X) (PCIE_APP_PORT_TO_BASE (X) + 0x38)
-+#define PCIE_VDM_RID_VENROR_MSG_REQ_ID 0x0000FFFF
-+#define PCIE_VDM_RID_VDMRID_S 0
-+
-+/* ASPM Control Register */
-+#define PCIE_ASPM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x40)
-+#define PCIE_ASPM_CR_HOT_RST 0x00000001 /* Hot Reset Request to the downstream device */
-+#define PCIE_ASPM_CR_REQ_EXIT_L1 0x00000002 /* Request to Exit L1 */
-+#define PCIE_ASPM_CR_REQ_ENTER_L1 0x00000004 /* Request to Enter L1 */
-+
-+/* Vendor Message DW0 Register */
-+#define PCIE_VM_MSG_DW0(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x50)
-+#define PCIE_VM_MSG_DW0_TYPE 0x0000001F /* Message type */
-+#define PCIE_VM_MSG_DW0_TYPE_S 0
-+#define PCIE_VM_MSG_DW0_FORMAT 0x00000060 /* Format */
-+#define PCIE_VM_MSG_DW0_FORMAT_S 5
-+#define PCIE_VM_MSG_DW0_TC 0x00007000 /* Traffic Class */
-+#define PCIE_VM_MSG_DW0_TC_S 12
-+#define PCIE_VM_MSG_DW0_ATTR 0x000C0000 /* Atrributes */
-+#define PCIE_VM_MSG_DW0_ATTR_S 18
-+#define PCIE_VM_MSG_DW0_EP_TLP 0x00100000 /* Poisoned TLP */
-+#define PCIE_VM_MSG_DW0_TD 0x00200000 /* TLP Digest */
-+#define PCIE_VM_MSG_DW0_LEN 0xFFC00000 /* Length */
-+#define PCIE_VM_MSG_DW0_LEN_S 22
-+
-+/* Format Definition */
-+enum {
-+ PCIE_VM_MSG_FORMAT_00 = 0, /* 3DW Hdr, no data*/
-+ PCIE_VM_MSG_FORMAT_01, /* 4DW Hdr, no data */
-+ PCIE_VM_MSG_FORMAT_10, /* 3DW Hdr, with data */
-+ PCIE_VM_MSG_FORMAT_11, /* 4DW Hdr, with data */
-+};
-+
-+/* Traffic Class Definition */
-+enum {
-+ PCIE_VM_MSG_TC0 = 0,
-+ PCIE_VM_MSG_TC1,
-+ PCIE_VM_MSG_TC2,
-+ PCIE_VM_MSG_TC3,
-+ PCIE_VM_MSG_TC4,
-+ PCIE_VM_MSG_TC5,
-+ PCIE_VM_MSG_TC6,
-+ PCIE_VM_MSG_TC7,
-+};
-+
-+/* Attributes Definition */
-+enum {
-+ PCIE_VM_MSG_ATTR_00 = 0, /* RO and No Snoop cleared */
-+ PCIE_VM_MSG_ATTR_01, /* RO cleared , No Snoop set */
-+ PCIE_VM_MSG_ATTR_10, /* RO set, No Snoop cleared*/
-+ PCIE_VM_MSG_ATTR_11, /* RO and No Snoop set */
-+};
-+
-+/* Payload Size Definition */
-+#define PCIE_VM_MSG_LEN_MIN 0
-+#define PCIE_VM_MSG_LEN_MAX 1024
-+
-+/* Vendor Message DW1 Register */
-+#define PCIE_VM_MSG_DW1(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x54)
-+#define PCIE_VM_MSG_DW1_FUNC_NUM 0x00000070 /* Function Number */
-+#define PCIE_VM_MSG_DW1_FUNC_NUM_S 8
-+#define PCIE_VM_MSG_DW1_CODE 0x00FF0000 /* Message Code */
-+#define PCIE_VM_MSG_DW1_CODE_S 16
-+#define PCIE_VM_MSG_DW1_TAG 0xFF000000 /* Tag */
-+#define PCIE_VM_MSG_DW1_TAG_S 24
-+
-+#define PCIE_VM_MSG_DW2(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x58)
-+#define PCIE_VM_MSG_DW3(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x5C)
-+
-+/* Vendor Message Request Register */
-+#define PCIE_VM_MSG_REQR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x60)
-+#define PCIE_VM_MSG_REQR_REQ 0x00000001 /* Vendor Message Request */
-+
-+
-+/* AHB Slave Side Band Control Register */
-+#define PCIE_AHB_SSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x70)
-+#define PCIE_AHB_SSB_REQ_BCM 0x00000001 /* Slave Reques BCM filed */
-+#define PCIE_AHB_SSB_REQ_EP 0x00000002 /* Slave Reques EP filed */
-+#define PCIE_AHB_SSB_REQ_TD 0x00000004 /* Slave Reques TD filed */
-+#define PCIE_AHB_SSB_REQ_ATTR 0x00000018 /* Slave Reques Attribute number */
-+#define PCIE_AHB_SSB_REQ_ATTR_S 3
-+#define PCIE_AHB_SSB_REQ_TC 0x000000E0 /* Slave Request TC Field */
-+#define PCIE_AHB_SSB_REQ_TC_S 5
-+
-+/* AHB Master SideBand Ctrl Register */
-+#define PCIE_AHB_MSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x74)
-+#define PCIE_AHB_MSB_RESP_ATTR 0x00000003 /* Master Response Attribute number */
-+#define PCIE_AHB_MSB_RESP_ATTR_S 0
-+#define PCIE_AHB_MSB_RESP_BAD_EOT 0x00000004 /* Master Response Badeot filed */
-+#define PCIE_AHB_MSB_RESP_BCM 0x00000008 /* Master Response BCM filed */
-+#define PCIE_AHB_MSB_RESP_EP 0x00000010 /* Master Response EP filed */
-+#define PCIE_AHB_MSB_RESP_TD 0x00000020 /* Master Response TD filed */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM 0x000003C0 /* Master Response Function number */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM_S 6
-+
-+/* AHB Control Register, fixed bus enumeration exception */
-+#define PCIE_AHB_CTRL(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x78)
-+#define PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS 0x00000001
-+
-+/* Interrupt Enalbe Register */
-+#define PCIE_IRNEN(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF4)
-+#define PCIE_IRNCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF8)
-+#define PCIE_IRNICR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xFC)
-+
-+/* PCIe interrupt enable/control/capture register definition */
-+#define PCIE_IRN_AER_REPORT 0x00000001 /* AER Interrupt */
-+#define PCIE_IRN_AER_MSIX 0x00000002 /* Advanced Error MSI-X Interrupt */
-+#define PCIE_IRN_PME 0x00000004 /* PME Interrupt */
-+#define PCIE_IRN_HOTPLUG 0x00000008 /* Hotplug Interrupt */
-+#define PCIE_IRN_RX_VDM_MSG 0x00000010 /* Vendor-Defined Message Interrupt */
-+#define PCIE_IRN_RX_CORRECTABLE_ERR_MSG 0x00000020 /* Correctable Error Message Interrupt */
-+#define PCIE_IRN_RX_NON_FATAL_ERR_MSG 0x00000040 /* Non-fatal Error Message */
-+#define PCIE_IRN_RX_FATAL_ERR_MSG 0x00000080 /* Fatal Error Message */
-+#define PCIE_IRN_RX_PME_MSG 0x00000100 /* PME Message Interrupt */
-+#define PCIE_IRN_RX_PME_TURNOFF_ACK 0x00000200 /* PME Turnoff Ack Message Interrupt */
-+#define PCIE_IRN_AHB_BR_FATAL_ERR 0x00000400 /* AHB Fatal Error Interrupt */
-+#define PCIE_IRN_LINK_AUTO_BW_STATUS 0x00000800 /* Link Auto Bandwidth Status Interrupt */
-+#define PCIE_IRN_BW_MGT 0x00001000 /* Bandwidth Managment Interrupt */
-+#define PCIE_IRN_INTA 0x00002000 /* INTA */
-+#define PCIE_IRN_INTB 0x00004000 /* INTB */
-+#define PCIE_IRN_INTC 0x00008000 /* INTC */
-+#define PCIE_IRN_INTD 0x00010000 /* INTD */
-+#define PCIE_IRN_WAKEUP 0x00020000 /* Wake up Interrupt */
-+
-+#define PCIE_RC_CORE_COMBINED_INT (PCIE_IRN_AER_REPORT | PCIE_IRN_AER_MSIX | PCIE_IRN_PME | \
-+ PCIE_IRN_HOTPLUG | PCIE_IRN_RX_VDM_MSG | PCIE_IRN_RX_CORRECTABLE_ERR_MSG |\
-+ PCIE_IRN_RX_NON_FATAL_ERR_MSG | PCIE_IRN_RX_FATAL_ERR_MSG | \
-+ PCIE_IRN_RX_PME_MSG | PCIE_IRN_RX_PME_TURNOFF_ACK | PCIE_IRN_AHB_BR_FATAL_ERR | \
-+ PCIE_IRN_LINK_AUTO_BW_STATUS | PCIE_IRN_BW_MGT)
-+/* PCIe RC Configuration Register */
-+#define PCIE_VDID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x00)
-+
-+/* Bit definition from pci_reg.h */
-+#define PCIE_PCICMDSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x04)
-+#define PCIE_CCRID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x08)
-+#define PCIE_CLSLTHTBR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x0C) /* EP only */
-+/* BAR0, BAR1,Only necessary if the bridges implements a device-specific register set or memory buffer */
-+#define PCIE_BAR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10) /* Not used*/
-+#define PCIE_BAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14) /* Not used */
-+
-+#define PCIE_BNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x18) /* Mandatory */
-+/* Bus Number Register bits */
-+#define PCIE_BNR_PRIMARY_BUS_NUM 0x000000FF
-+#define PCIE_BNR_PRIMARY_BUS_NUM_S 0
-+#define PCIE_PNR_SECONDARY_BUS_NUM 0x0000FF00
-+#define PCIE_PNR_SECONDARY_BUS_NUM_S 8
-+#define PCIE_PNR_SUB_BUS_NUM 0x00FF0000
-+#define PCIE_PNR_SUB_BUS_NUM_S 16
-+
-+/* IO Base/Limit Register bits */
-+#define PCIE_IOBLSECS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x1C) /* RC only */
-+#define PCIE_IOBLSECS_32BIT_IO_ADDR 0x00000001
-+#define PCIE_IOBLSECS_IO_BASE_ADDR 0x000000F0
-+#define PCIE_IOBLSECS_IO_BASE_ADDR_S 4
-+#define PCIE_IOBLSECS_32BIT_IOLIMT 0x00000100
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR 0x0000F000
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR_S 12
-+
-+/* Non-prefetchable Memory Base/Limit Register bit */
-+#define PCIE_MBML(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x20) /* RC only */
-+#define PCIE_MBML_MEM_BASE_ADDR 0x0000FFF0
-+#define PCIE_MBML_MEM_BASE_ADDR_S 4
-+#define PCIE_MBML_MEM_LIMIT_ADDR 0xFFF00000
-+#define PCIE_MBML_MEM_LIMIT_ADDR_S 20
-+
-+/* Prefetchable Memory Base/Limit Register bit */
-+#define PCIE_PMBL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x24) /* RC only */
-+#define PCIE_PMBL_64BIT_ADDR 0x00000001
-+#define PCIE_PMBL_UPPER_12BIT 0x0000FFF0
-+#define PCIE_PMBL_UPPER_12BIT_S 4
-+#define PCIE_PMBL_E64MA 0x00010000
-+#define PCIE_PMBL_END_ADDR 0xFFF00000
-+#define PCIE_PMBL_END_ADDR_S 20
-+#define PCIE_PMBU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x28) /* RC only */
-+#define PCIE_PMLU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x2C) /* RC only */
-+
-+/* I/O Base/Limit Upper 16 bits register */
-+#define PCIE_IO_BANDL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x30) /* RC only */
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE 0x0000FFFF
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE_S 0
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT 0xFFFF0000
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT_S 16
-+
-+#define PCIE_CPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x34)
-+#define PCIE_EBBAR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x38)
-+
-+/* Interrupt and Secondary Bridge Control Register */
-+#define PCIE_INTRBCTRL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x3C)
-+
-+#define PCIE_INTRBCTRL_INT_LINE 0x000000FF
-+#define PCIE_INTRBCTRL_INT_LINE_S 0
-+#define PCIE_INTRBCTRL_INT_PIN 0x0000FF00
-+#define PCIE_INTRBCTRL_INT_PIN_S 8
-+#define PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE 0x00010000 /* #PERR */
-+#define PCIE_INTRBCTRL_SERR_ENABLE 0x00020000 /* #SERR */
-+#define PCIE_INTRBCTRL_ISA_ENABLE 0x00040000 /* ISA enable, IO 64KB only */
-+#define PCIE_INTRBCTRL_VGA_ENABLE 0x00080000 /* VGA enable */
-+#define PCIE_INTRBCTRL_VGA_16BIT_DECODE 0x00100000 /* VGA 16bit decode */
-+#define PCIE_INTRBCTRL_RST_SECONDARY_BUS 0x00400000 /* Secondary bus rest, hot rest, 1ms */
-+/* Others are read only */
-+enum {
-+ PCIE_INTRBCTRL_INT_NON = 0,
-+ PCIE_INTRBCTRL_INTA,
-+ PCIE_INTRBCTRL_INTB,
-+ PCIE_INTRBCTRL_INTC,
-+ PCIE_INTRBCTRL_INTD,
-+};
-+
-+#define PCIE_PM_CAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x40)
-+
-+/* Power Management Control and Status Register */
-+#define PCIE_PM_CSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x44)
-+
-+#define PCIE_PM_CSR_POWER_STATE 0x00000003 /* Power State */
-+#define PCIE_PM_CSR_POWER_STATE_S 0
-+#define PCIE_PM_CSR_SW_RST 0x00000008 /* Soft Reset Enabled */
-+#define PCIE_PM_CSR_PME_ENABLE 0x00000100 /* PME Enable */
-+#define PCIE_PM_CSR_PME_STATUS 0x00008000 /* PME status */
-+
-+/* MSI Capability Register for EP */
-+#define PCIE_MCAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x50)
-+
-+#define PCIE_MCAPR_MSI_CAP_ID 0x000000FF /* MSI Capability ID */
-+#define PCIE_MCAPR_MSI_CAP_ID_S 0
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR_S 8
-+#define PCIE_MCAPR_MSI_ENABLE 0x00010000 /* MSI Enable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP 0x000E0000 /* Multiple Message Capable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP_S 17
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE 0x00700000 /* Multiple Message Enable */
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE_S 20
-+#define PCIE_MCAPR_ADDR64_CAP 0X00800000 /* 64-bit Address Capable */
-+
-+/* MSI Message Address Register */
-+#define PCIE_MA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x54)
-+
-+#define PCIE_MA_ADDR_MASK 0xFFFFFFFC /* Message Address */
-+
-+/* MSI Message Upper Address Register */
-+#define PCIE_MUA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x58)
-+
-+/* MSI Message Data Register */
-+#define PCIE_MD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x5C)
-+
-+#define PCIE_MD_DATA 0x0000FFFF /* Message Data */
-+#define PCIE_MD_DATA_S 0
-+
-+/* PCI Express Capability Register */
-+#define PCIE_XCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70)
-+
-+#define PCIE_XCAP_ID 0x000000FF /* PCI Express Capability ID */
-+#define PCIE_XCAP_ID_S 0
-+#define PCIE_XCAP_NEXT_CAP 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_XCAP_NEXT_CAP_S 8
-+#define PCIE_XCAP_VER 0x000F0000 /* PCI Express Capability Version */
-+#define PCIE_XCAP_VER_S 16
-+#define PCIE_XCAP_DEV_PORT_TYPE 0x00F00000 /* Device Port Type */
-+#define PCIE_XCAP_DEV_PORT_TYPE_S 20
-+#define PCIE_XCAP_SLOT_IMPLEMENTED 0x01000000 /* Slot Implemented */
-+#define PCIE_XCAP_MSG_INT_NUM 0x3E000000 /* Interrupt Message Number */
-+#define PCIE_XCAP_MSG_INT_NUM_S 25
-+
-+/* Device Capability Register */
-+#define PCIE_DCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74)
-+
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE 0x00000007 /* Max Payload size */
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE_S 0
-+#define PCIE_DCAP_PHANTOM_FUNC 0x00000018 /* Phanton Function, not supported */
-+#define PCIE_DCAP_PHANTOM_FUNC_S 3
-+#define PCIE_DCAP_EXT_TAG 0x00000020 /* Extended Tag Field */
-+#define PCIE_DCAP_EP_L0S_LATENCY 0x000001C0 /* EP L0s latency only */
-+#define PCIE_DCAP_EP_L0S_LATENCY_S 6
-+#define PCIE_DCAP_EP_L1_LATENCY 0x00000E00 /* EP L1 latency only */
-+#define PCIE_DCAP_EP_L1_LATENCY_S 9
-+#define PCIE_DCAP_ROLE_BASE_ERR_REPORT 0x00008000 /* Role Based ERR */
-+
-+/* Maximum payload size supported */
-+enum {
-+ PCIE_MAX_PAYLOAD_128 = 0,
-+ PCIE_MAX_PAYLOAD_256,
-+ PCIE_MAX_PAYLOAD_512,
-+ PCIE_MAX_PAYLOAD_1024,
-+ PCIE_MAX_PAYLOAD_2048,
-+ PCIE_MAX_PAYLOAD_4096,
-+};
-+
-+/* Device Control and Status Register */
-+#define PCIE_DCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x78)
-+
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR_EN 0x00000001 /* COR-ERR */
-+#define PCIE_DCTLSTS_NONFATAL_ERR_EN 0x00000002 /* Non-fatal ERR */
-+#define PCIE_DCTLSTS_FATAL_ERR_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_DCTLSYS_UR_REQ_EN 0x00000008 /* UR ERR */
-+#define PCIE_DCTLSTS_RELAXED_ORDERING_EN 0x00000010 /* Enable relaxing ordering */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE 0x000000E0 /* Max payload mask */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE_S 5
-+#define PCIE_DCTLSTS_EXT_TAG_EN 0x00000100 /* Extended tag field */
-+#define PCIE_DCTLSTS_PHANTOM_FUNC_EN 0x00000200 /* Phantom Function Enable */
-+#define PCIE_DCTLSTS_AUX_PM_EN 0x00000400 /* AUX Power PM Enable */
-+#define PCIE_DCTLSTS_NO_SNOOP_EN 0x00000800 /* Enable no snoop, except root port*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE 0x00007000 /* Max Read Request size*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE_S 12
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR 0x00010000 /* COR-ERR Detected */
-+#define PCIE_DCTLSTS_NONFATAL_ERR 0x00020000 /* Non-Fatal ERR Detected */
-+#define PCIE_DCTLSTS_FATAL_ER 0x00040000 /* Fatal ERR Detected */
-+#define PCIE_DCTLSTS_UNSUPPORTED_REQ 0x00080000 /* UR Detected */
-+#define PCIE_DCTLSTS_AUX_POWER 0x00100000 /* Aux Power Detected */
-+#define PCIE_DCTLSTS_TRANSACT_PENDING 0x00200000 /* Transaction pending */
-+
-+#define PCIE_DCTLSTS_ERR_EN (PCIE_DCTLSTS_CORRECTABLE_ERR_EN | \
-+ PCIE_DCTLSTS_NONFATAL_ERR_EN | PCIE_DCTLSTS_FATAL_ERR_EN | \
-+ PCIE_DCTLSYS_UR_REQ_EN)
-+
-+/* Link Capability Register */
-+#define PCIE_LCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7C)
-+#define PCIE_LCAP_MAX_LINK_SPEED 0x0000000F /* Max link speed, 0x1 by default */
-+#define PCIE_LCAP_MAX_LINK_SPEED_S 0
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH 0x000003F0 /* Maxium Length Width */
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH_S 4
-+#define PCIE_LCAP_ASPM_LEVEL 0x00000C00 /* Active State Link PM Support */
-+#define PCIE_LCAP_ASPM_LEVEL_S 10
-+#define PCIE_LCAP_L0S_EIXT_LATENCY 0x00007000 /* L0s Exit Latency */
-+#define PCIE_LCAP_L0S_EIXT_LATENCY_S 12
-+#define PCIE_LCAP_L1_EXIT_LATENCY 0x00038000 /* L1 Exit Latency */
-+#define PCIE_LCAP_L1_EXIT_LATENCY_S 15
-+#define PCIE_LCAP_CLK_PM 0x00040000 /* Clock Power Management */
-+#define PCIE_LCAP_SDER 0x00080000 /* Surprise Down Error Reporting */
-+#define PCIE_LCAP_DLL_ACTIVE_REPROT 0x00100000 /* Data Link Layer Active Reporting Capable */
-+#define PCIE_LCAP_PORT_NUM 0xFF0000000 /* Port number */
-+#define PCIE_LCAP_PORT_NUM_S 24
-+
-+/* Maximum Length width definition */
-+#define PCIE_MAX_LENGTH_WIDTH_RES 0x00
-+#define PCIE_MAX_LENGTH_WIDTH_X1 0x01 /* Default */
-+#define PCIE_MAX_LENGTH_WIDTH_X2 0x02
-+#define PCIE_MAX_LENGTH_WIDTH_X4 0x04
-+#define PCIE_MAX_LENGTH_WIDTH_X8 0x08
-+#define PCIE_MAX_LENGTH_WIDTH_X12 0x0C
-+#define PCIE_MAX_LENGTH_WIDTH_X16 0x10
-+#define PCIE_MAX_LENGTH_WIDTH_X32 0x20
-+
-+/* Active State Link PM definition */
-+enum {
-+ PCIE_ASPM_RES0 = 0,
-+ PCIE_ASPM_L0S_ENTRY_SUPPORT, /* L0s */
-+ PCIE_ASPM_RES1,
-+ PCIE_ASPM_L0S_L1_ENTRY_SUPPORT, /* L0s and L1, default */
-+};
-+
-+/* L0s Exit Latency definition */
-+enum {
-+ PCIE_L0S_EIXT_LATENCY_L64NS = 0, /* < 64 ns */
-+ PCIE_L0S_EIXT_LATENCY_B64A128, /* > 64 ns < 128 ns */
-+ PCIE_L0S_EIXT_LATENCY_B128A256, /* > 128 ns < 256 ns */
-+ PCIE_L0S_EIXT_LATENCY_B256A512, /* > 256 ns < 512 ns */
-+ PCIE_L0S_EIXT_LATENCY_B512TO1U, /* > 512 ns < 1 us */
-+ PCIE_L0S_EIXT_LATENCY_B1A2U, /* > 1 us < 2 us */
-+ PCIE_L0S_EIXT_LATENCY_B2A4U, /* > 2 us < 4 us */
-+ PCIE_L0S_EIXT_LATENCY_M4US, /* > 4 us */
-+};
-+
-+/* L1 Exit Latency definition */
-+enum {
-+ PCIE_L1_EXIT_LATENCY_L1US = 0, /* < 1 us */
-+ PCIE_L1_EXIT_LATENCY_B1A2, /* > 1 us < 2 us */
-+ PCIE_L1_EXIT_LATENCY_B2A4, /* > 2 us < 4 us */
-+ PCIE_L1_EXIT_LATENCY_B4A8, /* > 4 us < 8 us */
-+ PCIE_L1_EXIT_LATENCY_B8A16, /* > 8 us < 16 us */
-+ PCIE_L1_EXIT_LATENCY_B16A32, /* > 16 us < 32 us */
-+ PCIE_L1_EXIT_LATENCY_B32A64, /* > 32 us < 64 us */
-+ PCIE_L1_EXIT_LATENCY_M64US, /* > 64 us */
-+};
-+
-+/* Link Control and Status Register */
-+#define PCIE_LCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x80)
-+#define PCIE_LCTLSTS_ASPM_ENABLE 0x00000003 /* Active State Link PM Control */
-+#define PCIE_LCTLSTS_ASPM_ENABLE_S 0
-+#define PCIE_LCTLSTS_RCB128 0x00000008 /* Read Completion Boundary 128*/
-+#define PCIE_LCTLSTS_LINK_DISABLE 0x00000010 /* Link Disable */
-+#define PCIE_LCTLSTS_RETRIAN_LINK 0x00000020 /* Retrain Link */
-+#define PCIE_LCTLSTS_COM_CLK_CFG 0x00000040 /* Common Clock Configuration */
-+#define PCIE_LCTLSTS_EXT_SYNC 0x00000080 /* Extended Synch */
-+#define PCIE_LCTLSTS_CLK_PM_EN 0x00000100 /* Enable Clock Powerm Management */
-+#define PCIE_LCTLSTS_LINK_SPEED 0x000F0000 /* Link Speed */
-+#define PCIE_LCTLSTS_LINK_SPEED_S 16
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH 0x03F00000 /* Negotiated Link Width */
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH_S 20
-+#define PCIE_LCTLSTS_RETRAIN_PENDING 0x08000000 /* Link training is ongoing */
-+#define PCIE_LCTLSTS_SLOT_CLK_CFG 0x10000000 /* Slot Clock Configuration */
-+#define PCIE_LCTLSTS_DLL_ACTIVE 0x20000000 /* Data Link Layer Active */
-+
-+/* Slot Capabilities Register */
-+#define PCIE_SLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x84)
-+
-+/* Slot Capabilities */
-+#define PCIE_SLCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x88)
-+
-+/* Root Control and Capability Register */
-+#define PCIE_RCTLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x8C)
-+#define PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR 0x00000001 /* #SERR on COR-ERR */
-+#define PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR 0x00000002 /* #SERR on Non-Fatal ERR */
-+#define PCIE_RCTLCAP_SERR_ON_FATAL_ERR 0x00000004 /* #SERR on Fatal ERR */
-+#define PCIE_RCTLCAP_PME_INT_EN 0x00000008 /* PME Interrupt Enable */
-+#define PCIE_RCTLCAP_SERR_ENABLE (PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR | \
-+ PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR | PCIE_RCTLCAP_SERR_ON_FATAL_ERR)
-+/* Root Status Register */
-+#define PCIE_RSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x90)
-+#define PCIE_RSTS_PME_REQ_ID 0x0000FFFF /* PME Request ID */
-+#define PCIE_RSTS_PME_REQ_ID_S 0
-+#define PCIE_RSTS_PME_STATUS 0x00010000 /* PME Status */
-+#define PCIE_RSTS_PME_PENDING 0x00020000 /* PME Pending */
-+
-+/* PCI Express Enhanced Capability Header */
-+#define PCIE_ENHANCED_CAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x100)
-+#define PCIE_ENHANCED_CAP_ID 0x0000FFFF /* PCI Express Extended Capability ID */
-+#define PCIE_ENHANCED_CAP_ID_S 0
-+#define PCIE_ENHANCED_CAP_VER 0x000F0000 /* Capability Version */
-+#define PCIE_ENHANCED_CAP_VER_S 16
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET 0xFFF00000 /* Next Capability Offset */
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET_S 20
-+
-+/* Uncorrectable Error Status Register */
-+#define PCIE_UES_R(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x104)
-+#define PCIE_DATA_LINK_PROTOCOL_ERR 0x00000010 /* Data Link Protocol Error Status */
-+#define PCIE_SURPRISE_DOWN_ERROR 0x00000020 /* Surprise Down Error Status */
-+#define PCIE_POISONED_TLP 0x00001000 /* Poisoned TLP Status */
-+#define PCIE_FC_PROTOCOL_ERR 0x00002000 /* Flow Control Protocol Error Status */
-+#define PCIE_COMPLETION_TIMEOUT 0x00004000 /* Completion Timeout Status */
-+#define PCIE_COMPLETOR_ABORT 0x00008000 /* Completer Abort Error */
-+#define PCIE_UNEXPECTED_COMPLETION 0x00010000 /* Unexpected Completion Status */
-+#define PCIE_RECEIVER_OVERFLOW 0x00020000 /* Receive Overflow Status */
-+#define PCIE_MALFORNED_TLP 0x00040000 /* Malformed TLP Stauts */
-+#define PCIE_ECRC_ERR 0x00080000 /* ECRC Error Stauts */
-+#define PCIE_UR_REQ 0x00100000 /* Unsupported Request Error Status */
-+#define PCIE_ALL_UNCORRECTABLE_ERR (PCIE_DATA_LINK_PROTOCOL_ERR | PCIE_SURPRISE_DOWN_ERROR | \
-+ PCIE_POISONED_TLP | PCIE_FC_PROTOCOL_ERR | PCIE_COMPLETION_TIMEOUT | \
-+ PCIE_COMPLETOR_ABORT | PCIE_UNEXPECTED_COMPLETION | PCIE_RECEIVER_OVERFLOW |\
-+ PCIE_MALFORNED_TLP | PCIE_ECRC_ERR | PCIE_UR_REQ)
-+
-+/* Uncorrectable Error Mask Register, Mask means no report */
-+#define PCIE_UEMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x108)
-+
-+/* Uncorrectable Error Severity Register */
-+#define PCIE_UESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10C)
-+
-+/* Correctable Error Status Register */
-+#define PCIE_CESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x110)
-+#define PCIE_RX_ERR 0x00000001 /* Receive Error Status */
-+#define PCIE_BAD_TLP 0x00000040 /* Bad TLP Status */
-+#define PCIE_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-+#define PCIE_REPLAY_NUM_ROLLOVER 0x00000100 /* Replay Number Rollover Status */
-+#define PCIE_REPLAY_TIMER_TIMEOUT_ERR 0x00001000 /* Reply Timer Timeout Status */
-+#define PCIE_ADVISORY_NONFTAL_ERR 0x00002000 /* Advisory Non-Fatal Error Status */
-+#define PCIE_CORRECTABLE_ERR (PCIE_RX_ERR | PCIE_BAD_TLP | PCIE_BAD_DLLP | PCIE_REPLAY_NUM_ROLLOVER |\
-+ PCIE_REPLAY_TIMER_TIMEOUT_ERR | PCIE_ADVISORY_NONFTAL_ERR)
-+
-+/* Correctable Error Mask Register */
-+#define PCIE_CEMR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x114)
-+
-+/* Advanced Error Capabilities and Control Register */
-+#define PCIE_AECCR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x118)
-+#define PCIE_AECCR_FIRST_ERR_PTR 0x0000001F /* First Error Pointer */
-+#define PCIE_AECCR_FIRST_ERR_PTR_S 0
-+#define PCIE_AECCR_ECRC_GEN_CAP 0x00000020 /* ECRC Generation Capable */
-+#define PCIE_AECCR_ECRC_GEN_EN 0x00000040 /* ECRC Generation Enable */
-+#define PCIE_AECCR_ECRC_CHECK_CAP 0x00000080 /* ECRC Check Capable */
-+#define PCIE_AECCR_ECRC_CHECK_EN 0x00000100 /* ECRC Check Enable */
-+
-+/* Header Log Register 1 */
-+#define PCIE_HLR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x11C)
-+
-+/* Header Log Register 2 */
-+#define PCIE_HLR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x120)
-+
-+/* Header Log Register 3 */
-+#define PCIE_HLR3(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x124)
-+
-+/* Header Log Register 4 */
-+#define PCIE_HLR4(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x128)
-+
-+/* Root Error Command Register */
-+#define PCIE_RECR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x12C)
-+#define PCIE_RECR_CORRECTABLE_ERR_REPORT_EN 0x00000001 /* COR-ERR */
-+#define PCIE_RECR_NONFATAL_ERR_REPORT_EN 0x00000002 /* Non-Fatal ERR */
-+#define PCIE_RECR_FATAL_ERR_REPORT_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_RECR_ERR_REPORT_EN (PCIE_RECR_CORRECTABLE_ERR_REPORT_EN | \
-+ PCIE_RECR_NONFATAL_ERR_REPORT_EN | PCIE_RECR_FATAL_ERR_REPORT_EN)
-+
-+/* Root Error Status Register */
-+#define PCIE_RESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x130)
-+#define PCIE_RESR_CORRECTABLE_ERR 0x00000001 /* COR-ERR Receveid */
-+#define PCIE_RESR_MULTI_CORRECTABLE_ERR 0x00000002 /* Multiple COR-ERR Received */
-+#define PCIE_RESR_FATAL_NOFATAL_ERR 0x00000004 /* ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_MULTI_FATAL_NOFATAL_ERR 0x00000008 /* Multiple ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_FIRST_UNCORRECTABLE_FATAL_ERR 0x00000010 /* First UN-COR Fatal */
-+#define PCIR_RESR_NON_FATAL_ERR 0x00000020 /* Non-Fatal Error Message Received */
-+#define PCIE_RESR_FATAL_ERR 0x00000040 /* Fatal Message Received */
-+#define PCIE_RESR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_RESR_AER_INT_MSG_NUM_S 27
-+
-+/* Error Source Indentification Register */
-+#define PCIE_ESIR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x134)
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID 0x0000FFFF
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID_S 0
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID 0xFFFF0000
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID_S 16
-+
-+/* VC Enhanced Capability Header */
-+#define PCIE_VC_ECH(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x140)
-+
-+/* Port VC Capability Register */
-+#define PCIE_PVC1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x144)
-+#define PCIE_PVC1_EXT_VC_CNT 0x00000007 /* Extended VC Count */
-+#define PCIE_PVC1_EXT_VC_CNT_S 0
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT 0x00000070 /* Low Priority Extended VC Count */
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT_S 4
-+#define PCIE_PVC1_REF_CLK 0x00000300 /* Reference Clock */
-+#define PCIE_PVC1_REF_CLK_S 8
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE 0x00000C00 /* Port Arbitration Table Entry Size */
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE_S 10
-+
-+/* Extended Virtual Channel Count Defintion */
-+#define PCIE_EXT_VC_CNT_MIN 0
-+#define PCIE_EXT_VC_CNT_MAX 7
-+
-+/* Port Arbitration Table Entry Size Definition */
-+enum {
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S1BIT = 0,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S2BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S4BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S8BIT,
-+};
-+
-+/* Port VC Capability Register 2 */
-+#define PCIE_PVC2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x148)
-+#define PCIE_PVC2_VC_ARB_16P_FIXED_WRR 0x00000001 /* HW Fixed arbitration, 16 phase WRR */
-+#define PCIE_PVC2_VC_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_PVC2_VC_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_PVC2_VC_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_PVC2_VC_ARB_WRR 0x0000000F
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET 0xFF000000 /* VC arbitration table offset, not support */
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET_S 24
-+
-+/* Port VC Control and Status Register */
-+#define PCIE_PVCCRSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14C)
-+#define PCIE_PVCCRSR_LOAD_VC_ARB_TAB 0x00000001 /* Load VC Arbitration Table */
-+#define PCIE_PVCCRSR_VC_ARB_SEL 0x0000000E /* VC Arbitration Select */
-+#define PCIE_PVCCRSR_VC_ARB_SEL_S 1
-+#define PCIE_PVCCRSR_VC_ARB_TAB_STATUS 0x00010000 /* Arbitration Status */
-+
-+/* VC0 Resource Capability Register */
-+#define PCIE_VC0_RC(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x150)
-+#define PCIE_VC0_RC_PORT_ARB_HW_FIXED 0x00000001 /* HW Fixed arbitration */
-+#define PCIE_VC0_RC_PORT_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_128P_WRR 0x00000010 /* Time-based 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_256P_WRR 0x00000020 /* Time-based 256 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB (PCIE_VC0_RC_PORT_ARB_HW_FIXED | PCIE_VC0_RC_PORT_ARB_32P_WRR |\
-+ PCIE_VC0_RC_PORT_ARB_64P_WRR | PCIE_VC0_RC_PORT_ARB_128P_WRR | \
-+ PCIE_VC0_RC_PORT_ARB_TM_128P_WRR | PCIE_VC0_RC_PORT_ARB_TM_256P_WRR)
-+
-+#define PCIE_VC0_RC_REJECT_SNOOP 0x00008000 /* Reject Snoop Transactioin */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS 0x007F0000 /* Maximum time Slots */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS_S 16
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET 0xFF000000 /* Port Arbitration Table Offset */
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET_S 24
-+
-+/* VC0 Resource Control Register */
-+#define PCIE_VC0_RC0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x154)
-+#define PCIE_VC0_RC0_TVM0 0x00000001 /* TC0 and VC0 */
-+#define PCIE_VC0_RC0_TVM1 0x00000002 /* TC1 and VC1 */
-+#define PCIE_VC0_RC0_TVM2 0x00000004 /* TC2 and VC2 */
-+#define PCIE_VC0_RC0_TVM3 0x00000008 /* TC3 and VC3 */
-+#define PCIE_VC0_RC0_TVM4 0x00000010 /* TC4 and VC4 */
-+#define PCIE_VC0_RC0_TVM5 0x00000020 /* TC5 and VC5 */
-+#define PCIE_VC0_RC0_TVM6 0x00000040 /* TC6 and VC6 */
-+#define PCIE_VC0_RC0_TVM7 0x00000080 /* TC7 and VC7 */
-+#define PCIE_VC0_RC0_TC_VC 0x000000FF /* TC/VC mask */
-+
-+#define PCIE_VC0_RC0_LOAD_PORT_ARB_TAB 0x00010000 /* Load Port Arbitration Table */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL 0x000E0000 /* Port Arbitration Select */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL_S 17
-+#define PCIE_VC0_RC0_VC_ID 0x07000000 /* VC ID */
-+#define PCIE_VC0_RC0_VC_ID_S 24
-+#define PCIE_VC0_RC0_VC_EN 0x80000000 /* VC Enable */
-+
-+/* VC0 Resource Status Register */
-+#define PCIE_VC0_RSR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x158)
-+#define PCIE_VC0_RSR0_PORT_ARB_TAB_STATUS 0x00010000 /* Port Arbitration Table Status,not used */
-+#define PCIE_VC0_RSR0_VC_NEG_PENDING 0x00020000 /* VC Negotiation Pending */
-+
-+/* Ack Latency Timer and Replay Timer Register */
-+#define PCIE_ALTRT(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x700)
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT 0x0000FFFF /* Round Trip Latency Time Limit */
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT_S 0
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT 0xFFFF0000 /* Replay Time Limit */
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT_S 16
-+
-+/* Other Message Register */
-+#define PCIE_OMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x704)
-+
-+/* Port Force Link Register */
-+#define PCIE_PFLR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x708)
-+#define PCIE_PFLR_LINK_NUM 0x000000FF /* Link Number */
-+#define PCIE_PFLR_LINK_NUM_S 0
-+#define PCIE_PFLR_FORCE_LINK 0x00008000 /* Force link */
-+#define PCIE_PFLR_LINK_STATE 0x003F0000 /* Link State */
-+#define PCIE_PFLR_LINK_STATE_S 16
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT 0xFF000000 /* Low Power Entrance Count, only for EP */
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT_S 24
-+
-+/* Ack Frequency Register */
-+#define PCIE_AFR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70C)
-+#define PCIE_AFR_AF 0x000000FF /* Ack Frequency */
-+#define PCIE_AFR_AF_S 0
-+#define PCIE_AFR_FTS_NUM 0x0000FF00 /* The number of Fast Training Sequence from L0S to L0 */
-+#define PCIE_AFR_FTS_NUM_S 8
-+#define PCIE_AFR_COM_FTS_NUM 0x00FF0000 /* N_FTS; when common clock is used*/
-+#define PCIE_AFR_COM_FTS_NUM_S 16
-+#define PCIE_AFR_L0S_ENTRY_LATENCY 0x07000000 /* L0s Entrance Latency */
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_S 24
-+#define PCIE_AFR_L1_ENTRY_LATENCY 0x38000000 /* L1 Entrance Latency */
-+#define PCIE_AFR_L1_ENTRY_LATENCY_S 27
-+#define PCIE_AFR_FTS_NUM_DEFAULT 32
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT 7
-+#define PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT 5
-+
-+/* Port Link Control Register */
-+#define PCIE_PLCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x710)
-+#define PCIE_PLCR_OTHER_MSG_REQ 0x00000001 /* Other Message Request */
-+#define PCIE_PLCR_SCRAMBLE_DISABLE 0x00000002 /* Scramble Disable */
-+#define PCIE_PLCR_LOOPBACK_EN 0x00000004 /* Loopback Enable */
-+#define PCIE_PLCR_LTSSM_HOT_RST 0x00000008 /* Force LTSSM to the hot reset */
-+#define PCIE_PLCR_DLL_LINK_EN 0x00000020 /* Enable Link initialization */
-+#define PCIE_PLCR_FAST_LINK_SIM_EN 0x00000080 /* Sets all internal timers to fast mode for simulation purposes */
-+#define PCIE_PLCR_LINK_MODE 0x003F0000 /* Link Mode Enable Mask */
-+#define PCIE_PLCR_LINK_MODE_S 16
-+#define PCIE_PLCR_CORRUPTED_CRC_EN 0x02000000 /* Enabled Corrupt CRC */
-+
-+/* Lane Skew Register */
-+#define PCIE_LSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x714)
-+#define PCIE_LSR_LANE_SKEW_NUM 0x00FFFFFF /* Insert Lane Skew for Transmit, not applicable */
-+#define PCIE_LSR_LANE_SKEW_NUM_S 0
-+#define PCIE_LSR_FC_DISABLE 0x01000000 /* Disable of Flow Control */
-+#define PCIE_LSR_ACKNAK_DISABLE 0x02000000 /* Disable of Ack/Nak */
-+#define PCIE_LSR_LANE_DESKEW_DISABLE 0x80000000 /* Disable of Lane-to-Lane Skew */
-+
-+/* Symbol Number Register */
-+#define PCIE_SNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x718)
-+#define PCIE_SNR_TS 0x0000000F /* Number of TS Symbol */
-+#define PCIE_SNR_TS_S 0
-+#define PCIE_SNR_SKP 0x00000700 /* Number of SKP Symbol */
-+#define PCIE_SNR_SKP_S 8
-+#define PCIE_SNR_REPLAY_TIMER 0x0007C000 /* Timer Modifier for Replay Timer */
-+#define PCIE_SNR_REPLAY_TIMER_S 14
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER 0x00F80000 /* Timer Modifier for Ack/Nak Latency Timer */
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER_S 19
-+#define PCIE_SNR_FC_TIMER 0x1F000000 /* Timer Modifier for Flow Control Watchdog Timer */
-+#define PCIE_SNR_FC_TIMER_S 28
-+
-+/* Symbol Timer Register and Filter Mask Register 1 */
-+#define PCIE_STRFMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x71C)
-+#define PCIE_STRFMR_SKP_INTERVAL 0x000007FF /* SKP lnterval Value */
-+#define PCIE_STRFMR_SKP_INTERVAL_S 0
-+#define PCIE_STRFMR_FC_WDT_DISABLE 0x00008000 /* Disable of FC Watchdog Timer */
-+#define PCIE_STRFMR_TLP_FUNC_MISMATCH_OK 0x00010000 /* Mask Function Mismatch Filtering for Incoming Requests */
-+#define PCIE_STRFMR_POISONED_TLP_OK 0x00020000 /* Mask Poisoned TLP Filtering */
-+#define PCIE_STRFMR_BAR_MATCH_OK 0x00040000 /* Mask BAR Match Filtering */
-+#define PCIE_STRFMR_TYPE1_CFG_REQ_OK 0x00080000 /* Mask Type 1 Configuration Request Filtering */
-+#define PCIE_STRFMR_LOCKED_REQ_OK 0x00100000 /* Mask Locked Request Filtering */
-+#define PCIE_STRFMR_CPL_TAG_ERR_RULES_OK 0x00200000 /* Mask Tag Error Rules for Received Completions */
-+#define PCIE_STRFMR_CPL_REQUESTOR_ID_MISMATCH_OK 0x00400000 /* Mask Requester ID Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_FUNC_MISMATCH_OK 0x00800000 /* Mask Function Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_TC_MISMATCH_OK 0x01000000 /* Mask Traffic Class Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_ATTR_MISMATCH_OK 0x02000000 /* Mask Attribute Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_LENGTH_MISMATCH_OK 0x04000000 /* Mask Length Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_TLP_ECRC_ERR_OK 0x08000000 /* Mask ECRC Error Filtering */
-+#define PCIE_STRFMR_CPL_TLP_ECRC_OK 0x10000000 /* Mask ECRC Error Filtering for Completions */
-+#define PCIE_STRFMR_RX_TLP_MSG_NO_DROP 0x20000000 /* Send Message TLPs */
-+#define PCIE_STRFMR_RX_IO_TRANS_ENABLE 0x40000000 /* Mask Filtering of received I/O Requests */
-+#define PCIE_STRFMR_RX_CFG_TRANS_ENABLE 0x80000000 /* Mask Filtering of Received Configuration Requests */
-+
-+#define PCIE_DEF_SKP_INTERVAL 700 /* 1180 ~1538 , 125MHz * 2, 250MHz * 1 */
-+
-+/* Filter Masker Register 2 */
-+#define PCIE_FMR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x720)
-+#define PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1 0x00000001 /* Mask RADM Filtering and Error Handling Rules */
-+#define PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 0x00000002 /* Mask RADM Filtering and Error Handling Rules */
-+
-+/* Debug Register 0 */
-+#define PCIE_DBR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x728)
-+
-+/* Debug Register 1 */
-+#define PCIE_DBR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x72C)
-+
-+/* Transmit Posted FC Credit Status Register */
-+#define PCIE_TPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x730)
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS 0x00000FFF /* Transmit Posted Data FC Credits */
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS_S 0
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS 0x000FF000 /* Transmit Posted Header FC Credits */
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Non-Posted FC Credit Status */
-+#define PCIE_TNPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x734)
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS 0x00000FFF /* Transmit Non-Posted Data FC Credits */
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS_S 0
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS 0x000FF000 /* Transmit Non-Posted Header FC Credits */
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Complete FC Credit Status Register */
-+#define PCIE_TCFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x738)
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS 0x00000FFF /* Transmit Completion Data FC Credits */
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS_S 0
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS 0x000FF000 /* Transmit Completion Header FC Credits */
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS_S 12
-+
-+/* Queue Status Register */
-+#define PCIE_QSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x73C)
-+#define PCIE_QSR_WAIT_UPDATE_FC_DLL 0x00000001 /* Received TLP FC Credits Not Returned */
-+#define PCIE_QSR_TX_RETRY_BUF_NOT_EMPTY 0x00000002 /* Transmit Retry Buffer Not Empty */
-+#define PCIE_QSR_RX_QUEUE_NOT_EMPTY 0x00000004 /* Received Queue Not Empty */
-+
-+/* VC Transmit Arbitration Register 1 */
-+#define PCIE_VCTAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x740)
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC0 0x000000FF /* WRR Weight for VC0 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC1 0x0000FF00 /* WRR Weight for VC1 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC2 0x00FF0000 /* WRR Weight for VC2 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC3 0xFF000000 /* WRR Weight for VC3 */
-+
-+/* VC Transmit Arbitration Register 2 */
-+#define PCIE_VCTAR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x744)
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC4 0x000000FF /* WRR Weight for VC4 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC5 0x0000FF00 /* WRR Weight for VC5 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC6 0x00FF0000 /* WRR Weight for VC6 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC7 0xFF000000 /* WRR Weight for VC7 */
-+
-+/* VC0 Posted Receive Queue Control Register */
-+#define PCIE_VC0_PRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x748)
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS 0x00000FFF /* VC0 Posted Data Credits */
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS_S 0
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS 0x000FF000 /* VC0 Posted Header Credits */
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS_S 12
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE 0x00E00000 /* VC0 Posted TLP Queue Mode */
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE_S 20
-+#define PCIE_VC0_PRQCR_TLP_RELAX_ORDER 0x40000000 /* TLP Type Ordering for VC0 */
-+#define PCIE_VC0_PRQCR_VC_STRICT_ORDER 0x80000000 /* VC0 Ordering for Receive Queues */
-+
-+/* VC0 Non-Posted Receive Queue Control */
-+#define PCIE_VC0_NPRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74C)
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS 0x00000FFF /* VC0 Non-Posted Data Credits */
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS_S 0
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS 0x000FF000 /* VC0 Non-Posted Header Credits */
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS_S 12
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE 0x00E00000 /* VC0 Non-Posted TLP Queue Mode */
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE_S 20
-+
-+/* VC0 Completion Receive Queue Control */
-+#define PCIE_VC0_CRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x750)
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS 0x00000FFF /* VC0 Completion TLP Queue Mode */
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS_S 0
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS 0x000FF000 /* VC0 Completion Header Credits */
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS_S 12
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE 0x00E00000 /* VC0 Completion Data Credits */
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE_S 21
-+
-+/* Applicable to the above three registers */
-+enum {
-+ PCIE_VC0_TLP_QUEUE_MODE_STORE_FORWARD = 1,
-+ PCIE_VC0_TLP_QUEUE_MODE_CUT_THROUGH = 2,
-+ PCIE_VC0_TLP_QUEUE_MODE_BYPASS = 4,
-+};
-+
-+/* VC0 Posted Buffer Depth Register */
-+#define PCIE_VC0_PBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7A8)
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Posted Data Queue Depth */
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Posted Header Queue Depth */
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Non-Posted Buffer Depth Register */
-+#define PCIE_VC0_NPBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7AC)
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Non-Posted Data Queue Depth */
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Non-Posted Header Queue Depth */
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Completion Buffer Depth Register */
-+#define PCIE_VC0_CBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7B0)
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES 0x00003FFF /* C0 Completion Data Queue Depth */
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Completion Header Queue Depth */
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES_S 16
-+
-+/* PHY Status Register, all zeros in VR9 */
-+#define PCIE_PHYSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x810)
-+
-+/* PHY Control Register, all zeros in VR9 */
-+#define PCIE_PHYCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x814)
-+
-+/*
-+ * PCIe PDI PHY register definition, suppose all the following
-+ * stuff is confidential.
-+ * XXX, detailed bit definition
-+ */
-+#define PCIE_PHY_PLL_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x22 << 1))
-+#define PCIE_PHY_PLL_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x23 << 1))
-+#define PCIE_PHY_PLL_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x24 << 1))
-+#define PCIE_PHY_PLL_CTRL4(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x25 << 1))
-+#define PCIE_PHY_PLL_CTRL5(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x26 << 1))
-+#define PCIE_PHY_PLL_CTRL6(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x27 << 1))
-+#define PCIE_PHY_PLL_CTRL7(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x28 << 1))
-+#define PCIE_PHY_PLL_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x29 << 1))
-+#define PCIE_PHY_PLL_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2A << 1))
-+#define PCIE_PHY_PLL_A_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2B << 1))
-+#define PCIE_PHY_PLL_STATUS(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2C << 1))
-+
-+#define PCIE_PHY_TX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x30 << 1))
-+#define PCIE_PHY_TX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x31 << 1))
-+#define PCIE_PHY_TX1_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x32 << 1))
-+#define PCIE_PHY_TX1_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x33 << 1))
-+#define PCIE_PHY_TX1_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x34 << 1))
-+#define PCIE_PHY_TX1_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x35 << 1))
-+#define PCIE_PHY_TX1_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x36 << 1))
-+#define PCIE_PHY_TX1_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x37 << 1))
-+
-+#define PCIE_PHY_TX2_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x38 << 1))
-+#define PCIE_PHY_TX2_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x39 << 1))
-+#define PCIE_PHY_TX2_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3B << 1))
-+#define PCIE_PHY_TX2_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3C << 1))
-+#define PCIE_PHY_TX2_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3D << 1))
-+#define PCIE_PHY_TX2_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3E << 1))
-+#define PCIE_PHY_TX2_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3F << 1))
-+
-+#define PCIE_PHY_RX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x50 << 1))
-+#define PCIE_PHY_RX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x51 << 1))
-+#define PCIE_PHY_RX1_CDR(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x52 << 1))
-+#define PCIE_PHY_RX1_EI(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x53 << 1))
-+#define PCIE_PHY_RX1_A_CTRL(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x55 << 1))
-+
-+/* Interrupt related stuff */
-+#define PCIE_LEGACY_DISABLE 0
-+#define PCIE_LEGACY_INTA 1
-+#define PCIE_LEGACY_INTB 2
-+#define PCIE_LEGACY_INTC 3
-+#define PCIE_LEGACY_INTD 4
-+#define PCIE_LEGACY_INT_MAX PCIE_LEGACY_INTD
-+
-+#define PCIE_IRQ_LOCK(lock) do { \
-+ unsigned long flags; \
-+ spin_lock_irqsave(&(lock), flags);
-+#define PCIE_IRQ_UNLOCK(lock) \
-+ spin_unlock_irqrestore(&(lock), flags); \
-+} while (0)
-+
-+#define PCIE_MSG_MSI 0x00000001
-+#define PCIE_MSG_ISR 0x00000002
-+#define PCIE_MSG_FIXUP 0x00000004
-+#define PCIE_MSG_READ_CFG 0x00000008
-+#define PCIE_MSG_WRITE_CFG 0x00000010
-+#define PCIE_MSG_CFG (PCIE_MSG_READ_CFG | PCIE_MSG_WRITE_CFG)
-+#define PCIE_MSG_REG 0x00000020
-+#define PCIE_MSG_INIT 0x00000040
-+#define PCIE_MSG_ERR 0x00000080
-+#define PCIE_MSG_PHY 0x00000100
-+#define PCIE_MSG_ANY 0x000001ff
-+
-+#define IFX_PCIE_PORT0 0
-+#define IFX_PCIE_PORT1 1
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+#define IFX_PCIE_CORE_NR 2
-+#else
-+#define IFX_PCIE_CORE_NR 1
-+#endif
-+
-+//#define IFX_PCIE_ERROR_INT
-+
-+//#define IFX_PCIE_DBG
-+
-+#if defined(IFX_PCIE_DBG)
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) do { \
-+ if (g_pcie_debug_flag & (_m)) { \
-+ ifx_pcie_debug((_fmt), ##args); \
-+ } \
-+} while (0)
-+
-+#define INLINE
-+#else
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) \
-+ do {} while(0)
-+#define INLINE inline
-+#endif
-+
-+struct ifx_pci_controller {
-+ struct pci_controller pcic;
-+
-+ /* RC specific, per host bus information */
-+ u32 port; /* Port index, 0 -- 1st core, 1 -- 2nd core */
-+};
-+
-+typedef struct ifx_pcie_ir_irq {
-+ const unsigned int irq;
-+ const char name[16];
-+}ifx_pcie_ir_irq_t;
-+
-+typedef struct ifx_pcie_legacy_irq{
-+ const u32 irq_bit;
-+ const int irq;
-+}ifx_pcie_legacy_irq_t;
-+
-+typedef struct ifx_pcie_irq {
-+ ifx_pcie_ir_irq_t ir_irq;
-+ ifx_pcie_legacy_irq_t legacy_irq[PCIE_LEGACY_INT_MAX];
-+}ifx_pcie_irq_t;
-+
-+extern u32 g_pcie_debug_flag;
-+extern void ifx_pcie_debug(const char *fmt, ...);
-+extern void pcie_phy_clock_mode_setup(int pcie_port);
-+extern void pcie_msi_pic_init(int pcie_port);
-+extern u32 ifx_pcie_bus_enum_read_hack(int where, u32 value);
-+extern u32 ifx_pcie_bus_enum_write_hack(int where, u32 value);
-+
-+
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+#include <linux/gpio.h>
-+#include <linux/clk.h>
-+
-+#include <lantiq_soc.h>
-+
-+#define IFX_PCIE_GPIO_RESET 38
-+#define IFX_REG_R32 ltq_r32
-+#define IFX_REG_W32 ltq_w32
-+#define CONFIG_IFX_PCIE_HW_SWAP
-+#define IFX_RCU_AHB_ENDIAN ((volatile u32*)(IFX_RCU + 0x004C))
-+#define IFX_RCU_RST_REQ ((volatile u32*)(IFX_RCU + 0x0010))
-+#define IFX_RCU_AHB_BE_PCIE_PDI 0x00000080 /* Configure PCIE PDI module in big endian*/
-+
-+#define IFX_RCU (KSEG1 | 0x1F203000)
-+#define IFX_RCU_AHB_BE_PCIE_M 0x00000001 /* Configure AHB master port that connects to PCIe RC in big endian */
-+#define IFX_RCU_AHB_BE_PCIE_S 0x00000010 /* Configure AHB slave port that connects to PCIe RC in little endian */
-+#define IFX_RCU_AHB_BE_XBAR_M 0x00000002 /* Configure AHB master port that connects to XBAR in big endian */
-+#define CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+
-+#define IFX_PMU1_MODULE_PCIE_PHY (0)
-+#define IFX_PMU1_MODULE_PCIE_CTRL (1)
-+#define IFX_PMU1_MODULE_PDI (4)
-+#define IFX_PMU1_MODULE_MSI (5)
-+
-+#define IFX_PMU_MODULE_PCIE_L0_CLK (31)
-+
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "ahb");
-+ clk_enable(clk);
-+ //ltq_pmu_enable(PMU_AHBM | PMU_AHBS);
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg |= IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#else
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "phy");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1<<IFX_PMU1_MODULE_PCIE_PHY);
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "phy");
-+ clk_disable(clk);
-+ //ltq_pmu1_disable(1<<IFX_PMU1_MODULE_PCIE_PHY);
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* SRAM2PDI endianness control. */
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "pdi");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1<<IFX_PMU1_MODULE_PDI);
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-+ reg |= 0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ /* Reset PCIe PHY & Core, bit 22 */
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg |= 0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
-+ // ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+// ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "ctl");
-+ clk_enable(clk);
-+ clk = clk_get_sys("ltq_pcie", "bus");
-+ clk_enable(clk);
-+
-+ //ltq_pmu1_enable(1 << IFX_PMU1_MODULE_PCIE_CTRL);
-+ //ltq_pmu_enable(1 << IFX_PMU_MODULE_PCIE_L0_CLK);
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ struct clk *clk;
-+ pcie_msi_pic_init(pcie_port);
-+ clk = clk_get_sys("ltq_pcie", "msi");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1 << IFX_PMU1_MODULE_MSI);
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+#endif /* CONFIG_PCI_LANTIQ */
-+ return tbus_number;
-+}
-+
-+static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ #endif /* CONFIG_PCI_LANTIQ */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_VR9_H */
-+
---- a/drivers/pci/pcie/Kconfig
-+++ b/drivers/pci/pcie/Kconfig
-@@ -51,6 +51,7 @@ config PCIEAER_INJECT
- config PCIE_ECRC
- bool "PCI Express ECRC settings control"
- depends on PCIEAER
-+ default n
- help
- Used to override firmware/bios settings for PCI Express ECRC
- (transaction layer end-to-end CRC checking).
---- a/include/linux/pci.h
-+++ b/include/linux/pci.h
-@@ -1558,6 +1558,8 @@ void pci_walk_bus_locked(struct pci_bus
- void *userdata);
- int pci_cfg_space_size(struct pci_dev *dev);
- unsigned char pci_bus_max_busnr(struct pci_bus *bus);
-+int pcibios_host_nr(void);
-+int pcibios_1st_host_bus_nr(void);
- void pci_setup_bridge(struct pci_bus *bus);
- resource_size_t pcibios_window_alignment(struct pci_bus *bus,
- unsigned long type);
---- a/include/linux/pci_ids.h
-+++ b/include/linux/pci_ids.h
-@@ -1097,6 +1097,12 @@
- #define PCI_DEVICE_ID_SGI_IOC3 0x0003
- #define PCI_DEVICE_ID_SGI_LITHIUM 0x1002
-
-+#define PCI_VENDOR_ID_INFINEON 0x15D1
-+#define PCI_DEVICE_ID_INFINEON_DANUBE 0x000F
-+#define PCI_DEVICE_ID_INFINEON_PCIE 0x0011
-+#define PCI_VENDOR_ID_LANTIQ 0x1BEF
-+#define PCI_DEVICE_ID_LANTIQ_PCIE 0x0011
-+
- #define PCI_VENDOR_ID_WINBOND 0x10ad
- #define PCI_DEVICE_ID_WINBOND_82C105 0x0105
- #define PCI_DEVICE_ID_WINBOND_83C553 0x0565
diff --git a/target/linux/lantiq/patches-6.1/0004-MIPS-lantiq-add-atm-hack.patch b/target/linux/lantiq/patches-6.1/0004-MIPS-lantiq-add-atm-hack.patch
deleted file mode 100644
index e32e4e2daa..0000000000
--- a/target/linux/lantiq/patches-6.1/0004-MIPS-lantiq-add-atm-hack.patch
+++ /dev/null
@@ -1,482 +0,0 @@
-From 9afadf01b1be371ee88491819aa67364684461f9 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 3 Aug 2012 10:27:25 +0200
-Subject: [PATCH 04/36] MIPS: lantiq: add atm hack
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/include/asm/mach-lantiq/lantiq_atm.h | 196 +++++++++++++++++++++++
- arch/mips/include/asm/mach-lantiq/lantiq_ptm.h | 203 ++++++++++++++++++++++++
- arch/mips/lantiq/irq.c | 2 +
- arch/mips/mm/cache.c | 4 +
- include/uapi/linux/atm.h | 6 +
- net/atm/common.c | 6 +
- net/atm/proc.c | 2 +-
- 7 files changed, 416 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_atm.h
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_atm.h
-@@ -0,0 +1,196 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifx_atm.h
-+** PROJECT : UEIP
-+** MODULES : ATM
-+**
-+** DATE : 17 Jun 2009
-+** AUTHOR : Xu Liang
-+** DESCRIPTION : Global ATM driver header file
-+** COPYRIGHT : Copyright (c) 2006
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 07 JUL 2009 Xu Liang Init Version
-+*******************************************************************************/
-+
-+#ifndef IFX_ATM_H
-+#define IFX_ATM_H
-+
-+
-+
-+/*!
-+ \defgroup IFX_ATM UEIP Project - ATM driver module
-+ \brief UEIP Project - ATM driver module, support Danube, Amazon-SE, AR9, VR9.
-+ */
-+
-+/*!
-+ \defgroup IFX_ATM_IOCTL IOCTL Commands
-+ \ingroup IFX_ATM
-+ \brief IOCTL Commands used by user application.
-+ */
-+
-+/*!
-+ \defgroup IFX_ATM_STRUCT Structures
-+ \ingroup IFX_ATM
-+ \brief Structures used by user application.
-+ */
-+
-+/*!
-+ \file ifx_atm.h
-+ \ingroup IFX_ATM
-+ \brief ATM driver header file
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_ATM_STRUCT
-+ */
-+/*@{*/
-+
-+/*
-+ * ATM MIB
-+ */
-+
-+/*!
-+ \struct atm_cell_ifEntry_t
-+ \brief Structure used for Cell Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_CELL".
-+ */
-+typedef struct {
-+ __u32 ifHCInOctets_h; /*!< byte counter of ingress cells (upper 32 bits, total 64 bits) */
-+ __u32 ifHCInOctets_l; /*!< byte counter of ingress cells (lower 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_h; /*!< byte counter of egress cells (upper 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_l; /*!< byte counter of egress cells (lower 32 bits, total 64 bits) */
-+ __u32 ifInErrors; /*!< counter of error ingress cells */
-+ __u32 ifInUnknownProtos; /*!< counter of unknown ingress cells */
-+ __u32 ifOutErrors; /*!< counter of error egress cells */
-+} atm_cell_ifEntry_t;
-+
-+/*!
-+ \struct atm_aal5_ifEntry_t
-+ \brief Structure used for AAL5 Frame Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_AAL5".
-+ */
-+typedef struct {
-+ __u32 ifHCInOctets_h; /*!< byte counter of ingress packets (upper 32 bits, total 64 bits) */
-+ __u32 ifHCInOctets_l; /*!< byte counter of ingress packets (lower 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_h; /*!< byte counter of egress packets (upper 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_l; /*!< byte counter of egress packets (lower 32 bits, total 64 bits) */
-+ __u32 ifInUcastPkts; /*!< counter of ingress packets */
-+ __u32 ifOutUcastPkts; /*!< counter of egress packets */
-+ __u32 ifInErrors; /*!< counter of error ingress packets */
-+ __u32 ifInDiscards; /*!< counter of dropped ingress packets */
-+ __u32 ifOutErros; /*!< counter of error egress packets */
-+ __u32 ifOutDiscards; /*!< counter of dropped egress packets */
-+} atm_aal5_ifEntry_t;
-+
-+/*!
-+ \struct atm_aal5_vcc_t
-+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
-+
-+ This structure is a part of structure "atm_aal5_vcc_x_t".
-+ */
-+typedef struct {
-+ __u32 aal5VccCrcErrors; /*!< counter of ingress packets with CRC error */
-+ __u32 aal5VccSarTimeOuts; /*!< counter of ingress packets with Re-assemble timeout */ //no timer support yet
-+ __u32 aal5VccOverSizedSDUs; /*!< counter of oversized ingress packets */
-+} atm_aal5_vcc_t;
-+
-+/*!
-+ \struct atm_aal5_vcc_x_t
-+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_VCC".
-+ */
-+typedef struct {
-+ int vpi; /*!< VPI of the VCC to get MIB counters */
-+ int vci; /*!< VCI of the VCC to get MIB counters */
-+ atm_aal5_vcc_t mib_vcc; /*!< structure to get MIB counters */
-+} atm_aal5_vcc_x_t;
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * IOCTL
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_ATM_IOCTL
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Command
-+ */
-+/*!
-+ \brief ATM IOCTL Magic Number
-+ */
-+#define PPE_ATM_IOC_MAGIC 'o'
-+/*!
-+ \brief ATM IOCTL Command - Get Cell Level MIB Counters
-+
-+ This command is obsolete. User can get cell level MIB from DSL API.
-+ This command uses structure "atm_cell_ifEntry_t" as parameter for output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_CELL _IOW(PPE_ATM_IOC_MAGIC, 0, atm_cell_ifEntry_t)
-+/*!
-+ \brief ATM IOCTL Command - Get AAL5 Level MIB Counters
-+
-+ Get AAL5 packet counters.
-+ This command uses structure "atm_aal5_ifEntry_t" as parameter for output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_AAL5 _IOW(PPE_ATM_IOC_MAGIC, 1, atm_aal5_ifEntry_t)
-+/*!
-+ \brief ATM IOCTL Command - Get Per PVC MIB Counters
-+
-+ Get AAL5 packet counters for each PVC.
-+ This command uses structure "atm_aal5_vcc_x_t" as parameter for input of VPI/VCI information and output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_VCC _IOWR(PPE_ATM_IOC_MAGIC, 2, atm_aal5_vcc_x_t)
-+/*!
-+ \brief Total Number of ATM IOCTL Commands
-+ */
-+#define PPE_ATM_IOC_MAXNR 3
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * API
-+ * ####################################
-+ */
-+
-+#ifdef __KERNEL__
-+struct port_cell_info {
-+ unsigned int port_num;
-+ unsigned int tx_link_rate[2];
-+};
-+#endif
-+
-+
-+
-+#endif // IFX_ATM_H
-+
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
-@@ -0,0 +1,203 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifx_ptm.h
-+** PROJECT : UEIP
-+** MODULES : PTM
-+**
-+** DATE : 17 Jun 2009
-+** AUTHOR : Xu Liang
-+** DESCRIPTION : Global PTM driver header file
-+** COPYRIGHT : Copyright (c) 2006
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 07 JUL 2009 Xu Liang Init Version
-+*******************************************************************************/
-+
-+#ifndef IFX_PTM_H
-+#define IFX_PTM_H
-+
-+
-+
-+/*!
-+ \defgroup IFX_PTM UEIP Project - PTM driver module
-+ \brief UEIP Project - PTM driver module, support Danube, Amazon-SE, AR9, VR9.
-+ */
-+
-+/*!
-+ \defgroup IFX_PTM_IOCTL IOCTL Commands
-+ \ingroup IFX_PTM
-+ \brief IOCTL Commands used by user application.
-+ */
-+
-+/*!
-+ \defgroup IFX_PTM_STRUCT Structures
-+ \ingroup IFX_PTM
-+ \brief Structures used by user application.
-+ */
-+
-+/*!
-+ \file ifx_ptm.h
-+ \ingroup IFX_PTM
-+ \brief PTM driver header file
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * IOCTL
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_PTM_IOCTL
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Command
-+ */
-+/*!
-+ \brief PTM IOCTL Command - Get codeword MIB counters.
-+
-+ This command uses structure "PTM_CW_IF_ENTRY_T" to get codeword level MIB counters.
-+ */
-+#define IFX_PTM_MIB_CW_GET SIOCDEVPRIVATE + 1
-+/*!
-+ \brief PTM IOCTL Command - Get packet MIB counters.
-+
-+ This command uses structure "PTM_FRAME_MIB_T" to get packet level MIB counters.
-+ */
-+#define IFX_PTM_MIB_FRAME_GET SIOCDEVPRIVATE + 2
-+/*!
-+ \brief PTM IOCTL Command - Get firmware configuration (CRC).
-+
-+ This command uses structure "IFX_PTM_CFG_T" to get firmware configuration (CRC).
-+ */
-+#define IFX_PTM_CFG_GET SIOCDEVPRIVATE + 3
-+/*!
-+ \brief PTM IOCTL Command - Set firmware configuration (CRC).
-+
-+ This command uses structure "IFX_PTM_CFG_T" to set firmware configuration (CRC).
-+ */
-+#define IFX_PTM_CFG_SET SIOCDEVPRIVATE + 4
-+/*!
-+ \brief PTM IOCTL Command - Program priority value to TX queue mapping.
-+
-+ This command uses structure "IFX_PTM_PRIO_Q_MAP_T" to program priority value to TX queue mapping.
-+ */
-+#define IFX_PTM_MAP_PKT_PRIO_TO_Q SIOCDEVPRIVATE + 14
-+
-+/*@}*/
-+
-+
-+/*!
-+ \addtogroup IFX_PTM_STRUCT
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Data Type
-+ */
-+
-+/*!
-+ \typedef PTM_CW_IF_ENTRY_T
-+ \brief Wrapping of structure "ptm_cw_ifEntry_t".
-+ */
-+/*!
-+ \struct ptm_cw_ifEntry_t
-+ \brief Structure used for CodeWord level MIB counters.
-+ */
-+typedef struct ptm_cw_ifEntry_t {
-+ uint32_t ifRxNoIdleCodewords; /*!< output, number of ingress user codeword */
-+ uint32_t ifRxIdleCodewords; /*!< output, number of ingress idle codeword */
-+ uint32_t ifRxCodingViolation; /*!< output, number of error ingress codeword */
-+ uint32_t ifTxNoIdleCodewords; /*!< output, number of egress user codeword */
-+ uint32_t ifTxIdleCodewords; /*!< output, number of egress idle codeword */
-+} PTM_CW_IF_ENTRY_T;
-+
-+/*!
-+ \typedef PTM_FRAME_MIB_T
-+ \brief Wrapping of structure "ptm_frame_mib_t".
-+ */
-+/*!
-+ \struct ptm_frame_mib_t
-+ \brief Structure used for packet level MIB counters.
-+ */
-+typedef struct ptm_frame_mib_t {
-+ uint32_t RxCorrect; /*!< output, number of ingress packet */
-+ uint32_t TC_CrcError; /*!< output, number of egress packet with CRC error */
-+ uint32_t RxDropped; /*!< output, number of dropped ingress packet */
-+ uint32_t TxSend; /*!< output, number of egress packet */
-+} PTM_FRAME_MIB_T;
-+
-+/*!
-+ \typedef IFX_PTM_CFG_T
-+ \brief Wrapping of structure "ptm_cfg_t".
-+ */
-+/*!
-+ \struct ptm_cfg_t
-+ \brief Structure used for ETH/TC CRC configuration.
-+ */
-+typedef struct ptm_cfg_t {
-+ uint32_t RxEthCrcPresent; /*!< input/output, ingress packet has ETH CRC */
-+ uint32_t RxEthCrcCheck; /*!< input/output, check ETH CRC of ingress packet */
-+ uint32_t RxTcCrcCheck; /*!< input/output, check TC CRC of ingress codeword */
-+ uint32_t RxTcCrcLen; /*!< input/output, length of TC CRC of ingress codeword */
-+ uint32_t TxEthCrcGen; /*!< input/output, generate ETH CRC for egress packet */
-+ uint32_t TxTcCrcGen; /*!< input/output, generate TC CRC for egress codeword */
-+ uint32_t TxTcCrcLen; /*!< input/output, length of TC CRC of egress codeword */
-+} IFX_PTM_CFG_T;
-+
-+/*!
-+ \typedef IFX_PTM_PRIO_Q_MAP_T
-+ \brief Wrapping of structure "ppe_prio_q_map".
-+ */
-+/*!
-+ \struct ppe_prio_q_map
-+ \brief Structure used for Priority Value to TX Queue mapping.
-+ */
-+typedef struct ppe_prio_q_map {
-+ int pkt_prio;
-+ int qid;
-+ int vpi; // ignored in eth interface
-+ int vci; // ignored in eth interface
-+} IFX_PTM_PRIO_Q_MAP_T;
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * API
-+ * ####################################
-+ */
-+
-+#ifdef __KERNEL__
-+struct port_cell_info {
-+ unsigned int port_num;
-+ unsigned int tx_link_rate[2];
-+};
-+#endif
-+
-+
-+
-+#endif // IFX_PTM_H
-+
---- a/arch/mips/lantiq/irq.c
-+++ b/arch/mips/lantiq/irq.c
-@@ -13,6 +13,7 @@
- #include <linux/of_platform.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
-+#include <linux/module.h>
-
- #include <asm/bootinfo.h>
- #include <asm/irq_cpu.h>
-@@ -92,6 +93,7 @@ void ltq_disable_irq(struct irq_data *d)
- }
- raw_spin_unlock_irqrestore(&ltq_icu_lock, flags);
- }
-+EXPORT_SYMBOL(ltq_mask_and_ack_irq);
-
- void ltq_mask_and_ack_irq(struct irq_data *d)
- {
---- a/arch/mips/mm/cache.c
-+++ b/arch/mips/mm/cache.c
-@@ -63,6 +63,10 @@ void (*_dma_cache_wback_inv)(unsigned lo
- void (*_dma_cache_wback)(unsigned long start, unsigned long size);
- void (*_dma_cache_inv)(unsigned long start, unsigned long size);
-
-+EXPORT_SYMBOL(_dma_cache_wback_inv);
-+EXPORT_SYMBOL(_dma_cache_wback);
-+EXPORT_SYMBOL(_dma_cache_inv);
-+
- #endif /* CONFIG_DMA_NONCOHERENT */
-
- /*
---- a/include/uapi/linux/atm.h
-+++ b/include/uapi/linux/atm.h
-@@ -131,8 +131,14 @@
- #define ATM_ABR 4
- #define ATM_ANYCLASS 5 /* compatible with everything */
-
-+#define ATM_VBR_NRT ATM_VBR
-+#define ATM_VBR_RT 6
-+#define ATM_UBR_PLUS 7
-+#define ATM_GFR 8
-+
- #define ATM_MAX_PCR -1 /* maximum available PCR */
-
-+
- struct atm_trafprm {
- unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */
- int max_pcr; /* maximum PCR in cells per second */
---- a/net/atm/proc.c
-+++ b/net/atm/proc.c
-@@ -141,7 +141,7 @@ static void *vcc_seq_next(struct seq_fil
- static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
- {
- static const char *const class_name[] = {
-- "off", "UBR", "CBR", "VBR", "ABR"};
-+ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"};
- static const char *const aal_name[] = {
- "---", "1", "2", "3/4", /* 0- 3 */
- "???", "5", "???", "???", /* 4- 7 */
diff --git a/target/linux/lantiq/patches-6.1/0008-MIPS-lantiq-backport-old-timer-code.patch b/target/linux/lantiq/patches-6.1/0008-MIPS-lantiq-backport-old-timer-code.patch
deleted file mode 100644
index 3e6c267685..0000000000
--- a/target/linux/lantiq/patches-6.1/0008-MIPS-lantiq-backport-old-timer-code.patch
+++ /dev/null
@@ -1,1076 +0,0 @@
-From 94800350cb8d2f29dda2206b5e9a3772024ee168 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:30:56 +0200
-Subject: [PATCH 08/36] MIPS: lantiq: backport old timer code
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/include/asm/mach-lantiq/lantiq_timer.h | 155 ++++
- arch/mips/lantiq/xway/Makefile | 2 +-
- arch/mips/lantiq/xway/timer.c | 845 ++++++++++++++++++++++
- 3 files changed, 1001 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_timer.h
- create mode 100644 arch/mips/lantiq/xway/timer.c
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_timer.h
-@@ -0,0 +1,155 @@
-+#ifndef __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
-+#define __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
-+
-+
-+/******************************************************************************
-+ Copyright (c) 2002, Infineon Technologies. All rights reserved.
-+
-+ No Warranty
-+ 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.
-+
-+ 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.
-+******************************************************************************/
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+/*
-+ * Available Timer/Counter Index
-+ */
-+#define TIMER(n, X) (n * 2 + (X ? 1 : 0))
-+#define TIMER_ANY 0x00
-+#define TIMER1A TIMER(1, 0)
-+#define TIMER1B TIMER(1, 1)
-+#define TIMER2A TIMER(2, 0)
-+#define TIMER2B TIMER(2, 1)
-+#define TIMER3A TIMER(3, 0)
-+#define TIMER3B TIMER(3, 1)
-+
-+/*
-+ * Flag of Timer/Counter
-+ * These flags specify the way in which timer is configured.
-+ */
-+/* Bit size of timer/counter. */
-+#define TIMER_FLAG_16BIT 0x0000
-+#define TIMER_FLAG_32BIT 0x0001
-+/* Switch between timer and counter. */
-+#define TIMER_FLAG_TIMER 0x0000
-+#define TIMER_FLAG_COUNTER 0x0002
-+/* Stop or continue when overflowing/underflowing. */
-+#define TIMER_FLAG_ONCE 0x0000
-+#define TIMER_FLAG_CYCLIC 0x0004
-+/* Count up or counter down. */
-+#define TIMER_FLAG_UP 0x0000
-+#define TIMER_FLAG_DOWN 0x0008
-+/* Count on specific level or edge. */
-+#define TIMER_FLAG_HIGH_LEVEL_SENSITIVE 0x0000
-+#define TIMER_FLAG_LOW_LEVEL_SENSITIVE 0x0040
-+#define TIMER_FLAG_RISE_EDGE 0x0010
-+#define TIMER_FLAG_FALL_EDGE 0x0020
-+#define TIMER_FLAG_ANY_EDGE 0x0030
-+/* Signal is syncronous to module clock or not. */
-+#define TIMER_FLAG_UNSYNC 0x0000
-+#define TIMER_FLAG_SYNC 0x0080
-+/* Different interrupt handle type. */
-+#define TIMER_FLAG_NO_HANDLE 0x0000
-+#if defined(__KERNEL__)
-+ #define TIMER_FLAG_CALLBACK_IN_IRQ 0x0100
-+#endif // defined(__KERNEL__)
-+#define TIMER_FLAG_SIGNAL 0x0300
-+/* Internal clock source or external clock source */
-+#define TIMER_FLAG_INT_SRC 0x0000
-+#define TIMER_FLAG_EXT_SRC 0x1000
-+
-+
-+/*
-+ * ioctl Command
-+ */
-+#define GPTU_REQUEST_TIMER 0x01 /* General method to setup timer/counter. */
-+#define GPTU_FREE_TIMER 0x02 /* Free timer/counter. */
-+#define GPTU_START_TIMER 0x03 /* Start or resume timer/counter. */
-+#define GPTU_STOP_TIMER 0x04 /* Suspend timer/counter. */
-+#define GPTU_GET_COUNT_VALUE 0x05 /* Get current count value. */
-+#define GPTU_CALCULATE_DIVIDER 0x06 /* Calculate timer divider from given freq.*/
-+#define GPTU_SET_TIMER 0x07 /* Simplified method to setup timer. */
-+#define GPTU_SET_COUNTER 0x08 /* Simplified method to setup counter. */
-+
-+/*
-+ * Data Type Used to Call ioctl
-+ */
-+struct gptu_ioctl_param {
-+ unsigned int timer; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
-+ * GPTU_SET_COUNTER, this field is ID of expected *
-+ * timer/counter. If it's zero, a timer/counter would *
-+ * be dynamically allocated and ID would be stored in *
-+ * this field. *
-+ * In command GPTU_GET_COUNT_VALUE, this field is *
-+ * ignored. *
-+ * In other command, this field is ID of timer/counter *
-+ * allocated. */
-+ unsigned int flag; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
-+ * GPTU_SET_COUNTER, this field contains flags to *
-+ * specify how to configure timer/counter. *
-+ * In command GPTU_START_TIMER, zero indicate start *
-+ * and non-zero indicate resume timer/counter. *
-+ * In other command, this field is ignored. */
-+ unsigned long value; /* In command GPTU_REQUEST_TIMER, this field contains *
-+ * init/reload value. *
-+ * In command GPTU_SET_TIMER, this field contains *
-+ * frequency (0.001Hz) of timer. *
-+ * In command GPTU_GET_COUNT_VALUE, current count *
-+ * value would be stored in this field. *
-+ * In command GPTU_CALCULATE_DIVIDER, this field *
-+ * contains frequency wanted, and after calculation, *
-+ * divider would be stored in this field to overwrite *
-+ * the frequency. *
-+ * In other command, this field is ignored. */
-+ int pid; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
-+ * if signal is required, this field contains process *
-+ * ID to which signal would be sent. *
-+ * In other command, this field is ignored. */
-+ int sig; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
-+ * if signal is required, this field contains signal *
-+ * number which would be sent. *
-+ * In other command, this field is ignored. */
-+};
-+
-+/*
-+ * ####################################
-+ * Data Type
-+ * ####################################
-+ */
-+typedef void (*timer_callback)(unsigned long arg);
-+
-+extern int lq_request_timer(unsigned int, unsigned int, unsigned long, unsigned long, unsigned long);
-+extern int lq_free_timer(unsigned int);
-+extern int lq_start_timer(unsigned int, int);
-+extern int lq_stop_timer(unsigned int);
-+extern int lq_reset_counter_flags(u32 timer, u32 flags);
-+extern int lq_get_count_value(unsigned int, unsigned long *);
-+extern u32 lq_cal_divider(unsigned long);
-+extern int lq_set_timer(unsigned int, unsigned int, int, int, unsigned int, unsigned long, unsigned long);
-+extern int lq_set_counter(unsigned int timer, unsigned int flag,
-+ u32 reload, unsigned long arg1, unsigned long arg2);
-+
-+#endif /* __DANUBE_GPTU_DEV_H__2005_07_26__10_19__ */
---- a/arch/mips/lantiq/xway/Makefile
-+++ b/arch/mips/lantiq/xway/Makefile
-@@ -1,4 +1,10 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o
-+obj-y := prom.o sysctrl.o clk.o dma.o dcdc.o
-+
-+ifdef CONFIG_SOC_AMAZON_SE
-+obj-y += gptu.o
-+else
-+obj-y += timer.o
-+endif
-
- obj-y += vmmc.o
---- /dev/null
-+++ b/arch/mips/lantiq/xway/timer.c
-@@ -0,0 +1,887 @@
-+#ifndef CONFIG_SOC_AMAZON_SE
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/uaccess.h>
-+#include <linux/unistd.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/sched/signal.h>
-+
-+#include <linux/of_platform.h>
-+
-+#include <asm/irq.h>
-+#include <asm/div64.h>
-+#include "../clk.h"
-+
-+#include <lantiq_soc.h>
-+#include <lantiq_irq.h>
-+#include <lantiq_timer.h>
-+
-+#define MAX_NUM_OF_32BIT_TIMER_BLOCKS 6
-+
-+#ifdef TIMER1A
-+#define FIRST_TIMER TIMER1A
-+#else
-+#define FIRST_TIMER 2
-+#endif
-+
-+/*
-+ * GPTC divider is set or not.
-+ */
-+#define GPTU_CLC_RMC_IS_SET 0
-+
-+/*
-+ * Timer Interrupt (IRQ)
-+ */
-+/* Must be adjusted when ICU driver is available */
-+#define TIMER_INTERRUPT (INT_NUM_IM3_IRL0 + 22)
-+
-+/*
-+ * Bits Operation
-+ */
-+#define GET_BITS(x, msb, lsb) \
-+ (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
-+#define SET_BITS(x, msb, lsb, value) \
-+ (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | \
-+ (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
-+
-+/*
-+ * GPTU Register Mapping
-+ */
-+#define LQ_GPTU (KSEG1 + 0x1E100A00)
-+#define LQ_GPTU_CLC ((volatile u32 *)(LQ_GPTU + 0x0000))
-+#define LQ_GPTU_ID ((volatile u32 *)(LQ_GPTU + 0x0008))
-+#define LQ_GPTU_CON(n, X) ((volatile u32 *)(LQ_GPTU + 0x0010 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_RUN(n, X) ((volatile u32 *)(LQ_GPTU + 0x0018 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_RELOAD(n, X) ((volatile u32 *)(LQ_GPTU + 0x0020 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_COUNT(n, X) ((volatile u32 *)(LQ_GPTU + 0x0028 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_IRNEN ((volatile u32 *)(LQ_GPTU + 0x00F4))
-+#define LQ_GPTU_IRNICR ((volatile u32 *)(LQ_GPTU + 0x00F8))
-+#define LQ_GPTU_IRNCR ((volatile u32 *)(LQ_GPTU + 0x00FC))
-+
-+/*
-+ * Clock Control Register
-+ */
-+#define GPTU_CLC_SMC GET_BITS(*LQ_GPTU_CLC, 23, 16)
-+#define GPTU_CLC_RMC GET_BITS(*LQ_GPTU_CLC, 15, 8)
-+#define GPTU_CLC_FSOE (*LQ_GPTU_CLC & (1 << 5))
-+#define GPTU_CLC_EDIS (*LQ_GPTU_CLC & (1 << 3))
-+#define GPTU_CLC_SPEN (*LQ_GPTU_CLC & (1 << 2))
-+#define GPTU_CLC_DISS (*LQ_GPTU_CLC & (1 << 1))
-+#define GPTU_CLC_DISR (*LQ_GPTU_CLC & (1 << 0))
-+
-+#define GPTU_CLC_SMC_SET(value) SET_BITS(0, 23, 16, (value))
-+#define GPTU_CLC_RMC_SET(value) SET_BITS(0, 15, 8, (value))
-+#define GPTU_CLC_FSOE_SET(value) ((value) ? (1 << 5) : 0)
-+#define GPTU_CLC_SBWE_SET(value) ((value) ? (1 << 4) : 0)
-+#define GPTU_CLC_EDIS_SET(value) ((value) ? (1 << 3) : 0)
-+#define GPTU_CLC_SPEN_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_CLC_DISR_SET(value) ((value) ? (1 << 0) : 0)
-+
-+/*
-+ * ID Register
-+ */
-+#define GPTU_ID_ID GET_BITS(*LQ_GPTU_ID, 15, 8)
-+#define GPTU_ID_CFG GET_BITS(*LQ_GPTU_ID, 7, 5)
-+#define GPTU_ID_REV GET_BITS(*LQ_GPTU_ID, 4, 0)
-+
-+/*
-+ * Control Register of Timer/Counter nX
-+ * n is the index of block (1 based index)
-+ * X is either A or B
-+ */
-+#define GPTU_CON_SRC_EG(n, X) (*LQ_GPTU_CON(n, X) & (1 << 10))
-+#define GPTU_CON_SRC_EXT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 9))
-+#define GPTU_CON_SYNC(n, X) (*LQ_GPTU_CON(n, X) & (1 << 8))
-+#define GPTU_CON_EDGE(n, X) GET_BITS(*LQ_GPTU_CON(n, X), 7, 6)
-+#define GPTU_CON_INV(n, X) (*LQ_GPTU_CON(n, X) & (1 << 5))
-+#define GPTU_CON_EXT(n, X) (*LQ_GPTU_CON(n, A) & (1 << 4)) /* Timer/Counter B does not have this bit */
-+#define GPTU_CON_STP(n, X) (*LQ_GPTU_CON(n, X) & (1 << 3))
-+#define GPTU_CON_CNT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 2))
-+#define GPTU_CON_DIR(n, X) (*LQ_GPTU_CON(n, X) & (1 << 1))
-+#define GPTU_CON_EN(n, X) (*LQ_GPTU_CON(n, X) & (1 << 0))
-+
-+#define GPTU_CON_SRC_EG_SET(value) ((value) ? 0 : (1 << 10))
-+#define GPTU_CON_SRC_EXT_SET(value) ((value) ? (1 << 9) : 0)
-+#define GPTU_CON_SYNC_SET(value) ((value) ? (1 << 8) : 0)
-+#define GPTU_CON_EDGE_SET(value) SET_BITS(0, 7, 6, (value))
-+#define GPTU_CON_INV_SET(value) ((value) ? (1 << 5) : 0)
-+#define GPTU_CON_EXT_SET(value) ((value) ? (1 << 4) : 0)
-+#define GPTU_CON_STP_SET(value) ((value) ? (1 << 3) : 0)
-+#define GPTU_CON_CNT_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_CON_DIR_SET(value) ((value) ? (1 << 1) : 0)
-+
-+#define GPTU_RUN_RL_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_RUN_CEN_SET(value) ((value) ? (1 << 1) : 0)
-+#define GPTU_RUN_SEN_SET(value) ((value) ? (1 << 0) : 0)
-+
-+#define GPTU_IRNEN_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
-+#define GPTU_IRNCR_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
-+
-+#define TIMER_FLAG_MASK_SIZE(x) (x & 0x0001)
-+#define TIMER_FLAG_MASK_TYPE(x) (x & 0x0002)
-+#define TIMER_FLAG_MASK_STOP(x) (x & 0x0004)
-+#define TIMER_FLAG_MASK_DIR(x) (x & 0x0008)
-+#define TIMER_FLAG_NONE_EDGE 0x0000
-+#define TIMER_FLAG_MASK_EDGE(x) (x & 0x0030)
-+#define TIMER_FLAG_REAL 0x0000
-+#define TIMER_FLAG_INVERT 0x0040
-+#define TIMER_FLAG_MASK_INVERT(x) (x & 0x0040)
-+#define TIMER_FLAG_MASK_TRIGGER(x) (x & 0x0070)
-+#define TIMER_FLAG_MASK_SYNC(x) (x & 0x0080)
-+#define TIMER_FLAG_CALLBACK_IN_HB 0x0200
-+#define TIMER_FLAG_MASK_HANDLE(x) (x & 0x0300)
-+#define TIMER_FLAG_MASK_SRC(x) (x & 0x1000)
-+
-+struct timer_dev_timer {
-+ unsigned int f_irq_on;
-+ unsigned int irq;
-+ unsigned int flag;
-+ unsigned long arg1;
-+ unsigned long arg2;
-+};
-+
-+struct timer_dev {
-+ struct mutex gptu_mutex;
-+ unsigned int number_of_timers;
-+ unsigned int occupation;
-+ unsigned int f_gptu_on;
-+ struct timer_dev_timer timer[MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2];
-+};
-+
-+
-+unsigned int ltq_get_fpi_bus_clock(int fpi) {
-+ struct clk *clk = clk_get_fpi();
-+ return clk_get_rate(clk);
-+}
-+
-+
-+static long gptu_ioctl(struct file *, unsigned int, unsigned long);
-+static int gptu_open(struct inode *, struct file *);
-+static int gptu_release(struct inode *, struct file *);
-+
-+static struct file_operations gptu_fops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = gptu_ioctl,
-+ .open = gptu_open,
-+ .release = gptu_release
-+};
-+
-+static struct miscdevice gptu_miscdev = {
-+ .minor = MISC_DYNAMIC_MINOR,
-+ .name = "gptu",
-+ .fops = &gptu_fops,
-+};
-+
-+static struct timer_dev timer_dev;
-+
-+static irqreturn_t timer_irq_handler(int irq, void *p)
-+{
-+ unsigned int timer;
-+ unsigned int flag;
-+ struct timer_dev_timer *dev_timer = (struct timer_dev_timer *)p;
-+
-+ timer = irq - TIMER_INTERRUPT;
-+ if (timer < timer_dev.number_of_timers
-+ && dev_timer == &timer_dev.timer[timer]) {
-+ /* Clear interrupt. */
-+ ltq_w32(1 << timer, LQ_GPTU_IRNCR);
-+
-+ /* Call user hanler or signal. */
-+ flag = dev_timer->flag;
-+ if (!(timer & 0x01)
-+ || TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
-+ /* 16-bit timer or timer A of 32-bit timer */
-+ switch (TIMER_FLAG_MASK_HANDLE(flag)) {
-+ case TIMER_FLAG_CALLBACK_IN_IRQ:
-+ case TIMER_FLAG_CALLBACK_IN_HB:
-+ if (dev_timer->arg1)
-+ (*(timer_callback)dev_timer->arg1)(dev_timer->arg2);
-+ break;
-+ case TIMER_FLAG_SIGNAL:
-+ send_sig((int)dev_timer->arg2, (struct task_struct *)dev_timer->arg1, 0);
-+ break;
-+ }
-+ }
-+ }
-+ return IRQ_HANDLED;
-+}
-+
-+static inline void lq_enable_gptu(void)
-+{
-+ struct clk *clk = clk_get_sys("1e100a00.gptu", NULL);
-+ clk_enable(clk);
-+
-+ //ltq_pmu_enable(PMU_GPT);
-+
-+ /* Set divider as 1, disable write protection for SPEN, enable module. */
-+ *LQ_GPTU_CLC =
-+ GPTU_CLC_SMC_SET(0x00) |
-+ GPTU_CLC_RMC_SET(0x01) |
-+ GPTU_CLC_FSOE_SET(0) |
-+ GPTU_CLC_SBWE_SET(1) |
-+ GPTU_CLC_EDIS_SET(0) |
-+ GPTU_CLC_SPEN_SET(0) |
-+ GPTU_CLC_DISR_SET(0);
-+}
-+
-+static inline void lq_disable_gptu(void)
-+{
-+ struct clk *clk = clk_get_sys("1e100a00.gptu", NULL);
-+ ltq_w32(0x00, LQ_GPTU_IRNEN);
-+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
-+
-+ /* Set divider as 0, enable write protection for SPEN, disable module. */
-+ *LQ_GPTU_CLC =
-+ GPTU_CLC_SMC_SET(0x00) |
-+ GPTU_CLC_RMC_SET(0x00) |
-+ GPTU_CLC_FSOE_SET(0) |
-+ GPTU_CLC_SBWE_SET(0) |
-+ GPTU_CLC_EDIS_SET(0) |
-+ GPTU_CLC_SPEN_SET(0) |
-+ GPTU_CLC_DISR_SET(1);
-+
-+ clk_enable(clk);
-+}
-+
-+int lq_request_timer(unsigned int timer, unsigned int flag,
-+ unsigned long value, unsigned long arg1, unsigned long arg2)
-+{
-+ int ret = 0;
-+ unsigned int con_reg, irnen_reg;
-+ int n, X;
-+
-+ if (timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ printk(KERN_INFO "request_timer(%d, 0x%08X, %lu)...",
-+ timer, flag, value);
-+
-+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT)
-+ value &= 0xFFFF;
-+ else
-+ timer &= ~0x01;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ /*
-+ * Allocate timer.
-+ */
-+ if (timer < FIRST_TIMER) {
-+ unsigned int mask;
-+ unsigned int shift;
-+ /* This takes care of TIMER1B which is the only choice for Voice TAPI system */
-+ unsigned int offset = TIMER2A;
-+
-+ /*
-+ * Pick up a free timer.
-+ */
-+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
-+ mask = 1 << offset;
-+ shift = 1;
-+ } else {
-+ mask = 3 << offset;
-+ shift = 2;
-+ }
-+ for (timer = offset;
-+ timer < offset + timer_dev.number_of_timers;
-+ timer += shift, mask <<= shift)
-+ if (!(timer_dev.occupation & mask)) {
-+ timer_dev.occupation |= mask;
-+ break;
-+ }
-+ if (timer >= offset + timer_dev.number_of_timers) {
-+ printk("failed![%d]\n", __LINE__);
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ } else
-+ ret = timer;
-+ } else {
-+ register unsigned int mask;
-+
-+ /*
-+ * Check if the requested timer is free.
-+ */
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if ((timer_dev.occupation & mask)) {
-+ printk("failed![%d] mask %#x, timer_dev.occupation %#x\n",
-+ __LINE__, mask, timer_dev.occupation);
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EBUSY;
-+ } else {
-+ timer_dev.occupation |= mask;
-+ ret = 0;
-+ }
-+ }
-+
-+ /*
-+ * Prepare control register value.
-+ */
-+ switch (TIMER_FLAG_MASK_EDGE(flag)) {
-+ default:
-+ case TIMER_FLAG_NONE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x00);
-+ break;
-+ case TIMER_FLAG_RISE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x01);
-+ break;
-+ case TIMER_FLAG_FALL_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x02);
-+ break;
-+ case TIMER_FLAG_ANY_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x03);
-+ break;
-+ }
-+ if (TIMER_FLAG_MASK_TYPE(flag) == TIMER_FLAG_TIMER)
-+ con_reg |=
-+ TIMER_FLAG_MASK_SRC(flag) ==
-+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) :
-+ GPTU_CON_SRC_EXT_SET(0);
-+ else
-+ con_reg |=
-+ TIMER_FLAG_MASK_SRC(flag) ==
-+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) :
-+ GPTU_CON_SRC_EG_SET(0);
-+ con_reg |=
-+ TIMER_FLAG_MASK_SYNC(flag) ==
-+ TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) :
-+ GPTU_CON_SYNC_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_INVERT(flag) ==
-+ TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_SIZE(flag) ==
-+ TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) :
-+ GPTU_CON_EXT_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_STOP(flag) ==
-+ TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
-+ con_reg |=
-+ TIMER_FLAG_MASK_TYPE(flag) ==
-+ TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) :
-+ GPTU_CON_CNT_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_DIR(flag) ==
-+ TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
-+
-+ /*
-+ * Fill up running data.
-+ */
-+ timer_dev.timer[timer - FIRST_TIMER].flag = flag;
-+ timer_dev.timer[timer - FIRST_TIMER].arg1 = arg1;
-+ timer_dev.timer[timer - FIRST_TIMER].arg2 = arg2;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flag;
-+
-+ /*
-+ * Enable GPTU module.
-+ */
-+ if (!timer_dev.f_gptu_on) {
-+ lq_enable_gptu();
-+ timer_dev.f_gptu_on = 1;
-+ }
-+
-+ /*
-+ * Enable IRQ.
-+ */
-+ if (TIMER_FLAG_MASK_HANDLE(flag) != TIMER_FLAG_NO_HANDLE) {
-+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL)
-+ timer_dev.timer[timer - FIRST_TIMER].arg1 =
-+ (unsigned long) find_task_by_vpid((int) arg1);
-+
-+ irnen_reg = 1 << (timer - FIRST_TIMER);
-+
-+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL
-+ || (TIMER_FLAG_MASK_HANDLE(flag) ==
-+ TIMER_FLAG_CALLBACK_IN_IRQ
-+ && timer_dev.timer[timer - FIRST_TIMER].arg1)) {
-+ enable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
-+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 1;
-+ }
-+ } else
-+ irnen_reg = 0;
-+
-+ /*
-+ * Write config register, reload value and enable interrupt.
-+ */
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+ *LQ_GPTU_CON(n, X) = con_reg;
-+ *LQ_GPTU_RELOAD(n, X) = value;
-+ /* printk("reload value = %d\n", (u32)value); */
-+ *LQ_GPTU_IRNEN |= irnen_reg;
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ printk("successful!\n");
-+ return ret;
-+}
-+EXPORT_SYMBOL(lq_request_timer);
-+
-+int lq_free_timer(unsigned int timer)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ if (GPTU_CON_EN(n, X))
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
-+
-+ *LQ_GPTU_IRNEN &= ~GPTU_IRNEN_TC_SET(n, X, 1);
-+ *LQ_GPTU_IRNCR |= GPTU_IRNCR_TC_SET(n, X, 1);
-+
-+ if (timer_dev.timer[timer - FIRST_TIMER].f_irq_on) {
-+ disable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
-+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 0;
-+ }
-+
-+ timer_dev.occupation &= ~mask;
-+ if (!timer_dev.occupation && timer_dev.f_gptu_on) {
-+ lq_disable_gptu();
-+ timer_dev.f_gptu_on = 0;
-+ }
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_free_timer);
-+
-+int lq_start_timer(unsigned int timer, int is_resume)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) ==
-+ TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_RL_SET(!is_resume) | GPTU_RUN_SEN_SET(1);
-+
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_start_timer);
-+
-+int lq_stop_timer(unsigned int timer)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER
-+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_stop_timer);
-+
-+int lq_reset_counter_flags(u32 timer, u32 flags)
-+{
-+ unsigned int oflag;
-+ unsigned int mask, con_reg;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ oflag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(oflag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(oflag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ switch (TIMER_FLAG_MASK_EDGE(flags)) {
-+ default:
-+ case TIMER_FLAG_NONE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x00);
-+ break;
-+ case TIMER_FLAG_RISE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x01);
-+ break;
-+ case TIMER_FLAG_FALL_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x02);
-+ break;
-+ case TIMER_FLAG_ANY_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x03);
-+ break;
-+ }
-+ if (TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER)
-+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) : GPTU_CON_SRC_EXT_SET(0);
-+ else
-+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) : GPTU_CON_SRC_EG_SET(0);
-+ con_reg |= TIMER_FLAG_MASK_SYNC(flags) == TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) : GPTU_CON_SYNC_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_INVERT(flags) == TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_SIZE(flags) == TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) : GPTU_CON_EXT_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_STOP(flags) == TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
-+ con_reg |= TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) : GPTU_CON_CNT_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_DIR(flags) == TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
-+
-+ timer_dev.timer[timer - FIRST_TIMER].flag = flags;
-+ if (TIMER_FLAG_MASK_SIZE(flags) != TIMER_FLAG_16BIT)
-+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flags;
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_CON(n, X) = con_reg;
-+ smp_wmb();
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_reset_counter_flags);
-+
-+int lq_get_count_value(unsigned int timer, unsigned long *value)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER
-+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *value = *LQ_GPTU_COUNT(n, X);
-+
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_get_count_value);
-+
-+u32 lq_cal_divider(unsigned long freq)
-+{
-+ u64 module_freq, fpi = ltq_get_fpi_bus_clock(2);
-+ u32 clock_divider = 1;
-+ module_freq = fpi * 1000;
-+ do_div(module_freq, clock_divider * freq);
-+ return module_freq;
-+}
-+EXPORT_SYMBOL(lq_cal_divider);
-+
-+int lq_set_timer(unsigned int timer, unsigned int freq, int is_cyclic,
-+ int is_ext_src, unsigned int handle_flag, unsigned long arg1,
-+ unsigned long arg2)
-+{
-+ unsigned long divider;
-+ unsigned int flag;
-+
-+ divider = lq_cal_divider(freq);
-+ if (divider == 0)
-+ return -EINVAL;
-+ flag = ((divider & ~0xFFFF) ? TIMER_FLAG_32BIT : TIMER_FLAG_16BIT)
-+ | (is_cyclic ? TIMER_FLAG_CYCLIC : TIMER_FLAG_ONCE)
-+ | (is_ext_src ? TIMER_FLAG_EXT_SRC : TIMER_FLAG_INT_SRC)
-+ | TIMER_FLAG_TIMER | TIMER_FLAG_DOWN
-+ | TIMER_FLAG_MASK_HANDLE(handle_flag);
-+
-+ printk(KERN_INFO "lq_set_timer(%d, %d), divider = %lu\n",
-+ timer, freq, divider);
-+ return lq_request_timer(timer, flag, divider, arg1, arg2);
-+}
-+EXPORT_SYMBOL(lq_set_timer);
-+
-+int lq_set_counter(unsigned int timer, unsigned int flag, u32 reload,
-+ unsigned long arg1, unsigned long arg2)
-+{
-+ printk(KERN_INFO "lq_set_counter(%d, %#x, %d)\n", timer, flag, reload);
-+ return lq_request_timer(timer, flag, reload, arg1, arg2);
-+}
-+EXPORT_SYMBOL(lq_set_counter);
-+
-+static long gptu_ioctl(struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ int ret;
-+ struct gptu_ioctl_param param;
-+
-+ if (!access_ok((void __user *)arg, sizeof(struct gptu_ioctl_param)))
-+ return -EFAULT;
-+ if (copy_from_user(&param, (void __user *)arg, sizeof(param)))
-+ return -EFAULT;
-+
-+ if ((((cmd == GPTU_REQUEST_TIMER || cmd == GPTU_SET_TIMER
-+ || GPTU_SET_COUNTER) && param.timer < 2)
-+ || cmd == GPTU_GET_COUNT_VALUE || cmd == GPTU_CALCULATE_DIVIDER)
-+ && !access_ok((void __user *)arg,
-+ sizeof(struct gptu_ioctl_param)))
-+ return -EFAULT;
-+
-+ switch (cmd) {
-+ case GPTU_REQUEST_TIMER:
-+ ret = lq_request_timer(param.timer, param.flag, param.value,
-+ (unsigned long) param.pid,
-+ (unsigned long) param.sig);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ case GPTU_FREE_TIMER:
-+ ret = lq_free_timer(param.timer);
-+ break;
-+ case GPTU_START_TIMER:
-+ ret = lq_start_timer(param.timer, param.flag);
-+ break;
-+ case GPTU_STOP_TIMER:
-+ ret = lq_stop_timer(param.timer);
-+ break;
-+ case GPTU_GET_COUNT_VALUE:
-+ ret = lq_get_count_value(param.timer, &param.value);
-+ if (!ret && copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ value, &param.value,sizeof(param.value)))
-+ ret = -EFAULT;
-+ break;
-+ case GPTU_CALCULATE_DIVIDER:
-+ param.value = lq_cal_divider(param.value);
-+ if (param.value == 0)
-+ ret = -EINVAL;
-+ else if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ value, &param.value,
-+ sizeof(param.value)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ break;
-+ case GPTU_SET_TIMER:
-+ ret = lq_set_timer(param.timer, param.value,
-+ TIMER_FLAG_MASK_STOP(param.flag) !=
-+ TIMER_FLAG_ONCE ? 1 : 0,
-+ TIMER_FLAG_MASK_SRC(param.flag) ==
-+ TIMER_FLAG_EXT_SRC ? 1 : 0,
-+ TIMER_FLAG_MASK_HANDLE(param.flag) ==
-+ TIMER_FLAG_SIGNAL ? TIMER_FLAG_SIGNAL :
-+ TIMER_FLAG_NO_HANDLE,
-+ (unsigned long) param.pid,
-+ (unsigned long) param.sig);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ case GPTU_SET_COUNTER:
-+ lq_set_counter(param.timer, param.flag, param.value, 0, 0);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ default:
-+ ret = -ENOTTY;
-+ }
-+
-+ return ret;
-+}
-+
-+static int gptu_open(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int gptu_release(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int gptu_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int i;
-+
-+ ltq_w32(0, LQ_GPTU_IRNEN);
-+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
-+
-+ memset(&timer_dev, 0, sizeof(timer_dev));
-+ mutex_init(&timer_dev.gptu_mutex);
-+
-+ lq_enable_gptu();
-+ timer_dev.number_of_timers = GPTU_ID_CFG * 2;
-+ lq_disable_gptu();
-+ if (timer_dev.number_of_timers > MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2)
-+ timer_dev.number_of_timers = MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2;
-+ printk(KERN_INFO "gptu: totally %d 16-bit timers/counters\n", timer_dev.number_of_timers);
-+
-+ ret = misc_register(&gptu_miscdev);
-+ if (ret) {
-+ printk(KERN_ERR "gptu: can't misc_register, get error %d\n", -ret);
-+ return ret;
-+ } else {
-+ printk(KERN_INFO "gptu: misc_register on minor %d\n", gptu_miscdev.minor);
-+ }
-+
-+ for (i = 0; i < timer_dev.number_of_timers; i++) {
-+ int irq = platform_get_irq(pdev, i);
-+ if (irq < 0) {
-+ printk(KERN_ERR "gptu: failed in getting irq (%d), get error %d\n", i, irq);
-+ for (i--; i >= 0; i--)
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ misc_deregister(&gptu_miscdev);
-+ return irq;
-+ }
-+
-+ ret = request_irq(irq, timer_irq_handler, IRQF_TIMER, gptu_miscdev.name, &timer_dev.timer[i]);
-+ if (ret) {
-+ printk(KERN_ERR "gptu: failed in requesting irq (%d), get error %d\n", i, -ret);
-+ for (i--; i >= 0; i--)
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ misc_deregister(&gptu_miscdev);
-+ return ret;
-+ } else {
-+ timer_dev.timer[i].irq = irq;
-+ disable_irq(timer_dev.timer[i].irq);
-+ printk(KERN_INFO "gptu: succeeded to request irq %d\n", timer_dev.timer[i].irq);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id gptu_match[] = {
-+ { .compatible = "lantiq,gptu-xway" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, gptu_match);
-+
-+static struct platform_driver gptu_driver = {
-+ .probe = gptu_probe,
-+ .driver = {
-+ .name = "gptu-xway",
-+ .owner = THIS_MODULE,
-+ .of_match_table = gptu_match,
-+ },
-+};
-+
-+int __init lq_gptu_init(void)
-+{
-+ int ret = platform_driver_register(&gptu_driver);
-+
-+ if (ret)
-+ pr_info("gptu: Error registering platform driver\n");
-+ return ret;
-+}
-+
-+void __exit lq_gptu_exit(void)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < timer_dev.number_of_timers; i++) {
-+ if (timer_dev.timer[i].f_irq_on)
-+ disable_irq(timer_dev.timer[i].irq);
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ }
-+ lq_disable_gptu();
-+ misc_deregister(&gptu_miscdev);
-+}
-+
-+module_init(lq_gptu_init);
-+module_exit(lq_gptu_exit);
-+
-+#endif
diff --git a/target/linux/lantiq/patches-6.1/0018-MTD-nand-lots-of-xrx200-fixes.patch b/target/linux/lantiq/patches-6.1/0018-MTD-nand-lots-of-xrx200-fixes.patch
deleted file mode 100644
index f420d8cde5..0000000000
--- a/target/linux/lantiq/patches-6.1/0018-MTD-nand-lots-of-xrx200-fixes.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 997a8965db8417266bea3fbdcfa3e5655a1b52fa Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 9 Sep 2014 23:12:15 +0200
-Subject: [PATCH 18/36] MTD: nand: lots of xrx200 fixes
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mtd/nand/raw/xway_nand.c | 63 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 63 insertions(+)
-
---- a/drivers/mtd/nand/raw/xway_nand.c
-+++ b/drivers/mtd/nand/raw/xway_nand.c
-@@ -61,6 +61,24 @@
- #define NAND_CON_CSMUX (1 << 1)
- #define NAND_CON_NANDM 1
-
-+#define DANUBE_PCI_REG32( addr ) (*(volatile u32 *)(addr))
-+#define PCI_CR_PR_OFFSET (KSEG1+0x1E105400)
-+#define PCI_CR_PC_ARB (PCI_CR_PR_OFFSET + 0x0080)
-+
-+/*
-+ * req_mask provides a mechanism to prevent interference between
-+ * nand and pci (probably only relevant for the BT Home Hub 2B).
-+ * Setting it causes the corresponding pci req pins to be masked
-+ * during nand access, and also moves ebu locking from the read/write
-+ * functions to the chip select function to ensure that the whole
-+ * operation runs with interrupts disabled.
-+ * In addition it switches on some extra waiting in xway_cmd_ctrl().
-+ * This seems to be necessary if the ebu_cs1 pin has open-drain disabled,
-+ * which in turn seems to be necessary for the nor chip to be recognised
-+ * reliably, on a board (Home Hub 2B again) which has both nor and nand.
-+ */
-+static __be32 req_mask = 0;
-+
- struct xway_nand_data {
- struct nand_controller controller;
- struct nand_chip chip;
-@@ -92,10 +110,22 @@ static void xway_select_chip(struct nand
- case -1:
- ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
- ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
-+
-+ if (req_mask) {
-+ /* Unmask all external PCI request */
-+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) &= ~(req_mask << 16);
-+ }
-+
- spin_unlock_irqrestore(&ebu_lock, data->csflags);
- break;
- case 0:
- spin_lock_irqsave(&ebu_lock, data->csflags);
-+
-+ if (req_mask) {
-+ /* Mask all external PCI request */
-+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) |= (req_mask << 16);
-+ }
-+
- ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
- ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
- break;
-@@ -108,6 +138,11 @@ static void xway_cmd_ctrl(struct nand_ch
- {
- struct mtd_info *mtd = nand_to_mtd(chip);
-
-+ if (req_mask) {
-+ if (cmd != NAND_CMD_STATUS)
-+ ltq_ebu_w32(0, EBU_NAND_WAIT); /* Clear nand ready */
-+ }
-+
- if (cmd == NAND_CMD_NONE)
- return;
-
-@@ -118,6 +153,24 @@ static void xway_cmd_ctrl(struct nand_ch
-
- while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
- ;
-+
-+ if (req_mask) {
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (cmd) {
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_SEQIN:
-+ case NAND_CMD_STATUS:
-+ case NAND_CMD_READID:
-+ return;
-+ }
-+
-+ /* wait until command is processed */
-+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
-+ ;
-+ }
- }
-
- static int xway_dev_ready(struct nand_chip *chip)
-@@ -169,6 +222,7 @@ static int xway_nand_probe(struct platfo
- int err;
- u32 cs;
- u32 cs_flag = 0;
-+ const __be32 *req_mask_ptr;
-
- /* Allocate memory for the device structure (and zero it) */
- data = devm_kzalloc(&pdev->dev, sizeof(struct xway_nand_data),
-@@ -204,6 +258,15 @@ static int xway_nand_probe(struct platfo
- if (!err && cs == 1)
- cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
-
-+ req_mask_ptr = of_get_property(pdev->dev.of_node,
-+ "req-mask", NULL);
-+
-+ /*
-+ * Load the PCI req lines to mask from the device tree. If the
-+ * property is not present, setting req_mask to 0 disables masking.
-+ */
-+ req_mask = (req_mask_ptr ? *req_mask_ptr : 0);
-+
- /* setup the EBU to run in NAND mode on our base addr */
- ltq_ebu_w32(CPHYSADDR(data->nandaddr)
- | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
diff --git a/target/linux/lantiq/patches-6.1/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch b/target/linux/lantiq/patches-6.1/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch
deleted file mode 100644
index c1fc59487a..0000000000
--- a/target/linux/lantiq/patches-6.1/0020-MTD-lantiq-handle-NO_XIP-on-cfi0001-flash.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From e3b20f04e9f9cae1babe091fdc1d08d7703ae344 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:18:00 +0200
-Subject: [PATCH 20/36] MTD: lantiq: handle NO_XIP on cfi0001 flash
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mtd/maps/lantiq-flash.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/maps/lantiq-flash.c
-+++ b/drivers/mtd/maps/lantiq-flash.c
-@@ -129,7 +129,11 @@ ltq_mtd_probe(struct platform_device *pd
- if (!ltq_mtd->map)
- return -ENOMEM;
-
-- ltq_mtd->map->phys = ltq_mtd->res->start;
-+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-+ ltq_mtd->map->phys = NO_XIP;
-+ else
-+ ltq_mtd->map->phys = ltq_mtd->res->start;
-+ ltq_mtd->res->start;
- ltq_mtd->map->size = resource_size(ltq_mtd->res);
- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
- if (IS_ERR(ltq_mtd->map->virt))
diff --git a/target/linux/lantiq/patches-6.1/0023-NET-PHY-add-led-support-for-intel-xway.patch b/target/linux/lantiq/patches-6.1/0023-NET-PHY-add-led-support-for-intel-xway.patch
deleted file mode 100644
index fcc760b911..0000000000
--- a/target/linux/lantiq/patches-6.1/0023-NET-PHY-add-led-support-for-intel-xway.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From 0a63ab263725c427051a8bbaa0732b749627da27 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:15:36 +0200
-Subject: [PATCH 23/36] NET: PHY: adds driver for lantiq PHY11G
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/phy/Kconfig | 5 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/lantiq.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 237 insertions(+)
- create mode 100644 drivers/net/phy/lantiq.c
-
---- a/drivers/net/phy/intel-xway.c
-+++ b/drivers/net/phy/intel-xway.c
-@@ -229,6 +229,51 @@ static int xway_gphy_rgmii_init(struct p
- XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
- }
-
-+#if IS_ENABLED(CONFIG_OF_MDIO)
-+static int vr9_gphy_of_reg_init(struct phy_device *phydev)
-+{
-+ u32 tmp;
-+
-+ /* store the led values if one was passed by the devicetree */
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,ledch", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,ledcl", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCL, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led0h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led0l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led1h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led1l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led2h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led2l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led3h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED3H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led3l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED3L, tmp);
-+
-+ return 0;
-+}
-+#else
-+static int vr9_gphy_of_reg_init(struct phy_device *phydev)
-+{
-+ return 0;
-+}
-+#endif /* CONFIG_OF_MDIO */
-+
- static int xway_gphy_config_init(struct phy_device *phydev)
- {
- int err;
-@@ -280,6 +325,7 @@ static int xway_gphy_config_init(struct
- if (err)
- return err;
-
-+ vr9_gphy_of_reg_init(phydev);
- return 0;
- }
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/phy-lanitq.txt
-@@ -0,0 +1,216 @@
-+Lanitq PHY binding
-+============================================
-+
-+This devicetree binding controls the lantiq ethernet phys led functionality.
-+
-+Example:
-+ mdio@0 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "lantiq,xrx200-mdio";
-+ phy5: ethernet-phy@5 {
-+ reg = <0x1>;
-+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
-+ };
-+ phy11: ethernet-phy@11 {
-+ reg = <0x11>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led2h = <0x00>;
-+ lantiq,led2l = <0x03>;
-+ };
-+ phy12: ethernet-phy@12 {
-+ reg = <0x12>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led1h = <0x00>;
-+ lantiq,led1l = <0x03>;
-+ };
-+ phy13: ethernet-phy@13 {
-+ reg = <0x13>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led2h = <0x00>;
-+ lantiq,led2l = <0x03>;
-+ };
-+ phy14: ethernet-phy@14 {
-+ reg = <0x14>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led1h = <0x00>;
-+ lantiq,led1l = <0x03>;
-+ };
-+ };
-+
-+Register Description
-+============================================
-+
-+LEDCH:
-+
-+Name Hardware Reset Value
-+LEDCH 0x00C5
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| FBF | SBF |RES | NACS |
-+=========================================
-+
-+Field Bits Type Description
-+FBF 7:6 RW Fast Blink Frequency
-+ ---
-+ 0x0 (00b) F02HZ 2 Hz blinking frequency
-+ 0x1 (01b) F04HZ 4 Hz blinking frequency
-+ 0x2 (10b) F08HZ 8 Hz blinking frequency
-+ 0x3 (11b) F16HZ 16 Hz blinking frequency
-+
-+SBF 5:4 RW Slow Blink Frequency
-+ ---
-+ 0x0 (00b) F02HZ 2 Hz blinking frequency
-+ 0x1 (01b) F04HZ 4 Hz blinking frequency
-+ 0x2 (10b) F08HZ 8 Hz blinking frequency
-+ 0x3 (11b) F16HZ 16 Hz blinking frequency
-+
-+NACS 2:0 RW Inverse of Scan Function
-+ ---
-+ 0x0 (000b) NONE No Function
-+ 0x1 (001b) LINK Complex function enabled when link is up
-+ 0x2 (010b) PDOWN Complex function enabled when device is powered-down
-+ 0x3 (011b) EEE Complex function enabled when device is in EEE mode
-+ 0x4 (100b) ANEG Complex function enabled when auto-negotiation is running
-+ 0x5 (101b) ABIST Complex function enabled when analog self-test is running
-+ 0x6 (110b) CDIAG Complex function enabled when cable diagnostics are running
-+ 0x7 (111b) TEST Complex function enabled when test mode is running
-+
-+LEDCL:
-+
-+Name Hardware Reset Value
-+LEDCL 0x0067
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+|RES | SCAN |RES | CBLINK |
-+=========================================
-+
-+Field Bits Type Description
-+SCAN 6:4 RW Complex Scan Configuration
-+ ---
-+ 000 B NONE No Function
-+ 001 B LINK Complex function enabled when link is up
-+ 010 B PDOWN Complex function enabled when device is powered-down
-+ 011 B EEE Complex function enabled when device is in EEE mode
-+ 100 B ANEG Complex function enabled when auto-negotiation is running
-+ 101 B ABIST Complex function enabled when analog self-test is running
-+ 110 B CDIAG Complex function enabled when cable diagnostics are running
-+ 111 B TEST Complex function enabled when test mode is running
-+
-+CBLINK 2:0 RW Complex Blinking Configuration
-+ ---
-+ 000 B NONE No Function
-+ 001 B LINK Complex function enabled when link is up
-+ 010 B PDOWN Complex function enabled when device is powered-down
-+ 011 B EEE Complex function enabled when device is in EEE mode
-+ 100 B ANEG Complex function enabled when auto-negotiation is running
-+ 101 B ABIST Complex function enabled when analog self-test is running
-+ 110 B CDIAG Complex function enabled when cable diagnostics are running
-+ 111 B TEST Complex function enabled when test mode is running
-+
-+LEDxH:
-+
-+Name Hardware Reset Value
-+LED0H 0x0070
-+LED1H 0x0020
-+LED2H 0x0040
-+LED3H 0x0040
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| CON | BLINKF |
-+=========================================
-+
-+Field Bits Type Description
-+CON 7:4 RW Constant On Configuration
-+ ---
-+ 0x0 (0000b) NONE LED does not light up constantly
-+ 0x1 (0001b) LINK10 LED is on when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 LED is on when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X LED is on when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 LED is on when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 LED is on when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X LED is on when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX LED is on when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN LED is on when device is powered-down
-+ 0x9 (1001b) EEE LED is on when device is in EEE mode
-+ 0xA (1010b) ANEG LED is on when auto-negotiation is running
-+ 0xB (1011b) ABIST LED is on when analog self-test is running
-+ 0xC (1100b) CDIAG LED is on when cable diagnostics are running
-+
-+BLINKF 3:0 RW Fast Blinking Configuration
-+ ---
-+ 0x0 (0000b) NONE No Blinking
-+ 0x1 (0001b) LINK10 Blink when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 Blink when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X Blink when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 Blink when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 Blink when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X Blink when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX Blink when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN Blink when device is powered-down
-+ 0x9 (1001b) EEE Blink when device is in EEE mode
-+ 0xA (1010b) ANEG Blink when auto-negotiation is running
-+ 0xB (1011b) ABIST Blink when analog self-test is running
-+ 0xC (1100b) CDIAG Blink when cable diagnostics are running
-+
-+LEDxL:
-+
-+Name Hardware Reset Value
-+LED0L 0x0003
-+LED1L 0x0000
-+LED2L 0x0000
-+LED3L 0x0020
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| BLINKS | PULSE |
-+=========================================
-+
-+Field Bits Type Description
-+BLINKS 7:4 RW Slow Blinkin Configuration
-+ ---
-+ 0x0 (0000b) NONE No Blinking
-+ 0x1 (0001b) LINK10 Blink when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 Blink when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X Blink when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 Blink when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 Blink when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X Blink when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX Blink when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN Blink when device is powered-down
-+ 0x9 (1001b) EEE Blink when device is in EEE mode
-+ 0xA (1010b) ANEG Blink when auto-negotiation is running
-+ 0xB (1011b) ABIST Blink when analog self-test is running
-+ 0xC (1100b) CDIAG Blink when cable diagnostics are runningning
-+
-+PULSE 3:0 RW Pulsing Configuration
-+ The pulse field is a mask field by which certain events can be combined
-+ ---
-+ 0x0 (0000b) NONE No pulsing
-+ 0x1 (0001b) TXACT Transmit activity
-+ 0x2 (0010b) RXACT Receive activity
-+ 0x4 (0100b) COL Collision
-+ 0x8 (1000b) RES Reserved
diff --git a/target/linux/lantiq/patches-6.1/0028-NET-lantiq-various-etop-fixes.patch b/target/linux/lantiq/patches-6.1/0028-NET-lantiq-various-etop-fixes.patch
deleted file mode 100644
index 8ac1097267..0000000000
--- a/target/linux/lantiq/patches-6.1/0028-NET-lantiq-various-etop-fixes.patch
+++ /dev/null
@@ -1,886 +0,0 @@
-From 870ed9cae083ff8a60a739ef7e74c5a1800533be Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 9 Sep 2014 22:45:34 +0200
-Subject: [PATCH 28/36] NET: lantiq: various etop fixes
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -1,7 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- *
-- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
-+ * Copyright (C) 2011-12 John Crispin <blogic@openwrt.org>
- */
-
- #include <linux/kernel.h>
-@@ -20,12 +20,17 @@
- #include <linux/mm.h>
- #include <linux/platform_device.h>
- #include <linux/ethtool.h>
-+#include <linux/if_vlan.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/io.h>
- #include <linux/dma-mapping.h>
- #include <linux/module.h>
- #include <linux/property.h>
-+#include <linux/clk.h>
-+#include <linux/of_net.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_platform.h>
-
- #include <asm/checksum.h>
-
-@@ -33,7 +38,7 @@
- #include <xway_dma.h>
- #include <lantiq_platform.h>
-
--#define LTQ_ETOP_MDIO 0x11804
-+#define LTQ_ETOP_MDIO_ACC 0x11804
- #define MDIO_REQUEST 0x80000000
- #define MDIO_READ 0x40000000
- #define MDIO_ADDR_MASK 0x1f
-@@ -42,44 +47,91 @@
- #define MDIO_REG_OFFSET 0x10
- #define MDIO_VAL_MASK 0xffff
-
--#define PPE32_CGEN 0x800
--#define LQ_PPE32_ENET_MAC_CFG 0x1840
-+#define LTQ_ETOP_MDIO_CFG 0x11800
-+#define MDIO_CFG_MASK 0x6
-+
-+#define LTQ_ETOP_CFG 0x11808
-+#define LTQ_ETOP_IGPLEN 0x11820
-+#define LTQ_ETOP_MAC_CFG 0x11840
-
- #define LTQ_ETOP_ENETS0 0x11850
- #define LTQ_ETOP_MAC_DA0 0x1186C
- #define LTQ_ETOP_MAC_DA1 0x11870
--#define LTQ_ETOP_CFG 0x16020
--#define LTQ_ETOP_IGPLEN 0x16080
-+
-+#define MAC_CFG_MASK 0xfff
-+#define MAC_CFG_CGEN (1 << 11)
-+#define MAC_CFG_DUPLEX (1 << 2)
-+#define MAC_CFG_SPEED (1 << 1)
-+#define MAC_CFG_LINK (1 << 0)
-
- #define MAX_DMA_CHAN 0x8
- #define MAX_DMA_CRC_LEN 0x4
- #define MAX_DMA_DATA_LEN 0x600
-
- #define ETOP_FTCU BIT(28)
--#define ETOP_MII_MASK 0xf
--#define ETOP_MII_NORMAL 0xd
--#define ETOP_MII_REVERSE 0xe
- #define ETOP_PLEN_UNDER 0x40
--#define ETOP_CGEN 0x800
-+#define ETOP_CFG_MII0 0x01
-
--/* use 2 static channels for TX/RX */
--#define LTQ_ETOP_TX_CHANNEL 1
--#define LTQ_ETOP_RX_CHANNEL 6
--#define IS_TX(x) ((x) == LTQ_ETOP_TX_CHANNEL)
--#define IS_RX(x) ((x) == LTQ_ETOP_RX_CHANNEL)
-+#define ETOP_CFG_MASK 0xfff
-+#define ETOP_CFG_FEN0 (1 << 8)
-+#define ETOP_CFG_SEN0 (1 << 6)
-+#define ETOP_CFG_OFF1 (1 << 3)
-+#define ETOP_CFG_REMII0 (1 << 1)
-+#define ETOP_CFG_OFF0 (1 << 0)
-+
-+#define LTQ_GBIT_MDIO_CTL 0xCC
-+#define LTQ_GBIT_MDIO_DATA 0xd0
-+#define LTQ_GBIT_GCTL0 0x68
-+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
-+#define LTQ_GBIT_P0_CTL 0x4
-+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
-+#define LTQ_GBIT_RGMII_CTL 0x78
-+
-+#define PMAC_HD_CTL_AS (1 << 19)
-+#define PMAC_HD_CTL_RXSH (1 << 22)
-+
-+/* Switch Enable (0=disable, 1=enable) */
-+#define GCTL0_SE 0x80000000
-+/* Disable MDIO auto polling (0=disable, 1=enable) */
-+#define PX_CTL_DMDIO 0x00400000
-+
-+/* MDC clock divider, clock = 25MHz/((MDC_CLOCK + 1) * 2) */
-+#define MDC_CLOCK_MASK 0xff000000
-+#define MDC_CLOCK_OFFSET 24
-+
-+/* register information for the gbit's MDIO bus */
-+#define MDIO_XR9_REQUEST 0x00008000
-+#define MDIO_XR9_READ 0x00000800
-+#define MDIO_XR9_WRITE 0x00000400
-+#define MDIO_XR9_REG_MASK 0x1f
-+#define MDIO_XR9_ADDR_MASK 0x1f
-+#define MDIO_XR9_RD_MASK 0xffff
-+#define MDIO_XR9_REG_OFFSET 0
-+#define MDIO_XR9_ADDR_OFFSET 5
-+#define MDIO_XR9_WR_OFFSET 16
-
-+#define LTQ_DMA_ETOP ((of_machine_is_compatible("lantiq,ase")) ? \
-+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
-+
-+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
- #define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
- #define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
- #define ltq_etop_w32_mask(x, y, z) \
- ltq_w32_mask(x, y, ltq_etop_membase + (z))
-
--#define DRV_VERSION "1.0"
-+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
-+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
-+#define ltq_gbit_w32_mask(x, y, z) \
-+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
-+
-+#define DRV_VERSION "1.2"
-
- static void __iomem *ltq_etop_membase;
-+static void __iomem *ltq_gbit_membase;
-
- struct ltq_etop_chan {
-- int idx;
- int tx_free;
-+ int irq;
- struct net_device *netdev;
- struct napi_struct napi;
- struct ltq_dma_channel dma;
-@@ -89,26 +141,39 @@ struct ltq_etop_chan {
- struct ltq_etop_priv {
- struct net_device *netdev;
- struct platform_device *pdev;
-- struct ltq_eth_data *pldata;
- struct resource *res;
-
- struct mii_bus *mii_bus;
-
-- struct ltq_etop_chan ch[MAX_DMA_CHAN];
-- int tx_free[MAX_DMA_CHAN >> 1];
-+ struct ltq_etop_chan txch;
-+ struct ltq_etop_chan rxch;
-
- int tx_burst_len;
- int rx_burst_len;
-
-- spinlock_t lock;
-+ int tx_irq;
-+ int rx_irq;
-+
-+ unsigned char mac[6];
-+ phy_interface_t mii_mode;
-+
-+ spinlock_t lock;
-+
-+ struct clk *clk_ppe;
-+ struct clk *clk_switch;
-+ struct clk *clk_ephy;
-+ struct clk *clk_ephycgu;
- };
-
-+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data);
-+
- static int
- ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
- {
- struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
-
-- ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN);
-+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
- if (!ch->skb[ch->dma.desc])
- return -ENOMEM;
- ch->dma.desc_base[ch->dma.desc].addr =
-@@ -143,8 +208,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan
- spin_unlock_irqrestore(&priv->lock, flags);
-
- skb_put(skb, len);
-+ skb->dev = ch->netdev;
- skb->protocol = eth_type_trans(skb, ch->netdev);
- netif_receive_skb(skb);
-+ ch->netdev->stats.rx_packets++;
-+ ch->netdev->stats.rx_bytes += len;
- }
-
- static int
-@@ -152,7 +220,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
- {
- struct ltq_etop_chan *ch = container_of(napi,
- struct ltq_etop_chan, napi);
-+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
- int work_done = 0;
-+ unsigned long flags;
-
- while (work_done < budget) {
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-@@ -164,7 +234,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
- }
- if (work_done < budget) {
- napi_complete_done(&ch->napi, work_done);
-+ spin_lock_irqsave(&priv->lock, flags);
- ltq_dma_ack_irq(&ch->dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
- }
- return work_done;
- }
-@@ -176,12 +248,14 @@ ltq_etop_poll_tx(struct napi_struct *nap
- container_of(napi, struct ltq_etop_chan, napi);
- struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
- struct netdev_queue *txq =
-- netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
-+ netdev_get_tx_queue(ch->netdev, ch->dma.nr >> 1);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- while ((ch->dma.desc_base[ch->tx_free].ctl &
- (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
-+ ch->netdev->stats.tx_packets++;
-+ ch->netdev->stats.tx_bytes += ch->skb[ch->tx_free]->len;
- dev_kfree_skb_any(ch->skb[ch->tx_free]);
- ch->skb[ch->tx_free] = NULL;
- memset(&ch->dma.desc_base[ch->tx_free], 0,
-@@ -194,7 +268,9 @@ ltq_etop_poll_tx(struct napi_struct *nap
- if (netif_tx_queue_stopped(txq))
- netif_tx_start_queue(txq);
- napi_complete(&ch->napi);
-+ spin_lock_irqsave(&priv->lock, flags);
- ltq_dma_ack_irq(&ch->dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
- return 1;
- }
-
-@@ -202,9 +278,10 @@ static irqreturn_t
- ltq_etop_dma_irq(int irq, void *_priv)
- {
- struct ltq_etop_priv *priv = _priv;
-- int ch = irq - LTQ_DMA_CH0_INT;
--
-- napi_schedule(&priv->ch[ch].napi);
-+ if (irq == priv->txch.dma.irq)
-+ napi_schedule(&priv->txch.napi);
-+ else
-+ napi_schedule(&priv->rxch.napi);
- return IRQ_HANDLED;
- }
-
-@@ -216,7 +293,7 @@ ltq_etop_free_channel(struct net_device
- ltq_dma_free(&ch->dma);
- if (ch->dma.irq)
- free_irq(ch->dma.irq, priv);
-- if (IS_RX(ch->idx)) {
-+ if (ch == &priv->txch) {
- int desc;
-
- for (desc = 0; desc < LTQ_DESC_NUM; desc++)
-@@ -228,80 +305,135 @@ static void
- ltq_etop_hw_exit(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-
-- ltq_pmu_disable(PMU_PPE);
-- for (i = 0; i < MAX_DMA_CHAN; i++)
-- if (IS_TX(i) || IS_RX(i))
-- ltq_etop_free_channel(dev, &priv->ch[i]);
-+ clk_disable(priv->clk_ppe);
-+
-+ if (of_machine_is_compatible("lantiq,ar9"))
-+ clk_disable(priv->clk_switch);
-+
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ clk_disable(priv->clk_ephy);
-+ clk_disable(priv->clk_ephycgu);
-+ }
-+
-+ ltq_etop_free_channel(dev, &priv->txch);
-+ ltq_etop_free_channel(dev, &priv->rxch);
-+}
-+
-+static void
-+ltq_etop_gbit_init(struct net_device *dev)
-+{
-+ struct ltq_etop_priv *priv = netdev_priv(dev);
-+
-+ clk_enable(priv->clk_switch);
-+
-+ /* enable gbit port0 on the SoC */
-+ ltq_gbit_w32_mask((1 << 17), (1 << 18), LTQ_GBIT_P0_CTL);
-+
-+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
-+ /* disable MDIO auto polling mode */
-+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
-+ /* set 1522 packet size */
-+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
-+ /* disable pmac & dmac headers */
-+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
-+ LTQ_GBIT_PMAC_HD_CTL);
-+ /* Due to traffic halt when burst length 8,
-+ replace default IPG value with 0x3B */
-+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
-+ /* set mdc clock to 2.5 MHz */
-+ ltq_gbit_w32_mask(MDC_CLOCK_MASK, 4 << MDC_CLOCK_OFFSET,
-+ LTQ_GBIT_RGMII_CTL);
- }
-
- static int
- ltq_etop_hw_init(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-- int err;
-+ phy_interface_t mii_mode = priv->mii_mode;
-
-- ltq_pmu_enable(PMU_PPE);
-+ clk_enable(priv->clk_ppe);
-
-- switch (priv->pldata->mii_mode) {
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ ltq_etop_gbit_init(dev);
-+ /* force the etops link to the gbit to MII */
-+ mii_mode = PHY_INTERFACE_MODE_MII;
-+ }
-+ ltq_etop_w32_mask(MDIO_CFG_MASK, 0, LTQ_ETOP_MDIO_CFG);
-+ ltq_etop_w32_mask(MAC_CFG_MASK, MAC_CFG_CGEN | MAC_CFG_DUPLEX |
-+ MAC_CFG_SPEED | MAC_CFG_LINK, LTQ_ETOP_MAC_CFG);
-+
-+ switch (mii_mode) {
- case PHY_INTERFACE_MODE_RMII:
-- ltq_etop_w32_mask(ETOP_MII_MASK, ETOP_MII_REVERSE,
-- LTQ_ETOP_CFG);
-+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_REMII0 | ETOP_CFG_OFF1 |
-+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
- break;
-
- case PHY_INTERFACE_MODE_MII:
-- ltq_etop_w32_mask(ETOP_MII_MASK, ETOP_MII_NORMAL,
-- LTQ_ETOP_CFG);
-+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_OFF1 |
-+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
- break;
-
- default:
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ clk_enable(priv->clk_ephy);
-+ /* disable external MII */
-+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
-+ /* enable clock for internal PHY */
-+ clk_enable(priv->clk_ephycgu);
-+ /* we need to write this magic to the internal phy to
-+ make it work */
-+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
-+ pr_info("Selected EPHY mode\n");
-+ break;
-+ }
- netdev_err(dev, "unknown mii mode %d\n",
-- priv->pldata->mii_mode);
-+ mii_mode);
- return -ENOTSUPP;
- }
-
-- /* enable crc generation */
-- ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
-+ return 0;
-+}
-+
-+static int
-+ltq_etop_dma_init(struct net_device *dev)
-+{
-+ struct ltq_etop_priv *priv = netdev_priv(dev);
-+ int tx = priv->tx_irq - LTQ_DMA_ETOP;
-+ int rx = priv->rx_irq - LTQ_DMA_ETOP;
-+ int err;
-
- ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len);
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- int irq = LTQ_DMA_CH0_INT + i;
-- struct ltq_etop_chan *ch = &priv->ch[i];
--
-- ch->dma.nr = i;
-- ch->idx = ch->dma.nr;
-- ch->dma.dev = &priv->pdev->dev;
--
-- if (IS_TX(i)) {
-- ltq_dma_alloc_tx(&ch->dma);
-- err = request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv);
-- if (err) {
-- netdev_err(dev,
-- "Unable to get Tx DMA IRQ %d\n",
-- irq);
-- return err;
-- }
-- } else if (IS_RX(i)) {
-- ltq_dma_alloc_rx(&ch->dma);
-- for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
-- ch->dma.desc++)
-- if (ltq_etop_alloc_skb(ch))
-- return -ENOMEM;
-- ch->dma.desc = 0;
-- err = request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv);
-- if (err) {
-- netdev_err(dev,
-- "Unable to get Rx DMA IRQ %d\n",
-- irq);
-- return err;
-- }
-+ priv->txch.dma.nr = tx;
-+ priv->txch.dma.dev = &priv->pdev->dev;
-+ ltq_dma_alloc_tx(&priv->txch.dma);
-+ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, 0, "eth_tx", priv);
-+ if (err) {
-+ netdev_err(dev, "failed to allocate tx irq\n");
-+ goto err_out;
-+ }
-+ priv->txch.dma.irq = priv->tx_irq;
-+
-+ priv->rxch.dma.nr = rx;
-+ priv->rxch.dma.dev = &priv->pdev->dev;
-+ ltq_dma_alloc_rx(&priv->rxch.dma);
-+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM;
-+ priv->rxch.dma.desc++) {
-+ if (ltq_etop_alloc_skb(&priv->rxch)) {
-+ netdev_err(dev, "failed to allocate skbs\n");
-+ err = -ENOMEM;
-+ goto err_out;
- }
-- ch->dma.irq = irq;
- }
-- return 0;
-+ priv->rxch.dma.desc = 0;
-+ err = request_irq(priv->rx_irq, ltq_etop_dma_irq, 0, "eth_rx", priv);
-+ if (err)
-+ netdev_err(dev, "failed to allocate rx irq\n");
-+ else
-+ priv->rxch.dma.irq = priv->rx_irq;
-+err_out:
-+ return err;
- }
-
- static void
-@@ -320,6 +452,39 @@ static const struct ethtool_ops ltq_etop
- };
-
- static int
-+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data)
-+{
-+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
-+ (phy_data << MDIO_XR9_WR_OFFSET) |
-+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
-+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
-+
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ return 0;
-+}
-+
-+static int
-+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
-+{
-+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
-+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
-+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
-+
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
-+ return val;
-+}
-+
-+static int
- ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
- {
- u32 val = MDIO_REQUEST |
-@@ -327,9 +492,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
- ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
- phy_data;
-
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- ltq_etop_w32(val, LTQ_ETOP_MDIO);
-+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
- return 0;
- }
-
-@@ -340,12 +505,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
- ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
- ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
-
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- ltq_etop_w32(val, LTQ_ETOP_MDIO);
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
-+ val = ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_VAL_MASK;
- return val;
- }
-
-@@ -361,7 +526,10 @@ ltq_etop_mdio_probe(struct net_device *d
- struct ltq_etop_priv *priv = netdev_priv(dev);
- struct phy_device *phydev;
-
-- phydev = phy_find_first(priv->mii_bus);
-+ if (of_machine_is_compatible("lantiq,ase"))
-+ phydev = mdiobus_get_phy(priv->mii_bus, 8);
-+ else
-+ phydev = mdiobus_get_phy(priv->mii_bus, 0);
-
- if (!phydev) {
- netdev_err(dev, "no PHY found\n");
-@@ -369,14 +537,17 @@ ltq_etop_mdio_probe(struct net_device *d
- }
-
- phydev = phy_connect(dev, phydev_name(phydev),
-- &ltq_etop_mdio_link, priv->pldata->mii_mode);
-+ &ltq_etop_mdio_link, priv->mii_mode);
-
- if (IS_ERR(phydev)) {
- netdev_err(dev, "Could not attach to PHY\n");
- return PTR_ERR(phydev);
- }
-
-- phy_set_max_speed(phydev, SPEED_100);
-+ if (of_machine_is_compatible("lantiq,ar9"))
-+ phy_set_max_speed(phydev, SPEED_1000);
-+ else
-+ phy_set_max_speed(phydev, SPEED_100);
-
- phy_attached_info(phydev);
-
-@@ -397,8 +568,13 @@ ltq_etop_mdio_init(struct net_device *de
- }
-
- priv->mii_bus->priv = dev;
-- priv->mii_bus->read = ltq_etop_mdio_rd;
-- priv->mii_bus->write = ltq_etop_mdio_wr;
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
-+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
-+ } else {
-+ priv->mii_bus->read = ltq_etop_mdio_rd;
-+ priv->mii_bus->write = ltq_etop_mdio_wr;
-+ }
- priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- priv->pdev->name, priv->pdev->id);
-@@ -435,18 +611,21 @@ static int
- ltq_etop_open(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ unsigned long flags;
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- struct ltq_etop_chan *ch = &priv->ch[i];
-+ napi_enable(&priv->txch.napi);
-+ napi_enable(&priv->rxch.napi);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ ltq_dma_open(&priv->txch.dma);
-+ ltq_dma_enable_irq(&priv->txch.dma);
-+ ltq_dma_open(&priv->rxch.dma);
-+ ltq_dma_enable_irq(&priv->rxch.dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ if (dev->phydev)
-+ phy_start(dev->phydev);
-
-- if (!IS_TX(i) && (!IS_RX(i)))
-- continue;
-- ltq_dma_open(&ch->dma);
-- ltq_dma_enable_irq(&ch->dma);
-- napi_enable(&ch->napi);
-- }
-- phy_start(dev->phydev);
- netif_tx_start_all_queues(dev);
- return 0;
- }
-@@ -455,18 +634,19 @@ static int
- ltq_etop_stop(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ unsigned long flags;
-
- netif_tx_stop_all_queues(dev);
-- phy_stop(dev->phydev);
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- struct ltq_etop_chan *ch = &priv->ch[i];
--
-- if (!IS_RX(i) && !IS_TX(i))
-- continue;
-- napi_disable(&ch->napi);
-- ltq_dma_close(&ch->dma);
-- }
-+ if (dev->phydev)
-+ phy_stop(dev->phydev);
-+ napi_disable(&priv->txch.napi);
-+ napi_disable(&priv->rxch.napi);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ ltq_dma_close(&priv->txch.dma);
-+ ltq_dma_close(&priv->rxch.dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
- return 0;
- }
-
-@@ -476,15 +656,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
- int queue = skb_get_queue_mapping(skb);
- struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
-- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-- int len;
-+ struct ltq_dma_desc *desc =
-+ &priv->txch.dma.desc_base[priv->txch.dma.desc];
- unsigned long flags;
- u32 byte_offset;
-+ int len;
-
- len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
-
-- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
-+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
-+ priv->txch.skb[priv->txch.dma.desc]) {
- netdev_err(dev, "tx ring full\n");
- netif_tx_stop_queue(txq);
- return NETDEV_TX_BUSY;
-@@ -492,7 +673,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
-
- /* dma needs to start on a burst length value aligned address */
- byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4);
-- ch->skb[ch->dma.desc] = skb;
-+ priv->txch.skb[priv->txch.dma.desc] = skb;
-
- netif_trans_update(dev);
-
-@@ -503,11 +684,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
- wmb();
- desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
- LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
-- ch->dma.desc++;
-- ch->dma.desc %= LTQ_DESC_NUM;
-+ priv->txch.dma.desc++;
-+ priv->txch.dma.desc %= LTQ_DESC_NUM;
- spin_unlock_irqrestore(&priv->lock, flags);
-
-- if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
-+ if (priv->txch.dma.desc_base[priv->txch.dma.desc].ctl & LTQ_DMA_OWN)
- netif_tx_stop_queue(txq);
-
- return NETDEV_TX_OK;
-@@ -518,11 +699,14 @@ ltq_etop_change_mtu(struct net_device *d
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
- unsigned long flags;
-+ int max;
-
- dev->mtu = new_mtu;
-
-+ max = ETH_HLEN + VLAN_HLEN + new_mtu + ETH_FCS_LEN;
-+
- spin_lock_irqsave(&priv->lock, flags);
-- ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu, LTQ_ETOP_IGPLEN);
-+ ltq_etop_w32((ETOP_PLEN_UNDER << 16) | max, LTQ_ETOP_IGPLEN);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-@@ -575,6 +759,9 @@ ltq_etop_init(struct net_device *dev)
- if (err)
- goto err_hw;
- ltq_etop_change_mtu(dev, 1500);
-+ err = ltq_etop_dma_init(dev);
-+ if (err)
-+ goto err_hw;
-
- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
- if (!is_valid_ether_addr(mac.sa_data)) {
-@@ -592,9 +779,10 @@ ltq_etop_init(struct net_device *dev)
- dev->addr_assign_type = NET_ADDR_RANDOM;
-
- ltq_etop_set_multicast_list(dev);
-- err = ltq_etop_mdio_init(dev);
-- if (err)
-- goto err_netdev;
-+ if (!ltq_etop_mdio_init(dev))
-+ dev->ethtool_ops = &ltq_etop_ethtool_ops;
-+ else
-+ pr_warn("etop: mdio probe failed\n");;
- return 0;
-
- err_netdev:
-@@ -614,6 +802,9 @@ ltq_etop_tx_timeout(struct net_device *d
- err = ltq_etop_hw_init(dev);
- if (err)
- goto err_hw;
-+ err = ltq_etop_dma_init(dev);
-+ if (err)
-+ goto err_hw;
- netif_trans_update(dev);
- netif_wake_queue(dev);
- return;
-@@ -637,14 +828,18 @@ static const struct net_device_ops ltq_e
- .ndo_tx_timeout = ltq_etop_tx_timeout,
- };
-
--static int __init
--ltq_etop_probe(struct platform_device *pdev)
-+static int ltq_etop_probe(struct platform_device *pdev)
- {
- struct net_device *dev;
- struct ltq_etop_priv *priv;
-- struct resource *res;
-+ struct resource *res, *gbit_res, irqres[2];
- int err;
-- int i;
-+
-+ err = of_irq_to_resource_table(pdev->dev.of_node, irqres, 2);
-+ if (err != 2) {
-+ dev_err(&pdev->dev, "failed to get etop irqs\n");
-+ return -EINVAL;
-+ }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
-@@ -670,19 +865,55 @@ ltq_etop_probe(struct platform_device *p
- goto err_out;
- }
-
-- dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
-- if (!dev) {
-- err = -ENOMEM;
-- goto err_out;
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+ if (!gbit_res) {
-+ dev_err(&pdev->dev, "failed to get gbit resource\n");
-+ err = -ENOENT;
-+ goto err_out;
-+ }
-+ ltq_gbit_membase = devm_ioremap(&pdev->dev,
-+ gbit_res->start, resource_size(gbit_res));
-+ if (!ltq_gbit_membase) {
-+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
-+ pdev->id);
-+ err = -ENOMEM;
-+ goto err_out;
-+ }
- }
-+
-+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
- strcpy(dev->name, "eth%d");
- dev->netdev_ops = &ltq_eth_netdev_ops;
-- dev->ethtool_ops = &ltq_etop_ethtool_ops;
- priv = netdev_priv(dev);
- priv->res = res;
- priv->pdev = pdev;
-- priv->pldata = dev_get_platdata(&pdev->dev);
- priv->netdev = dev;
-+ priv->tx_irq = irqres[0].start;
-+ priv->rx_irq = irqres[1].start;
-+ err = of_get_phy_mode(pdev->dev.of_node, &priv->mii_mode);
-+ if (err)
-+ pr_err("Can't find phy-mode for port\n");
-+
-+ of_get_mac_address(pdev->dev.of_node, priv->mac);
-+
-+ priv->clk_ppe = clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->clk_ppe))
-+ return PTR_ERR(priv->clk_ppe);
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ priv->clk_switch = clk_get(&pdev->dev, "switch");
-+ if (IS_ERR(priv->clk_switch))
-+ return PTR_ERR(priv->clk_switch);
-+ }
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ priv->clk_ephy = clk_get(&pdev->dev, "ephy");
-+ if (IS_ERR(priv->clk_ephy))
-+ return PTR_ERR(priv->clk_ephy);
-+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu");
-+ if (IS_ERR(priv->clk_ephycgu))
-+ return PTR_ERR(priv->clk_ephycgu);
-+ }
-+
- spin_lock_init(&priv->lock);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
-@@ -698,15 +929,10 @@ ltq_etop_probe(struct platform_device *p
- goto err_free;
- }
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- if (IS_TX(i))
-- netif_napi_add_weight(dev, &priv->ch[i].napi,
-- ltq_etop_poll_tx, 8);
-- else if (IS_RX(i))
-- netif_napi_add_weight(dev, &priv->ch[i].napi,
-- ltq_etop_poll_rx, 32);
-- priv->ch[i].netdev = dev;
-- }
-+ netif_napi_add_weight(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
-+ netif_napi_add_weight(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
-+ priv->txch.netdev = dev;
-+ priv->rxch.netdev = dev;
-
- err = register_netdev(dev);
- if (err)
-@@ -735,31 +961,22 @@ ltq_etop_remove(struct platform_device *
- return 0;
- }
-
-+static const struct of_device_id ltq_etop_match[] = {
-+ { .compatible = "lantiq,etop-xway" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ltq_etop_match);
-+
- static struct platform_driver ltq_mii_driver = {
-+ .probe = ltq_etop_probe,
- .remove = ltq_etop_remove,
- .driver = {
- .name = "ltq_etop",
-+ .of_match_table = ltq_etop_match,
- },
- };
-
--static int __init
--init_ltq_etop(void)
--{
-- int ret = platform_driver_probe(&ltq_mii_driver, ltq_etop_probe);
--
-- if (ret)
-- pr_err("ltq_etop: Error registering platform driver!");
-- return ret;
--}
--
--static void __exit
--exit_ltq_etop(void)
--{
-- platform_driver_unregister(&ltq_mii_driver);
--}
--
--module_init(init_ltq_etop);
--module_exit(exit_ltq_etop);
-+module_platform_driver(ltq_mii_driver);
-
- MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
- MODULE_DESCRIPTION("Lantiq SoC ETOP");
diff --git a/target/linux/lantiq/patches-6.1/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch b/target/linux/lantiq/patches-6.1/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch
deleted file mode 100644
index b5f79e95a8..0000000000
--- a/target/linux/lantiq/patches-6.1/0031-I2C-MIPS-lantiq-add-FALC-ON-i2c-bus-master.patch
+++ /dev/null
@@ -1,1034 +0,0 @@
-From f17e50f67fa3c77624edf2ca03fae0d50f0ce39b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:26:42 +0200
-Subject: [PATCH 31/36] I2C: MIPS: lantiq: add FALC-ON i2c bus master
-
-This patch adds the driver needed to make the I2C bus work on FALC-ON SoCs.
-
-Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/i2c/busses/Kconfig | 10 +
- drivers/i2c/busses/Makefile | 1 +
- drivers/i2c/busses/i2c-lantiq.c | 747 +++++++++++++++++++++++++++++++++++++++
- drivers/i2c/busses/i2c-lantiq.h | 234 ++++++++++++
- 4 files changed, 992 insertions(+)
- create mode 100644 drivers/i2c/busses/i2c-lantiq.c
- create mode 100644 drivers/i2c/busses/i2c-lantiq.h
-
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -795,6 +795,16 @@ config I2C_MICROCHIP_CORE
- This driver can also be built as a module. If so, the module will be
- called i2c-microchip-core.
-
-+config I2C_LANTIQ
-+ tristate "Lantiq I2C interface"
-+ depends on LANTIQ && SOC_FALCON
-+ help
-+ If you say yes to this option, support will be included for the
-+ Lantiq I2C core.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called i2c-lantiq.
-+
- config I2C_MPC
- tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
- depends on PPC
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_IMX_LPI2C) += i2c-imx-l
- obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
- obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
- obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
-+obj-$(CONFIG_I2C_LANTIQ) += i2c-lantiq.o
- obj-$(CONFIG_I2C_LPC2K) += i2c-lpc2k.o
- obj-$(CONFIG_I2C_MESON) += i2c-meson.o
- obj-$(CONFIG_I2C_MICROCHIP_CORE) += i2c-microchip-corei2c.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-lantiq.c
-@@ -0,0 +1,747 @@
-+
-+/*
-+ * Lantiq I2C bus adapter
-+ *
-+ * Parts based on i2c-designware.c and other i2c drivers from Linux 2.6.33
-+ *
-+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h> /* for kzalloc, kfree */
-+#include <linux/i2c.h>
-+#include <linux/errno.h>
-+#include <linux/completion.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/of_irq.h>
-+
-+#include <lantiq_soc.h>
-+#include "i2c-lantiq.h"
-+
-+/*
-+ * CURRENT ISSUES:
-+ * - no high speed support
-+ * - ten bit mode is not tested (no slave devices)
-+ */
-+
-+/* access macros */
-+#define i2c_r32(reg) \
-+ __raw_readl(&(priv->membase)->reg)
-+#define i2c_w32(val, reg) \
-+ __raw_writel(val, &(priv->membase)->reg)
-+#define i2c_w32_mask(clear, set, reg) \
-+ i2c_w32((i2c_r32(reg) & ~(clear)) | (set), reg)
-+
-+#define DRV_NAME "i2c-lantiq"
-+#define DRV_VERSION "1.00"
-+
-+#define LTQ_I2C_BUSY_TIMEOUT 20 /* ms */
-+
-+#ifdef DEBUG
-+#define LTQ_I2C_XFER_TIMEOUT (25*HZ)
-+#else
-+#define LTQ_I2C_XFER_TIMEOUT HZ
-+#endif
-+
-+#define LTQ_I2C_IMSC_DEFAULT_MASK (I2C_IMSC_I2C_P_INT_EN | \
-+ I2C_IMSC_I2C_ERR_INT_EN)
-+
-+#define LTQ_I2C_ARB_LOST (1 << 0)
-+#define LTQ_I2C_NACK (1 << 1)
-+#define LTQ_I2C_RX_UFL (1 << 2)
-+#define LTQ_I2C_RX_OFL (1 << 3)
-+#define LTQ_I2C_TX_UFL (1 << 4)
-+#define LTQ_I2C_TX_OFL (1 << 5)
-+
-+struct ltq_i2c {
-+ struct mutex mutex;
-+
-+
-+ /* active clock settings */
-+ unsigned int input_clock; /* clock input for i2c hardware block */
-+ unsigned int i2c_clock; /* approximated bus clock in kHz */
-+
-+ struct clk *clk_gate;
-+ struct clk *clk_input;
-+
-+
-+ /* resources (memory and interrupts) */
-+ int irq_lb; /* last burst irq */
-+
-+ struct lantiq_reg_i2c __iomem *membase; /* base of mapped registers */
-+
-+ struct i2c_adapter adap;
-+ struct device *dev;
-+
-+ struct completion cmd_complete;
-+
-+
-+ /* message transfer data */
-+ struct i2c_msg *current_msg; /* current message */
-+ int msgs_num; /* number of messages to handle */
-+ u8 *msg_buf; /* current buffer */
-+ u32 msg_buf_len; /* remaining length of current buffer */
-+ int msg_err; /* error status of the current transfer */
-+
-+
-+ /* master status codes */
-+ enum {
-+ STATUS_IDLE,
-+ STATUS_ADDR, /* address phase */
-+ STATUS_WRITE,
-+ STATUS_READ,
-+ STATUS_READ_END,
-+ STATUS_STOP
-+ } status;
-+};
-+
-+static irqreturn_t ltq_i2c_isr(int irq, void *dev_id);
-+
-+static inline void enable_burst_irq(struct ltq_i2c *priv)
-+{
-+ i2c_w32_mask(0, I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, imsc);
-+}
-+static inline void disable_burst_irq(struct ltq_i2c *priv)
-+{
-+ i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, 0, imsc);
-+}
-+
-+static void prepare_msg_send_addr(struct ltq_i2c *priv)
-+{
-+ struct i2c_msg *msg = priv->current_msg;
-+ int rd = !!(msg->flags & I2C_M_RD); /* extends to 0 or 1 */
-+ u16 addr = msg->addr;
-+
-+ /* new i2c_msg */
-+ priv->msg_buf = msg->buf;
-+ priv->msg_buf_len = msg->len;
-+ if (rd)
-+ priv->status = STATUS_READ;
-+ else
-+ priv->status = STATUS_WRITE;
-+
-+ /* send slave address */
-+ if (msg->flags & I2C_M_TEN) {
-+ i2c_w32(0xf0 | ((addr & 0x300) >> 7) | rd, txd);
-+ i2c_w32(addr & 0xff, txd);
-+ } else {
-+ i2c_w32((addr & 0x7f) << 1 | rd, txd);
-+ }
-+}
-+
-+static void ltq_i2c_set_tx_len(struct ltq_i2c *priv)
-+{
-+ struct i2c_msg *msg = priv->current_msg;
-+ int len = (msg->flags & I2C_M_TEN) ? 2 : 1;
-+
-+ pr_debug("set_tx_len %cX\n", (msg->flags & I2C_M_RD) ? 'R' : 'T');
-+
-+ priv->status = STATUS_ADDR;
-+
-+ if (!(msg->flags & I2C_M_RD))
-+ len += msg->len;
-+ else
-+ /* set maximum received packet size (before rx int!) */
-+ i2c_w32(msg->len, mrps_ctrl);
-+ i2c_w32(len, tps_ctrl);
-+ enable_burst_irq(priv);
-+}
-+
-+static int ltq_i2c_hw_set_clock(struct i2c_adapter *adap)
-+{
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+ unsigned int input_clock = clk_get_rate(priv->clk_input);
-+ u32 dec, inc = 1;
-+
-+ /* clock changed? */
-+ if (priv->input_clock == input_clock)
-+ return 0;
-+
-+ /*
-+ * this formula is only an approximation, found by the recommended
-+ * values in the "I2C Architecture Specification 1.7.1"
-+ */
-+ dec = input_clock / (priv->i2c_clock * 2);
-+ if (dec <= 6)
-+ return -ENXIO;
-+
-+ i2c_w32(0, fdiv_high_cfg);
-+ i2c_w32((inc << I2C_FDIV_CFG_INC_OFFSET) |
-+ (dec << I2C_FDIV_CFG_DEC_OFFSET),
-+ fdiv_cfg);
-+
-+ dev_info(priv->dev, "setup clocks (in %d kHz, bus %d kHz, dec=%d)\n",
-+ input_clock, priv->i2c_clock, dec);
-+
-+ priv->input_clock = input_clock;
-+ return 0;
-+}
-+
-+static int ltq_i2c_hw_init(struct i2c_adapter *adap)
-+{
-+ int ret = 0;
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+
-+ /* disable bus */
-+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
-+
-+#ifndef DEBUG
-+ /* set normal operation clock divider */
-+ i2c_w32(1 << I2C_CLC_RMC_OFFSET, clc);
-+#else
-+ /* for debugging a higher divider value! */
-+ i2c_w32(0xF0 << I2C_CLC_RMC_OFFSET, clc);
-+#endif
-+
-+ /* setup clock */
-+ ret = ltq_i2c_hw_set_clock(adap);
-+ if (ret != 0) {
-+ dev_warn(priv->dev, "invalid clock settings\n");
-+ return ret;
-+ }
-+
-+ /* configure fifo */
-+ i2c_w32(I2C_FIFO_CFG_TXFC | /* tx fifo as flow controller */
-+ I2C_FIFO_CFG_RXFC | /* rx fifo as flow controller */
-+ I2C_FIFO_CFG_TXFA_TXFA2 | /* tx fifo 4-byte aligned */
-+ I2C_FIFO_CFG_RXFA_RXFA2 | /* rx fifo 4-byte aligned */
-+ I2C_FIFO_CFG_TXBS_TXBS0 | /* tx fifo burst size is 1 word */
-+ I2C_FIFO_CFG_RXBS_RXBS0, /* rx fifo burst size is 1 word */
-+ fifo_cfg);
-+
-+ /* configure address */
-+ i2c_w32(I2C_ADDR_CFG_SOPE_EN | /* generate stop when no more data in
-+ the fifo */
-+ I2C_ADDR_CFG_SONA_EN | /* generate stop when NA received */
-+ I2C_ADDR_CFG_MnS_EN | /* we are master device */
-+ 0, /* our slave address (not used!) */
-+ addr_cfg);
-+
-+ /* enable bus */
-+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
-+
-+ return 0;
-+}
-+
-+static int ltq_i2c_wait_bus_not_busy(struct ltq_i2c *priv)
-+{
-+ unsigned long timeout;
-+
-+ timeout = jiffies + msecs_to_jiffies(LTQ_I2C_BUSY_TIMEOUT);
-+
-+ do {
-+ u32 stat = i2c_r32(bus_stat);
-+
-+ if ((stat & I2C_BUS_STAT_BS_MASK) == I2C_BUS_STAT_BS_FREE)
-+ return 0;
-+
-+ cond_resched();
-+ } while (!time_after_eq(jiffies, timeout));
-+
-+ dev_err(priv->dev, "timeout waiting for bus ready\n");
-+ return -ETIMEDOUT;
-+}
-+
-+static void ltq_i2c_tx(struct ltq_i2c *priv, int last)
-+{
-+ if (priv->msg_buf_len && priv->msg_buf) {
-+ i2c_w32(*priv->msg_buf, txd);
-+
-+ if (--priv->msg_buf_len)
-+ priv->msg_buf++;
-+ else
-+ priv->msg_buf = NULL;
-+ } else {
-+ last = 1;
-+ }
-+
-+ if (last)
-+ disable_burst_irq(priv);
-+}
-+
-+static void ltq_i2c_rx(struct ltq_i2c *priv, int last)
-+{
-+ u32 fifo_stat, timeout;
-+ if (priv->msg_buf_len && priv->msg_buf) {
-+ timeout = 5000000;
-+ do {
-+ fifo_stat = i2c_r32(ffs_stat);
-+ } while (!fifo_stat && --timeout);
-+ if (!timeout) {
-+ last = 1;
-+ pr_debug("\nrx timeout\n");
-+ goto err;
-+ }
-+ while (fifo_stat) {
-+ *priv->msg_buf = i2c_r32(rxd);
-+ if (--priv->msg_buf_len) {
-+ priv->msg_buf++;
-+ } else {
-+ priv->msg_buf = NULL;
-+ last = 1;
-+ break;
-+ }
-+ /*
-+ * do not read more than burst size, otherwise no "last
-+ * burst" is generated and the transaction is blocked!
-+ */
-+ fifo_stat = 0;
-+ }
-+ } else {
-+ last = 1;
-+ }
-+err:
-+ if (last) {
-+ disable_burst_irq(priv);
-+
-+ if (priv->status == STATUS_READ_END) {
-+ /*
-+ * do the STATUS_STOP and complete() here, as sometimes
-+ * the tx_end is already seen before this is finished
-+ */
-+ priv->status = STATUS_STOP;
-+ complete(&priv->cmd_complete);
-+ } else {
-+ i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
-+ priv->status = STATUS_READ_END;
-+ }
-+ }
-+}
-+
-+static void ltq_i2c_xfer_init(struct ltq_i2c *priv)
-+{
-+ /* enable interrupts */
-+ i2c_w32(LTQ_I2C_IMSC_DEFAULT_MASK, imsc);
-+
-+ /* trigger transfer of first msg */
-+ ltq_i2c_set_tx_len(priv);
-+}
-+
-+static void dump_msgs(struct i2c_msg msgs[], int num, int rx)
-+{
-+#if defined(DEBUG)
-+ int i, j;
-+ pr_debug("Messages %d %s\n", num, rx ? "out" : "in");
-+ for (i = 0; i < num; i++) {
-+ pr_debug("%2d %cX Msg(%d) addr=0x%X: ", i,
-+ (msgs[i].flags & I2C_M_RD) ? 'R' : 'T',
-+ msgs[i].len, msgs[i].addr);
-+ if (!(msgs[i].flags & I2C_M_RD) || rx) {
-+ for (j = 0; j < msgs[i].len; j++)
-+ pr_debug("%02X ", msgs[i].buf[j]);
-+ }
-+ pr_debug("\n");
-+ }
-+#endif
-+}
-+
-+static void ltq_i2c_release_bus(struct ltq_i2c *priv)
-+{
-+ if ((i2c_r32(bus_stat) & I2C_BUS_STAT_BS_MASK) == I2C_BUS_STAT_BS_BM)
-+ i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
-+}
-+
-+static int ltq_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
-+ int num)
-+{
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+ int ret;
-+
-+ dev_dbg(priv->dev, "xfer %u messages\n", num);
-+ dump_msgs(msgs, num, 0);
-+
-+ mutex_lock(&priv->mutex);
-+
-+ init_completion(&priv->cmd_complete);
-+ priv->current_msg = msgs;
-+ priv->msgs_num = num;
-+ priv->msg_err = 0;
-+ priv->status = STATUS_IDLE;
-+
-+ /* wait for the bus to become ready */
-+ ret = ltq_i2c_wait_bus_not_busy(priv);
-+ if (ret)
-+ goto done;
-+
-+ while (priv->msgs_num) {
-+ /* start the transfers */
-+ ltq_i2c_xfer_init(priv);
-+
-+ /* wait for transfers to complete */
-+ ret = wait_for_completion_interruptible_timeout(
-+ &priv->cmd_complete, LTQ_I2C_XFER_TIMEOUT);
-+ if (ret == 0) {
-+ dev_err(priv->dev, "controller timed out\n");
-+ ltq_i2c_hw_init(adap);
-+ ret = -ETIMEDOUT;
-+ goto done;
-+ } else if (ret < 0)
-+ goto done;
-+
-+ if (priv->msg_err) {
-+ if (priv->msg_err & LTQ_I2C_NACK)
-+ ret = -ENXIO;
-+ else
-+ ret = -EREMOTEIO;
-+ goto done;
-+ }
-+ if (--priv->msgs_num)
-+ priv->current_msg++;
-+ }
-+ /* no error? */
-+ ret = num;
-+
-+done:
-+ ltq_i2c_release_bus(priv);
-+
-+ mutex_unlock(&priv->mutex);
-+
-+ if (ret >= 0)
-+ dump_msgs(msgs, num, 1);
-+
-+ pr_debug("XFER ret %d\n", ret);
-+ return ret;
-+}
-+
-+static irqreturn_t ltq_i2c_isr_burst(int irq, void *dev_id)
-+{
-+ struct ltq_i2c *priv = dev_id;
-+ struct i2c_msg *msg = priv->current_msg;
-+ int last = (irq == priv->irq_lb);
-+
-+ if (last)
-+ pr_debug("LB ");
-+ else
-+ pr_debug("B ");
-+
-+ if (msg->flags & I2C_M_RD) {
-+ switch (priv->status) {
-+ case STATUS_ADDR:
-+ pr_debug("X");
-+ prepare_msg_send_addr(priv);
-+ disable_burst_irq(priv);
-+ break;
-+ case STATUS_READ:
-+ case STATUS_READ_END:
-+ pr_debug("R");
-+ ltq_i2c_rx(priv, last);
-+ break;
-+ default:
-+ disable_burst_irq(priv);
-+ pr_warn("Status R %d\n", priv->status);
-+ break;
-+ }
-+ } else {
-+ switch (priv->status) {
-+ case STATUS_ADDR:
-+ pr_debug("x");
-+ prepare_msg_send_addr(priv);
-+ break;
-+ case STATUS_WRITE:
-+ pr_debug("w");
-+ ltq_i2c_tx(priv, last);
-+ break;
-+ default:
-+ disable_burst_irq(priv);
-+ pr_warn("Status W %d\n", priv->status);
-+ break;
-+ }
-+ }
-+
-+ i2c_w32(I2C_ICR_BREQ_INT_CLR | I2C_ICR_LBREQ_INT_CLR, icr);
-+ return IRQ_HANDLED;
-+}
-+
-+static void ltq_i2c_isr_prot(struct ltq_i2c *priv)
-+{
-+ u32 i_pro = i2c_r32(p_irqss);
-+
-+ pr_debug("i2c-p");
-+
-+ /* not acknowledge */
-+ if (i_pro & I2C_P_IRQSS_NACK) {
-+ priv->msg_err |= LTQ_I2C_NACK;
-+ pr_debug(" nack");
-+ }
-+
-+ /* arbitration lost */
-+ if (i_pro & I2C_P_IRQSS_AL) {
-+ priv->msg_err |= LTQ_I2C_ARB_LOST;
-+ pr_debug(" arb-lost");
-+ }
-+ /* tx -> rx switch */
-+ if (i_pro & I2C_P_IRQSS_RX)
-+ pr_debug(" rx");
-+
-+ /* tx end */
-+ if (i_pro & I2C_P_IRQSS_TX_END)
-+ pr_debug(" txend");
-+ pr_debug("\n");
-+
-+ if (!priv->msg_err) {
-+ /* tx -> rx switch */
-+ if (i_pro & I2C_P_IRQSS_RX) {
-+ priv->status = STATUS_READ;
-+ enable_burst_irq(priv);
-+ }
-+ if (i_pro & I2C_P_IRQSS_TX_END) {
-+ if (priv->status == STATUS_READ)
-+ priv->status = STATUS_READ_END;
-+ else {
-+ disable_burst_irq(priv);
-+ priv->status = STATUS_STOP;
-+ }
-+ }
-+ }
-+
-+ i2c_w32(i_pro, p_irqsc);
-+}
-+
-+static irqreturn_t ltq_i2c_isr(int irq, void *dev_id)
-+{
-+ u32 i_raw, i_err = 0;
-+ struct ltq_i2c *priv = dev_id;
-+
-+ i_raw = i2c_r32(mis);
-+ pr_debug("i_raw 0x%08X\n", i_raw);
-+
-+ /* error interrupt */
-+ if (i_raw & I2C_RIS_I2C_ERR_INT_INTOCC) {
-+ i_err = i2c_r32(err_irqss);
-+ pr_debug("i_err 0x%08X bus_stat 0x%04X\n",
-+ i_err, i2c_r32(bus_stat));
-+
-+ /* tx fifo overflow (8) */
-+ if (i_err & I2C_ERR_IRQSS_TXF_OFL)
-+ priv->msg_err |= LTQ_I2C_TX_OFL;
-+
-+ /* tx fifo underflow (4) */
-+ if (i_err & I2C_ERR_IRQSS_TXF_UFL)
-+ priv->msg_err |= LTQ_I2C_TX_UFL;
-+
-+ /* rx fifo overflow (2) */
-+ if (i_err & I2C_ERR_IRQSS_RXF_OFL)
-+ priv->msg_err |= LTQ_I2C_RX_OFL;
-+
-+ /* rx fifo underflow (1) */
-+ if (i_err & I2C_ERR_IRQSS_RXF_UFL)
-+ priv->msg_err |= LTQ_I2C_RX_UFL;
-+
-+ i2c_w32(i_err, err_irqsc);
-+ }
-+
-+ /* protocol interrupt */
-+ if (i_raw & I2C_RIS_I2C_P_INT_INTOCC)
-+ ltq_i2c_isr_prot(priv);
-+
-+ if ((priv->msg_err) || (priv->status == STATUS_STOP))
-+ complete(&priv->cmd_complete);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static u32 ltq_i2c_functionality(struct i2c_adapter *adap)
-+{
-+ return I2C_FUNC_I2C |
-+ I2C_FUNC_10BIT_ADDR |
-+ I2C_FUNC_SMBUS_EMUL;
-+}
-+
-+static struct i2c_algorithm ltq_i2c_algorithm = {
-+ .master_xfer = ltq_i2c_xfer,
-+ .functionality = ltq_i2c_functionality,
-+};
-+
-+static int ltq_i2c_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ struct ltq_i2c *priv;
-+ struct i2c_adapter *adap;
-+ struct resource *mmres, irqres[4];
-+ int ret = 0;
-+
-+ dev_dbg(&pdev->dev, "probing\n");
-+
-+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ ret = of_irq_to_resource_table(node, irqres, 4);
-+ if (!mmres || (ret != 4)) {
-+ dev_err(&pdev->dev, "no resources\n");
-+ return -ENODEV;
-+ }
-+
-+ /* allocate private data */
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv) {
-+ dev_err(&pdev->dev, "can't allocate private data\n");
-+ return -ENOMEM;
-+ }
-+
-+ adap = &priv->adap;
-+ i2c_set_adapdata(adap, priv);
-+ adap->owner = THIS_MODULE;
-+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
-+ strlcpy(adap->name, DRV_NAME "-adapter", sizeof(adap->name));
-+ adap->algo = &ltq_i2c_algorithm;
-+ adap->dev.parent = &pdev->dev;
-+ adap->dev.of_node = pdev->dev.of_node;
-+
-+ if (of_property_read_u32(node, "clock-frequency", &priv->i2c_clock)) {
-+ dev_warn(&pdev->dev, "No I2C speed selected, using 100kHz\n");
-+ priv->i2c_clock = 100000;
-+ }
-+
-+ init_completion(&priv->cmd_complete);
-+ mutex_init(&priv->mutex);
-+
-+ priv->membase = devm_ioremap_resource(&pdev->dev, mmres);
-+ if (IS_ERR(priv->membase))
-+ return PTR_ERR(priv->membase);
-+
-+ priv->dev = &pdev->dev;
-+ priv->irq_lb = irqres[0].start;
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[0].start, ltq_i2c_isr_burst,
-+ 0x0, "i2c lb", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get last burst IRQ %d\n",
-+ irqres[0].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[1].start, ltq_i2c_isr_burst,
-+ 0x0, "i2c b", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get burst IRQ %d\n",
-+ irqres[1].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[2].start, ltq_i2c_isr,
-+ 0x0, "i2c err", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get error IRQ %d\n",
-+ irqres[2].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[3].start, ltq_i2c_isr,
-+ 0x0, "i2c p", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get protocol IRQ %d\n",
-+ irqres[3].start);
-+ return -ENODEV;
-+ }
-+
-+ dev_dbg(&pdev->dev, "mapped io-space to %p\n", priv->membase);
-+ dev_dbg(&pdev->dev, "use IRQs %d, %d, %d, %d\n", irqres[0].start,
-+ irqres[1].start, irqres[2].start, irqres[3].start);
-+
-+ priv->clk_gate = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->clk_gate)) {
-+ dev_err(&pdev->dev, "failed to get i2c clk\n");
-+ return -ENOENT;
-+ }
-+
-+ /* this is a static clock, which has no refcounting */
-+ priv->clk_input = clk_get_fpi();
-+ if (IS_ERR(priv->clk_input)) {
-+ dev_err(&pdev->dev, "failed to get fpi clk\n");
-+ return -ENOENT;
-+ }
-+
-+ clk_activate(priv->clk_gate);
-+
-+ /* add our adapter to the i2c stack */
-+ ret = i2c_add_numbered_adapter(adap);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't register I2C adapter\n");
-+ goto out;
-+ }
-+
-+ platform_set_drvdata(pdev, priv);
-+ i2c_set_adapdata(adap, priv);
-+
-+ /* print module version information */
-+ dev_dbg(&pdev->dev, "module id=%u revision=%u\n",
-+ (i2c_r32(id) & I2C_ID_ID_MASK) >> I2C_ID_ID_OFFSET,
-+ (i2c_r32(id) & I2C_ID_REV_MASK) >> I2C_ID_REV_OFFSET);
-+
-+ /* initialize HW */
-+ ret = ltq_i2c_hw_init(adap);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't configure adapter\n");
-+ i2c_del_adapter(adap);
-+ platform_set_drvdata(pdev, NULL);
-+ goto out;
-+ } else {
-+ dev_info(&pdev->dev, "version %s\n", DRV_VERSION);
-+ }
-+
-+out:
-+ /* if init failed, we need to deactivate the clock gate */
-+ if (ret)
-+ clk_deactivate(priv->clk_gate);
-+
-+ return ret;
-+}
-+
-+static int ltq_i2c_remove(struct platform_device *pdev)
-+{
-+ struct ltq_i2c *priv = platform_get_drvdata(pdev);
-+
-+ /* disable bus */
-+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
-+
-+ /* power down the core */
-+ clk_deactivate(priv->clk_gate);
-+
-+ /* remove driver */
-+ i2c_del_adapter(&priv->adap);
-+ kfree(priv);
-+
-+ dev_dbg(&pdev->dev, "removed\n");
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+static const struct of_device_id ltq_i2c_match[] = {
-+ { .compatible = "lantiq,lantiq-i2c" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ltq_i2c_match);
-+
-+static struct platform_driver ltq_i2c_driver = {
-+ .probe = ltq_i2c_probe,
-+ .remove = ltq_i2c_remove,
-+ .driver = {
-+ .name = DRV_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = ltq_i2c_match,
-+ },
-+};
-+
-+module_platform_driver(ltq_i2c_driver);
-+
-+MODULE_DESCRIPTION("Lantiq I2C bus adapter");
-+MODULE_AUTHOR("Thomas Langer <thomas.langer@lantiq.com>");
-+MODULE_ALIAS("platform:" DRV_NAME);
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-lantiq.h
-@@ -0,0 +1,234 @@
-+#ifndef I2C_LANTIQ_H
-+#define I2C_LANTIQ_H
-+
-+/* I2C register structure */
-+struct lantiq_reg_i2c {
-+ /* I2C Kernel Clock Control Register */
-+ unsigned int clc; /* 0x00000000 */
-+ /* Reserved */
-+ unsigned int res_0; /* 0x00000004 */
-+ /* I2C Identification Register */
-+ unsigned int id; /* 0x00000008 */
-+ /* Reserved */
-+ unsigned int res_1; /* 0x0000000C */
-+ /*
-+ * I2C RUN Control Register
-+ * This register enables and disables the I2C peripheral. Before
-+ * enabling, the I2C has to be configured properly. After enabling
-+ * no configuration is possible
-+ */
-+ unsigned int run_ctrl; /* 0x00000010 */
-+ /*
-+ * I2C End Data Control Register
-+ * This register is used to either turn around the data transmission
-+ * direction or to address another slave without sending a stop
-+ * condition. Also the software can stop the slave-transmitter by
-+ * sending a not-accolade when working as master-receiver or even
-+ * stop data transmission immediately when operating as
-+ * master-transmitter. The writing to the bits of this control
-+ * register is only effective when in MASTER RECEIVES BYTES, MASTER
-+ * TRANSMITS BYTES, MASTER RESTART or SLAVE RECEIVE BYTES state
-+ */
-+ unsigned int endd_ctrl; /* 0x00000014 */
-+ /*
-+ * I2C Fractional Divider Configuration Register
-+ * These register is used to program the fractional divider of the I2C
-+ * bus. Before the peripheral is switched on by setting the RUN-bit the
-+ * two (fixed) values for the two operating frequencies are programmed
-+ * into these (configuration) registers. The Register FDIV_HIGH_CFG has
-+ * the same layout as I2C_FDIV_CFG.
-+ */
-+ unsigned int fdiv_cfg; /* 0x00000018 */
-+ /*
-+ * I2C Fractional Divider (highspeed mode) Configuration Register
-+ * These register is used to program the fractional divider of the I2C
-+ * bus. Before the peripheral is switched on by setting the RUN-bit the
-+ * two (fixed) values for the two operating frequencies are programmed
-+ * into these (configuration) registers. The Register FDIV_CFG has the
-+ * same layout as I2C_FDIV_CFG.
-+ */
-+ unsigned int fdiv_high_cfg; /* 0x0000001C */
-+ /* I2C Address Configuration Register */
-+ unsigned int addr_cfg; /* 0x00000020 */
-+ /* I2C Bus Status Register
-+ * This register gives a status information of the I2C. This additional
-+ * information can be used by the software to start proper actions.
-+ */
-+ unsigned int bus_stat; /* 0x00000024 */
-+ /* I2C FIFO Configuration Register */
-+ unsigned int fifo_cfg; /* 0x00000028 */
-+ /* I2C Maximum Received Packet Size Register */
-+ unsigned int mrps_ctrl; /* 0x0000002C */
-+ /* I2C Received Packet Size Status Register */
-+ unsigned int rps_stat; /* 0x00000030 */
-+ /* I2C Transmit Packet Size Register */
-+ unsigned int tps_ctrl; /* 0x00000034 */
-+ /* I2C Filled FIFO Stages Status Register */
-+ unsigned int ffs_stat; /* 0x00000038 */
-+ /* Reserved */
-+ unsigned int res_2; /* 0x0000003C */
-+ /* I2C Timing Configuration Register */
-+ unsigned int tim_cfg; /* 0x00000040 */
-+ /* Reserved */
-+ unsigned int res_3[7]; /* 0x00000044 */
-+ /* I2C Error Interrupt Request Source Mask Register */
-+ unsigned int err_irqsm; /* 0x00000060 */
-+ /* I2C Error Interrupt Request Source Status Register */
-+ unsigned int err_irqss; /* 0x00000064 */
-+ /* I2C Error Interrupt Request Source Clear Register */
-+ unsigned int err_irqsc; /* 0x00000068 */
-+ /* Reserved */
-+ unsigned int res_4; /* 0x0000006C */
-+ /* I2C Protocol Interrupt Request Source Mask Register */
-+ unsigned int p_irqsm; /* 0x00000070 */
-+ /* I2C Protocol Interrupt Request Source Status Register */
-+ unsigned int p_irqss; /* 0x00000074 */
-+ /* I2C Protocol Interrupt Request Source Clear Register */
-+ unsigned int p_irqsc; /* 0x00000078 */
-+ /* Reserved */
-+ unsigned int res_5; /* 0x0000007C */
-+ /* I2C Raw Interrupt Status Register */
-+ unsigned int ris; /* 0x00000080 */
-+ /* I2C Interrupt Mask Control Register */
-+ unsigned int imsc; /* 0x00000084 */
-+ /* I2C Masked Interrupt Status Register */
-+ unsigned int mis; /* 0x00000088 */
-+ /* I2C Interrupt Clear Register */
-+ unsigned int icr; /* 0x0000008C */
-+ /* I2C Interrupt Set Register */
-+ unsigned int isr; /* 0x00000090 */
-+ /* I2C DMA Enable Register */
-+ unsigned int dmae; /* 0x00000094 */
-+ /* Reserved */
-+ unsigned int res_6[8154]; /* 0x00000098 */
-+ /* I2C Transmit Data Register */
-+ unsigned int txd; /* 0x00008000 */
-+ /* Reserved */
-+ unsigned int res_7[4095]; /* 0x00008004 */
-+ /* I2C Receive Data Register */
-+ unsigned int rxd; /* 0x0000C000 */
-+ /* Reserved */
-+ unsigned int res_8[4095]; /* 0x0000C004 */
-+};
-+
-+/*
-+ * Clock Divider for Normal Run Mode
-+ * Max 8-bit divider value. IF RMC is 0 the module is disabled. Note: As long
-+ * as the new divider value RMC is not valid, the register returns 0x0000 00xx
-+ * on reading.
-+ */
-+#define I2C_CLC_RMC_MASK 0x0000FF00
-+/* field offset */
-+#define I2C_CLC_RMC_OFFSET 8
-+
-+/* Fields of "I2C Identification Register" */
-+/* Module ID */
-+#define I2C_ID_ID_MASK 0x0000FF00
-+/* field offset */
-+#define I2C_ID_ID_OFFSET 8
-+/* Revision */
-+#define I2C_ID_REV_MASK 0x000000FF
-+/* field offset */
-+#define I2C_ID_REV_OFFSET 0
-+
-+/* Fields of "I2C Interrupt Mask Control Register" */
-+/* Enable */
-+#define I2C_IMSC_BREQ_INT_EN 0x00000008
-+/* Enable */
-+#define I2C_IMSC_LBREQ_INT_EN 0x00000004
-+
-+/* Fields of "I2C Fractional Divider Configuration Register" */
-+/* field offset */
-+#define I2C_FDIV_CFG_INC_OFFSET 16
-+
-+/* Fields of "I2C Interrupt Mask Control Register" */
-+/* Enable */
-+#define I2C_IMSC_I2C_P_INT_EN 0x00000020
-+/* Enable */
-+#define I2C_IMSC_I2C_ERR_INT_EN 0x00000010
-+
-+/* Fields of "I2C Error Interrupt Request Source Status Register" */
-+/* TXF_OFL */
-+#define I2C_ERR_IRQSS_TXF_OFL 0x00000008
-+/* TXF_UFL */
-+#define I2C_ERR_IRQSS_TXF_UFL 0x00000004
-+/* RXF_OFL */
-+#define I2C_ERR_IRQSS_RXF_OFL 0x00000002
-+/* RXF_UFL */
-+#define I2C_ERR_IRQSS_RXF_UFL 0x00000001
-+
-+/* Fields of "I2C Raw Interrupt Status Register" */
-+/* Read: Interrupt occurred. */
-+#define I2C_RIS_I2C_ERR_INT_INTOCC 0x00000010
-+/* Read: Interrupt occurred. */
-+#define I2C_RIS_I2C_P_INT_INTOCC 0x00000020
-+
-+/* Fields of "I2C FIFO Configuration Register" */
-+/* TX FIFO Flow Control */
-+#define I2C_FIFO_CFG_TXFC 0x00020000
-+/* RX FIFO Flow Control */
-+#define I2C_FIFO_CFG_RXFC 0x00010000
-+/* Word aligned (character alignment of four characters) */
-+#define I2C_FIFO_CFG_TXFA_TXFA2 0x00002000
-+/* Word aligned (character alignment of four characters) */
-+#define I2C_FIFO_CFG_RXFA_RXFA2 0x00000200
-+/* 1 word */
-+#define I2C_FIFO_CFG_TXBS_TXBS0 0x00000000
-+
-+/* Fields of "I2C FIFO Configuration Register" */
-+/* 1 word */
-+#define I2C_FIFO_CFG_RXBS_RXBS0 0x00000000
-+/* Stop on Packet End Enable */
-+#define I2C_ADDR_CFG_SOPE_EN 0x00200000
-+/* Stop on Not Acknowledge Enable */
-+#define I2C_ADDR_CFG_SONA_EN 0x00100000
-+/* Enable */
-+#define I2C_ADDR_CFG_MnS_EN 0x00080000
-+
-+/* Fields of "I2C Interrupt Clear Register" */
-+/* Clear */
-+#define I2C_ICR_BREQ_INT_CLR 0x00000008
-+/* Clear */
-+#define I2C_ICR_LBREQ_INT_CLR 0x00000004
-+
-+/* Fields of "I2C Fractional Divider Configuration Register" */
-+/* field offset */
-+#define I2C_FDIV_CFG_DEC_OFFSET 0
-+
-+/* Fields of "I2C Bus Status Register" */
-+/* Bus Status */
-+#define I2C_BUS_STAT_BS_MASK 0x00000003
-+/* Read from I2C Bus. */
-+#define I2C_BUS_STAT_RNW_READ 0x00000004
-+/* I2C Bus is free. */
-+#define I2C_BUS_STAT_BS_FREE 0x00000000
-+/*
-+ * The device is working as master and has claimed the control on the
-+ * I2C-bus (busy master).
-+ */
-+#define I2C_BUS_STAT_BS_BM 0x00000002
-+
-+/* Fields of "I2C RUN Control Register" */
-+/* Enable */
-+#define I2C_RUN_CTRL_RUN_EN 0x00000001
-+
-+/* Fields of "I2C End Data Control Register" */
-+/*
-+ * Set End of Transmission
-+ * Note:Do not write '1' to this bit when bus is free. This will cause an
-+ * abort after the first byte when a new transfer is started.
-+ */
-+#define I2C_ENDD_CTRL_SETEND 0x00000002
-+
-+/* Fields of "I2C Protocol Interrupt Request Source Status Register" */
-+/* NACK */
-+#define I2C_P_IRQSS_NACK 0x00000010
-+/* AL */
-+#define I2C_P_IRQSS_AL 0x00000008
-+/* RX */
-+#define I2C_P_IRQSS_RX 0x00000040
-+/* TX_END */
-+#define I2C_P_IRQSS_TX_END 0x00000020
-+
-+
-+#endif /* I2C_LANTIQ_H */
diff --git a/target/linux/lantiq/patches-6.1/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch b/target/linux/lantiq/patches-6.1/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
deleted file mode 100644
index aea5716596..0000000000
--- a/target/linux/lantiq/patches-6.1/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
+++ /dev/null
@@ -1,218 +0,0 @@
-From f8c5db89e793a4bc6c1e87bd7b3a5cec16b75bc3 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 10 Sep 2014 22:42:14 +0200
-Subject: [PATCH 35/36] owrt: lantiq: wifi and ethernet eeprom handling
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +
- arch/mips/lantiq/xway/Makefile | 3 +
- arch/mips/lantiq/xway/ath5k_eep.c | 136 +++++++++++++++++++++
- arch/mips/lantiq/xway/eth_mac.c | 25 ++++
- drivers/net/ethernet/lantiq_etop.c | 6 +-
- 5 files changed, 172 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/lantiq/xway/ath5k_eep.c
- create mode 100644 arch/mips/lantiq/xway/eth_mac.c
-
---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
-+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
-@@ -102,5 +102,8 @@ int xrx200_gphy_boot(struct device *dev,
- extern void ltq_pmu_enable(unsigned int module);
- extern void ltq_pmu_disable(unsigned int module);
-
-+/* allow the ethernet driver to load a flash mapped mac addr */
-+const u8* ltq_get_eth_mac(void);
-+
- #endif /* CONFIG_SOC_TYPE_XWAY */
- #endif /* _LTQ_XWAY_H__ */
---- a/arch/mips/lantiq/xway/Makefile
-+++ b/arch/mips/lantiq/xway/Makefile
-@@ -8,3 +8,6 @@ obj-y += timer.o
- endif
-
- obj-y += vmmc.o
-+
-+obj-y += eth_mac.o
-+obj-$(CONFIG_PCI) += ath5k_eep.o
---- /dev/null
-+++ b/arch/mips/lantiq/xway/ath5k_eep.c
-@@ -0,0 +1,136 @@
-+/*
-+ * Copyright (C) 2011 Luca Olivetti <luca@ventoso.org>
-+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
-+ * Copyright (C) 2011 Andrej Vlašić <andrej.vlasic0@gmail.com>
-+ * Copyright (C) 2013 Álvaro Fernández Rojas <noltari@gmail.com>
-+ * Copyright (C) 2013 Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
-+ * Copyright (C) 2015 Vittorio Gambaletta <openwrt@vittgam.net>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ath5k_platform.h>
-+#include <linux/pci.h>
-+#include <linux/err.h>
-+#include <linux/mtd/mtd.h>
-+#include <lantiq_soc.h>
-+
-+extern int (*ltq_pci_plat_dev_init)(struct pci_dev *dev);
-+struct ath5k_platform_data ath5k_pdata;
-+static u8 athxk_eeprom_mac[6];
-+
-+static int ath5k_pci_plat_dev_init(struct pci_dev *dev)
-+{
-+ dev->dev.platform_data = &ath5k_pdata;
-+ return 0;
-+}
-+
-+static int ath5k_eep_load;
-+int __init of_ath5k_eeprom_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node, *mtd_np = NULL;
-+ int mac_offset;
-+ u32 mac_inc = 0;
-+ int i;
-+ struct mtd_info *the_mtd;
-+ size_t flash_readlen;
-+ const __be32 *list;
-+ const char *part;
-+ phandle phandle;
-+
-+ list = of_get_property(np, "ath,eep-flash", &i);
-+ if (!list || (i != (2 * sizeof(*list))))
-+ return -ENODEV;
-+
-+ phandle = be32_to_cpup(list++);
-+ if (phandle)
-+ mtd_np = of_find_node_by_phandle(phandle);
-+
-+ if (!mtd_np)
-+ return -ENODEV;
-+
-+ part = of_get_property(mtd_np, "label", NULL);
-+ if (!part)
-+ part = mtd_np->name;
-+
-+ the_mtd = get_mtd_device_nm(part);
-+ if (IS_ERR(the_mtd))
-+ return -ENODEV;
-+
-+ ath5k_pdata.eeprom_data = kmalloc(ATH5K_PLAT_EEP_MAX_WORDS<<1, GFP_KERNEL);
-+
-+ i = mtd_read(the_mtd, be32_to_cpup(list), ATH5K_PLAT_EEP_MAX_WORDS << 1,
-+ &flash_readlen, (void *) ath5k_pdata.eeprom_data);
-+
-+ if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
-+ size_t mac_readlen;
-+ mtd_read(the_mtd, mac_offset, 6, &mac_readlen,
-+ (void *) athxk_eeprom_mac);
-+ }
-+ put_mtd_device(the_mtd);
-+
-+ if (((ATH5K_PLAT_EEP_MAX_WORDS<<1) != flash_readlen) || i) {
-+ dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
-+ return -ENODEV;
-+ }
-+
-+ if (of_find_property(np, "ath,eep-swap", NULL))
-+ for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS; i++)
-+ ath5k_pdata.eeprom_data[i] = swab16(ath5k_pdata.eeprom_data[i]);
-+
-+ if (!is_valid_ether_addr(athxk_eeprom_mac) && ltq_get_eth_mac())
-+ ether_addr_copy(athxk_eeprom_mac, ltq_get_eth_mac());
-+
-+ if (!is_valid_ether_addr(athxk_eeprom_mac)) {
-+ dev_warn(&pdev->dev, "using random mac\n");
-+ eth_random_addr(athxk_eeprom_mac);
-+ }
-+
-+ if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
-+ athxk_eeprom_mac[5] += mac_inc;
-+
-+ ath5k_pdata.macaddr = athxk_eeprom_mac;
-+ ltq_pci_plat_dev_init = ath5k_pci_plat_dev_init;
-+
-+ dev_info(&pdev->dev, "loaded ath5k eeprom\n");
-+
-+ return 0;
-+}
-+
-+static struct of_device_id ath5k_eeprom_ids[] = {
-+ { .compatible = "ath5k,eeprom" },
-+ { }
-+};
-+
-+static struct platform_driver ath5k_eeprom_driver = {
-+ .driver = {
-+ .name = "ath5k,eeprom",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(ath5k_eeprom_ids),
-+ },
-+};
-+
-+static int __init of_ath5k_eeprom_init(void)
-+{
-+ int ret = platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
-+
-+ if (ret)
-+ ath5k_eep_load = 1;
-+
-+ return ret;
-+}
-+
-+static int __init of_ath5k_eeprom_init_late(void)
-+{
-+ if (!ath5k_eep_load)
-+ return 0;
-+
-+ return platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
-+}
-+late_initcall(of_ath5k_eeprom_init_late);
-+subsys_initcall(of_ath5k_eeprom_init);
---- /dev/null
-+++ b/arch/mips/lantiq/xway/eth_mac.c
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/if_ether.h>
-+
-+static u8 eth_mac[6];
-+static int eth_mac_set;
-+
-+const u8* ltq_get_eth_mac(void)
-+{
-+ return eth_mac;
-+}
-+
-+static int __init setup_ethaddr(char *str)
-+{
-+ eth_mac_set = mac_pton(str, eth_mac);
-+ return !eth_mac_set;
-+}
-+early_param("ethaddr", setup_ethaddr);
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -763,7 +763,11 @@ ltq_etop_init(struct net_device *dev)
- if (err)
- goto err_hw;
-
-- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
-+ memcpy(&mac.sa_data, ltq_get_eth_mac(), ETH_ALEN);
-+
-+ if (!is_valid_ether_addr(mac.sa_data))
-+ memcpy(&mac.sa_data, priv->mac, ETH_ALEN);
-+
- if (!is_valid_ether_addr(mac.sa_data)) {
- pr_warn("etop: invalid MAC, using random\n");
- eth_random_addr(mac.sa_data);
diff --git a/target/linux/lantiq/patches-6.1/0042-arch-mips-increase-io_space_limit.patch b/target/linux/lantiq/patches-6.1/0042-arch-mips-increase-io_space_limit.patch
deleted file mode 100644
index c81222af57..0000000000
--- a/target/linux/lantiq/patches-6.1/0042-arch-mips-increase-io_space_limit.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 9807eb80a1b3bad7a4a89aa6566497bb1cadd6ef Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 3 Jun 2016 13:12:20 +0200
-Subject: [PATCH] arch: mips: increase io_space_limit
-
-this value comes from x86 and breaks some pci devices
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/mips/include/asm/mach-lantiq/spaces.h | 8 ++++++++
- 1 file changed, 8 insertions(+)
- create mode 100644 arch/mips/include/asm/mach-lantiq/spaces.h
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/spaces.h
-@@ -0,0 +1,8 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __ASM_MACH_LANTIQ_SPACES_H_
-+#define __ASM_MACH_LANTIQ_SPACES_H_
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+#include <asm/mach-generic/spaces.h>
-+#endif
diff --git a/target/linux/lantiq/patches-6.1/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch b/target/linux/lantiq/patches-6.1/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch
deleted file mode 100644
index a3bbda7c33..0000000000
--- a/target/linux/lantiq/patches-6.1/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From de2cad82c4d0872066f83ce59462603852b47f03 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:55:24 +0100
-Subject: [PATCH 2/2] usb: dwc2: add support for other Lantiq SoCs
-
-The size of the internal RAM of the DesignWare USB controller changed
-between the different Lantiq SoCs. We have the following sizes:
-
-Amazon + Danube: 8 KByte
-Amazon SE + arx100: 2 KByte
-xrx200 + xrx300: 2.5 KByte
-
-For Danube SoC we do not provide the params and let the driver decide
-to use sane defaults, for the Amazon SE and arx100 we use small fifos
-and for the xrx200 and xrx300 SCs a little bit bigger periodic fifo.
-The auto detection of max_transfer_size and max_packet_count should
-work, so remove it.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/usb/dwc2/platform.c | 46 ++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 39 insertions(+), 7 deletions(-)
-
---- a/drivers/usb/dwc2/params.c
-+++ b/drivers/usb/dwc2/params.c
-@@ -115,7 +115,15 @@ static void dwc2_set_rk_params(struct dw
- p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
- }
-
--static void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg)
-+static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_caps.hnp_support = false;
-+ p->otg_caps.srp_support = false;
-+}
-+
-+static void dwc2_set_ltq_ase_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-
-@@ -124,12 +132,21 @@ static void dwc2_set_ltq_params(struct d
- p->host_rx_fifo_size = 288;
- p->host_nperio_tx_fifo_size = 128;
- p->host_perio_tx_fifo_size = 96;
-- p->max_transfer_size = 65535;
-- p->max_packet_count = 511;
- p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
- GAHBCFG_HBSTLEN_SHIFT;
- }
-
-+static void dwc2_set_ltq_xrx200_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_caps.hnp_support = false;
-+ p->otg_caps.srp_support = false;
-+ p->host_rx_fifo_size = 288;
-+ p->host_nperio_tx_fifo_size = 128;
-+ p->host_perio_tx_fifo_size = 136;
-+}
-+
- static void dwc2_set_amlogic_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-@@ -241,8 +258,11 @@ const struct of_device_id dwc2_of_match_
- { .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 },
-- { .compatible = "lantiq,arx100-usb", .data = dwc2_set_ltq_params },
-- { .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params },
-+ { .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 },
-+ { .compatible = "lantiq,xrx200-usb", .data = &dwc2_set_ltq_xrx200_params },
-+ { .compatible = "lantiq,xrx300-usb", .data = &dwc2_set_ltq_xrx200_params },
- { .compatible = "snps,dwc2" },
- { .compatible = "samsung,s3c6400-hsotg",
- .data = dwc2_set_s3c6400_params },
diff --git a/target/linux/lantiq/patches-6.1/0051-MIPS-lantiq-improve-USB-initialization.patch b/target/linux/lantiq/patches-6.1/0051-MIPS-lantiq-improve-USB-initialization.patch
deleted file mode 100644
index dca9880e8f..0000000000
--- a/target/linux/lantiq/patches-6.1/0051-MIPS-lantiq-improve-USB-initialization.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 14909c4e4e836925668e74fc6e0e85ba0283cbf9 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:40:12 +0100
-Subject: [PATCH 2/2] MIPS: lantiq: improve USB initialization
-
-This adds code to initialize the USB controller and PHY also on Danube,
-Amazon SE and AR10. This code is based on the Vendor driver from
-different UGW versions and compared to the hardware documentation.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- arch/mips/lantiq/xway/sysctrl.c | 20 +++++++
- 2 files changed, 110 insertions(+), 30 deletions(-)
-
-
---- a/arch/mips/lantiq/xway/sysctrl.c
-+++ b/arch/mips/lantiq/xway/sysctrl.c
-@@ -248,6 +248,25 @@ static void pmu_disable(struct clk *clk)
- pr_warn("deactivating PMU module failed!");
- }
-
-+static void usb_set_clock(void)
-+{
-+ unsigned int val = ltq_cgu_r32(ifccr);
-+
-+ if (of_machine_is_compatible("lantiq,ar10") ||
-+ of_machine_is_compatible("lantiq,grx390")) {
-+ val &= ~0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ar9") ||
-+ of_machine_is_compatible("lantiq,vr9")) {
-+ /* TODO: this depends on the XTAL frequency */
-+ val |= 0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ase")) {
-+ val |= 0x20; /* from XTAL */
-+ } else if (of_machine_is_compatible("lantiq,danube")) {
-+ val |= 0x30; /* 12 MHz, generated from 36 MHz */
-+ }
-+ ltq_cgu_w32(val, ifccr);
-+}
-+
- /* the pci enable helper */
- static int pci_enable(struct clk *clk)
- {
-@@ -589,4 +608,5 @@ void __init ltq_soc_init(void)
- clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
- clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
- }
-+ usb_set_clock();
- }
diff --git a/target/linux/lantiq/patches-6.1/0101-find_active_root.patch b/target/linux/lantiq/patches-6.1/0101-find_active_root.patch
deleted file mode 100644
index 99e187a012..0000000000
--- a/target/linux/lantiq/patches-6.1/0101-find_active_root.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 2c82524000cca691c89c9fda251b55ef04eabcb6 Mon Sep 17 00:00:00 2001
-From: Mathias Kresin <openwrt@kresin.me>
-Date: Mon, 2 May 2016 18:50:00 +0000
-Subject: [PATCH] find active root
-
-Signed-off-by: Mathias Kresin <openwrt@kresin.me>
----
- drivers/mtd/parsers/ofpart_core.c | 49 ++++++++++++++++++++++++++++++-
- 1 file changed, 48 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/parsers/ofpart_core.c
-+++ b/drivers/mtd/parsers/ofpart_core.c
-@@ -38,6 +38,38 @@ static bool node_has_compatible(struct d
- return of_get_property(pp, "compatible", NULL);
- }
-
-+static uint8_t * brnboot_get_selected_root_part(struct mtd_info *master,
-+ loff_t offset)
-+{
-+ static uint8_t root_id;
-+ int err, len;
-+
-+ err = mtd_read(master, offset, 0x01, &len, &root_id);
-+
-+ if (mtd_is_bitflip(err) || !err)
-+ return &root_id;
-+
-+ return NULL;
-+}
-+
-+static void brnboot_set_active_root_part(struct mtd_partition *pparts,
-+ struct device_node **part_nodes,
-+ int nr_parts,
-+ uint8_t *root_id)
-+{
-+ int i;
-+
-+ for (i = 0; i < nr_parts; i++) {
-+ int part_root_id;
-+
-+ if (!of_property_read_u32(part_nodes[i], "brnboot,root-id", &part_root_id)
-+ && part_root_id == *root_id) {
-+ pparts[i].name = "firmware";
-+ break;
-+ }
-+ }
-+}
-+
- static int parse_fixed_partitions(struct mtd_info *master,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -51,6 +83,8 @@ static int parse_fixed_partitions(struct
- struct device_node *pp;
- int nr_parts, i, ret = 0;
- bool dedicated = true;
-+ uint8_t *proot_id = NULL;
-+ struct device_node **part_nodes;
-
- /* Pull of_node from the master device node */
- mtd_node = mtd_get_of_node(master);
-@@ -95,7 +129,9 @@ static int parse_fixed_partitions(struct
- return 0;
-
- parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
-- if (!parts)
-+ part_nodes = kcalloc(nr_parts, sizeof(*part_nodes), GFP_KERNEL);
-+
-+ if (!parts || !part_nodes)
- return -ENOMEM;
-
- i = 0;
-@@ -166,6 +202,11 @@ static int parse_fixed_partitions(struct
- if (of_property_read_bool(pp, "slc-mode"))
- parts[i].add_flags |= MTD_SLC_ON_MLC_EMULATION;
-
-+ if (!proot_id && of_device_is_compatible(pp, "brnboot,root-selector"))
-+ proot_id = brnboot_get_selected_root_part(master, parts[i].offset);
-+
-+ part_nodes[i] = pp;
-+
- i++;
- }
-
-@@ -175,6 +216,11 @@ static int parse_fixed_partitions(struct
- if (quirks && quirks->post_parse)
- quirks->post_parse(master, parts, nr_parts);
-
-+ if (proot_id)
-+ brnboot_set_active_root_part(parts, part_nodes, nr_parts, proot_id);
-+
-+ kfree(part_nodes);
-+
- *pparts = parts;
- return nr_parts;
-
-@@ -185,6 +231,7 @@ ofpart_fail:
- ofpart_none:
- of_node_put(pp);
- kfree(parts);
-+ kfree(part_nodes);
- return ret;
- }
-
diff --git a/target/linux/lantiq/patches-6.1/0151-lantiq-ifxmips_pcie-use-of.patch b/target/linux/lantiq/patches-6.1/0151-lantiq-ifxmips_pcie-use-of.patch
deleted file mode 100644
index b83bf992a6..0000000000
--- a/target/linux/lantiq/patches-6.1/0151-lantiq-ifxmips_pcie-use-of.patch
+++ /dev/null
@@ -1,486 +0,0 @@
-From 1d1885f4a7abd7272f47b835b03d8662fb981d19 Mon Sep 17 00:00:00 2001
-From: Eddi De Pieri <eddi@depieri.net>
-Date: Tue, 14 Oct 2014 11:04:00 +0000
-Subject: [PATCH] MIPS: lantiq: ifxmips_pcie: use of
-
-Signed-off-by: Eddi De Pieri <eddi@depieri.net>
----
- arch/mips/pci/Makefile | 2 +-
- arch/mips/pci/ifxmips_pcie.c | 151 +++++++++++++++++++++++++++----
- arch/mips/pci/ifxmips_pcie_vr9.h | 105 ---------------------
- 3 files changed, 133 insertions(+), 125 deletions(-)
-
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -41,7 +41,7 @@ obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o
- obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
- obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
- obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
--obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
-+obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie.o fixup-lantiq-pcie.o
- obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
- obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o
- obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o
---- a/arch/mips/pci/ifxmips_pcie.c
-+++ b/arch/mips/pci/ifxmips_pcie.c
-@@ -16,8 +16,15 @@
- #include <asm/paccess.h>
- #include <linux/pci.h>
- #include <linux/pci_regs.h>
-+#include <linux/phy/phy.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
-
-+#include <linux/of_gpio.h>
-+#include <linux/of_platform.h>
-+
- #include "ifxmips_pcie.h"
- #include "ifxmips_pcie_reg.h"
-
-@@ -25,11 +32,6 @@
- #define IFX_PCIE_ERROR_INT
- #define IFX_PCIE_IO_32BIT
-
--#define IFX_PCIE_IR (INT_NUM_IM4_IRL0 + 25)
--#define IFX_PCIE_INTA (INT_NUM_IM4_IRL0 + 8)
--#define IFX_PCIE_INTB (INT_NUM_IM4_IRL0 + 9)
--#define IFX_PCIE_INTC (INT_NUM_IM4_IRL0 + 10)
--#define IFX_PCIE_INTD (INT_NUM_IM4_IRL0 + 11)
- #define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
- #define SM(_v, _f) (((_v) << _f##_S) & (_f))
- #define IFX_REG_SET_BIT(_f, _r) \
-@@ -40,30 +42,30 @@
- static DEFINE_SPINLOCK(ifx_pcie_lock);
-
- u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
-+static int pcie_reset_gpio;
-+static struct phy *ltq_pcie_phy;
-+static struct reset_control *ltq_pcie_reset;
-+static struct regmap *ltq_rcu_regmap;
-+static bool switch_pcie_endianess;
-
- static ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
- {
- .ir_irq = {
-- .irq = IFX_PCIE_IR,
- .name = "ifx_pcie_rc0",
- },
-
- .legacy_irq = {
- {
- .irq_bit = PCIE_IRN_INTA,
-- .irq = IFX_PCIE_INTA,
- },
- {
- .irq_bit = PCIE_IRN_INTB,
-- .irq = IFX_PCIE_INTB,
- },
- {
- .irq_bit = PCIE_IRN_INTC,
-- .irq = IFX_PCIE_INTC,
- },
- {
- .irq_bit = PCIE_IRN_INTD,
-- .irq = IFX_PCIE_INTD,
- },
- },
- },
-@@ -82,6 +84,22 @@ void ifx_pcie_debug(const char *fmt, ...
- printk("%s", buf);
- }
-
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+ gpio_set_value(pcie_reset_gpio, 1);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(pcie_reset_gpio, 0);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+}
-
- static inline int pcie_ltssm_enable(int pcie_port)
- {
-@@ -857,7 +875,8 @@ pcie_rc_core_int_init(int pcie_port)
- ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
- pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
- if (ret)
-- printk(KERN_ERR "%s request irq %d failed\n", __func__, IFX_PCIE_IR);
-+ printk(KERN_ERR "%s request irq %d failed\n", __func__,
-+ pcie_irqs[pcie_port].ir_irq.irq);
-
- return ret;
- }
-@@ -988,10 +1007,26 @@ int ifx_pcie_bios_plat_dev_init(struct
- static int
- pcie_rc_initialize(int pcie_port)
- {
-- int i;
-+ int i, ret;
- #define IFX_PCIE_PHY_LOOP_CNT 5
-
-- pcie_rcu_endian_setup(pcie_port);
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_M,
-+ IFX_RCU_AHB_BE_PCIE_M);
-+
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_S,
-+ IFX_RCU_AHB_BE_PCIE_S);
-+ if (switch_pcie_endianess) {
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_XBAR_S,
-+ IFX_RCU_AHB_BE_XBAR_S);
-+ }
-+#else
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_S,
-+ 0x0);
-+#endif
-+
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_XBAR_M,
-+ 0x0);
-
- pcie_ep_gpio_rst_init(pcie_port);
-
-@@ -1000,26 +1035,21 @@ pcie_rc_initialize(int pcie_port)
- * reset PCIe PHY will solve this issue
- */
- for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
-- /* Disable PCIe PHY Analog part for sanity check */
-- pcie_phy_pmu_disable(pcie_port);
--
-- pcie_phy_rst_assert(pcie_port);
-- pcie_phy_rst_deassert(pcie_port);
--
-- /* Make sure PHY PLL is stable */
-- udelay(20);
--
-- /* PCIe Core reset enabled, low active, sw programmed */
-- pcie_core_rst_assert(pcie_port);
-+ ret = phy_init(ltq_pcie_phy);
-+ if (ret)
-+ continue;
-
- /* Put PCIe EP in reset status */
- pcie_device_rst_assert(pcie_port);
-
-- /* PCI PHY & Core reset disabled, high active, sw programmed */
-- pcie_core_rst_deassert(pcie_port);
-+ udelay(1);
-+ reset_control_deassert(ltq_pcie_reset);
-
-- /* Already in a quiet state, program PLL, enable PHY, check ready bit */
-- pcie_phy_clock_mode_setup(pcie_port);
-+ ret = phy_power_on(ltq_pcie_phy);
-+ if (ret) {
-+ phy_exit(ltq_pcie_phy);
-+ continue;
-+ }
-
- /* Enable PCIe PHY and Clock */
- pcie_core_pmu_setup(pcie_port);
-@@ -1035,6 +1065,10 @@ pcie_rc_initialize(int pcie_port)
- /* Once link is up, break out */
- if (pcie_app_loigc_setup(pcie_port) == 0)
- break;
-+
-+ phy_power_off(ltq_pcie_phy);
-+ reset_control_assert(ltq_pcie_reset);
-+ phy_exit(ltq_pcie_phy);
- }
- if (i >= IFX_PCIE_PHY_LOOP_CNT) {
- printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
-@@ -1045,17 +1079,73 @@ pcie_rc_initialize(int pcie_port)
- return 0;
- }
-
--static int __init ifx_pcie_bios_init(void)
-+static int ifx_pcie_bios_probe(struct platform_device *pdev)
- {
-+ struct device_node *node = pdev->dev.of_node;
- void __iomem *io_map_base;
- int pcie_port;
- int startup_port;
-+ struct device_node *np;
-+ struct pci_bus *bus;
-+
-+ /*
-+ * In case a PCI device is physical present, the Lantiq PCI driver need
-+ * to be loaded prior to the Lantiq PCIe driver. Otherwise none of them
-+ * will work.
-+ *
-+ * In case the lantiq PCI driver is enabled in the device tree, check if
-+ * a PCI bus (hopefully the one of the Lantiq PCI driver one) is already
-+ * registered.
-+ *
-+ * It will fail if there is another PCI controller, this controller is
-+ * registered before the Lantiq PCIe driver is probe and the lantiq PCI
-+ */
-+ np = of_find_compatible_node(NULL, NULL, "lantiq,pci-xway");
-+
-+ if (of_device_is_available(np)) {
-+ bus = pci_find_next_bus(bus);
-+
-+ if (!bus)
-+ return -EPROBE_DEFER;
-+ }
-
- /* Enable AHB Master/ Slave */
- pcie_ahb_pmu_setup();
-
- startup_port = IFX_PCIE_PORT0;
--
-+
-+ ltq_pcie_phy = devm_phy_get(&pdev->dev, "pcie");
-+ if (IS_ERR(ltq_pcie_phy))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(ltq_pcie_phy),
-+ "failed to get the PCIe PHY\n");
-+
-+ ltq_pcie_reset = devm_reset_control_get_shared(&pdev->dev, NULL);
-+ if (IS_ERR(ltq_pcie_reset)) {
-+ dev_err(&pdev->dev, "failed to get the PCIe reset line\n");
-+ return PTR_ERR(ltq_pcie_reset);
-+ }
-+
-+ if (of_property_read_bool(node, "lantiq,switch-pcie-endianess")) {
-+ switch_pcie_endianess = true;
-+ dev_info(&pdev->dev, "switch pcie endianess requested\n");
-+ } else {
-+ switch_pcie_endianess = false;
-+ }
-+
-+ ltq_rcu_regmap = syscon_regmap_lookup_by_phandle(node, "lantiq,rcu");
-+ if (IS_ERR(ltq_rcu_regmap))
-+ return PTR_ERR(ltq_rcu_regmap);
-+
-+ pcie_reset_gpio = of_get_named_gpio(node, "gpio-reset", 0);
-+ if (gpio_is_valid(pcie_reset_gpio)) {
-+ int ret = devm_gpio_request(&pdev->dev, pcie_reset_gpio, "pcie-reset");
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to request gpio %d\n", pcie_reset_gpio);
-+ return ret;
-+ }
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+ }
-+
- for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
- if (pcie_rc_initialize(pcie_port) == 0) {
- IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
-@@ -1066,7 +1156,19 @@ static int __init ifx_pcie_bios_init(voi
- IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
- return -ENOMEM;
- }
-+ pcie_irqs[pcie_port].ir_irq.irq = platform_get_irq(pdev, 0);
-+ if (pcie_irqs[pcie_port].ir_irq.irq < 0)
-+ return pcie_irqs[pcie_port].ir_irq.irq;
-+
-+ for (int i = 0; i <= 3; i++){
-+ pcie_irqs[pcie_port].legacy_irq[i].irq = platform_get_irq(pdev, i + 1);
-+
-+ if (pcie_irqs[pcie_port].legacy_irq[i].irq < 0)
-+ return pcie_irqs[pcie_port].legacy_irq[i].irq;
-+ }
-+
- ifx_pcie_controller[pcie_port].pcic.io_map_base = (unsigned long)io_map_base;
-+ pci_load_of_ranges(&ifx_pcie_controller[pcie_port].pcic, node);
-
- register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
- /* XXX, clear error status */
-@@ -1083,6 +1185,30 @@ static int __init ifx_pcie_bios_init(voi
-
- return 0;
- }
-+
-+static const struct of_device_id ifxmips_pcie_match[] = {
-+ { .compatible = "lantiq,pcie-xrx200" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ifxmips_pcie_match);
-+
-+static struct platform_driver ltq_pci_driver = {
-+ .probe = ifx_pcie_bios_probe,
-+ .driver = {
-+ .name = "pcie-xrx200",
-+ .owner = THIS_MODULE,
-+ .of_match_table = ifxmips_pcie_match,
-+ },
-+};
-+
-+int __init ifx_pcie_bios_init(void)
-+{
-+ int ret = platform_driver_register(&ltq_pci_driver);
-+ if (ret)
-+ pr_info("pcie-xrx200: Error registering platform driver!");
-+ return ret;
-+}
-+
- arch_initcall(ifx_pcie_bios_init);
-
- MODULE_LICENSE("GPL");
---- a/arch/mips/pci/ifxmips_pcie_vr9.h
-+++ b/arch/mips/pci/ifxmips_pcie_vr9.h
-@@ -22,8 +22,6 @@
- #include <linux/gpio.h>
- #include <lantiq_soc.h>
-
--#define IFX_PCIE_GPIO_RESET 494
--
- #define IFX_REG_R32 ltq_r32
- #define IFX_REG_W32 ltq_w32
- #define CONFIG_IFX_PCIE_HW_SWAP
-@@ -54,21 +52,6 @@
- #define OUT ((volatile u32*)(IFX_GPIO + 0x0070))
-
-
--static inline void pcie_ep_gpio_rst_init(int pcie_port)
--{
--
-- gpio_request(IFX_PCIE_GPIO_RESET, "pcie-reset");
-- gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-- gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
--
--/* ifx_gpio_pin_reserve(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_dir_out_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_altsel0_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_altsel1_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_open_drain_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);*/
--}
--
- static inline void pcie_ahb_pmu_setup(void)
- {
- /* Enable AHB bus master/slave */
-@@ -80,24 +63,6 @@ static inline void pcie_ahb_pmu_setup(vo
- //AHBS_PMU_SETUP(IFX_PMU_ENABLE);
- }
-
--static inline void pcie_rcu_endian_setup(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
--#ifdef CONFIG_IFX_PCIE_HW_SWAP
-- reg |= IFX_RCU_AHB_BE_PCIE_M;
-- reg |= IFX_RCU_AHB_BE_PCIE_S;
-- reg &= ~IFX_RCU_AHB_BE_XBAR_M;
--#else
-- reg |= IFX_RCU_AHB_BE_PCIE_M;
-- reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-- reg &= ~IFX_RCU_AHB_BE_XBAR_M;
--#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-- IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-- IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
--}
--
- static inline void pcie_phy_pmu_enable(int pcie_port)
- {
- struct clk *clk;
-@@ -116,17 +81,6 @@ static inline void pcie_phy_pmu_disable(
- // PCIE_PHY_PMU_SETUP(IFX_PMU_DISABLE);
- }
-
--static inline void pcie_pdi_big_endian(int pcie_port)
--{
-- u32 reg;
--
-- /* SRAM2PDI endianness control. */
-- reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-- /* Config AHB->PCIe and PDI endianness */
-- reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-- IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
--}
--
- static inline void pcie_pdi_pmu_enable(int pcie_port)
- {
- /* Enable PDI to access PCIe PHY register */
-@@ -136,65 +90,6 @@ static inline void pcie_pdi_pmu_enable(i
- //PDI_PMU_SETUP(IFX_PMU_ENABLE);
- }
-
--static inline void pcie_core_rst_assert(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
--
-- /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-- reg |= 0x00400000;
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_core_rst_deassert(int pcie_port)
--{
-- u32 reg;
--
-- /* Make sure one micro-second delay */
-- udelay(1);
--
-- /* Reset PCIe PHY & Core, bit 22 */
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg &= ~0x00400000;
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_phy_rst_assert(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg |= 0x00001000; /* Bit 12 */
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_phy_rst_deassert(int pcie_port)
--{
-- u32 reg;
--
-- /* Make sure one micro-second delay */
-- udelay(1);
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg &= ~0x00001000; /* Bit 12 */
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_device_rst_assert(int pcie_port)
--{
-- gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
--// ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
--}
--
--static inline void pcie_device_rst_deassert(int pcie_port)
--{
-- mdelay(100);
-- gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
--// gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-- //ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
--}
--
- static inline void pcie_core_pmu_setup(int pcie_port)
- {
- struct clk *clk;
---- a/arch/mips/pci/ifxmips_pcie.h
-+++ b/arch/mips/pci/ifxmips_pcie.h
-@@ -96,13 +96,13 @@ struct ifx_pci_controller {
- };
-
- typedef struct ifx_pcie_ir_irq {
-- const unsigned int irq;
-+ unsigned int irq;
- const char name[16];
- }ifx_pcie_ir_irq_t;
-
- typedef struct ifx_pcie_legacy_irq{
- const u32 irq_bit;
-- const int irq;
-+ int irq;
- }ifx_pcie_legacy_irq_t;
-
- typedef struct ifx_pcie_irq {
diff --git a/target/linux/lantiq/patches-6.1/0152-lantiq-VPE.patch b/target/linux/lantiq/patches-6.1/0152-lantiq-VPE.patch
deleted file mode 100644
index 51810fe924..0000000000
--- a/target/linux/lantiq/patches-6.1/0152-lantiq-VPE.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From 4d48a3d1ef6f8d036bd926e3c1f70b56fcc679b2 Mon Sep 17 00:00:00 2001
-From: Stefan Koch <stefan.koch10@gmail.com>
-Date: Thu, 20 Oct 2016 21:32:00 +0200
-Subject: [PATCH] lantiq: vpe
-
-Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
----
- arch/mips/Kconfig | 6 ++++
- arch/mips/include/asm/mipsmtregs.h | 5 ++++
- arch/mips/include/asm/vpe.h | 9 ++++++
- arch/mips/kernel/vpe-mt.c | 47 ++++++++++++++++++++++++++++++
- arch/mips/kernel/vpe.c | 35 ++++++++++++++++++++++
- arch/mips/lantiq/prom.c | 4 +++
- 6 files changed, 106 insertions(+)
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -2306,6 +2306,12 @@ config MIPS_VPE_LOADER
- Includes a loader for loading an elf relocatable object
- onto another VPE and running it.
-
-+config IFX_VPE_EXT
-+ bool "IFX APRP Extensions"
-+ depends on MIPS_VPE_LOADER
-+ help
-+ IFX included extensions in APRP
-+
- config MIPS_VPE_LOADER_CMP
- bool
- default "y"
---- a/arch/mips/include/asm/mipsmtregs.h
-+++ b/arch/mips/include/asm/mipsmtregs.h
-@@ -31,6 +31,9 @@
- #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3)
- #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val)
-
-+#define read_c0_vpeopt() __read_32bit_c0_register($1, 7)
-+#define write_c0_vpeopt(val) __write_32bit_c0_register($1, 7, val)
-+
- #define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
- #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
-
-@@ -377,6 +380,8 @@ do { \
- #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
- #define read_vpe_c0_vpeconf1() mftc0(1, 3)
- #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val)
-+#define read_vpe_c0_vpeopt() mftc0(1, 7)
-+#define write_vpe_c0_vpeopt(val) mttc0(1, 7, val)
- #define read_vpe_c0_count() mftc0(9, 0)
- #define write_vpe_c0_count(val) mttc0(9, 0, val)
- #define read_vpe_c0_status() mftc0(12, 0)
---- a/arch/mips/include/asm/vpe.h
-+++ b/arch/mips/include/asm/vpe.h
-@@ -124,4 +124,13 @@ void cleanup_tc(struct tc *tc);
-
- int __init vpe_module_init(void);
- void __exit vpe_module_exit(void);
-+
-+/* For the explanation of the APIs please refer the section "MT APRP Kernel
-+ * Programming" in AR9 SW Architecture Specification
-+ */
-+int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags);
-+int32_t vpe1_sw_stop(uint32_t flags);
-+uint32_t vpe1_get_load_addr(uint32_t flags);
-+uint32_t vpe1_get_max_mem(uint32_t flags);
-+
- #endif /* _ASM_VPE_H */
---- a/arch/mips/kernel/vpe-mt.c
-+++ b/arch/mips/kernel/vpe-mt.c
-@@ -416,6 +416,8 @@ int __init vpe_module_init(void)
- }
-
- v->ntcs = hw_tcs - aprp_cpu_index();
-+ write_tc_c0_tcbind((read_tc_c0_tcbind() &
-+ ~TCBIND_CURVPE) | 1);
-
- /* add the tc to the list of this vpe's tc's. */
- list_add(&t->tc, &v->tc);
-@@ -519,3 +521,47 @@ void __exit vpe_module_exit(void)
- release_vpe(v);
- }
- }
-+
-+#ifdef CONFIG_IFX_VPE_EXT
-+int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags)
-+{
-+ enum vpe_state state;
-+ struct vpe *v = get_vpe(tclimit);
-+ struct vpe_notifications *not;
-+
-+ if (tcmask || flags) {
-+ pr_warn("Currently tcmask and flags should be 0. Other values are not supported\n");
-+ return -1;
-+ }
-+
-+ state = xchg(&v->state, VPE_STATE_INUSE);
-+ if (state != VPE_STATE_UNUSED) {
-+ vpe_stop(v);
-+
-+ list_for_each_entry(not, &v->notify, list) {
-+ not->stop(tclimit);
-+ }
-+ }
-+
-+ v->__start = (unsigned long)sw_start_addr;
-+
-+ if (!vpe_run(v)) {
-+ pr_debug("VPE loader: VPE1 running successfully\n");
-+ return 0;
-+ }
-+ return -1;
-+}
-+EXPORT_SYMBOL(vpe1_sw_start);
-+
-+int32_t vpe1_sw_stop(uint32_t flags)
-+{
-+ struct vpe *v = get_vpe(tclimit);
-+
-+ if (!vpe_free(v)) {
-+ pr_debug("RP Stopped\n");
-+ return 0;
-+ } else
-+ return -1;
-+}
-+EXPORT_SYMBOL(vpe1_sw_stop);
-+#endif
---- a/arch/mips/kernel/vpe.c
-+++ b/arch/mips/kernel/vpe.c
-@@ -49,6 +49,41 @@ struct vpe_control vpecontrol = {
- .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
- };
-
-+#ifdef CONFIG_IFX_VPE_EXT
-+unsigned int vpe1_load_addr;
-+
-+static int __init load_address(char *str)
-+{
-+ get_option(&str, &vpe1_load_addr);
-+ return 1;
-+}
-+__setup("vpe1_load_addr=", load_address);
-+
-+static unsigned int vpe1_mem;
-+static int __init vpe1mem(char *str)
-+{
-+ vpe1_mem = memparse(str, &str);
-+ return 1;
-+}
-+__setup("vpe1_mem=", vpe1mem);
-+
-+uint32_t vpe1_get_load_addr(uint32_t flags)
-+{
-+ return vpe1_load_addr;
-+}
-+EXPORT_SYMBOL(vpe1_get_load_addr);
-+
-+uint32_t vpe1_get_max_mem(uint32_t flags)
-+{
-+ if (!vpe1_mem)
-+ return P_SIZE;
-+ else
-+ return vpe1_mem;
-+}
-+EXPORT_SYMBOL(vpe1_get_max_mem);
-+
-+#endif
-+
- /* get the vpe associated with this minor */
- struct vpe *get_vpe(int minor)
- {
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -42,10 +42,14 @@ extern const struct plat_smp_ops vsmp_sm
- static struct plat_smp_ops lantiq_smp_ops;
- #endif
-
-+/* for Multithreading (APRP), vpe.c will use it */
-+unsigned long cp0_memsize;
-+
- const char *get_system_type(void)
- {
- return soc_info.sys_type;
- }
-+EXPORT_SYMBOL(ltq_soc_type);
-
- int ltq_soc_type(void)
- {
diff --git a/target/linux/lantiq/patches-6.1/0154-lantiq-pci-bar11mask-fix.patch b/target/linux/lantiq/patches-6.1/0154-lantiq-pci-bar11mask-fix.patch
deleted file mode 100644
index 9214f786d7..0000000000
--- a/target/linux/lantiq/patches-6.1/0154-lantiq-pci-bar11mask-fix.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3c92a781de062064e36b867c0ab22f9aba48f3d3 Mon Sep 17 00:00:00 2001
-From: Eddi De Pieri <eddi@depieri.net>
-Date: Tue, 8 Nov 2016 17:38:00 +0100
-Subject: [PATCH] lantiq: pci: bar11mask fix
-
-Signed-off-by: Eddi De Pieri <eddi@depieri.net>
----
- arch/mips/pci/pci-lantiq.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/arch/mips/pci/pci-lantiq.c
-+++ b/arch/mips/pci/pci-lantiq.c
-@@ -59,6 +59,8 @@
- #define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y))
- #define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x))
-
-+extern u32 max_low_pfn;
-+
- __iomem void *ltq_pci_mapped_cfg;
- static __iomem void *ltq_pci_membase;
-
-@@ -84,8 +86,8 @@ static inline u32 ltq_calc_bar11mask(voi
- u32 mem, bar11mask;
-
- /* BAR11MASK value depends on available memory on system. */
-- mem = get_num_physpages() * PAGE_SIZE;
-- bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
-+ mem = max_low_pfn << PAGE_SHIFT;
-+ bar11mask = ((-roundup_pow_of_two(mem)) & 0x0F000000) | 8;
-
- return bar11mask;
- }
diff --git a/target/linux/lantiq/patches-6.1/0155-lantiq-VPE-nosmp.patch b/target/linux/lantiq/patches-6.1/0155-lantiq-VPE-nosmp.patch
deleted file mode 100644
index 015acabcfe..0000000000
--- a/target/linux/lantiq/patches-6.1/0155-lantiq-VPE-nosmp.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 07ce9e9bc4dcd5ac4728e587901112eef95bbe7b Mon Sep 17 00:00:00 2001
-From: Stefan Koch <stefan.koch10@gmail.com>
-Date: Mon, 13 Mar 2017 23:42:00 +0100
-Subject: [PATCH] lantiq: vpe nosmp
-
-Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
----
- arch/mips/kernel/vpe-mt.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/arch/mips/kernel/vpe-mt.c
-+++ b/arch/mips/kernel/vpe-mt.c
-@@ -131,7 +131,10 @@ int vpe_run(struct vpe *v)
- * kernels need to turn it on, even if that wasn't the pre-dvpe() state.
- */
- #ifdef CONFIG_SMP
-- evpe(vpeflags);
-+ if (!setup_max_cpus) /* nosmp is set */
-+ evpe(EVPE_ENABLE);
-+ else
-+ evpe(vpeflags);
- #else
- evpe(EVPE_ENABLE);
- #endif
diff --git a/target/linux/lantiq/patches-6.1/0160-owrt-lantiq-multiple-flash.patch b/target/linux/lantiq/patches-6.1/0160-owrt-lantiq-multiple-flash.patch
deleted file mode 100644
index a83325c094..0000000000
--- a/target/linux/lantiq/patches-6.1/0160-owrt-lantiq-multiple-flash.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-From ebaae1cd68cd79c7eee67c9c5c0fa45809e84525 Mon Sep 17 00:00:00 2001
-From: Maikel Bloemendal <openwrt@maikelenyvonne.nl>
-Date: Fri, 14 Nov 2014 17:06:00 +0000
-Subject: [PATCH] owrt: lantiq: multiple flash
-
-Signed-off-by: Maikel Bloemendal <openwrt@maikelenyvonne.nl>
----
- drivers/mtd/maps/lantiq-flash.c | 168 +++++++++++++++++++++-----------
- 1 file changed, 109 insertions(+), 59 deletions(-)
-
---- a/drivers/mtd/maps/lantiq-flash.c
-+++ b/drivers/mtd/maps/lantiq-flash.c
-@@ -17,6 +17,7 @@
- #include <linux/mtd/cfi.h>
- #include <linux/platform_device.h>
- #include <linux/mtd/physmap.h>
-+#include <linux/mtd/concat.h>
- #include <linux/of.h>
-
- #include <lantiq_soc.h>
-@@ -36,13 +37,16 @@ enum {
- LTQ_NOR_NORMAL
- };
-
-+#define MAX_RESOURCES 4
-+
- struct ltq_mtd {
-- struct resource *res;
-- struct mtd_info *mtd;
-- struct map_info *map;
-+ struct mtd_info *mtd[MAX_RESOURCES];
-+ struct mtd_info *cmtd;
-+ struct map_info map[MAX_RESOURCES];
- };
-
- static const char ltq_map_name[] = "ltq_nor";
-+static const char * const ltq_probe_types[] = { "cmdlinepart", "ofpart", NULL };
-
- static map_word
- ltq_read16(struct map_info *map, unsigned long adr)
-@@ -106,11 +110,43 @@ ltq_copy_to(struct map_info *map, unsign
- }
-
- static int
-+ltq_mtd_remove(struct platform_device *pdev)
-+{
-+ struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
-+ int i;
-+
-+ if (ltq_mtd == NULL)
-+ return 0;
-+
-+ if (ltq_mtd->cmtd) {
-+ mtd_device_unregister(ltq_mtd->cmtd);
-+ if (ltq_mtd->cmtd != ltq_mtd->mtd[0])
-+ mtd_concat_destroy(ltq_mtd->cmtd);
-+ }
-+
-+ for (i = 0; i < MAX_RESOURCES; i++) {
-+ if (ltq_mtd->mtd[i] != NULL)
-+ map_destroy(ltq_mtd->mtd[i]);
-+ }
-+
-+ kfree(ltq_mtd);
-+
-+ return 0;
-+}
-+
-+static int
- ltq_mtd_probe(struct platform_device *pdev)
- {
- struct ltq_mtd *ltq_mtd;
- struct cfi_private *cfi;
-- int err;
-+ int err = 0;
-+ int i;
-+ int devices_found = 0;
-+
-+ static const char *rom_probe_types[] = {
-+ "cfi_probe", "jedec_probe", NULL
-+ };
-+ const char **type;
-
- ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL);
- if (!ltq_mtd)
-@@ -118,75 +154,89 @@ ltq_mtd_probe(struct platform_device *pd
-
- platform_set_drvdata(pdev, ltq_mtd);
-
-- ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!ltq_mtd->res) {
-- dev_err(&pdev->dev, "failed to get memory resource\n");
-- return -ENOENT;
-+ for (i = 0; i < pdev->num_resources; i++) {
-+ printk(KERN_NOTICE "lantiq nor flash device: %.8llx at %.8llx\n",
-+ (unsigned long long)resource_size(&pdev->resource[i]),
-+ (unsigned long long)pdev->resource[i].start);
-+
-+ if (!devm_request_mem_region(&pdev->dev,
-+ pdev->resource[i].start,
-+ resource_size(&pdev->resource[i]),
-+ dev_name(&pdev->dev))) {
-+ dev_err(&pdev->dev, "Could not reserve memory region\n");
-+ return -ENOMEM;
-+ }
-+
-+ ltq_mtd->map[i].name = ltq_map_name;
-+ ltq_mtd->map[i].bankwidth = 2;
-+ ltq_mtd->map[i].read = ltq_read16;
-+ ltq_mtd->map[i].write = ltq_write16;
-+ ltq_mtd->map[i].copy_from = ltq_copy_from;
-+ ltq_mtd->map[i].copy_to = ltq_copy_to;
-+
-+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-+ ltq_mtd->map[i].phys = NO_XIP;
-+ else
-+ ltq_mtd->map[i].phys = pdev->resource[i].start;
-+ ltq_mtd->map[i].size = resource_size(&pdev->resource[i]);
-+ ltq_mtd->map[i].virt = devm_ioremap(&pdev->dev, pdev->resource[i].start,
-+ ltq_mtd->map[i].size);
-+ if (IS_ERR(ltq_mtd->map[i].virt))
-+ return PTR_ERR(ltq_mtd->map[i].virt);
-+
-+ if (ltq_mtd->map[i].virt == NULL) {
-+ dev_err(&pdev->dev, "Failed to ioremap flash region\n");
-+ err = PTR_ERR(ltq_mtd->map[i].virt);
-+ goto err_out;
-+ }
-+
-+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_PROBING;
-+ for (type = rom_probe_types; !ltq_mtd->mtd[i] && *type; type++)
-+ ltq_mtd->mtd[i] = do_map_probe(*type, &ltq_mtd->map[i]);
-+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_NORMAL;
-+
-+ if (!ltq_mtd->mtd[i]) {
-+ dev_err(&pdev->dev, "probing failed\n");
-+ return -ENXIO;
-+ } else {
-+ devices_found++;
-+ }
-+
-+ ltq_mtd->mtd[i]->owner = THIS_MODULE;
-+ ltq_mtd->mtd[i]->dev.parent = &pdev->dev;
-+
-+ cfi = ltq_mtd->map[i].fldrv_priv;
-+ cfi->addr_unlock1 ^= 1;
-+ cfi->addr_unlock2 ^= 1;
- }
-
-- ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
-- GFP_KERNEL);
-- if (!ltq_mtd->map)
-- return -ENOMEM;
--
-- if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-- ltq_mtd->map->phys = NO_XIP;
-- else
-- ltq_mtd->map->phys = ltq_mtd->res->start;
-- ltq_mtd->res->start;
-- ltq_mtd->map->size = resource_size(ltq_mtd->res);
-- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
-- if (IS_ERR(ltq_mtd->map->virt))
-- return PTR_ERR(ltq_mtd->map->virt);
--
-- ltq_mtd->map->name = ltq_map_name;
-- ltq_mtd->map->bankwidth = 2;
-- ltq_mtd->map->read = ltq_read16;
-- ltq_mtd->map->write = ltq_write16;
-- ltq_mtd->map->copy_from = ltq_copy_from;
-- ltq_mtd->map->copy_to = ltq_copy_to;
--
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
-- ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
--
-- if (!ltq_mtd->mtd) {
-- dev_err(&pdev->dev, "probing failed\n");
-- return -ENXIO;
-+ if (devices_found == 1) {
-+ ltq_mtd->cmtd = ltq_mtd->mtd[0];
-+ } else if (devices_found > 1) {
-+ /*
-+ * We detected multiple devices. Concatenate them together.
-+ */
-+ ltq_mtd->cmtd = mtd_concat_create(ltq_mtd->mtd, devices_found, dev_name(&pdev->dev));
-+ if (ltq_mtd->cmtd == NULL)
-+ err = -ENXIO;
- }
-
-- ltq_mtd->mtd->dev.parent = &pdev->dev;
-- mtd_set_of_node(ltq_mtd->mtd, pdev->dev.of_node);
--
-- cfi = ltq_mtd->map->fldrv_priv;
-- cfi->addr_unlock1 ^= 1;
-- cfi->addr_unlock2 ^= 1;
-+ ltq_mtd->cmtd->dev.parent = &pdev->dev;
-+ mtd_set_of_node(ltq_mtd->cmtd, pdev->dev.of_node);
-
-- err = mtd_device_register(ltq_mtd->mtd, NULL, 0);
-+ err = mtd_device_register(ltq_mtd->cmtd, NULL, 0);
- if (err) {
- dev_err(&pdev->dev, "failed to add partitions\n");
-- goto err_destroy;
-+ goto err_out;
- }
-
- return 0;
-
--err_destroy:
-- map_destroy(ltq_mtd->mtd);
-+err_out:
-+ ltq_mtd_remove(pdev);
- return err;
- }
-
--static int
--ltq_mtd_remove(struct platform_device *pdev)
--{
-- struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
--
-- if (ltq_mtd && ltq_mtd->mtd) {
-- mtd_device_unregister(ltq_mtd->mtd);
-- map_destroy(ltq_mtd->mtd);
-- }
-- return 0;
--}
--
- static const struct of_device_id ltq_mtd_match[] = {
- { .compatible = "lantiq,nor" },
- {},
diff --git a/target/linux/lantiq/patches-6.1/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch b/target/linux/lantiq/patches-6.1/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch
deleted file mode 100644
index f057ba324e..0000000000
--- a/target/linux/lantiq/patches-6.1/0200-MIPS-lantiq-xway-vmmc-use-platform_get_irq-to-get-ir.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 2b873c59fd313aee57864f96d64a228f2ea7c208 Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Mon, 13 May 2024 10:42:24 +0200
-Subject: [PATCH] MIPS: lantiq: xway: vmmc: use platform_get_irq to get irqs
- from dts
-
-Let's fetch the irqs from the dts here and expose them to the voice
-driver like it is done for the cp1 base memory.
-
-ToDo:
-Maybe it is possible to drop this driver completely and merge this
-handling to the voice driver.
-
-Signed-off-by: Martin Schiller <ms@dev.tdt.de>
----
- arch/mips/lantiq/xway/vmmc.c | 53 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 53 insertions(+)
-
---- a/arch/mips/lantiq/xway/vmmc.c
-+++ b/arch/mips/lantiq/xway/vmmc.c
-@@ -14,6 +14,10 @@
-
- static unsigned int *cp1_base;
-
-+static int ad0_irq;
-+static int ad1_irq;
-+static int vc_irq[4];
-+
- unsigned int *ltq_get_cp1_base(void)
- {
- if (!cp1_base)
-@@ -23,6 +27,33 @@ unsigned int *ltq_get_cp1_base(void)
- }
- EXPORT_SYMBOL(ltq_get_cp1_base);
-
-+unsigned int ltq_get_mps_ad0_irq(void)
-+{
-+ if (!ad0_irq)
-+ panic("no ad0 irq was set\n");
-+
-+ return ad0_irq;
-+}
-+EXPORT_SYMBOL(ltq_get_mps_ad0_irq);
-+
-+unsigned int ltq_get_mps_ad1_irq(void)
-+{
-+ if (!ad1_irq)
-+ panic("no ad1 irq was set\n");
-+
-+ return ad1_irq;
-+}
-+EXPORT_SYMBOL(ltq_get_mps_ad1_irq);
-+
-+unsigned int ltq_get_mps_vc_irq(int idx)
-+{
-+ if (!vc_irq[idx])
-+ panic("no vc%d irq was set\n", idx);
-+
-+ return vc_irq[idx];
-+}
-+EXPORT_SYMBOL(ltq_get_mps_vc_irq);
-+
- static int vmmc_probe(struct platform_device *pdev)
- {
- #define CP1_SIZE (1 << 20)
-@@ -30,11 +61,33 @@ static int vmmc_probe(struct platform_de
- int gpio_count;
- dma_addr_t dma;
- int error;
-+ int i;
-
- cp1_base =
- (void *) CPHYSADDR(dma_alloc_coherent(&pdev->dev, CP1_SIZE,
- &dma, GFP_KERNEL));
-
-+ ad0_irq = platform_get_irq(pdev, 4);
-+ if (ad0_irq < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS AD0 irq: %d\n", ad0_irq);
-+ return ad0_irq;
-+ }
-+
-+ ad1_irq = platform_get_irq(pdev, 5);
-+ if (ad1_irq < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS AD1 irq: %d\n", ad1_irq);
-+ return ad1_irq;
-+ }
-+
-+ for (i = 0; i < 4; i++) {
-+ vc_irq[i] = platform_get_irq(pdev, i);
-+ if (vc_irq[i] < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS VC%d irq: %d\n",
-+ i, vc_irq[i]);
-+ return vc_irq[i];
-+ }
-+ }
-+
- gpio_count = gpiod_count(&pdev->dev, NULL);
- while (gpio_count > 0) {
- gpio = devm_gpiod_get_index(&pdev->dev,
diff --git a/target/linux/lantiq/patches-6.1/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch b/target/linux/lantiq/patches-6.1/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch
deleted file mode 100644
index f62d167078..0000000000
--- a/target/linux/lantiq/patches-6.1/0300-MTD-cfi-cmdset-0001-disable-buffered-writes.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 5e93c85ac3e5626d1aa7e7f9c0a008b2a4224f04 Mon Sep 17 00:00:00 2001
-From: Matti Laakso <malaakso@elisanet.fi>
-Date: Sat, 14 Feb 2015 20:48:00 +0000
-Subject: [PATCH] MTD: cfi_cmdset_0001: disable buffered writes
-
-Signed-off-by: Matti Laakso <malaakso@elisanet.fi>
----
- drivers/mtd/chips/cfi_cmdset_0001.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/chips/cfi_cmdset_0001.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
-@@ -39,7 +39,7 @@
- /* #define CMDSET0001_DISABLE_WRITE_SUSPEND */
-
- // debugging, turns off buffer write mode if set to 1
--#define FORCE_WORD_WRITE 0
-+#define FORCE_WORD_WRITE 1
-
- /* Intel chips */
- #define I82802AB 0x00ad
diff --git a/target/linux/lantiq/patches-6.1/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch b/target/linux/lantiq/patches-6.1/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch
deleted file mode 100644
index e46790b2c3..0000000000
--- a/target/linux/lantiq/patches-6.1/0301-xrx200-add-gphy-clk-src-device-tree-binding.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 5502ef9d40ab20b2ac683660d1565a7c4968bcc8 Mon Sep 17 00:00:00 2001
-From: Mathias Kresin <openwrt@kresin.me>
-Date: Mon, 2 May 2016 18:50:00 +0000
-Subject: [PATCH] xrx200: add gphy clk src device tree binding
-
-Signed-off-by: Mathias Kresin <openwrt@kresin.me>
----
- arch/mips/lantiq/xway/sysctrl.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/arch/mips/lantiq/xway/sysctrl.c
-+++ b/arch/mips/lantiq/xway/sysctrl.c
-@@ -440,6 +440,20 @@ static void clkdev_add_clkout(void)
- }
- }
-
-+static void set_phy_clock_source(struct device_node *np_cgu)
-+{
-+ u32 phy_clk_src, ifcc;
-+
-+ if (!np_cgu)
-+ return;
-+
-+ if (of_property_read_u32(np_cgu, "lantiq,phy-clk-src", &phy_clk_src))
-+ return;
-+
-+ ifcc = ltq_cgu_r32(ifccr) & ~(0x1c);
-+ ltq_cgu_w32(ifcc | (phy_clk_src << 2), ifccr);
-+}
-+
- /* bring up all register ranges that we need for basic system control */
- void __init ltq_soc_init(void)
- {
-@@ -609,4 +623,6 @@ void __init ltq_soc_init(void)
- clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
- }
- usb_set_clock();
-+
-+ set_phy_clock_source(np_cgu);
- }
diff --git a/target/linux/lantiq/patches-6.1/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch b/target/linux/lantiq/patches-6.1/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch
deleted file mode 100644
index c43d9d4b35..0000000000
--- a/target/linux/lantiq/patches-6.1/0302-mtd-cfi_cmdset_0001-Disable-write-buffer-functions-i.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 118fe2c88b35482711adeee0d8758bddfe958701 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Sat, 6 May 2023 14:32:00 +0200
-Subject: [PATCH] mtd: cfi_cmdset_0001: Disable write buffer functions if
- FORCE_WORD_WRITE is 1
-
-Some write buffer functions are not used when FORCE_WORD_WRITE is set to 1.
-So the compile warning messages are output if FORCE_WORD_WRITE is 1. To
-resolve this disable the write buffer functions if FORCE_WORD_WRITE is 1.
-
-This is similar fix to: 557c759036fc3976a5358cef23e65a263853b93f.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
----
- drivers/mtd/chips/cfi_cmdset_0001.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/mtd/chips/cfi_cmdset_0001.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
-@@ -61,8 +61,10 @@
-
- static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-+#if !FORCE_WORD_WRITE
- static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
- static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
-+#endif
- static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
- static void cfi_intelext_sync (struct mtd_info *);
- static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
-@@ -304,6 +306,7 @@ static void fixup_use_point(struct mtd_i
- }
- }
-
-+#if !FORCE_WORD_WRITE
- static void fixup_use_write_buffers(struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -314,6 +317,7 @@ static void fixup_use_write_buffers(stru
- mtd->_writev = cfi_intelext_writev;
- }
- }
-+#endif /* !FORCE_WORD_WRITE */
-
- /*
- * Some chips power-up with all sectors locked by default.
-@@ -1719,6 +1723,7 @@ static int cfi_intelext_write_words (str
- }
-
-
-+#if !FORCE_WORD_WRITE
- static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
- unsigned long adr, const struct kvec **pvec,
- unsigned long *pvec_seek, int len)
-@@ -1947,6 +1952,7 @@ static int cfi_intelext_write_buffers (s
-
- return cfi_intelext_writev(mtd, &vec, 1, to, retlen);
- }
-+#endif /* !FORCE_WORD_WRITE */
-
- static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
- unsigned long adr, int len, void *thunk)
diff --git a/target/linux/lantiq/patches-6.1/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch b/target/linux/lantiq/patches-6.1/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch
deleted file mode 100644
index edf0626860..0000000000
--- a/target/linux/lantiq/patches-6.1/0400-mtd-rawnand-xway-don-t-yield-while-holding-spinlock.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 416f25a948d11ef15733f2e31658d31b5cc7bef6 Mon Sep 17 00:00:00 2001
-From: Thomas Nixon <tom@tomn.co.uk>
-Date: Sun, 26 Mar 2023 11:08:49 +0100
-Subject: [PATCH] mtd: rawnand: xway: don't yield while holding spinlock
-
-The nand driver normally while waiting for the device to become ready;
-this is normally fine, but xway_nand holds the ebu_lock spinlock, and
-this can cause lockups if other threads which use ebu_lock are
-interleaved. Fix this by waiting instead of polling.
-
-This mainly showed up as crashes in ath9k_pci_owl_loader (see
-https://github.com/openwrt/openwrt/issues/9829 ), but turning on
-spinlock debugging shows this happening in other places too.
-
-This doesn't seem to measurably impact boot time.
-
-Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
----
- drivers/mtd/nand/raw/xway_nand.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/raw/xway_nand.c
-+++ b/drivers/mtd/nand/raw/xway_nand.c
-@@ -175,7 +175,13 @@ static void xway_cmd_ctrl(struct nand_ch
-
- static int xway_dev_ready(struct nand_chip *chip)
- {
-- return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD;
-+ /*
-+ * wait until ready, as otherwise the driver will yield in nand_wait or
-+ * nand_wait_ready, which is a bad idea when we're holding ebu_lock
-+ */
-+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
-+ cpu_relax();
-+ return 1;
- }
-
- static unsigned char xway_read_byte(struct nand_chip *chip)
diff --git a/target/linux/lantiq/patches-6.1/0701-NET-lantiq-etop-of-mido.patch b/target/linux/lantiq/patches-6.1/0701-NET-lantiq-etop-of-mido.patch
deleted file mode 100644
index 19c027b9f8..0000000000
--- a/target/linux/lantiq/patches-6.1/0701-NET-lantiq-etop-of-mido.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 870ed9cae083ff8a60a739ef7e74c5a1800533be Mon Sep 17 00:00:00 2001
-From: Johann Neuhauser <johann@it-neuhauser.de>
-Date: Thu, 17 May 2018 19:12:35 +0200
-Subject: [PATCH] net: lantiq_etop: of mdio
-
-Signed-off-by: Johann Neuhauser <johann@it-neuhauser.de>
----
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -31,6 +31,7 @@
- #include <linux/of_net.h>
- #include <linux/of_irq.h>
- #include <linux/of_platform.h>
-+#include <linux/of_mdio.h>
-
- #include <asm/checksum.h>
-
-@@ -558,7 +559,8 @@ static int
- ltq_etop_mdio_init(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int err;
-+ struct device_node *mdio_np = NULL;
-+ int err, ret;
-
- priv->mii_bus = mdiobus_alloc();
- if (!priv->mii_bus) {
-@@ -578,7 +580,15 @@ ltq_etop_mdio_init(struct net_device *de
- priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- priv->pdev->name, priv->pdev->id);
-- if (mdiobus_register(priv->mii_bus)) {
-+
-+ mdio_np = of_get_child_by_name(priv->pdev->dev.of_node, "mdio-bus");
-+
-+ if (mdio_np)
-+ ret = of_mdiobus_register(priv->mii_bus, mdio_np);
-+ else
-+ ret = mdiobus_register(priv->mii_bus);
-+
-+ if (ret) {
- err = -ENXIO;
- goto err_out_free_mdiobus;
- }
diff --git a/target/linux/lantiq/patches-6.1/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch b/target/linux/lantiq/patches-6.1/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch
deleted file mode 100644
index c337c564b6..0000000000
--- a/target/linux/lantiq/patches-6.1/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 82ea7c7fb4e90620beba8b6436fc12df2379ef8d Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:52:25 +0200
-Subject: [PATCH 731/768] dt-bindings: net: dsa: lantiq_gswip: Add missing
- phy-mode and fixed-link
-
-The CPU port has to specify a phy-mode and either a phy or a fixed-link.
-Since GSWIP is connected using a SoC internal protocol there's no PHY
-involved. Add phy-mode = "internal" and a fixed-link to describe the
-communication between the PMAC (Ethernet controller) and GSWIP switch.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-@@ -96,7 +96,13 @@ switch@e108000 {
-
- port@6 {
- reg = <0x6>;
-+ phy-mode = "internal";
- ethernet = <&eth0>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
- };
-
diff --git a/target/linux/lantiq/patches-6.1/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch b/target/linux/lantiq/patches-6.1/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch
deleted file mode 100644
index 4800ee1dd2..0000000000
--- a/target/linux/lantiq/patches-6.1/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From a55b9d802e11baceb35bd312419ad82086065b08 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:59:35 +0200
-Subject: [PATCH 732/768] net: dsa: lantiq_gswip: Only allow phy-mode =
- "internal" on the CPU port
-
-Add the CPU port to gswip_xrx200_phylink_get_caps() and
-gswip_xrx300_phylink_get_caps(). It connects through a SoC-internal bus,
-so the only allowed phy-mode is PHY_INTERFACE_MODE_INTERNAL.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1509,6 +1509,7 @@ static void gswip_xrx200_phylink_get_cap
- case 2:
- case 3:
- case 4:
-+ case 6:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
- break;
-@@ -1540,6 +1541,7 @@ static void gswip_xrx300_phylink_get_cap
- case 2:
- case 3:
- case 4:
-+ case 6:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
- break;
diff --git a/target/linux/lantiq/patches-6.1/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch b/target/linux/lantiq/patches-6.1/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
deleted file mode 100644
index f30e7ab00c..0000000000
--- a/target/linux/lantiq/patches-6.1/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 4d3dd68a1c56674ff666d0622b545992fac31754 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Sun, 31 Jul 2022 22:54:52 +0200
-Subject: [PATCH 733/768] net: dsa: lantiq_gswip: Use dev_err_probe where
- appropriate
-
-dev_err_probe() can be used to simplify the existing code. Also it means
-we get rid of the following warning which is seen whenever the PMAC
-(Ethernet controller which connects to GSWIP's CPU port) has not been
-probed yet:
- gswip 1e108000.switch: dsa switch register failed: -517
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++------------------
- 1 file changed, 25 insertions(+), 28 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1919,11 +1919,9 @@ static int gswip_gphy_fw_load(struct gsw
- msleep(200);
-
- ret = request_firmware(&fw, gphy_fw->fw_name, dev);
-- if (ret) {
-- dev_err(dev, "failed to load firmware: %s, error: %i\n",
-- gphy_fw->fw_name, ret);
-- return ret;
-- }
-+ if (ret)
-+ return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
-+ gphy_fw->fw_name);
-
- /* GPHY cores need the firmware code in a persistent and contiguous
- * memory area with a 16 kB boundary aligned start address.
-@@ -1936,9 +1934,9 @@ static int gswip_gphy_fw_load(struct gsw
- dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
- memcpy(fw_addr, fw->data, fw->size);
- } else {
-- dev_err(dev, "failed to alloc firmware memory\n");
- release_firmware(fw);
-- return -ENOMEM;
-+ return dev_err_probe(dev, -ENOMEM,
-+ "failed to alloc firmware memory\n");
- }
-
- release_firmware(fw);
-@@ -1965,8 +1963,8 @@ static int gswip_gphy_fw_probe(struct gs
-
- gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
- if (IS_ERR(gphy_fw->clk_gate)) {
-- dev_err(dev, "Failed to lookup gate clock\n");
-- return PTR_ERR(gphy_fw->clk_gate);
-+ return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
-+ "Failed to lookup gate clock\n");
- }
-
- ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
-@@ -1986,8 +1984,8 @@ static int gswip_gphy_fw_probe(struct gs
- gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
- break;
- default:
-- dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
-- return -EINVAL;
-+ return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
-+ gphy_mode);
- }
-
- gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
-@@ -2038,8 +2036,9 @@ static int gswip_gphy_fw_list(struct gsw
- priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x",
-+ version);
- }
- }
-
-@@ -2047,10 +2046,9 @@ static int gswip_gphy_fw_list(struct gsw
- if (match && match->data)
- priv->gphy_fw_name_cfg = match->data;
-
-- if (!priv->gphy_fw_name_cfg) {
-- dev_err(dev, "GPHY compatible type not supported");
-- return -ENOENT;
-- }
-+ if (!priv->gphy_fw_name_cfg)
-+ return dev_err_probe(dev, -ENOENT,
-+ "GPHY compatible type not supported");
-
- priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
- if (!priv->num_gphy_fw)
-@@ -2150,8 +2148,8 @@ static int gswip_probe(struct platform_d
- return -EINVAL;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x", version);
- }
-
- /* bring up the mdio bus */
-@@ -2159,10 +2157,9 @@ static int gswip_probe(struct platform_d
- if (gphy_fw_np) {
- err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
- of_node_put(gphy_fw_np);
-- if (err) {
-- dev_err(dev, "gphy fw probe failed\n");
-- return err;
-- }
-+ if (err)
-+ return dev_err_probe(dev, err,
-+ "gphy fw probe failed\n");
- }
-
- /* bring up the mdio bus */
-@@ -2170,20 +2167,20 @@ static int gswip_probe(struct platform_d
- if (mdio_np) {
- err = gswip_mdio(priv, mdio_np);
- if (err) {
-- dev_err(dev, "mdio probe failed\n");
-+ dev_err_probe(dev, err, "mdio probe failed\n");
- goto put_mdio_node;
- }
- }
-
- err = dsa_register_switch(priv->ds);
- if (err) {
-- dev_err(dev, "dsa switch register failed: %i\n", err);
-+ dev_err_probe(dev, err, "dsa switch registration failed\n");
- goto mdio_bus;
- }
- if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
-- dev_err(dev, "wrong CPU port defined, HW only supports port: %i",
-- priv->hw_info->cpu_port);
-- err = -EINVAL;
-+ err = dev_err_probe(dev, -EINVAL,
-+ "wrong CPU port defined, HW only supports port: %i",
-+ priv->hw_info->cpu_port);
- goto disable_switch;
- }
-
diff --git a/target/linux/lantiq/patches-6.1/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch b/target/linux/lantiq/patches-6.1/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
deleted file mode 100644
index de8416380a..0000000000
--- a/target/linux/lantiq/patches-6.1/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 8cf0b680abc157adeec3fb93a10354c470694535 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Thu, 28 Jul 2022 22:37:11 +0200
-Subject: [PATCH 734/768] net: dsa: lantiq_gswip: Don't manually call
- gswip_port_enable()
-
-We don't need to manually call gswip_port_enable() from within
-gswip_setup() for the CPU port. DSA does this automatically for us.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -891,8 +891,6 @@ static int gswip_setup(struct dsa_switch
-
- ds->mtu_enforcement_ingress = true;
-
-- gswip_port_enable(ds, cpu_port, NULL);
--
- ds->configure_vlan_while_not_filtering = false;
-
- return 0;
diff --git a/target/linux/lantiq/patches-6.1/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch b/target/linux/lantiq/patches-6.1/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
deleted file mode 100644
index a653c85841..0000000000
--- a/target/linux/lantiq/patches-6.1/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 54a2f7f2c134738bd3f4ea0a213138d169f2726e Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Fri, 10 May 2024 13:52:10 +0200
-Subject: [PATCH] net: dsa: lantiq_gswip: do also enable or disable cpu port
-
-Before commit 74be4babe72f ("net: dsa: do not enable or disable non user
-ports"), gswip_port_enable/disable() were also executed for the cpu port
-in gswip_setup() which disabled the cpu port during initialization.
-
-Let's restore this by removing the dsa_is_user_port checks. Also, let's
-clean up the gswip_port_enable() function so that we only have to check
-for the cpu port once.
-
-Fixes: 74be4babe72f ("net: dsa: do not enable or disable non user ports")
-Signed-off-by: Martin Schiller <ms@dev.tdt.de>
----
- drivers/net/dsa/lantiq_gswip.c | 24 ++++++++----------------
- 1 file changed, 8 insertions(+), 16 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -688,13 +688,18 @@ static int gswip_port_enable(struct dsa_
- struct gswip_priv *priv = ds->priv;
- int err;
-
-- if (!dsa_is_user_port(ds, port))
-- return 0;
--
- if (!dsa_is_cpu_port(ds, port)) {
-+ u32 mdio_phy = 0;
-+
- err = gswip_add_single_port_br(priv, port, true);
- if (err)
- return err;
-+
-+ if (phydev)
-+ mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
-+
-+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-+ GSWIP_MDIO_PHYp(port));
- }
-
- /* RMON Counter Enable for port */
-@@ -707,16 +712,6 @@ static int gswip_port_enable(struct dsa_
- gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
- GSWIP_SDMA_PCTRLp(port));
-
-- if (!dsa_is_cpu_port(ds, port)) {
-- u32 mdio_phy = 0;
--
-- if (phydev)
-- mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
--
-- gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-- GSWIP_MDIO_PHYp(port));
-- }
--
- return 0;
- }
-
-@@ -724,9 +719,6 @@ static void gswip_port_disable(struct ds
- {
- 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,
diff --git a/target/linux/lantiq/patches-6.1/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch b/target/linux/lantiq/patches-6.1/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
deleted file mode 100644
index fd19982264..0000000000
--- a/target/linux/lantiq/patches-6.1/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8ab55ac9678ca1f50f786c84484599dd675c5a9f Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Wed, 18 May 2022 23:53:09 +0200
-Subject: [PATCH 736/768] net: dsa: lantiq_gswip: Use dsa_is_cpu_port() in
- gswip_port_change_mtu()
-
-Make the check for the CPU port in gswip_port_change_mtu() consistent
-with other areas of the driver by using dsa_is_cpu_port().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1457,12 +1457,11 @@ static int gswip_port_max_mtu(struct dsa
- static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct gswip_priv *priv = ds->priv;
-- int cpu_port = priv->hw_info->cpu_port;
-
- /* CPU port always has maximum mtu of user ports, so use it to set
- * switch frame size, including 8 byte special header.
- */
-- if (port == cpu_port) {
-+ if (dsa_is_cpu_port(ds, port)) {
- new_mtu += 8;
- gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
- GSWIP_MAC_FLEN);
diff --git a/target/linux/lantiq/patches-6.1/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch b/target/linux/lantiq/patches-6.1/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
deleted file mode 100644
index 74e52d1d18..0000000000
--- a/target/linux/lantiq/patches-6.1/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From ef98b183d8fc7187a2efcc21c8f54f3cf061d556 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Tue, 17 May 2022 22:39:58 +0200
-Subject: [PATCH 737/768] net: dsa: lantiq_gswip: Change literal 6 to ETH_ALEN
-
-The addr variable in gswip_port_fdb_dump() stores a mac address. Use
-ETH_ALEN to make this consistent across other drivers.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1406,7 +1406,7 @@ static int gswip_port_fdb_dump(struct ds
- {
- struct gswip_priv *priv = ds->priv;
- struct gswip_pce_table_entry mac_bridge = {0,};
-- unsigned char addr[6];
-+ unsigned char addr[ETH_ALEN];
- int i;
- int err;
-
diff --git a/target/linux/lantiq/patches-6.1/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch b/target/linux/lantiq/patches-6.1/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
deleted file mode 100644
index 0ea90db483..0000000000
--- a/target/linux/lantiq/patches-6.1/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 61e9b19f6e6174afa7540f0b468a69bc940b91d4 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 21:23:49 +0200
-Subject: [PATCH 738/768] net: dsa: lantiq_gswip: Consistently use macros for
- the mac bridge table
-
-Introduce a new GSWIP_TABLE_MAC_BRIDGE_PORT macro and use it throughout
-the driver. Also update GSWIP_TABLE_MAC_BRIDGE_STATIC to use the BIT()
-macro. This makes the driver code easier to understand.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -236,7 +236,8 @@
- #define GSWIP_TABLE_ACTIVE_VLAN 0x01
- #define GSWIP_TABLE_VLAN_MAPPING 0x02
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
--#define GSWIP_TABLE_MAC_BRIDGE_STATIC 0x01 /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1300,7 +1301,8 @@ static void gswip_port_fast_age(struct d
- if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC)
- continue;
-
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port)
-+ if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0]))
- continue;
-
- mac_bridge.valid = false;
-@@ -1438,7 +1440,8 @@ static int gswip_port_fdb_dump(struct ds
- return err;
- }
- } else {
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) {
-+ if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0])) {
- err = cb(addr, 0, false, data);
- if (err)
- return err;
diff --git a/target/linux/lantiq/patches-6.1/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch b/target/linux/lantiq/patches-6.1/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch
deleted file mode 100644
index 1347a98c5c..0000000000
--- a/target/linux/lantiq/patches-6.1/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 7a9e185075ababa827d1d3a33b787ad6d718c8ec Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:24:24 +0200
-Subject: [PATCH 739/768] net: dsa: lantiq_gswip: Forbid
- gswip_add_single_port_br on the CPU port
-
-Calling gswip_add_single_port_br() with the CPU port would be a bug
-because then only the CPU port could talk to itself. Add the CPU port to
-the validation at the beginning of gswip_add_single_port_br().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -650,7 +650,7 @@ static int gswip_add_single_port_br(stru
- unsigned int max_ports = priv->hw_info->max_ports;
- int err;
-
-- if (port >= max_ports) {
-+ if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
- dev_err(priv->dev, "single port for %i supported\n", port);
- return -EIO;
- }
diff --git a/target/linux/lantiq/patches-6.1/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch b/target/linux/lantiq/patches-6.1/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch
deleted file mode 100644
index 732588308e..0000000000
--- a/target/linux/lantiq/patches-6.1/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 28be6bfb735d851e646abb05b8e24eb6764596f5 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:26:20 +0200
-Subject: [PATCH 740/768] net: dsa: lantiq_gswip: Fix error message in
- gswip_add_single_port_br()
-
-The error message is printed when the port cannot be used. Update the
-error message to reflect that.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -651,7 +651,8 @@ static int gswip_add_single_port_br(stru
- int err;
-
- if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
-- dev_err(priv->dev, "single port for %i supported\n", port);
-+ dev_err(priv->dev, "single port for %i is not supported\n",
-+ port);
- return -EIO;
- }
-
diff --git a/target/linux/lantiq/patches-6.1/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch b/target/linux/lantiq/patches-6.1/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch
deleted file mode 100644
index 679dd53c47..0000000000
--- a/target/linux/lantiq/patches-6.1/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 45a0371568b1f050d787564875653f41a1f6fb98 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:06:40 +0200
-Subject: [PATCH 741/768] net: dsa: lantiq_gswip: Fix comments in
- gswip_port_vlan_filtering()
-
-Update the comments in gswip_port_vlan_filtering() so it's clear that
-there are two separate cases, one for "tag based VLAN" and another one
-for "port based VLAN".
-
-Suggested-by: Martin Schiller <ms@dev.tdt.de>
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -779,7 +779,7 @@ static int gswip_port_vlan_filtering(str
- }
-
- if (vlan_filtering) {
-- /* Use port based VLAN tag */
-+ /* Use tag based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_VSR,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
-@@ -788,7 +788,7 @@ static int gswip_port_vlan_filtering(str
- gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0,
- GSWIP_PCE_PCTRL_0p(port));
- } else {
-- /* Use port based VLAN tag */
-+ /* Use port based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
- GSWIP_PCE_VCTRL_VEMR,
diff --git a/target/linux/lantiq/patches-6.1/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch b/target/linux/lantiq/patches-6.1/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch
deleted file mode 100644
index 3d284c2ea6..0000000000
--- a/target/linux/lantiq/patches-6.1/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 4775f9543e691d9a2f5dd9aa5d46c66d37928250 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:19:05 +0200
-Subject: [PATCH 742/768] net: dsa: lantiq_gswip: Add and use a
- GSWIP_TABLE_MAC_BRIDGE_FID macro
-
-Only bits [5:0] in mac_bridge.key[3] are reserved for the FID. Add a
-macro so this becomes obvious when reading the driver code.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -238,6 +238,7 @@
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
- #define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
- #define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-+#define GSWIP_TABLE_MAC_BRIDGE_FID GENMASK(5, 0) /* Filtering identifier */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1378,7 +1379,7 @@ static int gswip_port_fdb(struct dsa_swi
- mac_bridge.key[0] = addr[5] | (addr[4] << 8);
- mac_bridge.key[1] = addr[3] | (addr[2] << 8);
- mac_bridge.key[2] = addr[1] | (addr[0] << 8);
-- mac_bridge.key[3] = fid;
-+ mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_FID, fid);
- mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */
- mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_STATIC;
- mac_bridge.valid = add;
diff --git a/target/linux/lantiq/patches-6.1/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch b/target/linux/lantiq/patches-6.1/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
deleted file mode 100644
index 5c756c5a19..0000000000
--- a/target/linux/lantiq/patches-6.1/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 00b5121435ccd4ce54f79179dd9ee3e2610d7dcf Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 16:31:57 +0200
-Subject: [PATCH 743/768] net: dsa: lantiq_gswip: Improve error message in
- gswip_port_fdb()
-
-Print the port which is not found to be part of a bridge so it's easier
-to investigate the underlying issue.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1370,7 +1370,8 @@ static int gswip_port_fdb(struct dsa_swi
- }
-
- if (fid == -1) {
-- dev_err(priv->dev, "Port not part of a bridge\n");
-+ dev_err(priv->dev,
-+ "Port %d is not known to be part of bridge\n", port);
- return -EINVAL;
- }
-
diff --git a/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch
index 3e23c0f23d..b796de9c11 100644
--- a/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch
+++ b/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch
@@ -5524,7 +5524,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
(transaction layer end-to-end CRC checking).
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
-@@ -1599,6 +1599,8 @@ void pci_walk_bus_locked(struct pci_bus
+@@ -1602,6 +1602,8 @@ void pci_walk_bus_locked(struct pci_bus
void *userdata);
int pci_cfg_space_size(struct pci_dev *dev);
unsigned char pci_bus_max_busnr(struct pci_bus *bus);
diff --git a/target/linux/lantiq/patches-6.6/0025-v6.12-net-ethernet-lantiq_etop-fix-memory-disclosure.patch b/target/linux/lantiq/patches-6.6/0025-v6.12-net-ethernet-lantiq_etop-fix-memory-disclosure.patch
new file mode 100644
index 0000000000..3b2ac25065
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0025-v6.12-net-ethernet-lantiq_etop-fix-memory-disclosure.patch
@@ -0,0 +1,42 @@
+From 45c0de18ff2dc9af01236380404bbd6a46502c69 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2@wp.pl>
+Date: Mon, 23 Sep 2024 23:49:49 +0200
+Subject: net: ethernet: lantiq_etop: fix memory disclosure
+
+When applying padding, the buffer is not zeroed, which results in memory
+disclosure. The mentioned data is observed on the wire. This patch uses
+skb_put_padto() to pad Ethernet frames properly. The mentioned function
+zeroes the expanded buffer.
+
+In case the packet cannot be padded it is silently dropped. Statistics
+are also not incremented. This driver does not support statistics in the
+old 32-bit format or the new 64-bit format. These will be added in the
+future. In its current form, the patch should be easily backported to
+stable versions.
+
+Ethernet MACs on Amazon-SE and Danube cannot do padding of the packets
+in hardware, so software padding must be applied.
+
+Fixes: 504d4721ee8e ("MIPS: Lantiq: Add ethernet driver")
+Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20240923214949.231511-2-olek2@wp.pl
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/lantiq_etop.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/lantiq_etop.c
++++ b/drivers/net/ethernet/lantiq_etop.c
+@@ -482,7 +482,9 @@ ltq_etop_tx(struct sk_buff *skb, struct
+ unsigned long flags;
+ u32 byte_offset;
+
+- len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
++ if (skb_put_padto(skb, ETH_ZLEN))
++ return NETDEV_TX_OK;
++ len = skb->len;
+
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+ netdev_err(dev, "tx ring full\n");
diff --git a/target/linux/lantiq/patches-6.6/0026-v6.12-net-ethernet-lantiq_etop-remove-unused-variable.patch b/target/linux/lantiq/patches-6.6/0026-v6.12-net-ethernet-lantiq_etop-remove-unused-variable.patch
new file mode 100644
index 0000000000..94f961d2c8
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0026-v6.12-net-ethernet-lantiq_etop-remove-unused-variable.patch
@@ -0,0 +1,24 @@
+From 1f803c95693f140bed46cd5581b97592e20b723e Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2@wp.pl>
+Date: Thu, 15 Aug 2024 09:49:56 +0200
+Subject: [PATCH] net: ethernet: lantiq_etop: remove unused variable
+
+Remove a variable that has never been used.
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
+Link: https://patch.msgid.link/20240815074956.155224-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/lantiq_etop.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/ethernet/lantiq_etop.c
++++ b/drivers/net/ethernet/lantiq_etop.c
+@@ -95,7 +95,6 @@ struct ltq_etop_priv {
+ struct mii_bus *mii_bus;
+
+ struct ltq_etop_chan ch[MAX_DMA_CHAN];
+- int tx_free[MAX_DMA_CHAN >> 1];
+
+ int tx_burst_len;
+ int rx_burst_len;
diff --git a/target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch b/target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch
new file mode 100644
index 0000000000..b2e06b8634
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch
@@ -0,0 +1,31 @@
+From 9283477e28913c1e7625c0a8d6959745e2431533 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2@wp.pl>
+Date: Sat, 13 Jul 2024 19:09:20 +0200
+Subject: [PATCH] net: ethernet: lantiq_etop: remove redundant device name
+ setup
+
+The same name is set when allocating the netdevice structure in the
+alloc_etherdev_mq()->alloc_etherrdev_mqs() function. Therefore, there
+is no need to manually set it.
+
+This fixes CheckPatch warnings:
+WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
+ strcpy(dev->name, "eth%d");
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
+Link: https://patch.msgid.link/20240713170920.863171-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/lantiq_etop.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/ethernet/lantiq_etop.c
++++ b/drivers/net/ethernet/lantiq_etop.c
+@@ -676,7 +676,6 @@ ltq_etop_probe(struct platform_device *p
+ err = -ENOMEM;
+ goto err_out;
+ }
+- strcpy(dev->name, "eth%d");
+ dev->netdev_ops = &ltq_eth_netdev_ops;
+ dev->ethtool_ops = &ltq_etop_ethtool_ops;
+ priv = netdev_priv(dev);
diff --git a/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch b/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch
index 8ac1097267..c761757c1c 100644
--- a/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch
+++ b/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch
@@ -5,8 +5,8 @@ Subject: [PATCH 28/36] NET: lantiq: various etop fixes
Signed-off-by: John Crispin <blogic@openwrt.org>
---
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
+ drivers/net/ethernet/lantiq_etop.c | 534 ++++++++++++++++++++---------
+ 1 file changed, 379 insertions(+), 155 deletions(-)
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -66,10 +66,10 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
-#define LTQ_ETOP_IGPLEN 0x16080
+
+#define MAC_CFG_MASK 0xfff
-+#define MAC_CFG_CGEN (1 << 11)
-+#define MAC_CFG_DUPLEX (1 << 2)
-+#define MAC_CFG_SPEED (1 << 1)
-+#define MAC_CFG_LINK (1 << 0)
++#define MAC_CFG_CGEN BIT(11)
++#define MAC_CFG_DUPLEX BIT(2)
++#define MAC_CFG_SPEED BIT(1)
++#define MAC_CFG_LINK BIT(0)
#define MAX_DMA_CHAN 0x8
#define MAX_DMA_CRC_LEN 0x4
@@ -89,11 +89,11 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
-#define IS_TX(x) ((x) == LTQ_ETOP_TX_CHANNEL)
-#define IS_RX(x) ((x) == LTQ_ETOP_RX_CHANNEL)
+#define ETOP_CFG_MASK 0xfff
-+#define ETOP_CFG_FEN0 (1 << 8)
-+#define ETOP_CFG_SEN0 (1 << 6)
-+#define ETOP_CFG_OFF1 (1 << 3)
-+#define ETOP_CFG_REMII0 (1 << 1)
-+#define ETOP_CFG_OFF0 (1 << 0)
++#define ETOP_CFG_FEN0 BIT(8)
++#define ETOP_CFG_SEN0 BIT(6)
++#define ETOP_CFG_OFF1 BIT(3)
++#define ETOP_CFG_REMII0 BIT(1)
++#define ETOP_CFG_OFF0 BIT(0)
+
+#define LTQ_GBIT_MDIO_CTL 0xCC
+#define LTQ_GBIT_MDIO_DATA 0xd0
@@ -103,8 +103,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
+#define LTQ_GBIT_RGMII_CTL 0x78
+
-+#define PMAC_HD_CTL_AS (1 << 19)
-+#define PMAC_HD_CTL_RXSH (1 << 22)
++#define PMAC_HD_CTL_AS BIT(19)
++#define PMAC_HD_CTL_RXSH BIT(22)
+
+/* Switch Enable (0=disable, 1=enable) */
+#define GCTL0_SE 0x80000000
@@ -153,7 +153,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
struct net_device *netdev;
struct napi_struct napi;
struct ltq_dma_channel dma;
-@@ -89,26 +141,39 @@ struct ltq_etop_chan {
+@@ -89,25 +141,39 @@ struct ltq_etop_chan {
struct ltq_etop_priv {
struct net_device *netdev;
struct platform_device *pdev;
@@ -163,21 +163,19 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
struct mii_bus *mii_bus;
- struct ltq_etop_chan ch[MAX_DMA_CHAN];
-- int tx_free[MAX_DMA_CHAN >> 1];
+ struct ltq_etop_chan txch;
+ struct ltq_etop_chan rxch;
int tx_burst_len;
int rx_burst_len;
-- spinlock_t lock;
+ int tx_irq;
+ int rx_irq;
+
+ unsigned char mac[6];
+ phy_interface_t mii_mode;
-+
-+ spinlock_t lock;
++
+ spinlock_t lock;
+
+ struct clk *clk_ppe;
+ struct clk *clk_switch;
@@ -186,7 +184,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
};
+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data);
++ int phy_reg, u16 phy_data);
+
static int
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
@@ -198,7 +196,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
if (!ch->skb[ch->dma.desc])
return -ENOMEM;
ch->dma.desc_base[ch->dma.desc].addr =
-@@ -143,8 +208,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan
+@@ -142,8 +208,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan
spin_unlock_irqrestore(&priv->lock, flags);
skb_put(skb, len);
@@ -210,7 +208,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
}
static int
-@@ -152,7 +220,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
+@@ -151,7 +220,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
{
struct ltq_etop_chan *ch = container_of(napi,
struct ltq_etop_chan, napi);
@@ -220,7 +218,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
while (work_done < budget) {
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-@@ -164,7 +234,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
+@@ -163,7 +234,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
}
if (work_done < budget) {
napi_complete_done(&ch->napi, work_done);
@@ -230,7 +228,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
}
return work_done;
}
-@@ -176,12 +248,14 @@ ltq_etop_poll_tx(struct napi_struct *nap
+@@ -175,12 +248,14 @@ ltq_etop_poll_tx(struct napi_struct *nap
container_of(napi, struct ltq_etop_chan, napi);
struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
struct netdev_queue *txq =
@@ -246,7 +244,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
dev_kfree_skb_any(ch->skb[ch->tx_free]);
ch->skb[ch->tx_free] = NULL;
memset(&ch->dma.desc_base[ch->tx_free], 0,
-@@ -194,7 +268,9 @@ ltq_etop_poll_tx(struct napi_struct *nap
+@@ -193,7 +268,9 @@ ltq_etop_poll_tx(struct napi_struct *nap
if (netif_tx_queue_stopped(txq))
netif_tx_start_queue(txq);
napi_complete(&ch->napi);
@@ -256,12 +254,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return 1;
}
-@@ -202,9 +278,10 @@ static irqreturn_t
+@@ -201,9 +278,11 @@ static irqreturn_t
ltq_etop_dma_irq(int irq, void *_priv)
{
struct ltq_etop_priv *priv = _priv;
- int ch = irq - LTQ_DMA_CH0_INT;
--
+
- napi_schedule(&priv->ch[ch].napi);
+ if (irq == priv->txch.dma.irq)
+ napi_schedule(&priv->txch.napi);
@@ -270,16 +268,16 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return IRQ_HANDLED;
}
-@@ -216,7 +293,7 @@ ltq_etop_free_channel(struct net_device
+@@ -215,7 +294,7 @@ ltq_etop_free_channel(struct net_device
ltq_dma_free(&ch->dma);
if (ch->dma.irq)
free_irq(ch->dma.irq, priv);
- if (IS_RX(ch->idx)) {
-+ if (ch == &priv->txch) {
- int desc;
++ if (ch == &priv->rxch) {
+ struct ltq_dma_channel *dma = &ch->dma;
- for (desc = 0; desc < LTQ_DESC_NUM; desc++)
-@@ -228,80 +305,135 @@ static void
+ for (dma->desc = 0; dma->desc < LTQ_DESC_NUM; dma->desc++)
+@@ -227,80 +306,137 @@ static void
ltq_etop_hw_exit(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -320,13 +318,14 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
+ /* disable pmac & dmac headers */
+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
-+ LTQ_GBIT_PMAC_HD_CTL);
++ LTQ_GBIT_PMAC_HD_CTL);
+ /* Due to traffic halt when burst length 8,
-+ replace default IPG value with 0x3B */
++ *replace default IPG value with 0x3B
++ */
+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
+ /* set mdc clock to 2.5 MHz */
+ ltq_gbit_w32_mask(MDC_CLOCK_MASK, 4 << MDC_CLOCK_OFFSET,
-+ LTQ_GBIT_RGMII_CTL);
++ LTQ_GBIT_RGMII_CTL);
}
static int
@@ -336,11 +335,10 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- int i;
- int err;
+ phy_interface_t mii_mode = priv->mii_mode;
-
-- ltq_pmu_enable(PMU_PPE);
++
+ clk_enable(priv->clk_ppe);
-- switch (priv->pldata->mii_mode) {
+- ltq_pmu_enable(PMU_PPE);
+ if (of_machine_is_compatible("lantiq,ar9")) {
+ ltq_etop_gbit_init(dev);
+ /* force the etops link to the gbit to MII */
@@ -349,7 +347,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ ltq_etop_w32_mask(MDIO_CFG_MASK, 0, LTQ_ETOP_MDIO_CFG);
+ ltq_etop_w32_mask(MAC_CFG_MASK, MAC_CFG_CGEN | MAC_CFG_DUPLEX |
+ MAC_CFG_SPEED | MAC_CFG_LINK, LTQ_ETOP_MAC_CFG);
-+
+
+- switch (priv->pldata->mii_mode) {
+ switch (mii_mode) {
case PHY_INTERFACE_MODE_RMII:
- ltq_etop_w32_mask(ETOP_MII_MASK, ETOP_MII_REVERSE,
@@ -373,7 +372,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ /* enable clock for internal PHY */
+ clk_enable(priv->clk_ephycgu);
+ /* we need to write this magic to the internal phy to
-+ make it work */
++ * make it work
++ */
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
+ pr_info("Selected EPHY mode\n");
+ break;
@@ -464,12 +464,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
}
static void
-@@ -320,6 +452,39 @@ static const struct ethtool_ops ltq_etop
+@@ -319,6 +455,39 @@ static const struct ethtool_ops ltq_etop
};
static int
+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data)
++ int phy_reg, u16 phy_data)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
+ (phy_data << MDIO_XR9_WR_OFFSET) |
@@ -504,7 +504,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
{
u32 val = MDIO_REQUEST |
-@@ -327,9 +492,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
+@@ -326,9 +495,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
phy_data;
@@ -516,7 +516,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return 0;
}
-@@ -340,12 +505,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
+@@ -339,12 +508,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
@@ -533,7 +533,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return val;
}
-@@ -361,7 +526,10 @@ ltq_etop_mdio_probe(struct net_device *d
+@@ -360,7 +529,10 @@ ltq_etop_mdio_probe(struct net_device *d
struct ltq_etop_priv *priv = netdev_priv(dev);
struct phy_device *phydev;
@@ -545,7 +545,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
if (!phydev) {
netdev_err(dev, "no PHY found\n");
-@@ -369,14 +537,17 @@ ltq_etop_mdio_probe(struct net_device *d
+@@ -368,14 +540,17 @@ ltq_etop_mdio_probe(struct net_device *d
}
phydev = phy_connect(dev, phydev_name(phydev),
@@ -565,7 +565,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
phy_attached_info(phydev);
-@@ -397,8 +568,13 @@ ltq_etop_mdio_init(struct net_device *de
+@@ -396,8 +571,13 @@ ltq_etop_mdio_init(struct net_device *de
}
priv->mii_bus->priv = dev;
@@ -581,7 +581,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
priv->mii_bus->name = "ltq_mii";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
priv->pdev->name, priv->pdev->id);
-@@ -435,18 +611,21 @@ static int
+@@ -434,18 +614,21 @@ static int
ltq_etop_open(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -613,7 +613,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_tx_start_all_queues(dev);
return 0;
}
-@@ -455,18 +634,19 @@ static int
+@@ -454,18 +637,19 @@ static int
ltq_etop_stop(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -643,7 +643,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return 0;
}
-@@ -476,15 +656,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
+@@ -475,17 +659,21 @@ ltq_etop_tx(struct sk_buff *skb, struct
int queue = skb_get_queue_mapping(skb);
struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -656,15 +656,21 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
u32 byte_offset;
+ int len;
- len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+- if (skb_put_padto(skb, ETH_ZLEN))
++ if (skb_put_padto(skb, ETH_ZLEN)) {
++ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
++ }
++
+ len = skb->len;
- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
-+ priv->txch.skb[priv->txch.dma.desc]) {
++ priv->txch.skb[priv->txch.dma.desc]) {
netdev_err(dev, "tx ring full\n");
netif_tx_stop_queue(txq);
return NETDEV_TX_BUSY;
-@@ -492,7 +673,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
+@@ -493,7 +681,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
/* dma needs to start on a burst length value aligned address */
byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4);
@@ -673,7 +679,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_trans_update(dev);
-@@ -503,11 +684,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
+@@ -504,11 +692,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
wmb();
desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
@@ -688,7 +694,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_tx_stop_queue(txq);
return NETDEV_TX_OK;
-@@ -518,11 +699,14 @@ ltq_etop_change_mtu(struct net_device *d
+@@ -519,11 +707,14 @@ ltq_etop_change_mtu(struct net_device *d
{
struct ltq_etop_priv *priv = netdev_priv(dev);
unsigned long flags;
@@ -704,7 +710,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
-@@ -575,6 +759,9 @@ ltq_etop_init(struct net_device *dev)
+@@ -576,6 +767,9 @@ ltq_etop_init(struct net_device *dev)
if (err)
goto err_hw;
ltq_etop_change_mtu(dev, 1500);
@@ -714,7 +720,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
if (!is_valid_ether_addr(mac.sa_data)) {
-@@ -592,9 +779,10 @@ ltq_etop_init(struct net_device *dev)
+@@ -593,9 +787,10 @@ ltq_etop_init(struct net_device *dev)
dev->addr_assign_type = NET_ADDR_RANDOM;
ltq_etop_set_multicast_list(dev);
@@ -724,11 +730,11 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ if (!ltq_etop_mdio_init(dev))
+ dev->ethtool_ops = &ltq_etop_ethtool_ops;
+ else
-+ pr_warn("etop: mdio probe failed\n");;
++ pr_warn("etop: mdio probe failed\n");
return 0;
err_netdev:
-@@ -614,6 +802,9 @@ ltq_etop_tx_timeout(struct net_device *d
+@@ -615,6 +810,9 @@ ltq_etop_tx_timeout(struct net_device *d
err = ltq_etop_hw_init(dev);
if (err)
goto err_hw;
@@ -738,7 +744,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_trans_update(dev);
netif_wake_queue(dev);
return;
-@@ -637,14 +828,18 @@ static const struct net_device_ops ltq_e
+@@ -638,14 +836,18 @@ static const struct net_device_ops ltq_e
.ndo_tx_timeout = ltq_etop_tx_timeout,
};
@@ -761,7 +767,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
-@@ -670,19 +865,55 @@ ltq_etop_probe(struct platform_device *p
+@@ -671,18 +873,54 @@ ltq_etop_probe(struct platform_device *p
goto err_out;
}
@@ -777,7 +783,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ goto err_out;
+ }
+ ltq_gbit_membase = devm_ioremap(&pdev->dev,
-+ gbit_res->start, resource_size(gbit_res));
++ gbit_res->start, resource_size(gbit_res));
+ if (!ltq_gbit_membase) {
+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
+ pdev->id);
@@ -787,7 +793,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
}
+
+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
- strcpy(dev->name, "eth%d");
dev->netdev_ops = &ltq_eth_netdev_ops;
- dev->ethtool_ops = &ltq_etop_ethtool_ops;
priv = netdev_priv(dev);
@@ -823,7 +828,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
spin_lock_init(&priv->lock);
SET_NETDEV_DEV(dev, &pdev->dev);
-@@ -698,15 +929,10 @@ ltq_etop_probe(struct platform_device *p
+@@ -698,15 +936,10 @@ ltq_etop_probe(struct platform_device *p
goto err_free;
}
@@ -843,7 +848,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
err = register_netdev(dev);
if (err)
-@@ -735,31 +961,22 @@ ltq_etop_remove(struct platform_device *
+@@ -735,31 +968,22 @@ ltq_etop_remove(struct platform_device *
return 0;
}
diff --git a/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch b/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
index b06c5ab47c..8bb6e5a0da 100644
--- a/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
+++ b/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
@@ -203,7 +203,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+early_param("ethaddr", setup_ethaddr);
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -763,7 +763,11 @@ ltq_etop_init(struct net_device *dev)
+@@ -771,7 +771,11 @@ ltq_etop_init(struct net_device *dev)
if (err)
goto err_hw;
diff --git a/target/linux/lantiq/patches-6.6/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch b/target/linux/lantiq/patches-6.6/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch
deleted file mode 100644
index 5099c0bb9e..0000000000
--- a/target/linux/lantiq/patches-6.6/0050-USB-DWC2-make-the-lantiq-settings-match-vendor-drive.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From de2cad82c4d0872066f83ce59462603852b47f03 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:55:24 +0100
-Subject: [PATCH 2/2] usb: dwc2: add support for other Lantiq SoCs
-
-The size of the internal RAM of the DesignWare USB controller changed
-between the different Lantiq SoCs. We have the following sizes:
-
-Amazon + Danube: 8 KByte
-Amazon SE + arx100: 2 KByte
-xrx200 + xrx300: 2.5 KByte
-
-For Danube SoC we do not provide the params and let the driver decide
-to use sane defaults, for the Amazon SE and arx100 we use small fifos
-and for the xrx200 and xrx300 SCs a little bit bigger periodic fifo.
-The auto detection of max_transfer_size and max_packet_count should
-work, so remove it.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/usb/dwc2/platform.c | 46 ++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 39 insertions(+), 7 deletions(-)
-
---- a/drivers/usb/dwc2/params.c
-+++ b/drivers/usb/dwc2/params.c
-@@ -132,7 +132,15 @@ static void dwc2_set_rk_params(struct dw
- p->hird_threshold_en = false;
- }
-
--static void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg)
-+static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_caps.hnp_support = false;
-+ p->otg_caps.srp_support = false;
-+}
-+
-+static void dwc2_set_ltq_ase_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-
-@@ -141,12 +149,21 @@ static void dwc2_set_ltq_params(struct d
- p->host_rx_fifo_size = 288;
- p->host_nperio_tx_fifo_size = 128;
- p->host_perio_tx_fifo_size = 96;
-- p->max_transfer_size = 65535;
-- p->max_packet_count = 511;
- p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
- GAHBCFG_HBSTLEN_SHIFT;
- }
-
-+static void dwc2_set_ltq_xrx200_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_caps.hnp_support = false;
-+ p->otg_caps.srp_support = false;
-+ p->host_rx_fifo_size = 288;
-+ p->host_nperio_tx_fifo_size = 128;
-+ p->host_perio_tx_fifo_size = 136;
-+}
-+
- static void dwc2_set_amlogic_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-@@ -277,8 +294,11 @@ const struct of_device_id dwc2_of_match_
- { .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 },
-- { .compatible = "lantiq,arx100-usb", .data = dwc2_set_ltq_params },
-- { .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params },
-+ { .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 },
-+ { .compatible = "lantiq,xrx200-usb", .data = &dwc2_set_ltq_xrx200_params },
-+ { .compatible = "lantiq,xrx300-usb", .data = &dwc2_set_ltq_xrx200_params },
- { .compatible = "snps,dwc2" },
- { .compatible = "samsung,s3c6400-hsotg",
- .data = dwc2_set_s3c6400_params },
diff --git a/target/linux/lantiq/patches-6.6/0050-v6.11-usb-dwc2-add-support-for-other-Lantiq-SoCs.patch b/target/linux/lantiq/patches-6.6/0050-v6.11-usb-dwc2-add-support-for-other-Lantiq-SoCs.patch
new file mode 100644
index 0000000000..cb453ff048
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0050-v6.11-usb-dwc2-add-support-for-other-Lantiq-SoCs.patch
@@ -0,0 +1,85 @@
+From 5af43708d21c30e2f418cb25d337779c56d235f6 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Tue, 9 Jul 2024 00:20:54 +0200
+Subject: [PATCH] usb: dwc2: add support for other Lantiq SoCs
+
+The size of the internal RAM of the DesignWare USB controller changed
+between the different Lantiq SoCs. We have the following sizes:
+
+Amazon + Danube: 8 KByte
+Amazon SE + arx100: 2 KByte
+xrx200 + xrx300: 2.5 KByte
+
+For Danube SoC we do not provide the params and let the driver decide
+to use sane defaults, for the Amazon SE and arx100 we use small fifos
+and for the xrx200 and xrx300 SCs a little bit bigger periodic fifo.
+The auto detection of max_transfer_size and max_packet_count should
+work, so remove it.
+
+This patch is included in OpenWrt for many years.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+Acked-by: Minas Harutyunyan <hminas@synopsys.com>
+Link: https://lore.kernel.org/r/20240708222054.2727789-1-hauke@hauke-m.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc2/params.c | 30 +++++++++++++++++++++++++-----
+ 1 file changed, 25 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/dwc2/params.c
++++ b/drivers/usb/dwc2/params.c
+@@ -132,7 +132,15 @@ static void dwc2_set_rk_params(struct dw
+ p->hird_threshold_en = false;
+ }
+
+-static void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg)
++static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg)
++{
++ struct dwc2_core_params *p = &hsotg->params;
++
++ p->otg_caps.hnp_support = false;
++ p->otg_caps.srp_support = false;
++}
++
++static void dwc2_set_ltq_ase_params(struct dwc2_hsotg *hsotg)
+ {
+ struct dwc2_core_params *p = &hsotg->params;
+
+@@ -141,12 +149,21 @@ static void dwc2_set_ltq_params(struct d
+ p->host_rx_fifo_size = 288;
+ p->host_nperio_tx_fifo_size = 128;
+ p->host_perio_tx_fifo_size = 96;
+- p->max_transfer_size = 65535;
+- p->max_packet_count = 511;
+ p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
+ GAHBCFG_HBSTLEN_SHIFT;
+ }
+
++static void dwc2_set_ltq_xrx200_params(struct dwc2_hsotg *hsotg)
++{
++ struct dwc2_core_params *p = &hsotg->params;
++
++ p->otg_caps.hnp_support = false;
++ p->otg_caps.srp_support = false;
++ p->host_rx_fifo_size = 288;
++ p->host_nperio_tx_fifo_size = 128;
++ p->host_perio_tx_fifo_size = 136;
++}
++
+ static void dwc2_set_amlogic_params(struct dwc2_hsotg *hsotg)
+ {
+ struct dwc2_core_params *p = &hsotg->params;
+@@ -277,8 +294,11 @@ const struct of_device_id dwc2_of_match_
+ { .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 },
+- { .compatible = "lantiq,arx100-usb", .data = dwc2_set_ltq_params },
+- { .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params },
++ { .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 },
++ { .compatible = "lantiq,xrx200-usb", .data = &dwc2_set_ltq_xrx200_params },
++ { .compatible = "lantiq,xrx300-usb", .data = &dwc2_set_ltq_xrx200_params },
+ { .compatible = "snps,dwc2" },
+ { .compatible = "samsung,s3c6400-hsotg",
+ .data = dwc2_set_s3c6400_params },
diff --git a/target/linux/lantiq/patches-6.6/0051-MIPS-lantiq-improve-USB-initialization.patch b/target/linux/lantiq/patches-6.6/0051-MIPS-lantiq-improve-USB-initialization.patch
deleted file mode 100644
index 29d696af27..0000000000
--- a/target/linux/lantiq/patches-6.6/0051-MIPS-lantiq-improve-USB-initialization.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 14909c4e4e836925668e74fc6e0e85ba0283cbf9 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:40:12 +0100
-Subject: [PATCH 2/2] MIPS: lantiq: improve USB initialization
-
-This adds code to initialize the USB controller and PHY also on Danube,
-Amazon SE and AR10. This code is based on the Vendor driver from
-different UGW versions and compared to the hardware documentation.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- arch/mips/lantiq/xway/sysctrl.c | 20 +++++++
- 2 files changed, 110 insertions(+), 30 deletions(-)
-
-
---- a/arch/mips/lantiq/xway/sysctrl.c
-+++ b/arch/mips/lantiq/xway/sysctrl.c
-@@ -247,6 +247,25 @@ static void pmu_disable(struct clk *clk)
- pr_warn("deactivating PMU module failed!");
- }
-
-+static void usb_set_clock(void)
-+{
-+ unsigned int val = ltq_cgu_r32(ifccr);
-+
-+ if (of_machine_is_compatible("lantiq,ar10") ||
-+ of_machine_is_compatible("lantiq,grx390")) {
-+ val &= ~0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ar9") ||
-+ of_machine_is_compatible("lantiq,vr9")) {
-+ /* TODO: this depends on the XTAL frequency */
-+ val |= 0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ase")) {
-+ val |= 0x20; /* from XTAL */
-+ } else if (of_machine_is_compatible("lantiq,danube")) {
-+ val |= 0x30; /* 12 MHz, generated from 36 MHz */
-+ }
-+ ltq_cgu_w32(val, ifccr);
-+}
-+
- /* the pci enable helper */
- static int pci_enable(struct clk *clk)
- {
-@@ -588,4 +607,5 @@ void __init ltq_soc_init(void)
- clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
- clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
- }
-+ usb_set_clock();
- }
diff --git a/target/linux/lantiq/patches-6.6/0051-v6.11-MIPS-lantiq-improve-USB-initialization.patch b/target/linux/lantiq/patches-6.6/0051-v6.11-MIPS-lantiq-improve-USB-initialization.patch
new file mode 100644
index 0000000000..558a7fbc25
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0051-v6.11-MIPS-lantiq-improve-USB-initialization.patch
@@ -0,0 +1,51 @@
+From 9c7a86c935074525f24cc20e78a7d5150e4600e3 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Tue, 9 Jul 2024 00:23:04 +0200
+Subject: [PATCH] MIPS: lantiq: improve USB initialization
+
+This adds code to initialize the USB controller and PHY also on Danube,
+Amazon SE and AR10. This code is based on the Vendor driver from
+different UGW versions and compared to the hardware documentation.
+
+This patch is included in OpenWrt for many years.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+---
+ arch/mips/lantiq/xway/sysctrl.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/arch/mips/lantiq/xway/sysctrl.c
++++ b/arch/mips/lantiq/xway/sysctrl.c
+@@ -247,6 +247,25 @@ static void pmu_disable(struct clk *clk)
+ pr_warn("deactivating PMU module failed!");
+ }
+
++static void usb_set_clock(void)
++{
++ unsigned int val = ltq_cgu_r32(ifccr);
++
++ if (of_machine_is_compatible("lantiq,ar10") ||
++ of_machine_is_compatible("lantiq,grx390")) {
++ val &= ~0x03; /* XTAL divided by 3 */
++ } else if (of_machine_is_compatible("lantiq,ar9") ||
++ of_machine_is_compatible("lantiq,vr9")) {
++ /* TODO: this depends on the XTAL frequency */
++ val |= 0x03; /* XTAL divided by 3 */
++ } else if (of_machine_is_compatible("lantiq,ase")) {
++ val |= 0x20; /* from XTAL */
++ } else if (of_machine_is_compatible("lantiq,danube")) {
++ val |= 0x30; /* 12 MHz, generated from 36 MHz */
++ }
++ ltq_cgu_w32(val, ifccr);
++}
++
+ /* the pci enable helper */
+ static int pci_enable(struct clk *clk)
+ {
+@@ -588,4 +607,5 @@ void __init ltq_soc_init(void)
+ clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+ clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
+ }
++ usb_set_clock();
+ }
diff --git a/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch b/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch
index 19c027b9f8..d80cdb0872 100644
--- a/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch
+++ b/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch
@@ -18,7 +18,7 @@ Signed-off-by: Johann Neuhauser <johann@it-neuhauser.de>
#include <asm/checksum.h>
-@@ -558,7 +559,8 @@ static int
+@@ -561,7 +562,8 @@ static int
ltq_etop_mdio_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -28,7 +28,7 @@ Signed-off-by: Johann Neuhauser <johann@it-neuhauser.de>
priv->mii_bus = mdiobus_alloc();
if (!priv->mii_bus) {
-@@ -578,7 +580,15 @@ ltq_etop_mdio_init(struct net_device *de
+@@ -581,7 +583,15 @@ ltq_etop_mdio_init(struct net_device *de
priv->mii_bus->name = "ltq_mii";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
priv->pdev->name, priv->pdev->id);
diff --git a/target/linux/lantiq/patches-6.6/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch b/target/linux/lantiq/patches-6.6/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch
deleted file mode 100644
index c337c564b6..0000000000
--- a/target/linux/lantiq/patches-6.6/0731-dt-bindings-net-dsa-lantiq_gswip-Add-missing-phy-mod.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 82ea7c7fb4e90620beba8b6436fc12df2379ef8d Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:52:25 +0200
-Subject: [PATCH 731/768] dt-bindings: net: dsa: lantiq_gswip: Add missing
- phy-mode and fixed-link
-
-The CPU port has to specify a phy-mode and either a phy or a fixed-link.
-Since GSWIP is connected using a SoC internal protocol there's no PHY
-involved. Add phy-mode = "internal" and a fixed-link to describe the
-communication between the PMAC (Ethernet controller) and GSWIP switch.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-@@ -96,7 +96,13 @@ switch@e108000 {
-
- port@6 {
- reg = <0x6>;
-+ phy-mode = "internal";
- ethernet = <&eth0>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
- };
-
diff --git a/target/linux/lantiq/patches-6.6/0731-v6.11-dt-bindings-net-dsa-lantiq-gswip-convert-to-YAML-schema.patch b/target/linux/lantiq/patches-6.6/0731-v6.11-dt-bindings-net-dsa-lantiq-gswip-convert-to-YAML-schema.patch
new file mode 100644
index 0000000000..40e52f2812
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0731-v6.11-dt-bindings-net-dsa-lantiq-gswip-convert-to-YAML-schema.patch
@@ -0,0 +1,392 @@
+From c7f75954212b5e64f6b1f2375215b02fd79758ce Mon Sep 17 00:00:00 2001
+From: Martin Schiller <ms@dev.tdt.de>
+Date: Tue, 11 Jun 2024 15:54:23 +0200
+Subject: dt-bindings: net: dsa: lantiq,gswip: convert to YAML schema
+
+Convert the lantiq,gswip bindings to YAML format.
+
+Also add this new file to the MAINTAINERS file.
+
+Furthermore, the CPU port has to specify a phy-mode and either a phy or
+a fixed-link. Since GSWIP is connected using a SoC internal protocol
+there's no PHY involved. Add phy-mode = "internal" and a fixed-link to
+the example code to describe the communication between the PMAC
+(Ethernet controller) and GSWIP switch.
+
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20240611135434.3180973-2-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ .../devicetree/bindings/net/dsa/lantiq,gswip.yaml | 202 +++++++++++++++++++++
+ .../devicetree/bindings/net/dsa/lantiq-gswip.txt | 146 ---------------
+ MAINTAINERS | 1 +
+ 3 files changed, 203 insertions(+), 146 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
+ delete mode 100644 Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
+@@ -0,0 +1,202 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/net/dsa/lantiq,gswip.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Lantiq GSWIP Ethernet switches
++
++allOf:
++ - $ref: dsa.yaml#/$defs/ethernet-ports
++
++maintainers:
++ - Hauke Mehrtens <hauke@hauke-m.de>
++
++properties:
++ compatible:
++ enum:
++ - lantiq,xrx200-gswip
++ - lantiq,xrx300-gswip
++ - lantiq,xrx330-gswip
++
++ reg:
++ minItems: 3
++ maxItems: 3
++
++ reg-names:
++ items:
++ - const: switch
++ - const: mdio
++ - const: mii
++
++ mdio:
++ $ref: /schemas/net/mdio.yaml#
++ unevaluatedProperties: false
++
++ properties:
++ compatible:
++ const: lantiq,xrx200-mdio
++
++ required:
++ - compatible
++
++ gphy-fw:
++ type: object
++ properties:
++ '#address-cells':
++ const: 1
++
++ '#size-cells':
++ const: 0
++
++ compatible:
++ items:
++ - enum:
++ - lantiq,xrx200-gphy-fw
++ - lantiq,xrx300-gphy-fw
++ - lantiq,xrx330-gphy-fw
++ - const: lantiq,gphy-fw
++
++ lantiq,rcu:
++ $ref: /schemas/types.yaml#/definitions/phandle
++ description: phandle to the RCU syscon
++
++ patternProperties:
++ "^gphy@[0-9a-f]{1,2}$":
++ type: object
++
++ additionalProperties: false
++
++ properties:
++ reg:
++ minimum: 0
++ maximum: 255
++ description:
++ Offset of the GPHY firmware register in the RCU register range
++
++ resets:
++ items:
++ - description: GPHY reset line
++
++ reset-names:
++ items:
++ - const: gphy
++
++ required:
++ - reg
++
++ required:
++ - compatible
++ - lantiq,rcu
++
++ additionalProperties: false
++
++required:
++ - compatible
++ - reg
++
++unevaluatedProperties: false
++
++examples:
++ - |
++ switch@e108000 {
++ compatible = "lantiq,xrx200-gswip";
++ reg = <0xe108000 0x3100>, /* switch */
++ <0xe10b100 0xd8>, /* mdio */
++ <0xe10b1d8 0x130>; /* mii */
++ dsa,member = <0 0>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ label = "lan3";
++ phy-mode = "rgmii";
++ phy-handle = <&phy0>;
++ };
++
++ port@1 {
++ reg = <1>;
++ label = "lan4";
++ phy-mode = "rgmii";
++ phy-handle = <&phy1>;
++ };
++
++ port@2 {
++ reg = <2>;
++ label = "lan2";
++ phy-mode = "internal";
++ phy-handle = <&phy11>;
++ };
++
++ port@4 {
++ reg = <4>;
++ label = "lan1";
++ phy-mode = "internal";
++ phy-handle = <&phy13>;
++ };
++
++ port@5 {
++ reg = <5>;
++ label = "wan";
++ phy-mode = "rgmii";
++ phy-handle = <&phy5>;
++ };
++
++ port@6 {
++ reg = <0x6>;
++ phy-mode = "internal";
++ ethernet = <&eth0>;
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++ };
++ };
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "lantiq,xrx200-mdio";
++
++ phy0: ethernet-phy@0 {
++ reg = <0x0>;
++ };
++ phy1: ethernet-phy@1 {
++ reg = <0x1>;
++ };
++ phy5: ethernet-phy@5 {
++ reg = <0x5>;
++ };
++ phy11: ethernet-phy@11 {
++ reg = <0x11>;
++ };
++ phy13: ethernet-phy@13 {
++ reg = <0x13>;
++ };
++ };
++
++ gphy-fw {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "lantiq,xrx200-gphy-fw", "lantiq,gphy-fw";
++ lantiq,rcu = <&rcu0>;
++
++ gphy@20 {
++ reg = <0x20>;
++
++ resets = <&reset0 31 30>;
++ reset-names = "gphy";
++ };
++
++ gphy@68 {
++ reg = <0x68>;
++
++ resets = <&reset0 29 28>;
++ reset-names = "gphy";
++ };
++ };
++ };
+--- a/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
++++ /dev/null
+@@ -1,146 +0,0 @@
+-Lantiq GSWIP Ethernet switches
+-==================================
+-
+-Required properties for GSWIP core:
+-
+-- compatible : "lantiq,xrx200-gswip" for the embedded GSWIP in the
+- xRX200 SoC
+- "lantiq,xrx300-gswip" for the embedded GSWIP in the
+- xRX300 SoC
+- "lantiq,xrx330-gswip" for the embedded GSWIP in the
+- xRX330 SoC
+-- reg : memory range of the GSWIP core registers
+- : memory range of the GSWIP MDIO registers
+- : memory range of the GSWIP MII registers
+-
+-See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of
+-additional required and optional properties.
+-
+-
+-Required properties for MDIO bus:
+-- compatible : "lantiq,xrx200-mdio" for the MDIO bus inside the GSWIP
+- core of the xRX200 SoC and the PHYs connected to it.
+-
+-See Documentation/devicetree/bindings/net/mdio.txt for a list of additional
+-required and optional properties.
+-
+-
+-Required properties for GPHY firmware loading:
+-- compatible : "lantiq,xrx200-gphy-fw", "lantiq,gphy-fw"
+- "lantiq,xrx300-gphy-fw", "lantiq,gphy-fw"
+- "lantiq,xrx330-gphy-fw", "lantiq,gphy-fw"
+- for the loading of the firmware into the embedded
+- GPHY core of the SoC.
+-- lantiq,rcu : reference to the rcu syscon
+-
+-The GPHY firmware loader has a list of GPHY entries, one for each
+-embedded GPHY
+-
+-- reg : Offset of the GPHY firmware register in the RCU
+- register range
+-- resets : list of resets of the embedded GPHY
+-- reset-names : list of names of the resets
+-
+-Example:
+-
+-Ethernet switch on the VRX200 SoC:
+-
+-switch@e108000 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- compatible = "lantiq,xrx200-gswip";
+- reg = < 0xe108000 0x3100 /* switch */
+- 0xe10b100 0xd8 /* mdio */
+- 0xe10b1d8 0x130 /* mii */
+- >;
+- dsa,member = <0 0>;
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@0 {
+- reg = <0>;
+- label = "lan3";
+- phy-mode = "rgmii";
+- phy-handle = <&phy0>;
+- };
+-
+- port@1 {
+- reg = <1>;
+- label = "lan4";
+- phy-mode = "rgmii";
+- phy-handle = <&phy1>;
+- };
+-
+- port@2 {
+- reg = <2>;
+- label = "lan2";
+- phy-mode = "internal";
+- phy-handle = <&phy11>;
+- };
+-
+- port@4 {
+- reg = <4>;
+- label = "lan1";
+- phy-mode = "internal";
+- phy-handle = <&phy13>;
+- };
+-
+- port@5 {
+- reg = <5>;
+- label = "wan";
+- phy-mode = "rgmii";
+- phy-handle = <&phy5>;
+- };
+-
+- port@6 {
+- reg = <0x6>;
+- ethernet = <&eth0>;
+- };
+- };
+-
+- mdio {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- compatible = "lantiq,xrx200-mdio";
+- reg = <0>;
+-
+- phy0: ethernet-phy@0 {
+- reg = <0x0>;
+- };
+- phy1: ethernet-phy@1 {
+- reg = <0x1>;
+- };
+- phy5: ethernet-phy@5 {
+- reg = <0x5>;
+- };
+- phy11: ethernet-phy@11 {
+- reg = <0x11>;
+- };
+- phy13: ethernet-phy@13 {
+- reg = <0x13>;
+- };
+- };
+-
+- gphy-fw {
+- compatible = "lantiq,xrx200-gphy-fw", "lantiq,gphy-fw";
+- lantiq,rcu = <&rcu0>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- gphy@20 {
+- reg = <0x20>;
+-
+- resets = <&reset0 31 30>;
+- reset-names = "gphy";
+- };
+-
+- gphy@68 {
+- reg = <0x68>;
+-
+- resets = <&reset0 29 28>;
+- reset-names = "gphy";
+- };
+- };
+-};
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -11863,6 +11863,7 @@ LANTIQ / INTEL Ethernet drivers
+ M: Hauke Mehrtens <hauke@hauke-m.de>
+ L: netdev@vger.kernel.org
+ S: Maintained
++F: Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
+ F: drivers/net/dsa/lantiq_gswip.c
+ F: drivers/net/dsa/lantiq_pce.h
+ F: drivers/net/ethernet/lantiq_xrx200.c
diff --git a/target/linux/lantiq/patches-6.6/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch b/target/linux/lantiq/patches-6.6/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch
deleted file mode 100644
index 4800ee1dd2..0000000000
--- a/target/linux/lantiq/patches-6.6/0732-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From a55b9d802e11baceb35bd312419ad82086065b08 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:59:35 +0200
-Subject: [PATCH 732/768] net: dsa: lantiq_gswip: Only allow phy-mode =
- "internal" on the CPU port
-
-Add the CPU port to gswip_xrx200_phylink_get_caps() and
-gswip_xrx300_phylink_get_caps(). It connects through a SoC-internal bus,
-so the only allowed phy-mode is PHY_INTERFACE_MODE_INTERNAL.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1509,6 +1509,7 @@ static void gswip_xrx200_phylink_get_cap
- case 2:
- case 3:
- case 4:
-+ case 6:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
- break;
-@@ -1540,6 +1541,7 @@ static void gswip_xrx300_phylink_get_cap
- case 2:
- case 3:
- case 4:
-+ case 6:
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- config->supported_interfaces);
- break;
diff --git a/target/linux/lantiq/patches-6.6/0732-v6.11-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on-the-CPU-port.patch b/target/linux/lantiq/patches-6.6/0732-v6.11-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on-the-CPU-port.patch
new file mode 100644
index 0000000000..305ad4c42c
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0732-v6.11-net-dsa-lantiq_gswip-Only-allow-phy-mode-internal-on-the-CPU-port.patch
@@ -0,0 +1,38 @@
+From b98f122ebdac28b0c932f3f4474eb0927c39297b Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:24 +0200
+Subject: net: dsa: lantiq_gswip: Only allow phy-mode = "internal" on the CPU
+ port
+
+Add the CPU port to gswip_xrx200_phylink_get_caps() and
+gswip_xrx300_phylink_get_caps(). It connects through a SoC-internal bus,
+so the only allowed phy-mode is PHY_INTERFACE_MODE_INTERNAL.
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://lore.kernel.org/r/20240611135434.3180973-3-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -1509,6 +1509,7 @@ static void gswip_xrx200_phylink_get_cap
+ case 2:
+ case 3:
+ case 4:
++ case 6:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+ break;
+@@ -1540,6 +1541,7 @@ static void gswip_xrx300_phylink_get_cap
+ case 2:
+ case 3:
+ case 4:
++ case 6:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+ break;
diff --git a/target/linux/lantiq/patches-6.6/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch b/target/linux/lantiq/patches-6.6/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
deleted file mode 100644
index f30e7ab00c..0000000000
--- a/target/linux/lantiq/patches-6.6/0733-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 4d3dd68a1c56674ff666d0622b545992fac31754 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Sun, 31 Jul 2022 22:54:52 +0200
-Subject: [PATCH 733/768] net: dsa: lantiq_gswip: Use dev_err_probe where
- appropriate
-
-dev_err_probe() can be used to simplify the existing code. Also it means
-we get rid of the following warning which is seen whenever the PMAC
-(Ethernet controller which connects to GSWIP's CPU port) has not been
-probed yet:
- gswip 1e108000.switch: dsa switch register failed: -517
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++------------------
- 1 file changed, 25 insertions(+), 28 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1919,11 +1919,9 @@ static int gswip_gphy_fw_load(struct gsw
- msleep(200);
-
- ret = request_firmware(&fw, gphy_fw->fw_name, dev);
-- if (ret) {
-- dev_err(dev, "failed to load firmware: %s, error: %i\n",
-- gphy_fw->fw_name, ret);
-- return ret;
-- }
-+ if (ret)
-+ return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
-+ gphy_fw->fw_name);
-
- /* GPHY cores need the firmware code in a persistent and contiguous
- * memory area with a 16 kB boundary aligned start address.
-@@ -1936,9 +1934,9 @@ static int gswip_gphy_fw_load(struct gsw
- dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
- memcpy(fw_addr, fw->data, fw->size);
- } else {
-- dev_err(dev, "failed to alloc firmware memory\n");
- release_firmware(fw);
-- return -ENOMEM;
-+ return dev_err_probe(dev, -ENOMEM,
-+ "failed to alloc firmware memory\n");
- }
-
- release_firmware(fw);
-@@ -1965,8 +1963,8 @@ static int gswip_gphy_fw_probe(struct gs
-
- gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
- if (IS_ERR(gphy_fw->clk_gate)) {
-- dev_err(dev, "Failed to lookup gate clock\n");
-- return PTR_ERR(gphy_fw->clk_gate);
-+ return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
-+ "Failed to lookup gate clock\n");
- }
-
- ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
-@@ -1986,8 +1984,8 @@ static int gswip_gphy_fw_probe(struct gs
- gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
- break;
- default:
-- dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
-- return -EINVAL;
-+ return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
-+ gphy_mode);
- }
-
- gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
-@@ -2038,8 +2036,9 @@ static int gswip_gphy_fw_list(struct gsw
- priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x",
-+ version);
- }
- }
-
-@@ -2047,10 +2046,9 @@ static int gswip_gphy_fw_list(struct gsw
- if (match && match->data)
- priv->gphy_fw_name_cfg = match->data;
-
-- if (!priv->gphy_fw_name_cfg) {
-- dev_err(dev, "GPHY compatible type not supported");
-- return -ENOENT;
-- }
-+ if (!priv->gphy_fw_name_cfg)
-+ return dev_err_probe(dev, -ENOENT,
-+ "GPHY compatible type not supported");
-
- priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
- if (!priv->num_gphy_fw)
-@@ -2150,8 +2148,8 @@ static int gswip_probe(struct platform_d
- return -EINVAL;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x", version);
- }
-
- /* bring up the mdio bus */
-@@ -2159,10 +2157,9 @@ static int gswip_probe(struct platform_d
- if (gphy_fw_np) {
- err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
- of_node_put(gphy_fw_np);
-- if (err) {
-- dev_err(dev, "gphy fw probe failed\n");
-- return err;
-- }
-+ if (err)
-+ return dev_err_probe(dev, err,
-+ "gphy fw probe failed\n");
- }
-
- /* bring up the mdio bus */
-@@ -2170,20 +2167,20 @@ static int gswip_probe(struct platform_d
- if (mdio_np) {
- err = gswip_mdio(priv, mdio_np);
- if (err) {
-- dev_err(dev, "mdio probe failed\n");
-+ dev_err_probe(dev, err, "mdio probe failed\n");
- goto put_mdio_node;
- }
- }
-
- err = dsa_register_switch(priv->ds);
- if (err) {
-- dev_err(dev, "dsa switch register failed: %i\n", err);
-+ dev_err_probe(dev, err, "dsa switch registration failed\n");
- goto mdio_bus;
- }
- if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
-- dev_err(dev, "wrong CPU port defined, HW only supports port: %i",
-- priv->hw_info->cpu_port);
-- err = -EINVAL;
-+ err = dev_err_probe(dev, -EINVAL,
-+ "wrong CPU port defined, HW only supports port: %i",
-+ priv->hw_info->cpu_port);
- goto disable_switch;
- }
-
diff --git a/target/linux/lantiq/patches-6.6/0733-v6.11-net-dsa-lantiq_gswip-add-terminating-n-where-missing.patch b/target/linux/lantiq/patches-6.6/0733-v6.11-net-dsa-lantiq_gswip-add-terminating-n-where-missing.patch
new file mode 100644
index 0000000000..55adfe021f
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0733-v6.11-net-dsa-lantiq_gswip-add-terminating-n-where-missing.patch
@@ -0,0 +1,82 @@
+From dd6d364e1895211df8a8fe02c2a5a0b2a7049957 Mon Sep 17 00:00:00 2001
+From: Martin Schiller <ms@dev.tdt.de>
+Date: Tue, 11 Jun 2024 15:54:25 +0200
+Subject: net: dsa: lantiq_gswip: add terminating \n where missing
+
+Some dev_err are missing the terminating \n. Let's add that.
+
+Suggested-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20240611135434.3180973-4-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -829,7 +829,7 @@ static int gswip_setup(struct dsa_switch
+
+ err = gswip_pce_load_microcode(priv);
+ if (err) {
+- dev_err(priv->dev, "writing PCE microcode failed, %i", err);
++ dev_err(priv->dev, "writing PCE microcode failed, %i\n", err);
+ return err;
+ }
+
+@@ -1780,7 +1780,7 @@ static u32 gswip_bcm_ram_entry_read(stru
+ err = gswip_switch_r_timeout(priv, GSWIP_BM_RAM_CTRL,
+ GSWIP_BM_RAM_CTRL_BAS);
+ if (err) {
+- dev_err(priv->dev, "timeout while reading table: %u, index: %u",
++ dev_err(priv->dev, "timeout while reading table: %u, index: %u\n",
+ table, index);
+ return 0;
+ }
+@@ -2009,7 +2009,7 @@ static void gswip_gphy_fw_remove(struct
+
+ ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, 0);
+ if (ret)
+- dev_err(priv->dev, "can not reset GPHY FW pointer");
++ dev_err(priv->dev, "can not reset GPHY FW pointer\n");
+
+ clk_disable_unprepare(gphy_fw->clk_gate);
+
+@@ -2038,7 +2038,7 @@ static int gswip_gphy_fw_list(struct gsw
+ priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
+ break;
+ default:
+- dev_err(dev, "unknown GSWIP version: 0x%x", version);
++ dev_err(dev, "unknown GSWIP version: 0x%x\n", version);
+ return -ENOENT;
+ }
+ }
+@@ -2048,7 +2048,7 @@ static int gswip_gphy_fw_list(struct gsw
+ priv->gphy_fw_name_cfg = match->data;
+
+ if (!priv->gphy_fw_name_cfg) {
+- dev_err(dev, "GPHY compatible type not supported");
++ dev_err(dev, "GPHY compatible type not supported\n");
+ return -ENOENT;
+ }
+
+@@ -2150,7 +2150,7 @@ static int gswip_probe(struct platform_d
+ return -EINVAL;
+ break;
+ default:
+- dev_err(dev, "unknown GSWIP version: 0x%x", version);
++ dev_err(dev, "unknown GSWIP version: 0x%x\n", version);
+ return -ENOENT;
+ }
+
+@@ -2181,7 +2181,7 @@ static int gswip_probe(struct platform_d
+ goto mdio_bus;
+ }
+ if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
+- dev_err(dev, "wrong CPU port defined, HW only supports port: %i",
++ dev_err(dev, "wrong CPU port defined, HW only supports port: %i\n",
+ priv->hw_info->cpu_port);
+ err = -EINVAL;
+ goto disable_switch;
diff --git a/target/linux/lantiq/patches-6.6/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch b/target/linux/lantiq/patches-6.6/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
deleted file mode 100644
index de8416380a..0000000000
--- a/target/linux/lantiq/patches-6.6/0734-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 8cf0b680abc157adeec3fb93a10354c470694535 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Thu, 28 Jul 2022 22:37:11 +0200
-Subject: [PATCH 734/768] net: dsa: lantiq_gswip: Don't manually call
- gswip_port_enable()
-
-We don't need to manually call gswip_port_enable() from within
-gswip_setup() for the CPU port. DSA does this automatically for us.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -891,8 +891,6 @@ static int gswip_setup(struct dsa_switch
-
- ds->mtu_enforcement_ingress = true;
-
-- gswip_port_enable(ds, cpu_port, NULL);
--
- ds->configure_vlan_while_not_filtering = false;
-
- return 0;
diff --git a/target/linux/lantiq/patches-6.6/0734-v6.11-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch b/target/linux/lantiq/patches-6.6/0734-v6.11-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
new file mode 100644
index 0000000000..7894979707
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0734-v6.11-net-dsa-lantiq_gswip-Use-dev_err_probe-where-appropr.patch
@@ -0,0 +1,149 @@
+From 1763b155da022ac0f984463e68cb0cda8ffc1fe8 Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:26 +0200
+Subject: net: dsa: lantiq_gswip: Use dev_err_probe where appropriate
+
+dev_err_probe() can be used to simplify the existing code. Also it means
+we get rid of the following warning which is seen whenever the PMAC
+(Ethernet controller which connects to GSWIP's CPU port) has not been
+probed yet:
+ gswip 1e108000.switch: dsa switch register failed: -517
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://lore.kernel.org/r/20240611135434.3180973-5-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++++++----------------------
+ 1 file changed, 25 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -1919,11 +1919,9 @@ static int gswip_gphy_fw_load(struct gsw
+ msleep(200);
+
+ ret = request_firmware(&fw, gphy_fw->fw_name, dev);
+- if (ret) {
+- dev_err(dev, "failed to load firmware: %s, error: %i\n",
+- gphy_fw->fw_name, ret);
+- return ret;
+- }
++ if (ret)
++ return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
++ gphy_fw->fw_name);
+
+ /* GPHY cores need the firmware code in a persistent and contiguous
+ * memory area with a 16 kB boundary aligned start address.
+@@ -1936,9 +1934,9 @@ static int gswip_gphy_fw_load(struct gsw
+ dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
+ memcpy(fw_addr, fw->data, fw->size);
+ } else {
+- dev_err(dev, "failed to alloc firmware memory\n");
+ release_firmware(fw);
+- return -ENOMEM;
++ return dev_err_probe(dev, -ENOMEM,
++ "failed to alloc firmware memory\n");
+ }
+
+ release_firmware(fw);
+@@ -1965,8 +1963,8 @@ static int gswip_gphy_fw_probe(struct gs
+
+ gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
+ if (IS_ERR(gphy_fw->clk_gate)) {
+- dev_err(dev, "Failed to lookup gate clock\n");
+- return PTR_ERR(gphy_fw->clk_gate);
++ return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
++ "Failed to lookup gate clock\n");
+ }
+
+ ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
+@@ -1986,8 +1984,8 @@ static int gswip_gphy_fw_probe(struct gs
+ gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
+ break;
+ default:
+- dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
+- return -EINVAL;
++ return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
++ gphy_mode);
+ }
+
+ gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
+@@ -2038,8 +2036,9 @@ static int gswip_gphy_fw_list(struct gsw
+ priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
+ break;
+ default:
+- dev_err(dev, "unknown GSWIP version: 0x%x\n", version);
+- return -ENOENT;
++ return dev_err_probe(dev, -ENOENT,
++ "unknown GSWIP version: 0x%x\n",
++ version);
+ }
+ }
+
+@@ -2047,10 +2046,9 @@ static int gswip_gphy_fw_list(struct gsw
+ if (match && match->data)
+ priv->gphy_fw_name_cfg = match->data;
+
+- if (!priv->gphy_fw_name_cfg) {
+- dev_err(dev, "GPHY compatible type not supported\n");
+- return -ENOENT;
+- }
++ if (!priv->gphy_fw_name_cfg)
++ return dev_err_probe(dev, -ENOENT,
++ "GPHY compatible type not supported\n");
+
+ priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
+ if (!priv->num_gphy_fw)
+@@ -2150,8 +2148,8 @@ static int gswip_probe(struct platform_d
+ return -EINVAL;
+ break;
+ default:
+- dev_err(dev, "unknown GSWIP version: 0x%x\n", version);
+- return -ENOENT;
++ return dev_err_probe(dev, -ENOENT,
++ "unknown GSWIP version: 0x%x\n", version);
+ }
+
+ /* bring up the mdio bus */
+@@ -2159,10 +2157,9 @@ static int gswip_probe(struct platform_d
+ if (gphy_fw_np) {
+ err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
+ of_node_put(gphy_fw_np);
+- if (err) {
+- dev_err(dev, "gphy fw probe failed\n");
+- return err;
+- }
++ if (err)
++ return dev_err_probe(dev, err,
++ "gphy fw probe failed\n");
+ }
+
+ /* bring up the mdio bus */
+@@ -2170,20 +2167,20 @@ static int gswip_probe(struct platform_d
+ if (mdio_np) {
+ err = gswip_mdio(priv, mdio_np);
+ if (err) {
+- dev_err(dev, "mdio probe failed\n");
++ dev_err_probe(dev, err, "mdio probe failed\n");
+ goto put_mdio_node;
+ }
+ }
+
+ err = dsa_register_switch(priv->ds);
+ if (err) {
+- dev_err(dev, "dsa switch register failed: %i\n", err);
++ dev_err_probe(dev, err, "dsa switch registration failed\n");
+ goto mdio_bus;
+ }
+ if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
+- dev_err(dev, "wrong CPU port defined, HW only supports port: %i\n",
+- priv->hw_info->cpu_port);
+- err = -EINVAL;
++ err = dev_err_probe(dev, -EINVAL,
++ "wrong CPU port defined, HW only supports port: %i\n",
++ priv->hw_info->cpu_port);
+ goto disable_switch;
+ }
+
diff --git a/target/linux/lantiq/patches-6.6/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch b/target/linux/lantiq/patches-6.6/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
deleted file mode 100644
index a653c85841..0000000000
--- a/target/linux/lantiq/patches-6.6/0735-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 54a2f7f2c134738bd3f4ea0a213138d169f2726e Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Fri, 10 May 2024 13:52:10 +0200
-Subject: [PATCH] net: dsa: lantiq_gswip: do also enable or disable cpu port
-
-Before commit 74be4babe72f ("net: dsa: do not enable or disable non user
-ports"), gswip_port_enable/disable() were also executed for the cpu port
-in gswip_setup() which disabled the cpu port during initialization.
-
-Let's restore this by removing the dsa_is_user_port checks. Also, let's
-clean up the gswip_port_enable() function so that we only have to check
-for the cpu port once.
-
-Fixes: 74be4babe72f ("net: dsa: do not enable or disable non user ports")
-Signed-off-by: Martin Schiller <ms@dev.tdt.de>
----
- drivers/net/dsa/lantiq_gswip.c | 24 ++++++++----------------
- 1 file changed, 8 insertions(+), 16 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -688,13 +688,18 @@ static int gswip_port_enable(struct dsa_
- struct gswip_priv *priv = ds->priv;
- int err;
-
-- if (!dsa_is_user_port(ds, port))
-- return 0;
--
- if (!dsa_is_cpu_port(ds, port)) {
-+ u32 mdio_phy = 0;
-+
- err = gswip_add_single_port_br(priv, port, true);
- if (err)
- return err;
-+
-+ if (phydev)
-+ mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
-+
-+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-+ GSWIP_MDIO_PHYp(port));
- }
-
- /* RMON Counter Enable for port */
-@@ -707,16 +712,6 @@ static int gswip_port_enable(struct dsa_
- gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
- GSWIP_SDMA_PCTRLp(port));
-
-- if (!dsa_is_cpu_port(ds, port)) {
-- u32 mdio_phy = 0;
--
-- if (phydev)
-- mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
--
-- gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-- GSWIP_MDIO_PHYp(port));
-- }
--
- return 0;
- }
-
-@@ -724,9 +719,6 @@ static void gswip_port_disable(struct ds
- {
- 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,
diff --git a/target/linux/lantiq/patches-6.6/0735-v6.11-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch b/target/linux/lantiq/patches-6.6/0735-v6.11-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
new file mode 100644
index 0000000000..b7de069c5f
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0735-v6.11-net-dsa-lantiq_gswip-Don-t-manually-call-gswip_port_.patch
@@ -0,0 +1,29 @@
+From f5ebf9ab60940b00c36dfe64add41c80f3daff6a Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:27 +0200
+Subject: net: dsa: lantiq_gswip: Don't manually call gswip_port_enable()
+
+We don't need to manually call gswip_port_enable() from within
+gswip_setup() for the CPU port. DSA does this automatically for us.
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://lore.kernel.org/r/20240611135434.3180973-6-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -891,8 +891,6 @@ static int gswip_setup(struct dsa_switch
+
+ ds->mtu_enforcement_ingress = true;
+
+- gswip_port_enable(ds, cpu_port, NULL);
+-
+ ds->configure_vlan_while_not_filtering = false;
+
+ return 0;
diff --git a/target/linux/lantiq/patches-6.6/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch b/target/linux/lantiq/patches-6.6/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
deleted file mode 100644
index fd19982264..0000000000
--- a/target/linux/lantiq/patches-6.6/0736-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8ab55ac9678ca1f50f786c84484599dd675c5a9f Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Wed, 18 May 2022 23:53:09 +0200
-Subject: [PATCH 736/768] net: dsa: lantiq_gswip: Use dsa_is_cpu_port() in
- gswip_port_change_mtu()
-
-Make the check for the CPU port in gswip_port_change_mtu() consistent
-with other areas of the driver by using dsa_is_cpu_port().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1457,12 +1457,11 @@ static int gswip_port_max_mtu(struct dsa
- static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct gswip_priv *priv = ds->priv;
-- int cpu_port = priv->hw_info->cpu_port;
-
- /* CPU port always has maximum mtu of user ports, so use it to set
- * switch frame size, including 8 byte special header.
- */
-- if (port == cpu_port) {
-+ if (dsa_is_cpu_port(ds, port)) {
- new_mtu += 8;
- gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
- GSWIP_MAC_FLEN);
diff --git a/target/linux/lantiq/patches-6.6/0736-v6.11-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch b/target/linux/lantiq/patches-6.6/0736-v6.11-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
new file mode 100644
index 0000000000..0baca3d7c2
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0736-v6.11-net-dsa-lantiq_gswip-do-also-enable-or-disable-cpu-p.patch
@@ -0,0 +1,73 @@
+From 86b9ea6412af41914ef6549f85a849c3b987f4f3 Mon Sep 17 00:00:00 2001
+From: Martin Schiller <ms@dev.tdt.de>
+Date: Tue, 11 Jun 2024 15:54:28 +0200
+Subject: net: dsa: lantiq_gswip: do also enable or disable cpu port
+
+Before commit 74be4babe72f ("net: dsa: do not enable or disable non user
+ports"), gswip_port_enable/disable() were also executed for the cpu port
+in gswip_setup() which disabled the cpu port during initialization.
+
+Let's restore this by removing the dsa_is_user_port checks. Also, let's
+clean up the gswip_port_enable() function so that we only have to check
+for the cpu port once. The operation reordering done here is safe.
+
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20240611135434.3180973-7-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 24 ++++++++----------------
+ 1 file changed, 8 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -688,13 +688,18 @@ static int gswip_port_enable(struct dsa_
+ struct gswip_priv *priv = ds->priv;
+ int err;
+
+- if (!dsa_is_user_port(ds, port))
+- return 0;
+-
+ if (!dsa_is_cpu_port(ds, port)) {
++ u32 mdio_phy = 0;
++
+ err = gswip_add_single_port_br(priv, port, true);
+ if (err)
+ return err;
++
++ if (phydev)
++ mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
++
++ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
++ GSWIP_MDIO_PHYp(port));
+ }
+
+ /* RMON Counter Enable for port */
+@@ -707,16 +712,6 @@ static int gswip_port_enable(struct dsa_
+ gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
+ GSWIP_SDMA_PCTRLp(port));
+
+- if (!dsa_is_cpu_port(ds, port)) {
+- u32 mdio_phy = 0;
+-
+- if (phydev)
+- mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
+-
+- gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
+- GSWIP_MDIO_PHYp(port));
+- }
+-
+ return 0;
+ }
+
+@@ -724,9 +719,6 @@ static void gswip_port_disable(struct ds
+ {
+ 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,
diff --git a/target/linux/lantiq/patches-6.6/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch b/target/linux/lantiq/patches-6.6/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
deleted file mode 100644
index 74e52d1d18..0000000000
--- a/target/linux/lantiq/patches-6.6/0737-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From ef98b183d8fc7187a2efcc21c8f54f3cf061d556 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Tue, 17 May 2022 22:39:58 +0200
-Subject: [PATCH 737/768] net: dsa: lantiq_gswip: Change literal 6 to ETH_ALEN
-
-The addr variable in gswip_port_fdb_dump() stores a mac address. Use
-ETH_ALEN to make this consistent across other drivers.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1406,7 +1406,7 @@ static int gswip_port_fdb_dump(struct ds
- {
- struct gswip_priv *priv = ds->priv;
- struct gswip_pce_table_entry mac_bridge = {0,};
-- unsigned char addr[6];
-+ unsigned char addr[ETH_ALEN];
- int i;
- int err;
-
diff --git a/target/linux/lantiq/patches-6.6/0737-v6.11-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch b/target/linux/lantiq/patches-6.6/0737-v6.11-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
new file mode 100644
index 0000000000..493aea4295
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0737-v6.11-net-dsa-lantiq_gswip-Use-dsa_is_cpu_port-in-gswip_po.patch
@@ -0,0 +1,35 @@
+From 7168ec1b06691295db6b335e5f5f6c86c7061213 Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:29 +0200
+Subject: net: dsa: lantiq_gswip: Use dsa_is_cpu_port() in
+ gswip_port_change_mtu()
+
+Make the check for the CPU port in gswip_port_change_mtu() consistent
+with other areas of the driver by using dsa_is_cpu_port().
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://lore.kernel.org/r/20240611135434.3180973-8-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -1457,12 +1457,11 @@ static int gswip_port_max_mtu(struct dsa
+ static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+ {
+ struct gswip_priv *priv = ds->priv;
+- int cpu_port = priv->hw_info->cpu_port;
+
+ /* CPU port always has maximum mtu of user ports, so use it to set
+ * switch frame size, including 8 byte special header.
+ */
+- if (port == cpu_port) {
++ if (dsa_is_cpu_port(ds, port)) {
+ new_mtu += 8;
+ gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
+ GSWIP_MAC_FLEN);
diff --git a/target/linux/lantiq/patches-6.6/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch b/target/linux/lantiq/patches-6.6/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
deleted file mode 100644
index 0ea90db483..0000000000
--- a/target/linux/lantiq/patches-6.6/0738-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 61e9b19f6e6174afa7540f0b468a69bc940b91d4 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 21:23:49 +0200
-Subject: [PATCH 738/768] net: dsa: lantiq_gswip: Consistently use macros for
- the mac bridge table
-
-Introduce a new GSWIP_TABLE_MAC_BRIDGE_PORT macro and use it throughout
-the driver. Also update GSWIP_TABLE_MAC_BRIDGE_STATIC to use the BIT()
-macro. This makes the driver code easier to understand.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -236,7 +236,8 @@
- #define GSWIP_TABLE_ACTIVE_VLAN 0x01
- #define GSWIP_TABLE_VLAN_MAPPING 0x02
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
--#define GSWIP_TABLE_MAC_BRIDGE_STATIC 0x01 /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1300,7 +1301,8 @@ static void gswip_port_fast_age(struct d
- if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC)
- continue;
-
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port)
-+ if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0]))
- continue;
-
- mac_bridge.valid = false;
-@@ -1438,7 +1440,8 @@ static int gswip_port_fdb_dump(struct ds
- return err;
- }
- } else {
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) {
-+ if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0])) {
- err = cb(addr, 0, false, data);
- if (err)
- return err;
diff --git a/target/linux/lantiq/patches-6.6/0738-v6.11-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch b/target/linux/lantiq/patches-6.6/0738-v6.11-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
new file mode 100644
index 0000000000..773d43ee19
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0738-v6.11-net-dsa-lantiq_gswip-Change-literal-6-to-ETH_ALEN.patch
@@ -0,0 +1,29 @@
+From c927b6e47b5cc7324217bf5fe7e6ccd0633971a0 Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:30 +0200
+Subject: net: dsa: lantiq_gswip: Change literal 6 to ETH_ALEN
+
+The addr variable in gswip_port_fdb_dump() stores a mac address. Use
+ETH_ALEN to make this consistent across other drivers.
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://lore.kernel.org/r/20240611135434.3180973-9-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -1406,7 +1406,7 @@ static int gswip_port_fdb_dump(struct ds
+ {
+ struct gswip_priv *priv = ds->priv;
+ struct gswip_pce_table_entry mac_bridge = {0,};
+- unsigned char addr[6];
++ unsigned char addr[ETH_ALEN];
+ int i;
+ int err;
+
diff --git a/target/linux/lantiq/patches-6.6/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch b/target/linux/lantiq/patches-6.6/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch
deleted file mode 100644
index 1347a98c5c..0000000000
--- a/target/linux/lantiq/patches-6.6/0739-net-dsa-lantiq_gswip-Forbid-gswip_add_single_port_br.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 7a9e185075ababa827d1d3a33b787ad6d718c8ec Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:24:24 +0200
-Subject: [PATCH 739/768] net: dsa: lantiq_gswip: Forbid
- gswip_add_single_port_br on the CPU port
-
-Calling gswip_add_single_port_br() with the CPU port would be a bug
-because then only the CPU port could talk to itself. Add the CPU port to
-the validation at the beginning of gswip_add_single_port_br().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -650,7 +650,7 @@ static int gswip_add_single_port_br(stru
- unsigned int max_ports = priv->hw_info->max_ports;
- int err;
-
-- if (port >= max_ports) {
-+ if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
- dev_err(priv->dev, "single port for %i supported\n", port);
- return -EIO;
- }
diff --git a/target/linux/lantiq/patches-6.6/0739-v6.11-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch b/target/linux/lantiq/patches-6.6/0739-v6.11-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
new file mode 100644
index 0000000000..31f2e60bfb
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0739-v6.11-net-dsa-lantiq_gswip-Consistently-use-macros-for-the.patch
@@ -0,0 +1,82 @@
+From e6c34597f89ac98c06176eed57f125252015a330 Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:31 +0200
+Subject: net: dsa: lantiq_gswip: Consistently use macros for the mac bridge
+ table
+
+Only bits [5:0] in mac_bridge.key[3] are reserved for the FID.
+Also, for dynamic (learned) entries, bits [7:4] in mac_bridge.val[0]
+represents the port.
+
+Introduce new macros GSWIP_TABLE_MAC_BRIDGE_KEY3_FID and
+GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT macro and use it throughout the driver.
+Also rename and update GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC to use the
+BIT() macro. This makes the driver code easier to understand.
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20240611135434.3180973-10-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -236,7 +236,9 @@
+ #define GSWIP_TABLE_ACTIVE_VLAN 0x01
+ #define GSWIP_TABLE_VLAN_MAPPING 0x02
+ #define GSWIP_TABLE_MAC_BRIDGE 0x0b
+-#define GSWIP_TABLE_MAC_BRIDGE_STATIC 0x01 /* Static not, aging entry */
++#define GSWIP_TABLE_MAC_BRIDGE_KEY3_FID GENMASK(5, 0) /* Filtering identifier */
++#define GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT GENMASK(7, 4) /* Port on learned entries */
++#define GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC BIT(0) /* Static, non-aging entry */
+
+ #define XRX200_GPHY_FW_ALIGN (16 * 1024)
+
+@@ -1297,10 +1299,11 @@ static void gswip_port_fast_age(struct d
+ if (!mac_bridge.valid)
+ continue;
+
+- if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC)
++ if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC)
+ continue;
+
+- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port)
++ if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT,
++ mac_bridge.val[0]))
+ continue;
+
+ mac_bridge.valid = false;
+@@ -1375,9 +1378,9 @@ static int gswip_port_fdb(struct dsa_swi
+ mac_bridge.key[0] = addr[5] | (addr[4] << 8);
+ mac_bridge.key[1] = addr[3] | (addr[2] << 8);
+ mac_bridge.key[2] = addr[1] | (addr[0] << 8);
+- mac_bridge.key[3] = fid;
++ mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_KEY3_FID, fid);
+ mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */
+- mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_STATIC;
++ mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC;
+ mac_bridge.valid = add;
+
+ err = gswip_pce_table_entry_write(priv, &mac_bridge);
+@@ -1431,14 +1434,15 @@ static int gswip_port_fdb_dump(struct ds
+ addr[2] = (mac_bridge.key[1] >> 8) & 0xff;
+ addr[1] = mac_bridge.key[2] & 0xff;
+ addr[0] = (mac_bridge.key[2] >> 8) & 0xff;
+- if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC) {
++ if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC) {
+ if (mac_bridge.val[0] & BIT(port)) {
+ err = cb(addr, 0, true, data);
+ if (err)
+ return err;
+ }
+ } else {
+- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) {
++ if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT,
++ mac_bridge.val[0])) {
+ err = cb(addr, 0, false, data);
+ if (err)
+ return err;
diff --git a/target/linux/lantiq/patches-6.6/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch b/target/linux/lantiq/patches-6.6/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch
deleted file mode 100644
index 732588308e..0000000000
--- a/target/linux/lantiq/patches-6.6/0740-net-dsa-lantiq_gswip-Fix-error-message-in-gswip_add_.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 28be6bfb735d851e646abb05b8e24eb6764596f5 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:26:20 +0200
-Subject: [PATCH 740/768] net: dsa: lantiq_gswip: Fix error message in
- gswip_add_single_port_br()
-
-The error message is printed when the port cannot be used. Update the
-error message to reflect that.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -651,7 +651,8 @@ static int gswip_add_single_port_br(stru
- int err;
-
- if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
-- dev_err(priv->dev, "single port for %i supported\n", port);
-+ dev_err(priv->dev, "single port for %i is not supported\n",
-+ port);
- return -EIO;
- }
-
diff --git a/target/linux/lantiq/patches-6.6/0740-v6.11-net-dsa-lantiq_gswip-Remove-dead-code-from-gswip_add_single_port_br.patch b/target/linux/lantiq/patches-6.6/0740-v6.11-net-dsa-lantiq_gswip-Remove-dead-code-from-gswip_add_single_port_br.patch
new file mode 100644
index 0000000000..4e297715c1
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0740-v6.11-net-dsa-lantiq_gswip-Remove-dead-code-from-gswip_add_single_port_br.patch
@@ -0,0 +1,35 @@
+From b068706b7831ccf7c7f1a56a65862fbcc28d061f Mon Sep 17 00:00:00 2001
+From: Martin Schiller <ms@dev.tdt.de>
+Date: Tue, 11 Jun 2024 15:54:32 +0200
+Subject: net: dsa: lantiq_gswip: Remove dead code from
+ gswip_add_single_port_br()
+
+The port validation in gswip_add_single_port_br() is superfluous and
+can be omitted.
+
+Suggested-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20240611135434.3180973-11-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -648,14 +648,8 @@ static int gswip_add_single_port_br(stru
+ struct gswip_pce_table_entry vlan_active = {0,};
+ struct gswip_pce_table_entry vlan_mapping = {0,};
+ unsigned int cpu_port = priv->hw_info->cpu_port;
+- unsigned int max_ports = priv->hw_info->max_ports;
+ int err;
+
+- if (port >= max_ports) {
+- dev_err(priv->dev, "single port for %i supported\n", port);
+- return -EIO;
+- }
+-
+ vlan_active.index = port + 1;
+ vlan_active.table = GSWIP_TABLE_ACTIVE_VLAN;
+ vlan_active.key[0] = 0; /* vid */
diff --git a/target/linux/lantiq/patches-6.6/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch b/target/linux/lantiq/patches-6.6/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch
deleted file mode 100644
index 679dd53c47..0000000000
--- a/target/linux/lantiq/patches-6.6/0741-net-dsa-lantiq_gswip-Fix-comments-in-gswip_port_vlan.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 45a0371568b1f050d787564875653f41a1f6fb98 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:06:40 +0200
-Subject: [PATCH 741/768] net: dsa: lantiq_gswip: Fix comments in
- gswip_port_vlan_filtering()
-
-Update the comments in gswip_port_vlan_filtering() so it's clear that
-there are two separate cases, one for "tag based VLAN" and another one
-for "port based VLAN".
-
-Suggested-by: Martin Schiller <ms@dev.tdt.de>
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -779,7 +779,7 @@ static int gswip_port_vlan_filtering(str
- }
-
- if (vlan_filtering) {
-- /* Use port based VLAN tag */
-+ /* Use tag based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_VSR,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
-@@ -788,7 +788,7 @@ static int gswip_port_vlan_filtering(str
- gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0,
- GSWIP_PCE_PCTRL_0p(port));
- } else {
-- /* Use port based VLAN tag */
-+ /* Use port based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
- GSWIP_PCE_VCTRL_VEMR,
diff --git a/target/linux/lantiq/patches-6.6/0741-v6.11-net-dsa-lantiq_gswip-Update-comments-in-gswip_port_vlan.patch b/target/linux/lantiq/patches-6.6/0741-v6.11-net-dsa-lantiq_gswip-Update-comments-in-gswip_port_vlan.patch
new file mode 100644
index 0000000000..16702c9356
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0741-v6.11-net-dsa-lantiq_gswip-Update-comments-in-gswip_port_vlan.patch
@@ -0,0 +1,41 @@
+From e19fbe3996aae35a467ebad35ff2b8d84975a65c Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:33 +0200
+Subject: net: dsa: lantiq_gswip: Update comments in
+ gswip_port_vlan_filtering()
+
+Update the comments in gswip_port_vlan_filtering() so it's clear that
+there are two separate cases, one for "tag based VLAN" and another one
+for "port based VLAN".
+
+Suggested-by: Martin Schiller <ms@dev.tdt.de>
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://lore.kernel.org/r/20240611135434.3180973-12-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -773,7 +773,7 @@ static int gswip_port_vlan_filtering(str
+ }
+
+ if (vlan_filtering) {
+- /* Use port based VLAN tag */
++ /* Use tag based VLAN */
+ gswip_switch_mask(priv,
+ GSWIP_PCE_VCTRL_VSR,
+ GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
+@@ -782,7 +782,7 @@ static int gswip_port_vlan_filtering(str
+ gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0,
+ GSWIP_PCE_PCTRL_0p(port));
+ } else {
+- /* Use port based VLAN tag */
++ /* Use port based VLAN */
+ gswip_switch_mask(priv,
+ GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
+ GSWIP_PCE_VCTRL_VEMR,
diff --git a/target/linux/lantiq/patches-6.6/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch b/target/linux/lantiq/patches-6.6/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch
deleted file mode 100644
index 3d284c2ea6..0000000000
--- a/target/linux/lantiq/patches-6.6/0742-net-dsa-lantiq_gswip-Add-and-use-a-GSWIP_TABLE_MAC_B.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 4775f9543e691d9a2f5dd9aa5d46c66d37928250 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:19:05 +0200
-Subject: [PATCH 742/768] net: dsa: lantiq_gswip: Add and use a
- GSWIP_TABLE_MAC_BRIDGE_FID macro
-
-Only bits [5:0] in mac_bridge.key[3] are reserved for the FID. Add a
-macro so this becomes obvious when reading the driver code.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -238,6 +238,7 @@
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
- #define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
- #define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-+#define GSWIP_TABLE_MAC_BRIDGE_FID GENMASK(5, 0) /* Filtering identifier */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1378,7 +1379,7 @@ static int gswip_port_fdb(struct dsa_swi
- mac_bridge.key[0] = addr[5] | (addr[4] << 8);
- mac_bridge.key[1] = addr[3] | (addr[2] << 8);
- mac_bridge.key[2] = addr[1] | (addr[0] << 8);
-- mac_bridge.key[3] = fid;
-+ mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_FID, fid);
- mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */
- mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_STATIC;
- mac_bridge.valid = add;
diff --git a/target/linux/lantiq/patches-6.6/0742-v6.11-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch b/target/linux/lantiq/patches-6.6/0742-v6.11-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
new file mode 100644
index 0000000000..56d882c9f9
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0742-v6.11-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
@@ -0,0 +1,30 @@
+From 3b0a95ed7782dce88a5ef4860dcaab962cec9527 Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Tue, 11 Jun 2024 15:54:34 +0200
+Subject: net: dsa: lantiq_gswip: Improve error message in gswip_port_fdb()
+
+Print that no FID is found for bridge %s instead of the incorrect
+message that the port is not part of a bridge.
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://lore.kernel.org/r/20240611135434.3180973-13-ms@dev.tdt.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -1363,7 +1363,8 @@ static int gswip_port_fdb(struct dsa_swi
+ }
+
+ if (fid == -1) {
+- dev_err(priv->dev, "Port not part of a bridge\n");
++ dev_err(priv->dev, "no FID found for bridge %s\n",
++ bridge->name);
+ return -EINVAL;
+ }
+
diff --git a/target/linux/lantiq/patches-6.6/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch b/target/linux/lantiq/patches-6.6/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
deleted file mode 100644
index 5c756c5a19..0000000000
--- a/target/linux/lantiq/patches-6.6/0743-net-dsa-lantiq_gswip-Improve-error-message-in-gswip_.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 00b5121435ccd4ce54f79179dd9ee3e2610d7dcf Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 16:31:57 +0200
-Subject: [PATCH 743/768] net: dsa: lantiq_gswip: Improve error message in
- gswip_port_fdb()
-
-Print the port which is not found to be part of a bridge so it's easier
-to investigate the underlying issue.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1370,7 +1370,8 @@ static int gswip_port_fdb(struct dsa_swi
- }
-
- if (fid == -1) {
-- dev_err(priv->dev, "Port not part of a bridge\n");
-+ dev_err(priv->dev,
-+ "Port %d is not known to be part of bridge\n", port);
- return -EINVAL;
- }
-
diff --git a/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network b/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network
index 2208752c14..27a3c75edc 100644
--- a/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network
+++ b/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network
@@ -110,10 +110,6 @@ lantiq_setup_macs()
lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr)
wan_mac=$(macaddr_add "$lan_mac" 1)
;;
- arcadyan,vgv7510kw22-brn|\
- arcadyan,vgv7510kw22-nor)
- wan_mac=$(macaddr_add "$(mtd_get_mac_binary board_config 0x16)" 2)
- ;;
arcadyan,vgv7519-brn|\
arcadyan,vgv7519-nor|\
arcadyan,vrv9510kwac23)
diff --git a/target/linux/lantiq/xrx200/config-5.15 b/target/linux/lantiq/xrx200/config-5.15
deleted file mode 100644
index 1b87ad65f0..0000000000
--- a/target/linux/lantiq/xrx200/config-5.15
+++ /dev/null
@@ -1,91 +0,0 @@
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_EXTRA_FIRMWARE="lantiq/xrx200_phy11g_a14.bin lantiq/xrx200_phy11g_a22.bin lantiq/xrx200_phy22f_a14.bin lantiq/xrx200_phy22f_a22.bin"
-CONFIG_EXTRA_FIRMWARE_DIR="firmware"
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GRO_CELLS=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_IFX_VPE_EXT=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INTEL_XWAY_PHY=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_XRX200=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MIPS_MT=y
-# CONFIG_MIPS_MT_FPAFF is not set
-CONFIG_MIPS_MT_SMP=y
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_VPE_APSP_API=y
-CONFIG_MIPS_VPE_APSP_API_MT=y
-CONFIG_MIPS_VPE_LOADER=y
-CONFIG_MIPS_VPE_LOADER_MT=y
-CONFIG_MIPS_VPE_LOADER_TOM=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_MTD_NAND_XWAY=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_LANTIQ_GSWIP=y
-CONFIG_NET_DSA_TAG_GSWIP=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=2
-CONFIG_PADATA=y
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_LANTIQ=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_PHYLINK=y
-CONFIG_PHY_LANTIQ_VRX200_PCIE=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_POWER_SUPPLY_HWMON=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_SENSORS_LTQ_CPUTEMP=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=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_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/lantiq/xrx200/config-6.1 b/target/linux/lantiq/xrx200/config-6.1
deleted file mode 100644
index dc41fe0ca8..0000000000
--- a/target/linux/lantiq/xrx200/config-6.1
+++ /dev/null
@@ -1,96 +0,0 @@
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_EXTRA_FIRMWARE="lantiq/xrx200_phy11g_a14.bin lantiq/xrx200_phy11g_a22.bin lantiq/xrx200_phy22f_a14.bin lantiq/xrx200_phy22f_a22.bin"
-CONFIG_EXTRA_FIRMWARE_DIR="firmware"
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GRO_CELLS=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_IFX_VPE_EXT=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INTEL_XWAY_PHY=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_XRX200=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MIPS_MT=y
-# CONFIG_MIPS_MT_FPAFF is not set
-CONFIG_MIPS_MT_SMP=y
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_VPE_APSP_API=y
-CONFIG_MIPS_VPE_APSP_API_MT=y
-CONFIG_MIPS_VPE_LOADER=y
-CONFIG_MIPS_VPE_LOADER_MT=y
-CONFIG_MIPS_VPE_LOADER_TOM=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_MTD_NAND_XWAY=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_LANTIQ_GSWIP=y
-CONFIG_NET_DSA_TAG_GSWIP=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=2
-CONFIG_PADATA=y
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_LANTIQ=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_PHYLINK=y
-CONFIG_PHY_LANTIQ_VRX200_PCIE=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_POWER_SUPPLY_HWMON=y
-CONFIG_QCOM_NET_PHYLIB=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_SENSORS_LTQ_CPUTEMP=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=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_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/lantiq/xway/config-5.15 b/target/linux/lantiq/xway/config-5.15
deleted file mode 100644
index 696ce77860..0000000000
--- a/target/linux/lantiq/xway/config-5.15
+++ /dev/null
@@ -1,76 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_AR8216_PHY=y
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HW_RANDOM=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MIPS_MT=y
-CONFIG_MIPS_MT_FPAFF=y
-CONFIG_MIPS_MT_SMP=y
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_XWAY=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=2
-CONFIG_PADATA=y
-CONFIG_PCI=y
-# CONFIG_PCIE_LANTIQ is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_PSB6970_PHY=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTL8306_PHY=y
-CONFIG_RTL8366RB_PHY=y
-CONFIG_RTL8366_SMI=y
-# CONFIG_SCHED_CORE is not set
-CONFIG_SCHED_SMT=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SWCONFIG=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=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_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/lantiq/xway/config-6.1 b/target/linux/lantiq/xway/config-6.1
deleted file mode 100644
index 1fc821575e..0000000000
--- a/target/linux/lantiq/xway/config-6.1
+++ /dev/null
@@ -1,81 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_AR8216_PHY=y
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_HW_RANDOM=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MIPS_MT=y
-CONFIG_MIPS_MT_FPAFF=y
-CONFIG_MIPS_MT_SMP=y
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_XWAY=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=2
-CONFIG_PADATA=y
-CONFIG_PCI=y
-# CONFIG_PCIE_LANTIQ is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_PSB6970_PHY=y
-CONFIG_QCOM_NET_PHYLIB=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTL8306_PHY=y
-CONFIG_RTL8366RB_PHY=y
-CONFIG_RTL8366_SMI=y
-# CONFIG_SCHED_CORE is not set
-CONFIG_SCHED_SMT=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SWCONFIG=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=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_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/lantiq/xway_legacy/config-5.15 b/target/linux/lantiq/xway_legacy/config-5.15
deleted file mode 100644
index ed3ecd8b4d..0000000000
--- a/target/linux/lantiq/xway_legacy/config-5.15
+++ /dev/null
@@ -1,30 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_GENERIC_ALLOCATOR=y
-# CONFIG_GPIO_CDEV is not set
-# CONFIG_GPIO_SYSFS is not set
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-# CONFIG_LEDS_TRIGGER_TIMER is not set
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_NLS=y
-CONFIG_PCI=y
-# CONFIG_PCIE_LANTIQ is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RTL8306_PHY=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SWCONFIG=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/lantiq/xway_legacy/config-6.1 b/target/linux/lantiq/xway_legacy/config-6.1
deleted file mode 100644
index ed3ecd8b4d..0000000000
--- a/target/linux/lantiq/xway_legacy/config-6.1
+++ /dev/null
@@ -1,30 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_GENERIC_ALLOCATOR=y
-# CONFIG_GPIO_CDEV is not set
-# CONFIG_GPIO_SYSFS is not set
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-# CONFIG_LEDS_TRIGGER_TIMER is not set
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_NLS=y
-CONFIG_PCI=y
-# CONFIG_PCIE_LANTIQ is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RTL8306_PHY=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SWCONFIG=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/layerscape/Makefile b/target/linux/layerscape/Makefile
index 30b9fb8f73..e0bc544f43 100644
--- a/target/linux/layerscape/Makefile
+++ b/target/linux/layerscape/Makefile
@@ -7,8 +7,7 @@ include $(TOPDIR)/rules.mk
BOARD:=layerscape
BOARDNAME:=NXP Layerscape
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
FEATURES:=squashfs nand usb pcie gpio fpu ubifs ext4 rootfs-part boot-part
SUBTARGETS:=armv8_64b armv7
diff --git a/target/linux/layerscape/armv7/config-6.1 b/target/linux/layerscape/armv7/config-6.1
deleted file mode 100644
index d60e5824db..0000000000
--- a/target/linux/layerscape/armv7/config-6.1
+++ /dev/null
@@ -1,699 +0,0 @@
-CONFIG_AD525X_DPOT=y
-CONFIG_AD525X_DPOT_I2C=y
-# CONFIG_AD525X_DPOT_SPI is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_APDS9802ALS=y
-CONFIG_AQUANTIA_PHY=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_MXC=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_ARM_CPUIDLE=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_ERRATA_430973=y
-CONFIG_ARM_ERRATA_643719=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_ARM_GIC=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-# CONFIG_ARM_HIGHBANK_CPUIDLE is not set
-# CONFIG_ARM_IMX8M_DDRC_DEVFREQ is not set
-# CONFIG_ARM_IMX_BUS_DEVFREQ is not set
-# CONFIG_ARM_IMX_CPUFREQ_DT is not set
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_LPAE=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_PSCI=y
-CONFIG_ARM_PSCI_FW=y
-# CONFIG_ARM_SMMU is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ATAGS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BATTERY_SBS=y
-CONFIG_BCM_NET_PHYLIB=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_BSG=y
-CONFIG_BLK_DEV_BSG_COMMON=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=262144
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_MQ_VIRTIO=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-CONFIG_BRCMSTB_GISB_ARB=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CDROM=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CLKSRC_IMX_GPT=y
-CONFIG_CLKSRC_MMIO=y
-# CONFIG_CLK_IMX8MM is not set
-# CONFIG_CLK_IMX8MN is not set
-# CONFIG_CLK_IMX8MP is not set
-# CONFIG_CLK_IMX8MQ is not set
-# CONFIG_CLK_IMX8ULP is not set
-# CONFIG_CLK_IMX93 is not set
-CONFIG_CLK_QORIQ=y
-# CONFIG_CLK_VEXPRESS_OSC is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=64
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_CMDLINE_PARTITION=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_COREDUMP=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_GOV_ATTR_SET=y
-CONFIG_CPU_FREQ_GOV_COMMON=y
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRASH_CORE=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_ALIGN_RODATA=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DECOMPRESS_LZO=y
-CONFIG_DECOMPRESS_XZ=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEVFREQ_GOV_PASSIVE is not set
-# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
-# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
-# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
-# CONFIG_DEVFREQ_GOV_USERSPACE is not set
-# CONFIG_DEVFREQ_THERMAL is not set
-CONFIG_DMADEVICES=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_DT_IDLE_STATES=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_DW_DMAC=y
-CONFIG_DW_DMAC_CORE=y
-CONFIG_DW_WATCHDOG=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_93CX6=y
-CONFIG_EEPROM_AT24=y
-CONFIG_ELF_CORE=y
-# CONFIG_ENABLE_DEFAULT_TRACERS is not set
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_F2FS_FS=y
-CONFIG_FAILOVER=y
-CONFIG_FAT_FS=y
-# CONFIG_FEC is not set
-CONFIG_FHANDLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FREEZER=y
-# CONFIG_FSL_DPAA2_SWITCH is not set
-CONFIG_FSL_EDMA=y
-CONFIG_FSL_GUTS=y
-CONFIG_FSL_IFC=y
-# CONFIG_FSL_PPFE is not set
-CONFIG_FSL_PQ_MDIO=y
-CONFIG_FSL_RCPM=y
-CONFIG_FSL_XGMAC_MDIO=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FTRACE=y
-# CONFIG_FTRACE_SYSCALLS is not set
-CONFIG_FUSE_FS=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_CACHE=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=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_GENERIC_VDSO_32=y
-CONFIG_GIANFAR=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GPIO_MPC8XXX=y
-CONFIG_GPIO_MXC=y
-CONFIG_GPIO_VF610=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HID=y
-CONFIG_HID_GENERIC=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-# CONFIG_HIST_TRIGGERS is not set
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HVC_DRIVER=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_DEMUX_PINCTRL=y
-CONFIG_I2C_DESIGNWARE_CORE=y
-CONFIG_I2C_DESIGNWARE_PLATFORM=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_IMX=y
-# CONFIG_I2C_IMX_LPI2C is not set
-CONFIG_I2C_MUX=y
-CONFIG_I2C_MUX_PCA954x=y
-CONFIG_I2C_MUX_PINCTRL=y
-CONFIG_I2C_RK3X=y
-CONFIG_I2C_SLAVE=y
-CONFIG_I2C_SLAVE_EEPROM=y
-# CONFIG_I2C_SLAVE_TESTUNIT is not set
-CONFIG_I2C_XILINX=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_ICS932S401=y
-CONFIG_IMX2_WDT=y
-# CONFIG_IMX7ULP_WDT is not set
-# CONFIG_IMX8MM_THERMAL is not set
-CONFIG_IMX_DMA=y
-# CONFIG_IMX_GPCV2_PM_DOMAINS is not set
-CONFIG_IMX_INTMUX=y
-# CONFIG_IMX_IRQSTEER is not set
-# CONFIG_IMX_MU_MSI is not set
-CONFIG_IMX_SDMA=y
-# CONFIG_IMX_WEIM is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-# CONFIG_IOMMU_DEBUGFS is not set
-# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IPC_NS=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISDN is not set
-CONFIG_ISL29003=y
-CONFIG_JBD2=y
-CONFIG_KALLSYMS=y
-CONFIG_KCMP=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_XZ is not set
-CONFIG_KEXEC=y
-CONFIG_KEXEC_CORE=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_LIBFDT=y
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LS_EXTIRQ=y
-CONFIG_LS_SCFG_MSI=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MCPM=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-# CONFIG_MDIO_GPIO is not set
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_ISOLATION=y
-# CONFIG_MFD_HI6421_SPMI is not set
-CONFIG_MFD_SYSCON=y
-# CONFIG_MFD_VEXPRESS_SYSREG is not set
-CONFIG_MICREL_PHY=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=16
-# CONFIG_MMC_MXC is not set
-CONFIG_MMC_SDHCI=y
-# CONFIG_MMC_SDHCI_ESDHC_IMX is not set
-CONFIG_MMC_SDHCI_IO_ACCESSORS=y
-CONFIG_MMC_SDHCI_OF_ESDHC=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MSDOS_FS=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_DATAFLASH=y
-# CONFIG_MTD_DATAFLASH_OTP is not set
-# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_FSL_IFC=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SST25L=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-# CONFIG_MTD_UBI_BLOCK is not set
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_MX3_IPU=y
-CONFIG_MX3_IPU_IRQS=4
-CONFIG_MXC_CLK=y
-# CONFIG_MXS_DMA is not set
-CONFIG_NAMESPACES=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEON=y
-CONFIG_NET_FAILOVER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_NS=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=16
-CONFIG_NTFS_FS=y
-CONFIG_NVMEM=y
-# CONFIG_NVMEM_IMX_IIM is not set
-# CONFIG_NVMEM_IMX_OCOTP_ELE is not set
-# CONFIG_NVMEM_SNVS_LPGPR is not set
-# CONFIG_NVMEM_SPMI_SDAM is not set
-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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PACKET_DIAG=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-# CONFIG_PANIC_ON_OOPS is not set
-CONFIG_PANIC_ON_OOPS_VALUE=0
-CONFIG_PANIC_TIMEOUT=0
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_DW=y
-CONFIG_PCIE_DW_HOST=y
-CONFIG_PCIE_PME=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_ECAM=y
-CONFIG_PCI_HOST_COMMON=y
-CONFIG_PCI_HOST_GENERIC=y
-# CONFIG_PCI_IMX6 is not set
-CONFIG_PCI_LAYERSCAPE=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PID_NS=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IMX8ULP is not set
-# CONFIG_PINCTRL_IMX93 is not set
-# CONFIG_PINCTRL_IMXRT1050 is not set
-# CONFIG_PINCTRL_IMXRT1170 is not set
-CONFIG_PL310_ERRATA_588369=y
-CONFIG_PL310_ERRATA_727915=y
-CONFIG_PL310_ERRATA_753970=y
-CONFIG_PL310_ERRATA_769419=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_DEVFREQ=y
-# CONFIG_PM_DEVFREQ_EVENT is not set
-CONFIG_PM_OPP=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_BRCMKONA=y
-CONFIG_POWER_RESET_BRCMSTB=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_RESET_GPIO_RESTART=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_RESET_SYSCON_POWEROFF=y
-CONFIG_POWER_RESET_VEXPRESS=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_CHILDREN=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_PSTORE=y
-CONFIG_PSTORE_COMPRESS=y
-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=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PTP_1588_CLOCK_QORIQ=y
-CONFIG_QORIQ_CPUFREQ=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_GZIP=y
-CONFIG_RD_LZMA=y
-CONFIG_RD_LZO=y
-CONFIG_RD_XZ=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REED_SOLOMON=y
-CONFIG_REED_SOLOMON_DEC8=y
-CONFIG_REED_SOLOMON_ENC8=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_CMOS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_DS3232=y
-CONFIG_RTC_DRV_EM3027=y
-CONFIG_RTC_DRV_FSL_FTM_ALARM=y
-# CONFIG_RTC_DRV_IMXDI is not set
-# CONFIG_RTC_DRV_MXC is not set
-# CONFIG_RTC_DRV_MXC_V2 is not set
-CONFIG_RTC_DRV_PCF2127=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_DEBUG=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SECCOMP=y
-CONFIG_SECCOMP_FILTER=y
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_CONEXANT_DIGICOLOR=y
-CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y
-CONFIG_SERIAL_FSL_LPUART=y
-CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_IMX_EARLYCON=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_ST_ASC=y
-CONFIG_SERIAL_ST_ASC_CONSOLE=y
-CONFIG_SERIAL_XILINX_PS_UART=y
-CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SMSC_PHY=y
-CONFIG_SOCK_DIAG=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BRCMSTB=y
-CONFIG_SOC_BUS=y
-# CONFIG_SOC_IMX50 is not set
-# CONFIG_SOC_IMX51 is not set
-# CONFIG_SOC_IMX53 is not set
-# CONFIG_SOC_IMX6Q is not set
-# CONFIG_SOC_IMX6SL is not set
-# CONFIG_SOC_IMX6SLL is not set
-# CONFIG_SOC_IMX6SX is not set
-# CONFIG_SOC_IMX6UL is not set
-# CONFIG_SOC_IMX7D is not set
-# CONFIG_SOC_IMX7ULP is not set
-# CONFIG_SOC_IMX8M is not set
-# CONFIG_SOC_IMX9 is not set
-CONFIG_SOC_LS1021A=y
-# CONFIG_SOC_VF610 is not set
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_CADENCE=y
-CONFIG_SPI_DYNAMIC=y
-# CONFIG_SPI_FSL_LPSPI is not set
-# CONFIG_SPI_FSL_QUADSPI is not set
-# CONFIG_SPI_IMX is not set
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_SPIDEV=y
-CONFIG_SPI_XILINX=y
-CONFIG_SPMI=y
-# CONFIG_SPMI_HISI3670 is not set
-# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
-CONFIG_SQUASHFS_DECOMP_SINGLE=y
-CONFIG_SQUASHFS_FILE_CACHE=y
-# CONFIG_SQUASHFS_FILE_DIRECT is not set
-CONFIG_SQUASHFS_LZO=y
-CONFIG_SQUASHFS_ZLIB=y
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-CONFIG_STAGING_BOARD=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYSFS_SYSCALL=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNIX_DIAG=y
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USER_NS=y
-CONFIG_USE_OF=y
-CONFIG_UTS_NS=y
-CONFIG_VEXPRESS_CONFIG=y
-CONFIG_VFAT_FS=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VIRTIO=y
-CONFIG_VIRTIO_ANCHOR=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_VIRTIO_CONSOLE=y
-CONFIG_VIRTIO_MMIO=y
-CONFIG_VIRTIO_NET=y
-CONFIG_VIRTIO_PCI=y
-CONFIG_VIRTIO_PCI_LEGACY=y
-CONFIG_VIRTIO_PCI_LIB=y
-CONFIG_VIRTIO_PCI_LIB_LEGACY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XILINX_WATCHDOG=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_XZ_DEC_IA64=y
-CONFIG_XZ_DEC_POWERPC=y
-CONFIG_XZ_DEC_SPARC=y
-CONFIG_XZ_DEC_X86=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/layerscape/armv7/config-6.6 b/target/linux/layerscape/armv7/config-6.6
index 63c49df174..ee397fc7c6 100644
--- a/target/linux/layerscape/armv7/config-6.6
+++ b/target/linux/layerscape/armv7/config-6.6
@@ -206,8 +206,6 @@ CONFIG_ELF_CORE=y
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_F2FS_FS=y
CONFIG_FAILOVER=y
CONFIG_FAT_FS=y
@@ -225,7 +223,6 @@ CONFIG_FSL_RCPM=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FTRACE=y
# CONFIG_FTRACE_SYSCALLS is not set
CONFIG_FUNCTION_ALIGNMENT=0
@@ -652,7 +649,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
diff --git a/target/linux/layerscape/armv8_64b/config-6.1 b/target/linux/layerscape/armv8_64b/config-6.1
deleted file mode 100644
index a2a4a633af..0000000000
--- a/target/linux/layerscape/armv8_64b/config-6.1
+++ /dev/null
@@ -1,905 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_AQUANTIA_PHY=y
-CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
-CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_HIBERNATION_HEADER=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_LAYERSCAPE=y
-CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
-CONFIG_ARCH_MMAP_RND_BITS=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=33
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_NXP=y
-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_ARCH_WANTS_THP_SWAP=y
-CONFIG_ARM64=y
-CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
-CONFIG_ARM64_ERRATUM_1165522=y
-CONFIG_ARM64_ERRATUM_1286807=y
-CONFIG_ARM64_ERRATUM_2051678=y
-CONFIG_ARM64_ERRATUM_2054223=y
-CONFIG_ARM64_ERRATUM_2067961=y
-CONFIG_ARM64_ERRATUM_2077057=y
-CONFIG_ARM64_ERRATUM_2658417=y
-CONFIG_ARM64_ERRATUM_819472=y
-CONFIG_ARM64_ERRATUM_824069=y
-CONFIG_ARM64_ERRATUM_826319=y
-CONFIG_ARM64_ERRATUM_827319=y
-CONFIG_ARM64_ERRATUM_832075=y
-CONFIG_ARM64_ERRATUM_843419=y
-CONFIG_ARM64_HW_AFDBM=y
-CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
-CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
-CONFIG_ARM64_PA_BITS=48
-CONFIG_ARM64_PA_BITS_48=y
-CONFIG_ARM64_PTR_AUTH=y
-CONFIG_ARM64_PTR_AUTH_KERNEL=y
-CONFIG_ARM64_SME=y
-CONFIG_ARM64_SVE=y
-CONFIG_ARM64_TAGGED_ADDR_ABI=y
-CONFIG_ARM64_VA_BITS=48
-# CONFIG_ARM64_VA_BITS_39 is not set
-CONFIG_ARM64_VA_BITS_48=y
-CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
-CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
-CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
-CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=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_FSL_MC=y
-CONFIG_ARM_GIC_V3_ITS_PCI=y
-# CONFIG_ARM_PL172_MPMC is not set
-CONFIG_ARM_PSCI_CPUIDLE=y
-CONFIG_ARM_PSCI_FW=y
-CONFIG_ARM_SMMU=y
-# CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT is not set
-# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set
-CONFIG_ARM_SMMU_V3=y
-# CONFIG_ARM_SMMU_V3_SVA is not set
-CONFIG_ARM_SP805_WATCHDOG=y
-CONFIG_ASM_MODVERSIONS=y
-CONFIG_ASN1=y
-CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
-CONFIG_ATA=y
-CONFIG_AUDIT=y
-CONFIG_AUDITSYSCALL=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_AUDIT_GENERIC=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_AUTOFS_FS=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BALLOON_COMPACTION=y
-CONFIG_BATTERY_BQ27XXX=y
-# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set
-CONFIG_BATTERY_BQ27XXX_I2C=y
-CONFIG_BLK_DEV_BSG=y
-CONFIG_BLK_DEV_BSGLIB=y
-CONFIG_BLK_DEV_BSG_COMMON=y
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_BLK_DEV_INTEGRITY_T10=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=262144
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_MQ_VIRTIO=y
-CONFIG_BLK_PM=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_BTRFS_FS=y
-# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
-CONFIG_BTRFS_FS_POSIX_ACL=y
-CONFIG_CAVIUM_ERRATUM_22375=y
-CONFIG_CAVIUM_ERRATUM_23144=y
-CONFIG_CAVIUM_ERRATUM_23154=y
-CONFIG_CAVIUM_ERRATUM_27456=y
-CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
-CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_CHROME_PLATFORMS=y
-CONFIG_CLK_LS1028A_PLLDIG=y
-CONFIG_CLK_QORIQ=y
-# CONFIG_CLK_VEXPRESS_OSC is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_CS2000_CP=y
-CONFIG_COMMON_CLK_FSL_FLEXSPI=y
-# CONFIG_COMMON_CLK_FSL_SAI is not set
-CONFIG_COMMON_CLK_XGENE=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_COREDUMP=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=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_FREQ_THERMAL=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CRASH_CORE=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRC64=y
-CONFIG_CRC64_ROCKSOFT=y
-CONFIG_CRC7=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRC_T10DIF=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-# CONFIG_CROS_EC is not set
-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_AUTHENC=y
-CONFIG_CRYPTO_BLAKE2B=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRC64_ROCKSOFT=y
-CONFIG_CRYPTO_CRCT10DIF=y
-CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_FSL_CAAM=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y
-# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set
-CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
-CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
-CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ENGINE=y
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA256_ARM64=y
-CONFIG_CRYPTO_SHA2_ARM64_CE=y
-CONFIG_CRYPTO_XTS=y
-CONFIG_CRYPTO_XXHASH=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DECOMPRESS_LZO=y
-CONFIG_DECOMPRESS_XZ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_DIMLIB=y
-CONFIG_DMADEVICES=y
-CONFIG_DMATEST=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_ENGINE_RAID=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DNOTIFY=y
-CONFIG_DPAA2_CONSOLE=y
-CONFIG_DPAA_ERRATUM_A050385=y
-CONFIG_DTC=y
-CONFIG_DT_IDLE_STATES=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-CONFIG_ELF_CORE=y
-# CONFIG_EMBEDDED is not set
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXTCON=y
-CONFIG_EXTCON_USB_GPIO=y
-CONFIG_F2FS_FS=y
-CONFIG_FAILOVER=y
-CONFIG_FANOTIFY=y
-CONFIG_FAT_FS=y
-CONFIG_FB=y
-CONFIG_FB_ARMCLCD=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_CMDLINE=y
-CONFIG_FB_DEFERRED_IO=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_SYS_COPYAREA=y
-CONFIG_FB_SYS_FILLRECT=y
-CONFIG_FB_SYS_FOPS=y
-CONFIG_FB_SYS_IMAGEBLIT=y
-CONFIG_FHANDLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FONT_8x16=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_SUPPORT=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_FREEZER=y
-# CONFIG_FSL_BMAN_TEST is not set
-CONFIG_FSL_DPAA=y
-CONFIG_FSL_DPAA2_ETH=y
-CONFIG_FSL_DPAA2_PTP_CLOCK=y
-# CONFIG_FSL_DPAA2_QDMA is not set
-# CONFIG_FSL_DPAA2_SWITCH is not set
-# CONFIG_FSL_DPAA_CHECKING is not set
-CONFIG_FSL_DPAA_ETH=y
-CONFIG_FSL_EDMA=y
-CONFIG_FSL_ENETC=y
-CONFIG_FSL_ENETC_IERB=y
-CONFIG_FSL_ENETC_MDIO=y
-CONFIG_FSL_ENETC_PTP_CLOCK=y
-CONFIG_FSL_ENETC_VF=y
-CONFIG_FSL_ERRATUM_A008585=y
-CONFIG_FSL_FMAN=y
-CONFIG_FSL_GUTS=y
-CONFIG_FSL_IFC=y
-CONFIG_FSL_MC_BUS=y
-CONFIG_FSL_MC_DPIO=y
-CONFIG_FSL_MC_UAPI_SUPPORT=y
-# CONFIG_FSL_PPFE is not set
-# CONFIG_FSL_QMAN_TEST is not set
-CONFIG_FSL_RCPM=y
-CONFIG_FSL_XGMAC_MDIO=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FUSE_FS=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_CACHE=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
-CONFIG_GARP=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_NUMA=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_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=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_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_GIANFAR is not set
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GPIO_MPC8XXX=y
-CONFIG_GPIO_PCA953X=y
-CONFIG_GPIO_PCA953X_IRQ=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HIBERNATE_CALLBACKS=y
-CONFIG_HIBERNATION=y
-CONFIG_HIBERNATION_SNAPSHOT_DEV=y
-CONFIG_HID=y
-CONFIG_HID_A4TECH=y
-CONFIG_HID_APPLE=y
-CONFIG_HID_BELKIN=y
-CONFIG_HID_CHERRY=y
-CONFIG_HID_CYPRESS=y
-CONFIG_HID_EZKEY=y
-CONFIG_HID_GENERIC=y
-CONFIG_HID_KENSINGTON=y
-CONFIG_HID_MICROSOFT=y
-CONFIG_HID_MONTEREY=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_HVC_DRIVER=y
-CONFIG_HVC_IRQ=y
-CONFIG_HVC_XEN=y
-CONFIG_HVC_XEN_FRONTEND=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_DESIGNWARE_CORE=y
-CONFIG_I2C_DESIGNWARE_PLATFORM=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_IMX=y
-CONFIG_I2C_MUX=y
-CONFIG_I2C_MUX_PCA954x=y
-CONFIG_I2C_RK3X=y
-CONFIG_I2C_SLAVE=y
-# CONFIG_I2C_SLAVE_TESTUNIT is not set
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_IMX2_WDT=y
-CONFIG_INET_DIAG=y
-# CONFIG_INET_DIAG_DESTROY is not set
-# CONFIG_INET_RAW_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_FF_MEMLESS=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_MOUSE=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_VIVALDIFMAP=y
-CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y
-CONFIG_INTERVAL_TREE=y
-CONFIG_IOMMU_API=y
-# CONFIG_IOMMU_DEBUGFS is not set
-# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
-# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set
-CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y
-CONFIG_IOMMU_DMA=y
-CONFIG_IOMMU_IOVA=y
-CONFIG_IOMMU_IO_PGTABLE=y
-# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
-# CONFIG_IOMMU_IO_PGTABLE_DART is not set
-CONFIG_IOMMU_IO_PGTABLE_LPAE=y
-# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IPC_NS=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_BYPASS_MANAGER=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MSI_IOMMU=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISDN is not set
-CONFIG_JBD2=y
-CONFIG_JUMP_LABEL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_KCMP=y
-CONFIG_KEXEC=y
-CONFIG_KEXEC_CORE=y
-CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KSM=y
-CONFIG_LIBCRC32C=y
-CONFIG_LIBFDT=y
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LS_EXTIRQ=y
-CONFIG_LS_SCFG_MSI=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_BUS_MUX=y
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-# CONFIG_MDIO_GPIO is not set
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_BALLOON=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MEMTEST=y
-# CONFIG_MFD_HI6421_SPMI is not set
-CONFIG_MFD_SYSCON=y
-# CONFIG_MFD_VEXPRESS_SYSREG is not set
-CONFIG_MICREL_PHY=y
-CONFIG_MICROSEMI_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=32
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_IO_ACCESSORS=y
-CONFIG_MMC_SDHCI_OF_ESDHC=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMU_NOTIFIER=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_CYAPA is not set
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_BYD=y
-CONFIG_MOUSE_PS2_CYPRESS=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-CONFIG_MOUSE_PS2_FOCALTECH=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SMBUS=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-CONFIG_MPILIB=y
-CONFIG_MRP=y
-CONFIG_MSCC_OCELOT_SWITCH_LIB=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-# CONFIG_MTD_CFI_GEOMETRY is not set
-CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_DATAFLASH=y
-# CONFIG_MTD_DATAFLASH_OTP is not set
-# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_FSL_IFC=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-CONFIG_MTD_SST25L=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MULTIPLEXER=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_MUX_MMIO=y
-CONFIG_MV_XOR_V2=y
-CONFIG_NAMESPACES=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
-CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MSCC_FELIX=y
-CONFIG_NET_DSA_TAG_OCELOT=y
-CONFIG_NET_DSA_TAG_OCELOT_8021Q=y
-CONFIG_NET_FAILOVER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_NS=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NODES_SHIFT=2
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=64
-CONFIG_NUMA=y
-CONFIG_NUMA_BALANCING=y
-CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYERSCAPE_SFP=y
-# CONFIG_NVMEM_SPMI_SDAM is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IOMMU=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NUMA=y
-CONFIG_PACKET_DIAG=y
-CONFIG_PACKING=y
-CONFIG_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_REPORTING=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-# CONFIG_PANIC_ON_OOPS is not set
-CONFIG_PANIC_ON_OOPS_VALUE=0
-CONFIG_PANIC_TIMEOUT=0
-CONFIG_PARAVIRT=y
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_DW=y
-CONFIG_PCIE_DW_HOST=y
-CONFIG_PCIE_LAYERSCAPE_GEN4=y
-CONFIG_PCIE_MOBIVEIL=y
-CONFIG_PCIE_MOBIVEIL_HOST=y
-CONFIG_PCIE_PME=y
-CONFIG_PCI_ATS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_ECAM=y
-CONFIG_PCI_HISI=y
-CONFIG_PCI_HOST_COMMON=y
-CONFIG_PCI_HOST_GENERIC=y
-CONFIG_PCI_IOV=y
-CONFIG_PCI_LAYERSCAPE=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCS_LYNX=y
-CONFIG_PGTABLE_LEVELS=4
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-# CONFIG_PHY_FSL_LYNX_28G is not set
-CONFIG_PHY_XGENE=y
-CONFIG_PID_IN_CONTEXTIDR=y
-CONFIG_PID_NS=y
-CONFIG_PL330_DMA=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_OPP=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_PM_STD_PARTITION=""
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_RESET_VEXPRESS=y
-CONFIG_POWER_RESET_XGENE=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PREEMPT=y
-CONFIG_PREEMPTION=y
-CONFIG_PREEMPT_BUILD=y
-CONFIG_PREEMPT_COUNT=y
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PRINT_QUOTA_WARNING=y
-CONFIG_PROC_CHILDREN=y
-CONFIG_PROFILING=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PTP_1588_CLOCK_QORIQ=y
-CONFIG_QCOM_HIDMA=y
-CONFIG_QCOM_HIDMA_MGMT=y
-CONFIG_QCOM_QDF2400_ERRATUM_0065=y
-# CONFIG_QFMT_V2 is not set
-CONFIG_QORIQ_CPUFREQ=y
-CONFIG_QORIQ_THERMAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_QUOTA=y
-CONFIG_QUOTACTL=y
-CONFIG_RAID6_PQ=y
-# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_GZIP=y
-CONFIG_RD_LZMA=y
-CONFIG_RD_LZO=y
-CONFIG_RD_XZ=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=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_DS1307=y
-CONFIG_RTC_DRV_DS3232=y
-CONFIG_RTC_DRV_FSL_FTM_ALARM=y
-CONFIG_RTC_DRV_PCF2127=y
-CONFIG_RTC_DRV_PL031=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_INFO=y
-CONFIG_SCHED_MC=y
-CONFIG_SCHED_THERMAL_PRESSURE=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SCSI_PROC_FS is not set
-# CONFIG_SCSI_SAS_ATA is not set
-CONFIG_SCSI_SAS_ATTRS=y
-CONFIG_SCSI_SAS_HOST_SMP=y
-CONFIG_SCSI_SAS_LIBSAS=y
-CONFIG_SECCOMP=y
-CONFIG_SECCOMP_FILTER=y
-CONFIG_SECRETMEM=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_FSL_LPUART=y
-CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_SC16IS7XX=y
-CONFIG_SERIAL_SC16IS7XX_CORE=y
-# CONFIG_SERIAL_SC16IS7XX_I2C is not set
-CONFIG_SERIAL_SC16IS7XX_SPI=y
-CONFIG_SERIAL_XILINX_PS_UART=y
-CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
-CONFIG_SERIO=y
-CONFIG_SERIO_AMBAKMI=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-CONFIG_SMP=y
-CONFIG_SOCK_DIAG=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=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_FSL_DSPI=y
-CONFIG_SPI_FSL_QUADSPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_NXP_FLEXSPI=y
-CONFIG_SPI_PL022=y
-CONFIG_SPMI=y
-# CONFIG_SPMI_HISI3670 is not set
-# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
-CONFIG_SQUASHFS_DECOMP_SINGLE=y
-CONFIG_SQUASHFS_FILE_CACHE=y
-# CONFIG_SQUASHFS_FILE_DIRECT is not set
-# CONFIG_SQUASHFS_XZ is not set
-CONFIG_SQUASHFS_ZLIB=y
-CONFIG_SRAM=y
-CONFIG_SRCU=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWIOTLB=y
-CONFIG_SWIOTLB_XEN=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYSFS_SYSCALL=y
-CONFIG_SYS_HYPERVISOR=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_TASK_XACCT=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_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THP_SWAP=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
-# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
-CONFIG_TRANS_TABLE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-# CONFIG_UACCE is not set
-CONFIG_UBIFS_FS=y
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UIO=y
-CONFIG_UIO_AEC=y
-CONFIG_UIO_CIF=y
-CONFIG_UIO_DMEM_GENIRQ=y
-CONFIG_UIO_MF624=y
-CONFIG_UIO_NETX=y
-CONFIG_UIO_PCI_GENERIC=y
-CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_PRUSS is not set
-CONFIG_UIO_SERCOS3=y
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_UNIX_DIAG=y
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USER_NS=y
-CONFIG_USE_PERCPU_NUMA_NODE_ID=y
-CONFIG_UTS_NS=y
-CONFIG_VEXPRESS_CONFIG=y
-CONFIG_VFAT_FS=y
-CONFIG_VFIO=y
-CONFIG_VFIO_FSL_MC=y
-CONFIG_VFIO_IOMMU_TYPE1=y
-# CONFIG_VFIO_MDEV is not set
-# CONFIG_VFIO_NOIOMMU is not set
-CONFIG_VFIO_PCI=y
-CONFIG_VFIO_PCI_CORE=y
-CONFIG_VFIO_PCI_INTX=y
-CONFIG_VFIO_PCI_MMAP=y
-CONFIG_VFIO_VIRQFD=y
-CONFIG_VGA_ARB=y
-CONFIG_VGA_ARB_MAX_GPUS=16
-CONFIG_VIDEOMODE_HELPERS=y
-CONFIG_VIRTIO=y
-CONFIG_VIRTIO_ANCHOR=y
-CONFIG_VIRTIO_BALLOON=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_VIRTIO_CONSOLE=y
-# CONFIG_VIRTIO_IOMMU is not set
-CONFIG_VIRTIO_MMIO=y
-CONFIG_VIRTIO_NET=y
-CONFIG_VIRTIO_PCI=y
-CONFIG_VIRTIO_PCI_LEGACY=y
-CONFIG_VIRTIO_PCI_LIB=y
-CONFIG_VIRTIO_PCI_LIB_LEGACY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_VLAN_8021Q_MVRP=y
-CONFIG_VMAP_STACK=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XARRAY_MULTI=y
-CONFIG_XEN=y
-CONFIG_XENFS=y
-CONFIG_XEN_AUTO_XLATE=y
-CONFIG_XEN_BACKEND=y
-CONFIG_XEN_BALLOON=y
-# CONFIG_XEN_BLKDEV_BACKEND is not set
-CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_COMPAT_XENFS=y
-CONFIG_XEN_DEV_EVTCHN=y
-CONFIG_XEN_DOM0=y
-CONFIG_XEN_FBDEV_FRONTEND=y
-CONFIG_XEN_GNTDEV=y
-CONFIG_XEN_GRANT_DEV_ALLOC=y
-# CONFIG_XEN_NETDEV_BACKEND is not set
-CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_PCIDEV_STUB is not set
-CONFIG_XEN_PRIVCMD=y
-# CONFIG_XEN_PVCALLS_BACKEND is not set
-# CONFIG_XEN_SCSI_FRONTEND is not set
-CONFIG_XEN_SYS_HYPERVISOR=y
-# CONFIG_XEN_VIRTIO is not set
-# CONFIG_XEN_WDT is not set
-CONFIG_XEN_XENBUS_FRONTEND=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
-CONFIG_XOR_BLOCKS=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_XZ_DEC_IA64=y
-CONFIG_XZ_DEC_POWERPC=y
-CONFIG_XZ_DEC_SPARC=y
-CONFIG_XZ_DEC_X86=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/layerscape/armv8_64b/config-6.6 b/target/linux/layerscape/armv8_64b/config-6.6
index f95b4603be..3c052edb7d 100644
--- a/target/linux/layerscape/armv8_64b/config-6.6
+++ b/target/linux/layerscape/armv8_64b/config-6.6
@@ -23,8 +23,6 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
CONFIG_ARM64_ERRATUM_2051678=y
@@ -41,7 +39,6 @@ CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -105,9 +102,6 @@ CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_PM=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_BTRFS_FS=y
-# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
-CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_BUFFER_HEAD=y
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
CONFIG_CAVIUM_ERRATUM_22375=y
@@ -268,8 +262,6 @@ CONFIG_EEPROM_AT24=y
CONFIG_ELF_CORE=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_F2FS_FS=y
@@ -329,7 +321,6 @@ CONFIG_FSL_RCPM=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FUSE_FS=y
@@ -802,7 +793,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
@@ -895,7 +885,6 @@ CONFIG_XEN_SYS_HYPERVISOR=y
# CONFIG_XEN_WDT is not set
CONFIG_XEN_XENBUS_FRONTEND=y
CONFIG_XFS_FS=y
-CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XOR_BLOCKS=y
CONFIG_XPS=y
diff --git a/target/linux/layerscape/armv8_64b/target.mk b/target/linux/layerscape/armv8_64b/target.mk
index c9a61701a9..d880afa7a3 100644
--- a/target/linux/layerscape/armv8_64b/target.mk
+++ b/target/linux/layerscape/armv8_64b/target.mk
@@ -5,6 +5,7 @@
ARCH:=aarch64
BOARDNAME:=ARMv8 64-bit based boards
KERNELNAME:=Image dtbs
+DEPENDS:=+@KERNEL_BTRFS_FS +@KERNEL_BTRFS_FS_POSIX_ACL
define Target/Description
Build firmware images for NXP Layerscape ARMv8 64-bit based boards.
diff --git a/target/linux/layerscape/image/armv7.mk b/target/linux/layerscape/image/armv7.mk
index 916f92eacf..6812d94e1f 100644
--- a/target/linux/layerscape/image/armv7.mk
+++ b/target/linux/layerscape/image/armv7.mk
@@ -6,11 +6,7 @@ define Device/Default
PROFILES := Default
FILESYSTEMS := squashfs
IMAGES := firmware.bin sysupgrade.bin
-ifdef CONFIG_LINUX_6_1
- DEVICE_DTS_DIR := $(DTS_DIR)
-else
DEVICE_DTS_DIR := $(DTS_DIR)/nxp/ls
-endif
KERNEL := kernel-bin | uImage none
KERNEL_INITRAMFS = kernel-bin | gzip | fit gzip $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb
KERNEL_NAME := zImage
diff --git a/target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch b/target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch
deleted file mode 100644
index 70e624a2a9..0000000000
--- a/target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch
+++ /dev/null
@@ -1,288 +0,0 @@
-From 1bb35ff4ce33e65601c8d9c736be52e4aabd6252 Mon Sep 17 00:00:00 2001
-From: Calvin Johnson <calvin.johnson@nxp.com>
-Date: Sat, 16 Sep 2017 14:20:23 +0530
-Subject: [PATCH] arm64: dts: freescale: ls1012a: update with ppfe support
-
-Update ls1012a dtsi and platform dts files with support for ppfe.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
----
- .../boot/dts/freescale/fsl-ls1012a-frdm.dts | 43 +++++++++++++++++
- .../boot/dts/freescale/fsl-ls1012a-frwy.dts | 43 +++++++++++++++++
- .../boot/dts/freescale/fsl-ls1012a-qds.dts | 43 +++++++++++++++++
- .../boot/dts/freescale/fsl-ls1012a-rdb.dts | 47 +++++++++++++++++++
- .../arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 29 ++++++++++++
- 5 files changed, 205 insertions(+)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-@@ -14,6 +14,11 @@
- model = "LS1012A Freedom Board";
- compatible = "fsl,ls1012a-frdm", "fsl,ls1012a";
-
-+ aliases {
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
-+ };
-+
- sys_mclk: clock-mclk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
-@@ -95,6 +100,44 @@
- };
- };
-
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-+
- &qspi {
- status = "okay";
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts
-@@ -14,6 +14,11 @@
- / {
- model = "LS1012A FRWY Board";
- compatible = "fsl,ls1012a-frwy", "fsl,ls1012a";
-+
-+ aliases {
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
-+ };
- };
-
- &duart0 {
-@@ -28,6 +33,44 @@
- status = "okay";
- };
-
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-+
- &qspi {
- status = "okay";
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-@@ -18,6 +18,11 @@
- mmc1 = &esdhc1;
- };
-
-+ aliases {
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
-+ };
-+
- sys_mclk: clock-mclk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
-@@ -132,6 +137,44 @@
- };
- };
- };
-+
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x2>;
-+ phy-mode = "sgmii-2500";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x3>;
-+ phy-mode = "sgmii-2500";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-
- &qspi {
- status = "okay";
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-@@ -16,6 +16,8 @@
-
- aliases {
- serial0 = &duart0;
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
- mmc0 = &esdhc0;
- mmc1 = &esdhc1;
- };
-@@ -86,6 +88,44 @@
- };
- };
-
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */
-+ fsl,gemac-phy-id = < 0x1 >; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "rgmii-txid";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-+
- &qspi {
- status = "okay";
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
-@@ -568,6 +568,35 @@
- };
- };
-
-+ reserved-memory {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ pfe_reserved: packetbuffer@83400000 {
-+ reg = <0 0x83400000 0 0xc00000>;
-+ };
-+ };
-+
-+ pfe: pfe@04000000 {
-+ compatible = "fsl,pfe";
-+ reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */
-+ <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */
-+ reg-names = "pfe", "pfe-ddr";
-+ fsl,pfe-num-interfaces = <0x2>;
-+ interrupts = <0 172 0x4>, /* HIF interrupt */
-+ <0 173 0x4>, /*HIF_NOCPY interrupt */
-+ <0 174 0x4>; /* WoL interrupt */
-+ interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol";
-+ memory-region = <&pfe_reserved>;
-+ fsl,pfe-scfg = <&scfg 0>;
-+ fsl,rcpm-wakeup = <&rcpm 0xf0000020>;
-+ clocks = <&clockgen 4 0>;
-+ clock-names = "pfe";
-+
-+ status = "okay";
-+ };
-+
- firmware {
- optee {
- compatible = "linaro,optee-tz";
diff --git a/target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch b/target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch
deleted file mode 100644
index 5d19cb92dc..0000000000
--- a/target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 9c5c18dbf8e1845d349ef7020f8af5bc9b56ed1f Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Fri, 28 Sep 2022 17:14:32 +0200
-Subject: [PATCH] arm64: dts: ls1012a-frdm/qds: workaround by updating qspi flash to
- single mode
-
-Update rx and tx bus-width to 1 to use single mode to workaround ubifs
-issue found with double mode. (The same method as RDB board)
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 4 ++--
- arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 4 ++--
- 2 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-@@ -148,8 +148,8 @@
- spi-max-frequency = <50000000>;
- m25p,fast-read;
- reg = <0>;
-- spi-rx-bus-width = <2>;
-- spi-tx-bus-width = <2>;
-+ spi-rx-bus-width = <1>;
-+ spi-tx-bus-width = <1>;
- };
- };
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-@@ -186,8 +186,8 @@
- spi-max-frequency = <50000000>;
- m25p,fast-read;
- reg = <0>;
-- spi-rx-bus-width = <2>;
-- spi-tx-bus-width = <2>;
-+ spi-rx-bus-width = <1>;
-+ spi-tx-bus-width = <1>;
- };
- };
-
diff --git a/target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch b/target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch
deleted file mode 100644
index 53cfd193b7..0000000000
--- a/target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 9c5c18dbf8e1845d349ef7020f8af5bc9b56ed1f Mon Sep 17 00:00:00 2001
-From: Kuldeep Singh <kuldeep.singh@nxp.com>
-Date: Tue, 7 Jan 2020 17:14:32 +0530
-Subject: [PATCH] arm64: dts: ls1012a-rdb: workaround by updating qspi flash to
- single mode
-
-Update rx and tx bus-width to 1 to use single mode to workaround ubifs
-issue found with double mode.
-
-[ Leo: Local workaround ]
-
-Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
----
- arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-@@ -136,8 +136,8 @@
- spi-max-frequency = <50000000>;
- m25p,fast-read;
- reg = <0>;
-- spi-rx-bus-width = <2>;
-- spi-tx-bus-width = <2>;
-+ spi-rx-bus-width = <1>;
-+ spi-tx-bus-width = <1>;
- };
- };
-
diff --git a/target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch b/target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch
deleted file mode 100644
index 9bc4e2b520..0000000000
--- a/target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 38093ebbf25eb60a1aa863f46118a68a0300c56e Mon Sep 17 00:00:00 2001
-From: Kuldeep Singh <kuldeep.singh@nxp.com>
-Date: Fri, 3 Jan 2020 14:49:07 +0530
-Subject: [PATCH] arm64: dts: ls1046a-rdb: Update qspi spi-rx-bus-width to 1
-
-Update rx width from quad mode to single mode as a workaround.
-
-[Leo: Local workaround ]
-
-Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
----
- arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
-@@ -104,7 +104,7 @@
- #address-cells = <1>;
- #size-cells = <1>;
- spi-max-frequency = <50000000>;
-- spi-rx-bus-width = <4>;
-+ spi-rx-bus-width = <1>;
- spi-tx-bus-width = <1>;
- reg = <0>;
- };
-@@ -114,7 +114,7 @@
- #address-cells = <1>;
- #size-cells = <1>;
- spi-max-frequency = <50000000>;
-- spi-rx-bus-width = <4>;
-+ spi-rx-bus-width = <1>;
- spi-tx-bus-width = <1>;
- reg = <1>;
- };
diff --git a/target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch b/target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch
deleted file mode 100644
index b06c0f8133..0000000000
--- a/target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 20b1193c8c1d81a8d44ae36e579f70e6fbab45b9 Mon Sep 17 00:00:00 2001
-From: Han Xu <han.xu@nxp.com>
-Date: Tue, 14 Apr 2020 11:58:44 -0500
-Subject: [PATCH] LF-20-3 mtd: spi-nor: Use 1 bit mode of spansion(s25fs512s)
- flash
-
-This is a workaround patch which uses only single bit mode of s25fs512s
-flash
-
-Signed-off-by: Han Xu <han.xu@nxp.com>
-Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
----
- drivers/mtd/spi-nor/spansion.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/spi-nor/spansion.c
-+++ b/drivers/mtd/spi-nor/spansion.c
-@@ -398,8 +398,8 @@ static const struct flash_info spansion_
- MFR_FLAGS(USE_CLSR)
- },
- { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256)
-- NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
- MFR_FLAGS(USE_CLSR)
-+ FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
- .fixups = &s25fs_s_nor_fixups, },
- { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) },
- { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) },
diff --git a/target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch b/target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch
deleted file mode 100644
index a52ac6201f..0000000000
--- a/target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch
+++ /dev/null
@@ -1,11808 +0,0 @@
-From 4bb50554937246443767e89d32e54df7a12396ca Mon Sep 17 00:00:00 2001
-From: Calvin Johnson <calvin.johnson@nxp.com>
-Date: Sat, 16 Sep 2017 07:05:49 +0530
-Subject: [PATCH] staging: add fsl_ppfe driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is squash of all commits with ppfe driver taken from NXP 6.1 tree:
-https://github.com/nxp-qoriq/linux/tree/lf-6.1.y
-
-List of original commits:
-
-net: fsl_ppfe: dts binding for ppfe
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: header files for pfe driver
-
-This patch has all pfe header files.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: introduce pfe driver
-
- This patch introduces Linux support for NXP's LS1012A Packet
-Forwarding Engine (pfe_eth). LS1012A uses hardware packet forwarding
-engine to provide high performance Ethernet interfaces. The device
-includes two Ethernet ports.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: fix RGMII tx delay issue
-
-Recently logic to enable RGMII tx delay was changed by
-below patch.
-
-https://patchwork.kernel.org/patch/9447581/
-
-Based on the patch, appropriate change is made in PFE driver.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: remove unused functions
-
-Remove unused functions hif_xmit_pkt & hif_lib_xmit_pkt.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: fix read/write/ack idx issue
-
-While fixing checkpatch errors some of the index increments
-were commented out. They are enabled.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: Make phy_ethtool_ksettings_get return void
-
-Make return value void since function never return meaningful value
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: add function to update tmu credits
-
-__hif_lib_update_credit function is used to update the tmu credits.
-If tx_qos is set, tmu credit is updated based on the number of packets
-transmitted by tmu.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: Avoid packet drop at TMU queues
-
-Added flow control between TMU queues and PFE Linux driver,
-based on TMU credits availability.
-Added tx_qos module parameter to control this behavior.
-Use queue-0 as default queue to transmit packets.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Akhila Kavi <akhila.kavi@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: Enable PFE in clause 45 mode
-
-when we opearate in clause 45 mode, we need to call
-the function get_phy_device() with its 3rd argument as
-"true" and then the resultant phy device needs to be
-register with phy layer via phy_device_register()
-
-Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
-
-staging: fsl_ppfe/eth: Disable autonegotiation for 2.5G SGMII
-
-PCS initialization sequence for 2.5G SGMII interface governs
-auto negotiation to be in disabled mode
-
-Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
-
-staging: fsl_ppfe/eth: calculate PFE_PKT_SIZE with SKB_DATA_ALIGN
-
-pfe packet size was calculated without considering skb data alignment
-and this resulted in jumbo frames crashing kernel when the
-cacheline size increased from 64 to 128 bytes with
-commit 97303480753e ("arm64: Increase the max granular size").
-
-Modify pfe packet size caclulation to include skb data alignment of
-sizeof(struct skb_shared_info).
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: support for userspace networking
-
-This patch adds the userspace mode support to fsl_ppfe network driver.
-In the new mode, basic hardware initialization is performed in kernel, while
-the datapath and HIF handling is the responsibility of the userspace.
-
-The new command line parameter is added to initialize the ppfe module
-in userspace mode. By default the module remains in kernelspace networking
-mode.
-To enable userspace mode, use "insmod pfe.ko us=1"
-
-Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
-Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
-
-staging: fsl_ppfe/eth: unregister netdev after pfe_phy_exit
-
-rmmod pfe.ko throws below warning:
-
-kernfs: can not remove 'phydev', no directory
-------------[ cut here ]------------
-WARNING: CPU: 0 PID: 2230 at fs/kernfs/dir.c:1481
-kernfs_remove_by_name_ns+0x90/0xa0
-
-This is caused when the unregistered netdev structure is accessed to
-disconnect phy.
-
-Resolve the issue by unregistering netdev after disconnecting phy.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: HW parse results for DPDK
-
-HW Parse results are included in the packet headroom.
-Length and Offset calculation now accommodates parse info size.
-
-Signed-off-by: Archana Madhavan <archana.madhavan@nxp.com>
-
-staging: fsl_ppfe/eth: reorganize pfe_netdev_ops
-
-Reorganize members of struct pfe_netdev_ops to match with the order
-of members in struct net_device_ops defined in include/linux/netdevice.h
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: use mask for rx max frame len
-
-Define and use PFE_RCR_MAX_FL_MASK to properly set Rx max frame
-length of MAC Receive Control Register.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: define pfe ndo_change_mtu function
-
-Define ndo_change_mtu function for pfe. This sets the max Rx frame
-length to the new mtu.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: remove jumbo frame enable from gemac init
-
-MAC Receive Control Register was configured to allow jumbo frames.
-This is removed as jumbo frames can be supported anytime by changing
-mtu which will in turn modify MAX_FL field of MAC RCR.
-Jumbo frames caused pfe to hang on LS1012A rev 1.0 Silicon due to
-erratum A-010897.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: disable CRC removal
-
-Disable CRC removal from the packet, so that packets are forwarded
-as is to Linux.
-CRC configuration in MAC will be reflected in the packet received
-to Linux.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: handle ls1012a errata_a010897
-
-On LS1012A rev 1.0, Jumbo frames are not supported as it causes
-the PFE controller to hang. A reset of the entire chip is required
-to resume normal operation.
-
-To handle this errata, frames with length > 1900 are truncated for
-rev 1.0 of LS1012A.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: replace magic numbers
-
-Replace magic numbers and some cosmetic changes.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: resolve indentation warning
-
-Resolve the following indentation warning:
-
-drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:
-In function ‘pfe_get_gemac_if_proprties’:
-drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:96:2:
-warning: this ‘else’ clause does not guard...
-[-Wmisleading-indentation]
- else
- ^~~~
-drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:98:3:
-note: ...this statement, but the latter is misleadingly indented as
-if it were guarded by the ‘else’
- pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
- ^~~~~
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: add fixed-link support
-
-In cases where MAC is not connected to a normal MDIO-managed PHY
-device, and instead to a switch, it is configured as a "fixed-link".
-Code to handle this scenario is added here.
-
-phy_node in the dtb is checked to identify a fixed-link.
-On identification of a fixed-link, it is registered and connected.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe: add support for a char dev for link status
-
-Read and IOCTL support is added. Application would need to open,
-read/ioctl the /dev/pfe_us_cdev device.
-select is pending as it requires a wait_queue.
-
-Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe: enable hif event from userspace
-
-HIF interrupts are enabled using ioctl from user space,
-and epoll wait from user space wakes up when there is an HIF
-interrupt.
-
-Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
-
-staging: fsl_ppfe: performance tuning for user space
-
-interrupt coalescing of 100 usec is added.
-
-Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
-Signed-off-by: Sachin Saxena <sachin.saxena@nxp.com>
-
-staging: fsl_ppfe/eth: Update to use SPDX identifiers
-
-Replace license text with corresponding SPDX identifiers and update the
-format of existing SPDX identifiers to follow the new guideline
-Documentation/process/license-rules.rst.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: misc clean up
-
-- remove redundant hwfeature init
-- remove unused vars from ls1012a_eth_platform_data
-- To handle ls1012a errata_a010897, PPFE driver requires GUTS driver
-to be compiled in. Select FSL_GUTS when PPFE driver is compiled.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: reorganize platform phy parameters
-
-- Use "phy-handle" and of_* functions to get phy node and fixed-link
-parameters
-
-- Reorganize phy parameters and initialize them only if phy-handle
-or fixed-link is defined in the dtb.
-
-- correct typo pfe_get_gemac_if_proprties to pfe_get_gemac_if_properties
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: support single interface initialization
-
-- arrange members of struct mii_bus in sequence matching phy.h
-- if mdio node is defined, use of_mdiobus_register to register
- child nodes (phy devices) available on the mdio bus.
-- remove of_phy_register_fixed_link from pfe_phy_init as it is being
- handled in pfe_get_gemac_if_properties
-- remove mdio enabled check
-- skip phy init, if no PHY or fixed-link
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-net: fsl_ppfe: update dts properties for phy
-
-Use commonly used phy-handle property and mdio subnode to handle
-phy properties.
-
-Deprecate bindings fsl,gemac-phy-id & fsl,pfe-phy-if-flags.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: remove unused code
-
-- remove gemac-bus-id related code that is unused.
-- remove unused prototype gemac_set_mdc_div.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: separate mdio init from mac init
-
-- separate mdio initialization from mac initialization
-- Define pfe_mdio_priv_s structure to hold mii_bus structure and other
- related data.
-- Modify functions to work with the separted mdio init model.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: adapt to link mode based phydev changes
-
-Setting link mode bits have changed with the integration of
-commit (3c1bcc8 net: ethernet: Convert phydev advertize and
-supported from u32 to link mode). Adapt to the new method of
-setting and clearing the link mode bits.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: use generic soc_device infra instead of fsl_guts_get_svr()
-
-Commit ("soc: fsl: guts: make fsl_guts_get_svr() static") has
-made fsl_guts_get_svr() static and hence use generic soc_device
-infrastructure to check SoC revision.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: use memremap() to map RAM area used by PFE
-
-RAM area used by PFE should be mapped using memremap() instead of
-directly traslating physical addr to virtual. This will ensure proper
-checks are done before the area is used.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: remove 'fallback' argument from dev->ndo_select_queue()
-
-To be consistent with upstream API change.
-
-Signed-off-by: Li Yang <leoyang.li@nxp.com>
-
-staging: fsl_ppfe/eth: prefix header search paths with $(srctree)/
-
-Currently, the rules for configuring search paths in Kbuild have
-changed: https://lkml.org/lkml/2019/5/13/37
-
-This will lead the below error:
-
-fatal error: pfe/pfe.h: No such file or directory
-
-Fix it by adding $(srctree)/ prefix to the search paths.
-
-Signed-off-by: Ting Liu <ting.liu@nxp.com>
-
-staging: fsl_ppfe/eth: add pfe support to Kconfig and Makefile
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-[ Aisheng: fix minor conflict due to removed VBOXSF_FS ]
-Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
-
-staging: fsl_ppfe/eth: Disable termination of CRC fwd.
-
-LS1012A MAC PCS block has an erratum that is seen with specific PHY AR803x.
-The issue is triggered by the (spec-compliant) operation of the AR803x PHY
-on the LS1012A-FRWY board.Due to this, good FCS packet is reported as error
-packet by MAC, so for these error packets FCS should be validated and
-discard only real error packets in PFE Rx packet path.
-
-Signed-off-by: Nagesh Koneti <koneti.nagesh@nxp.com>
-Signed-off-by: Nagesh Koneti <“koneti.nagesh@nxp.com”>
-
-net: ppfe: Cope with of_get_phy_mode() API change
-
-Signed-off-by: Li Yang <leoyang.li@nxp.com>
-
-staging: fsl_ppfe/eth: Enhance error checking in platform probe
-
-Fix the kernel crash when MAC addr is not passed in dtb.
-
-Signed-off-by: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: reject unsupported coalescing params
-
-Set ethtool_ops->supported_coalesce_params to let
-the core reject unsupported coalescing parameters.
-
-Signed-off-by: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth:check "reg" property before pfe_get_gemac_if_properties()
-
-It has been observed that the function pfe_get_gemac_if_properties() is
-been called blindly for the next two child nodes. There might be some
-cases where it may go wrong and that lead to missing interfaces.
-with these changes it is ensured thats not the case.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji J <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: "struct firmware" dereference is reduced in many functions
-
-firmware structure's data variable is the actual elf data. It has been
-dereferenced in multiple functions and this has been reduced.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji J <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: LF-27 load pfe binaries from FDT
-
-FDT prepared in uboot now has pfe firmware part of it.
-These changes will read the firmware by default from it and tries to load
-the elf into the PFE PEs. This help build the pfe driver pasrt of kernel.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji J <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: proper handling for RGMII delay mode
-
-The correct setting for the RGMII ports on LS1012ARDB is to
-enable delay on both Tx and Rx. So the phy mode to be matched
-is PHY_INTERFACE_MODE_RGMII_ID.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-LF-1762-2 staging: fsl_ppfe: replace '---help---' in Kconfig files with 'help'
-
-Update Kconfig to cope with upstream change
-commit 84af7a6194e4 ("checkpatch: kconfig: prefer 'help' over
-'---help---'").
-
-Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
-
-staging: fsl_ppfe/eth: Nesting level does not match indentation
-
-corrected nesting level
-LF-1661 and Coverity CID: 8879316
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Initialized scalar variable
-
-Proper initialization of scalar variable
-LF-1657 and Coverity CID: 3335133
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: misspelt variable name
-
-variable name corrected
-LF-1656 and Coverity CID: 3335119
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoiding out-of-bound writes
-
-avoid out-of-bound writes with proper error handling
-LF-1654, LF-1652 and Coverity CID: 3335106, 3335090
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Initializing scalar variable
-
-proper initialization of scalar variable.
-LF-1653 and Coverity CID: 3335101
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: checking return value
-
-proper checks added and handled for return value.
-LF-1644 and Coverity CID: 241888
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoid out-of-bound access
-
-proper handling to avoid out-of-bound access
-LF-1642, LF-1641 and Coverity CID: 240910, 240891
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoiding out-of-bound writes
-
-avoid out-of-bound writes with proper error handling
-LF-1654, LF-1652 and Coverity CID: 3335106, 3335090
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: return value init in error case
-
-proper err return in error case.
-LF-1806 and Coverity CID: 10468592
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoid recursion in header inclusion
-
-Avoiding header inclusions that are not necessary and also that are
-causing header inclusion recursion.
-
-LF-2102 and Coverity CID: 240838
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoiding return value overwrite
-
-avoid return value overwrite at the end of function.
-LF-2136, LF-2137 and Coverity CID: 8879341, 8879364
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: LF-27 enabling PFE firmware load from FDT
-
-The macro, "LOAD_PFEFIRMWARE_FROM_FILESYSTEM" is been disabled to load
-the firmware from FDT by default. Enabling the macro will load the
-firmware from filesystem.
-
-Also, the Makefile is now tuned to build pfe as per the config option
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Ethtool stats correction for IEEE_rx_drop counter
-
-Due to carrier extended bug the phy counter IEEE_rx_drop counter is
-incremented some times and phy reports the packet has crc error.
-Because of this PFE revalidates all the packets that are marked crc
-error by phy. Now, the counter phy reports is till bogus and this
-patch decrements the counter by pfe revalidated (and are crc ok)
-counter amount.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: PFE firmware load enhancements
-
-PFE driver enhancements to load the PE firmware from filesystem
-when the firmware is not found in FDT.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe: deal with upstream API change of of_get_mac_address()
-
-Uptream commit 83216e398 changed the of_get_mac_address() API, update
-the user accordingly.
-
-Signed-off-by: Li Yang <leoyang.li@nxp.com>
-
-staging: fsl_ppfe: update coalesce setting uAPI usage
-
-API changed since:
-f3ccfda19319 ("ethtool: extend coalesce setting uAPI with CQE mode")
-
-Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
-
-staging: fsl_ppfe: Addressed build warnings
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe: Addressed build warnings
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- .../devicetree/bindings/net/fsl_ppfe/pfe.txt | 199 ++
- MAINTAINERS | 8 +
- drivers/staging/Kconfig | 2 +
- drivers/staging/Makefile | 1 +
- drivers/staging/fsl_ppfe/Kconfig | 21 +
- drivers/staging/fsl_ppfe/Makefile | 20 +
- drivers/staging/fsl_ppfe/TODO | 2 +
- drivers/staging/fsl_ppfe/include/pfe/cbus.h | 78 +
- .../staging/fsl_ppfe/include/pfe/cbus/bmu.h | 55 +
- .../fsl_ppfe/include/pfe/cbus/class_csr.h | 289 ++
- .../fsl_ppfe/include/pfe/cbus/emac_mtip.h | 242 ++
- .../staging/fsl_ppfe/include/pfe/cbus/gpi.h | 86 +
- .../staging/fsl_ppfe/include/pfe/cbus/hif.h | 100 +
- .../fsl_ppfe/include/pfe/cbus/hif_nocpy.h | 50 +
- .../fsl_ppfe/include/pfe/cbus/tmu_csr.h | 168 ++
- .../fsl_ppfe/include/pfe/cbus/util_csr.h | 61 +
- drivers/staging/fsl_ppfe/include/pfe/pfe.h | 372 +++
- drivers/staging/fsl_ppfe/pfe_cdev.c | 258 ++
- drivers/staging/fsl_ppfe/pfe_cdev.h | 41 +
- drivers/staging/fsl_ppfe/pfe_ctrl.c | 226 ++
- drivers/staging/fsl_ppfe/pfe_ctrl.h | 100 +
- drivers/staging/fsl_ppfe/pfe_debugfs.c | 99 +
- drivers/staging/fsl_ppfe/pfe_debugfs.h | 13 +
- drivers/staging/fsl_ppfe/pfe_eth.c | 2588 +++++++++++++++++
- drivers/staging/fsl_ppfe/pfe_eth.h | 175 ++
- drivers/staging/fsl_ppfe/pfe_firmware.c | 398 +++
- drivers/staging/fsl_ppfe/pfe_firmware.h | 21 +
- drivers/staging/fsl_ppfe/pfe_hal.c | 1517 ++++++++++
- drivers/staging/fsl_ppfe/pfe_hif.c | 1063 +++++++
- drivers/staging/fsl_ppfe/pfe_hif.h | 199 ++
- drivers/staging/fsl_ppfe/pfe_hif_lib.c | 628 ++++
- drivers/staging/fsl_ppfe/pfe_hif_lib.h | 229 ++
- drivers/staging/fsl_ppfe/pfe_hw.c | 164 ++
- drivers/staging/fsl_ppfe/pfe_hw.h | 15 +
- .../staging/fsl_ppfe/pfe_ls1012a_platform.c | 383 +++
- drivers/staging/fsl_ppfe/pfe_mod.c | 158 +
- drivers/staging/fsl_ppfe/pfe_mod.h | 103 +
- drivers/staging/fsl_ppfe/pfe_perfmon.h | 26 +
- drivers/staging/fsl_ppfe/pfe_sysfs.c | 840 ++++++
- drivers/staging/fsl_ppfe/pfe_sysfs.h | 17 +
- 40 files changed, 11015 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
- create mode 100644 drivers/staging/fsl_ppfe/Kconfig
- create mode 100644 drivers/staging/fsl_ppfe/Makefile
- create mode 100644 drivers/staging/fsl_ppfe/TODO
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pfe.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hal.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_perfmon.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
-@@ -0,0 +1,199 @@
-+=============================================================================
-+NXP Programmable Packet Forwarding Engine Device Bindings
-+
-+CONTENTS
-+ - PFE Node
-+ - Ethernet Node
-+
-+=============================================================================
-+PFE Node
-+
-+DESCRIPTION
-+
-+PFE Node has all the properties associated with Packet Forwarding Engine block.
-+
-+PROPERTIES
-+
-+- compatible
-+ Usage: required
-+ Value type: <stringlist>
-+ Definition: Must include "fsl,pfe"
-+
-+- reg
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: A standard property.
-+ Specifies the offset of the following registers:
-+ - PFE configuration registers
-+ - DDR memory used by PFE
-+
-+- fsl,pfe-num-interfaces
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value can be either one or two.
-+
-+- interrupts
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: Three interrupts are specified in this property.
-+ - HIF interrupt
-+ - HIF NO COPY interrupt
-+ - Wake On LAN interrupt
-+
-+- interrupt-names
-+ Usage: required
-+ Value type: <stringlist>
-+ Definition: Following strings are defined for the 3 interrupts.
-+ "pfe_hif" - HIF interrupt
-+ "pfe_hif_nocpy" - HIF NO COPY interrupt
-+ "pfe_wol" - Wake On LAN interrupt
-+
-+- memory-region
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle to a node describing reserved memory used by pfe.
-+ Refer:- Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
-+
-+- fsl,pfe-scfg
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle for scfg.
-+
-+- fsl,rcpm-wakeup
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle for rcpm.
-+
-+- clocks
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle for clockgen.
-+
-+- clock-names
-+ Usage: required
-+ Value type: <string>
-+ Definition: phandle for clock name.
-+
-+EXAMPLE
-+
-+pfe: pfe@04000000 {
-+ compatible = "fsl,pfe";
-+ reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */
-+ <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */
-+ reg-names = "pfe", "pfe-ddr";
-+ fsl,pfe-num-interfaces = <0x2>;
-+ interrupts = <0 172 0x4>, /* HIF interrupt */
-+ <0 173 0x4>, /*HIF_NOCPY interrupt */
-+ <0 174 0x4>; /* WoL interrupt */
-+ interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol";
-+ memory-region = <&pfe_reserved>;
-+ fsl,pfe-scfg = <&scfg 0>;
-+ fsl,rcpm-wakeup = <&rcpm 0xf0000020>;
-+ clocks = <&clockgen 4 0>;
-+ clock-names = "pfe";
-+
-+ status = "okay";
-+ pfe_mac0: ethernet@0 {
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ };
-+};
-+
-+=============================================================================
-+Ethernet Node
-+
-+DESCRIPTION
-+
-+Ethernet Node has all the properties associated with PFE used by platforms to
-+connect to PHY:
-+
-+PROPERTIES
-+
-+- compatible
-+ Usage: required
-+ Value type: <stringlist>
-+ Definition: Must include "fsl,pfe-gemac-port"
-+
-+- reg
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: A standard property.
-+ Specifies the gemacid of the interface.
-+
-+- fsl,gemac-bus-id
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value should be the id of the bus
-+ connected to gemac.
-+
-+- fsl,gemac-phy-id (deprecated binding)
-+ Usage: required
-+ Value type: <u32>
-+ Definition: This binding shouldn't be used with new platforms.
-+ Must be present. Value should be the id of the phy
-+ connected to gemac.
-+
-+- fsl,mdio-mux-val
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value can be either 0 or 2 or 3.
-+ This value is used to configure the mux to enable mdio.
-+
-+- phy-mode
-+ Usage: required
-+ Value type: <string>
-+ Definition: Must include "sgmii"
-+
-+- fsl,pfe-phy-if-flags (deprecated binding)
-+ Usage: required
-+ Value type: <u32>
-+ Definition: This binding shouldn't be used with new platforms.
-+ Must be present. Value should be 0 by default.
-+ If there is not phy connected, this need to be 1.
-+
-+- phy-handle
-+ Usage: optional
-+ Value type: <phandle>
-+ Definition: phandle to the PHY device connected to this device.
-+
-+- mdio : A required subnode which specifies the mdio bus in the PFE and used as
-+a container for phy nodes according to ../phy.txt.
-+
-+EXAMPLE
-+
-+ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ phy-handle = <&sgmii_phy1>;
-+};
-+
-+
-+ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ phy-handle = <&sgmii_phy2>;
-+};
-+
-+mdio@0 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ sgmii_phy1: ethernet-phy@2 {
-+ reg = <0x2>;
-+ };
-+
-+ sgmii_phy2: ethernet-phy@1 {
-+ reg = <0x1>;
-+ };
-+};
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -8255,6 +8255,14 @@ F: drivers/ptp/ptp_qoriq.c
- F: drivers/ptp/ptp_qoriq_debugfs.c
- F: include/linux/fsl/ptp_qoriq.h
-
-+FREESCALE QORIQ PPFE ETHERNET DRIVER
-+M: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-+M: Calvin Johnson <calvin.johnson@nxp.com>
-+L: netdev@vger.kernel.org
-+S: Maintained
-+F: drivers/staging/fsl_ppfe
-+F: Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
-+
- FREESCALE QUAD SPI DRIVER
- M: Han Xu <han.xu@nxp.com>
- L: linux-spi@vger.kernel.org
---- a/drivers/staging/Kconfig
-+++ b/drivers/staging/Kconfig
-@@ -80,4 +80,6 @@ source "drivers/staging/qlge/Kconfig"
-
- source "drivers/staging/vme_user/Kconfig"
-
-+source "drivers/staging/fsl_ppfe/Kconfig"
-+
- endif # STAGING
---- a/drivers/staging/Makefile
-+++ b/drivers/staging/Makefile
-@@ -29,3 +29,4 @@ obj-$(CONFIG_PI433) += pi433/
- obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
- obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
- obj-$(CONFIG_QLGE) += qlge/
-+obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/Kconfig
-@@ -0,0 +1,21 @@
-+#
-+# Freescale Programmable Packet Forwarding Engine driver
-+#
-+config FSL_PPFE
-+ tristate "Freescale PPFE Driver"
-+ select FSL_GUTS
-+ default n
-+ help
-+ Freescale LS1012A SoC has a Programmable Packet Forwarding Engine.
-+ It provides two high performance ethernet interfaces.
-+ This driver initializes, programs and controls the PPFE.
-+ Use this driver to enable network connectivity on LS1012A platforms.
-+
-+if FSL_PPFE
-+
-+config FSL_PPFE_UTIL_DISABLED
-+ bool "Disable PPFE UTIL Processor Engine"
-+ help
-+ UTIL PE has to be enabled only if required.
-+
-+endif # FSL_PPFE
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/Makefile
-@@ -0,0 +1,20 @@
-+#
-+# Makefile for Freesecale PPFE driver
-+#
-+
-+ccflags-y += -I $(srctree)/$(src)/include -I $(srctree)/$(src)
-+
-+obj-$(CONFIG_FSL_PPFE) += pfe.o
-+
-+pfe-y += pfe_mod.o \
-+ pfe_hw.o \
-+ pfe_firmware.o \
-+ pfe_ctrl.o \
-+ pfe_hif.o \
-+ pfe_hif_lib.o\
-+ pfe_eth.o \
-+ pfe_sysfs.o \
-+ pfe_debugfs.o \
-+ pfe_ls1012a_platform.o \
-+ pfe_hal.o \
-+ pfe_cdev.o
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/TODO
-@@ -0,0 +1,2 @@
-+TODO:
-+ - provide pfe pe monitoring support
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus.h
-@@ -0,0 +1,78 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _CBUS_H_
-+#define _CBUS_H_
-+
-+#define EMAC1_BASE_ADDR (CBUS_BASE_ADDR + 0x200000)
-+#define EGPI1_BASE_ADDR (CBUS_BASE_ADDR + 0x210000)
-+#define EMAC2_BASE_ADDR (CBUS_BASE_ADDR + 0x220000)
-+#define EGPI2_BASE_ADDR (CBUS_BASE_ADDR + 0x230000)
-+#define BMU1_BASE_ADDR (CBUS_BASE_ADDR + 0x240000)
-+#define BMU2_BASE_ADDR (CBUS_BASE_ADDR + 0x250000)
-+#define ARB_BASE_ADDR (CBUS_BASE_ADDR + 0x260000)
-+#define DDR_CONFIG_BASE_ADDR (CBUS_BASE_ADDR + 0x270000)
-+#define HIF_BASE_ADDR (CBUS_BASE_ADDR + 0x280000)
-+#define HGPI_BASE_ADDR (CBUS_BASE_ADDR + 0x290000)
-+#define LMEM_BASE_ADDR (CBUS_BASE_ADDR + 0x300000)
-+#define LMEM_SIZE 0x10000
-+#define LMEM_END (LMEM_BASE_ADDR + LMEM_SIZE)
-+#define TMU_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x310000)
-+#define CLASS_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x320000)
-+#define HIF_NOCPY_BASE_ADDR (CBUS_BASE_ADDR + 0x350000)
-+#define UTIL_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x360000)
-+#define CBUS_GPT_BASE_ADDR (CBUS_BASE_ADDR + 0x370000)
-+
-+/*
-+ * defgroup XXX_MEM_ACCESS_ADDR PE memory access through CSR
-+ * XXX_MEM_ACCESS_ADDR register bit definitions.
-+ */
-+#define PE_MEM_ACCESS_WRITE BIT(31) /* Internal Memory Write. */
-+#define PE_MEM_ACCESS_IMEM BIT(15)
-+#define PE_MEM_ACCESS_DMEM BIT(16)
-+
-+/* Byte Enables of the Internal memory access. These are interpred in BE */
-+#define PE_MEM_ACCESS_BYTE_ENABLE(offset, size) \
-+ ({ typeof(size) size_ = (size); \
-+ (((BIT(size_) - 1) << (4 - (offset) - (size_))) & 0xf) << 24; })
-+
-+#include "cbus/emac_mtip.h"
-+#include "cbus/gpi.h"
-+#include "cbus/bmu.h"
-+#include "cbus/hif.h"
-+#include "cbus/tmu_csr.h"
-+#include "cbus/class_csr.h"
-+#include "cbus/hif_nocpy.h"
-+#include "cbus/util_csr.h"
-+
-+/* PFE cores states */
-+#define CORE_DISABLE 0x00000000
-+#define CORE_ENABLE 0x00000001
-+#define CORE_SW_RESET 0x00000002
-+
-+/* LMEM defines */
-+#define LMEM_HDR_SIZE 0x0010
-+#define LMEM_BUF_SIZE_LN2 0x7
-+#define LMEM_BUF_SIZE BIT(LMEM_BUF_SIZE_LN2)
-+
-+/* DDR defines */
-+#define DDR_HDR_SIZE 0x0100
-+#define DDR_BUF_SIZE_LN2 0xb
-+#define DDR_BUF_SIZE BIT(DDR_BUF_SIZE_LN2)
-+
-+#endif /* _CBUS_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _BMU_H_
-+#define _BMU_H_
-+
-+#define BMU_VERSION 0x000
-+#define BMU_CTRL 0x004
-+#define BMU_UCAST_CONFIG 0x008
-+#define BMU_UCAST_BASE_ADDR 0x00c
-+#define BMU_BUF_SIZE 0x010
-+#define BMU_BUF_CNT 0x014
-+#define BMU_THRES 0x018
-+#define BMU_INT_SRC 0x020
-+#define BMU_INT_ENABLE 0x024
-+#define BMU_ALLOC_CTRL 0x030
-+#define BMU_FREE_CTRL 0x034
-+#define BMU_FREE_ERR_ADDR 0x038
-+#define BMU_CURR_BUF_CNT 0x03c
-+#define BMU_MCAST_CNT 0x040
-+#define BMU_MCAST_ALLOC_CTRL 0x044
-+#define BMU_REM_BUF_CNT 0x048
-+#define BMU_LOW_WATERMARK 0x050
-+#define BMU_HIGH_WATERMARK 0x054
-+#define BMU_INT_MEM_ACCESS 0x100
-+
-+struct BMU_CFG {
-+ unsigned long baseaddr;
-+ u32 count;
-+ u32 size;
-+ u32 low_watermark;
-+ u32 high_watermark;
-+};
-+
-+#define BMU1_BUF_SIZE LMEM_BUF_SIZE_LN2
-+#define BMU2_BUF_SIZE DDR_BUF_SIZE_LN2
-+
-+#define BMU2_MCAST_ALLOC_CTRL (BMU2_BASE_ADDR + BMU_MCAST_ALLOC_CTRL)
-+
-+#endif /* _BMU_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
-@@ -0,0 +1,289 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _CLASS_CSR_H_
-+#define _CLASS_CSR_H_
-+
-+/* @file class_csr.h.
-+ * class_csr - block containing all the classifier control and status register.
-+ * Mapped on CBUS and accessible from all PE's and ARM.
-+ */
-+#define CLASS_VERSION (CLASS_CSR_BASE_ADDR + 0x000)
-+#define CLASS_TX_CTRL (CLASS_CSR_BASE_ADDR + 0x004)
-+#define CLASS_INQ_PKTPTR (CLASS_CSR_BASE_ADDR + 0x010)
-+
-+/* (ddr_hdr_size[24:16], lmem_hdr_size[5:0]) */
-+#define CLASS_HDR_SIZE (CLASS_CSR_BASE_ADDR + 0x014)
-+
-+/* LMEM header size for the Classifier block.\ Data in the LMEM
-+ * is written from this offset.
-+ */
-+#define CLASS_HDR_SIZE_LMEM(off) ((off) & 0x3f)
-+
-+/* DDR header size for the Classifier block.\ Data in the DDR
-+ * is written from this offset.
-+ */
-+#define CLASS_HDR_SIZE_DDR(off) (((off) & 0x1ff) << 16)
-+
-+#define CLASS_PE0_QB_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x020)
-+
-+/* DMEM address of first [15:0] and second [31:16] buffers on QB side. */
-+#define CLASS_PE0_QB_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x024)
-+
-+/* DMEM address of third [15:0] and fourth [31:16] buffers on QB side. */
-+#define CLASS_PE0_RO_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x060)
-+
-+/* DMEM address of first [15:0] and second [31:16] buffers on RO side. */
-+#define CLASS_PE0_RO_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x064)
-+
-+/* DMEM address of third [15:0] and fourth [31:16] buffers on RO side. */
-+
-+/* @name Class PE memory access. Allows external PE's and HOST to
-+ * read/write PMEM/DMEM memory ranges for each classifier PE.
-+ */
-+/* {sr_pe_mem_cmd[31], csr_pe_mem_wren[27:24], csr_pe_mem_addr[23:0]},
-+ * See \ref XXX_MEM_ACCESS_ADDR for details.
-+ */
-+#define CLASS_MEM_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x100)
-+
-+/* Internal Memory Access Write Data [31:0] */
-+#define CLASS_MEM_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x104)
-+
-+/* Internal Memory Access Read Data [31:0] */
-+#define CLASS_MEM_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x108)
-+#define CLASS_TM_INQ_ADDR (CLASS_CSR_BASE_ADDR + 0x114)
-+#define CLASS_PE_STATUS (CLASS_CSR_BASE_ADDR + 0x118)
-+
-+#define CLASS_PHY1_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x11c)
-+#define CLASS_PHY1_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x120)
-+#define CLASS_PHY1_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x124)
-+#define CLASS_PHY1_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x128)
-+#define CLASS_PHY1_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x12c)
-+#define CLASS_PHY1_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x130)
-+#define CLASS_PHY1_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x134)
-+#define CLASS_PHY1_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x138)
-+#define CLASS_PHY1_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x13c)
-+#define CLASS_PHY1_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x140)
-+#define CLASS_PHY2_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x144)
-+#define CLASS_PHY2_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x148)
-+#define CLASS_PHY2_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x14c)
-+#define CLASS_PHY2_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x150)
-+#define CLASS_PHY2_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x154)
-+#define CLASS_PHY2_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x158)
-+#define CLASS_PHY2_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x15c)
-+#define CLASS_PHY2_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x160)
-+#define CLASS_PHY2_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x164)
-+#define CLASS_PHY2_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x168)
-+#define CLASS_PHY3_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x16c)
-+#define CLASS_PHY3_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x170)
-+#define CLASS_PHY3_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x174)
-+#define CLASS_PHY3_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x178)
-+#define CLASS_PHY3_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x17c)
-+#define CLASS_PHY3_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x180)
-+#define CLASS_PHY3_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x184)
-+#define CLASS_PHY3_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x188)
-+#define CLASS_PHY3_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x18c)
-+#define CLASS_PHY3_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x190)
-+#define CLASS_PHY1_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x194)
-+#define CLASS_PHY1_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x198)
-+#define CLASS_PHY1_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x19c)
-+#define CLASS_PHY1_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a0)
-+#define CLASS_PHY2_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a4)
-+#define CLASS_PHY2_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a8)
-+#define CLASS_PHY2_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1ac)
-+#define CLASS_PHY2_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b0)
-+#define CLASS_PHY3_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b4)
-+#define CLASS_PHY3_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b8)
-+#define CLASS_PHY3_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1bc)
-+#define CLASS_PHY3_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c0)
-+#define CLASS_PHY4_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c4)
-+#define CLASS_PHY4_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c8)
-+#define CLASS_PHY4_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1cc)
-+#define CLASS_PHY4_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1d0)
-+#define CLASS_PHY4_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d4)
-+#define CLASS_PHY4_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d8)
-+#define CLASS_PHY4_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1dc)
-+#define CLASS_PHY4_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e0)
-+#define CLASS_PHY4_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x1e4)
-+#define CLASS_PHY4_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e8)
-+#define CLASS_PHY4_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x1ec)
-+#define CLASS_PHY4_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x1f0)
-+#define CLASS_PHY4_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f4)
-+#define CLASS_PHY4_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f8)
-+
-+#define CLASS_PE_SYS_CLK_RATIO (CLASS_CSR_BASE_ADDR + 0x200)
-+#define CLASS_AFULL_THRES (CLASS_CSR_BASE_ADDR + 0x204)
-+#define CLASS_GAP_BETWEEN_READS (CLASS_CSR_BASE_ADDR + 0x208)
-+#define CLASS_MAX_BUF_CNT (CLASS_CSR_BASE_ADDR + 0x20c)
-+#define CLASS_TSQ_FIFO_THRES (CLASS_CSR_BASE_ADDR + 0x210)
-+#define CLASS_TSQ_MAX_CNT (CLASS_CSR_BASE_ADDR + 0x214)
-+#define CLASS_IRAM_DATA_0 (CLASS_CSR_BASE_ADDR + 0x218)
-+#define CLASS_IRAM_DATA_1 (CLASS_CSR_BASE_ADDR + 0x21c)
-+#define CLASS_IRAM_DATA_2 (CLASS_CSR_BASE_ADDR + 0x220)
-+#define CLASS_IRAM_DATA_3 (CLASS_CSR_BASE_ADDR + 0x224)
-+
-+#define CLASS_BUS_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x228)
-+
-+#define CLASS_BUS_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x22c)
-+#define CLASS_BUS_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x230)
-+
-+/* (route_entry_size[9:0], route_hash_size[23:16]
-+ * (this is actually ln2(size)))
-+ */
-+#define CLASS_ROUTE_HASH_ENTRY_SIZE (CLASS_CSR_BASE_ADDR + 0x234)
-+
-+#define CLASS_ROUTE_ENTRY_SIZE(size) ((size) & 0x1ff)
-+#define CLASS_ROUTE_HASH_SIZE(hash_bits) (((hash_bits) & 0xff) << 16)
-+
-+#define CLASS_ROUTE_TABLE_BASE (CLASS_CSR_BASE_ADDR + 0x238)
-+
-+#define CLASS_ROUTE_MULTI (CLASS_CSR_BASE_ADDR + 0x23c)
-+#define CLASS_SMEM_OFFSET (CLASS_CSR_BASE_ADDR + 0x240)
-+#define CLASS_LMEM_BUF_SIZE (CLASS_CSR_BASE_ADDR + 0x244)
-+#define CLASS_VLAN_ID (CLASS_CSR_BASE_ADDR + 0x248)
-+#define CLASS_BMU1_BUF_FREE (CLASS_CSR_BASE_ADDR + 0x24c)
-+#define CLASS_USE_TMU_INQ (CLASS_CSR_BASE_ADDR + 0x250)
-+#define CLASS_VLAN_ID1 (CLASS_CSR_BASE_ADDR + 0x254)
-+
-+#define CLASS_BUS_ACCESS_BASE (CLASS_CSR_BASE_ADDR + 0x258)
-+#define CLASS_BUS_ACCESS_BASE_MASK (0xFF000000)
-+/* bit 31:24 of PE peripheral address are stored in CLASS_BUS_ACCESS_BASE */
-+
-+#define CLASS_HIF_PARSE (CLASS_CSR_BASE_ADDR + 0x25c)
-+
-+#define CLASS_HOST_PE0_GP (CLASS_CSR_BASE_ADDR + 0x260)
-+#define CLASS_PE0_GP (CLASS_CSR_BASE_ADDR + 0x264)
-+#define CLASS_HOST_PE1_GP (CLASS_CSR_BASE_ADDR + 0x268)
-+#define CLASS_PE1_GP (CLASS_CSR_BASE_ADDR + 0x26c)
-+#define CLASS_HOST_PE2_GP (CLASS_CSR_BASE_ADDR + 0x270)
-+#define CLASS_PE2_GP (CLASS_CSR_BASE_ADDR + 0x274)
-+#define CLASS_HOST_PE3_GP (CLASS_CSR_BASE_ADDR + 0x278)
-+#define CLASS_PE3_GP (CLASS_CSR_BASE_ADDR + 0x27c)
-+#define CLASS_HOST_PE4_GP (CLASS_CSR_BASE_ADDR + 0x280)
-+#define CLASS_PE4_GP (CLASS_CSR_BASE_ADDR + 0x284)
-+#define CLASS_HOST_PE5_GP (CLASS_CSR_BASE_ADDR + 0x288)
-+#define CLASS_PE5_GP (CLASS_CSR_BASE_ADDR + 0x28c)
-+
-+#define CLASS_PE_INT_SRC (CLASS_CSR_BASE_ADDR + 0x290)
-+#define CLASS_PE_INT_ENABLE (CLASS_CSR_BASE_ADDR + 0x294)
-+
-+#define CLASS_TPID0_TPID1 (CLASS_CSR_BASE_ADDR + 0x298)
-+#define CLASS_TPID2 (CLASS_CSR_BASE_ADDR + 0x29c)
-+
-+#define CLASS_L4_CHKSUM_ADDR (CLASS_CSR_BASE_ADDR + 0x2a0)
-+
-+#define CLASS_PE0_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a4)
-+#define CLASS_PE1_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a8)
-+#define CLASS_PE2_DEBUG (CLASS_CSR_BASE_ADDR + 0x2ac)
-+#define CLASS_PE3_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b0)
-+#define CLASS_PE4_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b4)
-+#define CLASS_PE5_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b8)
-+
-+#define CLASS_STATE (CLASS_CSR_BASE_ADDR + 0x2bc)
-+
-+/* CLASS defines */
-+#define CLASS_PBUF_SIZE 0x100 /* Fixed by hardware */
-+#define CLASS_PBUF_HEADER_OFFSET 0x80 /* Can be configured */
-+
-+/* Can be configured */
-+#define CLASS_PBUF0_BASE_ADDR 0x000
-+/* Can be configured */
-+#define CLASS_PBUF1_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_SIZE)
-+/* Can be configured */
-+#define CLASS_PBUF2_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_SIZE)
-+/* Can be configured */
-+#define CLASS_PBUF3_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_SIZE)
-+
-+#define CLASS_PBUF0_HEADER_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+#define CLASS_PBUF1_HEADER_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+#define CLASS_PBUF2_HEADER_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+#define CLASS_PBUF3_HEADER_BASE_ADDR (CLASS_PBUF3_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+
-+#define CLASS_PE0_RO_DM_ADDR0_VAL ((CLASS_PBUF1_BASE_ADDR << 16) | \
-+ CLASS_PBUF0_BASE_ADDR)
-+#define CLASS_PE0_RO_DM_ADDR1_VAL ((CLASS_PBUF3_BASE_ADDR << 16) | \
-+ CLASS_PBUF2_BASE_ADDR)
-+
-+#define CLASS_PE0_QB_DM_ADDR0_VAL ((CLASS_PBUF1_HEADER_BASE_ADDR << 16) |\
-+ CLASS_PBUF0_HEADER_BASE_ADDR)
-+#define CLASS_PE0_QB_DM_ADDR1_VAL ((CLASS_PBUF3_HEADER_BASE_ADDR << 16) |\
-+ CLASS_PBUF2_HEADER_BASE_ADDR)
-+
-+#define CLASS_ROUTE_SIZE 128
-+#define CLASS_MAX_ROUTE_SIZE 256
-+#define CLASS_ROUTE_HASH_BITS 20
-+#define CLASS_ROUTE_HASH_MASK (BIT(CLASS_ROUTE_HASH_BITS) - 1)
-+
-+/* Can be configured */
-+#define CLASS_ROUTE0_BASE_ADDR 0x400
-+/* Can be configured */
-+#define CLASS_ROUTE1_BASE_ADDR (CLASS_ROUTE0_BASE_ADDR + CLASS_ROUTE_SIZE)
-+/* Can be configured */
-+#define CLASS_ROUTE2_BASE_ADDR (CLASS_ROUTE1_BASE_ADDR + CLASS_ROUTE_SIZE)
-+/* Can be configured */
-+#define CLASS_ROUTE3_BASE_ADDR (CLASS_ROUTE2_BASE_ADDR + CLASS_ROUTE_SIZE)
-+
-+#define CLASS_SA_SIZE 128
-+#define CLASS_IPSEC_SA0_BASE_ADDR 0x600
-+/* not used */
-+#define CLASS_IPSEC_SA1_BASE_ADDR (CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE)
-+/* not used */
-+#define CLASS_IPSEC_SA2_BASE_ADDR (CLASS_IPSEC_SA1_BASE_ADDR + CLASS_SA_SIZE)
-+/* not used */
-+#define CLASS_IPSEC_SA3_BASE_ADDR (CLASS_IPSEC_SA2_BASE_ADDR + CLASS_SA_SIZE)
-+
-+/* generic purpose free dmem buffer, last portion of 2K dmem pbuf */
-+#define CLASS_GP_DMEM_BUF_SIZE (2048 - (CLASS_PBUF_SIZE * 4) - \
-+ (CLASS_ROUTE_SIZE * 4) - (CLASS_SA_SIZE))
-+#define CLASS_GP_DMEM_BUF ((void *)(CLASS_IPSEC_SA0_BASE_ADDR + \
-+ CLASS_SA_SIZE))
-+
-+#define TWO_LEVEL_ROUTE BIT(0)
-+#define PHYNO_IN_HASH BIT(1)
-+#define HW_ROUTE_FETCH BIT(3)
-+#define HW_BRIDGE_FETCH BIT(5)
-+#define IP_ALIGNED BIT(6)
-+#define ARC_HIT_CHECK_EN BIT(7)
-+#define CLASS_TOE BIT(11)
-+#define HASH_NORMAL (0 << 12)
-+#define HASH_CRC_PORT BIT(12)
-+#define HASH_CRC_IP (2 << 12)
-+#define HASH_CRC_PORT_IP (3 << 12)
-+#define QB2BUS_LE BIT(15)
-+
-+#define TCP_CHKSUM_DROP BIT(0)
-+#define UDP_CHKSUM_DROP BIT(1)
-+#define IPV4_CHKSUM_DROP BIT(9)
-+
-+/*CLASS_HIF_PARSE bits*/
-+#define HIF_PKT_CLASS_EN BIT(0)
-+#define HIF_PKT_OFFSET(ofst) (((ofst) & 0xF) << 1)
-+
-+struct class_cfg {
-+ u32 toe_mode;
-+ unsigned long route_table_baseaddr;
-+ u32 route_table_hash_bits;
-+ u32 pe_sys_clk_ratio;
-+ u32 resume;
-+};
-+
-+#endif /* _CLASS_CSR_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
-@@ -0,0 +1,242 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _EMAC_H_
-+#define _EMAC_H_
-+
-+#include <linux/ethtool.h>
-+
-+#define EMAC_IEVENT_REG 0x004
-+#define EMAC_IMASK_REG 0x008
-+#define EMAC_R_DES_ACTIVE_REG 0x010
-+#define EMAC_X_DES_ACTIVE_REG 0x014
-+#define EMAC_ECNTRL_REG 0x024
-+#define EMAC_MII_DATA_REG 0x040
-+#define EMAC_MII_CTRL_REG 0x044
-+#define EMAC_MIB_CTRL_STS_REG 0x064
-+#define EMAC_RCNTRL_REG 0x084
-+#define EMAC_TCNTRL_REG 0x0C4
-+#define EMAC_PHY_ADDR_LOW 0x0E4
-+#define EMAC_PHY_ADDR_HIGH 0x0E8
-+#define EMAC_GAUR 0x120
-+#define EMAC_GALR 0x124
-+#define EMAC_TFWR_STR_FWD 0x144
-+#define EMAC_RX_SECTION_FULL 0x190
-+#define EMAC_RX_SECTION_EMPTY 0x194
-+#define EMAC_TX_SECTION_EMPTY 0x1A0
-+#define EMAC_TRUNC_FL 0x1B0
-+
-+#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */
-+#define RMON_T_PACKETS 0x204 /* RMON TX packet count */
-+#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */
-+#define RMON_T_MC_PKT 0x20c /* RMON TX multicast pkts */
-+#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */
-+#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */
-+#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */
-+#define RMON_T_FRAG 0x21c /* RMON TX pkts < 64 bytes, bad CRC */
-+#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */
-+#define RMON_T_COL 0x224 /* RMON TX collision count */
-+#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */
-+#define RMON_T_P65TO127 0x22c /* RMON TX 65 to 127 byte pkts */
-+#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */
-+#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */
-+#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */
-+#define RMON_T_P1024TO2047 0x23c /* RMON TX 1024 to 2047 byte pkts */
-+#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */
-+#define RMON_T_OCTETS 0x244 /* RMON TX octets */
-+#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */
-+#define IEEE_T_FRAME_OK 0x24c /* Frames tx'd OK */
-+#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */
-+#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */
-+#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */
-+#define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */
-+#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */
-+#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */
-+#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */
-+#define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */
-+#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */
-+#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */
-+#define RMON_R_PACKETS 0x284 /* RMON RX packet count */
-+#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */
-+#define RMON_R_MC_PKT 0x28c /* RMON RX multicast pkts */
-+#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */
-+#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */
-+#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */
-+#define RMON_R_FRAG 0x29c /* RMON RX pkts < 64 bytes, bad CRC */
-+#define RMON_R_JAB 0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */
-+#define RMON_R_RESVD_O 0x2a4 /* Reserved */
-+#define RMON_R_P64 0x2a8 /* RMON RX 64 byte pkts */
-+#define RMON_R_P65TO127 0x2ac /* RMON RX 65 to 127 byte pkts */
-+#define RMON_R_P128TO255 0x2b0 /* RMON RX 128 to 255 byte pkts */
-+#define RMON_R_P256TO511 0x2b4 /* RMON RX 256 to 511 byte pkts */
-+#define RMON_R_P512TO1023 0x2b8 /* RMON RX 512 to 1023 byte pkts */
-+#define RMON_R_P1024TO2047 0x2bc /* RMON RX 1024 to 2047 byte pkts */
-+#define RMON_R_P_GTE2048 0x2c0 /* RMON RX pkts > 2048 bytes */
-+#define RMON_R_OCTETS 0x2c4 /* RMON RX octets */
-+#define IEEE_R_DROP 0x2c8 /* Count frames not counted correctly */
-+#define IEEE_R_FRAME_OK 0x2cc /* Frames rx'd OK */
-+#define IEEE_R_CRC 0x2d0 /* Frames rx'd with CRC err */
-+#define IEEE_R_ALIGN 0x2d4 /* Frames rx'd with alignment err */
-+#define IEEE_R_MACERR 0x2d8 /* Receive FIFO overflow count */
-+#define IEEE_R_FDXFC 0x2dc /* Flow control pause frames rx'd */
-+#define IEEE_R_OCTETS_OK 0x2e0 /* Octet cnt for frames rx'd w/o err */
-+
-+#define EMAC_SMAC_0_0 0x500 /*Supplemental MAC Address 0 (RW).*/
-+#define EMAC_SMAC_0_1 0x504 /*Supplemental MAC Address 0 (RW).*/
-+
-+/* GEMAC definitions and settings */
-+
-+#define EMAC_PORT_0 0
-+#define EMAC_PORT_1 1
-+
-+/* GEMAC Bit definitions */
-+#define EMAC_IEVENT_HBERR 0x80000000
-+#define EMAC_IEVENT_BABR 0x40000000
-+#define EMAC_IEVENT_BABT 0x20000000
-+#define EMAC_IEVENT_GRA 0x10000000
-+#define EMAC_IEVENT_TXF 0x08000000
-+#define EMAC_IEVENT_TXB 0x04000000
-+#define EMAC_IEVENT_RXF 0x02000000
-+#define EMAC_IEVENT_RXB 0x01000000
-+#define EMAC_IEVENT_MII 0x00800000
-+#define EMAC_IEVENT_EBERR 0x00400000
-+#define EMAC_IEVENT_LC 0x00200000
-+#define EMAC_IEVENT_RL 0x00100000
-+#define EMAC_IEVENT_UN 0x00080000
-+
-+#define EMAC_IMASK_HBERR 0x80000000
-+#define EMAC_IMASK_BABR 0x40000000
-+#define EMAC_IMASKT_BABT 0x20000000
-+#define EMAC_IMASK_GRA 0x10000000
-+#define EMAC_IMASKT_TXF 0x08000000
-+#define EMAC_IMASK_TXB 0x04000000
-+#define EMAC_IMASKT_RXF 0x02000000
-+#define EMAC_IMASK_RXB 0x01000000
-+#define EMAC_IMASK_MII 0x00800000
-+#define EMAC_IMASK_EBERR 0x00400000
-+#define EMAC_IMASK_LC 0x00200000
-+#define EMAC_IMASKT_RL 0x00100000
-+#define EMAC_IMASK_UN 0x00080000
-+
-+#define EMAC_RCNTRL_MAX_FL_SHIFT 16
-+#define EMAC_RCNTRL_LOOP 0x00000001
-+#define EMAC_RCNTRL_DRT 0x00000002
-+#define EMAC_RCNTRL_MII_MODE 0x00000004
-+#define EMAC_RCNTRL_PROM 0x00000008
-+#define EMAC_RCNTRL_BC_REJ 0x00000010
-+#define EMAC_RCNTRL_FCE 0x00000020
-+#define EMAC_RCNTRL_RGMII 0x00000040
-+#define EMAC_RCNTRL_SGMII 0x00000080
-+#define EMAC_RCNTRL_RMII 0x00000100
-+#define EMAC_RCNTRL_RMII_10T 0x00000200
-+#define EMAC_RCNTRL_CRC_FWD 0x00004000
-+
-+#define EMAC_TCNTRL_GTS 0x00000001
-+#define EMAC_TCNTRL_HBC 0x00000002
-+#define EMAC_TCNTRL_FDEN 0x00000004
-+#define EMAC_TCNTRL_TFC_PAUSE 0x00000008
-+#define EMAC_TCNTRL_RFC_PAUSE 0x00000010
-+
-+#define EMAC_ECNTRL_RESET 0x00000001 /* reset the EMAC */
-+#define EMAC_ECNTRL_ETHER_EN 0x00000002 /* enable the EMAC */
-+#define EMAC_ECNTRL_MAGIC_ENA 0x00000004
-+#define EMAC_ECNTRL_SLEEP 0x00000008
-+#define EMAC_ECNTRL_SPEED 0x00000020
-+#define EMAC_ECNTRL_DBSWAP 0x00000100
-+
-+#define EMAC_X_WMRK_STRFWD 0x00000100
-+
-+#define EMAC_X_DES_ACTIVE_TDAR 0x01000000
-+#define EMAC_R_DES_ACTIVE_RDAR 0x01000000
-+
-+#define EMAC_RX_SECTION_EMPTY_V 0x00010006
-+/*
-+ * The possible operating speeds of the MAC, currently supporting 10, 100 and
-+ * 1000Mb modes.
-+ */
-+enum mac_speed {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS};
-+
-+/* MII-related definitios */
-+#define EMAC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */
-+#define EMAC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */
-+#define EMAC_MII_DATA_OP_CL45_RD 0x30000000 /* Perform a read operation */
-+#define EMAC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */
-+#define EMAC_MII_DATA_OP_CL45_WR 0x10000000 /* Perform a write operation */
-+#define EMAC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */
-+#define EMAC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */
-+#define EMAC_MII_DATA_TA 0x00020000 /* Turnaround */
-+#define EMAC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */
-+
-+#define EMAC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */
-+#define EMAC_MII_DATA_RA_MASK 0x1F /* MII Register address mask */
-+#define EMAC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */
-+#define EMAC_MII_DATA_PA_MASK 0x1F /* MII PHY address mask */
-+
-+#define EMAC_MII_DATA_RA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \
-+ EMAC_MII_DATA_RA_SHIFT)
-+#define EMAC_MII_DATA_PA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \
-+ EMAC_MII_DATA_PA_SHIFT)
-+#define EMAC_MII_DATA(v) ((v) & 0xffff)
-+
-+#define EMAC_MII_SPEED_SHIFT 1
-+#define EMAC_HOLDTIME_SHIFT 8
-+#define EMAC_HOLDTIME_MASK 0x7
-+#define EMAC_HOLDTIME(v) (((v) & EMAC_HOLDTIME_MASK) << \
-+ EMAC_HOLDTIME_SHIFT)
-+
-+/*
-+ * The Address organisation for the MAC device. All addresses are split into
-+ * two 32-bit register fields. The first one (bottom) is the lower 32-bits of
-+ * the address and the other field are the high order bits - this may be 16-bits
-+ * in the case of MAC addresses, or 32-bits for the hash address.
-+ * In terms of memory storage, the first item (bottom) is assumed to be at a
-+ * lower address location than 'top'. i.e. top should be at address location of
-+ * 'bottom' + 4 bytes.
-+ */
-+struct pfe_mac_addr {
-+ u32 bottom; /* Lower 32-bits of address. */
-+ u32 top; /* Upper 32-bits of address. */
-+};
-+
-+/*
-+ * The following is the organisation of the address filters section of the MAC
-+ * registers. The Cadence MAC contains four possible specific address match
-+ * addresses, if an incoming frame corresponds to any one of these four
-+ * addresses then the frame will be copied to memory.
-+ * It is not necessary for all four of the address match registers to be
-+ * programmed, this is application dependent.
-+ */
-+struct spec_addr {
-+ struct pfe_mac_addr one; /* Specific address register 1. */
-+ struct pfe_mac_addr two; /* Specific address register 2. */
-+ struct pfe_mac_addr three; /* Specific address register 3. */
-+ struct pfe_mac_addr four; /* Specific address register 4. */
-+};
-+
-+struct gemac_cfg {
-+ u32 mode;
-+ u32 speed;
-+ u32 duplex;
-+};
-+
-+/* EMAC Hash size */
-+#define EMAC_HASH_REG_BITS 64
-+
-+#define EMAC_SPEC_ADDR_MAX 4
-+
-+#endif /* _EMAC_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _GPI_H_
-+#define _GPI_H_
-+
-+#define GPI_VERSION 0x00
-+#define GPI_CTRL 0x04
-+#define GPI_RX_CONFIG 0x08
-+#define GPI_HDR_SIZE 0x0c
-+#define GPI_BUF_SIZE 0x10
-+#define GPI_LMEM_ALLOC_ADDR 0x14
-+#define GPI_LMEM_FREE_ADDR 0x18
-+#define GPI_DDR_ALLOC_ADDR 0x1c
-+#define GPI_DDR_FREE_ADDR 0x20
-+#define GPI_CLASS_ADDR 0x24
-+#define GPI_DRX_FIFO 0x28
-+#define GPI_TRX_FIFO 0x2c
-+#define GPI_INQ_PKTPTR 0x30
-+#define GPI_DDR_DATA_OFFSET 0x34
-+#define GPI_LMEM_DATA_OFFSET 0x38
-+#define GPI_TMLF_TX 0x4c
-+#define GPI_DTX_ASEQ 0x50
-+#define GPI_FIFO_STATUS 0x54
-+#define GPI_FIFO_DEBUG 0x58
-+#define GPI_TX_PAUSE_TIME 0x5c
-+#define GPI_LMEM_SEC_BUF_DATA_OFFSET 0x60
-+#define GPI_DDR_SEC_BUF_DATA_OFFSET 0x64
-+#define GPI_TOE_CHKSUM_EN 0x68
-+#define GPI_OVERRUN_DROPCNT 0x6c
-+#define GPI_CSR_MTIP_PAUSE_REG 0x74
-+#define GPI_CSR_MTIP_PAUSE_QUANTUM 0x78
-+#define GPI_CSR_RX_CNT 0x7c
-+#define GPI_CSR_TX_CNT 0x80
-+#define GPI_CSR_DEBUG1 0x84
-+#define GPI_CSR_DEBUG2 0x88
-+
-+struct gpi_cfg {
-+ u32 lmem_rtry_cnt;
-+ u32 tmlf_txthres;
-+ u32 aseq_len;
-+ u32 mtip_pause_reg;
-+};
-+
-+/* GPI commons defines */
-+#define GPI_LMEM_BUF_EN 0x1
-+#define GPI_DDR_BUF_EN 0x1
-+
-+/* EGPI 1 defines */
-+#define EGPI1_LMEM_RTRY_CNT 0x40
-+#define EGPI1_TMLF_TXTHRES 0xBC
-+#define EGPI1_ASEQ_LEN 0x50
-+
-+/* EGPI 2 defines */
-+#define EGPI2_LMEM_RTRY_CNT 0x40
-+#define EGPI2_TMLF_TXTHRES 0xBC
-+#define EGPI2_ASEQ_LEN 0x40
-+
-+/* EGPI 3 defines */
-+#define EGPI3_LMEM_RTRY_CNT 0x40
-+#define EGPI3_TMLF_TXTHRES 0xBC
-+#define EGPI3_ASEQ_LEN 0x40
-+
-+/* HGPI defines */
-+#define HGPI_LMEM_RTRY_CNT 0x40
-+#define HGPI_TMLF_TXTHRES 0xBC
-+#define HGPI_ASEQ_LEN 0x40
-+
-+#define EGPI_PAUSE_TIME 0x000007D0
-+#define EGPI_PAUSE_ENABLE 0x40000000
-+#endif /* _GPI_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
-@@ -0,0 +1,100 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _HIF_H_
-+#define _HIF_H_
-+
-+/* @file hif.h.
-+ * hif - PFE hif block control and status register.
-+ * Mapped on CBUS and accessible from all PE's and ARM.
-+ */
-+#define HIF_VERSION (HIF_BASE_ADDR + 0x00)
-+#define HIF_TX_CTRL (HIF_BASE_ADDR + 0x04)
-+#define HIF_TX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x08)
-+#define HIF_TX_ALLOC (HIF_BASE_ADDR + 0x0c)
-+#define HIF_TX_BDP_ADDR (HIF_BASE_ADDR + 0x10)
-+#define HIF_TX_STATUS (HIF_BASE_ADDR + 0x14)
-+#define HIF_RX_CTRL (HIF_BASE_ADDR + 0x20)
-+#define HIF_RX_BDP_ADDR (HIF_BASE_ADDR + 0x24)
-+#define HIF_RX_STATUS (HIF_BASE_ADDR + 0x30)
-+#define HIF_INT_SRC (HIF_BASE_ADDR + 0x34)
-+#define HIF_INT_ENABLE (HIF_BASE_ADDR + 0x38)
-+#define HIF_POLL_CTRL (HIF_BASE_ADDR + 0x3c)
-+#define HIF_RX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x40)
-+#define HIF_RX_ALLOC (HIF_BASE_ADDR + 0x44)
-+#define HIF_TX_DMA_STATUS (HIF_BASE_ADDR + 0x48)
-+#define HIF_RX_DMA_STATUS (HIF_BASE_ADDR + 0x4c)
-+#define HIF_INT_COAL (HIF_BASE_ADDR + 0x50)
-+
-+/* HIF_INT_SRC/ HIF_INT_ENABLE control bits */
-+#define HIF_INT BIT(0)
-+#define HIF_RXBD_INT BIT(1)
-+#define HIF_RXPKT_INT BIT(2)
-+#define HIF_TXBD_INT BIT(3)
-+#define HIF_TXPKT_INT BIT(4)
-+
-+/* HIF_TX_CTRL bits */
-+#define HIF_CTRL_DMA_EN BIT(0)
-+#define HIF_CTRL_BDP_POLL_CTRL_EN BIT(1)
-+#define HIF_CTRL_BDP_CH_START_WSTB BIT(2)
-+
-+/* HIF_RX_STATUS bits */
-+#define BDP_CSR_RX_DMA_ACTV BIT(16)
-+
-+/* HIF_INT_ENABLE bits */
-+#define HIF_INT_EN BIT(0)
-+#define HIF_RXBD_INT_EN BIT(1)
-+#define HIF_RXPKT_INT_EN BIT(2)
-+#define HIF_TXBD_INT_EN BIT(3)
-+#define HIF_TXPKT_INT_EN BIT(4)
-+
-+/* HIF_POLL_CTRL bits*/
-+#define HIF_RX_POLL_CTRL_CYCLE 0x0400
-+#define HIF_TX_POLL_CTRL_CYCLE 0x0400
-+
-+/* HIF_INT_COAL bits*/
-+#define HIF_INT_COAL_ENABLE BIT(31)
-+
-+/* Buffer descriptor control bits */
-+#define BD_CTRL_BUFLEN_MASK 0x3fff
-+#define BD_BUF_LEN(x) ((x) & BD_CTRL_BUFLEN_MASK)
-+#define BD_CTRL_CBD_INT_EN BIT(16)
-+#define BD_CTRL_PKT_INT_EN BIT(17)
-+#define BD_CTRL_LIFM BIT(18)
-+#define BD_CTRL_LAST_BD BIT(19)
-+#define BD_CTRL_DIR BIT(20)
-+#define BD_CTRL_LMEM_CPY BIT(21) /* Valid only for HIF_NOCPY */
-+#define BD_CTRL_PKT_XFER BIT(24)
-+#define BD_CTRL_DESC_EN BIT(31)
-+#define BD_CTRL_PARSE_DISABLE BIT(25)
-+#define BD_CTRL_BRFETCH_DISABLE BIT(26)
-+#define BD_CTRL_RTFETCH_DISABLE BIT(27)
-+
-+/* Buffer descriptor status bits*/
-+#define BD_STATUS_CONN_ID(x) ((x) & 0xffff)
-+#define BD_STATUS_DIR_PROC_ID BIT(16)
-+#define BD_STATUS_CONN_ID_EN BIT(17)
-+#define BD_STATUS_PE2PROC_ID(x) (((x) & 7) << 18)
-+#define BD_STATUS_LE_DATA BIT(21)
-+#define BD_STATUS_CHKSUM_EN BIT(22)
-+
-+/* HIF Buffer descriptor status bits */
-+#define DIR_PROC_ID BIT(16)
-+#define PROC_ID(id) ((id) << 18)
-+
-+#endif /* _HIF_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
-@@ -0,0 +1,50 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _HIF_NOCPY_H_
-+#define _HIF_NOCPY_H_
-+
-+#define HIF_NOCPY_VERSION (HIF_NOCPY_BASE_ADDR + 0x00)
-+#define HIF_NOCPY_TX_CTRL (HIF_NOCPY_BASE_ADDR + 0x04)
-+#define HIF_NOCPY_TX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x08)
-+#define HIF_NOCPY_TX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x0c)
-+#define HIF_NOCPY_TX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x10)
-+#define HIF_NOCPY_TX_STATUS (HIF_NOCPY_BASE_ADDR + 0x14)
-+#define HIF_NOCPY_RX_CTRL (HIF_NOCPY_BASE_ADDR + 0x20)
-+#define HIF_NOCPY_RX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x24)
-+#define HIF_NOCPY_RX_STATUS (HIF_NOCPY_BASE_ADDR + 0x30)
-+#define HIF_NOCPY_INT_SRC (HIF_NOCPY_BASE_ADDR + 0x34)
-+#define HIF_NOCPY_INT_ENABLE (HIF_NOCPY_BASE_ADDR + 0x38)
-+#define HIF_NOCPY_POLL_CTRL (HIF_NOCPY_BASE_ADDR + 0x3c)
-+#define HIF_NOCPY_RX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x40)
-+#define HIF_NOCPY_RX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x44)
-+#define HIF_NOCPY_TX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x48)
-+#define HIF_NOCPY_RX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x4c)
-+#define HIF_NOCPY_RX_INQ0_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x50)
-+#define HIF_NOCPY_RX_INQ1_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x54)
-+#define HIF_NOCPY_TX_PORT_NO (HIF_NOCPY_BASE_ADDR + 0x60)
-+#define HIF_NOCPY_LMEM_ALLOC_ADDR (HIF_NOCPY_BASE_ADDR + 0x64)
-+#define HIF_NOCPY_CLASS_ADDR (HIF_NOCPY_BASE_ADDR + 0x68)
-+#define HIF_NOCPY_TMU_PORT0_ADDR (HIF_NOCPY_BASE_ADDR + 0x70)
-+#define HIF_NOCPY_TMU_PORT1_ADDR (HIF_NOCPY_BASE_ADDR + 0x74)
-+#define HIF_NOCPY_TMU_PORT2_ADDR (HIF_NOCPY_BASE_ADDR + 0x7c)
-+#define HIF_NOCPY_TMU_PORT3_ADDR (HIF_NOCPY_BASE_ADDR + 0x80)
-+#define HIF_NOCPY_TMU_PORT4_ADDR (HIF_NOCPY_BASE_ADDR + 0x84)
-+#define HIF_NOCPY_INT_COAL (HIF_NOCPY_BASE_ADDR + 0x90)
-+
-+#endif /* _HIF_NOCPY_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
-@@ -0,0 +1,168 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _TMU_CSR_H_
-+#define _TMU_CSR_H_
-+
-+#define TMU_VERSION (TMU_CSR_BASE_ADDR + 0x000)
-+#define TMU_INQ_WATERMARK (TMU_CSR_BASE_ADDR + 0x004)
-+#define TMU_PHY_INQ_PKTPTR (TMU_CSR_BASE_ADDR + 0x008)
-+#define TMU_PHY_INQ_PKTINFO (TMU_CSR_BASE_ADDR + 0x00c)
-+#define TMU_PHY_INQ_FIFO_CNT (TMU_CSR_BASE_ADDR + 0x010)
-+#define TMU_SYS_GENERIC_CONTROL (TMU_CSR_BASE_ADDR + 0x014)
-+#define TMU_SYS_GENERIC_STATUS (TMU_CSR_BASE_ADDR + 0x018)
-+#define TMU_SYS_GEN_CON0 (TMU_CSR_BASE_ADDR + 0x01c)
-+#define TMU_SYS_GEN_CON1 (TMU_CSR_BASE_ADDR + 0x020)
-+#define TMU_SYS_GEN_CON2 (TMU_CSR_BASE_ADDR + 0x024)
-+#define TMU_SYS_GEN_CON3 (TMU_CSR_BASE_ADDR + 0x028)
-+#define TMU_SYS_GEN_CON4 (TMU_CSR_BASE_ADDR + 0x02c)
-+#define TMU_TEQ_DISABLE_DROPCHK (TMU_CSR_BASE_ADDR + 0x030)
-+#define TMU_TEQ_CTRL (TMU_CSR_BASE_ADDR + 0x034)
-+#define TMU_TEQ_QCFG (TMU_CSR_BASE_ADDR + 0x038)
-+#define TMU_TEQ_DROP_STAT (TMU_CSR_BASE_ADDR + 0x03c)
-+#define TMU_TEQ_QAVG (TMU_CSR_BASE_ADDR + 0x040)
-+#define TMU_TEQ_WREG_PROB (TMU_CSR_BASE_ADDR + 0x044)
-+#define TMU_TEQ_TRANS_STAT (TMU_CSR_BASE_ADDR + 0x048)
-+#define TMU_TEQ_HW_PROB_CFG0 (TMU_CSR_BASE_ADDR + 0x04c)
-+#define TMU_TEQ_HW_PROB_CFG1 (TMU_CSR_BASE_ADDR + 0x050)
-+#define TMU_TEQ_HW_PROB_CFG2 (TMU_CSR_BASE_ADDR + 0x054)
-+#define TMU_TEQ_HW_PROB_CFG3 (TMU_CSR_BASE_ADDR + 0x058)
-+#define TMU_TEQ_HW_PROB_CFG4 (TMU_CSR_BASE_ADDR + 0x05c)
-+#define TMU_TEQ_HW_PROB_CFG5 (TMU_CSR_BASE_ADDR + 0x060)
-+#define TMU_TEQ_HW_PROB_CFG6 (TMU_CSR_BASE_ADDR + 0x064)
-+#define TMU_TEQ_HW_PROB_CFG7 (TMU_CSR_BASE_ADDR + 0x068)
-+#define TMU_TEQ_HW_PROB_CFG8 (TMU_CSR_BASE_ADDR + 0x06c)
-+#define TMU_TEQ_HW_PROB_CFG9 (TMU_CSR_BASE_ADDR + 0x070)
-+#define TMU_TEQ_HW_PROB_CFG10 (TMU_CSR_BASE_ADDR + 0x074)
-+#define TMU_TEQ_HW_PROB_CFG11 (TMU_CSR_BASE_ADDR + 0x078)
-+#define TMU_TEQ_HW_PROB_CFG12 (TMU_CSR_BASE_ADDR + 0x07c)
-+#define TMU_TEQ_HW_PROB_CFG13 (TMU_CSR_BASE_ADDR + 0x080)
-+#define TMU_TEQ_HW_PROB_CFG14 (TMU_CSR_BASE_ADDR + 0x084)
-+#define TMU_TEQ_HW_PROB_CFG15 (TMU_CSR_BASE_ADDR + 0x088)
-+#define TMU_TEQ_HW_PROB_CFG16 (TMU_CSR_BASE_ADDR + 0x08c)
-+#define TMU_TEQ_HW_PROB_CFG17 (TMU_CSR_BASE_ADDR + 0x090)
-+#define TMU_TEQ_HW_PROB_CFG18 (TMU_CSR_BASE_ADDR + 0x094)
-+#define TMU_TEQ_HW_PROB_CFG19 (TMU_CSR_BASE_ADDR + 0x098)
-+#define TMU_TEQ_HW_PROB_CFG20 (TMU_CSR_BASE_ADDR + 0x09c)
-+#define TMU_TEQ_HW_PROB_CFG21 (TMU_CSR_BASE_ADDR + 0x0a0)
-+#define TMU_TEQ_HW_PROB_CFG22 (TMU_CSR_BASE_ADDR + 0x0a4)
-+#define TMU_TEQ_HW_PROB_CFG23 (TMU_CSR_BASE_ADDR + 0x0a8)
-+#define TMU_TEQ_HW_PROB_CFG24 (TMU_CSR_BASE_ADDR + 0x0ac)
-+#define TMU_TEQ_HW_PROB_CFG25 (TMU_CSR_BASE_ADDR + 0x0b0)
-+#define TMU_TDQ_IIFG_CFG (TMU_CSR_BASE_ADDR + 0x0b4)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY0
-+ */
-+#define TMU_TDQ0_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x0b8)
-+
-+#define TMU_LLM_CTRL (TMU_CSR_BASE_ADDR + 0x0bc)
-+#define TMU_LLM_BASE_ADDR (TMU_CSR_BASE_ADDR + 0x0c0)
-+#define TMU_LLM_QUE_LEN (TMU_CSR_BASE_ADDR + 0x0c4)
-+#define TMU_LLM_QUE_HEADPTR (TMU_CSR_BASE_ADDR + 0x0c8)
-+#define TMU_LLM_QUE_TAILPTR (TMU_CSR_BASE_ADDR + 0x0cc)
-+#define TMU_LLM_QUE_DROPCNT (TMU_CSR_BASE_ADDR + 0x0d0)
-+#define TMU_INT_EN (TMU_CSR_BASE_ADDR + 0x0d4)
-+#define TMU_INT_SRC (TMU_CSR_BASE_ADDR + 0x0d8)
-+#define TMU_INQ_STAT (TMU_CSR_BASE_ADDR + 0x0dc)
-+#define TMU_CTRL (TMU_CSR_BASE_ADDR + 0x0e0)
-+
-+/* [31] Mem Access Command. 0 = Internal Memory Read, 1 = Internal memory
-+ * Write [27:24] Byte Enables of the Internal memory access [23:0] Address of
-+ * the internal memory. This address is used to access both the PM and DM of
-+ * all the PE's
-+ */
-+#define TMU_MEM_ACCESS_ADDR (TMU_CSR_BASE_ADDR + 0x0e4)
-+
-+/* Internal Memory Access Write Data */
-+#define TMU_MEM_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x0e8)
-+/* Internal Memory Access Read Data. The commands are blocked
-+ * at the mem_access only
-+ */
-+#define TMU_MEM_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x0ec)
-+
-+/* [31:0] PHY0 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY0_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f0)
-+/* [31:0] PHY1 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY1_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f4)
-+/* [31:0] PHY2 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY2_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f8)
-+/* [31:0] PHY3 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY3_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0fc)
-+#define TMU_BMU_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x100)
-+#define TMU_TX_CTRL (TMU_CSR_BASE_ADDR + 0x104)
-+
-+#define TMU_BUS_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x108)
-+#define TMU_BUS_ACCESS (TMU_CSR_BASE_ADDR + 0x10c)
-+#define TMU_BUS_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x110)
-+
-+#define TMU_PE_SYS_CLK_RATIO (TMU_CSR_BASE_ADDR + 0x114)
-+#define TMU_PE_STATUS (TMU_CSR_BASE_ADDR + 0x118)
-+#define TMU_TEQ_MAX_THRESHOLD (TMU_CSR_BASE_ADDR + 0x11c)
-+/* [31:0] PHY4 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY4_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x134)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY1
-+ */
-+#define TMU_TDQ1_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x138)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY2
-+ */
-+#define TMU_TDQ2_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x13c)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY3
-+ */
-+#define TMU_TDQ3_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x140)
-+#define TMU_BMU_BUF_SIZE (TMU_CSR_BASE_ADDR + 0x144)
-+/* [31:0] PHY5 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY5_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x148)
-+
-+#define SW_RESET BIT(0) /* Global software reset */
-+#define INQ_RESET BIT(2)
-+#define TEQ_RESET BIT(3)
-+#define TDQ_RESET BIT(4)
-+#define PE_RESET BIT(5)
-+#define MEM_INIT BIT(6)
-+#define MEM_INIT_DONE BIT(7)
-+#define LLM_INIT BIT(8)
-+#define LLM_INIT_DONE BIT(9)
-+#define ECC_MEM_INIT_DONE BIT(10)
-+
-+struct tmu_cfg {
-+ u32 pe_sys_clk_ratio;
-+ unsigned long llm_base_addr;
-+ u32 llm_queue_len;
-+};
-+
-+/* Not HW related for pfe_ctrl / pfe common defines */
-+#define DEFAULT_MAX_QDEPTH 80
-+#define DEFAULT_Q0_QDEPTH 511 /*We keep one large queue for host tx qos */
-+#define DEFAULT_TMU3_QDEPTH 127
-+
-+#endif /* _TMU_CSR_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _UTIL_CSR_H_
-+#define _UTIL_CSR_H_
-+
-+#define UTIL_VERSION (UTIL_CSR_BASE_ADDR + 0x000)
-+#define UTIL_TX_CTRL (UTIL_CSR_BASE_ADDR + 0x004)
-+#define UTIL_INQ_PKTPTR (UTIL_CSR_BASE_ADDR + 0x010)
-+
-+#define UTIL_HDR_SIZE (UTIL_CSR_BASE_ADDR + 0x014)
-+
-+#define UTIL_PE0_QB_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x020)
-+#define UTIL_PE0_QB_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x024)
-+#define UTIL_PE0_RO_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x060)
-+#define UTIL_PE0_RO_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x064)
-+
-+#define UTIL_MEM_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x100)
-+#define UTIL_MEM_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x104)
-+#define UTIL_MEM_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x108)
-+
-+#define UTIL_TM_INQ_ADDR (UTIL_CSR_BASE_ADDR + 0x114)
-+#define UTIL_PE_STATUS (UTIL_CSR_BASE_ADDR + 0x118)
-+
-+#define UTIL_PE_SYS_CLK_RATIO (UTIL_CSR_BASE_ADDR + 0x200)
-+#define UTIL_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x204)
-+#define UTIL_GAP_BETWEEN_READS (UTIL_CSR_BASE_ADDR + 0x208)
-+#define UTIL_MAX_BUF_CNT (UTIL_CSR_BASE_ADDR + 0x20c)
-+#define UTIL_TSQ_FIFO_THRES (UTIL_CSR_BASE_ADDR + 0x210)
-+#define UTIL_TSQ_MAX_CNT (UTIL_CSR_BASE_ADDR + 0x214)
-+#define UTIL_IRAM_DATA_0 (UTIL_CSR_BASE_ADDR + 0x218)
-+#define UTIL_IRAM_DATA_1 (UTIL_CSR_BASE_ADDR + 0x21c)
-+#define UTIL_IRAM_DATA_2 (UTIL_CSR_BASE_ADDR + 0x220)
-+#define UTIL_IRAM_DATA_3 (UTIL_CSR_BASE_ADDR + 0x224)
-+
-+#define UTIL_BUS_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x228)
-+#define UTIL_BUS_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x22c)
-+#define UTIL_BUS_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x230)
-+
-+#define UTIL_INQ_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x234)
-+
-+struct util_cfg {
-+ u32 pe_sys_clk_ratio;
-+};
-+
-+#endif /* _UTIL_CSR_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h
-@@ -0,0 +1,372 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _PFE_H_
-+#define _PFE_H_
-+
-+#include "cbus.h"
-+
-+#define CLASS_DMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20))
-+/*
-+ * Only valid for mem access register interface
-+ */
-+#define CLASS_IMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20))
-+#define CLASS_DMEM_SIZE 0x00002000
-+#define CLASS_IMEM_SIZE 0x00008000
-+
-+#define TMU_DMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20))
-+/*
-+ * Only valid for mem access register interface
-+ */
-+#define TMU_IMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20))
-+#define TMU_DMEM_SIZE 0x00000800
-+#define TMU_IMEM_SIZE 0x00002000
-+
-+#define UTIL_DMEM_BASE_ADDR 0x00000000
-+#define UTIL_DMEM_SIZE 0x00002000
-+
-+#define PE_LMEM_BASE_ADDR 0xc3010000
-+#define PE_LMEM_SIZE 0x8000
-+#define PE_LMEM_END (PE_LMEM_BASE_ADDR + PE_LMEM_SIZE)
-+
-+#define DMEM_BASE_ADDR 0x00000000
-+#define DMEM_SIZE 0x2000 /* TMU has less... */
-+#define DMEM_END (DMEM_BASE_ADDR + DMEM_SIZE)
-+
-+#define PMEM_BASE_ADDR 0x00010000
-+#define PMEM_SIZE 0x8000 /* TMU has less... */
-+#define PMEM_END (PMEM_BASE_ADDR + PMEM_SIZE)
-+
-+/* These check memory ranges from PE point of view/memory map */
-+#define IS_DMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= DMEM_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + (len)) <= DMEM_END); })
-+
-+#define IS_PMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= PMEM_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + (len)) <= PMEM_END); })
-+
-+#define IS_PE_LMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= \
-+ PE_LMEM_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + \
-+ (len)) <= PE_LMEM_END); })
-+
-+#define IS_PFE_LMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= \
-+ CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR)) && \
-+ (((unsigned long)(addr_) + (len)) <= \
-+ CBUS_VIRT_TO_PFE(LMEM_END)); })
-+
-+#define __IS_PHYS_DDR(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= \
-+ DDR_PHYS_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + (len)) <= \
-+ DDR_PHYS_END); })
-+
-+#define IS_PHYS_DDR(addr, len) __IS_PHYS_DDR(DDR_PFE_TO_PHYS(addr), len)
-+
-+/*
-+ * If using a run-time virtual address for the cbus base address use this code
-+ */
-+extern void *cbus_base_addr;
-+extern void *ddr_base_addr;
-+extern unsigned long ddr_phys_base_addr;
-+extern unsigned int ddr_size;
-+
-+#define CBUS_BASE_ADDR cbus_base_addr
-+#define DDR_PHYS_BASE_ADDR ddr_phys_base_addr
-+#define DDR_BASE_ADDR ddr_base_addr
-+#define DDR_SIZE ddr_size
-+
-+#define DDR_PHYS_END (DDR_PHYS_BASE_ADDR + DDR_SIZE)
-+
-+#define LS1012A_PFE_RESET_WA /*
-+ * PFE doesn't have global reset and re-init
-+ * should takecare few things to make PFE
-+ * functional after reset
-+ */
-+#define PFE_CBUS_PHYS_BASE_ADDR 0xc0000000 /* CBUS physical base address
-+ * as seen by PE's.
-+ */
-+/* CBUS physical base address as seen by PE's. */
-+#define PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE 0xc0000000
-+
-+#define DDR_PHYS_TO_PFE(p) (((unsigned long int)(p)) & 0x7FFFFFFF)
-+#define DDR_PFE_TO_PHYS(p) (((unsigned long int)(p)) | 0x80000000)
-+#define CBUS_PHYS_TO_PFE(p) (((p) - PFE_CBUS_PHYS_BASE_ADDR) + \
-+ PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE)
-+/* Translates to PFE address map */
-+
-+#define DDR_PHYS_TO_VIRT(p) (((p) - DDR_PHYS_BASE_ADDR) + DDR_BASE_ADDR)
-+#define DDR_VIRT_TO_PHYS(v) (((v) - DDR_BASE_ADDR) + DDR_PHYS_BASE_ADDR)
-+#define DDR_VIRT_TO_PFE(p) (DDR_PHYS_TO_PFE(DDR_VIRT_TO_PHYS(p)))
-+
-+#define CBUS_VIRT_TO_PFE(v) (((v) - CBUS_BASE_ADDR) + \
-+ PFE_CBUS_PHYS_BASE_ADDR)
-+#define CBUS_PFE_TO_VIRT(p) (((unsigned long int)(p) - \
-+ PFE_CBUS_PHYS_BASE_ADDR) + CBUS_BASE_ADDR)
-+
-+/* The below part of the code is used in QOS control driver from host */
-+#define TMU_APB_BASE_ADDR 0xc1000000 /* TMU base address seen by
-+ * pe's
-+ */
-+
-+enum {
-+ CLASS0_ID = 0,
-+ CLASS1_ID,
-+ CLASS2_ID,
-+ CLASS3_ID,
-+ CLASS4_ID,
-+ CLASS5_ID,
-+ TMU0_ID,
-+ TMU1_ID,
-+ TMU2_ID,
-+ TMU3_ID,
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ UTIL_ID,
-+#endif
-+ MAX_PE
-+};
-+
-+#define CLASS_MASK (BIT(CLASS0_ID) | BIT(CLASS1_ID) |\
-+ BIT(CLASS2_ID) | BIT(CLASS3_ID) |\
-+ BIT(CLASS4_ID) | BIT(CLASS5_ID))
-+#define CLASS_MAX_ID CLASS5_ID
-+
-+#define TMU_MASK (BIT(TMU0_ID) | BIT(TMU1_ID) |\
-+ BIT(TMU3_ID))
-+
-+#define TMU_MAX_ID TMU3_ID
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+#define UTIL_MASK BIT(UTIL_ID)
-+#endif
-+
-+struct pe_status {
-+ u32 cpu_state;
-+ u32 activity_counter;
-+ u32 rx;
-+ union {
-+ u32 tx;
-+ u32 tmu_qstatus;
-+ };
-+ u32 drop;
-+#if defined(CFG_PE_DEBUG)
-+ u32 debug_indicator;
-+ u32 debug[16];
-+#endif
-+} __aligned(16);
-+
-+struct pe_sync_mailbox {
-+ u32 stop;
-+ u32 stopped;
-+};
-+
-+/* Drop counter definitions */
-+
-+#define CLASS_NUM_DROP_COUNTERS 13
-+#define UTIL_NUM_DROP_COUNTERS 8
-+
-+/* PE information.
-+ * Structure containing PE's specific information. It is used to create
-+ * generic C functions common to all PE's.
-+ * Before using the library functions this structure needs to be initialized
-+ * with the different registers virtual addresses
-+ * (according to the ARM MMU mmaping). The default initialization supports a
-+ * virtual == physical mapping.
-+ */
-+struct pe_info {
-+ u32 dmem_base_addr; /* PE's dmem base address */
-+ u32 pmem_base_addr; /* PE's pmem base address */
-+ u32 pmem_size; /* PE's pmem size */
-+
-+ void *mem_access_wdata; /* PE's _MEM_ACCESS_WDATA register
-+ * address
-+ */
-+ void *mem_access_addr; /* PE's _MEM_ACCESS_ADDR register
-+ * address
-+ */
-+ void *mem_access_rdata; /* PE's _MEM_ACCESS_RDATA register
-+ * address
-+ */
-+};
-+
-+void pe_lmem_read(u32 *dst, u32 len, u32 offset);
-+void pe_lmem_write(u32 *src, u32 len, u32 offset);
-+
-+void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
-+void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
-+
-+u32 pe_pmem_read(int id, u32 addr, u8 size);
-+
-+void pe_dmem_write(int id, u32 val, u32 addr, u8 size);
-+u32 pe_dmem_read(int id, u32 addr, u8 size);
-+void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len);
-+void class_pe_lmem_memset(u32 dst, int val, unsigned int len);
-+void class_bus_write(u32 val, u32 addr, u8 size);
-+u32 class_bus_read(u32 addr, u8 size);
-+
-+#define class_bus_readl(addr) class_bus_read(addr, 4)
-+#define class_bus_readw(addr) class_bus_read(addr, 2)
-+#define class_bus_readb(addr) class_bus_read(addr, 1)
-+
-+#define class_bus_writel(val, addr) class_bus_write(val, addr, 4)
-+#define class_bus_writew(val, addr) class_bus_write(val, addr, 2)
-+#define class_bus_writeb(val, addr) class_bus_write(val, addr, 1)
-+
-+#define pe_dmem_readl(id, addr) pe_dmem_read(id, addr, 4)
-+#define pe_dmem_readw(id, addr) pe_dmem_read(id, addr, 2)
-+#define pe_dmem_readb(id, addr) pe_dmem_read(id, addr, 1)
-+
-+#define pe_dmem_writel(id, val, addr) pe_dmem_write(id, val, addr, 4)
-+#define pe_dmem_writew(id, val, addr) pe_dmem_write(id, val, addr, 2)
-+#define pe_dmem_writeb(id, val, addr) pe_dmem_write(id, val, addr, 1)
-+
-+/*int pe_load_elf_section(int id, const void *data, elf32_shdr *shdr); */
-+int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr,
-+ struct device *dev);
-+
-+void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base,
-+ unsigned int ddr_size);
-+void bmu_init(void *base, struct BMU_CFG *cfg);
-+void bmu_reset(void *base);
-+void bmu_enable(void *base);
-+void bmu_disable(void *base);
-+void bmu_set_config(void *base, struct BMU_CFG *cfg);
-+
-+/*
-+ * An enumerated type for loopback values. This can be one of three values, no
-+ * loopback -normal operation, local loopback with internal loopback module of
-+ * MAC or PHY loopback which is through the external PHY.
-+ */
-+#ifndef __MAC_LOOP_ENUM__
-+#define __MAC_LOOP_ENUM__
-+enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL};
-+#endif
-+
-+void gemac_init(void *base, void *config);
-+void gemac_disable_rx_checksum_offload(void *base);
-+void gemac_enable_rx_checksum_offload(void *base);
-+void gemac_set_speed(void *base, enum mac_speed gem_speed);
-+void gemac_set_duplex(void *base, int duplex);
-+void gemac_set_mode(void *base, int mode);
-+void gemac_enable(void *base);
-+void gemac_tx_disable(void *base);
-+void gemac_tx_enable(void *base);
-+void gemac_disable(void *base);
-+void gemac_reset(void *base);
-+void gemac_set_address(void *base, struct spec_addr *addr);
-+struct spec_addr gemac_get_address(void *base);
-+void gemac_set_loop(void *base, enum mac_loop gem_loop);
-+void gemac_set_laddr1(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddr2(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddr3(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddr4(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddrN(void *base, struct pfe_mac_addr *address,
-+ unsigned int entry_index);
-+void gemac_clear_laddr1(void *base);
-+void gemac_clear_laddr2(void *base);
-+void gemac_clear_laddr3(void *base);
-+void gemac_clear_laddr4(void *base);
-+void gemac_clear_laddrN(void *base, unsigned int entry_index);
-+struct pfe_mac_addr gemac_get_hash(void *base);
-+void gemac_set_hash(void *base, struct pfe_mac_addr *hash);
-+struct pfe_mac_addr gem_get_laddr1(void *base);
-+struct pfe_mac_addr gem_get_laddr2(void *base);
-+struct pfe_mac_addr gem_get_laddr3(void *base);
-+struct pfe_mac_addr gem_get_laddr4(void *base);
-+struct pfe_mac_addr gem_get_laddrN(void *base, unsigned int entry_index);
-+void gemac_set_config(void *base, struct gemac_cfg *cfg);
-+void gemac_allow_broadcast(void *base);
-+void gemac_no_broadcast(void *base);
-+void gemac_enable_1536_rx(void *base);
-+void gemac_disable_1536_rx(void *base);
-+void gemac_set_rx_max_fl(void *base, int mtu);
-+void gemac_enable_rx_jmb(void *base);
-+void gemac_disable_rx_jmb(void *base);
-+void gemac_enable_stacked_vlan(void *base);
-+void gemac_disable_stacked_vlan(void *base);
-+void gemac_enable_pause_rx(void *base);
-+void gemac_disable_pause_rx(void *base);
-+void gemac_enable_copy_all(void *base);
-+void gemac_disable_copy_all(void *base);
-+void gemac_set_bus_width(void *base, int width);
-+void gemac_set_wol(void *base, u32 wol_conf);
-+
-+void gpi_init(void *base, struct gpi_cfg *cfg);
-+void gpi_reset(void *base);
-+void gpi_enable(void *base);
-+void gpi_disable(void *base);
-+void gpi_set_config(void *base, struct gpi_cfg *cfg);
-+
-+void class_init(struct class_cfg *cfg);
-+void class_reset(void);
-+void class_enable(void);
-+void class_disable(void);
-+void class_set_config(struct class_cfg *cfg);
-+
-+void tmu_reset(void);
-+void tmu_init(struct tmu_cfg *cfg);
-+void tmu_enable(u32 pe_mask);
-+void tmu_disable(u32 pe_mask);
-+u32 tmu_qstatus(u32 if_id);
-+u32 tmu_pkts_processed(u32 if_id);
-+
-+void util_init(struct util_cfg *cfg);
-+void util_reset(void);
-+void util_enable(void);
-+void util_disable(void);
-+
-+void hif_init(void);
-+void hif_tx_enable(void);
-+void hif_tx_disable(void);
-+void hif_rx_enable(void);
-+void hif_rx_disable(void);
-+
-+/* Get Chip Revision level
-+ *
-+ */
-+static inline unsigned int CHIP_REVISION(void)
-+{
-+ /*For LS1012A return always 1 */
-+ return 1;
-+}
-+
-+/* Start HIF rx DMA
-+ *
-+ */
-+static inline void hif_rx_dma_start(void)
-+{
-+ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_RX_CTRL);
-+}
-+
-+/* Start HIF tx DMA
-+ *
-+ */
-+static inline void hif_tx_dma_start(void)
-+{
-+ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL);
-+}
-+
-+#endif /* _PFE_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c
-@@ -0,0 +1,258 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2018 NXP
-+ */
-+
-+/* @pfe_cdev.c.
-+ * Dummy device representing the PFE US in userspace.
-+ * - used for interacting with the kernel layer for link status
-+ */
-+
-+#include <linux/eventfd.h>
-+#include <linux/irqreturn.h>
-+#include <linux/io.h>
-+#include <asm/irq.h>
-+
-+#include "pfe_cdev.h"
-+#include "pfe_mod.h"
-+
-+static int pfe_majno;
-+static struct class *pfe_char_class;
-+static struct device *pfe_char_dev;
-+struct eventfd_ctx *g_trigger;
-+
-+struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT];
-+
-+static int pfe_cdev_open(struct inode *inp, struct file *fp)
-+{
-+ pr_debug("PFE CDEV device opened.\n");
-+ return 0;
-+}
-+
-+static ssize_t pfe_cdev_read(struct file *fp, char *buf,
-+ size_t len, loff_t *off)
-+{
-+ int ret = 0;
-+
-+ pr_info("PFE CDEV attempt copying (%lu) size of user.\n",
-+ sizeof(link_states));
-+
-+ pr_debug("Dump link_state on screen before copy_to_user\n");
-+ for (; ret < PFE_CDEV_ETH_COUNT; ret++) {
-+ pr_debug("%u %u", link_states[ret].phy_id,
-+ link_states[ret].state);
-+ pr_debug("\n");
-+ }
-+
-+ /* Copy to user the value in buffer sized len */
-+ ret = copy_to_user(buf, &link_states, sizeof(link_states));
-+ if (ret != 0) {
-+ pr_err("Failed to send (%d)bytes of (%lu) requested.\n",
-+ ret, len);
-+ return -EFAULT;
-+ }
-+
-+ /* offset set back to 0 as there is contextual reading offset */
-+ *off = 0;
-+ pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states));
-+
-+ return sizeof(link_states);
-+}
-+
-+/**
-+ * This function is for getting some commands from user through non-IOCTL
-+ * channel. It can used to configure the device.
-+ * TODO: To be filled in future, if require duplex communication with user
-+ * space.
-+ */
-+static ssize_t pfe_cdev_write(struct file *fp, const char *buf,
-+ size_t len, loff_t *off)
-+{
-+ pr_info("PFE CDEV Write operation not supported!\n");
-+
-+ return -EFAULT;
-+}
-+
-+static int pfe_cdev_release(struct inode *inp, struct file *fp)
-+{
-+ if (g_trigger) {
-+ free_irq(pfe->hif_irq, g_trigger);
-+ eventfd_ctx_put(g_trigger);
-+ g_trigger = NULL;
-+ }
-+
-+ pr_info("PFE_CDEV: Device successfully closed\n");
-+ return 0;
-+}
-+
-+/*
-+ * hif_us_isr-
-+ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block
-+ */
-+static irqreturn_t hif_us_isr(int irq, void *arg)
-+{
-+ struct eventfd_ctx *trigger = (struct eventfd_ctx *)arg;
-+ int int_status;
-+ int int_enable_mask;
-+
-+ /*Read hif interrupt source register */
-+ int_status = readl_relaxed(HIF_INT_SRC);
-+ int_enable_mask = readl_relaxed(HIF_INT_ENABLE);
-+
-+ if ((int_status & HIF_INT) == 0)
-+ return IRQ_NONE;
-+
-+ if (int_status & HIF_RXPKT_INT) {
-+ int_enable_mask &= ~(HIF_RXPKT_INT);
-+ /* Disable interrupts, they will be enabled after
-+ * they are serviced
-+ */
-+ writel_relaxed(int_enable_mask, HIF_INT_ENABLE);
-+
-+ eventfd_signal(trigger, 1);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+#define PFE_INTR_COAL_USECS 100
-+static long pfe_cdev_ioctl(struct file *fp, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ int ret = -EFAULT;
-+ int __user *argp = (int __user *)arg;
-+
-+ pr_debug("PFE CDEV IOCTL Called with cmd=(%u)\n", cmd);
-+
-+ switch (cmd) {
-+ case PFE_CDEV_ETH0_STATE_GET:
-+ /* Return an unsigned int (link state) for ETH0 */
-+ *argp = link_states[0].state;
-+ pr_debug("Returning state=%d for ETH0\n", *argp);
-+ ret = 0;
-+ break;
-+ case PFE_CDEV_ETH1_STATE_GET:
-+ /* Return an unsigned int (link state) for ETH0 */
-+ *argp = link_states[1].state;
-+ pr_debug("Returning state=%d for ETH1\n", *argp);
-+ ret = 0;
-+ break;
-+ case PFE_CDEV_HIF_INTR_EN:
-+ /* Return success/failure */
-+ g_trigger = eventfd_ctx_fdget(*argp);
-+ if (IS_ERR(g_trigger))
-+ return PTR_ERR(g_trigger);
-+ ret = request_irq(pfe->hif_irq, hif_us_isr, 0, "pfe_hif",
-+ g_trigger);
-+ if (ret) {
-+ pr_err("%s: failed to get the hif IRQ = %d\n",
-+ __func__, pfe->hif_irq);
-+ eventfd_ctx_put(g_trigger);
-+ g_trigger = NULL;
-+ }
-+ writel((PFE_INTR_COAL_USECS * (pfe->ctrl.sys_clk / 1000)) |
-+ HIF_INT_COAL_ENABLE, HIF_INT_COAL);
-+
-+ pr_debug("request_irq for hif interrupt: %d\n", pfe->hif_irq);
-+ ret = 0;
-+ break;
-+ default:
-+ pr_info("Unsupport cmd (%d) for PFE CDEV.\n", cmd);
-+ break;
-+ };
-+
-+ return ret;
-+}
-+
-+static unsigned int pfe_cdev_poll(struct file *fp,
-+ struct poll_table_struct *wait)
-+{
-+ pr_info("PFE CDEV poll method not supported\n");
-+ return 0;
-+}
-+
-+static const struct file_operations pfe_cdev_fops = {
-+ .open = pfe_cdev_open,
-+ .read = pfe_cdev_read,
-+ .write = pfe_cdev_write,
-+ .release = pfe_cdev_release,
-+ .unlocked_ioctl = pfe_cdev_ioctl,
-+ .poll = pfe_cdev_poll,
-+};
-+
-+int pfe_cdev_init(void)
-+{
-+ int ret;
-+
-+ pr_debug("PFE CDEV initialization begin\n");
-+
-+ /* Register the major number for the device */
-+ pfe_majno = register_chrdev(0, PFE_CDEV_NAME, &pfe_cdev_fops);
-+ if (pfe_majno < 0) {
-+ pr_err("Unable to register PFE CDEV. PFE CDEV not available\n");
-+ ret = pfe_majno;
-+ goto cleanup;
-+ }
-+
-+ pr_debug("PFE CDEV assigned major number: %d\n", pfe_majno);
-+
-+ /* Register the class for the device */
-+ pfe_char_class = class_create(THIS_MODULE, PFE_CLASS_NAME);
-+ if (IS_ERR(pfe_char_class)) {
-+ pr_err(
-+ "Failed to init class for PFE CDEV. PFE CDEV not available.\n");
-+ ret = PTR_ERR(pfe_char_class);
-+ goto cleanup;
-+ }
-+
-+ pr_debug("PFE CDEV Class created successfully.\n");
-+
-+ /* Create the device without any parent and without any callback data */
-+ pfe_char_dev = device_create(pfe_char_class, NULL,
-+ MKDEV(pfe_majno, 0), NULL,
-+ PFE_CDEV_NAME);
-+ if (IS_ERR(pfe_char_dev)) {
-+ pr_err("Unable to PFE CDEV device. PFE CDEV not available.\n");
-+ ret = PTR_ERR(pfe_char_dev);
-+ goto cleanup;
-+ }
-+
-+ /* Information structure being shared with the userspace */
-+ memset(link_states, 0, sizeof(struct pfe_shared_info) *
-+ PFE_CDEV_ETH_COUNT);
-+
-+ pr_info("PFE CDEV created: %s\n", PFE_CDEV_NAME);
-+
-+ ret = 0;
-+ return ret;
-+
-+cleanup:
-+ if (!IS_ERR(pfe_char_class))
-+ class_destroy(pfe_char_class);
-+
-+ if (pfe_majno > 0)
-+ unregister_chrdev(pfe_majno, PFE_CDEV_NAME);
-+
-+ return ret;
-+}
-+
-+void pfe_cdev_exit(void)
-+{
-+ if (!IS_ERR(pfe_char_dev))
-+ device_destroy(pfe_char_class, MKDEV(pfe_majno, 0));
-+
-+ if (!IS_ERR(pfe_char_class)) {
-+ class_unregister(pfe_char_class);
-+ class_destroy(pfe_char_class);
-+ }
-+
-+ if (pfe_majno > 0)
-+ unregister_chrdev(pfe_majno, PFE_CDEV_NAME);
-+
-+ /* reset the variables */
-+ pfe_majno = 0;
-+ pfe_char_class = NULL;
-+ pfe_char_dev = NULL;
-+
-+ pr_info("PFE CDEV Removed.\n");
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_cdev.h
-@@ -0,0 +1,41 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2018 NXP
-+ */
-+
-+#ifndef _PFE_CDEV_H_
-+#define _PFE_CDEV_H_
-+
-+#include <linux/init.h>
-+#include <linux/device.h>
-+#include <linux/err.h>
-+#include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/uaccess.h>
-+#include <linux/poll.h>
-+
-+#define PFE_CDEV_NAME "pfe_us_cdev"
-+#define PFE_CLASS_NAME "ppfe_us"
-+
-+/* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are
-+ * supported by PFE driver. Should be updated if number of eth devices are
-+ * changed.
-+ */
-+#define PFE_CDEV_ETH_COUNT 3
-+
-+struct pfe_shared_info {
-+ uint32_t phy_id; /* Link phy ID */
-+ uint8_t state; /* Has either 0 or 1 */
-+};
-+
-+extern struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT];
-+
-+/* IOCTL Commands */
-+#define PFE_CDEV_ETH0_STATE_GET _IOR('R', 0, int)
-+#define PFE_CDEV_ETH1_STATE_GET _IOR('R', 1, int)
-+#define PFE_CDEV_HIF_INTR_EN _IOWR('R', 2, int)
-+
-+int pfe_cdev_init(void);
-+void pfe_cdev_exit(void);
-+
-+#endif /* _PFE_CDEV_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.c
-@@ -0,0 +1,226 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/kthread.h>
-+
-+#include "pfe_mod.h"
-+#include "pfe_ctrl.h"
-+
-+#define TIMEOUT_MS 1000
-+
-+int relax(unsigned long end)
-+{
-+ if (time_after(jiffies, end)) {
-+ if (time_after(jiffies, end + (TIMEOUT_MS * HZ) / 1000))
-+ return -1;
-+
-+ if (need_resched())
-+ schedule();
-+ }
-+
-+ return 0;
-+}
-+
-+void pfe_ctrl_suspend(struct pfe_ctrl *ctrl)
-+{
-+ int id;
-+
-+ mutex_lock(&ctrl->mutex);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
-+ pe_dmem_write(id, cpu_to_be32(0x1), CLASS_DM_RESUME, 4);
-+
-+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
-+ if (id == TMU2_ID)
-+ continue;
-+ pe_dmem_write(id, cpu_to_be32(0x1), TMU_DM_RESUME, 4);
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe_dmem_write(UTIL_ID, cpu_to_be32(0x1), UTIL_DM_RESUME, 4);
-+#endif
-+ mutex_unlock(&ctrl->mutex);
-+}
-+
-+void pfe_ctrl_resume(struct pfe_ctrl *ctrl)
-+{
-+ int pe_mask = CLASS_MASK | TMU_MASK;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe_mask |= UTIL_MASK;
-+#endif
-+ mutex_lock(&ctrl->mutex);
-+ pe_start(&pfe->ctrl, pe_mask);
-+ mutex_unlock(&ctrl->mutex);
-+}
-+
-+/* PE sync stop.
-+ * Stops packet processing for a list of PE's (specified using a bitmask).
-+ * The caller must hold ctrl->mutex.
-+ *
-+ * @param ctrl Control context
-+ * @param pe_mask Mask of PE id's to stop
-+ *
-+ */
-+int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask)
-+{
-+ struct pe_sync_mailbox *mbox;
-+ int pe_stopped = 0;
-+ unsigned long end = jiffies + 2;
-+ int i;
-+
-+ pe_mask &= 0x2FF; /*Exclude Util + TMU2 */
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x1), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+
-+ while (pe_stopped != pe_mask) {
-+ for (i = 0; i < MAX_PE; i++)
-+ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ if (pe_dmem_read(i, (unsigned
-+ long)&mbox->stopped, 4) &
-+ cpu_to_be32(0x1))
-+ pe_stopped |= (1 << i);
-+ }
-+
-+ if (relax(end) < 0)
-+ goto err;
-+ }
-+
-+ return 0;
-+
-+err:
-+ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped);
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+
-+ return -EIO;
-+}
-+
-+/* PE start.
-+ * Starts packet processing for a list of PE's (specified using a bitmask).
-+ * The caller must hold ctrl->mutex.
-+ *
-+ * @param ctrl Control context
-+ * @param pe_mask Mask of PE id's to start
-+ *
-+ */
-+void pe_start(struct pfe_ctrl *ctrl, int pe_mask)
-+{
-+ struct pe_sync_mailbox *mbox;
-+ int i;
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+}
-+
-+/* This function will ensure all PEs are put in to idle state */
-+int pe_reset_all(struct pfe_ctrl *ctrl)
-+{
-+ struct pe_sync_mailbox *mbox;
-+ int pe_stopped = 0;
-+ unsigned long end = jiffies + 2;
-+ int i;
-+ int pe_mask = CLASS_MASK | TMU_MASK;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe_mask |= UTIL_MASK;
-+#endif
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x2), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+
-+ while (pe_stopped != pe_mask) {
-+ for (i = 0; i < MAX_PE; i++)
-+ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ if (pe_dmem_read(i, (unsigned long)
-+ &mbox->stopped, 4) &
-+ cpu_to_be32(0x1))
-+ pe_stopped |= (1 << i);
-+ }
-+
-+ if (relax(end) < 0)
-+ goto err;
-+ }
-+
-+ return 0;
-+
-+err:
-+ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped);
-+ return -EIO;
-+}
-+
-+int pfe_ctrl_init(struct pfe *pfe)
-+{
-+ struct pfe_ctrl *ctrl = &pfe->ctrl;
-+ int id;
-+
-+ pr_info("%s\n", __func__);
-+
-+ mutex_init(&ctrl->mutex);
-+ spin_lock_init(&ctrl->lock);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ ctrl->sync_mailbox_baseaddr[id] = CLASS_DM_SYNC_MBOX;
-+ ctrl->msg_mailbox_baseaddr[id] = CLASS_DM_MSG_MBOX;
-+ }
-+
-+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
-+ if (id == TMU2_ID)
-+ continue;
-+ ctrl->sync_mailbox_baseaddr[id] = TMU_DM_SYNC_MBOX;
-+ ctrl->msg_mailbox_baseaddr[id] = TMU_DM_MSG_MBOX;
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ ctrl->sync_mailbox_baseaddr[UTIL_ID] = UTIL_DM_SYNC_MBOX;
-+ ctrl->msg_mailbox_baseaddr[UTIL_ID] = UTIL_DM_MSG_MBOX;
-+#endif
-+
-+ ctrl->hash_array_baseaddr = pfe->ddr_baseaddr + ROUTE_TABLE_BASEADDR;
-+ ctrl->hash_array_phys_baseaddr = pfe->ddr_phys_baseaddr +
-+ ROUTE_TABLE_BASEADDR;
-+
-+ ctrl->dev = pfe->dev;
-+
-+ pr_info("%s finished\n", __func__);
-+
-+ return 0;
-+}
-+
-+void pfe_ctrl_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.h
-@@ -0,0 +1,100 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_CTRL_H_
-+#define _PFE_CTRL_H_
-+
-+#include <linux/dmapool.h>
-+
-+#include "pfe/pfe.h"
-+
-+#define DMA_BUF_SIZE_128 0x80 /* enough for 1 conntracks */
-+#define DMA_BUF_SIZE_256 0x100
-+/* enough for 2 conntracks, 1 bridge entry or 1 multicast entry */
-+#define DMA_BUF_SIZE_512 0x200
-+/* 512bytes dma allocated buffers used by rtp relay feature */
-+#define DMA_BUF_MIN_ALIGNMENT 8
-+#define DMA_BUF_BOUNDARY (4 * 1024)
-+/* bursts can not cross 4k boundary */
-+
-+#define CMD_TX_ENABLE 0x0501
-+#define CMD_TX_DISABLE 0x0502
-+
-+#define CMD_RX_LRO 0x0011
-+#define CMD_PKTCAP_ENABLE 0x0d01
-+#define CMD_QM_EXPT_RATE 0x020c
-+
-+#define CLASS_DM_SH_STATIC (0x800)
-+#define CLASS_DM_CPU_TICKS (CLASS_DM_SH_STATIC)
-+#define CLASS_DM_SYNC_MBOX (0x808)
-+#define CLASS_DM_MSG_MBOX (0x810)
-+#define CLASS_DM_DROP_CNTR (0x820)
-+#define CLASS_DM_RESUME (0x854)
-+#define CLASS_DM_PESTATUS (0x860)
-+#define CLASS_DM_CRC_VALIDATED (0x14b0)
-+
-+#define TMU_DM_SH_STATIC (0x80)
-+#define TMU_DM_CPU_TICKS (TMU_DM_SH_STATIC)
-+#define TMU_DM_SYNC_MBOX (0x88)
-+#define TMU_DM_MSG_MBOX (0x90)
-+#define TMU_DM_RESUME (0xA0)
-+#define TMU_DM_PESTATUS (0xB0)
-+#define TMU_DM_CONTEXT (0x300)
-+#define TMU_DM_TX_TRANS (0x480)
-+
-+#define UTIL_DM_SH_STATIC (0x0)
-+#define UTIL_DM_CPU_TICKS (UTIL_DM_SH_STATIC)
-+#define UTIL_DM_SYNC_MBOX (0x8)
-+#define UTIL_DM_MSG_MBOX (0x10)
-+#define UTIL_DM_DROP_CNTR (0x20)
-+#define UTIL_DM_RESUME (0x40)
-+#define UTIL_DM_PESTATUS (0x50)
-+
-+struct pfe_ctrl {
-+ struct mutex mutex; /* to serialize pfe control access */
-+ spinlock_t lock;
-+
-+ void *dma_pool;
-+ void *dma_pool_512;
-+ void *dma_pool_128;
-+
-+ struct device *dev;
-+
-+ void *hash_array_baseaddr; /*
-+ * Virtual base address of
-+ * the conntrack hash array
-+ */
-+ unsigned long hash_array_phys_baseaddr; /*
-+ * Physical base address of
-+ * the conntrack hash array
-+ */
-+
-+ int (*event_cb)(u16, u16, u16*);
-+
-+ unsigned long sync_mailbox_baseaddr[MAX_PE]; /*
-+ * Sync mailbox PFE
-+ * internal address,
-+ * initialized
-+ * when parsing elf images
-+ */
-+ unsigned long msg_mailbox_baseaddr[MAX_PE]; /*
-+ * Msg mailbox PFE internal
-+ * address, initialized
-+ * when parsing elf images
-+ */
-+ unsigned int sys_clk; /* AXI clock value, in KHz */
-+};
-+
-+int pfe_ctrl_init(struct pfe *pfe);
-+void pfe_ctrl_exit(struct pfe *pfe);
-+int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask);
-+void pe_start(struct pfe_ctrl *ctrl, int pe_mask);
-+int pe_reset_all(struct pfe_ctrl *ctrl);
-+void pfe_ctrl_suspend(struct pfe_ctrl *ctrl);
-+void pfe_ctrl_resume(struct pfe_ctrl *ctrl);
-+int relax(unsigned long end);
-+
-+#endif /* _PFE_CTRL_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.c
-@@ -0,0 +1,99 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/debugfs.h>
-+#include <linux/platform_device.h>
-+
-+#include "pfe_mod.h"
-+
-+static int dmem_show(struct seq_file *s, void *unused)
-+{
-+ u32 dmem_addr, val;
-+ int id = (long int)s->private;
-+ int i;
-+
-+ for (dmem_addr = 0; dmem_addr < CLASS_DMEM_SIZE; dmem_addr += 8 * 4) {
-+ seq_printf(s, "%04x:", dmem_addr);
-+
-+ for (i = 0; i < 8; i++) {
-+ val = pe_dmem_read(id, dmem_addr + i * 4, 4);
-+ seq_printf(s, " %02x %02x %02x %02x", val & 0xff,
-+ (val >> 8) & 0xff, (val >> 16) & 0xff,
-+ (val >> 24) & 0xff);
-+ }
-+
-+ seq_puts(s, "\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static int dmem_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, dmem_show, inode->i_private);
-+}
-+
-+static const struct file_operations dmem_fops = {
-+ .open = dmem_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = single_release,
-+};
-+
-+int pfe_debugfs_init(struct pfe *pfe)
-+{
-+ struct dentry *d;
-+
-+ pr_info("%s\n", __func__);
-+
-+ pfe->dentry = debugfs_create_dir("pfe", NULL);
-+ if (IS_ERR_OR_NULL(pfe->dentry))
-+ goto err_dir;
-+
-+ d = debugfs_create_file("pe0_dmem", 0444, pfe->dentry, (void *)0,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe1_dmem", 0444, pfe->dentry, (void *)1,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe2_dmem", 0444, pfe->dentry, (void *)2,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe3_dmem", 0444, pfe->dentry, (void *)3,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe4_dmem", 0444, pfe->dentry, (void *)4,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe5_dmem", 0444, pfe->dentry, (void *)5,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ return 0;
-+
-+err_pe:
-+ debugfs_remove_recursive(pfe->dentry);
-+
-+err_dir:
-+ return -1;
-+}
-+
-+void pfe_debugfs_exit(struct pfe *pfe)
-+{
-+ debugfs_remove_recursive(pfe->dentry);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_DEBUGFS_H_
-+#define _PFE_DEBUGFS_H_
-+
-+int pfe_debugfs_init(struct pfe *pfe);
-+void pfe_debugfs_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_DEBUGFS_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_eth.c
-@@ -0,0 +1,2588 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+/* @pfe_eth.c.
-+ * Ethernet driver for to handle exception path for PFE.
-+ * - uses HIF functions to send/receive packets.
-+ * - uses ctrl function to start/stop interfaces.
-+ * - uses direct register accesses to control phy operation.
-+ */
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ethtool.h>
-+#include <linux/mii.h>
-+#include <linux/phy.h>
-+#include <linux/timer.h>
-+#include <linux/hrtimer.h>
-+#include <linux/platform_device.h>
-+
-+#include <net/ip.h>
-+#include <net/sock.h>
-+
-+#include <linux/of.h>
-+#include <linux/of_mdio.h>
-+
-+#include <linux/io.h>
-+#include <asm/irq.h>
-+#include <linux/delay.h>
-+#include <linux/regmap.h>
-+#include <linux/i2c.h>
-+#include <linux/sys_soc.h>
-+
-+#if defined(CONFIG_NF_CONNTRACK_MARK)
-+#include <net/netfilter/nf_conntrack.h>
-+#endif
-+
-+#include "pfe_mod.h"
-+#include "pfe_eth.h"
-+#include "pfe_cdev.h"
-+
-+#define LS1012A_REV_1_0 0x87040010
-+
-+bool pfe_use_old_dts_phy;
-+bool pfe_errata_a010897;
-+
-+static void *cbus_emac_base[3];
-+static void *cbus_gpi_base[3];
-+
-+/* Forward Declaration */
-+static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv);
-+static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv);
-+static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
-+ from_tx, int n_desc);
-+
-+/* MDIO registers */
-+#define MDIO_SGMII_CR 0x00
-+#define MDIO_SGMII_SR 0x01
-+#define MDIO_SGMII_DEV_ABIL_SGMII 0x04
-+#define MDIO_SGMII_LINK_TMR_L 0x12
-+#define MDIO_SGMII_LINK_TMR_H 0x13
-+#define MDIO_SGMII_IF_MODE 0x14
-+
-+/* SGMII Control defines */
-+#define SGMII_CR_RST 0x8000
-+#define SGMII_CR_AN_EN 0x1000
-+#define SGMII_CR_RESTART_AN 0x0200
-+#define SGMII_CR_FD 0x0100
-+#define SGMII_CR_SPEED_SEL1_1G 0x0040
-+#define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \
-+ SGMII_CR_SPEED_SEL1_1G)
-+
-+/* SGMII IF Mode */
-+#define SGMII_DUPLEX_HALF 0x10
-+#define SGMII_SPEED_10MBPS 0x00
-+#define SGMII_SPEED_100MBPS 0x04
-+#define SGMII_SPEED_1GBPS 0x08
-+#define SGMII_USE_SGMII_AN 0x02
-+#define SGMII_EN 0x01
-+
-+/* SGMII Device Ability for SGMII */
-+#define SGMII_DEV_ABIL_ACK 0x4000
-+#define SGMII_DEV_ABIL_EEE_CLK_STP_EN 0x0100
-+#define SGMII_DEV_ABIL_SGMII 0x0001
-+
-+unsigned int gemac_regs[] = {
-+ 0x0004, /* Interrupt event */
-+ 0x0008, /* Interrupt mask */
-+ 0x0024, /* Ethernet control */
-+ 0x0064, /* MIB Control/Status */
-+ 0x0084, /* Receive control/status */
-+ 0x00C4, /* Transmit control */
-+ 0x00E4, /* Physical address low */
-+ 0x00E8, /* Physical address high */
-+ 0x0144, /* Transmit FIFO Watermark and Store and Forward Control*/
-+ 0x0190, /* Receive FIFO Section Full Threshold */
-+ 0x01A0, /* Transmit FIFO Section Empty Threshold */
-+ 0x01B0, /* Frame Truncation Length */
-+};
-+
-+const struct soc_device_attribute ls1012a_rev1_soc_attr[] = {
-+ { .family = "QorIQ LS1012A",
-+ .soc_id = "svr:0x87040010",
-+ .revision = "1.0",
-+ .data = NULL },
-+ { },
-+};
-+
-+/********************************************************************/
-+/* SYSFS INTERFACE */
-+/********************************************************************/
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+/*
-+ * pfe_eth_show_napi_stats
-+ */
-+static ssize_t pfe_eth_show_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "sched: %u\n",
-+ priv->napi_counters[NAPI_SCHED_COUNT]);
-+ len += sprintf(buf + len, "poll: %u\n",
-+ priv->napi_counters[NAPI_POLL_COUNT]);
-+ len += sprintf(buf + len, "packet: %u\n",
-+ priv->napi_counters[NAPI_PACKET_COUNT]);
-+ len += sprintf(buf + len, "budget: %u\n",
-+ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]);
-+ len += sprintf(buf + len, "desc: %u\n",
-+ priv->napi_counters[NAPI_DESC_COUNT]);
-+
-+ return len;
-+}
-+
-+/*
-+ * pfe_eth_set_napi_stats
-+ */
-+static ssize_t pfe_eth_set_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+
-+ memset(priv->napi_counters, 0, sizeof(priv->napi_counters));
-+
-+ return count;
-+}
-+#endif
-+#ifdef PFE_ETH_TX_STATS
-+/* pfe_eth_show_tx_stats
-+ *
-+ */
-+static ssize_t pfe_eth_show_tx_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ ssize_t len = 0;
-+ int i;
-+
-+ len += sprintf(buf + len, "TX queues stats:\n");
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ i);
-+
-+ len += sprintf(buf + len, "\n");
-+ __netif_tx_lock_bh(tx_queue);
-+
-+ hif_tx_lock(&pfe->hif);
-+ len += sprintf(buf + len,
-+ "Queue %2d : credits = %10d\n"
-+ , i, hif_lib_tx_credit_avail(pfe, priv->id, i));
-+ len += sprintf(buf + len,
-+ " tx packets = %10d\n"
-+ , pfe->tmu_credit.tx_packets[priv->id][i]);
-+ hif_tx_unlock(&pfe->hif);
-+
-+ /* Don't output additionnal stats if queue never used */
-+ if (!pfe->tmu_credit.tx_packets[priv->id][i])
-+ goto skip;
-+
-+ len += sprintf(buf + len,
-+ " clean_fail = %10d\n"
-+ , priv->clean_fail[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue = %10d\n"
-+ , priv->stop_queue_total[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue_hif = %10d\n"
-+ , priv->stop_queue_hif[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue_hif_client = %10d\n"
-+ , priv->stop_queue_hif_client[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue_credit = %10d\n"
-+ , priv->stop_queue_credit[i]);
-+skip:
-+ __netif_tx_unlock_bh(tx_queue);
-+ }
-+ return len;
-+}
-+
-+/* pfe_eth_set_tx_stats
-+ *
-+ */
-+static ssize_t pfe_eth_set_tx_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ int i;
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ i);
-+
-+ __netif_tx_lock_bh(tx_queue);
-+ priv->clean_fail[i] = 0;
-+ priv->stop_queue_total[i] = 0;
-+ priv->stop_queue_hif[i] = 0;
-+ priv->stop_queue_hif_client[i] = 0;
-+ priv->stop_queue_credit[i] = 0;
-+ __netif_tx_unlock_bh(tx_queue);
-+ }
-+
-+ return count;
-+}
-+#endif
-+/* pfe_eth_show_txavail
-+ *
-+ */
-+static ssize_t pfe_eth_show_txavail(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ ssize_t len = 0;
-+ int i;
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ i);
-+
-+ __netif_tx_lock_bh(tx_queue);
-+
-+ len += sprintf(buf + len, "%d",
-+ hif_lib_tx_avail(&priv->client, i));
-+
-+ __netif_tx_unlock_bh(tx_queue);
-+
-+ if (i == (emac_txq_cnt - 1))
-+ len += sprintf(buf + len, "\n");
-+ else
-+ len += sprintf(buf + len, " ");
-+ }
-+
-+ return len;
-+}
-+
-+/* pfe_eth_show_default_priority
-+ *
-+ */
-+static ssize_t pfe_eth_show_default_priority(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ unsigned long flags;
-+ int rc;
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ rc = sprintf(buf, "%d\n", priv->default_priority);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ return rc;
-+}
-+
-+/* pfe_eth_set_default_priority
-+ *
-+ */
-+
-+static ssize_t pfe_eth_set_default_priority(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ priv->default_priority = kstrtoul(buf, 0, 0);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ return count;
-+}
-+
-+static DEVICE_ATTR(txavail, 0444, pfe_eth_show_txavail, NULL);
-+static DEVICE_ATTR(default_priority, 0644, pfe_eth_show_default_priority,
-+ pfe_eth_set_default_priority);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+static DEVICE_ATTR(napi_stats, 0644, pfe_eth_show_napi_stats,
-+ pfe_eth_set_napi_stats);
-+#endif
-+
-+#ifdef PFE_ETH_TX_STATS
-+static DEVICE_ATTR(tx_stats, 0644, pfe_eth_show_tx_stats,
-+ pfe_eth_set_tx_stats);
-+#endif
-+
-+/*
-+ * pfe_eth_sysfs_init
-+ *
-+ */
-+static int pfe_eth_sysfs_init(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int err;
-+
-+ /* Initialize the default values */
-+
-+ /*
-+ * By default, packets without conntrack will use this default low
-+ * priority queue
-+ */
-+ priv->default_priority = 0;
-+
-+ /* Create our sysfs files */
-+ err = device_create_file(&ndev->dev, &dev_attr_default_priority);
-+ if (err) {
-+ netdev_err(ndev,
-+ "failed to create default_priority sysfs files\n");
-+ goto err_priority;
-+ }
-+
-+ err = device_create_file(&ndev->dev, &dev_attr_txavail);
-+ if (err) {
-+ netdev_err(ndev,
-+ "failed to create default_priority sysfs files\n");
-+ goto err_txavail;
-+ }
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ err = device_create_file(&ndev->dev, &dev_attr_napi_stats);
-+ if (err) {
-+ netdev_err(ndev, "failed to create napi stats sysfs files\n");
-+ goto err_napi;
-+ }
-+#endif
-+
-+#ifdef PFE_ETH_TX_STATS
-+ err = device_create_file(&ndev->dev, &dev_attr_tx_stats);
-+ if (err) {
-+ netdev_err(ndev, "failed to create tx stats sysfs files\n");
-+ goto err_tx;
-+ }
-+#endif
-+
-+ return 0;
-+
-+#ifdef PFE_ETH_TX_STATS
-+err_tx:
-+#endif
-+#ifdef PFE_ETH_NAPI_STATS
-+ device_remove_file(&ndev->dev, &dev_attr_napi_stats);
-+
-+err_napi:
-+#endif
-+ device_remove_file(&ndev->dev, &dev_attr_txavail);
-+
-+err_txavail:
-+ device_remove_file(&ndev->dev, &dev_attr_default_priority);
-+
-+err_priority:
-+ return -1;
-+}
-+
-+/* pfe_eth_sysfs_exit
-+ *
-+ */
-+void pfe_eth_sysfs_exit(struct net_device *ndev)
-+{
-+#ifdef PFE_ETH_TX_STATS
-+ device_remove_file(&ndev->dev, &dev_attr_tx_stats);
-+#endif
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ device_remove_file(&ndev->dev, &dev_attr_napi_stats);
-+#endif
-+ device_remove_file(&ndev->dev, &dev_attr_txavail);
-+ device_remove_file(&ndev->dev, &dev_attr_default_priority);
-+}
-+
-+/*************************************************************************/
-+/* ETHTOOL INTERCAE */
-+/*************************************************************************/
-+
-+/*MTIP GEMAC */
-+static const struct fec_stat {
-+ char name[ETH_GSTRING_LEN];
-+ u16 offset;
-+} fec_stats[] = {
-+ /* RMON TX */
-+ { "tx_dropped", RMON_T_DROP },
-+ { "tx_packets", RMON_T_PACKETS },
-+ { "tx_broadcast", RMON_T_BC_PKT },
-+ { "tx_multicast", RMON_T_MC_PKT },
-+ { "tx_crc_errors", RMON_T_CRC_ALIGN },
-+ { "tx_undersize", RMON_T_UNDERSIZE },
-+ { "tx_oversize", RMON_T_OVERSIZE },
-+ { "tx_fragment", RMON_T_FRAG },
-+ { "tx_jabber", RMON_T_JAB },
-+ { "tx_collision", RMON_T_COL },
-+ { "tx_64byte", RMON_T_P64 },
-+ { "tx_65to127byte", RMON_T_P65TO127 },
-+ { "tx_128to255byte", RMON_T_P128TO255 },
-+ { "tx_256to511byte", RMON_T_P256TO511 },
-+ { "tx_512to1023byte", RMON_T_P512TO1023 },
-+ { "tx_1024to2047byte", RMON_T_P1024TO2047 },
-+ { "tx_GTE2048byte", RMON_T_P_GTE2048 },
-+ { "tx_octets", RMON_T_OCTETS },
-+
-+ /* IEEE TX */
-+ { "IEEE_tx_drop", IEEE_T_DROP },
-+ { "IEEE_tx_frame_ok", IEEE_T_FRAME_OK },
-+ { "IEEE_tx_1col", IEEE_T_1COL },
-+ { "IEEE_tx_mcol", IEEE_T_MCOL },
-+ { "IEEE_tx_def", IEEE_T_DEF },
-+ { "IEEE_tx_lcol", IEEE_T_LCOL },
-+ { "IEEE_tx_excol", IEEE_T_EXCOL },
-+ { "IEEE_tx_macerr", IEEE_T_MACERR },
-+ { "IEEE_tx_cserr", IEEE_T_CSERR },
-+ { "IEEE_tx_sqe", IEEE_T_SQE },
-+ { "IEEE_tx_fdxfc", IEEE_T_FDXFC },
-+ { "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK },
-+
-+ /* RMON RX */
-+ { "rx_packets", RMON_R_PACKETS },
-+ { "rx_broadcast", RMON_R_BC_PKT },
-+ { "rx_multicast", RMON_R_MC_PKT },
-+ { "rx_crc_errors", RMON_R_CRC_ALIGN },
-+ { "rx_undersize", RMON_R_UNDERSIZE },
-+ { "rx_oversize", RMON_R_OVERSIZE },
-+ { "rx_fragment", RMON_R_FRAG },
-+ { "rx_jabber", RMON_R_JAB },
-+ { "rx_64byte", RMON_R_P64 },
-+ { "rx_65to127byte", RMON_R_P65TO127 },
-+ { "rx_128to255byte", RMON_R_P128TO255 },
-+ { "rx_256to511byte", RMON_R_P256TO511 },
-+ { "rx_512to1023byte", RMON_R_P512TO1023 },
-+ { "rx_1024to2047byte", RMON_R_P1024TO2047 },
-+ { "rx_GTE2048byte", RMON_R_P_GTE2048 },
-+ { "rx_octets", RMON_R_OCTETS },
-+
-+ /* IEEE RX */
-+ { "IEEE_rx_drop", IEEE_R_DROP },
-+ { "IEEE_rx_frame_ok", IEEE_R_FRAME_OK },
-+ { "IEEE_rx_crc", IEEE_R_CRC },
-+ { "IEEE_rx_align", IEEE_R_ALIGN },
-+ { "IEEE_rx_macerr", IEEE_R_MACERR },
-+ { "IEEE_rx_fdxfc", IEEE_R_FDXFC },
-+ { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
-+};
-+
-+static void pfe_eth_fill_stats(struct net_device *ndev, struct ethtool_stats
-+ *stats, u64 *data)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int i;
-+ u64 pfe_crc_validated = 0;
-+ int id;
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ pfe_crc_validated += be32_to_cpu(pe_dmem_read(id,
-+ CLASS_DM_CRC_VALIDATED + (priv->id * 4), 4));
-+ }
-+
-+ for (i = 0; i < ARRAY_SIZE(fec_stats); i++) {
-+ data[i] = readl(priv->EMAC_baseaddr + fec_stats[i].offset);
-+
-+ if (fec_stats[i].offset == IEEE_R_DROP)
-+ data[i] -= pfe_crc_validated;
-+ }
-+}
-+
-+static void pfe_eth_gstrings(struct net_device *netdev,
-+ u32 stringset, u8 *data)
-+{
-+ int i;
-+
-+ switch (stringset) {
-+ case ETH_SS_STATS:
-+ for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
-+ memcpy(data + i * ETH_GSTRING_LEN,
-+ fec_stats[i].name, ETH_GSTRING_LEN);
-+ break;
-+ }
-+}
-+
-+static int pfe_eth_stats_count(struct net_device *ndev, int sset)
-+{
-+ switch (sset) {
-+ case ETH_SS_STATS:
-+ return ARRAY_SIZE(fec_stats);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+/*
-+ * pfe_eth_gemac_reglen - Return the length of the register structure.
-+ *
-+ */
-+static int pfe_eth_gemac_reglen(struct net_device *ndev)
-+{
-+ pr_info("%s()\n", __func__);
-+ return (sizeof(gemac_regs) / sizeof(u32));
-+}
-+
-+/*
-+ * pfe_eth_gemac_get_regs - Return the gemac register structure.
-+ *
-+ */
-+static void pfe_eth_gemac_get_regs(struct net_device *ndev, struct ethtool_regs
-+ *regs, void *regbuf)
-+{
-+ int i;
-+
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ u32 *buf = (u32 *)regbuf;
-+
-+ pr_info("%s()\n", __func__);
-+ for (i = 0; i < sizeof(gemac_regs) / sizeof(u32); i++)
-+ buf[i] = readl(priv->EMAC_baseaddr + gemac_regs[i]);
-+}
-+
-+/*
-+ * pfe_eth_set_wol - Set the magic packet option, in WoL register.
-+ *
-+ */
-+static int pfe_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ if (wol->wolopts & ~WAKE_MAGIC)
-+ return -EOPNOTSUPP;
-+
-+ /* for MTIP we store wol->wolopts */
-+ priv->wol = wol->wolopts;
-+
-+ device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC);
-+
-+ return 0;
-+}
-+
-+/*
-+ *
-+ * pfe_eth_get_wol - Get the WoL options.
-+ *
-+ */
-+static void pfe_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo
-+ *wol)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ wol->supported = WAKE_MAGIC;
-+ wol->wolopts = 0;
-+
-+ if (priv->wol & WAKE_MAGIC)
-+ wol->wolopts = WAKE_MAGIC;
-+
-+ memset(&wol->sopass, 0, sizeof(wol->sopass));
-+}
-+
-+/*
-+ * pfe_eth_get_drvinfo - Fills in the drvinfo structure with some basic info
-+ *
-+ */
-+static void pfe_eth_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo
-+ *drvinfo)
-+{
-+ strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
-+ strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
-+ strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-+ strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info));
-+}
-+
-+/*
-+ * pfe_eth_set_settings - Used to send commands to PHY.
-+ *
-+ */
-+static int pfe_eth_set_settings(struct net_device *ndev,
-+ const struct ethtool_link_ksettings *cmd)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct phy_device *phydev = priv->phydev;
-+
-+ if (!phydev)
-+ return -ENODEV;
-+
-+ return phy_ethtool_ksettings_set(phydev, cmd);
-+}
-+
-+/*
-+ * pfe_eth_getsettings - Return the current settings in the ethtool_cmd
-+ * structure.
-+ *
-+ */
-+static int pfe_eth_get_settings(struct net_device *ndev,
-+ struct ethtool_link_ksettings *cmd)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct phy_device *phydev = priv->phydev;
-+
-+ if (!phydev)
-+ return -ENODEV;
-+
-+ phy_ethtool_ksettings_get(phydev, cmd);
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_get_msglevel - Gets the debug message mask.
-+ *
-+ */
-+static uint32_t pfe_eth_get_msglevel(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ return priv->msg_enable;
-+}
-+
-+/*
-+ * pfe_eth_set_msglevel - Sets the debug message mask.
-+ *
-+ */
-+static void pfe_eth_set_msglevel(struct net_device *ndev, uint32_t data)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ priv->msg_enable = data;
-+}
-+
-+#define HIF_RX_COAL_MAX_CLKS (~(1 << 31))
-+#define HIF_RX_COAL_CLKS_PER_USEC (pfe->ctrl.sys_clk / 1000)
-+#define HIF_RX_COAL_MAX_USECS (HIF_RX_COAL_MAX_CLKS / \
-+ HIF_RX_COAL_CLKS_PER_USEC)
-+
-+/*
-+ * pfe_eth_set_coalesce - Sets rx interrupt coalescing timer.
-+ *
-+ */
-+static int pfe_eth_set_coalesce(struct net_device *ndev,
-+ struct ethtool_coalesce *ec,
-+ struct kernel_ethtool_coalesce *kernel_coal,
-+ struct netlink_ext_ack *extack)
-+{
-+ if (ec->rx_coalesce_usecs > HIF_RX_COAL_MAX_USECS)
-+ return -EINVAL;
-+
-+ if (!ec->rx_coalesce_usecs) {
-+ writel(0, HIF_INT_COAL);
-+ return 0;
-+ }
-+
-+ writel((ec->rx_coalesce_usecs * HIF_RX_COAL_CLKS_PER_USEC) |
-+ HIF_INT_COAL_ENABLE, HIF_INT_COAL);
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_get_coalesce - Gets rx interrupt coalescing timer value.
-+ *
-+ */
-+static int pfe_eth_get_coalesce(struct net_device *ndev,
-+ struct ethtool_coalesce *ec,
-+ struct kernel_ethtool_coalesce *kernel_coal,
-+ struct netlink_ext_ack *extack)
-+{
-+ int reg_val = readl(HIF_INT_COAL);
-+
-+ if (reg_val & HIF_INT_COAL_ENABLE)
-+ ec->rx_coalesce_usecs = (reg_val & HIF_RX_COAL_MAX_CLKS) /
-+ HIF_RX_COAL_CLKS_PER_USEC;
-+ else
-+ ec->rx_coalesce_usecs = 0;
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_set_pauseparam - Sets pause parameters
-+ *
-+ */
-+static int pfe_eth_set_pauseparam(struct net_device *ndev,
-+ struct ethtool_pauseparam *epause)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ if (epause->tx_pause != epause->rx_pause) {
-+ netdev_info(ndev,
-+ "hardware only support enable/disable both tx and rx\n");
-+ return -EINVAL;
-+ }
-+
-+ priv->pause_flag = 0;
-+ priv->pause_flag |= epause->rx_pause ? PFE_PAUSE_FLAG_ENABLE : 0;
-+ priv->pause_flag |= epause->autoneg ? PFE_PAUSE_FLAG_AUTONEG : 0;
-+
-+ if (epause->rx_pause || epause->autoneg) {
-+ gemac_enable_pause_rx(priv->EMAC_baseaddr);
-+ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) |
-+ EGPI_PAUSE_ENABLE),
-+ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME);
-+ if (priv->phydev) {
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->advertising);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->advertising);
-+ }
-+ } else {
-+ gemac_disable_pause_rx(priv->EMAC_baseaddr);
-+ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) &
-+ ~EGPI_PAUSE_ENABLE),
-+ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME);
-+ if (priv->phydev) {
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->advertising);
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->advertising);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_get_pauseparam - Gets pause parameters
-+ *
-+ */
-+static void pfe_eth_get_pauseparam(struct net_device *ndev,
-+ struct ethtool_pauseparam *epause)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ epause->autoneg = (priv->pause_flag & PFE_PAUSE_FLAG_AUTONEG) != 0;
-+ epause->tx_pause = (priv->pause_flag & PFE_PAUSE_FLAG_ENABLE) != 0;
-+ epause->rx_pause = epause->tx_pause;
-+}
-+
-+/*
-+ * pfe_eth_get_hash
-+ */
-+#define PFE_HASH_BITS 6 /* #bits in hash */
-+#define CRC32_POLY 0xEDB88320
-+
-+static int pfe_eth_get_hash(u8 *addr)
-+{
-+ unsigned int i, bit, data, crc, hash;
-+
-+ /* calculate crc32 value of mac address */
-+ crc = 0xffffffff;
-+
-+ for (i = 0; i < 6; i++) {
-+ data = addr[i];
-+ for (bit = 0; bit < 8; bit++, data >>= 1) {
-+ crc = (crc >> 1) ^
-+ (((crc ^ data) & 1) ? CRC32_POLY : 0);
-+ }
-+ }
-+
-+ /*
-+ * only upper 6 bits (PFE_HASH_BITS) are used
-+ * which point to specific bit in the hash registers
-+ */
-+ hash = (crc >> (32 - PFE_HASH_BITS)) & 0x3f;
-+
-+ return hash;
-+}
-+
-+const struct ethtool_ops pfe_ethtool_ops = {
-+ .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
-+ .get_drvinfo = pfe_eth_get_drvinfo,
-+ .get_regs_len = pfe_eth_gemac_reglen,
-+ .get_regs = pfe_eth_gemac_get_regs,
-+ .get_link = ethtool_op_get_link,
-+ .get_wol = pfe_eth_get_wol,
-+ .set_wol = pfe_eth_set_wol,
-+ .set_pauseparam = pfe_eth_set_pauseparam,
-+ .get_pauseparam = pfe_eth_get_pauseparam,
-+ .get_strings = pfe_eth_gstrings,
-+ .get_sset_count = pfe_eth_stats_count,
-+ .get_ethtool_stats = pfe_eth_fill_stats,
-+ .get_msglevel = pfe_eth_get_msglevel,
-+ .set_msglevel = pfe_eth_set_msglevel,
-+ .set_coalesce = pfe_eth_set_coalesce,
-+ .get_coalesce = pfe_eth_get_coalesce,
-+ .get_link_ksettings = pfe_eth_get_settings,
-+ .set_link_ksettings = pfe_eth_set_settings,
-+};
-+
-+/* pfe_eth_mdio_reset
-+ */
-+int pfe_eth_mdio_reset(struct mii_bus *bus)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+ u32 phy_speed;
-+
-+
-+ mutex_lock(&bus->mdio_lock);
-+
-+ /*
-+ * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed)
-+ *
-+ * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while
-+ * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'.
-+ */
-+ phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000)
-+ << EMAC_MII_SPEED_SHIFT);
-+ phy_speed |= EMAC_HOLDTIME(0x5);
-+ __raw_writel(phy_speed, priv->mdio_base + EMAC_MII_CTRL_REG);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_mdio_timeout
-+ *
-+ */
-+static int pfe_eth_mdio_timeout(struct pfe_mdio_priv_s *priv, int timeout)
-+{
-+ while (!(__raw_readl(priv->mdio_base + EMAC_IEVENT_REG) &
-+ EMAC_IEVENT_MII)) {
-+ if (timeout-- <= 0)
-+ return -1;
-+ usleep_range(10, 20);
-+ }
-+ __raw_writel(EMAC_IEVENT_MII, priv->mdio_base + EMAC_IEVENT_REG);
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_mux(u8 muxval)
-+{
-+ struct i2c_adapter *a;
-+ struct i2c_msg msg;
-+ unsigned char buf[2];
-+ int ret;
-+
-+ a = i2c_get_adapter(0);
-+ if (!a)
-+ return -ENODEV;
-+
-+ /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */
-+ buf[0] = 0x54; /* reg number */
-+ buf[1] = (muxval << 6) | 0x3; /* data */
-+ msg.addr = 0x66;
-+ msg.buf = buf;
-+ msg.len = 2;
-+ msg.flags = 0;
-+ ret = i2c_transfer(a, &msg, 1);
-+ i2c_put_adapter(a);
-+ if (ret != 1)
-+ return -ENODEV;
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id,
-+ int dev_addr, int regnum)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+
-+ __raw_writel(EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA(dev_addr) |
-+ EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum),
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+
-+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ dev_err(&bus->dev, "phy MDIO address write timeout\n");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
-+ u16 value)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+
-+ /*To access external PHYs on QDS board mux needs to be configured*/
-+ if ((mii_id) && (pfe->mdio_muxval[mii_id]))
-+ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]);
-+
-+ if (regnum & MII_ADDR_C45) {
-+ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f,
-+ regnum & 0xffff);
-+ __raw_writel(EMAC_MII_DATA_OP_CL45_WR |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
-+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+ } else {
-+ /* start a write op */
-+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA(regnum) |
-+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+ }
-+
-+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ dev_err(&bus->dev, "%s: phy MDIO write timeout\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+ u16 value = 0;
-+
-+ /*To access external PHYs on QDS board mux needs to be configured*/
-+ if ((mii_id) && (pfe->mdio_muxval[mii_id]))
-+ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]);
-+
-+ if (regnum & MII_ADDR_C45) {
-+ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f,
-+ regnum & 0xffff);
-+ __raw_writel(EMAC_MII_DATA_OP_CL45_RD |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
-+ EMAC_MII_DATA_TA,
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+ } else {
-+ /* start a read op */
-+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA(regnum) |
-+ EMAC_MII_DATA_TA, priv->mdio_base +
-+ EMAC_MII_DATA_REG);
-+ }
-+
-+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ dev_err(&bus->dev, "%s: phy MDIO read timeout\n", __func__);
-+ return -1;
-+ }
-+
-+ value = EMAC_MII_DATA(__raw_readl(priv->mdio_base +
-+ EMAC_MII_DATA_REG));
-+ return value;
-+}
-+
-+static int pfe_eth_mdio_init(struct pfe *pfe,
-+ struct ls1012a_pfe_platform_data *pfe_info,
-+ int ii)
-+{
-+ struct pfe_mdio_priv_s *priv = NULL;
-+ struct ls1012a_mdio_platform_data *mdio_info;
-+ struct mii_bus *bus;
-+ struct device_node *mdio_node;
-+ int rc = 0;
-+
-+ mdio_info = (struct ls1012a_mdio_platform_data *)
-+ pfe_info->ls1012a_mdio_pdata;
-+ mdio_info->id = ii;
-+
-+ bus = mdiobus_alloc_size(sizeof(struct pfe_mdio_priv_s));
-+ if (!bus) {
-+ pr_err("mdiobus_alloc() failed\n");
-+ rc = -ENOMEM;
-+ goto err_mdioalloc;
-+ }
-+
-+ bus->name = "ls1012a MDIO Bus";
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", mdio_info->id);
-+
-+ bus->read = &pfe_eth_mdio_read;
-+ bus->write = &pfe_eth_mdio_write;
-+ bus->reset = &pfe_eth_mdio_reset;
-+ bus->parent = pfe->dev;
-+ bus->phy_mask = mdio_info->phy_mask;
-+ bus->irq[0] = mdio_info->irq[0];
-+ priv = bus->priv;
-+ priv->mdio_base = cbus_emac_base[ii];
-+
-+ priv->mdc_div = mdio_info->mdc_div;
-+ if (!priv->mdc_div)
-+ priv->mdc_div = 64;
-+
-+ dev_info(bus->parent, "%s: mdc_div: %d, phy_mask: %x\n",
-+ __func__, priv->mdc_div, bus->phy_mask);
-+ mdio_node = of_get_child_by_name(pfe->dev->of_node, "mdio");
-+ if ((mdio_info->id == 0) && mdio_node) {
-+ rc = of_mdiobus_register(bus, mdio_node);
-+ of_node_put(mdio_node);
-+ } else {
-+ rc = mdiobus_register(bus);
-+ }
-+
-+ if (rc) {
-+ dev_err(bus->parent, "mdiobus_register(%s) failed\n",
-+ bus->name);
-+ goto err_mdioregister;
-+ }
-+
-+ priv->mii_bus = bus;
-+ pfe->mdio.mdio_priv[ii] = priv;
-+
-+ pfe_eth_mdio_reset(bus);
-+
-+ return 0;
-+
-+err_mdioregister:
-+ mdiobus_free(bus);
-+err_mdioalloc:
-+ return rc;
-+}
-+
-+/* pfe_eth_mdio_exit
-+ */
-+static void pfe_eth_mdio_exit(struct pfe *pfe,
-+ int ii)
-+{
-+ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[ii];
-+ struct mii_bus *bus = mdio_priv->mii_bus;
-+
-+ if (!bus)
-+ return;
-+ mdiobus_unregister(bus);
-+ mdiobus_free(bus);
-+}
-+
-+/* pfe_get_phydev_speed
-+ */
-+static int pfe_get_phydev_speed(struct phy_device *phydev)
-+{
-+ switch (phydev->speed) {
-+ case 10:
-+ return SPEED_10M;
-+ case 100:
-+ return SPEED_100M;
-+ case 1000:
-+ default:
-+ return SPEED_1000M;
-+ }
-+}
-+
-+/* pfe_set_rgmii_speed
-+ */
-+#define RGMIIPCR 0x434
-+/* RGMIIPCR bit definitions*/
-+#define SCFG_RGMIIPCR_EN_AUTO (0x00000008)
-+#define SCFG_RGMIIPCR_SETSP_1000M (0x00000004)
-+#define SCFG_RGMIIPCR_SETSP_100M (0x00000000)
-+#define SCFG_RGMIIPCR_SETSP_10M (0x00000002)
-+#define SCFG_RGMIIPCR_SETFD (0x00000001)
-+
-+#define MDIOSELCR 0x484
-+#define MDIOSEL_SERDES 0x0
-+#define MDIOSEL_EXTPHY 0x80000000
-+
-+static void pfe_set_rgmii_speed(struct phy_device *phydev)
-+{
-+ u32 rgmii_pcr;
-+
-+ regmap_read(pfe->scfg, RGMIIPCR, &rgmii_pcr);
-+ rgmii_pcr &= ~(SCFG_RGMIIPCR_SETSP_1000M | SCFG_RGMIIPCR_SETSP_10M);
-+
-+ switch (phydev->speed) {
-+ case 10:
-+ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_10M;
-+ break;
-+ case 1000:
-+ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_1000M;
-+ break;
-+ case 100:
-+ default:
-+ /* Default is 100M */
-+ break;
-+ }
-+ regmap_write(pfe->scfg, RGMIIPCR, rgmii_pcr);
-+}
-+
-+/* pfe_get_phydev_duplex
-+ */
-+static int pfe_get_phydev_duplex(struct phy_device *phydev)
-+{
-+ /*return (phydev->duplex == DUPLEX_HALF) ? DUP_HALF:DUP_FULL ; */
-+ return DUPLEX_FULL;
-+}
-+
-+/* pfe_eth_adjust_link
-+ */
-+static void pfe_eth_adjust_link(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ unsigned long flags;
-+ struct phy_device *phydev = priv->phydev;
-+ int new_state = 0;
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+
-+ if (phydev->link) {
-+ /*
-+ * Now we make sure that we can be in full duplex mode.
-+ * If not, we operate in half-duplex mode.
-+ */
-+ if (phydev->duplex != priv->oldduplex) {
-+ new_state = 1;
-+ gemac_set_duplex(priv->EMAC_baseaddr,
-+ pfe_get_phydev_duplex(phydev));
-+ priv->oldduplex = phydev->duplex;
-+ }
-+
-+ if (phydev->speed != priv->oldspeed) {
-+ new_state = 1;
-+ gemac_set_speed(priv->EMAC_baseaddr,
-+ pfe_get_phydev_speed(phydev));
-+ if (priv->einfo->mii_config ==
-+ PHY_INTERFACE_MODE_RGMII_ID)
-+ pfe_set_rgmii_speed(phydev);
-+ priv->oldspeed = phydev->speed;
-+ }
-+
-+ if (!priv->oldlink) {
-+ new_state = 1;
-+ priv->oldlink = 1;
-+ }
-+
-+ } else if (priv->oldlink) {
-+ new_state = 1;
-+ priv->oldlink = 0;
-+ priv->oldspeed = 0;
-+ priv->oldduplex = -1;
-+ }
-+
-+ if (new_state && netif_msg_link(priv))
-+ phy_print_status(phydev);
-+
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ /* Now, dump the details to the cdev.
-+ * XXX: Locking would be required? (uniprocess arch)
-+ * Or, maybe move it in spinlock above
-+ */
-+ if (us && priv->einfo->gem_id < PFE_CDEV_ETH_COUNT) {
-+ pr_debug("Changing link state from (%u) to (%u) for ID=(%u)\n",
-+ link_states[priv->einfo->gem_id].state,
-+ phydev->link,
-+ priv->einfo->gem_id);
-+ link_states[priv->einfo->gem_id].phy_id = priv->einfo->gem_id;
-+ link_states[priv->einfo->gem_id].state = phydev->link;
-+ }
-+}
-+
-+/* pfe_phy_exit
-+ */
-+static void pfe_phy_exit(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ phy_disconnect(priv->phydev);
-+ priv->phydev = NULL;
-+}
-+
-+/* pfe_eth_stop
-+ */
-+static void pfe_eth_stop(struct net_device *ndev, int wake)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ if (wake) {
-+ gemac_tx_disable(priv->EMAC_baseaddr);
-+ } else {
-+ gemac_disable(priv->EMAC_baseaddr);
-+ gpi_disable(priv->GPI_baseaddr);
-+
-+ if (priv->phydev)
-+ phy_stop(priv->phydev);
-+ }
-+}
-+
-+/* pfe_eth_start
-+ */
-+static int pfe_eth_start(struct pfe_eth_priv_s *priv)
-+{
-+ netif_info(priv, drv, priv->ndev, "%s\n", __func__);
-+
-+ if (priv->phydev)
-+ phy_start(priv->phydev);
-+
-+ gpi_enable(priv->GPI_baseaddr);
-+ gemac_enable(priv->EMAC_baseaddr);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Configure on chip serdes through mdio
-+ */
-+static void ls1012a_configure_serdes(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *eth_priv = netdev_priv(ndev);
-+ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[eth_priv->id];
-+ int sgmii_2500 = 0;
-+ struct mii_bus *bus = mdio_priv->mii_bus;
-+ u16 value = 0;
-+
-+ if (eth_priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
-+ sgmii_2500 = 1;
-+
-+ netif_info(eth_priv, drv, ndev, "%s\n", __func__);
-+ /* PCS configuration done with corresponding GEMAC */
-+
-+ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR);
-+ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_SR);
-+
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, SGMII_CR_RST);
-+
-+ if (sgmii_2500) {
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE, SGMII_SPEED_1GBPS
-+ | SGMII_EN);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII,
-+ SGMII_DEV_ABIL_ACK | SGMII_DEV_ABIL_SGMII);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0xa120);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x7);
-+ /* Autonegotiation need to be disabled for 2.5G SGMII mode*/
-+ value = SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G;
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value);
-+ } else {
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE,
-+ SGMII_SPEED_1GBPS
-+ | SGMII_USE_SGMII_AN
-+ | SGMII_EN);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII,
-+ SGMII_DEV_ABIL_EEE_CLK_STP_EN
-+ | 0xa0
-+ | SGMII_DEV_ABIL_SGMII);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0x400);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x0);
-+ value = SGMII_CR_AN_EN | SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G;
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value);
-+ }
-+}
-+
-+/*
-+ * pfe_phy_init
-+ *
-+ */
-+static int pfe_phy_init(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct phy_device *phydev;
-+ char phy_id[MII_BUS_ID_SIZE + 3];
-+ char bus_id[MII_BUS_ID_SIZE];
-+ phy_interface_t interface;
-+
-+ priv->oldlink = 0;
-+ priv->oldspeed = 0;
-+ priv->oldduplex = -1;
-+
-+ snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0);
-+ snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
-+ priv->einfo->phy_id);
-+ netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id);
-+ interface = priv->einfo->mii_config;
-+ if ((interface == PHY_INTERFACE_MODE_SGMII) ||
-+ (interface == PHY_INTERFACE_MODE_2500SGMII)) {
-+ /*Configure SGMII PCS */
-+ if (pfe->scfg) {
-+ /* Config MDIO from serdes */
-+ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_SERDES);
-+ }
-+ ls1012a_configure_serdes(ndev);
-+ }
-+
-+ if (pfe->scfg) {
-+ /*Config MDIO from PAD */
-+ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_EXTPHY);
-+ }
-+
-+ priv->oldlink = 0;
-+ priv->oldspeed = 0;
-+ priv->oldduplex = -1;
-+ pr_info("%s interface %x\n", __func__, interface);
-+
-+ if (priv->phy_node) {
-+ phydev = of_phy_connect(ndev, priv->phy_node,
-+ pfe_eth_adjust_link, 0,
-+ priv->einfo->mii_config);
-+ if (!(phydev)) {
-+ netdev_err(ndev, "Unable to connect to phy\n");
-+ return -ENODEV;
-+ }
-+
-+ } else {
-+ phydev = phy_connect(ndev, phy_id,
-+ &pfe_eth_adjust_link, interface);
-+ if (IS_ERR(phydev)) {
-+ netdev_err(ndev, "Unable to connect to phy\n");
-+ return PTR_ERR(phydev);
-+ }
-+ }
-+
-+ priv->phydev = phydev;
-+ phydev->irq = PHY_POLL;
-+
-+ return 0;
-+}
-+
-+/* pfe_gemac_init
-+ */
-+static int pfe_gemac_init(struct pfe_eth_priv_s *priv)
-+{
-+ struct gemac_cfg cfg;
-+
-+ netif_info(priv, ifup, priv->ndev, "%s\n", __func__);
-+
-+ cfg.mode = 0;
-+ cfg.speed = SPEED_1000M;
-+ cfg.duplex = DUPLEX_FULL;
-+
-+ gemac_set_config(priv->EMAC_baseaddr, &cfg);
-+ gemac_allow_broadcast(priv->EMAC_baseaddr);
-+ gemac_enable_1536_rx(priv->EMAC_baseaddr);
-+ gemac_enable_stacked_vlan(priv->EMAC_baseaddr);
-+ gemac_enable_pause_rx(priv->EMAC_baseaddr);
-+ gemac_set_bus_width(priv->EMAC_baseaddr, 64);
-+
-+ /*GEM will perform checksum verifications*/
-+ if (priv->ndev->features & NETIF_F_RXCSUM)
-+ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
-+ else
-+ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_event_handler
-+ */
-+static int pfe_eth_event_handler(void *data, int event, int qno)
-+{
-+ struct pfe_eth_priv_s *priv = data;
-+
-+ switch (event) {
-+ case EVENT_RX_PKT_IND:
-+
-+ if (qno == 0) {
-+ if (napi_schedule_prep(&priv->high_napi)) {
-+ netif_info(priv, intr, priv->ndev,
-+ "%s: schedule high prio poll\n"
-+ , __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+
-+ __napi_schedule(&priv->high_napi);
-+ }
-+ } else if (qno == 1) {
-+ if (napi_schedule_prep(&priv->low_napi)) {
-+ netif_info(priv, intr, priv->ndev,
-+ "%s: schedule low prio poll\n"
-+ , __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+ __napi_schedule(&priv->low_napi);
-+ }
-+ } else if (qno == 2) {
-+ if (napi_schedule_prep(&priv->lro_napi)) {
-+ netif_info(priv, intr, priv->ndev,
-+ "%s: schedule lro prio poll\n"
-+ , __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+ __napi_schedule(&priv->lro_napi);
-+ }
-+ }
-+
-+ break;
-+
-+ case EVENT_TXDONE_IND:
-+ pfe_eth_flush_tx(priv);
-+ hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0);
-+ break;
-+ case EVENT_HIGH_RX_WM:
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+static int pfe_eth_change_mtu(struct net_device *ndev, int new_mtu)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ ndev->mtu = new_mtu;
-+ new_mtu += ETH_HLEN + ETH_FCS_LEN;
-+ gemac_set_rx_max_fl(priv->EMAC_baseaddr, new_mtu);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_open
-+ */
-+static int pfe_eth_open(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct hif_client_s *client;
-+ int rc;
-+
-+ netif_info(priv, ifup, ndev, "%s\n", __func__);
-+
-+ /* Register client driver with HIF */
-+ client = &priv->client;
-+ memset(client, 0, sizeof(*client));
-+ client->id = PFE_CL_GEM0 + priv->id;
-+ client->tx_qn = emac_txq_cnt;
-+ client->rx_qn = EMAC_RXQ_CNT;
-+ client->priv = priv;
-+ client->pfe = priv->pfe;
-+ client->event_handler = pfe_eth_event_handler;
-+
-+ client->tx_qsize = EMAC_TXQ_DEPTH;
-+ client->rx_qsize = EMAC_RXQ_DEPTH;
-+
-+ rc = hif_lib_client_register(client);
-+ if (rc) {
-+ netdev_err(ndev, "%s: hif_lib_client_register(%d) failed\n",
-+ __func__, client->id);
-+ goto err0;
-+ }
-+
-+ netif_info(priv, drv, ndev, "%s: registered client: %p\n", __func__,
-+ client);
-+
-+ pfe_gemac_init(priv);
-+
-+ if (!is_valid_ether_addr(ndev->dev_addr)) {
-+ netdev_err(ndev, "%s: invalid MAC address\n", __func__);
-+ rc = -EADDRNOTAVAIL;
-+ goto err1;
-+ }
-+
-+ gemac_set_laddrN(priv->EMAC_baseaddr,
-+ (struct pfe_mac_addr *)ndev->dev_addr, 1);
-+
-+ napi_enable(&priv->high_napi);
-+ napi_enable(&priv->low_napi);
-+ napi_enable(&priv->lro_napi);
-+
-+ rc = pfe_eth_start(priv);
-+
-+ netif_tx_wake_all_queues(ndev);
-+
-+ return rc;
-+
-+err1:
-+ hif_lib_client_unregister(&priv->client);
-+
-+err0:
-+ return rc;
-+}
-+
-+/*
-+ * pfe_eth_shutdown
-+ */
-+int pfe_eth_shutdown(struct net_device *ndev, int wake)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int i, qstatus, id;
-+ unsigned long next_poll = jiffies + 1, end = jiffies +
-+ (TX_POLL_TIMEOUT_MS * HZ) / 1000;
-+ int tx_pkts, prv_tx_pkts;
-+
-+ netif_info(priv, ifdown, ndev, "%s\n", __func__);
-+
-+ for (i = 0; i < emac_txq_cnt; i++)
-+ hrtimer_cancel(&priv->fast_tx_timeout[i].timer);
-+
-+ netif_tx_stop_all_queues(ndev);
-+
-+ do {
-+ tx_pkts = 0;
-+ pfe_eth_flush_tx(priv);
-+
-+ for (i = 0; i < emac_txq_cnt; i++)
-+ tx_pkts += hif_lib_tx_pending(&priv->client, i);
-+
-+ if (tx_pkts) {
-+ /*Don't wait forever, break if we cross max timeout */
-+ if (time_after(jiffies, end)) {
-+ pr_err(
-+ "(%s)Tx is not complete after %dmsec\n",
-+ ndev->name, TX_POLL_TIMEOUT_MS);
-+ break;
-+ }
-+
-+ pr_info("%s : (%s) Waiting for tx packets to free. Pending tx pkts = %d.\n"
-+ , __func__, ndev->name, tx_pkts);
-+ if (need_resched())
-+ schedule();
-+ }
-+
-+ } while (tx_pkts);
-+
-+ end = jiffies + (TX_POLL_TIMEOUT_MS * HZ) / 1000;
-+
-+ prv_tx_pkts = tmu_pkts_processed(priv->id);
-+ /*
-+ * Wait till TMU transmits all pending packets
-+ * poll tmu_qstatus and pkts processed by TMU for every 10ms
-+ * Consider TMU is busy, If we see TMU qeueu pending or any packets
-+ * processed by TMU
-+ */
-+ while (1) {
-+ if (time_after(jiffies, next_poll)) {
-+ tx_pkts = tmu_pkts_processed(priv->id);
-+ qstatus = tmu_qstatus(priv->id) & 0x7ffff;
-+
-+ if (!qstatus && (tx_pkts == prv_tx_pkts))
-+ break;
-+ /* Don't wait forever, break if we cross max
-+ * timeout(TX_POLL_TIMEOUT_MS)
-+ */
-+ if (time_after(jiffies, end)) {
-+ pr_err("TMU%d is busy after %dmsec\n",
-+ priv->id, TX_POLL_TIMEOUT_MS);
-+ break;
-+ }
-+ prv_tx_pkts = tx_pkts;
-+ next_poll++;
-+ }
-+ if (need_resched())
-+ schedule();
-+ }
-+ /* Wait for some more time to complete transmitting packet if any */
-+ next_poll = jiffies + 1;
-+ while (1) {
-+ if (time_after(jiffies, next_poll))
-+ break;
-+ if (need_resched())
-+ schedule();
-+ }
-+
-+ pfe_eth_stop(ndev, wake);
-+
-+ napi_disable(&priv->lro_napi);
-+ napi_disable(&priv->low_napi);
-+ napi_disable(&priv->high_napi);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ pe_dmem_write(id, 0, CLASS_DM_CRC_VALIDATED
-+ + (priv->id * 4), 4);
-+ }
-+
-+ hif_lib_client_unregister(&priv->client);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_close
-+ *
-+ */
-+static int pfe_eth_close(struct net_device *ndev)
-+{
-+ pfe_eth_shutdown(ndev, 0);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_suspend
-+ *
-+ * return value : 1 if netdevice is configured to wakeup system
-+ * 0 otherwise
-+ */
-+int pfe_eth_suspend(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int retval = 0;
-+
-+ if (priv->wol) {
-+ gemac_set_wol(priv->EMAC_baseaddr, priv->wol);
-+ retval = 1;
-+ }
-+ pfe_eth_shutdown(ndev, priv->wol);
-+
-+ return retval;
-+}
-+
-+/* pfe_eth_resume
-+ *
-+ */
-+int pfe_eth_resume(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ if (priv->wol)
-+ gemac_set_wol(priv->EMAC_baseaddr, 0);
-+ gemac_tx_enable(priv->EMAC_baseaddr);
-+
-+ return pfe_eth_open(ndev);
-+}
-+
-+/* pfe_eth_get_queuenum
-+ */
-+static int pfe_eth_get_queuenum(struct pfe_eth_priv_s *priv, struct sk_buff
-+ *skb)
-+{
-+ int queuenum = 0;
-+ unsigned long flags;
-+
-+ /* Get the Fast Path queue number */
-+ /*
-+ * Use conntrack mark (if conntrack exists), then packet mark (if any),
-+ * then fallback to default
-+ */
-+#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK)
-+ if (skb->_nfct) {
-+ enum ip_conntrack_info cinfo;
-+ struct nf_conn *ct;
-+
-+ ct = nf_ct_get(skb, &cinfo);
-+
-+ if (ct) {
-+ u32 connmark;
-+
-+ connmark = ct->mark;
-+
-+ if ((connmark & 0x80000000) && priv->id != 0)
-+ connmark >>= 16;
-+
-+ queuenum = connmark & EMAC_QUEUENUM_MASK;
-+ }
-+ } else {/* continued after #endif ... */
-+#endif
-+ if (skb->mark) {
-+ queuenum = skb->mark & EMAC_QUEUENUM_MASK;
-+ } else {
-+ spin_lock_irqsave(&priv->lock, flags);
-+ queuenum = priv->default_priority & EMAC_QUEUENUM_MASK;
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+ }
-+#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK)
-+ }
-+#endif
-+ return queuenum;
-+}
-+
-+/* pfe_eth_might_stop_tx
-+ *
-+ */
-+static int pfe_eth_might_stop_tx(struct pfe_eth_priv_s *priv, int queuenum,
-+ struct netdev_queue *tx_queue,
-+ unsigned int n_desc,
-+ unsigned int n_segs)
-+{
-+ ktime_t kt;
-+ int tried = 0;
-+
-+try_again:
-+ if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc) ||
-+ (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) ||
-+ (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) {
-+ if (!tried) {
-+ __hif_lib_update_credit(&priv->client, queuenum);
-+ tried = 1;
-+ goto try_again;
-+ }
-+#ifdef PFE_ETH_TX_STATS
-+ if (__hif_tx_avail(&pfe->hif) < n_desc) {
-+ priv->stop_queue_hif[queuenum]++;
-+ } else if (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) {
-+ priv->stop_queue_hif_client[queuenum]++;
-+ } else if (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) <
-+ n_segs) {
-+ priv->stop_queue_credit[queuenum]++;
-+ }
-+ priv->stop_queue_total[queuenum]++;
-+#endif
-+ netif_tx_stop_queue(tx_queue);
-+
-+ kt = ktime_set(0, LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS *
-+ NSEC_PER_MSEC);
-+ hrtimer_start(&priv->fast_tx_timeout[queuenum].timer, kt,
-+ HRTIMER_MODE_REL);
-+ return -1;
-+ } else {
-+ return 0;
-+ }
-+}
-+
-+#define SA_MAX_OP 2
-+/* pfe_hif_send_packet
-+ *
-+ * At this level if TX fails we drop the packet
-+ */
-+static void pfe_hif_send_packet(struct sk_buff *skb, struct pfe_eth_priv_s
-+ *priv, int queuenum)
-+{
-+ struct skb_shared_info *sh = skb_shinfo(skb);
-+ unsigned int nr_frags;
-+ u32 ctrl = 0;
-+
-+ netif_info(priv, tx_queued, priv->ndev, "%s\n", __func__);
-+
-+ if (skb_is_gso(skb)) {
-+ priv->stats.tx_dropped++;
-+ return;
-+ }
-+
-+ if (skb->ip_summed == CHECKSUM_PARTIAL)
-+ ctrl = HIF_CTRL_TX_CHECKSUM;
-+
-+ nr_frags = sh->nr_frags;
-+
-+ if (nr_frags) {
-+ skb_frag_t *f;
-+ int i;
-+
-+ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data,
-+ skb_headlen(skb), ctrl, HIF_FIRST_BUFFER,
-+ skb);
-+
-+ for (i = 0; i < nr_frags - 1; i++) {
-+ f = &sh->frags[i];
-+ __hif_lib_xmit_pkt(&priv->client, queuenum,
-+ skb_frag_address(f),
-+ skb_frag_size(f),
-+ 0x0, 0x0, skb);
-+ }
-+
-+ f = &sh->frags[i];
-+
-+ __hif_lib_xmit_pkt(&priv->client, queuenum,
-+ skb_frag_address(f), skb_frag_size(f),
-+ 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID,
-+ skb);
-+
-+ netif_info(priv, tx_queued, priv->ndev,
-+ "%s: pkt sent successfully skb:%p nr_frags:%d len:%d\n",
-+ __func__, skb, nr_frags, skb->len);
-+ } else {
-+ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data,
-+ skb->len, ctrl, HIF_FIRST_BUFFER |
-+ HIF_LAST_BUFFER | HIF_DATA_VALID,
-+ skb);
-+ netif_info(priv, tx_queued, priv->ndev,
-+ "%s: pkt sent successfully skb:%p len:%d\n",
-+ __func__, skb, skb->len);
-+ }
-+ hif_tx_dma_start();
-+ priv->stats.tx_packets++;
-+ priv->stats.tx_bytes += skb->len;
-+ hif_lib_tx_credit_use(pfe, priv->id, queuenum, 1);
-+}
-+
-+/* pfe_eth_flush_txQ
-+ */
-+static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
-+ from_tx, int n_desc)
-+{
-+ struct sk_buff *skb;
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ tx_q_num);
-+ unsigned int flags;
-+
-+ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__);
-+
-+ if (!from_tx)
-+ __netif_tx_lock_bh(tx_queue);
-+
-+ /* Clean HIF and client queue */
-+ while ((skb = hif_lib_tx_get_next_complete(&priv->client,
-+ tx_q_num, &flags,
-+ HIF_TX_DESC_NT))) {
-+ if (flags & HIF_DATA_VALID)
-+ dev_kfree_skb_any(skb);
-+ }
-+ if (!from_tx)
-+ __netif_tx_unlock_bh(tx_queue);
-+}
-+
-+/* pfe_eth_flush_tx
-+ */
-+static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv)
-+{
-+ int ii;
-+
-+ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__);
-+
-+ for (ii = 0; ii < emac_txq_cnt; ii++) {
-+ pfe_eth_flush_txQ(priv, ii, 0, 0);
-+ __hif_lib_update_credit(&priv->client, ii);
-+ }
-+}
-+
-+void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int
-+ *n_segs)
-+{
-+ struct skb_shared_info *sh = skb_shinfo(skb);
-+
-+ /* Scattered data */
-+ if (sh->nr_frags) {
-+ *n_desc = sh->nr_frags + 1;
-+ *n_segs = 1;
-+ /* Regular case */
-+ } else {
-+ *n_desc = 1;
-+ *n_segs = 1;
-+ }
-+}
-+
-+/* pfe_eth_send_packet
-+ */
-+static int pfe_eth_send_packet(struct sk_buff *skb, struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int tx_q_num = skb_get_queue_mapping(skb);
-+ int n_desc, n_segs;
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ tx_q_num);
-+
-+ netif_info(priv, tx_queued, ndev, "%s\n", __func__);
-+
-+ if ((!skb_is_gso(skb)) && (skb_headroom(skb) < (PFE_PKT_HEADER_SZ +
-+ sizeof(unsigned long)))) {
-+ netif_warn(priv, tx_err, priv->ndev, "%s: copying skb\n",
-+ __func__);
-+
-+ if (pskb_expand_head(skb, (PFE_PKT_HEADER_SZ + sizeof(unsigned
-+ long)), 0, GFP_ATOMIC)) {
-+ /* No need to re-transmit, no way to recover*/
-+ kfree_skb(skb);
-+ priv->stats.tx_dropped++;
-+ return NETDEV_TX_OK;
-+ }
-+ }
-+
-+ pfe_tx_get_req_desc(skb, &n_desc, &n_segs);
-+
-+ hif_tx_lock(&pfe->hif);
-+ if (unlikely(pfe_eth_might_stop_tx(priv, tx_q_num, tx_queue, n_desc,
-+ n_segs))) {
-+#ifdef PFE_ETH_TX_STATS
-+ if (priv->was_stopped[tx_q_num]) {
-+ priv->clean_fail[tx_q_num]++;
-+ priv->was_stopped[tx_q_num] = 0;
-+ }
-+#endif
-+ hif_tx_unlock(&pfe->hif);
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ pfe_hif_send_packet(skb, priv, tx_q_num);
-+
-+ hif_tx_unlock(&pfe->hif);
-+
-+ tx_queue->trans_start = jiffies;
-+
-+#ifdef PFE_ETH_TX_STATS
-+ priv->was_stopped[tx_q_num] = 0;
-+#endif
-+
-+ return NETDEV_TX_OK;
-+}
-+
-+/* pfe_eth_select_queue
-+ *
-+ */
-+static u16 pfe_eth_select_queue(struct net_device *ndev, struct sk_buff *skb,
-+ struct net_device *sb_dev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ return pfe_eth_get_queuenum(priv, skb);
-+}
-+
-+/* pfe_eth_get_stats
-+ */
-+static struct net_device_stats *pfe_eth_get_stats(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ return &priv->stats;
-+}
-+
-+/* pfe_eth_set_mac_address
-+ */
-+static int pfe_eth_set_mac_address(struct net_device *ndev, void *addr)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct sockaddr *sa = addr;
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ if (!is_valid_ether_addr(sa->sa_data))
-+ return -EADDRNOTAVAIL;
-+
-+ dev_addr_set(ndev, sa->sa_data);
-+
-+ gemac_set_laddrN(priv->EMAC_baseaddr,
-+ (struct pfe_mac_addr *)ndev->dev_addr, 1);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_enet_addr_byte_mac
-+ */
-+int pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr,
-+ struct pfe_mac_addr *enet_addr)
-+{
-+ if (!enet_byte_addr || !enet_addr) {
-+ return -1;
-+
-+ } else {
-+ enet_addr->bottom = enet_byte_addr[0] |
-+ (enet_byte_addr[1] << 8) |
-+ (enet_byte_addr[2] << 16) |
-+ (enet_byte_addr[3] << 24);
-+ enet_addr->top = enet_byte_addr[4] |
-+ (enet_byte_addr[5] << 8);
-+ return 0;
-+ }
-+}
-+
-+/* pfe_eth_set_multi
-+ */
-+static void pfe_eth_set_multi(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct pfe_mac_addr hash_addr; /* hash register structure */
-+ /* specific mac address register structure */
-+ struct pfe_mac_addr spec_addr;
-+ int result; /* index into hash register to set.. */
-+ int uc_count = 0;
-+ struct netdev_hw_addr *ha;
-+
-+ if (ndev->flags & IFF_PROMISC) {
-+ netif_info(priv, drv, ndev, "entering promiscuous mode\n");
-+
-+ priv->promisc = 1;
-+ gemac_enable_copy_all(priv->EMAC_baseaddr);
-+ } else {
-+ priv->promisc = 0;
-+ gemac_disable_copy_all(priv->EMAC_baseaddr);
-+ }
-+
-+ /* Enable broadcast frame reception if required. */
-+ if (ndev->flags & IFF_BROADCAST) {
-+ gemac_allow_broadcast(priv->EMAC_baseaddr);
-+ } else {
-+ netif_info(priv, drv, ndev,
-+ "disabling broadcast frame reception\n");
-+
-+ gemac_no_broadcast(priv->EMAC_baseaddr);
-+ }
-+
-+ if (ndev->flags & IFF_ALLMULTI) {
-+ /* Set the hash to rx all multicast frames */
-+ hash_addr.bottom = 0xFFFFFFFF;
-+ hash_addr.top = 0xFFFFFFFF;
-+ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
-+ netdev_for_each_uc_addr(ha, ndev) {
-+ if (uc_count >= MAX_UC_SPEC_ADDR_REG)
-+ break;
-+ pfe_eth_enet_addr_byte_mac(ha->addr, &spec_addr);
-+ gemac_set_laddrN(priv->EMAC_baseaddr, &spec_addr,
-+ uc_count + 2);
-+ uc_count++;
-+ }
-+ } else if ((netdev_mc_count(ndev) > 0) || (netdev_uc_count(ndev))) {
-+ u8 *addr;
-+
-+ hash_addr.bottom = 0;
-+ hash_addr.top = 0;
-+
-+ netdev_for_each_mc_addr(ha, ndev) {
-+ addr = ha->addr;
-+
-+ netif_info(priv, drv, ndev,
-+ "adding multicast address %X:%X:%X:%X:%X:%X to gem filter\n",
-+ addr[0], addr[1], addr[2],
-+ addr[3], addr[4], addr[5]);
-+
-+ result = pfe_eth_get_hash(addr);
-+
-+ if (result < EMAC_HASH_REG_BITS) {
-+ if (result < 32)
-+ hash_addr.bottom |= (1 << result);
-+ else
-+ hash_addr.top |= (1 << (result - 32));
-+ } else {
-+ break;
-+ }
-+ }
-+
-+ uc_count = -1;
-+ netdev_for_each_uc_addr(ha, ndev) {
-+ addr = ha->addr;
-+
-+ if (++uc_count < MAX_UC_SPEC_ADDR_REG) {
-+ netdev_info(ndev,
-+ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem filter\n",
-+ addr[0], addr[1], addr[2],
-+ addr[3], addr[4], addr[5]);
-+ pfe_eth_enet_addr_byte_mac(addr, &spec_addr);
-+ gemac_set_laddrN(priv->EMAC_baseaddr,
-+ &spec_addr, uc_count + 2);
-+ } else {
-+ netif_info(priv, drv, ndev,
-+ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem hash\n",
-+ addr[0], addr[1], addr[2],
-+ addr[3], addr[4], addr[5]);
-+
-+ result = pfe_eth_get_hash(addr);
-+ if (result >= EMAC_HASH_REG_BITS) {
-+ break;
-+
-+ } else {
-+ if (result < 32)
-+ hash_addr.bottom |= (1 <<
-+ result);
-+ else
-+ hash_addr.top |= (1 <<
-+ (result - 32));
-+ }
-+ }
-+ }
-+
-+ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
-+ }
-+
-+ if (!(netdev_uc_count(ndev) >= MAX_UC_SPEC_ADDR_REG)) {
-+ /*
-+ * Check if there are any specific address HW registers that
-+ * need to be flushed
-+ */
-+ for (uc_count = netdev_uc_count(ndev); uc_count <
-+ MAX_UC_SPEC_ADDR_REG; uc_count++)
-+ gemac_clear_laddrN(priv->EMAC_baseaddr, uc_count + 2);
-+ }
-+
-+ if (ndev->flags & IFF_LOOPBACK)
-+ gemac_set_loop(priv->EMAC_baseaddr, LB_LOCAL);
-+}
-+
-+/* pfe_eth_set_features
-+ */
-+static int pfe_eth_set_features(struct net_device *ndev, netdev_features_t
-+ features)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int rc = 0;
-+
-+ if (features & NETIF_F_RXCSUM)
-+ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
-+ else
-+ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
-+ return rc;
-+}
-+
-+/* pfe_eth_fast_tx_timeout
-+ */
-+static enum hrtimer_restart pfe_eth_fast_tx_timeout(struct hrtimer *timer)
-+{
-+ struct pfe_eth_fast_timer *fast_tx_timeout = container_of(timer, struct
-+ pfe_eth_fast_timer,
-+ timer);
-+ struct pfe_eth_priv_s *priv = container_of(fast_tx_timeout->base,
-+ struct pfe_eth_priv_s,
-+ fast_tx_timeout);
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ fast_tx_timeout->queuenum);
-+
-+ if (netif_tx_queue_stopped(tx_queue)) {
-+#ifdef PFE_ETH_TX_STATS
-+ priv->was_stopped[fast_tx_timeout->queuenum] = 1;
-+#endif
-+ netif_tx_wake_queue(tx_queue);
-+ }
-+
-+ return HRTIMER_NORESTART;
-+}
-+
-+/* pfe_eth_fast_tx_timeout_init
-+ */
-+static void pfe_eth_fast_tx_timeout_init(struct pfe_eth_priv_s *priv)
-+{
-+ int i;
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ priv->fast_tx_timeout[i].queuenum = i;
-+ hrtimer_init(&priv->fast_tx_timeout[i].timer, CLOCK_MONOTONIC,
-+ HRTIMER_MODE_REL);
-+ priv->fast_tx_timeout[i].timer.function =
-+ pfe_eth_fast_tx_timeout;
-+ priv->fast_tx_timeout[i].base = priv->fast_tx_timeout;
-+ }
-+}
-+
-+static struct sk_buff *pfe_eth_rx_skb(struct net_device *ndev,
-+ struct pfe_eth_priv_s *priv,
-+ unsigned int qno)
-+{
-+ void *buf_addr;
-+ unsigned int rx_ctrl;
-+ unsigned int desc_ctrl = 0;
-+ struct hif_ipsec_hdr *ipsec_hdr = NULL;
-+ struct sk_buff *skb;
-+ struct sk_buff *skb_frag, *skb_frag_last = NULL;
-+ int length = 0, offset;
-+
-+ skb = priv->skb_inflight[qno];
-+
-+ if (skb) {
-+ skb_frag_last = skb_shinfo(skb)->frag_list;
-+ if (skb_frag_last) {
-+ while (skb_frag_last->next)
-+ skb_frag_last = skb_frag_last->next;
-+ }
-+ }
-+
-+ while (!(desc_ctrl & CL_DESC_LAST)) {
-+ buf_addr = hif_lib_receive_pkt(&priv->client, qno, &length,
-+ &offset, &rx_ctrl, &desc_ctrl,
-+ (void **)&ipsec_hdr);
-+ if (!buf_addr)
-+ goto incomplete;
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_DESC_COUNT]++;
-+#endif
-+
-+ /* First frag */
-+ if (desc_ctrl & CL_DESC_FIRST) {
-+ skb = build_skb(buf_addr, 0);
-+ if (unlikely(!skb))
-+ goto pkt_drop;
-+
-+ skb_reserve(skb, offset);
-+ skb_put(skb, length);
-+ skb->dev = ndev;
-+
-+ if ((ndev->features & NETIF_F_RXCSUM) && (rx_ctrl &
-+ HIF_CTRL_RX_CHECKSUMMED))
-+ skb->ip_summed = CHECKSUM_UNNECESSARY;
-+ else
-+ skb_checksum_none_assert(skb);
-+
-+ } else {
-+ /* Next frags */
-+ if (unlikely(!skb)) {
-+ pr_err("%s: NULL skb_inflight\n",
-+ __func__);
-+ goto pkt_drop;
-+ }
-+
-+ skb_frag = build_skb(buf_addr, 0);
-+
-+ if (unlikely(!skb_frag)) {
-+ kfree(buf_addr);
-+ goto pkt_drop;
-+ }
-+
-+ skb_reserve(skb_frag, offset);
-+ skb_put(skb_frag, length);
-+
-+ skb_frag->dev = ndev;
-+
-+ if (skb_shinfo(skb)->frag_list)
-+ skb_frag_last->next = skb_frag;
-+ else
-+ skb_shinfo(skb)->frag_list = skb_frag;
-+
-+ skb->truesize += skb_frag->truesize;
-+ skb->data_len += length;
-+ skb->len += length;
-+ skb_frag_last = skb_frag;
-+ }
-+ }
-+
-+ priv->skb_inflight[qno] = NULL;
-+ return skb;
-+
-+incomplete:
-+ priv->skb_inflight[qno] = skb;
-+ return NULL;
-+
-+pkt_drop:
-+ priv->skb_inflight[qno] = NULL;
-+
-+ if (skb)
-+ kfree_skb(skb);
-+ else
-+ kfree(buf_addr);
-+
-+ priv->stats.rx_errors++;
-+
-+ return NULL;
-+}
-+
-+/* pfe_eth_poll
-+ */
-+static int pfe_eth_poll(struct pfe_eth_priv_s *priv, struct napi_struct *napi,
-+ unsigned int qno, int budget)
-+{
-+ struct net_device *ndev = priv->ndev;
-+ struct sk_buff *skb;
-+ int work_done = 0;
-+ unsigned int len;
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_POLL_COUNT]++;
-+#endif
-+
-+ do {
-+ skb = pfe_eth_rx_skb(ndev, priv, qno);
-+
-+ if (!skb)
-+ break;
-+
-+ len = skb->len;
-+
-+ /* Packet will be processed */
-+ skb->protocol = eth_type_trans(skb, ndev);
-+
-+ netif_receive_skb(skb);
-+
-+ priv->stats.rx_packets++;
-+ priv->stats.rx_bytes += len;
-+
-+ work_done++;
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_PACKET_COUNT]++;
-+#endif
-+
-+ } while (work_done < budget);
-+
-+ /*
-+ * If no Rx receive nor cleanup work was done, exit polling mode.
-+ * No more netif_running(dev) check is required here , as this is
-+ * checked in net/core/dev.c (2.6.33.5 kernel specific).
-+ */
-+ if (work_done < budget) {
-+ napi_complete(napi);
-+
-+ hif_lib_event_handler_start(&priv->client, EVENT_RX_PKT_IND,
-+ qno);
-+ }
-+#ifdef PFE_ETH_NAPI_STATS
-+ else
-+ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
-+#endif
-+
-+ return work_done;
-+}
-+
-+/*
-+ * pfe_eth_lro_poll
-+ */
-+static int pfe_eth_lro_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
-+ lro_napi);
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+ return pfe_eth_poll(priv, napi, 2, budget);
-+}
-+
-+/* pfe_eth_low_poll
-+ */
-+static int pfe_eth_low_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
-+ low_napi);
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+ return pfe_eth_poll(priv, napi, 1, budget);
-+}
-+
-+/* pfe_eth_high_poll
-+ */
-+static int pfe_eth_high_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
-+ high_napi);
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+ return pfe_eth_poll(priv, napi, 0, budget);
-+}
-+
-+static const struct net_device_ops pfe_netdev_ops = {
-+ .ndo_open = pfe_eth_open,
-+ .ndo_stop = pfe_eth_close,
-+ .ndo_start_xmit = pfe_eth_send_packet,
-+ .ndo_select_queue = pfe_eth_select_queue,
-+ .ndo_set_rx_mode = pfe_eth_set_multi,
-+ .ndo_set_mac_address = pfe_eth_set_mac_address,
-+ .ndo_validate_addr = eth_validate_addr,
-+ .ndo_change_mtu = pfe_eth_change_mtu,
-+ .ndo_get_stats = pfe_eth_get_stats,
-+ .ndo_set_features = pfe_eth_set_features,
-+};
-+
-+/* pfe_eth_init_one
-+ */
-+static int pfe_eth_init_one(struct pfe *pfe,
-+ struct ls1012a_pfe_platform_data *pfe_info,
-+ int id)
-+{
-+ struct net_device *ndev = NULL;
-+ struct pfe_eth_priv_s *priv = NULL;
-+ struct ls1012a_eth_platform_data *einfo;
-+ int err;
-+
-+ einfo = (struct ls1012a_eth_platform_data *)
-+ pfe_info->ls1012a_eth_pdata;
-+
-+ /* einfo never be NULL, but no harm in having this check */
-+ if (!einfo) {
-+ pr_err(
-+ "%s: pfe missing additional gemacs platform data\n"
-+ , __func__);
-+ err = -ENODEV;
-+ goto err0;
-+ }
-+
-+ if (us)
-+ emac_txq_cnt = EMAC_TXQ_CNT;
-+ /* Create an ethernet device instance */
-+ ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt);
-+
-+ if (!ndev) {
-+ pr_err("%s: gemac %d device allocation failed\n",
-+ __func__, einfo[id].gem_id);
-+ err = -ENOMEM;
-+ goto err0;
-+ }
-+
-+ priv = netdev_priv(ndev);
-+ priv->ndev = ndev;
-+ priv->id = einfo[id].gem_id;
-+ priv->pfe = pfe;
-+ priv->phy_node = einfo[id].phy_node;
-+
-+ SET_NETDEV_DEV(priv->ndev, priv->pfe->dev);
-+
-+ pfe->eth.eth_priv[id] = priv;
-+
-+ /* Set the info in the priv to the current info */
-+ priv->einfo = &einfo[id];
-+ priv->EMAC_baseaddr = cbus_emac_base[id];
-+ priv->GPI_baseaddr = cbus_gpi_base[id];
-+
-+ spin_lock_init(&priv->lock);
-+
-+ pfe_eth_fast_tx_timeout_init(priv);
-+
-+ /* Copy the station address into the dev structure, */
-+ dev_addr_set(ndev, einfo[id].mac_addr);
-+
-+ if (us)
-+ goto phy_init;
-+
-+ ndev->mtu = 1500;
-+
-+ /* Set MTU limits */
-+ ndev->min_mtu = ETH_MIN_MTU;
-+
-+/*
-+ * Jumbo frames are not supported on LS1012A rev-1.0.
-+ * So max mtu should be restricted to supported frame length.
-+ */
-+ if (pfe_errata_a010897)
-+ ndev->max_mtu = JUMBO_FRAME_SIZE_V1 - ETH_HLEN - ETH_FCS_LEN;
-+ else
-+ ndev->max_mtu = JUMBO_FRAME_SIZE_V2 - ETH_HLEN - ETH_FCS_LEN;
-+
-+ /*Enable after checksum offload is validated */
-+ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
-+ NETIF_F_IPV6_CSUM | NETIF_F_SG;
-+
-+ /* enabled by default */
-+ ndev->features = ndev->hw_features;
-+
-+ priv->usr_features = ndev->features;
-+
-+ ndev->netdev_ops = &pfe_netdev_ops;
-+
-+ ndev->ethtool_ops = &pfe_ethtool_ops;
-+
-+ /* Enable basic messages by default */
-+ priv->msg_enable = NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK |
-+ NETIF_MSG_PROBE;
-+
-+ netif_napi_add(ndev, &priv->low_napi, pfe_eth_low_poll);
-+ netif_napi_add(ndev, &priv->high_napi, pfe_eth_high_poll);
-+ netif_napi_add(ndev, &priv->lro_napi, pfe_eth_lro_poll);
-+
-+ err = register_netdev(ndev);
-+ if (err) {
-+ netdev_err(ndev, "register_netdev() failed\n");
-+ goto err1;
-+ }
-+
-+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
-+ ((pfe_use_old_dts_phy) &&
-+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
-+ pr_info("%s: No PHY or fixed-link\n", __func__);
-+ goto skip_phy_init;
-+ }
-+
-+phy_init:
-+ device_init_wakeup(&ndev->dev, true);
-+
-+ err = pfe_phy_init(ndev);
-+ if (err) {
-+ netdev_err(ndev, "%s: pfe_phy_init() failed\n",
-+ __func__);
-+ goto err2;
-+ }
-+
-+ if (us) {
-+ if (priv->phydev)
-+ phy_start(priv->phydev);
-+ return 0;
-+ }
-+
-+ netif_carrier_on(ndev);
-+
-+skip_phy_init:
-+ /* Create all the sysfs files */
-+ if (pfe_eth_sysfs_init(ndev))
-+ goto err3;
-+
-+ netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n",
-+ __func__, priv->EMAC_baseaddr);
-+
-+ return 0;
-+
-+err3:
-+ pfe_phy_exit(priv->ndev);
-+err2:
-+ if (us)
-+ goto err1;
-+ unregister_netdev(ndev);
-+err1:
-+ free_netdev(priv->ndev);
-+err0:
-+ return err;
-+}
-+
-+/* pfe_eth_init
-+ */
-+int pfe_eth_init(struct pfe *pfe)
-+{
-+ int ii = 0;
-+ int err;
-+ struct ls1012a_pfe_platform_data *pfe_info;
-+
-+ pr_info("%s\n", __func__);
-+
-+ cbus_emac_base[0] = EMAC1_BASE_ADDR;
-+ cbus_emac_base[1] = EMAC2_BASE_ADDR;
-+
-+ cbus_gpi_base[0] = EGPI1_BASE_ADDR;
-+ cbus_gpi_base[1] = EGPI2_BASE_ADDR;
-+
-+ pfe_info = (struct ls1012a_pfe_platform_data *)
-+ pfe->dev->platform_data;
-+ if (!pfe_info) {
-+ pr_err("%s: pfe missing additional platform data\n", __func__);
-+ err = -ENODEV;
-+ goto err_pdata;
-+ }
-+
-+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-+ err = pfe_eth_mdio_init(pfe, pfe_info, ii);
-+ if (err) {
-+ pr_err("%s: pfe_eth_mdio_init() failed\n", __func__);
-+ goto err_mdio_init;
-+ }
-+ }
-+
-+ if (soc_device_match(ls1012a_rev1_soc_attr))
-+ pfe_errata_a010897 = true;
-+ else
-+ pfe_errata_a010897 = false;
-+
-+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-+ err = pfe_eth_init_one(pfe, pfe_info, ii);
-+ if (err)
-+ goto err_eth_init;
-+ }
-+
-+ return 0;
-+
-+err_eth_init:
-+ while (ii--) {
-+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
-+ pfe_eth_mdio_exit(pfe, ii);
-+ }
-+
-+err_mdio_init:
-+err_pdata:
-+ return err;
-+}
-+
-+/* pfe_eth_exit_one
-+ */
-+static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv)
-+{
-+ netif_info(priv, probe, priv->ndev, "%s\n", __func__);
-+
-+ if (!us)
-+ pfe_eth_sysfs_exit(priv->ndev);
-+
-+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
-+ ((pfe_use_old_dts_phy) &&
-+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
-+ pr_info("%s: No PHY or fixed-link\n", __func__);
-+ goto skip_phy_exit;
-+ }
-+
-+ pfe_phy_exit(priv->ndev);
-+
-+skip_phy_exit:
-+ if (!us)
-+ unregister_netdev(priv->ndev);
-+
-+ free_netdev(priv->ndev);
-+}
-+
-+/* pfe_eth_exit
-+ */
-+void pfe_eth_exit(struct pfe *pfe)
-+{
-+ int ii;
-+
-+ pr_info("%s\n", __func__);
-+
-+ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
-+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
-+
-+ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
-+ pfe_eth_mdio_exit(pfe, ii);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_eth.h
-@@ -0,0 +1,175 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_ETH_H_
-+#define _PFE_ETH_H_
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ethtool.h>
-+#include <linux/mii.h>
-+#include <linux/phy.h>
-+#include <linux/clk.h>
-+#include <linux/interrupt.h>
-+#include <linux/time.h>
-+
-+#define PFE_ETH_NAPI_STATS
-+#define PFE_ETH_TX_STATS
-+
-+#define PFE_ETH_FRAGS_MAX (65536 / HIF_RX_PKT_MIN_SIZE)
-+#define LRO_LEN_COUNT_MAX 32
-+#define LRO_NB_COUNT_MAX 32
-+
-+#define PFE_PAUSE_FLAG_ENABLE 1
-+#define PFE_PAUSE_FLAG_AUTONEG 2
-+
-+/* GEMAC configured by SW */
-+/* GEMAC configured by phy lines (not for MII/GMII) */
-+
-+#define GEMAC_SW_FULL_DUPLEX BIT(9)
-+#define GEMAC_SW_SPEED_10M (0 << 12)
-+#define GEMAC_SW_SPEED_100M BIT(12)
-+#define GEMAC_SW_SPEED_1G (2 << 12)
-+
-+#define GEMAC_NO_PHY BIT(0)
-+
-+struct ls1012a_eth_platform_data {
-+ /* board specific information */
-+ phy_interface_t mii_config;
-+ u32 phy_flags;
-+ u32 gem_id;
-+ u32 phy_id;
-+ u32 mdio_muxval;
-+ u8 mac_addr[ETH_ALEN];
-+ struct device_node *phy_node;
-+};
-+
-+struct ls1012a_mdio_platform_data {
-+ int id;
-+ int irq[32];
-+ u32 phy_mask;
-+ int mdc_div;
-+};
-+
-+struct ls1012a_pfe_platform_data {
-+ struct ls1012a_eth_platform_data ls1012a_eth_pdata[3];
-+ struct ls1012a_mdio_platform_data ls1012a_mdio_pdata[3];
-+};
-+
-+#define NUM_GEMAC_SUPPORT 2
-+#define DRV_NAME "pfe-eth"
-+#define DRV_VERSION "1.0"
-+
-+#define LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS 3
-+#define TX_POLL_TIMEOUT_MS 1000
-+
-+#define EMAC_TXQ_CNT 16
-+#define EMAC_TXQ_DEPTH (HIF_TX_DESC_NT)
-+
-+#define JUMBO_FRAME_SIZE_V1 1900
-+#define JUMBO_FRAME_SIZE_V2 10258
-+/*
-+ * Client Tx queue threshold, for txQ flush condition.
-+ * It must be smaller than the queue size (in case we ever change it in the
-+ * future).
-+ */
-+#define HIF_CL_TX_FLUSH_MARK 32
-+
-+/*
-+ * Max number of TX resources (HIF descriptors or skbs) that will be released
-+ * in a single go during batch recycling.
-+ * Should be lower than the flush mark so the SW can provide the HW with a
-+ * continuous stream of packets instead of bursts.
-+ */
-+#define TX_FREE_MAX_COUNT 16
-+#define EMAC_RXQ_CNT 3
-+#define EMAC_RXQ_DEPTH HIF_RX_DESC_NT
-+/* make sure clients can receive a full burst of packets */
-+#define EMAC_RMON_TXBYTES_POS 0x00
-+#define EMAC_RMON_RXBYTES_POS 0x14
-+
-+#define EMAC_QUEUENUM_MASK (emac_txq_cnt - 1)
-+#define EMAC_MDIO_TIMEOUT 1000
-+#define MAX_UC_SPEC_ADDR_REG 31
-+
-+struct pfe_eth_fast_timer {
-+ int queuenum;
-+ struct hrtimer timer;
-+ void *base;
-+};
-+
-+struct pfe_eth_priv_s {
-+ struct pfe *pfe;
-+ struct hif_client_s client;
-+ struct napi_struct lro_napi;
-+ struct napi_struct low_napi;
-+ struct napi_struct high_napi;
-+ int low_tmu_q;
-+ int high_tmu_q;
-+ struct net_device_stats stats;
-+ struct net_device *ndev;
-+ int id;
-+ int promisc;
-+ unsigned int msg_enable;
-+ unsigned int usr_features;
-+
-+ spinlock_t lock; /* protect member variables */
-+ unsigned int event_status;
-+ int irq;
-+ void *EMAC_baseaddr;
-+ void *GPI_baseaddr;
-+ /* PHY stuff */
-+ struct phy_device *phydev;
-+ int oldspeed;
-+ int oldduplex;
-+ int oldlink;
-+ struct device_node *phy_node;
-+ struct clk *gemtx_clk;
-+ int wol;
-+ int pause_flag;
-+
-+ int default_priority;
-+ struct pfe_eth_fast_timer fast_tx_timeout[EMAC_TXQ_CNT];
-+
-+ struct ls1012a_eth_platform_data *einfo;
-+ struct sk_buff *skb_inflight[EMAC_RXQ_CNT + 6];
-+
-+#ifdef PFE_ETH_TX_STATS
-+ unsigned int stop_queue_total[EMAC_TXQ_CNT];
-+ unsigned int stop_queue_hif[EMAC_TXQ_CNT];
-+ unsigned int stop_queue_hif_client[EMAC_TXQ_CNT];
-+ unsigned int stop_queue_credit[EMAC_TXQ_CNT];
-+ unsigned int clean_fail[EMAC_TXQ_CNT];
-+ unsigned int was_stopped[EMAC_TXQ_CNT];
-+#endif
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ unsigned int napi_counters[NAPI_MAX_COUNT];
-+#endif
-+ unsigned int frags_inflight[EMAC_RXQ_CNT + 6];
-+};
-+
-+struct pfe_eth {
-+ struct pfe_eth_priv_s *eth_priv[3];
-+};
-+
-+struct pfe_mdio_priv_s {
-+ void __iomem *mdio_base;
-+ int mdc_div;
-+ struct mii_bus *mii_bus;
-+};
-+
-+struct pfe_mdio {
-+ struct pfe_mdio_priv_s *mdio_priv[3];
-+};
-+
-+int pfe_eth_init(struct pfe *pfe);
-+void pfe_eth_exit(struct pfe *pfe);
-+int pfe_eth_suspend(struct net_device *dev);
-+int pfe_eth_resume(struct net_device *dev);
-+int pfe_eth_mdio_reset(struct mii_bus *bus);
-+
-+#endif /* _PFE_ETH_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_firmware.c
-@@ -0,0 +1,398 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+/*
-+ * @file
-+ * Contains all the functions to handle parsing and loading of PE firmware
-+ * files.
-+ */
-+#include <linux/firmware.h>
-+
-+#include "pfe_mod.h"
-+#include "pfe_firmware.h"
-+#include "pfe/pfe.h"
-+#include <linux/of_platform.h>
-+#include <linux/of_address.h>
-+
-+static struct elf32_shdr *get_elf_section_header(const u8 *fw,
-+ const char *section)
-+{
-+ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw;
-+ struct elf32_shdr *shdr;
-+ struct elf32_shdr *shdr_shstr;
-+ Elf32_Off e_shoff = be32_to_cpu(elf_hdr->e_shoff);
-+ Elf32_Half e_shentsize = be16_to_cpu(elf_hdr->e_shentsize);
-+ Elf32_Half e_shnum = be16_to_cpu(elf_hdr->e_shnum);
-+ Elf32_Half e_shstrndx = be16_to_cpu(elf_hdr->e_shstrndx);
-+ Elf32_Off shstr_offset;
-+ Elf32_Word sh_name;
-+ const char *name;
-+ int i;
-+
-+ /* Section header strings */
-+ shdr_shstr = (struct elf32_shdr *)((u8 *)elf_hdr + e_shoff + e_shstrndx
-+ * e_shentsize);
-+ shstr_offset = be32_to_cpu(shdr_shstr->sh_offset);
-+
-+ for (i = 0; i < e_shnum; i++) {
-+ shdr = (struct elf32_shdr *)((u8 *)elf_hdr + e_shoff
-+ + i * e_shentsize);
-+
-+ sh_name = be32_to_cpu(shdr->sh_name);
-+
-+ name = (const char *)((u8 *)elf_hdr + shstr_offset + sh_name);
-+
-+ if (!strcmp(name, section))
-+ return shdr;
-+ }
-+
-+ pr_err("%s: didn't find section %s\n", __func__, section);
-+
-+ return NULL;
-+}
-+
-+#if defined(CFG_DIAGS)
-+static int pfe_get_diags_info(const u8 *fw, struct pfe_diags_info
-+ *diags_info)
-+{
-+ struct elf32_shdr *shdr;
-+ unsigned long offset, size;
-+
-+ shdr = get_elf_section_header(fw, ".pfe_diags_str");
-+ if (shdr) {
-+ offset = be32_to_cpu(shdr->sh_offset);
-+ size = be32_to_cpu(shdr->sh_size);
-+ diags_info->diags_str_base = be32_to_cpu(shdr->sh_addr);
-+ diags_info->diags_str_size = size;
-+ diags_info->diags_str_array = kmalloc(size, GFP_KERNEL);
-+ memcpy(diags_info->diags_str_array, fw + offset, size);
-+
-+ return 0;
-+ } else {
-+ return -1;
-+ }
-+}
-+#endif
-+
-+static void pfe_check_version_info(const u8 *fw)
-+{
-+ /*static char *version = NULL;*/
-+ const u8 *elf_data = fw;
-+ static char *version;
-+
-+ struct elf32_shdr *shdr = get_elf_section_header(fw, ".version");
-+
-+ if (shdr) {
-+ if (!version) {
-+ /*
-+ * this is the first fw we load, use its version
-+ * string as reference (whatever it is)
-+ */
-+ version = (char *)(elf_data +
-+ be32_to_cpu(shdr->sh_offset));
-+
-+ pr_info("PFE binary version: %s\n", version);
-+ } else {
-+ /*
-+ * already have loaded at least one firmware, check
-+ * sequence can start now
-+ */
-+ if (strcmp(version, (char *)(elf_data +
-+ be32_to_cpu(shdr->sh_offset)))) {
-+ pr_info(
-+ "WARNING: PFE firmware binaries from incompatible version\n");
-+ }
-+ }
-+ } else {
-+ /*
-+ * version cannot be verified, a potential issue that should
-+ * be reported
-+ */
-+ pr_info(
-+ "WARNING: PFE firmware binaries from incompatible version\n");
-+ }
-+}
-+
-+/* PFE elf firmware loader.
-+ * Loads an elf firmware image into a list of PE's (specified using a bitmask)
-+ *
-+ * @param pe_mask Mask of PE id's to load firmware to
-+ * @param fw Pointer to the firmware image
-+ *
-+ * @return 0 on success, a negative value on error
-+ *
-+ */
-+int pfe_load_elf(int pe_mask, const u8 *fw, struct pfe *pfe)
-+{
-+ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw;
-+ Elf32_Half sections = be16_to_cpu(elf_hdr->e_shnum);
-+ struct elf32_shdr *shdr = (struct elf32_shdr *)(fw +
-+ be32_to_cpu(elf_hdr->e_shoff));
-+ int id, section;
-+ int rc;
-+
-+ pr_info("%s\n", __func__);
-+
-+ /* Some sanity checks */
-+ if (strncmp(&elf_hdr->e_ident[EI_MAG0], ELFMAG, SELFMAG)) {
-+ pr_err("%s: incorrect elf magic number\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32) {
-+ pr_err("%s: incorrect elf class(%x)\n", __func__,
-+ elf_hdr->e_ident[EI_CLASS]);
-+ return -EINVAL;
-+ }
-+
-+ if (elf_hdr->e_ident[EI_DATA] != ELFDATA2MSB) {
-+ pr_err("%s: incorrect elf data(%x)\n", __func__,
-+ elf_hdr->e_ident[EI_DATA]);
-+ return -EINVAL;
-+ }
-+
-+ if (be16_to_cpu(elf_hdr->e_type) != ET_EXEC) {
-+ pr_err("%s: incorrect elf file type(%x)\n", __func__,
-+ be16_to_cpu(elf_hdr->e_type));
-+ return -EINVAL;
-+ }
-+
-+ for (section = 0; section < sections; section++, shdr++) {
-+ if (!(be32_to_cpu(shdr->sh_flags) & (SHF_WRITE | SHF_ALLOC |
-+ SHF_EXECINSTR)))
-+ continue;
-+
-+ for (id = 0; id < MAX_PE; id++)
-+ if (pe_mask & (1 << id)) {
-+ rc = pe_load_elf_section(id, elf_hdr, shdr,
-+ pfe->dev);
-+ if (rc < 0)
-+ goto err;
-+ }
-+ }
-+
-+ pfe_check_version_info(fw);
-+
-+ return 0;
-+
-+err:
-+ return rc;
-+}
-+
-+int get_firmware_in_fdt(const u8 **pe_fw, const char *name)
-+{
-+ struct device_node *np;
-+ const unsigned int *len;
-+ const void *data;
-+
-+ if (!strcmp(name, CLASS_FIRMWARE_FILENAME)) {
-+ /* The firmware should be inside the device tree. */
-+ np = of_find_compatible_node(NULL, NULL,
-+ "fsl,pfe-class-firmware");
-+ if (!np) {
-+ pr_info("Failed to find the node\n");
-+ return -ENOENT;
-+ }
-+
-+ data = of_get_property(np, "fsl,class-firmware", NULL);
-+ if (data) {
-+ len = of_get_property(np, "length", NULL);
-+ pr_info("CLASS fw of length %d bytes loaded from FDT.\n",
-+ be32_to_cpu(*len));
-+ } else {
-+ pr_info("fsl,class-firmware not found!!!!\n");
-+ return -ENOENT;
-+ }
-+ of_node_put(np);
-+ *pe_fw = data;
-+ } else if (!strcmp(name, TMU_FIRMWARE_FILENAME)) {
-+ np = of_find_compatible_node(NULL, NULL,
-+ "fsl,pfe-tmu-firmware");
-+ if (!np) {
-+ pr_info("Failed to find the node\n");
-+ return -ENOENT;
-+ }
-+
-+ data = of_get_property(np, "fsl,tmu-firmware", NULL);
-+ if (data) {
-+ len = of_get_property(np, "length", NULL);
-+ pr_info("TMU fw of length %d bytes loaded from FDT.\n",
-+ be32_to_cpu(*len));
-+ } else {
-+ pr_info("fsl,tmu-firmware not found!!!!\n");
-+ return -ENOENT;
-+ }
-+ of_node_put(np);
-+ *pe_fw = data;
-+ } else if (!strcmp(name, UTIL_FIRMWARE_FILENAME)) {
-+ np = of_find_compatible_node(NULL, NULL,
-+ "fsl,pfe-util-firmware");
-+ if (!np) {
-+ pr_info("Failed to find the node\n");
-+ return -ENOENT;
-+ }
-+
-+ data = of_get_property(np, "fsl,util-firmware", NULL);
-+ if (data) {
-+ len = of_get_property(np, "length", NULL);
-+ pr_info("UTIL fw of length %d bytes loaded from FDT.\n",
-+ be32_to_cpu(*len));
-+ } else {
-+ pr_info("fsl,util-firmware not found!!!!\n");
-+ return -ENOENT;
-+ }
-+ of_node_put(np);
-+ *pe_fw = data;
-+ } else {
-+ pr_err("firmware:%s not known\n", name);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* PFE firmware initialization.
-+ * Loads different firmware files from filesystem.
-+ * Initializes PE IMEM/DMEM and UTIL-PE DDR
-+ * Initializes control path symbol addresses (by looking them up in the elf
-+ * firmware files
-+ * Takes PE's out of reset
-+ *
-+ * @return 0 on success, a negative value on error
-+ *
-+ */
-+int pfe_firmware_init(struct pfe *pfe)
-+{
-+ const struct firmware *class_fw, *tmu_fw;
-+ const u8 *class_elf_fw, *tmu_elf_fw;
-+ int rc = 0, fs_load = 0;
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ const struct firmware *util_fw;
-+ const u8 *util_elf_fw;
-+
-+#endif
-+
-+ pr_info("%s\n", __func__);
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (get_firmware_in_fdt(&class_elf_fw, CLASS_FIRMWARE_FILENAME) ||
-+ get_firmware_in_fdt(&tmu_elf_fw, TMU_FIRMWARE_FILENAME) ||
-+ get_firmware_in_fdt(&util_elf_fw, UTIL_FIRMWARE_FILENAME))
-+#else
-+ if (get_firmware_in_fdt(&class_elf_fw, CLASS_FIRMWARE_FILENAME) ||
-+ get_firmware_in_fdt(&tmu_elf_fw, TMU_FIRMWARE_FILENAME))
-+#endif
-+ {
-+ pr_info("%s:PFE firmware not found in FDT.\n", __func__);
-+ pr_info("%s:Trying to load firmware from filesystem...!\n", __func__);
-+
-+ /* look for firmware in filesystem...!*/
-+ fs_load = 1;
-+ if (request_firmware(&class_fw, CLASS_FIRMWARE_FILENAME, pfe->dev)) {
-+ pr_err("%s: request firmware %s failed\n", __func__,
-+ CLASS_FIRMWARE_FILENAME);
-+ rc = -ETIMEDOUT;
-+ goto err0;
-+ }
-+ class_elf_fw = class_fw->data;
-+
-+ if (request_firmware(&tmu_fw, TMU_FIRMWARE_FILENAME, pfe->dev)) {
-+ pr_err("%s: request firmware %s failed\n", __func__,
-+ TMU_FIRMWARE_FILENAME);
-+ rc = -ETIMEDOUT;
-+ goto err1;
-+ }
-+ tmu_elf_fw = tmu_fw->data;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (request_firmware(&util_fw, UTIL_FIRMWARE_FILENAME, pfe->dev)) {
-+ pr_err("%s: request firmware %s failed\n", __func__,
-+ UTIL_FIRMWARE_FILENAME);
-+ rc = -ETIMEDOUT;
-+ goto err2;
-+ }
-+ util_elf_fw = util_fw->data;
-+#endif
-+ }
-+
-+ rc = pfe_load_elf(CLASS_MASK, class_elf_fw, pfe);
-+ if (rc < 0) {
-+ pr_err("%s: class firmware load failed\n", __func__);
-+ goto err3;
-+ }
-+
-+#if defined(CFG_DIAGS)
-+ rc = pfe_get_diags_info(class_elf_fw, &pfe->diags.class_diags_info);
-+ if (rc < 0) {
-+ pr_warn(
-+ "PFE diags won't be available for class PEs\n");
-+ rc = 0;
-+ }
-+#endif
-+
-+ rc = pfe_load_elf(TMU_MASK, tmu_elf_fw, pfe);
-+ if (rc < 0) {
-+ pr_err("%s: tmu firmware load failed\n", __func__);
-+ goto err3;
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ rc = pfe_load_elf(UTIL_MASK, util_elf_fw, pfe);
-+ if (rc < 0) {
-+ pr_err("%s: util firmware load failed\n", __func__);
-+ goto err3;
-+ }
-+
-+#if defined(CFG_DIAGS)
-+ rc = pfe_get_diags_info(util_elf_fw, &pfe->diags.util_diags_info);
-+ if (rc < 0) {
-+ pr_warn(
-+ "PFE diags won't be available for util PE\n");
-+ rc = 0;
-+ }
-+#endif
-+
-+ util_enable();
-+#endif
-+
-+ tmu_enable(0xf);
-+ class_enable();
-+
-+err3:
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (fs_load)
-+ release_firmware(util_fw);
-+err2:
-+#endif
-+ if (fs_load)
-+ release_firmware(tmu_fw);
-+
-+err1:
-+ if (fs_load)
-+ release_firmware(class_fw);
-+
-+err0:
-+ return rc;
-+}
-+
-+/* PFE firmware cleanup
-+ * Puts PE's in reset
-+ *
-+ *
-+ */
-+void pfe_firmware_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ if (pe_reset_all(&pfe->ctrl) != 0)
-+ pr_err("Error: Failed to stop PEs, PFE reload may not work correctly\n");
-+
-+ class_disable();
-+ tmu_disable(0xf);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ util_disable();
-+#endif
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_firmware.h
-@@ -0,0 +1,21 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_FIRMWARE_H_
-+#define _PFE_FIRMWARE_H_
-+
-+#define CLASS_FIRMWARE_FILENAME "ppfe_class_ls1012a.elf"
-+#define TMU_FIRMWARE_FILENAME "ppfe_tmu_ls1012a.elf"
-+#define UTIL_FIRMWARE_FILENAME "ppfe_util_ls1012a.elf"
-+
-+#define PFE_FW_CHECK_PASS 0
-+#define PFE_FW_CHECK_FAIL 1
-+#define NUM_PFE_FW 3
-+
-+int pfe_firmware_init(struct pfe *pfe);
-+void pfe_firmware_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_FIRMWARE_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hal.c
-@@ -0,0 +1,1517 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include "pfe_mod.h"
-+#include "pfe/pfe.h"
-+
-+/* A-010897: Jumbo frame is not supported */
-+extern bool pfe_errata_a010897;
-+
-+#define PFE_RCR_MAX_FL_MASK 0xC000FFFF
-+
-+void *cbus_base_addr;
-+void *ddr_base_addr;
-+unsigned long ddr_phys_base_addr;
-+unsigned int ddr_size;
-+
-+static struct pe_info pe[MAX_PE];
-+
-+/* Initializes the PFE library.
-+ * Must be called before using any of the library functions.
-+ *
-+ * @param[in] cbus_base CBUS virtual base address (as mapped in
-+ * the host CPU address space)
-+ * @param[in] ddr_base PFE DDR range virtual base address (as
-+ * mapped in the host CPU address space)
-+ * @param[in] ddr_phys_base PFE DDR range physical base address (as
-+ * mapped in platform)
-+ * @param[in] size PFE DDR range size (as defined by the host
-+ * software)
-+ */
-+void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base,
-+ unsigned int size)
-+{
-+ cbus_base_addr = cbus_base;
-+ ddr_base_addr = ddr_base;
-+ ddr_phys_base_addr = ddr_phys_base;
-+ ddr_size = size;
-+
-+ pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0);
-+ pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0);
-+ pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1);
-+ pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1);
-+ pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2);
-+ pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2);
-+ pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3);
-+ pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3);
-+ pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4);
-+ pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4);
-+ pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5);
-+ pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5);
-+ pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0);
-+ pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0);
-+ pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE;
-+ pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
-+ pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
-+ pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
-+
-+ pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1);
-+ pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1);
-+ pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE;
-+ pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
-+ pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
-+ pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
-+
-+ pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3);
-+ pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3);
-+ pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE;
-+ pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
-+ pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
-+ pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR;
-+ pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA;
-+ pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR;
-+ pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA;
-+#endif
-+}
-+
-+/* Writes a buffer to PE internal memory from the host
-+ * through indirect access registers.
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] src Buffer source address
-+ * @param[in] mem_access_addr DMEM destination address (must be 32bit
-+ * aligned)
-+ * @param[in] len Number of bytes to copy
-+ */
-+void pe_mem_memcpy_to32(int id, u32 mem_access_addr, const void *src, unsigned
-+int len)
-+{
-+ u32 offset = 0, val, addr;
-+ unsigned int len32 = len >> 2;
-+ int i;
-+
-+ addr = mem_access_addr | PE_MEM_ACCESS_WRITE |
-+ PE_MEM_ACCESS_BYTE_ENABLE(0, 4);
-+
-+ for (i = 0; i < len32; i++, offset += 4, src += 4) {
-+ val = *(u32 *)src;
-+ writel(cpu_to_be32(val), pe[id].mem_access_wdata);
-+ writel(addr + offset, pe[id].mem_access_addr);
-+ }
-+
-+ len = (len & 0x3);
-+ if (len) {
-+ val = 0;
-+
-+ addr = (mem_access_addr | PE_MEM_ACCESS_WRITE |
-+ PE_MEM_ACCESS_BYTE_ENABLE(0, len)) + offset;
-+
-+ for (i = 0; i < len; i++, src++)
-+ val |= (*(u8 *)src) << (8 * i);
-+
-+ writel(cpu_to_be32(val), pe[id].mem_access_wdata);
-+ writel(addr, pe[id].mem_access_addr);
-+ }
-+}
-+
-+/* Writes a buffer to PE internal data memory (DMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] src Buffer source address
-+ * @param[in] dst DMEM destination address (must be 32bit
-+ * aligned)
-+ * @param[in] len Number of bytes to copy
-+ */
-+void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
-+{
-+ pe_mem_memcpy_to32(id, pe[id].dmem_base_addr | dst |
-+ PE_MEM_ACCESS_DMEM, src, len);
-+}
-+
-+/* Writes a buffer to PE internal program memory (PMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., TMU3_ID)
-+ * @param[in] src Buffer source address
-+ * @param[in] dst PMEM destination address (must be 32bit
-+ * aligned)
-+ * @param[in] len Number of bytes to copy
-+ */
-+void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
-+{
-+ pe_mem_memcpy_to32(id, pe[id].pmem_base_addr | (dst & (pe[id].pmem_size
-+ - 1)) | PE_MEM_ACCESS_IMEM, src, len);
-+}
-+
-+/* Reads PE internal program memory (IMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., TMU3_ID)
-+ * @param[in] addr PMEM read address (must be aligned on size)
-+ * @param[in] size Number of bytes to read (maximum 4, must not
-+ * cross 32bit boundaries)
-+ * @return the data read (in PE endianness, i.e BE).
-+ */
-+u32 pe_pmem_read(int id, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+ u32 mask = 0xffffffff >> ((4 - size) << 3);
-+ u32 val;
-+
-+ addr = pe[id].pmem_base_addr | ((addr & ~0x3) & (pe[id].pmem_size - 1))
-+ | PE_MEM_ACCESS_IMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
-+
-+ writel(addr, pe[id].mem_access_addr);
-+ val = be32_to_cpu(readl(pe[id].mem_access_rdata));
-+
-+ return (val >> (offset << 3)) & mask;
-+}
-+
-+/* Writes PE internal data memory (DMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] addr DMEM write address (must be aligned on size)
-+ * @param[in] val Value to write (in PE endianness, i.e BE)
-+ * @param[in] size Number of bytes to write (maximum 4, must not
-+ * cross 32bit boundaries)
-+ */
-+void pe_dmem_write(int id, u32 val, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+
-+ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_WRITE |
-+ PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
-+
-+ /* Indirect access interface is byte swapping data being written */
-+ writel(cpu_to_be32(val << (offset << 3)), pe[id].mem_access_wdata);
-+ writel(addr, pe[id].mem_access_addr);
-+}
-+
-+/* Reads PE internal data memory (DMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] addr DMEM read address (must be aligned on size)
-+ * @param[in] size Number of bytes to read (maximum 4, must not
-+ * cross 32bit boundaries)
-+ * @return the data read (in PE endianness, i.e BE).
-+ */
-+u32 pe_dmem_read(int id, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+ u32 mask = 0xffffffff >> ((4 - size) << 3);
-+ u32 val;
-+
-+ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_DMEM |
-+ PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
-+
-+ writel(addr, pe[id].mem_access_addr);
-+
-+ /* Indirect access interface is byte swapping data being read */
-+ val = be32_to_cpu(readl(pe[id].mem_access_rdata));
-+
-+ return (val >> (offset << 3)) & mask;
-+}
-+
-+/* This function is used to write to CLASS internal bus peripherals (ccu,
-+ * pe-lem) from the host
-+ * through indirect access registers.
-+ * @param[in] val value to write
-+ * @param[in] addr Address to write to (must be aligned on size)
-+ * @param[in] size Number of bytes to write (1, 2 or 4)
-+ *
-+ */
-+void class_bus_write(u32 val, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+
-+ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
-+
-+ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | PE_MEM_ACCESS_WRITE |
-+ (size << 24);
-+
-+ writel(cpu_to_be32(val << (offset << 3)), CLASS_BUS_ACCESS_WDATA);
-+ writel(addr, CLASS_BUS_ACCESS_ADDR);
-+}
-+
-+/* Reads from CLASS internal bus peripherals (ccu, pe-lem) from the host
-+ * through indirect access registers.
-+ * @param[in] addr Address to read from (must be aligned on size)
-+ * @param[in] size Number of bytes to read (1, 2 or 4)
-+ * @return the read data
-+ *
-+ */
-+u32 class_bus_read(u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+ u32 mask = 0xffffffff >> ((4 - size) << 3);
-+ u32 val;
-+
-+ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
-+
-+ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | (size << 24);
-+
-+ writel(addr, CLASS_BUS_ACCESS_ADDR);
-+ val = be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA));
-+
-+ return (val >> (offset << 3)) & mask;
-+}
-+
-+/* Writes data to the cluster memory (PE_LMEM)
-+ * @param[in] dst PE LMEM destination address (must be 32bit aligned)
-+ * @param[in] src Buffer source address
-+ * @param[in] len Number of bytes to copy
-+ */
-+void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len)
-+{
-+ u32 len32 = len >> 2;
-+ int i;
-+
-+ for (i = 0; i < len32; i++, src += 4, dst += 4)
-+ class_bus_write(*(u32 *)src, dst, 4);
-+
-+ if (len & 0x2) {
-+ class_bus_write(*(u16 *)src, dst, 2);
-+ src += 2;
-+ dst += 2;
-+ }
-+
-+ if (len & 0x1) {
-+ class_bus_write(*(u8 *)src, dst, 1);
-+ src++;
-+ dst++;
-+ }
-+}
-+
-+/* Writes value to the cluster memory (PE_LMEM)
-+ * @param[in] dst PE LMEM destination address (must be 32bit aligned)
-+ * @param[in] val Value to write
-+ * @param[in] len Number of bytes to write
-+ */
-+void class_pe_lmem_memset(u32 dst, int val, unsigned int len)
-+{
-+ u32 len32 = len >> 2;
-+ int i;
-+
-+ val = val | (val << 8) | (val << 16) | (val << 24);
-+
-+ for (i = 0; i < len32; i++, dst += 4)
-+ class_bus_write(val, dst, 4);
-+
-+ if (len & 0x2) {
-+ class_bus_write(val, dst, 2);
-+ dst += 2;
-+ }
-+
-+ if (len & 0x1) {
-+ class_bus_write(val, dst, 1);
-+ dst++;
-+ }
-+}
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+
-+/* Writes UTIL program memory (DDR) from the host.
-+ *
-+ * @param[in] addr Address to write (virtual, must be aligned on size)
-+ * @param[in] val Value to write (in PE endianness, i.e BE)
-+ * @param[in] size Number of bytes to write (2 or 4)
-+ */
-+static void util_pmem_write(u32 val, void *addr, u8 size)
-+{
-+ void *addr64 = (void *)((unsigned long)addr & ~0x7);
-+ unsigned long off = 8 - ((unsigned long)addr & 0x7) - size;
-+
-+ /*
-+ * IMEM should be loaded as a 64bit swapped value in a 64bit aligned
-+ * location
-+ */
-+ if (size == 4)
-+ writel(be32_to_cpu(val), addr64 + off);
-+ else
-+ writew(be16_to_cpu((u16)val), addr64 + off);
-+}
-+
-+/* Writes a buffer to UTIL program memory (DDR) from the host.
-+ *
-+ * @param[in] dst Address to write (virtual, must be at least 16bit
-+ * aligned)
-+ * @param[in] src Buffer to write (in PE endianness, i.e BE, must have
-+ * same alignment as dst)
-+ * @param[in] len Number of bytes to write (must be at least 16bit
-+ * aligned)
-+ */
-+static void util_pmem_memcpy(void *dst, const void *src, unsigned int len)
-+{
-+ unsigned int len32;
-+ int i;
-+
-+ if ((unsigned long)src & 0x2) {
-+ util_pmem_write(*(u16 *)src, dst, 2);
-+ src += 2;
-+ dst += 2;
-+ len -= 2;
-+ }
-+
-+ len32 = len >> 2;
-+
-+ for (i = 0; i < len32; i++, dst += 4, src += 4)
-+ util_pmem_write(*(u32 *)src, dst, 4);
-+
-+ if (len & 0x2)
-+ util_pmem_write(*(u16 *)src, dst, len & 0x2);
-+}
-+#endif
-+
-+/* Loads an elf section into pmem
-+ * Code needs to be at least 16bit aligned and only PROGBITS sections are
-+ * supported
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ...,
-+ * TMU3_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_pmem_section(int id, const void *data,
-+ struct elf32_shdr *shdr)
-+{
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (id == UTIL_ID) {
-+ pr_err("%s: unsupported pmem section for UTIL\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+#endif
-+
-+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
-+ , __func__, addr, (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x1) {
-+ pr_err("%s: load address(%x) is not 16bit aligned\n",
-+ __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ if (size & 0x1) {
-+ pr_err("%s: load size(%x) is not 16bit aligned\n",
-+ __func__, size);
-+ return -EINVAL;
-+ }
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ pe_pmem_memcpy_to32(id, addr, data + offset, size);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into dmem
-+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
-+ * initialized to 0
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_dmem_section(int id, const void *data,
-+ struct elf32_shdr *shdr)
-+{
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+ u32 size32 = size >> 2;
-+ int i;
-+
-+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
-+ __func__, addr, (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x3) {
-+ pr_err("%s: load address(%x) is not 32bit aligned\n",
-+ __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ pe_dmem_memcpy_to32(id, addr, data + offset, size);
-+ break;
-+
-+ case SHT_NOBITS:
-+ for (i = 0; i < size32; i++, addr += 4)
-+ pe_dmem_write(id, 0, addr, 4);
-+
-+ if (size & 0x3)
-+ pe_dmem_write(id, 0, addr, size & 0x3);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into DDR
-+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
-+ * initialized to 0
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_ddr_section(int id, const void *data,
-+ struct elf32_shdr *shdr,
-+ struct device *dev) {
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+ u32 flags = be32_to_cpu(shdr->sh_flags);
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ if (flags & SHF_EXECINSTR) {
-+ if (id <= CLASS_MAX_ID) {
-+ /* DO the loading only once in DDR */
-+ if (id == CLASS0_ID) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) rcvd\n",
-+ __func__, addr,
-+ (unsigned long)data + offset);
-+ if (((unsigned long)(data + offset)
-+ & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
-+ , __func__, addr,
-+ (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x1) {
-+ pr_err(
-+ "%s: load address(%x) is not 16bit aligned\n"
-+ , __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ if (size & 0x1) {
-+ pr_err(
-+ "%s: load length(%x) is not 16bit aligned\n"
-+ , __func__, size);
-+ return -EINVAL;
-+ }
-+ memcpy(DDR_PHYS_TO_VIRT(
-+ DDR_PFE_TO_PHYS(addr)),
-+ data + offset, size);
-+ }
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ } else if (id == UTIL_ID) {
-+ if (((unsigned long)(data + offset) & 0x3)
-+ != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
-+ , __func__, addr,
-+ (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x1) {
-+ pr_err(
-+ "%s: load address(%x) is not 16bit aligned\n"
-+ , __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ if (size & 0x1) {
-+ pr_err(
-+ "%s: load length(%x) is not 16bit aligned\n"
-+ , __func__, size);
-+ return -EINVAL;
-+ }
-+
-+ util_pmem_memcpy(DDR_PHYS_TO_VIRT(
-+ DDR_PFE_TO_PHYS(addr)),
-+ data + offset, size);
-+ }
-+#endif
-+ } else {
-+ pr_err(
-+ "%s: unsupported ddr section type(%x) for PE(%d)\n"
-+ , __func__, type, id);
-+ return -EINVAL;
-+ }
-+
-+ } else {
-+ memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data
-+ + offset, size);
-+ }
-+
-+ break;
-+
-+ case SHT_NOBITS:
-+ memset(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), 0, size);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into pe lmem
-+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
-+ * initialized to 0
-+ *
-+ * @param[in] id PE identification (CLASS0_ID,..., CLASS5_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_pe_lmem_section(int id, const void *data,
-+ struct elf32_shdr *shdr)
-+{
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+
-+ if (id > CLASS_MAX_ID) {
-+ pr_err(
-+ "%s: unsupported pe-lmem section type(%x) for PE(%d)\n",
-+ __func__, type, id);
-+ return -EINVAL;
-+ }
-+
-+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
-+ __func__, addr, (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x3) {
-+ pr_err("%s: load address(%x) is not 32bit aligned\n",
-+ __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ class_pe_lmem_memcpy_to32(addr, data + offset, size);
-+ break;
-+
-+ case SHT_NOBITS:
-+ class_pe_lmem_memset(addr, 0, size);
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into a PE
-+ * For now only supports loading a section to dmem (all PE's), pmem (class and
-+ * tmu PE's),
-+ * DDDR (util PE code)
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr,
-+ struct device *dev) {
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+
-+ if (IS_DMEM(addr, size))
-+ return pe_load_dmem_section(id, data, shdr);
-+ else if (IS_PMEM(addr, size))
-+ return pe_load_pmem_section(id, data, shdr);
-+ else if (IS_PFE_LMEM(addr, size))
-+ return 0;
-+ else if (IS_PHYS_DDR(addr, size))
-+ return pe_load_ddr_section(id, data, shdr, dev);
-+ else if (IS_PE_LMEM(addr, size))
-+ return pe_load_pe_lmem_section(id, data, shdr);
-+
-+ pr_err("%s: unsupported memory range(%x)\n", __func__,
-+ addr);
-+ return 0;
-+}
-+
-+/**************************** BMU ***************************/
-+
-+/* Initializes a BMU block.
-+ * @param[in] base BMU block base address
-+ * @param[in] cfg BMU configuration
-+ */
-+void bmu_init(void *base, struct BMU_CFG *cfg)
-+{
-+ bmu_disable(base);
-+
-+ bmu_set_config(base, cfg);
-+
-+ bmu_reset(base);
-+}
-+
-+/* Resets a BMU block.
-+ * @param[in] base BMU block base address
-+ */
-+void bmu_reset(void *base)
-+{
-+ writel(CORE_SW_RESET, base + BMU_CTRL);
-+
-+ /* Wait for self clear */
-+ while (readl(base + BMU_CTRL) & CORE_SW_RESET)
-+ ;
-+}
-+
-+/* Enabled a BMU block.
-+ * @param[in] base BMU block base address
-+ */
-+void bmu_enable(void *base)
-+{
-+ writel(CORE_ENABLE, base + BMU_CTRL);
-+}
-+
-+/* Disables a BMU block.
-+ * @param[in] base BMU block base address
-+ */
-+void bmu_disable(void *base)
-+{
-+ writel(CORE_DISABLE, base + BMU_CTRL);
-+}
-+
-+/* Sets the configuration of a BMU block.
-+ * @param[in] base BMU block base address
-+ * @param[in] cfg BMU configuration
-+ */
-+void bmu_set_config(void *base, struct BMU_CFG *cfg)
-+{
-+ writel(cfg->baseaddr, base + BMU_UCAST_BASE_ADDR);
-+ writel(cfg->count & 0xffff, base + BMU_UCAST_CONFIG);
-+ writel(cfg->size & 0xffff, base + BMU_BUF_SIZE);
-+
-+ /* Interrupts are never used */
-+ writel(cfg->low_watermark, base + BMU_LOW_WATERMARK);
-+ writel(cfg->high_watermark, base + BMU_HIGH_WATERMARK);
-+ writel(0x0, base + BMU_INT_ENABLE);
-+}
-+
-+/**************************** MTIP GEMAC ***************************/
-+
-+/* Enable Rx Checksum Engine. With this enabled, Frame with bad IP,
-+ * TCP or UDP checksums are discarded
-+ *
-+ * @param[in] base GEMAC base address.
-+ */
-+void gemac_enable_rx_checksum_offload(void *base)
-+{
-+ /*Do not find configuration to do this */
-+}
-+
-+/* Disable Rx Checksum Engine.
-+ *
-+ * @param[in] base GEMAC base address.
-+ */
-+void gemac_disable_rx_checksum_offload(void *base)
-+{
-+ /*Do not find configuration to do this */
-+}
-+
-+/* GEMAC set speed.
-+ * @param[in] base GEMAC base address
-+ * @param[in] speed GEMAC speed (10, 100 or 1000 Mbps)
-+ */
-+void gemac_set_speed(void *base, enum mac_speed gem_speed)
-+{
-+ u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED;
-+ u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T;
-+
-+ switch (gem_speed) {
-+ case SPEED_10M:
-+ rcr |= EMAC_RCNTRL_RMII_10T;
-+ break;
-+
-+ case SPEED_1000M:
-+ ecr |= EMAC_ECNTRL_SPEED;
-+ break;
-+
-+ case SPEED_100M:
-+ default:
-+ /*It is in 100M mode */
-+ break;
-+ }
-+ writel(ecr, (base + EMAC_ECNTRL_REG));
-+ writel(rcr, (base + EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC set duplex.
-+ * @param[in] base GEMAC base address
-+ * @param[in] duplex GEMAC duplex mode (Full, Half)
-+ */
-+void gemac_set_duplex(void *base, int duplex)
-+{
-+ if (duplex == DUPLEX_HALF) {
-+ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base
-+ + EMAC_TCNTRL_REG);
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base
-+ + EMAC_RCNTRL_REG));
-+ } else{
-+ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base
-+ + EMAC_TCNTRL_REG);
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base
-+ + EMAC_RCNTRL_REG));
-+ }
-+}
-+
-+/* GEMAC set mode.
-+ * @param[in] base GEMAC base address
-+ * @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII)
-+ */
-+void gemac_set_mode(void *base, int mode)
-+{
-+ u32 val = readl(base + EMAC_RCNTRL_REG);
-+
-+ /*Remove loopbank*/
-+ val &= ~EMAC_RCNTRL_LOOP;
-+
-+ /* Enable flow control and MII mode.PFE firmware always expects
-+ CRC should be forwarded by MAC to validate CRC in software.*/
-+ val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE);
-+
-+ writel(val, base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable(void *base)
-+{
-+ writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base +
-+ EMAC_ECNTRL_REG);
-+}
-+
-+/* GEMAC disable function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable(void *base)
-+{
-+ writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base +
-+ EMAC_ECNTRL_REG);
-+}
-+
-+/* GEMAC TX disable function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_tx_disable(void *base)
-+{
-+ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base +
-+ EMAC_TCNTRL_REG);
-+}
-+
-+void gemac_tx_enable(void *base)
-+{
-+ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_GTS, base +
-+ EMAC_TCNTRL_REG);
-+}
-+
-+/* Sets the hash register of the MAC.
-+ * This register is used for matching unicast and multicast frames.
-+ *
-+ * @param[in] base GEMAC base address.
-+ * @param[in] hash 64-bit hash to be configured.
-+ */
-+void gemac_set_hash(void *base, struct pfe_mac_addr *hash)
-+{
-+ writel(hash->bottom, base + EMAC_GALR);
-+ writel(hash->top, base + EMAC_GAUR);
-+}
-+
-+void gemac_set_laddrN(void *base, struct pfe_mac_addr *address,
-+ unsigned int entry_index)
-+{
-+ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX))
-+ return;
-+
-+ entry_index = entry_index - 1;
-+ if (entry_index < 1) {
-+ writel(htonl(address->bottom), base + EMAC_PHY_ADDR_LOW);
-+ writel((htonl(address->top) | 0x8808), base +
-+ EMAC_PHY_ADDR_HIGH);
-+ } else {
-+ writel(htonl(address->bottom), base + ((entry_index - 1) * 8)
-+ + EMAC_SMAC_0_0);
-+ writel((htonl(address->top) | 0x8808), base + ((entry_index -
-+ 1) * 8) + EMAC_SMAC_0_1);
-+ }
-+}
-+
-+void gemac_clear_laddrN(void *base, unsigned int entry_index)
-+{
-+ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX))
-+ return;
-+
-+ entry_index = entry_index - 1;
-+ if (entry_index < 1) {
-+ writel(0, base + EMAC_PHY_ADDR_LOW);
-+ writel(0, base + EMAC_PHY_ADDR_HIGH);
-+ } else {
-+ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0);
-+ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1);
-+ }
-+}
-+
-+/* Set the loopback mode of the MAC. This can be either no loopback for
-+ * normal operation, local loopback through MAC internal loopback module or PHY
-+ * loopback for external loopback through a PHY. This asserts the external
-+ * loop pin.
-+ *
-+ * @param[in] base GEMAC base address.
-+ * @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC
-+ * Loopback,
-+ * LB_EXT - PHY Loopback.
-+ */
-+void gemac_set_loop(void *base, enum mac_loop gem_loop)
-+{
-+ pr_info("%s()\n", __func__);
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base +
-+ EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC allow frames
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_copy_all(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base +
-+ EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC do not allow frames
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable_copy_all(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base +
-+ EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC allow broadcast function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_allow_broadcast(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base +
-+ EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC no broadcast function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_no_broadcast(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base +
-+ EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable 1536 rx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_1536_rx(void *base)
-+{
-+ /* Set 1536 as Maximum frame length */
-+ writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
-+ | (1536 << 16), base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC set rx Max frame length.
-+ * @param[in] base GEMAC base address
-+ * @param[in] mtu new mtu
-+ */
-+void gemac_set_rx_max_fl(void *base, int mtu)
-+{
-+ /* Set mtu as Maximum frame length */
-+ writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
-+ | (mtu << 16), base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable stacked vlan function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_stacked_vlan(void *base)
-+{
-+ /* MTIP doesn't support stacked vlan */
-+}
-+
-+/* GEMAC enable pause rx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_pause_rx(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE,
-+ base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC disable pause rx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable_pause_rx(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE,
-+ base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable pause tx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_pause_tx(void *base)
-+{
-+ writel(EMAC_RX_SECTION_EMPTY_V, base + EMAC_RX_SECTION_EMPTY);
-+}
-+
-+/* GEMAC disable pause tx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable_pause_tx(void *base)
-+{
-+ writel(0x0, base + EMAC_RX_SECTION_EMPTY);
-+}
-+
-+/* GEMAC wol configuration
-+ * @param[in] base GEMAC base address
-+ * @param[in] wol_conf WoL register configuration
-+ */
-+void gemac_set_wol(void *base, u32 wol_conf)
-+{
-+ u32 val = readl(base + EMAC_ECNTRL_REG);
-+
-+ if (wol_conf)
-+ val |= (EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
-+ else
-+ val &= ~(EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
-+ writel(val, base + EMAC_ECNTRL_REG);
-+}
-+
-+/* Sets Gemac bus width to 64bit
-+ * @param[in] base GEMAC base address
-+ * @param[in] width gemac bus width to be set possible values are 32/64/128
-+ */
-+void gemac_set_bus_width(void *base, int width)
-+{
-+}
-+
-+/* Sets Gemac configuration.
-+ * @param[in] base GEMAC base address
-+ * @param[in] cfg GEMAC configuration
-+ */
-+void gemac_set_config(void *base, struct gemac_cfg *cfg)
-+{
-+ /*GEMAC config taken from VLSI */
-+ writel(0x00000004, base + EMAC_TFWR_STR_FWD);
-+ writel(0x00000005, base + EMAC_RX_SECTION_FULL);
-+
-+ if (pfe_errata_a010897)
-+ writel(0x0000076c, base + EMAC_TRUNC_FL);
-+ else
-+ writel(0x00003fff, base + EMAC_TRUNC_FL);
-+
-+ writel(0x00000030, base + EMAC_TX_SECTION_EMPTY);
-+ writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG);
-+
-+ gemac_set_mode(base, cfg->mode);
-+
-+ gemac_set_speed(base, cfg->speed);
-+
-+ gemac_set_duplex(base, cfg->duplex);
-+}
-+
-+/**************************** GPI ***************************/
-+
-+/* Initializes a GPI block.
-+ * @param[in] base GPI base address
-+ * @param[in] cfg GPI configuration
-+ */
-+void gpi_init(void *base, struct gpi_cfg *cfg)
-+{
-+ gpi_reset(base);
-+
-+ gpi_disable(base);
-+
-+ gpi_set_config(base, cfg);
-+}
-+
-+/* Resets a GPI block.
-+ * @param[in] base GPI base address
-+ */
-+void gpi_reset(void *base)
-+{
-+ writel(CORE_SW_RESET, base + GPI_CTRL);
-+}
-+
-+/* Enables a GPI block.
-+ * @param[in] base GPI base address
-+ */
-+void gpi_enable(void *base)
-+{
-+ writel(CORE_ENABLE, base + GPI_CTRL);
-+}
-+
-+/* Disables a GPI block.
-+ * @param[in] base GPI base address
-+ */
-+void gpi_disable(void *base)
-+{
-+ writel(CORE_DISABLE, base + GPI_CTRL);
-+}
-+
-+/* Sets the configuration of a GPI block.
-+ * @param[in] base GPI base address
-+ * @param[in] cfg GPI configuration
-+ */
-+void gpi_set_config(void *base, struct gpi_cfg *cfg)
-+{
-+ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base
-+ + GPI_LMEM_ALLOC_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base
-+ + GPI_LMEM_FREE_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base
-+ + GPI_DDR_ALLOC_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base
-+ + GPI_DDR_FREE_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR);
-+ writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET);
-+ writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET);
-+ writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET);
-+ writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET);
-+ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE);
-+ writel((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE);
-+
-+ writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) |
-+ GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG);
-+ writel(cfg->tmlf_txthres, base + GPI_TMLF_TX);
-+ writel(cfg->aseq_len, base + GPI_DTX_ASEQ);
-+ writel(1, base + GPI_TOE_CHKSUM_EN);
-+
-+ if (cfg->mtip_pause_reg) {
-+ writel(cfg->mtip_pause_reg, base + GPI_CSR_MTIP_PAUSE_REG);
-+ writel(EGPI_PAUSE_TIME, base + GPI_TX_PAUSE_TIME);
-+ }
-+}
-+
-+/**************************** CLASSIFIER ***************************/
-+
-+/* Initializes CLASSIFIER block.
-+ * @param[in] cfg CLASSIFIER configuration
-+ */
-+void class_init(struct class_cfg *cfg)
-+{
-+ class_reset();
-+
-+ class_disable();
-+
-+ class_set_config(cfg);
-+}
-+
-+/* Resets CLASSIFIER block.
-+ *
-+ */
-+void class_reset(void)
-+{
-+ writel(CORE_SW_RESET, CLASS_TX_CTRL);
-+}
-+
-+/* Enables all CLASS-PE's cores.
-+ *
-+ */
-+void class_enable(void)
-+{
-+ writel(CORE_ENABLE, CLASS_TX_CTRL);
-+}
-+
-+/* Disables all CLASS-PE's cores.
-+ *
-+ */
-+void class_disable(void)
-+{
-+ writel(CORE_DISABLE, CLASS_TX_CTRL);
-+}
-+
-+/*
-+ * Sets the configuration of the CLASSIFIER block.
-+ * @param[in] cfg CLASSIFIER configuration
-+ */
-+void class_set_config(struct class_cfg *cfg)
-+{
-+ u32 val;
-+
-+ /* Initialize route table */
-+ if (!cfg->resume)
-+ memset(DDR_PHYS_TO_VIRT(cfg->route_table_baseaddr), 0, (1 <<
-+ cfg->route_table_hash_bits) * CLASS_ROUTE_SIZE);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ writel(cfg->pe_sys_clk_ratio, CLASS_PE_SYS_CLK_RATIO);
-+#endif
-+
-+ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, CLASS_HDR_SIZE);
-+ writel(LMEM_BUF_SIZE, CLASS_LMEM_BUF_SIZE);
-+ writel(CLASS_ROUTE_ENTRY_SIZE(CLASS_ROUTE_SIZE) |
-+ CLASS_ROUTE_HASH_SIZE(cfg->route_table_hash_bits),
-+ CLASS_ROUTE_HASH_ENTRY_SIZE);
-+ writel(HIF_PKT_CLASS_EN | HIF_PKT_OFFSET(sizeof(struct hif_hdr)),
-+ CLASS_HIF_PARSE);
-+
-+ val = HASH_CRC_PORT_IP | QB2BUS_LE;
-+
-+#if defined(CONFIG_IP_ALIGNED)
-+ val |= IP_ALIGNED;
-+#endif
-+
-+ /*
-+ * Class PE packet steering will only work if TOE mode, bridge fetch or
-+ * route fetch are enabled (see class/qb_fet.v). Route fetch would
-+ * trigger additional memory copies (likely from DDR because of hash
-+ * table size, which cannot be reduced because PE software still
-+ * relies on hash value computed in HW), so when not in TOE mode we
-+ * simply enable HW bridge fetch even though we don't use it.
-+ */
-+ if (cfg->toe_mode)
-+ val |= CLASS_TOE;
-+ else
-+ val |= HW_BRIDGE_FETCH;
-+
-+ writel(val, CLASS_ROUTE_MULTI);
-+
-+ writel(DDR_PHYS_TO_PFE(cfg->route_table_baseaddr),
-+ CLASS_ROUTE_TABLE_BASE);
-+ writel(CLASS_PE0_RO_DM_ADDR0_VAL, CLASS_PE0_RO_DM_ADDR0);
-+ writel(CLASS_PE0_RO_DM_ADDR1_VAL, CLASS_PE0_RO_DM_ADDR1);
-+ writel(CLASS_PE0_QB_DM_ADDR0_VAL, CLASS_PE0_QB_DM_ADDR0);
-+ writel(CLASS_PE0_QB_DM_ADDR1_VAL, CLASS_PE0_QB_DM_ADDR1);
-+ writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR), CLASS_TM_INQ_ADDR);
-+
-+ writel(23, CLASS_AFULL_THRES);
-+ writel(23, CLASS_TSQ_FIFO_THRES);
-+
-+ writel(24, CLASS_MAX_BUF_CNT);
-+ writel(24, CLASS_TSQ_MAX_CNT);
-+}
-+
-+/**************************** TMU ***************************/
-+
-+void tmu_reset(void)
-+{
-+ writel(SW_RESET, TMU_CTRL);
-+}
-+
-+/* Initializes TMU block.
-+ * @param[in] cfg TMU configuration
-+ */
-+void tmu_init(struct tmu_cfg *cfg)
-+{
-+ int q, phyno;
-+
-+ tmu_disable(0xF);
-+ mdelay(10);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ /* keep in soft reset */
-+ writel(SW_RESET, TMU_CTRL);
-+#endif
-+ writel(0x3, TMU_SYS_GENERIC_CONTROL);
-+ writel(750, TMU_INQ_WATERMARK);
-+ writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR +
-+ GPI_INQ_PKTPTR), TMU_PHY0_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR +
-+ GPI_INQ_PKTPTR), TMU_PHY1_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR +
-+ GPI_INQ_PKTPTR), TMU_PHY3_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(HIF_NOCPY_RX_INQ0_PKTPTR), TMU_PHY4_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(UTIL_INQ_PKTPTR), TMU_PHY5_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL),
-+ TMU_BMU_INQ_ADDR);
-+
-+ writel(0x3FF, TMU_TDQ0_SCH_CTRL); /*
-+ * enabling all 10
-+ * schedulers [9:0] of each TDQ
-+ */
-+ writel(0x3FF, TMU_TDQ1_SCH_CTRL);
-+ writel(0x3FF, TMU_TDQ3_SCH_CTRL);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ writel(cfg->pe_sys_clk_ratio, TMU_PE_SYS_CLK_RATIO);
-+#endif
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ writel(DDR_PHYS_TO_PFE(cfg->llm_base_addr), TMU_LLM_BASE_ADDR);
-+ /* Extra packet pointers will be stored from this address onwards */
-+
-+ writel(cfg->llm_queue_len, TMU_LLM_QUE_LEN);
-+ writel(5, TMU_TDQ_IIFG_CFG);
-+ writel(DDR_BUF_SIZE, TMU_BMU_BUF_SIZE);
-+
-+ writel(0x0, TMU_CTRL);
-+
-+ /* MEM init */
-+ pr_info("%s: mem init\n", __func__);
-+ writel(MEM_INIT, TMU_CTRL);
-+
-+ while (!(readl(TMU_CTRL) & MEM_INIT_DONE))
-+ ;
-+
-+ /* LLM init */
-+ pr_info("%s: lmem init\n", __func__);
-+ writel(LLM_INIT, TMU_CTRL);
-+
-+ while (!(readl(TMU_CTRL) & LLM_INIT_DONE))
-+ ;
-+#endif
-+ /* set up each queue for tail drop */
-+ for (phyno = 0; phyno < 4; phyno++) {
-+ if (phyno == 2)
-+ continue;
-+ for (q = 0; q < 16; q++) {
-+ u32 qdepth;
-+
-+ writel((phyno << 8) | q, TMU_TEQ_CTRL);
-+ writel(1 << 22, TMU_TEQ_QCFG); /*Enable tail drop */
-+
-+ if (phyno == 3)
-+ qdepth = DEFAULT_TMU3_QDEPTH;
-+ else
-+ qdepth = (q == 0) ? DEFAULT_Q0_QDEPTH :
-+ DEFAULT_MAX_QDEPTH;
-+
-+ /* LOG: 68855 */
-+ /*
-+ * The following is a workaround for the reordered
-+ * packet and BMU2 buffer leakage issue.
-+ */
-+ if (CHIP_REVISION() == 0)
-+ qdepth = 31;
-+
-+ writel(qdepth << 18, TMU_TEQ_HW_PROB_CFG2);
-+ writel(qdepth >> 14, TMU_TEQ_HW_PROB_CFG3);
-+ }
-+ }
-+
-+#ifdef CFG_LRO
-+ /* Set TMU-3 queue 5 (LRO) in no-drop mode */
-+ writel((3 << 8) | TMU_QUEUE_LRO, TMU_TEQ_CTRL);
-+ writel(0, TMU_TEQ_QCFG);
-+#endif
-+
-+ writel(0x05, TMU_TEQ_DISABLE_DROPCHK);
-+
-+ writel(0x0, TMU_CTRL);
-+}
-+
-+/* Enables TMU-PE cores.
-+ * @param[in] pe_mask TMU PE mask
-+ */
-+void tmu_enable(u32 pe_mask)
-+{
-+ writel(readl(TMU_TX_CTRL) | (pe_mask & 0xF), TMU_TX_CTRL);
-+}
-+
-+/* Disables TMU cores.
-+ * @param[in] pe_mask TMU PE mask
-+ */
-+void tmu_disable(u32 pe_mask)
-+{
-+ writel(readl(TMU_TX_CTRL) & ~(pe_mask & 0xF), TMU_TX_CTRL);
-+}
-+
-+/* This will return the tmu queue status
-+ * @param[in] if_id gem interface id or TMU index
-+ * @return returns the bit mask of busy queues, zero means all
-+ * queues are empty
-+ */
-+u32 tmu_qstatus(u32 if_id)
-+{
-+ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS +
-+ offsetof(struct pe_status, tmu_qstatus), 4));
-+}
-+
-+u32 tmu_pkts_processed(u32 if_id)
-+{
-+ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS +
-+ offsetof(struct pe_status, rx), 4));
-+}
-+
-+/**************************** UTIL ***************************/
-+
-+/* Resets UTIL block.
-+ */
-+void util_reset(void)
-+{
-+ writel(CORE_SW_RESET, UTIL_TX_CTRL);
-+}
-+
-+/* Initializes UTIL block.
-+ * @param[in] cfg UTIL configuration
-+ */
-+void util_init(struct util_cfg *cfg)
-+{
-+ writel(cfg->pe_sys_clk_ratio, UTIL_PE_SYS_CLK_RATIO);
-+}
-+
-+/* Enables UTIL-PE core.
-+ *
-+ */
-+void util_enable(void)
-+{
-+ writel(CORE_ENABLE, UTIL_TX_CTRL);
-+}
-+
-+/* Disables UTIL-PE core.
-+ *
-+ */
-+void util_disable(void)
-+{
-+ writel(CORE_DISABLE, UTIL_TX_CTRL);
-+}
-+
-+/**************************** HIF ***************************/
-+/* Initializes HIF copy block.
-+ *
-+ */
-+void hif_init(void)
-+{
-+ /*Initialize HIF registers*/
-+ writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE,
-+ HIF_POLL_CTRL);
-+}
-+
-+/* Enable hif tx DMA and interrupt
-+ *
-+ */
-+void hif_tx_enable(void)
-+{
-+ writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL);
-+ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN),
-+ HIF_INT_ENABLE);
-+}
-+
-+/* Disable hif tx DMA and interrupt
-+ *
-+ */
-+void hif_tx_disable(void)
-+{
-+ u32 hif_int;
-+
-+ writel(0, HIF_TX_CTRL);
-+
-+ hif_int = readl(HIF_INT_ENABLE);
-+ hif_int &= HIF_TXPKT_INT_EN;
-+ writel(hif_int, HIF_INT_ENABLE);
-+}
-+
-+/* Enable hif rx DMA and interrupt
-+ *
-+ */
-+void hif_rx_enable(void)
-+{
-+ hif_rx_dma_start();
-+ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN),
-+ HIF_INT_ENABLE);
-+}
-+
-+/* Disable hif rx DMA and interrupt
-+ *
-+ */
-+void hif_rx_disable(void)
-+{
-+ u32 hif_int;
-+
-+ writel(0, HIF_RX_CTRL);
-+
-+ hif_int = readl(HIF_INT_ENABLE);
-+ hif_int &= HIF_RXPKT_INT_EN;
-+ writel(hif_int, HIF_INT_ENABLE);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
-@@ -0,0 +1,1063 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/sched.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/kthread.h>
-+#include <linux/slab.h>
-+
-+#include <linux/io.h>
-+#include <asm/irq.h>
-+
-+#include "pfe_mod.h"
-+
-+#define HIF_INT_MASK (HIF_INT | HIF_RXPKT_INT | HIF_TXPKT_INT)
-+
-+unsigned char napi_first_batch;
-+
-+static void pfe_tx_do_cleanup(unsigned long data);
-+
-+static int pfe_hif_alloc_descr(struct pfe_hif *hif)
-+{
-+ void *addr;
-+ dma_addr_t dma_addr;
-+ int err = 0;
-+
-+ pr_info("%s\n", __func__);
-+ addr = dma_alloc_coherent(pfe->dev,
-+ HIF_RX_DESC_NT * sizeof(struct hif_desc) +
-+ HIF_TX_DESC_NT * sizeof(struct hif_desc),
-+ &dma_addr, GFP_KERNEL);
-+
-+ if (!addr) {
-+ pr_err("%s: Could not allocate buffer descriptors!\n"
-+ , __func__);
-+ err = -ENOMEM;
-+ goto err0;
-+ }
-+
-+ hif->descr_baseaddr_p = dma_addr;
-+ hif->descr_baseaddr_v = addr;
-+ hif->rx_ring_size = HIF_RX_DESC_NT;
-+ hif->tx_ring_size = HIF_TX_DESC_NT;
-+
-+ return 0;
-+
-+err0:
-+ return err;
-+}
-+
-+#if defined(LS1012A_PFE_RESET_WA)
-+static void pfe_hif_disable_rx_desc(struct pfe_hif *hif)
-+{
-+ int ii;
-+ struct hif_desc *desc = hif->rx_base;
-+
-+ /*Mark all descriptors as LAST_BD */
-+ for (ii = 0; ii < hif->rx_ring_size; ii++) {
-+ desc->ctrl |= BD_CTRL_LAST_BD;
-+ desc++;
-+ }
-+}
-+
-+struct class_rx_hdr_t {
-+ u32 next_ptr; /* ptr to the start of the first DDR buffer */
-+ u16 length; /* total packet length */
-+ u16 phyno; /* input physical port number */
-+ u32 status; /* gemac status bits */
-+ u32 status2; /* reserved for software usage */
-+};
-+
-+/* STATUS_BAD_FRAME_ERR is set for all errors (including checksums if enabled)
-+ * except overflow
-+ */
-+#define STATUS_BAD_FRAME_ERR BIT(16)
-+#define STATUS_LENGTH_ERR BIT(17)
-+#define STATUS_CRC_ERR BIT(18)
-+#define STATUS_TOO_SHORT_ERR BIT(19)
-+#define STATUS_TOO_LONG_ERR BIT(20)
-+#define STATUS_CODE_ERR BIT(21)
-+#define STATUS_MC_HASH_MATCH BIT(22)
-+#define STATUS_CUMULATIVE_ARC_HIT BIT(23)
-+#define STATUS_UNICAST_HASH_MATCH BIT(24)
-+#define STATUS_IP_CHECKSUM_CORRECT BIT(25)
-+#define STATUS_TCP_CHECKSUM_CORRECT BIT(26)
-+#define STATUS_UDP_CHECKSUM_CORRECT BIT(27)
-+#define STATUS_OVERFLOW_ERR BIT(28) /* GPI error */
-+#define MIN_PKT_SIZE 64
-+
-+static inline void copy_to_lmem(u32 *dst, u32 *src, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i += sizeof(u32)) {
-+ *dst = htonl(*src);
-+ dst++; src++;
-+ }
-+}
-+
-+static void send_dummy_pkt_to_hif(void)
-+{
-+ void *lmem_ptr, *ddr_ptr, *lmem_virt_addr;
-+ u32 physaddr;
-+ struct class_rx_hdr_t local_hdr;
-+ static u32 dummy_pkt[] = {
-+ 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608,
-+ 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0,
-+ 0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
-+ 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
-+
-+ ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
-+ if (!ddr_ptr)
-+ return;
-+
-+ lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
-+ if (!lmem_ptr)
-+ return;
-+
-+ pr_info("Sending a dummy pkt to HIF %p %p\n", ddr_ptr, lmem_ptr);
-+ physaddr = (u32)DDR_VIRT_TO_PFE(ddr_ptr);
-+
-+ lmem_virt_addr = (void *)CBUS_PFE_TO_VIRT((unsigned long int)lmem_ptr);
-+
-+ local_hdr.phyno = htons(0); /* RX_PHY_0 */
-+ local_hdr.length = htons(MIN_PKT_SIZE);
-+
-+ local_hdr.next_ptr = htonl((u32)physaddr);
-+ /*Mark checksum is correct */
-+ local_hdr.status = htonl((STATUS_IP_CHECKSUM_CORRECT |
-+ STATUS_UDP_CHECKSUM_CORRECT |
-+ STATUS_TCP_CHECKSUM_CORRECT |
-+ STATUS_UNICAST_HASH_MATCH |
-+ STATUS_CUMULATIVE_ARC_HIT));
-+ local_hdr.status2 = 0;
-+
-+ copy_to_lmem((u32 *)lmem_virt_addr, (u32 *)&local_hdr,
-+ sizeof(local_hdr));
-+
-+ copy_to_lmem((u32 *)(lmem_virt_addr + LMEM_HDR_SIZE), (u32 *)dummy_pkt,
-+ 0x40);
-+
-+ writel((unsigned long int)lmem_ptr, CLASS_INQ_PKTPTR);
-+}
-+
-+void pfe_hif_rx_idle(struct pfe_hif *hif)
-+{
-+ int hif_stop_loop = 10;
-+ u32 rx_status;
-+
-+ pfe_hif_disable_rx_desc(hif);
-+ pr_info("Bringing hif to idle state...");
-+ writel(0, HIF_INT_ENABLE);
-+ /*If HIF Rx BDP is busy send a dummy packet */
-+ do {
-+ rx_status = readl(HIF_RX_STATUS);
-+ if (rx_status & BDP_CSR_RX_DMA_ACTV)
-+ send_dummy_pkt_to_hif();
-+
-+ usleep_range(100, 150);
-+ } while (--hif_stop_loop);
-+
-+ if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV)
-+ pr_info("Failed\n");
-+ else
-+ pr_info("Done\n");
-+}
-+#endif
-+
-+static void pfe_hif_free_descr(struct pfe_hif *hif)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ dma_free_coherent(pfe->dev,
-+ hif->rx_ring_size * sizeof(struct hif_desc) +
-+ hif->tx_ring_size * sizeof(struct hif_desc),
-+ hif->descr_baseaddr_v, hif->descr_baseaddr_p);
-+}
-+
-+void pfe_hif_desc_dump(struct pfe_hif *hif)
-+{
-+ struct hif_desc *desc;
-+ unsigned long desc_p;
-+ int ii = 0;
-+
-+ pr_info("%s\n", __func__);
-+
-+ desc = hif->rx_base;
-+ desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
-+ hif->descr_baseaddr_p);
-+
-+ pr_info("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p);
-+ for (ii = 0; ii < hif->rx_ring_size; ii++) {
-+ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
-+ readl(&desc->status), readl(&desc->ctrl),
-+ readl(&desc->data), readl(&desc->next));
-+ desc++;
-+ }
-+
-+ desc = hif->tx_base;
-+ desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
-+ hif->descr_baseaddr_p);
-+
-+ pr_info("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p);
-+ for (ii = 0; ii < hif->tx_ring_size; ii++) {
-+ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
-+ readl(&desc->status), readl(&desc->ctrl),
-+ readl(&desc->data), readl(&desc->next));
-+ desc++;
-+ }
-+}
-+
-+/* pfe_hif_release_buffers */
-+static void pfe_hif_release_buffers(struct pfe_hif *hif)
-+{
-+ struct hif_desc *desc;
-+ int i = 0;
-+
-+ hif->rx_base = hif->descr_baseaddr_v;
-+
-+ pr_info("%s\n", __func__);
-+
-+ /*Free Rx buffers */
-+ desc = hif->rx_base;
-+ for (i = 0; i < hif->rx_ring_size; i++) {
-+ if (readl(&desc->data)) {
-+ if ((i < hif->shm->rx_buf_pool_cnt) &&
-+ (!hif->shm->rx_buf_pool[i])) {
-+ /*
-+ * dma_unmap_single(hif->dev, desc->data,
-+ * hif->rx_buf_len[i], DMA_FROM_DEVICE);
-+ */
-+ dma_unmap_single(hif->dev,
-+ DDR_PFE_TO_PHYS(
-+ readl(&desc->data)),
-+ hif->rx_buf_len[i],
-+ DMA_FROM_DEVICE);
-+ hif->shm->rx_buf_pool[i] = hif->rx_buf_addr[i];
-+ } else {
-+ pr_err("%s: buffer pool already full\n"
-+ , __func__);
-+ }
-+ }
-+
-+ writel(0, &desc->data);
-+ writel(0, &desc->status);
-+ writel(0, &desc->ctrl);
-+ desc++;
-+ }
-+}
-+
-+/*
-+ * pfe_hif_init_buffers
-+ * This function initializes the HIF Rx/Tx ring descriptors and
-+ * initialize Rx queue with buffers.
-+ */
-+static int pfe_hif_init_buffers(struct pfe_hif *hif)
-+{
-+ struct hif_desc *desc, *first_desc_p;
-+ u32 data;
-+ int i = 0;
-+
-+ pr_info("%s\n", __func__);
-+
-+ /* Check enough Rx buffers available in the shared memory */
-+ if (hif->shm->rx_buf_pool_cnt < hif->rx_ring_size)
-+ return -ENOMEM;
-+
-+ hif->rx_base = hif->descr_baseaddr_v;
-+ memset(hif->rx_base, 0, hif->rx_ring_size * sizeof(struct hif_desc));
-+
-+ /*Initialize Rx descriptors */
-+ desc = hif->rx_base;
-+ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p;
-+
-+ for (i = 0; i < hif->rx_ring_size; i++) {
-+ /* Initialize Rx buffers from the shared memory */
-+
-+ data = (u32)dma_map_single(hif->dev, hif->shm->rx_buf_pool[i],
-+ pfe_pkt_size, DMA_FROM_DEVICE);
-+ hif->rx_buf_addr[i] = hif->shm->rx_buf_pool[i];
-+ hif->rx_buf_len[i] = pfe_pkt_size;
-+ hif->shm->rx_buf_pool[i] = NULL;
-+
-+ if (likely(dma_mapping_error(hif->dev, data) == 0)) {
-+ writel(DDR_PHYS_TO_PFE(data), &desc->data);
-+ } else {
-+ pr_err("%s : low on mem\n", __func__);
-+
-+ goto err;
-+ }
-+
-+ writel(0, &desc->status);
-+
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ wmb();
-+
-+ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM
-+ | BD_CTRL_DIR | BD_CTRL_DESC_EN
-+ | BD_BUF_LEN(pfe_pkt_size)), &desc->ctrl);
-+
-+ /* Chain descriptors */
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next);
-+ desc++;
-+ }
-+
-+ /* Overwrite last descriptor to chain it to first one*/
-+ desc--;
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next);
-+
-+ hif->rxtoclean_index = 0;
-+
-+ /*Initialize Rx buffer descriptor ring base address */
-+ writel(DDR_PHYS_TO_PFE(hif->descr_baseaddr_p), HIF_RX_BDP_ADDR);
-+
-+ hif->tx_base = hif->rx_base + hif->rx_ring_size;
-+ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p +
-+ hif->rx_ring_size;
-+ memset(hif->tx_base, 0, hif->tx_ring_size * sizeof(struct hif_desc));
-+
-+ /*Initialize tx descriptors */
-+ desc = hif->tx_base;
-+
-+ for (i = 0; i < hif->tx_ring_size; i++) {
-+ /* Chain descriptors */
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next);
-+ writel(0, &desc->ctrl);
-+ desc++;
-+ }
-+
-+ /* Overwrite last descriptor to chain it to first one */
-+ desc--;
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next);
-+ hif->txavail = hif->tx_ring_size;
-+ hif->txtosend = 0;
-+ hif->txtoclean = 0;
-+ hif->txtoflush = 0;
-+
-+ /*Initialize Tx buffer descriptor ring base address */
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), HIF_TX_BDP_ADDR);
-+
-+ return 0;
-+
-+err:
-+ pfe_hif_release_buffers(hif);
-+ return -ENOMEM;
-+}
-+
-+/*
-+ * pfe_hif_client_register
-+ *
-+ * This function used to register a client driver with the HIF driver.
-+ *
-+ * Return value:
-+ * 0 - on Successful registration
-+ */
-+static int pfe_hif_client_register(struct pfe_hif *hif, u32 client_id,
-+ struct hif_client_shm *client_shm)
-+{
-+ struct hif_client *client = &hif->client[client_id];
-+ u32 i, cnt;
-+ struct rx_queue_desc *rx_qbase;
-+ struct tx_queue_desc *tx_qbase;
-+ struct hif_rx_queue *rx_queue;
-+ struct hif_tx_queue *tx_queue;
-+ int err = 0;
-+
-+ pr_info("%s\n", __func__);
-+
-+ spin_lock_bh(&hif->tx_lock);
-+
-+ if (test_bit(client_id, &hif->shm->g_client_status[0])) {
-+ pr_err("%s: client %d already registered\n",
-+ __func__, client_id);
-+ err = -1;
-+ goto unlock;
-+ }
-+
-+ memset(client, 0, sizeof(struct hif_client));
-+
-+ /* Initialize client Rx queues baseaddr, size */
-+
-+ cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl);
-+ /* Check if client is requesting for more queues than supported */
-+ if (cnt > HIF_CLIENT_QUEUES_MAX)
-+ cnt = HIF_CLIENT_QUEUES_MAX;
-+
-+ client->rx_qn = cnt;
-+ rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase;
-+ for (i = 0; i < cnt; i++) {
-+ rx_queue = &client->rx_q[i];
-+ rx_queue->base = rx_qbase + i * client_shm->rx_qsize;
-+ rx_queue->size = client_shm->rx_qsize;
-+ rx_queue->write_idx = 0;
-+ }
-+
-+ /* Initialize client Tx queues baseaddr, size */
-+ cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl);
-+
-+ /* Check if client is requesting for more queues than supported */
-+ if (cnt > HIF_CLIENT_QUEUES_MAX)
-+ cnt = HIF_CLIENT_QUEUES_MAX;
-+
-+ client->tx_qn = cnt;
-+ tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase;
-+ for (i = 0; i < cnt; i++) {
-+ tx_queue = &client->tx_q[i];
-+ tx_queue->base = tx_qbase + i * client_shm->tx_qsize;
-+ tx_queue->size = client_shm->tx_qsize;
-+ tx_queue->ack_idx = 0;
-+ }
-+
-+ set_bit(client_id, &hif->shm->g_client_status[0]);
-+
-+unlock:
-+ spin_unlock_bh(&hif->tx_lock);
-+
-+ return err;
-+}
-+
-+/*
-+ * pfe_hif_client_unregister
-+ *
-+ * This function used to unregister a client from the HIF driver.
-+ *
-+ */
-+static void pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ /*
-+ * Mark client as no longer available (which prevents further packet
-+ * receive for this client)
-+ */
-+ spin_lock_bh(&hif->tx_lock);
-+
-+ if (!test_bit(client_id, &hif->shm->g_client_status[0])) {
-+ pr_err("%s: client %d not registered\n", __func__,
-+ client_id);
-+
-+ spin_unlock_bh(&hif->tx_lock);
-+ return;
-+ }
-+
-+ clear_bit(client_id, &hif->shm->g_client_status[0]);
-+
-+ spin_unlock_bh(&hif->tx_lock);
-+}
-+
-+/*
-+ * client_put_rxpacket-
-+ * This functions puts the Rx pkt in the given client Rx queue.
-+ * It actually swap the Rx pkt in the client Rx descriptor buffer
-+ * and returns the free buffer from it.
-+ *
-+ * If the function returns NULL means client Rx queue is full and
-+ * packet couldn't send to client queue.
-+ */
-+static void *client_put_rxpacket(struct hif_rx_queue *queue, void *pkt, u32 len,
-+ u32 flags, u32 client_ctrl, u32 *rem_len)
-+{
-+ void *free_pkt = NULL;
-+ struct rx_queue_desc *desc = queue->base + queue->write_idx;
-+
-+ if (readl(&desc->ctrl) & CL_DESC_OWN) {
-+ if (page_mode) {
-+ int rem_page_size = PAGE_SIZE -
-+ PRESENT_OFST_IN_PAGE(pkt);
-+ int cur_pkt_size = ROUND_MIN_RX_SIZE(len +
-+ pfe_pkt_headroom);
-+ *rem_len = (rem_page_size - cur_pkt_size);
-+ if (*rem_len) {
-+ free_pkt = pkt + cur_pkt_size;
-+ get_page(virt_to_page(free_pkt));
-+ } else {
-+ free_pkt = (void
-+ *)__get_free_page(GFP_ATOMIC | GFP_DMA_PFE);
-+ *rem_len = pfe_pkt_size;
-+ }
-+ } else {
-+ free_pkt = kmalloc(PFE_BUF_SIZE, GFP_ATOMIC |
-+ GFP_DMA_PFE);
-+ *rem_len = PFE_BUF_SIZE - pfe_pkt_headroom;
-+ }
-+
-+ if (free_pkt) {
-+ desc->data = pkt;
-+ desc->client_ctrl = client_ctrl;
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ smp_wmb();
-+ writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl);
-+ queue->write_idx = (queue->write_idx + 1)
-+ & (queue->size - 1);
-+
-+ free_pkt += pfe_pkt_headroom;
-+ }
-+ }
-+
-+ return free_pkt;
-+}
-+
-+/*
-+ * pfe_hif_rx_process-
-+ * This function does pfe hif rx queue processing.
-+ * Dequeue packet from Rx queue and send it to corresponding client queue
-+ */
-+static int pfe_hif_rx_process(struct pfe_hif *hif, int budget)
-+{
-+ struct hif_desc *desc;
-+ struct hif_hdr *pkt_hdr;
-+ struct __hif_hdr hif_hdr;
-+ void *free_buf;
-+ int rtc, len, rx_processed = 0;
-+ struct __hif_desc local_desc;
-+ int flags;
-+ unsigned int desc_p;
-+ unsigned int buf_size = 0;
-+
-+ spin_lock_bh(&hif->lock);
-+
-+ rtc = hif->rxtoclean_index;
-+
-+ while (rx_processed < budget) {
-+ desc = hif->rx_base + rtc;
-+
-+ __memcpy12(&local_desc, desc);
-+
-+ /* ACK pending Rx interrupt */
-+ if (local_desc.ctrl & BD_CTRL_DESC_EN) {
-+ writel(HIF_INT | HIF_RXPKT_INT, HIF_INT_SRC);
-+
-+ if (rx_processed == 0) {
-+ if (napi_first_batch == 1) {
-+ desc_p = hif->descr_baseaddr_p +
-+ ((unsigned long int)(desc) -
-+ (unsigned long
-+ int)hif->descr_baseaddr_v);
-+ napi_first_batch = 0;
-+ }
-+ }
-+
-+ __memcpy12(&local_desc, desc);
-+
-+ if (local_desc.ctrl & BD_CTRL_DESC_EN)
-+ break;
-+ }
-+
-+ napi_first_batch = 0;
-+
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_DESC_COUNT]++;
-+#endif
-+ len = BD_BUF_LEN(local_desc.ctrl);
-+ /*
-+ * dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data),
-+ * hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
-+ */
-+ dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data),
-+ hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
-+
-+ pkt_hdr = (struct hif_hdr *)hif->rx_buf_addr[rtc];
-+
-+ /* Track last HIF header received */
-+ if (!hif->started) {
-+ hif->started = 1;
-+
-+ __memcpy8(&hif_hdr, pkt_hdr);
-+
-+ hif->qno = hif_hdr.hdr.q_num;
-+ hif->client_id = hif_hdr.hdr.client_id;
-+ hif->client_ctrl = (hif_hdr.hdr.client_ctrl1 << 16) |
-+ hif_hdr.hdr.client_ctrl;
-+ flags = CL_DESC_FIRST;
-+
-+ } else {
-+ flags = 0;
-+ }
-+
-+ if (local_desc.ctrl & BD_CTRL_LIFM)
-+ flags |= CL_DESC_LAST;
-+
-+ /* Check for valid client id and still registered */
-+ if ((hif->client_id >= HIF_CLIENTS_MAX) ||
-+ !(test_bit(hif->client_id,
-+ &hif->shm->g_client_status[0]))) {
-+ printk_ratelimited("%s: packet with invalid client id %d q_num %d\n",
-+ __func__,
-+ hif->client_id,
-+ hif->qno);
-+
-+ free_buf = pkt_hdr;
-+
-+ goto pkt_drop;
-+ }
-+
-+ /* Check to valid queue number */
-+ if (hif->client[hif->client_id].rx_qn <= hif->qno) {
-+ pr_info("%s: packet with invalid queue: %d\n"
-+ , __func__, hif->qno);
-+ hif->qno = 0;
-+ }
-+
-+ free_buf =
-+ client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno],
-+ (void *)pkt_hdr, len, flags,
-+ hif->client_ctrl, &buf_size);
-+
-+ hif_lib_indicate_client(hif->client_id, EVENT_RX_PKT_IND,
-+ hif->qno);
-+
-+ if (unlikely(!free_buf)) {
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_CLIENT_FULL_COUNT]++;
-+#endif
-+ /*
-+ * If we want to keep in polling mode to retry later,
-+ * we need to tell napi that we consumed
-+ * the full budget or we will hit a livelock scenario.
-+ * The core code keeps this napi instance
-+ * at the head of the list and none of the other
-+ * instances get to run
-+ */
-+ rx_processed = budget;
-+
-+ if (flags & CL_DESC_FIRST)
-+ hif->started = 0;
-+
-+ break;
-+ }
-+
-+pkt_drop:
-+ /*Fill free buffer in the descriptor */
-+ hif->rx_buf_addr[rtc] = free_buf;
-+ hif->rx_buf_len[rtc] = min(pfe_pkt_size, buf_size);
-+ writel((DDR_PHYS_TO_PFE
-+ ((u32)dma_map_single(hif->dev,
-+ free_buf, hif->rx_buf_len[rtc], DMA_FROM_DEVICE))),
-+ &desc->data);
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ wmb();
-+ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR |
-+ BD_CTRL_DESC_EN | BD_BUF_LEN(hif->rx_buf_len[rtc])),
-+ &desc->ctrl);
-+
-+ rtc = (rtc + 1) & (hif->rx_ring_size - 1);
-+
-+ if (local_desc.ctrl & BD_CTRL_LIFM) {
-+ if (!(hif->client_ctrl & HIF_CTRL_RX_CONTINUED)) {
-+ rx_processed++;
-+
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_PACKET_COUNT]++;
-+#endif
-+ }
-+ hif->started = 0;
-+ }
-+ }
-+
-+ hif->rxtoclean_index = rtc;
-+ spin_unlock_bh(&hif->lock);
-+
-+ /* we made some progress, re-start rx dma in case it stopped */
-+ hif_rx_dma_start();
-+
-+ return rx_processed;
-+}
-+
-+/*
-+ * client_ack_txpacket-
-+ * This function ack the Tx packet in the give client Tx queue by resetting
-+ * ownership bit in the descriptor.
-+ */
-+static int client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id,
-+ unsigned int q_no)
-+{
-+ struct hif_tx_queue *queue = &hif->client[client_id].tx_q[q_no];
-+ struct tx_queue_desc *desc = queue->base + queue->ack_idx;
-+
-+ if (readl(&desc->ctrl) & CL_DESC_OWN) {
-+ writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl);
-+ queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1);
-+
-+ return 0;
-+
-+ } else {
-+ /*This should not happen */
-+ pr_err("%s: %d %d %d %d %d %p %d\n", __func__,
-+ hif->txtosend, hif->txtoclean, hif->txavail,
-+ client_id, q_no, queue, queue->ack_idx);
-+ WARN(1, "%s: doesn't own this descriptor", __func__);
-+ return 1;
-+ }
-+}
-+
-+void __hif_tx_done_process(struct pfe_hif *hif, int count)
-+{
-+ struct hif_desc *desc;
-+ struct hif_desc_sw *desc_sw;
-+ int ttc, tx_avl;
-+ int pkts_done[HIF_CLIENTS_MAX] = {0, 0};
-+
-+ ttc = hif->txtoclean;
-+ tx_avl = hif->txavail;
-+
-+ while ((tx_avl < hif->tx_ring_size) && count--) {
-+ desc = hif->tx_base + ttc;
-+
-+ if (readl(&desc->ctrl) & BD_CTRL_DESC_EN)
-+ break;
-+
-+ desc_sw = &hif->tx_sw_queue[ttc];
-+
-+ if (desc_sw->data) {
-+ /*
-+ * dmap_unmap_single(hif->dev, desc_sw->data,
-+ * desc_sw->len, DMA_TO_DEVICE);
-+ */
-+ dma_unmap_single(hif->dev, desc_sw->data,
-+ desc_sw->len, DMA_TO_DEVICE);
-+ }
-+
-+ if (desc_sw->client_id >= HIF_CLIENTS_MAX) {
-+ pr_err("Invalid cl id %d\n", desc_sw->client_id);
-+ break;
-+ }
-+
-+ pkts_done[desc_sw->client_id]++;
-+
-+ client_ack_txpacket(hif, desc_sw->client_id, desc_sw->q_no);
-+
-+ ttc = (ttc + 1) & (hif->tx_ring_size - 1);
-+ tx_avl++;
-+ }
-+
-+ if (pkts_done[0])
-+ hif_lib_indicate_client(0, EVENT_TXDONE_IND, 0);
-+ if (pkts_done[1])
-+ hif_lib_indicate_client(1, EVENT_TXDONE_IND, 0);
-+
-+ hif->txtoclean = ttc;
-+ hif->txavail = tx_avl;
-+
-+ if (!count) {
-+ tasklet_schedule(&hif->tx_cleanup_tasklet);
-+ } else {
-+ /*Enable Tx done interrupt */
-+ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_TXPKT_INT,
-+ HIF_INT_ENABLE);
-+ }
-+}
-+
-+static void pfe_tx_do_cleanup(unsigned long data)
-+{
-+ struct pfe_hif *hif = (struct pfe_hif *)data;
-+
-+ writel(HIF_INT | HIF_TXPKT_INT, HIF_INT_SRC);
-+
-+ hif_tx_done_process(hif, 64);
-+}
-+
-+/*
-+ * __hif_xmit_pkt -
-+ * This function puts one packet in the HIF Tx queue
-+ */
-+void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
-+ q_no, void *data, u32 len, unsigned int flags)
-+{
-+ struct hif_desc *desc;
-+ struct hif_desc_sw *desc_sw;
-+
-+ desc = hif->tx_base + hif->txtosend;
-+ desc_sw = &hif->tx_sw_queue[hif->txtosend];
-+
-+ desc_sw->len = len;
-+ desc_sw->client_id = client_id;
-+ desc_sw->q_no = q_no;
-+ desc_sw->flags = flags;
-+
-+ if (flags & HIF_DONT_DMA_MAP) {
-+ desc_sw->data = 0;
-+ writel((u32)DDR_PHYS_TO_PFE(data), &desc->data);
-+ } else {
-+ desc_sw->data = dma_map_single(hif->dev, data, len,
-+ DMA_TO_DEVICE);
-+ writel((u32)DDR_PHYS_TO_PFE(desc_sw->data), &desc->data);
-+ }
-+
-+ hif->txtosend = (hif->txtosend + 1) & (hif->tx_ring_size - 1);
-+ hif->txavail--;
-+
-+ if ((!((flags & HIF_DATA_VALID) && (flags &
-+ HIF_LAST_BUFFER))))
-+ goto skip_tx;
-+
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ wmb();
-+
-+ do {
-+ desc_sw = &hif->tx_sw_queue[hif->txtoflush];
-+ desc = hif->tx_base + hif->txtoflush;
-+
-+ if (desc_sw->flags & HIF_LAST_BUFFER) {
-+ writel((BD_CTRL_LIFM |
-+ BD_CTRL_BRFETCH_DISABLE | BD_CTRL_RTFETCH_DISABLE
-+ | BD_CTRL_PARSE_DISABLE | BD_CTRL_DESC_EN |
-+ BD_CTRL_PKT_INT_EN | BD_BUF_LEN(desc_sw->len)),
-+ &desc->ctrl);
-+ } else {
-+ writel((BD_CTRL_DESC_EN |
-+ BD_BUF_LEN(desc_sw->len)), &desc->ctrl);
-+ }
-+ hif->txtoflush = (hif->txtoflush + 1) & (hif->tx_ring_size - 1);
-+ }
-+ while (hif->txtoflush != hif->txtosend)
-+ ;
-+
-+skip_tx:
-+ return;
-+}
-+
-+static irqreturn_t wol_isr(int irq, void *dev_id)
-+{
-+ pr_info("WoL\n");
-+ gemac_set_wol(EMAC1_BASE_ADDR, 0);
-+ gemac_set_wol(EMAC2_BASE_ADDR, 0);
-+ return IRQ_HANDLED;
-+}
-+
-+/*
-+ * hif_isr-
-+ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block
-+ */
-+static irqreturn_t hif_isr(int irq, void *dev_id)
-+{
-+ struct pfe_hif *hif = (struct pfe_hif *)dev_id;
-+ int int_status;
-+ int int_enable_mask;
-+
-+ /*Read hif interrupt source register */
-+ int_status = readl_relaxed(HIF_INT_SRC);
-+ int_enable_mask = readl_relaxed(HIF_INT_ENABLE);
-+
-+ if ((int_status & HIF_INT) == 0)
-+ return IRQ_NONE;
-+
-+ int_status &= ~(HIF_INT);
-+
-+ if (int_status & HIF_RXPKT_INT) {
-+ int_status &= ~(HIF_RXPKT_INT);
-+ int_enable_mask &= ~(HIF_RXPKT_INT);
-+
-+ napi_first_batch = 1;
-+
-+ if (napi_schedule_prep(&hif->napi)) {
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+ __napi_schedule(&hif->napi);
-+ }
-+ }
-+
-+ if (int_status & HIF_TXPKT_INT) {
-+ int_status &= ~(HIF_TXPKT_INT);
-+ int_enable_mask &= ~(HIF_TXPKT_INT);
-+ /*Schedule tx cleanup tassklet */
-+ tasklet_schedule(&hif->tx_cleanup_tasklet);
-+ }
-+
-+ /*Disable interrupts, they will be enabled after they are serviced */
-+ writel_relaxed(int_enable_mask, HIF_INT_ENABLE);
-+
-+ if (int_status) {
-+ pr_info("%s : Invalid interrupt : %d\n", __func__,
-+ int_status);
-+ writel(int_status, HIF_INT_SRC);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2)
-+{
-+ unsigned int client_id = data1;
-+
-+ if (client_id >= HIF_CLIENTS_MAX) {
-+ pr_err("%s: client id %d out of bounds\n", __func__,
-+ client_id);
-+ return;
-+ }
-+
-+ switch (req) {
-+ case REQUEST_CL_REGISTER:
-+ /* Request for register a client */
-+ pr_info("%s: register client_id %d\n",
-+ __func__, client_id);
-+ pfe_hif_client_register(hif, client_id, (struct
-+ hif_client_shm *)&hif->shm->client[client_id]);
-+ break;
-+
-+ case REQUEST_CL_UNREGISTER:
-+ pr_info("%s: unregister client_id %d\n",
-+ __func__, client_id);
-+
-+ /* Request for unregister a client */
-+ pfe_hif_client_unregister(hif, client_id);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported request %d\n",
-+ __func__, req);
-+ break;
-+ }
-+
-+ /*
-+ * Process client Tx queues
-+ * Currently we don't have checking for tx pending
-+ */
-+}
-+
-+/*
-+ * pfe_hif_rx_poll
-+ * This function is NAPI poll function to process HIF Rx queue.
-+ */
-+static int pfe_hif_rx_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_hif *hif = container_of(napi, struct pfe_hif, napi);
-+ int work_done;
-+
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_POLL_COUNT]++;
-+#endif
-+
-+ work_done = pfe_hif_rx_process(hif, budget);
-+
-+ if (work_done < budget) {
-+ napi_complete(napi);
-+ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_RXPKT_INT,
-+ HIF_INT_ENABLE);
-+ }
-+#ifdef HIF_NAPI_STATS
-+ else
-+ hif->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
-+#endif
-+
-+ return work_done;
-+}
-+
-+/*
-+ * pfe_hif_init
-+ * This function initializes the baseaddresses and irq, etc.
-+ */
-+int pfe_hif_init(struct pfe *pfe)
-+{
-+ struct pfe_hif *hif = &pfe->hif;
-+ int err;
-+
-+ pr_info("%s\n", __func__);
-+
-+ hif->dev = pfe->dev;
-+ hif->irq = pfe->hif_irq;
-+
-+ err = pfe_hif_alloc_descr(hif);
-+ if (err)
-+ goto err0;
-+
-+ if (pfe_hif_init_buffers(hif)) {
-+ pr_err("%s: Could not initialize buffer descriptors\n"
-+ , __func__);
-+ err = -ENOMEM;
-+ goto err1;
-+ }
-+
-+ /* Initialize NAPI for Rx processing */
-+ init_dummy_netdev(&hif->dummy_dev);
-+ netif_napi_add(&hif->dummy_dev, &hif->napi, pfe_hif_rx_poll);
-+ napi_enable(&hif->napi);
-+
-+ spin_lock_init(&hif->tx_lock);
-+ spin_lock_init(&hif->lock);
-+
-+ hif_init();
-+ hif_rx_enable();
-+ hif_tx_enable();
-+
-+ /* Disable tx done interrupt */
-+ writel(HIF_INT_MASK, HIF_INT_ENABLE);
-+
-+ gpi_enable(HGPI_BASE_ADDR);
-+
-+ err = request_irq(hif->irq, hif_isr, 0, "pfe_hif", hif);
-+ if (err) {
-+ pr_err("%s: failed to get the hif IRQ = %d\n",
-+ __func__, hif->irq);
-+ goto err1;
-+ }
-+
-+ err = request_irq(pfe->wol_irq, wol_isr, 0, "pfe_wol", pfe);
-+ if (err) {
-+ pr_err("%s: failed to get the wol IRQ = %d\n",
-+ __func__, pfe->wol_irq);
-+ goto err1;
-+ }
-+
-+ tasklet_init(&hif->tx_cleanup_tasklet,
-+ (void(*)(unsigned long))pfe_tx_do_cleanup,
-+ (unsigned long)hif);
-+
-+ return 0;
-+err1:
-+ pfe_hif_free_descr(hif);
-+err0:
-+ return err;
-+}
-+
-+/* pfe_hif_exit- */
-+void pfe_hif_exit(struct pfe *pfe)
-+{
-+ struct pfe_hif *hif = &pfe->hif;
-+
-+ pr_info("%s\n", __func__);
-+
-+ tasklet_kill(&hif->tx_cleanup_tasklet);
-+
-+ spin_lock_bh(&hif->lock);
-+ hif->shm->g_client_status[0] = 0;
-+ /* Make sure all clients are disabled*/
-+ hif->shm->g_client_status[1] = 0;
-+
-+ spin_unlock_bh(&hif->lock);
-+
-+ /*Disable Rx/Tx */
-+ gpi_disable(HGPI_BASE_ADDR);
-+ hif_rx_disable();
-+ hif_tx_disable();
-+
-+ napi_disable(&hif->napi);
-+ netif_napi_del(&hif->napi);
-+
-+ free_irq(pfe->wol_irq, pfe);
-+ free_irq(hif->irq, hif);
-+
-+ pfe_hif_release_buffers(hif);
-+ pfe_hif_free_descr(hif);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif.h
-@@ -0,0 +1,199 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_HIF_H_
-+#define _PFE_HIF_H_
-+
-+#include <linux/netdevice.h>
-+
-+#define HIF_NAPI_STATS
-+
-+#define HIF_CLIENT_QUEUES_MAX 16
-+#define HIF_RX_POLL_WEIGHT 64
-+
-+#define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */
-+#define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1)
-+#define ROUND_MIN_RX_SIZE(_sz) (((_sz) + (HIF_RX_PKT_MIN_SIZE - 1)) \
-+ & HIF_RX_PKT_MIN_SIZE_MASK)
-+#define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)(_buf) & (PAGE_SIZE \
-+ - 1)) & HIF_RX_PKT_MIN_SIZE_MASK)
-+
-+enum {
-+ NAPI_SCHED_COUNT = 0,
-+ NAPI_POLL_COUNT,
-+ NAPI_PACKET_COUNT,
-+ NAPI_DESC_COUNT,
-+ NAPI_FULL_BUDGET_COUNT,
-+ NAPI_CLIENT_FULL_COUNT,
-+ NAPI_MAX_COUNT
-+};
-+
-+/*
-+ * HIF_TX_DESC_NT value should be always greter than 4,
-+ * Otherwise HIF_TX_POLL_MARK will become zero.
-+ */
-+#define HIF_RX_DESC_NT 256
-+#define HIF_TX_DESC_NT 2048
-+
-+#define HIF_FIRST_BUFFER BIT(0)
-+#define HIF_LAST_BUFFER BIT(1)
-+#define HIF_DONT_DMA_MAP BIT(2)
-+#define HIF_DATA_VALID BIT(3)
-+#define HIF_TSO BIT(4)
-+
-+enum {
-+ PFE_CL_GEM0 = 0,
-+ PFE_CL_GEM1,
-+ HIF_CLIENTS_MAX
-+};
-+
-+/*structure to store client queue info */
-+struct hif_rx_queue {
-+ struct rx_queue_desc *base;
-+ u32 size;
-+ u32 write_idx;
-+};
-+
-+struct hif_tx_queue {
-+ struct tx_queue_desc *base;
-+ u32 size;
-+ u32 ack_idx;
-+};
-+
-+/*Structure to store the client info */
-+struct hif_client {
-+ int rx_qn;
-+ struct hif_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX];
-+ int tx_qn;
-+ struct hif_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX];
-+};
-+
-+/*HIF hardware buffer descriptor */
-+struct hif_desc {
-+ u32 ctrl;
-+ u32 status;
-+ u32 data;
-+ u32 next;
-+};
-+
-+struct __hif_desc {
-+ u32 ctrl;
-+ u32 status;
-+ u32 data;
-+};
-+
-+struct hif_desc_sw {
-+ dma_addr_t data;
-+ u16 len;
-+ u8 client_id;
-+ u8 q_no;
-+ u16 flags;
-+};
-+
-+struct hif_hdr {
-+ u8 client_id;
-+ u8 q_num;
-+ u16 client_ctrl;
-+ u16 client_ctrl1;
-+};
-+
-+struct __hif_hdr {
-+ union {
-+ struct hif_hdr hdr;
-+ u32 word[2];
-+ };
-+};
-+
-+struct hif_ipsec_hdr {
-+ u16 sa_handle[2];
-+} __packed;
-+
-+/* HIF_CTRL_TX... defines */
-+#define HIF_CTRL_TX_CHECKSUM BIT(2)
-+
-+/* HIF_CTRL_RX... defines */
-+#define HIF_CTRL_RX_OFFSET_OFST (24)
-+#define HIF_CTRL_RX_CHECKSUMMED BIT(2)
-+#define HIF_CTRL_RX_CONTINUED BIT(1)
-+
-+struct pfe_hif {
-+ /* To store registered clients in hif layer */
-+ struct hif_client client[HIF_CLIENTS_MAX];
-+ struct hif_shm *shm;
-+ int irq;
-+
-+ void *descr_baseaddr_v;
-+ unsigned long descr_baseaddr_p;
-+
-+ struct hif_desc *rx_base;
-+ u32 rx_ring_size;
-+ u32 rxtoclean_index;
-+ void *rx_buf_addr[HIF_RX_DESC_NT];
-+ int rx_buf_len[HIF_RX_DESC_NT];
-+ unsigned int qno;
-+ unsigned int client_id;
-+ unsigned int client_ctrl;
-+ unsigned int started;
-+
-+ struct hif_desc *tx_base;
-+ u32 tx_ring_size;
-+ u32 txtosend;
-+ u32 txtoclean;
-+ u32 txavail;
-+ u32 txtoflush;
-+ struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT];
-+
-+/* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */
-+ spinlock_t tx_lock;
-+/* lock synchronizes hif rx queue processing */
-+ spinlock_t lock;
-+ struct net_device dummy_dev;
-+ struct napi_struct napi;
-+ struct device *dev;
-+
-+#ifdef HIF_NAPI_STATS
-+ unsigned int napi_counters[NAPI_MAX_COUNT];
-+#endif
-+ struct tasklet_struct tx_cleanup_tasklet;
-+};
-+
-+void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
-+ q_no, void *data, u32 len, unsigned int flags);
-+int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no,
-+ void *data, unsigned int len);
-+void __hif_tx_done_process(struct pfe_hif *hif, int count);
-+void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int
-+ data2);
-+int pfe_hif_init(struct pfe *pfe);
-+void pfe_hif_exit(struct pfe *pfe);
-+void pfe_hif_rx_idle(struct pfe_hif *hif);
-+static inline void hif_tx_done_process(struct pfe_hif *hif, int count)
-+{
-+ spin_lock_bh(&hif->tx_lock);
-+ __hif_tx_done_process(hif, count);
-+ spin_unlock_bh(&hif->tx_lock);
-+}
-+
-+static inline void hif_tx_lock(struct pfe_hif *hif)
-+{
-+ spin_lock_bh(&hif->tx_lock);
-+}
-+
-+static inline void hif_tx_unlock(struct pfe_hif *hif)
-+{
-+ spin_unlock_bh(&hif->tx_lock);
-+}
-+
-+static inline int __hif_tx_avail(struct pfe_hif *hif)
-+{
-+ return hif->txavail;
-+}
-+
-+#define __memcpy8(dst, src) memcpy(dst, src, 8)
-+#define __memcpy12(dst, src) memcpy(dst, src, 12)
-+#define __memcpy(dst, src, len) memcpy(dst, src, len)
-+
-+#endif /* _PFE_HIF_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
-@@ -0,0 +1,628 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/workqueue.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/sched.h>
-+#include <linux/skbuff.h>
-+#include <linux/moduleparam.h>
-+#include <linux/cpu.h>
-+
-+#include "pfe_mod.h"
-+#include "pfe_hif.h"
-+#include "pfe_hif_lib.h"
-+
-+unsigned int lro_mode;
-+unsigned int page_mode;
-+unsigned int tx_qos = 1;
-+module_param(tx_qos, uint, 0444);
-+MODULE_PARM_DESC(tx_qos, "0: disable ,\n"
-+ "1: enable (default), guarantee no packet drop at TMU level\n");
-+unsigned int pfe_pkt_size;
-+unsigned int pfe_pkt_headroom;
-+unsigned int emac_txq_cnt;
-+
-+/*
-+ * @pfe_hal_lib.c.
-+ * Common functions used by HIF client drivers
-+ */
-+
-+/*HIF shared memory Global variable */
-+struct hif_shm ghif_shm;
-+
-+/* Cleanup the HIF shared memory, release HIF rx_buffer_pool.
-+ * This function should be called after pfe_hif_exit
-+ *
-+ * @param[in] hif_shm Shared memory address location in DDR
-+ */
-+static void pfe_hif_shm_clean(struct hif_shm *hif_shm)
-+{
-+ int i;
-+ void *pkt;
-+
-+ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
-+ pkt = hif_shm->rx_buf_pool[i];
-+ if (pkt) {
-+ hif_shm->rx_buf_pool[i] = NULL;
-+ pkt -= pfe_pkt_headroom;
-+
-+ if (page_mode)
-+ put_page(virt_to_page(pkt));
-+ else
-+ kfree(pkt);
-+ }
-+ }
-+}
-+
-+/* Initialize shared memory used between HIF driver and clients,
-+ * allocate rx_buffer_pool required for HIF Rx descriptors.
-+ * This function should be called before initializing HIF driver.
-+ *
-+ * @param[in] hif_shm Shared memory address location in DDR
-+ * @rerurn 0 - on succes, <0 on fail to initialize
-+ */
-+static int pfe_hif_shm_init(struct hif_shm *hif_shm)
-+{
-+ int i;
-+ void *pkt;
-+
-+ memset(hif_shm, 0, sizeof(struct hif_shm));
-+ hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT;
-+
-+ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
-+ if (page_mode) {
-+ pkt = (void *)__get_free_page(GFP_KERNEL |
-+ GFP_DMA_PFE);
-+ } else {
-+ pkt = kmalloc(PFE_BUF_SIZE, GFP_KERNEL | GFP_DMA_PFE);
-+ }
-+
-+ if (pkt)
-+ hif_shm->rx_buf_pool[i] = pkt + pfe_pkt_headroom;
-+ else
-+ goto err0;
-+ }
-+
-+ return 0;
-+
-+err0:
-+ pr_err("%s Low memory\n", __func__);
-+ pfe_hif_shm_clean(hif_shm);
-+ return -ENOMEM;
-+}
-+
-+/*This function sends indication to HIF driver
-+ *
-+ * @param[in] hif hif context
-+ */
-+static void hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int
-+ data2)
-+{
-+ hif_process_client_req(hif, req, data1, data2);
-+}
-+
-+void hif_lib_indicate_client(int client_id, int event_type, int qno)
-+{
-+ struct hif_client_s *client = pfe->hif_client[client_id];
-+
-+ if (!client || (event_type >= HIF_EVENT_MAX) || (qno >=
-+ HIF_CLIENT_QUEUES_MAX))
-+ return;
-+
-+ if (!test_and_set_bit(qno, &client->queue_mask[event_type]))
-+ client->event_handler(client->priv, event_type, qno);
-+}
-+
-+/*This function releases Rx queue descriptors memory and pre-filled buffers
-+ *
-+ * @param[in] client hif_client context
-+ */
-+static void hif_lib_client_release_rx_buffers(struct hif_client_s *client)
-+{
-+ struct rx_queue_desc *desc;
-+ int qno, ii;
-+ void *buf;
-+
-+ for (qno = 0; qno < client->rx_qn; qno++) {
-+ desc = client->rx_q[qno].base;
-+
-+ for (ii = 0; ii < client->rx_q[qno].size; ii++) {
-+ buf = (void *)desc->data;
-+ if (buf) {
-+ buf -= pfe_pkt_headroom;
-+
-+ if (page_mode)
-+ free_page((unsigned long)buf);
-+ else
-+ kfree(buf);
-+
-+ desc->ctrl = 0;
-+ }
-+
-+ desc++;
-+ }
-+ }
-+
-+ kfree(client->rx_qbase);
-+}
-+
-+/*This function allocates memory for the rxq descriptors and pre-fill rx queues
-+ * with buffers.
-+ * @param[in] client client context
-+ * @param[in] q_size size of the rxQ, all queues are of same size
-+ */
-+static int hif_lib_client_init_rx_buffers(struct hif_client_s *client, int
-+ q_size)
-+{
-+ struct rx_queue_desc *desc;
-+ struct hif_client_rx_queue *queue;
-+ int ii, qno;
-+
-+ /*Allocate memory for the client queues */
-+ client->rx_qbase = kzalloc(client->rx_qn * q_size * sizeof(struct
-+ rx_queue_desc), GFP_KERNEL);
-+ if (!client->rx_qbase)
-+ goto err;
-+
-+ for (qno = 0; qno < client->rx_qn; qno++) {
-+ queue = &client->rx_q[qno];
-+
-+ queue->base = client->rx_qbase + qno * q_size * sizeof(struct
-+ rx_queue_desc);
-+ queue->size = q_size;
-+ queue->read_idx = 0;
-+ queue->write_idx = 0;
-+
-+ pr_debug("rx queue: %d, base: %p, size: %d\n", qno,
-+ queue->base, queue->size);
-+ }
-+
-+ for (qno = 0; qno < client->rx_qn; qno++) {
-+ queue = &client->rx_q[qno];
-+ desc = queue->base;
-+
-+ for (ii = 0; ii < queue->size; ii++) {
-+ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) |
-+ CL_DESC_OWN;
-+ desc++;
-+ }
-+ }
-+
-+ return 0;
-+
-+err:
-+ return 1;
-+}
-+
-+
-+static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue)
-+{
-+ pr_debug("%s\n", __func__);
-+
-+ /*
-+ * Check if there are any pending packets. Client must flush the tx
-+ * queues before unregistering, by calling by calling
-+ * hif_lib_tx_get_next_complete()
-+ *
-+ * Hif no longer calls since we are no longer registered
-+ */
-+ if (queue->tx_pending)
-+ pr_err("%s: pending transmit packets\n", __func__);
-+}
-+
-+static void hif_lib_client_release_tx_buffers(struct hif_client_s *client)
-+{
-+ int qno;
-+
-+ pr_debug("%s\n", __func__);
-+
-+ for (qno = 0; qno < client->tx_qn; qno++)
-+ hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]);
-+
-+ kfree(client->tx_qbase);
-+}
-+
-+static int hif_lib_client_init_tx_buffers(struct hif_client_s *client, int
-+ q_size)
-+{
-+ struct hif_client_tx_queue *queue;
-+ int qno;
-+
-+ client->tx_qbase = kzalloc(client->tx_qn * q_size * sizeof(struct
-+ tx_queue_desc), GFP_KERNEL);
-+ if (!client->tx_qbase)
-+ return 1;
-+
-+ for (qno = 0; qno < client->tx_qn; qno++) {
-+ queue = &client->tx_q[qno];
-+
-+ queue->base = client->tx_qbase + qno * q_size * sizeof(struct
-+ tx_queue_desc);
-+ queue->size = q_size;
-+ queue->read_idx = 0;
-+ queue->write_idx = 0;
-+ queue->tx_pending = 0;
-+ queue->nocpy_flag = 0;
-+ queue->prev_tmu_tx_pkts = 0;
-+ queue->done_tmu_tx_pkts = 0;
-+
-+ pr_debug("tx queue: %d, base: %p, size: %d\n", qno,
-+ queue->base, queue->size);
-+ }
-+
-+ return 0;
-+}
-+
-+static int hif_lib_event_dummy(void *priv, int event_type, int qno)
-+{
-+ return 0;
-+}
-+
-+int hif_lib_client_register(struct hif_client_s *client)
-+{
-+ struct hif_shm *hif_shm;
-+ struct hif_client_shm *client_shm;
-+ int err, i;
-+ /* int loop_cnt = 0; */
-+
-+ pr_debug("%s\n", __func__);
-+
-+ /*Allocate memory before spin_lock*/
-+ if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) {
-+ err = -ENOMEM;
-+ goto err_rx;
-+ }
-+
-+ if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) {
-+ err = -ENOMEM;
-+ goto err_tx;
-+ }
-+
-+ spin_lock_bh(&pfe->hif.lock);
-+ if (!(client->pfe) || (client->id >= HIF_CLIENTS_MAX) ||
-+ (pfe->hif_client[client->id])) {
-+ err = -EINVAL;
-+ goto err;
-+ }
-+
-+ hif_shm = client->pfe->hif.shm;
-+
-+ if (!client->event_handler)
-+ client->event_handler = hif_lib_event_dummy;
-+
-+ /*Initialize client specific shared memory */
-+ client_shm = (struct hif_client_shm *)&hif_shm->client[client->id];
-+ client_shm->rx_qbase = (unsigned long int)client->rx_qbase;
-+ client_shm->rx_qsize = client->rx_qsize;
-+ client_shm->tx_qbase = (unsigned long int)client->tx_qbase;
-+ client_shm->tx_qsize = client->tx_qsize;
-+ client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) |
-+ (client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST);
-+ /* spin_lock_init(&client->rx_lock); */
-+
-+ for (i = 0; i < HIF_EVENT_MAX; i++) {
-+ client->queue_mask[i] = 0; /*
-+ * By default all events are
-+ * unmasked
-+ */
-+ }
-+
-+ /*Indicate to HIF driver*/
-+ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_REGISTER, client->id, 0);
-+
-+ pr_debug("%s: client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d\n",
-+ __func__, client, client->id, client->tx_qsize,
-+ client->rx_qsize);
-+
-+ client->cpu_id = -1;
-+
-+ pfe->hif_client[client->id] = client;
-+ spin_unlock_bh(&pfe->hif.lock);
-+
-+ return 0;
-+
-+err:
-+ spin_unlock_bh(&pfe->hif.lock);
-+ hif_lib_client_release_tx_buffers(client);
-+
-+err_tx:
-+ hif_lib_client_release_rx_buffers(client);
-+
-+err_rx:
-+ return err;
-+}
-+
-+int hif_lib_client_unregister(struct hif_client_s *client)
-+{
-+ struct pfe *pfe = client->pfe;
-+ u32 client_id = client->id;
-+
-+ pr_info(
-+ "%s : client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d\n"
-+ , __func__, client, client->id, client->tx_qsize,
-+ client->rx_qsize);
-+
-+ spin_lock_bh(&pfe->hif.lock);
-+ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0);
-+
-+ hif_lib_client_release_tx_buffers(client);
-+ hif_lib_client_release_rx_buffers(client);
-+ pfe->hif_client[client_id] = NULL;
-+ spin_unlock_bh(&pfe->hif.lock);
-+
-+ return 0;
-+}
-+
-+int hif_lib_event_handler_start(struct hif_client_s *client, int event,
-+ int qno)
-+{
-+ struct hif_client_rx_queue *queue = &client->rx_q[qno];
-+ struct rx_queue_desc *desc = queue->base + queue->read_idx;
-+
-+ if ((event >= HIF_EVENT_MAX) || (qno >= HIF_CLIENT_QUEUES_MAX)) {
-+ pr_debug("%s: Unsupported event : %d queue number : %d\n",
-+ __func__, event, qno);
-+ return -1;
-+ }
-+
-+ test_and_clear_bit(qno, &client->queue_mask[event]);
-+
-+ switch (event) {
-+ case EVENT_RX_PKT_IND:
-+ if (!(desc->ctrl & CL_DESC_OWN))
-+ hif_lib_indicate_client(client->id,
-+ EVENT_RX_PKT_IND, qno);
-+ break;
-+
-+ case EVENT_HIGH_RX_WM:
-+ case EVENT_TXDONE_IND:
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * This function gets one packet from the specified client queue
-+ * It also refill the rx buffer
-+ */
-+void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
-+ *ofst, unsigned int *rx_ctrl,
-+ unsigned int *desc_ctrl, void **priv_data)
-+{
-+ struct hif_client_rx_queue *queue = &client->rx_q[qno];
-+ struct rx_queue_desc *desc;
-+ void *pkt = NULL;
-+
-+ /*
-+ * Following lock is to protect rx queue access from,
-+ * hif_lib_event_handler_start.
-+ * In general below lock is not required, because hif_lib_xmit_pkt and
-+ * hif_lib_event_handler_start are called from napi poll and which is
-+ * not re-entrant. But if some client use in different way this lock is
-+ * required.
-+ */
-+ /*spin_lock_irqsave(&client->rx_lock, flags); */
-+ desc = queue->base + queue->read_idx;
-+ if (!(desc->ctrl & CL_DESC_OWN)) {
-+ pkt = desc->data - pfe_pkt_headroom;
-+
-+ *rx_ctrl = desc->client_ctrl;
-+ *desc_ctrl = desc->ctrl;
-+
-+ if (desc->ctrl & CL_DESC_FIRST) {
-+ u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST;
-+
-+ if (size) {
-+ size += PFE_PARSE_INFO_SIZE;
-+ *len = CL_DESC_BUF_LEN(desc->ctrl) -
-+ PFE_PKT_HEADER_SZ - size;
-+ *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ
-+ + size;
-+ *priv_data = desc->data + PFE_PKT_HEADER_SZ;
-+ } else {
-+ *len = CL_DESC_BUF_LEN(desc->ctrl) -
-+ PFE_PKT_HEADER_SZ - PFE_PARSE_INFO_SIZE;
-+ *ofst = pfe_pkt_headroom
-+ + PFE_PKT_HEADER_SZ
-+ + PFE_PARSE_INFO_SIZE;
-+ *priv_data = NULL;
-+ }
-+
-+ } else {
-+ *len = CL_DESC_BUF_LEN(desc->ctrl);
-+ *ofst = pfe_pkt_headroom;
-+ }
-+
-+ /*
-+ * Needed so we don't free a buffer/page
-+ * twice on module_exit
-+ */
-+ desc->data = NULL;
-+
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ smp_wmb();
-+
-+ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN;
-+ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1);
-+ }
-+
-+ /*spin_unlock_irqrestore(&client->rx_lock, flags); */
-+ return pkt;
-+}
-+
-+static inline void hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int
-+ client_id, unsigned int qno,
-+ u32 client_ctrl)
-+{
-+ /* Optimize the write since the destinaton may be non-cacheable */
-+ if (!((unsigned long)pkt_hdr & 0x3)) {
-+ ((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) |
-+ client_id;
-+ } else {
-+ ((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF);
-+ ((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF);
-+ }
-+}
-+
-+/*This function puts the given packet in the specific client queue */
-+void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
-+ *data, unsigned int len, u32 client_ctrl,
-+ unsigned int flags, void *client_data)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+ struct tx_queue_desc *desc = queue->base + queue->write_idx;
-+
-+ /* First buffer */
-+ if (flags & HIF_FIRST_BUFFER) {
-+ data -= sizeof(struct hif_hdr);
-+ len += sizeof(struct hif_hdr);
-+
-+ hif_hdr_write(data, client->id, qno, client_ctrl);
-+ }
-+
-+ desc->data = client_data;
-+ desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags);
-+
-+ __hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags);
-+
-+ queue->write_idx = (queue->write_idx + 1) & (queue->size - 1);
-+ queue->tx_pending++;
-+ queue->jiffies_last_packet = jiffies;
-+}
-+
-+void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
-+ unsigned int *flags, int count)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+ struct tx_queue_desc *desc = queue->base + queue->read_idx;
-+
-+ pr_debug("%s: qno : %d rd_indx: %d pending:%d\n", __func__, qno,
-+ queue->read_idx, queue->tx_pending);
-+
-+ if (!queue->tx_pending)
-+ return NULL;
-+
-+ if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) {
-+ u32 tmu_tx_pkts = be32_to_cpu(pe_dmem_read(TMU0_ID +
-+ client->id, TMU_DM_TX_TRANS, 4));
-+
-+ if (queue->prev_tmu_tx_pkts > tmu_tx_pkts)
-+ queue->done_tmu_tx_pkts = UINT_MAX -
-+ queue->prev_tmu_tx_pkts + tmu_tx_pkts;
-+ else
-+ queue->done_tmu_tx_pkts = tmu_tx_pkts -
-+ queue->prev_tmu_tx_pkts;
-+
-+ queue->prev_tmu_tx_pkts = tmu_tx_pkts;
-+
-+ if (!queue->done_tmu_tx_pkts)
-+ return NULL;
-+ }
-+
-+ if (desc->ctrl & CL_DESC_OWN)
-+ return NULL;
-+
-+ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1);
-+ queue->tx_pending--;
-+
-+ *flags = CL_DESC_GET_FLAGS(desc->ctrl);
-+
-+ if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER))
-+ queue->done_tmu_tx_pkts--;
-+
-+ return desc->data;
-+}
-+
-+static void hif_lib_tmu_credit_init(struct pfe *pfe)
-+{
-+ int i, q;
-+
-+ for (i = 0; i < NUM_GEMAC_SUPPORT; i++)
-+ for (q = 0; q < emac_txq_cnt; q++) {
-+ pfe->tmu_credit.tx_credit_max[i][q] = (q == 0) ?
-+ DEFAULT_Q0_QDEPTH : DEFAULT_MAX_QDEPTH;
-+ pfe->tmu_credit.tx_credit[i][q] =
-+ pfe->tmu_credit.tx_credit_max[i][q];
-+ }
-+}
-+
-+/* __hif_lib_update_credit
-+ *
-+ * @param[in] client hif client context
-+ * @param[in] queue queue number in match with TMU
-+ */
-+void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue)
-+{
-+ unsigned int tmu_tx_packets, tmp;
-+
-+ if (tx_qos) {
-+ tmu_tx_packets = be32_to_cpu(pe_dmem_read(TMU0_ID +
-+ client->id, (TMU_DM_TX_TRANS + (queue * 4)), 4));
-+
-+ /* tx_packets counter overflowed */
-+ if (tmu_tx_packets >
-+ pfe->tmu_credit.tx_packets[client->id][queue]) {
-+ tmp = UINT_MAX - tmu_tx_packets +
-+ pfe->tmu_credit.tx_packets[client->id][queue];
-+
-+ pfe->tmu_credit.tx_credit[client->id][queue] =
-+ pfe->tmu_credit.tx_credit_max[client->id][queue] - tmp;
-+ } else {
-+ /* TMU tx <= pfe_eth tx, normal case or both OF since
-+ * last time
-+ */
-+ pfe->tmu_credit.tx_credit[client->id][queue] =
-+ pfe->tmu_credit.tx_credit_max[client->id][queue] -
-+ (pfe->tmu_credit.tx_packets[client->id][queue] -
-+ tmu_tx_packets);
-+ }
-+ }
-+}
-+
-+int pfe_hif_lib_init(struct pfe *pfe)
-+{
-+ int rc;
-+
-+ pr_info("%s\n", __func__);
-+
-+ if (lro_mode) {
-+ page_mode = 1;
-+ pfe_pkt_size = min(PAGE_SIZE, MAX_PFE_PKT_SIZE);
-+ pfe_pkt_headroom = 0;
-+ } else {
-+ page_mode = 0;
-+ pfe_pkt_size = PFE_PKT_SIZE;
-+ pfe_pkt_headroom = PFE_PKT_HEADROOM;
-+ }
-+
-+ if (tx_qos)
-+ emac_txq_cnt = EMAC_TXQ_CNT / 2;
-+ else
-+ emac_txq_cnt = EMAC_TXQ_CNT;
-+
-+ hif_lib_tmu_credit_init(pfe);
-+ pfe->hif.shm = &ghif_shm;
-+ rc = pfe_hif_shm_init(pfe->hif.shm);
-+
-+ return rc;
-+}
-+
-+void pfe_hif_lib_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ pfe_hif_shm_clean(pfe->hif.shm);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
-@@ -0,0 +1,229 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_HIF_LIB_H_
-+#define _PFE_HIF_LIB_H_
-+
-+#include "pfe_hif.h"
-+
-+#define HIF_CL_REQ_TIMEOUT 10
-+#define GFP_DMA_PFE 0
-+#define PFE_PARSE_INFO_SIZE 16
-+
-+enum {
-+ REQUEST_CL_REGISTER = 0,
-+ REQUEST_CL_UNREGISTER,
-+ HIF_REQUEST_MAX
-+};
-+
-+enum {
-+ /* Event to indicate that client rx queue is reached water mark level */
-+ EVENT_HIGH_RX_WM = 0,
-+ /* Event to indicate that, packet received for client */
-+ EVENT_RX_PKT_IND,
-+ /* Event to indicate that, packet tx done for client */
-+ EVENT_TXDONE_IND,
-+ HIF_EVENT_MAX
-+};
-+
-+/*structure to store client queue info */
-+
-+/*structure to store client queue info */
-+struct hif_client_rx_queue {
-+ struct rx_queue_desc *base;
-+ u32 size;
-+ u32 read_idx;
-+ u32 write_idx;
-+};
-+
-+struct hif_client_tx_queue {
-+ struct tx_queue_desc *base;
-+ u32 size;
-+ u32 read_idx;
-+ u32 write_idx;
-+ u32 tx_pending;
-+ unsigned long jiffies_last_packet;
-+ u32 nocpy_flag;
-+ u32 prev_tmu_tx_pkts;
-+ u32 done_tmu_tx_pkts;
-+};
-+
-+struct hif_client_s {
-+ int id;
-+ int tx_qn;
-+ int rx_qn;
-+ void *rx_qbase;
-+ void *tx_qbase;
-+ int tx_qsize;
-+ int rx_qsize;
-+ int cpu_id;
-+ struct hif_client_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX];
-+ struct hif_client_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX];
-+ int (*event_handler)(void *priv, int event, int data);
-+ unsigned long queue_mask[HIF_EVENT_MAX];
-+ struct pfe *pfe;
-+ void *priv;
-+};
-+
-+/*
-+ * Client specific shared memory
-+ * It contains number of Rx/Tx queues, base addresses and queue sizes
-+ */
-+struct hif_client_shm {
-+ u32 ctrl; /*0-7: number of Rx queues, 8-15: number of tx queues */
-+ unsigned long rx_qbase; /*Rx queue base address */
-+ u32 rx_qsize; /*each Rx queue size, all Rx queues are of same size */
-+ unsigned long tx_qbase; /* Tx queue base address */
-+ u32 tx_qsize; /*each Tx queue size, all Tx queues are of same size */
-+};
-+
-+/*Client shared memory ctrl bit description */
-+#define CLIENT_CTRL_RX_Q_CNT_OFST 0
-+#define CLIENT_CTRL_TX_Q_CNT_OFST 8
-+#define CLIENT_CTRL_RX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_RX_Q_CNT_OFST) \
-+ & 0xFF)
-+#define CLIENT_CTRL_TX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_TX_Q_CNT_OFST) \
-+ & 0xFF)
-+
-+/*
-+ * Shared memory used to communicate between HIF driver and host/client drivers
-+ * Before starting the hif driver rx_buf_pool ans rx_buf_pool_cnt should be
-+ * initialized with host buffers and buffers count in the pool.
-+ * rx_buf_pool_cnt should be >= HIF_RX_DESC_NT.
-+ *
-+ */
-+struct hif_shm {
-+ u32 rx_buf_pool_cnt; /*Number of rx buffers available*/
-+ /*Rx buffers required to initialize HIF rx descriptors */
-+ void *rx_buf_pool[HIF_RX_DESC_NT];
-+ unsigned long g_client_status[2]; /*Global client status bit mask */
-+ /* Client specific shared memory */
-+ struct hif_client_shm client[HIF_CLIENTS_MAX];
-+};
-+
-+#define CL_DESC_OWN BIT(31)
-+/* This sets owner ship to HIF driver */
-+#define CL_DESC_LAST BIT(30)
-+/* This indicates last packet for multi buffers handling */
-+#define CL_DESC_FIRST BIT(29)
-+/* This indicates first packet for multi buffers handling */
-+
-+#define CL_DESC_BUF_LEN(x) ((x) & 0xFFFF)
-+#define CL_DESC_FLAGS(x) (((x) & 0xF) << 16)
-+#define CL_DESC_GET_FLAGS(x) (((x) >> 16) & 0xF)
-+
-+struct rx_queue_desc {
-+ void *data;
-+ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
-+ u32 client_ctrl;
-+};
-+
-+struct tx_queue_desc {
-+ void *data;
-+ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
-+};
-+
-+/* HIF Rx is not working properly for 2-byte aligned buffers and
-+ * ip_header should be 4byte aligned for better iperformance.
-+ * "ip_header = 64 + 6(hif_header) + 14 (MAC Header)" will be 4byte aligned.
-+ */
-+#define PFE_PKT_HEADER_SZ sizeof(struct hif_hdr)
-+/* must be big enough for headroom, pkt size and skb shared info */
-+#define PFE_BUF_SIZE 2048
-+#define PFE_PKT_HEADROOM 128
-+
-+#define SKB_SHARED_INFO_SIZE SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
-+#define PFE_PKT_SIZE (PFE_BUF_SIZE - PFE_PKT_HEADROOM \
-+ - SKB_SHARED_INFO_SIZE)
-+#define MAX_L2_HDR_SIZE 14 /* Not correct for VLAN/PPPoE */
-+#define MAX_L3_HDR_SIZE 20 /* Not correct for IPv6 */
-+#define MAX_L4_HDR_SIZE 60 /* TCP with maximum options */
-+#define MAX_HDR_SIZE (MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE \
-+ + MAX_L4_HDR_SIZE)
-+/* Used in page mode to clamp packet size to the maximum supported by the hif
-+ *hw interface (<16KiB)
-+ */
-+#define MAX_PFE_PKT_SIZE 16380UL
-+
-+extern unsigned int pfe_pkt_size;
-+extern unsigned int pfe_pkt_headroom;
-+extern unsigned int page_mode;
-+extern unsigned int lro_mode;
-+extern unsigned int tx_qos;
-+extern unsigned int emac_txq_cnt;
-+
-+int pfe_hif_lib_init(struct pfe *pfe);
-+void pfe_hif_lib_exit(struct pfe *pfe);
-+int hif_lib_client_register(struct hif_client_s *client);
-+int hif_lib_client_unregister(struct hif_client_s *client);
-+void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
-+ *data, unsigned int len, u32 client_ctrl,
-+ unsigned int flags, void *client_data);
-+int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data,
-+ unsigned int len, u32 client_ctrl, void *client_data);
-+void hif_lib_indicate_client(int cl_id, int event, int data);
-+int hif_lib_event_handler_start(struct hif_client_s *client, int event, int
-+ data);
-+int hif_lib_tmu_queue_start(struct hif_client_s *client, int qno);
-+int hif_lib_tmu_queue_stop(struct hif_client_s *client, int qno);
-+void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
-+ unsigned int *flags, int count);
-+void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
-+ *ofst, unsigned int *rx_ctrl,
-+ unsigned int *desc_ctrl, void **priv_data);
-+void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue);
-+void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id);
-+void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int
-+ enable);
-+static inline int hif_lib_tx_avail(struct hif_client_s *client, unsigned int
-+ qno)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+
-+ return (queue->size - queue->tx_pending);
-+}
-+
-+static inline int hif_lib_get_tx_wr_index(struct hif_client_s *client, unsigned
-+ int qno)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+
-+ return queue->write_idx;
-+}
-+
-+static inline int hif_lib_tx_pending(struct hif_client_s *client, unsigned int
-+ qno)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+
-+ return queue->tx_pending;
-+}
-+
-+#define hif_lib_tx_credit_avail(pfe, id, qno) \
-+ ((pfe)->tmu_credit.tx_credit[id][qno])
-+
-+#define hif_lib_tx_credit_max(pfe, id, qno) \
-+ ((pfe)->tmu_credit.tx_credit_max[id][qno])
-+
-+/*
-+ * Test comment
-+ */
-+#define hif_lib_tx_credit_use(pfe, id, qno, credit) \
-+ ({ typeof(pfe) pfe_ = pfe; \
-+ typeof(id) id_ = id; \
-+ typeof(qno) qno_ = qno; \
-+ typeof(credit) credit_ = credit; \
-+ do { \
-+ if (tx_qos) { \
-+ (pfe_)->tmu_credit.tx_credit[id_][qno_]\
-+ -= credit_; \
-+ (pfe_)->tmu_credit.tx_packets[id_][qno_]\
-+ += credit_; \
-+ } \
-+ } while (0); \
-+ })
-+
-+#endif /* _PFE_HIF_LIB_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hw.c
-@@ -0,0 +1,164 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include "pfe_mod.h"
-+#include "pfe_hw.h"
-+
-+/* Functions to handle most of pfe hw register initialization */
-+int pfe_hw_init(struct pfe *pfe, int resume)
-+{
-+ struct class_cfg class_cfg = {
-+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
-+ .route_table_baseaddr = pfe->ddr_phys_baseaddr +
-+ ROUTE_TABLE_BASEADDR,
-+ .route_table_hash_bits = ROUTE_TABLE_HASH_BITS,
-+ };
-+
-+ struct tmu_cfg tmu_cfg = {
-+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
-+ .llm_base_addr = pfe->ddr_phys_baseaddr + TMU_LLM_BASEADDR,
-+ .llm_queue_len = TMU_LLM_QUEUE_LEN,
-+ };
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ struct util_cfg util_cfg = {
-+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
-+ };
-+#endif
-+
-+ struct BMU_CFG bmu1_cfg = {
-+ .baseaddr = CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR +
-+ BMU1_LMEM_BASEADDR),
-+ .count = BMU1_BUF_COUNT,
-+ .size = BMU1_BUF_SIZE,
-+ .low_watermark = 10,
-+ .high_watermark = 15,
-+ };
-+
-+ struct BMU_CFG bmu2_cfg = {
-+ .baseaddr = DDR_PHYS_TO_PFE(pfe->ddr_phys_baseaddr +
-+ BMU2_DDR_BASEADDR),
-+ .count = BMU2_BUF_COUNT,
-+ .size = BMU2_BUF_SIZE,
-+ .low_watermark = 250,
-+ .high_watermark = 253,
-+ };
-+
-+ struct gpi_cfg egpi1_cfg = {
-+ .lmem_rtry_cnt = EGPI1_LMEM_RTRY_CNT,
-+ .tmlf_txthres = EGPI1_TMLF_TXTHRES,
-+ .aseq_len = EGPI1_ASEQ_LEN,
-+ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC1_BASE_ADDR +
-+ EMAC_TCNTRL_REG),
-+ };
-+
-+ struct gpi_cfg egpi2_cfg = {
-+ .lmem_rtry_cnt = EGPI2_LMEM_RTRY_CNT,
-+ .tmlf_txthres = EGPI2_TMLF_TXTHRES,
-+ .aseq_len = EGPI2_ASEQ_LEN,
-+ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC2_BASE_ADDR +
-+ EMAC_TCNTRL_REG),
-+ };
-+
-+ struct gpi_cfg hgpi_cfg = {
-+ .lmem_rtry_cnt = HGPI_LMEM_RTRY_CNT,
-+ .tmlf_txthres = HGPI_TMLF_TXTHRES,
-+ .aseq_len = HGPI_ASEQ_LEN,
-+ .mtip_pause_reg = 0,
-+ };
-+
-+ pr_info("%s\n", __func__);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ /* LS1012A needs this to make PE work correctly */
-+ writel(0x3, CLASS_PE_SYS_CLK_RATIO);
-+ writel(0x3, TMU_PE_SYS_CLK_RATIO);
-+ writel(0x3, UTIL_PE_SYS_CLK_RATIO);
-+ usleep_range(10, 20);
-+#endif
-+
-+ pr_info("CLASS version: %x\n", readl(CLASS_VERSION));
-+ pr_info("TMU version: %x\n", readl(TMU_VERSION));
-+
-+ pr_info("BMU1 version: %x\n", readl(BMU1_BASE_ADDR +
-+ BMU_VERSION));
-+ pr_info("BMU2 version: %x\n", readl(BMU2_BASE_ADDR +
-+ BMU_VERSION));
-+
-+ pr_info("EGPI1 version: %x\n", readl(EGPI1_BASE_ADDR +
-+ GPI_VERSION));
-+ pr_info("EGPI2 version: %x\n", readl(EGPI2_BASE_ADDR +
-+ GPI_VERSION));
-+ pr_info("HGPI version: %x\n", readl(HGPI_BASE_ADDR +
-+ GPI_VERSION));
-+
-+ pr_info("HIF version: %x\n", readl(HIF_VERSION));
-+ pr_info("HIF NOPCY version: %x\n", readl(HIF_NOCPY_VERSION));
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pr_info("UTIL version: %x\n", readl(UTIL_VERSION));
-+#endif
-+ while (!(readl(TMU_CTRL) & ECC_MEM_INIT_DONE))
-+ ;
-+
-+ hif_rx_disable();
-+ hif_tx_disable();
-+
-+ bmu_init(BMU1_BASE_ADDR, &bmu1_cfg);
-+
-+ pr_info("bmu_init(1) done\n");
-+
-+ bmu_init(BMU2_BASE_ADDR, &bmu2_cfg);
-+
-+ pr_info("bmu_init(2) done\n");
-+
-+ class_cfg.resume = resume ? 1 : 0;
-+
-+ class_init(&class_cfg);
-+
-+ pr_info("class_init() done\n");
-+
-+ tmu_init(&tmu_cfg);
-+
-+ pr_info("tmu_init() done\n");
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ util_init(&util_cfg);
-+
-+ pr_info("util_init() done\n");
-+#endif
-+ gpi_init(EGPI1_BASE_ADDR, &egpi1_cfg);
-+
-+ pr_info("gpi_init(1) done\n");
-+
-+ gpi_init(EGPI2_BASE_ADDR, &egpi2_cfg);
-+
-+ pr_info("gpi_init(2) done\n");
-+
-+ gpi_init(HGPI_BASE_ADDR, &hgpi_cfg);
-+
-+ pr_info("gpi_init(hif) done\n");
-+
-+ bmu_enable(BMU1_BASE_ADDR);
-+
-+ pr_info("bmu_enable(1) done\n");
-+
-+ bmu_enable(BMU2_BASE_ADDR);
-+
-+ pr_info("bmu_enable(2) done\n");
-+
-+ return 0;
-+}
-+
-+void pfe_hw_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ bmu_disable(BMU1_BASE_ADDR);
-+ bmu_reset(BMU1_BASE_ADDR);
-+
-+ bmu_disable(BMU2_BASE_ADDR);
-+ bmu_reset(BMU2_BASE_ADDR);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hw.h
-@@ -0,0 +1,15 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_HW_H_
-+#define _PFE_HW_H_
-+
-+#define PE_SYS_CLK_RATIO 1 /* SYS/AXI = 250MHz, HFE = 500MHz */
-+
-+int pfe_hw_init(struct pfe *pfe, int resume);
-+void pfe_hw_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_HW_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
-@@ -0,0 +1,383 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/of.h>
-+#include <linux/of_net.h>
-+#include <linux/of_address.h>
-+#include <linux/of_mdio.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/clk.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/regmap.h>
-+
-+#include "pfe_mod.h"
-+
-+extern bool pfe_use_old_dts_phy;
-+struct ls1012a_pfe_platform_data pfe_platform_data;
-+
-+static int pfe_get_gemac_if_properties(struct device_node *gem,
-+ int port,
-+ struct ls1012a_pfe_platform_data *pdata)
-+{
-+ struct device_node *phy_node = NULL;
-+ int size;
-+ int phy_id = 0;
-+ const u32 *addr;
-+ int err;
-+
-+ addr = of_get_property(gem, "reg", &size);
-+ if (addr)
-+ port = be32_to_cpup(addr);
-+ else
-+ goto err;
-+
-+ pdata->ls1012a_eth_pdata[port].gem_id = port;
-+
-+ err = of_get_mac_address(gem, pdata->ls1012a_eth_pdata[port].mac_addr);
-+
-+ phy_node = of_parse_phandle(gem, "phy-handle", 0);
-+ pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
-+ if (phy_node) {
-+ pfe_use_old_dts_phy = false;
-+ goto process_phynode;
-+ } else if (of_phy_is_fixed_link(gem)) {
-+ pfe_use_old_dts_phy = false;
-+ if (of_phy_register_fixed_link(gem) < 0) {
-+ pr_err("broken fixed-link specification\n");
-+ goto err;
-+ }
-+ phy_node = of_node_get(gem);
-+ pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
-+ } else if (of_get_property(gem, "fsl,pfe-phy-if-flags", &size)) {
-+ pfe_use_old_dts_phy = true;
-+ /* Use old dts properties for phy handling */
-+ addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size);
-+ pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr);
-+
-+ addr = of_get_property(gem, "fsl,gemac-phy-id", &size);
-+ if (!addr) {
-+ pr_err("%s:%d Invalid gemac-phy-id....\n", __func__,
-+ __LINE__);
-+ } else {
-+ phy_id = be32_to_cpup(addr);
-+ pdata->ls1012a_eth_pdata[port].phy_id = phy_id;
-+ pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id);
-+ }
-+
-+ /* If PHY is enabled, read mdio properties */
-+ if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
-+ goto done;
-+
-+ } else {
-+ pr_info("%s: No PHY or fixed-link\n", __func__);
-+ return 0;
-+ }
-+
-+process_phynode:
-+ err = of_get_phy_mode(gem, &pdata->ls1012a_eth_pdata[port].mii_config);
-+ if (err)
-+ pr_err("%s:%d Incorrect Phy mode....\n", __func__,
-+ __LINE__);
-+
-+ addr = of_get_property(gem, "fsl,mdio-mux-val", &size);
-+ if (!addr) {
-+ pr_err("%s: Invalid mdio-mux-val....\n", __func__);
-+ } else {
-+ phy_id = be32_to_cpup(addr);
-+ pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
-+ }
-+
-+ if (pdata->ls1012a_eth_pdata[port].phy_id < 32)
-+ pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] =
-+ pdata->ls1012a_eth_pdata[port].mdio_muxval;
-+
-+
-+ pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL;
-+
-+done:
-+ return 0;
-+
-+err:
-+ return -1;
-+}
-+
-+/*
-+ *
-+ * pfe_platform_probe -
-+ *
-+ *
-+ */
-+static int pfe_platform_probe(struct platform_device *pdev)
-+{
-+ struct resource res;
-+ int ii = 0, rc, interface_count = 0, size = 0;
-+ const u32 *prop;
-+ struct device_node *np, *gem = NULL;
-+ struct clk *pfe_clk;
-+
-+ np = pdev->dev.of_node;
-+
-+ if (!np) {
-+ pr_err("Invalid device node\n");
-+ return -EINVAL;
-+ }
-+
-+ pfe = kzalloc(sizeof(*pfe), GFP_KERNEL);
-+ if (!pfe) {
-+ rc = -ENOMEM;
-+ goto err_alloc;
-+ }
-+
-+ platform_set_drvdata(pdev, pfe);
-+
-+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
-+ rc = -ENOMEM;
-+ pr_err("unable to configure DMA mask.\n");
-+ goto err_ddr;
-+ }
-+
-+ if (of_address_to_resource(np, 1, &res)) {
-+ rc = -ENOMEM;
-+ pr_err("failed to get ddr resource\n");
-+ goto err_ddr;
-+ }
-+
-+ pfe->ddr_phys_baseaddr = res.start;
-+ pfe->ddr_size = resource_size(&res);
-+
-+ pfe->ddr_baseaddr = memremap(res.start, resource_size(&res),
-+ MEMREMAP_WB);
-+ if (!pfe->ddr_baseaddr) {
-+ pr_err("memremap() ddr failed\n");
-+ rc = -ENOMEM;
-+ goto err_ddr;
-+ }
-+
-+ pfe->scfg =
-+ syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+ "fsl,pfe-scfg");
-+ if (IS_ERR(pfe->scfg)) {
-+ dev_err(&pdev->dev, "No syscfg phandle specified\n");
-+ return PTR_ERR(pfe->scfg);
-+ }
-+
-+ pfe->cbus_baseaddr = of_iomap(np, 0);
-+ if (!pfe->cbus_baseaddr) {
-+ rc = -ENOMEM;
-+ pr_err("failed to get axi resource\n");
-+ goto err_axi;
-+ }
-+
-+ pfe->hif_irq = platform_get_irq(pdev, 0);
-+ if (pfe->hif_irq < 0) {
-+ pr_err("platform_get_irq for hif failed\n");
-+ rc = pfe->hif_irq;
-+ goto err_hif_irq;
-+ }
-+
-+ pfe->wol_irq = platform_get_irq(pdev, 2);
-+ if (pfe->wol_irq < 0) {
-+ pr_err("platform_get_irq for WoL failed\n");
-+ rc = pfe->wol_irq;
-+ goto err_hif_irq;
-+ }
-+
-+ /* Read interface count */
-+ prop = of_get_property(np, "fsl,pfe-num-interfaces", &size);
-+ if (!prop) {
-+ pr_err("Failed to read number of interfaces\n");
-+ rc = -ENXIO;
-+ goto err_prop;
-+ }
-+
-+ interface_count = be32_to_cpup(prop);
-+ if (interface_count <= 0) {
-+ pr_err("No ethernet interface count : %d\n",
-+ interface_count);
-+ rc = -ENXIO;
-+ goto err_prop;
-+ }
-+
-+ pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
-+
-+ while ((gem = of_get_next_child(np, gem))) {
-+ if (of_find_property(gem, "reg", &size)) {
-+ pfe_get_gemac_if_properties(gem, ii,
-+ &pfe_platform_data);
-+ ii++;
-+ }
-+ }
-+
-+ if (interface_count != ii)
-+ pr_info("missing some of gemac interface properties.\n");
-+
-+ pfe->dev = &pdev->dev;
-+
-+ pfe->dev->platform_data = &pfe_platform_data;
-+
-+ /* declare WoL capabilities */
-+ device_init_wakeup(&pdev->dev, true);
-+
-+ /* find the clocks */
-+ pfe_clk = devm_clk_get(pfe->dev, "pfe");
-+ if (IS_ERR(pfe_clk))
-+ return PTR_ERR(pfe_clk);
-+
-+ /* PFE clock is (platform clock / 2) */
-+ /* save sys_clk value as KHz */
-+ pfe->ctrl.sys_clk = clk_get_rate(pfe_clk) / (2 * 1000);
-+
-+ rc = pfe_probe(pfe);
-+ if (rc < 0)
-+ goto err_probe;
-+
-+ return 0;
-+
-+err_probe:
-+err_prop:
-+err_hif_irq:
-+ iounmap(pfe->cbus_baseaddr);
-+
-+err_axi:
-+ memunmap(pfe->ddr_baseaddr);
-+
-+err_ddr:
-+ platform_set_drvdata(pdev, NULL);
-+
-+ kfree(pfe);
-+
-+err_alloc:
-+ return rc;
-+}
-+
-+/*
-+ * pfe_platform_remove -
-+ */
-+static int pfe_platform_remove(struct platform_device *pdev)
-+{
-+ struct pfe *pfe = platform_get_drvdata(pdev);
-+ int rc;
-+
-+ pr_info("%s\n", __func__);
-+
-+ rc = pfe_remove(pfe);
-+
-+ iounmap(pfe->cbus_baseaddr);
-+
-+ memunmap(pfe->ddr_baseaddr);
-+
-+ platform_set_drvdata(pdev, NULL);
-+
-+ kfree(pfe);
-+
-+ return rc;
-+}
-+
-+#ifdef CONFIG_PM
-+#ifdef CONFIG_PM_SLEEP
-+int pfe_platform_suspend(struct device *dev)
-+{
-+ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
-+ struct net_device *netdev;
-+ int i;
-+
-+ pfe->wake = 0;
-+
-+ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
-+ netdev = pfe->eth.eth_priv[i]->ndev;
-+
-+ netif_device_detach(netdev);
-+
-+ if (netif_running(netdev))
-+ if (pfe_eth_suspend(netdev))
-+ pfe->wake = 1;
-+ }
-+
-+ /* Shutdown PFE only if we're not waking up the system */
-+ if (!pfe->wake) {
-+#if defined(LS1012A_PFE_RESET_WA)
-+ pfe_hif_rx_idle(&pfe->hif);
-+#endif
-+ pfe_ctrl_suspend(&pfe->ctrl);
-+ pfe_firmware_exit(pfe);
-+
-+ pfe_hif_exit(pfe);
-+ pfe_hif_lib_exit(pfe);
-+
-+ pfe_hw_exit(pfe);
-+ }
-+
-+ return 0;
-+}
-+
-+static int pfe_platform_resume(struct device *dev)
-+{
-+ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
-+ struct net_device *netdev;
-+ int i;
-+
-+ if (!pfe->wake) {
-+ pfe_hw_init(pfe, 1);
-+ pfe_hif_lib_init(pfe);
-+ pfe_hif_init(pfe);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ util_enable();
-+#endif
-+ tmu_enable(0xf);
-+ class_enable();
-+ pfe_ctrl_resume(&pfe->ctrl);
-+ }
-+
-+ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
-+ netdev = pfe->eth.eth_priv[i]->ndev;
-+
-+ if (pfe->mdio.mdio_priv[i]->mii_bus)
-+ pfe_eth_mdio_reset(pfe->mdio.mdio_priv[i]->mii_bus);
-+
-+ if (netif_running(netdev))
-+ pfe_eth_resume(netdev);
-+
-+ netif_device_attach(netdev);
-+ }
-+ return 0;
-+}
-+#else
-+#define pfe_platform_suspend NULL
-+#define pfe_platform_resume NULL
-+#endif
-+
-+static const struct dev_pm_ops pfe_platform_pm_ops = {
-+ SET_SYSTEM_SLEEP_PM_OPS(pfe_platform_suspend, pfe_platform_resume)
-+};
-+#endif
-+
-+static const struct of_device_id pfe_match[] = {
-+ {
-+ .compatible = "fsl,pfe",
-+ },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, pfe_match);
-+
-+static struct platform_driver pfe_platform_driver = {
-+ .probe = pfe_platform_probe,
-+ .remove = pfe_platform_remove,
-+ .driver = {
-+ .name = "pfe",
-+ .of_match_table = pfe_match,
-+#ifdef CONFIG_PM
-+ .pm = &pfe_platform_pm_ops,
-+#endif
-+ },
-+};
-+
-+module_platform_driver(pfe_platform_driver);
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("PFE Ethernet driver");
-+MODULE_AUTHOR("NXP DNCPE");
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_mod.c
-@@ -0,0 +1,158 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/dma-mapping.h>
-+#include "pfe_mod.h"
-+#include "pfe_cdev.h"
-+
-+unsigned int us;
-+module_param(us, uint, 0444);
-+MODULE_PARM_DESC(us, "0: module enabled for kernel networking (DEFAULT)\n"
-+ "1: module enabled for userspace networking\n");
-+struct pfe *pfe;
-+
-+/*
-+ * pfe_probe -
-+ */
-+int pfe_probe(struct pfe *pfe)
-+{
-+ int rc;
-+
-+ if (pfe->ddr_size < DDR_MAX_SIZE) {
-+ pr_err("%s: required DDR memory (%x) above platform ddr memory (%x)\n",
-+ __func__, (unsigned int)DDR_MAX_SIZE, pfe->ddr_size);
-+ rc = -ENOMEM;
-+ goto err_hw;
-+ }
-+
-+ if (((int)(pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR) &
-+ (8 * SZ_1M - 1)) != 0) {
-+ pr_err("%s: BMU2 base address (0x%x) must be aligned on 8MB boundary\n",
-+ __func__, (int)pfe->ddr_phys_baseaddr +
-+ BMU2_DDR_BASEADDR);
-+ rc = -ENOMEM;
-+ goto err_hw;
-+ }
-+
-+ pr_info("cbus_baseaddr: %lx, ddr_baseaddr: %lx, ddr_phys_baseaddr: %lx, ddr_size: %x\n",
-+ (unsigned long)pfe->cbus_baseaddr,
-+ (unsigned long)pfe->ddr_baseaddr,
-+ pfe->ddr_phys_baseaddr, pfe->ddr_size);
-+
-+ pfe_lib_init(pfe->cbus_baseaddr, pfe->ddr_baseaddr,
-+ pfe->ddr_phys_baseaddr, pfe->ddr_size);
-+
-+ rc = pfe_hw_init(pfe, 0);
-+ if (rc < 0)
-+ goto err_hw;
-+
-+ if (us)
-+ goto firmware_init;
-+
-+ rc = pfe_hif_lib_init(pfe);
-+ if (rc < 0)
-+ goto err_hif_lib;
-+
-+ rc = pfe_hif_init(pfe);
-+ if (rc < 0)
-+ goto err_hif;
-+
-+firmware_init:
-+ rc = pfe_firmware_init(pfe);
-+ if (rc < 0)
-+ goto err_firmware;
-+
-+ rc = pfe_ctrl_init(pfe);
-+ if (rc < 0)
-+ goto err_ctrl;
-+
-+ rc = pfe_eth_init(pfe);
-+ if (rc < 0)
-+ goto err_eth;
-+
-+ rc = pfe_sysfs_init(pfe);
-+ if (rc < 0)
-+ goto err_sysfs;
-+
-+ rc = pfe_debugfs_init(pfe);
-+ if (rc < 0)
-+ goto err_debugfs;
-+
-+ if (us) {
-+ /* Creating a character device */
-+ rc = pfe_cdev_init();
-+ if (rc < 0)
-+ goto err_cdev;
-+ }
-+
-+ return 0;
-+
-+err_cdev:
-+ pfe_debugfs_exit(pfe);
-+
-+err_debugfs:
-+ pfe_sysfs_exit(pfe);
-+
-+err_sysfs:
-+ pfe_eth_exit(pfe);
-+
-+err_eth:
-+ pfe_ctrl_exit(pfe);
-+
-+err_ctrl:
-+ pfe_firmware_exit(pfe);
-+
-+err_firmware:
-+ if (us)
-+ goto err_hif_lib;
-+
-+ pfe_hif_exit(pfe);
-+
-+err_hif:
-+ pfe_hif_lib_exit(pfe);
-+
-+err_hif_lib:
-+ pfe_hw_exit(pfe);
-+
-+err_hw:
-+ return rc;
-+}
-+
-+/*
-+ * pfe_remove -
-+ */
-+int pfe_remove(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ if (us)
-+ pfe_cdev_exit();
-+
-+ pfe_debugfs_exit(pfe);
-+
-+ pfe_sysfs_exit(pfe);
-+
-+ pfe_eth_exit(pfe);
-+
-+ pfe_ctrl_exit(pfe);
-+
-+#if defined(LS1012A_PFE_RESET_WA)
-+ pfe_hif_rx_idle(&pfe->hif);
-+#endif
-+ pfe_firmware_exit(pfe);
-+
-+ if (us)
-+ goto hw_exit;
-+
-+ pfe_hif_exit(pfe);
-+
-+ pfe_hif_lib_exit(pfe);
-+
-+hw_exit:
-+ pfe_hw_exit(pfe);
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_mod.h
-@@ -0,0 +1,103 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_MOD_H_
-+#define _PFE_MOD_H_
-+
-+#include <linux/device.h>
-+#include <linux/elf.h>
-+
-+extern unsigned int us;
-+
-+struct pfe;
-+
-+#include "pfe_hw.h"
-+#include "pfe_firmware.h"
-+#include "pfe_ctrl.h"
-+#include "pfe_hif.h"
-+#include "pfe_hif_lib.h"
-+#include "pfe_eth.h"
-+#include "pfe_sysfs.h"
-+#include "pfe_perfmon.h"
-+#include "pfe_debugfs.h"
-+
-+#define PHYID_MAX_VAL 32
-+
-+struct pfe_tmu_credit {
-+ /* Number of allowed TX packet in-flight, matches TMU queue size */
-+ unsigned int tx_credit[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
-+ unsigned int tx_credit_max[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
-+ unsigned int tx_packets[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
-+};
-+
-+struct pfe {
-+ struct regmap *scfg;
-+ unsigned long ddr_phys_baseaddr;
-+ void *ddr_baseaddr;
-+ unsigned int ddr_size;
-+ void *cbus_baseaddr;
-+ void *apb_baseaddr;
-+ unsigned long iram_phys_baseaddr;
-+ void *iram_baseaddr;
-+ unsigned long ipsec_phys_baseaddr;
-+ void *ipsec_baseaddr;
-+ int hif_irq;
-+ int wol_irq;
-+ int hif_client_irq;
-+ struct device *dev;
-+ struct dentry *dentry;
-+ struct pfe_ctrl ctrl;
-+ struct pfe_hif hif;
-+ struct pfe_eth eth;
-+ struct pfe_mdio mdio;
-+ struct hif_client_s *hif_client[HIF_CLIENTS_MAX];
-+#if defined(CFG_DIAGS)
-+ struct pfe_diags diags;
-+#endif
-+ struct pfe_tmu_credit tmu_credit;
-+ struct pfe_cpumon cpumon;
-+ struct pfe_memmon memmon;
-+ int wake;
-+ int mdio_muxval[PHYID_MAX_VAL];
-+ struct clk *hfe_clock;
-+};
-+
-+extern struct pfe *pfe;
-+
-+int pfe_probe(struct pfe *pfe);
-+int pfe_remove(struct pfe *pfe);
-+
-+/* DDR Mapping in reserved memory*/
-+#define ROUTE_TABLE_BASEADDR 0
-+#define ROUTE_TABLE_HASH_BITS 15 /* 32K entries */
-+#define ROUTE_TABLE_SIZE ((1 << ROUTE_TABLE_HASH_BITS) \
-+ * CLASS_ROUTE_SIZE)
-+#define BMU2_DDR_BASEADDR (ROUTE_TABLE_BASEADDR + ROUTE_TABLE_SIZE)
-+#define BMU2_BUF_COUNT (4096 - 256)
-+/* This is to get a total DDR size of 12MiB */
-+#define BMU2_DDR_SIZE (DDR_BUF_SIZE * BMU2_BUF_COUNT)
-+#define UTIL_CODE_BASEADDR (BMU2_DDR_BASEADDR + BMU2_DDR_SIZE)
-+#define UTIL_CODE_SIZE (128 * SZ_1K)
-+#define UTIL_DDR_DATA_BASEADDR (UTIL_CODE_BASEADDR + UTIL_CODE_SIZE)
-+#define UTIL_DDR_DATA_SIZE (64 * SZ_1K)
-+#define CLASS_DDR_DATA_BASEADDR (UTIL_DDR_DATA_BASEADDR + UTIL_DDR_DATA_SIZE)
-+#define CLASS_DDR_DATA_SIZE (32 * SZ_1K)
-+#define TMU_DDR_DATA_BASEADDR (CLASS_DDR_DATA_BASEADDR + CLASS_DDR_DATA_SIZE)
-+#define TMU_DDR_DATA_SIZE (32 * SZ_1K)
-+#define TMU_LLM_BASEADDR (TMU_DDR_DATA_BASEADDR + TMU_DDR_DATA_SIZE)
-+#define TMU_LLM_QUEUE_LEN (8 * 512)
-+/* Must be power of two and at least 16 * 8 = 128 bytes */
-+#define TMU_LLM_SIZE (4 * 16 * TMU_LLM_QUEUE_LEN)
-+/* (4 TMU's x 16 queues x queue_len) */
-+
-+#define DDR_MAX_SIZE (TMU_LLM_BASEADDR + TMU_LLM_SIZE)
-+
-+/* LMEM Mapping */
-+#define BMU1_LMEM_BASEADDR 0
-+#define BMU1_BUF_COUNT 256
-+#define BMU1_LMEM_SIZE (LMEM_BUF_SIZE * BMU1_BUF_COUNT)
-+
-+#endif /* _PFE_MOD_H */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_perfmon.h
-@@ -0,0 +1,26 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_PERFMON_H_
-+#define _PFE_PERFMON_H_
-+
-+#include "pfe/pfe.h"
-+
-+#define CT_CPUMON_INTERVAL (1 * TIMER_TICKS_PER_SEC)
-+
-+struct pfe_cpumon {
-+ u32 cpu_usage_pct[MAX_PE];
-+ u32 class_usage_pct;
-+};
-+
-+struct pfe_memmon {
-+ u32 kernel_memory_allocated;
-+};
-+
-+int pfe_perfmon_init(struct pfe *pfe);
-+void pfe_perfmon_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_PERFMON_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
-@@ -0,0 +1,840 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+
-+#include "pfe_mod.h"
-+
-+#define PE_EXCEPTION_DUMP_ADDRESS 0x1fa8
-+#define NUM_QUEUES 16
-+
-+static char register_name[20][5] = {
-+ "EPC", "ECAS", "EID", "ED",
-+ "r0", "r1", "r2", "r3",
-+ "r4", "r5", "r6", "r7",
-+ "r8", "r9", "r10", "r11",
-+ "r12", "r13", "r14", "r15",
-+};
-+
-+static char exception_name[14][20] = {
-+ "Reset",
-+ "HardwareFailure",
-+ "NMI",
-+ "InstBreakpoint",
-+ "DataBreakpoint",
-+ "Unsupported",
-+ "PrivilegeViolation",
-+ "InstBusError",
-+ "DataBusError",
-+ "AlignmentError",
-+ "ArithmeticError",
-+ "SystemCall",
-+ "MemoryManagement",
-+ "Interrupt",
-+};
-+
-+static unsigned long class_do_clear;
-+static unsigned long tmu_do_clear;
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static unsigned long util_do_clear;
-+#endif
-+
-+static ssize_t display_pe_status(char *buf, int id, u32 dmem_addr, unsigned long
-+ do_clear)
-+{
-+ ssize_t len = 0;
-+ u32 val;
-+ char statebuf[5];
-+ struct pfe_cpumon *cpumon = &pfe->cpumon;
-+ u32 debug_indicator;
-+ u32 debug[20];
-+
-+ if (id < CLASS0_ID || id >= MAX_PE)
-+ return len;
-+
-+ *(u32 *)statebuf = pe_dmem_read(id, dmem_addr, 4);
-+ dmem_addr += 4;
-+
-+ statebuf[4] = '\0';
-+ len += sprintf(buf + len, "state=%4s ", statebuf);
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ dmem_addr += 4;
-+ len += sprintf(buf + len, "ctr=%08x ", cpu_to_be32(val));
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ if (do_clear && val)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ dmem_addr += 4;
-+ len += sprintf(buf + len, "rx=%u ", cpu_to_be32(val));
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ if (do_clear && val)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ dmem_addr += 4;
-+ if (id >= TMU0_ID && id <= TMU_MAX_ID)
-+ len += sprintf(buf + len, "qstatus=%x", cpu_to_be32(val));
-+ else
-+ len += sprintf(buf + len, "tx=%u", cpu_to_be32(val));
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ if (do_clear && val)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ dmem_addr += 4;
-+ if (val)
-+ len += sprintf(buf + len, " drop=%u", cpu_to_be32(val));
-+
-+ len += sprintf(buf + len, " load=%d%%", cpumon->cpu_usage_pct[id]);
-+
-+ len += sprintf(buf + len, "\n");
-+
-+ debug_indicator = pe_dmem_read(id, dmem_addr, 4);
-+ dmem_addr += 4;
-+ if (!strncmp((char *)&debug_indicator, "DBUG", 4)) {
-+ int j, last = 0;
-+
-+ for (j = 0; j < 16; j++) {
-+ debug[j] = pe_dmem_read(id, dmem_addr, 4);
-+ if (debug[j]) {
-+ if (do_clear)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ last = j + 1;
-+ }
-+ dmem_addr += 4;
-+ }
-+ for (j = 0; j < last; j++) {
-+ len += sprintf(buf + len, "%08x%s",
-+ cpu_to_be32(debug[j]),
-+ (j & 0x7) == 0x7 || j == last - 1 ? "\n" : " ");
-+ }
-+ }
-+
-+ if (!strncmp(statebuf, "DEAD", 4)) {
-+ u32 i, dump = PE_EXCEPTION_DUMP_ADDRESS;
-+
-+ len += sprintf(buf + len, "Exception details:\n");
-+ for (i = 0; i < 20; i++) {
-+ debug[i] = pe_dmem_read(id, dump, 4);
-+ dump += 4;
-+ if (i == 2)
-+ len += sprintf(buf + len, "%4s = %08x (=%s) ",
-+ register_name[i], cpu_to_be32(debug[i]),
-+ exception_name[min((u32)
-+ cpu_to_be32(debug[i]), (u32)13)]);
-+ else
-+ len += sprintf(buf + len, "%4s = %08x%s",
-+ register_name[i], cpu_to_be32(debug[i]),
-+ (i & 0x3) == 0x3 || i == 19 ? "\n" : " ");
-+ }
-+ }
-+
-+ return len;
-+}
-+
-+static ssize_t class_phy_stats(char *buf, int phy)
-+{
-+ ssize_t len = 0;
-+ int off1 = phy * 0x28;
-+ int off2 = phy * 0x10;
-+
-+ if (phy == 3)
-+ off1 = CLASS_PHY4_RX_PKTS - CLASS_PHY1_RX_PKTS;
-+
-+ len += sprintf(buf + len, "phy: %d\n", phy);
-+ len += sprintf(buf + len,
-+ " rx: %10u, tx: %10u, intf: %10u, ipv4: %10u, ipv6: %10u\n",
-+ readl(CLASS_PHY1_RX_PKTS + off1),
-+ readl(CLASS_PHY1_TX_PKTS + off1),
-+ readl(CLASS_PHY1_INTF_MATCH_PKTS + off1),
-+ readl(CLASS_PHY1_V4_PKTS + off1),
-+ readl(CLASS_PHY1_V6_PKTS + off1));
-+
-+ len += sprintf(buf + len,
-+ " icmp: %10u, igmp: %10u, tcp: %10u, udp: %10u\n",
-+ readl(CLASS_PHY1_ICMP_PKTS + off2),
-+ readl(CLASS_PHY1_IGMP_PKTS + off2),
-+ readl(CLASS_PHY1_TCP_PKTS + off2),
-+ readl(CLASS_PHY1_UDP_PKTS + off2));
-+
-+ len += sprintf(buf + len, " err\n");
-+ len += sprintf(buf + len,
-+ " lp: %10u, intf: %10u, l3: %10u, chcksum: %10u, ttl: %10u\n",
-+ readl(CLASS_PHY1_LP_FAIL_PKTS + off1),
-+ readl(CLASS_PHY1_INTF_FAIL_PKTS + off1),
-+ readl(CLASS_PHY1_L3_FAIL_PKTS + off1),
-+ readl(CLASS_PHY1_CHKSUM_ERR_PKTS + off1),
-+ readl(CLASS_PHY1_TTL_ERR_PKTS + off1));
-+
-+ return len;
-+}
-+
-+/* qm_read_drop_stat
-+ * This function is used to read the drop statistics from the TMU
-+ * hw drop counter. Since the hw counter is always cleared afer
-+ * reading, this function maintains the previous drop count, and
-+ * adds the new value to it. That value can be retrieved by
-+ * passing a pointer to it with the total_drops arg.
-+ *
-+ * @param tmu TMU number (0 - 3)
-+ * @param queue queue number (0 - 15)
-+ * @param total_drops pointer to location to store total drops (or NULL)
-+ * @param do_reset if TRUE, clear total drops after updating
-+ */
-+u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset)
-+{
-+ static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES];
-+ u32 val;
-+
-+ writel((tmu << 8) | queue, TMU_TEQ_CTRL);
-+ writel((tmu << 8) | queue, TMU_LLM_CTRL);
-+ val = readl(TMU_TEQ_DROP_STAT);
-+ qtotal[tmu][queue] += val;
-+ if (total_drops)
-+ *total_drops = qtotal[tmu][queue];
-+ if (do_reset)
-+ qtotal[tmu][queue] = 0;
-+ return val;
-+}
-+
-+static ssize_t tmu_queue_stats(char *buf, int tmu, int queue)
-+{
-+ ssize_t len = 0;
-+ u32 drops;
-+
-+ len += sprintf(buf + len, "%d-%02d, ", tmu, queue);
-+
-+ drops = qm_read_drop_stat(tmu, queue, NULL, 0);
-+
-+ /* Select queue */
-+ writel((tmu << 8) | queue, TMU_TEQ_CTRL);
-+ writel((tmu << 8) | queue, TMU_LLM_CTRL);
-+
-+ len += sprintf(buf + len,
-+ "(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n",
-+ drops, readl(TMU_TEQ_TRANS_STAT),
-+ readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR),
-+ readl(TMU_LLM_QUE_DROPCNT));
-+
-+ return len;
-+}
-+
-+static ssize_t tmu_queues(char *buf, int tmu)
-+{
-+ ssize_t len = 0;
-+ int queue;
-+
-+ for (queue = 0; queue < 16; queue++)
-+ len += tmu_queue_stats(buf + len, tmu, queue);
-+
-+ return len;
-+}
-+
-+static ssize_t block_version(char *buf, void *addr)
-+{
-+ ssize_t len = 0;
-+ u32 val;
-+
-+ val = readl(addr);
-+ len += sprintf(buf + len, "revision: %x, version: %x, id: %x\n",
-+ (val >> 24) & 0xff, (val >> 16) & 0xff, val & 0xffff);
-+
-+ return len;
-+}
-+
-+static ssize_t bmu(char *buf, int id, void *base)
-+{
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "%s: %d\n ", __func__, id);
-+
-+ len += block_version(buf + len, base + BMU_VERSION);
-+
-+ len += sprintf(buf + len, " buf size: %x\n", (1 << readl(base +
-+ BMU_BUF_SIZE)));
-+ len += sprintf(buf + len, " buf count: %x\n", readl(base +
-+ BMU_BUF_CNT));
-+ len += sprintf(buf + len, " buf rem: %x\n", readl(base +
-+ BMU_REM_BUF_CNT));
-+ len += sprintf(buf + len, " buf curr: %x\n", readl(base +
-+ BMU_CURR_BUF_CNT));
-+ len += sprintf(buf + len, " free err: %x\n", readl(base +
-+ BMU_FREE_ERR_ADDR));
-+
-+ return len;
-+}
-+
-+static ssize_t gpi(char *buf, int id, void *base)
-+{
-+ ssize_t len = 0;
-+ u32 val;
-+
-+ len += sprintf(buf + len, "%s%d:\n ", __func__, id);
-+ len += block_version(buf + len, base + GPI_VERSION);
-+
-+ len += sprintf(buf + len, " tx under stick: %x\n", readl(base +
-+ GPI_FIFO_STATUS));
-+ val = readl(base + GPI_FIFO_DEBUG);
-+ len += sprintf(buf + len, " tx pkts: %x\n", (val >> 23) &
-+ 0x3f);
-+ len += sprintf(buf + len, " rx pkts: %x\n", (val >> 18) &
-+ 0x3f);
-+ len += sprintf(buf + len, " tx bytes: %x\n", (val >> 9) &
-+ 0x1ff);
-+ len += sprintf(buf + len, " rx bytes: %x\n", (val >> 0) &
-+ 0x1ff);
-+ len += sprintf(buf + len, " overrun: %x\n", readl(base +
-+ GPI_OVERRUN_DROPCNT));
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_set_class(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ class_do_clear = kstrtoul(buf, 0, 0);
-+ return count;
-+}
-+
-+static ssize_t pfe_show_class(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ int id;
-+ u32 val;
-+ struct pfe_cpumon *cpumon = &pfe->cpumon;
-+
-+ len += block_version(buf + len, CLASS_VERSION);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ len += sprintf(buf + len, "%d: ", id - CLASS0_ID);
-+
-+ val = readl(CLASS_PE0_DEBUG + id * 4);
-+ len += sprintf(buf + len, "pc=1%04x ", val & 0xffff);
-+
-+ len += display_pe_status(buf + len, id, CLASS_DM_PESTATUS,
-+ class_do_clear);
-+ }
-+ len += sprintf(buf + len, "aggregate load=%d%%\n\n",
-+ cpumon->class_usage_pct);
-+
-+ len += sprintf(buf + len, "pe status: 0x%x\n",
-+ readl(CLASS_PE_STATUS));
-+ len += sprintf(buf + len, "max buf cnt: 0x%x afull thres: 0x%x\n",
-+ readl(CLASS_MAX_BUF_CNT), readl(CLASS_AFULL_THRES));
-+ len += sprintf(buf + len, "tsq max cnt: 0x%x tsq fifo thres: 0x%x\n",
-+ readl(CLASS_TSQ_MAX_CNT), readl(CLASS_TSQ_FIFO_THRES));
-+ len += sprintf(buf + len, "state: 0x%x\n", readl(CLASS_STATE));
-+
-+ len += class_phy_stats(buf + len, 0);
-+ len += class_phy_stats(buf + len, 1);
-+ len += class_phy_stats(buf + len, 2);
-+ len += class_phy_stats(buf + len, 3);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_set_tmu(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ tmu_do_clear = kstrtoul(buf, 0, 0);
-+ return count;
-+}
-+
-+static ssize_t pfe_show_tmu(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ int id;
-+ u32 val;
-+
-+ len += block_version(buf + len, TMU_VERSION);
-+
-+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
-+ if (id == TMU2_ID)
-+ continue;
-+ len += sprintf(buf + len, "%d: ", id - TMU0_ID);
-+
-+ len += display_pe_status(buf + len, id, TMU_DM_PESTATUS,
-+ tmu_do_clear);
-+ }
-+
-+ len += sprintf(buf + len, "pe status: %x\n", readl(TMU_PE_STATUS));
-+ len += sprintf(buf + len, "inq fifo cnt: %x\n",
-+ readl(TMU_PHY_INQ_FIFO_CNT));
-+ val = readl(TMU_INQ_STAT);
-+ len += sprintf(buf + len, "inq wr ptr: %x\n", val & 0x3ff);
-+ len += sprintf(buf + len, "inq rd ptr: %x\n", val >> 10);
-+
-+ return len;
-+}
-+
-+static unsigned long drops_do_clear;
-+static u32 class_drop_counter[CLASS_NUM_DROP_COUNTERS];
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static u32 util_drop_counter[UTIL_NUM_DROP_COUNTERS];
-+#endif
-+
-+char *class_drop_description[CLASS_NUM_DROP_COUNTERS] = {
-+ "ICC",
-+ "Host Pkt Error",
-+ "Rx Error",
-+ "IPsec Outbound",
-+ "IPsec Inbound",
-+ "EXPT IPsec Error",
-+ "Reassembly",
-+ "Fragmenter",
-+ "NAT-T",
-+ "Socket",
-+ "Multicast",
-+ "NAT-PT",
-+ "Tx Disabled",
-+};
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+char *util_drop_description[UTIL_NUM_DROP_COUNTERS] = {
-+ "IPsec Outbound",
-+ "IPsec Inbound",
-+ "IPsec Rate Limiter",
-+ "Fragmenter",
-+ "Socket",
-+ "Tx Disabled",
-+ "Rx Error",
-+};
-+#endif
-+
-+static ssize_t pfe_set_drops(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ drops_do_clear = kstrtoul(buf, 0, 0);
-+ return count;
-+}
-+
-+static u32 tmu_drops[4][16];
-+static ssize_t pfe_show_drops(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ int id, dropnum;
-+ int tmu, queue;
-+ u32 val;
-+ u32 dmem_addr;
-+ int num_class_drops = 0, num_tmu_drops = 0, num_util_drops = 0;
-+ struct pfe_ctrl *ctrl = &pfe->ctrl;
-+
-+ memset(class_drop_counter, 0, sizeof(class_drop_counter));
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ if (drops_do_clear)
-+ pe_sync_stop(ctrl, (1 << id));
-+ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS;
-+ dropnum++) {
-+ dmem_addr = CLASS_DM_DROP_CNTR;
-+ val = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4));
-+ class_drop_counter[dropnum] += val;
-+ num_class_drops += val;
-+ if (drops_do_clear)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ }
-+ if (drops_do_clear)
-+ pe_start(ctrl, (1 << id));
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (drops_do_clear)
-+ pe_sync_stop(ctrl, (1 << UTIL_ID));
-+ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) {
-+ dmem_addr = UTIL_DM_DROP_CNTR;
-+ val = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr, 4));
-+ util_drop_counter[dropnum] = val;
-+ num_util_drops += val;
-+ if (drops_do_clear)
-+ pe_dmem_write(UTIL_ID, 0, dmem_addr, 4);
-+ }
-+ if (drops_do_clear)
-+ pe_start(ctrl, (1 << UTIL_ID));
-+#endif
-+ for (tmu = 0; tmu < 4; tmu++) {
-+ for (queue = 0; queue < 16; queue++) {
-+ qm_read_drop_stat(tmu, queue, &tmu_drops[tmu][queue],
-+ drops_do_clear);
-+ num_tmu_drops += tmu_drops[tmu][queue];
-+ }
-+ }
-+
-+ if (num_class_drops == 0 && num_util_drops == 0 && num_tmu_drops == 0)
-+ len += sprintf(buf + len, "No PE drops\n\n");
-+
-+ if (num_class_drops > 0) {
-+ len += sprintf(buf + len, "Class PE drops --\n");
-+ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS;
-+ dropnum++) {
-+ if (class_drop_counter[dropnum] > 0)
-+ len += sprintf(buf + len, " %s: %d\n",
-+ class_drop_description[dropnum],
-+ class_drop_counter[dropnum]);
-+ }
-+ len += sprintf(buf + len, "\n");
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (num_util_drops > 0) {
-+ len += sprintf(buf + len, "Util PE drops --\n");
-+ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) {
-+ if (util_drop_counter[dropnum] > 0)
-+ len += sprintf(buf + len, " %s: %d\n",
-+ util_drop_description[dropnum],
-+ util_drop_counter[dropnum]);
-+ }
-+ len += sprintf(buf + len, "\n");
-+ }
-+#endif
-+ if (num_tmu_drops > 0) {
-+ len += sprintf(buf + len, "TMU drops --\n");
-+ for (tmu = 0; tmu < 4; tmu++) {
-+ for (queue = 0; queue < 16; queue++) {
-+ if (tmu_drops[tmu][queue] > 0)
-+ len += sprintf(buf + len,
-+ " TMU%d-Q%d: %d\n"
-+ , tmu, queue, tmu_drops[tmu][queue]);
-+ }
-+ }
-+ len += sprintf(buf + len, "\n");
-+ }
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_tmu0_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 0);
-+}
-+
-+static ssize_t pfe_show_tmu1_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 1);
-+}
-+
-+static ssize_t pfe_show_tmu2_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 2);
-+}
-+
-+static ssize_t pfe_show_tmu3_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 3);
-+}
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ util_do_clear = kstrtoul(buf, NULL, 0);
-+ return count;
-+}
-+
-+static ssize_t pfe_show_util(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ struct pfe_ctrl *ctrl = &pfe->ctrl;
-+
-+ len += block_version(buf + len, UTIL_VERSION);
-+
-+ pe_sync_stop(ctrl, (1 << UTIL_ID));
-+ len += display_pe_status(buf + len, UTIL_ID, UTIL_DM_PESTATUS,
-+ util_do_clear);
-+ pe_start(ctrl, (1 << UTIL_ID));
-+
-+ len += sprintf(buf + len, "pe status: %x\n", readl(UTIL_PE_STATUS));
-+ len += sprintf(buf + len, "max buf cnt: %x\n",
-+ readl(UTIL_MAX_BUF_CNT));
-+ len += sprintf(buf + len, "tsq max cnt: %x\n",
-+ readl(UTIL_TSQ_MAX_CNT));
-+
-+ return len;
-+}
-+#endif
-+
-+static ssize_t pfe_show_bmu(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+
-+ len += bmu(buf + len, 1, BMU1_BASE_ADDR);
-+ len += bmu(buf + len, 2, BMU2_BASE_ADDR);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_hif(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "hif:\n ");
-+ len += block_version(buf + len, HIF_VERSION);
-+
-+ len += sprintf(buf + len, " tx curr bd: %x\n",
-+ readl(HIF_TX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " tx status: %x\n",
-+ readl(HIF_TX_STATUS));
-+ len += sprintf(buf + len, " tx dma status: %x\n",
-+ readl(HIF_TX_DMA_STATUS));
-+
-+ len += sprintf(buf + len, " rx curr bd: %x\n",
-+ readl(HIF_RX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " rx status: %x\n",
-+ readl(HIF_RX_STATUS));
-+ len += sprintf(buf + len, " rx dma status: %x\n",
-+ readl(HIF_RX_DMA_STATUS));
-+
-+ len += sprintf(buf + len, "hif nocopy:\n ");
-+ len += block_version(buf + len, HIF_NOCPY_VERSION);
-+
-+ len += sprintf(buf + len, " tx curr bd: %x\n",
-+ readl(HIF_NOCPY_TX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " tx status: %x\n",
-+ readl(HIF_NOCPY_TX_STATUS));
-+ len += sprintf(buf + len, " tx dma status: %x\n",
-+ readl(HIF_NOCPY_TX_DMA_STATUS));
-+
-+ len += sprintf(buf + len, " rx curr bd: %x\n",
-+ readl(HIF_NOCPY_RX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " rx status: %x\n",
-+ readl(HIF_NOCPY_RX_STATUS));
-+ len += sprintf(buf + len, " rx dma status: %x\n",
-+ readl(HIF_NOCPY_RX_DMA_STATUS));
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_gpi(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+
-+ len += gpi(buf + len, 0, EGPI1_BASE_ADDR);
-+ len += gpi(buf + len, 1, EGPI2_BASE_ADDR);
-+ len += gpi(buf + len, 3, HGPI_BASE_ADDR);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_pfemem(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ ssize_t len = 0;
-+ struct pfe_memmon *memmon = &pfe->memmon;
-+
-+ len += sprintf(buf + len, "Kernel Memory: %d Bytes (%d KB)\n",
-+ memmon->kernel_memory_allocated,
-+ (memmon->kernel_memory_allocated + 1023) / 1024);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_crc_revalidated(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ u64 crc_validated = 0;
-+ ssize_t len = 0;
-+ int id, phyid;
-+
-+ len += sprintf(buf + len, "FCS re-validated by PFE:\n");
-+
-+ for (phyid = 0; phyid < 2; phyid++) {
-+ crc_validated = 0;
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ crc_validated += be32_to_cpu(pe_dmem_read(id,
-+ CLASS_DM_CRC_VALIDATED + (phyid * 4), 4));
-+ }
-+ len += sprintf(buf + len, "MAC %d:\n count:%10llu\n",
-+ phyid, crc_validated);
-+ }
-+
-+ return len;
-+}
-+
-+#ifdef HIF_NAPI_STATS
-+static ssize_t pfe_show_hif_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct pfe *pfe = platform_get_drvdata(pdev);
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "sched: %u\n",
-+ pfe->hif.napi_counters[NAPI_SCHED_COUNT]);
-+ len += sprintf(buf + len, "poll: %u\n",
-+ pfe->hif.napi_counters[NAPI_POLL_COUNT]);
-+ len += sprintf(buf + len, "packet: %u\n",
-+ pfe->hif.napi_counters[NAPI_PACKET_COUNT]);
-+ len += sprintf(buf + len, "budget: %u\n",
-+ pfe->hif.napi_counters[NAPI_FULL_BUDGET_COUNT]);
-+ len += sprintf(buf + len, "desc: %u\n",
-+ pfe->hif.napi_counters[NAPI_DESC_COUNT]);
-+ len += sprintf(buf + len, "full: %u\n",
-+ pfe->hif.napi_counters[NAPI_CLIENT_FULL_COUNT]);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_set_hif_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct pfe *pfe = platform_get_drvdata(pdev);
-+
-+ memset(pfe->hif.napi_counters, 0, sizeof(pfe->hif.napi_counters));
-+
-+ return count;
-+}
-+
-+static DEVICE_ATTR(hif_napi_stats, 0644, pfe_show_hif_napi_stats,
-+ pfe_set_hif_napi_stats);
-+#endif
-+
-+static DEVICE_ATTR(class, 0644, pfe_show_class, pfe_set_class);
-+static DEVICE_ATTR(tmu, 0644, pfe_show_tmu, pfe_set_tmu);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static DEVICE_ATTR(util, 0644, pfe_show_util, pfe_set_util);
-+#endif
-+static DEVICE_ATTR(bmu, 0444, pfe_show_bmu, NULL);
-+static DEVICE_ATTR(hif, 0444, pfe_show_hif, NULL);
-+static DEVICE_ATTR(gpi, 0444, pfe_show_gpi, NULL);
-+static DEVICE_ATTR(drops, 0644, pfe_show_drops, pfe_set_drops);
-+static DEVICE_ATTR(tmu0_queues, 0444, pfe_show_tmu0_queues, NULL);
-+static DEVICE_ATTR(tmu1_queues, 0444, pfe_show_tmu1_queues, NULL);
-+static DEVICE_ATTR(tmu2_queues, 0444, pfe_show_tmu2_queues, NULL);
-+static DEVICE_ATTR(tmu3_queues, 0444, pfe_show_tmu3_queues, NULL);
-+static DEVICE_ATTR(pfemem, 0444, pfe_show_pfemem, NULL);
-+static DEVICE_ATTR(fcs_revalidated, 0444, pfe_show_crc_revalidated, NULL);
-+
-+int pfe_sysfs_init(struct pfe *pfe)
-+{
-+ if (device_create_file(pfe->dev, &dev_attr_class))
-+ goto err_class;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu))
-+ goto err_tmu;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (device_create_file(pfe->dev, &dev_attr_util))
-+ goto err_util;
-+#endif
-+
-+ if (device_create_file(pfe->dev, &dev_attr_bmu))
-+ goto err_bmu;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_hif))
-+ goto err_hif;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_gpi))
-+ goto err_gpi;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_drops))
-+ goto err_drops;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu0_queues))
-+ goto err_tmu0_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu1_queues))
-+ goto err_tmu1_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu2_queues))
-+ goto err_tmu2_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu3_queues))
-+ goto err_tmu3_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_pfemem))
-+ goto err_pfemem;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_fcs_revalidated))
-+ goto err_crc_revalidated;
-+
-+#ifdef HIF_NAPI_STATS
-+ if (device_create_file(pfe->dev, &dev_attr_hif_napi_stats))
-+ goto err_hif_napi_stats;
-+#endif
-+
-+ return 0;
-+
-+#ifdef HIF_NAPI_STATS
-+err_hif_napi_stats:
-+ device_remove_file(pfe->dev, &dev_attr_fcs_revalidated);
-+#endif
-+
-+err_crc_revalidated:
-+ device_remove_file(pfe->dev, &dev_attr_pfemem);
-+
-+err_pfemem:
-+ device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
-+
-+err_tmu3_queues:
-+ device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
-+
-+err_tmu2_queues:
-+ device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
-+
-+err_tmu1_queues:
-+ device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
-+
-+err_tmu0_queues:
-+ device_remove_file(pfe->dev, &dev_attr_drops);
-+
-+err_drops:
-+ device_remove_file(pfe->dev, &dev_attr_gpi);
-+
-+err_gpi:
-+ device_remove_file(pfe->dev, &dev_attr_hif);
-+
-+err_hif:
-+ device_remove_file(pfe->dev, &dev_attr_bmu);
-+
-+err_bmu:
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ device_remove_file(pfe->dev, &dev_attr_util);
-+
-+err_util:
-+#endif
-+ device_remove_file(pfe->dev, &dev_attr_tmu);
-+
-+err_tmu:
-+ device_remove_file(pfe->dev, &dev_attr_class);
-+
-+err_class:
-+ return -1;
-+}
-+
-+void pfe_sysfs_exit(struct pfe *pfe)
-+{
-+#ifdef HIF_NAPI_STATS
-+ device_remove_file(pfe->dev, &dev_attr_hif_napi_stats);
-+#endif
-+ device_remove_file(pfe->dev, &dev_attr_fcs_revalidated);
-+ device_remove_file(pfe->dev, &dev_attr_pfemem);
-+ device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
-+ device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
-+ device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
-+ device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
-+ device_remove_file(pfe->dev, &dev_attr_drops);
-+ device_remove_file(pfe->dev, &dev_attr_gpi);
-+ device_remove_file(pfe->dev, &dev_attr_hif);
-+ device_remove_file(pfe->dev, &dev_attr_bmu);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ device_remove_file(pfe->dev, &dev_attr_util);
-+#endif
-+ device_remove_file(pfe->dev, &dev_attr_tmu);
-+ device_remove_file(pfe->dev, &dev_attr_class);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_SYSFS_H_
-+#define _PFE_SYSFS_H_
-+
-+#include <linux/proc_fs.h>
-+
-+u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset);
-+
-+int pfe_sysfs_init(struct pfe *pfe);
-+void pfe_sysfs_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_SYSFS_H_ */
diff --git a/target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch b/target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch
deleted file mode 100644
index c125d293d7..0000000000
--- a/target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From fd32b1bc9a49919d3d59a50d775d03fe7ca5e654 Mon Sep 17 00:00:00 2001
-From: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
-Date: Wed, 29 Nov 2017 15:27:57 +0530
-Subject: [PATCH] phy: Add 2.5G SGMII interface mode
-
-Add 2.5G SGMII interface mode(PHY_INTERFACE_MODE_2500SGMII)
-in existing phy_interface list
-
-Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
----
- drivers/net/phy/phy-core.c | 1 +
- drivers/net/phy/phylink.c | 1 +
- include/linux/phy.h | 3 +++
- 3 files changed, 5 insertions(+)
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -136,6 +136,7 @@ int phy_interface_num_ports(phy_interfac
- case PHY_INTERFACE_MODE_RXAUI:
- case PHY_INTERFACE_MODE_XAUI:
- case PHY_INTERFACE_MODE_1000BASEKX:
-+ case PHY_INTERFACE_MODE_2500SGMII:
- return 1;
- case PHY_INTERFACE_MODE_QSGMII:
- case PHY_INTERFACE_MODE_QUSGMII:
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -231,6 +231,7 @@ static int phylink_interface_max_speed(p
- return SPEED_1000;
-
- case PHY_INTERFACE_MODE_2500BASEX:
-+ case PHY_INTERFACE_MODE_2500SGMII:
- return SPEED_2500;
-
- case PHY_INTERFACE_MODE_5GBASER:
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -159,6 +159,7 @@ typedef enum {
- PHY_INTERFACE_MODE_10GKR,
- PHY_INTERFACE_MODE_QUSGMII,
- PHY_INTERFACE_MODE_1000BASEKX,
-+ PHY_INTERFACE_MODE_2500SGMII,
- PHY_INTERFACE_MODE_MAX,
- } phy_interface_t;
-
-@@ -280,6 +281,8 @@ static inline const char *phy_modes(phy_
- return "100base-x";
- case PHY_INTERFACE_MODE_QUSGMII:
- return "qusgmii";
-+ case PHY_INTERFACE_MODE_2500SGMII:
-+ return "sgmii-2500";
- default:
- return "unknown";
- }
diff --git a/target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch b/target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch
deleted file mode 100644
index d49488ab4c..0000000000
--- a/target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch
+++ /dev/null
@@ -1,239 +0,0 @@
-From 1dc3a2e216d99adc2df022ab37eab32f61d80e0e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 8 May 2023 19:26:48 +0200
-Subject: [PATCH] layerscape: 6.1: fix compilation warning for fsl ppfe driver
-
-Rework some desc dump and dummy pkt function to fix compilation warning.
-Fix compilation warning:
-drivers/staging/fsl_ppfe/pfe_hif.c: In function 'send_dummy_pkt_to_hif':
-drivers/staging/fsl_ppfe/pfe_hif.c:118:19: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
- 118 | ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:122:20: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
- 122 | lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c: In function 'pfe_hif_desc_dump':
-drivers/staging/fsl_ppfe/pfe_hif.c:195:24: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 195 | desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:195:36: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 195 | desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:207:19: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 207 | desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:207:31: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 207 | desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-cc1: all warnings being treated as errors
-
-In file included from ./include/linux/kernel.h:19,
- from ./include/linux/list.h:9,
- from ./include/linux/wait.h:7,
- from ./include/linux/eventfd.h:13,
- from drivers/staging/fsl_ppfe/pfe_cdev.c:11:
-drivers/staging/fsl_ppfe/pfe_cdev.c: In function 'pfe_cdev_read':
-./include/linux/kern_levels.h:5:25: error: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'int' [-Werror=format=]
- 5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
- | ^~~~~~
-./include/linux/printk.h:422:25: note: in definition of macro 'printk_index_wrap'
- 422 | _p_func(_fmt, ##__VA_ARGS__); \
- | ^~~~
-./include/linux/printk.h:132:17: note: in expansion of macro 'printk'
- 132 | printk(fmt, ##__VA_ARGS__); \
- | ^~~~~~
-./include/linux/printk.h:580:9: note: in expansion of macro 'no_printk'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~
-./include/linux/kern_levels.h:15:25: note: in expansion of macro 'KERN_SOH'
- 15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
- | ^~~~~~~~
-./include/linux/printk.h:580:19: note: in expansion of macro 'KERN_DEBUG'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~~
-drivers/staging/fsl_ppfe/pfe_cdev.c:42:17: note: in expansion of macro 'pr_debug'
- 42 | pr_debug("%u %lu", link_states[ret].phy_id,
- | ^~~~~~~~
-./include/linux/kern_levels.h:5:25: error: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
- 5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
- | ^~~~~~
-./include/linux/printk.h:422:25: note: in definition of macro 'printk_index_wrap'
- 422 | _p_func(_fmt, ##__VA_ARGS__); \
- | ^~~~
-./include/linux/printk.h:493:9: note: in expansion of macro 'printk'
- 493 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~
-./include/linux/kern_levels.h:11:25: note: in expansion of macro 'KERN_SOH'
- 11 | #define KERN_ERR KERN_SOH "3" /* error conditions */
- | ^~~~~~~~
-./include/linux/printk.h:493:16: note: in expansion of macro 'KERN_ERR'
- 493 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~
-drivers/staging/fsl_ppfe/pfe_cdev.c:50:17: note: in expansion of macro 'pr_err'
- 50 | pr_err("Failed to send (%d)bytes of (%lu) requested.\n",
- | ^~~~~~
-./include/linux/kern_levels.h:5:25: error: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'unsigned int' [-Werror=format=]
- 5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
- | ^~~~~~
-./include/linux/printk.h:422:25: note: in definition of macro 'printk_index_wrap'
- 422 | _p_func(_fmt, ##__VA_ARGS__); \
- | ^~~~
-./include/linux/printk.h:132:17: note: in expansion of macro 'printk'
- 132 | printk(fmt, ##__VA_ARGS__); \
- | ^~~~~~
-./include/linux/printk.h:580:9: note: in expansion of macro 'no_printk'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~
-./include/linux/kern_levels.h:15:25: note: in expansion of macro 'KERN_SOH'
- 15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
- | ^~~~~~~~
-./include/linux/printk.h:580:19: note: in expansion of macro 'KERN_DEBUG'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~~
-drivers/staging/fsl_ppfe/pfe_cdev.c:57:9: note: in expansion of macro 'pr_debug'
- 57 | pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states));
- | ^~~~~~~~
-cc1: all warnings being treated as errors
-
-In file included from ./include/uapi/linux/posix_types.h:5,
- from ./include/uapi/linux/types.h:14,
- from ./include/linux/types.h:6,
- from ./include/linux/list.h:5,
- from ./include/linux/module.h:12,
- from drivers/staging/fsl_ppfe/pfe_sysfs.c:7:
-drivers/staging/fsl_ppfe/pfe_sysfs.c: In function 'pfe_set_util':
-./include/linux/stddef.h:8:14: error: passing argument 2 of 'kstrtoul' makes integer from pointer without a cast [-Werror=int-conversion]
- 8 | #define NULL ((void *)0)
- | ^~~~~~~~~~~
- | |
- | void *
-drivers/staging/fsl_ppfe/pfe_sysfs.c:538:39: note: in expansion of macro 'NULL'
- 538 | util_do_clear = kstrtoul(buf, NULL, 0);
- | ^~~~
-In file included from ./include/linux/kernel.h:13,
- from ./include/linux/list.h:9:
-./include/linux/kstrtox.h:30:69: note: expected 'unsigned int' but argument is of type 'void *'
- 30 | static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res)
- | ~~~~~~~~~~~~~^~~~
-cc1: all warnings being treated as errors
-
-With UTIL compiled on, fix compilation warning:
-drivers/staging/fsl_ppfe/pfe_hal.c: In function 'pe_load_ddr_section':
-drivers/staging/fsl_ppfe/pfe_hal.c:617:19: error: 'else' without a previous 'if'
- 617 | } else {
- | ^~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:622:17: error: break statement not within loop or switch
- 622 | break;
- | ^~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:624:9: error: case label not within a switch statement
- 624 | case SHT_NOBITS:
- | ^~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:627:17: error: break statement not within loop or switch
- 627 | break;
- | ^~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:629:9: error: 'default' label not within a switch statement
- 629 | default:
- | ^~~~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c: At top level:
-drivers/staging/fsl_ppfe/pfe_hal.c:635:9: error: expected identifier or '(' before 'return'
- 635 | return 0;
- | ^~~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:636:1: error: expected identifier or '(' before '}' token
- 636 | }
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- drivers/staging/fsl_ppfe/pfe_cdev.c | 6 +++---
- drivers/staging/fsl_ppfe/pfe_hif.c | 14 +++++++-------
- drivers/staging/fsl_ppfe/pfe_sysfs.c | 2 +-
- 3 files changed, 11 insertions(+), 11 deletions(-)
-
---- a/drivers/staging/fsl_ppfe/pfe_cdev.c
-+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c
-@@ -34,7 +34,7 @@ static ssize_t pfe_cdev_read(struct file
- {
- int ret = 0;
-
-- pr_info("PFE CDEV attempt copying (%lu) size of user.\n",
-+ pr_info("PFE CDEV attempt copying (%zu) size of user.\n",
- sizeof(link_states));
-
- pr_debug("Dump link_state on screen before copy_to_user\n");
-@@ -47,14 +47,14 @@ static ssize_t pfe_cdev_read(struct file
- /* Copy to user the value in buffer sized len */
- ret = copy_to_user(buf, &link_states, sizeof(link_states));
- if (ret != 0) {
-- pr_err("Failed to send (%d)bytes of (%lu) requested.\n",
-+ pr_err("Failed to send (%d)bytes of (%zu) requested.\n",
- ret, len);
- return -EFAULT;
- }
-
- /* offset set back to 0 as there is contextual reading offset */
- *off = 0;
-- pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states));
-+ pr_debug("Read of (%zu) bytes performed.\n", sizeof(link_states));
-
- return sizeof(link_states);
- }
---- a/drivers/staging/fsl_ppfe/pfe_hif.c
-+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
-@@ -115,11 +115,11 @@ static void send_dummy_pkt_to_hif(void)
- 0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
-
-- ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
-+ ddr_ptr = (void *)((uintptr_t)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
- if (!ddr_ptr)
- return;
-
-- lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
-+ lmem_ptr = (void *)((uintptr_t)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
- if (!lmem_ptr)
- return;
-
-@@ -186,16 +186,16 @@ static void pfe_hif_free_descr(struct pf
- void pfe_hif_desc_dump(struct pfe_hif *hif)
- {
- struct hif_desc *desc;
-- unsigned long desc_p;
-+ u64 desc_p;
- int ii = 0;
-
- pr_info("%s\n", __func__);
-
- desc = hif->rx_base;
-- desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
-+ desc_p = ((void *)desc - hif->descr_baseaddr_v +
- hif->descr_baseaddr_p);
-
-- pr_info("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p);
-+ pr_info("HIF Rx desc base %p physical %llx\n", desc, desc_p);
- for (ii = 0; ii < hif->rx_ring_size; ii++) {
- pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
- readl(&desc->status), readl(&desc->ctrl),
-@@ -204,10 +204,10 @@ void pfe_hif_desc_dump(struct pfe_hif *h
- }
-
- desc = hif->tx_base;
-- desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
-+ desc_p = ((void *)desc - hif->descr_baseaddr_v +
- hif->descr_baseaddr_p);
-
-- pr_info("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p);
-+ pr_info("HIF Tx desc base %p physical %llx\n", desc, desc_p);
- for (ii = 0; ii < hif->tx_ring_size; ii++) {
- pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
- readl(&desc->status), readl(&desc->ctrl),
---- a/drivers/staging/fsl_ppfe/pfe_sysfs.c
-+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
-@@ -535,7 +535,7 @@ static ssize_t pfe_show_tmu3_queues(stru
- static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
-- util_do_clear = kstrtoul(buf, NULL, 0);
-+ util_do_clear = kstrtoul(buf, 0, 0);
- return count;
- }
-
diff --git a/target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch b/target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch
deleted file mode 100644
index ed7b2c2609..0000000000
--- a/target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From eb57941154e2ad142c07d47e874a221328467349 Mon Sep 17 00:00:00 2001
-From: Ioana Ciornei <ioana.ciornei@nxp.com>
-Date: Thu, 2 Jun 2022 12:11:11 +0300
-Subject: [PATCH] net: phylink: treat PHY_INTERFACE_MODE_2500SGMII in
- phylink_get_linkmodes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There is a downstream patch which adds a new interface type -
-PHY_INTERFACE_MODE_2500SGMII (which is really the same one as
-PHY_INTERFACE_MODE_2500BASEX).
-
-We backported from upstream the following phylink patch which, of
-course, does not treat the PHY_INTERFACE_MODE_2500SGMII interface mode
-in a switch case statement.
- 34ae2c09d46a ("net: phylink: add generic validate implementation")
-
-Because of this, we get the following build warning.
-
-drivers/net/phy/phylink.c: In function ‘phylink_get_linkmodes’:
-drivers/net/phy/phylink.c:322:2: warning: enumeration value ‘PHY_INTERFACE_MODE_2500SGMII’ not handled in switch [-Wswitch]
- 322 | switch (interface) {
- | ^~~~~~
-
-Fix it by treating the new interface mode in the switch-case statement.
-
-Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
----
- drivers/net/phy/phylink.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -518,6 +518,7 @@ unsigned long phylink_get_capabilities(p
- break;
-
- case PHY_INTERFACE_MODE_2500BASEX:
-+ case PHY_INTERFACE_MODE_2500SGMII:
- caps |= MAC_2500FD;
- break;
-
diff --git a/target/linux/loongarch64/config-6.6 b/target/linux/loongarch64/config-6.6
index 6f637a6f01..46a90c1284 100644
--- a/target/linux/loongarch64/config-6.6
+++ b/target/linux/loongarch64/config-6.6
@@ -234,8 +234,6 @@ CONFIG_ENCRYPTED_KEYS=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_FAILOVER=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_FANOTIFY=y
@@ -282,7 +280,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FREEZER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FW_CACHE=y
# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set
@@ -752,7 +749,6 @@ CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TMPFS_INODE64=y
-CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_TMPFS_QUOTA is not set
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
diff --git a/target/linux/malta/be64/target.mk b/target/linux/malta/be64/target.mk
index e992c2c698..7045d511bc 100644
--- a/target/linux/malta/be64/target.mk
+++ b/target/linux/malta/be64/target.mk
@@ -1,7 +1,6 @@
ARCH:=mips64
CPU_TYPE:=mips64r2
SUBTARGET:=be64
-FEATURES+=source-only
BOARDNAME:=Big Endian (64-bits)
define Target/Description
diff --git a/target/linux/malta/config-6.6 b/target/linux/malta/config-6.6
index 7c72f49265..73db6cea21 100644
--- a/target/linux/malta/config-6.6
+++ b/target/linux/malta/config-6.6
@@ -81,7 +81,6 @@ CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
@@ -131,8 +130,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_ISA_DMA_API=y
CONFIG_JBD2=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
CONFIG_KALLSYMS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
diff --git a/target/linux/malta/le/target.mk b/target/linux/malta/le/target.mk
index feb0f1d04c..f93ff78920 100644
--- a/target/linux/malta/le/target.mk
+++ b/target/linux/malta/le/target.mk
@@ -1,7 +1,6 @@
ARCH:=mipsel
CPU_TYPE:=24kc
SUBTARGET:=le
-FEATURES+=source-only
BOARDNAME:=Little Endian
define Target/Description
diff --git a/target/linux/malta/le64/target.mk b/target/linux/malta/le64/target.mk
index 59dcc86bef..098ab40c5c 100644
--- a/target/linux/malta/le64/target.mk
+++ b/target/linux/malta/le64/target.mk
@@ -1,7 +1,6 @@
ARCH:=mips64el
CPU_TYPE:=mips64r2
SUBTARGET:=le64
-FEATURES+=source-only
BOARDNAME:=Little Endian (64-bits)
define Target/Description
diff --git a/target/linux/mediatek/Makefile b/target/linux/mediatek/Makefile
index f667081253..478b00488b 100644
--- a/target/linux/mediatek/Makefile
+++ b/target/linux/mediatek/Makefile
@@ -4,8 +4,8 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=mediatek
-BOARDNAME:=MediaTek Ralink ARM
-SUBTARGETS:=mt7622 mt7623 mt7629 filogic
+BOARDNAME:=MediaTek ARM
+SUBTARGETS:=filogic mt7622 mt7623 mt7629
FEATURES:=dt-overlay emmc fpu gpio nand pci pcie rootfs-part separate_ramdisk squashfs usb
KERNEL_PATCHVER:=6.6
diff --git a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface
index 6dfa52c291..c982a8f1d8 100644
--- a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface
+++ b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface
@@ -6,6 +6,7 @@ set_preinit_iface() {
ip link set eth1 up
ifname=eth1
;;
+ cudy,ap3000outdoor-v1|\
cudy,re3000-v1|\
ubnt,unifi-6-lr|\
zyxel,nwa50ax-pro)
@@ -13,7 +14,8 @@ set_preinit_iface() {
ifname=eth0
;;
smartrg,sdg-8622|\
- smartrg,sdg-8632)
+ smartrg,sdg-8632|\
+ smartrg,sdg-8733a)
ip link set lan up
ifname=lan
;;
diff --git a/target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing b/target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing
new file mode 100644
index 0000000000..74458e075b
--- /dev/null
+++ b/target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+trigger_fip_scrubbing() {
+ local vol voltype volname
+ for vol in /sys/class/ubi/ubi*_*; do
+ [ -e "$vol" ] || continue
+ voltype="$(cat "$vol"/type)"
+ volname="$(cat "$vol"/name)"
+ if [ "$voltype" = "static" ] && [ "$volname" = "fip" ]; then
+ cat "/dev/${vol##*/}" > /dev/null
+ break
+ fi
+ done
+}
+
+boot_hook_add preinit_main trigger_fip_scrubbing
diff --git a/target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts b/target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts
new file mode 100644
index 0000000000..70b7cde6d9
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "mt7629.dtsi"
+
+/ {
+ model = "Linksys EA7500 v3";
+ compatible = "linksys,ea7500-v3", "mediatek,mt7629";
+
+ aliases {
+ led-boot = &led_power;
+ led-failsafe = &led_power;
+ led-running = &led_power;
+ led-upgrade = &led_power;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ bootargs-override = "console=ttyS0,115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power: power {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_WHITE>;
+ gpios = <&pio 52 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 58 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x40000000 0x10000000>;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_5v: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&eth {
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_pins>;
+ pinctrl-1 = <&ephy_leds_pins>;
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "gmii";
+ phy-handle = <&phy0>;
+ };
+
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ switch@1f {
+ compatible = "mediatek,mt7531";
+ reg = <31>;
+ reset-gpios = <&pio 28 0>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ };
+
+ port@6 {
+ reg = <6>;
+ ethernet = <&gmac0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+ };
+ };
+};
+
+&bch {
+ status = "okay";
+};
+
+&snfi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&serial_nand_pins>;
+ status = "okay";
+ flash@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ nand-ecc-engine = <&snfi>;
+ mediatek,bmt-v2;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Bootloader";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "Config";
+ reg = <0x100000 0x40000>;
+ };
+
+ partition@140000 {
+ label = "Factory";
+ reg = <0x140000 0x80000>;
+ read-only;
+ };
+
+ partition@1c0000 {
+ label = "kernel";
+ reg = <0x1c0000 0x800000>;
+ };
+
+ partition@9c0000 {
+ label = "ubi";
+ reg = <0x9c0000 0x2000000>;
+ };
+
+ partition@29c0000 {
+ label = "Kernel2";
+ reg = <0x29c0000 0x2800000>;
+ read-only;
+ };
+
+ partition@51c0000 {
+ label = "devinfo";
+ reg = <0x51c0000 0x40000>;
+ read-only;
+ };
+
+ partition@5200000 {
+ label = "sysdiag";
+ reg = <0x5200000 0x100000>;
+ read-only;
+ };
+
+ partition@5300000 {
+ label = "syscfg";
+ reg = <0x5300000 0x2000000>;
+ read-only;
+ };
+
+ partition@7300000 {
+ label = "s_env";
+ reg = <0x7300000 0x40000>;
+ };
+ };
+ };
+};
+
+&pio {
+ eth_pins: eth-pins {
+ mux {
+ function = "eth";
+ groups = "mdc_mdio";
+ };
+ };
+
+ ephy_leds_pins: ephy-leds-pins {
+ mux {
+ function = "led";
+ groups = "ephy_leds";
+ };
+ };
+
+ /* Serial NAND is shared pin with SPI-NOR */
+ serial_nand_pins: serial-nand-pins {
+ mux {
+ function = "flash";
+ groups = "snfi";
+ };
+ };
+
+ uart0_pins: uart0-pins {
+ mux {
+ function = "uart";
+ groups = "uart0_txd_rxd" ;
+ };
+ };
+
+ watchdog_pins: watchdog-pins {
+ mux {
+ function = "watchdog";
+ groups = "watchdog";
+ };
+ };
+};
+
+&ssusb {
+ vusb33-supply = <&reg_3p3v>;
+ vbus-supply = <&reg_5v>;
+ status = "okay";
+};
+
+&u3phy0 {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ pinctrl-names = "default";
+ pinctrl-0 = <&watchdog_pins>;
+ status = "okay";
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <GIC_SPI 0x80 IRQ_TYPE_EDGE_FALLING>;
+};
diff --git a/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts b/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts
index c306a5eb7b..0e7c4fe8b5 100644
--- a/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts
+++ b/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts
@@ -15,6 +15,7 @@
led-failsafe = &led_green;
led-running = &led_green;
led-upgrade = &led_green;
+ label-mac-device = &gmac1;
};
chosen {
diff --git a/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi b/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi
index e9050e02e5..919fb23c53 100644
--- a/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi
+++ b/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi
@@ -148,7 +148,7 @@
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts b/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts
new file mode 100644
index 0000000000..dd07def303
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "mt7981.dtsi"
+
+/ {
+ model = "ABT ASR3000";
+ compatible = "abt,asr3000", "mediatek,mt7981";
+
+ aliases {
+ led-boot = &mesh_led;
+ led-failsafe = &mesh_led;
+ led-upgrade = &mesh_led;
+ label-mac-device = &gmac1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ rootdisk = <&ubi_rootdisk>;
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x10000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ button-reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ };
+
+ button-mesh {
+ label = "mesh";
+ linux,code = <BTN_9>;
+ linux,input-type = <EV_SW>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&pio 4 GPIO_ACTIVE_LOW>;
+ };
+
+ led-1 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 8 GPIO_ACTIVE_LOW>;
+ };
+
+ mesh_led: led-2 {
+ label = "green:mesh";
+ gpios = <&pio 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-3 {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 34 GPIO_ACTIVE_LOW>;
+ };
+
+ led-4 {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 35 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&eth {
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+
+ nvmem-cells = <&macaddr_art_0 0>;
+ nvmem-cell-names = "mac-address";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "gmii";
+ phy-handle = <&int_gbe_phy>;
+
+ nvmem-cells = <&macaddr_art_0 0>;
+ nvmem-cell-names = "mac-address";
+ };
+};
+
+&mdio_bus {
+ switch: switch@1f {
+ compatible = "mediatek,mt7531";
+ reg = <31>;
+ reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
+
+&pio {
+ spi0_flash_pins: spi0-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <0>; /* bias-disable */
+ };
+
+ conf-pd {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <0>; /* bias-disable */
+ };
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+ status = "okay";
+
+ spi_nand: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-nand";
+ reg = <0>;
+
+ spi-max-frequency = <52000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot-env";
+ reg = <0x100000 0x80000>;
+ };
+
+ partition@180000 {
+ label = "art";
+ reg = <0x180000 0x100000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_art_0: macaddr@0 {
+ compatible = "mac-base";
+ reg = <0x0 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@280000 {
+ label = "factory";
+ reg = <0x280000 0x100000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+ };
+ };
+
+ partition@380000 {
+ label = "fip";
+ reg = <0x380000 0x200000>;
+ read-only;
+ };
+
+ partition@580000 {
+ compatible = "linux,ubi";
+ label = "ubi";
+ reg = <0x580000 0x7a80000>;
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
+ };
+ };
+ };
+};
+
+&switch {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan3";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan1";
+ };
+
+ port@6 {
+ reg = <6>;
+ ethernet = <&gmac0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi {
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ status = "okay";
+};
diff --git a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso
index c1c9c75c27..e6b140bfad 100644
--- a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso
+++ b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso
@@ -7,6 +7,29 @@
compatible = "cmcc,rax3000m", "mediatek,mt7981";
fragment@0 {
+ target = <&chosen>;
+ __overlay__ {
+ rootdisk = <&emmc_rootdisk>;
+ };
+ };
+
+ fragment@1 {
+ target = <&gmac0>;
+ __overlay__ {
+ nvmem-cells = <&macaddr_factory_2a 0>;
+ nvmem-cell-names = "mac-address";
+ };
+ };
+
+ fragment@2 {
+ target = <&gmac1>;
+ __overlay__ {
+ nvmem-cells = <&macaddr_factory_24 0>;
+ nvmem-cell-names = "mac-address";
+ };
+ };
+
+ fragment@3 {
target = <&mmc0>;
__overlay__ {
bus-width = <8>;
@@ -19,10 +42,51 @@
pinctrl-1 = <&mmc0_pins_uhs>;
vmmc-supply = <&reg_3p3v>;
status = "okay";
+
+ card@0 {
+ compatible = "mmc-card";
+ reg = <0>;
+
+ block {
+ compatible = "block-device";
+
+ partitions {
+ block-partition-factory {
+ partname = "factory";
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+
+ macaddr_factory_24: macaddr@24 {
+ compatible = "mac-base";
+ reg = <0x24 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_factory_2a: macaddr@2a {
+ compatible = "mac-base";
+ reg = <0x2a 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ emmc_rootdisk: block-partition-production {
+ partname = "production";
+ };
+ };
+ };
+ };
};
};
- fragment@1 {
+ fragment@4 {
target = <&pio>;
__overlay__ {
mmc0_pins_default: mmc0-pins {
@@ -40,4 +104,12 @@
};
};
};
+
+ fragment@5 {
+ target = <&wifi>;
+ __overlay__ {
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ };
+ };
};
diff --git a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso
index 4d2b01cb63..fded878332 100644
--- a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso
+++ b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso
@@ -7,6 +7,13 @@
compatible = "cmcc,rax3000m", "mediatek,mt7981";
fragment@0 {
+ target = <&chosen>;
+ __overlay__ {
+ rootdisk = <&ubi_rootdisk>;
+ };
+ };
+
+ fragment@1 {
target = <&gmac0>;
__overlay__ {
nvmem-cells = <&macaddr_factory_2a 0>;
@@ -14,7 +21,7 @@
};
};
- fragment@1 {
+ fragment@2 {
target = <&gmac1>;
__overlay__ {
nvmem-cells = <&macaddr_factory_24 0>;
@@ -22,7 +29,7 @@
};
};
- fragment@2 {
+ fragment@3 {
target = <&pio>;
__overlay__ {
spi0_flash_pins: spi0-pins {
@@ -46,7 +53,7 @@
};
};
- fragment@3 {
+ fragment@4 {
target = <&spi0>;
__overlay__ {
pinctrl-names = "default";
@@ -79,7 +86,7 @@
reg = <0x100000 0x80000>;
};
- factory: partition@180000 {
+ partition@180000 {
label = "factory";
reg = <0x180000 0x200000>;
read-only;
@@ -89,6 +96,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+
macaddr_factory_24: macaddr@24 {
compatible = "mac-base";
reg = <0x24 0x6>;
@@ -110,18 +121,26 @@
};
partition@580000 {
+ compatible = "linux,ubi";
label = "ubi";
reg = <0x580000 0x7200000>;
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
};
};
- fragment@4 {
+ fragment@5 {
target = <&wifi>;
__overlay__ {
- mediatek,mtd-eeprom = <&factory 0x0>;
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
};
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts
index c8db5b58f5..977a613333 100644
--- a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts
+++ b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts
@@ -22,7 +22,8 @@
serial0 = &uart0;
};
- chosen {
+ chosen: chosen {
+ bootargs-override = "root=/dev/fit0 rootwait";
stdout-path = "serial0:115200n8";
};
diff --git a/target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts b/target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts
new file mode 100644
index 0000000000..62e4063947
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+
+#include "mt7981.dtsi"
+
+/ {
+ model = "Cudy AP3000 Outdoor v1";
+ compatible = "cudy,ap3000outdoor-v1", "mediatek,mt7981-spim-snand-rfb";
+
+ aliases {
+ label-mac-device = &gmac1;
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_red;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_green: led@0 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_status_red: led_1 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&pio 11 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ gpio_export {
+ compatible = "gpio-export";
+ #size-cells = <0>;
+
+ antctrl {
+ /* Not sure if this pin does anything.
+ * It was taken from GPL sources.
+ * Intermediate image doesn't have it.
+ */
+ gpio-export,name = "antctrl";
+ gpio-export,output = <1>;
+ gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ watchdog-hw {
+ compatible = "linux,wdt-gpio";
+ gpios = <&pio 6 GPIO_ACTIVE_HIGH>;
+ hw_algo = "level";
+ hw_margin_ms = <10000>;
+ always-running;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&eth {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ status = "okay";
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "gmii";
+ phy-handle = <&int_gbe_phy>;
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_bdinfo_de00 1>;
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+ status = "okay";
+
+ spi_nand: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+
+ spi-cal-enable;
+ spi-cal-mode = "read-data";
+ spi-cal-datalen = <7>;
+ spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4E 0x41 0x4E 0x44>;
+ spi-cal-addrlen = <5>;
+ spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>;
+
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ mediatek,nmbm;
+ mediatek,bmt-max-ratio = <1>;
+ mediatek,bmt-max-reserved-blocks = <64>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "BL2";
+ reg = <0x00000 0x0100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot-env";
+ reg = <0x0100000 0x0080000>;
+ read-only;
+ };
+
+ factory: partition@180000 {
+ label = "Factory";
+ reg = <0x180000 0x0200000>;
+ read-only;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+ };
+ };
+
+ partition@380000 {
+ label = "bdinfo";
+ reg = <0x380000 0x0040000>;
+ read-only;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_bdinfo_de00: macaddr@de00 {
+ compatible = "mac-base";
+ reg = <0xde00 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+
+ };
+
+ partition@3C0000 {
+ label = "FIP";
+ reg = <0x3C0000 0x0200000>;
+ read-only;
+ };
+
+ partition@580000 {
+ label = "ubi";
+ reg = <0x5C0000 0x4000000>;
+ compatible = "linux,ubi";
+ };
+ };
+ };
+};
+
+
+&pio {
+ spi0_flash_pins: spi0-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+};
diff --git a/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts b/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts
index 15818a90fc..0bd3ac0a29 100644
--- a/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts
+++ b/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts
@@ -164,7 +164,7 @@
block-partition-u-boot-env {
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts b/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts
index 030cc25041..c405ce977e 100644
--- a/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts
+++ b/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts
@@ -20,6 +20,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -141,6 +143,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x4000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
/* yaffs partition */
diff --git a/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts b/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts
index c8b9aeba42..e866799ebc 100644
--- a/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts
+++ b/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts
@@ -21,6 +21,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -146,6 +148,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x7000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-openwrt-one.dts b/target/linux/mediatek/dts/mt7981b-openwrt-one.dts
index b2223f8d76..46d351f76d 100644
--- a/target/linux/mediatek/dts/mt7981b-openwrt-one.dts
+++ b/target/linux/mediatek/dts/mt7981b-openwrt-one.dts
@@ -8,13 +8,13 @@
compatible = "openwrt,one", "mediatek,mt7981";
aliases {
- ethernet0 = &gmac0;
- ethernet1 = &gmac1;
- serial0 = &uart0;
+ ethernet0 = &gmac1;
+ label-mac-device = &gmac0;
led-boot = &led_status_white;
led-failsafe = &led_status_red;
led-running = &led_status_green;
led-upgrade = &led_status_green;
+ serial0 = &uart0;
};
chosen {
@@ -140,7 +140,7 @@
phy-handle = <&phy15>;
phy-mode = "2500base-x";
nvmem-cell-names = "mac-address";
- nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cells = <&macaddr_factory_24>;
};
gmac1: mac@1 {
@@ -148,8 +148,6 @@
reg = <1>;
phy-mode = "gmii";
phy-handle = <&int_gbe_phy>;
- nvmem-cell-names = "mac-address";
- nvmem-cells = <&macaddr_factory_a>;
};
};
@@ -331,7 +329,7 @@
partition@580000 {
label = "ubi";
- reg = <0x100000 0x7F00000>;
+ reg = <0x100000 0xFF00000>;
compatible = "linux,ubi";
volumes {
@@ -388,15 +386,14 @@
};
macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
compatible = "mac-base";
- reg = <0x24 0x6>;
#nvmem-cell-cells = <1>;
};
- macaddr_factory_a: macaddr@a {
+ macaddr_factory_24: macaddr@24 {
+ reg = <0x24 0x6>;
compatible = "mac-base";
- reg = <0x2a 0x6>;
- #nvmem-cell-cells = <1>;
};
};
};
@@ -444,6 +441,18 @@
nvmem-cells = <&eeprom_factory_0>;
nvmem-cell-names = "eeprom";
status = "okay";
+
+ band@0 {
+ reg = <0>;
+ nvmem-cells = <&macaddr_factory_4 0>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ band@1 {
+ reg = <1>;
+ nvmem-cells = <&macaddr_factory_4 1>;
+ nvmem-cell-names = "mac-address";
+ };
};
&pcie {
diff --git a/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts b/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts
index 3925f80ba3..f167600f30 100644
--- a/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts
+++ b/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts
@@ -20,6 +20,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -134,6 +136,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x6c00000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
partition@7180000 {
diff --git a/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts b/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts
index abd4d4e59d..264c985612 100644
--- a/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts
+++ b/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts
@@ -32,7 +32,7 @@
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts
index 809e625ce1..7466b8f7c6 100644
--- a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts
+++ b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts
@@ -6,11 +6,23 @@
/ {
model = "Xiaomi Mi Router AX3000T (OpenWrt U-Boot layout)";
compatible = "xiaomi,mi-router-ax3000t-ubootmod", "mediatek,mt7981";
+
+ chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ };
};
&partitions {
partition@600000 {
label = "ubi";
reg = <0x600000 0x7000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts
index 6d0f3feb45..b22bbed379 100644
--- a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts
+++ b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts
@@ -6,11 +6,23 @@
/ {
model = "Xiaomi Mi Router WR30U (OpenWrt U-Boot layout)";
compatible = "xiaomi,mi-router-wr30u-ubootmod", "mediatek,mt7981";
+
+ chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ };
};
&partitions {
partition@600000 {
label = "ubi";
reg = <0x600000 0x7000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts b/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts
index 54df8c054a..95247eba9d 100644
--- a/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts
+++ b/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts
@@ -4,7 +4,7 @@
#include "mt7981.dtsi"
/ {
- model = "ZyXEL NWA50AX Pro";
+ model = "Zyxel NWA50AX Pro";
compatible = "zyxel,nwa50ax-pro", "mediatek,mt7981";
aliases {
diff --git a/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts b/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts
index fd0e1a6915..fe55f2ea3a 100644
--- a/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts
+++ b/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts
@@ -325,7 +325,7 @@
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
diff --git a/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts b/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts
index 372d4ec22a..7461cdd49b 100644
--- a/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts
+++ b/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts
@@ -133,8 +133,8 @@
reg = <6>;
reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>;
- reset-assert-us = <10000>;
- reset-deassert-us = <50000>;
+ reset-assert-us = <15000>;
+ reset-deassert-us = <68000>;
realtek,aldps-enable;
};
diff --git a/target/linux/mediatek/dts/mt7986a-netcore-n60.dts b/target/linux/mediatek/dts/mt7986a-netcore-n60.dts
index b96b1e2ec0..2c129acbba 100644
--- a/target/linux/mediatek/dts/mt7986a-netcore-n60.dts
+++ b/target/linux/mediatek/dts/mt7986a-netcore-n60.dts
@@ -21,6 +21,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -206,6 +208,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x7280000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
diff --git a/target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts b/target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts
new file mode 100644
index 0000000000..1b26b25f49
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "mt7986a.dtsi"
+
+/ {
+ model = "TP-Link TL-XTR8488";
+ compatible = "tplink,tl-xtr8488", "mediatek,mt7986a";
+
+ aliases {
+ serial0 = &uart0;
+ label-mac-device = &gmac0;
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_red;
+ };
+
+ chosen {
+ bootargs = "root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_5v: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 15 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 16 GPIO_ACTIVE_LOW>;
+ };
+
+ turbo {
+ label = "turbo";
+ linux,code = <BTN_1>;
+ gpios = <&pio 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_red: status-red {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_status_green: status-green {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&pio 8 GPIO_ACTIVE_HIGH>;
+ };
+
+ turbo {
+ label = "green:turbo";
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 12 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&crypto {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+
+ nvmem-cells = <&macaddr_config_1c 0>;
+ nvmem-cell-names = "mac-address";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-handle = <&phy7>;
+ phy-mode = "2500base-x";
+
+ nvmem-cells = <&macaddr_config_1c 1>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
+
+&mdio {
+ phy5: phy@5 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <5>;
+ realtek,aldps-enable;
+ };
+
+ phy7: phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <7>;
+ realtek,aldps-enable;
+ };
+
+ switch: switch@1f {
+ compatible = "mediatek,mt7531";
+ reg = <31>;
+ reset-gpios = <&pio 6 GPIO_ACTIVE_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
+
+&switch {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "lan5";
+ phy-handle = <&phy5>;
+ phy-mode = "2500base-x";
+ };
+
+ port@6 {
+ reg = <6>;
+ ethernet = <&gmac0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "spi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+
+ spi-max-frequency = <20000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x000000 0x0100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "config";
+ reg = <0x100000 0x0040000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_config_1c: macaddr@1c {
+ compatible = "mac-base";
+ reg = <0x1c 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@140000 {
+ label = "factory";
+ reg = <0x140000 0x0040000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+
+ eeprom_factory_1000: eeprom@1000 {
+ reg = <0x1000 0xe00>;
+ };
+ };
+ };
+
+ partition@180000 {
+ label = "reserved";
+ reg = <0x180000 0x0200000>;
+ read-only;
+ };
+
+ partition@380000 {
+ label = "fip";
+ reg = <0x380000 0x0200000>;
+ read-only;
+ };
+
+ partition@580000 {
+ compatible = "linux,ubi";
+ reg = <0x580000 0x7800000>;
+ label = "ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pins>;
+ status = "okay";
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ ieee80211-freq-limit = <5470000 5875000>;
+
+ nvmem-cells = <&eeprom_factory_1000>, <&macaddr_config_1c 3>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ };
+ };
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+&pio {
+ pcie_pins: pcie-pins {
+ mux {
+ function = "pcie";
+ groups = "pcie_clk", "pcie_wake", "pcie_pereset";
+ };
+ };
+
+ spi_flash_pins: spi-flash-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <0>; /* bias-disable */
+ };
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <8>;
+ mediatek,pull-down-adv = <0>; /* bias-disable */
+ };
+ };
+
+ wf_2g_5g_pins: wf_2g_5g-pins {
+ mux {
+ function = "wifi";
+ groups = "wf_2g", "wf_5g";
+ };
+ conf {
+ pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+ "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+ "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+ "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+ "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+ "WF1_TOP_CLK", "WF1_TOP_DATA";
+ drive-strength = <4>;
+ };
+ };
+};
+
+&ssusb {
+ vusb33-supply = <&reg_3p3v>;
+ vbus-supply = <&reg_5v>;
+ status = "okay";
+};
+
+&trng {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wf_2g_5g_pins>;
+ ieee80211-freq-limit = <2400000 2500000>, <5170000 5350000>;
+ nvmem-cells = <&eeprom_factory_0>, <&macaddr_config_1c 2>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ status = "okay";
+};
diff --git a/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts b/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts
index 62ce50ed23..d562243970 100644
--- a/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts
+++ b/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts
@@ -13,10 +13,16 @@
/ {
model = "Zyxel EX5601-T0 ubootmod";
compatible = "zyxel,ex5601-t0-ubootmod", "mediatek,mt7986a";
+
memory@40000000 {
device_type = "memory";
reg = <0x40000000 0x20000000>;
};
+
+ chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ };
};
&nand_partitions {
@@ -72,16 +78,23 @@
reg = <0x380000 0x0200000>;
read-only;
};
-
+
partition@540000 {
label = "zloader";
reg = <0x540000 0x0040000>;
read-only;
};
-
+
partition@580000 {
label = "ubi";
reg = <0x580000 0x1da80000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
diff --git a/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts b/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts
index 29961e528c..51147c1d81 100644
--- a/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts
+++ b/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts
@@ -8,7 +8,7 @@
#include "mt7986a.dtsi"
/ {
- model = "ZyXEL EX5700 (Telenor)";
+ model = "Zyxel EX5700 (Telenor)";
compatible = "zyxel,ex5700-telenor", "mediatek,mt7986a";
aliases {
@@ -158,11 +158,13 @@
phy5: phy@5 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <5>;
+ mxl,led-config = <0x3f0 0x330 0x0 0x0>;
};
phy6: phy@6 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <6>;
+ mxl,led-config = <0x3f0 0x330 0x0 0x0>;
};
switch: switch@1f {
diff --git a/target/linux/mediatek/dts/mt7986b-tplink-re6000xd.dts b/target/linux/mediatek/dts/mt7986b-tplink-re6000xd.dts
new file mode 100644
index 0000000000..44a5e21e7c
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7986b-tplink-re6000xd.dts
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: (GL-2.0 OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+#include "mt7986b.dtsi"
+
+/ {
+ compatible = "tplink,re6000xd", "mediatek,mt7986b";
+ model = "TP-Link RE6000XD";
+
+ aliases {
+ serial0 = &uart0;
+
+ led-boot = &led_status_blue;
+ led-failsafe = &led_status_blue;
+ led-running = &led_status_blue;
+ led-upgrade = &led_status_blue;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0 0x40000000 0 0x20000000>;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_blue: power {
+ gpios = <&pio 15 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ panic-indicator;
+ function-enumerator = <0>;
+ };
+ wlan_2g {
+ gpios = <&pio 11 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ linux,default-trigger = "phy0tpt";
+ };
+ wlan_5g {
+ gpios = <&pio 12 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ linux,default-trigger = "phy1tpt";
+ };
+ signal_blue {
+ gpios = <&pio 9 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ function-enumerator = <1>;
+ };
+ signal_red {
+ gpios = <&pio 19 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ function-enumerator = <2>;
+ };
+ lan1 {
+ gpios = <&pio 16 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <0>;
+ };
+ lan2 {
+ gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ };
+ lan3 {
+ gpios = <&pio 18 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <2>;
+ };
+ };
+};
+
+&crypto {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-handle = <&phy6>;
+ phy-mode = "2500base-x";
+ };
+
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
+
+&mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1500000>;
+ reset-post-delay-us = <1000000>;
+
+ /* LAN3 2.5Gbps phy
+ MaxLinear GPY211C0VC (SLNW8) */
+ phy6: phy@6 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <6>;
+ };
+
+ switch: switch@1f {
+ compatible = "mediatek,mt7531";
+ reg = <31>;
+ reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&switch {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* reorder LAN1 and LAN2 port to match the port order of the case
+ LAN1 - LAN2 - LAN3 (top to bottom of the case, no silkscreen)
+ */
+ /* LAN2 port */
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ /* LAN1 port */
+ port@2 {
+ reg = <2>;
+ label = "lan1";
+ };
+
+ port@6 {
+ reg = <6>;
+ ethernet = <&gmac0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+};
+
+&pio {
+ spi_flash_pins: spi-flash-pins-33-to-38 {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <0>; /* bias-disable */
+ };
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <8>;
+ mediatek,pull-down-adv = <0>; /* bias-disable */
+ };
+ };
+
+ wf_2g_5g_pins: wf_2g_5g-pins {
+ mux {
+ function = "wifi";
+ groups = "wf_2g", "wf_5g";
+ };
+ conf {
+ pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+ "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+ "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+ "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+ "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+ "WF1_TOP_CLK", "WF1_TOP_DATA";
+ drive-strength = <4>;
+ };
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+
+ spi_nand_flash: flash@0 {
+ compatible = "spi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+
+ spi-max-frequency = <20000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions: partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "boot";
+ reg = <0x0 0x200000>;
+ read-only;
+ };
+
+ partition@200000 {
+ label = "u-boot-env";
+ reg = <0x200000 0x100000>;
+ };
+
+ partition@300000 {
+ label = "ubi0";
+ reg = <0x300000 0x3200000>;
+ };
+
+ partition@3500000 {
+ label = "ubi1";
+ reg = <0x3500000 0x3200000>;
+ read-only;
+ };
+
+ partition@6700000 {
+ label = "userconfig";
+ reg = <0x6700000 0x800000>;
+ read-only;
+ };
+
+ partition@6f00000 {
+ label = "tp_data";
+ reg = <0x6f00000 0x400000>;
+ read-only;
+ };
+ };
+ };
+};
+
+&trng {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wf_2g_5g_pins>;
+};
diff --git a/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi b/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi
index 2b468f9bb3..93bbd0103b 100644
--- a/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi
+++ b/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi
@@ -451,19 +451,19 @@
#address-cells = <1>;
#size-cells = <0>;
- led@0 {
+ aqr_green_led: led@0 {
reg = <0>;
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
};
- led@1 {
+ aqr_orange_led: led@1 {
reg = <1>;
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_ORANGE>;
};
- led@2 {
+ aqr_white_led: led@2 {
reg = <2>;
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_WHITE>;
@@ -481,8 +481,6 @@
max-frequency = <200000000>;
cap-mmc-highspeed;
mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- hs400-ds-delay = <0x12814>;
vmmc-supply = <&reg_3p3v>;
vqmmc-supply = <&reg_1p8v>;
non-removable;
diff --git a/target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts b/target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts
new file mode 100644
index 0000000000..54fbbea0ba
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2024 SmartRG Inc.
+ * Author: Chad Monroe <chad.monroe@smartrg.com>
+ */
+
+#include "mt7988a-smartrg-mt-stuart.dtsi"
+
+/ {
+ model = "SmartRG SDG-8733A";
+ compatible = "smartrg,sdg-8733a", "mediatek,mt7988d";
+
+ cpus {
+ /delete-node/ cpu@3;
+ };
+
+ /delete-node/ gpio-export;
+ /delete-node/ gpio-leds;
+
+ gpio-export {
+ compatible = "gpio-export";
+
+ bluetooth_reset: bluetooth-reset {
+ gpio-export,name = "bt_reset";
+ gpio-export,direction_may_change;
+ gpios = <&pio 36 GPIO_ACTIVE_HIGH>;
+ };
+
+ bluetooth_txrx_ctl: bluetooth-txrx-ctl {
+ gpio-export,name = "bt_txrx_ctl";
+ gpio-export,direction_may_change;
+ gpios = <&pio 37 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ lan_amber {
+ color = <LED_COLOR_ID_GREEN>;
+ function = "lan";
+ gpios = <&pio 59 GPIO_ACTIVE_HIGH>;
+ };
+
+ lan_green {
+ color = <LED_COLOR_ID_AMBER>;
+ function = "lan";
+ gpios = <&pio 60 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&fan {
+ pwms = <&pwm 1 40000 0>;
+
+ interrupts = <57 IRQ_TYPE_EDGE_FALLING>;
+};
+
+&gmac0 {
+ status = "disabled";
+};
+
+&gmac1 {
+ label = "lan";
+ phy-mode = "internal";
+ phy-connection-type = "internal";
+ phy = <&int_2p5g_phy>;
+};
+
+&gmac2 {
+ label = "wan";
+ phy-mode = "usxgmii";
+ phy-connection-type = "usxgmii";
+ phy = <&phy8>;
+};
+
+&int_2p5g_phy {
+ pinctrl-names = "i2p5gbe-led";
+ pinctrl-0 = <&i2p5gbe_led0_pins>;
+};
+
+&mdio_bus {
+ /delete-node/ ethernet-phy@0;
+};
+
+&pio {
+ pcie3_1_pins: pcie3-pins-g1 {
+ mux {
+ function = "pcie";
+ groups = "pcie_1l_1_pereset", "pcie_clk_req_n3";
+ };
+ };
+};
+
+&pcie0 {
+ reset-gpios = <&pio 9 GPIO_ACTIVE_HIGH>;
+};
+
+&pcie1 {
+ status = "disabled";
+};
+
+&pcie3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_1_pins>;
+ status = "okay";
+};
+
+&phy8 {
+ reset-gpios = <&pio 62 GPIO_ACTIVE_LOW>;
+ marvell,mdi-cfg-order = <0>;
+};
+
+&aqr_green_led {
+ function = LED_FUNCTION_WAN;
+};
+
+&aqr_orange_led {
+ function = LED_FUNCTION_WAN;
+};
+
+&aqr_white_led {
+ function = LED_FUNCTION_WAN;
+};
+
+&i2p5gbe_led0 {
+ color = <LED_COLOR_ID_GREEN>;
+ status = "okay";
+};
+
+&ssusb0 {
+ status = "disabled";
+};
+
+&ssusb1 {
+ status = "disabled";
+};
+
+&switch {
+ status = "disabled";
+};
+
+&tphy {
+ status = "disabled";
+};
+
+&uart1 {
+ status = "disabled";
+};
+
+&xphy {
+ status = "disabled";
+};
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso
index 5b51dfd671..ab53f96cde 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso
@@ -6,6 +6,11 @@
compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
fragment@0 {
+ target = <&chosen>;
+ rootdisk-spim-nand = <&ubi_rootdisk>;
+ };
+
+ fragment@1 {
target = <&spi0>;
__overlay__ {
status = "okay";
@@ -50,13 +55,20 @@
partition@580000 {
label = "ubi";
reg = <0x580000 0x4000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
};
};
- fragment@1 {
+ fragment@2 {
target = <&wifi>;
__overlay__ {
mediatek,mtd-eeprom = <&factory 0x0>;
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts
index b2bb692956..791b56113a 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts
@@ -15,8 +15,9 @@
serial0 = &uart0;
};
- chosen {
+ chosen: chosen {
stdout-path = "serial0:115200n8";
+ bootargs-append = " root=/dev/fit0 rootwait";
};
memory {
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
index 4945185d69..cd266d6b0f 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
@@ -41,7 +41,7 @@
block-partition-env {
partname = "ubootenv";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
emmc_rootfs: block-partition-production {
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
index 1f5e1491a4..c2ab424e3e 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
@@ -39,7 +39,7 @@
block-partition-env {
partname = "ubootenv";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
sd_rootfs: block-partition-production {
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 9ad068fe05..6a15dcff3d 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -1490,6 +1490,23 @@
compatible = "ethernet-phy-ieee802.3-c45";
reg = <15>;
phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2p5gbe_led0: i2p5gbe-led0@0 {
+ reg = <0>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+
+ i2p5gbe_led1: i2p5gbe-led1@1 {
+ reg = <1>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+ };
};
};
};
diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c b/target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c
deleted file mode 100644
index d1d01190ed..0000000000
--- a/target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c
+++ /dev/null
@@ -1,321 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-#include <linux/bitfield.h>
-#include <linux/firmware.h>
-#include <linux/module.h>
-#include <linux/nvmem-consumer.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/phy.h>
-#include <linux/pm_domain.h>
-#include <linux/pm_runtime.h>
-
-#define MT7988_2P5GE_PMB "mediatek/mt7988/i2p5ge-phy-pmb.bin"
-
-#define MD32_EN BIT(0)
-#define PMEM_PRIORITY BIT(8)
-#define DMEM_PRIORITY BIT(16)
-
-#define BASE100T_STATUS_EXTEND 0x10
-#define BASE1000T_STATUS_EXTEND 0x11
-#define EXTEND_CTRL_AND_STATUS 0x16
-
-#define PHY_AUX_CTRL_STATUS 0x1d
-#define PHY_AUX_DPX_MASK GENMASK(5, 5)
-#define PHY_AUX_SPEED_MASK GENMASK(4, 2)
-
-/* Registers on MDIO_MMD_VEND1 */
-#define MTK_PHY_LINK_STATUS_MISC 0xa2
-#define MTK_PHY_FDX_ENABLE BIT(5)
-
-#define MTK_PHY_LPI_PCS_DSP_CTRL 0x121
-#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8)
-
-/* Registers on MDIO_MMD_VEND2 */
-#define MTK_PHY_LED0_ON_CTRL 0x24
-#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
-#define MTK_PHY_LED0_ON_LINK100 BIT(1)
-#define MTK_PHY_LED0_ON_LINK10 BIT(2)
-#define MTK_PHY_LED0_ON_LINK2500 BIT(7)
-#define MTK_PHY_LED0_POLARITY BIT(14)
-
-#define MTK_PHY_LED1_ON_CTRL 0x26
-#define MTK_PHY_LED1_ON_FDX BIT(4)
-#define MTK_PHY_LED1_ON_HDX BIT(5)
-#define MTK_PHY_LED1_POLARITY BIT(14)
-
-#define MTK_EXT_PAGE_ACCESS 0x1f
-#define MTK_PHY_PAGE_STANDARD 0x0000
-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
-
-struct mtk_i2p5ge_phy_priv {
- bool fw_loaded;
-};
-
-enum {
- PHY_AUX_SPD_10 = 0,
- PHY_AUX_SPD_100,
- PHY_AUX_SPD_1000,
- PHY_AUX_SPD_2500,
-};
-
-static int mtk_2p5ge_phy_read_page(struct phy_device *phydev)
-{
- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
-}
-
-static int mtk_2p5ge_phy_write_page(struct phy_device *phydev, int page)
-{
- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
-}
-
-static int mt7988_2p5ge_phy_probe(struct phy_device *phydev)
-{
- struct mtk_i2p5ge_phy_priv *phy_priv;
-
- phy_priv = devm_kzalloc(&phydev->mdio.dev,
- sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL);
- if (!phy_priv)
- return -ENOMEM;
-
- phydev->priv = phy_priv;
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_config_init(struct phy_device *phydev)
-{
- int ret, i;
- const struct firmware *fw;
- struct device *dev = &phydev->mdio.dev;
- struct device_node *np;
- void __iomem *pmb_addr;
- void __iomem *md32_en_cfg_base;
- struct mtk_i2p5ge_phy_priv *phy_priv = phydev->priv;
- u16 reg;
- struct pinctrl *pinctrl;
-
- if (!phy_priv->fw_loaded) {
- np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw");
- if (!np)
- return -ENOENT;
- pmb_addr = of_iomap(np, 0);
- if (!pmb_addr)
- return -ENOMEM;
- md32_en_cfg_base = of_iomap(np, 1);
- if (!md32_en_cfg_base)
- return -ENOMEM;
-
- ret = request_firmware(&fw, MT7988_2P5GE_PMB, dev);
- if (ret) {
- dev_err(dev, "failed to load firmware: %s, ret: %d\n",
- MT7988_2P5GE_PMB, ret);
- return ret;
- }
-
- reg = readw(md32_en_cfg_base);
- if (reg & MD32_EN) {
- phy_set_bits(phydev, 0, BIT(15));
- usleep_range(10000, 11000);
- }
- phy_set_bits(phydev, 0, BIT(11));
-
- /* Write magic number to safely stall MCU */
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800e, 0x1100);
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800f, 0x00df);
-
- for (i = 0; i < fw->size - 1; i += 4)
- writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
- release_firmware(fw);
-
- writew(reg & ~MD32_EN, md32_en_cfg_base);
- writew(reg | MD32_EN, md32_en_cfg_base);
- phy_set_bits(phydev, 0, BIT(15));
- dev_info(dev, "Firmware loading/trigger ok.\n");
-
- phy_priv->fw_loaded = true;
- }
-
- /* Setup LED */
-
- /* Set polarity of led0 to active-high for BPI-R4 */
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
- MTK_PHY_LED0_POLARITY);
-
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
- MTK_PHY_LED0_ON_LINK10 |
- MTK_PHY_LED0_ON_LINK100 |
- MTK_PHY_LED0_ON_LINK1000 |
- MTK_PHY_LED0_ON_LINK2500);
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
- MTK_PHY_LED1_ON_FDX | MTK_PHY_LED1_ON_HDX);
-
- pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
- if (IS_ERR(pinctrl)) {
- dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
- return PTR_ERR(pinctrl);
- }
-
- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL,
- MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0);
-
- /* Enable 16-bit next page exchange bit if 1000-BT isn't advertizing */
- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
- __phy_write(phydev, 0x11, 0xfbfa);
- __phy_write(phydev, 0x12, 0xc3);
- __phy_write(phydev, 0x10, 0x87f8);
- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_config_aneg(struct phy_device *phydev)
-{
- bool changed = false;
- u32 adv;
- int ret;
-
- if (phydev->autoneg == AUTONEG_DISABLE) {
- /* Configure half duplex with genphy_setup_forced,
- * because genphy_c45_pma_setup_forced does not support.
- */
- return phydev->duplex != DUPLEX_FULL
- ? genphy_setup_forced(phydev)
- : genphy_c45_pma_setup_forced(phydev);
- }
-
- ret = genphy_c45_an_config_aneg(phydev);
- if (ret < 0)
- return ret;
- if (ret > 0)
- changed = true;
-
- adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
- ret = phy_modify_changed(phydev, MII_CTRL1000,
- ADVERTISE_1000FULL | ADVERTISE_1000HALF,
- adv);
- if (ret < 0)
- return ret;
- if (ret > 0)
- changed = true;
-
- return genphy_c45_check_and_restart_aneg(phydev, changed);
-}
-
-static int mt7988_2p5ge_phy_get_features(struct phy_device *phydev)
-{
- int ret;
-
- ret = genphy_read_abilities(phydev);
- if (ret)
- return ret;
-
- /* We don't support HDX at MAC layer on mt7988.
- * So mask phy's HDX capabilities, too.
- */
- linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_read_status(struct phy_device *phydev)
-{
- int ret;
-
- ret = genphy_update_link(phydev);
- if (ret)
- return ret;
-
- phydev->speed = SPEED_UNKNOWN;
- phydev->duplex = DUPLEX_UNKNOWN;
- phydev->pause = 0;
- phydev->asym_pause = 0;
-
- if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
- ret = genphy_c45_read_lpa(phydev);
- if (ret < 0)
- return ret;
-
- /* Read the link partner's 1G advertisement */
- ret = phy_read(phydev, MII_STAT1000);
- if (ret < 0)
- return ret;
- mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
- } else if (phydev->autoneg == AUTONEG_DISABLE) {
- linkmode_zero(phydev->lp_advertising);
- }
-
- ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
- if (ret < 0)
- return ret;
-
- switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
- case PHY_AUX_SPD_10:
- phydev->speed = SPEED_10;
- break;
- case PHY_AUX_SPD_100:
- phydev->speed = SPEED_100;
- break;
- case PHY_AUX_SPD_1000:
- phydev->speed = SPEED_1000;
- break;
- case PHY_AUX_SPD_2500:
- phydev->speed = SPEED_2500;
- break;
- }
-
- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
- if (ret < 0)
- return ret;
-
- phydev->duplex = (ret & MTK_PHY_FDX_ENABLE) ? DUPLEX_FULL : DUPLEX_HALF;
- /* FIXME: The current firmware always enables rate adaptation mode. */
- phydev->rate_matching = RATE_MATCH_PAUSE;
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
- phy_interface_t iface)
-{
- return RATE_MATCH_PAUSE;
-}
-
-static struct phy_driver mtk_gephy_driver[] = {
- {
- PHY_ID_MATCH_MODEL(0x00339c11),
- .name = "MediaTek MT798x 2.5GbE PHY",
- .probe = mt7988_2p5ge_phy_probe,
- .config_init = mt7988_2p5ge_phy_config_init,
- .config_aneg = mt7988_2p5ge_phy_config_aneg,
- .get_features = mt7988_2p5ge_phy_get_features,
- .read_status = mt7988_2p5ge_phy_read_status,
- .get_rate_matching = mt7988_2p5ge_phy_get_rate_matching,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .read_page = mtk_2p5ge_phy_read_page,
- .write_page = mtk_2p5ge_phy_write_page,
- },
-};
-
-module_phy_driver(mtk_gephy_driver);
-
-static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
- { PHY_ID_MATCH_VENDOR(0x00339c00) },
- { }
-};
-
-MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
-MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
-MODULE_LICENSE("GPL");
-
-MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
-MODULE_FIRMWARE(MT7988_2P5GE_PMB);
diff --git a/target/linux/mediatek/files/block/partitions/fit.c b/target/linux/mediatek/files/block/partitions/fit.c
deleted file mode 100644
index 463cd4e9ab..0000000000
--- a/target/linux/mediatek/files/block/partitions/fit.c
+++ /dev/null
@@ -1,307 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * fs/partitions/fit.c
- * Copyright (C) 2021 Daniel Golle
- *
- * headers extracted from U-Boot mkimage sources
- * (C) Copyright 2008 Semihalf
- * (C) Copyright 2000-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * based on existing partition parsers
- * Copyright (C) 1991-1998 Linus Torvalds
- * Re-organised Feb 1998 Russell King
- */
-
-#define pr_fmt(fmt) fmt
-
-#include <linux/types.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_fdt.h>
-#include <linux/libfdt.h>
-#include <linux/version.h>
-
-#include "check.h"
-
-#define FIT_IMAGES_PATH "/images"
-#define FIT_CONFS_PATH "/configurations"
-
-/* hash/signature/key node */
-#define FIT_HASH_NODENAME "hash"
-#define FIT_ALGO_PROP "algo"
-#define FIT_VALUE_PROP "value"
-#define FIT_IGNORE_PROP "uboot-ignore"
-#define FIT_SIG_NODENAME "signature"
-#define FIT_KEY_REQUIRED "required"
-#define FIT_KEY_HINT "key-name-hint"
-
-/* cipher node */
-#define FIT_CIPHER_NODENAME "cipher"
-#define FIT_ALGO_PROP "algo"
-
-/* image node */
-#define FIT_DATA_PROP "data"
-#define FIT_DATA_POSITION_PROP "data-position"
-#define FIT_DATA_OFFSET_PROP "data-offset"
-#define FIT_DATA_SIZE_PROP "data-size"
-#define FIT_TIMESTAMP_PROP "timestamp"
-#define FIT_DESC_PROP "description"
-#define FIT_ARCH_PROP "arch"
-#define FIT_TYPE_PROP "type"
-#define FIT_OS_PROP "os"
-#define FIT_COMP_PROP "compression"
-#define FIT_ENTRY_PROP "entry"
-#define FIT_LOAD_PROP "load"
-
-/* configuration node */
-#define FIT_KERNEL_PROP "kernel"
-#define FIT_FILESYSTEM_PROP "filesystem"
-#define FIT_RAMDISK_PROP "ramdisk"
-#define FIT_FDT_PROP "fdt"
-#define FIT_LOADABLE_PROP "loadables"
-#define FIT_DEFAULT_PROP "default"
-#define FIT_SETUP_PROP "setup"
-#define FIT_FPGA_PROP "fpga"
-#define FIT_FIRMWARE_PROP "firmware"
-#define FIT_STANDALONE_PROP "standalone"
-
-#define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE
-
-#define MIN_FREE_SECT 16
-#define REMAIN_VOLNAME "rootfs_data"
-
-int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector, u64 sectors, int *slot, int add_remain)
-{
- struct block_device *bdev = state->disk->part0;
- struct address_space *mapping = bdev->bd_inode->i_mapping;
- struct page *page;
- void *fit, *init_fit;
- struct partition_meta_info *info;
- char tmp[sizeof(info->volname)];
- u64 dsize, dsectors, imgmaxsect = 0;
- u32 size, image_pos, image_len;
- const u32 *image_offset_be, *image_len_be, *image_pos_be;
- int ret = 1, node, images, config;
- const char *image_name, *image_type, *image_description, *config_default,
- *config_description, *config_loadables, *bootconf_c;
- int image_name_len, image_type_len, image_description_len, config_default_len,
- config_description_len, config_loadables_len, bootconf_len;
- sector_t start_sect, nr_sects;
- size_t label_min;
- struct device_node *np = NULL;
- char *bootconf = NULL, *bootconf_term;
- const char *loadable;
- const char *select_rootfs = NULL;
- bool found;
- int loadables_rem_len, loadable_len;
-
- if (fit_start_sector % (1<<(PAGE_SHIFT - SECTOR_SHIFT)))
- return -ERANGE;
-
- page = read_mapping_page(mapping, fit_start_sector >> (PAGE_SHIFT - SECTOR_SHIFT), NULL);
- if (IS_ERR(page))
- return -EFAULT;
-
- if (PageError(page))
- return -EFAULT;
-
- init_fit = page_address(page);
-
- if (!init_fit) {
- put_page(page);
- return -EFAULT;
- }
-
- if (fdt_check_header(init_fit)) {
- put_page(page);
- return 0;
- }
-
- dsectors = get_capacity(bdev->bd_disk);
- if (sectors)
- dsectors = (dsectors>sectors)?sectors:dsectors;
-
- dsize = dsectors << SECTOR_SHIFT;
- size = fdt_totalsize(init_fit);
-
- /* silently skip non-external-data legacy FIT images */
- if (size > PAGE_SIZE) {
- put_page(page);
- return 0;
- }
-
- if (size >= dsize) {
- state->access_beyond_eod = 1;
- put_page(page);
- return -EFBIG;
- }
-
- fit = kmemdup(init_fit, size, GFP_KERNEL);
- put_page(page);
- if (!fit)
- return -ENOMEM;
-
- np = of_find_node_by_path("/chosen");
- if (np) {
- /* new fitblk driver should take over if /chosen/rootdisk is defined */
- if (of_get_property(np, "rootdisk", NULL))
- return 0;
-
- bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len);
- if (bootconf_c && bootconf_len)
- bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL);
- }
-
- if (bootconf) {
- bootconf_term = strchr(bootconf, '#');
- if (bootconf_term)
- *bootconf_term = '\0';
- }
-
- config = fdt_path_offset(fit, FIT_CONFS_PATH);
- if (config < 0) {
- printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_CONFS_PATH, images);
- ret = -ENOENT;
- goto ret_out;
- }
-
- config_default = fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len);
-
- if (!config_default && !bootconf) {
- printk(KERN_ERR "FIT: Cannot find default configuration\n");
- ret = -ENOENT;
- goto ret_out;
- }
-
- node = fdt_subnode_offset(fit, config, bootconf?:config_default);
- if (node < 0) {
- printk(KERN_ERR "FIT: Cannot find %s node: %d\n", bootconf?:config_default, node);
- ret = -ENOENT;
- goto ret_out;
- }
-
- config_description = fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
- config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, &config_loadables_len);
-
- printk(KERN_DEBUG "FIT: %s configuration: \"%s\"%s%s%s\n",
- bootconf?"Selected":"Default", bootconf?:config_default,
- config_description?" (":"", config_description?:"", config_description?")":"");
-
- if (!config_loadables || !config_loadables_len) {
- printk(KERN_ERR "FIT: No loadables configured in \"%s\"\n", bootconf?:config_default);
- ret = -ENOENT;
- goto ret_out;
- }
-
- images = fdt_path_offset(fit, FIT_IMAGES_PATH);
- if (images < 0) {
- printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images);
- ret = -EINVAL;
- goto ret_out;
- }
-
- fdt_for_each_subnode(node, fit, images) {
- image_name = fdt_get_name(fit, node, &image_name_len);
- image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len);
- image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL);
- image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL);
- image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL);
- if (!image_name || !image_type || !image_len_be)
- continue;
-
- image_len = be32_to_cpu(*image_len_be);
- if (!image_len)
- continue;
-
- if (image_offset_be)
- image_pos = be32_to_cpu(*image_offset_be) + size;
- else if (image_pos_be)
- image_pos = be32_to_cpu(*image_pos_be);
- else
- continue;
-
- image_description = fdt_getprop(fit, node, FIT_DESC_PROP, &image_description_len);
-
- printk(KERN_DEBUG "FIT: %16s sub-image 0x%08x..0x%08x \"%s\" %s%s%s\n",
- image_type, image_pos, image_pos + image_len - 1, image_name,
- image_description?"(":"", image_description?:"", image_description?") ":"");
-
- if (strcmp(image_type, FIT_FILESYSTEM_PROP))
- continue;
-
- /* check if sub-image is part of configured loadables */
- found = false;
- loadable = config_loadables;
- loadables_rem_len = config_loadables_len;
- while (loadables_rem_len > 1) {
- loadable_len = strnlen(loadable, loadables_rem_len - 1) + 1;
- loadables_rem_len -= loadable_len;
- if (!strncmp(image_name, loadable, loadable_len)) {
- found = true;
- break;
- }
- loadable += loadable_len;
- }
- if (!found)
- continue;
-
- if (image_pos & ((1 << PAGE_SHIFT)-1)) {
- printk(KERN_ERR "FIT: image %s start not aligned to page boundaries, skipping\n", image_name);
- continue;
- }
-
- if (image_len & ((1 << PAGE_SHIFT)-1)) {
- printk(KERN_ERR "FIT: sub-image %s end not aligned to page boundaries, skipping\n", image_name);
- continue;
- }
-
- start_sect = image_pos >> SECTOR_SHIFT;
- nr_sects = image_len >> SECTOR_SHIFT;
- imgmaxsect = (imgmaxsect < (start_sect + nr_sects))?(start_sect + nr_sects):imgmaxsect;
-
- if (start_sect + nr_sects > dsectors) {
- state->access_beyond_eod = 1;
- continue;
- }
-
- put_partition(state, ++(*slot), fit_start_sector + start_sect, nr_sects);
- state->parts[*slot].flags = ADDPART_FLAG_READONLY;
- state->parts[*slot].has_info = true;
- info = &state->parts[*slot].info;
-
- label_min = min_t(int, sizeof(info->volname) - 1, image_name_len);
- strncpy(info->volname, image_name, label_min);
- info->volname[label_min] = '\0';
-
- snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
- strlcat(state->pp_buf, tmp, PAGE_SIZE);
-
- /* Mark first loadable listed to be mounted as rootfs */
- if (!strcmp(image_name, config_loadables)) {
- select_rootfs = image_name;
- state->parts[*slot].flags |= ADDPART_FLAG_ROOTDEV;
- }
- }
-
- if (select_rootfs)
- printk(KERN_DEBUG "FIT: selecting configured loadable \"%s\" to be root filesystem\n", select_rootfs);
-
- if (add_remain && (imgmaxsect + MIN_FREE_SECT) < dsectors) {
- put_partition(state, ++(*slot), fit_start_sector + imgmaxsect, dsectors - imgmaxsect);
- state->parts[*slot].flags = 0;
- info = &state->parts[*slot].info;
- strcpy(info->volname, REMAIN_VOLNAME);
- snprintf(tmp, sizeof(tmp), "(%s)", REMAIN_VOLNAME);
- strlcat(state->pp_buf, tmp, PAGE_SIZE);
- }
-ret_out:
- kfree(bootconf);
- kfree(fit);
- return ret;
-}
-
-int fit_partition(struct parsed_partitions *state) {
- int slot = 0;
- return parse_fit_partitions(state, 0, 0, &slot, 0);
-}
diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds
index ca462d2005..1437a120f5 100644
--- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds
+++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds
@@ -6,6 +6,11 @@ board=$(board_name)
board_config_update
case $board in
+abt,asr3000)
+ ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth1"
+ ucidef_set_led_netdev "wlan2g" "WLAN2G" "green:wlan-2ghz" "phy0-ap0"
+ ucidef_set_led_netdev "wlan5g" "WLAN5G" "green:wlan-5ghz" "phy1-ap0"
+ ;;
confiabits,mt7981)
ucidef_set_led_netdev "lan1" "lan1" "blue:lan-1" "lan1" "link tx rx"
ucidef_set_led_netdev "lan2" "lan2" "blue:lan-2" "lan2" "link tx rx"
@@ -91,11 +96,25 @@ smartrg,sdg-8734)
ucidef_set_led_netdev "wan-green" "WAN" "mdio-bus:00:green:wan" "wan" "link_2500 link_5000"
ucidef_set_led_netdev "wan-orange" "WAN" "mdio-bus:00:orange:wan" "wan" "link_100 link_1000"
ucidef_set_led_netdev "wan-white" "WAN" "mdio-bus:00:white:wan" "wan" "link_10000"
+ ;;
+smartrg,sdg-8733a)
+ ucidef_set_led_netdev "lan-green-act" "LAN" "mdio-bus:0f:green:lan" "lan" "link_2500"
+ ucidef_set_led_netdev "lan-amber" "LAN" "amber:lan" "lan" "link_100"
+ ucidef_set_led_netdev "lan-green" "LAN" "green:lan" "lan" "link_1000"
+ ucidef_set_led_netdev "wan-green" "WAN" "mdio-bus:08:green:wan" "wan" "link_2500 link_5000"
+ ucidef_set_led_netdev "wan-orange" "WAN" "mdio-bus:08:orange:wan" "wan" "link_100 link_1000"
+ ucidef_set_led_netdev "wan-white" "WAN" "mdio-bus:08:white:wan" "wan" "link_10000"
+ ;;
wavlink,wl-wn586x3)
ucidef_set_led_netdev "lan-1" "lan-1" "blue:lan-1" "lan1" "link tx rx"
ucidef_set_led_netdev "lan-2" "lan-2" "blue:lan-2" "lan2" "link tx rx"
ucidef_set_led_netdev "wan" "wan" "blue:wan" "eth1" "link tx rx"
;;
+tplink,re6000xd)
+ ucidef_set_led_netdev "lan-1" "lan-1" "blue:lan-0" "lan1" "link tx rx"
+ ucidef_set_led_netdev "lan-2" "lan-2" "blue:lan-1" "lan2" "link tx rx"
+ ucidef_set_led_netdev "eth1" "lan-3" "blue:lan-2" "eth1" "link tx rx"
+ ;;
xiaomi,mi-router-wr30u-stock|\
xiaomi,mi-router-wr30u-ubootmod)
ucidef_set_led_netdev "wan" "wan" "blue:wan" "wan" "link tx rx"
diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network
index 70b076dc9f..74ee571bc0 100644
--- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network
+++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network
@@ -11,6 +11,13 @@ mediatek_setup_interfaces()
acelink,ew-7886cax)
ucidef_set_interface_lan "eth0" "dhcp"
;;
+ abt,asr3000|\
+ cmcc,rax3000m|\
+ h3c,magic-nx30-pro|\
+ nokia,ea0326gmp|\
+ zbtlink,zbt-z8103ax)
+ ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" eth1
+ ;;
acer,predator-w6)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 game" eth1
;;
@@ -46,12 +53,6 @@ mediatek_setup_interfaces()
bananapi,bpi-r4-poe)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 eth1" "wan eth2"
;;
- cmcc,rax3000m|\
- h3c,magic-nx30-pro|\
- nokia,ea0326gmp|\
- zbtlink,zbt-z8103ax)
- ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" eth1
- ;;
comfast,cf-e393ax)
ucidef_set_interfaces_lan_wan "lan1" eth1
;;
@@ -70,7 +71,8 @@ mediatek_setup_interfaces()
;;
glinet,gl-mt6000|\
tplink,tl-xdr4288|\
- tplink,tl-xdr6088)
+ tplink,tl-xdr6088|\
+ tplink,tl-xtr8488)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 lan5" eth1
;;
mediatek,mt7986a-rfb)
@@ -80,11 +82,12 @@ mediatek_setup_interfaces()
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" eth1
;;
mediatek,mt7988a-rfb)
- ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 eth1" eth2
+ ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 eth2" eth1
;;
mercusys,mr90x-v1)
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2" eth1
;;
+ cudy,ap3000outdoor-v1|\
cudy,re3000-v1|\
netgear,wax220|\
ubnt,unifi-6-plus|\
@@ -93,6 +96,7 @@ mediatek_setup_interfaces()
;;
smartrg,sdg-8622|\
smartrg,sdg-8632|\
+ smartrg,sdg-8733a|\
yuncore,ax835)
ucidef_set_interfaces_lan_wan lan wan
;;
@@ -100,6 +104,9 @@ mediatek_setup_interfaces()
wavlink,wl-wn586x3)
ucidef_set_interfaces_lan_wan "lan1 lan2" eth1
;;
+ tplink,re6000xd)
+ ucidef_set_interface_lan "lan1 lan2 eth1"
+ ;;
xiaomi,mi-router-ax3000t|\
xiaomi,mi-router-ax3000t-ubootmod|\
xiaomi,mi-router-wr30u-stock|\
@@ -131,21 +138,13 @@ mediatek_setup_macs()
bananapi,bpi-r4)
wan_mac=$(macaddr_add $(cat /sys/class/net/eth0/address) 1)
;;
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- wan_mac=$(mmc_get_mac_binary factory 0x2a)
- lan_mac=$(mmc_get_mac_binary factory 0x24)
- label_mac=$wan_mac
- ;;
- esac
- ;;
h3c,magic-nx30-pro)
wan_mac=$(mtd_get_mac_ascii pdt_data_1 ethaddr)
lan_mac=$(macaddr_add "$wan_mac" 1)
label_mac=$wan_mac
;;
- mercusys,mr90x-v1)
+ mercusys,mr90x-v1|\
+ tplink,re6000xd)
label_mac=$(get_mac_binary "/tmp/tp_data/default-mac" 0)
lan_mac=$label_mac
;;
diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata
index e0d1d93207..c6900e6ebd 100644
--- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata
+++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata
@@ -24,16 +24,6 @@ case "$FIRMWARE" in
;;
"mediatek/mt7981_eeprom_mt7976_dbdc.bin")
case "$board" in
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- caldata_extract_mmc "factory" 0x0 0x1000
- ;;
- esac
- ;;
- openwrt,one)
- caldata_extract "factory" 0x0 0x1000
- ;;
ubnt,unifi-6-plus)
caldata_extract_mmc "factory" 0x0 0x1000
;;
@@ -41,7 +31,8 @@ case "$FIRMWARE" in
;;
"mediatek/mt7986_eeprom_mt7975_dual.bin")
case "$board" in
- mercusys,mr90x-v1)
+ mercusys,mr90x-v1|\
+ tplink,re6000xd)
ln -sf /tmp/tp_data/MT7986_EEPROM.bin \
/lib/firmware/$FIRMWARE
;;
diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac
index 334d221e21..3600e32340 100644
--- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac
+++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac
@@ -10,6 +10,13 @@ PHYNBR=${DEVPATH##*/phy}
board=$(board_name)
case "$board" in
+ abt,asr3000)
+ # Originally, phy1 is phy0 mac with LA bit set. However, this would conflict
+ # addresses on multiple VIFs with the other radio. Use label mac to set LA bit.
+ addr=$(cat /sys/class/net/eth1/address)
+ [ "$PHYNBR" = "0" ] && macaddr_add $addr 1 > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" = "1" ] && macaddr_setbit_la $addr > /sys${DEVPATH}/macaddress
+ ;;
acer,predator-w6)
key_path="/var/qcidata/data"
[ "$PHYNBR" = "0" ] && cat $key_path/2gMAC > /sys${DEVPATH}/macaddress
@@ -55,15 +62,8 @@ case "$board" in
[ "$PHYNBR" = "1" ] && macaddr_setbit_la $(macaddr_add $addr 2) > /sys${DEVPATH}/macaddress
;;
cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- addr=$(mmc_get_mac_binary factory 0xa)
- ;;
- *)
- addr=$(mtd_get_mac_binary factory 0xa)
- ;;
- esac
- [ "$PHYNBR" = "1" ] && echo "$addr" > /sys${DEVPATH}/macaddress
+ addr=$(cat /sys/class/net/eth0/address)
+ [ "$PHYNBR" = "1" ] && macaddr_add $addr -1 > /sys${DEVPATH}/macaddress
;;
comfast,cf-e393ax)
addr=$(mtd_get_mac_binary "Factory" 0x8000)
@@ -75,6 +75,7 @@ case "$board" in
[ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_setbit_la $(macaddr_add $addr 1) > /sys${DEVPATH}/macaddress
;;
+ cudy,ap3000outdoor-v1|\
cudy,m3000-v1|\
cudy,wr3000-v1)
addr=$(mtd_get_mac_binary bdinfo 0xde00)
@@ -109,7 +110,8 @@ case "$board" in
jdcloud,re-cp-03)
[ "$PHYNBR" = "1" ] && mmc_get_mac_binary factory 0xa > /sys${DEVPATH}/macaddress
;;
- mercusys,mr90x-v1)
+ mercusys,mr90x-v1|\
+ tplink,re6000xd)
addr=$(get_mac_binary "/tmp/tp_data/default-mac" 0)
[ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $addr -1 > /sys${DEVPATH}/macaddress
@@ -147,7 +149,8 @@ case "$board" in
[ "$PHYNBR" = "2" ] && macaddr_add $addr 4 > /sys${DEVPATH}/macaddress
;;
smartrg,sdg-8733|\
- smartrg,sdg-8634)
+ smartrg,sdg-8733a|\
+ smartrg,sdg-8734)
addr=$(mmc_get_mac_ascii mfginfo MFG_MAC)
[ "$PHYNBR" = "0" ] && macaddr_add $addr 4 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $addr a > /sys${DEVPATH}/macaddress
@@ -158,6 +161,9 @@ case "$board" in
tplink,tl-xdr6088)
[ "$PHYNBR" = "0" ] && get_mac_label > /sys${DEVPATH}/macaddress
;;
+ tplink,tl-xtr8488)
+ [ "$PHYNBR" = "1" ] && get_mac_label > /sys${DEVPATH}/macaddress
+ ;;
ubnt,unifi-6-plus)
addr=$(mtd_get_mac_binary EEPROM 0x6)
[ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
diff --git a/target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part b/target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part
index 819df40d08..11e3b598af 100644
--- a/target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part
+++ b/target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part
@@ -12,7 +12,8 @@ mount_ubi_part() {
preinit_mount_cfg_part() {
case $(board_name) in
- mercusys,mr90x-v1)
+ mercusys,mr90x-v1|\
+ tplink,re6000xd)
mount_ubi_part "tp_data"
;;
*)
diff --git a/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh b/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh
index 2fe48b0ccf..65bd517824 100644
--- a/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh
+++ b/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh
@@ -17,7 +17,8 @@ preinit_set_mac_address() {
ip link set dev eth0 address "$addr"
ip link set dev eth1 address "$addr"
;;
- mercusys,mr90x-v1)
+ mercusys,mr90x-v1|\
+ tplink,re6000xd)
addr=$(get_mac_binary "/tmp/tp_data/default-mac" 0)
ip link set dev eth1 address "$(macaddr_add $addr 1)"
;;
@@ -35,7 +36,8 @@ preinit_set_mac_address() {
ip link set dev lan4 address "$lan_addr"
;;
smartrg,sdg-8622|\
- smartrg,sdg-8632)
+ smartrg,sdg-8632|\
+ smartrg,sdg-8733a)
addr=$(mmc_get_mac_ascii mfginfo MFG_MAC)
ip link set dev wan address "$addr"
ip link set dev lan address "$(macaddr_add $addr 1)"
diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh
index 7e105b1089..429728392a 100755
--- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh
@@ -64,12 +64,38 @@ platform_do_upgrade() {
local board=$(board_name)
case "$board" in
+ abt,asr3000|\
+ bananapi,bpi-r3|\
+ bananapi,bpi-r3-mini|\
+ bananapi,bpi-r4|\
+ bananapi,bpi-r4-poe|\
+ cmcc,rax3000m|\
+ h3c,magic-nx30-pro|\
+ jcg,q30-pro|\
+ jdcloud,re-cp-03|\
+ mediatek,mt7981-rfb|\
+ mediatek,mt7988a-rfb|\
+ nokia,ea0326gmp|\
+ openwrt,one|\
+ netcore,n60|\
+ qihoo,360t7|\
+ tplink,tl-xdr4288|\
+ tplink,tl-xdr6086|\
+ tplink,tl-xdr6088|\
+ tplink,tl-xtr8488|\
+ xiaomi,mi-router-ax3000t-ubootmod|\
+ xiaomi,redmi-router-ax6000-ubootmod|\
+ xiaomi,mi-router-wr30u-ubootmod|\
+ zyxel,ex5601-t0-ubootmod)
+ fit_do_upgrade "$1"
+ ;;
acer,predator-w6|\
smartrg,sdg-8612|\
smartrg,sdg-8614|\
smartrg,sdg-8622|\
smartrg,sdg-8632|\
smartrg,sdg-8733|\
+ smartrg,sdg-8733a|\
smartrg,sdg-8734)
CI_KERNPART="kernel"
CI_ROOTPART="rootfs"
@@ -82,43 +108,6 @@ platform_do_upgrade() {
CI_KERNPART="linux"
nand_do_upgrade "$1"
;;
- bananapi,bpi-r3|\
- bananapi,bpi-r3-mini|\
- bananapi,bpi-r4|\
- bananapi,bpi-r4-poe|\
- jdcloud,re-cp-03|\
- mediatek,mt7988a-rfb|\
- openwrt,one)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- bootdev="$(fitblk_get_bootdev)"
- case "$bootdev" in
- mmcblk*)
- EMMC_KERN_DEV="/dev/$bootdev"
- emmc_do_upgrade "$1"
- ;;
- mtdblock*)
- PART_NAME="/dev/mtd${bootdev:8}"
- default_do_upgrade "$1"
- ;;
- ubiblock*)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
- esac
- ;;
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- CI_KERNPART="production"
- emmc_do_upgrade "$1"
- ;;
- *)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
- esac
- ;;
cudy,re3000-v1|\
cudy,wr3000-v1|\
yuncore,ax835)
@@ -132,30 +121,11 @@ platform_do_upgrade() {
CI_ROOTPART="rootfs"
emmc_do_upgrade "$1"
;;
- h3c,magic-nx30-pro|\
- jcg,q30-pro|\
- mediatek,mt7981-rfb|\
- netcore,n60|\
- qihoo,360t7|\
- xiaomi,mi-router-ax3000t-ubootmod|\
- xiaomi,mi-router-wr30u-ubootmod)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
- mercusys,mr90x-v1)
+ mercusys,mr90x-v1|\
+ tplink,re6000xd)
CI_UBIPART="ubi0"
nand_do_upgrade "$1"
;;
- nokia,ea0326gmp|\
- tplink,tl-xdr4288|\
- tplink,tl-xdr6086|\
- tplink,tl-xdr6088|\
- xiaomi,redmi-router-ax6000-ubootmod)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
ubnt,unifi-6-plus)
CI_KERNPART="kernel0"
EMMC_ROOT_DEV="$(cmdline_get_var root)"
@@ -168,11 +138,6 @@ platform_do_upgrade() {
CI_ROOT_UBIPART=ubi
nand_do_upgrade "$1"
;;
- zyxel,ex5601-t0-ubootmod)
- CI_KERNPART="fit"
- CI_ROOTPART="ubi_rootfs"
- nand_do_upgrade "$1"
- ;;
unielec,u7981-01*)
local rootdev="$(cmdline_get_var root)"
rootdev="${rootdev##*/}"
@@ -206,6 +171,7 @@ platform_check_image() {
case "$board" in
bananapi,bpi-r3|\
+ bananapi,bpi-r3-mini|\
bananapi,bpi-r4|\
bananapi,bpi-r4-poe|\
cmcc,rax3000m)
@@ -226,22 +192,14 @@ platform_check_image() {
platform_copy_config() {
case "$(board_name)" in
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- emmc_copy_config
- ;;
- esac
- ;;
bananapi,bpi-r3|\
bananapi,bpi-r3-mini|\
bananapi,bpi-r4|\
- bananapi,bpi-r4-poe)
- case "$(fitblk_get_bootdev)" in
- mmcblk*)
+ bananapi,bpi-r4-poe|\
+ cmcc,rax3000m)
+ if [ "$CI_METHOD" = "emmc" ]; then
emmc_copy_config
- ;;
- esac
+ fi
;;
acer,predator-w6|\
glinet,gl-mt2500|\
@@ -254,6 +212,7 @@ platform_copy_config() {
smartrg,sdg-8622|\
smartrg,sdg-8632|\
smartrg,sdg-8733|\
+ smartrg,sdg-8733a|\
smartrg,sdg-8734|\
ubnt,unifi-6-plus)
emmc_copy_config
diff --git a/target/linux/mediatek/filogic/config-6.6 b/target/linux/mediatek/filogic/config-6.6
index 6d9d42853b..818bcfa081 100644
--- a/target/linux/mediatek/filogic/config-6.6
+++ b/target/linux/mediatek/filogic/config-6.6
@@ -158,7 +158,6 @@ CONFIG_EINT_MTK=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=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
@@ -240,7 +239,7 @@ CONFIG_MAXLINEAR_GPHY=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
-CONFIG_MEDIATEK_2P5G_PHY=y
+CONFIG_MEDIATEK_2P5GE_PHY=y
CONFIG_MEDIATEK_GE_PHY=y
CONFIG_MEDIATEK_GE_SOC_PHY=y
CONFIG_MEDIATEK_WATCHDOG=y
diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk
index 4db0cf2372..3e10003e4c 100644
--- a/target/linux/mediatek/image/filogic.mk
+++ b/target/linux/mediatek/image/filogic.mk
@@ -105,6 +105,30 @@ define Build/cetron-header
rm $@.tmp
endef
+define Device/abt_asr3000
+ DEVICE_VENDOR := ABT
+ DEVICE_MODEL := ASR3000
+ DEVICE_DTS := mt7981b-abt-asr3000
+ DEVICE_DTS_DIR := ../dts
+ DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware
+ UBINIZE_OPTS := -E 5
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ KERNEL_IN_UBI := 1
+ UBOOTENV_IN_UBI := 1
+ IMAGES := sysupgrade.itb
+ KERNEL_INITRAMFS_SUFFIX := -recovery.itb
+ KERNEL := kernel-bin | gzip
+ KERNEL_INITRAMFS := kernel-bin | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k
+ IMAGE/sysupgrade.itb := append-kernel | \
+ fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb external-static-with-rootfs | append-metadata
+ ARTIFACTS := preloader.bin bl31-uboot.fip
+ ARTIFACT/preloader.bin := mt7981-bl2 spim-nand-ddr3
+ ARTIFACT/bl31-uboot.fip := mt7981-bl31-uboot abt_asr3000
+endef
+TARGET_DEVICES += abt_asr3000
+
define Device/acelink_ew-7886cax
DEVICE_VENDOR := Acelink
DEVICE_MODEL := EW-7886CAX
@@ -184,6 +208,14 @@ $(call Device/adtran_smartrg)
endef
TARGET_DEVICES += smartrg_sdg-8733
+define Device/smartrg_sdg-8733a
+$(call Device/adtran_smartrg)
+ DEVICE_MODEL := SDG-8733A
+ DEVICE_DTS := mt7988d-smartrg-SDG-8733A
+ DEVICE_PACKAGES += mt7988-2p5g-phy-firmware kmod-mt7996-233-firmware kmod-phy-aquantia
+endef
+TARGET_DEVICES += smartrg_sdg-8733a
+
define Device/smartrg_sdg-8734
$(call Device/adtran_smartrg)
DEVICE_MODEL := SDG-8734
@@ -341,7 +373,7 @@ define Device/bananapi_bpi-r4-common
DEVICE_DTS_LOADADDR := 0x45f00000
DEVICE_DTS_OVERLAY:= mt7988a-bananapi-bpi-r4-emmc mt7988a-bananapi-bpi-r4-rtc mt7988a-bananapi-bpi-r4-sd mt7988a-bananapi-bpi-r4-wifi-mt7996a
DEVICE_DTC_FLAGS := --pad 4096
- DEVICE_PACKAGES := kmod-hwmon-pwmfan kmod-i2c-mux-pca954x kmod-eeprom-at24 kmod-mt7996-firmware \
+ DEVICE_PACKAGES := kmod-hwmon-pwmfan kmod-i2c-mux-pca954x kmod-eeprom-at24 kmod-mt7996-firmware kmod-mt7996-233-firmware \
kmod-rtc-pcf8563 kmod-sfp kmod-usb3 e2fsprogs f2fsck mkf2fs
IMAGES := sysupgrade.itb
KERNEL_LOADADDR := 0x46000000
@@ -444,7 +476,7 @@ endef
TARGET_DEVICES += cmcc_rax3000m
define Device/comfast_cf-e393ax
- DEVICE_VENDOR := Comfast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-E393AX
DEVICE_DTS := mt7981a-comfast-cf-e393ax
DEVICE_DTS_DIR := ../dts
@@ -483,6 +515,23 @@ define Device/confiabits_mt7981
endef
TARGET_DEVICES += confiabits_mt7981
+define Device/cudy_ap3000outdoor-v1
+ DEVICE_VENDOR := Cudy
+ DEVICE_MODEL := AP3000 Outdoor
+ DEVICE_VARIANT := v1
+ DEVICE_DTS := mt7981b-cudy-ap3000outdoor-v1
+ DEVICE_DTS_DIR := ../dts
+ SUPPORTED_DEVICES += R51
+ UBINIZE_OPTS := -E 5
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ IMAGE_SIZE := 65536k
+ KERNEL_IN_UBI := 1
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+ DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware
+endef
+TARGET_DEVICES += cudy_ap3000outdoor-v1
+
define Device/cudy_m3000-v1
DEVICE_VENDOR := Cudy
DEVICE_MODEL := M3000
@@ -643,7 +692,11 @@ define Device/glinet_gl-x3000-xe3000-common
DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware mkf2fs \
kmod-fs-f2fs kmod-hwmon-pwmfan kmod-usb3 kmod-usb-serial-option \
kmod-usb-storage kmod-usb-net-qmi-wwan uqmi
+ IMAGES += factory.bin
+ IMAGE/factory.bin := append-kernel | pad-to 32M | append-rootfs
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+ ARTIFACTS := preloader.bin bl31-uboot.fip
+ ARTIFACT/preloader.bin := mt7981-bl2 emmc-ddr4
endef
define Device/glinet_gl-x3000
@@ -651,6 +704,7 @@ define Device/glinet_gl-x3000
DEVICE_DTS := mt7981a-glinet-gl-x3000
SUPPORTED_DEVICES := glinet,gl-x3000
$(call Device/glinet_gl-x3000-xe3000-common)
+ ARTIFACT/bl31-uboot.fip := mt7981-bl31-uboot glinet_gl-x3000
endef
TARGET_DEVICES += glinet_gl-x3000
@@ -659,6 +713,7 @@ define Device/glinet_gl-xe3000
DEVICE_DTS := mt7981a-glinet-gl-xe3000
SUPPORTED_DEVICES := glinet,gl-xe3000
$(call Device/glinet_gl-x3000-xe3000-common)
+ ARTIFACT/bl31-uboot.fip := mt7981-bl31-uboot glinet_gl-xe3000
endef
TARGET_DEVICES += glinet_gl-xe3000
@@ -1085,6 +1140,20 @@ define Device/ruijie_rg-x60-pro
endef
TARGET_DEVICES += ruijie_rg-x60-pro
+define Device/tplink_re6000xd
+ DEVICE_VENDOR := TP-Link
+ DEVICE_MODEL := RE6000XD
+ DEVICE_DTS := mt7986b-tplink-re6000xd
+ DEVICE_DTS_DIR := ../dts
+ DEVICE_PACKAGES := kmod-mt7915e kmod-mt7986-firmware mt7986-wo-firmware
+ UBINIZE_OPTS := -E 5
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ IMAGE_SIZE := 51200k
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+TARGET_DEVICES += tplink_re6000xd
+
define Device/tplink_tl-xdr-common
DEVICE_VENDOR := TP-Link
DEVICE_DTS_DIR := ../dts
@@ -1129,9 +1198,19 @@ define Device/tplink_tl-xdr6088
endef
TARGET_DEVICES += tplink_tl-xdr6088
+define Device/tplink_tl-xtr8488
+ DEVICE_MODEL := TL-XTR8488
+ DEVICE_DTS := mt7986a-tplink-tl-xtr8488
+ $(call Device/tplink_tl-xdr-common)
+ DEVICE_PACKAGES += kmod-mt7915-firmware
+ ARTIFACT/preloader.bin := mt7986-bl2 spim-nand-ddr4
+ ARTIFACT/bl31-uboot.fip := mt7986-bl31-uboot tplink_tl-xtr8488
+endef
+TARGET_DEVICES += tplink_tl-xtr8488
+
define Device/ubnt_unifi-6-plus
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 Plus
+ DEVICE_MODEL := UniFi U6+
DEVICE_DTS := mt7981a-ubnt-unifi-6-plus
DEVICE_DTS_DIR := ../dts
DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware e2fsprogs f2fsck mkf2fs fdisk partx-utils
@@ -1413,7 +1492,7 @@ endef
TARGET_DEVICES += zyxel_ex5601-t0-ubootmod
define Device/zyxel_ex5700-telenor
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := EX5700 (Telenor)
DEVICE_DTS := mt7986a-zyxel-ex5700-telenor
DEVICE_DTS_DIR := ../dts
@@ -1427,7 +1506,7 @@ endef
TARGET_DEVICES += zyxel_ex5700-telenor
define Device/zyxel_nwa50ax-pro
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NWA50AX Pro
DEVICE_DTS := mt7981b-zyxel-nwa50ax-pro
DEVICE_DTS_DIR := ../dts
diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk
index f91720479a..e1d9a09c64 100644
--- a/target/linux/mediatek/image/mt7622.mk
+++ b/target/linux/mediatek/image/mt7622.mk
@@ -328,7 +328,7 @@ TARGET_DEVICES += totolink_a8000ru
define Device/ubnt_unifi-6-lr-v1
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v1
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v1
@@ -340,7 +340,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v1
define Device/ubnt_unifi-6-lr-v1-ubootmod
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v1 U-Boot mod
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v1-ubootmod
DEVICE_DTS_DIR := ../dts
@@ -359,7 +359,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v1-ubootmod
define Device/ubnt_unifi-6-lr-v2
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v2
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v2
@@ -370,7 +370,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v2
define Device/ubnt_unifi-6-lr-v2-ubootmod
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v2 U-Boot mod
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v2-ubootmod
DEVICE_DTS_DIR := ../dts
@@ -388,7 +388,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v2-ubootmod
define Device/ubnt_unifi-6-lr-v3
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v3
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v3
@@ -399,7 +399,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v3
define Device/ubnt_unifi-6-lr-v3-ubootmod
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v3 U-Boot mod
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v3-ubootmod
DEVICE_DTS_DIR := ../dts
diff --git a/target/linux/mediatek/image/mt7629.mk b/target/linux/mediatek/image/mt7629.mk
index 9f0ea98950..57c0a5bc54 100644
--- a/target/linux/mediatek/image/mt7629.mk
+++ b/target/linux/mediatek/image/mt7629.mk
@@ -27,6 +27,22 @@ define Device/iptime_a6004mx
endef
TARGET_DEVICES += iptime_a6004mx
+define Device/linksys_ea7500-v3
+ $(Device/uimage-lzma-loader)
+ DEVICE_VENDOR := Linksys
+ DEVICE_MODEL := EA7500
+ DEVICE_VARIANT := v3
+ DEVICE_DTS := mt7629-linksys-ea7500-v3
+ DEVICE_DTS_DIR := ../dts
+ DEVICE_PACKAGES := kmod-usb3 uboot-envtools
+ IMAGE_SIZE := 40m
+ UBINIZE_OPTS := -E 5
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata | check-size
+endef
+TARGET_DEVICES += linksys_ea7500-v3
+
define Device/netgear_ex6250-v2
DEVICE_VENDOR := NETGEAR
DEVICE_MODEL := EX6250
diff --git a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh
index 59375ccd9b..61025fb380 100755
--- a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh
@@ -12,25 +12,8 @@ platform_do_upgrade() {
ubnt,unifi-6-lr-v2-ubootmod|\
ubnt,unifi-6-lr-v3-ubootmod|\
xiaomi,redmi-router-ax6s)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- bootdev="$(fitblk_get_bootdev)"
- case "$bootdev" in
- mmcblk*)
- EMMC_KERN_DEV="/dev/$bootdev"
- emmc_do_upgrade "$1"
- ;;
- mtdblock*)
- PART_NAME="/dev/mtd${bootdev:8}"
- default_do_upgrade "$1"
- ;;
- ubiblock*)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
- esac
+ fit_do_upgrade "$1"
;;
-
buffalo,wsr-2533dhp2|\
buffalo,wsr-3200ax4s)
local magic="$(get_magic_long "$1")"
@@ -103,7 +86,7 @@ platform_check_image() {
platform_copy_config() {
case "$(board_name)" in
bananapi,bpi-r64)
- if fitblk_get_bootdev | grep -q mmc; then
+ if [ "$CI_METHOD" = "emmc" ]; then
emmc_copy_config
fi
;;
diff --git a/target/linux/mediatek/mt7622/config-6.6 b/target/linux/mediatek/mt7622/config-6.6
index 067dd02d31..cf445b2b71 100644
--- a/target/linux/mediatek/mt7622/config-6.6
+++ b/target/linux/mediatek/mt7622/config-6.6
@@ -164,7 +164,6 @@ CONFIG_EINT_MTK=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
-# CONFIG_FIT_PARTITION is not set
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
@@ -242,7 +241,7 @@ CONFIG_MAXLINEAR_GPHY=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
-# CONFIG_MEDIATEK_2P5G_PHY is not set
+# CONFIG_MEDIATEK_2P5GE_PHY is not set
CONFIG_MEDIATEK_GE_PHY=y
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
CONFIG_MEDIATEK_WATCHDOG=y
diff --git a/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh
index 9cfb15cf3d..bce6709a58 100755
--- a/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh
@@ -1,4 +1,5 @@
REQUIRE_IMAGE_METADATA=1
+RAMFS_COPY_BIN='fitblk'
# Legacy full system upgrade including preloader for MediaTek SoCs on eMMC or SD
legacy_mtk_mmc_full_upgrade() {
@@ -83,11 +84,7 @@ platform_do_upgrade() {
case "$board" in
bananapi,bpi-r2|\
unielec,u7623-02)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- bootdev="$(fitblk_get_bootdev)"
- EMMC_KERN_DEV="/dev/$bootdev"
- emmc_do_upgrade "$1"
+ fit_do_upgrade "$1"
;;
unielec,u7623-02-emmc-512m)
local magic="$(get_magic_long "$1")"
diff --git a/target/linux/mediatek/mt7623/config-6.6 b/target/linux/mediatek/mt7623/config-6.6
index 9d6c5eed96..bb00bee8f3 100644
--- a/target/linux/mediatek/mt7623/config-6.6
+++ b/target/linux/mediatek/mt7623/config-6.6
@@ -224,7 +224,6 @@ CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_SYS_IMAGEBLIT=y
-# CONFIG_FIT_PARTITION is not set
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FONT_8x16=y
diff --git a/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network
index df042f8ad2..875ed34dcc 100644
--- a/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network
+++ b/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network
@@ -8,7 +8,8 @@ mediatek_setup_interfaces()
local board="$1"
case $board in
- iptime,a6004mx)
+ iptime,a6004mx|\
+ linksys,ea7500-v3)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "eth1"
;;
mediatek,mt7629-rfb)
@@ -28,6 +29,11 @@ mediatek_setup_macs()
local board="$1"
case $board in
+ linksys,ea7500-v3)
+ lan_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+ wan_mac=$lan_mac
+ label_mac=$lan_mac
+ ;;
netgear,ex6250-v2)
lan_mac=$(mtd_get_mac_ascii Config mac)
label_mac=$lan_mac
diff --git a/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount b/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount
index a6b8fac1d9..959944fef8 100755
--- a/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount
+++ b/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount
@@ -13,5 +13,8 @@ boot() {
exit 1
fi
;;
+ linksys,ea7500-v3)
+ mtd resetbc s_env || true
+ ;;
esac
}
diff --git a/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh
index f10ad14b49..ebd3678c2e 100755
--- a/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh
@@ -12,6 +12,11 @@ platform_do_upgrade() {
iptime,a6004mx)
nand_do_upgrade "$1"
;;
+ linksys,ea7500-v3)
+ fw_setenv boot_part 1
+ fw_setenv bootimage 1
+ nand_do_upgrade "$1"
+ ;;
*)
default_do_upgrade "$1"
;;
diff --git a/target/linux/mediatek/mt7629/config-6.6 b/target/linux/mediatek/mt7629/config-6.6
index ec029de2fe..1748efab77 100644
--- a/target/linux/mediatek/mt7629/config-6.6
+++ b/target/linux/mediatek/mt7629/config-6.6
@@ -106,7 +106,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EINT_MTK=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-# CONFIG_FIT_PARTITION is not set
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FS_IOMAP=y
diff --git a/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch b/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch
deleted file mode 100644
index 49fc7e638c..0000000000
--- a/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch
+++ /dev/null
@@ -1,216 +0,0 @@
-From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:37:33 +0200
-Subject: [PATCH] kernel: add block fit partition parser
-
----
- block/blk.h | 2 ++
- block/partitions/Kconfig | 7 +++++++
- block/partitions/Makefile | 1 +
- block/partitions/check.h | 3 +++
- block/partitions/core.c | 17 +++++++++++++++++
- block/partitions/efi.c | 8 ++++++++
- block/partitions/efi.h | 3 +++
- block/partitions/msdos.c | 10 ++++++++++
- drivers/mtd/mtd_blkdevs.c | 2 ++
- drivers/mtd/ubi/block.c | 3 +++
- include/linux/msdos_partition.h | 1 +
- 11 files changed, 57 insertions(+)
-
---- a/block/blk.h
-+++ b/block/blk.h
-@@ -424,6 +424,8 @@ void blk_free_ext_minor(unsigned int min
- #define ADDPART_FLAG_NONE 0
- #define ADDPART_FLAG_RAID 1
- #define ADDPART_FLAG_WHOLEDISK 2
-+#define ADDPART_FLAG_READONLY 4
-+#define ADDPART_FLAG_ROOTDEV 8
- int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
- sector_t length);
- int bdev_del_partition(struct gendisk *disk, int partno);
---- a/block/partitions/Kconfig
-+++ b/block/partitions/Kconfig
-@@ -103,6 +103,13 @@ config ATARI_PARTITION
- Say Y here if you would like to use hard disks under Linux which
- were partitioned under the Atari OS.
-
-+config FIT_PARTITION
-+ bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
-+ default n
-+ help
-+ Say Y here if your system needs to mount the filesystem part of
-+ a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
-+
- config IBM_PARTITION
- bool "IBM disk label and partition support"
- depends on PARTITION_ADVANCED && S390
---- a/block/partitions/Makefile
-+++ b/block/partitions/Makefile
-@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
- obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
- obj-$(CONFIG_ATARI_PARTITION) += atari.o
- obj-$(CONFIG_AIX_PARTITION) += aix.o
-+obj-$(CONFIG_FIT_PARTITION) += fit.o
- obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
- obj-$(CONFIG_MAC_PARTITION) += mac.o
- obj-$(CONFIG_LDM_PARTITION) += ldm.o
---- a/block/partitions/check.h
-+++ b/block/partitions/check.h
-@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partit
- int atari_partition(struct parsed_partitions *state);
- int cmdline_partition(struct parsed_partitions *state);
- int efi_partition(struct parsed_partitions *state);
-+int fit_partition(struct parsed_partitions *state);
- int ibm_partition(struct parsed_partitions *);
- int karma_partition(struct parsed_partitions *state);
- int ldm_partition(struct parsed_partitions *state);
-@@ -67,3 +68,5 @@ int sgi_partition(struct parsed_partitio
- int sun_partition(struct parsed_partitions *state);
- int sysv68_partition(struct parsed_partitions *state);
- int ultrix_partition(struct parsed_partitions *state);
-+
-+int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
---- a/block/partitions/core.c
-+++ b/block/partitions/core.c
-@@ -11,6 +11,9 @@
- #include <linux/vmalloc.h>
- #include <linux/raid/detect.h>
- #include <linux/property.h>
-+#ifdef CONFIG_FIT_PARTITION
-+#include <linux/root_dev.h>
-+#endif
-
- #include "check.h"
-
-@@ -48,6 +51,9 @@ static int (*const check_part[])(struct
- #ifdef CONFIG_EFI_PARTITION
- efi_partition, /* this must come before msdos */
- #endif
-+#ifdef CONFIG_FIT_PARTITION
-+ fit_partition,
-+#endif
- #ifdef CONFIG_SGI_PARTITION
- sgi_partition,
- #endif
-@@ -430,6 +436,11 @@ static struct block_device *add_partitio
- goto out_del;
- }
-
-+#ifdef CONFIG_FIT_PARTITION
-+ if (flags & ADDPART_FLAG_READONLY)
-+ bdev->bd_read_only = true;
-+#endif
-+
- /* everything is up and running, commence */
- err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
- if (err)
-@@ -622,6 +633,11 @@ static bool blk_add_partition(struct gen
- (state->parts[p].flags & ADDPART_FLAG_RAID))
- md_autodetect_dev(part->bd_dev);
-
-+#ifdef CONFIG_FIT_PARTITION
-+ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0)
-+ ROOT_DEV = part->bd_dev;
-+#endif
-+
- return true;
- }
-
---- a/block/partitions/efi.c
-+++ b/block/partitions/efi.c
-@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio
- gpt_entry *ptes = NULL;
- u32 i;
- unsigned ssz = queue_logical_block_size(state->disk->queue) / 512;
-+#ifdef CONFIG_FIT_PARTITION
-+ u32 extra_slot = 64;
-+#endif
-
- if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
- kfree(gpt);
-@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio
- ARRAY_SIZE(ptes[i].partition_name));
- utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
- state->parts[i + 1].has_info = true;
-+#ifdef CONFIG_FIT_PARTITION
-+ /* If this is a U-Boot FIT volume it may have subpartitions */
-+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
-+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
-+#endif
- }
- kfree(ptes);
- kfree(gpt);
---- a/block/partitions/efi.h
-+++ b/block/partitions/efi.h
-@@ -51,6 +51,9 @@
- #define PARTITION_LINUX_LVM_GUID \
- EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
- 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
-+#define PARTITION_LINUX_FIT_GUID \
-+ EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
-+ 0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
-
- typedef struct _gpt_header {
- __le64 signature;
---- a/block/partitions/msdos.c
-+++ b/block/partitions/msdos.c
-@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa
- #endif /* CONFIG_MINIX_SUBPARTITION */
- }
-
-+static void parse_fit_mbr(struct parsed_partitions *state,
-+ sector_t offset, sector_t size, int origin)
-+{
-+#ifdef CONFIG_FIT_PARTITION
-+ u32 extra_slot = 64;
-+ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1);
-+#endif /* CONFIG_FIT_PARTITION */
-+}
-+
- static struct {
- unsigned char id;
- void (*parse)(struct parsed_partitions *, sector_t, sector_t, int);
-@@ -575,6 +584,7 @@ static struct {
- {UNIXWARE_PARTITION, parse_unixware},
- {SOLARIS_X86_PARTITION, parse_solaris_x86},
- {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
-+ {FIT_PARTITION, parse_fit_mbr},
- {0, NULL},
- };
-
---- a/drivers/mtd/mtd_blkdevs.c
-+++ b/drivers/mtd/mtd_blkdevs.c
-@@ -359,7 +359,9 @@ int add_mtd_blktrans_dev(struct mtd_blkt
- } else {
- snprintf(gd->disk_name, sizeof(gd->disk_name),
- "%s%d", tr->name, new->devnum);
-- gd->flags |= GENHD_FL_NO_PART;
-+
-+ if (!IS_ENABLED(CONFIG_FIT_PARTITION) || mtd_type_is_nand(new->mtd))
-+ gd->flags |= GENHD_FL_NO_PART;
- }
-
- set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -410,7 +410,9 @@ int ubiblock_create(struct ubi_volume_in
- ret = -ENODEV;
- goto out_cleanup_disk;
- }
-- gd->flags |= GENHD_FL_NO_PART;
-+ if (!IS_ENABLED(CONFIG_FIT_PARTITION))
-+ gd->flags |= GENHD_FL_NO_PART;
-+
- gd->private_data = dev;
- sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
- set_capacity(gd, disk_capacity);
---- a/include/linux/msdos_partition.h
-+++ b/include/linux/msdos_partition.h
-@@ -31,6 +31,7 @@ enum msdos_sys_ind {
- LINUX_LVM_PARTITION = 0x8e,
- LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */
-
-+ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */
- SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */
- NEW_SOLARIS_X86_PARTITION = 0xbf,
-
diff --git a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch
index 8a4ec2bcbd..de8e880643 100644
--- a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch
+++ b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch
@@ -8,7 +8,7 @@
static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
{
-@@ -1345,6 +1346,7 @@ static int spinand_probe(struct spi_mem
+@@ -1346,6 +1347,7 @@ static int spinand_probe(struct spi_mem
if (ret)
return ret;
@@ -16,7 +16,7 @@
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
goto err_spinand_cleanup;
-@@ -1352,6 +1354,7 @@ static int spinand_probe(struct spi_mem
+@@ -1353,6 +1355,7 @@ static int spinand_probe(struct spi_mem
return 0;
err_spinand_cleanup:
@@ -24,7 +24,7 @@
spinand_cleanup(spinand);
return ret;
-@@ -1370,6 +1373,7 @@ static int spinand_remove(struct spi_mem
+@@ -1371,6 +1374,7 @@ static int spinand_remove(struct spi_mem
if (ret)
return ret;
diff --git a/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch b/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch
index fbaac13b64..499918f365 100644
--- a/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch
+++ b/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch
@@ -51,11 +51,12 @@ Signed-off-by: Sam Shih <sam.shih@mediatek.com>
static const struct mtk_cpufreq_platform_data mt8183_platform_data = {
.min_volt_shift = 100000,
.max_volt_shift = 200000,
-@@ -740,6 +749,7 @@ static const struct of_device_id mtk_cpu
+@@ -740,6 +749,8 @@ static const struct of_device_id mtk_cpu
{ .compatible = "mediatek,mt2712", .data = &mt2701_platform_data },
{ .compatible = "mediatek,mt7622", .data = &mt7622_platform_data },
{ .compatible = "mediatek,mt7623", .data = &mt7623_platform_data },
+ { .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data },
++ { .compatible = "mediatek,mt7988d", .data = &mt7988_platform_data },
{ .compatible = "mediatek,mt8167", .data = &mt8516_platform_data },
{ .compatible = "mediatek,mt817x", .data = &mt2701_platform_data },
{ .compatible = "mediatek,mt8173", .data = &mt2701_platform_data },
diff --git a/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch b/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch
index 1fcb1e64c7..fb65adb011 100644
--- a/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch
+++ b/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch
@@ -31,8 +31,8 @@
static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
-@@ -755,6 +779,12 @@ int mtk_pinconf_bias_set_combo(struct mt
- return err;
+@@ -758,6 +782,12 @@ int mtk_pinconf_bias_set_combo(struct mt
+ return 0;
}
+ if (try_all_type & MTK_PULL_PD_TYPE) {
@@ -44,7 +44,7 @@
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
if (!err)
-@@ -875,6 +905,29 @@ out:
+@@ -878,6 +908,29 @@ out:
return err;
}
@@ -74,19 +74,19 @@
static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
-@@ -943,6 +996,12 @@ int mtk_pinconf_bias_get_combo(struct mt
- if (!err)
- return err;
+@@ -947,6 +1000,12 @@ int mtk_pinconf_bias_get_combo(struct mt
+ return 0;
}
-+
+
+ if (try_all_type & MTK_PULL_PD_TYPE) {
+ err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable);
+ if (!err)
+ return err;
+ }
-
++
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+ if (!err)
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -24,6 +24,7 @@
diff --git a/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch b/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch
index 7ad07c3583..19fe984aa6 100644
--- a/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch
+++ b/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch
@@ -224,7 +224,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
/*
-@@ -1600,6 +1639,9 @@ spi_register_board_info(struct spi_board
+@@ -1601,6 +1640,9 @@ spi_register_board_info(struct spi_board
{ return 0; }
#endif
diff --git a/target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch b/target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch
index 80179cc7dc..99d0a0dbc2 100644
--- a/target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch
+++ b/target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch
@@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/drivers/net/phy/mxl-gpy.c
+++ b/drivers/net/phy/mxl-gpy.c
-@@ -386,8 +386,11 @@ static bool gpy_2500basex_chk(struct phy
+@@ -385,8 +385,11 @@ static bool gpy_2500basex_chk(struct phy
phydev->speed = SPEED_2500;
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
@@ -28,7 +28,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
return true;
}
-@@ -438,6 +441,14 @@ static int gpy_config_aneg(struct phy_de
+@@ -437,6 +440,14 @@ static int gpy_config_aneg(struct phy_de
u32 adv;
int ret;
@@ -43,7 +43,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
if (phydev->autoneg == AUTONEG_DISABLE) {
/* Configure half duplex with genphy_setup_forced,
* because genphy_c45_pma_setup_forced does not support.
-@@ -560,6 +571,8 @@ static int gpy_update_interface(struct p
+@@ -559,6 +570,8 @@ static int gpy_update_interface(struct p
switch (phydev->speed) {
case SPEED_2500:
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
@@ -52,7 +52,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
VSPEC1_SGMII_CTRL_ANEN, 0);
if (ret < 0) {
-@@ -573,7 +586,7 @@ static int gpy_update_interface(struct p
+@@ -572,7 +585,7 @@ static int gpy_update_interface(struct p
case SPEED_100:
case SPEED_10:
phydev->interface = PHY_INTERFACE_MODE_SGMII;
diff --git a/target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch b/target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch
new file mode 100644
index 0000000000..3ec756bb4b
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch
@@ -0,0 +1,3513 @@
+From c14e7c954fd752fbb3da17a8bcf65cd9dbf41186 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:05 +0800
+Subject: [PATCH 01/13] net: phy: mediatek: Re-organize MediaTek ethernet phy
+ drivers
+
+Re-organize MediaTek ethernet phy driver files and get ready to integrate
+some common functions and add new 2.5G phy driver.
+mtk-ge.c: MT7530 Gphy on MT7621 & MT7531 Gphy
+mtk-ge-soc.c: Built-in Gphy on MT7981 & Built-in switch Gphy on MT7988
+mtk-2p5ge.c: Planned for built-in 2.5G phy on MT7988
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/Kconfig | 17 +-------------
+ drivers/net/phy/Makefile | 3 +--
+ drivers/net/phy/mediatek/Kconfig | 22 +++++++++++++++++++
+ drivers/net/phy/mediatek/Makefile | 3 +++
+ .../mtk-ge-soc.c} | 0
+ .../phy/{mediatek-ge.c => mediatek/mtk-ge.c} | 0
+ 7 files changed, 29 insertions(+), 20 deletions(-)
+ create mode 100644 drivers/net/phy/mediatek/Kconfig
+ create mode 100644 drivers/net/phy/mediatek/Makefile
+ rename drivers/net/phy/{mediatek-ge-soc.c => mediatek/mtk-ge-soc.c} (100%)
+ rename drivers/net/phy/{mediatek-ge.c => mediatek/mtk-ge.c} (100%)
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -313,22 +313,7 @@ config MAXLINEAR_GPHY
+ Support for the Maxlinear GPY115, GPY211, GPY212, GPY215,
+ GPY241, GPY245 PHYs.
+
+-config MEDIATEK_GE_PHY
+- tristate "MediaTek Gigabit Ethernet PHYs"
+- help
+- Supports the MediaTek Gigabit Ethernet PHYs.
+-
+-config MEDIATEK_GE_SOC_PHY
+- tristate "MediaTek SoC Ethernet PHYs"
+- depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
+- depends on NVMEM_MTK_EFUSE
+- help
+- Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
+-
+- Include support for built-in Ethernet PHYs which are present in
+- the MT7981 and MT7988 SoCs. These PHYs need calibration data
+- present in the SoCs efuse and will dynamically calibrate VCM
+- (common-mode voltage) during startup.
++source "drivers/net/phy/mediatek/Kconfig"
+
+ config MICREL_PHY
+ tristate "Micrel PHYs"
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -82,8 +82,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
+ obj-$(CONFIG_MARVELL_88Q2XXX_PHY) += marvell-88q2xxx.o
+ obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o
+ obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o
+-obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
+-obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
++obj-y += mediatek/
+ obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
+ obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
+ obj-$(CONFIG_MICREL_PHY) += micrel.o
+--- /dev/null
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -0,0 +1,22 @@
++# SPDX-License-Identifier: GPL-2.0-only
++config MEDIATEK_GE_PHY
++ tristate "MediaTek Gigabit Ethernet PHYs"
++ help
++ Supports the MediaTek non-built-in Gigabit Ethernet PHYs.
++
++ Non-built-in Gigabit Ethernet PHYs include mt7530/mt7531.
++ You may find mt7530 inside mt7621. This driver shares some
++ common operations with MediaTek SoC built-in Gigabit
++ Ethernet PHYs.
++
++config MEDIATEK_GE_SOC_PHY
++ tristate "MediaTek SoC Ethernet PHYs"
++ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
++ select NVMEM_MTK_EFUSE
++ help
++ Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
++
++ Include support for built-in Ethernet PHYs which are present in
++ the MT7981 and MT7988 SoCs. These PHYs need calibration data
++ present in the SoCs efuse and will dynamically calibrate VCM
++ (common-mode voltage) during startup.
+--- /dev/null
++++ b/drivers/net/phy/mediatek/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o
++obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o
+--- a/drivers/net/phy/mediatek-ge-soc.c
++++ /dev/null
+@@ -1,1555 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0+
+-#include <linux/bitfield.h>
+-#include <linux/bitmap.h>
+-#include <linux/mfd/syscon.h>
+-#include <linux/module.h>
+-#include <linux/nvmem-consumer.h>
+-#include <linux/pinctrl/consumer.h>
+-#include <linux/phy.h>
+-#include <linux/regmap.h>
+-
+-#define MTK_GPHY_ID_MT7981 0x03a29461
+-#define MTK_GPHY_ID_MT7988 0x03a29481
+-
+-#define MTK_EXT_PAGE_ACCESS 0x1f
+-#define MTK_PHY_PAGE_STANDARD 0x0000
+-#define MTK_PHY_PAGE_EXTENDED_3 0x0003
+-
+-#define MTK_PHY_LPI_REG_14 0x14
+-#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK GENMASK(8, 0)
+-
+-#define MTK_PHY_LPI_REG_1c 0x1c
+-#define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8)
+-
+-#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+-
+-#define ANALOG_INTERNAL_OPERATION_MAX_US 20
+-#define TXRESERVE_MIN 0
+-#define TXRESERVE_MAX 7
+-
+-#define MTK_PHY_ANARG_RG 0x10
+-#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
+-
+-/* Registers on MDIO_MMD_VEND1 */
+-#define MTK_PHY_TXVLD_DA_RG 0x12
+-#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
+-#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 0x16
+-#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
+-#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 0x17
+-#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 0x18
+-#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 0x19
+-#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 0x20
+-#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 0x21
+-#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 0x22
+-#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_RXADC_CTRL_RG7 0xc6
+-#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
+-
+-#define MTK_PHY_RXADC_CTRL_RG9 0xc8
+-#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
+-#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
+-#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
+-#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
+-
+-#define MTK_PHY_LDO_OUTPUT_V 0xd7
+-
+-#define MTK_PHY_RG_ANA_CAL_RG0 0xdb
+-#define MTK_PHY_RG_CAL_CKINV BIT(12)
+-#define MTK_PHY_RG_ANA_CALEN BIT(8)
+-#define MTK_PHY_RG_ZCALEN_A BIT(0)
+-
+-#define MTK_PHY_RG_ANA_CAL_RG1 0xdc
+-#define MTK_PHY_RG_ZCALEN_B BIT(12)
+-#define MTK_PHY_RG_ZCALEN_C BIT(8)
+-#define MTK_PHY_RG_ZCALEN_D BIT(4)
+-#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
+-
+-#define MTK_PHY_RG_ANA_CAL_RG5 0xe0
+-#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
+-
+-#define MTK_PHY_RG_TX_FILTER 0xfe
+-
+-#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120 0x120
+-#define MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK GENMASK(12, 8)
+-#define MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK GENMASK(4, 0)
+-
+-#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122 0x122
+-#define MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK GENMASK(7, 0)
+-
+-#define MTK_PHY_RG_TESTMUX_ADC_CTRL 0x144
+-#define MTK_PHY_RG_TXEN_DIG_MASK GENMASK(5, 5)
+-
+-#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B 0x172
+-#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
+-#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
+-
+-#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D 0x173
+-#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
+-#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
+-
+-#define MTK_PHY_RG_AD_CAL_COMP 0x17a
+-#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
+-
+-#define MTK_PHY_RG_AD_CAL_CLK 0x17b
+-#define MTK_PHY_DA_CAL_CLK BIT(0)
+-
+-#define MTK_PHY_RG_AD_CALIN 0x17c
+-#define MTK_PHY_DA_CALIN_FLAG BIT(0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_A 0x17d
+-#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_B 0x17e
+-#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_C 0x17f
+-#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_D 0x180
+-#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_A 0x181
+-#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_B 0x182
+-#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_C 0x183
+-#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_D 0x184
+-#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DEV1E_REG19b 0x19b
+-#define MTK_PHY_BYPASS_DSP_LPI_READY BIT(8)
+-
+-#define MTK_PHY_RG_LP_IIR2_K1_L 0x22a
+-#define MTK_PHY_RG_LP_IIR2_K1_U 0x22b
+-#define MTK_PHY_RG_LP_IIR2_K2_L 0x22c
+-#define MTK_PHY_RG_LP_IIR2_K2_U 0x22d
+-#define MTK_PHY_RG_LP_IIR2_K3_L 0x22e
+-#define MTK_PHY_RG_LP_IIR2_K3_U 0x22f
+-#define MTK_PHY_RG_LP_IIR2_K4_L 0x230
+-#define MTK_PHY_RG_LP_IIR2_K4_U 0x231
+-#define MTK_PHY_RG_LP_IIR2_K5_L 0x232
+-#define MTK_PHY_RG_LP_IIR2_K5_U 0x233
+-
+-#define MTK_PHY_RG_DEV1E_REG234 0x234
+-#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
+-#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
+-#define MTK_PHY_TR_LP_IIR_EEE_EN BIT(12)
+-
+-#define MTK_PHY_RG_LPF_CNT_VAL 0x235
+-
+-#define MTK_PHY_RG_DEV1E_REG238 0x238
+-#define MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK GENMASK(8, 0)
+-#define MTK_PHY_LPI_SLV_SEND_TX_EN BIT(12)
+-
+-#define MTK_PHY_RG_DEV1E_REG239 0x239
+-#define MTK_PHY_LPI_SEND_LOC_TIMER_MASK GENMASK(8, 0)
+-#define MTK_PHY_LPI_TXPCS_LOC_RCV BIT(12)
+-
+-#define MTK_PHY_RG_DEV1E_REG27C 0x27c
+-#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
+-#define MTK_PHY_RG_DEV1E_REG27D 0x27d
+-#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
+-
+-#define MTK_PHY_RG_DEV1E_REG2C7 0x2c7
+-#define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0)
+-#define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8)
+-
+-#define MTK_PHY_RG_DEV1E_REG2D1 0x2d1
+-#define MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK GENMASK(7, 0)
+-#define MTK_PHY_LPI_SKIP_SD_SLV_TR BIT(8)
+-#define MTK_PHY_LPI_TR_READY BIT(9)
+-#define MTK_PHY_LPI_VCO_EEE_STG0_EN BIT(10)
+-
+-#define MTK_PHY_RG_DEV1E_REG323 0x323
+-#define MTK_PHY_EEE_WAKE_MAS_INT_DC BIT(0)
+-#define MTK_PHY_EEE_WAKE_SLV_INT_DC BIT(4)
+-
+-#define MTK_PHY_RG_DEV1E_REG324 0x324
+-#define MTK_PHY_SMI_DETCNT_MAX_MASK GENMASK(5, 0)
+-#define MTK_PHY_SMI_DET_MAX_EN BIT(8)
+-
+-#define MTK_PHY_RG_DEV1E_REG326 0x326
+-#define MTK_PHY_LPI_MODE_SD_ON BIT(0)
+-#define MTK_PHY_RESET_RANDUPD_CNT BIT(1)
+-#define MTK_PHY_TREC_UPDATE_ENAB_CLR BIT(2)
+-#define MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF BIT(4)
+-#define MTK_PHY_TR_READY_SKIP_AFE_WAKEUP BIT(5)
+-
+-#define MTK_PHY_LDO_PUMP_EN_PAIRAB 0x502
+-#define MTK_PHY_LDO_PUMP_EN_PAIRCD 0x503
+-
+-#define MTK_PHY_DA_TX_R50_PAIR_A 0x53d
+-#define MTK_PHY_DA_TX_R50_PAIR_B 0x53e
+-#define MTK_PHY_DA_TX_R50_PAIR_C 0x53f
+-#define MTK_PHY_DA_TX_R50_PAIR_D 0x540
+-
+-/* Registers on MDIO_MMD_VEND2 */
+-#define MTK_PHY_LED0_ON_CTRL 0x24
+-#define MTK_PHY_LED1_ON_CTRL 0x26
+-#define MTK_PHY_LED_ON_MASK GENMASK(6, 0)
+-#define MTK_PHY_LED_ON_LINK1000 BIT(0)
+-#define MTK_PHY_LED_ON_LINK100 BIT(1)
+-#define MTK_PHY_LED_ON_LINK10 BIT(2)
+-#define MTK_PHY_LED_ON_LINK (MTK_PHY_LED_ON_LINK10 |\
+- MTK_PHY_LED_ON_LINK100 |\
+- MTK_PHY_LED_ON_LINK1000)
+-#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
+-#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
+-#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
+-#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
+-#define MTK_PHY_LED_ON_POLARITY BIT(14)
+-#define MTK_PHY_LED_ON_ENABLE BIT(15)
+-
+-#define MTK_PHY_LED0_BLINK_CTRL 0x25
+-#define MTK_PHY_LED1_BLINK_CTRL 0x27
+-#define MTK_PHY_LED_BLINK_1000TX BIT(0)
+-#define MTK_PHY_LED_BLINK_1000RX BIT(1)
+-#define MTK_PHY_LED_BLINK_100TX BIT(2)
+-#define MTK_PHY_LED_BLINK_100RX BIT(3)
+-#define MTK_PHY_LED_BLINK_10TX BIT(4)
+-#define MTK_PHY_LED_BLINK_10RX BIT(5)
+-#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\
+- MTK_PHY_LED_BLINK_100RX |\
+- MTK_PHY_LED_BLINK_1000RX)
+-#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\
+- MTK_PHY_LED_BLINK_100TX |\
+- MTK_PHY_LED_BLINK_1000TX)
+-#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
+-#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
+-#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
+-#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
+-
+-#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1)
+-
+-#define MTK_PHY_RG_BG_RASEL 0x115
+-#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
+-
+-/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
+-#define RG_GPIO_MISC_TPBANK0 0x6f0
+-#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8)
+-
+-/* These macro privides efuse parsing for internal phy. */
+-#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
+-#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
+-#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
+-#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
+-#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
+-
+-#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
+-#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
+-#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
+-#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
+-#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
+-
+-#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
+-#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
+-
+-#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
+-#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
+-
+-enum {
+- NO_PAIR,
+- PAIR_A,
+- PAIR_B,
+- PAIR_C,
+- PAIR_D,
+-};
+-
+-enum calibration_mode {
+- EFUSE_K,
+- SW_K
+-};
+-
+-enum CAL_ITEM {
+- REXT,
+- TX_OFFSET,
+- TX_AMP,
+- TX_R50,
+- TX_VCM
+-};
+-
+-enum CAL_MODE {
+- EFUSE_M,
+- SW_M
+-};
+-
+-#define MTK_PHY_LED_STATE_FORCE_ON 0
+-#define MTK_PHY_LED_STATE_FORCE_BLINK 1
+-#define MTK_PHY_LED_STATE_NETDEV 2
+-
+-struct mtk_socphy_priv {
+- unsigned long led_state;
+-};
+-
+-struct mtk_socphy_shared {
+- u32 boottrap;
+- struct mtk_socphy_priv priv[4];
+-};
+-
+-static int mtk_socphy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_socphy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+-/* One calibration cycle consists of:
+- * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
+- * until AD_CAL_COMP is ready to output calibration result.
+- * 2.Wait until DA_CAL_CLK is available.
+- * 3.Fetch AD_CAL_COMP_OUT.
+- */
+-static int cal_cycle(struct phy_device *phydev, int devad,
+- u32 regnum, u16 mask, u16 cal_val)
+-{
+- int reg_val;
+- int ret;
+-
+- phy_modify_mmd(phydev, devad, regnum,
+- mask, cal_val);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+- MTK_PHY_DA_CALIN_FLAG);
+-
+- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_AD_CAL_CLK, reg_val,
+- reg_val & MTK_PHY_DA_CAL_CLK, 500,
+- ANALOG_INTERNAL_OPERATION_MAX_US, false);
+- if (ret) {
+- phydev_err(phydev, "Calibration cycle timeout\n");
+- return ret;
+- }
+-
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+- MTK_PHY_DA_CALIN_FLAG);
+- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
+- MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
+- phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
+-
+- return ret;
+-}
+-
+-static int rext_fill_result(struct phy_device *phydev, u16 *buf)
+-{
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
+- MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
+- MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
+-
+- return 0;
+-}
+-
+-static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
+-{
+- u16 rext_cal_val[2];
+-
+- rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
+- rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
+- rext_fill_result(phydev, rext_cal_val);
+-
+- return 0;
+-}
+-
+-static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
+-{
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
+- MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
+- MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
+- MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
+- MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
+-
+- return 0;
+-}
+-
+-static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
+-{
+- u16 tx_offset_cal_val[4];
+-
+- tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
+- tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
+- tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
+- tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
+-
+- tx_offset_fill_result(phydev, tx_offset_cal_val);
+-
+- return 0;
+-}
+-
+-static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
+-{
+- int i;
+- int bias[16] = {};
+- const int vals_9461[16] = { 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7 };
+- const int vals_9481[16] = { 10, 6, 6, 10,
+- 10, 6, 6, 10,
+- 10, 6, 6, 10,
+- 10, 6, 6, 10 };
+- switch (phydev->drv->phy_id) {
+- case MTK_GPHY_ID_MT7981:
+- /* We add some calibration to efuse values
+- * due to board level influence.
+- * GBE: +7, TBT: +1, HBT: +4, TST: +7
+- */
+- memcpy(bias, (const void *)vals_9461, sizeof(bias));
+- break;
+- case MTK_GPHY_ID_MT7988:
+- memcpy(bias, (const void *)vals_9481, sizeof(bias));
+- break;
+- }
+-
+- /* Prevent overflow */
+- for (i = 0; i < 12; i++) {
+- if (buf[i >> 2] + bias[i] > 63) {
+- buf[i >> 2] = 63;
+- bias[i] = 0;
+- }
+- }
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+- MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+- MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+- MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+- MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+- MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+- MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+- MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+- MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+- MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+- MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+- MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+- MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+- MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+- MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+- MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+- MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
+-
+- return 0;
+-}
+-
+-static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
+-{
+- u16 tx_amp_cal_val[4];
+-
+- tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
+- tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
+- tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
+- tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
+- tx_amp_fill_result(phydev, tx_amp_cal_val);
+-
+- return 0;
+-}
+-
+-static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
+- u8 txg_calen_x)
+-{
+- int bias = 0;
+- u16 reg, val;
+-
+- if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
+- bias = -1;
+-
+- val = clamp_val(bias + tx_r50_cal_val, 0, 63);
+-
+- switch (txg_calen_x) {
+- case PAIR_A:
+- reg = MTK_PHY_DA_TX_R50_PAIR_A;
+- break;
+- case PAIR_B:
+- reg = MTK_PHY_DA_TX_R50_PAIR_B;
+- break;
+- case PAIR_C:
+- reg = MTK_PHY_DA_TX_R50_PAIR_C;
+- break;
+- case PAIR_D:
+- reg = MTK_PHY_DA_TX_R50_PAIR_D;
+- break;
+- default:
+- return -EINVAL;
+- }
+-
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
+-
+- return 0;
+-}
+-
+-static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
+- u8 txg_calen_x)
+-{
+- u16 tx_r50_cal_val;
+-
+- switch (txg_calen_x) {
+- case PAIR_A:
+- tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
+- break;
+- case PAIR_B:
+- tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
+- break;
+- case PAIR_C:
+- tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
+- break;
+- case PAIR_D:
+- tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
+- break;
+- default:
+- return -EINVAL;
+- }
+- tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
+-
+- return 0;
+-}
+-
+-static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
+-{
+- u8 lower_idx, upper_idx, txreserve_val;
+- u8 lower_ret, upper_ret;
+- int ret;
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ANA_CALEN);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_CAL_CKINV);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_TXVOS_CALEN);
+-
+- switch (rg_txreserve_x) {
+- case PAIR_A:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_A,
+- MTK_PHY_DASN_DAC_IN0_A_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_A,
+- MTK_PHY_DASN_DAC_IN1_A_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ZCALEN_A);
+- break;
+- case PAIR_B:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_B,
+- MTK_PHY_DASN_DAC_IN0_B_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_B,
+- MTK_PHY_DASN_DAC_IN1_B_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_B);
+- break;
+- case PAIR_C:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_C,
+- MTK_PHY_DASN_DAC_IN0_C_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_C,
+- MTK_PHY_DASN_DAC_IN1_C_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_C);
+- break;
+- case PAIR_D:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_D,
+- MTK_PHY_DASN_DAC_IN0_D_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_D,
+- MTK_PHY_DASN_DAC_IN1_D_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_D);
+- break;
+- default:
+- ret = -EINVAL;
+- goto restore;
+- }
+-
+- lower_idx = TXRESERVE_MIN;
+- upper_idx = TXRESERVE_MAX;
+-
+- phydev_dbg(phydev, "Start TX-VCM SW cal.\n");
+- while ((upper_idx - lower_idx) > 1) {
+- txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
+- ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- txreserve_val << 12 | txreserve_val << 8 |
+- txreserve_val << 4 | txreserve_val);
+- if (ret == 1) {
+- upper_idx = txreserve_val;
+- upper_ret = ret;
+- } else if (ret == 0) {
+- lower_idx = txreserve_val;
+- lower_ret = ret;
+- } else {
+- goto restore;
+- }
+- }
+-
+- if (lower_idx == TXRESERVE_MIN) {
+- lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- lower_idx << 12 | lower_idx << 8 |
+- lower_idx << 4 | lower_idx);
+- ret = lower_ret;
+- } else if (upper_idx == TXRESERVE_MAX) {
+- upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- upper_idx << 12 | upper_idx << 8 |
+- upper_idx << 4 | upper_idx);
+- ret = upper_ret;
+- }
+- if (ret < 0)
+- goto restore;
+-
+- /* We calibrate TX-VCM in different logic. Check upper index and then
+- * lower index. If this calibration is valid, apply lower index's result.
+- */
+- ret = upper_ret - lower_ret;
+- if (ret == 1) {
+- ret = 0;
+- /* Make sure we use upper_idx in our calibration system */
+- cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- upper_idx << 12 | upper_idx << 8 |
+- upper_idx << 4 | upper_idx);
+- phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
+- } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
+- lower_ret == 1) {
+- ret = 0;
+- cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- lower_idx << 12 | lower_idx << 8 |
+- lower_idx << 4 | lower_idx);
+- phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",
+- lower_idx);
+- } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
+- lower_ret == 0) {
+- ret = 0;
+- phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
+- upper_idx);
+- } else {
+- ret = -EINVAL;
+- }
+-
+-restore:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ANA_CALEN);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_TXVOS_CALEN);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ZCALEN_A);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
+- MTK_PHY_RG_ZCALEN_D);
+-
+- return ret;
+-}
+-
+-static void mt798x_phy_common_finetune(struct phy_device *phydev)
+-{
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
+- __phy_write(phydev, 0x11, 0xc71);
+- __phy_write(phydev, 0x12, 0xc);
+- __phy_write(phydev, 0x10, 0x8fae);
+-
+- /* EnabRandUpdTrig = 1 */
+- __phy_write(phydev, 0x11, 0x2f00);
+- __phy_write(phydev, 0x12, 0xe);
+- __phy_write(phydev, 0x10, 0x8fb0);
+-
+- /* NormMseLoThresh = 85 */
+- __phy_write(phydev, 0x11, 0x55a0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x83aa);
+-
+- /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
+- __phy_write(phydev, 0x11, 0x240);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9680);
+-
+- /* TrFreeze = 0 (mt7988 default) */
+- __phy_write(phydev, 0x11, 0x0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9686);
+-
+- /* SSTrKp100 = 5 */
+- /* SSTrKf100 = 6 */
+- /* SSTrKp1000Mas = 5 */
+- /* SSTrKf1000Mas = 6 */
+- /* SSTrKp1000Slv = 5 */
+- /* SSTrKf1000Slv = 6 */
+- __phy_write(phydev, 0x11, 0xbaef);
+- __phy_write(phydev, 0x12, 0x2e);
+- __phy_write(phydev, 0x10, 0x968c);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-}
+-
+-static void mt7981_phy_finetune(struct phy_device *phydev)
+-{
+- u16 val[8] = { 0x01ce, 0x01c1,
+- 0x020f, 0x0202,
+- 0x03d0, 0x03c0,
+- 0x0013, 0x0005 };
+- int i, k;
+-
+- /* 100M eye finetune:
+- * Keep middle level of TX MLT3 shapper as default.
+- * Only change TX MLT3 overshoot level here.
+- */
+- for (k = 0, i = 1; i < 12; i++) {
+- if (i % 3 == 0)
+- continue;
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
+- }
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 6 */
+- __phy_write(phydev, 0x11, 0x600);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
+-
+- /* VgaDecRate = 1 */
+- __phy_write(phydev, 0x11, 0x4c2a);
+- __phy_write(phydev, 0x12, 0x3e);
+- __phy_write(phydev, 0x10, 0x8fa4);
+-
+- /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
+- * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
+- */
+- __phy_write(phydev, 0x11, 0xd10a);
+- __phy_write(phydev, 0x12, 0x34);
+- __phy_write(phydev, 0x10, 0x8f82);
+-
+- /* VcoSlicerThreshBitsHigh */
+- __phy_write(phydev, 0x11, 0x5555);
+- __phy_write(phydev, 0x12, 0x55);
+- __phy_write(phydev, 0x10, 0x8ec0);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
+- BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
+-
+- /* rg_tr_lpf_cnt_val = 512 */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
+-
+- /* IIR2 related */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
+-
+- /* FFE peaking */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
+- MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
+- MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
+-
+- /* Disable LDO pump */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
+- /* Adjust LDO output voltage */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
+-}
+-
+-static void mt7988_phy_finetune(struct phy_device *phydev)
+-{
+- u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
+- 0x020d, 0x0206, 0x0384, 0x03d0,
+- 0x03c6, 0x030a, 0x0011, 0x0005 };
+- int i;
+-
+- /* Set default MLT3 shaper first */
+- for (i = 0; i < 12; i++)
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
+-
+- /* TCT finetune */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 5 */
+- __phy_write(phydev, 0x11, 0x500);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
+-
+- /* VgaDecRate is 1 at default on mt7988 */
+-
+- /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
+- * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
+- */
+- __phy_write(phydev, 0x11, 0xb90a);
+- __phy_write(phydev, 0x12, 0x6f);
+- __phy_write(phydev, 0x10, 0x8f82);
+-
+- /* RemAckCntLimitCtrl = 1 */
+- __phy_write(phydev, 0x11, 0xfbba);
+- __phy_write(phydev, 0x12, 0xc3);
+- __phy_write(phydev, 0x10, 0x87f8);
+-
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
+- BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
+-
+- /* rg_tr_lpf_cnt_val = 1023 */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
+-}
+-
+-static void mt798x_phy_eee(struct phy_device *phydev)
+-{
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
+- MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
+- MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
+- FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
+- MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- 0xff));
+-
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_TESTMUX_ADC_CTRL,
+- MTK_PHY_RG_TXEN_DIG_MASK);
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
+-
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
+- MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
+- MTK_PHY_LPI_SLV_SEND_TX_EN,
+- FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
+-
+- /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
+- MTK_PHY_LPI_TXPCS_LOC_RCV);
+-
+- /* This also fixes some IoT issues, such as CH340 */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
+- MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
+- FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
+- FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
+- MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
+- FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
+- 0x33) |
+- MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
+- MTK_PHY_LPI_VCO_EEE_STG0_EN);
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
+- MTK_PHY_EEE_WAKE_MAS_INT_DC |
+- MTK_PHY_EEE_WAKE_SLV_INT_DC);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
+- MTK_PHY_SMI_DETCNT_MAX_MASK,
+- FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
+- MTK_PHY_SMI_DET_MAX_EN);
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
+- MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
+- MTK_PHY_TREC_UPDATE_ENAB_CLR |
+- MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
+- MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* Regsigdet_sel_1000 = 0 */
+- __phy_write(phydev, 0x11, 0xb);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9690);
+-
+- /* REG_EEE_st2TrKf1000 = 2 */
+- __phy_write(phydev, 0x11, 0x114f);
+- __phy_write(phydev, 0x12, 0x2);
+- __phy_write(phydev, 0x10, 0x969a);
+-
+- /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
+- __phy_write(phydev, 0x11, 0x3028);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x969e);
+-
+- /* RegEEE_slv_wake_int_timer_tar = 8 */
+- __phy_write(phydev, 0x11, 0x5010);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a0);
+-
+- /* RegEEE_trfreeze_timer2 = 586 */
+- __phy_write(phydev, 0x11, 0x24a);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a8);
+-
+- /* RegEEE100Stg1_tar = 16 */
+- __phy_write(phydev, 0x11, 0x3210);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96b8);
+-
+- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
+- __phy_write(phydev, 0x11, 0x1463);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96ca);
+-
+- /* DfeTailEnableVgaThresh1000 = 27 */
+- __phy_write(phydev, 0x11, 0x36);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8f80);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
+- __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
+-
+- __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
+- FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
+- MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
+-}
+-
+-static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
+- u8 start_pair, u8 end_pair)
+-{
+- u8 pair_n;
+- int ret;
+-
+- for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
+- /* TX_OFFSET & TX_AMP have no SW calibration. */
+- switch (cal_item) {
+- case TX_VCM:
+- ret = tx_vcm_cal_sw(phydev, pair_n);
+- break;
+- default:
+- return -EINVAL;
+- }
+- if (ret)
+- return ret;
+- }
+- return 0;
+-}
+-
+-static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
+- u8 start_pair, u8 end_pair, u32 *buf)
+-{
+- u8 pair_n;
+- int ret;
+-
+- for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
+- /* TX_VCM has no efuse calibration. */
+- switch (cal_item) {
+- case REXT:
+- ret = rext_cal_efuse(phydev, buf);
+- break;
+- case TX_OFFSET:
+- ret = tx_offset_cal_efuse(phydev, buf);
+- break;
+- case TX_AMP:
+- ret = tx_amp_cal_efuse(phydev, buf);
+- break;
+- case TX_R50:
+- ret = tx_r50_cal_efuse(phydev, buf, pair_n);
+- break;
+- default:
+- return -EINVAL;
+- }
+- if (ret)
+- return ret;
+- }
+-
+- return 0;
+-}
+-
+-static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
+- enum CAL_MODE cal_mode, u8 start_pair,
+- u8 end_pair, u32 *buf)
+-{
+- int ret;
+-
+- switch (cal_mode) {
+- case EFUSE_M:
+- ret = cal_efuse(phydev, cal_item, start_pair,
+- end_pair, buf);
+- break;
+- case SW_M:
+- ret = cal_sw(phydev, cal_item, start_pair, end_pair);
+- break;
+- default:
+- return -EINVAL;
+- }
+-
+- if (ret) {
+- phydev_err(phydev, "cal %d failed\n", cal_item);
+- return -EIO;
+- }
+-
+- return 0;
+-}
+-
+-static int mt798x_phy_calibration(struct phy_device *phydev)
+-{
+- int ret = 0;
+- u32 *buf;
+- size_t len;
+- struct nvmem_cell *cell;
+-
+- cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
+- if (IS_ERR(cell)) {
+- if (PTR_ERR(cell) == -EPROBE_DEFER)
+- return PTR_ERR(cell);
+- return 0;
+- }
+-
+- buf = (u32 *)nvmem_cell_read(cell, &len);
+- if (IS_ERR(buf))
+- return PTR_ERR(buf);
+- nvmem_cell_put(cell);
+-
+- if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
+- phydev_err(phydev, "invalid efuse data\n");
+- ret = -EINVAL;
+- goto out;
+- }
+-
+- ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
+- if (ret)
+- goto out;
+-
+-out:
+- kfree(buf);
+- return ret;
+-}
+-
+-static int mt798x_phy_config_init(struct phy_device *phydev)
+-{
+- switch (phydev->drv->phy_id) {
+- case MTK_GPHY_ID_MT7981:
+- mt7981_phy_finetune(phydev);
+- break;
+- case MTK_GPHY_ID_MT7988:
+- mt7988_phy_finetune(phydev);
+- break;
+- }
+-
+- mt798x_phy_common_finetune(phydev);
+- mt798x_phy_eee(phydev);
+-
+- return mt798x_phy_calibration(phydev);
+-}
+-
+-static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
+- bool on)
+-{
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (on)
+- changed = !test_and_set_bit(bit_on, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_on, &priv->led_state);
+-
+- changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_MASK,
+- on ? MTK_PHY_LED_ON_FORCE_ON : 0);
+- else
+- return 0;
+-}
+-
+-static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
+- bool blinking)
+-{
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (blinking)
+- changed = !test_and_set_bit(bit_blink, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
+-
+- changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
+- blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
+- else
+- return 0;
+-}
+-
+-static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
+- unsigned long *delay_on,
+- unsigned long *delay_off)
+-{
+- bool blinking = false;
+- int err = 0;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
+- blinking = true;
+- *delay_on = 50;
+- *delay_off = 50;
+- }
+-
+- err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
+- if (err)
+- return err;
+-
+- return mt798x_phy_hw_led_on_set(phydev, index, false);
+-}
+-
+-static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
+- u8 index, enum led_brightness value)
+-{
+- int err;
+-
+- err = mt798x_phy_hw_led_blink_set(phydev, index, false);
+- if (err)
+- return err;
+-
+- return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
+-}
+-
+-static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
+-
+-static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+- unsigned long rules)
+-{
+- if (index > 1)
+- return -EINVAL;
+-
+- /* All combinations of the supported triggers are allowed */
+- if (rules & ~supported_triggers)
+- return -EOPNOTSUPP;
+-
+- return 0;
+-};
+-
+-static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
+- unsigned long *rules)
+-{
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- int on, blink;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
+-
+- if (on < 0)
+- return -EIO;
+-
+- blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL);
+- if (blink < 0)
+- return -EIO;
+-
+- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINKDOWN)) ||
+- (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- if (on & MTK_PHY_LED_ON_FORCE_ON)
+- set_bit(bit_on, &priv->led_state);
+- else
+- clear_bit(bit_on, &priv->led_state);
+-
+- if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
+- set_bit(bit_blink, &priv->led_state);
+- else
+- clear_bit(bit_blink, &priv->led_state);
+-
+- if (!rules)
+- return 0;
+-
+- if (on & MTK_PHY_LED_ON_LINK)
+- *rules |= BIT(TRIGGER_NETDEV_LINK);
+-
+- if (on & MTK_PHY_LED_ON_LINK10)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_10);
+-
+- if (on & MTK_PHY_LED_ON_LINK100)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_100);
+-
+- if (on & MTK_PHY_LED_ON_LINK1000)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
+-
+- if (on & MTK_PHY_LED_ON_FDX)
+- *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
+-
+- if (on & MTK_PHY_LED_ON_HDX)
+- *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
+-
+- if (blink & MTK_PHY_LED_BLINK_RX)
+- *rules |= BIT(TRIGGER_NETDEV_RX);
+-
+- if (blink & MTK_PHY_LED_BLINK_TX)
+- *rules |= BIT(TRIGGER_NETDEV_TX);
+-
+- return 0;
+-};
+-
+-static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
+- unsigned long rules)
+-{
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- u16 on = 0, blink = 0;
+- int ret;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
+- on |= MTK_PHY_LED_ON_FDX;
+-
+- if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
+- on |= MTK_PHY_LED_ON_HDX;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK10;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK100;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK1000;
+-
+- if (rules & BIT(TRIGGER_NETDEV_RX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
+- MTK_PHY_LED_BLINK_RX;
+- }
+-
+- if (rules & BIT(TRIGGER_NETDEV_TX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
+- MTK_PHY_LED_BLINK_TX;
+- }
+-
+- if (blink || on)
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL :
+- MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_FDX |
+- MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINK,
+- on);
+-
+- if (ret)
+- return ret;
+-
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL, blink);
+-};
+-
+-static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
+-{
+- struct mtk_socphy_shared *priv = phydev->shared->priv;
+- u32 polarities;
+-
+- if (led_num == 0)
+- polarities = ~(priv->boottrap);
+- else
+- polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
+-
+- if (polarities & BIT(phydev->mdio.addr))
+- return true;
+-
+- return false;
+-}
+-
+-static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
+-{
+- struct pinctrl *pinctrl;
+- int index;
+-
+- /* Setup LED polarity according to bootstrap use of LED pins */
+- for (index = 0; index < 2; ++index)
+- phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_POLARITY,
+- mt7988_phy_led_get_polarity(phydev, index) ?
+- MTK_PHY_LED_ON_POLARITY : 0);
+-
+- /* Only now setup pinctrl to avoid bogus blinking */
+- pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
+- if (IS_ERR(pinctrl))
+- dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
+-
+- return 0;
+-}
+-
+-static int mt7988_phy_probe_shared(struct phy_device *phydev)
+-{
+- struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
+- struct mtk_socphy_shared *shared = phydev->shared->priv;
+- struct regmap *regmap;
+- u32 reg;
+- int ret;
+-
+- /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
+- * LED_C and LED_D respectively. At the same time those pins are used to
+- * bootstrap configuration of the reference clock source (LED_A),
+- * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
+- * In practise this is done using a LED and a resistor pulling the pin
+- * either to GND or to VIO.
+- * The detected value at boot time is accessible at run-time using the
+- * TPBANK0 register located in the gpio base of the pinctrl, in order
+- * to read it here it needs to be referenced by a phandle called
+- * 'mediatek,pio' in the MDIO bus hosting the PHY.
+- * The 4 bits in TPBANK0 are kept as package shared data and are used to
+- * set LED polarity for each of the LED0.
+- */
+- regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
+- if (IS_ERR(regmap))
+- return PTR_ERR(regmap);
+-
+- ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
+- if (ret)
+- return ret;
+-
+- shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
+-
+- return 0;
+-}
+-
+-static void mt798x_phy_leds_state_init(struct phy_device *phydev)
+-{
+- int i;
+-
+- for (i = 0; i < 2; ++i)
+- mt798x_phy_led_hw_control_get(phydev, i, NULL);
+-}
+-
+-static int mt7988_phy_probe(struct phy_device *phydev)
+-{
+- struct mtk_socphy_shared *shared;
+- struct mtk_socphy_priv *priv;
+- int err;
+-
+- if (phydev->mdio.addr > 3)
+- return -EINVAL;
+-
+- err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
+- sizeof(struct mtk_socphy_shared));
+- if (err)
+- return err;
+-
+- if (phy_package_probe_once(phydev)) {
+- err = mt7988_phy_probe_shared(phydev);
+- if (err)
+- return err;
+- }
+-
+- shared = phydev->shared->priv;
+- priv = &shared->priv[phydev->mdio.addr];
+-
+- phydev->priv = priv;
+-
+- mt798x_phy_leds_state_init(phydev);
+-
+- err = mt7988_phy_fix_leds_polarities(phydev);
+- if (err)
+- return err;
+-
+- /* Disable TX power saving at probing to:
+- * 1. Meet common mode compliance test criteria
+- * 2. Make sure that TX-VCM calibration works fine
+- */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
+- MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
+-
+- return mt798x_phy_calibration(phydev);
+-}
+-
+-static int mt7981_phy_probe(struct phy_device *phydev)
+-{
+- struct mtk_socphy_priv *priv;
+-
+- priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
+- GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- phydev->priv = priv;
+-
+- mt798x_phy_leds_state_init(phydev);
+-
+- return mt798x_phy_calibration(phydev);
+-}
+-
+-static struct phy_driver mtk_socphy_driver[] = {
+- {
+- PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+- .name = "MediaTek MT7981 PHY",
+- .config_init = mt798x_phy_config_init,
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7981_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
+- .led_brightness_set = mt798x_phy_led_brightness_set,
+- .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+- .led_hw_control_set = mt798x_phy_led_hw_control_set,
+- .led_hw_control_get = mt798x_phy_led_hw_control_get,
+- },
+- {
+- PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+- .name = "MediaTek MT7988 PHY",
+- .config_init = mt798x_phy_config_init,
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7988_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
+- .led_brightness_set = mt798x_phy_led_brightness_set,
+- .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+- .led_hw_control_set = mt798x_phy_led_hw_control_set,
+- .led_hw_control_get = mt798x_phy_led_hw_control_get,
+- },
+-};
+-
+-module_phy_driver(mtk_socphy_driver);
+-
+-static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
+- { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
+- { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
+- { }
+-};
+-
+-MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");
+-MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+-MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
+-MODULE_LICENSE("GPL");
+-
+-MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
+--- a/drivers/net/phy/mediatek-ge.c
++++ /dev/null
+@@ -1,148 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0+
+-#include <linux/of.h>
+-#include <linux/bitfield.h>
+-#include <linux/module.h>
+-#include <linux/phy.h>
+-
+-#define MTK_EXT_PAGE_ACCESS 0x1f
+-#define MTK_PHY_PAGE_STANDARD 0x0000
+-#define MTK_PHY_PAGE_EXTENDED 0x0001
+-#define MTK_PHY_PAGE_EXTENDED_2 0x0002
+-#define MTK_PHY_PAGE_EXTENDED_3 0x0003
+-#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+-
+-static int mtk_gephy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_gephy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+-static void mtk_gephy_config_init(struct phy_device *phydev)
+-{
+- /* Disable EEE */
+- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+-
+- /* Enable HW auto downshift */
+- phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
+-
+- /* Increase SlvDPSready time */
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- __phy_write(phydev, 0x10, 0xafae);
+- __phy_write(phydev, 0x12, 0x2f);
+- __phy_write(phydev, 0x10, 0x8fae);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- /* Adjust 100_mse_threshold */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
+-
+- /* Disable mcc */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
+-}
+-
+-static int mt7530_phy_config_init(struct phy_device *phydev)
+-{
+- mtk_gephy_config_init(phydev);
+-
+- /* Increase post_update_timer */
+- phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
+-
+- return 0;
+-}
+-
+-static int mt7530_led_config_of(struct phy_device *phydev)
+-{
+- struct device_node *np = phydev->mdio.dev.of_node;
+- const __be32 *paddr;
+- int len;
+- int i;
+-
+- paddr = of_get_property(np, "mediatek,led-config", &len);
+- if (!paddr)
+- return 0;
+-
+- if (len < (2 * sizeof(*paddr)))
+- return -EINVAL;
+-
+- len /= sizeof(*paddr);
+-
+- phydev_warn(phydev, "Configure LED registers (num=%d)\n", len);
+- for (i = 0; i < len - 1; i += 2) {
+- u32 reg;
+- u32 val;
+-
+- reg = be32_to_cpup(paddr + i);
+- val = be32_to_cpup(paddr + i + 1);
+-
+- phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val);
+- }
+-
+- return 0;
+-}
+-
+-static int mt7531_phy_config_init(struct phy_device *phydev)
+-{
+- mtk_gephy_config_init(phydev);
+-
+- /* PHY link down power saving enable */
+- phy_set_bits(phydev, 0x17, BIT(4));
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
+-
+- /* Set TX Pair delay selection */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
+-
+- /* LED Config*/
+- mt7530_led_config_of(phydev);
+-
+- return 0;
+-}
+-
+-static struct phy_driver mtk_gephy_driver[] = {
+- {
+- PHY_ID_MATCH_EXACT(0x03a29412),
+- .name = "MediaTek MT7530 PHY",
+- .config_init = mt7530_phy_config_init,
+- /* Interrupts are handled by the switch, not the PHY
+- * itself.
+- */
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
+- },
+- {
+- PHY_ID_MATCH_EXACT(0x03a29441),
+- .name = "MediaTek MT7531 PHY",
+- .config_init = mt7531_phy_config_init,
+- /* Interrupts are handled by the switch, not the PHY
+- * itself.
+- */
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
+- },
+-};
+-
+-module_phy_driver(mtk_gephy_driver);
+-
+-static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
+- { PHY_ID_MATCH_EXACT(0x03a29441) },
+- { PHY_ID_MATCH_EXACT(0x03a29412) },
+- { }
+-};
+-
+-MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
+-MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
+-MODULE_LICENSE("GPL");
+-
+-MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -0,0 +1,1555 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/bitfield.h>
++#include <linux/bitmap.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/phy.h>
++#include <linux/regmap.h>
++
++#define MTK_GPHY_ID_MT7981 0x03a29461
++#define MTK_GPHY_ID_MT7988 0x03a29481
++
++#define MTK_EXT_PAGE_ACCESS 0x1f
++#define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED_3 0x0003
++
++#define MTK_PHY_LPI_REG_14 0x14
++#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK GENMASK(8, 0)
++
++#define MTK_PHY_LPI_REG_1c 0x1c
++#define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8)
++
++#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
++#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++
++#define ANALOG_INTERNAL_OPERATION_MAX_US 20
++#define TXRESERVE_MIN 0
++#define TXRESERVE_MAX 7
++
++#define MTK_PHY_ANARG_RG 0x10
++#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_TXVLD_DA_RG 0x12
++#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
++#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 0x16
++#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
++#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 0x17
++#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 0x18
++#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 0x19
++#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 0x20
++#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 0x21
++#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 0x22
++#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_RXADC_CTRL_RG7 0xc6
++#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
++
++#define MTK_PHY_RXADC_CTRL_RG9 0xc8
++#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
++#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
++#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
++#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
++
++#define MTK_PHY_LDO_OUTPUT_V 0xd7
++
++#define MTK_PHY_RG_ANA_CAL_RG0 0xdb
++#define MTK_PHY_RG_CAL_CKINV BIT(12)
++#define MTK_PHY_RG_ANA_CALEN BIT(8)
++#define MTK_PHY_RG_ZCALEN_A BIT(0)
++
++#define MTK_PHY_RG_ANA_CAL_RG1 0xdc
++#define MTK_PHY_RG_ZCALEN_B BIT(12)
++#define MTK_PHY_RG_ZCALEN_C BIT(8)
++#define MTK_PHY_RG_ZCALEN_D BIT(4)
++#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
++
++#define MTK_PHY_RG_ANA_CAL_RG5 0xe0
++#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
++
++#define MTK_PHY_RG_TX_FILTER 0xfe
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120 0x120
++#define MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK GENMASK(12, 8)
++#define MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK GENMASK(4, 0)
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122 0x122
++#define MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK GENMASK(7, 0)
++
++#define MTK_PHY_RG_TESTMUX_ADC_CTRL 0x144
++#define MTK_PHY_RG_TXEN_DIG_MASK GENMASK(5, 5)
++
++#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B 0x172
++#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
++#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
++
++#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D 0x173
++#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
++#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
++
++#define MTK_PHY_RG_AD_CAL_COMP 0x17a
++#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
++
++#define MTK_PHY_RG_AD_CAL_CLK 0x17b
++#define MTK_PHY_DA_CAL_CLK BIT(0)
++
++#define MTK_PHY_RG_AD_CALIN 0x17c
++#define MTK_PHY_DA_CALIN_FLAG BIT(0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_A 0x17d
++#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_B 0x17e
++#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_C 0x17f
++#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_D 0x180
++#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_A 0x181
++#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_B 0x182
++#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_C 0x183
++#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_D 0x184
++#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DEV1E_REG19b 0x19b
++#define MTK_PHY_BYPASS_DSP_LPI_READY BIT(8)
++
++#define MTK_PHY_RG_LP_IIR2_K1_L 0x22a
++#define MTK_PHY_RG_LP_IIR2_K1_U 0x22b
++#define MTK_PHY_RG_LP_IIR2_K2_L 0x22c
++#define MTK_PHY_RG_LP_IIR2_K2_U 0x22d
++#define MTK_PHY_RG_LP_IIR2_K3_L 0x22e
++#define MTK_PHY_RG_LP_IIR2_K3_U 0x22f
++#define MTK_PHY_RG_LP_IIR2_K4_L 0x230
++#define MTK_PHY_RG_LP_IIR2_K4_U 0x231
++#define MTK_PHY_RG_LP_IIR2_K5_L 0x232
++#define MTK_PHY_RG_LP_IIR2_K5_U 0x233
++
++#define MTK_PHY_RG_DEV1E_REG234 0x234
++#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
++#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
++#define MTK_PHY_TR_LP_IIR_EEE_EN BIT(12)
++
++#define MTK_PHY_RG_LPF_CNT_VAL 0x235
++
++#define MTK_PHY_RG_DEV1E_REG238 0x238
++#define MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK GENMASK(8, 0)
++#define MTK_PHY_LPI_SLV_SEND_TX_EN BIT(12)
++
++#define MTK_PHY_RG_DEV1E_REG239 0x239
++#define MTK_PHY_LPI_SEND_LOC_TIMER_MASK GENMASK(8, 0)
++#define MTK_PHY_LPI_TXPCS_LOC_RCV BIT(12)
++
++#define MTK_PHY_RG_DEV1E_REG27C 0x27c
++#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
++#define MTK_PHY_RG_DEV1E_REG27D 0x27d
++#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
++
++#define MTK_PHY_RG_DEV1E_REG2C7 0x2c7
++#define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0)
++#define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8)
++
++#define MTK_PHY_RG_DEV1E_REG2D1 0x2d1
++#define MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK GENMASK(7, 0)
++#define MTK_PHY_LPI_SKIP_SD_SLV_TR BIT(8)
++#define MTK_PHY_LPI_TR_READY BIT(9)
++#define MTK_PHY_LPI_VCO_EEE_STG0_EN BIT(10)
++
++#define MTK_PHY_RG_DEV1E_REG323 0x323
++#define MTK_PHY_EEE_WAKE_MAS_INT_DC BIT(0)
++#define MTK_PHY_EEE_WAKE_SLV_INT_DC BIT(4)
++
++#define MTK_PHY_RG_DEV1E_REG324 0x324
++#define MTK_PHY_SMI_DETCNT_MAX_MASK GENMASK(5, 0)
++#define MTK_PHY_SMI_DET_MAX_EN BIT(8)
++
++#define MTK_PHY_RG_DEV1E_REG326 0x326
++#define MTK_PHY_LPI_MODE_SD_ON BIT(0)
++#define MTK_PHY_RESET_RANDUPD_CNT BIT(1)
++#define MTK_PHY_TREC_UPDATE_ENAB_CLR BIT(2)
++#define MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF BIT(4)
++#define MTK_PHY_TR_READY_SKIP_AFE_WAKEUP BIT(5)
++
++#define MTK_PHY_LDO_PUMP_EN_PAIRAB 0x502
++#define MTK_PHY_LDO_PUMP_EN_PAIRCD 0x503
++
++#define MTK_PHY_DA_TX_R50_PAIR_A 0x53d
++#define MTK_PHY_DA_TX_R50_PAIR_B 0x53e
++#define MTK_PHY_DA_TX_R50_PAIR_C 0x53f
++#define MTK_PHY_DA_TX_R50_PAIR_D 0x540
++
++/* Registers on MDIO_MMD_VEND2 */
++#define MTK_PHY_LED0_ON_CTRL 0x24
++#define MTK_PHY_LED1_ON_CTRL 0x26
++#define MTK_PHY_LED_ON_MASK GENMASK(6, 0)
++#define MTK_PHY_LED_ON_LINK1000 BIT(0)
++#define MTK_PHY_LED_ON_LINK100 BIT(1)
++#define MTK_PHY_LED_ON_LINK10 BIT(2)
++#define MTK_PHY_LED_ON_LINK (MTK_PHY_LED_ON_LINK10 |\
++ MTK_PHY_LED_ON_LINK100 |\
++ MTK_PHY_LED_ON_LINK1000)
++#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
++#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
++#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
++#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
++#define MTK_PHY_LED_ON_POLARITY BIT(14)
++#define MTK_PHY_LED_ON_ENABLE BIT(15)
++
++#define MTK_PHY_LED0_BLINK_CTRL 0x25
++#define MTK_PHY_LED1_BLINK_CTRL 0x27
++#define MTK_PHY_LED_BLINK_1000TX BIT(0)
++#define MTK_PHY_LED_BLINK_1000RX BIT(1)
++#define MTK_PHY_LED_BLINK_100TX BIT(2)
++#define MTK_PHY_LED_BLINK_100RX BIT(3)
++#define MTK_PHY_LED_BLINK_10TX BIT(4)
++#define MTK_PHY_LED_BLINK_10RX BIT(5)
++#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\
++ MTK_PHY_LED_BLINK_100RX |\
++ MTK_PHY_LED_BLINK_1000RX)
++#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\
++ MTK_PHY_LED_BLINK_100TX |\
++ MTK_PHY_LED_BLINK_1000TX)
++#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
++#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
++#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
++#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
++
++#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1)
++
++#define MTK_PHY_RG_BG_RASEL 0x115
++#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
++
++/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
++#define RG_GPIO_MISC_TPBANK0 0x6f0
++#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8)
++
++/* These macro privides efuse parsing for internal phy. */
++#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
++
++#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
++
++#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
++
++#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
++#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
++
++enum {
++ NO_PAIR,
++ PAIR_A,
++ PAIR_B,
++ PAIR_C,
++ PAIR_D,
++};
++
++enum calibration_mode {
++ EFUSE_K,
++ SW_K
++};
++
++enum CAL_ITEM {
++ REXT,
++ TX_OFFSET,
++ TX_AMP,
++ TX_R50,
++ TX_VCM
++};
++
++enum CAL_MODE {
++ EFUSE_M,
++ SW_M
++};
++
++#define MTK_PHY_LED_STATE_FORCE_ON 0
++#define MTK_PHY_LED_STATE_FORCE_BLINK 1
++#define MTK_PHY_LED_STATE_NETDEV 2
++
++struct mtk_socphy_priv {
++ unsigned long led_state;
++};
++
++struct mtk_socphy_shared {
++ u32 boottrap;
++ struct mtk_socphy_priv priv[4];
++};
++
++static int mtk_socphy_read_page(struct phy_device *phydev)
++{
++ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
++}
++
++static int mtk_socphy_write_page(struct phy_device *phydev, int page)
++{
++ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
++}
++
++/* One calibration cycle consists of:
++ * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
++ * until AD_CAL_COMP is ready to output calibration result.
++ * 2.Wait until DA_CAL_CLK is available.
++ * 3.Fetch AD_CAL_COMP_OUT.
++ */
++static int cal_cycle(struct phy_device *phydev, int devad,
++ u32 regnum, u16 mask, u16 cal_val)
++{
++ int reg_val;
++ int ret;
++
++ phy_modify_mmd(phydev, devad, regnum,
++ mask, cal_val);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
++ MTK_PHY_DA_CALIN_FLAG);
++
++ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_AD_CAL_CLK, reg_val,
++ reg_val & MTK_PHY_DA_CAL_CLK, 500,
++ ANALOG_INTERNAL_OPERATION_MAX_US, false);
++ if (ret) {
++ phydev_err(phydev, "Calibration cycle timeout\n");
++ return ret;
++ }
++
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
++ MTK_PHY_DA_CALIN_FLAG);
++ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
++ MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
++ phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
++
++ return ret;
++}
++
++static int rext_fill_result(struct phy_device *phydev, u16 *buf)
++{
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
++ MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
++ MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
++
++ return 0;
++}
++
++static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++ u16 rext_cal_val[2];
++
++ rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
++ rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
++ rext_fill_result(phydev, rext_cal_val);
++
++ return 0;
++}
++
++static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
++{
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
++ MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
++ MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
++ MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
++ MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
++
++ return 0;
++}
++
++static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++ u16 tx_offset_cal_val[4];
++
++ tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
++ tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
++ tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
++ tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
++
++ tx_offset_fill_result(phydev, tx_offset_cal_val);
++
++ return 0;
++}
++
++static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
++{
++ int i;
++ int bias[16] = {};
++ const int vals_9461[16] = { 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7 };
++ const int vals_9481[16] = { 10, 6, 6, 10,
++ 10, 6, 6, 10,
++ 10, 6, 6, 10,
++ 10, 6, 6, 10 };
++ switch (phydev->drv->phy_id) {
++ case MTK_GPHY_ID_MT7981:
++ /* We add some calibration to efuse values
++ * due to board level influence.
++ * GBE: +7, TBT: +1, HBT: +4, TST: +7
++ */
++ memcpy(bias, (const void *)vals_9461, sizeof(bias));
++ break;
++ case MTK_GPHY_ID_MT7988:
++ memcpy(bias, (const void *)vals_9481, sizeof(bias));
++ break;
++ }
++
++ /* Prevent overflow */
++ for (i = 0; i < 12; i++) {
++ if (buf[i >> 2] + bias[i] > 63) {
++ buf[i >> 2] = 63;
++ bias[i] = 0;
++ }
++ }
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
++ MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
++ MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
++ MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
++ MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
++ MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
++ MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
++ MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
++ MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
++ MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
++ MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
++ MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
++ MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
++ MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
++ MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
++ MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
++ MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
++
++ return 0;
++}
++
++static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++ u16 tx_amp_cal_val[4];
++
++ tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
++ tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
++ tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
++ tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
++ tx_amp_fill_result(phydev, tx_amp_cal_val);
++
++ return 0;
++}
++
++static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
++ u8 txg_calen_x)
++{
++ int bias = 0;
++ u16 reg, val;
++
++ if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
++ bias = -1;
++
++ val = clamp_val(bias + tx_r50_cal_val, 0, 63);
++
++ switch (txg_calen_x) {
++ case PAIR_A:
++ reg = MTK_PHY_DA_TX_R50_PAIR_A;
++ break;
++ case PAIR_B:
++ reg = MTK_PHY_DA_TX_R50_PAIR_B;
++ break;
++ case PAIR_C:
++ reg = MTK_PHY_DA_TX_R50_PAIR_C;
++ break;
++ case PAIR_D:
++ reg = MTK_PHY_DA_TX_R50_PAIR_D;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
++
++ return 0;
++}
++
++static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
++ u8 txg_calen_x)
++{
++ u16 tx_r50_cal_val;
++
++ switch (txg_calen_x) {
++ case PAIR_A:
++ tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
++ break;
++ case PAIR_B:
++ tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
++ break;
++ case PAIR_C:
++ tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
++ break;
++ case PAIR_D:
++ tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
++ break;
++ default:
++ return -EINVAL;
++ }
++ tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
++
++ return 0;
++}
++
++static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
++{
++ u8 lower_idx, upper_idx, txreserve_val;
++ u8 lower_ret, upper_ret;
++ int ret;
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ANA_CALEN);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_CAL_CKINV);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_TXVOS_CALEN);
++
++ switch (rg_txreserve_x) {
++ case PAIR_A:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_A,
++ MTK_PHY_DASN_DAC_IN0_A_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_A,
++ MTK_PHY_DASN_DAC_IN1_A_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ZCALEN_A);
++ break;
++ case PAIR_B:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_B,
++ MTK_PHY_DASN_DAC_IN0_B_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_B,
++ MTK_PHY_DASN_DAC_IN1_B_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_B);
++ break;
++ case PAIR_C:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_C,
++ MTK_PHY_DASN_DAC_IN0_C_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_C,
++ MTK_PHY_DASN_DAC_IN1_C_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_C);
++ break;
++ case PAIR_D:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_D,
++ MTK_PHY_DASN_DAC_IN0_D_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_D,
++ MTK_PHY_DASN_DAC_IN1_D_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_D);
++ break;
++ default:
++ ret = -EINVAL;
++ goto restore;
++ }
++
++ lower_idx = TXRESERVE_MIN;
++ upper_idx = TXRESERVE_MAX;
++
++ phydev_dbg(phydev, "Start TX-VCM SW cal.\n");
++ while ((upper_idx - lower_idx) > 1) {
++ txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
++ ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ txreserve_val << 12 | txreserve_val << 8 |
++ txreserve_val << 4 | txreserve_val);
++ if (ret == 1) {
++ upper_idx = txreserve_val;
++ upper_ret = ret;
++ } else if (ret == 0) {
++ lower_idx = txreserve_val;
++ lower_ret = ret;
++ } else {
++ goto restore;
++ }
++ }
++
++ if (lower_idx == TXRESERVE_MIN) {
++ lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ lower_idx << 12 | lower_idx << 8 |
++ lower_idx << 4 | lower_idx);
++ ret = lower_ret;
++ } else if (upper_idx == TXRESERVE_MAX) {
++ upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ upper_idx << 12 | upper_idx << 8 |
++ upper_idx << 4 | upper_idx);
++ ret = upper_ret;
++ }
++ if (ret < 0)
++ goto restore;
++
++ /* We calibrate TX-VCM in different logic. Check upper index and then
++ * lower index. If this calibration is valid, apply lower index's result.
++ */
++ ret = upper_ret - lower_ret;
++ if (ret == 1) {
++ ret = 0;
++ /* Make sure we use upper_idx in our calibration system */
++ cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ upper_idx << 12 | upper_idx << 8 |
++ upper_idx << 4 | upper_idx);
++ phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
++ } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
++ lower_ret == 1) {
++ ret = 0;
++ cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ lower_idx << 12 | lower_idx << 8 |
++ lower_idx << 4 | lower_idx);
++ phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",
++ lower_idx);
++ } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
++ lower_ret == 0) {
++ ret = 0;
++ phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
++ upper_idx);
++ } else {
++ ret = -EINVAL;
++ }
++
++restore:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ANA_CALEN);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_TXVOS_CALEN);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ZCALEN_A);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
++ MTK_PHY_RG_ZCALEN_D);
++
++ return ret;
++}
++
++static void mt798x_phy_common_finetune(struct phy_device *phydev)
++{
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
++ __phy_write(phydev, 0x11, 0xc71);
++ __phy_write(phydev, 0x12, 0xc);
++ __phy_write(phydev, 0x10, 0x8fae);
++
++ /* EnabRandUpdTrig = 1 */
++ __phy_write(phydev, 0x11, 0x2f00);
++ __phy_write(phydev, 0x12, 0xe);
++ __phy_write(phydev, 0x10, 0x8fb0);
++
++ /* NormMseLoThresh = 85 */
++ __phy_write(phydev, 0x11, 0x55a0);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x83aa);
++
++ /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
++ __phy_write(phydev, 0x11, 0x240);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x9680);
++
++ /* TrFreeze = 0 (mt7988 default) */
++ __phy_write(phydev, 0x11, 0x0);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x9686);
++
++ /* SSTrKp100 = 5 */
++ /* SSTrKf100 = 6 */
++ /* SSTrKp1000Mas = 5 */
++ /* SSTrKf1000Mas = 6 */
++ /* SSTrKp1000Slv = 5 */
++ /* SSTrKf1000Slv = 6 */
++ __phy_write(phydev, 0x11, 0xbaef);
++ __phy_write(phydev, 0x12, 0x2e);
++ __phy_write(phydev, 0x10, 0x968c);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++}
++
++static void mt7981_phy_finetune(struct phy_device *phydev)
++{
++ u16 val[8] = { 0x01ce, 0x01c1,
++ 0x020f, 0x0202,
++ 0x03d0, 0x03c0,
++ 0x0013, 0x0005 };
++ int i, k;
++
++ /* 100M eye finetune:
++ * Keep middle level of TX MLT3 shapper as default.
++ * Only change TX MLT3 overshoot level here.
++ */
++ for (k = 0, i = 1; i < 12; i++) {
++ if (i % 3 == 0)
++ continue;
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
++ }
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* ResetSyncOffset = 6 */
++ __phy_write(phydev, 0x11, 0x600);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x8fc0);
++
++ /* VgaDecRate = 1 */
++ __phy_write(phydev, 0x11, 0x4c2a);
++ __phy_write(phydev, 0x12, 0x3e);
++ __phy_write(phydev, 0x10, 0x8fa4);
++
++ /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
++ * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
++ */
++ __phy_write(phydev, 0x11, 0xd10a);
++ __phy_write(phydev, 0x12, 0x34);
++ __phy_write(phydev, 0x10, 0x8f82);
++
++ /* VcoSlicerThreshBitsHigh */
++ __phy_write(phydev, 0x11, 0x5555);
++ __phy_write(phydev, 0x12, 0x55);
++ __phy_write(phydev, 0x10, 0x8ec0);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
++
++ /* rg_tr_lpf_cnt_val = 512 */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
++
++ /* IIR2 related */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
++
++ /* FFE peaking */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
++ MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
++ MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
++
++ /* Disable LDO pump */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
++ /* Adjust LDO output voltage */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
++}
++
++static void mt7988_phy_finetune(struct phy_device *phydev)
++{
++ u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
++ 0x020d, 0x0206, 0x0384, 0x03d0,
++ 0x03c6, 0x030a, 0x0011, 0x0005 };
++ int i;
++
++ /* Set default MLT3 shaper first */
++ for (i = 0; i < 12; i++)
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
++
++ /* TCT finetune */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* ResetSyncOffset = 5 */
++ __phy_write(phydev, 0x11, 0x500);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x8fc0);
++
++ /* VgaDecRate is 1 at default on mt7988 */
++
++ /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
++ * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
++ */
++ __phy_write(phydev, 0x11, 0xb90a);
++ __phy_write(phydev, 0x12, 0x6f);
++ __phy_write(phydev, 0x10, 0x8f82);
++
++ /* RemAckCntLimitCtrl = 1 */
++ __phy_write(phydev, 0x11, 0xfbba);
++ __phy_write(phydev, 0x12, 0xc3);
++ __phy_write(phydev, 0x10, 0x87f8);
++
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
++
++ /* rg_tr_lpf_cnt_val = 1023 */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
++}
++
++static void mt798x_phy_eee(struct phy_device *phydev)
++{
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
++ MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
++ MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
++ FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
++ MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ 0xff));
++
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_TESTMUX_ADC_CTRL,
++ MTK_PHY_RG_TXEN_DIG_MASK);
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
++
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
++ MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
++ MTK_PHY_LPI_SLV_SEND_TX_EN,
++ FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
++
++ /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
++ MTK_PHY_LPI_TXPCS_LOC_RCV);
++
++ /* This also fixes some IoT issues, such as CH340 */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
++ MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
++ FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
++ FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
++ MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
++ FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
++ 0x33) |
++ MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
++ MTK_PHY_LPI_VCO_EEE_STG0_EN);
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
++ MTK_PHY_EEE_WAKE_MAS_INT_DC |
++ MTK_PHY_EEE_WAKE_SLV_INT_DC);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
++ MTK_PHY_SMI_DETCNT_MAX_MASK,
++ FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
++ MTK_PHY_SMI_DET_MAX_EN);
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
++ MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
++ MTK_PHY_TREC_UPDATE_ENAB_CLR |
++ MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
++ MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* Regsigdet_sel_1000 = 0 */
++ __phy_write(phydev, 0x11, 0xb);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x9690);
++
++ /* REG_EEE_st2TrKf1000 = 2 */
++ __phy_write(phydev, 0x11, 0x114f);
++ __phy_write(phydev, 0x12, 0x2);
++ __phy_write(phydev, 0x10, 0x969a);
++
++ /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
++ __phy_write(phydev, 0x11, 0x3028);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x969e);
++
++ /* RegEEE_slv_wake_int_timer_tar = 8 */
++ __phy_write(phydev, 0x11, 0x5010);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96a0);
++
++ /* RegEEE_trfreeze_timer2 = 586 */
++ __phy_write(phydev, 0x11, 0x24a);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96a8);
++
++ /* RegEEE100Stg1_tar = 16 */
++ __phy_write(phydev, 0x11, 0x3210);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96b8);
++
++ /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
++ __phy_write(phydev, 0x11, 0x1463);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96ca);
++
++ /* DfeTailEnableVgaThresh1000 = 27 */
++ __phy_write(phydev, 0x11, 0x36);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x8f80);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
++ __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
++
++ __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
++ FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
++ MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
++}
++
++static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
++ u8 start_pair, u8 end_pair)
++{
++ u8 pair_n;
++ int ret;
++
++ for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
++ /* TX_OFFSET & TX_AMP have no SW calibration. */
++ switch (cal_item) {
++ case TX_VCM:
++ ret = tx_vcm_cal_sw(phydev, pair_n);
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (ret)
++ return ret;
++ }
++ return 0;
++}
++
++static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
++ u8 start_pair, u8 end_pair, u32 *buf)
++{
++ u8 pair_n;
++ int ret;
++
++ for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
++ /* TX_VCM has no efuse calibration. */
++ switch (cal_item) {
++ case REXT:
++ ret = rext_cal_efuse(phydev, buf);
++ break;
++ case TX_OFFSET:
++ ret = tx_offset_cal_efuse(phydev, buf);
++ break;
++ case TX_AMP:
++ ret = tx_amp_cal_efuse(phydev, buf);
++ break;
++ case TX_R50:
++ ret = tx_r50_cal_efuse(phydev, buf, pair_n);
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
++ enum CAL_MODE cal_mode, u8 start_pair,
++ u8 end_pair, u32 *buf)
++{
++ int ret;
++
++ switch (cal_mode) {
++ case EFUSE_M:
++ ret = cal_efuse(phydev, cal_item, start_pair,
++ end_pair, buf);
++ break;
++ case SW_M:
++ ret = cal_sw(phydev, cal_item, start_pair, end_pair);
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (ret) {
++ phydev_err(phydev, "cal %d failed\n", cal_item);
++ return -EIO;
++ }
++
++ return 0;
++}
++
++static int mt798x_phy_calibration(struct phy_device *phydev)
++{
++ int ret = 0;
++ u32 *buf;
++ size_t len;
++ struct nvmem_cell *cell;
++
++ cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
++ if (IS_ERR(cell)) {
++ if (PTR_ERR(cell) == -EPROBE_DEFER)
++ return PTR_ERR(cell);
++ return 0;
++ }
++
++ buf = (u32 *)nvmem_cell_read(cell, &len);
++ if (IS_ERR(buf))
++ return PTR_ERR(buf);
++ nvmem_cell_put(cell);
++
++ if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
++ phydev_err(phydev, "invalid efuse data\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
++ if (ret)
++ goto out;
++
++out:
++ kfree(buf);
++ return ret;
++}
++
++static int mt798x_phy_config_init(struct phy_device *phydev)
++{
++ switch (phydev->drv->phy_id) {
++ case MTK_GPHY_ID_MT7981:
++ mt7981_phy_finetune(phydev);
++ break;
++ case MTK_GPHY_ID_MT7988:
++ mt7988_phy_finetune(phydev);
++ break;
++ }
++
++ mt798x_phy_common_finetune(phydev);
++ mt798x_phy_eee(phydev);
++
++ return mt798x_phy_calibration(phydev);
++}
++
++static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++ bool on)
++{
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ bool changed;
++
++ if (on)
++ changed = !test_and_set_bit(bit_on, &priv->led_state);
++ else
++ changed = !!test_and_clear_bit(bit_on, &priv->led_state);
++
++ changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), &priv->led_state);
++ if (changed)
++ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_MASK,
++ on ? MTK_PHY_LED_ON_FORCE_ON : 0);
++ else
++ return 0;
++}
++
++static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++ bool blinking)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ bool changed;
++
++ if (blinking)
++ changed = !test_and_set_bit(bit_blink, &priv->led_state);
++ else
++ changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
++
++ changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), &priv->led_state);
++ if (changed)
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
++ blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
++ else
++ return 0;
++}
++
++static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *delay_on,
++ unsigned long *delay_off)
++{
++ bool blinking = false;
++ int err = 0;
++
++ if (index > 1)
++ return -EINVAL;
++
++ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
++ blinking = true;
++ *delay_on = 50;
++ *delay_off = 50;
++ }
++
++ err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
++ if (err)
++ return err;
++
++ return mt798x_phy_hw_led_on_set(phydev, index, false);
++}
++
++static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
++ u8 index, enum led_brightness value)
++{
++ int err;
++
++ err = mt798x_phy_hw_led_blink_set(phydev, index, false);
++ if (err)
++ return err;
++
++ return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
++}
++
++static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX));
++
++static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ if (index > 1)
++ return -EINVAL;
++
++ /* All combinations of the supported triggers are allowed */
++ if (rules & ~supported_triggers)
++ return -EOPNOTSUPP;
++
++ return 0;
++};
++
++static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ int on, blink;
++
++ if (index > 1)
++ return -EINVAL;
++
++ on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
++
++ if (on < 0)
++ return -EIO;
++
++ blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL);
++ if (blink < 0)
++ return -EIO;
++
++ if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
++ MTK_PHY_LED_ON_LINKDOWN)) ||
++ (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
++ set_bit(bit_netdev, &priv->led_state);
++ else
++ clear_bit(bit_netdev, &priv->led_state);
++
++ if (on & MTK_PHY_LED_ON_FORCE_ON)
++ set_bit(bit_on, &priv->led_state);
++ else
++ clear_bit(bit_on, &priv->led_state);
++
++ if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
++ set_bit(bit_blink, &priv->led_state);
++ else
++ clear_bit(bit_blink, &priv->led_state);
++
++ if (!rules)
++ return 0;
++
++ if (on & MTK_PHY_LED_ON_LINK)
++ *rules |= BIT(TRIGGER_NETDEV_LINK);
++
++ if (on & MTK_PHY_LED_ON_LINK10)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_10);
++
++ if (on & MTK_PHY_LED_ON_LINK100)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_100);
++
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++ if (on & MTK_PHY_LED_ON_FDX)
++ *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
++
++ if (on & MTK_PHY_LED_ON_HDX)
++ *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
++
++ if (blink & MTK_PHY_LED_BLINK_RX)
++ *rules |= BIT(TRIGGER_NETDEV_RX);
++
++ if (blink & MTK_PHY_LED_BLINK_TX)
++ *rules |= BIT(TRIGGER_NETDEV_TX);
++
++ return 0;
++};
++
++static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ u16 on = 0, blink = 0;
++ int ret;
++
++ if (index > 1)
++ return -EINVAL;
++
++ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
++ on |= MTK_PHY_LED_ON_FDX;
++
++ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
++ on |= MTK_PHY_LED_ON_HDX;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK10;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK100;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK1000;
++
++ if (rules & BIT(TRIGGER_NETDEV_RX)) {
++ blink |= (on & MTK_PHY_LED_ON_LINK) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
++ MTK_PHY_LED_BLINK_RX;
++ }
++
++ if (rules & BIT(TRIGGER_NETDEV_TX)) {
++ blink |= (on & MTK_PHY_LED_ON_LINK) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
++ MTK_PHY_LED_BLINK_TX;
++ }
++
++ if (blink || on)
++ set_bit(bit_netdev, &priv->led_state);
++ else
++ clear_bit(bit_netdev, &priv->led_state);
++
++ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL :
++ MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_FDX |
++ MTK_PHY_LED_ON_HDX |
++ MTK_PHY_LED_ON_LINK,
++ on);
++
++ if (ret)
++ return ret;
++
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL, blink);
++};
++
++static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
++{
++ struct mtk_socphy_shared *priv = phydev->shared->priv;
++ u32 polarities;
++
++ if (led_num == 0)
++ polarities = ~(priv->boottrap);
++ else
++ polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
++
++ if (polarities & BIT(phydev->mdio.addr))
++ return true;
++
++ return false;
++}
++
++static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
++{
++ struct pinctrl *pinctrl;
++ int index;
++
++ /* Setup LED polarity according to bootstrap use of LED pins */
++ for (index = 0; index < 2; ++index)
++ phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_POLARITY,
++ mt7988_phy_led_get_polarity(phydev, index) ?
++ MTK_PHY_LED_ON_POLARITY : 0);
++
++ /* Only now setup pinctrl to avoid bogus blinking */
++ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
++ if (IS_ERR(pinctrl))
++ dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
++
++ return 0;
++}
++
++static int mt7988_phy_probe_shared(struct phy_device *phydev)
++{
++ struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
++ struct mtk_socphy_shared *shared = phydev->shared->priv;
++ struct regmap *regmap;
++ u32 reg;
++ int ret;
++
++ /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
++ * LED_C and LED_D respectively. At the same time those pins are used to
++ * bootstrap configuration of the reference clock source (LED_A),
++ * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
++ * In practise this is done using a LED and a resistor pulling the pin
++ * either to GND or to VIO.
++ * The detected value at boot time is accessible at run-time using the
++ * TPBANK0 register located in the gpio base of the pinctrl, in order
++ * to read it here it needs to be referenced by a phandle called
++ * 'mediatek,pio' in the MDIO bus hosting the PHY.
++ * The 4 bits in TPBANK0 are kept as package shared data and are used to
++ * set LED polarity for each of the LED0.
++ */
++ regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
++ if (IS_ERR(regmap))
++ return PTR_ERR(regmap);
++
++ ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
++ if (ret)
++ return ret;
++
++ shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
++
++ return 0;
++}
++
++static void mt798x_phy_leds_state_init(struct phy_device *phydev)
++{
++ int i;
++
++ for (i = 0; i < 2; ++i)
++ mt798x_phy_led_hw_control_get(phydev, i, NULL);
++}
++
++static int mt7988_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_socphy_shared *shared;
++ struct mtk_socphy_priv *priv;
++ int err;
++
++ if (phydev->mdio.addr > 3)
++ return -EINVAL;
++
++ err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
++ sizeof(struct mtk_socphy_shared));
++ if (err)
++ return err;
++
++ if (phy_package_probe_once(phydev)) {
++ err = mt7988_phy_probe_shared(phydev);
++ if (err)
++ return err;
++ }
++
++ shared = phydev->shared->priv;
++ priv = &shared->priv[phydev->mdio.addr];
++
++ phydev->priv = priv;
++
++ mt798x_phy_leds_state_init(phydev);
++
++ err = mt7988_phy_fix_leds_polarities(phydev);
++ if (err)
++ return err;
++
++ /* Disable TX power saving at probing to:
++ * 1. Meet common mode compliance test criteria
++ * 2. Make sure that TX-VCM calibration works fine
++ */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
++ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
++
++ return mt798x_phy_calibration(phydev);
++}
++
++static int mt7981_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_socphy_priv *priv;
++
++ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ phydev->priv = priv;
++
++ mt798x_phy_leds_state_init(phydev);
++
++ return mt798x_phy_calibration(phydev);
++}
++
++static struct phy_driver mtk_socphy_driver[] = {
++ {
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
++ .name = "MediaTek MT7981 PHY",
++ .config_init = mt798x_phy_config_init,
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .probe = mt7981_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_socphy_read_page,
++ .write_page = mtk_socphy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
++ .led_brightness_set = mt798x_phy_led_brightness_set,
++ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++ .led_hw_control_set = mt798x_phy_led_hw_control_set,
++ .led_hw_control_get = mt798x_phy_led_hw_control_get,
++ },
++ {
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
++ .name = "MediaTek MT7988 PHY",
++ .config_init = mt798x_phy_config_init,
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .probe = mt7988_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_socphy_read_page,
++ .write_page = mtk_socphy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
++ .led_brightness_set = mt798x_phy_led_brightness_set,
++ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++ .led_hw_control_set = mt798x_phy_led_hw_control_set,
++ .led_hw_control_get = mt798x_phy_led_hw_control_get,
++ },
++};
++
++module_phy_driver(mtk_socphy_driver);
++
++static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
++ { }
++};
++
++MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -0,0 +1,148 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/of.h>
++#include <linux/bitfield.h>
++#include <linux/module.h>
++#include <linux/phy.h>
++
++#define MTK_EXT_PAGE_ACCESS 0x1f
++#define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED 0x0001
++#define MTK_PHY_PAGE_EXTENDED_2 0x0002
++#define MTK_PHY_PAGE_EXTENDED_3 0x0003
++#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
++#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++
++static int mtk_gephy_read_page(struct phy_device *phydev)
++{
++ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
++}
++
++static int mtk_gephy_write_page(struct phy_device *phydev, int page)
++{
++ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
++}
++
++static void mtk_gephy_config_init(struct phy_device *phydev)
++{
++ /* Disable EEE */
++ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
++
++ /* Enable HW auto downshift */
++ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
++
++ /* Increase SlvDPSready time */
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ __phy_write(phydev, 0x10, 0xafae);
++ __phy_write(phydev, 0x12, 0x2f);
++ __phy_write(phydev, 0x10, 0x8fae);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ /* Adjust 100_mse_threshold */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
++
++ /* Disable mcc */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
++}
++
++static int mt7530_phy_config_init(struct phy_device *phydev)
++{
++ mtk_gephy_config_init(phydev);
++
++ /* Increase post_update_timer */
++ phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
++
++ return 0;
++}
++
++static int mt7530_led_config_of(struct phy_device *phydev)
++{
++ struct device_node *np = phydev->mdio.dev.of_node;
++ const __be32 *paddr;
++ int len;
++ int i;
++
++ paddr = of_get_property(np, "mediatek,led-config", &len);
++ if (!paddr)
++ return 0;
++
++ if (len < (2 * sizeof(*paddr)))
++ return -EINVAL;
++
++ len /= sizeof(*paddr);
++
++ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len);
++ for (i = 0; i < len - 1; i += 2) {
++ u32 reg;
++ u32 val;
++
++ reg = be32_to_cpup(paddr + i);
++ val = be32_to_cpup(paddr + i + 1);
++
++ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val);
++ }
++
++ return 0;
++}
++
++static int mt7531_phy_config_init(struct phy_device *phydev)
++{
++ mtk_gephy_config_init(phydev);
++
++ /* PHY link down power saving enable */
++ phy_set_bits(phydev, 0x17, BIT(4));
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
++
++ /* Set TX Pair delay selection */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
++
++ /* LED Config*/
++ mt7530_led_config_of(phydev);
++
++ return 0;
++}
++
++static struct phy_driver mtk_gephy_driver[] = {
++ {
++ PHY_ID_MATCH_EXACT(0x03a29412),
++ .name = "MediaTek MT7530 PHY",
++ .config_init = mt7530_phy_config_init,
++ /* Interrupts are handled by the switch, not the PHY
++ * itself.
++ */
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_gephy_read_page,
++ .write_page = mtk_gephy_write_page,
++ },
++ {
++ PHY_ID_MATCH_EXACT(0x03a29441),
++ .name = "MediaTek MT7531 PHY",
++ .config_init = mt7531_phy_config_init,
++ /* Interrupts are handled by the switch, not the PHY
++ * itself.
++ */
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_gephy_read_page,
++ .write_page = mtk_gephy_write_page,
++ },
++};
++
++module_phy_driver(mtk_gephy_driver);
++
++static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
++ { PHY_ID_MATCH_EXACT(0x03a29441) },
++ { PHY_ID_MATCH_EXACT(0x03a29412) },
++ { }
++};
++
++MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
++MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);
diff --git a/target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch b/target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch
new file mode 100644
index 0000000000..901949fe9f
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch
@@ -0,0 +1,62 @@
+From 12054d38fc55adbfa2b40299ad8af3449d882ee2 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:06 +0800
+Subject: [PATCH 02/13] net: phy: mediatek: Fix spelling errors and rearrange
+ variables
+
+This patch fixes spelling errors which comes from mediatek-ge-soc.c and
+rearrange variables with reverse Xmas tree order.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -408,16 +408,17 @@ static int tx_offset_cal_efuse(struct ph
+
+ static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
+ {
+- int i;
+- int bias[16] = {};
+- const int vals_9461[16] = { 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7 };
+ const int vals_9481[16] = { 10, 6, 6, 10,
+ 10, 6, 6, 10,
+ 10, 6, 6, 10,
+ 10, 6, 6, 10 };
++ const int vals_9461[16] = { 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7 };
++ int bias[16] = {};
++ int i;
++
+ switch (phydev->drv->phy_id) {
+ case MTK_GPHY_ID_MT7981:
+ /* We add some calibration to efuse values
+@@ -1069,10 +1070,10 @@ static int start_cal(struct phy_device *
+
+ static int mt798x_phy_calibration(struct phy_device *phydev)
+ {
++ struct nvmem_cell *cell;
+ int ret = 0;
+- u32 *buf;
+ size_t len;
+- struct nvmem_cell *cell;
++ u32 *buf;
+
+ cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
+ if (IS_ERR(cell)) {
+@@ -1415,7 +1416,7 @@ static int mt7988_phy_probe_shared(struc
+ * LED_C and LED_D respectively. At the same time those pins are used to
+ * bootstrap configuration of the reference clock source (LED_A),
+ * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
+- * In practise this is done using a LED and a resistor pulling the pin
++ * In practice this is done using a LED and a resistor pulling the pin
+ * either to GND or to VIO.
+ * The detected value at boot time is accessible at run-time using the
+ * TPBANK0 register located in the gpio base of the pinctrl, in order
diff --git a/target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch b/target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch
new file mode 100644
index 0000000000..9e6ae4b136
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch
@@ -0,0 +1,742 @@
+From 434e41555c45ec10b19320024163bb009da168bc Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:07 +0800
+Subject: [PATCH 03/13] net: phy: mediatek: Move LED helper functions into mtk
+ phy lib
+
+This patch creates mtk-phy-lib.c & mtk-phy.h and integrates mtk-ge-soc.c's
+LED helper functions so that we can use those helper functions in other
+MTK's ethernet phy driver.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/Kconfig | 5 +
+ drivers/net/phy/mediatek/Makefile | 1 +
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 262 +++----------------------
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 251 +++++++++++++++++++++++
+ drivers/net/phy/mediatek/mtk.h | 82 ++++++++
+ 6 files changed, 368 insertions(+), 235 deletions(-)
+ create mode 100644 drivers/net/phy/mediatek/mtk-phy-lib.c
+ create mode 100644 drivers/net/phy/mediatek/mtk.h
+
+--- a/drivers/net/phy/mediatek/Kconfig
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -1,6 +1,10 @@
+ # SPDX-License-Identifier: GPL-2.0-only
++config MTK_NET_PHYLIB
++ tristate
++
+ config MEDIATEK_GE_PHY
+ tristate "MediaTek Gigabit Ethernet PHYs"
++ select MTK_NET_PHYLIB
+ help
+ Supports the MediaTek non-built-in Gigabit Ethernet PHYs.
+
+@@ -13,6 +17,7 @@ config MEDIATEK_GE_SOC_PHY
+ tristate "MediaTek SoC Ethernet PHYs"
+ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
+ select NVMEM_MTK_EFUSE
++ select MTK_NET_PHYLIB
+ help
+ Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
+
+--- a/drivers/net/phy/mediatek/Makefile
++++ b/drivers/net/phy/mediatek/Makefile
+@@ -1,3 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o
+ obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -8,6 +8,8 @@
+ #include <linux/phy.h>
+ #include <linux/regmap.h>
+
++#include "mtk.h"
++
+ #define MTK_GPHY_ID_MT7981 0x03a29461
+ #define MTK_GPHY_ID_MT7988 0x03a29481
+
+@@ -210,41 +212,6 @@
+ #define MTK_PHY_DA_TX_R50_PAIR_D 0x540
+
+ /* Registers on MDIO_MMD_VEND2 */
+-#define MTK_PHY_LED0_ON_CTRL 0x24
+-#define MTK_PHY_LED1_ON_CTRL 0x26
+-#define MTK_PHY_LED_ON_MASK GENMASK(6, 0)
+-#define MTK_PHY_LED_ON_LINK1000 BIT(0)
+-#define MTK_PHY_LED_ON_LINK100 BIT(1)
+-#define MTK_PHY_LED_ON_LINK10 BIT(2)
+-#define MTK_PHY_LED_ON_LINK (MTK_PHY_LED_ON_LINK10 |\
+- MTK_PHY_LED_ON_LINK100 |\
+- MTK_PHY_LED_ON_LINK1000)
+-#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
+-#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
+-#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
+-#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
+-#define MTK_PHY_LED_ON_POLARITY BIT(14)
+-#define MTK_PHY_LED_ON_ENABLE BIT(15)
+-
+-#define MTK_PHY_LED0_BLINK_CTRL 0x25
+-#define MTK_PHY_LED1_BLINK_CTRL 0x27
+-#define MTK_PHY_LED_BLINK_1000TX BIT(0)
+-#define MTK_PHY_LED_BLINK_1000RX BIT(1)
+-#define MTK_PHY_LED_BLINK_100TX BIT(2)
+-#define MTK_PHY_LED_BLINK_100RX BIT(3)
+-#define MTK_PHY_LED_BLINK_10TX BIT(4)
+-#define MTK_PHY_LED_BLINK_10RX BIT(5)
+-#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\
+- MTK_PHY_LED_BLINK_100RX |\
+- MTK_PHY_LED_BLINK_1000RX)
+-#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\
+- MTK_PHY_LED_BLINK_100TX |\
+- MTK_PHY_LED_BLINK_1000TX)
+-#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
+-#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
+-#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
+-#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
+-
+ #define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1)
+
+ #define MTK_PHY_RG_BG_RASEL 0x115
+@@ -299,10 +266,6 @@ enum CAL_MODE {
+ SW_M
+ };
+
+-#define MTK_PHY_LED_STATE_FORCE_ON 0
+-#define MTK_PHY_LED_STATE_FORCE_BLINK 1
+-#define MTK_PHY_LED_STATE_NETDEV 2
+-
+ struct mtk_socphy_priv {
+ unsigned long led_state;
+ };
+@@ -1131,84 +1094,39 @@ static int mt798x_phy_config_init(struct
+ return mt798x_phy_calibration(phydev);
+ }
+
+-static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
+- bool on)
+-{
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (on)
+- changed = !test_and_set_bit(bit_on, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_on, &priv->led_state);
+-
+- changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_MASK,
+- on ? MTK_PHY_LED_ON_FORCE_ON : 0);
+- else
+- return 0;
+-}
+-
+-static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
+- bool blinking)
+-{
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (blinking)
+- changed = !test_and_set_bit(bit_blink, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
+-
+- changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
+- blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
+- else
+- return 0;
+-}
+-
+ static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+ {
++ struct mtk_socphy_priv *priv = phydev->priv;
+ bool blinking = false;
+ int err = 0;
+
+- if (index > 1)
+- return -EINVAL;
+-
+- if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
+- blinking = true;
+- *delay_on = 50;
+- *delay_off = 50;
+- }
++ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
++ if (err < 0)
++ return err;
+
+- err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state,
++ blinking);
+ if (err)
+ return err;
+
+- return mt798x_phy_hw_led_on_set(phydev, index, false);
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, false);
+ }
+
+ static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
+ u8 index, enum led_brightness value)
+ {
++ struct mtk_socphy_priv *priv = phydev->priv;
+ int err;
+
+- err = mt798x_phy_hw_led_blink_set(phydev, index, false);
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false);
+ if (err)
+ return err;
+
+- return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, (value != LED_OFF));
+ }
+
+ static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+@@ -1223,148 +1141,30 @@ static const unsigned long supported_tri
+ static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+ {
+- if (index > 1)
+- return -EINVAL;
+-
+- /* All combinations of the supported triggers are allowed */
+- if (rules & ~supported_triggers)
+- return -EOPNOTSUPP;
+-
+- return 0;
+-};
++ return mtk_phy_led_hw_is_supported(phydev, index, rules,
++ supported_triggers);
++}
+
+ static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
+ unsigned long *rules)
+ {
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+ struct mtk_socphy_priv *priv = phydev->priv;
+- int on, blink;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
+-
+- if (on < 0)
+- return -EIO;
+-
+- blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL);
+- if (blink < 0)
+- return -EIO;
+-
+- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINKDOWN)) ||
+- (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- if (on & MTK_PHY_LED_ON_FORCE_ON)
+- set_bit(bit_on, &priv->led_state);
+- else
+- clear_bit(bit_on, &priv->led_state);
+-
+- if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
+- set_bit(bit_blink, &priv->led_state);
+- else
+- clear_bit(bit_blink, &priv->led_state);
+-
+- if (!rules)
+- return 0;
+-
+- if (on & MTK_PHY_LED_ON_LINK)
+- *rules |= BIT(TRIGGER_NETDEV_LINK);
+
+- if (on & MTK_PHY_LED_ON_LINK10)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_10);
+-
+- if (on & MTK_PHY_LED_ON_LINK100)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_100);
+-
+- if (on & MTK_PHY_LED_ON_LINK1000)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
+-
+- if (on & MTK_PHY_LED_ON_FDX)
+- *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
+-
+- if (on & MTK_PHY_LED_ON_HDX)
+- *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
+-
+- if (blink & MTK_PHY_LED_BLINK_RX)
+- *rules |= BIT(TRIGGER_NETDEV_RX);
+-
+- if (blink & MTK_PHY_LED_BLINK_TX)
+- *rules |= BIT(TRIGGER_NETDEV_TX);
+-
+- return 0;
++ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
+ };
+
+ static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+ {
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+ struct mtk_socphy_priv *priv = phydev->priv;
+- u16 on = 0, blink = 0;
+- int ret;
+
+- if (index > 1)
+- return -EINVAL;
+-
+- if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
+- on |= MTK_PHY_LED_ON_FDX;
+-
+- if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
+- on |= MTK_PHY_LED_ON_HDX;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK10;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK100;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK1000;
+-
+- if (rules & BIT(TRIGGER_NETDEV_RX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
+- MTK_PHY_LED_BLINK_RX;
+- }
+-
+- if (rules & BIT(TRIGGER_NETDEV_TX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
+- MTK_PHY_LED_BLINK_TX;
+- }
+-
+- if (blink || on)
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL :
+- MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_FDX |
+- MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINK,
+- on);
+-
+- if (ret)
+- return ret;
+-
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL, blink);
++ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
+ };
+
+ static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
+@@ -1438,14 +1238,6 @@ static int mt7988_phy_probe_shared(struc
+ return 0;
+ }
+
+-static void mt798x_phy_leds_state_init(struct phy_device *phydev)
+-{
+- int i;
+-
+- for (i = 0; i < 2; ++i)
+- mt798x_phy_led_hw_control_get(phydev, i, NULL);
+-}
+-
+ static int mt7988_phy_probe(struct phy_device *phydev)
+ {
+ struct mtk_socphy_shared *shared;
+@@ -1471,7 +1263,7 @@ static int mt7988_phy_probe(struct phy_d
+
+ phydev->priv = priv;
+
+- mt798x_phy_leds_state_init(phydev);
++ mtk_phy_leds_state_init(phydev);
+
+ err = mt7988_phy_fix_leds_polarities(phydev);
+ if (err)
+@@ -1498,7 +1290,7 @@ static int mt7981_phy_probe(struct phy_d
+
+ phydev->priv = priv;
+
+- mt798x_phy_leds_state_init(phydev);
++ mtk_phy_leds_state_init(phydev);
+
+ return mt798x_phy_calibration(phydev);
+ }
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -0,0 +1,251 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <linux/phy.h>
++#include <linux/module.h>
++
++#include <linux/netdevice.h>
++
++#include "mtk.h"
++
++int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules,
++ unsigned long supported_triggers)
++{
++ if (index > 1)
++ return -EINVAL;
++
++ /* All combinations of the supported triggers are allowed */
++ if (rules & ~supported_triggers)
++ return -EOPNOTSUPP;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_hw_is_supported);
++
++int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
++ (index ? 16 : 0);
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ int on, blink;
++
++ if (index > 1)
++ return -EINVAL;
++
++ on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
++
++ if (on < 0)
++ return -EIO;
++
++ blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL);
++ if (blink < 0)
++ return -EIO;
++
++ if ((on & (on_set | MTK_PHY_LED_ON_FDX |
++ MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) ||
++ (blink & (rx_blink_set | tx_blink_set)))
++ set_bit(bit_netdev, led_state);
++ else
++ clear_bit(bit_netdev, led_state);
++
++ if (on & MTK_PHY_LED_ON_FORCE_ON)
++ set_bit(bit_on, led_state);
++ else
++ clear_bit(bit_on, led_state);
++
++ if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
++ set_bit(bit_blink, led_state);
++ else
++ clear_bit(bit_blink, led_state);
++
++ if (!rules)
++ return 0;
++
++ if (on & on_set)
++ *rules |= BIT(TRIGGER_NETDEV_LINK);
++
++ if (on & MTK_PHY_LED_ON_LINK10)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_10);
++
++ if (on & MTK_PHY_LED_ON_LINK100)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_100);
++
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++ if (on & MTK_PHY_LED_ON_LINK2500)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_2500);
++
++ if (on & MTK_PHY_LED_ON_FDX)
++ *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
++
++ if (on & MTK_PHY_LED_ON_HDX)
++ *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
++
++ if (blink & rx_blink_set)
++ *rules |= BIT(TRIGGER_NETDEV_RX);
++
++ if (blink & tx_blink_set)
++ *rules |= BIT(TRIGGER_NETDEV_TX);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_get);
++
++int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index,
++ unsigned long rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set)
++{
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ u16 on = 0, blink = 0;
++ int ret;
++
++ if (index > 1)
++ return -EINVAL;
++
++ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
++ on |= MTK_PHY_LED_ON_FDX;
++
++ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
++ on |= MTK_PHY_LED_ON_HDX;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK10;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK100;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK1000;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK2500;
++
++ if (rules & BIT(TRIGGER_NETDEV_RX)) {
++ blink |= (on & on_set) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ?
++ MTK_PHY_LED_BLINK_10RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ?
++ MTK_PHY_LED_BLINK_100RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ?
++ MTK_PHY_LED_BLINK_1000RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK2500) ?
++ MTK_PHY_LED_BLINK_2500RX : 0)) :
++ rx_blink_set;
++ }
++
++ if (rules & BIT(TRIGGER_NETDEV_TX)) {
++ blink |= (on & on_set) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ?
++ MTK_PHY_LED_BLINK_10TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ?
++ MTK_PHY_LED_BLINK_100TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ?
++ MTK_PHY_LED_BLINK_1000TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK2500) ?
++ MTK_PHY_LED_BLINK_2500TX : 0)) :
++ tx_blink_set;
++ }
++
++ if (blink || on)
++ set_bit(bit_netdev, led_state);
++ else
++ clear_bit(bit_netdev, led_state);
++
++ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | on_set,
++ on);
++
++ if (ret)
++ return ret;
++
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL, blink);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_set);
++
++int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on,
++ unsigned long *delay_off, bool *blinking)
++{
++ if (index > 1)
++ return -EINVAL;
++
++ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
++ *blinking = true;
++ *delay_on = 50;
++ *delay_off = 50;
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_num_dly_cfg);
++
++int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, u16 led_on_mask, bool on)
++{
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ bool changed;
++
++ if (on)
++ changed = !test_and_set_bit(bit_on, led_state);
++ else
++ changed = !!test_and_clear_bit(bit_on, led_state);
++
++ changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), led_state);
++ if (changed)
++ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL :
++ MTK_PHY_LED0_ON_CTRL,
++ led_on_mask,
++ on ? MTK_PHY_LED_ON_FORCE_ON : 0);
++ else
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_hw_led_on_set);
++
++int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, bool blinking)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
++ (index ? 16 : 0);
++ bool changed;
++
++ if (blinking)
++ changed = !test_and_set_bit(bit_blink, led_state);
++ else
++ changed = !!test_and_clear_bit(bit_blink, led_state);
++
++ changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), led_state);
++ if (changed)
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL,
++ blinking ?
++ MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
++ else
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_hw_led_blink_set);
++
++void mtk_phy_leds_state_init(struct phy_device *phydev)
++{
++ int i;
++
++ for (i = 0; i < 2; ++i)
++ phydev->drv->led_hw_control_get(phydev, i, NULL);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_leds_state_init);
++
++MODULE_DESCRIPTION("MediaTek Ethernet PHY driver common");
++MODULE_AUTHOR("Sky Huang <SkyLake.Huang@mediatek.com>");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -0,0 +1,82 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Common definition for Mediatek Ethernet PHYs
++ * Author: SkyLake Huang <SkyLake.Huang@mediatek.com>
++ * Copyright (c) 2024 MediaTek Inc.
++ */
++
++#ifndef _MTK_EPHY_H_
++#define _MTK_EPHY_H_
++
++#define MTK_EXT_PAGE_ACCESS 0x1f
++
++/* Registers on MDIO_MMD_VEND2 */
++#define MTK_PHY_LED0_ON_CTRL 0x24
++#define MTK_PHY_LED1_ON_CTRL 0x26
++#define MTK_GPHY_LED_ON_MASK GENMASK(6, 0)
++#define MTK_2P5GPHY_LED_ON_MASK GENMASK(7, 0)
++#define MTK_PHY_LED_ON_LINK1000 BIT(0)
++#define MTK_PHY_LED_ON_LINK100 BIT(1)
++#define MTK_PHY_LED_ON_LINK10 BIT(2)
++#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
++#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
++#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
++#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
++#define MTK_PHY_LED_ON_LINK2500 BIT(7)
++#define MTK_PHY_LED_ON_POLARITY BIT(14)
++#define MTK_PHY_LED_ON_ENABLE BIT(15)
++
++#define MTK_PHY_LED0_BLINK_CTRL 0x25
++#define MTK_PHY_LED1_BLINK_CTRL 0x27
++#define MTK_PHY_LED_BLINK_1000TX BIT(0)
++#define MTK_PHY_LED_BLINK_1000RX BIT(1)
++#define MTK_PHY_LED_BLINK_100TX BIT(2)
++#define MTK_PHY_LED_BLINK_100RX BIT(3)
++#define MTK_PHY_LED_BLINK_10TX BIT(4)
++#define MTK_PHY_LED_BLINK_10RX BIT(5)
++#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
++#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
++#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
++#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
++#define MTK_PHY_LED_BLINK_2500TX BIT(10)
++#define MTK_PHY_LED_BLINK_2500RX BIT(11)
++
++#define MTK_GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK1000 | \
++ MTK_PHY_LED_ON_LINK100 | \
++ MTK_PHY_LED_ON_LINK10)
++#define MTK_GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \
++ MTK_PHY_LED_BLINK_100RX | \
++ MTK_PHY_LED_BLINK_10RX)
++#define MTK_GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \
++ MTK_PHY_LED_BLINK_100RX | \
++ MTK_PHY_LED_BLINK_10RX)
++
++#define MTK_2P5GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK2500 | \
++ MTK_GPHY_LED_ON_SET)
++#define MTK_2P5GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \
++ MTK_GPHY_LED_RX_BLINK_SET)
++#define MTK_2P5GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \
++ MTK_GPHY_LED_TX_BLINK_SET)
++
++#define MTK_PHY_LED_STATE_FORCE_ON 0
++#define MTK_PHY_LED_STATE_FORCE_BLINK 1
++#define MTK_PHY_LED_STATE_NETDEV 2
++
++int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules,
++ unsigned long supported_triggers);
++int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index,
++ unsigned long rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set);
++int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set);
++int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on,
++ unsigned long *delay_off, bool *blinking);
++int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, u16 led_on_mask, bool on);
++int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, bool blinking);
++void mtk_phy_leds_state_init(struct phy_device *phydev);
++
++#endif /* _MTK_EPHY_H_ */
diff --git a/target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch b/target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch
new file mode 100644
index 0000000000..717dc890e3
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch
@@ -0,0 +1,70 @@
+From 2783929879854d5750ba82e2e203663313362abb Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:08 +0800
+Subject: [PATCH 04/13] net: phy: mediatek: Improve readability of
+ mtk-phy-lib.c's mtk_phy_led_hw_ctrl_set()
+
+This patch removes parens around TRIGGER_NETDEV_RX/TRIGGER_NETDEV_TX in
+mtk_phy_led_hw_ctrl_set(), which improves readability.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 44 ++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -127,29 +127,33 @@ int mtk_phy_led_hw_ctrl_set(struct phy_d
+ on |= MTK_PHY_LED_ON_LINK2500;
+
+ if (rules & BIT(TRIGGER_NETDEV_RX)) {
+- blink |= (on & on_set) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ?
+- MTK_PHY_LED_BLINK_10RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ?
+- MTK_PHY_LED_BLINK_100RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ?
+- MTK_PHY_LED_BLINK_1000RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK2500) ?
+- MTK_PHY_LED_BLINK_2500RX : 0)) :
+- rx_blink_set;
++ if (on & on_set) {
++ if (on & MTK_PHY_LED_ON_LINK10)
++ blink |= MTK_PHY_LED_BLINK_10RX;
++ if (on & MTK_PHY_LED_ON_LINK100)
++ blink |= MTK_PHY_LED_BLINK_100RX;
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ blink |= MTK_PHY_LED_BLINK_1000RX;
++ if (on & MTK_PHY_LED_ON_LINK2500)
++ blink |= MTK_PHY_LED_BLINK_2500RX;
++ } else {
++ blink |= rx_blink_set;
++ }
+ }
+
+ if (rules & BIT(TRIGGER_NETDEV_TX)) {
+- blink |= (on & on_set) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ?
+- MTK_PHY_LED_BLINK_10TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ?
+- MTK_PHY_LED_BLINK_100TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ?
+- MTK_PHY_LED_BLINK_1000TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK2500) ?
+- MTK_PHY_LED_BLINK_2500TX : 0)) :
+- tx_blink_set;
++ if (on & on_set) {
++ if (on & MTK_PHY_LED_ON_LINK10)
++ blink |= MTK_PHY_LED_BLINK_10TX;
++ if (on & MTK_PHY_LED_ON_LINK100)
++ blink |= MTK_PHY_LED_BLINK_100TX;
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ blink |= MTK_PHY_LED_BLINK_1000TX;
++ if (on & MTK_PHY_LED_ON_LINK2500)
++ blink |= MTK_PHY_LED_BLINK_2500TX;
++ } else {
++ blink |= tx_blink_set;
++ }
+ }
+
+ if (blink || on)
diff --git a/target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch b/target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch
new file mode 100644
index 0000000000..4a112a202c
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch
@@ -0,0 +1,141 @@
+From 58c1270423ab48464cdc31ef71ffe7f5b2441961 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:09 +0800
+Subject: [PATCH 05/13] net: phy: mediatek: Integrate read/write page helper
+ functions
+
+This patch integrates read/write page helper functions as MTK phy lib.
+They are basically the same in mtk-ge.c & mtk-ge-soc.c.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 18 ++++--------------
+ drivers/net/phy/mediatek/mtk-ge.c | 20 ++++++--------------
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 12 ++++++++++++
+ drivers/net/phy/mediatek/mtk.h | 3 +++
+ 4 files changed, 25 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -275,16 +275,6 @@ struct mtk_socphy_shared {
+ struct mtk_socphy_priv priv[4];
+ };
+
+-static int mtk_socphy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_socphy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+ /* One calibration cycle consists of:
+ * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
+ * until AD_CAL_COMP is ready to output calibration result.
+@@ -1305,8 +1295,8 @@ static struct phy_driver mtk_socphy_driv
+ .probe = mt7981_phy_probe,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+@@ -1322,8 +1312,8 @@ static struct phy_driver mtk_socphy_driv
+ .probe = mt7988_phy_probe,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -4,6 +4,8 @@
+ #include <linux/module.h>
+ #include <linux/phy.h>
+
++#include "mtk.h"
++
+ #define MTK_EXT_PAGE_ACCESS 0x1f
+ #define MTK_PHY_PAGE_STANDARD 0x0000
+ #define MTK_PHY_PAGE_EXTENDED 0x0001
+@@ -12,16 +14,6 @@
+ #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+ #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
+-static int mtk_gephy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_gephy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+ static void mtk_gephy_config_init(struct phy_device *phydev)
+ {
+ /* Disable EEE */
+@@ -114,8 +106,8 @@ static struct phy_driver mtk_gephy_drive
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ },
+ {
+ PHY_ID_MATCH_EXACT(0x03a29441),
+@@ -128,8 +120,8 @@ static struct phy_driver mtk_gephy_drive
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ },
+ };
+
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -6,6 +6,18 @@
+
+ #include "mtk.h"
+
++int mtk_phy_read_page(struct phy_device *phydev)
++{
++ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_read_page);
++
++int mtk_phy_write_page(struct phy_device *phydev, int page)
++{
++ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_write_page);
++
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers)
+--- a/drivers/net/phy/mediatek/mtk.h
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -62,6 +62,9 @@
+ #define MTK_PHY_LED_STATE_FORCE_BLINK 1
+ #define MTK_PHY_LED_STATE_NETDEV 2
+
++int mtk_phy_read_page(struct phy_device *phydev);
++int mtk_phy_write_page(struct phy_device *phydev, int page);
++
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers);
diff --git a/target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch b/target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch
new file mode 100644
index 0000000000..485e262134
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch
@@ -0,0 +1,146 @@
+From 9403f1d54598ae56386a8bf47a5b6b34c884e4f5 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:10 +0800
+Subject: [PATCH 06/13] net: phy: mediatek: Hook LED helper functions in
+ mtk-ge.c
+
+We have mtk-phy-lib.c now so that we can use LED helper functions in
+mtk-ge.c(mt7531 part). It also means that mt7531/mt7981/mt7988's
+Giga ethernet phys share almost the same HW LED controller design.
+Also, add probe function for mt7531 so that it can initialize LED state.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge.c | 100 ++++++++++++++++++++++++++++++
+ 1 file changed, 100 insertions(+)
+
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -14,6 +14,10 @@
+ #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+ #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
++struct mtk_gephy_priv {
++ unsigned long led_state;
++};
++
+ static void mtk_gephy_config_init(struct phy_device *phydev)
+ {
+ /* Disable EEE */
+@@ -94,6 +98,96 @@ static int mt7531_phy_config_init(struct
+ return 0;
+ }
+
++static int mt7531_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_gephy_priv *priv;
++
++ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_gephy_priv),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ phydev->priv = priv;
++
++ mtk_phy_leds_state_init(phydev);
++
++ return 0;
++}
++
++static int mt753x_phy_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *delay_on,
++ unsigned long *delay_off)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++ bool blinking = false;
++ int err = 0;
++
++ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
++ if (err < 0)
++ return err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state,
++ blinking);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, false);
++}
++
++static int mt753x_phy_led_brightness_set(struct phy_device *phydev,
++ u8 index, enum led_brightness value)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++ int err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, (value != LED_OFF));
++}
++
++static const unsigned long supported_triggers =
++ (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX));
++
++static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ return mtk_phy_led_hw_is_supported(phydev, index, rules,
++ supported_triggers);
++}
++
++static int mt753x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
++};
++
++static int mt753x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
++};
++
+ static struct phy_driver mtk_gephy_driver[] = {
+ {
+ PHY_ID_MATCH_EXACT(0x03a29412),
+@@ -112,6 +206,7 @@ static struct phy_driver mtk_gephy_drive
+ {
+ PHY_ID_MATCH_EXACT(0x03a29441),
+ .name = "MediaTek MT7531 PHY",
++ .probe = mt7531_phy_probe,
+ .config_init = mt7531_phy_config_init,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+@@ -122,6 +217,11 @@ static struct phy_driver mtk_gephy_drive
+ .resume = genphy_resume,
+ .read_page = mtk_phy_read_page,
+ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt753x_phy_led_blink_set,
++ .led_brightness_set = mt753x_phy_led_brightness_set,
++ .led_hw_is_supported = mt753x_phy_led_hw_is_supported,
++ .led_hw_control_set = mt753x_phy_led_hw_control_set,
++ .led_hw_control_get = mt753x_phy_led_hw_control_get,
+ },
+ };
+
diff --git a/target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch b/target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch
new file mode 100644
index 0000000000..bfdf864f8d
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch
@@ -0,0 +1,54 @@
+From 51ee83602dbb84716180d9b6e43f6bebb0c2d7bd Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:11 +0800
+Subject: [PATCH 07/13] net: phy: mediatek: add MT7530 & MT7531's PHY ID macros
+
+This patch adds MT7530 & MT7531's PHY ID macros in mtk-ge.c so that
+it follows the same rule of mtk-ge-soc.c.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -6,6 +6,9 @@
+
+ #include "mtk.h"
+
++#define MTK_GPHY_ID_MT7530 0x03a29412
++#define MTK_GPHY_ID_MT7531 0x03a29441
++
+ #define MTK_EXT_PAGE_ACCESS 0x1f
+ #define MTK_PHY_PAGE_STANDARD 0x0000
+ #define MTK_PHY_PAGE_EXTENDED 0x0001
+@@ -190,7 +193,7 @@ static int mt753x_phy_led_hw_control_set
+
+ static struct phy_driver mtk_gephy_driver[] = {
+ {
+- PHY_ID_MATCH_EXACT(0x03a29412),
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
+ .name = "MediaTek MT7530 PHY",
+ .config_init = mt7530_phy_config_init,
+ /* Interrupts are handled by the switch, not the PHY
+@@ -204,7 +207,7 @@ static struct phy_driver mtk_gephy_drive
+ .write_page = mtk_phy_write_page,
+ },
+ {
+- PHY_ID_MATCH_EXACT(0x03a29441),
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
+ .name = "MediaTek MT7531 PHY",
+ .probe = mt7531_phy_probe,
+ .config_init = mt7531_phy_config_init,
+@@ -228,8 +231,8 @@ static struct phy_driver mtk_gephy_drive
+ module_phy_driver(mtk_gephy_driver);
+
+ static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
+- { PHY_ID_MATCH_EXACT(0x03a29441) },
+- { PHY_ID_MATCH_EXACT(0x03a29412) },
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) },
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) },
+ { }
+ };
+
diff --git a/target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch b/target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch
new file mode 100644
index 0000000000..ca155e5012
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch
@@ -0,0 +1,182 @@
+From e73df692396b0d6bdcb2317299fa1e8e547f3446 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:12 +0800
+Subject: [PATCH 08/13] net: phy: mediatek: Change mtk-ge-soc.c line wrapping
+
+This patch shrinks mtk-ge-soc.c line wrapping to 80 characters.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 67 +++++++++++++++++----------
+ 1 file changed, 42 insertions(+), 25 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -295,7 +295,8 @@ static int cal_cycle(struct phy_device *
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ MTK_PHY_RG_AD_CAL_CLK, reg_val,
+ reg_val & MTK_PHY_DA_CAL_CLK, 500,
+- ANALOG_INTERNAL_OPERATION_MAX_US, false);
++ ANALOG_INTERNAL_OPERATION_MAX_US,
++ false);
+ if (ret) {
+ phydev_err(phydev, "Calibration cycle timeout\n");
+ return ret;
+@@ -304,7 +305,7 @@ static int cal_cycle(struct phy_device *
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+ MTK_PHY_DA_CALIN_FLAG);
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
+- MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
++ MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
+ phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
+
+ return ret;
+@@ -394,38 +395,46 @@ static int tx_amp_fill_result(struct phy
+ }
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+- MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
++ MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
++ (buf[0] + bias[0]) << 10);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+ MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+- MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
++ MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
++ (buf[0] + bias[2]) << 10);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+ MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+- MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
++ MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
++ (buf[1] + bias[4]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+ MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+- MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
++ MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
++ (buf[1] + bias[6]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+ MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+- MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
++ MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
++ (buf[2] + bias[8]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+ MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+- MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
++ MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
++ (buf[2] + bias[10]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+ MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+- MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
++ MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
++ (buf[3] + bias[12]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+ MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+- MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
++ MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
++ (buf[3] + bias[14]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+ MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
+
+@@ -616,7 +625,8 @@ static int tx_vcm_cal_sw(struct phy_devi
+ goto restore;
+
+ /* We calibrate TX-VCM in different logic. Check upper index and then
+- * lower index. If this calibration is valid, apply lower index's result.
++ * lower index. If this calibration is valid, apply lower index's
++ * result.
+ */
+ ret = upper_ret - lower_ret;
+ if (ret == 1) {
+@@ -645,7 +655,8 @@ static int tx_vcm_cal_sw(struct phy_devi
+ } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
+ lower_ret == 0) {
+ ret = 0;
+- phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
++ phydev_warn(phydev,
++ "TX-VCM SW cal result at high margin 0x%x\n",
+ upper_idx);
+ } else {
+ ret = -EINVAL;
+@@ -749,7 +760,8 @@ static void mt7981_phy_finetune(struct p
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK |
++ MTK_PHY_LPF_X_AVERAGE_MASK,
+ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
+
+ /* rg_tr_lpf_cnt_val = 512 */
+@@ -818,7 +830,8 @@ static void mt7988_phy_finetune(struct p
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK |
++ MTK_PHY_LPF_X_AVERAGE_MASK,
+ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
+
+ /* rg_tr_lpf_cnt_val = 1023 */
+@@ -930,7 +943,8 @@ static void mt798x_phy_eee(struct phy_de
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
+- __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
++ __phy_modify(phydev, MTK_PHY_LPI_REG_14,
++ MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
+ FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
+
+ __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
+@@ -940,7 +954,8 @@ static void mt798x_phy_eee(struct phy_de
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
+ MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ 0xff));
+ }
+
+ static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
+@@ -1119,14 +1134,15 @@ static int mt798x_phy_led_brightness_set
+ MTK_GPHY_LED_ON_MASK, (value != LED_OFF));
+ }
+
+-static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
++static const unsigned long supported_triggers =
++ (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX));
+
+ static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+@@ -1189,7 +1205,8 @@ static int mt7988_phy_fix_leds_polaritie
+ /* Only now setup pinctrl to avoid bogus blinking */
+ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
+ if (IS_ERR(pinctrl))
+- dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
++ dev_err(&phydev->mdio.bus->dev,
++ "Failed to setup PHY LED pinctrl\n");
+
+ return 0;
+ }
diff --git a/target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch b/target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch
new file mode 100644
index 0000000000..49e4c2057f
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch
@@ -0,0 +1,614 @@
+From 60228de48d8bfde62b4db5945314e6a62079f091 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:13 +0800
+Subject: [PATCH 09/13] net: phy: mediatek: Add token ring access helper
+ functions in mtk-phy-lib
+
+This patch adds TR(token ring) manipulations and adds correct
+macro names for those magic numbers. TR is a way to access
+proprietary registers on page 52b5. Use these helper functions
+so we can see which fields we're going to modify/set/clear.
+
+This patch doesn't really change registers' settings but just
+enhances readability and maintainability.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 297 ++++++++++++++++---------
+ drivers/net/phy/mediatek/mtk-ge.c | 82 +++++--
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 91 ++++++++
+ drivers/net/phy/mediatek/mtk.h | 13 ++
+ 4 files changed, 358 insertions(+), 125 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -24,7 +24,108 @@
+ #define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8)
+
+ #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x0, node_addr = 0x7, data_addr = 0x15 */
++/* NormMseLoThresh */
++#define NORMAL_MSE_LO_THRESH_MASK GENMASK(15, 8)
++
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
++/* RemAckCntLimitCtrl */
++#define REMOTE_ACK_COUNT_LIMIT_CTRL_MASK GENMASK(2, 1)
++
++/* ch_addr = 0x1, node_addr = 0xd, data_addr = 0x20 */
++/* VcoSlicerThreshBitsHigh */
++#define VCO_SLICER_THRESH_HIGH_MASK GENMASK(23, 0)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x0 */
++/* DfeTailEnableVgaThresh1000 */
++#define DFE_TAIL_EANBLE_VGA_TRHESH_1000 GENMASK(5, 1)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x1 */
++/* MrvlTrFix100Kp */
++#define MRVL_TR_FIX_100KP_MASK GENMASK(22, 20)
++/* MrvlTrFix100Kf */
++#define MRVL_TR_FIX_100KF_MASK GENMASK(19, 17)
++/* MrvlTrFix1000Kp */
++#define MRVL_TR_FIX_1000KP_MASK GENMASK(16, 14)
++/* MrvlTrFix1000Kf */
++#define MRVL_TR_FIX_1000KF_MASK GENMASK(13, 11)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x12 */
++/* VgaDecRate */
++#define VGA_DECIMATION_RATE_MASK GENMASK(8, 5)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */
++/* SlvDSPreadyTime */
++#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15)
++/* MasDSPreadyTime */
++#define MASTER_DSP_READY_TIME_MASK GENMASK(14, 7)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x18 */
++/* EnabRandUpdTrig */
++#define ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER BIT(8)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x20 */
++/* ResetSyncOffset */
++#define RESET_SYNC_OFFSET_MASK GENMASK(11, 8)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x0 */
++/* FfeUpdGainForceVal */
++#define FFE_UPDATE_GAIN_FORCE_VAL_MASK GENMASK(9, 7)
++/* FfeUpdGainForce */
++#define FFE_UPDATE_GAIN_FORCE BIT(6)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x3 */
++/* TrFreeze */
++#define TR_FREEZE_MASK GENMASK(11, 0)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x6 */
++/* SS: Steady-state, KP: Proportional Gain */
++/* SSTrKp100 */
++#define SS_TR_KP100_MASK GENMASK(21, 19)
++/* SSTrKf100 */
++#define SS_TR_KF100_MASK GENMASK(18, 16)
++/* SSTrKp1000Mas */
++#define SS_TR_KP1000_MASTER_MASK GENMASK(15, 13)
++/* SSTrKf1000Mas */
++#define SS_TR_KF1000_MASTER_MASK GENMASK(12, 10)
++/* SSTrKp1000Slv */
++#define SS_TR_KP1000_SLAVE_MASK GENMASK(9, 7)
++/* SSTrKf1000Slv */
++#define SS_TR_KF1000_SLAVE_MASK GENMASK(6, 4)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x8 */
++/* clear this bit if wanna select from AFE */
++/* Regsigdet_sel_1000 */
++#define EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE BIT(4)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xd */
++/* RegEEE_st2TrKf1000 */
++#define EEE1000_STAGE2_TR_KF_MASK GENMASK(13, 11)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xf */
++/* RegEEE_slv_waketr_timer_tar */
++#define SLAVE_WAKETR_TIMER_MASK GENMASK(20, 11)
++/* RegEEE_slv_remtx_timer_tar */
++#define SLAVE_REMTX_TIMER_MASK GENMASK(10, 1)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x10 */
++/* RegEEE_slv_wake_int_timer_tar */
++#define SLAVE_WAKEINT_TIMER_MASK GENMASK(10, 1)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x14 */
++/* RegEEE_trfreeze_timer2 */
++#define TR_FREEZE_TIMER2_MASK GENMASK(9, 0)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x1c */
++/* RegEEE100Stg1_tar */
++#define EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK GENMASK(8, 0)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x25 */
++/* REGEEE_wake_slv_tr_wait_dfesigdet_en */
++#define WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN BIT(11)
++
+
+ #define ANALOG_INTERNAL_OPERATION_MAX_US 20
+ #define TXRESERVE_MIN 0
+@@ -679,40 +780,36 @@ restore:
+ static void mt798x_phy_common_finetune(struct phy_device *phydev)
+ {
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
+- __phy_write(phydev, 0x11, 0xc71);
+- __phy_write(phydev, 0x12, 0xc);
+- __phy_write(phydev, 0x10, 0x8fae);
+-
+- /* EnabRandUpdTrig = 1 */
+- __phy_write(phydev, 0x11, 0x2f00);
+- __phy_write(phydev, 0x12, 0xe);
+- __phy_write(phydev, 0x10, 0x8fb0);
+-
+- /* NormMseLoThresh = 85 */
+- __phy_write(phydev, 0x11, 0x55a0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x83aa);
+-
+- /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
+- __phy_write(phydev, 0x11, 0x240);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9680);
+-
+- /* TrFreeze = 0 (mt7988 default) */
+- __phy_write(phydev, 0x11, 0x0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9686);
+-
+- /* SSTrKp100 = 5 */
+- /* SSTrKf100 = 6 */
+- /* SSTrKp1000Mas = 5 */
+- /* SSTrKf1000Mas = 6 */
+- /* SSTrKp1000Slv = 5 */
+- /* SSTrKf1000Slv = 6 */
+- __phy_write(phydev, 0x11, 0xbaef);
+- __phy_write(phydev, 0x12, 0x2e);
+- __phy_write(phydev, 0x10, 0x968c);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x17,
++ SLAVE_DSP_READY_TIME_MASK | MASTER_DSP_READY_TIME_MASK,
++ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x18) |
++ FIELD_PREP(MASTER_DSP_READY_TIME_MASK, 0x18));
++
++ __mtk_tr_set_bits(phydev, 0x1, 0xf, 0x18,
++ ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER);
++
++ __mtk_tr_modify(phydev, 0x0, 0x7, 0x15,
++ NORMAL_MSE_LO_THRESH_MASK,
++ FIELD_PREP(NORMAL_MSE_LO_THRESH_MASK, 0x55));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x0,
++ FFE_UPDATE_GAIN_FORCE_VAL_MASK,
++ FIELD_PREP(FFE_UPDATE_GAIN_FORCE_VAL_MASK, 0x4) |
++ FFE_UPDATE_GAIN_FORCE);
++
++ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x3, TR_FREEZE_MASK);
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x6,
++ SS_TR_KP100_MASK | SS_TR_KF100_MASK |
++ SS_TR_KP1000_MASTER_MASK | SS_TR_KF1000_MASTER_MASK |
++ SS_TR_KP1000_SLAVE_MASK | SS_TR_KF1000_SLAVE_MASK,
++ FIELD_PREP(SS_TR_KP100_MASK, 0x5) |
++ FIELD_PREP(SS_TR_KF100_MASK, 0x6) |
++ FIELD_PREP(SS_TR_KP1000_MASTER_MASK, 0x5) |
++ FIELD_PREP(SS_TR_KF1000_MASTER_MASK, 0x6) |
++ FIELD_PREP(SS_TR_KP1000_SLAVE_MASK, 0x5) |
++ FIELD_PREP(SS_TR_KF1000_SLAVE_MASK, 0x6));
++
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+ }
+
+@@ -735,27 +832,29 @@ static void mt7981_phy_finetune(struct p
+ }
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 6 */
+- __phy_write(phydev, 0x11, 0x600);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
+-
+- /* VgaDecRate = 1 */
+- __phy_write(phydev, 0x11, 0x4c2a);
+- __phy_write(phydev, 0x12, 0x3e);
+- __phy_write(phydev, 0x10, 0x8fa4);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20,
++ RESET_SYNC_OFFSET_MASK,
++ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x6));
++
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x12,
++ VGA_DECIMATION_RATE_MASK,
++ FIELD_PREP(VGA_DECIMATION_RATE_MASK, 0x1));
+
+ /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
+ * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
+ */
+- __phy_write(phydev, 0x11, 0xd10a);
+- __phy_write(phydev, 0x12, 0x34);
+- __phy_write(phydev, 0x10, 0x8f82);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1,
++ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK |
++ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK,
++ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x3) |
++ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x2) |
++ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x3) |
++ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x2));
+
+ /* VcoSlicerThreshBitsHigh */
+- __phy_write(phydev, 0x11, 0x5555);
+- __phy_write(phydev, 0x12, 0x55);
+- __phy_write(phydev, 0x10, 0x8ec0);
++ __mtk_tr_modify(phydev, 0x1, 0xd, 0x20,
++ VCO_SLICER_THRESH_HIGH_MASK,
++ FIELD_PREP(VCO_SLICER_THRESH_HIGH_MASK, 0x555555));
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
+@@ -807,25 +906,23 @@ static void mt7988_phy_finetune(struct p
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 5 */
+- __phy_write(phydev, 0x11, 0x500);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20,
++ RESET_SYNC_OFFSET_MASK,
++ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x5));
+
+ /* VgaDecRate is 1 at default on mt7988 */
+
+- /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
+- * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
+- */
+- __phy_write(phydev, 0x11, 0xb90a);
+- __phy_write(phydev, 0x12, 0x6f);
+- __phy_write(phydev, 0x10, 0x8f82);
+-
+- /* RemAckCntLimitCtrl = 1 */
+- __phy_write(phydev, 0x11, 0xfbba);
+- __phy_write(phydev, 0x12, 0xc3);
+- __phy_write(phydev, 0x10, 0x87f8);
+-
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1,
++ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK |
++ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK,
++ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x6) |
++ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x7) |
++ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x6) |
++ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x7));
++
++ __mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
++ REMOTE_ACK_COUNT_LIMIT_CTRL_MASK,
++ FIELD_PREP(REMOTE_ACK_COUNT_LIMIT_CTRL_MASK, 0x1));
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
+@@ -901,45 +998,37 @@ static void mt798x_phy_eee(struct phy_de
+ MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* Regsigdet_sel_1000 = 0 */
+- __phy_write(phydev, 0x11, 0xb);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9690);
+-
+- /* REG_EEE_st2TrKf1000 = 2 */
+- __phy_write(phydev, 0x11, 0x114f);
+- __phy_write(phydev, 0x12, 0x2);
+- __phy_write(phydev, 0x10, 0x969a);
+-
+- /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
+- __phy_write(phydev, 0x11, 0x3028);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x969e);
+-
+- /* RegEEE_slv_wake_int_timer_tar = 8 */
+- __phy_write(phydev, 0x11, 0x5010);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a0);
+-
+- /* RegEEE_trfreeze_timer2 = 586 */
+- __phy_write(phydev, 0x11, 0x24a);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a8);
+-
+- /* RegEEE100Stg1_tar = 16 */
+- __phy_write(phydev, 0x11, 0x3210);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96b8);
+-
+- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
+- __phy_write(phydev, 0x11, 0x1463);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96ca);
+-
+- /* DfeTailEnableVgaThresh1000 = 27 */
+- __phy_write(phydev, 0x11, 0x36);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8f80);
++ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x8,
++ EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE);
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0xd,
++ EEE1000_STAGE2_TR_KF_MASK,
++ FIELD_PREP(EEE1000_STAGE2_TR_KF_MASK, 0x2));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0xf,
++ SLAVE_WAKETR_TIMER_MASK | SLAVE_REMTX_TIMER_MASK,
++ FIELD_PREP(SLAVE_WAKETR_TIMER_MASK, 0x6) |
++ FIELD_PREP(SLAVE_REMTX_TIMER_MASK, 0x14));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x10,
++ SLAVE_WAKEINT_TIMER_MASK,
++ FIELD_PREP(SLAVE_WAKEINT_TIMER_MASK, 0x8));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x14,
++ TR_FREEZE_TIMER2_MASK,
++ FIELD_PREP(TR_FREEZE_TIMER2_MASK, 0x24a));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x1c,
++ EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK,
++ FIELD_PREP(EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK,
++ 0x10));
++
++ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x25,
++ WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN);
++
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x0,
++ DFE_TAIL_EANBLE_VGA_TRHESH_1000,
++ FIELD_PREP(DFE_TAIL_EANBLE_VGA_TRHESH_1000, 0x1b));
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -9,13 +9,35 @@
+ #define MTK_GPHY_ID_MT7530 0x03a29412
+ #define MTK_GPHY_ID_MT7531 0x03a29441
+
+-#define MTK_EXT_PAGE_ACCESS 0x1f
+-#define MTK_PHY_PAGE_STANDARD 0x0000
+-#define MTK_PHY_PAGE_EXTENDED 0x0001
+-#define MTK_PHY_PAGE_EXTENDED_2 0x0002
+-#define MTK_PHY_PAGE_EXTENDED_3 0x0003
+-#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++#define MTK_PHY_PAGE_EXTENDED_1 0x0001
++#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
++#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
++
++#define MTK_PHY_PAGE_EXTENDED_2 0x0002
++#define MTK_PHY_PAGE_EXTENDED_3 0x0003
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11
++
++#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
++
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */
++#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_GBE_MODE_TX_DELAY_SEL 0x13
++#define MTK_PHY_TEST_MODE_TX_DELAY_SEL 0x14
++#define MTK_TX_DELAY_PAIR_B_MASK GENMASK(10, 8)
++#define MTK_TX_DELAY_PAIR_D_MASK GENMASK(2, 0)
++
++#define MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL 0xa6
++#define MTK_MCC_NEARECHO_OFFSET_MASK GENMASK(15, 8)
++
++#define MTK_PHY_RXADC_CTRL_RG7 0xc6
++#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123 0x123
++#define MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK GENMASK(15, 8)
++#define MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK GENMASK(7, 0)
+
+ struct mtk_gephy_priv {
+ unsigned long led_state;
+@@ -27,20 +49,29 @@ static void mtk_gephy_config_init(struct
+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+
+ /* Enable HW auto downshift */
+- phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
++ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
++ MTK_PHY_AUX_CTRL_AND_STATUS,
++ 0, MTK_PHY_ENABLE_DOWNSHIFT);
+
+ /* Increase SlvDPSready time */
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- __phy_write(phydev, 0x10, 0xafae);
+- __phy_write(phydev, 0x12, 0x2f);
+- __phy_write(phydev, 0x10, 0x8fae);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++ mtk_tr_modify(phydev, 0x1, 0xf, 0x17, SLAVE_DSP_READY_TIME_MASK,
++ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x5e));
+
+ /* Adjust 100_mse_threshold */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
+-
+- /* Disable mcc */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123,
++ MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK |
++ MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK,
++ 0xff) |
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
++ 0xff));
++
++ /* If echo time is narrower than 0x3, it will be regarded as noise */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL,
++ MTK_MCC_NEARECHO_OFFSET_MASK,
++ FIELD_PREP(MTK_MCC_NEARECHO_OFFSET_MASK, 0x3));
+ }
+
+ static int mt7530_phy_config_init(struct phy_device *phydev)
+@@ -48,7 +79,8 @@ static int mt7530_phy_config_init(struct
+ mtk_gephy_config_init(phydev);
+
+ /* Increase post_update_timer */
+- phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
++ phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11, 0x4b);
+
+ return 0;
+ }
+@@ -89,11 +121,19 @@ static int mt7531_phy_config_init(struct
+
+ /* PHY link down power saving enable */
+ phy_set_bits(phydev, 0x17, BIT(4));
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
++ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK,
++ FIELD_PREP(MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3));
+
+ /* Set TX Pair delay selection */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_GBE_MODE_TX_DELAY_SEL,
++ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
++ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
++ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TEST_MODE_TX_DELAY_SEL,
++ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
++ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
++ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
+
+ /* LED Config*/
+ mt7530_led_config_of(phydev);
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -6,6 +6,97 @@
+
+ #include "mtk.h"
+
++/* Difference between functions with mtk_tr* and __mtk_tr* prefixes is
++ * mtk_tr* functions: wrapped by page switching operations
++ * __mtk_tr* functions: no page switching operations
++ */
++
++static void __mtk_tr_access(struct phy_device *phydev, bool read, u8 ch_addr,
++ u8 node_addr, u8 data_addr)
++{
++ u16 tr_cmd = BIT(15); /* bit 14 & 0 are reserved */
++
++ if (read)
++ tr_cmd |= BIT(13);
++
++ tr_cmd |= (((ch_addr & 0x3) << 11) |
++ ((node_addr & 0xf) << 7) |
++ ((data_addr & 0x3f) << 1));
++ dev_dbg(&phydev->mdio.dev, "tr_cmd: 0x%x\n", tr_cmd);
++ __phy_write(phydev, 0x10, tr_cmd);
++}
++
++static void __mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u16 *tr_high, u16 *tr_low)
++{
++ __mtk_tr_access(phydev, true, ch_addr, node_addr, data_addr);
++ *tr_low = __phy_read(phydev, 0x11);
++ *tr_high = __phy_read(phydev, 0x12);
++ dev_dbg(&phydev->mdio.dev, "tr_high read: 0x%x, tr_low read: 0x%x\n",
++ *tr_high, *tr_low);
++}
++
++u32 mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr)
++{
++ u16 tr_high;
++ u16 tr_low;
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ return (tr_high << 16) | tr_low;
++}
++EXPORT_SYMBOL_GPL(mtk_tr_read);
++
++static void __mtk_tr_write(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 tr_data)
++{
++ __phy_write(phydev, 0x11, tr_data & 0xffff);
++ __phy_write(phydev, 0x12, tr_data >> 16);
++ dev_dbg(&phydev->mdio.dev, "tr_high write: 0x%x, tr_low write: 0x%x\n",
++ tr_data >> 16, tr_data & 0xffff);
++ __mtk_tr_access(phydev, false, ch_addr, node_addr, data_addr);
++}
++
++void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set)
++{
++ u32 tr_data;
++ u16 tr_high;
++ u16 tr_low;
++
++ __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low);
++ tr_data = (tr_high << 16) | tr_low;
++ tr_data = (tr_data & ~mask) | set;
++ __mtk_tr_write(phydev, ch_addr, node_addr, data_addr, tr_data);
++}
++EXPORT_SYMBOL_GPL(__mtk_tr_modify);
++
++void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set)
++{
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, mask, set);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++}
++EXPORT_SYMBOL_GPL(mtk_tr_modify);
++
++void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 set)
++{
++ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, 0, set);
++}
++EXPORT_SYMBOL_GPL(__mtk_tr_set_bits);
++
++void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 clr)
++{
++ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, clr, 0);
++}
++EXPORT_SYMBOL_GPL(__mtk_tr_clr_bits);
++
+ int mtk_phy_read_page(struct phy_device *phydev)
+ {
+ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+--- a/drivers/net/phy/mediatek/mtk.h
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -9,6 +9,8 @@
+ #define _MTK_EPHY_H_
+
+ #define MTK_EXT_PAGE_ACCESS 0x1f
++#define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
+ /* Registers on MDIO_MMD_VEND2 */
+ #define MTK_PHY_LED0_ON_CTRL 0x24
+@@ -62,6 +64,17 @@
+ #define MTK_PHY_LED_STATE_FORCE_BLINK 1
+ #define MTK_PHY_LED_STATE_NETDEV 2
+
++u32 mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr);
++void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set);
++void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set);
++void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 set);
++void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 clr);
++
+ int mtk_phy_read_page(struct phy_device *phydev);
+ int mtk_phy_write_page(struct phy_device *phydev, int page);
+
diff --git a/target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch b/target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch
new file mode 100644
index 0000000000..2fc1adb5ec
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch
@@ -0,0 +1,219 @@
+From 3c05195fc2c232cd853fc8cebf55310c4605111d Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:14 +0800
+Subject: [PATCH 10/13] net: phy: mediatek: Extend 1G TX/RX link pulse time
+
+We observe that some 10G devices' (mostly Marvell's chips inside) 1G
+training time violates specification, which may last 2230ms and affect
+later TX/RX link pulse time. This will invalidate MediaTek series
+gigabit Ethernet PHYs' hardware auto downshift mechanism.
+
+Without this patch, if someone is trying to use "4-wire" cable to
+connect above devices, MediaTek' gigabit Ethernet PHYs may fail
+to downshift to 100Mbps. (If partner 10G devices' downshift mechanism
+stops at 1G)
+
+This patch extends our 1G TX/RX link pulse time so that we can still
+link up with those 10G devices.
+
+Tested device:
+- Netgear GS110EMX's 10G port (Marvell 88X3340P)
+- QNAP QSW-M408-4C
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 2 +
+ drivers/net/phy/mediatek/mtk-ge.c | 5 +-
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 92 ++++++++++++++++++++++++++
+ drivers/net/phy/mediatek/mtk.h | 21 ++++++
+ 4 files changed, 116 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -1396,6 +1396,7 @@ static struct phy_driver mtk_socphy_driv
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+ .name = "MediaTek MT7981 PHY",
+ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .probe = mt7981_phy_probe,
+@@ -1413,6 +1414,7 @@ static struct phy_driver mtk_socphy_driv
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+ .name = "MediaTek MT7988 PHY",
+ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .probe = mt7988_phy_probe,
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -9,10 +9,6 @@
+ #define MTK_GPHY_ID_MT7530 0x03a29412
+ #define MTK_GPHY_ID_MT7531 0x03a29441
+
+-#define MTK_PHY_PAGE_EXTENDED_1 0x0001
+-#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
+-#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
+-
+ #define MTK_PHY_PAGE_EXTENDED_2 0x0002
+ #define MTK_PHY_PAGE_EXTENDED_3 0x0003
+ #define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11
+@@ -251,6 +247,7 @@ static struct phy_driver mtk_gephy_drive
+ .name = "MediaTek MT7531 PHY",
+ .probe = mt7531_phy_probe,
+ .config_init = mt7531_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+ */
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -109,6 +109,108 @@ int mtk_phy_write_page(struct phy_device
+ }
+ EXPORT_SYMBOL_GPL(mtk_phy_write_page);
+
++/* This function deals with the case that 1G AN starts but isn't completed. We
++ * set AN_NEW_LP_CNT_LIMIT with different values time after time to let our
++ * 1G->100Mbps hardware automatic downshift to fit more partner devices.
++ */
++static int extend_an_new_lp_cnt_limit(struct phy_device *phydev)
++{
++ int ret;
++ u32 reg_val;
++ int timeout;
++
++ /* According to table 28-9 & Figure 28-18 in IEEE 802.3,
++ * link_fail_inhibit_timer of 10/100/1000 Mbps devices ranges from 750
++ * to "1000ms". Once MTK_PHY_FINAL_SPEED_1000 is set, it means that we
++ * enter "FLP LINK GOOD CHECK" state, link_fail_inhibit_timer starts and
++ * this PHY's 1G training starts. If 1G training never starts, we do
++ * nothing but leave.
++ */
++ timeout = read_poll_timeout(ret = phy_read_mmd, reg_val,
++ (ret < 0) ||
++ reg_val & MTK_PHY_FINAL_SPEED_1000,
++ 10000, 500000, false, phydev,
++ MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
++ phydev_dbg(phydev, "%s: Training Indicator: 0x%x\n", __func__, reg_val);
++ if (ret < 0)
++ return ret;
++
++ if (!timeout) {
++ /* Once we found MTK_PHY_FINAL_SPEED_1000 is set, no matter 1G
++ * AN is completed or not, we'll set AN_NEW_LP_CNT_LIMIT again
++ * and again.
++ */
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AN_NEW_LP_CNT_LIMIT_MASK,
++ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK, 0xf));
++ msleep(1500);
++
++ /* Read phy status again to make sure the following step won't
++ * affect normal devices.
++ */
++ ret = genphy_read_status(phydev);
++ if (ret)
++ return ret;
++ if (phydev->link)
++ return 0;
++
++ timeout = read_poll_timeout(mtk_tr_read, reg_val,
++ (reg_val & AN_STATE_MASK) !=
++ (AN_STATE_TX_DISABLE <<
++ AN_STATE_SHIFT),
++ 10000, 1000000, false, phydev,
++ 0x0, 0xf, 0x2);
++ phydev_dbg(phydev, "%s: AN State: 0x%x\n", __func__, reg_val);
++ if (!timeout) {
++ msleep(625);
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
++ AN_NEW_LP_CNT_LIMIT_MASK,
++ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
++ 0x8));
++ msleep(500);
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
++ AN_NEW_LP_CNT_LIMIT_MASK,
++ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
++ 0xf));
++ }
++ }
++
++ return 0;
++}
++
++int mtk_gphy_cl22_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = genphy_read_status(phydev);
++ if (ret)
++ return ret;
++
++ if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) {
++ ret = phy_read_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
++ MTK_PHY_AUX_CTRL_AND_STATUS);
++ if (ret < 0)
++ return ret;
++
++ /* Once LP_DETECTED is set, it means that"ability_match" in
++ * IEEE 802.3 Figure 28-18 is set. This happens after we plug in
++ * cable. Also, LP_DETECTED will be cleared after AN complete.
++ */
++ if (!FIELD_GET(MTK_PHY_LP_DETECTED_MASK, ret))
++ return 0;
++
++ ret = phy_read(phydev, MII_CTRL1000);
++ if (ret & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) {
++ ret = extend_an_new_lp_cnt_limit(phydev);
++ phydev_dbg(phydev, "%s: counter limit ret: %d\n", __func__, ret);
++ if (ret < 0)
++ return ret;
++ }
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_gphy_cl22_read_status);
++
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers)
+--- a/drivers/net/phy/mediatek/mtk.h
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -10,8 +10,28 @@
+
+ #define MTK_EXT_PAGE_ACCESS 0x1f
+ #define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED_1 0x0001
++#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
++/* suprv_media_select_RefClk */
++#define MTK_PHY_LP_DETECTED_MASK GENMASK(7, 6)
++#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
++
+ #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x2 */
++#define AN_STATE_MASK GENMASK(22, 19)
++#define AN_STATE_SHIFT 19
++#define AN_STATE_TX_DISABLE 1
++
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
++#define AN_NEW_LP_CNT_LIMIT_MASK GENMASK(23, 20)
++#define AUTO_NP_10XEN BIT(6)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_LINK_STATUS_MISC (0xa2)
++#define MTK_PHY_FINAL_SPEED_1000 BIT(3)
++
+ /* Registers on MDIO_MMD_VEND2 */
+ #define MTK_PHY_LED0_ON_CTRL 0x24
+ #define MTK_PHY_LED1_ON_CTRL 0x26
+@@ -78,6 +98,7 @@ void __mtk_tr_clr_bits(struct phy_device
+ int mtk_phy_read_page(struct phy_device *phydev);
+ int mtk_phy_write_page(struct phy_device *phydev, int page);
+
++int mtk_gphy_cl22_read_status(struct phy_device *phydev);
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers);
diff --git a/target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch b/target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch
new file mode 100644
index 0000000000..a9595157ff
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch
@@ -0,0 +1,477 @@
+From 69ca89165e39e6b6f4c79e6b4c03559e0fac7051 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:15 +0800
+Subject: [PATCH 11/13] net: phy: add driver for built-in 2.5G ethernet PHY on
+ MT7988
+
+Add support for internal 2.5Gphy on MT7988. This driver will load
+necessary firmware, add appropriate time delay and figure out LED.
+Also, certain control registers will be set to fix link-up issues.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/Kconfig | 11 +
+ drivers/net/phy/mediatek/Makefile | 1 +
+ drivers/net/phy/mediatek/mtk-2p5ge.c | 432 +++++++++++++++++++++++++++
+ 4 files changed, 445 insertions(+)
+ create mode 100644 drivers/net/phy/mediatek/mtk-2p5ge.c
+
+--- a/drivers/net/phy/mediatek/Kconfig
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -25,3 +25,14 @@ config MEDIATEK_GE_SOC_PHY
+ the MT7981 and MT7988 SoCs. These PHYs need calibration data
+ present in the SoCs efuse and will dynamically calibrate VCM
+ (common-mode voltage) during startup.
++
++config MEDIATEK_2P5GE_PHY
++ tristate "MediaTek 2.5Gb Ethernet PHYs"
++ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
++ select MTK_NET_PHYLIB
++ help
++ Supports MediaTek SoC built-in 2.5Gb Ethernet PHYs.
++
++ This will load necessary firmware and add appropriate time delay.
++ Accelerate this procedure through internal pbus instead of MDIO
++ bus. Certain link-up issues will also be fixed here.
+--- a/drivers/net/phy/mediatek/Makefile
++++ b/drivers/net/phy/mediatek/Makefile
+@@ -2,3 +2,4 @@
+ obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o
+ obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o
++obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-2p5ge.c
+@@ -0,0 +1,432 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/bitfield.h>
++#include <linux/firmware.h>
++#include <linux/module.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/of_address.h>
++#include <linux/of_platform.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/phy.h>
++#include <linux/pm_domain.h>
++#include <linux/pm_runtime.h>
++
++#include "mtk.h"
++
++#define MTK_2P5GPHY_ID_MT7988 (0x00339c11)
++
++#define MT7988_2P5GE_PMB_FW "mediatek/mt7988/i2p5ge-phy-pmb.bin"
++#define MT7988_2P5GE_PMB_FW_SIZE (0x20000)
++#define MT7988_2P5GE_PMB_FW_BASE (0x0f100000)
++#define MT7988_2P5GE_PMB_FW_LEN (0x20000)
++#define MT7988_2P5GE_MD32_EN_CFG_BASE (0x0f0f0018)
++#define MT7988_2P5GE_MD32_EN_CFG_LEN (0x20)
++#define MD32_EN BIT(0)
++
++#define BASE100T_STATUS_EXTEND (0x10)
++#define BASE1000T_STATUS_EXTEND (0x11)
++#define EXTEND_CTRL_AND_STATUS (0x16)
++
++#define PHY_AUX_CTRL_STATUS (0x1d)
++#define PHY_AUX_DPX_MASK GENMASK(5, 5)
++#define PHY_AUX_SPEED_MASK GENMASK(4, 2)
++
++#define MTK_PHY_LPI_PCS_DSP_CTRL (0x121)
++#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8)
++
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
++#define AUTO_NP_10XEN BIT(6)
++
++struct mtk_i2p5ge_phy_priv {
++ bool fw_loaded;
++ unsigned long led_state;
++};
++
++enum {
++ PHY_AUX_SPD_10 = 0,
++ PHY_AUX_SPD_100,
++ PHY_AUX_SPD_1000,
++ PHY_AUX_SPD_2500,
++};
++
++static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++ void __iomem *md32_en_cfg_base, *pmb_addr;
++ struct device *dev = &phydev->mdio.dev;
++ const struct firmware *fw;
++ int ret, i;
++ u16 reg;
++
++ if (priv->fw_loaded)
++ return 0;
++
++ pmb_addr = ioremap(MT7988_2P5GE_PMB_FW_BASE, MT7988_2P5GE_PMB_FW_LEN);
++ if (!pmb_addr)
++ return -ENOMEM;
++ md32_en_cfg_base = ioremap(MT7988_2P5GE_MD32_EN_CFG_BASE,
++ MT7988_2P5GE_MD32_EN_CFG_LEN);
++ if (!md32_en_cfg_base) {
++ ret = -ENOMEM;
++ goto free_pmb;
++ }
++
++ ret = request_firmware(&fw, MT7988_2P5GE_PMB_FW, dev);
++ if (ret) {
++ dev_err(dev, "failed to load firmware: %s, ret: %d\n",
++ MT7988_2P5GE_PMB_FW, ret);
++ goto free;
++ }
++
++ if (fw->size != MT7988_2P5GE_PMB_FW_SIZE) {
++ dev_err(dev, "Firmware size 0x%zx != 0x%x\n",
++ fw->size, MT7988_2P5GE_PMB_FW_SIZE);
++ ret = -EINVAL;
++ goto release_fw;
++ }
++
++ reg = readw(md32_en_cfg_base);
++ if (reg & MD32_EN) {
++ phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++ usleep_range(10000, 11000);
++ }
++ phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
++
++ /* Write magic number to safely stall MCU */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800e, 0x1100);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800f, 0x00df);
++
++ for (i = 0; i < MT7988_2P5GE_PMB_FW_SIZE - 1; i += 4)
++ writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
++ dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n",
++ be16_to_cpu(*((__be16 *)(fw->data +
++ MT7988_2P5GE_PMB_FW_SIZE - 8))),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 6),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 5),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 2),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 1));
++
++ writew(reg & ~MD32_EN, md32_en_cfg_base);
++ writew(reg | MD32_EN, md32_en_cfg_base);
++ phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++ /* We need a delay here to stabilize initialization of MCU */
++ usleep_range(7000, 8000);
++ dev_info(dev, "Firmware loading/trigger ok.\n");
++
++ priv->fw_loaded = true;
++
++release_fw:
++ release_firmware(fw);
++free:
++ iounmap(md32_en_cfg_base);
++free_pmb:
++ iounmap(pmb_addr);
++
++ return ret;
++}
++
++static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev)
++{
++ struct pinctrl *pinctrl;
++ int ret;
++
++ /* Check if PHY interface type is compatible */
++ if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
++ return -ENODEV;
++
++ ret = mt798x_2p5ge_phy_load_fw(phydev);
++ if (ret < 0)
++ return ret;
++
++ /* Setup LED */
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_POLARITY | MTK_PHY_LED_ON_LINK10 |
++ MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK1000 |
++ MTK_PHY_LED_ON_LINK2500);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
++ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX);
++
++ /* Switch pinctrl after setting polarity to avoid bogus blinking */
++ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
++ if (IS_ERR(pinctrl))
++ dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL,
++ MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0);
++
++ /* Enable 16-bit next page exchange bit if 1000-BT isn't advertising */
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AUTO_NP_10XEN,
++ FIELD_PREP(AUTO_NP_10XEN, 0x1));
++
++ /* Enable HW auto downshift */
++ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
++ MTK_PHY_AUX_CTRL_AND_STATUS,
++ 0, MTK_PHY_ENABLE_DOWNSHIFT);
++
++ return 0;
++}
++
++static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev)
++{
++ bool changed = false;
++ u32 adv;
++ int ret;
++
++ /* In fact, if we disable autoneg, we can't link up correctly:
++ * 2.5G/1G: Need AN to exchange master/slave information.
++ * 100M/10M: Without AN, link starts at half duplex (According to
++ * IEEE 802.3-2018), which this phy doesn't support.
++ */
++ if (phydev->autoneg == AUTONEG_DISABLE)
++ return -EOPNOTSUPP;
++
++ ret = genphy_c45_an_config_aneg(phydev);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ /* Clause 45 doesn't define 1000BaseT support. Use Clause 22 instead in
++ * our design.
++ */
++ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
++ ret = phy_modify_changed(phydev, MII_CTRL1000, ADVERTISE_1000FULL, adv);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ return genphy_c45_check_and_restart_aneg(phydev, changed);
++}
++
++static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = genphy_c45_pma_read_abilities(phydev);
++ if (ret)
++ return ret;
++
++ /* This phy can't handle collision, and neither can (XFI)MAC it's
++ * connected to. Although it can do HDX handshake, it doesn't support
++ * CSMA/CD that HDX requires.
++ */
++ linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
++ phydev->supported);
++
++ return 0;
++}
++
++static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ /* When MDIO_STAT1_LSTATUS is raised genphy_c45_read_link(), this phy
++ * actually hasn't finished AN. So use CL22's link update function
++ * instead.
++ */
++ ret = genphy_update_link(phydev);
++ if (ret)
++ return ret;
++
++ phydev->speed = SPEED_UNKNOWN;
++ phydev->duplex = DUPLEX_UNKNOWN;
++ phydev->pause = 0;
++ phydev->asym_pause = 0;
++
++ /* We'll read link speed through vendor specific registers down below.
++ * So remove phy_resolve_aneg_linkmode (AN on) & genphy_c45_read_pma
++ * (AN off).
++ */
++ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
++ ret = genphy_c45_read_lpa(phydev);
++ if (ret < 0)
++ return ret;
++
++ /* Clause 45 doesn't define 1000BaseT support. Read the link
++ * partner's 1G advertisement via Clause 22.
++ */
++ ret = phy_read(phydev, MII_STAT1000);
++ if (ret < 0)
++ return ret;
++ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
++ } else if (phydev->autoneg == AUTONEG_DISABLE) {
++ linkmode_zero(phydev->lp_advertising);
++ }
++
++ if (phydev->link) {
++ ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
++ if (ret < 0)
++ return ret;
++
++ switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
++ case PHY_AUX_SPD_10:
++ phydev->speed = SPEED_10;
++ break;
++ case PHY_AUX_SPD_100:
++ phydev->speed = SPEED_100;
++ break;
++ case PHY_AUX_SPD_1000:
++ phydev->speed = SPEED_1000;
++ break;
++ case PHY_AUX_SPD_2500:
++ phydev->speed = SPEED_2500;
++ break;
++ }
++
++ phydev->duplex = DUPLEX_FULL;
++ /* FIXME:
++ * The current firmware always enables rate adaptation mode.
++ */
++ phydev->rate_matching = RATE_MATCH_PAUSE;
++ }
++
++ return 0;
++}
++
++static int mt798x_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
++ phy_interface_t iface)
++{
++ return RATE_MATCH_PAUSE;
++}
++
++static const unsigned long supported_triggers =
++ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_LINK_2500) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
++
++static int mt798x_2p5ge_phy_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *delay_on,
++ unsigned long *delay_off)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++ bool blinking = false;
++ int err = 0;
++
++ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
++ if (err < 0)
++ return err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state,
++ blinking);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_MASK, false);
++}
++
++static int mt798x_2p5ge_phy_led_brightness_set(struct phy_device *phydev,
++ u8 index,
++ enum led_brightness value)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++ int err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_MASK,
++ (value != LED_OFF));
++}
++
++static int mt798x_2p5ge_phy_led_hw_is_supported(struct phy_device *phydev,
++ u8 index, unsigned long rules)
++{
++ return mtk_phy_led_hw_is_supported(phydev, index, rules,
++ supported_triggers);
++}
++
++static int mt798x_2p5ge_phy_led_hw_control_get(struct phy_device *phydev,
++ u8 index, unsigned long *rules)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_SET,
++ MTK_2P5GPHY_LED_RX_BLINK_SET,
++ MTK_2P5GPHY_LED_TX_BLINK_SET);
++};
++
++static int mt798x_2p5ge_phy_led_hw_control_set(struct phy_device *phydev,
++ u8 index, unsigned long rules)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_SET,
++ MTK_2P5GPHY_LED_RX_BLINK_SET,
++ MTK_2P5GPHY_LED_TX_BLINK_SET);
++};
++
++static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_i2p5ge_phy_priv *priv;
++
++ priv = devm_kzalloc(&phydev->mdio.dev,
++ sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ switch (phydev->drv->phy_id) {
++ case MTK_2P5GPHY_ID_MT7988:
++ /* The original hardware only sets MDIO_DEVS_PMAPMD */
++ phydev->c45_ids.mmds_present |= MDIO_DEVS_PCS |
++ MDIO_DEVS_AN |
++ MDIO_DEVS_VEND1 |
++ MDIO_DEVS_VEND2;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ priv->fw_loaded = false;
++ phydev->priv = priv;
++
++ mtk_phy_leds_state_init(phydev);
++
++ return 0;
++}
++
++static struct phy_driver mtk_2p5gephy_driver[] = {
++ {
++ PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988),
++ .name = "MediaTek MT7988 2.5GbE PHY",
++ .probe = mt798x_2p5ge_phy_probe,
++ .config_init = mt798x_2p5ge_phy_config_init,
++ .config_aneg = mt798x_2p5ge_phy_config_aneg,
++ .get_features = mt798x_2p5ge_phy_get_features,
++ .read_status = mt798x_2p5ge_phy_read_status,
++ .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt798x_2p5ge_phy_led_blink_set,
++ .led_brightness_set = mt798x_2p5ge_phy_led_brightness_set,
++ .led_hw_is_supported = mt798x_2p5ge_phy_led_hw_is_supported,
++ .led_hw_control_get = mt798x_2p5ge_phy_led_hw_control_get,
++ .led_hw_control_set = mt798x_2p5ge_phy_led_hw_control_set,
++ },
++};
++
++module_phy_driver(mtk_2p5gephy_driver);
++
++static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
++ { PHY_ID_MATCH_VENDOR(0x00339c00) },
++ { }
++};
++
++MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
++MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
++MODULE_FIRMWARE(MT7988_2P5GE_PMB_FW);
diff --git a/target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch b/target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch
new file mode 100644
index 0000000000..8657886138
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch
@@ -0,0 +1,130 @@
+From 07e90eb1819319a0c34b0cf3a57a4a3878e96e4d Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:16 +0800
+Subject: [PATCH 12/13] net: phy: mediatek: Fix alignment in callback
+ functions' hook
+
+Align declarations in mtk_gephy_driver(mtk-ge.c) and
+mtk_socphy_driver(mtk-ge-soc.c). At first, some of them are
+".foo<tab>= method_foo", and others are ".bar<space>= method_bar".
+Use space instead for all of them here in case line is longer than
+80 chars.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 40 +++++++++++++--------------
+ drivers/net/phy/mediatek/mtk-ge.c | 34 +++++++++++------------
+ 2 files changed, 37 insertions(+), 37 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -1394,17 +1394,17 @@ static int mt7981_phy_probe(struct phy_d
+ static struct phy_driver mtk_socphy_driver[] = {
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+- .name = "MediaTek MT7981 PHY",
+- .config_init = mt798x_phy_config_init,
+- .read_status = mtk_gphy_cl22_read_status,
+- .config_intr = genphy_no_config_intr,
++ .name = "MediaTek MT7981 PHY",
++ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7981_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
++ .probe = mt7981_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+ .led_hw_control_set = mt798x_phy_led_hw_control_set,
+@@ -1412,17 +1412,17 @@ static struct phy_driver mtk_socphy_driv
+ },
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+- .name = "MediaTek MT7988 PHY",
+- .config_init = mt798x_phy_config_init,
+- .read_status = mtk_gphy_cl22_read_status,
+- .config_intr = genphy_no_config_intr,
++ .name = "MediaTek MT7988 PHY",
++ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7988_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
++ .probe = mt7988_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+ .led_hw_control_set = mt798x_phy_led_hw_control_set,
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -230,34 +230,34 @@ static int mt753x_phy_led_hw_control_set
+ static struct phy_driver mtk_gephy_driver[] = {
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
+- .name = "MediaTek MT7530 PHY",
+- .config_init = mt7530_phy_config_init,
++ .name = "MediaTek MT7530 PHY",
++ .config_init = mt7530_phy_config_init,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+ */
+- .config_intr = genphy_no_config_intr,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ },
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
+- .name = "MediaTek MT7531 PHY",
+- .probe = mt7531_phy_probe,
+- .config_init = mt7531_phy_config_init,
+- .read_status = mtk_gphy_cl22_read_status,
++ .name = "MediaTek MT7531 PHY",
++ .probe = mt7531_phy_probe,
++ .config_init = mt7531_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+ */
+- .config_intr = genphy_no_config_intr,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
+- .led_blink_set = mt753x_phy_led_blink_set,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt753x_phy_led_blink_set,
+ .led_brightness_set = mt753x_phy_led_brightness_set,
+ .led_hw_is_supported = mt753x_phy_led_hw_is_supported,
+ .led_hw_control_set = mt753x_phy_led_hw_control_set,
diff --git a/target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch b/target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch
new file mode 100644
index 0000000000..dd99bbba9a
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch
@@ -0,0 +1,65 @@
+From e59883b637ae317c2ac275b542e8a50670d76e7c Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:17 +0800
+Subject: [PATCH 13/13] net: phy: mediatek: Remove unnecessary outer parens of
+ "supported_triggers" var
+
+This patch removes unnecessary outer parens of "supported_triggers" vars
+in mtk-ge.c & mtk-ge-soc.c to improve readability.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 16 ++++++++--------
+ drivers/net/phy/mediatek/mtk-ge.c | 16 ++++++++--------
+ 2 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -1224,14 +1224,14 @@ static int mt798x_phy_led_brightness_set
+ }
+
+ static const unsigned long supported_triggers =
+- (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
++ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
+
+ static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -189,14 +189,14 @@ static int mt753x_phy_led_brightness_set
+ }
+
+ static const unsigned long supported_triggers =
+- (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
++ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
+
+ static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
diff --git a/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch b/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch
deleted file mode 100644
index 74b16be152..0000000000
--- a/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 128dc09b0af36772062142ce9e85b19c84ac789a Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 28 Feb 2023 17:53:37 +0000
-Subject: [PATCH] net: phy: add driver for MediaTek 2.5G PHY
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/Kconfig | 7 ++
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/mediatek-2p5ge.c | 220 +++++++++++++++++++++++++++++++
- 3 files changed, 226 insertions(+)
- create mode 100644 drivers/net/phy/mediatek-2p5ge.c
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -330,6 +330,13 @@ config MEDIATEK_GE_SOC_PHY
- present in the SoCs efuse and will dynamically calibrate VCM
- (common-mode voltage) during startup.
-
-+config MEDIATEK_2P5G_PHY
-+ tristate "MediaTek 2.5G Ethernet PHY"
-+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-+ default NET_MEDIATEK_SOC
-+ help
-+ Supports the MediaTek 2.5G Ethernet PHY.
-+
- config MICREL_PHY
- tristate "Micrel PHYs"
- depends on PTP_1588_CLOCK_OPTIONAL
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -82,6 +82,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
- obj-$(CONFIG_MARVELL_88Q2XXX_PHY) += marvell-88q2xxx.o
- obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o
- obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o
-+obj-$(CONFIG_MEDIATEK_2P5G_PHY) += mediatek-2p5ge.o
- obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
- obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
- obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch b/target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch
index 29393a6891..2793f3857f 100644
--- a/target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch
+++ b/target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch
@@ -29,7 +29,7 @@ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -1243,7 +1243,7 @@ static int lvts_probe(struct platform_de
+@@ -1249,7 +1249,7 @@ static int lvts_probe(struct platform_de
return 0;
}
@@ -38,7 +38,7 @@ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
{
struct lvts_domain *lvts_td;
int i;
-@@ -1254,8 +1254,6 @@ static int lvts_remove(struct platform_d
+@@ -1260,8 +1260,6 @@ static int lvts_remove(struct platform_d
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
lvts_debugfs_exit(lvts_td);
@@ -47,7 +47,7 @@ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
}
static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
-@@ -1356,7 +1354,7 @@ MODULE_DEVICE_TABLE(of, lvts_of_match);
+@@ -1362,7 +1360,7 @@ MODULE_DEVICE_TABLE(of, lvts_of_match);
static struct platform_driver lvts_driver = {
.probe = lvts_probe,
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch b/target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch
index 5871c87549..a9f84a4c7d 100644
--- a/target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch
+++ b/target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch
@@ -135,8 +135,8 @@ Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
{
u32 gt;
-@@ -703,7 +712,7 @@ static int lvts_golden_temp_init(struct
- if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
+@@ -707,7 +716,7 @@ static int lvts_golden_temp_init(struct
+ if (gt < LVTS_GOLDEN_TEMP_MAX)
golden_temp = gt;
- coeff_b = golden_temp * 500 + LVTS_COEFF_B;
@@ -144,7 +144,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
return 0;
}
-@@ -726,7 +735,7 @@ static int lvts_ctrl_init(struct device
+@@ -730,7 +739,7 @@ static int lvts_ctrl_init(struct device
* The golden temp information is contained in the first chunk
* of efuse data.
*/
@@ -153,7 +153,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
if (ret)
return ret;
-@@ -737,6 +746,7 @@ static int lvts_ctrl_init(struct device
+@@ -741,6 +750,7 @@ static int lvts_ctrl_init(struct device
for (i = 0; i < lvts_data->num_lvts_ctrl; i++) {
lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;
@@ -161,7 +161,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
ret = lvts_sensor_init(dev, &lvts_ctrl[i],
&lvts_data->lvts_ctrl[i]);
-@@ -760,7 +770,8 @@ static int lvts_ctrl_init(struct device
+@@ -764,7 +774,8 @@ static int lvts_ctrl_init(struct device
* after initializing the calibration.
*/
lvts_ctrl[i].hw_tshut_raw_temp =
@@ -171,7 +171,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
lvts_ctrl[i].low_thresh = INT_MIN;
lvts_ctrl[i].high_thresh = INT_MIN;
-@@ -1225,6 +1236,8 @@ static int lvts_probe(struct platform_de
+@@ -1231,6 +1242,8 @@ static int lvts_probe(struct platform_de
if (irq < 0)
return irq;
@@ -180,7 +180,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
ret = lvts_domain_init(dev, lvts_td, lvts_data);
if (ret)
return dev_err_probe(dev, ret, "Failed to initialize the lvts domain\n");
-@@ -1338,11 +1351,15 @@ static const struct lvts_ctrl_data mt819
+@@ -1344,11 +1357,15 @@ static const struct lvts_ctrl_data mt819
static const struct lvts_data mt8195_lvts_mcu_data = {
.lvts_ctrl = mt8195_lvts_mcu_data_ctrl,
.num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch b/target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch
index b758720d24..a32d950fc9 100644
--- a/target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch
+++ b/target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch
@@ -33,7 +33,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-5-linux@fw-web.de
#define LVTS_HW_SHUTDOWN_MT8195 105000
#define LVTS_MINIMUM_THRESHOLD 20000
-@@ -1269,6 +1272,33 @@ static void lvts_remove(struct platform_
+@@ -1275,6 +1278,33 @@ static void lvts_remove(struct platform_
lvts_debugfs_exit(lvts_td);
}
@@ -67,7 +67,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-5-linux@fw-web.de
static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
{
.cal_offset = { 0x04, 0x07 },
-@@ -1348,6 +1378,13 @@ static const struct lvts_ctrl_data mt819
+@@ -1354,6 +1384,13 @@ static const struct lvts_ctrl_data mt819
}
};
@@ -81,7 +81,7 @@ Link: https://lore.kernel.org/r/20230922055020.6436-5-linux@fw-web.de
static const struct lvts_data mt8195_lvts_mcu_data = {
.lvts_ctrl = mt8195_lvts_mcu_data_ctrl,
.num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
-@@ -1363,6 +1400,7 @@ static const struct lvts_data mt8195_lvt
+@@ -1369,6 +1406,7 @@ static const struct lvts_data mt8195_lvt
};
static const struct of_device_id lvts_of_match[] = {
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch b/target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch
index 0893db74a5..46e1eeb239 100644
--- a/target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch
+++ b/target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch
@@ -24,7 +24,7 @@ Link: https://lore.kernel.org/r/20231017190545.157282-3-bero@baylibre.com
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -1299,6 +1299,38 @@ static const struct lvts_ctrl_data mt798
+@@ -1305,6 +1305,38 @@ static const struct lvts_ctrl_data mt798
}
};
@@ -63,7 +63,7 @@ Link: https://lore.kernel.org/r/20231017190545.157282-3-bero@baylibre.com
static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
{
.cal_offset = { 0x04, 0x07 },
-@@ -1407,12 +1439,17 @@ static const struct of_device_id lvts_of
+@@ -1413,12 +1445,17 @@ static const struct of_device_id lvts_of
};
MODULE_DEVICE_TABLE(of, lvts_of_match);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch b/target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch
index 1fe7e255b7..3b7d9489f2 100644
--- a/target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch
+++ b/target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch
@@ -34,7 +34,7 @@ Link: https://lore.kernel.org/r/20231017190545.157282-4-bero@baylibre.com
#define LVTS_HW_SHUTDOWN_MT8195 105000
#define LVTS_MINIMUM_THRESHOLD 20000
-@@ -1331,6 +1332,88 @@ static int lvts_resume(struct device *de
+@@ -1337,6 +1338,88 @@ static int lvts_resume(struct device *de
return 0;
}
@@ -123,7 +123,7 @@ Link: https://lore.kernel.org/r/20231017190545.157282-4-bero@baylibre.com
static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
{
.cal_offset = { 0x04, 0x07 },
-@@ -1417,6 +1500,16 @@ static const struct lvts_data mt7988_lvt
+@@ -1423,6 +1506,16 @@ static const struct lvts_data mt7988_lvt
.temp_offset = LVTS_COEFF_B_MT7988,
};
@@ -140,7 +140,7 @@ Link: https://lore.kernel.org/r/20231017190545.157282-4-bero@baylibre.com
static const struct lvts_data mt8195_lvts_mcu_data = {
.lvts_ctrl = mt8195_lvts_mcu_data_ctrl,
.num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
-@@ -1433,6 +1526,8 @@ static const struct lvts_data mt8195_lvt
+@@ -1439,6 +1532,8 @@ static const struct lvts_data mt8195_lvt
static const struct of_device_id lvts_of_match[] = {
{ .compatible = "mediatek,mt7988-lvts-ap", .data = &mt7988_lvts_ap_data },
diff --git a/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch
index 8397915b26..21bbed88d7 100644
--- a/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch
+++ b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch
@@ -37,7 +37,7 @@
* CONFIG_CMDLINE is meant to be a default in case nothing else
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
-@@ -2269,6 +2269,14 @@ config CMDLINE_FORCE
+@@ -2307,6 +2307,14 @@ config CMDLINE_FORCE
endchoice
diff --git a/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch b/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch
index 4feb0e5d1a..a28d274493 100644
--- a/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch
+++ b/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch
@@ -25,7 +25,7 @@
+ block-partition-env {
+ partname = "ubootenv";
+ nvmem-layout {
-+ compatible = "u-boot,env-layout";
++ compatible = "u-boot,env";
+ };
+ };
+ emmc_rootfs: block-partition-production {
@@ -52,7 +52,7 @@
+ block-partition-env {
+ partname = "ubootenv";
+ nvmem-layout {
-+ compatible = "u-boot,env-layout";
++ compatible = "u-boot,env";
+ };
+ };
+ sd_rootfs: block-partition-production {
diff --git a/target/linux/mpc85xx/Makefile b/target/linux/mpc85xx/Makefile
index b9bf0eaff0..a095714c8a 100644
--- a/target/linux/mpc85xx/Makefile
+++ b/target/linux/mpc85xx/Makefile
@@ -11,8 +11,7 @@ CPU_TYPE:=8548
FEATURES:=squashfs ramdisk nand
SUBTARGETS:=p1010 p1020 p2020
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
KERNELNAME:=zImage
@@ -21,6 +20,6 @@ include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += \
kmod-input-core kmod-input-gpio-keys kmod-button-hotplug \
kmod-leds-gpio swconfig kmod-ath9k wpad-basic-mbedtls kmod-usb2 \
- uboot-envtools
+ uboot-envtools kmod-crypto-hw-talitos
$(eval $(call BuildTarget))
diff --git a/target/linux/mpc85xx/base-files/etc/board.d/02_network b/target/linux/mpc85xx/base-files/etc/board.d/02_network
index 2574ebc9b9..601bd7e9f1 100644
--- a/target/linux/mpc85xx/base-files/etc/board.d/02_network
+++ b/target/linux/mpc85xx/base-files/etc/board.d/02_network
@@ -24,13 +24,10 @@ hpe,msm460)
ucidef_set_interface_lan "eth0"
;;
ocedo,panda)
- ucidef_set_interface_wan "eth1"
- ucidef_add_switch "switch0" \
- "0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:lan" "6:lan" "7:lan" "8u@eth0"
+ ucidef_set_interface_lan_wan "lan1 lan2 lan3 lan4 lan5 lan6 lan7 lan8" "eth1"
;;
tplink,tl-wdr4900-v1)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
- ucidef_set_interface_macaddr "wan" "$(macaddr_add $(mtd_get_mac_binary u-boot 0x4fc00) 1)"
;;
watchguard,firebox-t10)
ucidef_set_interfaces_lan_wan "eth1 eth2" "eth0"
diff --git a/target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
deleted file mode 100644
index be6ee40389..0000000000
--- a/target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-[ -e /lib/firmware/$FIRMWARE ] && exit 0
-
-. /lib/functions/caldata.sh
-
-board=$(board_name)
-
-case "$FIRMWARE" in
-"pci_wmac0.eeprom")
- case $board in
- tplink,tl-wdr4900-v1)
- caldata_extract "caldata" 0x1000 0x800
- ath9k_patch_mac $(mtd_get_mac_binary u-boot 0x4fc00)
- ;;
- *)
- caldata_die "board $board is not supported yet"
- ;;
- esac
- ;;
-
-"pci_wmac1.eeprom")
- case $board in
- tplink,tl-wdr4900-v1)
- caldata_extract "caldata" 0x5000 0x800
- ath9k_patch_mac $(macaddr_add $(mtd_get_mac_binary u-boot 0x4fc00) -1)
- ;;
- *)
- caldata_die "board $board is not supported yet"
- ;;
- esac
- ;;
-esac
diff --git a/target/linux/mpc85xx/config-6.1 b/target/linux/mpc85xx/config-6.1
deleted file mode 100644
index c017422714..0000000000
--- a/target/linux/mpc85xx/config-6.1
+++ /dev/null
@@ -1,295 +0,0 @@
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_ADVANCED_OPTIONS is not set
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
-CONFIG_ARCH_MMAP_RND_BITS=11
-CONFIG_ARCH_MMAP_RND_BITS_MAX=17
-CONFIG_ARCH_MMAP_RND_BITS_MIN=11
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SPLIT_ARG64=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
-CONFIG_ASN1=y
-CONFIG_AUDIT_ARCH=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOOKE=y
-CONFIG_BOOKE_OR_40x=y
-CONFIG_BOOKE_WDT=y
-# CONFIG_BR200_WP is not set
-# CONFIG_BSC9131_RDB is not set
-# CONFIG_BSC9132_QDS is not set
-# CONFIG_C293_PCIE is not set
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_CMDLINE="console=ttyS0,115200"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-# CONFIG_COMMON_CLK is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-# CONFIG_CORENET_GENERIC is not set
-# CONFIG_CPM2 is not set
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CRYPTO_AES_PPC_SPE is not set
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-# CONFIG_CRYPTO_MD5_PPC is not set
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RSA=y
-# CONFIG_CRYPTO_SHA1_PPC is not set
-# CONFIG_CRYPTO_SHA1_PPC_SPE is not set
-# CONFIG_CRYPTO_SHA256_PPC_SPE is not set
-CONFIG_DATA_SHIFT=24
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_E500_CPU=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_MPC85XX=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-# CONFIG_FIREBOX_T10 is not set
-CONFIG_FIXED_PHY=y
-CONFIG_FSL_EMB_PERFMON=y
-# CONFIG_FSL_FMAN is not set
-CONFIG_FSL_LBC=y
-CONFIG_FSL_PCI=y
-CONFIG_FSL_PQ_MDIO=y
-CONFIG_FSL_SOC=y
-CONFIG_FSL_SOC_BOOKE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GEN_RTC=y
-# CONFIG_GE_IMP3A is not set
-CONFIG_GIANFAR=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_MPC8XXX=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-# CONFIG_HIVEAP_330 is not set
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_MPC=y
-CONFIG_ILLEGAL_POINTER_VALUE=0
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_ISA_DMA_API=y
-CONFIG_KERNEL_START=0xc0000000
-# CONFIG_KSI8560 is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOWMEM_CAM_NUM=9
-CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_LXT_PHY=y
-# CONFIG_MATH_EMULATION is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MMU_GATHER_MERGE_VMAS=y
-CONFIG_MMU_GATHER_PAGE_SIZE=y
-CONFIG_MODULES_USE_ELF_RELA=y
-# CONFIG_MPC8536_DS is not set
-# CONFIG_MPC8540_ADS is not set
-# CONFIG_MPC8560_ADS is not set
-# CONFIG_MPC85xx_CDS is not set
-# CONFIG_MPC85xx_DS is not set
-# CONFIG_MPC85xx_MDS is not set
-# CONFIG_MPC85xx_RDB is not set
-CONFIG_MPIC=y
-# CONFIG_MPIC_MSGR is not set
-CONFIG_MPIC_TIMER=y
-CONFIG_MPILIB=y
-# CONFIG_MSM460 is not set
-# CONFIG_MTD_CFI is not set
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-# CONFIG_MVME2500 is not set
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=1
-CONFIG_NR_IRQS=512
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-# CONFIG_NVMEM_QORIQ_EFUSE is not set
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DMA_DEFAULT_COHERENT=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_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND=y
-# CONFIG_P1010_RDB is not set
-# CONFIG_P1022_DS is not set
-# CONFIG_P1022_RDK is not set
-# CONFIG_P1023_RDB is not set
-CONFIG_PAGE_OFFSET=0xc0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-# CONFIG_PANDA is not set
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYSICAL_ALIGN=0x04000000
-CONFIG_PHYSICAL_START=0x00000000
-# CONFIG_PHYS_64BIT is not set
-# CONFIG_PMU_SYSFS is not set
-# CONFIG_PPA8548 is not set
-CONFIG_PPC=y
-CONFIG_PPC32=y
-# CONFIG_PPC64 is not set
-CONFIG_PPC_85xx=y
-# CONFIG_PPC_8xx is not set
-CONFIG_PPC_ADV_DEBUG_DACS=2
-CONFIG_PPC_ADV_DEBUG_DVCS=0
-CONFIG_PPC_ADV_DEBUG_IACS=2
-CONFIG_PPC_ADV_DEBUG_REGS=y
-CONFIG_PPC_BARRIER_NOSPEC=y
-# CONFIG_PPC_BOOK3S_32 is not set
-CONFIG_PPC_DOORBELL=y
-CONFIG_PPC_E500=y
-# CONFIG_PPC_E500MC is not set
-# CONFIG_PPC_EARLY_DEBUG is not set
-CONFIG_PPC_INDIRECT_PCI=y
-CONFIG_PPC_KUAP=y
-# CONFIG_PPC_KUAP_DEBUG is not set
-CONFIG_PPC_KUEP=y
-CONFIG_PPC_MMU_NOHASH=y
-CONFIG_PPC_PAGE_SHIFT=12
-# CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT is not set
-# CONFIG_PPC_QEMU_E500 is not set
-CONFIG_PPC_SMP_MUXED_IPI=y
-CONFIG_PPC_UDBG_16550=y
-CONFIG_PPC_WERROR=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QE_GPIO=y
-CONFIG_QUICC_ENGINE=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-# CONFIG_RED_15W_REV1 is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_GENERIC=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-# CONFIG_SCOM_DEBUGFS is not set
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SERIAL_QE is not set
-# CONFIG_SOCRATES is not set
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPE=y
-CONFIG_SPE_POSSIBLE=y
-CONFIG_SPI=y
-CONFIG_SPI_FSL_ESPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-# CONFIG_STATIC_CALL_SELFTEST is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_STX_GP3 is not set
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_TARGET_CPU="8540"
-CONFIG_TARGET_CPU_BOOL=y
-CONFIG_TASK_SIZE=0xc0000000
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_THREAD_SHIFT=13
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-# CONFIG_TL_WDR4900_V1 is not set
-# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
-# CONFIG_TQM8540 is not set
-# CONFIG_TQM8541 is not set
-# CONFIG_TQM8548 is not set
-# CONFIG_TQM8555 is not set
-# CONFIG_TQM8560 is not set
-# CONFIG_TWR_P102x is not set
-CONFIG_UCC=y
-CONFIG_UCC_FAST=y
-CONFIG_UCC_GETH=y
-# CONFIG_UGETH_TX_ON_DEMAND is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_VDSO32=y
-# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WS_AP3710I is not set
-# CONFIG_WS_AP3715I is not set
-# CONFIG_WS_AP3825I is not set
-# CONFIG_XES_MPC85xx is not set
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_XZ_DEC_POWERPC=y
diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts
index 4b3b52d35b..c4125052ec 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts
+++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts
@@ -87,6 +87,7 @@
};
switch0: ethernet-phy@0 {
+ compatible = "brcm,bcm53128";
reg = <0x0>;
ports {
@@ -135,7 +136,8 @@
port@8 {
reg = <8>;
- label = "cpu";
+ phy-mode = "rgmii-id";
+ ethernet = <&enet0>;
fixed-link {
speed = <1000>;
@@ -160,7 +162,6 @@
enet0: ethernet@b0000 {
phy-connection-type = "rgmii-id";
- phy-handle = <&switch0>;
fixed-link {
speed = <1000>;
diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts
index 5cf3c26fc9..4fd9767d2d 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts
+++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts
@@ -9,6 +9,7 @@
* option) any later version.
*/
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
@@ -63,7 +64,9 @@
#size-cells = <1>;
macaddr_uboot_4fc00: macaddr@4fc00 {
+ compatible = "mac-base";
reg = <0x4fc00 0x6>;
+ #nvmem-cell-cells = <1>;
};
};
};
@@ -90,6 +93,20 @@
reg = <0x00ff0000 0x00010000>;
label = "caldata";
read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_caldata_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
+ cal_caldata_5000: calibration@5000 {
+ reg = <0x5000 0x440>;
+ };
+ };
};
};
};
@@ -101,6 +118,23 @@
usb@22000 {
phy_type = "utmi";
dr_mode = "host";
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ #trigger-source-cells = <0>;
+
+ hub_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ hub_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+ };
};
mdio@24000 {
@@ -148,30 +182,93 @@
reg = <1>;
label = "wan";
phy-handle = <&phy_port1>;
+
+ nvmem-cells = <&macaddr_uboot_4fc00 1>;
+ nvmem-cell-names = "mac-address";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+ };
};
port@2 {
reg = <2>;
label = "lan1";
phy-handle = <&phy_port2>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
port@3 {
reg = <3>;
label = "lan2";
phy-handle = <&phy_port3>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
port@4 {
reg = <4>;
label = "lan3";
phy-handle = <&phy_port4>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
port@5 {
reg = <5>;
label = "lan4";
phy-handle = <&phy_port5>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
};
};
@@ -187,7 +284,7 @@
enet0: ethernet@b0000 {
phy-connection-type = "rgmii-id";
- nvmem-cells = <&macaddr_uboot_4fc00>;
+ nvmem-cells = <&macaddr_uboot_4fc00 0>;
nvmem-cell-names = "mac-address";
fixed-link {
@@ -246,6 +343,16 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
+
+ ath9k: wifi@0,0 {
+ compatible = "pci168c,0033";
+ reg = <0x0000 0 0 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ qca,led-pin = /bits/ 8 <0>;
+ nvmem-cells = <&cal_caldata_1000>, <&macaddr_uboot_4fc00 0>;
+ nvmem-cell-names = "calibration", "mac-address";
+ };
};
};
@@ -261,6 +368,22 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
+
+ wifi@0,0 {
+ compatible = "pci168c,0030";
+ reg = <0x0000 0 0 0 0>;
+ /*
+ * The PCI header of the AR9381 chip is not programmed
+ * correctly by the bootloader and the device uses wrong
+ * data due to that. Replace the broken values with the
+ * correct ones.
+ */
+ device-id = <0x0030>;
+ class-code = <0x028000>;
+ qca,led-pin = /bits/ 8 <0>;
+ nvmem-cells = <&cal_caldata_5000>, <&macaddr_uboot_4fc00 (-1)>;
+ nvmem-cell-names = "calibration", "mac-address";
+ };
};
};
@@ -271,26 +394,47 @@
leds {
compatible = "gpio-leds";
- system_green: system {
+ led-0 {
+ gpios = <&ath9k 1 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WPS;
+ };
+
+ system_green: led-1 {
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
- label = "tp-link:blue:system";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
};
- usb1 {
+ led-2 {
gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
- label = "tp-link:green:usb1";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_USB;
+ function-enumerator = <1>;
+ linux,default-trigger = "usbport";
+ trigger-sources = <&hub_port1>;
};
- usb2 {
+ led-3 {
gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
- label = "tp-link:green:usb2";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_USB;
+ function-enumerator = <2>;
+ linux,default-trigger = "usbport";
+ trigger-sources = <&hub_port2>;
};
+ };
- usbpower {
- gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
- label = "tp-link:usb:power";
+ gpio_export {
+ compatible = "gpio-export";
+ #size-cells = <0>;
+
+ usb-pwr {
+ gpio-export,name = "usb_pwr";
+ gpio-export,output = <1>;
+ gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+ };
};
- };
buttons {
compatible = "gpio-keys";
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c
index 23fd11a5c6..8bd5a679b8 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -29,7 +28,7 @@
#include "mpc85xx.h"
-void __init br200_wp_pic_init(void)
+static void __init br200_wp_pic_init(void)
{
struct mpic *mpic;
@@ -57,19 +56,9 @@ static void __init br200_wp_setup_arch(void)
machine_arch_initcall(br200_wp, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init br200_wp_probe(void)
-{
- if (of_machine_is_compatible("aerohive,br200-wp"))
- return 1;
- return 0;
-}
-
define_machine(br200_wp) {
.name = "P1020 RDB",
- .probe = br200_wp_probe,
+ .compatible = "aerohive,br200-wp",
.setup_arch = br200_wp_setup_arch,
.init_IRQ = br200_wp_pic_init,
#ifdef CONFIG_PCI
@@ -77,6 +66,5 @@ define_machine(br200_wp) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c
index 422bde6903..f8f90b22bf 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -35,7 +34,7 @@
#include "mpc85xx.h"
-void __init firebox_t10_pic_init(void)
+static void __init firebox_t10_pic_init(void)
{
struct mpic *mpic;
@@ -62,19 +61,9 @@ static void __init firebox_t10_setup_arch(void)
machine_arch_initcall(firebox_t10, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init firebox_t10_probe(void)
-{
- if (of_machine_is_compatible("watchguard,firebox-t10"))
- return 1;
- return 0;
-}
-
define_machine(firebox_t10) {
.name = "P1010 RDB",
- .probe = firebox_t10_probe,
+ .compatible = "watchguard,firebox-t10",
.setup_arch = firebox_t10_setup_arch,
.init_IRQ = firebox_t10_pic_init,
#ifdef CONFIG_PCI
@@ -82,6 +71,5 @@ define_machine(firebox_t10) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c
index f325b32ce6..3c97eeaff7 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -34,7 +33,7 @@
#include "mpc85xx.h"
-void __init hiveap_330_pic_init(void)
+static void __init hiveap_330_pic_init(void)
{
struct mpic *mpic;
@@ -64,19 +63,9 @@ static void __init hiveap_330_setup_arch(void)
machine_arch_initcall(hiveap_330, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init hiveap_330_probe(void)
-{
- if (of_machine_is_compatible("aerohive,hiveap-330"))
- return 1;
- return 0;
-}
-
define_machine(hiveap_330) {
.name = "P1020 RDB",
- .probe = hiveap_330_probe,
+ .compatible = "aerohive,hiveap-330",
.setup_arch = hiveap_330_setup_arch,
.init_IRQ = hiveap_330_pic_init,
#ifdef CONFIG_PCI
@@ -84,6 +73,5 @@ define_machine(hiveap_330) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c
index a4f547d313..24eac19a76 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init msm_pic_init(void)
+static void __init msm_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init msm_setup_arch(void)
machine_arch_initcall(msm, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init msm_probe(void)
-{
- if (of_machine_is_compatible("hpe,msm460"))
- return 1;
- return 0;
-}
-
define_machine(msm) {
.name = "P1020 RDB",
- .probe = msm_probe,
+ .compatible = "hpe,msm460",
.setup_arch = msm_setup_arch,
.init_IRQ = msm_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(msm) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c
index 7eec2cf15c..aab2b591ae 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init panda_pic_init(void)
+static void __init panda_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init panda_setup_arch(void)
machine_arch_initcall(panda, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init panda_probe(void)
-{
- if (of_machine_is_compatible("ocedo,panda"))
- return 1;
- return 0;
-}
-
define_machine(panda) {
.name = "P1020 RDB",
- .probe = panda_probe,
+ .compatible = "ocedo,panda",
.setup_arch = panda_setup_arch,
.init_IRQ = panda_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(panda) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c
index 1b2be853a5..8966cc3452 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -35,7 +34,7 @@
#include "mpc85xx.h"
-void __init red_15w_rev1_pic_init(void)
+static void __init red_15w_rev1_pic_init(void)
{
struct mpic *mpic;
@@ -62,19 +61,9 @@ static void __init red_15w_rev1_setup_arch(void)
machine_arch_initcall(red_15w_rev1, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init red_15w_rev1_probe(void)
-{
- if (of_machine_is_compatible("sophos,red-15w-rev1"))
- return 1;
- return 0;
-}
-
define_machine(red_15w_rev1) {
.name = "P1010 RDB",
- .probe = red_15w_rev1_probe,
+ .compatible = "sophos,red-15w-rev1",
.setup_arch = red_15w_rev1_setup_arch,
.init_IRQ = red_15w_rev1_pic_init,
#ifdef CONFIG_PCI
@@ -82,6 +71,5 @@ define_machine(red_15w_rev1) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c
index 87a97e65c8..8180ddaeef 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c
@@ -16,12 +16,8 @@
#include <linux/stddef.h>
#include <linux/kernel.h>
-#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
-#include <linux/ath9k_platform.h>
-#include <linux/leds.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +32,7 @@
#include "mpc85xx.h"
-void __init tl_wdr4900_v1_pic_init(void)
+static void __init tl_wdr4900_v1_pic_init(void)
{
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU,
@@ -47,60 +43,6 @@ void __init tl_wdr4900_v1_pic_init(void)
mpic_init(mpic);
}
-#ifdef CONFIG_PCI
-static struct gpio_led tl_wdr4900_v1_wmac_leds_gpio[] = {
- {
- .name = "tp-link:blue:wps",
- .gpio = 1,
- .active_low = 1,
- },
-};
-
-static struct ath9k_platform_data tl_wdr4900_v1_wmac0_data = {
- .led_pin = 0,
- .eeprom_name = "pci_wmac0.eeprom",
- .leds = tl_wdr4900_v1_wmac_leds_gpio,
- .num_leds = ARRAY_SIZE(tl_wdr4900_v1_wmac_leds_gpio),
-};
-
-static struct ath9k_platform_data tl_wdr4900_v1_wmac1_data = {
- .led_pin = 0,
- .eeprom_name = "pci_wmac1.eeprom",
-};
-
-static void tl_wdr4900_v1_pci_wmac_fixup(struct pci_dev *dev)
-{
- if (!machine_is(tl_wdr4900_v1))
- return;
-
- if (dev->bus->number == 1 &&
- PCI_SLOT(dev->devfn) == 0) {
- dev->dev.platform_data = &tl_wdr4900_v1_wmac0_data;
- return;
- }
-
- if (dev->bus->number == 3 &&
- PCI_SLOT(dev->devfn) == 0 &&
- dev->device == 0xabcd) {
- dev->dev.platform_data = &tl_wdr4900_v1_wmac1_data;
-
- /*
- * The PCI header of the AR9381 chip is not programmed
- * correctly by the bootloader and the device uses wrong
- * data due to that. Replace the broken values with the
- * correct ones.
- */
- dev->device = 0x30;
- dev->class = 0x028000;
-
- pr_info("pci %s: AR9381 fixup applied\n", pci_name(dev));
- }
-}
-
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID,
- tl_wdr4900_v1_pci_wmac_fixup);
-#endif /* CONFIG_PCI */
-
/*
* Setup the architecture
*/
@@ -116,25 +58,14 @@ static void __init tl_wdr4900_v1_setup_arch(void)
machine_arch_initcall(tl_wdr4900_v1, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init tl_wdr4900_v1_probe(void)
-{
- if (of_machine_is_compatible("tplink,tl-wdr4900-v1"))
- return 1;
- return 0;
-}
-
define_machine(tl_wdr4900_v1) {
.name = "Freescale P1014",
- .probe = tl_wdr4900_v1_probe,
+ .compatible = "tplink,tl-wdr4900-v1",
.setup_arch = tl_wdr4900_v1_setup_arch,
.init_IRQ = tl_wdr4900_v1_pic_init,
#ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c
index f23902de39..75f881a119 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init ws_ap3710i_pic_init(void)
+static void __init ws_ap3710i_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init ws_ap3710i_setup_arch(void)
machine_arch_initcall(ws_ap3710i, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init ws_ap3710i_probe(void)
-{
- if (of_machine_is_compatible("enterasys,ws-ap3710i"))
- return 1;
- return 0;
-}
-
define_machine(ws_ap3710i) {
.name = "P1020 RDB",
- .probe = ws_ap3710i_probe,
+ .compatible = "enterasys,ws-ap3710i",
.setup_arch = ws_ap3710i_setup_arch,
.init_IRQ = ws_ap3710i_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(ws_ap3710i) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c
index aa2a366b3d..3c3d2bf255 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -35,7 +34,7 @@
#include "mpc85xx.h"
-void __init wsap3715i_pic_init(void)
+static void __init wsap3715i_pic_init(void)
{
struct mpic *mpic;
@@ -62,19 +61,9 @@ static void __init wsap3715i_setup_arch(void)
machine_arch_initcall(wsap3715i, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init wsap3715i_probe(void)
-{
- if (of_machine_is_compatible("enterasys,ws-ap3715i"))
- return 1;
- return 0;
-}
-
define_machine(wsap3715i) {
.name = "P1010 RDB",
- .probe = wsap3715i_probe,
+ .compatible = "enterasys,ws-ap3715i",
.setup_arch = wsap3715i_setup_arch,
.init_IRQ = wsap3715i_pic_init,
#ifdef CONFIG_PCI
@@ -82,6 +71,5 @@ define_machine(wsap3715i) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c
index 5a0919c200..fbacbc96c4 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init ws_ap3825i_pic_init(void)
+static void __init ws_ap3825i_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init ws_ap3825i_setup_arch(void)
machine_arch_initcall(ws_ap3825i, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init ws_ap3825i_probe(void)
-{
- if (of_machine_is_compatible("extreme-networks,ws-ap3825i"))
- return 1;
- return 0;
-}
-
define_machine(ws_ap3825i) {
.name = "P1020 RDB",
- .probe = ws_ap3825i_probe,
+ .compatible = "extreme-networks,ws-ap3825i",
.setup_arch = ws_ap3825i_setup_arch,
.init_IRQ = ws_ap3825i_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(ws_ap3825i) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/image/p1010.mk b/target/linux/mpc85xx/image/p1010.mk
index a4f2d13dd4..1f898c483f 100644
--- a/target/linux/mpc85xx/image/p1010.mk
+++ b/target/linux/mpc85xx/image/p1010.mk
@@ -53,6 +53,7 @@ define Device/tplink_tl-wdr4900-v1
DEVICE_VARIANT := v1
DEVICE_COMPAT_VERSION := 1.1
DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
+ DEVICE_PACKAGES := kmod-usb-ledtrig-usbport
TPLINK_HEADER_VERSION := 1
TPLINK_HWID := 0x49000001
TPLINK_HWREV := 1
diff --git a/target/linux/mpc85xx/image/p1020.mk b/target/linux/mpc85xx/image/p1020.mk
index e3902d23d6..c310b26c87 100644
--- a/target/linux/mpc85xx/image/p1020.mk
+++ b/target/linux/mpc85xx/image/p1020.mk
@@ -120,5 +120,7 @@ define Device/ocedo_panda
IMAGES := fdt.bin sysupgrade.bin
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
IMAGE/fdt.bin := append-dtb
+ DEVICE_COMPAT_VERSION := 1.1
+ DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
endef
TARGET_DEVICES += ocedo_panda
diff --git a/target/linux/mpc85xx/p1010/config-default b/target/linux/mpc85xx/p1010/config-default
index f00fb4d5fd..afa930f4b4 100644
--- a/target/linux/mpc85xx/p1010/config-default
+++ b/target/linux/mpc85xx/p1010/config-default
@@ -1,4 +1,3 @@
-CONFIG_AT803X_PHY=y
CONFIG_BR200_WP=y
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_FIREBOX_T10=y
@@ -21,6 +20,8 @@ CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y
CONFIG_NET_DSA_TAG_QCA=y
CONFIG_NET_SWITCHDEV=y
CONFIG_PHYLINK=y
+CONFIG_QCA83XX_PHY=y
+CONFIG_QCOM_NET_PHYLIB=y
CONFIG_REALTEK_PHY=y
CONFIG_RED_15W_REV1=y
CONFIG_REGMAP=y
diff --git a/target/linux/mpc85xx/p1020/config-default b/target/linux/mpc85xx/p1020/config-default
index d1c0532582..36ace8015f 100644
--- a/target/linux/mpc85xx/p1020/config-default
+++ b/target/linux/mpc85xx/p1020/config-default
@@ -1,5 +1,8 @@
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_AT803X_PHY=y
+CONFIG_B53=y
+CONFIG_B53_MDIO_DRIVER=y
+CONFIG_BCM_NET_PHYLIB=y
CONFIG_BROADCOM_PHY=y
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_CPU_RMAP=y
@@ -8,6 +11,7 @@ CONFIG_EEPROM_LEGACY=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_TBSYNC=y
CONFIG_GPIO_74X164=y
+CONFIG_GRO_CELLS=y
# CONFIG_GPIO_MAX77620 is not set
CONFIG_HAVE_RCU_TABLE_FREE=y
CONFIG_HIVEAP_330=y
@@ -32,7 +36,15 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_TAG_BRCM=y
+CONFIG_NET_DSA_TAG_BRCM_COMMON=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
+CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_SWITCHDEV=y
CONFIG_NR_CPUS=2
CONFIG_PADATA=y
CONFIG_REGMAP_IRQ=y
@@ -43,13 +55,6 @@ CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SMP=y
CONFIG_SPI_GPIO=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_B53=y
-# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set
-CONFIG_SWCONFIG_B53_PHY_DRIVER=y
-# CONFIG_SWCONFIG_B53_PHY_FIXUP is not set
-# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set
-# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set
CONFIG_TREE_RCU=y
CONFIG_UBIFS_FS=y
CONFIG_WS_AP3710I=y
diff --git a/target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch b/target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch
deleted file mode 100644
index 5e5ab10daf..0000000000
--- a/target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/powerpc/platforms/85xx/common.c
-+++ b/arch/powerpc/platforms/85xx/common.c
-@@ -30,6 +30,7 @@ static const struct of_device_id mpc85xx
- { .compatible = "fsl,mpc8548-guts", },
- /* Probably unnecessary? */
- { .compatible = "gpio-leds", },
-+ { .compatible = "gpio-keys", },
- /* For all PCI controllers */
- { .compatible = "fsl,mpc8540-pci", },
- { .compatible = "fsl,mpc8548-pcie", },
diff --git a/target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch b/target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch
deleted file mode 100644
index 16ef37bd78..0000000000
--- a/target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From b30ba76a980b3a9282f309c23e3bb0b0eb2c72cd Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 30 May 2024 02:55:38 +0200
-Subject: [PATCH] powerpc: add compressed zImage for mpc85xx
-
-Add a universal zImage which can be loaded by mpc85xx boards at
-load address 0x3000000. This allows boards to boot kernels larger than
-16MB even if the image is loaded temporarily from NAND at offset
-0x1000000 which some bootloaders do by default.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/powerpc/boot/Makefile | 1 +
- arch/powerpc/boot/wrapper | 5 +++++
- 2 files changed, 6 insertions(+)
-
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -175,6 +175,7 @@ src-plat-$(CONFIG_EMBEDDED6xx) += cuboot
- src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c
- src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
- src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
-+src-plat-$(CONFIG_PPC_ZIMAGE_LA3000000) += fixed-head.S
- src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
-@@ -345,6 +346,7 @@ image-$(CONFIG_MPC836x_MDS) += cuImage.
- image-$(CONFIG_ASP834x) += dtbImage.asp834x-redboot
-
- # Board ports in arch/powerpc/platform/85xx/Kconfig
-+image-$(CONFIG_PPC_ZIMAGE_LA3000000) += zImage.la3000000
- image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads
- image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads
- image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -254,6 +254,11 @@ if [ -n "$esm_blob" -a "$platform" != "p
- fi
-
- case "$platform" in
-+la3000000)
-+ binary=y
-+ platformo="$object/fixed-head.o $object/of.o $object/epapr.o"
-+ link_address='0x3000000'
-+ ;;
- of)
- platformo="$object/of.o $object/epapr.o"
- make_space=n
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -74,6 +74,10 @@ config NMI_IPI
- depends on SMP && (DEBUGGER || KEXEC_CORE || HARDLOCKUP_DETECTOR)
- default y
-
-+config PPC_ZIMAGE_LA3000000
-+ bool
-+ default n
-+
- config PPC_WATCHDOG
- bool
- depends on HARDLOCKUP_DETECTOR
diff --git a/target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch b/target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch
deleted file mode 100644
index 5f8d84ccee..0000000000
--- a/target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 1d9f596e572917772b87a2a37e1680902964782f Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 20 Feb 2013 08:40:33 +0100
-Subject: [PATCH] powerpc: 85xx: add support for the TP-Link TL-WDR4900 v1
- board
-
-This patch adds support for the TP-Link TL-WDR4900 v1
-concurrent dual-band wireless router. The devices uses
-the Freescale P1014 SoC.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/powerpc/boot/Makefile | 3 ++-
- arch/powerpc/boot/wrapper | 5 +++++
- arch/powerpc/platforms/85xx/Kconfig | 12 ++++++++++++
- arch/powerpc/platforms/85xx/Makefile | 1 +
- 4 files changed, 20 insertions(+), 1 deletion(-)
-
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -180,6 +180,7 @@ src-plat-$(CONFIG_PPC_PSERIES) += pserie
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
-+src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-
-@@ -361,7 +362,7 @@ image-$(CONFIG_TQM8548) += cuImage.tqm
- image-$(CONFIG_TQM8555) += cuImage.tqm8555
- image-$(CONFIG_TQM8560) += cuImage.tqm8560
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
--
-+image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -346,6 +346,11 @@ adder875-redboot)
- platformo="$object/fixed-head.o $object/redboot-8xx.o"
- binary=y
- ;;
-+simpleboot-tl-wdr4900-v1)
-+ platformo="$object/fixed-head.o $object/simpleboot.o"
-+ link_address='0x1500000'
-+ binary=y
-+ ;;
- simpleboot-*)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- binary=y
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -163,6 +163,18 @@ config STX_GP3
- select CPM2
- select DEFAULT_UIMAGE
-
-+config TL_WDR4900_V1
-+ bool "TP-Link TL-WDR4900 v1"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ select SWIOTLB
-+ help
-+ This option enables support for the TP-Link TL-WDR4900 v1 board.
-+
-+ This board is a Concurrent Dual-Band wireless router with a
-+ Freescale P1014 SoC.
-+
- config TQM8540
- bool "TQ Components TQM8540"
- help
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_STX_GP3) += stx_gp3.o
-+obj-$(CONFIG_TL_WDR4900_V1) += tl_wdr4900_v1.o
- obj-$(CONFIG_TQM85xx) += tqm85xx.o
- obj-$(CONFIG_PPA8548) += ppa8548.o
- obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o
diff --git a/target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch b/target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch
deleted file mode 100644
index 18466216c0..0000000000
--- a/target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch
+++ /dev/null
@@ -1,58 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -40,6 +40,17 @@ config BSC9132_QDS
- and dual StarCore SC3850 DSP cores.
- Manufacturer : Freescale Semiconductor, Inc
-
-+config HIVEAP_330
-+ bool "Aerohive HiveAP-330"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Aerohive HiveAP-330 board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -12,6 +12,7 @@ obj-y += common.o
- obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o
- obj-$(CONFIG_BSC9132_QDS) += bsc913x_qds.o
- obj-$(CONFIG_C293_PCIE) += c293pcie.o
-+obj-$(CONFIG_HIVEAP_330) += hiveap-330.o
- obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
- obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
- obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -180,6 +180,7 @@ src-plat-$(CONFIG_PPC_PSERIES) += pserie
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
-+src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-@@ -362,6 +363,7 @@ image-$(CONFIG_TQM8548) += cuImage.tqm
- image-$(CONFIG_TQM8555) += cuImage.tqm8555
- image-$(CONFIG_TQM8560) += cuImage.tqm8560
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
-+image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -346,6 +346,7 @@ adder875-redboot)
- platformo="$object/fixed-head.o $object/redboot-8xx.o"
- binary=y
- ;;
-+simpleboot-hiveap-330|\
- simpleboot-tl-wdr4900-v1)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- link_address='0x1500000'
diff --git a/target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch b/target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch
deleted file mode 100644
index 2ac10eae8e..0000000000
--- a/target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch
+++ /dev/null
@@ -1,37 +0,0 @@
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -958,6 +958,14 @@ config CMDLINE_FORCE
-
- endchoice
-
-+config CMDLINE_OVERRIDE
-+ bool "Use alternative cmdline from device tree"
-+ help
-+ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can
-+ be used, this is not a good option for kernels that are shared across
-+ devices. This setting enables using "chosen/cmdline-override" as the
-+ cmdline if it exists in the device tree.
-+
- config EXTRA_TARGETS
- string "Additional default image types"
- help
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -1187,6 +1187,17 @@ int __init early_init_dt_scan_chosen(cha
- if (p != NULL && l > 0)
- strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE));
-
-+ /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different
-+ * device tree option of chosen/bootargs-override. This is
-+ * helpful on boards where u-boot sets bootargs, and is unable
-+ * to be modified.
-+ */
-+#ifdef CONFIG_CMDLINE_OVERRIDE
-+ p = of_get_flat_dt_prop(node, "bootargs-override", &l);
-+ if (p != NULL && l > 0)
-+ strlcpy(cmdline, p, min((int)l, COMMAND_LINE_SIZE));
-+#endif
-+
- handle_cmdline:
- /*
- * CONFIG_CMDLINE is meant to be a default in case nothing else
diff --git a/target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch b/target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch
deleted file mode 100644
index 711d98abe7..0000000000
--- a/target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -166,6 +166,16 @@ config XES_MPC85xx
- Manufacturer: Extreme Engineering Solutions, Inc.
- URL: <https://www.xes-inc.com/>
-
-+config RED_15W_REV1
-+ bool "Sophos RED 15w Rev.1"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Sophos RED 15w Rev.1 board.
-+
-+ This board is a wireless VPN router with a Freescale P1010 SoC.
-+
- config STX_GP3
- bool "Silicon Turnkey Express GP3"
- help
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
-+obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
- obj-$(CONFIG_STX_GP3) += stx_gp3.o
- obj-$(CONFIG_TL_WDR4900_V1) += tl_wdr4900_v1.o
- obj-$(CONFIG_TQM85xx) += tqm85xx.o
diff --git a/target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch b/target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch
deleted file mode 100644
index 94ed26c3df..0000000000
--- a/target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-From 93514afd769c305182beeed1f9c4c46235879ef8 Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Sun, 30 Dec 2018 23:24:41 +0100
-Subject: [PATCH] powerpc: mpc85xx: change P2020RDB dts file for OpenWRT
-
-This patch apply chages for OpenWRT in P2020RDB
-dts file.
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/powerpc/boot/dts/fsl/p2020rdb.dts | 98 +++++++++++++++++---------
- 1 file changed, 63 insertions(+), 35 deletions(-)
-
---- a/arch/powerpc/boot/dts/fsl/p2020rdb.dts
-+++ b/arch/powerpc/boot/dts/fsl/p2020rdb.dts
-@@ -5,10 +5,15 @@
- * Copyright 2009-2012 Freescale Semiconductor Inc.
- */
-
-+/dts-v1/;
-+
- /include/ "p2020si-pre.dtsi"
-
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+
- / {
-- model = "fsl,P2020RDB";
-+ model = "Freescale P2020RDB";
- compatible = "fsl,P2020RDB";
-
- aliases {
-@@ -34,48 +39,38 @@
- 0x2 0x0 0x0 0xffb00000 0x00020000>;
-
- nor@0,0 {
-- #address-cells = <1>;
-- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
-- partition@0 {
-- /* This location must not be altered */
-- /* 256KB for Vitesse 7385 Switch firmware */
-- reg = <0x0 0x00040000>;
-- label = "NOR (RO) Vitesse-7385 Firmware";
-- read-only;
-- };
--
-- partition@40000 {
-- /* 256KB for DTB Image */
-- reg = <0x00040000 0x00040000>;
-- label = "NOR (RO) DTB Image";
-- read-only;
-- };
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-
-- partition@80000 {
-- /* 3.5 MB for Linux Kernel Image */
-- reg = <0x00080000 0x00380000>;
-- label = "NOR (RO) Linux Kernel Image";
-- read-only;
-- };
-+ partition@0 {
-+ /* This location must not be altered */
-+ /* 256KB for Vitesse 7385 Switch firmware */
-+ reg = <0x0 0x00040000>;
-+ label = "NOR (RO) Vitesse-7385 Firmware";
-+ read-only;
-+ };
-
-- partition@400000 {
-- /* 11MB for JFFS2 based Root file System */
-- reg = <0x00400000 0x00b00000>;
-- label = "NOR (RW) JFFS2 Root File System";
-- };
-+ partition@40000 {
-+ compatible = "denx,fit";
-+ reg = <0x00040000 0x00ec0000>;
-+ label = "firmware";
-+ };
-
-- partition@f00000 {
-- /* This location must not be altered */
-- /* 512KB for u-boot Bootloader Image */
-- /* 512KB for u-boot Environment Variables */
-- reg = <0x00f00000 0x00100000>;
-- label = "NOR (RO) U-Boot Image";
-- read-only;
-+ partition@f00000 {
-+ /* This location must not be altered */
-+ /* 512KB for u-boot Bootloader Image */
-+ /* 512KB for u-boot Environment Variables */
-+ reg = <0x00f00000 0x00100000>;
-+ label = "u-boot";
-+ read-only;
-+ };
- };
- };
-
-@@ -85,6 +80,7 @@
- compatible = "fsl,p2020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-+ nand-ecc-mode = "none";
-
- partition@0 {
- /* This location must not be altered */
-@@ -140,13 +136,43 @@
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
-
-+ gpio0: gpio-controller@fc00 {
-+ };
-+
- i2c@3000 {
-+ temperature-sensor@4c {
-+ compatible = "adi,adt7461";
-+ reg = <0x4c>;
-+ };
-+
-+ eeprom@50 {
-+ compatible = "atmel,24c256";
-+ reg = <0x50>;
-+ };
-+
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
-+ i2c@3100 {
-+ pmic@11 {
-+ compatible = "zl2006";
-+ reg = <0x11>;
-+ };
-+
-+ gpio@18 {
-+ compatible = "nxp,pca9557";
-+ reg = <0x18>;
-+ };
-+
-+ eeprom@52 {
-+ compatible = "atmel,24c01";
-+ reg = <0x52>;
-+ };
-+ };
-+
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
-@@ -200,10 +226,12 @@
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x0>;
-+ reset-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <3 1 0 0>;
- reg = <0x1>;
-+ reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
- };
- tbi-phy@2 {
- device_type = "tbi-phy";
diff --git a/target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch b/target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch
deleted file mode 100644
index 3c24a373ab..0000000000
--- a/target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -51,6 +51,17 @@ config HIVEAP_330
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config PANDA
-+ bool "OCEDO PANDA"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the OCEDO PANDA board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -24,6 +24,7 @@ obj-$(CONFIG_P1010_RDB) += p1010rdb.o
- obj-$(CONFIG_P1022_DS) += p1022_ds.o
- obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
- obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
-+obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
diff --git a/target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch b/target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch
deleted file mode 100644
index 742fe7c2c0..0000000000
--- a/target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch
+++ /dev/null
@@ -1,60 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -62,6 +62,17 @@ config PANDA
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config WS_AP3710I
-+ bool "Enterasys WS-AP3710i"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Enterasys WS-AP3710i board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -26,6 +26,7 @@ obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
- obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
-+obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -182,6 +182,7 @@ src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) +=
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
-+src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-
-@@ -365,6 +366,7 @@ image-$(CONFIG_TQM8560) += cuImage.tqm
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
-+image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -347,7 +347,8 @@ adder875-redboot)
- binary=y
- ;;
- simpleboot-hiveap-330|\
--simpleboot-tl-wdr4900-v1)
-+simpleboot-tl-wdr4900-v1|\
-+simpleboot-ws-ap3710i)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- link_address='0x1500000'
- binary=y
diff --git a/target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch b/target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch
deleted file mode 100644
index 346001271b..0000000000
--- a/target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 2fa1a7983ef30f3c7486f9b07c001bee87d1f6d6 Mon Sep 17 00:00:00 2001
-From: Martin Kennedy <hurricos@gmail.com>
-Date: Sat, 1 Jan 2022 11:01:37 -0500
-Subject: [PATCH] PowerPC 85xx: Add WS-AP3825i support
-
-This patch adds support for building Linux for the Extreme Networks
-WS-AP3825i AP.
-
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -73,6 +73,16 @@ config WS_AP3710I
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config WS_AP3825I
-+ bool "Extreme Networks WS-AP3825i"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Extreme Networks WS-AP3825i board.
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
-+obj-$(CONFIG_WS_AP3825I) += ws-ap3825i.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -183,6 +183,7 @@ src-plat-$(CONFIG_MVME7100) += motload-h
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-+src-plat-$(CONFIG_WS_AP3825I) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-
-@@ -367,6 +368,7 @@ image-$(CONFIG_KSI8560) += cuImage.ksi
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
-+image-$(CONFIG_WS_AP3825I) += simpleImage.ws-ap3825i
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -348,7 +348,8 @@ adder875-redboot)
- ;;
- simpleboot-hiveap-330|\
- simpleboot-tl-wdr4900-v1|\
--simpleboot-ws-ap3710i)
-+simpleboot-ws-ap3710i|\
-+simpleboot-ws-ap3825i)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- link_address='0x1500000'
- binary=y
diff --git a/target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch b/target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch
deleted file mode 100644
index 0b3a93b848..0000000000
--- a/target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -83,6 +83,16 @@ config WS_AP3825I
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config FIREBOX_T10
-+ bool "Watchguard Firebox T10"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Watchguard Firebox T10 board.
-+ This board is a VPN Gateway-Router with a
-+ Freescale P1010 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -28,6 +28,7 @@ obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
- obj-$(CONFIG_WS_AP3825I) += ws-ap3825i.o
-+obj-$(CONFIG_FIREBOX_T10) += firebox_t10.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
diff --git a/target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch b/target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch
deleted file mode 100644
index a9f7079866..0000000000
--- a/target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch
+++ /dev/null
@@ -1,48 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -73,6 +73,17 @@ config WS_AP3710I
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config WS_AP3715I
-+ bool "Enterasys WS-AP3715i"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Enterasys WS-AP3715i board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1010 SoC.
-+
- config WS_AP3825I
- bool "Extreme Networks WS-AP3825i"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
-+obj-$(CONFIG_WS_AP3715I) += ws-ap3715i.o
- obj-$(CONFIG_WS_AP3825I) += ws-ap3825i.o
- obj-$(CONFIG_FIREBOX_T10) += firebox_t10.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -183,6 +183,7 @@ src-plat-$(CONFIG_MVME7100) += motload-h
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-+src-plat-$(CONFIG_WS_AP3715I) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3825I) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-@@ -368,6 +369,7 @@ image-$(CONFIG_KSI8560) += cuImage.ksi
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
-+image-$(CONFIG_WS_AP3715I) += simpleImage.ws-ap3715i
- image-$(CONFIG_WS_AP3825I) += simpleImage.ws-ap3825i
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
diff --git a/target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch b/target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch
deleted file mode 100644
index a58d12aef2..0000000000
--- a/target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch
+++ /dev/null
@@ -1,57 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -40,6 +40,16 @@ config BSC9132_QDS
- and dual StarCore SC3850 DSP cores.
- Manufacturer : Freescale Semiconductor, Inc
-
-+config BR200_WP
-+ bool "Aerohive BR200-WP"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Aerohive BR200-WP board.
-+
-+ This board is a wireless router with a Freescale P1011 SoC.
-+
- config HIVEAP_330
- bool "Aerohive HiveAP-330"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -12,6 +12,7 @@ obj-y += common.o
- obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o
- obj-$(CONFIG_BSC9132_QDS) += bsc913x_qds.o
- obj-$(CONFIG_C293_PCIE) += c293pcie.o
-+obj-$(CONFIG_BR200_WP) += br200-wp.o
- obj-$(CONFIG_HIVEAP_330) += hiveap-330.o
- obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
- obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -180,6 +180,7 @@ src-plat-$(CONFIG_PPC_PSERIES) += pserie
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
-+src-plat-$(CONFIG_BR200_WP) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-@@ -366,6 +367,7 @@ image-$(CONFIG_TQM8548) += cuImage.tqm
- image-$(CONFIG_TQM8555) += cuImage.tqm8555
- image-$(CONFIG_TQM8560) += cuImage.tqm8560
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
-+image-$(CONFIG_BR200_WP) += simpleImage.br200-wp
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -346,6 +346,7 @@ adder875-redboot)
- platformo="$object/fixed-head.o $object/redboot-8xx.o"
- binary=y
- ;;
-+simpleboot-br200-wp|\
- simpleboot-hiveap-330|\
- simpleboot-tl-wdr4900-v1|\
- simpleboot-ws-ap3710i|\
diff --git a/target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch b/target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch
deleted file mode 100644
index 4b9c6f8219..0000000000
--- a/target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -114,6 +114,18 @@ config FIREBOX_T10
- This board is a VPN Gateway-Router with a
- Freescale P1010 SoC.
-
-+config MSM460
-+ bool "HPE MSM460"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ select PPC_ZIMAGE_LA3000000
-+ help
-+ This option enables support for the HPE MSM460 board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -21,6 +21,7 @@ obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.
- obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o
- obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
- obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
-+obj-$(CONFIG_MSM460) += msm460.o
- obj-$(CONFIG_P1010_RDB) += p1010rdb.o
- obj-$(CONFIG_P1022_DS) += p1022_ds.o
- obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
diff --git a/target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch b/target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch
deleted file mode 100644
index 1ff80a5016..0000000000
--- a/target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 5f856ccc34df25060d36a5a81b7b45b574d86e35 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 3 Dec 2023 20:09:24 +0100
-Subject: [PATCH] arch: powerpc: simpleboot: prevent overwrite of CPU1
- spin-table
-
-Don't overwrite the spin-table of additional CPU cores with loader-heap.
-
-U-Boot places the spin-table for CPU1 on P1020 SoCs in the top 1MB of
-system-memory. Instead of parsing reserved-memory (which would be
-considerable more work), reduce the available system-memory for the
-loader by 1MB.
-
-This prevents the loader from overwriting the spin-table of
-additional CPU cores on these platforms.
-
-Linux itself needs to be made aware by this using reserved-memory
-definitions.
-
-This patch is required for using CPU1 on the Extreme Networks
-WS-AP3825i.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/powerpc/boot/simpleboot.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/arch/powerpc/boot/simpleboot.c
-+++ b/arch/powerpc/boot/simpleboot.c
-@@ -65,6 +65,11 @@ void platform_init(unsigned long r3, uns
- if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
- memsize64 = 0xffffffff;
-
-+ /* Reserve upper 1 MB of memory for CPU1 spin-table */
-+ if (memsize64 > 0x100000) {
-+ memsize64 = memsize64 - 0x100000;
-+ }
-+
- /* finally, setup the timebase */
- node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
- "cpu", sizeof("cpu"));
diff --git a/target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch b/target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch
deleted file mode 100644
index a997a1b9b7..0000000000
--- a/target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From d43ab14605510d9d2bd257a8cd70f24ada4621b0 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sat, 29 Feb 2020 14:27:04 +0100
-Subject: [PATCH] powerpc: bootwrapper: disable uImage generation
-
-Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
-instruct the mkimage to use the xz compression, which isn't
-supported. This disables the uImage generation, as OpenWrt
-generates individual uImages for each board using it's own
-toolchain.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/powerpc/boot/Makefile | 9 ---------
- 1 file changed, 9 deletions(-)
-
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -294,7 +294,6 @@ image-$(CONFIG_PPC_CHRP) += zImage.chrp
- image-$(CONFIG_PPC_EFIKA) += zImage.chrp
- image-$(CONFIG_PPC_PMAC) += zImage.pmac
- image-$(CONFIG_PPC_HOLLY) += dtbImage.holly
--image-$(CONFIG_DEFAULT_UIMAGE) += uImage
- image-$(CONFIG_EPAPR_BOOT) += zImage.epapr
-
- #
-@@ -432,15 +431,6 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits
- $(obj)/vmlinux.strip: vmlinux
- $(STRIP) -s -R .comment $< -o $@
-
--$(obj)/uImage: vmlinux $(wrapperbits) FORCE
-- $(call if_changed,wrap,uboot)
--
--$(obj)/uImage.initrd.%: vmlinux $(obj)/dts/%.dtb $(wrapperbits) FORCE
-- $(call if_changed,wrap,uboot-$*,,$(obj)/dts/$*.dtb,$(obj)/ramdisk.image.gz)
--
--$(obj)/uImage.%: vmlinux $(obj)/dts/%.dtb $(wrapperbits) FORCE
-- $(call if_changed,wrap,uboot-$*,,$(obj)/dts/$*.dtb)
--
- $(obj)/cuImage.initrd.%: vmlinux $(obj)/dts/%.dtb $(wrapperbits) FORCE
- $(call if_changed,wrap,cuboot-$*,,$(obj)/dts/$*.dtb,$(obj)/ramdisk.image.gz)
-
diff --git a/target/linux/mvebu/config-6.6 b/target/linux/mvebu/config-6.6
index 88e5fff4d9..a4572d8a89 100644
--- a/target/linux/mvebu/config-6.6
+++ b/target/linux/mvebu/config-6.6
@@ -270,6 +270,7 @@ CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_NAND_MARVELL=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
diff --git a/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds b/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds
index 809a64a60e..2d18587a62 100644
--- a/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds
+++ b/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds
@@ -13,6 +13,10 @@ iei,puzzle-m901)
iei,puzzle-m902)
ucidef_set_led_netdev "wan" "WAN" "white:network" "eth2" "link"
;;
+mikrotik,rb5009)
+ ucidef_set_led_netdev "sfp" "SFP" "green:sfp" "sfp"
+ ucidef_set_led_netdev "wan-port-link" "WAN-PORT-LINK" "!cp0!config-space@f2000000!mdio@12a200!switch@0!mdio1:00:green:" "p1" "tx rx link_10 link_100 link_1000 link_2500"
+ ;;
esac
board_config_flush
diff --git a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh
index a2742aa374..3badb0583a 100644
--- a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh
+++ b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh
@@ -1,31 +1,129 @@
. /lib/functions.sh
-fortinet_fwinfo_blocks() {
+fortinet_bswap32() {
+ local val="$(printf %08x $(($1)))"
+
+ # swap and print in hex
+ echo "0x${val:6:2}${val:4:2}${val:2:2}${val:0:2}"
+}
+
+fortinet_by2bl() {
+ local blks="$(($1 / 0x200))"
+ [ $(($1 % 0x200)) -gt 0 ] && blks=$((blks + 1))
+
+ printf "0x%08x" $blks
+}
+
+fortinet_bl2by() {
+ printf "0x%08x" $(($1 * 0x200))
+}
+
+fortinet_build_partmap() {
+ local new="$1" old="$2"
+ local len="${old%%@*}" ofs="${old##*@}"
+
+ case "$new" in
+ @*) ofs="$(fortinet_by2bl ${new##@})" ;; # "@<offset>"
+
+ *@*) len="$(fortinet_by2bl ${new%%@*})" # "<length>@<offset>"
+ ofs="$(fortinet_by2bl ${new##*@})" ;;
+
+ "") ;; # "" (empty)
+
+ *) len="$(fortinet_by2bl ${new%%@*})" ;; # "<length>"
+ esac
+
+ # print N blocks of length/offset in dec
+ echo "${len}@${ofs}"
+}
+
+# Update firmware information in "firmware-info" partition
+#
+# parameters:
+# $1: image index (0/1)
+# $2: new image name (up to 32 characters)
+# $3: length and/or offset for kernel (bytes)
+# $4: length and/or offset for rootfs (bytes)
+#
+# Note: $3 and $4 support multiple formats:
+#
+# - <length>@<offset>: set <length> and <rootfs>
+# - <length> : set <length> and keep the current offset
+# - @<offset> : set <offset> and keep the current length
+# - "" (empty) : keep the current length and offset
+fortinet_update_fwinfo() {
local fwinfo_mtd="$(find_mtd_part firmware-info)"
- local offset="$1"
- local len="$2"
- local blks
+ local index="$1"
+ local name="$2"
+ local offset
+ local old_kr
+ local old new tmp part pos
+ local output
if [ -z "$fwinfo_mtd" ]; then
- echo "WARN: MTD device \"firmware-info\" not found"
+ echo "ERROR: MTD device \"firmware-info\" not found"
return 1
fi
- blks=$((len / 0x200))
- [ $((len % 0x200)) -gt 0 ] && blks=$((blks + 1))
- blks=$(printf "%04x" $blks)
- printf "fwinfo: offset-> 0x%x, blocks-> 0x%s (len: 0x%08x)\n" \
- $offset $blks $len
+ # Image Name
+ case "$index" in
+ 0) offset=0x10 ;;
+ 1) offset=0x30 ;;
+ *) echo "ERROR: invalid image index specified!"; return 1 ;;
+ esac
+
+ printf "Image Index: %d\n" $index
+
+ old="$(dd bs=16 count=2 skip=$((offset / 16)) if=$fwinfo_mtd 2>/dev/null)"
+ printf "Image Name : \"%s\"\n" "$old"
+ if [ -n "$name" ]; then
+ echo -n "$name" | \
+ dd bs=32 count=1 oflag=seek_bytes seek=$((offset)) \
+ conv=sync,notrunc of=$fwinfo_mtd 2>/dev/null
+ printf " --> \"%s\"\n\n" "$name"
+ else
+ printf "\n"
+ fi
+
+ # length/offset values of kernel/rootfs
+ case "$index" in
+ 0) offset=0x180 ;;
+ 1) offset=0x190 ;;
+ esac
+
+ # <kernel offset:4><kernel length:4><rootfs offset:4><rootfs length:4>
+ old_kr="$(hexdump -n 16 -v -s $((offset)) -e '1/4 "%08x"' $fwinfo_mtd)"
+
+ pos=0
+ for part in kernel rootfs; do
+ old="0x${old_kr:$((8 + pos)):8}@0x${old_kr:$((0 + pos)):8}"
+ new="$(fortinet_build_partmap "$3" "$old")"
+ shift
+
+ printf " %s:\n" $part
+ printf " old: 0x%08x@0x%08x\n" \
+ $(fortinet_bl2by ${old%%@*}) $(fortinet_bl2by ${old##*@})
+ printf " new: 0x%08x@0x%08x\n\n" \
+ $(fortinet_bl2by ${new%%@*}) $(fortinet_bl2by ${new##*@})
- printf "\x${blks:2:2}\x${blks:0:2}" | \
- dd bs=2 count=1 seek=$((offset / 2)) conv=notrunc of=${fwinfo_mtd}
+ tmp="$(fortinet_bswap32 ${new%%@*})@$(fortinet_bswap32 ${new##*@})"
+ new="$(echo $tmp | sed 's/0x\([0-9a-f]\{8\}\)@0x\([0-9a-f]\{8\}\)/\2\1/')"
+ output="${output}${new}"
+
+ pos=$((pos + 16))
+ done
+
+ data_2bin "$output" | \
+ dd bs=16 count=1 seek=$((offset / 16)) conv=notrunc \
+ of=$fwinfo_mtd 2>/dev/null
}
fortinet_do_upgrade() {
local board_dir="$(tar tf "$1" | grep -m 1 '^sysupgrade-.*/$')"
local kern_mtd="$(find_mtd_part kernel)"
local root_mtd="$(find_mtd_part rootfs)"
- local kern_len root_len
+ local kern_len kern_ofs root_len root_ofs
+ local imgname
board_dir="${board_dir%/}"
@@ -34,6 +132,14 @@ fortinet_do_upgrade() {
umount -a
reboot -f
fi
+ kern_ofs=$(cat /sys/class/mtd/${kern_mtd//\/dev\/mtdblock/mtd}/offset)
+ root_ofs=$(cat /sys/class/mtd/${root_mtd//\/dev\/mtdblock/mtd}/offset)
+
+ if [ -z "$kern_ofs" ] || [ -z "$root_ofs" ]; then
+ echo "ERROR: failed to get offset of kernel or rootfs"
+ umount -a
+ reboot -f
+ fi
kern_len=$( (tar xOf "$1" "$board_dir/kernel" | wc -c) 2> /dev/null)
root_len=$( (tar xOf "$1" "$board_dir/root" | wc -c) 2> /dev/null)
@@ -44,8 +150,34 @@ fortinet_do_upgrade() {
reboot -f
fi
- fortinet_fwinfo_blocks "0x184" "$kern_len"
- fortinet_fwinfo_blocks "0x18c" "$root_len"
+ # try to load and parse /tmp/sysupgrade.meta for image name
+ if [ -r "/tmp/sysupgrade.meta" ]; then
+ local key value
+
+ sed -e 's/, \{1,2\}\"/\n"/g' \
+ -e 's/{ \{1,2\}/\n/g' \
+ -e 's/ \{1,2\}}/\n/g' < /tmp/sysupgrade.meta \
+ > /tmp/sysupgrade.meta.tmp
+ while read key value; do
+ key="${key//\"/}"
+ value="${value//\"/}"
+
+ [ -z "$value" ] && continue
+ case "$key" in
+ dist:|\
+ version:|\
+ revision:) imgname="${imgname}$value " ;;
+ esac
+ done < /tmp/sysupgrade.meta.tmp
+ else
+ imgname="OpenWrt"
+ fi
+
+ fortinet_update_fwinfo 0 "${imgname%% }" \
+ "${kern_len}@${kern_ofs}" "${root_len}@${root_ofs}" || {
+ umount -a
+ reboot -f
+ }
tar xOf "$1" "$board_dir/kernel" | \
mtd write - "kernel"
diff --git a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
index a15823d8c6..049f8eeb8c 100755
--- a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
@@ -3,7 +3,7 @@
# Copyright (C) 2016 LEDE-Project.org
#
-RAMFS_COPY_BIN='fw_printenv fw_setenv strings'
+RAMFS_COPY_BIN='fw_printenv fw_setenv seq strings'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
PART_NAME=firmware
diff --git a/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-3xe.dtsi b/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-3xe.dtsi
index 44dd42201d..6d835332d2 100644
--- a/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-3xe.dtsi
+++ b/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-3xe.dtsi
@@ -14,14 +14,14 @@
gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
color = <LED_COLOR_ID_AMBER>;
function = LED_FUNCTION_SPEED_WAN;
- linux,default-trigger = "mv88e6xxx-1:00:100Mbps";
+ linux,default-trigger = "mv88e6xxx-0:00:100Mbps";
};
led-15 {
gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_SPEED_WAN;
- linux,default-trigger = "mv88e6xxx-1:00:1Gbps";
+ linux,default-trigger = "mv88e6xxx-0:00:1Gbps";
};
};
diff --git a/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-5xe.dtsi b/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-5xe.dtsi
index 063632d888..bf1daa3bc6 100644
--- a/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-5xe.dtsi
+++ b/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-5xe.dtsi
@@ -31,7 +31,7 @@
color = <LED_COLOR_ID_AMBER>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <5>;
- linux,default-trigger = "mv88e6xxx-1:00:100Mbps";
+ linux,default-trigger = "mv88e6xxx-0:00:100Mbps";
};
led-17 {
@@ -39,7 +39,7 @@
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <5>;
- linux,default-trigger = "mv88e6xxx-1:00:1Gbps";
+ linux,default-trigger = "mv88e6xxx-0:00:1Gbps";
};
};
diff --git a/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-xxe.dtsi b/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-xxe.dtsi
index ba4460fddd..a1adddc4e0 100644
--- a/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-xxe.dtsi
+++ b/target/linux/mvebu/files-6.6/arch/arm/boot/dts/marvell/armada-385-fortinet-fg-xxe.dtsi
@@ -86,7 +86,7 @@
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <4>;
- linux,default-trigger = "mv88e6xxx-1:01:1Gbps";
+ linux,default-trigger = "mv88e6xxx-0:01:1Gbps";
};
led-7 {
@@ -94,7 +94,7 @@
color = <LED_COLOR_ID_AMBER>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <4>;
- linux,default-trigger = "mv88e6xxx-1:01:100Mbps";
+ linux,default-trigger = "mv88e6xxx-0:01:100Mbps";
};
led-8 {
@@ -102,7 +102,7 @@
color = <LED_COLOR_ID_AMBER>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <3>;
- linux,default-trigger = "mv88e6xxx-1:02:100Mbps";
+ linux,default-trigger = "mv88e6xxx-0:02:100Mbps";
};
led-9 {
@@ -110,7 +110,7 @@
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <3>;
- linux,default-trigger = "mv88e6xxx-1:02:1Gbps";
+ linux,default-trigger = "mv88e6xxx-0:02:1Gbps";
};
led-10 {
@@ -118,7 +118,7 @@
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <1>;
- linux,default-trigger = "mv88e6xxx-1:04:1Gbps";
+ linux,default-trigger = "mv88e6xxx-0:04:1Gbps";
};
led-11 {
@@ -126,7 +126,7 @@
color = <LED_COLOR_ID_AMBER>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <1>;
- linux,default-trigger = "mv88e6xxx-1:04:100Mbps";
+ linux,default-trigger = "mv88e6xxx-0:04:100Mbps";
};
led-12 {
@@ -134,7 +134,7 @@
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <2>;
- linux,default-trigger = "mv88e6xxx-1:03:1Gbps";
+ linux,default-trigger = "mv88e6xxx-0:03:1Gbps";
};
led-13 {
@@ -142,12 +142,12 @@
color = <LED_COLOR_ID_AMBER>;
function = LED_FUNCTION_SPEED_LAN;
function-enumerator = <2>;
- linux,default-trigger = "mv88e6xxx-1:03:100Mbps";
+ linux,default-trigger = "mv88e6xxx-0:03:100Mbps";
};
};
reg_usb_vbus: regulator-usb-vbus {
- compatible = "fixed-regulator";
+ compatible = "regulator-fixed";
regulator-name = "usb-vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
diff --git a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
index 07400fce3a..e098ede75f 100644
--- a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
+++ b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
@@ -100,7 +100,6 @@
partition@f0000 {
label = "u-boot-env";
reg = <0xf0000 0x8000>;
- read-only;
};
factory: partition@f8000 {
diff --git a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-7040-rb5009.dts b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-7040-rb5009.dts
index 8cd744f64d..dfbf3af137 100644
--- a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-7040-rb5009.dts
+++ b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-7040-rb5009.dts
@@ -5,6 +5,7 @@
#include "armada-7040.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
/ {
model = "MikroTik RB5009";
@@ -71,23 +72,27 @@
compatible = "gpio-leds";
led_user: user {
- label = "green:user";
+ function = "user";
gpios = <&cp0_gpio2 26 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
};
sfp {
- label = "green:sfp";
+ function = "sfp";
gpios = <&cp0_gpio2 25 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
};
hdr1 {
- label = "blue:hdr1";
+ function = "hdr1";
gpios = <&cp0_gpio1 4 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_BLUE>;
};
hdr2 {
- label = "blue:hdr2";
+ function = "hdr2";
gpios = <&cp0_gpio2 19 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_BLUE>;
};
};
@@ -378,6 +383,19 @@
qca8081: qca8081@0 {
reg = <0>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ active-low;
+ };
+ };
};
};
};
diff --git a/target/linux/mvebu/image/cortexa53.mk b/target/linux/mvebu/image/cortexa53.mk
index afe8d9ce21..2a3b5ee11e 100644
--- a/target/linux/mvebu/image/cortexa53.mk
+++ b/target/linux/mvebu/image/cortexa53.mk
@@ -3,6 +3,7 @@ define Device/glinet_gl-mv1000
DEVICE_VENDOR := GL.iNet
DEVICE_MODEL := GL-MV1000
SOC := armada-3720
+ BOOT_SCRIPT := gl-mv1000
endef
TARGET_DEVICES += glinet_gl-mv1000
diff --git a/target/linux/mvebu/image/cortexa9.mk b/target/linux/mvebu/image/cortexa9.mk
index b3b8960a32..a396b48675 100644
--- a/target/linux/mvebu/image/cortexa9.mk
+++ b/target/linux/mvebu/image/cortexa9.mk
@@ -106,7 +106,8 @@ define Device/cznic_turris-omnia
DEVICE_PACKAGES := \
mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 \
wpad-basic-mbedtls kmod-ath9k kmod-ath10k-ct ath10k-firmware-qca988x-ct \
- kmod-mt7915-firmware partx-utils kmod-i2c-mux-pca954x kmod-leds-turris-omnia
+ kmod-mt7915-firmware partx-utils kmod-i2c-mux-pca954x kmod-leds-turris-omnia \
+ kmod-turris-omnia-mcu kmod-gpio-button-hotplug omnia-mcu-firmware omnia-mcutool
IMAGES := sysupgrade.img.gz
IMAGE/sysupgrade.img.gz := boot-scr | boot-img | sdcard-img | gzip | append-metadata
SUPPORTED_DEVICES += armada-385-turris-omnia
diff --git a/target/linux/mvebu/image/gl-mv1000.bootscript b/target/linux/mvebu/image/gl-mv1000.bootscript
new file mode 100644
index 0000000000..be93aa36a0
--- /dev/null
+++ b/target/linux/mvebu/image/gl-mv1000.bootscript
@@ -0,0 +1,28 @@
+# Boot script for GL.iNet GL-MV1000 to make it easier to boot from eMMC or SD
+# card.
+
+setenv bootargs "root=PARTUUID=@ROOT@-02 rw rootwait"
+
+if test -n "${console}"; then
+ setenv bootargs "${bootargs} ${console}"
+fi
+
+# Should mmc_dev not be present, default to internal MMC boot
+if test -z "${mmc_dev}"; then
+ setenv mmc_dev 0
+fi
+
+setenv mmcdev "${mmc_dev}"
+
+if test -n "${fdt_addr_r}"; then
+ setenv fdt_addr ${fdt_addr_r}
+fi
+
+if test -n "${kernel_addr_r}"; then
+ setenv kernel_addr ${kernel_addr_r}
+fi
+
+load mmc ${mmcdev}:1 ${fdt_addr} @DTB@.dtb
+load mmc ${mmcdev}:1 ${kernel_addr} Image
+
+booti ${kernel_addr} - ${fdt_addr}
diff --git a/target/linux/mvebu/modules.mk b/target/linux/mvebu/modules.mk
index 311cc07c7f..e6fa6ab3ed 100644
--- a/target/linux/mvebu/modules.mk
+++ b/target/linux/mvebu/modules.mk
@@ -17,6 +17,27 @@ endef
$(eval $(call KernelPackage,linkstation-poweroff))
+define KernelPackage/turris-omnia-mcu
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=CZ.NIC's Turris Omnia MCU driver
+ DEPENDS:=@TARGET_mvebu_cortexa9
+ KCONFIG:= \
+ CONFIG_CZNIC_PLATFORMS=y \
+ CONFIG_TURRIS_OMNIA_MCU
+ FILES:=$(LINUX_DIR)/drivers/platform/cznic/turris-omnia-mcu.ko
+ AUTOLOAD:=$(call AutoProbe,turris-omnia-mcu,1)
+endef
+
+define KernelPackage/turris-omnia-mcu/description
+ This adds support for the features implemented by the microcontroller
+ on the CZ.NIC's Turris Omnia SOHO router, including true board
+ poweroff, the ability to configure wake up from powered off state at
+ a specific time, MCU watchdog and MCU connected GPIO pins.
+endef
+
+$(eval $(call KernelPackage,turris-omnia-mcu))
+
+
define KernelPackage/leds-turris-omnia
SUBMENU:=$(LEDS_MENU)
TITLE:=LED support for CZ.NIC's Turris Omnia
diff --git a/target/linux/mvebu/patches-6.6/701-mvpp2-read-mac-address-from-nvmem.patch b/target/linux/mvebu/patches-6.6/701-mvpp2-read-mac-address-from-nvmem.patch
index c5bad1772f..69ee10c3f2 100644
--- a/target/linux/mvebu/patches-6.6/701-mvpp2-read-mac-address-from-nvmem.patch
+++ b/target/linux/mvebu/patches-6.6/701-mvpp2-read-mac-address-from-nvmem.patch
@@ -12,7 +12,7 @@ Signed-off-by: Tobias Schramm <tobias@t-sys.eu>
---
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-@@ -6153,6 +6153,12 @@ static int mvpp2_port_copy_mac_addr(stru
+@@ -6156,6 +6156,12 @@ static int mvpp2_port_copy_mac_addr(stru
return 0;
}
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch b/target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch
new file mode 100644
index 0000000000..4d6d8e82c2
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch
@@ -0,0 +1,125 @@
+From cdfed4d05780450817ef96567e2cd8d355ca9e70 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:03 +0200
+Subject: [PATCH 01/11] dt-bindings: firmware: add cznic,turris-omnia-mcu
+ binding
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding for cznic,turris-omnia-mcu, the device-tree node
+representing the system-controller features provided by the MCU on the
+Turris Omnia router.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-2-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../firmware/cznic,turris-omnia-mcu.yaml | 86 +++++++++++++++++++
+ MAINTAINERS | 1 +
+ 2 files changed, 87 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
+@@ -0,0 +1,86 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/firmware/cznic,turris-omnia-mcu.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: CZ.NIC's Turris Omnia MCU
++
++maintainers:
++ - Marek Behún <kabel@kernel.org>
++
++description:
++ The MCU on Turris Omnia acts as a system controller providing additional
++ GPIOs, interrupts, watchdog, system power off and wakeup configuration.
++
++properties:
++ compatible:
++ const: cznic,turris-omnia-mcu
++
++ reg:
++ description: MCU I2C slave address
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ interrupt-controller: true
++
++ '#interrupt-cells':
++ const: 2
++ description: |
++ The first cell specifies the interrupt number (0 to 63), the second cell
++ specifies interrupt type (which can be one of IRQ_TYPE_EDGE_RISING,
++ IRQ_TYPE_EDGE_FALLING or IRQ_TYPE_EDGE_BOTH).
++ The interrupt numbers correspond sequentially to GPIO numbers, taking the
++ GPIO banks into account:
++ IRQ number GPIO bank GPIO pin within bank
++ 0 - 15 0 0 - 15
++ 16 - 47 1 0 - 31
++ 48 - 63 2 0 - 15
++ There are several exceptions:
++ IRQ number meaning
++ 11 LED panel brightness changed by button press
++ 13 TRNG entropy ready
++ 14 ECDSA message signature computation done
++
++ gpio-controller: true
++
++ '#gpio-cells':
++ const: 3
++ description:
++ The first cell is bank number (0, 1 or 2), the second cell is pin number
++ within the bank (0 to 15 for banks 0 and 2, 0 to 31 for bank 1), and the
++ third cell specifies consumer flags.
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - interrupt-controller
++ - gpio-controller
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/interrupt-controller/irq.h>
++
++ i2c {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ system-controller@2a {
++ compatible = "cznic,turris-omnia-mcu";
++ reg = <0x2a>;
++
++ interrupt-parent = <&gpio1>;
++ interrupts = <11 IRQ_TYPE_NONE>;
++
++ gpio-controller;
++ #gpio-cells = <3>;
++
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++ };
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -2104,6 +2104,7 @@ F: Documentation/ABI/testing/sysfs-bus-m
+ F: Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
+ F: Documentation/devicetree/bindings/bus/moxtet.txt
+ F: Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt
++F: Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
+ F: Documentation/devicetree/bindings/gpio/gpio-moxtet.txt
+ F: Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml
+ F: Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch b/target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch
new file mode 100644
index 0000000000..72bd18d144
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch
@@ -0,0 +1,922 @@
+From 4a63f684c8badfc43f384df2291ed2566909a3bc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:04 +0200
+Subject: [PATCH 02/11] platform: cznic: Add preliminary support for Turris
+ Omnia MCU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add the basic skeleton for a new platform driver for the microcontroller
+found on the Turris Omnia board.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-3-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../sysfs-bus-i2c-devices-turris-omnia-mcu | 81 ++++
+ MAINTAINERS | 3 +
+ drivers/platform/Kconfig | 2 +
+ drivers/platform/Makefile | 1 +
+ drivers/platform/cznic/Kconfig | 25 ++
+ drivers/platform/cznic/Makefile | 4 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 393 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 74 ++++
+ include/linux/turris-omnia-mcu-interface.h | 249 +++++++++++
+ 9 files changed, 832 insertions(+)
+ create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+ create mode 100644 drivers/platform/cznic/Kconfig
+ create mode 100644 drivers/platform/cznic/Makefile
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-base.c
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu.h
+ create mode 100644 include/linux/turris-omnia-mcu-interface.h
+
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+@@ -0,0 +1,81 @@
++What: /sys/bus/i2c/devices/<mcu_device>/board_revision
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains board revision number.
++
++ Only available if board information is burned in the MCU (older
++ revisions have board information burned in the ATSHA204-A chip).
++
++ Format: %u.
++
++What: /sys/bus/i2c/devices/<mcu_device>/first_mac_address
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains device first MAC address. Each Turris Omnia is
++ allocated 3 MAC addresses. The two additional addresses are
++ computed from the first one by incrementing it.
++
++ Only available if board information is burned in the MCU (older
++ revisions have board information burned in the ATSHA204-A chip).
++
++ Format: %pM.
++
++What: /sys/bus/i2c/devices/<mcu_device>/fw_features
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Newer versions of the microcontroller firmware report the
++ features they support. These can be read from this file. If the
++ MCU firmware is too old, this file reads 0x0.
++
++ Format: 0x%x.
++
++What: /sys/bus/i2c/devices/<mcu_device>/fw_version_hash_application
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the version hash (commit hash) of the application
++ part of the microcontroller firmware.
++
++ Format: %s.
++
++What: /sys/bus/i2c/devices/<mcu_device>/fw_version_hash_bootloader
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the version hash (commit hash) of the bootloader
++ part of the microcontroller firmware.
++
++ Format: %s.
++
++What: /sys/bus/i2c/devices/<mcu_device>/mcu_type
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the microcontroller type (STM32, GD32, MKL).
++
++ Format: %s.
++
++What: /sys/bus/i2c/devices/<mcu_device>/reset_selector
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the selected factory reset level, determined by
++ how long the rear reset button was held by the user during board
++ reset.
++
++ Format: %i.
++
++What: /sys/bus/i2c/devices/<mcu_device>/serial_number
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the 64-bit board serial number in hexadecimal
++ format.
++
++ Only available if board information is burned in the MCU (older
++ revisions have board information burned in the ATSHA204-A chip).
++
++ Format: %016X.
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -2100,6 +2100,7 @@ M: Marek Behún <kabel@kernel.org>
+ S: Maintained
+ W: https://www.turris.cz/
+ F: Documentation/ABI/testing/debugfs-moxtet
++F: Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+ F: Documentation/ABI/testing/sysfs-bus-moxtet-devices
+ F: Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
+ F: Documentation/devicetree/bindings/bus/moxtet.txt
+@@ -2113,10 +2114,12 @@ F: drivers/firmware/turris-mox-rwtm.c
+ F: drivers/gpio/gpio-moxtet.c
+ F: drivers/leds/leds-turris-omnia.c
+ F: drivers/mailbox/armada-37xx-rwtm-mailbox.c
++F: drivers/platform/cznic/
+ F: drivers/watchdog/armada_37xx_wdt.c
+ F: include/dt-bindings/bus/moxtet.h
+ F: include/linux/armada-37xx-rwtm-mailbox.h
+ F: include/linux/moxtet.h
++F: include/linux/turris-omnia-mcu-interface.h
+
+ ARM/FARADAY FA526 PORT
+ M: Hans Ulli Kroll <ulli.kroll@googlemail.com>
+--- a/drivers/platform/Kconfig
++++ b/drivers/platform/Kconfig
+@@ -7,6 +7,8 @@ source "drivers/platform/goldfish/Kconfi
+
+ source "drivers/platform/chrome/Kconfig"
+
++source "drivers/platform/cznic/Kconfig"
++
+ source "drivers/platform/mellanox/Kconfig"
+
+ source "drivers/platform/olpc/Kconfig"
+--- a/drivers/platform/Makefile
++++ b/drivers/platform/Makefile
+@@ -10,5 +10,6 @@ obj-$(CONFIG_MIPS) += mips/
+ obj-$(CONFIG_OLPC_EC) += olpc/
+ obj-$(CONFIG_GOLDFISH) += goldfish/
+ obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
++obj-$(CONFIG_CZNIC_PLATFORMS) += cznic/
+ obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
+ obj-$(CONFIG_MIKROTIK) += mikrotik/
+--- /dev/null
++++ b/drivers/platform/cznic/Kconfig
+@@ -0,0 +1,25 @@
++# SPDX-License-Identifier: GPL-2.0-only
++#
++# For a description of the syntax of this configuration file,
++# see Documentation/kbuild/kconfig-language.rst.
++#
++
++menuconfig CZNIC_PLATFORMS
++ bool "Platform support for CZ.NIC's Turris hardware"
++ help
++ Say Y here to be able to choose driver support for CZ.NIC's Turris
++ devices. This option alone does not add any kernel code.
++
++if CZNIC_PLATFORMS
++
++config TURRIS_OMNIA_MCU
++ tristate "Turris Omnia MCU driver"
++ depends on MACH_ARMADA_38X || COMPILE_TEST
++ depends on I2C
++ help
++ Say Y here to add support for the features implemented by the
++ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
++ To compile this driver as a module, choose M here; the module will be
++ called turris-omnia-mcu.
++
++endif # CZNIC_PLATFORMS
+--- /dev/null
++++ b/drivers/platform/cznic/Makefile
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris-omnia-mcu.o
++turris-omnia-mcu-y := turris-omnia-mcu-base.o
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -0,0 +1,393 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bits.h>
++#include <linux/device.h>
++#include <linux/errno.h>
++#include <linux/hex.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/sysfs.h>
++#include <linux/types.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define OMNIA_FW_VERSION_LEN 20
++#define OMNIA_FW_VERSION_HEX_LEN (2 * OMNIA_FW_VERSION_LEN + 1)
++#define OMNIA_BOARD_INFO_LEN 16
++
++int omnia_cmd_write_read(const struct i2c_client *client,
++ void *cmd, unsigned int cmd_len,
++ void *reply, unsigned int reply_len)
++{
++ struct i2c_msg msgs[2];
++ int ret, num;
++
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = cmd_len;
++ msgs[0].buf = cmd;
++ num = 1;
++
++ if (reply_len) {
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = reply_len;
++ msgs[1].buf = reply;
++ num++;
++ }
++
++ ret = i2c_transfer(client->adapter, msgs, num);
++ if (ret < 0)
++ return ret;
++ if (ret != num)
++ return -EIO;
++
++ return 0;
++}
++
++static int omnia_get_version_hash(struct omnia_mcu *mcu, bool bootloader,
++ char version[static OMNIA_FW_VERSION_HEX_LEN])
++{
++ u8 reply[OMNIA_FW_VERSION_LEN];
++ char *p;
++ int err;
++
++ err = omnia_cmd_read(mcu->client,
++ bootloader ? OMNIA_CMD_GET_FW_VERSION_BOOT
++ : OMNIA_CMD_GET_FW_VERSION_APP,
++ reply, sizeof(reply));
++ if (err)
++ return err;
++
++ p = bin2hex(version, reply, OMNIA_FW_VERSION_LEN);
++ *p = '\0';
++
++ return 0;
++}
++
++static ssize_t fw_version_hash_show(struct device *dev, char *buf,
++ bool bootloader)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ char version[OMNIA_FW_VERSION_HEX_LEN];
++ int err;
++
++ err = omnia_get_version_hash(mcu, bootloader, version);
++ if (err)
++ return err;
++
++ return sysfs_emit(buf, "%s\n", version);
++}
++
++static ssize_t fw_version_hash_application_show(struct device *dev,
++ struct device_attribute *a,
++ char *buf)
++{
++ return fw_version_hash_show(dev, buf, false);
++}
++static DEVICE_ATTR_RO(fw_version_hash_application);
++
++static ssize_t fw_version_hash_bootloader_show(struct device *dev,
++ struct device_attribute *a,
++ char *buf)
++{
++ return fw_version_hash_show(dev, buf, true);
++}
++static DEVICE_ATTR_RO(fw_version_hash_bootloader);
++
++static ssize_t fw_features_show(struct device *dev, struct device_attribute *a,
++ char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "0x%x\n", mcu->features);
++}
++static DEVICE_ATTR_RO(fw_features);
++
++static ssize_t mcu_type_show(struct device *dev, struct device_attribute *a,
++ char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%s\n", mcu->type);
++}
++static DEVICE_ATTR_RO(mcu_type);
++
++static ssize_t reset_selector_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ u8 reply;
++ int err;
++
++ err = omnia_cmd_read_u8(to_i2c_client(dev), OMNIA_CMD_GET_RESET,
++ &reply);
++ if (err)
++ return err;
++
++ return sysfs_emit(buf, "%d\n", reply);
++}
++static DEVICE_ATTR_RO(reset_selector);
++
++static ssize_t serial_number_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%016llX\n", mcu->board_serial_number);
++}
++static DEVICE_ATTR_RO(serial_number);
++
++static ssize_t first_mac_address_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%pM\n", mcu->board_first_mac);
++}
++static DEVICE_ATTR_RO(first_mac_address);
++
++static ssize_t board_revision_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%u\n", mcu->board_revision);
++}
++static DEVICE_ATTR_RO(board_revision);
++
++static struct attribute *omnia_mcu_base_attrs[] = {
++ &dev_attr_fw_version_hash_application.attr,
++ &dev_attr_fw_version_hash_bootloader.attr,
++ &dev_attr_fw_features.attr,
++ &dev_attr_mcu_type.attr,
++ &dev_attr_reset_selector.attr,
++ &dev_attr_serial_number.attr,
++ &dev_attr_first_mac_address.attr,
++ &dev_attr_board_revision.attr,
++ NULL
++};
++
++static umode_t omnia_mcu_base_attrs_visible(struct kobject *kobj,
++ struct attribute *a, int n)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ if ((a == &dev_attr_serial_number.attr ||
++ a == &dev_attr_first_mac_address.attr ||
++ a == &dev_attr_board_revision.attr) &&
++ !(mcu->features & OMNIA_FEAT_BOARD_INFO))
++ return 0;
++
++ return a->mode;
++}
++
++static const struct attribute_group omnia_mcu_base_group = {
++ .attrs = omnia_mcu_base_attrs,
++ .is_visible = omnia_mcu_base_attrs_visible,
++};
++
++static const struct attribute_group *omnia_mcu_groups[] = {
++ &omnia_mcu_base_group,
++ NULL
++};
++
++static void omnia_mcu_print_version_hash(struct omnia_mcu *mcu, bool bootloader)
++{
++ const char *type = bootloader ? "bootloader" : "application";
++ struct device *dev = &mcu->client->dev;
++ char version[OMNIA_FW_VERSION_HEX_LEN];
++ int err;
++
++ err = omnia_get_version_hash(mcu, bootloader, version);
++ if (err) {
++ dev_err(dev, "Cannot read MCU %s firmware version: %d\n",
++ type, err);
++ return;
++ }
++
++ dev_info(dev, "MCU %s firmware version hash: %s\n", type, version);
++}
++
++static const char *omnia_status_to_mcu_type(u16 status)
++{
++ switch (status & OMNIA_STS_MCU_TYPE_MASK) {
++ case OMNIA_STS_MCU_TYPE_STM32:
++ return "STM32";
++ case OMNIA_STS_MCU_TYPE_GD32:
++ return "GD32";
++ case OMNIA_STS_MCU_TYPE_MKL:
++ return "MKL";
++ default:
++ return "unknown";
++ }
++}
++
++static void omnia_info_missing_feature(struct device *dev, const char *feature)
++{
++ dev_info(dev,
++ "Your board's MCU firmware does not support the %s feature.\n",
++ feature);
++}
++
++static int omnia_mcu_read_features(struct omnia_mcu *mcu)
++{
++ static const struct {
++ u16 mask;
++ const char *name;
++ } features[] = {
++#define _DEF_FEAT(_n, _m) { OMNIA_FEAT_ ## _n, _m }
++ _DEF_FEAT(EXT_CMDS, "extended control and status"),
++ _DEF_FEAT(WDT_PING, "watchdog pinging"),
++ _DEF_FEAT(LED_STATE_EXT_MASK, "peripheral LED pins reading"),
++ _DEF_FEAT(NEW_INT_API, "new interrupt API"),
++ _DEF_FEAT(POWEROFF_WAKEUP, "poweroff and wakeup"),
++ _DEF_FEAT(TRNG, "true random number generator"),
++#undef _DEF_FEAT
++ };
++ struct i2c_client *client = mcu->client;
++ struct device *dev = &client->dev;
++ bool suggest_fw_upgrade = false;
++ u16 status;
++ int err;
++
++ /* status word holds MCU type, which we need below */
++ err = omnia_cmd_read_u16(client, OMNIA_CMD_GET_STATUS_WORD, &status);
++ if (err)
++ return err;
++
++ /*
++ * Check whether MCU firmware supports the OMNIA_CMD_GET_FEATURES
++ * command.
++ */
++ if (status & OMNIA_STS_FEATURES_SUPPORTED) {
++ /* try read 32-bit features */
++ err = omnia_cmd_read_u32(client, OMNIA_CMD_GET_FEATURES,
++ &mcu->features);
++ if (err) {
++ /* try read 16-bit features */
++ u16 features16;
++
++ err = omnia_cmd_read_u16(client, OMNIA_CMD_GET_FEATURES,
++ &features16);
++ if (err)
++ return err;
++
++ mcu->features = features16;
++ } else {
++ if (mcu->features & OMNIA_FEAT_FROM_BIT_16_INVALID)
++ mcu->features &= GENMASK(15, 0);
++ }
++ } else {
++ dev_info(dev,
++ "Your board's MCU firmware does not support feature reading.\n");
++ suggest_fw_upgrade = true;
++ }
++
++ mcu->type = omnia_status_to_mcu_type(status);
++ dev_info(dev, "MCU type %s%s\n", mcu->type,
++ (mcu->features & OMNIA_FEAT_PERIPH_MCU) ?
++ ", with peripheral resets wired" : "");
++
++ omnia_mcu_print_version_hash(mcu, true);
++
++ if (mcu->features & OMNIA_FEAT_BOOTLOADER)
++ dev_warn(dev,
++ "MCU is running bootloader firmware. Was firmware upgrade interrupted?\n");
++ else
++ omnia_mcu_print_version_hash(mcu, false);
++
++ for (unsigned int i = 0; i < ARRAY_SIZE(features); i++) {
++ if (mcu->features & features[i].mask)
++ continue;
++
++ omnia_info_missing_feature(dev, features[i].name);
++ suggest_fw_upgrade = true;
++ }
++
++ if (suggest_fw_upgrade)
++ dev_info(dev,
++ "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
++
++ return 0;
++}
++
++static int omnia_mcu_read_board_info(struct omnia_mcu *mcu)
++{
++ u8 reply[1 + OMNIA_BOARD_INFO_LEN];
++ int err;
++
++ err = omnia_cmd_read(mcu->client, OMNIA_CMD_BOARD_INFO_GET, reply,
++ sizeof(reply));
++ if (err)
++ return err;
++
++ if (reply[0] != OMNIA_BOARD_INFO_LEN)
++ return -EIO;
++
++ mcu->board_serial_number = get_unaligned_le64(&reply[1]);
++
++ /* we can't use ether_addr_copy() because reply is not u16-aligned */
++ memcpy(mcu->board_first_mac, &reply[9], sizeof(mcu->board_first_mac));
++
++ mcu->board_revision = reply[15];
++
++ return 0;
++}
++
++static int omnia_mcu_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct omnia_mcu *mcu;
++ int err;
++
++ if (!client->irq)
++ return dev_err_probe(dev, -EINVAL, "IRQ resource not found\n");
++
++ mcu = devm_kzalloc(dev, sizeof(*mcu), GFP_KERNEL);
++ if (!mcu)
++ return -ENOMEM;
++
++ mcu->client = client;
++ i2c_set_clientdata(client, mcu);
++
++ err = omnia_mcu_read_features(mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot determine MCU supported features\n");
++
++ if (mcu->features & OMNIA_FEAT_BOARD_INFO) {
++ err = omnia_mcu_read_board_info(mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot read board info\n");
++ }
++
++ return 0;
++}
++
++static const struct of_device_id of_omnia_mcu_match[] = {
++ { .compatible = "cznic,turris-omnia-mcu" },
++ {}
++};
++
++static struct i2c_driver omnia_mcu_driver = {
++ .probe = omnia_mcu_probe,
++ .driver = {
++ .name = "turris-omnia-mcu",
++ .of_match_table = of_omnia_mcu_match,
++ .dev_groups = omnia_mcu_groups,
++ },
++};
++module_i2c_driver(omnia_mcu_driver);
++
++MODULE_AUTHOR("Marek Behun <kabel@kernel.org>");
++MODULE_DESCRIPTION("CZ.NIC's Turris Omnia MCU");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -0,0 +1,74 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * CZ.NIC's Turris Omnia MCU driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#ifndef __TURRIS_OMNIA_MCU_H
++#define __TURRIS_OMNIA_MCU_H
++
++#include <linux/if_ether.h>
++#include <linux/types.h>
++#include <asm/byteorder.h>
++
++struct i2c_client;
++
++struct omnia_mcu {
++ struct i2c_client *client;
++ const char *type;
++ u32 features;
++
++ /* board information */
++ u64 board_serial_number;
++ u8 board_first_mac[ETH_ALEN];
++ u8 board_revision;
++};
++
++int omnia_cmd_write_read(const struct i2c_client *client,
++ void *cmd, unsigned int cmd_len,
++ void *reply, unsigned int reply_len);
++
++static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
++ void *reply, unsigned int len)
++{
++ return omnia_cmd_write_read(client, &cmd, 1, reply, len);
++}
++
++static inline int omnia_cmd_read_u32(const struct i2c_client *client, u8 cmd,
++ u32 *dst)
++{
++ __le32 reply;
++ int err;
++
++ err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
++ if (err)
++ return err;
++
++ *dst = le32_to_cpu(reply);
++
++ return 0;
++}
++
++static inline int omnia_cmd_read_u16(const struct i2c_client *client, u8 cmd,
++ u16 *dst)
++{
++ __le16 reply;
++ int err;
++
++ err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
++ if (err)
++ return err;
++
++ *dst = le16_to_cpu(reply);
++
++ return 0;
++}
++
++static inline int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd,
++ u8 *reply)
++{
++ return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
++}
++
++#endif /* __TURRIS_OMNIA_MCU_H */
+--- /dev/null
++++ b/include/linux/turris-omnia-mcu-interface.h
+@@ -0,0 +1,249 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * CZ.NIC's Turris Omnia MCU I2C interface commands definitions
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#ifndef __TURRIS_OMNIA_MCU_INTERFACE_H
++#define __TURRIS_OMNIA_MCU_INTERFACE_H
++
++#include <linux/bitfield.h>
++#include <linux/bits.h>
++
++enum omnia_commands_e {
++ OMNIA_CMD_GET_STATUS_WORD = 0x01, /* slave sends status word back */
++ OMNIA_CMD_GENERAL_CONTROL = 0x02,
++ OMNIA_CMD_LED_MODE = 0x03, /* default/user */
++ OMNIA_CMD_LED_STATE = 0x04, /* LED on/off */
++ OMNIA_CMD_LED_COLOR = 0x05, /* LED number + RED + GREEN + BLUE */
++ OMNIA_CMD_USER_VOLTAGE = 0x06,
++ OMNIA_CMD_SET_BRIGHTNESS = 0x07,
++ OMNIA_CMD_GET_BRIGHTNESS = 0x08,
++ OMNIA_CMD_GET_RESET = 0x09,
++ OMNIA_CMD_GET_FW_VERSION_APP = 0x0A, /* 20B git hash number */
++ OMNIA_CMD_SET_WATCHDOG_STATE = 0x0B, /* 0 - disable
++ * 1 - enable / ping
++ * after boot watchdog is started
++ * with 2 minutes timeout
++ */
++
++ /* OMNIA_CMD_WATCHDOG_STATUS = 0x0C, not implemented anymore */
++
++ OMNIA_CMD_GET_WATCHDOG_STATE = 0x0D,
++ OMNIA_CMD_GET_FW_VERSION_BOOT = 0x0E, /* 20B Git hash number */
++ OMNIA_CMD_GET_FW_CHECKSUM = 0x0F, /* 4B length, 4B checksum */
++
++ /* available if FEATURES_SUPPORTED bit set in status word */
++ OMNIA_CMD_GET_FEATURES = 0x10,
++
++ /* available if EXT_CMD bit set in features */
++ OMNIA_CMD_GET_EXT_STATUS_DWORD = 0x11,
++ OMNIA_CMD_EXT_CONTROL = 0x12,
++ OMNIA_CMD_GET_EXT_CONTROL_STATUS = 0x13,
++
++ /* available if NEW_INT_API bit set in features */
++ OMNIA_CMD_GET_INT_AND_CLEAR = 0x14,
++ OMNIA_CMD_GET_INT_MASK = 0x15,
++ OMNIA_CMD_SET_INT_MASK = 0x16,
++
++ /* available if FLASHING bit set in features */
++ OMNIA_CMD_FLASH = 0x19,
++
++ /* available if WDT_PING bit set in features */
++ OMNIA_CMD_SET_WDT_TIMEOUT = 0x20,
++ OMNIA_CMD_GET_WDT_TIMELEFT = 0x21,
++
++ /* available if POWEROFF_WAKEUP bit set in features */
++ OMNIA_CMD_SET_WAKEUP = 0x22,
++ OMNIA_CMD_GET_UPTIME_AND_WAKEUP = 0x23,
++ OMNIA_CMD_POWER_OFF = 0x24,
++
++ /* available if USB_OVC_PROT_SETTING bit set in features */
++ OMNIA_CMD_SET_USB_OVC_PROT = 0x25,
++ OMNIA_CMD_GET_USB_OVC_PROT = 0x26,
++
++ /* available if TRNG bit set in features */
++ OMNIA_CMD_TRNG_COLLECT_ENTROPY = 0x28,
++
++ /* available if CRYPTO bit set in features */
++ OMNIA_CMD_CRYPTO_GET_PUBLIC_KEY = 0x29,
++ OMNIA_CMD_CRYPTO_SIGN_MESSAGE = 0x2A,
++ OMNIA_CMD_CRYPTO_COLLECT_SIGNATURE = 0x2B,
++
++ /* available if BOARD_INFO it set in features */
++ OMNIA_CMD_BOARD_INFO_GET = 0x2C,
++ OMNIA_CMD_BOARD_INFO_BURN = 0x2D,
++
++ /* available only at address 0x2b (LED-controller) */
++ /* available only if LED_GAMMA_CORRECTION bit set in features */
++ OMNIA_CMD_SET_GAMMA_CORRECTION = 0x30,
++ OMNIA_CMD_GET_GAMMA_CORRECTION = 0x31,
++
++ /* available only at address 0x2b (LED-controller) */
++ /* available only if PER_LED_CORRECTION bit set in features */
++ /* available only if FROM_BIT_16_INVALID bit NOT set in features */
++ OMNIA_CMD_SET_LED_CORRECTIONS = 0x32,
++ OMNIA_CMD_GET_LED_CORRECTIONS = 0x33,
++};
++
++enum omnia_flashing_commands_e {
++ OMNIA_FLASH_CMD_UNLOCK = 0x01,
++ OMNIA_FLASH_CMD_SIZE_AND_CSUM = 0x02,
++ OMNIA_FLASH_CMD_PROGRAM = 0x03,
++ OMNIA_FLASH_CMD_RESET = 0x04,
++};
++
++enum omnia_sts_word_e {
++ OMNIA_STS_MCU_TYPE_MASK = GENMASK(1, 0),
++ OMNIA_STS_MCU_TYPE_STM32 = FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 0),
++ OMNIA_STS_MCU_TYPE_GD32 = FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 1),
++ OMNIA_STS_MCU_TYPE_MKL = FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 2),
++ OMNIA_STS_FEATURES_SUPPORTED = BIT(2),
++ OMNIA_STS_USER_REGULATOR_NOT_SUPPORTED = BIT(3),
++ OMNIA_STS_CARD_DET = BIT(4),
++ OMNIA_STS_MSATA_IND = BIT(5),
++ OMNIA_STS_USB30_OVC = BIT(6),
++ OMNIA_STS_USB31_OVC = BIT(7),
++ OMNIA_STS_USB30_PWRON = BIT(8),
++ OMNIA_STS_USB31_PWRON = BIT(9),
++ OMNIA_STS_ENABLE_4V5 = BIT(10),
++ OMNIA_STS_BUTTON_MODE = BIT(11),
++ OMNIA_STS_BUTTON_PRESSED = BIT(12),
++ OMNIA_STS_BUTTON_COUNTER_MASK = GENMASK(15, 13),
++};
++
++enum omnia_ctl_byte_e {
++ OMNIA_CTL_LIGHT_RST = BIT(0),
++ OMNIA_CTL_HARD_RST = BIT(1),
++ /* BIT(2) is currently reserved */
++ OMNIA_CTL_USB30_PWRON = BIT(3),
++ OMNIA_CTL_USB31_PWRON = BIT(4),
++ OMNIA_CTL_ENABLE_4V5 = BIT(5),
++ OMNIA_CTL_BUTTON_MODE = BIT(6),
++ OMNIA_CTL_BOOTLOADER = BIT(7),
++};
++
++enum omnia_features_e {
++ OMNIA_FEAT_PERIPH_MCU = BIT(0),
++ OMNIA_FEAT_EXT_CMDS = BIT(1),
++ OMNIA_FEAT_WDT_PING = BIT(2),
++ OMNIA_FEAT_LED_STATE_EXT_MASK = GENMASK(4, 3),
++ OMNIA_FEAT_LED_STATE_EXT = FIELD_PREP_CONST(OMNIA_FEAT_LED_STATE_EXT_MASK, 1),
++ OMNIA_FEAT_LED_STATE_EXT_V32 = FIELD_PREP_CONST(OMNIA_FEAT_LED_STATE_EXT_MASK, 2),
++ OMNIA_FEAT_LED_GAMMA_CORRECTION = BIT(5),
++ OMNIA_FEAT_NEW_INT_API = BIT(6),
++ OMNIA_FEAT_BOOTLOADER = BIT(7),
++ OMNIA_FEAT_FLASHING = BIT(8),
++ OMNIA_FEAT_NEW_MESSAGE_API = BIT(9),
++ OMNIA_FEAT_BRIGHTNESS_INT = BIT(10),
++ OMNIA_FEAT_POWEROFF_WAKEUP = BIT(11),
++ OMNIA_FEAT_CAN_OLD_MESSAGE_API = BIT(12),
++ OMNIA_FEAT_TRNG = BIT(13),
++ OMNIA_FEAT_CRYPTO = BIT(14),
++ OMNIA_FEAT_BOARD_INFO = BIT(15),
++
++ /*
++ * Orginally the features command replied only 16 bits. If more were
++ * read, either the I2C transaction failed or 0xff bytes were sent.
++ * Therefore to consider bits 16 - 31 valid, one bit (20) was reserved
++ * to be zero.
++ */
++
++ /* Bits 16 - 19 correspond to bits 0 - 3 of status word */
++ OMNIA_FEAT_MCU_TYPE_MASK = GENMASK(17, 16),
++ OMNIA_FEAT_MCU_TYPE_STM32 = FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 0),
++ OMNIA_FEAT_MCU_TYPE_GD32 = FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 1),
++ OMNIA_FEAT_MCU_TYPE_MKL = FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 2),
++ OMNIA_FEAT_FEATURES_SUPPORTED = BIT(18),
++ OMNIA_FEAT_USER_REGULATOR_NOT_SUPPORTED = BIT(19),
++
++ /* must not be set */
++ OMNIA_FEAT_FROM_BIT_16_INVALID = BIT(20),
++
++ OMNIA_FEAT_PER_LED_CORRECTION = BIT(21),
++ OMNIA_FEAT_USB_OVC_PROT_SETTING = BIT(22),
++};
++
++enum omnia_ext_sts_dword_e {
++ OMNIA_EXT_STS_SFP_nDET = BIT(0),
++ OMNIA_EXT_STS_LED_STATES_MASK = GENMASK(31, 12),
++ OMNIA_EXT_STS_WLAN0_MSATA_LED = BIT(12),
++ OMNIA_EXT_STS_WLAN1_LED = BIT(13),
++ OMNIA_EXT_STS_WLAN2_LED = BIT(14),
++ OMNIA_EXT_STS_WPAN0_LED = BIT(15),
++ OMNIA_EXT_STS_WPAN1_LED = BIT(16),
++ OMNIA_EXT_STS_WPAN2_LED = BIT(17),
++ OMNIA_EXT_STS_WAN_LED0 = BIT(18),
++ OMNIA_EXT_STS_WAN_LED1 = BIT(19),
++ OMNIA_EXT_STS_LAN0_LED0 = BIT(20),
++ OMNIA_EXT_STS_LAN0_LED1 = BIT(21),
++ OMNIA_EXT_STS_LAN1_LED0 = BIT(22),
++ OMNIA_EXT_STS_LAN1_LED1 = BIT(23),
++ OMNIA_EXT_STS_LAN2_LED0 = BIT(24),
++ OMNIA_EXT_STS_LAN2_LED1 = BIT(25),
++ OMNIA_EXT_STS_LAN3_LED0 = BIT(26),
++ OMNIA_EXT_STS_LAN3_LED1 = BIT(27),
++ OMNIA_EXT_STS_LAN4_LED0 = BIT(28),
++ OMNIA_EXT_STS_LAN4_LED1 = BIT(29),
++ OMNIA_EXT_STS_LAN5_LED0 = BIT(30),
++ OMNIA_EXT_STS_LAN5_LED1 = BIT(31),
++};
++
++enum omnia_ext_ctl_e {
++ OMNIA_EXT_CTL_nRES_MMC = BIT(0),
++ OMNIA_EXT_CTL_nRES_LAN = BIT(1),
++ OMNIA_EXT_CTL_nRES_PHY = BIT(2),
++ OMNIA_EXT_CTL_nPERST0 = BIT(3),
++ OMNIA_EXT_CTL_nPERST1 = BIT(4),
++ OMNIA_EXT_CTL_nPERST2 = BIT(5),
++ OMNIA_EXT_CTL_PHY_SFP = BIT(6),
++ OMNIA_EXT_CTL_PHY_SFP_AUTO = BIT(7),
++ OMNIA_EXT_CTL_nVHV_CTRL = BIT(8),
++};
++
++enum omnia_int_e {
++ OMNIA_INT_CARD_DET = BIT(0),
++ OMNIA_INT_MSATA_IND = BIT(1),
++ OMNIA_INT_USB30_OVC = BIT(2),
++ OMNIA_INT_USB31_OVC = BIT(3),
++ OMNIA_INT_BUTTON_PRESSED = BIT(4),
++ OMNIA_INT_SFP_nDET = BIT(5),
++ OMNIA_INT_BRIGHTNESS_CHANGED = BIT(6),
++ OMNIA_INT_TRNG = BIT(7),
++ OMNIA_INT_MESSAGE_SIGNED = BIT(8),
++
++ OMNIA_INT_LED_STATES_MASK = GENMASK(31, 12),
++ OMNIA_INT_WLAN0_MSATA_LED = BIT(12),
++ OMNIA_INT_WLAN1_LED = BIT(13),
++ OMNIA_INT_WLAN2_LED = BIT(14),
++ OMNIA_INT_WPAN0_LED = BIT(15),
++ OMNIA_INT_WPAN1_LED = BIT(16),
++ OMNIA_INT_WPAN2_LED = BIT(17),
++ OMNIA_INT_WAN_LED0 = BIT(18),
++ OMNIA_INT_WAN_LED1 = BIT(19),
++ OMNIA_INT_LAN0_LED0 = BIT(20),
++ OMNIA_INT_LAN0_LED1 = BIT(21),
++ OMNIA_INT_LAN1_LED0 = BIT(22),
++ OMNIA_INT_LAN1_LED1 = BIT(23),
++ OMNIA_INT_LAN2_LED0 = BIT(24),
++ OMNIA_INT_LAN2_LED1 = BIT(25),
++ OMNIA_INT_LAN3_LED0 = BIT(26),
++ OMNIA_INT_LAN3_LED1 = BIT(27),
++ OMNIA_INT_LAN4_LED0 = BIT(28),
++ OMNIA_INT_LAN4_LED1 = BIT(29),
++ OMNIA_INT_LAN5_LED0 = BIT(30),
++ OMNIA_INT_LAN5_LED1 = BIT(31),
++};
++
++enum omnia_cmd_poweroff_e {
++ OMNIA_CMD_POWER_OFF_POWERON_BUTTON = BIT(0),
++ OMNIA_CMD_POWER_OFF_MAGIC = 0xdead,
++};
++
++enum omnia_cmd_usb_ovc_prot_e {
++ OMNIA_CMD_xET_USB_OVC_PROT_PORT_MASK = GENMASK(3, 0),
++ OMNIA_CMD_xET_USB_OVC_PROT_ENABLE = BIT(4),
++};
++
++#endif /* __TURRIS_OMNIA_MCU_INTERFACE_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch b/target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
new file mode 100644
index 0000000000..3309a773a9
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
@@ -0,0 +1,1311 @@
+From 7f4f2744f9788312e12940b516b51a0a466b137e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:05 +0200
+Subject: [PATCH 03/11] platform: cznic: turris-omnia-mcu: Add support for MCU
+ connected GPIOs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for GPIOs connected to the MCU on the Turris Omnia board.
+
+This includes:
+- front button pin
+- enable pins for USB regulators
+- MiniPCIe / mSATA card presence pins in MiniPCIe port 0
+- LED output pins from WAN ethernet PHY, LAN switch and MiniPCIe ports
+- on board revisions 32+ also various peripheral resets and another
+ voltage regulator enable pin
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-4-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../sysfs-bus-i2c-devices-turris-omnia-mcu | 16 +
+ drivers/platform/cznic/Kconfig | 15 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 3 +-
+ .../platform/cznic/turris-omnia-mcu-gpio.c | 1094 +++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 68 +
+ 6 files changed, 1196 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-gpio.c
+
+--- a/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
++++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+@@ -22,6 +22,22 @@ Description: (RO) Contains device first
+
+ Format: %pM.
+
++What: /sys/bus/i2c/devices/<mcu_device>/front_button_mode
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RW) The front button on the Turris Omnia router can be
++ configured either to change the intensity of all the LEDs on the
++ front panel, or to send the press event to the CPU as an
++ interrupt.
++
++ This file switches between these two modes:
++ - "mcu" makes the button press event be handled by the MCU to
++ change the LEDs panel intensity.
++ - "cpu" makes the button press event be handled by the CPU.
++
++ Format: %s.
++
+ What: /sys/bus/i2c/devices/<mcu_device>/fw_features
+ Date: September 2024
+ KernelVersion: 6.11
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -16,9 +16,24 @@ config TURRIS_OMNIA_MCU
+ tristate "Turris Omnia MCU driver"
+ depends on MACH_ARMADA_38X || COMPILE_TEST
+ depends on I2C
++ select GPIOLIB
++ select GPIOLIB_IRQCHIP
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
++ The features include:
++ - GPIO pins
++ - to get front button press events (the front button can be
++ configured either to generate press events to the CPU or to change
++ front LEDs panel brightness)
++ - to enable / disable USB port voltage regulators and to detect
++ USB overcurrent
++ - to detect MiniPCIe / mSATA card presence in MiniPCIe port 0
++ - to configure resets of various peripherals on board revisions 32+
++ - to enable / disable the VHV voltage regulator to the SOC in order
++ to be able to program SOC's OTP on board revisions 32+
++ - to get input from the LED output pins of the WAN ethernet PHY, LAN
++ switch and MiniPCIe ports
+ To compile this driver as a module, choose M here; the module will be
+ called turris-omnia-mcu.
+
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -2,3 +2,4 @@
+
+ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris-omnia-mcu.o
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
++turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -196,6 +196,7 @@ static const struct attribute_group omni
+
+ static const struct attribute_group *omnia_mcu_groups[] = {
+ &omnia_mcu_base_group,
++ &omnia_mcu_gpio_group,
+ NULL
+ };
+
+@@ -370,7 +371,7 @@ static int omnia_mcu_probe(struct i2c_cl
+ "Cannot read board info\n");
+ }
+
+- return 0;
++ return omnia_mcu_register_gpiochip(mcu);
+ }
+
+ static const struct of_device_id of_omnia_mcu_match[] = {
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-gpio.c
+@@ -0,0 +1,1094 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU GPIO and IRQ driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/bitops.h>
++#include <linux/bug.h>
++#include <linux/cleanup.h>
++#include <linux/device.h>
++#include <linux/devm-helpers.h>
++#include <linux/errno.h>
++#include <linux/gpio/driver.h>
++#include <linux/i2c.h>
++#include <linux/interrupt.h>
++#include <linux/mutex.h>
++#include <linux/sysfs.h>
++#include <linux/types.h>
++#include <linux/workqueue.h>
++#include <asm/unaligned.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define OMNIA_CMD_INT_ARG_LEN 8
++#define FRONT_BUTTON_RELEASE_DELAY_MS 50
++
++static const char * const omnia_mcu_gpio_templates[64] = {
++ /* GPIOs with value read from the 16-bit wide status */
++ [4] = "MiniPCIe0 Card Detect",
++ [5] = "MiniPCIe0 mSATA Indicator",
++ [6] = "Front USB3 port over-current",
++ [7] = "Rear USB3 port over-current",
++ [8] = "Front USB3 port power",
++ [9] = "Rear USB3 port power",
++ [12] = "Front Button",
++
++ /* GPIOs with value read from the 32-bit wide extended status */
++ [16] = "SFP nDET",
++ [28] = "MiniPCIe0 LED",
++ [29] = "MiniPCIe1 LED",
++ [30] = "MiniPCIe2 LED",
++ [31] = "MiniPCIe0 PAN LED",
++ [32] = "MiniPCIe1 PAN LED",
++ [33] = "MiniPCIe2 PAN LED",
++ [34] = "WAN PHY LED0",
++ [35] = "WAN PHY LED1",
++ [36] = "LAN switch p0 LED0",
++ [37] = "LAN switch p0 LED1",
++ [38] = "LAN switch p1 LED0",
++ [39] = "LAN switch p1 LED1",
++ [40] = "LAN switch p2 LED0",
++ [41] = "LAN switch p2 LED1",
++ [42] = "LAN switch p3 LED0",
++ [43] = "LAN switch p3 LED1",
++ [44] = "LAN switch p4 LED0",
++ [45] = "LAN switch p4 LED1",
++ [46] = "LAN switch p5 LED0",
++ [47] = "LAN switch p5 LED1",
++
++ /* GPIOs with value read from the 16-bit wide extended control status */
++ [48] = "eMMC nRESET",
++ [49] = "LAN switch nRESET",
++ [50] = "WAN PHY nRESET",
++ [51] = "MiniPCIe0 nPERST",
++ [52] = "MiniPCIe1 nPERST",
++ [53] = "MiniPCIe2 nPERST",
++ [54] = "WAN PHY SFP mux",
++ [56] = "VHV power disable",
++};
++
++struct omnia_gpio {
++ u8 cmd;
++ u8 ctl_cmd;
++ u8 bit;
++ u8 ctl_bit;
++ u8 int_bit;
++ u16 feat;
++ u16 feat_mask;
++};
++
++#define OMNIA_GPIO_INVALID_INT_BIT 0xff
++
++#define _DEF_GPIO(_cmd, _ctl_cmd, _bit, _ctl_bit, _int_bit, _feat, _feat_mask) \
++ { \
++ .cmd = _cmd, \
++ .ctl_cmd = _ctl_cmd, \
++ .bit = _bit, \
++ .ctl_bit = _ctl_bit, \
++ .int_bit = (_int_bit) < 0 ? OMNIA_GPIO_INVALID_INT_BIT \
++ : (_int_bit), \
++ .feat = _feat, \
++ .feat_mask = _feat_mask, \
++ }
++
++#define _DEF_GPIO_STS(_name) \
++ _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, 0, __bf_shf(OMNIA_STS_ ## _name), \
++ 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
++
++#define _DEF_GPIO_CTL(_name) \
++ _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, OMNIA_CMD_GENERAL_CONTROL, \
++ __bf_shf(OMNIA_STS_ ## _name), __bf_shf(OMNIA_CTL_ ## _name), \
++ -1, 0, 0)
++
++#define _DEF_GPIO_EXT_STS(_name, _feat) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
++ __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
++ __bf_shf(OMNIA_INT_ ## _name), \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
++
++#define _DEF_GPIO_EXT_STS_LED(_name, _ledext) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
++ __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
++ __bf_shf(OMNIA_INT_ ## _name), \
++ OMNIA_FEAT_LED_STATE_ ## _ledext, \
++ OMNIA_FEAT_LED_STATE_EXT_MASK)
++
++#define _DEF_GPIO_EXT_STS_LEDALL(_name) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
++ __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
++ __bf_shf(OMNIA_INT_ ## _name), \
++ OMNIA_FEAT_LED_STATE_EXT_MASK, 0)
++
++#define _DEF_GPIO_EXT_CTL(_name, _feat) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_CONTROL_STATUS, OMNIA_CMD_EXT_CONTROL, \
++ __bf_shf(OMNIA_EXT_CTL_ ## _name), \
++ __bf_shf(OMNIA_EXT_CTL_ ## _name), -1, \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
++
++#define _DEF_INT(_name) \
++ _DEF_GPIO(0, 0, 0, 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
++
++static inline bool is_int_bit_valid(const struct omnia_gpio *gpio)
++{
++ return gpio->int_bit != OMNIA_GPIO_INVALID_INT_BIT;
++}
++
++static const struct omnia_gpio omnia_gpios[64] = {
++ /* GPIOs with value read from the 16-bit wide status */
++ [4] = _DEF_GPIO_STS(CARD_DET),
++ [5] = _DEF_GPIO_STS(MSATA_IND),
++ [6] = _DEF_GPIO_STS(USB30_OVC),
++ [7] = _DEF_GPIO_STS(USB31_OVC),
++ [8] = _DEF_GPIO_CTL(USB30_PWRON),
++ [9] = _DEF_GPIO_CTL(USB31_PWRON),
++
++ /* brightness changed interrupt, no GPIO */
++ [11] = _DEF_INT(BRIGHTNESS_CHANGED),
++
++ [12] = _DEF_GPIO_STS(BUTTON_PRESSED),
++
++ /* TRNG interrupt, no GPIO */
++ [13] = _DEF_INT(TRNG),
++
++ /* MESSAGE_SIGNED interrupt, no GPIO */
++ [14] = _DEF_INT(MESSAGE_SIGNED),
++
++ /* GPIOs with value read from the 32-bit wide extended status */
++ [16] = _DEF_GPIO_EXT_STS(SFP_nDET, PERIPH_MCU),
++ [28] = _DEF_GPIO_EXT_STS_LEDALL(WLAN0_MSATA_LED),
++ [29] = _DEF_GPIO_EXT_STS_LEDALL(WLAN1_LED),
++ [30] = _DEF_GPIO_EXT_STS_LEDALL(WLAN2_LED),
++ [31] = _DEF_GPIO_EXT_STS_LED(WPAN0_LED, EXT),
++ [32] = _DEF_GPIO_EXT_STS_LED(WPAN1_LED, EXT),
++ [33] = _DEF_GPIO_EXT_STS_LED(WPAN2_LED, EXT),
++ [34] = _DEF_GPIO_EXT_STS_LEDALL(WAN_LED0),
++ [35] = _DEF_GPIO_EXT_STS_LED(WAN_LED1, EXT_V32),
++ [36] = _DEF_GPIO_EXT_STS_LEDALL(LAN0_LED0),
++ [37] = _DEF_GPIO_EXT_STS_LEDALL(LAN0_LED1),
++ [38] = _DEF_GPIO_EXT_STS_LEDALL(LAN1_LED0),
++ [39] = _DEF_GPIO_EXT_STS_LEDALL(LAN1_LED1),
++ [40] = _DEF_GPIO_EXT_STS_LEDALL(LAN2_LED0),
++ [41] = _DEF_GPIO_EXT_STS_LEDALL(LAN2_LED1),
++ [42] = _DEF_GPIO_EXT_STS_LEDALL(LAN3_LED0),
++ [43] = _DEF_GPIO_EXT_STS_LEDALL(LAN3_LED1),
++ [44] = _DEF_GPIO_EXT_STS_LEDALL(LAN4_LED0),
++ [45] = _DEF_GPIO_EXT_STS_LEDALL(LAN4_LED1),
++ [46] = _DEF_GPIO_EXT_STS_LEDALL(LAN5_LED0),
++ [47] = _DEF_GPIO_EXT_STS_LEDALL(LAN5_LED1),
++
++ /* GPIOs with value read from the 16-bit wide extended control status */
++ [48] = _DEF_GPIO_EXT_CTL(nRES_MMC, PERIPH_MCU),
++ [49] = _DEF_GPIO_EXT_CTL(nRES_LAN, PERIPH_MCU),
++ [50] = _DEF_GPIO_EXT_CTL(nRES_PHY, PERIPH_MCU),
++ [51] = _DEF_GPIO_EXT_CTL(nPERST0, PERIPH_MCU),
++ [52] = _DEF_GPIO_EXT_CTL(nPERST1, PERIPH_MCU),
++ [53] = _DEF_GPIO_EXT_CTL(nPERST2, PERIPH_MCU),
++ [54] = _DEF_GPIO_EXT_CTL(PHY_SFP, PERIPH_MCU),
++ [56] = _DEF_GPIO_EXT_CTL(nVHV_CTRL, PERIPH_MCU),
++};
++
++/* mapping from interrupts to indexes of GPIOs in the omnia_gpios array */
++static const u8 omnia_int_to_gpio_idx[32] = {
++ [__bf_shf(OMNIA_INT_CARD_DET)] = 4,
++ [__bf_shf(OMNIA_INT_MSATA_IND)] = 5,
++ [__bf_shf(OMNIA_INT_USB30_OVC)] = 6,
++ [__bf_shf(OMNIA_INT_USB31_OVC)] = 7,
++ [__bf_shf(OMNIA_INT_BUTTON_PRESSED)] = 12,
++ [__bf_shf(OMNIA_INT_TRNG)] = 13,
++ [__bf_shf(OMNIA_INT_MESSAGE_SIGNED)] = 14,
++ [__bf_shf(OMNIA_INT_SFP_nDET)] = 16,
++ [__bf_shf(OMNIA_INT_BRIGHTNESS_CHANGED)] = 11,
++ [__bf_shf(OMNIA_INT_WLAN0_MSATA_LED)] = 28,
++ [__bf_shf(OMNIA_INT_WLAN1_LED)] = 29,
++ [__bf_shf(OMNIA_INT_WLAN2_LED)] = 30,
++ [__bf_shf(OMNIA_INT_WPAN0_LED)] = 31,
++ [__bf_shf(OMNIA_INT_WPAN1_LED)] = 32,
++ [__bf_shf(OMNIA_INT_WPAN2_LED)] = 33,
++ [__bf_shf(OMNIA_INT_WAN_LED0)] = 34,
++ [__bf_shf(OMNIA_INT_WAN_LED1)] = 35,
++ [__bf_shf(OMNIA_INT_LAN0_LED0)] = 36,
++ [__bf_shf(OMNIA_INT_LAN0_LED1)] = 37,
++ [__bf_shf(OMNIA_INT_LAN1_LED0)] = 38,
++ [__bf_shf(OMNIA_INT_LAN1_LED1)] = 39,
++ [__bf_shf(OMNIA_INT_LAN2_LED0)] = 40,
++ [__bf_shf(OMNIA_INT_LAN2_LED1)] = 41,
++ [__bf_shf(OMNIA_INT_LAN3_LED0)] = 42,
++ [__bf_shf(OMNIA_INT_LAN3_LED1)] = 43,
++ [__bf_shf(OMNIA_INT_LAN4_LED0)] = 44,
++ [__bf_shf(OMNIA_INT_LAN4_LED1)] = 45,
++ [__bf_shf(OMNIA_INT_LAN5_LED0)] = 46,
++ [__bf_shf(OMNIA_INT_LAN5_LED1)] = 47,
++};
++
++/* index of PHY_SFP GPIO in the omnia_gpios array */
++#define OMNIA_GPIO_PHY_SFP_OFFSET 54
++
++static int omnia_ctl_cmd_locked(struct omnia_mcu *mcu, u8 cmd, u16 val, u16 mask)
++{
++ unsigned int len;
++ u8 buf[5];
++
++ buf[0] = cmd;
++
++ switch (cmd) {
++ case OMNIA_CMD_GENERAL_CONTROL:
++ buf[1] = val;
++ buf[2] = mask;
++ len = 3;
++ break;
++
++ case OMNIA_CMD_EXT_CONTROL:
++ put_unaligned_le16(val, &buf[1]);
++ put_unaligned_le16(mask, &buf[3]);
++ len = 5;
++ break;
++
++ default:
++ BUG();
++ }
++
++ return omnia_cmd_write(mcu->client, buf, len);
++}
++
++static int omnia_ctl_cmd(struct omnia_mcu *mcu, u8 cmd, u16 val, u16 mask)
++{
++ guard(mutex)(&mcu->lock);
++
++ return omnia_ctl_cmd_locked(mcu, cmd, val, mask);
++}
++
++static int omnia_gpio_request(struct gpio_chip *gc, unsigned int offset)
++{
++ if (!omnia_gpios[offset].cmd)
++ return -EINVAL;
++
++ return 0;
++}
++
++static int omnia_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ if (offset == OMNIA_GPIO_PHY_SFP_OFFSET) {
++ int val;
++
++ scoped_guard(mutex, &mcu->lock) {
++ val = omnia_cmd_read_bit(mcu->client,
++ OMNIA_CMD_GET_EXT_CONTROL_STATUS,
++ OMNIA_EXT_CTL_PHY_SFP_AUTO);
++ if (val < 0)
++ return val;
++ }
++
++ if (val)
++ return GPIO_LINE_DIRECTION_IN;
++
++ return GPIO_LINE_DIRECTION_OUT;
++ }
++
++ if (omnia_gpios[offset].ctl_cmd)
++ return GPIO_LINE_DIRECTION_OUT;
++
++ return GPIO_LINE_DIRECTION_IN;
++}
++
++static int omnia_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ if (offset == OMNIA_GPIO_PHY_SFP_OFFSET)
++ return omnia_ctl_cmd(mcu, OMNIA_CMD_EXT_CONTROL,
++ OMNIA_EXT_CTL_PHY_SFP_AUTO,
++ OMNIA_EXT_CTL_PHY_SFP_AUTO);
++
++ if (gpio->ctl_cmd)
++ return -ENOTSUPP;
++
++ return 0;
++}
++
++static int omnia_gpio_direction_output(struct gpio_chip *gc,
++ unsigned int offset, int value)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ u16 val, mask;
++
++ if (!gpio->ctl_cmd)
++ return -ENOTSUPP;
++
++ mask = BIT(gpio->ctl_bit);
++ val = value ? mask : 0;
++
++ if (offset == OMNIA_GPIO_PHY_SFP_OFFSET)
++ mask |= OMNIA_EXT_CTL_PHY_SFP_AUTO;
++
++ return omnia_ctl_cmd(mcu, gpio->ctl_cmd, val, mask);
++}
++
++static int omnia_gpio_get(struct gpio_chip *gc, unsigned int offset)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ /*
++ * If firmware does not support the new interrupt API, we are informed
++ * of every change of the status word by an interrupt from MCU and save
++ * its value in the interrupt service routine. Simply return the saved
++ * value.
++ */
++ if (gpio->cmd == OMNIA_CMD_GET_STATUS_WORD &&
++ !(mcu->features & OMNIA_FEAT_NEW_INT_API))
++ return test_bit(gpio->bit, &mcu->last_status);
++
++ guard(mutex)(&mcu->lock);
++
++ /*
++ * If firmware does support the new interrupt API, we may have cached
++ * the value of a GPIO in the interrupt service routine. If not, read
++ * the relevant bit now.
++ */
++ if (is_int_bit_valid(gpio) && test_bit(gpio->int_bit, &mcu->is_cached))
++ return test_bit(gpio->int_bit, &mcu->cached);
++
++ return omnia_cmd_read_bit(mcu->client, gpio->cmd, BIT(gpio->bit));
++}
++
++static unsigned long *
++_relevant_field_for_sts_cmd(u8 cmd, unsigned long *sts, unsigned long *ext_sts,
++ unsigned long *ext_ctl)
++{
++ switch (cmd) {
++ case OMNIA_CMD_GET_STATUS_WORD:
++ return sts;
++ case OMNIA_CMD_GET_EXT_STATUS_DWORD:
++ return ext_sts;
++ case OMNIA_CMD_GET_EXT_CONTROL_STATUS:
++ return ext_ctl;
++ default:
++ return NULL;
++ }
++}
++
++static int omnia_gpio_get_multiple(struct gpio_chip *gc, unsigned long *mask,
++ unsigned long *bits)
++{
++ unsigned long sts = 0, ext_sts = 0, ext_ctl = 0, *field;
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ struct i2c_client *client = mcu->client;
++ unsigned int i;
++ int err;
++
++ /* determine which bits to read from the 3 possible commands */
++ for_each_set_bit(i, mask, ARRAY_SIZE(omnia_gpios)) {
++ field = _relevant_field_for_sts_cmd(omnia_gpios[i].cmd,
++ &sts, &ext_sts, &ext_ctl);
++ if (!field)
++ continue;
++
++ __set_bit(omnia_gpios[i].bit, field);
++ }
++
++ guard(mutex)(&mcu->lock);
++
++ if (mcu->features & OMNIA_FEAT_NEW_INT_API) {
++ /* read relevant bits from status */
++ err = omnia_cmd_read_bits(client, OMNIA_CMD_GET_STATUS_WORD,
++ sts, &sts);
++ if (err)
++ return err;
++ } else {
++ /*
++ * Use status word value cached in the interrupt service routine
++ * if firmware does not support the new interrupt API.
++ */
++ sts = mcu->last_status;
++ }
++
++ /* read relevant bits from extended status */
++ err = omnia_cmd_read_bits(client, OMNIA_CMD_GET_EXT_STATUS_DWORD,
++ ext_sts, &ext_sts);
++ if (err)
++ return err;
++
++ /* read relevant bits from extended control */
++ err = omnia_cmd_read_bits(client, OMNIA_CMD_GET_EXT_CONTROL_STATUS,
++ ext_ctl, &ext_ctl);
++ if (err)
++ return err;
++
++ /* assign relevant bits in result */
++ for_each_set_bit(i, mask, ARRAY_SIZE(omnia_gpios)) {
++ field = _relevant_field_for_sts_cmd(omnia_gpios[i].cmd,
++ &sts, &ext_sts, &ext_ctl);
++ if (!field)
++ continue;
++
++ __assign_bit(i, bits, test_bit(omnia_gpios[i].bit, field));
++ }
++
++ return 0;
++}
++
++static void omnia_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ u16 val, mask;
++
++ if (!gpio->ctl_cmd)
++ return;
++
++ mask = BIT(gpio->ctl_bit);
++ val = value ? mask : 0;
++
++ omnia_ctl_cmd(mcu, gpio->ctl_cmd, val, mask);
++}
++
++static void omnia_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
++ unsigned long *bits)
++{
++ unsigned long ctl = 0, ctl_mask = 0, ext_ctl = 0, ext_ctl_mask = 0;
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ unsigned int i;
++
++ for_each_set_bit(i, mask, ARRAY_SIZE(omnia_gpios)) {
++ unsigned long *field, *field_mask;
++ u8 bit = omnia_gpios[i].ctl_bit;
++
++ switch (omnia_gpios[i].ctl_cmd) {
++ case OMNIA_CMD_GENERAL_CONTROL:
++ field = &ctl;
++ field_mask = &ctl_mask;
++ break;
++ case OMNIA_CMD_EXT_CONTROL:
++ field = &ext_ctl;
++ field_mask = &ext_ctl_mask;
++ break;
++ default:
++ field = field_mask = NULL;
++ break;
++ }
++
++ if (!field)
++ continue;
++
++ __set_bit(bit, field_mask);
++ __assign_bit(bit, field, test_bit(i, bits));
++ }
++
++ guard(mutex)(&mcu->lock);
++
++ if (ctl_mask)
++ omnia_ctl_cmd_locked(mcu, OMNIA_CMD_GENERAL_CONTROL,
++ ctl, ctl_mask);
++
++ if (ext_ctl_mask)
++ omnia_ctl_cmd_locked(mcu, OMNIA_CMD_EXT_CONTROL,
++ ext_ctl, ext_ctl_mask);
++}
++
++static bool omnia_gpio_available(struct omnia_mcu *mcu,
++ const struct omnia_gpio *gpio)
++{
++ if (gpio->feat_mask)
++ return (mcu->features & gpio->feat_mask) == gpio->feat;
++
++ if (gpio->feat)
++ return mcu->features & gpio->feat;
++
++ return true;
++}
++
++static int omnia_gpio_init_valid_mask(struct gpio_chip *gc,
++ unsigned long *valid_mask,
++ unsigned int ngpios)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ for (unsigned int i = 0; i < ngpios; i++) {
++ const struct omnia_gpio *gpio = &omnia_gpios[i];
++
++ if (gpio->cmd || is_int_bit_valid(gpio))
++ __assign_bit(i, valid_mask,
++ omnia_gpio_available(mcu, gpio));
++ else
++ __clear_bit(i, valid_mask);
++ }
++
++ return 0;
++}
++
++static int omnia_gpio_of_xlate(struct gpio_chip *gc,
++ const struct of_phandle_args *gpiospec,
++ u32 *flags)
++{
++ u32 bank, gpio;
++
++ if (WARN_ON(gpiospec->args_count != 3))
++ return -EINVAL;
++
++ if (flags)
++ *flags = gpiospec->args[2];
++
++ bank = gpiospec->args[0];
++ gpio = gpiospec->args[1];
++
++ switch (bank) {
++ case 0:
++ return gpio < 16 ? gpio : -EINVAL;
++ case 1:
++ return gpio < 32 ? 16 + gpio : -EINVAL;
++ case 2:
++ return gpio < 16 ? 48 + gpio : -EINVAL;
++ default:
++ return -EINVAL;
++ }
++}
++
++static void omnia_irq_shutdown(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ __clear_bit(bit, &mcu->rising);
++ __clear_bit(bit, &mcu->falling);
++}
++
++static void omnia_irq_mask(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ if (!omnia_gpios[hwirq].cmd)
++ __clear_bit(bit, &mcu->rising);
++ __clear_bit(bit, &mcu->mask);
++ gpiochip_disable_irq(gc, hwirq);
++}
++
++static void omnia_irq_unmask(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ gpiochip_enable_irq(gc, hwirq);
++ __set_bit(bit, &mcu->mask);
++ if (!omnia_gpios[hwirq].cmd)
++ __set_bit(bit, &mcu->rising);
++}
++
++static int omnia_irq_set_type(struct irq_data *d, unsigned int type)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ struct device *dev = &mcu->client->dev;
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ if (!(type & IRQ_TYPE_EDGE_BOTH)) {
++ dev_err(dev, "irq %u: unsupported type %u\n", d->irq, type);
++ return -EINVAL;
++ }
++
++ __assign_bit(bit, &mcu->rising, type & IRQ_TYPE_EDGE_RISING);
++ __assign_bit(bit, &mcu->falling, type & IRQ_TYPE_EDGE_FALLING);
++
++ return 0;
++}
++
++static void omnia_irq_bus_lock(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ /* nothing to do if MCU firmware does not support new interrupt API */
++ if (!(mcu->features & OMNIA_FEAT_NEW_INT_API))
++ return;
++
++ mutex_lock(&mcu->lock);
++}
++
++/**
++ * omnia_mask_interleave - Interleaves the bytes from @rising and @falling
++ * @dst: the destination u8 array of interleaved bytes
++ * @rising: rising mask
++ * @falling: falling mask
++ *
++ * Interleaves the little-endian bytes from @rising and @falling words.
++ *
++ * If @rising = (r0, r1, r2, r3) and @falling = (f0, f1, f2, f3), the result is
++ * @dst = (r0, f0, r1, f1, r2, f2, r3, f3).
++ *
++ * The MCU receives an interrupt mask and reports a pending interrupt bitmap in
++ * this interleaved format. The rationale behind this is that the low-indexed
++ * bits are more important - in many cases, the user will be interested only in
++ * interrupts with indexes 0 to 7, and so the system can stop reading after
++ * first 2 bytes (r0, f0), to save time on the slow I2C bus.
++ *
++ * Feel free to remove this function and its inverse, omnia_mask_deinterleave,
++ * and use an appropriate bitmap_*() function once such a function exists.
++ */
++static void
++omnia_mask_interleave(u8 *dst, unsigned long rising, unsigned long falling)
++{
++ for (unsigned int i = 0; i < sizeof(u32); i++) {
++ dst[2 * i] = rising >> (8 * i);
++ dst[2 * i + 1] = falling >> (8 * i);
++ }
++}
++
++/**
++ * omnia_mask_deinterleave - Deinterleaves the bytes into @rising and @falling
++ * @src: the source u8 array containing the interleaved bytes
++ * @rising: pointer where to store the rising mask gathered from @src
++ * @falling: pointer where to store the falling mask gathered from @src
++ *
++ * This is the inverse function to omnia_mask_interleave.
++ */
++static void omnia_mask_deinterleave(const u8 *src, unsigned long *rising,
++ unsigned long *falling)
++{
++ *rising = *falling = 0;
++
++ for (unsigned int i = 0; i < sizeof(u32); i++) {
++ *rising |= src[2 * i] << (8 * i);
++ *falling |= src[2 * i + 1] << (8 * i);
++ }
++}
++
++static void omnia_irq_bus_sync_unlock(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ struct device *dev = &mcu->client->dev;
++ u8 cmd[1 + OMNIA_CMD_INT_ARG_LEN];
++ unsigned long rising, falling;
++ int err;
++
++ /* nothing to do if MCU firmware does not support new interrupt API */
++ if (!(mcu->features & OMNIA_FEAT_NEW_INT_API))
++ return;
++
++ cmd[0] = OMNIA_CMD_SET_INT_MASK;
++
++ rising = mcu->rising & mcu->mask;
++ falling = mcu->falling & mcu->mask;
++
++ /* interleave the rising and falling bytes into the command arguments */
++ omnia_mask_interleave(&cmd[1], rising, falling);
++
++ dev_dbg(dev, "set int mask %8ph\n", &cmd[1]);
++
++ err = omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++ if (err) {
++ dev_err(dev, "Cannot set mask: %d\n", err);
++ goto unlock;
++ }
++
++ /*
++ * Remember which GPIOs have both rising and falling interrupts enabled.
++ * For those we will cache their value so that .get() method is faster.
++ * We also need to forget cached values of GPIOs that aren't cached
++ * anymore.
++ */
++ mcu->both = rising & falling;
++ mcu->is_cached &= mcu->both;
++
++unlock:
++ mutex_unlock(&mcu->lock);
++}
++
++static const struct irq_chip omnia_mcu_irq_chip = {
++ .name = "Turris Omnia MCU interrupts",
++ .irq_shutdown = omnia_irq_shutdown,
++ .irq_mask = omnia_irq_mask,
++ .irq_unmask = omnia_irq_unmask,
++ .irq_set_type = omnia_irq_set_type,
++ .irq_bus_lock = omnia_irq_bus_lock,
++ .irq_bus_sync_unlock = omnia_irq_bus_sync_unlock,
++ .flags = IRQCHIP_IMMUTABLE,
++ GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
++static void omnia_irq_init_valid_mask(struct gpio_chip *gc,
++ unsigned long *valid_mask,
++ unsigned int ngpios)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ for (unsigned int i = 0; i < ngpios; i++) {
++ const struct omnia_gpio *gpio = &omnia_gpios[i];
++
++ if (is_int_bit_valid(gpio))
++ __assign_bit(i, valid_mask,
++ omnia_gpio_available(mcu, gpio));
++ else
++ __clear_bit(i, valid_mask);
++ }
++}
++
++static int omnia_irq_init_hw(struct gpio_chip *gc)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ u8 cmd[1 + OMNIA_CMD_INT_ARG_LEN] = {};
++
++ cmd[0] = OMNIA_CMD_SET_INT_MASK;
++
++ return omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++}
++
++/*
++ * Determine how many bytes we need to read from the reply to the
++ * OMNIA_CMD_GET_INT_AND_CLEAR command in order to retrieve all unmasked
++ * interrupts.
++ */
++static unsigned int
++omnia_irq_compute_pending_length(unsigned long rising, unsigned long falling)
++{
++ return max(omnia_compute_reply_length(rising, true, 0),
++ omnia_compute_reply_length(falling, true, 1));
++}
++
++static bool omnia_irq_read_pending_new(struct omnia_mcu *mcu,
++ unsigned long *pending)
++{
++ struct device *dev = &mcu->client->dev;
++ u8 reply[OMNIA_CMD_INT_ARG_LEN] = {};
++ unsigned long rising, falling;
++ unsigned int len;
++ int err;
++
++ len = omnia_irq_compute_pending_length(mcu->rising & mcu->mask,
++ mcu->falling & mcu->mask);
++ if (!len)
++ return false;
++
++ guard(mutex)(&mcu->lock);
++
++ err = omnia_cmd_read(mcu->client, OMNIA_CMD_GET_INT_AND_CLEAR, reply,
++ len);
++ if (err) {
++ dev_err(dev, "Cannot read pending IRQs: %d\n", err);
++ return false;
++ }
++
++ /* deinterleave the reply bytes into rising and falling */
++ omnia_mask_deinterleave(reply, &rising, &falling);
++
++ rising &= mcu->mask;
++ falling &= mcu->mask;
++ *pending = rising | falling;
++
++ /* cache values for GPIOs that have both edges enabled */
++ mcu->is_cached &= ~(rising & falling);
++ mcu->is_cached |= mcu->both & (rising ^ falling);
++ mcu->cached = (mcu->cached | rising) & ~falling;
++
++ return true;
++}
++
++static int omnia_read_status_word_old_fw(struct omnia_mcu *mcu,
++ unsigned long *status)
++{
++ u16 raw_status;
++ int err;
++
++ err = omnia_cmd_read_u16(mcu->client, OMNIA_CMD_GET_STATUS_WORD,
++ &raw_status);
++ if (err)
++ return err;
++
++ /*
++ * Old firmware has a bug wherein it never resets the USB port
++ * overcurrent bits back to zero. Ignore them.
++ */
++ *status = raw_status & ~(OMNIA_STS_USB30_OVC | OMNIA_STS_USB31_OVC);
++
++ return 0;
++}
++
++static void button_release_emul_fn(struct work_struct *work)
++{
++ struct omnia_mcu *mcu = container_of(to_delayed_work(work),
++ struct omnia_mcu,
++ button_release_emul_work);
++
++ mcu->button_pressed_emul = false;
++ generic_handle_irq_safe(mcu->client->irq);
++}
++
++static void
++fill_int_from_sts(unsigned long *rising, unsigned long *falling,
++ unsigned long rising_sts, unsigned long falling_sts,
++ unsigned long sts_bit, unsigned long int_bit)
++{
++ if (rising_sts & sts_bit)
++ *rising |= int_bit;
++ if (falling_sts & sts_bit)
++ *falling |= int_bit;
++}
++
++static bool omnia_irq_read_pending_old(struct omnia_mcu *mcu,
++ unsigned long *pending)
++{
++ unsigned long status, rising_sts, falling_sts, rising, falling;
++ struct device *dev = &mcu->client->dev;
++ int err;
++
++ guard(mutex)(&mcu->lock);
++
++ err = omnia_read_status_word_old_fw(mcu, &status);
++ if (err) {
++ dev_err(dev, "Cannot read pending IRQs: %d\n", err);
++ return false;
++ }
++
++ /*
++ * The old firmware triggers an interrupt whenever status word changes,
++ * but does not inform about which bits rose or fell. We need to compute
++ * this here by comparing with the last status word value.
++ *
++ * The OMNIA_STS_BUTTON_PRESSED bit needs special handling, because the
++ * old firmware clears the OMNIA_STS_BUTTON_PRESSED bit on successful
++ * completion of the OMNIA_CMD_GET_STATUS_WORD command, resulting in
++ * another interrupt:
++ * - first we get an interrupt, we read the status word where
++ * OMNIA_STS_BUTTON_PRESSED is present,
++ * - MCU clears the OMNIA_STS_BUTTON_PRESSED bit because we read the
++ * status word,
++ * - we get another interrupt because the status word changed again
++ * (the OMNIA_STS_BUTTON_PRESSED bit was cleared).
++ *
++ * The gpiolib-cdev, gpiolib-sysfs and gpio-keys input driver all call
++ * the gpiochip's .get() method after an edge event on a requested GPIO
++ * occurs.
++ *
++ * We ensure that the .get() method reads 1 for the button GPIO for some
++ * time.
++ */
++
++ if (status & OMNIA_STS_BUTTON_PRESSED) {
++ mcu->button_pressed_emul = true;
++ mod_delayed_work(system_wq, &mcu->button_release_emul_work,
++ msecs_to_jiffies(FRONT_BUTTON_RELEASE_DELAY_MS));
++ } else if (mcu->button_pressed_emul) {
++ status |= OMNIA_STS_BUTTON_PRESSED;
++ }
++
++ rising_sts = ~mcu->last_status & status;
++ falling_sts = mcu->last_status & ~status;
++
++ mcu->last_status = status;
++
++ /*
++ * Fill in the relevant interrupt bits from status bits for CARD_DET,
++ * MSATA_IND and BUTTON_PRESSED.
++ */
++ rising = 0;
++ falling = 0;
++ fill_int_from_sts(&rising, &falling, rising_sts, falling_sts,
++ OMNIA_STS_CARD_DET, OMNIA_INT_CARD_DET);
++ fill_int_from_sts(&rising, &falling, rising_sts, falling_sts,
++ OMNIA_STS_MSATA_IND, OMNIA_INT_MSATA_IND);
++ fill_int_from_sts(&rising, &falling, rising_sts, falling_sts,
++ OMNIA_STS_BUTTON_PRESSED, OMNIA_INT_BUTTON_PRESSED);
++
++ /* Use only bits that are enabled */
++ rising &= mcu->rising & mcu->mask;
++ falling &= mcu->falling & mcu->mask;
++ *pending = rising | falling;
++
++ return true;
++}
++
++static bool omnia_irq_read_pending(struct omnia_mcu *mcu,
++ unsigned long *pending)
++{
++ if (mcu->features & OMNIA_FEAT_NEW_INT_API)
++ return omnia_irq_read_pending_new(mcu, pending);
++ else
++ return omnia_irq_read_pending_old(mcu, pending);
++}
++
++static irqreturn_t omnia_irq_thread_handler(int irq, void *dev_id)
++{
++ struct omnia_mcu *mcu = dev_id;
++ struct irq_domain *domain;
++ unsigned long pending;
++ unsigned int i;
++
++ if (!omnia_irq_read_pending(mcu, &pending))
++ return IRQ_NONE;
++
++ domain = mcu->gc.irq.domain;
++
++ for_each_set_bit(i, &pending, 32) {
++ unsigned int nested_irq;
++
++ nested_irq = irq_find_mapping(domain, omnia_int_to_gpio_idx[i]);
++
++ handle_nested_irq(nested_irq);
++ }
++
++ return IRQ_RETVAL(pending);
++}
++
++static const char * const front_button_modes[] = { "mcu", "cpu" };
++
++static ssize_t front_button_mode_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ int val;
++
++ if (mcu->features & OMNIA_FEAT_NEW_INT_API) {
++ val = omnia_cmd_read_bit(mcu->client, OMNIA_CMD_GET_STATUS_WORD,
++ OMNIA_STS_BUTTON_MODE);
++ if (val < 0)
++ return val;
++ } else {
++ val = !!(mcu->last_status & OMNIA_STS_BUTTON_MODE);
++ }
++
++ return sysfs_emit(buf, "%s\n", front_button_modes[val]);
++}
++
++static ssize_t front_button_mode_store(struct device *dev,
++ struct device_attribute *a,
++ const char *buf, size_t count)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ int err, i;
++
++ i = sysfs_match_string(front_button_modes, buf);
++ if (i < 0)
++ return i;
++
++ err = omnia_ctl_cmd_locked(mcu, OMNIA_CMD_GENERAL_CONTROL,
++ i ? OMNIA_CTL_BUTTON_MODE : 0,
++ OMNIA_CTL_BUTTON_MODE);
++ if (err)
++ return err;
++
++ return count;
++}
++static DEVICE_ATTR_RW(front_button_mode);
++
++static struct attribute *omnia_mcu_gpio_attrs[] = {
++ &dev_attr_front_button_mode.attr,
++ NULL
++};
++
++const struct attribute_group omnia_mcu_gpio_group = {
++ .attrs = omnia_mcu_gpio_attrs,
++};
++
++int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu)
++{
++ bool new_api = mcu->features & OMNIA_FEAT_NEW_INT_API;
++ struct device *dev = &mcu->client->dev;
++ unsigned long irqflags;
++ int err;
++
++ err = devm_mutex_init(dev, &mcu->lock);
++ if (err)
++ return err;
++
++ mcu->gc.request = omnia_gpio_request;
++ mcu->gc.get_direction = omnia_gpio_get_direction;
++ mcu->gc.direction_input = omnia_gpio_direction_input;
++ mcu->gc.direction_output = omnia_gpio_direction_output;
++ mcu->gc.get = omnia_gpio_get;
++ mcu->gc.get_multiple = omnia_gpio_get_multiple;
++ mcu->gc.set = omnia_gpio_set;
++ mcu->gc.set_multiple = omnia_gpio_set_multiple;
++ mcu->gc.init_valid_mask = omnia_gpio_init_valid_mask;
++ mcu->gc.can_sleep = true;
++ mcu->gc.names = omnia_mcu_gpio_templates;
++ mcu->gc.base = -1;
++ mcu->gc.ngpio = ARRAY_SIZE(omnia_gpios);
++ mcu->gc.label = "Turris Omnia MCU GPIOs";
++ mcu->gc.parent = dev;
++ mcu->gc.owner = THIS_MODULE;
++ mcu->gc.of_gpio_n_cells = 3;
++ mcu->gc.of_xlate = omnia_gpio_of_xlate;
++
++ gpio_irq_chip_set_chip(&mcu->gc.irq, &omnia_mcu_irq_chip);
++ /* This will let us handle the parent IRQ in the driver */
++ mcu->gc.irq.parent_handler = NULL;
++ mcu->gc.irq.num_parents = 0;
++ mcu->gc.irq.parents = NULL;
++ mcu->gc.irq.default_type = IRQ_TYPE_NONE;
++ mcu->gc.irq.handler = handle_bad_irq;
++ mcu->gc.irq.threaded = true;
++ if (new_api)
++ mcu->gc.irq.init_hw = omnia_irq_init_hw;
++ mcu->gc.irq.init_valid_mask = omnia_irq_init_valid_mask;
++
++ err = devm_gpiochip_add_data(dev, &mcu->gc, mcu);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot add GPIO chip\n");
++
++ /*
++ * Before requesting the interrupt, if firmware does not support the new
++ * interrupt API, we need to cache the value of the status word, so that
++ * when it changes, we may compare the new value with the cached one in
++ * the interrupt handler.
++ */
++ if (!new_api) {
++ err = omnia_read_status_word_old_fw(mcu, &mcu->last_status);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot read status word\n");
++
++ INIT_DELAYED_WORK(&mcu->button_release_emul_work,
++ button_release_emul_fn);
++ }
++
++ irqflags = IRQF_ONESHOT;
++ if (new_api)
++ irqflags |= IRQF_TRIGGER_LOW;
++ else
++ irqflags |= IRQF_TRIGGER_FALLING;
++
++ err = devm_request_threaded_irq(dev, mcu->client->irq, NULL,
++ omnia_irq_thread_handler, irqflags,
++ "turris-omnia-mcu", mcu);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot request IRQ\n");
++
++ if (!new_api) {
++ /*
++ * The button_release_emul_work has to be initialized before the
++ * thread is requested, and on driver remove it needs to be
++ * canceled before the thread is freed. Therefore we can't use
++ * devm_delayed_work_autocancel() directly, because the order
++ * devm_delayed_work_autocancel();
++ * devm_request_threaded_irq();
++ * would cause improper release order:
++ * free_irq();
++ * cancel_delayed_work_sync();
++ * Instead we first initialize the work above, and only now
++ * after IRQ is requested we add the work devm action.
++ */
++ err = devm_add_action(dev, devm_delayed_work_drop,
++ &mcu->button_release_emul_work);
++ if (err)
++ return err;
++ }
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -8,8 +8,12 @@
+ #ifndef __TURRIS_OMNIA_MCU_H
+ #define __TURRIS_OMNIA_MCU_H
+
++#include <linux/bitops.h>
++#include <linux/gpio/driver.h>
+ #include <linux/if_ether.h>
++#include <linux/mutex.h>
+ #include <linux/types.h>
++#include <linux/workqueue.h>
+ #include <asm/byteorder.h>
+
+ struct i2c_client;
+@@ -23,18 +27,78 @@ struct omnia_mcu {
+ u64 board_serial_number;
+ u8 board_first_mac[ETH_ALEN];
+ u8 board_revision;
++
++ /* GPIO chip */
++ struct gpio_chip gc;
++ struct mutex lock;
++ unsigned long mask, rising, falling, both, cached, is_cached;
++ /* Old MCU firmware handling needs the following */
++ struct delayed_work button_release_emul_work;
++ unsigned long last_status;
++ bool button_pressed_emul;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+ void *cmd, unsigned int cmd_len,
+ void *reply, unsigned int reply_len);
+
++static inline int omnia_cmd_write(const struct i2c_client *client, void *cmd,
++ unsigned int len)
++{
++ return omnia_cmd_write_read(client, cmd, len, NULL, 0);
++}
++
+ static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
+ void *reply, unsigned int len)
+ {
+ return omnia_cmd_write_read(client, &cmd, 1, reply, len);
+ }
+
++static inline unsigned int
++omnia_compute_reply_length(unsigned long mask, bool interleaved,
++ unsigned int offset)
++{
++ if (!mask)
++ return 0;
++
++ return ((__fls(mask) >> 3) << interleaved) + 1 + offset;
++}
++
++/* Returns 0 on success */
++static inline int omnia_cmd_read_bits(const struct i2c_client *client, u8 cmd,
++ unsigned long bits, unsigned long *dst)
++{
++ __le32 reply;
++ int err;
++
++ if (!bits) {
++ *dst = 0;
++ return 0;
++ }
++
++ err = omnia_cmd_read(client, cmd, &reply,
++ omnia_compute_reply_length(bits, false, 0));
++ if (err)
++ return err;
++
++ *dst = le32_to_cpu(reply) & bits;
++
++ return 0;
++}
++
++static inline int omnia_cmd_read_bit(const struct i2c_client *client, u8 cmd,
++ unsigned long bit)
++{
++ unsigned long reply;
++ int err;
++
++ err = omnia_cmd_read_bits(client, cmd, bit, &reply);
++ if (err)
++ return err;
++
++ return !!reply;
++}
++
+ static inline int omnia_cmd_read_u32(const struct i2c_client *client, u8 cmd,
+ u32 *dst)
+ {
+@@ -71,4 +135,8 @@ static inline int omnia_cmd_read_u8(cons
+ return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
+ }
+
++extern const struct attribute_group omnia_mcu_gpio_group;
++
++int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
++
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch b/target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch
new file mode 100644
index 0000000000..2ef6242d70
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch
@@ -0,0 +1,415 @@
+From f69e0a731ab471f3a57c48258ad2d9990820c173 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:06 +0200
+Subject: [PATCH 04/11] platform: cznic: turris-omnia-mcu: Add support for
+ poweroff and wakeup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for true board poweroff (MCU can disable all unnecessary
+voltage regulators) and wakeup at a specified time, implemented via a
+RTC driver so that the rtcwake utility can be used to configure it.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-5-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../sysfs-bus-i2c-devices-turris-omnia-mcu | 16 ++
+ drivers/platform/cznic/Kconfig | 4 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 5 +
+ .../cznic/turris-omnia-mcu-sys-off-wakeup.c | 260 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 20 ++
+ 6 files changed, 306 insertions(+)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-sys-off-wakeup.c
+
+--- a/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
++++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+@@ -38,6 +38,22 @@ Description: (RW) The front button on th
+
+ Format: %s.
+
++What: /sys/bus/i2c/devices/<mcu_device>/front_button_poweron
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RW) Newer versions of the microcontroller firmware of the
++ Turris Omnia router support powering off the router into true
++ low power mode. The router can be powered on by pressing the
++ front button.
++
++ This file configures whether front button power on is enabled.
++
++ This file is present only if the power off feature is supported
++ by the firmware.
++
++ Format: %i.
++
+ What: /sys/bus/i2c/devices/<mcu_device>/fw_features
+ Date: September 2024
+ KernelVersion: 6.11
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -18,10 +18,14 @@ config TURRIS_OMNIA_MCU
+ depends on I2C
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
++ select RTC_CLASS
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
+ The features include:
++ - board poweroff into true low power mode (with voltage regulators
++ disabled) and the ability to configure wake up from this mode (via
++ rtcwake)
+ - GPIO pins
+ - to get front button press events (the front button can be
+ configured either to generate press events to the CPU or to change
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -3,3 +3,4 @@
+ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris-omnia-mcu.o
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
+ turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
++turris-omnia-mcu-y += turris-omnia-mcu-sys-off-wakeup.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -197,6 +197,7 @@ static const struct attribute_group omni
+ static const struct attribute_group *omnia_mcu_groups[] = {
+ &omnia_mcu_base_group,
+ &omnia_mcu_gpio_group,
++ &omnia_mcu_poweroff_group,
+ NULL
+ };
+
+@@ -371,6 +372,10 @@ static int omnia_mcu_probe(struct i2c_cl
+ "Cannot read board info\n");
+ }
+
++ err = omnia_mcu_register_sys_off_and_wakeup(mcu);
++ if (err)
++ return err;
++
+ return omnia_mcu_register_gpiochip(mcu);
+ }
+
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-sys-off-wakeup.c
+@@ -0,0 +1,260 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU system off and RTC wakeup driver
++ *
++ * This is not a true RTC driver (in the sense that it does not provide a
++ * real-time clock), rather the MCU implements a wakeup from powered off state
++ * at a specified time relative to MCU boot, and we expose this feature via RTC
++ * alarm, so that it can be used via the rtcwake command, which is the standard
++ * Linux command for this.
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/crc32.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include <linux/kstrtox.h>
++#include <linux/reboot.h>
++#include <linux/rtc.h>
++#include <linux/sysfs.h>
++#include <linux/types.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++static int omnia_get_uptime_wakeup(const struct i2c_client *client, u32 *uptime,
++ u32 *wakeup)
++{
++ __le32 reply[2];
++ int err;
++
++ err = omnia_cmd_read(client, OMNIA_CMD_GET_UPTIME_AND_WAKEUP, reply,
++ sizeof(reply));
++ if (err)
++ return err;
++
++ if (uptime)
++ *uptime = le32_to_cpu(reply[0]);
++
++ if (wakeup)
++ *wakeup = le32_to_cpu(reply[1]);
++
++ return 0;
++}
++
++static int omnia_read_time(struct device *dev, struct rtc_time *tm)
++{
++ u32 uptime;
++ int err;
++
++ err = omnia_get_uptime_wakeup(to_i2c_client(dev), &uptime, NULL);
++ if (err)
++ return err;
++
++ rtc_time64_to_tm(uptime, tm);
++
++ return 0;
++}
++
++static int omnia_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct omnia_mcu *mcu = i2c_get_clientdata(client);
++ u32 wakeup;
++ int err;
++
++ err = omnia_get_uptime_wakeup(client, NULL, &wakeup);
++ if (err)
++ return err;
++
++ alrm->enabled = !!wakeup;
++ rtc_time64_to_tm(wakeup ?: mcu->rtc_alarm, &alrm->time);
++
++ return 0;
++}
++
++static int omnia_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct omnia_mcu *mcu = i2c_get_clientdata(client);
++
++ mcu->rtc_alarm = rtc_tm_to_time64(&alrm->time);
++
++ if (alrm->enabled)
++ return omnia_cmd_write_u32(client, OMNIA_CMD_SET_WAKEUP,
++ mcu->rtc_alarm);
++
++ return 0;
++}
++
++static int omnia_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct omnia_mcu *mcu = i2c_get_clientdata(client);
++
++ return omnia_cmd_write_u32(client, OMNIA_CMD_SET_WAKEUP,
++ enabled ? mcu->rtc_alarm : 0);
++}
++
++static const struct rtc_class_ops omnia_rtc_ops = {
++ .read_time = omnia_read_time,
++ .read_alarm = omnia_read_alarm,
++ .set_alarm = omnia_set_alarm,
++ .alarm_irq_enable = omnia_alarm_irq_enable,
++};
++
++static int omnia_power_off(struct sys_off_data *data)
++{
++ struct omnia_mcu *mcu = data->cb_data;
++ __be32 tmp;
++ u8 cmd[9];
++ u16 arg;
++ int err;
++
++ if (mcu->front_button_poweron)
++ arg = OMNIA_CMD_POWER_OFF_POWERON_BUTTON;
++ else
++ arg = 0;
++
++ cmd[0] = OMNIA_CMD_POWER_OFF;
++ put_unaligned_le16(OMNIA_CMD_POWER_OFF_MAGIC, &cmd[1]);
++ put_unaligned_le16(arg, &cmd[3]);
++
++ /*
++ * Although all values from and to MCU are passed in little-endian, the
++ * MCU's CRC unit uses big-endian CRC32 polynomial (0x04c11db7), so we
++ * need to use crc32_be() here.
++ */
++ tmp = cpu_to_be32(get_unaligned_le32(&cmd[1]));
++ put_unaligned_le32(crc32_be(~0, (void *)&tmp, sizeof(tmp)), &cmd[5]);
++
++ err = omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++ if (err)
++ dev_err(&mcu->client->dev,
++ "Unable to send the poweroff command: %d\n", err);
++
++ return NOTIFY_DONE;
++}
++
++static int omnia_restart(struct sys_off_data *data)
++{
++ struct omnia_mcu *mcu = data->cb_data;
++ u8 cmd[3];
++ int err;
++
++ cmd[0] = OMNIA_CMD_GENERAL_CONTROL;
++
++ if (reboot_mode == REBOOT_HARD)
++ cmd[1] = cmd[2] = OMNIA_CTL_HARD_RST;
++ else
++ cmd[1] = cmd[2] = OMNIA_CTL_LIGHT_RST;
++
++ err = omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++ if (err)
++ dev_err(&mcu->client->dev,
++ "Unable to send the restart command: %d\n", err);
++
++ /*
++ * MCU needs a little bit to process the I2C command, otherwise it will
++ * do a light reset based on SOC SYSRES_OUT pin.
++ */
++ mdelay(1);
++
++ return NOTIFY_DONE;
++}
++
++static ssize_t front_button_poweron_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%d\n", mcu->front_button_poweron);
++}
++
++static ssize_t front_button_poweron_store(struct device *dev,
++ struct device_attribute *a,
++ const char *buf, size_t count)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ bool val;
++ int err;
++
++ err = kstrtobool(buf, &val);
++ if (err)
++ return err;
++
++ mcu->front_button_poweron = val;
++
++ return count;
++}
++static DEVICE_ATTR_RW(front_button_poweron);
++
++static struct attribute *omnia_mcu_poweroff_attrs[] = {
++ &dev_attr_front_button_poweron.attr,
++ NULL
++};
++
++static umode_t poweroff_attrs_visible(struct kobject *kobj, struct attribute *a,
++ int n)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ if (mcu->features & OMNIA_FEAT_POWEROFF_WAKEUP)
++ return a->mode;
++
++ return 0;
++}
++
++const struct attribute_group omnia_mcu_poweroff_group = {
++ .attrs = omnia_mcu_poweroff_attrs,
++ .is_visible = poweroff_attrs_visible,
++};
++
++int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu)
++{
++ struct device *dev = &mcu->client->dev;
++ int err;
++
++ /* MCU restart is always available */
++ err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART,
++ SYS_OFF_PRIO_FIRMWARE,
++ omnia_restart, mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot register system restart handler\n");
++
++ /*
++ * Poweroff and wakeup are available only if POWEROFF_WAKEUP feature is
++ * present.
++ */
++ if (!(mcu->features & OMNIA_FEAT_POWEROFF_WAKEUP))
++ return 0;
++
++ err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
++ SYS_OFF_PRIO_FIRMWARE,
++ omnia_power_off, mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot register system power off handler\n");
++
++ mcu->rtcdev = devm_rtc_allocate_device(dev);
++ if (IS_ERR(mcu->rtcdev))
++ return dev_err_probe(dev, PTR_ERR(mcu->rtcdev),
++ "Cannot allocate RTC device\n");
++
++ mcu->rtcdev->ops = &omnia_rtc_ops;
++ mcu->rtcdev->range_max = U32_MAX;
++ set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, mcu->rtcdev->features);
++
++ err = devm_rtc_register_device(mcu->rtcdev);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot register RTC device\n");
++
++ mcu->front_button_poweron = true;
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -15,8 +15,10 @@
+ #include <linux/types.h>
+ #include <linux/workqueue.h>
+ #include <asm/byteorder.h>
++#include <asm/unaligned.h>
+
+ struct i2c_client;
++struct rtc_device;
+
+ struct omnia_mcu {
+ struct i2c_client *client;
+@@ -36,6 +38,11 @@ struct omnia_mcu {
+ struct delayed_work button_release_emul_work;
+ unsigned long last_status;
+ bool button_pressed_emul;
++
++ /* RTC device for configuring wake-up */
++ struct rtc_device *rtcdev;
++ u32 rtc_alarm;
++ bool front_button_poweron;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+@@ -48,6 +55,17 @@ static inline int omnia_cmd_write(const
+ return omnia_cmd_write_read(client, cmd, len, NULL, 0);
+ }
+
++static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
++ u32 val)
++{
++ u8 buf[5];
++
++ buf[0] = cmd;
++ put_unaligned_le32(val, &buf[1]);
++
++ return omnia_cmd_write(client, buf, sizeof(buf));
++}
++
+ static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
+ void *reply, unsigned int len)
+ {
+@@ -136,7 +154,9 @@ static inline int omnia_cmd_read_u8(cons
+ }
+
+ extern const struct attribute_group omnia_mcu_gpio_group;
++extern const struct attribute_group omnia_mcu_poweroff_group;
+
+ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
++int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
+
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch b/target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
new file mode 100644
index 0000000000..cf3f88bfcf
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
@@ -0,0 +1,250 @@
+From 33ae4e4c86bc6ff298489fb8b743e2743dd0af6d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:07 +0200
+Subject: [PATCH 05/11] platform: cznic: turris-omnia-mcu: Add support for MCU
+ watchdog
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for the watchdog mechanism provided by the MCU.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-6-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 2 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 4 +
+ .../cznic/turris-omnia-mcu-watchdog.c | 130 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 24 ++++
+ 5 files changed, 161 insertions(+)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-watchdog.c
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -19,6 +19,7 @@ config TURRIS_OMNIA_MCU
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select RTC_CLASS
++ select WATCHDOG_CORE
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
+@@ -26,6 +27,7 @@ config TURRIS_OMNIA_MCU
+ - board poweroff into true low power mode (with voltage regulators
+ disabled) and the ability to configure wake up from this mode (via
+ rtcwake)
++ - MCU watchdog
+ - GPIO pins
+ - to get front button press events (the front button can be
+ configured either to generate press events to the CPU or to change
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -4,3 +4,4 @@ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
+ turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
+ turris-omnia-mcu-y += turris-omnia-mcu-sys-off-wakeup.o
++turris-omnia-mcu-y += turris-omnia-mcu-watchdog.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -376,6 +376,10 @@ static int omnia_mcu_probe(struct i2c_cl
+ if (err)
+ return err;
+
++ err = omnia_mcu_register_watchdog(mcu);
++ if (err)
++ return err;
++
+ return omnia_mcu_register_gpiochip(mcu);
+ }
+
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-watchdog.c
+@@ -0,0 +1,130 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU watchdog driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bitops.h>
++#include <linux/device.h>
++#include <linux/i2c.h>
++#include <linux/moduleparam.h>
++#include <linux/types.h>
++#include <linux/units.h>
++#include <linux/watchdog.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define WATCHDOG_TIMEOUT 120
++
++static unsigned int timeout;
++module_param(timeout, int, 0);
++MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds");
++
++static bool nowayout = WATCHDOG_NOWAYOUT;
++module_param(nowayout, bool, 0);
++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
++ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
++
++static int omnia_wdt_start(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u8(mcu->client, OMNIA_CMD_SET_WATCHDOG_STATE, 1);
++}
++
++static int omnia_wdt_stop(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u8(mcu->client, OMNIA_CMD_SET_WATCHDOG_STATE, 0);
++}
++
++static int omnia_wdt_ping(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u8(mcu->client, OMNIA_CMD_SET_WATCHDOG_STATE, 1);
++}
++
++static int omnia_wdt_set_timeout(struct watchdog_device *wdt,
++ unsigned int timeout)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u16(mcu->client, OMNIA_CMD_SET_WDT_TIMEOUT,
++ timeout * DECI);
++}
++
++static unsigned int omnia_wdt_get_timeleft(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++ u16 timeleft;
++ int err;
++
++ err = omnia_cmd_read_u16(mcu->client, OMNIA_CMD_GET_WDT_TIMELEFT,
++ &timeleft);
++ if (err) {
++ dev_err(&mcu->client->dev, "Cannot get watchdog timeleft: %d\n",
++ err);
++ return 0;
++ }
++
++ return timeleft / DECI;
++}
++
++static const struct watchdog_info omnia_wdt_info = {
++ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
++ .identity = "Turris Omnia MCU Watchdog",
++};
++
++static const struct watchdog_ops omnia_wdt_ops = {
++ .owner = THIS_MODULE,
++ .start = omnia_wdt_start,
++ .stop = omnia_wdt_stop,
++ .ping = omnia_wdt_ping,
++ .set_timeout = omnia_wdt_set_timeout,
++ .get_timeleft = omnia_wdt_get_timeleft,
++};
++
++int omnia_mcu_register_watchdog(struct omnia_mcu *mcu)
++{
++ struct device *dev = &mcu->client->dev;
++ u8 state;
++ int err;
++
++ if (!(mcu->features & OMNIA_FEAT_WDT_PING))
++ return 0;
++
++ mcu->wdt.info = &omnia_wdt_info;
++ mcu->wdt.ops = &omnia_wdt_ops;
++ mcu->wdt.parent = dev;
++ mcu->wdt.min_timeout = 1;
++ mcu->wdt.max_timeout = 65535 / DECI;
++
++ mcu->wdt.timeout = WATCHDOG_TIMEOUT;
++ watchdog_init_timeout(&mcu->wdt, timeout, dev);
++
++ watchdog_set_drvdata(&mcu->wdt, mcu);
++
++ omnia_wdt_set_timeout(&mcu->wdt, mcu->wdt.timeout);
++
++ err = omnia_cmd_read_u8(mcu->client, OMNIA_CMD_GET_WATCHDOG_STATE,
++ &state);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot get MCU watchdog state\n");
++
++ if (state)
++ set_bit(WDOG_HW_RUNNING, &mcu->wdt.status);
++
++ watchdog_set_nowayout(&mcu->wdt, nowayout);
++ watchdog_stop_on_reboot(&mcu->wdt);
++ err = devm_watchdog_register_device(dev, &mcu->wdt);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot register MCU watchdog\n");
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -13,6 +13,7 @@
+ #include <linux/if_ether.h>
+ #include <linux/mutex.h>
+ #include <linux/types.h>
++#include <linux/watchdog.h>
+ #include <linux/workqueue.h>
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+@@ -43,6 +44,9 @@ struct omnia_mcu {
+ struct rtc_device *rtcdev;
+ u32 rtc_alarm;
+ bool front_button_poweron;
++
++ /* MCU watchdog */
++ struct watchdog_device wdt;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+@@ -55,6 +59,25 @@ static inline int omnia_cmd_write(const
+ return omnia_cmd_write_read(client, cmd, len, NULL, 0);
+ }
+
++static inline int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd,
++ u8 val)
++{
++ u8 buf[2] = { cmd, val };
++
++ return omnia_cmd_write(client, buf, sizeof(buf));
++}
++
++static inline int omnia_cmd_write_u16(const struct i2c_client *client, u8 cmd,
++ u16 val)
++{
++ u8 buf[3];
++
++ buf[0] = cmd;
++ put_unaligned_le16(val, &buf[1]);
++
++ return omnia_cmd_write(client, buf, sizeof(buf));
++}
++
+ static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
+ u32 val)
+ {
+@@ -158,5 +181,6 @@ extern const struct attribute_group omni
+
+ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
+ int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
++int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
+
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch b/target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
new file mode 100644
index 0000000000..35387e34c7
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
@@ -0,0 +1,225 @@
+From b3ed8645c45567b598bef0868dca166f8ed166a0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:08 +0200
+Subject: [PATCH 06/11] platform: cznic: turris-omnia-mcu: Add support for MCU
+ provided TRNG
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for true random number generator provided by the MCU.
+New Omnia boards come without the Atmel SHA204-A chip. Instead the
+crypto functionality is provided by new microcontroller, which has
+a TRNG peripheral.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-7-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 2 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 6 +-
+ .../platform/cznic/turris-omnia-mcu-gpio.c | 2 +-
+ .../platform/cznic/turris-omnia-mcu-trng.c | 105 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 8 ++
+ 6 files changed, 122 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-trng.c
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -18,6 +18,7 @@ config TURRIS_OMNIA_MCU
+ depends on I2C
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
++ select HW_RANDOM
+ select RTC_CLASS
+ select WATCHDOG_CORE
+ help
+@@ -27,6 +28,7 @@ config TURRIS_OMNIA_MCU
+ - board poweroff into true low power mode (with voltage regulators
+ disabled) and the ability to configure wake up from this mode (via
+ rtcwake)
++ - true random number generator (if available on the MCU)
+ - MCU watchdog
+ - GPIO pins
+ - to get front button press events (the front button can be
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -4,4 +4,5 @@ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
+ turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
+ turris-omnia-mcu-y += turris-omnia-mcu-sys-off-wakeup.o
++turris-omnia-mcu-y += turris-omnia-mcu-trng.o
+ turris-omnia-mcu-y += turris-omnia-mcu-watchdog.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -380,7 +380,11 @@ static int omnia_mcu_probe(struct i2c_cl
+ if (err)
+ return err;
+
+- return omnia_mcu_register_gpiochip(mcu);
++ err = omnia_mcu_register_gpiochip(mcu);
++ if (err)
++ return err;
++
++ return omnia_mcu_register_trng(mcu);
+ }
+
+ static const struct of_device_id of_omnia_mcu_match[] = {
+--- a/drivers/platform/cznic/turris-omnia-mcu-gpio.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-gpio.c
+@@ -194,7 +194,7 @@ static const struct omnia_gpio omnia_gpi
+ };
+
+ /* mapping from interrupts to indexes of GPIOs in the omnia_gpios array */
+-static const u8 omnia_int_to_gpio_idx[32] = {
++const u8 omnia_int_to_gpio_idx[32] = {
+ [__bf_shf(OMNIA_INT_CARD_DET)] = 4,
+ [__bf_shf(OMNIA_INT_MSATA_IND)] = 5,
+ [__bf_shf(OMNIA_INT_USB30_OVC)] = 6,
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-trng.c
+@@ -0,0 +1,105 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU TRNG driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/completion.h>
++#include <linux/container_of.h>
++#include <linux/errno.h>
++#include <linux/gpio/consumer.h>
++#include <linux/gpio/driver.h>
++#include <linux/hw_random.h>
++#include <linux/i2c.h>
++#include <linux/interrupt.h>
++#include <linux/minmax.h>
++#include <linux/string.h>
++#include <linux/types.h>
++
++#include "../../gpio/gpiolib.h"
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define OMNIA_CMD_TRNG_MAX_ENTROPY_LEN 64
++
++static irqreturn_t omnia_trng_irq_handler(int irq, void *dev_id)
++{
++ struct omnia_mcu *mcu = dev_id;
++
++ complete(&mcu->trng_entropy_ready);
++
++ return IRQ_HANDLED;
++}
++
++static int omnia_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
++{
++ struct omnia_mcu *mcu = container_of(rng, struct omnia_mcu, trng);
++ u8 reply[1 + OMNIA_CMD_TRNG_MAX_ENTROPY_LEN];
++ int err, bytes;
++
++ if (!wait && !completion_done(&mcu->trng_entropy_ready))
++ return 0;
++
++ do {
++ if (wait_for_completion_interruptible(&mcu->trng_entropy_ready))
++ return -ERESTARTSYS;
++
++ err = omnia_cmd_read(mcu->client,
++ OMNIA_CMD_TRNG_COLLECT_ENTROPY,
++ reply, sizeof(reply));
++ if (err)
++ return err;
++
++ bytes = min3(reply[0], max, OMNIA_CMD_TRNG_MAX_ENTROPY_LEN);
++ } while (wait && !bytes);
++
++ memcpy(data, &reply[1], bytes);
++
++ return bytes;
++}
++
++int omnia_mcu_register_trng(struct omnia_mcu *mcu)
++{
++ struct device *dev = &mcu->client->dev;
++ u8 irq_idx, dummy;
++ int irq, err;
++
++ if (!(mcu->features & OMNIA_FEAT_TRNG))
++ return 0;
++
++ irq_idx = omnia_int_to_gpio_idx[__bf_shf(OMNIA_INT_TRNG)];
++ irq = gpiod_to_irq(gpiochip_get_desc(&mcu->gc, irq_idx));
++ if (!irq)
++ return dev_err_probe(dev, -ENXIO, "Cannot get TRNG IRQ\n");
++
++ /*
++ * If someone else cleared the TRNG interrupt but did not read the
++ * entropy, a new interrupt won't be generated, and entropy collection
++ * will be stuck. Ensure an interrupt will be generated by executing
++ * the collect entropy command (and discarding the result).
++ */
++ err = omnia_cmd_read(mcu->client, OMNIA_CMD_TRNG_COLLECT_ENTROPY,
++ &dummy, 1);
++ if (err)
++ return err;
++
++ init_completion(&mcu->trng_entropy_ready);
++
++ err = devm_request_threaded_irq(dev, irq, NULL, omnia_trng_irq_handler,
++ IRQF_ONESHOT, "turris-omnia-mcu-trng",
++ mcu);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot request TRNG IRQ\n");
++
++ mcu->trng.name = "turris-omnia-mcu-trng";
++ mcu->trng.read = omnia_trng_read;
++
++ err = devm_hwrng_register(dev, &mcu->trng);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot register TRNG\n");
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -9,7 +9,9 @@
+ #define __TURRIS_OMNIA_MCU_H
+
+ #include <linux/bitops.h>
++#include <linux/completion.h>
+ #include <linux/gpio/driver.h>
++#include <linux/hw_random.h>
+ #include <linux/if_ether.h>
+ #include <linux/mutex.h>
+ #include <linux/types.h>
+@@ -47,6 +49,10 @@ struct omnia_mcu {
+
+ /* MCU watchdog */
+ struct watchdog_device wdt;
++
++ /* true random number generator */
++ struct hwrng trng;
++ struct completion trng_entropy_ready;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+@@ -176,11 +182,13 @@ static inline int omnia_cmd_read_u8(cons
+ return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
+ }
+
++extern const u8 omnia_int_to_gpio_idx[32];
+ extern const struct attribute_group omnia_mcu_gpio_group;
+ extern const struct attribute_group omnia_mcu_poweroff_group;
+
+ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
+ int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
++int omnia_mcu_register_trng(struct omnia_mcu *mcu);
+ int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
+
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch b/target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch
new file mode 100644
index 0000000000..ad65de2f52
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch
@@ -0,0 +1,69 @@
+From 4f11095a4ae00b2fe4cebb21e36ee37cc62f5e1a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:09 +0200
+Subject: [PATCH 07/11] ARM: dts: turris-omnia: Add MCU system-controller node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Turris Omnia's MCU provides various features that can be configured over
+I2C at address 0x2a. Add device-tree node.
+
+This does not carry a Fixes tag - we do not want this to get backported
+to stable kernels for the following reason: U-Boot since v2022.10
+inserts a phy-reset-gpio property into the WAN ethernet node pointing to
+the MCU node if it finds the MCU node with a cznic,turris-omnia-mcu
+compatible. Thus if this change got backported to a stable kernel, the
+WAN interface driver would defer probe indefinitely (since it would wait
+for the turris-omnia-mcu driver which would not be present).
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20240701113010.16447-8-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../dts/marvell/armada-385-turris-omnia.dts | 22 ++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
+@@ -218,7 +218,22 @@
+ #size-cells = <0>;
+ reg = <0>;
+
+- /* STM32F0 command interface at address 0x2a */
++ mcu: system-controller@2a {
++ compatible = "cznic,turris-omnia-mcu";
++ reg = <0x2a>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcu_pins>;
++
++ interrupt-parent = <&gpio1>;
++ interrupts = <11 IRQ_TYPE_NONE>;
++
++ gpio-controller;
++ #gpio-cells = <3>;
++
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
+
+ led-controller@2b {
+ compatible = "cznic,turris-omnia-leds";
+@@ -503,6 +518,11 @@
+ };
+
+ &pinctrl {
++ mcu_pins: mcu-pins {
++ marvell,pins = "mpp43";
++ marvell,function = "gpio";
++ };
++
+ pcawan_pins: pcawan-pins {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch b/target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch
new file mode 100644
index 0000000000..4b36167d66
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch
@@ -0,0 +1,46 @@
+From c3eeabe0b8d22d7c869278cc0cb35b83512fbed5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:10 +0200
+Subject: [PATCH 08/11] ARM: dts: turris-omnia: Add GPIO key node for front
+ button
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Now that we have the MCU device-tree node, which acts as a GPIO
+controller, add GPIO key node for the front button.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20240701113010.16447-9-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../boot/dts/marvell/armada-385-turris-omnia.dts | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
+@@ -112,6 +112,19 @@
+ status = "disabled";
+ };
+
++ gpio-keys {
++ compatible = "gpio-keys";
++
++ front-button {
++ label = "Front Button";
++ linux,code = <KEY_VENDOR>;
++ linux,can-disable;
++ gpios = <&mcu 0 12 GPIO_ACTIVE_HIGH>;
++ /* debouncing is done by the microcontroller */
++ debounce-interval = <0>;
++ };
++ };
++
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "SPDIF";
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch b/target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch
new file mode 100644
index 0000000000..80c9e1a3cc
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch
@@ -0,0 +1,32 @@
+From 08838657bbc35494276c7ba4ef53f30a9816f8c9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 8 Jul 2024 13:40:01 +0200
+Subject: [PATCH 09/11] platform: cznic: turris-omnia-mcu: Depend on OF
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add depend on OF, otherwise the compilation fails with
+ error: no member named 'of_gpio_n_cells' in 'struct gpio_chip'
+ error: no member named 'of_xlate' in 'struct gpio_chip'
+
+Fixes: dfa556e45ae9 ("platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202407031646.trNSwajF-lkp@intel.com/
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20240708114002.4285-2-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -16,6 +16,7 @@ config TURRIS_OMNIA_MCU
+ tristate "Turris Omnia MCU driver"
+ depends on MACH_ARMADA_38X || COMPILE_TEST
+ depends on I2C
++ depends on OF
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select HW_RANDOM
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch b/target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch
new file mode 100644
index 0000000000..50e028752a
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch
@@ -0,0 +1,32 @@
+From 5e425e6eca155c162da58d4e58e896ed4109c7fd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 8 Jul 2024 13:40:02 +0200
+Subject: [PATCH 10/11] platform: cznic: turris-omnia-mcu: Depend on WATCHDOG
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add depend on WATCHDOG, otherwise modpost fails with
+ ERROR: modpost: "watchdog_init_timeout" [drivers/platform/cznic/turris-omnia-mcu.ko] undefined!
+ ERROR: modpost: "devm_watchdog_register_device" [drivers/platform/cznic/turris-omnia-mcu.ko] undefined!
+
+Fixes: ab89fb5fb92c ("platform: cznic: turris-omnia-mcu: Add support for MCU watchdog")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202407040711.g19y3cWq-lkp@intel.com/
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20240708114002.4285-3-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -17,6 +17,7 @@ config TURRIS_OMNIA_MCU
+ depends on MACH_ARMADA_38X || COMPILE_TEST
+ depends on I2C
+ depends on OF
++ depends on WATCHDOG
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select HW_RANDOM
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch b/target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch
new file mode 100644
index 0000000000..30a476586e
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch
@@ -0,0 +1,45 @@
+From 24c68c2525de5fcd0f3b16b2ad1028fb13b53393 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 15 Jul 2024 08:02:30 +0200
+Subject: [PATCH 11/11] platform: cznic: turris-omnia-mcu: fix Kconfig
+ dependencies
+
+The newly added driver causes a Kconfig warning:
+
+WARNING: unmet direct dependencies detected for RTC_CLASS
+ Depends on [n]: !S390 [=y]
+ Selected by [m]:
+ - TURRIS_OMNIA_MCU [=m] && CZNIC_PLATFORMS [=y] && (MACH_ARMADA_38X || COMPILE_TEST [=y]) && I2C [=m] && OF [=y] && WATCHDOG [=y]
+
+The problem here is that it selects entire subsystems, which normal
+device drivers should not do. Changes all of these to 'depends on'
+instead.
+
+Fixes: dfa556e45ae9e ("platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs")
+Fixes: 90e700fd12b61 ("platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup")
+Fixes: ab89fb5fb92c7 ("platform: cznic: turris-omnia-mcu: Add support for MCU watchdog")
+Fixes: 41bb142a40289 ("platform: cznic: turris-omnia-mcu: Add support for MCU provided TRNG")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -18,11 +18,11 @@ config TURRIS_OMNIA_MCU
+ depends on I2C
+ depends on OF
+ depends on WATCHDOG
+- select GPIOLIB
++ depends on GPIOLIB
++ depends on HW_RANDOM
++ depends on RTC_CLASS
++ depends on WATCHDOG_CORE
+ select GPIOLIB_IRQCHIP
+- select HW_RANDOM
+- select RTC_CLASS
+- select WATCHDOG_CORE
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
diff --git a/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch b/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch
index 2a8397d0b5..dad8c16be1 100644
--- a/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch
+++ b/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch
@@ -16,7 +16,7 @@ Cc: Robert Marko <robert.marko@sartura.hr>
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -10138,6 +10138,22 @@ IFCVF VIRTIO DATA PATH ACCELERATOR
+@@ -10142,6 +10142,22 @@ IFCVF VIRTIO DATA PATH ACCELERATOR
R: Zhu Lingshan <lingshan.zhu@intel.com>
F: drivers/vdpa/ifcvf/
diff --git a/target/linux/octeon/Makefile b/target/linux/octeon/Makefile
index fa3da97579..c59b0af6a2 100644
--- a/target/linux/octeon/Makefile
+++ b/target/linux/octeon/Makefile
@@ -10,7 +10,7 @@ BOARDNAME:=Cavium Networks Octeon
FEATURES:=squashfs ramdisk pci usb
CPU_TYPE:=octeonplus
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Cavium Networks Octeon-based boards.
diff --git a/target/linux/octeon/base-files/lib/preinit/79_move_config b/target/linux/octeon/base-files/lib/preinit/79_move_config
index 01491500a0..db99e02ce8 100644
--- a/target/linux/octeon/base-files/lib/preinit/79_move_config
+++ b/target/linux/octeon/base-files/lib/preinit/79_move_config
@@ -4,28 +4,46 @@ move_config() {
. /lib/upgrade/common.sh
local device="$1"
+ local fstype="$2"
[ -n "$device" ] && [ -b "$device" ] && {
- mount -t vfat "$device" /mnt
+ mount -t "${fstype}" "$device" /mnt
[ -f "/mnt/$BACKUP_FILE" ] && mv -f "/mnt/$BACKUP_FILE" /
umount /mnt
}
}
+octeon_get_n821_disk() {
+ local partnum=$1
+ local MAJOR MINOR DEVNAME DEVTYPE
+ while read line; do
+ export -n "${line}"
+ done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
+ echo "/dev/${DEVNAME}${partnum}"
+}
+
octeon_move_config() {
. /lib/functions.sh
case "$(board_name)" in
erlite|\
ubnt,usg)
- move_config "/dev/sda1"
+ move_config "/dev/sda1" "vfat"
;;
itus,shield-router)
- move_config "/dev/mmcblk1p1"
+ move_config "/dev/mmcblk1p1" "vfat"
;;
- ubnt,edgerouter-4 | \
+ er|\
+ ubnt,edgerouter-4|\
ubnt,edgerouter-6p)
- move_config "/dev/mmcblk0p1"
+ move_config "/dev/mmcblk0p1" "vfat"
;;
+ cisco,vedge1000)
+ # Copy from the internal USB disk's first partition.
+ # It is resolved from the device path to not be dependent on which
+ # /dev/sd? path it is at, nor which UUID it happens to have.
+ move_config "$(octeon_get_n821_disk 1)" "ext2"
+ ;;
+
esac
}
diff --git a/target/linux/octeon/base-files/lib/upgrade/platform.sh b/target/linux/octeon/base-files/lib/upgrade/platform.sh
index 14b3eefe7e..b8a856712b 100755
--- a/target/linux/octeon/base-files/lib/upgrade/platform.sh
+++ b/target/linux/octeon/base-files/lib/upgrade/platform.sh
@@ -2,11 +2,21 @@
# Copyright (C) 2021 OpenWrt.org
#
+if [ -x /usr/sbin/blkid ]; then
+ RAMFS_COPY_BIN="/usr/sbin/blkid"
+fi
+
platform_get_rootfs() {
local rootfsdev
+ local rootpartuuid
if read cmdline < /proc/cmdline; then
case "$cmdline" in
+ *root=PARTUUID=*)
+ rootpartuuid="${cmdline##*root=PARTUUID=}"
+ rootpartuuid="${rootpartuuid%% *}"
+ rootfsdev="$(blkid -o device -t PARTUUID="${rootpartuuid}")"
+ ;;
*root=*)
rootfsdev="${cmdline##*root=}"
rootfsdev="${rootfsdev%% *}"
@@ -17,10 +27,20 @@ platform_get_rootfs() {
fi
}
+platform_get_n821_disk() {
+ local partnum=$1
+ local DEVNAME
+ while read line; do
+ export -n "${line}"
+ done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
+ echo "/dev/${DEVNAME}${partnum}"
+}
+
platform_copy_config_helper() {
local device=$1
+ local fstype=$2
- mount -t vfat "$device" /mnt
+ mount -t "${fstype}" "$device" /mnt
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
umount /mnt
}
@@ -29,14 +49,18 @@ platform_copy_config() {
case "$(board_name)" in
erlite|\
ubnt,usg)
- platform_copy_config_helper /dev/sda1
+ platform_copy_config_helper /dev/sda1 vfat
;;
itus,shield-router)
- platform_copy_config_helper /dev/mmcblk1p1
+ platform_copy_config_helper /dev/mmcblk1p1 vfat
;;
+ er|\
ubnt,edgerouter-4|\
ubnt,edgerouter-6p)
- platform_copy_config_helper /dev/mmcblk0p1
+ platform_copy_config_helper /dev/mmcblk0p1 vfat
+ ;;
+ cisco,vedge1000)
+ platform_copy_config_helper "$(platform_get_n821_disk 1)" ext2
;;
esac
}
@@ -60,14 +84,26 @@ platform_do_flash() {
echo "flashing Itus Kernel to /boot/$kernel (/dev/mmblk1p1)"
tar -Oxf $tar_file "$board_dir/kernel" > /boot/$kernel
else
- mount -t vfat /dev/$kernel /boot
+ if [ "${board}" = "cisco,vedge1000" ]; then
+ local rootpartuuid
+ rootpartuuid="$(/usr/sbin/blkid -o value -s PARTUUID "${rootfs}")"
+ if [ -n "${rootpartuuid}" ]; then
+ echo "setting root partition to PARTUUID=${rootpartuuid}"
+ fw_setenv bootcmd 'usb start; ext2load usb 0:1 $loadaddr vmlinux.64; bootoctlinux $loadaddr coremask=f endbootargs rootfstype=squashfs rootwait root=PARTUUID='"${rootpartuuid}"
+ else
+ echo "WARNING: unable to figure out root partition UUID, leaving bootcmd unchanged"
+ fi
+ mount -t ext2 "${kernel}" /boot
+ else
+ mount -t vfat "${kernel}" /boot
+ fi
[ -f /boot/vmlinux.64 -a ! -L /boot/vmlinux.64 ] && {
mv /boot/vmlinux.64 /boot/vmlinux.64.previous
mv /boot/vmlinux.64.md5 /boot/vmlinux.64.md5.previous
}
- echo "flashing kernel to /dev/$kernel"
+ echo "flashing kernel to $(awk '/\/boot/ {print $1}' /proc/mounts)"
tar xf $tar_file $board_dir/kernel -O > /boot/vmlinux.64
md5sum /boot/vmlinux.64 | cut -f1 -d " " > /boot/vmlinux.64.md5
fi
@@ -85,20 +121,27 @@ platform_do_upgrade() {
local rootfs="$(platform_get_rootfs)"
local kernel=
+ if [ ! -b "${rootfs}" ] && [ "${board}" = "cisco,vedge1000" ]; then
+ # Default to the built-in USB disk for N821
+ rootfs="$(platform_get_n821_disk 2)"
+ fi
[ -b "${rootfs}" ] || return 1
case "$board" in
er | \
ubnt,edgerouter-4 | \
ubnt,edgerouter-6p)
- kernel=mmcblk0p1
+ kernel=/dev/mmcblk0p1
;;
erlite|\
ubnt,usg)
- kernel=sda1
+ kernel=/dev/sda1
;;
itus,shield-router)
kernel=ItusrouterImage
;;
+ cisco,vedge1000)
+ kernel="$(platform_get_n821_disk 1)"
+ ;;
*)
return 1
esac
@@ -122,7 +165,8 @@ platform_check_image() {
itus,shield-router | \
ubnt,edgerouter-4 | \
ubnt,edgerouter-6p | \
- ubnt,usg)
+ ubnt,usg | \
+ cisco,vedge1000)
local kernel_length=$(tar xf $tar_file $board_dir/kernel -O | wc -c 2> /dev/null)
local rootfs_length=$(tar xf $tar_file $board_dir/root -O | wc -c 2> /dev/null)
[ "$kernel_length" = 0 -o "$rootfs_length" = 0 ] && {
diff --git a/target/linux/octeon/config-6.1 b/target/linux/octeon/config-6.1
deleted file mode 100644
index af5cdf4852..0000000000
--- a/target/linux/octeon/config-6.1
+++ /dev/null
@@ -1,274 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_AHCI_OCTEON=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS=12
-CONFIG_ARCH_MMAP_RND_BITS_MAX=18
-CONFIG_ARCH_MMAP_RND_BITS_MIN=12
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ATA=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BUILTIN_DTB=y
-CONFIG_CAVIUM_CN63XXP1=y
-CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=0
-CONFIG_CAVIUM_OCTEON_LOCK_L2=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB=y
-CONFIG_CAVIUM_OCTEON_SOC=y
-CONFIG_CAVIUM_RESERVE32=0
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLONE_BACKWARDS=y
-# CONFIG_COMMON_CLK is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_CAVIUM_OCTEON=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS64=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_FPU=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_HUGEPAGES=y
-CONFIG_CRAMFS=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-# CONFIG_CRYPTO_MD5_OCTEON is not set
-CONFIG_CRYPTO_RNG2=y
-# CONFIG_CRYPTO_SHA1_OCTEON is not set
-# CONFIG_CRYPTO_SHA256_OCTEON is not set
-# CONFIG_CRYPTO_SHA512_OCTEON is not set
-# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
-CONFIG_DEBUG_INFO_NONE=y
-CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_OCTEON_L2C=y
-CONFIG_EDAC_OCTEON_LMC=y
-CONFIG_EDAC_OCTEON_PC=y
-CONFIG_EDAC_OCTEON_PCI=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_F2FS_FS=y
-CONFIG_FAT_FS=y
-CONFIG_FIXED_PHY=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GLOB=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_OCTEON=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_OCTEON=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_OCTEON=y
-CONFIG_IMAGE_CMDLINE_HACK=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_CAVIUM=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_OCTEON=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_MIPS_ELF_APPENDED_DTB=y
-CONFIG_MIPS_FP_SUPPORT=y
-CONFIG_MIPS_L1_CACHE_SHIFT=7
-CONFIG_MIPS_L1_CACHE_SHIFT_7=y
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_NR_CPU_NR_MAP=1024
-CONFIG_MIPS_NR_CPU_NR_MAP_1024=y
-CONFIG_MIPS_PGD_C0_CONTEXT=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CAVIUM_OCTEON=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MODULES_USE_ELF_RELA=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NR_CPUS=16
-CONFIG_NR_CPUS_DEFAULT_64=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OCTEON_ETHERNET=y
-CONFIG_OCTEON_ILM=y
-CONFIG_OCTEON_MGMT_ETHERNET=y
-CONFIG_OCTEON_WDT=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_PATA_OCTEON_CF=y
-CONFIG_PATA_TIMINGS=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_RELAY=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_SATA_AHCI_PLATFORM=y
-CONFIG_SATA_HOST=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SECCOMP=y
-CONFIG_SECCOMP_FILTER=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPARSEMEM=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_OCTEON=y
-CONFIG_SRCU=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_CAVIUM_OCTEON=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_RELOCATABLE=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-# CONFIG_USB_OCTEON_EHCI is not set
-CONFIG_USB_OCTEON_HCD=y
-# CONFIG_USB_OCTEON_OHCI is not set
-CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PLATFORM=y
-CONFIG_USE_OF=y
-CONFIG_VFAT_FS=y
-CONFIG_VITESSE_PHY=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WEAK_ORDERING=y
-CONFIG_XPS=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
diff --git a/target/linux/octeon/config-6.6 b/target/linux/octeon/config-6.6
new file mode 100644
index 0000000000..724361d5ea
--- /dev/null
+++ b/target/linux/octeon/config-6.6
@@ -0,0 +1,283 @@
+CONFIG_64BIT=y
+CONFIG_AHCI_OCTEON=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MMAP_RND_BITS=12
+CONFIG_ARCH_MMAP_RND_BITS_MAX=18
+CONFIG_ARCH_MMAP_RND_BITS_MIN=12
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ATA=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUILTIN_DTB=y
+CONFIG_CAVIUM_CN63XXP1=y
+CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=0
+CONFIG_CAVIUM_OCTEON_LOCK_L2=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB=y
+CONFIG_CAVIUM_OCTEON_SOC=y
+CONFIG_CAVIUM_RESERVE32=0
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLONE_BACKWARDS=y
+# CONFIG_COMMON_CLK is not set
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_CAVIUM_OCTEON=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_DIEI=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_MIPS64=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_FPU=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_HUGEPAGES=y
+CONFIG_CRAMFS=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+# CONFIG_CRYPTO_MD5_OCTEON is not set
+# CONFIG_CRYPTO_SHA1_OCTEON is not set
+# CONFIG_CRYPTO_SHA256_OCTEON is not set
+# CONFIG_CRYPTO_SHA512_OCTEON is not set
+# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
+CONFIG_DEBUG_INFO_NONE=y
+CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EDAC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_LEGACY_SYSFS=y
+CONFIG_EDAC_OCTEON_L2C=y
+CONFIG_EDAC_OCTEON_LMC=y
+CONFIG_EDAC_OCTEON_PC=y
+CONFIG_EDAC_OCTEON_PCI=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_F2FS_FS=y
+CONFIG_FAT_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_OCTEON=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_OCTEON=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_OCTEON=y
+CONFIG_IMAGE_CMDLINE_HACK=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_LEGACY_DIRECT_IO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_CAVIUM=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_OCTEON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_MIPS_ELF_APPENDED_DTB=y
+CONFIG_MIPS_FP_SUPPORT=y
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+CONFIG_MIPS_L1_CACHE_SHIFT_7=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_NR_CPU_NR_MAP=1024
+CONFIG_MIPS_NR_CPU_NR_MAP_1024=y
+CONFIG_MIPS_PGD_C0_CONTEXT=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CAVIUM_OCTEON=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULES_USE_ELF_RELA=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_NR_CPUS=16
+CONFIG_NR_CPUS_DEFAULT_64=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OCTEON_ETHERNET=y
+CONFIG_OCTEON_ILM=y
+CONFIG_OCTEON_MGMT_ETHERNET=y
+CONFIG_OCTEON_WDT=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PATA_OCTEON_CF=y
+CONFIG_PATA_TIMINGS=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_RELAY=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_HOST=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_OCTEON=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_CAVIUM_OCTEON=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_RELOCATABLE=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_OCTEON_EHCI is not set
+CONFIG_USB_OCTEON_HCD=y
+# CONFIG_USB_OCTEON_OHCI is not set
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USE_OF=y
+CONFIG_VFAT_FS=y
+CONFIG_VITESSE_PHY=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_XPS=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
diff --git a/target/linux/octeon/image/Makefile b/target/linux/octeon/image/Makefile
index dcab815791..f00e87c520 100644
--- a/target/linux/octeon/image/Makefile
+++ b/target/linux/octeon/image/Makefile
@@ -42,7 +42,8 @@ define Device/itus_shield-router
endef
TARGET_DEVICES += itus_shield-router
-ER_CMDLINE:=-mtdparts=phys_mapped_flash:640k(boot0)ro,640k(boot1)ro,64k(eeprom)ro root=/dev/mmcblk0p2 rootfstype=squashfs,ext4 rootwait
+# Disable PCIe on ER as it doesn't have PCIe peripherals and some devices lock up on initialization
+ER_CMDLINE:=-mtdparts=phys_mapped_flash:640k(boot0)ro,640k(boot1)ro,64k(eeprom)ro root=/dev/mmcblk0p2 rootfstype=squashfs,ext4 rootwait pcie_octeon.pcie_disable=1
define Device/ubnt_edgerouter
DEVICE_VENDOR := Ubiquiti
DEVICE_MODEL := EdgeRouter
@@ -99,13 +100,16 @@ define Device/cisco_vedge1000
DEVICE_MODEL := vEdge 1000
BOARD_NAME := cisco,vedge1000
DEVICE_PACKAGES += \
+ blkid \
kmod-hwmon-jc42 \
kmod-hwmon-max6697 \
kmod-of-mdio \
kmod-rtc-ds1307 \
kmod-usb-dwc3 \
kmod-usb-storage-uas \
- kmod-usb3
+ kmod-usb3 \
+ sfdisk \
+ uboot-envtools
KERNEL := kernel-bin | append-dtb-elf
KERNEL_DEPENDS := $$(wildcard $(DTS_DIR)/$(DEVICE_DTS).dts)
DEVICE_DTS := cn6130_cisco_vedge1000
diff --git a/target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch b/target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch
deleted file mode 100644
index f63af640dd..0000000000
--- a/target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From: John Crispin <john@phrozen.org>
-Subject: hack: kernel: add generic image_cmdline hack to MIPS targets
-
-lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- arch/mips/Kconfig | 4 ++++
- arch/mips/kernel/head.S | 6 ++++++
- 2 files changed, 10 insertions(+)
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -1115,6 +1115,10 @@ config MIPS_MSC
- config SYNC_R4K
- bool
-
-+config IMAGE_CMDLINE_HACK
-+ bool "OpenWrt specific image command line hack"
-+ default n
-+
- config NO_IOPORT_MAP
- def_bool n
-
---- a/arch/mips/kernel/head.S
-+++ b/arch/mips/kernel/head.S
-@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
- j kernel_entry
- #endif /* CONFIG_BOOT_RAW */
-
-+#ifdef CONFIG_IMAGE_CMDLINE_HACK
-+ .ascii "CMDLINE:"
-+EXPORT(__image_cmdline)
-+ .fill 0x400
-+#endif /* CONFIG_IMAGE_CMDLINE_HACK */
-+
- __REF
-
- NESTED(kernel_entry, 16, sp) # kernel entry point
diff --git a/target/linux/octeon/patches-6.1/130-add_itus_support.patch b/target/linux/octeon/patches-6.1/130-add_itus_support.patch
deleted file mode 100644
index d76e8637ea..0000000000
--- a/target/linux/octeon/patches-6.1/130-add_itus_support.patch
+++ /dev/null
@@ -1,42 +0,0 @@
---- a/arch/mips/cavium-octeon/octeon-platform.c
-+++ b/arch/mips/cavium-octeon/octeon-platform.c
-@@ -774,7 +774,7 @@ int __init octeon_prune_device_tree(void
- if (fdt_check_header(initial_boot_params))
- panic("Corrupt Device Tree.");
-
-- WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_CUST_DSR1000N,
-+ WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_ITUS_SHIELD,
- "Built-in DTB booting is deprecated on %s. Please switch to use appended DTB.",
- cvmx_board_type_to_string(octeon_bootinfo->board_type));
-
---- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-@@ -298,7 +298,7 @@ enum cvmx_board_types_enum {
- CVMX_BOARD_TYPE_UBNT_E100 = 20002,
- CVMX_BOARD_TYPE_UBNT_E200 = 20003,
- CVMX_BOARD_TYPE_UBNT_E220 = 20005,
-- CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
-+ CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
- CVMX_BOARD_TYPE_UBNT_E300 = 20300,
- CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,
- CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
-@@ -403,7 +403,7 @@ static inline const char *cvmx_board_typ
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
-- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
-+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E300)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
---- a/arch/mips/pci/pci-octeon.c
-+++ b/arch/mips/pci/pci-octeon.c
-@@ -211,7 +211,7 @@ const char *octeon_get_pci_interrupts(vo
- return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
- case CVMX_BOARD_TYPE_BBGW_REF:
- return "AABCD";
-- case CVMX_BOARD_TYPE_CUST_DSR1000N:
-+ case CVMX_BOARD_TYPE_ITUS_SHIELD:
- return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
- case CVMX_BOARD_TYPE_THUNDER:
- case CVMX_BOARD_TYPE_EBH3000:
diff --git a/target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch b/target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch
deleted file mode 100644
index 00c268eda8..0000000000
--- a/target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch
+++ /dev/null
@@ -1,46 +0,0 @@
---- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-@@ -297,6 +297,7 @@ enum cvmx_board_types_enum {
- CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
- CVMX_BOARD_TYPE_UBNT_E100 = 20002,
- CVMX_BOARD_TYPE_UBNT_E200 = 20003,
-+ CVMX_BOARD_TYPE_UBNT_USG = 20004,
- CVMX_BOARD_TYPE_UBNT_E220 = 20005,
- CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
- CVMX_BOARD_TYPE_UBNT_E300 = 20300,
-@@ -401,6 +402,7 @@ static inline const char *cvmx_board_typ
- /* Customer private range */
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
-+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_USG)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
---- a/arch/mips/cavium-octeon/octeon-platform.c
-+++ b/arch/mips/cavium-octeon/octeon-platform.c
-@@ -635,6 +635,7 @@ static void __init octeon_rx_tx_delay(in
- }
- break;
- case CVMX_BOARD_TYPE_UBNT_E100:
-+ case CVMX_BOARD_TYPE_UBNT_USG:
- if (iface == 0 && port <= 2) {
- _octeon_rx_tx_delay(eth, 0x0, 0x10);
- return;
---- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
-+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
-@@ -170,6 +170,7 @@ int cvmx_helper_board_get_mii_address(in
- else
- return -1;
- case CVMX_BOARD_TYPE_UBNT_E100:
-+ case CVMX_BOARD_TYPE_UBNT_USG:
- if (ipd_port >= 0 && ipd_port <= 2)
- return 7 - ipd_port;
- else
-@@ -337,6 +338,7 @@ enum cvmx_helper_board_usb_clock_types _
- case CVMX_BOARD_TYPE_LANAI2_G:
- case CVMX_BOARD_TYPE_NIC10E_66:
- case CVMX_BOARD_TYPE_UBNT_E100:
-+ case CVMX_BOARD_TYPE_UBNT_USG:
- return USB_CLOCK_TYPE_CRYSTAL_12;
- case CVMX_BOARD_TYPE_NIC10E:
- return USB_CLOCK_TYPE_REF_12;
diff --git a/target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch b/target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch
new file mode 100644
index 0000000000..5a5cc21808
--- /dev/null
+++ b/target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch
@@ -0,0 +1,38 @@
+From: John Crispin <john@phrozen.org>
+Subject: hack: kernel: add generic image_cmdline hack to MIPS targets
+
+lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ arch/mips/Kconfig | 4 ++++
+ arch/mips/kernel/head.S | 6 ++++++
+ 2 files changed, 10 insertions(+)
+
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -1090,6 +1090,10 @@ config MIPS_MSC
+ config SYNC_R4K
+ bool
+
++config IMAGE_CMDLINE_HACK
++ bool "OpenWrt specific image command line hack"
++ default n
++
+ config NO_IOPORT_MAP
+ def_bool n
+
+--- a/arch/mips/kernel/head.S
++++ b/arch/mips/kernel/head.S
+@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
+ j kernel_entry
+ #endif /* CONFIG_BOOT_RAW */
+
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++ .ascii "CMDLINE:"
++EXPORT(__image_cmdline)
++ .fill 0x400
++#endif /* CONFIG_IMAGE_CMDLINE_HACK */
++
+ __REF
+
+ NESTED(kernel_entry, 16, sp) # kernel entry point
diff --git a/target/linux/octeon/patches-6.1/100-ubnt_edgerouter2_support.patch b/target/linux/octeon/patches-6.6/100-ubnt_edgerouter2_support.patch
index 606debda7f..606debda7f 100644
--- a/target/linux/octeon/patches-6.1/100-ubnt_edgerouter2_support.patch
+++ b/target/linux/octeon/patches-6.6/100-ubnt_edgerouter2_support.patch
diff --git a/target/linux/octeon/patches-6.1/110-er200-ethernet_probe_order.patch b/target/linux/octeon/patches-6.6/110-er200-ethernet_probe_order.patch
index 133e167d2c..133e167d2c 100644
--- a/target/linux/octeon/patches-6.1/110-er200-ethernet_probe_order.patch
+++ b/target/linux/octeon/patches-6.6/110-er200-ethernet_probe_order.patch
diff --git a/target/linux/octeon/patches-6.1/120-cmdline-hack.patch b/target/linux/octeon/patches-6.6/120-cmdline-hack.patch
index e65cf78da4..e65cf78da4 100644
--- a/target/linux/octeon/patches-6.1/120-cmdline-hack.patch
+++ b/target/linux/octeon/patches-6.6/120-cmdline-hack.patch
diff --git a/target/linux/octeon/patches-6.6/130-add_itus_support.patch b/target/linux/octeon/patches-6.6/130-add_itus_support.patch
new file mode 100644
index 0000000000..cf841c613e
--- /dev/null
+++ b/target/linux/octeon/patches-6.6/130-add_itus_support.patch
@@ -0,0 +1,42 @@
+--- a/arch/mips/cavium-octeon/octeon-platform.c
++++ b/arch/mips/cavium-octeon/octeon-platform.c
+@@ -775,7 +775,7 @@ int __init octeon_prune_device_tree(void
+ if (fdt_check_header(initial_boot_params))
+ panic("Corrupt Device Tree.");
+
+- WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_CUST_DSR1000N,
++ WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_ITUS_SHIELD,
+ "Built-in DTB booting is deprecated on %s. Please switch to use appended DTB.",
+ cvmx_board_type_to_string(octeon_bootinfo->board_type));
+
+--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
++++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
+@@ -298,7 +298,7 @@ enum cvmx_board_types_enum {
+ CVMX_BOARD_TYPE_UBNT_E100 = 20002,
+ CVMX_BOARD_TYPE_UBNT_E200 = 20003,
+ CVMX_BOARD_TYPE_UBNT_E220 = 20005,
+- CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
++ CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
+ CVMX_BOARD_TYPE_UBNT_E300 = 20300,
+ CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
+@@ -403,7 +403,7 @@ static inline const char *cvmx_board_typ
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
+- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
++ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E300)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
+--- a/arch/mips/pci/pci-octeon.c
++++ b/arch/mips/pci/pci-octeon.c
+@@ -211,7 +211,7 @@ const char *octeon_get_pci_interrupts(vo
+ return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ case CVMX_BOARD_TYPE_BBGW_REF:
+ return "AABCD";
+- case CVMX_BOARD_TYPE_CUST_DSR1000N:
++ case CVMX_BOARD_TYPE_ITUS_SHIELD:
+ return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
+ case CVMX_BOARD_TYPE_THUNDER:
+ case CVMX_BOARD_TYPE_EBH3000:
diff --git a/target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch b/target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch
new file mode 100644
index 0000000000..dd69f728a1
--- /dev/null
+++ b/target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch
@@ -0,0 +1,46 @@
+--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
++++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
+@@ -297,6 +297,7 @@ enum cvmx_board_types_enum {
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
+ CVMX_BOARD_TYPE_UBNT_E100 = 20002,
+ CVMX_BOARD_TYPE_UBNT_E200 = 20003,
++ CVMX_BOARD_TYPE_UBNT_USG = 20004,
+ CVMX_BOARD_TYPE_UBNT_E220 = 20005,
+ CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
+ CVMX_BOARD_TYPE_UBNT_E300 = 20300,
+@@ -401,6 +402,7 @@ static inline const char *cvmx_board_typ
+ /* Customer private range */
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
++ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_USG)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
+--- a/arch/mips/cavium-octeon/octeon-platform.c
++++ b/arch/mips/cavium-octeon/octeon-platform.c
+@@ -636,6 +636,7 @@ static void __init octeon_rx_tx_delay(in
+ }
+ break;
+ case CVMX_BOARD_TYPE_UBNT_E100:
++ case CVMX_BOARD_TYPE_UBNT_USG:
+ if (iface == 0 && port <= 2) {
+ _octeon_rx_tx_delay(eth, 0x0, 0x10);
+ return;
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+@@ -170,6 +170,7 @@ int cvmx_helper_board_get_mii_address(in
+ else
+ return -1;
+ case CVMX_BOARD_TYPE_UBNT_E100:
++ case CVMX_BOARD_TYPE_UBNT_USG:
+ if (ipd_port >= 0 && ipd_port <= 2)
+ return 7 - ipd_port;
+ else
+@@ -337,6 +338,7 @@ enum cvmx_helper_board_usb_clock_types _
+ case CVMX_BOARD_TYPE_LANAI2_G:
+ case CVMX_BOARD_TYPE_NIC10E_66:
+ case CVMX_BOARD_TYPE_UBNT_E100:
++ case CVMX_BOARD_TYPE_UBNT_USG:
+ return USB_CLOCK_TYPE_CRYSTAL_12;
+ case CVMX_BOARD_TYPE_NIC10E:
+ return USB_CLOCK_TYPE_REF_12;
diff --git a/target/linux/octeon/patches-6.1/700-allocate_interface_by_label.patch b/target/linux/octeon/patches-6.6/700-allocate_interface_by_label.patch
index 22f284b2c0..22f284b2c0 100644
--- a/target/linux/octeon/patches-6.1/700-allocate_interface_by_label.patch
+++ b/target/linux/octeon/patches-6.6/700-allocate_interface_by_label.patch
diff --git a/target/linux/octeon/patches-6.1/701-honor_sgmii_node_device_tree_status.patch b/target/linux/octeon/patches-6.6/701-honor_sgmii_node_device_tree_status.patch
index fdfbc233ab..fdfbc233ab 100644
--- a/target/linux/octeon/patches-6.1/701-honor_sgmii_node_device_tree_status.patch
+++ b/target/linux/octeon/patches-6.6/701-honor_sgmii_node_device_tree_status.patch
diff --git a/target/linux/omap/Makefile b/target/linux/omap/Makefile
index fc0842d056..67db2aa07d 100644
--- a/target/linux/omap/Makefile
+++ b/target/linux/omap/Makefile
@@ -7,12 +7,12 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=omap
BOARDNAME:=TI OMAP3/4/AM33xx
-FEATURES:=usb usbgadget ext4 targz fpu audio display nand rootfs-part squashfs source-only
+FEATURES:=usb usbgadget ext4 targz fpu audio display nand rootfs-part squashfs
CPU_TYPE:=cortex-a8
CPU_SUBTYPE:=vfpv3
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
KERNELNAME:=zImage dtbs
diff --git a/target/linux/omap/config-6.1 b/target/linux/omap/config-6.1
deleted file mode 100644
index d5ed19afe1..0000000000
--- a/target/linux/omap/config-6.1
+++ /dev/null
@@ -1,711 +0,0 @@
-# CONFIG_AHCI_DM816 is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_AM335X_CONTROL_USB=y
-CONFIG_AM335X_PHY_USB=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP2PLUS=y
-CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
-CONFIG_ARCH_OMAP3=y
-CONFIG_ARCH_OMAP4=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_ARM_CPUIDLE=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_ERRATA_430973=y
-CONFIG_ARM_ERRATA_720789=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_OMAP2PLUS_CPUFREQ=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_TI_CPUFREQ=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ASSOCIATIVE_ARRAY=y
-CONFIG_AT803X_PHY=y
-CONFIG_ATA=y
-CONFIG_AUDIT=y
-CONFIG_AUDITSYSCALL=y
-CONFIG_AUDIT_GENERIC=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_TPS65217 is not set
-CONFIG_BCH=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEC_CORE=y
-# CONFIG_CHARGER_TPS65217 is not set
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLKSRC_TI_32K=y
-CONFIG_CLK_TWL6040=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_COMMON_CLK=y
-# CONFIG_COMMON_CLK_PALMAS is not set
-# CONFIG_COMMON_CLK_TI_ADPLL is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONNECTOR=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-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_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRAMFS=y
-CONFIG_CRC16=y
-CONFIG_CRC7=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRC_T10DIF=y
-CONFIG_CRYPTO_AES_ARM=y
-CONFIG_CRYPTO_AES_ARM_BS=y
-CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_CHACHA20_NEON=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRCT10DIF=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_OMAP=y
-CONFIG_CRYPTO_DEV_OMAP_AES=y
-CONFIG_CRYPTO_DEV_OMAP_DES=y
-CONFIG_CRYPTO_DEV_OMAP_SHAM=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ENGINE=y
-CONFIG_CRYPTO_GHASH_ARM_CE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_SEQIV=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA1_ARM=y
-CONFIG_CRYPTO_SHA1_ARM_NEON=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA256_ARM=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_SHA512_ARM=y
-CONFIG_CRYPTO_SIMD=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DDR=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DMADEVICES=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OMAP=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DNS_RESOLVER=y
-CONFIG_DRM=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_DISPLAY_CONNECTOR=y
-CONFIG_DRM_KMS_HELPER=y
-CONFIG_DRM_MIPI_DSI=y
-CONFIG_DRM_NOMODESET=y
-CONFIG_DRM_OMAP=y
-CONFIG_DRM_PANEL=y
-CONFIG_DRM_PANEL_BRIDGE=y
-CONFIG_DRM_PANEL_LG_LB035Q02=y
-CONFIG_DRM_PANEL_NEC_NL8048HL11=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DRM_PANEL_SHARP_LS037V7DW01=y
-CONFIG_DRM_PANEL_SONY_ACX565AKM=y
-CONFIG_DRM_PANEL_TPO_TD028TTEC1=y
-CONFIG_DRM_PANEL_TPO_TD043MTEA1=y
-CONFIG_DRM_SIMPLE_BRIDGE=y
-CONFIG_DRM_TI_TFP410=y
-CONFIG_DRM_TI_TPD12S015=y
-CONFIG_DTC=y
-CONFIG_DT_IDLE_STATES=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_93CX6=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXTCON=y
-CONFIG_EXTCON_PALMAS=y
-CONFIG_EXTCON_USB_GPIO=y
-CONFIG_F2FS_FS=y
-CONFIG_FANOTIFY=y
-CONFIG_FAT_FS=y
-CONFIG_FB_CMDLINE=y
-CONFIG_FHANDLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=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_GENERIC_VDSO_32=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_OMAP=y
-CONFIG_GPIO_PALMAS=y
-CONFIG_GPIO_PCA953X=y
-CONFIG_GPIO_PCA953X_IRQ=y
-CONFIG_GPIO_PCF857X=y
-# CONFIG_GPIO_TPS65218 is not set
-CONFIG_GPIO_TPS65910=y
-CONFIG_GPIO_TWL4030=y
-CONFIG_GPIO_TWL6040=y
-CONFIG_GRACE_PERIOD=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HDMI=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HSI=y
-CONFIG_HSI_BOARDINFO=y
-# CONFIG_HSI_CHAR is not set
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_OMAP=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_OMAP=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_KCMP=y
-CONFIG_KEYS=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_KPROBES=y
-CONFIG_KRETPROBES=y
-CONFIG_KS8851=y
-CONFIG_KS8851_MLL=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_PLATFORM=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_PWM=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
-CONFIG_LEDS_TRIGGER_CPU=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_ONESHOT=y
-CONFIG_LIBCRC32C=y
-CONFIG_LIBFDT=y
-CONFIG_LOCKD=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-# CONFIG_MDIO_GPIO is not set
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_PALMAS=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MFD_TI_AM335X_TSCADC=y
-CONFIG_MFD_TPS65217=y
-CONFIG_MFD_TPS65218=y
-CONFIG_MFD_TPS65910=y
-CONFIG_MFD_TWL4030_AUDIO=y
-CONFIG_MICREL_PHY=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-# CONFIG_MMC_OMAP is not set
-CONFIG_MMC_OMAP_HS=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_EXTERNAL_DMA=y
-CONFIG_MMC_SDHCI_OMAP=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MSDOS_FS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_OMAP2=y
-CONFIG_MTD_NAND_OMAP_BCH=y
-CONFIG_MTD_NAND_OMAP_BCH_BUILD=y
-CONFIG_MTD_ONENAND=y
-# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
-# CONFIG_MTD_ONENAND_GENERIC is not set
-CONFIG_MTD_ONENAND_OMAP2=y
-# CONFIG_MTD_ONENAND_OTP is not set
-CONFIG_MTD_ONENAND_VERIFY_WRITE=y
-CONFIG_MTD_OOPS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-# CONFIG_MTD_UBI_BLOCK is not set
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEON=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NFS_ACL_SUPPORT=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_USE_KERNEL_DNS=y
-# CONFIG_NFS_USE_LEGACY_DNS is not set
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_OID_REGISTRY=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OMAP2_DSS_DPI=y
-CONFIG_OMAP2_DSS_DSI=y
-CONFIG_OMAP2_DSS_HDMI_COMMON=y
-CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
-CONFIG_OMAP2_DSS_SDI=y
-CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
-CONFIG_OMAP2_DSS_VENC=y
-# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set
-# CONFIG_OMAP3_SDRC_AC_TIMING is not set
-CONFIG_OMAP3_THERMAL=y
-CONFIG_OMAP4_DSS_HDMI=y
-CONFIG_OMAP4_DSS_HDMI_CEC=y
-CONFIG_OMAP4_THERMAL=y
-CONFIG_OMAP5_DSS_HDMI=y
-CONFIG_OMAP_CONTROL_PHY=y
-CONFIG_OMAP_DM_SYSTIMER=y
-CONFIG_OMAP_DM_TIMER=y
-CONFIG_OMAP_GPMC=y
-# CONFIG_OMAP_GPMC_DEBUG is not set
-CONFIG_OMAP_HWMOD=y
-CONFIG_OMAP_INTERCONNECT=y
-CONFIG_OMAP_INTERCONNECT_BARRIER=y
-CONFIG_OMAP_IRQCHIP=y
-CONFIG_OMAP_OCP2SCP=y
-# CONFIG_OMAP_SSI is not set
-CONFIG_OMAP_USB2=y
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_OPTPROBES=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-# CONFIG_PHY_DM816X_USB is not set
-CONFIG_PHY_TI_GMII_SEL=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_PALMAS is not set
-CONFIG_PL310_ERRATA_588369=y
-CONFIG_PL310_ERRATA_727915=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_PM_OPP=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_POWER_AVS_OMAP=y
-CONFIG_POWER_AVS_OMAP_CLASS3=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PRINT_QUOTA_WARNING=y
-CONFIG_PROC_EVENTS=y
-CONFIG_PROFILING=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-# CONFIG_PWM_OMAP_DMTIMER is not set
-CONFIG_PWM_SYSFS=y
-CONFIG_PWM_TIECAP=y
-CONFIG_PWM_TIEHRPWM=y
-# CONFIG_PWM_TWL is not set
-# CONFIG_PWM_TWL_LED is not set
-CONFIG_QCOM_NET_PHYLIB=y
-CONFIG_QFMT_V2=y
-CONFIG_QUOTA=y
-CONFIG_QUOTACTL=y
-CONFIG_QUOTA_TREE=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_IRQ=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_PALMAS=y
-CONFIG_REGULATOR_PBIAS=y
-CONFIG_REGULATOR_TI_ABB=y
-CONFIG_REGULATOR_TPS62360=y
-CONFIG_REGULATOR_TPS65023=y
-CONFIG_REGULATOR_TPS6507X=y
-CONFIG_REGULATOR_TPS65217=y
-CONFIG_REGULATOR_TPS65218=y
-CONFIG_REGULATOR_TPS65910=y
-CONFIG_REGULATOR_TWL4030=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_ROOT_NFS=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_RTC_DRV_PALMAS=y
-# CONFIG_RTC_DRV_TPS65910 is not set
-CONFIG_RTC_DRV_TWL4030=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SATA_AHCI_PLATFORM=y
-CONFIG_SATA_HOST=y
-CONFIG_SCHEDSTATS=y
-CONFIG_SCHED_INFO=y
-CONFIG_SCHED_MC=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_SDIO_UART=y
-CONFIG_SECCOMP=y
-CONFIG_SECCOMP_FILTER=y
-CONFIG_SENSORS_GPIO_FAN=y
-CONFIG_SENSORS_LM75=y
-CONFIG_SENSORS_TMP102=y
-CONFIG_SENSORS_TSL2550=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-# CONFIG_SERIAL_8250_OMAP is not set
-CONFIG_SERIAL_8250_RSA=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_OMAP=y
-CONFIG_SERIAL_OMAP_CONSOLE=y
-CONFIG_SERIO=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SG_SPLIT=y
-CONFIG_SKB_EXTENSIONS=y
-CONFIG_SMC91X=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SMSC911X=y
-CONFIG_SMSC_PHY=y
-CONFIG_SND=y
-# CONFIG_SND_COMPRESS_OFFLOAD is not set
-CONFIG_SND_DMAENGINE_PCM=y
-CONFIG_SND_JACK=y
-CONFIG_SND_PCM=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SIMPLE_CARD=y
-CONFIG_SND_SIMPLE_CARD_UTILS=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_DAVINCI_MCASP=y
-CONFIG_SND_SOC_DMIC=y
-CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SOC_NOKIA_RX51 is not set
-# CONFIG_SND_SOC_OMAP3_PANDORA is not set
-CONFIG_SND_SOC_OMAP3_TWL4030=y
-CONFIG_SND_SOC_OMAP_ABE_TWL6040=y
-CONFIG_SND_SOC_OMAP_DMIC=y
-CONFIG_SND_SOC_OMAP_HDMI=y
-CONFIG_SND_SOC_OMAP_MCBSP=y
-CONFIG_SND_SOC_OMAP_MCPDM=y
-CONFIG_SND_SOC_TI_EDMA_PCM=y
-CONFIG_SND_SOC_TI_SDMA_PCM=y
-CONFIG_SND_SOC_TI_UDMA_PCM=y
-CONFIG_SND_SOC_TWL4030=y
-CONFIG_SND_SOC_TWL6040=y
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_AM33XX=y
-CONFIG_SOC_AM43XX=y
-CONFIG_SOC_BUS=y
-CONFIG_SOC_HAS_OMAP2_SDRC=y
-CONFIG_SOC_OMAP3430=y
-# CONFIG_SOC_TI81XX is not set
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SOUND_OSS_CORE_PRECLAIM=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_OMAP24XX=y
-CONFIG_SPI_TI_QSPI=y
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-CONFIG_SUNRPC=y
-CONFIG_SUNRPC_GSS=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_FAIR_SHARE=y
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_GOV_USER_SPACE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TI_CPPI41=y
-CONFIG_TI_CPSW=y
-CONFIG_TI_CPSW_SWITCHDEV=y
-CONFIG_TI_CPTS=y
-CONFIG_TI_DAVINCI_EMAC=y
-CONFIG_TI_DAVINCI_MDIO=y
-CONFIG_TI_DMA_CROSSBAR=y
-CONFIG_TI_EDMA=y
-CONFIG_TI_EMIF=y
-# CONFIG_TI_EMIF_SRAM is not set
-CONFIG_TI_PIPE3=y
-CONFIG_TI_PWMSS=y
-CONFIG_TI_SOC_THERMAL=y
-CONFIG_TI_SYSC=y
-CONFIG_TI_THERMAL=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_TWL4030_CORE=y
-CONFIG_TWL4030_POWER=y
-CONFIG_TWL4030_USB=y
-CONFIG_TWL4030_WATCHDOG=y
-# CONFIG_TWL6030_USB is not set
-CONFIG_TWL6040_CORE=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_DWC3=y
-CONFIG_USB_DWC3_DUAL_ROLE=y
-# CONFIG_USB_DWC3_GADGET is not set
-# CONFIG_USB_DWC3_HOST is not set
-CONFIG_USB_DWC3_OMAP=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_OMAP=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_INVENTRA_DMA=y
-CONFIG_USB_MUSB_AM35X=y
-CONFIG_USB_MUSB_DSPS=y
-CONFIG_USB_MUSB_DUAL_ROLE=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_OMAP2PLUS=y
-CONFIG_USB_MUSB_TUSB6010=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_TI_CPPI41_DMA=y
-CONFIG_USB_TUSB_OMAP_DMA=y
-CONFIG_USE_OF=y
-CONFIG_VFAT_FS=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VIDEOMODE_HELPERS=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XFRM_ALGO=y
-CONFIG_XFRM_MIGRATE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/omap/config-6.6 b/target/linux/omap/config-6.6
new file mode 100644
index 0000000000..f85a68f0aa
--- /dev/null
+++ b/target/linux/omap/config-6.6
@@ -0,0 +1,720 @@
+# CONFIG_AHCI_DM816 is not set
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_AM335X_CONTROL_USB=y
+CONFIG_AM335X_PHY_USB=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
+CONFIG_ARCH_OMAP=y
+CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
+CONFIG_ARCH_OMAP3=y
+CONFIG_ARCH_OMAP4=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_OMAP2PLUS_CPUFREQ=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_TI_CPUFREQ=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_AT803X_PHY=y
+CONFIG_ATA=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_TPS65217 is not set
+CONFIG_BCH=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_PM=y
+CONFIG_BOUNCE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CEC_CORE=y
+# CONFIG_CHARGER_TPS65217 is not set
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_TI_32K=y
+CONFIG_CLK_TWL6040=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=16
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SYSFS is not set
+CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_COMMON_CLK=y
+# CONFIG_COMMON_CLK_PALMAS is not set
+# CONFIG_COMMON_CLK_TI_ADPLL is not set
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONNECTOR=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+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_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRAMFS=y
+CONFIG_CRC16=y
+CONFIG_CRC7=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRYPTO_AES_ARM=y
+CONFIG_CRYPTO_AES_ARM_BS=y
+CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CHACHA20_NEON=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CRCT10DIF=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_DEV_OMAP=y
+CONFIG_CRYPTO_DEV_OMAP_AES=y
+CONFIG_CRYPTO_DEV_OMAP_DES=y
+CONFIG_CRYPTO_DEV_OMAP_SHAM=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ENGINE=y
+CONFIG_CRYPTO_GENIV=y
+CONFIG_CRYPTO_GHASH_ARM_CE=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_DES=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+# CONFIG_CRYPTO_MANAGER_EXTRA_TESTS is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_ARM=y
+CONFIG_CRYPTO_SHA1_ARM_NEON=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA256_ARM=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SHA512_ARM=y
+CONFIG_CRYPTO_SIG2=y
+CONFIG_CRYPTO_SIMD=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DDR=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DMADEVICES=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OMAP=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DNS_RESOLVER=y
+CONFIG_DRM=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_DISPLAY_CONNECTOR=y
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_MIPI_DSI=y
+CONFIG_DRM_OMAP=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_LG_LB035Q02=y
+CONFIG_DRM_PANEL_NEC_NL8048HL11=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DRM_PANEL_SHARP_LS037V7DW01=y
+CONFIG_DRM_PANEL_SONY_ACX565AKM=y
+CONFIG_DRM_PANEL_TPO_TD028TTEC1=y
+CONFIG_DRM_PANEL_TPO_TD043MTEA1=y
+CONFIG_DRM_SIMPLE_BRIDGE=y
+CONFIG_DRM_TI_TFP410=y
+CONFIG_DRM_TI_TPD12S015=y
+CONFIG_DTC=y
+CONFIG_DT_IDLE_STATES=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_93CX6=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_EXTCON_PALMAS=y
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_F2FS_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_FAT_FS=y
+CONFIG_FHANDLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=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_GENERIC_VDSO_32=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_OMAP=y
+CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCF857X=y
+# CONFIG_GPIO_TPS65218 is not set
+CONFIG_GPIO_TPS65910=y
+CONFIG_GPIO_TWL4030=y
+CONFIG_GPIO_TWL6040=y
+CONFIG_GRACE_PERIOD=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_SMP=y
+CONFIG_HDMI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HSI=y
+CONFIG_HSI_BOARDINFO=y
+# CONFIG_HSI_CHAR is not set
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_OMAP=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_OMAP=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KCMP=y
+CONFIG_KEYS=y
+CONFIG_KMAP_LOCAL=y
+CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_KS8851=y
+CONFIG_KS8851_MLL=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEGACY_DIRECT_IO=y
+CONFIG_LIBCRC32C=y
+CONFIG_LIBFDT=y
+CONFIG_LOCKD=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACH_OMAP_GENERIC=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_MEMORY=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_TI_AM335X_TSCADC=y
+CONFIG_MFD_TPS65217=y
+CONFIG_MFD_TPS65218=y
+CONFIG_MFD_TPS65910=y
+CONFIG_MFD_TWL4030_AUDIO=y
+CONFIG_MICREL_PHY=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_EXTERNAL_DMA=y
+CONFIG_MMC_SDHCI_OMAP=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MSDOS_FS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_BCH=y
+CONFIG_MTD_NAND_OMAP_BCH_BUILD=y
+CONFIG_MTD_ONENAND=y
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_GENERIC is not set
+CONFIG_MTD_ONENAND_OMAP2=y
+# CONFIG_MTD_ONENAND_OTP is not set
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+CONFIG_MTD_OOPS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_BLOCK is not set
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NEON=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_HANDSHAKE=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_USE_KERNEL_DNS=y
+# CONFIG_NFS_USE_LEGACY_DNS is not set
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_OID_REGISTRY=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OMAP2_DSS_DPI=y
+CONFIG_OMAP2_DSS_DSI=y
+CONFIG_OMAP2_DSS_HDMI_COMMON=y
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_OMAP2_DSS_SDI=y
+CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
+CONFIG_OMAP2_DSS_VENC=y
+# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set
+CONFIG_OMAP3_THERMAL=y
+CONFIG_OMAP4_DSS_HDMI=y
+CONFIG_OMAP4_DSS_HDMI_CEC=y
+CONFIG_OMAP4_THERMAL=y
+CONFIG_OMAP5_DSS_HDMI=y
+CONFIG_OMAP_CONTROL_PHY=y
+CONFIG_OMAP_DM_SYSTIMER=y
+CONFIG_OMAP_DM_TIMER=y
+CONFIG_OMAP_GPMC=y
+# CONFIG_OMAP_GPMC_DEBUG is not set
+CONFIG_OMAP_HWMOD=y
+CONFIG_OMAP_INTERCONNECT=y
+CONFIG_OMAP_INTERCONNECT_BARRIER=y
+CONFIG_OMAP_IRQCHIP=y
+CONFIG_OMAP_OCP2SCP=y
+# CONFIG_OMAP_SSI is not set
+CONFIG_OMAP_USB2=y
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_OPTPROBES=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+# CONFIG_PHY_DM816X_USB is not set
+CONFIG_PHY_TI_GMII_SEL=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_PALMAS is not set
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_OPP=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_POWER_AVS_OMAP=y
+CONFIG_POWER_AVS_OMAP_CLASS3=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_EVENTS=y
+CONFIG_PROFILING=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+# CONFIG_PWM_OMAP_DMTIMER is not set
+CONFIG_PWM_SYSFS=y
+CONFIG_PWM_TIECAP=y
+CONFIG_PWM_TIEHRPWM=y
+# CONFIG_PWM_TWL is not set
+# CONFIG_PWM_TWL_LED is not set
+CONFIG_QCOM_NET_PHYLIB=y
+CONFIG_QFMT_V2=y
+CONFIG_QUOTA=y
+CONFIG_QUOTACTL=y
+CONFIG_QUOTA_TREE=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_IRQ=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_PALMAS=y
+CONFIG_REGULATOR_PBIAS=y
+CONFIG_REGULATOR_TI_ABB=y
+CONFIG_REGULATOR_TPS62360=y
+CONFIG_REGULATOR_TPS65023=y
+CONFIG_REGULATOR_TPS6507X=y
+CONFIG_REGULATOR_TPS65217=y
+CONFIG_REGULATOR_TPS65218=y
+CONFIG_REGULATOR_TPS65910=y
+CONFIG_REGULATOR_TWL4030=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_ROOT_NFS=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_OMAP=y
+CONFIG_RTC_DRV_PALMAS=y
+# CONFIG_RTC_DRV_TPS65910 is not set
+CONFIG_RTC_DRV_TWL4030=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_HOST=y
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_INFO=y
+CONFIG_SCHED_MC=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SDIO_UART=y
+CONFIG_SECCOMP=y
+CONFIG_SECCOMP_FILTER=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SENSORS_TMP102=y
+CONFIG_SENSORS_TSL2550=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+# CONFIG_SERIAL_8250_OMAP is not set
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
+CONFIG_SERIO=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SG_SPLIT=y
+CONFIG_SKB_EXTENSIONS=y
+CONFIG_SMC91X=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SMSC911X=y
+CONFIG_SMSC_PHY=y
+CONFIG_SND=y
+# CONFIG_SND_COMPRESS_OFFLOAD is not set
+CONFIG_SND_DMAENGINE_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_PCM=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_SND_SIMPLE_CARD_UTILS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_DAVINCI_MCASP=y
+CONFIG_SND_SOC_DMIC=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_NOKIA_RX51 is not set
+# CONFIG_SND_SOC_OMAP3_PANDORA is not set
+CONFIG_SND_SOC_OMAP3_TWL4030=y
+CONFIG_SND_SOC_OMAP_ABE_TWL6040=y
+CONFIG_SND_SOC_OMAP_DMIC=y
+CONFIG_SND_SOC_OMAP_HDMI=y
+CONFIG_SND_SOC_OMAP_MCBSP=y
+CONFIG_SND_SOC_OMAP_MCPDM=y
+CONFIG_SND_SOC_TI_EDMA_PCM=y
+CONFIG_SND_SOC_TI_SDMA_PCM=y
+CONFIG_SND_SOC_TI_UDMA_PCM=y
+CONFIG_SND_SOC_TWL4030=y
+CONFIG_SND_SOC_TWL6040=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_AM33XX=y
+CONFIG_SOC_AM43XX=y
+CONFIG_SOC_BUS=y
+CONFIG_SOC_HAS_OMAP2_SDRC=y
+CONFIG_SOC_OMAP3430=y
+# CONFIG_SOC_TI81XX is not set
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_OMAP24XX=y
+CONFIG_SPI_TI_QSPI=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SRAM=y
+CONFIG_SRAM_EXEC=y
+CONFIG_STACKTRACE=y
+CONFIG_SUNRPC=y
+CONFIG_SWPHY=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TI_CPPI41=y
+CONFIG_TI_CPSW=y
+CONFIG_TI_CPSW_SWITCHDEV=y
+CONFIG_TI_CPTS=y
+CONFIG_TI_DAVINCI_EMAC=y
+CONFIG_TI_DAVINCI_MDIO=y
+CONFIG_TI_DMA_CROSSBAR=y
+CONFIG_TI_EDMA=y
+CONFIG_TI_EMIF=y
+# CONFIG_TI_EMIF_SRAM is not set
+CONFIG_TI_PIPE3=y
+CONFIG_TI_PWMSS=y
+CONFIG_TI_SOC_THERMAL=y
+CONFIG_TI_SYSC=y
+CONFIG_TI_THERMAL=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TWL4030_CORE=y
+CONFIG_TWL4030_POWER=y
+CONFIG_TWL4030_USB=y
+CONFIG_TWL4030_WATCHDOG=y
+# CONFIG_TWL6030_USB is not set
+CONFIG_TWL6040_CORE=y
+CONFIG_UBIFS_FS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_DUAL_ROLE=y
+# CONFIG_USB_DWC3_GADGET is not set
+# CONFIG_USB_DWC3_HOST is not set
+CONFIG_USB_DWC3_OMAP=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_OMAP=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_INVENTRA_DMA=y
+CONFIG_USB_MUSB_DSPS=y
+CONFIG_USB_MUSB_DUAL_ROLE=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_OMAP2PLUS=y
+CONFIG_USB_MUSB_TUSB6010=y
+CONFIG_USB_PHY=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_TI_CPPI41_DMA=y
+CONFIG_USB_TUSB_OMAP_DMA=y
+CONFIG_USE_OF=y
+CONFIG_VFAT_FS=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VIDEOMODE_HELPERS=y
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_VIDEO_NOMODESET=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/omap/image/Makefile b/target/linux/omap/image/Makefile
index 507c91b2cc..591628c53f 100644
--- a/target/linux/omap/image/Makefile
+++ b/target/linux/omap/image/Makefile
@@ -33,6 +33,7 @@ define Device/Default
PROFILES := Default
KERNEL_NAME := zImage
KERNEL := kernel-bin
+ DTS_DIR := $(DTS_DIR)/ti/omap
DEVICE_DTS = $(lastword $(subst _, ,$(1)))
IMAGES := sdcard.img.gz
IMAGE/sdcard.img.gz := omap-sdcard | append-metadata | gzip
diff --git a/target/linux/omap/patches-6.6/900-use-cpsw-ethernet-driver.patch b/target/linux/omap/patches-6.6/900-use-cpsw-ethernet-driver.patch
new file mode 100644
index 0000000000..31fa0028c6
--- /dev/null
+++ b/target/linux/omap/patches-6.6/900-use-cpsw-ethernet-driver.patch
@@ -0,0 +1,93 @@
+From: Jan Hoffmann <jan@3e8.eu>
+Date: Sat, 27 Apr 2024 20:41:43 +0200
+Subject: ARM: dts: Use cpsw ethernet driver for some am335x devices
+
+The new cpsw-switch driver requires a vid for every port which is
+reserved for internal usage (defaulting to 1 and 2). As a result, some
+network configurations are impossible, such as a bridge with
+default_pvid of 1 (even if it is not vlan aware).
+
+As a simple workaround, the ti,dual-emac-pvid property could be changed
+to another value, but that would just shift the problem. Instead, switch
+some devices back to the older cpsw ethernet driver.
+
+(This patch is not suitable for upstreaming, it just makes the affected
+devices in OpenWrt usable again with the default network config.)
+
+Signed-off-by: Jan Hoffmann <jan@3e8.eu>
+---
+
+--- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
+@@ -358,27 +358,24 @@
+ };
+ };
+
+-&cpsw_port1 {
++&cpsw_emac0 {
+ phy-handle = <&ethphy0>;
+ phy-mode = "mii";
+- ti,dual-emac-pvid = <1>;
+ };
+
+-&cpsw_port2 {
+- status = "disabled";
+-};
+-
+-&mac_sw {
++&mac {
++ slaves = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+ };
+
+-&davinci_mdio_sw {
++&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
++ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+--- a/arch/arm/boot/dts/ti/omap/am335x-evm.dts
++++ b/arch/arm/boot/dts/ti/omap/am335x-evm.dts
+@@ -682,31 +682,28 @@
+ };
+ };
+
+-&mac_sw {
++&mac {
++ slaves = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+ };
+
+-&davinci_mdio_sw {
++&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
++ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+-&cpsw_port1 {
++&cpsw_emac0 {
+ phy-handle = <&ethphy0>;
+ phy-mode = "rgmii-id";
+- ti,dual-emac-pvid = <1>;
+-};
+-
+-&cpsw_port2 {
+- status = "disabled";
+ };
+
+ &tscadc {
diff --git a/target/linux/pistachio/Makefile b/target/linux/pistachio/Makefile
index d5cfb0fe15..ec003f6ed9 100644
--- a/target/linux/pistachio/Makefile
+++ b/target/linux/pistachio/Makefile
@@ -12,7 +12,7 @@ CPU_TYPE:=24kc
CPU_SUBTYPE:=24kf
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/pistachio/config-6.1 b/target/linux/pistachio/config-6.1
deleted file mode 100644
index 926b5e67f7..0000000000
--- a/target/linux/pistachio/config-6.1
+++ /dev/null
@@ -1,335 +0,0 @@
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-# CONFIG_BOARD_INGENIC is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_BUILTIN_DTB=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLKSRC_MIPS_GIC=y
-CONFIG_CLKSRC_PISTACHIO=y
-CONFIG_CLOCKSOURCE_WATCHDOG=y
-CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_PISTACHIO=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONNECTOR=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-# CONFIG_CPU_HAS_SMARTMIPS is not set
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_CPU_MICROMIPS is not set
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-# CONFIG_CPU_MIPS32_R6 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_MIPS64_R6 is not set
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRC16=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CSRC_R4K=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DTC=y
-CONFIG_DWMAC_GENERIC=y
-CONFIG_EXT4_FS=y
-# CONFIG_FIT_IMAGE_FDT_BOSTON is not set
-# CONFIG_FIT_IMAGE_FDT_JAGUAR2 is not set
-# CONFIG_FIT_IMAGE_FDT_LUTON is not set
-CONFIG_FIT_IMAGE_FDT_MARDUK=y
-# CONFIG_FIT_IMAGE_FDT_NI169445 is not set
-# CONFIG_FIT_IMAGE_FDT_OCELOT is not set
-# CONFIG_FIT_IMAGE_FDT_SERVAL is not set
-# CONFIG_FIT_IMAGE_FDT_XILFPGA is not set
-CONFIG_FIXED_PHY=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=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_TIME_VSYSCALL=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_IMG=y
-CONFIG_IMGPDC_WDT=y
-CONFIG_IMG_MDC_DMA=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_PWM=y
-# CONFIG_LEGACY_BOARD_OCELOT is not set
-# CONFIG_LEGACY_BOARD_SEAD3 is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOG_BUF_SHIFT=18
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MICREL_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_AUTO_PFN_OFFSET=y
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-CONFIG_MIPS_CM=y
-CONFIG_MIPS_CMDLINE_DTB_EXTEND=y
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CPC=y
-CONFIG_MIPS_CPS=y
-# CONFIG_MIPS_CPS_CPUIDLE is not set
-# CONFIG_MIPS_CPS_NS16550_BOOL is not set
-CONFIG_MIPS_CPS_PM=y
-CONFIG_MIPS_CPU_SCACHE=y
-CONFIG_MIPS_EBPF_JIT=y
-CONFIG_MIPS_GENERIC=y
-CONFIG_MIPS_GENERIC_KERNEL=y
-CONFIG_MIPS_GIC=y
-CONFIG_MIPS_L1_CACHE_SHIFT=7
-CONFIG_MIPS_L1_CACHE_SHIFT_7=y
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-CONFIG_MIPS_MT=y
-CONFIG_MIPS_MT_FPAFF=y
-CONFIG_MIPS_MT_SMP=y
-CONFIG_MIPS_NO_APPENDED_DTB=y
-CONFIG_MIPS_NR_CPU_NR_MAP=4
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_DW=y
-# CONFIG_MMC_DW_BLUEFIELD is not set
-# CONFIG_MMC_DW_EXYNOS is not set
-# CONFIG_MMC_DW_HI3798CV200 is not set
-# CONFIG_MMC_DW_K3 is not set
-CONFIG_MMC_DW_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_SPI_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_FASTMAP=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NO_EXCEPT_FILL=y
-CONFIG_NR_CPUS=4
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PCI_DRIVERS_GENERIC=y
-CONFIG_PCS_XPCS=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHY_PISTACHIO_USB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_PISTACHIO=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_EVENTS=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_IMG=y
-CONFIG_PWM_SYSFS=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_PISTACHIO=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_SCHEDSTATS=y
-CONFIG_SCHED_INFO=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_SC16IS7XX=y
-CONFIG_SERIAL_SC16IS7XX_CORE=y
-# CONFIG_SERIAL_SC16IS7XX_I2C is not set
-CONFIG_SERIAL_SC16IS7XX_SPI=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPI=y
-CONFIG_SPI_IMG_SPFI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRAM=y
-CONFIG_SRCU=y
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_CPU_MIPS32_R6=y
-CONFIG_SYS_HAS_CPU_MIPS64_R1=y
-CONFIG_SYS_HAS_CPU_MIPS64_R2=y
-CONFIG_SYS_HAS_CPU_MIPS64_R6=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MICROMIPS=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_MIPS_CPS=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_SYS_SUPPORTS_RELOCATABLE=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMARTMIPS=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UHI_BOOT=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_DWC2=y
-CONFIG_USB_DWC2_DUAL_ROLE=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VIRT_BOARD_RANCHU is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WEAK_ORDERING=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZBOOT_LOAD_ADDRESS=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSMALLOC=y
-# CONFIG_ZSMALLOC_STAT is not set
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/pistachio/config-6.6 b/target/linux/pistachio/config-6.6
new file mode 100644
index 0000000000..80ff36ebbb
--- /dev/null
+++ b/target/linux/pistachio/config-6.6
@@ -0,0 +1,361 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_BOARD_INGENIC is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUILTIN_DTB=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLKSRC_MIPS_GIC=y
+CONFIG_CLKSRC_PISTACHIO=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_PISTACHIO=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONNECTOR=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_DIEI=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_MICROMIPS is not set
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+# CONFIG_CPU_MIPS32_R5 is not set
+# CONFIG_CPU_MIPS32_R5_FEATURES is not set
+# CONFIG_CPU_MIPS32_R6 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_MIPS64_R5 is not set
+# CONFIG_CPU_MIPS64_R6 is not set
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_EI=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRC16=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+CONFIG_DWMAC_GENERIC=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+# CONFIG_FIT_IMAGE_FDT_BOSTON is not set
+# CONFIG_FIT_IMAGE_FDT_JAGUAR2 is not set
+# CONFIG_FIT_IMAGE_FDT_LUTON is not set
+CONFIG_FIT_IMAGE_FDT_MARDUK=y
+# CONFIG_FIT_IMAGE_FDT_NI169445 is not set
+# CONFIG_FIT_IMAGE_FDT_OCELOT is not set
+# CONFIG_FIT_IMAGE_FDT_SERVAL is not set
+# CONFIG_FIT_IMAGE_FDT_XILFPGA is not set
+CONFIG_FIXED_PHY=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=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_TIME_VSYSCALL=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_IMG=y
+CONFIG_IMGPDC_WDT=y
+CONFIG_IMG_MDC_DMA=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+# CONFIG_LEGACY_BOARD_OCELOT is not set
+# CONFIG_LEGACY_BOARD_SEAD3 is not set
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MICREL_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_AUTO_PFN_OFFSET=y
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+CONFIG_MIPS_CM=y
+CONFIG_MIPS_CMDLINE_DTB_EXTEND=y
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CPC=y
+CONFIG_MIPS_CPS=y
+# CONFIG_MIPS_CPS_CPUIDLE is not set
+# CONFIG_MIPS_CPS_NS16550_BOOL is not set
+CONFIG_MIPS_CPS_PM=y
+CONFIG_MIPS_CPU_SCACHE=y
+CONFIG_MIPS_GENERIC=y
+CONFIG_MIPS_GENERIC_KERNEL=y
+CONFIG_MIPS_GIC=y
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+CONFIG_MIPS_L1_CACHE_SHIFT_7=y
+CONFIG_MIPS_MT=y
+CONFIG_MIPS_MT_FPAFF=y
+CONFIG_MIPS_MT_SMP=y
+CONFIG_MIPS_NO_APPENDED_DTB=y
+CONFIG_MIPS_NR_CPU_NR_MAP=4
+CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
+# CONFIG_MMC_DW_EXYNOS is not set
+# CONFIG_MMC_DW_HI3798CV200 is not set
+# CONFIG_MMC_DW_K3 is not set
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NO_EXCEPT_FILL=y
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI_DRIVERS_GENERIC=y
+CONFIG_PCS_XPCS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHY_PISTACHIO_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_PISTACHIO=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_EVENTS=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_IMG=y
+CONFIG_PWM_SYSFS=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_PISTACHIO=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_INFO=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_SC16IS7XX=y
+CONFIG_SERIAL_SC16IS7XX_CORE=y
+# CONFIG_SERIAL_SC16IS7XX_I2C is not set
+CONFIG_SERIAL_SC16IS7XX_SPI=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SMP_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPI=y
+CONFIG_SPI_IMG_SPFI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SRAM=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_R4K=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS32_R5=y
+CONFIG_SYS_HAS_CPU_MIPS32_R6=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_SYS_HAS_CPU_MIPS64_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R5=y
+CONFIG_SYS_HAS_CPU_MIPS64_R6=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MICROMIPS=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_SYS_SUPPORTS_MIPS_CPS=y
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
+CONFIG_SYS_SUPPORTS_RELOCATABLE=y
+CONFIG_SYS_SUPPORTS_SCHED_SMT=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_TARGET_ISA_REV=2
+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_UHI_BOOT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_DWC2_DUAL_ROLE=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+# CONFIG_VIRT_BOARD_RANCHU is not set
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_ZBOOT_LOAD_ADDRESS=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch b/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch
deleted file mode 100644
index 031a4e3e5e..0000000000
--- a/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From a2dd154377c9aa6ddda00d39b8c7c334e4fa16ff Mon Sep 17 00:00:00 2001
-From: Damien Horsley <damien.horsley@imgtec.com>
-Date: Tue, 22 Mar 2016 12:46:09 +0000
-Subject: dmaengine: img-mdc: Handle early status read
-
-It is possible that mdc_tx_status may be called before the first
-node has been read from memory.
-
-In this case, the residue value stored in the register is undefined.
-Return the transfer size instead.
-
-Signed-off-by: Damien Horsley <damien.horsley@imgtec.com>
----
- drivers/dma/img-mdc-dma.c | 40 ++++++++++++++++++++++++----------------
- 1 file changed, 24 insertions(+), 16 deletions(-)
-
---- a/drivers/dma/img-mdc-dma.c
-+++ b/drivers/dma/img-mdc-dma.c
-@@ -618,25 +618,33 @@ static enum dma_status mdc_tx_status(str
- (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1);
-
- /*
-- * If the command loaded event hasn't been processed yet, then
-- * the difference above includes an extra command.
-+ * If the first node has not yet been read from memory,
-+ * the residue register value is undefined
- */
-- if (!mdesc->cmd_loaded)
-- cmds--;
-- else
-- cmds += mdesc->list_cmds_done;
--
-- bytes = mdesc->list_xfer_size;
-- ldesc = mdesc->list;
-- for (i = 0; i < cmds; i++) {
-- bytes -= ldesc->xfer_size + 1;
-- ldesc = ldesc->next_desc;
-- }
-- if (ldesc) {
-- if (residue != MDC_TRANSFER_SIZE_MASK)
-- bytes -= ldesc->xfer_size - residue;
-+ if (!mdesc->cmd_loaded && !cmds) {
-+ bytes = mdesc->list_xfer_size;
-+ } else {
-+ /*
-+ * If the command loaded event hasn't been processed yet, then
-+ * the difference above includes an extra command.
-+ */
-+ if (!mdesc->cmd_loaded)
-+ cmds--;
- else
-+ cmds += mdesc->list_cmds_done;
-+
-+ bytes = mdesc->list_xfer_size;
-+ ldesc = mdesc->list;
-+ for (i = 0; i < cmds; i++) {
- bytes -= ldesc->xfer_size + 1;
-+ ldesc = ldesc->next_desc;
-+ }
-+ if (ldesc) {
-+ if (residue != MDC_TRANSFER_SIZE_MASK)
-+ bytes -= ldesc->xfer_size - residue;
-+ else
-+ bytes -= ldesc->xfer_size + 1;
-+ }
- }
- }
- spin_unlock_irqrestore(&mchan->vc.lock, flags);
diff --git a/target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch b/target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
deleted file mode 100644
index 83f21a5c0a..0000000000
--- a/target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
+++ /dev/null
@@ -1,198 +0,0 @@
-From cd2a6af51553d38072cd31699b58d16ca6176ef5 Mon Sep 17 00:00:00 2001
-From: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Date: Thu, 2 Feb 2017 16:46:14 +0000
-Subject: spi: img-spfi: Implement dual and quad mode
-
-For dual and quad modes to work the SPFI controller needs
-to have information about command/address/dummy bytes in the
-transaction register. This information is not relevant for
-single mode, and therefore it can have any value in the
-allowed range. Therefore, for any read or write transfers of less
-than 8 bytes (cmd = 1 byte, addr up to 7 bytes), SPFI will be
-configured, but not enabled (unless it is the last transfer in
-the queue). The transfer will be enabled by the subsequent tranfer.
-A pending transfer is determined by the content of the transaction
-register: if command part is set and tsize is not.
-
-This way we ensure that for dual and quad transactions
-the command request size will apear in the command/address part
-of the transaction register, while the data size will be in
-tsize, all data being sent/received in the same transaction (as
-set up in the transaction register).
-
-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
----
- drivers/spi/spi-img-spfi.c | 96 ++++++++++++++++++++++++++++++++++++++++------
- 1 file changed, 85 insertions(+), 11 deletions(-)
-
---- a/drivers/spi/spi-img-spfi.c
-+++ b/drivers/spi/spi-img-spfi.c
-@@ -36,7 +36,8 @@
- #define SPFI_CONTROL_SOFT_RESET BIT(11)
- #define SPFI_CONTROL_SEND_DMA BIT(10)
- #define SPFI_CONTROL_GET_DMA BIT(9)
--#define SPFI_CONTROL_SE BIT(8)
-+#define SPFI_CONTROL_SE BIT(8)
-+#define SPFI_CONTROL_TX_RX BIT(1)
- #define SPFI_CONTROL_TMODE_SHIFT 5
- #define SPFI_CONTROL_TMODE_MASK 0x7
- #define SPFI_CONTROL_TMODE_SINGLE 0
-@@ -47,6 +48,10 @@
- #define SPFI_TRANSACTION 0x18
- #define SPFI_TRANSACTION_TSIZE_SHIFT 16
- #define SPFI_TRANSACTION_TSIZE_MASK 0xffff
-+#define SPFI_TRANSACTION_CMD_SHIFT 13
-+#define SPFI_TRANSACTION_CMD_MASK 0x7
-+#define SPFI_TRANSACTION_ADDR_SHIFT 10
-+#define SPFI_TRANSACTION_ADDR_MASK 0x7
-
- #define SPFI_PORT_STATE 0x1c
- #define SPFI_PORT_STATE_DEV_SEL_SHIFT 20
-@@ -83,6 +88,7 @@
- */
- #define SPFI_32BIT_FIFO_SIZE 64
- #define SPFI_8BIT_FIFO_SIZE 16
-+#define SPFI_DATA_REQUEST_MAX_SIZE 8
-
- struct img_spfi {
- struct device *dev;
-@@ -99,6 +105,8 @@ struct img_spfi {
- struct dma_chan *tx_ch;
- bool tx_dma_busy;
- bool rx_dma_busy;
-+
-+ bool complete;
- };
-
- static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg)
-@@ -115,9 +123,11 @@ static inline void spfi_start(struct img
- {
- u32 val;
-
-- val = spfi_readl(spfi, SPFI_CONTROL);
-- val |= SPFI_CONTROL_SPFI_EN;
-- spfi_writel(spfi, val, SPFI_CONTROL);
-+ if (spfi->complete) {
-+ val = spfi_readl(spfi, SPFI_CONTROL);
-+ val |= SPFI_CONTROL_SPFI_EN;
-+ spfi_writel(spfi, val, SPFI_CONTROL);
-+ }
- }
-
- static inline void spfi_reset(struct img_spfi *spfi)
-@@ -130,12 +140,21 @@ static int spfi_wait_all_done(struct img
- {
- unsigned long timeout = jiffies + msecs_to_jiffies(50);
-
-+ if (!(spfi->complete))
-+ return 0;
-+
- while (time_before(jiffies, timeout)) {
- u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
-
- if (status & SPFI_INTERRUPT_ALLDONETRIG) {
- spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG,
- SPFI_INTERRUPT_CLEAR);
-+ /*
-+ * Disable SPFI for it not to interfere with
-+ * pending transactions
-+ */
-+ spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL)
-+ & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL);
- return 0;
- }
- cpu_relax();
-@@ -441,9 +460,32 @@ static void img_spfi_config(struct spi_m
- struct spi_transfer *xfer)
- {
- struct img_spfi *spfi = spi_master_get_devdata(spi->master);
-- u32 val, div;
-+ u32 val, div, transact;
-+ bool is_pending;
-
- /*
-+ * For read or write transfers of less than 8 bytes (cmd = 1 byte,
-+ * addr up to 7 bytes), SPFI will be configured, but not enabled
-+ * (unless it is the last transfer in the queue).The transfer will
-+ * be enabled by the subsequent transfer.
-+ * A pending transfer is determined by the content of the
-+ * transaction register: if command part is set and tsize
-+ * is not
-+ */
-+ transact = spfi_readl(spfi, SPFI_TRANSACTION);
-+ is_pending = ((transact >> SPFI_TRANSACTION_CMD_SHIFT) &
-+ SPFI_TRANSACTION_CMD_MASK) &&
-+ (!((transact >> SPFI_TRANSACTION_TSIZE_SHIFT) &
-+ SPFI_TRANSACTION_TSIZE_MASK));
-+
-+ /* If there are no pending transactions it's OK to soft reset */
-+ if (!is_pending) {
-+ /* Start the transaction from a known (reset) state */
-+ spfi_reset(spfi);
-+ }
-+
-+ /*
-+ * Before anything else, set up parameters.
- * output = spfi_clk * (BITCLK / 512), where BITCLK must be a
- * power of 2 up to 128
- */
-@@ -456,20 +498,52 @@ static void img_spfi_config(struct spi_m
- val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT;
- spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select));
-
-- spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT,
-- SPFI_TRANSACTION);
-+ if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) &&
-+ /*
-+ * For duplex mode (both the tx and rx buffers are !NULL) the
-+ * CMD, ADDR, and DUMMY byte parts of the transaction register
-+ * should always be 0 and therefore the pending transfer
-+ * technique cannot be used.
-+ */
-+ (xfer->tx_buf) && (!xfer->rx_buf) &&
-+ (xfer->len <= SPFI_DATA_REQUEST_MAX_SIZE) && !is_pending) {
-+ transact = (1 & SPFI_TRANSACTION_CMD_MASK) <<
-+ SPFI_TRANSACTION_CMD_SHIFT;
-+ transact |= ((xfer->len - 1) & SPFI_TRANSACTION_ADDR_MASK) <<
-+ SPFI_TRANSACTION_ADDR_SHIFT;
-+ spfi->complete = false;
-+ } else {
-+ spfi->complete = true;
-+ if (is_pending) {
-+ /* Keep setup from pending transfer */
-+ transact |= ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) <<
-+ SPFI_TRANSACTION_TSIZE_SHIFT);
-+ } else {
-+ transact = ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) <<
-+ SPFI_TRANSACTION_TSIZE_SHIFT);
-+ }
-+ }
-+ spfi_writel(spfi, transact, SPFI_TRANSACTION);
-
- val = spfi_readl(spfi, SPFI_CONTROL);
- val &= ~(SPFI_CONTROL_SEND_DMA | SPFI_CONTROL_GET_DMA);
-- if (xfer->tx_buf)
-+ /*
-+ * We set up send DMA for pending transfers also, as
-+ * those are always send transfers
-+ */
-+ if ((xfer->tx_buf) || is_pending)
- val |= SPFI_CONTROL_SEND_DMA;
-- if (xfer->rx_buf)
-+ if (xfer->tx_buf)
-+ val |= SPFI_CONTROL_TX_RX;
-+ if (xfer->rx_buf) {
- val |= SPFI_CONTROL_GET_DMA;
-+ val &= ~SPFI_CONTROL_TX_RX;
-+ }
- val &= ~(SPFI_CONTROL_TMODE_MASK << SPFI_CONTROL_TMODE_SHIFT);
-- if (xfer->tx_nbits == SPI_NBITS_DUAL &&
-+ if (xfer->tx_nbits == SPI_NBITS_DUAL ||
- xfer->rx_nbits == SPI_NBITS_DUAL)
- val |= SPFI_CONTROL_TMODE_DUAL << SPFI_CONTROL_TMODE_SHIFT;
-- else if (xfer->tx_nbits == SPI_NBITS_QUAD &&
-+ else if (xfer->tx_nbits == SPI_NBITS_QUAD ||
- xfer->rx_nbits == SPI_NBITS_QUAD)
- val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT;
- val |= SPFI_CONTROL_SE;
diff --git a/target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch b/target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch
deleted file mode 100644
index 2995b7dd88..0000000000
--- a/target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 905ee06a9966113fe51d6bad1819759cb30fd0bd Mon Sep 17 00:00:00 2001
-From: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Date: Tue, 9 Feb 2016 10:18:31 +0000
-Subject: spi: img-spfi: use device 0 configuration for all devices
-
-Given that we control the chip select line externally
-we can use only one parameter register (device 0 parameter
-register) and one set of configuration bits (port configuration
-bits for device 0) for all devices (all chip select lines).
-
-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
----
- drivers/spi/spi-img-spfi.c | 23 ++++++++++++++++-------
- 1 file changed, 16 insertions(+), 7 deletions(-)
-
---- a/drivers/spi/spi-img-spfi.c
-+++ b/drivers/spi/spi-img-spfi.c
-@@ -429,18 +429,23 @@ static int img_spfi_prepare(struct spi_m
- struct img_spfi *spfi = spi_master_get_devdata(master);
- u32 val;
-
-+ /*
-+ * The chip select line is controlled externally so
-+ * we can use the CS0 configuration for all devices
-+ */
- val = spfi_readl(spfi, SPFI_PORT_STATE);
-+
-+ /* 0 for device selection */
- val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK <<
- SPFI_PORT_STATE_DEV_SEL_SHIFT);
-- val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT;
- if (msg->spi->mode & SPI_CPHA)
-- val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select);
-+ val |= SPFI_PORT_STATE_CK_PHASE(0);
- else
-- val &= ~SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select);
-+ val &= ~SPFI_PORT_STATE_CK_PHASE(0);
- if (msg->spi->mode & SPI_CPOL)
-- val |= SPFI_PORT_STATE_CK_POL(msg->spi->chip_select);
-+ val |= SPFI_PORT_STATE_CK_POL(0);
- else
-- val &= ~SPFI_PORT_STATE_CK_POL(msg->spi->chip_select);
-+ val &= ~SPFI_PORT_STATE_CK_POL(0);
- spfi_writel(spfi, val, SPFI_PORT_STATE);
-
- return 0;
-@@ -492,11 +497,15 @@ static void img_spfi_config(struct spi_m
- div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz);
- div = clamp(512 / (1 << get_count_order(div)), 1, 128);
-
-- val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi->chip_select));
-+ /*
-+ * The chip select line is controlled externally so
-+ * we can use the CS0 parameters for all devices
-+ */
-+ val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(0));
- val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK <<
- SPFI_DEVICE_PARAMETER_BITCLK_SHIFT);
- val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT;
-- spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select));
-+ spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(0));
-
- if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) &&
- /*
diff --git a/target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch b/target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch
deleted file mode 100644
index ea1f9f28cc..0000000000
--- a/target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 5fcca3fd4b621d7b5bdeca18d36dfc6ca6cfe383 Mon Sep 17 00:00:00 2001
-From: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Date: Wed, 10 Aug 2016 11:42:26 +0100
-Subject: spi: img-spfi: finish every transfer cleanly
-
-Before this change, the interrupt status bit that signaled
-the end of a tranfers was cleared in the wait_all_done
-function. That functionality triggered issues for DMA
-duplex transactions where the wait function was called
-twice, in both the TX and RX callbacks.
-
-In order to fix the issue, clear all interrupt data bits
-at the end of a PIO transfer or at the end of both TX and RX
-duplex transfers, if the transfer is not a pending tranfer
-(command waiting for data). After that, the status register
-is checked for new incoming data or new data requests to be
-signaled. If SPFI finished cleanly, no new interrupt data
-bits should be set.
-
-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
----
- drivers/spi/spi-img-spfi.c | 49 +++++++++++++++++++++++++++++++++-------------
- 1 file changed, 35 insertions(+), 14 deletions(-)
-
---- a/drivers/spi/spi-img-spfi.c
-+++ b/drivers/spi/spi-img-spfi.c
-@@ -79,6 +79,14 @@
- #define SPFI_INTERRUPT_SDE BIT(1)
- #define SPFI_INTERRUPT_SDTRIG BIT(0)
-
-+#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\
-+ SPFI_INTERRUPT_SDFUL |\
-+ SPFI_INTERRUPT_GDEX32BIT |\
-+ SPFI_INTERRUPT_GDHF |\
-+ SPFI_INTERRUPT_GDFUL |\
-+ SPFI_INTERRUPT_ALLDONETRIG |\
-+ SPFI_INTERRUPT_GDEX8BIT)
-+
- /*
- * There are four parallel FIFOs of 16 bytes each. The word buffer
- * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an
-@@ -136,6 +144,23 @@ static inline void spfi_reset(struct img
- spfi_writel(spfi, 0, SPFI_CONTROL);
- }
-
-+static inline void spfi_finish(struct img_spfi *spfi)
-+{
-+ if (!(spfi->complete))
-+ return;
-+
-+ /* Clear data bits as all transfers(TX and RX) have finished */
-+ spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR);
-+ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) {
-+ dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n");
-+ spfi_reset(spfi);
-+ }
-+ /* Disable SPFI for it not to interfere with pending transactions */
-+ spfi_writel(spfi,
-+ spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN,
-+ SPFI_CONTROL);
-+}
-+
- static int spfi_wait_all_done(struct img_spfi *spfi)
- {
- unsigned long timeout = jiffies + msecs_to_jiffies(50);
-@@ -144,19 +169,9 @@ static int spfi_wait_all_done(struct img
- return 0;
-
- while (time_before(jiffies, timeout)) {
-- u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
--
-- if (status & SPFI_INTERRUPT_ALLDONETRIG) {
-- spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG,
-- SPFI_INTERRUPT_CLEAR);
-- /*
-- * Disable SPFI for it not to interfere with
-- * pending transactions
-- */
-- spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL)
-- & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL);
-+ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) &
-+ SPFI_INTERRUPT_ALLDONETRIG)
- return 0;
-- }
- cpu_relax();
- }
-
-@@ -288,6 +303,8 @@ static int img_spfi_start_pio(struct spi
- }
-
- ret = spfi_wait_all_done(spfi);
-+ spfi_finish(spfi);
-+
- if (ret < 0)
- return ret;
-
-@@ -303,8 +320,10 @@ static void img_spfi_dma_rx_cb(void *dat
-
- spin_lock_irqsave(&spfi->lock, flags);
- spfi->rx_dma_busy = false;
-- if (!spfi->tx_dma_busy)
-+ if (!spfi->tx_dma_busy) {
-+ spfi_finish(spfi);
- spi_finalize_current_transfer(spfi->master);
-+ }
- spin_unlock_irqrestore(&spfi->lock, flags);
- }
-
-@@ -317,8 +336,10 @@ static void img_spfi_dma_tx_cb(void *dat
-
- spin_lock_irqsave(&spfi->lock, flags);
- spfi->tx_dma_busy = false;
-- if (!spfi->rx_dma_busy)
-+ if (!spfi->rx_dma_busy) {
-+ spfi_finish(spfi);
- spi_finalize_current_transfer(spfi->master);
-+ }
- spin_unlock_irqrestore(&spfi->lock, flags);
- }
-
diff --git a/target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch b/target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch
deleted file mode 100644
index a8ebab9cd2..0000000000
--- a/target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From f32bc2aa01edcba2f2ed5db151cf183eac9ef919 Mon Sep 17 00:00:00 2001
-From: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com>
-Date: Sat, 25 Feb 2017 16:42:50 +0000
-Subject: mtd: nor: support mtd name from device tree
-
-Signed-off-by: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com>
----
- drivers/mtd/spi-nor/spi-nor.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -2964,12 +2964,20 @@ static void spi_nor_set_mtd_info(struct
- {
- struct mtd_info *mtd = &nor->mtd;
- struct device *dev = nor->dev;
-+ struct device_node *np = spi_nor_get_flash_node(nor);
-+ const char __maybe_unused *of_mtd_name = NULL;
-
- spi_nor_set_mtd_locking_ops(nor);
- spi_nor_set_mtd_otp_ops(nor);
-
- mtd->dev.parent = dev;
- if (!mtd->name)
-+#ifdef CONFIG_MTD_OF_PARTS
-+ of_property_read_string(np, "linux,mtd-name", &of_mtd_name);
-+#endif
-+ if (of_mtd_name)
-+ mtd->name = of_mtd_name;
-+ else if (!mtd->name)
- mtd->name = dev_name(dev);
- mtd->type = MTD_NORFLASH;
- mtd->flags = MTD_CAP_NORFLASH;
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -863,6 +863,17 @@ out_error:
- */
- static void mtd_set_dev_defaults(struct mtd_info *mtd)
- {
-+#ifdef CONFIG_MTD_OF_PARTS
-+ const char __maybe_unused *of_mtd_name = NULL;
-+ struct device_node *np;
-+
-+ np = mtd_get_of_node(mtd);
-+ if (np && !mtd->name) {
-+ of_property_read_string(np, "linux,mtd-name", &of_mtd_name);
-+ if (of_mtd_name)
-+ mtd->name = of_mtd_name;
-+ } else
-+#endif
- if (mtd->dev.parent) {
- if (!mtd->owner && mtd->dev.parent->driver)
- mtd->owner = mtd->dev.parent->driver->owner;
diff --git a/target/linux/pistachio/patches-6.6/101-dmaengine-img-mdc-Handle-early-status-read.patch b/target/linux/pistachio/patches-6.6/101-dmaengine-img-mdc-Handle-early-status-read.patch
new file mode 100644
index 0000000000..abaaae1cc7
--- /dev/null
+++ b/target/linux/pistachio/patches-6.6/101-dmaengine-img-mdc-Handle-early-status-read.patch
@@ -0,0 +1,68 @@
+From a2dd154377c9aa6ddda00d39b8c7c334e4fa16ff Mon Sep 17 00:00:00 2001
+From: Damien Horsley <damien.horsley@imgtec.com>
+Date: Tue, 22 Mar 2016 12:46:09 +0000
+Subject: dmaengine: img-mdc: Handle early status read
+
+It is possible that mdc_tx_status may be called before the first
+node has been read from memory.
+
+In this case, the residue value stored in the register is undefined.
+Return the transfer size instead.
+
+Signed-off-by: Damien Horsley <damien.horsley@imgtec.com>
+---
+ drivers/dma/img-mdc-dma.c | 40 ++++++++++++++++++++++++----------------
+ 1 file changed, 24 insertions(+), 16 deletions(-)
+
+--- a/drivers/dma/img-mdc-dma.c
++++ b/drivers/dma/img-mdc-dma.c
+@@ -617,25 +617,33 @@ static enum dma_status mdc_tx_status(str
+ (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1);
+
+ /*
+- * If the command loaded event hasn't been processed yet, then
+- * the difference above includes an extra command.
++ * If the first node has not yet been read from memory,
++ * the residue register value is undefined
+ */
+- if (!mdesc->cmd_loaded)
+- cmds--;
+- else
+- cmds += mdesc->list_cmds_done;
+-
+- bytes = mdesc->list_xfer_size;
+- ldesc = mdesc->list;
+- for (i = 0; i < cmds; i++) {
+- bytes -= ldesc->xfer_size + 1;
+- ldesc = ldesc->next_desc;
+- }
+- if (ldesc) {
+- if (residue != MDC_TRANSFER_SIZE_MASK)
+- bytes -= ldesc->xfer_size - residue;
++ if (!mdesc->cmd_loaded && !cmds) {
++ bytes = mdesc->list_xfer_size;
++ } else {
++ /*
++ * If the command loaded event hasn't been processed yet, then
++ * the difference above includes an extra command.
++ */
++ if (!mdesc->cmd_loaded)
++ cmds--;
+ else
++ cmds += mdesc->list_cmds_done;
++
++ bytes = mdesc->list_xfer_size;
++ ldesc = mdesc->list;
++ for (i = 0; i < cmds; i++) {
+ bytes -= ldesc->xfer_size + 1;
++ ldesc = ldesc->next_desc;
++ }
++ if (ldesc) {
++ if (residue != MDC_TRANSFER_SIZE_MASK)
++ bytes -= ldesc->xfer_size - residue;
++ else
++ bytes -= ldesc->xfer_size + 1;
++ }
+ }
+ }
+ spin_unlock_irqrestore(&mchan->vc.lock, flags);
diff --git a/target/linux/pistachio/patches-6.6/102-spi-img-spfi-Implement-dual-and-quad-mode.patch b/target/linux/pistachio/patches-6.6/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
new file mode 100644
index 0000000000..6ec1a2ab12
--- /dev/null
+++ b/target/linux/pistachio/patches-6.6/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
@@ -0,0 +1,198 @@
+From cd2a6af51553d38072cd31699b58d16ca6176ef5 Mon Sep 17 00:00:00 2001
+From: Ionela Voinescu <ionela.voinescu@imgtec.com>
+Date: Thu, 2 Feb 2017 16:46:14 +0000
+Subject: spi: img-spfi: Implement dual and quad mode
+
+For dual and quad modes to work the SPFI controller needs
+to have information about command/address/dummy bytes in the
+transaction register. This information is not relevant for
+single mode, and therefore it can have any value in the
+allowed range. Therefore, for any read or write transfers of less
+than 8 bytes (cmd = 1 byte, addr up to 7 bytes), SPFI will be
+configured, but not enabled (unless it is the last transfer in
+the queue). The transfer will be enabled by the subsequent tranfer.
+A pending transfer is determined by the content of the transaction
+register: if command part is set and tsize is not.
+
+This way we ensure that for dual and quad transactions
+the command request size will apear in the command/address part
+of the transaction register, while the data size will be in
+tsize, all data being sent/received in the same transaction (as
+set up in the transaction register).
+
+Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
+---
+ drivers/spi/spi-img-spfi.c | 96 ++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 85 insertions(+), 11 deletions(-)
+
+--- a/drivers/spi/spi-img-spfi.c
++++ b/drivers/spi/spi-img-spfi.c
+@@ -36,7 +36,8 @@
+ #define SPFI_CONTROL_SOFT_RESET BIT(11)
+ #define SPFI_CONTROL_SEND_DMA BIT(10)
+ #define SPFI_CONTROL_GET_DMA BIT(9)
+-#define SPFI_CONTROL_SE BIT(8)
++#define SPFI_CONTROL_SE BIT(8)
++#define SPFI_CONTROL_TX_RX BIT(1)
+ #define SPFI_CONTROL_TMODE_SHIFT 5
+ #define SPFI_CONTROL_TMODE_MASK 0x7
+ #define SPFI_CONTROL_TMODE_SINGLE 0
+@@ -47,6 +48,10 @@
+ #define SPFI_TRANSACTION 0x18
+ #define SPFI_TRANSACTION_TSIZE_SHIFT 16
+ #define SPFI_TRANSACTION_TSIZE_MASK 0xffff
++#define SPFI_TRANSACTION_CMD_SHIFT 13
++#define SPFI_TRANSACTION_CMD_MASK 0x7
++#define SPFI_TRANSACTION_ADDR_SHIFT 10
++#define SPFI_TRANSACTION_ADDR_MASK 0x7
+
+ #define SPFI_PORT_STATE 0x1c
+ #define SPFI_PORT_STATE_DEV_SEL_SHIFT 20
+@@ -83,6 +88,7 @@
+ */
+ #define SPFI_32BIT_FIFO_SIZE 64
+ #define SPFI_8BIT_FIFO_SIZE 16
++#define SPFI_DATA_REQUEST_MAX_SIZE 8
+
+ struct img_spfi {
+ struct device *dev;
+@@ -99,6 +105,8 @@ struct img_spfi {
+ struct dma_chan *tx_ch;
+ bool tx_dma_busy;
+ bool rx_dma_busy;
++
++ bool complete;
+ };
+
+ static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg)
+@@ -115,9 +123,11 @@ static inline void spfi_start(struct img
+ {
+ u32 val;
+
+- val = spfi_readl(spfi, SPFI_CONTROL);
+- val |= SPFI_CONTROL_SPFI_EN;
+- spfi_writel(spfi, val, SPFI_CONTROL);
++ if (spfi->complete) {
++ val = spfi_readl(spfi, SPFI_CONTROL);
++ val |= SPFI_CONTROL_SPFI_EN;
++ spfi_writel(spfi, val, SPFI_CONTROL);
++ }
+ }
+
+ static inline void spfi_reset(struct img_spfi *spfi)
+@@ -130,12 +140,21 @@ static int spfi_wait_all_done(struct img
+ {
+ unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
++ if (!(spfi->complete))
++ return 0;
++
+ while (time_before(jiffies, timeout)) {
+ u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
+
+ if (status & SPFI_INTERRUPT_ALLDONETRIG) {
+ spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG,
+ SPFI_INTERRUPT_CLEAR);
++ /*
++ * Disable SPFI for it not to interfere with
++ * pending transactions
++ */
++ spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL)
++ & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL);
+ return 0;
+ }
+ cpu_relax();
+@@ -441,9 +460,32 @@ static void img_spfi_config(struct spi_c
+ struct spi_transfer *xfer)
+ {
+ struct img_spfi *spfi = spi_controller_get_devdata(spi->controller);
+- u32 val, div;
++ u32 val, div, transact;
++ bool is_pending;
+
+ /*
++ * For read or write transfers of less than 8 bytes (cmd = 1 byte,
++ * addr up to 7 bytes), SPFI will be configured, but not enabled
++ * (unless it is the last transfer in the queue).The transfer will
++ * be enabled by the subsequent transfer.
++ * A pending transfer is determined by the content of the
++ * transaction register: if command part is set and tsize
++ * is not
++ */
++ transact = spfi_readl(spfi, SPFI_TRANSACTION);
++ is_pending = ((transact >> SPFI_TRANSACTION_CMD_SHIFT) &
++ SPFI_TRANSACTION_CMD_MASK) &&
++ (!((transact >> SPFI_TRANSACTION_TSIZE_SHIFT) &
++ SPFI_TRANSACTION_TSIZE_MASK));
++
++ /* If there are no pending transactions it's OK to soft reset */
++ if (!is_pending) {
++ /* Start the transaction from a known (reset) state */
++ spfi_reset(spfi);
++ }
++
++ /*
++ * Before anything else, set up parameters.
+ * output = spfi_clk * (BITCLK / 512), where BITCLK must be a
+ * power of 2 up to 128
+ */
+@@ -456,20 +498,52 @@ static void img_spfi_config(struct spi_c
+ val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT;
+ spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi_get_chipselect(spi, 0)));
+
+- spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT,
+- SPFI_TRANSACTION);
++ if (!list_is_last(&xfer->transfer_list, &host->cur_msg->transfers) &&
++ /*
++ * For duplex mode (both the tx and rx buffers are !NULL) the
++ * CMD, ADDR, and DUMMY byte parts of the transaction register
++ * should always be 0 and therefore the pending transfer
++ * technique cannot be used.
++ */
++ (xfer->tx_buf) && (!xfer->rx_buf) &&
++ (xfer->len <= SPFI_DATA_REQUEST_MAX_SIZE) && !is_pending) {
++ transact = (1 & SPFI_TRANSACTION_CMD_MASK) <<
++ SPFI_TRANSACTION_CMD_SHIFT;
++ transact |= ((xfer->len - 1) & SPFI_TRANSACTION_ADDR_MASK) <<
++ SPFI_TRANSACTION_ADDR_SHIFT;
++ spfi->complete = false;
++ } else {
++ spfi->complete = true;
++ if (is_pending) {
++ /* Keep setup from pending transfer */
++ transact |= ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) <<
++ SPFI_TRANSACTION_TSIZE_SHIFT);
++ } else {
++ transact = ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) <<
++ SPFI_TRANSACTION_TSIZE_SHIFT);
++ }
++ }
++ spfi_writel(spfi, transact, SPFI_TRANSACTION);
+
+ val = spfi_readl(spfi, SPFI_CONTROL);
+ val &= ~(SPFI_CONTROL_SEND_DMA | SPFI_CONTROL_GET_DMA);
+- if (xfer->tx_buf)
++ /*
++ * We set up send DMA for pending transfers also, as
++ * those are always send transfers
++ */
++ if ((xfer->tx_buf) || is_pending)
+ val |= SPFI_CONTROL_SEND_DMA;
+- if (xfer->rx_buf)
++ if (xfer->tx_buf)
++ val |= SPFI_CONTROL_TX_RX;
++ if (xfer->rx_buf) {
+ val |= SPFI_CONTROL_GET_DMA;
++ val &= ~SPFI_CONTROL_TX_RX;
++ }
+ val &= ~(SPFI_CONTROL_TMODE_MASK << SPFI_CONTROL_TMODE_SHIFT);
+- if (xfer->tx_nbits == SPI_NBITS_DUAL &&
++ if (xfer->tx_nbits == SPI_NBITS_DUAL ||
+ xfer->rx_nbits == SPI_NBITS_DUAL)
+ val |= SPFI_CONTROL_TMODE_DUAL << SPFI_CONTROL_TMODE_SHIFT;
+- else if (xfer->tx_nbits == SPI_NBITS_QUAD &&
++ else if (xfer->tx_nbits == SPI_NBITS_QUAD ||
+ xfer->rx_nbits == SPI_NBITS_QUAD)
+ val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT;
+ val |= SPFI_CONTROL_SE;
diff --git a/target/linux/pistachio/patches-6.6/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch b/target/linux/pistachio/patches-6.6/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch
new file mode 100644
index 0000000000..b3505134b6
--- /dev/null
+++ b/target/linux/pistachio/patches-6.6/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch
@@ -0,0 +1,64 @@
+From 905ee06a9966113fe51d6bad1819759cb30fd0bd Mon Sep 17 00:00:00 2001
+From: Ionela Voinescu <ionela.voinescu@imgtec.com>
+Date: Tue, 9 Feb 2016 10:18:31 +0000
+Subject: spi: img-spfi: use device 0 configuration for all devices
+
+Given that we control the chip select line externally
+we can use only one parameter register (device 0 parameter
+register) and one set of configuration bits (port configuration
+bits for device 0) for all devices (all chip select lines).
+
+Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
+---
+ drivers/spi/spi-img-spfi.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+--- a/drivers/spi/spi-img-spfi.c
++++ b/drivers/spi/spi-img-spfi.c
+@@ -429,18 +429,23 @@ static int img_spfi_prepare(struct spi_c
+ struct img_spfi *spfi = spi_controller_get_devdata(host);
+ u32 val;
+
++ /*
++ * The chip select line is controlled externally so
++ * we can use the CS0 configuration for all devices
++ */
+ val = spfi_readl(spfi, SPFI_PORT_STATE);
++
++ /* 0 for device selection */
+ val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK <<
+ SPFI_PORT_STATE_DEV_SEL_SHIFT);
+- val |= spi_get_chipselect(msg->spi, 0) << SPFI_PORT_STATE_DEV_SEL_SHIFT;
+ if (msg->spi->mode & SPI_CPHA)
+- val |= SPFI_PORT_STATE_CK_PHASE(spi_get_chipselect(msg->spi, 0));
++ val |= SPFI_PORT_STATE_CK_PHASE(0);
+ else
+- val &= ~SPFI_PORT_STATE_CK_PHASE(spi_get_chipselect(msg->spi, 0));
++ val &= ~SPFI_PORT_STATE_CK_PHASE(0);
+ if (msg->spi->mode & SPI_CPOL)
+- val |= SPFI_PORT_STATE_CK_POL(spi_get_chipselect(msg->spi, 0));
++ val |= SPFI_PORT_STATE_CK_POL(0);
+ else
+- val &= ~SPFI_PORT_STATE_CK_POL(spi_get_chipselect(msg->spi, 0));
++ val &= ~SPFI_PORT_STATE_CK_POL(0);
+ spfi_writel(spfi, val, SPFI_PORT_STATE);
+
+ return 0;
+@@ -492,11 +497,15 @@ static void img_spfi_config(struct spi_c
+ div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz);
+ div = clamp(512 / (1 << get_count_order(div)), 1, 128);
+
+- val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi_get_chipselect(spi, 0)));
++ /*
++ * The chip select line is controlled externally so
++ * we can use the CS0 parameters for all devices
++ */
++ val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(0));
+ val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK <<
+ SPFI_DEVICE_PARAMETER_BITCLK_SHIFT);
+ val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT;
+- spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi_get_chipselect(spi, 0)));
++ spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(0));
+
+ if (!list_is_last(&xfer->transfer_list, &host->cur_msg->transfers) &&
+ /*
diff --git a/target/linux/pistachio/patches-6.1/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch b/target/linux/pistachio/patches-6.6/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch
index 5418503816..5418503816 100644
--- a/target/linux/pistachio/patches-6.1/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch
+++ b/target/linux/pistachio/patches-6.6/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch
diff --git a/target/linux/pistachio/patches-6.6/106-spi-img-spfi-finish-every-transfer-cleanly.patch b/target/linux/pistachio/patches-6.6/106-spi-img-spfi-finish-every-transfer-cleanly.patch
new file mode 100644
index 0000000000..a87594e4c7
--- /dev/null
+++ b/target/linux/pistachio/patches-6.6/106-spi-img-spfi-finish-every-transfer-cleanly.patch
@@ -0,0 +1,120 @@
+From 5fcca3fd4b621d7b5bdeca18d36dfc6ca6cfe383 Mon Sep 17 00:00:00 2001
+From: Ionela Voinescu <ionela.voinescu@imgtec.com>
+Date: Wed, 10 Aug 2016 11:42:26 +0100
+Subject: spi: img-spfi: finish every transfer cleanly
+
+Before this change, the interrupt status bit that signaled
+the end of a tranfers was cleared in the wait_all_done
+function. That functionality triggered issues for DMA
+duplex transactions where the wait function was called
+twice, in both the TX and RX callbacks.
+
+In order to fix the issue, clear all interrupt data bits
+at the end of a PIO transfer or at the end of both TX and RX
+duplex transfers, if the transfer is not a pending tranfer
+(command waiting for data). After that, the status register
+is checked for new incoming data or new data requests to be
+signaled. If SPFI finished cleanly, no new interrupt data
+bits should be set.
+
+Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
+---
+ drivers/spi/spi-img-spfi.c | 49 +++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 35 insertions(+), 14 deletions(-)
+
+--- a/drivers/spi/spi-img-spfi.c
++++ b/drivers/spi/spi-img-spfi.c
+@@ -79,6 +79,14 @@
+ #define SPFI_INTERRUPT_SDE BIT(1)
+ #define SPFI_INTERRUPT_SDTRIG BIT(0)
+
++#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\
++ SPFI_INTERRUPT_SDFUL |\
++ SPFI_INTERRUPT_GDEX32BIT |\
++ SPFI_INTERRUPT_GDHF |\
++ SPFI_INTERRUPT_GDFUL |\
++ SPFI_INTERRUPT_ALLDONETRIG |\
++ SPFI_INTERRUPT_GDEX8BIT)
++
+ /*
+ * There are four parallel FIFOs of 16 bytes each. The word buffer
+ * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an
+@@ -136,6 +144,23 @@ static inline void spfi_reset(struct img
+ spfi_writel(spfi, 0, SPFI_CONTROL);
+ }
+
++static inline void spfi_finish(struct img_spfi *spfi)
++{
++ if (!(spfi->complete))
++ return;
++
++ /* Clear data bits as all transfers(TX and RX) have finished */
++ spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR);
++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) {
++ dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n");
++ spfi_reset(spfi);
++ }
++ /* Disable SPFI for it not to interfere with pending transactions */
++ spfi_writel(spfi,
++ spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN,
++ SPFI_CONTROL);
++}
++
+ static int spfi_wait_all_done(struct img_spfi *spfi)
+ {
+ unsigned long timeout = jiffies + msecs_to_jiffies(50);
+@@ -144,19 +169,9 @@ static int spfi_wait_all_done(struct img
+ return 0;
+
+ while (time_before(jiffies, timeout)) {
+- u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
+-
+- if (status & SPFI_INTERRUPT_ALLDONETRIG) {
+- spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG,
+- SPFI_INTERRUPT_CLEAR);
+- /*
+- * Disable SPFI for it not to interfere with
+- * pending transactions
+- */
+- spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL)
+- & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL);
++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) &
++ SPFI_INTERRUPT_ALLDONETRIG)
+ return 0;
+- }
+ cpu_relax();
+ }
+
+@@ -288,6 +303,8 @@ static int img_spfi_start_pio(struct spi
+ }
+
+ ret = spfi_wait_all_done(spfi);
++ spfi_finish(spfi);
++
+ if (ret < 0)
+ return ret;
+
+@@ -303,8 +320,10 @@ static void img_spfi_dma_rx_cb(void *dat
+
+ spin_lock_irqsave(&spfi->lock, flags);
+ spfi->rx_dma_busy = false;
+- if (!spfi->tx_dma_busy)
++ if (!spfi->tx_dma_busy) {
++ spfi_finish(spfi);
+ spi_finalize_current_transfer(spfi->host);
++ }
+ spin_unlock_irqrestore(&spfi->lock, flags);
+ }
+
+@@ -317,8 +336,10 @@ static void img_spfi_dma_tx_cb(void *dat
+
+ spin_lock_irqsave(&spfi->lock, flags);
+ spfi->tx_dma_busy = false;
+- if (!spfi->rx_dma_busy)
++ if (!spfi->rx_dma_busy) {
++ spfi_finish(spfi);
+ spi_finalize_current_transfer(spfi->host);
++ }
+ spin_unlock_irqrestore(&spfi->lock, flags);
+ }
+
diff --git a/target/linux/pistachio/patches-6.1/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch b/target/linux/pistachio/patches-6.6/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch
index 6fddbe269a..6fddbe269a 100644
--- a/target/linux/pistachio/patches-6.1/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch
+++ b/target/linux/pistachio/patches-6.6/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch
diff --git a/target/linux/pistachio/patches-6.1/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch b/target/linux/pistachio/patches-6.6/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch
index faba23c5f1..faba23c5f1 100644
--- a/target/linux/pistachio/patches-6.1/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch
+++ b/target/linux/pistachio/patches-6.6/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch
diff --git a/target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch b/target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch
new file mode 100644
index 0000000000..0000c22a89
--- /dev/null
+++ b/target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch
@@ -0,0 +1,61 @@
+From f32bc2aa01edcba2f2ed5db151cf183eac9ef919 Mon Sep 17 00:00:00 2001
+From: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com>
+Date: Sat, 25 Feb 2017 16:42:50 +0000
+Subject: mtd: nor: support mtd name from device tree
+
+Signed-off-by: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com>
+---
+ drivers/mtd/spi-nor/spi-nor.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -846,7 +846,9 @@ static int spi_mem_probe(struct spi_devi
+ {
+ struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver);
+ struct spi_controller *ctlr = spi->controller;
++ const char __maybe_unused *of_mtd_name = NULL;
+ struct spi_mem *mem;
++ int ret;
+
+ mem = devm_kzalloc(&spi->dev, sizeof(*mem), GFP_KERNEL);
+ if (!mem)
+@@ -854,10 +856,15 @@ static int spi_mem_probe(struct spi_devi
+
+ mem->spi = spi;
+
+- if (ctlr->mem_ops && ctlr->mem_ops->get_name)
++ if (ctlr->mem_ops && ctlr->mem_ops->get_name) {
+ mem->name = ctlr->mem_ops->get_name(mem);
+- else
+- mem->name = dev_name(&spi->dev);
++ } else {
++ ret = device_property_read_string(&spi->dev, "linux,mtd-name", &of_mtd_name);
++ if (!ret)
++ mem->name = of_mtd_name;
++ else
++ mem->name = dev_name(&spi->dev);
++ }
+
+ if (IS_ERR_OR_NULL(mem->name))
+ return PTR_ERR_OR_ZERO(mem->name);
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -870,6 +870,17 @@ out_error:
+ */
+ static void mtd_set_dev_defaults(struct mtd_info *mtd)
+ {
++#ifdef CONFIG_MTD_OF_PARTS
++ const char __maybe_unused *of_mtd_name = NULL;
++ struct device_node *np;
++
++ np = mtd_get_of_node(mtd);
++ if (np && !mtd->name) {
++ of_property_read_string(np, "linux,mtd-name", &of_mtd_name);
++ if (of_mtd_name)
++ mtd->name = of_mtd_name;
++ } else
++#endif
+ if (mtd->dev.parent) {
+ if (!mtd->owner && mtd->dev.parent->driver)
+ mtd->owner = mtd->dev.parent->driver->owner;
diff --git a/target/linux/pistachio/patches-6.1/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch b/target/linux/pistachio/patches-6.6/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch
index 4b28f46833..4b28f46833 100644
--- a/target/linux/pistachio/patches-6.1/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch
+++ b/target/linux/pistachio/patches-6.6/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch
diff --git a/target/linux/pistachio/patches-6.1/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch b/target/linux/pistachio/patches-6.6/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch
index d4c4ccac53..d4c4ccac53 100644
--- a/target/linux/pistachio/patches-6.1/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch
+++ b/target/linux/pistachio/patches-6.6/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch
diff --git a/target/linux/pistachio/patches-6.1/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch b/target/linux/pistachio/patches-6.6/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch
index b1070c3d30..b1070c3d30 100644
--- a/target/linux/pistachio/patches-6.1/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch
+++ b/target/linux/pistachio/patches-6.6/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch
diff --git a/target/linux/pistachio/patches-6.1/904-MIPS-DTS-img-marduk-Add-partition-name.patch b/target/linux/pistachio/patches-6.6/904-MIPS-DTS-img-marduk-Add-partition-name.patch
index 490027a702..490027a702 100644
--- a/target/linux/pistachio/patches-6.1/904-MIPS-DTS-img-marduk-Add-partition-name.patch
+++ b/target/linux/pistachio/patches-6.6/904-MIPS-DTS-img-marduk-Add-partition-name.patch
diff --git a/target/linux/pistachio/patches-6.1/905-MIPS-DTS-img-marduk-Add-led-aliases.patch b/target/linux/pistachio/patches-6.6/905-MIPS-DTS-img-marduk-Add-led-aliases.patch
index 8c03ddeea2..8c03ddeea2 100644
--- a/target/linux/pistachio/patches-6.1/905-MIPS-DTS-img-marduk-Add-led-aliases.patch
+++ b/target/linux/pistachio/patches-6.6/905-MIPS-DTS-img-marduk-Add-led-aliases.patch
diff --git a/target/linux/qoriq/Makefile b/target/linux/qoriq/Makefile
index 50d3187d84..59c413aa50 100644
--- a/target/linux/qoriq/Makefile
+++ b/target/linux/qoriq/Makefile
@@ -11,7 +11,7 @@ CPU_TYPE:=e5500
FEATURES:=boot-part ext4 fpu legacy-sdcard powerpc64 ramdisk rootfs-part rtc source-only
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
KERNELNAME:=zImage
diff --git a/target/linux/qoriq/config-6.1 b/target/linux/qoriq/config-6.1
deleted file mode 100644
index bf3b2cfae8..0000000000
--- a/target/linux/qoriq/config-6.1
+++ /dev/null
@@ -1,422 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_ALTIVEC=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_FORCE_MAX_ORDER=13
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
-CONFIG_ARCH_MMAP_RND_BITS=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=32
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
-CONFIG_ASN1=y
-CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
-CONFIG_AUDIT_ARCH=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BOOKE=y
-CONFIG_BOOKE_OR_40x=y
-CONFIG_BOOKE_WDT=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLK_QORIQ=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CORENET_GENERIC=y
-# CONFIG_CPUFREQ_DT is not set
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=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 is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_TEO=y
-CONFIG_CPU_ISOLATION=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_CRC32C_VPMSUM is not set
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_FSL_CAAM=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y
-# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set
-CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
-CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
-# CONFIG_CRYPTO_DEV_NX is not set
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ENGINE=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-# CONFIG_CRYPTO_MD5_PPC is not set
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RSA=y
-# CONFIG_CRYPTO_SHA1_PPC is not set
-CONFIG_CRYPTO_XTS=y
-CONFIG_DATA_SHIFT=12
-CONFIG_DEBUG_INFO=y
-CONFIG_DEFAULT_UIMAGE=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_OPS_BYPASS=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_E5500_CPU is not set
-CONFIG_E6500_CPU=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-# CONFIG_EDAC_CPC925 is not set
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_MPC85XX=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EPAPR_PARAVIRT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_F2FS_FS=y
-CONFIG_FIXED_PHY=y
-# CONFIG_FSL_BMAN_TEST is not set
-CONFIG_FSL_CORENET_CF=y
-CONFIG_FSL_CORENET_RCPM=y
-CONFIG_FSL_DMA=y
-CONFIG_FSL_DPAA=y
-# CONFIG_FSL_DPAA_CHECKING is not set
-CONFIG_FSL_DPAA_ETH=y
-CONFIG_FSL_EMB_PERFMON=y
-CONFIG_FSL_FMAN=y
-CONFIG_FSL_GUTS=y
-CONFIG_FSL_IFC=y
-CONFIG_FSL_LBC=y
-CONFIG_FSL_MPIC_TIMER_WAKEUP=y
-CONFIG_FSL_PAMU=y
-CONFIG_FSL_PCI=y
-# CONFIG_FSL_QMAN_TEST is not set
-CONFIG_FSL_SOC=y
-CONFIG_FSL_SOC_BOOKE=y
-CONFIG_FSL_XGMAC_MDIO=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FTL=y
-CONFIG_FUNCTION_ERROR_INJECTION=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_GIANFAR is not set
-CONFIG_GLOB=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_MPC8XXX=y
-CONFIG_GRO_CELLS=y
-# CONFIG_HANGCHECK_TIMER is not set
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HWMON=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_MPC=y
-CONFIG_ILLEGAL_POINTER_VALUE=0x5deadbeef0000000
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_IOMMU_API=y
-# CONFIG_IOMMU_DEBUGFS is not set
-# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
-CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
-# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
-CONFIG_IOMMU_HELPER=y
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_ISA_DMA_API=y
-CONFIG_JBD2=y
-CONFIG_JUMP_LABEL=y
-CONFIG_JUMP_LABEL_FEATURE_CHECKS=y
-# CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG is not set
-CONFIG_KALLSYMS=y
-CONFIG_KERNEL_GZIP=y
-CONFIG_KERNEL_START=0xc000000000000000
-CONFIG_KPROBES=y
-CONFIG_KRETPROBES=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MATH_EMULATION=y
-# CONFIG_MATH_EMULATION_FULL is not set
-CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_IO_ACCESSORS=y
-CONFIG_MMC_SDHCI_OF_ESDHC=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-# CONFIG_MMC_WBSD is not set
-CONFIG_MMIOWB=y
-CONFIG_MMU_GATHER_MERGE_VMAS=y
-CONFIG_MMU_GATHER_PAGE_SIZE=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MPIC=y
-CONFIG_MPIC_MSGR=y
-CONFIG_MPIC_TIMER=y
-CONFIG_MPILIB=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_FSL_IFC=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
-CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MV88E6XXX=y
-CONFIG_NET_DSA_TAG_DSA=y
-CONFIG_NET_DSA_TAG_DSA_COMMON=y
-CONFIG_NET_DSA_TAG_EDSA=y
-CONFIG_NET_DSA_TAG_OCELOT=y
-CONFIG_NET_DSA_TAG_TRAILER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NONSTATIC_KERNEL=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=24
-CONFIG_NR_IRQS=512
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DMA_DEFAULT_COHERENT=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IOMMU=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGSUSPEND=y
-CONFIG_OPTPROBES=y
-CONFIG_PACKING=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xc000000000000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_ARCH_FALLBACKS=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCS_LYNX=y
-CONFIG_PGTABLE_LEVELS=4
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PHYSICAL_START=0x00000000
-CONFIG_PHYS_64BIT=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PM=y
-# CONFIG_PMU_SYSFS is not set
-CONFIG_PM_CLK=y
-CONFIG_PPC=y
-CONFIG_PPC64=y
-CONFIG_PPC64_ELF_ABI_V1=y
-CONFIG_PPC_ADV_DEBUG_DACS=2
-CONFIG_PPC_ADV_DEBUG_DVCS=0
-CONFIG_PPC_ADV_DEBUG_IACS=2
-CONFIG_PPC_ADV_DEBUG_REGS=y
-CONFIG_PPC_BARRIER_NOSPEC=y
-CONFIG_PPC_BOOK3E_64=y
-# CONFIG_PPC_BOOK3S_64 is not set
-CONFIG_PPC_DAWR=y
-CONFIG_PPC_DOORBELL=y
-CONFIG_PPC_E500=y
-CONFIG_PPC_E500MC=y
-# CONFIG_PPC_EARLY_DEBUG is not set
-CONFIG_PPC_EPAPR_HV_PIC=y
-CONFIG_PPC_FPU=y
-CONFIG_PPC_FPU_REGS=y
-CONFIG_PPC_INDIRECT_PCI=y
-# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set
-CONFIG_PPC_KUAP=y
-# CONFIG_PPC_KUAP_DEBUG is not set
-CONFIG_PPC_KUEP=y
-CONFIG_PPC_MMU_NOHASH=y
-CONFIG_PPC_MSI_BITMAP=y
-CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
-CONFIG_PPC_PAGE_SHIFT=12
-# CONFIG_PPC_QEMU_E500 is not set
-CONFIG_PPC_QUEUED_SPINLOCKS=y
-CONFIG_PPC_SMP_MUXED_IPI=y
-CONFIG_PPC_UDBG_16550=y
-CONFIG_PPC_WERROR=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTE_64BIT=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PTP_1588_CLOCK_QORIQ=y
-CONFIG_QORIQ_CPUFREQ=y
-CONFIG_QORIQ_THERMAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-# CONFIG_RAVE_SP_CORE is not set
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RELOCATABLE=y
-# CONFIG_RELOCATABLE_TEST is not set
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-# CONFIG_SCOM_DEBUGFS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_DEV_BUS=y
-CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
-CONFIG_SERIAL_FSL_LINFLEXUART=y
-CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
-CONFIG_SERIAL_FSL_LPUART=y
-CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_FSL_ESPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SRCU=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_TARGET_CPU="e6500"
-CONFIG_TARGET_CPU_BOOL=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_THREAD_SHIFT=14
-# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-# CONFIG_UACCE is not set
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_FSL=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_UAS=y
-CONFIG_VGA_CONSOLE=y
-CONFIG_VIRT_CPU_ACCOUNTING=y
-CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XPS=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/target/linux/qoriq/config-6.6 b/target/linux/qoriq/config-6.6
new file mode 100644
index 0000000000..3f42563db1
--- /dev/null
+++ b/target/linux/qoriq/config-6.6
@@ -0,0 +1,430 @@
+CONFIG_64BIT=y
+CONFIG_ALTIVEC=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_DMA_DEFAULT_COHERENT=y
+CONFIG_ARCH_FORCE_MAX_ORDER=12
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=32
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
+CONFIG_ASN1=y
+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BOOKE=y
+CONFIG_BOOKE_OR_40x=y
+CONFIG_BOOKE_WDT=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLK_QORIQ=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CLZ_TAB=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CORENET_GENERIC=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=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 is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_TEO=y
+CONFIG_CPU_ISOLATION=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32C_VPMSUM is not set
+CONFIG_CRYPTO_CURVE25519=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
+# CONFIG_CRYPTO_DEV_NX is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ENGINE=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y
+CONFIG_CRYPTO_LIB_DES=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+# CONFIG_CRYPTO_MD5_PPC is not set
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RSA=y
+# CONFIG_CRYPTO_SHA1_PPC is not set
+CONFIG_CRYPTO_XTS=y
+CONFIG_DATA_SHIFT=12
+CONFIG_DEBUG_INFO=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_OPS_BYPASS=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_E5500_CPU is not set
+CONFIG_E6500_CPU=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EDAC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+# CONFIG_EDAC_CPC925 is not set
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_LEGACY_SYSFS=y
+CONFIG_EDAC_MPC85XX=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EPAPR_PARAVIRT=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_F2FS_FS=y
+CONFIG_FIXED_PHY=y
+# CONFIG_FSL_BMAN_TEST is not set
+CONFIG_FSL_CORENET_CF=y
+CONFIG_FSL_CORENET_RCPM=y
+CONFIG_FSL_DMA=y
+CONFIG_FSL_DPAA=y
+# CONFIG_FSL_DPAA_CHECKING is not set
+CONFIG_FSL_DPAA_ETH=y
+CONFIG_FSL_EMB_PERFMON=y
+CONFIG_FSL_FMAN=y
+CONFIG_FSL_GUTS=y
+CONFIG_FSL_IFC=y
+CONFIG_FSL_LBC=y
+CONFIG_FSL_MPIC_TIMER_WAKEUP=y
+CONFIG_FSL_PAMU=y
+CONFIG_FSL_PCI=y
+# CONFIG_FSL_QMAN_TEST is not set
+CONFIG_FSL_SOC=y
+CONFIG_FSL_SOC_BOOKE=y
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_FSL_XGMAC_MDIO=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FTL=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FUNCTION_ERROR_INJECTION=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_GIANFAR is not set
+CONFIG_GLOB=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_MPC8XXX=y
+CONFIG_GRO_CELLS=y
+# CONFIG_HANGCHECK_TIMER is not set
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_MPC=y
+CONFIG_ILLEGAL_POINTER_VALUE=0x5deadbeef0000000
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INTERRUPT_SANITIZE_REGISTERS=y
+# CONFIG_IOMMUFD is not set
+CONFIG_IOMMU_API=y
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
+CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
+# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
+CONFIG_IOMMU_HELPER=y
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_ISA_DMA_API=y
+CONFIG_JBD2=y
+CONFIG_JUMP_LABEL=y
+CONFIG_JUMP_LABEL_FEATURE_CHECKS=y
+# CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG is not set
+CONFIG_KALLSYMS=y
+CONFIG_KERNEL_GZIP=y
+CONFIG_KERNEL_START=0xc000000000000000
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MATH_EMULATION=y
+# CONFIG_MATH_EMULATION_FULL is not set
+CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMORY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_OF_ESDHC=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+# CONFIG_MMC_WBSD is not set
+CONFIG_MMIOWB=y
+CONFIG_MMU_GATHER_MERGE_VMAS=y
+CONFIG_MMU_GATHER_PAGE_SIZE=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MPIC=y
+CONFIG_MPIC_MSGR=y
+CONFIG_MPIC_TIMER=y
+CONFIG_MPILIB=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_FSL_IFC=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MV88E6XXX=y
+CONFIG_NET_DSA_TAG_DSA=y
+CONFIG_NET_DSA_TAG_DSA_COMMON=y
+CONFIG_NET_DSA_TAG_EDSA=y
+CONFIG_NET_DSA_TAG_OCELOT=y
+CONFIG_NET_DSA_TAG_TRAILER=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NONSTATIC_KERNEL=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=24
+CONFIG_NR_IRQS=512
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IOMMU=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OLD_SIGSUSPEND=y
+CONFIG_OPTPROBES=y
+CONFIG_PACKING=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xc000000000000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_ARCH_FALLBACKS=y
+CONFIG_PCS_LYNX=y
+CONFIG_PGTABLE_LEVELS=4
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_PHYS_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_PM=y
+# CONFIG_PMU_SYSFS is not set
+CONFIG_PM_CLK=y
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_PPC64_BIG_ENDIAN_ELF_ABI_V2=y
+CONFIG_PPC64_ELF_ABI_V2=y
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_BARRIER_NOSPEC=y
+CONFIG_PPC_BOOK3E_64=y
+# CONFIG_PPC_BOOK3S_64 is not set
+CONFIG_PPC_DAWR=y
+CONFIG_PPC_DOORBELL=y
+CONFIG_PPC_E500=y
+CONFIG_PPC_E500MC=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+CONFIG_PPC_EPAPR_HV_PIC=y
+CONFIG_PPC_FPU=y
+CONFIG_PPC_FPU_REGS=y
+CONFIG_PPC_HAS_LBARX_LHARX=y
+CONFIG_PPC_INDIRECT_PCI=y
+# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set
+CONFIG_PPC_KUAP=y
+# CONFIG_PPC_KUAP_DEBUG is not set
+CONFIG_PPC_KUEP=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MSI_BITMAP=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+CONFIG_PPC_PAGE_SHIFT=12
+# CONFIG_PPC_QEMU_E500 is not set
+CONFIG_PPC_QUEUED_SPINLOCKS=y
+CONFIG_PPC_SMP_MUXED_IPI=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_PPC_WERROR=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PTE_64BIT=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PTP_1588_CLOCK_QORIQ=y
+CONFIG_QORIQ_CPUFREQ=y
+CONFIG_QORIQ_THERMAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+# CONFIG_RAVE_SP_CORE is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RELOCATABLE=y
+# CONFIG_RELOCATABLE_TEST is not set
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+# CONFIG_SCOM_DEBUGFS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+CONFIG_SERIAL_FSL_LINFLEXUART=y
+CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SMT_NUM_THREADS_DYNAMIC=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BUS=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_ESPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_TARGET_CPU="e6500"
+CONFIG_TARGET_CPU_BOOL=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_THREAD_SHIFT=14
+# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
+CONFIG_TOOLS_SUPPORT_RELR=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+# CONFIG_UCLAMP_TASK is not set
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_UAS=y
+CONFIG_VGA_CONSOLE=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XPS=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts
new file mode 100644
index 0000000000..eba4d116ad
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts
@@ -0,0 +1,454 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+
+/dts-v1/;
+
+#include "ipq6018.dtsi"
+#include "ipq6018-fixed-smps.dtsi"
+#include "ipq6018-ess.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ /* Qualcomm Technologies, Inc. IPQ6018/AP-CP01-C3 */
+ model = "Cambium Networks XE3-4";
+ compatible = "cambiumnetworks,xe3-4", "qcom,ipq6018-cp01", "qcom,ipq6018";
+
+ aliases {
+ serial0 = &blsp1_uart3;
+ sdhc2 = &sdhc_1;
+ ethernet0 = &dp5;
+ ethernet1 = &dp4;
+ label-mac-device = &dp5;
+
+ led-boot = &led_status_amber;
+ led-failsafe = &led_status_amber;
+ led-running = &led_status_white;
+ led-upgrade = &led_status_amber;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ bootargs-append = " root=/dev/ubiblock0_1";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pins>;
+ pinctrl-names = "default";
+
+ led_status_white: status-white {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_STATUS;
+ gpio = <&tlmm 56 GPIO_ACTIVE_LOW>;
+ };
+
+ led_status_amber: status-amber {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_STATUS;
+ gpio = <&tlmm 35 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ reg_sd_vmmc: regulator-sdcard-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "sdcard-vmmc";
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ startup-delay-us = <200>;
+
+ gpio = <&tlmm 66 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_vmmc_en_default>;
+ };
+};
+
+&blsp1_uart3 {
+ pinctrl-0 = <&serial_3_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&blsp1_i2c3 {
+ pinctrl-0 = <&i2c_1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tlmm {
+ /* TZ has exclusive control over GPIO20 */
+ gpio-reserved-ranges = <20 1>;
+
+ mdio_pins: mdio-pins {
+ mdc {
+ pins = "gpio64";
+ function = "mdc";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ mdio {
+ pins = "gpio65";
+ function = "mdio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+
+ i2c_1_pins: i2c-1-state {
+ pins = "gpio42", "gpio43";
+ function = "blsp2_i2c";
+ drive-strength = <8>;
+ };
+
+ spi_0_pins: spi-0-state {
+ pins = "gpio38", "gpio39", "gpio40", "gpio41";
+ function = "blsp0_spi";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+
+ led_pins: led_pins {
+ leds {
+ pins = "gpio35", "gpio37", "gpio50";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+ };
+
+ sd_vmmc_en_default: sd-vmmc-en-default-state {
+ pins = "gpio66";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+
+ sd_pins: sd-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+ perst-gpio = <&tlmm 60 GPIO_ACTIVE_LOW>;
+
+ bridge@0,0 {
+ reg = <0x00000000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ wifi@1,0 {
+ status = "okay";
+
+ /* ath11k has no DT compatible for PCI cards */
+ compatible = "pci17cb,1104";
+ reg = <0x00010000 0 0 0 0>;
+
+ qcom,ath11k-fw-memory-mode = <0>;
+ qcom,ath11k-calibration-variant = "CambiumNetworks-XE34";
+ };
+ };
+};
+
+&sdhc_1 {
+ pinctrl-0 = <&sd_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+ vqmmc-supply = <&reg_sd_vmmc>;
+ bus-width = <4>;
+};
+
+&edma {
+ status = "okay";
+};
+
+&switch {
+ status = "okay";
+
+ switch_lan_bmp = <(ESS_PORT4 | ESS_PORT5)>;
+ switch_mac_mode = <MAC_MODE_PSGMII>;
+ switch_mac_mode2 = <MAC_MODE_SGMII_PLUS>;
+
+ qcom,port_phyinfo {
+ port@4 {
+ port_id = <4>;
+ phy_address = <3>;
+ };
+
+ port@5 {
+ port_id = <5>;
+ phy_address = <24>;
+ port_mac_sel = "QGMAC_PORT";
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <50000>;
+
+ ethernet-phy-package@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,qca8075-package";
+ reg = <0>;
+
+ qcom,package-mode = "psgmii";
+
+ qca8072: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <3>;
+ };
+ };
+
+ qca8081: ethernet-phy@24 {
+ compatible = "ethernet-phy-id004d.d101";
+ reg = <24>;
+ reset-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <50000>;
+ };
+};
+
+&dp4 {
+ status = "okay";
+
+ phy-handle = <&qca8072>;
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&eth1addr 0>;
+ label = "lan2";
+};
+
+&dp5 {
+ status = "okay";
+
+ phy-mode = "sgmii";
+ phy-handle = <&qca8081>;
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&ethaddr 0>;
+ label = "lan1";
+};
+
+&blsp1_spi1 {
+ pinctrl-0 = <&spi_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ /*
+ * U-boot looks for "n25q128a11" node,
+ * if we don't have it, it will spit out the following warning:
+ * "ipq: fdt fixup unable to find compatible node".
+ */
+ linux,modalias = "m25p80", "mx30uf2g18ac", "n25q128a11";
+ compatible = "micron,n25q128a11", "jedec,spi-nor";
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "0:SBL1";
+ reg = <0x0 0xc0000>;
+ read-only;
+ };
+
+ partition@c0000 {
+ label = "0:MIBIB";
+ reg = <0xc0000 0x10000>;
+ read-only;
+ };
+
+ partition@d0000 {
+ label = "0:BOOTCONFIG";
+ reg = <0xd0000 0x20000>;
+ read-only;
+ };
+
+ partition@f0000 {
+ label = "0:BOOTCONFIG1";
+ reg = <0xf0000 0x20000>;
+ read-only;
+ };
+
+ partition@110000 {
+ label = "0:QSEE";
+ reg = <0x110000 0x1a0000>;
+ read-only;
+ };
+
+ partition@2b0000 {
+ label = "0:QSEE_1";
+ reg = <0x2b0000 0x1a0000>;
+ read-only;
+ };
+
+ partition@450000 {
+ label = "0:DEVCFG";
+ reg = <0x450000 0x10000>;
+ read-only;
+ };
+
+ partition@460000 {
+ label = "mfginfo";
+ reg = <0x460000 0x10000>;
+ read-only;
+ };
+
+ partition@470000 {
+ label = "0:RPM";
+ reg = <0x470000 0x40000>;
+ read-only;
+ };
+
+ partition@4b0000 {
+ label = "0:RPM_1";
+ reg = <0x4b0000 0x40000>;
+ read-only;
+ };
+
+ partition@4f0000 {
+ label = "0:CDT";
+ reg = <0x4f0000 0x10000>;
+ read-only;
+ };
+
+ partition@500000 {
+ label = "0:CDT_1";
+ reg = <0x500000 0x10000>;
+ read-only;
+ };
+
+ partition@510000 {
+ compatible = "u-boot,env";
+ label = "0:APPSBLENV";
+ reg = <0x510000 0x10000>;
+
+ ethaddr: ethaddr {
+ #nvmem-cell-cells = <0>;
+ };
+
+ eth1addr: eth1addr {
+ #nvmem-cell-cells = <0>;
+ };
+
+ eth2addr: eth2addr {
+ #nvmem-cell-cells = <0>;
+ };
+
+ eth5addr: eth5addr {
+ #nvmem-cell-cells = <0>;
+ };
+ };
+
+ partition@520000 {
+ label = "0:APPSBL";
+ reg = <0x520000 0xa0000>;
+ read-only;
+ };
+
+ partition@5c0000 {
+ label = "0:APPSBL_1";
+ reg = <0x5c0000 0xa0000>;
+ read-only;
+ };
+
+ partition@660000 {
+ label = "0:ART";
+ reg = <0x660000 0x80000>;
+ read-only;
+ };
+ };
+ };
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
+&qpic_nand {
+ status = "okay";
+
+ nand@0 {
+ reg = <0>;
+
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ nand-bus-width = <8>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "rootfs";
+ reg = <0x0 0x6000000>;
+ };
+
+ partition@6000000 {
+ label = "rootfs_1";
+ reg = <0x6000000 0x6000000>;
+ };
+
+ partition@c000000 {
+ label = "NVRAM";
+ reg = <0xc000000 0x3000000>;
+ };
+
+ partition@f000000 {
+ label = "crashLog";
+ reg = <0xf000000 0x1000000>;
+ };
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+ qcom,ath11k-calibration-variant = "CambiumNetworks-XE34";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&eth2addr>;
+};
+
+&qusb_phy_1 {
+ status = "okay";
+};
+
+&usb2 {
+ status = "okay";
+};
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi
new file mode 100644
index 0000000000..e867daf866
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/*
+ * Board does not use companion MP5496 PMIC,
+ * but rather uses fixed external SMPS.
+ */
+
+&rpm {
+ status = "disabled";
+};
+
+&CPU0 {
+ /delete-property/ cpu-supply;
+};
+
+&CPU1 {
+ /delete-property/ cpu-supply;
+};
+
+&CPU2 {
+ /delete-property/ cpu-supply;
+};
+
+&CPU3 {
+ /delete-property/ cpu-supply;
+};
+
+&cpu_opp_table {
+ opp-864000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1056000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1320000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1440000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1608000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1800000000 {
+ opp-microvolt = <1100000>;
+ };
+};
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts
new file mode 100644
index 0000000000..500847c98b
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause
+
+/dts-v1/;
+
+#include "ipq8074.dtsi"
+#include "ipq8074-hk-cpu.dtsi"
+#include "ipq8074-ess.dtsi"
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "TP-Link EAP660 HD v1";
+ compatible = "tplink,eap660hd-v1", "qcom,ipq8074";
+
+ aliases {
+ serial0 = &blsp1_uart5;
+ led-boot = &led_status_blue;
+ led-failsafe = &led_status_blue;
+ led-running = &led_status_blue;
+ led-upgrade = &led_status_blue;
+ };
+
+ chosen {
+ stdout-path = "serial0,115200n8";
+ bootargs-append = " root=/dev/ubiblock0_1";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&tlmm 50 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_blue: status-blue {
+ function = LED_FUNCTION_STATUS;
+ gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+ };
+};
+
+&blsp1_uart5 {
+ status = "okay";
+};
+
+&tlmm {
+ mdio_pins: mdio-pins {
+ mdc {
+ pins = "gpio68";
+ function = "mdc";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ mdio {
+ pins = "gpio69";
+ function = "mdio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
+
+ qca8081_28: ethernet-phy@28 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <28>;
+ };
+};
+
+&dp5 {
+ status = "okay";
+ phy-mode = "sgmii";
+ phy-handle = <&qca8081_28>;
+ label = "lan";
+};
+
+&switch {
+ status = "okay";
+ switch_lan_bmp = <ESS_PORT5>;
+ switch_mac_mode1 = <MAC_MODE_SGMII_PLUS>;
+
+ qcom,port_phyinfo {
+ port@5 {
+ phy_address = <28>;
+ port_id = <5>;
+ port_mac_sel = "QGMAC_PORT";
+ };
+ };
+};
+
+&edma {
+ status = "okay";
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
+&qpic_nand {
+ status = "okay";
+
+ nand@0 {
+ reg = <0>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ nand-bus-width = <8>;
+
+ partitions {
+ compatible = "qcom,smem-part";
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+ qcom,ath11k-calibration-variant = "TP-Link-EAP660-HD-v1";
+};
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi
index 76838b86c5..194540aac1 100644
--- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi
@@ -17,407 +17,413 @@
};
&soc {
- switch: ess-switch@3a000000 {
- compatible = "qcom,ess-switch-ipq807x";
- reg = <0x3a000000 0x1000000>;
- switch_access_mode = "local bus";
- switch_cpu_bmp = <ESS_PORT0>; /* cpu port bitmap */
- switch_inner_bmp = <ESS_PORT7>; /*inner port bitmap*/
- clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>,
- <&gcc GCC_CMN_12GPLL_SYS_CLK>,
- <&gcc GCC_UNIPHY0_AHB_CLK>,
- <&gcc GCC_UNIPHY0_SYS_CLK>,
- <&gcc GCC_UNIPHY1_AHB_CLK>,
- <&gcc GCC_UNIPHY1_SYS_CLK>,
- <&gcc GCC_UNIPHY2_AHB_CLK>,
- <&gcc GCC_UNIPHY2_SYS_CLK>,
- <&gcc GCC_PORT1_MAC_CLK>,
- <&gcc GCC_PORT2_MAC_CLK>,
- <&gcc GCC_PORT3_MAC_CLK>,
- <&gcc GCC_PORT4_MAC_CLK>,
- <&gcc GCC_PORT5_MAC_CLK>,
- <&gcc GCC_PORT6_MAC_CLK>,
- <&gcc GCC_NSS_PPE_CLK>,
- <&gcc GCC_NSS_PPE_CFG_CLK>,
- <&gcc GCC_NSSNOC_PPE_CLK>,
- <&gcc GCC_NSSNOC_PPE_CFG_CLK>,
- <&gcc GCC_NSS_EDMA_CLK>,
- <&gcc GCC_NSS_EDMA_CFG_CLK>,
- <&gcc GCC_NSS_PPE_IPE_CLK>,
- <&gcc GCC_NSS_PPE_BTQ_CLK>,
- <&gcc GCC_MDIO_AHB_CLK>,
- <&gcc GCC_NSS_NOC_CLK>,
- <&gcc GCC_NSSNOC_SNOC_CLK>,
- <&gcc GCC_MEM_NOC_NSS_AXI_CLK>,
- <&gcc GCC_NSS_CRYPTO_CLK>,
- <&gcc GCC_NSS_IMEM_CLK>,
- <&gcc GCC_NSS_PTP_REF_CLK>,
- <&gcc GCC_NSS_PORT1_RX_CLK>,
- <&gcc GCC_NSS_PORT1_TX_CLK>,
- <&gcc GCC_NSS_PORT2_RX_CLK>,
- <&gcc GCC_NSS_PORT2_TX_CLK>,
- <&gcc GCC_NSS_PORT3_RX_CLK>,
- <&gcc GCC_NSS_PORT3_TX_CLK>,
- <&gcc GCC_NSS_PORT4_RX_CLK>,
- <&gcc GCC_NSS_PORT4_TX_CLK>,
- <&gcc GCC_NSS_PORT5_RX_CLK>,
- <&gcc GCC_NSS_PORT5_TX_CLK>,
- <&gcc GCC_NSS_PORT6_RX_CLK>,
- <&gcc GCC_NSS_PORT6_TX_CLK>,
- <&gcc GCC_UNIPHY0_PORT1_RX_CLK>,
- <&gcc GCC_UNIPHY0_PORT1_TX_CLK>,
- <&gcc GCC_UNIPHY0_PORT2_RX_CLK>,
- <&gcc GCC_UNIPHY0_PORT2_TX_CLK>,
- <&gcc GCC_UNIPHY0_PORT3_RX_CLK>,
- <&gcc GCC_UNIPHY0_PORT3_TX_CLK>,
- <&gcc GCC_UNIPHY0_PORT4_RX_CLK>,
- <&gcc GCC_UNIPHY0_PORT4_TX_CLK>,
- <&gcc GCC_UNIPHY0_PORT5_RX_CLK>,
- <&gcc GCC_UNIPHY0_PORT5_TX_CLK>,
- <&gcc GCC_UNIPHY1_PORT5_RX_CLK>,
- <&gcc GCC_UNIPHY1_PORT5_TX_CLK>,
- <&gcc GCC_UNIPHY2_PORT6_RX_CLK>,
- <&gcc GCC_UNIPHY2_PORT6_TX_CLK>,
- <&gcc NSS_PORT5_RX_CLK_SRC>,
- <&gcc NSS_PORT5_TX_CLK_SRC>;
- clock-names = "cmn_ahb_clk", "cmn_sys_clk",
- "uniphy0_ahb_clk", "uniphy0_sys_clk",
- "uniphy1_ahb_clk", "uniphy1_sys_clk",
- "uniphy2_ahb_clk", "uniphy2_sys_clk",
- "port1_mac_clk", "port2_mac_clk",
- "port3_mac_clk", "port4_mac_clk",
- "port5_mac_clk", "port6_mac_clk",
- "nss_ppe_clk", "nss_ppe_cfg_clk",
- "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk",
- "nss_edma_clk", "nss_edma_cfg_clk",
- "nss_ppe_ipe_clk", "nss_ppe_btq_clk",
- "gcc_mdio_ahb_clk", "gcc_nss_noc_clk",
- "gcc_nssnoc_snoc_clk",
- "gcc_mem_noc_nss_axi_clk",
- "gcc_nss_crypto_clk",
- "gcc_nss_imem_clk",
- "gcc_nss_ptp_ref_clk",
- "nss_port1_rx_clk", "nss_port1_tx_clk",
- "nss_port2_rx_clk", "nss_port2_tx_clk",
- "nss_port3_rx_clk", "nss_port3_tx_clk",
- "nss_port4_rx_clk", "nss_port4_tx_clk",
- "nss_port5_rx_clk", "nss_port5_tx_clk",
- "nss_port6_rx_clk", "nss_port6_tx_clk",
- "uniphy0_port1_rx_clk",
- "uniphy0_port1_tx_clk",
- "uniphy0_port2_rx_clk",
- "uniphy0_port2_tx_clk",
- "uniphy0_port3_rx_clk",
- "uniphy0_port3_tx_clk",
- "uniphy0_port4_rx_clk",
- "uniphy0_port4_tx_clk",
- "uniphy0_port5_rx_clk",
- "uniphy0_port5_tx_clk",
- "uniphy1_port5_rx_clk",
- "uniphy1_port5_tx_clk",
- "uniphy2_port6_rx_clk",
- "uniphy2_port6_tx_clk",
- "nss_port5_rx_clk_src",
- "nss_port5_tx_clk_src";
- resets = <&gcc GCC_PPE_FULL_RESET>,
- <&gcc GCC_UNIPHY0_SOFT_RESET>,
- <&gcc GCC_UNIPHY0_XPCS_RESET>,
- <&gcc GCC_UNIPHY1_SOFT_RESET>,
- <&gcc GCC_UNIPHY1_XPCS_RESET>,
- <&gcc GCC_UNIPHY2_SOFT_RESET>,
- <&gcc GCC_UNIPHY2_XPCS_RESET>,
- <&gcc GCC_NSSPORT1_RESET>,
- <&gcc GCC_NSSPORT2_RESET>,
- <&gcc GCC_NSSPORT3_RESET>,
- <&gcc GCC_NSSPORT4_RESET>,
- <&gcc GCC_NSSPORT5_RESET>,
- <&gcc GCC_NSSPORT6_RESET>;
- reset-names = "ppe_rst", "uniphy0_soft_rst",
- "uniphy0_xpcs_rst", "uniphy1_soft_rst",
- "uniphy1_xpcs_rst", "uniphy2_soft_rst",
- "uniphy2_xpcs_rst", "nss_port1_rst",
- "nss_port2_rst", "nss_port3_rst",
- "nss_port4_rst", "nss_port5_rst",
- "nss_port6_rst";
- mdio-bus = <&mdio>;
+ ess_instance: ess-instance {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ num_devices = <1>;
- switch_mac_mode = <MAC_MODE_DISABLED>; /* MAC mode for UNIPHY instance 0 */
- switch_mac_mode1 = <MAC_MODE_DISABLED>; /* MAC mode for UNIPHY instance 1 */
- switch_mac_mode2 = <MAC_MODE_DISABLED>; /* MAC mode for UNIPHY instance 2 */
+ switch: ess-switch@3a000000 {
+ compatible = "qcom,ess-switch-ipq807x";
+ reg = <0x3a000000 0x1000000>;
+ switch_access_mode = "local bus";
+ switch_cpu_bmp = <ESS_PORT0>; /* cpu port bitmap */
+ switch_inner_bmp = <ESS_PORT7>; /*inner port bitmap*/
+ clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>,
+ <&gcc GCC_CMN_12GPLL_SYS_CLK>,
+ <&gcc GCC_UNIPHY0_AHB_CLK>,
+ <&gcc GCC_UNIPHY0_SYS_CLK>,
+ <&gcc GCC_UNIPHY1_AHB_CLK>,
+ <&gcc GCC_UNIPHY1_SYS_CLK>,
+ <&gcc GCC_UNIPHY2_AHB_CLK>,
+ <&gcc GCC_UNIPHY2_SYS_CLK>,
+ <&gcc GCC_PORT1_MAC_CLK>,
+ <&gcc GCC_PORT2_MAC_CLK>,
+ <&gcc GCC_PORT3_MAC_CLK>,
+ <&gcc GCC_PORT4_MAC_CLK>,
+ <&gcc GCC_PORT5_MAC_CLK>,
+ <&gcc GCC_PORT6_MAC_CLK>,
+ <&gcc GCC_NSS_PPE_CLK>,
+ <&gcc GCC_NSS_PPE_CFG_CLK>,
+ <&gcc GCC_NSSNOC_PPE_CLK>,
+ <&gcc GCC_NSSNOC_PPE_CFG_CLK>,
+ <&gcc GCC_NSS_EDMA_CLK>,
+ <&gcc GCC_NSS_EDMA_CFG_CLK>,
+ <&gcc GCC_NSS_PPE_IPE_CLK>,
+ <&gcc GCC_NSS_PPE_BTQ_CLK>,
+ <&gcc GCC_MDIO_AHB_CLK>,
+ <&gcc GCC_NSS_NOC_CLK>,
+ <&gcc GCC_NSSNOC_SNOC_CLK>,
+ <&gcc GCC_MEM_NOC_NSS_AXI_CLK>,
+ <&gcc GCC_NSS_CRYPTO_CLK>,
+ <&gcc GCC_NSS_IMEM_CLK>,
+ <&gcc GCC_NSS_PTP_REF_CLK>,
+ <&gcc GCC_NSS_PORT1_RX_CLK>,
+ <&gcc GCC_NSS_PORT1_TX_CLK>,
+ <&gcc GCC_NSS_PORT2_RX_CLK>,
+ <&gcc GCC_NSS_PORT2_TX_CLK>,
+ <&gcc GCC_NSS_PORT3_RX_CLK>,
+ <&gcc GCC_NSS_PORT3_TX_CLK>,
+ <&gcc GCC_NSS_PORT4_RX_CLK>,
+ <&gcc GCC_NSS_PORT4_TX_CLK>,
+ <&gcc GCC_NSS_PORT5_RX_CLK>,
+ <&gcc GCC_NSS_PORT5_TX_CLK>,
+ <&gcc GCC_NSS_PORT6_RX_CLK>,
+ <&gcc GCC_NSS_PORT6_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT1_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT1_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT2_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT2_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT3_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT3_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT4_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT4_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT5_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT5_TX_CLK>,
+ <&gcc GCC_UNIPHY1_PORT5_RX_CLK>,
+ <&gcc GCC_UNIPHY1_PORT5_TX_CLK>,
+ <&gcc GCC_UNIPHY2_PORT6_RX_CLK>,
+ <&gcc GCC_UNIPHY2_PORT6_TX_CLK>,
+ <&gcc NSS_PORT5_RX_CLK_SRC>,
+ <&gcc NSS_PORT5_TX_CLK_SRC>;
+ clock-names = "cmn_ahb_clk", "cmn_sys_clk",
+ "uniphy0_ahb_clk", "uniphy0_sys_clk",
+ "uniphy1_ahb_clk", "uniphy1_sys_clk",
+ "uniphy2_ahb_clk", "uniphy2_sys_clk",
+ "port1_mac_clk", "port2_mac_clk",
+ "port3_mac_clk", "port4_mac_clk",
+ "port5_mac_clk", "port6_mac_clk",
+ "nss_ppe_clk", "nss_ppe_cfg_clk",
+ "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk",
+ "nss_edma_clk", "nss_edma_cfg_clk",
+ "nss_ppe_ipe_clk", "nss_ppe_btq_clk",
+ "gcc_mdio_ahb_clk", "gcc_nss_noc_clk",
+ "gcc_nssnoc_snoc_clk",
+ "gcc_mem_noc_nss_axi_clk",
+ "gcc_nss_crypto_clk",
+ "gcc_nss_imem_clk",
+ "gcc_nss_ptp_ref_clk",
+ "nss_port1_rx_clk", "nss_port1_tx_clk",
+ "nss_port2_rx_clk", "nss_port2_tx_clk",
+ "nss_port3_rx_clk", "nss_port3_tx_clk",
+ "nss_port4_rx_clk", "nss_port4_tx_clk",
+ "nss_port5_rx_clk", "nss_port5_tx_clk",
+ "nss_port6_rx_clk", "nss_port6_tx_clk",
+ "uniphy0_port1_rx_clk",
+ "uniphy0_port1_tx_clk",
+ "uniphy0_port2_rx_clk",
+ "uniphy0_port2_tx_clk",
+ "uniphy0_port3_rx_clk",
+ "uniphy0_port3_tx_clk",
+ "uniphy0_port4_rx_clk",
+ "uniphy0_port4_tx_clk",
+ "uniphy0_port5_rx_clk",
+ "uniphy0_port5_tx_clk",
+ "uniphy1_port5_rx_clk",
+ "uniphy1_port5_tx_clk",
+ "uniphy2_port6_rx_clk",
+ "uniphy2_port6_tx_clk",
+ "nss_port5_rx_clk_src",
+ "nss_port5_tx_clk_src";
+ resets = <&gcc GCC_PPE_FULL_RESET>,
+ <&gcc GCC_UNIPHY0_SOFT_RESET>,
+ <&gcc GCC_UNIPHY0_XPCS_RESET>,
+ <&gcc GCC_UNIPHY1_SOFT_RESET>,
+ <&gcc GCC_UNIPHY1_XPCS_RESET>,
+ <&gcc GCC_UNIPHY2_SOFT_RESET>,
+ <&gcc GCC_UNIPHY2_XPCS_RESET>,
+ <&gcc GCC_NSSPORT1_RESET>,
+ <&gcc GCC_NSSPORT2_RESET>,
+ <&gcc GCC_NSSPORT3_RESET>,
+ <&gcc GCC_NSSPORT4_RESET>,
+ <&gcc GCC_NSSPORT5_RESET>,
+ <&gcc GCC_NSSPORT6_RESET>;
+ reset-names = "ppe_rst", "uniphy0_soft_rst",
+ "uniphy0_xpcs_rst", "uniphy1_soft_rst",
+ "uniphy1_xpcs_rst", "uniphy2_soft_rst",
+ "uniphy2_xpcs_rst", "nss_port1_rst",
+ "nss_port2_rst", "nss_port3_rst",
+ "nss_port4_rst", "nss_port5_rst",
+ "nss_port6_rst";
+ mdio-bus = <&mdio>;
- bm_tick_mode = <0>; /* bm tick mode */
- tm_tick_mode = <0>; /* tm tick mode */
+ switch_mac_mode = <MAC_MODE_DISABLED>; /* MAC mode for UNIPHY instance 0 */
+ switch_mac_mode1 = <MAC_MODE_DISABLED>; /* MAC mode for UNIPHY instance 1 */
+ switch_mac_mode2 = <MAC_MODE_DISABLED>; /* MAC mode for UNIPHY instance 2 */
- status = "disabled";
+ bm_tick_mode = <0>; /* bm tick mode */
+ tm_tick_mode = <0>; /* tm tick mode */
- port_scheduler_resource {
- port@0 {
- port_id = <0>;
- ucast_queue = <0 143>;
- mcast_queue = <256 271>;
- l0sp = <0 35>;
- l0cdrr = <0 47>;
- l0edrr = <0 47>;
- l1cdrr = <0 7>;
- l1edrr = <0 7>;
- };
- port@1 {
- port_id = <1>;
- ucast_queue = <144 159>;
- mcast_queue = <272 275>;
- l0sp = <36 39>;
- l0cdrr = <48 63>;
- l0edrr = <48 63>;
- l1cdrr = <8 11>;
- l1edrr = <8 11>;
- };
- port@2 {
- port_id = <2>;
- ucast_queue = <160 175>;
- mcast_queue = <276 279>;
- l0sp = <40 43>;
- l0cdrr = <64 79>;
- l0edrr = <64 79>;
- l1cdrr = <12 15>;
- l1edrr = <12 15>;
- };
- port@3 {
- port_id = <3>;
- ucast_queue = <176 191>;
- mcast_queue = <280 283>;
- l0sp = <44 47>;
- l0cdrr = <80 95>;
- l0edrr = <80 95>;
- l1cdrr = <16 19>;
- l1edrr = <16 19>;
- };
- port@4 {
- port_id = <4>;
- ucast_queue = <192 207>;
- mcast_queue = <284 287>;
- l0sp = <48 51>;
- l0cdrr = <96 111>;
- l0edrr = <96 111>;
- l1cdrr = <20 23>;
- l1edrr = <20 23>;
- };
- port@5 {
- port_id = <5>;
- ucast_queue = <208 223>;
- mcast_queue = <288 291>;
- l0sp = <52 55>;
- l0cdrr = <112 127>;
- l0edrr = <112 127>;
- l1cdrr = <24 27>;
- l1edrr = <24 27>;
- };
- port@6 {
- port_id = <6>;
- ucast_queue = <224 239>;
- mcast_queue = <292 295>;
- l0sp = <56 59>;
- l0cdrr = <128 143>;
- l0edrr = <128 143>;
- l1cdrr = <28 31>;
- l1edrr = <28 31>;
- };
- port@7 {
- port_id = <7>;
- ucast_queue = <240 255>;
- mcast_queue = <296 299>;
- l0sp = <60 63>;
- l0cdrr = <144 159>;
- l0edrr = <144 159>;
- l1cdrr = <32 35>;
- l1edrr = <32 35>;
- };
- };
- port_scheduler_config {
- port@0 {
- port_id = <0>;
- l1scheduler {
- group@0 {
- sp = <0 1>; /*L0 SPs*/
- /*cpri cdrr epri edrr*/
- cfg = <0 0 0 0>;
- };
+ status = "disabled";
+
+ port_scheduler_resource {
+ port@0 {
+ port_id = <0>;
+ ucast_queue = <0 143>;
+ mcast_queue = <256 271>;
+ l0sp = <0 35>;
+ l0cdrr = <0 47>;
+ l0edrr = <0 47>;
+ l1cdrr = <0 7>;
+ l1edrr = <0 7>;
};
- l0scheduler {
- group@0 {
- /*unicast queues*/
- ucast_queue = <0 4 8>;
- /*multicast queues*/
- mcast_queue = <256 260>;
- /*sp cpri cdrr epri edrr*/
- cfg = <0 0 0 0 0>;
- };
- group@1 {
- ucast_queue = <1 5 9>;
- mcast_queue = <257 261>;
- cfg = <0 1 1 1 1>;
- };
- group@2 {
- ucast_queue = <2 6 10>;
- mcast_queue = <258 262>;
- cfg = <0 2 2 2 2>;
- };
- group@3 {
- ucast_queue = <3 7 11>;
- mcast_queue = <259 263>;
- cfg = <0 3 3 3 3>;
- };
+ port@1 {
+ port_id = <1>;
+ ucast_queue = <144 159>;
+ mcast_queue = <272 275>;
+ l0sp = <36 39>;
+ l0cdrr = <48 63>;
+ l0edrr = <48 63>;
+ l1cdrr = <8 11>;
+ l1edrr = <8 11>;
};
- };
- port@1 {
- port_id = <1>;
- l1scheduler {
- group@0 {
- sp = <36>;
- cfg = <0 8 0 8>;
- };
- group@1 {
- sp = <37>;
- cfg = <1 9 1 9>;
- };
+ port@2 {
+ port_id = <2>;
+ ucast_queue = <160 175>;
+ mcast_queue = <276 279>;
+ l0sp = <40 43>;
+ l0cdrr = <64 79>;
+ l0edrr = <64 79>;
+ l1cdrr = <12 15>;
+ l1edrr = <12 15>;
};
- l0scheduler {
- group@0 {
- ucast_queue = <144>;
- ucast_loop_pri = <16>;
- mcast_queue = <272>;
- mcast_loop_pri = <4>;
- cfg = <36 0 48 0 48>;
- };
+ port@3 {
+ port_id = <3>;
+ ucast_queue = <176 191>;
+ mcast_queue = <280 283>;
+ l0sp = <44 47>;
+ l0cdrr = <80 95>;
+ l0edrr = <80 95>;
+ l1cdrr = <16 19>;
+ l1edrr = <16 19>;
};
- };
- port@2 {
- port_id = <2>;
- l1scheduler {
- group@0 {
- sp = <40>;
- cfg = <0 12 0 12>;
- };
- group@1 {
- sp = <41>;
- cfg = <1 13 1 13>;
- };
+ port@4 {
+ port_id = <4>;
+ ucast_queue = <192 207>;
+ mcast_queue = <284 287>;
+ l0sp = <48 51>;
+ l0cdrr = <96 111>;
+ l0edrr = <96 111>;
+ l1cdrr = <20 23>;
+ l1edrr = <20 23>;
};
- l0scheduler {
- group@0 {
- ucast_queue = <160>;
- ucast_loop_pri = <16>;
- mcast_queue = <276>;
- mcast_loop_pri = <4>;
- cfg = <40 0 64 0 64>;
- };
+ port@5 {
+ port_id = <5>;
+ ucast_queue = <208 223>;
+ mcast_queue = <288 291>;
+ l0sp = <52 55>;
+ l0cdrr = <112 127>;
+ l0edrr = <112 127>;
+ l1cdrr = <24 27>;
+ l1edrr = <24 27>;
};
- };
- port@3 {
- port_id = <3>;
- l1scheduler {
- group@0 {
- sp = <44>;
- cfg = <0 16 0 16>;
- };
- group@1 {
- sp = <45>;
- cfg = <1 17 1 17>;
- };
+ port@6 {
+ port_id = <6>;
+ ucast_queue = <224 239>;
+ mcast_queue = <292 295>;
+ l0sp = <56 59>;
+ l0cdrr = <128 143>;
+ l0edrr = <128 143>;
+ l1cdrr = <28 31>;
+ l1edrr = <28 31>;
};
- l0scheduler {
- group@0 {
- ucast_queue = <176>;
- ucast_loop_pri = <16>;
- mcast_queue = <280>;
- mcast_loop_pri = <4>;
- cfg = <44 0 80 0 80>;
- };
+ port@7 {
+ port_id = <7>;
+ ucast_queue = <240 255>;
+ mcast_queue = <296 299>;
+ l0sp = <60 63>;
+ l0cdrr = <144 159>;
+ l0edrr = <144 159>;
+ l1cdrr = <32 35>;
+ l1edrr = <32 35>;
};
};
- port@4 {
- port_id = <4>;
- l1scheduler {
- group@0 {
- sp = <48>;
- cfg = <0 20 0 20>;
+ port_scheduler_config {
+ port@0 {
+ port_id = <0>;
+ l1scheduler {
+ group@0 {
+ sp = <0 1>; /*L0 SPs*/
+ /*cpri cdrr epri edrr*/
+ cfg = <0 0 0 0>;
+ };
};
- group@1 {
- sp = <49>;
- cfg = <1 21 1 21>;
+ l0scheduler {
+ group@0 {
+ /*unicast queues*/
+ ucast_queue = <0 4 8>;
+ /*multicast queues*/
+ mcast_queue = <256 260>;
+ /*sp cpri cdrr epri edrr*/
+ cfg = <0 0 0 0 0>;
+ };
+ group@1 {
+ ucast_queue = <1 5 9>;
+ mcast_queue = <257 261>;
+ cfg = <0 1 1 1 1>;
+ };
+ group@2 {
+ ucast_queue = <2 6 10>;
+ mcast_queue = <258 262>;
+ cfg = <0 2 2 2 2>;
+ };
+ group@3 {
+ ucast_queue = <3 7 11>;
+ mcast_queue = <259 263>;
+ cfg = <0 3 3 3 3>;
+ };
};
};
- l0scheduler {
- group@0 {
- ucast_queue = <192>;
- ucast_loop_pri = <16>;
- mcast_queue = <284>;
- mcast_loop_pri = <4>;
- cfg = <48 0 96 0 96>;
+ port@1 {
+ port_id = <1>;
+ l1scheduler {
+ group@0 {
+ sp = <36>;
+ cfg = <0 8 0 8>;
+ };
+ group@1 {
+ sp = <37>;
+ cfg = <1 9 1 9>;
+ };
+ };
+ l0scheduler {
+ group@0 {
+ ucast_queue = <144>;
+ ucast_loop_pri = <16>;
+ mcast_queue = <272>;
+ mcast_loop_pri = <4>;
+ cfg = <36 0 48 0 48>;
+ };
};
};
- };
- port@5 {
- port_id = <5>;
- l1scheduler {
- group@0 {
- sp = <52>;
- cfg = <0 24 0 24>;
+ port@2 {
+ port_id = <2>;
+ l1scheduler {
+ group@0 {
+ sp = <40>;
+ cfg = <0 12 0 12>;
+ };
+ group@1 {
+ sp = <41>;
+ cfg = <1 13 1 13>;
+ };
};
- group@1 {
- sp = <53>;
- cfg = <1 25 1 25>;
+ l0scheduler {
+ group@0 {
+ ucast_queue = <160>;
+ ucast_loop_pri = <16>;
+ mcast_queue = <276>;
+ mcast_loop_pri = <4>;
+ cfg = <40 0 64 0 64>;
+ };
};
};
- l0scheduler {
- group@0 {
- ucast_queue = <208>;
- ucast_loop_pri = <16>;
- mcast_queue = <288>;
- mcast_loop_pri = <4>;
- cfg = <52 0 112 0 112>;
+ port@3 {
+ port_id = <3>;
+ l1scheduler {
+ group@0 {
+ sp = <44>;
+ cfg = <0 16 0 16>;
+ };
+ group@1 {
+ sp = <45>;
+ cfg = <1 17 1 17>;
+ };
+ };
+ l0scheduler {
+ group@0 {
+ ucast_queue = <176>;
+ ucast_loop_pri = <16>;
+ mcast_queue = <280>;
+ mcast_loop_pri = <4>;
+ cfg = <44 0 80 0 80>;
+ };
};
};
- };
- port@6 {
- port_id = <6>;
- l1scheduler {
- group@0 {
- sp = <56>;
- cfg = <0 28 0 28>;
+ port@4 {
+ port_id = <4>;
+ l1scheduler {
+ group@0 {
+ sp = <48>;
+ cfg = <0 20 0 20>;
+ };
+ group@1 {
+ sp = <49>;
+ cfg = <1 21 1 21>;
+ };
};
- group@1 {
- sp = <57>;
- cfg = <1 29 1 29>;
+ l0scheduler {
+ group@0 {
+ ucast_queue = <192>;
+ ucast_loop_pri = <16>;
+ mcast_queue = <284>;
+ mcast_loop_pri = <4>;
+ cfg = <48 0 96 0 96>;
+ };
};
};
- l0scheduler {
- group@0 {
- ucast_queue = <224>;
- ucast_loop_pri = <16>;
- mcast_queue = <292>;
- mcast_loop_pri = <4>;
- cfg = <56 0 128 0 128>;
+ port@5 {
+ port_id = <5>;
+ l1scheduler {
+ group@0 {
+ sp = <52>;
+ cfg = <0 24 0 24>;
+ };
+ group@1 {
+ sp = <53>;
+ cfg = <1 25 1 25>;
+ };
+ };
+ l0scheduler {
+ group@0 {
+ ucast_queue = <208>;
+ ucast_loop_pri = <16>;
+ mcast_queue = <288>;
+ mcast_loop_pri = <4>;
+ cfg = <52 0 112 0 112>;
+ };
};
};
- };
- port@7 {
- port_id = <7>;
- l1scheduler {
- group@0 {
- sp = <60>;
- cfg = <0 32 0 32>;
+ port@6 {
+ port_id = <6>;
+ l1scheduler {
+ group@0 {
+ sp = <56>;
+ cfg = <0 28 0 28>;
+ };
+ group@1 {
+ sp = <57>;
+ cfg = <1 29 1 29>;
+ };
};
- group@1 {
- sp = <61>;
- cfg = <1 33 1 33>;
+ l0scheduler {
+ group@0 {
+ ucast_queue = <224>;
+ ucast_loop_pri = <16>;
+ mcast_queue = <292>;
+ mcast_loop_pri = <4>;
+ cfg = <56 0 128 0 128>;
+ };
};
};
- l0scheduler {
- group@0 {
- ucast_queue = <240>;
- ucast_loop_pri = <16>;
- mcast_queue = <296>;
- cfg = <60 0 144 0 144>;
+ port@7 {
+ port_id = <7>;
+ l1scheduler {
+ group@0 {
+ sp = <60>;
+ cfg = <0 32 0 32>;
+ };
+ group@1 {
+ sp = <61>;
+ cfg = <1 33 1 33>;
+ };
+ };
+ l0scheduler {
+ group@0 {
+ ucast_queue = <240>;
+ ucast_loop_pri = <16>;
+ mcast_queue = <296>;
+ cfg = <60 0 144 0 144>;
+ };
};
};
};
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rt-ax89x.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rt-ax89x.dts
new file mode 100644
index 0000000000..4af942c289
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rt-ax89x.dts
@@ -0,0 +1,741 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/* Copyright (c) 2024, Robert Marko <robimarko@gmail.com> */
+
+/dts-v1/;
+
+#include "ipq8074.dtsi"
+#include "ipq8074-hk-cpu.dtsi"
+#include "ipq8074-ess.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Asus RT-AX89X";
+ compatible = "asus,rt-ax89x", "qcom,ipq8074";
+
+ aliases {
+ serial0 = &blsp1_uart5;
+ mdio-gpio0 = &mdio1;
+ ethernet0 = &dp1;
+ ethernet1 = &dp2;
+ ethernet2 = &dp3;
+ ethernet3 = &dp4;
+ ethernet4 = &dp5_syn;
+ ethernet5 = &dp6_syn;
+ led-boot = &led_pwr;
+ led-failsafe = &led_pwr;
+ led-running = &led_pwr;
+ led-upgrade = &led_pwr;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ /* We have to override root and ubi device passed by bootloader */
+ bootargs-append = " ubi.block=0,jffs2 root=/dev/ubiblock0_4";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&button_pins>;
+ pinctrl-names = "default";
+
+ wifi-button {
+ label = "wifi";
+ gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WLAN>;
+ };
+
+ reset-button {
+ label = "reset";
+ gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ wps-button {
+ label = "wps";
+ gpios = <&tlmm 34 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ led-button {
+ label = "led";
+ gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_LIGHTS_TOGGLE>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pins>;
+ pinctrl-names = "default";
+
+ led_pwr: led-pwr {
+ function = LED_FUNCTION_POWER;
+ gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ led-2g {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ linux,default-trigger = "phy0radio";
+ };
+
+ led-5g {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ gpios = <&tlmm 19 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ linux,default-trigger = "phy1radio";
+ };
+
+ led-10g-copper {
+ function = "aqr10g";
+ gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ led-lan {
+ function = LED_FUNCTION_LAN;
+ gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ led-sfp {
+ function = "sfp";
+ gpios = <&tlmm 36 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ led-wan-red {
+ function = LED_FUNCTION_WAN;
+ gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_RED>;
+ };
+
+ led-wan-white {
+ function = LED_FUNCTION_WAN;
+ gpios = <&tlmm 47 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+ };
+
+ gpio_fan: gpio-fan {
+ compatible = "gpio-fan";
+ pinctrl-0 = <&fan_pins>;
+ pinctrl-names = "default";
+ gpios = <&tlmm 64 GPIO_ACTIVE_HIGH
+ &tlmm 66 GPIO_ACTIVE_HIGH>;
+ /*
+ * Not supported upstream, but good to document for
+ * future uses.
+ * It seems that Delta AFB0712VHB fan has its tacho
+ * output connected to GPIO 65.
+ */
+ //rpm-gpios = <&tlmm 65 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 1600 1
+ 1850 2
+ 2100 3 >;
+ #cooling-cells = <2>;
+ };
+
+ usb0_vbus: regulator-usb0-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&tlmm 30 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+
+ usb1_vbus: regulator-usb1-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&tlmm 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+
+ output-usb0-power {
+ compatible = "regulator-output";
+ vout-supply = <&usb0_vbus>;
+ };
+
+ output-usb1-power {
+ compatible = "regulator-output";
+ vout-supply = <&usb1_vbus>;
+ };
+};
+
+&cpu0_thermal {
+ trips {
+ cpu0_active: cpu-active {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map2 {
+ trip = <&cpu0_active>;
+ cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+&cpu1_thermal {
+ trips {
+ cpu1_active: cpu-active {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map2 {
+ trip = <&cpu1_active>;
+ cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+&cpu2_thermal {
+ trips {
+ cpu2_active: cpu-active {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map2 {
+ trip = <&cpu2_active>;
+ cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+&cpu3_thermal {
+ trips {
+ cpu3_active: cpu-active {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map2 {
+ trip = <&cpu3_active>;
+ cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+&cluster_thermal {
+ trips {
+ cluster_active: cluster-active {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map2 {
+ trip = <&cluster_active>;
+ cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+&tlmm {
+ button_pins: button-state {
+ pins = "gpio25", "gpio26", "gpio34", "gpio61";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ i2c_pins: i2c-pins {
+ pins = "gpio42", "gpio43";
+ function = "blsp1_i2c";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ mdio_pins: mdio-pins {
+ mdc {
+ pins = "gpio68";
+ function = "mdc";
+ drive-strength = <16>;
+ bias-pull-up;
+ };
+
+ mdio {
+ pins = "gpio69";
+ function = "mdio";
+ drive-strength = <16>;
+ bias-pull-up;
+ };
+ };
+
+ mdio_gpio_pins: mdio-gpio-pins {
+ pins = "gpio54", "gpio56";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ uniphy_pins: uniphy_pinmux {
+ mux {
+ pins = "gpio60";
+ function = "rx2";
+ bias-disable;
+ };
+
+ sfp_tx_disable {
+ pins = "gpio48";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ output-low;
+ };
+
+ sfp_tx_fault {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ output-high;
+ };
+
+ sfp_mod_def0 {
+ pins = "gpio46";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+
+ led_pins: led-state {
+ power {
+ pins = "gpio21";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ default_off {
+ pins = "gpio18", "gpio19", "gpio20", "gpio47",
+ "gpio44", "gpio35", "gpio36";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+ };
+
+ fan_pins: fan-state {
+ pins = "gpio64", "gpio66";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ output-high;
+ };
+};
+
+&blsp1_uart5 {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&cryptobam {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
+&ssphy_0 {
+ status = "okay";
+};
+
+&qusb_phy_0 {
+ status = "okay";
+};
+
+&ssphy_1 {
+ status = "okay";
+};
+
+&qusb_phy_1 {
+ status = "okay";
+};
+
+&usb_0 {
+ status = "okay";
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
+&qpic_nand {
+ status = "okay";
+
+ nand@0 {
+ reg = <0>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ nand-bus-width = <8>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "0:sbl1";
+ reg = <0x0 0x60000>;
+ read-only;
+ };
+
+ partition@60000 {
+ label = "0:mibib";
+ reg = <0x00060000 0x40000>;
+ read-only;
+ };
+
+ partition@a0000 {
+ label = "0:qsee";
+ reg = <0x000a0000 0x1e0000>;
+ read-only;
+ };
+
+ partition@280000 {
+ label = "0:devcfg";
+ reg = <0x00280000 0x20000>;
+ read-only;
+ };
+
+ partition@2a0000 {
+ label = "0:apdp";
+ reg = <0x002a0000 0x20000>;
+ read-only;
+ };
+
+ partition@2c0000 {
+ label = "0:rpm";
+ reg = <0x002c0000 0x40000>;
+ read-only;
+ };
+
+ partition@300000 {
+ label = "0:cdt";
+ reg = <0x00300000 0x20000>;
+ read-only;
+ };
+
+ partition@320000 {
+ label = "0:appsbl";
+ reg = <0x00320000 0xc0000>;
+ read-only;
+ };
+
+ partition@3e0000 {
+ label = "0:appsblenv";
+ reg = <0x003e0000 0x20000>;
+ };
+
+ partition@400000 {
+ compatible = "linux,ubi";
+ label = "UBI_DEV";
+ reg = <0x00400000 0xfc00000>;
+ };
+ };
+ };
+};
+
+&blsp1_i2c2 {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
+
+ qca8337_0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0>;
+ };
+
+ qca8337_1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1>;
+ };
+
+ qca8337_2: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x2>;
+ };
+
+ qca8337_3: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x3>;
+ };
+
+ qca8337_4: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x4>;
+ };
+
+ /*
+ * Vendor bootloader has path for ethernet-phy@5 hardcoded
+ * and if its there it will delete the node, but since we
+ * need the QCA8035 for DSA lets fool the bootloader by using
+ * ethernet-phy@05 even though it causes DTC to print a warning.
+ */
+ qca8035: ethernet-phy@05 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x5>;
+ };
+
+ qca8033: ethernet-phy@6 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x6>;
+ };
+
+ ethernet-phy-package@8 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,qca8075-package";
+ reg = <8>;
+
+ qcom,package-mode = "qsgmii";
+
+ qca8075_8: ethernet-phy@8 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x8>;
+ };
+
+ qca8075_9: ethernet-phy@9 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x9>;
+ };
+
+ qca8075_a: ethernet-phy@a {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0xa>;
+ };
+
+ qca8075_b: ethernet-phy@b {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0xb>;
+ };
+ };
+
+ qca8337: switch@10 {
+ compatible = "qca,qca8337";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10>;
+
+ ports {
+ port@0 {
+ reg = <0>;
+ label = "cpu";
+ ethernet = <&dp1>;
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&qca8035>;
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan7";
+ phy-handle = <&qca8337_0>;
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan6";
+ phy-handle = <&qca8337_1>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan5";
+ phy-handle = <&qca8337_2>;
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "lan4";
+ phy-handle = <&qca8337_3>;
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "lan3";
+ phy-handle = <&qca8337_4>;
+ };
+
+ port@6 {
+ reg = <6>;
+ label = "lan8";
+ phy-mode = "sgmii";
+ phy-handle = <&qca8033>;
+ managed = "in-band-status";
+ qca,sgmii-enable-pll;
+ };
+ };
+ };
+};
+
+&soc {
+ /*
+ * This is techically incorrect and will cause a DTC warning as
+ * all nodes under a bus are supposed to have addresses as well
+ * but its required as bootloader has this path hardcoded in
+ * order to enable AQR113C on newer revisions.
+ */
+ mdio1: mdio1 {
+ compatible = "virtual,mdio-gpio";
+ pinctrl-0 = <&mdio_gpio_pins>;
+ pinctrl-names = "default";
+ gpios = <&tlmm 56 GPIO_ACTIVE_HIGH>,
+ <&tlmm 54 GPIO_ACTIVE_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * PCB R5.00, AQR113C
+ * No idea why the bitbanged this one.
+ * @5 is wrong, but their bootloader has it hardcoded in
+ * order to dynamically enable the PHY for newer HW.
+ */
+ aqr113c: ethernet-phy@5 {
+ status = "disabled";
+ compatible ="ethernet-phy-ieee802.3-c45";
+ reg = <8>;
+ };
+ };
+};
+
+&switch {
+ status = "okay";
+
+ pinctrl-0 = <&uniphy_pins>;
+ pinctrl-names = "default";
+
+ switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT5 | ESS_PORT6)>; /* lan port bitmap */
+ switch_wan_bmp = <ESS_PORT4>; /* wan port bitmap */
+ switch_mac_mode = <MAC_MODE_QSGMII>; /* mac mode for uniphy instance0*/
+ switch_mac_mode1 = <MAC_MODE_10GBASE_R>; /* mac mode for uniphy instance1*/
+ switch_mac_mode2 = <MAC_MODE_USXGMII>; /* mac mode for uniphy instance2*/
+
+ qcom,port_phyinfo {
+ port@0 {
+ port_id = <1>;
+ phy_address = <0x8>;
+ };
+ port@1 {
+ port_id = <2>;
+ phy_address = <0x9>;
+ };
+ port@2 {
+ port_id = <3>;
+ phy_address = <0xa>;
+ };
+ port@3 {
+ port_id = <4>;
+ phy_address = <0xb>;
+ };
+
+ sfp: port@4 {
+ port_id = <5>;
+ phy_address = <30>;
+ phy_i2c_address = <30>;
+ phy-i2c-mode; /*i2c access phy */
+ media-type = "sfp"; /* fiber mode */
+ sfp_tx_dis_pin = <&tlmm 48 GPIO_ACTIVE_HIGH>;
+ sfp_mod_present_pin = <&tlmm 46 GPIO_ACTIVE_LOW>;
+ };
+
+ /* PCB R5.00, AQR113C */
+ port@5_113c {
+ status = "disabled";
+ port_id = <6>;
+ phy_address = <8>;
+ ethernet-phy-ieee802.3-c45;
+ mdiobus = <&mdio1>;
+ };
+ };
+};
+
+&edma {
+ status = "okay";
+};
+
+&dp1 {
+ status = "okay";
+ phy-mode = "qsgmii";
+ phy-handle = <&qca8075_8>;
+ label = "switch";
+};
+
+&dp2 {
+ status = "okay";
+ phy-mode = "qsgmii";
+ phy-handle = <&qca8075_9>;
+ label = "lan2";
+};
+
+&dp3 {
+ status = "okay";
+ phy-mode = "qsgmii";
+ phy-handle = <&qca8075_a>;
+ label = "lan1";
+};
+
+&dp4 {
+ status = "okay";
+ phy-mode = "qsgmii";
+ phy-handle = <&qca8075_b>;
+ label = "wan";
+};
+
+&dp5_syn {
+ status = "okay";
+ phy-handle = <&sfp>;
+ label = "10g-sfp";
+};
+
+&dp6_syn {
+ status = "okay";
+ phy-handle = <&aqr113c>;
+ label = "10g-copper";
+};
+
+&wifi {
+ status = "okay";
+ qcom,ath11k-calibration-variant = "Asus-RT-AX89X";
+};
diff --git a/target/linux/qualcommax/image/ipq60xx.mk b/target/linux/qualcommax/image/ipq60xx.mk
index 79822ceb01..41cfd164ee 100644
--- a/target/linux/qualcommax/image/ipq60xx.mk
+++ b/target/linux/qualcommax/image/ipq60xx.mk
@@ -11,6 +11,19 @@ define Device/8devices_mango-dvk
endef
TARGET_DEVICES += 8devices_mango-dvk
+define Device/cambiumnetworks_xe3-4
+ $(call Device/FitImage)
+ $(call Device/UbiFit)
+ DEVICE_VENDOR := Cambium Networks
+ DEVICE_MODEL := XE3-4
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ DEVICE_DTS_CONFIG := config@cp01-c3-xv3-4
+ SOC := ipq6010
+ DEVICE_PACKAGES := ipq-wifi-cambiumnetworks_xe34 ath11k-firmware-qcn9074 kmod-ath11k-pci
+endef
+TARGET_DEVICES += cambiumnetworks_xe3-4
+
define Device/netgear_wax214
$(call Device/FitImage)
$(call Device/UbiFit)
diff --git a/target/linux/qualcommax/image/ipq807x.mk b/target/linux/qualcommax/image/ipq807x.mk
index d75cf3dd3c..faefb479c2 100644
--- a/target/linux/qualcommax/image/ipq807x.mk
+++ b/target/linux/qualcommax/image/ipq807x.mk
@@ -1,3 +1,26 @@
+define Build/asus-fake-ramdisk
+ rm -rf $(KDIR)/tmp/fakerd
+ dd if=/dev/zero bs=32 count=1 > $(KDIR)/tmp/fakerd
+ $(info KERNEL_INITRAMFS is $(KERNEL_INITRAMFS))
+endef
+
+define Build/asus-fake-rootfs
+ $(eval comp=$(word 1,$(1)))
+ $(eval filepath=$(word 2,$(1)))
+ $(eval filecont=$(word 3,$(1)))
+ rm -rf $(KDIR)/tmp/fakefs $(KDIR)/tmp/fakehsqs
+ mkdir -p $(KDIR)/tmp/fakefs/$$(dirname $(filepath))
+ echo '$(filecont)' > $(KDIR)/tmp/fakefs/$(filepath)
+ $(STAGING_DIR_HOST)/bin/mksquashfs4 $(KDIR)/tmp/fakefs $(KDIR)/tmp/fakehsqs -comp $(comp) \
+ -b 4096 -no-exports -no-sparse -no-xattrs -all-root -noappend \
+ $(wordlist 4,$(words $(1)),$(1))
+endef
+
+define Build/asus-trx
+ $(STAGING_DIR_HOST)/bin/asusuimage $(wordlist 1,$(words $(1)),$(1)) -i $@ -o $@.new
+ mv $@.new $@
+endef
+
define Build/wax6xx-netgear-tar
mkdir $@.tmp
mv $@ $@.tmp/nand-ipq807x-apps.img
@@ -22,6 +45,34 @@ define Device/arcadyan_aw1000
endef
TARGET_DEVICES += arcadyan_aw1000
+define Device/asus_rt-ax89x
+ DEVICE_VENDOR := Asus
+ DEVICE_MODEL := RT-AX89X
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ DEVICE_DTS_CONFIG := config@hk01
+ SOC := ipq8074
+ DEVICE_PACKAGES := kmod-hwmon-gpiofan ipq-wifi-asus_rt-ax89x
+ KERNEL_NAME := vmlinux
+ KERNEL := kernel-bin | libdeflate-gzip
+ KERNEL_IN_UBI := 1
+ IMAGE/sysupgrade.bin/squashfs := \
+ append-kernel | asus-fake-ramdisk |\
+ multiImage gzip $$(KDIR)/tmp/fakerd $$(KDIR)/image-$$(DEVICE_DTS).dtb |\
+ sysupgrade-tar kernel=$$$$@ | append-metadata
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+ ARTIFACTS := initramfs-factory.trx initramfs-uImage.itb
+ ARTIFACT/initramfs-uImage.itb := \
+ append-image-stage initramfs-kernel.bin | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb
+ ARTIFACT/initramfs-factory.trx := \
+ append-image-stage initramfs-kernel.bin |\
+ asus-fake-rootfs xz /lib/firmware/IPQ8074A/fw_version.txt "fake" -no-compression |\
+ multiImage gzip $$(KDIR)/tmp/fakehsqs $$(KDIR)/image-$$(DEVICE_DTS).dtb |\
+ asus-trx -v 2 -n RT-AX89U -b 388 -e 49000
+endif
+endef
+TARGET_DEVICES += asus_rt-ax89x
+
define Device/buffalo_wxr-5950ax12
$(call Device/FitImage)
DEVICE_VENDOR := Buffalo
@@ -162,10 +213,12 @@ define Device/netgear_rax120v2
NETGEAR_HW_ID := 29765589+0+512+1024+4x4+8x8
DEVICE_PACKAGES := ipq-wifi-netgear_rax120v2 kmod-spi-gpio \
kmod-spi-bitbang kmod-gpio-nxp-74hc164 kmod-hwmon-g762
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
IMAGES += web-ui-factory.img
IMAGE/web-ui-factory.img := append-image initramfs-uImage.itb | \
pad-offset $$$$(BLOCKSIZE) 64 | append-uImage-fakehdr filesystem | \
netgear-dni
+endif
IMAGE/sysupgrade.bin := append-kernel | pad-offset $$$$(BLOCKSIZE) 64 | \
append-uImage-fakehdr filesystem | sysupgrade-tar kernel=$$$$@ | \
append-metadata
@@ -287,10 +340,24 @@ define Device/spectrum_sax1v1k
DEVICE_DTS_CONFIG := config@rt5010w-d187-rev6
SOC := ipq8072
IMAGES := sysupgrade.bin
- DEVICE_PACKAGES := ipq-wifi-spectrum_sax1v1k
+ DEVICE_PACKAGES := kmod-fs-f2fs f2fs-tools ipq-wifi-spectrum_sax1v1k
endef
TARGET_DEVICES += spectrum_sax1v1k
+define Device/tplink_eap660hd-v1
+ $(call Device/FitImage)
+ $(call Device/UbiFit)
+ DEVICE_VENDOR := TP-Link
+ DEVICE_MODEL := EAP660 HD
+ DEVICE_VARIANT := v1
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ SOC := ipq8072
+ DEVICE_PACKAGES := ipq-wifi-tplink_eap660hd-v1
+ TPLINK_SUPPORT_STRING := SupportList:\r\nEAP660 HD(TP-Link|UN|AX3600-D):1.0\r\n
+endef
+TARGET_DEVICES += tplink_eap660hd-v1
+
define Device/xiaomi_ax3600
$(call Device/FitImage)
$(call Device/UbiFit)
diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network
index f5fd35cf44..86d55de7b8 100644
--- a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network
+++ b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network
@@ -14,6 +14,9 @@ ipq60xx_setup_interfaces()
8devices,mango-dvk)
ucidef_set_interfaces_lan_wan "lan1 lan2" "wan"
;;
+ cambiumnetworks,xe3-4)
+ ucidef_set_interface_lan "lan1 lan2" "dhcp"
+ ;;
netgear,wax214)
ucidef_set_interfaces_lan_wan "lan"
;;
diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata
index 23a3da0b4b..cc2de7514e 100644
--- a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata
+++ b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata
@@ -12,6 +12,9 @@ case "$FIRMWARE" in
8devices,mango-dvk)
caldata_extract "0:ART" 0x1000 0x20000
;;
+ cambiumnetworks,xe3-4)
+ caldata_extract "0:ART" 0x1000 0x10000
+ ;;
netgear,wax214)
caldata_extract "0:art" 0x1000 0x10000
;;
@@ -20,6 +23,13 @@ case "$FIRMWARE" in
;;
esac
;;
+"ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin")
+ case "$board" in
+ cambiumnetworks,xe3-4)
+ caldata_extract "0:ART" 0x26800 0x20000
+ ;;
+ esac
+ ;;
*)
exit 1
;;
diff --git a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh
index a8e4872cdd..cbc6292978 100644
--- a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh
@@ -33,6 +33,10 @@ EOF
platform_do_upgrade() {
case "$(board_name)" in
+ cambiumnetworks,xe3-4)
+ fw_setenv bootcount 0
+ nand_do_upgrade "$1"
+ ;;
netgear,wax214)
nand_do_upgrade "$1"
;;
diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds
index 23d87f1b2d..b5c3cbc736 100644
--- a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds
+++ b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds
@@ -11,6 +11,11 @@ arcadyan,aw1000)
ucidef_set_led_netdev "wan" "WAN" "green:internet" "wan"
ucidef_set_led_netdev "wan-port-link" "WAN-PORT-LINK" "90000.mdio-1:1c:green:wan" "wan" "tx rx link_10 link_100 link_1000 link_2500"
;;
+asus,rt-ax89x)
+ ucidef_set_led_netdev "aqr" "AQR" "white:aqr10g" "10g-copper"
+ ucidef_set_led_netdev "sfp" "SFP" "white:sfp" "10g-sfp"
+ ucidef_set_led_netdev "wan" "WAN" "white:wan" "wan"
+ ;;
dynalink,dl-wrx36)
ucidef_set_led_netdev "wan-port-link-green" "WAN-PORT-LINK-GREEN" "90000.mdio-1:1c:green:wan" "wan" "link_2500"
ucidef_set_led_netdev "wan-port-link-yellow" "WAN-PORT-LINK-YELLOW" "90000.mdio-1:1c:yellow:wan" "wan" "tx rx link_10 link_100 link_1000"
diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
index 0bf224f380..437581d001 100644
--- a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
+++ b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
@@ -11,6 +11,9 @@ ipq807x_setup_interfaces()
local board="$1"
case "$board" in
+ asus,rt-ax89x)
+ ucidef_set_interfaces_lan_wan "10g-sfp 10g-copper lan1 lan2 lan3 lan4 lan5 lan6 lan7 lan8" "wan"
+ ;;
arcadyan,aw1000|\
buffalo,wxr-5950ax12|\
dynalink,dl-wrx36|\
@@ -57,6 +60,9 @@ ipq807x_setup_interfaces()
qnap,301w)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g-2" "10g-1"
;;
+ tplink,eap660hd-v1)
+ ucidef_set_interface_lan "lan" "dhcp"
+ ;;
zyxel,nbg7815)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g" "wan"
;;
@@ -86,6 +92,10 @@ ipq807x_setup_macs()
lan_mac=$(macaddr_add $label_mac 1)
wan_mac=$label_mac
;;
+ tplink,eap660hd-v1)
+ label_mac=$(get_mac_binary /tmp/factory_data/default-mac 0)
+ lan_mac=$label_mac
+ ;;
esac
[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
index 1170a35413..2e741f0448 100644
--- a/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
+++ b/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
@@ -9,6 +9,10 @@ board=$(board_name)
case "$FIRMWARE" in
"ath11k/IPQ8074/hw2.0/cal-ahb-c000000.wifi.bin")
case "$board" in
+ asus,rt-ax89x)
+ CI_UBIPART="UBI_DEV"
+ caldata_extract_ubi "Factory" 0x1000 0x20000
+ ;;
arcadyan,aw1000|\
buffalo,wxr-5950ax12|\
cmcc,rm2-6|\
@@ -76,6 +80,13 @@ case "$FIRMWARE" in
spectrum,sax1v1k)
caldata_extract_mmc "0:ART" 0x1000 0x20000
;;
+ tplink,eap660hd-v1)
+ caldata_from_file "/tmp/factory_data/radio" 0 0x20000
+ label_mac=$(get_mac_binary /tmp/factory_data/default-mac 0)
+ ath11k_patch_mac $label_mac 1
+ ath11k_patch_mac $(macaddr_add $label_mac 1) 0
+ ath11k_set_macflag
+ ;;
zbtlink,zbt-z800ax)
caldata_extract "0:art" 0x1000 0x20000
label_mac=$(get_mac_label)
diff --git a/target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data b/target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data
new file mode 100644
index 0000000000..59fde529d3
--- /dev/null
+++ b/target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+preinit_mount_factory_data() {
+ local mtd_path
+
+ . /lib/functions.sh
+ . /lib/functions/system.sh
+
+ case $(board_name) in
+ tplink,eap660hd-v1)
+ mtd_path=$(find_mtd_chardev "factory_data")
+ ubiattach --dev-path="$mtd_path" --devn=1
+ mkdir /tmp/factory_data
+ mount -o ro,noatime -t ubifs ubi1:ubi_factory_data /tmp/factory_data
+ ;;
+ esac
+}
+
+boot_hook_add preinit_main preinit_mount_factory_data
diff --git a/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
index 5d89554133..808acac684 100644
--- a/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
+++ b/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
@@ -27,12 +27,96 @@ xiaomi_initramfs_prepare() {
ubiformat /dev/mtd$kern_mtdnum -y
}
+asus_initial_setup() {
+ # Remove existing linux and jffs2 volumes
+ [ "$(rootfs_type)" = "tmpfs" ] || return 0
+
+ ubirmvol /dev/ubi0 -N linux
+ ubirmvol /dev/ubi0 -N jffs2
+}
+
+remove_oem_ubi_volume() {
+ local oem_volume_name="$1"
+ local oem_ubivol
+ local mtdnum
+ local ubidev
+
+ mtdnum=$(find_mtd_index "$CI_UBIPART")
+ if [ ! "$mtdnum" ]; then
+ return
+ fi
+
+ ubidev=$(nand_find_ubi "$CI_UBIPART")
+ if [ ! "$ubidev" ]; then
+ ubiattach --mtdn="$mtdnum"
+ ubidev=$(nand_find_ubi "$CI_UBIPART")
+ fi
+
+ if [ "$ubidev" ]; then
+ oem_ubivol=$(nand_find_volume "$ubidev" "$oem_volume_name")
+ [ "$oem_ubivol" ] && ubirmvol "/dev/$ubidev" --name="$oem_volume_name"
+ fi
+}
+
+tplink_get_boot_part() {
+ local cur_boot_part
+ local args
+
+ # Try to find rootfs from kernel arguments
+ read -r args < /proc/cmdline
+ for arg in $args; do
+ local ubi_mtd_arg=${arg#ubi.mtd=}
+ case "$ubi_mtd_arg" in
+ rootfs|rootfs_1)
+ echo "$ubi_mtd_arg"
+ return
+ ;;
+ esac
+ done
+
+ # Fallback to u-boot env (e.g. when running initramfs)
+ cur_boot_part="$(/usr/sbin/fw_printenv -n tp_boot_idx)"
+ case $cur_boot_part in
+ 1)
+ echo rootfs_1
+ ;;
+ 0|*)
+ echo rootfs
+ ;;
+ esac
+}
+
+tplink_do_upgrade() {
+ local new_boot_part
+
+ case $(tplink_get_boot_part) in
+ rootfs)
+ CI_UBIPART="rootfs_1"
+ new_boot_part=1
+ ;;
+ rootfs_1)
+ CI_UBIPART="rootfs"
+ new_boot_part=0
+ ;;
+ esac
+
+ fw_setenv -s - <<-EOF
+ tp_boot_idx $new_boot_part
+ EOF
+
+ remove_oem_ubi_volume ubi_rootfs
+ nand_do_upgrade "$1"
+}
+
platform_check_image() {
return 0;
}
platform_pre_upgrade() {
case "$(board_name)" in
+ asus,rt-ax89x)
+ asus_initial_setup
+ ;;
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000)
@@ -56,6 +140,12 @@ platform_do_upgrade() {
netgear,wax630)
nand_do_upgrade "$1"
;;
+ asus,rt-ax89x)
+ CI_UBIPART="UBI_DEV"
+ CI_KERNPART="linux"
+ CI_ROOTPART="jffs2"
+ nand_do_upgrade "$1"
+ ;;
buffalo,wxr-5950ax12)
CI_KERN_UBIPART="rootfs"
CI_ROOT_UBIPART="user_property"
@@ -94,12 +184,14 @@ platform_do_upgrade() {
nand_do_upgrade "$1"
;;
prpl,haze|\
- qnap,301w|\
- spectrum,sax1v1k)
+ qnap,301w)
kernelname="0:HLOS"
rootfsname="rootfs"
mmc_do_upgrade "$1"
;;
+ tplink,eap660hd-v1)
+ tplink_do_upgrade "$1"
+ ;;
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000)
@@ -119,6 +211,12 @@ platform_do_upgrade() {
CI_ROOT_UBIPART="rootfs"
nand_do_upgrade "$1"
;;
+ spectrum,sax1v1k)
+ CI_KERNPART="0:HLOS"
+ CI_ROOTPART="rootfs"
+ CI_DATAPART="rootfs_data"
+ emmc_do_upgrade "$1"
+ ;;
yuncore,ax880)
active="$(fw_printenv -n active)"
if [ "$active" -eq "1" ]; then
@@ -167,3 +265,11 @@ platform_do_upgrade() {
;;
esac
}
+
+platform_copy_config() {
+ case "$(board_name)" in
+ spectrum,sax1v1k)
+ emmc_copy_config
+ ;;
+ esac
+}
diff --git a/target/linux/qualcommax/ipq807x/config-default b/target/linux/qualcommax/ipq807x/config-default
index 18483d05b4..f4942c32cc 100644
--- a/target/linux/qualcommax/ipq807x/config-default
+++ b/target/linux/qualcommax/ipq807x/config-default
@@ -1,15 +1,24 @@
CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
CONFIG_DT_IDLE_GENPD=y
+CONFIG_GRO_CELLS=y
CONFIG_IPQ_GCC_8074=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
# CONFIG_MFD_HI6421_SPMI is not set
CONFIG_MFD_SPMI_PMIC=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_QCA8K=y
+CONFIG_NET_DSA_TAG_QCA=y
# CONFIG_NVMEM_SPMI_SDAM is not set
+CONFIG_PHYLINK=y
CONFIG_PINCTRL_IPQ8074=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
# CONFIG_PM8916_WATCHDOG is not set
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_PM_GENERIC_DOMAINS_OF=y
# CONFIG_POWER_RESET_QCOM_PON is not set
+CONFIG_QCA83XX_PHY=y
CONFIG_QCOM_APM=y
# CONFIG_QCOM_COINCELL is not set
CONFIG_QCOM_GDSC=y
@@ -23,6 +32,7 @@ CONFIG_REGULATOR_CPR4_APSS=y
# CONFIG_REGULATOR_QCOM_LABIBB is not set
CONFIG_REGULATOR_QCOM_SPMI=y
# CONFIG_REGULATOR_QCOM_USB_VBUS is not set
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
CONFIG_RTC_DRV_PM8XXX=y
CONFIG_SPMI=y
# CONFIG_SPMI_HISI3670 is not set
diff --git a/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch b/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch
index 6b305cc282..95c6c9505d 100644
--- a/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch
+++ b/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch
@@ -44,7 +44,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
struct qcom_cpufreq_drv;
struct qcom_cpufreq_match_data {
-@@ -203,6 +205,57 @@ len_error:
+@@ -207,6 +209,57 @@ len_error:
return ret;
}
@@ -102,7 +102,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static const struct qcom_cpufreq_match_data match_data_kryo = {
.get_version = qcom_cpufreq_kryo_name_version,
};
-@@ -217,6 +270,10 @@ static const struct qcom_cpufreq_match_d
+@@ -221,6 +274,10 @@ static const struct qcom_cpufreq_match_d
.genpd_names = qcs404_genpd_names,
};
@@ -113,7 +113,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static int qcom_cpufreq_probe(struct platform_device *pdev)
{
struct qcom_cpufreq_drv *drv;
-@@ -359,6 +416,7 @@ static const struct of_device_id qcom_cp
+@@ -353,6 +410,7 @@ static const struct of_device_id qcom_cp
{ .compatible = "qcom,apq8096", .data = &match_data_kryo },
{ .compatible = "qcom,msm8996", .data = &match_data_kryo },
{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 },
diff --git a/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch b/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
index 8ff3b5f9b1..5640038404 100644
--- a/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
+++ b/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
@@ -47,7 +47,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
struct qcom_cpufreq_drv;
struct qcom_cpufreq_match_data {
-@@ -256,6 +261,44 @@ static int qcom_cpufreq_ipq6018_name_ver
+@@ -260,6 +265,44 @@ static int qcom_cpufreq_ipq6018_name_ver
return 0;
}
@@ -92,7 +92,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static const struct qcom_cpufreq_match_data match_data_kryo = {
.get_version = qcom_cpufreq_kryo_name_version,
};
-@@ -274,6 +317,10 @@ static const struct qcom_cpufreq_match_d
+@@ -278,6 +321,10 @@ static const struct qcom_cpufreq_match_d
.get_version = qcom_cpufreq_ipq6018_name_version,
};
@@ -103,7 +103,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static int qcom_cpufreq_probe(struct platform_device *pdev)
{
struct qcom_cpufreq_drv *drv;
-@@ -418,6 +465,7 @@ static const struct of_device_id qcom_cp
+@@ -412,6 +459,7 @@ static const struct of_device_id qcom_cp
{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 },
{ .compatible = "qcom,ipq6018", .data = &match_data_ipq6018 },
{ .compatible = "qcom,ipq8064", .data = &match_data_krait },
diff --git a/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch b/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch
index 7607bdad8b..6b7dd2f261 100644
--- a/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch
+++ b/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch
@@ -19,7 +19,7 @@ Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-@@ -721,8 +721,8 @@
+@@ -723,8 +723,8 @@
compatible = "qcom,ipq8074-apcs-apps-global",
"qcom,ipq6018-apcs-apps-global";
reg = <0x0b111000 0x1000>;
diff --git a/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch b/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch
index 3239404977..d407b9c5c4 100644
--- a/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch
+++ b/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch
@@ -22,7 +22,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -619,8 +619,8 @@
+@@ -620,8 +620,8 @@
compatible = "qcom,ipq6018-apcs-apps-global";
reg = <0x0 0x0b111000 0x0 0x1000>;
#clock-cells = <1>;
diff --git a/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch b/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch
index 8eb3915057..6559f3bbe9 100644
--- a/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch
+++ b/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch
@@ -79,7 +79,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
power-domains = <&gcc USB0_GDSC>;
resets = <&gcc GCC_USB0_BCR>;
-@@ -674,6 +681,13 @@
+@@ -675,6 +682,13 @@
<133330000>,
<19200000>;
diff --git a/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch b/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch
index b8b623c8bc..7e8c84558e 100644
--- a/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch
+++ b/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch
@@ -55,7 +55,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
};
L2_0: l2-cache {
-@@ -889,6 +894,122 @@
+@@ -890,6 +895,122 @@
};
};
diff --git a/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch b/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
index dc009cd414..fdf7f84b92 100644
--- a/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
+++ b/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
@@ -12,7 +12,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-@@ -755,7 +755,7 @@
+@@ -757,7 +757,7 @@
reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
ranges = <0 0xb00a000 0xffd>;
@@ -21,7 +21,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
compatible = "arm,gic-v2m-frame";
msi-controller;
reg = <0x0 0xffd>;
-@@ -868,8 +868,7 @@
+@@ -870,8 +870,7 @@
ranges = <0x81000000 0x0 0x00000000 0x10200000 0x0 0x10000>, /* I/O */
<0x82000000 0x0 0x10220000 0x10220000 0x0 0xfde0000>; /* MEM */
@@ -31,7 +31,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 0 142
-@@ -930,8 +929,7 @@
+@@ -932,8 +931,7 @@
ranges = <0x81000000 0x0 0x00000000 0x20200000 0x0 0x10000>, /* I/O */
<0x82000000 0x0 0x20220000 0x20220000 0x0 0xfde0000>; /* MEM */
diff --git a/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch b/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
index 2ea9bcb9fc..07f5144108 100644
--- a/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
+++ b/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
@@ -61,7 +61,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
spmi_bus: spmi@200f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0200f000 0x001000>,
-@@ -970,6 +1001,56 @@
+@@ -972,6 +1003,56 @@
"axi_s_sticky";
status = "disabled";
};
diff --git a/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch b/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
index 627b0711b7..ef34c50eca 100644
--- a/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
+++ b/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
@@ -15,7 +15,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-@@ -1051,6 +1051,117 @@
+@@ -1053,6 +1053,117 @@
};
};
};
diff --git a/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch b/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch
index 3e040cd2fd..f4968f1a4d 100644
--- a/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch
+++ b/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch
@@ -15,7 +15,7 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -808,6 +808,102 @@
+@@ -809,6 +809,102 @@
};
};
diff --git a/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch b/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch
index d1bca14063..094442a59b 100644
--- a/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch
+++ b/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch
@@ -15,7 +15,7 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -1156,6 +1156,7 @@
+@@ -1157,6 +1157,7 @@
wcss_smp2p_out: master-kernel {
qcom,entry-name = "master-kernel";
diff --git a/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch b/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch
index 3e0ac68f2b..a0528e7f50 100644
--- a/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch
+++ b/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch
@@ -13,7 +13,7 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -929,8 +929,8 @@
+@@ -930,8 +930,8 @@
"wcss_reset",
"wcss_q6_reset";
diff --git a/target/linux/ramips/dts/mt7620a.dtsi b/target/linux/ramips/dts/mt7620a.dtsi
index 65122304c9..0e925b4dcc 100644
--- a/target/linux/ramips/dts/mt7620a.dtsi
+++ b/target/linux/ramips/dts/mt7620a.dtsi
@@ -32,6 +32,35 @@
compatible = "mti,cpu-interrupt-controller";
};
+ mmc_clk: mmc-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-accuracy = <100>;
+ };
+
+ mmc_reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+
+ enable-active-high;
+
+ regulator-always-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "mmc_io";
+ };
+
+ mmc_reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+
+ enable-active-high;
+
+ regulator-always-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "mmc_power";
+ };
+
palmbus: palmbus@10000000 {
compatible = "palmbus";
reg = <0x10000000 0x200000>;
@@ -48,7 +77,7 @@
};
timer: timer@100 {
- compatible = "ralink,mt7620a-timer", "ralink,rt2880-timer";
+ compatible = "ralink,rt2880-timer";
reg = <0x100 0x20>;
clocks = <&sysc 5>;
@@ -58,7 +87,7 @@
};
watchdog: watchdog@120 {
- compatible = "ralink,mt7620a-wdt", "ralink,rt2880-wdt";
+ compatible = "ralink,rt2880-wdt";
reg = <0x120 0x10>;
clocks = <&sysc 6>;
@@ -71,7 +100,7 @@
};
intc: intc@200 {
- compatible = "ralink,mt7620a-intc", "ralink,rt2880-intc";
+ compatible = "ralink,rt2880-intc";
reg = <0x200 0x100>;
interrupt-controller;
@@ -106,7 +135,7 @@
};
gpio0: gpio@600 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x600 0x34>;
interrupt-parent = <&intc>;
@@ -116,14 +145,13 @@
#gpio-cells = <2>;
ngpios = <24>;
- ralink,gpio-base = <0>;
ralink,register-map = [ 00 04 08 0c
20 24 28 2c
30 34 ];
};
gpio1: gpio@638 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x638 0x24>;
interrupt-parent = <&intc>;
@@ -133,7 +161,6 @@
#gpio-cells = <2>;
ngpios = <16>;
- ralink,gpio-base = <24>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -142,7 +169,7 @@
};
gpio2: gpio@660 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x660 0x24>;
interrupt-parent = <&intc>;
@@ -152,7 +179,6 @@
#gpio-cells = <2>;
ngpios = <32>;
- ralink,gpio-base = <40>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -161,7 +187,7 @@
};
gpio3: gpio@688 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x688 0x24>;
interrupt-parent = <&intc>;
@@ -171,7 +197,6 @@
#gpio-cells = <2>;
ngpios = <1>;
- ralink,gpio-base = <72>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -220,7 +245,7 @@
};
spi0: spi@b00 {
- compatible = "ralink,mt7620a-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb00 0x40>;
clocks = <&sysc 10>;
@@ -465,14 +490,14 @@
mediatek,switch = <&gsw>;
port@4 {
- compatible = "mediatek,mt7620a-gsw-port", "mediatek,eth-port";
+ compatible = "mediatek,eth-port";
reg = <4>;
status = "disabled";
};
port@5 {
- compatible = "mediatek,mt7620a-gsw-port", "mediatek,eth-port";
+ compatible = "mediatek,eth-port";
reg = <5>;
status = "disabled";
@@ -497,15 +522,34 @@
interrupts = <17>;
};
- sdhci: sdhci@10130000 {
- compatible = "ralink,mt7620-sdhci";
+ sdhci: mmc@10130000 {
+ compatible = "mediatek,mt7620-mmc", "ralink,mt7620-sdhci";
reg = <0x10130000 0x4000>;
+ bus-width = <4>;
+
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+
+ clocks = <&mmc_clk>, <&mmc_clk>;
+ clock-names = "source", "hclk";
+
+ disable-wp;
+
interrupt-parent = <&intc>;
interrupts = <14>;
- pinctrl-names = "default";
+ max-frequency = <48000000>;
+
+ pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&sdhci_pins>;
+ pinctrl-1 = <&sdhci_pins>;
+
+ resets = <&sysc 30>;
+ reset-names = "hrst";
+
+ vmmc-supply = <&mmc_reg_3v3>;
+ vqmmc-supply = <&mmc_reg_1v8>;
status = "disabled";
};
diff --git a/target/linux/ramips/dts/mt7620a_bolt_bl100.dts b/target/linux/ramips/dts/mt7620a_bolt_bl100.dts
index e4bc6e211b..cb1f3b8055 100644
--- a/target/linux/ramips/dts/mt7620a_bolt_bl100.dts
+++ b/target/linux/ramips/dts/mt7620a_bolt_bl100.dts
@@ -145,7 +145,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <70000000>;
+ spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts b/target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts
index 7ea288615c..6ed3063ecb 100644
--- a/target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts
+++ b/target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts
@@ -101,7 +101,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts b/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts
index 978de470f0..645030b5bb 100644
--- a/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts
+++ b/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts
@@ -97,7 +97,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
diff --git a/target/linux/ramips/dts/mt7620a_domywifi.dtsi b/target/linux/ramips/dts/mt7620a_domywifi.dtsi
index e2bd8e103b..844c1a4ee4 100644
--- a/target/linux/ramips/dts/mt7620a_domywifi.dtsi
+++ b/target/linux/ramips/dts/mt7620a_domywifi.dtsi
@@ -95,7 +95,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts b/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts
index 83e5698d63..29aff9958a 100644
--- a/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts
+++ b/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts
@@ -51,12 +51,6 @@
gpio-export,output = <0>;
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
};
-
- sdpower {
- gpio-export,name = "sdpower";
- gpio-export,output = <0>;
- gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
- };
};
};
@@ -94,6 +88,12 @@
mediatek,ephy-base = /bits/ 8 <12>;
};
+&mmc_reg_3v3 {
+ /delete-property/ enable-active-high;
+
+ gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+};
+
&pcie {
status = "okay";
};
@@ -108,6 +108,10 @@
};
};
+&sdhci {
+ max-frequency = <24000000>;
+};
+
&wmac {
pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
diff --git a/target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi b/target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi
index 7fcd68e6ba..6a602b8411 100644
--- a/target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi
+++ b/target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi
@@ -31,7 +31,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts b/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
index d95a4ad99d..19b1538241 100644
--- a/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
+++ b/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
@@ -77,7 +77,7 @@
compatible = "realtek,rtl8367b";
gpio-sda = <&gpio0 22 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 23 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <6 1 0 1 1 1 1 1 1 2>;
};
};
diff --git a/target/linux/ramips/dts/mt7620a_netcore_nw5212.dts b/target/linux/ramips/dts/mt7620a_netcore_nw5212.dts
index 2e112c7179..439ad2a118 100644
--- a/target/linux/ramips/dts/mt7620a_netcore_nw5212.dts
+++ b/target/linux/ramips/dts/mt7620a_netcore_nw5212.dts
@@ -75,7 +75,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <70000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_phicomm_k2x.dtsi b/target/linux/ramips/dts/mt7620a_phicomm_k2x.dtsi
index 4faa45933f..ce53781e60 100644
--- a/target/linux/ramips/dts/mt7620a_phicomm_k2x.dtsi
+++ b/target/linux/ramips/dts/mt7620a_phicomm_k2x.dtsi
@@ -52,7 +52,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions: partitions {
diff --git a/target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts b/target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts
index c5c4d01835..b032cd9d4f 100644
--- a/target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts
+++ b/target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts
@@ -55,7 +55,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi b/target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi
index 8c565385e8..cedefe3c5e 100644
--- a/target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi
+++ b/target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi
@@ -158,7 +158,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <70000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
index 06f3eba37b..feb619a0c0 100644
--- a/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
@@ -55,7 +55,7 @@
rtl8367rb {
compatible = "realtek,rtl8367b";
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <6 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
};
};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts
index 855e06e9f6..91b3a255c1 100644
--- a/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts
@@ -74,7 +74,7 @@
rtl8367s {
compatible = "realtek,rtl8367b";
- realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <7 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
phy-id = <29>;
};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts b/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts
index 7fc075aedd..f20cbb4c8f 100644
--- a/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts
+++ b/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts
@@ -47,14 +47,14 @@
function = LED_FUNCTION_WLAN_2GHZ;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "phy0tpt";
+ linux,default-trigger = "phy1tpt";
};
led-5 {
function = LED_FUNCTION_WLAN_5GHZ;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "phy1tpt";
+ linux,default-trigger = "phy0tpt";
};
led-6 {
@@ -82,7 +82,7 @@
rtl8367s {
compatible = "realtek,rtl8367b";
- realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <7 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
phy-id = <29>;
};
diff --git a/target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts
new file mode 100644
index 0000000000..1a12005c92
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7620a.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "wavlink,wl-wn531g3", "ralink,mt7620a-soc";
+ model = "Wavlink WL-WN531G3";
+
+ aliases {
+ led-boot = &led_status_blue;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_blue;
+ led-upgrade = &led_status_red;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ turbo {
+ label = "turbo";
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_1>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ touchlink {
+ label = "touchlink";
+ gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_blue: led_status_blue {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_status_red: led_status_red {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&ehci {
+ status = "okay";
+};
+
+&ohci {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ factory: partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_28: macaddr@28 {
+ reg = <0x28 0x6>;
+ };
+
+ macaddr_factory_2e: macaddr@2e {
+ reg = <0x2e 0x6>;
+ };
+
+ eeprom_radio_0: eeprom@0 {
+ reg = <0x0 0x200>;
+ };
+
+ eeprom_radio_8000: eeprom@8000 {
+ reg = <0x8000 0x200>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+ };
+};
+
+&ethernet {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii1_pins>, <&rgmii2_pins>, <&mdio_pins>;
+
+ nvmem-cells = <&macaddr_factory_28>;
+ nvmem-cell-names = "mac-address";
+
+ mediatek,portmap = "llllw";
+
+ port@4 {
+ status = "okay";
+ phy-handle = <&phy4>;
+ phy-mode = "rgmii";
+
+ nvmem-cells = <&macaddr_factory_2e>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ port@5 {
+ status = "okay";
+ phy-handle = <&phy5>;
+ phy-mode = "rgmii";
+ };
+
+ mdio-bus {
+ status = "okay";
+
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ phy-mode = "rgmii";
+ };
+
+ phy5: ethernet-phy@5 {
+ reg = <5>;
+ phy-mode = "rgmii";
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie0 {
+ mt76@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_radio_8000>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <5000000 6000000>;
+ };
+};
+
+&gsw {
+ mediatek,port4-gmac;
+};
+
+&wmac {
+ nvmem-cells = <&eeprom_radio_0>;
+ nvmem-cell-names = "eeprom";
+};
+
+&state_default {
+ gpio {
+ groups = "i2c", "uartf";
+ function = "gpio";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts b/target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts
index c0141b196d..41221891f7 100644
--- a/target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts
+++ b/target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts
@@ -83,7 +83,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <70000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi b/target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi
index 2f9920fc45..2ddb0d8408 100644
--- a/target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi
+++ b/target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi
@@ -63,7 +63,7 @@
flash0: flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts b/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
index 0630e8a160..9921db770a 100644
--- a/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
+++ b/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-viva", "ralink,mt7620a-soc";
- model = "ZyXEL Keenetic Viva";
+ model = "Zyxel Keenetic Viva";
aliases {
led-boot = &led_power_green;
@@ -85,7 +85,7 @@
rtl8367rb {
compatible = "realtek,rtl8367b";
- realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <7 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
};
};
diff --git a/target/linux/ramips/dts/mt7620n.dtsi b/target/linux/ramips/dts/mt7620n.dtsi
index 4f07c6bc4b..eafa7c16bb 100644
--- a/target/linux/ramips/dts/mt7620n.dtsi
+++ b/target/linux/ramips/dts/mt7620n.dtsi
@@ -48,7 +48,7 @@
};
timer: timer@100 {
- compatible = "ralink,mt7620a-timer", "ralink,rt2880-timer";
+ compatible = "ralink,rt2880-timer";
reg = <0x100 0x20>;
clocks = <&sysc 5>;
@@ -58,7 +58,7 @@
};
watchdog: watchdog@120 {
- compatible = "ralink,mt7620a-wdt", "ralink,rt2880-wdt";
+ compatible = "ralink,rt2880-wdt";
reg = <0x120 0x10>;
clocks = <&sysc 6>;
@@ -71,7 +71,7 @@
};
intc: intc@200 {
- compatible = "ralink,mt7620a-intc", "ralink,rt2880-intc";
+ compatible = "ralink,rt2880-intc";
reg = <0x200 0x100>;
interrupt-controller;
@@ -90,7 +90,7 @@
};
gpio0: gpio@600 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x600 0x34>;
interrupt-parent = <&intc>;
@@ -100,14 +100,13 @@
#gpio-cells = <2>;
ngpios = <24>;
- ralink,gpio-base = <0>;
ralink,register-map = [ 00 04 08 0c
20 24 28 2c
30 34 ];
};
gpio1: gpio@638 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x638 0x24>;
interrupt-parent = <&intc>;
@@ -117,7 +116,6 @@
#gpio-cells = <2>;
ngpios = <16>;
- ralink,gpio-base = <24>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -126,7 +124,7 @@
};
gpio2: gpio@660 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x660 0x24>;
interrupt-parent = <&intc>;
@@ -136,7 +134,6 @@
#gpio-cells = <2>;
ngpios = <32>;
- ralink,gpio-base = <40>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -145,7 +142,7 @@
};
gpio3: gpio@688 {
- compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x688 0x24>;
interrupt-parent = <&intc>;
@@ -155,7 +152,6 @@
#gpio-cells = <2>;
ngpios = <1>;
- ralink,gpio-base = <72>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -182,7 +178,7 @@
};
spi0: spi@b00 {
- compatible = "ralink,mt7620a-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb00 0x40>;
clocks = <&sysc 10>;
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts
index 899479781e..eb3e8aac54 100644
--- a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-lite-iii-a", "ralink,mt7620n-soc";
- model = "ZyXEL Keenetic Lite III (rev. A)";
+ model = "Zyxel Keenetic Lite III (rev. A)";
aliases {
led-boot = &led_wan;
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
index dd1d256f41..ff4667f458 100644
--- a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-omni-ii", "ralink,mt7620n-soc";
- model = "ZyXEL Keenetic Omni II";
+ model = "Zyxel Keenetic Omni II";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
index 0ba185b7eb..b5722d2427 100644
--- a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-omni", "ralink,mt7620n-soc";
- model = "ZyXEL Keenetic Omni";
+ model = "Zyxel Keenetic Omni";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
index 54fe13123d..da992bada4 100644
--- a/target/linux/ramips/dts/mt7621.dtsi
+++ b/target/linux/ramips/dts/mt7621.dtsi
@@ -42,6 +42,28 @@
bootargs = "console=ttyS0,57600";
};
+ mmc_reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+
+ enable-active-high;
+
+ regulator-always-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "mmc_io";
+ };
+
+ mmc_reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+
+ enable-active-high;
+
+ regulator-always-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "mmc_power";
+ };
+
palmbus: palmbus@1e000000 {
compatible = "palmbus";
reg = <0x1e000000 0x100000>;
@@ -326,17 +348,36 @@
};
};
- sdhci: sdhci@1e130000 {
- status = "disabled";
-
- compatible = "ralink,mt7620-sdhci";
+ sdhci: mmc@1e130000 {
+ compatible = "mediatek,mt7620-mmc", "ralink,mt7620-sdhci";
reg = <0x1e130000 0x4000>;
+ bus-width = <4>;
+
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+
+ clocks = <&sysc MT7621_CLK_SHXC>, <&sysc MT7621_CLK_SHXC>;
+ clock-names = "source", "hclk";
+
+ disable-wp;
+
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
- pinctrl-names = "default";
+ max-frequency = <48000000>;
+
+ pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&sdhci_pins>;
+ pinctrl-1 = <&sdhci_pins>;
+
+ resets = <&sysc MT7621_RST_SDXC>;
+ reset-names = "hrst";
+
+ vmmc-supply = <&mmc_reg_3v3>;
+ vqmmc-supply = <&mmc_reg_1v8>;
+
+ status = "disabled";
};
xhci: xhci@1e1c0000 {
diff --git a/target/linux/ramips/dts/mt7621_arcadyan_we420223-99.dts b/target/linux/ramips/dts/mt7621_arcadyan_we420223-99.dts
index 4a5194c363..6895052eb9 100644
--- a/target/linux/ramips/dts/mt7621_arcadyan_we420223-99.dts
+++ b/target/linux/ramips/dts/mt7621_arcadyan_we420223-99.dts
@@ -97,7 +97,7 @@
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <70000000>;
+ spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-2150-r1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-2150-r1.dts
new file mode 100644
index 0000000000..8a1bae328f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-2150-r1.dts
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "dlink,dir-2150-r1", "mediatek,mt7621-soc";
+ model = "D-Link DIR-2150 R1";
+
+ aliases {
+ label-mac-device = &gmac1;
+ led-boot = &led_power_orange;
+ led-failsafe = &led_power_white;
+ led-running = &led_power_white;
+ led-upgrade = &led_net_orange;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power_orange: led-0 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_ORANGE>;
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_white: led-1 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_WHITE>;
+ gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+ };
+
+ led_net_orange: led-2 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_ORANGE>;
+ gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+ };
+
+ led-3 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_WHITE>;
+ gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Bootloader";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "config";
+ reg = <0x80000 0x80000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "factory";
+ reg = <0x100000 0x40000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x400>;
+ };
+
+ eeprom_factory_8000: eeprom@8000 {
+ reg = <0x8000 0x4da8>;
+ };
+
+ macaddr_factory_e006: macaddr@e006 {
+ compatible = "mac-base";
+ reg = <0xe006 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@140000 {
+ label = "firmware";
+ compatible = "denx,uimage";
+ reg = <0x140000 0x7E80000>;
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie0 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&macaddr_factory_e006 2>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ ieee80211-freq-limit = <2400000 2500000>;
+
+ led {
+ led-active-low;
+ };
+ };
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_e006 4>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ ieee80211-freq-limit = <5000000 6000000>;
+
+ led {
+ led-active-low;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_e006 1>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <&ethphy4>;
+
+ nvmem-cells = <&macaddr_factory_e006 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&ethphy4 {
+ /delete-property/ interrupts;
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ status = "okay";
+ label = "lan4";
+ };
+
+ port@1 {
+ status = "okay";
+ label = "lan3";
+ };
+
+ port@2 {
+ status = "okay";
+ label = "lan2";
+ };
+
+ port@3 {
+ status = "okay";
+ label = "lan1";
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "i2c", "uart3", "jtag", "wdt";
+ function = "gpio";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_dna_valokuitu-plus-ex400.dts b/target/linux/ramips/dts/mt7621_dna_valokuitu-plus-ex400.dts
new file mode 100644
index 0000000000..98b2bbf7b6
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dna_valokuitu-plus-ex400.dts
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "dna,valokuitu-plus-ex400", "mediatek,mt7621-soc";
+ model = "DNA Valokuitu Plus EX400";
+
+ aliases {
+ ethernet0 = &gmac0;
+ label-mac-device = &gmac0;
+ led-boot = &led_status_red;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_green;
+ led-upgrade = &led_update_green;
+ };
+
+ chosen {
+ bootargs-override = "console=ttyS0,115200 rootfstype=squashfs,jffs2";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_green: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ };
+
+ led_status_red: led-1 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_update_green: led-2 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_PROGRAMMING;
+ gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&nand {
+ status = "okay";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x00 0x100000>;
+ label = "uboot";
+ read-only;
+ };
+
+ partition@100000 {
+ reg = <0x100000 0xff00000>;
+ label = "ubi";
+
+ volumes {
+ ubi-volume-env1 {
+ volname = "env1";
+
+ nvmem-layout {
+ compatible = "u-boot,env";
+
+ ethaddr: ethaddr {
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+ };
+ };
+ };
+};
+
+&gmac1 {
+ label = "wan";
+ phy-handle = <&ethphy0>;
+ nvmem-cells = <&ethaddr 1>;
+ nvmem-cell-names = "mac-address";
+ status = "okay";
+};
+
+&i2c {
+ status = "okay";
+};
+
+&ethphy0 {
+ /delete-property/ interrupts;
+};
+
+&state_default {
+ gpio {
+ groups = "uart2", "uart3";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@1 {
+ label = "lan";
+ nvmem-cells = <&ethaddr 0>;
+ nvmem-cell-names = "mac-address";
+ status = "okay";
+ };
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wmc-x1800gst.dts b/target/linux/ramips/dts/mt7621_elecom_wmc-x1800gst.dts
new file mode 100644
index 0000000000..36a7aee122
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wmc-x1800gst.dts
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wxc-x1800gsx.dtsi"
+
+/ {
+ compatible = "elecom,wmc-x1800gst", "mediatek,mt7621-soc";
+ model = "ELECOM WMC-X1800GST";
+
+ aliases {
+ label-mac-device = &gmac1;
+ };
+};
+
+&keys {
+ switch-ap {
+ label = "ap";
+ gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ linux,input-type = <EV_SW>;
+ };
+
+ switch-router {
+ label = "router";
+ gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_1>;
+ linux,input-type = <EV_SW>;
+ };
+
+ switch-extender {
+ label = "extender";
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_2>;
+ linux,input-type = <EV_SW>;
+ };
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <&ethphy0>;
+
+ nvmem-cells = <&macaddr_factory_3fffa>;
+ nvmem-cell-names = "mac-address";
+};
+
+&ethphy0 {
+ /delete-property/ interrupts;
+};
+
+&state_default {
+ gpio {
+ groups = "i2c", "uart3", "uart2", "jtag", "wdt";
+ function = "gpio";
+ };
+};
+
+&wifi {
+ band@0 {
+ reg = <0>;
+ nvmem-cells = <&macaddr_factory_4 0>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ band@1 {
+ reg = <1>;
+ nvmem-cells = <&macaddr_factory_4 1>;
+ nvmem-cell-names = "mac-address";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wsc-x1800gs.dts b/target/linux/ramips/dts/mt7621_elecom_wsc-x1800gs.dts
new file mode 100644
index 0000000000..a24edb6136
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wsc-x1800gs.dts
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wxc-x1800gsx.dtsi"
+
+/ {
+ compatible = "elecom,wsc-x1800gs", "mediatek,mt7621-soc";
+ model = "ELECOM WSC-X1800GS";
+
+ aliases {
+ label-mac-device = &wifi_band1;
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "uart3", "uart2", "jtag", "wdt";
+ function = "gpio";
+ };
+};
+
+&wifi {
+ band@0 {
+ reg = <0>;
+ nvmem-cells = <&macaddr_factory_4 (-1)>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ wifi_band1: band@1 {
+ reg = <1>;
+ nvmem-cells = <&macaddr_factory_4 0>;
+ nvmem-cell-names = "mac-address";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wxc-x1800gsx.dtsi b/target/linux/ramips/dts/mt7621_elecom_wxc-x1800gsx.dtsi
new file mode 100644
index 0000000000..2dcd664b93
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wxc-x1800gsx.dtsi
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ led-boot = &led_power_green;
+ led-failsafe = &led_power_red;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_green;
+ };
+
+ chosen {
+ bootargs-override = "console=ttyS0,115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ };
+
+ led-1 {
+ gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ linux,default-trigger = "phy1tpt";
+ };
+
+ led_power_green: led-2 {
+ gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ };
+
+ led-3 {
+ gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_POWER;
+ };
+
+ led-4 {
+ gpios = <&gpio 9 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ };
+
+ led-5 {
+ gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ };
+
+ led-6 {
+ gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ };
+
+ led-7 {
+ gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ linux,default-trigger = "phy0tpt";
+ };
+
+ led_power_red: led-8 {
+ gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+ };
+ };
+
+ keys: keys {
+ compatible = "gpio-keys";
+
+ button-reset {
+ label = "reset";
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ button-wps {
+ label = "wps";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_3fff4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&nand {
+ status = "okay";
+ pinctrl-0 = <&nand_pins>;
+ pinctrl-names = "default";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "u-boot-env";
+ reg = <0x80000 0x80000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "factory";
+ reg = <0x100000 0x80000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ precal_factory_e10: precal@e10 {
+ reg = <0xe10 0x19c10>;
+ };
+
+ macaddr_factory_4: mac-address@4 {
+ compatible = "mac-base";
+ reg = <0x4 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_factory_3fff4: mac-address@3fff4 {
+ reg = <0x3fff4 0x6>;
+ };
+
+ macaddr_factory_3fffa: mac-address@3fffa {
+ reg = <0x3fffa 0x6>;
+ };
+ };
+ };
+
+ /* stock: "firmware" */
+ partition@180000 {
+ reg = <0x180000 0xf00000>;
+ label = "kernel";
+ };
+
+ partition@1080000 {
+ label = "user_data";
+ reg = <0x1080000 0x500000>;
+ read-only;
+ };
+
+ partition@1580000 {
+ label = "tm_pattern";
+ reg = <0x1580000 0x500000>;
+ read-only;
+ };
+
+ partition@1a80000 {
+ label = "tm_key";
+ reg = <0x1a80000 0x100000>;
+ read-only;
+ };
+
+ /* stock: (unused) */
+ partition@1b80000 {
+ label = "ubi";
+ reg = <0x1b80000 0x6480000>;
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi: wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&precal_factory_e10>;
+ nvmem-cell-names = "eeprom", "precal";
+ mediatek,disable-radar-background;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
+
+&switch0 {
+ ports {
+ port@1 {
+ status = "okay";
+ label = "lan2";
+ };
+
+ port@2 {
+ status = "okay";
+ label = "lan1";
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "i2c", "uart3", "uart2", "jtag", "wdt";
+ function = "gpio";
+ };
+};
+
+&uartlite {
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+};
+
+&xhci {
+ status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_iptime_a6004ns-m.dtsi b/target/linux/ramips/dts/mt7621_iptime_a6004ns-m.dtsi
index 6bfdffefb7..24869f3d56 100644
--- a/target/linux/ramips/dts/mt7621_iptime_a6004ns-m.dtsi
+++ b/target/linux/ramips/dts/mt7621_iptime_a6004ns-m.dtsi
@@ -68,7 +68,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts b/target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts
index 548ab7ba59..f1c593ea83 100644
--- a/target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts
+++ b/target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts
@@ -65,7 +65,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_jcg_y2.dts b/target/linux/ramips/dts/mt7621_jcg_y2.dts
index 5012bc3d62..555beae04f 100644
--- a/target/linux/ramips/dts/mt7621_jcg_y2.dts
+++ b/target/linux/ramips/dts/mt7621_jcg_y2.dts
@@ -41,7 +41,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts b/target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts
new file mode 100644
index 0000000000..5a647d75e8
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "keenetic,kn-3510", "mediatek,mt7621-soc";
+ model = "Keenetic KN-3510";
+
+ aliases {
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_green;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_green;
+ label-mac-device = &gmac0;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_AMBER>;
+ gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+ };
+
+ led_status_green: led-1 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ fn1 {
+ label = "fn1";
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+ };
+
+ virtual_flash {
+ compatible = "mtd-concat";
+ devices = <&firmware1 &storage1 &firmware2 &storage2>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x400000>;
+ };
+
+ partition@400000 {
+ label = "ubi";
+ reg = <0x400000 0x0>;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "uart3", "jtag";
+ function = "gpio";
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "u-config";
+ reg = <0x80000 0x80000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "rf-eeprom";
+ reg = <0x100000 0x80000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
+ };
+
+ macaddr_factory_a: macaddr@a {
+ reg = <0xa 0x6>;
+ };
+
+ precal_factory_e10: precal@e10 {
+ reg = <0xe10 0x19c10>;
+ };
+ };
+ };
+
+ firmware1: partition@180000 {
+ label = "firmware_1";
+ reg = <0x180000 0x1a40000>;
+ };
+
+ partition@1bc0000 {
+ label = "config_1";
+ reg = <0x1bc0000 0x20000>;
+ read-only;
+ };
+
+ partition@1dc0000 {
+ label = "storage_legacy";
+ reg = <0x1dc0000 0x20000>;
+ read-only;
+ };
+
+ partition@1fc0000 {
+ label = "dump";
+ reg = <0x1fc0000 0x40000>;
+ read-only;
+ };
+
+ storage1: partition@2000000 {
+ label = "storage_a";
+ reg = <0x2000000 0x1fc0000>;
+ };
+
+ partition@3fc0000 {
+ label = "u-state";
+ reg = <0x3fc0000 0x80000>;
+ read-only;
+ };
+
+ partition@4040000 {
+ label = "u-config_res";
+ reg = <0x4040000 0x80000>;
+ read-only;
+ };
+
+ partition@40c0000 {
+ label = "rf-eeprom_res";
+ reg = <0x40c0000 0x80000>;
+ read-only;
+ };
+
+ firmware2: partition@4140000 {
+ label = "firmware_2";
+ reg = <0x4140000 0x1a40000>;
+ };
+
+ partition@5b80000 {
+ label = "config_2";
+ reg = <0x5d00000 0x20000>;
+ read-only;
+ };
+
+ storage2: partition@5d80000 {
+ label = "storage_b";
+ reg = <0x5d80000 0x2200000>;
+ };
+ };
+};
+
+&ethphy0 {
+ /delete-property/ interrupts;
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <&ethphy0>;
+
+ nvmem-cells = <&macaddr_factory_a>;
+ nvmem-cell-names = "mac-address";
+};
+
+&switch0 {
+ ports {
+ port@3 {
+ status = "okay";
+ label = "lan";
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&precal_factory_e10>;
+ nvmem-cell-names = "eeprom", "precal";
+ mediatek,disable-radar-background;
+ };
+};
+
+&xhci {
+ status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_mtc_wr1201.dts b/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
index 31f3eb8657..24303ec5b3 100644
--- a/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
+++ b/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
@@ -166,8 +166,18 @@
status = "okay";
};
+&pcie_pins {
+ uart3 {
+ groups = "uart3";
+ function = "gpio";
+ };
+};
+
&pcie {
status = "okay";
+
+ reset-gpios = <&gpio 8 GPIO_ACTIVE_LOW>,
+ <&gpio 19 GPIO_ACTIVE_LOW>;
};
&pcie0 {
diff --git a/target/linux/ramips/dts/mt7621_netgear_wax214v2.dts b/target/linux/ramips/dts/mt7621_netgear_wax214v2.dts
new file mode 100644
index 0000000000..a9597119fa
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_wax214v2.dts
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "netgear,wax214v2", "mediatek,mt7621-soc";
+ model = "Netgear WAX214v2";
+
+ aliases {
+ led-boot = &led_power_green;
+ led-failsafe = &led_power_amber;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_blue;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power_green: power_green {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_blue: power_blue {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_amber: power_amber {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_AMBER>;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ };
+
+ wifin_green {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "phy0radio";
+ };
+
+ wifia_green {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "phy1radio";
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Bootloader";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "Config";
+ reg = <0x80000 0x80000>;
+ };
+
+ partition@100000 {
+ label = "Factory";
+ reg = <0x100000 0x80000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ precal_factory_e10: precal@e10 {
+ reg = <0xe10 0x19c10>;
+ };
+ };
+ };
+
+ partition@180000 {
+ label = "firmware";
+ reg = <0x180000 0x2600000>;
+
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x400000>;
+ };
+
+ partition@400000 {
+ label = "ubi";
+ reg = <0x400000 0x2200000>;
+ };
+ };
+
+ partition@2780000 {
+ label = "firmware_backup";
+ reg = <0x2780000 0x2600000>;
+ read-only;
+ };
+
+ partition@4d80000 {
+ label = "CFG";
+ reg = <0x4d80000 0x800000>;
+ read-only;
+ };
+
+ partition@5580000 {
+ label = "RAE";
+ reg = <0x5580000 0x400000>;
+ read-only;
+ };
+
+ partition@5980000 {
+ label = "POT";
+ reg = <0x5980000 0x100000>;
+ read-only;
+ };
+
+ partition@5a80000 {
+ label = "Language";
+ reg = <0x5a80000 0x400000>;
+ read-only;
+ };
+
+ partition@5e80000 {
+ label = "Traffic";
+ reg = <0x5e80000 0x200000>;
+ read-only;
+ };
+
+ partition@6080000 {
+ label = "Cert";
+ reg = <0x6080000 0x100000>;
+ read-only;
+ };
+
+ partition@6180000 {
+ label = "NTGRcryptK";
+ reg = <0x6180000 0x100000>;
+ read-only;
+ };
+
+ partition@6280000 {
+ label = "NTGRcryptD";
+ reg = <0x6280000 0x500000>;
+ read-only;
+ };
+
+ partition@6780000 {
+ label = "LOG";
+ reg = <0x6780000 0x100000>;
+ read-only;
+ };
+
+ partition@6880000 {
+ label = "User_data";
+ reg = <0x6880000 0x640000>;
+ read-only;
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&precal_factory_e10>;
+ nvmem-cell-names = "eeprom", "precal";
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "uart3", "uart2", "jtag";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ status = "okay";
+ label = "lan";
+ };
+ };
+};
+
+&xhci {
+ status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_netis_n6.dts b/target/linux/ramips/dts/mt7621_netis_n6.dts
new file mode 100644
index 0000000000..eb728cfd9b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netis_n6.dts
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "netis,n6", "mediatek,mt7621-soc";
+ model = "netis N6";
+
+ aliases {
+ label-mac-device = &gmac0;
+
+ led-boot = &led_power_green;
+ led-failsafe = &led_system_green;
+ led-running = &led_power_green;
+ led-upgrade = &led_system_green;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ key-0 {
+ label = "wps";
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ debounce-interval = <60>;
+ };
+
+ key-1 {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_USB;
+ gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+ trigger-sources = <&xhci_ehci_port1>;
+ linux,default-trigger = "usbport";
+ };
+
+ led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WPS;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ };
+
+ led_system_green: led-2 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ };
+
+ led-3 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_green: led-4 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_7ef20 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <&ethphy4>;
+
+ nvmem-cells = <&macaddr_factory_7ef26 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&ethphy4 {
+ /delete-property/ interrupts;
+};
+
+&nand {
+ status = "okay";
+
+ mediatek,nmbm;
+ mediatek,bmt-remap-range = <0x000000 0x580000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "Config";
+ reg = <0x80000 0x80000>;
+ };
+
+ partition@100000 {
+ label = "Factory";
+ reg = <0x100000 0x80000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ macaddr_factory_7ef20: macaddr@7ef20 {
+ reg = <0x7ef20 0x6>;
+ };
+
+ macaddr_factory_7ef26: macaddr@7ef26 {
+ reg = <0x7ef26 0x6>;
+ };
+ };
+ };
+
+ partition@180000 {
+ label = "firmware";
+ reg = <0x180000 0x7680000>;
+
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x400000>;
+ };
+
+ partition@400000 {
+ label = "ubi";
+ reg = <0x400000 0x7280000>;
+ };
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+
+ /*
+ * *** The code block below is commented out ***
+ * Reason: Probably, original Netis N6 EEPROM has wrong
+ * MT_EE_WIFI_CONF value 0xd2. As a result 2.4 GHz
+ * doesn't start with mt76 driver. Other routers
+ * with the same WLAN chips (e.g., Routerich
+ * AX1800) have MT_EE_WIFI_CONF = 0x92.
+ * Workaround: Extract EEPROM to a file at the first time
+ * boot and change MT_EE_WIFI_CONF (offset
+ * 0x190) value from 0xd2 to 0x92. See
+ * /etc/hotplug.d/firmware/11-mt76-caldata for
+ * details.
+ */
+
+ /*
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ */
+
+ mediatek,disable-radar-background;
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "i2c", "jtag", "wdt";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ status = "okay";
+ label = "lan4";
+ };
+
+ port@1 {
+ status = "okay";
+ label = "lan3";
+ };
+
+ port@2 {
+ status = "okay";
+ label = "lan2";
+ };
+
+ port@3 {
+ status = "okay";
+ label = "lan1";
+ };
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_openfi_5pro.dts b/target/linux/ramips/dts/mt7621_openfi_5pro.dts
index 6348259081..6348259081 100755..100644
--- a/target/linux/ramips/dts/mt7621_openfi_5pro.dts
+++ b/target/linux/ramips/dts/mt7621_openfi_5pro.dts
diff --git a/target/linux/ramips/dts/mt7621_ruijie_rg-ew1200g-pro-v1.1.dts b/target/linux/ramips/dts/mt7621_ruijie_rg-ew1200g-pro-v1.1.dts
new file mode 100644
index 0000000000..0223ece164
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ruijie_rg-ew1200g-pro-v1.1.dts
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "ruijie,rg-ew1200g-pro-v1.1", "mediatek,mt7621-soc";
+ model = "Ruijie RG-EW1200G PRO v.1.1";
+
+ aliases {
+ led-boot = &led_power_blue;
+ led-failsafe = &led_power_blue;
+ led-running = &led_power_blue;
+ led-upgrade = &led_power_blue;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,57600n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power_blue: power_blue {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <25000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x000000 0x50000>;
+ read-only;
+ };
+
+ partition@50000 {
+ label = "u-boot-env";
+ reg = <0x50000 0x10000>;
+ read-only;
+ };
+
+ partition@60000 {
+ label = "factory";
+ reg = <0x60000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x4da8>;
+ };
+ };
+ };
+
+ partition@70000 {
+ label = "product_info";
+ reg = <0x70000 0x10000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "kdump";
+ reg = <0x80000 0x10000>;
+ read-only;
+ };
+
+ partition@90000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x90000 0xf70000>;
+ };
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie0 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ status = "okay";
+ label = "wan";
+ };
+
+ port@1 {
+ status = "okay";
+ label = "lan3";
+ };
+
+ port@2 {
+ status = "okay";
+ label = "lan2";
+ };
+
+ port@3 {
+ status = "okay";
+ label = "lan1";
+ };
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_snr_snr-cpe-me2-lite.dts b/target/linux/ramips/dts/mt7621_snr_snr-cpe-me2-lite.dts
index cd0e7465ff..8ee88b2609 100644
--- a/target/linux/ramips/dts/mt7621_snr_snr-cpe-me2-lite.dts
+++ b/target/linux/ramips/dts/mt7621_snr_snr-cpe-me2-lite.dts
@@ -53,7 +53,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <104000000>;
+ spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
diff --git a/target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts b/target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts
index de352741f8..4917ffc81e 100644
--- a/target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts
+++ b/target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts
@@ -102,7 +102,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
diff --git a/target/linux/ramips/dts/mt7621_tplink_er605-v2.dts b/target/linux/ramips/dts/mt7621_tplink_er605-v2.dts
index 1299b02806..28c8e8b083 100644
--- a/target/linux/ramips/dts/mt7621_tplink_er605-v2.dts
+++ b/target/linux/ramips/dts/mt7621_tplink_er605-v2.dts
@@ -84,7 +84,7 @@
&gmac1 {
status = "okay";
- label = "eth0";
+ label = "wan1";
phy-handle = <&ethphy0>;
};
@@ -97,22 +97,22 @@
port@1 {
status = "okay";
- label = "eth1";
+ label = "lan2";
};
port@2 {
status = "okay";
- label = "eth2";
+ label = "lan3";
};
port@3 {
status = "okay";
- label = "eth3";
+ label = "lan4";
};
port@4 {
status = "okay";
- label = "eth4";
+ label = "lan5";
};
};
};
diff --git a/target/linux/ramips/dts/mt7621_tplink_mr600-v2-eu.dts b/target/linux/ramips/dts/mt7621_tplink_mr600-v2-eu.dts
index 234202ba87..165b48d209 100644
--- a/target/linux/ramips/dts/mt7621_tplink_mr600-v2-eu.dts
+++ b/target/linux/ramips/dts/mt7621_tplink_mr600-v2-eu.dts
@@ -92,7 +92,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
diff --git a/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi b/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi
index 3264a8673c..ff2c39d704 100644
--- a/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi
+++ b/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi
@@ -44,7 +44,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_winstars_ws-wn536p3.dts b/target/linux/ramips/dts/mt7621_winstars_ws-wn536p3.dts
index 5c99ddc527..5c99ddc527 100755..100644
--- a/target/linux/ramips/dts/mt7621_winstars_ws-wn536p3.dts
+++ b/target/linux/ramips/dts/mt7621_winstars_ws-wn536p3.dts
diff --git a/target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts b/target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts
index 7090869c4e..d40f56e1e9 100644
--- a/target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts
+++ b/target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts
@@ -67,7 +67,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <104000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts b/target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts
new file mode 100644
index 0000000000..f16d27e8d7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "wodesys,wd-r1802u", "mediatek,mt7621-soc";
+ model = "Wodesys WD-R1802U";
+
+ aliases {
+ label-mac-device = &gmac0;
+ led-boot = &led_blue;
+ led-failsafe = &led_red;
+ led-running = &led_green;
+ led-upgrade = &led_blue;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-0 {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led_green: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ };
+
+ led_blue: led-1 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ };
+
+ led_red: led-2 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+ panic-indicator;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_4 1>;
+ nvmem-cell-names = "mac-address";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&precal_factory_e10>;
+ nvmem-cell-names = "eeprom", "precal";
+ mediatek,disable-radar-background;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000 0x30000>;
+ read-only;
+ };
+
+ /* 0x30000-0x4ffff are unused
+ (flash contents is 0xff) */
+
+ partition@50000 {
+ label = "factory";
+ reg = <0x50000 0x40000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ macaddr_factory_4: macaddr@4 { // wifi 2.4
+ compatible = "mac-base";
+ reg = <0x4 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ precal_factory_e10: precal@e10 {
+ reg = <0xe10 0x19c10>;
+ };
+ };
+ };
+
+ partition@90000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x90000 0xf70000>;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "jtag", "wdt";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@4 {
+ status = "okay";
+ label = "lan";
+ };
+ };
+};
+
+&xhci {
+ status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_yuncore_ax820.dts b/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
index 316c180098..51421aba6a 100644
--- a/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
+++ b/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
@@ -87,7 +87,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_yuncore_fap640.dts b/target/linux/ramips/dts/mt7621_yuncore_fap640.dts
index 536b45e03f..5e18ded9b0 100644
--- a/target/linux/ramips/dts/mt7621_yuncore_fap640.dts
+++ b/target/linux/ramips/dts/mt7621_yuncore_fap640.dts
@@ -100,7 +100,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_yuncore_fap690.dts b/target/linux/ramips/dts/mt7621_yuncore_fap690.dts
index 9f7ca43092..bb25ade1a8 100644
--- a/target/linux/ramips/dts/mt7621_yuncore_fap690.dts
+++ b/target/linux/ramips/dts/mt7621_yuncore_fap690.dts
@@ -69,7 +69,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
index 7dfe9a7699..2b54faae9e 100644
--- a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
@@ -1,7 +1,6 @@
-#include "mt7621.dtsi"
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
+#include "mt7621_zbtlink_zbt-wexx26.dtsi"
/ {
compatible = "zbtlink,zbt-we1326", "mediatek,mt7621-soc";
@@ -10,167 +9,4 @@
aliases {
label-mac-device = &wifi1;
};
-
- chosen {
- bootargs = "console=ttyS0,115200";
- };
-
- keys {
- compatible = "gpio-keys";
-
- reset {
- label = "reset";
- gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_RESTART>;
- };
- };
-};
-
-&state_default {
- gpio {
- groups = "wdt";
- function = "gpio";
- };
-};
-
-&spi0 {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <10000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0 0x30000>;
- read-only;
- };
-
- partition@30000 {
- label = "u-boot-env";
- reg = <0x30000 0x10000>;
- read-only;
- };
-
- partition@40000 {
- label = "factory";
- reg = <0x40000 0x10000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- eeprom_factory_0: eeprom@0 {
- reg = <0x0 0x400>;
- };
-
- eeprom_factory_8000: eeprom@8000 {
- reg = <0x8000 0x200>;
- };
-
- macaddr_factory_e000: macaddr@e000 {
- reg = <0xe000 0x6>;
- };
-
- macaddr_factory_e006: macaddr@e006 {
- reg = <0xe006 0x6>;
- };
- };
- };
-
- partition@50000 {
- compatible = "denx,uimage";
- label = "firmware";
- reg = <0x50000 0xfb0000>;
- };
- };
- };
-};
-
-&gmac0 {
- nvmem-cells = <&macaddr_factory_e000>;
- nvmem-cell-names = "mac-address";
-};
-
-&gmac1 {
- status = "okay";
- label = "wan";
- phy-handle = <&ethphy4>;
-
- nvmem-cells = <&macaddr_factory_e006>;
- nvmem-cell-names = "mac-address";
-};
-
-&ethphy4 {
- /delete-property/ interrupts;
-};
-
-&switch0 {
- ports {
- port@0 {
- status = "okay";
- label = "lan1";
- };
-
- port@1 {
- status = "okay";
- label = "lan2";
- };
-
- port@2 {
- status = "okay";
- label = "lan3";
- };
-
- port@3 {
- status = "okay";
- label = "lan4";
- };
- };
-};
-
-&pcie {
- status = "okay";
-};
-
-&pcie1 {
- wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_8000>;
- nvmem-cell-names = "eeprom";
- ieee80211-freq-limit = <5000000 6000000>;
-
- led {
- led-sources = <2>;
- led-active-low;
- };
- };
-};
-
-&pcie2 {
- wifi1: wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_0>;
- nvmem-cell-names = "eeprom";
- ieee80211-freq-limit = <2400000 2500000>;
-
- led {
- led-sources = <0>;
- led-active-low;
- };
- };
-};
-
-&sdhci {
- status = "okay";
};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
index 31a4e4482a..4f40f2926c 100644
--- a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
@@ -1,169 +1,8 @@
-#include "mt7621.dtsi"
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
+#include "mt7621_zbtlink_zbt-wexx26.dtsi"
/ {
compatible = "zbtlink,zbt-we3526", "mediatek,mt7621-soc";
model = "Zbtlink ZBT-WE3526";
-
- chosen {
- bootargs = "console=ttyS0,115200";
- };
-
- keys {
- compatible = "gpio-keys";
-
- reset {
- label = "reset";
- gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_RESTART>;
- };
- };
-};
-
-&i2c {
- status = "okay";
-};
-
-&sdhci {
- status = "okay";
-};
-
-&spi0 {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <10000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0 0x30000>;
- read-only;
- };
-
- partition@30000 {
- label = "u-boot-env";
- reg = <0x30000 0x10000>;
- read-only;
- };
-
- partition@40000 {
- label = "factory";
- reg = <0x40000 0x10000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- eeprom_factory_0: eeprom@0 {
- reg = <0x0 0x400>;
- };
-
- eeprom_factory_8000: eeprom@8000 {
- reg = <0x8000 0x200>;
- };
-
- macaddr_factory_e000: macaddr@e000 {
- reg = <0xe000 0x6>;
- };
-
- macaddr_factory_e006: macaddr@e006 {
- reg = <0xe006 0x6>;
- };
- };
- };
-
- partition@50000 {
- compatible = "denx,uimage";
- label = "firmware";
- reg = <0x50000 0xfb0000>;
- };
- };
- };
-};
-
-&pcie {
- status = "okay";
-};
-
-&pcie0 {
- wifi@0,0 {
- compatible = "pci14c3,7662";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_8000>;
- nvmem-cell-names = "eeprom";
- ieee80211-freq-limit = <5000000 6000000>;
-
- led {
- led-sources = <2>;
- };
- };
-};
-
-&pcie1 {
- wifi@0,0 {
- compatible = "pci14c3,7603";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_0>;
- nvmem-cell-names = "eeprom";
- };
-};
-
-&gmac0 {
- nvmem-cells = <&macaddr_factory_e000>;
- nvmem-cell-names = "mac-address";
-};
-
-&gmac1 {
- status = "okay";
- label = "wan";
- phy-handle = <&ethphy4>;
-
- nvmem-cells = <&macaddr_factory_e006>;
- nvmem-cell-names = "mac-address";
-};
-
-&ethphy4 {
- /delete-property/ interrupts;
-};
-
-&switch0 {
- ports {
- port@0 {
- status = "okay";
- label = "lan1";
- };
-
- port@1 {
- status = "okay";
- label = "lan2";
- };
-
- port@2 {
- status = "okay";
- label = "lan3";
- };
-
- port@3 {
- status = "okay";
- label = "lan4";
- };
- };
-};
-
-&state_default {
- gpio {
- groups = "wdt";
- function = "gpio";
- };
};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi
new file mode 100644
index 0000000000..e1428b7148
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+};
+
+&ethphy4 {
+ /delete-property/ interrupts;
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_e000>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <&ethphy4>;
+
+ nvmem-cells = <&macaddr_factory_e006>;
+ nvmem-cell-names = "mac-address";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_8000>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <5000000 6000000>;
+
+ led {
+ led-sources = <2>;
+ led-active-low;
+ };
+ };
+};
+
+&pcie2 {
+ wifi1: wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <2400000 2500000>;
+
+ led {
+ led-sources = <0>;
+ led-active-low;
+ };
+ };
+};
+
+&sdhci {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x400>;
+ };
+
+ eeprom_factory_8000: eeprom@8000 {
+ reg = <0x8000 0x200>;
+ };
+
+ macaddr_factory_e000: macaddr@e000 {
+ reg = <0xe000 0x6>;
+ };
+
+ macaddr_factory_e006: macaddr@e006 {
+ reg = <0xe006 0x6>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0xfb0000>;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "wdt";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ status = "okay";
+ label = "lan1";
+ };
+
+ port@1 {
+ status = "okay";
+ label = "lan2";
+ };
+
+ port@2 {
+ status = "okay";
+ label = "lan3";
+ };
+
+ port@3 {
+ status = "okay";
+ label = "lan4";
+ };
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts b/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts
index edc861db61..9eed123157 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts
@@ -7,7 +7,7 @@
/ {
compatible = "zyxel,lte3301-plus", "mediatek,mt7621-soc";
- model = "ZyXEL LTE3301-Plus";
+ model = "Zyxel LTE3301-Plus";
aliases {
label-mac-device = &gmac0;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts b/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts
index ca8adfe10e..e121077b0a 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,lte5398-m904", "mediatek,mt7621-soc";
- model = "ZyXEL LTE5398-M904";
+ model = "Zyxel LTE5398-M904";
aliases {
label-mac-device = &gmac0;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts b/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
index 756d4bd6e6..070ea4a13f 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
@@ -7,7 +7,7 @@
/ {
compatible = "zyxel,nr7101", "mediatek,mt7621-soc";
- model = "ZyXEL NR7101";
+ model = "Zyxel NR7101";
aliases {
led-boot = &led_system_green;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts b/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
index 2cdaa40a1c..1ae3b9ad63 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
@@ -5,7 +5,7 @@
/ {
compatible = "zyxel,nwa50ax", "mediatek,mt7621-soc";
- model = "ZyXEL NWA50AX";
+ model = "Zyxel NWA50AX";
aliases {
led-boot = &led_system_green;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts b/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
index 7f0a6d2cdf..0dc4943cb4 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
@@ -2,5 +2,5 @@
/ {
compatible = "zyxel,nwa55axe", "mediatek,mt7621-soc";
- model = "ZyXEL NWA55AXE";
+ model = "Zyxel NWA55AXE";
};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts b/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
index eabfcc2ef0..b3e8f6db74 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,wap6805", "mediatek,mt7621-soc";
- model = "ZyXEL WAP6805";
+ model = "Zyxel WAP6805";
aliases {
led-boot = &led_status_green;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts b/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts
index 6bf65a0218..42dc716027 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts
@@ -7,7 +7,7 @@
/ {
compatible = "zyxel,wsm20", "mediatek,mt7621-soc";
- model = "ZyXEL WSM20";
+ model = "Zyxel WSM20";
aliases {
led-boot = &led_system_white;
diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi
index 906ea03fe9..445c530815 100644
--- a/target/linux/ramips/dts/mt7628an.dtsi
+++ b/target/linux/ramips/dts/mt7628an.dtsi
@@ -30,6 +30,35 @@
compatible = "mti,cpu-interrupt-controller";
};
+ mmc_clk: mmc-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-accuracy = <100>;
+ };
+
+ mmc_reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+
+ enable-active-high;
+
+ regulator-always-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "mmc_io";
+ };
+
+ mmc_reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+
+ enable-active-high;
+
+ regulator-always-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "mmc_power";
+ };
+
palmbus: palmbus@10000000 {
compatible = "palmbus";
reg = <0x10000000 0x200000>;
@@ -52,7 +81,7 @@
};
intc: intc@200 {
- compatible = "ralink,mt7628an-intc", "ralink,rt2880-intc";
+ compatible = "ralink,rt2880-intc";
reg = <0x200 0x100>;
interrupt-controller;
@@ -355,15 +384,34 @@
reset-names = "host", "device";
};
- sdhci: sdhci@10130000 {
- compatible = "ralink,mt7620-sdhci";
+ sdhci: mmc@10130000 {
+ compatible = "mediatek,mt7620-mmc", "ralink,mt7620-sdhci";
reg = <0x10130000 0x4000>;
+ bus-width = <4>;
+
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+
+ clocks = <&mmc_clk>, <&mmc_clk>;
+ clock-names = "source", "hclk";
+
+ disable-wp;
+
interrupt-parent = <&intc>;
interrupts = <14>;
- pinctrl-names = "default";
+ max-frequency = <48000000>;
+
+ pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&sdxc_pins>;
+ pinctrl-1 = <&sdxc_pins>;
+
+ resets = <&sysc 30>;
+ reset-names = "hrst";
+
+ vmmc-supply = <&mmc_reg_3v3>;
+ vqmmc-supply = <&mmc_reg_1v8>;
status = "disabled";
};
@@ -418,7 +466,7 @@
};
esw: esw@10110000 {
- compatible = "mediatek,mt7628-esw", "ralink,rt3050-esw";
+ compatible = "ralink,rt3050-esw";
reg = <0x10110000 0x8000>;
resets = <&sysc 24>;
diff --git a/target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts b/target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts
index 940104d47e..bcd2cecb3a 100644
--- a/target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts
+++ b/target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts
@@ -171,5 +171,5 @@
&sdhci {
status = "okay";
- mediatek,cd-high;
+ cd-inverted;
};
diff --git a/target/linux/ramips/dts/mt7628an_duzun_dm06.dts b/target/linux/ramips/dts/mt7628an_duzun_dm06.dts
index 59d411f88f..1c40c12caf 100644
--- a/target/linux/ramips/dts/mt7628an_duzun_dm06.dts
+++ b/target/linux/ramips/dts/mt7628an_duzun_dm06.dts
@@ -96,7 +96,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <60000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts b/target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts
index 51731c3c64..c7e3640d88 100644
--- a/target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts
+++ b/target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts
@@ -55,16 +55,10 @@
gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
};
+};
- sdhci@10130000 {
- compatible = "ralink,mt7620-sdhci";
- reg = <0x10130000 4000>;
-
- interrupt-parent = <&intc>;
- interrupts = <14>;
-
- status = "okay";
- };
+&sdhci {
+ status = "okay";
};
&state_default {
diff --git a/target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi b/target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi
index 42bb804c65..4b114c9414 100644
--- a/target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi
+++ b/target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi
@@ -36,7 +36,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi b/target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi
index 96d36f66e0..0aee4e408a 100644
--- a/target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi
+++ b/target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi
@@ -132,7 +132,6 @@
&sdhci {
status = "okay";
- mediatek,cd-low;
};
&wmac {
diff --git a/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts b/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts
index 37b4b9baa5..fdce5cbec5 100644
--- a/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts
+++ b/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts
@@ -167,7 +167,7 @@
&sdhci {
status = "okay";
- mediatek,cd-high;
+ cd-inverted;
};
&wmac {
diff --git a/target/linux/ramips/dts/mt7628an_minew_g1-c.dts b/target/linux/ramips/dts/mt7628an_minew_g1-c.dts
index 3912f23a9e..603bc09fa6 100644
--- a/target/linux/ramips/dts/mt7628an_minew_g1-c.dts
+++ b/target/linux/ramips/dts/mt7628an_minew_g1-c.dts
@@ -151,5 +151,5 @@
&sdhci {
status = "okay";
- mediatek,cd-high;
+ cd-inverted;
};
diff --git a/target/linux/ramips/dts/mt7628an_motorola_mwr03.dts b/target/linux/ramips/dts/mt7628an_motorola_mwr03.dts
index 1c57fce196..7b288701c9 100644
--- a/target/linux/ramips/dts/mt7628an_motorola_mwr03.dts
+++ b/target/linux/ramips/dts/mt7628an_motorola_mwr03.dts
@@ -50,7 +50,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <80000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi b/target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi
index 41e5fb7e4b..a8e7353967 100644
--- a/target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi
+++ b/target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi
@@ -70,7 +70,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <86000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions: partitions {
diff --git a/target/linux/ramips/dts/mt7628an_onion_omega2.dtsi b/target/linux/ramips/dts/mt7628an_onion_omega2.dtsi
index 983c7fc03e..d279cbcfb8 100644
--- a/target/linux/ramips/dts/mt7628an_onion_omega2.dtsi
+++ b/target/linux/ramips/dts/mt7628an_onion_omega2.dtsi
@@ -172,7 +172,6 @@
&sdhci {
status = "okay";
- mediatek,cd-low;
};
&wmac {
diff --git a/target/linux/ramips/dts/mt7628an_tplink_archer-mr200-v5.dts b/target/linux/ramips/dts/mt7628an_tplink_archer-mr200-v5.dts
index 177cd4db8a..b6a5a61b7c 100644
--- a/target/linux/ramips/dts/mt7628an_tplink_archer-mr200-v5.dts
+++ b/target/linux/ramips/dts/mt7628an_tplink_archer-mr200-v5.dts
@@ -89,7 +89,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <104000000>;
+ spi-max-frequency = <50000000>;
m25p,fast-read;
partitions {
diff --git a/target/linux/ramips/dts/mt7628an_widora_neo.dtsi b/target/linux/ramips/dts/mt7628an_widora_neo.dtsi
index de3b7d625e..74df529bd2 100644
--- a/target/linux/ramips/dts/mt7628an_widora_neo.dtsi
+++ b/target/linux/ramips/dts/mt7628an_widora_neo.dtsi
@@ -175,7 +175,6 @@
&sdhci {
status = "okay";
- mediatek,cd-low;
};
&wmac {
diff --git a/target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts b/target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts
index 429b00c5b5..5714aaedc3 100644
--- a/target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts
+++ b/target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts
@@ -168,7 +168,7 @@
&sdhci {
status = "okay";
- mediatek,cd-high;
+ cd-inverted;
};
&wmac {
diff --git a/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts
new file mode 100644
index 0000000000..b12901bd5b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include <dt-bindings/leds/common.h>
+
+#include "mt7628an_xiaomi_mi-router-4.dtsi"
+
+/ {
+ compatible = "xiaomi,mi-router-4a-100m-intl-v2", "mediatek,mt7628an-soc";
+ model = "Xiaomi Mi Router 4A (100M International Edition V2)";
+
+ aliases {
+ led-boot = &led_power_yellow;
+ led-failsafe = &led_power_yellow;
+ led-running = &led_power_blue;
+ led-upgrade = &led_power_yellow;
+ label-mac-device = &ethernet;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power_blue: power_blue {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_yellow: power_yellow {
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+ };
+
+ wan {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+};
+
+&partitions {
+ partition@60000 {
+ label = "overlay";
+ reg = <0x60000 0x100000>;
+ read-only;
+ };
+
+ partition@160000 {
+ label = "firmware";
+ reg = <0x160000 0xea0000>;
+ compatible = "denx,uimage";
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&eeprom_factory_8000 {
+ /* MT7613 has different eeprom size '0x4da8' */
+ /* See https://github.com/openwrt/openwrt/pull/13587 */
+ /* You can also see this in mt76/mt7615/eeprom.h: */
+ /* MT7615_EEPROM_FULL_SIZE = MT7615_EEPROM_TXDPD_OFFSET + \ */
+ /* MT7615_EEPROM_TXDPD_COUNT * MT7615_EEPROM_TXDPD_SIZE */
+ /* where MT7615_EEPROM_TXDPD_OFFSET is 1024 + 256 * 34 = 9728: */
+ /* MT7615_EEPROM_SIZE(1024 defined in mt7615.h) + \ */
+ /* MT7615_EEPROM_DCOC_COUNT(34) * MT7615_EEPROM_DCOC_SIZE(256)*/
+ /* where MT7615_EEPROM_TXDPD_COUNT = 44 + 3 = 47 */
+ /* and MT7615_EEPROM_TXDPD_SIZE = 216. */
+ /* Altogether it will be 19880 or 0x4da8. */
+ reg = <0x8000 0x4da8>;
+};
+
+&pcie0 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_8000>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <5000000 6000000>;
+ };
+};
+
+&ethernet {
+ nvmem-cells = <&macaddr_factory_4 (-1)>;
+ nvmem-cell-names = "mac-address";
+};
+
+&esw {
+ mediatek,portmap = <0x3e>;
+ mediatek,portdisable = <0x2a>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts b/target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts
new file mode 100644
index 0000000000..6e6202f02b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts
@@ -0,0 +1,165 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "yuncore,cpe200", "mediatek,mt7628an-soc";
+ model = "Yuncore CPE200";
+
+ chosen {
+ bootargs = "console=ttyS0,57600";
+ };
+
+ aliases {
+ label-mac = &ethernet;
+ led-boot = &led_power;
+ led-failsafe = &led_power;
+ led-running = &led_power;
+ led-upgrade = &led_power;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ mode {
+ label = "mode";
+ linux,input-type = <EV_SW>;
+ linux,code = <BTN_0>;
+ gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power: power {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ lan {
+ function = LED_FUNCTION_LAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+ };
+
+ wan {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ watchdog {
+ compatible = "linux,wdt-gpio";
+ gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
+ hw_algo = "toggle";
+ hw_margin_ms = <20000>;
+ always-running;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
+ };
+
+ eeprom_factory_8000: eeprom@8000 {
+ reg = <0x8000 0x600>;
+ };
+
+ macaddr_factory_8004: macaddr@8004 {
+ reg = <0x8004 0x6>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+ };
+};
+
+&ethernet {
+ nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&esw {
+ mediatek,portmap = <0x2f>;
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie0 {
+ mt76@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ ieee80211-freq-limit = <5000000 6000000>;
+ nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_8004>;
+ nvmem-cell-names = "eeprom", "mac-address";
+
+ led {
+ led-sources = <0>;
+ led-active-low;
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "pwm0", "i2c", "refclk", "wdt", "i2s", "spi cs1",
+ "spis", "gpio", "p0led_an", "p1led_an", "p2led_an",
+ "p3led_an", "p4led_an", "wled_kn", "p0led_kn",
+ "p1led_kn", "p2led_kn", "p3led_kn", "p4led_kn", "wled_an";
+ function = "gpio";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7628an_yuncore_m300.dts b/target/linux/ramips/dts/mt7628an_yuncore_m300.dts
new file mode 100644
index 0000000000..8897c11d67
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_yuncore_m300.dts
@@ -0,0 +1,148 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "yuncore,m300", "mediatek,mt7628an-soc";
+ model = "Yuncore M300";
+
+ chosen {
+ bootargs = "console=ttyS0,57600";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ aliases {
+ label-mac = &ethernet;
+ led-boot = &led_indicator;
+ led-failsafe = &led_indicator;
+ led-running = &led_indicator;
+ led-upgrade = &led_indicator;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_indicator: indicator {
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ lan {
+ function = LED_FUNCTION_LAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+ };
+
+ wan {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ watchdog {
+ compatible = "linux,wdt-gpio";
+ gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
+ hw_algo = "toggle";
+ hw_margin_ms = <20000>;
+ always-running;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x400>;
+ };
+
+ macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+ };
+};
+
+&ethernet {
+ nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&esw {
+ mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+};
+
+&state_default {
+ gpio {
+ groups = "pwm1", "pwm0", "uart2", "uart1", "i2c", "refclk",
+ "perst", "wdt", "sdmode", "i2s", "spi cs1", "spis",
+ "gpio", "p0led_an", "p1led_an", "p2led_an", "p3led_an",
+ "p4led_an", "wled_kn", "p0led_kn", "p1led_kn",
+ "p2led_kn", "p3led_kn", "p4led_kn";
+ function = "gpio";
+ };
+
+ wlan {
+ groups = "wled_an";
+ function = "wled_an";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts b/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
index 70956724fb..3e59fc6bf4 100644
--- a/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
+++ b/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-extra-ii", "mediatek,mt7628an-soc";
- model = "ZyXEL Keenetic Extra II";
+ model = "Zyxel Keenetic Extra II";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt2880.dtsi b/target/linux/ramips/dts/rt2880.dtsi
index 998b49a277..15f5eac625 100644
--- a/target/linux/ramips/dts/rt2880.dtsi
+++ b/target/linux/ramips/dts/rt2880.dtsi
@@ -88,7 +88,6 @@
#gpio-cells = <2>;
ngpios = <24>;
- ralink,gpio-base = <0>;
ralink,register-map = [ 00 04 08 0c
20 24 28 2c
30 34 ];
@@ -102,7 +101,6 @@
#gpio-cells = <2>;
ngpios = <16>;
- ralink,gpio-base = <24>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -118,7 +116,6 @@
#gpio-cells = <2>;
ngpios = <32>;
- ralink,gpio-base = <40>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -218,7 +215,7 @@
status = "disabled";
port@0 {
- compatible = "ralink,rt2880-port", "mediatek,eth-port";
+ compatible = "mediatek,eth-port";
reg = <0>;
};
diff --git a/target/linux/ramips/dts/rt3050.dtsi b/target/linux/ramips/dts/rt3050.dtsi
index 30a3f898cd..886f6b7de1 100644
--- a/target/linux/ramips/dts/rt3050.dtsi
+++ b/target/linux/ramips/dts/rt3050.dtsi
@@ -47,7 +47,7 @@
};
timer: timer@100 {
- compatible = "ralink,rt3050-timer", "ralink,rt2880-timer";
+ compatible = "ralink,rt2880-timer";
reg = <0x100 0x20>;
clocks = <&sysc 3>;
@@ -57,7 +57,7 @@
};
watchdog: watchdog@120 {
- compatible = "ralink,rt3050-wdt", "ralink,rt2880-wdt";
+ compatible = "ralink,rt2880-wdt";
reg = <0x120 0x10>;
clocks = <&sysc 4>;
@@ -70,7 +70,7 @@
};
intc: intc@200 {
- compatible = "ralink,rt3050-intc", "ralink,rt2880-intc";
+ compatible = "ralink,rt2880-intc";
reg = <0x200 0x100>;
interrupt-controller;
@@ -89,7 +89,7 @@
};
uart: uart@500 {
- compatible = "ralink,rt3050-uart", "ralink,rt2880-uart", "ns16550a";
+ compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0x500 0x100>;
clocks = <&sysc 5>;
@@ -105,14 +105,13 @@
};
gpio0: gpio@600 {
- compatible = "ralink,rt3050-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x600 0x34>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <24>;
- ralink,gpio-base = <0>;
ralink,register-map = [ 00 04 08 0c
20 24 28 2c
30 34 ];
@@ -122,14 +121,13 @@
};
gpio1: gpio@638 {
- compatible = "ralink,rt3050-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x638 0x24>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <16>;
- ralink,gpio-base = <24>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -138,14 +136,13 @@
};
gpio2: gpio@660 {
- compatible = "ralink,rt3050-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x660 0x24>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <12>;
- ralink,gpio-base = <40>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -209,7 +206,7 @@
};
spi0: spi@b00 {
- compatible = "ralink,rt3050-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb00 0x100>;
resets = <&sysc 18>;
@@ -227,7 +224,7 @@
};
uartlite: uartlite@c00 {
- compatible = "ralink,rt3050-uart", "ralink,rt2880-uart", "ns16550a";
+ compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0xc00 0x100>;
clocks = <&sysc 10>;
diff --git a/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts b/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
index e7db3eda15..c7285150d9 100644
--- a/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
+++ b/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic", "ralink,rt3052-soc";
- model = "ZyXEL Keenetic";
+ model = "Zyxel Keenetic";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts b/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
index 8dee38c1f8..fc6cd21f3c 100644
--- a/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
+++ b/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg-419n", "ralink,rt3052-soc";
- model = "ZyXEL NBG-419N";
+ model = "Zyxel NBG-419N";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt3352.dtsi b/target/linux/ramips/dts/rt3352.dtsi
index b4829cb1b1..ceef29259c 100644
--- a/target/linux/ramips/dts/rt3352.dtsi
+++ b/target/linux/ramips/dts/rt3352.dtsi
@@ -48,7 +48,7 @@
};
timer: timer@100 {
- compatible = "ralink,rt3352-timer", "ralink,rt2880-timer";
+ compatible = "ralink,rt2880-timer";
reg = <0x100 0x20>;
clocks = <&sysc 4>;
@@ -58,7 +58,7 @@
};
watchdog: watchdog@120 {
- compatible = "ralink,rt3352-wdt", "ralink,rt2880-wdt";
+ compatible = "ralink,rt2880-wdt";
reg = <0x120 0x10>;
clocks = <&sysc 5>;
@@ -71,7 +71,7 @@
};
intc: intc@200 {
- compatible = "ralink,rt3352-intc", "ralink,rt2880-intc";
+ compatible = "ralink,rt2880-intc";
reg = <0x200 0x100>;
interrupt-controller;
@@ -82,7 +82,7 @@
};
memc: memc@300 {
- compatible = "ralink,rt3352-memc", "ralink,rt3050-memc";
+ compatible = "ralink,rt3050-memc";
reg = <0x300 0x100>;
interrupt-parent = <&intc>;
@@ -90,7 +90,7 @@
};
uart: uart@500 {
- compatible = "ralink,rt3352-uart", "ralink,rt2880-uart", "ns16550a";
+ compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0x500 0x100>;
clocks = <&sysc 6>;
@@ -106,14 +106,13 @@
};
gpio0: gpio@600 {
- compatible = "ralink,rt3352-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x600 0x34>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <24>;
- ralink,gpio-base = <0>;
ralink,register-map = [ 00 04 08 0c
20 24 28 2c
30 34 ];
@@ -123,14 +122,13 @@
};
gpio1: gpio@638 {
- compatible = "ralink,rt3352-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x638 0x24>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <16>;
- ralink,gpio-base = <24>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -139,14 +137,13 @@
};
gpio2: gpio@660 {
- compatible = "ralink,rt3352-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x660 0x24>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <6>;
- ralink,gpio-base = <40>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -195,7 +192,7 @@
};
spi0: spi@b00 {
- compatible = "ralink,rt3352-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb00 0x40>;
#address-cells = <1>;
#size-cells = <0>;
@@ -212,7 +209,7 @@
};
spi1: spi@b40 {
- compatible = "ralink,rt3352-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb40 0x60>;
#address-cells = <1>;
#size-cells = <0>;
@@ -227,7 +224,7 @@
};
uartlite: uartlite@c00 {
- compatible = "ralink,rt3352-uart", "ralink,rt2880-uart", "ns16550a";
+ compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0xc00 0x100>;
clocks = <&sysc 11>;
@@ -314,7 +311,7 @@
};
ethernet: ethernet@10100000 {
- compatible = "ralink,rt3352-eth", "ralink,rt3050-eth";
+ compatible = "ralink,rt3050-eth";
reg = <0x10100000 0x10000>;
clocks = <&sysc 12>;
@@ -329,7 +326,7 @@
};
esw: esw@10110000 {
- compatible = "ralink,rt3352-esw", "ralink,rt3050-esw";
+ compatible = "ralink,rt3050-esw";
reg = <0x10110000 0x8000>;
resets = <&sysc 24>;
diff --git a/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts b/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
index f00fd58b71..ce776d4603 100644
--- a/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
+++ b/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg-419n-v2", "ralink,rt3352-soc";
- model = "ZyXEL NBG-419N v2";
+ model = "Zyxel NBG-419N v2";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts b/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
index 391076cee9..c381aa3e03 100644
--- a/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
+++ b/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
@@ -73,7 +73,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <8 1 0 1 1 1 1 1 1 2>;
};
keys {
diff --git a/target/linux/ramips/dts/rt3662_dlink_dir-645.dts b/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
index 3d6479f44f..8cfa48e195 100644
--- a/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
+++ b/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
@@ -19,7 +19,7 @@
compatible = "realtek,rtl8367b";
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <6 1 0 1 1 1 1 1 1 2>;
};
keys {
diff --git a/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
index 051e28da8f..fbc795b24f 100644
--- a/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
+++ b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
@@ -127,7 +127,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio0 5 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 4 GPIO_ACTIVE_HIGH>;
- realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <9 1 0 1 1 1 1 1 1 2>;
};
/*
diff --git a/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts b/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
index 9964fcf600..bcc215c17a 100644
--- a/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
+++ b/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
@@ -81,7 +81,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <9 1 0 1 1 1 1 1 1 2>;
};
keys {
diff --git a/target/linux/ramips/dts/rt3883.dtsi b/target/linux/ramips/dts/rt3883.dtsi
index 8c76eb6631..30c0916785 100644
--- a/target/linux/ramips/dts/rt3883.dtsi
+++ b/target/linux/ramips/dts/rt3883.dtsi
@@ -48,20 +48,20 @@
};
timer: timer@100 {
- compatible = "ralink,rt3883-timer", "ralink,rt2880-timer";
+ compatible = "ralink,rt2880-timer";
reg = <0x100 0x20>;
- clocks = <&sysc 3>;
+ clocks = <&sysc 4>;
interrupt-parent = <&intc>;
interrupts = <1>;
};
watchdog: watchdog@120 {
- compatible = "ralink,rt3883-wdt", "ralink,rt2880-wdt";
+ compatible = "ralink,rt2880-wdt";
reg = <0x120 0x10>;
- clocks = <&sysc 4>;
+ clocks = <&sysc 5>;
resets = <&sysc 8>;
reset-names = "wdt";
@@ -71,7 +71,7 @@
};
intc: intc@200 {
- compatible = "ralink,rt3883-intc", "ralink,rt2880-intc";
+ compatible = "ralink,rt2880-intc";
reg = <0x200 0x100>;
interrupt-controller;
@@ -93,7 +93,7 @@
compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0x500 0x100>;
- clocks = <&sysc 5>;
+ clocks = <&sysc 6>;
resets = <&sysc 12>;
@@ -106,7 +106,7 @@
};
gpio0: gpio@600 {
- compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x600 0x34>;
interrupt-parent = <&intc>;
@@ -116,21 +116,19 @@
#gpio-cells = <2>;
ngpios = <24>;
- ralink,gpio-base = <0>;
ralink,register-map = [ 00 04 08 0c
20 24 28 2c
30 34 ];
};
gpio1: gpio@638 {
- compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x638 0x24>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <16>;
- ralink,gpio-base = <24>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -139,14 +137,13 @@
};
gpio2: gpio@660 {
- compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x660 0x24>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
- ralink,gpio-base = <40>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -155,14 +152,13 @@
};
gpio3: gpio@688 {
- compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x688 0x24>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <24>;
- ralink,gpio-base = <72>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -174,7 +170,7 @@
compatible = "ralink,rt2880-i2c";
reg = <0x900 0x100>;
- clocks = <&sysc 6>;
+ clocks = <&sysc 7>;
resets = <&sysc 16>;
reset-names = "i2c";
@@ -192,7 +188,7 @@
compatible = "ralink,rt3883-i2s";
reg = <0xa00 0x100>;
- clocks = <&sysc 7>;
+ clocks = <&sysc 8>;
resets = <&sysc 17>;
reset-names = "i2s";
@@ -211,12 +207,12 @@
};
spi0: spi@b00 {
- compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb00 0x40>;
#address-cells = <1>;
#size-cells = <0>;
- clocks = <&sysc 8>;
+ clocks = <&sysc 9>;
resets = <&sysc 18>;
reset-names = "spi";
@@ -228,12 +224,12 @@
};
spi1: spi@b40 {
- compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb40 0x60>;
#address-cells = <1>;
#size-cells = <0>;
- clocks = <&sysc 9>;
+ clocks = <&sysc 10>;
resets = <&sysc 18>;
reset-names = "spi";
@@ -248,7 +244,7 @@
compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0xc00 0x100>;
- clocks = <&sysc 10>;
+ clocks = <&sysc 11>;
resets = <&sysc 19>;
@@ -330,7 +326,7 @@
#size-cells = <0>;
reg = <0x10100000 0x10000>;
- clocks = <&sysc 11>;
+ clocks = <&sysc 12>;
resets = <&sysc 21>;
reset-names = "fe";
@@ -339,7 +335,7 @@
interrupts = <5>;
port@0 {
- compatible = "ralink,rt3883-port", "mediatek,eth-port";
+ compatible = "mediatek,eth-port";
reg = <0>;
};
@@ -450,7 +446,7 @@
compatible = "ralink,rt3883-wmac", "ralink,rt2880-wmac";
reg = <0x10180000 0x40000>;
- clocks = <&sysc 12>;
+ clocks = <&sysc 13>;
interrupt-parent = <&cpuintc>;
interrupts = <6>;
diff --git a/target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts b/target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts
index 38667a5fda..5547ec0f48 100644
--- a/target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts
+++ b/target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include <dt-bindings/leds/common.h>
+#include "rt3883.dtsi"
-#include "rt3883_belkin_f9k110x.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
/ {
compatible = "belkin,f9k1109v1", "ralink,rt3883-soc";
@@ -71,18 +73,125 @@
linux,code = <KEY_WPS_BUTTON>;
};
};
+
+ rtl8367b {
+ compatible = "realtek,rtl8367b";
+ gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+ gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+ realtek,extif = <5 1 0 1 1 1 1 1 1 2>;
+ };
};
&ehci {
+ status = "okay";
+
ehci_port2: port@2 {
reg = <2>;
#trigger-source-cells = <0>;
};
};
+&ethernet {
+ port@0 {
+ mediatek,fixed-link = <1000 1 1 1>;
+ phy-mode = "rgmii";
+ };
+};
+
&ohci {
+ status = "okay";
+
ohci_port2: port@2 {
reg = <2>;
#trigger-source-cells = <0>;
};
};
+
+&pci {
+ status = "okay";
+};
+
+&pci1 {
+ status = "okay";
+
+ wifi@0,0 {
+ compatible = "pci1814,3091";
+ reg = <0x10000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_8000>;
+ nvmem-cell-names = "eeprom";
+ ralink,5ghz = <0>;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "uboot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x200>;
+ };
+
+ eeprom_factory_8000: eeprom@8000 {
+ reg = <0x8000 0x200>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x7a0000>;
+ };
+
+ partition@7f0000 {
+ label = "user-cfg";
+ reg = <0x7f0000 0x10000>;
+ read-only;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "i2c", "jtag", "uartf";
+ function = "gpio";
+ };
+};
+
+&wmac {
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ ralink,2ghz = <0>;
+};
diff --git a/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi b/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi
deleted file mode 100644
index a2d1906b89..0000000000
--- a/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi
+++ /dev/null
@@ -1,120 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "rt3883.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-
-/ {
- compatible = "ralink,rt3883-soc";
-
- rtl8367b {
- compatible = "realtek,rtl8367b";
- gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
- gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
- };
-};
-
-&spi0 {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <25000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "uboot";
- reg = <0x0 0x30000>;
- read-only;
- };
-
- partition@30000 {
- label = "uboot-env";
- reg = <0x30000 0x10000>;
- read-only;
- };
-
- partition@40000 {
- label = "factory";
- reg = <0x40000 0x10000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- eeprom_factory_0: eeprom@0 {
- reg = <0x0 0x200>;
- };
-
- eeprom_factory_8000: eeprom@8000 {
- reg = <0x8000 0x200>;
- };
- };
- };
-
- partition@50000 {
- compatible = "denx,uimage";
- label = "firmware";
- reg = <0x50000 0x7a0000>;
- };
-
- partition@7f0000 {
- label = "user-cfg";
- reg = <0x7f0000 0x10000>;
- read-only;
- };
- };
- };
-};
-
-&ethernet {
- port@0 {
- mediatek,fixed-link = <1000 1 1 1>;
- phy-mode = "rgmii";
- };
-};
-
-&state_default {
- gpio {
- groups = "i2c", "jtag", "uartf";
- function = "gpio";
- };
-};
-
-&wmac {
- nvmem-cells = <&eeprom_factory_0>;
- nvmem-cell-names = "eeprom";
-};
-
-&pci {
- status = "okay";
-};
-
-&pci1 {
- status = "okay";
-
- wifi@0,0 {
- compatible = "pci1814,3091";
- reg = <0x10000 0 0 0 0>;
- ralink,5ghz = <0>;
- nvmem-cells = <&eeprom_factory_8000>;
- nvmem-cell-names = "eeprom";
- };
-};
-
-&ehci {
- status = "okay";
-};
-
-&ohci {
- status = "okay";
-};
diff --git a/target/linux/ramips/dts/rt5350.dtsi b/target/linux/ramips/dts/rt5350.dtsi
index 30f6435842..cb6f3ff232 100644
--- a/target/linux/ramips/dts/rt5350.dtsi
+++ b/target/linux/ramips/dts/rt5350.dtsi
@@ -48,7 +48,7 @@
};
timer: timer@100 {
- compatible = "ralink,rt5350-timer", "ralink,rt2880-timer";
+ compatible = "ralink,rt2880-timer";
reg = <0x100 0x20>;
clocks = <&sysc 4>;
@@ -58,7 +58,7 @@
};
watchdog: watchdog@120 {
- compatible = "ralink,rt5350-wdt", "ralink,rt2880-wdt";
+ compatible = "ralink,rt2880-wdt";
reg = <0x120 0x10>;
clocks = <&sysc 5>;
@@ -71,7 +71,7 @@
};
intc: intc@200 {
- compatible = "ralink,rt5350-intc", "ralink,rt2880-intc";
+ compatible = "ralink,rt2880-intc";
reg = <0x200 0x100>;
interrupt-controller;
@@ -90,7 +90,7 @@
};
uart: uart@500 {
- compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
+ compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0x500 0x100>;
clocks = <&sysc 6>;
@@ -106,7 +106,7 @@
};
gpio0: gpio@600 {
- compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x600 0x34>;
interrupt-parent = <&intc>;
@@ -116,14 +116,13 @@
#gpio-cells = <2>;
ngpios = <22>;
- ralink,gpio-base = <0>;
ralink,register-map = [ 00 04 08 0c
20 24 28 2c
30 34 ];
};
gpio1: gpio@660 {
- compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+ compatible = "ralink,rt2880-gpio";
reg = <0x660 0x24>;
interrupt-parent = <&intc>;
@@ -133,7 +132,6 @@
#gpio-cells = <2>;
ngpios = <6>;
- ralink,gpio-base = <22>;
ralink,register-map = [ 00 04 08 0c
10 14 18 1c
20 24 ];
@@ -182,7 +180,7 @@
};
spi0: spi@b00 {
- compatible = "ralink,rt5350-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb00 0x40>;
clocks = <&sysc 9>;
@@ -200,7 +198,7 @@
};
spi1: spi@b40 {
- compatible = "ralink,rt5350-spi", "ralink,rt2880-spi";
+ compatible = "ralink,rt2880-spi";
reg = <0xb40 0x60>;
clocks = <&sysc 10>;
@@ -218,7 +216,7 @@
};
uartlite: uartlite@c00 {
- compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
+ compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0xc00 0x100>;
clocks = <&sysc 11>;
@@ -350,7 +348,7 @@
};
esw: esw@10110000 {
- compatible = "ralink,rt5350-esw", "ralink,rt3050-esw";
+ compatible = "ralink,rt3050-esw";
reg = <0x10110000 0x8000>;
resets = <&sysc 24>;
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts
index d37e4189a8..511d97a336 100644
--- a/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-4g-b", "ralink,rt5350-soc";
- model = "ZyXEL Keenetic 4G Rev.B";
+ model = "Zyxel Keenetic 4G Rev.B";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
index 7755b5dfef..433701397a 100644
--- a/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-lite-b", "ralink,rt5350-soc";
- model = "ZyXEL Keenetic Lite Rev.B";
+ model = "Zyxel Keenetic Lite Rev.B";
aliases {
led-boot = &led_power;
@@ -56,7 +56,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <60000000>;
+ spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
index 663b9a3d8c..459350fade 100644
--- a/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-start", "ralink,rt5350-soc";
- model = "ZyXEL Keenetic Start";
+ model = "Zyxel Keenetic Start";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c
index 756a1c5b57..3a9c69cb37 100644
--- a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c
@@ -2245,7 +2245,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
//TODO: read this as bus-width from dt (via mmc_of_parse)
mmc->caps |= MMC_CAP_4_BIT_DATA;
- cd_active_low = !of_property_read_bool(pdev->dev.of_node, "mediatek,cd-high");
+ cd_active_low = !of_property_read_bool(pdev->dev.of_node, "cd-inverted");
if (of_property_read_bool(pdev->dev.of_node, "mediatek,cd-poll"))
mmc->caps |= MMC_CAP_NEEDS_POLL;
diff --git a/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c b/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c
index 89cc7e2624..fba389e5a9 100644
--- a/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c
+++ b/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c
@@ -1248,7 +1248,6 @@ static int mt7621_nfc_init_chip(struct mt7621_nfc *nfc)
nand->ecc.write_oob_raw = mt7621_nfc_write_oob_raw;
mtd = nand_to_mtd(nand);
- mtd->owner = THIS_MODULE;
mtd->dev.parent = nfc->dev;
mtd->name = MT7621_NFC_NAME;
mtd_set_ooblayout(mtd, &mt7621_nfc_ooblayout_ops);
@@ -1290,44 +1289,28 @@ static int mt7621_nfc_probe(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi");
nfc->nfi_base = res->start;
nfc->nfi_regs = devm_ioremap_resource(dev, res);
- if (IS_ERR(nfc->nfi_regs)) {
- ret = PTR_ERR(nfc->nfi_regs);
- return ret;
- }
+ if (IS_ERR(nfc->nfi_regs))
+ return PTR_ERR(nfc->nfi_regs);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecc");
nfc->ecc_regs = devm_ioremap_resource(dev, res);
- if (IS_ERR(nfc->ecc_regs)) {
- ret = PTR_ERR(nfc->ecc_regs);
- return ret;
- }
+ if (IS_ERR(nfc->ecc_regs))
+ return PTR_ERR(nfc->ecc_regs);
- nfc->nfi_clk = devm_clk_get(dev, "nfi_clk");
- if (IS_ERR(nfc->nfi_clk)) {
+ nfc->nfi_clk = devm_clk_get_optional_enabled(dev, "nfi_clk");
+ if (IS_ERR(nfc->nfi_clk))
+ return PTR_ERR(nfc->nfi_clk);
+
+ if (!nfc->nfi_clk)
dev_warn(dev, "nfi clk not provided\n");
- nfc->nfi_clk = NULL;
- } else {
- ret = clk_prepare_enable(nfc->nfi_clk);
- if (ret) {
- dev_err(dev, "Failed to enable nfi core clock\n");
- return ret;
- }
- }
platform_set_drvdata(pdev, nfc);
ret = mt7621_nfc_init_chip(nfc);
- if (ret) {
- dev_err(dev, "Failed to initialize nand chip\n");
- goto clk_disable;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to initialize nand chip\n");
return 0;
-
-clk_disable:
- clk_disable_unprepare(nfc->nfi_clk);
-
- return ret;
}
static int mt7621_nfc_remove(struct platform_device *pdev)
@@ -1339,7 +1322,6 @@ static int mt7621_nfc_remove(struct platform_device *pdev)
mtk_bmt_detach(mtd);
mtd_device_unregister(mtd);
nand_cleanup(nand);
- clk_disable_unprepare(nfc->nfi_clk);
return 0;
}
@@ -1355,7 +1337,6 @@ static struct platform_driver mt7621_nfc_driver = {
.remove = mt7621_nfc_remove,
.driver = {
.name = MT7621_NFC_NAME,
- .owner = THIS_MODULE,
.of_match_table = mt7621_nfc_id_table,
},
};
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
index dcaff04db1..5853df70c5 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
@@ -245,7 +245,7 @@ int mtk_gsw_init(struct fe_priv *priv)
mt7620_ephy_init(gsw);
if (gsw->irq) {
- ret = request_irq(gsw->irq, gsw_interrupt_mt7620, 0,
+ ret = devm_request_irq(&pdev->dev, gsw->irq, gsw_interrupt_mt7620, 0,
"gsw", priv);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq");
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
index c8afa4e3bb..d8d27fda3b 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
@@ -1354,13 +1354,8 @@ static int __init fe_init(struct net_device *dev)
if (priv->soc->switch_init) {
err = priv->soc->switch_init(priv);
- if (err) {
- if (err == -EPROBE_DEFER)
- return err;
-
- netdev_err(dev, "failed to initialize switch core\n");
- return -ENODEV;
- }
+ if (err)
+ return dev_err_probe(&dev->dev, err, "failed to initialize switch core");
}
fe_reset_phy(priv);
@@ -1414,7 +1409,6 @@ static void fe_uninit(struct net_device *dev)
fe_mdio_cleanup(priv);
fe_reg_w32(0, FE_REG_FE_INT_ENABLE);
- free_irq(dev->irq, dev);
}
static int fe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1480,7 +1474,7 @@ static const struct net_device_ops fe_netdev_ops = {
.ndo_start_xmit = fe_start_xmit,
.ndo_set_mac_address = fe_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = fe_do_ioctl,
+ .ndo_eth_ioctl = fe_do_ioctl,
.ndo_change_mtu = fe_change_mtu,
.ndo_tx_timeout = fe_tx_timeout,
.ndo_get_stats64 = fe_get_stats64,
@@ -1528,7 +1522,6 @@ static void fe_pending_work(struct work_struct *work)
static int fe_probe(struct platform_device *pdev)
{
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
const struct of_device_id *match;
struct fe_soc_data *soc;
struct net_device *netdev;
@@ -1548,17 +1541,14 @@ static int fe_probe(struct platform_device *pdev)
else
soc->reg_table = fe_reg_table;
- fe_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(fe_base)) {
- err = -EADDRNOTAVAIL;
- goto err_out;
- }
+ fe_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(fe_base))
+ return PTR_ERR(fe_base);
- netdev = alloc_etherdev(sizeof(*priv));
+ netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv));
if (!netdev) {
dev_err(&pdev->dev, "alloc_etherdev failed\n");
- err = -ENOMEM;
- goto err_iounmap;
+ return -ENOMEM;
}
SET_NETDEV_DEV(netdev, &pdev->dev);
@@ -1568,16 +1558,15 @@ static int fe_probe(struct platform_device *pdev)
netdev->irq = platform_get_irq(pdev, 0);
if (netdev->irq < 0) {
dev_err(&pdev->dev, "no IRQ resource found\n");
- err = -ENXIO;
- goto err_free_dev;
+ return -ENXIO;
}
priv = netdev_priv(netdev);
spin_lock_init(&priv->page_lock);
- priv->resets = devm_reset_control_array_get_exclusive(&pdev->dev);
+ priv->resets = devm_reset_control_array_get_optional_exclusive(&pdev->dev);
if (IS_ERR(priv->resets)) {
dev_err(&pdev->dev, "Failed to get resets for FE and ESW cores: %pe\n", priv->resets);
- priv->resets = NULL;
+ return PTR_ERR(priv->resets);
}
if (soc->init_data)
@@ -1595,11 +1584,9 @@ static int fe_probe(struct platform_device *pdev)
netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
if (fe_reg_table[FE_REG_FE_COUNTER_BASE]) {
- priv->hw_stats = kzalloc(sizeof(*priv->hw_stats), GFP_KERNEL);
- if (!priv->hw_stats) {
- err = -ENOMEM;
- goto err_free_dev;
- }
+ priv->hw_stats = devm_kzalloc(&pdev->dev, sizeof(*priv->hw_stats), GFP_KERNEL);
+ if (!priv->hw_stats)
+ return -ENOMEM;
spin_lock_init(&priv->hw_stats->stats_lock);
u64_stats_init(&priv->hw_stats->syncp);
}
@@ -1609,15 +1596,13 @@ static int fe_probe(struct platform_device *pdev)
priv->sysclk = clk_get_rate(sysclk);
} else if ((priv->flags & FE_FLAG_CALIBRATE_CLK)) {
dev_err(&pdev->dev, "this soc needs a clk for calibration\n");
- err = -ENXIO;
- goto err_free_dev;
+ return -ENXIO;
}
priv->switch_np = of_parse_phandle(pdev->dev.of_node, "mediatek,switch", 0);
if ((priv->flags & FE_FLAG_HAS_SWITCH) && !priv->switch_np) {
dev_err(&pdev->dev, "failed to read switch phandle\n");
- err = -ENODEV;
- goto err_free_dev;
+ return -ENODEV;
}
priv->netdev = netdev;
@@ -1639,10 +1624,10 @@ static int fe_probe(struct platform_device *pdev)
netif_napi_add_weight(netdev, &priv->rx_napi, fe_poll, napi_weight);
fe_set_ethtool_ops(netdev);
- err = register_netdev(netdev);
+ err = devm_register_netdev(&pdev->dev, netdev);
if (err) {
dev_err(&pdev->dev, "error bringing up device\n");
- goto err_free_dev;
+ return err;
}
platform_set_drvdata(pdev, netdev);
@@ -1651,13 +1636,6 @@ static int fe_probe(struct platform_device *pdev)
netdev->base_addr, netdev->irq);
return 0;
-
-err_free_dev:
- free_netdev(netdev);
-err_iounmap:
- devm_iounmap(&pdev->dev, fe_base);
-err_out:
- return err;
}
static int fe_remove(struct platform_device *pdev)
@@ -1666,12 +1644,9 @@ static int fe_remove(struct platform_device *pdev)
struct fe_priv *priv = netdev_priv(dev);
netif_napi_del(&priv->rx_napi);
- kfree(priv->hw_stats);
cancel_work_sync(&priv->pending_work);
- unregister_netdev(dev);
- free_netdev(dev);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c b/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c
deleted file mode 100644
index 8b642e28b1..0000000000
--- a/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c
+++ /dev/null
@@ -1,1128 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Awinic AW9523B i2c pin controller driver
- * Copyright (c) 2020, AngeloGioacchino Del Regno
- * <angelogioacchino.delregno@somainline.org>
- */
-
-#include <linux/bitfield.h>
-#include <linux/regmap.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio/driver.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf-generic.h>
-#include <linux/regulator/consumer.h>
-
-#include "core.h"
-#include "pinconf.h"
-#include "pinctrl-utils.h"
-
-#define AW9523_MAX_FUNCS 2
-#define AW9523_NUM_PORTS 2
-#define AW9523_PINS_PER_PORT 8
-
-/*
- * HW needs at least 20uS for reset and at least 1-2uS to recover from
- * reset, but we have to account for eventual board quirks, if any:
- * for this reason, keep reset asserted for 50uS and wait for 20uS
- * to recover from the reset.
- */
-#define AW9523_HW_RESET_US 50
-#define AW9523_HW_RESET_RECOVERY_US 20
-
-/* Port 0: P0_0...P0_7 - Port 1: P1_0...P1_7 */
-#define AW9523_PIN_TO_PORT(pin) (pin >> 3)
-#define AW9523_REG_IN_STATE(pin) (0x00 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_OUT_STATE(pin) (0x02 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_CONF_STATE(pin) (0x04 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_INTR_DIS(pin) (0x06 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_CHIPID 0x10
-#define AW9523_VAL_EXPECTED_CHIPID 0x23
-
-#define AW9523_REG_GCR 0x11
-#define AW9523_GCR_ISEL_MASK GENMASK(0, 1)
-#define AW9523_GCR_GPOMD_MASK BIT(4)
-
-#define AW9523_REG_PORT_MODE(pin) (0x12 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_SOFT_RESET 0x7f
-#define AW9523_VAL_RESET 0x00
-
-/*
- * struct aw9523_irq - Interrupt controller structure
- * @lock: mutex locking for the irq bus
- * @irqchip: structure holding irqchip params
- * @cached_gpio: stores the previous gpio status for bit comparison
- */
-struct aw9523_irq {
- struct mutex lock;
- struct irq_chip *irqchip;
- u16 cached_gpio;
-};
-
-/*
- * struct aw9523_pinmux - Pin mux params
- * @name: Name of the mux
- * @grps: Groups of the mux
- * @num_grps: Number of groups (sizeof array grps)
- */
-struct aw9523_pinmux {
- const char *name;
- const char * const *grps;
- const u8 num_grps;
-};
-
-/*
- * struct aw9523 - Main driver structure
- * @dev: device handle
- * @regmap: regmap handle for current device
- * @i2c_lock: Mutex lock for i2c operations
- * @reset_gpio: Hardware reset (RSTN) signal GPIO
- * @vio_vreg: VCC regulator (Optional)
- * @pctl: pinctrl handle for current device
- * @gpio: structure holding gpiochip params
- * @irq: Interrupt controller structure
- */
-struct aw9523 {
- struct device *dev;
- struct regmap *regmap;
- struct mutex i2c_lock;
- struct gpio_desc *reset_gpio;
- struct regulator *vio_vreg;
- struct pinctrl_dev *pctl;
- struct gpio_chip gpio;
- struct aw9523_irq *irq;
-};
-
-static const struct pinctrl_pin_desc aw9523_pins[] = {
- /* Port 0 */
- PINCTRL_PIN(0, "gpio0"),
- PINCTRL_PIN(1, "gpio1"),
- PINCTRL_PIN(2, "gpio2"),
- PINCTRL_PIN(3, "gpio3"),
- PINCTRL_PIN(4, "gpio4"),
- PINCTRL_PIN(5, "gpio5"),
- PINCTRL_PIN(6, "gpio6"),
- PINCTRL_PIN(7, "gpio7"),
-
- /* Port 1 */
- PINCTRL_PIN(8, "gpio8"),
- PINCTRL_PIN(9, "gpio9"),
- PINCTRL_PIN(10, "gpio10"),
- PINCTRL_PIN(11, "gpio11"),
- PINCTRL_PIN(12, "gpio12"),
- PINCTRL_PIN(13, "gpio13"),
- PINCTRL_PIN(14, "gpio14"),
- PINCTRL_PIN(15, "gpio15"),
-};
-
-static int aw9523_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
-{
- return ARRAY_SIZE(aw9523_pins);
-}
-
-static const char *aw9523_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
- unsigned int selector)
-{
- return aw9523_pins[selector].name;
-}
-
-static int aw9523_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
- unsigned int selector,
- const unsigned int **pins,
- unsigned int *num_pins)
-{
- *pins = &aw9523_pins[selector].number;
- *num_pins = 1;
- return 0;
-}
-
-static const struct pinctrl_ops aw9523_pinctrl_ops = {
- .get_groups_count = aw9523_pinctrl_get_groups_count,
- .get_group_pins = aw9523_pinctrl_get_group_pins,
- .get_group_name = aw9523_pinctrl_get_group_name,
- .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
- .dt_free_map = pinconf_generic_dt_free_map,
-};
-
-static const char * const gpio_pwm_groups[] = {
- "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
- "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
- "gpio12", "gpio13", "gpio14", "gpio15"
-};
-
-/* Warning: Do NOT reorder this array */
-static const struct aw9523_pinmux aw9523_pmx[] = {
- {
- .name = "pwm",
- .grps = gpio_pwm_groups,
- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
- },
- {
- .name = "gpio",
- .grps = gpio_pwm_groups,
- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
- },
-};
-
-static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
-{
- return ARRAY_SIZE(aw9523_pmx);
-}
-
-static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl,
- unsigned int sel)
-{
- return aw9523_pmx[sel].name;
-}
-
-static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
- const char * const **groups,
- unsigned int * const num_groups)
-{
- *groups = aw9523_pmx[sel].grps;
- *num_groups = aw9523_pmx[sel].num_grps;
- return 0;
-}
-
-static int aw9523_pmx_set_mux(struct pinctrl_dev *pctl, unsigned int fsel,
- unsigned int grp)
-{
- struct aw9523 *awi = pinctrl_dev_get_drvdata(pctl);
- int ret, pin = aw9523_pins[grp].number % AW9523_PINS_PER_PORT;
-
- if (fsel >= ARRAY_SIZE(aw9523_pmx))
- return -EINVAL;
-
- /*
- * This maps directly to the aw9523_pmx array: programming a
- * high bit means "gpio" and a low bit means "pwm".
- */
- mutex_lock(&awi->i2c_lock);
- ret = regmap_update_bits(awi->regmap, AW9523_REG_PORT_MODE(pin),
- BIT(pin), (fsel ? BIT(pin) : 0));
- mutex_unlock(&awi->i2c_lock);
- return ret;
-}
-
-static const struct pinmux_ops aw9523_pinmux_ops = {
- .get_functions_count = aw9523_pmx_get_funcs_count,
- .get_function_name = aw9523_pmx_get_fname,
- .get_function_groups = aw9523_pmx_get_groups,
- .set_mux = aw9523_pmx_set_mux,
-};
-
-static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r)
-{
- u8 reg;
-
- switch (pcp) {
- case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_BIAS_PULL_UP:
- reg = AW9523_REG_IN_STATE(pin);
- break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN:
- case PIN_CONFIG_DRIVE_PUSH_PULL:
- reg = AW9523_REG_GCR;
- break;
- case PIN_CONFIG_INPUT_ENABLE:
- case PIN_CONFIG_OUTPUT_ENABLE:
- reg = AW9523_REG_CONF_STATE(pin);
- break;
- case PIN_CONFIG_OUTPUT:
- reg = AW9523_REG_OUT_STATE(pin);
- break;
- default:
- return -ENOTSUPP;
- }
- *r = reg;
-
- return 0;
-}
-
-static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
- unsigned long *config)
-{
- struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
- enum pin_config_param param = pinconf_to_config_param(*config);
- int regbit = pin % AW9523_PINS_PER_PORT;
- unsigned int val;
- u8 reg;
- int rc;
-
- rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
- if (rc)
- return rc;
-
- mutex_lock(&awi->i2c_lock);
- rc = regmap_read(awi->regmap, reg, &val);
- mutex_unlock(&awi->i2c_lock);
- if (rc)
- return rc;
-
- switch (param) {
- case PIN_CONFIG_BIAS_PULL_UP:
- case PIN_CONFIG_INPUT_ENABLE:
- case PIN_CONFIG_OUTPUT:
- val &= BIT(regbit);
- break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_OUTPUT_ENABLE:
- val &= BIT(regbit);
- val = !val;
- break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN:
- if (pin >= AW9523_PINS_PER_PORT)
- val = 0;
- else
- val = !FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
- break;
- case PIN_CONFIG_DRIVE_PUSH_PULL:
- if (pin >= AW9523_PINS_PER_PORT)
- val = 1;
- else
- val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
- break;
- default:
- return -ENOTSUPP;
- }
- if (val < 1)
- return -EINVAL;
-
- *config = pinconf_to_config_packed(param, !!val);
-
- return rc;
-}
-
-static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
- unsigned long *configs, unsigned int num_configs)
-{
- struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
- enum pin_config_param param;
- int regbit = pin % AW9523_PINS_PER_PORT;
- u32 arg;
- u8 reg;
- unsigned int mask, val;
- int i, rc;
-
- mutex_lock(&awi->i2c_lock);
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
- if (rc)
- goto end;
-
- switch (param) {
- case PIN_CONFIG_OUTPUT:
- /* First, enable pin output */
- rc = regmap_update_bits(awi->regmap,
- AW9523_REG_CONF_STATE(pin),
- BIT(regbit), 0);
- if (rc)
- goto end;
-
- /* Then, fall through to config output level */
- fallthrough;
- case PIN_CONFIG_OUTPUT_ENABLE:
- arg = !arg;
- fallthrough;
- case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_BIAS_PULL_UP:
- case PIN_CONFIG_INPUT_ENABLE:
- mask = BIT(regbit);
- val = arg ? BIT(regbit) : 0;
- break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN:
- /* Open-Drain is supported only on port 0 */
- if (pin >= AW9523_PINS_PER_PORT) {
- rc = -ENOTSUPP;
- goto end;
- }
- mask = AW9523_GCR_GPOMD_MASK;
- val = 0;
- break;
- case PIN_CONFIG_DRIVE_PUSH_PULL:
- /* Port 1 is always Push-Pull */
- if (pin >= AW9523_PINS_PER_PORT) {
- mask = 0;
- val = 0;
- continue;
- }
- mask = AW9523_GCR_GPOMD_MASK;
- val = AW9523_GCR_GPOMD_MASK;
- break;
- default:
- rc = -ENOTSUPP;
- goto end;
- }
-
- rc = regmap_update_bits(awi->regmap, reg, mask, val);
- if (rc)
- goto end;
- }
-end:
- mutex_unlock(&awi->i2c_lock);
- return rc;
-}
-
-static const struct pinconf_ops aw9523_pinconf_ops = {
- .pin_config_get = aw9523_pconf_get,
- .pin_config_set = aw9523_pconf_set,
- .is_generic = true,
-};
-
-/*
- * aw9523_get_pin_direction - Get pin direction
- * @regmap: Regmap structure
- * @pin: gpiolib pin number
- * @n: pin index in port register
- *
- * Return: Pin direction for success or negative number for error
- */
-static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n)
-{
- int val, ret;
-
- ret = regmap_read(regmap, AW9523_REG_CONF_STATE(pin), &val);
- if (ret < 0)
- return ret;
-
- return (val & BIT(n)) == BIT(n);
-}
-
-/*
- * aw9523_get_port_state - Get input or output state for entire port
- * @regmap: Regmap structure
- * @pin: gpiolib pin number
- * @regbit: hw pin index, used to retrieve port number
- * @state: returned port state
- *
- * Return: Zero for success or negative number for error
- */
-static int aw9523_get_port_state(struct regmap *regmap, u8 pin,
- u8 regbit, unsigned int *state)
-{
- u8 reg;
- int dir;
-
- dir = aw9523_get_pin_direction(regmap, pin, regbit);
- if (dir < 0)
- return dir;
-
- if (dir == GPIO_LINE_DIRECTION_IN)
- reg = AW9523_REG_IN_STATE(pin);
- else
- reg = AW9523_REG_OUT_STATE(pin);
-
- return regmap_read(regmap, reg, state);
-}
-
-static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type)
-{
- switch (type) {
- case IRQ_TYPE_NONE:
- case IRQ_TYPE_EDGE_BOTH:
- return 0;
- default:
- return -EINVAL;
- };
-}
-
-/*
- * aw9523_irq_mask - Mask interrupt
- * @d: irq data
- *
- * Sets which interrupt to mask in the bitmap;
- * The interrupt will be masked when unlocking the irq bus.
- */
-static void aw9523_irq_mask(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
-
- regmap_update_bits(awi->regmap,
- AW9523_REG_INTR_DIS(d->hwirq),
- BIT(n), BIT(n));
-}
-
-/*
- * aw9523_irq_unmask - Unmask interrupt
- * @d: irq data
- *
- * Sets which interrupt to unmask in the bitmap;
- * The interrupt will be masked when unlocking the irq bus.
- */
-static void aw9523_irq_unmask(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
-
- regmap_update_bits(awi->regmap,
- AW9523_REG_INTR_DIS(d->hwirq),
- BIT(n), 0);
-}
-
-static irqreturn_t aw9523_irq_thread_func(int irq, void *dev_id)
-{
- struct aw9523 *awi = (struct aw9523 *)dev_id;
- unsigned long n, val = 0;
- unsigned long changed_gpio;
- unsigned int tmp, port_pin, i, ret;
-
- for (i = 0; i < AW9523_NUM_PORTS; i++) {
- port_pin = i * AW9523_PINS_PER_PORT;
- ret = regmap_read(awi->regmap,
- AW9523_REG_IN_STATE(port_pin),
- &tmp);
- if (ret)
- return ret;
- val |= (u8)tmp << (i * 8);
- }
-
- /* Handle GPIO input release interrupt as well */
- changed_gpio = awi->irq->cached_gpio ^ val;
- awi->irq->cached_gpio = val;
-
- /*
- * To avoid up to four *slow* i2c reads from any driver hooked
- * up to our interrupts, just check for the irq_find_mapping
- * result: if the interrupt is not mapped, then we don't want
- * to care about it.
- */
- for_each_set_bit(n, &changed_gpio, awi->gpio.ngpio) {
- tmp = irq_find_mapping(awi->gpio.irq.domain, n);
- if (tmp <= 0)
- continue;
- handle_nested_irq(tmp);
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * aw9523_irq_bus_lock - Grab lock for interrupt operation
- * @d: irq data
- */
-static void aw9523_irq_bus_lock(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
-
- mutex_lock(&awi->irq->lock);
- regcache_cache_only(awi->regmap, true);
-}
-
-/*
- * aw9523_irq_bus_sync_unlock - Synchronize state and unlock
- * @d: irq data
- *
- * Writes the interrupt mask bits (found in the bit map) to the
- * hardware, then unlocks the bus.
- */
-static void aw9523_irq_bus_sync_unlock(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
-
- regcache_cache_only(awi->regmap, false);
- regcache_sync(awi->regmap);
- mutex_unlock(&awi->irq->lock);
-}
-
-static int aw9523_gpio_get_direction(struct gpio_chip *chip,
- unsigned int offset)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = aw9523_get_pin_direction(awi->regmap, offset, regbit);
- mutex_unlock(&awi->i2c_lock);
-
- return ret;
-}
-
-static int aw9523_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- unsigned int val;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = aw9523_get_port_state(awi->regmap, offset, regbit, &val);
- mutex_unlock(&awi->i2c_lock);
- if (ret)
- return ret;
-
- return !!(val & BIT(regbit));
-}
-
-/**
- * _aw9523_gpio_get_multiple - Get I/O state for an entire port
- * @regmap: Regmap structure
- * @pin: gpiolib pin number
- * @regbit: hw pin index, used to retrieve port number
- * @state: returned port I/O state
- *
- * Return: Zero for success or negative number for error
- */
-static int _aw9523_gpio_get_multiple(struct aw9523 *awi, u8 regbit,
- u8 *state, u8 mask)
-{
- u32 dir_in, val;
- u8 m;
- int ret;
-
- /* Registers are 8-bits wide */
- ret = regmap_read(awi->regmap, AW9523_REG_CONF_STATE(regbit), &dir_in);
- if (ret)
- return ret;
- *state = 0;
-
- m = mask & dir_in;
- if (m) {
- ret = regmap_read(awi->regmap, AW9523_REG_IN_STATE(regbit),
- &val);
- if (ret)
- return ret;
- *state |= (u8)val & m;
- }
-
- m = mask & ~dir_in;
- if (m) {
- ret = regmap_read(awi->regmap, AW9523_REG_OUT_STATE(regbit),
- &val);
- if (ret)
- return ret;
- *state |= (u8)val & m;
- }
-
- return 0;
-}
-
-static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
- unsigned long *mask,
- unsigned long *bits)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 m, state = 0;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
-
- /* Port 0 (gpio 0-7) */
- m = *mask & U8_MAX;
- if (m) {
- ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
- if (ret)
- goto out;
- }
- *bits = state;
-
- /* Port 1 (gpio 8-15) */
- m = (*mask >> 8) & U8_MAX;
- if (m) {
- ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
- &state, m);
- if (ret)
- goto out;
-
- *bits |= (state << 8);
- }
-out:
- mutex_unlock(&awi->i2c_lock);
- return ret;
-}
-
-static void aw9523_gpio_set_multiple(struct gpio_chip *chip,
- unsigned long *mask,
- unsigned long *bits)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 mask_lo, mask_hi, bits_lo, bits_hi;
- unsigned int reg;
- int ret = 0;
-
- mask_lo = *mask & U8_MAX;
- mask_hi = (*mask >> 8) & U8_MAX;
- mutex_lock(&awi->i2c_lock);
- if (mask_hi) {
- reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
- bits_hi = (*bits >> 8) & U8_MAX;
-
- ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
- if (ret) {
- dev_warn(awi->dev, "Cannot write port1 out level\n");
- goto out;
- }
- }
- if (mask_lo) {
- reg = AW9523_REG_OUT_STATE(0);
- bits_lo = *bits & U8_MAX;
- ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
- if (ret)
- dev_warn(awi->dev, "Cannot write port0 out level\n");
- }
-out:
- mutex_unlock(&awi->i2c_lock);
-}
-
-static void aw9523_gpio_set(struct gpio_chip *chip,
- unsigned int offset, int value)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
-
- mutex_lock(&awi->i2c_lock);
- regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
- BIT(regbit), value ? BIT(regbit) : 0);
- mutex_unlock(&awi->i2c_lock);
-}
-
-
-static int aw9523_direction_input(struct gpio_chip *chip, unsigned int offset)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
- BIT(regbit), BIT(regbit));
- mutex_unlock(&awi->i2c_lock);
-
- return ret;
-}
-
-static int aw9523_direction_output(struct gpio_chip *chip,
- unsigned int offset, int value)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
- BIT(regbit), value ? BIT(regbit) : 0);
- if (ret)
- goto end;
-
- ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
- BIT(regbit), 0);
-end:
- mutex_unlock(&awi->i2c_lock);
- return ret;
-}
-
-static int aw9523_drive_reset_gpio(struct aw9523 *awi)
-{
- unsigned int chip_id;
- int ret;
-
- /*
- * If the chip is already configured for any reason, then we
- * will probably succeed in sending the soft reset signal to
- * the hardware through I2C: this operation takes less time
- * compared to a full HW reset and it gives the same results.
- */
- ret = regmap_write(awi->regmap, AW9523_REG_SOFT_RESET, 0);
- if (ret == 0)
- goto done;
-
- dev_dbg(awi->dev, "Cannot execute soft reset: trying hard reset\n");
- ret = gpiod_direction_output(awi->reset_gpio, 0);
- if (ret)
- return ret;
-
- /* The reset pulse has to be longer than 20uS due to deglitch */
- usleep_range(AW9523_HW_RESET_US, AW9523_HW_RESET_US + 1);
-
- ret = gpiod_direction_output(awi->reset_gpio, 1);
- if (ret)
- return ret;
-done:
- /* The HW needs at least 1uS to reliably recover after reset */
- usleep_range(AW9523_HW_RESET_RECOVERY_US,
- AW9523_HW_RESET_RECOVERY_US + 1);
-
- /* Check the ChipID */
- ret = regmap_read(awi->regmap, AW9523_REG_CHIPID, &chip_id);
- if (ret) {
- dev_err(awi->dev, "Cannot read Chip ID: %d\n", ret);
- return ret;
- }
- if (chip_id != AW9523_VAL_EXPECTED_CHIPID) {
- dev_err(awi->dev, "Bad ChipID; read 0x%x, expected 0x%x\n",
- chip_id, AW9523_VAL_EXPECTED_CHIPID);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int aw9523_hw_reset(struct aw9523 *awi)
-{
- int ret, max_retries = 2;
-
- /* Sometimes the chip needs more than one reset cycle */
- do {
- ret = aw9523_drive_reset_gpio(awi);
- if (ret == 0)
- break;
- max_retries--;
- } while (max_retries);
-
- return ret;
-}
-
-static int aw9523_init_gpiochip(struct aw9523 *awi, unsigned int npins)
-{
- struct device *dev = awi->dev;
- struct gpio_chip *gpiochip = &awi->gpio;
-
- gpiochip->label = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
- if (!gpiochip->label)
- return -ENOMEM;
-
- gpiochip->base = -1;
- gpiochip->ngpio = npins;
- gpiochip->get_direction = aw9523_gpio_get_direction;
- gpiochip->direction_input = aw9523_direction_input;
- gpiochip->direction_output = aw9523_direction_output;
- gpiochip->get = aw9523_gpio_get;
- gpiochip->get_multiple = aw9523_gpio_get_multiple;
- gpiochip->set = aw9523_gpio_set;
- gpiochip->set_multiple = aw9523_gpio_set_multiple;
- gpiochip->set_config = gpiochip_generic_config;
- gpiochip->parent = dev;
- gpiochip->fwnode = dev->fwnode;
- gpiochip->owner = THIS_MODULE;
- gpiochip->can_sleep = true;
-
- return 0;
-}
-
-static int aw9523_init_irq(struct aw9523 *awi, int irq)
-{
- struct device *dev = awi->dev;
- struct gpio_irq_chip *gpioirq;
- struct irq_chip *irqchip;
- int ret;
-
- if (!device_property_read_bool(dev, "interrupt-controller"))
- return 0;
-
- irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
- if (!irqchip)
- return -ENOMEM;
-
- awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
- if (!awi->irq)
- return -ENOMEM;
-
- irqchip->name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
- if (!irqchip->name)
- return -ENOMEM;
-
- irqchip->irq_mask = aw9523_irq_mask;
- irqchip->irq_unmask = aw9523_irq_unmask;
- irqchip->irq_bus_lock = aw9523_irq_bus_lock;
- irqchip->irq_bus_sync_unlock = aw9523_irq_bus_sync_unlock;
- irqchip->irq_set_type = aw9523_gpio_irq_type;
- awi->irq->irqchip = irqchip;
- mutex_init(&awi->irq->lock);
-
- ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
- IRQF_ONESHOT, dev_name(dev), awi);
- if (ret) {
- dev_err(dev, "Failed to request irq %d\n", irq);
- return ret;
- }
-
- gpioirq = &awi->gpio.irq;
- gpioirq->chip = irqchip;
- gpioirq->parent_handler = NULL;
- gpioirq->num_parents = 0;
- gpioirq->parents = NULL;
- gpioirq->default_type = IRQ_TYPE_LEVEL_MASK;
- gpioirq->handler = handle_simple_irq;
- gpioirq->threaded = true;
- gpioirq->first = 0;
-
- return 0;
-}
-
-static bool aw9523_is_reg_hole(unsigned int reg)
-{
- return (reg > AW9523_REG_PORT_MODE(AW9523_PINS_PER_PORT) &&
- reg < AW9523_REG_SOFT_RESET) ||
- (reg > AW9523_REG_INTR_DIS(AW9523_PINS_PER_PORT) &&
- reg < AW9523_REG_CHIPID);
-}
-
-static bool aw9523_readable_reg(struct device *dev, unsigned int reg)
-{
- /* All available registers (minus holes) can be read */
- return !aw9523_is_reg_hole(reg);
-}
-
-static bool aw9523_volatile_reg(struct device *dev, unsigned int reg)
-{
- return aw9523_is_reg_hole(reg) ||
- reg == AW9523_REG_IN_STATE(0) ||
- reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT) ||
- reg == AW9523_REG_CHIPID ||
- reg == AW9523_REG_SOFT_RESET;
-}
-
-static bool aw9523_writeable_reg(struct device *dev, unsigned int reg)
-{
- return !aw9523_is_reg_hole(reg) && reg != AW9523_REG_CHIPID;
-}
-
-static bool aw9523_precious_reg(struct device *dev, unsigned int reg)
-{
- /* Reading AW9523_REG_IN_STATE clears interrupt status */
- return aw9523_is_reg_hole(reg) ||
- reg == AW9523_REG_IN_STATE(0) ||
- reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT);
-}
-
-static const struct regmap_config aw9523_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
- .reg_stride = 1,
-
- .precious_reg = aw9523_precious_reg,
- .readable_reg = aw9523_readable_reg,
- .volatile_reg = aw9523_volatile_reg,
- .writeable_reg = aw9523_writeable_reg,
-
- .cache_type = REGCACHE_FLAT,
- .disable_locking = true,
-
- .num_reg_defaults_raw = AW9523_REG_SOFT_RESET,
-};
-
-static int aw9523_hw_init(struct aw9523 *awi)
-{
- u8 p1_pin = AW9523_PINS_PER_PORT;
- unsigned int val;
- int ret;
-
- /* No register caching during initialization */
- regcache_cache_bypass(awi->regmap, true);
-
- /* Bring up the chip */
- ret = aw9523_hw_reset(awi);
- if (ret) {
- dev_err(awi->dev, "HW Reset failed: %d\n", ret);
- return ret;
- }
-
- /*
- * This is the expected chip and it is running: it's time to
- * set a safe default configuration in case the user doesn't
- * configure (all of the available) pins in this chip.
- * P.S.: The writes order doesn't matter.
- */
-
- /* Set all pins as GPIO */
- ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(0), U8_MAX);
- if (ret)
- return ret;
- ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(p1_pin), U8_MAX);
- if (ret)
- return ret;
-
- /* Set Open-Drain mode on Port 0 (Port 1 is always P-P) */
- ret = regmap_write(awi->regmap, AW9523_REG_GCR, 0);
- if (ret)
- return ret;
-
- /* Set all pins as inputs */
- ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(0), U8_MAX);
- if (ret)
- return ret;
- ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(p1_pin), U8_MAX);
- if (ret)
- return ret;
-
- /* Disable all interrupts to avoid unreasoned wakeups */
- ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(0), U8_MAX);
- if (ret)
- return ret;
- ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(p1_pin), U8_MAX);
- if (ret)
- return ret;
-
- /* Clear setup-generated interrupts by performing a port state read */
- ret = aw9523_get_port_state(awi->regmap, 0, 0, &val);
- if (ret)
- return ret;
- ret = aw9523_get_port_state(awi->regmap, p1_pin, 0, &val);
- if (ret)
- return ret;
-
- /* Everything went fine: activate and reinitialize register cache */
- regcache_cache_bypass(awi->regmap, false);
- return regmap_reinit_cache(awi->regmap, &aw9523_regmap);
-}
-
-static int aw9523_probe(struct i2c_client *client)
-{
- struct device *dev = &client->dev;
- struct pinctrl_desc *pdesc;
- struct aw9523 *awi;
- int ret;
-
- awi = devm_kzalloc(dev, sizeof(*awi), GFP_KERNEL);
- if (!awi)
- return -ENOMEM;
-
- i2c_set_clientdata(client, awi);
-
- awi->dev = dev;
- awi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
- if (IS_ERR(awi->reset_gpio))
- return PTR_ERR(awi->reset_gpio);
- gpiod_set_consumer_name(awi->reset_gpio, "aw9523 reset");
-
- awi->regmap = devm_regmap_init_i2c(client, &aw9523_regmap);
- if (IS_ERR(awi->regmap))
- return PTR_ERR(awi->regmap);
-
- awi->vio_vreg = devm_regulator_get_optional(dev, "vio");
- if (IS_ERR(awi->vio_vreg)) {
- if (PTR_ERR(awi->vio_vreg) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- awi->vio_vreg = NULL;
- } else {
- ret = regulator_enable(awi->vio_vreg);
- if (ret)
- return ret;
- }
-
- mutex_init(&awi->i2c_lock);
- lockdep_set_subclass(&awi->i2c_lock,
- i2c_adapter_depth(client->adapter));
-
- pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
- if (!pdesc)
- return -ENOMEM;
-
- ret = aw9523_hw_init(awi);
- if (ret)
- goto err_disable_vregs;
-
- pdesc->name = dev_name(dev);
- pdesc->owner = THIS_MODULE;
- pdesc->pctlops = &aw9523_pinctrl_ops;
- pdesc->pmxops = &aw9523_pinmux_ops;
- pdesc->confops = &aw9523_pinconf_ops;
- pdesc->pins = aw9523_pins;
- pdesc->npins = ARRAY_SIZE(aw9523_pins);
-
- ret = aw9523_init_gpiochip(awi, pdesc->npins);
- if (ret)
- goto err_disable_vregs;
-
- if (client->irq) {
- ret = aw9523_init_irq(awi, client->irq);
- if (ret)
- goto err_disable_vregs;
- }
-
- awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
- if (IS_ERR(awi->pctl)) {
- ret = PTR_ERR(awi->pctl);
- dev_err(dev, "Cannot register pinctrl: %d", ret);
- goto err_disable_vregs;
- }
-
- ret = devm_gpiochip_add_data(dev, &awi->gpio, awi);
- if (ret)
- goto err_disable_vregs;
-
- return ret;
-
-err_disable_vregs:
- if (awi->vio_vreg)
- regulator_disable(awi->vio_vreg);
- mutex_destroy(&awi->i2c_lock);
- return ret;
-}
-
-static int aw9523_remove(struct i2c_client *client)
-{
- struct aw9523 *awi = i2c_get_clientdata(client);
- int ret;
-
- if (!awi)
- return 0;
-
- /*
- * If the chip VIO is connected to a regulator that we can turn
- * off, life is easy... otherwise, reinitialize the chip and
- * set the pins to hardware defaults before removing the driver
- * to leave it in a clean, safe and predictable state.
- */
- if (awi->vio_vreg) {
- regulator_disable(awi->vio_vreg);
- } else {
- mutex_lock(&awi->i2c_lock);
- ret = aw9523_hw_init(awi);
- mutex_unlock(&awi->i2c_lock);
- if (ret)
- return ret;
- }
-
- mutex_destroy(&awi->i2c_lock);
- return 0;
-}
-
-static void aw9523_remove_void(struct i2c_client *client)
-{
- aw9523_remove(client);
-}
-
-static const struct i2c_device_id aw9523_i2c_id_table[] = {
- { "aw9523_i2c", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, aw9523_i2c_id_table);
-
-static const struct of_device_id of_aw9523_i2c_match[] = {
- { .compatible = "awinic,aw9523-pinctrl", },
-};
-MODULE_DEVICE_TABLE(of, of_aw9523_i2c_match);
-
-static struct i2c_driver aw9523_driver = {
- .driver = {
- .name = "aw9523-pinctrl",
- .of_match_table = of_aw9523_i2c_match,
- },
- .probe = aw9523_probe,
- .remove = aw9523_remove_void,
- .id_table = aw9523_i2c_id_table,
-};
-module_i2c_driver(aw9523_driver);
-
-MODULE_DESCRIPTION("Awinic AW9523 I2C GPIO Expander driver");
-MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:aw9523");
diff --git a/target/linux/ramips/image/mt7620.mk b/target/linux/ramips/image/mt7620.mk
index cb41e9bb5a..9f3a8dce0e 100644
--- a/target/linux/ramips/image/mt7620.mk
+++ b/target/linux/ramips/image/mt7620.mk
@@ -145,7 +145,7 @@ define Device/bdcom_wap2100-sk
DEVICE_VENDOR := BDCOM
DEVICE_MODEL := WAP2100-SK (ZTE ZXECS EBG3130)
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mt76x2 kmod-mt76x0e \
- kmod-sdhci-mt7620 kmod-usb-ledtrig-usbport
+ kmod-mmc-mtk kmod-usb-ledtrig-usbport
endef
TARGET_DEVICES += bdcom_wap2100-sk
@@ -372,7 +372,7 @@ define Device/domywifi_dm202
IMAGE_SIZE := 16064k
DEVICE_VENDOR := DomyWifi
DEVICE_MODEL := DM202
- DEVICE_PACKAGES := kmod-mt76x0e kmod-sdhci-mt7620 kmod-usb2 kmod-usb-ohci
+ DEVICE_PACKAGES := kmod-mt76x0e kmod-mmc-mtk kmod-usb2 kmod-usb-ohci
endef
TARGET_DEVICES += domywifi_dm202
@@ -381,7 +381,7 @@ define Device/domywifi_dm203
IMAGE_SIZE := 16064k
DEVICE_VENDOR := DomyWifi
DEVICE_MODEL := DM203
- DEVICE_PACKAGES := kmod-mt76x0e kmod-sdhci-mt7620 kmod-usb2 kmod-usb-ohci
+ DEVICE_PACKAGES := kmod-mt76x0e kmod-mmc-mtk kmod-usb2 kmod-usb-ohci
endef
TARGET_DEVICES += domywifi_dm203
@@ -390,7 +390,7 @@ define Device/domywifi_dw22d
IMAGE_SIZE := 16064k
DEVICE_VENDOR := DomyWifi
DEVICE_MODEL := DW22D
- DEVICE_PACKAGES := kmod-mt76x0e kmod-sdhci-mt7620 kmod-usb2 kmod-usb-ohci
+ DEVICE_PACKAGES := kmod-mt76x0e kmod-mmc-mtk kmod-usb2 kmod-usb-ohci
endef
TARGET_DEVICES += domywifi_dw22d
@@ -557,7 +557,7 @@ define Device/head-weblink_hdrm200
IMAGE_SIZE := 16064k
DEVICE_VENDOR := Head Weblink
DEVICE_MODEL := HDRM2000
- DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-mmc-mtk \
uqmi kmod-usb-serial-option
endef
TARGET_DEVICES += head-weblink_hdrm200
@@ -567,7 +567,7 @@ define Device/hiwifi_hc5661
IMAGE_SIZE := 15808k
DEVICE_VENDOR := HiWiFi
DEVICE_MODEL := HC5661
- DEVICE_PACKAGES := kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-mmc-mtk
SUPPORTED_DEVICES += hc5661
endef
TARGET_DEVICES += hiwifi_hc5661
@@ -577,7 +577,7 @@ define Device/hiwifi_hc5761
IMAGE_SIZE := 15808k
DEVICE_VENDOR := HiWiFi
DEVICE_MODEL := HC5761
- DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci kmod-mmc-mtk \
kmod-usb-ledtrig-usbport
SUPPORTED_DEVICES += hc5761
endef
@@ -588,7 +588,7 @@ define Device/hiwifi_hc5861
IMAGE_SIZE := 15808k
DEVICE_VENDOR := HiWiFi
DEVICE_MODEL := HC5861
- DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-mmc-mtk \
kmod-phy-realtek kmod-usb-ledtrig-usbport
SUPPORTED_DEVICES += hc5861
endef
@@ -599,7 +599,7 @@ define Device/hnet_c108
IMAGE_SIZE := 16064k
DEVICE_VENDOR := HNET
DEVICE_MODEL := C108
- DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mmc-mtk
SUPPORTED_DEVICES += c108
endef
TARGET_DEVICES += hnet_c108
@@ -1023,7 +1023,7 @@ define Device/planex_cs-qr10
DEVICE_VENDOR := Planex
DEVICE_MODEL := CS-QR10
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sound-core \
- kmod-sound-mt7620 kmod-i2c-ralink kmod-sdhci-mt7620
+ kmod-sound-mt7620 kmod-i2c-ralink kmod-mmc-mtk
SUPPORTED_DEVICES += cs-qr10
endef
TARGET_DEVICES += planex_cs-qr10
@@ -1139,7 +1139,7 @@ define Device/sanlinking_d240
IMAGE_SIZE := 16064k
DEVICE_VENDOR := Sanlinking Technologies
DEVICE_MODEL := D240
- DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-mmc-mtk
SUPPORTED_DEVICES += d240
endef
TARGET_DEVICES += sanlinking_d240
@@ -1220,7 +1220,7 @@ define Device/tplink_archer-c2-v1
DEVICE_MODEL := Archer C2
DEVICE_VARIANT := v1
DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
- kmod-usb-ledtrig-usbport kmod-switch-rtl8366-smi kmod-switch-rtl8367b
+ kmod-usb-ledtrig-usbport kmod-switch-rtl8367b
endef
TARGET_DEVICES += tplink_archer-c2-v1
@@ -1349,6 +1349,16 @@ define Device/wavlink_wl-wn531g3
endef
TARGET_DEVICES += wavlink_wl-wn531g3
+
+define Device/wavlink_wl-wn531g3-a2
+ SOC := mt7620a
+ IMAGE_SIZE := 7872k
+ DEVICE_VENDOR := Wavlink
+ DEVICE_MODEL := WL-WN531G3-A2
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-phy-realtek kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += wavlink_wl-wn531g3-a2
+
define Device/wavlink_wl-wn535k1
SOC := mt7620a
IMAGE_SIZE := 7360k
@@ -1407,7 +1417,7 @@ define Device/youku_x2
DEVICE_VENDOR := Youku
DEVICE_MODEL := X2
DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci \
- kmod-sdhci-mt7620 kmod-usb-ledtrig-usbport
+ kmod-mmc-mtk kmod-usb-ledtrig-usbport
UIMAGE_MAGIC := 0x12291000
UIMAGE_NAME := 400000000000000000001000
endef
@@ -1418,7 +1428,7 @@ define Device/youku_yk-l1
IMAGE_SIZE := 32448k
DEVICE_VENDOR := Youku
DEVICE_MODEL := YK-L1
- DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mmc-mtk \
kmod-usb-ledtrig-usbport
SUPPORTED_DEVICES += youku-yk1 youku,yk1
UIMAGE_MAGIC := 0x12291000
@@ -1431,7 +1441,7 @@ define Device/youku_yk-l1c
IMAGE_SIZE := 16064k
DEVICE_VENDOR := Youku
DEVICE_MODEL := YK-L1c
- DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mmc-mtk \
kmod-usb-ledtrig-usbport
UIMAGE_MAGIC := 0x12291000
UIMAGE_NAME := 400000000000000000000000
@@ -1484,7 +1494,7 @@ define Device/zbtlink_zbt-we1026-5g-16m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WE1026-5G
DEVICE_VARIANT := 16M
- DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-mmc-mtk
SUPPORTED_DEVICES += we1026-5g-16m zbtlink,we1026-5g-16m
endef
TARGET_DEVICES += zbtlink_zbt-we1026-5g-16m
@@ -1495,7 +1505,7 @@ define Device/zbtlink_zbt-we1026-h-32m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WE1026-H
DEVICE_VARIANT := 32M
- DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mmc-mtk
endef
TARGET_DEVICES += zbtlink_zbt-we1026-h-32m
@@ -1514,7 +1524,7 @@ define Device/zbtlink_zbt-we826-16m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WE826
DEVICE_VARIANT := 16M
- DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-mmc-mtk
SUPPORTED_DEVICES += zbt-we826 zbt-we826-16M
endef
TARGET_DEVICES += zbtlink_zbt-we826-16m
@@ -1525,7 +1535,7 @@ define Device/zbtlink_zbt-we826-32m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WE826
DEVICE_VARIANT := 32M
- DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-mmc-mtk
SUPPORTED_DEVICES += zbt-we826-32M
endef
TARGET_DEVICES += zbtlink_zbt-we826-32m
@@ -1535,7 +1545,7 @@ define Device/zbtlink_zbt-we826-e
IMAGE_SIZE := 32448k
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WE826-E
- DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 uqmi \
+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mmc-mtk uqmi \
kmod-usb-serial-option
endef
TARGET_DEVICES += zbtlink_zbt-we826-e
@@ -1564,7 +1574,7 @@ TARGET_DEVICES += zte_q7
define Device/zyxel_keenetic-lite-iii-a
SOC := mt7620n
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Lite III
DEVICE_VARIANT := A
IMAGES += factory.bin
@@ -1576,7 +1586,7 @@ TARGET_DEVICES += zyxel_keenetic-lite-iii-a
define Device/zyxel_keenetic-omni
SOC := mt7620n
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Omni
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
IMAGES += factory.bin
@@ -1589,7 +1599,7 @@ TARGET_DEVICES += zyxel_keenetic-omni
define Device/zyxel_keenetic-omni-ii
SOC := mt7620n
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Omni II
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
IMAGES += factory.bin
@@ -1602,10 +1612,10 @@ TARGET_DEVICES += zyxel_keenetic-omni-ii
define Device/zyxel_keenetic-viva
SOC := mt7620a
IMAGE_SIZE := 16064k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Viva
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
- kmod-switch-rtl8366-smi kmod-switch-rtl8367b
+ kmod-switch-rtl8367b
IMAGES += factory.bin
IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to 64k | check-size | \
zyimage -d 8997 -v "ZyXEL Keenetic Viva"
diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
index 13b6a51966..70454bcbaf 100644
--- a/target/linux/ramips/image/mt7621.mk
+++ b/target/linux/ramips/image/mt7621.mk
@@ -23,6 +23,21 @@ define Build/append-dlink-covr-metadata
rm $@metadata.tmp
endef
+define Build/append-netis-n6-metadata
+ ( echo -ne '{ \
+ "up_model": "Netis-N6R", \
+ "supported_devices": ["mt7621-rfb-ax-nand"], \
+ "version": { \
+ "dist": "$(call json_quote,$(VERSION_DIST))", \
+ "version": "$(call json_quote,$(VERSION_NUMBER))", \
+ "revision": "$(call json_quote,$(REVISION))", \
+ "board": "$(call json_quote,$(BOARD))" \
+ } }' \
+ ) > $@.metadata.tmp
+ fwtool -I $@.metadata.tmp $@
+ rm $@.metadata.tmp
+endef
+
define Build/arcadyan-trx
echo -ne "hsqs" > $@.hsqs
$(eval trx_magic=$(word 1,$(1)))
@@ -36,6 +51,68 @@ define Build/arcadyan-trx
rm $@.hsqs $@.tail
endef
+define Build/dna-header
+ BC='$(STAGING_DIR_HOST)/bin/bc' ;\
+ ubifsofs="1024" ;\
+ ubifs="$$(stat -c%s $@)" ;\
+ pkginfoofs="$$(echo $${ubifsofs} + $${ubifs} | $${BC})" ;\
+ pkginfo="0" ;\
+ scrofs="$$(echo $${pkginfoofs} + $${pkginfo} | $${BC})" ;\
+ scr="0" ;\
+ sigofs="$$(echo $${scrofs} + $${scr} | $${BC})" ;\
+ sig="0" ;\
+ md5ofs="$$(echo $${sigofs} + $${sig} | $${BC})" ;\
+ md5="32" ;\
+ size="$$(echo $${md5ofs} + $${md5} | $${BC})" ;\
+ echo "IntenoIopY" > $@.tmp ;\
+ echo "version 5" >> $@.tmp ;\
+ echo "integrity MD5SUM" >> $@.tmp ;\
+ echo "board EX400" >> $@.tmp ;\
+ echo "chip 7621" >> $@.tmp ;\
+ echo "arch all mipsel_1004kc" >> $@.tmp ;\
+ echo "model EX400" >> $@.tmp ;\
+ echo "release EX400-X-DNA-4.3.6.100-R-210518_0935" >> $@.tmp ;\
+ echo "customer DNA" >> $@.tmp ;\
+ echo "ubifsofs $${ubifsofs}" >> $@.tmp ;\
+ echo "ubifs $${ubifs}" >> $@.tmp ;\
+ echo "pkginfoofs $${pkginfoofs}" >> $@.tmp ;\
+ echo "pkginfo $${pkginfo}" >> $@.tmp ;\
+ echo "scrofs $${scrofs}" >> $@.tmp ;\
+ echo "scr $${scr}" >> $@.tmp ;\
+ echo "sigofs $${sigofs}" >> $@.tmp ;\
+ echo "sig $${sig}" >> $@.tmp ;\
+ echo "md5ofs $${md5ofs}" >> $@.tmp ;\
+ echo "md5 $${md5}" >> $@.tmp ;\
+ echo "size $${size}" >> $@.tmp
+
+ dd if=$@.tmp of=$@.tmp2 bs=1024 count=1 conv=sync
+ cat $@.tmp2 $@ > $@.tmp
+ rm $@.tmp2
+ mv $@.tmp $@
+endef
+
+define Build/dna-bootfs
+ mkdir -p $@.ubifs-dir/boot
+
+ # populate the boot fs with the dtb and with either initramfs kernel or
+ # the normal kernel
+ $(CP) $(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb $@.ubifs-dir/boot/dtb
+
+ $(if $(findstring with-initrd,$(word 1,$(1))),\
+ ( \
+ $(CP) $@ $@.ubifs-dir/boot/uImage \
+ ) , \
+ ( \
+ $(CP) $(IMAGE_KERNEL) $@.ubifs-dir/boot/uImage \
+ ) \
+ )
+
+ # create ubifs
+ $(STAGING_DIR_HOST)/bin/mkfs.ubifs ${MKUBIFS_OPTS} -r $@.ubifs-dir/ -o $@.new
+ rm -rf $@.ubifs-dir
+ mv $@.new $@
+endef
+
define Build/gemtek-trailer
printf "%s%08X" ".GEMTEK." "$$(cksum $@ | cut -d ' ' -f1)" >> $@
endef
@@ -103,6 +180,10 @@ define Build/iodata-mstc-header2
mv $@.new $@
endef
+define Build/kernel-initramfs-bin
+ $(CP) $(KDIR)/vmlinux-initramfs $@
+endef
+
define Build/znet-header
$(eval version=$(word 1,$(1)))
$(eval magic=$(if $(word 2,$(1)),$(word 2,$(1)),ZNET))
@@ -242,7 +323,7 @@ define Device/alfa-network_quad-e4g
IMAGE_SIZE := 16064k
DEVICE_VENDOR := ALFA Network
DEVICE_MODEL := Quad-E4G
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-usb3 \
-wpad-basic-mbedtls
SUPPORTED_DEVICES += quad-e4g
endef
@@ -300,7 +381,7 @@ define Device/asiarf_ap7621-001
IMAGE_SIZE := 16000k
DEVICE_VENDOR := AsiaRF
DEVICE_MODEL := AP7621-001
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt76x2 kmod-usb3 \
-wpad-basic-mbedtls -uboot-envtools
endef
TARGET_DEVICES += asiarf_ap7621-001
@@ -311,7 +392,7 @@ define Device/asiarf_ap7621-nv1
IMAGE_SIZE := 16000k
DEVICE_VENDOR := AsiaRF
DEVICE_MODEL := AP7621-NV1
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt76x2 kmod-usb3 \
-wpad-basic-mbedtls -uboot-envtools
endef
TARGET_DEVICES += asiarf_ap7621-nv1
@@ -604,7 +685,7 @@ define Device/comfast_cf-e390ax
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 15808k
- DEVICE_VENDOR := ComFast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-E390AX
DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
IMAGES += factory.bin
@@ -618,7 +699,7 @@ define Device/comfast_cf-ew72-v2
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 15808k
- DEVICE_VENDOR := ComFast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-EW72 V2
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap \
-uboot-envtools
@@ -835,6 +916,20 @@ define Device/dlink_dir-2150-a1
endef
TARGET_DEVICES += dlink_dir-2150-a1
+define Device/dlink_dir-2150-r1
+ $(Device/nand)
+ IMAGE_SIZE := 129536k
+ DEVICE_VENDOR := D-Link
+ DEVICE_MODEL := DIR-2150
+ DEVICE_VARIANT := R1
+ DEVICE_PACKAGES := -uboot-envtools kmod-mt7603 kmod-mt7615-firmware kmod-usb3
+ KERNEL := $$(KERNEL)
+ IMAGES += factory.bin
+ IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+ check-size | sign-dlink-ru e6587b35a6b34e07bedeca23e140322f
+endef
+TARGET_DEVICES += dlink_dir-2150-r1
+
define Device/dlink_dir-2640-a1
$(Device/dlink_dir_nand_128m)
DEVICE_MODEL := DIR-2640
@@ -961,7 +1056,7 @@ define Device/dual-q_h721
IMAGE_SIZE := 16064k
DEVICE_VENDOR := Dual-Q
DEVICE_MODEL := H721
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-usb3 \
-wpad-basic-mbedtls -uboot-envtools
endef
TARGET_DEVICES += dual-q_h721
@@ -982,12 +1077,33 @@ define Device/d-team_pbr-m1
IMAGE_SIZE := 32448k
DEVICE_VENDOR := PandoraBox
DEVICE_MODEL := PBR-M1
- DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-mmc-mtk \
kmod-usb3 kmod-usb-ledtrig-usbport -uboot-envtools
SUPPORTED_DEVICES += pbr-m1
endef
TARGET_DEVICES += d-team_pbr-m1
+define Device/dna_valokuitu-plus-ex400
+ $(Device/dsa-migration)
+ IMAGE_SIZE := 117m
+ PAGESIZE := 2048
+ MKUBIFS_OPTS := --min-io-size=$$(PAGESIZE) --leb-size=124KiB --max-leb-cnt=96 \
+ --log-lebs=2 --space-fixup --squash-uids
+ DEVICE_VENDOR := DNA
+ DEVICE_MODEL := Valokuitu Plus EX400
+ KERNEL := kernel-bin | lzma | uImage lzma
+ KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | uImage lzma
+ IMAGES := factory.bin sysupgrade.bin
+ IMAGE/factory.bin := kernel-initramfs-bin | lzma | uImage lzma | \
+ dna-bootfs with-initrd | dna-header | \
+ append-md5sum-ascii-salted
+ IMAGE/sysupgrade.bin := dna-bootfs | sysupgrade-tar kernel=$$$$@ | check-size | \
+ append-metadata
+ DEVICE_IMG_NAME = $$(DEVICE_IMG_PREFIX)-$$(2)
+ DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615-firmware kmod-usb3
+endef
+TARGET_DEVICES += dna_valokuitu-plus-ex400
+
define Device/edimax_ra21s
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
@@ -1062,6 +1178,24 @@ define Device/elecom_wmc-s1267gs2
endef
TARGET_DEVICES += elecom_wmc-s1267gs2
+define Device/elecom_wmc-x1800gst
+ $(Device/nand)
+ DEVICE_VENDOR := ELECOM
+ DEVICE_MODEL := WMC-X1800GST
+ KERNEL_SIZE := 15360k
+ KERNEL_LOADADDR := 0x82000000
+ KERNEL := kernel-bin | relocate-kernel $(loadaddr-y) | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+ ARTIFACTS := initramfs-factory.bin
+ ARTIFACT/initramfs-factory.bin := append-image-stage initramfs-kernel.bin | \
+ check-size $$$$(KERNEL_SIZE) | elecom-wrc-gs-factory WMC-2LX 0.00 -N | \
+ append-string MT7621_ELECOM_WMC-2LX
+endif
+ DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
+endef
+TARGET_DEVICES += elecom_wmc-x1800gst
+
define Device/elecom_wrc-1167ghbk2-s
$(Device/dsa-migration)
IMAGE_SIZE := 15488k
@@ -1195,6 +1329,24 @@ endif
endef
TARGET_DEVICES += elecom_wrc-x1800gs
+define Device/elecom_wsc-x1800gs
+ $(Device/nand)
+ DEVICE_VENDOR := ELECOM
+ DEVICE_MODEL := WSC-X1800GS
+ KERNEL_SIZE := 15360k
+ KERNEL_LOADADDR := 0x82000000
+ KERNEL := kernel-bin | relocate-kernel $(loadaddr-y) | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+ ARTIFACTS := initramfs-factory.bin
+ ARTIFACT/initramfs-factory.bin := append-image-stage initramfs-kernel.bin | \
+ check-size $$$$(KERNEL_SIZE) | elecom-wrc-gs-factory WMC-2LX 0.00 -N | \
+ append-string MT7621_ELECOM_WMC-2LX
+endif
+ DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
+endef
+TARGET_DEVICES += elecom_wsc-x1800gs
+
define Device/etisalat_s3
$(Device/sercomm_dxx)
IMAGE_SIZE := 32768k
@@ -1244,7 +1396,7 @@ define Device/gnubee_gb-pc1
$(Device/uimage-lzma-loader)
DEVICE_VENDOR := GnuBee
DEVICE_MODEL := GB-PC1
- DEVICE_PACKAGES := kmod-ata-ahci kmod-usb3 kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-usb3 kmod-mmc-mtk \
-wpad-basic-mbedtls -uboot-envtools
IMAGE_SIZE := 32448k
endef
@@ -1255,7 +1407,7 @@ define Device/gnubee_gb-pc2
$(Device/uimage-lzma-loader)
DEVICE_VENDOR := GnuBee
DEVICE_MODEL := GB-PC2
- DEVICE_PACKAGES := kmod-ata-ahci kmod-usb3 kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-usb3 kmod-mmc-mtk \
-wpad-basic-mbedtls -uboot-envtools
IMAGE_SIZE := 32448k
endef
@@ -1370,7 +1522,7 @@ define Device/huasifei_ws1208v2
IMAGE_SIZE := 16064k
DEVICE_VENDOR := Huasifei
DEVICE_MODEL := WS1208V2
- DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-mmc-mtk \
kmod-usb3 kmod-usb-net-cdc-mbim kmod-usb-net-qmi-wwan \
kmod-usb-serial-option -uboot-envtools
endef
@@ -1632,7 +1784,7 @@ define Device/jdcloud_re-cp-02
IMAGE_SIZE := 16000k
DEVICE_VENDOR := JD-Cloud
DEVICE_MODEL := RE-CP-02
- DEVICE_PACKAGES := kmod-mt7915-firmware kmod-sdhci-mt7620
+ DEVICE_PACKAGES := kmod-mt7915-firmware kmod-mmc-mtk
endef
TARGET_DEVICES += jdcloud_re-cp-02
@@ -1650,13 +1802,26 @@ define Device/keenetic_kn-3010
endef
TARGET_DEVICES += keenetic_kn-3010
+define Device/keenetic_kn-3510
+ $(Device/nand)
+ $(Device/uimage-lzma-loader)
+ IMAGE_SIZE := 121088k
+ DEVICE_VENDOR := Keenetic
+ DEVICE_MODEL := KN-3510
+ DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
+ IMAGES += factory.bin
+ IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+ check-size | zyimage -d 0x803510 -v "KN-3510"
+endef
+TARGET_DEVICES += keenetic_kn-3510
+
define Device/lenovo_newifi-d1
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 32448k
DEVICE_VENDOR := Lenovo
DEVICE_MODEL := Newifi D1
- DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-mmc-mtk \
kmod-usb-ledtrig-usbport -uboot-envtools
SUPPORTED_DEVICES += newifi-d1
endef
@@ -1770,7 +1935,7 @@ define Device/mediatek_ap-mt7621a-v60
IMAGE_SIZE := 7872k
DEVICE_VENDOR := Mediatek
DEVICE_MODEL := AP-MT7621A-V60 EVB
- DEVICE_PACKAGES := kmod-usb3 kmod-sdhci-mt7620 kmod-sound-mt7620 \
+ DEVICE_PACKAGES := kmod-usb3 kmod-mmc-mtk kmod-sound-mt7620 \
-wpad-basic-mbedtls -uboot-envtools
endef
TARGET_DEVICES += mediatek_ap-mt7621a-v60
@@ -1865,7 +2030,7 @@ define Device/mqmaker_witi
IMAGE_SIZE := 16064k
DEVICE_VENDOR := MQmaker
DEVICE_MODEL := WiTi
- DEVICE_PACKAGES := kmod-ata-ahci kmod-mt76x2 kmod-sdhci-mt7620 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mt76x2 kmod-mmc-mtk kmod-usb3 \
kmod-usb-ledtrig-usbport -uboot-envtools
SUPPORTED_DEVICES += witi mqmaker,witi-256m mqmaker,witi-512m
endef
@@ -1878,7 +2043,7 @@ define Device/mtc_wr1201
DEVICE_VENDOR := MTC
DEVICE_MODEL := Wireless Router WR1201
KERNEL_INITRAMFS := $(KERNEL_DTB) | uImage lzma -n 'WR1201_8_128'
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport -uboot-envtools
endef
TARGET_DEVICES += mtc_wr1201
@@ -2113,6 +2278,24 @@ define Device/netgear_wax202
endef
TARGET_DEVICES += netgear_wax202
+define Device/netgear_wax214v2
+ $(Device/nand)
+ DEVICE_VENDOR := NETGEAR
+ DEVICE_MODEL := WAX214v2
+ DEVICE_PACKAGES := kmod-mt7915-firmware
+ NETGEAR_ENC_MODEL := WAX214v2
+ NETGEAR_ENC_REGION := US
+ IMAGE_SIZE := 38912k
+ KERNEL_LOADADDR := 0x82000000
+ KERNEL := kernel-bin | relocate-kernel 0x80001000 | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb | \
+ append-squashfs4-fakeroot
+ IMAGES += factory.img
+ IMAGE/factory.img := append-kernel | pad-to $$(KERNEL_SIZE) | \
+ append-ubi | check-size | netgear-encrypted-factory
+endef
+TARGET_DEVICES += netgear_wax214v2
+
define Device/netgear_wndr3700-v5
$(Device/dsa-migration)
$(Device/netgear_sercomm_nor)
@@ -2131,6 +2314,23 @@ define Device/netgear_wndr3700-v5
endef
TARGET_DEVICES += netgear_wndr3700-v5
+define Device/netis_n6
+ $(Device/dsa-migration)
+ $(Device/nand)
+ IMAGE_SIZE := 121344k
+ DEVICE_VENDOR := netis
+ DEVICE_MODEL := N6
+ KERNEL_LOADADDR := 0x82000000
+ KERNEL := kernel-bin | relocate-kernel $(loadaddr-y) | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
+ IMAGES += factory.bin
+ IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | \
+ append-ubi | check-size | append-netis-n6-metadata
+ DEVICE_PACKAGES += kmod-mt7915-firmware kmod-usb-ledtrig-usbport \
+ kmod-usb3
+endef
+TARGET_DEVICES += netis_n6
+
define Device/netis_wf2881
$(Device/nand)
$(Device/uimage-lzma-loader)
@@ -2154,7 +2354,7 @@ define Device/openfi_5pro
DEVICE_VENDOR := OpenFi
DEVICE_MODEL := 5Pro
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap kmod-usb3 \
- kmod-sdhci-mt7620
+ kmod-mmc-mtk
endef
TARGET_DEVICES += openfi_5pro
@@ -2242,6 +2442,17 @@ define Device/rostelecom_rt-sf-1
endef
TARGET_DEVICES += rostelecom_rt-sf-1
+define Device/ruijie_rg-ew1200g-pro-v1.1
+ $(Device/dsa-migration)
+ $(Device/uimage-lzma-loader)
+ IMAGE_SIZE := 15808k
+ DEVICE_VENDOR := Ruijie
+ DEVICE_MODEL := RG-EW1200G PRO
+ DEVICE_VARIANT := v1.1
+ DEVICE_PACKAGES := kmod-mt7615-firmware
+endef
+TARGET_DEVICES += ruijie_rg-ew1200g-pro-v1.1
+
define Device/samknows_whitebox-v8
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
@@ -2266,6 +2477,7 @@ TARGET_DEVICES += sercomm_na502
define Device/sercomm_na502s
$(Device/nand)
+ $(Device/uimage-lzma-loader)
IMAGE_SIZE := 20971520
DEVICE_VENDOR := SERCOMM
DEVICE_MODEL := NA502S
@@ -2520,6 +2732,8 @@ TARGET_DEVICES += tplink_ec330-g5u-v1
define Device/tplink_er605-v2
$(Device/nand)
+ DEVICE_COMPAT_VERSION := 1.2
+ DEVICE_COMPAT_MESSAGE := Config cannot be migrated because interface names have changed
DEVICE_VENDOR := TP-Link
DEVICE_MODEL := ER605
DEVICE_VARIANT := v2
@@ -2528,7 +2742,6 @@ define Device/tplink_er605-v2
KERNEL_LOADADDR := 0x82000000
KERNEL := kernel-bin | relocate-kernel $(loadaddr-y) | lzma | \
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
- IMAGES += sysupgrade.tar
IMAGE_SIZE := 127744k
endef
TARGET_DEVICES += tplink_er605-v2
@@ -2656,7 +2869,7 @@ TARGET_DEVICES += ubnt_edgerouter-x-sfp
define Device/ubnt_unifi-6-lite
$(Device/dsa-migration)
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 Lite
+ DEVICE_MODEL := UniFi U6 Lite
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS_LOADADDR := 0x87000000
DEVICE_PACKAGES += kmod-mt7603 kmod-mt7915-firmware -uboot-envtools
@@ -2717,7 +2930,7 @@ define Device/unielec_u7621-06-16m
DEVICE_VENDOR := UniElec
DEVICE_MODEL := U7621-06
DEVICE_VARIANT := 16M
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-usb3 \
-wpad-basic-mbedtls -uboot-envtools
SUPPORTED_DEVICES += u7621-06-256M-16M unielec,u7621-06-256m-16m
endef
@@ -2730,7 +2943,7 @@ define Device/unielec_u7621-06-32m
DEVICE_VENDOR := UniElec
DEVICE_MODEL := U7621-06
DEVICE_VARIANT := 32M
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-usb3 \
-wpad-basic-mbedtls -uboot-envtools
SUPPORTED_DEVICES += unielec,u7621-06-32m
endef
@@ -2743,7 +2956,7 @@ define Device/unielec_u7621-06-64m
DEVICE_VENDOR := UniElec
DEVICE_MODEL := U7621-06
DEVICE_VARIANT := 64M
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-usb3 \
-wpad-basic-mbedtls -uboot-envtools
SUPPORTED_DEVICES += unielec,u7621-06-512m-64m
endef
@@ -2784,7 +2997,6 @@ define Device/wavlink_ws-wn572hp3-4g
endef
TARGET_DEVICES += wavlink_ws-wn572hp3-4g
-
define Device/wavlink_wl-wn573hx1
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 15808k
@@ -2867,6 +3079,17 @@ define Device/winstars_ws-wn583a6
endef
TARGET_DEVICES += winstars_ws-wn583a6
+define Device/wodesys_wd-r1802u
+ $(Device/dsa-migration)
+ $(Device/uimage-lzma-loader)
+ IMAGE_SIZE := 15808k
+ DEVICE_VENDOR := Wodesys
+ DEVICE_MODEL := WD-R1802U
+ DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
+ SUPPORTED_DEVICES += mt7621-rfb-ax-nor
+endef
+TARGET_DEVICES += wodesys_wd-r1802u
+
define Device/xiaomi_nand_separate
$(Device/nand)
$(Device/uimage-lzma-loader)
@@ -3003,7 +3226,7 @@ define Device/xzwifi_creativebox-v1
IMAGE_SIZE := 32448k
DEVICE_VENDOR := CreativeBox
DEVICE_MODEL := v1
- DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-mmc-mtk \
kmod-usb3 -wpad-basic-mbedtls -uboot-envtools
endef
TARGET_DEVICES += xzwifi_creativebox-v1
@@ -3092,7 +3315,7 @@ define Device/zbtlink_zbt-we1326
DEVICE_MODEL := ZBT-WE1326
DEVICE_ALT0_VENDOR := Wiflyer
DEVICE_ALT0_MODEL := WF3526-P
- DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-sdhci-mt7620 \
+ DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-mmc-mtk \
-uboot-envtools
SUPPORTED_DEVICES += zbt-we1326
endef
@@ -3104,7 +3327,7 @@ define Device/zbtlink_zbt-we3526
IMAGE_SIZE := 16064k
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WE3526
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt7603 kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport -uboot-envtools
endef
TARGET_DEVICES += zbtlink_zbt-we3526
@@ -3116,7 +3339,7 @@ define Device/zbtlink_zbt-wg1602-16m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG1602
DEVICE_VARIANT := 16M
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt7603 kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport -uboot-envtools
endef
TARGET_DEVICES += zbtlink_zbt-wg1602-16m
@@ -3128,7 +3351,7 @@ define Device/zbtlink_zbt-wg1602-v04-16m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG1602-V04
DEVICE_VARIANT := 16M
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt7603 kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport -uboot-envtools
endef
TARGET_DEVICES += zbtlink_zbt-wg1602-v04-16m
@@ -3140,7 +3363,7 @@ define Device/zbtlink_zbt-wg1602-v04-32m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG1602-V04
DEVICE_VARIANT := 32M
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt7603 kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport -uboot-envtools
endef
TARGET_DEVICES += zbtlink_zbt-wg1602-v04-32m
@@ -3152,7 +3375,7 @@ define Device/zbtlink_zbt-wg1608-16m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG1608
DEVICE_VARIANT := 16M
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt7603 kmod-mt7615e \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt7603 kmod-mt7615e \
kmod-mt7663-firmware-ap kmod-usb3 kmod-usb-ledtrig-usbport \
-uboot-envtools
endef
@@ -3165,7 +3388,7 @@ define Device/zbtlink_zbt-wg1608-32m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG1608
DEVICE_VARIANT := 32M
- DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt7603 kmod-mt7615e \
+ DEVICE_PACKAGES := kmod-mmc-mtk kmod-mt7603 kmod-mt7615e \
kmod-mt7663-firmware-ap kmod-usb3 kmod-usb-ledtrig-usbport
endef
TARGET_DEVICES += zbtlink_zbt-wg1608-32m
@@ -3176,7 +3399,7 @@ define Device/zbtlink_zbt-wg2626
IMAGE_SIZE := 16064k
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG2626
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport -uboot-envtools
SUPPORTED_DEVICES += zbt-wg2626
endef
@@ -3189,7 +3412,7 @@ define Device/zbtlink_zbt-wg3526-16m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG3526
DEVICE_VARIANT := 16M
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-mt7603 kmod-mt76x2 \
kmod-usb3 kmod-usb-ledtrig-usbport -uboot-envtools
SUPPORTED_DEVICES += zbt-wg3526 zbt-wg3526-16M
endef
@@ -3202,7 +3425,7 @@ define Device/zbtlink_zbt-wg3526-32m
DEVICE_VENDOR := Zbtlink
DEVICE_MODEL := ZBT-WG3526
DEVICE_VARIANT := 32M
- DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 \
+ DEVICE_PACKAGES := kmod-ata-ahci kmod-mmc-mtk kmod-mt7603 kmod-mt76x2 \
kmod-usb3 kmod-usb-ledtrig-usbport -uboot-envtools
SUPPORTED_DEVICES += ac1200pro zbt-wg3526-32M
endef
@@ -3220,7 +3443,7 @@ TARGET_DEVICES += zio_freezio
define Device/zyxel_lte3301-plus
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := LTE3301-PLUS
KERNEL_SIZE := 31488k
DEVICE_PACKAGES := kmod-mt7615-firmware kmod-usb3 kmod-usb-ledtrig-usbport \
@@ -3235,7 +3458,7 @@ TARGET_DEVICES += zyxel_lte3301-plus
define Device/zyxel_lte5398-m904
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := LTE5398-M904
KERNEL_SIZE := 31488k
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615-firmware kmod-usb3 uqmi \
@@ -3250,7 +3473,7 @@ TARGET_DEVICES += zyxel_lte5398-m904
define Device/zyxel_nr7101
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NR7101
KERNEL_SIZE := 31488k
DEVICE_PACKAGES := kmod-mt7603 kmod-usb3 kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi
@@ -3262,7 +3485,7 @@ TARGET_DEVICES += zyxel_nr7101
define Device/zyxel_nwa-ax
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
KERNEL_SIZE := 8192k
DEVICE_PACKAGES := kmod-mt7915-firmware zyxel-bootconfig
KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
@@ -3287,7 +3510,7 @@ define Device/zyxel_wap6805
$(Device/nand)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 32448k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := WAP6805
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7621-qtn-rgmii -uboot-envtools
KERNEL := $$(KERNEL/lzma-loader) | uImage none | uimage-padhdr 160
@@ -3298,7 +3521,7 @@ define Device/zyxel_wsm20
$(Device/nand)
KERNEL_SIZE := 8192k
IMAGE_SIZE := 41943040
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := WSM20
DEVICE_PACKAGES := kmod-mt7915-firmware
KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb | znet-header V1.00(ABZF.0)C0
diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk
index 07000a1a11..8ad840ddfe 100644
--- a/target/linux/ramips/image/mt76x8.mk
+++ b/target/linux/ramips/image/mt76x8.mk
@@ -135,7 +135,7 @@ TARGET_DEVICES += buffalo_wcr-1166ds
define Device/comfast_cf-wr617ac
IMAGE_SIZE := 7872k
DTS := CF-WR617AC
- DEVICE_VENDOR := Comfast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-WR617AC
DEVICE_PACKAGES := kmod-mt76x2 kmod-rt2800-pci
endef
@@ -406,7 +406,7 @@ define Device/mediatek_linkit-smart-7688
IMAGE_SIZE := 32448k
DEVICE_VENDOR := MediaTek
DEVICE_MODEL := LinkIt Smart 7688
- DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci uboot-envtools kmod-sdhci-mt7620
+ DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci uboot-envtools kmod-mmc-mtk
SUPPORTED_DEVICES += linkits7688 linkits7688d
endef
TARGET_DEVICES += mediatek_linkit-smart-7688
@@ -499,7 +499,7 @@ define Device/onion_omega2p
IMAGE_SIZE := 32448k
DEVICE_VENDOR := Onion
DEVICE_MODEL := Omega2+
- DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci uboot-envtools kmod-sdhci-mt7620
+ DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci uboot-envtools kmod-mmc-mtk
SUPPORTED_DEVICES += omega2p
endef
TARGET_DEVICES += onion_omega2p
@@ -526,7 +526,7 @@ define Device/ravpower_rp-wd009
DEVICE_MODEL := RP-WD009
UBOOT_PATH := $(STAGING_DIR_IMAGE)/mt7628_ravpower_rp-wd009-u-boot.bin
DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
- kmod-sdhci-mt7620 kmod-i2c-mt7628 ravpower-mcu
+ kmod-mmc-mtk kmod-i2c-mt7628 ravpower-mcu
IMAGES += factory.bin
IMAGE/factory.bin := $$(sysupgrade_bin) | ravpower-wd009-factory
endef
@@ -954,7 +954,7 @@ define Device/vocore_vocore2
DEVICE_VENDOR := VoCore
DEVICE_MODEL := VoCore2
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
- kmod-sdhci-mt7620
+ kmod-mmc-mtk
SUPPORTED_DEVICES += vocore2
endef
TARGET_DEVICES += vocore_vocore2
@@ -964,7 +964,7 @@ define Device/vocore_vocore2-lite
DEVICE_VENDOR := VoCore
DEVICE_MODEL := VoCore2-Lite
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
- kmod-sdhci-mt7620
+ kmod-mmc-mtk
SUPPORTED_DEVICES += vocore2lite
endef
TARGET_DEVICES += vocore_vocore2-lite
@@ -1092,6 +1092,15 @@ define Device/xiaomi_mi-router-4a-100m-intl
endef
TARGET_DEVICES += xiaomi_mi-router-4a-100m-intl
+define Device/xiaomi_mi-router-4a-100m-intl-v2
+ IMAGE_SIZE := 14976k
+ DEVICE_VENDOR := Xiaomi
+ DEVICE_MODEL := Mi Router 4A
+ DEVICE_VARIANT := 100M International Edition V2
+ DEVICE_PACKAGES := kmod-mt7615e kmod-mt7663-firmware-ap
+endef
+TARGET_DEVICES += xiaomi_mi-router-4a-100m-intl-v2
+
define Device/xiaomi_mi-router-4c
IMAGE_SIZE := 14976k
DEVICE_VENDOR := Xiaomi
@@ -1127,6 +1136,21 @@ define Device/xiaomi_mi-ra75
endef
TARGET_DEVICES += xiaomi_mi-ra75
+define Device/yuncore_cpe200
+ IMAGE_SIZE := 7872k
+ DEVICE_VENDOR := Yuncore
+ DEVICE_MODEL := CPE200
+ DEVICE_PACKAGES := -kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap kmod-mt7663-firmware-sta
+endef
+TARGET_DEVICES += yuncore_cpe200
+
+define Device/yuncore_m300
+ IMAGE_SIZE := 7872k
+ DEVICE_VENDOR := Yuncore
+ DEVICE_MODEL := M300
+endef
+TARGET_DEVICES += yuncore_m300
+
define Device/zbtlink_zbt-we1226
IMAGE_SIZE := 7872k
DEVICE_VENDOR := Zbtlink
@@ -1136,7 +1160,7 @@ TARGET_DEVICES += zbtlink_zbt-we1226
define Device/zyxel_keenetic-extra-ii
IMAGE_SIZE := 29824k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Extra II
DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci \
kmod-usb-ledtrig-usbport
diff --git a/target/linux/ramips/image/rt305x.mk b/target/linux/ramips/image/rt305x.mk
index 815e03a8d4..f52098c733 100644
--- a/target/linux/ramips/image/rt305x.mk
+++ b/target/linux/ramips/image/rt305x.mk
@@ -1220,7 +1220,7 @@ TARGET_DEVICES += zte_mf283plus
define Device/zyxel_keenetic
SOC := rt3052
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ehci kmod-usb-ledtrig-usbport \
kmod-usb-dwc2
@@ -1233,7 +1233,7 @@ define Device/zyxel_keenetic-4g-b
$(Device/uimage-lzma-loader)
SOC := rt5350
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic 4G
DEVICE_VARIANT := B
DEFAULT := n
@@ -1244,7 +1244,7 @@ define Device/zyxel_keenetic-lite-b
$(Device/uimage-lzma-loader)
SOC := rt5350
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Lite
DEVICE_VARIANT := B
DEFAULT := n
@@ -1254,7 +1254,7 @@ TARGET_DEVICES += zyxel_keenetic-lite-b
define Device/zyxel_keenetic-start
SOC := rt5350
IMAGE_SIZE := 3776k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Start
DEFAULT := n
endef
@@ -1263,7 +1263,7 @@ TARGET_DEVICES += zyxel_keenetic-start
define Device/zyxel_nbg-419n
SOC := rt3052
IMAGE_SIZE := 3776k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG-419N
SUPPORTED_DEVICES += nbg-419n
DEFAULT := n
@@ -1274,7 +1274,7 @@ define Device/zyxel_nbg-419n-v2
$(Device/uimage-lzma-loader)
SOC := rt3352
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG-419N
DEVICE_VARIANT := v2
SUPPORTED_DEVICES += nbg-419n2
diff --git a/target/linux/ramips/image/rt3883.mk b/target/linux/ramips/image/rt3883.mk
index 0430099296..1728f84444 100644
--- a/target/linux/ramips/image/rt3883.mk
+++ b/target/linux/ramips/image/rt3883.mk
@@ -8,7 +8,8 @@ endef
define Device/asus_rt-n56u
SOC := rt3662
IMAGE_SIZE := 7872k
- IMAGE/sysupgrade.bin += | mkrtn56uimg -s
+ IMAGE/sysupgrade.bin := $$(sysupgrade_bin) | check-size | \
+ mkrtn56uimg -s | append-metadata
DEVICE_VENDOR := ASUS
DEVICE_MODEL := RT-N56U
DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk
index f32b82aef8..ced479dc93 100644
--- a/target/linux/ramips/modules.mk
+++ b/target/linux/ramips/modules.mk
@@ -4,6 +4,27 @@
OTHER_MENU:=Other modules
+define KernelPackage/mmc-mtk
+ SUBMENU:=Other modules
+ TITLE:=MediaTek SD/MMC Card Interface support
+ DEPENDS:=@(TARGET_ramips_mt7620||TARGET_ramips_mt76x8||TARGET_ramips_mt7621) +kmod-mmc
+ KCONFIG:= \
+ CONFIG_MMC \
+ CONFIG_MMC_MTK \
+ CONFIG_MMC_CQHCI
+ FILES:= \
+ $(LINUX_DIR)/drivers/mmc/host/cqhci.ko \
+ $(LINUX_DIR)/drivers/mmc/host/mtk-sd.ko
+ AUTOLOAD:=$(call AutoProbe,cqhci mtk-sd,1)
+endef
+
+define KernelPackage/mmc-mtk/description
+ MediaTek(R) Secure digital and Multimedia card Interface.
+ This is needed if support for any SD/SDIO/MMC devices is required.
+endef
+
+$(eval $(call KernelPackage,mmc-mtk))
+
define KernelPackage/pwm-mediatek-ramips
SUBMENU:=Other modules
TITLE:=MT7628 PWM
diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/02_network b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
index d23ec76327..577f77cb93 100644
--- a/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
@@ -257,6 +257,10 @@ ramips_setup_interfaces()
ucidef_add_switch "switch0" \
"0:lan:4" "1:lan:3" "2:lan:2" "5:lan:1" "4:wan" "6@eth0"
;;
+ wavlink,wl-wn531g3-a2)
+ ucidef_add_switch "switch0" \
+ "0:lan:4" "1:lan:3" "2:lan:2" "5:lan:1" "4:wan" "6@eth0"
+ ;;
wavlink,wl-wn535k1)
ucidef_add_switch "switch0" \
"2:lan:2" "5:lan:1" "4:wan" "6@eth0"
@@ -431,6 +435,7 @@ ramips_setup_macs()
wan_mac=$(macaddr_add "$(mtd_get_mac_binary rom 0xf100)" 1)
;;
wavlink,wl-wn531g3|\
+ wavlink,wl-wn531g3-a2|\
zbtlink,zbt-we1026-5g-16m)
label_mac=$(mtd_get_mac_binary factory 0x4)
;;
diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches b/target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches
index 5588113548..6d3cc61aca 100644
--- a/target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches
+++ b/target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches
@@ -7,30 +7,30 @@ board=$(board_name)
case "$board" in
bolt,bl100)
- ucidef_add_gpio_switch "modem_enable" "Enable LTE Modem" "28" "1"
+ ucidef_add_gpio_switch "modem_enable" "Enable LTE Modem" "540" "1"
;;
dlink,dir-510l)
- ucidef_add_gpio_switch "usb_enable1" "USB 1A enable" "12" "0"
- ucidef_add_gpio_switch "usb_enable05" "USB 0.5A enable" "13" "1"
+ ucidef_add_gpio_switch "usb_enable1" "USB 1A enable" "524" "0"
+ ucidef_add_gpio_switch "usb_enable05" "USB 0.5A enable" "525" "1"
;;
dlink,dwr-960|\
dlink,dwr-961-a1)
- ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "0" "1"
+ ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "512" "1"
;;
head-weblink,hdrm200)
- ucidef_add_gpio_switch "sim_switch" "SIM slot switch" "0"
- ucidef_add_gpio_switch "io1" "I/O 1" "1"
- ucidef_add_gpio_switch "io2" "I/O 2" "2"
- ucidef_add_gpio_switch "io3" "I/O 3" "11"
- ucidef_add_gpio_switch "io4" "I/O 4" "14"
- ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "21" "1"
+ ucidef_add_gpio_switch "sim_switch" "SIM slot switch" "512"
+ ucidef_add_gpio_switch "io1" "I/O 1" "513"
+ ucidef_add_gpio_switch "io2" "I/O 2" "514"
+ ucidef_add_gpio_switch "io3" "I/O 3" "523"
+ ucidef_add_gpio_switch "io4" "I/O 4" "526"
+ ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "533" "1"
;;
lb-link,bl-w1200)
- ucidef_add_gpio_switch "eth_leds_enable" "ETH LEDs enable" "10" "1"
+ ucidef_add_gpio_switch "eth_leds_enable" "ETH LEDs enable" "522" "1"
;;
zbtlink,zbt-we826-e)
- ucidef_add_gpio_switch "sim_switch" "SIM slot switch" "13"
- ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "14" "1"
+ ucidef_add_gpio_switch "sim_switch" "SIM slot switch" "525"
+ ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "526" "1"
;;
esac
diff --git a/target/linux/ramips/mt7620/config-6.6 b/target/linux/ramips/mt7620/config-6.6
index bf96543344..20bba0c5a4 100644
--- a/target/linux/ramips/mt7620/config-6.6
+++ b/target/linux/ramips/mt7620/config-6.6
@@ -30,6 +30,7 @@ CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -58,8 +59,7 @@ CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
@@ -82,6 +82,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
# CONFIG_GPIO_MT7621 is not set
CONFIG_GPIO_RALINK=y
CONFIG_GPIO_WATCHDOG=y
@@ -185,6 +186,8 @@ CONFIG_RANDSTRUCT_NONE=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RESET_CONTROLLER=y
CONFIG_SERIAL_8250_RT288X=y
CONFIG_SERIAL_MCTRL_GPIO=y
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds
index 21b1e8ea91..9a77b1b1bc 100644
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds
@@ -94,6 +94,7 @@ dlink,dap-x1860-a1)
dlink,dir-1960-a1|\
dlink,dir-2055-a1|\
dlink,dir-2150-a1|\
+dlink,dir-2150-r1|\
dlink,dir-2640-a1|\
dlink,dir-2660-a1)
ucidef_set_led_netdev "wan" "wan" "white:wan" "wan"
@@ -187,6 +188,9 @@ netgear,r7450)
netgear,wax202)
ucidef_set_led_netdev "internet" "Internet" "green:net" "wan"
;;
+netis,n6)
+ ucidef_set_led_netdev "wan" "wan" "green:wan" "wan" "link tx rx"
+ ;;
oraybox,x3a)
ucidef_set_led_netdev "wan" "wan link" "red:status" "wan"
ucidef_set_led_netdev "lan" "lan link" "green:status" "br-lan"
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
index 386a3bb41d..12098f0bbf 100644
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
@@ -47,6 +47,7 @@ ramips_setup_interfaces()
mikrotik,routerboard-m11g|\
netgear,eax12|\
netgear,ex6150|\
+ netgear,wax214v2|\
sercomm,na502|\
sercomm,na502s|\
thunder,timecloud|\
@@ -60,12 +61,15 @@ ramips_setup_interfaces()
ubnt,unifi-nanohd|\
yuncore,fap690|\
wavlink,wl-wn573hx1|\
+ wodesys,wd-r1802u|\
zyxel,nwa50ax|\
zyxel,nwa55axe)
ucidef_set_interface_lan "lan"
;;
asiarf,ap7621-001|\
+ dna,valokuitu-plus-ex400|\
humax,e10|\
+ keenetic,kn-3510|\
openfi,5pro|\
wavlink,ws-wn572hp3-4g|\
winstars,ws-wn583a6)
@@ -74,6 +78,7 @@ ramips_setup_interfaces()
asiarf,ap7621-nv1|\
beeline,smartbox-flash|\
beeline,smartbox-giga|\
+ elecom,wmc-x1800gst|\
elecom,wrc-x1800gs|\
glinet,gl-mt1300|\
iodata,wn-deax1800gr|\
@@ -112,6 +117,9 @@ ramips_setup_interfaces()
zyxel,lte3301-plus)
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
+ elecom,wsc-x1800gs)
+ ucidef_set_interface_lan "lan1 lan2"
+ ;;
gnubee,gb-pc1)
ucidef_set_interface_lan "ethblack ethblue"
;;
@@ -140,7 +148,7 @@ ramips_setup_interfaces()
ucidef_set_interface_lan "lan0 lan1 lan2 lan3"
;;
tplink,er605-v2)
- ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4" "eth0"
+ ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan1"
;;
tplink,tl-wpa8631p-v3)
ucidef_set_interface_lan "lan1 lan2 lan3 plc0"
@@ -165,6 +173,9 @@ ramips_setup_interfaces()
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
ucidef_set_interface "qtn" ifname "eth1" protocol "static" ipaddr "1.1.1.1" netmask "255.255.255.0"
;;
+ ruijie,rg-ew1200g-pro-v1.1)
+ ucidef_set_interfaces_lan_wan "lan3 lan2 lan1" "wan"
+ ;;
comfast,cf-e390ax|\
comfast,cf-ew72-v2|\
meig,slt866)
@@ -311,6 +322,11 @@ ramips_setup_macs()
wan_mac=$label_mac
lan_mac=$(macaddr_add $label_mac 1)
;;
+ ruijie,rg-ew1200g-pro-v1.1)
+ lan_mac=$(mtd_get_mac_ascii product_info ethaddr)
+ wan_mac=$(macaddr_add "$lan_mac" 8)
+ label_mac=$lan_mac
+ ;;
mts,wg430223)
wan_mac=$(mtd_get_mac_encrypted_arcadyan "board_data")
label_mac=$wan_mac
@@ -325,6 +341,10 @@ ramips_setup_macs()
wan_mac=$(macaddr_add "$lan_mac" 1)
label_mac=$lan_mac
;;
+ netgear,wax214v2)
+ lan_mac=$(mtd_get_mac_ascii Config ethaddr)
+ label_mac=$lan_mac
+ ;;
yuncore,ax820)
label_mac=$(mtd_get_mac_binary Factory 0x4)
;;
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches b/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
index 22cf272429..b8f2922f48 100644
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
@@ -7,10 +7,10 @@ board=$(board_name)
case "$board" in
mikrotik,routerboard-760igs)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "497"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "529"
;;
telco-electronics,x1)
- ucidef_add_gpio_switch "modem_reset" "Modem Reset" "496"
+ ucidef_add_gpio_switch "modem_reset" "Modem Reset" "528"
;;
tozed,zlt-s12-pro)
ucidef_add_gpio_switch "lt72_power" "Power LTE modem" "lt72_power" "1"
@@ -20,14 +20,14 @@ tplink,eap615-wall-v1)
ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "poe-passthrough"
;;
ubnt,edgerouter-x)
- ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "480"
+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "512"
;;
ubnt,edgerouter-x-sfp)
- ucidef_add_gpio_switch "poe_power_port0" "PoE Power Port0" "400"
- ucidef_add_gpio_switch "poe_power_port1" "PoE Power Port1" "401"
- ucidef_add_gpio_switch "poe_power_port2" "PoE Power Port2" "402"
- ucidef_add_gpio_switch "poe_power_port3" "PoE Power Port3" "403"
- ucidef_add_gpio_switch "poe_power_port4" "PoE Power Port4" "404"
+ ucidef_add_gpio_switch "poe_power_port0" "PoE Power Port0" "608"
+ ucidef_add_gpio_switch "poe_power_port1" "PoE Power Port1" "609"
+ ucidef_add_gpio_switch "poe_power_port2" "PoE Power Port2" "610"
+ ucidef_add_gpio_switch "poe_power_port3" "PoE Power Port3" "611"
+ ucidef_add_gpio_switch "poe_power_port4" "PoE Power Port4" "612"
;;
zyxel,lte3301-plus|\
zyxel,lte5398-m904)
@@ -35,10 +35,10 @@ zyxel,lte5398-m904)
ucidef_add_gpio_switch "lte_power" "Power LTE modem" "lte_power" "1"
;;
zyxel,nr7101)
- ucidef_add_gpio_switch "lte_reset" "Reset LTE/5G modem" "483"
+ ucidef_add_gpio_switch "lte_reset" "Reset LTE/5G modem" "515"
;;
zyxel,wap6805)
- ucidef_add_gpio_switch "qtn_power" "Quantenna Module Power" "496" "1"
+ ucidef_add_gpio_switch "qtn_power" "Quantenna Module Power" "528" "1"
;;
esac
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version b/target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version
index c510dfd81a..acc69021d0 100644
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version
@@ -11,6 +11,9 @@ case "$(board_name)" in
iptime,ax2004m)
ucidef_set_compat_version "2.0"
;;
+ tplink,er605-v2)
+ ucidef_set_compat_version "1.2"
+ ;;
*)
ucidef_set_compat_version "1.1"
;;
diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/firmware/11-mt76-caldata b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/firmware/11-mt76-caldata
new file mode 100644
index 0000000000..b34678d355
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/firmware/11-mt76-caldata
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+[ -e /lib/firmware/$FIRMWARE ] && exit 0
+
+. /lib/functions/caldata.sh
+
+board=$(board_name)
+
+case "$FIRMWARE" in
+"mediatek/mt7915_eeprom_dbdc.bin")
+ case "$board" in
+ netis,n6)
+ EEPROM=/lib/firmware/$FIRMWARE
+ head -c $((0xe00)) /dev/mtd2 > $EEPROM
+ printf "\x92" | \
+ dd of=$EEPROM seek=$((0x190)) bs=1 conv=notrunc \
+ 2>/dev/null
+ ;;
+ esac
+ ;;
+esac
diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate
index 6504dc81a5..0e7ff41453 100644
--- a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate
+++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate
@@ -63,7 +63,8 @@ netgear,wac104|\
netgear,wndr3700-v5)
migrate_radio '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0' '1e140000.pcie/pci0000:00/0000:00:02.0/0000:02:00.0'
;;
-zbtlink,zbt-we1326)
+zbtlink,zbt-we1326|\
+zbtlink,zbt-we3526)
migrate_radio '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0' '1e140000.pcie/pci0000:00/0000:00:02.0/0000:02:00.0'
migrate_radio '1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0' '1e140000.pcie/pci0000:00/0000:00:01.0/0000:01:00.0'
;;
diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
index 9350d67466..4a056623ab 100644
--- a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
+++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
@@ -126,6 +126,10 @@ case "$board" in
[ "$PHYNBR" = "1" ] && \
macaddr_setbit_la "$(mtd_get_mac_binary Factory 0x4)" > /sys${DEVPATH}/macaddress
;;
+ keenetic,kn-3510)
+ [ "$PHYNBR" = "1" ] && \
+ macaddr_setbit_la "$(mtd_get_mac_binary rf-eeprom 0x4)" > /sys${DEVPATH}/macaddress
+ ;;
linksys,e5600|\
linksys,ea6350-v4|\
linksys,ea7300-v1|\
@@ -153,6 +157,19 @@ case "$board" in
[ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 3 > /sys${DEVPATH}/macaddress
;;
+ netgear,wax214v2)
+ hw_mac_addr=$(mtd_get_mac_ascii Config ethaddr)
+ [ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 3 > /sys${DEVPATH}/macaddress
+ ;;
+ netis,n6)
+ hw_mac_addr="$(mtd_get_mac_binary Factory 0x4)"
+ hw_mac_addr=$(macaddr_setbit $hw_mac_addr 28)
+ hw_mac_2g=$(macaddr_unsetbit $hw_mac_addr 26)
+ hw_mac_5g=$(macaddr_setbit $hw_mac_addr 27)
+ [ "$PHYNBR" = "0" ] && echo -n "$hw_mac_2g" > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" = "1" ] && echo -n "$hw_mac_5g" > /sys${DEVPATH}/macaddress
+ ;;
mercusys,mr70x-v1|\
tplink,archer-ax23-v1)
hw_mac_addr="$(mtd_get_mac_binary config 0x8)"
@@ -176,6 +193,11 @@ case "$board" in
[ "$PHYNBR" = "0" ] && \
macaddr_setbit_la "$(get_mac_label)" > /sys${DEVPATH}/macaddress
;;
+ ruijie,rg-ew1200g-pro-v1.1)
+ hw_mac_addr="$(mtd_get_mac_ascii product_info ethaddr)"
+ [ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 1 > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
+ ;;
snr,snr-cpe-me2-sfp)
hw_mac_addr="$(mtd_get_mac_binary factory 0x8004)"
[ "$PHYNBR" = "1" ] && echo -n "$hw_mac_addr" > /sys${DEVPATH}/macaddress
diff --git a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
index 06846cd4ca..b83223e7dd 100755
--- a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
+++ b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
@@ -32,6 +32,10 @@ boot() {
samknows,whitebox-v8)
fw_setenv bootcount 0
;;
+ dna,valokuitu-plus-ex400)
+ fw_setenv boot_cnt_primary 0
+ fw_setenv boot_cnt_alt 0
+ ;;
zyxel,lte3301-plus)
[ $(printf %d $(fw_printenv -n DebugFlag)) -gt 0 ] || fw_setenv DebugFlag 1
[ $(printf %d $(fw_printenv -n Image1Stable)) -gt 0 ] || fw_setenv Image1Stable 1
diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/dna.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/dna.sh
new file mode 100644
index 0000000000..d699516ff6
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/dna.sh
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2023 Mauri Sandberg
+#
+
+# The vendor UBI is split in volumes 0-3. Volumes 0 and 1 contain U-Boot
+# environments env1 and env2, respectively. The vendor root file systems
+# are in volumes 2 (rootfs_0) and 3 (rootfs_1). Drop the two roots and
+# explicitly use rootfs_0 as a boot partition that contains the dtb and the
+# OpenWrt kernel. This is because the vendor U-Boot expects to find them there.
+# Then continue upgrade with the default method - a SquashFS rootfs will be
+# installed and the rest of UBI will be used as an overlay.
+
+# The 'kernel' inside the sysupgrage.tar is an UBIFS image that contains
+# /boot/dtb and /boot/kernel. The 'root' is an OpenWrt SquashFS root
+
+. /lib/functions.sh
+. /lib/upgrade/nand.sh
+
+dna_do_upgrade () {
+ tar -xaf $1
+
+ # get the size of the new bootfs
+ local _bootfs_size=$(wc -c < ./sysupgrade-dna_valokuitu-plus-ex400/kernel)
+ [ -n "$_bootfs_size" -a "$_bootfs_size" -gt "0" ] || nand_do_upgrade_failed
+
+ # remove existing rootfses and recreate rootfs_0
+ ubirmvol /dev/ubi0 --name=rootfs_0 > /dev/null 2>&1
+ ubirmvol /dev/ubi0 --name=rootfs_1 > /dev/null 2>&1
+ ubirmvol /dev/ubi0 --name=rootfs > /dev/null 2>&1
+ ubirmvol /dev/ubi0 --name=rootfs_data > /dev/null 2>&1
+ ubimkvol /dev/ubi0 --type=static --size=${_bootfs_size} --name=rootfs_0
+
+ # update the rootfs_0 contents
+ local _kern_ubivol=$( nand_find_volume "ubi0" "rootfs_0" )
+ ubiupdatevol /dev/${_kern_ubivol} sysupgrade-dna_valokuitu-plus-ex400/kernel
+
+ fw_setenv root_vol rootfs_0
+ fw_setenv boot_cnt_primary 0
+ fw_setenv boot_cnt_alt 0
+
+ # proceed to upgrade the default way
+ CI_KERNPART=none
+ nand_do_upgrade "$1"
+}
diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
index 32dad72944..97887ca8c3 100755
--- a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
@@ -85,11 +85,14 @@ platform_do_upgrade() {
dlink,dir-1960-a1|\
dlink,dir-2055-a1|\
dlink,dir-2150-a1|\
+ dlink,dir-2150-r1|\
dlink,dir-2640-a1|\
dlink,dir-2660-a1|\
dlink,dir-3040-a1|\
dlink,dir-3060-a1|\
dlink,dir-853-a3|\
+ elecom,wmc-x1800gst|\
+ elecom,wsc-x1800gs|\
etisalat,s3|\
h3c,tx1800-plus|\
h3c,tx1801-plus|\
@@ -100,6 +103,7 @@ platform_do_upgrade() {
iptime,ax2004m|\
iptime,t5004|\
jcg,q20|\
+ keenetic,kn-3510|\
linksys,e5600|\
linksys,e7350|\
linksys,ea6350-v4|\
@@ -122,6 +126,8 @@ platform_do_upgrade() {
netgear,wac104|\
netgear,wac124|\
netgear,wax202|\
+ netgear,wax214v2|\
+ netis,n6|\
netis,wf2881|\
raisecom,msg1500-x-00|\
rostelecom,rt-fe-1a|\
@@ -148,6 +154,9 @@ platform_do_upgrade() {
buffalo,wsr-2533dhpls)
buffalo_do_upgrade "$1"
;;
+ dna,valokuitu-plus-ex400)
+ dna_do_upgrade "$1"
+ ;;
elecom,wrc-x1800gs)
[ "$(fw_printenv -n bootmenu_delay)" != "0" ] || \
fw_setenv bootmenu_delay 3
diff --git a/target/linux/ramips/mt7621/config-6.6 b/target/linux/ramips/mt7621/config-6.6
index 219e61a467..75d3f300fd 100644
--- a/target/linux/ramips/mt7621/config-6.6
+++ b/target/linux/ramips/mt7621/config-6.6
@@ -34,6 +34,7 @@ CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_MIPSR2_IRQ_EI=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_RMAP=y
@@ -64,8 +65,7 @@ CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
@@ -128,7 +128,6 @@ CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MIKROTIK=y
CONFIG_MIKROTIK_RB_SYSFS=y
-# CONFIG_NVMEM_LAYOUT_MIKROTIK is not set
CONFIG_MIPS=y
CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
@@ -201,6 +200,7 @@ CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
+# CONFIG_NVMEM_LAYOUT_MIKROTIK is not set
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
index 3e0b70cc20..5ea668de01 100644
--- a/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
+++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
@@ -18,7 +18,9 @@ asus,rt-n11p-b1|\
asus,rt-n12-vp-b1|\
netgear,r6020|\
netgear,r6080|\
-netgear,r6120)
+netgear,r6120|\
+yuncore,cpe200|\
+yuncore,m300)
ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0xf"
ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
;;
@@ -171,7 +173,8 @@ wavlink,wl-wn578a2)
ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
;;
xiaomi,mi-router-4a-100m|\
-xiaomi,mi-router-4a-100m-intl)
+xiaomi,mi-router-4a-100m-intl|\
+xiaomi,mi-router-4a-100m-intl-v2)
ucidef_set_led_switch "wan" "WAN" "blue:wan" "switch0" "0x01"
;;
xiaomi,mi-router-4c)
diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
index c44361a439..cb0983b9dc 100644
--- a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
@@ -81,7 +81,8 @@ ramips_setup_interfaces()
buffalo,wcr-1166ds|\
elecom,wrc-1167fs|\
wavlink,wl-wn577a2|\
- wavlink,wl-wn578a2)
+ wavlink,wl-wn578a2|\
+ yuncore,m300)
ucidef_add_switch "switch0" \
"3:lan" "4:wan" "6@eth0"
;;
@@ -186,7 +187,8 @@ ramips_setup_interfaces()
"0:wan" "3:lan" "4:lan" "6@eth0"
;;
xiaomi,mi-router-4a-100m|\
- xiaomi,mi-router-4a-100m-intl)
+ xiaomi,mi-router-4a-100m-intl|\
+ xiaomi,mi-router-4a-100m-intl-v2)
ucidef_add_switch "switch0" \
"4:lan:1" "2:lan:2" "0:wan" "6@eth0"
;;
@@ -202,6 +204,10 @@ ramips_setup_interfaces()
ucidef_add_switch "switch0" \
"0:lan:2" "2:lan:1" "4:wan" "6@eth0"
;;
+ yuncore,cpe200)
+ ucidef_add_switch "switch0" \
+ "0:lan" "4:wan" "6@eth0"
+ ;;
zbtlink,zbt-we1226)
ucidef_add_switch "switch0" \
"0:lan:2" "1:lan:1" "4:wan" "6@eth0"
@@ -323,6 +329,7 @@ ramips_setup_macs()
;;
xiaomi,mi-router-4a-100m|\
xiaomi,mi-router-4a-100m-intl|\
+ xiaomi,mi-router-4a-100m-intl-v2|\
xiaomi,mi-router-4c)
wan_mac=$(mtd_get_mac_binary factory 0x4)
;;
diff --git a/target/linux/ramips/mt76x8/config-6.6 b/target/linux/ramips/mt76x8/config-6.6
index db1281ad54..b9dc8525df 100644
--- a/target/linux/ramips/mt76x8/config-6.6
+++ b/target/linux/ramips/mt76x8/config-6.6
@@ -29,6 +29,7 @@ CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -56,8 +57,7 @@ CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
@@ -84,6 +84,8 @@ CONFIG_GPIO_CDEV=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_MT7621=y
# CONFIG_GPIO_RALINK is not set
+CONFIG_GPIO_WATCHDOG=y
+# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
diff --git a/target/linux/ramips/patches-6.6/100-clk-ralink-mtmips-fix-clock-plan-for-Ralink-SoC-RT3883.patch b/target/linux/ramips/patches-6.6/100-clk-ralink-mtmips-fix-clock-plan-for-Ralink-SoC-RT3883.patch
new file mode 100644
index 0000000000..a3d58b78f6
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/100-clk-ralink-mtmips-fix-clock-plan-for-Ralink-SoC-RT3883.patch
@@ -0,0 +1,45 @@
+Subject: [PATCH] clk: ralink: mtmips: fix clock plan for Ralink SoC RT3883
+Date: Tue, 6 Aug 2024 16:29:02 +0200
+Message-Id: <20240806142902.224164-1-sergio.paracuellos@gmail.com>
+
+Clock plan for Ralink SoC RT3883 needs an extra 'periph' clock to properly
+set some peripherals that has this clock as their parent. When this driver
+was mainlined we could not find any active users of this SoC so we cannot
+perform any real tests for it. Now, one user of a Belkin f9k1109 version 1
+device which uses this SoC appear and reported some issues in openWRT:
+- https://github.com/openwrt/openwrt/issues/16054
+The peripherals that are wrong are 'uart', 'i2c', 'i2s' and 'uartlite' which
+has a not defined 'periph' clock as parent. Hence, introduce it to have a
+properly working clock plan for this SoC.
+
+Fixes: 6f3b15586eef ("clk: ralink: add clock and reset driver for MTMIPS SoCs")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+---
+ drivers/clk/ralink/clk-mtmips.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/ralink/clk-mtmips.c
++++ b/drivers/clk/ralink/clk-mtmips.c
+@@ -267,6 +267,11 @@ static struct mtmips_clk_fixed rt305x_fi
+ CLK_FIXED("xtal", NULL, 40000000)
+ };
+
++static struct mtmips_clk_fixed rt3383_fixed_clocks[] = {
++ CLK_FIXED("xtal", NULL, 40000000),
++ CLK_FIXED("periph", "xtal", 40000000)
++};
++
+ static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {
+ CLK_FIXED("periph", "xtal", 40000000)
+ };
+@@ -779,8 +784,8 @@ static const struct mtmips_clk_data rt33
+ static const struct mtmips_clk_data rt3883_clk_data = {
+ .clk_base = rt3883_clks_base,
+ .num_clk_base = ARRAY_SIZE(rt3883_clks_base),
+- .clk_fixed = rt305x_fixed_clocks,
+- .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
++ .clk_fixed = rt3383_fixed_clocks,
++ .num_clk_fixed = ARRAY_SIZE(rt3383_fixed_clocks),
+ .clk_factor = NULL,
+ .num_clk_factor = 0,
+ .clk_periph = rt5350_pherip_clks,
diff --git a/target/linux/ramips/patches-6.6/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch b/target/linux/ramips/patches-6.6/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch
index 172cf98ad1..36925b8326 100644
--- a/target/linux/ramips/patches-6.6/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch
+++ b/target/linux/ramips/patches-6.6/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch
@@ -6,29 +6,10 @@ Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k
Signed-off-by: John Crispin <blogic@openwrt.org>
---
- arch/mips/ralink/Kconfig | 5 +++++
- 1 file changed, 5 insertions(+)
+ arch/mips/kernel/cevt-r4k.c | 43 +++++++++++++++++++++++++++++++++++++
+ arch/mips/ralink/Kconfig | 5 +++++
+ 2 files changed, 48 insertions(+)
---- a/arch/mips/ralink/Kconfig
-+++ b/arch/mips/ralink/Kconfig
-@@ -1,12 +1,17 @@
- # SPDX-License-Identifier: GPL-2.0
- if RALINK
-
-+config CEVT_SYSTICK_QUIRK
-+ bool
-+ default n
-+
- config CLKEVT_RT3352
- bool
- depends on SOC_RT305X || SOC_MT7620
- default y
- select TIMER_OF
- select CLKSRC_MMIO
-+ select CEVT_SYSTICK_QUIRK
-
- config RALINK_ILL_ACC
- bool
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -16,6 +16,31 @@
@@ -73,11 +54,28 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
unsigned int cpu = smp_processor_id();
struct clock_event_device *cd;
unsigned int irq, min_delta;
-@@ -322,11 +349,16 @@ int r4k_clockevent_init(void)
+@@ -303,6 +330,15 @@ int r4k_clockevent_init(void)
+ if (!c0_compare_int_usable())
+ return -ENXIO;
+
++#ifdef CONFIG_CEVT_SYSTICK_QUIRK
++ /*
++ * With vectored interrupts things are getting platform specific.
++ * get_c0_compare_int is a hook to allow a platform to return the
++ * interrupt number of its liking.
++ */
++ irq = get_c0_compare_int();
++#endif
++
+ cd = &per_cpu(mips_clockevent_device, cpu);
+
+ cd->name = "MIPS";
+@@ -314,11 +350,17 @@ int r4k_clockevent_init(void)
+
cd->rating = 300;
- cd->irq = irq;
cd->cpumask = cpumask_of(cpu);
+#ifdef CONFIG_CEVT_SYSTICK_QUIRK
++ cd->irq = irq;
+ cd->set_state_shutdown = mips_state_shutdown;
+ cd->set_state_oneshot = mips_state_oneshot;
+#endif
@@ -90,7 +88,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
if (cp0_timer_irq_installed)
return 0;
-@@ -335,6 +367,7 @@ int r4k_clockevent_init(void)
+@@ -334,6 +376,7 @@ int r4k_clockevent_init(void)
if (request_irq(irq, c0_compare_interrupt, flags, "timer",
c0_compare_interrupt))
pr_err("Failed to request irq %d (timer)\n", irq);
@@ -98,3 +96,23 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return 0;
}
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -1,12 +1,17 @@
+ # SPDX-License-Identifier: GPL-2.0
+ if RALINK
+
++config CEVT_SYSTICK_QUIRK
++ bool
++ default n
++
+ config CLKEVT_RT3352
+ bool
+ depends on SOC_RT305X || SOC_MT7620
+ default y
+ select TIMER_OF
+ select CLKSRC_MMIO
++ select CEVT_SYSTICK_QUIRK
+
+ config RALINK_ILL_ACC
+ bool
diff --git a/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch b/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
index 51f1a5ec5e..f87edd3e67 100644
--- a/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
+++ b/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
@@ -20,7 +20,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -338,6 +338,14 @@ config MTD_NAND_QCOM
+@@ -337,6 +337,14 @@ config MTD_NAND_QCOM
Enables support for NAND flash chips on SoCs containing the EBI2 NAND
controller. This controller is found on IPQ806x SoC.
diff --git a/target/linux/ramips/patches-6.6/801-DT-Add-documentation-for-gpio-ralink.patch b/target/linux/ramips/patches-6.6/801-DT-Add-documentation-for-gpio-ralink.patch
index 93dabf8776..fdb07f84f7 100644
--- a/target/linux/ramips/patches-6.6/801-DT-Add-documentation-for-gpio-ralink.patch
+++ b/target/linux/ramips/patches-6.6/801-DT-Add-documentation-for-gpio-ralink.patch
@@ -1,22 +1,18 @@
-From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 28 Jul 2013 19:45:30 +0200
-Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink
+Subject: [PATCH 1/3] DT: Add documentation for gpio-ralink
Describe gpio-ralink binding.
Signed-off-by: John Crispin <blogic@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Cc: devicetree@vger.kernel.org
-Cc: linux-gpio@vger.kernel.org
---
- .../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++
- 1 file changed, 40 insertions(+)
+ .../devicetree/bindings/gpio/gpio-ralink.txt | 36 +++++++++++++++++++
+ 1 file changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-@@ -0,0 +1,40 @@
+@@ -0,0 +1,36 @@
+Ralink SoC GPIO controller bindings
+
+Required properties:
@@ -34,13 +30,10 @@ Cc: linux-gpio@vger.kernel.org
+ SoC type. Register offsets need to be in this order.
+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
+
-+Optional properties:
-+- ralink,gpio-base : Specify the GPIO chips base number
-+
+Example:
+
+ gpio0: gpio@600 {
-+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
++ compatible = "ralink,rt2880-gpio";
+
+ #gpio-cells = <2>;
+ gpio-controller;
@@ -51,7 +44,6 @@ Cc: linux-gpio@vger.kernel.org
+ interrupts = <6>;
+
+ ngpios = <24>;
-+ ralink,gpio-base = <0>;
+ ralink,register-map = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
diff --git a/target/linux/ramips/patches-6.6/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch b/target/linux/ramips/patches-6.6/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch
index 75a7374054..2930c57f40 100644
--- a/target/linux/ramips/patches-6.6/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch
+++ b/target/linux/ramips/patches-6.6/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch
@@ -1,59 +1,28 @@
-From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 4 Aug 2014 20:36:29 +0200
-Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC
+Subject: [PATCH 2/3] GPIO: MIPS: ralink: add gpio driver for ralink SoC
Add gpio driver for Ralink SoC. This driver makes the gpio core on
RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
Signed-off-by: John Crispin <blogic@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Cc: linux-gpio@vger.kernel.org
---
- arch/mips/include/asm/mach-ralink/gpio.h | 24 ++
- drivers/gpio/Kconfig | 6 +
- drivers/gpio/Makefile | 1 +
- drivers/gpio/gpio-ralink.c | 355 ++++++++++++++++++++++++++++++
- 4 files changed, 386 insertions(+)
- create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
+ drivers/gpio/Kconfig | 7 +
+ drivers/gpio/Makefile | 1 +
+ drivers/gpio/gpio-ralink.c | 273 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 281 insertions(+)
create mode 100644 drivers/gpio/gpio-ralink.c
---- /dev/null
-+++ b/arch/mips/include/asm/mach-ralink/gpio.h
-@@ -0,0 +1,24 @@
-+/*
-+ * Ralink SoC GPIO API support
-+ *
-+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ */
-+
-+#ifndef __ASM_MACH_RALINK_GPIO_H
-+#define __ASM_MACH_RALINK_GPIO_H
-+
-+#define ARCH_NR_GPIOS 128
-+#include <asm-generic/gpio.h>
-+
-+#define gpio_get_value __gpio_get_value
-+#define gpio_set_value __gpio_set_value
-+#define gpio_cansleep __gpio_cansleep
-+#define gpio_to_irq __gpio_to_irq
-+
-+#endif /* __ASM_MACH_RALINK_GPIO_H */
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
-@@ -594,6 +594,12 @@ config GPIO_SNPS_CREG
+@@ -594,6 +594,13 @@ config GPIO_SNPS_CREG
where only several fields in register belong to GPIO lines and
each GPIO line owns a field with different length and on/off value.
+config GPIO_RALINK
+ bool "Ralink GPIO Support"
+ depends on RALINK
++ select GPIO_GENERIC
+ help
+ Say yes here to support the Ralink SoC GPIO device
+
@@ -72,7 +41,7 @@ Cc: linux-gpio@vger.kernel.org
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
--- /dev/null
+++ b/drivers/gpio/gpio-ralink.c
-@@ -0,0 +1,341 @@
+@@ -0,0 +1,273 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
@@ -142,52 +111,6 @@ Cc: linux-gpio@vger.kernel.org
+ return ioread32(rg->membase + rg->regs[reg]);
+}
+
-+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+
-+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
-+}
-+
-+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+
-+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
-+}
-+
-+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+ unsigned long flags;
-+ u32 t;
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
-+ t &= ~BIT(offset);
-+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int ralink_gpio_direction_output(struct gpio_chip *chip,
-+ unsigned offset, int value)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+ unsigned long flags;
-+ u32 t;
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ ralink_gpio_set(chip, offset, value);
-+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
-+ t |= BIT(offset);
-+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+
-+ return 0;
-+}
-+
+static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
@@ -330,55 +253,35 @@ Cc: linux-gpio@vger.kernel.org
+
+static int ralink_gpio_probe(struct platform_device *pdev)
+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
+ struct ralink_gpio_chip *rg;
-+ const __be32 *ngpio, *gpiobase;
-+
-+ if (!res) {
-+ dev_err(&pdev->dev, "failed to find resource\n");
-+ return -ENOMEM;
-+ }
++ int ret;
+
-+ rg = devm_kzalloc(&pdev->dev,
-+ sizeof(struct ralink_gpio_chip), GFP_KERNEL);
++ rg = devm_kzalloc(dev, sizeof(struct ralink_gpio_chip), GFP_KERNEL);
+ if (!rg)
+ return -ENOMEM;
+
-+ rg->membase = devm_ioremap_resource(&pdev->dev, res);
-+ if (!rg->membase) {
-+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
-+ return -ENOMEM;
-+ }
++ rg->membase = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(rg->membase))
++ return PTR_ERR(rg->membase);
+
+ if (of_property_read_u8_array(np, "ralink,register-map",
+ rg->regs, GPIO_REG_MAX)) {
-+ dev_err(&pdev->dev, "failed to read register definition\n");
++ dev_err(dev, "failed to read register definition\n");
+ return -EINVAL;
+ }
+
-+ ngpio = of_get_property(np, "ngpios", NULL);
-+ if (!ngpio) {
-+ dev_err(&pdev->dev, "failed to read number of pins\n");
-+ return -EINVAL;
-+ }
-+
-+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
-+ if (gpiobase)
-+ rg->chip.base = be32_to_cpu(*gpiobase);
-+ else
-+ rg->chip.base = -1;
-+
+ spin_lock_init(&rg->lock);
+
-+ rg->chip.parent = &pdev->dev;
-+ rg->chip.label = dev_name(&pdev->dev);
-+ rg->chip.fwnode = of_node_to_fwnode(np);
-+ rg->chip.ngpio = be32_to_cpu(*ngpio);
-+ rg->chip.direction_input = ralink_gpio_direction_input;
-+ rg->chip.direction_output = ralink_gpio_direction_output;
-+ rg->chip.get = ralink_gpio_get;
-+ rg->chip.set = ralink_gpio_set;
++ ret = bgpio_init(&rg->chip, dev, 4,
++ rg->membase + rg->regs[GPIO_REG_DATA],
++ rg->membase + rg->regs[GPIO_REG_SET],
++ rg->membase + rg->regs[GPIO_REG_RESET],
++ rg->membase + rg->regs[GPIO_REG_DIR],
++ NULL, 0);
++ if (ret)
++ return dev_err_probe(dev, ret, "bgpio_init() failed\n");
+ rg->chip.request = gpiochip_generic_request;
+ rg->chip.to_irq = ralink_gpio_to_irq;
+ rg->chip.free = gpiochip_generic_free;
@@ -386,11 +289,9 @@ Cc: linux-gpio@vger.kernel.org
+ /* set polarity to low for all lines */
+ rt_gpio_w32(rg, GPIO_REG_POL, 0);
+
-+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
-+
+ ralink_gpio_irq_init(np, rg);
+
-+ return gpiochip_add(&rg->chip);
++ return devm_gpiochip_add_data(dev, &rg->chip, rg);
+}
+
+static const struct of_device_id ralink_gpio_match[] = {
diff --git a/target/linux/ramips/patches-6.6/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch b/target/linux/ramips/patches-6.6/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch
index 8520ce32ff..54dadc735d 100644
--- a/target/linux/ramips/patches-6.6/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch
+++ b/target/linux/ramips/patches-6.6/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch
@@ -1,7 +1,6 @@
-From 57fa7f2f4ef6f78ce1d30509c0d111aa3791b524 Mon Sep 17 00:00:00 2001
From: Daniel Santos <daniel.santos@pobox.com>
Date: Sun, 4 Nov 2018 20:24:32 -0600
-Subject: gpio-ralink: Add support for GPIO as interrupt-controller
+Subject: [PATCH 3/3] gpio-ralink: Add support for GPIO as interrupt-controller
Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
---
@@ -11,17 +10,17 @@ Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
--- a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-@@ -17,6 +17,9 @@ Required properties:
-
- Optional properties:
- - ralink,gpio-base : Specify the GPIO chips base number
+@@ -14,6 +14,9 @@ Required properties:
+ - ralink,register-map : The register layout depends on the GPIO bank and actual
+ SoC type. Register offsets need to be in this order.
+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
+- interrupt-controller : marks this as an interrupt controller
+- #interrupt-cells : a standard two-cell interrupt flag, see
+ interrupt-controller/interrupts.txt
Example:
-@@ -28,6 +31,9 @@ Example:
+@@ -25,6 +28,9 @@ Example:
reg = <0x600 0x34>;
@@ -33,7 +32,7 @@ Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
--- a/drivers/gpio/gpio-ralink.c
+++ b/drivers/gpio/gpio-ralink.c
-@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d
+@@ -174,7 +174,7 @@ static int gpio_map(struct irq_domain *d
}
static const struct irq_domain_ops irq_domain_ops = {
diff --git a/target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch b/target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch
new file mode 100644
index 0000000000..84b4571b48
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch
@@ -0,0 +1,1190 @@
+From 576623d706613feec2392ef16b84e23a46200552 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+Date: Fri, 1 Mar 2024 14:29:24 +0100
+Subject: [PATCH] pinctrl: Add driver for Awinic AW9523/B I2C GPIO Expander
+
+The Awinic AW9523(B) is a multi-function I2C gpio expander in a
+TQFN-24L package, featuring PWM (max 37mA per pin, or total max
+power 3.2Watts) for LED driving capability.
+
+It has two ports with 8 pins per port (for a total of 16 pins),
+configurable as either PWM with 1/256 stepping or GPIO input/output,
+1.8V logic input; each GPIO can be configured as input or output
+independently from each other.
+
+This IC also has an internal interrupt controller, which is capable
+of generating an interrupt for each GPIO, depending on the
+configuration, and will raise an interrupt on the INTN pin to
+advertise this to an external interrupt controller.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Link: https://lore.kernel.org/r/20210624214458.68716-2-mail@david-bauer.net
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240301-awinic-aw9523-v8-1-7ec572f5dfb4@linaro.org
+---
+ drivers/pinctrl/Kconfig | 18 +
+ drivers/pinctrl/Makefile | 1 +
+ drivers/pinctrl/pinctrl-aw9523.c | 1118 ++++++++++++++++++++++++++++++
+ 3 files changed, 1137 insertions(+)
+ create mode 100644 drivers/pinctrl/pinctrl-aw9523.c
+
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -127,6 +127,24 @@ config PINCTRL_AXP209
+ selected.
+ Say Y to enable pinctrl and GPIO support for the AXP209 PMIC.
+
++config PINCTRL_AW9523
++ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
++ depends on OF && I2C
++ select PINMUX
++ select PINCONF
++ select GENERIC_PINCONF
++ select GPIOLIB
++ select GPIOLIB_IRQCHIP
++ select REGMAP
++ select REGMAP_I2C
++ help
++ The Awinic AW9523/AW9523B is a multi-function I2C GPIO
++ expander with PWM functionality. This driver bundles a
++ pinctrl driver to select the function muxing and a GPIO
++ driver to handle GPIO, when the GPIO function is selected.
++
++ Say yes to enable pinctrl and GPIO support for the AW9523(B).
++
+ config PINCTRL_BM1880
+ bool "Bitmain BM1880 Pinctrl driver"
+ depends on OF && (ARCH_BITMAIN || COMPILE_TEST)
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl
+ obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
+ obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
+ obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
++obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
+ obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o
+ obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
+ obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o
+--- /dev/null
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -0,0 +1,1118 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Awinic AW9523B i2c pin controller driver
++ * Copyright (c) 2020, AngeloGioacchino Del Regno
++ * <angelogioacchino.delregno@somainline.org>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/gpio/consumer.h>
++#include <linux/gpio/driver.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/mutex.h>
++#include <linux/module.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/property.h>
++#include <linux/regmap.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++
++#define AW9523_MAX_FUNCS 2
++#define AW9523_NUM_PORTS 2
++#define AW9523_PINS_PER_PORT 8
++
++/*
++ * HW needs at least 20uS for reset and at least 1-2uS to recover from
++ * reset, but we have to account for eventual board quirks, if any:
++ * for this reason, keep reset asserted for 50uS and wait for 20uS
++ * to recover from the reset.
++ */
++#define AW9523_HW_RESET_US 50
++#define AW9523_HW_RESET_RECOVERY_US 20
++
++/* Port 0: P0_0...P0_7 - Port 1: P1_0...P1_7 */
++#define AW9523_PIN_TO_PORT(pin) (pin >> 3)
++#define AW9523_REG_IN_STATE(pin) (0x00 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_OUT_STATE(pin) (0x02 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_CONF_STATE(pin) (0x04 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_INTR_DIS(pin) (0x06 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_CHIPID 0x10
++#define AW9523_VAL_EXPECTED_CHIPID 0x23
++
++#define AW9523_REG_GCR 0x11
++#define AW9523_GCR_ISEL_MASK GENMASK(0, 1)
++#define AW9523_GCR_GPOMD_MASK BIT(4)
++
++#define AW9523_REG_PORT_MODE(pin) (0x12 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_SOFT_RESET 0x7f
++#define AW9523_VAL_RESET 0x00
++
++/*
++ * struct aw9523_irq - Interrupt controller structure
++ * @lock: mutex locking for the irq bus
++ * @irqchip: structure holding irqchip params
++ * @cached_gpio: stores the previous gpio status for bit comparison
++ */
++struct aw9523_irq {
++ struct mutex lock;
++ struct irq_chip *irqchip;
++ u16 cached_gpio;
++};
++
++/*
++ * struct aw9523_pinmux - Pin mux params
++ * @name: Name of the mux
++ * @grps: Groups of the mux
++ * @num_grps: Number of groups (sizeof array grps)
++ */
++struct aw9523_pinmux {
++ const char *name;
++ const char * const *grps;
++ const u8 num_grps;
++};
++
++/*
++ * struct aw9523 - Main driver structure
++ * @dev: device handle
++ * @regmap: regmap handle for current device
++ * @i2c_lock: Mutex lock for i2c operations
++ * @reset_gpio: Hardware reset (RSTN) signal GPIO
++ * @vio_vreg: VCC regulator (Optional)
++ * @pctl: pinctrl handle for current device
++ * @gpio: structure holding gpiochip params
++ * @irq: Interrupt controller structure
++ */
++struct aw9523 {
++ struct device *dev;
++ struct regmap *regmap;
++ struct mutex i2c_lock;
++ struct gpio_desc *reset_gpio;
++ struct regulator *vio_vreg;
++ struct pinctrl_dev *pctl;
++ struct gpio_chip gpio;
++ struct aw9523_irq *irq;
++};
++
++static const struct pinctrl_pin_desc aw9523_pins[] = {
++ /* Port 0 */
++ PINCTRL_PIN(0, "gpio0"),
++ PINCTRL_PIN(1, "gpio1"),
++ PINCTRL_PIN(2, "gpio2"),
++ PINCTRL_PIN(3, "gpio3"),
++ PINCTRL_PIN(4, "gpio4"),
++ PINCTRL_PIN(5, "gpio5"),
++ PINCTRL_PIN(6, "gpio6"),
++ PINCTRL_PIN(7, "gpio7"),
++
++ /* Port 1 */
++ PINCTRL_PIN(8, "gpio8"),
++ PINCTRL_PIN(9, "gpio9"),
++ PINCTRL_PIN(10, "gpio10"),
++ PINCTRL_PIN(11, "gpio11"),
++ PINCTRL_PIN(12, "gpio12"),
++ PINCTRL_PIN(13, "gpio13"),
++ PINCTRL_PIN(14, "gpio14"),
++ PINCTRL_PIN(15, "gpio15"),
++};
++
++static int aw9523_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
++{
++ return ARRAY_SIZE(aw9523_pins);
++}
++
++static const char *aw9523_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++ unsigned int selector)
++{
++ return aw9523_pins[selector].name;
++}
++
++static int aw9523_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++ unsigned int selector,
++ const unsigned int **pins,
++ unsigned int *num_pins)
++{
++ *pins = &aw9523_pins[selector].number;
++ *num_pins = 1;
++ return 0;
++}
++
++static const struct pinctrl_ops aw9523_pinctrl_ops = {
++ .get_groups_count = aw9523_pinctrl_get_groups_count,
++ .get_group_pins = aw9523_pinctrl_get_group_pins,
++ .get_group_name = aw9523_pinctrl_get_group_name,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .dt_free_map = pinconf_generic_dt_free_map,
++};
++
++static const char * const gpio_pwm_groups[] = {
++ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15"
++};
++
++/* Warning: Do NOT reorder this array */
++static const struct aw9523_pinmux aw9523_pmx[] = {
++ {
++ .name = "pwm",
++ .grps = gpio_pwm_groups,
++ .num_grps = ARRAY_SIZE(gpio_pwm_groups),
++ },
++ {
++ .name = "gpio",
++ .grps = gpio_pwm_groups,
++ .num_grps = ARRAY_SIZE(gpio_pwm_groups),
++ },
++};
++
++static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
++{
++ return ARRAY_SIZE(aw9523_pmx);
++}
++
++static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl,
++ unsigned int sel)
++{
++ return aw9523_pmx[sel].name;
++}
++
++static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
++ const char * const **groups,
++ unsigned int * const num_groups)
++{
++ *groups = aw9523_pmx[sel].grps;
++ *num_groups = aw9523_pmx[sel].num_grps;
++ return 0;
++}
++
++static int aw9523_pmx_set_mux(struct pinctrl_dev *pctl, unsigned int fsel,
++ unsigned int grp)
++{
++ struct aw9523 *awi = pinctrl_dev_get_drvdata(pctl);
++ int ret, pin = aw9523_pins[grp].number % AW9523_PINS_PER_PORT;
++
++ if (fsel >= ARRAY_SIZE(aw9523_pmx))
++ return -EINVAL;
++
++ /*
++ * This maps directly to the aw9523_pmx array: programming a
++ * high bit means "gpio" and a low bit means "pwm".
++ */
++ mutex_lock(&awi->i2c_lock);
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_PORT_MODE(pin),
++ BIT(pin), (fsel ? BIT(pin) : 0));
++ mutex_unlock(&awi->i2c_lock);
++ return ret;
++}
++
++static const struct pinmux_ops aw9523_pinmux_ops = {
++ .get_functions_count = aw9523_pmx_get_funcs_count,
++ .get_function_name = aw9523_pmx_get_fname,
++ .get_function_groups = aw9523_pmx_get_groups,
++ .set_mux = aw9523_pmx_set_mux,
++};
++
++static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r)
++{
++ u8 reg;
++
++ switch (pcp) {
++ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ case PIN_CONFIG_BIAS_PULL_UP:
++ reg = AW9523_REG_IN_STATE(pin);
++ break;
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ reg = AW9523_REG_GCR;
++ break;
++ case PIN_CONFIG_INPUT_ENABLE:
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ reg = AW9523_REG_CONF_STATE(pin);
++ break;
++ case PIN_CONFIG_OUTPUT:
++ reg = AW9523_REG_OUT_STATE(pin);
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++ *r = reg;
++
++ return 0;
++}
++
++static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
++ unsigned long *config)
++{
++ struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
++ enum pin_config_param param = pinconf_to_config_param(*config);
++ int regbit = pin % AW9523_PINS_PER_PORT;
++ unsigned int val;
++ u8 reg;
++ int rc;
++
++ rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
++ if (rc)
++ return rc;
++
++ mutex_lock(&awi->i2c_lock);
++ rc = regmap_read(awi->regmap, reg, &val);
++ mutex_unlock(&awi->i2c_lock);
++ if (rc)
++ return rc;
++
++ switch (param) {
++ case PIN_CONFIG_BIAS_PULL_UP:
++ case PIN_CONFIG_INPUT_ENABLE:
++ case PIN_CONFIG_OUTPUT:
++ val &= BIT(regbit);
++ break;
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ val &= BIT(regbit);
++ val = !val;
++ break;
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ if (pin >= AW9523_PINS_PER_PORT)
++ val = 0;
++ else
++ val = !FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
++ break;
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ if (pin >= AW9523_PINS_PER_PORT)
++ val = 1;
++ else
++ val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++ if (val < 1)
++ return -EINVAL;
++
++ *config = pinconf_to_config_packed(param, !!val);
++
++ return rc;
++}
++
++static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
++ unsigned long *configs, unsigned int num_configs)
++{
++ struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
++ enum pin_config_param param;
++ int regbit = pin % AW9523_PINS_PER_PORT;
++ u32 arg;
++ u8 reg;
++ unsigned int mask, val;
++ int i, rc;
++
++ mutex_lock(&awi->i2c_lock);
++ for (i = 0; i < num_configs; i++) {
++ param = pinconf_to_config_param(configs[i]);
++ arg = pinconf_to_config_argument(configs[i]);
++
++ rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
++ if (rc)
++ goto end;
++
++ switch (param) {
++ case PIN_CONFIG_OUTPUT:
++ /* First, enable pin output */
++ rc = regmap_update_bits(awi->regmap,
++ AW9523_REG_CONF_STATE(pin),
++ BIT(regbit), 0);
++ if (rc)
++ goto end;
++
++ /* Then, fall through to config output level */
++ fallthrough;
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ arg = !arg;
++ fallthrough;
++ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ case PIN_CONFIG_BIAS_PULL_UP:
++ case PIN_CONFIG_INPUT_ENABLE:
++ mask = BIT(regbit);
++ val = arg ? BIT(regbit) : 0;
++ break;
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ /* Open-Drain is supported only on port 0 */
++ if (pin >= AW9523_PINS_PER_PORT) {
++ rc = -EOPNOTSUPP;
++ goto end;
++ }
++ mask = AW9523_GCR_GPOMD_MASK;
++ val = 0;
++ break;
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ /* Port 1 is always Push-Pull */
++ if (pin >= AW9523_PINS_PER_PORT) {
++ mask = 0;
++ val = 0;
++ continue;
++ }
++ mask = AW9523_GCR_GPOMD_MASK;
++ val = AW9523_GCR_GPOMD_MASK;
++ break;
++ default:
++ rc = -EOPNOTSUPP;
++ goto end;
++ }
++
++ rc = regmap_update_bits(awi->regmap, reg, mask, val);
++ if (rc)
++ goto end;
++ }
++end:
++ mutex_unlock(&awi->i2c_lock);
++ return rc;
++}
++
++static const struct pinconf_ops aw9523_pinconf_ops = {
++ .pin_config_get = aw9523_pconf_get,
++ .pin_config_set = aw9523_pconf_set,
++ .is_generic = true,
++};
++
++/*
++ * aw9523_get_pin_direction - Get pin direction
++ * @regmap: Regmap structure
++ * @pin: gpiolib pin number
++ * @n: pin index in port register
++ *
++ * Return: Pin direction for success or negative number for error
++ */
++static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n)
++{
++ int ret;
++
++ ret = regmap_test_bits(regmap, AW9523_REG_CONF_STATE(pin), BIT(n));
++ if (ret < 0)
++ return ret;
++
++ return ret ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
++}
++
++/*
++ * aw9523_get_port_state - Get input or output state for entire port
++ * @regmap: Regmap structure
++ * @pin: gpiolib pin number
++ * @regbit: hw pin index, used to retrieve port number
++ * @state: returned port state
++ *
++ * Return: Zero for success or negative number for error
++ */
++static int aw9523_get_port_state(struct regmap *regmap, u8 pin,
++ u8 regbit, unsigned int *state)
++{
++ u8 reg;
++ int dir;
++
++ dir = aw9523_get_pin_direction(regmap, pin, regbit);
++ if (dir < 0)
++ return dir;
++
++ if (dir == GPIO_LINE_DIRECTION_IN)
++ reg = AW9523_REG_IN_STATE(pin);
++ else
++ reg = AW9523_REG_OUT_STATE(pin);
++
++ return regmap_read(regmap, reg, state);
++}
++
++static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type)
++{
++ switch (type) {
++ case IRQ_TYPE_NONE:
++ case IRQ_TYPE_EDGE_BOTH:
++ return 0;
++ default:
++ return -EINVAL;
++ };
++}
++
++/*
++ * aw9523_irq_mask - Mask interrupt
++ * @d: irq data
++ *
++ * Sets which interrupt to mask in the bitmap;
++ * The interrupt will be masked when unlocking the irq bus.
++ */
++static void aw9523_irq_mask(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++ unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++
++ regmap_update_bits(awi->regmap,
++ AW9523_REG_INTR_DIS(d->hwirq),
++ BIT(n), BIT(n));
++ gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d));
++}
++
++/*
++ * aw9523_irq_unmask - Unmask interrupt
++ * @d: irq data
++ *
++ * Sets which interrupt to unmask in the bitmap;
++ * The interrupt will be masked when unlocking the irq bus.
++ */
++static void aw9523_irq_unmask(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++ unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++
++ gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d));
++ regmap_update_bits(awi->regmap,
++ AW9523_REG_INTR_DIS(d->hwirq),
++ BIT(n), 0);
++}
++
++static irqreturn_t aw9523_irq_thread_func(int irq, void *dev_id)
++{
++ struct aw9523 *awi = (struct aw9523 *)dev_id;
++ unsigned long n, val = 0;
++ unsigned long changed_gpio;
++ unsigned int tmp, port_pin, i, ret;
++
++ for (i = 0; i < AW9523_NUM_PORTS; i++) {
++ port_pin = i * AW9523_PINS_PER_PORT;
++ ret = regmap_read(awi->regmap,
++ AW9523_REG_IN_STATE(port_pin),
++ &tmp);
++ if (ret)
++ return ret;
++ val |= (u8)tmp << (i * 8);
++ }
++
++ /* Handle GPIO input release interrupt as well */
++ changed_gpio = awi->irq->cached_gpio ^ val;
++ awi->irq->cached_gpio = val;
++
++ /*
++ * To avoid up to four *slow* i2c reads from any driver hooked
++ * up to our interrupts, just check for the irq_find_mapping
++ * result: if the interrupt is not mapped, then we don't want
++ * to care about it.
++ */
++ for_each_set_bit(n, &changed_gpio, awi->gpio.ngpio) {
++ tmp = irq_find_mapping(awi->gpio.irq.domain, n);
++ if (tmp <= 0)
++ continue;
++ handle_nested_irq(tmp);
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * aw9523_irq_bus_lock - Grab lock for interrupt operation
++ * @d: irq data
++ */
++static void aw9523_irq_bus_lock(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++
++ mutex_lock(&awi->irq->lock);
++ regcache_cache_only(awi->regmap, true);
++}
++
++/*
++ * aw9523_irq_bus_sync_unlock - Synchronize state and unlock
++ * @d: irq data
++ *
++ * Writes the interrupt mask bits (found in the bit map) to the
++ * hardware, then unlocks the bus.
++ */
++static void aw9523_irq_bus_sync_unlock(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++
++ regcache_cache_only(awi->regmap, false);
++ regcache_sync(awi->regmap);
++ mutex_unlock(&awi->irq->lock);
++}
++
++static int aw9523_gpio_get_direction(struct gpio_chip *chip,
++ unsigned int offset)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = aw9523_get_pin_direction(awi->regmap, offset, regbit);
++ mutex_unlock(&awi->i2c_lock);
++
++ return ret;
++}
++
++static int aw9523_gpio_get(struct gpio_chip *chip, unsigned int offset)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ unsigned int val;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = aw9523_get_port_state(awi->regmap, offset, regbit, &val);
++ mutex_unlock(&awi->i2c_lock);
++ if (ret)
++ return ret;
++
++ return !!(val & BIT(regbit));
++}
++
++/**
++ * _aw9523_gpio_get_multiple - Get I/O state for an entire port
++ * @regmap: Regmap structure
++ * @pin: gpiolib pin number
++ * @regbit: hw pin index, used to retrieve port number
++ * @state: returned port I/O state
++ *
++ * Return: Zero for success or negative number for error
++ */
++static int _aw9523_gpio_get_multiple(struct aw9523 *awi, u8 regbit,
++ u8 *state, u8 mask)
++{
++ u32 dir_in, val;
++ u8 m;
++ int ret;
++
++ /* Registers are 8-bits wide */
++ ret = regmap_read(awi->regmap, AW9523_REG_CONF_STATE(regbit), &dir_in);
++ if (ret)
++ return ret;
++ *state = 0;
++
++ m = mask & dir_in;
++ if (m) {
++ ret = regmap_read(awi->regmap, AW9523_REG_IN_STATE(regbit),
++ &val);
++ if (ret)
++ return ret;
++ *state |= (u8)val & m;
++ }
++
++ m = mask & ~dir_in;
++ if (m) {
++ ret = regmap_read(awi->regmap, AW9523_REG_OUT_STATE(regbit),
++ &val);
++ if (ret)
++ return ret;
++ *state |= (u8)val & m;
++ }
++
++ return 0;
++}
++
++static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
++ unsigned long *mask,
++ unsigned long *bits)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 m, state = 0;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++
++ /* Port 0 (gpio 0-7) */
++ m = *mask & U8_MAX;
++ if (m) {
++ ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
++ if (ret)
++ goto out;
++ }
++ *bits = state;
++
++ /* Port 1 (gpio 8-15) */
++ m = (*mask >> 8) & U8_MAX;
++ if (m) {
++ ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
++ &state, m);
++ if (ret)
++ goto out;
++
++ *bits |= (state << 8);
++ }
++out:
++ mutex_unlock(&awi->i2c_lock);
++ return ret;
++}
++
++static void aw9523_gpio_set_multiple(struct gpio_chip *chip,
++ unsigned long *mask,
++ unsigned long *bits)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 mask_lo, mask_hi, bits_lo, bits_hi;
++ unsigned int reg;
++ int ret = 0;
++
++ mask_lo = *mask & U8_MAX;
++ mask_hi = (*mask >> 8) & U8_MAX;
++ mutex_lock(&awi->i2c_lock);
++ if (mask_hi) {
++ reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
++ bits_hi = (*bits >> 8) & U8_MAX;
++
++ ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
++ if (ret) {
++ dev_warn(awi->dev, "Cannot write port1 out level\n");
++ goto out;
++ }
++ }
++ if (mask_lo) {
++ reg = AW9523_REG_OUT_STATE(0);
++ bits_lo = *bits & U8_MAX;
++ ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
++ if (ret)
++ dev_warn(awi->dev, "Cannot write port0 out level\n");
++ }
++out:
++ mutex_unlock(&awi->i2c_lock);
++}
++
++static void aw9523_gpio_set(struct gpio_chip *chip,
++ unsigned int offset, int value)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++
++ mutex_lock(&awi->i2c_lock);
++ regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
++ BIT(regbit), value ? BIT(regbit) : 0);
++ mutex_unlock(&awi->i2c_lock);
++}
++
++
++static int aw9523_direction_input(struct gpio_chip *chip, unsigned int offset)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
++ BIT(regbit), BIT(regbit));
++ mutex_unlock(&awi->i2c_lock);
++
++ return ret;
++}
++
++static int aw9523_direction_output(struct gpio_chip *chip,
++ unsigned int offset, int value)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
++ BIT(regbit), value ? BIT(regbit) : 0);
++ if (ret)
++ goto end;
++
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
++ BIT(regbit), 0);
++end:
++ mutex_unlock(&awi->i2c_lock);
++ return ret;
++}
++
++static int aw9523_drive_reset_gpio(struct aw9523 *awi)
++{
++ unsigned int chip_id;
++ int ret;
++
++ /*
++ * If the chip is already configured for any reason, then we
++ * will probably succeed in sending the soft reset signal to
++ * the hardware through I2C: this operation takes less time
++ * compared to a full HW reset and it gives the same results.
++ */
++ ret = regmap_write(awi->regmap, AW9523_REG_SOFT_RESET, 0);
++ if (ret == 0)
++ goto done;
++
++ dev_dbg(awi->dev, "Cannot execute soft reset: trying hard reset\n");
++ ret = gpiod_direction_output(awi->reset_gpio, 0);
++ if (ret)
++ return ret;
++
++ /* The reset pulse has to be longer than 20uS due to deglitch */
++ usleep_range(AW9523_HW_RESET_US, AW9523_HW_RESET_US + 1);
++
++ ret = gpiod_direction_output(awi->reset_gpio, 1);
++ if (ret)
++ return ret;
++done:
++ /* The HW needs at least 1uS to reliably recover after reset */
++ usleep_range(AW9523_HW_RESET_RECOVERY_US,
++ AW9523_HW_RESET_RECOVERY_US + 1);
++
++ /* Check the ChipID */
++ ret = regmap_read(awi->regmap, AW9523_REG_CHIPID, &chip_id);
++ if (ret) {
++ dev_err(awi->dev, "Cannot read Chip ID: %d\n", ret);
++ return ret;
++ }
++ if (chip_id != AW9523_VAL_EXPECTED_CHIPID) {
++ dev_err(awi->dev, "Bad ChipID; read 0x%x, expected 0x%x\n",
++ chip_id, AW9523_VAL_EXPECTED_CHIPID);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int aw9523_hw_reset(struct aw9523 *awi)
++{
++ int ret, max_retries = 2;
++
++ /* Sometimes the chip needs more than one reset cycle */
++ do {
++ ret = aw9523_drive_reset_gpio(awi);
++ if (ret == 0)
++ break;
++ max_retries--;
++ } while (max_retries);
++
++ return ret;
++}
++
++static int aw9523_init_gpiochip(struct aw9523 *awi, unsigned int npins)
++{
++ struct device *dev = awi->dev;
++ struct gpio_chip *gc = &awi->gpio;
++
++ gc->label = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
++ if (!gc->label)
++ return -ENOMEM;
++
++ gc->base = -1;
++ gc->ngpio = npins;
++ gc->get_direction = aw9523_gpio_get_direction;
++ gc->direction_input = aw9523_direction_input;
++ gc->direction_output = aw9523_direction_output;
++ gc->get = aw9523_gpio_get;
++ gc->get_multiple = aw9523_gpio_get_multiple;
++ gc->set = aw9523_gpio_set;
++ gc->set_multiple = aw9523_gpio_set_multiple;
++ gc->set_config = gpiochip_generic_config;
++ gc->parent = dev;
++ gc->owner = THIS_MODULE;
++ gc->can_sleep = false;
++
++ return 0;
++}
++
++static const struct irq_chip aw9523_irq_chip = {
++ .name = "aw9523",
++ .irq_mask = aw9523_irq_mask,
++ .irq_unmask = aw9523_irq_unmask,
++ .irq_bus_lock = aw9523_irq_bus_lock,
++ .irq_bus_sync_unlock = aw9523_irq_bus_sync_unlock,
++ .irq_set_type = aw9523_gpio_irq_type,
++ .flags = IRQCHIP_IMMUTABLE,
++ GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
++static int aw9523_init_irq(struct aw9523 *awi, int irq)
++{
++ struct device *dev = awi->dev;
++ struct gpio_irq_chip *girq;
++ struct irq_chip *irqchip;
++ int ret;
++
++ if (!device_property_read_bool(dev, "interrupt-controller"))
++ return 0;
++
++ irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
++ if (!irqchip)
++ return -ENOMEM;
++
++ awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
++ if (!awi->irq)
++ return -ENOMEM;
++
++ awi->irq->irqchip = irqchip;
++ mutex_init(&awi->irq->lock);
++
++ ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
++ IRQF_ONESHOT, dev_name(dev), awi);
++ if (ret) {
++ dev_err(dev, "Failed to request irq %d\n", irq);
++ return ret;
++ }
++
++ girq = &awi->gpio.irq;
++ gpio_irq_chip_set_chip(girq, &aw9523_irq_chip);
++ girq->parent_handler = NULL;
++ girq->num_parents = 0;
++ girq->parents = NULL;
++ girq->default_type = IRQ_TYPE_EDGE_BOTH;
++ girq->handler = handle_simple_irq;
++ girq->threaded = true;
++
++ return 0;
++}
++
++static bool aw9523_is_reg_hole(unsigned int reg)
++{
++ return (reg > AW9523_REG_PORT_MODE(AW9523_PINS_PER_PORT) &&
++ reg < AW9523_REG_SOFT_RESET) ||
++ (reg > AW9523_REG_INTR_DIS(AW9523_PINS_PER_PORT) &&
++ reg < AW9523_REG_CHIPID);
++}
++
++static bool aw9523_readable_reg(struct device *dev, unsigned int reg)
++{
++ /* All available registers (minus holes) can be read */
++ return !aw9523_is_reg_hole(reg);
++}
++
++static bool aw9523_volatile_reg(struct device *dev, unsigned int reg)
++{
++ return aw9523_is_reg_hole(reg) ||
++ reg == AW9523_REG_IN_STATE(0) ||
++ reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT) ||
++ reg == AW9523_REG_CHIPID ||
++ reg == AW9523_REG_SOFT_RESET;
++}
++
++static bool aw9523_writeable_reg(struct device *dev, unsigned int reg)
++{
++ return !aw9523_is_reg_hole(reg) && reg != AW9523_REG_CHIPID;
++}
++
++static bool aw9523_precious_reg(struct device *dev, unsigned int reg)
++{
++ /* Reading AW9523_REG_IN_STATE clears interrupt status */
++ return aw9523_is_reg_hole(reg) ||
++ reg == AW9523_REG_IN_STATE(0) ||
++ reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT);
++}
++
++static const struct regmap_config aw9523_regmap = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .reg_stride = 1,
++
++ .precious_reg = aw9523_precious_reg,
++ .readable_reg = aw9523_readable_reg,
++ .volatile_reg = aw9523_volatile_reg,
++ .writeable_reg = aw9523_writeable_reg,
++
++ .cache_type = REGCACHE_FLAT,
++ .disable_locking = true,
++
++ .num_reg_defaults_raw = AW9523_REG_SOFT_RESET,
++};
++
++static int aw9523_hw_init(struct aw9523 *awi)
++{
++ u8 p1_pin = AW9523_PINS_PER_PORT;
++ unsigned int val;
++ int ret;
++
++ /* No register caching during initialization */
++ regcache_cache_bypass(awi->regmap, true);
++
++ /* Bring up the chip */
++ ret = aw9523_hw_reset(awi);
++ if (ret) {
++ dev_err(awi->dev, "HW Reset failed: %d\n", ret);
++ return ret;
++ }
++
++ /*
++ * This is the expected chip and it is running: it's time to
++ * set a safe default configuration in case the user doesn't
++ * configure (all of the available) pins in this chip.
++ * P.S.: The writes order doesn't matter.
++ */
++
++ /* Set all pins as GPIO */
++ ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(0), U8_MAX);
++ if (ret)
++ return ret;
++ ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(p1_pin), U8_MAX);
++ if (ret)
++ return ret;
++
++ /* Set Open-Drain mode on Port 0 (Port 1 is always P-P) */
++ ret = regmap_write(awi->regmap, AW9523_REG_GCR, 0);
++ if (ret)
++ return ret;
++
++ /* Set all pins as inputs */
++ ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(0), U8_MAX);
++ if (ret)
++ return ret;
++ ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(p1_pin), U8_MAX);
++ if (ret)
++ return ret;
++
++ /* Disable all interrupts to avoid unreasoned wakeups */
++ ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(0), U8_MAX);
++ if (ret)
++ return ret;
++ ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(p1_pin), U8_MAX);
++ if (ret)
++ return ret;
++
++ /* Clear setup-generated interrupts by performing a port state read */
++ ret = aw9523_get_port_state(awi->regmap, 0, 0, &val);
++ if (ret)
++ return ret;
++ ret = aw9523_get_port_state(awi->regmap, p1_pin, 0, &val);
++ if (ret)
++ return ret;
++
++ /* Everything went fine: activate and reinitialize register cache */
++ regcache_cache_bypass(awi->regmap, false);
++ return regmap_reinit_cache(awi->regmap, &aw9523_regmap);
++}
++
++static int aw9523_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct pinctrl_desc *pdesc;
++ struct aw9523 *awi;
++ int ret;
++
++ awi = devm_kzalloc(dev, sizeof(*awi), GFP_KERNEL);
++ if (!awi)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, awi);
++
++ awi->dev = dev;
++ awi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
++ if (IS_ERR(awi->reset_gpio))
++ return PTR_ERR(awi->reset_gpio);
++ gpiod_set_consumer_name(awi->reset_gpio, "aw9523 reset");
++
++ awi->regmap = devm_regmap_init_i2c(client, &aw9523_regmap);
++ if (IS_ERR(awi->regmap))
++ return PTR_ERR(awi->regmap);
++
++ awi->vio_vreg = devm_regulator_get_optional(dev, "vio");
++ if (IS_ERR(awi->vio_vreg)) {
++ if (PTR_ERR(awi->vio_vreg) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ awi->vio_vreg = NULL;
++ } else {
++ ret = regulator_enable(awi->vio_vreg);
++ if (ret)
++ return ret;
++ }
++
++ mutex_init(&awi->i2c_lock);
++ lockdep_set_subclass(&awi->i2c_lock,
++ i2c_adapter_depth(client->adapter));
++
++ pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
++ if (!pdesc)
++ return -ENOMEM;
++
++ ret = aw9523_hw_init(awi);
++ if (ret)
++ goto err_disable_vregs;
++
++ pdesc->name = dev_name(dev);
++ pdesc->owner = THIS_MODULE;
++ pdesc->pctlops = &aw9523_pinctrl_ops;
++ pdesc->pmxops = &aw9523_pinmux_ops;
++ pdesc->confops = &aw9523_pinconf_ops;
++ pdesc->pins = aw9523_pins;
++ pdesc->npins = ARRAY_SIZE(aw9523_pins);
++
++ ret = aw9523_init_gpiochip(awi, pdesc->npins);
++ if (ret)
++ goto err_disable_vregs;
++
++ if (client->irq) {
++ ret = aw9523_init_irq(awi, client->irq);
++ if (ret)
++ goto err_disable_vregs;
++ }
++
++ awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
++ if (IS_ERR(awi->pctl)) {
++ ret = PTR_ERR(awi->pctl);
++ dev_err(dev, "Cannot register pinctrl: %d", ret);
++ goto err_disable_vregs;
++ }
++
++ ret = devm_gpiochip_add_data(dev, &awi->gpio, awi);
++ if (ret)
++ goto err_disable_vregs;
++
++ return ret;
++
++err_disable_vregs:
++ if (awi->vio_vreg)
++ regulator_disable(awi->vio_vreg);
++ mutex_destroy(&awi->i2c_lock);
++ return ret;
++}
++
++static void aw9523_remove(struct i2c_client *client)
++{
++ struct aw9523 *awi = i2c_get_clientdata(client);
++ int ret;
++
++ if (!awi)
++ return;
++
++ /*
++ * If the chip VIO is connected to a regulator that we can turn
++ * off, life is easy... otherwise, reinitialize the chip and
++ * set the pins to hardware defaults before removing the driver
++ * to leave it in a clean, safe and predictable state.
++ */
++ if (awi->vio_vreg) {
++ regulator_disable(awi->vio_vreg);
++ } else {
++ mutex_lock(&awi->i2c_lock);
++ ret = aw9523_hw_init(awi);
++ mutex_unlock(&awi->i2c_lock);
++ if (ret)
++ return;
++ }
++
++ mutex_destroy(&awi->i2c_lock);
++}
++
++static const struct i2c_device_id aw9523_i2c_id_table[] = {
++ { "aw9523_i2c", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, aw9523_i2c_id_table);
++
++static const struct of_device_id of_aw9523_i2c_match[] = {
++ { .compatible = "awinic,aw9523-pinctrl", },
++};
++MODULE_DEVICE_TABLE(of, of_aw9523_i2c_match);
++
++static struct i2c_driver aw9523_driver = {
++ .driver = {
++ .name = "aw9523-pinctrl",
++ .of_match_table = of_aw9523_i2c_match,
++ },
++ .probe = aw9523_probe,
++ .remove = aw9523_remove,
++ .id_table = aw9523_i2c_id_table,
++};
++module_i2c_driver(aw9523_driver);
++
++MODULE_DESCRIPTION("Awinic AW9523 I2C GPIO Expander driver");
++MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch b/target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch
new file mode 100644
index 0000000000..193c797c21
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch
@@ -0,0 +1,26 @@
+From 52279c3d50d964c646692c42a0db87ef7bb451cc Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Wed, 6 Mar 2024 08:54:25 +0100
+Subject: [PATCH] pinctrl: aw9523: Add proper terminator
+
+The of_device_id array needs to be terminated with a NULL
+entry.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202403061147.85XYVsk3-lkp@intel.com/
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240306-fix-aw9523-terminator-v1-1-13f90f87a7f6@linaro.org
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -1099,6 +1099,7 @@ MODULE_DEVICE_TABLE(i2c, aw9523_i2c_id_t
+
+ static const struct of_device_id of_aw9523_i2c_match[] = {
+ { .compatible = "awinic,aw9523-pinctrl", },
++ { }
+ };
+ MODULE_DEVICE_TABLE(of, of_aw9523_i2c_match);
+
diff --git a/target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch b/target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch
new file mode 100644
index 0000000000..97d262451e
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch
@@ -0,0 +1,41 @@
+From e5e8a58023707472e5dbe9bc7b473a8703b401e0 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:15 +0200
+Subject: [PATCH] pinctrl: aw9523: Destroy mutex on ->remove()
+
+If aw9523_hw_init() fails on ->remove() the mutex left alive.
+Destroy it in that case as well. While at it, remove never
+true check at the beginning of the function.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-2-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -1067,10 +1067,6 @@ err_disable_vregs:
+ static void aw9523_remove(struct i2c_client *client)
+ {
+ struct aw9523 *awi = i2c_get_clientdata(client);
+- int ret;
+-
+- if (!awi)
+- return;
+
+ /*
+ * If the chip VIO is connected to a regulator that we can turn
+@@ -1082,10 +1078,8 @@ static void aw9523_remove(struct i2c_cli
+ regulator_disable(awi->vio_vreg);
+ } else {
+ mutex_lock(&awi->i2c_lock);
+- ret = aw9523_hw_init(awi);
++ aw9523_hw_init(awi);
+ mutex_unlock(&awi->i2c_lock);
+- if (ret)
+- return;
+ }
+
+ mutex_destroy(&awi->i2c_lock);
diff --git a/target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch b/target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch
new file mode 100644
index 0000000000..1217a6ce5e
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch
@@ -0,0 +1,62 @@
+From f91eafcb18e096108cd19d24ab71a0db5bc12416 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:16 +0200
+Subject: [PATCH] pinctrl: aw9523: Use correct error code for not supported
+ functionality
+
+The pin control subsystem internally uses ENOTSUPP for the not supported
+functionality. The checkpatch is false positive about this error code.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-3-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/bitfield.h>
++#include <linux/errno.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/gpio/driver.h>
+ #include <linux/i2c.h>
+@@ -239,7 +240,7 @@ static int aw9523_pcfg_param_to_reg(enum
+ reg = AW9523_REG_OUT_STATE(pin);
+ break;
+ default:
+- return -EOPNOTSUPP;
++ return -ENOTSUPP;
+ }
+ *r = reg;
+
+@@ -290,7 +291,7 @@ static int aw9523_pconf_get(struct pinct
+ val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
+ break;
+ default:
+- return -EOPNOTSUPP;
++ return -ENOTSUPP;
+ }
+ if (val < 1)
+ return -EINVAL;
+@@ -344,7 +345,7 @@ static int aw9523_pconf_set(struct pinct
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ /* Open-Drain is supported only on port 0 */
+ if (pin >= AW9523_PINS_PER_PORT) {
+- rc = -EOPNOTSUPP;
++ rc = -ENOTSUPP;
+ goto end;
+ }
+ mask = AW9523_GCR_GPOMD_MASK;
+@@ -361,7 +362,7 @@ static int aw9523_pconf_set(struct pinct
+ val = AW9523_GCR_GPOMD_MASK;
+ break;
+ default:
+- rc = -EOPNOTSUPP;
++ rc = -ENOTSUPP;
+ goto end;
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch b/target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch
new file mode 100644
index 0000000000..c90d4dac32
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch
@@ -0,0 +1,47 @@
+From 091655b9285d837db520381924c689bd5dc5d286 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:17 +0200
+Subject: [PATCH] pinctrl: aw9523: Always try both ports in
+ aw9523_gpio_set_multiple()
+
+The ports are equivalent from the user's point of view. Don't limit
+trying them both if writing to one fails.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-4-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -653,7 +653,7 @@ static void aw9523_gpio_set_multiple(str
+ struct aw9523 *awi = gpiochip_get_data(chip);
+ u8 mask_lo, mask_hi, bits_lo, bits_hi;
+ unsigned int reg;
+- int ret = 0;
++ int ret;
+
+ mask_lo = *mask & U8_MAX;
+ mask_hi = (*mask >> 8) & U8_MAX;
+@@ -663,10 +663,8 @@ static void aw9523_gpio_set_multiple(str
+ bits_hi = (*bits >> 8) & U8_MAX;
+
+ ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
+- if (ret) {
++ if (ret)
+ dev_warn(awi->dev, "Cannot write port1 out level\n");
+- goto out;
+- }
+ }
+ if (mask_lo) {
+ reg = AW9523_REG_OUT_STATE(0);
+@@ -675,7 +673,6 @@ static void aw9523_gpio_set_multiple(str
+ if (ret)
+ dev_warn(awi->dev, "Cannot write port0 out level\n");
+ }
+-out:
+ mutex_unlock(&awi->i2c_lock);
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch b/target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch
new file mode 100644
index 0000000000..f300fa0193
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch
@@ -0,0 +1,72 @@
+From 418ee9488ff74ab4ada3a539a2840dda9e56f847 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 29 Mar 2024 12:55:18 +0200
+Subject: [PATCH] pinctrl: aw9523: Make use of struct pinfunction and
+ PINCTRL_PINFUNCTION()
+
+Since pin control provides a generic data type and a macro for
+the pin function definition, use them in the driver.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-5-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 32 ++++++--------------------------
+ 1 file changed, 6 insertions(+), 26 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -67,18 +67,6 @@ struct aw9523_irq {
+ };
+
+ /*
+- * struct aw9523_pinmux - Pin mux params
+- * @name: Name of the mux
+- * @grps: Groups of the mux
+- * @num_grps: Number of groups (sizeof array grps)
+- */
+-struct aw9523_pinmux {
+- const char *name;
+- const char * const *grps;
+- const u8 num_grps;
+-};
+-
+-/*
+ * struct aw9523 - Main driver structure
+ * @dev: device handle
+ * @regmap: regmap handle for current device
+@@ -158,17 +146,9 @@ static const char * const gpio_pwm_group
+ };
+
+ /* Warning: Do NOT reorder this array */
+-static const struct aw9523_pinmux aw9523_pmx[] = {
+- {
+- .name = "pwm",
+- .grps = gpio_pwm_groups,
+- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
+- },
+- {
+- .name = "gpio",
+- .grps = gpio_pwm_groups,
+- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
+- },
++static const struct pinfunction aw9523_pmx[] = {
++ PINCTRL_PINFUNCTION("pwm", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
++ PINCTRL_PINFUNCTION("gpio", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
+ };
+
+ static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
+@@ -184,10 +164,10 @@ static const char *aw9523_pmx_get_fname(
+
+ static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
+ const char * const **groups,
+- unsigned int * const num_groups)
++ unsigned int * const ngroups)
+ {
+- *groups = aw9523_pmx[sel].grps;
+- *num_groups = aw9523_pmx[sel].num_grps;
++ *groups = aw9523_pmx[sel].groups;
++ *ngroups = aw9523_pmx[sel].ngroups;
+ return 0;
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch b/target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch
new file mode 100644
index 0000000000..98a1310ad5
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch
@@ -0,0 +1,50 @@
+From 66413f0468d35adb352c76bc286bf6f6746ba354 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:19 +0200
+Subject: [PATCH] pinctrl: aw9523: Use temporary variable for HW IRQ number
+
+There are two different ways on how to get HW IRQ number in some functions.
+Unify that by using temporary variable and irqd_to_hwirq() call.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-6-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -428,12 +428,12 @@ static int aw9523_gpio_irq_type(struct i
+ static void aw9523_irq_mask(struct irq_data *d)
+ {
+ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ unsigned int n = hwirq % AW9523_PINS_PER_PORT;
+
+- regmap_update_bits(awi->regmap,
+- AW9523_REG_INTR_DIS(d->hwirq),
++ regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
+ BIT(n), BIT(n));
+- gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d));
++ gpiochip_disable_irq(&awi->gpio, hwirq);
+ }
+
+ /*
+@@ -446,11 +446,11 @@ static void aw9523_irq_mask(struct irq_d
+ static void aw9523_irq_unmask(struct irq_data *d)
+ {
+ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ unsigned int n = hwirq % AW9523_PINS_PER_PORT;
+
+- gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d));
+- regmap_update_bits(awi->regmap,
+- AW9523_REG_INTR_DIS(d->hwirq),
++ gpiochip_enable_irq(&awi->gpio, hwirq);
++ regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
+ BIT(n), 0);
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch b/target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch
new file mode 100644
index 0000000000..a9f86481e3
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch
@@ -0,0 +1,61 @@
+From 4210ef801a248223a0ea5f47b5446081b4925e10 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:20 +0200
+Subject: [PATCH] pinctrl: aw9523: Get rid of redundant ' & U8_MAX' pieces
+
+When the variable is declared as u8, no need to perform ' & U8_MAX'
+as it's implied anyway.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-7-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -603,7 +603,7 @@ static int aw9523_gpio_get_multiple(stru
+ mutex_lock(&awi->i2c_lock);
+
+ /* Port 0 (gpio 0-7) */
+- m = *mask & U8_MAX;
++ m = *mask;
+ if (m) {
+ ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
+ if (ret)
+@@ -612,7 +612,7 @@ static int aw9523_gpio_get_multiple(stru
+ *bits = state;
+
+ /* Port 1 (gpio 8-15) */
+- m = (*mask >> 8) & U8_MAX;
++ m = *mask >> 8;
+ if (m) {
+ ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
+ &state, m);
+@@ -635,20 +635,20 @@ static void aw9523_gpio_set_multiple(str
+ unsigned int reg;
+ int ret;
+
+- mask_lo = *mask & U8_MAX;
+- mask_hi = (*mask >> 8) & U8_MAX;
++ mask_lo = *mask;
++ mask_hi = *mask >> 8;
++ bits_lo = *bits;
++ bits_hi = *bits >> 8;
++
+ mutex_lock(&awi->i2c_lock);
+ if (mask_hi) {
+ reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
+- bits_hi = (*bits >> 8) & U8_MAX;
+-
+ ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
+ if (ret)
+ dev_warn(awi->dev, "Cannot write port1 out level\n");
+ }
+ if (mask_lo) {
+ reg = AW9523_REG_OUT_STATE(0);
+- bits_lo = *bits & U8_MAX;
+ ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
+ if (ret)
+ dev_warn(awi->dev, "Cannot write port0 out level\n");
diff --git a/target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch b/target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch
new file mode 100644
index 0000000000..b37a425e8d
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch
@@ -0,0 +1,52 @@
+From 6bf270863ade776485d1c6bdb8f69d642b0e5f64 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:21 +0200
+Subject: [PATCH] pinctrl: aw9523: Remove unused irqchip field in struct
+ aw9523_irq
+
+The irqchip field is allocated, assigned but never used. Remove it.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-8-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -57,12 +57,10 @@
+ /*
+ * struct aw9523_irq - Interrupt controller structure
+ * @lock: mutex locking for the irq bus
+- * @irqchip: structure holding irqchip params
+ * @cached_gpio: stores the previous gpio status for bit comparison
+ */
+ struct aw9523_irq {
+ struct mutex lock;
+- struct irq_chip *irqchip;
+ u16 cached_gpio;
+ };
+
+@@ -805,21 +803,15 @@ static int aw9523_init_irq(struct aw9523
+ {
+ struct device *dev = awi->dev;
+ struct gpio_irq_chip *girq;
+- struct irq_chip *irqchip;
+ int ret;
+
+ if (!device_property_read_bool(dev, "interrupt-controller"))
+ return 0;
+
+- irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
+- if (!irqchip)
+- return -ENOMEM;
+-
+ awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
+ if (!awi->irq)
+ return -ENOMEM;
+
+- awi->irq->irqchip = irqchip;
+ mutex_init(&awi->irq->lock);
+
+ ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
diff --git a/target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch b/target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch
new file mode 100644
index 0000000000..f1f4e52140
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch
@@ -0,0 +1,40 @@
+From c567b00cc3d73f3ce4e92126731545d177262090 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 29 Mar 2024 12:55:22 +0200
+Subject: [PATCH] pinctrl: aw9523: Make use of dev_err_probe()
+
+Simplify the error handling in probe function by switching from
+dev_err() to dev_err_probe().
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-9-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -816,10 +816,8 @@ static int aw9523_init_irq(struct aw9523
+
+ ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
+ IRQF_ONESHOT, dev_name(dev), awi);
+- if (ret) {
+- dev_err(dev, "Failed to request irq %d\n", irq);
+- return ret;
+- }
++ if (ret)
++ return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
+
+ girq = &awi->gpio.irq;
+ gpio_irq_chip_set_chip(girq, &aw9523_irq_chip);
+@@ -1016,8 +1014,7 @@ static int aw9523_probe(struct i2c_clien
+
+ awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
+ if (IS_ERR(awi->pctl)) {
+- ret = PTR_ERR(awi->pctl);
+- dev_err(dev, "Cannot register pinctrl: %d", ret);
++ ret = dev_err_probe(dev, PTR_ERR(awi->pctl), "Cannot register pinctrl");
+ goto err_disable_vregs;
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch b/target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch
new file mode 100644
index 0000000000..4d81c6ae7f
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch
@@ -0,0 +1,41 @@
+From 7b8b9b5450b89d01e4b8f120b903cee85b529231 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:23 +0200
+Subject: [PATCH] pinctrl: aw9523: Sort headers and group pinctrl/*
+
+One header was misplaced and group pinctrl/* ones to show the relation
+with the pin control subsystem.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-10-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -13,17 +13,18 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+-#include <linux/mutex.h>
+ #include <linux/module.h>
+-#include <linux/pinctrl/pinconf.h>
+-#include <linux/pinctrl/pinctrl.h>
+-#include <linux/pinctrl/pinmux.h>
+-#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/mutex.h>
+ #include <linux/property.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/slab.h>
+
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++
+ #define AW9523_MAX_FUNCS 2
+ #define AW9523_NUM_PORTS 2
+ #define AW9523_PINS_PER_PORT 8
diff --git a/target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch b/target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch
new file mode 100644
index 0000000000..3ebdcdfa4a
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch
@@ -0,0 +1,62 @@
+From 4aad0ad20f4ea80180a3e58b04b701728541c0f7 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:24 +0200
+Subject: [PATCH] pinctrl: aw9523: Fix indentation in a few places
+
+In the comment, function prototype, and array of strings indentation
+is kinda broken. Reindent that.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-11-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -1,8 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+ * Awinic AW9523B i2c pin controller driver
+- * Copyright (c) 2020, AngeloGioacchino Del Regno
+- * <angelogioacchino.delregno@somainline.org>
++ * Copyright (c) 2020, AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+ */
+
+ #include <linux/bitfield.h>
+@@ -139,9 +138,10 @@ static const struct pinctrl_ops aw9523_p
+ };
+
+ static const char * const gpio_pwm_groups[] = {
+- "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15"
++ "gpio0", "gpio1", "gpio2", "gpio3", /* 0-3 */
++ "gpio4", "gpio5", "gpio6", "gpio7", /* 4-7 */
++ "gpio8", "gpio9", "gpio10", "gpio11", /* 8-11 */
++ "gpio12", "gpio13", "gpio14", "gpio15", /* 11-15 */
+ };
+
+ /* Warning: Do NOT reorder this array */
+@@ -388,8 +388,8 @@ static int aw9523_get_pin_direction(stru
+ *
+ * Return: Zero for success or negative number for error
+ */
+-static int aw9523_get_port_state(struct regmap *regmap, u8 pin,
+- u8 regbit, unsigned int *state)
++static int aw9523_get_port_state(struct regmap *regmap, u8 pin, u8 regbit,
++ unsigned int *state)
+ {
+ u8 reg;
+ int dir;
+@@ -984,8 +984,7 @@ static int aw9523_probe(struct i2c_clien
+ }
+
+ mutex_init(&awi->i2c_lock);
+- lockdep_set_subclass(&awi->i2c_lock,
+- i2c_adapter_depth(client->adapter));
++ lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter));
+
+ pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
+ if (!pdesc)
diff --git a/target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch b/target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch
deleted file mode 100644
index f9fa791fe1..0000000000
--- a/target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From: AngeloGioacchino Del Regno
- <angelogioacchino.delregno@somainline.org>
-To: linus.walleij@linaro.org
-Cc: linux-kernel@vger.kernel.org, konrad.dybcio@somainline.org,
- marijn.suijten@somainline.org, martin.botka@somainline.org,
- phone-devel@vger.kernel.org, linux-gpio@vger.kernel.org,
- devicetree@vger.kernel.org, robh+dt@kernel.org,
- AngeloGioacchino Del Regno
- <angelogioacchino.delregno@somainline.org>
-Subject: [PATCH v5 1/2] pinctrl: Add driver for Awinic AW9523/B I2C GPIO
- Expander
-Date: Mon, 25 Jan 2021 19:22:18 +0100
-
-The Awinic AW9523(B) is a multi-function I2C gpio expander in a
-TQFN-24L package, featuring PWM (max 37mA per pin, or total max
-power 3.2Watts) for LED driving capability.
-
-It has two ports with 8 pins per port (for a total of 16 pins),
-configurable as either PWM with 1/256 stepping or GPIO input/output,
-1.8V logic input; each GPIO can be configured as input or output
-independently from each other.
-
-This IC also has an internal interrupt controller, which is capable
-of generating an interrupt for each GPIO, depending on the
-configuration, and will raise an interrupt on the INTN pin to
-advertise this to an external interrupt controller.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
----
- drivers/pinctrl/Kconfig | 17 +
- drivers/pinctrl/Makefile | 1 +
- drivers/pinctrl/pinctrl-aw9523.c | 1122 ++++++++++++++++++++++++++++++
- 3 files changed, 1140 insertions(+)
- create mode 100644 drivers/pinctrl/pinctrl-aw9523.c
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -113,6 +113,24 @@ config PINCTRL_AT91PIO4
- Say Y here to enable the at91 pinctrl/gpio driver for Atmel PIO4
- controller available on sama5d2 SoC.
-
-+config PINCTRL_AW9523
-+ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
-+ depends on OF && I2C
-+ select PINMUX
-+ select PINCONF
-+ select GENERIC_PINCONF
-+ select GPIOLIB
-+ select GPIOLIB_IRQCHIP
-+ select REGMAP
-+ select REGMAP_I2C
-+ help
-+ The Awinic AW9523/AW9523B is a multi-function I2C GPIO
-+ expander with PWM functionality. This driver bundles a
-+ pinctrl driver to select the function muxing and a GPIO
-+ driver to handle GPIO, when the GPIO function is selected.
-+
-+ Say yes to enable pinctrl and GPIO support for the AW9523(B).
-+
- config PINCTRL_AXP209
- tristate "X-Powers AXP209 PMIC pinctrl and GPIO Support"
- depends on MFD_AXP20X
---- a/drivers/pinctrl/Makefile
-+++ b/drivers/pinctrl/Makefile
-@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl
- obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
- obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
- obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
-+obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
- obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o
- obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
- obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o
diff --git a/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch
index b58cb786ad..71adf6600f 100644
--- a/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch
+++ b/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch
@@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
-@@ -3151,6 +3151,18 @@ static const struct usb_device_id uvc_id
+@@ -3183,6 +3183,18 @@ static const struct usb_device_id uvc_id
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
@@ -64,7 +64,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
#include <media/v4l2-common.h>
-@@ -1235,9 +1240,149 @@ static void uvc_video_decode_data(struct
+@@ -1275,9 +1280,149 @@ static void uvc_video_decode_data(struct
uvc_urb->async_operations++;
}
@@ -214,7 +214,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
/* Mark the buffer as done if the EOF marker is set. */
if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
uvc_dbg(stream->dev, FRAME, "Frame complete (EOF found)\n");
-@@ -1819,6 +1964,8 @@ static int uvc_init_video_isoc(struct uv
+@@ -1859,6 +2004,8 @@ static int uvc_init_video_isoc(struct uv
if (npackets == 0)
return -ENOMEM;
@@ -225,16 +225,16 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
for_each_uvc_urb(uvc_urb, stream) {
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
-@@ -74,6 +74,8 @@
- #define UVC_QUIRK_FORCE_BPP 0x00001000
- #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000
+@@ -76,6 +76,8 @@
#define UVC_QUIRK_NO_RESET_RESUME 0x00004000
-+#define UVC_QUIRK_MOTION 0x00008000
-+#define UVC_QUIRK_SINGLE_ISO 0x00010000
+ #define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
+ #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
++#define UVC_QUIRK_MOTION 0x00020000
++#define UVC_QUIRK_SINGLE_ISO 0x00040000
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
-@@ -583,6 +585,7 @@ struct uvc_device {
+@@ -585,6 +587,7 @@ struct uvc_device {
struct input_dev *input;
char input_phys[64];
diff --git a/target/linux/ramips/patches-6.6/825-i2c-MIPS-adds-ralink-I2C-driver.patch b/target/linux/ramips/patches-6.6/825-i2c-MIPS-adds-ralink-I2C-driver.patch
index 609ea71735..c8cfb784ce 100644
--- a/target/linux/ramips/patches-6.6/825-i2c-MIPS-adds-ralink-I2C-driver.patch
+++ b/target/linux/ramips/patches-6.6/825-i2c-MIPS-adds-ralink-I2C-driver.patch
@@ -69,7 +69,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
obj-$(CONFIG_I2C_QUP) += i2c-qup.o
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ralink.c
-@@ -0,0 +1,440 @@
+@@ -0,0 +1,397 @@
+/*
+ * drivers/i2c/busses/i2c-ralink.c
+ *
@@ -410,101 +410,58 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+
+static int rt_i2c_probe(struct platform_device *pdev)
+{
-+ struct resource *res;
++ struct device *dev = &pdev->dev;
+ struct rt_i2c *i2c;
+ struct i2c_adapter *adap;
-+ const struct of_device_id *match;
-+ int ret, restart;
++ int restart;
+
-+ match = of_match_device(i2c_rt_dt_ids, &pdev->dev);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res) {
-+ dev_err(&pdev->dev, "no memory resource found\n");
-+ return -ENODEV;
-+ }
-+
-+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct rt_i2c), GFP_KERNEL);
++ i2c = devm_kzalloc(dev, sizeof(struct rt_i2c), GFP_KERNEL);
+ if (!i2c) {
-+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
++ dev_err(dev, "failed to allocate i2c_adapter\n");
+ return -ENOMEM;
+ }
+
-+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
++ i2c->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(i2c->base))
+ return PTR_ERR(i2c->base);
+
-+ i2c->clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(i2c->clk)) {
-+ dev_err(&pdev->dev, "no clock defined\n");
-+ return -ENODEV;
-+ }
-+ clk_prepare_enable(i2c->clk);
-+ i2c->dev = &pdev->dev;
++ i2c->clk = devm_clk_get_enabled(dev, NULL);
++ if (IS_ERR(i2c->clk))
++ return dev_err_probe(dev, PTR_ERR(i2c->clk), "no clock defined");
++
++ i2c->dev = dev;
+
+ if (of_property_read_u32(pdev->dev.of_node,
+ "clock-frequency", &i2c->cur_clk))
+ i2c->cur_clk = 100000;
+
+ adap = &i2c->adap;
-+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adap->algo = &rt_i2c_algo;
+ adap->retries = 3;
-+ adap->dev.parent = &pdev->dev;
++ adap->dev.parent = dev;
+ i2c_set_adapdata(adap, i2c);
+ adap->dev.of_node = pdev->dev.of_node;
-+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
++ strlcpy(adap->name, dev_name(dev), sizeof(adap->name));
+ adap->quirks = &rt_i2c_quirks;
+
-+ platform_set_drvdata(pdev, i2c);
-+
+ restart = rt_i2c_init(i2c);
+
-+ ret = i2c_add_adapter(adap);
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "failed to add adapter\n");
-+ clk_disable_unprepare(i2c->clk);
-+ return ret;
-+ }
-+
-+ dev_info(&pdev->dev, "clock %uKHz, re-start %ssupport\n",
++ dev_info(dev, "clock %uKHz, re-start %ssupport\n",
+ i2c->cur_clk/1000, restart ? "" : "not ");
+
-+ return ret;
-+}
-+
-+static int rt_i2c_remove(struct platform_device *pdev)
-+{
-+ struct rt_i2c *i2c = platform_get_drvdata(pdev);
-+
-+ i2c_del_adapter(&i2c->adap);
-+ clk_disable_unprepare(i2c->clk);
-+
-+ return 0;
++ return devm_i2c_add_adapter(dev, adap);
+}
+
+static struct platform_driver rt_i2c_driver = {
+ .probe = rt_i2c_probe,
-+ .remove = rt_i2c_remove,
+ .driver = {
-+ .owner = THIS_MODULE,
+ .name = "i2c-ralink",
+ .of_match_table = i2c_rt_dt_ids,
+ },
+};
+
-+static int __init i2c_rt_init (void)
-+{
-+ return platform_driver_register(&rt_i2c_driver);
-+}
-+subsys_initcall(i2c_rt_init);
-+
-+static void __exit i2c_rt_exit (void)
-+{
-+ platform_driver_unregister(&rt_i2c_driver);
-+}
-+module_exit(i2c_rt_exit);
++module_platform_driver(rt_i2c_driver);
+
+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
+MODULE_DESCRIPTION("Ralink I2c host driver");
diff --git a/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch b/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
new file mode 100644
index 0000000000..1d5c6dcd40
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
@@ -0,0 +1,39 @@
+From: Shiji Yang <yangshiji66@outlook.com>
+Date: Wed, 10 Jul 2024 12:18:52 +0800
+Subject: [PATCH] mmc: mtk-sd: initialize the pad and tune registers
+
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+---
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -75,8 +75,12 @@
+ #define MSDC_PATCH_BIT 0xb0
+ #define MSDC_PATCH_BIT1 0xb4
+ #define MSDC_PATCH_BIT2 0xb8
++#define MSDC_PAD_CTRL0 0xe0
++#define MSDC_PAD_CTRL1 0xe4
++#define MSDC_PAD_CTRL2 0xe8
+ #define MSDC_PAD_TUNE 0xec
+ #define MSDC_PAD_TUNE0 0xf0
++#define MSDC_PAD_TUNE1 0xf4
+ #define PAD_DS_TUNE 0x188
+ #define PAD_CMD_TUNE 0x18c
+ #define EMMC51_CFG0 0x204
+@@ -1795,6 +1799,16 @@ static void msdc_init_hw(struct msdc_hos
+ MSDC_PAD_TUNE_RXDLYSEL);
+ }
+
++ /* Set pins drive strength */
++ writel(0x000d0044, host->base + MSDC_PAD_CTRL0);
++ writel(0x000e0044, host->base + MSDC_PAD_CTRL1);
++ writel(0x000e0044, host->base + MSDC_PAD_CTRL2);
++
++ /* Set pad delay */
++ writel(0x84101010, host->base + MSDC_PAD_TUNE);
++ writel(0x10101010, host->base + MSDC_PAD_TUNE0);
++ writel(0x10101010, host->base + MSDC_PAD_TUNE1);
++
+ if (mmc->caps2 & MMC_CAP2_NO_SDIO) {
+ sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIO);
+ sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
diff --git a/target/linux/ramips/rt288x/config-6.6 b/target/linux/ramips/rt288x/config-6.6
index f3261258ae..3a6657fdfe 100644
--- a/target/linux/ramips/rt288x/config-6.6
+++ b/target/linux/ramips/rt288x/config-6.6
@@ -25,6 +25,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -49,8 +50,7 @@ CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
@@ -73,6 +73,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_RALINK=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
diff --git a/target/linux/ramips/rt305x/config-6.6 b/target/linux/ramips/rt305x/config-6.6
index 27bf316c68..69070730ad 100644
--- a/target/linux/ramips/rt305x/config-6.6
+++ b/target/linux/ramips/rt305x/config-6.6
@@ -27,6 +27,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -52,8 +53,7 @@ CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
@@ -76,6 +76,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_RALINK=y
CONFIG_GPIO_WATCHDOG=y
# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
diff --git a/target/linux/ramips/rt3883/config-6.6 b/target/linux/ramips/rt3883/config-6.6
index b272c751ed..55dd19406e 100644
--- a/target/linux/ramips/rt3883/config-6.6
+++ b/target/linux/ramips/rt3883/config-6.6
@@ -26,6 +26,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -52,8 +53,7 @@ CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
@@ -76,6 +76,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_RALINK=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
diff --git a/target/linux/realtek/Makefile b/target/linux/realtek/Makefile
index cd86bdc11e..2614b148c4 100644
--- a/target/linux/realtek/Makefile
+++ b/target/linux/realtek/Makefile
@@ -9,7 +9,7 @@ DEVICE_TYPE:=basic
FEATURES:=ramdisk squashfs
SUBTARGETS:=rtl838x rtl839x rtl930x rtl931x
-KERNEL_PATCHVER:=5.15
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Realtek RTL83xx based boards.
diff --git a/target/linux/realtek/base-files/etc/board.d/02_network b/target/linux/realtek/base-files/etc/board.d/02_network
index 35c79cffa2..5073dbcc31 100644
--- a/target/linux/realtek/base-files/etc/board.d/02_network
+++ b/target/linux/realtek/base-files/etc/board.d/02_network
@@ -35,7 +35,9 @@ hpe,1920-8g|\
hpe,1920-8g-poe-65w|\
hpe,1920-8g-poe-180w|\
hpe,1920-16g|\
-hpe,1920-24g)
+hpe,1920-24g|\
+hpe,1920-48g|\
+hpe,1920-48g-poe)
label_mac=$(mtd_get_mac_binary factory 0x68)
lan_mac=$label_mac
mac_count1=$(hexdump -v -n 4 -s 0x110 -e '4 "%d"' $(find_mtd_part factory) 2>/dev/null)
@@ -80,6 +82,10 @@ d-link,dgs-1210-28mp-f)
ucidef_set_poe 370 "lan8 lan7 lan6 lan5 lan4 lan3 lan2 lan1 lan16 lan15 lan14 lan13 lan12 lan11 lan10 lan9 lan24 lan23
lan22 lan21 lan20 lan19 lan18 lan17"
;;
+d-link,dgs-1210-28p-f)
+ ucidef_set_poe 193 "lan8 lan7 lan6 lan5 lan4 lan3 lan2 lan1 lan16 lan15 lan14 lan13 lan12 lan11 lan10 lan9 lan24 lan23
+ lan22 lan21 lan20 lan19 lan18 lan17"
+ ;;
engenius,ews2910p)
ucidef_set_poe 60 "$(filter_port_list "$lan_list" "lan9 lan10")"
;;
@@ -89,6 +95,11 @@ hpe,1920-8g-poe-65w)
hpe,1920-8g-poe-180w)
ucidef_set_poe 180 "$(filter_port_list_reverse "$lan_list" "lan9 lan10")"
;;
+hpe,1920-48g-poe)
+ ucidef_set_poe 370 "lan8 lan7 lan6 lan5 lan4 lan3 lan2 lan1 lan16 lan15 lan14 lan13 lan12 lan11 lan10 lan9 lan24 lan23
+ lan22 lan21 lan20 lan19 lan18 lan17 lan32 lan31 lan30 lan29 lan28 lan27 lan26 lan25 lan40 lan39 lan38 lan37
+ lan36 lan35 lan34 lan33 lan48 lan47 lan46 lan45 lan44 lan43 lan42 lan41"
+ ;;
netgear,gs110tpp-v1)
ucidef_set_poe 130 "$(filter_port_list "$lan_list" "lan9 lan10")"
;;
diff --git a/target/linux/realtek/base-files/etc/uci-defaults/04_dlinkfan b/target/linux/realtek/base-files/etc/uci-defaults/04_dlinkfan
new file mode 100644
index 0000000000..17cc649438
--- /dev/null
+++ b/target/linux/realtek/base-files/etc/uci-defaults/04_dlinkfan
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2024 openwrt.org
+#
+
+. /lib/functions.sh
+
+board=$(board_name)
+
+case "$board" in
+d-link,dgs-1210-28p-f|d-link,dgs-1210-28mp-f)
+ # Enable fan control
+ FAN_CTRL='/sys/class/hwmon/hwmon0'
+ echo 1 > "$FAN_PATH/pwm1_enable"
+
+ # Set fan script execution in crontab
+ grep -s -q fan_ctrl.sh /etc/crontabs/root && exit 0
+
+ echo "# dlink fan script runs every 5 minutes" >> /etc/crontabs/root
+ echo "*/5 * * * * /sbin/fan_ctrl.sh" >> /etc/crontabs/root
+
+ # Execute one time after initial flash (instead of waiting 5 min for cron)
+ /sbin/fan_ctrl.sh
+ ;;
+esac
+
+exit 0
diff --git a/target/linux/realtek/base-files/sbin/fan_ctrl.sh b/target/linux/realtek/base-files/sbin/fan_ctrl.sh
new file mode 100755
index 0000000000..e7b661d7bb
--- /dev/null
+++ b/target/linux/realtek/base-files/sbin/fan_ctrl.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+PSU_TEMP=$(cut -c1-2 /sys/class/hwmon/hwmon0/temp1_input)
+
+FAN_CTRL='/sys/class/hwmon/hwmon0/pwm1'
+
+PSU_THRESH=51000
+
+if [ "$PSU_TEMP" -ge "$PSU_THRESH" ];then
+ echo "250" > $FAN_CTRL
+else
+ echo "156" > $FAN_CTRL
+fi
diff --git a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g.dtsi b/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g.dtsi
deleted file mode 100644
index 58f2c1f6c9..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g.dtsi
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "rtl838x.dtsi"
-#include "rtl838x_hpe_1920.dtsi"
-
-/ {
- gpio1: rtl8231-gpio {
- compatible = "realtek,rtl8231-gpio";
- #gpio-cells = <2>;
- gpio-controller;
- indirect-access-bus-id = <0>;
- };
-
- i2c0: i2c-gpio-0 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp0: sfp-0 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 25 GPIO_ACTIVE_LOW>;
- // tx-fault and tx-disable unconnected
- };
-
- i2c1: i2c-gpio-1 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp1: sfp-1 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- los-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
- // tx-fault and tx-disable unconnected
- };
-};
-
-&ethernet0 {
- mdio: mdio-bus {
- compatible = "realtek,rtl838x-mdio";
- regmap = <&ethernet0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- INTERNAL_PHY(8)
- INTERNAL_PHY(9)
- INTERNAL_PHY(10)
- INTERNAL_PHY(11)
- INTERNAL_PHY(12)
- INTERNAL_PHY(13)
- INTERNAL_PHY(14)
- INTERNAL_PHY(15)
-
- INTERNAL_PHY(24)
- INTERNAL_PHY(26)
- };
-};
-
-&switch0 {
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- SWITCH_PORT(8, 1, internal)
- SWITCH_PORT(9, 2, internal)
- SWITCH_PORT(10, 3, internal)
- SWITCH_PORT(11, 4, internal)
- SWITCH_PORT(12, 5, internal)
- SWITCH_PORT(13, 6, internal)
- SWITCH_PORT(14, 7, internal)
- SWITCH_PORT(15, 8, internal)
-
- port@24 {
- reg = <24>;
- label = "lan9";
- phy-handle = <&phy24>;
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp0>;
- };
-
- port@26 {
- reg = <26>;
- label = "lan10";
- phy-handle = <&phy26>;
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp1>;
- };
-
- port@28 {
- ethernet = <&ethernet0>;
- reg = <28>;
- phy-mode = "internal";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts
deleted file mode 100644
index 82df6789a9..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-10hp", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-10HP Switch";
-
- /* i2c of the left SFP cage: port 9 */
- i2c0: i2c-gpio-0 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp0: sfp-p9 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- };
-
- /* i2c of the right SFP cage: port 10 */
- i2c1: i2c-gpio-1 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp1: sfp-p10 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
- };
-};
-
-&uart1 {
- status = "okay";
-};
-
-&mdio {
- INTERNAL_PHY(24)
- INTERNAL_PHY(26)
-};
-
-&switch0 {
- ports {
- port@24 {
- reg = <24>;
- label = "lan9";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp0>;
- };
-
- port@26 {
- reg = <26>;
- label = "lan10";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp1>;
- };
- };
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts
deleted file mode 100644
index 7aa1cc274c..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-8", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-8v1/v2 Switch";
-};
-
-&gpio1 {
- /delete-node/ poe_enable;
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts
deleted file mode 100644
index 5ee340eac6..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-8hp-v1", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-8HP v1 Switch";
-};
-
-&uart1 {
- status = "okay";
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts
deleted file mode 100644
index 0768462255..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-8hp-v2", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-8HP v2 Switch";
-};
-
-&uart1 {
- status = "okay";
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28.dts b/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28.dts
deleted file mode 100644
index 0bcb196b7c..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28.dts
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "rtl838x.dtsi"
-#include "rtl83xx_d-link_dgs-1210_common.dtsi"
-#include "rtl83xx_d-link_dgs-1210_gpio.dtsi"
-#include "rtl8382_d-link_dgs-1210-28_common.dtsi"
-
-/ {
- compatible = "d-link,dgs-1210-28", "realtek,rtl838x-soc";
- model = "D-Link DGS-1210-28";
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28_common.dtsi b/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28_common.dtsi
deleted file mode 100644
index 17866d5f03..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28_common.dtsi
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-&ethernet0 {
- mdio: mdio-bus {
- compatible = "realtek,rtl838x-mdio";
- regmap = <&ethernet0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- EXTERNAL_PHY(0)
- EXTERNAL_PHY(1)
- EXTERNAL_PHY(2)
- EXTERNAL_PHY(3)
- EXTERNAL_PHY(4)
- EXTERNAL_PHY(5)
- EXTERNAL_PHY(6)
- EXTERNAL_PHY(7)
-
- INTERNAL_PHY(8)
- INTERNAL_PHY(9)
- INTERNAL_PHY(10)
- INTERNAL_PHY(11)
- INTERNAL_PHY(12)
- INTERNAL_PHY(13)
- INTERNAL_PHY(14)
- INTERNAL_PHY(15)
-
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-
- EXTERNAL_SFP_PHY(24)
- EXTERNAL_SFP_PHY(25)
- EXTERNAL_SFP_PHY(26)
- EXTERNAL_SFP_PHY(27)
- };
-};
-
-&switch0 {
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- SWITCH_PORT(0, 1, qsgmii)
- SWITCH_PORT(1, 2, qsgmii)
- SWITCH_PORT(2, 3, qsgmii)
- SWITCH_PORT(3, 4, qsgmii)
- SWITCH_PORT(4, 5, qsgmii)
- SWITCH_PORT(5, 6, qsgmii)
- SWITCH_PORT(6, 7, qsgmii)
- SWITCH_PORT(7, 8, qsgmii)
-
- SWITCH_PORT(8, 9, internal)
- SWITCH_PORT(9, 10, internal)
- SWITCH_PORT(10, 11, internal)
- SWITCH_PORT(11, 12, internal)
- SWITCH_PORT(12, 13, internal)
- SWITCH_PORT(13, 14, internal)
- SWITCH_PORT(14, 15, internal)
- SWITCH_PORT(15, 16, internal)
-
- SWITCH_PORT(16, 17, qsgmii)
- SWITCH_PORT(17, 18, qsgmii)
- SWITCH_PORT(18, 19, qsgmii)
- SWITCH_PORT(19, 20, qsgmii)
- SWITCH_PORT(20, 21, qsgmii)
- SWITCH_PORT(21, 22, qsgmii)
- SWITCH_PORT(22, 23, qsgmii)
- SWITCH_PORT(23, 24, qsgmii)
-
- SWITCH_PORT(24, 25, qsgmii)
- SWITCH_PORT(25, 26, qsgmii)
- SWITCH_PORT(26, 27, qsgmii)
- SWITCH_PORT(27, 28, qsgmii)
-
- port@28 {
- ethernet = <&ethernet0>;
- reg = <28>;
- phy-mode = "internal";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28mp-f.dts b/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28mp-f.dts
deleted file mode 100644
index ce008229b3..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-28mp-f.dts
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "rtl838x.dtsi"
-#include "rtl83xx_d-link_dgs-1210_common.dtsi"
-#include "rtl83xx_d-link_dgs-1210_gpio.dtsi"
-#include "rtl8382_d-link_dgs-1210-28_common.dtsi"
-
-/ {
- compatible = "d-link,dgs-1210-28mp-f", "realtek,rtl8382-soc", "realtek,rtl838x-soc";
- model = "D-Link DGS-1210-28MP F";
-};
-
-&leds {
- link_act {
- label = "green:link_act";
- gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
- };
-
- poe {
- label = "green:poe";
- gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
- };
-
- poe_max {
- label = "yellow:poe_max";
- gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
- };
-};
-
-&keys {
- mode {
- label = "mode";
- gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
- linux,code = <BTN_0>;
- };
-};
-
-&uart1 {
- status = "okay";
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_hpe_1920.dtsi b/target/linux/realtek/dts-5.15/rtl8382_hpe_1920.dtsi
deleted file mode 100644
index 5368b41c27..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_hpe_1920.dtsi
+++ /dev/null
@@ -1,117 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "rtl838x.dtsi"
-#include "rtl838x_hpe_1920.dtsi"
-
-/ {
- gpio1: rtl8231-gpio {
- compatible = "realtek,rtl8231-gpio";
- #gpio-cells = <2>;
- gpio-controller;
- indirect-access-bus-id = <0>;
- };
-
- i2c0: i2c-gpio-0 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp0: sfp-0 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
- // tx-fault unconnected
- // tx-disable connected to RTL8214FC
- };
-
- i2c1: i2c-gpio-1 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp1: sfp-1 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- los-gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 25 GPIO_ACTIVE_LOW>;
- // tx-fault unconnected
- // tx-disable connected to RTL8214FC
- };
-
- i2c2: i2c-gpio-2 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp2: sfp-2 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c2>;
- los-gpio = <&gpio1 30 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
- // tx-fault unconnected
- // tx-disable connected to RTL8214FC
- };
-
- i2c3: i2c-gpio-3 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 32 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp3: sfp-3 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c3>;
- los-gpio = <&gpio1 34 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 33 GPIO_ACTIVE_LOW>;
- // tx-fault unconnected
- // tx-disable connected to RTL8214FC
- };
-};
-
-&ethernet0 {
- mdio: mdio-bus {
- compatible = "realtek,rtl838x-mdio";
- regmap = <&ethernet0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- INTERNAL_PHY(8)
- INTERNAL_PHY(9)
- INTERNAL_PHY(10)
- INTERNAL_PHY(11)
- INTERNAL_PHY(12)
- INTERNAL_PHY(13)
- INTERNAL_PHY(14)
- INTERNAL_PHY(15)
-
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-
- EXTERNAL_SFP_PHY_FULL(24, 0)
- EXTERNAL_SFP_PHY_FULL(25, 1)
- EXTERNAL_SFP_PHY_FULL(26, 2)
- EXTERNAL_SFP_PHY_FULL(27, 3)
- };
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts
deleted file mode 100644
index ac2eea7015..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-16", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-16";
-};
-
-&mdio {
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-};
-
-&switch0 {
- ports {
- SWITCH_PORT(16, 9, qsgmii)
- SWITCH_PORT(17, 10, qsgmii)
- SWITCH_PORT(18, 11, qsgmii)
- SWITCH_PORT(19, 12, qsgmii)
- SWITCH_PORT(20, 13, qsgmii)
- SWITCH_PORT(21, 14, qsgmii)
- SWITCH_PORT(22, 15, qsgmii)
- SWITCH_PORT(23, 16, qsgmii)
- };
-};
-
-&gpio1 {
- /delete-node/ poe_enable;
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts
deleted file mode 100644
index 81482dde10..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts
+++ /dev/null
@@ -1,128 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-24-v1", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24 v1";
-
- memory@0 {
- reg = <0x0 0x4000000>;
- };
-
- /* i2c of the left SFP cage: port 25 */
- i2c0: i2c-gpio-0 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp0: sfp-p25 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- };
-
- /* i2c of the right SFP cage: port 26 */
- i2c1: i2c-gpio-1 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp1: sfp-p26 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
- };
-};
-
-&uart1 {
- status = "okay";
-};
-
-&mdio {
- EXTERNAL_PHY(0)
- EXTERNAL_PHY(1)
- EXTERNAL_PHY(2)
- EXTERNAL_PHY(3)
- EXTERNAL_PHY(4)
- EXTERNAL_PHY(5)
- EXTERNAL_PHY(6)
- EXTERNAL_PHY(7)
-
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-
- INTERNAL_PHY(24)
- INTERNAL_PHY(26)
-};
-
-&switch0 {
- ports {
- SWITCH_PORT(0, 1, qsgmii)
- SWITCH_PORT(1, 2, qsgmii)
- SWITCH_PORT(2, 3, qsgmii)
- SWITCH_PORT(3, 4, qsgmii)
- SWITCH_PORT(4, 5, qsgmii)
- SWITCH_PORT(5, 6, qsgmii)
- SWITCH_PORT(6, 7, qsgmii)
- SWITCH_PORT(7, 8, qsgmii)
-
- SWITCH_PORT(8, 9, internal)
- SWITCH_PORT(9, 10, internal)
- SWITCH_PORT(10, 11, internal)
- SWITCH_PORT(11, 12, internal)
- SWITCH_PORT(12, 13, internal)
- SWITCH_PORT(13, 14, internal)
- SWITCH_PORT(14, 15, internal)
- SWITCH_PORT(15, 16, internal)
-
- SWITCH_PORT(16, 17, qsgmii)
- SWITCH_PORT(17, 18, qsgmii)
- SWITCH_PORT(18, 19, qsgmii)
- SWITCH_PORT(19, 20, qsgmii)
- SWITCH_PORT(20, 21, qsgmii)
- SWITCH_PORT(21, 22, qsgmii)
- SWITCH_PORT(22, 23, qsgmii)
- SWITCH_PORT(23, 24, qsgmii)
-
- port@24 {
- reg = <24>;
- label = "lan25";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp0>;
- };
-
- port@26 {
- reg = <26>;
- label = "lan26";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp1>;
- };
- };
-};
-
-&gpio1 {
- /delete-node/ poe_enable;
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts
deleted file mode 100644
index 3d00034a3b..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts
+++ /dev/null
@@ -1,63 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-24e", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24E";
-};
-
-&mdio {
- EXTERNAL_PHY(0)
- EXTERNAL_PHY(1)
- EXTERNAL_PHY(2)
- EXTERNAL_PHY(3)
- EXTERNAL_PHY(4)
- EXTERNAL_PHY(5)
- EXTERNAL_PHY(6)
- EXTERNAL_PHY(7)
-
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-};
-
-&switch0 {
- ports {
- SWITCH_PORT(1, 1, qsgmii)
- SWITCH_PORT(0, 2, qsgmii)
- SWITCH_PORT(3, 3, qsgmii)
- SWITCH_PORT(2, 4, qsgmii)
- SWITCH_PORT(5, 5, qsgmii)
- SWITCH_PORT(4, 6, qsgmii)
- SWITCH_PORT(7, 7, qsgmii)
- SWITCH_PORT(6, 8, qsgmii)
-
- SWITCH_PORT(9, 9, internal)
- SWITCH_PORT(8, 10, internal)
- SWITCH_PORT(11, 11, internal)
- SWITCH_PORT(10, 12, internal)
- SWITCH_PORT(13, 13, internal)
- SWITCH_PORT(12, 14, internal)
- SWITCH_PORT(15, 15, internal)
- SWITCH_PORT(14, 16, internal)
-
- SWITCH_PORT(17, 17, qsgmii)
- SWITCH_PORT(16, 18, qsgmii)
- SWITCH_PORT(19, 19, qsgmii)
- SWITCH_PORT(18, 20, qsgmii)
- SWITCH_PORT(21, 21, qsgmii)
- SWITCH_PORT(20, 22, qsgmii)
- SWITCH_PORT(23, 23, qsgmii)
- SWITCH_PORT(22, 24, qsgmii)
- };
-};
-
-&gpio1 {
- /delete-node/ poe_enable;
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts
deleted file mode 100644
index 8a77121f4c..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts
+++ /dev/null
@@ -1,63 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-24ep", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24EP Switch";
-};
-
-&uart1 {
- status = "okay";
-};
-
-&mdio {
- EXTERNAL_PHY(0)
- EXTERNAL_PHY(1)
- EXTERNAL_PHY(2)
- EXTERNAL_PHY(3)
- EXTERNAL_PHY(4)
- EXTERNAL_PHY(5)
- EXTERNAL_PHY(6)
- EXTERNAL_PHY(7)
-
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-};
-
-&switch0 {
- ports {
- SWITCH_PORT(0, 1, qsgmii)
- SWITCH_PORT(1, 2, qsgmii)
- SWITCH_PORT(2, 3, qsgmii)
- SWITCH_PORT(3, 4, qsgmii)
- SWITCH_PORT(4, 5, qsgmii)
- SWITCH_PORT(5, 6, qsgmii)
- SWITCH_PORT(6, 7, qsgmii)
- SWITCH_PORT(7, 8, qsgmii)
-
- SWITCH_PORT(8, 9, internal)
- SWITCH_PORT(9, 10, internal)
- SWITCH_PORT(10, 11, internal)
- SWITCH_PORT(11, 12, internal)
- SWITCH_PORT(12, 13, internal)
- SWITCH_PORT(13, 14, internal)
- SWITCH_PORT(14, 15, internal)
- SWITCH_PORT(15, 16, internal)
-
- SWITCH_PORT(16, 17, qsgmii)
- SWITCH_PORT(17, 18, qsgmii)
- SWITCH_PORT(18, 19, qsgmii)
- SWITCH_PORT(19, 20, qsgmii)
- SWITCH_PORT(20, 21, qsgmii)
- SWITCH_PORT(21, 22, qsgmii)
- SWITCH_PORT(22, 23, qsgmii)
- SWITCH_PORT(23, 24, qsgmii)
- };
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts
deleted file mode 100644
index 7bb3410a31..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts
+++ /dev/null
@@ -1,125 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-24hp-v1", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24HP v1";
-
- memory@0 {
- reg = <0x0 0x4000000>;
- };
-
- /* i2c of the left SFP cage: port 25 */
- i2c0: i2c-gpio-0 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp0: sfp-p25 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- };
-
- /* i2c of the right SFP cage: port 26 */
- i2c1: i2c-gpio-1 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp1: sfp-p26 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
- };
-};
-
-&uart1 {
- status = "okay";
-};
-
-&mdio {
- EXTERNAL_PHY(0)
- EXTERNAL_PHY(1)
- EXTERNAL_PHY(2)
- EXTERNAL_PHY(3)
- EXTERNAL_PHY(4)
- EXTERNAL_PHY(5)
- EXTERNAL_PHY(6)
- EXTERNAL_PHY(7)
-
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-
- INTERNAL_PHY(24)
- INTERNAL_PHY(26)
-};
-
-&switch0 {
- ports {
- SWITCH_PORT(0, 1, qsgmii)
- SWITCH_PORT(1, 2, qsgmii)
- SWITCH_PORT(2, 3, qsgmii)
- SWITCH_PORT(3, 4, qsgmii)
- SWITCH_PORT(4, 5, qsgmii)
- SWITCH_PORT(5, 6, qsgmii)
- SWITCH_PORT(6, 7, qsgmii)
- SWITCH_PORT(7, 8, qsgmii)
-
- SWITCH_PORT(8, 9, internal)
- SWITCH_PORT(9, 10, internal)
- SWITCH_PORT(10, 11, internal)
- SWITCH_PORT(11, 12, internal)
- SWITCH_PORT(12, 13, internal)
- SWITCH_PORT(13, 14, internal)
- SWITCH_PORT(14, 15, internal)
- SWITCH_PORT(15, 16, internal)
-
- SWITCH_PORT(16, 17, qsgmii)
- SWITCH_PORT(17, 18, qsgmii)
- SWITCH_PORT(18, 19, qsgmii)
- SWITCH_PORT(19, 20, qsgmii)
- SWITCH_PORT(20, 21, qsgmii)
- SWITCH_PORT(21, 22, qsgmii)
- SWITCH_PORT(22, 23, qsgmii)
- SWITCH_PORT(23, 24, qsgmii)
-
- port@24 {
- reg = <24>;
- label = "lan25";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp0>;
- };
-
- port@26 {
- reg = <26>;
- label = "lan26";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp1>;
- };
- };
-};
-
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts
deleted file mode 100644
index 7b6a9a1e7f..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts
+++ /dev/null
@@ -1,121 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "rtl8380_zyxel_gs1900.dtsi"
-
-/ {
- compatible = "zyxel,gs1900-24hp-v2", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24HP v2 Switch";
-
- /* i2c of the left SFP cage: port 25 */
- i2c0: i2c-gpio-0 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp0: sfp-p25 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- };
-
- /* i2c of the right SFP cage: port 26 */
- i2c1: i2c-gpio-1 {
- compatible = "i2c-gpio";
- sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- sfp1: sfp-p26 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
- };
-};
-
-&uart1 {
- status = "okay";
-};
-
-&mdio {
- EXTERNAL_PHY(0)
- EXTERNAL_PHY(1)
- EXTERNAL_PHY(2)
- EXTERNAL_PHY(3)
- EXTERNAL_PHY(4)
- EXTERNAL_PHY(5)
- EXTERNAL_PHY(6)
- EXTERNAL_PHY(7)
-
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-
- INTERNAL_PHY(24)
- INTERNAL_PHY(26)
-};
-
-&switch0 {
- ports {
- SWITCH_PORT(0, 1, qsgmii)
- SWITCH_PORT(1, 2, qsgmii)
- SWITCH_PORT(2, 3, qsgmii)
- SWITCH_PORT(3, 4, qsgmii)
- SWITCH_PORT(4, 5, qsgmii)
- SWITCH_PORT(5, 6, qsgmii)
- SWITCH_PORT(6, 7, qsgmii)
- SWITCH_PORT(7, 8, qsgmii)
-
- SWITCH_PORT(8, 9, internal)
- SWITCH_PORT(9, 10, internal)
- SWITCH_PORT(10, 11, internal)
- SWITCH_PORT(11, 12, internal)
- SWITCH_PORT(12, 13, internal)
- SWITCH_PORT(13, 14, internal)
- SWITCH_PORT(14, 15, internal)
- SWITCH_PORT(15, 16, internal)
-
- SWITCH_PORT(16, 17, qsgmii)
- SWITCH_PORT(17, 18, qsgmii)
- SWITCH_PORT(18, 19, qsgmii)
- SWITCH_PORT(19, 20, qsgmii)
- SWITCH_PORT(20, 21, qsgmii)
- SWITCH_PORT(21, 22, qsgmii)
- SWITCH_PORT(22, 23, qsgmii)
- SWITCH_PORT(23, 24, qsgmii)
-
-
- port@24 {
- reg = <24>;
- label = "lan25";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp0>;
- };
-
- port@26 {
- reg = <26>;
- label = "lan26";
- phy-mode = "1000base-x";
- managed = "in-band-status";
- sfp = <&sfp1>;
- };
- };
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8393_d-link_dgs-1210-52.dts b/target/linux/realtek/dts-5.15/rtl8393_d-link_dgs-1210-52.dts
deleted file mode 100644
index 5b876e7c43..0000000000
--- a/target/linux/realtek/dts-5.15/rtl8393_d-link_dgs-1210-52.dts
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "rtl839x.dtsi"
-#include "rtl83xx_d-link_dgs-1210_common.dtsi"
-#include "rtl83xx_d-link_dgs-1210_gpio.dtsi"
-#include "rtl839x_d-link_dgs-1210_gpio.dtsi"
-
-/ {
- compatible = "d-link,dgs-1210-52", "realtek,rtl8393-soc";
- model = "D-Link DGS-1210-52";
-};
-
-&ethernet0 {
- mdio: mdio-bus {
- compatible = "realtek,rtl838x-mdio";
- regmap = <&ethernet0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* External phy RTL8218B #1 */
- EXTERNAL_PHY(0)
- EXTERNAL_PHY(1)
- EXTERNAL_PHY(2)
- EXTERNAL_PHY(3)
- EXTERNAL_PHY(4)
- EXTERNAL_PHY(5)
- EXTERNAL_PHY(6)
- EXTERNAL_PHY(7)
-
- /* External phy RTL8218B #2 */
- EXTERNAL_PHY(8)
- EXTERNAL_PHY(9)
- EXTERNAL_PHY(10)
- EXTERNAL_PHY(11)
- EXTERNAL_PHY(12)
- EXTERNAL_PHY(13)
- EXTERNAL_PHY(14)
- EXTERNAL_PHY(15)
-
- /* External phy RTL8218B #3 */
- EXTERNAL_PHY(16)
- EXTERNAL_PHY(17)
- EXTERNAL_PHY(18)
- EXTERNAL_PHY(19)
- EXTERNAL_PHY(20)
- EXTERNAL_PHY(21)
- EXTERNAL_PHY(22)
- EXTERNAL_PHY(23)
-
- /* External phy RTL8218B #4 */
- EXTERNAL_PHY(24)
- EXTERNAL_PHY(25)
- EXTERNAL_PHY(26)
- EXTERNAL_PHY(27)
- EXTERNAL_PHY(28)
- EXTERNAL_PHY(29)
- EXTERNAL_PHY(30)
- EXTERNAL_PHY(31)
-
- /* External phy RTL8218B #5 */
- EXTERNAL_PHY(32)
- EXTERNAL_PHY(33)
- EXTERNAL_PHY(34)
- EXTERNAL_PHY(35)
- EXTERNAL_PHY(36)
- EXTERNAL_PHY(37)
- EXTERNAL_PHY(38)
- EXTERNAL_PHY(39)
-
- /* External phy RTL8218B #6 */
- EXTERNAL_PHY(40)
- EXTERNAL_PHY(41)
- EXTERNAL_PHY(42)
- EXTERNAL_PHY(43)
- EXTERNAL_PHY(44)
- EXTERNAL_PHY(45)
- EXTERNAL_PHY(46)
- EXTERNAL_PHY(47)
-
- /* External phy RTL8214FC */
- EXTERNAL_SFP_PHY_FULL(48, 0)
- EXTERNAL_SFP_PHY_FULL(49, 1)
- EXTERNAL_SFP_PHY_FULL(50, 2)
- EXTERNAL_SFP_PHY_FULL(51, 3)
- };
-};
-
-&switch0 {
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- SWITCH_PORT(0, 1, qsgmii)
- SWITCH_PORT(1, 2, qsgmii)
- SWITCH_PORT(2, 3, qsgmii)
- SWITCH_PORT(3, 4, qsgmii)
- SWITCH_PORT(4, 5, qsgmii)
- SWITCH_PORT(5, 6, qsgmii)
- SWITCH_PORT(6, 7, qsgmii)
- SWITCH_PORT(7, 8, qsgmii)
-
- SWITCH_PORT(8, 9, qsgmii)
- SWITCH_PORT(9, 10, qsgmii)
- SWITCH_PORT(10, 11, qsgmii)
- SWITCH_PORT(11, 12, qsgmii)
- SWITCH_PORT(12, 13, qsgmii)
- SWITCH_PORT(13, 14, qsgmii)
- SWITCH_PORT(14, 15, qsgmii)
- SWITCH_PORT(15, 16, qsgmii)
-
- SWITCH_PORT(16, 17, qsgmii)
- SWITCH_PORT(17, 18, qsgmii)
- SWITCH_PORT(18, 19, qsgmii)
- SWITCH_PORT(19, 20, qsgmii)
- SWITCH_PORT(20, 21, qsgmii)
- SWITCH_PORT(21, 22, qsgmii)
- SWITCH_PORT(22, 23, qsgmii)
- SWITCH_PORT(23, 24, qsgmii)
-
- SWITCH_PORT(24, 25, qsgmii)
- SWITCH_PORT(25, 26, qsgmii)
- SWITCH_PORT(26, 27, qsgmii)
- SWITCH_PORT(27, 28, qsgmii)
- SWITCH_PORT(28, 29, qsgmii)
- SWITCH_PORT(29, 30, qsgmii)
- SWITCH_PORT(30, 31, qsgmii)
- SWITCH_PORT(31, 32, qsgmii)
-
- SWITCH_PORT(32, 33, qsgmii)
- SWITCH_PORT(33, 34, qsgmii)
- SWITCH_PORT(34, 35, qsgmii)
- SWITCH_PORT(35, 36, qsgmii)
- SWITCH_PORT(36, 37, qsgmii)
- SWITCH_PORT(37, 38, qsgmii)
- SWITCH_PORT(38, 39, qsgmii)
- SWITCH_PORT(39, 40, qsgmii)
-
- SWITCH_PORT(40, 41, qsgmii)
- SWITCH_PORT(41, 42, qsgmii)
- SWITCH_PORT(42, 43, qsgmii)
- SWITCH_PORT(43, 44, qsgmii)
- SWITCH_PORT(44, 45, qsgmii)
- SWITCH_PORT(45, 46, qsgmii)
- SWITCH_PORT(46, 47, qsgmii)
- SWITCH_PORT(47, 48, qsgmii)
-
- SWITCH_PORT(48, 49, qsgmii)
- SWITCH_PORT(49, 50, qsgmii)
- SWITCH_PORT(50, 51, qsgmii)
- SWITCH_PORT(51, 52, qsgmii)
-
- /* CPU-Port */
- port@52 {
- ethernet = <&ethernet0>;
- reg = <52>;
- phy-mode = "qsgmii";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
-};
diff --git a/target/linux/realtek/dts-5.15/rtl8380_d-link_dgs-1210-10mp-f.dts b/target/linux/realtek/dts/rtl8380_d-link_dgs-1210-10mp-f.dts
index 664cab5999..664cab5999 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_d-link_dgs-1210-10mp-f.dts
+++ b/target/linux/realtek/dts/rtl8380_d-link_dgs-1210-10mp-f.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_engenius_ews2910p.dts b/target/linux/realtek/dts/rtl8380_engenius_ews2910p.dts
index 289ec86274..289ec86274 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_engenius_ews2910p.dts
+++ b/target/linux/realtek/dts/rtl8380_engenius_ews2910p.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g-poe-180w.dts b/target/linux/realtek/dts/rtl8380_hpe_1920-8g-poe-180w.dts
index 6398e6d034..6398e6d034 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g-poe-180w.dts
+++ b/target/linux/realtek/dts/rtl8380_hpe_1920-8g-poe-180w.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g-poe-65w.dts b/target/linux/realtek/dts/rtl8380_hpe_1920-8g-poe-65w.dts
index 341f535e93..341f535e93 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g-poe-65w.dts
+++ b/target/linux/realtek/dts/rtl8380_hpe_1920-8g-poe-65w.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g.dts b/target/linux/realtek/dts/rtl8380_hpe_1920-8g.dts
index ac95a00c01..ac95a00c01 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_hpe_1920-8g.dts
+++ b/target/linux/realtek/dts/rtl8380_hpe_1920-8g.dts
diff --git a/target/linux/realtek/dts/rtl8380_hpe_1920-8g.dtsi b/target/linux/realtek/dts/rtl8380_hpe_1920-8g.dtsi
new file mode 100644
index 0000000000..262dd83d21
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8380_hpe_1920-8g.dtsi
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl838x.dtsi"
+#include "rtl83xx_hpe_1920.dtsi"
+
+/ {
+ gpio1: rtl8231-gpio {
+ compatible = "realtek,rtl8231-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ indirect-access-bus-id = <0>;
+ };
+
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-0 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ // tx-fault and tx-disable unconnected
+ };
+
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-1 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ // tx-fault and tx-disable unconnected
+ };
+};
+
+&ethernet0 {
+ mdio: mdio-bus {
+ compatible = "realtek,rtl838x-mdio";
+ regmap = <&ethernet0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ INTERNAL_PHY(8)
+ INTERNAL_PHY(9)
+ INTERNAL_PHY(10)
+ INTERNAL_PHY(11)
+ INTERNAL_PHY(12)
+ INTERNAL_PHY(13)
+ INTERNAL_PHY(14)
+ INTERNAL_PHY(15)
+
+ INTERNAL_PHY(24)
+ INTERNAL_PHY(26)
+ };
+};
+
+&switch0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ SWITCH_PORT(8, 1, internal)
+ SWITCH_PORT(9, 2, internal)
+ SWITCH_PORT(10, 3, internal)
+ SWITCH_PORT(11, 4, internal)
+ SWITCH_PORT(12, 5, internal)
+ SWITCH_PORT(13, 6, internal)
+ SWITCH_PORT(14, 7, internal)
+ SWITCH_PORT(15, 8, internal)
+
+ port@24 {
+ reg = <24>;
+ label = "lan9";
+ phy-handle = <&phy24>;
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp0>;
+ };
+
+ port@26 {
+ reg = <26>;
+ label = "lan10";
+ phy-handle = <&phy26>;
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp1>;
+ };
+
+ port@28 {
+ ethernet = <&ethernet0>;
+ reg = <28>;
+ phy-mode = "internal";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+};
diff --git a/target/linux/realtek/dts/rtl8380_linksys_lgs310c.dts b/target/linux/realtek/dts/rtl8380_linksys_lgs310c.dts
new file mode 100644
index 0000000000..08ef740399
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8380_linksys_lgs310c.dts
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#include "rtl838x.dtsi"
+
+/ {
+ compatible = "linksys,lgs310c", "realtek,rtl838x-soc";
+ model = "Linksys LGS310C";
+
+ aliases {
+ led-boot = &led_power;
+ led-failsafe = &led_fault;
+ led-running = &led_power;
+ led-upgrade = &led_power;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x10000000>;
+ };
+
+ leds: leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinmux_disable_sys_led>;
+ compatible = "gpio-leds";
+
+ led_power: led-0 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ };
+
+ led_fault: led-1 {
+ function = LED_FUNCTION_FAULT;
+ color = <LED_COLOR_ID_AMBER>;
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ };
+
+ };
+
+ /* i2c of the left SFP cage: port 9 */
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-p9 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* i2c of the right SFP cage: port 10 */
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+/*
+ * ports 9 & 10 use a shared SCL, and are currently not usable in parallel
+ * So for now disable the SCL on the second port.
+ *
+ * scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ */
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-p10 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ gpio1: rtl8231-gpio {
+ compatible = "realtek,rtl8231-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ indirect-access-bus-id = <0>;
+ };
+};
+
+&spi0 {
+ status = "okay";
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000000 0x80000>;
+ read-only;
+ };
+ partition@80000 {
+ label = "u-boot-env";
+ reg = <0x00080000 0x10000>;
+ };
+ partition@90000 {
+ label = "u-boot-env2";
+ reg = <0x00090000 0x10000>;
+ };
+ partition@a0000 {
+ label = "jffs2";
+ reg = <0x000a0000 0x500000>;
+ };
+ partition@5a0000 {
+ label = "firmware";
+ compatible = "openwrt,uimage";
+ reg = <0x005a0000 0xd30000>;
+ };
+ partition@2d0000 {
+ label = "kernel2";
+ reg = <0x012d0000 0xd30000>;
+ };
+ };
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&ethernet0 {
+ mdio: mdio-bus {
+ compatible = "realtek,rtl838x-mdio";
+ regmap = <&ethernet0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ INTERNAL_PHY(8)
+ INTERNAL_PHY(9)
+ INTERNAL_PHY(10)
+ INTERNAL_PHY(11)
+ INTERNAL_PHY(12)
+ INTERNAL_PHY(13)
+ INTERNAL_PHY(14)
+ INTERNAL_PHY(15)
+ INTERNAL_PHY(24)
+ INTERNAL_PHY(26)
+ };
+};
+
+&switch0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ SWITCH_PORT(8, 1, internal)
+ SWITCH_PORT(9, 2, internal)
+ SWITCH_PORT(10, 3, internal)
+ SWITCH_PORT(11, 4, internal)
+ SWITCH_PORT(12, 5, internal)
+ SWITCH_PORT(13, 6, internal)
+ SWITCH_PORT(14, 7, internal)
+ SWITCH_PORT(15, 8, internal)
+
+ port@24 {
+ reg = <24>;
+ label = "lan9";
+ phy-handle = <&phy24>;
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp0>;
+ };
+
+ port@26 {
+ reg = <26>;
+ label = "lan10";
+ phy-handle = <&phy26>;
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp1>;
+ };
+
+ port@28 {
+ ethernet = <&ethernet0>;
+ reg = <28>;
+ phy-mode = "internal";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+};
diff --git a/target/linux/realtek/dts-5.15/rtl8380_netgear_gigabit.dtsi b/target/linux/realtek/dts/rtl8380_netgear_gigabit.dtsi
index aca1a14774..aca1a14774 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_netgear_gigabit.dtsi
+++ b/target/linux/realtek/dts/rtl8380_netgear_gigabit.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs108t-v3.dts b/target/linux/realtek/dts/rtl8380_netgear_gs108t-v3.dts
index b26ebb9806..b26ebb9806 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs108t-v3.dts
+++ b/target/linux/realtek/dts/rtl8380_netgear_gs108t-v3.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs110tpp-v1.dts b/target/linux/realtek/dts/rtl8380_netgear_gs110tpp-v1.dts
index f694ae3317..f694ae3317 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs110tpp-v1.dts
+++ b/target/linux/realtek/dts/rtl8380_netgear_gs110tpp-v1.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs110tup-v1.dts b/target/linux/realtek/dts/rtl8380_netgear_gs110tup-v1.dts
index 335aff2cf0..335aff2cf0 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs110tup-v1.dts
+++ b/target/linux/realtek/dts/rtl8380_netgear_gs110tup-v1.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs308t-v1.dts b/target/linux/realtek/dts/rtl8380_netgear_gs308t-v1.dts
index 5d77cf8c36..5d77cf8c36 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs308t-v1.dts
+++ b/target/linux/realtek/dts/rtl8380_netgear_gs308t-v1.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs310tp-v1.dts b/target/linux/realtek/dts/rtl8380_netgear_gs310tp-v1.dts
index a6f7181c11..a6f7181c11 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_netgear_gs310tp-v1.dts
+++ b/target/linux/realtek/dts/rtl8380_netgear_gs310tp-v1.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_panasonic_m8eg-pn28080k.dts b/target/linux/realtek/dts/rtl8380_panasonic_m8eg-pn28080k.dts
index bd59ff36f4..bd59ff36f4 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_panasonic_m8eg-pn28080k.dts
+++ b/target/linux/realtek/dts/rtl8380_panasonic_m8eg-pn28080k.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_tplink_sg2008p-v1.dts b/target/linux/realtek/dts/rtl8380_tplink_sg2008p-v1.dts
index bf43e412b1..bf43e412b1 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_tplink_sg2008p-v1.dts
+++ b/target/linux/realtek/dts/rtl8380_tplink_sg2008p-v1.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_tplink_sg2210p-v3.dts b/target/linux/realtek/dts/rtl8380_tplink_sg2210p-v3.dts
index 4b0022c388..4b0022c388 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_tplink_sg2210p-v3.dts
+++ b/target/linux/realtek/dts/rtl8380_tplink_sg2210p-v3.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8380_tplink_sg2xxx.dtsi b/target/linux/realtek/dts/rtl8380_tplink_sg2xxx.dtsi
index d30d7b374e..d30d7b374e 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_tplink_sg2xxx.dtsi
+++ b/target/linux/realtek/dts/rtl8380_tplink_sg2xxx.dtsi
diff --git a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts
new file mode 100644
index 0000000000..190a77b7ff
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-10hp", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-10HP Switch";
+
+ /* i2c of the left SFP cage: port 9 */
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-p9 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* i2c of the right SFP cage: port 10 */
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-p10 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&mdio {
+ INTERNAL_PHY(24)
+ INTERNAL_PHY(26)
+};
+
+&switch0 {
+ ports {
+ port@24 {
+ reg = <24>;
+ label = "lan9";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp0>;
+ };
+
+ port@26 {
+ reg = <26>;
+ label = "lan10";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp1>;
+ };
+ };
+};
diff --git a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8.dts b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8.dts
new file mode 100644
index 0000000000..548e83ba73
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-8", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-8v1/v2 Switch";
+};
+
+&gpio1 {
+ /delete-node/ poe_enable;
+};
diff --git a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v1.dts b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v1.dts
new file mode 100644
index 0000000000..386edfb015
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v1.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-8hp-v1", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-8HP v1 Switch";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v2.dts b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v2.dts
new file mode 100644
index 0000000000..2702f2ba1c
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-8hp-v2.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-8hp-v2", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-8HP v2 Switch";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900.dtsi b/target/linux/realtek/dts/rtl8380_zyxel_gs1900.dtsi
index 5993c1b798..5993c1b798 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900.dtsi
+++ b/target/linux/realtek/dts/rtl8380_zyxel_gs1900.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl8382_allnet_all-sg8208m.dts b/target/linux/realtek/dts/rtl8382_allnet_all-sg8208m.dts
index 320cb08ac7..320cb08ac7 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_allnet_all-sg8208m.dts
+++ b/target/linux/realtek/dts/rtl8382_allnet_all-sg8208m.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_apresia_aplgs120gtss.dts b/target/linux/realtek/dts/rtl8382_apresia_aplgs120gtss.dts
index de17958af1..de17958af1 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_apresia_aplgs120gtss.dts
+++ b/target/linux/realtek/dts/rtl8382_apresia_aplgs120gtss.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-10p.dts b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-10p.dts
index 1aef88afd4..1aef88afd4 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-10p.dts
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-10p.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-16.dts b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-16.dts
index c9a79fb607..c9a79fb607 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-16.dts
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-16.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-20.dts b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-20.dts
index dacc50676d..dacc50676d 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_d-link_dgs-1210-20.dts
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-20.dts
diff --git a/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28.dts b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28.dts
new file mode 100644
index 0000000000..29ff8153fb
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl838x.dtsi"
+#include "rtl83xx_d-link_dgs-1210_common.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio_sfp.dtsi"
+#include "rtl8382_d-link_dgs-1210-28_common.dtsi"
+
+/ {
+ compatible = "d-link,dgs-1210-28", "realtek,rtl838x-soc";
+ model = "D-Link DGS-1210-28";
+};
diff --git a/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28_common.dtsi b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28_common.dtsi
new file mode 100644
index 0000000000..d5b984b0a6
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28_common.dtsi
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+&ethernet0 {
+ mdio: mdio-bus {
+ compatible = "realtek,rtl838x-mdio";
+ regmap = <&ethernet0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ INTERNAL_PHY(8)
+ INTERNAL_PHY(9)
+ INTERNAL_PHY(10)
+ INTERNAL_PHY(11)
+ INTERNAL_PHY(12)
+ INTERNAL_PHY(13)
+ INTERNAL_PHY(14)
+ INTERNAL_PHY(15)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+
+ /* External phy RTL8214FC */
+ EXTERNAL_SFP_PHY_FULL(24, 0)
+ EXTERNAL_SFP_PHY_FULL(25, 1)
+ EXTERNAL_SFP_PHY_FULL(26, 2)
+ EXTERNAL_SFP_PHY_FULL(27, 3)
+ };
+};
+
+&switch0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ SWITCH_PORT(0, 1, qsgmii)
+ SWITCH_PORT(1, 2, qsgmii)
+ SWITCH_PORT(2, 3, qsgmii)
+ SWITCH_PORT(3, 4, qsgmii)
+ SWITCH_PORT(4, 5, qsgmii)
+ SWITCH_PORT(5, 6, qsgmii)
+ SWITCH_PORT(6, 7, qsgmii)
+ SWITCH_PORT(7, 8, qsgmii)
+
+ SWITCH_PORT(8, 9, internal)
+ SWITCH_PORT(9, 10, internal)
+ SWITCH_PORT(10, 11, internal)
+ SWITCH_PORT(11, 12, internal)
+ SWITCH_PORT(12, 13, internal)
+ SWITCH_PORT(13, 14, internal)
+ SWITCH_PORT(14, 15, internal)
+ SWITCH_PORT(15, 16, internal)
+
+ SWITCH_PORT(16, 17, qsgmii)
+ SWITCH_PORT(17, 18, qsgmii)
+ SWITCH_PORT(18, 19, qsgmii)
+ SWITCH_PORT(19, 20, qsgmii)
+ SWITCH_PORT(20, 21, qsgmii)
+ SWITCH_PORT(21, 22, qsgmii)
+ SWITCH_PORT(22, 23, qsgmii)
+ SWITCH_PORT(23, 24, qsgmii)
+
+ SWITCH_PORT(24, 25, qsgmii)
+ SWITCH_PORT(25, 26, qsgmii)
+ SWITCH_PORT(26, 27, qsgmii)
+ SWITCH_PORT(27, 28, qsgmii)
+
+ port@28 {
+ ethernet = <&ethernet0>;
+ reg = <28>;
+ phy-mode = "internal";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+};
diff --git a/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28mp-f.dts b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28mp-f.dts
new file mode 100644
index 0000000000..4aa6498b03
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28mp-f.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl838x.dtsi"
+#include "rtl83xx_d-link_dgs-1210_common.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio_sfp.dtsi"
+#include "rtl8382_d-link_dgs-1210-28_common.dtsi"
+#include "rtl8382_d-link_dgs-1210-28p_common.dtsi"
+
+/ {
+ compatible = "d-link,dgs-1210-28mp-f", "realtek,rtl8382-soc", "realtek,rtl838x-soc";
+ model = "D-Link DGS-1210-28MP F";
+
+};
diff --git a/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p-f.dts b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p-f.dts
new file mode 100644
index 0000000000..6cb8db81bc
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p-f.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl838x.dtsi"
+#include "rtl83xx_d-link_dgs-1210_common.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio_sfp.dtsi"
+#include "rtl8382_d-link_dgs-1210-28_common.dtsi"
+#include "rtl8382_d-link_dgs-1210-28p_common.dtsi"
+
+/ {
+ compatible = "d-link,dgs-1210-28p-f", "realtek,rtl8382-soc", "realtek,rtl838x-soc";
+ model = "D-Link DGS-1210-28P F";
+};
diff --git a/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p_common.dtsi b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p_common.dtsi
new file mode 100644
index 0000000000..8aaa637afe
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_d-link_dgs-1210-28p_common.dtsi
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/ {
+ /* LM63 */
+ i2c-gpio-4 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 32 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+ i2c-gpio,delay-us = <2>;
+ i2c-gpio,scl-open-drain; /* should be replaced by i2c-gpio,scl-has-no-pullup in kernel 6.6 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lm63@4c {
+ compatible = "national,lm63";
+ reg = <0x4c>;
+ };
+ };
+};
+
+&leds {
+ link_act {
+ label = "green:link_act";
+ gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
+ };
+
+ poe {
+ label = "green:poe";
+ gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ };
+
+ poe_max {
+ label = "yellow:poe_max";
+ gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&keys {
+ mode {
+ label = "mode";
+ gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_hpe_1920-16g.dts b/target/linux/realtek/dts/rtl8382_hpe_1920-16g.dts
index 59043b2f6f..59043b2f6f 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_hpe_1920-16g.dts
+++ b/target/linux/realtek/dts/rtl8382_hpe_1920-16g.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_hpe_1920-24g.dts b/target/linux/realtek/dts/rtl8382_hpe_1920-24g.dts
index 61781c708e..61781c708e 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_hpe_1920-24g.dts
+++ b/target/linux/realtek/dts/rtl8382_hpe_1920-24g.dts
diff --git a/target/linux/realtek/dts/rtl8382_hpe_1920.dtsi b/target/linux/realtek/dts/rtl8382_hpe_1920.dtsi
new file mode 100644
index 0000000000..af168067d4
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_hpe_1920.dtsi
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl838x.dtsi"
+#include "rtl83xx_hpe_1920.dtsi"
+
+/ {
+ gpio1: rtl8231-gpio {
+ compatible = "realtek,rtl8231-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ indirect-access-bus-id = <0>;
+ };
+
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-0 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected
+ // tx-disable connected to RTL8214FC
+ };
+
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-1 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected
+ // tx-disable connected to RTL8214FC
+ };
+
+ i2c2: i2c-gpio-2 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp2: sfp-2 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c2>;
+ los-gpio = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected
+ // tx-disable connected to RTL8214FC
+ };
+
+ i2c3: i2c-gpio-3 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 32 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp3: sfp-3 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c3>;
+ los-gpio = <&gpio1 34 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 33 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected
+ // tx-disable connected to RTL8214FC
+ };
+};
+
+&ethernet0 {
+ mdio: mdio-bus {
+ compatible = "realtek,rtl838x-mdio";
+ regmap = <&ethernet0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ INTERNAL_PHY(8)
+ INTERNAL_PHY(9)
+ INTERNAL_PHY(10)
+ INTERNAL_PHY(11)
+ INTERNAL_PHY(12)
+ INTERNAL_PHY(13)
+ INTERNAL_PHY(14)
+ INTERNAL_PHY(15)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+
+ EXTERNAL_SFP_PHY_FULL(24, 0)
+ EXTERNAL_SFP_PHY_FULL(25, 1)
+ EXTERNAL_SFP_PHY_FULL(26, 2)
+ EXTERNAL_SFP_PHY_FULL(27, 3)
+ };
+};
diff --git a/target/linux/realtek/dts-5.15/rtl8382_inaba_aml2-17gp.dts b/target/linux/realtek/dts/rtl8382_inaba_aml2-17gp.dts
index 4808141494..4808141494 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_inaba_aml2-17gp.dts
+++ b/target/linux/realtek/dts/rtl8382_inaba_aml2-17gp.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_iodata_bsh-g24mb.dts b/target/linux/realtek/dts/rtl8382_iodata_bsh-g24mb.dts
index 49b55813f9..49b55813f9 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_iodata_bsh-g24mb.dts
+++ b/target/linux/realtek/dts/rtl8382_iodata_bsh-g24mb.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_panasonic_m16eg-pn28160k.dts b/target/linux/realtek/dts/rtl8382_panasonic_m16eg-pn28160k.dts
index abbfd60085..abbfd60085 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_panasonic_m16eg-pn28160k.dts
+++ b/target/linux/realtek/dts/rtl8382_panasonic_m16eg-pn28160k.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_panasonic_m24eg-pn28240k.dts b/target/linux/realtek/dts/rtl8382_panasonic_m24eg-pn28240k.dts
index d01352ec56..d01352ec56 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_panasonic_m24eg-pn28240k.dts
+++ b/target/linux/realtek/dts/rtl8382_panasonic_m24eg-pn28240k.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8382_tplink_t1600g-28ts-v3.dts b/target/linux/realtek/dts/rtl8382_tplink_t1600g-28ts-v3.dts
index d84987d209..d84987d209 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_tplink_t1600g-28ts-v3.dts
+++ b/target/linux/realtek/dts/rtl8382_tplink_t1600g-28ts-v3.dts
diff --git a/target/linux/realtek/dts/rtl8382_zyxel_gs1900-16.dts b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-16.dts
new file mode 100644
index 0000000000..6010da2e26
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-16.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-16", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-16";
+};
+
+&mdio {
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+};
+
+&switch0 {
+ ports {
+ SWITCH_PORT(16, 9, qsgmii)
+ SWITCH_PORT(17, 10, qsgmii)
+ SWITCH_PORT(18, 11, qsgmii)
+ SWITCH_PORT(19, 12, qsgmii)
+ SWITCH_PORT(20, 13, qsgmii)
+ SWITCH_PORT(21, 14, qsgmii)
+ SWITCH_PORT(22, 15, qsgmii)
+ SWITCH_PORT(23, 16, qsgmii)
+ };
+};
+
+&gpio1 {
+ /delete-node/ poe_enable;
+};
diff --git a/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24-v1.dts b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24-v1.dts
new file mode 100644
index 0000000000..6d98e7fae1
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24-v1.dts
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-24-v1", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-24 v1";
+
+ memory@0 {
+ reg = <0x0 0x4000000>;
+ };
+
+ /* i2c of the left SFP cage: port 25 */
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-p25 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* i2c of the right SFP cage: port 26 */
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-p26 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&mdio {
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+
+ INTERNAL_PHY(24)
+ INTERNAL_PHY(26)
+};
+
+&switch0 {
+ ports {
+ SWITCH_PORT(0, 1, qsgmii)
+ SWITCH_PORT(1, 2, qsgmii)
+ SWITCH_PORT(2, 3, qsgmii)
+ SWITCH_PORT(3, 4, qsgmii)
+ SWITCH_PORT(4, 5, qsgmii)
+ SWITCH_PORT(5, 6, qsgmii)
+ SWITCH_PORT(6, 7, qsgmii)
+ SWITCH_PORT(7, 8, qsgmii)
+
+ SWITCH_PORT(8, 9, internal)
+ SWITCH_PORT(9, 10, internal)
+ SWITCH_PORT(10, 11, internal)
+ SWITCH_PORT(11, 12, internal)
+ SWITCH_PORT(12, 13, internal)
+ SWITCH_PORT(13, 14, internal)
+ SWITCH_PORT(14, 15, internal)
+ SWITCH_PORT(15, 16, internal)
+
+ SWITCH_PORT(16, 17, qsgmii)
+ SWITCH_PORT(17, 18, qsgmii)
+ SWITCH_PORT(18, 19, qsgmii)
+ SWITCH_PORT(19, 20, qsgmii)
+ SWITCH_PORT(20, 21, qsgmii)
+ SWITCH_PORT(21, 22, qsgmii)
+ SWITCH_PORT(22, 23, qsgmii)
+ SWITCH_PORT(23, 24, qsgmii)
+
+ port@24 {
+ reg = <24>;
+ label = "lan25";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp0>;
+ };
+
+ port@26 {
+ reg = <26>;
+ label = "lan26";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp1>;
+ };
+ };
+};
+
+&gpio1 {
+ /delete-node/ poe_enable;
+};
diff --git a/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24e.dts b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24e.dts
new file mode 100644
index 0000000000..b455ddf23a
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24e.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-24e", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-24E";
+};
+
+&mdio {
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+};
+
+&switch0 {
+ ports {
+ SWITCH_PORT(1, 1, qsgmii)
+ SWITCH_PORT(0, 2, qsgmii)
+ SWITCH_PORT(3, 3, qsgmii)
+ SWITCH_PORT(2, 4, qsgmii)
+ SWITCH_PORT(5, 5, qsgmii)
+ SWITCH_PORT(4, 6, qsgmii)
+ SWITCH_PORT(7, 7, qsgmii)
+ SWITCH_PORT(6, 8, qsgmii)
+
+ SWITCH_PORT(9, 9, internal)
+ SWITCH_PORT(8, 10, internal)
+ SWITCH_PORT(11, 11, internal)
+ SWITCH_PORT(10, 12, internal)
+ SWITCH_PORT(13, 13, internal)
+ SWITCH_PORT(12, 14, internal)
+ SWITCH_PORT(15, 15, internal)
+ SWITCH_PORT(14, 16, internal)
+
+ SWITCH_PORT(17, 17, qsgmii)
+ SWITCH_PORT(16, 18, qsgmii)
+ SWITCH_PORT(19, 19, qsgmii)
+ SWITCH_PORT(18, 20, qsgmii)
+ SWITCH_PORT(21, 21, qsgmii)
+ SWITCH_PORT(20, 22, qsgmii)
+ SWITCH_PORT(23, 23, qsgmii)
+ SWITCH_PORT(22, 24, qsgmii)
+ };
+};
+
+&gpio1 {
+ /delete-node/ poe_enable;
+};
diff --git a/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24ep.dts b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24ep.dts
new file mode 100644
index 0000000000..25c82f089e
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24ep.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-24ep", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-24EP Switch";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&mdio {
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+};
+
+&switch0 {
+ ports {
+ SWITCH_PORT(0, 1, qsgmii)
+ SWITCH_PORT(1, 2, qsgmii)
+ SWITCH_PORT(2, 3, qsgmii)
+ SWITCH_PORT(3, 4, qsgmii)
+ SWITCH_PORT(4, 5, qsgmii)
+ SWITCH_PORT(5, 6, qsgmii)
+ SWITCH_PORT(6, 7, qsgmii)
+ SWITCH_PORT(7, 8, qsgmii)
+
+ SWITCH_PORT(8, 9, internal)
+ SWITCH_PORT(9, 10, internal)
+ SWITCH_PORT(10, 11, internal)
+ SWITCH_PORT(11, 12, internal)
+ SWITCH_PORT(12, 13, internal)
+ SWITCH_PORT(13, 14, internal)
+ SWITCH_PORT(14, 15, internal)
+ SWITCH_PORT(15, 16, internal)
+
+ SWITCH_PORT(16, 17, qsgmii)
+ SWITCH_PORT(17, 18, qsgmii)
+ SWITCH_PORT(18, 19, qsgmii)
+ SWITCH_PORT(19, 20, qsgmii)
+ SWITCH_PORT(20, 21, qsgmii)
+ SWITCH_PORT(21, 22, qsgmii)
+ SWITCH_PORT(22, 23, qsgmii)
+ SWITCH_PORT(23, 24, qsgmii)
+ };
+};
diff --git a/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v1.dts b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v1.dts
new file mode 100644
index 0000000000..fa9bef89d6
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v1.dts
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-24hp-v1", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-24HP v1";
+
+ memory@0 {
+ reg = <0x0 0x4000000>;
+ };
+
+ /* i2c of the left SFP cage: port 25 */
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-p25 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* i2c of the right SFP cage: port 26 */
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-p26 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&mdio {
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+
+ INTERNAL_PHY(24)
+ INTERNAL_PHY(26)
+};
+
+&switch0 {
+ ports {
+ SWITCH_PORT(0, 1, qsgmii)
+ SWITCH_PORT(1, 2, qsgmii)
+ SWITCH_PORT(2, 3, qsgmii)
+ SWITCH_PORT(3, 4, qsgmii)
+ SWITCH_PORT(4, 5, qsgmii)
+ SWITCH_PORT(5, 6, qsgmii)
+ SWITCH_PORT(6, 7, qsgmii)
+ SWITCH_PORT(7, 8, qsgmii)
+
+ SWITCH_PORT(8, 9, internal)
+ SWITCH_PORT(9, 10, internal)
+ SWITCH_PORT(10, 11, internal)
+ SWITCH_PORT(11, 12, internal)
+ SWITCH_PORT(12, 13, internal)
+ SWITCH_PORT(13, 14, internal)
+ SWITCH_PORT(14, 15, internal)
+ SWITCH_PORT(15, 16, internal)
+
+ SWITCH_PORT(16, 17, qsgmii)
+ SWITCH_PORT(17, 18, qsgmii)
+ SWITCH_PORT(18, 19, qsgmii)
+ SWITCH_PORT(19, 20, qsgmii)
+ SWITCH_PORT(20, 21, qsgmii)
+ SWITCH_PORT(21, 22, qsgmii)
+ SWITCH_PORT(22, 23, qsgmii)
+ SWITCH_PORT(23, 24, qsgmii)
+
+ port@24 {
+ reg = <24>;
+ label = "lan25";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp0>;
+ };
+
+ port@26 {
+ reg = <26>;
+ label = "lan26";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp1>;
+ };
+ };
+};
+
diff --git a/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v2.dts b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v2.dts
new file mode 100644
index 0000000000..93011cbdaa
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8382_zyxel_gs1900-24hp-v2.dts
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl8380_zyxel_gs1900.dtsi"
+
+/ {
+ compatible = "zyxel,gs1900-24hp-v2", "realtek,rtl838x-soc";
+ model = "Zyxel GS1900-24HP v2 Switch";
+
+ /* i2c of the left SFP cage: port 25 */
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-p25 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 26 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* i2c of the right SFP cage: port 26 */
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-p26 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio1 33 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 32 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&mdio {
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+
+ INTERNAL_PHY(24)
+ INTERNAL_PHY(26)
+};
+
+&switch0 {
+ ports {
+ SWITCH_PORT(0, 1, qsgmii)
+ SWITCH_PORT(1, 2, qsgmii)
+ SWITCH_PORT(2, 3, qsgmii)
+ SWITCH_PORT(3, 4, qsgmii)
+ SWITCH_PORT(4, 5, qsgmii)
+ SWITCH_PORT(5, 6, qsgmii)
+ SWITCH_PORT(6, 7, qsgmii)
+ SWITCH_PORT(7, 8, qsgmii)
+
+ SWITCH_PORT(8, 9, internal)
+ SWITCH_PORT(9, 10, internal)
+ SWITCH_PORT(10, 11, internal)
+ SWITCH_PORT(11, 12, internal)
+ SWITCH_PORT(12, 13, internal)
+ SWITCH_PORT(13, 14, internal)
+ SWITCH_PORT(14, 15, internal)
+ SWITCH_PORT(15, 16, internal)
+
+ SWITCH_PORT(16, 17, qsgmii)
+ SWITCH_PORT(17, 18, qsgmii)
+ SWITCH_PORT(18, 19, qsgmii)
+ SWITCH_PORT(19, 20, qsgmii)
+ SWITCH_PORT(20, 21, qsgmii)
+ SWITCH_PORT(21, 22, qsgmii)
+ SWITCH_PORT(22, 23, qsgmii)
+ SWITCH_PORT(23, 24, qsgmii)
+
+
+ port@24 {
+ reg = <24>;
+ label = "lan25";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp0>;
+ };
+
+ port@26 {
+ reg = <26>;
+ label = "lan26";
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
+ sfp = <&sfp1>;
+ };
+ };
+};
diff --git a/target/linux/realtek/dts-5.15/rtl838x.dtsi b/target/linux/realtek/dts/rtl838x.dtsi
index 13ba6450b2..13ba6450b2 100644
--- a/target/linux/realtek/dts-5.15/rtl838x.dtsi
+++ b/target/linux/realtek/dts/rtl838x.dtsi
diff --git a/target/linux/realtek/dts/rtl8393_d-link_dgs-1210-52.dts b/target/linux/realtek/dts/rtl8393_d-link_dgs-1210-52.dts
new file mode 100644
index 0000000000..3ddf56f4f5
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8393_d-link_dgs-1210-52.dts
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl839x.dtsi"
+#include "rtl83xx_d-link_dgs-1210_common.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio.dtsi"
+#include "rtl83xx_d-link_dgs-1210_gpio_sfp.dtsi"
+
+/ {
+ compatible = "d-link,dgs-1210-52", "realtek,rtl8393-soc";
+ model = "D-Link DGS-1210-52";
+};
+
+&ethernet0 {
+ mdio: mdio-bus {
+ compatible = "realtek,rtl838x-mdio";
+ regmap = <&ethernet0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* External phy RTL8218B #1 */
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ /* External phy RTL8218B #2 */
+ EXTERNAL_PHY(8)
+ EXTERNAL_PHY(9)
+ EXTERNAL_PHY(10)
+ EXTERNAL_PHY(11)
+ EXTERNAL_PHY(12)
+ EXTERNAL_PHY(13)
+ EXTERNAL_PHY(14)
+ EXTERNAL_PHY(15)
+
+ /* External phy RTL8218B #3 */
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+
+ /* External phy RTL8218B #4 */
+ EXTERNAL_PHY(24)
+ EXTERNAL_PHY(25)
+ EXTERNAL_PHY(26)
+ EXTERNAL_PHY(27)
+ EXTERNAL_PHY(28)
+ EXTERNAL_PHY(29)
+ EXTERNAL_PHY(30)
+ EXTERNAL_PHY(31)
+
+ /* External phy RTL8218B #5 */
+ EXTERNAL_PHY(32)
+ EXTERNAL_PHY(33)
+ EXTERNAL_PHY(34)
+ EXTERNAL_PHY(35)
+ EXTERNAL_PHY(36)
+ EXTERNAL_PHY(37)
+ EXTERNAL_PHY(38)
+ EXTERNAL_PHY(39)
+
+ /* External phy RTL8218B #6 */
+ EXTERNAL_PHY(40)
+ EXTERNAL_PHY(41)
+ EXTERNAL_PHY(42)
+ EXTERNAL_PHY(43)
+ EXTERNAL_PHY(44)
+ EXTERNAL_PHY(45)
+ EXTERNAL_PHY(46)
+ EXTERNAL_PHY(47)
+
+ /* External phy RTL8214FC */
+ EXTERNAL_SFP_PHY_FULL(48, 0)
+ EXTERNAL_SFP_PHY_FULL(49, 1)
+ EXTERNAL_SFP_PHY_FULL(50, 2)
+ EXTERNAL_SFP_PHY_FULL(51, 3)
+ };
+};
+
+&switch0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ SWITCH_PORT(0, 1, qsgmii)
+ SWITCH_PORT(1, 2, qsgmii)
+ SWITCH_PORT(2, 3, qsgmii)
+ SWITCH_PORT(3, 4, qsgmii)
+ SWITCH_PORT(4, 5, qsgmii)
+ SWITCH_PORT(5, 6, qsgmii)
+ SWITCH_PORT(6, 7, qsgmii)
+ SWITCH_PORT(7, 8, qsgmii)
+
+ SWITCH_PORT(8, 9, qsgmii)
+ SWITCH_PORT(9, 10, qsgmii)
+ SWITCH_PORT(10, 11, qsgmii)
+ SWITCH_PORT(11, 12, qsgmii)
+ SWITCH_PORT(12, 13, qsgmii)
+ SWITCH_PORT(13, 14, qsgmii)
+ SWITCH_PORT(14, 15, qsgmii)
+ SWITCH_PORT(15, 16, qsgmii)
+
+ SWITCH_PORT(16, 17, qsgmii)
+ SWITCH_PORT(17, 18, qsgmii)
+ SWITCH_PORT(18, 19, qsgmii)
+ SWITCH_PORT(19, 20, qsgmii)
+ SWITCH_PORT(20, 21, qsgmii)
+ SWITCH_PORT(21, 22, qsgmii)
+ SWITCH_PORT(22, 23, qsgmii)
+ SWITCH_PORT(23, 24, qsgmii)
+
+ SWITCH_PORT(24, 25, qsgmii)
+ SWITCH_PORT(25, 26, qsgmii)
+ SWITCH_PORT(26, 27, qsgmii)
+ SWITCH_PORT(27, 28, qsgmii)
+ SWITCH_PORT(28, 29, qsgmii)
+ SWITCH_PORT(29, 30, qsgmii)
+ SWITCH_PORT(30, 31, qsgmii)
+ SWITCH_PORT(31, 32, qsgmii)
+
+ SWITCH_PORT(32, 33, qsgmii)
+ SWITCH_PORT(33, 34, qsgmii)
+ SWITCH_PORT(34, 35, qsgmii)
+ SWITCH_PORT(35, 36, qsgmii)
+ SWITCH_PORT(36, 37, qsgmii)
+ SWITCH_PORT(37, 38, qsgmii)
+ SWITCH_PORT(38, 39, qsgmii)
+ SWITCH_PORT(39, 40, qsgmii)
+
+ SWITCH_PORT(40, 41, qsgmii)
+ SWITCH_PORT(41, 42, qsgmii)
+ SWITCH_PORT(42, 43, qsgmii)
+ SWITCH_PORT(43, 44, qsgmii)
+ SWITCH_PORT(44, 45, qsgmii)
+ SWITCH_PORT(45, 46, qsgmii)
+ SWITCH_PORT(46, 47, qsgmii)
+ SWITCH_PORT(47, 48, qsgmii)
+
+ SWITCH_PORT(48, 49, qsgmii)
+ SWITCH_PORT(49, 50, qsgmii)
+ SWITCH_PORT(50, 51, qsgmii)
+ SWITCH_PORT(51, 52, qsgmii)
+
+ /* CPU-Port */
+ port@52 {
+ ethernet = <&ethernet0>;
+ reg = <52>;
+ phy-mode = "qsgmii";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+};
diff --git a/target/linux/realtek/dts/rtl8393_hpe_1920-48g-poe.dts b/target/linux/realtek/dts/rtl8393_hpe_1920-48g-poe.dts
new file mode 100644
index 0000000000..e242775434
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8393_hpe_1920-48g-poe.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl8393_hpe_1920.dtsi"
+
+/ {
+ compatible = "hpe,1920-48g-poe", "realtek,rtl8393-soc";
+ model = "HPE 1920-48G-PoE (JG928A)";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/target/linux/realtek/dts/rtl8393_hpe_1920-48g.dts b/target/linux/realtek/dts/rtl8393_hpe_1920-48g.dts
new file mode 100644
index 0000000000..b6a6a1c433
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8393_hpe_1920-48g.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl8393_hpe_1920.dtsi"
+
+/ {
+ compatible = "hpe,1920-48g", "realtek,rtl8393-soc";
+ model = "HPE 1920-48G (JG927A)";
+};
diff --git a/target/linux/realtek/dts/rtl8393_hpe_1920.dtsi b/target/linux/realtek/dts/rtl8393_hpe_1920.dtsi
new file mode 100644
index 0000000000..dda29e59e1
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8393_hpe_1920.dtsi
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl839x.dtsi"
+#include "rtl83xx_hpe_1920.dtsi"
+
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ led-boot = &led_power;
+ led-failsafe = &led_power;
+ led-running = &led_power;
+ led-upgrade = &led_power;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power: led-0 {
+ label = "green:power";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio0 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio0 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-p49 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio0 19 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected (TODO?)
+ // tx-disable connected to RTL8214FC (TODO?)
+ };
+
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio0 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio0 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-p50 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected (TODO?)
+ // tx-disable connected to RTL8214FC (TODO?)
+ };
+
+ // not enabled due to shared I2C clock
+ i2c2: i2c-gpio-2 {
+ status = "disabled";
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio0 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio0 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp2: sfp-p51 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c2>;
+ los-gpio = <&gpio0 23 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio0 22 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected (TODO?)
+ // tx-disable connected to RTL8214FC (TODO?)
+ };
+
+ // not enabled due to shared I2C clock
+ i2c3: i2c-gpio-3 {
+ status = "disabled";
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio0 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio0 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp3: sfp-p52 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c3>;
+ los-gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio0 15 GPIO_ACTIVE_LOW>;
+ // tx-fault unconnected (TODO?)
+ // tx-disable connected to RTL8214FC (TODO?)
+ };
+};
+
+&ethernet0 {
+ mdio: mdio-bus {
+ compatible = "realtek,rtl838x-mdio";
+ regmap = <&ethernet0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ EXTERNAL_PHY(0)
+ EXTERNAL_PHY(1)
+ EXTERNAL_PHY(2)
+ EXTERNAL_PHY(3)
+ EXTERNAL_PHY(4)
+ EXTERNAL_PHY(5)
+ EXTERNAL_PHY(6)
+ EXTERNAL_PHY(7)
+
+ EXTERNAL_PHY(8)
+ EXTERNAL_PHY(9)
+ EXTERNAL_PHY(10)
+ EXTERNAL_PHY(11)
+ EXTERNAL_PHY(12)
+ EXTERNAL_PHY(13)
+ EXTERNAL_PHY(14)
+ EXTERNAL_PHY(15)
+
+ EXTERNAL_PHY(16)
+ EXTERNAL_PHY(17)
+ EXTERNAL_PHY(18)
+ EXTERNAL_PHY(19)
+ EXTERNAL_PHY(20)
+ EXTERNAL_PHY(21)
+ EXTERNAL_PHY(22)
+ EXTERNAL_PHY(23)
+
+ EXTERNAL_PHY(24)
+ EXTERNAL_PHY(25)
+ EXTERNAL_PHY(26)
+ EXTERNAL_PHY(27)
+ EXTERNAL_PHY(28)
+ EXTERNAL_PHY(29)
+ EXTERNAL_PHY(30)
+ EXTERNAL_PHY(31)
+
+ EXTERNAL_PHY(32)
+ EXTERNAL_PHY(33)
+ EXTERNAL_PHY(34)
+ EXTERNAL_PHY(35)
+ EXTERNAL_PHY(36)
+ EXTERNAL_PHY(37)
+ EXTERNAL_PHY(38)
+ EXTERNAL_PHY(39)
+
+ EXTERNAL_PHY(40)
+ EXTERNAL_PHY(41)
+ EXTERNAL_PHY(42)
+ EXTERNAL_PHY(43)
+ EXTERNAL_PHY(44)
+ EXTERNAL_PHY(45)
+ EXTERNAL_PHY(46)
+ EXTERNAL_PHY(47)
+
+ EXTERNAL_SFP_PHY_FULL(48, 1)
+ EXTERNAL_SFP_PHY_FULL(49, 3)
+ EXTERNAL_SFP_PHY_FULL(50, 0)
+ EXTERNAL_SFP_PHY_FULL(51, 2)
+ };
+};
+
+&switch0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ SWITCH_PORT(0, 1, qsgmii)
+ SWITCH_PORT(1, 2, qsgmii)
+ SWITCH_PORT(2, 3, qsgmii)
+ SWITCH_PORT(3, 4, qsgmii)
+ SWITCH_PORT(4, 5, qsgmii)
+ SWITCH_PORT(5, 6, qsgmii)
+ SWITCH_PORT(6, 7, qsgmii)
+ SWITCH_PORT(7, 8, qsgmii)
+
+ SWITCH_PORT(8, 9, qsgmii)
+ SWITCH_PORT(9, 10, qsgmii)
+ SWITCH_PORT(10, 11, qsgmii)
+ SWITCH_PORT(11, 12, qsgmii)
+ SWITCH_PORT(12, 13, qsgmii)
+ SWITCH_PORT(13, 14, qsgmii)
+ SWITCH_PORT(14, 15, qsgmii)
+ SWITCH_PORT(15, 16, qsgmii)
+
+ SWITCH_PORT(16, 17, qsgmii)
+ SWITCH_PORT(17, 18, qsgmii)
+ SWITCH_PORT(18, 19, qsgmii)
+ SWITCH_PORT(19, 20, qsgmii)
+ SWITCH_PORT(20, 21, qsgmii)
+ SWITCH_PORT(21, 22, qsgmii)
+ SWITCH_PORT(22, 23, qsgmii)
+ SWITCH_PORT(23, 24, qsgmii)
+
+ SWITCH_PORT(24, 25, qsgmii)
+ SWITCH_PORT(25, 26, qsgmii)
+ SWITCH_PORT(26, 27, qsgmii)
+ SWITCH_PORT(27, 28, qsgmii)
+ SWITCH_PORT(28, 29, qsgmii)
+ SWITCH_PORT(29, 30, qsgmii)
+ SWITCH_PORT(30, 31, qsgmii)
+ SWITCH_PORT(31, 32, qsgmii)
+
+ SWITCH_PORT(32, 33, qsgmii)
+ SWITCH_PORT(33, 34, qsgmii)
+ SWITCH_PORT(34, 35, qsgmii)
+ SWITCH_PORT(35, 36, qsgmii)
+ SWITCH_PORT(36, 37, qsgmii)
+ SWITCH_PORT(37, 38, qsgmii)
+ SWITCH_PORT(38, 39, qsgmii)
+ SWITCH_PORT(39, 40, qsgmii)
+
+ SWITCH_PORT(40, 41, qsgmii)
+ SWITCH_PORT(41, 42, qsgmii)
+ SWITCH_PORT(42, 43, qsgmii)
+ SWITCH_PORT(43, 44, qsgmii)
+ SWITCH_PORT(44, 45, qsgmii)
+ SWITCH_PORT(45, 46, qsgmii)
+ SWITCH_PORT(46, 47, qsgmii)
+ SWITCH_PORT(47, 48, qsgmii)
+
+ SWITCH_PORT(48, 50, qsgmii)
+ SWITCH_PORT(49, 52, qsgmii)
+ SWITCH_PORT(50, 49, qsgmii)
+ SWITCH_PORT(51, 51, qsgmii)
+
+ port@52 {
+ ethernet = <&ethernet0>;
+ reg = <52>;
+ phy-mode = "internal";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+};
diff --git a/target/linux/realtek/dts-5.15/rtl8393_netgear_gs750e.dts b/target/linux/realtek/dts/rtl8393_netgear_gs750e.dts
index 5a7ed276bf..5a7ed276bf 100644
--- a/target/linux/realtek/dts-5.15/rtl8393_netgear_gs750e.dts
+++ b/target/linux/realtek/dts/rtl8393_netgear_gs750e.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8393_panasonic_m48eg-pn28480k.dts b/target/linux/realtek/dts/rtl8393_panasonic_m48eg-pn28480k.dts
index 8e7d32de1c..8e7d32de1c 100644
--- a/target/linux/realtek/dts-5.15/rtl8393_panasonic_m48eg-pn28480k.dts
+++ b/target/linux/realtek/dts/rtl8393_panasonic_m48eg-pn28480k.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8393_tplink_sg2452p-v4.dts b/target/linux/realtek/dts/rtl8393_tplink_sg2452p-v4.dts
index 4a19d83fda..4a19d83fda 100644
--- a/target/linux/realtek/dts-5.15/rtl8393_tplink_sg2452p-v4.dts
+++ b/target/linux/realtek/dts/rtl8393_tplink_sg2452p-v4.dts
diff --git a/target/linux/realtek/dts-5.15/rtl8393_zyxel_gs1900-48.dts b/target/linux/realtek/dts/rtl8393_zyxel_gs1900-48.dts
index c7ddd8313a..c7ddd8313a 100644
--- a/target/linux/realtek/dts-5.15/rtl8393_zyxel_gs1900-48.dts
+++ b/target/linux/realtek/dts/rtl8393_zyxel_gs1900-48.dts
diff --git a/target/linux/realtek/dts-5.15/rtl839x.dtsi b/target/linux/realtek/dts/rtl839x.dtsi
index 3f87f5622e..3f87f5622e 100644
--- a/target/linux/realtek/dts-5.15/rtl839x.dtsi
+++ b/target/linux/realtek/dts/rtl839x.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl83xx_d-link_dgs-1210_common.dtsi b/target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_common.dtsi
index fa623d7a90..fa623d7a90 100644
--- a/target/linux/realtek/dts-5.15/rtl83xx_d-link_dgs-1210_common.dtsi
+++ b/target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_common.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl83xx_d-link_dgs-1210_gpio.dtsi b/target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_gpio.dtsi
index b1477aa182..b1477aa182 100644
--- a/target/linux/realtek/dts-5.15/rtl83xx_d-link_dgs-1210_gpio.dtsi
+++ b/target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_gpio.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl839x_d-link_dgs-1210_gpio.dtsi b/target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_gpio_sfp.dtsi
index 260ab67ef3..260ab67ef3 100644
--- a/target/linux/realtek/dts-5.15/rtl839x_d-link_dgs-1210_gpio.dtsi
+++ b/target/linux/realtek/dts/rtl83xx_d-link_dgs-1210_gpio_sfp.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl838x_hpe_1920.dtsi b/target/linux/realtek/dts/rtl83xx_hpe_1920.dtsi
index c7b6013117..c7b6013117 100644
--- a/target/linux/realtek/dts-5.15/rtl838x_hpe_1920.dtsi
+++ b/target/linux/realtek/dts/rtl83xx_hpe_1920.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl83xx_panasonic_mxxeg-pn28xx0k.dtsi b/target/linux/realtek/dts/rtl83xx_panasonic_mxxeg-pn28xx0k.dtsi
index c08034b958..c08034b958 100644
--- a/target/linux/realtek/dts-5.15/rtl83xx_panasonic_mxxeg-pn28xx0k.dtsi
+++ b/target/linux/realtek/dts/rtl83xx_panasonic_mxxeg-pn28xx0k.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl9302_zyxel_xgs1250-12.dts b/target/linux/realtek/dts/rtl9302_zyxel_xgs1250-12.dts
index 0c35d7b004..0c35d7b004 100644
--- a/target/linux/realtek/dts-5.15/rtl9302_zyxel_xgs1250-12.dts
+++ b/target/linux/realtek/dts/rtl9302_zyxel_xgs1250-12.dts
diff --git a/target/linux/realtek/dts-5.15/rtl930x.dtsi b/target/linux/realtek/dts/rtl930x.dtsi
index 9b0a5781a2..9b0a5781a2 100644
--- a/target/linux/realtek/dts-5.15/rtl930x.dtsi
+++ b/target/linux/realtek/dts/rtl930x.dtsi
diff --git a/target/linux/realtek/dts-5.15/rtl931x.dtsi b/target/linux/realtek/dts/rtl931x.dtsi
index 61599e89b5..61599e89b5 100644
--- a/target/linux/realtek/dts-5.15/rtl931x.dtsi
+++ b/target/linux/realtek/dts/rtl931x.dtsi
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c
deleted file mode 100644
index 221428cc77..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c
+++ /dev/null
@@ -1,1717 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include <linux/of_mdio.h>
-#include <linux/of_platform.h>
-#include <net/arp.h>
-#include <net/nexthop.h>
-#include <net/neighbour.h>
-#include <net/netevent.h>
-#include <linux/etherdevice.h>
-#include <linux/if_vlan.h>
-#include <linux/inetdevice.h>
-#include <linux/rhashtable.h>
-#include <linux/of_net.h>
-#include <asm/mach-rtl838x/mach-rtl83xx.h>
-
-#include "rtl83xx.h"
-
-extern struct rtl83xx_soc_info soc_info;
-
-extern const struct rtl838x_reg rtl838x_reg;
-extern const struct rtl838x_reg rtl839x_reg;
-extern const struct rtl838x_reg rtl930x_reg;
-extern const struct rtl838x_reg rtl931x_reg;
-
-extern const struct dsa_switch_ops rtl83xx_switch_ops;
-extern const struct dsa_switch_ops rtl930x_switch_ops;
-
-DEFINE_MUTEX(smi_lock);
-
-int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port)
-{
- u32 msti = 0;
- u32 port_state[4];
- int index, bit;
- int pos = port;
- int n = priv->port_width << 1;
-
- /* Ports above or equal CPU port can never be configured */
- if (port >= priv->cpu_port)
- return -1;
-
- mutex_lock(&priv->reg_mutex);
-
- /* For the RTL839x and following, the bits are left-aligned in the 64/128 bit field */
- if (priv->family_id == RTL8390_FAMILY_ID)
- pos += 12;
- if (priv->family_id == RTL9300_FAMILY_ID)
- pos += 3;
- if (priv->family_id == RTL9310_FAMILY_ID)
- pos += 8;
-
- index = n - (pos >> 4) - 1;
- bit = (pos << 1) % 32;
-
- priv->r->stp_get(priv, msti, port_state);
-
- mutex_unlock(&priv->reg_mutex);
-
- return (port_state[index] >> bit) & 3;
-}
-
-static struct table_reg rtl838x_tbl_regs[] = {
- TBL_DESC(0x6900, 0x6908, 3, 15, 13, 1), /* RTL8380_TBL_L2 */
- TBL_DESC(0x6914, 0x6918, 18, 14, 12, 1), /* RTL8380_TBL_0 */
- TBL_DESC(0xA4C8, 0xA4CC, 6, 14, 12, 1), /* RTL8380_TBL_1 */
-
- TBL_DESC(0x1180, 0x1184, 3, 16, 14, 0), /* RTL8390_TBL_L2 */
- TBL_DESC(0x1190, 0x1194, 17, 15, 12, 0), /* RTL8390_TBL_0 */
- TBL_DESC(0x6B80, 0x6B84, 4, 14, 12, 0), /* RTL8390_TBL_1 */
- TBL_DESC(0x611C, 0x6120, 9, 8, 6, 0), /* RTL8390_TBL_2 */
-
- TBL_DESC(0xB320, 0xB334, 3, 18, 16, 0), /* RTL9300_TBL_L2 */
- TBL_DESC(0xB340, 0xB344, 19, 16, 12, 0), /* RTL9300_TBL_0 */
- TBL_DESC(0xB3A0, 0xB3A4, 20, 16, 13, 0), /* RTL9300_TBL_1 */
- TBL_DESC(0xCE04, 0xCE08, 6, 14, 12, 0), /* RTL9300_TBL_2 */
- TBL_DESC(0xD600, 0xD604, 30, 7, 6, 0), /* RTL9300_TBL_HSB */
- TBL_DESC(0x7880, 0x7884, 22, 9, 8, 0), /* RTL9300_TBL_HSA */
-
- TBL_DESC(0x8500, 0x8508, 8, 19, 15, 0), /* RTL9310_TBL_0 */
- TBL_DESC(0x40C0, 0x40C4, 22, 16, 14, 0), /* RTL9310_TBL_1 */
- TBL_DESC(0x8528, 0x852C, 6, 18, 14, 0), /* RTL9310_TBL_2 */
- TBL_DESC(0x0200, 0x0204, 9, 15, 12, 0), /* RTL9310_TBL_3 */
- TBL_DESC(0x20dc, 0x20e0, 29, 7, 6, 0), /* RTL9310_TBL_4 */
- TBL_DESC(0x7e1c, 0x7e20, 53, 8, 6, 0), /* RTL9310_TBL_5 */
-};
-
-void rtl_table_init(void)
-{
- for (int i = 0; i < RTL_TBL_END; i++)
- mutex_init(&rtl838x_tbl_regs[i].lock);
-}
-
-/* Request access to table t in table access register r
- * Returns a handle to a lock for that table
- */
-struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t)
-{
- if (r >= RTL_TBL_END)
- return NULL;
-
- if (t >= BIT(rtl838x_tbl_regs[r].c_bit-rtl838x_tbl_regs[r].t_bit))
- return NULL;
-
- mutex_lock(&rtl838x_tbl_regs[r].lock);
- rtl838x_tbl_regs[r].tbl = t;
-
- return &rtl838x_tbl_regs[r];
-}
-
-/* Release a table r, unlock the corresponding lock */
-void rtl_table_release(struct table_reg *r)
-{
- if (!r)
- return;
-
-/* pr_info("Unlocking %08x\n", (u32)r); */
- mutex_unlock(&r->lock);
-/* pr_info("Unlock done\n"); */
-}
-
-static int rtl_table_exec(struct table_reg *r, bool is_write, int idx)
-{
- int ret = 0;
- u32 cmd, val;
-
- /* Read/write bit has inverted meaning on RTL838x */
- if (r->rmode)
- cmd = is_write ? 0 : BIT(r->c_bit);
- else
- cmd = is_write ? BIT(r->c_bit) : 0;
-
- cmd |= BIT(r->c_bit + 1); /* Execute bit */
- cmd |= r->tbl << r->t_bit; /* Table type */
- cmd |= idx & (BIT(r->t_bit) - 1); /* Index */
-
- sw_w32(cmd, r->addr);
-
- ret = readx_poll_timeout(sw_r32, r->addr, val,
- !(val & BIT(r->c_bit + 1)), 20, 10000);
- if (ret)
- pr_err("%s: timeout\n", __func__);
-
- return ret;
-}
-
-/* Reads table index idx into the data registers of the table */
-int rtl_table_read(struct table_reg *r, int idx)
-{
- return rtl_table_exec(r, false, idx);
-}
-
-/* Writes the content of the table data registers into the table at index idx */
-int rtl_table_write(struct table_reg *r, int idx)
-{
- return rtl_table_exec(r, true, idx);
-}
-
-/* Returns the address of the ith data register of table register r
- * the address is relative to the beginning of the Switch-IO block at 0xbb000000
- */
-inline u16 rtl_table_data(struct table_reg *r, int i)
-{
- if (i >= r->max_data)
- i = r->max_data - 1;
- return r->data + i * 4;
-}
-
-inline u32 rtl_table_data_r(struct table_reg *r, int i)
-{
- return sw_r32(rtl_table_data(r, i));
-}
-
-inline void rtl_table_data_w(struct table_reg *r, u32 v, int i)
-{
- sw_w32(v, rtl_table_data(r, i));
-}
-
-/* Port register accessor functions for the RTL838x and RTL930X SoCs */
-void rtl838x_mask_port_reg(u64 clear, u64 set, int reg)
-{
- sw_w32_mask((u32)clear, (u32)set, reg);
-}
-
-void rtl838x_set_port_reg(u64 set, int reg)
-{
- sw_w32((u32)set, reg);
-}
-
-u64 rtl838x_get_port_reg(int reg)
-{
- return ((u64)sw_r32(reg));
-}
-
-/* Port register accessor functions for the RTL839x and RTL931X SoCs */
-void rtl839x_mask_port_reg_be(u64 clear, u64 set, int reg)
-{
- sw_w32_mask((u32)(clear >> 32), (u32)(set >> 32), reg);
- sw_w32_mask((u32)(clear & 0xffffffff), (u32)(set & 0xffffffff), reg + 4);
-}
-
-u64 rtl839x_get_port_reg_be(int reg)
-{
- u64 v = sw_r32(reg);
-
- v <<= 32;
- v |= sw_r32(reg + 4);
-
- return v;
-}
-
-void rtl839x_set_port_reg_be(u64 set, int reg)
-{
- sw_w32(set >> 32, reg);
- sw_w32(set & 0xffffffff, reg + 4);
-}
-
-void rtl839x_mask_port_reg_le(u64 clear, u64 set, int reg)
-{
- sw_w32_mask((u32)clear, (u32)set, reg);
- sw_w32_mask((u32)(clear >> 32), (u32)(set >> 32), reg + 4);
-}
-
-void rtl839x_set_port_reg_le(u64 set, int reg)
-{
- sw_w32(set, reg);
- sw_w32(set >> 32, reg + 4);
-}
-
-u64 rtl839x_get_port_reg_le(int reg)
-{
- u64 v = sw_r32(reg + 4);
-
- v <<= 32;
- v |= sw_r32(reg);
-
- return v;
-}
-
-int read_phy(u32 port, u32 page, u32 reg, u32 *val)
-{
- switch (soc_info.family) {
- case RTL8380_FAMILY_ID:
- return rtl838x_read_phy(port, page, reg, val);
- case RTL8390_FAMILY_ID:
- return rtl839x_read_phy(port, page, reg, val);
- case RTL9300_FAMILY_ID:
- return rtl930x_read_phy(port, page, reg, val);
- case RTL9310_FAMILY_ID:
- return rtl931x_read_phy(port, page, reg, val);
- }
-
- return -1;
-}
-
-int write_phy(u32 port, u32 page, u32 reg, u32 val)
-{
- switch (soc_info.family) {
- case RTL8380_FAMILY_ID:
- return rtl838x_write_phy(port, page, reg, val);
- case RTL8390_FAMILY_ID:
- return rtl839x_write_phy(port, page, reg, val);
- case RTL9300_FAMILY_ID:
- return rtl930x_write_phy(port, page, reg, val);
- case RTL9310_FAMILY_ID:
- return rtl931x_write_phy(port, page, reg, val);
- }
-
- return -1;
-}
-
-static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
-{
- struct device *dev = priv->dev;
- struct device_node *dn, *phy_node, *led_node, *mii_np = dev->of_node;
- struct mii_bus *bus;
- int ret;
- u32 pn;
-
- pr_debug("In %s\n", __func__);
- mii_np = of_find_compatible_node(NULL, NULL, "realtek,rtl838x-mdio");
- if (mii_np) {
- pr_debug("Found compatible MDIO node!\n");
- } else {
- dev_err(priv->dev, "no %s child node found", "mdio-bus");
- return -ENODEV;
- }
-
- priv->mii_bus = of_mdio_find_bus(mii_np);
- if (!priv->mii_bus) {
- pr_debug("Deferring probe of mdio bus\n");
- return -EPROBE_DEFER;
- }
- if (!of_device_is_available(mii_np))
- ret = -ENODEV;
-
- bus = devm_mdiobus_alloc(priv->ds->dev);
- if (!bus)
- return -ENOMEM;
-
- bus->name = "rtl838x slave mii";
-
- /* Since the NIC driver is loaded first, we can use the mdio rw functions
- * assigned there.
- */
- bus->read = priv->mii_bus->read;
- bus->write = priv->mii_bus->write;
- bus->read_paged = priv->mii_bus->read_paged;
- bus->write_paged = priv->mii_bus->write_paged;
- snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", bus->name, dev->id);
-
- bus->parent = dev;
- priv->ds->slave_mii_bus = bus;
- priv->ds->slave_mii_bus->priv = priv->mii_bus->priv;
- priv->ds->slave_mii_bus->access_capabilities = priv->mii_bus->access_capabilities;
-
- ret = mdiobus_register(priv->ds->slave_mii_bus);
- if (ret && mii_np) {
- of_node_put(dn);
- return ret;
- }
-
- dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch");
- if (!dn) {
- dev_err(priv->dev, "No RTL switch node in DTS\n");
- return -ENODEV;
- }
-
- led_node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds");
-
- for_each_node_by_name(dn, "port") {
- phy_interface_t interface;
- u32 led_set;
- char led_set_str[16] = {0};
-
- if (!of_device_is_available(dn))
- continue;
-
- if (of_property_read_u32(dn, "reg", &pn))
- continue;
-
- phy_node = of_parse_phandle(dn, "phy-handle", 0);
- if (!phy_node) {
- if (pn != priv->cpu_port)
- dev_err(priv->dev, "Port node %d misses phy-handle\n", pn);
- continue;
- }
-
- if (of_property_read_u32(phy_node, "sds", &priv->ports[pn].sds_num))
- priv->ports[pn].sds_num = -1;
- pr_debug("%s port %d has SDS %d\n", __func__, pn, priv->ports[pn].sds_num);
-
- if (of_get_phy_mode(dn, &interface))
- interface = PHY_INTERFACE_MODE_NA;
- if (interface == PHY_INTERFACE_MODE_HSGMII)
- priv->ports[pn].is2G5 = true;
- if (interface == PHY_INTERFACE_MODE_USXGMII)
- priv->ports[pn].is2G5 = priv->ports[pn].is10G = true;
- if (interface == PHY_INTERFACE_MODE_10GBASER)
- priv->ports[pn].is10G = true;
-
- priv->ports[pn].leds_on_this_port = 0;
- if (led_node) {
- if (of_property_read_u32(dn, "led-set", &led_set))
- led_set = 0;
- priv->ports[pn].led_set = led_set;
- sprintf(led_set_str, "led_set%d", led_set);
- priv->ports[pn].leds_on_this_port = of_property_count_u32_elems(led_node, led_set_str);
- if (priv->ports[pn].leds_on_this_port > 4) {
- dev_err(priv->dev, "led_set %d for port %d configuration is invalid\n", led_set, pn);
- return -ENODEV;
- }
- }
-
- /* Check for the integrated SerDes of the RTL8380M first */
- if (of_property_read_bool(phy_node, "phy-is-integrated")
- && priv->id == 0x8380 && pn >= 24) {
- pr_debug("----> FÓUND A SERDES\n");
- priv->ports[pn].phy = PHY_RTL838X_SDS;
- continue;
- }
-
- if (priv->id >= 0x9300) {
- priv->ports[pn].phy_is_integrated = false;
- if (of_property_read_bool(phy_node, "phy-is-integrated")) {
- priv->ports[pn].phy_is_integrated = true;
- priv->ports[pn].phy = PHY_RTL930X_SDS;
- }
- } else {
- if (of_property_read_bool(phy_node, "phy-is-integrated") &&
- !of_property_read_bool(phy_node, "sfp")) {
- priv->ports[pn].phy = PHY_RTL8218B_INT;
- continue;
- }
- }
-
- if (!of_property_read_bool(phy_node, "phy-is-integrated") &&
- of_property_read_bool(phy_node, "sfp")) {
- priv->ports[pn].phy = PHY_RTL8214FC;
- continue;
- }
-
- if (!of_property_read_bool(phy_node, "phy-is-integrated") &&
- !of_property_read_bool(phy_node, "sfp")) {
- priv->ports[pn].phy = PHY_RTL8218B_EXT;
- continue;
- }
- }
-
- /* Disable MAC polling the PHY so that we can start configuration */
- priv->r->set_port_reg_le(0ULL, priv->r->smi_poll_ctrl);
-
- /* Enable PHY control via SoC */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- /* Enable SerDes NWAY and PHY control via SoC */
- sw_w32_mask(BIT(7), BIT(15), RTL838X_SMI_GLB_CTRL);
- } else if (priv->family_id == RTL8390_FAMILY_ID) {
- /* Disable PHY polling via SoC */
- sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL);
- }
-
- /* Power on fibre ports and reset them if necessary */
- if (priv->ports[24].phy == PHY_RTL838X_SDS) {
- pr_debug("Powering on fibre ports & reset\n");
- rtl8380_sds_power(24, 1);
- rtl8380_sds_power(26, 1);
- }
-
- pr_debug("%s done\n", __func__);
-
- return 0;
-}
-
-static int __init rtl83xx_get_l2aging(struct rtl838x_switch_priv *priv)
-{
- int t = sw_r32(priv->r->l2_ctrl_1);
-
- t &= priv->family_id == RTL8380_FAMILY_ID ? 0x7fffff : 0x1FFFFF;
-
- if (priv->family_id == RTL8380_FAMILY_ID)
- t = t * 128 / 625; /* Aging time in seconds. 0: L2 aging disabled */
- else
- t = (t * 3) / 5;
-
- pr_debug("L2 AGING time: %d sec\n", t);
- pr_debug("Dynamic aging for ports: %x\n", sw_r32(priv->r->l2_port_aging_out));
-
- return t;
-}
-
-/* Caller must hold priv->reg_mutex */
-int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- int i;
- u32 algomsk = 0;
- u32 algoidx = 0;
-
- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
- pr_err("%s: Only mode LACP 802.3ad (4) allowed.\n", __func__);
- return -EINVAL;
- }
-
- if (group >= priv->n_lags) {
- pr_err("%s: LAG %d invalid.\n", __func__, group);
- return -EINVAL;
- }
-
- if (port >= priv->cpu_port) {
- pr_err("%s: Port %d invalid.\n", __func__, port);
- return -EINVAL;
- }
-
- for (i = 0; i < priv->n_lags; i++) {
- if (priv->lags_port_members[i] & BIT_ULL(port))
- break;
- }
- if (i != priv->n_lags) {
- pr_err("%s: Port %d already member of LAG %d.\n", __func__, port, i);
- return -ENOSPC;
- }
-
- switch(info->hash_type) {
- case NETDEV_LAG_HASH_L2:
- algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT;
- algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT;
- break;
- case NETDEV_LAG_HASH_L23:
- algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT;
- algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT;
- algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; /* source ip */
- algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; /* dest ip */
- algoidx = 1;
- break;
- case NETDEV_LAG_HASH_L34:
- algomsk |= TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT; /* sport */
- algomsk |= TRUNK_DISTRIBUTION_ALGO_DST_L4PORT_BIT; /* dport */
- algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; /* source ip */
- algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; /* dest ip */
- algoidx = 2;
- break;
- default:
- algomsk |= 0x7f;
- }
- priv->r->set_distribution_algorithm(group, algoidx, algomsk);
- priv->r->mask_port_reg_be(0, BIT_ULL(port), priv->r->trk_mbr_ctr(group));
- priv->lags_port_members[group] |= BIT_ULL(port);
-
- pr_info("%s: Added port %d to LAG %d. Members now %016llx.\n",
- __func__, port, group, priv->lags_port_members[group]);
-
- return 0;
-}
-
-/* Caller must hold priv->reg_mutex */
-int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- if (group >= priv->n_lags) {
- pr_err("%s: LAG %d invalid.\n", __func__, group);
- return -EINVAL;
- }
-
- if (port >= priv->cpu_port) {
- pr_err("%s: Port %d invalid.\n", __func__, port);
- return -EINVAL;
- }
-
- if (!(priv->lags_port_members[group] & BIT_ULL(port))) {
- pr_err("%s: Port %d not member of LAG %d.\n", __func__, port, group);
- return -ENOSPC;
- }
-
- /* 0x7f algo mask all */
- priv->r->mask_port_reg_be(BIT_ULL(port), 0, priv->r->trk_mbr_ctr(group));
- priv->lags_port_members[group] &= ~BIT_ULL(port);
-
- pr_info("%s: Removed port %d from LAG %d. Members now %016llx.\n",
- __func__, port, group, priv->lags_port_members[group]);
-
- return 0;
-}
-
-// Currently Unused
-// /* Allocate a 64 bit octet counter located in the LOG HW table */
-// static int rtl83xx_octet_cntr_alloc(struct rtl838x_switch_priv *priv)
-// {
-// int idx;
-
-// mutex_lock(&priv->reg_mutex);
-
-// idx = find_first_zero_bit(priv->octet_cntr_use_bm, MAX_COUNTERS);
-// if (idx >= priv->n_counters) {
-// mutex_unlock(&priv->reg_mutex);
-// return -1;
-// }
-
-// set_bit(idx, priv->octet_cntr_use_bm);
-// mutex_unlock(&priv->reg_mutex);
-
-// return idx;
-// }
-
-/* Allocate a 32-bit packet counter
- * 2 32-bit packet counters share the location of a 64-bit octet counter
- * Initially there are no free packet counters and 2 new ones need to be freed
- * by allocating the corresponding octet counter
- */
-int rtl83xx_packet_cntr_alloc(struct rtl838x_switch_priv *priv)
-{
- int idx, j;
-
- mutex_lock(&priv->reg_mutex);
-
- /* Because initially no packet counters are free, the logic is reversed:
- * a 0-bit means the counter is already allocated (for octets)
- */
- idx = find_first_bit(priv->packet_cntr_use_bm, MAX_COUNTERS * 2);
- if (idx >= priv->n_counters * 2) {
- j = find_first_zero_bit(priv->octet_cntr_use_bm, MAX_COUNTERS);
- if (j >= priv->n_counters) {
- mutex_unlock(&priv->reg_mutex);
- return -1;
- }
- set_bit(j, priv->octet_cntr_use_bm);
- idx = j * 2;
- set_bit(j * 2 + 1, priv->packet_cntr_use_bm);
-
- } else {
- clear_bit(idx, priv->packet_cntr_use_bm);
- }
-
- mutex_unlock(&priv->reg_mutex);
-
- return idx;
-}
-
-/* Add an L2 nexthop entry for the L3 routing system / PIE forwarding in the SoC
- * Use VID and MAC in rtl838x_l2_entry to identify either a free slot in the L2 hash table
- * or mark an existing entry as a nexthop by setting it's nexthop bit
- * Called from the L3 layer
- * The index in the L2 hash table is filled into nh->l2_id;
- */
-int rtl83xx_l2_nexthop_add(struct rtl838x_switch_priv *priv, struct rtl83xx_nexthop *nh)
-{
- struct rtl838x_l2_entry e;
- u64 seed = priv->r->l2_hash_seed(nh->mac, nh->rvid);
- u32 key = priv->r->l2_hash_key(priv, seed);
- int idx = -1;
- u64 entry;
-
- pr_debug("%s searching for %08llx vid %d with key %d, seed: %016llx\n",
- __func__, nh->mac, nh->rvid, key, seed);
-
- e.type = L2_UNICAST;
- u64_to_ether_addr(nh->mac, &e.mac[0]);
- e.port = nh->port;
-
- /* Loop over all entries in the hash-bucket and over the second block on 93xx SoCs */
- for (int i = 0; i < priv->l2_bucket_size; i++) {
- entry = priv->r->read_l2_entry_using_hash(key, i, &e);
-
- if (!e.valid || ((entry & 0x0fffffffffffffffULL) == seed)) {
- idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1
- : ((key << 2) | i) & 0xffff;
- break;
- }
- }
-
- if (idx < 0) {
- pr_err("%s: No more L2 forwarding entries available\n", __func__);
- return -1;
- }
-
- /* Found an existing (e->valid is true) or empty entry, make it a nexthop entry */
- nh->l2_id = idx;
- if (e.valid) {
- nh->port = e.port;
- nh->vid = e.vid; /* Save VID */
- nh->rvid = e.rvid;
- nh->dev_id = e.stack_dev;
- /* If the entry is already a valid next hop entry, don't change it */
- if (e.next_hop)
- return 0;
- } else {
- e.valid = true;
- e.is_static = true;
- e.rvid = nh->rvid;
- e.is_ip_mc = false;
- e.is_ipv6_mc = false;
- e.block_da = false;
- e.block_sa = false;
- e.suspended = false;
- e.age = 0; /* With port-ignore */
- e.port = priv->port_ignore;
- u64_to_ether_addr(nh->mac, &e.mac[0]);
- }
- e.next_hop = true;
- e.nh_route_id = nh->id; /* NH route ID takes place of VID */
- e.nh_vlan_target = false;
-
- priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
-
- return 0;
-}
-
-/* Removes a Layer 2 next hop entry in the forwarding database
- * If it was static, the entire entry is removed, otherwise the nexthop bit is cleared
- * and we wait until the entry ages out
- */
-int rtl83xx_l2_nexthop_rm(struct rtl838x_switch_priv *priv, struct rtl83xx_nexthop *nh)
-{
- struct rtl838x_l2_entry e;
- u32 key = nh->l2_id >> 2;
- int i = nh->l2_id & 0x3;
- u64 entry = entry = priv->r->read_l2_entry_using_hash(key, i, &e);
-
- pr_debug("%s: id %d, key %d, index %d\n", __func__, nh->l2_id, key, i);
- if (!e.valid) {
- dev_err(priv->dev, "unknown nexthop, id %x\n", nh->l2_id);
- return -1;
- }
-
- if (e.is_static)
- e.valid = false;
- e.next_hop = false;
- e.vid = nh->vid; /* Restore VID */
- e.rvid = nh->rvid;
-
- priv->r->write_l2_entry_using_hash(key, i, &e);
-
- return 0;
-}
-
-static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv,
- struct net_device *ndev,
- struct netdev_notifier_changeupper_info *info)
-{
- struct net_device *upper = info->upper_dev;
- struct netdev_lag_upper_info *lag_upper_info = NULL;
- int i, j, err;
-
- if (!netif_is_lag_master(upper))
- return 0;
-
- mutex_lock(&priv->reg_mutex);
-
- for (i = 0; i < priv->n_lags; i++) {
- if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == upper))
- break;
- }
- for (j = 0; j < priv->cpu_port; j++) {
- if (priv->ports[j].dp->slave == ndev)
- break;
- }
- if (j >= priv->cpu_port) {
- err = -EINVAL;
- goto out;
- }
-
- if (info->linking) {
- lag_upper_info = info->upper_info;
- if (!priv->lag_devs[i])
- priv->lag_devs[i] = upper;
- err = rtl83xx_lag_add(priv->ds, i, priv->ports[j].dp->index, lag_upper_info);
- if (err) {
- err = -EINVAL;
- goto out;
- }
- } else {
- if (!priv->lag_devs[i])
- err = -EINVAL;
- err = rtl83xx_lag_del(priv->ds, i, priv->ports[j].dp->index);
- if (err) {
- err = -EINVAL;
- goto out;
- }
- if (!priv->lags_port_members[i])
- priv->lag_devs[i] = NULL;
- }
-
-out:
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-/* Is the lower network device a DSA slave network device of our RTL930X-switch?
- * Unfortunately we cannot just follow dev->dsa_prt as this is only set for the
- * DSA master device.
- */
-int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_priv *priv)
-{
-/* TODO: On 5.12:
- * if(!dsa_slave_dev_check(dev)) {
- * netdev_info(dev, "%s: not a DSA device.\n", __func__);
- * return -EINVAL;
- * }
- */
-
- for (int i = 0; i < priv->cpu_port; i++) {
- if (!priv->ports[i].dp)
- continue;
- if (priv->ports[i].dp->slave == dev)
- return i;
- }
-
- return -EINVAL;
-}
-
-static int rtl83xx_netdevice_event(struct notifier_block *this,
- unsigned long event, void *ptr)
-{
- struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
- struct rtl838x_switch_priv *priv;
- int err;
-
- pr_debug("In: %s, event: %lu\n", __func__, event);
-
- if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE))
- return NOTIFY_DONE;
-
- priv = container_of(this, struct rtl838x_switch_priv, nb);
- switch (event) {
- case NETDEV_CHANGEUPPER:
- err = rtl83xx_handle_changeupper(priv, ndev, ptr);
- break;
- }
-
- if (err)
- return err;
-
- return NOTIFY_DONE;
-}
-
-const static struct rhashtable_params route_ht_params = {
- .key_len = sizeof(u32),
- .key_offset = offsetof(struct rtl83xx_route, gw_ip),
- .head_offset = offsetof(struct rtl83xx_route, linkage),
-};
-
-/* Updates an L3 next hop entry in the ROUTING table */
-static int rtl83xx_l3_nexthop_update(struct rtl838x_switch_priv *priv, __be32 ip_addr, u64 mac)
-{
- struct rtl83xx_route *r;
- struct rhlist_head *tmp, *list;
-
- rcu_read_lock();
- list = rhltable_lookup(&priv->routes, &ip_addr, route_ht_params);
- if (!list) {
- rcu_read_unlock();
- return -ENOENT;
- }
-
- rhl_for_each_entry_rcu(r, tmp, list, linkage) {
- pr_info("%s: Setting up fwding: ip %pI4, GW mac %016llx\n",
- __func__, &ip_addr, mac);
-
- /* Reads the ROUTING table entry associated with the route */
- priv->r->route_read(r->id, r);
- pr_info("Route with id %d to %pI4 / %d\n", r->id, &r->dst_ip, r->prefix_len);
-
- r->nh.mac = r->nh.gw = mac;
- r->nh.port = priv->port_ignore;
- r->nh.id = r->id;
-
- /* Do we need to explicitly add a DMAC entry with the route's nh index? */
- if (priv->r->set_l3_egress_mac)
- priv->r->set_l3_egress_mac(r->id, mac);
-
- /* Update ROUTING table: map gateway-mac and switch-mac id to route id */
- rtl83xx_l2_nexthop_add(priv, &r->nh);
-
- r->attr.valid = true;
- r->attr.action = ROUTE_ACT_FORWARD;
- r->attr.type = 0;
- r->attr.hit = false; /* Reset route-used indicator */
-
- /* Add PIE entry with dst_ip and prefix_len */
- r->pr.dip = r->dst_ip;
- r->pr.dip_m = inet_make_mask(r->prefix_len);
-
- if (r->is_host_route) {
- int slot = priv->r->find_l3_slot(r, false);
-
- pr_info("%s: Got slot for route: %d\n", __func__, slot);
- priv->r->host_route_write(slot, r);
- } else {
- priv->r->route_write(r->id, r);
- r->pr.fwd_sel = true;
- r->pr.fwd_data = r->nh.l2_id;
- r->pr.fwd_act = PIE_ACT_ROUTE_UC;
- }
-
- if (priv->r->set_l3_nexthop)
- priv->r->set_l3_nexthop(r->nh.id, r->nh.l2_id, r->nh.if_id);
-
- if (r->pr.id < 0) {
- r->pr.packet_cntr = rtl83xx_packet_cntr_alloc(priv);
- if (r->pr.packet_cntr >= 0) {
- pr_info("Using packet counter %d\n", r->pr.packet_cntr);
- r->pr.log_sel = true;
- r->pr.log_data = r->pr.packet_cntr;
- }
- priv->r->pie_rule_add(priv, &r->pr);
- } else {
- int pkts = priv->r->packet_cntr_read(r->pr.packet_cntr);
- pr_info("%s: total packets: %d\n", __func__, pkts);
-
- priv->r->pie_rule_write(priv, r->pr.id, &r->pr);
- }
- }
- rcu_read_unlock();
-
- return 0;
-}
-
-static int rtl83xx_port_ipv4_resolve(struct rtl838x_switch_priv *priv,
- struct net_device *dev, __be32 ip_addr)
-{
- struct neighbour *n = neigh_lookup(&arp_tbl, &ip_addr, dev);
- int err = 0;
- u64 mac;
-
- if (!n) {
- n = neigh_create(&arp_tbl, &ip_addr, dev);
- if (IS_ERR(n))
- return PTR_ERR(n);
- }
-
- /* If the neigh is already resolved, then go ahead and
- * install the entry, otherwise start the ARP process to
- * resolve the neigh.
- */
- if (n->nud_state & NUD_VALID) {
- mac = ether_addr_to_u64(n->ha);
- pr_info("%s: resolved mac: %016llx\n", __func__, mac);
- rtl83xx_l3_nexthop_update(priv, ip_addr, mac);
- } else {
- pr_info("%s: need to wait\n", __func__);
- neigh_event_send(n, NULL);
- }
-
- neigh_release(n);
-
- return err;
-}
-
-struct rtl83xx_walk_data {
- struct rtl838x_switch_priv *priv;
- int port;
-};
-
-static int rtl83xx_port_lower_walk(struct net_device *lower, struct netdev_nested_priv *_priv)
-{
- struct rtl83xx_walk_data *data = (struct rtl83xx_walk_data *)_priv->data;
- struct rtl838x_switch_priv *priv = data->priv;
- int ret = 0;
- int index;
-
- index = rtl83xx_port_is_under(lower, priv);
- data->port = index;
- if (index >= 0) {
- pr_debug("Found DSA-port, index %d\n", index);
- ret = 1;
- }
-
- return ret;
-}
-
-int rtl83xx_port_dev_lower_find(struct net_device *dev, struct rtl838x_switch_priv *priv)
-{
- struct rtl83xx_walk_data data;
- struct netdev_nested_priv _priv;
-
- data.priv = priv;
- data.port = 0;
- _priv.data = (void *)&data;
-
- netdev_walk_all_lower_dev(dev, rtl83xx_port_lower_walk, &_priv);
-
- return data.port;
-}
-
-static struct rtl83xx_route *rtl83xx_route_alloc(struct rtl838x_switch_priv *priv, u32 ip)
-{
- struct rtl83xx_route *r;
- int idx = 0, err;
-
- mutex_lock(&priv->reg_mutex);
-
- idx = find_first_zero_bit(priv->route_use_bm, MAX_ROUTES);
- pr_debug("%s id: %d, ip %pI4\n", __func__, idx, &ip);
-
- r = kzalloc(sizeof(*r), GFP_KERNEL);
- if (!r) {
- mutex_unlock(&priv->reg_mutex);
- return r;
- }
-
- r->id = idx;
- r->gw_ip = ip;
- r->pr.id = -1; /* We still need to allocate a rule in HW */
- r->is_host_route = false;
-
- err = rhltable_insert(&priv->routes, &r->linkage, route_ht_params);
- if (err) {
- pr_err("Could not insert new rule\n");
- mutex_unlock(&priv->reg_mutex);
- goto out_free;
- }
-
- set_bit(idx, priv->route_use_bm);
-
- mutex_unlock(&priv->reg_mutex);
-
- return r;
-
-out_free:
- kfree(r);
-
- return NULL;
-}
-
-
-static struct rtl83xx_route *rtl83xx_host_route_alloc(struct rtl838x_switch_priv *priv, u32 ip)
-{
- struct rtl83xx_route *r;
- int idx = 0, err;
-
- mutex_lock(&priv->reg_mutex);
-
- idx = find_first_zero_bit(priv->host_route_use_bm, MAX_HOST_ROUTES);
- pr_debug("%s id: %d, ip %pI4\n", __func__, idx, &ip);
-
- r = kzalloc(sizeof(*r), GFP_KERNEL);
- if (!r) {
- mutex_unlock(&priv->reg_mutex);
- return r;
- }
-
- /* We require a unique route ID irrespective of whether it is a prefix or host
- * route (on RTL93xx) as we use this ID to associate a DMAC and next-hop entry
- */
- r->id = idx + MAX_ROUTES;
-
- r->gw_ip = ip;
- r->pr.id = -1; /* We still need to allocate a rule in HW */
- r->is_host_route = true;
-
- err = rhltable_insert(&priv->routes, &r->linkage, route_ht_params);
- if (err) {
- pr_err("Could not insert new rule\n");
- mutex_unlock(&priv->reg_mutex);
- goto out_free;
- }
-
- set_bit(idx, priv->host_route_use_bm);
-
- mutex_unlock(&priv->reg_mutex);
-
- return r;
-
-out_free:
- kfree(r);
-
- return NULL;
-}
-
-
-
-static void rtl83xx_route_rm(struct rtl838x_switch_priv *priv, struct rtl83xx_route *r)
-{
- int id;
-
- if (rhltable_remove(&priv->routes, &r->linkage, route_ht_params))
- dev_warn(priv->dev, "Could not remove route\n");
-
- if (r->is_host_route) {
- id = priv->r->find_l3_slot(r, false);
- pr_debug("%s: Got id for host route: %d\n", __func__, id);
- r->attr.valid = false;
- priv->r->host_route_write(id, r);
- clear_bit(r->id - MAX_ROUTES, priv->host_route_use_bm);
- } else {
- /* If there is a HW representation of the route, delete it */
- if (priv->r->route_lookup_hw) {
- id = priv->r->route_lookup_hw(r);
- pr_info("%s: Got id for prefix route: %d\n", __func__, id);
- r->attr.valid = false;
- priv->r->route_write(id, r);
- }
- clear_bit(r->id, priv->route_use_bm);
- }
-
- kfree(r);
-}
-
-static int rtl83xx_fib4_del(struct rtl838x_switch_priv *priv,
- struct fib_entry_notifier_info *info)
-{
- struct fib_nh *nh = fib_info_nh(info->fi, 0);
- struct rtl83xx_route *r;
- struct rhlist_head *tmp, *list;
-
- pr_debug("In %s, ip %pI4, len %d\n", __func__, &info->dst, info->dst_len);
- rcu_read_lock();
- list = rhltable_lookup(&priv->routes, &nh->fib_nh_gw4, route_ht_params);
- if (!list) {
- rcu_read_unlock();
- pr_err("%s: no such gateway: %pI4\n", __func__, &nh->fib_nh_gw4);
- return -ENOENT;
- }
- rhl_for_each_entry_rcu(r, tmp, list, linkage) {
- if (r->dst_ip == info->dst && r->prefix_len == info->dst_len) {
- pr_info("%s: found a route with id %d, nh-id %d\n",
- __func__, r->id, r->nh.id);
- break;
- }
- }
- rcu_read_unlock();
-
- rtl83xx_l2_nexthop_rm(priv, &r->nh);
-
- pr_debug("%s: Releasing packet counter %d\n", __func__, r->pr.packet_cntr);
- set_bit(r->pr.packet_cntr, priv->packet_cntr_use_bm);
- priv->r->pie_rule_rm(priv, &r->pr);
-
- rtl83xx_route_rm(priv, r);
-
- nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
-
- return 0;
-}
-
-/* On the RTL93xx, an L3 termination endpoint MAC address on which the router waits
- * for packets to be routed needs to be allocated.
- */
-static int rtl83xx_alloc_router_mac(struct rtl838x_switch_priv *priv, u64 mac)
-{
- int free_mac = -1;
- struct rtl93xx_rt_mac m;
-
- mutex_lock(&priv->reg_mutex);
- for (int i = 0; i < MAX_ROUTER_MACS; i++) {
- priv->r->get_l3_router_mac(i, &m);
- if (free_mac < 0 && !m.valid) {
- free_mac = i;
- continue;
- }
- if (m.valid && m.mac == mac) {
- free_mac = i;
- break;
- }
- }
-
- if (free_mac < 0) {
- pr_err("No free router MACs, cannot offload\n");
- mutex_unlock(&priv->reg_mutex);
- return -1;
- }
-
- m.valid = true;
- m.mac = mac;
- m.p_type = 0; /* An individual port, not a trunk port */
- m.p_id = 0x3f; /* Listen on any port */
- m.p_id_mask = 0;
- m.vid = 0; /* Listen on any VLAN... */
- m.vid_mask = 0; /* ... so mask needs to be 0 */
- m.mac_mask = 0xffffffffffffULL; /* We want an exact match of the interface MAC */
- m.action = L3_FORWARD; /* Route the packet */
- priv->r->set_l3_router_mac(free_mac, &m);
-
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static int rtl83xx_alloc_egress_intf(struct rtl838x_switch_priv *priv, u64 mac, int vlan)
-{
- int free_mac = -1;
- struct rtl838x_l3_intf intf;
- u64 m;
-
- mutex_lock(&priv->reg_mutex);
- for (int i = 0; i < MAX_SMACS; i++) {
- m = priv->r->get_l3_egress_mac(L3_EGRESS_DMACS + i);
- if (free_mac < 0 && !m) {
- free_mac = i;
- continue;
- }
- if (m == mac) {
- mutex_unlock(&priv->reg_mutex);
- return i;
- }
- }
-
- if (free_mac < 0) {
- pr_err("No free egress interface, cannot offload\n");
- return -1;
- }
-
- /* Set up default egress interface 1 */
- intf.vid = vlan;
- intf.smac_idx = free_mac;
- intf.ip4_mtu_id = 1;
- intf.ip6_mtu_id = 1;
- intf.ttl_scope = 1; /* TTL */
- intf.hl_scope = 1; /* Hop Limit */
- intf.ip4_icmp_redirect = intf.ip6_icmp_redirect = 2; /* FORWARD */
- intf.ip4_pbr_icmp_redirect = intf.ip6_pbr_icmp_redirect = 2; /* FORWARD; */
- priv->r->set_l3_egress_intf(free_mac, &intf);
-
- priv->r->set_l3_egress_mac(L3_EGRESS_DMACS + free_mac, mac);
-
- mutex_unlock(&priv->reg_mutex);
-
- return free_mac;
-}
-
-static int rtl83xx_fib4_add(struct rtl838x_switch_priv *priv,
- struct fib_entry_notifier_info *info)
-{
- struct fib_nh *nh = fib_info_nh(info->fi, 0);
- struct net_device *dev = fib_info_nh(info->fi, 0)->fib_nh_dev;
- int port;
- struct rtl83xx_route *r;
- bool to_localhost;
- int vlan = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : 0;
-
- pr_debug("In %s, ip %pI4, len %d\n", __func__, &info->dst, info->dst_len);
- if (!info->dst) {
- pr_info("Not offloading default route for now\n");
- return 0;
- }
-
- pr_debug("GW: %pI4, interface name %s, mac %016llx, vlan %d\n", &nh->fib_nh_gw4, dev->name,
- ether_addr_to_u64(dev->dev_addr), vlan
- );
-
- port = rtl83xx_port_dev_lower_find(dev, priv);
- if (port < 0)
- return -1;
-
- /* For now we only work with routes that have a gateway and are not ourself */
-/* if ((!nh->fib_nh_gw4) && (info->dst_len != 32)) */
-/* return 0; */
-
- if ((info->dst & 0xff) == 0xff)
- return 0;
-
- /* Do not offload routes to 192.168.100.x */
- if ((info->dst & 0xffffff00) == 0xc0a86400)
- return 0;
-
- /* Do not offload routes to 127.x.x.x */
- if ((info->dst & 0xff000000) == 0x7f000000)
- return 0;
-
- /* Allocate route or host-route (entry if hardware supports this) */
- if (info->dst_len == 32 && priv->r->host_route_write)
- r = rtl83xx_host_route_alloc(priv, nh->fib_nh_gw4);
- else
- r = rtl83xx_route_alloc(priv, nh->fib_nh_gw4);
-
- if (!r) {
- pr_err("%s: No more free route entries\n", __func__);
- return -1;
- }
-
- r->dst_ip = info->dst;
- r->prefix_len = info->dst_len;
- r->nh.rvid = vlan;
- to_localhost = !nh->fib_nh_gw4;
-
- if (priv->r->set_l3_router_mac) {
- u64 mac = ether_addr_to_u64(dev->dev_addr);
-
- pr_debug("Local route and router mac %016llx\n", mac);
-
- if (rtl83xx_alloc_router_mac(priv, mac))
- goto out_free_rt;
-
- /* vid = 0: Do not care about VID */
- r->nh.if_id = rtl83xx_alloc_egress_intf(priv, mac, vlan);
- if (r->nh.if_id < 0)
- goto out_free_rmac;
-
- if (to_localhost) {
- int slot;
-
- r->nh.mac = mac;
- r->nh.port = priv->port_ignore;
- r->attr.valid = true;
- r->attr.action = ROUTE_ACT_TRAP2CPU;
- r->attr.type = 0;
-
- slot = priv->r->find_l3_slot(r, false);
- pr_debug("%s: Got slot for route: %d\n", __func__, slot);
- priv->r->host_route_write(slot, r);
- }
- }
-
- /* We need to resolve the mac address of the GW */
- if (!to_localhost)
- rtl83xx_port_ipv4_resolve(priv, dev, nh->fib_nh_gw4);
-
- nh->fib_nh_flags |= RTNH_F_OFFLOAD;
-
- return 0;
-
-out_free_rmac:
-out_free_rt:
- return 0;
-}
-
-static int rtl83xx_fib6_add(struct rtl838x_switch_priv *priv,
- struct fib6_entry_notifier_info *info)
-{
- pr_debug("In %s\n", __func__);
-/* nh->fib_nh_flags |= RTNH_F_OFFLOAD; */
-
- return 0;
-}
-
-struct net_event_work {
- struct work_struct work;
- struct rtl838x_switch_priv *priv;
- u64 mac;
- u32 gw_addr;
-};
-
-static void rtl83xx_net_event_work_do(struct work_struct *work)
-{
- struct net_event_work *net_work =
- container_of(work, struct net_event_work, work);
- struct rtl838x_switch_priv *priv = net_work->priv;
-
- rtl83xx_l3_nexthop_update(priv, net_work->gw_addr, net_work->mac);
-
- kfree(net_work);
-}
-
-static int rtl83xx_netevent_event(struct notifier_block *this,
- unsigned long event, void *ptr)
-{
- struct rtl838x_switch_priv *priv;
- struct net_device *dev;
- struct neighbour *n = ptr;
- int err, port;
- struct net_event_work *net_work;
-
- priv = container_of(this, struct rtl838x_switch_priv, ne_nb);
-
- switch (event) {
- case NETEVENT_NEIGH_UPDATE:
- if (n->tbl != &arp_tbl)
- return NOTIFY_DONE;
- dev = n->dev;
- port = rtl83xx_port_dev_lower_find(dev, priv);
- if (port < 0 || !(n->nud_state & NUD_VALID)) {
- pr_debug("%s: Neigbour invalid, not updating\n", __func__);
- return NOTIFY_DONE;
- }
-
- net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
- if (!net_work)
- return NOTIFY_BAD;
-
- INIT_WORK(&net_work->work, rtl83xx_net_event_work_do);
- net_work->priv = priv;
-
- net_work->mac = ether_addr_to_u64(n->ha);
- net_work->gw_addr = *(__be32 *) n->primary_key;
-
- pr_debug("%s: updating neighbour on port %d, mac %016llx\n",
- __func__, port, net_work->mac);
- schedule_work(&net_work->work);
- if (err)
- netdev_warn(dev, "failed to handle neigh update (err %d)\n", err);
- break;
- }
-
- return NOTIFY_DONE;
-}
-
-struct rtl83xx_fib_event_work {
- struct work_struct work;
- union {
- struct fib_entry_notifier_info fen_info;
- struct fib6_entry_notifier_info fen6_info;
- struct fib_rule_notifier_info fr_info;
- };
- struct rtl838x_switch_priv *priv;
- bool is_fib6;
- unsigned long event;
-};
-
-static void rtl83xx_fib_event_work_do(struct work_struct *work)
-{
- struct rtl83xx_fib_event_work *fib_work =
- container_of(work, struct rtl83xx_fib_event_work, work);
- struct rtl838x_switch_priv *priv = fib_work->priv;
- struct fib_rule *rule;
- int err;
-
- /* Protect internal structures from changes */
- rtnl_lock();
- pr_debug("%s: doing work, event %ld\n", __func__, fib_work->event);
- switch (fib_work->event) {
- case FIB_EVENT_ENTRY_ADD:
- case FIB_EVENT_ENTRY_REPLACE:
- case FIB_EVENT_ENTRY_APPEND:
- if (fib_work->is_fib6) {
- err = rtl83xx_fib6_add(priv, &fib_work->fen6_info);
- } else {
- err = rtl83xx_fib4_add(priv, &fib_work->fen_info);
- fib_info_put(fib_work->fen_info.fi);
- }
- if (err)
- pr_err("%s: FIB4 failed\n", __func__);
- break;
- case FIB_EVENT_ENTRY_DEL:
- rtl83xx_fib4_del(priv, &fib_work->fen_info);
- fib_info_put(fib_work->fen_info.fi);
- break;
- case FIB_EVENT_RULE_ADD:
- case FIB_EVENT_RULE_DEL:
- rule = fib_work->fr_info.rule;
- if (!fib4_rule_default(rule))
- pr_err("%s: FIB4 default rule failed\n", __func__);
- fib_rule_put(rule);
- break;
- }
- rtnl_unlock();
- kfree(fib_work);
-}
-
-/* Called with rcu_read_lock() */
-static int rtl83xx_fib_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
- struct fib_notifier_info *info = ptr;
- struct rtl838x_switch_priv *priv;
- struct rtl83xx_fib_event_work *fib_work;
-
- if ((info->family != AF_INET && info->family != AF_INET6 &&
- info->family != RTNL_FAMILY_IPMR &&
- info->family != RTNL_FAMILY_IP6MR))
- return NOTIFY_DONE;
-
- priv = container_of(this, struct rtl838x_switch_priv, fib_nb);
-
- fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC);
- if (!fib_work)
- return NOTIFY_BAD;
-
- INIT_WORK(&fib_work->work, rtl83xx_fib_event_work_do);
- fib_work->priv = priv;
- fib_work->event = event;
- fib_work->is_fib6 = false;
-
- switch (event) {
- case FIB_EVENT_ENTRY_ADD:
- case FIB_EVENT_ENTRY_REPLACE:
- case FIB_EVENT_ENTRY_APPEND:
- case FIB_EVENT_ENTRY_DEL:
- pr_debug("%s: FIB_ENTRY ADD/DEL, event %ld\n", __func__, event);
- if (info->family == AF_INET) {
- struct fib_entry_notifier_info *fen_info = ptr;
-
- if (fen_info->fi->fib_nh_is_v6) {
- NL_SET_ERR_MSG_MOD(info->extack,
- "IPv6 gateway with IPv4 route is not supported");
- kfree(fib_work);
- return notifier_from_errno(-EINVAL);
- }
-
- memcpy(&fib_work->fen_info, ptr, sizeof(fib_work->fen_info));
- /* Take referece on fib_info to prevent it from being
- * freed while work is queued. Release it afterwards.
- */
- fib_info_hold(fib_work->fen_info.fi);
-
- } else if (info->family == AF_INET6) {
- //struct fib6_entry_notifier_info *fen6_info = ptr;
- pr_warn("%s: FIB_RULE ADD/DEL for IPv6 not supported\n", __func__);
- kfree(fib_work);
- return NOTIFY_DONE;
- }
- break;
-
- case FIB_EVENT_RULE_ADD:
- case FIB_EVENT_RULE_DEL:
- pr_debug("%s: FIB_RULE ADD/DEL, event: %ld\n", __func__, event);
- memcpy(&fib_work->fr_info, ptr, sizeof(fib_work->fr_info));
- fib_rule_get(fib_work->fr_info.rule);
- break;
- }
-
- schedule_work(&fib_work->work);
-
- return NOTIFY_DONE;
-}
-
-static int __init rtl83xx_sw_probe(struct platform_device *pdev)
-{
- int err = 0;
- struct rtl838x_switch_priv *priv;
- struct device *dev = &pdev->dev;
- u64 bpdu_mask;
-
- pr_debug("Probing RTL838X switch device\n");
- if (!pdev->dev.of_node) {
- dev_err(dev, "No DT found\n");
- return -EINVAL;
- }
-
- /* Initialize access to RTL switch tables */
- rtl_table_init();
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
-
- if (!priv->ds)
- return -ENOMEM;
- priv->ds->dev = dev;
- priv->ds->priv = priv;
- priv->ds->ops = &rtl83xx_switch_ops;
- priv->ds->needs_standalone_vlan_filtering = true;
- priv->dev = dev;
-
- mutex_init(&priv->reg_mutex);
-
- priv->family_id = soc_info.family;
- priv->id = soc_info.id;
- switch(soc_info.family) {
- case RTL8380_FAMILY_ID:
- priv->ds->ops = &rtl83xx_switch_ops;
- priv->cpu_port = RTL838X_CPU_PORT;
- priv->port_mask = 0x1f;
- priv->port_width = 1;
- priv->irq_mask = 0x0FFFFFFF;
- priv->r = &rtl838x_reg;
- priv->ds->num_ports = 29;
- priv->fib_entries = 8192;
- rtl8380_get_version(priv);
- priv->n_lags = 8;
- priv->l2_bucket_size = 4;
- priv->n_pie_blocks = 12;
- priv->port_ignore = 0x1f;
- priv->n_counters = 128;
- break;
- case RTL8390_FAMILY_ID:
- priv->ds->ops = &rtl83xx_switch_ops;
- priv->cpu_port = RTL839X_CPU_PORT;
- priv->port_mask = 0x3f;
- priv->port_width = 2;
- priv->irq_mask = 0xFFFFFFFFFFFFFULL;
- priv->r = &rtl839x_reg;
- priv->ds->num_ports = 53;
- priv->fib_entries = 16384;
- rtl8390_get_version(priv);
- priv->n_lags = 16;
- priv->l2_bucket_size = 4;
- priv->n_pie_blocks = 18;
- priv->port_ignore = 0x3f;
- priv->n_counters = 1024;
- break;
- case RTL9300_FAMILY_ID:
- priv->ds->ops = &rtl930x_switch_ops;
- priv->cpu_port = RTL930X_CPU_PORT;
- priv->port_mask = 0x1f;
- priv->port_width = 1;
- priv->irq_mask = 0x0FFFFFFF;
- priv->r = &rtl930x_reg;
- priv->ds->num_ports = 29;
- priv->fib_entries = 16384;
- priv->version = RTL8390_VERSION_A;
- priv->n_lags = 16;
- sw_w32(1, RTL930X_ST_CTRL);
- priv->l2_bucket_size = 8;
- priv->n_pie_blocks = 16;
- priv->port_ignore = 0x3f;
- priv->n_counters = 2048;
- break;
- case RTL9310_FAMILY_ID:
- priv->ds->ops = &rtl930x_switch_ops;
- priv->cpu_port = RTL931X_CPU_PORT;
- priv->port_mask = 0x3f;
- priv->port_width = 2;
- priv->irq_mask = 0xFFFFFFFFFFFFFULL;
- priv->r = &rtl931x_reg;
- priv->ds->num_ports = 57;
- priv->fib_entries = 16384;
- priv->version = RTL8390_VERSION_A;
- priv->n_lags = 16;
- priv->l2_bucket_size = 8;
- break;
- }
- pr_debug("Chip version %c\n", priv->version);
-
- err = rtl83xx_mdio_probe(priv);
- if (err) {
- /* Probing fails the 1st time because of missing ethernet driver
- * initialization. Use this to disable traffic in case the bootloader left if on
- */
- return err;
- }
-
- err = dsa_register_switch(priv->ds);
- if (err) {
- dev_err(dev, "Error registering switch: %d\n", err);
- return err;
- }
-
- /* dsa_to_port returns dsa_port from the port list in
- * dsa_switch_tree, the tree is built when the switch
- * is registered by dsa_register_switch
- */
- for (int i = 0; i <= priv->cpu_port; i++)
- priv->ports[i].dp = dsa_to_port(priv->ds, i);
-
- /* Enable link and media change interrupts. Are the SERDES masks needed? */
- sw_w32_mask(0, 3, priv->r->isr_glb_src);
-
- priv->r->set_port_reg_le(priv->irq_mask, priv->r->isr_port_link_sts_chg);
- priv->r->set_port_reg_le(priv->irq_mask, priv->r->imr_port_link_sts_chg);
-
- priv->link_state_irq = platform_get_irq(pdev, 0);
- pr_info("LINK state irq: %d\n", priv->link_state_irq);
- switch (priv->family_id) {
- case RTL8380_FAMILY_ID:
- err = request_irq(priv->link_state_irq, rtl838x_switch_irq,
- IRQF_SHARED, "rtl838x-link-state", priv->ds);
- break;
- case RTL8390_FAMILY_ID:
- err = request_irq(priv->link_state_irq, rtl839x_switch_irq,
- IRQF_SHARED, "rtl839x-link-state", priv->ds);
- break;
- case RTL9300_FAMILY_ID:
- err = request_irq(priv->link_state_irq, rtl930x_switch_irq,
- IRQF_SHARED, "rtl930x-link-state", priv->ds);
- break;
- case RTL9310_FAMILY_ID:
- err = request_irq(priv->link_state_irq, rtl931x_switch_irq,
- IRQF_SHARED, "rtl931x-link-state", priv->ds);
- break;
- }
- if (err) {
- dev_err(dev, "Error setting up switch interrupt.\n");
- /* Need to free allocated switch here */
- }
-
- /* Enable interrupts for switch, on RTL931x, the IRQ is always on globally */
- if (soc_info.family != RTL9310_FAMILY_ID)
- sw_w32(0x1, priv->r->imr_glb);
-
- rtl83xx_get_l2aging(priv);
-
- rtl83xx_setup_qos(priv);
-
- priv->r->l3_setup(priv);
-
- /* Clear all destination ports for mirror groups */
- for (int i = 0; i < 4; i++)
- priv->mirror_group_ports[i] = -1;
-
- /* Register netdevice event callback to catch changes in link aggregation groups */
- priv->nb.notifier_call = rtl83xx_netdevice_event;
- if (register_netdevice_notifier(&priv->nb)) {
- priv->nb.notifier_call = NULL;
- dev_err(dev, "Failed to register LAG netdev notifier\n");
- goto err_register_nb;
- }
-
- /* Initialize hash table for L3 routing */
- rhltable_init(&priv->routes, &route_ht_params);
-
- /* Register netevent notifier callback to catch notifications about neighboring
- * changes to update nexthop entries for L3 routing.
- */
- priv->ne_nb.notifier_call = rtl83xx_netevent_event;
- if (register_netevent_notifier(&priv->ne_nb)) {
- priv->ne_nb.notifier_call = NULL;
- dev_err(dev, "Failed to register netevent notifier\n");
- goto err_register_ne_nb;
- }
-
- priv->fib_nb.notifier_call = rtl83xx_fib_event;
-
- /* Register Forwarding Information Base notifier to offload routes where
- * where possible
- * Only FIBs pointing to our own netdevs are programmed into
- * the device, so no need to pass a callback.
- */
- err = register_fib_notifier(&init_net, &priv->fib_nb, NULL, NULL);
- if (err)
- goto err_register_fib_nb;
-
- /* TODO: put this into l2_setup() */
- /* Flood BPDUs to all ports including cpu-port */
- if (soc_info.family != RTL9300_FAMILY_ID) {
- bpdu_mask = soc_info.family == RTL8380_FAMILY_ID ? 0x1FFFFFFF : 0x1FFFFFFFFFFFFF;
- priv->r->set_port_reg_be(bpdu_mask, priv->r->rma_bpdu_fld_pmask);
-
- /* TRAP 802.1X frames (EAPOL) to the CPU-Port, bypass STP and VLANs */
- sw_w32(7, priv->r->spcl_trap_eapol_ctrl);
-
- rtl838x_dbgfs_init(priv);
- } else {
- rtl930x_dbgfs_init(priv);
- }
-
- return 0;
-
-err_register_fib_nb:
- unregister_netevent_notifier(&priv->ne_nb);
-err_register_ne_nb:
- unregister_netdevice_notifier(&priv->nb);
-err_register_nb:
- return err;
-}
-
-static int rtl83xx_sw_remove(struct platform_device *pdev)
-{
- /* TODO: */
- pr_debug("Removing platform driver for rtl83xx-sw\n");
-
- return 0;
-}
-
-static const struct of_device_id rtl83xx_switch_of_ids[] = {
- { .compatible = "realtek,rtl83xx-switch"},
- { /* sentinel */ }
-};
-
-
-MODULE_DEVICE_TABLE(of, rtl83xx_switch_of_ids);
-
-static struct platform_driver rtl83xx_switch_driver = {
- .probe = rtl83xx_sw_probe,
- .remove = rtl83xx_sw_remove,
- .driver = {
- .name = "rtl83xx-switch",
- .pm = NULL,
- .of_match_table = rtl83xx_switch_of_ids,
- },
-};
-
-module_platform_driver(rtl83xx_switch_driver);
-
-MODULE_AUTHOR("B. Koblitz");
-MODULE_DESCRIPTION("RTL83XX SoC Switch Driver");
-MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c
deleted file mode 100644
index 9eb444515f..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c
+++ /dev/null
@@ -1,2218 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include <net/dsa.h>
-#include <linux/etherdevice.h>
-#include <linux/if_bridge.h>
-#include <asm/mach-rtl838x/mach-rtl83xx.h>
-
-#include "rtl83xx.h"
-
-extern struct rtl83xx_soc_info soc_info;
-
-static void rtl83xx_init_stats(struct rtl838x_switch_priv *priv)
-{
- mutex_lock(&priv->reg_mutex);
-
- /* Enable statistics module: all counters plus debug.
- * On RTL839x all counters are enabled by default
- */
- if (priv->family_id == RTL8380_FAMILY_ID)
- sw_w32_mask(0, 3, RTL838X_STAT_CTRL);
-
- /* Reset statistics counters */
- sw_w32_mask(0, 1, priv->r->stat_rst);
-
- mutex_unlock(&priv->reg_mutex);
-}
-
-static void rtl83xx_enable_phy_polling(struct rtl838x_switch_priv *priv)
-{
- u64 v = 0;
-
- msleep(1000);
- /* Enable all ports with a PHY, including the SFP-ports */
- for (int i = 0; i < priv->cpu_port; i++) {
- if (priv->ports[i].phy)
- v |= BIT_ULL(i);
- }
-
- pr_info("%s: %16llx\n", __func__, v);
- priv->r->set_port_reg_le(v, priv->r->smi_poll_ctrl);
-
- /* PHY update complete, there is no global PHY polling enable bit on the 9300 */
- if (priv->family_id == RTL8390_FAMILY_ID)
- sw_w32_mask(0, BIT(7), RTL839X_SMI_GLB_CTRL);
- else if(priv->family_id == RTL9300_FAMILY_ID)
- sw_w32_mask(0, 0x8000, RTL838X_SMI_GLB_CTRL);
-}
-
-const struct rtl83xx_mib_desc rtl83xx_mib[] = {
- MIB_DESC(2, 0xf8, "ifInOctets"),
- MIB_DESC(2, 0xf0, "ifOutOctets"),
- MIB_DESC(1, 0xec, "dot1dTpPortInDiscards"),
- MIB_DESC(1, 0xe8, "ifInUcastPkts"),
- MIB_DESC(1, 0xe4, "ifInMulticastPkts"),
- MIB_DESC(1, 0xe0, "ifInBroadcastPkts"),
- MIB_DESC(1, 0xdc, "ifOutUcastPkts"),
- MIB_DESC(1, 0xd8, "ifOutMulticastPkts"),
- MIB_DESC(1, 0xd4, "ifOutBroadcastPkts"),
- MIB_DESC(1, 0xd0, "ifOutDiscards"),
- MIB_DESC(1, 0xcc, ".3SingleCollisionFrames"),
- MIB_DESC(1, 0xc8, ".3MultipleCollisionFrames"),
- MIB_DESC(1, 0xc4, ".3DeferredTransmissions"),
- MIB_DESC(1, 0xc0, ".3LateCollisions"),
- MIB_DESC(1, 0xbc, ".3ExcessiveCollisions"),
- MIB_DESC(1, 0xb8, ".3SymbolErrors"),
- MIB_DESC(1, 0xb4, ".3ControlInUnknownOpcodes"),
- MIB_DESC(1, 0xb0, ".3InPauseFrames"),
- MIB_DESC(1, 0xac, ".3OutPauseFrames"),
- MIB_DESC(1, 0xa8, "DropEvents"),
- MIB_DESC(1, 0xa4, "tx_BroadcastPkts"),
- MIB_DESC(1, 0xa0, "tx_MulticastPkts"),
- MIB_DESC(1, 0x9c, "CRCAlignErrors"),
- MIB_DESC(1, 0x98, "tx_UndersizePkts"),
- MIB_DESC(1, 0x94, "rx_UndersizePkts"),
- MIB_DESC(1, 0x90, "rx_UndersizedropPkts"),
- MIB_DESC(1, 0x8c, "tx_OversizePkts"),
- MIB_DESC(1, 0x88, "rx_OversizePkts"),
- MIB_DESC(1, 0x84, "Fragments"),
- MIB_DESC(1, 0x80, "Jabbers"),
- MIB_DESC(1, 0x7c, "Collisions"),
- MIB_DESC(1, 0x78, "tx_Pkts64Octets"),
- MIB_DESC(1, 0x74, "rx_Pkts64Octets"),
- MIB_DESC(1, 0x70, "tx_Pkts65to127Octets"),
- MIB_DESC(1, 0x6c, "rx_Pkts65to127Octets"),
- MIB_DESC(1, 0x68, "tx_Pkts128to255Octets"),
- MIB_DESC(1, 0x64, "rx_Pkts128to255Octets"),
- MIB_DESC(1, 0x60, "tx_Pkts256to511Octets"),
- MIB_DESC(1, 0x5c, "rx_Pkts256to511Octets"),
- MIB_DESC(1, 0x58, "tx_Pkts512to1023Octets"),
- MIB_DESC(1, 0x54, "rx_Pkts512to1023Octets"),
- MIB_DESC(1, 0x50, "tx_Pkts1024to1518Octets"),
- MIB_DESC(1, 0x4c, "rx_StatsPkts1024to1518Octets"),
- MIB_DESC(1, 0x48, "tx_Pkts1519toMaxOctets"),
- MIB_DESC(1, 0x44, "rx_Pkts1519toMaxOctets"),
- MIB_DESC(1, 0x40, "rxMacDiscards")
-};
-
-
-/* DSA callbacks */
-
-
-static enum dsa_tag_protocol rtl83xx_get_tag_protocol(struct dsa_switch *ds,
- int port,
- enum dsa_tag_protocol mprot)
-{
- /* The switch does not tag the frames, instead internally the header
- * structure for each packet is tagged accordingly.
- */
- return DSA_TAG_PROTO_TRAILER;
-}
-
-/* Initialize all VLANS */
-static void rtl83xx_vlan_setup(struct rtl838x_switch_priv *priv)
-{
- struct rtl838x_vlan_info info;
-
- pr_info("In %s\n", __func__);
-
- priv->r->vlan_profile_setup(0);
- priv->r->vlan_profile_setup(1);
- pr_info("UNKNOWN_MC_PMASK: %016llx\n", priv->r->read_mcast_pmask(UNKNOWN_MC_PMASK));
- priv->r->vlan_profile_dump(0);
-
- info.fid = 0; /* Default Forwarding ID / MSTI */
- info.hash_uc_fid = false; /* Do not build the L2 lookup hash with FID, but VID */
- info.hash_mc_fid = false; /* Do the same for Multicast packets */
- info.profile_id = 0; /* Use default Vlan Profile 0 */
- info.tagged_ports = 0; /* Initially no port members */
- if (priv->family_id == RTL9310_FAMILY_ID) {
- info.if_id = 0;
- info.multicast_grp_mask = 0;
- info.l2_tunnel_list_id = -1;
- }
-
- /* Initialize all vlans 0-4095 */
- for (int i = 0; i < MAX_VLANS; i ++)
- priv->r->vlan_set_tagged(i, &info);
-
- /* reset PVIDs; defaults to 1 on reset */
- for (int i = 0; i <= priv->cpu_port; i++) {
- priv->r->vlan_port_pvid_set(i, PBVLAN_TYPE_INNER, 1);
- priv->r->vlan_port_pvid_set(i, PBVLAN_TYPE_OUTER, 1);
- priv->r->vlan_port_pvidmode_set(i, PBVLAN_TYPE_INNER, PBVLAN_MODE_UNTAG_AND_PRITAG);
- priv->r->vlan_port_pvidmode_set(i, PBVLAN_TYPE_OUTER, PBVLAN_MODE_UNTAG_AND_PRITAG);
- }
-
- /* Set forwarding action based on inner VLAN tag */
- for (int i = 0; i < priv->cpu_port; i++)
- priv->r->vlan_fwd_on_inner(i, true);
-}
-
-static void rtl83xx_setup_bpdu_traps(struct rtl838x_switch_priv *priv)
-{
- for (int i = 0; i < priv->cpu_port; i++)
- priv->r->set_receive_management_action(i, BPDU, TRAP2CPU);
-}
-
-static void rtl83xx_setup_lldp_traps(struct rtl838x_switch_priv *priv)
-{
- for (int i = 0; i < priv->cpu_port; i++)
- priv->r->set_receive_management_action(i, LLDP, TRAP2CPU);
-}
-
-static void rtl83xx_port_set_salrn(struct rtl838x_switch_priv *priv,
- int port, bool enable)
-{
- int shift = SALRN_PORT_SHIFT(port);
- int val = enable ? SALRN_MODE_HARDWARE : SALRN_MODE_DISABLED;
-
- sw_w32_mask(SALRN_MODE_MASK << shift, val << shift,
- priv->r->l2_port_new_salrn(port));
-}
-
-static int rtl83xx_setup(struct dsa_switch *ds)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- pr_debug("%s called\n", __func__);
-
- /* Disable MAC polling the PHY so that we can start configuration */
- priv->r->set_port_reg_le(0ULL, priv->r->smi_poll_ctrl);
-
- for (int i = 0; i < ds->num_ports; i++)
- priv->ports[i].enable = false;
- priv->ports[priv->cpu_port].enable = true;
-
- /* Configure ports so they are disabled by default, but once enabled
- * they will work in isolated mode (only traffic between port and CPU).
- */
- for (int i = 0; i < priv->cpu_port; i++) {
- if (priv->ports[i].phy) {
- priv->ports[i].pm = BIT_ULL(priv->cpu_port);
- priv->r->traffic_set(i, BIT_ULL(i));
- }
- }
- priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port));
-
- /* For standalone ports, forward packets even if a static fdb
- * entry for the source address exists on another port.
- */
- if (priv->r->set_static_move_action) {
- for (int i = 0; i <= priv->cpu_port; i++)
- priv->r->set_static_move_action(i, true);
- }
-
- if (priv->family_id == RTL8380_FAMILY_ID)
- rtl838x_print_matrix();
- else
- rtl839x_print_matrix();
-
- rtl83xx_init_stats(priv);
-
- rtl83xx_vlan_setup(priv);
-
- rtl83xx_setup_bpdu_traps(priv);
- rtl83xx_setup_lldp_traps(priv);
-
- ds->configure_vlan_while_not_filtering = true;
-
- priv->r->l2_learning_setup();
-
- rtl83xx_port_set_salrn(priv, priv->cpu_port, false);
- ds->assisted_learning_on_cpu_port = true;
-
- /* Make sure all frames sent to the switch's MAC are trapped to the CPU-port
- * 0: FWD, 1: DROP, 2: TRAP2CPU
- */
- if (priv->family_id == RTL8380_FAMILY_ID)
- sw_w32(0x2, RTL838X_SPCL_TRAP_SWITCH_MAC_CTRL);
- else
- sw_w32(0x2, RTL839X_SPCL_TRAP_SWITCH_MAC_CTRL);
-
- /* Enable MAC Polling PHY again */
- rtl83xx_enable_phy_polling(priv);
- pr_debug("Please wait until PHY is settled\n");
- msleep(1000);
- priv->r->pie_init(priv);
-
- return 0;
-}
-
-static int rtl93xx_setup(struct dsa_switch *ds)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- pr_info("%s called\n", __func__);
-
- /* Disable MAC polling the PHY so that we can start configuration */
- if (priv->family_id == RTL9300_FAMILY_ID)
- sw_w32(0, RTL930X_SMI_POLL_CTRL);
-
- if (priv->family_id == RTL9310_FAMILY_ID) {
- sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL);
- sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL + 4);
- }
-
- /* Disable all ports except CPU port */
- for (int i = 0; i < ds->num_ports; i++)
- priv->ports[i].enable = false;
- priv->ports[priv->cpu_port].enable = true;
-
- /* Configure ports so they are disabled by default, but once enabled
- * they will work in isolated mode (only traffic between port and CPU).
- */
- for (int i = 0; i < priv->cpu_port; i++) {
- if (priv->ports[i].phy) {
- priv->ports[i].pm = BIT_ULL(priv->cpu_port);
- priv->r->traffic_set(i, BIT_ULL(i));
- }
- }
- priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port));
-
- rtl930x_print_matrix();
-
- /* TODO: Initialize statistics */
-
- rtl83xx_vlan_setup(priv);
-
- ds->configure_vlan_while_not_filtering = true;
-
- priv->r->l2_learning_setup();
-
- rtl83xx_port_set_salrn(priv, priv->cpu_port, false);
- ds->assisted_learning_on_cpu_port = true;
-
- rtl83xx_enable_phy_polling(priv);
-
- priv->r->pie_init(priv);
-
- priv->r->led_init(priv);
-
- return 0;
-}
-
-static int rtl93xx_get_sds(struct phy_device *phydev)
-{
- struct device *dev = &phydev->mdio.dev;
- struct device_node *dn;
- u32 sds_num;
-
- if (!dev)
- return -1;
- if (dev->of_node) {
- dn = dev->of_node;
- if (of_property_read_u32(dn, "sds", &sds_num))
- sds_num = -1;
- } else {
- dev_err(dev, "No DT node.\n");
- return -1;
- }
-
- return sds_num;
-}
-
-static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
- pr_debug("In %s port %d, state is %d", __func__, port, state->interface);
-
- if (!phy_interface_mode_is_rgmii(state->interface) &&
- state->interface != PHY_INTERFACE_MODE_NA &&
- state->interface != PHY_INTERFACE_MODE_1000BASEX &&
- state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII &&
- state->interface != PHY_INTERFACE_MODE_GMII &&
- state->interface != PHY_INTERFACE_MODE_QSGMII &&
- state->interface != PHY_INTERFACE_MODE_INTERNAL &&
- state->interface != PHY_INTERFACE_MODE_SGMII) {
- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
- dev_err(ds->dev,
- "Unsupported interface: %d for port %d\n",
- state->interface, port);
- return;
- }
-
- /* Allow all the expected bits */
- phylink_set(mask, Autoneg);
- phylink_set_port_modes(mask);
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
-
- /* With the exclusion of MII and Reverse MII, we support Gigabit,
- * including Half duplex
- */
- if (state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII) {
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 1000baseT_Half);
- }
-
- /* On both the 8380 and 8382, ports 24-27 are SFP ports */
- if (port >= 24 && port <= 27 && priv->family_id == RTL8380_FAMILY_ID)
- phylink_set(mask, 1000baseX_Full);
-
- /* On the RTL839x family of SoCs, ports 48 to 51 are SFP ports */
- if (port >= 48 && port <= 51 && priv->family_id == RTL8390_FAMILY_ID)
- phylink_set(mask, 1000baseX_Full);
-
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
-
- bitmap_and(supported, supported, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
- bitmap_and(state->advertising, state->advertising, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
-static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
- pr_debug("In %s port %d, state is %d (%s)", __func__, port, state->interface,
- phy_modes(state->interface));
-
- if (!phy_interface_mode_is_rgmii(state->interface) &&
- state->interface != PHY_INTERFACE_MODE_NA &&
- state->interface != PHY_INTERFACE_MODE_1000BASEX &&
- state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII &&
- state->interface != PHY_INTERFACE_MODE_GMII &&
- state->interface != PHY_INTERFACE_MODE_QSGMII &&
- state->interface != PHY_INTERFACE_MODE_XGMII &&
- state->interface != PHY_INTERFACE_MODE_HSGMII &&
- state->interface != PHY_INTERFACE_MODE_10GBASER &&
- state->interface != PHY_INTERFACE_MODE_10GKR &&
- state->interface != PHY_INTERFACE_MODE_USXGMII &&
- state->interface != PHY_INTERFACE_MODE_INTERNAL &&
- state->interface != PHY_INTERFACE_MODE_SGMII) {
- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
- dev_err(ds->dev,
- "Unsupported interface: %d for port %d\n",
- state->interface, port);
- return;
- }
-
- /* Allow all the expected bits */
- phylink_set(mask, Autoneg);
- phylink_set_port_modes(mask);
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
-
- /* With the exclusion of MII and Reverse MII, we support Gigabit,
- * including Half duplex
- */
- if (state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII) {
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 1000baseT_Half);
- }
-
- /* Internal phys of the RTL93xx family provide 10G */
- if (priv->ports[port].phy_is_integrated &&
- state->interface == PHY_INTERFACE_MODE_1000BASEX) {
- phylink_set(mask, 1000baseX_Full);
- } else if (priv->ports[port].phy_is_integrated) {
- phylink_set(mask, 1000baseX_Full);
- phylink_set(mask, 10000baseKR_Full);
- phylink_set(mask, 10000baseSR_Full);
- phylink_set(mask, 10000baseCR_Full);
- }
- if (state->interface == PHY_INTERFACE_MODE_INTERNAL) {
- phylink_set(mask, 1000baseX_Full);
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 10000baseKR_Full);
- phylink_set(mask, 10000baseT_Full);
- phylink_set(mask, 10000baseSR_Full);
- phylink_set(mask, 10000baseCR_Full);
- }
-
- if (state->interface == PHY_INTERFACE_MODE_USXGMII) {
- phylink_set(mask, 2500baseT_Full);
- phylink_set(mask, 5000baseT_Full);
- phylink_set(mask, 10000baseT_Full);
- }
-
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
-
- bitmap_and(supported, supported, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
- bitmap_and(state->advertising, state->advertising, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
- pr_debug("%s leaving supported: %*pb", __func__, __ETHTOOL_LINK_MODE_MASK_NBITS, supported);
-}
-
-static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
- struct phylink_link_state *state)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 speed;
- u64 link;
-
- if (port < 0 || port > priv->cpu_port)
- return -EINVAL;
-
- state->link = 0;
- link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
- if (link & BIT_ULL(port))
- state->link = 1;
- pr_debug("%s: link state port %d: %llx\n", __func__, port, link & BIT_ULL(port));
-
- state->duplex = 0;
- if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
- state->duplex = 1;
-
- speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
- speed >>= (port % 16) << 1;
- switch (speed & 0x3) {
- case 0:
- state->speed = SPEED_10;
- break;
- case 1:
- state->speed = SPEED_100;
- break;
- case 2:
- state->speed = SPEED_1000;
- break;
- case 3:
- if (priv->family_id == RTL9300_FAMILY_ID
- && (port == 24 || port == 26)) /* Internal serdes */
- state->speed = SPEED_2500;
- else
- state->speed = SPEED_100; /* Is in fact 500Mbit */
- }
-
- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
- if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
- state->pause |= MLO_PAUSE_RX;
- if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
- state->pause |= MLO_PAUSE_TX;
-
- return 1;
-}
-
-static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
- struct phylink_link_state *state)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 speed;
- u64 link;
- u64 media;
-
- if (port < 0 || port > priv->cpu_port)
- return -EINVAL;
-
- /* On the RTL9300 for at least the RTL8226B PHY, the MAC-side link
- * state needs to be read twice in order to read a correct result.
- * This would not be necessary for ports connected e.g. to RTL8218D
- * PHYs.
- */
- state->link = 0;
- link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
- link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
- if (link & BIT_ULL(port))
- state->link = 1;
-
- if (priv->family_id == RTL9310_FAMILY_ID)
- media = priv->r->get_port_reg_le(RTL931X_MAC_LINK_MEDIA_STS);
-
- if (priv->family_id == RTL9300_FAMILY_ID)
- media = sw_r32(RTL930X_MAC_LINK_MEDIA_STS);
-
- if (media & BIT_ULL(port))
- state->link = 1;
-
- pr_debug("%s: link state port %d: %llx, media %llx\n", __func__, port,
- link & BIT_ULL(port), media);
-
- state->duplex = 0;
- if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
- state->duplex = 1;
-
- speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
- speed >>= (port % 8) << 2;
- switch (speed & 0xf) {
- case 0:
- state->speed = SPEED_10;
- break;
- case 1:
- state->speed = SPEED_100;
- break;
- case 2:
- case 7:
- state->speed = SPEED_1000;
- break;
- case 4:
- state->speed = SPEED_10000;
- break;
- case 5:
- case 8:
- state->speed = SPEED_2500;
- break;
- case 6:
- state->speed = SPEED_5000;
- break;
- default:
- pr_err("%s: unknown speed: %d\n", __func__, (u32)speed & 0xf);
- }
-
- if (priv->family_id == RTL9310_FAMILY_ID
- && (port >= 52 && port <= 55)) { /* Internal serdes */
- state->speed = SPEED_10000;
- state->link = 1;
- state->duplex = 1;
- }
-
- pr_debug("%s: speed is: %d %d\n", __func__, (u32)speed & 0xf, state->speed);
- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
- if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
- state->pause |= MLO_PAUSE_RX;
- if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
- state->pause |= MLO_PAUSE_TX;
-
- return 1;
-}
-
-static void rtl83xx_config_interface(int port, phy_interface_t interface)
-{
- u32 old, int_shift, sds_shift;
-
- switch (port) {
- case 24:
- int_shift = 0;
- sds_shift = 5;
- break;
- case 26:
- int_shift = 3;
- sds_shift = 0;
- break;
- default:
- return;
- }
-
- old = sw_r32(RTL838X_SDS_MODE_SEL);
- switch (interface) {
- case PHY_INTERFACE_MODE_1000BASEX:
- if ((old >> sds_shift & 0x1f) == 4)
- return;
- sw_w32_mask(0x7 << int_shift, 1 << int_shift, RTL838X_INT_MODE_CTRL);
- sw_w32_mask(0x1f << sds_shift, 4 << sds_shift, RTL838X_SDS_MODE_SEL);
- break;
- case PHY_INTERFACE_MODE_SGMII:
- if ((old >> sds_shift & 0x1f) == 2)
- return;
- sw_w32_mask(0x7 << int_shift, 2 << int_shift, RTL838X_INT_MODE_CTRL);
- sw_w32_mask(0x1f << sds_shift, 2 << sds_shift, RTL838X_SDS_MODE_SEL);
- break;
- default:
- return;
- }
- pr_debug("configured port %d for interface %s\n", port, phy_modes(interface));
-}
-
-static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
- unsigned int mode,
- const struct phylink_link_state *state)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u32 reg;
- int speed_bit = priv->family_id == RTL8380_FAMILY_ID ? 4 : 3;
-
- pr_debug("%s port %d, mode %x\n", __func__, port, mode);
-
- if (port == priv->cpu_port) {
- /* Set Speed, duplex, flow control
- * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL
- * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN
- * | MEDIA_SEL
- */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- sw_w32(0x6192F, priv->r->mac_force_mode_ctrl(priv->cpu_port));
- /* allow CRC errors on CPU-port */
- sw_w32_mask(0, 0x8, RTL838X_MAC_PORT_CTRL(priv->cpu_port));
- } else {
- sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl(priv->cpu_port));
- }
- return;
- }
-
- reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
- /* Auto-Negotiation does not work for MAC in RTL8390 */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
- pr_debug("PHY autonegotiates\n");
- reg |= RTL838X_NWAY_EN;
- sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
- rtl83xx_config_interface(port, state->interface);
- return;
- }
- }
-
- if (mode != MLO_AN_FIXED)
- pr_debug("Fixed state.\n");
-
- /* Clear id_mode_dis bit, and the existing port mode, let
- * RGMII_MODE_EN bet set by mac_link_{up,down} */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- reg &= ~(RTL838X_RX_PAUSE_EN | RTL838X_TX_PAUSE_EN);
- if (state->pause & MLO_PAUSE_TXRX_MASK) {
- if (state->pause & MLO_PAUSE_TX)
- reg |= RTL838X_TX_PAUSE_EN;
- reg |= RTL838X_RX_PAUSE_EN;
- }
- } else if (priv->family_id == RTL8390_FAMILY_ID) {
- reg &= ~(RTL839X_RX_PAUSE_EN | RTL839X_TX_PAUSE_EN);
- if (state->pause & MLO_PAUSE_TXRX_MASK) {
- if (state->pause & MLO_PAUSE_TX)
- reg |= RTL839X_TX_PAUSE_EN;
- reg |= RTL839X_RX_PAUSE_EN;
- }
- }
-
-
- reg &= ~(3 << speed_bit);
- switch (state->speed) {
- case SPEED_1000:
- reg |= 2 << speed_bit;
- break;
- case SPEED_100:
- reg |= 1 << speed_bit;
- break;
- default:
- break; /* Ignore, including 10MBit which has a speed value of 0 */
- }
-
- if (priv->family_id == RTL8380_FAMILY_ID) {
- reg &= ~(RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
- if (state->link)
- reg |= RTL838X_FORCE_LINK_EN;
- if (state->duplex == RTL838X_DUPLEX_MODE)
- reg |= RTL838X_DUPLEX_MODE;
- } else if (priv->family_id == RTL8390_FAMILY_ID) {
- reg &= ~(RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN);
- if (state->link)
- reg |= RTL839X_FORCE_LINK_EN;
- if (state->duplex == RTL839X_DUPLEX_MODE)
- reg |= RTL839X_DUPLEX_MODE;
- }
-
- /* LAG members must use DUPLEX and we need to enable the link */
- if (priv->lagmembers & BIT_ULL(port)) {
- switch(priv->family_id) {
- case RTL8380_FAMILY_ID:
- reg |= (RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
- break;
- case RTL8390_FAMILY_ID:
- reg |= (RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN);
- break;
- }
- }
-
- /* Disable AN */
- if (priv->family_id == RTL8380_FAMILY_ID)
- reg &= ~RTL838X_NWAY_EN;
- sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
-}
-
-static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port,
- unsigned int mode,
- const struct phylink_link_state *state)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- int sds_num;
- u32 reg, band;
-
- sds_num = priv->ports[port].sds_num;
- pr_info("%s: speed %d sds_num %d\n", __func__, state->speed, sds_num);
-
- switch (state->interface) {
- case PHY_INTERFACE_MODE_HSGMII:
- pr_info("%s setting mode PHY_INTERFACE_MODE_HSGMII\n", __func__);
- band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_HSGMII);
- rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_HSGMII);
- band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_HSGMII);
- break;
- case PHY_INTERFACE_MODE_1000BASEX:
- band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_1000BASEX);
- rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_1000BASEX);
- break;
- case PHY_INTERFACE_MODE_XGMII:
- band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_XGMII);
- rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_XGMII);
- break;
- case PHY_INTERFACE_MODE_10GBASER:
- case PHY_INTERFACE_MODE_10GKR:
- band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_10GBASER);
- rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_10GBASER);
- break;
- case PHY_INTERFACE_MODE_USXGMII:
- /* Translates to MII_USXGMII_10GSXGMII */
- band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_USXGMII);
- rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_USXGMII);
- break;
- case PHY_INTERFACE_MODE_SGMII:
- pr_info("%s setting mode PHY_INTERFACE_MODE_SGMII\n", __func__);
- band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_SGMII);
- rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_SGMII);
- band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_SGMII);
- break;
- case PHY_INTERFACE_MODE_QSGMII:
- band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_QSGMII);
- rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_QSGMII);
- break;
- default:
- pr_err("%s: unknown serdes mode: %s\n",
- __func__, phy_modes(state->interface));
- return;
- }
-
- reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
- pr_info("%s reading FORCE_MODE_CTRL: %08x\n", __func__, reg);
-
- reg &= ~(RTL931X_DUPLEX_MODE | RTL931X_FORCE_EN | RTL931X_FORCE_LINK_EN);
-
- reg &= ~(0xf << 12);
- reg |= 0x2 << 12; /* Set SMI speed to 0x2 */
-
- reg |= RTL931X_TX_PAUSE_EN | RTL931X_RX_PAUSE_EN;
-
- if (priv->lagmembers & BIT_ULL(port))
- reg |= RTL931X_DUPLEX_MODE;
-
- if (state->duplex == DUPLEX_FULL)
- reg |= RTL931X_DUPLEX_MODE;
-
- sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
-
-}
-
-static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port,
- unsigned int mode,
- const struct phylink_link_state *state)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- int sds_num;
- u32 reg;
-
- pr_info("%s port %d, mode %x, phy-mode: %s, speed %d, link %d\n", __func__,
- port, mode, phy_modes(state->interface), state->speed, state->link);
-
- /* Nothing to be done for the CPU-port */
- if (port == priv->cpu_port)
- return;
-
- if (priv->family_id == RTL9310_FAMILY_ID)
- return rtl931x_phylink_mac_config(ds, port, mode, state);
-
- sds_num = priv->ports[port].sds_num;
- pr_info("%s SDS is %d\n", __func__, sds_num);
- if (sds_num >= 0 &&
- (state->interface == PHY_INTERFACE_MODE_1000BASEX ||
- state->interface == PHY_INTERFACE_MODE_10GBASER))
- rtl9300_serdes_setup(port, sds_num, state->interface);
-
- reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
- reg &= ~(0xf << 3);
-
- switch (state->speed) {
- case SPEED_10000:
- reg |= 4 << 3;
- break;
- case SPEED_5000:
- reg |= 6 << 3;
- break;
- case SPEED_2500:
- reg |= 5 << 3;
- break;
- case SPEED_1000:
- reg |= 2 << 3;
- break;
- case SPEED_100:
- reg |= 1 << 3;
- break;
- default:
- /* Also covers 10M */
- break;
- }
-
- if (state->link)
- reg |= RTL930X_FORCE_LINK_EN;
-
- if (priv->lagmembers & BIT_ULL(port))
- reg |= RTL930X_DUPLEX_MODE | RTL930X_FORCE_LINK_EN;
-
- if (state->duplex == DUPLEX_FULL)
- reg |= RTL930X_DUPLEX_MODE;
- else
- reg &= ~RTL930X_DUPLEX_MODE; /* Clear duplex bit otherwise */
-
- if (priv->ports[port].phy_is_integrated)
- reg &= ~RTL930X_FORCE_EN; /* Clear MAC_FORCE_EN to allow SDS-MAC link */
- else
- reg |= RTL930X_FORCE_EN;
-
- sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
-}
-
-static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- /* Stop TX/RX to port */
- sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
-
- /* No longer force link */
- sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl(port));
-}
-
-static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u32 v = 0;
-
- /* Stop TX/RX to port */
- sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
-
- /* No longer force link */
- if (priv->family_id == RTL9300_FAMILY_ID)
- v = RTL930X_FORCE_EN | RTL930X_FORCE_LINK_EN;
- else if (priv->family_id == RTL9310_FAMILY_ID)
- v = RTL931X_FORCE_EN | RTL931X_FORCE_LINK_EN;
- sw_w32_mask(v, 0, priv->r->mac_force_mode_ctrl(port));
-}
-
-static void rtl83xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
- struct phy_device *phydev,
- int speed, int duplex,
- bool tx_pause, bool rx_pause)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- /* Restart TX/RX to port */
- sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
- /* TODO: Set speed/duplex/pauses */
-}
-
-static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
- struct phy_device *phydev,
- int speed, int duplex,
- bool tx_pause, bool rx_pause)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- /* Restart TX/RX to port */
- sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
- /* TODO: Set speed/duplex/pauses */
-}
-
-static void rtl83xx_get_strings(struct dsa_switch *ds,
- int port, u32 stringset, u8 *data)
-{
- if (stringset != ETH_SS_STATS)
- return;
-
- for (int i = 0; i < ARRAY_SIZE(rtl83xx_mib); i++)
- ethtool_puts(&data, rtl83xx_mib[i].name);
-}
-
-static void rtl83xx_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *data)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- const struct rtl83xx_mib_desc *mib;
- u64 h;
-
- for (int i = 0; i < ARRAY_SIZE(rtl83xx_mib); i++) {
- mib = &rtl83xx_mib[i];
-
- data[i] = sw_r32(priv->r->stat_port_std_mib + (port << 8) + 252 - mib->offset);
- if (mib->size == 2) {
- h = sw_r32(priv->r->stat_port_std_mib + (port << 8) + 248 - mib->offset);
- data[i] |= h << 32;
- }
- }
-}
-
-static int rtl83xx_get_sset_count(struct dsa_switch *ds, int port, int sset)
-{
- if (sset != ETH_SS_STATS)
- return 0;
-
- return ARRAY_SIZE(rtl83xx_mib);
-}
-
-static int rtl83xx_mc_group_alloc(struct rtl838x_switch_priv *priv, int port)
-{
- int mc_group = find_first_zero_bit(priv->mc_group_bm, MAX_MC_GROUPS - 1);
- u64 portmask;
-
- if (mc_group >= MAX_MC_GROUPS - 1)
- return -1;
-
- set_bit(mc_group, priv->mc_group_bm);
- portmask = BIT_ULL(port);
- priv->r->write_mcast_pmask(mc_group, portmask);
-
- return mc_group;
-}
-
-static u64 rtl83xx_mc_group_add_port(struct rtl838x_switch_priv *priv, int mc_group, int port)
-{
- u64 portmask = priv->r->read_mcast_pmask(mc_group);
-
- pr_debug("%s: %d\n", __func__, port);
-
- portmask |= BIT_ULL(port);
- priv->r->write_mcast_pmask(mc_group, portmask);
-
- return portmask;
-}
-
-static u64 rtl83xx_mc_group_del_port(struct rtl838x_switch_priv *priv, int mc_group, int port)
-{
- u64 portmask = priv->r->read_mcast_pmask(mc_group);
-
- pr_debug("%s: %d\n", __func__, port);
-
- portmask &= ~BIT_ULL(port);
- priv->r->write_mcast_pmask(mc_group, portmask);
- if (!portmask)
- clear_bit(mc_group, priv->mc_group_bm);
-
- return portmask;
-}
-
-static int rtl83xx_port_enable(struct dsa_switch *ds, int port,
- struct phy_device *phydev)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 v;
-
- pr_debug("%s: %x %d", __func__, (u32) priv, port);
- priv->ports[port].enable = true;
-
- /* enable inner tagging on egress, do not keep any tags */
- priv->r->vlan_port_keep_tag_set(port, 0, 1);
-
- if (dsa_is_cpu_port(ds, port))
- return 0;
-
- /* add port to switch mask of CPU_PORT */
- priv->r->traffic_enable(priv->cpu_port, port);
-
- if (priv->is_lagmember[port]) {
- pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
- return 0;
- }
-
- /* add all other ports in the same bridge to switch mask of port */
- v = priv->r->traffic_get(port);
- v |= priv->ports[port].pm;
- priv->r->traffic_set(port, v);
-
- /* TODO: Figure out if this is necessary */
- if (priv->family_id == RTL9300_FAMILY_ID) {
- sw_w32_mask(0, BIT(port), RTL930X_L2_PORT_SABLK_CTRL);
- sw_w32_mask(0, BIT(port), RTL930X_L2_PORT_DABLK_CTRL);
- }
-
- if (priv->ports[port].sds_num < 0)
- priv->ports[port].sds_num = rtl93xx_get_sds(phydev);
-
- return 0;
-}
-
-static void rtl83xx_port_disable(struct dsa_switch *ds, int port)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 v;
-
- pr_debug("%s %x: %d", __func__, (u32)priv, port);
- /* you can only disable user ports */
- if (!dsa_is_user_port(ds, port))
- return;
-
- /* BUG: This does not work on RTL931X */
- /* remove port from switch mask of CPU_PORT */
- priv->r->traffic_disable(priv->cpu_port, port);
-
- /* remove all other ports in the same bridge from switch mask of port */
- v = priv->r->traffic_get(port);
- v &= ~priv->ports[port].pm;
- priv->r->traffic_set(port, v);
-
- priv->ports[port].enable = false;
-}
-
-static int rtl83xx_set_mac_eee(struct dsa_switch *ds, int port,
- struct ethtool_eee *e)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- if (e->eee_enabled && !priv->eee_enabled) {
- pr_info("Globally enabling EEE\n");
- priv->r->init_eee(priv, true);
- }
-
- priv->r->port_eee_set(priv, port, e->eee_enabled);
-
- if (e->eee_enabled)
- pr_info("Enabled EEE for port %d\n", port);
- else
- pr_info("Disabled EEE for port %d\n", port);
-
- return 0;
-}
-
-static int rtl83xx_get_mac_eee(struct dsa_switch *ds, int port,
- struct ethtool_eee *e)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- e->supported = SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full;
-
- priv->r->eee_port_ability(priv, e, port);
-
- e->eee_enabled = priv->ports[port].eee_enabled;
-
- e->eee_active = !!(e->advertised & e->lp_advertised);
-
- return 0;
-}
-
-static int rtl93xx_get_mac_eee(struct dsa_switch *ds, int port,
- struct ethtool_eee *e)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- e->supported = SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full;
-
- priv->r->eee_port_ability(priv, e, port);
-
- e->eee_enabled = priv->ports[port].eee_enabled;
-
- e->eee_active = !!(e->advertised & e->lp_advertised);
-
- return 0;
-}
-
-static int rtl83xx_set_ageing_time(struct dsa_switch *ds, unsigned int msec)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- priv->r->set_ageing_time(msec);
-
- return 0;
-}
-
-static int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port,
- struct net_device *bridge)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 port_bitmap = BIT_ULL(priv->cpu_port), v;
-
- pr_debug("%s %x: %d %llx", __func__, (u32)priv, port, port_bitmap);
-
- if (priv->is_lagmember[port]) {
- pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
- return 0;
- }
-
- mutex_lock(&priv->reg_mutex);
- for (int i = 0; i < ds->num_ports; i++) {
- /* Add this port to the port matrix of the other ports in the
- * same bridge. If the port is disabled, port matrix is kept
- * and not being setup until the port becomes enabled.
- */
- if (dsa_is_user_port(ds, i) && !priv->is_lagmember[i] && i != port) {
- if (dsa_to_port(ds, i)->bridge_dev != bridge)
- continue;
- if (priv->ports[i].enable)
- priv->r->traffic_enable(i, port);
-
- priv->ports[i].pm |= BIT_ULL(port);
- port_bitmap |= BIT_ULL(i);
- }
- }
-
- /* Add all other ports to this port matrix. */
- if (priv->ports[port].enable) {
- priv->r->traffic_enable(priv->cpu_port, port);
- v = priv->r->traffic_get(port);
- v |= port_bitmap;
- priv->r->traffic_set(port, v);
- }
- priv->ports[port].pm |= port_bitmap;
-
- if (priv->r->set_static_move_action)
- priv->r->set_static_move_action(port, false);
-
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
- struct net_device *bridge)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 port_bitmap = 0, v;
-
- pr_debug("%s %x: %d", __func__, (u32)priv, port);
- mutex_lock(&priv->reg_mutex);
- for (int i = 0; i < ds->num_ports; i++) {
- /* Remove this port from the port matrix of the other ports
- * in the same bridge. If the port is disabled, port matrix
- * is kept and not being setup until the port becomes enabled.
- * And the other port's port matrix cannot be broken when the
- * other port is still a VLAN-aware port.
- */
- if (dsa_is_user_port(ds, i) && i != port) {
- if (dsa_to_port(ds, i)->bridge_dev != bridge)
- continue;
- if (priv->ports[i].enable)
- priv->r->traffic_disable(i, port);
-
- priv->ports[i].pm &= ~BIT_ULL(port);
- port_bitmap |= BIT_ULL(i);
- }
- }
-
- /* Remove all other ports from this port matrix. */
- if (priv->ports[port].enable) {
- v = priv->r->traffic_get(port);
- v &= ~port_bitmap;
- priv->r->traffic_set(port, v);
- }
- priv->ports[port].pm &= ~port_bitmap;
-
- if (priv->r->set_static_move_action)
- priv->r->set_static_move_action(port, true);
-
- mutex_unlock(&priv->reg_mutex);
-}
-
-void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-{
- u32 msti = 0;
- u32 port_state[4];
- int index, bit;
- int pos = port;
- struct rtl838x_switch_priv *priv = ds->priv;
- int n = priv->port_width << 1;
-
- /* Ports above or equal CPU port can never be configured */
- if (port >= priv->cpu_port)
- return;
-
- mutex_lock(&priv->reg_mutex);
-
- /* For the RTL839x and following, the bits are left-aligned, 838x and 930x
- * have 64 bit fields, 839x and 931x have 128 bit fields
- */
- if (priv->family_id == RTL8390_FAMILY_ID)
- pos += 12;
- if (priv->family_id == RTL9300_FAMILY_ID)
- pos += 3;
- if (priv->family_id == RTL9310_FAMILY_ID)
- pos += 8;
-
- index = n - (pos >> 4) - 1;
- bit = (pos << 1) % 32;
-
- priv->r->stp_get(priv, msti, port_state);
-
- pr_debug("Current state, port %d: %d\n", port, (port_state[index] >> bit) & 3);
- port_state[index] &= ~(3 << bit);
-
- switch (state) {
- case BR_STATE_DISABLED: /* 0 */
- port_state[index] |= (0 << bit);
- break;
- case BR_STATE_BLOCKING: /* 4 */
- case BR_STATE_LISTENING: /* 1 */
- port_state[index] |= (1 << bit);
- break;
- case BR_STATE_LEARNING: /* 2 */
- port_state[index] |= (2 << bit);
- break;
- case BR_STATE_FORWARDING: /* 3 */
- port_state[index] |= (3 << bit);
- default:
- break;
- }
-
- priv->r->stp_set(priv, msti, port_state);
-
- mutex_unlock(&priv->reg_mutex);
-}
-
-void rtl83xx_fast_age(struct dsa_switch *ds, int port)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- int s = priv->family_id == RTL8390_FAMILY_ID ? 2 : 0;
-
- pr_debug("FAST AGE port %d\n", port);
- mutex_lock(&priv->reg_mutex);
- /* RTL838X_L2_TBL_FLUSH_CTRL register bits, 839x has 1 bit larger
- * port fields:
- * 0-4: Replacing port
- * 5-9: Flushed/replaced port
- * 10-21: FVID
- * 22: Entry types: 1: dynamic, 0: also static
- * 23: Match flush port
- * 24: Match FVID
- * 25: Flush (0) or replace (1) L2 entries
- * 26: Status of action (1: Start, 0: Done)
- */
- sw_w32(1 << (26 + s) | 1 << (23 + s) | port << (5 + (s / 2)), priv->r->l2_tbl_flush_ctrl);
-
- do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(26 + s));
-
- mutex_unlock(&priv->reg_mutex);
-}
-
-void rtl931x_fast_age(struct dsa_switch *ds, int port)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- pr_info("%s port %d\n", __func__, port);
- mutex_lock(&priv->reg_mutex);
- sw_w32(port << 11, RTL931X_L2_TBL_FLUSH_CTRL + 4);
-
- sw_w32(BIT(24) | BIT(28), RTL931X_L2_TBL_FLUSH_CTRL);
-
- do { } while (sw_r32(RTL931X_L2_TBL_FLUSH_CTRL) & BIT (28));
-
- mutex_unlock(&priv->reg_mutex);
-}
-
-void rtl930x_fast_age(struct dsa_switch *ds, int port)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- if (priv->family_id == RTL9310_FAMILY_ID)
- return rtl931x_fast_age(ds, port);
-
- pr_debug("FAST AGE port %d\n", port);
- mutex_lock(&priv->reg_mutex);
- sw_w32(port << 11, RTL930X_L2_TBL_FLUSH_CTRL + 4);
-
- sw_w32(BIT(26) | BIT(30), RTL930X_L2_TBL_FLUSH_CTRL);
-
- do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(30));
-
- mutex_unlock(&priv->reg_mutex);
-}
-
-static int rtl83xx_vlan_filtering(struct dsa_switch *ds, int port,
- bool vlan_filtering,
- struct netlink_ext_ack *extack)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- pr_debug("%s: port %d\n", __func__, port);
- mutex_lock(&priv->reg_mutex);
-
- if (vlan_filtering) {
- /* Enable ingress and egress filtering
- * The VLAN_PORT_IGR_FILTER register uses 2 bits for each port to define
- * the filter action:
- * 0: Always Forward
- * 1: Drop packet
- * 2: Trap packet to CPU port
- * The Egress filter used 1 bit per state (0: DISABLED, 1: ENABLED)
- */
- if (port != priv->cpu_port) {
- priv->r->set_vlan_igr_filter(port, IGR_DROP);
- priv->r->set_vlan_egr_filter(port, EGR_ENABLE);
- }
- else {
- priv->r->set_vlan_igr_filter(port, IGR_TRAP);
- priv->r->set_vlan_egr_filter(port, EGR_DISABLE);
- }
-
- } else {
- /* Disable ingress and egress filtering */
- if (port != priv->cpu_port)
- priv->r->set_vlan_igr_filter(port, IGR_FORWARD);
-
- priv->r->set_vlan_egr_filter(port, EGR_DISABLE);
- }
-
- /* Do we need to do something to the CPU-Port, too? */
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static int rtl83xx_vlan_prepare(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan)
-{
- struct rtl838x_vlan_info info;
- struct rtl838x_switch_priv *priv = ds->priv;
-
- priv->r->vlan_tables_read(0, &info);
-
- pr_debug("VLAN 0: Tagged ports %llx, untag %llx, profile %d, MC# %d, UC# %d, FID %x\n",
- info.tagged_ports, info.untagged_ports, info.profile_id,
- info.hash_mc_fid, info.hash_uc_fid, info.fid);
-
- priv->r->vlan_tables_read(1, &info);
- pr_debug("VLAN 1: Tagged ports %llx, untag %llx, profile %d, MC# %d, UC# %d, FID %x\n",
- info.tagged_ports, info.untagged_ports, info.profile_id,
- info.hash_mc_fid, info.hash_uc_fid, info.fid);
- priv->r->vlan_set_untagged(1, info.untagged_ports);
- pr_debug("SET: Untagged ports, VLAN %d: %llx\n", 1, info.untagged_ports);
-
- priv->r->vlan_set_tagged(1, &info);
- pr_debug("SET: Tagged ports, VLAN %d: %llx\n", 1, info.tagged_ports);
-
- return 0;
-}
-
-static void rtl83xx_vlan_set_pvid(struct rtl838x_switch_priv *priv,
- int port, int pvid)
-{
- /* Set both inner and outer PVID of the port */
- priv->r->vlan_port_pvid_set(port, PBVLAN_TYPE_INNER, pvid);
- priv->r->vlan_port_pvid_set(port, PBVLAN_TYPE_OUTER, pvid);
- priv->r->vlan_port_pvidmode_set(port, PBVLAN_TYPE_INNER,
- PBVLAN_MODE_UNTAG_AND_PRITAG);
- priv->r->vlan_port_pvidmode_set(port, PBVLAN_TYPE_OUTER,
- PBVLAN_MODE_UNTAG_AND_PRITAG);
-
- priv->ports[port].pvid = pvid;
-}
-
-static int rtl83xx_vlan_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan,
- struct netlink_ext_ack *extack)
-{
- struct rtl838x_vlan_info info;
- struct rtl838x_switch_priv *priv = ds->priv;
- int err;
-
- pr_debug("%s port %d, vid %d, flags %x\n",
- __func__, port, vlan->vid, vlan->flags);
-
- if(!vlan->vid) return 0;
-
- if (vlan->vid > 4095) {
- dev_err(priv->dev, "VLAN out of range: %d", vlan->vid);
- return -ENOTSUPP;
- }
-
- err = rtl83xx_vlan_prepare(ds, port, vlan);
- if (err)
- return err;
-
- mutex_lock(&priv->reg_mutex);
-
- if (vlan->flags & BRIDGE_VLAN_INFO_PVID)
- rtl83xx_vlan_set_pvid(priv, port, vlan->vid);
- else if (priv->ports[port].pvid == vlan->vid)
- rtl83xx_vlan_set_pvid(priv, port, 0);
-
- /* Get port memberships of this vlan */
- priv->r->vlan_tables_read(vlan->vid, &info);
-
- /* new VLAN? */
- if (!info.tagged_ports) {
- info.fid = 0;
- info.hash_mc_fid = false;
- info.hash_uc_fid = false;
- info.profile_id = 0;
- }
-
- /* sanitize untagged_ports - must be a subset */
- if (info.untagged_ports & ~info.tagged_ports)
- info.untagged_ports = 0;
-
- info.tagged_ports |= BIT_ULL(port);
- if (vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)
- info.untagged_ports |= BIT_ULL(port);
- else
- info.untagged_ports &= ~BIT_ULL(port);
-
- priv->r->vlan_set_untagged(vlan->vid, info.untagged_ports);
- pr_debug("Untagged ports, VLAN %d: %llx\n", vlan->vid, info.untagged_ports);
-
- priv->r->vlan_set_tagged(vlan->vid, &info);
- pr_debug("Tagged ports, VLAN %d: %llx\n", vlan->vid, info.tagged_ports);
-
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static int rtl83xx_vlan_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan)
-{
- struct rtl838x_vlan_info info;
- struct rtl838x_switch_priv *priv = ds->priv;
- u16 pvid;
-
- pr_debug("%s: port %d, vid %d, flags %x\n",
- __func__, port, vlan->vid, vlan->flags);
-
- if (vlan->vid > 4095) {
- dev_err(priv->dev, "VLAN out of range: %d", vlan->vid);
- return -ENOTSUPP;
- }
-
- mutex_lock(&priv->reg_mutex);
- pvid = priv->ports[port].pvid;
-
- /* Reset to default if removing the current PVID */
- if (vlan->vid == pvid) {
- rtl83xx_vlan_set_pvid(priv, port, 0);
- }
- /* Get port memberships of this vlan */
- priv->r->vlan_tables_read(vlan->vid, &info);
-
- /* remove port from both tables */
- info.untagged_ports &= (~BIT_ULL(port));
- info.tagged_ports &= (~BIT_ULL(port));
-
- priv->r->vlan_set_untagged(vlan->vid, info.untagged_ports);
- pr_debug("Untagged ports, VLAN %d: %llx\n", vlan->vid, info.untagged_ports);
-
- priv->r->vlan_set_tagged(vlan->vid, &info);
- pr_debug("Tagged ports, VLAN %d: %llx\n", vlan->vid, info.tagged_ports);
-
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static void rtl83xx_setup_l2_uc_entry(struct rtl838x_l2_entry *e, int port, int vid, u64 mac)
-{
- memset(e, 0, sizeof(*e));
-
- e->type = L2_UNICAST;
- e->valid = true;
-
- e->age = 3;
- e->is_static = true;
-
- e->port = port;
-
- e->rvid = e->vid = vid;
- e->is_ip_mc = e->is_ipv6_mc = false;
- u64_to_ether_addr(mac, e->mac);
-}
-
-static void rtl83xx_setup_l2_mc_entry(struct rtl838x_l2_entry *e, int vid, u64 mac, int mc_group)
-{
- memset(e, 0, sizeof(*e));
-
- e->type = L2_MULTICAST;
- e->valid = true;
-
- e->mc_portmask_index = mc_group;
-
- e->rvid = e->vid = vid;
- e->is_ip_mc = e->is_ipv6_mc = false;
- u64_to_ether_addr(mac, e->mac);
-}
-
-/* Uses the seed to identify a hash bucket in the L2 using the derived hash key and then loops
- * over the entries in the bucket until either a matching entry is found or an empty slot
- * Returns the filled in rtl838x_l2_entry and the index in the bucket when an entry was found
- * when an empty slot was found and must exist is false, the index of the slot is returned
- * when no slots are available returns -1
- */
-static int rtl83xx_find_l2_hash_entry(struct rtl838x_switch_priv *priv, u64 seed,
- bool must_exist, struct rtl838x_l2_entry *e)
-{
- int idx = -1;
- u32 key = priv->r->l2_hash_key(priv, seed);
- u64 entry;
-
- pr_debug("%s: using key %x, for seed %016llx\n", __func__, key, seed);
- /* Loop over all entries in the hash-bucket and over the second block on 93xx SoCs */
- for (int i = 0; i < priv->l2_bucket_size; i++) {
- entry = priv->r->read_l2_entry_using_hash(key, i, e);
- pr_debug("valid %d, mac %016llx\n", e->valid, ether_addr_to_u64(&e->mac[0]));
- if (must_exist && !e->valid)
- continue;
- if (!e->valid || ((entry & 0x0fffffffffffffffULL) == seed)) {
- idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1 : ((key << 2) | i) & 0xffff;
- break;
- }
- }
-
- return idx;
-}
-
-/* Uses the seed to identify an entry in the CAM by looping over all its entries
- * Returns the filled in rtl838x_l2_entry and the index in the CAM when an entry was found
- * when an empty slot was found the index of the slot is returned
- * when no slots are available returns -1
- */
-static int rtl83xx_find_l2_cam_entry(struct rtl838x_switch_priv *priv, u64 seed,
- bool must_exist, struct rtl838x_l2_entry *e)
-{
- int idx = -1;
- u64 entry;
-
- for (int i = 0; i < 64; i++) {
- entry = priv->r->read_cam(i, e);
- if (!must_exist && !e->valid) {
- if (idx < 0) /* First empty entry? */
- idx = i;
- break;
- } else if ((entry & 0x0fffffffffffffffULL) == seed) {
- pr_debug("Found entry in CAM\n");
- idx = i;
- break;
- }
- }
-
- return idx;
-}
-
-static int rtl83xx_port_fdb_add(struct dsa_switch *ds, int port,
- const unsigned char *addr, u16 vid)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 mac = ether_addr_to_u64(addr);
- struct rtl838x_l2_entry e;
- int err = 0, idx;
- u64 seed = priv->r->l2_hash_seed(mac, vid);
-
- if (priv->is_lagmember[port]) {
- pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
- return 0;
- }
-
- mutex_lock(&priv->reg_mutex);
-
- idx = rtl83xx_find_l2_hash_entry(priv, seed, false, &e);
-
- /* Found an existing or empty entry */
- if (idx >= 0) {
- rtl83xx_setup_l2_uc_entry(&e, port, vid, mac);
- priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
- goto out;
- }
-
- /* Hash buckets full, try CAM */
- idx = rtl83xx_find_l2_cam_entry(priv, seed, false, &e);
-
- if (idx >= 0) {
- rtl83xx_setup_l2_uc_entry(&e, port, vid, mac);
- priv->r->write_cam(idx, &e);
- goto out;
- }
-
- err = -ENOTSUPP;
-
-out:
- mutex_unlock(&priv->reg_mutex);
-
- return err;
-}
-
-static int rtl83xx_port_fdb_del(struct dsa_switch *ds, int port,
- const unsigned char *addr, u16 vid)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 mac = ether_addr_to_u64(addr);
- struct rtl838x_l2_entry e;
- int err = 0, idx;
- u64 seed = priv->r->l2_hash_seed(mac, vid);
-
- pr_debug("In %s, mac %llx, vid: %d\n", __func__, mac, vid);
- mutex_lock(&priv->reg_mutex);
-
- idx = rtl83xx_find_l2_hash_entry(priv, seed, true, &e);
-
- if (idx >= 0) {
- pr_debug("Found entry index %d, key %d and bucket %d\n", idx, idx >> 2, idx & 3);
- e.valid = false;
- priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
- goto out;
- }
-
- /* Check CAM for spillover from hash buckets */
- idx = rtl83xx_find_l2_cam_entry(priv, seed, true, &e);
-
- if (idx >= 0) {
- e.valid = false;
- priv->r->write_cam(idx, &e);
- goto out;
- }
- err = -ENOENT;
-
-out:
- mutex_unlock(&priv->reg_mutex);
-
- return err;
-}
-
-static int rtl83xx_port_fdb_dump(struct dsa_switch *ds, int port,
- dsa_fdb_dump_cb_t *cb, void *data)
-{
- struct rtl838x_l2_entry e;
- struct rtl838x_switch_priv *priv = ds->priv;
-
- mutex_lock(&priv->reg_mutex);
-
- for (int i = 0; i < priv->fib_entries; i++) {
- priv->r->read_l2_entry_using_hash(i >> 2, i & 0x3, &e);
-
- if (!e.valid)
- continue;
-
- if (e.port == port || e.port == RTL930X_PORT_IGNORE)
- cb(e.mac, e.vid, e.is_static, data);
-
- if (!((i + 1) % 64))
- cond_resched();
- }
-
- for (int i = 0; i < 64; i++) {
- priv->r->read_cam(i, &e);
-
- if (!e.valid)
- continue;
-
- if (e.port == port)
- cb(e.mac, e.vid, e.is_static, data);
- }
-
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static int rtl83xx_port_mdb_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_mdb *mdb)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 mac = ether_addr_to_u64(mdb->addr);
- struct rtl838x_l2_entry e;
- int err = 0, idx;
- int vid = mdb->vid;
- u64 seed = priv->r->l2_hash_seed(mac, vid);
- int mc_group;
-
- if (priv->id >= 0x9300)
- return -EOPNOTSUPP;
-
- pr_debug("In %s port %d, mac %llx, vid: %d\n", __func__, port, mac, vid);
-
- if (priv->is_lagmember[port]) {
- pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
- return -EINVAL;
- }
-
- mutex_lock(&priv->reg_mutex);
-
- idx = rtl83xx_find_l2_hash_entry(priv, seed, false, &e);
-
- /* Found an existing or empty entry */
- if (idx >= 0) {
- if (e.valid) {
- pr_debug("Found an existing entry %016llx, mc_group %d\n",
- ether_addr_to_u64(e.mac), e.mc_portmask_index);
- rtl83xx_mc_group_add_port(priv, e.mc_portmask_index, port);
- } else {
- pr_debug("New entry for seed %016llx\n", seed);
- mc_group = rtl83xx_mc_group_alloc(priv, port);
- if (mc_group < 0) {
- err = -ENOTSUPP;
- goto out;
- }
- rtl83xx_setup_l2_mc_entry(&e, vid, mac, mc_group);
- priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
- }
- goto out;
- }
-
- /* Hash buckets full, try CAM */
- idx = rtl83xx_find_l2_cam_entry(priv, seed, false, &e);
-
- if (idx >= 0) {
- if (e.valid) {
- pr_debug("Found existing CAM entry %016llx, mc_group %d\n",
- ether_addr_to_u64(e.mac), e.mc_portmask_index);
- rtl83xx_mc_group_add_port(priv, e.mc_portmask_index, port);
- } else {
- pr_debug("New entry\n");
- mc_group = rtl83xx_mc_group_alloc(priv, port);
- if (mc_group < 0) {
- err = -ENOTSUPP;
- goto out;
- }
- rtl83xx_setup_l2_mc_entry(&e, vid, mac, mc_group);
- priv->r->write_cam(idx, &e);
- }
- goto out;
- }
-
- err = -ENOTSUPP;
-
-out:
- mutex_unlock(&priv->reg_mutex);
- if (err)
- dev_err(ds->dev, "failed to add MDB entry\n");
-
- return err;
-}
-
-int rtl83xx_port_mdb_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_mdb *mdb)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- u64 mac = ether_addr_to_u64(mdb->addr);
- struct rtl838x_l2_entry e;
- int err = 0, idx;
- int vid = mdb->vid;
- u64 seed = priv->r->l2_hash_seed(mac, vid);
- u64 portmask;
-
- pr_debug("In %s, port %d, mac %llx, vid: %d\n", __func__, port, mac, vid);
-
- if (priv->is_lagmember[port]) {
- pr_info("%s: %d is lag slave. ignore\n", __func__, port);
- return 0;
- }
-
- mutex_lock(&priv->reg_mutex);
-
- idx = rtl83xx_find_l2_hash_entry(priv, seed, true, &e);
-
- if (idx >= 0) {
- pr_debug("Found entry index %d, key %d and bucket %d\n", idx, idx >> 2, idx & 3);
- portmask = rtl83xx_mc_group_del_port(priv, e.mc_portmask_index, port);
- if (!portmask) {
- e.valid = false;
- priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
- }
- goto out;
- }
-
- /* Check CAM for spillover from hash buckets */
- idx = rtl83xx_find_l2_cam_entry(priv, seed, true, &e);
-
- if (idx >= 0) {
- portmask = rtl83xx_mc_group_del_port(priv, e.mc_portmask_index, port);
- if (!portmask) {
- e.valid = false;
- priv->r->write_cam(idx, &e);
- }
- goto out;
- }
- /* TODO: Re-enable with a newer kernel: err = -ENOENT; */
-
-out:
- mutex_unlock(&priv->reg_mutex);
-
- return err;
-}
-
-static int rtl83xx_port_mirror_add(struct dsa_switch *ds, int port,
- struct dsa_mall_mirror_tc_entry *mirror,
- bool ingress)
-{
- /* We support 4 mirror groups, one destination port per group */
- int group;
- struct rtl838x_switch_priv *priv = ds->priv;
- int ctrl_reg, dpm_reg, spm_reg;
-
- pr_debug("In %s\n", __func__);
-
- for (group = 0; group < 4; group++) {
- if (priv->mirror_group_ports[group] == mirror->to_local_port)
- break;
- }
- if (group >= 4) {
- for (group = 0; group < 4; group++) {
- if (priv->mirror_group_ports[group] < 0)
- break;
- }
- }
-
- if (group >= 4)
- return -ENOSPC;
-
- ctrl_reg = priv->r->mir_ctrl + group * 4;
- dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width;
- spm_reg = priv->r->mir_spm + group * 4 * priv->port_width;
-
- pr_debug("Using group %d\n", group);
- mutex_lock(&priv->reg_mutex);
-
- if (priv->family_id == RTL8380_FAMILY_ID) {
- /* Enable mirroring to port across VLANs (bit 11) */
- sw_w32(1 << 11 | (mirror->to_local_port << 4) | 1, ctrl_reg);
- } else {
- /* Enable mirroring to destination port */
- sw_w32((mirror->to_local_port << 4) | 1, ctrl_reg);
- }
-
- if (ingress && (priv->r->get_port_reg_be(spm_reg) & (1ULL << port))) {
- mutex_unlock(&priv->reg_mutex);
- return -EEXIST;
- }
- if ((!ingress) && (priv->r->get_port_reg_be(dpm_reg) & (1ULL << port))) {
- mutex_unlock(&priv->reg_mutex);
- return -EEXIST;
- }
-
- if (ingress)
- priv->r->mask_port_reg_be(0, 1ULL << port, spm_reg);
- else
- priv->r->mask_port_reg_be(0, 1ULL << port, dpm_reg);
-
- priv->mirror_group_ports[group] = mirror->to_local_port;
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static void rtl83xx_port_mirror_del(struct dsa_switch *ds, int port,
- struct dsa_mall_mirror_tc_entry *mirror)
-{
- int group = 0;
- struct rtl838x_switch_priv *priv = ds->priv;
- int ctrl_reg, dpm_reg, spm_reg;
-
- pr_debug("In %s\n", __func__);
- for (group = 0; group < 4; group++) {
- if (priv->mirror_group_ports[group] == mirror->to_local_port)
- break;
- }
- if (group >= 4)
- return;
-
- ctrl_reg = priv->r->mir_ctrl + group * 4;
- dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width;
- spm_reg = priv->r->mir_spm + group * 4 * priv->port_width;
-
- mutex_lock(&priv->reg_mutex);
- if (mirror->ingress) {
- /* Ingress, clear source port matrix */
- priv->r->mask_port_reg_be(1ULL << port, 0, spm_reg);
- } else {
- /* Egress, clear destination port matrix */
- priv->r->mask_port_reg_be(1ULL << port, 0, dpm_reg);
- }
-
- if (!(sw_r32(spm_reg) || sw_r32(dpm_reg))) {
- priv->mirror_group_ports[group] = -1;
- sw_w32(0, ctrl_reg);
- }
-
- mutex_unlock(&priv->reg_mutex);
-}
-
-static int rtl83xx_port_pre_bridge_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- unsigned long features = 0;
- pr_debug("%s: %d %lX\n", __func__, port, flags.val);
- if (priv->r->enable_learning)
- features |= BR_LEARNING;
- if (priv->r->enable_flood)
- features |= BR_FLOOD;
- if (priv->r->enable_mcast_flood)
- features |= BR_MCAST_FLOOD;
- if (priv->r->enable_bcast_flood)
- features |= BR_BCAST_FLOOD;
- if (flags.mask & ~(features))
- return -EINVAL;
-
- return 0;
-}
-
-static int rtl83xx_port_bridge_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
-
- pr_debug("%s: %d %lX\n", __func__, port, flags.val);
- if (priv->r->enable_learning && (flags.mask & BR_LEARNING))
- priv->r->enable_learning(port, !!(flags.val & BR_LEARNING));
-
- if (priv->r->enable_flood && (flags.mask & BR_FLOOD))
- priv->r->enable_flood(port, !!(flags.val & BR_FLOOD));
-
- if (priv->r->enable_mcast_flood && (flags.mask & BR_MCAST_FLOOD))
- priv->r->enable_mcast_flood(port, !!(flags.val & BR_MCAST_FLOOD));
-
- if (priv->r->enable_bcast_flood && (flags.mask & BR_BCAST_FLOOD))
- priv->r->enable_bcast_flood(port, !!(flags.val & BR_BCAST_FLOOD));
-
- return 0;
-}
-
-static bool rtl83xx_lag_can_offload(struct dsa_switch *ds,
- struct net_device *lag,
- struct netdev_lag_upper_info *info)
-{
- int id;
-
- id = dsa_lag_id(ds->dst, lag);
- if (id < 0 || id >= ds->num_lag_ids)
- return false;
-
- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
- return false;
- }
- if (info->hash_type != NETDEV_LAG_HASH_L2 && info->hash_type != NETDEV_LAG_HASH_L23)
- return false;
-
- return true;
-}
-
-static int rtl83xx_port_lag_change(struct dsa_switch *ds, int port)
-{
- pr_debug("%s: %d\n", __func__, port);
- /* Nothing to be done... */
-
- return 0;
-}
-
-static int rtl83xx_port_lag_join(struct dsa_switch *ds, int port,
- struct net_device *lag,
- struct netdev_lag_upper_info *info)
-{
- struct rtl838x_switch_priv *priv = ds->priv;
- int i, err = 0;
-
- if (!rtl83xx_lag_can_offload(ds, lag, info))
- return -EOPNOTSUPP;
-
- mutex_lock(&priv->reg_mutex);
-
- for (i = 0; i < priv->n_lags; i++) {
- if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == lag))
- break;
- }
- if (port >= priv->cpu_port) {
- err = -EINVAL;
- goto out;
- }
- pr_info("port_lag_join: group %d, port %d\n",i, port);
- if (!priv->lag_devs[i])
- priv->lag_devs[i] = lag;
-
- if (priv->lag_primary[i] == -1) {
- priv->lag_primary[i] = port;
- } else
- priv->is_lagmember[port] = 1;
-
- priv->lagmembers |= (1ULL << port);
-
- pr_debug("lag_members = %llX\n", priv->lagmembers);
- err = rtl83xx_lag_add(priv->ds, i, port, info);
- if (err) {
- err = -EINVAL;
- goto out;
- }
-
-out:
- mutex_unlock(&priv->reg_mutex);
-
- return err;
-}
-
-static int rtl83xx_port_lag_leave(struct dsa_switch *ds, int port,
- struct net_device *lag)
-{
- int i, group = -1, err;
- struct rtl838x_switch_priv *priv = ds->priv;
-
- mutex_lock(&priv->reg_mutex);
- for (i = 0; i < priv->n_lags; i++) {
- if (priv->lags_port_members[i] & BIT_ULL(port)) {
- group = i;
- break;
- }
- }
-
- if (group == -1) {
- pr_info("port_lag_leave: port %d is not a member\n", port);
- err = -EINVAL;
- goto out;
- }
-
- if (port >= priv->cpu_port) {
- err = -EINVAL;
- goto out;
- }
- pr_info("port_lag_del: group %d, port %d\n",group, port);
- priv->lagmembers &=~ (1ULL << port);
- priv->lag_primary[i] = -1;
- priv->is_lagmember[port] = 0;
- pr_debug("lag_members = %llX\n", priv->lagmembers);
- err = rtl83xx_lag_del(priv->ds, group, port);
- if (err) {
- err = -EINVAL;
- goto out;
- }
- if (!priv->lags_port_members[i])
- priv->lag_devs[i] = NULL;
-
-out:
- mutex_unlock(&priv->reg_mutex);
- return 0;
-}
-
-int dsa_phy_read(struct dsa_switch *ds, int phy_addr, int phy_reg)
-{
- u32 val;
- u32 offset = 0;
- struct rtl838x_switch_priv *priv = ds->priv;
-
- if ((phy_addr >= 24) &&
- (phy_addr <= 27) &&
- (priv->ports[24].phy == PHY_RTL838X_SDS)) {
- if (phy_addr == 26)
- offset = 0x100;
- val = sw_r32(RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2)) & 0xffff;
- return val;
- }
-
- read_phy(phy_addr, 0, phy_reg, &val);
- return val;
-}
-
-int dsa_phy_write(struct dsa_switch *ds, int phy_addr, int phy_reg, u16 val)
-{
- u32 offset = 0;
- struct rtl838x_switch_priv *priv = ds->priv;
-
- if ((phy_addr >= 24) &&
- (phy_addr <= 27) &&
- (priv->ports[24].phy == PHY_RTL838X_SDS)) {
- if (phy_addr == 26)
- offset = 0x100;
- sw_w32(val, RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2));
- return 0;
- }
- return write_phy(phy_addr, 0, phy_reg, val);
-}
-
-const struct dsa_switch_ops rtl83xx_switch_ops = {
- .get_tag_protocol = rtl83xx_get_tag_protocol,
- .setup = rtl83xx_setup,
-
- .phy_read = dsa_phy_read,
- .phy_write = dsa_phy_write,
-
- .phylink_validate = rtl83xx_phylink_validate,
- .phylink_mac_link_state = rtl83xx_phylink_mac_link_state,
- .phylink_mac_config = rtl83xx_phylink_mac_config,
- .phylink_mac_link_down = rtl83xx_phylink_mac_link_down,
- .phylink_mac_link_up = rtl83xx_phylink_mac_link_up,
-
- .get_strings = rtl83xx_get_strings,
- .get_ethtool_stats = rtl83xx_get_ethtool_stats,
- .get_sset_count = rtl83xx_get_sset_count,
-
- .port_enable = rtl83xx_port_enable,
- .port_disable = rtl83xx_port_disable,
-
- .get_mac_eee = rtl83xx_get_mac_eee,
- .set_mac_eee = rtl83xx_set_mac_eee,
-
- .set_ageing_time = rtl83xx_set_ageing_time,
- .port_bridge_join = rtl83xx_port_bridge_join,
- .port_bridge_leave = rtl83xx_port_bridge_leave,
- .port_stp_state_set = rtl83xx_port_stp_state_set,
- .port_fast_age = rtl83xx_fast_age,
-
- .port_vlan_filtering = rtl83xx_vlan_filtering,
- .port_vlan_add = rtl83xx_vlan_add,
- .port_vlan_del = rtl83xx_vlan_del,
-
- .port_fdb_add = rtl83xx_port_fdb_add,
- .port_fdb_del = rtl83xx_port_fdb_del,
- .port_fdb_dump = rtl83xx_port_fdb_dump,
-
- .port_mdb_add = rtl83xx_port_mdb_add,
- .port_mdb_del = rtl83xx_port_mdb_del,
-
- .port_mirror_add = rtl83xx_port_mirror_add,
- .port_mirror_del = rtl83xx_port_mirror_del,
-
- .port_lag_change = rtl83xx_port_lag_change,
- .port_lag_join = rtl83xx_port_lag_join,
- .port_lag_leave = rtl83xx_port_lag_leave,
-
- .port_pre_bridge_flags = rtl83xx_port_pre_bridge_flags,
- .port_bridge_flags = rtl83xx_port_bridge_flags,
-};
-
-const struct dsa_switch_ops rtl930x_switch_ops = {
- .get_tag_protocol = rtl83xx_get_tag_protocol,
- .setup = rtl93xx_setup,
-
- .phy_read = dsa_phy_read,
- .phy_write = dsa_phy_write,
-
- .phylink_validate = rtl93xx_phylink_validate,
- .phylink_mac_link_state = rtl93xx_phylink_mac_link_state,
- .phylink_mac_config = rtl93xx_phylink_mac_config,
- .phylink_mac_link_down = rtl93xx_phylink_mac_link_down,
- .phylink_mac_link_up = rtl93xx_phylink_mac_link_up,
-
- .get_strings = rtl83xx_get_strings,
- .get_ethtool_stats = rtl83xx_get_ethtool_stats,
- .get_sset_count = rtl83xx_get_sset_count,
-
- .port_enable = rtl83xx_port_enable,
- .port_disable = rtl83xx_port_disable,
-
- .get_mac_eee = rtl93xx_get_mac_eee,
- .set_mac_eee = rtl83xx_set_mac_eee,
-
- .set_ageing_time = rtl83xx_set_ageing_time,
- .port_bridge_join = rtl83xx_port_bridge_join,
- .port_bridge_leave = rtl83xx_port_bridge_leave,
- .port_stp_state_set = rtl83xx_port_stp_state_set,
- .port_fast_age = rtl930x_fast_age,
-
- .port_vlan_filtering = rtl83xx_vlan_filtering,
- .port_vlan_add = rtl83xx_vlan_add,
- .port_vlan_del = rtl83xx_vlan_del,
-
- .port_fdb_add = rtl83xx_port_fdb_add,
- .port_fdb_del = rtl83xx_port_fdb_del,
- .port_fdb_dump = rtl83xx_port_fdb_dump,
-
- .port_mdb_add = rtl83xx_port_mdb_add,
- .port_mdb_del = rtl83xx_port_mdb_del,
-
- .port_lag_change = rtl83xx_port_lag_change,
- .port_lag_join = rtl83xx_port_lag_join,
- .port_lag_leave = rtl83xx_port_lag_leave,
-
- .port_pre_bridge_flags = rtl83xx_port_pre_bridge_flags,
- .port_bridge_flags = rtl83xx_port_bridge_flags,
-};
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h
deleted file mode 100644
index 261af32bb4..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h
+++ /dev/null
@@ -1,1103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef _RTL838X_H
-#define _RTL838X_H
-
-#include <net/dsa.h>
-
-/* Register definition */
-#define RTL838X_MAC_PORT_CTRL(port) (0xd560 + (((port) << 7)))
-#define RTL839X_MAC_PORT_CTRL(port) (0x8004 + (((port) << 7)))
-#define RTL930X_MAC_PORT_CTRL(port) (0x3260 + (((port) << 6)))
-#define RTL931X_MAC_PORT_CTRL (0x6004)
-
-#define RTL930X_MAC_L2_PORT_CTRL(port) (0x3268 + (((port) << 6)))
-#define RTL931X_MAC_L2_PORT_CTRL (0x6000)
-
-#define RTL838X_RST_GLB_CTRL_0 (0x003c)
-
-#define RTL838X_MAC_FORCE_MODE_CTRL (0xa104)
-#define RTL839X_MAC_FORCE_MODE_CTRL (0x02bc)
-#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C)
-#define RTL931X_MAC_FORCE_MODE_CTRL (0x0DCC)
-
-#define RTL838X_DMY_REG31 (0x3b28)
-#define RTL838X_SDS_MODE_SEL (0x0028)
-#define RTL838X_SDS_CFG_REG (0x0034)
-#define RTL838X_INT_MODE_CTRL (0x005c)
-#define RTL838X_CHIP_INFO (0x00d8)
-#define RTL839X_CHIP_INFO (0x0ff4)
-#define RTL838X_PORT_ISO_CTRL(port) (0x4100 + ((port) << 2))
-#define RTL839X_PORT_ISO_CTRL(port) (0x1400 + ((port) << 3))
-
-/* Packet statistics */
-#define RTL838X_STAT_PORT_STD_MIB (0x1200)
-#define RTL839X_STAT_PORT_STD_MIB (0xC000)
-#define RTL930X_STAT_PORT_MIB_CNTR (0x0664)
-#define RTL838X_STAT_RST (0x3100)
-#define RTL839X_STAT_RST (0xF504)
-#define RTL930X_STAT_RST (0x3240)
-#define RTL931X_STAT_RST (0x7ef4)
-#define RTL838X_STAT_PORT_RST (0x3104)
-#define RTL839X_STAT_PORT_RST (0xF508)
-#define RTL930X_STAT_PORT_RST (0x3244)
-#define RTL931X_STAT_PORT_RST (0x7ef8)
-#define RTL838X_STAT_CTRL (0x3108)
-#define RTL839X_STAT_CTRL (0x04cc)
-#define RTL930X_STAT_CTRL (0x3248)
-#define RTL931X_STAT_CTRL (0x5720)
-
-/* Registers of the internal Serdes of the 8390 */
-#define RTL8390_SDS0_1_XSG0 (0xA000)
-#define RTL8390_SDS0_1_XSG1 (0xA100)
-#define RTL839X_SDS12_13_XSG0 (0xB800)
-#define RTL839X_SDS12_13_XSG1 (0xB900)
-#define RTL839X_SDS12_13_PWR0 (0xb880)
-#define RTL839X_SDS12_13_PWR1 (0xb980)
-
-/* Registers of the internal Serdes of the 8380 */
-#define RTL838X_SDS4_FIB_REG0 (0xF800)
-#define RTL838X_SDS4_REG28 (0xef80)
-#define RTL838X_SDS4_DUMMY0 (0xef8c)
-#define RTL838X_SDS5_EXT_REG6 (0xf18c)
-
-/* VLAN registers */
-#define RTL838X_VLAN_CTRL (0x3A74)
-#define RTL838X_VLAN_PROFILE(idx) (0x3A88 + ((idx) << 2))
-#define RTL838X_VLAN_PORT_EGR_FLTR (0x3A84)
-#define RTL838X_VLAN_PORT_PB_VLAN (0x3C00)
-#define RTL838X_VLAN_PORT_IGR_FLTR (0x3A7C)
-
-#define RTL839X_VLAN_PROFILE(idx) (0x25C0 + (((idx) << 3)))
-#define RTL839X_VLAN_CTRL (0x26D4)
-#define RTL839X_VLAN_PORT_PB_VLAN (0x26D8)
-#define RTL839X_VLAN_PORT_IGR_FLTR (0x27B4)
-#define RTL839X_VLAN_PORT_EGR_FLTR (0x27C4)
-
-#define RTL930X_VLAN_PROFILE_SET(idx) (0x9c60 + (((idx) * 20)))
-#define RTL930X_VLAN_CTRL (0x82D4)
-#define RTL930X_VLAN_PORT_PB_VLAN (0x82D8)
-#define RTL930X_VLAN_PORT_IGR_FLTR (0x83C0)
-#define RTL930X_VLAN_PORT_EGR_FLTR (0x83C8)
-
-#define RTL931X_VLAN_PROFILE_SET(idx) (0x9800 + (((idx) * 28)))
-#define RTL931X_VLAN_CTRL (0x94E4)
-#define RTL931X_VLAN_PORT_IGR_CTRL (0x94E8)
-#define RTL931X_VLAN_PORT_IGR_FLTR (0x96B4)
-#define RTL931X_VLAN_PORT_EGR_FLTR (0x96C4)
-
-/* Table access registers */
-#define RTL838X_TBL_ACCESS_CTRL_0 (0x6914)
-#define RTL838X_TBL_ACCESS_DATA_0(idx) (0x6918 + ((idx) << 2))
-#define RTL838X_TBL_ACCESS_CTRL_1 (0xA4C8)
-#define RTL838X_TBL_ACCESS_DATA_1(idx) (0xA4CC + ((idx) << 2))
-
-#define RTL839X_TBL_ACCESS_CTRL_0 (0x1190)
-#define RTL839X_TBL_ACCESS_DATA_0(idx) (0x1194 + ((idx) << 2))
-#define RTL839X_TBL_ACCESS_CTRL_1 (0x6b80)
-#define RTL839X_TBL_ACCESS_DATA_1(idx) (0x6b84 + ((idx) << 2))
-#define RTL839X_TBL_ACCESS_CTRL_2 (0x611C)
-#define RTL839X_TBL_ACCESS_DATA_2(i) (0x6120 + (((i) << 2)))
-
-#define RTL930X_TBL_ACCESS_CTRL_0 (0xB340)
-#define RTL930X_TBL_ACCESS_DATA_0(idx) (0xB344 + ((idx) << 2))
-#define RTL930X_TBL_ACCESS_CTRL_1 (0xB3A0)
-#define RTL930X_TBL_ACCESS_DATA_1(idx) (0xB3A4 + ((idx) << 2))
-#define RTL930X_TBL_ACCESS_CTRL_2 (0xCE04)
-#define RTL930X_TBL_ACCESS_DATA_2(i) (0xCE08 + (((i) << 2)))
-
-#define RTL931X_TBL_ACCESS_CTRL_0 (0x8500)
-#define RTL931X_TBL_ACCESS_DATA_0(idx) (0x8508 + ((idx) << 2))
-#define RTL931X_TBL_ACCESS_CTRL_1 (0x40C0)
-#define RTL931X_TBL_ACCESS_DATA_1(idx) (0x40C4 + ((idx) << 2))
-#define RTL931X_TBL_ACCESS_CTRL_2 (0x8528)
-#define RTL931X_TBL_ACCESS_DATA_2(i) (0x852C + (((i) << 2)))
-#define RTL931X_TBL_ACCESS_CTRL_3 (0x0200)
-#define RTL931X_TBL_ACCESS_DATA_3(i) (0x0204 + (((i) << 2)))
-#define RTL931X_TBL_ACCESS_CTRL_4 (0x20DC)
-#define RTL931X_TBL_ACCESS_DATA_4(i) (0x20E0 + (((i) << 2)))
-#define RTL931X_TBL_ACCESS_CTRL_5 (0x7E1C)
-#define RTL931X_TBL_ACCESS_DATA_5(i) (0x7E20 + (((i) << 2)))
-
-/* MAC handling */
-#define RTL838X_MAC_LINK_STS (0xa188)
-#define RTL839X_MAC_LINK_STS (0x0390)
-#define RTL930X_MAC_LINK_STS (0xCB10)
-#define RTL931X_MAC_LINK_STS (0x0EC0)
-#define RTL838X_MAC_LINK_SPD_STS(p) (0xa190 + (((p >> 4) << 2)))
-#define RTL839X_MAC_LINK_SPD_STS(p) (0x03a0 + (((p >> 4) << 2)))
-#define RTL930X_MAC_LINK_SPD_STS(p) (0xCB18 + (((p >> 3) << 2)))
-#define RTL931X_MAC_LINK_SPD_STS (0x0ED0)
-#define RTL838X_MAC_LINK_DUP_STS (0xa19c)
-#define RTL839X_MAC_LINK_DUP_STS (0x03b0)
-#define RTL930X_MAC_LINK_DUP_STS (0xCB28)
-#define RTL931X_MAC_LINK_DUP_STS (0x0EF0)
-#define RTL838X_MAC_TX_PAUSE_STS (0xa1a0)
-#define RTL839X_MAC_TX_PAUSE_STS (0x03b8)
-#define RTL930X_MAC_TX_PAUSE_STS (0xCB2C)
-#define RTL931X_MAC_TX_PAUSE_STS (0x0EF8)
-#define RTL838X_MAC_RX_PAUSE_STS (0xa1a4)
-#define RTL839X_MAC_RX_PAUSE_STS (0x03c0)
-#define RTL930X_MAC_RX_PAUSE_STS (0xCB30)
-#define RTL931X_MAC_RX_PAUSE_STS (0x0F00)
-#define RTL930X_MAC_LINK_MEDIA_STS (0xCB14)
-#define RTL931X_MAC_LINK_MEDIA_STS (0x0EC8)
-
-/* MAC link state bits */
-#define RTL838X_FORCE_EN (1 << 0)
-#define RTL838X_FORCE_LINK_EN (1 << 1)
-#define RTL838X_NWAY_EN (1 << 2)
-#define RTL838X_DUPLEX_MODE (1 << 3)
-#define RTL838X_TX_PAUSE_EN (1 << 6)
-#define RTL838X_RX_PAUSE_EN (1 << 7)
-#define RTL838X_MAC_FORCE_FC_EN (1 << 8)
-
-#define RTL839X_FORCE_EN (1 << 0)
-#define RTL839X_FORCE_LINK_EN (1 << 1)
-#define RTL839X_DUPLEX_MODE (1 << 2)
-#define RTL839X_TX_PAUSE_EN (1 << 5)
-#define RTL839X_RX_PAUSE_EN (1 << 6)
-#define RTL839X_MAC_FORCE_FC_EN (1 << 7)
-
-#define RTL930X_FORCE_EN (1 << 0)
-#define RTL930X_FORCE_LINK_EN (1 << 1)
-#define RTL930X_DUPLEX_MODE (1 << 2)
-#define RTL930X_TX_PAUSE_EN (1 << 7)
-#define RTL930X_RX_PAUSE_EN (1 << 8)
-#define RTL930X_MAC_FORCE_FC_EN (1 << 9)
-
-#define RTL931X_FORCE_EN (1 << 9)
-#define RTL931X_FORCE_LINK_EN (1 << 0)
-#define RTL931X_DUPLEX_MODE (1 << 2)
-#define RTL931X_MAC_FORCE_FC_EN (1 << 4)
-#define RTL931X_TX_PAUSE_EN (1 << 16)
-#define RTL931X_RX_PAUSE_EN (1 << 17)
-
-/* EEE */
-#define RTL838X_MAC_EEE_ABLTY (0xa1a8)
-#define RTL838X_EEE_PORT_TX_EN (0x014c)
-#define RTL838X_EEE_PORT_RX_EN (0x0150)
-#define RTL838X_EEE_CLK_STOP_CTRL (0x0148)
-#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04)
-#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08)
-
-#define RTL839X_EEE_TX_TIMER_GELITE_CTRL (0x042C)
-#define RTL839X_EEE_TX_TIMER_GIGA_CTRL (0x0430)
-#define RTL839X_EEE_TX_TIMER_10G_CTRL (0x0434)
-#define RTL839X_EEE_CTRL(p) (0x8008 + ((p) << 7))
-#define RTL839X_MAC_EEE_ABLTY (0x03C8)
-
-#define RTL930X_MAC_EEE_ABLTY (0xCB34)
-#define RTL930X_EEE_CTRL(p) (0x3274 + ((p) << 6))
-#define RTL930X_EEEP_PORT_CTRL(p) (0x3278 + ((p) << 6))
-
-/* L2 functionality */
-#define RTL838X_L2_CTRL_0 (0x3200)
-#define RTL839X_L2_CTRL_0 (0x3800)
-#define RTL930X_L2_CTRL (0x8FD8)
-#define RTL931X_L2_CTRL (0xC800)
-#define RTL838X_L2_CTRL_1 (0x3204)
-#define RTL839X_L2_CTRL_1 (0x3804)
-#define RTL930X_L2_AGE_CTRL (0x8FDC)
-#define RTL931X_L2_AGE_CTRL (0xC804)
-#define RTL838X_L2_PORT_AGING_OUT (0x3358)
-#define RTL839X_L2_PORT_AGING_OUT (0x3b74)
-#define RTL930X_L2_PORT_AGE_CTRL (0x8FE0)
-#define RTL931X_L2_PORT_AGE_CTRL (0xc808)
-#define RTL838X_TBL_ACCESS_L2_CTRL (0x6900)
-#define RTL839X_TBL_ACCESS_L2_CTRL (0x1180)
-#define RTL930X_TBL_ACCESS_L2_CTRL (0xB320)
-#define RTL930X_TBL_ACCESS_L2_METHOD_CTRL (0xB324)
-#define RTL838X_TBL_ACCESS_L2_DATA(idx) (0x6908 + ((idx) << 2))
-#define RTL839X_TBL_ACCESS_L2_DATA(idx) (0x1184 + ((idx) << 2))
-#define RTL930X_TBL_ACCESS_L2_DATA(idx) (0xab08 + ((idx) << 2))
-
-#define RTL838X_L2_TBL_FLUSH_CTRL (0x3370)
-#define RTL839X_L2_TBL_FLUSH_CTRL (0x3ba0)
-#define RTL930X_L2_TBL_FLUSH_CTRL (0x9404)
-#define RTL931X_L2_TBL_FLUSH_CTRL (0xCD9C)
-
-#define RTL838X_L2_LRN_CONSTRT (0x329C)
-#define RTL839X_L2_LRN_CONSTRT (0x3910)
-#define RTL930X_L2_LRN_CONSTRT_CTRL (0x909c)
-#define RTL931X_L2_LRN_CONSTRT_CTRL (0xC964)
-
-#define RTL838X_L2_FLD_PMSK (0x3288)
-#define RTL839X_L2_FLD_PMSK (0x38EC)
-#define RTL930X_L2_BC_FLD_PMSK (0x9068)
-#define RTL931X_L2_BC_FLD_PMSK (0xC8FC)
-
-#define RTL930X_L2_UNKN_UC_FLD_PMSK (0x9064)
-#define RTL931X_L2_UNKN_UC_FLD_PMSK (0xC8F4)
-
-#define RTL838X_L2_LRN_CONSTRT_EN (0x3368)
-#define RTL838X_L2_PORT_LRN_CONSTRT (0x32A0)
-#define RTL839X_L2_PORT_LRN_CONSTRT (0x3914)
-
-#define RTL838X_L2_PORT_NEW_SALRN(p) (0x328c + (((p >> 4) << 2)))
-#define RTL839X_L2_PORT_NEW_SALRN(p) (0x38F0 + (((p >> 4) << 2)))
-#define RTL930X_L2_PORT_SALRN(p) (0x8FEC + (((p >> 4) << 2)))
-#define RTL931X_L2_PORT_NEW_SALRN(p) (0xC820 + (((p >> 4) << 2)))
-
-#define SALRN_PORT_SHIFT(p) ((p % 16) * 2)
-#define SALRN_MODE_MASK 0x3
-#define SALRN_MODE_HARDWARE 0
-#define SALRN_MODE_DISABLED 2
-
-#define RTL838X_L2_PORT_NEW_SA_FWD(p) (0x3294 + (((p >> 4) << 2)))
-#define RTL839X_L2_PORT_NEW_SA_FWD(p) (0x3900 + (((p >> 4) << 2)))
-#define RTL930X_L2_PORT_NEW_SA_FWD(p) (0x8FF4 + (((p / 10) << 2)))
-#define RTL931X_L2_PORT_NEW_SA_FWD(p) (0xC830 + (((p / 10) << 2)))
-
-#define RTL838X_L2_PORT_MV_ACT(p) (0x335c + (((p >> 4) << 2)))
-#define RTL839X_L2_PORT_MV_ACT(p) (0x3b80 + (((p >> 4) << 2)))
-
-#define RTL838X_L2_PORT_STATIC_MV_ACT(p) (0x327c + (((p >> 4) << 2)))
-#define RTL839X_L2_PORT_STATIC_MV_ACT(p) (0x38dc + (((p >> 4) << 2)))
-
-#define MV_ACT_PORT_SHIFT(p) ((p % 16) * 2)
-#define MV_ACT_MASK 0x3
-#define MV_ACT_FORWARD 0
-#define MV_ACT_DROP 1
-#define MV_ACT_TRAP2CPU 2
-#define MV_ACT_COPY2CPU 3
-
-#define RTL930X_ST_CTRL (0x8798)
-
-#define RTL930X_L2_PORT_SABLK_CTRL (0x905c)
-#define RTL930X_L2_PORT_DABLK_CTRL (0x9060)
-
-#define RTL838X_L2_PORT_LM_ACT(p) (0x3208 + ((p) << 2))
-#define RTL838X_VLAN_PORT_FWD (0x3A78)
-#define RTL839X_VLAN_PORT_FWD (0x27AC)
-#define RTL930X_VLAN_PORT_FWD (0x834C)
-#define RTL931X_VLAN_PORT_FWD (0x95CC)
-#define RTL838X_VLAN_FID_CTRL (0x3aa8)
-
-/* Port Mirroring */
-#define RTL838X_MIR_CTRL (0x5D00)
-#define RTL838X_MIR_DPM_CTRL (0x5D20)
-#define RTL838X_MIR_SPM_CTRL (0x5D10)
-
-#define RTL839X_MIR_CTRL (0x2500)
-#define RTL839X_MIR_DPM_CTRL (0x2530)
-#define RTL839X_MIR_SPM_CTRL (0x2510)
-
-#define RTL930X_MIR_CTRL (0xA2A0)
-#define RTL930X_MIR_DPM_CTRL (0xA2C0)
-#define RTL930X_MIR_SPM_CTRL (0xA2B0)
-
-#define RTL931X_MIR_CTRL (0xAF00)
-#define RTL931X_MIR_DPM_CTRL (0xAF30)
-#define RTL931X_MIR_SPM_CTRL (0xAF10)
-
-/* Storm/rate control and scheduling */
-#define RTL838X_STORM_CTRL (0x4700)
-#define RTL839X_STORM_CTRL (0x1800)
-#define RTL838X_STORM_CTRL_LB_CTRL(p) (0x4884 + (((p) << 2)))
-#define RTL838X_STORM_CTRL_BURST_PPS_0 (0x4874)
-#define RTL838X_STORM_CTRL_BURST_PPS_1 (0x4878)
-#define RTL838X_STORM_CTRL_BURST_0 (0x487c)
-#define RTL838X_STORM_CTRL_BURST_1 (0x4880)
-#define RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_0 (0x1804)
-#define RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_1 (0x1808)
-#define RTL838X_SCHED_CTRL (0xB980)
-#define RTL839X_SCHED_CTRL (0x60F4)
-#define RTL838X_SCHED_LB_TICK_TKN_CTRL_0 (0xAD58)
-#define RTL838X_SCHED_LB_TICK_TKN_CTRL_1 (0xAD5C)
-#define RTL839X_SCHED_LB_TICK_TKN_CTRL_0 (0x1804)
-#define RTL839X_SCHED_LB_TICK_TKN_CTRL_1 (0x1808)
-#define RTL839X_STORM_CTRL_SPCL_LB_TICK_TKN_CTRL (0x2000)
-#define RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_0 (0x1604)
-#define RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_1 (0x1608)
-#define RTL839X_SCHED_LB_TICK_TKN_CTRL (0x60F8)
-#define RTL839X_SCHED_LB_TICK_TKN_PPS_CTRL (0x6200)
-#define RTL838X_SCHED_LB_THR (0xB984)
-#define RTL839X_SCHED_LB_THR (0x60FC)
-#define RTL838X_SCHED_P_EGR_RATE_CTRL(p) (0xC008 + (((p) << 7)))
-#define RTL838X_SCHED_Q_EGR_RATE_CTRL(p, q) (0xC00C + (p << 7) + (((q) << 2)))
-#define RTL838X_STORM_CTRL_PORT_BC_EXCEED (0x470C)
-#define RTL838X_STORM_CTRL_PORT_MC_EXCEED (0x4710)
-#define RTL838X_STORM_CTRL_PORT_UC_EXCEED (0x4714)
-#define RTL839X_STORM_CTRL_PORT_BC_EXCEED(p) (0x180c + (((p >> 5) << 2)))
-#define RTL839X_STORM_CTRL_PORT_MC_EXCEED(p) (0x1814 + (((p >> 5) << 2)))
-#define RTL839X_STORM_CTRL_PORT_UC_EXCEED(p) (0x181c + (((p >> 5) << 2)))
-#define RTL838X_STORM_CTRL_PORT_UC(p) (0x4718 + (((p) << 2)))
-#define RTL838X_STORM_CTRL_PORT_MC(p) (0x478c + (((p) << 2)))
-#define RTL838X_STORM_CTRL_PORT_BC(p) (0x4800 + (((p) << 2)))
-#define RTL839X_STORM_CTRL_PORT_UC_0(p) (0x185C + (((p) << 3)))
-#define RTL839X_STORM_CTRL_PORT_UC_1(p) (0x1860 + (((p) << 3)))
-#define RTL839X_STORM_CTRL_PORT_MC_0(p) (0x19FC + (((p) << 3)))
-#define RTL839X_STORM_CTRL_PORT_MC_1(p) (0x1a00 + (((p) << 3)))
-#define RTL839X_STORM_CTRL_PORT_BC_0(p) (0x1B9C + (((p) << 3)))
-#define RTL839X_STORM_CTRL_PORT_BC_1(p) (0x1BA0 + (((p) << 3)))
-#define RTL839X_TBL_ACCESS_CTRL_2 (0x611C)
-#define RTL839X_TBL_ACCESS_DATA_2(i) (0x6120 + (((i) << 2)))
-#define RTL839X_IGR_BWCTRL_PORT_CTRL_10G_0(p) (0x1618 + (((p) << 3)))
-#define RTL839X_IGR_BWCTRL_PORT_CTRL_10G_1(p) (0x161C + (((p) << 3)))
-#define RTL839X_IGR_BWCTRL_PORT_CTRL_0(p) (0x1640 + (((p) << 3)))
-#define RTL839X_IGR_BWCTRL_PORT_CTRL_1(p) (0x1644 + (((p) << 3)))
-#define RTL839X_IGR_BWCTRL_CTRL_LB_THR (0x1614)
-
-/* Link aggregation (Trunking) */
-#define TRUNK_DISTRIBUTION_ALGO_SPA_BIT 0x01
-#define TRUNK_DISTRIBUTION_ALGO_SMAC_BIT 0x02
-#define TRUNK_DISTRIBUTION_ALGO_DMAC_BIT 0x04
-#define TRUNK_DISTRIBUTION_ALGO_SIP_BIT 0x08
-#define TRUNK_DISTRIBUTION_ALGO_DIP_BIT 0x10
-#define TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT 0x20
-#define TRUNK_DISTRIBUTION_ALGO_DST_L4PORT_BIT 0x40
-#define TRUNK_DISTRIBUTION_ALGO_MASKALL 0x7F
-
-#define TRUNK_DISTRIBUTION_ALGO_L2_SPA_BIT 0x01
-#define TRUNK_DISTRIBUTION_ALGO_L2_SMAC_BIT 0x02
-#define TRUNK_DISTRIBUTION_ALGO_L2_DMAC_BIT 0x04
-#define TRUNK_DISTRIBUTION_ALGO_L2_VLAN_BIT 0x08
-#define TRUNK_DISTRIBUTION_ALGO_L2_MASKALL 0xF
-
-#define TRUNK_DISTRIBUTION_ALGO_L3_SPA_BIT 0x01
-#define TRUNK_DISTRIBUTION_ALGO_L3_SMAC_BIT 0x02
-#define TRUNK_DISTRIBUTION_ALGO_L3_DMAC_BIT 0x04
-#define TRUNK_DISTRIBUTION_ALGO_L3_VLAN_BIT 0x08
-#define TRUNK_DISTRIBUTION_ALGO_L3_SIP_BIT 0x10
-#define TRUNK_DISTRIBUTION_ALGO_L3_DIP_BIT 0x20
-#define TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT 0x40
-#define TRUNK_DISTRIBUTION_ALGO_L3_DST_L4PORT_BIT 0x80
-#define TRUNK_DISTRIBUTION_ALGO_L3_PROTO_BIT 0x100
-#define TRUNK_DISTRIBUTION_ALGO_L3_FLOW_LABEL_BIT 0x200
-#define TRUNK_DISTRIBUTION_ALGO_L3_MASKALL 0x3FF
-
-#define RTL838X_TRK_MBR_CTR (0x3E00)
-#define RTL838X_TRK_HASH_IDX_CTRL (0x3E20)
-#define RTL838X_TRK_HASH_CTRL (0x3E24)
-
-#define RTL839X_TRK_MBR_CTR (0x2200)
-#define RTL839X_TRK_HASH_IDX_CTRL (0x2280)
-#define RTL839X_TRK_HASH_CTRL (0x2284)
-
-#define RTL930X_TRK_MBR_CTRL (0xA41C)
-#define RTL930X_TRK_HASH_CTRL (0x9F80)
-
-#define RTL931X_TRK_MBR_CTRL (0xB8D0)
-#define RTL931X_TRK_HASH_CTRL (0xBA70)
-
-/* Attack prevention */
-#define RTL838X_ATK_PRVNT_PORT_EN (0x5B00)
-#define RTL838X_ATK_PRVNT_CTRL (0x5B04)
-#define RTL838X_ATK_PRVNT_ACT (0x5B08)
-#define RTL838X_ATK_PRVNT_STS (0x5B1C)
-
-/* 802.1X */
-#define RTL838X_RMA_BPDU_FLD_PMSK (0x4348)
-#define RTL930X_RMA_BPDU_FLD_PMSK (0x9F18)
-#define RTL931X_RMA_BPDU_FLD_PMSK (0x8950)
-#define RTL839X_RMA_BPDU_FLD_PMSK (0x125C)
-
-#define RTL838X_SPCL_TRAP_CTRL (0x6980)
-#define RTL838X_SPCL_TRAP_EAPOL_CTRL (0x6988)
-#define RTL838X_SPCL_TRAP_ARP_CTRL (0x698C)
-#define RTL838X_SPCL_TRAP_IGMP_CTRL (0x6984)
-#define RTL838X_SPCL_TRAP_IPV6_CTRL (0x6994)
-#define RTL838X_SPCL_TRAP_SWITCH_MAC_CTRL (0x6998)
-
-#define RTL839X_SPCL_TRAP_CTRL (0x1054)
-#define RTL839X_SPCL_TRAP_EAPOL_CTRL (0x105C)
-#define RTL839X_SPCL_TRAP_ARP_CTRL (0x1060)
-#define RTL839X_SPCL_TRAP_IGMP_CTRL (0x1058)
-#define RTL839X_SPCL_TRAP_IPV6_CTRL (0x1064)
-#define RTL839X_SPCL_TRAP_SWITCH_MAC_CTRL (0x1068)
-#define RTL839X_SPCL_TRAP_SWITCH_IPV4_ADDR_CTRL (0x106C)
-#define RTL839X_SPCL_TRAP_CRC_CTRL (0x1070)
-/* special port action controls */
-/* values:
- * 0 = FORWARD (default)
- * 1 = DROP
- * 2 = TRAP2CPU
- * 3 = FLOOD IN ALL PORT
- *
- * Register encoding.
- * offset = CTRL + (port >> 4) << 2
- * value/mask = 3 << ((port & 0xF) << 1)
- */
-
-typedef enum {
- BPDU = 0,
- PTP,
- PTP_UDP,
- PTP_ETH2,
- LLDP,
- EAPOL,
- GRATARP,
-} rma_ctrl_t;
-
-typedef enum {
- FORWARD = 0,
- DROP,
- TRAP2CPU,
- FLOODALL,
- TRAP2MASTERCPU,
- COPY2CPU,
-} action_type_t;
-
-#define RTL838X_RMA_BPDU_CTRL (0x4330)
-#define RTL839X_RMA_BPDU_CTRL (0x122C)
-#define RTL930X_RMA_BPDU_CTRL (0x9E7C)
-#define RTL931X_RMA_BPDU_CTRL (0x881C)
-
-#define RTL838X_RMA_PTP_CTRL (0x4338)
-#define RTL839X_RMA_PTP_CTRL (0x123C)
-#define RTL930X_RMA_PTP_CTRL (0x9E88)
-#define RTL931X_RMA_PTP_CTRL (0x8834)
-
-#define RTL838X_RMA_LLDP_CTRL (0x4340)
-#define RTL839X_RMA_LLDP_CTRL (0x124C)
-#define RTL930X_RMA_LLDP_CTRL (0x9EFC)
-#define RTL931X_RMA_LLDP_CTRL (0x8918)
-
-#define RTL930X_RMA_EAPOL_CTRL (0x9F08)
-#define RTL931X_RMA_EAPOL_CTRL (0x8930)
-#define RTL931X_TRAP_ARP_GRAT_PORT_ACT (0x8C04)
-
-/* QoS */
-#define RTL838X_QM_INTPRI2QID_CTRL (0x5F00)
-#define RTL839X_QM_INTPRI2QID_CTRL(q) (0x1110 + (q << 2))
-#define RTL839X_QM_PORT_QNUM(p) (0x1130 + (((p / 10) << 2)))
-#define RTL838X_PRI_SEL_PORT_PRI(p) (0x5FB8 + (((p / 10) << 2)))
-#define RTL839X_PRI_SEL_PORT_PRI(p) (0x10A8 + (((p / 10) << 2)))
-#define RTL838X_QM_PKT2CPU_INTPRI_MAP (0x5F10)
-#define RTL839X_QM_PKT2CPU_INTPRI_MAP (0x1154)
-#define RTL838X_PRI_SEL_CTRL (0x10E0)
-#define RTL839X_PRI_SEL_CTRL (0x10E0)
-#define RTL838X_PRI_SEL_TBL_CTRL(i) (0x5FD8 + (((i) << 2)))
-#define RTL839X_PRI_SEL_TBL_CTRL(i) (0x10D0 + (((i) << 2)))
-#define RTL838X_QM_PKT2CPU_INTPRI_0 (0x5F04)
-#define RTL838X_QM_PKT2CPU_INTPRI_1 (0x5F08)
-#define RTL838X_QM_PKT2CPU_INTPRI_2 (0x5F0C)
-#define RTL839X_OAM_CTRL (0x2100)
-#define RTL839X_OAM_PORT_ACT_CTRL(p) (0x2104 + (((p) << 2)))
-#define RTL839X_RMK_PORT_DEI_TAG_CTRL(p) (0x6A9C + (((p >> 5) << 2)))
-#define RTL839X_PRI_SEL_IPRI_REMAP (0x1080)
-#define RTL838X_PRI_SEL_IPRI_REMAP (0x5F8C)
-#define RTL839X_PRI_SEL_DEI2DP_REMAP (0x10EC)
-#define RTL839X_PRI_SEL_DSCP2DP_REMAP_ADDR(i) (0x10F0 + (((i >> 4) << 2)))
-#define RTL839X_RMK_DEI_CTRL (0x6AA4)
-#define RTL839X_WRED_PORT_THR_CTRL(i) (0x6084 + ((i) << 2))
-#define RTL839X_WRED_QUEUE_THR_CTRL(q, i) (0x6090 + ((q) * 12) + ((i) << 2))
-#define RTL838X_PRI_DSCP_INVLD_CTRL0 (0x5FE8)
-#define RTL838X_RMK_IPRI_CTRL (0xA460)
-#define RTL838X_RMK_OPRI_CTRL (0xA464)
-#define RTL838X_SCHED_P_TYPE_CTRL(p) (0xC04C + (((p) << 7)))
-#define RTL838X_SCHED_LB_CTRL(p) (0xC004 + (((p) << 7)))
-#define RTL838X_FC_P_EGR_DROP_CTRL(p) (0x6B1C + (((p) << 2)))
-
-/* Debug features */
-#define RTL930X_STAT_PRVTE_DROP_COUNTER0 (0xB5B8)
-
-/* Packet Inspection Engine */
-#define RTL838X_METER_GLB_CTRL (0x4B08)
-#define RTL839X_METER_GLB_CTRL (0x1300)
-#define RTL930X_METER_GLB_CTRL (0xa0a0)
-#define RTL931X_METER_GLB_CTRL (0x411C)
-
-#define RTL839X_ACL_CTRL (0x1288)
-
-#define RTL838X_ACL_BLK_LOOKUP_CTRL (0x6100)
-#define RTL839X_ACL_BLK_LOOKUP_CTRL (0x1280)
-#define RTL930X_PIE_BLK_LOOKUP_CTRL (0xa5a0)
-#define RTL931X_PIE_BLK_LOOKUP_CTRL (0x4180)
-
-#define RTL838X_ACL_BLK_PWR_CTRL (0x6104)
-#define RTL839X_PS_ACL_PWR_CTRL (0x049c)
-
-#define RTL838X_ACL_BLK_TMPLTE_CTRL(block) (0x6108 + ((block) << 2))
-#define RTL839X_ACL_BLK_TMPLTE_CTRL(block) (0x128c + ((block) << 2))
-#define RTL930X_PIE_BLK_TMPLTE_CTRL(block) (0xa624 + ((block) << 2))
-#define RTL931X_PIE_BLK_TMPLTE_CTRL(block) (0x4214 + ((block) << 2))
-
-#define RTL838X_ACL_BLK_GROUP_CTRL (0x615C)
-#define RTL839X_ACL_BLK_GROUP_CTRL (0x12ec)
-
-#define RTL838X_ACL_CLR_CTRL (0x6168)
-#define RTL839X_ACL_CLR_CTRL (0x12fc)
-#define RTL930X_PIE_CLR_CTRL (0xa66c)
-#define RTL931X_PIE_CLR_CTRL (0x42D8)
-
-#define RTL838X_DMY_REG27 (0x3378)
-
-#define RTL838X_ACL_PORT_LOOKUP_CTRL(p) (0x616C + (((p) << 2)))
-#define RTL930X_ACL_PORT_LOOKUP_CTRL(p) (0xA784 + (((p) << 2)))
-#define RTL931X_ACL_PORT_LOOKUP_CTRL(p) (0x44F8 + (((p) << 2)))
-
-#define RTL930X_PIE_BLK_PHASE_CTRL (0xA5A4)
-#define RTL931X_PIE_BLK_PHASE_CTRL (0x4184)
-
-/* PIE actions */
-#define PIE_ACT_COPY_TO_PORT 2
-#define PIE_ACT_REDIRECT_TO_PORT 4
-#define PIE_ACT_ROUTE_UC 6
-#define PIE_ACT_VID_ASSIGN 0
-
-/* L3 actions */
-#define L3_FORWARD 0
-#define L3_DROP 1
-#define L3_TRAP2CPU 2
-#define L3_COPY2CPU 3
-#define L3_TRAP2MASTERCPU 4
-#define L3_COPY2MASTERCPU 5
-#define L3_HARDDROP 6
-
-/* Route actions */
-#define ROUTE_ACT_FORWARD 0
-#define ROUTE_ACT_TRAP2CPU 1
-#define ROUTE_ACT_COPY2CPU 2
-#define ROUTE_ACT_DROP 3
-
-/* L3 Routing */
-#define RTL839X_ROUTING_SA_CTRL 0x6afc
-#define RTL930X_L3_HOST_TBL_CTRL (0xAB48)
-#define RTL930X_L3_IPUC_ROUTE_CTRL (0xAB4C)
-#define RTL930X_L3_IP6UC_ROUTE_CTRL (0xAB50)
-#define RTL930X_L3_IPMC_ROUTE_CTRL (0xAB54)
-#define RTL930X_L3_IP6MC_ROUTE_CTRL (0xAB58)
-#define RTL930X_L3_IP_MTU_CTRL(i) (0xAB5C + ((i >> 1) << 2))
-#define RTL930X_L3_IP6_MTU_CTRL(i) (0xAB6C + ((i >> 1) << 2))
-#define RTL930X_L3_HW_LU_KEY_CTRL (0xAC9C)
-#define RTL930X_L3_HW_LU_KEY_IP_CTRL (0xACA0)
-#define RTL930X_L3_HW_LU_CTRL (0xACC0)
-#define RTL930X_L3_IP_ROUTE_CTRL 0xab44
-
-/* Port LED Control */
-#define RTL930X_LED_PORT_NUM_CTRL(p) (0xCC04 + (((p >> 4) << 2)))
-#define RTL930X_LED_SET0_0_CTRL (0xCC28)
-#define RTL930X_LED_PORT_COPR_SET_SEL_CTRL(p) (0xCC2C + (((p >> 4) << 2)))
-#define RTL930X_LED_PORT_FIB_SET_SEL_CTRL(p) (0xCC34 + (((p >> 4) << 2)))
-#define RTL930X_LED_PORT_COPR_MASK_CTRL (0xCC3C)
-#define RTL930X_LED_PORT_FIB_MASK_CTRL (0xCC40)
-#define RTL930X_LED_PORT_COMBO_MASK_CTRL (0xCC44)
-
-#define RTL931X_LED_PORT_NUM_CTRL(p) (0x0604 + (((p >> 4) << 2)))
-#define RTL931X_LED_SET0_0_CTRL (0x0630)
-#define RTL931X_LED_PORT_COPR_SET_SEL_CTRL(p) (0x0634 + (((p >> 4) << 2)))
-#define RTL931X_LED_PORT_FIB_SET_SEL_CTRL(p) (0x0644 + (((p >> 4) << 2)))
-#define RTL931X_LED_PORT_COPR_MASK_CTRL (0x0654)
-#define RTL931X_LED_PORT_FIB_MASK_CTRL (0x065c)
-#define RTL931X_LED_PORT_COMBO_MASK_CTRL (0x0664)
-
-#define MAX_VLANS 4096
-#define MAX_LAGS 16
-#define MAX_PRIOS 8
-#define RTL930X_PORT_IGNORE 0x3f
-#define MAX_MC_GROUPS 512
-#define UNKNOWN_MC_PMASK (MAX_MC_GROUPS - 1)
-#define PIE_BLOCK_SIZE 128
-#define MAX_PIE_ENTRIES (18 * PIE_BLOCK_SIZE)
-#define N_FIXED_FIELDS 12
-#define N_FIXED_FIELDS_RTL931X 14
-#define MAX_COUNTERS 2048
-#define MAX_ROUTES 512
-#define MAX_HOST_ROUTES 1536
-#define MAX_INTF_MTUS 8
-#define DEFAULT_MTU 1536
-#define MAX_INTERFACES 100
-#define MAX_ROUTER_MACS 64
-#define L3_EGRESS_DMACS 2048
-#define MAX_SMACS 64
-
-enum phy_type {
- PHY_NONE = 0,
- PHY_RTL838X_SDS = 1,
- PHY_RTL8218B_INT = 2,
- PHY_RTL8218B_EXT = 3,
- PHY_RTL8214FC = 4,
- PHY_RTL839X_SDS = 5,
- PHY_RTL930X_SDS = 6,
-};
-
-enum pbvlan_type {
- PBVLAN_TYPE_INNER = 0,
- PBVLAN_TYPE_OUTER,
-};
-
-enum pbvlan_mode {
- PBVLAN_MODE_UNTAG_AND_PRITAG = 0,
- PBVLAN_MODE_UNTAG_ONLY,
- PBVLAN_MODE_ALL_PKT,
-};
-
-struct rtl838x_port {
- bool enable;
- u64 pm;
- u16 pvid;
- bool eee_enabled;
- enum phy_type phy;
- bool phy_is_integrated;
- bool is10G;
- bool is2G5;
- int sds_num;
- int led_set;
- int leds_on_this_port;
- const struct dsa_port *dp;
-};
-
-struct rtl838x_vlan_info {
- u64 untagged_ports;
- u64 tagged_ports;
- u8 profile_id;
- bool hash_mc_fid;
- bool hash_uc_fid;
- u8 fid; /* AKA MSTI */
-
- /* The following fields are used only by the RTL931X */
- int if_id; /* Interface (index in L3_EGR_INTF_IDX) */
- u16 multicast_grp_mask;
- int l2_tunnel_list_id;
-};
-
-enum l2_entry_type {
- L2_INVALID = 0,
- L2_UNICAST = 1,
- L2_MULTICAST = 2,
- IP4_MULTICAST = 3,
- IP6_MULTICAST = 4,
-};
-
-struct rtl838x_l2_entry {
- u8 mac[6];
- u16 vid;
- u16 rvid;
- u8 port;
- bool valid;
- enum l2_entry_type type;
- bool is_static;
- bool is_ip_mc;
- bool is_ipv6_mc;
- bool block_da;
- bool block_sa;
- bool suspended;
- bool next_hop;
- int age;
- u8 trunk;
- bool is_trunk;
- u8 stack_dev;
- u16 mc_portmask_index;
- u32 mc_gip;
- u32 mc_sip;
- u16 mc_mac_index;
- u16 nh_route_id;
- bool nh_vlan_target; /* Only RTL83xx: VLAN used for next hop */
-
- /* The following is only valid on RTL931x */
- bool is_open_flow;
- bool is_pe_forward;
- bool is_local_forward;
- bool is_remote_forward;
- bool is_l2_tunnel;
- int l2_tunnel_id;
- int l2_tunnel_list_id;
-};
-
-enum fwd_rule_action {
- FWD_RULE_ACTION_NONE = 0,
- FWD_RULE_ACTION_FWD = 1,
-};
-
-enum pie_phase {
- PHASE_VACL = 0,
- PHASE_IACL = 1,
-};
-
-enum igr_filter {
- IGR_FORWARD = 0,
- IGR_DROP = 1,
- IGR_TRAP = 2,
-};
-
-enum egr_filter {
- EGR_DISABLE = 0,
- EGR_ENABLE = 1,
-};
-
-/* Intermediate representation of a Packet Inspection Engine Rule
- * as suggested by the Kernel's tc flower offload subsystem
- * Field meaning is universal across SoC families, but data content is specific
- * to SoC family (e.g. because of different port ranges) */
-struct pie_rule {
- int id;
- enum pie_phase phase; /* Phase in which this template is applied */
- int packet_cntr; /* ID of a packet counter assigned to this rule */
- int octet_cntr; /* ID of a byte counter assigned to this rule */
- u32 last_packet_cnt;
- u64 last_octet_cnt;
-
- /* The following are requirements for the pie template */
- bool is_egress;
- bool is_ipv6; /* This is a rule with IPv6 fields */
-
- /* Fixed fields that are always matched against on RTL8380 */
- u8 spmmask_fix;
- u8 spn; /* Source port number */
- bool stacking_port; /* Source port is stacking port */
- bool mgnt_vlan; /* Packet arrived on management VLAN */
- bool dmac_hit_sw; /* The packet's destination MAC matches one of the device's */
- bool content_too_deep; /* The content of the packet cannot be parsed: too many layers */
- bool not_first_frag; /* Not the first IP fragment */
- u8 frame_type_l4; /* 0: UDP, 1: TCP, 2: ICMP/ICMPv6, 3: IGMP */
- u8 frame_type; /* 0: ARP, 1: L2 only, 2: IPv4, 3: IPv6 */
- bool otag_fmt; /* 0: outer tag packet, 1: outer priority tag or untagged */
- bool itag_fmt; /* 0: inner tag packet, 1: inner priority tag or untagged */
- bool otag_exist; /* packet with outer tag */
- bool itag_exist; /* packet with inner tag */
- bool frame_type_l2; /* 0: Ethernet, 1: LLC_SNAP, 2: LLC_Other, 3: Reserved */
- bool igr_normal_port; /* Ingress port is not cpu or stacking port */
- u8 tid; /* The template ID defining the what the templated fields mean */
-
- /* Masks for the fields that are always matched against on RTL8380 */
- u8 spmmask_fix_m;
- u8 spn_m;
- bool stacking_port_m;
- bool mgnt_vlan_m;
- bool dmac_hit_sw_m;
- bool content_too_deep_m;
- bool not_first_frag_m;
- u8 frame_type_l4_m;
- u8 frame_type_m;
- bool otag_fmt_m;
- bool itag_fmt_m;
- bool otag_exist_m;
- bool itag_exist_m;
- bool frame_type_l2_m;
- bool igr_normal_port_m;
- u8 tid_m;
-
- /* Logical operations between rules, special rules for rule numbers apply */
- bool valid;
- bool cond_not; /* Matches when conditions not match */
- bool cond_and1; /* And this rule 2n with the next rule 2n+1 in same block */
- bool cond_and2; /* And this rule m in block 2n with rule m in block 2n+1 */
- bool ivalid;
-
- /* Actions to be performed */
- bool drop; /* Drop the packet */
- bool fwd_sel; /* Forward packet: to port, portmask, dest route, next rule, drop */
- bool ovid_sel; /* So something to outer vlan-id: shift, re-assign */
- bool ivid_sel; /* Do something to inner vlan-id: shift, re-assign */
- bool flt_sel; /* Filter the packet when sending to certain ports */
- bool log_sel; /* Log the packet in one of the LOG-table counters */
- bool rmk_sel; /* Re-mark the packet, i.e. change the priority-tag */
- bool meter_sel; /* Meter the packet, i.e. limit rate of this type of packet */
- bool tagst_sel; /* Change the ergress tag */
- bool mir_sel; /* Mirror the packet to a Link Aggregation Group */
- bool nopri_sel; /* Change the normal priority */
- bool cpupri_sel; /* Change the CPU priority */
- bool otpid_sel; /* Change Outer Tag Protocol Identifier (802.1q) */
- bool itpid_sel; /* Change Inner Tag Protocol Identifier (802.1q) */
- bool shaper_sel; /* Apply traffic shaper */
- bool mpls_sel; /* MPLS actions */
- bool bypass_sel; /* Bypass actions */
- bool fwd_sa_lrn; /* Learn the source address when forwarding */
- bool fwd_mod_to_cpu; /* Forward the modified VLAN tag format to CPU-port */
-
- /* Fields used in predefined templates 0-2 on RTL8380 / 90 / 9300 */
- u64 spm; /* Source Port Matrix */
- u16 otag; /* Outer VLAN-ID */
- u8 smac[ETH_ALEN]; /* Source MAC address */
- u8 dmac[ETH_ALEN]; /* Destination MAC address */
- u16 ethertype; /* Ethernet frame type field in ethernet header */
- u16 itag; /* Inner VLAN-ID */
- u16 field_range_check;
- u32 sip; /* Source IP */
- struct in6_addr sip6; /* IPv6 Source IP */
- u32 dip; /* Destination IP */
- struct in6_addr dip6; /* IPv6 Destination IP */
- u16 tos_proto; /* IPv4: TOS + Protocol fields, IPv6: Traffic class + next header */
- u16 sport; /* TCP/UDP source port */
- u16 dport; /* TCP/UDP destination port */
- u16 icmp_igmp;
- u16 tcp_info;
- u16 dsap_ssap; /* Destination / Source Service Access Point bytes (802.3) */
-
- u64 spm_m;
- u16 otag_m;
- u8 smac_m[ETH_ALEN];
- u8 dmac_m[ETH_ALEN];
- u8 ethertype_m;
- u16 itag_m;
- u16 field_range_check_m;
- u32 sip_m;
- struct in6_addr sip6_m; /* IPv6 Source IP mask */
- u32 dip_m;
- struct in6_addr dip6_m; /* IPv6 Destination IP mask */
- u16 tos_proto_m;
- u16 sport_m;
- u16 dport_m;
- u16 icmp_igmp_m;
- u16 tcp_info_m;
- u16 dsap_ssap_m;
-
- /* Data associated with actions */
- u8 fwd_act; /* Type of forwarding action */
- /* 0: permit, 1: drop, 2: copy to port id, 4: copy to portmask */
- /* 4: redirect to portid, 5: redirect to portmask */
- /* 6: route, 7: vlan leaky (only 8380) */
- u16 fwd_data; /* Additional data for forwarding action, e.g. destination port */
- u8 ovid_act;
- u16 ovid_data; /* Outer VLAN ID */
- u8 ivid_act;
- u16 ivid_data; /* Inner VLAN ID */
- u16 flt_data; /* Filtering data */
- u16 log_data; /* ID of packet or octet counter in LOG table, on RTL93xx */
- /* unnecessary since PIE-Rule-ID == LOG-counter-ID */
- bool log_octets;
- u8 mpls_act; /* MPLS action type */
- u16 mpls_lib_idx; /* MPLS action data */
-
- u16 rmk_data; /* Data for remarking */
- u16 meter_data; /* ID of meter for bandwidth control */
- u16 tagst_data;
- u16 mir_data;
- u16 nopri_data;
- u16 cpupri_data;
- u16 otpid_data;
- u16 itpid_data;
- u16 shaper_data;
-
- /* Bypass actions, ignored on RTL8380 */
- bool bypass_all; /* Not clear */
- bool bypass_igr_stp; /* Bypass Ingress STP state */
- bool bypass_ibc_sc; /* Bypass Ingress Bandwidth Control and Storm Control */
-};
-
-struct rtl838x_l3_intf {
- u16 vid;
- u8 smac_idx;
- u8 ip4_mtu_id;
- u8 ip6_mtu_id;
- u16 ip4_mtu;
- u16 ip6_mtu;
- u8 ttl_scope;
- u8 hl_scope;
- u8 ip4_icmp_redirect;
- u8 ip6_icmp_redirect;
- u8 ip4_pbr_icmp_redirect;
- u8 ip6_pbr_icmp_redirect;
-};
-
-/* An entry in the RTL93XX SoC's ROUTER_MAC tables setting up a termination point
- * for the L3 routing system. Packets arriving and matching an entry in this table
- * will be considered for routing.
- * Mask fields state whether the corresponding data fields matter for matching
- */
-struct rtl93xx_rt_mac {
- bool valid; /* Valid or not */
- bool p_type; /* Individual (0) or trunk (1) port */
- bool p_mask; /* Whether the port type is used */
- u8 p_id;
- u8 p_id_mask; /* Mask for the port */
- u8 action; /* Routing action performed: 0: FORWARD, 1: DROP, 2: TRAP2CPU */
- /* 3: COPY2CPU, 4: TRAP2MASTERCPU, 5: COPY2MASTERCPU, 6: HARDDROP */
- u16 vid;
- u16 vid_mask;
- u64 mac; /* MAC address used as source MAC in the routed packet */
- u64 mac_mask;
-};
-
-struct rtl83xx_nexthop {
- u16 id; /* ID: L3_NEXT_HOP table-index or route-index set in L2_NEXT_HOP */
- u32 dev_id;
- u16 port;
- u16 vid; /* VLAN-ID for L2 table entry (saved from L2-UC entry) */
- u16 rvid; /* Relay VID/FID for the L2 table entry */
- u64 mac; /* The MAC address of the entry in the L2_NEXT_HOP table */
- u16 mac_id;
- u16 l2_id; /* Index of this next hop forwarding entry in L2 FIB table */
- u64 gw; /* The gateway MAC address packets are forwarded to */
- int if_id; /* Interface (into L3_EGR_INTF_IDX) */
-};
-
-struct rtl838x_switch_priv;
-
-struct rtl83xx_flow {
- unsigned long cookie;
- struct rhash_head node;
- struct rcu_head rcu_head;
- struct rtl838x_switch_priv *priv;
- struct pie_rule rule;
- u32 flags;
-};
-
-struct rtl93xx_route_attr {
- bool valid;
- bool hit;
- bool ttl_dec;
- bool ttl_check;
- bool dst_null;
- bool qos_as;
- u8 qos_prio;
- u8 type;
- u8 action;
-};
-
-struct rtl83xx_route {
- u32 gw_ip; /* IP of the route's gateway */
- u32 dst_ip; /* IP of the destination net */
- struct in6_addr dst_ip6;
- int prefix_len; /* Network prefix len of the destination net */
- bool is_host_route;
- int id; /* ID number of this route */
- struct rhlist_head linkage;
- u16 switch_mac_id; /* Index into switch's own MACs, RTL839X only */
- struct rtl83xx_nexthop nh;
- struct pie_rule pr;
- struct rtl93xx_route_attr attr;
-};
-
-struct rtl838x_reg {
- void (*mask_port_reg_be)(u64 clear, u64 set, int reg);
- void (*set_port_reg_be)(u64 set, int reg);
- u64 (*get_port_reg_be)(int reg);
- void (*mask_port_reg_le)(u64 clear, u64 set, int reg);
- void (*set_port_reg_le)(u64 set, int reg);
- u64 (*get_port_reg_le)(int reg);
- int stat_port_rst;
- int stat_rst;
- int stat_port_std_mib;
- int (*port_iso_ctrl)(int p);
- void (*traffic_enable)(int source, int dest);
- void (*traffic_disable)(int source, int dest);
- void (*traffic_set)(int source, u64 dest_matrix);
- u64 (*traffic_get)(int source);
- int l2_ctrl_0;
- int l2_ctrl_1;
- int smi_poll_ctrl;
- u32 l2_port_aging_out;
- int l2_tbl_flush_ctrl;
- void (*exec_tbl0_cmd)(u32 cmd);
- void (*exec_tbl1_cmd)(u32 cmd);
- int (*tbl_access_data_0)(int i);
- int isr_glb_src;
- int isr_port_link_sts_chg;
- int imr_port_link_sts_chg;
- int imr_glb;
- void (*vlan_tables_read)(u32 vlan, struct rtl838x_vlan_info *info);
- void (*vlan_set_tagged)(u32 vlan, struct rtl838x_vlan_info *info);
- void (*vlan_set_untagged)(u32 vlan, u64 portmask);
- void (*vlan_profile_dump)(int index);
- void (*vlan_profile_setup)(int profile);
- void (*vlan_port_pvidmode_set)(int port, enum pbvlan_type type, enum pbvlan_mode mode);
- void (*vlan_port_pvid_set)(int port, enum pbvlan_type type, int pvid);
- void (*vlan_port_keep_tag_set)(int port, bool keep_outer, bool keep_inner);
- void (*set_vlan_igr_filter)(int port, enum igr_filter state);
- void (*set_vlan_egr_filter)(int port, enum egr_filter state);
- void (*enable_learning)(int port, bool enable);
- void (*enable_flood)(int port, bool enable);
- void (*enable_mcast_flood)(int port, bool enable);
- void (*enable_bcast_flood)(int port, bool enable);
- void (*set_static_move_action)(int port, bool forward);
- void (*stp_get)(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]);
- void (*stp_set)(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]);
- int (*mac_force_mode_ctrl)(int port);
- int (*mac_port_ctrl)(int port);
- int (*l2_port_new_salrn)(int port);
- int (*l2_port_new_sa_fwd)(int port);
- int (*set_ageing_time)(unsigned long msec);
- int mir_ctrl;
- int mir_dpm;
- int mir_spm;
- int mac_link_sts;
- int mac_link_dup_sts;
- int (*mac_link_spd_sts)(int port);
- int mac_rx_pause_sts;
- int mac_tx_pause_sts;
- u64 (*read_l2_entry_using_hash)(u32 hash, u32 position, struct rtl838x_l2_entry *e);
- void (*write_l2_entry_using_hash)(u32 hash, u32 pos, struct rtl838x_l2_entry *e);
- u64 (*read_cam)(int idx, struct rtl838x_l2_entry *e);
- void (*write_cam)(int idx, struct rtl838x_l2_entry *e);
- int (*trk_mbr_ctr)(int group);
- int rma_bpdu_fld_pmask;
- int spcl_trap_eapol_ctrl;
- void (*init_eee)(struct rtl838x_switch_priv *priv, bool enable);
- void (*port_eee_set)(struct rtl838x_switch_priv *priv, int port, bool enable);
- int (*eee_port_ability)(struct rtl838x_switch_priv *priv,
- struct ethtool_eee *e, int port);
- u64 (*l2_hash_seed)(u64 mac, u32 vid);
- u32 (*l2_hash_key)(struct rtl838x_switch_priv *priv, u64 seed);
- u64 (*read_mcast_pmask)(int idx);
- void (*write_mcast_pmask)(int idx, u64 portmask);
- void (*vlan_fwd_on_inner)(int port, bool is_set);
- void (*pie_init)(struct rtl838x_switch_priv *priv);
- int (*pie_rule_read)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr);
- int (*pie_rule_write)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr);
- int (*pie_rule_add)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
- void (*pie_rule_rm)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
- void (*l2_learning_setup)(void);
- u32 (*packet_cntr_read)(int counter);
- void (*packet_cntr_clear)(int counter);
- void (*route_read)(int idx, struct rtl83xx_route *rt);
- void (*route_write)(int idx, struct rtl83xx_route *rt);
- void (*host_route_write)(int idx, struct rtl83xx_route *rt);
- int (*l3_setup)(struct rtl838x_switch_priv *priv);
- void (*set_l3_nexthop)(int idx, u16 dmac_id, u16 interface);
- void (*get_l3_nexthop)(int idx, u16 *dmac_id, u16 *interface);
- u64 (*get_l3_egress_mac)(u32 idx);
- void (*set_l3_egress_mac)(u32 idx, u64 mac);
- int (*find_l3_slot)(struct rtl83xx_route *rt, bool must_exist);
- int (*route_lookup_hw)(struct rtl83xx_route *rt);
- void (*get_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m);
- void (*set_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m);
- void (*set_l3_egress_intf)(int idx, struct rtl838x_l3_intf *intf);
- void (*set_distribution_algorithm)(int group, int algoidx, u32 algomask);
- void (*set_receive_management_action)(int port, rma_ctrl_t type, action_type_t action);
- void (*led_init)(struct rtl838x_switch_priv *priv);
-};
-
-struct rtl838x_switch_priv {
- /* Switch operation */
- struct dsa_switch *ds;
- struct device *dev;
- u16 id;
- u16 family_id;
- char version;
- struct rtl838x_port ports[57];
- struct mutex reg_mutex; /* Mutex for individual register manipulations */
- struct mutex pie_mutex; /* Mutex for Packet Inspection Engine */
- int link_state_irq;
- int mirror_group_ports[4];
- struct mii_bus *mii_bus;
- const struct rtl838x_reg *r;
- u8 cpu_port;
- u8 port_mask;
- u8 port_width;
- u8 port_ignore;
- u64 irq_mask;
- u32 fib_entries;
- int l2_bucket_size;
- struct dentry *dbgfs_dir;
- int n_lags;
- u64 lags_port_members[MAX_LAGS];
- struct net_device *lag_devs[MAX_LAGS];
- u32 lag_primary[MAX_LAGS];
- u32 is_lagmember[57];
- u64 lagmembers;
- struct notifier_block nb; /* TODO: change to different name */
- struct notifier_block ne_nb;
- struct notifier_block fib_nb;
- bool eee_enabled;
- unsigned long int mc_group_bm[MAX_MC_GROUPS >> 5];
- int n_pie_blocks;
- struct rhashtable tc_ht;
- unsigned long int pie_use_bm[MAX_PIE_ENTRIES >> 5];
- int n_counters;
- unsigned long int octet_cntr_use_bm[MAX_COUNTERS >> 5];
- unsigned long int packet_cntr_use_bm[MAX_COUNTERS >> 4];
- struct rhltable routes;
- unsigned long int route_use_bm[MAX_ROUTES >> 5];
- unsigned long int host_route_use_bm[MAX_HOST_ROUTES >> 5];
- struct rtl838x_l3_intf *interfaces[MAX_INTERFACES];
- u16 intf_mtus[MAX_INTF_MTUS];
- int intf_mtu_count[MAX_INTF_MTUS];
-};
-
-void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv);
-void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv);
-
-#endif /* _RTL838X_H */
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c
deleted file mode 100644
index 25ad4eaa11..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c
+++ /dev/null
@@ -1,1694 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include <asm/mach-rtl838x/mach-rtl83xx.h>
-#include <linux/etherdevice.h>
-
-#include "rtl83xx.h"
-
-#define RTL931X_VLAN_PORT_TAG_STS_INTERNAL 0x0
-#define RTL931X_VLAN_PORT_TAG_STS_UNTAG 0x1
-#define RTL931X_VLAN_PORT_TAG_STS_TAGGED 0x2
-#define RTL931X_VLAN_PORT_TAG_STS_PRIORITY_TAGGED 0x3
-
-#define RTL931X_VLAN_PORT_TAG_CTRL_BASE 0x4860
-/* port 0-56 */
-#define RTL931X_VLAN_PORT_TAG_CTRL(port) \
- RTL931X_VLAN_PORT_TAG_CTRL_BASE + (port << 2)
-#define RTL931X_VLAN_PORT_TAG_EGR_OTAG_STS_MASK GENMASK(13,12)
-#define RTL931X_VLAN_PORT_TAG_EGR_ITAG_STS_MASK GENMASK(11,10)
-#define RTL931X_VLAN_PORT_TAG_EGR_OTAG_KEEP_MASK GENMASK(9,9)
-#define RTL931X_VLAN_PORT_TAG_EGR_ITAG_KEEP_MASK GENMASK(8,8)
-#define RTL931X_VLAN_PORT_TAG_IGR_OTAG_KEEP_MASK GENMASK(7,7)
-#define RTL931X_VLAN_PORT_TAG_IGR_ITAG_KEEP_MASK GENMASK(6,6)
-#define RTL931X_VLAN_PORT_TAG_OTPID_IDX_MASK GENMASK(5,4)
-#define RTL931X_VLAN_PORT_TAG_OTPID_KEEP_MASK GENMASK(3,3)
-#define RTL931X_VLAN_PORT_TAG_ITPID_IDX_MASK GENMASK(2,1)
-#define RTL931X_VLAN_PORT_TAG_ITPID_KEEP_MASK GENMASK(0,0)
-
-extern struct mutex smi_lock;
-extern struct rtl83xx_soc_info soc_info;
-
-/* Definition of the RTL931X-specific template field IDs as used in the PIE */
-enum template_field_id {
- TEMPLATE_FIELD_SPM0 = 1,
- TEMPLATE_FIELD_SPM1 = 2,
- TEMPLATE_FIELD_SPM2 = 3,
- TEMPLATE_FIELD_SPM3 = 4,
- TEMPLATE_FIELD_DMAC0 = 9,
- TEMPLATE_FIELD_DMAC1 = 10,
- TEMPLATE_FIELD_DMAC2 = 11,
- TEMPLATE_FIELD_SMAC0 = 12,
- TEMPLATE_FIELD_SMAC1 = 13,
- TEMPLATE_FIELD_SMAC2 = 14,
- TEMPLATE_FIELD_ETHERTYPE = 15,
- TEMPLATE_FIELD_OTAG = 16,
- TEMPLATE_FIELD_ITAG = 17,
- TEMPLATE_FIELD_SIP0 = 18,
- TEMPLATE_FIELD_SIP1 = 19,
- TEMPLATE_FIELD_DIP0 = 20,
- TEMPLATE_FIELD_DIP1 = 21,
- TEMPLATE_FIELD_IP_TOS_PROTO = 22,
- TEMPLATE_FIELD_L4_SPORT = 23,
- TEMPLATE_FIELD_L4_DPORT = 24,
- TEMPLATE_FIELD_L34_HEADER = 25,
- TEMPLATE_FIELD_TCP_INFO = 26,
- TEMPLATE_FIELD_SIP2 = 34,
- TEMPLATE_FIELD_SIP3 = 35,
- TEMPLATE_FIELD_SIP4 = 36,
- TEMPLATE_FIELD_SIP5 = 37,
- TEMPLATE_FIELD_SIP6 = 38,
- TEMPLATE_FIELD_SIP7 = 39,
- TEMPLATE_FIELD_DIP2 = 42,
- TEMPLATE_FIELD_DIP3 = 43,
- TEMPLATE_FIELD_DIP4 = 44,
- TEMPLATE_FIELD_DIP5 = 45,
- TEMPLATE_FIELD_DIP6 = 46,
- TEMPLATE_FIELD_DIP7 = 47,
- TEMPLATE_FIELD_FLOW_LABEL = 49,
- TEMPLATE_FIELD_DSAP_SSAP = 50,
- TEMPLATE_FIELD_FWD_VID = 52,
- TEMPLATE_FIELD_RANGE_CHK = 53,
- TEMPLATE_FIELD_SLP = 55,
- TEMPLATE_FIELD_DLP = 56,
- TEMPLATE_FIELD_META_DATA = 57,
- TEMPLATE_FIELD_FIRST_MPLS1 = 60,
- TEMPLATE_FIELD_FIRST_MPLS2 = 61,
- TEMPLATE_FIELD_DPM3 = 8,
-};
-
-/* The meaning of TEMPLATE_FIELD_VLAN depends on phase and the configuration in
- * RTL931X_PIE_CTRL. We use always the same definition and map to the inner VLAN tag:
- */
-#define TEMPLATE_FIELD_VLAN TEMPLATE_FIELD_ITAG
-
-/* Number of fixed templates predefined in the RTL9300 SoC */
-#define N_FIXED_TEMPLATES 5
-/* RTL931x specific predefined templates */
-static enum template_field_id fixed_templates[N_FIXED_TEMPLATES][N_FIXED_FIELDS_RTL931X] =
-{
- {
- TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2,
- TEMPLATE_FIELD_SMAC0, TEMPLATE_FIELD_SMAC1, TEMPLATE_FIELD_SMAC2,
- TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_DSAP_SSAP,
- TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1,
- TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3
- }, {
- TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0,
- TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_TCP_INFO,
- TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_VLAN,
- TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1,
- TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3
- }, {
- TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2,
- TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_IP_TOS_PROTO,
- TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0,
- TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT,
- TEMPLATE_FIELD_META_DATA, TEMPLATE_FIELD_SLP
- }, {
- TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_DIP2,
- TEMPLATE_FIELD_DIP3, TEMPLATE_FIELD_DIP4, TEMPLATE_FIELD_DIP5,
- TEMPLATE_FIELD_DIP6, TEMPLATE_FIELD_DIP7, TEMPLATE_FIELD_IP_TOS_PROTO,
- TEMPLATE_FIELD_TCP_INFO, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT,
- TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SLP
- }, {
- TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_SIP2,
- TEMPLATE_FIELD_SIP3, TEMPLATE_FIELD_SIP4, TEMPLATE_FIELD_SIP5,
- TEMPLATE_FIELD_SIP6, TEMPLATE_FIELD_SIP7, TEMPLATE_FIELD_META_DATA,
- TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1,
- TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3
- },
-};
-
-inline void rtl931x_exec_tbl0_cmd(u32 cmd)
-{
- sw_w32(cmd, RTL931X_TBL_ACCESS_CTRL_0);
- do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_0) & (1 << 20));
-}
-
-inline void rtl931x_exec_tbl1_cmd(u32 cmd)
-{
- sw_w32(cmd, RTL931X_TBL_ACCESS_CTRL_1);
- do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_1) & (1 << 17));
-}
-
-inline int rtl931x_tbl_access_data_0(int i)
-{
- return RTL931X_TBL_ACCESS_DATA_0(i);
-}
-
-void rtl931x_vlan_profile_dump(int index)
-{
- u64 profile[4];
-
- if (index < 0 || index > 15)
- return;
-
- profile[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(index));
- profile[1] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 4) & 0x1FFFFFFFULL) << 32 |
- (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 8) & 0xFFFFFFFF);
- profile[2] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 16) & 0x1FFFFFFFULL) << 32 |
- (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 12) & 0xFFFFFFFF);
- profile[3] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 20) & 0x1FFFFFFFULL) << 32 |
- (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 24) & 0xFFFFFFFF);
-
- pr_info("VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %llx, \
- IPv4 Unknown MultiCast Field %llx, IPv6 Unknown MultiCast Field: %llx",
- index, (u32) (profile[0] & (3 << 14)), profile[1], profile[2], profile[3]);
-}
-
-static void rtl931x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
-{
- u32 cmd = 1 << 20 | /* Execute cmd */
- 0 << 19 | /* Read */
- 5 << 15 | /* Table type 0b101 */
- (msti & 0x3fff);
- priv->r->exec_tbl0_cmd(cmd);
-
- for (int i = 0; i < 4; i++)
- port_state[i] = sw_r32(priv->r->tbl_access_data_0(i));
-}
-
-static void rtl931x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
-{
- u32 cmd = 1 << 20 | /* Execute cmd */
- 1 << 19 | /* Write */
- 5 << 15 | /* Table type 0b101 */
- (msti & 0x3fff);
- for (int i = 0; i < 4; i++)
- sw_w32(port_state[i], priv->r->tbl_access_data_0(i));
- priv->r->exec_tbl0_cmd(cmd);
-}
-
-inline static int rtl931x_trk_mbr_ctr(int group)
-{
- return RTL931X_TRK_MBR_CTRL + (group << 2);
-}
-
-static void rtl931x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info)
-{
- u32 v, w, x, y;
- /* Read VLAN table (3) via register 0 */
- struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 3);
-
- rtl_table_read(r, vlan);
- v = sw_r32(rtl_table_data(r, 0));
- w = sw_r32(rtl_table_data(r, 1));
- x = sw_r32(rtl_table_data(r, 2));
- y = sw_r32(rtl_table_data(r, 3));
- rtl_table_release(r);
-
- pr_debug("VLAN_READ %d: %08x %08x %08x %08x\n", vlan, v, w, x, y);
- info->tagged_ports = ((u64) v) << 25 | (w >> 7);
- info->profile_id = (x >> 16) & 0xf;
- info->fid = w & 0x7f; /* AKA MSTI depending on context */
- info->hash_uc_fid = !!(x & BIT(31));
- info->hash_mc_fid = !!(x & BIT(30));
- info->if_id = (x >> 20) & 0x3ff;
- info->profile_id = (x >> 16) & 0xf;
- info->multicast_grp_mask = x & 0xffff;
- if (x & BIT(31))
- info->l2_tunnel_list_id = y >> 18;
- else
- info->l2_tunnel_list_id = -1;
- pr_debug("%s read tagged %016llx, profile-id %d, uc %d, mc %d, intf-id %d\n", __func__,
- info->tagged_ports, info->profile_id, info->hash_uc_fid, info->hash_mc_fid,
- info->if_id);
-
- /* Read UNTAG table via table register 3 */
- r = rtl_table_get(RTL9310_TBL_3, 0);
- rtl_table_read(r, vlan);
- v = ((u64)sw_r32(rtl_table_data(r, 0))) << 25;
- v |= sw_r32(rtl_table_data(r, 1)) >> 7;
- rtl_table_release(r);
-
- info->untagged_ports = v;
-}
-
-static void rtl931x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info)
-{
- u32 v, w, x, y;
- /* Access VLAN table (1) via register 0 */
- struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 3);
-
- v = info->tagged_ports >> 25;
- w = (info->tagged_ports & 0x1fffff) << 7;
- w |= info->fid & 0x7f;
- x = info->hash_uc_fid ? BIT(31) : 0;
- x |= info->hash_mc_fid ? BIT(30) : 0;
- x |= info->if_id & 0x3ff << 20;
- x |= (info->profile_id & 0xf) << 16;
- x |= info->multicast_grp_mask & 0xffff;
- if (info->l2_tunnel_list_id >= 0) {
- y = info->l2_tunnel_list_id << 18;
- y |= BIT(31);
- } else {
- y = 0;
- }
-
- sw_w32(v, rtl_table_data(r, 0));
- sw_w32(w, rtl_table_data(r, 1));
- sw_w32(x, rtl_table_data(r, 2));
- sw_w32(y, rtl_table_data(r, 3));
-
- rtl_table_write(r, vlan);
- rtl_table_release(r);
-}
-
-static void rtl931x_vlan_set_untagged(u32 vlan, u64 portmask)
-{
- struct table_reg *r = rtl_table_get(RTL9310_TBL_3, 0);
-
- rtl839x_set_port_reg_be(portmask << 7, rtl_table_data(r, 0));
- rtl_table_write(r, vlan);
- rtl_table_release(r);
-}
-
-static inline int rtl931x_mac_force_mode_ctrl(int p)
-{
- return RTL931X_MAC_FORCE_MODE_CTRL + (p << 2);
-}
-
-static inline int rtl931x_mac_link_spd_sts(int p)
-{
- return RTL931X_MAC_LINK_SPD_STS + (((p >> 3) << 2));
-}
-
-static inline int rtl931x_mac_port_ctrl(int p)
-{
- return RTL931X_MAC_L2_PORT_CTRL + (p << 7);
-}
-
-static inline int rtl931x_l2_port_new_salrn(int p)
-{
- return RTL931X_L2_PORT_NEW_SALRN(p);
-}
-
-static inline int rtl931x_l2_port_new_sa_fwd(int p)
-{
- return RTL931X_L2_PORT_NEW_SA_FWD(p);
-}
-
-irqreturn_t rtl931x_switch_irq(int irq, void *dev_id)
-{
- struct dsa_switch *ds = dev_id;
- u32 status = sw_r32(RTL931X_ISR_GLB_SRC);
- u64 ports = rtl839x_get_port_reg_le(RTL931X_ISR_PORT_LINK_STS_CHG);
- u64 link;
-
- /* Clear status */
- rtl839x_set_port_reg_le(ports, RTL931X_ISR_PORT_LINK_STS_CHG);
- pr_debug("RTL931X Link change: status: %x, ports %016llx\n", status, ports);
-
- link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS);
- /* Must re-read this to get correct status */
- link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS);
- pr_debug("RTL931X Link change: status: %x, link status %016llx\n", status, link);
-
- for (int i = 0; i < 56; i++) {
- if (ports & BIT_ULL(i)) {
- if (link & BIT_ULL(i)) {
- pr_info("%s port %d up\n", __func__, i);
- dsa_port_phylink_mac_change(ds, i, true);
- } else {
- pr_info("%s port %d down\n", __func__, i);
- dsa_port_phylink_mac_change(ds, i, false);
- }
- }
- }
-
- return IRQ_HANDLED;
-}
-
-int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val)
-{
- u32 v;
- int err = 0;
-
- val &= 0xffff;
- if (port > 63 || page > 4095 || reg > 31)
- return -ENOTSUPP;
-
- mutex_lock(&smi_lock);
- pr_debug("%s: writing to phy %d %d %d %d\n", __func__, port, page, reg, val);
- /* Clear both port registers */
- sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2);
- sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4);
- sw_w32_mask(0, BIT(port % 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + (port / 32) * 4);
-
- sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3);
-
- v = reg << 6 | page << 11 ;
- sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
-
- sw_w32(0x1ff, RTL931X_SMI_INDRT_ACCESS_CTRL_1);
-
- v |= BIT(4) | 1; /* Write operation and execute */
- sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
-
- do {
- } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1);
-
- if (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x2)
- err = -EIO;
-
- mutex_unlock(&smi_lock);
-
- return err;
-}
-
-int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
-{
- u32 v;
-
- if (port > 63 || page > 4095 || reg > 31)
- return -ENOTSUPP;
-
- mutex_lock(&smi_lock);
-
- sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL);
-
- v = reg << 6 | page << 11 | 1;
- sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
-
- do {
- } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1);
-
- v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
- *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3);
- *val = (*val & 0xffff0000) >> 16;
-
- pr_debug("%s: port %d, page: %d, reg: %x, val: %x, v: %08x\n",
- __func__, port, page, reg, *val, v);
-
- mutex_unlock(&smi_lock);
-
- return 0;
-}
-
-/* Read an mmd register of the PHY */
-int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val)
-{
- int err = 0;
- u32 v;
- /* Select PHY register type
- * If select 1G/10G MMD register type, registers EXT_PAGE, MAIN_PAGE and REG settings are don’t care.
- * 0x0 Normal register (Clause 22)
- * 0x1: 1G MMD register (MMD via Clause 22 registers 13 and 14)
- * 0x2: 10G MMD register (MMD via Clause 45)
- */
- int type = (regnum & MII_ADDR_C45)?2:1;
-
- mutex_lock(&smi_lock);
-
- /* Set PHY to access via port-number */
- sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL);
-
- /* Set MMD device number and register to write to */
- sw_w32(devnum << 16 | mdiobus_c45_regad(regnum), RTL931X_SMI_INDRT_ACCESS_MMD_CTRL);
-
- v = type << 2 | BIT(0); /* MMD-access-type | EXEC */
- sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
-
- do {
- v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
- } while (v & BIT(0));
-
- /* Check for error condition */
- if (v & BIT(1))
- err = -EIO;
-
- *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3) >> 16;
-
- pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__,
- port, devnum, mdiobus_c45_regad(regnum), *val, err);
-
- mutex_unlock(&smi_lock);
-
- return err;
-}
-
-/* Write to an mmd register of the PHY */
-int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val)
-{
- int err = 0;
- u32 v;
- int type = (regnum & MII_ADDR_C45)?2:1;
- u64 pm;
-
- mutex_lock(&smi_lock);
-
- /* Set PHY to access via port-mask */
- pm = (u64)1 << port;
- sw_w32((u32)pm, RTL931X_SMI_INDRT_ACCESS_CTRL_2);
- sw_w32((u32)(pm >> 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4);
-
- /* Set data to write */
- sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3);
-
- /* Set MMD device number and register to write to */
- sw_w32(devnum << 16 | mdiobus_c45_regad(regnum), RTL931X_SMI_INDRT_ACCESS_MMD_CTRL);
-
- v = BIT(4) | type << 2 | BIT(0); /* WRITE | MMD-access-type | EXEC */
- sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
-
- do {
- v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
- } while (v & BIT(0));
-
- pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__,
- port, devnum, mdiobus_c45_regad(regnum), val, err);
- mutex_unlock(&smi_lock);
-
- return err;
-}
-
-void rtl931x_print_matrix(void)
-{
- volatile u64 *ptr = RTL838X_SW_BASE + RTL839X_PORT_ISO_CTRL(0);
-
- for (int i = 0; i < 52; i += 4)
- pr_info("> %16llx %16llx %16llx %16llx\n",
- ptr[i + 0], ptr[i + 1], ptr[i + 2], ptr[i + 3]);
- pr_info("CPU_PORT> %16llx\n", ptr[52]);
-}
-
-void rtl931x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action)
-{
- u32 value = 0;
-
- /* hack for value mapping */
- if (type == GRATARP && action == COPY2CPU)
- action = TRAP2MASTERCPU;
-
- switch(action) {
- case FORWARD:
- value = 0;
- break;
- case DROP:
- value = 1;
- break;
- case TRAP2CPU:
- value = 2;
- break;
- case TRAP2MASTERCPU:
- value = 3;
- break;
- case FLOODALL:
- value = 4;
- break;
- default:
- break;
- }
-
- switch(type) {
- case BPDU:
- sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_BPDU_CTRL + ((port / 10) << 2));
- break;
- case PTP:
- /* udp */
- sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2));
- /* eth2 */
- sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2));
- break;
- case PTP_UDP:
- sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2));
- break;
- case PTP_ETH2:
- sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2));
- break;
- case LLDP:
- sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_LLDP_CTRL + ((port / 10) << 2));
- break;
- case EAPOL:
- sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_EAPOL_CTRL + ((port / 10) << 2));
- break;
- case GRATARP:
- sw_w32_mask(3 << ((port & 0xf) << 1), value << ((port & 0xf) << 1), RTL931X_TRAP_ARP_GRAT_PORT_ACT + ((port >> 4) << 2));
- break;
- }
-}
-
-u64 rtl931x_traffic_get(int source)
-{
- u32 v;
- struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
-
- rtl_table_read(r, source);
- v = sw_r32(rtl_table_data(r, 0));
- rtl_table_release(r);
- v = v >> 3;
-
- return v;
-}
-
-/* Enable traffic between a source port and a destination port matrix */
-void rtl931x_traffic_set(int source, u64 dest_matrix)
-{
- struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
-
- sw_w32((dest_matrix << 3), rtl_table_data(r, 0));
- rtl_table_write(r, source);
- rtl_table_release(r);
-}
-
-void rtl931x_traffic_enable(int source, int dest)
-{
- struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
- rtl_table_read(r, source);
- sw_w32_mask(0, BIT(dest + 3), rtl_table_data(r, 0));
- rtl_table_write(r, source);
- rtl_table_release(r);
-}
-
-void rtl931x_traffic_disable(int source, int dest)
-{
- struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
- rtl_table_read(r, source);
- sw_w32_mask(BIT(dest + 3), 0, rtl_table_data(r, 0));
- rtl_table_write(r, source);
- rtl_table_release(r);
-}
-
-static u64 rtl931x_l2_hash_seed(u64 mac, u32 vid)
-{
- u64 v = vid;
-
- v <<= 48;
- v |= mac;
-
- return v;
-}
-
-/* Calculate both the block 0 and the block 1 hash by applyingthe same hash
- * algorithm as the one used currently by the ASIC to the seed, and return
- * both hashes in the lower and higher word of the return value since only 12 bit of
- * the hash are significant.
- */
-static u32 rtl931x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed)
-{
- u32 h, h0, h1, h2, h3, h4, k0, k1;
-
- h0 = seed & 0xfff;
- h1 = (seed >> 12) & 0xfff;
- h2 = (seed >> 24) & 0xfff;
- h3 = (seed >> 36) & 0xfff;
- h4 = (seed >> 48) & 0xfff;
- h4 = ((h4 & 0x7) << 9) | ((h4 >> 3) & 0x1ff);
- k0 = h0 ^ h1 ^ h2 ^ h3 ^ h4;
-
- h0 = seed & 0xfff;
- h0 = ((h0 & 0x1ff) << 3) | ((h0 >> 9) & 0x7);
- h1 = (seed >> 12) & 0xfff;
- h1 = ((h1 & 0x3f) << 6) | ((h1 >> 6) & 0x3f);
- h2 = (seed >> 24) & 0xfff;
- h3 = (seed >> 36) & 0xfff;
- h3 = ((h3 & 0x3f) << 6) | ((h3 >> 6) & 0x3f);
- h4 = (seed >> 48) & 0xfff;
- k1 = h0 ^ h1 ^ h2 ^ h3 ^ h4;
-
- /* Algorithm choice for block 0 */
- if (sw_r32(RTL931X_L2_CTRL) & BIT(0))
- h = k1;
- else
- h = k0;
-
- /* Algorithm choice for block 1
- * Since k0 and k1 are < 4096, adding 4096 will offset the hash into the second
- * half of hash-space
- * 4096 is in fact the hash-table size 32768 divided by 4 hashes per bucket
- * divided by 2 to divide the hash space in 2
- */
- if (sw_r32(RTL931X_L2_CTRL) & BIT(1))
- h |= (k1 + 4096) << 16;
- else
- h |= (k0 + 4096) << 16;
-
- return h;
-}
-
-/* Fills an L2 entry structure from the SoC registers */
-static void rtl931x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e)
-{
- pr_debug("In %s valid?\n", __func__);
- e->valid = !!(r[0] & BIT(31));
- if (!e->valid)
- return;
-
- pr_debug("%s: entry valid, raw: %08x %08x %08x %08x\n", __func__, r[0], r[1], r[2], r[3]);
- e->is_ip_mc = false;
- e->is_ipv6_mc = false;
-
- e->mac[0] = r[0] >> 8;
- e->mac[1] = r[0];
- e->mac[2] = r[1] >> 24;
- e->mac[3] = r[1] >> 16;
- e->mac[4] = r[1] >> 8;
- e->mac[5] = r[1];
-
- e->is_open_flow = !!(r[0] & BIT(30));
- e->is_pe_forward = !!(r[0] & BIT(29));
- e->next_hop = !!(r[2] & BIT(30));
- e->rvid = (r[0] >> 16) & 0xfff;
-
- /* Is it a unicast entry? check multicast bit */
- if (!(e->mac[0] & 1)) {
- e->type = L2_UNICAST;
- e->is_l2_tunnel = !!(r[2] & BIT(31));
- e->is_static = !!(r[2] & BIT(13));
- e->port = (r[2] >> 19) & 0x3ff;
- /* Check for trunk port */
- if (r[2] & BIT(29)) {
- e->is_trunk = true;
- e->stack_dev = (e->port >> 9) & 1;
- e->trunk = e->port & 0x3f;
- } else {
- e->is_trunk = false;
- e->stack_dev = (e->port >> 6) & 0xf;
- e->port = e->port & 0x3f;
- }
-
- e->block_da = !!(r[2] & BIT(14));
- e->block_sa = !!(r[2] & BIT(15));
- e->suspended = !!(r[2] & BIT(12));
- e->age = (r[2] >> 16) & 3;
-
- /* the UC_VID field in hardware is used for the VID or for the route id */
- if (e->next_hop) {
- e->nh_route_id = r[2] & 0x7ff;
- e->vid = 0;
- } else {
- e->vid = r[2] & 0xfff;
- e->nh_route_id = 0;
- }
- if (e->is_l2_tunnel)
- e->l2_tunnel_id = ((r[2] & 0xff) << 4) | (r[3] >> 28);
- /* TODO: Implement VLAN conversion */
- } else {
- e->type = L2_MULTICAST;
- e->is_local_forward = !!(r[2] & BIT(31));
- e->is_remote_forward = !!(r[2] & BIT(17));
- e->mc_portmask_index = (r[2] >> 18) & 0xfff;
- e->l2_tunnel_list_id = (r[2] >> 4) & 0x1fff;
- }
-}
-
-/* Fills the 3 SoC table registers r[] with the information of in the rtl838x_l2_entry */
-static void rtl931x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e)
-{
- u32 port;
-
- if (!e->valid) {
- r[0] = r[1] = r[2] = 0;
- return;
- }
-
- r[2] = BIT(31); /* Set valid bit */
-
- r[0] = ((u32)e->mac[0]) << 24 |
- ((u32)e->mac[1]) << 16 |
- ((u32)e->mac[2]) << 8 |
- ((u32)e->mac[3]);
- r[1] = ((u32)e->mac[4]) << 24 |
- ((u32)e->mac[5]) << 16;
-
- r[2] |= e->next_hop ? BIT(12) : 0;
-
- if (e->type == L2_UNICAST) {
- r[2] |= e->is_static ? BIT(14) : 0;
- r[1] |= e->rvid & 0xfff;
- r[2] |= (e->port & 0x3ff) << 20;
- if (e->is_trunk) {
- r[2] |= BIT(30);
- port = e->stack_dev << 9 | (e->port & 0x3f);
- } else {
- port = (e->stack_dev & 0xf) << 6;
- port |= e->port & 0x3f;
- }
- r[2] |= port << 20;
- r[2] |= e->block_da ? BIT(15) : 0;
- r[2] |= e->block_sa ? BIT(17) : 0;
- r[2] |= e->suspended ? BIT(13) : 0;
- r[2] |= (e->age & 0x3) << 17;
- /* the UC_VID field in hardware is used for the VID or for the route id */
- if (e->next_hop)
- r[2] |= e->nh_route_id & 0x7ff;
- else
- r[2] |= e->vid & 0xfff;
- } else { /* L2_MULTICAST */
- r[2] |= (e->mc_portmask_index & 0x3ff) << 16;
- r[2] |= e->mc_mac_index & 0x7ff;
- }
-}
-
-/* Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table
- * hash is the id of the bucket and pos is the position of the entry in that bucket
- * The data read from the SoC is filled into rtl838x_l2_entry
- */
-static u64 rtl931x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
-{
- u32 r[4];
- struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 0);
- u32 idx;
- u64 mac;
- u64 seed;
-
- pr_debug("%s: hash %08x, pos: %d\n", __func__, hash, pos);
-
- /* On the RTL93xx, 2 different hash algorithms are used making it a total of
- * 8 buckets that need to be searched, 4 for each hash-half
- * Use second hash space when bucket is between 4 and 8
- */
- if (pos >= 4) {
- pos -= 4;
- hash >>= 16;
- } else {
- hash &= 0xffff;
- }
-
- idx = (0 << 14) | (hash << 2) | pos; /* Search SRAM, with hash and at pos in bucket */
- pr_debug("%s: NOW hash %08x, pos: %d\n", __func__, hash, pos);
-
- rtl_table_read(q, idx);
- for (int i = 0; i < 4; i++)
- r[i] = sw_r32(rtl_table_data(q, i));
-
- rtl_table_release(q);
-
- rtl931x_fill_l2_entry(r, e);
-
- pr_debug("%s: valid: %d, nh: %d\n", __func__, e->valid, e->next_hop);
- if (!e->valid)
- return 0;
-
- mac = ((u64)e->mac[0]) << 40 |
- ((u64)e->mac[1]) << 32 |
- ((u64)e->mac[2]) << 24 |
- ((u64)e->mac[3]) << 16 |
- ((u64)e->mac[4]) << 8 |
- ((u64)e->mac[5]);
-
- seed = rtl931x_l2_hash_seed(mac, e->rvid);
- pr_debug("%s: mac %016llx, seed %016llx\n", __func__, mac, seed);
-
- /* return vid with concatenated mac as unique id */
- return seed;
-}
-
-static u64 rtl931x_read_cam(int idx, struct rtl838x_l2_entry *e)
-{
- return 0;
-}
-
-static void rtl931x_write_cam(int idx, struct rtl838x_l2_entry *e)
-{
-}
-
-static void rtl931x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
-{
- u32 r[4];
- struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 0);
- u32 idx = (0 << 14) | (hash << 2) | pos; /* Access SRAM, with hash and at pos in bucket */
-
- pr_info("%s: hash %d, pos %d\n", __func__, hash, pos);
- pr_info("%s: index %d -> mac %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, idx,
- e->mac[0], e->mac[1], e->mac[2], e->mac[3],e->mac[4],e->mac[5]);
-
- rtl931x_fill_l2_row(r, e);
- pr_info("%s: %d: %08x %08x %08x\n", __func__, idx, r[0], r[1], r[2]);
-
- for (int i = 0; i < 4; i++)
- sw_w32(r[i], rtl_table_data(q, i));
-
- rtl_table_write(q, idx);
- rtl_table_release(q);
-}
-
-static void rtl931x_vlan_fwd_on_inner(int port, bool is_set)
-{
- /* Always set all tag modes to fwd based on either inner or outer tag */
- if (is_set)
- sw_w32_mask(0xf, 0, RTL931X_VLAN_PORT_FWD + (port << 2));
- else
- sw_w32_mask(0, 0xf, RTL931X_VLAN_PORT_FWD + (port << 2));
-}
-
-static void rtl931x_vlan_profile_setup(int profile)
-{
- u32 p[7];
-
- pr_info("In %s\n", __func__);
-
- if (profile > 15)
- return;
-
- p[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(profile));
-
- /* Enable routing of Ipv4/6 Unicast and IPv4/6 Multicast traffic */
- /* p[0] |= BIT(17) | BIT(16) | BIT(13) | BIT(12); */
- p[0] |= 0x3 << 11; /* COPY2CPU */
-
- p[1] = 0x1FFFFFF; /* L2 unknwon MC flooding portmask all ports, including the CPU-port */
- p[2] = 0xFFFFFFFF;
- p[3] = 0x1FFFFFF; /* IPv4 unknwon MC flooding portmask */
- p[4] = 0xFFFFFFFF;
- p[5] = 0x1FFFFFF; /* IPv6 unknwon MC flooding portmask */
- p[6] = 0xFFFFFFFF;
-
- for (int i = 0; i < 7; i++)
- sw_w32(p[i], RTL931X_VLAN_PROFILE_SET(profile) + i * 4);
- pr_info("Leaving %s\n", __func__);
-}
-
-static void rtl931x_l2_learning_setup(void)
-{
- /* Portmask for flooding broadcast traffic */
- rtl839x_set_port_reg_be(0x1FFFFFFFFFFFFFF, RTL931X_L2_BC_FLD_PMSK);
-
- /* Portmask for flooding unicast traffic with unknown destination */
- rtl839x_set_port_reg_be(0x1FFFFFFFFFFFFFF, RTL931X_L2_UNKN_UC_FLD_PMSK);
-
- /* Limit learning to maximum: 64k entries, after that just flood (bits 0-2) */
- sw_w32((0xffff << 3) | FORWARD, RTL931X_L2_LRN_CONSTRT_CTRL);
-}
-
-static u64 rtl931x_read_mcast_pmask(int idx)
-{
- u64 portmask;
- /* Read MC_PMSK (2) via register RTL9310_TBL_0 */
- struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 2);
-
- rtl_table_read(q, idx);
- portmask = sw_r32(rtl_table_data(q, 0));
- portmask <<= 32;
- portmask |= sw_r32(rtl_table_data(q, 1));
- portmask >>= 7;
- rtl_table_release(q);
-
- pr_debug("%s: Index idx %d has portmask %016llx\n", __func__, idx, portmask);
-
- return portmask;
-}
-
-static void rtl931x_write_mcast_pmask(int idx, u64 portmask)
-{
- u64 pm = portmask;
-
- /* Access MC_PMSK (2) via register RTL9310_TBL_0 */
- struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 2);
-
- pr_debug("%s: Index idx %d has portmask %016llx\n", __func__, idx, pm);
- pm <<= 7;
- sw_w32((u32)(pm >> 32), rtl_table_data(q, 0));
- sw_w32((u32)pm, rtl_table_data(q, 1));
- rtl_table_write(q, idx);
- rtl_table_release(q);
-}
-
-
-static int rtl931x_set_ageing_time(unsigned long msec)
-{
- int t = sw_r32(RTL931X_L2_AGE_CTRL);
-
- t &= 0x1FFFFF;
- t = (t * 8) / 10;
- pr_debug("L2 AGING time: %d sec\n", t);
-
- t = (msec / 100 + 7) / 8;
- t = t > 0x1FFFFF ? 0x1FFFFF : t;
- sw_w32_mask(0x1FFFFF, t, RTL931X_L2_AGE_CTRL);
- pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL931X_L2_PORT_AGE_CTRL));
-
- return 0;
-}
-void rtl931x_sw_init(struct rtl838x_switch_priv *priv)
-{
-/* rtl931x_sds_init(priv); */
-}
-
-static void rtl931x_pie_lookup_enable(struct rtl838x_switch_priv *priv, int index)
-{
- int block = index / PIE_BLOCK_SIZE;
-
- sw_w32_mask(0, BIT(block), RTL931X_PIE_BLK_LOOKUP_CTRL);
-}
-
-/* Fills the data in the intermediate representation in the pie_rule structure
- * into a data field for a given template field field_type
- * TODO: This function looks very similar to the function of the rtl9300, but
- * since it uses the physical template_field_id, which are different for each
- * SoC and there are other field types, it is actually not. If we would also use
- * an intermediate representation for a field type, we would could have one
- * pie_data_fill function for all SoCs, provided we have also for each SoC a
- * function to map between physical and intermediate field type
- */
-int rtl931x_pie_data_fill(enum template_field_id field_type, struct pie_rule *pr, u16 *data, u16 *data_m)
-{
- *data = *data_m = 0;
-
- switch (field_type) {
- case TEMPLATE_FIELD_SPM0:
- *data = pr->spm;
- *data_m = pr->spm_m;
- break;
- case TEMPLATE_FIELD_SPM1:
- *data = pr->spm >> 16;
- *data_m = pr->spm_m >> 16;
- break;
- case TEMPLATE_FIELD_OTAG:
- *data = pr->otag;
- *data_m = pr->otag_m;
- break;
- case TEMPLATE_FIELD_SMAC0:
- *data = pr->smac[4];
- *data = (*data << 8) | pr->smac[5];
- *data_m = pr->smac_m[4];
- *data_m = (*data_m << 8) | pr->smac_m[5];
- break;
- case TEMPLATE_FIELD_SMAC1:
- *data = pr->smac[2];
- *data = (*data << 8) | pr->smac[3];
- *data_m = pr->smac_m[2];
- *data_m = (*data_m << 8) | pr->smac_m[3];
- break;
- case TEMPLATE_FIELD_SMAC2:
- *data = pr->smac[0];
- *data = (*data << 8) | pr->smac[1];
- *data_m = pr->smac_m[0];
- *data_m = (*data_m << 8) | pr->smac_m[1];
- break;
- case TEMPLATE_FIELD_DMAC0:
- *data = pr->dmac[4];
- *data = (*data << 8) | pr->dmac[5];
- *data_m = pr->dmac_m[4];
- *data_m = (*data_m << 8) | pr->dmac_m[5];
- break;
- case TEMPLATE_FIELD_DMAC1:
- *data = pr->dmac[2];
- *data = (*data << 8) | pr->dmac[3];
- *data_m = pr->dmac_m[2];
- *data_m = (*data_m << 8) | pr->dmac_m[3];
- break;
- case TEMPLATE_FIELD_DMAC2:
- *data = pr->dmac[0];
- *data = (*data << 8) | pr->dmac[1];
- *data_m = pr->dmac_m[0];
- *data_m = (*data_m << 8) | pr->dmac_m[1];
- break;
- case TEMPLATE_FIELD_ETHERTYPE:
- *data = pr->ethertype;
- *data_m = pr->ethertype_m;
- break;
- case TEMPLATE_FIELD_ITAG:
- *data = pr->itag;
- *data_m = pr->itag_m;
- break;
- case TEMPLATE_FIELD_SIP0:
- if (pr->is_ipv6) {
- *data = pr->sip6.s6_addr16[7];
- *data_m = pr->sip6_m.s6_addr16[7];
- } else {
- *data = pr->sip;
- *data_m = pr->sip_m;
- }
- break;
- case TEMPLATE_FIELD_SIP1:
- if (pr->is_ipv6) {
- *data = pr->sip6.s6_addr16[6];
- *data_m = pr->sip6_m.s6_addr16[6];
- } else {
- *data = pr->sip >> 16;
- *data_m = pr->sip_m >> 16;
- }
- break;
- case TEMPLATE_FIELD_SIP2:
- case TEMPLATE_FIELD_SIP3:
- case TEMPLATE_FIELD_SIP4:
- case TEMPLATE_FIELD_SIP5:
- case TEMPLATE_FIELD_SIP6:
- case TEMPLATE_FIELD_SIP7:
- *data = pr->sip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)];
- *data_m = pr->sip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)];
- break;
- case TEMPLATE_FIELD_DIP0:
- if (pr->is_ipv6) {
- *data = pr->dip6.s6_addr16[7];
- *data_m = pr->dip6_m.s6_addr16[7];
- } else {
- *data = pr->dip;
- *data_m = pr->dip_m;
- }
- break;
- case TEMPLATE_FIELD_DIP1:
- if (pr->is_ipv6) {
- *data = pr->dip6.s6_addr16[6];
- *data_m = pr->dip6_m.s6_addr16[6];
- } else {
- *data = pr->dip >> 16;
- *data_m = pr->dip_m >> 16;
- }
- break;
- case TEMPLATE_FIELD_DIP2:
- case TEMPLATE_FIELD_DIP3:
- case TEMPLATE_FIELD_DIP4:
- case TEMPLATE_FIELD_DIP5:
- case TEMPLATE_FIELD_DIP6:
- case TEMPLATE_FIELD_DIP7:
- *data = pr->dip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)];
- *data_m = pr->dip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)];
- break;
- case TEMPLATE_FIELD_IP_TOS_PROTO:
- *data = pr->tos_proto;
- *data_m = pr->tos_proto_m;
- break;
- case TEMPLATE_FIELD_L4_SPORT:
- *data = pr->sport;
- *data_m = pr->sport_m;
- break;
- case TEMPLATE_FIELD_L4_DPORT:
- *data = pr->dport;
- *data_m = pr->dport_m;
- break;
- case TEMPLATE_FIELD_DSAP_SSAP:
- *data = pr->dsap_ssap;
- *data_m = pr->dsap_ssap_m;
- break;
- case TEMPLATE_FIELD_TCP_INFO:
- *data = pr->tcp_info;
- *data_m = pr->tcp_info_m;
- break;
- case TEMPLATE_FIELD_RANGE_CHK:
- pr_info("TEMPLATE_FIELD_RANGE_CHK: not configured\n");
- break;
- default:
- pr_info("%s: unknown field %d\n", __func__, field_type);
- return -1;
- }
-
- return 0;
-}
-
-/* Reads the intermediate representation of the templated match-fields of the
- * PIE rule in the pie_rule structure and fills in the raw data fields in the
- * raw register space r[].
- * The register space configuration size is identical for the RTL8380/90 and RTL9300,
- * however the RTL931X has 2 more registers / fields and the physical field-ids are different
- * on all SoCs
- * On the RTL9300 the mask fields are not word-aligend!
- */
-static void rtl931x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[])
-{
- for (int i = 0; i < N_FIXED_FIELDS; i++) {
- u16 data, data_m;
-
- rtl931x_pie_data_fill(t[i], pr, &data, &data_m);
-
- /* On the RTL9300, the mask fields are not word aligned! */
- if (!(i % 2)) {
- r[5 - i / 2] = data;
- r[12 - i / 2] |= ((u32)data_m << 8);
- } else {
- r[5 - i / 2] |= ((u32)data) << 16;
- r[12 - i / 2] |= ((u32)data_m) << 24;
- r[11 - i / 2] |= ((u32)data_m) >> 8;
- }
- }
-}
-
-// Currently unused
-// static void rtl931x_read_pie_fixed_fields(u32 r[], struct pie_rule *pr)
-// {
-// pr->mgnt_vlan = r[7] & BIT(31);
-// if (pr->phase == PHASE_IACL)
-// pr->dmac_hit_sw = r[7] & BIT(30);
-// else /* TODO: EACL/VACL phase handling */
-// pr->content_too_deep = r[7] & BIT(30);
-// pr->not_first_frag = r[7] & BIT(29);
-// pr->frame_type_l4 = (r[7] >> 26) & 7;
-// pr->frame_type = (r[7] >> 24) & 3;
-// pr->otag_fmt = (r[7] >> 23) & 1;
-// pr->itag_fmt = (r[7] >> 22) & 1;
-// pr->otag_exist = (r[7] >> 21) & 1;
-// pr->itag_exist = (r[7] >> 20) & 1;
-// pr->frame_type_l2 = (r[7] >> 18) & 3;
-// pr->igr_normal_port = (r[7] >> 17) & 1;
-// pr->tid = (r[7] >> 16) & 1;
-
-// pr->mgnt_vlan_m = r[14] & BIT(15);
-// if (pr->phase == PHASE_IACL)
-// pr->dmac_hit_sw_m = r[14] & BIT(14);
-// else
-// pr->content_too_deep_m = r[14] & BIT(14);
-// pr->not_first_frag_m = r[14] & BIT(13);
-// pr->frame_type_l4_m = (r[14] >> 10) & 7;
-// pr->frame_type_m = (r[14] >> 8) & 3;
-// pr->otag_fmt_m = r[14] & BIT(7);
-// pr->itag_fmt_m = r[14] & BIT(6);
-// pr->otag_exist_m = r[14] & BIT(5);
-// pr->itag_exist_m = r[14] & BIT (4);
-// pr->frame_type_l2_m = (r[14] >> 2) & 3;
-// pr->igr_normal_port_m = r[14] & BIT(1);
-// pr->tid_m = r[14] & 1;
-
-// pr->valid = r[15] & BIT(31);
-// pr->cond_not = r[15] & BIT(30);
-// pr->cond_and1 = r[15] & BIT(29);
-// pr->cond_and2 = r[15] & BIT(28);
-// }
-
-static void rtl931x_write_pie_fixed_fields(u32 r[], struct pie_rule *pr)
-{
- r[7] |= pr->mgnt_vlan ? BIT(31) : 0;
- if (pr->phase == PHASE_IACL)
- r[7] |= pr->dmac_hit_sw ? BIT(30) : 0;
- else
- r[7] |= pr->content_too_deep ? BIT(30) : 0;
- r[7] |= pr->not_first_frag ? BIT(29) : 0;
- r[7] |= ((u32) (pr->frame_type_l4 & 0x7)) << 26;
- r[7] |= ((u32) (pr->frame_type & 0x3)) << 24;
- r[7] |= pr->otag_fmt ? BIT(23) : 0;
- r[7] |= pr->itag_fmt ? BIT(22) : 0;
- r[7] |= pr->otag_exist ? BIT(21) : 0;
- r[7] |= pr->itag_exist ? BIT(20) : 0;
- r[7] |= ((u32) (pr->frame_type_l2 & 0x3)) << 18;
- r[7] |= pr->igr_normal_port ? BIT(17) : 0;
- r[7] |= ((u32) (pr->tid & 0x1)) << 16;
-
- r[14] |= pr->mgnt_vlan_m ? BIT(15) : 0;
- if (pr->phase == PHASE_IACL)
- r[14] |= pr->dmac_hit_sw_m ? BIT(14) : 0;
- else
- r[14] |= pr->content_too_deep_m ? BIT(14) : 0;
- r[14] |= pr->not_first_frag_m ? BIT(13) : 0;
- r[14] |= ((u32) (pr->frame_type_l4_m & 0x7)) << 10;
- r[14] |= ((u32) (pr->frame_type_m & 0x3)) << 8;
- r[14] |= pr->otag_fmt_m ? BIT(7) : 0;
- r[14] |= pr->itag_fmt_m ? BIT(6) : 0;
- r[14] |= pr->otag_exist_m ? BIT(5) : 0;
- r[14] |= pr->itag_exist_m ? BIT(4) : 0;
- r[14] |= ((u32) (pr->frame_type_l2_m & 0x3)) << 2;
- r[14] |= pr->igr_normal_port_m ? BIT(1) : 0;
- r[14] |= (u32) (pr->tid_m & 0x1);
-
- r[15] |= pr->valid ? BIT(31) : 0;
- r[15] |= pr->cond_not ? BIT(30) : 0;
- r[15] |= pr->cond_and1 ? BIT(29) : 0;
- r[15] |= pr->cond_and2 ? BIT(28) : 0;
-}
-
-static void rtl931x_write_pie_action(u32 r[], struct pie_rule *pr)
-{
- /* Either drop or forward */
- if (pr->drop) {
- r[15] |= BIT(11) | BIT(12) | BIT(13); /* Do Green, Yellow and Red drops */
- /* Actually DROP, not PERMIT in Green / Yellow / Red */
- r[16] |= BIT(27) | BIT(28) | BIT(29);
- } else {
- r[15] |= pr->fwd_sel ? BIT(14) : 0;
- r[16] |= pr->fwd_act << 24;
- r[16] |= BIT(21); /* We overwrite any drop */
- }
- if (pr->phase == PHASE_VACL)
- r[16] |= pr->fwd_sa_lrn ? BIT(22) : 0;
- r[15] |= pr->bypass_sel ? BIT(10) : 0;
- r[15] |= pr->nopri_sel ? BIT(21) : 0;
- r[15] |= pr->tagst_sel ? BIT(20) : 0;
- r[15] |= pr->ovid_sel ? BIT(18) : 0;
- r[15] |= pr->ivid_sel ? BIT(16) : 0;
- r[15] |= pr->meter_sel ? BIT(27) : 0;
- r[15] |= pr->mir_sel ? BIT(15) : 0;
- r[15] |= pr->log_sel ? BIT(26) : 0;
-
- r[16] |= ((u32)(pr->fwd_data & 0xfff)) << 9;
-/* r[15] |= pr->log_octets ? BIT(31) : 0; */
- r[15] |= (u32)(pr->meter_data) >> 2;
- r[16] |= (((u32)(pr->meter_data) >> 7) & 0x3) << 29;
-
- r[16] |= ((u32)(pr->ivid_act & 0x3)) << 21;
- r[15] |= ((u32)(pr->ivid_data & 0xfff)) << 9;
- r[16] |= ((u32)(pr->ovid_act & 0x3)) << 30;
- r[16] |= ((u32)(pr->ovid_data & 0xfff)) << 16;
- r[16] |= ((u32)(pr->mir_data & 0x3)) << 6;
- r[17] |= ((u32)(pr->tagst_data & 0xf)) << 28;
- r[17] |= ((u32)(pr->nopri_data & 0x7)) << 25;
- r[17] |= pr->bypass_ibc_sc ? BIT(16) : 0;
-}
-
-void rtl931x_pie_rule_dump_raw(u32 r[])
-{
- pr_info("Raw IACL table entry:\n");
- pr_info("r 0 - 7: %08x %08x %08x %08x %08x %08x %08x %08x\n",
- r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
- pr_info("r 8 - 15: %08x %08x %08x %08x %08x %08x %08x %08x\n",
- r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
- pr_info("r 16 - 18: %08x %08x %08x\n", r[16], r[17], r[18]);
- pr_info("Match : %08x %08x %08x %08x %08x %08x\n", r[0], r[1], r[2], r[3], r[4], r[5]);
- pr_info("Fixed : %06x\n", r[6] >> 8);
- pr_info("Match M: %08x %08x %08x %08x %08x %08x\n",
- (r[6] << 24) | (r[7] >> 8), (r[7] << 24) | (r[8] >> 8), (r[8] << 24) | (r[9] >> 8),
- (r[9] << 24) | (r[10] >> 8), (r[10] << 24) | (r[11] >> 8),
- (r[11] << 24) | (r[12] >> 8));
- pr_info("R[13]: %08x\n", r[13]);
- pr_info("Fixed M: %06x\n", ((r[12] << 16) | (r[13] >> 16)) & 0xffffff);
- pr_info("Valid / not / and1 / and2 : %1x\n", (r[13] >> 12) & 0xf);
- pr_info("r 13-16: %08x %08x %08x %08x\n", r[13], r[14], r[15], r[16]);
-}
-
-static int rtl931x_pie_rule_write(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr)
-{
- /* Access IACL table (0) via register 1, the table size is 4096 */
- struct table_reg *q = rtl_table_get(RTL9310_TBL_1, 0);
- u32 r[22];
- int block = idx / PIE_BLOCK_SIZE;
- u32 t_select = sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block));
-
- pr_info("%s: %d, t_select: %08x\n", __func__, idx, t_select);
-
- for (int i = 0; i < 22; i++)
- r[i] = 0;
-
- if (!pr->valid) {
- rtl_table_write(q, idx);
- rtl_table_release(q);
- return 0;
- }
- rtl931x_write_pie_fixed_fields(r, pr);
-
- pr_info("%s: template %d\n", __func__, (t_select >> (pr->tid * 4)) & 0xf);
- rtl931x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 4)) & 0xf]);
-
- rtl931x_write_pie_action(r, pr);
-
- rtl931x_pie_rule_dump_raw(r);
-
- for (int i = 0; i < 22; i++)
- sw_w32(r[i], rtl_table_data(q, i));
-
- rtl_table_write(q, idx);
- rtl_table_release(q);
-
- return 0;
-}
-
-static bool rtl931x_pie_templ_has(int t, enum template_field_id field_type)
-{
- for (int i = 0; i < N_FIXED_FIELDS_RTL931X; i++) {
- enum template_field_id ft = fixed_templates[t][i];
- if (field_type == ft)
- return true;
- }
-
- return false;
-}
-
-/* Verify that the rule pr is compatible with a given template t in block block
- * Note that this function is SoC specific since the values of e.g. TEMPLATE_FIELD_SIP0
- * depend on the SoC
- */
-static int rtl931x_pie_verify_template(struct rtl838x_switch_priv *priv,
- struct pie_rule *pr, int t, int block)
-{
- int i;
-
- if (!pr->is_ipv6 && pr->sip_m && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SIP0))
- return -1;
-
- if (!pr->is_ipv6 && pr->dip_m && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DIP0))
- return -1;
-
- if (pr->is_ipv6) {
- if ((pr->sip6_m.s6_addr32[0] ||
- pr->sip6_m.s6_addr32[1] ||
- pr->sip6_m.s6_addr32[2] ||
- pr->sip6_m.s6_addr32[3]) &&
- !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SIP2))
- return -1;
- if ((pr->dip6_m.s6_addr32[0] ||
- pr->dip6_m.s6_addr32[1] ||
- pr->dip6_m.s6_addr32[2] ||
- pr->dip6_m.s6_addr32[3]) &&
- !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DIP2))
- return -1;
- }
-
- if (ether_addr_to_u64(pr->smac) && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SMAC0))
- return -1;
-
- if (ether_addr_to_u64(pr->dmac) && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DMAC0))
- return -1;
-
- /* TODO: Check more */
-
- i = find_first_zero_bit(&priv->pie_use_bm[block * 4], PIE_BLOCK_SIZE);
-
- if (i >= PIE_BLOCK_SIZE)
- return -1;
-
- return i + PIE_BLOCK_SIZE * block;
-}
-
-static int rtl931x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr)
-{
- int idx, block, j;
- int min_block = 0;
- int max_block = priv->n_pie_blocks / 2;
-
- if (pr->is_egress) {
- min_block = max_block;
- max_block = priv->n_pie_blocks;
- }
- pr_info("In %s\n", __func__);
-
- mutex_lock(&priv->pie_mutex);
-
- for (block = min_block; block < max_block; block++) {
- for (j = 0; j < 2; j++) {
- int t = (sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block)) >> (j * 4)) & 0xf;
- pr_info("Testing block %d, template %d, template id %d\n", block, j, t);
- pr_info("%s: %08x\n",
- __func__, sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block)));
- idx = rtl931x_pie_verify_template(priv, pr, t, block);
- if (idx >= 0)
- break;
- }
- if (j < 2)
- break;
- }
-
- if (block >= priv->n_pie_blocks) {
- mutex_unlock(&priv->pie_mutex);
- return -EOPNOTSUPP;
- }
-
- pr_info("Using block: %d, index %d, template-id %d\n", block, idx, j);
- set_bit(idx, priv->pie_use_bm);
-
- pr->valid = true;
- pr->tid = j; /* Mapped to template number */
- pr->tid_m = 0x1;
- pr->id = idx;
-
- rtl931x_pie_lookup_enable(priv, idx);
- rtl931x_pie_rule_write(priv, idx, pr);
-
- mutex_unlock(&priv->pie_mutex);
-
- return 0;
-}
-
-/* Delete a range of Packet Inspection Engine rules */
-static int rtl931x_pie_rule_del(struct rtl838x_switch_priv *priv, int index_from, int index_to)
-{
- u32 v = (index_from << 1)| (index_to << 13 ) | BIT(0);
-
- pr_info("%s: from %d to %d\n", __func__, index_from, index_to);
- mutex_lock(&priv->reg_mutex);
-
- /* Write from-to and execute bit into control register */
- sw_w32(v, RTL931X_PIE_CLR_CTRL);
-
- /* Wait until command has completed */
- do {
- } while (sw_r32(RTL931X_PIE_CLR_CTRL) & BIT(0));
-
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
-static void rtl931x_pie_rule_rm(struct rtl838x_switch_priv *priv, struct pie_rule *pr)
-{
- int idx = pr->id;
-
- rtl931x_pie_rule_del(priv, idx, idx);
- clear_bit(idx, priv->pie_use_bm);
-}
-
-static void rtl931x_pie_init(struct rtl838x_switch_priv *priv)
-{
- u32 template_selectors;
-
- mutex_init(&priv->pie_mutex);
-
- pr_info("%s\n", __func__);
- /* Enable ACL lookup on all ports, including CPU_PORT */
- for (int i = 0; i <= priv->cpu_port; i++)
- sw_w32(1, RTL931X_ACL_PORT_LOOKUP_CTRL(i));
-
- /* Include IPG in metering */
- sw_w32_mask(0, 1, RTL931X_METER_GLB_CTRL);
-
- /* Delete all present rules, block size is 128 on all SoC families */
- rtl931x_pie_rule_del(priv, 0, priv->n_pie_blocks * 128 - 1);
-
- /* Assign first half blocks 0-7 to VACL phase, second half to IACL */
- /* 3 bits are used for each block, values for PIE blocks are */
- /* 6: Disabled, 0: VACL, 1: IACL, 2: EACL */
- /* And for OpenFlow Flow blocks: 3: Ingress Flow table 0, */
- /* 4: Ingress Flow Table 3, 5: Egress flow table 0 */
- for (int i = 0; i < priv->n_pie_blocks; i++) {
- int pos = (i % 10) * 3;
- u32 r = RTL931X_PIE_BLK_PHASE_CTRL + 4 * (i / 10);
-
- if (i < priv->n_pie_blocks / 2)
- sw_w32_mask(0x7 << pos, 0, r);
- else
- sw_w32_mask(0x7 << pos, 1 << pos, r);
- }
-
- /* Enable predefined templates 0, 1 for first quarter of all blocks */
- template_selectors = 0 | (1 << 4);
- for (int i = 0; i < priv->n_pie_blocks / 4; i++)
- sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
-
- /* Enable predefined templates 2, 3 for second quarter of all blocks */
- template_selectors = 2 | (3 << 4);
- for (int i = priv->n_pie_blocks / 4; i < priv->n_pie_blocks / 2; i++)
- sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
-
- /* Enable predefined templates 0, 1 for third quater of all blocks */
- template_selectors = 0 | (1 << 4);
- for (int i = priv->n_pie_blocks / 2; i < priv->n_pie_blocks * 3 / 4; i++)
- sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
-
- /* Enable predefined templates 2, 3 for fourth quater of all blocks */
- template_selectors = 2 | (3 << 4);
- for (int i = priv->n_pie_blocks * 3 / 4; i < priv->n_pie_blocks; i++)
- sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
-
-}
-
-int rtl931x_l3_setup(struct rtl838x_switch_priv *priv)
-{
- return 0;
-}
-
-void rtl931x_vlan_port_keep_tag_set(int port, bool keep_outer, bool keep_inner)
-{
- sw_w32(FIELD_PREP(RTL931X_VLAN_PORT_TAG_EGR_OTAG_STS_MASK,
- keep_outer ? RTL931X_VLAN_PORT_TAG_STS_TAGGED : RTL931X_VLAN_PORT_TAG_STS_UNTAG) |
- FIELD_PREP(RTL931X_VLAN_PORT_TAG_EGR_ITAG_STS_MASK,
- keep_inner ? RTL931X_VLAN_PORT_TAG_STS_TAGGED : RTL931X_VLAN_PORT_TAG_STS_UNTAG),
- RTL931X_VLAN_PORT_TAG_CTRL(port));
-}
-
-void rtl931x_vlan_port_pvidmode_set(int port, enum pbvlan_type type, enum pbvlan_mode mode)
-{
- if (type == PBVLAN_TYPE_INNER)
- sw_w32_mask(0x3 << 12, mode << 12, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
- else
- sw_w32_mask(0x3 << 26, mode << 26, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
-}
-
-void rtl931x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid)
-{
- if (type == PBVLAN_TYPE_INNER)
- sw_w32_mask(0xfff, pvid, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
- else
- sw_w32_mask(0xfff << 14, pvid << 14, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
-}
-
-static void rtl931x_set_igr_filter(int port, enum igr_filter state)
-{
- sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1),
- RTL931X_VLAN_PORT_IGR_FLTR + (((port >> 4) << 2)));
-}
-
-static void rtl931x_set_egr_filter(int port, enum egr_filter state)
-{
- sw_w32_mask(0x1 << (port % 0x20), state << (port % 0x20),
- RTL931X_VLAN_PORT_EGR_FLTR + (((port >> 5) << 2)));
-}
-
-void rtl931x_set_distribution_algorithm(int group, int algoidx, u32 algomsk)
-{
- u32 l3shift = 0;
- u32 newmask = 0;
-
- /* TODO: for now we set algoidx to 0 */
- algoidx = 0;
-
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_SIP_BIT) {
- l3shift = 4;
- newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SIP_BIT;
- }
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_DIP_BIT) {
- l3shift = 4;
- newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DIP_BIT;
- }
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) {
- l3shift = 4;
- newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT;
- }
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) {
- l3shift = 4;
- newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT;
- }
-
- if (l3shift == 4) {
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT)
- newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SMAC_BIT;
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT)
- newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DMAC_BIT;
- } else {
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT)
- newmask |= TRUNK_DISTRIBUTION_ALGO_L2_SMAC_BIT;
- if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT)
- newmask |= TRUNK_DISTRIBUTION_ALGO_L2_DMAC_BIT;
- }
-
- sw_w32(newmask << l3shift, RTL931X_TRK_HASH_CTRL + (algoidx << 2));
-}
-
-static void rtl931x_led_init(struct rtl838x_switch_priv *priv)
-{
- u64 pm_copper = 0, pm_fiber = 0;
- struct device_node *node;
-
- pr_info("%s called\n", __func__);
- node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds");
- if (!node) {
- pr_info("%s No compatible LED node found\n", __func__);
- return;
- }
-
- for (int i = 0; i < priv->cpu_port; i++) {
- int pos = (i << 1) % 32;
- u32 set;
- u32 v;
-
- sw_w32_mask(0x3 << pos, 0, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i));
- sw_w32_mask(0x3 << pos, 0, RTL931X_LED_PORT_COPR_SET_SEL_CTRL(i));
-
- if (!priv->ports[i].phy)
- continue;
-
- v = 0x1; /* Found on the EdgeCore, but we do not have any HW description */
- sw_w32_mask(0x3 << pos, v << pos, RTL931X_LED_PORT_NUM_CTRL(i));
-
- if (priv->ports[i].phy_is_integrated)
- pm_fiber |= BIT_ULL(i);
- else
- pm_copper |= BIT_ULL(i);
-
- set = priv->ports[i].led_set;
- sw_w32_mask(0, set << pos, RTL931X_LED_PORT_COPR_SET_SEL_CTRL(i));
- sw_w32_mask(0, set << pos, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i));
- }
-
- for (int i = 0; i < 4; i++) {
- const __be32 *led_set;
- char set_name[9];
- u32 setlen;
- u32 v;
-
- sprintf(set_name, "led_set%d", i);
- pr_info(">%s<\n", set_name);
- led_set = of_get_property(node, set_name, &setlen);
- if (!led_set || setlen != 16)
- break;
- v = be32_to_cpup(led_set) << 16 | be32_to_cpup(led_set + 1);
- sw_w32(v, RTL931X_LED_SET0_0_CTRL - 4 - i * 8);
- v = be32_to_cpup(led_set + 2) << 16 | be32_to_cpup(led_set + 3);
- sw_w32(v, RTL931X_LED_SET0_0_CTRL - i * 8);
- }
-
- /* Set LED mode to serial (0x1) */
- sw_w32_mask(0x3, 0x1, RTL931X_LED_GLB_CTRL);
-
- rtl839x_set_port_reg_le(pm_copper, RTL931X_LED_PORT_COPR_MASK_CTRL);
- rtl839x_set_port_reg_le(pm_fiber, RTL931X_LED_PORT_FIB_MASK_CTRL);
- rtl839x_set_port_reg_le(pm_copper | pm_fiber, RTL931X_LED_PORT_COMBO_MASK_CTRL);
-
- for (int i = 0; i < 32; i++)
- pr_info("%s %08x: %08x\n",__func__, 0xbb000600 + i * 4, sw_r32(0x0600 + i * 4));
-}
-
-const struct rtl838x_reg rtl931x_reg = {
- .mask_port_reg_be = rtl839x_mask_port_reg_be,
- .set_port_reg_be = rtl839x_set_port_reg_be,
- .get_port_reg_be = rtl839x_get_port_reg_be,
- .mask_port_reg_le = rtl839x_mask_port_reg_le,
- .set_port_reg_le = rtl839x_set_port_reg_le,
- .get_port_reg_le = rtl839x_get_port_reg_le,
- .stat_port_rst = RTL931X_STAT_PORT_RST,
- .stat_rst = RTL931X_STAT_RST,
- .stat_port_std_mib = 0, /* Not defined */
- .traffic_enable = rtl931x_traffic_enable,
- .traffic_disable = rtl931x_traffic_disable,
- .traffic_get = rtl931x_traffic_get,
- .traffic_set = rtl931x_traffic_set,
- .l2_ctrl_0 = RTL931X_L2_CTRL,
- .l2_ctrl_1 = RTL931X_L2_AGE_CTRL,
- .l2_port_aging_out = RTL931X_L2_PORT_AGE_CTRL,
- .set_ageing_time = rtl931x_set_ageing_time,
- /* .smi_poll_ctrl does not exist */
- .l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL,
- .exec_tbl0_cmd = rtl931x_exec_tbl0_cmd,
- .exec_tbl1_cmd = rtl931x_exec_tbl1_cmd,
- .tbl_access_data_0 = rtl931x_tbl_access_data_0,
- .isr_glb_src = RTL931X_ISR_GLB_SRC,
- .isr_port_link_sts_chg = RTL931X_ISR_PORT_LINK_STS_CHG,
- .imr_port_link_sts_chg = RTL931X_IMR_PORT_LINK_STS_CHG,
- /* imr_glb does not exist on RTL931X */
- .vlan_tables_read = rtl931x_vlan_tables_read,
- .vlan_set_tagged = rtl931x_vlan_set_tagged,
- .vlan_set_untagged = rtl931x_vlan_set_untagged,
- .vlan_profile_dump = rtl931x_vlan_profile_dump,
- .vlan_profile_setup = rtl931x_vlan_profile_setup,
- .vlan_fwd_on_inner = rtl931x_vlan_fwd_on_inner,
- .stp_get = rtl931x_stp_get,
- .stp_set = rtl931x_stp_set,
- .mac_force_mode_ctrl = rtl931x_mac_force_mode_ctrl,
- .mac_port_ctrl = rtl931x_mac_port_ctrl,
- .l2_port_new_salrn = rtl931x_l2_port_new_salrn,
- .l2_port_new_sa_fwd = rtl931x_l2_port_new_sa_fwd,
- .mir_ctrl = RTL931X_MIR_CTRL,
- .mir_dpm = RTL931X_MIR_DPM_CTRL,
- .mir_spm = RTL931X_MIR_SPM_CTRL,
- .mac_link_sts = RTL931X_MAC_LINK_STS,
- .mac_link_dup_sts = RTL931X_MAC_LINK_DUP_STS,
- .mac_link_spd_sts = rtl931x_mac_link_spd_sts,
- .mac_rx_pause_sts = RTL931X_MAC_RX_PAUSE_STS,
- .mac_tx_pause_sts = RTL931X_MAC_TX_PAUSE_STS,
- .read_l2_entry_using_hash = rtl931x_read_l2_entry_using_hash,
- .write_l2_entry_using_hash = rtl931x_write_l2_entry_using_hash,
- .read_cam = rtl931x_read_cam,
- .write_cam = rtl931x_write_cam,
- .vlan_port_keep_tag_set = rtl931x_vlan_port_keep_tag_set,
- .vlan_port_pvidmode_set = rtl931x_vlan_port_pvidmode_set,
- .vlan_port_pvid_set = rtl931x_vlan_port_pvid_set,
- .trk_mbr_ctr = rtl931x_trk_mbr_ctr,
- .set_vlan_igr_filter = rtl931x_set_igr_filter,
- .set_vlan_egr_filter = rtl931x_set_egr_filter,
- .set_distribution_algorithm = rtl931x_set_distribution_algorithm,
- .l2_hash_key = rtl931x_l2_hash_key,
- .read_mcast_pmask = rtl931x_read_mcast_pmask,
- .write_mcast_pmask = rtl931x_write_mcast_pmask,
- .pie_init = rtl931x_pie_init,
- .pie_rule_write = rtl931x_pie_rule_write,
- .pie_rule_add = rtl931x_pie_rule_add,
- .pie_rule_rm = rtl931x_pie_rule_rm,
- .l2_learning_setup = rtl931x_l2_learning_setup,
- .l3_setup = rtl931x_l3_setup,
- .led_init = rtl931x_led_init,
-};
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c
deleted file mode 100644
index 3f7c31e04d..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c
+++ /dev/null
@@ -1,410 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include <net/dsa.h>
-#include <linux/delay.h>
-#include <linux/etherdevice.h>
-#include <linux/netdevice.h>
-#include <net/flow_offload.h>
-#include <linux/rhashtable.h>
-#include <asm/mach-rtl838x/mach-rtl83xx.h>
-
-#include "rtl83xx.h"
-#include "rtl838x.h"
-
-/* Parse the flow rule for the matching conditions */
-static int rtl83xx_parse_flow_rule(struct rtl838x_switch_priv *priv,
- struct flow_rule *rule, struct rtl83xx_flow *flow)
-{
- struct flow_dissector *dissector = rule->match.dissector;
-
- pr_debug("In %s\n", __func__);
- /* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */
- if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 ||
- (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) {
- pr_err("Cannot form TC key: used_keys = 0x%x\n", dissector->used_keys);
- return -EOPNOTSUPP;
- }
-
- if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
- struct flow_match_basic match;
-
- pr_debug("%s: BASIC\n", __func__);
- flow_rule_match_basic(rule, &match);
- if (match.key->n_proto == htons(ETH_P_ARP))
- flow->rule.frame_type = 0;
- if (match.key->n_proto == htons(ETH_P_IP))
- flow->rule.frame_type = 2;
- if (match.key->n_proto == htons(ETH_P_IPV6))
- flow->rule.frame_type = 3;
- if ((match.key->n_proto == htons(ETH_P_ARP)) || flow->rule.frame_type)
- flow->rule.frame_type_m = 3;
- if (flow->rule.frame_type >= 2) {
- if (match.key->ip_proto == IPPROTO_UDP)
- flow->rule.frame_type_l4 = 0;
- if (match.key->ip_proto == IPPROTO_TCP)
- flow->rule.frame_type_l4 = 1;
- if (match.key->ip_proto == IPPROTO_ICMP || match.key->ip_proto == IPPROTO_ICMPV6)
- flow->rule.frame_type_l4 = 2;
- if (match.key->ip_proto == IPPROTO_TCP)
- flow->rule.frame_type_l4 = 3;
- if ((match.key->ip_proto == IPPROTO_UDP) || flow->rule.frame_type_l4)
- flow->rule.frame_type_l4_m = 7;
- }
- }
-
- if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
- struct flow_match_eth_addrs match;
-
- pr_debug("%s: ETH_ADDR\n", __func__);
- flow_rule_match_eth_addrs(rule, &match);
- ether_addr_copy(flow->rule.dmac, match.key->dst);
- ether_addr_copy(flow->rule.dmac_m, match.mask->dst);
- ether_addr_copy(flow->rule.smac, match.key->src);
- ether_addr_copy(flow->rule.smac_m, match.mask->src);
- }
-
- if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
- struct flow_match_vlan match;
-
- pr_debug("%s: VLAN\n", __func__);
- flow_rule_match_vlan(rule, &match);
- flow->rule.itag = match.key->vlan_id;
- flow->rule.itag_m = match.mask->vlan_id;
- /* TODO: What about match.key->vlan_priority? */
- }
-
- if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
- struct flow_match_ipv4_addrs match;
-
- pr_debug("%s: IPV4\n", __func__);
- flow_rule_match_ipv4_addrs(rule, &match);
- flow->rule.is_ipv6 = false;
- flow->rule.dip = match.key->dst;
- flow->rule.dip_m = match.mask->dst;
- flow->rule.sip = match.key->src;
- flow->rule.sip_m = match.mask->src;
- } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
- struct flow_match_ipv6_addrs match;
-
- pr_debug("%s: IPV6\n", __func__);
- flow->rule.is_ipv6 = true;
- flow_rule_match_ipv6_addrs(rule, &match);
- flow->rule.dip6 = match.key->dst;
- flow->rule.dip6_m = match.mask->dst;
- flow->rule.sip6 = match.key->src;
- flow->rule.sip6_m = match.mask->src;
- }
-
- if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
- struct flow_match_ports match;
-
- pr_debug("%s: PORTS\n", __func__);
- flow_rule_match_ports(rule, &match);
- flow->rule.dport = match.key->dst;
- flow->rule.dport_m = match.mask->dst;
- flow->rule.sport = match.key->src;
- flow->rule.sport_m = match.mask->src;
- }
-
- /* TODO: ICMP */
- return 0;
-}
-
-static void rtl83xx_flow_bypass_all(struct rtl83xx_flow *flow)
-{
- flow->rule.bypass_sel = true;
- flow->rule.bypass_all = true;
- flow->rule.bypass_igr_stp = true;
- flow->rule.bypass_ibc_sc = true;
-}
-
-static int rtl83xx_parse_fwd(struct rtl838x_switch_priv *priv,
- const struct flow_action_entry *act, struct rtl83xx_flow *flow)
-{
- struct net_device *dev = act->dev;
- int port;
-
- port = rtl83xx_port_is_under(dev, priv);
- if (port < 0) {
- netdev_info(dev, "%s: not a DSA device.\n", __func__);
- return -EINVAL;
- }
-
- flow->rule.fwd_sel = true;
- flow->rule.fwd_data = port;
- pr_debug("Using port index: %d\n", port);
- rtl83xx_flow_bypass_all(flow);
-
- return 0;
-}
-
-static int rtl83xx_add_flow(struct rtl838x_switch_priv *priv, struct flow_cls_offload *f,
- struct rtl83xx_flow *flow)
-{
- struct flow_rule *rule = flow_cls_offload_flow_rule(f);
- const struct flow_action_entry *act;
- int i, err;
-
- pr_debug("%s\n", __func__);
-
- rtl83xx_parse_flow_rule(priv, rule, flow);
-
- flow_action_for_each(i, act, &rule->action) {
- switch (act->id) {
- case FLOW_ACTION_DROP:
- pr_debug("%s: DROP\n", __func__);
- flow->rule.drop = true;
- rtl83xx_flow_bypass_all(flow);
- return 0;
-
- case FLOW_ACTION_TRAP:
- pr_debug("%s: TRAP\n", __func__);
- flow->rule.fwd_data = priv->cpu_port;
- flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT;
- rtl83xx_flow_bypass_all(flow);
- break;
-
- case FLOW_ACTION_MANGLE:
- pr_err("%s: FLOW_ACTION_MANGLE not supported\n", __func__);
- return -EOPNOTSUPP;
-
- case FLOW_ACTION_ADD:
- pr_err("%s: FLOW_ACTION_ADD not supported\n", __func__);
- return -EOPNOTSUPP;
-
- case FLOW_ACTION_VLAN_PUSH:
- pr_debug("%s: VLAN_PUSH\n", __func__);
-/* TODO: act->vlan.proto */
- flow->rule.ivid_act = PIE_ACT_VID_ASSIGN;
- flow->rule.ivid_sel = true;
- flow->rule.ivid_data = htons(act->vlan.vid);
- flow->rule.ovid_act = PIE_ACT_VID_ASSIGN;
- flow->rule.ovid_sel = true;
- flow->rule.ovid_data = htons(act->vlan.vid);
- flow->rule.fwd_mod_to_cpu = true;
- break;
-
- case FLOW_ACTION_VLAN_POP:
- pr_debug("%s: VLAN_POP\n", __func__);
- flow->rule.ivid_act = PIE_ACT_VID_ASSIGN;
- flow->rule.ivid_data = 0;
- flow->rule.ivid_sel = true;
- flow->rule.ovid_act = PIE_ACT_VID_ASSIGN;
- flow->rule.ovid_data = 0;
- flow->rule.ovid_sel = true;
- flow->rule.fwd_mod_to_cpu = true;
- break;
-
- case FLOW_ACTION_CSUM:
- pr_err("%s: FLOW_ACTION_CSUM not supported\n", __func__);
- return -EOPNOTSUPP;
-
- case FLOW_ACTION_REDIRECT:
- pr_debug("%s: REDIRECT\n", __func__);
- err = rtl83xx_parse_fwd(priv, act, flow);
- if (err)
- return err;
- flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT;
- break;
-
- case FLOW_ACTION_MIRRED:
- pr_debug("%s: MIRRED\n", __func__);
- err = rtl83xx_parse_fwd(priv, act, flow);
- if (err)
- return err;
- flow->rule.fwd_act = PIE_ACT_COPY_TO_PORT;
- break;
-
- default:
- pr_err("%s: Flow action not supported: %d\n", __func__, act->id);
- return -EOPNOTSUPP;
- }
- }
-
- return 0;
-}
-
-static const struct rhashtable_params tc_ht_params = {
- .head_offset = offsetof(struct rtl83xx_flow, node),
- .key_offset = offsetof(struct rtl83xx_flow, cookie),
- .key_len = sizeof(((struct rtl83xx_flow *)0)->cookie),
- .automatic_shrinking = true,
-};
-
-static int rtl83xx_configure_flower(struct rtl838x_switch_priv *priv,
- struct flow_cls_offload *f)
-{
- struct rtl83xx_flow *flow;
- int err = 0;
-
- pr_debug("In %s\n", __func__);
-
- rcu_read_lock();
- pr_debug("Cookie %08lx\n", f->cookie);
- flow = rhashtable_lookup(&priv->tc_ht, &f->cookie, tc_ht_params);
- if (flow) {
- pr_info("%s: Got flow\n", __func__);
- err = -EEXIST;
- goto rcu_unlock;
- }
-
-rcu_unlock:
- rcu_read_unlock();
- if (flow)
- goto out;
- pr_debug("%s: New flow\n", __func__);
-
- flow = kzalloc(sizeof(*flow), GFP_KERNEL);
- if (!flow) {
- err = -ENOMEM;
- goto out;
- }
-
- flow->cookie = f->cookie;
- flow->priv = priv;
-
- err = rhashtable_insert_fast(&priv->tc_ht, &flow->node, tc_ht_params);
- if (err) {
- pr_err("Could not insert add new rule\n");
- goto out_free;
- }
-
- rtl83xx_add_flow(priv, f, flow); /* TODO: check error */
-
- /* Add log action to flow */
- flow->rule.packet_cntr = rtl83xx_packet_cntr_alloc(priv);
- if (flow->rule.packet_cntr >= 0) {
- pr_debug("Using packet counter %d\n", flow->rule.packet_cntr);
- flow->rule.log_sel = true;
- flow->rule.log_data = flow->rule.packet_cntr;
- }
-
- err = priv->r->pie_rule_add(priv, &flow->rule);
- return err;
-
-out_free:
- kfree(flow);
-out:
- pr_err("%s: error %d\n", __func__, err);
-
- return err;
-}
-
-static int rtl83xx_delete_flower(struct rtl838x_switch_priv *priv,
- struct flow_cls_offload * cls_flower)
-{
- struct rtl83xx_flow *flow;
-
- pr_debug("In %s\n", __func__);
- rcu_read_lock();
- flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params);
- if (!flow) {
- rcu_read_unlock();
- return -EINVAL;
- }
-
- priv->r->pie_rule_rm(priv, &flow->rule);
-
- rhashtable_remove_fast(&priv->tc_ht, &flow->node, tc_ht_params);
-
- kfree_rcu(flow, rcu_head);
-
- rcu_read_unlock();
-
- return 0;
-}
-
-static int rtl83xx_stats_flower(struct rtl838x_switch_priv *priv,
- struct flow_cls_offload * cls_flower)
-{
- struct rtl83xx_flow *flow;
- unsigned long lastused = 0;
- int total_packets, new_packets;
-
- pr_debug("%s: \n", __func__);
- flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params);
- if (!flow)
- return -1;
-
- if (flow->rule.packet_cntr >= 0) {
- total_packets = priv->r->packet_cntr_read(flow->rule.packet_cntr);
- pr_debug("Total packets: %d\n", total_packets);
- new_packets = total_packets - flow->rule.last_packet_cnt;
- flow->rule.last_packet_cnt = total_packets;
- }
-
- /* TODO: We need a second PIE rule to count the bytes */
- flow_stats_update(&cls_flower->stats, 100 * new_packets, new_packets, 0, lastused,
- FLOW_ACTION_HW_STATS_IMMEDIATE);
-
- return 0;
-}
-
-static int rtl83xx_setup_tc_cls_flower(struct rtl838x_switch_priv *priv,
- struct flow_cls_offload *cls_flower)
-{
- pr_debug("%s: %d\n", __func__, cls_flower->command);
- switch (cls_flower->command) {
- case FLOW_CLS_REPLACE:
- return rtl83xx_configure_flower(priv, cls_flower);
- case FLOW_CLS_DESTROY:
- return rtl83xx_delete_flower(priv, cls_flower);
- case FLOW_CLS_STATS:
- return rtl83xx_stats_flower(priv, cls_flower);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-
-static int rtl83xx_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
- void *cb_priv)
-{
- struct rtl838x_switch_priv *priv = cb_priv;
-
- switch (type) {
- case TC_SETUP_CLSFLOWER:
- pr_debug("%s: TC_SETUP_CLSFLOWER\n", __func__);
- return rtl83xx_setup_tc_cls_flower(priv, type_data);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static LIST_HEAD(rtl83xx_block_cb_list);
-
-int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
-{
- struct rtl838x_switch_priv *priv;
- struct flow_block_offload *f = type_data;
- static bool first_time = true;
- int err;
-
- pr_debug("%s: %d\n", __func__, type);
-
- if(!netdev_uses_dsa(dev)) {
- pr_err("%s: no DSA\n", __func__);
- return 0;
- }
- priv = dev->dsa_ptr->ds->priv;
-
- switch (type) {
- case TC_SETUP_BLOCK:
- if (first_time) {
- first_time = false;
- err = rhashtable_init(&priv->tc_ht, &tc_ht_params);
- if (err)
- pr_err("%s: Could not initialize hash table\n", __func__);
- }
-
- f->unlocked_driver_cb = true;
- return flow_block_cb_setup_simple(type_data,
- &rtl83xx_block_cb_list,
- rtl83xx_setup_tc_block_cb,
- priv, priv, true);
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
diff --git a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c
deleted file mode 100644
index 71e7937336..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c
+++ /dev/null
@@ -1,2599 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* linux/drivers/net/ethernet/rtl838x_eth.c
- * Copyright (C) 2020 B. Koblitz
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/etherdevice.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_net.h>
-#include <linux/of_mdio.h>
-#include <linux/module.h>
-#include <linux/phylink.h>
-#include <linux/pkt_sched.h>
-#include <net/dsa.h>
-#include <net/switchdev.h>
-#include <asm/cacheflush.h>
-
-#include <asm/mach-rtl838x/mach-rtl83xx.h>
-#include "rtl838x_eth.h"
-
-extern struct rtl83xx_soc_info soc_info;
-
-/* Maximum number of RX rings is 8 on RTL83XX and 32 on the 93XX
- * The ring is assigned by switch based on packet/port priortity
- * Maximum number of TX rings is 2, Ring 2 being the high priority
- * ring on the RTL93xx SoCs. MAX_RXLEN gives the maximum length
- * for an RX ring, MAX_ENTRIES the maximum number of entries
- * available in total for all queues.
- */
-#define MAX_RXRINGS 32
-#define MAX_RXLEN 300
-#define MAX_ENTRIES (300 * 8)
-#define TXRINGS 2
-#define TXRINGLEN 160
-#define NOTIFY_EVENTS 10
-#define NOTIFY_BLOCKS 10
-#define TX_EN 0x8
-#define RX_EN 0x4
-#define TX_EN_93XX 0x20
-#define RX_EN_93XX 0x10
-#define RX_TRUNCATE_EN_93XX BIT(6)
-#define RX_TRUNCATE_EN_83XX BIT(4)
-#define TX_PAD_EN_838X BIT(5)
-#define TX_DO 0x2
-#define WRAP 0x2
-#define MAX_PORTS 57
-#define MAX_SMI_BUSSES 4
-
-#define RING_BUFFER 1600
-
-struct p_hdr {
- uint8_t *buf;
- uint16_t reserved;
- uint16_t size; /* buffer size */
- uint16_t offset;
- uint16_t len; /* pkt len */
- /* cpu_tag[0] is a reserved uint16_t on RTL83xx */
- uint16_t cpu_tag[10];
-} __packed __aligned(1);
-
-struct n_event {
- uint32_t type:2;
- uint32_t fidVid:12;
- uint64_t mac:48;
- uint32_t slp:6;
- uint32_t valid:1;
- uint32_t reserved:27;
-} __packed __aligned(1);
-
-struct ring_b {
- uint32_t rx_r[MAX_RXRINGS][MAX_RXLEN];
- uint32_t tx_r[TXRINGS][TXRINGLEN];
- struct p_hdr rx_header[MAX_RXRINGS][MAX_RXLEN];
- struct p_hdr tx_header[TXRINGS][TXRINGLEN];
- uint32_t c_rx[MAX_RXRINGS];
- uint32_t c_tx[TXRINGS];
- uint8_t tx_space[TXRINGS * TXRINGLEN * RING_BUFFER];
- uint8_t *rx_space;
-};
-
-struct notify_block {
- struct n_event events[NOTIFY_EVENTS];
-};
-
-struct notify_b {
- struct notify_block blocks[NOTIFY_BLOCKS];
- u32 reserved1[8];
- u32 ring[NOTIFY_BLOCKS];
- u32 reserved2[8];
-};
-
-static void rtl838x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
-{
- /* cpu_tag[0] is reserved on the RTL83XX SoCs */
- h->cpu_tag[1] = 0x0400; /* BIT 10: RTL8380_CPU_TAG */
- h->cpu_tag[2] = 0x0200; /* Set only AS_DPM, to enable DPM settings below */
- h->cpu_tag[3] = 0x0000;
- h->cpu_tag[4] = BIT(dest_port) >> 16;
- h->cpu_tag[5] = BIT(dest_port) & 0xffff;
-
- /* Set internal priority (PRI) and enable (AS_PRI) */
- if (prio >= 0)
- h->cpu_tag[2] |= ((prio & 0x7) | BIT(3)) << 12;
-}
-
-static void rtl839x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
-{
- /* cpu_tag[0] is reserved on the RTL83XX SoCs */
- h->cpu_tag[1] = 0x0100; /* RTL8390_CPU_TAG marker */
- h->cpu_tag[2] = BIT(4); /* AS_DPM flag */
- h->cpu_tag[3] = h->cpu_tag[4] = h->cpu_tag[5] = 0;
- /* h->cpu_tag[1] |= BIT(1) | BIT(0); */ /* Bypass filter 1/2 */
- if (dest_port >= 32) {
- dest_port -= 32;
- h->cpu_tag[2] |= (BIT(dest_port) >> 16) & 0xf;
- h->cpu_tag[3] = BIT(dest_port) & 0xffff;
- } else {
- h->cpu_tag[4] = BIT(dest_port) >> 16;
- h->cpu_tag[5] = BIT(dest_port) & 0xffff;
- }
-
- /* Set internal priority (PRI) and enable (AS_PRI) */
- if (prio >= 0)
- h->cpu_tag[2] |= ((prio & 0x7) | BIT(3)) << 8;
-}
-
-static void rtl930x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
-{
- h->cpu_tag[0] = 0x8000; /* CPU tag marker */
- h->cpu_tag[1] = h->cpu_tag[2] = 0;
- h->cpu_tag[3] = 0;
- h->cpu_tag[4] = 0;
- h->cpu_tag[5] = 0;
- h->cpu_tag[6] = BIT(dest_port) >> 16;
- h->cpu_tag[7] = BIT(dest_port) & 0xffff;
-
- /* Enable (AS_QID) and set priority queue (QID) */
- if (prio >= 0)
- h->cpu_tag[2] = (BIT(5) | (prio & 0x1f)) << 8;
-}
-
-static void rtl931x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
-{
- h->cpu_tag[0] = 0x8000; /* CPU tag marker */
- h->cpu_tag[1] = h->cpu_tag[2] = 0;
- h->cpu_tag[3] = 0;
- h->cpu_tag[4] = h->cpu_tag[5] = h->cpu_tag[6] = h->cpu_tag[7] = 0;
- if (dest_port >= 32) {
- dest_port -= 32;
- h->cpu_tag[4] = BIT(dest_port) >> 16;
- h->cpu_tag[5] = BIT(dest_port) & 0xffff;
- } else {
- h->cpu_tag[6] = BIT(dest_port) >> 16;
- h->cpu_tag[7] = BIT(dest_port) & 0xffff;
- }
-
- /* Enable (AS_QID) and set priority queue (QID) */
- if (prio >= 0)
- h->cpu_tag[2] = (BIT(5) | (prio & 0x1f)) << 8;
-}
-
-// Currently unused
-// static void rtl93xx_header_vlan_set(struct p_hdr *h, int vlan)
-// {
-// h->cpu_tag[2] |= BIT(4); /* Enable VLAN forwarding offload */
-// h->cpu_tag[2] |= (vlan >> 8) & 0xf;
-// h->cpu_tag[3] |= (vlan & 0xff) << 8;
-// }
-
-struct rtl838x_rx_q {
- int id;
- struct rtl838x_eth_priv *priv;
- struct napi_struct napi;
-};
-
-struct rtl838x_eth_priv {
- struct net_device *netdev;
- struct platform_device *pdev;
- void *membase;
- spinlock_t lock;
- struct mii_bus *mii_bus;
- struct rtl838x_rx_q rx_qs[MAX_RXRINGS];
- struct phylink *phylink;
- struct phylink_config phylink_config;
- u16 id;
- u16 family_id;
- const struct rtl838x_eth_reg *r;
- u8 cpu_port;
- u32 lastEvent;
- u16 rxrings;
- u16 rxringlen;
- u8 smi_bus[MAX_PORTS];
- u8 smi_addr[MAX_PORTS];
- u32 sds_id[MAX_PORTS];
- bool smi_bus_isc45[MAX_SMI_BUSSES];
- bool phy_is_internal[MAX_PORTS];
- phy_interface_t interfaces[MAX_PORTS];
-};
-
-extern int rtl838x_phy_init(struct rtl838x_eth_priv *priv);
-extern int rtl838x_read_sds_phy(int phy_addr, int phy_reg);
-extern int rtl839x_read_sds_phy(int phy_addr, int phy_reg);
-extern int rtl839x_write_sds_phy(int phy_addr, int phy_reg, u16 v);
-extern int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg);
-extern int rtl930x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v);
-extern int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg);
-extern int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v);
-extern int rtl930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
-extern int rtl930x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val);
-extern int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
-extern int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val);
-
-/* On the RTL93XX, the RTL93XX_DMA_IF_RX_RING_CNTR track the fill level of
- * the rings. Writing x into these registers substracts x from its content.
- * When the content reaches the ring size, the ASIC no longer adds
- * packets to this receive queue.
- */
-void rtl838x_update_cntr(int r, int released)
-{
- /* This feature is not available on RTL838x SoCs */
-}
-
-void rtl839x_update_cntr(int r, int released)
-{
- /* This feature is not available on RTL839x SoCs */
-}
-
-void rtl930x_update_cntr(int r, int released)
-{
- int pos = (r % 3) * 10;
- u32 reg = RTL930X_DMA_IF_RX_RING_CNTR + ((r / 3) << 2);
- u32 v = sw_r32(reg);
-
- v = (v >> pos) & 0x3ff;
- pr_debug("RX: Work done %d, old value: %d, pos %d, reg %04x\n", released, v, pos, reg);
- sw_w32_mask(0x3ff << pos, released << pos, reg);
- sw_w32(v, reg);
-}
-
-void rtl931x_update_cntr(int r, int released)
-{
- int pos = (r % 3) * 10;
- u32 reg = RTL931X_DMA_IF_RX_RING_CNTR + ((r / 3) << 2);
- u32 v = sw_r32(reg);
-
- v = (v >> pos) & 0x3ff;
- sw_w32_mask(0x3ff << pos, released << pos, reg);
- sw_w32(v, reg);
-}
-
-struct dsa_tag {
- u8 reason;
- u8 queue;
- u16 port;
- u8 l2_offloaded;
- u8 prio;
- bool crc_error;
-};
-
-bool rtl838x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
-{
- /* cpu_tag[0] is reserved. Fields are off-by-one */
- t->reason = h->cpu_tag[4] & 0xf;
- t->queue = (h->cpu_tag[1] & 0xe0) >> 5;
- t->port = h->cpu_tag[1] & 0x1f;
- t->crc_error = t->reason == 13;
-
- pr_debug("Reason: %d\n", t->reason);
- if (t->reason != 6) /* NIC_RX_REASON_SPECIAL_TRAP */
- t->l2_offloaded = 1;
- else
- t->l2_offloaded = 0;
-
- return t->l2_offloaded;
-}
-
-bool rtl839x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
-{
- /* cpu_tag[0] is reserved. Fields are off-by-one */
- t->reason = h->cpu_tag[5] & 0x1f;
- t->queue = (h->cpu_tag[4] & 0xe000) >> 13;
- t->port = h->cpu_tag[1] & 0x3f;
- t->crc_error = h->cpu_tag[4] & BIT(6);
-
- pr_debug("Reason: %d\n", t->reason);
- if ((t->reason >= 7 && t->reason <= 13) || /* NIC_RX_REASON_RMA */
- (t->reason >= 23 && t->reason <= 25)) /* NIC_RX_REASON_SPECIAL_TRAP */
- t->l2_offloaded = 0;
- else
- t->l2_offloaded = 1;
-
- return t->l2_offloaded;
-}
-
-bool rtl930x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
-{
- t->reason = h->cpu_tag[7] & 0x3f;
- t->queue = (h->cpu_tag[2] >> 11) & 0x1f;
- t->port = (h->cpu_tag[0] >> 8) & 0x1f;
- t->crc_error = h->cpu_tag[1] & BIT(6);
-
- pr_debug("Reason %d, port %d, queue %d\n", t->reason, t->port, t->queue);
- if (t->reason >= 19 && t->reason <= 27)
- t->l2_offloaded = 0;
- else
- t->l2_offloaded = 1;
-
- return t->l2_offloaded;
-}
-
-bool rtl931x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
-{
- t->reason = h->cpu_tag[7] & 0x3f;
- t->queue = (h->cpu_tag[2] >> 11) & 0x1f;
- t->port = (h->cpu_tag[0] >> 8) & 0x3f;
- t->crc_error = h->cpu_tag[1] & BIT(6);
-
- if (t->reason != 63)
- pr_info("%s: Reason %d, port %d, queue %d\n", __func__, t->reason, t->port, t->queue);
- if (t->reason >= 19 && t->reason <= 27) /* NIC_RX_REASON_RMA */
- t->l2_offloaded = 0;
- else
- t->l2_offloaded = 1;
-
- return t->l2_offloaded;
-}
-
-/* Discard the RX ring-buffers, called as part of the net-ISR
- * when the buffer runs over
- */
-static void rtl838x_rb_cleanup(struct rtl838x_eth_priv *priv, int status)
-{
- for (int r = 0; r < priv->rxrings; r++) {
- struct ring_b *ring = priv->membase;
- struct p_hdr *h;
- u32 *last;
-
- pr_debug("In %s working on r: %d\n", __func__, r);
- last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4));
- do {
- if ((ring->rx_r[r][ring->c_rx[r]] & 0x1))
- break;
- pr_debug("Got something: %d\n", ring->c_rx[r]);
- h = &ring->rx_header[r][ring->c_rx[r]];
- memset(h, 0, sizeof(struct p_hdr));
- h->buf = (u8 *)KSEG1ADDR(ring->rx_space +
- r * priv->rxringlen * RING_BUFFER +
- ring->c_rx[r] * RING_BUFFER);
- h->size = RING_BUFFER;
- /* make sure the header is visible to the ASIC */
- mb();
-
- ring->rx_r[r][ring->c_rx[r]] = KSEG1ADDR(h) | 0x1 | (ring->c_rx[r] == (priv->rxringlen - 1) ?
- WRAP :
- 0x1);
- ring->c_rx[r] = (ring->c_rx[r] + 1) % priv->rxringlen;
- } while (&ring->rx_r[r][ring->c_rx[r]] != last);
- }
-}
-
-struct fdb_update_work {
- struct work_struct work;
- struct net_device *ndev;
- u64 macs[NOTIFY_EVENTS + 1];
-};
-
-void rtl838x_fdb_sync(struct work_struct *work)
-{
- const struct fdb_update_work *uw = container_of(work, struct fdb_update_work, work);
-
- for (int i = 0; uw->macs[i]; i++) {
- struct switchdev_notifier_fdb_info info;
- u8 addr[ETH_ALEN];
- int action;
-
- action = (uw->macs[i] & (1ULL << 63)) ?
- SWITCHDEV_FDB_ADD_TO_BRIDGE :
- SWITCHDEV_FDB_DEL_TO_BRIDGE;
- u64_to_ether_addr(uw->macs[i] & 0xffffffffffffULL, addr);
- info.addr = &addr[0];
- info.vid = 0;
- info.offloaded = 1;
- pr_debug("FDB entry %d: %llx, action %d\n", i, uw->macs[0], action);
- call_switchdev_notifiers(action, uw->ndev, &info.info, NULL);
- }
- kfree(work);
-}
-
-static void rtl839x_l2_notification_handler(struct rtl838x_eth_priv *priv)
-{
- struct notify_b *nb = priv->membase + sizeof(struct ring_b);
- u32 e = priv->lastEvent;
-
- while (!(nb->ring[e] & 1)) {
- struct fdb_update_work *w;
- struct n_event *event;
- u64 mac;
- int i;
-
- w = kzalloc(sizeof(*w), GFP_ATOMIC);
- if (!w) {
- pr_err("Out of memory: %s", __func__);
- return;
- }
- INIT_WORK(&w->work, rtl838x_fdb_sync);
-
- for (i = 0; i < NOTIFY_EVENTS; i++) {
- event = &nb->blocks[e].events[i];
- if (!event->valid)
- continue;
- mac = event->mac;
- if (event->type)
- mac |= 1ULL << 63;
- w->ndev = priv->netdev;
- w->macs[i] = mac;
- }
-
- /* Hand the ring entry back to the switch */
- nb->ring[e] = nb->ring[e] | 1;
- e = (e + 1) % NOTIFY_BLOCKS;
-
- w->macs[i] = 0ULL;
- schedule_work(&w->work);
- }
- priv->lastEvent = e;
-}
-
-static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
- u32 status = sw_r32(priv->r->dma_if_intr_sts);
-
- pr_debug("IRQ: %08x\n", status);
-
- /* Ignore TX interrupt */
- if ((status & 0xf0000)) {
- /* Clear ISR */
- sw_w32(0x000f0000, priv->r->dma_if_intr_sts);
- }
-
- /* RX interrupt */
- if (status & 0x0ff00) {
- /* ACK and disable RX interrupt for this ring */
- sw_w32_mask(0xff00 & status, 0, priv->r->dma_if_intr_msk);
- sw_w32(0x0000ff00 & status, priv->r->dma_if_intr_sts);
- for (int i = 0; i < priv->rxrings; i++) {
- if (status & BIT(i + 8)) {
- pr_debug("Scheduling queue: %d\n", i);
- napi_schedule(&priv->rx_qs[i].napi);
- }
- }
- }
-
- /* RX buffer overrun */
- if (status & 0x000ff) {
- pr_debug("RX buffer overrun: status %x, mask: %x\n",
- status, sw_r32(priv->r->dma_if_intr_msk));
- sw_w32(status, priv->r->dma_if_intr_sts);
- rtl838x_rb_cleanup(priv, status & 0xff);
- }
-
- if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00100000) {
- sw_w32(0x00100000, priv->r->dma_if_intr_sts);
- rtl839x_l2_notification_handler(priv);
- }
-
- if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00200000) {
- sw_w32(0x00200000, priv->r->dma_if_intr_sts);
- rtl839x_l2_notification_handler(priv);
- }
-
- if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00400000) {
- sw_w32(0x00400000, priv->r->dma_if_intr_sts);
- rtl839x_l2_notification_handler(priv);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t rtl93xx_net_irq(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
- u32 status_rx_r = sw_r32(priv->r->dma_if_intr_rx_runout_sts);
- u32 status_rx = sw_r32(priv->r->dma_if_intr_rx_done_sts);
- u32 status_tx = sw_r32(priv->r->dma_if_intr_tx_done_sts);
-
- pr_debug("In %s, status_tx: %08x, status_rx: %08x, status_rx_r: %08x\n",
- __func__, status_tx, status_rx, status_rx_r);
-
- /* Ignore TX interrupt */
- if (status_tx) {
- /* Clear ISR */
- pr_debug("TX done\n");
- sw_w32(status_tx, priv->r->dma_if_intr_tx_done_sts);
- }
-
- /* RX interrupt */
- if (status_rx) {
- pr_debug("RX IRQ\n");
- /* ACK and disable RX interrupt for given rings */
- sw_w32(status_rx, priv->r->dma_if_intr_rx_done_sts);
- sw_w32_mask(status_rx, 0, priv->r->dma_if_intr_rx_done_msk);
- for (int i = 0; i < priv->rxrings; i++) {
- if (status_rx & BIT(i)) {
- pr_debug("Scheduling queue: %d\n", i);
- napi_schedule(&priv->rx_qs[i].napi);
- }
- }
- }
-
- /* RX buffer overrun */
- if (status_rx_r) {
- pr_debug("RX buffer overrun: status %x, mask: %x\n",
- status_rx_r, sw_r32(priv->r->dma_if_intr_rx_runout_msk));
- sw_w32(status_rx_r, priv->r->dma_if_intr_rx_runout_sts);
- rtl838x_rb_cleanup(priv, status_rx_r);
- }
-
- return IRQ_HANDLED;
-}
-
-static const struct rtl838x_eth_reg rtl838x_reg = {
- .net_irq = rtl83xx_net_irq,
- .mac_port_ctrl = rtl838x_mac_port_ctrl,
- .dma_if_intr_sts = RTL838X_DMA_IF_INTR_STS,
- .dma_if_intr_msk = RTL838X_DMA_IF_INTR_MSK,
- .dma_if_ctrl = RTL838X_DMA_IF_CTRL,
- .mac_force_mode_ctrl = RTL838X_MAC_FORCE_MODE_CTRL,
- .dma_rx_base = RTL838X_DMA_RX_BASE,
- .dma_tx_base = RTL838X_DMA_TX_BASE,
- .dma_if_rx_ring_size = rtl838x_dma_if_rx_ring_size,
- .dma_if_rx_ring_cntr = rtl838x_dma_if_rx_ring_cntr,
- .dma_if_rx_cur = RTL838X_DMA_IF_RX_CUR,
- .rst_glb_ctrl = RTL838X_RST_GLB_CTRL_0,
- .get_mac_link_sts = rtl838x_get_mac_link_sts,
- .get_mac_link_dup_sts = rtl838x_get_mac_link_dup_sts,
- .get_mac_link_spd_sts = rtl838x_get_mac_link_spd_sts,
- .get_mac_rx_pause_sts = rtl838x_get_mac_rx_pause_sts,
- .get_mac_tx_pause_sts = rtl838x_get_mac_tx_pause_sts,
- .mac = RTL838X_MAC,
- .l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL,
- .update_cntr = rtl838x_update_cntr,
- .create_tx_header = rtl838x_create_tx_header,
- .decode_tag = rtl838x_decode_tag,
-};
-
-static const struct rtl838x_eth_reg rtl839x_reg = {
- .net_irq = rtl83xx_net_irq,
- .mac_port_ctrl = rtl839x_mac_port_ctrl,
- .dma_if_intr_sts = RTL839X_DMA_IF_INTR_STS,
- .dma_if_intr_msk = RTL839X_DMA_IF_INTR_MSK,
- .dma_if_ctrl = RTL839X_DMA_IF_CTRL,
- .mac_force_mode_ctrl = RTL839X_MAC_FORCE_MODE_CTRL,
- .dma_rx_base = RTL839X_DMA_RX_BASE,
- .dma_tx_base = RTL839X_DMA_TX_BASE,
- .dma_if_rx_ring_size = rtl839x_dma_if_rx_ring_size,
- .dma_if_rx_ring_cntr = rtl839x_dma_if_rx_ring_cntr,
- .dma_if_rx_cur = RTL839X_DMA_IF_RX_CUR,
- .rst_glb_ctrl = RTL839X_RST_GLB_CTRL,
- .get_mac_link_sts = rtl839x_get_mac_link_sts,
- .get_mac_link_dup_sts = rtl839x_get_mac_link_dup_sts,
- .get_mac_link_spd_sts = rtl839x_get_mac_link_spd_sts,
- .get_mac_rx_pause_sts = rtl839x_get_mac_rx_pause_sts,
- .get_mac_tx_pause_sts = rtl839x_get_mac_tx_pause_sts,
- .mac = RTL839X_MAC,
- .l2_tbl_flush_ctrl = RTL839X_L2_TBL_FLUSH_CTRL,
- .update_cntr = rtl839x_update_cntr,
- .create_tx_header = rtl839x_create_tx_header,
- .decode_tag = rtl839x_decode_tag,
-};
-
-static const struct rtl838x_eth_reg rtl930x_reg = {
- .net_irq = rtl93xx_net_irq,
- .mac_port_ctrl = rtl930x_mac_port_ctrl,
- .dma_if_intr_rx_runout_sts = RTL930X_DMA_IF_INTR_RX_RUNOUT_STS,
- .dma_if_intr_rx_done_sts = RTL930X_DMA_IF_INTR_RX_DONE_STS,
- .dma_if_intr_tx_done_sts = RTL930X_DMA_IF_INTR_TX_DONE_STS,
- .dma_if_intr_rx_runout_msk = RTL930X_DMA_IF_INTR_RX_RUNOUT_MSK,
- .dma_if_intr_rx_done_msk = RTL930X_DMA_IF_INTR_RX_DONE_MSK,
- .dma_if_intr_tx_done_msk = RTL930X_DMA_IF_INTR_TX_DONE_MSK,
- .l2_ntfy_if_intr_sts = RTL930X_L2_NTFY_IF_INTR_STS,
- .l2_ntfy_if_intr_msk = RTL930X_L2_NTFY_IF_INTR_MSK,
- .dma_if_ctrl = RTL930X_DMA_IF_CTRL,
- .mac_force_mode_ctrl = RTL930X_MAC_FORCE_MODE_CTRL,
- .dma_rx_base = RTL930X_DMA_RX_BASE,
- .dma_tx_base = RTL930X_DMA_TX_BASE,
- .dma_if_rx_ring_size = rtl930x_dma_if_rx_ring_size,
- .dma_if_rx_ring_cntr = rtl930x_dma_if_rx_ring_cntr,
- .dma_if_rx_cur = RTL930X_DMA_IF_RX_CUR,
- .rst_glb_ctrl = RTL930X_RST_GLB_CTRL_0,
- .get_mac_link_sts = rtl930x_get_mac_link_sts,
- .get_mac_link_dup_sts = rtl930x_get_mac_link_dup_sts,
- .get_mac_link_spd_sts = rtl930x_get_mac_link_spd_sts,
- .get_mac_rx_pause_sts = rtl930x_get_mac_rx_pause_sts,
- .get_mac_tx_pause_sts = rtl930x_get_mac_tx_pause_sts,
- .mac = RTL930X_MAC_L2_ADDR_CTRL,
- .l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL,
- .update_cntr = rtl930x_update_cntr,
- .create_tx_header = rtl930x_create_tx_header,
- .decode_tag = rtl930x_decode_tag,
-};
-
-static const struct rtl838x_eth_reg rtl931x_reg = {
- .net_irq = rtl93xx_net_irq,
- .mac_port_ctrl = rtl931x_mac_port_ctrl,
- .dma_if_intr_rx_runout_sts = RTL931X_DMA_IF_INTR_RX_RUNOUT_STS,
- .dma_if_intr_rx_done_sts = RTL931X_DMA_IF_INTR_RX_DONE_STS,
- .dma_if_intr_tx_done_sts = RTL931X_DMA_IF_INTR_TX_DONE_STS,
- .dma_if_intr_rx_runout_msk = RTL931X_DMA_IF_INTR_RX_RUNOUT_MSK,
- .dma_if_intr_rx_done_msk = RTL931X_DMA_IF_INTR_RX_DONE_MSK,
- .dma_if_intr_tx_done_msk = RTL931X_DMA_IF_INTR_TX_DONE_MSK,
- .l2_ntfy_if_intr_sts = RTL931X_L2_NTFY_IF_INTR_STS,
- .l2_ntfy_if_intr_msk = RTL931X_L2_NTFY_IF_INTR_MSK,
- .dma_if_ctrl = RTL931X_DMA_IF_CTRL,
- .mac_force_mode_ctrl = RTL931X_MAC_FORCE_MODE_CTRL,
- .dma_rx_base = RTL931X_DMA_RX_BASE,
- .dma_tx_base = RTL931X_DMA_TX_BASE,
- .dma_if_rx_ring_size = rtl931x_dma_if_rx_ring_size,
- .dma_if_rx_ring_cntr = rtl931x_dma_if_rx_ring_cntr,
- .dma_if_rx_cur = RTL931X_DMA_IF_RX_CUR,
- .rst_glb_ctrl = RTL931X_RST_GLB_CTRL,
- .get_mac_link_sts = rtl931x_get_mac_link_sts,
- .get_mac_link_dup_sts = rtl931x_get_mac_link_dup_sts,
- .get_mac_link_spd_sts = rtl931x_get_mac_link_spd_sts,
- .get_mac_rx_pause_sts = rtl931x_get_mac_rx_pause_sts,
- .get_mac_tx_pause_sts = rtl931x_get_mac_tx_pause_sts,
- .mac = RTL931X_MAC_L2_ADDR_CTRL,
- .l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL,
- .update_cntr = rtl931x_update_cntr,
- .create_tx_header = rtl931x_create_tx_header,
- .decode_tag = rtl931x_decode_tag,
-};
-
-static void rtl838x_hw_reset(struct rtl838x_eth_priv *priv)
-{
- u32 int_saved, nbuf;
- u32 reset_mask;
-
- pr_info("RESETTING %x, CPU_PORT %d\n", priv->family_id, priv->cpu_port);
- sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(priv->cpu_port));
- mdelay(100);
-
- /* Disable and clear interrupts */
- if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) {
- sw_w32(0x00000000, priv->r->dma_if_intr_rx_runout_msk);
- sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_sts);
- sw_w32(0x00000000, priv->r->dma_if_intr_rx_done_msk);
- sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_sts);
- sw_w32(0x00000000, priv->r->dma_if_intr_tx_done_msk);
- sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_sts);
- } else {
- sw_w32(0x00000000, priv->r->dma_if_intr_msk);
- sw_w32(0xffffffff, priv->r->dma_if_intr_sts);
- }
-
- if (priv->family_id == RTL8390_FAMILY_ID) {
- /* Preserve L2 notification and NBUF settings */
- int_saved = sw_r32(priv->r->dma_if_intr_msk);
- nbuf = sw_r32(RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL);
-
- /* Disable link change interrupt on RTL839x */
- sw_w32(0, RTL839X_IMR_PORT_LINK_STS_CHG);
- sw_w32(0, RTL839X_IMR_PORT_LINK_STS_CHG + 4);
-
- sw_w32(0x00000000, priv->r->dma_if_intr_msk);
- sw_w32(0xffffffff, priv->r->dma_if_intr_sts);
- }
-
- /* Reset NIC (SW_NIC_RST) and queues (SW_Q_RST) */
- if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID)
- reset_mask = 0x6;
- else
- reset_mask = 0xc;
-
- sw_w32_mask(0, reset_mask, priv->r->rst_glb_ctrl);
-
- do { /* Wait for reset of NIC and Queues done */
- udelay(20);
- } while (sw_r32(priv->r->rst_glb_ctrl) & reset_mask);
- mdelay(100);
-
- /* Setup Head of Line */
- if (priv->family_id == RTL8380_FAMILY_ID)
- sw_w32(0, RTL838X_DMA_IF_RX_RING_SIZE); /* Disabled on RTL8380 */
- if (priv->family_id == RTL8390_FAMILY_ID)
- sw_w32(0xffffffff, RTL839X_DMA_IF_RX_RING_CNTR);
- if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) {
- for (int i = 0; i < priv->rxrings; i++) {
- int pos = (i % 3) * 10;
-
- sw_w32_mask(0x3ff << pos, 0, priv->r->dma_if_rx_ring_size(i));
- sw_w32_mask(0x3ff << pos, priv->rxringlen,
- priv->r->dma_if_rx_ring_cntr(i));
- }
- }
-
- /* Re-enable link change interrupt */
- if (priv->family_id == RTL8390_FAMILY_ID) {
- sw_w32(0xffffffff, RTL839X_ISR_PORT_LINK_STS_CHG);
- sw_w32(0xffffffff, RTL839X_ISR_PORT_LINK_STS_CHG + 4);
- sw_w32(0xffffffff, RTL839X_IMR_PORT_LINK_STS_CHG);
- sw_w32(0xffffffff, RTL839X_IMR_PORT_LINK_STS_CHG + 4);
-
- /* Restore notification settings: on RTL838x these bits are null */
- sw_w32_mask(7 << 20, int_saved & (7 << 20), priv->r->dma_if_intr_msk);
- sw_w32(nbuf, RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL);
- }
-}
-
-static void rtl838x_hw_ring_setup(struct rtl838x_eth_priv *priv)
-{
- struct ring_b *ring = priv->membase;
-
- for (int i = 0; i < priv->rxrings; i++)
- sw_w32(KSEG1ADDR(&ring->rx_r[i]), priv->r->dma_rx_base + i * 4);
-
- for (int i = 0; i < TXRINGS; i++)
- sw_w32(KSEG1ADDR(&ring->tx_r[i]), priv->r->dma_tx_base + i * 4);
-}
-
-static void rtl838x_hw_en_rxtx(struct rtl838x_eth_priv *priv)
-{
- /* Disable Head of Line features for all RX rings */
- sw_w32(0xffffffff, priv->r->dma_if_rx_ring_size(0));
-
- /* Truncate RX buffer to DEFAULT_MTU bytes, pad TX */
- sw_w32((DEFAULT_MTU << 16) | RX_TRUNCATE_EN_83XX | TX_PAD_EN_838X, priv->r->dma_if_ctrl);
-
- /* Enable RX done, RX overflow and TX done interrupts */
- sw_w32(0xfffff, priv->r->dma_if_intr_msk);
-
- /* Enable DMA, engine expects empty FCS field */
- sw_w32_mask(0, RX_EN | TX_EN, priv->r->dma_if_ctrl);
-
- /* Restart TX/RX to CPU port */
- sw_w32_mask(0x0, 0x3, priv->r->mac_port_ctrl(priv->cpu_port));
- /* Set Speed, duplex, flow control
- * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL
- * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN
- * | MEDIA_SEL
- */
- sw_w32(0x6192F, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
-
- /* Enable CRC checks on CPU-port */
- sw_w32_mask(0, BIT(3), priv->r->mac_port_ctrl(priv->cpu_port));
-}
-
-static void rtl839x_hw_en_rxtx(struct rtl838x_eth_priv *priv)
-{
- /* Setup CPU-Port: RX Buffer */
- sw_w32((DEFAULT_MTU << 5) | RX_TRUNCATE_EN_83XX, priv->r->dma_if_ctrl);
-
- /* Enable Notify, RX done, RX overflow and TX done interrupts */
- sw_w32(0x007fffff, priv->r->dma_if_intr_msk); /* Notify IRQ! */
-
- /* Enable DMA */
- sw_w32_mask(0, RX_EN | TX_EN, priv->r->dma_if_ctrl);
-
- /* Restart TX/RX to CPU port, enable CRC checking */
- sw_w32_mask(0x0, 0x3 | BIT(3), priv->r->mac_port_ctrl(priv->cpu_port));
-
- /* CPU port joins Lookup Miss Flooding Portmask */
- /* TODO: The code below should also work for the RTL838x */
- sw_w32(0x28000, RTL839X_TBL_ACCESS_L2_CTRL);
- sw_w32_mask(0, 0x80000000, RTL839X_TBL_ACCESS_L2_DATA(0));
- sw_w32(0x38000, RTL839X_TBL_ACCESS_L2_CTRL);
-
- /* Force CPU port link up */
- sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
-}
-
-static void rtl93xx_hw_en_rxtx(struct rtl838x_eth_priv *priv)
-{
- /* Setup CPU-Port: RX Buffer truncated at DEFAULT_MTU Bytes */
- sw_w32((DEFAULT_MTU << 16) | RX_TRUNCATE_EN_93XX, priv->r->dma_if_ctrl);
-
- for (int i = 0; i < priv->rxrings; i++) {
- int pos = (i % 3) * 10;
- u32 v;
-
- sw_w32_mask(0x3ff << pos, priv->rxringlen << pos, priv->r->dma_if_rx_ring_size(i));
-
- /* Some SoCs have issues with missing underflow protection */
- v = (sw_r32(priv->r->dma_if_rx_ring_cntr(i)) >> pos) & 0x3ff;
- sw_w32_mask(0x3ff << pos, v, priv->r->dma_if_rx_ring_cntr(i));
- }
-
- /* Enable Notify, RX done, RX overflow and TX done interrupts */
- sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_msk);
- sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk);
- sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_msk);
-
- /* Enable DMA */
- sw_w32_mask(0, RX_EN_93XX | TX_EN_93XX, priv->r->dma_if_ctrl);
-
- /* Restart TX/RX to CPU port, enable CRC checking */
- sw_w32_mask(0x0, 0x3 | BIT(4), priv->r->mac_port_ctrl(priv->cpu_port));
-
- if (priv->family_id == RTL9300_FAMILY_ID)
- sw_w32_mask(0, BIT(priv->cpu_port), RTL930X_L2_UNKN_UC_FLD_PMSK);
- else
- sw_w32_mask(0, BIT(priv->cpu_port), RTL931X_L2_UNKN_UC_FLD_PMSK);
-
- if (priv->family_id == RTL9300_FAMILY_ID)
- sw_w32(0x217, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
- else
- sw_w32(0x2a1d, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
-}
-
-static void rtl838x_setup_ring_buffer(struct rtl838x_eth_priv *priv, struct ring_b *ring)
-{
- for (int i = 0; i < priv->rxrings; i++) {
- struct p_hdr *h;
- int j;
-
- for (j = 0; j < priv->rxringlen; j++) {
- h = &ring->rx_header[i][j];
- memset(h, 0, sizeof(struct p_hdr));
- h->buf = (u8 *)KSEG1ADDR(ring->rx_space +
- i * priv->rxringlen * RING_BUFFER +
- j * RING_BUFFER);
- h->size = RING_BUFFER;
- /* All rings owned by switch, last one wraps */
- ring->rx_r[i][j] = KSEG1ADDR(h) | 1 | (j == (priv->rxringlen - 1) ?
- WRAP :
- 0);
- }
- ring->c_rx[i] = 0;
- }
-
- for (int i = 0; i < TXRINGS; i++) {
- struct p_hdr *h;
- int j;
-
- for (j = 0; j < TXRINGLEN; j++) {
- h = &ring->tx_header[i][j];
- memset(h, 0, sizeof(struct p_hdr));
- h->buf = (u8 *)KSEG1ADDR(ring->tx_space +
- i * TXRINGLEN * RING_BUFFER +
- j * RING_BUFFER);
- h->size = RING_BUFFER;
- ring->tx_r[i][j] = KSEG1ADDR(&ring->tx_header[i][j]);
- }
- /* Last header is wrapping around */
- ring->tx_r[i][j - 1] |= WRAP;
- ring->c_tx[i] = 0;
- }
-}
-
-static void rtl839x_setup_notify_ring_buffer(struct rtl838x_eth_priv *priv)
-{
- struct notify_b *b = priv->membase + sizeof(struct ring_b);
-
- for (int i = 0; i < NOTIFY_BLOCKS; i++)
- b->ring[i] = KSEG1ADDR(&b->blocks[i]) | 1 | (i == (NOTIFY_BLOCKS - 1) ? WRAP : 0);
-
- sw_w32((u32) b->ring, RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL);
- sw_w32_mask(0x3ff << 2, 100 << 2, RTL839X_L2_NOTIFICATION_CTRL);
-
- /* Setup notification events */
- sw_w32_mask(0, 1 << 14, RTL839X_L2_CTRL_0); /* RTL8390_L2_CTRL_0_FLUSH_NOTIFY_EN */
- sw_w32_mask(0, 1 << 12, RTL839X_L2_NOTIFICATION_CTRL); /* SUSPEND_NOTIFICATION_EN */
-
- /* Enable Notification */
- sw_w32_mask(0, 1 << 0, RTL839X_L2_NOTIFICATION_CTRL);
- priv->lastEvent = 0;
-}
-
-static int rtl838x_eth_open(struct net_device *ndev)
-{
- unsigned long flags;
- struct rtl838x_eth_priv *priv = netdev_priv(ndev);
- struct ring_b *ring = priv->membase;
-
- pr_debug("%s called: RX rings %d(length %d), TX rings %d(length %d)\n",
- __func__, priv->rxrings, priv->rxringlen, TXRINGS, TXRINGLEN);
-
- spin_lock_irqsave(&priv->lock, flags);
- rtl838x_hw_reset(priv);
- rtl838x_setup_ring_buffer(priv, ring);
- if (priv->family_id == RTL8390_FAMILY_ID) {
- rtl839x_setup_notify_ring_buffer(priv);
- /* Make sure the ring structure is visible to the ASIC */
- mb();
- flush_cache_all();
- }
-
- rtl838x_hw_ring_setup(priv);
- phylink_start(priv->phylink);
-
- for (int i = 0; i < priv->rxrings; i++)
- napi_enable(&priv->rx_qs[i].napi);
-
- switch (priv->family_id) {
- case RTL8380_FAMILY_ID:
- rtl838x_hw_en_rxtx(priv);
- /* Trap IGMP/MLD traffic to CPU-Port */
- sw_w32(0x3, RTL838X_SPCL_TRAP_IGMP_CTRL);
- /* Flush learned FDB entries on link down of a port */
- sw_w32_mask(0, BIT(7), RTL838X_L2_CTRL_0);
- break;
-
- case RTL8390_FAMILY_ID:
- rtl839x_hw_en_rxtx(priv);
- /* Trap MLD and IGMP messages to CPU_PORT */
- sw_w32(0x3, RTL839X_SPCL_TRAP_IGMP_CTRL);
- /* Flush learned FDB entries on link down of a port */
- sw_w32_mask(0, BIT(7), RTL839X_L2_CTRL_0);
- break;
-
- case RTL9300_FAMILY_ID:
- rtl93xx_hw_en_rxtx(priv);
- /* Flush learned FDB entries on link down of a port */
- sw_w32_mask(0, BIT(7), RTL930X_L2_CTRL);
- /* Trap MLD and IGMP messages to CPU_PORT */
- sw_w32((0x2 << 3) | 0x2, RTL930X_VLAN_APP_PKT_CTRL);
- break;
-
- case RTL9310_FAMILY_ID:
- rtl93xx_hw_en_rxtx(priv);
-
- /* Trap MLD and IGMP messages to CPU_PORT */
- sw_w32((0x2 << 3) | 0x2, RTL931X_VLAN_APP_PKT_CTRL);
-
- /* Disable External CPU access to switch, clear EXT_CPU_EN */
- sw_w32_mask(BIT(2), 0, RTL931X_MAC_L2_GLOBAL_CTRL2);
-
- /* Set PCIE_PWR_DOWN */
- sw_w32_mask(0, BIT(1), RTL931X_PS_SOC_CTRL);
- break;
- }
-
- netif_tx_start_all_queues(ndev);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
-static void rtl838x_hw_stop(struct rtl838x_eth_priv *priv)
-{
- u32 force_mac = priv->family_id == RTL8380_FAMILY_ID ? 0x6192C : 0x75;
- u32 clear_irq = priv->family_id == RTL8380_FAMILY_ID ? 0x000fffff : 0x007fffff;
-
- /* Disable RX/TX from/to CPU-port */
- sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(priv->cpu_port));
-
- /* Disable traffic */
- if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID)
- sw_w32_mask(RX_EN_93XX | TX_EN_93XX, 0, priv->r->dma_if_ctrl);
- else
- sw_w32_mask(RX_EN | TX_EN, 0, priv->r->dma_if_ctrl);
- mdelay(200); /* Test, whether this is needed */
-
- /* Block all ports */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- sw_w32(0x03000000, RTL838X_TBL_ACCESS_DATA_0(0));
- sw_w32(0x00000000, RTL838X_TBL_ACCESS_DATA_0(1));
- sw_w32(1 << 15 | 2 << 12, RTL838X_TBL_ACCESS_CTRL_0);
- }
-
- /* Flush L2 address cache */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- for (int i = 0; i <= priv->cpu_port; i++) {
- sw_w32(1 << 26 | 1 << 23 | i << 5, priv->r->l2_tbl_flush_ctrl);
- do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & (1 << 26));
- }
- } else if (priv->family_id == RTL8390_FAMILY_ID) {
- for (int i = 0; i <= priv->cpu_port; i++) {
- sw_w32(1 << 28 | 1 << 25 | i << 5, priv->r->l2_tbl_flush_ctrl);
- do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & (1 << 28));
- }
- }
- /* TODO: L2 flush register is 64 bit on RTL931X and 930X */
-
- /* CPU-Port: Link down */
- if (priv->family_id == RTL8380_FAMILY_ID || priv->family_id == RTL8390_FAMILY_ID)
- sw_w32(force_mac, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
- else if (priv->family_id == RTL9300_FAMILY_ID)
- sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl + priv->cpu_port *4);
- else if (priv->family_id == RTL9310_FAMILY_ID)
- sw_w32_mask(BIT(0) | BIT(9), 0, priv->r->mac_force_mode_ctrl + priv->cpu_port *4);
- mdelay(100);
-
- /* Disable all TX/RX interrupts */
- if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) {
- sw_w32(0x00000000, priv->r->dma_if_intr_rx_runout_msk);
- sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_sts);
- sw_w32(0x00000000, priv->r->dma_if_intr_rx_done_msk);
- sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_sts);
- sw_w32(0x00000000, priv->r->dma_if_intr_tx_done_msk);
- sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_sts);
- } else {
- sw_w32(0x00000000, priv->r->dma_if_intr_msk);
- sw_w32(clear_irq, priv->r->dma_if_intr_sts);
- }
-
- /* Disable TX/RX DMA */
- sw_w32(0x00000000, priv->r->dma_if_ctrl);
- mdelay(200);
-}
-
-static int rtl838x_eth_stop(struct net_device *ndev)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(ndev);
-
- pr_info("in %s\n", __func__);
-
- phylink_stop(priv->phylink);
- rtl838x_hw_stop(priv);
-
- for (int i = 0; i < priv->rxrings; i++)
- napi_disable(&priv->rx_qs[i].napi);
-
- netif_tx_stop_all_queues(ndev);
-
- return 0;
-}
-
-static void rtl838x_eth_set_multicast_list(struct net_device *ndev)
-{
- /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
- * CTRL_0_FULL = GENMASK(21, 0) = 0x3FFFFF
- */
- if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
- sw_w32(0x0, RTL838X_RMA_CTRL_0);
- sw_w32(0x0, RTL838X_RMA_CTRL_1);
- }
- if (ndev->flags & IFF_ALLMULTI)
- sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0);
- if (ndev->flags & IFF_PROMISC) {
- sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0);
- sw_w32(0x7fff, RTL838X_RMA_CTRL_1);
- }
-}
-
-static void rtl839x_eth_set_multicast_list(struct net_device *ndev)
-{
- /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
- * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
- * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
- * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
- */
- if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
- sw_w32(0x0, RTL839X_RMA_CTRL_0);
- sw_w32(0x0, RTL839X_RMA_CTRL_1);
- sw_w32(0x0, RTL839X_RMA_CTRL_2);
- sw_w32(0x0, RTL839X_RMA_CTRL_3);
- }
- if (ndev->flags & IFF_ALLMULTI) {
- sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0);
- sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1);
- sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2);
- }
- if (ndev->flags & IFF_PROMISC) {
- sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0);
- sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1);
- sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2);
- sw_w32(0x3ff, RTL839X_RMA_CTRL_3);
- }
-}
-
-static void rtl930x_eth_set_multicast_list(struct net_device *ndev)
-{
- /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
- * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
- * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
- * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
- */
- if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
- sw_w32(GENMASK(31, 2), RTL930X_RMA_CTRL_0);
- sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_1);
- sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_2);
- } else {
- sw_w32(0x0, RTL930X_RMA_CTRL_0);
- sw_w32(0x0, RTL930X_RMA_CTRL_1);
- sw_w32(0x0, RTL930X_RMA_CTRL_2);
- }
-}
-
-static void rtl931x_eth_set_multicast_list(struct net_device *ndev)
-{
- /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
- * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
- * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00.
- * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
- */
- if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
- sw_w32(GENMASK(31, 2), RTL931X_RMA_CTRL_0);
- sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_1);
- sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_2);
- } else {
- sw_w32(0x0, RTL931X_RMA_CTRL_0);
- sw_w32(0x0, RTL931X_RMA_CTRL_1);
- sw_w32(0x0, RTL931X_RMA_CTRL_2);
- }
-}
-
-static void rtl838x_eth_tx_timeout(struct net_device *ndev, unsigned int txqueue)
-{
- unsigned long flags;
- struct rtl838x_eth_priv *priv = netdev_priv(ndev);
-
- pr_warn("%s\n", __func__);
- spin_lock_irqsave(&priv->lock, flags);
- rtl838x_hw_stop(priv);
- rtl838x_hw_ring_setup(priv);
- rtl838x_hw_en_rxtx(priv);
- netif_trans_update(ndev);
- netif_start_queue(ndev);
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static int rtl838x_eth_tx(struct sk_buff *skb, struct net_device *dev)
-{
- int len;
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
- struct ring_b *ring = priv->membase;
- int ret;
- unsigned long flags;
- struct p_hdr *h;
- int dest_port = -1;
- int q = skb_get_queue_mapping(skb) % TXRINGS;
-
- if (q) /* Check for high prio queue */
- pr_debug("SKB priority: %d\n", skb->priority);
-
- spin_lock_irqsave(&priv->lock, flags);
- len = skb->len;
-
- /* Check for DSA tagging at the end of the buffer */
- if (netdev_uses_dsa(dev) &&
- skb->data[len - 4] == 0x80 &&
- skb->data[len - 3] < priv->cpu_port &&
- skb->data[len - 2] == 0x10 &&
- skb->data[len - 1] == 0x00) {
- /* Reuse tag space for CRC if possible */
- dest_port = skb->data[len - 3];
- skb->data[len - 4] = skb->data[len - 3] = skb->data[len - 2] = skb->data[len - 1] = 0x00;
- len -= 4;
- }
-
- len += 4; /* Add space for CRC */
-
- if (skb_padto(skb, len)) {
- ret = NETDEV_TX_OK;
- goto txdone;
- }
-
- /* We can send this packet if CPU owns the descriptor */
- if (!(ring->tx_r[q][ring->c_tx[q]] & 0x1)) {
-
- /* Set descriptor for tx */
- h = &ring->tx_header[q][ring->c_tx[q]];
- h->size = len;
- h->len = len;
- /* On RTL8380 SoCs, small packet lengths being sent need adjustments */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- if (len < ETH_ZLEN - 4)
- h->len -= 4;
- }
-
- if (dest_port >= 0)
- priv->r->create_tx_header(h, dest_port, skb->priority >> 1);
-
- /* Copy packet data to tx buffer */
- memcpy((void *)KSEG1ADDR(h->buf), skb->data, len);
- /* Make sure packet data is visible to ASIC */
- wmb();
-
- /* Hand over to switch */
- ring->tx_r[q][ring->c_tx[q]] |= 1;
-
- /* Before starting TX, prevent a Lextra bus bug on RTL8380 SoCs */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- for (int i = 0; i < 10; i++) {
- u32 val = sw_r32(priv->r->dma_if_ctrl);
- if ((val & 0xc) == 0xc)
- break;
- }
- }
-
- /* Tell switch to send data */
- if (priv->family_id == RTL9310_FAMILY_ID || priv->family_id == RTL9300_FAMILY_ID) {
- /* Ring ID q == 0: Low priority, Ring ID = 1: High prio queue */
- if (!q)
- sw_w32_mask(0, BIT(2), priv->r->dma_if_ctrl);
- else
- sw_w32_mask(0, BIT(3), priv->r->dma_if_ctrl);
- } else {
- sw_w32_mask(0, TX_DO, priv->r->dma_if_ctrl);
- }
-
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += len;
- dev_kfree_skb(skb);
- ring->c_tx[q] = (ring->c_tx[q] + 1) % TXRINGLEN;
- ret = NETDEV_TX_OK;
- } else {
- dev_warn(&priv->pdev->dev, "Data is owned by switch\n");
- ret = NETDEV_TX_BUSY;
- }
-
-txdone:
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return ret;
-}
-
-/* Return queue number for TX. On the RTL83XX, these queues have equal priority
- * so we do round-robin
- */
-u16 rtl83xx_pick_tx_queue(struct net_device *dev, struct sk_buff *skb,
- struct net_device *sb_dev)
-{
- static u8 last = 0;
-
- last++;
- return last % TXRINGS;
-}
-
-/* Return queue number for TX. On the RTL93XX, queue 1 is the high priority queue
- */
-u16 rtl93xx_pick_tx_queue(struct net_device *dev, struct sk_buff *skb,
- struct net_device *sb_dev)
-{
- if (skb->priority >= TC_PRIO_CONTROL)
- return 1;
-
- return 0;
-}
-
-static int rtl838x_hw_receive(struct net_device *dev, int r, int budget)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
- struct ring_b *ring = priv->membase;
- LIST_HEAD(rx_list);
- unsigned long flags;
- int work_done = 0;
- u32 *last;
- bool dsa = netdev_uses_dsa(dev);
-
- pr_debug("---------------------------------------------------------- RX - %d\n", r);
- spin_lock_irqsave(&priv->lock, flags);
- last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4));
-
- do {
- struct sk_buff *skb;
- struct dsa_tag tag;
- struct p_hdr *h;
- u8 *skb_data;
- u8 *data;
- int len;
-
- if ((ring->rx_r[r][ring->c_rx[r]] & 0x1)) {
- if (&ring->rx_r[r][ring->c_rx[r]] != last) {
- netdev_warn(dev, "Ring contention: r: %x, last %x, cur %x\n",
- r, (uint32_t)last, (u32) &ring->rx_r[r][ring->c_rx[r]]);
- }
- break;
- }
-
- h = &ring->rx_header[r][ring->c_rx[r]];
- data = (u8 *)KSEG1ADDR(h->buf);
- len = h->len;
- if (!len)
- break;
- work_done++;
-
- len -= 4; /* strip the CRC */
- /* Add 4 bytes for cpu_tag */
- if (dsa)
- len += 4;
-
- skb = netdev_alloc_skb(dev, len + 4);
- skb_reserve(skb, NET_IP_ALIGN);
-
- if (likely(skb)) {
- /* BUG: Prevent bug on RTL838x SoCs */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- sw_w32(0xffffffff, priv->r->dma_if_rx_ring_size(0));
- for (int i = 0; i < priv->rxrings; i++) {
- unsigned int val;
-
- /* Update each ring cnt */
- val = sw_r32(priv->r->dma_if_rx_ring_cntr(i));
- sw_w32(val, priv->r->dma_if_rx_ring_cntr(i));
- }
- }
-
- skb_data = skb_put(skb, len);
- /* Make sure data is visible */
- mb();
- memcpy(skb->data, (u8 *)KSEG1ADDR(data), len);
- /* Overwrite CRC with cpu_tag */
- if (dsa) {
- priv->r->decode_tag(h, &tag);
- skb->data[len - 4] = 0x80;
- skb->data[len - 3] = tag.port;
- skb->data[len - 2] = 0x10;
- skb->data[len - 1] = 0x00;
- if (tag.l2_offloaded)
- skb->data[len - 3] |= 0x40;
- }
-
- if (tag.queue >= 0)
- pr_debug("Queue: %d, len: %d, reason %d port %d\n",
- tag.queue, len, tag.reason, tag.port);
-
- skb->protocol = eth_type_trans(skb, dev);
- if (dev->features & NETIF_F_RXCSUM) {
- if (tag.crc_error)
- skb_checksum_none_assert(skb);
- else
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- }
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += len;
-
- list_add_tail(&skb->list, &rx_list);
- } else {
- if (net_ratelimit())
- dev_warn(&dev->dev, "low on memory - packet dropped\n");
- dev->stats.rx_dropped++;
- }
-
- /* Reset header structure */
- memset(h, 0, sizeof(struct p_hdr));
- h->buf = data;
- h->size = RING_BUFFER;
-
- ring->rx_r[r][ring->c_rx[r]] = KSEG1ADDR(h) | 0x1 | (ring->c_rx[r] == (priv->rxringlen - 1) ?
- WRAP :
- 0x1);
- ring->c_rx[r] = (ring->c_rx[r] + 1) % priv->rxringlen;
- last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4));
- } while (&ring->rx_r[r][ring->c_rx[r]] != last && work_done < budget);
-
- netif_receive_skb_list(&rx_list);
-
- /* Update counters */
- priv->r->update_cntr(r, 0);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return work_done;
-}
-
-static int rtl838x_poll_rx(struct napi_struct *napi, int budget)
-{
- struct rtl838x_rx_q *rx_q = container_of(napi, struct rtl838x_rx_q, napi);
- struct rtl838x_eth_priv *priv = rx_q->priv;
- int work_done = 0;
- int r = rx_q->id;
- int work;
-
- while (work_done < budget) {
- work = rtl838x_hw_receive(priv->netdev, r, budget - work_done);
- if (!work)
- break;
- work_done += work;
- }
-
- if (work_done < budget) {
- napi_complete_done(napi, work_done);
-
- /* Enable RX interrupt */
- if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID)
- sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk);
- else
- sw_w32_mask(0, 0xf00ff | BIT(r + 8), priv->r->dma_if_intr_msk);
- }
-
- return work_done;
-}
-
-
-static void rtl838x_validate(struct phylink_config *config,
- unsigned long *supported,
- struct phylink_link_state *state)
-{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
- pr_debug("In %s\n", __func__);
-
- if (!phy_interface_mode_is_rgmii(state->interface) &&
- state->interface != PHY_INTERFACE_MODE_1000BASEX &&
- state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII &&
- state->interface != PHY_INTERFACE_MODE_GMII &&
- state->interface != PHY_INTERFACE_MODE_QSGMII &&
- state->interface != PHY_INTERFACE_MODE_INTERNAL &&
- state->interface != PHY_INTERFACE_MODE_SGMII) {
- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
- pr_err("Unsupported interface: %d\n", state->interface);
- return;
- }
-
- /* Allow all the expected bits */
- phylink_set(mask, Autoneg);
- phylink_set_port_modes(mask);
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
-
- /* With the exclusion of MII and Reverse MII, we support Gigabit,
- * including Half duplex
- */
- if (state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII) {
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 1000baseT_Half);
- }
-
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
-
- bitmap_and(supported, supported, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
- bitmap_and(state->advertising, state->advertising, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
-
-static void rtl838x_mac_config(struct phylink_config *config,
- unsigned int mode,
- const struct phylink_link_state *state)
-{
- /* This is only being called for the master device,
- * i.e. the CPU-Port. We don't need to do anything.
- */
-
- pr_info("In %s, mode %x\n", __func__, mode);
-}
-
-static void rtl838x_mac_an_restart(struct phylink_config *config)
-{
- struct net_device *dev = container_of(config->dev, struct net_device, dev);
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
-
- /* This works only on RTL838x chips */
- if (priv->family_id != RTL8380_FAMILY_ID)
- return;
-
- pr_debug("In %s\n", __func__);
- /* Restart by disabling and re-enabling link */
- sw_w32(0x6192D, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
- mdelay(20);
- sw_w32(0x6192F, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
-}
-
-static void rtl838x_mac_pcs_get_state(struct phylink_config *config,
- struct phylink_link_state *state)
-{
- u32 speed;
- struct net_device *dev = container_of(config->dev, struct net_device, dev);
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
- int port = priv->cpu_port;
-
- pr_info("In %s\n", __func__);
-
- state->link = priv->r->get_mac_link_sts(port) ? 1 : 0;
- state->duplex = priv->r->get_mac_link_dup_sts(port) ? 1 : 0;
-
- pr_info("%s link status is %d\n", __func__, state->link);
- speed = priv->r->get_mac_link_spd_sts(port);
- switch (speed) {
- case 0:
- state->speed = SPEED_10;
- break;
- case 1:
- state->speed = SPEED_100;
- break;
- case 2:
- state->speed = SPEED_1000;
- break;
- case 5:
- state->speed = SPEED_2500;
- break;
- case 6:
- state->speed = SPEED_5000;
- break;
- case 4:
- state->speed = SPEED_10000;
- break;
- default:
- state->speed = SPEED_UNKNOWN;
- break;
- }
-
- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
- if (priv->r->get_mac_rx_pause_sts(port))
- state->pause |= MLO_PAUSE_RX;
- if (priv->r->get_mac_tx_pause_sts(port))
- state->pause |= MLO_PAUSE_TX;
-}
-
-static void rtl838x_mac_link_down(struct phylink_config *config,
- unsigned int mode,
- phy_interface_t interface)
-{
- struct net_device *dev = container_of(config->dev, struct net_device, dev);
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
-
- pr_debug("In %s\n", __func__);
- /* Stop TX/RX to port */
- sw_w32_mask(0x03, 0, priv->r->mac_port_ctrl(priv->cpu_port));
-}
-
-static void rtl838x_mac_link_up(struct phylink_config *config,
- struct phy_device *phy, unsigned int mode,
- phy_interface_t interface, int speed, int duplex,
- bool tx_pause, bool rx_pause)
-{
- struct net_device *dev = container_of(config->dev, struct net_device, dev);
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
-
- pr_debug("In %s\n", __func__);
- /* Restart TX/RX to port */
- sw_w32_mask(0, 0x03, priv->r->mac_port_ctrl(priv->cpu_port));
-}
-
-static void rtl838x_set_mac_hw(struct net_device *dev, u8 *mac)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- pr_debug("In %s\n", __func__);
- sw_w32((mac[0] << 8) | mac[1], priv->r->mac);
- sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], priv->r->mac + 4);
-
- if (priv->family_id == RTL8380_FAMILY_ID) {
- /* 2 more registers, ALE/MAC block */
- sw_w32((mac[0] << 8) | mac[1], RTL838X_MAC_ALE);
- sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
- (RTL838X_MAC_ALE + 4));
-
- sw_w32((mac[0] << 8) | mac[1], RTL838X_MAC2);
- sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
- RTL838X_MAC2 + 4);
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static int rtl838x_set_mac_address(struct net_device *dev, void *p)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
- const struct sockaddr *addr = p;
- u8 *mac = (u8 *) (addr->sa_data);
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- dev_addr_set(dev, addr->sa_data);
- rtl838x_set_mac_hw(dev, mac);
-
- pr_info("Using MAC %08x%08x\n", sw_r32(priv->r->mac), sw_r32(priv->r->mac + 4));
-
- return 0;
-}
-
-static int rtl8390_init_mac(struct rtl838x_eth_priv *priv)
-{
- /* We will need to set-up EEE and the egress-rate limitation */
- return 0;
-}
-
-static int rtl8380_init_mac(struct rtl838x_eth_priv *priv)
-{
- if (priv->family_id == 0x8390)
- return rtl8390_init_mac(priv);
-
- /* At present we do not know how to set up EEE on any other SoC than RTL8380 */
- if (priv->family_id != 0x8380)
- return 0;
-
- pr_info("%s\n", __func__);
- /* fix timer for EEE */
- sw_w32(0x5001411, RTL838X_EEE_TX_TIMER_GIGA_CTRL);
- sw_w32(0x5001417, RTL838X_EEE_TX_TIMER_GELITE_CTRL);
-
- /* Init VLAN. TODO: Understand what is being done, here */
- if (priv->id == 0x8382) {
- for (int i = 0; i <= 28; i++)
- sw_w32(0, 0xd57c + i * 0x80);
- }
- if (priv->id == 0x8380) {
- for (int i = 8; i <= 28; i++)
- sw_w32(0, 0xd57c + i * 0x80);
- }
-
- return 0;
-}
-
-static int rtl838x_get_link_ksettings(struct net_device *ndev,
- struct ethtool_link_ksettings *cmd)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(ndev);
-
- pr_debug("%s called\n", __func__);
-
- return phylink_ethtool_ksettings_get(priv->phylink, cmd);
-}
-
-static int rtl838x_set_link_ksettings(struct net_device *ndev,
- const struct ethtool_link_ksettings *cmd)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(ndev);
-
- pr_debug("%s called\n", __func__);
-
- return phylink_ethtool_ksettings_set(priv->phylink, cmd);
-}
-
-static int rtl838x_mdio_read_paged(struct mii_bus *bus, int mii_id, u16 page, int regnum)
-{
- u32 val;
- int err;
- struct rtl838x_eth_priv *priv = bus->priv;
-
- if (mii_id >= 24 && mii_id <= 27 && priv->id == 0x8380)
- return rtl838x_read_sds_phy(mii_id, regnum);
-
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
- err = rtl838x_read_mmd_phy(mii_id,
- mdiobus_c45_devad(regnum),
- regnum, &val);
- pr_debug("MMD: %d dev %x register %x read %x, err %d\n", mii_id,
- mdiobus_c45_devad(regnum), mdiobus_c45_regad(regnum),
- val, err);
- } else {
- pr_debug("PHY: %d register %x read %x, err %d\n", mii_id, regnum, val, err);
- err = rtl838x_read_phy(mii_id, page, regnum, &val);
- }
- if (err)
- return err;
-
- return val;
-}
-
-static int rtl838x_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
- return rtl838x_mdio_read_paged(bus, mii_id, 0, regnum);
-}
-
-static int rtl839x_mdio_read_paged(struct mii_bus *bus, int mii_id, u16 page, int regnum)
-{
- u32 val;
- int err;
- struct rtl838x_eth_priv *priv = bus->priv;
-
- if (priv->phy_is_internal[mii_id])
- return rtl839x_read_sds_phy(mii_id, regnum);
-
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
- err = rtl839x_read_mmd_phy(mii_id,
- mdiobus_c45_devad(regnum),
- regnum, &val);
- pr_debug("MMD: %d dev %x register %x read %x, err %d\n", mii_id,
- mdiobus_c45_devad(regnum), mdiobus_c45_regad(regnum),
- val, err);
- } else {
- err = rtl839x_read_phy(mii_id, page, regnum, &val);
- pr_debug("PHY: %d register %x read %x, err %d\n", mii_id, regnum, val, err);
- }
-
- if (err)
- return err;
-
- return val;
-}
-
-static int rtl839x_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
- return rtl839x_mdio_read_paged(bus, mii_id, 0, regnum);
-}
-
-static int rtl930x_mdio_read_paged(struct mii_bus *bus, int mii_id, u16 page, int regnum)
-{
- u32 val;
- int err;
- struct rtl838x_eth_priv *priv = bus->priv;
-
- if (priv->phy_is_internal[mii_id])
- return rtl930x_read_sds_phy(priv->sds_id[mii_id], page, regnum);
-
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
- err = rtl930x_read_mmd_phy(mii_id,
- mdiobus_c45_devad(regnum),
- regnum, &val);
- pr_debug("MMD: %d dev %x register %x read %x, err %d\n", mii_id,
- mdiobus_c45_devad(regnum), mdiobus_c45_regad(regnum),
- val, err);
- } else {
- err = rtl930x_read_phy(mii_id, page, regnum, &val);
- pr_debug("PHY: %d register %x read %x, err %d\n", mii_id, regnum, val, err);
- }
-
- if (err)
- return err;
-
- return val;
-}
-
-static int rtl930x_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
- return rtl930x_mdio_read_paged(bus, mii_id, 0, regnum);
-}
-
-static int rtl931x_mdio_read_paged(struct mii_bus *bus, int mii_id, u16 page, int regnum)
-{
- u32 val;
- int err, v;
- struct rtl838x_eth_priv *priv = bus->priv;
-
- pr_debug("%s: In here, port %d\n", __func__, mii_id);
- if (priv->phy_is_internal[mii_id]) {
- v = rtl931x_read_sds_phy(priv->sds_id[mii_id], page, regnum);
- if (v < 0) {
- err = v;
- } else {
- err = 0;
- val = v;
- }
- } else {
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
- err = rtl931x_read_mmd_phy(mii_id,
- mdiobus_c45_devad(regnum),
- regnum, &val);
- pr_debug("MMD: %d dev %x register %x read %x, err %d\n", mii_id,
- mdiobus_c45_devad(regnum), mdiobus_c45_regad(regnum),
- val, err);
- } else {
- err = rtl931x_read_phy(mii_id, page, regnum, &val);
- pr_debug("PHY: %d register %x read %x, err %d\n", mii_id, regnum, val, err);
- }
- }
-
- if (err)
- return err;
-
- return val;
-}
-
-static int rtl931x_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
- return rtl931x_mdio_read_paged(bus, mii_id, 0, regnum);
-}
-
-static int rtl838x_mdio_write_paged(struct mii_bus *bus, int mii_id, u16 page,
- int regnum, u16 value)
-{
- u32 offset = 0;
- struct rtl838x_eth_priv *priv = bus->priv;
- int err;
-
- if (mii_id >= 24 && mii_id <= 27 && priv->id == 0x8380) {
- if (mii_id == 26)
- offset = 0x100;
- sw_w32(value, RTL838X_SDS4_FIB_REG0 + offset + (regnum << 2));
- return 0;
- }
-
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
- err = rtl838x_write_mmd_phy(mii_id, mdiobus_c45_devad(regnum),
- regnum, value);
- pr_debug("MMD: %d dev %x register %x write %x, err %d\n", mii_id,
- mdiobus_c45_devad(regnum), mdiobus_c45_regad(regnum),
- value, err);
-
- return err;
- }
- err = rtl838x_write_phy(mii_id, page, regnum, value);
- pr_debug("PHY: %d register %x write %x, err %d\n", mii_id, regnum, value, err);
-
- return err;
-}
-
-static int rtl838x_mdio_write(struct mii_bus *bus, int mii_id,
- int regnum, u16 value)
-{
- return rtl838x_mdio_write_paged(bus, mii_id, 0, regnum, value);
-}
-
-static int rtl839x_mdio_write_paged(struct mii_bus *bus, int mii_id, u16 page,
- int regnum, u16 value)
-{
- struct rtl838x_eth_priv *priv = bus->priv;
- int err;
-
- if (priv->phy_is_internal[mii_id])
- return rtl839x_write_sds_phy(mii_id, regnum, value);
-
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
- err = rtl839x_write_mmd_phy(mii_id, mdiobus_c45_devad(regnum),
- regnum, value);
- pr_debug("MMD: %d dev %x register %x write %x, err %d\n", mii_id,
- mdiobus_c45_devad(regnum), mdiobus_c45_regad(regnum),
- value, err);
-
- return err;
- }
-
- err = rtl839x_write_phy(mii_id, page, regnum, value);
- pr_debug("PHY: %d register %x write %x, err %d\n", mii_id, regnum, value, err);
-
- return err;
-}
-
-static int rtl839x_mdio_write(struct mii_bus *bus, int mii_id,
- int regnum, u16 value)
-{
- return rtl839x_mdio_write_paged(bus, mii_id, 0, regnum, value);
-}
-
-static int rtl930x_mdio_write_paged(struct mii_bus *bus, int mii_id, u16 page,
- int regnum, u16 value)
-{
- struct rtl838x_eth_priv *priv = bus->priv;
- int err;
-
- if (priv->phy_is_internal[mii_id])
- return rtl930x_write_sds_phy(priv->sds_id[mii_id], page, regnum, value);
-
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD))
- return rtl930x_write_mmd_phy(mii_id, mdiobus_c45_devad(regnum),
- regnum, value);
-
- err = rtl930x_write_phy(mii_id, page, regnum, value);
- pr_debug("PHY: %d register %x write %x, err %d\n", mii_id, regnum, value, err);
-
- return err;
-}
-
-static int rtl930x_mdio_write(struct mii_bus *bus, int mii_id,
- int regnum, u16 value)
-{
- return rtl930x_mdio_write_paged(bus, mii_id, 0, regnum, value);
-}
-
-static int rtl931x_mdio_write_paged(struct mii_bus *bus, int mii_id, u16 page,
- int regnum, u16 value)
-{
- struct rtl838x_eth_priv *priv = bus->priv;
- int err;
-
- if (priv->phy_is_internal[mii_id])
- return rtl931x_write_sds_phy(priv->sds_id[mii_id], page, regnum, value);
-
- if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
- err = rtl931x_write_mmd_phy(mii_id, mdiobus_c45_devad(regnum),
- regnum, value);
- pr_debug("MMD: %d dev %x register %x write %x, err %d\n", mii_id,
- mdiobus_c45_devad(regnum), mdiobus_c45_regad(regnum),
- value, err);
-
- return err;
- }
-
- err = rtl931x_write_phy(mii_id, page, regnum, value);
- pr_debug("PHY: %d register %x write %x, err %d\n", mii_id, regnum, value, err);
-
- return err;
-}
-
-static int rtl931x_mdio_write(struct mii_bus *bus, int mii_id,
- int regnum, u16 value)
-{
- return rtl931x_mdio_write_paged(bus, mii_id, 0, regnum, value);
-}
-
-static int rtl838x_mdio_reset(struct mii_bus *bus)
-{
- pr_debug("%s called\n", __func__);
- /* Disable MAC polling the PHY so that we can start configuration */
- sw_w32(0x00000000, RTL838X_SMI_POLL_CTRL);
-
- /* Enable PHY control via SoC */
- sw_w32_mask(0, 1 << 15, RTL838X_SMI_GLB_CTRL);
-
- /* Probably should reset all PHYs here... */
- return 0;
-}
-
-static int rtl839x_mdio_reset(struct mii_bus *bus)
-{
- return 0;
-
- pr_debug("%s called\n", __func__);
- /* BUG: The following does not work, but should! */
- /* Disable MAC polling the PHY so that we can start configuration */
- sw_w32(0x00000000, RTL839X_SMI_PORT_POLLING_CTRL);
- sw_w32(0x00000000, RTL839X_SMI_PORT_POLLING_CTRL + 4);
- /* Disable PHY polling via SoC */
- sw_w32_mask(1 << 7, 0, RTL839X_SMI_GLB_CTRL);
-
- /* Probably should reset all PHYs here... */
- return 0;
-}
-
-u8 mac_type_bit[RTL930X_CPU_PORT] = {0, 0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6,
- 8, 8, 8, 8, 10, 10, 10, 10, 12, 15, 18, 21};
-
-static int rtl930x_mdio_reset(struct mii_bus *bus)
-{
- struct rtl838x_eth_priv *priv = bus->priv;
- u32 c45_mask = 0;
- u32 poll_sel[2];
- u32 poll_ctrl = 0;
- u32 private_poll_mask = 0;
- u32 v;
- bool uses_usxgmii = false; /* For the Aquantia PHYs */
- bool uses_hisgmii = false; /* For the RTL8221/8226 */
-
- /* Mapping of port to phy-addresses on an SMI bus */
- poll_sel[0] = poll_sel[1] = 0;
- for (int i = 0; i < RTL930X_CPU_PORT; i++) {
- int pos;
-
- if (priv->smi_bus[i] > 3)
- continue;
- pos = (i % 6) * 5;
- sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos,
- RTL930X_SMI_PORT0_5_ADDR + (i / 6) * 4);
-
- pos = (i * 2) % 32;
- poll_sel[i / 16] |= priv->smi_bus[i] << pos;
- poll_ctrl |= BIT(20 + priv->smi_bus[i]);
- }
-
- /* Configure which SMI bus is behind which port number */
- sw_w32(poll_sel[0], RTL930X_SMI_PORT0_15_POLLING_SEL);
- sw_w32(poll_sel[1], RTL930X_SMI_PORT16_27_POLLING_SEL);
-
- /* Disable POLL_SEL for any SMI bus with a normal PHY (not RTL8295R for SFP+) */
- sw_w32_mask(poll_ctrl, 0, RTL930X_SMI_GLB_CTRL);
-
- /* Configure which SMI busses are polled in c45 based on a c45 PHY being on that bus */
- for (int i = 0; i < 4; i++)
- if (priv->smi_bus_isc45[i])
- c45_mask |= BIT(i + 16);
-
- pr_info("c45_mask: %08x\n", c45_mask);
- sw_w32_mask(0, c45_mask, RTL930X_SMI_GLB_CTRL);
-
- /* Set the MAC type of each port according to the PHY-interface */
- /* Values are FE: 2, GE: 3, XGE/2.5G: 0(SERDES) or 1(otherwise), SXGE: 0 */
- v = 0;
- for (int i = 0; i < RTL930X_CPU_PORT; i++) {
- switch (priv->interfaces[i]) {
- case PHY_INTERFACE_MODE_10GBASER:
- break; /* Serdes: Value = 0 */
- case PHY_INTERFACE_MODE_HSGMII:
- private_poll_mask |= BIT(i);
- fallthrough;
- case PHY_INTERFACE_MODE_USXGMII:
- v |= BIT(mac_type_bit[i]);
- uses_usxgmii = true;
- break;
- case PHY_INTERFACE_MODE_QSGMII:
- private_poll_mask |= BIT(i);
- v |= 3 << mac_type_bit[i];
- break;
- default:
- break;
- }
- }
- sw_w32(v, RTL930X_SMI_MAC_TYPE_CTRL);
-
- /* Set the private polling mask for all Realtek PHYs (i.e. not the 10GBit Aquantia ones) */
- sw_w32(private_poll_mask, RTL930X_SMI_PRVTE_POLLING_CTRL);
-
- /* The following magic values are found in the port configuration, they seem to
- * define different ways of polling a PHY. The below is for the Aquantia PHYs of
- * the XGS1250 and the RTL8226 of the XGS1210
- */
- if (uses_usxgmii) {
- sw_w32(0x01010000, RTL930X_SMI_10GPHY_POLLING_REG0_CFG);
- sw_w32(0x01E7C400, RTL930X_SMI_10GPHY_POLLING_REG9_CFG);
- sw_w32(0x01E7E820, RTL930X_SMI_10GPHY_POLLING_REG10_CFG);
- }
- if (uses_hisgmii) {
- sw_w32(0x011FA400, RTL930X_SMI_10GPHY_POLLING_REG0_CFG);
- sw_w32(0x013FA412, RTL930X_SMI_10GPHY_POLLING_REG9_CFG);
- sw_w32(0x017FA414, RTL930X_SMI_10GPHY_POLLING_REG10_CFG);
- }
-
- pr_debug("%s: RTL930X_SMI_GLB_CTRL %08x\n", __func__,
- sw_r32(RTL930X_SMI_GLB_CTRL));
- pr_debug("%s: RTL930X_SMI_PORT0_15_POLLING_SEL %08x\n", __func__,
- sw_r32(RTL930X_SMI_PORT0_15_POLLING_SEL));
- pr_debug("%s: RTL930X_SMI_PORT16_27_POLLING_SEL %08x\n", __func__,
- sw_r32(RTL930X_SMI_PORT16_27_POLLING_SEL));
- pr_debug("%s: RTL930X_SMI_MAC_TYPE_CTRL %08x\n", __func__,
- sw_r32(RTL930X_SMI_MAC_TYPE_CTRL));
- pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG0_CFG %08x\n", __func__,
- sw_r32(RTL930X_SMI_10GPHY_POLLING_REG0_CFG));
- pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG9_CFG %08x\n", __func__,
- sw_r32(RTL930X_SMI_10GPHY_POLLING_REG9_CFG));
- pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG10_CFG %08x\n", __func__,
- sw_r32(RTL930X_SMI_10GPHY_POLLING_REG10_CFG));
- pr_debug("%s: RTL930X_SMI_PRVTE_POLLING_CTRL %08x\n", __func__,
- sw_r32(RTL930X_SMI_PRVTE_POLLING_CTRL));
-
- return 0;
-}
-
-static int rtl931x_mdio_reset(struct mii_bus *bus)
-{
- struct rtl838x_eth_priv *priv = bus->priv;
- u32 c45_mask = 0;
- u32 poll_sel[4];
- u32 poll_ctrl = 0;
- bool mdc_on[4];
-
- pr_info("%s called\n", __func__);
- /* Disable port polling for configuration purposes */
- sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL);
- sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL + 4);
- msleep(100);
-
- mdc_on[0] = mdc_on[1] = mdc_on[2] = mdc_on[3] = false;
- /* Mapping of port to phy-addresses on an SMI bus */
- poll_sel[0] = poll_sel[1] = poll_sel[2] = poll_sel[3] = 0;
- for (int i = 0; i < 56; i++) {
- u32 pos;
-
- pos = (i % 6) * 5;
- sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos, RTL931X_SMI_PORT_ADDR + (i / 6) * 4);
- pos = (i * 2) % 32;
- poll_sel[i / 16] |= priv->smi_bus[i] << pos;
- poll_ctrl |= BIT(20 + priv->smi_bus[i]);
- mdc_on[priv->smi_bus[i]] = true;
- }
-
- /* Configure which SMI bus is behind which port number */
- for (int i = 0; i < 4; i++) {
- pr_info("poll sel %d, %08x\n", i, poll_sel[i]);
- sw_w32(poll_sel[i], RTL931X_SMI_PORT_POLLING_SEL + (i * 4));
- }
-
- /* Configure which SMI busses */
- pr_info("%s: WAS RTL931X_MAC_L2_GLOBAL_CTRL2 %08x\n", __func__, sw_r32(RTL931X_MAC_L2_GLOBAL_CTRL2));
- pr_info("c45_mask: %08x, RTL931X_SMI_GLB_CTRL0 was %X", c45_mask, sw_r32(RTL931X_SMI_GLB_CTRL0));
- for (int i = 0; i < 4; i++) {
- /* bus is polled in c45 */
- if (priv->smi_bus_isc45[i])
- c45_mask |= 0x2 << (i * 2); /* Std. C45, non-standard is 0x3 */
- /* Enable bus access via MDC */
- if (mdc_on[i])
- sw_w32_mask(0, BIT(9 + i), RTL931X_MAC_L2_GLOBAL_CTRL2);
- }
-
- pr_info("%s: RTL931X_MAC_L2_GLOBAL_CTRL2 %08x\n", __func__, sw_r32(RTL931X_MAC_L2_GLOBAL_CTRL2));
- pr_info("c45_mask: %08x, RTL931X_SMI_GLB_CTRL0 was %X", c45_mask, sw_r32(RTL931X_SMI_GLB_CTRL0));
-
- /* We have a 10G PHY enable polling
- * sw_w32(0x01010000, RTL931X_SMI_10GPHY_POLLING_SEL2);
- * sw_w32(0x01E7C400, RTL931X_SMI_10GPHY_POLLING_SEL3);
- * sw_w32(0x01E7E820, RTL931X_SMI_10GPHY_POLLING_SEL4);
- */
- sw_w32_mask(0xff, c45_mask, RTL931X_SMI_GLB_CTRL1);
-
- return 0;
-}
-
-static int rtl931x_chip_init(struct rtl838x_eth_priv *priv)
-{
- pr_info("In %s\n", __func__);
-
- /* Initialize Encapsulation memory and wait until finished */
- sw_w32(0x1, RTL931X_MEM_ENCAP_INIT);
- do { } while (sw_r32(RTL931X_MEM_ENCAP_INIT) & 1);
- pr_info("%s: init ENCAP done\n", __func__);
-
- /* Initialize Managemen Information Base memory and wait until finished */
- sw_w32(0x1, RTL931X_MEM_MIB_INIT);
- do { } while (sw_r32(RTL931X_MEM_MIB_INIT) & 1);
- pr_info("%s: init MIB done\n", __func__);
-
- /* Initialize ACL (PIE) memory and wait until finished */
- sw_w32(0x1, RTL931X_MEM_ACL_INIT);
- do { } while (sw_r32(RTL931X_MEM_ACL_INIT) & 1);
- pr_info("%s: init ACL done\n", __func__);
-
- /* Initialize ALE memory and wait until finished */
- sw_w32(0xFFFFFFFF, RTL931X_MEM_ALE_INIT_0);
- do { } while (sw_r32(RTL931X_MEM_ALE_INIT_0));
- sw_w32(0x7F, RTL931X_MEM_ALE_INIT_1);
- sw_w32(0x7ff, RTL931X_MEM_ALE_INIT_2);
- do { } while (sw_r32(RTL931X_MEM_ALE_INIT_2) & 0x7ff);
- pr_info("%s: init ALE done\n", __func__);
-
- /* Enable ESD auto recovery */
- sw_w32(0x1, RTL931X_MDX_CTRL_RSVD);
-
- /* Init SPI, is this for thermal control or what? */
- sw_w32_mask(0x7 << 11, 0x2 << 11, RTL931X_SPI_CTRL0);
-
- return 0;
-}
-
-static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
-{
- struct device_node *mii_np, *dn;
- u32 pn;
- int ret;
-
- pr_debug("%s called\n", __func__);
- mii_np = of_get_child_by_name(priv->pdev->dev.of_node, "mdio-bus");
-
- if (!mii_np) {
- dev_err(&priv->pdev->dev, "no %s child node found", "mdio-bus");
- return -ENODEV;
- }
-
- if (!of_device_is_available(mii_np)) {
- ret = -ENODEV;
- goto err_put_node;
- }
-
- priv->mii_bus = devm_mdiobus_alloc(&priv->pdev->dev);
- if (!priv->mii_bus) {
- ret = -ENOMEM;
- goto err_put_node;
- }
-
- switch(priv->family_id) {
- case RTL8380_FAMILY_ID:
- priv->mii_bus->name = "rtl838x-eth-mdio";
- priv->mii_bus->read = rtl838x_mdio_read;
- priv->mii_bus->read_paged = rtl838x_mdio_read_paged;
- priv->mii_bus->write = rtl838x_mdio_write;
- priv->mii_bus->write_paged = rtl838x_mdio_write_paged;
- priv->mii_bus->reset = rtl838x_mdio_reset;
- break;
- case RTL8390_FAMILY_ID:
- priv->mii_bus->name = "rtl839x-eth-mdio";
- priv->mii_bus->read = rtl839x_mdio_read;
- priv->mii_bus->read_paged = rtl839x_mdio_read_paged;
- priv->mii_bus->write = rtl839x_mdio_write;
- priv->mii_bus->write_paged = rtl839x_mdio_write_paged;
- priv->mii_bus->reset = rtl839x_mdio_reset;
- break;
- case RTL9300_FAMILY_ID:
- priv->mii_bus->name = "rtl930x-eth-mdio";
- priv->mii_bus->read = rtl930x_mdio_read;
- priv->mii_bus->read_paged = rtl930x_mdio_read_paged;
- priv->mii_bus->write = rtl930x_mdio_write;
- priv->mii_bus->write_paged = rtl930x_mdio_write_paged;
- priv->mii_bus->reset = rtl930x_mdio_reset;
- priv->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
- break;
- case RTL9310_FAMILY_ID:
- priv->mii_bus->name = "rtl931x-eth-mdio";
- priv->mii_bus->read = rtl931x_mdio_read;
- priv->mii_bus->read_paged = rtl931x_mdio_read_paged;
- priv->mii_bus->write = rtl931x_mdio_write;
- priv->mii_bus->write_paged = rtl931x_mdio_write_paged;
- priv->mii_bus->reset = rtl931x_mdio_reset;
- priv->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
- break;
- }
- priv->mii_bus->access_capabilities = MDIOBUS_ACCESS_C22_MMD;
- priv->mii_bus->priv = priv;
- priv->mii_bus->parent = &priv->pdev->dev;
-
- for_each_node_by_name(dn, "ethernet-phy") {
- u32 smi_addr[2];
-
- if (of_property_read_u32(dn, "reg", &pn))
- continue;
-
- if (of_property_read_u32_array(dn, "rtl9300,smi-address", &smi_addr[0], 2)) {
- smi_addr[0] = 0;
- smi_addr[1] = pn;
- }
-
- if (of_property_read_u32(dn, "sds", &priv->sds_id[pn]))
- priv->sds_id[pn] = -1;
- else {
- pr_info("set sds port %d to %d\n", pn, priv->sds_id[pn]);
- }
-
- if (pn < MAX_PORTS) {
- priv->smi_bus[pn] = smi_addr[0];
- priv->smi_addr[pn] = smi_addr[1];
- } else {
- pr_err("%s: illegal port number %d\n", __func__, pn);
- }
-
- if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45"))
- priv->smi_bus_isc45[smi_addr[0]] = true;
-
- if (of_property_read_bool(dn, "phy-is-integrated")) {
- priv->phy_is_internal[pn] = true;
- }
- }
-
- dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch");
- if (!dn) {
- dev_err(&priv->pdev->dev, "No RTL switch node in DTS\n");
- return -ENODEV;
- }
-
- for_each_node_by_name(dn, "port") {
- if (of_property_read_u32(dn, "reg", &pn))
- continue;
- pr_debug("%s Looking at port %d\n", __func__, pn);
- if (pn > priv->cpu_port)
- continue;
- if (of_get_phy_mode(dn, &priv->interfaces[pn]))
- priv->interfaces[pn] = PHY_INTERFACE_MODE_NA;
- pr_debug("%s phy mode of port %d is %s\n", __func__, pn, phy_modes(priv->interfaces[pn]));
- }
-
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
- ret = of_mdiobus_register(priv->mii_bus, mii_np);
-
-err_put_node:
- of_node_put(mii_np);
-
- return ret;
-}
-
-static int rtl838x_mdio_remove(struct rtl838x_eth_priv *priv)
-{
- pr_debug("%s called\n", __func__);
- if (!priv->mii_bus)
- return 0;
-
- mdiobus_unregister(priv->mii_bus);
- mdiobus_free(priv->mii_bus);
-
- return 0;
-}
-
-static netdev_features_t rtl838x_fix_features(struct net_device *dev,
- netdev_features_t features)
-{
- return features;
-}
-
-static int rtl83xx_set_features(struct net_device *dev, netdev_features_t features)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
-
- if ((features ^ dev->features) & NETIF_F_RXCSUM) {
- if (!(features & NETIF_F_RXCSUM))
- sw_w32_mask(BIT(3), 0, priv->r->mac_port_ctrl(priv->cpu_port));
- else
- sw_w32_mask(0, BIT(3), priv->r->mac_port_ctrl(priv->cpu_port));
- }
-
- return 0;
-}
-
-static int rtl93xx_set_features(struct net_device *dev, netdev_features_t features)
-{
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
-
- if ((features ^ dev->features) & NETIF_F_RXCSUM) {
- if (!(features & NETIF_F_RXCSUM))
- sw_w32_mask(BIT(4), 0, priv->r->mac_port_ctrl(priv->cpu_port));
- else
- sw_w32_mask(0, BIT(4), priv->r->mac_port_ctrl(priv->cpu_port));
- }
-
- return 0;
-}
-
-static const struct net_device_ops rtl838x_eth_netdev_ops = {
- .ndo_open = rtl838x_eth_open,
- .ndo_stop = rtl838x_eth_stop,
- .ndo_start_xmit = rtl838x_eth_tx,
- .ndo_select_queue = rtl83xx_pick_tx_queue,
- .ndo_set_mac_address = rtl838x_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = rtl838x_eth_set_multicast_list,
- .ndo_tx_timeout = rtl838x_eth_tx_timeout,
- .ndo_set_features = rtl83xx_set_features,
- .ndo_fix_features = rtl838x_fix_features,
- .ndo_setup_tc = rtl83xx_setup_tc,
-};
-
-static const struct net_device_ops rtl839x_eth_netdev_ops = {
- .ndo_open = rtl838x_eth_open,
- .ndo_stop = rtl838x_eth_stop,
- .ndo_start_xmit = rtl838x_eth_tx,
- .ndo_select_queue = rtl83xx_pick_tx_queue,
- .ndo_set_mac_address = rtl838x_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = rtl839x_eth_set_multicast_list,
- .ndo_tx_timeout = rtl838x_eth_tx_timeout,
- .ndo_set_features = rtl83xx_set_features,
- .ndo_fix_features = rtl838x_fix_features,
- .ndo_setup_tc = rtl83xx_setup_tc,
-};
-
-static const struct net_device_ops rtl930x_eth_netdev_ops = {
- .ndo_open = rtl838x_eth_open,
- .ndo_stop = rtl838x_eth_stop,
- .ndo_start_xmit = rtl838x_eth_tx,
- .ndo_select_queue = rtl93xx_pick_tx_queue,
- .ndo_set_mac_address = rtl838x_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = rtl930x_eth_set_multicast_list,
- .ndo_tx_timeout = rtl838x_eth_tx_timeout,
- .ndo_set_features = rtl93xx_set_features,
- .ndo_fix_features = rtl838x_fix_features,
- .ndo_setup_tc = rtl83xx_setup_tc,
-};
-
-static const struct net_device_ops rtl931x_eth_netdev_ops = {
- .ndo_open = rtl838x_eth_open,
- .ndo_stop = rtl838x_eth_stop,
- .ndo_start_xmit = rtl838x_eth_tx,
- .ndo_select_queue = rtl93xx_pick_tx_queue,
- .ndo_set_mac_address = rtl838x_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = rtl931x_eth_set_multicast_list,
- .ndo_tx_timeout = rtl838x_eth_tx_timeout,
- .ndo_set_features = rtl93xx_set_features,
- .ndo_fix_features = rtl838x_fix_features,
-};
-
-static const struct phylink_mac_ops rtl838x_phylink_ops = {
- .validate = rtl838x_validate,
- .mac_pcs_get_state = rtl838x_mac_pcs_get_state,
- .mac_an_restart = rtl838x_mac_an_restart,
- .mac_config = rtl838x_mac_config,
- .mac_link_down = rtl838x_mac_link_down,
- .mac_link_up = rtl838x_mac_link_up,
-};
-
-static const struct ethtool_ops rtl838x_ethtool_ops = {
- .get_link_ksettings = rtl838x_get_link_ksettings,
- .set_link_ksettings = rtl838x_set_link_ksettings,
-};
-
-static int __init rtl838x_eth_probe(struct platform_device *pdev)
-{
- struct net_device *dev;
- struct device_node *dn = pdev->dev.of_node;
- struct rtl838x_eth_priv *priv;
- struct resource *res, *mem;
- phy_interface_t phy_mode;
- struct phylink *phylink;
- u8 mac_addr[ETH_ALEN];
- int err = 0, rxrings, rxringlen;
- struct ring_b *ring;
-
- pr_info("Probing RTL838X eth device pdev: %x, dev: %x\n",
- (u32)pdev, (u32)(&(pdev->dev)));
-
- if (!dn) {
- dev_err(&pdev->dev, "No DT found\n");
- return -EINVAL;
- }
-
- rxrings = (soc_info.family == RTL8380_FAMILY_ID
- || soc_info.family == RTL8390_FAMILY_ID) ? 8 : 32;
- rxrings = rxrings > MAX_RXRINGS ? MAX_RXRINGS : rxrings;
- rxringlen = MAX_ENTRIES / rxrings;
- rxringlen = rxringlen > MAX_RXLEN ? MAX_RXLEN : rxringlen;
-
- dev = alloc_etherdev_mqs(sizeof(struct rtl838x_eth_priv), TXRINGS, rxrings);
- if (!dev) {
- err = -ENOMEM;
- goto err_free;
- }
- SET_NETDEV_DEV(dev, &pdev->dev);
- priv = netdev_priv(dev);
-
- /* obtain buffer memory space */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res) {
- mem = devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res), res->name);
- if (!mem) {
- dev_err(&pdev->dev, "cannot request memory space\n");
- err = -ENXIO;
- goto err_free;
- }
-
- dev->mem_start = mem->start;
- dev->mem_end = mem->end;
- } else {
- dev_err(&pdev->dev, "cannot request IO resource\n");
- err = -ENXIO;
- goto err_free;
- }
-
- /* Allocate buffer memory */
- priv->membase = dmam_alloc_coherent(&pdev->dev, rxrings * rxringlen * RING_BUFFER +
- sizeof(struct ring_b) + sizeof(struct notify_b),
- (void *)&dev->mem_start, GFP_KERNEL);
- if (!priv->membase) {
- dev_err(&pdev->dev, "cannot allocate DMA buffer\n");
- err = -ENOMEM;
- goto err_free;
- }
-
- /* Allocate ring-buffer space at the end of the allocated memory */
- ring = priv->membase;
- ring->rx_space = priv->membase + sizeof(struct ring_b) + sizeof(struct notify_b);
-
- spin_lock_init(&priv->lock);
-
- dev->ethtool_ops = &rtl838x_ethtool_ops;
- dev->min_mtu = ETH_ZLEN;
- dev->max_mtu = DEFAULT_MTU;
- dev->features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM;
- dev->hw_features = NETIF_F_RXCSUM;
-
- priv->id = soc_info.id;
- priv->family_id = soc_info.family;
- if (priv->id) {
- pr_info("Found SoC ID: %4x: %s, family %x\n",
- priv->id, soc_info.name, priv->family_id);
- } else {
- pr_err("Unknown chip id (%04x)\n", priv->id);
- return -ENODEV;
- }
-
- switch (priv->family_id) {
- case RTL8380_FAMILY_ID:
- priv->cpu_port = RTL838X_CPU_PORT;
- priv->r = &rtl838x_reg;
- dev->netdev_ops = &rtl838x_eth_netdev_ops;
- break;
- case RTL8390_FAMILY_ID:
- priv->cpu_port = RTL839X_CPU_PORT;
- priv->r = &rtl839x_reg;
- dev->netdev_ops = &rtl839x_eth_netdev_ops;
- break;
- case RTL9300_FAMILY_ID:
- priv->cpu_port = RTL930X_CPU_PORT;
- priv->r = &rtl930x_reg;
- dev->netdev_ops = &rtl930x_eth_netdev_ops;
- break;
- case RTL9310_FAMILY_ID:
- priv->cpu_port = RTL931X_CPU_PORT;
- priv->r = &rtl931x_reg;
- dev->netdev_ops = &rtl931x_eth_netdev_ops;
- rtl931x_chip_init(priv);
- break;
- default:
- pr_err("Unknown SoC family\n");
- return -ENODEV;
- }
- priv->rxringlen = rxringlen;
- priv->rxrings = rxrings;
-
- /* Obtain device IRQ number */
- dev->irq = platform_get_irq(pdev, 0);
- if (dev->irq < 0) {
- dev_err(&pdev->dev, "cannot obtain network-device IRQ\n");
- goto err_free;
- }
-
- err = devm_request_irq(&pdev->dev, dev->irq, priv->r->net_irq,
- IRQF_SHARED, dev->name, dev);
- if (err) {
- dev_err(&pdev->dev, "%s: could not acquire interrupt: %d\n",
- __func__, err);
- goto err_free;
- }
-
- rtl8380_init_mac(priv);
-
- /* Try to get mac address in the following order:
- * 1) from device tree data
- * 2) from internal registers set by bootloader
- */
- of_get_mac_address(pdev->dev.of_node, mac_addr);
- if (is_valid_ether_addr(mac_addr)) {
- rtl838x_set_mac_hw(dev, mac_addr);
- } else {
- mac_addr[0] = (sw_r32(priv->r->mac) >> 8) & 0xff;
- mac_addr[1] = sw_r32(priv->r->mac) & 0xff;
- mac_addr[2] = (sw_r32(priv->r->mac + 4) >> 24) & 0xff;
- mac_addr[3] = (sw_r32(priv->r->mac + 4) >> 16) & 0xff;
- mac_addr[4] = (sw_r32(priv->r->mac + 4) >> 8) & 0xff;
- mac_addr[5] = sw_r32(priv->r->mac + 4) & 0xff;
- }
- dev_addr_set(dev, mac_addr);
- /* if the address is invalid, use a random value */
- if (!is_valid_ether_addr(dev->dev_addr)) {
- struct sockaddr sa = { AF_UNSPEC };
-
- netdev_warn(dev, "Invalid MAC address, using random\n");
- eth_hw_addr_random(dev);
- memcpy(sa.sa_data, dev->dev_addr, ETH_ALEN);
- if (rtl838x_set_mac_address(dev, &sa))
- netdev_warn(dev, "Failed to set MAC address.\n");
- }
- pr_info("Using MAC %08x%08x\n", sw_r32(priv->r->mac),
- sw_r32(priv->r->mac + 4));
- strcpy(dev->name, "eth%d");
- priv->pdev = pdev;
- priv->netdev = dev;
-
- err = rtl838x_mdio_init(priv);
- if (err)
- goto err_free;
-
- err = register_netdev(dev);
- if (err)
- goto err_free;
-
- for (int i = 0; i < priv->rxrings; i++) {
- priv->rx_qs[i].id = i;
- priv->rx_qs[i].priv = priv;
- netif_napi_add(dev, &priv->rx_qs[i].napi, rtl838x_poll_rx, 64);
- }
-
- platform_set_drvdata(pdev, dev);
-
- phy_mode = PHY_INTERFACE_MODE_NA;
- err = of_get_phy_mode(dn, &phy_mode);
- if (err < 0) {
- dev_err(&pdev->dev, "incorrect phy-mode\n");
- err = -EINVAL;
- goto err_free;
- }
- priv->phylink_config.dev = &dev->dev;
- priv->phylink_config.type = PHYLINK_NETDEV;
-
- phylink = phylink_create(&priv->phylink_config, pdev->dev.fwnode,
- phy_mode, &rtl838x_phylink_ops);
-
- if (IS_ERR(phylink)) {
- err = PTR_ERR(phylink);
- goto err_free;
- }
- priv->phylink = phylink;
-
- return 0;
-
-err_free:
- pr_err("Error setting up netdev, freeing it again.\n");
- free_netdev(dev);
-
- return err;
-}
-
-static int rtl838x_eth_remove(struct platform_device *pdev)
-{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct rtl838x_eth_priv *priv = netdev_priv(dev);
-
- if (dev) {
- pr_info("Removing platform driver for rtl838x-eth\n");
- rtl838x_mdio_remove(priv);
- rtl838x_hw_stop(priv);
-
- netif_tx_stop_all_queues(dev);
-
- for (int i = 0; i < priv->rxrings; i++)
- netif_napi_del(&priv->rx_qs[i].napi);
-
- unregister_netdev(dev);
- free_netdev(dev);
- }
-
- return 0;
-}
-
-static const struct of_device_id rtl838x_eth_of_ids[] = {
- { .compatible = "realtek,rtl838x-eth"},
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, rtl838x_eth_of_ids);
-
-static struct platform_driver rtl838x_eth_driver = {
- .probe = rtl838x_eth_probe,
- .remove = rtl838x_eth_remove,
- .driver = {
- .name = "rtl838x-eth",
- .pm = NULL,
- .of_match_table = rtl838x_eth_of_ids,
- },
-};
-
-module_platform_driver(rtl838x_eth_driver);
-
-MODULE_AUTHOR("B. Koblitz");
-MODULE_DESCRIPTION("RTL838X SoC Ethernet Driver");
-MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h
deleted file mode 100644
index 47ed286aa4..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h
+++ /dev/null
@@ -1,458 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef _RTL838X_ETH_H
-#define _RTL838X_ETH_H
-
-/* Register definition */
-
-/* Per port MAC control */
-#define RTL838X_MAC_PORT_CTRL (0xd560)
-#define RTL839X_MAC_PORT_CTRL (0x8004)
-#define RTL930X_MAC_L2_PORT_CTRL (0x3268)
-#define RTL930X_MAC_PORT_CTRL (0x3260)
-#define RTL931X_MAC_L2_PORT_CTRL (0x6000)
-#define RTL931X_MAC_PORT_CTRL (0x6004)
-
-/* DMA interrupt control and status registers */
-#define RTL838X_DMA_IF_CTRL (0x9f58)
-#define RTL838X_DMA_IF_INTR_STS (0x9f54)
-#define RTL838X_DMA_IF_INTR_MSK (0x9f50)
-
-#define RTL839X_DMA_IF_CTRL (0x786c)
-#define RTL839X_DMA_IF_INTR_STS (0x7868)
-#define RTL839X_DMA_IF_INTR_MSK (0x7864)
-
-#define RTL930X_DMA_IF_CTRL (0xe028)
-#define RTL930X_DMA_IF_INTR_RX_RUNOUT_STS (0xe01C)
-#define RTL930X_DMA_IF_INTR_RX_DONE_STS (0xe020)
-#define RTL930X_DMA_IF_INTR_TX_DONE_STS (0xe024)
-#define RTL930X_DMA_IF_INTR_RX_RUNOUT_MSK (0xe010)
-#define RTL930X_DMA_IF_INTR_RX_DONE_MSK (0xe014)
-#define RTL930X_DMA_IF_INTR_TX_DONE_MSK (0xe018)
-#define RTL930X_L2_NTFY_IF_INTR_MSK (0xe04C)
-#define RTL930X_L2_NTFY_IF_INTR_STS (0xe050)
-
-/* TODO: RTL931X_DMA_IF_CTRL has different bits meanings */
-#define RTL931X_DMA_IF_CTRL (0x0928)
-#define RTL931X_DMA_IF_INTR_RX_RUNOUT_STS (0x091c)
-#define RTL931X_DMA_IF_INTR_RX_DONE_STS (0x0920)
-#define RTL931X_DMA_IF_INTR_TX_DONE_STS (0x0924)
-#define RTL931X_DMA_IF_INTR_RX_RUNOUT_MSK (0x0910)
-#define RTL931X_DMA_IF_INTR_RX_DONE_MSK (0x0914)
-#define RTL931X_DMA_IF_INTR_TX_DONE_MSK (0x0918)
-#define RTL931X_L2_NTFY_IF_INTR_MSK (0x09E4)
-#define RTL931X_L2_NTFY_IF_INTR_STS (0x09E8)
-
-#define RTL838X_MAC_FORCE_MODE_CTRL (0xa104)
-#define RTL839X_MAC_FORCE_MODE_CTRL (0x02bc)
-#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C)
-#define RTL931X_MAC_FORCE_MODE_CTRL (0x0ddc)
-
-/* MAC address settings */
-#define RTL838X_MAC (0xa9ec)
-#define RTL839X_MAC (0x02b4)
-#define RTL838X_MAC_ALE (0x6b04)
-#define RTL838X_MAC2 (0xa320)
-#define RTL930X_MAC_L2_ADDR_CTRL (0xC714)
-#define RTL931X_MAC_L2_ADDR_CTRL (0x135c)
-
-/* Ringbuffer setup */
-#define RTL838X_DMA_RX_BASE (0x9f00)
-#define RTL839X_DMA_RX_BASE (0x780c)
-#define RTL930X_DMA_RX_BASE (0xdf00)
-#define RTL931X_DMA_RX_BASE (0x0800)
-
-#define RTL838X_DMA_TX_BASE (0x9f40)
-#define RTL839X_DMA_TX_BASE (0x784c)
-#define RTL930X_DMA_TX_BASE (0xe000)
-#define RTL931X_DMA_TX_BASE (0x0900)
-
-#define RTL838X_DMA_IF_RX_RING_SIZE (0xB7E4)
-#define RTL839X_DMA_IF_RX_RING_SIZE (0x6038)
-#define RTL930X_DMA_IF_RX_RING_SIZE (0x7C60)
-#define RTL931X_DMA_IF_RX_RING_SIZE (0x2080)
-
-#define RTL838X_DMA_IF_RX_RING_CNTR (0xB7E8)
-#define RTL839X_DMA_IF_RX_RING_CNTR (0x603c)
-#define RTL930X_DMA_IF_RX_RING_CNTR (0x7C8C)
-#define RTL931X_DMA_IF_RX_RING_CNTR (0x20AC)
-
-#define RTL838X_DMA_IF_RX_CUR (0x9F20)
-#define RTL839X_DMA_IF_RX_CUR (0x782c)
-#define RTL930X_DMA_IF_RX_CUR (0xdf80)
-#define RTL931X_DMA_IF_RX_CUR (0x0880)
-
-#define RTL838X_DMA_IF_TX_CUR_DESC_ADDR_CTRL (0x9F48)
-#define RTL930X_DMA_IF_TX_CUR_DESC_ADDR_CTRL (0xE008)
-
-#define RTL838X_DMY_REG31 (0x3b28)
-#define RTL838X_SDS_MODE_SEL (0x0028)
-#define RTL838X_SDS_CFG_REG (0x0034)
-#define RTL838X_INT_MODE_CTRL (0x005c)
-#define RTL838X_CHIP_INFO (0x00d8)
-#define RTL838X_SDS4_REG28 (0xef80)
-#define RTL838X_SDS4_DUMMY0 (0xef8c)
-#define RTL838X_SDS5_EXT_REG6 (0xf18c)
-
-/* L2 features */
-#define RTL839X_TBL_ACCESS_L2_CTRL (0x1180)
-#define RTL839X_TBL_ACCESS_L2_DATA(idx) (0x1184 + ((idx) << 2))
-#define RTL838X_TBL_ACCESS_CTRL_0 (0x6914)
-#define RTL838X_TBL_ACCESS_DATA_0(idx) (0x6918 + ((idx) << 2))
-
-/* MAC-side link state handling */
-#define RTL838X_MAC_LINK_STS (0xa188)
-#define RTL839X_MAC_LINK_STS (0x0390)
-#define RTL930X_MAC_LINK_STS (0xCB10)
-#define RTL931X_MAC_LINK_STS (0x0ec0)
-
-#define RTL838X_MAC_LINK_SPD_STS (0xa190)
-#define RTL839X_MAC_LINK_SPD_STS (0x03a0)
-#define RTL930X_MAC_LINK_SPD_STS (0xCB18)
-#define RTL931X_MAC_LINK_SPD_STS (0x0ed0)
-
-#define RTL838X_MAC_LINK_DUP_STS (0xa19c)
-#define RTL839X_MAC_LINK_DUP_STS (0x03b0)
-#define RTL930X_MAC_LINK_DUP_STS (0xCB28)
-#define RTL931X_MAC_LINK_DUP_STS (0x0ef0)
-
-/* TODO: RTL8390_MAC_LINK_MEDIA_STS_ADDR??? */
-
-#define RTL838X_MAC_TX_PAUSE_STS (0xa1a0)
-#define RTL839X_MAC_TX_PAUSE_STS (0x03b8)
-#define RTL930X_MAC_TX_PAUSE_STS (0xCB2C)
-#define RTL931X_MAC_TX_PAUSE_STS (0x0ef8)
-
-#define RTL838X_MAC_RX_PAUSE_STS (0xa1a4)
-#define RTL839X_MAC_RX_PAUSE_STS (0xCB30)
-#define RTL930X_MAC_RX_PAUSE_STS (0xC2F8)
-#define RTL931X_MAC_RX_PAUSE_STS (0x0f00)
-
-#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04)
-#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08)
-
-#define RTL930X_L2_UNKN_UC_FLD_PMSK (0x9064)
-#define RTL931X_L2_UNKN_UC_FLD_PMSK (0xC8F4)
-
-#define RTL839X_MAC_GLB_CTRL (0x02a8)
-#define RTL839X_SCHED_LB_TICK_TKN_CTRL (0x60f8)
-
-#define RTL838X_L2_TBL_FLUSH_CTRL (0x3370)
-#define RTL839X_L2_TBL_FLUSH_CTRL (0x3ba0)
-#define RTL930X_L2_TBL_FLUSH_CTRL (0x9404)
-#define RTL931X_L2_TBL_FLUSH_CTRL (0xCD9C)
-
-#define RTL930X_L2_PORT_SABLK_CTRL (0x905c)
-#define RTL930X_L2_PORT_DABLK_CTRL (0x9060)
-
-/* MAC link state bits */
-#define FORCE_EN (1 << 0)
-#define FORCE_LINK_EN (1 << 1)
-#define NWAY_EN (1 << 2)
-#define DUPLX_MODE (1 << 3)
-#define TX_PAUSE_EN (1 << 6)
-#define RX_PAUSE_EN (1 << 7)
-
-/* L2 Notification DMA interface */
-#define RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL (0x785C)
-#define RTL839X_L2_NOTIFICATION_CTRL (0x7808)
-#define RTL931X_L2_NTFY_RING_BASE_ADDR (0x09DC)
-#define RTL931X_L2_NTFY_RING_CUR_ADDR (0x09E0)
-#define RTL839X_L2_NOTIFICATION_CTRL (0x7808)
-#define RTL931X_L2_NTFY_CTRL (0xCDC8)
-#define RTL838X_L2_CTRL_0 (0x3200)
-#define RTL839X_L2_CTRL_0 (0x3800)
-#define RTL930X_L2_CTRL (0x8FD8)
-#define RTL931X_L2_CTRL (0xC800)
-
-/* TRAPPING to CPU-PORT */
-#define RTL838X_SPCL_TRAP_IGMP_CTRL (0x6984)
-#define RTL838X_RMA_CTRL_0 (0x4300)
-#define RTL838X_RMA_CTRL_1 (0x4304)
-#define RTL839X_RMA_CTRL_0 (0x1200)
-
-#define RTL839X_SPCL_TRAP_IGMP_CTRL (0x1058)
-#define RTL839X_RMA_CTRL_1 (0x1204)
-#define RTL839X_RMA_CTRL_2 (0x1208)
-#define RTL839X_RMA_CTRL_3 (0x120C)
-
-#define RTL930X_VLAN_APP_PKT_CTRL (0xA23C)
-#define RTL930X_RMA_CTRL_0 (0x9E60)
-#define RTL930X_RMA_CTRL_1 (0x9E64)
-#define RTL930X_RMA_CTRL_2 (0x9E68)
-
-#define RTL931X_VLAN_APP_PKT_CTRL (0x96b0)
-#define RTL931X_RMA_CTRL_0 (0x8800)
-#define RTL931X_RMA_CTRL_1 (0x8804)
-#define RTL931X_RMA_CTRL_2 (0x8808)
-
-/* Advanced SMI control for clause 45 PHYs */
-#define RTL930X_SMI_MAC_TYPE_CTRL (0xCA04)
-#define RTL930X_SMI_PORT24_27_ADDR_CTRL (0xCB90)
-#define RTL930X_SMI_PORT0_15_POLLING_SEL (0xCA08)
-#define RTL930X_SMI_PORT16_27_POLLING_SEL (0xCA0C)
-
-#define RTL930X_SMI_10GPHY_POLLING_REG0_CFG (0xCBB4)
-#define RTL930X_SMI_10GPHY_POLLING_REG9_CFG (0xCBB8)
-#define RTL930X_SMI_10GPHY_POLLING_REG10_CFG (0xCBBC)
-#define RTL930X_SMI_PRVTE_POLLING_CTRL (0xCA10)
-
-/* Registers of the internal Serdes of the 8390 */
-#define RTL839X_SDS12_13_XSG0 (0xB800)
-
-/* Chip configuration registers of the RTL9310 */
-#define RTL931X_MEM_ENCAP_INIT (0x4854)
-#define RTL931X_MEM_MIB_INIT (0x7E18)
-#define RTL931X_MEM_ACL_INIT (0x40BC)
-#define RTL931X_MEM_ALE_INIT_0 (0x83F0)
-#define RTL931X_MEM_ALE_INIT_1 (0x83F4)
-#define RTL931X_MEM_ALE_INIT_2 (0x82E4)
-#define RTL931X_MDX_CTRL_RSVD (0x0fcc)
-#define RTL931X_PS_SOC_CTRL (0x13f8)
-#define RTL931X_SMI_10GPHY_POLLING_SEL2 (0xCF8)
-#define RTL931X_SMI_10GPHY_POLLING_SEL3 (0xCFC)
-#define RTL931X_SMI_10GPHY_POLLING_SEL4 (0xD00)
-
-/* Registers of the internal Serdes of the 8380 */
-#define RTL838X_SDS4_FIB_REG0 (0xF800)
-
-/* Default MTU with jumbo frames support */
-#define DEFAULT_MTU 9000
-
-inline int rtl838x_mac_port_ctrl(int p)
-{
- return RTL838X_MAC_PORT_CTRL + (p << 7);
-}
-
-inline int rtl839x_mac_port_ctrl(int p)
-{
- return RTL839X_MAC_PORT_CTRL + (p << 7);
-}
-
-/* On the RTL931XX, the functionality of the MAC port control register is split up
- * into RTL931X_MAC_L2_PORT_CTRL and RTL931X_MAC_PORT_CTRL the functionality used
- * by the Ethernet driver is in the same bits now in RTL931X_MAC_L2_PORT_CTRL
- */
-
-inline int rtl930x_mac_port_ctrl(int p)
-{
- return RTL930X_MAC_L2_PORT_CTRL + (p << 6);
-}
-
-inline int rtl931x_mac_port_ctrl(int p)
-{
- return RTL931X_MAC_L2_PORT_CTRL + (p << 7);
-}
-
-inline int rtl838x_dma_if_rx_ring_size(int i)
-{
- return RTL838X_DMA_IF_RX_RING_SIZE + ((i >> 3) << 2);
-}
-
-inline int rtl839x_dma_if_rx_ring_size(int i)
-{
- return RTL839X_DMA_IF_RX_RING_SIZE + ((i >> 3) << 2);
-}
-
-inline int rtl930x_dma_if_rx_ring_size(int i)
-{
- return RTL930X_DMA_IF_RX_RING_SIZE + ((i / 3) << 2);
-}
-
-inline int rtl931x_dma_if_rx_ring_size(int i)
-{
- return RTL931X_DMA_IF_RX_RING_SIZE + ((i / 3) << 2);
-}
-
-inline int rtl838x_dma_if_rx_ring_cntr(int i)
-{
- return RTL838X_DMA_IF_RX_RING_CNTR + ((i >> 3) << 2);
-}
-
-inline int rtl839x_dma_if_rx_ring_cntr(int i)
-{
- return RTL839X_DMA_IF_RX_RING_CNTR + ((i >> 3) << 2);
-}
-
-inline int rtl930x_dma_if_rx_ring_cntr(int i)
-{
- return RTL930X_DMA_IF_RX_RING_CNTR + ((i / 3) << 2);
-}
-
-inline int rtl931x_dma_if_rx_ring_cntr(int i)
-{
- return RTL931X_DMA_IF_RX_RING_CNTR + ((i / 3) << 2);
-}
-
-inline u32 rtl838x_get_mac_link_sts(int port)
-{
- return (sw_r32(RTL838X_MAC_LINK_STS) & BIT(port));
-}
-
-inline u32 rtl839x_get_mac_link_sts(int p)
-{
- return (sw_r32(RTL839X_MAC_LINK_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-inline u32 rtl930x_get_mac_link_sts(int port)
-{
- u32 link = sw_r32(RTL930X_MAC_LINK_STS);
-
- link = sw_r32(RTL930X_MAC_LINK_STS);
- pr_info("%s link state is %08x\n", __func__, link);
- return link & BIT(port);
-}
-
-inline u32 rtl931x_get_mac_link_sts(int p)
-{
- return (sw_r32(RTL931X_MAC_LINK_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-inline u32 rtl838x_get_mac_link_dup_sts(int port)
-{
- return (sw_r32(RTL838X_MAC_LINK_DUP_STS) & BIT(port));
-}
-
-inline u32 rtl839x_get_mac_link_dup_sts(int p)
-{
- return (sw_r32(RTL839X_MAC_LINK_DUP_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-inline u32 rtl930x_get_mac_link_dup_sts(int port)
-{
- return (sw_r32(RTL930X_MAC_LINK_DUP_STS) & BIT(port));
-}
-
-inline u32 rtl931x_get_mac_link_dup_sts(int p)
-{
- return (sw_r32(RTL931X_MAC_LINK_DUP_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-inline u32 rtl838x_get_mac_link_spd_sts(int port)
-{
- int r = RTL838X_MAC_LINK_SPD_STS + ((port >> 4) << 2);
- u32 speed = sw_r32(r);
-
- speed >>= (port % 16) << 1;
- return (speed & 0x3);
-}
-
-inline u32 rtl839x_get_mac_link_spd_sts(int port)
-{
- int r = RTL839X_MAC_LINK_SPD_STS + ((port >> 4) << 2);
- u32 speed = sw_r32(r);
-
- speed >>= (port % 16) << 1;
- return (speed & 0x3);
-}
-
-
-inline u32 rtl930x_get_mac_link_spd_sts(int port)
-{
- int r = RTL930X_MAC_LINK_SPD_STS + ((port >> 3) << 2);
- u32 speed = sw_r32(r);
-
- speed >>= (port % 8) << 2;
- return (speed & 0xf);
-}
-
-inline u32 rtl931x_get_mac_link_spd_sts(int port)
-{
- int r = RTL931X_MAC_LINK_SPD_STS + ((port >> 3) << 2);
- u32 speed = sw_r32(r);
-
- speed >>= (port % 8) << 2;
- return (speed & 0xf);
-}
-
-inline u32 rtl838x_get_mac_rx_pause_sts(int port)
-{
- return (sw_r32(RTL838X_MAC_RX_PAUSE_STS) & (1 << port));
-}
-
-inline u32 rtl839x_get_mac_rx_pause_sts(int p)
-{
- return (sw_r32(RTL839X_MAC_RX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-inline u32 rtl930x_get_mac_rx_pause_sts(int port)
-{
- return (sw_r32(RTL930X_MAC_RX_PAUSE_STS) & (1 << port));
-}
-
-inline u32 rtl931x_get_mac_rx_pause_sts(int p)
-{
- return (sw_r32(RTL931X_MAC_RX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-inline u32 rtl838x_get_mac_tx_pause_sts(int port)
-{
- return (sw_r32(RTL838X_MAC_TX_PAUSE_STS) & (1 << port));
-}
-
-inline u32 rtl839x_get_mac_tx_pause_sts(int p)
-{
- return (sw_r32(RTL839X_MAC_TX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-inline u32 rtl930x_get_mac_tx_pause_sts(int port)
-{
- return (sw_r32(RTL930X_MAC_TX_PAUSE_STS) & (1 << port));
-}
-
-inline u32 rtl931x_get_mac_tx_pause_sts(int p)
-{
- return (sw_r32(RTL931X_MAC_TX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
-}
-
-struct p_hdr;
-struct dsa_tag;
-
-struct rtl838x_eth_reg {
- irqreturn_t (*net_irq)(int irq, void *dev_id);
- int (*mac_port_ctrl)(int port);
- int dma_if_intr_sts;
- int dma_if_intr_msk;
- int dma_if_intr_rx_runout_sts;
- int dma_if_intr_rx_done_sts;
- int dma_if_intr_tx_done_sts;
- int dma_if_intr_rx_runout_msk;
- int dma_if_intr_rx_done_msk;
- int dma_if_intr_tx_done_msk;
- int l2_ntfy_if_intr_sts;
- int l2_ntfy_if_intr_msk;
- int dma_if_ctrl;
- int mac_force_mode_ctrl;
- int dma_rx_base;
- int dma_tx_base;
- int (*dma_if_rx_ring_size)(int ring);
- int (*dma_if_rx_ring_cntr)(int ring);
- int dma_if_rx_cur;
- int rst_glb_ctrl;
- u32 (*get_mac_link_sts)(int port);
- u32 (*get_mac_link_dup_sts)(int port);
- u32 (*get_mac_link_spd_sts)(int port);
- u32 (*get_mac_rx_pause_sts)(int port);
- u32 (*get_mac_tx_pause_sts)(int port);
- int mac;
- int l2_tbl_flush_ctrl;
- void (*update_cntr)(int r, int work_done);
- void (*create_tx_header)(struct p_hdr *h, unsigned int dest_port, int prio);
- bool (*decode_tag)(struct p_hdr *h, struct dsa_tag *tag);
-};
-
-int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val);
-int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
-int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val);
-int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val);
-int rtl839x_write_phy(u32 port, u32 page, u32 reg, u32 val);
-int rtl839x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
-int rtl839x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
-int rtl839x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val);
-int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val);
-int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
-int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val);
-int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
-int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data);
-
-#endif /* _RTL838X_ETH_H */
diff --git a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c
deleted file mode 100644
index 490020989f..0000000000
--- a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c
+++ /dev/null
@@ -1,3988 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Realtek RTL838X Ethernet MDIO interface driver
- *
- * Copyright (C) 2020 B. Koblitz
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/of.h>
-#include <linux/phy.h>
-#include <linux/netdevice.h>
-#include <linux/firmware.h>
-#include <linux/crc32.h>
-#include <linux/sfp.h>
-#include <linux/mii.h>
-#include <linux/mdio.h>
-
-#include <asm/mach-rtl838x/mach-rtl83xx.h>
-#include "rtl83xx-phy.h"
-
-extern struct rtl83xx_soc_info soc_info;
-extern struct mutex smi_lock;
-
-#define PHY_PAGE_2 2
-#define PHY_PAGE_4 4
-
-/* all Clause-22 RealTek MDIO PHYs use register 0x1f for page select */
-#define RTL8XXX_PAGE_SELECT 0x1f
-
-#define RTL8XXX_PAGE_MAIN 0x0000
-#define RTL821X_PAGE_PORT 0x0266
-#define RTL821X_PAGE_POWER 0x0a40
-#define RTL821X_PAGE_GPHY 0x0a42
-#define RTL821X_PAGE_MAC 0x0a43
-#define RTL821X_PAGE_STATE 0x0b80
-#define RTL821X_PAGE_PATCH 0x0b82
-
-/* Using the special page 0xfff with the MDIO controller found in
- * RealTek SoCs allows to access the PHY in RAW mode, ie. bypassing
- * the cache and paging engine of the MDIO controller.
- */
-#define RTL83XX_PAGE_RAW 0x0fff
-
-/* internal RTL821X PHY uses register 0x1d to select media page */
-#define RTL821XINT_MEDIA_PAGE_SELECT 0x1d
-/* external RTL821X PHY uses register 0x1e to select media page */
-#define RTL821XEXT_MEDIA_PAGE_SELECT 0x1e
-
-#define RTL821X_CHIP_ID 0x6276
-
-#define RTL821X_MEDIA_PAGE_AUTO 0
-#define RTL821X_MEDIA_PAGE_COPPER 1
-#define RTL821X_MEDIA_PAGE_FIBRE 3
-#define RTL821X_MEDIA_PAGE_INTERNAL 8
-
-#define RTL9300_PHY_ID_MASK 0xf0ffffff
-
-/* RTL930X SerDes supports the following modes:
- * 0x02: SGMII 0x04: 1000BX_FIBER 0x05: FIBER100
- * 0x06: QSGMII 0x09: RSGMII 0x0d: USXGMII
- * 0x10: XSGMII 0x12: HISGMII 0x16: 2500Base_X
- * 0x17: RXAUI_LITE 0x19: RXAUI_PLUS 0x1a: 10G Base-R
- * 0x1b: 10GR1000BX_AUTO 0x1f: OFF
- */
-#define RTL930X_SDS_MODE_SGMII 0x02
-#define RTL930X_SDS_MODE_1000BASEX 0x04
-#define RTL930X_SDS_MODE_USXGMII 0x0d
-#define RTL930X_SDS_MODE_XGMII 0x10
-#define RTL930X_SDS_MODE_HSGMII 0x12
-#define RTL930X_SDS_MODE_2500BASEX 0x16
-#define RTL930X_SDS_MODE_10GBASER 0x1a
-#define RTL930X_SDS_OFF 0x1f
-#define RTL930X_SDS_MASK 0x1f
-
-/* This lock protects the state of the SoC automatically polling the PHYs over the SMI
- * bus to detect e.g. link and media changes. For operations on the PHYs such as
- * patching or other configuration changes such as EEE, polling needs to be disabled
- * since otherwise these operations may fails or lead to unpredictable results.
- */
-DEFINE_MUTEX(poll_lock);
-
-static const struct firmware rtl838x_8380_fw;
-static const struct firmware rtl838x_8214fc_fw;
-static const struct firmware rtl838x_8218b_fw;
-
-static u64 disable_polling(int port)
-{
- u64 saved_state;
-
- mutex_lock(&poll_lock);
-
- switch (soc_info.family) {
- case RTL8380_FAMILY_ID:
- saved_state = sw_r32(RTL838X_SMI_POLL_CTRL);
- sw_w32_mask(BIT(port), 0, RTL838X_SMI_POLL_CTRL);
- break;
- case RTL8390_FAMILY_ID:
- saved_state = sw_r32(RTL839X_SMI_PORT_POLLING_CTRL + 4);
- saved_state <<= 32;
- saved_state |= sw_r32(RTL839X_SMI_PORT_POLLING_CTRL);
- sw_w32_mask(BIT(port % 32), 0,
- RTL839X_SMI_PORT_POLLING_CTRL + ((port >> 5) << 2));
- break;
- case RTL9300_FAMILY_ID:
- saved_state = sw_r32(RTL930X_SMI_POLL_CTRL);
- sw_w32_mask(BIT(port), 0, RTL930X_SMI_POLL_CTRL);
- break;
- case RTL9310_FAMILY_ID:
- pr_warn("%s not implemented for RTL931X\n", __func__);
- break;
- }
-
- mutex_unlock(&poll_lock);
-
- return saved_state;
-}
-
-static int resume_polling(u64 saved_state)
-{
- mutex_lock(&poll_lock);
-
- switch (soc_info.family) {
- case RTL8380_FAMILY_ID:
- sw_w32(saved_state, RTL838X_SMI_POLL_CTRL);
- break;
- case RTL8390_FAMILY_ID:
- sw_w32(saved_state >> 32, RTL839X_SMI_PORT_POLLING_CTRL + 4);
- sw_w32(saved_state, RTL839X_SMI_PORT_POLLING_CTRL);
- break;
- case RTL9300_FAMILY_ID:
- sw_w32(saved_state, RTL930X_SMI_POLL_CTRL);
- break;
- case RTL9310_FAMILY_ID:
- pr_warn("%s not implemented for RTL931X\n", __func__);
- break;
- }
-
- mutex_unlock(&poll_lock);
-
- return 0;
-}
-
-static void rtl8380_int_phy_on_off(struct phy_device *phydev, bool on)
-{
- phy_modify(phydev, 0, BMCR_PDOWN, on ? 0 : BMCR_PDOWN);
-}
-
-static void rtl8380_rtl8214fc_on_off(struct phy_device *phydev, bool on)
-{
- /* fiber ports */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
- phy_modify(phydev, 0x10, BMCR_PDOWN, on ? 0 : BMCR_PDOWN);
-
- /* copper ports */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
- phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, BMCR_PDOWN, on ? 0 : BMCR_PDOWN);
-}
-
-static void rtl8380_phy_reset(struct phy_device *phydev)
-{
- phy_modify(phydev, 0, BMCR_RESET, BMCR_RESET);
-}
-
-/* The access registers for SDS_MODE_SEL and the LSB for each SDS within */
-u16 rtl9300_sds_regs[] = { 0x0194, 0x0194, 0x0194, 0x0194, 0x02a0, 0x02a0, 0x02a0, 0x02a0,
- 0x02A4, 0x02A4, 0x0198, 0x0198 };
-u8 rtl9300_sds_lsb[] = { 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 0, 6};
-
-/* Reset the SerDes by powering it off and set a new operation mode
- * of the SerDes.
- */
-void rtl9300_sds_rst(int sds_num, u32 mode)
-{
- pr_info("%s %d\n", __func__, mode);
- if (sds_num < 0 || sds_num > 11) {
- pr_err("Wrong SerDes number: %d\n", sds_num);
- return;
- }
-
- sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num],
- RTL930X_SDS_OFF << rtl9300_sds_lsb[sds_num],
- rtl9300_sds_regs[sds_num]);
- mdelay(10);
-
- sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num], mode << rtl9300_sds_lsb[sds_num],
- rtl9300_sds_regs[sds_num]);
- mdelay(10);
-
- pr_debug("%s: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n", __func__,
- sw_r32(0x194), sw_r32(0x198), sw_r32(0x2a0), sw_r32(0x2a4));
-}
-
-void rtl9300_sds_set(int sds_num, u32 mode)
-{
- pr_info("%s %d\n", __func__, mode);
- if (sds_num < 0 || sds_num > 11) {
- pr_err("Wrong SerDes number: %d\n", sds_num);
- return;
- }
-
- sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num], mode << rtl9300_sds_lsb[sds_num],
- rtl9300_sds_regs[sds_num]);
- mdelay(10);
-
- pr_debug("%s: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n", __func__,
- sw_r32(0x194), sw_r32(0x198), sw_r32(0x2a0), sw_r32(0x2a4));
-}
-
-u32 rtl9300_sds_mode_get(int sds_num)
-{
- u32 v;
-
- if (sds_num < 0 || sds_num > 11) {
- pr_err("Wrong SerDes number: %d\n", sds_num);
- return 0;
- }
-
- v = sw_r32(rtl9300_sds_regs[sds_num]);
- v >>= rtl9300_sds_lsb[sds_num];
-
- return v & RTL930X_SDS_MASK;
-}
-
-/* On the RTL839x family of SoCs with inbuilt SerDes, these SerDes are accessed through
- * a 2048 bit register that holds the contents of the PHY being simulated by the SoC.
- */
-int rtl839x_read_sds_phy(int phy_addr, int phy_reg)
-{
- int offset = 0;
- int reg;
- u32 val;
-
- if (phy_addr == 49)
- offset = 0x100;
-
- /* For the RTL8393 internal SerDes, we simulate a PHY ID in registers 2/3
- * which would otherwise read as 0.
- */
- if (soc_info.id == 0x8393) {
- if (phy_reg == MII_PHYSID1)
- return 0x1c;
- if (phy_reg == MII_PHYSID2)
- return 0x8393;
- }
-
- /* Register RTL839X_SDS12_13_XSG0 is 2048 bit broad, the MSB (bit 15) of the
- * 0th PHY register is bit 1023 (in byte 0x80). Because PHY-registers are 16
- * bit broad, we offset by reg << 1. In the SoC 2 registers are stored in
- * one 32 bit register.
- */
- reg = (phy_reg << 1) & 0xfc;
- val = sw_r32(RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg);
-
- if (phy_reg & 1)
- val = (val >> 16) & 0xffff;
- else
- val &= 0xffff;
-
- return val;
-}
-
-/* On the RTL930x family of SoCs, the internal SerDes are accessed through an IO
- * register which simulates commands to an internal MDIO bus.
- */
-int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg)
-{
- int i;
- u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1;
-
- sw_w32(cmd, RTL930X_SDS_INDACS_CMD);
-
- for (i = 0; i < 100; i++) {
- if (!(sw_r32(RTL930X_SDS_INDACS_CMD) & 0x1))
- break;
- mdelay(1);
- }
-
- if (i >= 100)
- return -EIO;
-
- return sw_r32(RTL930X_SDS_INDACS_DATA) & 0xffff;
-}
-
-int rtl930x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v)
-{
- int i;
- u32 cmd;
-
- sw_w32(v, RTL930X_SDS_INDACS_DATA);
- cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 0x3;
-
- sw_w32(cmd, RTL930X_SDS_INDACS_CMD);
-
- for (i = 0; i < 100; i++) {
- if (!(sw_r32(RTL930X_SDS_INDACS_CMD) & 0x1))
- break;
- mdelay(1);
- }
-
-
- if (i >= 100) {
- pr_info("%s ERROR !!!!!!!!!!!!!!!!!!!!\n", __func__);
- return -EIO;
- }
-
- return 0;
-}
-
-int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg)
-{
- int i;
- u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1;
-
- pr_debug("%s: phy_addr(SDS-ID) %d, phy_reg: %d\n", __func__, phy_addr, phy_reg);
- sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL);
-
- for (i = 0; i < 100; i++) {
- if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1))
- break;
- mdelay(1);
- }
-
- if (i >= 100)
- return -EIO;
-
- pr_debug("%s: returning %04x\n", __func__, sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff);
-
- return sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff;
-}
-
-int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v)
-{
- int i;
- u32 cmd;
-
- cmd = phy_addr << 2 | page << 7 | phy_reg << 13;
- sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL);
-
- sw_w32(v, RTL931X_SERDES_INDRT_DATA_CTRL);
-
- cmd = sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) | 0x3;
- sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL);
-
- for (i = 0; i < 100; i++) {
- if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1))
- break;
- mdelay(1);
- }
-
- if (i >= 100)
- return -EIO;
-
- return 0;
-}
-
-/* On the RTL838x SoCs, the internal SerDes is accessed through direct access to
- * standard PHY registers, where a 32 bit register holds a 16 bit word as found
- * in a standard page 0 of a PHY
- */
-int rtl838x_read_sds_phy(int phy_addr, int phy_reg)
-{
- int offset = 0;
- u32 val;
-
- if (phy_addr == 26)
- offset = 0x100;
- val = sw_r32(RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2)) & 0xffff;
-
- return val;
-}
-
-int rtl839x_write_sds_phy(int phy_addr, int phy_reg, u16 v)
-{
- int offset = 0;
- int reg;
- u32 val;
-
- if (phy_addr == 49)
- offset = 0x100;
-
- reg = (phy_reg << 1) & 0xfc;
- val = v;
- if (phy_reg & 1) {
- val = val << 16;
- sw_w32_mask(0xffff0000, val,
- RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg);
- } else {
- sw_w32_mask(0xffff, val,
- RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg);
- }
-
- return 0;
-}
-
-/* Read the link and speed status of the 2 internal SGMII/1000Base-X
- * ports of the RTL838x SoCs
- */
-static int rtl8380_read_status(struct phy_device *phydev)
-{
- int err;
-
- err = genphy_read_status(phydev);
-
- if (phydev->link) {
- phydev->speed = SPEED_1000;
- phydev->duplex = DUPLEX_FULL;
- }
-
- return err;
-}
-
-/* Read the link and speed status of the 2 internal SGMII/1000Base-X
- * ports of the RTL8393 SoC
- */
-static int rtl8393_read_status(struct phy_device *phydev)
-{
- int offset = 0;
- int err;
- int phy_addr = phydev->mdio.addr;
- u32 v;
-
- err = genphy_read_status(phydev);
- if (phy_addr == 49)
- offset = 0x100;
-
- if (phydev->link) {
- phydev->speed = SPEED_100;
- /* Read SPD_RD_00 (bit 13) and SPD_RD_01 (bit 6) out of the internal
- * PHY registers
- */
- v = sw_r32(RTL839X_SDS12_13_XSG0 + offset + 0x80);
- if (!(v & (1 << 13)) && (v & (1 << 6)))
- phydev->speed = SPEED_1000;
- phydev->duplex = DUPLEX_FULL;
- }
-
- return err;
-}
-
-static int rtl8226_read_page(struct phy_device *phydev)
-{
- return __phy_read(phydev, RTL8XXX_PAGE_SELECT);
-}
-
-static int rtl8226_write_page(struct phy_device *phydev, int page)
-{
- return __phy_write(phydev, RTL8XXX_PAGE_SELECT, page);
-}
-
-static int rtl8226_read_status(struct phy_device *phydev)
-{
- int ret = 0;
- u32 val;
-
-/* TODO: ret = genphy_read_status(phydev);
- * if (ret < 0) {
- * pr_info("%s: genphy_read_status failed\n", __func__);
- * return ret;
- * }
- */
-
- /* Link status must be read twice */
- for (int i = 0; i < 2; i++)
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA402);
-
- phydev->link = val & BIT(2) ? 1 : 0;
- if (!phydev->link)
- goto out;
-
- /* Read duplex status */
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434);
- if (val < 0)
- goto out;
- phydev->duplex = !!(val & BIT(3));
-
- /* Read speed */
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434);
- switch (val & 0x0630) {
- case 0x0000:
- phydev->speed = SPEED_10;
- break;
- case 0x0010:
- phydev->speed = SPEED_100;
- break;
- case 0x0020:
- phydev->speed = SPEED_1000;
- break;
- case 0x0200:
- phydev->speed = SPEED_10000;
- break;
- case 0x0210:
- phydev->speed = SPEED_2500;
- break;
- case 0x0220:
- phydev->speed = SPEED_5000;
- break;
- default:
- break;
- }
-
-out:
- return ret;
-}
-
-static int rtl8226_advertise_aneg(struct phy_device *phydev)
-{
- int ret = 0;
- u32 v;
-
- pr_info("In %s\n", __func__);
-
- v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
- if (v < 0)
- goto out;
-
- v |= ADVERTISE_10HALF;
- v |= ADVERTISE_10FULL;
- v |= ADVERTISE_100HALF;
- v |= ADVERTISE_100FULL;
-
- ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, v);
-
- /* Allow 1GBit */
- v = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA412);
- if (v < 0)
- goto out;
- v |= ADVERTISE_1000FULL;
-
- ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA412, v);
- if (ret < 0)
- goto out;
-
- /* Allow 2.5G */
- v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
- if (v < 0)
- goto out;
-
- v |= MDIO_AN_10GBT_CTRL_ADV2_5G;
- ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, v);
-
-out:
- return ret;
-}
-
-static int rtl8226_config_aneg(struct phy_device *phydev)
-{
- int ret = 0;
- u32 v;
-
- pr_debug("In %s\n", __func__);
- if (phydev->autoneg == AUTONEG_ENABLE) {
- ret = rtl8226_advertise_aneg(phydev);
- if (ret)
- goto out;
- /* AutoNegotiationEnable */
- v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
- if (v < 0)
- goto out;
-
- v |= MDIO_AN_CTRL1_ENABLE; /* Enable AN */
- ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, v);
- if (ret < 0)
- goto out;
-
- /* RestartAutoNegotiation */
- v = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA400);
- if (v < 0)
- goto out;
- v |= MDIO_AN_CTRL1_RESTART;
-
- ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA400, v);
- }
-
-/* TODO: ret = __genphy_config_aneg(phydev, ret); */
-
-out:
- return ret;
-}
-
-static int rtl8226_get_eee(struct phy_device *phydev,
- struct ethtool_eee *e)
-{
- u32 val;
- int addr = phydev->mdio.addr;
-
- pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
-
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
- if (e->eee_enabled) {
- e->eee_enabled = !!(val & MDIO_EEE_100TX);
- if (!e->eee_enabled) {
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2);
- e->eee_enabled = !!(val & MDIO_EEE_2_5GT);
- }
- }
- pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
-
- return 0;
-}
-
-static int rtl8226_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
-{
- int port = phydev->mdio.addr;
- u64 poll_state;
- bool an_enabled;
- u32 val;
-
- pr_info("In %s, port %d, enabled %d\n", __func__, port, e->eee_enabled);
-
- poll_state = disable_polling(port);
-
- /* Remember aneg state */
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
- an_enabled = !!(val & MDIO_AN_CTRL1_ENABLE);
-
- /* Setup 100/1000MBit */
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
- if (e->eee_enabled)
- val |= (MDIO_EEE_100TX | MDIO_EEE_1000T);
- else
- val &= (MDIO_EEE_100TX | MDIO_EEE_1000T);
- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
-
- /* Setup 2.5GBit */
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2);
- if (e->eee_enabled)
- val |= MDIO_EEE_2_5GT;
- else
- val &= MDIO_EEE_2_5GT;
- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2, val);
-
- /* RestartAutoNegotiation */
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA400);
- val |= MDIO_AN_CTRL1_RESTART;
- phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA400, val);
-
- resume_polling(poll_state);
-
- return 0;
-}
-
-static struct fw_header *rtl838x_request_fw(struct phy_device *phydev,
- const struct firmware *fw,
- const char *name)
-{
- struct device *dev = &phydev->mdio.dev;
- int err;
- struct fw_header *h;
- uint32_t checksum, my_checksum;
-
- err = request_firmware(&fw, name, dev);
- if (err < 0)
- goto out;
-
- if (fw->size < sizeof(struct fw_header)) {
- pr_err("Firmware size too small.\n");
- err = -EINVAL;
- goto out;
- }
-
- h = (struct fw_header *) fw->data;
- pr_info("Firmware loaded. Size %d, magic: %08x\n", fw->size, h->magic);
-
- if (h->magic != 0x83808380) {
- pr_err("Wrong firmware file: MAGIC mismatch.\n");
- goto out;
- }
-
- checksum = h->checksum;
- h->checksum = 0;
- my_checksum = ~crc32(0xFFFFFFFFU, fw->data, fw->size);
- if (checksum != my_checksum) {
- pr_err("Firmware checksum mismatch.\n");
- err = -EINVAL;
- goto out;
- }
- h->checksum = checksum;
-
- return h;
-out:
- dev_err(dev, "Unable to load firmware %s (%d)\n", name, err);
- return NULL;
-}
-
-static void rtl821x_phy_setup_package_broadcast(struct phy_device *phydev, bool enable)
-{
- int mac = phydev->mdio.addr;
-
- /* select main page 0 */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
- /* write to 0x8 to register 0x1d on main page 0 */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
- /* select page 0x266 */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PORT);
- /* set phy id and target broadcast bitmap in register 0x16 on page 0x266 */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x16, (enable?0xff00:0x00) | mac);
- /* return to main page 0 */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
- /* write to 0x0 to register 0x1d on main page 0 */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
- mdelay(1);
-}
-
-static int rtl8390_configure_generic(struct phy_device *phydev)
-{
- int mac = phydev->mdio.addr;
- u32 val, phy_id;
-
- val = phy_read(phydev, 2);
- phy_id = val << 16;
- val = phy_read(phydev, 3);
- phy_id |= val;
- pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
-
- /* Read internal PHY ID */
- phy_write_paged(phydev, 31, 27, 0x0002);
- val = phy_read_paged(phydev, 31, 28);
-
- /* Internal RTL8218B, version 2 */
- phydev_info(phydev, "Detected unknown %x\n", val);
-
- return 0;
-}
-
-static int rtl8380_configure_int_rtl8218b(struct phy_device *phydev)
-{
- u32 val, phy_id;
- int mac = phydev->mdio.addr;
- struct fw_header *h;
- u32 *rtl838x_6275B_intPhy_perport;
- u32 *rtl8218b_6276B_hwEsd_perport;
-
- val = phy_read(phydev, 2);
- phy_id = val << 16;
- val = phy_read(phydev, 3);
- phy_id |= val;
- pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
-
- /* Read internal PHY ID */
- phy_write_paged(phydev, 31, 27, 0x0002);
- val = phy_read_paged(phydev, 31, 28);
- if (val != 0x6275) {
- phydev_err(phydev, "Expected internal RTL8218B, found PHY-ID %x\n", val);
- return -1;
- }
-
- /* Internal RTL8218B, version 2 */
- phydev_info(phydev, "Detected internal RTL8218B\n");
-
- h = rtl838x_request_fw(phydev, &rtl838x_8380_fw, FIRMWARE_838X_8380_1);
- if (!h)
- return -1;
-
- if (h->phy != 0x83800000) {
- phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
- return -1;
- }
-
- rtl838x_6275B_intPhy_perport = (void *)h + sizeof(struct fw_header) + h->parts[8].start;
- rtl8218b_6276B_hwEsd_perport = (void *)h + sizeof(struct fw_header) + h->parts[9].start;
-
- // Currently not used
- // if (sw_r32(RTL838X_DMY_REG31) == 0x1) {
- // int ipd_flag = 1;
- // }
-
- val = phy_read(phydev, MII_BMCR);
- if (val & BMCR_PDOWN)
- rtl8380_int_phy_on_off(phydev, true);
- else
- rtl8380_phy_reset(phydev);
- msleep(100);
-
- /* Ready PHY for patch */
- for (int p = 0; p < 8; p++) {
- phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
- phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, 0x10, 0x0010);
- }
- msleep(500);
- for (int p = 0; p < 8; p++) {
- int i;
-
- for (i = 0; i < 100 ; i++) {
- val = phy_package_port_read_paged(phydev, p, RTL821X_PAGE_STATE, 0x10);
- if (val & 0x40)
- break;
- }
- if (i >= 100) {
- phydev_err(phydev,
- "ERROR: Port %d not ready for patch.\n",
- mac + p);
- return -1;
- }
- }
- for (int p = 0; p < 8; p++) {
- int i;
-
- i = 0;
- while (rtl838x_6275B_intPhy_perport[i * 2]) {
- phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW,
- rtl838x_6275B_intPhy_perport[i * 2],
- rtl838x_6275B_intPhy_perport[i * 2 + 1]);
- i++;
- }
- i = 0;
- while (rtl8218b_6276B_hwEsd_perport[i * 2]) {
- phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW,
- rtl8218b_6276B_hwEsd_perport[i * 2],
- rtl8218b_6276B_hwEsd_perport[i * 2 + 1]);
- i++;
- }
- }
-
- return 0;
-}
-
-static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
-{
- u32 val, ipd, phy_id;
- int mac = phydev->mdio.addr;
- struct fw_header *h;
- u32 *rtl8380_rtl8218b_perchip;
- u32 *rtl8218B_6276B_rtl8380_perport;
- u32 *rtl8380_rtl8218b_perport;
-
- if (soc_info.family == RTL8380_FAMILY_ID && mac != 0 && mac != 16) {
- phydev_err(phydev, "External RTL8218B must have PHY-IDs 0 or 16!\n");
- return -1;
- }
- val = phy_read(phydev, 2);
- phy_id = val << 16;
- val = phy_read(phydev, 3);
- phy_id |= val;
- pr_info("Phy on MAC %d: %x\n", mac, phy_id);
-
- /* Read internal PHY ID */
- phy_write_paged(phydev, 31, 27, 0x0002);
- val = phy_read_paged(phydev, 31, 28);
- if (val != RTL821X_CHIP_ID) {
- phydev_err(phydev, "Expected external RTL8218B, found PHY-ID %x\n", val);
- return -1;
- }
- phydev_info(phydev, "Detected external RTL8218B\n");
-
- h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8218b_1);
- if (!h)
- return -1;
-
- if (h->phy != 0x8218b000) {
- phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
- return -1;
- }
-
- rtl8380_rtl8218b_perchip = (void *)h + sizeof(struct fw_header) + h->parts[0].start;
- rtl8218B_6276B_rtl8380_perport = (void *)h + sizeof(struct fw_header) + h->parts[1].start;
- rtl8380_rtl8218b_perport = (void *)h + sizeof(struct fw_header) + h->parts[2].start;
-
- val = phy_read(phydev, MII_BMCR);
- if (val & BMCR_PDOWN)
- rtl8380_int_phy_on_off(phydev, true);
- else
- rtl8380_phy_reset(phydev);
-
- msleep(100);
-
- /* Get Chip revision */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x1b, 0x4);
- val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 0x1c);
-
- phydev_info(phydev, "Detected chip revision %04x\n", val);
-
- for (int i = 0; rtl8380_rtl8218b_perchip[i * 3] &&
- rtl8380_rtl8218b_perchip[i * 3 + 1]; i++) {
- phy_package_port_write_paged(phydev, rtl8380_rtl8218b_perchip[i * 3],
- RTL83XX_PAGE_RAW, rtl8380_rtl8218b_perchip[i * 3 + 1],
- rtl8380_rtl8218b_perchip[i * 3 + 2]);
- }
-
- /* Enable PHY */
- for (int i = 0; i < 8; i++) {
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140);
- }
- mdelay(100);
-
- /* Request patch */
- for (int i = 0; i < 8; i++) {
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010);
- }
-
- mdelay(300);
-
- /* Verify patch readiness */
- for (int i = 0; i < 8; i++) {
- int l;
-
- for (l = 0; l < 100; l++) {
- val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10);
- if (val & 0x40)
- break;
- }
- if (l >= 100) {
- phydev_err(phydev, "Could not patch PHY\n");
- return -1;
- }
- }
-
- /* Use Broadcast ID method for patching */
- rtl821x_phy_setup_package_broadcast(phydev, true);
-
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, 30, 8);
- phy_write_paged(phydev, 0x26e, 17, 0xb);
- phy_write_paged(phydev, 0x26e, 16, 0x2);
- mdelay(1);
- ipd = phy_read_paged(phydev, 0x26e, 19);
- phy_write_paged(phydev, 0, 30, 0);
- ipd = (ipd >> 4) & 0xf; /* unused ? */
-
- for (int i = 0; rtl8218B_6276B_rtl8380_perport[i * 2]; i++) {
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8218B_6276B_rtl8380_perport[i * 2],
- rtl8218B_6276B_rtl8380_perport[i * 2 + 1]);
- }
-
- /* Disable broadcast ID */
- rtl821x_phy_setup_package_broadcast(phydev, false);
-
- return 0;
-}
-
-static int rtl8218b_ext_match_phy_device(struct phy_device *phydev)
-{
- int addr = phydev->mdio.addr;
-
- /* Both the RTL8214FC and the external RTL8218B have the same
- * PHY ID. On the RTL838x, the RTL8218B can only be attached_dev
- * at PHY IDs 0-7, while the RTL8214FC must be attached via
- * the pair of SGMII/1000Base-X with higher PHY-IDs
- */
- if (soc_info.family == RTL8380_FAMILY_ID)
- return phydev->phy_id == PHY_ID_RTL8218B_E && addr < 8;
- else
- return phydev->phy_id == PHY_ID_RTL8218B_E;
-}
-
-static bool rtl8214fc_media_is_fibre(struct phy_device *phydev)
-{
- int mac = phydev->mdio.addr;
-
- static int reg[] = {16, 19, 20, 21};
- u32 val;
-
- phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
- val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
- phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-
- if (val & BMCR_PDOWN)
- return false;
-
- return true;
-}
-
-static void rtl8214fc_power_set(struct phy_device *phydev, int port, bool on)
-{
- char *state = on ? "on" : "off";
-
- if (port == PORT_FIBRE) {
- pr_info("%s: Powering %s FIBRE (port %d)\n", __func__, state, phydev->mdio.addr);
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
- } else {
- pr_info("%s: Powering %s COPPER (port %d)\n", __func__, state, phydev->mdio.addr);
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
- }
-
- if (on) {
- phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, BMCR_PDOWN, 0);
- } else {
- phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, 0, BMCR_PDOWN);
- }
-
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-}
-
-static int rtl8214fc_suspend(struct phy_device *phydev)
-{
- rtl8214fc_power_set(phydev, PORT_MII, false);
- rtl8214fc_power_set(phydev, PORT_FIBRE, false);
-
- return 0;
-}
-
-static int rtl8214fc_resume(struct phy_device *phydev)
-{
- if (rtl8214fc_media_is_fibre(phydev)) {
- rtl8214fc_power_set(phydev, PORT_MII, false);
- rtl8214fc_power_set(phydev, PORT_FIBRE, true);
- } else {
- rtl8214fc_power_set(phydev, PORT_FIBRE, false);
- rtl8214fc_power_set(phydev, PORT_MII, true);
- }
-
- return 0;
-}
-
-static void rtl8214fc_media_set(struct phy_device *phydev, bool set_fibre)
-{
- int mac = phydev->mdio.addr;
-
- static int reg[] = {16, 19, 20, 21};
- int val;
-
- pr_info("%s: port %d, set_fibre: %d\n", __func__, mac, set_fibre);
- phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
- val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
-
- val |= BIT(10);
- if (set_fibre) {
- val &= ~BMCR_PDOWN;
- } else {
- val |= BMCR_PDOWN;
- }
-
- phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
- phy_package_write_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4], val);
- phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-
- if (!phydev->suspended) {
- if (set_fibre) {
- rtl8214fc_power_set(phydev, PORT_MII, false);
- rtl8214fc_power_set(phydev, PORT_FIBRE, true);
- } else {
- rtl8214fc_power_set(phydev, PORT_FIBRE, false);
- rtl8214fc_power_set(phydev, PORT_MII, true);
- }
- }
-}
-
-static int rtl8214fc_set_port(struct phy_device *phydev, int port)
-{
- bool is_fibre = (port == PORT_FIBRE ? true : false);
- int addr = phydev->mdio.addr;
-
- pr_debug("%s port %d to %d\n", __func__, addr, port);
-
- rtl8214fc_media_set(phydev, is_fibre);
-
- return 0;
-}
-
-static int rtl8214fc_get_port(struct phy_device *phydev)
-{
- int addr = phydev->mdio.addr;
-
- pr_debug("%s: port %d\n", __func__, addr);
- if (rtl8214fc_media_is_fibre(phydev))
- return PORT_FIBRE;
-
- return PORT_MII;
-}
-
-/* Enable EEE on the RTL8218B PHYs
- * The method used is not the preferred way (which would be based on the MAC-EEE state,
- * but the only way that works since the kernel first enables EEE in the MAC
- * and then sets up the PHY. The MAC-based approach would require the oppsite.
- */
-void rtl8218d_eee_set(struct phy_device *phydev, bool enable)
-{
- u32 val;
- bool an_enabled;
-
- pr_debug("In %s %d, enable %d\n", __func__, phydev->mdio.addr, enable);
- /* Set GPHY page to copper */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
-
- val = phy_read(phydev, MII_BMCR);
- an_enabled = val & BMCR_ANENABLE;
-
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
- val |= MDIO_EEE_1000T | MDIO_EEE_100TX;
- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, enable ? (MDIO_EEE_100TX | MDIO_EEE_1000T) : 0);
-
- /* 500M EEE ability */
- val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20);
- if (enable)
- val |= BIT(7);
- else
- val &= ~BIT(7);
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val);
-
- /* Restart AN if enabled */
- if (an_enabled) {
- val = phy_read(phydev, MII_BMCR);
- val |= BMCR_ANRESTART;
- phy_write(phydev, MII_BMCR, val);
- }
-
- /* GPHY page back to auto */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-}
-
-static int rtl8218b_get_eee(struct phy_device *phydev,
- struct ethtool_eee *e)
-{
- u32 val;
- int addr = phydev->mdio.addr;
-
- pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
-
- /* Set GPHY page to copper */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
-
- val = phy_read_paged(phydev, 7, MDIO_AN_EEE_ADV);
- if (e->eee_enabled) {
- /* Verify vs MAC-based EEE */
- e->eee_enabled = !!(val & BIT(7));
- if (!e->eee_enabled) {
- val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
- e->eee_enabled = !!(val & BIT(4));
- }
- }
- pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
-
- /* GPHY page to auto */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-
- return 0;
-}
-
-static int rtl8218d_get_eee(struct phy_device *phydev,
- struct ethtool_eee *e)
-{
- u32 val;
- int addr = phydev->mdio.addr;
-
- pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
-
- /* Set GPHY page to copper */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
-
- val = phy_read_paged(phydev, 7, MDIO_AN_EEE_ADV);
- if (e->eee_enabled)
- e->eee_enabled = !!(val & BIT(7));
- pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
-
- /* GPHY page to auto */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-
- return 0;
-}
-
-static int rtl8214fc_set_eee(struct phy_device *phydev,
- struct ethtool_eee *e)
-{
- u32 poll_state;
- int port = phydev->mdio.addr;
- bool an_enabled;
- u32 val;
-
- pr_debug("In %s port %d, enabled %d\n", __func__, port, e->eee_enabled);
-
- if (rtl8214fc_media_is_fibre(phydev)) {
- netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", port);
- return -ENOTSUPP;
- }
-
- poll_state = disable_polling(port);
-
- /* Set GPHY page to copper */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
-
- /* Get auto-negotiation status */
- val = phy_read(phydev, MII_BMCR);
- an_enabled = val & BMCR_ANENABLE;
-
- pr_info("%s: aneg: %d\n", __func__, an_enabled);
- val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
- val &= ~BIT(5); /* Use MAC-based EEE */
- phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
-
- /* Enable 100M (bit 1) / 1000M (bit 2) EEE */
- phy_write_paged(phydev, 7, MDIO_AN_EEE_ADV, e->eee_enabled ? (MDIO_EEE_100TX | MDIO_EEE_1000T) : 0);
-
- /* 500M EEE ability */
- val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20);
- if (e->eee_enabled)
- val |= BIT(7);
- else
- val &= ~BIT(7);
-
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val);
-
- /* Restart AN if enabled */
- if (an_enabled) {
- pr_info("%s: doing aneg\n", __func__);
- val = phy_read(phydev, MII_BMCR);
- val |= BMCR_ANRESTART;
- phy_write(phydev, MII_BMCR, val);
- }
-
- /* GPHY page back to auto */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-
- resume_polling(poll_state);
-
- return 0;
-}
-
-static int rtl8214fc_get_eee(struct phy_device *phydev,
- struct ethtool_eee *e)
-{
- int addr = phydev->mdio.addr;
-
- pr_debug("In %s port %d, enabled %d\n", __func__, addr, e->eee_enabled);
- if (rtl8214fc_media_is_fibre(phydev)) {
- netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", addr);
- return -ENOTSUPP;
- }
-
- return rtl8218b_get_eee(phydev, e);
-}
-
-static int rtl8218b_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
-{
- int port = phydev->mdio.addr;
- u64 poll_state;
- u32 val;
- bool an_enabled;
-
- pr_info("In %s, port %d, enabled %d\n", __func__, port, e->eee_enabled);
-
- poll_state = disable_polling(port);
-
- /* Set GPHY page to copper */
- phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
- val = phy_read(phydev, MII_BMCR);
- an_enabled = val & BMCR_ANENABLE;
-
- if (e->eee_enabled) {
- /* 100/1000M EEE Capability */
- phy_write(phydev, 13, 0x0007);
- phy_write(phydev, 14, 0x003C);
- phy_write(phydev, 13, 0x4007);
- phy_write(phydev, 14, 0x0006);
-
- val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
- val |= BIT(4);
- phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
- } else {
- /* 100/1000M EEE Capability */
- phy_write(phydev, 13, 0x0007);
- phy_write(phydev, 14, 0x003C);
- phy_write(phydev, 13, 0x0007);
- phy_write(phydev, 14, 0x0000);
-
- val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
- val &= ~BIT(4);
- phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
- }
-
- /* Restart AN if enabled */
- if (an_enabled) {
- val = phy_read(phydev, MII_BMCR);
- val |= BMCR_ANRESTART;
- phy_write(phydev, MII_BMCR, val);
- }
-
- /* GPHY page back to auto */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-
- pr_info("%s done\n", __func__);
- resume_polling(poll_state);
-
- return 0;
-}
-
-static int rtl8218d_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
-{
- int addr = phydev->mdio.addr;
- u64 poll_state;
-
- pr_info("In %s, port %d, enabled %d\n", __func__, addr, e->eee_enabled);
-
- poll_state = disable_polling(addr);
-
- rtl8218d_eee_set(phydev, (bool) e->eee_enabled);
-
- resume_polling(poll_state);
-
- return 0;
-}
-
-static int rtl8214c_match_phy_device(struct phy_device *phydev)
-{
- return phydev->phy_id == PHY_ID_RTL8214C;
-}
-
-static int rtl8380_configure_rtl8214c(struct phy_device *phydev)
-{
- u32 phy_id, val;
- int mac = phydev->mdio.addr;
-
- val = phy_read(phydev, 2);
- phy_id = val << 16;
- val = phy_read(phydev, 3);
- phy_id |= val;
- pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
-
- phydev_info(phydev, "Detected external RTL8214C\n");
-
- /* GPHY auto conf */
- phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
-
- return 0;
-}
-
-static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
-{
- int mac = phydev->mdio.addr;
- struct fw_header *h;
- u32 *rtl8380_rtl8214fc_perchip;
- u32 *rtl8380_rtl8214fc_perport;
- u32 phy_id;
- u32 val;
-
- val = phy_read(phydev, 2);
- phy_id = val << 16;
- val = phy_read(phydev, 3);
- phy_id |= val;
- pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
-
- /* Read internal PHY id */
- phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
- phy_write_paged(phydev, 0x1f, 0x1b, 0x0002);
- val = phy_read_paged(phydev, 0x1f, 0x1c);
- if (val != RTL821X_CHIP_ID) {
- phydev_err(phydev, "Expected external RTL8214FC, found PHY-ID %x\n", val);
- return -1;
- }
- phydev_info(phydev, "Detected external RTL8214FC\n");
-
- h = rtl838x_request_fw(phydev, &rtl838x_8214fc_fw, FIRMWARE_838X_8214FC_1);
- if (!h)
- return -1;
-
- if (h->phy != 0x8214fc00) {
- phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
- return -1;
- }
-
- rtl8380_rtl8214fc_perchip = (void *)h + sizeof(struct fw_header) + h->parts[0].start;
-
- rtl8380_rtl8214fc_perport = (void *)h + sizeof(struct fw_header) + h->parts[1].start;
-
- /* detect phy version */
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, 27, 0x0004);
- val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 28);
-
- val = phy_read(phydev, 16);
- if (val & BMCR_PDOWN)
- rtl8380_rtl8214fc_on_off(phydev, true);
- else
- rtl8380_phy_reset(phydev);
-
- msleep(100);
- phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
-
- for (int i = 0; rtl8380_rtl8214fc_perchip[i * 3] &&
- rtl8380_rtl8214fc_perchip[i * 3 + 1]; i++) {
- u32 page = 0;
-
- if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x1f)
- page = rtl8380_rtl8214fc_perchip[i * 3 + 2];
- if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x13 && page == 0x260) {
- val = phy_read_paged(phydev, 0x260, 13);
- val = (val & 0x1f00) | (rtl8380_rtl8214fc_perchip[i * 3 + 2] & 0xe0ff);
- phy_write_paged(phydev, RTL83XX_PAGE_RAW,
- rtl8380_rtl8214fc_perchip[i * 3 + 1], val);
- } else {
- phy_write_paged(phydev, RTL83XX_PAGE_RAW,
- rtl8380_rtl8214fc_perchip[i * 3 + 1],
- rtl8380_rtl8214fc_perchip[i * 3 + 2]);
- }
- }
-
- /* Force copper medium */
- for (int i = 0; i < 4; i++) {
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
- }
-
- /* Enable PHY */
- for (int i = 0; i < 4; i++) {
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140);
- }
- mdelay(100);
-
- /* Disable Autosensing */
- for (int i = 0; i < 4; i++) {
- int l;
-
- for (l = 0; l < 100; l++) {
- val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_GPHY, 0x10);
- if ((val & 0x7) >= 3)
- break;
- }
- if (l >= 100) {
- phydev_err(phydev, "Could not disable autosensing\n");
- return -1;
- }
- }
-
- /* Request patch */
- for (int i = 0; i < 4; i++) {
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
- phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010);
- }
- mdelay(300);
-
- /* Verify patch readiness */
- for (int i = 0; i < 4; i++) {
- int l;
-
- for (l = 0; l < 100; l++) {
- val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10);
- if (val & 0x40)
- break;
- }
- if (l >= 100) {
- phydev_err(phydev, "Could not patch PHY\n");
- return -1;
- }
- }
- /* Use Broadcast ID method for patching */
- rtl821x_phy_setup_package_broadcast(phydev, true);
-
- for (int i = 0; rtl8380_rtl8214fc_perport[i * 2]; i++) {
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8380_rtl8214fc_perport[i * 2],
- rtl8380_rtl8214fc_perport[i * 2 + 1]);
- }
-
- /* Disable broadcast ID */
- rtl821x_phy_setup_package_broadcast(phydev, false);
-
- /* Auto medium selection */
- for (int i = 0; i < 4; i++) {
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
- phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
- }
-
- return 0;
-}
-
-static int rtl8214fc_match_phy_device(struct phy_device *phydev)
-{
- int addr = phydev->mdio.addr;
-
- return phydev->phy_id == PHY_ID_RTL8214FC && addr >= 24;
-}
-
-static int rtl8380_configure_serdes(struct phy_device *phydev)
-{
- u32 v;
- u32 sds_conf_value;
- int i;
- struct fw_header *h;
- u32 *rtl8380_sds_take_reset;
- u32 *rtl8380_sds_common;
- u32 *rtl8380_sds01_qsgmii_6275b;
- u32 *rtl8380_sds23_qsgmii_6275b;
- u32 *rtl8380_sds4_fiber_6275b;
- u32 *rtl8380_sds5_fiber_6275b;
- u32 *rtl8380_sds_reset;
- u32 *rtl8380_sds_release_reset;
-
- phydev_info(phydev, "Detected internal RTL8380 SERDES\n");
-
- h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8380_1);
- if (!h)
- return -1;
-
- if (h->magic != 0x83808380) {
- phydev_err(phydev, "Wrong firmware file: magic number mismatch.\n");
- return -1;
- }
-
- rtl8380_sds_take_reset = (void *)h + sizeof(struct fw_header) + h->parts[0].start;
-
- rtl8380_sds_common = (void *)h + sizeof(struct fw_header) + h->parts[1].start;
-
- rtl8380_sds01_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[2].start;
-
- rtl8380_sds23_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[3].start;
-
- rtl8380_sds4_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[4].start;
-
- rtl8380_sds5_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[5].start;
-
- rtl8380_sds_reset = (void *)h + sizeof(struct fw_header) + h->parts[6].start;
-
- rtl8380_sds_release_reset = (void *)h + sizeof(struct fw_header) + h->parts[7].start;
-
- /* Back up serdes power off value */
- sds_conf_value = sw_r32(RTL838X_SDS_CFG_REG);
- pr_info("SDS power down value: %x\n", sds_conf_value);
-
- /* take serdes into reset */
- i = 0;
- while (rtl8380_sds_take_reset[2 * i]) {
- sw_w32(rtl8380_sds_take_reset[2 * i + 1], rtl8380_sds_take_reset[2 * i]);
- i++;
- udelay(1000);
- }
-
- /* apply common serdes patch */
- i = 0;
- while (rtl8380_sds_common[2 * i]) {
- sw_w32(rtl8380_sds_common[2 * i + 1], rtl8380_sds_common[2 * i]);
- i++;
- udelay(1000);
- }
-
- /* internal R/W enable */
- sw_w32(3, RTL838X_INT_RW_CTRL);
-
- /* SerDes ports 4 and 5 are FIBRE ports */
- sw_w32_mask(0x7 | 0x38, 1 | (1 << 3), RTL838X_INT_MODE_CTRL);
-
- /* SerDes module settings, SerDes 0-3 are QSGMII */
- v = 0x6 << 25 | 0x6 << 20 | 0x6 << 15 | 0x6 << 10;
- /* SerDes 4 and 5 are 1000BX FIBRE */
- v |= 0x4 << 5 | 0x4;
- sw_w32(v, RTL838X_SDS_MODE_SEL);
-
- pr_info("PLL control register: %x\n", sw_r32(RTL838X_PLL_CML_CTRL));
- sw_w32_mask(0xfffffff0, 0xaaaaaaaf & 0xf, RTL838X_PLL_CML_CTRL);
- i = 0;
- while (rtl8380_sds01_qsgmii_6275b[2 * i]) {
- sw_w32(rtl8380_sds01_qsgmii_6275b[2 * i + 1],
- rtl8380_sds01_qsgmii_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds23_qsgmii_6275b[2 * i]) {
- sw_w32(rtl8380_sds23_qsgmii_6275b[2 * i + 1], rtl8380_sds23_qsgmii_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds4_fiber_6275b[2 * i]) {
- sw_w32(rtl8380_sds4_fiber_6275b[2 * i + 1], rtl8380_sds4_fiber_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds5_fiber_6275b[2 * i]) {
- sw_w32(rtl8380_sds5_fiber_6275b[2 * i + 1], rtl8380_sds5_fiber_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds_reset[2 * i]) {
- sw_w32(rtl8380_sds_reset[2 * i + 1], rtl8380_sds_reset[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds_release_reset[2 * i]) {
- sw_w32(rtl8380_sds_release_reset[2 * i + 1], rtl8380_sds_release_reset[2 * i]);
- i++;
- }
-
- pr_info("SDS power down value now: %x\n", sw_r32(RTL838X_SDS_CFG_REG));
- sw_w32(sds_conf_value, RTL838X_SDS_CFG_REG);
-
- pr_info("Configuration of SERDES done\n");
-
- return 0;
-}
-
-static int rtl8390_configure_serdes(struct phy_device *phydev)
-{
- phydev_info(phydev, "Detected internal RTL8390 SERDES\n");
-
- /* In autoneg state, force link, set SR4_CFG_EN_LINK_FIB1G */
- sw_w32_mask(0, 1 << 18, RTL839X_SDS12_13_XSG0 + 0x0a);
-
- /* Disable EEE: Clear FRE16_EEE_RSG_FIB1G, FRE16_EEE_STD_FIB1G,
- * FRE16_C1_PWRSAV_EN_FIB1G, FRE16_C2_PWRSAV_EN_FIB1G
- * and FRE16_EEE_QUIET_FIB1G
- */
- sw_w32_mask(0x1f << 10, 0, RTL839X_SDS12_13_XSG0 + 0xe0);
-
- return 0;
-}
-
-void rtl9300_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int start_bit, u32 v)
-{
- int l = end_bit - start_bit + 1;
- u32 data = v;
-
- if (l < 32) {
- u32 mask = BIT(l) - 1;
-
- data = rtl930x_read_sds_phy(sds, page, reg);
- data &= ~(mask << start_bit);
- data |= (v & mask) << start_bit;
- }
-
- rtl930x_write_sds_phy(sds, page, reg, data);
-}
-
-u32 rtl9300_sds_field_r(int sds, u32 page, u32 reg, int end_bit, int start_bit)
-{
- int l = end_bit - start_bit + 1;
- u32 v = rtl930x_read_sds_phy(sds, page, reg);
-
- if (l >= 32)
- return v;
-
- return (v >> start_bit) & (BIT(l) - 1);
-}
-
-/* Read the link and speed status of the internal SerDes of the RTL9300
- */
-static int rtl9300_read_status(struct phy_device *phydev)
-{
- struct device *dev = &phydev->mdio.dev;
- int phy_addr = phydev->mdio.addr;
- struct device_node *dn;
- u32 sds_num = 0, status, latch_status, mode;
-
- if (dev->of_node) {
- dn = dev->of_node;
-
- if (of_property_read_u32(dn, "sds", &sds_num))
- sds_num = -1;
- pr_info("%s: Port %d, SerDes is %d\n", __func__, phy_addr, sds_num);
- } else {
- dev_err(dev, "No DT node.\n");
- return -EINVAL;
- }
-
- if (sds_num < 0)
- return 0;
-
- mode = rtl9300_sds_mode_get(sds_num);
- pr_info("%s got SDS mode %02x\n", __func__, mode);
- if (mode == RTL930X_SDS_OFF)
- mode = rtl9300_sds_field_r(sds_num, 0x1f, 9, 11, 7);
- if (mode == RTL930X_SDS_MODE_10GBASER) { /* 10GR mode */
- status = rtl9300_sds_field_r(sds_num, 0x5, 0, 12, 12);
- latch_status = rtl9300_sds_field_r(sds_num, 0x4, 1, 2, 2);
- status |= rtl9300_sds_field_r(sds_num, 0x5, 0, 12, 12);
- latch_status |= rtl9300_sds_field_r(sds_num, 0x4, 1, 2, 2);
- } else {
- status = rtl9300_sds_field_r(sds_num, 0x1, 29, 8, 0);
- latch_status = rtl9300_sds_field_r(sds_num, 0x1, 30, 8, 0);
- status |= rtl9300_sds_field_r(sds_num, 0x1, 29, 8, 0);
- latch_status |= rtl9300_sds_field_r(sds_num, 0x1, 30, 8, 0);
- }
-
- pr_info("%s link status: status: %d, latch %d\n", __func__, status, latch_status);
-
- if (latch_status) {
- phydev->link = true;
- if (mode == RTL930X_SDS_MODE_10GBASER) {
- phydev->speed = SPEED_10000;
- phydev->interface = PHY_INTERFACE_MODE_10GBASER;
- } else {
- phydev->speed = SPEED_1000;
- phydev->interface = PHY_INTERFACE_MODE_1000BASEX;
- }
-
- phydev->duplex = DUPLEX_FULL;
- }
-
- return 0;
-}
-
-void rtl930x_sds_rx_rst(int sds_num, phy_interface_t phy_if)
-{
- int page = 0x2e; /* 10GR and USXGMII */
-
- if (phy_if == PHY_INTERFACE_MODE_1000BASEX)
- page = 0x24;
-
- rtl9300_sds_field_w(sds_num, page, 0x15, 4, 4, 0x1);
- mdelay(5);
- rtl9300_sds_field_w(sds_num, page, 0x15, 4, 4, 0x0);
-}
-
-/* Force PHY modes on 10GBit Serdes
- */
-void rtl9300_force_sds_mode(int sds, phy_interface_t phy_if)
-{
- int lc_value;
- int sds_mode;
- bool lc_on;
- int lane_0 = (sds % 2) ? sds - 1 : sds;
- u32 v;
-
- pr_info("%s: SDS: %d, mode %d\n", __func__, sds, phy_if);
- switch (phy_if) {
- case PHY_INTERFACE_MODE_SGMII:
- sds_mode = RTL930X_SDS_MODE_SGMII;
- lc_on = false;
- lc_value = 0x1;
- break;
-
- case PHY_INTERFACE_MODE_HSGMII:
- sds_mode = RTL930X_SDS_MODE_HSGMII;
- lc_value = 0x3;
- /* Configure LC */
- break;
-
- case PHY_INTERFACE_MODE_1000BASEX:
- sds_mode = RTL930X_SDS_MODE_1000BASEX;
- lc_on = false;
- break;
-
- case PHY_INTERFACE_MODE_2500BASEX:
- sds_mode = RTL930X_SDS_MODE_2500BASEX;
- lc_value = 0x3;
- /* Configure LC */
- break;
-
- case PHY_INTERFACE_MODE_10GBASER:
- sds_mode = RTL930X_SDS_MODE_10GBASER;
- lc_on = true;
- lc_value = 0x5;
- break;
-
- case PHY_INTERFACE_MODE_NA:
- /* This will disable SerDes */
- sds_mode = RTL930X_SDS_OFF;
- break;
-
- default:
- pr_err("%s: unknown serdes mode: %s\n",
- __func__, phy_modes(phy_if));
- return;
- }
-
- pr_info("%s --------------------- serdes %d forcing to %x ...\n", __func__, sds, sds_mode);
- /* Power down SerDes */
- rtl9300_sds_field_w(sds, 0x20, 0, 7, 6, 0x3);
- if (sds == 5) pr_info("%s after %x\n", __func__, rtl930x_read_sds_phy(sds, 0x20, 0));
-
- if (sds == 5) pr_info("%s a %x\n", __func__, rtl930x_read_sds_phy(sds, 0x1f, 9));
- /* Force mode enable */
- rtl9300_sds_field_w(sds, 0x1f, 9, 6, 6, 0x1);
- if (sds == 5) pr_info("%s b %x\n", __func__, rtl930x_read_sds_phy(sds, 0x1f, 9));
-
- /* SerDes off */
- rtl9300_sds_field_w(sds, 0x1f, 9, 11, 7, RTL930X_SDS_OFF);
-
- if (phy_if == PHY_INTERFACE_MODE_NA)
- return;
-
- if (sds == 5) pr_info("%s c %x\n", __func__, rtl930x_read_sds_phy(sds, 0x20, 18));
- /* Enable LC and ring */
- rtl9300_sds_field_w(lane_0, 0x20, 18, 3, 0, 0xf);
-
- if (sds == lane_0)
- rtl9300_sds_field_w(lane_0, 0x20, 18, 5, 4, 0x1);
- else
- rtl9300_sds_field_w(lane_0, 0x20, 18, 7, 6, 0x1);
-
- rtl9300_sds_field_w(sds, 0x20, 0, 5, 4, 0x3);
-
- if (lc_on)
- rtl9300_sds_field_w(lane_0, 0x20, 18, 11, 8, lc_value);
- else
- rtl9300_sds_field_w(lane_0, 0x20, 18, 15, 12, lc_value);
-
- /* Force analog LC & ring on */
- rtl9300_sds_field_w(lane_0, 0x21, 11, 3, 0, 0xf);
-
- v = lc_on ? 0x3 : 0x1;
-
- if (sds == lane_0)
- rtl9300_sds_field_w(lane_0, 0x20, 18, 5, 4, v);
- else
- rtl9300_sds_field_w(lane_0, 0x20, 18, 7, 6, v);
-
- /* Force SerDes mode */
- rtl9300_sds_field_w(sds, 0x1f, 9, 6, 6, 1);
- rtl9300_sds_field_w(sds, 0x1f, 9, 11, 7, sds_mode);
-
- /* Toggle LC or Ring */
- for (int i = 0; i < 20; i++) {
- u32 cr_0, cr_1, cr_2;
- u32 m_bit, l_bit;
-
- mdelay(200);
-
- rtl930x_write_sds_phy(lane_0, 0x1f, 2, 53);
-
- m_bit = (lane_0 == sds) ? (4) : (5);
- l_bit = (lane_0 == sds) ? (4) : (5);
-
- cr_0 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit);
- mdelay(10);
- cr_1 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit);
- mdelay(10);
- cr_2 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit);
-
- if (cr_0 && cr_1 && cr_2) {
- u32 t;
-
- if (phy_if != PHY_INTERFACE_MODE_10GBASER)
- break;
-
- t = rtl9300_sds_field_r(sds, 0x6, 0x1, 2, 2);
- rtl9300_sds_field_w(sds, 0x6, 0x1, 2, 2, 0x1);
-
- /* Reset FSM */
- rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x1);
- mdelay(10);
- rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x0);
- mdelay(10);
-
- /* Need to read this twice */
- v = rtl9300_sds_field_r(sds, 0x5, 0, 12, 12);
- v = rtl9300_sds_field_r(sds, 0x5, 0, 12, 12);
-
- rtl9300_sds_field_w(sds, 0x6, 0x1, 2, 2, t);
-
- /* Reset FSM again */
- rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x1);
- mdelay(10);
- rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x0);
- mdelay(10);
-
- if (v == 1)
- break;
- }
-
- m_bit = (phy_if == PHY_INTERFACE_MODE_10GBASER) ? 3 : 1;
- l_bit = (phy_if == PHY_INTERFACE_MODE_10GBASER) ? 2 : 0;
-
- rtl9300_sds_field_w(lane_0, 0x21, 11, m_bit, l_bit, 0x2);
- mdelay(10);
- rtl9300_sds_field_w(lane_0, 0x21, 11, m_bit, l_bit, 0x3);
- }
-
- rtl930x_sds_rx_rst(sds, phy_if);
-
- /* Re-enable power */
- rtl9300_sds_field_w(sds, 0x20, 0, 7, 6, 0);
-
- pr_info("%s --------------------- serdes %d forced to %x DONE\n", __func__, sds, sds_mode);
-}
-
-void rtl9300_sds_tx_config(int sds, phy_interface_t phy_if)
-{
- /* parameters: rtl9303_80G_txParam_s2 */
- int impedance = 0x8;
- int pre_amp = 0x2;
- int main_amp = 0x9;
- int post_amp = 0x2;
- int pre_en = 0x1;
- int post_en = 0x1;
- int page;
-
- switch(phy_if) {
- case PHY_INTERFACE_MODE_1000BASEX:
- pre_amp = 0x1;
- main_amp = 0x9;
- post_amp = 0x1;
- page = 0x25;
- break;
- case PHY_INTERFACE_MODE_HSGMII:
- case PHY_INTERFACE_MODE_2500BASEX:
- pre_amp = 0;
- post_amp = 0x8;
- pre_en = 0;
- page = 0x29;
- break;
- case PHY_INTERFACE_MODE_10GBASER:
- case PHY_INTERFACE_MODE_USXGMII:
- case PHY_INTERFACE_MODE_XGMII:
- pre_en = 0;
- pre_amp = 0;
- main_amp = 0x10;
- post_amp = 0;
- post_en = 0;
- page = 0x2f;
- break;
- default:
- pr_err("%s: unsupported PHY mode\n", __func__);
- return;
- }
-
- rtl9300_sds_field_w(sds, page, 0x01, 15, 11, pre_amp);
- rtl9300_sds_field_w(sds, page, 0x06, 4, 0, post_amp);
- rtl9300_sds_field_w(sds, page, 0x07, 0, 0, pre_en);
- rtl9300_sds_field_w(sds, page, 0x07, 3, 3, post_en);
- rtl9300_sds_field_w(sds, page, 0x07, 8, 4, main_amp);
- rtl9300_sds_field_w(sds, page, 0x18, 15, 12, impedance);
-}
-
-/* Wait for clock ready, this assumes the SerDes is in XGMII mode
- * timeout is in ms
- */
-int rtl9300_sds_clock_wait(int timeout)
-{
- u32 v;
- unsigned long start = jiffies;
-
- do {
- rtl9300_sds_field_w(2, 0x1f, 0x2, 15, 0, 53);
- v = rtl9300_sds_field_r(2, 0x1f, 20, 5, 4);
- if (v == 3)
- return 0;
- } while (jiffies < start + (HZ / 1000) * timeout);
-
- return 1;
-}
-
-void rtl9300_serdes_mac_link_config(int sds, bool tx_normal, bool rx_normal)
-{
- u32 v10, v1;
-
- v10 = rtl930x_read_sds_phy(sds, 6, 2); /* 10GBit, page 6, reg 2 */
- v1 = rtl930x_read_sds_phy(sds, 0, 0); /* 1GBit, page 0, reg 0 */
- pr_info("%s: registers before %08x %08x\n", __func__, v10, v1);
-
- v10 &= ~(BIT(13) | BIT(14));
- v1 &= ~(BIT(8) | BIT(9));
-
- v10 |= rx_normal ? 0 : BIT(13);
- v1 |= rx_normal ? 0 : BIT(9);
-
- v10 |= tx_normal ? 0 : BIT(14);
- v1 |= tx_normal ? 0 : BIT(8);
-
- rtl930x_write_sds_phy(sds, 6, 2, v10);
- rtl930x_write_sds_phy(sds, 0, 0, v1);
-
- v10 = rtl930x_read_sds_phy(sds, 6, 2);
- v1 = rtl930x_read_sds_phy(sds, 0, 0);
- pr_info("%s: registers after %08x %08x\n", __func__, v10, v1);
-}
-
-void rtl9300_sds_rxcal_dcvs_manual(u32 sds_num, u32 dcvs_id, bool manual, u32 dvcs_list[])
-{
- if (manual) {
- switch(dcvs_id) {
- case 0:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 14, 14, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 5, 5, dvcs_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 4, 0, dvcs_list[1]);
- break;
- case 1:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 13, 13, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 15, 15, dvcs_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 14, 11, dvcs_list[1]);
- break;
- case 2:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 12, 12, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 10, 10, dvcs_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 9, 6, dvcs_list[1]);
- break;
- case 3:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 11, 11, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 5, 5, dvcs_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 4, 1, dvcs_list[1]);
- break;
- case 4:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 15, 15, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 10, 10, dvcs_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 9, 6, dvcs_list[1]);
- break;
- case 5:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x02, 11, 11, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 4, 4, dvcs_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 3, 0, dvcs_list[1]);
- break;
- default:
- break;
- }
- } else {
- switch(dcvs_id) {
- case 0:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 14, 14, 0x0);
- break;
- case 1:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 13, 13, 0x0);
- break;
- case 2:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 12, 12, 0x0);
- break;
- case 3:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 11, 11, 0x0);
- break;
- case 4:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 15, 15, 0x0);
- break;
- case 5:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x02, 11, 11, 0x0);
- break;
- default:
- break;
- }
- mdelay(1);
- }
-}
-
-void rtl9300_sds_rxcal_dcvs_get(u32 sds_num, u32 dcvs_id, u32 dcvs_list[])
-{
- u32 dcvs_sign_out = 0, dcvs_coef_bin = 0;
- bool dcvs_manual;
-
- if (!(sds_num % 2))
- rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
- else
- rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
-
- /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
-
- /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
- rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
-
- switch(dcvs_id) {
- case 0:
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x22);
- mdelay(1);
-
- /* ##DCVS0 Read Out */
- dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
- dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
- dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 14, 14);
- break;
-
- case 1:
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x23);
- mdelay(1);
-
- /* ##DCVS0 Read Out */
- dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
- dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
- dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 13, 13);
- break;
-
- case 2:
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x24);
- mdelay(1);
-
- /* ##DCVS0 Read Out */
- dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
- dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
- dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 12, 12);
- break;
- case 3:
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x25);
- mdelay(1);
-
- /* ##DCVS0 Read Out */
- dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
- dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
- dcvs_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 11, 11);
- break;
-
- case 4:
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x2c);
- mdelay(1);
-
- /* ##DCVS0 Read Out */
- dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
- dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
- dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x01, 15, 15);
- break;
-
- case 5:
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x2d);
- mdelay(1);
-
- /* ##DCVS0 Read Out */
- dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
- dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
- dcvs_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x02, 11, 11);
- break;
-
- default:
- break;
- }
-
- if (dcvs_sign_out)
- pr_info("%s DCVS %u Sign: -", __func__, dcvs_id);
- else
- pr_info("%s DCVS %u Sign: +", __func__, dcvs_id);
-
- pr_info("DCVS %u even coefficient = %u", dcvs_id, dcvs_coef_bin);
- pr_info("DCVS %u manual = %u", dcvs_id, dcvs_manual);
-
- dcvs_list[0] = dcvs_sign_out;
- dcvs_list[1] = dcvs_coef_bin;
-}
-
-void rtl9300_sds_rxcal_leq_manual(u32 sds_num, bool manual, u32 leq_gray)
-{
- if (manual) {
- rtl9300_sds_field_w(sds_num, 0x2e, 0x18, 15, 15, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x16, 14, 10, leq_gray);
- } else {
- rtl9300_sds_field_w(sds_num, 0x2e, 0x18, 15, 15, 0x0);
- mdelay(100);
- }
-}
-
-void rtl9300_sds_rxcal_leq_offset_manual(u32 sds_num, bool manual, u32 offset)
-{
- if (manual) {
- rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 6, 2, offset);
- } else {
- rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 6, 2, offset);
- mdelay(1);
- }
-}
-
-#define GRAY_BITS 5
-u32 rtl9300_sds_rxcal_gray_to_binary(u32 gray_code)
-{
- int i, j, m;
- u32 g[GRAY_BITS];
- u32 c[GRAY_BITS];
- u32 leq_binary = 0;
-
- for(i = 0; i < GRAY_BITS; i++)
- g[i] = (gray_code & BIT(i)) >> i;
-
- m = GRAY_BITS - 1;
-
- c[m] = g[m];
-
- for(i = 0; i < m; i++) {
- c[i] = g[i];
- for(j = i + 1; j < GRAY_BITS; j++)
- c[i] = c[i] ^ g[j];
- }
-
- for(i = 0; i < GRAY_BITS; i++)
- leq_binary += c[i] << i;
-
- return leq_binary;
-}
-
-u32 rtl9300_sds_rxcal_leq_read(int sds_num)
-{
- u32 leq_gray, leq_bin;
- bool leq_manual;
-
- if (!(sds_num % 2))
- rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
- else
- rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
-
- /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
-
- /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[0 1 x x x x] */
- rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x10);
- mdelay(1);
-
- /* ##LEQ Read Out */
- leq_gray = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 7, 3);
- leq_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x18, 15, 15);
- leq_bin = rtl9300_sds_rxcal_gray_to_binary(leq_gray);
-
- pr_info("LEQ_gray: %u, LEQ_bin: %u", leq_gray, leq_bin);
- pr_info("LEQ manual: %u", leq_manual);
-
- return leq_bin;
-}
-
-void rtl9300_sds_rxcal_vth_manual(u32 sds_num, bool manual, u32 vth_list[])
-{
- if (manual) {
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, 13, 13, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x13, 5, 3, vth_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x13, 2, 0, vth_list[1]);
- } else {
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, 13, 13, 0x0);
- mdelay(10);
- }
-}
-
-void rtl9300_sds_rxcal_vth_get(u32 sds_num, u32 vth_list[])
-{
- u32 vth_manual;
-
- /* ##Page0x1F, Reg0x02[15 0], REG_DBGO_SEL=[0x002F]; */ /* Lane0 */
- /* ##Page0x1F, Reg0x02[15 0], REG_DBGO_SEL=[0x0031]; */ /* Lane1 */
- if (!(sds_num % 2))
- rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
- else
- rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
-
- /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
- /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
- rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
- /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 0 0] */
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xc);
-
- mdelay(1);
-
- /* ##VthP & VthN Read Out */
- vth_list[0] = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 2, 0); /* v_thp set bin */
- vth_list[1] = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 3); /* v_thn set bin */
-
- pr_info("vth_set_bin = %d", vth_list[0]);
- pr_info("vth_set_bin = %d", vth_list[1]);
-
- vth_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, 13, 13);
- pr_info("Vth Maunal = %d", vth_manual);
-}
-
-void rtl9300_sds_rxcal_tap_manual(u32 sds_num, int tap_id, bool manual, u32 tap_list[])
-{
- if (manual) {
- switch(tap_id) {
- case 0:
- /* ##REG0_LOAD_IN_INIT[0]=1; REG0_TAP0_INIT[5:0]=Tap0_Value */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 5, 5, tap_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 4, 0, tap_list[1]);
- break;
- case 1:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
- rtl9300_sds_field_w(sds_num, 0x21, 0x07, 6, 6, tap_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 11, 6, tap_list[1]);
- rtl9300_sds_field_w(sds_num, 0x21, 0x07, 5, 5, tap_list[2]);
- rtl9300_sds_field_w(sds_num, 0x2f, 0x12, 5, 0, tap_list[3]);
- break;
- case 2:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 5, 5, tap_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 4, 0, tap_list[1]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 11, 11, tap_list[2]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 10, 6, tap_list[3]);
- break;
- case 3:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 5, 5, tap_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 4, 0, tap_list[1]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 5, 5, tap_list[2]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 4, 0, tap_list[3]);
- break;
- case 4:
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
- rtl9300_sds_field_w(sds_num, 0x2f, 0x01, 5, 5, tap_list[0]);
- rtl9300_sds_field_w(sds_num, 0x2f, 0x01, 4, 0, tap_list[1]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 11, 11, tap_list[2]);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 10, 6, tap_list[3]);
- break;
- default:
- break;
- }
- } else {
- rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x0);
- mdelay(10);
- }
-}
-
-void rtl9300_sds_rxcal_tap_get(u32 sds_num, u32 tap_id, u32 tap_list[])
-{
- u32 tap0_sign_out;
- u32 tap0_coef_bin;
- u32 tap_sign_out_even;
- u32 tap_coef_bin_even;
- u32 tap_sign_out_odd;
- u32 tap_coef_bin_odd;
- bool tap_manual;
-
- if (!(sds_num % 2))
- rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
- else
- rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
-
- /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
- /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
- rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
-
- if (!tap_id) {
- /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 0 0 1] */
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0);
- /* ##Tap1 Even Read Out */
- mdelay(1);
- tap0_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5);
- tap0_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0);
-
- if (tap0_sign_out == 1)
- pr_info("Tap0 Sign : -");
- else
- pr_info("Tap0 Sign : +");
-
- pr_info("tap0_coef_bin = %d", tap0_coef_bin);
-
- tap_list[0] = tap0_sign_out;
- tap_list[1] = tap0_coef_bin;
-
- tap_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, 7, 7);
- pr_info("tap0 manual = %u",tap_manual);
- } else {
- /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 0 0 1] */
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, tap_id);
- mdelay(1);
- /* ##Tap1 Even Read Out */
- tap_sign_out_even = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5);
- tap_coef_bin_even = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0);
-
- /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 1 1 0] */
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, (tap_id + 5));
- /* ##Tap1 Odd Read Out */
- tap_sign_out_odd = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5);
- tap_coef_bin_odd = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0);
-
- if (tap_sign_out_even == 1)
- pr_info("Tap %u even sign: -", tap_id);
- else
- pr_info("Tap %u even sign: +", tap_id);
-
- pr_info("Tap %u even coefficient = %u", tap_id, tap_coef_bin_even);
-
- if (tap_sign_out_odd == 1)
- pr_info("Tap %u odd sign: -", tap_id);
- else
- pr_info("Tap %u odd sign: +", tap_id);
-
- pr_info("Tap %u odd coefficient = %u", tap_id,tap_coef_bin_odd);
-
- tap_list[0] = tap_sign_out_even;
- tap_list[1] = tap_coef_bin_even;
- tap_list[2] = tap_sign_out_odd;
- tap_list[3] = tap_coef_bin_odd;
-
- tap_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7);
- pr_info("tap %u manual = %d",tap_id, tap_manual);
- }
-}
-
-void rtl9300_do_rx_calibration_1(int sds, phy_interface_t phy_mode)
-{
- /* From both rtl9300_rxCaliConf_serdes_myParam and rtl9300_rxCaliConf_phy_myParam */
- int tap0_init_val = 0x1f; /* Initial Decision Fed Equalizer 0 tap */
- int vth_min = 0x0;
-
- pr_info("start_1.1.1 initial value for sds %d\n", sds);
- rtl930x_write_sds_phy(sds, 6, 0, 0);
-
- /* FGCAL */
- rtl9300_sds_field_w(sds, 0x2e, 0x01, 14, 14, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x1c, 10, 5, 0x20);
- rtl9300_sds_field_w(sds, 0x2f, 0x02, 0, 0, 0x01);
-
- /* DCVS */
- rtl9300_sds_field_w(sds, 0x2e, 0x1e, 14, 11, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x01, 15, 15, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x02, 11, 11, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x1c, 4, 0, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x1d, 15, 11, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x1d, 10, 6, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x1d, 5, 1, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x02, 10, 6, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x11, 4, 0, 0x00);
- rtl9300_sds_field_w(sds, 0x2f, 0x00, 3, 0, 0x0f);
- rtl9300_sds_field_w(sds, 0x2e, 0x04, 6, 6, 0x01);
- rtl9300_sds_field_w(sds, 0x2e, 0x04, 7, 7, 0x01);
-
- /* LEQ (Long Term Equivalent signal level) */
- rtl9300_sds_field_w(sds, 0x2e, 0x16, 14, 8, 0x00);
-
- /* DFE (Decision Fed Equalizer) */
- rtl9300_sds_field_w(sds, 0x2f, 0x03, 5, 0, tap0_init_val);
- rtl9300_sds_field_w(sds, 0x2e, 0x09, 11, 6, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x09, 5, 0, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x0a, 5, 0, 0x00);
- rtl9300_sds_field_w(sds, 0x2f, 0x01, 5, 0, 0x00);
- rtl9300_sds_field_w(sds, 0x2f, 0x12, 5, 0, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x0a, 11, 6, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x06, 5, 0, 0x00);
- rtl9300_sds_field_w(sds, 0x2f, 0x01, 5, 0, 0x00);
-
- /* Vth */
- rtl9300_sds_field_w(sds, 0x2e, 0x13, 5, 3, 0x07);
- rtl9300_sds_field_w(sds, 0x2e, 0x13, 2, 0, 0x07);
- rtl9300_sds_field_w(sds, 0x2f, 0x0b, 5, 3, vth_min);
-
- pr_info("end_1.1.1 --\n");
-
- pr_info("start_1.1.2 Load DFE init. value\n");
-
- rtl9300_sds_field_w(sds, 0x2e, 0x0f, 13, 7, 0x7f);
-
- pr_info("end_1.1.2\n");
-
- pr_info("start_1.1.3 disable LEQ training,enable DFE clock\n");
-
- rtl9300_sds_field_w(sds, 0x2e, 0x17, 7, 7, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x17, 6, 2, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x0c, 8, 8, 0x00);
- rtl9300_sds_field_w(sds, 0x2e, 0x0b, 4, 4, 0x01);
- rtl9300_sds_field_w(sds, 0x2e, 0x12, 14, 14, 0x00);
- rtl9300_sds_field_w(sds, 0x2f, 0x02, 15, 15, 0x00);
-
- pr_info("end_1.1.3 --\n");
-
- pr_info("start_1.1.4 offset cali setting\n");
-
- rtl9300_sds_field_w(sds, 0x2e, 0x0f, 15, 14, 0x03);
-
- pr_info("end_1.1.4\n");
-
- pr_info("start_1.1.5 LEQ and DFE setting\n");
-
- /* TODO: make this work for DAC cables of different lengths */
- /* For a 10GBit serdes wit Fibre, SDS 8 or 9 */
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER || PHY_INTERFACE_MODE_1000BASEX)
- rtl9300_sds_field_w(sds, 0x2e, 0x16, 3, 2, 0x02);
- else
- pr_err("%s not PHY-based or SerDes, implement DAC!\n", __func__);
-
- /* No serdes, check for Aquantia PHYs */
- rtl9300_sds_field_w(sds, 0x2e, 0x16, 3, 2, 0x02);
-
- rtl9300_sds_field_w(sds, 0x2e, 0x0f, 6, 0, 0x5f);
- rtl9300_sds_field_w(sds, 0x2f, 0x05, 7, 2, 0x1f);
- rtl9300_sds_field_w(sds, 0x2e, 0x19, 9, 5, 0x1f);
- rtl9300_sds_field_w(sds, 0x2f, 0x0b, 15, 9, 0x3c);
- rtl9300_sds_field_w(sds, 0x2e, 0x0b, 1, 0, 0x03);
-
- pr_info("end_1.1.5\n");
-}
-
-void rtl9300_do_rx_calibration_2_1(u32 sds_num)
-{
- pr_info("start_1.2.1 ForegroundOffsetCal_Manual\n");
-
- /* Gray config endis to 1 */
- rtl9300_sds_field_w(sds_num, 0x2f, 0x02, 2, 2, 0x01);
-
- /* ForegroundOffsetCal_Manual(auto mode) */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 14, 14, 0x00);
-
- pr_info("end_1.2.1");
-}
-
-void rtl9300_do_rx_calibration_2_2(int sds_num)
-{
- /* Force Rx-Run = 0 */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 8, 8, 0x0);
-
- rtl930x_sds_rx_rst(sds_num, PHY_INTERFACE_MODE_10GBASER);
-}
-
-void rtl9300_do_rx_calibration_2_3(int sds_num)
-{
- u32 fgcal_binary, fgcal_gray;
- u32 offset_range;
-
- pr_info("start_1.2.3 Foreground Calibration\n");
-
- while(1) {
- if (!(sds_num % 2))
- rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
- else
- rtl930x_write_sds_phy(sds_num -1 , 0x1f, 0x2, 0x31);
-
- /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
- rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
- /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
- rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
- /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 1 1] */
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xf);
- /* ##FGCAL read gray */
- fgcal_gray = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 0);
- /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 1 0] */
- rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xe);
- /* ##FGCAL read binary */
- fgcal_binary = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 0);
-
- pr_info("%s: fgcal_gray: %d, fgcal_binary %d\n",
- __func__, fgcal_gray, fgcal_binary);
-
- offset_range = rtl9300_sds_field_r(sds_num, 0x2e, 0x15, 15, 14);
-
- if (fgcal_binary > 60 || fgcal_binary < 3) {
- if (offset_range == 3) {
- pr_info("%s: Foreground Calibration result marginal!", __func__);
- break;
- } else {
- offset_range++;
- rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 15, 14, offset_range);
- rtl9300_do_rx_calibration_2_2(sds_num);
- }
- } else {
- break;
- }
- }
- pr_info("%s: end_1.2.3\n", __func__);
-}
-
-void rtl9300_do_rx_calibration_2(int sds)
-{
- rtl930x_sds_rx_rst(sds, PHY_INTERFACE_MODE_10GBASER);
- rtl9300_do_rx_calibration_2_1(sds);
- rtl9300_do_rx_calibration_2_2(sds);
- rtl9300_do_rx_calibration_2_3(sds);
-}
-
-void rtl9300_sds_rxcal_3_1(int sds_num, phy_interface_t phy_mode)
-{
- pr_info("start_1.3.1");
-
- /* ##1.3.1 */
- if (phy_mode != PHY_INTERFACE_MODE_10GBASER && phy_mode != PHY_INTERFACE_MODE_1000BASEX)
- rtl9300_sds_field_w(sds_num, 0x2e, 0xc, 8, 8, 0);
-
- rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x0);
- rtl9300_sds_rxcal_leq_manual(sds_num, false, 0);
-
- pr_info("end_1.3.1");
-}
-
-void rtl9300_sds_rxcal_3_2(int sds_num, phy_interface_t phy_mode)
-{
- u32 sum10 = 0, avg10, int10;
- int dac_long_cable_offset;
- bool eq_hold_enabled;
- int i;
-
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX) {
- /* rtl9300_rxCaliConf_serdes_myParam */
- dac_long_cable_offset = 3;
- eq_hold_enabled = true;
- } else {
- /* rtl9300_rxCaliConf_phy_myParam */
- dac_long_cable_offset = 0;
- eq_hold_enabled = false;
- }
-
- if (phy_mode == PHY_INTERFACE_MODE_1000BASEX)
- pr_warn("%s: LEQ only valid for 10GR!\n", __func__);
-
- pr_info("start_1.3.2");
-
- for(i = 0; i < 10; i++) {
- sum10 += rtl9300_sds_rxcal_leq_read(sds_num);
- mdelay(10);
- }
-
- avg10 = (sum10 / 10) + (((sum10 % 10) >= 5) ? 1 : 0);
- int10 = sum10 / 10;
-
- pr_info("sum10:%u, avg10:%u, int10:%u", sum10, avg10, int10);
-
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX) {
- if (dac_long_cable_offset) {
- rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, dac_long_cable_offset);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, eq_hold_enabled);
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER)
- rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10);
- } else {
- if (sum10 >= 5) {
- rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, 3);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x1);
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER)
- rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10);
- } else {
- rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, 0);
- rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x1);
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER)
- rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10);
- }
- }
- }
-
- pr_info("Sds:%u LEQ = %u",sds_num, rtl9300_sds_rxcal_leq_read(sds_num));
-
- pr_info("end_1.3.2");
-}
-
-void rtl9300_do_rx_calibration_3(int sds_num, phy_interface_t phy_mode)
-{
- rtl9300_sds_rxcal_3_1(sds_num, phy_mode);
-
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX)
- rtl9300_sds_rxcal_3_2(sds_num, phy_mode);
-}
-
-void rtl9300_do_rx_calibration_4_1(int sds_num)
-{
- u32 vth_list[2] = {0, 0};
- u32 tap0_list[4] = {0, 0, 0, 0};
-
- pr_info("start_1.4.1");
-
- /* ##1.4.1 */
- rtl9300_sds_rxcal_vth_manual(sds_num, false, vth_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 0, false, tap0_list);
- mdelay(200);
-
- pr_info("end_1.4.1");
-}
-
-void rtl9300_do_rx_calibration_4_2(u32 sds_num)
-{
- u32 vth_list[2];
- u32 tap_list[4];
-
- pr_info("start_1.4.2");
-
- rtl9300_sds_rxcal_vth_get(sds_num, vth_list);
- rtl9300_sds_rxcal_vth_manual(sds_num, true, vth_list);
-
- mdelay(100);
-
- rtl9300_sds_rxcal_tap_get(sds_num, 0, tap_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 0, true, tap_list);
-
- pr_info("end_1.4.2");
-}
-
-void rtl9300_do_rx_calibration_4(u32 sds_num)
-{
- rtl9300_do_rx_calibration_4_1(sds_num);
- rtl9300_do_rx_calibration_4_2(sds_num);
-}
-
-void rtl9300_do_rx_calibration_5_2(u32 sds_num)
-{
- u32 tap1_list[4] = {0};
- u32 tap2_list[4] = {0};
- u32 tap3_list[4] = {0};
- u32 tap4_list[4] = {0};
-
- pr_info("start_1.5.2");
-
- rtl9300_sds_rxcal_tap_manual(sds_num, 1, false, tap1_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 2, false, tap2_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 3, false, tap3_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 4, false, tap4_list);
-
- mdelay(30);
-
- pr_info("end_1.5.2");
-}
-
-void rtl9300_do_rx_calibration_5(u32 sds_num, phy_interface_t phy_mode)
-{
- if (phy_mode == PHY_INTERFACE_MODE_10GBASER) /* dfeTap1_4Enable true */
- rtl9300_do_rx_calibration_5_2(sds_num);
-}
-
-
-void rtl9300_do_rx_calibration_dfe_disable(u32 sds_num)
-{
- u32 tap1_list[4] = {0};
- u32 tap2_list[4] = {0};
- u32 tap3_list[4] = {0};
- u32 tap4_list[4] = {0};
-
- rtl9300_sds_rxcal_tap_manual(sds_num, 1, true, tap1_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 2, true, tap2_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 3, true, tap3_list);
- rtl9300_sds_rxcal_tap_manual(sds_num, 4, true, tap4_list);
-
- mdelay(10);
-}
-
-void rtl9300_do_rx_calibration(int sds, phy_interface_t phy_mode)
-{
- u32 latch_sts;
-
- rtl9300_do_rx_calibration_1(sds, phy_mode);
- rtl9300_do_rx_calibration_2(sds);
- rtl9300_do_rx_calibration_4(sds);
- rtl9300_do_rx_calibration_5(sds, phy_mode);
- mdelay(20);
-
- /* Do this only for 10GR mode, SDS active in mode 0x1a */
- if (rtl9300_sds_field_r(sds, 0x1f, 9, 11, 7) == RTL930X_SDS_MODE_10GBASER) {
- pr_info("%s: SDS enabled\n", __func__);
- latch_sts = rtl9300_sds_field_r(sds, 0x4, 1, 2, 2);
- mdelay(1);
- latch_sts = rtl9300_sds_field_r(sds, 0x4, 1, 2, 2);
- if (latch_sts) {
- rtl9300_do_rx_calibration_dfe_disable(sds);
- rtl9300_do_rx_calibration_4(sds);
- rtl9300_do_rx_calibration_5(sds, phy_mode);
- }
- }
-}
-
-int rtl9300_sds_sym_err_reset(int sds_num, phy_interface_t phy_mode)
-{
- switch (phy_mode) {
- case PHY_INTERFACE_MODE_XGMII:
- break;
-
- case PHY_INTERFACE_MODE_10GBASER:
- /* Read twice to clear */
- rtl930x_read_sds_phy(sds_num, 5, 1);
- rtl930x_read_sds_phy(sds_num, 5, 1);
- break;
-
- case PHY_INTERFACE_MODE_1000BASEX:
- rtl9300_sds_field_w(sds_num, 0x1, 24, 2, 0, 0);
- rtl9300_sds_field_w(sds_num, 0x1, 3, 15, 8, 0);
- rtl9300_sds_field_w(sds_num, 0x1, 2, 15, 0, 0);
- break;
-
- default:
- pr_info("%s unsupported phy mode\n", __func__);
- return -1;
- }
-
- return 0;
-}
-
-u32 rtl9300_sds_sym_err_get(int sds_num, phy_interface_t phy_mode)
-{
- u32 v = 0;
-
- switch (phy_mode) {
- case PHY_INTERFACE_MODE_XGMII:
- break;
-
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_10GBASER:
- v = rtl930x_read_sds_phy(sds_num, 5, 1);
- return v & 0xff;
-
- default:
- pr_info("%s unsupported PHY-mode\n", __func__);
- }
-
- return v;
-}
-
-int rtl9300_sds_check_calibration(int sds_num, phy_interface_t phy_mode)
-{
- u32 errors1, errors2;
-
- rtl9300_sds_sym_err_reset(sds_num, phy_mode);
- rtl9300_sds_sym_err_reset(sds_num, phy_mode);
-
- /* Count errors during 1ms */
- errors1 = rtl9300_sds_sym_err_get(sds_num, phy_mode);
- mdelay(1);
- errors2 = rtl9300_sds_sym_err_get(sds_num, phy_mode);
-
- switch (phy_mode) {
- case PHY_INTERFACE_MODE_1000BASEX:
- case PHY_INTERFACE_MODE_XGMII:
- if ((errors2 - errors1 > 100) ||
- (errors1 >= 0xffff00) || (errors2 >= 0xffff00)) {
- pr_info("%s XSGMII error rate too high\n", __func__);
- return 1;
- }
- break;
- case PHY_INTERFACE_MODE_10GBASER:
- if (errors2 > 0) {
- pr_info("%s 10GBASER error rate too high\n", __func__);
- return 1;
- }
- break;
- default:
- return 1;
- }
-
- return 0;
-}
-
-void rtl9300_phy_enable_10g_1g(int sds_num)
-{
- u32 v;
-
- /* Enable 1GBit PHY */
- v = rtl930x_read_sds_phy(sds_num, PHY_PAGE_2, MII_BMCR);
- pr_info("%s 1gbit phy: %08x\n", __func__, v);
- v &= ~BMCR_PDOWN;
- rtl930x_write_sds_phy(sds_num, PHY_PAGE_2, MII_BMCR, v);
- pr_info("%s 1gbit phy enabled: %08x\n", __func__, v);
-
- /* Enable 10GBit PHY */
- v = rtl930x_read_sds_phy(sds_num, PHY_PAGE_4, MII_BMCR);
- pr_info("%s 10gbit phy: %08x\n", __func__, v);
- v &= ~BMCR_PDOWN;
- rtl930x_write_sds_phy(sds_num, PHY_PAGE_4, MII_BMCR, v);
- pr_info("%s 10gbit phy after: %08x\n", __func__, v);
-
- /* dal_longan_construct_mac_default_10gmedia_fiber */
- v = rtl930x_read_sds_phy(sds_num, 0x1f, 11);
- pr_info("%s set medium: %08x\n", __func__, v);
- v |= BIT(1);
- rtl930x_write_sds_phy(sds_num, 0x1f, 11, v);
- pr_info("%s set medium after: %08x\n", __func__, v);
-}
-
-static int rtl9300_sds_10g_idle(int sds_num);
-static void rtl9300_serdes_patch(int sds_num);
-
-#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C)
-int rtl9300_serdes_setup(int port, int sds_num, phy_interface_t phy_mode)
-{
- int calib_tries = 0;
-
- /* Turn Off Serdes */
- rtl9300_sds_rst(sds_num, RTL930X_SDS_OFF);
-
- /* Apply serdes patches */
- rtl9300_serdes_patch(sds_num);
-
- /* Maybe use dal_longan_sds_init */
-
- /* dal_longan_construct_serdesConfig_init */ /* Serdes Construct */
- rtl9300_phy_enable_10g_1g(sds_num);
-
- /* Disable MAC */
- sw_w32_mask(0, 1, RTL930X_MAC_FORCE_MODE_CTRL + 4 * port);
- mdelay(20);
-
- /* ----> dal_longan_sds_mode_set */
- pr_info("%s: Configuring RTL9300 SERDES %d\n", __func__, sds_num);
-
- /* Configure link to MAC */
- rtl9300_serdes_mac_link_config(sds_num, true, true); /* MAC Construct */
-
- /* Re-Enable MAC */
- sw_w32_mask(1, 0, RTL930X_MAC_FORCE_MODE_CTRL + 4 * port);
-
- /* Enable SDS in desired mode */
- rtl9300_force_sds_mode(sds_num, phy_mode);
-
- /* Enable Fiber RX */
- rtl9300_sds_field_w(sds_num, 0x20, 2, 12, 12, 0);
-
- /* Calibrate SerDes receiver in loopback mode */
- rtl9300_sds_10g_idle(sds_num);
- do {
- rtl9300_do_rx_calibration(sds_num, phy_mode);
- calib_tries++;
- mdelay(50);
- } while (rtl9300_sds_check_calibration(sds_num, phy_mode) && calib_tries < 3);
- if (calib_tries >= 3)
- pr_warn("%s: SerDes RX calibration failed\n", __func__);
-
- /* Leave loopback mode */
- rtl9300_sds_tx_config(sds_num, phy_mode);
-
- return 0;
-}
-
-static int rtl9300_sds_10g_idle(int sds_num)
-{
- bool busy;
- int i = 0;
-
- do {
- if (sds_num % 2) {
- rtl9300_sds_field_w(sds_num - 1, 0x1f, 0x2, 15, 0, 53);
- busy = !!rtl9300_sds_field_r(sds_num - 1, 0x1f, 0x14, 1, 1);
- } else {
- rtl9300_sds_field_w(sds_num, 0x1f, 0x2, 15, 0, 53);
- busy = !!rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 0, 0);
- }
- i++;
- } while (busy && i < 100);
-
- if (i < 100)
- return 0;
-
- pr_warn("%s WARNING: Waiting for RX idle timed out, SDS %d\n", __func__, sds_num);
- return -EIO;
-}
-
-typedef struct {
- u8 page;
- u8 reg;
- u16 data;
-} sds_config;
-
-sds_config rtl9300_a_sds_10gr_lane0[] =
-{
- /* 1G */
- {0x00, 0x0E, 0x3053}, {0x01, 0x14, 0x0100}, {0x21, 0x03, 0x8206},
- {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F},
- {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, {0x21, 0x0E, 0x0000},
- {0x21, 0x0F, 0x0008}, {0x24, 0x00, 0x0668}, {0x24, 0x02, 0xD020},
- {0x24, 0x06, 0xC000}, {0x24, 0x0B, 0x1892}, {0x24, 0x0F, 0xFFDF},
- {0x24, 0x12, 0x03C4}, {0x24, 0x13, 0x027F}, {0x24, 0x14, 0x1311},
- {0x24, 0x16, 0x00C9}, {0x24, 0x17, 0xA100}, {0x24, 0x1A, 0x0001},
- {0x24, 0x1C, 0x0400}, {0x25, 0x01, 0x0300}, {0x25, 0x02, 0x1017},
- {0x25, 0x03, 0xFFDF}, {0x25, 0x05, 0x7F7C}, {0x25, 0x07, 0x8100},
- {0x25, 0x08, 0x0001}, {0x25, 0x09, 0xFFD4}, {0x25, 0x0A, 0x7C2F},
- {0x25, 0x0E, 0x003F}, {0x25, 0x0F, 0x0121}, {0x25, 0x10, 0x0020},
- {0x25, 0x11, 0x8840}, {0x2B, 0x13, 0x0050}, {0x2B, 0x18, 0x8E88},
- {0x2B, 0x19, 0x4902}, {0x2B, 0x1D, 0x2501}, {0x2D, 0x13, 0x0050},
- {0x2D, 0x18, 0x8E88}, {0x2D, 0x19, 0x4902}, {0x2D, 0x1D, 0x2641},
- {0x2F, 0x13, 0x0050}, {0x2F, 0x18, 0x8E88}, {0x2F, 0x19, 0x4902},
- {0x2F, 0x1D, 0x66E1},
- /* 3.125G */
- {0x28, 0x00, 0x0668}, {0x28, 0x02, 0xD020}, {0x28, 0x06, 0xC000},
- {0x28, 0x0B, 0x1892}, {0x28, 0x0F, 0xFFDF}, {0x28, 0x12, 0x01C4},
- {0x28, 0x13, 0x027F}, {0x28, 0x14, 0x1311}, {0x28, 0x16, 0x00C9},
- {0x28, 0x17, 0xA100}, {0x28, 0x1A, 0x0001}, {0x28, 0x1C, 0x0400},
- {0x29, 0x01, 0x0300}, {0x29, 0x02, 0x1017}, {0x29, 0x03, 0xFFDF},
- {0x29, 0x05, 0x7F7C}, {0x29, 0x07, 0x8100}, {0x29, 0x08, 0x0001},
- {0x29, 0x09, 0xFFD4}, {0x29, 0x0A, 0x7C2F}, {0x29, 0x0E, 0x003F},
- {0x29, 0x0F, 0x0121}, {0x29, 0x10, 0x0020}, {0x29, 0x11, 0x8840},
- /* 10G */
- {0x06, 0x0D, 0x0F00}, {0x06, 0x00, 0x0000}, {0x06, 0x01, 0xC800},
- {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010},
- {0x21, 0x07, 0xF09F}, {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009},
- {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008}, {0x2E, 0x00, 0xA668},
- {0x2E, 0x02, 0xD020}, {0x2E, 0x06, 0xC000}, {0x2E, 0x0B, 0x1892},
- {0x2E, 0x0F, 0xFFDF}, {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0044},
- {0x2E, 0x13, 0x027F}, {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100},
- {0x2E, 0x1A, 0x0001}, {0x2E, 0x1C, 0x0400}, {0x2F, 0x01, 0x0300},
- {0x2F, 0x02, 0x1217}, {0x2F, 0x03, 0xFFDF}, {0x2F, 0x05, 0x7F7C},
- {0x2F, 0x07, 0x80C4}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4},
- {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121},
- {0x2F, 0x10, 0x0020}, {0x2F, 0x11, 0x8840}, {0x2F, 0x14, 0xE008},
- {0x2B, 0x13, 0x0050}, {0x2B, 0x18, 0x8E88}, {0x2B, 0x19, 0x4902},
- {0x2B, 0x1D, 0x2501}, {0x2D, 0x13, 0x0050}, {0x2D, 0x17, 0x4109},
- {0x2D, 0x18, 0x8E88}, {0x2D, 0x19, 0x4902}, {0x2D, 0x1C, 0x1109},
- {0x2D, 0x1D, 0x2641}, {0x2F, 0x13, 0x0050}, {0x2F, 0x18, 0x8E88},
- {0x2F, 0x19, 0x4902}, {0x2F, 0x1D, 0x76E1},
-};
-
-sds_config rtl9300_a_sds_10gr_lane1[] =
-{
- /* 1G */
- {0x00, 0x0E, 0x3053}, {0x01, 0x14, 0x0100}, {0x21, 0x03, 0x8206},
- {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F}, {0x21, 0x0A, 0x0003},
- {0x21, 0x0B, 0x0005}, {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009},
- {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008}, {0x24, 0x00, 0x0668},
- {0x24, 0x02, 0xD020}, {0x24, 0x06, 0xC000}, {0x24, 0x0B, 0x1892},
- {0x24, 0x0F, 0xFFDF}, {0x24, 0x12, 0x03C4}, {0x24, 0x13, 0x027F},
- {0x24, 0x14, 0x1311}, {0x24, 0x16, 0x00C9}, {0x24, 0x17, 0xA100},
- {0x24, 0x1A, 0x0001}, {0x24, 0x1C, 0x0400}, {0x25, 0x00, 0x820F},
- {0x25, 0x01, 0x0300}, {0x25, 0x02, 0x1017}, {0x25, 0x03, 0xFFDF},
- {0x25, 0x05, 0x7F7C}, {0x25, 0x07, 0x8100}, {0x25, 0x08, 0x0001},
- {0x25, 0x09, 0xFFD4}, {0x25, 0x0A, 0x7C2F}, {0x25, 0x0E, 0x003F},
- {0x25, 0x0F, 0x0121}, {0x25, 0x10, 0x0020}, {0x25, 0x11, 0x8840},
- {0x2B, 0x13, 0x3D87}, {0x2B, 0x14, 0x3108}, {0x2D, 0x13, 0x3C87},
- {0x2D, 0x14, 0x1808},
- /* 3.125G */
- {0x28, 0x00, 0x0668}, {0x28, 0x02, 0xD020}, {0x28, 0x06, 0xC000},
- {0x28, 0x0B, 0x1892}, {0x28, 0x0F, 0xFFDF}, {0x28, 0x12, 0x01C4},
- {0x28, 0x13, 0x027F}, {0x28, 0x14, 0x1311}, {0x28, 0x16, 0x00C9},
- {0x28, 0x17, 0xA100}, {0x28, 0x1A, 0x0001}, {0x28, 0x1C, 0x0400},
- {0x29, 0x00, 0x820F}, {0x29, 0x01, 0x0300}, {0x29, 0x02, 0x1017},
- {0x29, 0x03, 0xFFDF}, {0x29, 0x05, 0x7F7C}, {0x29, 0x07, 0x8100},
- {0x29, 0x08, 0x0001}, {0x29, 0x0A, 0x7C2F}, {0x29, 0x0E, 0x003F},
- {0x29, 0x0F, 0x0121}, {0x29, 0x10, 0x0020}, {0x29, 0x11, 0x8840},
- /* 10G */
- {0x06, 0x0D, 0x0F00}, {0x06, 0x00, 0x0000}, {0x06, 0x01, 0xC800},
- {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010},
- {0x21, 0x07, 0xF09F}, {0x21, 0x0A, 0x0003}, {0x21, 0x0B, 0x0005},
- {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, {0x21, 0x0E, 0x0000},
- {0x21, 0x0F, 0x0008}, {0x2E, 0x00, 0xA668}, {0x2E, 0x02, 0xD020},
- {0x2E, 0x06, 0xC000}, {0x2E, 0x0B, 0x1892}, {0x2E, 0x0F, 0xFFDF},
- {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0044}, {0x2E, 0x13, 0x027F},
- {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100}, {0x2E, 0x1A, 0x0001},
- {0x2E, 0x1C, 0x0400}, {0x2F, 0x00, 0x820F}, {0x2F, 0x01, 0x0300},
- {0x2F, 0x02, 0x1217}, {0x2F, 0x03, 0xFFDF}, {0x2F, 0x05, 0x7F7C},
- {0x2F, 0x07, 0x80C4}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4},
- {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121},
- {0x2F, 0x10, 0x0020}, {0x2F, 0x11, 0x8840}, {0x2B, 0x13, 0x3D87},
- {0x2B, 0x14, 0x3108}, {0x2D, 0x13, 0x3C87}, {0x2D, 0x14, 0x1808},
-};
-
-static void rtl9300_serdes_patch(int sds_num)
-{
- if (sds_num % 2) {
- for (int i = 0; i < sizeof(rtl9300_a_sds_10gr_lane1) / sizeof(sds_config); ++i) {
- rtl930x_write_sds_phy(sds_num, rtl9300_a_sds_10gr_lane1[i].page,
- rtl9300_a_sds_10gr_lane1[i].reg,
- rtl9300_a_sds_10gr_lane1[i].data);
- }
- } else {
- for (int i = 0; i < sizeof(rtl9300_a_sds_10gr_lane0) / sizeof(sds_config); ++i) {
- rtl930x_write_sds_phy(sds_num, rtl9300_a_sds_10gr_lane0[i].page,
- rtl9300_a_sds_10gr_lane0[i].reg,
- rtl9300_a_sds_10gr_lane0[i].data);
- }
- }
-}
-
-int rtl9300_sds_cmu_band_get(int sds)
-{
- u32 page;
- u32 en;
- u32 cmu_band;
-
-/* page = rtl9300_sds_cmu_page_get(sds); */
- page = 0x25; /* 10GR and 1000BX */
- sds = (sds % 2) ? (sds - 1) : (sds);
-
- rtl9300_sds_field_w(sds, page, 0x1c, 15, 15, 1);
- rtl9300_sds_field_w(sds + 1, page, 0x1c, 15, 15, 1);
-
- en = rtl9300_sds_field_r(sds, page, 27, 1, 1);
- if(!en) { /* Auto mode */
- rtl930x_write_sds_phy(sds, 0x1f, 0x02, 31);
-
- cmu_band = rtl9300_sds_field_r(sds, 0x1f, 0x15, 5, 1);
- } else {
- cmu_band = rtl9300_sds_field_r(sds, page, 30, 4, 0);
- }
-
- return cmu_band;
-}
-
-void rtl9310_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int start_bit, u32 v)
-{
- int l = end_bit - start_bit + 1;
- u32 data = v;
-
- if (l < 32) {
- u32 mask = BIT(l) - 1;
-
- data = rtl930x_read_sds_phy(sds, page, reg);
- data &= ~(mask << start_bit);
- data |= (v & mask) << start_bit;
- }
-
- rtl931x_write_sds_phy(sds, page, reg, data);
-}
-
-u32 rtl9310_sds_field_r(int sds, u32 page, u32 reg, int end_bit, int start_bit)
-{
- int l = end_bit - start_bit + 1;
- u32 v = rtl931x_read_sds_phy(sds, page, reg);
-
- if (l >= 32)
- return v;
-
- return (v >> start_bit) & (BIT(l) - 1);
-}
-
-static void rtl931x_sds_rst(u32 sds)
-{
- u32 o, v, o_mode;
- int shift = ((sds & 0x3) << 3);
-
- /* TODO: We need to lock this! */
-
- o = sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
- v = o | BIT(sds);
- sw_w32(v, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
-
- o_mode = sw_r32(RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
- v = BIT(7) | 0x1F;
- sw_w32_mask(0xff << shift, v << shift, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
- sw_w32(o_mode, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
-
- sw_w32(o, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
-}
-
-static void rtl931x_symerr_clear(u32 sds, phy_interface_t mode)
-{
-
- switch (mode) {
- case PHY_INTERFACE_MODE_NA:
- break;
- case PHY_INTERFACE_MODE_XGMII:
- u32 xsg_sdsid_0, xsg_sdsid_1;
-
- if (sds < 2)
- xsg_sdsid_0 = sds;
- else
- xsg_sdsid_0 = (sds - 1) * 2;
- xsg_sdsid_1 = xsg_sdsid_0 + 1;
-
- for (int i = 0; i < 4; ++i) {
- rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 24, 2, 0, i);
- rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 3, 15, 8, 0x0);
- rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 2, 15, 0, 0x0);
- }
-
- for (int i = 0; i < 4; ++i) {
- rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 24, 2, 0, i);
- rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 3, 15, 8, 0x0);
- rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 2, 15, 0, 0x0);
- }
-
- rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 0, 15, 0, 0x0);
- rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 1, 15, 8, 0x0);
- rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0, 15, 0, 0x0);
- rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 1, 15, 8, 0x0);
- break;
- default:
- break;
- }
-
- return;
-}
-
-static u32 rtl931x_get_analog_sds(u32 sds)
-{
- u32 sds_map[] = { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23 };
-
- if (sds < 14)
- return sds_map[sds];
-
- return sds;
-}
-
-void rtl931x_sds_fiber_disable(u32 sds)
-{
- u32 v = 0x3F;
- u32 asds = rtl931x_get_analog_sds(sds);
-
- rtl9310_sds_field_w(asds, 0x1F, 0x9, 11, 6, v);
-}
-
-static void rtl931x_sds_fiber_mode_set(u32 sds, phy_interface_t mode)
-{
- u32 val, asds = rtl931x_get_analog_sds(sds);
-
- /* clear symbol error count before changing mode */
- rtl931x_symerr_clear(sds, mode);
-
- val = 0x9F;
- sw_w32(val, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
-
- switch (mode) {
- case PHY_INTERFACE_MODE_SGMII:
- val = 0x5;
- break;
-
- case PHY_INTERFACE_MODE_1000BASEX:
- /* serdes mode FIBER1G */
- val = 0x9;
- break;
-
- case PHY_INTERFACE_MODE_10GBASER:
- case PHY_INTERFACE_MODE_10GKR:
- val = 0x35;
- break;
-/* case MII_10GR1000BX_AUTO:
- val = 0x39;
- break; */
-
-
- case PHY_INTERFACE_MODE_USXGMII:
- val = 0x1B;
- break;
- default:
- val = 0x25;
- }
-
- pr_info("%s writing analog SerDes Mode value %02x\n", __func__, val);
- rtl9310_sds_field_w(asds, 0x1F, 0x9, 11, 6, val);
-
- return;
-}
-
-static int rtl931x_sds_cmu_page_get(phy_interface_t mode)
-{
- switch (mode) {
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_1000BASEX: /* MII_1000BX_FIBER / 100BX_FIBER / 1000BX100BX_AUTO */
- return 0x24;
- case PHY_INTERFACE_MODE_HSGMII:
- case PHY_INTERFACE_MODE_2500BASEX: /* MII_2500Base_X: */
- return 0x28;
-/* case MII_HISGMII_5G: */
-/* return 0x2a; */
- case PHY_INTERFACE_MODE_QSGMII:
- return 0x2a; /* Code also has 0x34 */
- case PHY_INTERFACE_MODE_XAUI: /* MII_RXAUI_LITE: */
- return 0x2c;
- case PHY_INTERFACE_MODE_XGMII: /* MII_XSGMII */
- case PHY_INTERFACE_MODE_10GKR:
- case PHY_INTERFACE_MODE_10GBASER: /* MII_10GR */
- return 0x2e;
- default:
- return -1;
- }
-
- return -1;
-}
-
-static void rtl931x_cmu_type_set(u32 asds, phy_interface_t mode, int chiptype)
-{
- int cmu_type = 0; /* Clock Management Unit */
- u32 cmu_page = 0;
- u32 frc_cmu_spd;
- u32 evenSds;
- u32 lane, frc_lc_mode_bitnum, frc_lc_mode_val_bitnum;
-
- switch (mode) {
- case PHY_INTERFACE_MODE_NA:
- case PHY_INTERFACE_MODE_10GKR:
- case PHY_INTERFACE_MODE_XGMII:
- case PHY_INTERFACE_MODE_10GBASER:
- case PHY_INTERFACE_MODE_USXGMII:
- return;
-
-/* case MII_10GR1000BX_AUTO:
- if (chiptype)
- rtl9310_sds_field_w(asds, 0x24, 0xd, 14, 14, 0);
- return; */
-
- case PHY_INTERFACE_MODE_QSGMII:
- cmu_type = 1;
- frc_cmu_spd = 0;
- break;
-
- case PHY_INTERFACE_MODE_HSGMII:
- cmu_type = 1;
- frc_cmu_spd = 1;
- break;
-
- case PHY_INTERFACE_MODE_1000BASEX:
- cmu_type = 1;
- frc_cmu_spd = 0;
- break;
-
-/* case MII_1000BX100BX_AUTO:
- cmu_type = 1;
- frc_cmu_spd = 0;
- break; */
-
- case PHY_INTERFACE_MODE_SGMII:
- cmu_type = 1;
- frc_cmu_spd = 0;
- break;
-
- case PHY_INTERFACE_MODE_2500BASEX:
- cmu_type = 1;
- frc_cmu_spd = 1;
- break;
-
- default:
- pr_info("SerDes %d mode is invalid\n", asds);
- return;
- }
-
- if (cmu_type == 1)
- cmu_page = rtl931x_sds_cmu_page_get(mode);
-
- lane = asds % 2;
-
- if (!lane) {
- frc_lc_mode_bitnum = 4;
- frc_lc_mode_val_bitnum = 5;
- } else {
- frc_lc_mode_bitnum = 6;
- frc_lc_mode_val_bitnum = 7;
- }
-
- evenSds = asds - lane;
-
- pr_info("%s: cmu_type %0d cmu_page %x frc_cmu_spd %d lane %d asds %d\n",
- __func__, cmu_type, cmu_page, frc_cmu_spd, lane, asds);
-
- if (cmu_type == 1) {
- pr_info("%s A CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
- rtl9310_sds_field_w(asds, cmu_page, 0x7, 15, 15, 0);
- pr_info("%s B CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
- if (chiptype) {
- rtl9310_sds_field_w(asds, cmu_page, 0xd, 14, 14, 0);
- }
-
- rtl9310_sds_field_w(evenSds, 0x20, 0x12, 3, 2, 0x3);
- rtl9310_sds_field_w(evenSds, 0x20, 0x12, frc_lc_mode_bitnum, frc_lc_mode_bitnum, 1);
- rtl9310_sds_field_w(evenSds, 0x20, 0x12, frc_lc_mode_val_bitnum, frc_lc_mode_val_bitnum, 0);
- rtl9310_sds_field_w(evenSds, 0x20, 0x12, 12, 12, 1);
- rtl9310_sds_field_w(evenSds, 0x20, 0x12, 15, 13, frc_cmu_spd);
- }
-
- pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
- return;
-}
-
-static void rtl931x_sds_rx_rst(u32 sds)
-{
- u32 asds = rtl931x_get_analog_sds(sds);
-
- if (sds < 2)
- return;
-
- rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x2740);
- rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0x0);
- rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x2010);
- rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc10);
-
- rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x27c0);
- rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0xc000);
- rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x6010);
- rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc30);
-
- mdelay(50);
-}
-
-// Currently not used
-// static void rtl931x_sds_disable(u32 sds)
-// {
-// u32 v = 0x1f;
-
-// v |= BIT(7);
-// sw_w32(v, RTL931X_SERDES_MODE_CTRL + (sds >> 2) * 4);
-// }
-
-static void rtl931x_sds_mii_mode_set(u32 sds, phy_interface_t mode)
-{
- u32 val;
-
- switch (mode) {
- case PHY_INTERFACE_MODE_QSGMII:
- val = 0x6;
- break;
- case PHY_INTERFACE_MODE_XGMII:
- val = 0x10; /* serdes mode XSGMII */
- break;
- case PHY_INTERFACE_MODE_USXGMII:
- case PHY_INTERFACE_MODE_2500BASEX:
- val = 0xD;
- break;
- case PHY_INTERFACE_MODE_HSGMII:
- val = 0x12;
- break;
- case PHY_INTERFACE_MODE_SGMII:
- val = 0x2;
- break;
- default:
- return;
- }
-
- val |= (1 << 7);
-
- sw_w32(val, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
-}
-
-static sds_config sds_config_10p3125g_type1[] = {
- { 0x2E, 0x00, 0x0107 }, { 0x2E, 0x01, 0x01A3 }, { 0x2E, 0x02, 0x6A24 },
- { 0x2E, 0x03, 0xD10D }, { 0x2E, 0x04, 0x8000 }, { 0x2E, 0x05, 0xA17E },
- { 0x2E, 0x06, 0xE31D }, { 0x2E, 0x07, 0x800E }, { 0x2E, 0x08, 0x0294 },
- { 0x2E, 0x09, 0x0CE4 }, { 0x2E, 0x0A, 0x7FC8 }, { 0x2E, 0x0B, 0xE0E7 },
- { 0x2E, 0x0C, 0x0200 }, { 0x2E, 0x0D, 0xDF80 }, { 0x2E, 0x0E, 0x0000 },
- { 0x2E, 0x0F, 0x1FC2 }, { 0x2E, 0x10, 0x0C3F }, { 0x2E, 0x11, 0x0000 },
- { 0x2E, 0x12, 0x27C0 }, { 0x2E, 0x13, 0x7E1D }, { 0x2E, 0x14, 0x1300 },
- { 0x2E, 0x15, 0x003F }, { 0x2E, 0x16, 0xBE7F }, { 0x2E, 0x17, 0x0090 },
- { 0x2E, 0x18, 0x0000 }, { 0x2E, 0x19, 0x4000 }, { 0x2E, 0x1A, 0x0000 },
- { 0x2E, 0x1B, 0x8000 }, { 0x2E, 0x1C, 0x011F }, { 0x2E, 0x1D, 0x0000 },
- { 0x2E, 0x1E, 0xC8FF }, { 0x2E, 0x1F, 0x0000 }, { 0x2F, 0x00, 0xC000 },
- { 0x2F, 0x01, 0xF000 }, { 0x2F, 0x02, 0x6010 }, { 0x2F, 0x12, 0x0EE7 },
- { 0x2F, 0x13, 0x0000 }
-};
-
-static sds_config sds_config_10p3125g_cmu_type1[] = {
- { 0x2F, 0x03, 0x4210 }, { 0x2F, 0x04, 0x0000 }, { 0x2F, 0x05, 0x0019 },
- { 0x2F, 0x06, 0x18A6 }, { 0x2F, 0x07, 0x2990 }, { 0x2F, 0x08, 0xFFF4 },
- { 0x2F, 0x09, 0x1F08 }, { 0x2F, 0x0A, 0x0000 }, { 0x2F, 0x0B, 0x8000 },
- { 0x2F, 0x0C, 0x4224 }, { 0x2F, 0x0D, 0x0000 }, { 0x2F, 0x0E, 0x0000 },
- { 0x2F, 0x0F, 0xA470 }, { 0x2F, 0x10, 0x8000 }, { 0x2F, 0x11, 0x037B }
-};
-
-void rtl931x_sds_init(u32 sds, phy_interface_t mode)
-{
- u32 board_sds_tx_type1[] = {
- 0x01c3, 0x01c3, 0x01c3, 0x01a3, 0x01a3, 0x01a3,
- 0x0143, 0x0143, 0x0143, 0x0143, 0x0163, 0x0163,
- };
- u32 board_sds_tx[] = {
- 0x1a00, 0x1a00, 0x0200, 0x0200, 0x0200, 0x0200,
- 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01e3, 0x01e3
- };
- u32 board_sds_tx2[] = {
- 0x0dc0, 0x01c0, 0x0200, 0x0180, 0x0160, 0x0123,
- 0x0123, 0x0163, 0x01a3, 0x01a0, 0x01c3, 0x09c3,
- };
- u32 asds, dSds, ori, model_info, val;
- int chiptype = 0;
-
- asds = rtl931x_get_analog_sds(sds);
-
- if (sds > 13)
- return;
-
- pr_info("%s: set sds %d to mode %d\n", __func__, sds, mode);
- val = rtl9310_sds_field_r(asds, 0x1F, 0x9, 11, 6);
-
- pr_info("%s: fibermode %08X stored mode 0x%x analog SDS %d", __func__,
- rtl931x_read_sds_phy(asds, 0x1f, 0x9), val, asds);
- pr_info("%s: SGMII mode %08X in 0x24 0x9 analog SDS %d", __func__,
- rtl931x_read_sds_phy(asds, 0x24, 0x9), asds);
- pr_info("%s: CMU mode %08X stored even SDS %d", __func__,
- rtl931x_read_sds_phy(asds & ~1, 0x20, 0x12), asds & ~1);
- pr_info("%s: serdes_mode_ctrl %08X", __func__, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
- pr_info("%s CMU page 0x24 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x24, 0x7));
- pr_info("%s CMU page 0x26 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x26, 0x7));
- pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
- pr_info("%s XSG page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds, 0x0, 0xe));
- pr_info("%s XSG2 page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds + 1, 0x0, 0xe));
-
- model_info = sw_r32(RTL93XX_MODEL_NAME_INFO);
- if ((model_info >> 4) & 0x1) {
- pr_info("detected chiptype 1\n");
- chiptype = 1;
- } else {
- pr_info("detected chiptype 0\n");
- }
-
- if (sds < 2)
- dSds = sds;
- else
- dSds = (sds - 1) * 2;
-
- pr_info("%s: 2.5gbit %08X dsds %d", __func__,
- rtl931x_read_sds_phy(dSds, 0x1, 0x14), dSds);
-
- pr_info("%s: RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR 0x%08X\n", __func__, sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR));
- ori = sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
- val = ori | (1 << sds);
- sw_w32(val, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
-
- switch (mode) {
- case PHY_INTERFACE_MODE_NA:
- break;
-
- case PHY_INTERFACE_MODE_XGMII: /* MII_XSGMII */
-
- if (chiptype) {
- u32 xsg_sdsid_1;
- xsg_sdsid_1 = dSds + 1;
- /* fifo inv clk */
- rtl9310_sds_field_w(dSds, 0x1, 0x1, 7, 4, 0xf);
- rtl9310_sds_field_w(dSds, 0x1, 0x1, 3, 0, 0xf);
-
- rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0x1, 7, 4, 0xf);
- rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0x1, 3, 0, 0xf);
-
- }
-
- rtl9310_sds_field_w(dSds, 0x0, 0xE, 12, 12, 1);
- rtl9310_sds_field_w(dSds + 1, 0x0, 0xE, 12, 12, 1);
- break;
-
- case PHY_INTERFACE_MODE_USXGMII: /* MII_USXGMII_10GSXGMII/10GDXGMII/10GQXGMII: */
- u32 op_code = 0x6003;
- u32 evenSds;
-
- if (chiptype) {
- rtl9310_sds_field_w(asds, 0x6, 0x2, 12, 12, 1);
-
- for (int i = 0; i < sizeof(sds_config_10p3125g_type1) / sizeof(sds_config); ++i) {
- rtl931x_write_sds_phy(asds, sds_config_10p3125g_type1[i].page - 0x4, sds_config_10p3125g_type1[i].reg, sds_config_10p3125g_type1[i].data);
- }
-
- evenSds = asds - (asds % 2);
-
- for (int i = 0; i < sizeof(sds_config_10p3125g_cmu_type1) / sizeof(sds_config); ++i) {
- rtl931x_write_sds_phy(evenSds,
- sds_config_10p3125g_cmu_type1[i].page - 0x4, sds_config_10p3125g_cmu_type1[i].reg, sds_config_10p3125g_cmu_type1[i].data);
- }
-
- rtl9310_sds_field_w(asds, 0x6, 0x2, 12, 12, 0);
- } else {
-
- rtl9310_sds_field_w(asds, 0x2e, 0xd, 6, 0, 0x0);
- rtl9310_sds_field_w(asds, 0x2e, 0xd, 7, 7, 0x1);
-
- rtl9310_sds_field_w(asds, 0x2e, 0x1c, 5, 0, 0x1E);
- rtl9310_sds_field_w(asds, 0x2e, 0x1d, 11, 0, 0x00);
- rtl9310_sds_field_w(asds, 0x2e, 0x1f, 11, 0, 0x00);
- rtl9310_sds_field_w(asds, 0x2f, 0x0, 11, 0, 0x00);
- rtl9310_sds_field_w(asds, 0x2f, 0x1, 11, 0, 0x00);
-
- rtl9310_sds_field_w(asds, 0x2e, 0xf, 12, 6, 0x7F);
- rtl931x_write_sds_phy(asds, 0x2f, 0x12, 0xaaa);
-
- rtl931x_sds_rx_rst(sds);
-
- rtl931x_write_sds_phy(asds, 0x7, 0x10, op_code);
- rtl931x_write_sds_phy(asds, 0x6, 0x1d, 0x0480);
- rtl931x_write_sds_phy(asds, 0x6, 0xe, 0x0400);
- }
- break;
-
- case PHY_INTERFACE_MODE_10GBASER: /* MII_10GR / MII_10GR1000BX_AUTO: */
- /* configure 10GR fiber mode=1 */
- rtl9310_sds_field_w(asds, 0x1f, 0xb, 1, 1, 1);
-
- /* init fiber_1g */
- rtl9310_sds_field_w(dSds, 0x3, 0x13, 15, 14, 0);
-
- rtl9310_sds_field_w(dSds, 0x2, 0x0, 12, 12, 1);
- rtl9310_sds_field_w(dSds, 0x2, 0x0, 6, 6, 1);
- rtl9310_sds_field_w(dSds, 0x2, 0x0, 13, 13, 0);
-
- /* init auto */
- rtl9310_sds_field_w(asds, 0x1f, 13, 15, 0, 0x109e);
- rtl9310_sds_field_w(asds, 0x1f, 0x6, 14, 10, 0x8);
- rtl9310_sds_field_w(asds, 0x1f, 0x7, 10, 4, 0x7f);
- break;
-
- case PHY_INTERFACE_MODE_HSGMII:
- rtl9310_sds_field_w(dSds, 0x1, 0x14, 8, 8, 1);
- break;
-
- case PHY_INTERFACE_MODE_1000BASEX: /* MII_1000BX_FIBER */
- rtl9310_sds_field_w(dSds, 0x3, 0x13, 15, 14, 0);
-
- rtl9310_sds_field_w(dSds, 0x2, 0x0, 12, 12, 1);
- rtl9310_sds_field_w(dSds, 0x2, 0x0, 6, 6, 1);
- rtl9310_sds_field_w(dSds, 0x2, 0x0, 13, 13, 0);
- break;
-
- case PHY_INTERFACE_MODE_SGMII:
- rtl9310_sds_field_w(asds, 0x24, 0x9, 15, 15, 0);
- break;
-
- case PHY_INTERFACE_MODE_2500BASEX:
- rtl9310_sds_field_w(dSds, 0x1, 0x14, 8, 8, 1);
- break;
-
- case PHY_INTERFACE_MODE_QSGMII:
- default:
- pr_info("%s: PHY mode %s not supported by SerDes %d\n",
- __func__, phy_modes(mode), sds);
- return;
- }
-
- rtl931x_cmu_type_set(asds, mode, chiptype);
-
- if (sds >= 2 && sds <= 13) {
- if (chiptype)
- rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx_type1[sds - 2]);
- else {
- val = 0xa0000;
- sw_w32(val, RTL931X_CHIP_INFO_ADDR);
- val = sw_r32(RTL931X_CHIP_INFO_ADDR);
- if (val & BIT(28)) /* consider 9311 etc. RTL9313_CHIP_ID == HWP_CHIP_ID(unit)) */
- {
- rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx2[sds - 2]);
- } else {
- rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx[sds - 2]);
- }
- val = 0;
- sw_w32(val, RTL931X_CHIP_INFO_ADDR);
- }
- }
-
- val = ori & ~BIT(sds);
- sw_w32(val, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
- pr_debug("%s: RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR 0x%08X\n", __func__, sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR));
-
- if (mode == PHY_INTERFACE_MODE_XGMII ||
- mode == PHY_INTERFACE_MODE_QSGMII ||
- mode == PHY_INTERFACE_MODE_HSGMII ||
- mode == PHY_INTERFACE_MODE_SGMII ||
- mode == PHY_INTERFACE_MODE_USXGMII) {
- if (mode == PHY_INTERFACE_MODE_XGMII)
- rtl931x_sds_mii_mode_set(sds, mode);
- else
- rtl931x_sds_fiber_mode_set(sds, mode);
- }
-}
-
-int rtl931x_sds_cmu_band_set(int sds, bool enable, u32 band, phy_interface_t mode)
-{
- u32 asds;
- int page = rtl931x_sds_cmu_page_get(mode);
-
- sds -= (sds % 2);
- sds = sds & ~1;
- asds = rtl931x_get_analog_sds(sds);
- page += 1;
-
- if (enable) {
- rtl9310_sds_field_w(asds, page, 0x7, 13, 13, 0);
- rtl9310_sds_field_w(asds, page, 0x7, 11, 11, 0);
- } else {
- rtl9310_sds_field_w(asds, page, 0x7, 13, 13, 0);
- rtl9310_sds_field_w(asds, page, 0x7, 11, 11, 0);
- }
-
- rtl9310_sds_field_w(asds, page, 0x7, 4, 0, band);
-
- rtl931x_sds_rst(sds);
-
- return 0;
-}
-
-int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode)
-{
- int page = rtl931x_sds_cmu_page_get(mode);
- u32 asds, band;
-
- sds -= (sds % 2);
- asds = rtl931x_get_analog_sds(sds);
- page += 1;
- rtl931x_write_sds_phy(asds, 0x1f, 0x02, 73);
-
- rtl9310_sds_field_w(asds, page, 0x5, 15, 15, 1);
- band = rtl9310_sds_field_r(asds, 0x1f, 0x15, 8, 3);
- pr_info("%s band is: %d\n", __func__, band);
-
- return band;
-}
-
-
-int rtl931x_link_sts_get(u32 sds)
-{
- u32 sts, sts1, latch_sts, latch_sts1;
- if (0){
- u32 xsg_sdsid_0, xsg_sdsid_1;
-
- xsg_sdsid_0 = sds < 2 ? sds : (sds - 1) * 2;
- xsg_sdsid_1 = xsg_sdsid_0 + 1;
-
- sts = rtl9310_sds_field_r(xsg_sdsid_0, 0x1, 29, 8, 0);
- sts1 = rtl9310_sds_field_r(xsg_sdsid_1, 0x1, 29, 8, 0);
- latch_sts = rtl9310_sds_field_r(xsg_sdsid_0, 0x1, 30, 8, 0);
- latch_sts1 = rtl9310_sds_field_r(xsg_sdsid_1, 0x1, 30, 8, 0);
- } else {
- u32 asds, dsds;
-
- asds = rtl931x_get_analog_sds(sds);
- sts = rtl9310_sds_field_r(asds, 0x5, 0, 12, 12);
- latch_sts = rtl9310_sds_field_r(asds, 0x4, 1, 2, 2);
-
- dsds = sds < 2 ? sds : (sds - 1) * 2;
- latch_sts1 = rtl9310_sds_field_r(dsds, 0x2, 1, 2, 2);
- sts1 = rtl9310_sds_field_r(dsds, 0x2, 1, 2, 2);
- }
-
- pr_info("%s: serdes %d sts %d, sts1 %d, latch_sts %d, latch_sts1 %d\n", __func__,
- sds, sts, sts1, latch_sts, latch_sts1);
-
- return sts1;
-}
-
-static int rtl8214fc_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-{
- struct phy_device *phydev = upstream;
-
- rtl8214fc_media_set(phydev, true);
-
- return 0;
-}
-
-static void rtl8214fc_sfp_remove(void *upstream)
-{
- struct phy_device *phydev = upstream;
-
- rtl8214fc_media_set(phydev, false);
-}
-
-static const struct sfp_upstream_ops rtl8214fc_sfp_ops = {
- .attach = phy_sfp_attach,
- .detach = phy_sfp_detach,
- .module_insert = rtl8214fc_sfp_insert,
- .module_remove = rtl8214fc_sfp_remove,
-};
-
-static int rtl8214fc_phy_probe(struct phy_device *phydev)
-{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
- int ret = 0;
-
- /* 839x has internal SerDes */
- if (soc_info.id == 0x8393)
- return -ENODEV;
-
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8214FC";
- /* Configuration must be done while patching still possible */
- ret = rtl8380_configure_rtl8214fc(phydev);
- if (ret)
- return ret;
- }
-
- return phy_sfp_probe(phydev, &rtl8214fc_sfp_ops);
-}
-
-static int rtl8214c_phy_probe(struct phy_device *phydev)
-{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
-
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8214C";
- /* Configuration must be done whil patching still possible */
- return rtl8380_configure_rtl8214c(phydev);
- }
-
- return 0;
-}
-
-static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
-{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
-
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8218B (external)";
- if (soc_info.family == RTL8380_FAMILY_ID) {
- /* Configuration must be done while patching still possible */
- return rtl8380_configure_ext_rtl8218b(phydev);
- }
- }
-
- return 0;
-}
-
-static int rtl8218b_int_phy_probe(struct phy_device *phydev)
-{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
-
- if (soc_info.family != RTL8380_FAMILY_ID)
- return -ENODEV;
- if (addr >= 24)
- return -ENODEV;
-
- pr_debug("%s: id: %d\n", __func__, addr);
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8218B (internal)";
- /* Configuration must be done while patching still possible */
- return rtl8380_configure_int_rtl8218b(phydev);
- }
-
- return 0;
-}
-
-static int rtl8218d_phy_probe(struct phy_device *phydev)
-{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
-
- pr_debug("%s: id: %d\n", __func__, addr);
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- /* All base addresses of the PHYs start at multiples of 8 */
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8218D";
- /* Configuration must be done while patching still possible */
-/* TODO: return configure_rtl8218d(phydev); */
- }
-
- return 0;
-}
-
-static int rtl838x_serdes_probe(struct phy_device *phydev)
-{
- int addr = phydev->mdio.addr;
-
- if (soc_info.family != RTL8380_FAMILY_ID)
- return -ENODEV;
- if (addr < 24)
- return -ENODEV;
-
- /* On the RTL8380M, PHYs 24-27 connect to the internal SerDes */
- if (soc_info.id == 0x8380) {
- if (addr == 24)
- return rtl8380_configure_serdes(phydev);
- return 0;
- }
-
- return -ENODEV;
-}
-
-static int rtl8393_serdes_probe(struct phy_device *phydev)
-{
- int addr = phydev->mdio.addr;
-
- pr_info("%s: id: %d\n", __func__, addr);
- if (soc_info.family != RTL8390_FAMILY_ID)
- return -ENODEV;
-
- if (addr < 24)
- return -ENODEV;
-
- return rtl8390_configure_serdes(phydev);
-}
-
-static int rtl8390_serdes_probe(struct phy_device *phydev)
-{
- int addr = phydev->mdio.addr;
-
- if (soc_info.family != RTL8390_FAMILY_ID)
- return -ENODEV;
-
- if (addr < 24)
- return -ENODEV;
-
- return rtl8390_configure_generic(phydev);
-}
-
-static int rtl9300_serdes_probe(struct phy_device *phydev)
-{
- if (soc_info.family != RTL9300_FAMILY_ID)
- return -ENODEV;
-
- phydev_info(phydev, "Detected internal RTL9300 Serdes\n");
-
- return 0;
-}
-
-static struct phy_driver rtl83xx_phy_driver[] = {
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8214C),
- .name = "Realtek RTL8214C",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .match_phy_device = rtl8214c_match_phy_device,
- .probe = rtl8214c_phy_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC),
- .name = "Realtek RTL8214FC",
- .features = PHY_GBIT_FIBRE_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .match_phy_device = rtl8214fc_match_phy_device,
- .probe = rtl8214fc_phy_probe,
- .suspend = rtl8214fc_suspend,
- .resume = rtl8214fc_resume,
- .set_loopback = genphy_loopback,
- .set_port = rtl8214fc_set_port,
- .get_port = rtl8214fc_get_port,
- .set_eee = rtl8214fc_set_eee,
- .get_eee = rtl8214fc_get_eee,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_E),
- .name = "Realtek RTL8218B (external)",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .match_phy_device = rtl8218b_ext_match_phy_device,
- .probe = rtl8218b_ext_phy_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .set_eee = rtl8218b_set_eee,
- .get_eee = rtl8218b_get_eee,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8218D),
- .name = "REALTEK RTL8218D",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .probe = rtl8218d_phy_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .set_eee = rtl8218d_set_eee,
- .get_eee = rtl8218d_get_eee,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8221B),
- .name = "REALTEK RTL8221B",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .read_page = rtl8226_read_page,
- .write_page = rtl8226_write_page,
- .read_status = rtl8226_read_status,
- .config_aneg = rtl8226_config_aneg,
- .set_eee = rtl8226_set_eee,
- .get_eee = rtl8226_get_eee,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8226),
- .name = "REALTEK RTL8226",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .read_page = rtl8226_read_page,
- .write_page = rtl8226_write_page,
- .read_status = rtl8226_read_status,
- .config_aneg = rtl8226_config_aneg,
- .set_eee = rtl8226_set_eee,
- .get_eee = rtl8226_get_eee,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I),
- .name = "Realtek RTL8218B (internal)",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .probe = rtl8218b_int_phy_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .set_eee = rtl8218b_set_eee,
- .get_eee = rtl8218b_get_eee,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I),
- .name = "Realtek RTL8380 SERDES",
- .features = PHY_GBIT_FIBRE_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .probe = rtl838x_serdes_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .read_status = rtl8380_read_status,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8393_I),
- .name = "Realtek RTL8393 SERDES",
- .features = PHY_GBIT_FIBRE_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .probe = rtl8393_serdes_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .read_status = rtl8393_read_status,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8390_GENERIC),
- .name = "Realtek RTL8390 Generic",
- .features = PHY_GBIT_FIBRE_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .probe = rtl8390_serdes_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- },
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL9300_I),
- .name = "REALTEK RTL9300 SERDES",
- .features = PHY_GBIT_FIBRE_FEATURES,
- .flags = PHY_HAS_REALTEK_PAGES,
- .probe = rtl9300_serdes_probe,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .set_loopback = genphy_loopback,
- .read_status = rtl9300_read_status,
- },
-};
-
-module_phy_driver(rtl83xx_phy_driver);
-
-static struct mdio_device_id __maybe_unused rtl83xx_tbl[] = {
- { PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC) },
- { }
-};
-
-MODULE_DEVICE_TABLE(mdio, rtl83xx_tbl);
-
-MODULE_AUTHOR("B. Koblitz");
-MODULE_DESCRIPTION("RTL83xx PHY driver");
-MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/files-5.15/Documentation/devicetree/bindings/realtek,otto-timer.yaml b/target/linux/realtek/files-6.6/Documentation/devicetree/bindings/realtek,otto-timer.yaml
index 40e834e377..40e834e377 100644
--- a/target/linux/realtek/files-5.15/Documentation/devicetree/bindings/realtek,otto-timer.yaml
+++ b/target/linux/realtek/files-6.6/Documentation/devicetree/bindings/realtek,otto-timer.yaml
diff --git a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/ioremap.h b/target/linux/realtek/files-6.6/arch/mips/include/asm/mach-rtl838x/ioremap.h
index c49a095792..c49a095792 100644
--- a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/ioremap.h
+++ b/target/linux/realtek/files-6.6/arch/mips/include/asm/mach-rtl838x/ioremap.h
diff --git a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h b/target/linux/realtek/files-6.6/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h
index 8ea580f3d1..8ea580f3d1 100644
--- a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h
+++ b/target/linux/realtek/files-6.6/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h
diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Makefile b/target/linux/realtek/files-6.6/arch/mips/rtl838x/Makefile
index a9d1666d46..a9d1666d46 100644
--- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Makefile
+++ b/target/linux/realtek/files-6.6/arch/mips/rtl838x/Makefile
diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Platform b/target/linux/realtek/files-6.6/arch/mips/rtl838x/Platform
index 98f18cac1b..98f18cac1b 100644
--- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Platform
+++ b/target/linux/realtek/files-6.6/arch/mips/rtl838x/Platform
diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/prom.c b/target/linux/realtek/files-6.6/arch/mips/rtl838x/prom.c
index 0c98af9548..0c98af9548 100644
--- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/prom.c
+++ b/target/linux/realtek/files-6.6/arch/mips/rtl838x/prom.c
diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/setup.c b/target/linux/realtek/files-6.6/arch/mips/rtl838x/setup.c
index 546b2fa2f8..546b2fa2f8 100644
--- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/setup.c
+++ b/target/linux/realtek/files-6.6/arch/mips/rtl838x/setup.c
diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/Kconfig b/target/linux/realtek/files-6.6/drivers/clk/realtek/Kconfig
index 4cf3cd9633..4cf3cd9633 100644
--- a/target/linux/realtek/files-5.15/drivers/clk/realtek/Kconfig
+++ b/target/linux/realtek/files-6.6/drivers/clk/realtek/Kconfig
diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/Makefile b/target/linux/realtek/files-6.6/drivers/clk/realtek/Makefile
index 7bc4ed910c..7bc4ed910c 100644
--- a/target/linux/realtek/files-5.15/drivers/clk/realtek/Makefile
+++ b/target/linux/realtek/files-6.6/drivers/clk/realtek/Makefile
diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl838x-sram.S b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl838x-sram.S
index 2431723133..2431723133 100644
--- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl838x-sram.S
+++ b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl838x-sram.S
diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl839x-sram.S b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl839x-sram.S
index eb44cd90f1..eb44cd90f1 100644
--- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl839x-sram.S
+++ b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl839x-sram.S
diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.c b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl83xx.c
index 0cca32ab34..0cca32ab34 100644
--- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.c
+++ b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl83xx.c
diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.h b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl83xx.h
index a69b16b475..a69b16b475 100644
--- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.h
+++ b/target/linux/realtek/files-6.6/drivers/clk/realtek/clk-rtl83xx.h
diff --git a/target/linux/realtek/files-5.15/drivers/clocksource/timer-rtl-otto.c b/target/linux/realtek/files-6.6/drivers/clocksource/timer-rtl-otto.c
index 086f62112a..086f62112a 100644
--- a/target/linux/realtek/files-5.15/drivers/clocksource/timer-rtl-otto.c
+++ b/target/linux/realtek/files-6.6/drivers/clocksource/timer-rtl-otto.c
diff --git a/target/linux/realtek/files-5.15/drivers/gpio/gpio-rtl8231.c b/target/linux/realtek/files-6.6/drivers/gpio/gpio-rtl8231.c
index 2821591a97..2821591a97 100644
--- a/target/linux/realtek/files-5.15/drivers/gpio/gpio-rtl8231.c
+++ b/target/linux/realtek/files-6.6/drivers/gpio/gpio-rtl8231.c
diff --git a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c b/target/linux/realtek/files-6.6/drivers/i2c/busses/i2c-rtl9300.c
index 54d916d17a..54d916d17a 100644
--- a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c
+++ b/target/linux/realtek/files-6.6/drivers/i2c/busses/i2c-rtl9300.c
diff --git a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.h b/target/linux/realtek/files-6.6/drivers/i2c/busses/i2c-rtl9300.h
index 617a1b6632..617a1b6632 100644
--- a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.h
+++ b/target/linux/realtek/files-6.6/drivers/i2c/busses/i2c-rtl9300.h
diff --git a/target/linux/realtek/files-5.15/drivers/i2c/muxes/i2c-mux-rtl9300.c b/target/linux/realtek/files-6.6/drivers/i2c/muxes/i2c-mux-rtl9300.c
index 57036d9d56..57036d9d56 100644
--- a/target/linux/realtek/files-5.15/drivers/i2c/muxes/i2c-mux-rtl9300.c
+++ b/target/linux/realtek/files-6.6/drivers/i2c/muxes/i2c-mux-rtl9300.c
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Kconfig b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/Kconfig
index 3124ee8d20..3124ee8d20 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Kconfig
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/Kconfig
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Makefile b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/Makefile
index 8752c79700..8752c79700 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Makefile
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/Makefile
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c
new file mode 100644
index 0000000000..b17d9ae5d5
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/common.c
@@ -0,0 +1,1733 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <net/arp.h>
+#include <net/nexthop.h>
+#include <net/neighbour.h>
+#include <net/netevent.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/inetdevice.h>
+#include <linux/rhashtable.h>
+#include <linux/of_net.h>
+#include <asm/mach-rtl838x/mach-rtl83xx.h>
+
+#include "rtl83xx.h"
+
+extern struct rtl83xx_soc_info soc_info;
+
+extern const struct rtl838x_reg rtl838x_reg;
+extern const struct rtl838x_reg rtl839x_reg;
+extern const struct rtl838x_reg rtl930x_reg;
+extern const struct rtl838x_reg rtl931x_reg;
+
+extern const struct dsa_switch_ops rtl83xx_switch_ops;
+extern const struct dsa_switch_ops rtl930x_switch_ops;
+
+extern const struct phylink_pcs_ops rtl83xx_pcs_ops;
+extern const struct phylink_pcs_ops rtl93xx_pcs_ops;
+
+DEFINE_MUTEX(smi_lock);
+
+int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port)
+{
+ u32 msti = 0;
+ u32 port_state[4];
+ int index, bit;
+ int pos = port;
+ int n = priv->port_width << 1;
+
+ /* Ports above or equal CPU port can never be configured */
+ if (port >= priv->cpu_port)
+ return -1;
+
+ mutex_lock(&priv->reg_mutex);
+
+ /* For the RTL839x and following, the bits are left-aligned in the 64/128 bit field */
+ if (priv->family_id == RTL8390_FAMILY_ID)
+ pos += 12;
+ if (priv->family_id == RTL9300_FAMILY_ID)
+ pos += 3;
+ if (priv->family_id == RTL9310_FAMILY_ID)
+ pos += 8;
+
+ index = n - (pos >> 4) - 1;
+ bit = (pos << 1) % 32;
+
+ priv->r->stp_get(priv, msti, port_state);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return (port_state[index] >> bit) & 3;
+}
+
+static struct table_reg rtl838x_tbl_regs[] = {
+ TBL_DESC(0x6900, 0x6908, 3, 15, 13, 1), /* RTL8380_TBL_L2 */
+ TBL_DESC(0x6914, 0x6918, 18, 14, 12, 1), /* RTL8380_TBL_0 */
+ TBL_DESC(0xA4C8, 0xA4CC, 6, 14, 12, 1), /* RTL8380_TBL_1 */
+
+ TBL_DESC(0x1180, 0x1184, 3, 16, 14, 0), /* RTL8390_TBL_L2 */
+ TBL_DESC(0x1190, 0x1194, 17, 15, 12, 0), /* RTL8390_TBL_0 */
+ TBL_DESC(0x6B80, 0x6B84, 4, 14, 12, 0), /* RTL8390_TBL_1 */
+ TBL_DESC(0x611C, 0x6120, 9, 8, 6, 0), /* RTL8390_TBL_2 */
+
+ TBL_DESC(0xB320, 0xB334, 3, 18, 16, 0), /* RTL9300_TBL_L2 */
+ TBL_DESC(0xB340, 0xB344, 19, 16, 12, 0), /* RTL9300_TBL_0 */
+ TBL_DESC(0xB3A0, 0xB3A4, 20, 16, 13, 0), /* RTL9300_TBL_1 */
+ TBL_DESC(0xCE04, 0xCE08, 6, 14, 12, 0), /* RTL9300_TBL_2 */
+ TBL_DESC(0xD600, 0xD604, 30, 7, 6, 0), /* RTL9300_TBL_HSB */
+ TBL_DESC(0x7880, 0x7884, 22, 9, 8, 0), /* RTL9300_TBL_HSA */
+
+ TBL_DESC(0x8500, 0x8508, 8, 19, 15, 0), /* RTL9310_TBL_0 */
+ TBL_DESC(0x40C0, 0x40C4, 22, 16, 14, 0), /* RTL9310_TBL_1 */
+ TBL_DESC(0x8528, 0x852C, 6, 18, 14, 0), /* RTL9310_TBL_2 */
+ TBL_DESC(0x0200, 0x0204, 9, 15, 12, 0), /* RTL9310_TBL_3 */
+ TBL_DESC(0x20dc, 0x20e0, 29, 7, 6, 0), /* RTL9310_TBL_4 */
+ TBL_DESC(0x7e1c, 0x7e20, 53, 8, 6, 0), /* RTL9310_TBL_5 */
+};
+
+void rtl_table_init(void)
+{
+ for (int i = 0; i < RTL_TBL_END; i++)
+ mutex_init(&rtl838x_tbl_regs[i].lock);
+}
+
+/* Request access to table t in table access register r
+ * Returns a handle to a lock for that table
+ */
+struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t)
+{
+ if (r >= RTL_TBL_END)
+ return NULL;
+
+ if (t >= BIT(rtl838x_tbl_regs[r].c_bit-rtl838x_tbl_regs[r].t_bit))
+ return NULL;
+
+ mutex_lock(&rtl838x_tbl_regs[r].lock);
+ rtl838x_tbl_regs[r].tbl = t;
+
+ return &rtl838x_tbl_regs[r];
+}
+
+/* Release a table r, unlock the corresponding lock */
+void rtl_table_release(struct table_reg *r)
+{
+ if (!r)
+ return;
+
+/* pr_info("Unlocking %08x\n", (u32)r); */
+ mutex_unlock(&r->lock);
+/* pr_info("Unlock done\n"); */
+}
+
+static int rtl_table_exec(struct table_reg *r, bool is_write, int idx)
+{
+ int ret = 0;
+ u32 cmd, val;
+
+ /* Read/write bit has inverted meaning on RTL838x */
+ if (r->rmode)
+ cmd = is_write ? 0 : BIT(r->c_bit);
+ else
+ cmd = is_write ? BIT(r->c_bit) : 0;
+
+ cmd |= BIT(r->c_bit + 1); /* Execute bit */
+ cmd |= r->tbl << r->t_bit; /* Table type */
+ cmd |= idx & (BIT(r->t_bit) - 1); /* Index */
+
+ sw_w32(cmd, r->addr);
+
+ ret = readx_poll_timeout(sw_r32, r->addr, val,
+ !(val & BIT(r->c_bit + 1)), 20, 10000);
+ if (ret)
+ pr_err("%s: timeout\n", __func__);
+
+ return ret;
+}
+
+/* Reads table index idx into the data registers of the table */
+int rtl_table_read(struct table_reg *r, int idx)
+{
+ return rtl_table_exec(r, false, idx);
+}
+
+/* Writes the content of the table data registers into the table at index idx */
+int rtl_table_write(struct table_reg *r, int idx)
+{
+ return rtl_table_exec(r, true, idx);
+}
+
+/* Returns the address of the ith data register of table register r
+ * the address is relative to the beginning of the Switch-IO block at 0xbb000000
+ */
+inline u16 rtl_table_data(struct table_reg *r, int i)
+{
+ if (i >= r->max_data)
+ i = r->max_data - 1;
+ return r->data + i * 4;
+}
+
+inline u32 rtl_table_data_r(struct table_reg *r, int i)
+{
+ return sw_r32(rtl_table_data(r, i));
+}
+
+inline void rtl_table_data_w(struct table_reg *r, u32 v, int i)
+{
+ sw_w32(v, rtl_table_data(r, i));
+}
+
+/* Port register accessor functions for the RTL838x and RTL930X SoCs */
+void rtl838x_mask_port_reg(u64 clear, u64 set, int reg)
+{
+ sw_w32_mask((u32)clear, (u32)set, reg);
+}
+
+void rtl838x_set_port_reg(u64 set, int reg)
+{
+ sw_w32((u32)set, reg);
+}
+
+u64 rtl838x_get_port_reg(int reg)
+{
+ return ((u64)sw_r32(reg));
+}
+
+/* Port register accessor functions for the RTL839x and RTL931X SoCs */
+void rtl839x_mask_port_reg_be(u64 clear, u64 set, int reg)
+{
+ sw_w32_mask((u32)(clear >> 32), (u32)(set >> 32), reg);
+ sw_w32_mask((u32)(clear & 0xffffffff), (u32)(set & 0xffffffff), reg + 4);
+}
+
+u64 rtl839x_get_port_reg_be(int reg)
+{
+ u64 v = sw_r32(reg);
+
+ v <<= 32;
+ v |= sw_r32(reg + 4);
+
+ return v;
+}
+
+void rtl839x_set_port_reg_be(u64 set, int reg)
+{
+ sw_w32(set >> 32, reg);
+ sw_w32(set & 0xffffffff, reg + 4);
+}
+
+void rtl839x_mask_port_reg_le(u64 clear, u64 set, int reg)
+{
+ sw_w32_mask((u32)clear, (u32)set, reg);
+ sw_w32_mask((u32)(clear >> 32), (u32)(set >> 32), reg + 4);
+}
+
+void rtl839x_set_port_reg_le(u64 set, int reg)
+{
+ sw_w32(set, reg);
+ sw_w32(set >> 32, reg + 4);
+}
+
+u64 rtl839x_get_port_reg_le(int reg)
+{
+ u64 v = sw_r32(reg + 4);
+
+ v <<= 32;
+ v |= sw_r32(reg);
+
+ return v;
+}
+
+int read_phy(u32 port, u32 page, u32 reg, u32 *val)
+{
+ switch (soc_info.family) {
+ case RTL8380_FAMILY_ID:
+ return rtl838x_read_phy(port, page, reg, val);
+ case RTL8390_FAMILY_ID:
+ return rtl839x_read_phy(port, page, reg, val);
+ case RTL9300_FAMILY_ID:
+ return rtl930x_read_phy(port, page, reg, val);
+ case RTL9310_FAMILY_ID:
+ return rtl931x_read_phy(port, page, reg, val);
+ }
+
+ return -1;
+}
+
+int write_phy(u32 port, u32 page, u32 reg, u32 val)
+{
+ switch (soc_info.family) {
+ case RTL8380_FAMILY_ID:
+ return rtl838x_write_phy(port, page, reg, val);
+ case RTL8390_FAMILY_ID:
+ return rtl839x_write_phy(port, page, reg, val);
+ case RTL9300_FAMILY_ID:
+ return rtl930x_write_phy(port, page, reg, val);
+ case RTL9310_FAMILY_ID:
+ return rtl931x_write_phy(port, page, reg, val);
+ }
+
+ return -1;
+}
+
+static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
+{
+ struct device *dev = priv->dev;
+ struct device_node *dn, *phy_node, *led_node, *mii_np = dev->of_node;
+ struct mii_bus *bus;
+ int ret;
+ u32 pn;
+
+ pr_debug("In %s\n", __func__);
+ mii_np = of_find_compatible_node(NULL, NULL, "realtek,rtl838x-mdio");
+ if (mii_np) {
+ pr_debug("Found compatible MDIO node!\n");
+ } else {
+ dev_err(priv->dev, "no %s child node found", "mdio-bus");
+ return -ENODEV;
+ }
+
+ priv->mii_bus = of_mdio_find_bus(mii_np);
+ if (!priv->mii_bus) {
+ pr_debug("Deferring probe of mdio bus\n");
+ return -EPROBE_DEFER;
+ }
+ if (!of_device_is_available(mii_np))
+ ret = -ENODEV;
+
+ bus = devm_mdiobus_alloc(priv->ds->dev);
+ if (!bus)
+ return -ENOMEM;
+
+ bus->name = "rtl838x slave mii";
+
+ /* Since the NIC driver is loaded first, we can use the mdio rw functions
+ * assigned there.
+ */
+ bus->read = priv->mii_bus->read;
+ bus->write = priv->mii_bus->write;
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", bus->name, dev->id);
+
+ bus->parent = dev;
+ priv->ds->slave_mii_bus = bus;
+ priv->ds->slave_mii_bus->priv = priv->mii_bus->priv;
+
+ ret = mdiobus_register(priv->ds->slave_mii_bus);
+ if (ret && mii_np) {
+ of_node_put(dn);
+ return ret;
+ }
+
+ dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch");
+ if (!dn) {
+ dev_err(priv->dev, "No RTL switch node in DTS\n");
+ return -ENODEV;
+ }
+
+ led_node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds");
+
+ for_each_node_by_name(dn, "port") {
+ phy_interface_t interface;
+ u32 led_set;
+ char led_set_str[16] = {0};
+
+ if (!of_device_is_available(dn))
+ continue;
+
+ if (of_property_read_u32(dn, "reg", &pn))
+ continue;
+
+ phy_node = of_parse_phandle(dn, "phy-handle", 0);
+ if (!phy_node) {
+ if (pn != priv->cpu_port)
+ dev_err(priv->dev, "Port node %d misses phy-handle\n", pn);
+ continue;
+ }
+
+ if (of_property_read_u32(phy_node, "sds", &priv->ports[pn].sds_num))
+ priv->ports[pn].sds_num = -1;
+ pr_debug("%s port %d has SDS %d\n", __func__, pn, priv->ports[pn].sds_num);
+
+ if (of_get_phy_mode(dn, &interface))
+ interface = PHY_INTERFACE_MODE_NA;
+ if (interface == PHY_INTERFACE_MODE_HSGMII)
+ priv->ports[pn].is2G5 = true;
+ if (interface == PHY_INTERFACE_MODE_USXGMII)
+ priv->ports[pn].is2G5 = priv->ports[pn].is10G = true;
+ if (interface == PHY_INTERFACE_MODE_10GBASER)
+ priv->ports[pn].is10G = true;
+
+ priv->ports[pn].leds_on_this_port = 0;
+ if (led_node) {
+ if (of_property_read_u32(dn, "led-set", &led_set))
+ led_set = 0;
+ priv->ports[pn].led_set = led_set;
+ sprintf(led_set_str, "led_set%d", led_set);
+ priv->ports[pn].leds_on_this_port = of_property_count_u32_elems(led_node, led_set_str);
+ if (priv->ports[pn].leds_on_this_port > 4) {
+ dev_err(priv->dev, "led_set %d for port %d configuration is invalid\n", led_set, pn);
+ return -ENODEV;
+ }
+ }
+
+ /* Check for the integrated SerDes of the RTL8380M first */
+ if (of_property_read_bool(phy_node, "phy-is-integrated")
+ && priv->id == 0x8380 && pn >= 24) {
+ pr_debug("----> FÓUND A SERDES\n");
+ priv->ports[pn].phy = PHY_RTL838X_SDS;
+ continue;
+ }
+
+ if (priv->id >= 0x9300) {
+ priv->ports[pn].phy_is_integrated = false;
+ if (of_property_read_bool(phy_node, "phy-is-integrated")) {
+ priv->ports[pn].phy_is_integrated = true;
+ priv->ports[pn].phy = PHY_RTL930X_SDS;
+ }
+ } else {
+ if (of_property_read_bool(phy_node, "phy-is-integrated") &&
+ !of_property_read_bool(phy_node, "sfp")) {
+ priv->ports[pn].phy = PHY_RTL8218B_INT;
+ continue;
+ }
+ }
+
+ if (!of_property_read_bool(phy_node, "phy-is-integrated") &&
+ of_property_read_bool(phy_node, "sfp")) {
+ priv->ports[pn].phy = PHY_RTL8214FC;
+ continue;
+ }
+
+ if (!of_property_read_bool(phy_node, "phy-is-integrated") &&
+ !of_property_read_bool(phy_node, "sfp")) {
+ priv->ports[pn].phy = PHY_RTL8218B_EXT;
+ continue;
+ }
+ }
+
+ /* Disable MAC polling the PHY so that we can start configuration */
+ priv->r->set_port_reg_le(0ULL, priv->r->smi_poll_ctrl);
+
+ /* Enable PHY control via SoC */
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ /* Enable SerDes NWAY and PHY control via SoC */
+ sw_w32_mask(BIT(7), BIT(15), RTL838X_SMI_GLB_CTRL);
+ } else if (priv->family_id == RTL8390_FAMILY_ID) {
+ /* Disable PHY polling via SoC */
+ sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL);
+ }
+
+ /* Power on fibre ports and reset them if necessary */
+ if (priv->ports[24].phy == PHY_RTL838X_SDS) {
+ pr_debug("Powering on fibre ports & reset\n");
+ rtl8380_sds_power(24, 1);
+ rtl8380_sds_power(26, 1);
+ }
+
+ pr_debug("%s done\n", __func__);
+
+ return 0;
+}
+
+static int __init rtl83xx_get_l2aging(struct rtl838x_switch_priv *priv)
+{
+ int t = sw_r32(priv->r->l2_ctrl_1);
+
+ t &= priv->family_id == RTL8380_FAMILY_ID ? 0x7fffff : 0x1FFFFF;
+
+ if (priv->family_id == RTL8380_FAMILY_ID)
+ t = t * 128 / 625; /* Aging time in seconds. 0: L2 aging disabled */
+ else
+ t = (t * 3) / 5;
+
+ pr_debug("L2 AGING time: %d sec\n", t);
+ pr_debug("Dynamic aging for ports: %x\n", sw_r32(priv->r->l2_port_aging_out));
+
+ return t;
+}
+
+/* Caller must hold priv->reg_mutex */
+int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int i;
+ u32 algomsk = 0;
+ u32 algoidx = 0;
+
+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
+ pr_err("%s: Only mode LACP 802.3ad (4) allowed.\n", __func__);
+ return -EINVAL;
+ }
+
+ if (group >= priv->n_lags) {
+ pr_err("%s: LAG %d invalid.\n", __func__, group);
+ return -EINVAL;
+ }
+
+ if (port >= priv->cpu_port) {
+ pr_err("%s: Port %d invalid.\n", __func__, port);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < priv->n_lags; i++) {
+ if (priv->lags_port_members[i] & BIT_ULL(port))
+ break;
+ }
+ if (i != priv->n_lags) {
+ pr_err("%s: Port %d already member of LAG %d.\n", __func__, port, i);
+ return -ENOSPC;
+ }
+
+ switch(info->hash_type) {
+ case NETDEV_LAG_HASH_L2:
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT;
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT;
+ break;
+ case NETDEV_LAG_HASH_L23:
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT;
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT;
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; /* source ip */
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; /* dest ip */
+ algoidx = 1;
+ break;
+ case NETDEV_LAG_HASH_L34:
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT; /* sport */
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_DST_L4PORT_BIT; /* dport */
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; /* source ip */
+ algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; /* dest ip */
+ algoidx = 2;
+ break;
+ default:
+ algomsk |= 0x7f;
+ }
+ priv->r->set_distribution_algorithm(group, algoidx, algomsk);
+ priv->r->mask_port_reg_be(0, BIT_ULL(port), priv->r->trk_mbr_ctr(group));
+ priv->lags_port_members[group] |= BIT_ULL(port);
+
+ pr_info("%s: Added port %d to LAG %d. Members now %016llx.\n",
+ __func__, port, group, priv->lags_port_members[group]);
+
+ return 0;
+}
+
+/* Caller must hold priv->reg_mutex */
+int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ if (group >= priv->n_lags) {
+ pr_err("%s: LAG %d invalid.\n", __func__, group);
+ return -EINVAL;
+ }
+
+ if (port >= priv->cpu_port) {
+ pr_err("%s: Port %d invalid.\n", __func__, port);
+ return -EINVAL;
+ }
+
+ if (!(priv->lags_port_members[group] & BIT_ULL(port))) {
+ pr_err("%s: Port %d not member of LAG %d.\n", __func__, port, group);
+ return -ENOSPC;
+ }
+
+ /* 0x7f algo mask all */
+ priv->r->mask_port_reg_be(BIT_ULL(port), 0, priv->r->trk_mbr_ctr(group));
+ priv->lags_port_members[group] &= ~BIT_ULL(port);
+
+ pr_info("%s: Removed port %d from LAG %d. Members now %016llx.\n",
+ __func__, port, group, priv->lags_port_members[group]);
+
+ return 0;
+}
+
+// Currently Unused
+// /* Allocate a 64 bit octet counter located in the LOG HW table */
+// static int rtl83xx_octet_cntr_alloc(struct rtl838x_switch_priv *priv)
+// {
+// int idx;
+
+// mutex_lock(&priv->reg_mutex);
+
+// idx = find_first_zero_bit(priv->octet_cntr_use_bm, MAX_COUNTERS);
+// if (idx >= priv->n_counters) {
+// mutex_unlock(&priv->reg_mutex);
+// return -1;
+// }
+
+// set_bit(idx, priv->octet_cntr_use_bm);
+// mutex_unlock(&priv->reg_mutex);
+
+// return idx;
+// }
+
+/* Allocate a 32-bit packet counter
+ * 2 32-bit packet counters share the location of a 64-bit octet counter
+ * Initially there are no free packet counters and 2 new ones need to be freed
+ * by allocating the corresponding octet counter
+ */
+int rtl83xx_packet_cntr_alloc(struct rtl838x_switch_priv *priv)
+{
+ int idx, j;
+
+ mutex_lock(&priv->reg_mutex);
+
+ /* Because initially no packet counters are free, the logic is reversed:
+ * a 0-bit means the counter is already allocated (for octets)
+ */
+ idx = find_first_bit(priv->packet_cntr_use_bm, MAX_COUNTERS * 2);
+ if (idx >= priv->n_counters * 2) {
+ j = find_first_zero_bit(priv->octet_cntr_use_bm, MAX_COUNTERS);
+ if (j >= priv->n_counters) {
+ mutex_unlock(&priv->reg_mutex);
+ return -1;
+ }
+ set_bit(j, priv->octet_cntr_use_bm);
+ idx = j * 2;
+ set_bit(j * 2 + 1, priv->packet_cntr_use_bm);
+
+ } else {
+ clear_bit(idx, priv->packet_cntr_use_bm);
+ }
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return idx;
+}
+
+/* Add an L2 nexthop entry for the L3 routing system / PIE forwarding in the SoC
+ * Use VID and MAC in rtl838x_l2_entry to identify either a free slot in the L2 hash table
+ * or mark an existing entry as a nexthop by setting it's nexthop bit
+ * Called from the L3 layer
+ * The index in the L2 hash table is filled into nh->l2_id;
+ */
+int rtl83xx_l2_nexthop_add(struct rtl838x_switch_priv *priv, struct rtl83xx_nexthop *nh)
+{
+ struct rtl838x_l2_entry e;
+ u64 seed = priv->r->l2_hash_seed(nh->mac, nh->rvid);
+ u32 key = priv->r->l2_hash_key(priv, seed);
+ int idx = -1;
+ u64 entry;
+
+ pr_debug("%s searching for %08llx vid %d with key %d, seed: %016llx\n",
+ __func__, nh->mac, nh->rvid, key, seed);
+
+ e.type = L2_UNICAST;
+ u64_to_ether_addr(nh->mac, &e.mac[0]);
+ e.port = nh->port;
+
+ /* Loop over all entries in the hash-bucket and over the second block on 93xx SoCs */
+ for (int i = 0; i < priv->l2_bucket_size; i++) {
+ entry = priv->r->read_l2_entry_using_hash(key, i, &e);
+
+ if (!e.valid || ((entry & 0x0fffffffffffffffULL) == seed)) {
+ idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1
+ : ((key << 2) | i) & 0xffff;
+ break;
+ }
+ }
+
+ if (idx < 0) {
+ pr_err("%s: No more L2 forwarding entries available\n", __func__);
+ return -1;
+ }
+
+ /* Found an existing (e->valid is true) or empty entry, make it a nexthop entry */
+ nh->l2_id = idx;
+ if (e.valid) {
+ nh->port = e.port;
+ nh->vid = e.vid; /* Save VID */
+ nh->rvid = e.rvid;
+ nh->dev_id = e.stack_dev;
+ /* If the entry is already a valid next hop entry, don't change it */
+ if (e.next_hop)
+ return 0;
+ } else {
+ e.valid = true;
+ e.is_static = true;
+ e.rvid = nh->rvid;
+ e.is_ip_mc = false;
+ e.is_ipv6_mc = false;
+ e.block_da = false;
+ e.block_sa = false;
+ e.suspended = false;
+ e.age = 0; /* With port-ignore */
+ e.port = priv->port_ignore;
+ u64_to_ether_addr(nh->mac, &e.mac[0]);
+ }
+ e.next_hop = true;
+ e.nh_route_id = nh->id; /* NH route ID takes place of VID */
+ e.nh_vlan_target = false;
+
+ priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
+
+ return 0;
+}
+
+/* Removes a Layer 2 next hop entry in the forwarding database
+ * If it was static, the entire entry is removed, otherwise the nexthop bit is cleared
+ * and we wait until the entry ages out
+ */
+int rtl83xx_l2_nexthop_rm(struct rtl838x_switch_priv *priv, struct rtl83xx_nexthop *nh)
+{
+ struct rtl838x_l2_entry e;
+ u32 key = nh->l2_id >> 2;
+ int i = nh->l2_id & 0x3;
+ u64 entry = entry = priv->r->read_l2_entry_using_hash(key, i, &e);
+
+ pr_debug("%s: id %d, key %d, index %d\n", __func__, nh->l2_id, key, i);
+ if (!e.valid) {
+ dev_err(priv->dev, "unknown nexthop, id %x\n", nh->l2_id);
+ return -1;
+ }
+
+ if (e.is_static)
+ e.valid = false;
+ e.next_hop = false;
+ e.vid = nh->vid; /* Restore VID */
+ e.rvid = nh->rvid;
+
+ priv->r->write_l2_entry_using_hash(key, i, &e);
+
+ return 0;
+}
+
+static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv,
+ struct net_device *ndev,
+ struct netdev_notifier_changeupper_info *info)
+{
+ struct net_device *upper = info->upper_dev;
+ struct netdev_lag_upper_info *lag_upper_info = NULL;
+ int i, j, err;
+
+ if (!netif_is_lag_master(upper))
+ return 0;
+
+ mutex_lock(&priv->reg_mutex);
+
+ for (i = 0; i < priv->n_lags; i++) {
+ if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == upper))
+ break;
+ }
+ for (j = 0; j < priv->cpu_port; j++) {
+ if (priv->ports[j].dp->slave == ndev)
+ break;
+ }
+ if (j >= priv->cpu_port) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (info->linking) {
+ lag_upper_info = info->upper_info;
+ if (!priv->lag_devs[i])
+ priv->lag_devs[i] = upper;
+ err = rtl83xx_lag_add(priv->ds, i, priv->ports[j].dp->index, lag_upper_info);
+ if (err) {
+ err = -EINVAL;
+ goto out;
+ }
+ } else {
+ if (!priv->lag_devs[i])
+ err = -EINVAL;
+ err = rtl83xx_lag_del(priv->ds, i, priv->ports[j].dp->index);
+ if (err) {
+ err = -EINVAL;
+ goto out;
+ }
+ if (!priv->lags_port_members[i])
+ priv->lag_devs[i] = NULL;
+ }
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+/* Is the lower network device a DSA slave network device of our RTL930X-switch?
+ * Unfortunately we cannot just follow dev->dsa_prt as this is only set for the
+ * DSA master device.
+ */
+int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_priv *priv)
+{
+/* TODO: On 5.12:
+ * if(!dsa_slave_dev_check(dev)) {
+ * netdev_info(dev, "%s: not a DSA device.\n", __func__);
+ * return -EINVAL;
+ * }
+ */
+
+ for (int i = 0; i < priv->cpu_port; i++) {
+ if (!priv->ports[i].dp)
+ continue;
+ if (priv->ports[i].dp->slave == dev)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+static int rtl83xx_netdevice_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
+ struct rtl838x_switch_priv *priv;
+ int err;
+
+ pr_debug("In: %s, event: %lu\n", __func__, event);
+
+ if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE))
+ return NOTIFY_DONE;
+
+ priv = container_of(this, struct rtl838x_switch_priv, nb);
+ switch (event) {
+ case NETDEV_CHANGEUPPER:
+ err = rtl83xx_handle_changeupper(priv, ndev, ptr);
+ break;
+ }
+
+ if (err)
+ return err;
+
+ return NOTIFY_DONE;
+}
+
+const static struct rhashtable_params route_ht_params = {
+ .key_len = sizeof(u32),
+ .key_offset = offsetof(struct rtl83xx_route, gw_ip),
+ .head_offset = offsetof(struct rtl83xx_route, linkage),
+};
+
+/* Updates an L3 next hop entry in the ROUTING table */
+static int rtl83xx_l3_nexthop_update(struct rtl838x_switch_priv *priv, __be32 ip_addr, u64 mac)
+{
+ struct rtl83xx_route *r;
+ struct rhlist_head *tmp, *list;
+
+ rcu_read_lock();
+ list = rhltable_lookup(&priv->routes, &ip_addr, route_ht_params);
+ if (!list) {
+ rcu_read_unlock();
+ return -ENOENT;
+ }
+
+ rhl_for_each_entry_rcu(r, tmp, list, linkage) {
+ pr_info("%s: Setting up fwding: ip %pI4, GW mac %016llx\n",
+ __func__, &ip_addr, mac);
+
+ /* Reads the ROUTING table entry associated with the route */
+ priv->r->route_read(r->id, r);
+ pr_info("Route with id %d to %pI4 / %d\n", r->id, &r->dst_ip, r->prefix_len);
+
+ r->nh.mac = r->nh.gw = mac;
+ r->nh.port = priv->port_ignore;
+ r->nh.id = r->id;
+
+ /* Do we need to explicitly add a DMAC entry with the route's nh index? */
+ if (priv->r->set_l3_egress_mac)
+ priv->r->set_l3_egress_mac(r->id, mac);
+
+ /* Update ROUTING table: map gateway-mac and switch-mac id to route id */
+ rtl83xx_l2_nexthop_add(priv, &r->nh);
+
+ r->attr.valid = true;
+ r->attr.action = ROUTE_ACT_FORWARD;
+ r->attr.type = 0;
+ r->attr.hit = false; /* Reset route-used indicator */
+
+ /* Add PIE entry with dst_ip and prefix_len */
+ r->pr.dip = r->dst_ip;
+ r->pr.dip_m = inet_make_mask(r->prefix_len);
+
+ if (r->is_host_route) {
+ int slot = priv->r->find_l3_slot(r, false);
+
+ pr_info("%s: Got slot for route: %d\n", __func__, slot);
+ priv->r->host_route_write(slot, r);
+ } else {
+ priv->r->route_write(r->id, r);
+ r->pr.fwd_sel = true;
+ r->pr.fwd_data = r->nh.l2_id;
+ r->pr.fwd_act = PIE_ACT_ROUTE_UC;
+ }
+
+ if (priv->r->set_l3_nexthop)
+ priv->r->set_l3_nexthop(r->nh.id, r->nh.l2_id, r->nh.if_id);
+
+ if (r->pr.id < 0) {
+ r->pr.packet_cntr = rtl83xx_packet_cntr_alloc(priv);
+ if (r->pr.packet_cntr >= 0) {
+ pr_info("Using packet counter %d\n", r->pr.packet_cntr);
+ r->pr.log_sel = true;
+ r->pr.log_data = r->pr.packet_cntr;
+ }
+ priv->r->pie_rule_add(priv, &r->pr);
+ } else {
+ int pkts = priv->r->packet_cntr_read(r->pr.packet_cntr);
+ pr_info("%s: total packets: %d\n", __func__, pkts);
+
+ priv->r->pie_rule_write(priv, r->pr.id, &r->pr);
+ }
+ }
+ rcu_read_unlock();
+
+ return 0;
+}
+
+static int rtl83xx_port_ipv4_resolve(struct rtl838x_switch_priv *priv,
+ struct net_device *dev, __be32 ip_addr)
+{
+ struct neighbour *n = neigh_lookup(&arp_tbl, &ip_addr, dev);
+ int err = 0;
+ u64 mac;
+
+ if (!n) {
+ n = neigh_create(&arp_tbl, &ip_addr, dev);
+ if (IS_ERR(n))
+ return PTR_ERR(n);
+ }
+
+ /* If the neigh is already resolved, then go ahead and
+ * install the entry, otherwise start the ARP process to
+ * resolve the neigh.
+ */
+ if (n->nud_state & NUD_VALID) {
+ mac = ether_addr_to_u64(n->ha);
+ pr_info("%s: resolved mac: %016llx\n", __func__, mac);
+ rtl83xx_l3_nexthop_update(priv, ip_addr, mac);
+ } else {
+ pr_info("%s: need to wait\n", __func__);
+ neigh_event_send(n, NULL);
+ }
+
+ neigh_release(n);
+
+ return err;
+}
+
+struct rtl83xx_walk_data {
+ struct rtl838x_switch_priv *priv;
+ int port;
+};
+
+static int rtl83xx_port_lower_walk(struct net_device *lower, struct netdev_nested_priv *_priv)
+{
+ struct rtl83xx_walk_data *data = (struct rtl83xx_walk_data *)_priv->data;
+ struct rtl838x_switch_priv *priv = data->priv;
+ int ret = 0;
+ int index;
+
+ index = rtl83xx_port_is_under(lower, priv);
+ data->port = index;
+ if (index >= 0) {
+ pr_debug("Found DSA-port, index %d\n", index);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+int rtl83xx_port_dev_lower_find(struct net_device *dev, struct rtl838x_switch_priv *priv)
+{
+ struct rtl83xx_walk_data data;
+ struct netdev_nested_priv _priv;
+
+ data.priv = priv;
+ data.port = 0;
+ _priv.data = (void *)&data;
+
+ netdev_walk_all_lower_dev(dev, rtl83xx_port_lower_walk, &_priv);
+
+ return data.port;
+}
+
+static struct rtl83xx_route *rtl83xx_route_alloc(struct rtl838x_switch_priv *priv, u32 ip)
+{
+ struct rtl83xx_route *r;
+ int idx = 0, err;
+
+ mutex_lock(&priv->reg_mutex);
+
+ idx = find_first_zero_bit(priv->route_use_bm, MAX_ROUTES);
+ pr_debug("%s id: %d, ip %pI4\n", __func__, idx, &ip);
+
+ r = kzalloc(sizeof(*r), GFP_KERNEL);
+ if (!r) {
+ mutex_unlock(&priv->reg_mutex);
+ return r;
+ }
+
+ r->id = idx;
+ r->gw_ip = ip;
+ r->pr.id = -1; /* We still need to allocate a rule in HW */
+ r->is_host_route = false;
+
+ err = rhltable_insert(&priv->routes, &r->linkage, route_ht_params);
+ if (err) {
+ pr_err("Could not insert new rule\n");
+ mutex_unlock(&priv->reg_mutex);
+ goto out_free;
+ }
+
+ set_bit(idx, priv->route_use_bm);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return r;
+
+out_free:
+ kfree(r);
+
+ return NULL;
+}
+
+
+static struct rtl83xx_route *rtl83xx_host_route_alloc(struct rtl838x_switch_priv *priv, u32 ip)
+{
+ struct rtl83xx_route *r;
+ int idx = 0, err;
+
+ mutex_lock(&priv->reg_mutex);
+
+ idx = find_first_zero_bit(priv->host_route_use_bm, MAX_HOST_ROUTES);
+ pr_debug("%s id: %d, ip %pI4\n", __func__, idx, &ip);
+
+ r = kzalloc(sizeof(*r), GFP_KERNEL);
+ if (!r) {
+ mutex_unlock(&priv->reg_mutex);
+ return r;
+ }
+
+ /* We require a unique route ID irrespective of whether it is a prefix or host
+ * route (on RTL93xx) as we use this ID to associate a DMAC and next-hop entry
+ */
+ r->id = idx + MAX_ROUTES;
+
+ r->gw_ip = ip;
+ r->pr.id = -1; /* We still need to allocate a rule in HW */
+ r->is_host_route = true;
+
+ err = rhltable_insert(&priv->routes, &r->linkage, route_ht_params);
+ if (err) {
+ pr_err("Could not insert new rule\n");
+ mutex_unlock(&priv->reg_mutex);
+ goto out_free;
+ }
+
+ set_bit(idx, priv->host_route_use_bm);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return r;
+
+out_free:
+ kfree(r);
+
+ return NULL;
+}
+
+
+
+static void rtl83xx_route_rm(struct rtl838x_switch_priv *priv, struct rtl83xx_route *r)
+{
+ int id;
+
+ if (rhltable_remove(&priv->routes, &r->linkage, route_ht_params))
+ dev_warn(priv->dev, "Could not remove route\n");
+
+ if (r->is_host_route) {
+ id = priv->r->find_l3_slot(r, false);
+ pr_debug("%s: Got id for host route: %d\n", __func__, id);
+ r->attr.valid = false;
+ priv->r->host_route_write(id, r);
+ clear_bit(r->id - MAX_ROUTES, priv->host_route_use_bm);
+ } else {
+ /* If there is a HW representation of the route, delete it */
+ if (priv->r->route_lookup_hw) {
+ id = priv->r->route_lookup_hw(r);
+ pr_info("%s: Got id for prefix route: %d\n", __func__, id);
+ r->attr.valid = false;
+ priv->r->route_write(id, r);
+ }
+ clear_bit(r->id, priv->route_use_bm);
+ }
+
+ kfree(r);
+}
+
+static int rtl83xx_fib4_del(struct rtl838x_switch_priv *priv,
+ struct fib_entry_notifier_info *info)
+{
+ struct fib_nh *nh = fib_info_nh(info->fi, 0);
+ struct rtl83xx_route *r;
+ struct rhlist_head *tmp, *list;
+
+ pr_debug("In %s, ip %pI4, len %d\n", __func__, &info->dst, info->dst_len);
+ rcu_read_lock();
+ list = rhltable_lookup(&priv->routes, &nh->fib_nh_gw4, route_ht_params);
+ if (!list) {
+ rcu_read_unlock();
+ pr_err("%s: no such gateway: %pI4\n", __func__, &nh->fib_nh_gw4);
+ return -ENOENT;
+ }
+ rhl_for_each_entry_rcu(r, tmp, list, linkage) {
+ if (r->dst_ip == info->dst && r->prefix_len == info->dst_len) {
+ pr_info("%s: found a route with id %d, nh-id %d\n",
+ __func__, r->id, r->nh.id);
+ break;
+ }
+ }
+ rcu_read_unlock();
+
+ rtl83xx_l2_nexthop_rm(priv, &r->nh);
+
+ pr_debug("%s: Releasing packet counter %d\n", __func__, r->pr.packet_cntr);
+ set_bit(r->pr.packet_cntr, priv->packet_cntr_use_bm);
+ priv->r->pie_rule_rm(priv, &r->pr);
+
+ rtl83xx_route_rm(priv, r);
+
+ nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
+
+ return 0;
+}
+
+/* On the RTL93xx, an L3 termination endpoint MAC address on which the router waits
+ * for packets to be routed needs to be allocated.
+ */
+static int rtl83xx_alloc_router_mac(struct rtl838x_switch_priv *priv, u64 mac)
+{
+ int free_mac = -1;
+ struct rtl93xx_rt_mac m;
+
+ mutex_lock(&priv->reg_mutex);
+ for (int i = 0; i < MAX_ROUTER_MACS; i++) {
+ priv->r->get_l3_router_mac(i, &m);
+ if (free_mac < 0 && !m.valid) {
+ free_mac = i;
+ continue;
+ }
+ if (m.valid && m.mac == mac) {
+ free_mac = i;
+ break;
+ }
+ }
+
+ if (free_mac < 0) {
+ pr_err("No free router MACs, cannot offload\n");
+ mutex_unlock(&priv->reg_mutex);
+ return -1;
+ }
+
+ m.valid = true;
+ m.mac = mac;
+ m.p_type = 0; /* An individual port, not a trunk port */
+ m.p_id = 0x3f; /* Listen on any port */
+ m.p_id_mask = 0;
+ m.vid = 0; /* Listen on any VLAN... */
+ m.vid_mask = 0; /* ... so mask needs to be 0 */
+ m.mac_mask = 0xffffffffffffULL; /* We want an exact match of the interface MAC */
+ m.action = L3_FORWARD; /* Route the packet */
+ priv->r->set_l3_router_mac(free_mac, &m);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static int rtl83xx_alloc_egress_intf(struct rtl838x_switch_priv *priv, u64 mac, int vlan)
+{
+ int free_mac = -1;
+ struct rtl838x_l3_intf intf;
+ u64 m;
+
+ mutex_lock(&priv->reg_mutex);
+ for (int i = 0; i < MAX_SMACS; i++) {
+ m = priv->r->get_l3_egress_mac(L3_EGRESS_DMACS + i);
+ if (free_mac < 0 && !m) {
+ free_mac = i;
+ continue;
+ }
+ if (m == mac) {
+ mutex_unlock(&priv->reg_mutex);
+ return i;
+ }
+ }
+
+ if (free_mac < 0) {
+ pr_err("No free egress interface, cannot offload\n");
+ return -1;
+ }
+
+ /* Set up default egress interface 1 */
+ intf.vid = vlan;
+ intf.smac_idx = free_mac;
+ intf.ip4_mtu_id = 1;
+ intf.ip6_mtu_id = 1;
+ intf.ttl_scope = 1; /* TTL */
+ intf.hl_scope = 1; /* Hop Limit */
+ intf.ip4_icmp_redirect = intf.ip6_icmp_redirect = 2; /* FORWARD */
+ intf.ip4_pbr_icmp_redirect = intf.ip6_pbr_icmp_redirect = 2; /* FORWARD; */
+ priv->r->set_l3_egress_intf(free_mac, &intf);
+
+ priv->r->set_l3_egress_mac(L3_EGRESS_DMACS + free_mac, mac);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return free_mac;
+}
+
+static int rtl83xx_fib4_add(struct rtl838x_switch_priv *priv,
+ struct fib_entry_notifier_info *info)
+{
+ struct fib_nh *nh = fib_info_nh(info->fi, 0);
+ struct net_device *dev = fib_info_nh(info->fi, 0)->fib_nh_dev;
+ int port;
+ struct rtl83xx_route *r;
+ bool to_localhost;
+ int vlan = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : 0;
+
+ pr_debug("In %s, ip %pI4, len %d\n", __func__, &info->dst, info->dst_len);
+ if (!info->dst) {
+ pr_info("Not offloading default route for now\n");
+ return 0;
+ }
+
+ pr_debug("GW: %pI4, interface name %s, mac %016llx, vlan %d\n", &nh->fib_nh_gw4, dev->name,
+ ether_addr_to_u64(dev->dev_addr), vlan
+ );
+
+ port = rtl83xx_port_dev_lower_find(dev, priv);
+ if (port < 0)
+ return -1;
+
+ /* For now we only work with routes that have a gateway and are not ourself */
+/* if ((!nh->fib_nh_gw4) && (info->dst_len != 32)) */
+/* return 0; */
+
+ if ((info->dst & 0xff) == 0xff)
+ return 0;
+
+ /* Do not offload routes to 192.168.100.x */
+ if ((info->dst & 0xffffff00) == 0xc0a86400)
+ return 0;
+
+ /* Do not offload routes to 127.x.x.x */
+ if ((info->dst & 0xff000000) == 0x7f000000)
+ return 0;
+
+ /* Allocate route or host-route (entry if hardware supports this) */
+ if (info->dst_len == 32 && priv->r->host_route_write)
+ r = rtl83xx_host_route_alloc(priv, nh->fib_nh_gw4);
+ else
+ r = rtl83xx_route_alloc(priv, nh->fib_nh_gw4);
+
+ if (!r) {
+ pr_err("%s: No more free route entries\n", __func__);
+ return -1;
+ }
+
+ r->dst_ip = info->dst;
+ r->prefix_len = info->dst_len;
+ r->nh.rvid = vlan;
+ to_localhost = !nh->fib_nh_gw4;
+
+ if (priv->r->set_l3_router_mac) {
+ u64 mac = ether_addr_to_u64(dev->dev_addr);
+
+ pr_debug("Local route and router mac %016llx\n", mac);
+
+ if (rtl83xx_alloc_router_mac(priv, mac))
+ goto out_free_rt;
+
+ /* vid = 0: Do not care about VID */
+ r->nh.if_id = rtl83xx_alloc_egress_intf(priv, mac, vlan);
+ if (r->nh.if_id < 0)
+ goto out_free_rmac;
+
+ if (to_localhost) {
+ int slot;
+
+ r->nh.mac = mac;
+ r->nh.port = priv->port_ignore;
+ r->attr.valid = true;
+ r->attr.action = ROUTE_ACT_TRAP2CPU;
+ r->attr.type = 0;
+
+ slot = priv->r->find_l3_slot(r, false);
+ pr_debug("%s: Got slot for route: %d\n", __func__, slot);
+ priv->r->host_route_write(slot, r);
+ }
+ }
+
+ /* We need to resolve the mac address of the GW */
+ if (!to_localhost)
+ rtl83xx_port_ipv4_resolve(priv, dev, nh->fib_nh_gw4);
+
+ nh->fib_nh_flags |= RTNH_F_OFFLOAD;
+
+ return 0;
+
+out_free_rmac:
+out_free_rt:
+ return 0;
+}
+
+static int rtl83xx_fib6_add(struct rtl838x_switch_priv *priv,
+ struct fib6_entry_notifier_info *info)
+{
+ pr_debug("In %s\n", __func__);
+/* nh->fib_nh_flags |= RTNH_F_OFFLOAD; */
+
+ return 0;
+}
+
+struct net_event_work {
+ struct work_struct work;
+ struct rtl838x_switch_priv *priv;
+ u64 mac;
+ u32 gw_addr;
+};
+
+static void rtl83xx_net_event_work_do(struct work_struct *work)
+{
+ struct net_event_work *net_work =
+ container_of(work, struct net_event_work, work);
+ struct rtl838x_switch_priv *priv = net_work->priv;
+
+ rtl83xx_l3_nexthop_update(priv, net_work->gw_addr, net_work->mac);
+
+ kfree(net_work);
+}
+
+static int rtl83xx_netevent_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct rtl838x_switch_priv *priv;
+ struct net_device *dev;
+ struct neighbour *n = ptr;
+ int err, port;
+ struct net_event_work *net_work;
+
+ priv = container_of(this, struct rtl838x_switch_priv, ne_nb);
+
+ switch (event) {
+ case NETEVENT_NEIGH_UPDATE:
+ if (n->tbl != &arp_tbl)
+ return NOTIFY_DONE;
+ dev = n->dev;
+ port = rtl83xx_port_dev_lower_find(dev, priv);
+ if (port < 0 || !(n->nud_state & NUD_VALID)) {
+ pr_debug("%s: Neigbour invalid, not updating\n", __func__);
+ return NOTIFY_DONE;
+ }
+
+ net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
+ if (!net_work)
+ return NOTIFY_BAD;
+
+ INIT_WORK(&net_work->work, rtl83xx_net_event_work_do);
+ net_work->priv = priv;
+
+ net_work->mac = ether_addr_to_u64(n->ha);
+ net_work->gw_addr = *(__be32 *) n->primary_key;
+
+ pr_debug("%s: updating neighbour on port %d, mac %016llx\n",
+ __func__, port, net_work->mac);
+ schedule_work(&net_work->work);
+ if (err)
+ netdev_warn(dev, "failed to handle neigh update (err %d)\n", err);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+struct rtl83xx_fib_event_work {
+ struct work_struct work;
+ union {
+ struct fib_entry_notifier_info fen_info;
+ struct fib6_entry_notifier_info fen6_info;
+ struct fib_rule_notifier_info fr_info;
+ };
+ struct rtl838x_switch_priv *priv;
+ bool is_fib6;
+ unsigned long event;
+};
+
+static void rtl83xx_fib_event_work_do(struct work_struct *work)
+{
+ struct rtl83xx_fib_event_work *fib_work =
+ container_of(work, struct rtl83xx_fib_event_work, work);
+ struct rtl838x_switch_priv *priv = fib_work->priv;
+ struct fib_rule *rule;
+ int err;
+
+ /* Protect internal structures from changes */
+ rtnl_lock();
+ pr_debug("%s: doing work, event %ld\n", __func__, fib_work->event);
+ switch (fib_work->event) {
+ case FIB_EVENT_ENTRY_ADD:
+ case FIB_EVENT_ENTRY_REPLACE:
+ case FIB_EVENT_ENTRY_APPEND:
+ if (fib_work->is_fib6) {
+ err = rtl83xx_fib6_add(priv, &fib_work->fen6_info);
+ } else {
+ err = rtl83xx_fib4_add(priv, &fib_work->fen_info);
+ fib_info_put(fib_work->fen_info.fi);
+ }
+ if (err)
+ pr_err("%s: FIB4 failed\n", __func__);
+ break;
+ case FIB_EVENT_ENTRY_DEL:
+ rtl83xx_fib4_del(priv, &fib_work->fen_info);
+ fib_info_put(fib_work->fen_info.fi);
+ break;
+ case FIB_EVENT_RULE_ADD:
+ case FIB_EVENT_RULE_DEL:
+ rule = fib_work->fr_info.rule;
+ if (!fib4_rule_default(rule))
+ pr_err("%s: FIB4 default rule failed\n", __func__);
+ fib_rule_put(rule);
+ break;
+ }
+ rtnl_unlock();
+ kfree(fib_work);
+}
+
+/* Called with rcu_read_lock() */
+static int rtl83xx_fib_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ struct fib_notifier_info *info = ptr;
+ struct rtl838x_switch_priv *priv;
+ struct rtl83xx_fib_event_work *fib_work;
+
+ if ((info->family != AF_INET && info->family != AF_INET6 &&
+ info->family != RTNL_FAMILY_IPMR &&
+ info->family != RTNL_FAMILY_IP6MR))
+ return NOTIFY_DONE;
+
+ priv = container_of(this, struct rtl838x_switch_priv, fib_nb);
+
+ fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC);
+ if (!fib_work)
+ return NOTIFY_BAD;
+
+ INIT_WORK(&fib_work->work, rtl83xx_fib_event_work_do);
+ fib_work->priv = priv;
+ fib_work->event = event;
+ fib_work->is_fib6 = false;
+
+ switch (event) {
+ case FIB_EVENT_ENTRY_ADD:
+ case FIB_EVENT_ENTRY_REPLACE:
+ case FIB_EVENT_ENTRY_APPEND:
+ case FIB_EVENT_ENTRY_DEL:
+ pr_debug("%s: FIB_ENTRY ADD/DEL, event %ld\n", __func__, event);
+ if (info->family == AF_INET) {
+ struct fib_entry_notifier_info *fen_info = ptr;
+
+ if (fen_info->fi->fib_nh_is_v6) {
+ NL_SET_ERR_MSG_MOD(info->extack,
+ "IPv6 gateway with IPv4 route is not supported");
+ kfree(fib_work);
+ return notifier_from_errno(-EINVAL);
+ }
+
+ memcpy(&fib_work->fen_info, ptr, sizeof(fib_work->fen_info));
+ /* Take referece on fib_info to prevent it from being
+ * freed while work is queued. Release it afterwards.
+ */
+ fib_info_hold(fib_work->fen_info.fi);
+
+ } else if (info->family == AF_INET6) {
+ //struct fib6_entry_notifier_info *fen6_info = ptr;
+ pr_warn("%s: FIB_RULE ADD/DEL for IPv6 not supported\n", __func__);
+ kfree(fib_work);
+ return NOTIFY_DONE;
+ }
+ break;
+
+ case FIB_EVENT_RULE_ADD:
+ case FIB_EVENT_RULE_DEL:
+ pr_debug("%s: FIB_RULE ADD/DEL, event: %ld\n", __func__, event);
+ memcpy(&fib_work->fr_info, ptr, sizeof(fib_work->fr_info));
+ fib_rule_get(fib_work->fr_info.rule);
+ break;
+ }
+
+ schedule_work(&fib_work->work);
+
+ return NOTIFY_DONE;
+}
+
+static int __init rtl83xx_sw_probe(struct platform_device *pdev)
+{
+ int i, err = 0;
+ struct rtl838x_switch_priv *priv;
+ struct device *dev = &pdev->dev;
+ u64 bpdu_mask;
+
+ pr_debug("Probing RTL838X switch device\n");
+ if (!pdev->dev.of_node) {
+ dev_err(dev, "No DT found\n");
+ return -EINVAL;
+ }
+
+ /* Initialize access to RTL switch tables */
+ rtl_table_init();
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
+
+ if (!priv->ds)
+ return -ENOMEM;
+ priv->ds->dev = dev;
+ priv->ds->priv = priv;
+ priv->ds->ops = &rtl83xx_switch_ops;
+ priv->ds->needs_standalone_vlan_filtering = true;
+ priv->dev = dev;
+
+ mutex_init(&priv->reg_mutex);
+
+ priv->family_id = soc_info.family;
+ priv->id = soc_info.id;
+ switch(soc_info.family) {
+ case RTL8380_FAMILY_ID:
+ priv->ds->ops = &rtl83xx_switch_ops;
+ priv->cpu_port = RTL838X_CPU_PORT;
+ priv->port_mask = 0x1f;
+ priv->port_width = 1;
+ priv->irq_mask = 0x0FFFFFFF;
+ priv->r = &rtl838x_reg;
+ priv->ds->num_ports = 29;
+ priv->fib_entries = 8192;
+ rtl8380_get_version(priv);
+ priv->n_lags = 8;
+ priv->l2_bucket_size = 4;
+ priv->n_pie_blocks = 12;
+ priv->port_ignore = 0x1f;
+ priv->n_counters = 128;
+ break;
+ case RTL8390_FAMILY_ID:
+ priv->ds->ops = &rtl83xx_switch_ops;
+ priv->cpu_port = RTL839X_CPU_PORT;
+ priv->port_mask = 0x3f;
+ priv->port_width = 2;
+ priv->irq_mask = 0xFFFFFFFFFFFFFULL;
+ priv->r = &rtl839x_reg;
+ priv->ds->num_ports = 53;
+ priv->fib_entries = 16384;
+ rtl8390_get_version(priv);
+ priv->n_lags = 16;
+ priv->l2_bucket_size = 4;
+ priv->n_pie_blocks = 18;
+ priv->port_ignore = 0x3f;
+ priv->n_counters = 1024;
+ break;
+ case RTL9300_FAMILY_ID:
+ priv->ds->ops = &rtl930x_switch_ops;
+ priv->cpu_port = RTL930X_CPU_PORT;
+ priv->port_mask = 0x1f;
+ priv->port_width = 1;
+ priv->irq_mask = 0x0FFFFFFF;
+ priv->r = &rtl930x_reg;
+ priv->ds->num_ports = 29;
+ priv->fib_entries = 16384;
+ priv->version = RTL8390_VERSION_A;
+ priv->n_lags = 16;
+ sw_w32(1, RTL930X_ST_CTRL);
+ priv->l2_bucket_size = 8;
+ priv->n_pie_blocks = 16;
+ priv->port_ignore = 0x3f;
+ priv->n_counters = 2048;
+ break;
+ case RTL9310_FAMILY_ID:
+ priv->ds->ops = &rtl930x_switch_ops;
+ priv->cpu_port = RTL931X_CPU_PORT;
+ priv->port_mask = 0x3f;
+ priv->port_width = 2;
+ priv->irq_mask = 0xFFFFFFFFFFFFFULL;
+ priv->r = &rtl931x_reg;
+ priv->ds->num_ports = 57;
+ priv->fib_entries = 16384;
+ priv->version = RTL8390_VERSION_A;
+ priv->n_lags = 16;
+ priv->l2_bucket_size = 8;
+ break;
+ }
+ pr_debug("Chip version %c\n", priv->version);
+
+ for (i = 0; i <= priv->cpu_port; i++) {
+ switch (soc_info.family) {
+ case RTL8380_FAMILY_ID:
+ case RTL8390_FAMILY_ID:
+ priv->pcs[i].pcs.ops = &rtl83xx_pcs_ops;
+ break;
+ case RTL9300_FAMILY_ID:
+ case RTL9310_FAMILY_ID:
+ priv->pcs[i].pcs.ops = &rtl93xx_pcs_ops;
+ break;
+ }
+ priv->pcs[i].pcs.neg_mode = true;
+ priv->pcs[i].priv = priv;
+ priv->pcs[i].port = i;
+ }
+
+ err = rtl83xx_mdio_probe(priv);
+ if (err) {
+ /* Probing fails the 1st time because of missing ethernet driver
+ * initialization. Use this to disable traffic in case the bootloader left if on
+ */
+ return err;
+ }
+
+ err = dsa_register_switch(priv->ds);
+ if (err) {
+ dev_err(dev, "Error registering switch: %d\n", err);
+ return err;
+ }
+
+ /* dsa_to_port returns dsa_port from the port list in
+ * dsa_switch_tree, the tree is built when the switch
+ * is registered by dsa_register_switch
+ */
+ for (int i = 0; i <= priv->cpu_port; i++)
+ priv->ports[i].dp = dsa_to_port(priv->ds, i);
+
+ /* Enable link and media change interrupts. Are the SERDES masks needed? */
+ sw_w32_mask(0, 3, priv->r->isr_glb_src);
+
+ priv->r->set_port_reg_le(priv->irq_mask, priv->r->isr_port_link_sts_chg);
+ priv->r->set_port_reg_le(priv->irq_mask, priv->r->imr_port_link_sts_chg);
+
+ priv->link_state_irq = platform_get_irq(pdev, 0);
+ pr_info("LINK state irq: %d\n", priv->link_state_irq);
+ switch (priv->family_id) {
+ case RTL8380_FAMILY_ID:
+ err = request_irq(priv->link_state_irq, rtl838x_switch_irq,
+ IRQF_SHARED, "rtl838x-link-state", priv->ds);
+ break;
+ case RTL8390_FAMILY_ID:
+ err = request_irq(priv->link_state_irq, rtl839x_switch_irq,
+ IRQF_SHARED, "rtl839x-link-state", priv->ds);
+ break;
+ case RTL9300_FAMILY_ID:
+ err = request_irq(priv->link_state_irq, rtl930x_switch_irq,
+ IRQF_SHARED, "rtl930x-link-state", priv->ds);
+ break;
+ case RTL9310_FAMILY_ID:
+ err = request_irq(priv->link_state_irq, rtl931x_switch_irq,
+ IRQF_SHARED, "rtl931x-link-state", priv->ds);
+ break;
+ }
+ if (err) {
+ dev_err(dev, "Error setting up switch interrupt.\n");
+ /* Need to free allocated switch here */
+ }
+
+ /* Enable interrupts for switch, on RTL931x, the IRQ is always on globally */
+ if (soc_info.family != RTL9310_FAMILY_ID)
+ sw_w32(0x1, priv->r->imr_glb);
+
+ rtl83xx_get_l2aging(priv);
+
+ rtl83xx_setup_qos(priv);
+
+ priv->r->l3_setup(priv);
+
+ /* Clear all destination ports for mirror groups */
+ for (int i = 0; i < 4; i++)
+ priv->mirror_group_ports[i] = -1;
+
+ /* Register netdevice event callback to catch changes in link aggregation groups */
+ priv->nb.notifier_call = rtl83xx_netdevice_event;
+ if (register_netdevice_notifier(&priv->nb)) {
+ priv->nb.notifier_call = NULL;
+ dev_err(dev, "Failed to register LAG netdev notifier\n");
+ goto err_register_nb;
+ }
+
+ /* Initialize hash table for L3 routing */
+ rhltable_init(&priv->routes, &route_ht_params);
+
+ /* Register netevent notifier callback to catch notifications about neighboring
+ * changes to update nexthop entries for L3 routing.
+ */
+ priv->ne_nb.notifier_call = rtl83xx_netevent_event;
+ if (register_netevent_notifier(&priv->ne_nb)) {
+ priv->ne_nb.notifier_call = NULL;
+ dev_err(dev, "Failed to register netevent notifier\n");
+ goto err_register_ne_nb;
+ }
+
+ priv->fib_nb.notifier_call = rtl83xx_fib_event;
+
+ /* Register Forwarding Information Base notifier to offload routes where
+ * where possible
+ * Only FIBs pointing to our own netdevs are programmed into
+ * the device, so no need to pass a callback.
+ */
+ err = register_fib_notifier(&init_net, &priv->fib_nb, NULL, NULL);
+ if (err)
+ goto err_register_fib_nb;
+
+ /* TODO: put this into l2_setup() */
+ /* Flood BPDUs to all ports including cpu-port */
+ if (soc_info.family != RTL9300_FAMILY_ID) {
+ bpdu_mask = soc_info.family == RTL8380_FAMILY_ID ? 0x1FFFFFFF : 0x1FFFFFFFFFFFFF;
+ priv->r->set_port_reg_be(bpdu_mask, priv->r->rma_bpdu_fld_pmask);
+
+ /* TRAP 802.1X frames (EAPOL) to the CPU-Port, bypass STP and VLANs */
+ sw_w32(7, priv->r->spcl_trap_eapol_ctrl);
+
+ rtl838x_dbgfs_init(priv);
+ } else {
+ rtl930x_dbgfs_init(priv);
+ }
+
+ return 0;
+
+err_register_fib_nb:
+ unregister_netevent_notifier(&priv->ne_nb);
+err_register_ne_nb:
+ unregister_netdevice_notifier(&priv->nb);
+err_register_nb:
+ return err;
+}
+
+static int rtl83xx_sw_remove(struct platform_device *pdev)
+{
+ /* TODO: */
+ pr_debug("Removing platform driver for rtl83xx-sw\n");
+
+ return 0;
+}
+
+static const struct of_device_id rtl83xx_switch_of_ids[] = {
+ { .compatible = "realtek,rtl83xx-switch"},
+ { /* sentinel */ }
+};
+
+
+MODULE_DEVICE_TABLE(of, rtl83xx_switch_of_ids);
+
+static struct platform_driver rtl83xx_switch_driver = {
+ .probe = rtl83xx_sw_probe,
+ .remove = rtl83xx_sw_remove,
+ .driver = {
+ .name = "rtl83xx-switch",
+ .pm = NULL,
+ .of_match_table = rtl83xx_switch_of_ids,
+ },
+};
+
+module_platform_driver(rtl83xx_switch_driver);
+
+MODULE_AUTHOR("B. Koblitz");
+MODULE_DESCRIPTION("RTL83XX SoC Switch Driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/debugfs.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/debugfs.c
index 92d6932dc5..92d6932dc5 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/debugfs.c
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/debugfs.c
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
new file mode 100644
index 0000000000..d61122e330
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
@@ -0,0 +1,2284 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <net/dsa.h>
+#include <linux/etherdevice.h>
+#include <linux/if_bridge.h>
+#include <asm/mach-rtl838x/mach-rtl83xx.h>
+
+#include "rtl83xx.h"
+
+extern struct rtl83xx_soc_info soc_info;
+
+static void rtl83xx_init_stats(struct rtl838x_switch_priv *priv)
+{
+ mutex_lock(&priv->reg_mutex);
+
+ /* Enable statistics module: all counters plus debug.
+ * On RTL839x all counters are enabled by default
+ */
+ if (priv->family_id == RTL8380_FAMILY_ID)
+ sw_w32_mask(0, 3, RTL838X_STAT_CTRL);
+
+ /* Reset statistics counters */
+ sw_w32_mask(0, 1, priv->r->stat_rst);
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
+static void rtl83xx_enable_phy_polling(struct rtl838x_switch_priv *priv)
+{
+ u64 v = 0;
+
+ msleep(1000);
+ /* Enable all ports with a PHY, including the SFP-ports */
+ for (int i = 0; i < priv->cpu_port; i++) {
+ if (priv->ports[i].phy)
+ v |= BIT_ULL(i);
+ }
+
+ pr_info("%s: %16llx\n", __func__, v);
+ priv->r->set_port_reg_le(v, priv->r->smi_poll_ctrl);
+
+ /* PHY update complete, there is no global PHY polling enable bit on the 9300 */
+ if (priv->family_id == RTL8390_FAMILY_ID)
+ sw_w32_mask(0, BIT(7), RTL839X_SMI_GLB_CTRL);
+ else if(priv->family_id == RTL9300_FAMILY_ID)
+ sw_w32_mask(0, 0x8000, RTL838X_SMI_GLB_CTRL);
+}
+
+const struct rtl83xx_mib_desc rtl83xx_mib[] = {
+ MIB_DESC(2, 0xf8, "ifInOctets"),
+ MIB_DESC(2, 0xf0, "ifOutOctets"),
+ MIB_DESC(1, 0xec, "dot1dTpPortInDiscards"),
+ MIB_DESC(1, 0xe8, "ifInUcastPkts"),
+ MIB_DESC(1, 0xe4, "ifInMulticastPkts"),
+ MIB_DESC(1, 0xe0, "ifInBroadcastPkts"),
+ MIB_DESC(1, 0xdc, "ifOutUcastPkts"),
+ MIB_DESC(1, 0xd8, "ifOutMulticastPkts"),
+ MIB_DESC(1, 0xd4, "ifOutBroadcastPkts"),
+ MIB_DESC(1, 0xd0, "ifOutDiscards"),
+ MIB_DESC(1, 0xcc, ".3SingleCollisionFrames"),
+ MIB_DESC(1, 0xc8, ".3MultipleCollisionFrames"),
+ MIB_DESC(1, 0xc4, ".3DeferredTransmissions"),
+ MIB_DESC(1, 0xc0, ".3LateCollisions"),
+ MIB_DESC(1, 0xbc, ".3ExcessiveCollisions"),
+ MIB_DESC(1, 0xb8, ".3SymbolErrors"),
+ MIB_DESC(1, 0xb4, ".3ControlInUnknownOpcodes"),
+ MIB_DESC(1, 0xb0, ".3InPauseFrames"),
+ MIB_DESC(1, 0xac, ".3OutPauseFrames"),
+ MIB_DESC(1, 0xa8, "DropEvents"),
+ MIB_DESC(1, 0xa4, "tx_BroadcastPkts"),
+ MIB_DESC(1, 0xa0, "tx_MulticastPkts"),
+ MIB_DESC(1, 0x9c, "CRCAlignErrors"),
+ MIB_DESC(1, 0x98, "tx_UndersizePkts"),
+ MIB_DESC(1, 0x94, "rx_UndersizePkts"),
+ MIB_DESC(1, 0x90, "rx_UndersizedropPkts"),
+ MIB_DESC(1, 0x8c, "tx_OversizePkts"),
+ MIB_DESC(1, 0x88, "rx_OversizePkts"),
+ MIB_DESC(1, 0x84, "Fragments"),
+ MIB_DESC(1, 0x80, "Jabbers"),
+ MIB_DESC(1, 0x7c, "Collisions"),
+ MIB_DESC(1, 0x78, "tx_Pkts64Octets"),
+ MIB_DESC(1, 0x74, "rx_Pkts64Octets"),
+ MIB_DESC(1, 0x70, "tx_Pkts65to127Octets"),
+ MIB_DESC(1, 0x6c, "rx_Pkts65to127Octets"),
+ MIB_DESC(1, 0x68, "tx_Pkts128to255Octets"),
+ MIB_DESC(1, 0x64, "rx_Pkts128to255Octets"),
+ MIB_DESC(1, 0x60, "tx_Pkts256to511Octets"),
+ MIB_DESC(1, 0x5c, "rx_Pkts256to511Octets"),
+ MIB_DESC(1, 0x58, "tx_Pkts512to1023Octets"),
+ MIB_DESC(1, 0x54, "rx_Pkts512to1023Octets"),
+ MIB_DESC(1, 0x50, "tx_Pkts1024to1518Octets"),
+ MIB_DESC(1, 0x4c, "rx_StatsPkts1024to1518Octets"),
+ MIB_DESC(1, 0x48, "tx_Pkts1519toMaxOctets"),
+ MIB_DESC(1, 0x44, "rx_Pkts1519toMaxOctets"),
+ MIB_DESC(1, 0x40, "rxMacDiscards")
+};
+
+
+/* DSA callbacks */
+
+
+static enum dsa_tag_protocol rtl83xx_get_tag_protocol(struct dsa_switch *ds,
+ int port,
+ enum dsa_tag_protocol mprot)
+{
+ /* The switch does not tag the frames, instead internally the header
+ * structure for each packet is tagged accordingly.
+ */
+ return DSA_TAG_PROTO_TRAILER;
+}
+
+static void rtl83xx_vlan_set_pvid(struct rtl838x_switch_priv *priv,
+ int port, int pvid)
+{
+ /* Set both inner and outer PVID of the port */
+ priv->r->vlan_port_pvid_set(port, PBVLAN_TYPE_INNER, pvid);
+ priv->r->vlan_port_pvid_set(port, PBVLAN_TYPE_OUTER, pvid);
+ priv->r->vlan_port_pvidmode_set(port, PBVLAN_TYPE_INNER,
+ PBVLAN_MODE_UNTAG_AND_PRITAG);
+ priv->r->vlan_port_pvidmode_set(port, PBVLAN_TYPE_OUTER,
+ PBVLAN_MODE_UNTAG_AND_PRITAG);
+
+ priv->ports[port].pvid = pvid;
+}
+
+/* Initialize all VLANS */
+static void rtl83xx_vlan_setup(struct rtl838x_switch_priv *priv)
+{
+ struct rtl838x_vlan_info info;
+
+ pr_info("In %s\n", __func__);
+
+ priv->r->vlan_profile_setup(0);
+ priv->r->vlan_profile_setup(1);
+ pr_info("UNKNOWN_MC_PMASK: %016llx\n", priv->r->read_mcast_pmask(UNKNOWN_MC_PMASK));
+ priv->r->vlan_profile_dump(0);
+
+ info.fid = 0; /* Default Forwarding ID / MSTI */
+ info.hash_uc_fid = false; /* Do not build the L2 lookup hash with FID, but VID */
+ info.hash_mc_fid = false; /* Do the same for Multicast packets */
+ info.profile_id = 0; /* Use default Vlan Profile 0 */
+ info.tagged_ports = 0; /* Initially no port members */
+ if (priv->family_id == RTL9310_FAMILY_ID) {
+ info.if_id = 0;
+ info.multicast_grp_mask = 0;
+ info.l2_tunnel_list_id = -1;
+ }
+
+ /* Initialize normal VLANs 1-4095 */
+ for (int i = 1; i < MAX_VLANS; i ++)
+ priv->r->vlan_set_tagged(i, &info);
+
+ /*
+ * Initialize the special VLAN 0 and reset PVIDs. The CPU port PVID
+ * is applied to packets from the CPU for untagged destinations,
+ * regardless if the actual ingress VID. Any port with untagged
+ * egress VLAN(s) must therefore be a member of VLAN 0 to support
+ * CPU port as ingress when VLAN filtering is enabled.
+ */
+ for (int i = 0; i <= priv->cpu_port; i++) {
+ rtl83xx_vlan_set_pvid(priv, i, 0);
+ info.tagged_ports |= BIT_ULL(i);
+ }
+ priv->r->vlan_set_tagged(0, &info);
+
+ /* Set forwarding action based on inner VLAN tag */
+ for (int i = 0; i < priv->cpu_port; i++)
+ priv->r->vlan_fwd_on_inner(i, true);
+}
+
+static void rtl83xx_setup_bpdu_traps(struct rtl838x_switch_priv *priv)
+{
+ for (int i = 0; i < priv->cpu_port; i++)
+ priv->r->set_receive_management_action(i, BPDU, TRAP2CPU);
+}
+
+static void rtl83xx_setup_lldp_traps(struct rtl838x_switch_priv *priv)
+{
+ for (int i = 0; i < priv->cpu_port; i++)
+ priv->r->set_receive_management_action(i, LLDP, TRAP2CPU);
+}
+
+static void rtl83xx_port_set_salrn(struct rtl838x_switch_priv *priv,
+ int port, bool enable)
+{
+ int shift = SALRN_PORT_SHIFT(port);
+ int val = enable ? SALRN_MODE_HARDWARE : SALRN_MODE_DISABLED;
+
+ sw_w32_mask(SALRN_MODE_MASK << shift, val << shift,
+ priv->r->l2_port_new_salrn(port));
+}
+
+static int rtl83xx_setup(struct dsa_switch *ds)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ pr_debug("%s called\n", __func__);
+
+ /* Disable MAC polling the PHY so that we can start configuration */
+ priv->r->set_port_reg_le(0ULL, priv->r->smi_poll_ctrl);
+
+ for (int i = 0; i < ds->num_ports; i++)
+ priv->ports[i].enable = false;
+ priv->ports[priv->cpu_port].enable = true;
+
+ /* Configure ports so they are disabled by default, but once enabled
+ * they will work in isolated mode (only traffic between port and CPU).
+ */
+ for (int i = 0; i < priv->cpu_port; i++) {
+ if (priv->ports[i].phy) {
+ priv->ports[i].pm = BIT_ULL(priv->cpu_port);
+ priv->r->traffic_set(i, BIT_ULL(i));
+ }
+ }
+ priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port));
+
+ /* For standalone ports, forward packets even if a static fdb
+ * entry for the source address exists on another port.
+ */
+ if (priv->r->set_static_move_action) {
+ for (int i = 0; i <= priv->cpu_port; i++)
+ priv->r->set_static_move_action(i, true);
+ }
+
+ if (priv->family_id == RTL8380_FAMILY_ID)
+ rtl838x_print_matrix();
+ else
+ rtl839x_print_matrix();
+
+ rtl83xx_init_stats(priv);
+
+ rtl83xx_vlan_setup(priv);
+
+ rtl83xx_setup_bpdu_traps(priv);
+ rtl83xx_setup_lldp_traps(priv);
+
+ ds->configure_vlan_while_not_filtering = true;
+
+ priv->r->l2_learning_setup();
+
+ rtl83xx_port_set_salrn(priv, priv->cpu_port, false);
+ ds->assisted_learning_on_cpu_port = true;
+
+ /* Make sure all frames sent to the switch's MAC are trapped to the CPU-port
+ * 0: FWD, 1: DROP, 2: TRAP2CPU
+ */
+ if (priv->family_id == RTL8380_FAMILY_ID)
+ sw_w32(0x2, RTL838X_SPCL_TRAP_SWITCH_MAC_CTRL);
+ else
+ sw_w32(0x2, RTL839X_SPCL_TRAP_SWITCH_MAC_CTRL);
+
+ /* Enable MAC Polling PHY again */
+ rtl83xx_enable_phy_polling(priv);
+ pr_debug("Please wait until PHY is settled\n");
+ msleep(1000);
+ priv->r->pie_init(priv);
+
+ return 0;
+}
+
+static int rtl93xx_setup(struct dsa_switch *ds)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ pr_info("%s called\n", __func__);
+
+ /* Disable MAC polling the PHY so that we can start configuration */
+ if (priv->family_id == RTL9300_FAMILY_ID)
+ sw_w32(0, RTL930X_SMI_POLL_CTRL);
+
+ if (priv->family_id == RTL9310_FAMILY_ID) {
+ sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL);
+ sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL + 4);
+ }
+
+ /* Disable all ports except CPU port */
+ for (int i = 0; i < ds->num_ports; i++)
+ priv->ports[i].enable = false;
+ priv->ports[priv->cpu_port].enable = true;
+
+ /* Configure ports so they are disabled by default, but once enabled
+ * they will work in isolated mode (only traffic between port and CPU).
+ */
+ for (int i = 0; i < priv->cpu_port; i++) {
+ if (priv->ports[i].phy) {
+ priv->ports[i].pm = BIT_ULL(priv->cpu_port);
+ priv->r->traffic_set(i, BIT_ULL(i));
+ }
+ }
+ priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port));
+
+ rtl930x_print_matrix();
+
+ /* TODO: Initialize statistics */
+
+ rtl83xx_vlan_setup(priv);
+
+ ds->configure_vlan_while_not_filtering = true;
+
+ priv->r->l2_learning_setup();
+
+ rtl83xx_port_set_salrn(priv, priv->cpu_port, false);
+ ds->assisted_learning_on_cpu_port = true;
+
+ rtl83xx_enable_phy_polling(priv);
+
+ priv->r->pie_init(priv);
+
+ priv->r->led_init(priv);
+
+ return 0;
+}
+
+static int rtl93xx_get_sds(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ struct device_node *dn;
+ u32 sds_num;
+
+ if (!dev)
+ return -1;
+ if (dev->of_node) {
+ dn = dev->of_node;
+ if (of_property_read_u32(dn, "sds", &sds_num))
+ sds_num = -1;
+ } else {
+ dev_err(dev, "No DT node.\n");
+ return -1;
+ }
+
+ return sds_num;
+}
+
+static int rtl83xx_pcs_validate(struct phylink_pcs *pcs,
+ unsigned long *supported,
+ const struct phylink_link_state *state)
+{
+ struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs);
+ struct rtl838x_switch_priv *priv = rtpcs->priv;
+ int port = rtpcs->port;
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+ pr_debug("In %s port %d, state is %d", __func__, port, state->interface);
+
+ if (!phy_interface_mode_is_rgmii(state->interface) &&
+ state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != PHY_INTERFACE_MODE_1000BASEX &&
+ state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_REVMII &&
+ state->interface != PHY_INTERFACE_MODE_GMII &&
+ state->interface != PHY_INTERFACE_MODE_QSGMII &&
+ state->interface != PHY_INTERFACE_MODE_INTERNAL &&
+ state->interface != PHY_INTERFACE_MODE_SGMII) {
+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ dev_err(priv->ds->dev,
+ "Unsupported interface: %d for port %d\n",
+ state->interface, port);
+ return -EINVAL;
+ }
+
+ /* Allow all the expected bits */
+ phylink_set(mask, Autoneg);
+ phylink_set_port_modes(mask);
+ phylink_set(mask, Pause);
+ phylink_set(mask, Asym_Pause);
+
+ /* With the exclusion of MII and Reverse MII, we support Gigabit,
+ * including Half duplex
+ */
+ if (state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_REVMII) {
+ phylink_set(mask, 1000baseT_Full);
+ phylink_set(mask, 1000baseT_Half);
+ }
+
+ /* On both the 8380 and 8382, ports 24-27 are SFP ports */
+ if (port >= 24 && port <= 27 && priv->family_id == RTL8380_FAMILY_ID)
+ phylink_set(mask, 1000baseX_Full);
+
+ /* On the RTL839x family of SoCs, ports 48 to 51 are SFP ports */
+ if (port >= 48 && port <= 51 && priv->family_id == RTL8390_FAMILY_ID)
+ phylink_set(mask, 1000baseX_Full);
+
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 100baseT_Full);
+
+ bitmap_and(supported, supported, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+
+ return 0;
+}
+
+static int rtl93xx_pcs_validate(struct phylink_pcs *pcs,
+ unsigned long *supported,
+ const struct phylink_link_state *state)
+{
+ struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs);
+ struct rtl838x_switch_priv *priv = rtpcs->priv;
+ int port = rtpcs->port;
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+ pr_debug("In %s port %d, state is %d (%s)", __func__, port, state->interface,
+ phy_modes(state->interface));
+
+ if (!phy_interface_mode_is_rgmii(state->interface) &&
+ state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != PHY_INTERFACE_MODE_1000BASEX &&
+ state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_REVMII &&
+ state->interface != PHY_INTERFACE_MODE_GMII &&
+ state->interface != PHY_INTERFACE_MODE_QSGMII &&
+ state->interface != PHY_INTERFACE_MODE_XGMII &&
+ state->interface != PHY_INTERFACE_MODE_HSGMII &&
+ state->interface != PHY_INTERFACE_MODE_10GBASER &&
+ state->interface != PHY_INTERFACE_MODE_10GKR &&
+ state->interface != PHY_INTERFACE_MODE_USXGMII &&
+ state->interface != PHY_INTERFACE_MODE_INTERNAL &&
+ state->interface != PHY_INTERFACE_MODE_SGMII) {
+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ dev_err(priv->ds->dev,
+ "Unsupported interface: %d for port %d\n",
+ state->interface, port);
+ return -EINVAL;
+ }
+
+ /* Allow all the expected bits */
+ phylink_set(mask, Autoneg);
+ phylink_set_port_modes(mask);
+ phylink_set(mask, Pause);
+ phylink_set(mask, Asym_Pause);
+
+ /* With the exclusion of MII and Reverse MII, we support Gigabit,
+ * including Half duplex
+ */
+ if (state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_REVMII) {
+ phylink_set(mask, 1000baseT_Full);
+ phylink_set(mask, 1000baseT_Half);
+ }
+
+ /* Internal phys of the RTL93xx family provide 10G */
+ if (priv->ports[port].phy_is_integrated &&
+ state->interface == PHY_INTERFACE_MODE_1000BASEX) {
+ phylink_set(mask, 1000baseX_Full);
+ } else if (priv->ports[port].phy_is_integrated) {
+ phylink_set(mask, 1000baseX_Full);
+ phylink_set(mask, 10000baseKR_Full);
+ phylink_set(mask, 10000baseSR_Full);
+ phylink_set(mask, 10000baseCR_Full);
+ }
+ if (state->interface == PHY_INTERFACE_MODE_INTERNAL) {
+ phylink_set(mask, 1000baseX_Full);
+ phylink_set(mask, 1000baseT_Full);
+ phylink_set(mask, 10000baseKR_Full);
+ phylink_set(mask, 10000baseT_Full);
+ phylink_set(mask, 10000baseSR_Full);
+ phylink_set(mask, 10000baseCR_Full);
+ }
+
+ if (state->interface == PHY_INTERFACE_MODE_USXGMII) {
+ phylink_set(mask, 2500baseT_Full);
+ phylink_set(mask, 5000baseT_Full);
+ phylink_set(mask, 10000baseT_Full);
+ }
+
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 100baseT_Full);
+
+ bitmap_and(supported, supported, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ pr_debug("%s leaving supported: %*pb", __func__, __ETHTOOL_LINK_MODE_MASK_NBITS, supported);
+
+ return 0;
+}
+
+static void rtl83xx_pcs_get_state(struct phylink_pcs *pcs,
+ struct phylink_link_state *state)
+{
+ struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs);
+ struct rtl838x_switch_priv *priv = rtpcs->priv;
+ int port = rtpcs->port;
+ u64 speed;
+ u64 link;
+
+ if (port < 0 || port > priv->cpu_port) {
+ state->link = false;
+ return;
+ }
+
+ state->link = 0;
+ link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
+ if (link & BIT_ULL(port))
+ state->link = 1;
+ pr_debug("%s: link state port %d: %llx\n", __func__, port, link & BIT_ULL(port));
+
+ state->duplex = 0;
+ if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
+ state->duplex = 1;
+
+ speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
+ speed >>= (port % 16) << 1;
+ switch (speed & 0x3) {
+ case 0:
+ state->speed = SPEED_10;
+ break;
+ case 1:
+ state->speed = SPEED_100;
+ break;
+ case 2:
+ state->speed = SPEED_1000;
+ break;
+ case 3:
+ if (priv->family_id == RTL9300_FAMILY_ID
+ && (port == 24 || port == 26)) /* Internal serdes */
+ state->speed = SPEED_2500;
+ else
+ state->speed = SPEED_100; /* Is in fact 500Mbit */
+ }
+
+ state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
+ if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
+ state->pause |= MLO_PAUSE_RX;
+ if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
+ state->pause |= MLO_PAUSE_TX;
+}
+
+static void rtl93xx_pcs_get_state(struct phylink_pcs *pcs,
+ struct phylink_link_state *state)
+{
+ struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs);
+ struct rtl838x_switch_priv *priv = rtpcs->priv;
+ int port = rtpcs->port;
+ u64 speed;
+ u64 link;
+ u64 media;
+
+ if (port < 0 || port > priv->cpu_port) {
+ state->link = false;
+ return;
+ }
+
+ /* On the RTL9300 for at least the RTL8226B PHY, the MAC-side link
+ * state needs to be read twice in order to read a correct result.
+ * This would not be necessary for ports connected e.g. to RTL8218D
+ * PHYs.
+ */
+ state->link = 0;
+ link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
+ link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
+ if (link & BIT_ULL(port))
+ state->link = 1;
+
+ if (priv->family_id == RTL9310_FAMILY_ID)
+ media = priv->r->get_port_reg_le(RTL931X_MAC_LINK_MEDIA_STS);
+
+ if (priv->family_id == RTL9300_FAMILY_ID)
+ media = sw_r32(RTL930X_MAC_LINK_MEDIA_STS);
+
+ if (media & BIT_ULL(port))
+ state->link = 1;
+
+ pr_debug("%s: link state port %d: %llx, media %llx\n", __func__, port,
+ link & BIT_ULL(port), media);
+
+ state->duplex = 0;
+ if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
+ state->duplex = 1;
+
+ speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
+ speed >>= (port % 8) << 2;
+ switch (speed & 0xf) {
+ case 0:
+ state->speed = SPEED_10;
+ break;
+ case 1:
+ state->speed = SPEED_100;
+ break;
+ case 2:
+ case 7:
+ state->speed = SPEED_1000;
+ break;
+ case 4:
+ state->speed = SPEED_10000;
+ break;
+ case 5:
+ case 8:
+ state->speed = SPEED_2500;
+ break;
+ case 6:
+ state->speed = SPEED_5000;
+ break;
+ default:
+ pr_err("%s: unknown speed: %d\n", __func__, (u32)speed & 0xf);
+ }
+
+ if (priv->family_id == RTL9310_FAMILY_ID
+ && (port >= 52 && port <= 55)) { /* Internal serdes */
+ state->speed = SPEED_10000;
+ state->link = 1;
+ state->duplex = 1;
+ }
+
+ pr_debug("%s: speed is: %d %d\n", __func__, (u32)speed & 0xf, state->speed);
+ state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
+ if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
+ state->pause |= MLO_PAUSE_RX;
+ if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
+ state->pause |= MLO_PAUSE_TX;
+}
+
+static int rtl83xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+ phy_interface_t interface,
+ const unsigned long *advertising,
+ bool permit_pause_to_mac)
+{
+ return 0;
+}
+
+static void rtl83xx_pcs_an_restart(struct phylink_pcs *pcs)
+{
+/* No restart functionality existed before we migrated to pcs */
+}
+
+static struct phylink_pcs *rtl83xx_phylink_mac_select_pcs(struct dsa_switch *ds,
+ int port,
+ phy_interface_t interface)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ return &priv->pcs[port].pcs;
+}
+
+static void rtl83xx_config_interface(int port, phy_interface_t interface)
+{
+ u32 old, int_shift, sds_shift;
+
+ switch (port) {
+ case 24:
+ int_shift = 0;
+ sds_shift = 5;
+ break;
+ case 26:
+ int_shift = 3;
+ sds_shift = 0;
+ break;
+ default:
+ return;
+ }
+
+ old = sw_r32(RTL838X_SDS_MODE_SEL);
+ switch (interface) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ if ((old >> sds_shift & 0x1f) == 4)
+ return;
+ sw_w32_mask(0x7 << int_shift, 1 << int_shift, RTL838X_INT_MODE_CTRL);
+ sw_w32_mask(0x1f << sds_shift, 4 << sds_shift, RTL838X_SDS_MODE_SEL);
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ if ((old >> sds_shift & 0x1f) == 2)
+ return;
+ sw_w32_mask(0x7 << int_shift, 2 << int_shift, RTL838X_INT_MODE_CTRL);
+ sw_w32_mask(0x1f << sds_shift, 2 << sds_shift, RTL838X_SDS_MODE_SEL);
+ break;
+ default:
+ return;
+ }
+ pr_debug("configured port %d for interface %s\n", port, phy_modes(interface));
+}
+
+static void rtl83xx_phylink_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+/*
+ * This capability check will need some love. Depending on the model and the port
+ * different link modes are supported. For now just enable all required values
+ * so that we can make use of the ports.
+ */
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_GMII, config->supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_QSGMII, config->supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_SGMII, config->supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_XGMII, config->supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, config->supported_interfaces);
+}
+
+static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ const struct phylink_link_state *state)
+{
+ struct dsa_port *dp = dsa_to_port(ds, port);
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u32 mcr;
+
+ pr_debug("%s port %d, mode %x\n", __func__, port, mode);
+
+ /* currently only needed for RTL8380 */
+ if (priv->family_id != RTL8380_FAMILY_ID)
+ return;
+
+ if (dsa_port_is_cpu(dp)) {
+ /* allow CRC errors on CPU-port */
+ sw_w32_mask(0, 0x8, priv->r->mac_port_ctrl(port));
+ return;
+ }
+
+ mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
+ if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
+ pr_debug("port %d PHY autonegotiates\n", port);
+ rtl83xx_config_interface(port, state->interface);
+ mcr |= RTL838X_NWAY_EN;
+ } else {
+ mcr &= ~RTL838X_NWAY_EN;
+ }
+ sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
+}
+
+static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ const struct phylink_link_state *state)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int sds_num;
+ u32 reg, band;
+
+ sds_num = priv->ports[port].sds_num;
+ pr_info("%s: speed %d sds_num %d\n", __func__, state->speed, sds_num);
+
+ switch (state->interface) {
+ case PHY_INTERFACE_MODE_HSGMII:
+ pr_info("%s setting mode PHY_INTERFACE_MODE_HSGMII\n", __func__);
+ band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_HSGMII);
+ rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_HSGMII);
+ band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_HSGMII);
+ break;
+ case PHY_INTERFACE_MODE_1000BASEX:
+ band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_1000BASEX);
+ rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_1000BASEX);
+ break;
+ case PHY_INTERFACE_MODE_XGMII:
+ band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_XGMII);
+ rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_XGMII);
+ break;
+ case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_10GKR:
+ band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_10GBASER);
+ rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_10GBASER);
+ break;
+ case PHY_INTERFACE_MODE_USXGMII:
+ /* Translates to MII_USXGMII_10GSXGMII */
+ band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_USXGMII);
+ rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_USXGMII);
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ pr_info("%s setting mode PHY_INTERFACE_MODE_SGMII\n", __func__);
+ band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_SGMII);
+ rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_SGMII);
+ band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_SGMII);
+ break;
+ case PHY_INTERFACE_MODE_QSGMII:
+ band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_QSGMII);
+ rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_QSGMII);
+ break;
+ default:
+ pr_err("%s: unknown serdes mode: %s\n",
+ __func__, phy_modes(state->interface));
+ return;
+ }
+
+ reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
+ pr_info("%s reading FORCE_MODE_CTRL: %08x\n", __func__, reg);
+
+ reg &= ~(RTL931X_DUPLEX_MODE | RTL931X_FORCE_EN | RTL931X_FORCE_LINK_EN);
+
+ reg &= ~(0xf << 12);
+ reg |= 0x2 << 12; /* Set SMI speed to 0x2 */
+
+ reg |= RTL931X_TX_PAUSE_EN | RTL931X_RX_PAUSE_EN;
+
+ if (priv->lagmembers & BIT_ULL(port))
+ reg |= RTL931X_DUPLEX_MODE;
+
+ if (state->duplex == DUPLEX_FULL)
+ reg |= RTL931X_DUPLEX_MODE;
+
+ sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
+
+}
+
+static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ const struct phylink_link_state *state)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int sds_num;
+ u32 reg;
+
+ pr_info("%s port %d, mode %x, phy-mode: %s, speed %d, link %d\n", __func__,
+ port, mode, phy_modes(state->interface), state->speed, state->link);
+
+ /* Nothing to be done for the CPU-port */
+ if (port == priv->cpu_port)
+ return;
+
+ if (priv->family_id == RTL9310_FAMILY_ID)
+ return rtl931x_phylink_mac_config(ds, port, mode, state);
+
+ sds_num = priv->ports[port].sds_num;
+ pr_info("%s SDS is %d\n", __func__, sds_num);
+ if (sds_num >= 0 &&
+ (state->interface == PHY_INTERFACE_MODE_1000BASEX ||
+ state->interface == PHY_INTERFACE_MODE_10GBASER))
+ rtl9300_serdes_setup(port, sds_num, state->interface);
+
+ reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
+ reg &= ~(0xf << 3);
+
+ switch (state->speed) {
+ case SPEED_10000:
+ reg |= 4 << 3;
+ break;
+ case SPEED_5000:
+ reg |= 6 << 3;
+ break;
+ case SPEED_2500:
+ reg |= 5 << 3;
+ break;
+ case SPEED_1000:
+ reg |= 2 << 3;
+ break;
+ case SPEED_100:
+ reg |= 1 << 3;
+ break;
+ default:
+ /* Also covers 10M */
+ break;
+ }
+
+ if (state->link)
+ reg |= RTL930X_FORCE_LINK_EN;
+
+ if (priv->lagmembers & BIT_ULL(port))
+ reg |= RTL930X_DUPLEX_MODE | RTL930X_FORCE_LINK_EN;
+
+ if (state->duplex == DUPLEX_FULL)
+ reg |= RTL930X_DUPLEX_MODE;
+ else
+ reg &= ~RTL930X_DUPLEX_MODE; /* Clear duplex bit otherwise */
+
+ if (priv->ports[port].phy_is_integrated)
+ reg &= ~RTL930X_FORCE_EN; /* Clear MAC_FORCE_EN to allow SDS-MAC link */
+ else
+ reg |= RTL930X_FORCE_EN;
+
+ sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
+}
+
+static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ phy_interface_t interface)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int mask = 0;
+
+ /* Stop TX/RX to port */
+ sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
+
+ /* No longer force link */
+ mask = RTL83XX_FORCE_EN | RTL83XX_FORCE_LINK_EN;
+ sw_w32_mask(mask, 0, priv->r->mac_force_mode_ctrl(port));
+}
+
+static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ phy_interface_t interface)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u32 v = 0;
+
+ /* Stop TX/RX to port */
+ sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
+
+ /* No longer force link */
+ if (priv->family_id == RTL9300_FAMILY_ID)
+ v = RTL930X_FORCE_EN | RTL930X_FORCE_LINK_EN;
+ else if (priv->family_id == RTL9310_FAMILY_ID)
+ v = RTL931X_FORCE_EN | RTL931X_FORCE_LINK_EN;
+ sw_w32_mask(v, 0, priv->r->mac_force_mode_ctrl(port));
+}
+
+static void rtl83xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ phy_interface_t interface,
+ struct phy_device *phydev,
+ int speed, int duplex,
+ bool tx_pause, bool rx_pause)
+{
+ struct dsa_port *dp = dsa_to_port(ds, port);
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u32 mcr, spdsel;
+
+ if (speed == SPEED_1000)
+ spdsel = RTL_SPEED_1000;
+ else if (speed == SPEED_100)
+ spdsel = RTL_SPEED_100;
+ else
+ spdsel = RTL_SPEED_10;
+
+ mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
+
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ mcr &= ~RTL838X_RX_PAUSE_EN;
+ mcr &= ~RTL838X_TX_PAUSE_EN;
+ mcr &= ~RTL838X_DUPLEX_MODE;
+ mcr &= ~RTL838X_SPEED_MASK;
+ mcr |= RTL83XX_FORCE_LINK_EN;
+ mcr |= spdsel << RTL838X_SPEED_SHIFT;
+
+ if (tx_pause)
+ mcr |= RTL838X_TX_PAUSE_EN;
+ if (rx_pause)
+ mcr |= RTL838X_RX_PAUSE_EN;
+ if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
+ mcr |= RTL838X_DUPLEX_MODE;
+ if (dsa_port_is_cpu(dp))
+ mcr |= RTL83XX_FORCE_EN;
+
+ } else if (priv->family_id == RTL8390_FAMILY_ID) {
+ mcr &= ~RTL839X_RX_PAUSE_EN;
+ mcr &= ~RTL839X_TX_PAUSE_EN;
+ mcr &= ~RTL839X_DUPLEX_MODE;
+ mcr &= ~RTL839X_SPEED_MASK;
+ mcr |= RTL83XX_FORCE_LINK_EN;
+ mcr |= spdsel << RTL839X_SPEED_SHIFT;
+
+ if (tx_pause)
+ mcr |= RTL839X_TX_PAUSE_EN;
+ if (rx_pause)
+ mcr |= RTL839X_RX_PAUSE_EN;
+ if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
+ mcr |= RTL839X_DUPLEX_MODE;
+ if (dsa_port_is_cpu(dp))
+ mcr |= RTL83XX_FORCE_EN;
+ }
+
+ pr_debug("%s port %d, mode %x, speed %d, duplex %d, txpause %d, rxpause %d: set mcr=%08x\n",
+ __func__, port, mode, speed, duplex, tx_pause, rx_pause, mcr);
+ sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
+
+ /* Restart TX/RX to port */
+ sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
+}
+
+static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ phy_interface_t interface,
+ struct phy_device *phydev,
+ int speed, int duplex,
+ bool tx_pause, bool rx_pause)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ /* Restart TX/RX to port */
+ sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
+ /* TODO: Set speed/duplex/pauses */
+}
+
+static void rtl83xx_get_strings(struct dsa_switch *ds,
+ int port, u32 stringset, u8 *data)
+{
+ if (stringset != ETH_SS_STATS)
+ return;
+
+ for (int i = 0; i < ARRAY_SIZE(rtl83xx_mib); i++)
+ ethtool_puts(&data, rtl83xx_mib[i].name);
+}
+
+static void rtl83xx_get_ethtool_stats(struct dsa_switch *ds, int port,
+ uint64_t *data)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ const struct rtl83xx_mib_desc *mib;
+ u64 h;
+
+ for (int i = 0; i < ARRAY_SIZE(rtl83xx_mib); i++) {
+ mib = &rtl83xx_mib[i];
+
+ data[i] = sw_r32(priv->r->stat_port_std_mib + (port << 8) + 252 - mib->offset);
+ if (mib->size == 2) {
+ h = sw_r32(priv->r->stat_port_std_mib + (port << 8) + 248 - mib->offset);
+ data[i] |= h << 32;
+ }
+ }
+}
+
+static int rtl83xx_get_sset_count(struct dsa_switch *ds, int port, int sset)
+{
+ if (sset != ETH_SS_STATS)
+ return 0;
+
+ return ARRAY_SIZE(rtl83xx_mib);
+}
+
+static int rtl83xx_mc_group_alloc(struct rtl838x_switch_priv *priv, int port)
+{
+ int mc_group = find_first_zero_bit(priv->mc_group_bm, MAX_MC_GROUPS - 1);
+ u64 portmask;
+
+ if (mc_group >= MAX_MC_GROUPS - 1)
+ return -1;
+
+ set_bit(mc_group, priv->mc_group_bm);
+ portmask = BIT_ULL(port);
+ priv->r->write_mcast_pmask(mc_group, portmask);
+
+ return mc_group;
+}
+
+static u64 rtl83xx_mc_group_add_port(struct rtl838x_switch_priv *priv, int mc_group, int port)
+{
+ u64 portmask = priv->r->read_mcast_pmask(mc_group);
+
+ pr_debug("%s: %d\n", __func__, port);
+
+ portmask |= BIT_ULL(port);
+ priv->r->write_mcast_pmask(mc_group, portmask);
+
+ return portmask;
+}
+
+static u64 rtl83xx_mc_group_del_port(struct rtl838x_switch_priv *priv, int mc_group, int port)
+{
+ u64 portmask = priv->r->read_mcast_pmask(mc_group);
+
+ pr_debug("%s: %d\n", __func__, port);
+
+ portmask &= ~BIT_ULL(port);
+ priv->r->write_mcast_pmask(mc_group, portmask);
+ if (!portmask)
+ clear_bit(mc_group, priv->mc_group_bm);
+
+ return portmask;
+}
+
+static int rtl83xx_port_enable(struct dsa_switch *ds, int port,
+ struct phy_device *phydev)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 v;
+
+ pr_debug("%s: %x %d", __func__, (u32) priv, port);
+ priv->ports[port].enable = true;
+
+ /* enable inner tagging on egress, do not keep any tags */
+ priv->r->vlan_port_keep_tag_set(port, 0, 1);
+
+ if (dsa_is_cpu_port(ds, port))
+ return 0;
+
+ /* add port to switch mask of CPU_PORT */
+ priv->r->traffic_enable(priv->cpu_port, port);
+
+ if (priv->is_lagmember[port]) {
+ pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
+ return 0;
+ }
+
+ /* add all other ports in the same bridge to switch mask of port */
+ v = priv->r->traffic_get(port);
+ v |= priv->ports[port].pm;
+ priv->r->traffic_set(port, v);
+
+ /* TODO: Figure out if this is necessary */
+ if (priv->family_id == RTL9300_FAMILY_ID) {
+ sw_w32_mask(0, BIT(port), RTL930X_L2_PORT_SABLK_CTRL);
+ sw_w32_mask(0, BIT(port), RTL930X_L2_PORT_DABLK_CTRL);
+ }
+
+ if (priv->ports[port].sds_num < 0)
+ priv->ports[port].sds_num = rtl93xx_get_sds(phydev);
+
+ return 0;
+}
+
+static void rtl83xx_port_disable(struct dsa_switch *ds, int port)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 v;
+
+ pr_debug("%s %x: %d", __func__, (u32)priv, port);
+ /* you can only disable user ports */
+ if (!dsa_is_user_port(ds, port))
+ return;
+
+ /* BUG: This does not work on RTL931X */
+ /* remove port from switch mask of CPU_PORT */
+ priv->r->traffic_disable(priv->cpu_port, port);
+
+ /* remove all other ports in the same bridge from switch mask of port */
+ v = priv->r->traffic_get(port);
+ v &= ~priv->ports[port].pm;
+ priv->r->traffic_set(port, v);
+
+ priv->ports[port].enable = false;
+}
+
+static int rtl83xx_set_mac_eee(struct dsa_switch *ds, int port,
+ struct ethtool_eee *e)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ if (e->eee_enabled && !priv->eee_enabled) {
+ pr_info("Globally enabling EEE\n");
+ priv->r->init_eee(priv, true);
+ }
+
+ priv->r->port_eee_set(priv, port, e->eee_enabled);
+
+ if (e->eee_enabled)
+ pr_info("Enabled EEE for port %d\n", port);
+ else
+ pr_info("Disabled EEE for port %d\n", port);
+
+ return 0;
+}
+
+static int rtl83xx_get_mac_eee(struct dsa_switch *ds, int port,
+ struct ethtool_eee *e)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ e->supported = SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full;
+
+ priv->r->eee_port_ability(priv, e, port);
+
+ e->eee_enabled = priv->ports[port].eee_enabled;
+
+ e->eee_active = !!(e->advertised & e->lp_advertised);
+
+ return 0;
+}
+
+static int rtl93xx_get_mac_eee(struct dsa_switch *ds, int port,
+ struct ethtool_eee *e)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ e->supported = SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_2500baseX_Full;
+
+ priv->r->eee_port_ability(priv, e, port);
+
+ e->eee_enabled = priv->ports[port].eee_enabled;
+
+ e->eee_active = !!(e->advertised & e->lp_advertised);
+
+ return 0;
+}
+
+static int rtl83xx_set_ageing_time(struct dsa_switch *ds, unsigned int msec)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ priv->r->set_ageing_time(msec);
+
+ return 0;
+}
+
+static int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port,
+ struct dsa_bridge bridge,
+ bool *tx_fwd_offload,
+ struct netlink_ext_ack *extack)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 port_bitmap = BIT_ULL(priv->cpu_port), v;
+
+ pr_debug("%s %x: %d %llx", __func__, (u32)priv, port, port_bitmap);
+
+ if (priv->is_lagmember[port]) {
+ pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
+ return 0;
+ }
+
+ mutex_lock(&priv->reg_mutex);
+ for (int i = 0; i < ds->num_ports; i++) {
+ /* Add this port to the port matrix of the other ports in the
+ * same bridge. If the port is disabled, port matrix is kept
+ * and not being setup until the port becomes enabled.
+ */
+ if (dsa_is_user_port(ds, i) && !priv->is_lagmember[i] && i != port) {
+ if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
+ continue;
+ if (priv->ports[i].enable)
+ priv->r->traffic_enable(i, port);
+
+ priv->ports[i].pm |= BIT_ULL(port);
+ port_bitmap |= BIT_ULL(i);
+ }
+ }
+
+ /* Add all other ports to this port matrix. */
+ if (priv->ports[port].enable) {
+ priv->r->traffic_enable(priv->cpu_port, port);
+ v = priv->r->traffic_get(port);
+ v |= port_bitmap;
+ priv->r->traffic_set(port, v);
+ }
+ priv->ports[port].pm |= port_bitmap;
+
+ if (priv->r->set_static_move_action)
+ priv->r->set_static_move_action(port, false);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
+ struct dsa_bridge bridge)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 port_bitmap = 0, v;
+
+ pr_debug("%s %x: %d", __func__, (u32)priv, port);
+ mutex_lock(&priv->reg_mutex);
+ for (int i = 0; i < ds->num_ports; i++) {
+ /* Remove this port from the port matrix of the other ports
+ * in the same bridge. If the port is disabled, port matrix
+ * is kept and not being setup until the port becomes enabled.
+ * And the other port's port matrix cannot be broken when the
+ * other port is still a VLAN-aware port.
+ */
+ if (dsa_is_user_port(ds, i) && i != port) {
+ if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
+ continue;
+ if (priv->ports[i].enable)
+ priv->r->traffic_disable(i, port);
+
+ priv->ports[i].pm &= ~BIT_ULL(port);
+ port_bitmap |= BIT_ULL(i);
+ }
+ }
+
+ /* Remove all other ports from this port matrix. */
+ if (priv->ports[port].enable) {
+ v = priv->r->traffic_get(port);
+ v &= ~port_bitmap;
+ priv->r->traffic_set(port, v);
+ }
+ priv->ports[port].pm &= ~port_bitmap;
+
+ if (priv->r->set_static_move_action)
+ priv->r->set_static_move_action(port, true);
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
+void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+ u32 msti = 0;
+ u32 port_state[4];
+ int index, bit;
+ int pos = port;
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int n = priv->port_width << 1;
+
+ /* Ports above or equal CPU port can never be configured */
+ if (port >= priv->cpu_port)
+ return;
+
+ mutex_lock(&priv->reg_mutex);
+
+ /* For the RTL839x and following, the bits are left-aligned, 838x and 930x
+ * have 64 bit fields, 839x and 931x have 128 bit fields
+ */
+ if (priv->family_id == RTL8390_FAMILY_ID)
+ pos += 12;
+ if (priv->family_id == RTL9300_FAMILY_ID)
+ pos += 3;
+ if (priv->family_id == RTL9310_FAMILY_ID)
+ pos += 8;
+
+ index = n - (pos >> 4) - 1;
+ bit = (pos << 1) % 32;
+
+ priv->r->stp_get(priv, msti, port_state);
+
+ pr_debug("Current state, port %d: %d\n", port, (port_state[index] >> bit) & 3);
+ port_state[index] &= ~(3 << bit);
+
+ switch (state) {
+ case BR_STATE_DISABLED: /* 0 */
+ port_state[index] |= (0 << bit);
+ break;
+ case BR_STATE_BLOCKING: /* 4 */
+ case BR_STATE_LISTENING: /* 1 */
+ port_state[index] |= (1 << bit);
+ break;
+ case BR_STATE_LEARNING: /* 2 */
+ port_state[index] |= (2 << bit);
+ break;
+ case BR_STATE_FORWARDING: /* 3 */
+ port_state[index] |= (3 << bit);
+ default:
+ break;
+ }
+
+ priv->r->stp_set(priv, msti, port_state);
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
+void rtl83xx_fast_age(struct dsa_switch *ds, int port)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int s = priv->family_id == RTL8390_FAMILY_ID ? 2 : 0;
+
+ pr_debug("FAST AGE port %d\n", port);
+ mutex_lock(&priv->reg_mutex);
+ /* RTL838X_L2_TBL_FLUSH_CTRL register bits, 839x has 1 bit larger
+ * port fields:
+ * 0-4: Replacing port
+ * 5-9: Flushed/replaced port
+ * 10-21: FVID
+ * 22: Entry types: 1: dynamic, 0: also static
+ * 23: Match flush port
+ * 24: Match FVID
+ * 25: Flush (0) or replace (1) L2 entries
+ * 26: Status of action (1: Start, 0: Done)
+ */
+ sw_w32(1 << (26 + s) | 1 << (23 + s) | port << (5 + (s / 2)), priv->r->l2_tbl_flush_ctrl);
+
+ do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(26 + s));
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
+void rtl931x_fast_age(struct dsa_switch *ds, int port)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ pr_info("%s port %d\n", __func__, port);
+ mutex_lock(&priv->reg_mutex);
+ sw_w32(port << 11, RTL931X_L2_TBL_FLUSH_CTRL + 4);
+
+ sw_w32(BIT(24) | BIT(28), RTL931X_L2_TBL_FLUSH_CTRL);
+
+ do { } while (sw_r32(RTL931X_L2_TBL_FLUSH_CTRL) & BIT (28));
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
+void rtl930x_fast_age(struct dsa_switch *ds, int port)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ if (priv->family_id == RTL9310_FAMILY_ID)
+ return rtl931x_fast_age(ds, port);
+
+ pr_debug("FAST AGE port %d\n", port);
+ mutex_lock(&priv->reg_mutex);
+ sw_w32(port << 11, RTL930X_L2_TBL_FLUSH_CTRL + 4);
+
+ sw_w32(BIT(26) | BIT(30), RTL930X_L2_TBL_FLUSH_CTRL);
+
+ do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(30));
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
+static int rtl83xx_vlan_filtering(struct dsa_switch *ds, int port,
+ bool vlan_filtering,
+ struct netlink_ext_ack *extack)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ pr_debug("%s: port %d\n", __func__, port);
+ mutex_lock(&priv->reg_mutex);
+
+ if (vlan_filtering) {
+ /* Enable ingress and egress filtering
+ * The VLAN_PORT_IGR_FILTER register uses 2 bits for each port to define
+ * the filter action:
+ * 0: Always Forward
+ * 1: Drop packet
+ * 2: Trap packet to CPU port
+ * The Egress filter used 1 bit per state (0: DISABLED, 1: ENABLED)
+ */
+ if (port != priv->cpu_port) {
+ priv->r->set_vlan_igr_filter(port, IGR_DROP);
+ priv->r->set_vlan_egr_filter(port, EGR_ENABLE);
+ }
+ else {
+ priv->r->set_vlan_igr_filter(port, IGR_TRAP);
+ priv->r->set_vlan_egr_filter(port, EGR_DISABLE);
+ }
+
+ } else {
+ /* Disable ingress and egress filtering */
+ if (port != priv->cpu_port)
+ priv->r->set_vlan_igr_filter(port, IGR_FORWARD);
+
+ priv->r->set_vlan_egr_filter(port, EGR_DISABLE);
+ }
+
+ /* Do we need to do something to the CPU-Port, too? */
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static int rtl83xx_vlan_prepare(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan)
+{
+ struct rtl838x_vlan_info info;
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ priv->r->vlan_tables_read(0, &info);
+
+ pr_debug("VLAN 0: Tagged ports %llx, untag %llx, profile %d, MC# %d, UC# %d, FID %x\n",
+ info.tagged_ports, info.untagged_ports, info.profile_id,
+ info.hash_mc_fid, info.hash_uc_fid, info.fid);
+
+ priv->r->vlan_tables_read(1, &info);
+ pr_debug("VLAN 1: Tagged ports %llx, untag %llx, profile %d, MC# %d, UC# %d, FID %x\n",
+ info.tagged_ports, info.untagged_ports, info.profile_id,
+ info.hash_mc_fid, info.hash_uc_fid, info.fid);
+ priv->r->vlan_set_untagged(1, info.untagged_ports);
+ pr_debug("SET: Untagged ports, VLAN %d: %llx\n", 1, info.untagged_ports);
+
+ priv->r->vlan_set_tagged(1, &info);
+ pr_debug("SET: Tagged ports, VLAN %d: %llx\n", 1, info.tagged_ports);
+
+ return 0;
+}
+
+static int rtl83xx_vlan_add(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan,
+ struct netlink_ext_ack *extack)
+{
+ struct rtl838x_vlan_info info;
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int err;
+
+ pr_debug("%s port %d, vid %d, flags %x\n",
+ __func__, port, vlan->vid, vlan->flags);
+
+ /* Let no one mess with our special VLAN 0 */
+ if (!vlan->vid) return 0;
+
+ if (vlan->vid > 4095) {
+ dev_err(priv->dev, "VLAN out of range: %d", vlan->vid);
+ return -ENOTSUPP;
+ }
+
+ err = rtl83xx_vlan_prepare(ds, port, vlan);
+ if (err)
+ return err;
+
+ mutex_lock(&priv->reg_mutex);
+
+ /*
+ * Realtek switches copy frames as-is to/from the CPU. For a proper
+ * VLAN handling the 12 bit RVID field (= VLAN id) for incoming traffic
+ * and the 1 bit RVID_SEL field (0 = use inner tag, 1 = use outer tag)
+ * for outgoing traffic of the CPU tag structure need to be handled. As
+ * of now no such logic is in place. So for the CPU port keep the fixed
+ * PVID=0 from initial setup in place and ignore all subsequent settings.
+ */
+ if (port != priv->cpu_port) {
+ if (vlan->flags & BRIDGE_VLAN_INFO_PVID)
+ rtl83xx_vlan_set_pvid(priv, port, vlan->vid);
+ else if (priv->ports[port].pvid == vlan->vid)
+ rtl83xx_vlan_set_pvid(priv, port, 0);
+ }
+
+ /* Get port memberships of this vlan */
+ priv->r->vlan_tables_read(vlan->vid, &info);
+
+ /* new VLAN? */
+ if (!info.tagged_ports) {
+ info.fid = 0;
+ info.hash_mc_fid = false;
+ info.hash_uc_fid = false;
+ info.profile_id = 0;
+ }
+
+ /* sanitize untagged_ports - must be a subset */
+ if (info.untagged_ports & ~info.tagged_ports)
+ info.untagged_ports = 0;
+
+ info.tagged_ports |= BIT_ULL(port);
+ if (vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)
+ info.untagged_ports |= BIT_ULL(port);
+ else
+ info.untagged_ports &= ~BIT_ULL(port);
+
+ priv->r->vlan_set_untagged(vlan->vid, info.untagged_ports);
+ pr_debug("Untagged ports, VLAN %d: %llx\n", vlan->vid, info.untagged_ports);
+
+ priv->r->vlan_set_tagged(vlan->vid, &info);
+ pr_debug("Tagged ports, VLAN %d: %llx\n", vlan->vid, info.tagged_ports);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static int rtl83xx_vlan_del(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan)
+{
+ struct rtl838x_vlan_info info;
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u16 pvid;
+
+ pr_debug("%s: port %d, vid %d, flags %x\n",
+ __func__, port, vlan->vid, vlan->flags);
+
+ /* Let no one mess with our special VLAN 0 */
+ if (!vlan->vid) return 0;
+
+ if (vlan->vid > 4095) {
+ dev_err(priv->dev, "VLAN out of range: %d", vlan->vid);
+ return -ENOTSUPP;
+ }
+
+ mutex_lock(&priv->reg_mutex);
+ pvid = priv->ports[port].pvid;
+
+ /* Reset to default if removing the current PVID */
+ if (vlan->vid == pvid) {
+ rtl83xx_vlan_set_pvid(priv, port, 0);
+ }
+ /* Get port memberships of this vlan */
+ priv->r->vlan_tables_read(vlan->vid, &info);
+
+ /* remove port from both tables */
+ info.untagged_ports &= (~BIT_ULL(port));
+ info.tagged_ports &= (~BIT_ULL(port));
+
+ priv->r->vlan_set_untagged(vlan->vid, info.untagged_ports);
+ pr_debug("Untagged ports, VLAN %d: %llx\n", vlan->vid, info.untagged_ports);
+
+ priv->r->vlan_set_tagged(vlan->vid, &info);
+ pr_debug("Tagged ports, VLAN %d: %llx\n", vlan->vid, info.tagged_ports);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static void rtl83xx_setup_l2_uc_entry(struct rtl838x_l2_entry *e, int port, int vid, u64 mac)
+{
+ memset(e, 0, sizeof(*e));
+
+ e->type = L2_UNICAST;
+ e->valid = true;
+
+ e->age = 3;
+ e->is_static = true;
+
+ e->port = port;
+
+ e->rvid = e->vid = vid;
+ e->is_ip_mc = e->is_ipv6_mc = false;
+ u64_to_ether_addr(mac, e->mac);
+}
+
+static void rtl83xx_setup_l2_mc_entry(struct rtl838x_l2_entry *e, int vid, u64 mac, int mc_group)
+{
+ memset(e, 0, sizeof(*e));
+
+ e->type = L2_MULTICAST;
+ e->valid = true;
+
+ e->mc_portmask_index = mc_group;
+
+ e->rvid = e->vid = vid;
+ e->is_ip_mc = e->is_ipv6_mc = false;
+ u64_to_ether_addr(mac, e->mac);
+}
+
+/* Uses the seed to identify a hash bucket in the L2 using the derived hash key and then loops
+ * over the entries in the bucket until either a matching entry is found or an empty slot
+ * Returns the filled in rtl838x_l2_entry and the index in the bucket when an entry was found
+ * when an empty slot was found and must exist is false, the index of the slot is returned
+ * when no slots are available returns -1
+ */
+static int rtl83xx_find_l2_hash_entry(struct rtl838x_switch_priv *priv, u64 seed,
+ bool must_exist, struct rtl838x_l2_entry *e)
+{
+ int idx = -1;
+ u32 key = priv->r->l2_hash_key(priv, seed);
+ u64 entry;
+
+ pr_debug("%s: using key %x, for seed %016llx\n", __func__, key, seed);
+ /* Loop over all entries in the hash-bucket and over the second block on 93xx SoCs */
+ for (int i = 0; i < priv->l2_bucket_size; i++) {
+ entry = priv->r->read_l2_entry_using_hash(key, i, e);
+ pr_debug("valid %d, mac %016llx\n", e->valid, ether_addr_to_u64(&e->mac[0]));
+ if (must_exist && !e->valid)
+ continue;
+ if (!e->valid || ((entry & 0x0fffffffffffffffULL) == seed)) {
+ idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1 : ((key << 2) | i) & 0xffff;
+ break;
+ }
+ }
+
+ return idx;
+}
+
+/* Uses the seed to identify an entry in the CAM by looping over all its entries
+ * Returns the filled in rtl838x_l2_entry and the index in the CAM when an entry was found
+ * when an empty slot was found the index of the slot is returned
+ * when no slots are available returns -1
+ */
+static int rtl83xx_find_l2_cam_entry(struct rtl838x_switch_priv *priv, u64 seed,
+ bool must_exist, struct rtl838x_l2_entry *e)
+{
+ int idx = -1;
+ u64 entry;
+
+ for (int i = 0; i < 64; i++) {
+ entry = priv->r->read_cam(i, e);
+ if (!must_exist && !e->valid) {
+ if (idx < 0) /* First empty entry? */
+ idx = i;
+ break;
+ } else if ((entry & 0x0fffffffffffffffULL) == seed) {
+ pr_debug("Found entry in CAM\n");
+ idx = i;
+ break;
+ }
+ }
+
+ return idx;
+}
+
+static int rtl83xx_port_fdb_add(struct dsa_switch *ds, int port,
+ const unsigned char *addr, u16 vid,
+ const struct dsa_db db)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 mac = ether_addr_to_u64(addr);
+ struct rtl838x_l2_entry e;
+ int err = 0, idx;
+ u64 seed = priv->r->l2_hash_seed(mac, vid);
+
+ if (priv->is_lagmember[port]) {
+ pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
+ return 0;
+ }
+
+ mutex_lock(&priv->reg_mutex);
+
+ idx = rtl83xx_find_l2_hash_entry(priv, seed, false, &e);
+
+ /* Found an existing or empty entry */
+ if (idx >= 0) {
+ rtl83xx_setup_l2_uc_entry(&e, port, vid, mac);
+ priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
+ goto out;
+ }
+
+ /* Hash buckets full, try CAM */
+ idx = rtl83xx_find_l2_cam_entry(priv, seed, false, &e);
+
+ if (idx >= 0) {
+ rtl83xx_setup_l2_uc_entry(&e, port, vid, mac);
+ priv->r->write_cam(idx, &e);
+ goto out;
+ }
+
+ err = -ENOTSUPP;
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+
+ return err;
+}
+
+static int rtl83xx_port_fdb_del(struct dsa_switch *ds, int port,
+ const unsigned char *addr, u16 vid,
+ const struct dsa_db db)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 mac = ether_addr_to_u64(addr);
+ struct rtl838x_l2_entry e;
+ int err = 0, idx;
+ u64 seed = priv->r->l2_hash_seed(mac, vid);
+
+ pr_debug("In %s, mac %llx, vid: %d\n", __func__, mac, vid);
+ mutex_lock(&priv->reg_mutex);
+
+ idx = rtl83xx_find_l2_hash_entry(priv, seed, true, &e);
+
+ if (idx >= 0) {
+ pr_debug("Found entry index %d, key %d and bucket %d\n", idx, idx >> 2, idx & 3);
+ e.valid = false;
+ priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
+ goto out;
+ }
+
+ /* Check CAM for spillover from hash buckets */
+ idx = rtl83xx_find_l2_cam_entry(priv, seed, true, &e);
+
+ if (idx >= 0) {
+ e.valid = false;
+ priv->r->write_cam(idx, &e);
+ goto out;
+ }
+ err = -ENOENT;
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+
+ return err;
+}
+
+static int rtl83xx_port_fdb_dump(struct dsa_switch *ds, int port,
+ dsa_fdb_dump_cb_t *cb, void *data)
+{
+ struct rtl838x_l2_entry e;
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ mutex_lock(&priv->reg_mutex);
+
+ for (int i = 0; i < priv->fib_entries; i++) {
+ priv->r->read_l2_entry_using_hash(i >> 2, i & 0x3, &e);
+
+ if (!e.valid)
+ continue;
+
+ if (e.port == port || e.port == RTL930X_PORT_IGNORE)
+ cb(e.mac, e.vid, e.is_static, data);
+
+ if (!((i + 1) % 64))
+ cond_resched();
+ }
+
+ for (int i = 0; i < 64; i++) {
+ priv->r->read_cam(i, &e);
+
+ if (!e.valid)
+ continue;
+
+ if (e.port == port)
+ cb(e.mac, e.vid, e.is_static, data);
+ }
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static int rtl83xx_port_mdb_add(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb,
+ const struct dsa_db db)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 mac = ether_addr_to_u64(mdb->addr);
+ struct rtl838x_l2_entry e;
+ int err = 0, idx;
+ int vid = mdb->vid;
+ u64 seed = priv->r->l2_hash_seed(mac, vid);
+ int mc_group;
+
+ if (priv->id >= 0x9300)
+ return -EOPNOTSUPP;
+
+ pr_debug("In %s port %d, mac %llx, vid: %d\n", __func__, port, mac, vid);
+
+ if (priv->is_lagmember[port]) {
+ pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
+ return -EINVAL;
+ }
+
+ mutex_lock(&priv->reg_mutex);
+
+ idx = rtl83xx_find_l2_hash_entry(priv, seed, false, &e);
+
+ /* Found an existing or empty entry */
+ if (idx >= 0) {
+ if (e.valid) {
+ pr_debug("Found an existing entry %016llx, mc_group %d\n",
+ ether_addr_to_u64(e.mac), e.mc_portmask_index);
+ rtl83xx_mc_group_add_port(priv, e.mc_portmask_index, port);
+ } else {
+ pr_debug("New entry for seed %016llx\n", seed);
+ mc_group = rtl83xx_mc_group_alloc(priv, port);
+ if (mc_group < 0) {
+ err = -ENOTSUPP;
+ goto out;
+ }
+ rtl83xx_setup_l2_mc_entry(&e, vid, mac, mc_group);
+ priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
+ }
+ goto out;
+ }
+
+ /* Hash buckets full, try CAM */
+ idx = rtl83xx_find_l2_cam_entry(priv, seed, false, &e);
+
+ if (idx >= 0) {
+ if (e.valid) {
+ pr_debug("Found existing CAM entry %016llx, mc_group %d\n",
+ ether_addr_to_u64(e.mac), e.mc_portmask_index);
+ rtl83xx_mc_group_add_port(priv, e.mc_portmask_index, port);
+ } else {
+ pr_debug("New entry\n");
+ mc_group = rtl83xx_mc_group_alloc(priv, port);
+ if (mc_group < 0) {
+ err = -ENOTSUPP;
+ goto out;
+ }
+ rtl83xx_setup_l2_mc_entry(&e, vid, mac, mc_group);
+ priv->r->write_cam(idx, &e);
+ }
+ goto out;
+ }
+
+ err = -ENOTSUPP;
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+ if (err)
+ dev_err(ds->dev, "failed to add MDB entry\n");
+
+ return err;
+}
+
+int rtl83xx_port_mdb_del(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb,
+ const struct dsa_db db)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ u64 mac = ether_addr_to_u64(mdb->addr);
+ struct rtl838x_l2_entry e;
+ int err = 0, idx;
+ int vid = mdb->vid;
+ u64 seed = priv->r->l2_hash_seed(mac, vid);
+ u64 portmask;
+
+ pr_debug("In %s, port %d, mac %llx, vid: %d\n", __func__, port, mac, vid);
+
+ if (priv->is_lagmember[port]) {
+ pr_info("%s: %d is lag slave. ignore\n", __func__, port);
+ return 0;
+ }
+
+ mutex_lock(&priv->reg_mutex);
+
+ idx = rtl83xx_find_l2_hash_entry(priv, seed, true, &e);
+
+ if (idx >= 0) {
+ pr_debug("Found entry index %d, key %d and bucket %d\n", idx, idx >> 2, idx & 3);
+ portmask = rtl83xx_mc_group_del_port(priv, e.mc_portmask_index, port);
+ if (!portmask) {
+ e.valid = false;
+ priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
+ }
+ goto out;
+ }
+
+ /* Check CAM for spillover from hash buckets */
+ idx = rtl83xx_find_l2_cam_entry(priv, seed, true, &e);
+
+ if (idx >= 0) {
+ portmask = rtl83xx_mc_group_del_port(priv, e.mc_portmask_index, port);
+ if (!portmask) {
+ e.valid = false;
+ priv->r->write_cam(idx, &e);
+ }
+ goto out;
+ }
+ /* TODO: Re-enable with a newer kernel: err = -ENOENT; */
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+
+ return err;
+}
+
+static int rtl83xx_port_mirror_add(struct dsa_switch *ds, int port,
+ struct dsa_mall_mirror_tc_entry *mirror,
+ bool ingress, struct netlink_ext_ack *extack)
+{
+ /* We support 4 mirror groups, one destination port per group */
+ int group;
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int ctrl_reg, dpm_reg, spm_reg;
+
+ pr_debug("In %s\n", __func__);
+
+ for (group = 0; group < 4; group++) {
+ if (priv->mirror_group_ports[group] == mirror->to_local_port)
+ break;
+ }
+ if (group >= 4) {
+ for (group = 0; group < 4; group++) {
+ if (priv->mirror_group_ports[group] < 0)
+ break;
+ }
+ }
+
+ if (group >= 4)
+ return -ENOSPC;
+
+ ctrl_reg = priv->r->mir_ctrl + group * 4;
+ dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width;
+ spm_reg = priv->r->mir_spm + group * 4 * priv->port_width;
+
+ pr_debug("Using group %d\n", group);
+ mutex_lock(&priv->reg_mutex);
+
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ /* Enable mirroring to port across VLANs (bit 11) */
+ sw_w32(1 << 11 | (mirror->to_local_port << 4) | 1, ctrl_reg);
+ } else {
+ /* Enable mirroring to destination port */
+ sw_w32((mirror->to_local_port << 4) | 1, ctrl_reg);
+ }
+
+ if (ingress && (priv->r->get_port_reg_be(spm_reg) & (1ULL << port))) {
+ mutex_unlock(&priv->reg_mutex);
+ return -EEXIST;
+ }
+ if ((!ingress) && (priv->r->get_port_reg_be(dpm_reg) & (1ULL << port))) {
+ mutex_unlock(&priv->reg_mutex);
+ return -EEXIST;
+ }
+
+ if (ingress)
+ priv->r->mask_port_reg_be(0, 1ULL << port, spm_reg);
+ else
+ priv->r->mask_port_reg_be(0, 1ULL << port, dpm_reg);
+
+ priv->mirror_group_ports[group] = mirror->to_local_port;
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static void rtl83xx_port_mirror_del(struct dsa_switch *ds, int port,
+ struct dsa_mall_mirror_tc_entry *mirror)
+{
+ int group = 0;
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int ctrl_reg, dpm_reg, spm_reg;
+
+ pr_debug("In %s\n", __func__);
+ for (group = 0; group < 4; group++) {
+ if (priv->mirror_group_ports[group] == mirror->to_local_port)
+ break;
+ }
+ if (group >= 4)
+ return;
+
+ ctrl_reg = priv->r->mir_ctrl + group * 4;
+ dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width;
+ spm_reg = priv->r->mir_spm + group * 4 * priv->port_width;
+
+ mutex_lock(&priv->reg_mutex);
+ if (mirror->ingress) {
+ /* Ingress, clear source port matrix */
+ priv->r->mask_port_reg_be(1ULL << port, 0, spm_reg);
+ } else {
+ /* Egress, clear destination port matrix */
+ priv->r->mask_port_reg_be(1ULL << port, 0, dpm_reg);
+ }
+
+ if (!(sw_r32(spm_reg) || sw_r32(dpm_reg))) {
+ priv->mirror_group_ports[group] = -1;
+ sw_w32(0, ctrl_reg);
+ }
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
+static int rtl83xx_port_pre_bridge_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ unsigned long features = 0;
+ pr_debug("%s: %d %lX\n", __func__, port, flags.val);
+ if (priv->r->enable_learning)
+ features |= BR_LEARNING;
+ if (priv->r->enable_flood)
+ features |= BR_FLOOD;
+ if (priv->r->enable_mcast_flood)
+ features |= BR_MCAST_FLOOD;
+ if (priv->r->enable_bcast_flood)
+ features |= BR_BCAST_FLOOD;
+ if (flags.mask & ~(features))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int rtl83xx_port_bridge_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ pr_debug("%s: %d %lX\n", __func__, port, flags.val);
+ if (priv->r->enable_learning && (flags.mask & BR_LEARNING))
+ priv->r->enable_learning(port, !!(flags.val & BR_LEARNING));
+
+ if (priv->r->enable_flood && (flags.mask & BR_FLOOD))
+ priv->r->enable_flood(port, !!(flags.val & BR_FLOOD));
+
+ if (priv->r->enable_mcast_flood && (flags.mask & BR_MCAST_FLOOD))
+ priv->r->enable_mcast_flood(port, !!(flags.val & BR_MCAST_FLOOD));
+
+ if (priv->r->enable_bcast_flood && (flags.mask & BR_BCAST_FLOOD))
+ priv->r->enable_bcast_flood(port, !!(flags.val & BR_BCAST_FLOOD));
+
+ return 0;
+}
+
+static bool rtl83xx_lag_can_offload(struct dsa_switch *ds,
+ struct net_device *lag,
+ struct netdev_lag_upper_info *info)
+{
+ int id;
+
+ id = dsa_lag_id(ds->dst, lag);
+ if (id < 0 || id >= ds->num_lag_ids)
+ return false;
+
+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
+ return false;
+ }
+ if (info->hash_type != NETDEV_LAG_HASH_L2 && info->hash_type != NETDEV_LAG_HASH_L23)
+ return false;
+
+ return true;
+}
+
+static int rtl83xx_port_lag_change(struct dsa_switch *ds, int port)
+{
+ pr_debug("%s: %d\n", __func__, port);
+ /* Nothing to be done... */
+
+ return 0;
+}
+
+static int rtl83xx_port_lag_join(struct dsa_switch *ds,
+ int port,
+ struct dsa_lag lag,
+ struct netdev_lag_upper_info *info,
+ struct netlink_ext_ack *extack)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int i, err = 0;
+
+ if (!rtl83xx_lag_can_offload(ds, lag.dev, info))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&priv->reg_mutex);
+
+ for (i = 0; i < priv->n_lags; i++) {
+ if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == lag.dev))
+ break;
+ }
+ if (port >= priv->cpu_port) {
+ err = -EINVAL;
+ goto out;
+ }
+ pr_info("port_lag_join: group %d, port %d\n",i, port);
+ if (!priv->lag_devs[i])
+ priv->lag_devs[i] = lag.dev;
+
+ if (priv->lag_primary[i] == -1) {
+ priv->lag_primary[i] = port;
+ } else
+ priv->is_lagmember[port] = 1;
+
+ priv->lagmembers |= (1ULL << port);
+
+ pr_debug("lag_members = %llX\n", priv->lagmembers);
+ err = rtl83xx_lag_add(priv->ds, i, port, info);
+ if (err) {
+ err = -EINVAL;
+ goto out;
+ }
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+
+ return err;
+}
+
+static int rtl83xx_port_lag_leave(struct dsa_switch *ds, int port,
+ struct dsa_lag lag)
+{
+ int i, group = -1, err;
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ mutex_lock(&priv->reg_mutex);
+ for (i = 0; i < priv->n_lags; i++) {
+ if (priv->lags_port_members[i] & BIT_ULL(port)) {
+ group = i;
+ break;
+ }
+ }
+
+ if (group == -1) {
+ pr_info("port_lag_leave: port %d is not a member\n", port);
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (port >= priv->cpu_port) {
+ err = -EINVAL;
+ goto out;
+ }
+ pr_info("port_lag_del: group %d, port %d\n",group, port);
+ priv->lagmembers &=~ (1ULL << port);
+ priv->lag_primary[i] = -1;
+ priv->is_lagmember[port] = 0;
+ pr_debug("lag_members = %llX\n", priv->lagmembers);
+ err = rtl83xx_lag_del(priv->ds, group, port);
+ if (err) {
+ err = -EINVAL;
+ goto out;
+ }
+ if (!priv->lags_port_members[i])
+ priv->lag_devs[i] = NULL;
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+ return 0;
+}
+
+int dsa_phy_read(struct dsa_switch *ds, int phy_addr, int phy_reg)
+{
+ u32 val;
+ u32 offset = 0;
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ if ((phy_addr >= 24) &&
+ (phy_addr <= 27) &&
+ (priv->ports[24].phy == PHY_RTL838X_SDS)) {
+ if (phy_addr == 26)
+ offset = 0x100;
+ val = sw_r32(RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2)) & 0xffff;
+ return val;
+ }
+
+ read_phy(phy_addr, 0, phy_reg, &val);
+ return val;
+}
+
+int dsa_phy_write(struct dsa_switch *ds, int phy_addr, int phy_reg, u16 val)
+{
+ u32 offset = 0;
+ struct rtl838x_switch_priv *priv = ds->priv;
+
+ if ((phy_addr >= 24) &&
+ (phy_addr <= 27) &&
+ (priv->ports[24].phy == PHY_RTL838X_SDS)) {
+ if (phy_addr == 26)
+ offset = 0x100;
+ sw_w32(val, RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2));
+ return 0;
+ }
+ return write_phy(phy_addr, 0, phy_reg, val);
+}
+
+const struct phylink_pcs_ops rtl83xx_pcs_ops = {
+ .pcs_an_restart = rtl83xx_pcs_an_restart,
+ .pcs_validate = rtl83xx_pcs_validate,
+ .pcs_get_state = rtl83xx_pcs_get_state,
+ .pcs_config = rtl83xx_pcs_config,
+};
+
+const struct dsa_switch_ops rtl83xx_switch_ops = {
+ .get_tag_protocol = rtl83xx_get_tag_protocol,
+ .setup = rtl83xx_setup,
+
+ .phy_read = dsa_phy_read,
+ .phy_write = dsa_phy_write,
+
+ .phylink_get_caps = rtl83xx_phylink_get_caps,
+ .phylink_mac_config = rtl83xx_phylink_mac_config,
+ .phylink_mac_link_down = rtl83xx_phylink_mac_link_down,
+ .phylink_mac_link_up = rtl83xx_phylink_mac_link_up,
+ .phylink_mac_select_pcs = rtl83xx_phylink_mac_select_pcs,
+
+ .get_strings = rtl83xx_get_strings,
+ .get_ethtool_stats = rtl83xx_get_ethtool_stats,
+ .get_sset_count = rtl83xx_get_sset_count,
+
+ .port_enable = rtl83xx_port_enable,
+ .port_disable = rtl83xx_port_disable,
+
+ .get_mac_eee = rtl83xx_get_mac_eee,
+ .set_mac_eee = rtl83xx_set_mac_eee,
+
+ .set_ageing_time = rtl83xx_set_ageing_time,
+ .port_bridge_join = rtl83xx_port_bridge_join,
+ .port_bridge_leave = rtl83xx_port_bridge_leave,
+ .port_stp_state_set = rtl83xx_port_stp_state_set,
+ .port_fast_age = rtl83xx_fast_age,
+
+ .port_vlan_filtering = rtl83xx_vlan_filtering,
+ .port_vlan_add = rtl83xx_vlan_add,
+ .port_vlan_del = rtl83xx_vlan_del,
+
+ .port_fdb_add = rtl83xx_port_fdb_add,
+ .port_fdb_del = rtl83xx_port_fdb_del,
+ .port_fdb_dump = rtl83xx_port_fdb_dump,
+
+ .port_mdb_add = rtl83xx_port_mdb_add,
+ .port_mdb_del = rtl83xx_port_mdb_del,
+
+ .port_mirror_add = rtl83xx_port_mirror_add,
+ .port_mirror_del = rtl83xx_port_mirror_del,
+
+ .port_lag_change = rtl83xx_port_lag_change,
+ .port_lag_join = rtl83xx_port_lag_join,
+ .port_lag_leave = rtl83xx_port_lag_leave,
+
+ .port_pre_bridge_flags = rtl83xx_port_pre_bridge_flags,
+ .port_bridge_flags = rtl83xx_port_bridge_flags,
+};
+
+const struct phylink_pcs_ops rtl93xx_pcs_ops = {
+ .pcs_an_restart = rtl83xx_pcs_an_restart,
+ .pcs_validate = rtl93xx_pcs_validate,
+ .pcs_get_state = rtl93xx_pcs_get_state,
+ .pcs_config = rtl83xx_pcs_config,
+};
+
+const struct dsa_switch_ops rtl930x_switch_ops = {
+ .get_tag_protocol = rtl83xx_get_tag_protocol,
+ .setup = rtl93xx_setup,
+
+ .phy_read = dsa_phy_read,
+ .phy_write = dsa_phy_write,
+
+ .phylink_get_caps = rtl83xx_phylink_get_caps,
+ .phylink_mac_config = rtl93xx_phylink_mac_config,
+ .phylink_mac_link_down = rtl93xx_phylink_mac_link_down,
+ .phylink_mac_link_up = rtl93xx_phylink_mac_link_up,
+ .phylink_mac_select_pcs = rtl83xx_phylink_mac_select_pcs,
+
+ .get_strings = rtl83xx_get_strings,
+ .get_ethtool_stats = rtl83xx_get_ethtool_stats,
+ .get_sset_count = rtl83xx_get_sset_count,
+
+ .port_enable = rtl83xx_port_enable,
+ .port_disable = rtl83xx_port_disable,
+
+ .get_mac_eee = rtl93xx_get_mac_eee,
+ .set_mac_eee = rtl83xx_set_mac_eee,
+
+ .set_ageing_time = rtl83xx_set_ageing_time,
+ .port_bridge_join = rtl83xx_port_bridge_join,
+ .port_bridge_leave = rtl83xx_port_bridge_leave,
+ .port_stp_state_set = rtl83xx_port_stp_state_set,
+ .port_fast_age = rtl930x_fast_age,
+
+ .port_vlan_filtering = rtl83xx_vlan_filtering,
+ .port_vlan_add = rtl83xx_vlan_add,
+ .port_vlan_del = rtl83xx_vlan_del,
+
+ .port_fdb_add = rtl83xx_port_fdb_add,
+ .port_fdb_del = rtl83xx_port_fdb_del,
+ .port_fdb_dump = rtl83xx_port_fdb_dump,
+
+ .port_mdb_add = rtl83xx_port_mdb_add,
+ .port_mdb_del = rtl83xx_port_mdb_del,
+
+ .port_lag_change = rtl83xx_port_lag_change,
+ .port_lag_join = rtl83xx_port_lag_join,
+ .port_lag_leave = rtl83xx_port_lag_leave,
+
+ .port_pre_bridge_flags = rtl83xx_port_pre_bridge_flags,
+ .port_bridge_flags = rtl83xx_port_bridge_flags,
+};
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/qos.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/qos.c
index d101e1c97e..d101e1c97e 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/qos.c
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/qos.c
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.c
index d93087f5b1..d93087f5b1 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.c
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.c
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
new file mode 100644
index 0000000000..13a0bb5ffa
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -0,0 +1,1117 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _RTL838X_H
+#define _RTL838X_H
+
+#include <net/dsa.h>
+
+/* Register definition */
+#define RTL838X_MAC_PORT_CTRL(port) (0xd560 + (((port) << 7)))
+#define RTL839X_MAC_PORT_CTRL(port) (0x8004 + (((port) << 7)))
+#define RTL930X_MAC_PORT_CTRL(port) (0x3260 + (((port) << 6)))
+#define RTL931X_MAC_PORT_CTRL (0x6004)
+
+#define RTL930X_MAC_L2_PORT_CTRL(port) (0x3268 + (((port) << 6)))
+#define RTL931X_MAC_L2_PORT_CTRL (0x6000)
+
+#define RTL838X_RST_GLB_CTRL_0 (0x003c)
+
+#define RTL838X_MAC_FORCE_MODE_CTRL (0xa104)
+#define RTL839X_MAC_FORCE_MODE_CTRL (0x02bc)
+#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C)
+#define RTL931X_MAC_FORCE_MODE_CTRL (0x0DCC)
+
+#define RTL838X_DMY_REG31 (0x3b28)
+#define RTL838X_SDS_MODE_SEL (0x0028)
+#define RTL838X_SDS_CFG_REG (0x0034)
+#define RTL838X_INT_MODE_CTRL (0x005c)
+#define RTL838X_CHIP_INFO (0x00d8)
+#define RTL839X_CHIP_INFO (0x0ff4)
+#define RTL838X_PORT_ISO_CTRL(port) (0x4100 + ((port) << 2))
+#define RTL839X_PORT_ISO_CTRL(port) (0x1400 + ((port) << 3))
+
+/* Packet statistics */
+#define RTL838X_STAT_PORT_STD_MIB (0x1200)
+#define RTL839X_STAT_PORT_STD_MIB (0xC000)
+#define RTL930X_STAT_PORT_MIB_CNTR (0x0664)
+#define RTL838X_STAT_RST (0x3100)
+#define RTL839X_STAT_RST (0xF504)
+#define RTL930X_STAT_RST (0x3240)
+#define RTL931X_STAT_RST (0x7ef4)
+#define RTL838X_STAT_PORT_RST (0x3104)
+#define RTL839X_STAT_PORT_RST (0xF508)
+#define RTL930X_STAT_PORT_RST (0x3244)
+#define RTL931X_STAT_PORT_RST (0x7ef8)
+#define RTL838X_STAT_CTRL (0x3108)
+#define RTL839X_STAT_CTRL (0x04cc)
+#define RTL930X_STAT_CTRL (0x3248)
+#define RTL931X_STAT_CTRL (0x5720)
+
+/* Registers of the internal Serdes of the 8390 */
+#define RTL8390_SDS0_1_XSG0 (0xA000)
+#define RTL8390_SDS0_1_XSG1 (0xA100)
+#define RTL839X_SDS12_13_XSG0 (0xB800)
+#define RTL839X_SDS12_13_XSG1 (0xB900)
+#define RTL839X_SDS12_13_PWR0 (0xb880)
+#define RTL839X_SDS12_13_PWR1 (0xb980)
+
+/* Registers of the internal Serdes of the 8380 */
+#define RTL838X_SDS4_FIB_REG0 (0xF800)
+#define RTL838X_SDS4_REG28 (0xef80)
+#define RTL838X_SDS4_DUMMY0 (0xef8c)
+#define RTL838X_SDS5_EXT_REG6 (0xf18c)
+
+/* VLAN registers */
+#define RTL838X_VLAN_CTRL (0x3A74)
+#define RTL838X_VLAN_PROFILE(idx) (0x3A88 + ((idx) << 2))
+#define RTL838X_VLAN_PORT_EGR_FLTR (0x3A84)
+#define RTL838X_VLAN_PORT_PB_VLAN (0x3C00)
+#define RTL838X_VLAN_PORT_IGR_FLTR (0x3A7C)
+
+#define RTL839X_VLAN_PROFILE(idx) (0x25C0 + (((idx) << 3)))
+#define RTL839X_VLAN_CTRL (0x26D4)
+#define RTL839X_VLAN_PORT_PB_VLAN (0x26D8)
+#define RTL839X_VLAN_PORT_IGR_FLTR (0x27B4)
+#define RTL839X_VLAN_PORT_EGR_FLTR (0x27C4)
+
+#define RTL930X_VLAN_PROFILE_SET(idx) (0x9c60 + (((idx) * 20)))
+#define RTL930X_VLAN_CTRL (0x82D4)
+#define RTL930X_VLAN_PORT_PB_VLAN (0x82D8)
+#define RTL930X_VLAN_PORT_IGR_FLTR (0x83C0)
+#define RTL930X_VLAN_PORT_EGR_FLTR (0x83C8)
+
+#define RTL931X_VLAN_PROFILE_SET(idx) (0x9800 + (((idx) * 28)))
+#define RTL931X_VLAN_CTRL (0x94E4)
+#define RTL931X_VLAN_PORT_IGR_CTRL (0x94E8)
+#define RTL931X_VLAN_PORT_IGR_FLTR (0x96B4)
+#define RTL931X_VLAN_PORT_EGR_FLTR (0x96C4)
+
+/* Table access registers */
+#define RTL838X_TBL_ACCESS_CTRL_0 (0x6914)
+#define RTL838X_TBL_ACCESS_DATA_0(idx) (0x6918 + ((idx) << 2))
+#define RTL838X_TBL_ACCESS_CTRL_1 (0xA4C8)
+#define RTL838X_TBL_ACCESS_DATA_1(idx) (0xA4CC + ((idx) << 2))
+
+#define RTL839X_TBL_ACCESS_CTRL_0 (0x1190)
+#define RTL839X_TBL_ACCESS_DATA_0(idx) (0x1194 + ((idx) << 2))
+#define RTL839X_TBL_ACCESS_CTRL_1 (0x6b80)
+#define RTL839X_TBL_ACCESS_DATA_1(idx) (0x6b84 + ((idx) << 2))
+#define RTL839X_TBL_ACCESS_CTRL_2 (0x611C)
+#define RTL839X_TBL_ACCESS_DATA_2(i) (0x6120 + (((i) << 2)))
+
+#define RTL930X_TBL_ACCESS_CTRL_0 (0xB340)
+#define RTL930X_TBL_ACCESS_DATA_0(idx) (0xB344 + ((idx) << 2))
+#define RTL930X_TBL_ACCESS_CTRL_1 (0xB3A0)
+#define RTL930X_TBL_ACCESS_DATA_1(idx) (0xB3A4 + ((idx) << 2))
+#define RTL930X_TBL_ACCESS_CTRL_2 (0xCE04)
+#define RTL930X_TBL_ACCESS_DATA_2(i) (0xCE08 + (((i) << 2)))
+
+#define RTL931X_TBL_ACCESS_CTRL_0 (0x8500)
+#define RTL931X_TBL_ACCESS_DATA_0(idx) (0x8508 + ((idx) << 2))
+#define RTL931X_TBL_ACCESS_CTRL_1 (0x40C0)
+#define RTL931X_TBL_ACCESS_DATA_1(idx) (0x40C4 + ((idx) << 2))
+#define RTL931X_TBL_ACCESS_CTRL_2 (0x8528)
+#define RTL931X_TBL_ACCESS_DATA_2(i) (0x852C + (((i) << 2)))
+#define RTL931X_TBL_ACCESS_CTRL_3 (0x0200)
+#define RTL931X_TBL_ACCESS_DATA_3(i) (0x0204 + (((i) << 2)))
+#define RTL931X_TBL_ACCESS_CTRL_4 (0x20DC)
+#define RTL931X_TBL_ACCESS_DATA_4(i) (0x20E0 + (((i) << 2)))
+#define RTL931X_TBL_ACCESS_CTRL_5 (0x7E1C)
+#define RTL931X_TBL_ACCESS_DATA_5(i) (0x7E20 + (((i) << 2)))
+
+/* MAC handling */
+#define RTL838X_MAC_LINK_STS (0xa188)
+#define RTL839X_MAC_LINK_STS (0x0390)
+#define RTL930X_MAC_LINK_STS (0xCB10)
+#define RTL931X_MAC_LINK_STS (0x0EC0)
+#define RTL838X_MAC_LINK_SPD_STS(p) (0xa190 + (((p >> 4) << 2)))
+#define RTL839X_MAC_LINK_SPD_STS(p) (0x03a0 + (((p >> 4) << 2)))
+#define RTL930X_MAC_LINK_SPD_STS(p) (0xCB18 + (((p >> 3) << 2)))
+#define RTL931X_MAC_LINK_SPD_STS (0x0ED0)
+#define RTL838X_MAC_LINK_DUP_STS (0xa19c)
+#define RTL839X_MAC_LINK_DUP_STS (0x03b0)
+#define RTL930X_MAC_LINK_DUP_STS (0xCB28)
+#define RTL931X_MAC_LINK_DUP_STS (0x0EF0)
+#define RTL838X_MAC_TX_PAUSE_STS (0xa1a0)
+#define RTL839X_MAC_TX_PAUSE_STS (0x03b8)
+#define RTL930X_MAC_TX_PAUSE_STS (0xCB2C)
+#define RTL931X_MAC_TX_PAUSE_STS (0x0EF8)
+#define RTL838X_MAC_RX_PAUSE_STS (0xa1a4)
+#define RTL839X_MAC_RX_PAUSE_STS (0x03c0)
+#define RTL930X_MAC_RX_PAUSE_STS (0xCB30)
+#define RTL931X_MAC_RX_PAUSE_STS (0x0F00)
+#define RTL930X_MAC_LINK_MEDIA_STS (0xCB14)
+#define RTL931X_MAC_LINK_MEDIA_STS (0x0EC8)
+
+/* MAC link state bits */
+#define RTL_SPEED_10 0
+#define RTL_SPEED_100 1
+#define RTL_SPEED_1000 2
+
+#define RTL83XX_FORCE_EN (1 << 0)
+#define RTL83XX_FORCE_LINK_EN (1 << 1)
+
+#define RTL838X_NWAY_EN (1 << 2)
+#define RTL838X_DUPLEX_MODE (1 << 3)
+#define RTL838X_SPEED_SHIFT (4)
+#define RTL838X_SPEED_MASK (3 << RTL838X_SPEED_SHIFT)
+#define RTL838X_TX_PAUSE_EN (1 << 6)
+#define RTL838X_RX_PAUSE_EN (1 << 7)
+#define RTL838X_MAC_FORCE_FC_EN (1 << 8)
+
+#define RTL839X_DUPLEX_MODE (1 << 2)
+#define RTL839X_SPEED_SHIFT (3)
+#define RTL839X_SPEED_MASK (3 << RTL839X_SPEED_SHIFT)
+#define RTL839X_TX_PAUSE_EN (1 << 5)
+#define RTL839X_RX_PAUSE_EN (1 << 6)
+#define RTL839X_MAC_FORCE_FC_EN (1 << 7)
+
+#define RTL930X_FORCE_EN (1 << 0)
+#define RTL930X_FORCE_LINK_EN (1 << 1)
+#define RTL930X_DUPLEX_MODE (1 << 2)
+#define RTL930X_TX_PAUSE_EN (1 << 7)
+#define RTL930X_RX_PAUSE_EN (1 << 8)
+#define RTL930X_MAC_FORCE_FC_EN (1 << 9)
+
+#define RTL931X_FORCE_EN (1 << 9)
+#define RTL931X_FORCE_LINK_EN (1 << 0)
+#define RTL931X_DUPLEX_MODE (1 << 2)
+#define RTL931X_MAC_FORCE_FC_EN (1 << 4)
+#define RTL931X_TX_PAUSE_EN (1 << 16)
+#define RTL931X_RX_PAUSE_EN (1 << 17)
+
+/* EEE */
+#define RTL838X_MAC_EEE_ABLTY (0xa1a8)
+#define RTL838X_EEE_PORT_TX_EN (0x014c)
+#define RTL838X_EEE_PORT_RX_EN (0x0150)
+#define RTL838X_EEE_CLK_STOP_CTRL (0x0148)
+#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04)
+#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08)
+
+#define RTL839X_EEE_TX_TIMER_GELITE_CTRL (0x042C)
+#define RTL839X_EEE_TX_TIMER_GIGA_CTRL (0x0430)
+#define RTL839X_EEE_TX_TIMER_10G_CTRL (0x0434)
+#define RTL839X_EEE_CTRL(p) (0x8008 + ((p) << 7))
+#define RTL839X_MAC_EEE_ABLTY (0x03C8)
+
+#define RTL930X_MAC_EEE_ABLTY (0xCB34)
+#define RTL930X_EEE_CTRL(p) (0x3274 + ((p) << 6))
+#define RTL930X_EEEP_PORT_CTRL(p) (0x3278 + ((p) << 6))
+
+/* L2 functionality */
+#define RTL838X_L2_CTRL_0 (0x3200)
+#define RTL839X_L2_CTRL_0 (0x3800)
+#define RTL930X_L2_CTRL (0x8FD8)
+#define RTL931X_L2_CTRL (0xC800)
+#define RTL838X_L2_CTRL_1 (0x3204)
+#define RTL839X_L2_CTRL_1 (0x3804)
+#define RTL930X_L2_AGE_CTRL (0x8FDC)
+#define RTL931X_L2_AGE_CTRL (0xC804)
+#define RTL838X_L2_PORT_AGING_OUT (0x3358)
+#define RTL839X_L2_PORT_AGING_OUT (0x3b74)
+#define RTL930X_L2_PORT_AGE_CTRL (0x8FE0)
+#define RTL931X_L2_PORT_AGE_CTRL (0xc808)
+#define RTL838X_TBL_ACCESS_L2_CTRL (0x6900)
+#define RTL839X_TBL_ACCESS_L2_CTRL (0x1180)
+#define RTL930X_TBL_ACCESS_L2_CTRL (0xB320)
+#define RTL930X_TBL_ACCESS_L2_METHOD_CTRL (0xB324)
+#define RTL838X_TBL_ACCESS_L2_DATA(idx) (0x6908 + ((idx) << 2))
+#define RTL839X_TBL_ACCESS_L2_DATA(idx) (0x1184 + ((idx) << 2))
+#define RTL930X_TBL_ACCESS_L2_DATA(idx) (0xab08 + ((idx) << 2))
+
+#define RTL838X_L2_TBL_FLUSH_CTRL (0x3370)
+#define RTL839X_L2_TBL_FLUSH_CTRL (0x3ba0)
+#define RTL930X_L2_TBL_FLUSH_CTRL (0x9404)
+#define RTL931X_L2_TBL_FLUSH_CTRL (0xCD9C)
+
+#define RTL838X_L2_LRN_CONSTRT (0x329C)
+#define RTL839X_L2_LRN_CONSTRT (0x3910)
+#define RTL930X_L2_LRN_CONSTRT_CTRL (0x909c)
+#define RTL931X_L2_LRN_CONSTRT_CTRL (0xC964)
+
+#define RTL838X_L2_FLD_PMSK (0x3288)
+#define RTL839X_L2_FLD_PMSK (0x38EC)
+#define RTL930X_L2_BC_FLD_PMSK (0x9068)
+#define RTL931X_L2_BC_FLD_PMSK (0xC8FC)
+
+#define RTL930X_L2_UNKN_UC_FLD_PMSK (0x9064)
+#define RTL931X_L2_UNKN_UC_FLD_PMSK (0xC8F4)
+
+#define RTL838X_L2_LRN_CONSTRT_EN (0x3368)
+#define RTL838X_L2_PORT_LRN_CONSTRT (0x32A0)
+#define RTL839X_L2_PORT_LRN_CONSTRT (0x3914)
+
+#define RTL838X_L2_PORT_NEW_SALRN(p) (0x328c + (((p >> 4) << 2)))
+#define RTL839X_L2_PORT_NEW_SALRN(p) (0x38F0 + (((p >> 4) << 2)))
+#define RTL930X_L2_PORT_SALRN(p) (0x8FEC + (((p >> 4) << 2)))
+#define RTL931X_L2_PORT_NEW_SALRN(p) (0xC820 + (((p >> 4) << 2)))
+
+#define SALRN_PORT_SHIFT(p) ((p % 16) * 2)
+#define SALRN_MODE_MASK 0x3
+#define SALRN_MODE_HARDWARE 0
+#define SALRN_MODE_DISABLED 2
+
+#define RTL838X_L2_PORT_NEW_SA_FWD(p) (0x3294 + (((p >> 4) << 2)))
+#define RTL839X_L2_PORT_NEW_SA_FWD(p) (0x3900 + (((p >> 4) << 2)))
+#define RTL930X_L2_PORT_NEW_SA_FWD(p) (0x8FF4 + (((p / 10) << 2)))
+#define RTL931X_L2_PORT_NEW_SA_FWD(p) (0xC830 + (((p / 10) << 2)))
+
+#define RTL838X_L2_PORT_MV_ACT(p) (0x335c + (((p >> 4) << 2)))
+#define RTL839X_L2_PORT_MV_ACT(p) (0x3b80 + (((p >> 4) << 2)))
+
+#define RTL838X_L2_PORT_STATIC_MV_ACT(p) (0x327c + (((p >> 4) << 2)))
+#define RTL839X_L2_PORT_STATIC_MV_ACT(p) (0x38dc + (((p >> 4) << 2)))
+
+#define MV_ACT_PORT_SHIFT(p) ((p % 16) * 2)
+#define MV_ACT_MASK 0x3
+#define MV_ACT_FORWARD 0
+#define MV_ACT_DROP 1
+#define MV_ACT_TRAP2CPU 2
+#define MV_ACT_COPY2CPU 3
+
+#define RTL930X_ST_CTRL (0x8798)
+
+#define RTL930X_L2_PORT_SABLK_CTRL (0x905c)
+#define RTL930X_L2_PORT_DABLK_CTRL (0x9060)
+
+#define RTL838X_L2_PORT_LM_ACT(p) (0x3208 + ((p) << 2))
+#define RTL838X_VLAN_PORT_FWD (0x3A78)
+#define RTL839X_VLAN_PORT_FWD (0x27AC)
+#define RTL930X_VLAN_PORT_FWD (0x834C)
+#define RTL931X_VLAN_PORT_FWD (0x95CC)
+#define RTL838X_VLAN_FID_CTRL (0x3aa8)
+
+/* Port Mirroring */
+#define RTL838X_MIR_CTRL (0x5D00)
+#define RTL838X_MIR_DPM_CTRL (0x5D20)
+#define RTL838X_MIR_SPM_CTRL (0x5D10)
+
+#define RTL839X_MIR_CTRL (0x2500)
+#define RTL839X_MIR_DPM_CTRL (0x2530)
+#define RTL839X_MIR_SPM_CTRL (0x2510)
+
+#define RTL930X_MIR_CTRL (0xA2A0)
+#define RTL930X_MIR_DPM_CTRL (0xA2C0)
+#define RTL930X_MIR_SPM_CTRL (0xA2B0)
+
+#define RTL931X_MIR_CTRL (0xAF00)
+#define RTL931X_MIR_DPM_CTRL (0xAF30)
+#define RTL931X_MIR_SPM_CTRL (0xAF10)
+
+/* Storm/rate control and scheduling */
+#define RTL838X_STORM_CTRL (0x4700)
+#define RTL839X_STORM_CTRL (0x1800)
+#define RTL838X_STORM_CTRL_LB_CTRL(p) (0x4884 + (((p) << 2)))
+#define RTL838X_STORM_CTRL_BURST_PPS_0 (0x4874)
+#define RTL838X_STORM_CTRL_BURST_PPS_1 (0x4878)
+#define RTL838X_STORM_CTRL_BURST_0 (0x487c)
+#define RTL838X_STORM_CTRL_BURST_1 (0x4880)
+#define RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_0 (0x1804)
+#define RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_1 (0x1808)
+#define RTL838X_SCHED_CTRL (0xB980)
+#define RTL839X_SCHED_CTRL (0x60F4)
+#define RTL838X_SCHED_LB_TICK_TKN_CTRL_0 (0xAD58)
+#define RTL838X_SCHED_LB_TICK_TKN_CTRL_1 (0xAD5C)
+#define RTL839X_SCHED_LB_TICK_TKN_CTRL_0 (0x1804)
+#define RTL839X_SCHED_LB_TICK_TKN_CTRL_1 (0x1808)
+#define RTL839X_STORM_CTRL_SPCL_LB_TICK_TKN_CTRL (0x2000)
+#define RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_0 (0x1604)
+#define RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_1 (0x1608)
+#define RTL839X_SCHED_LB_TICK_TKN_CTRL (0x60F8)
+#define RTL839X_SCHED_LB_TICK_TKN_PPS_CTRL (0x6200)
+#define RTL838X_SCHED_LB_THR (0xB984)
+#define RTL839X_SCHED_LB_THR (0x60FC)
+#define RTL838X_SCHED_P_EGR_RATE_CTRL(p) (0xC008 + (((p) << 7)))
+#define RTL838X_SCHED_Q_EGR_RATE_CTRL(p, q) (0xC00C + (p << 7) + (((q) << 2)))
+#define RTL838X_STORM_CTRL_PORT_BC_EXCEED (0x470C)
+#define RTL838X_STORM_CTRL_PORT_MC_EXCEED (0x4710)
+#define RTL838X_STORM_CTRL_PORT_UC_EXCEED (0x4714)
+#define RTL839X_STORM_CTRL_PORT_BC_EXCEED(p) (0x180c + (((p >> 5) << 2)))
+#define RTL839X_STORM_CTRL_PORT_MC_EXCEED(p) (0x1814 + (((p >> 5) << 2)))
+#define RTL839X_STORM_CTRL_PORT_UC_EXCEED(p) (0x181c + (((p >> 5) << 2)))
+#define RTL838X_STORM_CTRL_PORT_UC(p) (0x4718 + (((p) << 2)))
+#define RTL838X_STORM_CTRL_PORT_MC(p) (0x478c + (((p) << 2)))
+#define RTL838X_STORM_CTRL_PORT_BC(p) (0x4800 + (((p) << 2)))
+#define RTL839X_STORM_CTRL_PORT_UC_0(p) (0x185C + (((p) << 3)))
+#define RTL839X_STORM_CTRL_PORT_UC_1(p) (0x1860 + (((p) << 3)))
+#define RTL839X_STORM_CTRL_PORT_MC_0(p) (0x19FC + (((p) << 3)))
+#define RTL839X_STORM_CTRL_PORT_MC_1(p) (0x1a00 + (((p) << 3)))
+#define RTL839X_STORM_CTRL_PORT_BC_0(p) (0x1B9C + (((p) << 3)))
+#define RTL839X_STORM_CTRL_PORT_BC_1(p) (0x1BA0 + (((p) << 3)))
+#define RTL839X_TBL_ACCESS_CTRL_2 (0x611C)
+#define RTL839X_TBL_ACCESS_DATA_2(i) (0x6120 + (((i) << 2)))
+#define RTL839X_IGR_BWCTRL_PORT_CTRL_10G_0(p) (0x1618 + (((p) << 3)))
+#define RTL839X_IGR_BWCTRL_PORT_CTRL_10G_1(p) (0x161C + (((p) << 3)))
+#define RTL839X_IGR_BWCTRL_PORT_CTRL_0(p) (0x1640 + (((p) << 3)))
+#define RTL839X_IGR_BWCTRL_PORT_CTRL_1(p) (0x1644 + (((p) << 3)))
+#define RTL839X_IGR_BWCTRL_CTRL_LB_THR (0x1614)
+
+/* Link aggregation (Trunking) */
+#define TRUNK_DISTRIBUTION_ALGO_SPA_BIT 0x01
+#define TRUNK_DISTRIBUTION_ALGO_SMAC_BIT 0x02
+#define TRUNK_DISTRIBUTION_ALGO_DMAC_BIT 0x04
+#define TRUNK_DISTRIBUTION_ALGO_SIP_BIT 0x08
+#define TRUNK_DISTRIBUTION_ALGO_DIP_BIT 0x10
+#define TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT 0x20
+#define TRUNK_DISTRIBUTION_ALGO_DST_L4PORT_BIT 0x40
+#define TRUNK_DISTRIBUTION_ALGO_MASKALL 0x7F
+
+#define TRUNK_DISTRIBUTION_ALGO_L2_SPA_BIT 0x01
+#define TRUNK_DISTRIBUTION_ALGO_L2_SMAC_BIT 0x02
+#define TRUNK_DISTRIBUTION_ALGO_L2_DMAC_BIT 0x04
+#define TRUNK_DISTRIBUTION_ALGO_L2_VLAN_BIT 0x08
+#define TRUNK_DISTRIBUTION_ALGO_L2_MASKALL 0xF
+
+#define TRUNK_DISTRIBUTION_ALGO_L3_SPA_BIT 0x01
+#define TRUNK_DISTRIBUTION_ALGO_L3_SMAC_BIT 0x02
+#define TRUNK_DISTRIBUTION_ALGO_L3_DMAC_BIT 0x04
+#define TRUNK_DISTRIBUTION_ALGO_L3_VLAN_BIT 0x08
+#define TRUNK_DISTRIBUTION_ALGO_L3_SIP_BIT 0x10
+#define TRUNK_DISTRIBUTION_ALGO_L3_DIP_BIT 0x20
+#define TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT 0x40
+#define TRUNK_DISTRIBUTION_ALGO_L3_DST_L4PORT_BIT 0x80
+#define TRUNK_DISTRIBUTION_ALGO_L3_PROTO_BIT 0x100
+#define TRUNK_DISTRIBUTION_ALGO_L3_FLOW_LABEL_BIT 0x200
+#define TRUNK_DISTRIBUTION_ALGO_L3_MASKALL 0x3FF
+
+#define RTL838X_TRK_MBR_CTR (0x3E00)
+#define RTL838X_TRK_HASH_IDX_CTRL (0x3E20)
+#define RTL838X_TRK_HASH_CTRL (0x3E24)
+
+#define RTL839X_TRK_MBR_CTR (0x2200)
+#define RTL839X_TRK_HASH_IDX_CTRL (0x2280)
+#define RTL839X_TRK_HASH_CTRL (0x2284)
+
+#define RTL930X_TRK_MBR_CTRL (0xA41C)
+#define RTL930X_TRK_HASH_CTRL (0x9F80)
+
+#define RTL931X_TRK_MBR_CTRL (0xB8D0)
+#define RTL931X_TRK_HASH_CTRL (0xBA70)
+
+/* Attack prevention */
+#define RTL838X_ATK_PRVNT_PORT_EN (0x5B00)
+#define RTL838X_ATK_PRVNT_CTRL (0x5B04)
+#define RTL838X_ATK_PRVNT_ACT (0x5B08)
+#define RTL838X_ATK_PRVNT_STS (0x5B1C)
+
+/* 802.1X */
+#define RTL838X_RMA_BPDU_FLD_PMSK (0x4348)
+#define RTL930X_RMA_BPDU_FLD_PMSK (0x9F18)
+#define RTL931X_RMA_BPDU_FLD_PMSK (0x8950)
+#define RTL839X_RMA_BPDU_FLD_PMSK (0x125C)
+
+#define RTL838X_SPCL_TRAP_CTRL (0x6980)
+#define RTL838X_SPCL_TRAP_EAPOL_CTRL (0x6988)
+#define RTL838X_SPCL_TRAP_ARP_CTRL (0x698C)
+#define RTL838X_SPCL_TRAP_IGMP_CTRL (0x6984)
+#define RTL838X_SPCL_TRAP_IPV6_CTRL (0x6994)
+#define RTL838X_SPCL_TRAP_SWITCH_MAC_CTRL (0x6998)
+
+#define RTL839X_SPCL_TRAP_CTRL (0x1054)
+#define RTL839X_SPCL_TRAP_EAPOL_CTRL (0x105C)
+#define RTL839X_SPCL_TRAP_ARP_CTRL (0x1060)
+#define RTL839X_SPCL_TRAP_IGMP_CTRL (0x1058)
+#define RTL839X_SPCL_TRAP_IPV6_CTRL (0x1064)
+#define RTL839X_SPCL_TRAP_SWITCH_MAC_CTRL (0x1068)
+#define RTL839X_SPCL_TRAP_SWITCH_IPV4_ADDR_CTRL (0x106C)
+#define RTL839X_SPCL_TRAP_CRC_CTRL (0x1070)
+/* special port action controls */
+/* values:
+ * 0 = FORWARD (default)
+ * 1 = DROP
+ * 2 = TRAP2CPU
+ * 3 = FLOOD IN ALL PORT
+ *
+ * Register encoding.
+ * offset = CTRL + (port >> 4) << 2
+ * value/mask = 3 << ((port & 0xF) << 1)
+ */
+
+typedef enum {
+ BPDU = 0,
+ PTP,
+ PTP_UDP,
+ PTP_ETH2,
+ LLDP,
+ EAPOL,
+ GRATARP,
+} rma_ctrl_t;
+
+typedef enum {
+ FORWARD = 0,
+ DROP,
+ TRAP2CPU,
+ FLOODALL,
+ TRAP2MASTERCPU,
+ COPY2CPU,
+} action_type_t;
+
+#define RTL838X_RMA_BPDU_CTRL (0x4330)
+#define RTL839X_RMA_BPDU_CTRL (0x122C)
+#define RTL930X_RMA_BPDU_CTRL (0x9E7C)
+#define RTL931X_RMA_BPDU_CTRL (0x881C)
+
+#define RTL838X_RMA_PTP_CTRL (0x4338)
+#define RTL839X_RMA_PTP_CTRL (0x123C)
+#define RTL930X_RMA_PTP_CTRL (0x9E88)
+#define RTL931X_RMA_PTP_CTRL (0x8834)
+
+#define RTL838X_RMA_LLDP_CTRL (0x4340)
+#define RTL839X_RMA_LLDP_CTRL (0x124C)
+#define RTL930X_RMA_LLDP_CTRL (0x9EFC)
+#define RTL931X_RMA_LLDP_CTRL (0x8918)
+
+#define RTL930X_RMA_EAPOL_CTRL (0x9F08)
+#define RTL931X_RMA_EAPOL_CTRL (0x8930)
+#define RTL931X_TRAP_ARP_GRAT_PORT_ACT (0x8C04)
+
+/* QoS */
+#define RTL838X_QM_INTPRI2QID_CTRL (0x5F00)
+#define RTL839X_QM_INTPRI2QID_CTRL(q) (0x1110 + (q << 2))
+#define RTL839X_QM_PORT_QNUM(p) (0x1130 + (((p / 10) << 2)))
+#define RTL838X_PRI_SEL_PORT_PRI(p) (0x5FB8 + (((p / 10) << 2)))
+#define RTL839X_PRI_SEL_PORT_PRI(p) (0x10A8 + (((p / 10) << 2)))
+#define RTL838X_QM_PKT2CPU_INTPRI_MAP (0x5F10)
+#define RTL839X_QM_PKT2CPU_INTPRI_MAP (0x1154)
+#define RTL838X_PRI_SEL_CTRL (0x10E0)
+#define RTL839X_PRI_SEL_CTRL (0x10E0)
+#define RTL838X_PRI_SEL_TBL_CTRL(i) (0x5FD8 + (((i) << 2)))
+#define RTL839X_PRI_SEL_TBL_CTRL(i) (0x10D0 + (((i) << 2)))
+#define RTL838X_QM_PKT2CPU_INTPRI_0 (0x5F04)
+#define RTL838X_QM_PKT2CPU_INTPRI_1 (0x5F08)
+#define RTL838X_QM_PKT2CPU_INTPRI_2 (0x5F0C)
+#define RTL839X_OAM_CTRL (0x2100)
+#define RTL839X_OAM_PORT_ACT_CTRL(p) (0x2104 + (((p) << 2)))
+#define RTL839X_RMK_PORT_DEI_TAG_CTRL(p) (0x6A9C + (((p >> 5) << 2)))
+#define RTL839X_PRI_SEL_IPRI_REMAP (0x1080)
+#define RTL838X_PRI_SEL_IPRI_REMAP (0x5F8C)
+#define RTL839X_PRI_SEL_DEI2DP_REMAP (0x10EC)
+#define RTL839X_PRI_SEL_DSCP2DP_REMAP_ADDR(i) (0x10F0 + (((i >> 4) << 2)))
+#define RTL839X_RMK_DEI_CTRL (0x6AA4)
+#define RTL839X_WRED_PORT_THR_CTRL(i) (0x6084 + ((i) << 2))
+#define RTL839X_WRED_QUEUE_THR_CTRL(q, i) (0x6090 + ((q) * 12) + ((i) << 2))
+#define RTL838X_PRI_DSCP_INVLD_CTRL0 (0x5FE8)
+#define RTL838X_RMK_IPRI_CTRL (0xA460)
+#define RTL838X_RMK_OPRI_CTRL (0xA464)
+#define RTL838X_SCHED_P_TYPE_CTRL(p) (0xC04C + (((p) << 7)))
+#define RTL838X_SCHED_LB_CTRL(p) (0xC004 + (((p) << 7)))
+#define RTL838X_FC_P_EGR_DROP_CTRL(p) (0x6B1C + (((p) << 2)))
+
+/* Debug features */
+#define RTL930X_STAT_PRVTE_DROP_COUNTER0 (0xB5B8)
+
+/* Packet Inspection Engine */
+#define RTL838X_METER_GLB_CTRL (0x4B08)
+#define RTL839X_METER_GLB_CTRL (0x1300)
+#define RTL930X_METER_GLB_CTRL (0xa0a0)
+#define RTL931X_METER_GLB_CTRL (0x411C)
+
+#define RTL839X_ACL_CTRL (0x1288)
+
+#define RTL838X_ACL_BLK_LOOKUP_CTRL (0x6100)
+#define RTL839X_ACL_BLK_LOOKUP_CTRL (0x1280)
+#define RTL930X_PIE_BLK_LOOKUP_CTRL (0xa5a0)
+#define RTL931X_PIE_BLK_LOOKUP_CTRL (0x4180)
+
+#define RTL838X_ACL_BLK_PWR_CTRL (0x6104)
+#define RTL839X_PS_ACL_PWR_CTRL (0x049c)
+
+#define RTL838X_ACL_BLK_TMPLTE_CTRL(block) (0x6108 + ((block) << 2))
+#define RTL839X_ACL_BLK_TMPLTE_CTRL(block) (0x128c + ((block) << 2))
+#define RTL930X_PIE_BLK_TMPLTE_CTRL(block) (0xa624 + ((block) << 2))
+#define RTL931X_PIE_BLK_TMPLTE_CTRL(block) (0x4214 + ((block) << 2))
+
+#define RTL838X_ACL_BLK_GROUP_CTRL (0x615C)
+#define RTL839X_ACL_BLK_GROUP_CTRL (0x12ec)
+
+#define RTL838X_ACL_CLR_CTRL (0x6168)
+#define RTL839X_ACL_CLR_CTRL (0x12fc)
+#define RTL930X_PIE_CLR_CTRL (0xa66c)
+#define RTL931X_PIE_CLR_CTRL (0x42D8)
+
+#define RTL838X_DMY_REG27 (0x3378)
+
+#define RTL838X_ACL_PORT_LOOKUP_CTRL(p) (0x616C + (((p) << 2)))
+#define RTL930X_ACL_PORT_LOOKUP_CTRL(p) (0xA784 + (((p) << 2)))
+#define RTL931X_ACL_PORT_LOOKUP_CTRL(p) (0x44F8 + (((p) << 2)))
+
+#define RTL930X_PIE_BLK_PHASE_CTRL (0xA5A4)
+#define RTL931X_PIE_BLK_PHASE_CTRL (0x4184)
+
+/* PIE actions */
+#define PIE_ACT_COPY_TO_PORT 2
+#define PIE_ACT_REDIRECT_TO_PORT 4
+#define PIE_ACT_ROUTE_UC 6
+#define PIE_ACT_VID_ASSIGN 0
+
+/* L3 actions */
+#define L3_FORWARD 0
+#define L3_DROP 1
+#define L3_TRAP2CPU 2
+#define L3_COPY2CPU 3
+#define L3_TRAP2MASTERCPU 4
+#define L3_COPY2MASTERCPU 5
+#define L3_HARDDROP 6
+
+/* Route actions */
+#define ROUTE_ACT_FORWARD 0
+#define ROUTE_ACT_TRAP2CPU 1
+#define ROUTE_ACT_COPY2CPU 2
+#define ROUTE_ACT_DROP 3
+
+/* L3 Routing */
+#define RTL839X_ROUTING_SA_CTRL 0x6afc
+#define RTL930X_L3_HOST_TBL_CTRL (0xAB48)
+#define RTL930X_L3_IPUC_ROUTE_CTRL (0xAB4C)
+#define RTL930X_L3_IP6UC_ROUTE_CTRL (0xAB50)
+#define RTL930X_L3_IPMC_ROUTE_CTRL (0xAB54)
+#define RTL930X_L3_IP6MC_ROUTE_CTRL (0xAB58)
+#define RTL930X_L3_IP_MTU_CTRL(i) (0xAB5C + ((i >> 1) << 2))
+#define RTL930X_L3_IP6_MTU_CTRL(i) (0xAB6C + ((i >> 1) << 2))
+#define RTL930X_L3_HW_LU_KEY_CTRL (0xAC9C)
+#define RTL930X_L3_HW_LU_KEY_IP_CTRL (0xACA0)
+#define RTL930X_L3_HW_LU_CTRL (0xACC0)
+#define RTL930X_L3_IP_ROUTE_CTRL 0xab44
+
+/* Port LED Control */
+#define RTL930X_LED_PORT_NUM_CTRL(p) (0xCC04 + (((p >> 4) << 2)))
+#define RTL930X_LED_SET0_0_CTRL (0xCC28)
+#define RTL930X_LED_PORT_COPR_SET_SEL_CTRL(p) (0xCC2C + (((p >> 4) << 2)))
+#define RTL930X_LED_PORT_FIB_SET_SEL_CTRL(p) (0xCC34 + (((p >> 4) << 2)))
+#define RTL930X_LED_PORT_COPR_MASK_CTRL (0xCC3C)
+#define RTL930X_LED_PORT_FIB_MASK_CTRL (0xCC40)
+#define RTL930X_LED_PORT_COMBO_MASK_CTRL (0xCC44)
+
+#define RTL931X_LED_PORT_NUM_CTRL(p) (0x0604 + (((p >> 4) << 2)))
+#define RTL931X_LED_SET0_0_CTRL (0x0630)
+#define RTL931X_LED_PORT_COPR_SET_SEL_CTRL(p) (0x0634 + (((p >> 4) << 2)))
+#define RTL931X_LED_PORT_FIB_SET_SEL_CTRL(p) (0x0644 + (((p >> 4) << 2)))
+#define RTL931X_LED_PORT_COPR_MASK_CTRL (0x0654)
+#define RTL931X_LED_PORT_FIB_MASK_CTRL (0x065c)
+#define RTL931X_LED_PORT_COMBO_MASK_CTRL (0x0664)
+
+#define MAX_VLANS 4096
+#define MAX_LAGS 16
+#define MAX_PRIOS 8
+#define RTL930X_PORT_IGNORE 0x3f
+#define MAX_MC_GROUPS 512
+#define UNKNOWN_MC_PMASK (MAX_MC_GROUPS - 1)
+#define PIE_BLOCK_SIZE 128
+#define MAX_PIE_ENTRIES (18 * PIE_BLOCK_SIZE)
+#define N_FIXED_FIELDS 12
+#define N_FIXED_FIELDS_RTL931X 14
+#define MAX_COUNTERS 2048
+#define MAX_ROUTES 512
+#define MAX_HOST_ROUTES 1536
+#define MAX_INTF_MTUS 8
+#define DEFAULT_MTU 1536
+#define MAX_INTERFACES 100
+#define MAX_ROUTER_MACS 64
+#define L3_EGRESS_DMACS 2048
+#define MAX_SMACS 64
+
+enum phy_type {
+ PHY_NONE = 0,
+ PHY_RTL838X_SDS = 1,
+ PHY_RTL8218B_INT = 2,
+ PHY_RTL8218B_EXT = 3,
+ PHY_RTL8214FC = 4,
+ PHY_RTL839X_SDS = 5,
+ PHY_RTL930X_SDS = 6,
+};
+
+enum pbvlan_type {
+ PBVLAN_TYPE_INNER = 0,
+ PBVLAN_TYPE_OUTER,
+};
+
+enum pbvlan_mode {
+ PBVLAN_MODE_UNTAG_AND_PRITAG = 0,
+ PBVLAN_MODE_UNTAG_ONLY,
+ PBVLAN_MODE_ALL_PKT,
+};
+
+struct rtl838x_port {
+ bool enable;
+ u64 pm;
+ u16 pvid;
+ bool eee_enabled;
+ enum phy_type phy;
+ bool phy_is_integrated;
+ bool is10G;
+ bool is2G5;
+ int sds_num;
+ int led_set;
+ int leds_on_this_port;
+ const struct dsa_port *dp;
+};
+
+struct rtl838x_pcs {
+ struct phylink_pcs pcs;
+ struct rtl838x_switch_priv *priv;
+ int port;
+};
+
+struct rtl838x_vlan_info {
+ u64 untagged_ports;
+ u64 tagged_ports;
+ u8 profile_id;
+ bool hash_mc_fid;
+ bool hash_uc_fid;
+ u8 fid; /* AKA MSTI */
+
+ /* The following fields are used only by the RTL931X */
+ int if_id; /* Interface (index in L3_EGR_INTF_IDX) */
+ u16 multicast_grp_mask;
+ int l2_tunnel_list_id;
+};
+
+enum l2_entry_type {
+ L2_INVALID = 0,
+ L2_UNICAST = 1,
+ L2_MULTICAST = 2,
+ IP4_MULTICAST = 3,
+ IP6_MULTICAST = 4,
+};
+
+struct rtl838x_l2_entry {
+ u8 mac[6];
+ u16 vid;
+ u16 rvid;
+ u8 port;
+ bool valid;
+ enum l2_entry_type type;
+ bool is_static;
+ bool is_ip_mc;
+ bool is_ipv6_mc;
+ bool block_da;
+ bool block_sa;
+ bool suspended;
+ bool next_hop;
+ int age;
+ u8 trunk;
+ bool is_trunk;
+ u8 stack_dev;
+ u16 mc_portmask_index;
+ u32 mc_gip;
+ u32 mc_sip;
+ u16 mc_mac_index;
+ u16 nh_route_id;
+ bool nh_vlan_target; /* Only RTL83xx: VLAN used for next hop */
+
+ /* The following is only valid on RTL931x */
+ bool is_open_flow;
+ bool is_pe_forward;
+ bool is_local_forward;
+ bool is_remote_forward;
+ bool is_l2_tunnel;
+ int l2_tunnel_id;
+ int l2_tunnel_list_id;
+};
+
+enum fwd_rule_action {
+ FWD_RULE_ACTION_NONE = 0,
+ FWD_RULE_ACTION_FWD = 1,
+};
+
+enum pie_phase {
+ PHASE_VACL = 0,
+ PHASE_IACL = 1,
+};
+
+enum igr_filter {
+ IGR_FORWARD = 0,
+ IGR_DROP = 1,
+ IGR_TRAP = 2,
+};
+
+enum egr_filter {
+ EGR_DISABLE = 0,
+ EGR_ENABLE = 1,
+};
+
+/* Intermediate representation of a Packet Inspection Engine Rule
+ * as suggested by the Kernel's tc flower offload subsystem
+ * Field meaning is universal across SoC families, but data content is specific
+ * to SoC family (e.g. because of different port ranges) */
+struct pie_rule {
+ int id;
+ enum pie_phase phase; /* Phase in which this template is applied */
+ int packet_cntr; /* ID of a packet counter assigned to this rule */
+ int octet_cntr; /* ID of a byte counter assigned to this rule */
+ u32 last_packet_cnt;
+ u64 last_octet_cnt;
+
+ /* The following are requirements for the pie template */
+ bool is_egress;
+ bool is_ipv6; /* This is a rule with IPv6 fields */
+
+ /* Fixed fields that are always matched against on RTL8380 */
+ u8 spmmask_fix;
+ u8 spn; /* Source port number */
+ bool stacking_port; /* Source port is stacking port */
+ bool mgnt_vlan; /* Packet arrived on management VLAN */
+ bool dmac_hit_sw; /* The packet's destination MAC matches one of the device's */
+ bool content_too_deep; /* The content of the packet cannot be parsed: too many layers */
+ bool not_first_frag; /* Not the first IP fragment */
+ u8 frame_type_l4; /* 0: UDP, 1: TCP, 2: ICMP/ICMPv6, 3: IGMP */
+ u8 frame_type; /* 0: ARP, 1: L2 only, 2: IPv4, 3: IPv6 */
+ bool otag_fmt; /* 0: outer tag packet, 1: outer priority tag or untagged */
+ bool itag_fmt; /* 0: inner tag packet, 1: inner priority tag or untagged */
+ bool otag_exist; /* packet with outer tag */
+ bool itag_exist; /* packet with inner tag */
+ bool frame_type_l2; /* 0: Ethernet, 1: LLC_SNAP, 2: LLC_Other, 3: Reserved */
+ bool igr_normal_port; /* Ingress port is not cpu or stacking port */
+ u8 tid; /* The template ID defining the what the templated fields mean */
+
+ /* Masks for the fields that are always matched against on RTL8380 */
+ u8 spmmask_fix_m;
+ u8 spn_m;
+ bool stacking_port_m;
+ bool mgnt_vlan_m;
+ bool dmac_hit_sw_m;
+ bool content_too_deep_m;
+ bool not_first_frag_m;
+ u8 frame_type_l4_m;
+ u8 frame_type_m;
+ bool otag_fmt_m;
+ bool itag_fmt_m;
+ bool otag_exist_m;
+ bool itag_exist_m;
+ bool frame_type_l2_m;
+ bool igr_normal_port_m;
+ u8 tid_m;
+
+ /* Logical operations between rules, special rules for rule numbers apply */
+ bool valid;
+ bool cond_not; /* Matches when conditions not match */
+ bool cond_and1; /* And this rule 2n with the next rule 2n+1 in same block */
+ bool cond_and2; /* And this rule m in block 2n with rule m in block 2n+1 */
+ bool ivalid;
+
+ /* Actions to be performed */
+ bool drop; /* Drop the packet */
+ bool fwd_sel; /* Forward packet: to port, portmask, dest route, next rule, drop */
+ bool ovid_sel; /* So something to outer vlan-id: shift, re-assign */
+ bool ivid_sel; /* Do something to inner vlan-id: shift, re-assign */
+ bool flt_sel; /* Filter the packet when sending to certain ports */
+ bool log_sel; /* Log the packet in one of the LOG-table counters */
+ bool rmk_sel; /* Re-mark the packet, i.e. change the priority-tag */
+ bool meter_sel; /* Meter the packet, i.e. limit rate of this type of packet */
+ bool tagst_sel; /* Change the ergress tag */
+ bool mir_sel; /* Mirror the packet to a Link Aggregation Group */
+ bool nopri_sel; /* Change the normal priority */
+ bool cpupri_sel; /* Change the CPU priority */
+ bool otpid_sel; /* Change Outer Tag Protocol Identifier (802.1q) */
+ bool itpid_sel; /* Change Inner Tag Protocol Identifier (802.1q) */
+ bool shaper_sel; /* Apply traffic shaper */
+ bool mpls_sel; /* MPLS actions */
+ bool bypass_sel; /* Bypass actions */
+ bool fwd_sa_lrn; /* Learn the source address when forwarding */
+ bool fwd_mod_to_cpu; /* Forward the modified VLAN tag format to CPU-port */
+
+ /* Fields used in predefined templates 0-2 on RTL8380 / 90 / 9300 */
+ u64 spm; /* Source Port Matrix */
+ u16 otag; /* Outer VLAN-ID */
+ u8 smac[ETH_ALEN]; /* Source MAC address */
+ u8 dmac[ETH_ALEN]; /* Destination MAC address */
+ u16 ethertype; /* Ethernet frame type field in ethernet header */
+ u16 itag; /* Inner VLAN-ID */
+ u16 field_range_check;
+ u32 sip; /* Source IP */
+ struct in6_addr sip6; /* IPv6 Source IP */
+ u32 dip; /* Destination IP */
+ struct in6_addr dip6; /* IPv6 Destination IP */
+ u16 tos_proto; /* IPv4: TOS + Protocol fields, IPv6: Traffic class + next header */
+ u16 sport; /* TCP/UDP source port */
+ u16 dport; /* TCP/UDP destination port */
+ u16 icmp_igmp;
+ u16 tcp_info;
+ u16 dsap_ssap; /* Destination / Source Service Access Point bytes (802.3) */
+
+ u64 spm_m;
+ u16 otag_m;
+ u8 smac_m[ETH_ALEN];
+ u8 dmac_m[ETH_ALEN];
+ u8 ethertype_m;
+ u16 itag_m;
+ u16 field_range_check_m;
+ u32 sip_m;
+ struct in6_addr sip6_m; /* IPv6 Source IP mask */
+ u32 dip_m;
+ struct in6_addr dip6_m; /* IPv6 Destination IP mask */
+ u16 tos_proto_m;
+ u16 sport_m;
+ u16 dport_m;
+ u16 icmp_igmp_m;
+ u16 tcp_info_m;
+ u16 dsap_ssap_m;
+
+ /* Data associated with actions */
+ u8 fwd_act; /* Type of forwarding action */
+ /* 0: permit, 1: drop, 2: copy to port id, 4: copy to portmask */
+ /* 4: redirect to portid, 5: redirect to portmask */
+ /* 6: route, 7: vlan leaky (only 8380) */
+ u16 fwd_data; /* Additional data for forwarding action, e.g. destination port */
+ u8 ovid_act;
+ u16 ovid_data; /* Outer VLAN ID */
+ u8 ivid_act;
+ u16 ivid_data; /* Inner VLAN ID */
+ u16 flt_data; /* Filtering data */
+ u16 log_data; /* ID of packet or octet counter in LOG table, on RTL93xx */
+ /* unnecessary since PIE-Rule-ID == LOG-counter-ID */
+ bool log_octets;
+ u8 mpls_act; /* MPLS action type */
+ u16 mpls_lib_idx; /* MPLS action data */
+
+ u16 rmk_data; /* Data for remarking */
+ u16 meter_data; /* ID of meter for bandwidth control */
+ u16 tagst_data;
+ u16 mir_data;
+ u16 nopri_data;
+ u16 cpupri_data;
+ u16 otpid_data;
+ u16 itpid_data;
+ u16 shaper_data;
+
+ /* Bypass actions, ignored on RTL8380 */
+ bool bypass_all; /* Not clear */
+ bool bypass_igr_stp; /* Bypass Ingress STP state */
+ bool bypass_ibc_sc; /* Bypass Ingress Bandwidth Control and Storm Control */
+};
+
+struct rtl838x_l3_intf {
+ u16 vid;
+ u8 smac_idx;
+ u8 ip4_mtu_id;
+ u8 ip6_mtu_id;
+ u16 ip4_mtu;
+ u16 ip6_mtu;
+ u8 ttl_scope;
+ u8 hl_scope;
+ u8 ip4_icmp_redirect;
+ u8 ip6_icmp_redirect;
+ u8 ip4_pbr_icmp_redirect;
+ u8 ip6_pbr_icmp_redirect;
+};
+
+/* An entry in the RTL93XX SoC's ROUTER_MAC tables setting up a termination point
+ * for the L3 routing system. Packets arriving and matching an entry in this table
+ * will be considered for routing.
+ * Mask fields state whether the corresponding data fields matter for matching
+ */
+struct rtl93xx_rt_mac {
+ bool valid; /* Valid or not */
+ bool p_type; /* Individual (0) or trunk (1) port */
+ bool p_mask; /* Whether the port type is used */
+ u8 p_id;
+ u8 p_id_mask; /* Mask for the port */
+ u8 action; /* Routing action performed: 0: FORWARD, 1: DROP, 2: TRAP2CPU */
+ /* 3: COPY2CPU, 4: TRAP2MASTERCPU, 5: COPY2MASTERCPU, 6: HARDDROP */
+ u16 vid;
+ u16 vid_mask;
+ u64 mac; /* MAC address used as source MAC in the routed packet */
+ u64 mac_mask;
+};
+
+struct rtl83xx_nexthop {
+ u16 id; /* ID: L3_NEXT_HOP table-index or route-index set in L2_NEXT_HOP */
+ u32 dev_id;
+ u16 port;
+ u16 vid; /* VLAN-ID for L2 table entry (saved from L2-UC entry) */
+ u16 rvid; /* Relay VID/FID for the L2 table entry */
+ u64 mac; /* The MAC address of the entry in the L2_NEXT_HOP table */
+ u16 mac_id;
+ u16 l2_id; /* Index of this next hop forwarding entry in L2 FIB table */
+ u64 gw; /* The gateway MAC address packets are forwarded to */
+ int if_id; /* Interface (into L3_EGR_INTF_IDX) */
+};
+
+struct rtl838x_switch_priv;
+
+struct rtl83xx_flow {
+ unsigned long cookie;
+ struct rhash_head node;
+ struct rcu_head rcu_head;
+ struct rtl838x_switch_priv *priv;
+ struct pie_rule rule;
+ u32 flags;
+};
+
+struct rtl93xx_route_attr {
+ bool valid;
+ bool hit;
+ bool ttl_dec;
+ bool ttl_check;
+ bool dst_null;
+ bool qos_as;
+ u8 qos_prio;
+ u8 type;
+ u8 action;
+};
+
+struct rtl83xx_route {
+ u32 gw_ip; /* IP of the route's gateway */
+ u32 dst_ip; /* IP of the destination net */
+ struct in6_addr dst_ip6;
+ int prefix_len; /* Network prefix len of the destination net */
+ bool is_host_route;
+ int id; /* ID number of this route */
+ struct rhlist_head linkage;
+ u16 switch_mac_id; /* Index into switch's own MACs, RTL839X only */
+ struct rtl83xx_nexthop nh;
+ struct pie_rule pr;
+ struct rtl93xx_route_attr attr;
+};
+
+struct rtl838x_reg {
+ void (*mask_port_reg_be)(u64 clear, u64 set, int reg);
+ void (*set_port_reg_be)(u64 set, int reg);
+ u64 (*get_port_reg_be)(int reg);
+ void (*mask_port_reg_le)(u64 clear, u64 set, int reg);
+ void (*set_port_reg_le)(u64 set, int reg);
+ u64 (*get_port_reg_le)(int reg);
+ int stat_port_rst;
+ int stat_rst;
+ int stat_port_std_mib;
+ int (*port_iso_ctrl)(int p);
+ void (*traffic_enable)(int source, int dest);
+ void (*traffic_disable)(int source, int dest);
+ void (*traffic_set)(int source, u64 dest_matrix);
+ u64 (*traffic_get)(int source);
+ int l2_ctrl_0;
+ int l2_ctrl_1;
+ int smi_poll_ctrl;
+ u32 l2_port_aging_out;
+ int l2_tbl_flush_ctrl;
+ void (*exec_tbl0_cmd)(u32 cmd);
+ void (*exec_tbl1_cmd)(u32 cmd);
+ int (*tbl_access_data_0)(int i);
+ int isr_glb_src;
+ int isr_port_link_sts_chg;
+ int imr_port_link_sts_chg;
+ int imr_glb;
+ void (*vlan_tables_read)(u32 vlan, struct rtl838x_vlan_info *info);
+ void (*vlan_set_tagged)(u32 vlan, struct rtl838x_vlan_info *info);
+ void (*vlan_set_untagged)(u32 vlan, u64 portmask);
+ void (*vlan_profile_dump)(int index);
+ void (*vlan_profile_setup)(int profile);
+ void (*vlan_port_pvidmode_set)(int port, enum pbvlan_type type, enum pbvlan_mode mode);
+ void (*vlan_port_pvid_set)(int port, enum pbvlan_type type, int pvid);
+ void (*vlan_port_keep_tag_set)(int port, bool keep_outer, bool keep_inner);
+ void (*set_vlan_igr_filter)(int port, enum igr_filter state);
+ void (*set_vlan_egr_filter)(int port, enum egr_filter state);
+ void (*enable_learning)(int port, bool enable);
+ void (*enable_flood)(int port, bool enable);
+ void (*enable_mcast_flood)(int port, bool enable);
+ void (*enable_bcast_flood)(int port, bool enable);
+ void (*set_static_move_action)(int port, bool forward);
+ void (*stp_get)(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]);
+ void (*stp_set)(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]);
+ int (*mac_force_mode_ctrl)(int port);
+ int (*mac_port_ctrl)(int port);
+ int (*l2_port_new_salrn)(int port);
+ int (*l2_port_new_sa_fwd)(int port);
+ int (*set_ageing_time)(unsigned long msec);
+ int mir_ctrl;
+ int mir_dpm;
+ int mir_spm;
+ int mac_link_sts;
+ int mac_link_dup_sts;
+ int (*mac_link_spd_sts)(int port);
+ int mac_rx_pause_sts;
+ int mac_tx_pause_sts;
+ u64 (*read_l2_entry_using_hash)(u32 hash, u32 position, struct rtl838x_l2_entry *e);
+ void (*write_l2_entry_using_hash)(u32 hash, u32 pos, struct rtl838x_l2_entry *e);
+ u64 (*read_cam)(int idx, struct rtl838x_l2_entry *e);
+ void (*write_cam)(int idx, struct rtl838x_l2_entry *e);
+ int (*trk_mbr_ctr)(int group);
+ int rma_bpdu_fld_pmask;
+ int spcl_trap_eapol_ctrl;
+ void (*init_eee)(struct rtl838x_switch_priv *priv, bool enable);
+ void (*port_eee_set)(struct rtl838x_switch_priv *priv, int port, bool enable);
+ int (*eee_port_ability)(struct rtl838x_switch_priv *priv,
+ struct ethtool_eee *e, int port);
+ u64 (*l2_hash_seed)(u64 mac, u32 vid);
+ u32 (*l2_hash_key)(struct rtl838x_switch_priv *priv, u64 seed);
+ u64 (*read_mcast_pmask)(int idx);
+ void (*write_mcast_pmask)(int idx, u64 portmask);
+ void (*vlan_fwd_on_inner)(int port, bool is_set);
+ void (*pie_init)(struct rtl838x_switch_priv *priv);
+ int (*pie_rule_read)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr);
+ int (*pie_rule_write)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr);
+ int (*pie_rule_add)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
+ void (*pie_rule_rm)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
+ void (*l2_learning_setup)(void);
+ u32 (*packet_cntr_read)(int counter);
+ void (*packet_cntr_clear)(int counter);
+ void (*route_read)(int idx, struct rtl83xx_route *rt);
+ void (*route_write)(int idx, struct rtl83xx_route *rt);
+ void (*host_route_write)(int idx, struct rtl83xx_route *rt);
+ int (*l3_setup)(struct rtl838x_switch_priv *priv);
+ void (*set_l3_nexthop)(int idx, u16 dmac_id, u16 interface);
+ void (*get_l3_nexthop)(int idx, u16 *dmac_id, u16 *interface);
+ u64 (*get_l3_egress_mac)(u32 idx);
+ void (*set_l3_egress_mac)(u32 idx, u64 mac);
+ int (*find_l3_slot)(struct rtl83xx_route *rt, bool must_exist);
+ int (*route_lookup_hw)(struct rtl83xx_route *rt);
+ void (*get_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m);
+ void (*set_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m);
+ void (*set_l3_egress_intf)(int idx, struct rtl838x_l3_intf *intf);
+ void (*set_distribution_algorithm)(int group, int algoidx, u32 algomask);
+ void (*set_receive_management_action)(int port, rma_ctrl_t type, action_type_t action);
+ void (*led_init)(struct rtl838x_switch_priv *priv);
+};
+
+struct rtl838x_switch_priv {
+ /* Switch operation */
+ struct dsa_switch *ds;
+ struct device *dev;
+ u16 id;
+ u16 family_id;
+ char version;
+ struct rtl838x_port ports[57];
+ struct rtl838x_pcs pcs[57];
+ struct mutex reg_mutex; /* Mutex for individual register manipulations */
+ struct mutex pie_mutex; /* Mutex for Packet Inspection Engine */
+ int link_state_irq;
+ int mirror_group_ports[4];
+ struct mii_bus *mii_bus;
+ const struct rtl838x_reg *r;
+ u8 cpu_port;
+ u8 port_mask;
+ u8 port_width;
+ u8 port_ignore;
+ u64 irq_mask;
+ u32 fib_entries;
+ int l2_bucket_size;
+ struct dentry *dbgfs_dir;
+ int n_lags;
+ u64 lags_port_members[MAX_LAGS];
+ struct net_device *lag_devs[MAX_LAGS];
+ u32 lag_primary[MAX_LAGS];
+ u32 is_lagmember[57];
+ u64 lagmembers;
+ struct notifier_block nb; /* TODO: change to different name */
+ struct notifier_block ne_nb;
+ struct notifier_block fib_nb;
+ bool eee_enabled;
+ unsigned long int mc_group_bm[MAX_MC_GROUPS >> 5];
+ int n_pie_blocks;
+ struct rhashtable tc_ht;
+ unsigned long int pie_use_bm[MAX_PIE_ENTRIES >> 5];
+ int n_counters;
+ unsigned long int octet_cntr_use_bm[MAX_COUNTERS >> 5];
+ unsigned long int packet_cntr_use_bm[MAX_COUNTERS >> 4];
+ struct rhltable routes;
+ unsigned long int route_use_bm[MAX_ROUTES >> 5];
+ unsigned long int host_route_use_bm[MAX_HOST_ROUTES >> 5];
+ struct rtl838x_l3_intf *interfaces[MAX_INTERFACES];
+ u16 intf_mtus[MAX_INTF_MTUS];
+ int intf_mtu_count[MAX_INTF_MTUS];
+};
+
+void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv);
+void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv);
+
+#endif /* _RTL838X_H */
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl839x.c
index 5889cea6d6..5889cea6d6 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl839x.c
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl839x.c
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl83xx.h
index 55a6851d46..55a6851d46 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl83xx.h
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl930x.c
index 793d762489..793d762489 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl930x.c
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl930x.c
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl931x.c
new file mode 100644
index 0000000000..2ba3a7819d
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl931x.c
@@ -0,0 +1,1694 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <asm/mach-rtl838x/mach-rtl83xx.h>
+#include <linux/etherdevice.h>
+
+#include "rtl83xx.h"
+
+#define RTL931X_VLAN_PORT_TAG_STS_INTERNAL 0x0
+#define RTL931X_VLAN_PORT_TAG_STS_UNTAG 0x1
+#define RTL931X_VLAN_PORT_TAG_STS_TAGGED 0x2
+#define RTL931X_VLAN_PORT_TAG_STS_PRIORITY_TAGGED 0x3
+
+#define RTL931X_VLAN_PORT_TAG_CTRL_BASE 0x4860
+/* port 0-56 */
+#define RTL931X_VLAN_PORT_TAG_CTRL(port) \
+ RTL931X_VLAN_PORT_TAG_CTRL_BASE + (port << 2)
+#define RTL931X_VLAN_PORT_TAG_EGR_OTAG_STS_MASK GENMASK(13,12)
+#define RTL931X_VLAN_PORT_TAG_EGR_ITAG_STS_MASK GENMASK(11,10)
+#define RTL931X_VLAN_PORT_TAG_EGR_OTAG_KEEP_MASK GENMASK(9,9)
+#define RTL931X_VLAN_PORT_TAG_EGR_ITAG_KEEP_MASK GENMASK(8,8)
+#define RTL931X_VLAN_PORT_TAG_IGR_OTAG_KEEP_MASK GENMASK(7,7)
+#define RTL931X_VLAN_PORT_TAG_IGR_ITAG_KEEP_MASK GENMASK(6,6)
+#define RTL931X_VLAN_PORT_TAG_OTPID_IDX_MASK GENMASK(5,4)
+#define RTL931X_VLAN_PORT_TAG_OTPID_KEEP_MASK GENMASK(3,3)
+#define RTL931X_VLAN_PORT_TAG_ITPID_IDX_MASK GENMASK(2,1)
+#define RTL931X_VLAN_PORT_TAG_ITPID_KEEP_MASK GENMASK(0,0)
+
+extern struct mutex smi_lock;
+extern struct rtl83xx_soc_info soc_info;
+
+/* Definition of the RTL931X-specific template field IDs as used in the PIE */
+enum template_field_id {
+ TEMPLATE_FIELD_SPM0 = 1,
+ TEMPLATE_FIELD_SPM1 = 2,
+ TEMPLATE_FIELD_SPM2 = 3,
+ TEMPLATE_FIELD_SPM3 = 4,
+ TEMPLATE_FIELD_DMAC0 = 9,
+ TEMPLATE_FIELD_DMAC1 = 10,
+ TEMPLATE_FIELD_DMAC2 = 11,
+ TEMPLATE_FIELD_SMAC0 = 12,
+ TEMPLATE_FIELD_SMAC1 = 13,
+ TEMPLATE_FIELD_SMAC2 = 14,
+ TEMPLATE_FIELD_ETHERTYPE = 15,
+ TEMPLATE_FIELD_OTAG = 16,
+ TEMPLATE_FIELD_ITAG = 17,
+ TEMPLATE_FIELD_SIP0 = 18,
+ TEMPLATE_FIELD_SIP1 = 19,
+ TEMPLATE_FIELD_DIP0 = 20,
+ TEMPLATE_FIELD_DIP1 = 21,
+ TEMPLATE_FIELD_IP_TOS_PROTO = 22,
+ TEMPLATE_FIELD_L4_SPORT = 23,
+ TEMPLATE_FIELD_L4_DPORT = 24,
+ TEMPLATE_FIELD_L34_HEADER = 25,
+ TEMPLATE_FIELD_TCP_INFO = 26,
+ TEMPLATE_FIELD_SIP2 = 34,
+ TEMPLATE_FIELD_SIP3 = 35,
+ TEMPLATE_FIELD_SIP4 = 36,
+ TEMPLATE_FIELD_SIP5 = 37,
+ TEMPLATE_FIELD_SIP6 = 38,
+ TEMPLATE_FIELD_SIP7 = 39,
+ TEMPLATE_FIELD_DIP2 = 42,
+ TEMPLATE_FIELD_DIP3 = 43,
+ TEMPLATE_FIELD_DIP4 = 44,
+ TEMPLATE_FIELD_DIP5 = 45,
+ TEMPLATE_FIELD_DIP6 = 46,
+ TEMPLATE_FIELD_DIP7 = 47,
+ TEMPLATE_FIELD_FLOW_LABEL = 49,
+ TEMPLATE_FIELD_DSAP_SSAP = 50,
+ TEMPLATE_FIELD_FWD_VID = 52,
+ TEMPLATE_FIELD_RANGE_CHK = 53,
+ TEMPLATE_FIELD_SLP = 55,
+ TEMPLATE_FIELD_DLP = 56,
+ TEMPLATE_FIELD_META_DATA = 57,
+ TEMPLATE_FIELD_FIRST_MPLS1 = 60,
+ TEMPLATE_FIELD_FIRST_MPLS2 = 61,
+ TEMPLATE_FIELD_DPM3 = 8,
+};
+
+/* The meaning of TEMPLATE_FIELD_VLAN depends on phase and the configuration in
+ * RTL931X_PIE_CTRL. We use always the same definition and map to the inner VLAN tag:
+ */
+#define TEMPLATE_FIELD_VLAN TEMPLATE_FIELD_ITAG
+
+/* Number of fixed templates predefined in the RTL9300 SoC */
+#define N_FIXED_TEMPLATES 5
+/* RTL931x specific predefined templates */
+static enum template_field_id fixed_templates[N_FIXED_TEMPLATES][N_FIXED_FIELDS_RTL931X] =
+{
+ {
+ TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2,
+ TEMPLATE_FIELD_SMAC0, TEMPLATE_FIELD_SMAC1, TEMPLATE_FIELD_SMAC2,
+ TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_DSAP_SSAP,
+ TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1,
+ TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3
+ }, {
+ TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0,
+ TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_TCP_INFO,
+ TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_VLAN,
+ TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1,
+ TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3
+ }, {
+ TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2,
+ TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_IP_TOS_PROTO,
+ TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0,
+ TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT,
+ TEMPLATE_FIELD_META_DATA, TEMPLATE_FIELD_SLP
+ }, {
+ TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_DIP2,
+ TEMPLATE_FIELD_DIP3, TEMPLATE_FIELD_DIP4, TEMPLATE_FIELD_DIP5,
+ TEMPLATE_FIELD_DIP6, TEMPLATE_FIELD_DIP7, TEMPLATE_FIELD_IP_TOS_PROTO,
+ TEMPLATE_FIELD_TCP_INFO, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT,
+ TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SLP
+ }, {
+ TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_SIP2,
+ TEMPLATE_FIELD_SIP3, TEMPLATE_FIELD_SIP4, TEMPLATE_FIELD_SIP5,
+ TEMPLATE_FIELD_SIP6, TEMPLATE_FIELD_SIP7, TEMPLATE_FIELD_META_DATA,
+ TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1,
+ TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3
+ },
+};
+
+inline void rtl931x_exec_tbl0_cmd(u32 cmd)
+{
+ sw_w32(cmd, RTL931X_TBL_ACCESS_CTRL_0);
+ do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_0) & (1 << 20));
+}
+
+inline void rtl931x_exec_tbl1_cmd(u32 cmd)
+{
+ sw_w32(cmd, RTL931X_TBL_ACCESS_CTRL_1);
+ do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_1) & (1 << 17));
+}
+
+inline int rtl931x_tbl_access_data_0(int i)
+{
+ return RTL931X_TBL_ACCESS_DATA_0(i);
+}
+
+void rtl931x_vlan_profile_dump(int index)
+{
+ u64 profile[4];
+
+ if (index < 0 || index > 15)
+ return;
+
+ profile[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(index));
+ profile[1] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 4) & 0x1FFFFFFFULL) << 32 |
+ (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 8) & 0xFFFFFFFF);
+ profile[2] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 16) & 0x1FFFFFFFULL) << 32 |
+ (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 12) & 0xFFFFFFFF);
+ profile[3] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 20) & 0x1FFFFFFFULL) << 32 |
+ (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 24) & 0xFFFFFFFF);
+
+ pr_info("VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %llx, \
+ IPv4 Unknown MultiCast Field %llx, IPv6 Unknown MultiCast Field: %llx",
+ index, (u32) (profile[0] & (3 << 14)), profile[1], profile[2], profile[3]);
+}
+
+static void rtl931x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
+{
+ u32 cmd = 1 << 20 | /* Execute cmd */
+ 0 << 19 | /* Read */
+ 5 << 15 | /* Table type 0b101 */
+ (msti & 0x3fff);
+ priv->r->exec_tbl0_cmd(cmd);
+
+ for (int i = 0; i < 4; i++)
+ port_state[i] = sw_r32(priv->r->tbl_access_data_0(i));
+}
+
+static void rtl931x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
+{
+ u32 cmd = 1 << 20 | /* Execute cmd */
+ 1 << 19 | /* Write */
+ 5 << 15 | /* Table type 0b101 */
+ (msti & 0x3fff);
+ for (int i = 0; i < 4; i++)
+ sw_w32(port_state[i], priv->r->tbl_access_data_0(i));
+ priv->r->exec_tbl0_cmd(cmd);
+}
+
+inline static int rtl931x_trk_mbr_ctr(int group)
+{
+ return RTL931X_TRK_MBR_CTRL + (group << 2);
+}
+
+static void rtl931x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info)
+{
+ u32 v, w, x, y;
+ /* Read VLAN table (3) via register 0 */
+ struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 3);
+
+ rtl_table_read(r, vlan);
+ v = sw_r32(rtl_table_data(r, 0));
+ w = sw_r32(rtl_table_data(r, 1));
+ x = sw_r32(rtl_table_data(r, 2));
+ y = sw_r32(rtl_table_data(r, 3));
+ rtl_table_release(r);
+
+ pr_debug("VLAN_READ %d: %08x %08x %08x %08x\n", vlan, v, w, x, y);
+ info->tagged_ports = ((u64) v) << 25 | (w >> 7);
+ info->profile_id = (x >> 16) & 0xf;
+ info->fid = w & 0x7f; /* AKA MSTI depending on context */
+ info->hash_uc_fid = !!(x & BIT(31));
+ info->hash_mc_fid = !!(x & BIT(30));
+ info->if_id = (x >> 20) & 0x3ff;
+ info->profile_id = (x >> 16) & 0xf;
+ info->multicast_grp_mask = x & 0xffff;
+ if (x & BIT(31))
+ info->l2_tunnel_list_id = y >> 18;
+ else
+ info->l2_tunnel_list_id = -1;
+ pr_debug("%s read tagged %016llx, profile-id %d, uc %d, mc %d, intf-id %d\n", __func__,
+ info->tagged_ports, info->profile_id, info->hash_uc_fid, info->hash_mc_fid,
+ info->if_id);
+
+ /* Read UNTAG table via table register 3 */
+ r = rtl_table_get(RTL9310_TBL_3, 0);
+ rtl_table_read(r, vlan);
+ v = ((u64)sw_r32(rtl_table_data(r, 0))) << 25;
+ v |= sw_r32(rtl_table_data(r, 1)) >> 7;
+ rtl_table_release(r);
+
+ info->untagged_ports = v;
+}
+
+static void rtl931x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info)
+{
+ u32 v, w, x, y;
+ /* Access VLAN table (1) via register 0 */
+ struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 3);
+
+ v = info->tagged_ports >> 25;
+ w = (info->tagged_ports & 0x1fffff) << 7;
+ w |= info->fid & 0x7f;
+ x = info->hash_uc_fid ? BIT(31) : 0;
+ x |= info->hash_mc_fid ? BIT(30) : 0;
+ x |= info->if_id & 0x3ff << 20;
+ x |= (info->profile_id & 0xf) << 16;
+ x |= info->multicast_grp_mask & 0xffff;
+ if (info->l2_tunnel_list_id >= 0) {
+ y = info->l2_tunnel_list_id << 18;
+ y |= BIT(31);
+ } else {
+ y = 0;
+ }
+
+ sw_w32(v, rtl_table_data(r, 0));
+ sw_w32(w, rtl_table_data(r, 1));
+ sw_w32(x, rtl_table_data(r, 2));
+ sw_w32(y, rtl_table_data(r, 3));
+
+ rtl_table_write(r, vlan);
+ rtl_table_release(r);
+}
+
+static void rtl931x_vlan_set_untagged(u32 vlan, u64 portmask)
+{
+ struct table_reg *r = rtl_table_get(RTL9310_TBL_3, 0);
+
+ rtl839x_set_port_reg_be(portmask << 7, rtl_table_data(r, 0));
+ rtl_table_write(r, vlan);
+ rtl_table_release(r);
+}
+
+static inline int rtl931x_mac_force_mode_ctrl(int p)
+{
+ return RTL931X_MAC_FORCE_MODE_CTRL + (p << 2);
+}
+
+static inline int rtl931x_mac_link_spd_sts(int p)
+{
+ return RTL931X_MAC_LINK_SPD_STS + (((p >> 3) << 2));
+}
+
+static inline int rtl931x_mac_port_ctrl(int p)
+{
+ return RTL931X_MAC_L2_PORT_CTRL + (p << 7);
+}
+
+static inline int rtl931x_l2_port_new_salrn(int p)
+{
+ return RTL931X_L2_PORT_NEW_SALRN(p);
+}
+
+static inline int rtl931x_l2_port_new_sa_fwd(int p)
+{
+ return RTL931X_L2_PORT_NEW_SA_FWD(p);
+}
+
+irqreturn_t rtl931x_switch_irq(int irq, void *dev_id)
+{
+ struct dsa_switch *ds = dev_id;
+ u32 status = sw_r32(RTL931X_ISR_GLB_SRC);
+ u64 ports = rtl839x_get_port_reg_le(RTL931X_ISR_PORT_LINK_STS_CHG);
+ u64 link;
+
+ /* Clear status */
+ rtl839x_set_port_reg_le(ports, RTL931X_ISR_PORT_LINK_STS_CHG);
+ pr_debug("RTL931X Link change: status: %x, ports %016llx\n", status, ports);
+
+ link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS);
+ /* Must re-read this to get correct status */
+ link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS);
+ pr_debug("RTL931X Link change: status: %x, link status %016llx\n", status, link);
+
+ for (int i = 0; i < 56; i++) {
+ if (ports & BIT_ULL(i)) {
+ if (link & BIT_ULL(i)) {
+ pr_info("%s port %d up\n", __func__, i);
+ dsa_port_phylink_mac_change(ds, i, true);
+ } else {
+ pr_info("%s port %d down\n", __func__, i);
+ dsa_port_phylink_mac_change(ds, i, false);
+ }
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val)
+{
+ u32 v;
+ int err = 0;
+
+ val &= 0xffff;
+ if (port > 63 || page > 4095 || reg > 31)
+ return -ENOTSUPP;
+
+ mutex_lock(&smi_lock);
+ pr_debug("%s: writing to phy %d %d %d %d\n", __func__, port, page, reg, val);
+ /* Clear both port registers */
+ sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2);
+ sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4);
+ sw_w32_mask(0, BIT(port % 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + (port / 32) * 4);
+
+ sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3);
+
+ v = reg << 6 | page << 11 ;
+ sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+
+ sw_w32(0x1ff, RTL931X_SMI_INDRT_ACCESS_CTRL_1);
+
+ v |= BIT(4) | 1; /* Write operation and execute */
+ sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+
+ do {
+ } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1);
+
+ if (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x2)
+ err = -EIO;
+
+ mutex_unlock(&smi_lock);
+
+ return err;
+}
+
+int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
+{
+ u32 v;
+
+ if (port > 63 || page > 4095 || reg > 31)
+ return -ENOTSUPP;
+
+ mutex_lock(&smi_lock);
+
+ sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL);
+
+ v = reg << 6 | page << 11 | 1;
+ sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+
+ do {
+ } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1);
+
+ v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+ *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3);
+ *val = (*val & 0xffff0000) >> 16;
+
+ pr_debug("%s: port %d, page: %d, reg: %x, val: %x, v: %08x\n",
+ __func__, port, page, reg, *val, v);
+
+ mutex_unlock(&smi_lock);
+
+ return 0;
+}
+
+/* Read an mmd register of the PHY */
+int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val)
+{
+ int err = 0;
+ u32 v;
+ /* Select PHY register type
+ * If select 1G/10G MMD register type, registers EXT_PAGE, MAIN_PAGE and REG settings are don’t care.
+ * 0x0 Normal register (Clause 22)
+ * 0x1: 1G MMD register (MMD via Clause 22 registers 13 and 14)
+ * 0x2: 10G MMD register (MMD via Clause 45)
+ */
+ int type = 2;
+
+ mutex_lock(&smi_lock);
+
+ /* Set PHY to access via port-number */
+ sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL);
+
+ /* Set MMD device number and register to write to */
+ sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL);
+
+ v = type << 2 | BIT(0); /* MMD-access-type | EXEC */
+ sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+
+ do {
+ v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+ } while (v & BIT(0));
+
+ /* Check for error condition */
+ if (v & BIT(1))
+ err = -EIO;
+
+ *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3) >> 16;
+
+ pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__,
+ port, devnum, regnum, *val, err);
+
+ mutex_unlock(&smi_lock);
+
+ return err;
+}
+
+/* Write to an mmd register of the PHY */
+int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val)
+{
+ int err = 0;
+ u32 v;
+ int type = 2;
+ u64 pm;
+
+ mutex_lock(&smi_lock);
+
+ /* Set PHY to access via port-mask */
+ pm = (u64)1 << port;
+ sw_w32((u32)pm, RTL931X_SMI_INDRT_ACCESS_CTRL_2);
+ sw_w32((u32)(pm >> 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4);
+
+ /* Set data to write */
+ sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3);
+
+ /* Set MMD device number and register to write to */
+ sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL);
+
+ v = BIT(4) | type << 2 | BIT(0); /* WRITE | MMD-access-type | EXEC */
+ sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+
+ do {
+ v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+ } while (v & BIT(0));
+
+ pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__,
+ port, devnum, regnum, val, err);
+ mutex_unlock(&smi_lock);
+
+ return err;
+}
+
+void rtl931x_print_matrix(void)
+{
+ volatile u64 *ptr = RTL838X_SW_BASE + RTL839X_PORT_ISO_CTRL(0);
+
+ for (int i = 0; i < 52; i += 4)
+ pr_info("> %16llx %16llx %16llx %16llx\n",
+ ptr[i + 0], ptr[i + 1], ptr[i + 2], ptr[i + 3]);
+ pr_info("CPU_PORT> %16llx\n", ptr[52]);
+}
+
+void rtl931x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action)
+{
+ u32 value = 0;
+
+ /* hack for value mapping */
+ if (type == GRATARP && action == COPY2CPU)
+ action = TRAP2MASTERCPU;
+
+ switch(action) {
+ case FORWARD:
+ value = 0;
+ break;
+ case DROP:
+ value = 1;
+ break;
+ case TRAP2CPU:
+ value = 2;
+ break;
+ case TRAP2MASTERCPU:
+ value = 3;
+ break;
+ case FLOODALL:
+ value = 4;
+ break;
+ default:
+ break;
+ }
+
+ switch(type) {
+ case BPDU:
+ sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_BPDU_CTRL + ((port / 10) << 2));
+ break;
+ case PTP:
+ /* udp */
+ sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2));
+ /* eth2 */
+ sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2));
+ break;
+ case PTP_UDP:
+ sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2));
+ break;
+ case PTP_ETH2:
+ sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2));
+ break;
+ case LLDP:
+ sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_LLDP_CTRL + ((port / 10) << 2));
+ break;
+ case EAPOL:
+ sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_EAPOL_CTRL + ((port / 10) << 2));
+ break;
+ case GRATARP:
+ sw_w32_mask(3 << ((port & 0xf) << 1), value << ((port & 0xf) << 1), RTL931X_TRAP_ARP_GRAT_PORT_ACT + ((port >> 4) << 2));
+ break;
+ }
+}
+
+u64 rtl931x_traffic_get(int source)
+{
+ u32 v;
+ struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
+
+ rtl_table_read(r, source);
+ v = sw_r32(rtl_table_data(r, 0));
+ rtl_table_release(r);
+ v = v >> 3;
+
+ return v;
+}
+
+/* Enable traffic between a source port and a destination port matrix */
+void rtl931x_traffic_set(int source, u64 dest_matrix)
+{
+ struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
+
+ sw_w32((dest_matrix << 3), rtl_table_data(r, 0));
+ rtl_table_write(r, source);
+ rtl_table_release(r);
+}
+
+void rtl931x_traffic_enable(int source, int dest)
+{
+ struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
+ rtl_table_read(r, source);
+ sw_w32_mask(0, BIT(dest + 3), rtl_table_data(r, 0));
+ rtl_table_write(r, source);
+ rtl_table_release(r);
+}
+
+void rtl931x_traffic_disable(int source, int dest)
+{
+ struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6);
+ rtl_table_read(r, source);
+ sw_w32_mask(BIT(dest + 3), 0, rtl_table_data(r, 0));
+ rtl_table_write(r, source);
+ rtl_table_release(r);
+}
+
+static u64 rtl931x_l2_hash_seed(u64 mac, u32 vid)
+{
+ u64 v = vid;
+
+ v <<= 48;
+ v |= mac;
+
+ return v;
+}
+
+/* Calculate both the block 0 and the block 1 hash by applyingthe same hash
+ * algorithm as the one used currently by the ASIC to the seed, and return
+ * both hashes in the lower and higher word of the return value since only 12 bit of
+ * the hash are significant.
+ */
+static u32 rtl931x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed)
+{
+ u32 h, h0, h1, h2, h3, h4, k0, k1;
+
+ h0 = seed & 0xfff;
+ h1 = (seed >> 12) & 0xfff;
+ h2 = (seed >> 24) & 0xfff;
+ h3 = (seed >> 36) & 0xfff;
+ h4 = (seed >> 48) & 0xfff;
+ h4 = ((h4 & 0x7) << 9) | ((h4 >> 3) & 0x1ff);
+ k0 = h0 ^ h1 ^ h2 ^ h3 ^ h4;
+
+ h0 = seed & 0xfff;
+ h0 = ((h0 & 0x1ff) << 3) | ((h0 >> 9) & 0x7);
+ h1 = (seed >> 12) & 0xfff;
+ h1 = ((h1 & 0x3f) << 6) | ((h1 >> 6) & 0x3f);
+ h2 = (seed >> 24) & 0xfff;
+ h3 = (seed >> 36) & 0xfff;
+ h3 = ((h3 & 0x3f) << 6) | ((h3 >> 6) & 0x3f);
+ h4 = (seed >> 48) & 0xfff;
+ k1 = h0 ^ h1 ^ h2 ^ h3 ^ h4;
+
+ /* Algorithm choice for block 0 */
+ if (sw_r32(RTL931X_L2_CTRL) & BIT(0))
+ h = k1;
+ else
+ h = k0;
+
+ /* Algorithm choice for block 1
+ * Since k0 and k1 are < 4096, adding 4096 will offset the hash into the second
+ * half of hash-space
+ * 4096 is in fact the hash-table size 32768 divided by 4 hashes per bucket
+ * divided by 2 to divide the hash space in 2
+ */
+ if (sw_r32(RTL931X_L2_CTRL) & BIT(1))
+ h |= (k1 + 4096) << 16;
+ else
+ h |= (k0 + 4096) << 16;
+
+ return h;
+}
+
+/* Fills an L2 entry structure from the SoC registers */
+static void rtl931x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e)
+{
+ pr_debug("In %s valid?\n", __func__);
+ e->valid = !!(r[0] & BIT(31));
+ if (!e->valid)
+ return;
+
+ pr_debug("%s: entry valid, raw: %08x %08x %08x %08x\n", __func__, r[0], r[1], r[2], r[3]);
+ e->is_ip_mc = false;
+ e->is_ipv6_mc = false;
+
+ e->mac[0] = r[0] >> 8;
+ e->mac[1] = r[0];
+ e->mac[2] = r[1] >> 24;
+ e->mac[3] = r[1] >> 16;
+ e->mac[4] = r[1] >> 8;
+ e->mac[5] = r[1];
+
+ e->is_open_flow = !!(r[0] & BIT(30));
+ e->is_pe_forward = !!(r[0] & BIT(29));
+ e->next_hop = !!(r[2] & BIT(30));
+ e->rvid = (r[0] >> 16) & 0xfff;
+
+ /* Is it a unicast entry? check multicast bit */
+ if (!(e->mac[0] & 1)) {
+ e->type = L2_UNICAST;
+ e->is_l2_tunnel = !!(r[2] & BIT(31));
+ e->is_static = !!(r[2] & BIT(13));
+ e->port = (r[2] >> 19) & 0x3ff;
+ /* Check for trunk port */
+ if (r[2] & BIT(29)) {
+ e->is_trunk = true;
+ e->stack_dev = (e->port >> 9) & 1;
+ e->trunk = e->port & 0x3f;
+ } else {
+ e->is_trunk = false;
+ e->stack_dev = (e->port >> 6) & 0xf;
+ e->port = e->port & 0x3f;
+ }
+
+ e->block_da = !!(r[2] & BIT(14));
+ e->block_sa = !!(r[2] & BIT(15));
+ e->suspended = !!(r[2] & BIT(12));
+ e->age = (r[2] >> 16) & 3;
+
+ /* the UC_VID field in hardware is used for the VID or for the route id */
+ if (e->next_hop) {
+ e->nh_route_id = r[2] & 0x7ff;
+ e->vid = 0;
+ } else {
+ e->vid = r[2] & 0xfff;
+ e->nh_route_id = 0;
+ }
+ if (e->is_l2_tunnel)
+ e->l2_tunnel_id = ((r[2] & 0xff) << 4) | (r[3] >> 28);
+ /* TODO: Implement VLAN conversion */
+ } else {
+ e->type = L2_MULTICAST;
+ e->is_local_forward = !!(r[2] & BIT(31));
+ e->is_remote_forward = !!(r[2] & BIT(17));
+ e->mc_portmask_index = (r[2] >> 18) & 0xfff;
+ e->l2_tunnel_list_id = (r[2] >> 4) & 0x1fff;
+ }
+}
+
+/* Fills the 3 SoC table registers r[] with the information of in the rtl838x_l2_entry */
+static void rtl931x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e)
+{
+ u32 port;
+
+ if (!e->valid) {
+ r[0] = r[1] = r[2] = 0;
+ return;
+ }
+
+ r[2] = BIT(31); /* Set valid bit */
+
+ r[0] = ((u32)e->mac[0]) << 24 |
+ ((u32)e->mac[1]) << 16 |
+ ((u32)e->mac[2]) << 8 |
+ ((u32)e->mac[3]);
+ r[1] = ((u32)e->mac[4]) << 24 |
+ ((u32)e->mac[5]) << 16;
+
+ r[2] |= e->next_hop ? BIT(12) : 0;
+
+ if (e->type == L2_UNICAST) {
+ r[2] |= e->is_static ? BIT(14) : 0;
+ r[1] |= e->rvid & 0xfff;
+ r[2] |= (e->port & 0x3ff) << 20;
+ if (e->is_trunk) {
+ r[2] |= BIT(30);
+ port = e->stack_dev << 9 | (e->port & 0x3f);
+ } else {
+ port = (e->stack_dev & 0xf) << 6;
+ port |= e->port & 0x3f;
+ }
+ r[2] |= port << 20;
+ r[2] |= e->block_da ? BIT(15) : 0;
+ r[2] |= e->block_sa ? BIT(17) : 0;
+ r[2] |= e->suspended ? BIT(13) : 0;
+ r[2] |= (e->age & 0x3) << 17;
+ /* the UC_VID field in hardware is used for the VID or for the route id */
+ if (e->next_hop)
+ r[2] |= e->nh_route_id & 0x7ff;
+ else
+ r[2] |= e->vid & 0xfff;
+ } else { /* L2_MULTICAST */
+ r[2] |= (e->mc_portmask_index & 0x3ff) << 16;
+ r[2] |= e->mc_mac_index & 0x7ff;
+ }
+}
+
+/* Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table
+ * hash is the id of the bucket and pos is the position of the entry in that bucket
+ * The data read from the SoC is filled into rtl838x_l2_entry
+ */
+static u64 rtl931x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
+{
+ u32 r[4];
+ struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 0);
+ u32 idx;
+ u64 mac;
+ u64 seed;
+
+ pr_debug("%s: hash %08x, pos: %d\n", __func__, hash, pos);
+
+ /* On the RTL93xx, 2 different hash algorithms are used making it a total of
+ * 8 buckets that need to be searched, 4 for each hash-half
+ * Use second hash space when bucket is between 4 and 8
+ */
+ if (pos >= 4) {
+ pos -= 4;
+ hash >>= 16;
+ } else {
+ hash &= 0xffff;
+ }
+
+ idx = (0 << 14) | (hash << 2) | pos; /* Search SRAM, with hash and at pos in bucket */
+ pr_debug("%s: NOW hash %08x, pos: %d\n", __func__, hash, pos);
+
+ rtl_table_read(q, idx);
+ for (int i = 0; i < 4; i++)
+ r[i] = sw_r32(rtl_table_data(q, i));
+
+ rtl_table_release(q);
+
+ rtl931x_fill_l2_entry(r, e);
+
+ pr_debug("%s: valid: %d, nh: %d\n", __func__, e->valid, e->next_hop);
+ if (!e->valid)
+ return 0;
+
+ mac = ((u64)e->mac[0]) << 40 |
+ ((u64)e->mac[1]) << 32 |
+ ((u64)e->mac[2]) << 24 |
+ ((u64)e->mac[3]) << 16 |
+ ((u64)e->mac[4]) << 8 |
+ ((u64)e->mac[5]);
+
+ seed = rtl931x_l2_hash_seed(mac, e->rvid);
+ pr_debug("%s: mac %016llx, seed %016llx\n", __func__, mac, seed);
+
+ /* return vid with concatenated mac as unique id */
+ return seed;
+}
+
+static u64 rtl931x_read_cam(int idx, struct rtl838x_l2_entry *e)
+{
+ return 0;
+}
+
+static void rtl931x_write_cam(int idx, struct rtl838x_l2_entry *e)
+{
+}
+
+static void rtl931x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
+{
+ u32 r[4];
+ struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 0);
+ u32 idx = (0 << 14) | (hash << 2) | pos; /* Access SRAM, with hash and at pos in bucket */
+
+ pr_info("%s: hash %d, pos %d\n", __func__, hash, pos);
+ pr_info("%s: index %d -> mac %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, idx,
+ e->mac[0], e->mac[1], e->mac[2], e->mac[3],e->mac[4],e->mac[5]);
+
+ rtl931x_fill_l2_row(r, e);
+ pr_info("%s: %d: %08x %08x %08x\n", __func__, idx, r[0], r[1], r[2]);
+
+ for (int i = 0; i < 4; i++)
+ sw_w32(r[i], rtl_table_data(q, i));
+
+ rtl_table_write(q, idx);
+ rtl_table_release(q);
+}
+
+static void rtl931x_vlan_fwd_on_inner(int port, bool is_set)
+{
+ /* Always set all tag modes to fwd based on either inner or outer tag */
+ if (is_set)
+ sw_w32_mask(0xf, 0, RTL931X_VLAN_PORT_FWD + (port << 2));
+ else
+ sw_w32_mask(0, 0xf, RTL931X_VLAN_PORT_FWD + (port << 2));
+}
+
+static void rtl931x_vlan_profile_setup(int profile)
+{
+ u32 p[7];
+
+ pr_info("In %s\n", __func__);
+
+ if (profile > 15)
+ return;
+
+ p[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(profile));
+
+ /* Enable routing of Ipv4/6 Unicast and IPv4/6 Multicast traffic */
+ /* p[0] |= BIT(17) | BIT(16) | BIT(13) | BIT(12); */
+ p[0] |= 0x3 << 11; /* COPY2CPU */
+
+ p[1] = 0x1FFFFFF; /* L2 unknwon MC flooding portmask all ports, including the CPU-port */
+ p[2] = 0xFFFFFFFF;
+ p[3] = 0x1FFFFFF; /* IPv4 unknwon MC flooding portmask */
+ p[4] = 0xFFFFFFFF;
+ p[5] = 0x1FFFFFF; /* IPv6 unknwon MC flooding portmask */
+ p[6] = 0xFFFFFFFF;
+
+ for (int i = 0; i < 7; i++)
+ sw_w32(p[i], RTL931X_VLAN_PROFILE_SET(profile) + i * 4);
+ pr_info("Leaving %s\n", __func__);
+}
+
+static void rtl931x_l2_learning_setup(void)
+{
+ /* Portmask for flooding broadcast traffic */
+ rtl839x_set_port_reg_be(0x1FFFFFFFFFFFFFF, RTL931X_L2_BC_FLD_PMSK);
+
+ /* Portmask for flooding unicast traffic with unknown destination */
+ rtl839x_set_port_reg_be(0x1FFFFFFFFFFFFFF, RTL931X_L2_UNKN_UC_FLD_PMSK);
+
+ /* Limit learning to maximum: 64k entries, after that just flood (bits 0-2) */
+ sw_w32((0xffff << 3) | FORWARD, RTL931X_L2_LRN_CONSTRT_CTRL);
+}
+
+static u64 rtl931x_read_mcast_pmask(int idx)
+{
+ u64 portmask;
+ /* Read MC_PMSK (2) via register RTL9310_TBL_0 */
+ struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 2);
+
+ rtl_table_read(q, idx);
+ portmask = sw_r32(rtl_table_data(q, 0));
+ portmask <<= 32;
+ portmask |= sw_r32(rtl_table_data(q, 1));
+ portmask >>= 7;
+ rtl_table_release(q);
+
+ pr_debug("%s: Index idx %d has portmask %016llx\n", __func__, idx, portmask);
+
+ return portmask;
+}
+
+static void rtl931x_write_mcast_pmask(int idx, u64 portmask)
+{
+ u64 pm = portmask;
+
+ /* Access MC_PMSK (2) via register RTL9310_TBL_0 */
+ struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 2);
+
+ pr_debug("%s: Index idx %d has portmask %016llx\n", __func__, idx, pm);
+ pm <<= 7;
+ sw_w32((u32)(pm >> 32), rtl_table_data(q, 0));
+ sw_w32((u32)pm, rtl_table_data(q, 1));
+ rtl_table_write(q, idx);
+ rtl_table_release(q);
+}
+
+
+static int rtl931x_set_ageing_time(unsigned long msec)
+{
+ int t = sw_r32(RTL931X_L2_AGE_CTRL);
+
+ t &= 0x1FFFFF;
+ t = (t * 8) / 10;
+ pr_debug("L2 AGING time: %d sec\n", t);
+
+ t = (msec / 100 + 7) / 8;
+ t = t > 0x1FFFFF ? 0x1FFFFF : t;
+ sw_w32_mask(0x1FFFFF, t, RTL931X_L2_AGE_CTRL);
+ pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL931X_L2_PORT_AGE_CTRL));
+
+ return 0;
+}
+void rtl931x_sw_init(struct rtl838x_switch_priv *priv)
+{
+/* rtl931x_sds_init(priv); */
+}
+
+static void rtl931x_pie_lookup_enable(struct rtl838x_switch_priv *priv, int index)
+{
+ int block = index / PIE_BLOCK_SIZE;
+
+ sw_w32_mask(0, BIT(block), RTL931X_PIE_BLK_LOOKUP_CTRL);
+}
+
+/* Fills the data in the intermediate representation in the pie_rule structure
+ * into a data field for a given template field field_type
+ * TODO: This function looks very similar to the function of the rtl9300, but
+ * since it uses the physical template_field_id, which are different for each
+ * SoC and there are other field types, it is actually not. If we would also use
+ * an intermediate representation for a field type, we would could have one
+ * pie_data_fill function for all SoCs, provided we have also for each SoC a
+ * function to map between physical and intermediate field type
+ */
+int rtl931x_pie_data_fill(enum template_field_id field_type, struct pie_rule *pr, u16 *data, u16 *data_m)
+{
+ *data = *data_m = 0;
+
+ switch (field_type) {
+ case TEMPLATE_FIELD_SPM0:
+ *data = pr->spm;
+ *data_m = pr->spm_m;
+ break;
+ case TEMPLATE_FIELD_SPM1:
+ *data = pr->spm >> 16;
+ *data_m = pr->spm_m >> 16;
+ break;
+ case TEMPLATE_FIELD_OTAG:
+ *data = pr->otag;
+ *data_m = pr->otag_m;
+ break;
+ case TEMPLATE_FIELD_SMAC0:
+ *data = pr->smac[4];
+ *data = (*data << 8) | pr->smac[5];
+ *data_m = pr->smac_m[4];
+ *data_m = (*data_m << 8) | pr->smac_m[5];
+ break;
+ case TEMPLATE_FIELD_SMAC1:
+ *data = pr->smac[2];
+ *data = (*data << 8) | pr->smac[3];
+ *data_m = pr->smac_m[2];
+ *data_m = (*data_m << 8) | pr->smac_m[3];
+ break;
+ case TEMPLATE_FIELD_SMAC2:
+ *data = pr->smac[0];
+ *data = (*data << 8) | pr->smac[1];
+ *data_m = pr->smac_m[0];
+ *data_m = (*data_m << 8) | pr->smac_m[1];
+ break;
+ case TEMPLATE_FIELD_DMAC0:
+ *data = pr->dmac[4];
+ *data = (*data << 8) | pr->dmac[5];
+ *data_m = pr->dmac_m[4];
+ *data_m = (*data_m << 8) | pr->dmac_m[5];
+ break;
+ case TEMPLATE_FIELD_DMAC1:
+ *data = pr->dmac[2];
+ *data = (*data << 8) | pr->dmac[3];
+ *data_m = pr->dmac_m[2];
+ *data_m = (*data_m << 8) | pr->dmac_m[3];
+ break;
+ case TEMPLATE_FIELD_DMAC2:
+ *data = pr->dmac[0];
+ *data = (*data << 8) | pr->dmac[1];
+ *data_m = pr->dmac_m[0];
+ *data_m = (*data_m << 8) | pr->dmac_m[1];
+ break;
+ case TEMPLATE_FIELD_ETHERTYPE:
+ *data = pr->ethertype;
+ *data_m = pr->ethertype_m;
+ break;
+ case TEMPLATE_FIELD_ITAG:
+ *data = pr->itag;
+ *data_m = pr->itag_m;
+ break;
+ case TEMPLATE_FIELD_SIP0:
+ if (pr->is_ipv6) {
+ *data = pr->sip6.s6_addr16[7];
+ *data_m = pr->sip6_m.s6_addr16[7];
+ } else {
+ *data = pr->sip;
+ *data_m = pr->sip_m;
+ }
+ break;
+ case TEMPLATE_FIELD_SIP1:
+ if (pr->is_ipv6) {
+ *data = pr->sip6.s6_addr16[6];
+ *data_m = pr->sip6_m.s6_addr16[6];
+ } else {
+ *data = pr->sip >> 16;
+ *data_m = pr->sip_m >> 16;
+ }
+ break;
+ case TEMPLATE_FIELD_SIP2:
+ case TEMPLATE_FIELD_SIP3:
+ case TEMPLATE_FIELD_SIP4:
+ case TEMPLATE_FIELD_SIP5:
+ case TEMPLATE_FIELD_SIP6:
+ case TEMPLATE_FIELD_SIP7:
+ *data = pr->sip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)];
+ *data_m = pr->sip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)];
+ break;
+ case TEMPLATE_FIELD_DIP0:
+ if (pr->is_ipv6) {
+ *data = pr->dip6.s6_addr16[7];
+ *data_m = pr->dip6_m.s6_addr16[7];
+ } else {
+ *data = pr->dip;
+ *data_m = pr->dip_m;
+ }
+ break;
+ case TEMPLATE_FIELD_DIP1:
+ if (pr->is_ipv6) {
+ *data = pr->dip6.s6_addr16[6];
+ *data_m = pr->dip6_m.s6_addr16[6];
+ } else {
+ *data = pr->dip >> 16;
+ *data_m = pr->dip_m >> 16;
+ }
+ break;
+ case TEMPLATE_FIELD_DIP2:
+ case TEMPLATE_FIELD_DIP3:
+ case TEMPLATE_FIELD_DIP4:
+ case TEMPLATE_FIELD_DIP5:
+ case TEMPLATE_FIELD_DIP6:
+ case TEMPLATE_FIELD_DIP7:
+ *data = pr->dip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)];
+ *data_m = pr->dip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)];
+ break;
+ case TEMPLATE_FIELD_IP_TOS_PROTO:
+ *data = pr->tos_proto;
+ *data_m = pr->tos_proto_m;
+ break;
+ case TEMPLATE_FIELD_L4_SPORT:
+ *data = pr->sport;
+ *data_m = pr->sport_m;
+ break;
+ case TEMPLATE_FIELD_L4_DPORT:
+ *data = pr->dport;
+ *data_m = pr->dport_m;
+ break;
+ case TEMPLATE_FIELD_DSAP_SSAP:
+ *data = pr->dsap_ssap;
+ *data_m = pr->dsap_ssap_m;
+ break;
+ case TEMPLATE_FIELD_TCP_INFO:
+ *data = pr->tcp_info;
+ *data_m = pr->tcp_info_m;
+ break;
+ case TEMPLATE_FIELD_RANGE_CHK:
+ pr_info("TEMPLATE_FIELD_RANGE_CHK: not configured\n");
+ break;
+ default:
+ pr_info("%s: unknown field %d\n", __func__, field_type);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Reads the intermediate representation of the templated match-fields of the
+ * PIE rule in the pie_rule structure and fills in the raw data fields in the
+ * raw register space r[].
+ * The register space configuration size is identical for the RTL8380/90 and RTL9300,
+ * however the RTL931X has 2 more registers / fields and the physical field-ids are different
+ * on all SoCs
+ * On the RTL9300 the mask fields are not word-aligend!
+ */
+static void rtl931x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[])
+{
+ for (int i = 0; i < N_FIXED_FIELDS; i++) {
+ u16 data, data_m;
+
+ rtl931x_pie_data_fill(t[i], pr, &data, &data_m);
+
+ /* On the RTL9300, the mask fields are not word aligned! */
+ if (!(i % 2)) {
+ r[5 - i / 2] = data;
+ r[12 - i / 2] |= ((u32)data_m << 8);
+ } else {
+ r[5 - i / 2] |= ((u32)data) << 16;
+ r[12 - i / 2] |= ((u32)data_m) << 24;
+ r[11 - i / 2] |= ((u32)data_m) >> 8;
+ }
+ }
+}
+
+// Currently unused
+// static void rtl931x_read_pie_fixed_fields(u32 r[], struct pie_rule *pr)
+// {
+// pr->mgnt_vlan = r[7] & BIT(31);
+// if (pr->phase == PHASE_IACL)
+// pr->dmac_hit_sw = r[7] & BIT(30);
+// else /* TODO: EACL/VACL phase handling */
+// pr->content_too_deep = r[7] & BIT(30);
+// pr->not_first_frag = r[7] & BIT(29);
+// pr->frame_type_l4 = (r[7] >> 26) & 7;
+// pr->frame_type = (r[7] >> 24) & 3;
+// pr->otag_fmt = (r[7] >> 23) & 1;
+// pr->itag_fmt = (r[7] >> 22) & 1;
+// pr->otag_exist = (r[7] >> 21) & 1;
+// pr->itag_exist = (r[7] >> 20) & 1;
+// pr->frame_type_l2 = (r[7] >> 18) & 3;
+// pr->igr_normal_port = (r[7] >> 17) & 1;
+// pr->tid = (r[7] >> 16) & 1;
+
+// pr->mgnt_vlan_m = r[14] & BIT(15);
+// if (pr->phase == PHASE_IACL)
+// pr->dmac_hit_sw_m = r[14] & BIT(14);
+// else
+// pr->content_too_deep_m = r[14] & BIT(14);
+// pr->not_first_frag_m = r[14] & BIT(13);
+// pr->frame_type_l4_m = (r[14] >> 10) & 7;
+// pr->frame_type_m = (r[14] >> 8) & 3;
+// pr->otag_fmt_m = r[14] & BIT(7);
+// pr->itag_fmt_m = r[14] & BIT(6);
+// pr->otag_exist_m = r[14] & BIT(5);
+// pr->itag_exist_m = r[14] & BIT (4);
+// pr->frame_type_l2_m = (r[14] >> 2) & 3;
+// pr->igr_normal_port_m = r[14] & BIT(1);
+// pr->tid_m = r[14] & 1;
+
+// pr->valid = r[15] & BIT(31);
+// pr->cond_not = r[15] & BIT(30);
+// pr->cond_and1 = r[15] & BIT(29);
+// pr->cond_and2 = r[15] & BIT(28);
+// }
+
+static void rtl931x_write_pie_fixed_fields(u32 r[], struct pie_rule *pr)
+{
+ r[7] |= pr->mgnt_vlan ? BIT(31) : 0;
+ if (pr->phase == PHASE_IACL)
+ r[7] |= pr->dmac_hit_sw ? BIT(30) : 0;
+ else
+ r[7] |= pr->content_too_deep ? BIT(30) : 0;
+ r[7] |= pr->not_first_frag ? BIT(29) : 0;
+ r[7] |= ((u32) (pr->frame_type_l4 & 0x7)) << 26;
+ r[7] |= ((u32) (pr->frame_type & 0x3)) << 24;
+ r[7] |= pr->otag_fmt ? BIT(23) : 0;
+ r[7] |= pr->itag_fmt ? BIT(22) : 0;
+ r[7] |= pr->otag_exist ? BIT(21) : 0;
+ r[7] |= pr->itag_exist ? BIT(20) : 0;
+ r[7] |= ((u32) (pr->frame_type_l2 & 0x3)) << 18;
+ r[7] |= pr->igr_normal_port ? BIT(17) : 0;
+ r[7] |= ((u32) (pr->tid & 0x1)) << 16;
+
+ r[14] |= pr->mgnt_vlan_m ? BIT(15) : 0;
+ if (pr->phase == PHASE_IACL)
+ r[14] |= pr->dmac_hit_sw_m ? BIT(14) : 0;
+ else
+ r[14] |= pr->content_too_deep_m ? BIT(14) : 0;
+ r[14] |= pr->not_first_frag_m ? BIT(13) : 0;
+ r[14] |= ((u32) (pr->frame_type_l4_m & 0x7)) << 10;
+ r[14] |= ((u32) (pr->frame_type_m & 0x3)) << 8;
+ r[14] |= pr->otag_fmt_m ? BIT(7) : 0;
+ r[14] |= pr->itag_fmt_m ? BIT(6) : 0;
+ r[14] |= pr->otag_exist_m ? BIT(5) : 0;
+ r[14] |= pr->itag_exist_m ? BIT(4) : 0;
+ r[14] |= ((u32) (pr->frame_type_l2_m & 0x3)) << 2;
+ r[14] |= pr->igr_normal_port_m ? BIT(1) : 0;
+ r[14] |= (u32) (pr->tid_m & 0x1);
+
+ r[15] |= pr->valid ? BIT(31) : 0;
+ r[15] |= pr->cond_not ? BIT(30) : 0;
+ r[15] |= pr->cond_and1 ? BIT(29) : 0;
+ r[15] |= pr->cond_and2 ? BIT(28) : 0;
+}
+
+static void rtl931x_write_pie_action(u32 r[], struct pie_rule *pr)
+{
+ /* Either drop or forward */
+ if (pr->drop) {
+ r[15] |= BIT(11) | BIT(12) | BIT(13); /* Do Green, Yellow and Red drops */
+ /* Actually DROP, not PERMIT in Green / Yellow / Red */
+ r[16] |= BIT(27) | BIT(28) | BIT(29);
+ } else {
+ r[15] |= pr->fwd_sel ? BIT(14) : 0;
+ r[16] |= pr->fwd_act << 24;
+ r[16] |= BIT(21); /* We overwrite any drop */
+ }
+ if (pr->phase == PHASE_VACL)
+ r[16] |= pr->fwd_sa_lrn ? BIT(22) : 0;
+ r[15] |= pr->bypass_sel ? BIT(10) : 0;
+ r[15] |= pr->nopri_sel ? BIT(21) : 0;
+ r[15] |= pr->tagst_sel ? BIT(20) : 0;
+ r[15] |= pr->ovid_sel ? BIT(18) : 0;
+ r[15] |= pr->ivid_sel ? BIT(16) : 0;
+ r[15] |= pr->meter_sel ? BIT(27) : 0;
+ r[15] |= pr->mir_sel ? BIT(15) : 0;
+ r[15] |= pr->log_sel ? BIT(26) : 0;
+
+ r[16] |= ((u32)(pr->fwd_data & 0xfff)) << 9;
+/* r[15] |= pr->log_octets ? BIT(31) : 0; */
+ r[15] |= (u32)(pr->meter_data) >> 2;
+ r[16] |= (((u32)(pr->meter_data) >> 7) & 0x3) << 29;
+
+ r[16] |= ((u32)(pr->ivid_act & 0x3)) << 21;
+ r[15] |= ((u32)(pr->ivid_data & 0xfff)) << 9;
+ r[16] |= ((u32)(pr->ovid_act & 0x3)) << 30;
+ r[16] |= ((u32)(pr->ovid_data & 0xfff)) << 16;
+ r[16] |= ((u32)(pr->mir_data & 0x3)) << 6;
+ r[17] |= ((u32)(pr->tagst_data & 0xf)) << 28;
+ r[17] |= ((u32)(pr->nopri_data & 0x7)) << 25;
+ r[17] |= pr->bypass_ibc_sc ? BIT(16) : 0;
+}
+
+void rtl931x_pie_rule_dump_raw(u32 r[])
+{
+ pr_info("Raw IACL table entry:\n");
+ pr_info("r 0 - 7: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
+ pr_info("r 8 - 15: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
+ pr_info("r 16 - 18: %08x %08x %08x\n", r[16], r[17], r[18]);
+ pr_info("Match : %08x %08x %08x %08x %08x %08x\n", r[0], r[1], r[2], r[3], r[4], r[5]);
+ pr_info("Fixed : %06x\n", r[6] >> 8);
+ pr_info("Match M: %08x %08x %08x %08x %08x %08x\n",
+ (r[6] << 24) | (r[7] >> 8), (r[7] << 24) | (r[8] >> 8), (r[8] << 24) | (r[9] >> 8),
+ (r[9] << 24) | (r[10] >> 8), (r[10] << 24) | (r[11] >> 8),
+ (r[11] << 24) | (r[12] >> 8));
+ pr_info("R[13]: %08x\n", r[13]);
+ pr_info("Fixed M: %06x\n", ((r[12] << 16) | (r[13] >> 16)) & 0xffffff);
+ pr_info("Valid / not / and1 / and2 : %1x\n", (r[13] >> 12) & 0xf);
+ pr_info("r 13-16: %08x %08x %08x %08x\n", r[13], r[14], r[15], r[16]);
+}
+
+static int rtl931x_pie_rule_write(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr)
+{
+ /* Access IACL table (0) via register 1, the table size is 4096 */
+ struct table_reg *q = rtl_table_get(RTL9310_TBL_1, 0);
+ u32 r[22];
+ int block = idx / PIE_BLOCK_SIZE;
+ u32 t_select = sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block));
+
+ pr_info("%s: %d, t_select: %08x\n", __func__, idx, t_select);
+
+ for (int i = 0; i < 22; i++)
+ r[i] = 0;
+
+ if (!pr->valid) {
+ rtl_table_write(q, idx);
+ rtl_table_release(q);
+ return 0;
+ }
+ rtl931x_write_pie_fixed_fields(r, pr);
+
+ pr_info("%s: template %d\n", __func__, (t_select >> (pr->tid * 4)) & 0xf);
+ rtl931x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 4)) & 0xf]);
+
+ rtl931x_write_pie_action(r, pr);
+
+ rtl931x_pie_rule_dump_raw(r);
+
+ for (int i = 0; i < 22; i++)
+ sw_w32(r[i], rtl_table_data(q, i));
+
+ rtl_table_write(q, idx);
+ rtl_table_release(q);
+
+ return 0;
+}
+
+static bool rtl931x_pie_templ_has(int t, enum template_field_id field_type)
+{
+ for (int i = 0; i < N_FIXED_FIELDS_RTL931X; i++) {
+ enum template_field_id ft = fixed_templates[t][i];
+ if (field_type == ft)
+ return true;
+ }
+
+ return false;
+}
+
+/* Verify that the rule pr is compatible with a given template t in block block
+ * Note that this function is SoC specific since the values of e.g. TEMPLATE_FIELD_SIP0
+ * depend on the SoC
+ */
+static int rtl931x_pie_verify_template(struct rtl838x_switch_priv *priv,
+ struct pie_rule *pr, int t, int block)
+{
+ int i;
+
+ if (!pr->is_ipv6 && pr->sip_m && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SIP0))
+ return -1;
+
+ if (!pr->is_ipv6 && pr->dip_m && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DIP0))
+ return -1;
+
+ if (pr->is_ipv6) {
+ if ((pr->sip6_m.s6_addr32[0] ||
+ pr->sip6_m.s6_addr32[1] ||
+ pr->sip6_m.s6_addr32[2] ||
+ pr->sip6_m.s6_addr32[3]) &&
+ !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SIP2))
+ return -1;
+ if ((pr->dip6_m.s6_addr32[0] ||
+ pr->dip6_m.s6_addr32[1] ||
+ pr->dip6_m.s6_addr32[2] ||
+ pr->dip6_m.s6_addr32[3]) &&
+ !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DIP2))
+ return -1;
+ }
+
+ if (ether_addr_to_u64(pr->smac) && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SMAC0))
+ return -1;
+
+ if (ether_addr_to_u64(pr->dmac) && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DMAC0))
+ return -1;
+
+ /* TODO: Check more */
+
+ i = find_first_zero_bit(&priv->pie_use_bm[block * 4], PIE_BLOCK_SIZE);
+
+ if (i >= PIE_BLOCK_SIZE)
+ return -1;
+
+ return i + PIE_BLOCK_SIZE * block;
+}
+
+static int rtl931x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr)
+{
+ int idx, block, j;
+ int min_block = 0;
+ int max_block = priv->n_pie_blocks / 2;
+
+ if (pr->is_egress) {
+ min_block = max_block;
+ max_block = priv->n_pie_blocks;
+ }
+ pr_info("In %s\n", __func__);
+
+ mutex_lock(&priv->pie_mutex);
+
+ for (block = min_block; block < max_block; block++) {
+ for (j = 0; j < 2; j++) {
+ int t = (sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block)) >> (j * 4)) & 0xf;
+ pr_info("Testing block %d, template %d, template id %d\n", block, j, t);
+ pr_info("%s: %08x\n",
+ __func__, sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block)));
+ idx = rtl931x_pie_verify_template(priv, pr, t, block);
+ if (idx >= 0)
+ break;
+ }
+ if (j < 2)
+ break;
+ }
+
+ if (block >= priv->n_pie_blocks) {
+ mutex_unlock(&priv->pie_mutex);
+ return -EOPNOTSUPP;
+ }
+
+ pr_info("Using block: %d, index %d, template-id %d\n", block, idx, j);
+ set_bit(idx, priv->pie_use_bm);
+
+ pr->valid = true;
+ pr->tid = j; /* Mapped to template number */
+ pr->tid_m = 0x1;
+ pr->id = idx;
+
+ rtl931x_pie_lookup_enable(priv, idx);
+ rtl931x_pie_rule_write(priv, idx, pr);
+
+ mutex_unlock(&priv->pie_mutex);
+
+ return 0;
+}
+
+/* Delete a range of Packet Inspection Engine rules */
+static int rtl931x_pie_rule_del(struct rtl838x_switch_priv *priv, int index_from, int index_to)
+{
+ u32 v = (index_from << 1)| (index_to << 13 ) | BIT(0);
+
+ pr_info("%s: from %d to %d\n", __func__, index_from, index_to);
+ mutex_lock(&priv->reg_mutex);
+
+ /* Write from-to and execute bit into control register */
+ sw_w32(v, RTL931X_PIE_CLR_CTRL);
+
+ /* Wait until command has completed */
+ do {
+ } while (sw_r32(RTL931X_PIE_CLR_CTRL) & BIT(0));
+
+ mutex_unlock(&priv->reg_mutex);
+
+ return 0;
+}
+
+static void rtl931x_pie_rule_rm(struct rtl838x_switch_priv *priv, struct pie_rule *pr)
+{
+ int idx = pr->id;
+
+ rtl931x_pie_rule_del(priv, idx, idx);
+ clear_bit(idx, priv->pie_use_bm);
+}
+
+static void rtl931x_pie_init(struct rtl838x_switch_priv *priv)
+{
+ u32 template_selectors;
+
+ mutex_init(&priv->pie_mutex);
+
+ pr_info("%s\n", __func__);
+ /* Enable ACL lookup on all ports, including CPU_PORT */
+ for (int i = 0; i <= priv->cpu_port; i++)
+ sw_w32(1, RTL931X_ACL_PORT_LOOKUP_CTRL(i));
+
+ /* Include IPG in metering */
+ sw_w32_mask(0, 1, RTL931X_METER_GLB_CTRL);
+
+ /* Delete all present rules, block size is 128 on all SoC families */
+ rtl931x_pie_rule_del(priv, 0, priv->n_pie_blocks * 128 - 1);
+
+ /* Assign first half blocks 0-7 to VACL phase, second half to IACL */
+ /* 3 bits are used for each block, values for PIE blocks are */
+ /* 6: Disabled, 0: VACL, 1: IACL, 2: EACL */
+ /* And for OpenFlow Flow blocks: 3: Ingress Flow table 0, */
+ /* 4: Ingress Flow Table 3, 5: Egress flow table 0 */
+ for (int i = 0; i < priv->n_pie_blocks; i++) {
+ int pos = (i % 10) * 3;
+ u32 r = RTL931X_PIE_BLK_PHASE_CTRL + 4 * (i / 10);
+
+ if (i < priv->n_pie_blocks / 2)
+ sw_w32_mask(0x7 << pos, 0, r);
+ else
+ sw_w32_mask(0x7 << pos, 1 << pos, r);
+ }
+
+ /* Enable predefined templates 0, 1 for first quarter of all blocks */
+ template_selectors = 0 | (1 << 4);
+ for (int i = 0; i < priv->n_pie_blocks / 4; i++)
+ sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
+
+ /* Enable predefined templates 2, 3 for second quarter of all blocks */
+ template_selectors = 2 | (3 << 4);
+ for (int i = priv->n_pie_blocks / 4; i < priv->n_pie_blocks / 2; i++)
+ sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
+
+ /* Enable predefined templates 0, 1 for third quater of all blocks */
+ template_selectors = 0 | (1 << 4);
+ for (int i = priv->n_pie_blocks / 2; i < priv->n_pie_blocks * 3 / 4; i++)
+ sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
+
+ /* Enable predefined templates 2, 3 for fourth quater of all blocks */
+ template_selectors = 2 | (3 << 4);
+ for (int i = priv->n_pie_blocks * 3 / 4; i < priv->n_pie_blocks; i++)
+ sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i));
+
+}
+
+int rtl931x_l3_setup(struct rtl838x_switch_priv *priv)
+{
+ return 0;
+}
+
+void rtl931x_vlan_port_keep_tag_set(int port, bool keep_outer, bool keep_inner)
+{
+ sw_w32(FIELD_PREP(RTL931X_VLAN_PORT_TAG_EGR_OTAG_STS_MASK,
+ keep_outer ? RTL931X_VLAN_PORT_TAG_STS_TAGGED : RTL931X_VLAN_PORT_TAG_STS_UNTAG) |
+ FIELD_PREP(RTL931X_VLAN_PORT_TAG_EGR_ITAG_STS_MASK,
+ keep_inner ? RTL931X_VLAN_PORT_TAG_STS_TAGGED : RTL931X_VLAN_PORT_TAG_STS_UNTAG),
+ RTL931X_VLAN_PORT_TAG_CTRL(port));
+}
+
+void rtl931x_vlan_port_pvidmode_set(int port, enum pbvlan_type type, enum pbvlan_mode mode)
+{
+ if (type == PBVLAN_TYPE_INNER)
+ sw_w32_mask(0x3 << 12, mode << 12, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
+ else
+ sw_w32_mask(0x3 << 26, mode << 26, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
+}
+
+void rtl931x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid)
+{
+ if (type == PBVLAN_TYPE_INNER)
+ sw_w32_mask(0xfff, pvid, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
+ else
+ sw_w32_mask(0xfff << 14, pvid << 14, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
+}
+
+static void rtl931x_set_igr_filter(int port, enum igr_filter state)
+{
+ sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1),
+ RTL931X_VLAN_PORT_IGR_FLTR + (((port >> 4) << 2)));
+}
+
+static void rtl931x_set_egr_filter(int port, enum egr_filter state)
+{
+ sw_w32_mask(0x1 << (port % 0x20), state << (port % 0x20),
+ RTL931X_VLAN_PORT_EGR_FLTR + (((port >> 5) << 2)));
+}
+
+void rtl931x_set_distribution_algorithm(int group, int algoidx, u32 algomsk)
+{
+ u32 l3shift = 0;
+ u32 newmask = 0;
+
+ /* TODO: for now we set algoidx to 0 */
+ algoidx = 0;
+
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_SIP_BIT) {
+ l3shift = 4;
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SIP_BIT;
+ }
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_DIP_BIT) {
+ l3shift = 4;
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DIP_BIT;
+ }
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) {
+ l3shift = 4;
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT;
+ }
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) {
+ l3shift = 4;
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT;
+ }
+
+ if (l3shift == 4) {
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT)
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SMAC_BIT;
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT)
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DMAC_BIT;
+ } else {
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT)
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L2_SMAC_BIT;
+ if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT)
+ newmask |= TRUNK_DISTRIBUTION_ALGO_L2_DMAC_BIT;
+ }
+
+ sw_w32(newmask << l3shift, RTL931X_TRK_HASH_CTRL + (algoidx << 2));
+}
+
+static void rtl931x_led_init(struct rtl838x_switch_priv *priv)
+{
+ u64 pm_copper = 0, pm_fiber = 0;
+ struct device_node *node;
+
+ pr_info("%s called\n", __func__);
+ node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds");
+ if (!node) {
+ pr_info("%s No compatible LED node found\n", __func__);
+ return;
+ }
+
+ for (int i = 0; i < priv->cpu_port; i++) {
+ int pos = (i << 1) % 32;
+ u32 set;
+ u32 v;
+
+ sw_w32_mask(0x3 << pos, 0, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i));
+ sw_w32_mask(0x3 << pos, 0, RTL931X_LED_PORT_COPR_SET_SEL_CTRL(i));
+
+ if (!priv->ports[i].phy)
+ continue;
+
+ v = 0x1; /* Found on the EdgeCore, but we do not have any HW description */
+ sw_w32_mask(0x3 << pos, v << pos, RTL931X_LED_PORT_NUM_CTRL(i));
+
+ if (priv->ports[i].phy_is_integrated)
+ pm_fiber |= BIT_ULL(i);
+ else
+ pm_copper |= BIT_ULL(i);
+
+ set = priv->ports[i].led_set;
+ sw_w32_mask(0, set << pos, RTL931X_LED_PORT_COPR_SET_SEL_CTRL(i));
+ sw_w32_mask(0, set << pos, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i));
+ }
+
+ for (int i = 0; i < 4; i++) {
+ const __be32 *led_set;
+ char set_name[9];
+ u32 setlen;
+ u32 v;
+
+ sprintf(set_name, "led_set%d", i);
+ pr_info(">%s<\n", set_name);
+ led_set = of_get_property(node, set_name, &setlen);
+ if (!led_set || setlen != 16)
+ break;
+ v = be32_to_cpup(led_set) << 16 | be32_to_cpup(led_set + 1);
+ sw_w32(v, RTL931X_LED_SET0_0_CTRL - 4 - i * 8);
+ v = be32_to_cpup(led_set + 2) << 16 | be32_to_cpup(led_set + 3);
+ sw_w32(v, RTL931X_LED_SET0_0_CTRL - i * 8);
+ }
+
+ /* Set LED mode to serial (0x1) */
+ sw_w32_mask(0x3, 0x1, RTL931X_LED_GLB_CTRL);
+
+ rtl839x_set_port_reg_le(pm_copper, RTL931X_LED_PORT_COPR_MASK_CTRL);
+ rtl839x_set_port_reg_le(pm_fiber, RTL931X_LED_PORT_FIB_MASK_CTRL);
+ rtl839x_set_port_reg_le(pm_copper | pm_fiber, RTL931X_LED_PORT_COMBO_MASK_CTRL);
+
+ for (int i = 0; i < 32; i++)
+ pr_info("%s %08x: %08x\n",__func__, 0xbb000600 + i * 4, sw_r32(0x0600 + i * 4));
+}
+
+const struct rtl838x_reg rtl931x_reg = {
+ .mask_port_reg_be = rtl839x_mask_port_reg_be,
+ .set_port_reg_be = rtl839x_set_port_reg_be,
+ .get_port_reg_be = rtl839x_get_port_reg_be,
+ .mask_port_reg_le = rtl839x_mask_port_reg_le,
+ .set_port_reg_le = rtl839x_set_port_reg_le,
+ .get_port_reg_le = rtl839x_get_port_reg_le,
+ .stat_port_rst = RTL931X_STAT_PORT_RST,
+ .stat_rst = RTL931X_STAT_RST,
+ .stat_port_std_mib = 0, /* Not defined */
+ .traffic_enable = rtl931x_traffic_enable,
+ .traffic_disable = rtl931x_traffic_disable,
+ .traffic_get = rtl931x_traffic_get,
+ .traffic_set = rtl931x_traffic_set,
+ .l2_ctrl_0 = RTL931X_L2_CTRL,
+ .l2_ctrl_1 = RTL931X_L2_AGE_CTRL,
+ .l2_port_aging_out = RTL931X_L2_PORT_AGE_CTRL,
+ .set_ageing_time = rtl931x_set_ageing_time,
+ /* .smi_poll_ctrl does not exist */
+ .l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL,
+ .exec_tbl0_cmd = rtl931x_exec_tbl0_cmd,
+ .exec_tbl1_cmd = rtl931x_exec_tbl1_cmd,
+ .tbl_access_data_0 = rtl931x_tbl_access_data_0,
+ .isr_glb_src = RTL931X_ISR_GLB_SRC,
+ .isr_port_link_sts_chg = RTL931X_ISR_PORT_LINK_STS_CHG,
+ .imr_port_link_sts_chg = RTL931X_IMR_PORT_LINK_STS_CHG,
+ /* imr_glb does not exist on RTL931X */
+ .vlan_tables_read = rtl931x_vlan_tables_read,
+ .vlan_set_tagged = rtl931x_vlan_set_tagged,
+ .vlan_set_untagged = rtl931x_vlan_set_untagged,
+ .vlan_profile_dump = rtl931x_vlan_profile_dump,
+ .vlan_profile_setup = rtl931x_vlan_profile_setup,
+ .vlan_fwd_on_inner = rtl931x_vlan_fwd_on_inner,
+ .stp_get = rtl931x_stp_get,
+ .stp_set = rtl931x_stp_set,
+ .mac_force_mode_ctrl = rtl931x_mac_force_mode_ctrl,
+ .mac_port_ctrl = rtl931x_mac_port_ctrl,
+ .l2_port_new_salrn = rtl931x_l2_port_new_salrn,
+ .l2_port_new_sa_fwd = rtl931x_l2_port_new_sa_fwd,
+ .mir_ctrl = RTL931X_MIR_CTRL,
+ .mir_dpm = RTL931X_MIR_DPM_CTRL,
+ .mir_spm = RTL931X_MIR_SPM_CTRL,
+ .mac_link_sts = RTL931X_MAC_LINK_STS,
+ .mac_link_dup_sts = RTL931X_MAC_LINK_DUP_STS,
+ .mac_link_spd_sts = rtl931x_mac_link_spd_sts,
+ .mac_rx_pause_sts = RTL931X_MAC_RX_PAUSE_STS,
+ .mac_tx_pause_sts = RTL931X_MAC_TX_PAUSE_STS,
+ .read_l2_entry_using_hash = rtl931x_read_l2_entry_using_hash,
+ .write_l2_entry_using_hash = rtl931x_write_l2_entry_using_hash,
+ .read_cam = rtl931x_read_cam,
+ .write_cam = rtl931x_write_cam,
+ .vlan_port_keep_tag_set = rtl931x_vlan_port_keep_tag_set,
+ .vlan_port_pvidmode_set = rtl931x_vlan_port_pvidmode_set,
+ .vlan_port_pvid_set = rtl931x_vlan_port_pvid_set,
+ .trk_mbr_ctr = rtl931x_trk_mbr_ctr,
+ .set_vlan_igr_filter = rtl931x_set_igr_filter,
+ .set_vlan_egr_filter = rtl931x_set_egr_filter,
+ .set_distribution_algorithm = rtl931x_set_distribution_algorithm,
+ .l2_hash_key = rtl931x_l2_hash_key,
+ .read_mcast_pmask = rtl931x_read_mcast_pmask,
+ .write_mcast_pmask = rtl931x_write_mcast_pmask,
+ .pie_init = rtl931x_pie_init,
+ .pie_rule_write = rtl931x_pie_rule_write,
+ .pie_rule_add = rtl931x_pie_rule_add,
+ .pie_rule_rm = rtl931x_pie_rule_rm,
+ .l2_learning_setup = rtl931x_l2_learning_setup,
+ .l3_setup = rtl931x_l3_setup,
+ .led_init = rtl931x_led_init,
+};
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/tc.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/tc.c
new file mode 100644
index 0000000000..e72313c664
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/tc.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <net/dsa.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <net/flow_offload.h>
+#include <linux/rhashtable.h>
+#include <asm/mach-rtl838x/mach-rtl83xx.h>
+
+#include "rtl83xx.h"
+#include "rtl838x.h"
+
+/* Parse the flow rule for the matching conditions */
+static int rtl83xx_parse_flow_rule(struct rtl838x_switch_priv *priv,
+ struct flow_rule *rule, struct rtl83xx_flow *flow)
+{
+ struct flow_dissector *dissector = rule->match.dissector;
+
+ pr_debug("In %s\n", __func__);
+ /* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */
+ if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 ||
+ (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) {
+ pr_err("Cannot form TC key: used_keys = 0x%llx\n", dissector->used_keys);
+ return -EOPNOTSUPP;
+ }
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
+ struct flow_match_basic match;
+
+ pr_debug("%s: BASIC\n", __func__);
+ flow_rule_match_basic(rule, &match);
+ if (match.key->n_proto == htons(ETH_P_ARP))
+ flow->rule.frame_type = 0;
+ if (match.key->n_proto == htons(ETH_P_IP))
+ flow->rule.frame_type = 2;
+ if (match.key->n_proto == htons(ETH_P_IPV6))
+ flow->rule.frame_type = 3;
+ if ((match.key->n_proto == htons(ETH_P_ARP)) || flow->rule.frame_type)
+ flow->rule.frame_type_m = 3;
+ if (flow->rule.frame_type >= 2) {
+ if (match.key->ip_proto == IPPROTO_UDP)
+ flow->rule.frame_type_l4 = 0;
+ if (match.key->ip_proto == IPPROTO_TCP)
+ flow->rule.frame_type_l4 = 1;
+ if (match.key->ip_proto == IPPROTO_ICMP || match.key->ip_proto == IPPROTO_ICMPV6)
+ flow->rule.frame_type_l4 = 2;
+ if (match.key->ip_proto == IPPROTO_TCP)
+ flow->rule.frame_type_l4 = 3;
+ if ((match.key->ip_proto == IPPROTO_UDP) || flow->rule.frame_type_l4)
+ flow->rule.frame_type_l4_m = 7;
+ }
+ }
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
+ struct flow_match_eth_addrs match;
+
+ pr_debug("%s: ETH_ADDR\n", __func__);
+ flow_rule_match_eth_addrs(rule, &match);
+ ether_addr_copy(flow->rule.dmac, match.key->dst);
+ ether_addr_copy(flow->rule.dmac_m, match.mask->dst);
+ ether_addr_copy(flow->rule.smac, match.key->src);
+ ether_addr_copy(flow->rule.smac_m, match.mask->src);
+ }
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
+ struct flow_match_vlan match;
+
+ pr_debug("%s: VLAN\n", __func__);
+ flow_rule_match_vlan(rule, &match);
+ flow->rule.itag = match.key->vlan_id;
+ flow->rule.itag_m = match.mask->vlan_id;
+ /* TODO: What about match.key->vlan_priority? */
+ }
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
+ struct flow_match_ipv4_addrs match;
+
+ pr_debug("%s: IPV4\n", __func__);
+ flow_rule_match_ipv4_addrs(rule, &match);
+ flow->rule.is_ipv6 = false;
+ flow->rule.dip = match.key->dst;
+ flow->rule.dip_m = match.mask->dst;
+ flow->rule.sip = match.key->src;
+ flow->rule.sip_m = match.mask->src;
+ } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
+ struct flow_match_ipv6_addrs match;
+
+ pr_debug("%s: IPV6\n", __func__);
+ flow->rule.is_ipv6 = true;
+ flow_rule_match_ipv6_addrs(rule, &match);
+ flow->rule.dip6 = match.key->dst;
+ flow->rule.dip6_m = match.mask->dst;
+ flow->rule.sip6 = match.key->src;
+ flow->rule.sip6_m = match.mask->src;
+ }
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
+ struct flow_match_ports match;
+
+ pr_debug("%s: PORTS\n", __func__);
+ flow_rule_match_ports(rule, &match);
+ flow->rule.dport = match.key->dst;
+ flow->rule.dport_m = match.mask->dst;
+ flow->rule.sport = match.key->src;
+ flow->rule.sport_m = match.mask->src;
+ }
+
+ /* TODO: ICMP */
+ return 0;
+}
+
+static void rtl83xx_flow_bypass_all(struct rtl83xx_flow *flow)
+{
+ flow->rule.bypass_sel = true;
+ flow->rule.bypass_all = true;
+ flow->rule.bypass_igr_stp = true;
+ flow->rule.bypass_ibc_sc = true;
+}
+
+static int rtl83xx_parse_fwd(struct rtl838x_switch_priv *priv,
+ const struct flow_action_entry *act, struct rtl83xx_flow *flow)
+{
+ struct net_device *dev = act->dev;
+ int port;
+
+ port = rtl83xx_port_is_under(dev, priv);
+ if (port < 0) {
+ netdev_info(dev, "%s: not a DSA device.\n", __func__);
+ return -EINVAL;
+ }
+
+ flow->rule.fwd_sel = true;
+ flow->rule.fwd_data = port;
+ pr_debug("Using port index: %d\n", port);
+ rtl83xx_flow_bypass_all(flow);
+
+ return 0;
+}
+
+static int rtl83xx_add_flow(struct rtl838x_switch_priv *priv, struct flow_cls_offload *f,
+ struct rtl83xx_flow *flow)
+{
+ struct flow_rule *rule = flow_cls_offload_flow_rule(f);
+ const struct flow_action_entry *act;
+ int i, err;
+
+ pr_debug("%s\n", __func__);
+
+ rtl83xx_parse_flow_rule(priv, rule, flow);
+
+ flow_action_for_each(i, act, &rule->action) {
+ switch (act->id) {
+ case FLOW_ACTION_DROP:
+ pr_debug("%s: DROP\n", __func__);
+ flow->rule.drop = true;
+ rtl83xx_flow_bypass_all(flow);
+ return 0;
+
+ case FLOW_ACTION_TRAP:
+ pr_debug("%s: TRAP\n", __func__);
+ flow->rule.fwd_data = priv->cpu_port;
+ flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT;
+ rtl83xx_flow_bypass_all(flow);
+ break;
+
+ case FLOW_ACTION_MANGLE:
+ pr_err("%s: FLOW_ACTION_MANGLE not supported\n", __func__);
+ return -EOPNOTSUPP;
+
+ case FLOW_ACTION_ADD:
+ pr_err("%s: FLOW_ACTION_ADD not supported\n", __func__);
+ return -EOPNOTSUPP;
+
+ case FLOW_ACTION_VLAN_PUSH:
+ pr_debug("%s: VLAN_PUSH\n", __func__);
+/* TODO: act->vlan.proto */
+ flow->rule.ivid_act = PIE_ACT_VID_ASSIGN;
+ flow->rule.ivid_sel = true;
+ flow->rule.ivid_data = htons(act->vlan.vid);
+ flow->rule.ovid_act = PIE_ACT_VID_ASSIGN;
+ flow->rule.ovid_sel = true;
+ flow->rule.ovid_data = htons(act->vlan.vid);
+ flow->rule.fwd_mod_to_cpu = true;
+ break;
+
+ case FLOW_ACTION_VLAN_POP:
+ pr_debug("%s: VLAN_POP\n", __func__);
+ flow->rule.ivid_act = PIE_ACT_VID_ASSIGN;
+ flow->rule.ivid_data = 0;
+ flow->rule.ivid_sel = true;
+ flow->rule.ovid_act = PIE_ACT_VID_ASSIGN;
+ flow->rule.ovid_data = 0;
+ flow->rule.ovid_sel = true;
+ flow->rule.fwd_mod_to_cpu = true;
+ break;
+
+ case FLOW_ACTION_CSUM:
+ pr_err("%s: FLOW_ACTION_CSUM not supported\n", __func__);
+ return -EOPNOTSUPP;
+
+ case FLOW_ACTION_REDIRECT:
+ pr_debug("%s: REDIRECT\n", __func__);
+ err = rtl83xx_parse_fwd(priv, act, flow);
+ if (err)
+ return err;
+ flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT;
+ break;
+
+ case FLOW_ACTION_MIRRED:
+ pr_debug("%s: MIRRED\n", __func__);
+ err = rtl83xx_parse_fwd(priv, act, flow);
+ if (err)
+ return err;
+ flow->rule.fwd_act = PIE_ACT_COPY_TO_PORT;
+ break;
+
+ default:
+ pr_err("%s: Flow action not supported: %d\n", __func__, act->id);
+ return -EOPNOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+static const struct rhashtable_params tc_ht_params = {
+ .head_offset = offsetof(struct rtl83xx_flow, node),
+ .key_offset = offsetof(struct rtl83xx_flow, cookie),
+ .key_len = sizeof(((struct rtl83xx_flow *)0)->cookie),
+ .automatic_shrinking = true,
+};
+
+static int rtl83xx_configure_flower(struct rtl838x_switch_priv *priv,
+ struct flow_cls_offload *f)
+{
+ struct rtl83xx_flow *flow;
+ int err = 0;
+
+ pr_debug("In %s\n", __func__);
+
+ rcu_read_lock();
+ pr_debug("Cookie %08lx\n", f->cookie);
+ flow = rhashtable_lookup(&priv->tc_ht, &f->cookie, tc_ht_params);
+ if (flow) {
+ pr_info("%s: Got flow\n", __func__);
+ err = -EEXIST;
+ goto rcu_unlock;
+ }
+
+rcu_unlock:
+ rcu_read_unlock();
+ if (flow)
+ goto out;
+ pr_debug("%s: New flow\n", __func__);
+
+ flow = kzalloc(sizeof(*flow), GFP_KERNEL);
+ if (!flow) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ flow->cookie = f->cookie;
+ flow->priv = priv;
+
+ err = rhashtable_insert_fast(&priv->tc_ht, &flow->node, tc_ht_params);
+ if (err) {
+ pr_err("Could not insert add new rule\n");
+ goto out_free;
+ }
+
+ rtl83xx_add_flow(priv, f, flow); /* TODO: check error */
+
+ /* Add log action to flow */
+ flow->rule.packet_cntr = rtl83xx_packet_cntr_alloc(priv);
+ if (flow->rule.packet_cntr >= 0) {
+ pr_debug("Using packet counter %d\n", flow->rule.packet_cntr);
+ flow->rule.log_sel = true;
+ flow->rule.log_data = flow->rule.packet_cntr;
+ }
+
+ err = priv->r->pie_rule_add(priv, &flow->rule);
+ return err;
+
+out_free:
+ kfree(flow);
+out:
+ pr_err("%s: error %d\n", __func__, err);
+
+ return err;
+}
+
+static int rtl83xx_delete_flower(struct rtl838x_switch_priv *priv,
+ struct flow_cls_offload * cls_flower)
+{
+ struct rtl83xx_flow *flow;
+
+ pr_debug("In %s\n", __func__);
+ rcu_read_lock();
+ flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params);
+ if (!flow) {
+ rcu_read_unlock();
+ return -EINVAL;
+ }
+
+ priv->r->pie_rule_rm(priv, &flow->rule);
+
+ rhashtable_remove_fast(&priv->tc_ht, &flow->node, tc_ht_params);
+
+ kfree_rcu(flow, rcu_head);
+
+ rcu_read_unlock();
+
+ return 0;
+}
+
+static int rtl83xx_stats_flower(struct rtl838x_switch_priv *priv,
+ struct flow_cls_offload * cls_flower)
+{
+ struct rtl83xx_flow *flow;
+ unsigned long lastused = 0;
+ int total_packets, new_packets;
+
+ pr_debug("%s: \n", __func__);
+ flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params);
+ if (!flow)
+ return -1;
+
+ if (flow->rule.packet_cntr >= 0) {
+ total_packets = priv->r->packet_cntr_read(flow->rule.packet_cntr);
+ pr_debug("Total packets: %d\n", total_packets);
+ new_packets = total_packets - flow->rule.last_packet_cnt;
+ flow->rule.last_packet_cnt = total_packets;
+ }
+
+ /* TODO: We need a second PIE rule to count the bytes */
+ flow_stats_update(&cls_flower->stats, 100 * new_packets, new_packets, 0, lastused,
+ FLOW_ACTION_HW_STATS_IMMEDIATE);
+
+ return 0;
+}
+
+static int rtl83xx_setup_tc_cls_flower(struct rtl838x_switch_priv *priv,
+ struct flow_cls_offload *cls_flower)
+{
+ pr_debug("%s: %d\n", __func__, cls_flower->command);
+ switch (cls_flower->command) {
+ case FLOW_CLS_REPLACE:
+ return rtl83xx_configure_flower(priv, cls_flower);
+ case FLOW_CLS_DESTROY:
+ return rtl83xx_delete_flower(priv, cls_flower);
+ case FLOW_CLS_STATS:
+ return rtl83xx_stats_flower(priv, cls_flower);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+
+static int rtl83xx_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
+ void *cb_priv)
+{
+ struct rtl838x_switch_priv *priv = cb_priv;
+
+ switch (type) {
+ case TC_SETUP_CLSFLOWER:
+ pr_debug("%s: TC_SETUP_CLSFLOWER\n", __func__);
+ return rtl83xx_setup_tc_cls_flower(priv, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static LIST_HEAD(rtl83xx_block_cb_list);
+
+int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
+{
+ struct rtl838x_switch_priv *priv;
+ struct flow_block_offload *f = type_data;
+ static bool first_time = true;
+ int err;
+
+ pr_debug("%s: %d\n", __func__, type);
+
+ if(!netdev_uses_dsa(dev)) {
+ pr_err("%s: no DSA\n", __func__);
+ return 0;
+ }
+ priv = dev->dsa_ptr->ds->priv;
+
+ switch (type) {
+ case TC_SETUP_BLOCK:
+ if (first_time) {
+ first_time = false;
+ err = rhashtable_init(&priv->tc_ht, &tc_ht_params);
+ if (err)
+ pr_err("%s: Could not initialize hash table\n", __func__);
+ }
+
+ f->unlocked_driver_cb = true;
+ return flow_block_cb_setup_simple(type_data,
+ &rtl83xx_block_cb_list,
+ rtl83xx_setup_tc_block_cb,
+ priv, priv, true);
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
diff --git a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
new file mode 100644
index 0000000000..07664f9f38
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
@@ -0,0 +1,2718 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* linux/drivers/net/ethernet/rtl838x_eth.c
+ * Copyright (C) 2020 B. Koblitz
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+#include <linux/phylink.h>
+#include <linux/pkt_sched.h>
+#include <net/dsa.h>
+#include <net/switchdev.h>
+#include <asm/cacheflush.h>
+
+#include <asm/mach-rtl838x/mach-rtl83xx.h>
+#include "rtl838x_eth.h"
+
+extern struct rtl83xx_soc_info soc_info;
+
+/* Maximum number of RX rings is 8 on RTL83XX and 32 on the 93XX
+ * The ring is assigned by switch based on packet/port priortity
+ * Maximum number of TX rings is 2, Ring 2 being the high priority
+ * ring on the RTL93xx SoCs. MAX_RXLEN gives the maximum length
+ * for an RX ring, MAX_ENTRIES the maximum number of entries
+ * available in total for all queues.
+ */
+#define MAX_RXRINGS 32
+#define MAX_RXLEN 300
+#define MAX_ENTRIES (300 * 8)
+#define TXRINGS 2
+#define TXRINGLEN 160
+#define NOTIFY_EVENTS 10
+#define NOTIFY_BLOCKS 10
+#define TX_EN 0x8
+#define RX_EN 0x4
+#define TX_EN_93XX 0x20
+#define RX_EN_93XX 0x10
+#define RX_TRUNCATE_EN_93XX BIT(6)
+#define RX_TRUNCATE_EN_83XX BIT(4)
+#define TX_PAD_EN_838X BIT(5)
+#define TX_DO 0x2
+#define WRAP 0x2
+#define MAX_PORTS 57
+#define MAX_SMI_BUSSES 4
+
+#define RING_BUFFER 1600
+
+struct p_hdr {
+ uint8_t *buf;
+ uint16_t reserved;
+ uint16_t size; /* buffer size */
+ uint16_t offset;
+ uint16_t len; /* pkt len */
+ /* cpu_tag[0] is a reserved uint16_t on RTL83xx */
+ uint16_t cpu_tag[10];
+} __packed __aligned(1);
+
+struct n_event {
+ uint32_t type:2;
+ uint32_t fidVid:12;
+ uint64_t mac:48;
+ uint32_t slp:6;
+ uint32_t valid:1;
+ uint32_t reserved:27;
+} __packed __aligned(1);
+
+struct ring_b {
+ uint32_t rx_r[MAX_RXRINGS][MAX_RXLEN];
+ uint32_t tx_r[TXRINGS][TXRINGLEN];
+ struct p_hdr rx_header[MAX_RXRINGS][MAX_RXLEN];
+ struct p_hdr tx_header[TXRINGS][TXRINGLEN];
+ uint32_t c_rx[MAX_RXRINGS];
+ uint32_t c_tx[TXRINGS];
+ uint8_t tx_space[TXRINGS * TXRINGLEN * RING_BUFFER];
+ uint8_t *rx_space;
+};
+
+struct notify_block {
+ struct n_event events[NOTIFY_EVENTS];
+};
+
+struct notify_b {
+ struct notify_block blocks[NOTIFY_BLOCKS];
+ u32 reserved1[8];
+ u32 ring[NOTIFY_BLOCKS];
+ u32 reserved2[8];
+};
+
+static void rtl838x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
+{
+ /* cpu_tag[0] is reserved on the RTL83XX SoCs */
+ h->cpu_tag[1] = 0x0400; /* BIT 10: RTL8380_CPU_TAG */
+ h->cpu_tag[2] = 0x0200; /* Set only AS_DPM, to enable DPM settings below */
+ h->cpu_tag[3] = 0x0000;
+ h->cpu_tag[4] = BIT(dest_port) >> 16;
+ h->cpu_tag[5] = BIT(dest_port) & 0xffff;
+
+ /* Set internal priority (PRI) and enable (AS_PRI) */
+ if (prio >= 0)
+ h->cpu_tag[2] |= ((prio & 0x7) | BIT(3)) << 12;
+}
+
+static void rtl839x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
+{
+ /* cpu_tag[0] is reserved on the RTL83XX SoCs */
+ h->cpu_tag[1] = 0x0100; /* RTL8390_CPU_TAG marker */
+ h->cpu_tag[2] = BIT(4); /* AS_DPM flag */
+ h->cpu_tag[3] = h->cpu_tag[4] = h->cpu_tag[5] = 0;
+ /* h->cpu_tag[1] |= BIT(1) | BIT(0); */ /* Bypass filter 1/2 */
+ if (dest_port >= 32) {
+ dest_port -= 32;
+ h->cpu_tag[2] |= (BIT(dest_port) >> 16) & 0xf;
+ h->cpu_tag[3] = BIT(dest_port) & 0xffff;
+ } else {
+ h->cpu_tag[4] = BIT(dest_port) >> 16;
+ h->cpu_tag[5] = BIT(dest_port) & 0xffff;
+ }
+
+ /* Set internal priority (PRI) and enable (AS_PRI) */
+ if (prio >= 0)
+ h->cpu_tag[2] |= ((prio & 0x7) | BIT(3)) << 8;
+}
+
+static void rtl930x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
+{
+ h->cpu_tag[0] = 0x8000; /* CPU tag marker */
+ h->cpu_tag[1] = h->cpu_tag[2] = 0;
+ h->cpu_tag[3] = 0;
+ h->cpu_tag[4] = 0;
+ h->cpu_tag[5] = 0;
+ h->cpu_tag[6] = BIT(dest_port) >> 16;
+ h->cpu_tag[7] = BIT(dest_port) & 0xffff;
+
+ /* Enable (AS_QID) and set priority queue (QID) */
+ if (prio >= 0)
+ h->cpu_tag[2] = (BIT(5) | (prio & 0x1f)) << 8;
+}
+
+static void rtl931x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio)
+{
+ h->cpu_tag[0] = 0x8000; /* CPU tag marker */
+ h->cpu_tag[1] = h->cpu_tag[2] = 0;
+ h->cpu_tag[3] = 0;
+ h->cpu_tag[4] = h->cpu_tag[5] = h->cpu_tag[6] = h->cpu_tag[7] = 0;
+ if (dest_port >= 32) {
+ dest_port -= 32;
+ h->cpu_tag[4] = BIT(dest_port) >> 16;
+ h->cpu_tag[5] = BIT(dest_port) & 0xffff;
+ } else {
+ h->cpu_tag[6] = BIT(dest_port) >> 16;
+ h->cpu_tag[7] = BIT(dest_port) & 0xffff;
+ }
+
+ /* Enable (AS_QID) and set priority queue (QID) */
+ if (prio >= 0)
+ h->cpu_tag[2] = (BIT(5) | (prio & 0x1f)) << 8;
+}
+
+// Currently unused
+// static void rtl93xx_header_vlan_set(struct p_hdr *h, int vlan)
+// {
+// h->cpu_tag[2] |= BIT(4); /* Enable VLAN forwarding offload */
+// h->cpu_tag[2] |= (vlan >> 8) & 0xf;
+// h->cpu_tag[3] |= (vlan & 0xff) << 8;
+// }
+
+struct rtl838x_rx_q {
+ int id;
+ struct rtl838x_eth_priv *priv;
+ struct napi_struct napi;
+};
+
+struct rtl838x_eth_priv {
+ struct net_device *netdev;
+ struct platform_device *pdev;
+ void *membase;
+ spinlock_t lock;
+ struct mii_bus *mii_bus;
+ struct rtl838x_rx_q rx_qs[MAX_RXRINGS];
+ struct phylink *phylink;
+ struct phylink_config phylink_config;
+ struct phylink_pcs pcs;
+ u16 id;
+ u16 family_id;
+ const struct rtl838x_eth_reg *r;
+ u8 cpu_port;
+ u32 lastEvent;
+ u16 rxrings;
+ u16 rxringlen;
+ u8 smi_bus[MAX_PORTS];
+ u8 smi_addr[MAX_PORTS];
+ u32 sds_id[MAX_PORTS];
+ bool smi_bus_isc45[MAX_SMI_BUSSES];
+ bool phy_is_internal[MAX_PORTS];
+ phy_interface_t interfaces[MAX_PORTS];
+};
+
+extern int rtl838x_phy_init(struct rtl838x_eth_priv *priv);
+extern int rtl838x_read_sds_phy(int phy_addr, int phy_reg);
+extern int rtl839x_read_sds_phy(int phy_addr, int phy_reg);
+extern int rtl839x_write_sds_phy(int phy_addr, int phy_reg, u16 v);
+extern int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg);
+extern int rtl930x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v);
+extern int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg);
+extern int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v);
+extern int rtl930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
+extern int rtl930x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val);
+extern int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
+extern int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val);
+
+/* On the RTL93XX, the RTL93XX_DMA_IF_RX_RING_CNTR track the fill level of
+ * the rings. Writing x into these registers substracts x from its content.
+ * When the content reaches the ring size, the ASIC no longer adds
+ * packets to this receive queue.
+ */
+void rtl838x_update_cntr(int r, int released)
+{
+ /* This feature is not available on RTL838x SoCs */
+}
+
+void rtl839x_update_cntr(int r, int released)
+{
+ /* This feature is not available on RTL839x SoCs */
+}
+
+void rtl930x_update_cntr(int r, int released)
+{
+ int pos = (r % 3) * 10;
+ u32 reg = RTL930X_DMA_IF_RX_RING_CNTR + ((r / 3) << 2);
+ u32 v = sw_r32(reg);
+
+ v = (v >> pos) & 0x3ff;
+ pr_debug("RX: Work done %d, old value: %d, pos %d, reg %04x\n", released, v, pos, reg);
+ sw_w32_mask(0x3ff << pos, released << pos, reg);
+ sw_w32(v, reg);
+}
+
+void rtl931x_update_cntr(int r, int released)
+{
+ int pos = (r % 3) * 10;
+ u32 reg = RTL931X_DMA_IF_RX_RING_CNTR + ((r / 3) << 2);
+ u32 v = sw_r32(reg);
+
+ v = (v >> pos) & 0x3ff;
+ sw_w32_mask(0x3ff << pos, released << pos, reg);
+ sw_w32(v, reg);
+}
+
+struct dsa_tag {
+ u8 reason;
+ u8 queue;
+ u16 port;
+ u8 l2_offloaded;
+ u8 prio;
+ bool crc_error;
+};
+
+bool rtl838x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
+{
+ /* cpu_tag[0] is reserved. Fields are off-by-one */
+ t->reason = h->cpu_tag[4] & 0xf;
+ t->queue = (h->cpu_tag[1] & 0xe0) >> 5;
+ t->port = h->cpu_tag[1] & 0x1f;
+ t->crc_error = t->reason == 13;
+
+ pr_debug("Reason: %d\n", t->reason);
+ if (t->reason != 6) /* NIC_RX_REASON_SPECIAL_TRAP */
+ t->l2_offloaded = 1;
+ else
+ t->l2_offloaded = 0;
+
+ return t->l2_offloaded;
+}
+
+bool rtl839x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
+{
+ /* cpu_tag[0] is reserved. Fields are off-by-one */
+ t->reason = h->cpu_tag[5] & 0x1f;
+ t->queue = (h->cpu_tag[4] & 0xe000) >> 13;
+ t->port = h->cpu_tag[1] & 0x3f;
+ t->crc_error = h->cpu_tag[4] & BIT(6);
+
+ pr_debug("Reason: %d\n", t->reason);
+ if ((t->reason >= 7 && t->reason <= 13) || /* NIC_RX_REASON_RMA */
+ (t->reason >= 23 && t->reason <= 25)) /* NIC_RX_REASON_SPECIAL_TRAP */
+ t->l2_offloaded = 0;
+ else
+ t->l2_offloaded = 1;
+
+ return t->l2_offloaded;
+}
+
+bool rtl930x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
+{
+ t->reason = h->cpu_tag[7] & 0x3f;
+ t->queue = (h->cpu_tag[2] >> 11) & 0x1f;
+ t->port = (h->cpu_tag[0] >> 8) & 0x1f;
+ t->crc_error = h->cpu_tag[1] & BIT(6);
+
+ pr_debug("Reason %d, port %d, queue %d\n", t->reason, t->port, t->queue);
+ if (t->reason >= 19 && t->reason <= 27)
+ t->l2_offloaded = 0;
+ else
+ t->l2_offloaded = 1;
+
+ return t->l2_offloaded;
+}
+
+bool rtl931x_decode_tag(struct p_hdr *h, struct dsa_tag *t)
+{
+ t->reason = h->cpu_tag[7] & 0x3f;
+ t->queue = (h->cpu_tag[2] >> 11) & 0x1f;
+ t->port = (h->cpu_tag[0] >> 8) & 0x3f;
+ t->crc_error = h->cpu_tag[1] & BIT(6);
+
+ if (t->reason != 63)
+ pr_info("%s: Reason %d, port %d, queue %d\n", __func__, t->reason, t->port, t->queue);
+ if (t->reason >= 19 && t->reason <= 27) /* NIC_RX_REASON_RMA */
+ t->l2_offloaded = 0;
+ else
+ t->l2_offloaded = 1;
+
+ return t->l2_offloaded;
+}
+
+/* Discard the RX ring-buffers, called as part of the net-ISR
+ * when the buffer runs over
+ */
+static void rtl838x_rb_cleanup(struct rtl838x_eth_priv *priv, int status)
+{
+ for (int r = 0; r < priv->rxrings; r++) {
+ struct ring_b *ring = priv->membase;
+ struct p_hdr *h;
+ u32 *last;
+
+ pr_debug("In %s working on r: %d\n", __func__, r);
+ last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4));
+ do {
+ if ((ring->rx_r[r][ring->c_rx[r]] & 0x1))
+ break;
+ pr_debug("Got something: %d\n", ring->c_rx[r]);
+ h = &ring->rx_header[r][ring->c_rx[r]];
+ memset(h, 0, sizeof(struct p_hdr));
+ h->buf = (u8 *)KSEG1ADDR(ring->rx_space +
+ r * priv->rxringlen * RING_BUFFER +
+ ring->c_rx[r] * RING_BUFFER);
+ h->size = RING_BUFFER;
+ /* make sure the header is visible to the ASIC */
+ mb();
+
+ ring->rx_r[r][ring->c_rx[r]] = KSEG1ADDR(h) | 0x1 | (ring->c_rx[r] == (priv->rxringlen - 1) ?
+ WRAP :
+ 0x1);
+ ring->c_rx[r] = (ring->c_rx[r] + 1) % priv->rxringlen;
+ } while (&ring->rx_r[r][ring->c_rx[r]] != last);
+ }
+}
+
+struct fdb_update_work {
+ struct work_struct work;
+ struct net_device *ndev;
+ u64 macs[NOTIFY_EVENTS + 1];
+};
+
+void rtl838x_fdb_sync(struct work_struct *work)
+{
+ const struct fdb_update_work *uw = container_of(work, struct fdb_update_work, work);
+
+ for (int i = 0; uw->macs[i]; i++) {
+ struct switchdev_notifier_fdb_info info;
+ u8 addr[ETH_ALEN];
+ int action;
+
+ action = (uw->macs[i] & (1ULL << 63)) ?
+ SWITCHDEV_FDB_ADD_TO_BRIDGE :
+ SWITCHDEV_FDB_DEL_TO_BRIDGE;
+ u64_to_ether_addr(uw->macs[i] & 0xffffffffffffULL, addr);
+ info.addr = &addr[0];
+ info.vid = 0;
+ info.offloaded = 1;
+ pr_debug("FDB entry %d: %llx, action %d\n", i, uw->macs[0], action);
+ call_switchdev_notifiers(action, uw->ndev, &info.info, NULL);
+ }
+ kfree(work);
+}
+
+static void rtl839x_l2_notification_handler(struct rtl838x_eth_priv *priv)
+{
+ struct notify_b *nb = priv->membase + sizeof(struct ring_b);
+ u32 e = priv->lastEvent;
+
+ while (!(nb->ring[e] & 1)) {
+ struct fdb_update_work *w;
+ struct n_event *event;
+ u64 mac;
+ int i;
+
+ w = kzalloc(sizeof(*w), GFP_ATOMIC);
+ if (!w) {
+ pr_err("Out of memory: %s", __func__);
+ return;
+ }
+ INIT_WORK(&w->work, rtl838x_fdb_sync);
+
+ for (i = 0; i < NOTIFY_EVENTS; i++) {
+ event = &nb->blocks[e].events[i];
+ if (!event->valid)
+ continue;
+ mac = event->mac;
+ if (event->type)
+ mac |= 1ULL << 63;
+ w->ndev = priv->netdev;
+ w->macs[i] = mac;
+ }
+
+ /* Hand the ring entry back to the switch */
+ nb->ring[e] = nb->ring[e] | 1;
+ e = (e + 1) % NOTIFY_BLOCKS;
+
+ w->macs[i] = 0ULL;
+ schedule_work(&w->work);
+ }
+ priv->lastEvent = e;
+}
+
+static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+ u32 status = sw_r32(priv->r->dma_if_intr_sts);
+
+ pr_debug("IRQ: %08x\n", status);
+
+ /* Ignore TX interrupt */
+ if ((status & 0xf0000)) {
+ /* Clear ISR */
+ sw_w32(0x000f0000, priv->r->dma_if_intr_sts);
+ }
+
+ /* RX interrupt */
+ if (status & 0x0ff00) {
+ /* ACK and disable RX interrupt for this ring */
+ sw_w32_mask(0xff00 & status, 0, priv->r->dma_if_intr_msk);
+ sw_w32(0x0000ff00 & status, priv->r->dma_if_intr_sts);
+ for (int i = 0; i < priv->rxrings; i++) {
+ if (status & BIT(i + 8)) {
+ pr_debug("Scheduling queue: %d\n", i);
+ napi_schedule(&priv->rx_qs[i].napi);
+ }
+ }
+ }
+
+ /* RX buffer overrun */
+ if (status & 0x000ff) {
+ pr_debug("RX buffer overrun: status %x, mask: %x\n",
+ status, sw_r32(priv->r->dma_if_intr_msk));
+ sw_w32(status, priv->r->dma_if_intr_sts);
+ rtl838x_rb_cleanup(priv, status & 0xff);
+ }
+
+ if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00100000) {
+ sw_w32(0x00100000, priv->r->dma_if_intr_sts);
+ rtl839x_l2_notification_handler(priv);
+ }
+
+ if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00200000) {
+ sw_w32(0x00200000, priv->r->dma_if_intr_sts);
+ rtl839x_l2_notification_handler(priv);
+ }
+
+ if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00400000) {
+ sw_w32(0x00400000, priv->r->dma_if_intr_sts);
+ rtl839x_l2_notification_handler(priv);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rtl93xx_net_irq(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+ u32 status_rx_r = sw_r32(priv->r->dma_if_intr_rx_runout_sts);
+ u32 status_rx = sw_r32(priv->r->dma_if_intr_rx_done_sts);
+ u32 status_tx = sw_r32(priv->r->dma_if_intr_tx_done_sts);
+
+ pr_debug("In %s, status_tx: %08x, status_rx: %08x, status_rx_r: %08x\n",
+ __func__, status_tx, status_rx, status_rx_r);
+
+ /* Ignore TX interrupt */
+ if (status_tx) {
+ /* Clear ISR */
+ pr_debug("TX done\n");
+ sw_w32(status_tx, priv->r->dma_if_intr_tx_done_sts);
+ }
+
+ /* RX interrupt */
+ if (status_rx) {
+ pr_debug("RX IRQ\n");
+ /* ACK and disable RX interrupt for given rings */
+ sw_w32(status_rx, priv->r->dma_if_intr_rx_done_sts);
+ sw_w32_mask(status_rx, 0, priv->r->dma_if_intr_rx_done_msk);
+ for (int i = 0; i < priv->rxrings; i++) {
+ if (status_rx & BIT(i)) {
+ pr_debug("Scheduling queue: %d\n", i);
+ napi_schedule(&priv->rx_qs[i].napi);
+ }
+ }
+ }
+
+ /* RX buffer overrun */
+ if (status_rx_r) {
+ pr_debug("RX buffer overrun: status %x, mask: %x\n",
+ status_rx_r, sw_r32(priv->r->dma_if_intr_rx_runout_msk));
+ sw_w32(status_rx_r, priv->r->dma_if_intr_rx_runout_sts);
+ rtl838x_rb_cleanup(priv, status_rx_r);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static const struct rtl838x_eth_reg rtl838x_reg = {
+ .net_irq = rtl83xx_net_irq,
+ .mac_port_ctrl = rtl838x_mac_port_ctrl,
+ .dma_if_intr_sts = RTL838X_DMA_IF_INTR_STS,
+ .dma_if_intr_msk = RTL838X_DMA_IF_INTR_MSK,
+ .dma_if_ctrl = RTL838X_DMA_IF_CTRL,
+ .mac_force_mode_ctrl = RTL838X_MAC_FORCE_MODE_CTRL,
+ .dma_rx_base = RTL838X_DMA_RX_BASE,
+ .dma_tx_base = RTL838X_DMA_TX_BASE,
+ .dma_if_rx_ring_size = rtl838x_dma_if_rx_ring_size,
+ .dma_if_rx_ring_cntr = rtl838x_dma_if_rx_ring_cntr,
+ .dma_if_rx_cur = RTL838X_DMA_IF_RX_CUR,
+ .rst_glb_ctrl = RTL838X_RST_GLB_CTRL_0,
+ .get_mac_link_sts = rtl838x_get_mac_link_sts,
+ .get_mac_link_dup_sts = rtl838x_get_mac_link_dup_sts,
+ .get_mac_link_spd_sts = rtl838x_get_mac_link_spd_sts,
+ .get_mac_rx_pause_sts = rtl838x_get_mac_rx_pause_sts,
+ .get_mac_tx_pause_sts = rtl838x_get_mac_tx_pause_sts,
+ .mac = RTL838X_MAC,
+ .l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL,
+ .update_cntr = rtl838x_update_cntr,
+ .create_tx_header = rtl838x_create_tx_header,
+ .decode_tag = rtl838x_decode_tag,
+};
+
+static const struct rtl838x_eth_reg rtl839x_reg = {
+ .net_irq = rtl83xx_net_irq,
+ .mac_port_ctrl = rtl839x_mac_port_ctrl,
+ .dma_if_intr_sts = RTL839X_DMA_IF_INTR_STS,
+ .dma_if_intr_msk = RTL839X_DMA_IF_INTR_MSK,
+ .dma_if_ctrl = RTL839X_DMA_IF_CTRL,
+ .mac_force_mode_ctrl = RTL839X_MAC_FORCE_MODE_CTRL,
+ .dma_rx_base = RTL839X_DMA_RX_BASE,
+ .dma_tx_base = RTL839X_DMA_TX_BASE,
+ .dma_if_rx_ring_size = rtl839x_dma_if_rx_ring_size,
+ .dma_if_rx_ring_cntr = rtl839x_dma_if_rx_ring_cntr,
+ .dma_if_rx_cur = RTL839X_DMA_IF_RX_CUR,
+ .rst_glb_ctrl = RTL839X_RST_GLB_CTRL,
+ .get_mac_link_sts = rtl839x_get_mac_link_sts,
+ .get_mac_link_dup_sts = rtl839x_get_mac_link_dup_sts,
+ .get_mac_link_spd_sts = rtl839x_get_mac_link_spd_sts,
+ .get_mac_rx_pause_sts = rtl839x_get_mac_rx_pause_sts,
+ .get_mac_tx_pause_sts = rtl839x_get_mac_tx_pause_sts,
+ .mac = RTL839X_MAC,
+ .l2_tbl_flush_ctrl = RTL839X_L2_TBL_FLUSH_CTRL,
+ .update_cntr = rtl839x_update_cntr,
+ .create_tx_header = rtl839x_create_tx_header,
+ .decode_tag = rtl839x_decode_tag,
+};
+
+static const struct rtl838x_eth_reg rtl930x_reg = {
+ .net_irq = rtl93xx_net_irq,
+ .mac_port_ctrl = rtl930x_mac_port_ctrl,
+ .dma_if_intr_rx_runout_sts = RTL930X_DMA_IF_INTR_RX_RUNOUT_STS,
+ .dma_if_intr_rx_done_sts = RTL930X_DMA_IF_INTR_RX_DONE_STS,
+ .dma_if_intr_tx_done_sts = RTL930X_DMA_IF_INTR_TX_DONE_STS,
+ .dma_if_intr_rx_runout_msk = RTL930X_DMA_IF_INTR_RX_RUNOUT_MSK,
+ .dma_if_intr_rx_done_msk = RTL930X_DMA_IF_INTR_RX_DONE_MSK,
+ .dma_if_intr_tx_done_msk = RTL930X_DMA_IF_INTR_TX_DONE_MSK,
+ .l2_ntfy_if_intr_sts = RTL930X_L2_NTFY_IF_INTR_STS,
+ .l2_ntfy_if_intr_msk = RTL930X_L2_NTFY_IF_INTR_MSK,
+ .dma_if_ctrl = RTL930X_DMA_IF_CTRL,
+ .mac_force_mode_ctrl = RTL930X_MAC_FORCE_MODE_CTRL,
+ .dma_rx_base = RTL930X_DMA_RX_BASE,
+ .dma_tx_base = RTL930X_DMA_TX_BASE,
+ .dma_if_rx_ring_size = rtl930x_dma_if_rx_ring_size,
+ .dma_if_rx_ring_cntr = rtl930x_dma_if_rx_ring_cntr,
+ .dma_if_rx_cur = RTL930X_DMA_IF_RX_CUR,
+ .rst_glb_ctrl = RTL930X_RST_GLB_CTRL_0,
+ .get_mac_link_sts = rtl930x_get_mac_link_sts,
+ .get_mac_link_dup_sts = rtl930x_get_mac_link_dup_sts,
+ .get_mac_link_spd_sts = rtl930x_get_mac_link_spd_sts,
+ .get_mac_rx_pause_sts = rtl930x_get_mac_rx_pause_sts,
+ .get_mac_tx_pause_sts = rtl930x_get_mac_tx_pause_sts,
+ .mac = RTL930X_MAC_L2_ADDR_CTRL,
+ .l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL,
+ .update_cntr = rtl930x_update_cntr,
+ .create_tx_header = rtl930x_create_tx_header,
+ .decode_tag = rtl930x_decode_tag,
+};
+
+static const struct rtl838x_eth_reg rtl931x_reg = {
+ .net_irq = rtl93xx_net_irq,
+ .mac_port_ctrl = rtl931x_mac_port_ctrl,
+ .dma_if_intr_rx_runout_sts = RTL931X_DMA_IF_INTR_RX_RUNOUT_STS,
+ .dma_if_intr_rx_done_sts = RTL931X_DMA_IF_INTR_RX_DONE_STS,
+ .dma_if_intr_tx_done_sts = RTL931X_DMA_IF_INTR_TX_DONE_STS,
+ .dma_if_intr_rx_runout_msk = RTL931X_DMA_IF_INTR_RX_RUNOUT_MSK,
+ .dma_if_intr_rx_done_msk = RTL931X_DMA_IF_INTR_RX_DONE_MSK,
+ .dma_if_intr_tx_done_msk = RTL931X_DMA_IF_INTR_TX_DONE_MSK,
+ .l2_ntfy_if_intr_sts = RTL931X_L2_NTFY_IF_INTR_STS,
+ .l2_ntfy_if_intr_msk = RTL931X_L2_NTFY_IF_INTR_MSK,
+ .dma_if_ctrl = RTL931X_DMA_IF_CTRL,
+ .mac_force_mode_ctrl = RTL931X_MAC_FORCE_MODE_CTRL,
+ .dma_rx_base = RTL931X_DMA_RX_BASE,
+ .dma_tx_base = RTL931X_DMA_TX_BASE,
+ .dma_if_rx_ring_size = rtl931x_dma_if_rx_ring_size,
+ .dma_if_rx_ring_cntr = rtl931x_dma_if_rx_ring_cntr,
+ .dma_if_rx_cur = RTL931X_DMA_IF_RX_CUR,
+ .rst_glb_ctrl = RTL931X_RST_GLB_CTRL,
+ .get_mac_link_sts = rtl931x_get_mac_link_sts,
+ .get_mac_link_dup_sts = rtl931x_get_mac_link_dup_sts,
+ .get_mac_link_spd_sts = rtl931x_get_mac_link_spd_sts,
+ .get_mac_rx_pause_sts = rtl931x_get_mac_rx_pause_sts,
+ .get_mac_tx_pause_sts = rtl931x_get_mac_tx_pause_sts,
+ .mac = RTL931X_MAC_L2_ADDR_CTRL,
+ .l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL,
+ .update_cntr = rtl931x_update_cntr,
+ .create_tx_header = rtl931x_create_tx_header,
+ .decode_tag = rtl931x_decode_tag,
+};
+
+static void rtl838x_hw_reset(struct rtl838x_eth_priv *priv)
+{
+ u32 int_saved, nbuf;
+ u32 reset_mask;
+
+ pr_info("RESETTING %x, CPU_PORT %d\n", priv->family_id, priv->cpu_port);
+ sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(priv->cpu_port));
+ mdelay(100);
+
+ /* Disable and clear interrupts */
+ if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) {
+ sw_w32(0x00000000, priv->r->dma_if_intr_rx_runout_msk);
+ sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_sts);
+ sw_w32(0x00000000, priv->r->dma_if_intr_rx_done_msk);
+ sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_sts);
+ sw_w32(0x00000000, priv->r->dma_if_intr_tx_done_msk);
+ sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_sts);
+ } else {
+ sw_w32(0x00000000, priv->r->dma_if_intr_msk);
+ sw_w32(0xffffffff, priv->r->dma_if_intr_sts);
+ }
+
+ if (priv->family_id == RTL8390_FAMILY_ID) {
+ /* Preserve L2 notification and NBUF settings */
+ int_saved = sw_r32(priv->r->dma_if_intr_msk);
+ nbuf = sw_r32(RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL);
+
+ /* Disable link change interrupt on RTL839x */
+ sw_w32(0, RTL839X_IMR_PORT_LINK_STS_CHG);
+ sw_w32(0, RTL839X_IMR_PORT_LINK_STS_CHG + 4);
+
+ sw_w32(0x00000000, priv->r->dma_if_intr_msk);
+ sw_w32(0xffffffff, priv->r->dma_if_intr_sts);
+ }
+
+ /* Reset NIC (SW_NIC_RST) and queues (SW_Q_RST) */
+ if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID)
+ reset_mask = 0x6;
+ else
+ reset_mask = 0xc;
+
+ sw_w32_mask(0, reset_mask, priv->r->rst_glb_ctrl);
+
+ do { /* Wait for reset of NIC and Queues done */
+ udelay(20);
+ } while (sw_r32(priv->r->rst_glb_ctrl) & reset_mask);
+ mdelay(100);
+
+ /* Setup Head of Line */
+ if (priv->family_id == RTL8380_FAMILY_ID)
+ sw_w32(0, RTL838X_DMA_IF_RX_RING_SIZE); /* Disabled on RTL8380 */
+ if (priv->family_id == RTL8390_FAMILY_ID)
+ sw_w32(0xffffffff, RTL839X_DMA_IF_RX_RING_CNTR);
+ if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) {
+ for (int i = 0; i < priv->rxrings; i++) {
+ int pos = (i % 3) * 10;
+
+ sw_w32_mask(0x3ff << pos, 0, priv->r->dma_if_rx_ring_size(i));
+ sw_w32_mask(0x3ff << pos, priv->rxringlen,
+ priv->r->dma_if_rx_ring_cntr(i));
+ }
+ }
+
+ /* Re-enable link change interrupt */
+ if (priv->family_id == RTL8390_FAMILY_ID) {
+ sw_w32(0xffffffff, RTL839X_ISR_PORT_LINK_STS_CHG);
+ sw_w32(0xffffffff, RTL839X_ISR_PORT_LINK_STS_CHG + 4);
+ sw_w32(0xffffffff, RTL839X_IMR_PORT_LINK_STS_CHG);
+ sw_w32(0xffffffff, RTL839X_IMR_PORT_LINK_STS_CHG + 4);
+
+ /* Restore notification settings: on RTL838x these bits are null */
+ sw_w32_mask(7 << 20, int_saved & (7 << 20), priv->r->dma_if_intr_msk);
+ sw_w32(nbuf, RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL);
+ }
+}
+
+static void rtl838x_hw_ring_setup(struct rtl838x_eth_priv *priv)
+{
+ struct ring_b *ring = priv->membase;
+
+ for (int i = 0; i < priv->rxrings; i++)
+ sw_w32(KSEG1ADDR(&ring->rx_r[i]), priv->r->dma_rx_base + i * 4);
+
+ for (int i = 0; i < TXRINGS; i++)
+ sw_w32(KSEG1ADDR(&ring->tx_r[i]), priv->r->dma_tx_base + i * 4);
+}
+
+static void rtl838x_hw_en_rxtx(struct rtl838x_eth_priv *priv)
+{
+ /* Disable Head of Line features for all RX rings */
+ sw_w32(0xffffffff, priv->r->dma_if_rx_ring_size(0));
+
+ /* Truncate RX buffer to DEFAULT_MTU bytes, pad TX */
+ sw_w32((DEFAULT_MTU << 16) | RX_TRUNCATE_EN_83XX | TX_PAD_EN_838X, priv->r->dma_if_ctrl);
+
+ /* Enable RX done, RX overflow and TX done interrupts */
+ sw_w32(0xfffff, priv->r->dma_if_intr_msk);
+
+ /* Enable DMA, engine expects empty FCS field */
+ sw_w32_mask(0, RX_EN | TX_EN, priv->r->dma_if_ctrl);
+
+ /* Restart TX/RX to CPU port */
+ sw_w32_mask(0x0, 0x3, priv->r->mac_port_ctrl(priv->cpu_port));
+ /* Set Speed, duplex, flow control
+ * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL
+ * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN
+ * | MEDIA_SEL
+ */
+ sw_w32(0x6192F, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
+
+ /* Enable CRC checks on CPU-port */
+ sw_w32_mask(0, BIT(3), priv->r->mac_port_ctrl(priv->cpu_port));
+}
+
+static void rtl839x_hw_en_rxtx(struct rtl838x_eth_priv *priv)
+{
+ /* Setup CPU-Port: RX Buffer */
+ sw_w32((DEFAULT_MTU << 5) | RX_TRUNCATE_EN_83XX, priv->r->dma_if_ctrl);
+
+ /* Enable Notify, RX done, RX overflow and TX done interrupts */
+ sw_w32(0x007fffff, priv->r->dma_if_intr_msk); /* Notify IRQ! */
+
+ /* Enable DMA */
+ sw_w32_mask(0, RX_EN | TX_EN, priv->r->dma_if_ctrl);
+
+ /* Restart TX/RX to CPU port, enable CRC checking */
+ sw_w32_mask(0x0, 0x3 | BIT(3), priv->r->mac_port_ctrl(priv->cpu_port));
+
+ /* CPU port joins Lookup Miss Flooding Portmask */
+ /* TODO: The code below should also work for the RTL838x */
+ sw_w32(0x28000, RTL839X_TBL_ACCESS_L2_CTRL);
+ sw_w32_mask(0, 0x80000000, RTL839X_TBL_ACCESS_L2_DATA(0));
+ sw_w32(0x38000, RTL839X_TBL_ACCESS_L2_CTRL);
+
+ /* Force CPU port link up */
+ sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
+}
+
+static void rtl93xx_hw_en_rxtx(struct rtl838x_eth_priv *priv)
+{
+ /* Setup CPU-Port: RX Buffer truncated at DEFAULT_MTU Bytes */
+ sw_w32((DEFAULT_MTU << 16) | RX_TRUNCATE_EN_93XX, priv->r->dma_if_ctrl);
+
+ for (int i = 0; i < priv->rxrings; i++) {
+ int pos = (i % 3) * 10;
+ u32 v;
+
+ sw_w32_mask(0x3ff << pos, priv->rxringlen << pos, priv->r->dma_if_rx_ring_size(i));
+
+ /* Some SoCs have issues with missing underflow protection */
+ v = (sw_r32(priv->r->dma_if_rx_ring_cntr(i)) >> pos) & 0x3ff;
+ sw_w32_mask(0x3ff << pos, v, priv->r->dma_if_rx_ring_cntr(i));
+ }
+
+ /* Enable Notify, RX done, RX overflow and TX done interrupts */
+ sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_msk);
+ sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk);
+ sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_msk);
+
+ /* Enable DMA */
+ sw_w32_mask(0, RX_EN_93XX | TX_EN_93XX, priv->r->dma_if_ctrl);
+
+ /* Restart TX/RX to CPU port, enable CRC checking */
+ sw_w32_mask(0x0, 0x3 | BIT(4), priv->r->mac_port_ctrl(priv->cpu_port));
+
+ if (priv->family_id == RTL9300_FAMILY_ID)
+ sw_w32_mask(0, BIT(priv->cpu_port), RTL930X_L2_UNKN_UC_FLD_PMSK);
+ else
+ sw_w32_mask(0, BIT(priv->cpu_port), RTL931X_L2_UNKN_UC_FLD_PMSK);
+
+ if (priv->family_id == RTL9300_FAMILY_ID)
+ sw_w32(0x217, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
+ else
+ sw_w32(0x2a1d, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
+}
+
+static void rtl838x_setup_ring_buffer(struct rtl838x_eth_priv *priv, struct ring_b *ring)
+{
+ for (int i = 0; i < priv->rxrings; i++) {
+ struct p_hdr *h;
+ int j;
+
+ for (j = 0; j < priv->rxringlen; j++) {
+ h = &ring->rx_header[i][j];
+ memset(h, 0, sizeof(struct p_hdr));
+ h->buf = (u8 *)KSEG1ADDR(ring->rx_space +
+ i * priv->rxringlen * RING_BUFFER +
+ j * RING_BUFFER);
+ h->size = RING_BUFFER;
+ /* All rings owned by switch, last one wraps */
+ ring->rx_r[i][j] = KSEG1ADDR(h) | 1 | (j == (priv->rxringlen - 1) ?
+ WRAP :
+ 0);
+ }
+ ring->c_rx[i] = 0;
+ }
+
+ for (int i = 0; i < TXRINGS; i++) {
+ struct p_hdr *h;
+ int j;
+
+ for (j = 0; j < TXRINGLEN; j++) {
+ h = &ring->tx_header[i][j];
+ memset(h, 0, sizeof(struct p_hdr));
+ h->buf = (u8 *)KSEG1ADDR(ring->tx_space +
+ i * TXRINGLEN * RING_BUFFER +
+ j * RING_BUFFER);
+ h->size = RING_BUFFER;
+ ring->tx_r[i][j] = KSEG1ADDR(&ring->tx_header[i][j]);
+ }
+ /* Last header is wrapping around */
+ ring->tx_r[i][j - 1] |= WRAP;
+ ring->c_tx[i] = 0;
+ }
+}
+
+static void rtl839x_setup_notify_ring_buffer(struct rtl838x_eth_priv *priv)
+{
+ struct notify_b *b = priv->membase + sizeof(struct ring_b);
+
+ for (int i = 0; i < NOTIFY_BLOCKS; i++)
+ b->ring[i] = KSEG1ADDR(&b->blocks[i]) | 1 | (i == (NOTIFY_BLOCKS - 1) ? WRAP : 0);
+
+ sw_w32((u32) b->ring, RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL);
+ sw_w32_mask(0x3ff << 2, 100 << 2, RTL839X_L2_NOTIFICATION_CTRL);
+
+ /* Setup notification events */
+ sw_w32_mask(0, 1 << 14, RTL839X_L2_CTRL_0); /* RTL8390_L2_CTRL_0_FLUSH_NOTIFY_EN */
+ sw_w32_mask(0, 1 << 12, RTL839X_L2_NOTIFICATION_CTRL); /* SUSPEND_NOTIFICATION_EN */
+
+ /* Enable Notification */
+ sw_w32_mask(0, 1 << 0, RTL839X_L2_NOTIFICATION_CTRL);
+ priv->lastEvent = 0;
+}
+
+static int rtl838x_eth_open(struct net_device *ndev)
+{
+ unsigned long flags;
+ struct rtl838x_eth_priv *priv = netdev_priv(ndev);
+ struct ring_b *ring = priv->membase;
+
+ pr_debug("%s called: RX rings %d(length %d), TX rings %d(length %d)\n",
+ __func__, priv->rxrings, priv->rxringlen, TXRINGS, TXRINGLEN);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ rtl838x_hw_reset(priv);
+ rtl838x_setup_ring_buffer(priv, ring);
+ if (priv->family_id == RTL8390_FAMILY_ID) {
+ rtl839x_setup_notify_ring_buffer(priv);
+ /* Make sure the ring structure is visible to the ASIC */
+ mb();
+ flush_cache_all();
+ }
+
+ rtl838x_hw_ring_setup(priv);
+ phylink_start(priv->phylink);
+
+ for (int i = 0; i < priv->rxrings; i++)
+ napi_enable(&priv->rx_qs[i].napi);
+
+ switch (priv->family_id) {
+ case RTL8380_FAMILY_ID:
+ rtl838x_hw_en_rxtx(priv);
+ /* Trap IGMP/MLD traffic to CPU-Port */
+ sw_w32(0x3, RTL838X_SPCL_TRAP_IGMP_CTRL);
+ /* Flush learned FDB entries on link down of a port */
+ sw_w32_mask(0, BIT(7), RTL838X_L2_CTRL_0);
+ break;
+
+ case RTL8390_FAMILY_ID:
+ rtl839x_hw_en_rxtx(priv);
+ /* Trap MLD and IGMP messages to CPU_PORT */
+ sw_w32(0x3, RTL839X_SPCL_TRAP_IGMP_CTRL);
+ /* Flush learned FDB entries on link down of a port */
+ sw_w32_mask(0, BIT(7), RTL839X_L2_CTRL_0);
+ break;
+
+ case RTL9300_FAMILY_ID:
+ rtl93xx_hw_en_rxtx(priv);
+ /* Flush learned FDB entries on link down of a port */
+ sw_w32_mask(0, BIT(7), RTL930X_L2_CTRL);
+ /* Trap MLD and IGMP messages to CPU_PORT */
+ sw_w32((0x2 << 3) | 0x2, RTL930X_VLAN_APP_PKT_CTRL);
+ break;
+
+ case RTL9310_FAMILY_ID:
+ rtl93xx_hw_en_rxtx(priv);
+
+ /* Trap MLD and IGMP messages to CPU_PORT */
+ sw_w32((0x2 << 3) | 0x2, RTL931X_VLAN_APP_PKT_CTRL);
+
+ /* Disable External CPU access to switch, clear EXT_CPU_EN */
+ sw_w32_mask(BIT(2), 0, RTL931X_MAC_L2_GLOBAL_CTRL2);
+
+ /* Set PCIE_PWR_DOWN */
+ sw_w32_mask(0, BIT(1), RTL931X_PS_SOC_CTRL);
+ break;
+ }
+
+ netif_tx_start_all_queues(ndev);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static void rtl838x_hw_stop(struct rtl838x_eth_priv *priv)
+{
+ u32 force_mac = priv->family_id == RTL8380_FAMILY_ID ? 0x6192C : 0x75;
+ u32 clear_irq = priv->family_id == RTL8380_FAMILY_ID ? 0x000fffff : 0x007fffff;
+
+ /* Disable RX/TX from/to CPU-port */
+ sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(priv->cpu_port));
+
+ /* Disable traffic */
+ if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID)
+ sw_w32_mask(RX_EN_93XX | TX_EN_93XX, 0, priv->r->dma_if_ctrl);
+ else
+ sw_w32_mask(RX_EN | TX_EN, 0, priv->r->dma_if_ctrl);
+ mdelay(200); /* Test, whether this is needed */
+
+ /* Block all ports */
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ sw_w32(0x03000000, RTL838X_TBL_ACCESS_DATA_0(0));
+ sw_w32(0x00000000, RTL838X_TBL_ACCESS_DATA_0(1));
+ sw_w32(1 << 15 | 2 << 12, RTL838X_TBL_ACCESS_CTRL_0);
+ }
+
+ /* Flush L2 address cache */
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ for (int i = 0; i <= priv->cpu_port; i++) {
+ sw_w32(1 << 26 | 1 << 23 | i << 5, priv->r->l2_tbl_flush_ctrl);
+ do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & (1 << 26));
+ }
+ } else if (priv->family_id == RTL8390_FAMILY_ID) {
+ for (int i = 0; i <= priv->cpu_port; i++) {
+ sw_w32(1 << 28 | 1 << 25 | i << 5, priv->r->l2_tbl_flush_ctrl);
+ do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & (1 << 28));
+ }
+ }
+ /* TODO: L2 flush register is 64 bit on RTL931X and 930X */
+
+ /* CPU-Port: Link down */
+ if (priv->family_id == RTL8380_FAMILY_ID || priv->family_id == RTL8390_FAMILY_ID)
+ sw_w32(force_mac, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
+ else if (priv->family_id == RTL9300_FAMILY_ID)
+ sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl + priv->cpu_port *4);
+ else if (priv->family_id == RTL9310_FAMILY_ID)
+ sw_w32_mask(BIT(0) | BIT(9), 0, priv->r->mac_force_mode_ctrl + priv->cpu_port *4);
+ mdelay(100);
+
+ /* Disable all TX/RX interrupts */
+ if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) {
+ sw_w32(0x00000000, priv->r->dma_if_intr_rx_runout_msk);
+ sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_sts);
+ sw_w32(0x00000000, priv->r->dma_if_intr_rx_done_msk);
+ sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_sts);
+ sw_w32(0x00000000, priv->r->dma_if_intr_tx_done_msk);
+ sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_sts);
+ } else {
+ sw_w32(0x00000000, priv->r->dma_if_intr_msk);
+ sw_w32(clear_irq, priv->r->dma_if_intr_sts);
+ }
+
+ /* Disable TX/RX DMA */
+ sw_w32(0x00000000, priv->r->dma_if_ctrl);
+ mdelay(200);
+}
+
+static int rtl838x_eth_stop(struct net_device *ndev)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(ndev);
+
+ pr_info("in %s\n", __func__);
+
+ phylink_stop(priv->phylink);
+ rtl838x_hw_stop(priv);
+
+ for (int i = 0; i < priv->rxrings; i++)
+ napi_disable(&priv->rx_qs[i].napi);
+
+ netif_tx_stop_all_queues(ndev);
+
+ return 0;
+}
+
+static void rtl838x_eth_set_multicast_list(struct net_device *ndev)
+{
+ /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(21, 0) = 0x3FFFFF
+ */
+ if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
+ sw_w32(0x0, RTL838X_RMA_CTRL_0);
+ sw_w32(0x0, RTL838X_RMA_CTRL_1);
+ }
+ if (ndev->flags & IFF_ALLMULTI)
+ sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0);
+ if (ndev->flags & IFF_PROMISC) {
+ sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0);
+ sw_w32(0x7fff, RTL838X_RMA_CTRL_1);
+ }
+}
+
+static void rtl839x_eth_set_multicast_list(struct net_device *ndev)
+{
+ /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
+ * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
+ * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
+ */
+ if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
+ sw_w32(0x0, RTL839X_RMA_CTRL_0);
+ sw_w32(0x0, RTL839X_RMA_CTRL_1);
+ sw_w32(0x0, RTL839X_RMA_CTRL_2);
+ sw_w32(0x0, RTL839X_RMA_CTRL_3);
+ }
+ if (ndev->flags & IFF_ALLMULTI) {
+ sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2);
+ }
+ if (ndev->flags & IFF_PROMISC) {
+ sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2);
+ sw_w32(0x3ff, RTL839X_RMA_CTRL_3);
+ }
+}
+
+static void rtl930x_eth_set_multicast_list(struct net_device *ndev)
+{
+ /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
+ * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
+ * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
+ */
+ if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+ sw_w32(GENMASK(31, 2), RTL930X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_2);
+ } else {
+ sw_w32(0x0, RTL930X_RMA_CTRL_0);
+ sw_w32(0x0, RTL930X_RMA_CTRL_1);
+ sw_w32(0x0, RTL930X_RMA_CTRL_2);
+ }
+}
+
+static void rtl931x_eth_set_multicast_list(struct net_device *ndev)
+{
+ /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
+ * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00.
+ * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
+ */
+ if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+ sw_w32(GENMASK(31, 2), RTL931X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_2);
+ } else {
+ sw_w32(0x0, RTL931X_RMA_CTRL_0);
+ sw_w32(0x0, RTL931X_RMA_CTRL_1);
+ sw_w32(0x0, RTL931X_RMA_CTRL_2);
+ }
+}
+
+static void rtl838x_eth_tx_timeout(struct net_device *ndev, unsigned int txqueue)
+{
+ unsigned long flags;
+ struct rtl838x_eth_priv *priv = netdev_priv(ndev);
+
+ pr_warn("%s\n", __func__);
+ spin_lock_irqsave(&priv->lock, flags);
+ rtl838x_hw_stop(priv);
+ rtl838x_hw_ring_setup(priv);
+ rtl838x_hw_en_rxtx(priv);
+ netif_trans_update(ndev);
+ netif_start_queue(ndev);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int rtl838x_eth_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ int len;
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+ struct ring_b *ring = priv->membase;
+ int ret;
+ unsigned long flags;
+ struct p_hdr *h;
+ int dest_port = -1;
+ int q = skb_get_queue_mapping(skb) % TXRINGS;
+
+ if (q) /* Check for high prio queue */
+ pr_debug("SKB priority: %d\n", skb->priority);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ len = skb->len;
+
+ /* Check for DSA tagging at the end of the buffer */
+ if (netdev_uses_dsa(dev) &&
+ skb->data[len - 4] == 0x80 &&
+ skb->data[len - 3] < priv->cpu_port &&
+ skb->data[len - 2] == 0x10 &&
+ skb->data[len - 1] == 0x00) {
+ /* Reuse tag space for CRC if possible */
+ dest_port = skb->data[len - 3];
+ skb->data[len - 4] = skb->data[len - 3] = skb->data[len - 2] = skb->data[len - 1] = 0x00;
+ len -= 4;
+ }
+
+ len += 4; /* Add space for CRC */
+
+ if (skb_padto(skb, len)) {
+ ret = NETDEV_TX_OK;
+ goto txdone;
+ }
+
+ /* We can send this packet if CPU owns the descriptor */
+ if (!(ring->tx_r[q][ring->c_tx[q]] & 0x1)) {
+
+ /* Set descriptor for tx */
+ h = &ring->tx_header[q][ring->c_tx[q]];
+ h->size = len;
+ h->len = len;
+ /* On RTL8380 SoCs, small packet lengths being sent need adjustments */
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ if (len < ETH_ZLEN - 4)
+ h->len -= 4;
+ }
+
+ if (dest_port >= 0)
+ priv->r->create_tx_header(h, dest_port, skb->priority >> 1);
+
+ /* Copy packet data to tx buffer */
+ memcpy((void *)KSEG1ADDR(h->buf), skb->data, len);
+ /* Make sure packet data is visible to ASIC */
+ wmb();
+
+ /* Hand over to switch */
+ ring->tx_r[q][ring->c_tx[q]] |= 1;
+
+ /* Before starting TX, prevent a Lextra bus bug on RTL8380 SoCs */
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ for (int i = 0; i < 10; i++) {
+ u32 val = sw_r32(priv->r->dma_if_ctrl);
+ if ((val & 0xc) == 0xc)
+ break;
+ }
+ }
+
+ /* Tell switch to send data */
+ if (priv->family_id == RTL9310_FAMILY_ID || priv->family_id == RTL9300_FAMILY_ID) {
+ /* Ring ID q == 0: Low priority, Ring ID = 1: High prio queue */
+ if (!q)
+ sw_w32_mask(0, BIT(2), priv->r->dma_if_ctrl);
+ else
+ sw_w32_mask(0, BIT(3), priv->r->dma_if_ctrl);
+ } else {
+ sw_w32_mask(0, TX_DO, priv->r->dma_if_ctrl);
+ }
+
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += len;
+ dev_kfree_skb(skb);
+ ring->c_tx[q] = (ring->c_tx[q] + 1) % TXRINGLEN;
+ ret = NETDEV_TX_OK;
+ } else {
+ dev_warn(&priv->pdev->dev, "Data is owned by switch\n");
+ ret = NETDEV_TX_BUSY;
+ }
+
+txdone:
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return ret;
+}
+
+/* Return queue number for TX. On the RTL83XX, these queues have equal priority
+ * so we do round-robin
+ */
+u16 rtl83xx_pick_tx_queue(struct net_device *dev, struct sk_buff *skb,
+ struct net_device *sb_dev)
+{
+ static u8 last = 0;
+
+ last++;
+ return last % TXRINGS;
+}
+
+/* Return queue number for TX. On the RTL93XX, queue 1 is the high priority queue
+ */
+u16 rtl93xx_pick_tx_queue(struct net_device *dev, struct sk_buff *skb,
+ struct net_device *sb_dev)
+{
+ if (skb->priority >= TC_PRIO_CONTROL)
+ return 1;
+
+ return 0;
+}
+
+static int rtl838x_hw_receive(struct net_device *dev, int r, int budget)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+ struct ring_b *ring = priv->membase;
+ LIST_HEAD(rx_list);
+ unsigned long flags;
+ int work_done = 0;
+ u32 *last;
+ bool dsa = netdev_uses_dsa(dev);
+
+ pr_debug("---------------------------------------------------------- RX - %d\n", r);
+ spin_lock_irqsave(&priv->lock, flags);
+ last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4));
+
+ do {
+ struct sk_buff *skb;
+ struct dsa_tag tag;
+ struct p_hdr *h;
+ u8 *skb_data;
+ u8 *data;
+ int len;
+
+ if ((ring->rx_r[r][ring->c_rx[r]] & 0x1)) {
+ if (&ring->rx_r[r][ring->c_rx[r]] != last) {
+ netdev_warn(dev, "Ring contention: r: %x, last %x, cur %x\n",
+ r, (uint32_t)last, (u32) &ring->rx_r[r][ring->c_rx[r]]);
+ }
+ break;
+ }
+
+ h = &ring->rx_header[r][ring->c_rx[r]];
+ data = (u8 *)KSEG1ADDR(h->buf);
+ len = h->len;
+ if (!len)
+ break;
+ work_done++;
+
+ len -= 4; /* strip the CRC */
+ /* Add 4 bytes for cpu_tag */
+ if (dsa)
+ len += 4;
+
+ skb = netdev_alloc_skb(dev, len + 4);
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ if (likely(skb)) {
+ /* BUG: Prevent bug on RTL838x SoCs */
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ sw_w32(0xffffffff, priv->r->dma_if_rx_ring_size(0));
+ for (int i = 0; i < priv->rxrings; i++) {
+ unsigned int val;
+
+ /* Update each ring cnt */
+ val = sw_r32(priv->r->dma_if_rx_ring_cntr(i));
+ sw_w32(val, priv->r->dma_if_rx_ring_cntr(i));
+ }
+ }
+
+ skb_data = skb_put(skb, len);
+ /* Make sure data is visible */
+ mb();
+ memcpy(skb->data, (u8 *)KSEG1ADDR(data), len);
+ /* Overwrite CRC with cpu_tag */
+ if (dsa) {
+ priv->r->decode_tag(h, &tag);
+ skb->data[len - 4] = 0x80;
+ skb->data[len - 3] = tag.port;
+ skb->data[len - 2] = 0x10;
+ skb->data[len - 1] = 0x00;
+ if (tag.l2_offloaded)
+ skb->data[len - 3] |= 0x40;
+ }
+
+ if (tag.queue >= 0)
+ pr_debug("Queue: %d, len: %d, reason %d port %d\n",
+ tag.queue, len, tag.reason, tag.port);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ if (dev->features & NETIF_F_RXCSUM) {
+ if (tag.crc_error)
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
+
+ list_add_tail(&skb->list, &rx_list);
+ } else {
+ if (net_ratelimit())
+ dev_warn(&dev->dev, "low on memory - packet dropped\n");
+ dev->stats.rx_dropped++;
+ }
+
+ /* Reset header structure */
+ memset(h, 0, sizeof(struct p_hdr));
+ h->buf = data;
+ h->size = RING_BUFFER;
+
+ ring->rx_r[r][ring->c_rx[r]] = KSEG1ADDR(h) | 0x1 | (ring->c_rx[r] == (priv->rxringlen - 1) ?
+ WRAP :
+ 0x1);
+ ring->c_rx[r] = (ring->c_rx[r] + 1) % priv->rxringlen;
+ last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4));
+ } while (&ring->rx_r[r][ring->c_rx[r]] != last && work_done < budget);
+
+ netif_receive_skb_list(&rx_list);
+
+ /* Update counters */
+ priv->r->update_cntr(r, 0);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return work_done;
+}
+
+static int rtl838x_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct rtl838x_rx_q *rx_q = container_of(napi, struct rtl838x_rx_q, napi);
+ struct rtl838x_eth_priv *priv = rx_q->priv;
+ int work_done = 0;
+ int r = rx_q->id;
+ int work;
+
+ while (work_done < budget) {
+ work = rtl838x_hw_receive(priv->netdev, r, budget - work_done);
+ if (!work)
+ break;
+ work_done += work;
+ }
+
+ if (work_done < budget) {
+ napi_complete_done(napi, work_done);
+
+ /* Enable RX interrupt */
+ if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID)
+ sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk);
+ else
+ sw_w32_mask(0, 0xf00ff | BIT(r + 8), priv->r->dma_if_intr_msk);
+ }
+
+ return work_done;
+}
+
+
+static void rtl838x_validate(struct phylink_config *config,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+{
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+ pr_debug("In %s\n", __func__);
+
+ if (!phy_interface_mode_is_rgmii(state->interface) &&
+ state->interface != PHY_INTERFACE_MODE_1000BASEX &&
+ state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_REVMII &&
+ state->interface != PHY_INTERFACE_MODE_GMII &&
+ state->interface != PHY_INTERFACE_MODE_QSGMII &&
+ state->interface != PHY_INTERFACE_MODE_INTERNAL &&
+ state->interface != PHY_INTERFACE_MODE_SGMII) {
+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ pr_err("Unsupported interface: %d\n", state->interface);
+ return;
+ }
+
+ /* Allow all the expected bits */
+ phylink_set(mask, Autoneg);
+ phylink_set_port_modes(mask);
+ phylink_set(mask, Pause);
+ phylink_set(mask, Asym_Pause);
+
+ /* With the exclusion of MII and Reverse MII, we support Gigabit,
+ * including Half duplex
+ */
+ if (state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_REVMII) {
+ phylink_set(mask, 1000baseT_Full);
+ phylink_set(mask, 1000baseT_Half);
+ }
+
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 100baseT_Full);
+
+ bitmap_and(supported, supported, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_and(state->advertising, state->advertising, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+
+static void rtl838x_mac_config(struct phylink_config *config,
+ unsigned int mode,
+ const struct phylink_link_state *state)
+{
+ /* This is only being called for the master device,
+ * i.e. the CPU-Port. We don't need to do anything.
+ */
+
+ pr_info("In %s, mode %x\n", __func__, mode);
+}
+
+static void rtl838x_pcs_an_restart(struct phylink_pcs *pcs)
+{
+ struct rtl838x_eth_priv *priv = container_of(pcs, struct rtl838x_eth_priv, pcs);
+
+ /* This works only on RTL838x chips */
+ if (priv->family_id != RTL8380_FAMILY_ID)
+ return;
+
+ pr_debug("In %s\n", __func__);
+ /* Restart by disabling and re-enabling link */
+ sw_w32(0x6192D, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
+ mdelay(20);
+ sw_w32(0x6192F, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4);
+}
+
+static void rtl838x_pcs_get_state(struct phylink_pcs *pcs,
+ struct phylink_link_state *state)
+{
+ u32 speed;
+ struct rtl838x_eth_priv *priv = container_of(pcs, struct rtl838x_eth_priv, pcs);
+ int port = priv->cpu_port;
+
+ pr_info("In %s\n", __func__);
+
+ state->link = priv->r->get_mac_link_sts(port) ? 1 : 0;
+ state->duplex = priv->r->get_mac_link_dup_sts(port) ? 1 : 0;
+
+ pr_info("%s link status is %d\n", __func__, state->link);
+ speed = priv->r->get_mac_link_spd_sts(port);
+ switch (speed) {
+ case 0:
+ state->speed = SPEED_10;
+ break;
+ case 1:
+ state->speed = SPEED_100;
+ break;
+ case 2:
+ state->speed = SPEED_1000;
+ break;
+ case 5:
+ state->speed = SPEED_2500;
+ break;
+ case 6:
+ state->speed = SPEED_5000;
+ break;
+ case 4:
+ state->speed = SPEED_10000;
+ break;
+ default:
+ state->speed = SPEED_UNKNOWN;
+ break;
+ }
+
+ state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
+ if (priv->r->get_mac_rx_pause_sts(port))
+ state->pause |= MLO_PAUSE_RX;
+ if (priv->r->get_mac_tx_pause_sts(port))
+ state->pause |= MLO_PAUSE_TX;
+}
+
+static int rtl838x_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+ phy_interface_t interface,
+ const unsigned long *advertising,
+ bool permit_pause_to_mac)
+{
+ return 0;
+}
+
+static void rtl838x_mac_link_down(struct phylink_config *config,
+ unsigned int mode,
+ phy_interface_t interface)
+{
+ struct net_device *dev = container_of(config->dev, struct net_device, dev);
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+
+ pr_debug("In %s\n", __func__);
+ /* Stop TX/RX to port */
+ sw_w32_mask(0x03, 0, priv->r->mac_port_ctrl(priv->cpu_port));
+}
+
+static void rtl838x_mac_link_up(struct phylink_config *config,
+ struct phy_device *phy, unsigned int mode,
+ phy_interface_t interface, int speed, int duplex,
+ bool tx_pause, bool rx_pause)
+{
+ struct net_device *dev = container_of(config->dev, struct net_device, dev);
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+
+ pr_debug("In %s\n", __func__);
+ /* Restart TX/RX to port */
+ sw_w32_mask(0, 0x03, priv->r->mac_port_ctrl(priv->cpu_port));
+}
+
+static void rtl838x_set_mac_hw(struct net_device *dev, u8 *mac)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ pr_debug("In %s\n", __func__);
+ sw_w32((mac[0] << 8) | mac[1], priv->r->mac);
+ sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], priv->r->mac + 4);
+
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ /* 2 more registers, ALE/MAC block */
+ sw_w32((mac[0] << 8) | mac[1], RTL838X_MAC_ALE);
+ sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
+ (RTL838X_MAC_ALE + 4));
+
+ sw_w32((mac[0] << 8) | mac[1], RTL838X_MAC2);
+ sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
+ RTL838X_MAC2 + 4);
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int rtl838x_set_mac_address(struct net_device *dev, void *p)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+ const struct sockaddr *addr = p;
+ u8 *mac = (u8 *) (addr->sa_data);
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ dev_addr_set(dev, addr->sa_data);
+ rtl838x_set_mac_hw(dev, mac);
+
+ pr_info("Using MAC %08x%08x\n", sw_r32(priv->r->mac), sw_r32(priv->r->mac + 4));
+
+ return 0;
+}
+
+static int rtl8390_init_mac(struct rtl838x_eth_priv *priv)
+{
+ /* We will need to set-up EEE and the egress-rate limitation */
+ return 0;
+}
+
+static int rtl8380_init_mac(struct rtl838x_eth_priv *priv)
+{
+ if (priv->family_id == 0x8390)
+ return rtl8390_init_mac(priv);
+
+ /* At present we do not know how to set up EEE on any other SoC than RTL8380 */
+ if (priv->family_id != 0x8380)
+ return 0;
+
+ pr_info("%s\n", __func__);
+ /* fix timer for EEE */
+ sw_w32(0x5001411, RTL838X_EEE_TX_TIMER_GIGA_CTRL);
+ sw_w32(0x5001417, RTL838X_EEE_TX_TIMER_GELITE_CTRL);
+
+ /* Init VLAN. TODO: Understand what is being done, here */
+ if (priv->id == 0x8382) {
+ for (int i = 0; i <= 28; i++)
+ sw_w32(0, 0xd57c + i * 0x80);
+ }
+ if (priv->id == 0x8380) {
+ for (int i = 8; i <= 28; i++)
+ sw_w32(0, 0xd57c + i * 0x80);
+ }
+
+ return 0;
+}
+
+static int rtl838x_get_link_ksettings(struct net_device *ndev,
+ struct ethtool_link_ksettings *cmd)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(ndev);
+
+ pr_debug("%s called\n", __func__);
+
+ return phylink_ethtool_ksettings_get(priv->phylink, cmd);
+}
+
+static int rtl838x_set_link_ksettings(struct net_device *ndev,
+ const struct ethtool_link_ksettings *cmd)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(ndev);
+
+ pr_debug("%s called\n", __func__);
+
+ return phylink_ethtool_ksettings_set(priv->phylink, cmd);
+}
+
+/*
+ * On all Realtek switch platforms the hardware periodically reads the link status of all
+ * PHYs. This is to some degree programmable, so that one can tell the hardware to read
+ * specific C22 registers from specific pages, or C45 registers, to determine the current
+ * link speed, duplex, flow-control, ...
+ *
+ * This happens without any need for the driver to do anything at runtime, completely
+ * invisible and in a parallel hardware thread, independent of the CPU running Linux.
+ * All one needs to do is to set it up once. Having the MAC link settings automatically
+ * follow the PHY link status also happens to be the only way to control MAC port status
+ * in a meaningful way, or at least it's the only way we fully understand, as this is
+ * what every vendor firmware is doing.
+ *
+ * The hardware PHY polling unit doesn't care about bus locking, it just assumes that all
+ * paged PHY operations are also done via the same hardware unit offering this PHY access
+ * abstractions.
+ *
+ * Additionally at least the RTL838x and RTL839x devices are known to have a so called
+ * raw mode. Using the special MAX_PAGE-1 with the MDIO controller found in Realtek
+ * SoCs allows to access the PHY in raw mode, ie. bypassing the cache and paging engine
+ * of the MDIO controller. E.g. for RTL838x this is 0xfff.
+ *
+ * On the other hand Realtek PHYs usually make use of select register 0x1f to switch
+ * pages. There is no problem to issue separate page and access bus calls to the PHYs
+ * when they are not attached to an Realtek SoC. The paradigm should be to keep the PHY
+ * implementation bus independent.
+ *
+ * As if this is not enough the PHY packages consist of 4 or 8 ports that all can be
+ * programmed individually. Some registers are only available on port 0 and configure
+ * the whole package.
+ *
+ * To bring all this together we need a tricky bus design that intercepts select page
+ * calls but lets raw page accesses through. And especially knows how to handle raw
+ * accesses to the select register. Additionally we need the possibility to write to
+ * all 8 ports of the PHY individually.
+ *
+ * While the C45 clause stuff is pretty standard the legacy functions basically track
+ * the accesses and the state of the bus with the attributes page[], raw[] and portaddr
+ * of the bus_priv structure. The page selection works as follows:
+ *
+ * phy_write(phydev, RTMDIO_PAGE_SELECT, 12) : store internal page 12 in driver
+ * phy_write(phydev, 7, 33) : write page=12, reg=7, val=33
+ *
+ * or simply
+ *
+ * phy_write_paged(phydev, 12, 7, 33) : write page=12, reg=7, val=33
+ *
+ * The port selection works as follows and must be called under a held mdio bus lock
+ *
+ * __mdiobus_write(bus, RTMDIO_PORT_SELECT, 4) : switch to port 4
+ * __phy_write(phydev, RTMDIO_PAGE_SELECT, 11) : store internal page 11 in driver
+ * __phy_write(phydev, 8, 19) : write page=11, reg=8, val=19, port=4
+ *
+ * Any Realtek PHY that will be connected to this bus must simply provide the standard
+ * page functions:
+ *
+ * define RTL821X_PAGE_SELECT 0x1f
+ *
+ * static int rtl821x_read_page(struct phy_device *phydev)
+ * {
+ * return __phy_read(phydev, RTL821X_PAGE_SELECT);
+ * }
+ *
+ * static int rtl821x_write_page(struct phy_device *phydev, int page)
+ * {
+ * return __phy_write(phydev, RTL821X_PAGE_SELECT, page);
+ * }
+ *
+ * In case there are non Realtek PHYs attached to the bus the logic might need to be
+ * reimplemented. For now it should be sufficient.
+ */
+
+#define RTMDIO_PAGE_SELECT 0x1f
+#define RTMDIO_PORT_SELECT 0x2000
+#define RTMDIO_READ 0x1
+#define RTMDIO_WRITE 0x2
+#define RTMDIO_ABS 0x4
+#define RTMDIO_PKG 0x8
+
+/*
+ * Provide a generic read/write function so we can access arbitrary ports on the bus.
+ * E.g. other ports of a PHY package on the bus. This basically resembles the kernel
+ * phy_read_paged() and phy_write_paged() functions. To inform the bus that we are
+ * working on a not default port send a RTMDIO_PORT_SELECT command at the beginning
+ * and the end to switch the port handling logic.
+ */
+
+static int rtmdio_access(struct phy_device *phydev, int op, int port,
+ int page, u32 regnum, u16 val)
+{
+ int r, ret = 0, oldpage;
+
+ if (op & RTMDIO_PKG) {
+ if (!phydev->shared)
+ return -EIO;
+ port = phydev->shared->base_addr + port;
+ }
+
+ /* lock and inform bus about non default addressing */
+ phy_lock_mdio_bus(phydev);
+ __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+ RTMDIO_PORT_SELECT, port);
+
+ oldpage = ret = __phy_read(phydev, RTMDIO_PAGE_SELECT);
+ if (oldpage >= 0 && oldpage != page) {
+ ret = __phy_write(phydev, RTMDIO_PAGE_SELECT, page);
+ if (ret < 0)
+ oldpage = ret;
+ }
+
+ if (oldpage >= 0) {
+ if (op & RTMDIO_WRITE)
+ ret = __phy_write(phydev, regnum, val);
+ else
+ ret = __phy_read(phydev, regnum);
+ }
+
+ if (oldpage >= 0) {
+ r = __phy_write(phydev, RTMDIO_PAGE_SELECT, oldpage);
+ if (ret >= 0 && r < 0)
+ ret = r;
+ } else
+ ret = oldpage;
+
+ /* reset bus to default adressing and unlock it */
+ __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+ RTMDIO_PORT_SELECT, -1);
+ phy_unlock_mdio_bus(phydev);
+
+ return ret;
+}
+
+/*
+ * To make use of the shared package functions provide wrappers that align with kernel
+ * naming conventions. The package() functions are useful to change settings on the
+ * package as a whole. The package_port() functions will allow to target the PHYs
+ * of a package individually. The port() only functions allow to access arbitrary ports
+ * on the bus through a PHY.
+ */
+
+int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val)
+{
+ return rtmdio_access(phydev, RTMDIO_WRITE | RTMDIO_PKG, port, page, regnum, val);
+}
+
+int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val)
+{
+ return rtmdio_access(phydev, RTMDIO_WRITE | RTMDIO_PKG, 0, page, regnum, val);
+}
+
+int phy_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val)
+{
+ return rtmdio_access(phydev, RTMDIO_WRITE | RTMDIO_ABS, port, page, regnum, val);
+}
+
+int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum)
+{
+ return rtmdio_access(phydev, RTMDIO_READ | RTMDIO_PKG, port, page, regnum, 0);
+}
+
+int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnum)
+{
+ return rtmdio_access(phydev, RTMDIO_READ | RTMDIO_PKG, 0, page, regnum, 0);
+}
+
+int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum)
+{
+ return rtmdio_access(phydev, RTMDIO_READ | RTMDIO_ABS, port, page, regnum, 0);
+}
+
+/* These are the core functions of our new Realtek SoC MDIO bus. */
+
+static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum)
+{
+ int err, val;
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+
+ if (bus_priv->extaddr >= 0)
+ addr = bus_priv->extaddr;
+
+ err = (*bus_priv->read_mmd_phy)(addr, devnum, regnum, &val);
+ pr_debug("rd_MMD(adr=%d, dev=%d, reg=%d) = %d, err = %d\n",
+ addr, devnum, regnum, val, err);
+ return err ? err : val;
+}
+
+static int rtmdio_83xx_read(struct mii_bus *bus, int addr, int regnum)
+{
+ int err, val;
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+ struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
+
+ if (bus_priv->extaddr >= 0)
+ addr = bus_priv->extaddr;
+
+ if (addr >= 24 && addr <= 27 && eth_priv->id == 0x8380)
+ return rtl838x_read_sds_phy(addr, regnum);
+
+ if (eth_priv->family_id == RTL8390_FAMILY_ID && eth_priv->phy_is_internal[addr])
+ return rtl839x_read_sds_phy(addr, regnum);
+
+ if (regnum == RTMDIO_PAGE_SELECT && bus_priv->page[addr] != bus_priv->rawpage)
+ return bus_priv->page[addr];
+
+ bus_priv->raw[addr] = (bus_priv->page[addr] == bus_priv->rawpage);
+ err = (*bus_priv->read_phy)(addr, bus_priv->page[addr], regnum, &val);
+ pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n",
+ addr, bus_priv->page[addr], regnum, val, err);
+ return err ? err : val;
+}
+
+static int rtmdio_93xx_read(struct mii_bus *bus, int addr, int regnum)
+{
+ int err, val;
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+ struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
+
+ if (bus_priv->extaddr >= 0)
+ addr = bus_priv->extaddr;
+
+ if (regnum == RTMDIO_PAGE_SELECT && bus_priv->page[addr] != bus_priv->rawpage)
+ return bus_priv->page[addr];
+
+ bus_priv->raw[addr] = (bus_priv->page[addr] == bus_priv->rawpage);
+ if (eth_priv->phy_is_internal[addr]) {
+ if (eth_priv->family_id == RTL9300_FAMILY_ID)
+ return rtl930x_read_sds_phy(eth_priv->sds_id[addr],
+ bus_priv->page[addr], regnum);
+ else
+ return rtl931x_read_sds_phy(eth_priv->sds_id[addr],
+ bus_priv->page[addr], regnum);
+ }
+
+ err = (*bus_priv->read_phy)(addr, bus_priv->page[addr], regnum, &val);
+ pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n",
+ addr, bus_priv->page[addr], regnum, val, err);
+ return err ? err : val;
+}
+
+static int rtmdio_write_c45(struct mii_bus *bus, int addr, int devnum, int regnum, u16 val)
+{
+ int err;
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+
+ if (bus_priv->extaddr >= 0)
+ addr = bus_priv->extaddr;
+
+ err = (*bus_priv->write_mmd_phy)(addr, devnum, regnum, val);
+ pr_debug("wr_MMD(adr=%d, dev=%d, reg=%d, val=%d) err = %d\n",
+ addr, devnum, regnum, val, err);
+ return err;
+}
+
+static int rtmdio_83xx_write(struct mii_bus *bus, int addr, int regnum, u16 val)
+{
+ int err, page, offset = 0;
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+ struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
+
+ if (regnum == RTMDIO_PORT_SELECT) {
+ bus_priv->extaddr = (s16)val;
+ return 0;
+ }
+
+ if (bus_priv->extaddr >= 0)
+ addr = bus_priv->extaddr;
+ page = bus_priv->page[addr];
+
+ if (addr >= 24 && addr <= 27 && eth_priv->id == 0x8380) {
+ if (addr == 26)
+ offset = 0x100;
+ sw_w32(val, RTL838X_SDS4_FIB_REG0 + offset + (regnum << 2));
+ return 0;
+ }
+
+ if (eth_priv->family_id == RTL8390_FAMILY_ID && eth_priv->phy_is_internal[addr])
+ return rtl839x_write_sds_phy(addr, regnum, val);
+
+ if (regnum == RTMDIO_PAGE_SELECT)
+ bus_priv->page[addr] = val;
+
+ if (!bus_priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == bus_priv->rawpage)) {
+ bus_priv->raw[addr] = (page == bus_priv->rawpage);
+ err = (*bus_priv->write_phy)(addr, page, regnum, val);
+ pr_debug("wr_PHY(adr=%d, pag=%d, reg=%d, val=%d) err = %d\n",
+ addr, page, regnum, val, err);
+ return err;
+ }
+
+ bus_priv->raw[addr] = false;
+ return 0;
+}
+
+static int rtmdio_93xx_write(struct mii_bus *bus, int addr, int regnum, u16 val)
+{
+ int err, page;
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+ struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
+
+ if (regnum == RTMDIO_PORT_SELECT) {
+ bus_priv->extaddr = (s16)val;
+ return 0;
+ }
+
+ if (bus_priv->extaddr >= 0)
+ addr = bus_priv->extaddr;
+ page = bus_priv->page[addr];
+
+ if (regnum == RTMDIO_PAGE_SELECT)
+ bus_priv->page[addr] = val;
+
+ if (!bus_priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == bus_priv->rawpage)) {
+ bus_priv->raw[addr] = (page == bus_priv->rawpage);
+ if (eth_priv->phy_is_internal[addr]) {
+ if (eth_priv->family_id == RTL9300_FAMILY_ID)
+ return rtl930x_write_sds_phy(eth_priv->sds_id[addr],
+ page, regnum, val);
+ else
+ return rtl931x_write_sds_phy(eth_priv->sds_id[addr],
+ page, regnum, val);
+ }
+
+ err = (*bus_priv->write_phy)(addr, page, regnum, val);
+ pr_debug("wr_PHY(adr=%d, pag=%d, reg=%d, val=%d) err = %d\n",
+ addr, page, regnum, val, err);
+ }
+
+ bus_priv->raw[addr] = false;
+ return 0;
+}
+
+static int rtmdio_838x_reset(struct mii_bus *bus)
+{
+ pr_debug("%s called\n", __func__);
+ /* Disable MAC polling the PHY so that we can start configuration */
+ sw_w32(0x00000000, RTL838X_SMI_POLL_CTRL);
+
+ /* Enable PHY control via SoC */
+ sw_w32_mask(0, 1 << 15, RTL838X_SMI_GLB_CTRL);
+
+ /* Probably should reset all PHYs here... */
+ return 0;
+}
+
+static int rtmdio_839x_reset(struct mii_bus *bus)
+{
+ return 0;
+
+ pr_debug("%s called\n", __func__);
+ /* BUG: The following does not work, but should! */
+ /* Disable MAC polling the PHY so that we can start configuration */
+ sw_w32(0x00000000, RTL839X_SMI_PORT_POLLING_CTRL);
+ sw_w32(0x00000000, RTL839X_SMI_PORT_POLLING_CTRL + 4);
+ /* Disable PHY polling via SoC */
+ sw_w32_mask(1 << 7, 0, RTL839X_SMI_GLB_CTRL);
+
+ /* Probably should reset all PHYs here... */
+ return 0;
+}
+
+u8 mac_type_bit[RTL930X_CPU_PORT] = {0, 0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6,
+ 8, 8, 8, 8, 10, 10, 10, 10, 12, 15, 18, 21};
+
+static int rtmdio_930x_reset(struct mii_bus *bus)
+{
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+ struct rtl838x_eth_priv *priv = bus_priv->eth_priv;
+ u32 c45_mask = 0;
+ u32 poll_sel[2];
+ u32 poll_ctrl = 0;
+ u32 private_poll_mask = 0;
+ u32 v;
+ bool uses_usxgmii = false; /* For the Aquantia PHYs */
+ bool uses_hisgmii = false; /* For the RTL8221/8226 */
+
+ /* Mapping of port to phy-addresses on an SMI bus */
+ poll_sel[0] = poll_sel[1] = 0;
+ for (int i = 0; i < RTL930X_CPU_PORT; i++) {
+ int pos;
+
+ if (priv->smi_bus[i] > 3)
+ continue;
+ pos = (i % 6) * 5;
+ sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos,
+ RTL930X_SMI_PORT0_5_ADDR + (i / 6) * 4);
+
+ pos = (i * 2) % 32;
+ poll_sel[i / 16] |= priv->smi_bus[i] << pos;
+ poll_ctrl |= BIT(20 + priv->smi_bus[i]);
+ }
+
+ /* Configure which SMI bus is behind which port number */
+ sw_w32(poll_sel[0], RTL930X_SMI_PORT0_15_POLLING_SEL);
+ sw_w32(poll_sel[1], RTL930X_SMI_PORT16_27_POLLING_SEL);
+
+ /* Disable POLL_SEL for any SMI bus with a normal PHY (not RTL8295R for SFP+) */
+ sw_w32_mask(poll_ctrl, 0, RTL930X_SMI_GLB_CTRL);
+
+ /* Configure which SMI busses are polled in c45 based on a c45 PHY being on that bus */
+ for (int i = 0; i < 4; i++)
+ if (priv->smi_bus_isc45[i])
+ c45_mask |= BIT(i + 16);
+
+ pr_info("c45_mask: %08x\n", c45_mask);
+ sw_w32_mask(0, c45_mask, RTL930X_SMI_GLB_CTRL);
+
+ /* Set the MAC type of each port according to the PHY-interface */
+ /* Values are FE: 2, GE: 3, XGE/2.5G: 0(SERDES) or 1(otherwise), SXGE: 0 */
+ v = 0;
+ for (int i = 0; i < RTL930X_CPU_PORT; i++) {
+ switch (priv->interfaces[i]) {
+ case PHY_INTERFACE_MODE_10GBASER:
+ break; /* Serdes: Value = 0 */
+ case PHY_INTERFACE_MODE_HSGMII:
+ private_poll_mask |= BIT(i);
+ fallthrough;
+ case PHY_INTERFACE_MODE_USXGMII:
+ v |= BIT(mac_type_bit[i]);
+ uses_usxgmii = true;
+ break;
+ case PHY_INTERFACE_MODE_QSGMII:
+ private_poll_mask |= BIT(i);
+ v |= 3 << mac_type_bit[i];
+ break;
+ default:
+ break;
+ }
+ }
+ sw_w32(v, RTL930X_SMI_MAC_TYPE_CTRL);
+
+ /* Set the private polling mask for all Realtek PHYs (i.e. not the 10GBit Aquantia ones) */
+ sw_w32(private_poll_mask, RTL930X_SMI_PRVTE_POLLING_CTRL);
+
+ /* The following magic values are found in the port configuration, they seem to
+ * define different ways of polling a PHY. The below is for the Aquantia PHYs of
+ * the XGS1250 and the RTL8226 of the XGS1210
+ */
+ if (uses_usxgmii) {
+ sw_w32(0x01010000, RTL930X_SMI_10GPHY_POLLING_REG0_CFG);
+ sw_w32(0x01E7C400, RTL930X_SMI_10GPHY_POLLING_REG9_CFG);
+ sw_w32(0x01E7E820, RTL930X_SMI_10GPHY_POLLING_REG10_CFG);
+ }
+ if (uses_hisgmii) {
+ sw_w32(0x011FA400, RTL930X_SMI_10GPHY_POLLING_REG0_CFG);
+ sw_w32(0x013FA412, RTL930X_SMI_10GPHY_POLLING_REG9_CFG);
+ sw_w32(0x017FA414, RTL930X_SMI_10GPHY_POLLING_REG10_CFG);
+ }
+
+ pr_debug("%s: RTL930X_SMI_GLB_CTRL %08x\n", __func__,
+ sw_r32(RTL930X_SMI_GLB_CTRL));
+ pr_debug("%s: RTL930X_SMI_PORT0_15_POLLING_SEL %08x\n", __func__,
+ sw_r32(RTL930X_SMI_PORT0_15_POLLING_SEL));
+ pr_debug("%s: RTL930X_SMI_PORT16_27_POLLING_SEL %08x\n", __func__,
+ sw_r32(RTL930X_SMI_PORT16_27_POLLING_SEL));
+ pr_debug("%s: RTL930X_SMI_MAC_TYPE_CTRL %08x\n", __func__,
+ sw_r32(RTL930X_SMI_MAC_TYPE_CTRL));
+ pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG0_CFG %08x\n", __func__,
+ sw_r32(RTL930X_SMI_10GPHY_POLLING_REG0_CFG));
+ pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG9_CFG %08x\n", __func__,
+ sw_r32(RTL930X_SMI_10GPHY_POLLING_REG9_CFG));
+ pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG10_CFG %08x\n", __func__,
+ sw_r32(RTL930X_SMI_10GPHY_POLLING_REG10_CFG));
+ pr_debug("%s: RTL930X_SMI_PRVTE_POLLING_CTRL %08x\n", __func__,
+ sw_r32(RTL930X_SMI_PRVTE_POLLING_CTRL));
+
+ return 0;
+}
+
+static int rtmdio_931x_reset(struct mii_bus *bus)
+{
+ struct rtl838x_bus_priv *bus_priv = bus->priv;
+ struct rtl838x_eth_priv *priv = bus_priv->eth_priv;
+ u32 c45_mask = 0;
+ u32 poll_sel[4];
+ u32 poll_ctrl = 0;
+ bool mdc_on[4];
+
+ pr_info("%s called\n", __func__);
+ /* Disable port polling for configuration purposes */
+ sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL);
+ sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL + 4);
+ msleep(100);
+
+ mdc_on[0] = mdc_on[1] = mdc_on[2] = mdc_on[3] = false;
+ /* Mapping of port to phy-addresses on an SMI bus */
+ poll_sel[0] = poll_sel[1] = poll_sel[2] = poll_sel[3] = 0;
+ for (int i = 0; i < 56; i++) {
+ u32 pos;
+
+ pos = (i % 6) * 5;
+ sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos, RTL931X_SMI_PORT_ADDR + (i / 6) * 4);
+ pos = (i * 2) % 32;
+ poll_sel[i / 16] |= priv->smi_bus[i] << pos;
+ poll_ctrl |= BIT(20 + priv->smi_bus[i]);
+ mdc_on[priv->smi_bus[i]] = true;
+ }
+
+ /* Configure which SMI bus is behind which port number */
+ for (int i = 0; i < 4; i++) {
+ pr_info("poll sel %d, %08x\n", i, poll_sel[i]);
+ sw_w32(poll_sel[i], RTL931X_SMI_PORT_POLLING_SEL + (i * 4));
+ }
+
+ /* Configure which SMI busses */
+ pr_info("%s: WAS RTL931X_MAC_L2_GLOBAL_CTRL2 %08x\n", __func__, sw_r32(RTL931X_MAC_L2_GLOBAL_CTRL2));
+ pr_info("c45_mask: %08x, RTL931X_SMI_GLB_CTRL0 was %X", c45_mask, sw_r32(RTL931X_SMI_GLB_CTRL0));
+ for (int i = 0; i < 4; i++) {
+ /* bus is polled in c45 */
+ if (priv->smi_bus_isc45[i])
+ c45_mask |= 0x2 << (i * 2); /* Std. C45, non-standard is 0x3 */
+ /* Enable bus access via MDC */
+ if (mdc_on[i])
+ sw_w32_mask(0, BIT(9 + i), RTL931X_MAC_L2_GLOBAL_CTRL2);
+ }
+
+ pr_info("%s: RTL931X_MAC_L2_GLOBAL_CTRL2 %08x\n", __func__, sw_r32(RTL931X_MAC_L2_GLOBAL_CTRL2));
+ pr_info("c45_mask: %08x, RTL931X_SMI_GLB_CTRL0 was %X", c45_mask, sw_r32(RTL931X_SMI_GLB_CTRL0));
+
+ /* We have a 10G PHY enable polling
+ * sw_w32(0x01010000, RTL931X_SMI_10GPHY_POLLING_SEL2);
+ * sw_w32(0x01E7C400, RTL931X_SMI_10GPHY_POLLING_SEL3);
+ * sw_w32(0x01E7E820, RTL931X_SMI_10GPHY_POLLING_SEL4);
+ */
+ sw_w32_mask(0xff, c45_mask, RTL931X_SMI_GLB_CTRL1);
+
+ return 0;
+}
+
+static int rtl931x_chip_init(struct rtl838x_eth_priv *priv)
+{
+ pr_info("In %s\n", __func__);
+
+ /* Initialize Encapsulation memory and wait until finished */
+ sw_w32(0x1, RTL931X_MEM_ENCAP_INIT);
+ do { } while (sw_r32(RTL931X_MEM_ENCAP_INIT) & 1);
+ pr_info("%s: init ENCAP done\n", __func__);
+
+ /* Initialize Managemen Information Base memory and wait until finished */
+ sw_w32(0x1, RTL931X_MEM_MIB_INIT);
+ do { } while (sw_r32(RTL931X_MEM_MIB_INIT) & 1);
+ pr_info("%s: init MIB done\n", __func__);
+
+ /* Initialize ACL (PIE) memory and wait until finished */
+ sw_w32(0x1, RTL931X_MEM_ACL_INIT);
+ do { } while (sw_r32(RTL931X_MEM_ACL_INIT) & 1);
+ pr_info("%s: init ACL done\n", __func__);
+
+ /* Initialize ALE memory and wait until finished */
+ sw_w32(0xFFFFFFFF, RTL931X_MEM_ALE_INIT_0);
+ do { } while (sw_r32(RTL931X_MEM_ALE_INIT_0));
+ sw_w32(0x7F, RTL931X_MEM_ALE_INIT_1);
+ sw_w32(0x7ff, RTL931X_MEM_ALE_INIT_2);
+ do { } while (sw_r32(RTL931X_MEM_ALE_INIT_2) & 0x7ff);
+ pr_info("%s: init ALE done\n", __func__);
+
+ /* Enable ESD auto recovery */
+ sw_w32(0x1, RTL931X_MDX_CTRL_RSVD);
+
+ /* Init SPI, is this for thermal control or what? */
+ sw_w32_mask(0x7 << 11, 0x2 << 11, RTL931X_SPI_CTRL0);
+
+ return 0;
+}
+
+static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
+{
+ struct device_node *mii_np, *dn;
+ struct rtl838x_bus_priv *bus_priv;
+ u32 pn;
+ int i, ret;
+
+ pr_debug("%s called\n", __func__);
+ mii_np = of_get_child_by_name(priv->pdev->dev.of_node, "mdio-bus");
+
+ if (!mii_np) {
+ dev_err(&priv->pdev->dev, "no %s child node found", "mdio-bus");
+ return -ENODEV;
+ }
+
+ if (!of_device_is_available(mii_np)) {
+ ret = -ENODEV;
+ goto err_put_node;
+ }
+
+ priv->mii_bus = devm_mdiobus_alloc_size(&priv->pdev->dev, sizeof(*bus_priv));
+ if (!priv->mii_bus) {
+ ret = -ENOMEM;
+ goto err_put_node;
+ }
+
+ bus_priv = priv->mii_bus->priv;
+ bus_priv->eth_priv = priv;
+ for (i=0; i < 64; i++) {
+ bus_priv->page[i] = 0;
+ bus_priv->raw[i] = false;
+ }
+ bus_priv->extaddr = -1;
+
+ switch(priv->family_id) {
+ case RTL8380_FAMILY_ID:
+ priv->mii_bus->name = "rtl838x-eth-mdio";
+ priv->mii_bus->read = rtmdio_83xx_read;
+ priv->mii_bus->write = rtmdio_83xx_write;
+ priv->mii_bus->reset = rtmdio_838x_reset;
+ bus_priv->read_mmd_phy = rtl838x_read_mmd_phy;
+ bus_priv->write_mmd_phy = rtl838x_write_mmd_phy;
+ bus_priv->read_phy = rtl838x_read_phy;
+ bus_priv->write_phy = rtl838x_write_phy;
+ bus_priv->rawpage = 0xfff;
+ break;
+ case RTL8390_FAMILY_ID:
+ priv->mii_bus->name = "rtl839x-eth-mdio";
+ priv->mii_bus->read = rtmdio_83xx_read;
+ priv->mii_bus->write = rtmdio_83xx_write;
+ priv->mii_bus->reset = rtmdio_839x_reset;
+ bus_priv->read_mmd_phy = rtl839x_read_mmd_phy;
+ bus_priv->write_mmd_phy = rtl839x_write_mmd_phy;
+ bus_priv->read_phy = rtl839x_read_phy;
+ bus_priv->write_phy = rtl839x_write_phy;
+ bus_priv->rawpage = 0x1fff;
+ break;
+ case RTL9300_FAMILY_ID:
+ priv->mii_bus->name = "rtl930x-eth-mdio";
+ priv->mii_bus->read = rtmdio_93xx_read;
+ priv->mii_bus->write = rtmdio_93xx_write;
+ priv->mii_bus->reset = rtmdio_930x_reset;
+ bus_priv->read_mmd_phy = rtl930x_read_mmd_phy;
+ bus_priv->write_mmd_phy = rtl930x_write_mmd_phy;
+ bus_priv->read_phy = rtl930x_read_phy;
+ bus_priv->write_phy = rtl930x_write_phy;
+ bus_priv->rawpage = 0xfff;
+ break;
+ case RTL9310_FAMILY_ID:
+ priv->mii_bus->name = "rtl931x-eth-mdio";
+ priv->mii_bus->read = rtmdio_93xx_read;
+ priv->mii_bus->write = rtmdio_93xx_write;
+ priv->mii_bus->reset = rtmdio_931x_reset;
+ bus_priv->read_mmd_phy = rtl931x_read_mmd_phy;
+ bus_priv->write_mmd_phy = rtl931x_write_mmd_phy;
+ bus_priv->read_phy = rtl931x_read_phy;
+ bus_priv->write_phy = rtl931x_write_phy;
+ bus_priv->rawpage = 0x1fff;
+ break;
+ }
+ priv->mii_bus->read_c45 = rtmdio_read_c45;
+ priv->mii_bus->write_c45 = rtmdio_write_c45;
+ priv->mii_bus->parent = &priv->pdev->dev;
+
+ for_each_node_by_name(dn, "ethernet-phy") {
+ u32 smi_addr[2];
+
+ if (of_property_read_u32(dn, "reg", &pn))
+ continue;
+
+ if (of_property_read_u32_array(dn, "rtl9300,smi-address", &smi_addr[0], 2)) {
+ smi_addr[0] = 0;
+ smi_addr[1] = pn;
+ }
+
+ if (of_property_read_u32(dn, "sds", &priv->sds_id[pn]))
+ priv->sds_id[pn] = -1;
+ else {
+ pr_info("set sds port %d to %d\n", pn, priv->sds_id[pn]);
+ }
+
+ if (pn < MAX_PORTS) {
+ priv->smi_bus[pn] = smi_addr[0];
+ priv->smi_addr[pn] = smi_addr[1];
+ } else {
+ pr_err("%s: illegal port number %d\n", __func__, pn);
+ }
+
+ if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45"))
+ priv->smi_bus_isc45[smi_addr[0]] = true;
+
+ if (of_property_read_bool(dn, "phy-is-integrated")) {
+ priv->phy_is_internal[pn] = true;
+ }
+ }
+
+ dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch");
+ if (!dn) {
+ dev_err(&priv->pdev->dev, "No RTL switch node in DTS\n");
+ return -ENODEV;
+ }
+
+ for_each_node_by_name(dn, "port") {
+ if (of_property_read_u32(dn, "reg", &pn))
+ continue;
+ pr_debug("%s Looking at port %d\n", __func__, pn);
+ if (pn > priv->cpu_port)
+ continue;
+ if (of_get_phy_mode(dn, &priv->interfaces[pn]))
+ priv->interfaces[pn] = PHY_INTERFACE_MODE_NA;
+ pr_debug("%s phy mode of port %d is %s\n", __func__, pn, phy_modes(priv->interfaces[pn]));
+ }
+
+ snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
+ ret = of_mdiobus_register(priv->mii_bus, mii_np);
+
+err_put_node:
+ of_node_put(mii_np);
+
+ return ret;
+}
+
+static int rtl838x_mdio_remove(struct rtl838x_eth_priv *priv)
+{
+ pr_debug("%s called\n", __func__);
+ if (!priv->mii_bus)
+ return 0;
+
+ mdiobus_unregister(priv->mii_bus);
+ mdiobus_free(priv->mii_bus);
+
+ return 0;
+}
+
+static netdev_features_t rtl838x_fix_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ return features;
+}
+
+static int rtl83xx_set_features(struct net_device *dev, netdev_features_t features)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+
+ if ((features ^ dev->features) & NETIF_F_RXCSUM) {
+ if (!(features & NETIF_F_RXCSUM))
+ sw_w32_mask(BIT(3), 0, priv->r->mac_port_ctrl(priv->cpu_port));
+ else
+ sw_w32_mask(0, BIT(3), priv->r->mac_port_ctrl(priv->cpu_port));
+ }
+
+ return 0;
+}
+
+static int rtl93xx_set_features(struct net_device *dev, netdev_features_t features)
+{
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+
+ if ((features ^ dev->features) & NETIF_F_RXCSUM) {
+ if (!(features & NETIF_F_RXCSUM))
+ sw_w32_mask(BIT(4), 0, priv->r->mac_port_ctrl(priv->cpu_port));
+ else
+ sw_w32_mask(0, BIT(4), priv->r->mac_port_ctrl(priv->cpu_port));
+ }
+
+ return 0;
+}
+
+static struct phylink_pcs *rtl838x_mac_select_pcs(struct phylink_config *config,
+ phy_interface_t interface)
+{
+ struct net_device *dev = to_net_dev(config->dev);
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+
+ return &priv->pcs;
+}
+
+static const struct net_device_ops rtl838x_eth_netdev_ops = {
+ .ndo_open = rtl838x_eth_open,
+ .ndo_stop = rtl838x_eth_stop,
+ .ndo_start_xmit = rtl838x_eth_tx,
+ .ndo_select_queue = rtl83xx_pick_tx_queue,
+ .ndo_set_mac_address = rtl838x_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_rx_mode = rtl838x_eth_set_multicast_list,
+ .ndo_tx_timeout = rtl838x_eth_tx_timeout,
+ .ndo_set_features = rtl83xx_set_features,
+ .ndo_fix_features = rtl838x_fix_features,
+ .ndo_setup_tc = rtl83xx_setup_tc,
+};
+
+static const struct net_device_ops rtl839x_eth_netdev_ops = {
+ .ndo_open = rtl838x_eth_open,
+ .ndo_stop = rtl838x_eth_stop,
+ .ndo_start_xmit = rtl838x_eth_tx,
+ .ndo_select_queue = rtl83xx_pick_tx_queue,
+ .ndo_set_mac_address = rtl838x_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_rx_mode = rtl839x_eth_set_multicast_list,
+ .ndo_tx_timeout = rtl838x_eth_tx_timeout,
+ .ndo_set_features = rtl83xx_set_features,
+ .ndo_fix_features = rtl838x_fix_features,
+ .ndo_setup_tc = rtl83xx_setup_tc,
+};
+
+static const struct net_device_ops rtl930x_eth_netdev_ops = {
+ .ndo_open = rtl838x_eth_open,
+ .ndo_stop = rtl838x_eth_stop,
+ .ndo_start_xmit = rtl838x_eth_tx,
+ .ndo_select_queue = rtl93xx_pick_tx_queue,
+ .ndo_set_mac_address = rtl838x_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_rx_mode = rtl930x_eth_set_multicast_list,
+ .ndo_tx_timeout = rtl838x_eth_tx_timeout,
+ .ndo_set_features = rtl93xx_set_features,
+ .ndo_fix_features = rtl838x_fix_features,
+ .ndo_setup_tc = rtl83xx_setup_tc,
+};
+
+static const struct net_device_ops rtl931x_eth_netdev_ops = {
+ .ndo_open = rtl838x_eth_open,
+ .ndo_stop = rtl838x_eth_stop,
+ .ndo_start_xmit = rtl838x_eth_tx,
+ .ndo_select_queue = rtl93xx_pick_tx_queue,
+ .ndo_set_mac_address = rtl838x_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_rx_mode = rtl931x_eth_set_multicast_list,
+ .ndo_tx_timeout = rtl838x_eth_tx_timeout,
+ .ndo_set_features = rtl93xx_set_features,
+ .ndo_fix_features = rtl838x_fix_features,
+};
+
+static const struct phylink_pcs_ops rtl838x_pcs_ops = {
+ .pcs_get_state = rtl838x_pcs_get_state,
+ .pcs_an_restart = rtl838x_pcs_an_restart,
+ .pcs_config = rtl838x_pcs_config,
+};
+
+static const struct phylink_mac_ops rtl838x_phylink_ops = {
+ .validate = rtl838x_validate,
+ .mac_select_pcs = rtl838x_mac_select_pcs,
+ .mac_config = rtl838x_mac_config,
+ .mac_link_down = rtl838x_mac_link_down,
+ .mac_link_up = rtl838x_mac_link_up,
+};
+
+static const struct ethtool_ops rtl838x_ethtool_ops = {
+ .get_link_ksettings = rtl838x_get_link_ksettings,
+ .set_link_ksettings = rtl838x_set_link_ksettings,
+};
+
+static int __init rtl838x_eth_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct device_node *dn = pdev->dev.of_node;
+ struct rtl838x_eth_priv *priv;
+ struct resource *res, *mem;
+ phy_interface_t phy_mode;
+ struct phylink *phylink;
+ u8 mac_addr[ETH_ALEN];
+ int err = 0, rxrings, rxringlen;
+ struct ring_b *ring;
+
+ pr_info("Probing RTL838X eth device pdev: %x, dev: %x\n",
+ (u32)pdev, (u32)(&(pdev->dev)));
+
+ if (!dn) {
+ dev_err(&pdev->dev, "No DT found\n");
+ return -EINVAL;
+ }
+
+ rxrings = (soc_info.family == RTL8380_FAMILY_ID
+ || soc_info.family == RTL8390_FAMILY_ID) ? 8 : 32;
+ rxrings = rxrings > MAX_RXRINGS ? MAX_RXRINGS : rxrings;
+ rxringlen = MAX_ENTRIES / rxrings;
+ rxringlen = rxringlen > MAX_RXLEN ? MAX_RXLEN : rxringlen;
+
+ dev = alloc_etherdev_mqs(sizeof(struct rtl838x_eth_priv), TXRINGS, rxrings);
+ if (!dev) {
+ err = -ENOMEM;
+ goto err_free;
+ }
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ priv = netdev_priv(dev);
+
+ /* obtain buffer memory space */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res) {
+ mem = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), res->name);
+ if (!mem) {
+ dev_err(&pdev->dev, "cannot request memory space\n");
+ err = -ENXIO;
+ goto err_free;
+ }
+
+ dev->mem_start = mem->start;
+ dev->mem_end = mem->end;
+ } else {
+ dev_err(&pdev->dev, "cannot request IO resource\n");
+ err = -ENXIO;
+ goto err_free;
+ }
+
+ /* Allocate buffer memory */
+ priv->membase = dmam_alloc_coherent(&pdev->dev, rxrings * rxringlen * RING_BUFFER +
+ sizeof(struct ring_b) + sizeof(struct notify_b),
+ (void *)&dev->mem_start, GFP_KERNEL);
+ if (!priv->membase) {
+ dev_err(&pdev->dev, "cannot allocate DMA buffer\n");
+ err = -ENOMEM;
+ goto err_free;
+ }
+
+ /* Allocate ring-buffer space at the end of the allocated memory */
+ ring = priv->membase;
+ ring->rx_space = priv->membase + sizeof(struct ring_b) + sizeof(struct notify_b);
+
+ spin_lock_init(&priv->lock);
+
+ dev->ethtool_ops = &rtl838x_ethtool_ops;
+ dev->min_mtu = ETH_ZLEN;
+ dev->max_mtu = DEFAULT_MTU;
+ dev->features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM;
+ dev->hw_features = NETIF_F_RXCSUM;
+
+ priv->id = soc_info.id;
+ priv->family_id = soc_info.family;
+ if (priv->id) {
+ pr_info("Found SoC ID: %4x: %s, family %x\n",
+ priv->id, soc_info.name, priv->family_id);
+ } else {
+ pr_err("Unknown chip id (%04x)\n", priv->id);
+ return -ENODEV;
+ }
+
+ switch (priv->family_id) {
+ case RTL8380_FAMILY_ID:
+ priv->cpu_port = RTL838X_CPU_PORT;
+ priv->r = &rtl838x_reg;
+ dev->netdev_ops = &rtl838x_eth_netdev_ops;
+ break;
+ case RTL8390_FAMILY_ID:
+ priv->cpu_port = RTL839X_CPU_PORT;
+ priv->r = &rtl839x_reg;
+ dev->netdev_ops = &rtl839x_eth_netdev_ops;
+ break;
+ case RTL9300_FAMILY_ID:
+ priv->cpu_port = RTL930X_CPU_PORT;
+ priv->r = &rtl930x_reg;
+ dev->netdev_ops = &rtl930x_eth_netdev_ops;
+ break;
+ case RTL9310_FAMILY_ID:
+ priv->cpu_port = RTL931X_CPU_PORT;
+ priv->r = &rtl931x_reg;
+ dev->netdev_ops = &rtl931x_eth_netdev_ops;
+ rtl931x_chip_init(priv);
+ break;
+ default:
+ pr_err("Unknown SoC family\n");
+ return -ENODEV;
+ }
+ priv->rxringlen = rxringlen;
+ priv->rxrings = rxrings;
+
+ /* Obtain device IRQ number */
+ dev->irq = platform_get_irq(pdev, 0);
+ if (dev->irq < 0) {
+ dev_err(&pdev->dev, "cannot obtain network-device IRQ\n");
+ goto err_free;
+ }
+
+ err = devm_request_irq(&pdev->dev, dev->irq, priv->r->net_irq,
+ IRQF_SHARED, dev->name, dev);
+ if (err) {
+ dev_err(&pdev->dev, "%s: could not acquire interrupt: %d\n",
+ __func__, err);
+ goto err_free;
+ }
+
+ rtl8380_init_mac(priv);
+
+ /* Try to get mac address in the following order:
+ * 1) from device tree data
+ * 2) from internal registers set by bootloader
+ */
+ of_get_mac_address(pdev->dev.of_node, mac_addr);
+ if (is_valid_ether_addr(mac_addr)) {
+ rtl838x_set_mac_hw(dev, mac_addr);
+ } else {
+ mac_addr[0] = (sw_r32(priv->r->mac) >> 8) & 0xff;
+ mac_addr[1] = sw_r32(priv->r->mac) & 0xff;
+ mac_addr[2] = (sw_r32(priv->r->mac + 4) >> 24) & 0xff;
+ mac_addr[3] = (sw_r32(priv->r->mac + 4) >> 16) & 0xff;
+ mac_addr[4] = (sw_r32(priv->r->mac + 4) >> 8) & 0xff;
+ mac_addr[5] = sw_r32(priv->r->mac + 4) & 0xff;
+ }
+ dev_addr_set(dev, mac_addr);
+ /* if the address is invalid, use a random value */
+ if (!is_valid_ether_addr(dev->dev_addr)) {
+ struct sockaddr sa = { AF_UNSPEC };
+
+ netdev_warn(dev, "Invalid MAC address, using random\n");
+ eth_hw_addr_random(dev);
+ memcpy(sa.sa_data, dev->dev_addr, ETH_ALEN);
+ if (rtl838x_set_mac_address(dev, &sa))
+ netdev_warn(dev, "Failed to set MAC address.\n");
+ }
+ pr_info("Using MAC %08x%08x\n", sw_r32(priv->r->mac),
+ sw_r32(priv->r->mac + 4));
+ strcpy(dev->name, "eth%d");
+ priv->pdev = pdev;
+ priv->netdev = dev;
+
+ err = rtl838x_mdio_init(priv);
+ if (err)
+ goto err_free;
+
+ err = register_netdev(dev);
+ if (err)
+ goto err_free;
+
+ for (int i = 0; i < priv->rxrings; i++) {
+ priv->rx_qs[i].id = i;
+ priv->rx_qs[i].priv = priv;
+ netif_napi_add(dev, &priv->rx_qs[i].napi, rtl838x_poll_rx);
+ }
+
+ platform_set_drvdata(pdev, dev);
+
+ phy_mode = PHY_INTERFACE_MODE_NA;
+ err = of_get_phy_mode(dn, &phy_mode);
+ if (err < 0) {
+ dev_err(&pdev->dev, "incorrect phy-mode\n");
+ err = -EINVAL;
+ goto err_free;
+ }
+
+ priv->pcs.ops = &rtl838x_pcs_ops;
+ priv->phylink_config.dev = &dev->dev;
+ priv->phylink_config.type = PHYLINK_NETDEV;
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, priv->phylink_config.supported_interfaces);
+
+ phylink = phylink_create(&priv->phylink_config, pdev->dev.fwnode,
+ phy_mode, &rtl838x_phylink_ops);
+
+ if (IS_ERR(phylink)) {
+ err = PTR_ERR(phylink);
+ goto err_free;
+ }
+ priv->phylink = phylink;
+
+ return 0;
+
+err_free:
+ pr_err("Error setting up netdev, freeing it again.\n");
+ free_netdev(dev);
+
+ return err;
+}
+
+static int rtl838x_eth_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct rtl838x_eth_priv *priv = netdev_priv(dev);
+
+ if (dev) {
+ pr_info("Removing platform driver for rtl838x-eth\n");
+ rtl838x_mdio_remove(priv);
+ rtl838x_hw_stop(priv);
+
+ netif_tx_stop_all_queues(dev);
+
+ for (int i = 0; i < priv->rxrings; i++)
+ netif_napi_del(&priv->rx_qs[i].napi);
+
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id rtl838x_eth_of_ids[] = {
+ { .compatible = "realtek,rtl838x-eth"},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rtl838x_eth_of_ids);
+
+static struct platform_driver rtl838x_eth_driver = {
+ .probe = rtl838x_eth_probe,
+ .remove = rtl838x_eth_remove,
+ .driver = {
+ .name = "rtl838x-eth",
+ .pm = NULL,
+ .of_match_table = rtl838x_eth_of_ids,
+ },
+};
+
+module_platform_driver(rtl838x_eth_driver);
+
+MODULE_AUTHOR("B. Koblitz");
+MODULE_DESCRIPTION("RTL838X SoC Ethernet Driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h
new file mode 100644
index 0000000000..d6d88fc2ed
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h
@@ -0,0 +1,470 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _RTL838X_ETH_H
+#define _RTL838X_ETH_H
+
+/* Register definition */
+
+/* Per port MAC control */
+#define RTL838X_MAC_PORT_CTRL (0xd560)
+#define RTL839X_MAC_PORT_CTRL (0x8004)
+#define RTL930X_MAC_L2_PORT_CTRL (0x3268)
+#define RTL930X_MAC_PORT_CTRL (0x3260)
+#define RTL931X_MAC_L2_PORT_CTRL (0x6000)
+#define RTL931X_MAC_PORT_CTRL (0x6004)
+
+/* DMA interrupt control and status registers */
+#define RTL838X_DMA_IF_CTRL (0x9f58)
+#define RTL838X_DMA_IF_INTR_STS (0x9f54)
+#define RTL838X_DMA_IF_INTR_MSK (0x9f50)
+
+#define RTL839X_DMA_IF_CTRL (0x786c)
+#define RTL839X_DMA_IF_INTR_STS (0x7868)
+#define RTL839X_DMA_IF_INTR_MSK (0x7864)
+
+#define RTL930X_DMA_IF_CTRL (0xe028)
+#define RTL930X_DMA_IF_INTR_RX_RUNOUT_STS (0xe01C)
+#define RTL930X_DMA_IF_INTR_RX_DONE_STS (0xe020)
+#define RTL930X_DMA_IF_INTR_TX_DONE_STS (0xe024)
+#define RTL930X_DMA_IF_INTR_RX_RUNOUT_MSK (0xe010)
+#define RTL930X_DMA_IF_INTR_RX_DONE_MSK (0xe014)
+#define RTL930X_DMA_IF_INTR_TX_DONE_MSK (0xe018)
+#define RTL930X_L2_NTFY_IF_INTR_MSK (0xe04C)
+#define RTL930X_L2_NTFY_IF_INTR_STS (0xe050)
+
+/* TODO: RTL931X_DMA_IF_CTRL has different bits meanings */
+#define RTL931X_DMA_IF_CTRL (0x0928)
+#define RTL931X_DMA_IF_INTR_RX_RUNOUT_STS (0x091c)
+#define RTL931X_DMA_IF_INTR_RX_DONE_STS (0x0920)
+#define RTL931X_DMA_IF_INTR_TX_DONE_STS (0x0924)
+#define RTL931X_DMA_IF_INTR_RX_RUNOUT_MSK (0x0910)
+#define RTL931X_DMA_IF_INTR_RX_DONE_MSK (0x0914)
+#define RTL931X_DMA_IF_INTR_TX_DONE_MSK (0x0918)
+#define RTL931X_L2_NTFY_IF_INTR_MSK (0x09E4)
+#define RTL931X_L2_NTFY_IF_INTR_STS (0x09E8)
+
+#define RTL838X_MAC_FORCE_MODE_CTRL (0xa104)
+#define RTL839X_MAC_FORCE_MODE_CTRL (0x02bc)
+#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C)
+#define RTL931X_MAC_FORCE_MODE_CTRL (0x0ddc)
+
+/* MAC address settings */
+#define RTL838X_MAC (0xa9ec)
+#define RTL839X_MAC (0x02b4)
+#define RTL838X_MAC_ALE (0x6b04)
+#define RTL838X_MAC2 (0xa320)
+#define RTL930X_MAC_L2_ADDR_CTRL (0xC714)
+#define RTL931X_MAC_L2_ADDR_CTRL (0x135c)
+
+/* Ringbuffer setup */
+#define RTL838X_DMA_RX_BASE (0x9f00)
+#define RTL839X_DMA_RX_BASE (0x780c)
+#define RTL930X_DMA_RX_BASE (0xdf00)
+#define RTL931X_DMA_RX_BASE (0x0800)
+
+#define RTL838X_DMA_TX_BASE (0x9f40)
+#define RTL839X_DMA_TX_BASE (0x784c)
+#define RTL930X_DMA_TX_BASE (0xe000)
+#define RTL931X_DMA_TX_BASE (0x0900)
+
+#define RTL838X_DMA_IF_RX_RING_SIZE (0xB7E4)
+#define RTL839X_DMA_IF_RX_RING_SIZE (0x6038)
+#define RTL930X_DMA_IF_RX_RING_SIZE (0x7C60)
+#define RTL931X_DMA_IF_RX_RING_SIZE (0x2080)
+
+#define RTL838X_DMA_IF_RX_RING_CNTR (0xB7E8)
+#define RTL839X_DMA_IF_RX_RING_CNTR (0x603c)
+#define RTL930X_DMA_IF_RX_RING_CNTR (0x7C8C)
+#define RTL931X_DMA_IF_RX_RING_CNTR (0x20AC)
+
+#define RTL838X_DMA_IF_RX_CUR (0x9F20)
+#define RTL839X_DMA_IF_RX_CUR (0x782c)
+#define RTL930X_DMA_IF_RX_CUR (0xdf80)
+#define RTL931X_DMA_IF_RX_CUR (0x0880)
+
+#define RTL838X_DMA_IF_TX_CUR_DESC_ADDR_CTRL (0x9F48)
+#define RTL930X_DMA_IF_TX_CUR_DESC_ADDR_CTRL (0xE008)
+
+#define RTL838X_DMY_REG31 (0x3b28)
+#define RTL838X_SDS_MODE_SEL (0x0028)
+#define RTL838X_SDS_CFG_REG (0x0034)
+#define RTL838X_INT_MODE_CTRL (0x005c)
+#define RTL838X_CHIP_INFO (0x00d8)
+#define RTL838X_SDS4_REG28 (0xef80)
+#define RTL838X_SDS4_DUMMY0 (0xef8c)
+#define RTL838X_SDS5_EXT_REG6 (0xf18c)
+
+/* L2 features */
+#define RTL839X_TBL_ACCESS_L2_CTRL (0x1180)
+#define RTL839X_TBL_ACCESS_L2_DATA(idx) (0x1184 + ((idx) << 2))
+#define RTL838X_TBL_ACCESS_CTRL_0 (0x6914)
+#define RTL838X_TBL_ACCESS_DATA_0(idx) (0x6918 + ((idx) << 2))
+
+/* MAC-side link state handling */
+#define RTL838X_MAC_LINK_STS (0xa188)
+#define RTL839X_MAC_LINK_STS (0x0390)
+#define RTL930X_MAC_LINK_STS (0xCB10)
+#define RTL931X_MAC_LINK_STS (0x0ec0)
+
+#define RTL838X_MAC_LINK_SPD_STS (0xa190)
+#define RTL839X_MAC_LINK_SPD_STS (0x03a0)
+#define RTL930X_MAC_LINK_SPD_STS (0xCB18)
+#define RTL931X_MAC_LINK_SPD_STS (0x0ed0)
+
+#define RTL838X_MAC_LINK_DUP_STS (0xa19c)
+#define RTL839X_MAC_LINK_DUP_STS (0x03b0)
+#define RTL930X_MAC_LINK_DUP_STS (0xCB28)
+#define RTL931X_MAC_LINK_DUP_STS (0x0ef0)
+
+/* TODO: RTL8390_MAC_LINK_MEDIA_STS_ADDR??? */
+
+#define RTL838X_MAC_TX_PAUSE_STS (0xa1a0)
+#define RTL839X_MAC_TX_PAUSE_STS (0x03b8)
+#define RTL930X_MAC_TX_PAUSE_STS (0xCB2C)
+#define RTL931X_MAC_TX_PAUSE_STS (0x0ef8)
+
+#define RTL838X_MAC_RX_PAUSE_STS (0xa1a4)
+#define RTL839X_MAC_RX_PAUSE_STS (0xCB30)
+#define RTL930X_MAC_RX_PAUSE_STS (0xC2F8)
+#define RTL931X_MAC_RX_PAUSE_STS (0x0f00)
+
+#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04)
+#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08)
+
+#define RTL930X_L2_UNKN_UC_FLD_PMSK (0x9064)
+#define RTL931X_L2_UNKN_UC_FLD_PMSK (0xC8F4)
+
+#define RTL839X_MAC_GLB_CTRL (0x02a8)
+#define RTL839X_SCHED_LB_TICK_TKN_CTRL (0x60f8)
+
+#define RTL838X_L2_TBL_FLUSH_CTRL (0x3370)
+#define RTL839X_L2_TBL_FLUSH_CTRL (0x3ba0)
+#define RTL930X_L2_TBL_FLUSH_CTRL (0x9404)
+#define RTL931X_L2_TBL_FLUSH_CTRL (0xCD9C)
+
+#define RTL930X_L2_PORT_SABLK_CTRL (0x905c)
+#define RTL930X_L2_PORT_DABLK_CTRL (0x9060)
+
+/* MAC link state bits */
+#define FORCE_EN (1 << 0)
+#define FORCE_LINK_EN (1 << 1)
+#define NWAY_EN (1 << 2)
+#define DUPLX_MODE (1 << 3)
+#define TX_PAUSE_EN (1 << 6)
+#define RX_PAUSE_EN (1 << 7)
+
+/* L2 Notification DMA interface */
+#define RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL (0x785C)
+#define RTL839X_L2_NOTIFICATION_CTRL (0x7808)
+#define RTL931X_L2_NTFY_RING_BASE_ADDR (0x09DC)
+#define RTL931X_L2_NTFY_RING_CUR_ADDR (0x09E0)
+#define RTL839X_L2_NOTIFICATION_CTRL (0x7808)
+#define RTL931X_L2_NTFY_CTRL (0xCDC8)
+#define RTL838X_L2_CTRL_0 (0x3200)
+#define RTL839X_L2_CTRL_0 (0x3800)
+#define RTL930X_L2_CTRL (0x8FD8)
+#define RTL931X_L2_CTRL (0xC800)
+
+/* TRAPPING to CPU-PORT */
+#define RTL838X_SPCL_TRAP_IGMP_CTRL (0x6984)
+#define RTL838X_RMA_CTRL_0 (0x4300)
+#define RTL838X_RMA_CTRL_1 (0x4304)
+#define RTL839X_RMA_CTRL_0 (0x1200)
+
+#define RTL839X_SPCL_TRAP_IGMP_CTRL (0x1058)
+#define RTL839X_RMA_CTRL_1 (0x1204)
+#define RTL839X_RMA_CTRL_2 (0x1208)
+#define RTL839X_RMA_CTRL_3 (0x120C)
+
+#define RTL930X_VLAN_APP_PKT_CTRL (0xA23C)
+#define RTL930X_RMA_CTRL_0 (0x9E60)
+#define RTL930X_RMA_CTRL_1 (0x9E64)
+#define RTL930X_RMA_CTRL_2 (0x9E68)
+
+#define RTL931X_VLAN_APP_PKT_CTRL (0x96b0)
+#define RTL931X_RMA_CTRL_0 (0x8800)
+#define RTL931X_RMA_CTRL_1 (0x8804)
+#define RTL931X_RMA_CTRL_2 (0x8808)
+
+/* Advanced SMI control for clause 45 PHYs */
+#define RTL930X_SMI_MAC_TYPE_CTRL (0xCA04)
+#define RTL930X_SMI_PORT24_27_ADDR_CTRL (0xCB90)
+#define RTL930X_SMI_PORT0_15_POLLING_SEL (0xCA08)
+#define RTL930X_SMI_PORT16_27_POLLING_SEL (0xCA0C)
+
+#define RTL930X_SMI_10GPHY_POLLING_REG0_CFG (0xCBB4)
+#define RTL930X_SMI_10GPHY_POLLING_REG9_CFG (0xCBB8)
+#define RTL930X_SMI_10GPHY_POLLING_REG10_CFG (0xCBBC)
+#define RTL930X_SMI_PRVTE_POLLING_CTRL (0xCA10)
+
+/* Registers of the internal Serdes of the 8390 */
+#define RTL839X_SDS12_13_XSG0 (0xB800)
+
+/* Chip configuration registers of the RTL9310 */
+#define RTL931X_MEM_ENCAP_INIT (0x4854)
+#define RTL931X_MEM_MIB_INIT (0x7E18)
+#define RTL931X_MEM_ACL_INIT (0x40BC)
+#define RTL931X_MEM_ALE_INIT_0 (0x83F0)
+#define RTL931X_MEM_ALE_INIT_1 (0x83F4)
+#define RTL931X_MEM_ALE_INIT_2 (0x82E4)
+#define RTL931X_MDX_CTRL_RSVD (0x0fcc)
+#define RTL931X_PS_SOC_CTRL (0x13f8)
+#define RTL931X_SMI_10GPHY_POLLING_SEL2 (0xCF8)
+#define RTL931X_SMI_10GPHY_POLLING_SEL3 (0xCFC)
+#define RTL931X_SMI_10GPHY_POLLING_SEL4 (0xD00)
+
+/* Registers of the internal Serdes of the 8380 */
+#define RTL838X_SDS4_FIB_REG0 (0xF800)
+
+/* Default MTU with jumbo frames support */
+#define DEFAULT_MTU 9000
+
+inline int rtl838x_mac_port_ctrl(int p)
+{
+ return RTL838X_MAC_PORT_CTRL + (p << 7);
+}
+
+inline int rtl839x_mac_port_ctrl(int p)
+{
+ return RTL839X_MAC_PORT_CTRL + (p << 7);
+}
+
+/* On the RTL931XX, the functionality of the MAC port control register is split up
+ * into RTL931X_MAC_L2_PORT_CTRL and RTL931X_MAC_PORT_CTRL the functionality used
+ * by the Ethernet driver is in the same bits now in RTL931X_MAC_L2_PORT_CTRL
+ */
+
+inline int rtl930x_mac_port_ctrl(int p)
+{
+ return RTL930X_MAC_L2_PORT_CTRL + (p << 6);
+}
+
+inline int rtl931x_mac_port_ctrl(int p)
+{
+ return RTL931X_MAC_L2_PORT_CTRL + (p << 7);
+}
+
+inline int rtl838x_dma_if_rx_ring_size(int i)
+{
+ return RTL838X_DMA_IF_RX_RING_SIZE + ((i >> 3) << 2);
+}
+
+inline int rtl839x_dma_if_rx_ring_size(int i)
+{
+ return RTL839X_DMA_IF_RX_RING_SIZE + ((i >> 3) << 2);
+}
+
+inline int rtl930x_dma_if_rx_ring_size(int i)
+{
+ return RTL930X_DMA_IF_RX_RING_SIZE + ((i / 3) << 2);
+}
+
+inline int rtl931x_dma_if_rx_ring_size(int i)
+{
+ return RTL931X_DMA_IF_RX_RING_SIZE + ((i / 3) << 2);
+}
+
+inline int rtl838x_dma_if_rx_ring_cntr(int i)
+{
+ return RTL838X_DMA_IF_RX_RING_CNTR + ((i >> 3) << 2);
+}
+
+inline int rtl839x_dma_if_rx_ring_cntr(int i)
+{
+ return RTL839X_DMA_IF_RX_RING_CNTR + ((i >> 3) << 2);
+}
+
+inline int rtl930x_dma_if_rx_ring_cntr(int i)
+{
+ return RTL930X_DMA_IF_RX_RING_CNTR + ((i / 3) << 2);
+}
+
+inline int rtl931x_dma_if_rx_ring_cntr(int i)
+{
+ return RTL931X_DMA_IF_RX_RING_CNTR + ((i / 3) << 2);
+}
+
+inline u32 rtl838x_get_mac_link_sts(int port)
+{
+ return (sw_r32(RTL838X_MAC_LINK_STS) & BIT(port));
+}
+
+inline u32 rtl839x_get_mac_link_sts(int p)
+{
+ return (sw_r32(RTL839X_MAC_LINK_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+inline u32 rtl930x_get_mac_link_sts(int port)
+{
+ u32 link = sw_r32(RTL930X_MAC_LINK_STS);
+
+ link = sw_r32(RTL930X_MAC_LINK_STS);
+ pr_info("%s link state is %08x\n", __func__, link);
+ return link & BIT(port);
+}
+
+inline u32 rtl931x_get_mac_link_sts(int p)
+{
+ return (sw_r32(RTL931X_MAC_LINK_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+inline u32 rtl838x_get_mac_link_dup_sts(int port)
+{
+ return (sw_r32(RTL838X_MAC_LINK_DUP_STS) & BIT(port));
+}
+
+inline u32 rtl839x_get_mac_link_dup_sts(int p)
+{
+ return (sw_r32(RTL839X_MAC_LINK_DUP_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+inline u32 rtl930x_get_mac_link_dup_sts(int port)
+{
+ return (sw_r32(RTL930X_MAC_LINK_DUP_STS) & BIT(port));
+}
+
+inline u32 rtl931x_get_mac_link_dup_sts(int p)
+{
+ return (sw_r32(RTL931X_MAC_LINK_DUP_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+inline u32 rtl838x_get_mac_link_spd_sts(int port)
+{
+ int r = RTL838X_MAC_LINK_SPD_STS + ((port >> 4) << 2);
+ u32 speed = sw_r32(r);
+
+ speed >>= (port % 16) << 1;
+ return (speed & 0x3);
+}
+
+inline u32 rtl839x_get_mac_link_spd_sts(int port)
+{
+ int r = RTL839X_MAC_LINK_SPD_STS + ((port >> 4) << 2);
+ u32 speed = sw_r32(r);
+
+ speed >>= (port % 16) << 1;
+ return (speed & 0x3);
+}
+
+
+inline u32 rtl930x_get_mac_link_spd_sts(int port)
+{
+ int r = RTL930X_MAC_LINK_SPD_STS + ((port >> 3) << 2);
+ u32 speed = sw_r32(r);
+
+ speed >>= (port % 8) << 2;
+ return (speed & 0xf);
+}
+
+inline u32 rtl931x_get_mac_link_spd_sts(int port)
+{
+ int r = RTL931X_MAC_LINK_SPD_STS + ((port >> 3) << 2);
+ u32 speed = sw_r32(r);
+
+ speed >>= (port % 8) << 2;
+ return (speed & 0xf);
+}
+
+inline u32 rtl838x_get_mac_rx_pause_sts(int port)
+{
+ return (sw_r32(RTL838X_MAC_RX_PAUSE_STS) & (1 << port));
+}
+
+inline u32 rtl839x_get_mac_rx_pause_sts(int p)
+{
+ return (sw_r32(RTL839X_MAC_RX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+inline u32 rtl930x_get_mac_rx_pause_sts(int port)
+{
+ return (sw_r32(RTL930X_MAC_RX_PAUSE_STS) & (1 << port));
+}
+
+inline u32 rtl931x_get_mac_rx_pause_sts(int p)
+{
+ return (sw_r32(RTL931X_MAC_RX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+inline u32 rtl838x_get_mac_tx_pause_sts(int port)
+{
+ return (sw_r32(RTL838X_MAC_TX_PAUSE_STS) & (1 << port));
+}
+
+inline u32 rtl839x_get_mac_tx_pause_sts(int p)
+{
+ return (sw_r32(RTL839X_MAC_TX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+inline u32 rtl930x_get_mac_tx_pause_sts(int port)
+{
+ return (sw_r32(RTL930X_MAC_TX_PAUSE_STS) & (1 << port));
+}
+
+inline u32 rtl931x_get_mac_tx_pause_sts(int p)
+{
+ return (sw_r32(RTL931X_MAC_TX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32));
+}
+
+struct p_hdr;
+struct dsa_tag;
+
+struct rtl838x_bus_priv {
+ struct rtl838x_eth_priv *eth_priv;
+ int extaddr;
+ int rawpage;
+ int page[64];
+ bool raw[64];
+ int (*read_mmd_phy)(u32 port, u32 addr, u32 reg, u32 *val);
+ int (*write_mmd_phy)(u32 port, u32 addr, u32 reg, u32 val);
+ int (*read_phy)(u32 port, u32 page, u32 reg, u32 *val);
+ int (*write_phy)(u32 port, u32 page, u32 reg, u32 val);
+};
+
+struct rtl838x_eth_reg {
+ irqreturn_t (*net_irq)(int irq, void *dev_id);
+ int (*mac_port_ctrl)(int port);
+ int dma_if_intr_sts;
+ int dma_if_intr_msk;
+ int dma_if_intr_rx_runout_sts;
+ int dma_if_intr_rx_done_sts;
+ int dma_if_intr_tx_done_sts;
+ int dma_if_intr_rx_runout_msk;
+ int dma_if_intr_rx_done_msk;
+ int dma_if_intr_tx_done_msk;
+ int l2_ntfy_if_intr_sts;
+ int l2_ntfy_if_intr_msk;
+ int dma_if_ctrl;
+ int mac_force_mode_ctrl;
+ int dma_rx_base;
+ int dma_tx_base;
+ int (*dma_if_rx_ring_size)(int ring);
+ int (*dma_if_rx_ring_cntr)(int ring);
+ int dma_if_rx_cur;
+ int rst_glb_ctrl;
+ u32 (*get_mac_link_sts)(int port);
+ u32 (*get_mac_link_dup_sts)(int port);
+ u32 (*get_mac_link_spd_sts)(int port);
+ u32 (*get_mac_rx_pause_sts)(int port);
+ u32 (*get_mac_tx_pause_sts)(int port);
+ int mac;
+ int l2_tbl_flush_ctrl;
+ void (*update_cntr)(int r, int work_done);
+ void (*create_tx_header)(struct p_hdr *h, unsigned int dest_port, int prio);
+ bool (*decode_tag)(struct p_hdr *h, struct dsa_tag *tag);
+};
+
+int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val);
+int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
+int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val);
+int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val);
+int rtl839x_write_phy(u32 port, u32 page, u32 reg, u32 val);
+int rtl839x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
+int rtl839x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
+int rtl839x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val);
+int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val);
+int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
+int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val);
+int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
+int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data);
+
+#endif /* _RTL838X_ETH_H */
diff --git a/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c
new file mode 100644
index 0000000000..df5e2e4440
--- /dev/null
+++ b/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c
@@ -0,0 +1,4001 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Realtek RTL838X Ethernet MDIO interface driver
+ *
+ * Copyright (C) 2020 B. Koblitz
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/firmware.h>
+#include <linux/crc32.h>
+#include <linux/sfp.h>
+#include <linux/mii.h>
+#include <linux/mdio.h>
+
+#include <asm/mach-rtl838x/mach-rtl83xx.h>
+#include "rtl83xx-phy.h"
+
+extern struct rtl83xx_soc_info soc_info;
+extern struct mutex smi_lock;
+extern int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val);
+extern int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val);
+extern int phy_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val);
+extern int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum);
+extern int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnum);
+extern int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum);
+
+#define PHY_PAGE_2 2
+#define PHY_PAGE_4 4
+
+/* all Clause-22 RealTek MDIO PHYs use register 0x1f for page select */
+#define RTL8XXX_PAGE_SELECT 0x1f
+
+#define RTL8XXX_PAGE_MAIN 0x0000
+#define RTL821X_PAGE_PORT 0x0266
+#define RTL821X_PAGE_POWER 0x0a40
+#define RTL821X_PAGE_GPHY 0x0a42
+#define RTL821X_PAGE_MAC 0x0a43
+#define RTL821X_PAGE_STATE 0x0b80
+#define RTL821X_PAGE_PATCH 0x0b82
+
+/* Using the special page 0xfff with the MDIO controller found in
+ * RealTek SoCs allows to access the PHY in RAW mode, ie. bypassing
+ * the cache and paging engine of the MDIO controller.
+ */
+#define RTL83XX_PAGE_RAW 0x0fff
+
+/* internal RTL821X PHY uses register 0x1d to select media page */
+#define RTL821XINT_MEDIA_PAGE_SELECT 0x1d
+/* external RTL821X PHY uses register 0x1e to select media page */
+#define RTL821XEXT_MEDIA_PAGE_SELECT 0x1e
+
+#define RTL821X_CHIP_ID 0x6276
+
+#define RTL821X_MEDIA_PAGE_AUTO 0
+#define RTL821X_MEDIA_PAGE_COPPER 1
+#define RTL821X_MEDIA_PAGE_FIBRE 3
+#define RTL821X_MEDIA_PAGE_INTERNAL 8
+
+#define RTL9300_PHY_ID_MASK 0xf0ffffff
+
+/* RTL930X SerDes supports the following modes:
+ * 0x02: SGMII 0x04: 1000BX_FIBER 0x05: FIBER100
+ * 0x06: QSGMII 0x09: RSGMII 0x0d: USXGMII
+ * 0x10: XSGMII 0x12: HISGMII 0x16: 2500Base_X
+ * 0x17: RXAUI_LITE 0x19: RXAUI_PLUS 0x1a: 10G Base-R
+ * 0x1b: 10GR1000BX_AUTO 0x1f: OFF
+ */
+#define RTL930X_SDS_MODE_SGMII 0x02
+#define RTL930X_SDS_MODE_1000BASEX 0x04
+#define RTL930X_SDS_MODE_USXGMII 0x0d
+#define RTL930X_SDS_MODE_XGMII 0x10
+#define RTL930X_SDS_MODE_HSGMII 0x12
+#define RTL930X_SDS_MODE_2500BASEX 0x16
+#define RTL930X_SDS_MODE_10GBASER 0x1a
+#define RTL930X_SDS_OFF 0x1f
+#define RTL930X_SDS_MASK 0x1f
+
+/* This lock protects the state of the SoC automatically polling the PHYs over the SMI
+ * bus to detect e.g. link and media changes. For operations on the PHYs such as
+ * patching or other configuration changes such as EEE, polling needs to be disabled
+ * since otherwise these operations may fails or lead to unpredictable results.
+ */
+DEFINE_MUTEX(poll_lock);
+
+static const struct firmware rtl838x_8380_fw;
+static const struct firmware rtl838x_8214fc_fw;
+static const struct firmware rtl838x_8218b_fw;
+
+static u64 disable_polling(int port)
+{
+ u64 saved_state;
+
+ mutex_lock(&poll_lock);
+
+ switch (soc_info.family) {
+ case RTL8380_FAMILY_ID:
+ saved_state = sw_r32(RTL838X_SMI_POLL_CTRL);
+ sw_w32_mask(BIT(port), 0, RTL838X_SMI_POLL_CTRL);
+ break;
+ case RTL8390_FAMILY_ID:
+ saved_state = sw_r32(RTL839X_SMI_PORT_POLLING_CTRL + 4);
+ saved_state <<= 32;
+ saved_state |= sw_r32(RTL839X_SMI_PORT_POLLING_CTRL);
+ sw_w32_mask(BIT(port % 32), 0,
+ RTL839X_SMI_PORT_POLLING_CTRL + ((port >> 5) << 2));
+ break;
+ case RTL9300_FAMILY_ID:
+ saved_state = sw_r32(RTL930X_SMI_POLL_CTRL);
+ sw_w32_mask(BIT(port), 0, RTL930X_SMI_POLL_CTRL);
+ break;
+ case RTL9310_FAMILY_ID:
+ pr_warn("%s not implemented for RTL931X\n", __func__);
+ break;
+ }
+
+ mutex_unlock(&poll_lock);
+
+ return saved_state;
+}
+
+static int resume_polling(u64 saved_state)
+{
+ mutex_lock(&poll_lock);
+
+ switch (soc_info.family) {
+ case RTL8380_FAMILY_ID:
+ sw_w32(saved_state, RTL838X_SMI_POLL_CTRL);
+ break;
+ case RTL8390_FAMILY_ID:
+ sw_w32(saved_state >> 32, RTL839X_SMI_PORT_POLLING_CTRL + 4);
+ sw_w32(saved_state, RTL839X_SMI_PORT_POLLING_CTRL);
+ break;
+ case RTL9300_FAMILY_ID:
+ sw_w32(saved_state, RTL930X_SMI_POLL_CTRL);
+ break;
+ case RTL9310_FAMILY_ID:
+ pr_warn("%s not implemented for RTL931X\n", __func__);
+ break;
+ }
+
+ mutex_unlock(&poll_lock);
+
+ return 0;
+}
+
+static void rtl8380_int_phy_on_off(struct phy_device *phydev, bool on)
+{
+ phy_modify(phydev, 0, BMCR_PDOWN, on ? 0 : BMCR_PDOWN);
+}
+
+static void rtl8380_rtl8214fc_on_off(struct phy_device *phydev, bool on)
+{
+ /* fiber ports */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
+ phy_modify(phydev, 0x10, BMCR_PDOWN, on ? 0 : BMCR_PDOWN);
+
+ /* copper ports */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+ phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, BMCR_PDOWN, on ? 0 : BMCR_PDOWN);
+}
+
+static void rtl8380_phy_reset(struct phy_device *phydev)
+{
+ phy_modify(phydev, 0, BMCR_RESET, BMCR_RESET);
+}
+
+/* The access registers for SDS_MODE_SEL and the LSB for each SDS within */
+u16 rtl9300_sds_regs[] = { 0x0194, 0x0194, 0x0194, 0x0194, 0x02a0, 0x02a0, 0x02a0, 0x02a0,
+ 0x02A4, 0x02A4, 0x0198, 0x0198 };
+u8 rtl9300_sds_lsb[] = { 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 0, 6};
+
+/* Reset the SerDes by powering it off and set a new operation mode
+ * of the SerDes.
+ */
+void rtl9300_sds_rst(int sds_num, u32 mode)
+{
+ pr_info("%s %d\n", __func__, mode);
+ if (sds_num < 0 || sds_num > 11) {
+ pr_err("Wrong SerDes number: %d\n", sds_num);
+ return;
+ }
+
+ sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num],
+ RTL930X_SDS_OFF << rtl9300_sds_lsb[sds_num],
+ rtl9300_sds_regs[sds_num]);
+ mdelay(10);
+
+ sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num], mode << rtl9300_sds_lsb[sds_num],
+ rtl9300_sds_regs[sds_num]);
+ mdelay(10);
+
+ pr_debug("%s: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n", __func__,
+ sw_r32(0x194), sw_r32(0x198), sw_r32(0x2a0), sw_r32(0x2a4));
+}
+
+void rtl9300_sds_set(int sds_num, u32 mode)
+{
+ pr_info("%s %d\n", __func__, mode);
+ if (sds_num < 0 || sds_num > 11) {
+ pr_err("Wrong SerDes number: %d\n", sds_num);
+ return;
+ }
+
+ sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num], mode << rtl9300_sds_lsb[sds_num],
+ rtl9300_sds_regs[sds_num]);
+ mdelay(10);
+
+ pr_debug("%s: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n", __func__,
+ sw_r32(0x194), sw_r32(0x198), sw_r32(0x2a0), sw_r32(0x2a4));
+}
+
+u32 rtl9300_sds_mode_get(int sds_num)
+{
+ u32 v;
+
+ if (sds_num < 0 || sds_num > 11) {
+ pr_err("Wrong SerDes number: %d\n", sds_num);
+ return 0;
+ }
+
+ v = sw_r32(rtl9300_sds_regs[sds_num]);
+ v >>= rtl9300_sds_lsb[sds_num];
+
+ return v & RTL930X_SDS_MASK;
+}
+
+/* On the RTL839x family of SoCs with inbuilt SerDes, these SerDes are accessed through
+ * a 2048 bit register that holds the contents of the PHY being simulated by the SoC.
+ */
+int rtl839x_read_sds_phy(int phy_addr, int phy_reg)
+{
+ int offset = 0;
+ int reg;
+ u32 val;
+
+ if (phy_addr == 49)
+ offset = 0x100;
+
+ /* For the RTL8393 internal SerDes, we simulate a PHY ID in registers 2/3
+ * which would otherwise read as 0.
+ */
+ if (soc_info.id == 0x8393) {
+ if (phy_reg == MII_PHYSID1)
+ return 0x1c;
+ if (phy_reg == MII_PHYSID2)
+ return 0x8393;
+ }
+
+ /* Register RTL839X_SDS12_13_XSG0 is 2048 bit broad, the MSB (bit 15) of the
+ * 0th PHY register is bit 1023 (in byte 0x80). Because PHY-registers are 16
+ * bit broad, we offset by reg << 1. In the SoC 2 registers are stored in
+ * one 32 bit register.
+ */
+ reg = (phy_reg << 1) & 0xfc;
+ val = sw_r32(RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg);
+
+ if (phy_reg & 1)
+ val = (val >> 16) & 0xffff;
+ else
+ val &= 0xffff;
+
+ return val;
+}
+
+/* On the RTL930x family of SoCs, the internal SerDes are accessed through an IO
+ * register which simulates commands to an internal MDIO bus.
+ */
+int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg)
+{
+ int i;
+ u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1;
+
+ sw_w32(cmd, RTL930X_SDS_INDACS_CMD);
+
+ for (i = 0; i < 100; i++) {
+ if (!(sw_r32(RTL930X_SDS_INDACS_CMD) & 0x1))
+ break;
+ mdelay(1);
+ }
+
+ if (i >= 100)
+ return -EIO;
+
+ return sw_r32(RTL930X_SDS_INDACS_DATA) & 0xffff;
+}
+
+int rtl930x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v)
+{
+ int i;
+ u32 cmd;
+
+ sw_w32(v, RTL930X_SDS_INDACS_DATA);
+ cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 0x3;
+
+ sw_w32(cmd, RTL930X_SDS_INDACS_CMD);
+
+ for (i = 0; i < 100; i++) {
+ if (!(sw_r32(RTL930X_SDS_INDACS_CMD) & 0x1))
+ break;
+ mdelay(1);
+ }
+
+
+ if (i >= 100) {
+ pr_info("%s ERROR !!!!!!!!!!!!!!!!!!!!\n", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg)
+{
+ int i;
+ u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1;
+
+ pr_debug("%s: phy_addr(SDS-ID) %d, phy_reg: %d\n", __func__, phy_addr, phy_reg);
+ sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL);
+
+ for (i = 0; i < 100; i++) {
+ if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1))
+ break;
+ mdelay(1);
+ }
+
+ if (i >= 100)
+ return -EIO;
+
+ pr_debug("%s: returning %04x\n", __func__, sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff);
+
+ return sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff;
+}
+
+int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v)
+{
+ int i;
+ u32 cmd;
+
+ cmd = phy_addr << 2 | page << 7 | phy_reg << 13;
+ sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL);
+
+ sw_w32(v, RTL931X_SERDES_INDRT_DATA_CTRL);
+
+ cmd = sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) | 0x3;
+ sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL);
+
+ for (i = 0; i < 100; i++) {
+ if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1))
+ break;
+ mdelay(1);
+ }
+
+ if (i >= 100)
+ return -EIO;
+
+ return 0;
+}
+
+/* On the RTL838x SoCs, the internal SerDes is accessed through direct access to
+ * standard PHY registers, where a 32 bit register holds a 16 bit word as found
+ * in a standard page 0 of a PHY
+ */
+int rtl838x_read_sds_phy(int phy_addr, int phy_reg)
+{
+ int offset = 0;
+ u32 val;
+
+ if (phy_addr == 26)
+ offset = 0x100;
+ val = sw_r32(RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2)) & 0xffff;
+
+ return val;
+}
+
+int rtl839x_write_sds_phy(int phy_addr, int phy_reg, u16 v)
+{
+ int offset = 0;
+ int reg;
+ u32 val;
+
+ if (phy_addr == 49)
+ offset = 0x100;
+
+ reg = (phy_reg << 1) & 0xfc;
+ val = v;
+ if (phy_reg & 1) {
+ val = val << 16;
+ sw_w32_mask(0xffff0000, val,
+ RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg);
+ } else {
+ sw_w32_mask(0xffff, val,
+ RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg);
+ }
+
+ return 0;
+}
+
+/* Read the link and speed status of the 2 internal SGMII/1000Base-X
+ * ports of the RTL838x SoCs
+ */
+static int rtl8380_read_status(struct phy_device *phydev)
+{
+ int err;
+
+ err = genphy_read_status(phydev);
+
+ if (phydev->link) {
+ phydev->speed = SPEED_1000;
+ phydev->duplex = DUPLEX_FULL;
+ }
+
+ return err;
+}
+
+/* Read the link and speed status of the 2 internal SGMII/1000Base-X
+ * ports of the RTL8393 SoC
+ */
+static int rtl8393_read_status(struct phy_device *phydev)
+{
+ int offset = 0;
+ int err;
+ int phy_addr = phydev->mdio.addr;
+ u32 v;
+
+ err = genphy_read_status(phydev);
+ if (phy_addr == 49)
+ offset = 0x100;
+
+ if (phydev->link) {
+ phydev->speed = SPEED_100;
+ /* Read SPD_RD_00 (bit 13) and SPD_RD_01 (bit 6) out of the internal
+ * PHY registers
+ */
+ v = sw_r32(RTL839X_SDS12_13_XSG0 + offset + 0x80);
+ if (!(v & (1 << 13)) && (v & (1 << 6)))
+ phydev->speed = SPEED_1000;
+ phydev->duplex = DUPLEX_FULL;
+ }
+
+ return err;
+}
+
+static int rtl821x_read_page(struct phy_device *phydev)
+{
+ return __phy_read(phydev, RTL8XXX_PAGE_SELECT);
+}
+
+static int rtl821x_write_page(struct phy_device *phydev, int page)
+{
+ return __phy_write(phydev, RTL8XXX_PAGE_SELECT, page);
+}
+
+static int rtl8226_read_status(struct phy_device *phydev)
+{
+ int ret = 0;
+ u32 val;
+
+/* TODO: ret = genphy_read_status(phydev);
+ * if (ret < 0) {
+ * pr_info("%s: genphy_read_status failed\n", __func__);
+ * return ret;
+ * }
+ */
+
+ /* Link status must be read twice */
+ for (int i = 0; i < 2; i++)
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA402);
+
+ phydev->link = val & BIT(2) ? 1 : 0;
+ if (!phydev->link)
+ goto out;
+
+ /* Read duplex status */
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434);
+ if (val < 0)
+ goto out;
+ phydev->duplex = !!(val & BIT(3));
+
+ /* Read speed */
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434);
+ switch (val & 0x0630) {
+ case 0x0000:
+ phydev->speed = SPEED_10;
+ break;
+ case 0x0010:
+ phydev->speed = SPEED_100;
+ break;
+ case 0x0020:
+ phydev->speed = SPEED_1000;
+ break;
+ case 0x0200:
+ phydev->speed = SPEED_10000;
+ break;
+ case 0x0210:
+ phydev->speed = SPEED_2500;
+ break;
+ case 0x0220:
+ phydev->speed = SPEED_5000;
+ break;
+ default:
+ break;
+ }
+
+out:
+ return ret;
+}
+
+static int rtl8226_advertise_aneg(struct phy_device *phydev)
+{
+ int ret = 0;
+ u32 v;
+
+ pr_info("In %s\n", __func__);
+
+ v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
+ if (v < 0)
+ goto out;
+
+ v |= ADVERTISE_10HALF;
+ v |= ADVERTISE_10FULL;
+ v |= ADVERTISE_100HALF;
+ v |= ADVERTISE_100FULL;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, v);
+
+ /* Allow 1GBit */
+ v = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA412);
+ if (v < 0)
+ goto out;
+ v |= ADVERTISE_1000FULL;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA412, v);
+ if (ret < 0)
+ goto out;
+
+ /* Allow 2.5G */
+ v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
+ if (v < 0)
+ goto out;
+
+ v |= MDIO_AN_10GBT_CTRL_ADV2_5G;
+ ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, v);
+
+out:
+ return ret;
+}
+
+static int rtl8226_config_aneg(struct phy_device *phydev)
+{
+ int ret = 0;
+ u32 v;
+
+ pr_debug("In %s\n", __func__);
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+ ret = rtl8226_advertise_aneg(phydev);
+ if (ret)
+ goto out;
+ /* AutoNegotiationEnable */
+ v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
+ if (v < 0)
+ goto out;
+
+ v |= MDIO_AN_CTRL1_ENABLE; /* Enable AN */
+ ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, v);
+ if (ret < 0)
+ goto out;
+
+ /* RestartAutoNegotiation */
+ v = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA400);
+ if (v < 0)
+ goto out;
+ v |= MDIO_AN_CTRL1_RESTART;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA400, v);
+ }
+
+/* TODO: ret = __genphy_config_aneg(phydev, ret); */
+
+out:
+ return ret;
+}
+
+static int rtl8226_get_eee(struct phy_device *phydev,
+ struct ethtool_eee *e)
+{
+ u32 val;
+ int addr = phydev->mdio.addr;
+
+ pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
+
+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
+ if (e->eee_enabled) {
+ e->eee_enabled = !!(val & MDIO_EEE_100TX);
+ if (!e->eee_enabled) {
+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2);
+ e->eee_enabled = !!(val & MDIO_EEE_2_5GT);
+ }
+ }
+ pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
+
+ return 0;
+}
+
+static int rtl8226_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
+{
+ int port = phydev->mdio.addr;
+ u64 poll_state;
+ bool an_enabled;
+ u32 val;
+
+ pr_info("In %s, port %d, enabled %d\n", __func__, port, e->eee_enabled);
+
+ poll_state = disable_polling(port);
+
+ /* Remember aneg state */
+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
+ an_enabled = !!(val & MDIO_AN_CTRL1_ENABLE);
+
+ /* Setup 100/1000MBit */
+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
+ if (e->eee_enabled)
+ val |= (MDIO_EEE_100TX | MDIO_EEE_1000T);
+ else
+ val &= (MDIO_EEE_100TX | MDIO_EEE_1000T);
+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+
+ /* Setup 2.5GBit */
+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2);
+ if (e->eee_enabled)
+ val |= MDIO_EEE_2_5GT;
+ else
+ val &= MDIO_EEE_2_5GT;
+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2, val);
+
+ /* RestartAutoNegotiation */
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA400);
+ val |= MDIO_AN_CTRL1_RESTART;
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA400, val);
+
+ resume_polling(poll_state);
+
+ return 0;
+}
+
+static struct fw_header *rtl838x_request_fw(struct phy_device *phydev,
+ const struct firmware *fw,
+ const char *name)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int err;
+ struct fw_header *h;
+ uint32_t checksum, my_checksum;
+
+ err = request_firmware(&fw, name, dev);
+ if (err < 0)
+ goto out;
+
+ if (fw->size < sizeof(struct fw_header)) {
+ pr_err("Firmware size too small.\n");
+ err = -EINVAL;
+ goto out;
+ }
+
+ h = (struct fw_header *) fw->data;
+ pr_info("Firmware loaded. Size %d, magic: %08x\n", fw->size, h->magic);
+
+ if (h->magic != 0x83808380) {
+ pr_err("Wrong firmware file: MAGIC mismatch.\n");
+ goto out;
+ }
+
+ checksum = h->checksum;
+ h->checksum = 0;
+ my_checksum = ~crc32(0xFFFFFFFFU, fw->data, fw->size);
+ if (checksum != my_checksum) {
+ pr_err("Firmware checksum mismatch.\n");
+ err = -EINVAL;
+ goto out;
+ }
+ h->checksum = checksum;
+
+ return h;
+out:
+ dev_err(dev, "Unable to load firmware %s (%d)\n", name, err);
+ return NULL;
+}
+
+static void rtl821x_phy_setup_package_broadcast(struct phy_device *phydev, bool enable)
+{
+ int mac = phydev->mdio.addr;
+
+ /* select main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ /* write to 0x8 to register 0x1d on main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ /* select page 0x266 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PORT);
+ /* set phy id and target broadcast bitmap in register 0x16 on page 0x266 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x16, (enable?0xff00:0x00) | mac);
+ /* return to main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ /* write to 0x0 to register 0x1d on main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+ mdelay(1);
+}
+
+static int rtl8390_configure_generic(struct phy_device *phydev)
+{
+ int mac = phydev->mdio.addr;
+ u32 val, phy_id;
+
+ val = phy_read(phydev, 2);
+ phy_id = val << 16;
+ val = phy_read(phydev, 3);
+ phy_id |= val;
+ pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
+
+ /* Read internal PHY ID */
+ phy_write_paged(phydev, 31, 27, 0x0002);
+ val = phy_read_paged(phydev, 31, 28);
+
+ /* Internal RTL8218B, version 2 */
+ phydev_info(phydev, "Detected unknown %x\n", val);
+
+ return 0;
+}
+
+static int rtl8380_configure_int_rtl8218b(struct phy_device *phydev)
+{
+ u32 val, phy_id;
+ int mac = phydev->mdio.addr;
+ struct fw_header *h;
+ u32 *rtl838x_6275B_intPhy_perport;
+ u32 *rtl8218b_6276B_hwEsd_perport;
+
+ val = phy_read(phydev, 2);
+ phy_id = val << 16;
+ val = phy_read(phydev, 3);
+ phy_id |= val;
+ pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
+
+ /* Read internal PHY ID */
+ phy_write_paged(phydev, 31, 27, 0x0002);
+ val = phy_read_paged(phydev, 31, 28);
+ if (val != 0x6275) {
+ phydev_err(phydev, "Expected internal RTL8218B, found PHY-ID %x\n", val);
+ return -1;
+ }
+
+ /* Internal RTL8218B, version 2 */
+ phydev_info(phydev, "Detected internal RTL8218B\n");
+
+ h = rtl838x_request_fw(phydev, &rtl838x_8380_fw, FIRMWARE_838X_8380_1);
+ if (!h)
+ return -1;
+
+ if (h->phy != 0x83800000) {
+ phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
+ return -1;
+ }
+
+ rtl838x_6275B_intPhy_perport = (void *)h + sizeof(struct fw_header) + h->parts[8].start;
+ rtl8218b_6276B_hwEsd_perport = (void *)h + sizeof(struct fw_header) + h->parts[9].start;
+
+ // Currently not used
+ // if (sw_r32(RTL838X_DMY_REG31) == 0x1) {
+ // int ipd_flag = 1;
+ // }
+
+ val = phy_read(phydev, MII_BMCR);
+ if (val & BMCR_PDOWN)
+ rtl8380_int_phy_on_off(phydev, true);
+ else
+ rtl8380_phy_reset(phydev);
+ msleep(100);
+
+ /* Ready PHY for patch */
+ for (int p = 0; p < 8; p++) {
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, 0x10, 0x0010);
+ }
+ msleep(500);
+ for (int p = 0; p < 8; p++) {
+ int i;
+
+ for (i = 0; i < 100 ; i++) {
+ val = phy_package_port_read_paged(phydev, p, RTL821X_PAGE_STATE, 0x10);
+ if (val & 0x40)
+ break;
+ }
+ if (i >= 100) {
+ phydev_err(phydev,
+ "ERROR: Port %d not ready for patch.\n",
+ mac + p);
+ return -1;
+ }
+ }
+ for (int p = 0; p < 8; p++) {
+ int i;
+
+ i = 0;
+ while (rtl838x_6275B_intPhy_perport[i * 2]) {
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW,
+ rtl838x_6275B_intPhy_perport[i * 2],
+ rtl838x_6275B_intPhy_perport[i * 2 + 1]);
+ i++;
+ }
+ i = 0;
+ while (rtl8218b_6276B_hwEsd_perport[i * 2]) {
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW,
+ rtl8218b_6276B_hwEsd_perport[i * 2],
+ rtl8218b_6276B_hwEsd_perport[i * 2 + 1]);
+ i++;
+ }
+ }
+
+ return 0;
+}
+
+static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
+{
+ u32 val, ipd, phy_id;
+ int mac = phydev->mdio.addr;
+ struct fw_header *h;
+ u32 *rtl8380_rtl8218b_perchip;
+ u32 *rtl8218B_6276B_rtl8380_perport;
+ u32 *rtl8380_rtl8218b_perport;
+
+ if (soc_info.family == RTL8380_FAMILY_ID && mac != 0 && mac != 16) {
+ phydev_err(phydev, "External RTL8218B must have PHY-IDs 0 or 16!\n");
+ return -1;
+ }
+ val = phy_read(phydev, 2);
+ phy_id = val << 16;
+ val = phy_read(phydev, 3);
+ phy_id |= val;
+ pr_info("Phy on MAC %d: %x\n", mac, phy_id);
+
+ /* Read internal PHY ID */
+ phy_write_paged(phydev, 31, 27, 0x0002);
+ val = phy_read_paged(phydev, 31, 28);
+ if (val != RTL821X_CHIP_ID) {
+ phydev_err(phydev, "Expected external RTL8218B, found PHY-ID %x\n", val);
+ return -1;
+ }
+ phydev_info(phydev, "Detected external RTL8218B\n");
+
+ h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8218b_1);
+ if (!h)
+ return -1;
+
+ if (h->phy != 0x8218b000) {
+ phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
+ return -1;
+ }
+
+ rtl8380_rtl8218b_perchip = (void *)h + sizeof(struct fw_header) + h->parts[0].start;
+ rtl8218B_6276B_rtl8380_perport = (void *)h + sizeof(struct fw_header) + h->parts[1].start;
+ rtl8380_rtl8218b_perport = (void *)h + sizeof(struct fw_header) + h->parts[2].start;
+
+ val = phy_read(phydev, MII_BMCR);
+ if (val & BMCR_PDOWN)
+ rtl8380_int_phy_on_off(phydev, true);
+ else
+ rtl8380_phy_reset(phydev);
+
+ msleep(100);
+
+ /* Get Chip revision */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x1b, 0x4);
+ val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 0x1c);
+
+ phydev_info(phydev, "Detected chip revision %04x\n", val);
+
+ for (int i = 0; rtl8380_rtl8218b_perchip[i * 3] &&
+ rtl8380_rtl8218b_perchip[i * 3 + 1]; i++) {
+ phy_package_port_write_paged(phydev, rtl8380_rtl8218b_perchip[i * 3],
+ RTL83XX_PAGE_RAW, rtl8380_rtl8218b_perchip[i * 3 + 1],
+ rtl8380_rtl8218b_perchip[i * 3 + 2]);
+ }
+
+ /* Enable PHY */
+ for (int i = 0; i < 8; i++) {
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140);
+ }
+ mdelay(100);
+
+ /* Request patch */
+ for (int i = 0; i < 8; i++) {
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010);
+ }
+
+ mdelay(300);
+
+ /* Verify patch readiness */
+ for (int i = 0; i < 8; i++) {
+ int l;
+
+ for (l = 0; l < 100; l++) {
+ val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10);
+ if (val & 0x40)
+ break;
+ }
+ if (l >= 100) {
+ phydev_err(phydev, "Could not patch PHY\n");
+ return -1;
+ }
+ }
+
+ /* Use Broadcast ID method for patching */
+ rtl821x_phy_setup_package_broadcast(phydev, true);
+
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 30, 8);
+ phy_write_paged(phydev, 0x26e, 17, 0xb);
+ phy_write_paged(phydev, 0x26e, 16, 0x2);
+ mdelay(1);
+ ipd = phy_read_paged(phydev, 0x26e, 19);
+ phy_write_paged(phydev, 0, 30, 0);
+ ipd = (ipd >> 4) & 0xf; /* unused ? */
+
+ for (int i = 0; rtl8218B_6276B_rtl8380_perport[i * 2]; i++) {
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8218B_6276B_rtl8380_perport[i * 2],
+ rtl8218B_6276B_rtl8380_perport[i * 2 + 1]);
+ }
+
+ /* Disable broadcast ID */
+ rtl821x_phy_setup_package_broadcast(phydev, false);
+
+ return 0;
+}
+
+static int rtl8218b_ext_match_phy_device(struct phy_device *phydev)
+{
+ int addr = phydev->mdio.addr;
+
+ /* Both the RTL8214FC and the external RTL8218B have the same
+ * PHY ID. On the RTL838x, the RTL8218B can only be attached_dev
+ * at PHY IDs 0-7, while the RTL8214FC must be attached via
+ * the pair of SGMII/1000Base-X with higher PHY-IDs
+ */
+ if (soc_info.family == RTL8380_FAMILY_ID)
+ return phydev->phy_id == PHY_ID_RTL8218B_E && addr < 8;
+ else
+ return phydev->phy_id == PHY_ID_RTL8218B_E;
+}
+
+static bool rtl8214fc_media_is_fibre(struct phy_device *phydev)
+{
+ int mac = phydev->mdio.addr;
+
+ static int reg[] = {16, 19, 20, 21};
+ u32 val;
+
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+
+ if (val & BMCR_PDOWN)
+ return false;
+
+ return true;
+}
+
+static void rtl8214fc_power_set(struct phy_device *phydev, int port, bool on)
+{
+ char *state = on ? "on" : "off";
+
+ if (port == PORT_FIBRE) {
+ pr_info("%s: Powering %s FIBRE (port %d)\n", __func__, state, phydev->mdio.addr);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
+ } else {
+ pr_info("%s: Powering %s COPPER (port %d)\n", __func__, state, phydev->mdio.addr);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+ }
+
+ if (on) {
+ phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, BMCR_PDOWN, 0);
+ } else {
+ phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, 0, BMCR_PDOWN);
+ }
+
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+}
+
+static int rtl8214fc_suspend(struct phy_device *phydev)
+{
+ rtl8214fc_power_set(phydev, PORT_MII, false);
+ rtl8214fc_power_set(phydev, PORT_FIBRE, false);
+
+ return 0;
+}
+
+static int rtl8214fc_resume(struct phy_device *phydev)
+{
+ if (rtl8214fc_media_is_fibre(phydev)) {
+ rtl8214fc_power_set(phydev, PORT_MII, false);
+ rtl8214fc_power_set(phydev, PORT_FIBRE, true);
+ } else {
+ rtl8214fc_power_set(phydev, PORT_FIBRE, false);
+ rtl8214fc_power_set(phydev, PORT_MII, true);
+ }
+
+ return 0;
+}
+
+static void rtl8214fc_media_set(struct phy_device *phydev, bool set_fibre)
+{
+ int mac = phydev->mdio.addr;
+
+ static int reg[] = {16, 19, 20, 21};
+ int val;
+
+ pr_info("%s: port %d, set_fibre: %d\n", __func__, mac, set_fibre);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
+
+ val |= BIT(10);
+ if (set_fibre) {
+ val &= ~BMCR_PDOWN;
+ } else {
+ val |= BMCR_PDOWN;
+ }
+
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ phy_package_write_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4], val);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+
+ if (!phydev->suspended) {
+ if (set_fibre) {
+ rtl8214fc_power_set(phydev, PORT_MII, false);
+ rtl8214fc_power_set(phydev, PORT_FIBRE, true);
+ } else {
+ rtl8214fc_power_set(phydev, PORT_FIBRE, false);
+ rtl8214fc_power_set(phydev, PORT_MII, true);
+ }
+ }
+}
+
+static int rtl8214fc_set_port(struct phy_device *phydev, int port)
+{
+ bool is_fibre = (port == PORT_FIBRE ? true : false);
+ int addr = phydev->mdio.addr;
+
+ pr_debug("%s port %d to %d\n", __func__, addr, port);
+
+ rtl8214fc_media_set(phydev, is_fibre);
+
+ return 0;
+}
+
+static int rtl8214fc_get_port(struct phy_device *phydev)
+{
+ int addr = phydev->mdio.addr;
+
+ pr_debug("%s: port %d\n", __func__, addr);
+ if (rtl8214fc_media_is_fibre(phydev))
+ return PORT_FIBRE;
+
+ return PORT_MII;
+}
+
+/* Enable EEE on the RTL8218B PHYs
+ * The method used is not the preferred way (which would be based on the MAC-EEE state,
+ * but the only way that works since the kernel first enables EEE in the MAC
+ * and then sets up the PHY. The MAC-based approach would require the oppsite.
+ */
+void rtl8218d_eee_set(struct phy_device *phydev, bool enable)
+{
+ u32 val;
+ bool an_enabled;
+
+ pr_debug("In %s %d, enable %d\n", __func__, phydev->mdio.addr, enable);
+ /* Set GPHY page to copper */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+
+ val = phy_read(phydev, MII_BMCR);
+ an_enabled = val & BMCR_ANENABLE;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
+ val |= MDIO_EEE_1000T | MDIO_EEE_100TX;
+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, enable ? (MDIO_EEE_100TX | MDIO_EEE_1000T) : 0);
+
+ /* 500M EEE ability */
+ val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20);
+ if (enable)
+ val |= BIT(7);
+ else
+ val &= ~BIT(7);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val);
+
+ /* Restart AN if enabled */
+ if (an_enabled) {
+ val = phy_read(phydev, MII_BMCR);
+ val |= BMCR_ANRESTART;
+ phy_write(phydev, MII_BMCR, val);
+ }
+
+ /* GPHY page back to auto */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+}
+
+static int rtl8218b_get_eee(struct phy_device *phydev,
+ struct ethtool_eee *e)
+{
+ u32 val;
+ int addr = phydev->mdio.addr;
+
+ pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
+
+ /* Set GPHY page to copper */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+
+ val = phy_read_paged(phydev, 7, MDIO_AN_EEE_ADV);
+ if (e->eee_enabled) {
+ /* Verify vs MAC-based EEE */
+ e->eee_enabled = !!(val & BIT(7));
+ if (!e->eee_enabled) {
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
+ e->eee_enabled = !!(val & BIT(4));
+ }
+ }
+ pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
+
+ /* GPHY page to auto */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+
+ return 0;
+}
+
+static int rtl8218d_get_eee(struct phy_device *phydev,
+ struct ethtool_eee *e)
+{
+ u32 val;
+ int addr = phydev->mdio.addr;
+
+ pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
+
+ /* Set GPHY page to copper */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+
+ val = phy_read_paged(phydev, 7, MDIO_AN_EEE_ADV);
+ if (e->eee_enabled)
+ e->eee_enabled = !!(val & BIT(7));
+ pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
+
+ /* GPHY page to auto */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+
+ return 0;
+}
+
+static int rtl8214fc_set_eee(struct phy_device *phydev,
+ struct ethtool_eee *e)
+{
+ u32 poll_state;
+ int port = phydev->mdio.addr;
+ bool an_enabled;
+ u32 val;
+
+ pr_debug("In %s port %d, enabled %d\n", __func__, port, e->eee_enabled);
+
+ if (rtl8214fc_media_is_fibre(phydev)) {
+ netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", port);
+ return -ENOTSUPP;
+ }
+
+ poll_state = disable_polling(port);
+
+ /* Set GPHY page to copper */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+
+ /* Get auto-negotiation status */
+ val = phy_read(phydev, MII_BMCR);
+ an_enabled = val & BMCR_ANENABLE;
+
+ pr_info("%s: aneg: %d\n", __func__, an_enabled);
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
+ val &= ~BIT(5); /* Use MAC-based EEE */
+ phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
+
+ /* Enable 100M (bit 1) / 1000M (bit 2) EEE */
+ phy_write_paged(phydev, 7, MDIO_AN_EEE_ADV, e->eee_enabled ? (MDIO_EEE_100TX | MDIO_EEE_1000T) : 0);
+
+ /* 500M EEE ability */
+ val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20);
+ if (e->eee_enabled)
+ val |= BIT(7);
+ else
+ val &= ~BIT(7);
+
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val);
+
+ /* Restart AN if enabled */
+ if (an_enabled) {
+ pr_info("%s: doing aneg\n", __func__);
+ val = phy_read(phydev, MII_BMCR);
+ val |= BMCR_ANRESTART;
+ phy_write(phydev, MII_BMCR, val);
+ }
+
+ /* GPHY page back to auto */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+
+ resume_polling(poll_state);
+
+ return 0;
+}
+
+static int rtl8214fc_get_eee(struct phy_device *phydev,
+ struct ethtool_eee *e)
+{
+ int addr = phydev->mdio.addr;
+
+ pr_debug("In %s port %d, enabled %d\n", __func__, addr, e->eee_enabled);
+ if (rtl8214fc_media_is_fibre(phydev)) {
+ netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", addr);
+ return -ENOTSUPP;
+ }
+
+ return rtl8218b_get_eee(phydev, e);
+}
+
+static int rtl8218b_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
+{
+ int port = phydev->mdio.addr;
+ u64 poll_state;
+ u32 val;
+ bool an_enabled;
+
+ pr_info("In %s, port %d, enabled %d\n", __func__, port, e->eee_enabled);
+
+ poll_state = disable_polling(port);
+
+ /* Set GPHY page to copper */
+ phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+ val = phy_read(phydev, MII_BMCR);
+ an_enabled = val & BMCR_ANENABLE;
+
+ if (e->eee_enabled) {
+ /* 100/1000M EEE Capability */
+ phy_write(phydev, 13, 0x0007);
+ phy_write(phydev, 14, 0x003C);
+ phy_write(phydev, 13, 0x4007);
+ phy_write(phydev, 14, 0x0006);
+
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
+ val |= BIT(4);
+ phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
+ } else {
+ /* 100/1000M EEE Capability */
+ phy_write(phydev, 13, 0x0007);
+ phy_write(phydev, 14, 0x003C);
+ phy_write(phydev, 13, 0x0007);
+ phy_write(phydev, 14, 0x0000);
+
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
+ val &= ~BIT(4);
+ phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
+ }
+
+ /* Restart AN if enabled */
+ if (an_enabled) {
+ val = phy_read(phydev, MII_BMCR);
+ val |= BMCR_ANRESTART;
+ phy_write(phydev, MII_BMCR, val);
+ }
+
+ /* GPHY page back to auto */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+
+ pr_info("%s done\n", __func__);
+ resume_polling(poll_state);
+
+ return 0;
+}
+
+static int rtl8218d_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
+{
+ int addr = phydev->mdio.addr;
+ u64 poll_state;
+
+ pr_info("In %s, port %d, enabled %d\n", __func__, addr, e->eee_enabled);
+
+ poll_state = disable_polling(addr);
+
+ rtl8218d_eee_set(phydev, (bool) e->eee_enabled);
+
+ resume_polling(poll_state);
+
+ return 0;
+}
+
+static int rtl8214c_match_phy_device(struct phy_device *phydev)
+{
+ return phydev->phy_id == PHY_ID_RTL8214C;
+}
+
+static int rtl8380_configure_rtl8214c(struct phy_device *phydev)
+{
+ u32 phy_id, val;
+ int mac = phydev->mdio.addr;
+
+ val = phy_read(phydev, 2);
+ phy_id = val << 16;
+ val = phy_read(phydev, 3);
+ phy_id |= val;
+ pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
+
+ phydev_info(phydev, "Detected external RTL8214C\n");
+
+ /* GPHY auto conf */
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+
+ return 0;
+}
+
+static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
+{
+ int mac = phydev->mdio.addr;
+ struct fw_header *h;
+ u32 *rtl8380_rtl8214fc_perchip;
+ u32 *rtl8380_rtl8214fc_perport;
+ u32 phy_id;
+ u32 val;
+
+ val = phy_read(phydev, 2);
+ phy_id = val << 16;
+ val = phy_read(phydev, 3);
+ phy_id |= val;
+ pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
+
+ /* Read internal PHY id */
+ phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+ phy_write_paged(phydev, 0x1f, 0x1b, 0x0002);
+ val = phy_read_paged(phydev, 0x1f, 0x1c);
+ if (val != RTL821X_CHIP_ID) {
+ phydev_err(phydev, "Expected external RTL8214FC, found PHY-ID %x\n", val);
+ return -1;
+ }
+ phydev_info(phydev, "Detected external RTL8214FC\n");
+
+ h = rtl838x_request_fw(phydev, &rtl838x_8214fc_fw, FIRMWARE_838X_8214FC_1);
+ if (!h)
+ return -1;
+
+ if (h->phy != 0x8214fc00) {
+ phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n");
+ return -1;
+ }
+
+ rtl8380_rtl8214fc_perchip = (void *)h + sizeof(struct fw_header) + h->parts[0].start;
+
+ rtl8380_rtl8214fc_perport = (void *)h + sizeof(struct fw_header) + h->parts[1].start;
+
+ /* detect phy version */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 27, 0x0004);
+ val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 28);
+
+ val = phy_read(phydev, 16);
+ if (val & BMCR_PDOWN)
+ rtl8380_rtl8214fc_on_off(phydev, true);
+ else
+ rtl8380_phy_reset(phydev);
+
+ msleep(100);
+ phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+
+ for (int i = 0; rtl8380_rtl8214fc_perchip[i * 3] &&
+ rtl8380_rtl8214fc_perchip[i * 3 + 1]; i++) {
+ u32 page = 0;
+
+ if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x1f)
+ page = rtl8380_rtl8214fc_perchip[i * 3 + 2];
+ if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x13 && page == 0x260) {
+ val = phy_read_paged(phydev, 0x260, 13);
+ val = (val & 0x1f00) | (rtl8380_rtl8214fc_perchip[i * 3 + 2] & 0xe0ff);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW,
+ rtl8380_rtl8214fc_perchip[i * 3 + 1], val);
+ } else {
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW,
+ rtl8380_rtl8214fc_perchip[i * 3 + 1],
+ rtl8380_rtl8214fc_perchip[i * 3 + 2]);
+ }
+ }
+
+ /* Force copper medium */
+ for (int i = 0; i < 4; i++) {
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+ }
+
+ /* Enable PHY */
+ for (int i = 0; i < 4; i++) {
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140);
+ }
+ mdelay(100);
+
+ /* Disable Autosensing */
+ for (int i = 0; i < 4; i++) {
+ int l;
+
+ for (l = 0; l < 100; l++) {
+ val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_GPHY, 0x10);
+ if ((val & 0x7) >= 3)
+ break;
+ }
+ if (l >= 100) {
+ phydev_err(phydev, "Could not disable autosensing\n");
+ return -1;
+ }
+ }
+
+ /* Request patch */
+ for (int i = 0; i < 4; i++) {
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010);
+ }
+ mdelay(300);
+
+ /* Verify patch readiness */
+ for (int i = 0; i < 4; i++) {
+ int l;
+
+ for (l = 0; l < 100; l++) {
+ val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10);
+ if (val & 0x40)
+ break;
+ }
+ if (l >= 100) {
+ phydev_err(phydev, "Could not patch PHY\n");
+ return -1;
+ }
+ }
+ /* Use Broadcast ID method for patching */
+ rtl821x_phy_setup_package_broadcast(phydev, true);
+
+ for (int i = 0; rtl8380_rtl8214fc_perport[i * 2]; i++) {
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8380_rtl8214fc_perport[i * 2],
+ rtl8380_rtl8214fc_perport[i * 2 + 1]);
+ }
+
+ /* Disable broadcast ID */
+ rtl821x_phy_setup_package_broadcast(phydev, false);
+
+ /* Auto medium selection */
+ for (int i = 0; i < 4; i++) {
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+ }
+
+ return 0;
+}
+
+static int rtl8214fc_match_phy_device(struct phy_device *phydev)
+{
+ int addr = phydev->mdio.addr;
+
+ return phydev->phy_id == PHY_ID_RTL8214FC && addr >= 24;
+}
+
+static int rtl8380_configure_serdes(struct phy_device *phydev)
+{
+ u32 v;
+ u32 sds_conf_value;
+ int i;
+ struct fw_header *h;
+ u32 *rtl8380_sds_take_reset;
+ u32 *rtl8380_sds_common;
+ u32 *rtl8380_sds01_qsgmii_6275b;
+ u32 *rtl8380_sds23_qsgmii_6275b;
+ u32 *rtl8380_sds4_fiber_6275b;
+ u32 *rtl8380_sds5_fiber_6275b;
+ u32 *rtl8380_sds_reset;
+ u32 *rtl8380_sds_release_reset;
+
+ phydev_info(phydev, "Detected internal RTL8380 SERDES\n");
+
+ h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8380_1);
+ if (!h)
+ return -1;
+
+ if (h->magic != 0x83808380) {
+ phydev_err(phydev, "Wrong firmware file: magic number mismatch.\n");
+ return -1;
+ }
+
+ rtl8380_sds_take_reset = (void *)h + sizeof(struct fw_header) + h->parts[0].start;
+
+ rtl8380_sds_common = (void *)h + sizeof(struct fw_header) + h->parts[1].start;
+
+ rtl8380_sds01_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[2].start;
+
+ rtl8380_sds23_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[3].start;
+
+ rtl8380_sds4_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[4].start;
+
+ rtl8380_sds5_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[5].start;
+
+ rtl8380_sds_reset = (void *)h + sizeof(struct fw_header) + h->parts[6].start;
+
+ rtl8380_sds_release_reset = (void *)h + sizeof(struct fw_header) + h->parts[7].start;
+
+ /* Back up serdes power off value */
+ sds_conf_value = sw_r32(RTL838X_SDS_CFG_REG);
+ pr_info("SDS power down value: %x\n", sds_conf_value);
+
+ /* take serdes into reset */
+ i = 0;
+ while (rtl8380_sds_take_reset[2 * i]) {
+ sw_w32(rtl8380_sds_take_reset[2 * i + 1], rtl8380_sds_take_reset[2 * i]);
+ i++;
+ udelay(1000);
+ }
+
+ /* apply common serdes patch */
+ i = 0;
+ while (rtl8380_sds_common[2 * i]) {
+ sw_w32(rtl8380_sds_common[2 * i + 1], rtl8380_sds_common[2 * i]);
+ i++;
+ udelay(1000);
+ }
+
+ /* internal R/W enable */
+ sw_w32(3, RTL838X_INT_RW_CTRL);
+
+ /* SerDes ports 4 and 5 are FIBRE ports */
+ sw_w32_mask(0x7 | 0x38, 1 | (1 << 3), RTL838X_INT_MODE_CTRL);
+
+ /* SerDes module settings, SerDes 0-3 are QSGMII */
+ v = 0x6 << 25 | 0x6 << 20 | 0x6 << 15 | 0x6 << 10;
+ /* SerDes 4 and 5 are 1000BX FIBRE */
+ v |= 0x4 << 5 | 0x4;
+ sw_w32(v, RTL838X_SDS_MODE_SEL);
+
+ pr_info("PLL control register: %x\n", sw_r32(RTL838X_PLL_CML_CTRL));
+ sw_w32_mask(0xfffffff0, 0xaaaaaaaf & 0xf, RTL838X_PLL_CML_CTRL);
+ i = 0;
+ while (rtl8380_sds01_qsgmii_6275b[2 * i]) {
+ sw_w32(rtl8380_sds01_qsgmii_6275b[2 * i + 1],
+ rtl8380_sds01_qsgmii_6275b[2 * i]);
+ i++;
+ }
+
+ i = 0;
+ while (rtl8380_sds23_qsgmii_6275b[2 * i]) {
+ sw_w32(rtl8380_sds23_qsgmii_6275b[2 * i + 1], rtl8380_sds23_qsgmii_6275b[2 * i]);
+ i++;
+ }
+
+ i = 0;
+ while (rtl8380_sds4_fiber_6275b[2 * i]) {
+ sw_w32(rtl8380_sds4_fiber_6275b[2 * i + 1], rtl8380_sds4_fiber_6275b[2 * i]);
+ i++;
+ }
+
+ i = 0;
+ while (rtl8380_sds5_fiber_6275b[2 * i]) {
+ sw_w32(rtl8380_sds5_fiber_6275b[2 * i + 1], rtl8380_sds5_fiber_6275b[2 * i]);
+ i++;
+ }
+
+ i = 0;
+ while (rtl8380_sds_reset[2 * i]) {
+ sw_w32(rtl8380_sds_reset[2 * i + 1], rtl8380_sds_reset[2 * i]);
+ i++;
+ }
+
+ i = 0;
+ while (rtl8380_sds_release_reset[2 * i]) {
+ sw_w32(rtl8380_sds_release_reset[2 * i + 1], rtl8380_sds_release_reset[2 * i]);
+ i++;
+ }
+
+ pr_info("SDS power down value now: %x\n", sw_r32(RTL838X_SDS_CFG_REG));
+ sw_w32(sds_conf_value, RTL838X_SDS_CFG_REG);
+
+ pr_info("Configuration of SERDES done\n");
+
+ return 0;
+}
+
+static int rtl8390_configure_serdes(struct phy_device *phydev)
+{
+ phydev_info(phydev, "Detected internal RTL8390 SERDES\n");
+
+ /* In autoneg state, force link, set SR4_CFG_EN_LINK_FIB1G */
+ sw_w32_mask(0, 1 << 18, RTL839X_SDS12_13_XSG0 + 0x0a);
+
+ /* Disable EEE: Clear FRE16_EEE_RSG_FIB1G, FRE16_EEE_STD_FIB1G,
+ * FRE16_C1_PWRSAV_EN_FIB1G, FRE16_C2_PWRSAV_EN_FIB1G
+ * and FRE16_EEE_QUIET_FIB1G
+ */
+ sw_w32_mask(0x1f << 10, 0, RTL839X_SDS12_13_XSG0 + 0xe0);
+
+ return 0;
+}
+
+void rtl9300_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int start_bit, u32 v)
+{
+ int l = end_bit - start_bit + 1;
+ u32 data = v;
+
+ if (l < 32) {
+ u32 mask = BIT(l) - 1;
+
+ data = rtl930x_read_sds_phy(sds, page, reg);
+ data &= ~(mask << start_bit);
+ data |= (v & mask) << start_bit;
+ }
+
+ rtl930x_write_sds_phy(sds, page, reg, data);
+}
+
+u32 rtl9300_sds_field_r(int sds, u32 page, u32 reg, int end_bit, int start_bit)
+{
+ int l = end_bit - start_bit + 1;
+ u32 v = rtl930x_read_sds_phy(sds, page, reg);
+
+ if (l >= 32)
+ return v;
+
+ return (v >> start_bit) & (BIT(l) - 1);
+}
+
+/* Read the link and speed status of the internal SerDes of the RTL9300
+ */
+static int rtl9300_read_status(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int phy_addr = phydev->mdio.addr;
+ struct device_node *dn;
+ u32 sds_num = 0, status, latch_status, mode;
+
+ if (dev->of_node) {
+ dn = dev->of_node;
+
+ if (of_property_read_u32(dn, "sds", &sds_num))
+ sds_num = -1;
+ pr_info("%s: Port %d, SerDes is %d\n", __func__, phy_addr, sds_num);
+ } else {
+ dev_err(dev, "No DT node.\n");
+ return -EINVAL;
+ }
+
+ if (sds_num < 0)
+ return 0;
+
+ mode = rtl9300_sds_mode_get(sds_num);
+ pr_info("%s got SDS mode %02x\n", __func__, mode);
+ if (mode == RTL930X_SDS_OFF)
+ mode = rtl9300_sds_field_r(sds_num, 0x1f, 9, 11, 7);
+ if (mode == RTL930X_SDS_MODE_10GBASER) { /* 10GR mode */
+ status = rtl9300_sds_field_r(sds_num, 0x5, 0, 12, 12);
+ latch_status = rtl9300_sds_field_r(sds_num, 0x4, 1, 2, 2);
+ status |= rtl9300_sds_field_r(sds_num, 0x5, 0, 12, 12);
+ latch_status |= rtl9300_sds_field_r(sds_num, 0x4, 1, 2, 2);
+ } else {
+ status = rtl9300_sds_field_r(sds_num, 0x1, 29, 8, 0);
+ latch_status = rtl9300_sds_field_r(sds_num, 0x1, 30, 8, 0);
+ status |= rtl9300_sds_field_r(sds_num, 0x1, 29, 8, 0);
+ latch_status |= rtl9300_sds_field_r(sds_num, 0x1, 30, 8, 0);
+ }
+
+ pr_info("%s link status: status: %d, latch %d\n", __func__, status, latch_status);
+
+ if (latch_status) {
+ phydev->link = true;
+ if (mode == RTL930X_SDS_MODE_10GBASER) {
+ phydev->speed = SPEED_10000;
+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
+ } else {
+ phydev->speed = SPEED_1000;
+ phydev->interface = PHY_INTERFACE_MODE_1000BASEX;
+ }
+
+ phydev->duplex = DUPLEX_FULL;
+ }
+
+ return 0;
+}
+
+void rtl930x_sds_rx_rst(int sds_num, phy_interface_t phy_if)
+{
+ int page = 0x2e; /* 10GR and USXGMII */
+
+ if (phy_if == PHY_INTERFACE_MODE_1000BASEX)
+ page = 0x24;
+
+ rtl9300_sds_field_w(sds_num, page, 0x15, 4, 4, 0x1);
+ mdelay(5);
+ rtl9300_sds_field_w(sds_num, page, 0x15, 4, 4, 0x0);
+}
+
+/* Force PHY modes on 10GBit Serdes
+ */
+void rtl9300_force_sds_mode(int sds, phy_interface_t phy_if)
+{
+ int lc_value;
+ int sds_mode;
+ bool lc_on;
+ int lane_0 = (sds % 2) ? sds - 1 : sds;
+ u32 v;
+
+ pr_info("%s: SDS: %d, mode %d\n", __func__, sds, phy_if);
+ switch (phy_if) {
+ case PHY_INTERFACE_MODE_SGMII:
+ sds_mode = RTL930X_SDS_MODE_SGMII;
+ lc_on = false;
+ lc_value = 0x1;
+ break;
+
+ case PHY_INTERFACE_MODE_HSGMII:
+ sds_mode = RTL930X_SDS_MODE_HSGMII;
+ lc_value = 0x3;
+ /* Configure LC */
+ break;
+
+ case PHY_INTERFACE_MODE_1000BASEX:
+ sds_mode = RTL930X_SDS_MODE_1000BASEX;
+ lc_on = false;
+ break;
+
+ case PHY_INTERFACE_MODE_2500BASEX:
+ sds_mode = RTL930X_SDS_MODE_2500BASEX;
+ lc_value = 0x3;
+ /* Configure LC */
+ break;
+
+ case PHY_INTERFACE_MODE_10GBASER:
+ sds_mode = RTL930X_SDS_MODE_10GBASER;
+ lc_on = true;
+ lc_value = 0x5;
+ break;
+
+ case PHY_INTERFACE_MODE_NA:
+ /* This will disable SerDes */
+ sds_mode = RTL930X_SDS_OFF;
+ break;
+
+ default:
+ pr_err("%s: unknown serdes mode: %s\n",
+ __func__, phy_modes(phy_if));
+ return;
+ }
+
+ pr_info("%s --------------------- serdes %d forcing to %x ...\n", __func__, sds, sds_mode);
+ /* Power down SerDes */
+ rtl9300_sds_field_w(sds, 0x20, 0, 7, 6, 0x3);
+ if (sds == 5) pr_info("%s after %x\n", __func__, rtl930x_read_sds_phy(sds, 0x20, 0));
+
+ if (sds == 5) pr_info("%s a %x\n", __func__, rtl930x_read_sds_phy(sds, 0x1f, 9));
+ /* Force mode enable */
+ rtl9300_sds_field_w(sds, 0x1f, 9, 6, 6, 0x1);
+ if (sds == 5) pr_info("%s b %x\n", __func__, rtl930x_read_sds_phy(sds, 0x1f, 9));
+
+ /* SerDes off */
+ rtl9300_sds_field_w(sds, 0x1f, 9, 11, 7, RTL930X_SDS_OFF);
+
+ if (phy_if == PHY_INTERFACE_MODE_NA)
+ return;
+
+ if (sds == 5) pr_info("%s c %x\n", __func__, rtl930x_read_sds_phy(sds, 0x20, 18));
+ /* Enable LC and ring */
+ rtl9300_sds_field_w(lane_0, 0x20, 18, 3, 0, 0xf);
+
+ if (sds == lane_0)
+ rtl9300_sds_field_w(lane_0, 0x20, 18, 5, 4, 0x1);
+ else
+ rtl9300_sds_field_w(lane_0, 0x20, 18, 7, 6, 0x1);
+
+ rtl9300_sds_field_w(sds, 0x20, 0, 5, 4, 0x3);
+
+ if (lc_on)
+ rtl9300_sds_field_w(lane_0, 0x20, 18, 11, 8, lc_value);
+ else
+ rtl9300_sds_field_w(lane_0, 0x20, 18, 15, 12, lc_value);
+
+ /* Force analog LC & ring on */
+ rtl9300_sds_field_w(lane_0, 0x21, 11, 3, 0, 0xf);
+
+ v = lc_on ? 0x3 : 0x1;
+
+ if (sds == lane_0)
+ rtl9300_sds_field_w(lane_0, 0x20, 18, 5, 4, v);
+ else
+ rtl9300_sds_field_w(lane_0, 0x20, 18, 7, 6, v);
+
+ /* Force SerDes mode */
+ rtl9300_sds_field_w(sds, 0x1f, 9, 6, 6, 1);
+ rtl9300_sds_field_w(sds, 0x1f, 9, 11, 7, sds_mode);
+
+ /* Toggle LC or Ring */
+ for (int i = 0; i < 20; i++) {
+ u32 cr_0, cr_1, cr_2;
+ u32 m_bit, l_bit;
+
+ mdelay(200);
+
+ rtl930x_write_sds_phy(lane_0, 0x1f, 2, 53);
+
+ m_bit = (lane_0 == sds) ? (4) : (5);
+ l_bit = (lane_0 == sds) ? (4) : (5);
+
+ cr_0 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit);
+ mdelay(10);
+ cr_1 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit);
+ mdelay(10);
+ cr_2 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit);
+
+ if (cr_0 && cr_1 && cr_2) {
+ u32 t;
+
+ if (phy_if != PHY_INTERFACE_MODE_10GBASER)
+ break;
+
+ t = rtl9300_sds_field_r(sds, 0x6, 0x1, 2, 2);
+ rtl9300_sds_field_w(sds, 0x6, 0x1, 2, 2, 0x1);
+
+ /* Reset FSM */
+ rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x1);
+ mdelay(10);
+ rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x0);
+ mdelay(10);
+
+ /* Need to read this twice */
+ v = rtl9300_sds_field_r(sds, 0x5, 0, 12, 12);
+ v = rtl9300_sds_field_r(sds, 0x5, 0, 12, 12);
+
+ rtl9300_sds_field_w(sds, 0x6, 0x1, 2, 2, t);
+
+ /* Reset FSM again */
+ rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x1);
+ mdelay(10);
+ rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x0);
+ mdelay(10);
+
+ if (v == 1)
+ break;
+ }
+
+ m_bit = (phy_if == PHY_INTERFACE_MODE_10GBASER) ? 3 : 1;
+ l_bit = (phy_if == PHY_INTERFACE_MODE_10GBASER) ? 2 : 0;
+
+ rtl9300_sds_field_w(lane_0, 0x21, 11, m_bit, l_bit, 0x2);
+ mdelay(10);
+ rtl9300_sds_field_w(lane_0, 0x21, 11, m_bit, l_bit, 0x3);
+ }
+
+ rtl930x_sds_rx_rst(sds, phy_if);
+
+ /* Re-enable power */
+ rtl9300_sds_field_w(sds, 0x20, 0, 7, 6, 0);
+
+ pr_info("%s --------------------- serdes %d forced to %x DONE\n", __func__, sds, sds_mode);
+}
+
+void rtl9300_sds_tx_config(int sds, phy_interface_t phy_if)
+{
+ /* parameters: rtl9303_80G_txParam_s2 */
+ int impedance = 0x8;
+ int pre_amp = 0x2;
+ int main_amp = 0x9;
+ int post_amp = 0x2;
+ int pre_en = 0x1;
+ int post_en = 0x1;
+ int page;
+
+ switch(phy_if) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ pre_amp = 0x1;
+ main_amp = 0x9;
+ post_amp = 0x1;
+ page = 0x25;
+ break;
+ case PHY_INTERFACE_MODE_HSGMII:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ pre_amp = 0;
+ post_amp = 0x8;
+ pre_en = 0;
+ page = 0x29;
+ break;
+ case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_XGMII:
+ pre_en = 0;
+ pre_amp = 0;
+ main_amp = 0x10;
+ post_amp = 0;
+ post_en = 0;
+ page = 0x2f;
+ break;
+ default:
+ pr_err("%s: unsupported PHY mode\n", __func__);
+ return;
+ }
+
+ rtl9300_sds_field_w(sds, page, 0x01, 15, 11, pre_amp);
+ rtl9300_sds_field_w(sds, page, 0x06, 4, 0, post_amp);
+ rtl9300_sds_field_w(sds, page, 0x07, 0, 0, pre_en);
+ rtl9300_sds_field_w(sds, page, 0x07, 3, 3, post_en);
+ rtl9300_sds_field_w(sds, page, 0x07, 8, 4, main_amp);
+ rtl9300_sds_field_w(sds, page, 0x18, 15, 12, impedance);
+}
+
+/* Wait for clock ready, this assumes the SerDes is in XGMII mode
+ * timeout is in ms
+ */
+int rtl9300_sds_clock_wait(int timeout)
+{
+ u32 v;
+ unsigned long start = jiffies;
+
+ do {
+ rtl9300_sds_field_w(2, 0x1f, 0x2, 15, 0, 53);
+ v = rtl9300_sds_field_r(2, 0x1f, 20, 5, 4);
+ if (v == 3)
+ return 0;
+ } while (jiffies < start + (HZ / 1000) * timeout);
+
+ return 1;
+}
+
+void rtl9300_serdes_mac_link_config(int sds, bool tx_normal, bool rx_normal)
+{
+ u32 v10, v1;
+
+ v10 = rtl930x_read_sds_phy(sds, 6, 2); /* 10GBit, page 6, reg 2 */
+ v1 = rtl930x_read_sds_phy(sds, 0, 0); /* 1GBit, page 0, reg 0 */
+ pr_info("%s: registers before %08x %08x\n", __func__, v10, v1);
+
+ v10 &= ~(BIT(13) | BIT(14));
+ v1 &= ~(BIT(8) | BIT(9));
+
+ v10 |= rx_normal ? 0 : BIT(13);
+ v1 |= rx_normal ? 0 : BIT(9);
+
+ v10 |= tx_normal ? 0 : BIT(14);
+ v1 |= tx_normal ? 0 : BIT(8);
+
+ rtl930x_write_sds_phy(sds, 6, 2, v10);
+ rtl930x_write_sds_phy(sds, 0, 0, v1);
+
+ v10 = rtl930x_read_sds_phy(sds, 6, 2);
+ v1 = rtl930x_read_sds_phy(sds, 0, 0);
+ pr_info("%s: registers after %08x %08x\n", __func__, v10, v1);
+}
+
+void rtl9300_sds_rxcal_dcvs_manual(u32 sds_num, u32 dcvs_id, bool manual, u32 dvcs_list[])
+{
+ if (manual) {
+ switch(dcvs_id) {
+ case 0:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 14, 14, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 5, 5, dvcs_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 4, 0, dvcs_list[1]);
+ break;
+ case 1:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 13, 13, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 15, 15, dvcs_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 14, 11, dvcs_list[1]);
+ break;
+ case 2:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 12, 12, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 10, 10, dvcs_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 9, 6, dvcs_list[1]);
+ break;
+ case 3:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 11, 11, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 5, 5, dvcs_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 4, 1, dvcs_list[1]);
+ break;
+ case 4:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 15, 15, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 10, 10, dvcs_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 9, 6, dvcs_list[1]);
+ break;
+ case 5:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x02, 11, 11, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 4, 4, dvcs_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 3, 0, dvcs_list[1]);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch(dcvs_id) {
+ case 0:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 14, 14, 0x0);
+ break;
+ case 1:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 13, 13, 0x0);
+ break;
+ case 2:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 12, 12, 0x0);
+ break;
+ case 3:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 11, 11, 0x0);
+ break;
+ case 4:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 15, 15, 0x0);
+ break;
+ case 5:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x02, 11, 11, 0x0);
+ break;
+ default:
+ break;
+ }
+ mdelay(1);
+ }
+}
+
+void rtl9300_sds_rxcal_dcvs_get(u32 sds_num, u32 dcvs_id, u32 dcvs_list[])
+{
+ u32 dcvs_sign_out = 0, dcvs_coef_bin = 0;
+ bool dcvs_manual;
+
+ if (!(sds_num % 2))
+ rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
+ else
+ rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
+
+ /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
+
+ /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
+ rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
+
+ switch(dcvs_id) {
+ case 0:
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x22);
+ mdelay(1);
+
+ /* ##DCVS0 Read Out */
+ dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
+ dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
+ dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 14, 14);
+ break;
+
+ case 1:
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x23);
+ mdelay(1);
+
+ /* ##DCVS0 Read Out */
+ dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
+ dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
+ dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 13, 13);
+ break;
+
+ case 2:
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x24);
+ mdelay(1);
+
+ /* ##DCVS0 Read Out */
+ dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
+ dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
+ dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 12, 12);
+ break;
+ case 3:
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x25);
+ mdelay(1);
+
+ /* ##DCVS0 Read Out */
+ dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
+ dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
+ dcvs_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 11, 11);
+ break;
+
+ case 4:
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x2c);
+ mdelay(1);
+
+ /* ##DCVS0 Read Out */
+ dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
+ dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
+ dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x01, 15, 15);
+ break;
+
+ case 5:
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x2d);
+ mdelay(1);
+
+ /* ##DCVS0 Read Out */
+ dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4);
+ dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0);
+ dcvs_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x02, 11, 11);
+ break;
+
+ default:
+ break;
+ }
+
+ if (dcvs_sign_out)
+ pr_info("%s DCVS %u Sign: -", __func__, dcvs_id);
+ else
+ pr_info("%s DCVS %u Sign: +", __func__, dcvs_id);
+
+ pr_info("DCVS %u even coefficient = %u", dcvs_id, dcvs_coef_bin);
+ pr_info("DCVS %u manual = %u", dcvs_id, dcvs_manual);
+
+ dcvs_list[0] = dcvs_sign_out;
+ dcvs_list[1] = dcvs_coef_bin;
+}
+
+void rtl9300_sds_rxcal_leq_manual(u32 sds_num, bool manual, u32 leq_gray)
+{
+ if (manual) {
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x18, 15, 15, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x16, 14, 10, leq_gray);
+ } else {
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x18, 15, 15, 0x0);
+ mdelay(100);
+ }
+}
+
+void rtl9300_sds_rxcal_leq_offset_manual(u32 sds_num, bool manual, u32 offset)
+{
+ if (manual) {
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 6, 2, offset);
+ } else {
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 6, 2, offset);
+ mdelay(1);
+ }
+}
+
+#define GRAY_BITS 5
+u32 rtl9300_sds_rxcal_gray_to_binary(u32 gray_code)
+{
+ int i, j, m;
+ u32 g[GRAY_BITS];
+ u32 c[GRAY_BITS];
+ u32 leq_binary = 0;
+
+ for(i = 0; i < GRAY_BITS; i++)
+ g[i] = (gray_code & BIT(i)) >> i;
+
+ m = GRAY_BITS - 1;
+
+ c[m] = g[m];
+
+ for(i = 0; i < m; i++) {
+ c[i] = g[i];
+ for(j = i + 1; j < GRAY_BITS; j++)
+ c[i] = c[i] ^ g[j];
+ }
+
+ for(i = 0; i < GRAY_BITS; i++)
+ leq_binary += c[i] << i;
+
+ return leq_binary;
+}
+
+u32 rtl9300_sds_rxcal_leq_read(int sds_num)
+{
+ u32 leq_gray, leq_bin;
+ bool leq_manual;
+
+ if (!(sds_num % 2))
+ rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
+ else
+ rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
+
+ /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
+
+ /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[0 1 x x x x] */
+ rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x10);
+ mdelay(1);
+
+ /* ##LEQ Read Out */
+ leq_gray = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 7, 3);
+ leq_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x18, 15, 15);
+ leq_bin = rtl9300_sds_rxcal_gray_to_binary(leq_gray);
+
+ pr_info("LEQ_gray: %u, LEQ_bin: %u", leq_gray, leq_bin);
+ pr_info("LEQ manual: %u", leq_manual);
+
+ return leq_bin;
+}
+
+void rtl9300_sds_rxcal_vth_manual(u32 sds_num, bool manual, u32 vth_list[])
+{
+ if (manual) {
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, 13, 13, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x13, 5, 3, vth_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x13, 2, 0, vth_list[1]);
+ } else {
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, 13, 13, 0x0);
+ mdelay(10);
+ }
+}
+
+void rtl9300_sds_rxcal_vth_get(u32 sds_num, u32 vth_list[])
+{
+ u32 vth_manual;
+
+ /* ##Page0x1F, Reg0x02[15 0], REG_DBGO_SEL=[0x002F]; */ /* Lane0 */
+ /* ##Page0x1F, Reg0x02[15 0], REG_DBGO_SEL=[0x0031]; */ /* Lane1 */
+ if (!(sds_num % 2))
+ rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
+ else
+ rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
+
+ /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
+ /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
+ rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
+ /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 0 0] */
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xc);
+
+ mdelay(1);
+
+ /* ##VthP & VthN Read Out */
+ vth_list[0] = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 2, 0); /* v_thp set bin */
+ vth_list[1] = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 3); /* v_thn set bin */
+
+ pr_info("vth_set_bin = %d", vth_list[0]);
+ pr_info("vth_set_bin = %d", vth_list[1]);
+
+ vth_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, 13, 13);
+ pr_info("Vth Maunal = %d", vth_manual);
+}
+
+void rtl9300_sds_rxcal_tap_manual(u32 sds_num, int tap_id, bool manual, u32 tap_list[])
+{
+ if (manual) {
+ switch(tap_id) {
+ case 0:
+ /* ##REG0_LOAD_IN_INIT[0]=1; REG0_TAP0_INIT[5:0]=Tap0_Value */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 5, 5, tap_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 4, 0, tap_list[1]);
+ break;
+ case 1:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x21, 0x07, 6, 6, tap_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 11, 6, tap_list[1]);
+ rtl9300_sds_field_w(sds_num, 0x21, 0x07, 5, 5, tap_list[2]);
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x12, 5, 0, tap_list[3]);
+ break;
+ case 2:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 5, 5, tap_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 4, 0, tap_list[1]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 11, 11, tap_list[2]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 10, 6, tap_list[3]);
+ break;
+ case 3:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 5, 5, tap_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 4, 0, tap_list[1]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 5, 5, tap_list[2]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 4, 0, tap_list[3]);
+ break;
+ case 4:
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1);
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x01, 5, 5, tap_list[0]);
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x01, 4, 0, tap_list[1]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 11, 11, tap_list[2]);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 10, 6, tap_list[3]);
+ break;
+ default:
+ break;
+ }
+ } else {
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x0);
+ mdelay(10);
+ }
+}
+
+void rtl9300_sds_rxcal_tap_get(u32 sds_num, u32 tap_id, u32 tap_list[])
+{
+ u32 tap0_sign_out;
+ u32 tap0_coef_bin;
+ u32 tap_sign_out_even;
+ u32 tap_coef_bin_even;
+ u32 tap_sign_out_odd;
+ u32 tap_coef_bin_odd;
+ bool tap_manual;
+
+ if (!(sds_num % 2))
+ rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
+ else
+ rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31);
+
+ /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
+ /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
+ rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
+
+ if (!tap_id) {
+ /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 0 0 1] */
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0);
+ /* ##Tap1 Even Read Out */
+ mdelay(1);
+ tap0_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5);
+ tap0_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0);
+
+ if (tap0_sign_out == 1)
+ pr_info("Tap0 Sign : -");
+ else
+ pr_info("Tap0 Sign : +");
+
+ pr_info("tap0_coef_bin = %d", tap0_coef_bin);
+
+ tap_list[0] = tap0_sign_out;
+ tap_list[1] = tap0_coef_bin;
+
+ tap_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, 7, 7);
+ pr_info("tap0 manual = %u",tap_manual);
+ } else {
+ /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 0 0 1] */
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, tap_id);
+ mdelay(1);
+ /* ##Tap1 Even Read Out */
+ tap_sign_out_even = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5);
+ tap_coef_bin_even = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0);
+
+ /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 1 1 0] */
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, (tap_id + 5));
+ /* ##Tap1 Odd Read Out */
+ tap_sign_out_odd = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5);
+ tap_coef_bin_odd = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0);
+
+ if (tap_sign_out_even == 1)
+ pr_info("Tap %u even sign: -", tap_id);
+ else
+ pr_info("Tap %u even sign: +", tap_id);
+
+ pr_info("Tap %u even coefficient = %u", tap_id, tap_coef_bin_even);
+
+ if (tap_sign_out_odd == 1)
+ pr_info("Tap %u odd sign: -", tap_id);
+ else
+ pr_info("Tap %u odd sign: +", tap_id);
+
+ pr_info("Tap %u odd coefficient = %u", tap_id,tap_coef_bin_odd);
+
+ tap_list[0] = tap_sign_out_even;
+ tap_list[1] = tap_coef_bin_even;
+ tap_list[2] = tap_sign_out_odd;
+ tap_list[3] = tap_coef_bin_odd;
+
+ tap_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7);
+ pr_info("tap %u manual = %d",tap_id, tap_manual);
+ }
+}
+
+void rtl9300_do_rx_calibration_1(int sds, phy_interface_t phy_mode)
+{
+ /* From both rtl9300_rxCaliConf_serdes_myParam and rtl9300_rxCaliConf_phy_myParam */
+ int tap0_init_val = 0x1f; /* Initial Decision Fed Equalizer 0 tap */
+ int vth_min = 0x0;
+
+ pr_info("start_1.1.1 initial value for sds %d\n", sds);
+ rtl930x_write_sds_phy(sds, 6, 0, 0);
+
+ /* FGCAL */
+ rtl9300_sds_field_w(sds, 0x2e, 0x01, 14, 14, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x1c, 10, 5, 0x20);
+ rtl9300_sds_field_w(sds, 0x2f, 0x02, 0, 0, 0x01);
+
+ /* DCVS */
+ rtl9300_sds_field_w(sds, 0x2e, 0x1e, 14, 11, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x01, 15, 15, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x02, 11, 11, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x1c, 4, 0, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x1d, 15, 11, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x1d, 10, 6, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x1d, 5, 1, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x02, 10, 6, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x11, 4, 0, 0x00);
+ rtl9300_sds_field_w(sds, 0x2f, 0x00, 3, 0, 0x0f);
+ rtl9300_sds_field_w(sds, 0x2e, 0x04, 6, 6, 0x01);
+ rtl9300_sds_field_w(sds, 0x2e, 0x04, 7, 7, 0x01);
+
+ /* LEQ (Long Term Equivalent signal level) */
+ rtl9300_sds_field_w(sds, 0x2e, 0x16, 14, 8, 0x00);
+
+ /* DFE (Decision Fed Equalizer) */
+ rtl9300_sds_field_w(sds, 0x2f, 0x03, 5, 0, tap0_init_val);
+ rtl9300_sds_field_w(sds, 0x2e, 0x09, 11, 6, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x09, 5, 0, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x0a, 5, 0, 0x00);
+ rtl9300_sds_field_w(sds, 0x2f, 0x01, 5, 0, 0x00);
+ rtl9300_sds_field_w(sds, 0x2f, 0x12, 5, 0, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x0a, 11, 6, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x06, 5, 0, 0x00);
+ rtl9300_sds_field_w(sds, 0x2f, 0x01, 5, 0, 0x00);
+
+ /* Vth */
+ rtl9300_sds_field_w(sds, 0x2e, 0x13, 5, 3, 0x07);
+ rtl9300_sds_field_w(sds, 0x2e, 0x13, 2, 0, 0x07);
+ rtl9300_sds_field_w(sds, 0x2f, 0x0b, 5, 3, vth_min);
+
+ pr_info("end_1.1.1 --\n");
+
+ pr_info("start_1.1.2 Load DFE init. value\n");
+
+ rtl9300_sds_field_w(sds, 0x2e, 0x0f, 13, 7, 0x7f);
+
+ pr_info("end_1.1.2\n");
+
+ pr_info("start_1.1.3 disable LEQ training,enable DFE clock\n");
+
+ rtl9300_sds_field_w(sds, 0x2e, 0x17, 7, 7, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x17, 6, 2, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x0c, 8, 8, 0x00);
+ rtl9300_sds_field_w(sds, 0x2e, 0x0b, 4, 4, 0x01);
+ rtl9300_sds_field_w(sds, 0x2e, 0x12, 14, 14, 0x00);
+ rtl9300_sds_field_w(sds, 0x2f, 0x02, 15, 15, 0x00);
+
+ pr_info("end_1.1.3 --\n");
+
+ pr_info("start_1.1.4 offset cali setting\n");
+
+ rtl9300_sds_field_w(sds, 0x2e, 0x0f, 15, 14, 0x03);
+
+ pr_info("end_1.1.4\n");
+
+ pr_info("start_1.1.5 LEQ and DFE setting\n");
+
+ /* TODO: make this work for DAC cables of different lengths */
+ /* For a 10GBit serdes wit Fibre, SDS 8 or 9 */
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER || PHY_INTERFACE_MODE_1000BASEX)
+ rtl9300_sds_field_w(sds, 0x2e, 0x16, 3, 2, 0x02);
+ else
+ pr_err("%s not PHY-based or SerDes, implement DAC!\n", __func__);
+
+ /* No serdes, check for Aquantia PHYs */
+ rtl9300_sds_field_w(sds, 0x2e, 0x16, 3, 2, 0x02);
+
+ rtl9300_sds_field_w(sds, 0x2e, 0x0f, 6, 0, 0x5f);
+ rtl9300_sds_field_w(sds, 0x2f, 0x05, 7, 2, 0x1f);
+ rtl9300_sds_field_w(sds, 0x2e, 0x19, 9, 5, 0x1f);
+ rtl9300_sds_field_w(sds, 0x2f, 0x0b, 15, 9, 0x3c);
+ rtl9300_sds_field_w(sds, 0x2e, 0x0b, 1, 0, 0x03);
+
+ pr_info("end_1.1.5\n");
+}
+
+void rtl9300_do_rx_calibration_2_1(u32 sds_num)
+{
+ pr_info("start_1.2.1 ForegroundOffsetCal_Manual\n");
+
+ /* Gray config endis to 1 */
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x02, 2, 2, 0x01);
+
+ /* ForegroundOffsetCal_Manual(auto mode) */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 14, 14, 0x00);
+
+ pr_info("end_1.2.1");
+}
+
+void rtl9300_do_rx_calibration_2_2(int sds_num)
+{
+ /* Force Rx-Run = 0 */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 8, 8, 0x0);
+
+ rtl930x_sds_rx_rst(sds_num, PHY_INTERFACE_MODE_10GBASER);
+}
+
+void rtl9300_do_rx_calibration_2_3(int sds_num)
+{
+ u32 fgcal_binary, fgcal_gray;
+ u32 offset_range;
+
+ pr_info("start_1.2.3 Foreground Calibration\n");
+
+ while(1) {
+ if (!(sds_num % 2))
+ rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f);
+ else
+ rtl930x_write_sds_phy(sds_num -1 , 0x1f, 0x2, 0x31);
+
+ /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1);
+ /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */
+ rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20);
+ /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 1 1] */
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xf);
+ /* ##FGCAL read gray */
+ fgcal_gray = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 0);
+ /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 1 0] */
+ rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xe);
+ /* ##FGCAL read binary */
+ fgcal_binary = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 0);
+
+ pr_info("%s: fgcal_gray: %d, fgcal_binary %d\n",
+ __func__, fgcal_gray, fgcal_binary);
+
+ offset_range = rtl9300_sds_field_r(sds_num, 0x2e, 0x15, 15, 14);
+
+ if (fgcal_binary > 60 || fgcal_binary < 3) {
+ if (offset_range == 3) {
+ pr_info("%s: Foreground Calibration result marginal!", __func__);
+ break;
+ } else {
+ offset_range++;
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 15, 14, offset_range);
+ rtl9300_do_rx_calibration_2_2(sds_num);
+ }
+ } else {
+ break;
+ }
+ }
+ pr_info("%s: end_1.2.3\n", __func__);
+}
+
+void rtl9300_do_rx_calibration_2(int sds)
+{
+ rtl930x_sds_rx_rst(sds, PHY_INTERFACE_MODE_10GBASER);
+ rtl9300_do_rx_calibration_2_1(sds);
+ rtl9300_do_rx_calibration_2_2(sds);
+ rtl9300_do_rx_calibration_2_3(sds);
+}
+
+void rtl9300_sds_rxcal_3_1(int sds_num, phy_interface_t phy_mode)
+{
+ pr_info("start_1.3.1");
+
+ /* ##1.3.1 */
+ if (phy_mode != PHY_INTERFACE_MODE_10GBASER && phy_mode != PHY_INTERFACE_MODE_1000BASEX)
+ rtl9300_sds_field_w(sds_num, 0x2e, 0xc, 8, 8, 0);
+
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x0);
+ rtl9300_sds_rxcal_leq_manual(sds_num, false, 0);
+
+ pr_info("end_1.3.1");
+}
+
+void rtl9300_sds_rxcal_3_2(int sds_num, phy_interface_t phy_mode)
+{
+ u32 sum10 = 0, avg10, int10;
+ int dac_long_cable_offset;
+ bool eq_hold_enabled;
+ int i;
+
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX) {
+ /* rtl9300_rxCaliConf_serdes_myParam */
+ dac_long_cable_offset = 3;
+ eq_hold_enabled = true;
+ } else {
+ /* rtl9300_rxCaliConf_phy_myParam */
+ dac_long_cable_offset = 0;
+ eq_hold_enabled = false;
+ }
+
+ if (phy_mode == PHY_INTERFACE_MODE_1000BASEX)
+ pr_warn("%s: LEQ only valid for 10GR!\n", __func__);
+
+ pr_info("start_1.3.2");
+
+ for(i = 0; i < 10; i++) {
+ sum10 += rtl9300_sds_rxcal_leq_read(sds_num);
+ mdelay(10);
+ }
+
+ avg10 = (sum10 / 10) + (((sum10 % 10) >= 5) ? 1 : 0);
+ int10 = sum10 / 10;
+
+ pr_info("sum10:%u, avg10:%u, int10:%u", sum10, avg10, int10);
+
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX) {
+ if (dac_long_cable_offset) {
+ rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, dac_long_cable_offset);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, eq_hold_enabled);
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER)
+ rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10);
+ } else {
+ if (sum10 >= 5) {
+ rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, 3);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x1);
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER)
+ rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10);
+ } else {
+ rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, 0);
+ rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x1);
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER)
+ rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10);
+ }
+ }
+ }
+
+ pr_info("Sds:%u LEQ = %u",sds_num, rtl9300_sds_rxcal_leq_read(sds_num));
+
+ pr_info("end_1.3.2");
+}
+
+void rtl9300_do_rx_calibration_3(int sds_num, phy_interface_t phy_mode)
+{
+ rtl9300_sds_rxcal_3_1(sds_num, phy_mode);
+
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX)
+ rtl9300_sds_rxcal_3_2(sds_num, phy_mode);
+}
+
+void rtl9300_do_rx_calibration_4_1(int sds_num)
+{
+ u32 vth_list[2] = {0, 0};
+ u32 tap0_list[4] = {0, 0, 0, 0};
+
+ pr_info("start_1.4.1");
+
+ /* ##1.4.1 */
+ rtl9300_sds_rxcal_vth_manual(sds_num, false, vth_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 0, false, tap0_list);
+ mdelay(200);
+
+ pr_info("end_1.4.1");
+}
+
+void rtl9300_do_rx_calibration_4_2(u32 sds_num)
+{
+ u32 vth_list[2];
+ u32 tap_list[4];
+
+ pr_info("start_1.4.2");
+
+ rtl9300_sds_rxcal_vth_get(sds_num, vth_list);
+ rtl9300_sds_rxcal_vth_manual(sds_num, true, vth_list);
+
+ mdelay(100);
+
+ rtl9300_sds_rxcal_tap_get(sds_num, 0, tap_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 0, true, tap_list);
+
+ pr_info("end_1.4.2");
+}
+
+void rtl9300_do_rx_calibration_4(u32 sds_num)
+{
+ rtl9300_do_rx_calibration_4_1(sds_num);
+ rtl9300_do_rx_calibration_4_2(sds_num);
+}
+
+void rtl9300_do_rx_calibration_5_2(u32 sds_num)
+{
+ u32 tap1_list[4] = {0};
+ u32 tap2_list[4] = {0};
+ u32 tap3_list[4] = {0};
+ u32 tap4_list[4] = {0};
+
+ pr_info("start_1.5.2");
+
+ rtl9300_sds_rxcal_tap_manual(sds_num, 1, false, tap1_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 2, false, tap2_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 3, false, tap3_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 4, false, tap4_list);
+
+ mdelay(30);
+
+ pr_info("end_1.5.2");
+}
+
+void rtl9300_do_rx_calibration_5(u32 sds_num, phy_interface_t phy_mode)
+{
+ if (phy_mode == PHY_INTERFACE_MODE_10GBASER) /* dfeTap1_4Enable true */
+ rtl9300_do_rx_calibration_5_2(sds_num);
+}
+
+
+void rtl9300_do_rx_calibration_dfe_disable(u32 sds_num)
+{
+ u32 tap1_list[4] = {0};
+ u32 tap2_list[4] = {0};
+ u32 tap3_list[4] = {0};
+ u32 tap4_list[4] = {0};
+
+ rtl9300_sds_rxcal_tap_manual(sds_num, 1, true, tap1_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 2, true, tap2_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 3, true, tap3_list);
+ rtl9300_sds_rxcal_tap_manual(sds_num, 4, true, tap4_list);
+
+ mdelay(10);
+}
+
+void rtl9300_do_rx_calibration(int sds, phy_interface_t phy_mode)
+{
+ u32 latch_sts;
+
+ rtl9300_do_rx_calibration_1(sds, phy_mode);
+ rtl9300_do_rx_calibration_2(sds);
+ rtl9300_do_rx_calibration_4(sds);
+ rtl9300_do_rx_calibration_5(sds, phy_mode);
+ mdelay(20);
+
+ /* Do this only for 10GR mode, SDS active in mode 0x1a */
+ if (rtl9300_sds_field_r(sds, 0x1f, 9, 11, 7) == RTL930X_SDS_MODE_10GBASER) {
+ pr_info("%s: SDS enabled\n", __func__);
+ latch_sts = rtl9300_sds_field_r(sds, 0x4, 1, 2, 2);
+ mdelay(1);
+ latch_sts = rtl9300_sds_field_r(sds, 0x4, 1, 2, 2);
+ if (latch_sts) {
+ rtl9300_do_rx_calibration_dfe_disable(sds);
+ rtl9300_do_rx_calibration_4(sds);
+ rtl9300_do_rx_calibration_5(sds, phy_mode);
+ }
+ }
+}
+
+int rtl9300_sds_sym_err_reset(int sds_num, phy_interface_t phy_mode)
+{
+ switch (phy_mode) {
+ case PHY_INTERFACE_MODE_XGMII:
+ break;
+
+ case PHY_INTERFACE_MODE_10GBASER:
+ /* Read twice to clear */
+ rtl930x_read_sds_phy(sds_num, 5, 1);
+ rtl930x_read_sds_phy(sds_num, 5, 1);
+ break;
+
+ case PHY_INTERFACE_MODE_1000BASEX:
+ rtl9300_sds_field_w(sds_num, 0x1, 24, 2, 0, 0);
+ rtl9300_sds_field_w(sds_num, 0x1, 3, 15, 8, 0);
+ rtl9300_sds_field_w(sds_num, 0x1, 2, 15, 0, 0);
+ break;
+
+ default:
+ pr_info("%s unsupported phy mode\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+u32 rtl9300_sds_sym_err_get(int sds_num, phy_interface_t phy_mode)
+{
+ u32 v = 0;
+
+ switch (phy_mode) {
+ case PHY_INTERFACE_MODE_XGMII:
+ break;
+
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_10GBASER:
+ v = rtl930x_read_sds_phy(sds_num, 5, 1);
+ return v & 0xff;
+
+ default:
+ pr_info("%s unsupported PHY-mode\n", __func__);
+ }
+
+ return v;
+}
+
+int rtl9300_sds_check_calibration(int sds_num, phy_interface_t phy_mode)
+{
+ u32 errors1, errors2;
+
+ rtl9300_sds_sym_err_reset(sds_num, phy_mode);
+ rtl9300_sds_sym_err_reset(sds_num, phy_mode);
+
+ /* Count errors during 1ms */
+ errors1 = rtl9300_sds_sym_err_get(sds_num, phy_mode);
+ mdelay(1);
+ errors2 = rtl9300_sds_sym_err_get(sds_num, phy_mode);
+
+ switch (phy_mode) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_XGMII:
+ if ((errors2 - errors1 > 100) ||
+ (errors1 >= 0xffff00) || (errors2 >= 0xffff00)) {
+ pr_info("%s XSGMII error rate too high\n", __func__);
+ return 1;
+ }
+ break;
+ case PHY_INTERFACE_MODE_10GBASER:
+ if (errors2 > 0) {
+ pr_info("%s 10GBASER error rate too high\n", __func__);
+ return 1;
+ }
+ break;
+ default:
+ return 1;
+ }
+
+ return 0;
+}
+
+void rtl9300_phy_enable_10g_1g(int sds_num)
+{
+ u32 v;
+
+ /* Enable 1GBit PHY */
+ v = rtl930x_read_sds_phy(sds_num, PHY_PAGE_2, MII_BMCR);
+ pr_info("%s 1gbit phy: %08x\n", __func__, v);
+ v &= ~BMCR_PDOWN;
+ rtl930x_write_sds_phy(sds_num, PHY_PAGE_2, MII_BMCR, v);
+ pr_info("%s 1gbit phy enabled: %08x\n", __func__, v);
+
+ /* Enable 10GBit PHY */
+ v = rtl930x_read_sds_phy(sds_num, PHY_PAGE_4, MII_BMCR);
+ pr_info("%s 10gbit phy: %08x\n", __func__, v);
+ v &= ~BMCR_PDOWN;
+ rtl930x_write_sds_phy(sds_num, PHY_PAGE_4, MII_BMCR, v);
+ pr_info("%s 10gbit phy after: %08x\n", __func__, v);
+
+ /* dal_longan_construct_mac_default_10gmedia_fiber */
+ v = rtl930x_read_sds_phy(sds_num, 0x1f, 11);
+ pr_info("%s set medium: %08x\n", __func__, v);
+ v |= BIT(1);
+ rtl930x_write_sds_phy(sds_num, 0x1f, 11, v);
+ pr_info("%s set medium after: %08x\n", __func__, v);
+}
+
+static int rtl9300_sds_10g_idle(int sds_num);
+static void rtl9300_serdes_patch(int sds_num);
+
+#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C)
+int rtl9300_serdes_setup(int port, int sds_num, phy_interface_t phy_mode)
+{
+ int calib_tries = 0;
+
+ /* Turn Off Serdes */
+ rtl9300_sds_rst(sds_num, RTL930X_SDS_OFF);
+
+ /* Apply serdes patches */
+ rtl9300_serdes_patch(sds_num);
+
+ /* Maybe use dal_longan_sds_init */
+
+ /* dal_longan_construct_serdesConfig_init */ /* Serdes Construct */
+ rtl9300_phy_enable_10g_1g(sds_num);
+
+ /* Disable MAC */
+ sw_w32_mask(0, 1, RTL930X_MAC_FORCE_MODE_CTRL + 4 * port);
+ mdelay(20);
+
+ /* ----> dal_longan_sds_mode_set */
+ pr_info("%s: Configuring RTL9300 SERDES %d\n", __func__, sds_num);
+
+ /* Configure link to MAC */
+ rtl9300_serdes_mac_link_config(sds_num, true, true); /* MAC Construct */
+
+ /* Re-Enable MAC */
+ sw_w32_mask(1, 0, RTL930X_MAC_FORCE_MODE_CTRL + 4 * port);
+
+ /* Enable SDS in desired mode */
+ rtl9300_force_sds_mode(sds_num, phy_mode);
+
+ /* Enable Fiber RX */
+ rtl9300_sds_field_w(sds_num, 0x20, 2, 12, 12, 0);
+
+ /* Calibrate SerDes receiver in loopback mode */
+ rtl9300_sds_10g_idle(sds_num);
+ do {
+ rtl9300_do_rx_calibration(sds_num, phy_mode);
+ calib_tries++;
+ mdelay(50);
+ } while (rtl9300_sds_check_calibration(sds_num, phy_mode) && calib_tries < 3);
+ if (calib_tries >= 3)
+ pr_warn("%s: SerDes RX calibration failed\n", __func__);
+
+ /* Leave loopback mode */
+ rtl9300_sds_tx_config(sds_num, phy_mode);
+
+ return 0;
+}
+
+static int rtl9300_sds_10g_idle(int sds_num)
+{
+ bool busy;
+ int i = 0;
+
+ do {
+ if (sds_num % 2) {
+ rtl9300_sds_field_w(sds_num - 1, 0x1f, 0x2, 15, 0, 53);
+ busy = !!rtl9300_sds_field_r(sds_num - 1, 0x1f, 0x14, 1, 1);
+ } else {
+ rtl9300_sds_field_w(sds_num, 0x1f, 0x2, 15, 0, 53);
+ busy = !!rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 0, 0);
+ }
+ i++;
+ } while (busy && i < 100);
+
+ if (i < 100)
+ return 0;
+
+ pr_warn("%s WARNING: Waiting for RX idle timed out, SDS %d\n", __func__, sds_num);
+ return -EIO;
+}
+
+typedef struct {
+ u8 page;
+ u8 reg;
+ u16 data;
+} sds_config;
+
+sds_config rtl9300_a_sds_10gr_lane0[] =
+{
+ /* 1G */
+ {0x00, 0x0E, 0x3053}, {0x01, 0x14, 0x0100}, {0x21, 0x03, 0x8206},
+ {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F},
+ {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, {0x21, 0x0E, 0x0000},
+ {0x21, 0x0F, 0x0008}, {0x24, 0x00, 0x0668}, {0x24, 0x02, 0xD020},
+ {0x24, 0x06, 0xC000}, {0x24, 0x0B, 0x1892}, {0x24, 0x0F, 0xFFDF},
+ {0x24, 0x12, 0x03C4}, {0x24, 0x13, 0x027F}, {0x24, 0x14, 0x1311},
+ {0x24, 0x16, 0x00C9}, {0x24, 0x17, 0xA100}, {0x24, 0x1A, 0x0001},
+ {0x24, 0x1C, 0x0400}, {0x25, 0x01, 0x0300}, {0x25, 0x02, 0x1017},
+ {0x25, 0x03, 0xFFDF}, {0x25, 0x05, 0x7F7C}, {0x25, 0x07, 0x8100},
+ {0x25, 0x08, 0x0001}, {0x25, 0x09, 0xFFD4}, {0x25, 0x0A, 0x7C2F},
+ {0x25, 0x0E, 0x003F}, {0x25, 0x0F, 0x0121}, {0x25, 0x10, 0x0020},
+ {0x25, 0x11, 0x8840}, {0x2B, 0x13, 0x0050}, {0x2B, 0x18, 0x8E88},
+ {0x2B, 0x19, 0x4902}, {0x2B, 0x1D, 0x2501}, {0x2D, 0x13, 0x0050},
+ {0x2D, 0x18, 0x8E88}, {0x2D, 0x19, 0x4902}, {0x2D, 0x1D, 0x2641},
+ {0x2F, 0x13, 0x0050}, {0x2F, 0x18, 0x8E88}, {0x2F, 0x19, 0x4902},
+ {0x2F, 0x1D, 0x66E1},
+ /* 3.125G */
+ {0x28, 0x00, 0x0668}, {0x28, 0x02, 0xD020}, {0x28, 0x06, 0xC000},
+ {0x28, 0x0B, 0x1892}, {0x28, 0x0F, 0xFFDF}, {0x28, 0x12, 0x01C4},
+ {0x28, 0x13, 0x027F}, {0x28, 0x14, 0x1311}, {0x28, 0x16, 0x00C9},
+ {0x28, 0x17, 0xA100}, {0x28, 0x1A, 0x0001}, {0x28, 0x1C, 0x0400},
+ {0x29, 0x01, 0x0300}, {0x29, 0x02, 0x1017}, {0x29, 0x03, 0xFFDF},
+ {0x29, 0x05, 0x7F7C}, {0x29, 0x07, 0x8100}, {0x29, 0x08, 0x0001},
+ {0x29, 0x09, 0xFFD4}, {0x29, 0x0A, 0x7C2F}, {0x29, 0x0E, 0x003F},
+ {0x29, 0x0F, 0x0121}, {0x29, 0x10, 0x0020}, {0x29, 0x11, 0x8840},
+ /* 10G */
+ {0x06, 0x0D, 0x0F00}, {0x06, 0x00, 0x0000}, {0x06, 0x01, 0xC800},
+ {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010},
+ {0x21, 0x07, 0xF09F}, {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009},
+ {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008}, {0x2E, 0x00, 0xA668},
+ {0x2E, 0x02, 0xD020}, {0x2E, 0x06, 0xC000}, {0x2E, 0x0B, 0x1892},
+ {0x2E, 0x0F, 0xFFDF}, {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0044},
+ {0x2E, 0x13, 0x027F}, {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100},
+ {0x2E, 0x1A, 0x0001}, {0x2E, 0x1C, 0x0400}, {0x2F, 0x01, 0x0300},
+ {0x2F, 0x02, 0x1217}, {0x2F, 0x03, 0xFFDF}, {0x2F, 0x05, 0x7F7C},
+ {0x2F, 0x07, 0x80C4}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4},
+ {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121},
+ {0x2F, 0x10, 0x0020}, {0x2F, 0x11, 0x8840}, {0x2F, 0x14, 0xE008},
+ {0x2B, 0x13, 0x0050}, {0x2B, 0x18, 0x8E88}, {0x2B, 0x19, 0x4902},
+ {0x2B, 0x1D, 0x2501}, {0x2D, 0x13, 0x0050}, {0x2D, 0x17, 0x4109},
+ {0x2D, 0x18, 0x8E88}, {0x2D, 0x19, 0x4902}, {0x2D, 0x1C, 0x1109},
+ {0x2D, 0x1D, 0x2641}, {0x2F, 0x13, 0x0050}, {0x2F, 0x18, 0x8E88},
+ {0x2F, 0x19, 0x4902}, {0x2F, 0x1D, 0x76E1},
+};
+
+sds_config rtl9300_a_sds_10gr_lane1[] =
+{
+ /* 1G */
+ {0x00, 0x0E, 0x3053}, {0x01, 0x14, 0x0100}, {0x21, 0x03, 0x8206},
+ {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F}, {0x21, 0x0A, 0x0003},
+ {0x21, 0x0B, 0x0005}, {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009},
+ {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008}, {0x24, 0x00, 0x0668},
+ {0x24, 0x02, 0xD020}, {0x24, 0x06, 0xC000}, {0x24, 0x0B, 0x1892},
+ {0x24, 0x0F, 0xFFDF}, {0x24, 0x12, 0x03C4}, {0x24, 0x13, 0x027F},
+ {0x24, 0x14, 0x1311}, {0x24, 0x16, 0x00C9}, {0x24, 0x17, 0xA100},
+ {0x24, 0x1A, 0x0001}, {0x24, 0x1C, 0x0400}, {0x25, 0x00, 0x820F},
+ {0x25, 0x01, 0x0300}, {0x25, 0x02, 0x1017}, {0x25, 0x03, 0xFFDF},
+ {0x25, 0x05, 0x7F7C}, {0x25, 0x07, 0x8100}, {0x25, 0x08, 0x0001},
+ {0x25, 0x09, 0xFFD4}, {0x25, 0x0A, 0x7C2F}, {0x25, 0x0E, 0x003F},
+ {0x25, 0x0F, 0x0121}, {0x25, 0x10, 0x0020}, {0x25, 0x11, 0x8840},
+ {0x2B, 0x13, 0x3D87}, {0x2B, 0x14, 0x3108}, {0x2D, 0x13, 0x3C87},
+ {0x2D, 0x14, 0x1808},
+ /* 3.125G */
+ {0x28, 0x00, 0x0668}, {0x28, 0x02, 0xD020}, {0x28, 0x06, 0xC000},
+ {0x28, 0x0B, 0x1892}, {0x28, 0x0F, 0xFFDF}, {0x28, 0x12, 0x01C4},
+ {0x28, 0x13, 0x027F}, {0x28, 0x14, 0x1311}, {0x28, 0x16, 0x00C9},
+ {0x28, 0x17, 0xA100}, {0x28, 0x1A, 0x0001}, {0x28, 0x1C, 0x0400},
+ {0x29, 0x00, 0x820F}, {0x29, 0x01, 0x0300}, {0x29, 0x02, 0x1017},
+ {0x29, 0x03, 0xFFDF}, {0x29, 0x05, 0x7F7C}, {0x29, 0x07, 0x8100},
+ {0x29, 0x08, 0x0001}, {0x29, 0x0A, 0x7C2F}, {0x29, 0x0E, 0x003F},
+ {0x29, 0x0F, 0x0121}, {0x29, 0x10, 0x0020}, {0x29, 0x11, 0x8840},
+ /* 10G */
+ {0x06, 0x0D, 0x0F00}, {0x06, 0x00, 0x0000}, {0x06, 0x01, 0xC800},
+ {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010},
+ {0x21, 0x07, 0xF09F}, {0x21, 0x0A, 0x0003}, {0x21, 0x0B, 0x0005},
+ {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, {0x21, 0x0E, 0x0000},
+ {0x21, 0x0F, 0x0008}, {0x2E, 0x00, 0xA668}, {0x2E, 0x02, 0xD020},
+ {0x2E, 0x06, 0xC000}, {0x2E, 0x0B, 0x1892}, {0x2E, 0x0F, 0xFFDF},
+ {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0044}, {0x2E, 0x13, 0x027F},
+ {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100}, {0x2E, 0x1A, 0x0001},
+ {0x2E, 0x1C, 0x0400}, {0x2F, 0x00, 0x820F}, {0x2F, 0x01, 0x0300},
+ {0x2F, 0x02, 0x1217}, {0x2F, 0x03, 0xFFDF}, {0x2F, 0x05, 0x7F7C},
+ {0x2F, 0x07, 0x80C4}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4},
+ {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121},
+ {0x2F, 0x10, 0x0020}, {0x2F, 0x11, 0x8840}, {0x2B, 0x13, 0x3D87},
+ {0x2B, 0x14, 0x3108}, {0x2D, 0x13, 0x3C87}, {0x2D, 0x14, 0x1808},
+};
+
+static void rtl9300_serdes_patch(int sds_num)
+{
+ if (sds_num % 2) {
+ for (int i = 0; i < sizeof(rtl9300_a_sds_10gr_lane1) / sizeof(sds_config); ++i) {
+ rtl930x_write_sds_phy(sds_num, rtl9300_a_sds_10gr_lane1[i].page,
+ rtl9300_a_sds_10gr_lane1[i].reg,
+ rtl9300_a_sds_10gr_lane1[i].data);
+ }
+ } else {
+ for (int i = 0; i < sizeof(rtl9300_a_sds_10gr_lane0) / sizeof(sds_config); ++i) {
+ rtl930x_write_sds_phy(sds_num, rtl9300_a_sds_10gr_lane0[i].page,
+ rtl9300_a_sds_10gr_lane0[i].reg,
+ rtl9300_a_sds_10gr_lane0[i].data);
+ }
+ }
+}
+
+int rtl9300_sds_cmu_band_get(int sds)
+{
+ u32 page;
+ u32 en;
+ u32 cmu_band;
+
+/* page = rtl9300_sds_cmu_page_get(sds); */
+ page = 0x25; /* 10GR and 1000BX */
+ sds = (sds % 2) ? (sds - 1) : (sds);
+
+ rtl9300_sds_field_w(sds, page, 0x1c, 15, 15, 1);
+ rtl9300_sds_field_w(sds + 1, page, 0x1c, 15, 15, 1);
+
+ en = rtl9300_sds_field_r(sds, page, 27, 1, 1);
+ if(!en) { /* Auto mode */
+ rtl930x_write_sds_phy(sds, 0x1f, 0x02, 31);
+
+ cmu_band = rtl9300_sds_field_r(sds, 0x1f, 0x15, 5, 1);
+ } else {
+ cmu_band = rtl9300_sds_field_r(sds, page, 30, 4, 0);
+ }
+
+ return cmu_band;
+}
+
+void rtl9310_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int start_bit, u32 v)
+{
+ int l = end_bit - start_bit + 1;
+ u32 data = v;
+
+ if (l < 32) {
+ u32 mask = BIT(l) - 1;
+
+ data = rtl930x_read_sds_phy(sds, page, reg);
+ data &= ~(mask << start_bit);
+ data |= (v & mask) << start_bit;
+ }
+
+ rtl931x_write_sds_phy(sds, page, reg, data);
+}
+
+u32 rtl9310_sds_field_r(int sds, u32 page, u32 reg, int end_bit, int start_bit)
+{
+ int l = end_bit - start_bit + 1;
+ u32 v = rtl931x_read_sds_phy(sds, page, reg);
+
+ if (l >= 32)
+ return v;
+
+ return (v >> start_bit) & (BIT(l) - 1);
+}
+
+static void rtl931x_sds_rst(u32 sds)
+{
+ u32 o, v, o_mode;
+ int shift = ((sds & 0x3) << 3);
+
+ /* TODO: We need to lock this! */
+
+ o = sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
+ v = o | BIT(sds);
+ sw_w32(v, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
+
+ o_mode = sw_r32(RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
+ v = BIT(7) | 0x1F;
+ sw_w32_mask(0xff << shift, v << shift, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
+ sw_w32(o_mode, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
+
+ sw_w32(o, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
+}
+
+static void rtl931x_symerr_clear(u32 sds, phy_interface_t mode)
+{
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_NA:
+ break;
+ case PHY_INTERFACE_MODE_XGMII:
+ u32 xsg_sdsid_0, xsg_sdsid_1;
+
+ if (sds < 2)
+ xsg_sdsid_0 = sds;
+ else
+ xsg_sdsid_0 = (sds - 1) * 2;
+ xsg_sdsid_1 = xsg_sdsid_0 + 1;
+
+ for (int i = 0; i < 4; ++i) {
+ rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 24, 2, 0, i);
+ rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 3, 15, 8, 0x0);
+ rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 2, 15, 0, 0x0);
+ }
+
+ for (int i = 0; i < 4; ++i) {
+ rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 24, 2, 0, i);
+ rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 3, 15, 8, 0x0);
+ rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 2, 15, 0, 0x0);
+ }
+
+ rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 0, 15, 0, 0x0);
+ rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 1, 15, 8, 0x0);
+ rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0, 15, 0, 0x0);
+ rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 1, 15, 8, 0x0);
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+static u32 rtl931x_get_analog_sds(u32 sds)
+{
+ u32 sds_map[] = { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23 };
+
+ if (sds < 14)
+ return sds_map[sds];
+
+ return sds;
+}
+
+void rtl931x_sds_fiber_disable(u32 sds)
+{
+ u32 v = 0x3F;
+ u32 asds = rtl931x_get_analog_sds(sds);
+
+ rtl9310_sds_field_w(asds, 0x1F, 0x9, 11, 6, v);
+}
+
+static void rtl931x_sds_fiber_mode_set(u32 sds, phy_interface_t mode)
+{
+ u32 val, asds = rtl931x_get_analog_sds(sds);
+
+ /* clear symbol error count before changing mode */
+ rtl931x_symerr_clear(sds, mode);
+
+ val = 0x9F;
+ sw_w32(val, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_SGMII:
+ val = 0x5;
+ break;
+
+ case PHY_INTERFACE_MODE_1000BASEX:
+ /* serdes mode FIBER1G */
+ val = 0x9;
+ break;
+
+ case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_10GKR:
+ val = 0x35;
+ break;
+/* case MII_10GR1000BX_AUTO:
+ val = 0x39;
+ break; */
+
+
+ case PHY_INTERFACE_MODE_USXGMII:
+ val = 0x1B;
+ break;
+ default:
+ val = 0x25;
+ }
+
+ pr_info("%s writing analog SerDes Mode value %02x\n", __func__, val);
+ rtl9310_sds_field_w(asds, 0x1F, 0x9, 11, 6, val);
+
+ return;
+}
+
+static int rtl931x_sds_cmu_page_get(phy_interface_t mode)
+{
+ switch (mode) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX: /* MII_1000BX_FIBER / 100BX_FIBER / 1000BX100BX_AUTO */
+ return 0x24;
+ case PHY_INTERFACE_MODE_HSGMII:
+ case PHY_INTERFACE_MODE_2500BASEX: /* MII_2500Base_X: */
+ return 0x28;
+/* case MII_HISGMII_5G: */
+/* return 0x2a; */
+ case PHY_INTERFACE_MODE_QSGMII:
+ return 0x2a; /* Code also has 0x34 */
+ case PHY_INTERFACE_MODE_XAUI: /* MII_RXAUI_LITE: */
+ return 0x2c;
+ case PHY_INTERFACE_MODE_XGMII: /* MII_XSGMII */
+ case PHY_INTERFACE_MODE_10GKR:
+ case PHY_INTERFACE_MODE_10GBASER: /* MII_10GR */
+ return 0x2e;
+ default:
+ return -1;
+ }
+
+ return -1;
+}
+
+static void rtl931x_cmu_type_set(u32 asds, phy_interface_t mode, int chiptype)
+{
+ int cmu_type = 0; /* Clock Management Unit */
+ u32 cmu_page = 0;
+ u32 frc_cmu_spd;
+ u32 evenSds;
+ u32 lane, frc_lc_mode_bitnum, frc_lc_mode_val_bitnum;
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_NA:
+ case PHY_INTERFACE_MODE_10GKR:
+ case PHY_INTERFACE_MODE_XGMII:
+ case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_USXGMII:
+ return;
+
+/* case MII_10GR1000BX_AUTO:
+ if (chiptype)
+ rtl9310_sds_field_w(asds, 0x24, 0xd, 14, 14, 0);
+ return; */
+
+ case PHY_INTERFACE_MODE_QSGMII:
+ cmu_type = 1;
+ frc_cmu_spd = 0;
+ break;
+
+ case PHY_INTERFACE_MODE_HSGMII:
+ cmu_type = 1;
+ frc_cmu_spd = 1;
+ break;
+
+ case PHY_INTERFACE_MODE_1000BASEX:
+ cmu_type = 1;
+ frc_cmu_spd = 0;
+ break;
+
+/* case MII_1000BX100BX_AUTO:
+ cmu_type = 1;
+ frc_cmu_spd = 0;
+ break; */
+
+ case PHY_INTERFACE_MODE_SGMII:
+ cmu_type = 1;
+ frc_cmu_spd = 0;
+ break;
+
+ case PHY_INTERFACE_MODE_2500BASEX:
+ cmu_type = 1;
+ frc_cmu_spd = 1;
+ break;
+
+ default:
+ pr_info("SerDes %d mode is invalid\n", asds);
+ return;
+ }
+
+ if (cmu_type == 1)
+ cmu_page = rtl931x_sds_cmu_page_get(mode);
+
+ lane = asds % 2;
+
+ if (!lane) {
+ frc_lc_mode_bitnum = 4;
+ frc_lc_mode_val_bitnum = 5;
+ } else {
+ frc_lc_mode_bitnum = 6;
+ frc_lc_mode_val_bitnum = 7;
+ }
+
+ evenSds = asds - lane;
+
+ pr_info("%s: cmu_type %0d cmu_page %x frc_cmu_spd %d lane %d asds %d\n",
+ __func__, cmu_type, cmu_page, frc_cmu_spd, lane, asds);
+
+ if (cmu_type == 1) {
+ pr_info("%s A CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
+ rtl9310_sds_field_w(asds, cmu_page, 0x7, 15, 15, 0);
+ pr_info("%s B CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
+ if (chiptype) {
+ rtl9310_sds_field_w(asds, cmu_page, 0xd, 14, 14, 0);
+ }
+
+ rtl9310_sds_field_w(evenSds, 0x20, 0x12, 3, 2, 0x3);
+ rtl9310_sds_field_w(evenSds, 0x20, 0x12, frc_lc_mode_bitnum, frc_lc_mode_bitnum, 1);
+ rtl9310_sds_field_w(evenSds, 0x20, 0x12, frc_lc_mode_val_bitnum, frc_lc_mode_val_bitnum, 0);
+ rtl9310_sds_field_w(evenSds, 0x20, 0x12, 12, 12, 1);
+ rtl9310_sds_field_w(evenSds, 0x20, 0x12, 15, 13, frc_cmu_spd);
+ }
+
+ pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
+ return;
+}
+
+static void rtl931x_sds_rx_rst(u32 sds)
+{
+ u32 asds = rtl931x_get_analog_sds(sds);
+
+ if (sds < 2)
+ return;
+
+ rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x2740);
+ rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0x0);
+ rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x2010);
+ rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc10);
+
+ rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x27c0);
+ rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0xc000);
+ rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x6010);
+ rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc30);
+
+ mdelay(50);
+}
+
+// Currently not used
+// static void rtl931x_sds_disable(u32 sds)
+// {
+// u32 v = 0x1f;
+
+// v |= BIT(7);
+// sw_w32(v, RTL931X_SERDES_MODE_CTRL + (sds >> 2) * 4);
+// }
+
+static void rtl931x_sds_mii_mode_set(u32 sds, phy_interface_t mode)
+{
+ u32 val;
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_QSGMII:
+ val = 0x6;
+ break;
+ case PHY_INTERFACE_MODE_XGMII:
+ val = 0x10; /* serdes mode XSGMII */
+ break;
+ case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ val = 0xD;
+ break;
+ case PHY_INTERFACE_MODE_HSGMII:
+ val = 0x12;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ val = 0x2;
+ break;
+ default:
+ return;
+ }
+
+ val |= (1 << 7);
+
+ sw_w32(val, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
+}
+
+static sds_config sds_config_10p3125g_type1[] = {
+ { 0x2E, 0x00, 0x0107 }, { 0x2E, 0x01, 0x01A3 }, { 0x2E, 0x02, 0x6A24 },
+ { 0x2E, 0x03, 0xD10D }, { 0x2E, 0x04, 0x8000 }, { 0x2E, 0x05, 0xA17E },
+ { 0x2E, 0x06, 0xE31D }, { 0x2E, 0x07, 0x800E }, { 0x2E, 0x08, 0x0294 },
+ { 0x2E, 0x09, 0x0CE4 }, { 0x2E, 0x0A, 0x7FC8 }, { 0x2E, 0x0B, 0xE0E7 },
+ { 0x2E, 0x0C, 0x0200 }, { 0x2E, 0x0D, 0xDF80 }, { 0x2E, 0x0E, 0x0000 },
+ { 0x2E, 0x0F, 0x1FC2 }, { 0x2E, 0x10, 0x0C3F }, { 0x2E, 0x11, 0x0000 },
+ { 0x2E, 0x12, 0x27C0 }, { 0x2E, 0x13, 0x7E1D }, { 0x2E, 0x14, 0x1300 },
+ { 0x2E, 0x15, 0x003F }, { 0x2E, 0x16, 0xBE7F }, { 0x2E, 0x17, 0x0090 },
+ { 0x2E, 0x18, 0x0000 }, { 0x2E, 0x19, 0x4000 }, { 0x2E, 0x1A, 0x0000 },
+ { 0x2E, 0x1B, 0x8000 }, { 0x2E, 0x1C, 0x011F }, { 0x2E, 0x1D, 0x0000 },
+ { 0x2E, 0x1E, 0xC8FF }, { 0x2E, 0x1F, 0x0000 }, { 0x2F, 0x00, 0xC000 },
+ { 0x2F, 0x01, 0xF000 }, { 0x2F, 0x02, 0x6010 }, { 0x2F, 0x12, 0x0EE7 },
+ { 0x2F, 0x13, 0x0000 }
+};
+
+static sds_config sds_config_10p3125g_cmu_type1[] = {
+ { 0x2F, 0x03, 0x4210 }, { 0x2F, 0x04, 0x0000 }, { 0x2F, 0x05, 0x0019 },
+ { 0x2F, 0x06, 0x18A6 }, { 0x2F, 0x07, 0x2990 }, { 0x2F, 0x08, 0xFFF4 },
+ { 0x2F, 0x09, 0x1F08 }, { 0x2F, 0x0A, 0x0000 }, { 0x2F, 0x0B, 0x8000 },
+ { 0x2F, 0x0C, 0x4224 }, { 0x2F, 0x0D, 0x0000 }, { 0x2F, 0x0E, 0x0000 },
+ { 0x2F, 0x0F, 0xA470 }, { 0x2F, 0x10, 0x8000 }, { 0x2F, 0x11, 0x037B }
+};
+
+void rtl931x_sds_init(u32 sds, phy_interface_t mode)
+{
+ u32 board_sds_tx_type1[] = {
+ 0x01c3, 0x01c3, 0x01c3, 0x01a3, 0x01a3, 0x01a3,
+ 0x0143, 0x0143, 0x0143, 0x0143, 0x0163, 0x0163,
+ };
+ u32 board_sds_tx[] = {
+ 0x1a00, 0x1a00, 0x0200, 0x0200, 0x0200, 0x0200,
+ 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01e3, 0x01e3
+ };
+ u32 board_sds_tx2[] = {
+ 0x0dc0, 0x01c0, 0x0200, 0x0180, 0x0160, 0x0123,
+ 0x0123, 0x0163, 0x01a3, 0x01a0, 0x01c3, 0x09c3,
+ };
+ u32 asds, dSds, ori, model_info, val;
+ int chiptype = 0;
+
+ asds = rtl931x_get_analog_sds(sds);
+
+ if (sds > 13)
+ return;
+
+ pr_info("%s: set sds %d to mode %d\n", __func__, sds, mode);
+ val = rtl9310_sds_field_r(asds, 0x1F, 0x9, 11, 6);
+
+ pr_info("%s: fibermode %08X stored mode 0x%x analog SDS %d", __func__,
+ rtl931x_read_sds_phy(asds, 0x1f, 0x9), val, asds);
+ pr_info("%s: SGMII mode %08X in 0x24 0x9 analog SDS %d", __func__,
+ rtl931x_read_sds_phy(asds, 0x24, 0x9), asds);
+ pr_info("%s: CMU mode %08X stored even SDS %d", __func__,
+ rtl931x_read_sds_phy(asds & ~1, 0x20, 0x12), asds & ~1);
+ pr_info("%s: serdes_mode_ctrl %08X", __func__, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2));
+ pr_info("%s CMU page 0x24 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x24, 0x7));
+ pr_info("%s CMU page 0x26 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x26, 0x7));
+ pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7));
+ pr_info("%s XSG page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds, 0x0, 0xe));
+ pr_info("%s XSG2 page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds + 1, 0x0, 0xe));
+
+ model_info = sw_r32(RTL93XX_MODEL_NAME_INFO);
+ if ((model_info >> 4) & 0x1) {
+ pr_info("detected chiptype 1\n");
+ chiptype = 1;
+ } else {
+ pr_info("detected chiptype 0\n");
+ }
+
+ if (sds < 2)
+ dSds = sds;
+ else
+ dSds = (sds - 1) * 2;
+
+ pr_info("%s: 2.5gbit %08X dsds %d", __func__,
+ rtl931x_read_sds_phy(dSds, 0x1, 0x14), dSds);
+
+ pr_info("%s: RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR 0x%08X\n", __func__, sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR));
+ ori = sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
+ val = ori | (1 << sds);
+ sw_w32(val, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_NA:
+ break;
+
+ case PHY_INTERFACE_MODE_XGMII: /* MII_XSGMII */
+
+ if (chiptype) {
+ u32 xsg_sdsid_1;
+ xsg_sdsid_1 = dSds + 1;
+ /* fifo inv clk */
+ rtl9310_sds_field_w(dSds, 0x1, 0x1, 7, 4, 0xf);
+ rtl9310_sds_field_w(dSds, 0x1, 0x1, 3, 0, 0xf);
+
+ rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0x1, 7, 4, 0xf);
+ rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0x1, 3, 0, 0xf);
+
+ }
+
+ rtl9310_sds_field_w(dSds, 0x0, 0xE, 12, 12, 1);
+ rtl9310_sds_field_w(dSds + 1, 0x0, 0xE, 12, 12, 1);
+ break;
+
+ case PHY_INTERFACE_MODE_USXGMII: /* MII_USXGMII_10GSXGMII/10GDXGMII/10GQXGMII: */
+ u32 op_code = 0x6003;
+ u32 evenSds;
+
+ if (chiptype) {
+ rtl9310_sds_field_w(asds, 0x6, 0x2, 12, 12, 1);
+
+ for (int i = 0; i < sizeof(sds_config_10p3125g_type1) / sizeof(sds_config); ++i) {
+ rtl931x_write_sds_phy(asds, sds_config_10p3125g_type1[i].page - 0x4, sds_config_10p3125g_type1[i].reg, sds_config_10p3125g_type1[i].data);
+ }
+
+ evenSds = asds - (asds % 2);
+
+ for (int i = 0; i < sizeof(sds_config_10p3125g_cmu_type1) / sizeof(sds_config); ++i) {
+ rtl931x_write_sds_phy(evenSds,
+ sds_config_10p3125g_cmu_type1[i].page - 0x4, sds_config_10p3125g_cmu_type1[i].reg, sds_config_10p3125g_cmu_type1[i].data);
+ }
+
+ rtl9310_sds_field_w(asds, 0x6, 0x2, 12, 12, 0);
+ } else {
+
+ rtl9310_sds_field_w(asds, 0x2e, 0xd, 6, 0, 0x0);
+ rtl9310_sds_field_w(asds, 0x2e, 0xd, 7, 7, 0x1);
+
+ rtl9310_sds_field_w(asds, 0x2e, 0x1c, 5, 0, 0x1E);
+ rtl9310_sds_field_w(asds, 0x2e, 0x1d, 11, 0, 0x00);
+ rtl9310_sds_field_w(asds, 0x2e, 0x1f, 11, 0, 0x00);
+ rtl9310_sds_field_w(asds, 0x2f, 0x0, 11, 0, 0x00);
+ rtl9310_sds_field_w(asds, 0x2f, 0x1, 11, 0, 0x00);
+
+ rtl9310_sds_field_w(asds, 0x2e, 0xf, 12, 6, 0x7F);
+ rtl931x_write_sds_phy(asds, 0x2f, 0x12, 0xaaa);
+
+ rtl931x_sds_rx_rst(sds);
+
+ rtl931x_write_sds_phy(asds, 0x7, 0x10, op_code);
+ rtl931x_write_sds_phy(asds, 0x6, 0x1d, 0x0480);
+ rtl931x_write_sds_phy(asds, 0x6, 0xe, 0x0400);
+ }
+ break;
+
+ case PHY_INTERFACE_MODE_10GBASER: /* MII_10GR / MII_10GR1000BX_AUTO: */
+ /* configure 10GR fiber mode=1 */
+ rtl9310_sds_field_w(asds, 0x1f, 0xb, 1, 1, 1);
+
+ /* init fiber_1g */
+ rtl9310_sds_field_w(dSds, 0x3, 0x13, 15, 14, 0);
+
+ rtl9310_sds_field_w(dSds, 0x2, 0x0, 12, 12, 1);
+ rtl9310_sds_field_w(dSds, 0x2, 0x0, 6, 6, 1);
+ rtl9310_sds_field_w(dSds, 0x2, 0x0, 13, 13, 0);
+
+ /* init auto */
+ rtl9310_sds_field_w(asds, 0x1f, 13, 15, 0, 0x109e);
+ rtl9310_sds_field_w(asds, 0x1f, 0x6, 14, 10, 0x8);
+ rtl9310_sds_field_w(asds, 0x1f, 0x7, 10, 4, 0x7f);
+ break;
+
+ case PHY_INTERFACE_MODE_HSGMII:
+ rtl9310_sds_field_w(dSds, 0x1, 0x14, 8, 8, 1);
+ break;
+
+ case PHY_INTERFACE_MODE_1000BASEX: /* MII_1000BX_FIBER */
+ rtl9310_sds_field_w(dSds, 0x3, 0x13, 15, 14, 0);
+
+ rtl9310_sds_field_w(dSds, 0x2, 0x0, 12, 12, 1);
+ rtl9310_sds_field_w(dSds, 0x2, 0x0, 6, 6, 1);
+ rtl9310_sds_field_w(dSds, 0x2, 0x0, 13, 13, 0);
+ break;
+
+ case PHY_INTERFACE_MODE_SGMII:
+ rtl9310_sds_field_w(asds, 0x24, 0x9, 15, 15, 0);
+ break;
+
+ case PHY_INTERFACE_MODE_2500BASEX:
+ rtl9310_sds_field_w(dSds, 0x1, 0x14, 8, 8, 1);
+ break;
+
+ case PHY_INTERFACE_MODE_QSGMII:
+ default:
+ pr_info("%s: PHY mode %s not supported by SerDes %d\n",
+ __func__, phy_modes(mode), sds);
+ return;
+ }
+
+ rtl931x_cmu_type_set(asds, mode, chiptype);
+
+ if (sds >= 2 && sds <= 13) {
+ if (chiptype)
+ rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx_type1[sds - 2]);
+ else {
+ val = 0xa0000;
+ sw_w32(val, RTL931X_CHIP_INFO_ADDR);
+ val = sw_r32(RTL931X_CHIP_INFO_ADDR);
+ if (val & BIT(28)) /* consider 9311 etc. RTL9313_CHIP_ID == HWP_CHIP_ID(unit)) */
+ {
+ rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx2[sds - 2]);
+ } else {
+ rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx[sds - 2]);
+ }
+ val = 0;
+ sw_w32(val, RTL931X_CHIP_INFO_ADDR);
+ }
+ }
+
+ val = ori & ~BIT(sds);
+ sw_w32(val, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR);
+ pr_debug("%s: RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR 0x%08X\n", __func__, sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR));
+
+ if (mode == PHY_INTERFACE_MODE_XGMII ||
+ mode == PHY_INTERFACE_MODE_QSGMII ||
+ mode == PHY_INTERFACE_MODE_HSGMII ||
+ mode == PHY_INTERFACE_MODE_SGMII ||
+ mode == PHY_INTERFACE_MODE_USXGMII) {
+ if (mode == PHY_INTERFACE_MODE_XGMII)
+ rtl931x_sds_mii_mode_set(sds, mode);
+ else
+ rtl931x_sds_fiber_mode_set(sds, mode);
+ }
+}
+
+int rtl931x_sds_cmu_band_set(int sds, bool enable, u32 band, phy_interface_t mode)
+{
+ u32 asds;
+ int page = rtl931x_sds_cmu_page_get(mode);
+
+ sds -= (sds % 2);
+ sds = sds & ~1;
+ asds = rtl931x_get_analog_sds(sds);
+ page += 1;
+
+ if (enable) {
+ rtl9310_sds_field_w(asds, page, 0x7, 13, 13, 0);
+ rtl9310_sds_field_w(asds, page, 0x7, 11, 11, 0);
+ } else {
+ rtl9310_sds_field_w(asds, page, 0x7, 13, 13, 0);
+ rtl9310_sds_field_w(asds, page, 0x7, 11, 11, 0);
+ }
+
+ rtl9310_sds_field_w(asds, page, 0x7, 4, 0, band);
+
+ rtl931x_sds_rst(sds);
+
+ return 0;
+}
+
+int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode)
+{
+ int page = rtl931x_sds_cmu_page_get(mode);
+ u32 asds, band;
+
+ sds -= (sds % 2);
+ asds = rtl931x_get_analog_sds(sds);
+ page += 1;
+ rtl931x_write_sds_phy(asds, 0x1f, 0x02, 73);
+
+ rtl9310_sds_field_w(asds, page, 0x5, 15, 15, 1);
+ band = rtl9310_sds_field_r(asds, 0x1f, 0x15, 8, 3);
+ pr_info("%s band is: %d\n", __func__, band);
+
+ return band;
+}
+
+
+int rtl931x_link_sts_get(u32 sds)
+{
+ u32 sts, sts1, latch_sts, latch_sts1;
+ if (0){
+ u32 xsg_sdsid_0, xsg_sdsid_1;
+
+ xsg_sdsid_0 = sds < 2 ? sds : (sds - 1) * 2;
+ xsg_sdsid_1 = xsg_sdsid_0 + 1;
+
+ sts = rtl9310_sds_field_r(xsg_sdsid_0, 0x1, 29, 8, 0);
+ sts1 = rtl9310_sds_field_r(xsg_sdsid_1, 0x1, 29, 8, 0);
+ latch_sts = rtl9310_sds_field_r(xsg_sdsid_0, 0x1, 30, 8, 0);
+ latch_sts1 = rtl9310_sds_field_r(xsg_sdsid_1, 0x1, 30, 8, 0);
+ } else {
+ u32 asds, dsds;
+
+ asds = rtl931x_get_analog_sds(sds);
+ sts = rtl9310_sds_field_r(asds, 0x5, 0, 12, 12);
+ latch_sts = rtl9310_sds_field_r(asds, 0x4, 1, 2, 2);
+
+ dsds = sds < 2 ? sds : (sds - 1) * 2;
+ latch_sts1 = rtl9310_sds_field_r(dsds, 0x2, 1, 2, 2);
+ sts1 = rtl9310_sds_field_r(dsds, 0x2, 1, 2, 2);
+ }
+
+ pr_info("%s: serdes %d sts %d, sts1 %d, latch_sts %d, latch_sts1 %d\n", __func__,
+ sds, sts, sts1, latch_sts, latch_sts1);
+
+ return sts1;
+}
+
+static int rtl8214fc_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
+{
+ struct phy_device *phydev = upstream;
+
+ rtl8214fc_media_set(phydev, true);
+
+ return 0;
+}
+
+static void rtl8214fc_sfp_remove(void *upstream)
+{
+ struct phy_device *phydev = upstream;
+
+ rtl8214fc_media_set(phydev, false);
+}
+
+static const struct sfp_upstream_ops rtl8214fc_sfp_ops = {
+ .attach = phy_sfp_attach,
+ .detach = phy_sfp_detach,
+ .module_insert = rtl8214fc_sfp_insert,
+ .module_remove = rtl8214fc_sfp_remove,
+};
+
+static int rtl8214fc_phy_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int addr = phydev->mdio.addr;
+ int ret = 0;
+
+ /* 839x has internal SerDes */
+ if (soc_info.id == 0x8393)
+ return -ENODEV;
+
+ /* All base addresses of the PHYs start at multiples of 8 */
+ devm_phy_package_join(dev, phydev, addr & (~7),
+ sizeof(struct rtl83xx_shared_private));
+
+ if (!(addr % 8)) {
+ struct rtl83xx_shared_private *shared = phydev->shared->priv;
+ shared->name = "RTL8214FC";
+ /* Configuration must be done while patching still possible */
+ ret = rtl8380_configure_rtl8214fc(phydev);
+ if (ret)
+ return ret;
+ }
+
+ return phy_sfp_probe(phydev, &rtl8214fc_sfp_ops);
+}
+
+static int rtl8214c_phy_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int addr = phydev->mdio.addr;
+
+ /* All base addresses of the PHYs start at multiples of 8 */
+ devm_phy_package_join(dev, phydev, addr & (~7),
+ sizeof(struct rtl83xx_shared_private));
+
+ if (!(addr % 8)) {
+ struct rtl83xx_shared_private *shared = phydev->shared->priv;
+ shared->name = "RTL8214C";
+ /* Configuration must be done whil patching still possible */
+ return rtl8380_configure_rtl8214c(phydev);
+ }
+
+ return 0;
+}
+
+static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int addr = phydev->mdio.addr;
+
+ /* All base addresses of the PHYs start at multiples of 8 */
+ devm_phy_package_join(dev, phydev, addr & (~7),
+ sizeof(struct rtl83xx_shared_private));
+
+ if (!(addr % 8)) {
+ struct rtl83xx_shared_private *shared = phydev->shared->priv;
+ shared->name = "RTL8218B (external)";
+ if (soc_info.family == RTL8380_FAMILY_ID) {
+ /* Configuration must be done while patching still possible */
+ return rtl8380_configure_ext_rtl8218b(phydev);
+ }
+ }
+
+ return 0;
+}
+
+static int rtl8218b_int_phy_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int addr = phydev->mdio.addr;
+
+ if (soc_info.family != RTL8380_FAMILY_ID)
+ return -ENODEV;
+ if (addr >= 24)
+ return -ENODEV;
+
+ pr_debug("%s: id: %d\n", __func__, addr);
+ /* All base addresses of the PHYs start at multiples of 8 */
+ devm_phy_package_join(dev, phydev, addr & (~7),
+ sizeof(struct rtl83xx_shared_private));
+
+ if (!(addr % 8)) {
+ struct rtl83xx_shared_private *shared = phydev->shared->priv;
+ shared->name = "RTL8218B (internal)";
+ /* Configuration must be done while patching still possible */
+ return rtl8380_configure_int_rtl8218b(phydev);
+ }
+
+ return 0;
+}
+
+static int rtl8218d_phy_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int addr = phydev->mdio.addr;
+
+ pr_debug("%s: id: %d\n", __func__, addr);
+ /* All base addresses of the PHYs start at multiples of 8 */
+ devm_phy_package_join(dev, phydev, addr & (~7),
+ sizeof(struct rtl83xx_shared_private));
+
+ /* All base addresses of the PHYs start at multiples of 8 */
+ if (!(addr % 8)) {
+ struct rtl83xx_shared_private *shared = phydev->shared->priv;
+ shared->name = "RTL8218D";
+ /* Configuration must be done while patching still possible */
+/* TODO: return configure_rtl8218d(phydev); */
+ }
+
+ return 0;
+}
+
+static int rtl838x_serdes_probe(struct phy_device *phydev)
+{
+ int addr = phydev->mdio.addr;
+
+ if (soc_info.family != RTL8380_FAMILY_ID)
+ return -ENODEV;
+ if (addr < 24)
+ return -ENODEV;
+
+ /* On the RTL8380M, PHYs 24-27 connect to the internal SerDes */
+ if (soc_info.id == 0x8380) {
+ if (addr == 24)
+ return rtl8380_configure_serdes(phydev);
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static int rtl8393_serdes_probe(struct phy_device *phydev)
+{
+ int addr = phydev->mdio.addr;
+
+ pr_info("%s: id: %d\n", __func__, addr);
+ if (soc_info.family != RTL8390_FAMILY_ID)
+ return -ENODEV;
+
+ if (addr < 24)
+ return -ENODEV;
+
+ return rtl8390_configure_serdes(phydev);
+}
+
+static int rtl8390_serdes_probe(struct phy_device *phydev)
+{
+ int addr = phydev->mdio.addr;
+
+ if (soc_info.family != RTL8390_FAMILY_ID)
+ return -ENODEV;
+
+ if (addr < 24)
+ return -ENODEV;
+
+ return rtl8390_configure_generic(phydev);
+}
+
+static int rtl9300_serdes_probe(struct phy_device *phydev)
+{
+ if (soc_info.family != RTL9300_FAMILY_ID)
+ return -ENODEV;
+
+ phydev_info(phydev, "Detected internal RTL9300 Serdes\n");
+
+ return 0;
+}
+
+static struct phy_driver rtl83xx_phy_driver[] = {
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8214C),
+ .name = "Realtek RTL8214C",
+ .features = PHY_GBIT_FEATURES,
+ .match_phy_device = rtl8214c_match_phy_device,
+ .probe = rtl8214c_phy_probe,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC),
+ .name = "Realtek RTL8214FC",
+ .features = PHY_GBIT_FIBRE_FEATURES,
+ .match_phy_device = rtl8214fc_match_phy_device,
+ .probe = rtl8214fc_phy_probe,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .suspend = rtl8214fc_suspend,
+ .resume = rtl8214fc_resume,
+ .set_loopback = genphy_loopback,
+ .set_port = rtl8214fc_set_port,
+ .get_port = rtl8214fc_get_port,
+ .set_eee = rtl8214fc_set_eee,
+ .get_eee = rtl8214fc_get_eee,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_E),
+ .name = "Realtek RTL8218B (external)",
+ .features = PHY_GBIT_FEATURES,
+ .match_phy_device = rtl8218b_ext_match_phy_device,
+ .probe = rtl8218b_ext_phy_probe,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .set_eee = rtl8218b_set_eee,
+ .get_eee = rtl8218b_get_eee,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8218D),
+ .name = "REALTEK RTL8218D",
+ .features = PHY_GBIT_FEATURES,
+ .probe = rtl8218d_phy_probe,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .set_eee = rtl8218d_set_eee,
+ .get_eee = rtl8218d_get_eee,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8221B),
+ .name = "REALTEK RTL8221B",
+ .features = PHY_GBIT_FEATURES,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .read_status = rtl8226_read_status,
+ .config_aneg = rtl8226_config_aneg,
+ .set_eee = rtl8226_set_eee,
+ .get_eee = rtl8226_get_eee,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8226),
+ .name = "REALTEK RTL8226",
+ .features = PHY_GBIT_FEATURES,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .read_status = rtl8226_read_status,
+ .config_aneg = rtl8226_config_aneg,
+ .set_eee = rtl8226_set_eee,
+ .get_eee = rtl8226_get_eee,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I),
+ .name = "Realtek RTL8218B (internal)",
+ .features = PHY_GBIT_FEATURES,
+ .probe = rtl8218b_int_phy_probe,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .set_eee = rtl8218b_set_eee,
+ .get_eee = rtl8218b_get_eee,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I),
+ .name = "Realtek RTL8380 SERDES",
+ .features = PHY_GBIT_FIBRE_FEATURES,
+ .probe = rtl838x_serdes_probe,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .read_status = rtl8380_read_status,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8393_I),
+ .name = "Realtek RTL8393 SERDES",
+ .features = PHY_GBIT_FIBRE_FEATURES,
+ .probe = rtl8393_serdes_probe,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .read_status = rtl8393_read_status,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL8390_GENERIC),
+ .name = "Realtek RTL8390 Generic",
+ .features = PHY_GBIT_FIBRE_FEATURES,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .probe = rtl8390_serdes_probe,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_RTL9300_I),
+ .name = "REALTEK RTL9300 SERDES",
+ .features = PHY_GBIT_FIBRE_FEATURES,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .probe = rtl9300_serdes_probe,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .set_loopback = genphy_loopback,
+ .read_status = rtl9300_read_status,
+ },
+};
+
+module_phy_driver(rtl83xx_phy_driver);
+
+static struct mdio_device_id __maybe_unused rtl83xx_tbl[] = {
+ { PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(mdio, rtl83xx_tbl);
+
+MODULE_AUTHOR("B. Koblitz");
+MODULE_DESCRIPTION("RTL83xx PHY driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.h b/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.h
index fb79560e6b..fb79560e6b 100644
--- a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.h
+++ b/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.h
diff --git a/target/linux/realtek/files-5.15/include/dt-bindings/clock/rtl83xx-clk.h b/target/linux/realtek/files-6.6/include/dt-bindings/clock/rtl83xx-clk.h
index 3937052cc5..3937052cc5 100644
--- a/target/linux/realtek/files-5.15/include/dt-bindings/clock/rtl83xx-clk.h
+++ b/target/linux/realtek/files-6.6/include/dt-bindings/clock/rtl83xx-clk.h
diff --git a/target/linux/realtek/image/Makefile b/target/linux/realtek/image/Makefile
index bb704ac863..19fab03dba 100644
--- a/target/linux/realtek/image/Makefile
+++ b/target/linux/realtek/image/Makefile
@@ -6,6 +6,8 @@ include $(INCLUDE_DIR)/image.mk
KERNEL_LOADADDR = 0x80100000
DEVICE_VARS += \
+ BELKIN_HEADER \
+ BELKIN_MODEL \
CAMEO_BOARD_MODEL \
CAMEO_BOARD_VERSION \
CAMEO_CUSTOMER_SIGNATURE \
@@ -14,6 +16,7 @@ DEVICE_VARS += \
CAMEO_ROOTFS_PART \
H3C_DEVICE_ID \
H3C_PRODUCT_ID \
+ LINKSYS_HEADER \
ZYXEL_VERS
define Build/zyxel-vers
@@ -71,6 +74,16 @@ define Build/h3c-vfs
mv $@.new $@
endef
+define Build/belkin-header
+ $(SCRIPT_DIR)/belkin-header.py $(@) $(@).new $(BELKIN_HEADER) ${BELKIN_MODEL}
+ mv $@.new $@
+endef
+
+define Build/linksys-image
+ $(SCRIPT_DIR)/linksys-image.sh $(@) $(@).new $(LINKSYS_MODEL)
+ mv $@.new $@
+endef
+
define Device/Default
PROFILES = Default
KERNEL := \
@@ -83,7 +96,7 @@ define Device/Default
append-dtb | \
libdeflate-gzip | \
uImage gzip
- DEVICE_DTS_DIR := ../dts-$(KERNEL_PATCHVER)
+ DEVICE_DTS_DIR := ../dts
DEVICE_DTS = $$(SOC)_$(1)
IMAGES := sysupgrade.bin
IMAGE/sysupgrade.bin := \
diff --git a/target/linux/realtek/image/common.mk b/target/linux/realtek/image/common.mk
index 37370f1999..27fcea86ec 100644
--- a/target/linux/realtek/image/common.mk
+++ b/target/linux/realtek/image/common.mk
@@ -57,7 +57,7 @@ define Device/hpe_1920
endef
define Device/zyxel_gs1900
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
IMAGE_SIZE := 6976k
UIMAGE_MAGIC := 0x83800000
KERNEL_INITRAMFS := \
diff --git a/target/linux/realtek/image/rtl838x.mk b/target/linux/realtek/image/rtl838x.mk
index 7c64d8d667..01397af931 100644
--- a/target/linux/realtek/image/rtl838x.mk
+++ b/target/linux/realtek/image/rtl838x.mk
@@ -71,10 +71,19 @@ define Device/d-link_dgs-1210-28mp-f
SOC := rtl8382
DEVICE_MODEL := DGS-1210-28MP
DEVICE_VARIANT := F
- DEVICE_PACKAGES += realtek-poe
+ DEVICE_PACKAGES += realtek-poe kmod-hwmon-lm63
endef
TARGET_DEVICES += d-link_dgs-1210-28mp-f
+define Device/d-link_dgs-1210-28p-f
+ $(Device/d-link_dgs-1210)
+ SOC := rtl8382
+ DEVICE_MODEL := DGS-1210-28P
+ DEVICE_VARIANT := F
+ DEVICE_PACKAGES += realtek-poe kmod-hwmon-lm63
+endef
+TARGET_DEVICES += d-link_dgs-1210-28p-f
+
# The "IMG-" uImage name allows flashing the iniramfs from the vendor Web UI.
# Avoided for sysupgrade, as the vendor FW would do an incomplete flash.
define Device/engenius_ews2910p
@@ -153,6 +162,27 @@ define Device/iodata_bsh-g24mb
endef
TARGET_DEVICES += iodata_bsh-g24mb
+define Device/linksys_lgs310c
+ SOC := rtl8380
+ IMAGE_SIZE := 13504k
+ DEVICE_VENDOR := Linksys
+ DEVICE_MODEL := LGS310C
+ BELKIN_MODEL := BKS-RTL83xx
+ BELKIN_HEADER := 0x07800001
+ LINKSYS_MODEL := 60402060
+ IMAGES += factory.imag
+ IMAGE/factory.imag := \
+ append-kernel | \
+ pad-to 64k | \
+ append-rootfs | \
+ pad-rootfs | \
+ check-size | \
+ append-metadata | \
+ linksys-image | \
+ belkin-header
+endef
+TARGET_DEVICES += linksys_lgs310c
+
# "NGE" refers to the uImage magic
define Device/netgear_nge
KERNEL := \
@@ -314,7 +344,7 @@ define Device/zyxel_gs1900-8
SOC := rtl8380
DEVICE_MODEL := GS1900-8
DEVICE_VARIANT := v1
- DEVICE_ALT0_VENDOR := ZyXEL
+ DEVICE_ALT0_VENDOR := Zyxel
DEVICE_ALT0_MODEL := GS1900-8
DEVICE_ALT0_VARIANT := v2
ZYXEL_VERS := AAHH
diff --git a/target/linux/realtek/image/rtl839x.mk b/target/linux/realtek/image/rtl839x.mk
index 65078e0c44..14d23ff371 100644
--- a/target/linux/realtek/image/rtl839x.mk
+++ b/target/linux/realtek/image/rtl839x.mk
@@ -9,6 +9,23 @@ define Device/d-link_dgs-1210-52
endef
TARGET_DEVICES += d-link_dgs-1210-52
+define Device/hpe_1920-48g
+ $(Device/hpe_1920)
+ SOC := rtl8393
+ DEVICE_MODEL := 1920-48G (JG927A)
+ H3C_DEVICE_ID := 0x0001002a
+endef
+TARGET_DEVICES += hpe_1920-48g
+
+define Device/hpe_1920-48g-poe
+ $(Device/hpe_1920)
+ SOC := rtl8393
+ DEVICE_MODEL := 1920-48G-PoE (JG928A)
+ DEVICE_PACKAGES += realtek-poe
+ H3C_DEVICE_ID := 0x0001002b
+endef
+TARGET_DEVICES += hpe_1920-48g-poe
+
# When the factory image won't fit anymore, it can be removed.
# New installation will be performed booting the initramfs image from
# ram and then flashing the sysupgrade image from OpenWrt
diff --git a/target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch b/target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch
deleted file mode 100644
index 7df22b0725..0000000000
--- a/target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch
+++ /dev/null
@@ -1,467 +0,0 @@
-From 293903b9dfe43520f01374dc1661be11d6838c49 Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Thu, 18 Nov 2021 17:29:52 +0100
-Subject: watchdog: Add Realtek Otto watchdog timer
-
-Realtek MIPS SoCs (platform name Otto) have a watchdog timer with
-pretimeout notifitication support. The WDT can (partially) hard reset,
-or soft reset the SoC.
-
-This driver implements all features as described in the devicetree
-binding, except the phase2 interrupt, and also functions as a restart
-handler. The cpu reset mode is considered to be a "warm" restart, since
-this mode does not reset all peripherals. Being an embedded system
-though, the "cpu" and "software" modes will still cause the bootloader
-to run on restart.
-
-It is not known how a forced system reset can be disabled on the
-supported platforms. This means that the phase2 interrupt will only fire
-at the same time as reset, so implementing phase2 is of little use.
-
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
-Link: https://lore.kernel.org/r/6d060bccbdcc709cfa79203485db85aad3c3beb5.1637252610.git.sander@svanheule.net
-Signed-off-by: Guenter Roeck <linux@roeck-us.net>
----
- MAINTAINERS | 7 +
- drivers/watchdog/Kconfig | 13 ++
- drivers/watchdog/Makefile | 1 +
- drivers/watchdog/realtek_otto_wdt.c | 384 ++++++++++++++++++++++++++++++++++++
- 4 files changed, 405 insertions(+)
- create mode 100644 drivers/watchdog/realtek_otto_wdt.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -15903,6 +15903,13 @@ S: Maintained
- F: include/sound/rt*.h
- F: sound/soc/codecs/rt*
-
-+REALTEK OTTO WATCHDOG
-+M: Sander Vanheule <sander@svanheule.net>
-+L: linux-watchdog@vger.kernel.org
-+S: Maintained
-+F: Documentation/devicetree/bindings/watchdog/realtek,otto-wdt.yaml
-+F: driver/watchdog/realtek_otto_wdt.c
-+
- REALTEK RTL83xx SMI DSA ROUTER CHIPS
- M: Linus Walleij <linus.walleij@linaro.org>
- S: Maintained
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -954,6 +954,19 @@ config RTD119X_WATCHDOG
- Say Y here to include support for the watchdog timer in
- Realtek RTD1295 SoCs.
-
-+config REALTEK_OTTO_WDT
-+ tristate "Realtek Otto MIPS watchdog support"
-+ depends on MACH_REALTEK_RTL || COMPILE_TEST
-+ depends on COMMON_CLK
-+ select WATCHDOG_CORE
-+ default MACH_REALTEK_RTL
-+ help
-+ Say Y here to include support for the watchdog timer on Realtek
-+ RTL838x, RTL839x, RTL930x SoCs. This watchdog has pretimeout
-+ notifications and system reset on timeout.
-+
-+ When built as a module this will be called realtek_otto_wdt.
-+
- config SPRD_WATCHDOG
- tristate "Spreadtrum watchdog support"
- depends on ARCH_SPRD || COMPILE_TEST
---- a/drivers/watchdog/Makefile
-+++ b/drivers/watchdog/Makefile
-@@ -171,6 +171,7 @@ obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o
- obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o
- obj-$(CONFIG_PIC32_WDT) += pic32-wdt.o
- obj-$(CONFIG_PIC32_DMT) += pic32-dmt.o
-+obj-$(CONFIG_REALTEK_OTTO_WDT) += realtek_otto_wdt.o
-
- # PARISC Architecture
-
---- /dev/null
-+++ b/drivers/watchdog/realtek_otto_wdt.c
-@@ -0,0 +1,384 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+
-+/*
-+ * Realtek Otto MIPS platform watchdog
-+ *
-+ * Watchdog timer that will reset the system after timeout, using the selected
-+ * reset mode.
-+ *
-+ * Counter scaling and timeouts:
-+ * - Base prescale of (2 << 25), providing tick duration T_0: 168ms @ 200MHz
-+ * - PRESCALE: logarithmic prescaler adding a factor of {1, 2, 4, 8}
-+ * - Phase 1: Times out after (PHASE1 + 1) × PRESCALE × T_0
-+ * Generates an interrupt, WDT cannot be stopped after phase 1
-+ * - Phase 2: starts after phase 1, times out after (PHASE2 + 1) × PRESCALE × T_0
-+ * Resets the system according to RST_MODE
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/bitfield.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/math.h>
-+#include <linux/minmax.h>
-+#include <linux/module.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/platform_device.h>
-+#include <linux/property.h>
-+#include <linux/reboot.h>
-+#include <linux/watchdog.h>
-+
-+#define OTTO_WDT_REG_CNTR 0x0
-+#define OTTO_WDT_CNTR_PING BIT(31)
-+
-+#define OTTO_WDT_REG_INTR 0x4
-+#define OTTO_WDT_INTR_PHASE_1 BIT(31)
-+#define OTTO_WDT_INTR_PHASE_2 BIT(30)
-+
-+#define OTTO_WDT_REG_CTRL 0x8
-+#define OTTO_WDT_CTRL_ENABLE BIT(31)
-+#define OTTO_WDT_CTRL_PRESCALE GENMASK(30, 29)
-+#define OTTO_WDT_CTRL_PHASE1 GENMASK(26, 22)
-+#define OTTO_WDT_CTRL_PHASE2 GENMASK(19, 15)
-+#define OTTO_WDT_CTRL_RST_MODE GENMASK(1, 0)
-+#define OTTO_WDT_MODE_SOC 0
-+#define OTTO_WDT_MODE_CPU 1
-+#define OTTO_WDT_MODE_SOFTWARE 2
-+#define OTTO_WDT_CTRL_DEFAULT OTTO_WDT_MODE_CPU
-+
-+#define OTTO_WDT_PRESCALE_MAX 3
-+
-+/*
-+ * One higher than the max values contained in PHASE{1,2}, since a value of 0
-+ * corresponds to one tick.
-+ */
-+#define OTTO_WDT_PHASE_TICKS_MAX 32
-+
-+/*
-+ * The maximum reset delay is actually 2×32 ticks, but that would require large
-+ * pretimeout values for timeouts longer than 32 ticks. Limit the maximum timeout
-+ * to 32 + 1 to ensure small pretimeout values can be configured as expected.
-+ */
-+#define OTTO_WDT_TIMEOUT_TICKS_MAX (OTTO_WDT_PHASE_TICKS_MAX + 1)
-+
-+struct otto_wdt_ctrl {
-+ struct watchdog_device wdev;
-+ struct device *dev;
-+ void __iomem *base;
-+ unsigned int clk_rate_khz;
-+ int irq_phase1;
-+};
-+
-+static int otto_wdt_start(struct watchdog_device *wdev)
-+{
-+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
-+ u32 v;
-+
-+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
-+ v |= OTTO_WDT_CTRL_ENABLE;
-+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
-+
-+ return 0;
-+}
-+
-+static int otto_wdt_stop(struct watchdog_device *wdev)
-+{
-+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
-+ u32 v;
-+
-+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
-+ v &= ~OTTO_WDT_CTRL_ENABLE;
-+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
-+
-+ return 0;
-+}
-+
-+static int otto_wdt_ping(struct watchdog_device *wdev)
-+{
-+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
-+
-+ iowrite32(OTTO_WDT_CNTR_PING, ctrl->base + OTTO_WDT_REG_CNTR);
-+
-+ return 0;
-+}
-+
-+static int otto_wdt_tick_ms(struct otto_wdt_ctrl *ctrl, int prescale)
-+{
-+ return DIV_ROUND_CLOSEST(1 << (25 + prescale), ctrl->clk_rate_khz);
-+}
-+
-+/*
-+ * The timer asserts the PHASE1/PHASE2 IRQs when the number of ticks exceeds
-+ * the value stored in those fields. This means each phase will run for at least
-+ * one tick, so small values need to be clamped to correctly reflect the timeout.
-+ */
-+static inline unsigned int div_round_ticks(unsigned int val, unsigned int tick_duration,
-+ unsigned int min_ticks)
-+{
-+ return max(min_ticks, DIV_ROUND_UP(val, tick_duration));
-+}
-+
-+static int otto_wdt_determine_timeouts(struct watchdog_device *wdev, unsigned int timeout,
-+ unsigned int pretimeout)
-+{
-+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
-+ unsigned int pretimeout_ms = pretimeout * 1000;
-+ unsigned int timeout_ms = timeout * 1000;
-+ unsigned int prescale_next = 0;
-+ unsigned int phase1_ticks;
-+ unsigned int phase2_ticks;
-+ unsigned int total_ticks;
-+ unsigned int prescale;
-+ unsigned int tick_ms;
-+ u32 v;
-+
-+ do {
-+ prescale = prescale_next;
-+ if (prescale > OTTO_WDT_PRESCALE_MAX)
-+ return -EINVAL;
-+
-+ tick_ms = otto_wdt_tick_ms(ctrl, prescale);
-+ total_ticks = div_round_ticks(timeout_ms, tick_ms, 2);
-+ phase1_ticks = div_round_ticks(timeout_ms - pretimeout_ms, tick_ms, 1);
-+ phase2_ticks = total_ticks - phase1_ticks;
-+
-+ prescale_next++;
-+ } while (phase1_ticks > OTTO_WDT_PHASE_TICKS_MAX
-+ || phase2_ticks > OTTO_WDT_PHASE_TICKS_MAX);
-+
-+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
-+
-+ v &= ~(OTTO_WDT_CTRL_PRESCALE | OTTO_WDT_CTRL_PHASE1 | OTTO_WDT_CTRL_PHASE2);
-+ v |= FIELD_PREP(OTTO_WDT_CTRL_PHASE1, phase1_ticks - 1);
-+ v |= FIELD_PREP(OTTO_WDT_CTRL_PHASE2, phase2_ticks - 1);
-+ v |= FIELD_PREP(OTTO_WDT_CTRL_PRESCALE, prescale);
-+
-+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
-+
-+ timeout_ms = total_ticks * tick_ms;
-+ ctrl->wdev.timeout = timeout_ms / 1000;
-+
-+ pretimeout_ms = phase2_ticks * tick_ms;
-+ ctrl->wdev.pretimeout = pretimeout_ms / 1000;
-+
-+ return 0;
-+}
-+
-+static int otto_wdt_set_timeout(struct watchdog_device *wdev, unsigned int val)
-+{
-+ return otto_wdt_determine_timeouts(wdev, val, min(wdev->pretimeout, val - 1));
-+}
-+
-+static int otto_wdt_set_pretimeout(struct watchdog_device *wdev, unsigned int val)
-+{
-+ return otto_wdt_determine_timeouts(wdev, wdev->timeout, val);
-+}
-+
-+static int otto_wdt_restart(struct watchdog_device *wdev, unsigned long reboot_mode,
-+ void *data)
-+{
-+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
-+ u32 reset_mode;
-+ u32 v;
-+
-+ disable_irq(ctrl->irq_phase1);
-+
-+ switch (reboot_mode) {
-+ case REBOOT_SOFT:
-+ reset_mode = OTTO_WDT_MODE_SOFTWARE;
-+ break;
-+ case REBOOT_WARM:
-+ reset_mode = OTTO_WDT_MODE_CPU;
-+ break;
-+ default:
-+ reset_mode = OTTO_WDT_MODE_SOC;
-+ break;
-+ }
-+
-+ /* Configure for shortest timeout and wait for reset to occur */
-+ v = FIELD_PREP(OTTO_WDT_CTRL_RST_MODE, reset_mode) | OTTO_WDT_CTRL_ENABLE;
-+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
-+
-+ mdelay(3 * otto_wdt_tick_ms(ctrl, 0));
-+
-+ return 0;
-+}
-+
-+static irqreturn_t otto_wdt_phase1_isr(int irq, void *dev_id)
-+{
-+ struct otto_wdt_ctrl *ctrl = dev_id;
-+
-+ iowrite32(OTTO_WDT_INTR_PHASE_1, ctrl->base + OTTO_WDT_REG_INTR);
-+ dev_crit(ctrl->dev, "phase 1 timeout\n");
-+ watchdog_notify_pretimeout(&ctrl->wdev);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static const struct watchdog_ops otto_wdt_ops = {
-+ .owner = THIS_MODULE,
-+ .start = otto_wdt_start,
-+ .stop = otto_wdt_stop,
-+ .ping = otto_wdt_ping,
-+ .set_timeout = otto_wdt_set_timeout,
-+ .set_pretimeout = otto_wdt_set_pretimeout,
-+ .restart = otto_wdt_restart,
-+};
-+
-+static const struct watchdog_info otto_wdt_info = {
-+ .identity = "Realtek Otto watchdog timer",
-+ .options = WDIOF_KEEPALIVEPING |
-+ WDIOF_MAGICCLOSE |
-+ WDIOF_SETTIMEOUT |
-+ WDIOF_PRETIMEOUT,
-+};
-+
-+static void otto_wdt_clock_action(void *data)
-+{
-+ clk_disable_unprepare(data);
-+}
-+
-+static int otto_wdt_probe_clk(struct otto_wdt_ctrl *ctrl)
-+{
-+ struct clk *clk = devm_clk_get(ctrl->dev, NULL);
-+ int ret;
-+
-+ if (IS_ERR(clk))
-+ return dev_err_probe(ctrl->dev, PTR_ERR(clk), "Failed to get clock\n");
-+
-+ ret = clk_prepare_enable(clk);
-+ if (ret)
-+ return dev_err_probe(ctrl->dev, ret, "Failed to enable clock\n");
-+
-+ ret = devm_add_action_or_reset(ctrl->dev, otto_wdt_clock_action, clk);
-+ if (ret)
-+ return ret;
-+
-+ ctrl->clk_rate_khz = clk_get_rate(clk) / 1000;
-+ if (ctrl->clk_rate_khz == 0)
-+ return dev_err_probe(ctrl->dev, -ENXIO, "Failed to get clock rate\n");
-+
-+ return 0;
-+}
-+
-+static int otto_wdt_probe_reset_mode(struct otto_wdt_ctrl *ctrl)
-+{
-+ static const char *mode_property = "realtek,reset-mode";
-+ const struct fwnode_handle *node = ctrl->dev->fwnode;
-+ int mode_count;
-+ u32 mode;
-+ u32 v;
-+
-+ if (!node)
-+ return -ENXIO;
-+
-+ mode_count = fwnode_property_string_array_count(node, mode_property);
-+ if (mode_count < 0)
-+ return mode_count;
-+ else if (mode_count == 0)
-+ return 0;
-+ else if (mode_count != 1)
-+ return -EINVAL;
-+
-+ if (fwnode_property_match_string(node, mode_property, "soc") == 0)
-+ mode = OTTO_WDT_MODE_SOC;
-+ else if (fwnode_property_match_string(node, mode_property, "cpu") == 0)
-+ mode = OTTO_WDT_MODE_CPU;
-+ else if (fwnode_property_match_string(node, mode_property, "software") == 0)
-+ mode = OTTO_WDT_MODE_SOFTWARE;
-+ else
-+ return -EINVAL;
-+
-+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
-+ v &= ~OTTO_WDT_CTRL_RST_MODE;
-+ v |= FIELD_PREP(OTTO_WDT_CTRL_RST_MODE, mode);
-+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
-+
-+ return 0;
-+}
-+
-+static int otto_wdt_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct otto_wdt_ctrl *ctrl;
-+ unsigned int max_tick_ms;
-+ int ret;
-+
-+ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
-+ if (!ctrl)
-+ return -ENOMEM;
-+
-+ ctrl->dev = dev;
-+ ctrl->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(ctrl->base))
-+ return PTR_ERR(ctrl->base);
-+
-+ /* Clear any old interrupts and reset initial state */
-+ iowrite32(OTTO_WDT_INTR_PHASE_1 | OTTO_WDT_INTR_PHASE_2,
-+ ctrl->base + OTTO_WDT_REG_INTR);
-+ iowrite32(OTTO_WDT_CTRL_DEFAULT, ctrl->base + OTTO_WDT_REG_CTRL);
-+
-+ ret = otto_wdt_probe_clk(ctrl);
-+ if (ret)
-+ return ret;
-+
-+ ctrl->irq_phase1 = platform_get_irq_byname(pdev, "phase1");
-+ if (ctrl->irq_phase1 < 0)
-+ return ctrl->irq_phase1;
-+
-+ ret = devm_request_irq(dev, ctrl->irq_phase1, otto_wdt_phase1_isr, 0,
-+ "realtek-otto-wdt", ctrl);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Failed to get IRQ for phase1\n");
-+
-+ ret = otto_wdt_probe_reset_mode(ctrl);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Invalid reset mode specified\n");
-+
-+ ctrl->wdev.parent = dev;
-+ ctrl->wdev.info = &otto_wdt_info;
-+ ctrl->wdev.ops = &otto_wdt_ops;
-+
-+ /*
-+ * Since pretimeout cannot be disabled, min. timeout is twice the
-+ * subsystem resolution. Max. timeout is ca. 43s at a bus clock of 200MHz.
-+ */
-+ ctrl->wdev.min_timeout = 2;
-+ max_tick_ms = otto_wdt_tick_ms(ctrl, OTTO_WDT_PRESCALE_MAX);
-+ ctrl->wdev.max_hw_heartbeat_ms = max_tick_ms * OTTO_WDT_TIMEOUT_TICKS_MAX;
-+ ctrl->wdev.timeout = min(30U, ctrl->wdev.max_hw_heartbeat_ms / 1000);
-+
-+ watchdog_set_drvdata(&ctrl->wdev, ctrl);
-+ watchdog_init_timeout(&ctrl->wdev, 0, dev);
-+ watchdog_stop_on_reboot(&ctrl->wdev);
-+ watchdog_set_restart_priority(&ctrl->wdev, 128);
-+
-+ ret = otto_wdt_determine_timeouts(&ctrl->wdev, ctrl->wdev.timeout, 1);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Failed to set timeout\n");
-+
-+ return devm_watchdog_register_device(dev, &ctrl->wdev);
-+}
-+
-+static const struct of_device_id otto_wdt_ids[] = {
-+ { .compatible = "realtek,rtl8380-wdt" },
-+ { .compatible = "realtek,rtl8390-wdt" },
-+ { .compatible = "realtek,rtl9300-wdt" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, otto_wdt_ids);
-+
-+static struct platform_driver otto_wdt_driver = {
-+ .probe = otto_wdt_probe,
-+ .driver = {
-+ .name = "realtek-otto-watchdog",
-+ .of_match_table = otto_wdt_ids,
-+ },
-+};
-+module_platform_driver(otto_wdt_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
-+MODULE_DESCRIPTION("Realtek Otto watchdog timer driver");
diff --git a/target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch b/target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch
deleted file mode 100644
index da33aaa72f..0000000000
--- a/target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From c6af53f038aa32cec12e8a305ba07c7ef168f1b0 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 4 Jan 2022 12:07:00 +0000
-Subject: [PATCH 2/3] net: mdio: add helpers to extract clause 45 regad and
- devad fields
-
-Add a couple of helpers and definitions to extract the clause 45 regad
-and devad fields from the regnum passed into MDIO drivers.
-
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/linux/mdio.h | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/include/linux/mdio.h
-+++ b/include/linux/mdio.h
-@@ -7,6 +7,7 @@
- #define __LINUX_MDIO_H__
-
- #include <uapi/linux/mdio.h>
-+#include <linux/bitfield.h>
- #include <linux/mod_devicetable.h>
-
- /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
-@@ -14,6 +15,7 @@
- */
- #define MII_ADDR_C45 (1<<30)
- #define MII_DEVADDR_C45_SHIFT 16
-+#define MII_DEVADDR_C45_MASK GENMASK(20, 16)
- #define MII_REGADDR_C45_MASK GENMASK(15, 0)
-
- struct gpio_desc;
-@@ -355,6 +357,16 @@ static inline u32 mdiobus_c45_addr(int d
- return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
- }
-
-+static inline u16 mdiobus_c45_regad(u32 regnum)
-+{
-+ return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
-+}
-+
-+static inline u16 mdiobus_c45_devad(u32 regnum)
-+{
-+ return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
-+}
-+
- static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
- u16 regnum)
- {
diff --git a/target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch b/target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch
deleted file mode 100644
index 437e7862d9..0000000000
--- a/target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From 512c5be35223d9baa2629efa1084cf5210eaee80 Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sat, 9 Apr 2022 21:55:47 +0200
-Subject: [PATCH 2/6] gpio: realtek-otto: Support reversed port layouts
-
-The GPIO port layout on the RTL930x SoC series is reversed compared to
-the RTL838x and RTL839x SoC series. Add new port offset calculator
-functions to ensure the correct order is used when reading port IRQ
-data, and ensure bgpio uses the right byte ordering.
-
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
----
- drivers/gpio/gpio-realtek-otto.c | 55 +++++++++++++++++++++++++++++---
- 1 file changed, 51 insertions(+), 4 deletions(-)
-
---- a/drivers/gpio/gpio-realtek-otto.c
-+++ b/drivers/gpio/gpio-realtek-otto.c
-@@ -58,6 +58,8 @@ struct realtek_gpio_ctrl {
- raw_spinlock_t lock;
- u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK];
- u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK];
-+ unsigned int (*port_offset_u8)(unsigned int port);
-+ unsigned int (*port_offset_u16)(unsigned int port);
- };
-
- /* Expand with more flags as devices with other quirks are added */
-@@ -69,6 +71,11 @@ enum realtek_gpio_flags {
- * line the IRQ handler was assigned to, causing uncaught interrupts.
- */
- GPIO_INTERRUPTS_DISABLED = BIT(0),
-+ /*
-+ * Port order is reversed, meaning DCBA register layout for 1-bit
-+ * fields, and [BA, DC] for 2-bit fields.
-+ */
-+ GPIO_PORTS_REVERSED = BIT(1),
- };
-
- static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)
-@@ -86,21 +93,50 @@ static struct realtek_gpio_ctrl *irq_dat
- * port. The two interrupt mask registers store two bits per GPIO, so use u16
- * values.
- */
-+static unsigned int realtek_gpio_port_offset_u8(unsigned int port)
-+{
-+ return port;
-+}
-+
-+static unsigned int realtek_gpio_port_offset_u16(unsigned int port)
-+{
-+ return 2 * port;
-+}
-+
-+/*
-+ * Reversed port order register access
-+ *
-+ * For registers with one bit per GPIO, all ports are stored as u8-s in one
-+ * register in reversed order. The two interrupt mask registers store two bits
-+ * per GPIO, so use u16 values. The first register contains ports 1 and 0, the
-+ * second ports 3 and 2.
-+ */
-+static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port)
-+{
-+ return 3 - port;
-+}
-+
-+static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port)
-+{
-+ return 2 * (port ^ 1);
-+}
-+
- static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl,
- unsigned int port, u16 irq_type, u16 irq_mask)
- {
-- iowrite16(irq_type & irq_mask, ctrl->base + REALTEK_GPIO_REG_IMR + 2 * port);
-+ iowrite16(irq_type & irq_mask,
-+ ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port));
- }
-
- static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl,
- unsigned int port, u8 mask)
- {
-- iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + port);
-+ iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
- }
-
- static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port)
- {
-- return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + port);
-+ return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
- }
-
- /* Set the rising and falling edge mask bits for a GPIO port pin */
-@@ -250,6 +286,7 @@ MODULE_DEVICE_TABLE(of, realtek_gpio_of_
- static int realtek_gpio_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-+ unsigned long bgpio_flags;
- unsigned int dev_flags;
- struct gpio_irq_chip *girq;
- struct realtek_gpio_ctrl *ctrl;
-@@ -277,10 +314,20 @@ static int realtek_gpio_probe(struct pla
-
- raw_spin_lock_init(&ctrl->lock);
-
-+ if (dev_flags & GPIO_PORTS_REVERSED) {
-+ bgpio_flags = 0;
-+ ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev;
-+ ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev;
-+ } else {
-+ bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
-+ ctrl->port_offset_u8 = realtek_gpio_port_offset_u8;
-+ ctrl->port_offset_u16 = realtek_gpio_port_offset_u16;
-+ }
-+
- err = bgpio_init(&ctrl->gc, dev, 4,
- ctrl->base + REALTEK_GPIO_REG_DATA, NULL, NULL,
- ctrl->base + REALTEK_GPIO_REG_DIR, NULL,
-- BGPIOF_BIG_ENDIAN_BYTE_ORDER);
-+ bgpio_flags);
- if (err) {
- dev_err(dev, "unable to init generic GPIO");
- return err;
diff --git a/target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch b/target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch
deleted file mode 100644
index b632095c36..0000000000
--- a/target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 95fa6dbe58f286a8f87cb37b7516232eb678de2d Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sat, 9 Apr 2022 21:55:48 +0200
-Subject: [PATCH 3/6] gpio: realtek-otto: Support per-cpu interrupts
-
-On SoCs with multiple cores, it is possible that the GPIO interrupt
-controller supports assigning specific pins to one or more cores.
-
-IRQ balancing can be performed on a line-by-line basis if the parent
-interrupt is routed to all available cores, which is the default upon
-initialisation.
-
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
----
- drivers/gpio/gpio-realtek-otto.c | 75 +++++++++++++++++++++++++++++++-
- 1 file changed, 74 insertions(+), 1 deletion(-)
-
---- a/drivers/gpio/gpio-realtek-otto.c
-+++ b/drivers/gpio/gpio-realtek-otto.c
-@@ -1,6 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-only
-
- #include <linux/gpio/driver.h>
-+#include <linux/cpumask.h>
- #include <linux/irq.h>
- #include <linux/minmax.h>
- #include <linux/mod_devicetable.h>
-@@ -55,6 +56,8 @@
- struct realtek_gpio_ctrl {
- struct gpio_chip gc;
- void __iomem *base;
-+ void __iomem *cpumask_base;
-+ struct cpumask cpu_irq_maskable;
- raw_spinlock_t lock;
- u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK];
- u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK];
-@@ -76,6 +79,11 @@ enum realtek_gpio_flags {
- * fields, and [BA, DC] for 2-bit fields.
- */
- GPIO_PORTS_REVERSED = BIT(1),
-+ /*
-+ * Interrupts can be enabled per cpu. This requires a secondary IO
-+ * range, where the per-cpu enable masks are located.
-+ */
-+ GPIO_INTERRUPTS_PER_CPU = BIT(2),
- };
-
- static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)
-@@ -247,14 +255,61 @@ static void realtek_gpio_irq_handler(str
- chained_irq_exit(irq_chip, desc);
- }
-
-+static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl,
-+ unsigned int port, int cpu)
-+{
-+ return ctrl->cpumask_base + ctrl->port_offset_u8(port) +
-+ REALTEK_GPIO_PORTS_PER_BANK * cpu;
-+}
-+
-+static int realtek_gpio_irq_set_affinity(struct irq_data *data,
-+ const struct cpumask *dest, bool force)
-+{
-+ struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
-+ unsigned int line = irqd_to_hwirq(data);
-+ unsigned int port = line / 8;
-+ unsigned int port_pin = line % 8;
-+ void __iomem *irq_cpu_mask;
-+ unsigned long flags;
-+ int cpu;
-+ u8 v;
-+
-+ if (!ctrl->cpumask_base)
-+ return -ENXIO;
-+
-+ raw_spin_lock_irqsave(&ctrl->lock, flags);
-+
-+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
-+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
-+ v = ioread8(irq_cpu_mask);
-+
-+ if (cpumask_test_cpu(cpu, dest))
-+ v |= BIT(port_pin);
-+ else
-+ v &= ~BIT(port_pin);
-+
-+ iowrite8(v, irq_cpu_mask);
-+ }
-+
-+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
-+
-+ irq_data_update_effective_affinity(data, dest);
-+
-+ return 0;
-+}
-+
- static int realtek_gpio_irq_init(struct gpio_chip *gc)
- {
- struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
- unsigned int port;
-+ int cpu;
-
- for (port = 0; (port * 8) < gc->ngpio; port++) {
- realtek_gpio_write_imr(ctrl, port, 0, 0);
- realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0));
-+
-+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable)
-+ iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu));
- }
-
- return 0;
-@@ -266,6 +321,7 @@ static struct irq_chip realtek_gpio_irq_
- .irq_mask = realtek_gpio_irq_mask,
- .irq_unmask = realtek_gpio_irq_unmask,
- .irq_set_type = realtek_gpio_irq_set_type,
-+ .irq_set_affinity = realtek_gpio_irq_set_affinity,
- };
-
- static const struct of_device_id realtek_gpio_of_match[] = {
-@@ -290,8 +346,10 @@ static int realtek_gpio_probe(struct pla
- unsigned int dev_flags;
- struct gpio_irq_chip *girq;
- struct realtek_gpio_ctrl *ctrl;
-+ struct resource *res;
- u32 ngpios;
-- int err, irq;
-+ unsigned int nr_cpus;
-+ int cpu, err, irq;
-
- ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
- if (!ctrl)
-@@ -352,6 +410,21 @@ static int realtek_gpio_probe(struct pla
- girq->init_hw = realtek_gpio_irq_init;
- }
-
-+ cpumask_clear(&ctrl->cpu_irq_maskable);
-+
-+ if ((dev_flags & GPIO_INTERRUPTS_PER_CPU) && irq > 0) {
-+ ctrl->cpumask_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res);
-+ if (IS_ERR(ctrl->cpumask_base))
-+ return dev_err_probe(dev, PTR_ERR(ctrl->cpumask_base),
-+ "missing CPU IRQ mask registers");
-+
-+ nr_cpus = resource_size(res) / REALTEK_GPIO_PORTS_PER_BANK;
-+ nr_cpus = min(nr_cpus, num_present_cpus());
-+
-+ for (cpu = 0; cpu < nr_cpus; cpu++)
-+ cpumask_set_cpu(cpu, &ctrl->cpu_irq_maskable);
-+ }
-+
- return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
- }
-
diff --git a/target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch b/target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch
deleted file mode 100644
index 9b25803138..0000000000
--- a/target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From deaf1cecdeb052cdb5e92fd642016198724b44a4 Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sat, 9 Apr 2022 21:55:49 +0200
-Subject: [PATCH 4/6] gpio: realtek-otto: Add RTL930x support
-
-The RTL930x SoC series has support for 24 GPIOs, with the port order
-reversed compared to RTL838x and RTL839x. The RTL930x series also has
-two CPUs (VPEs) and can distribute individual GPIO interrupts between
-them.
-
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
----
- drivers/gpio/gpio-realtek-otto.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/gpio/gpio-realtek-otto.c
-+++ b/drivers/gpio/gpio-realtek-otto.c
-@@ -335,6 +335,10 @@ static const struct of_device_id realtek
- {
- .compatible = "realtek,rtl8390-gpio",
- },
-+ {
-+ .compatible = "realtek,rtl9300-gpio",
-+ .data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU)
-+ },
- {}
- };
- MODULE_DEVICE_TABLE(of, realtek_gpio_of_match);
diff --git a/target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch b/target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch
deleted file mode 100644
index 810856eb89..0000000000
--- a/target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From d3bf3dc4bbbf6109bd9b4bd60089d36205ec4a37 Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sat, 9 Apr 2022 21:55:51 +0200
-Subject: [PATCH 6/6] gpio: realtek-otto: Add RTL931x support
-
-The RTL931x SoC series has support for 32 GPIOs, although not all lines
-may be broken out to a physical pad.
-
-The GPIO bank's parent interrupt can be routed to either or both of the
-SoC's CPU cores by the GIC. Line-by-line IRQ balancing is not possible
-on these SoCs.
-
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
----
- drivers/gpio/gpio-realtek-otto.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/gpio/gpio-realtek-otto.c
-+++ b/drivers/gpio/gpio-realtek-otto.c
-@@ -339,6 +339,9 @@ static const struct of_device_id realtek
- .compatible = "realtek,rtl9300-gpio",
- .data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU)
- },
-+ {
-+ .compatible = "realtek,rtl9310-gpio",
-+ },
- {}
- };
- MODULE_DEVICE_TABLE(of, realtek_gpio_of_match);
diff --git a/target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch b/target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch
deleted file mode 100644
index eaeea0991d..0000000000
--- a/target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From fce11f68491b46b93df69de0630cd9edb90bc772 Mon Sep 17 00:00:00 2001
-From: Birger Koblitz <git@birger-koblitz.de>
-Date: Wed, 29 Dec 2021 21:54:21 +0100
-Subject: [PATCH] realtek: Create 4 different Realtek Platforms
-
-Creates RTL83XX as a basic kernel config parameter for the
-RTL838X, RTL839x, RTL930X and RTL931X platforms with respective
-configurations for the SoCs, which are introduced in addition.
-
-Submitted-by: Birger Koblitz <git@birger-koblitz.de>
----
- arch/mips/Kbuild.platforms | 1 +
- arch/mips/Kconfig | 57 ++++++++++++++
- 2 files changed, 58 insertions(+)
-
---- a/arch/mips/Kbuild.platforms
-+++ b/arch/mips/Kbuild.platforms
-@@ -23,6 +23,7 @@ platform-$(CONFIG_NLM_COMMON) += netlog
- platform-$(CONFIG_PIC32MZDA) += pic32/
- platform-$(CONFIG_RALINK) += ralink/
- platform-$(CONFIG_MIKROTIK_RB532) += rb532/
-+platform-$(CONFIG_RTL83XX) += rtl838x/
- platform-$(CONFIG_SGI_IP22) += sgi-ip22/
- platform-$(CONFIG_SGI_IP27) += sgi-ip27/
- platform-$(CONFIG_SGI_IP28) += sgi-ip22/
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -1056,8 +1056,58 @@ config NLM_XLP_BOARD
- This board is based on Netlogic XLP Processor.
- Say Y here if you have a XLP based board.
-
-+config RTL83XX
-+ bool "Realtek based platforms"
-+ select DMA_NONCOHERENT
-+ select IRQ_MIPS_CPU
-+ select NO_EXCEPT_FILL
-+ select SYS_HAS_CPU_MIPS32_R1
-+ select SYS_HAS_CPU_MIPS32_R2
-+ select SYS_SUPPORTS_BIG_ENDIAN
-+ select SYS_SUPPORTS_HIGHMEM
-+ select SYS_SUPPORTS_32BIT_KERNEL
-+ select SYS_SUPPORTS_MIPS16
-+ select SYS_HAS_EARLY_PRINTK
-+ select SYS_HAS_EARLY_PRINTK_8250
-+ select USE_GENERIC_EARLY_PRINTK_8250
-+ select BOOT_RAW
-+ select PINCTRL
-+ select ARCH_HAS_RESET_CONTROLLER
-+ select RESET_CONTROLLER
-+ select USE_OF
-+
- endchoice
-
-+config RTL838X
-+ bool "Realtek RTL838X based platforms"
-+ depends on RTL83XX
-+ select CPU_SUPPORTS_CPUFREQ
-+ select MIPS_EXTERNAL_TIMER
-+
-+config RTL839X
-+ bool "Realtek RTL839X based platforms"
-+ depends on RTL83XX
-+ select CPU_SUPPORTS_CPUFREQ
-+ select MIPS_EXTERNAL_TIMER
-+ select SYS_SUPPORTS_MULTITHREADING
-+
-+config RTL930X
-+ bool "Realtek RTL930X based platforms"
-+ depends on RTL83XX
-+ select MIPS_CPU_SCACHE
-+ select MIPS_EXTERNAL_TIMER
-+ select SYS_SUPPORTS_MULTITHREADING
-+
-+config RTL931X
-+ bool "Realtek RTL931X based platforms"
-+ depends on RTL930X
-+ select MIPS_GIC
-+ select COMMON_CLK
-+ select CLKSRC_MIPS_GIC
-+ select SYS_SUPPORTS_VPE_LOADER
-+ select SYS_SUPPORTS_SMP
-+ select SYS_SUPPORTS_MIPS_CPS
-+
- source "arch/mips/alchemy/Kconfig"
- source "arch/mips/ath25/Kconfig"
- source "arch/mips/ath79/Kconfig"
diff --git a/target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch b/target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch
deleted file mode 100644
index 7603a03744..0000000000
--- a/target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 26 Nov 2020 12:02:21 +0100
-Subject: [PATCH] realtek: update the tree to the latest refactored version
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-* rename the target to realtek
-* add refactored DSA driver
-* add latest gpio driver
-* lots of arch cleanups
-* new irq driver
-* additional boards
-
-Submitted-by: Bert Vermeulen <bert@biot.com>
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Submitted-by: Bjørn Mork <bjorn@mork.no>
-Submitted-by: John Crispin <john@phrozen.org>
----
- drivers/gpio/Kconfig | 6 ++++++
- drivers/gpio/Makefile | 1 +
- 2 files changed, 7 insertions(+)
-
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -529,6 +529,12 @@ config GPIO_ROCKCHIP
- help
- Say yes here to support GPIO on Rockchip SoCs.
-
-+config GPIO_RTL8231
-+ tristate "RTL8231 GPIO"
-+ depends on RTL83XX
-+ help
-+ Say yes here to support Realtek RTL8231 GPIO expansion chips.
-+
- config GPIO_SAMA5D2_PIOBU
- tristate "SAMA5D2 PIOBU GPIO support"
- depends on MFD_SYSCON
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -129,6 +129,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc3
- obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o
- obj-$(CONFIG_GPIO_REG) += gpio-reg.o
- obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
-+obj-$(CONFIG_GPIO_RTL8231) += gpio-rtl8231.o
- obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
- obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
- obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
diff --git a/target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch b/target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch
deleted file mode 100644
index 63a5050ebb..0000000000
--- a/target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 3cc8011171186d906c547bc6f0c1f8e350edc7cf Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Mon, 3 Oct 2022 14:45:21 +0200
-Subject: [PATCH] realtek: resurrect timer driver
-
-Now that we provide a clock driver for the Reltek SOCs the CPU frequency might
-change on demand. This has direct visible effects during operation
-
-- the CEVT 4K timer is no longer a stable clocksource
-- after CPU frequencies changes time calculation works wrong
-- sched_clock falls back to kernel default interval (100 Hz)
-- timestamps in dmesg have only 2 digits left
-
-[ 0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps ...
-[ 0.060000] pid_max: default: 32768 minimum: 301
-[ 0.070000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
-[ 0.070000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
-[ 0.080000] dyndbg: Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build
-[ 0.090000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, ...
-
-Looking around where we can start the CEVT timer for RTL930X is a good basis.
-Initially it was developed as a clocksource driver for the broken timer in that
-specific SOC series. Afterwards it was shifted around to the CEVT location,
-got SMP enablement and lost its clocksource feature. So we at least have
-something to copy from. As the timers on these devices are well understood
-the implementation follows this way:
-
-- leave the RTL930X implementation as is
-- provide a new driver for RTL83XX devices only
-- swap RTL930X driver at a later time
-
-Like the clock driver this patch contains a self contained module that is SOC
-independet and already provides full support for the RTL838X, RTL839X and
-RTL930X devices. Some of the new (or reestablished) features are:
-
-- simplified initialization routines
-- SMP setup with CPU hotplug framework
-- derived from LXB clock speed
-- supplied clocksource
-- dedicated register functions for better readability
-- documentation about some caveats
-
-Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-[remove unused header includes, remove old CONFIG_MIPS dependency, add
-REALTEK_ prefix to driver symbol]
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-
----
- drivers/clocksource/Kconfig | 12 +++
- drivers/clocksource/Makefile | 1 +
- include/linux/cpuhotplug.h | 1 +
- 3 files changed, 14 insertions(+)
-
---- a/drivers/clocksource/Kconfig
-+++ b/drivers/clocksource/Kconfig
-@@ -127,6 +127,17 @@ config RDA_TIMER
- help
- Enables the support for the RDA Micro timer driver.
-
-+config REALTEK_OTTO_TIMER
-+ bool "Clocksource/timer for the Realtek Otto platform"
-+ select COMMON_CLK
-+ select TIMER_OF
-+ help
-+ This driver adds support for the timers found in the Realtek RTL83xx
-+ and RTL93xx SoCs series. This includes chips such as RTL8380, RTL8381
-+ and RTL832, as well as chips from the RTL839x series, such as RTL8390
-+ RT8391, RTL8392, RTL8393 and RTL8396 and chips of the RTL930x series
-+ such as RTL9301, RTL9302 or RTL9303.
-+
- config SUN4I_TIMER
- bool "Sun4i timer driver" if COMPILE_TEST
- depends on HAS_IOMEM
---- a/drivers/clocksource/Makefile
-+++ b/drivers/clocksource/Makefile
-@@ -58,6 +58,7 @@ obj-$(CONFIG_MILBEAUT_TIMER) += timer-mi
- obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o
- obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o
- obj-$(CONFIG_RDA_TIMER) += timer-rda.o
-+obj-$(CONFIG_REALTEK_OTTO_TIMER) += timer-rtl-otto.o
-
- obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
- obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
---- a/include/linux/cpuhotplug.h
-+++ b/include/linux/cpuhotplug.h
-@@ -176,6 +176,7 @@ enum cpuhp_state {
- CPUHP_AP_MARCO_TIMER_STARTING,
- CPUHP_AP_MIPS_GIC_TIMER_STARTING,
- CPUHP_AP_ARC_TIMER_STARTING,
-+ CPUHP_AP_REALTEK_TIMER_STARTING,
- CPUHP_AP_RISCV_TIMER_STARTING,
- CPUHP_AP_CLINT_TIMER_STARTING,
- CPUHP_AP_CSKY_TIMER_STARTING,
diff --git a/target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch b/target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch
deleted file mode 100644
index beaddcb58e..0000000000
--- a/target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 9bac1c20b8f39f2e0e342b087add5093b94feaed Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Wed, 5 May 2021 22:05:39 +0900
-Subject: realtek: backport gpio-realtek-otto driver from 5.13 to 5.10
-
-This patch backports "gpio-realtek-otto" driver to Kernel 5.10.
-"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X"
-is used in OpenWrt, so update the dependency by the additional patch.
-
-Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- drivers/gpio/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -503,8 +503,8 @@ config GPIO_RDA
-
- config GPIO_REALTEK_OTTO
- tristate "Realtek Otto GPIO support"
-- depends on MACH_REALTEK_RTL
-- default MACH_REALTEK_RTL
-+ depends on RTL83XX
-+ default RTL838X
- select GPIO_GENERIC
- select GPIOLIB_IRQCHIP
- help
diff --git a/target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch b/target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch
deleted file mode 100644
index f2b57bacde..0000000000
--- a/target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0b000cbfe0aa0323bffa855ef8449c0687a4c071 Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Thu, 6 May 2021 19:30:58 +0900
-Subject: realtek: backport spi-realtek-rtl driver from 5.12 to 5.10
-
-This patch backports "spi-realtek-rtl" driver to Kernel 5.10 from 5.12.
-"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X"
-is used in OpenWrt, so update the dependency by the additional patch.
-
-Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- drivers/spi/Makefile | 2 +-
- 1 files changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -97,7 +97,7 @@ obj-$(CONFIG_SPI_QUP) += spi-qup.o
- obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
- obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o
- obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
--obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
-+obj-$(CONFIG_RTL83XX) += spi-realtek-rtl.o
- obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
- obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
- obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
diff --git a/target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch b/target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch
deleted file mode 100644
index a94a3ff8ac..0000000000
--- a/target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 2cd00b51470a30198b048a5fca48a04db77e29cc Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Fri, 21 May 2021 23:16:37 +0900
-Subject: [PATCH] realtek: backport irq-realtek-rtl driver from 5.12 to 5.10
-
-This patch backports "irq-realtek-rtl" driver to Kernel 5.10 from 5.12.
-"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X"
-is used in OpenWrt, so update the dependency by the additional patch.
-
-Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- drivers/irqchip/Makefile | 2 +-
- 1 files changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/irqchip/Makefile
-+++ b/drivers/irqchip/Makefile
-@@ -112,7 +112,7 @@ obj-$(CONFIG_LOONGSON_PCH_PIC) += irq-l
- obj-$(CONFIG_LOONGSON_PCH_MSI) += irq-loongson-pch-msi.o
- obj-$(CONFIG_MST_IRQ) += irq-mst-intc.o
- obj-$(CONFIG_SL28CPLD_INTC) += irq-sl28cpld.o
--obj-$(CONFIG_MACH_REALTEK_RTL) += irq-realtek-rtl.o
-+obj-$(CONFIG_RTL83XX) += irq-realtek-rtl.o
- obj-$(CONFIG_WPCM450_AIC) += irq-wpcm450-aic.o
- obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o
- obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o
diff --git a/target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch b/target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch
deleted file mode 100644
index b44aebea12..0000000000
--- a/target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From b8fc5eecdc5d33cf261986436597b5482ab856da Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sun, 14 Nov 2021 19:45:32 +0100
-Subject: [PATCH] realtek: Backport Realtek Otto WDT driver
-
-Add patch submitted upstream to linux-watchdog and replace the MIPS
-architecture symbols. Requires one extra patch for the DIV_ROUND_*
-macros, which have moved to a different header since 5.10.
-
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Tested-by: Stijn Segers <foss@volatilesystems.org>
-Tested-by: Paul Fertser <fercerpav@gmail.com>
-Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
----
- drivers/watchdog/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -956,10 +956,10 @@ config RTD119X_WATCHDOG
-
- config REALTEK_OTTO_WDT
- tristate "Realtek Otto MIPS watchdog support"
-- depends on MACH_REALTEK_RTL || COMPILE_TEST
-+ depends on RTL83XX
- depends on COMMON_CLK
- select WATCHDOG_CORE
-- default MACH_REALTEK_RTL
-+ default RTL83XX
- help
- Say Y here to include support for the watchdog timer on Realtek
- RTL838x, RTL839x, RTL930x SoCs. This watchdog has pretimeout
diff --git a/target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch b/target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch
deleted file mode 100644
index 78b145617f..0000000000
--- a/target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From b8fc5eecdc5d33cf261986436597b5482ab856da Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sun, 14 Nov 2021 19:45:32 +0100
-Subject: [PATCH] realtek: Backport Realtek Otto WDT driver
-
-Add patch submitted upstream to linux-watchdog and replace the MIPS
-architecture symbols. Requires one extra patch for the DIV_ROUND_*
-macros, which have moved to a different header since 5.10.
-
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Tested-by: Stijn Segers <foss@volatilesystems.org>
-Tested-by: Paul Fertser <fercerpav@gmail.com>
-Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
----
- drivers/watchdog/realtek_otto_wdt.c | 2 +-
- 1 files changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/watchdog/realtek_otto_wdt.c
-+++ b/drivers/watchdog/realtek_otto_wdt.c
-@@ -21,7 +21,7 @@
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/io.h>
--#include <linux/math.h>
-+#include <linux/kernel.h>
- #include <linux/minmax.h>
- #include <linux/module.h>
- #include <linux/mod_devicetable.h>
diff --git a/target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch b/target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch
deleted file mode 100644
index 2125aea77f..0000000000
--- a/target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 63a0a4d85bc900464c5b046b13808a582345f8c8 Mon Sep 17 00:00:00 2001
-From: Birger Koblitz <git@birger-koblitz.de>
-Date: Sat, 11 Dec 2021 20:14:47 +0100
-Subject: [PATCH] realtek: Add support for RTL9300/RTL9310 I2C controller
-
-This adds support for the RTL9300 and RTL9310 I2C controller.
-The controller implements the SMBus protocol for SMBus transfers
-over an I2C bus. The driver supports selecting one of the 2 possible
-SCL pins and any of the 8 possible SDA pins. Bus speeds of
-100kHz (standard speed) and 400kHz (high speed I2C) are supported.
-
-Submitted-by: Birger Koblitz <git@birger-koblitz.de>
----
- drivers/i2c/busses/Kconfig | 10 +++++++++
- drivers/i2c/busses/Makefile | 1 +
- 2 files changed, 11 insertions(+)
-
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -949,6 +949,16 @@ config I2C_RK3X
- This driver can also be built as a module. If so, the module will
- be called i2c-rk3x.
-
-+config I2C_RTL9300
-+ tristate "Realtek RTL9300 I2C adapter"
-+ depends on OF
-+ help
-+ Say Y here to include support for the I2C adapter in Realtek RTL9300
-+ and RTL9310 SoCs.
-+
-+ This driver can also be built as a module. If so, the module will
-+ be called i2c-rtl9300.
-+
- config HAVE_S3C2410_I2C
- bool
- help
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -94,6 +94,7 @@ obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-
- obj-$(CONFIG_I2C_QUP) += i2c-qup.o
- obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
- obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o
-+obj-$(CONFIG_I2C_RTL9300) += i2c-rtl9300.o
- obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
- obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
- obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
diff --git a/target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch b/target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch
deleted file mode 100644
index 102c9850ce..0000000000
--- a/target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch
+++ /dev/null
@@ -1,402 +0,0 @@
-From 6c18e9c491959ac0674ebe36b09f9ddc3f2c9bce Mon Sep 17 00:00:00 2001
-From: Birger Koblitz <git@birger-koblitz.de>
-Date: Fri, 31 Dec 2021 11:56:49 +0100
-Subject: [PATCH] realtek: Add VPE support for the IRQ driver
-
-In order to support VSMP, enable support for both VPEs
-of the RTL839X and RTL930X SoCs in the irq-realtek-rtl
-driver. Add support for IRQ affinity setting.
-
-Submitted-by: Birger Koblitz <git@birger-koblitz.de>
----
- drivers/irqchip/irq-realtek-rtl.c | 152 +++++++++++++++---
- 1 file changed, 73 insertions(+), 76 deletions(-)
-
---- a/drivers/irqchip/irq-realtek-rtl.c
-+++ b/drivers/irqchip/irq-realtek-rtl.c
-@@ -21,21 +21,63 @@
- #define RTL_ICTL_IRR2 0x10
- #define RTL_ICTL_IRR3 0x14
-
--#define REG(x) (realtek_ictl_base + x)
-+#define RTL_ICTL_NUM_INPUTS 32
-+#define RTL_ICTL_NUM_OUTPUTS 15
-
- static DEFINE_RAW_SPINLOCK(irq_lock);
--static void __iomem *realtek_ictl_base;
-+
-+#define REG(offset, cpu) (realtek_ictl_base[cpu] + offset)
-+
-+static void __iomem *realtek_ictl_base[NR_CPUS];
-+static cpumask_t realtek_ictl_cpu_configurable;
-+
-+struct realtek_ictl_output {
-+ /* IRQ controller data */
-+ struct fwnode_handle *fwnode;
-+ /* Output specific data */
-+ unsigned int output_index;
-+ struct irq_domain *domain;
-+ u32 child_mask;
-+};
-+
-+/*
-+ * IRR0-IRR3 store 4 bits per interrupt, but Realtek uses inverted numbering,
-+ * placing IRQ 31 in the first four bits. A routing value of '0' means the
-+ * interrupt is left disconnected. Routing values {1..15} connect to output
-+ * lines {0..14}.
-+ */
-+#define IRR_OFFSET(idx) (4 * (3 - (idx * 4) / 32))
-+#define IRR_SHIFT(idx) ((idx * 4) % 32)
-+
-+static inline u32 read_irr(void __iomem *irr0, int idx)
-+{
-+ return (readl(irr0 + IRR_OFFSET(idx)) >> IRR_SHIFT(idx)) & 0xf;
-+}
-+
-+static inline void write_irr(void __iomem *irr0, int idx, u32 value)
-+{
-+ unsigned int offset = IRR_OFFSET(idx);
-+ unsigned int shift = IRR_SHIFT(idx);
-+ u32 irr;
-+
-+ irr = readl(irr0 + offset) & ~(0xf << shift);
-+ irr |= (value & 0xf) << shift;
-+ writel(irr, irr0 + offset);
-+}
-
- static void realtek_ictl_unmask_irq(struct irq_data *i)
- {
- unsigned long flags;
- u32 value;
-+ int cpu;
-
- raw_spin_lock_irqsave(&irq_lock, flags);
-
-- value = readl(REG(RTL_ICTL_GIMR));
-- value |= BIT(i->hwirq);
-- writel(value, REG(RTL_ICTL_GIMR));
-+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) {
-+ value = readl(REG(RTL_ICTL_GIMR, cpu));
-+ value |= BIT(i->hwirq);
-+ writel(value, REG(RTL_ICTL_GIMR, cpu));
-+ }
-
- raw_spin_unlock_irqrestore(&irq_lock, flags);
- }
-@@ -44,52 +86,137 @@ static void realtek_ictl_mask_irq(struct
- {
- unsigned long flags;
- u32 value;
-+ int cpu;
-
- raw_spin_lock_irqsave(&irq_lock, flags);
-
-- value = readl(REG(RTL_ICTL_GIMR));
-- value &= ~BIT(i->hwirq);
-- writel(value, REG(RTL_ICTL_GIMR));
-+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) {
-+ value = readl(REG(RTL_ICTL_GIMR, cpu));
-+ value &= ~BIT(i->hwirq);
-+ writel(value, REG(RTL_ICTL_GIMR, cpu));
-+ }
-
- raw_spin_unlock_irqrestore(&irq_lock, flags);
- }
-
-+static int __maybe_unused realtek_ictl_irq_affinity(struct irq_data *i,
-+ const struct cpumask *dest, bool force)
-+{
-+ struct realtek_ictl_output *output = i->domain->host_data;
-+ cpumask_t cpu_configure;
-+ cpumask_t cpu_disable;
-+ cpumask_t cpu_enable;
-+ unsigned long flags;
-+ int cpu;
-+
-+ raw_spin_lock_irqsave(&irq_lock, flags);
-+
-+ cpumask_and(&cpu_configure, cpu_present_mask, &realtek_ictl_cpu_configurable);
-+
-+ cpumask_and(&cpu_enable, &cpu_configure, dest);
-+ cpumask_andnot(&cpu_disable, &cpu_configure, dest);
-+
-+ for_each_cpu(cpu, &cpu_disable)
-+ write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, 0);
-+
-+ for_each_cpu(cpu, &cpu_enable)
-+ write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, output->output_index + 1);
-+
-+ irq_data_update_effective_affinity(i, &cpu_enable);
-+
-+ raw_spin_unlock_irqrestore(&irq_lock, flags);
-+
-+ return IRQ_SET_MASK_OK;
-+}
-+
- static struct irq_chip realtek_ictl_irq = {
- .name = "realtek-rtl-intc",
- .irq_mask = realtek_ictl_mask_irq,
- .irq_unmask = realtek_ictl_unmask_irq,
-+#ifdef CONFIG_SMP
-+ .irq_set_affinity = realtek_ictl_irq_affinity,
-+#endif
- };
-
- static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
- {
-+ struct realtek_ictl_output *output = d->host_data;
-+ unsigned long flags;
-+
- irq_set_chip_and_handler(irq, &realtek_ictl_irq, handle_level_irq);
-
-+ raw_spin_lock_irqsave(&irq_lock, flags);
-+
-+ output->child_mask |= BIT(hw);
-+ write_irr(REG(RTL_ICTL_IRR0, 0), hw, output->output_index + 1);
-+
-+ raw_spin_unlock_irqrestore(&irq_lock, flags);
-+
- return 0;
- }
-
-+static int intc_select(struct irq_domain *d, struct irq_fwspec *fwspec,
-+ enum irq_domain_bus_token bus_token)
-+{
-+ struct realtek_ictl_output *output = d->host_data;
-+ bool routed_elsewhere;
-+ unsigned long flags;
-+ u32 routing_old;
-+ int cpu;
-+
-+ if (fwspec->fwnode != output->fwnode)
-+ return false;
-+
-+ /* Original specifiers had only one parameter */
-+ if (fwspec->param_count < 2)
-+ return true;
-+
-+ raw_spin_lock_irqsave(&irq_lock, flags);
-+
-+ /*
-+ * Inputs can only be routed to one output, so they shouldn't be
-+ * allowed to end up in multiple domains.
-+ */
-+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) {
-+ routing_old = read_irr(REG(RTL_ICTL_IRR0, cpu), fwspec->param[0]);
-+ routed_elsewhere = routing_old && fwspec->param[1] != routing_old - 1;
-+ if (routed_elsewhere) {
-+ pr_warn("soc int %d already routed to output %d\n",
-+ fwspec->param[0], routing_old - 1);
-+ break;
-+ }
-+ }
-+
-+ raw_spin_unlock_irqrestore(&irq_lock, flags);
-+
-+ return !routed_elsewhere && fwspec->param[1] == output->output_index;
-+}
-+
- static const struct irq_domain_ops irq_domain_ops = {
- .map = intc_map,
-+ .select = intc_select,
- .xlate = irq_domain_xlate_onecell,
- };
-
- static void realtek_irq_dispatch(struct irq_desc *desc)
- {
-+ struct realtek_ictl_output *output = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
-- struct irq_domain *domain;
-+ int cpu = smp_processor_id();
- unsigned long pending;
- unsigned int soc_int;
-
- chained_irq_enter(chip, desc);
-- pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR));
-+ pending = readl(REG(RTL_ICTL_GIMR, cpu)) & readl(REG(RTL_ICTL_GISR, cpu))
-+ & output->child_mask;
-
- if (unlikely(!pending)) {
- spurious_interrupt();
- goto out;
- }
-
-- domain = irq_desc_get_handler_data(desc);
-- for_each_set_bit(soc_int, &pending, 32)
-- generic_handle_domain_irq(domain, soc_int);
-+ for_each_set_bit(soc_int, &pending, RTL_ICTL_NUM_INPUTS)
-+ generic_handle_domain_irq(output->domain, soc_int);
-
- out:
- chained_irq_exit(chip, desc);
-@@ -102,85 +229,110 @@ out:
- * thus go into 4 IRRs. A routing value of '0' means the interrupt is left
- * disconnected. Routing values {1..15} connect to output lines {0..14}.
- */
--static int __init map_interrupts(struct device_node *node, struct irq_domain *domain)
-+static int __init setup_parent_interrupts(struct device_node *node, int *parents,
-+ unsigned int num_parents)
- {
-- struct device_node *cpu_ictl;
-- const __be32 *imap;
-- u32 imaplen, soc_int, cpu_int, tmp, regs[4];
-- int ret, i, irr_regs[] = {
-- RTL_ICTL_IRR3,
-- RTL_ICTL_IRR2,
-- RTL_ICTL_IRR1,
-- RTL_ICTL_IRR0,
-- };
-- u8 mips_irqs_set;
-+ struct realtek_ictl_output *outputs;
-+ struct realtek_ictl_output *output;
-+ struct irq_domain *domain;
-+ unsigned int p;
-
-- ret = of_property_read_u32(node, "#address-cells", &tmp);
-- if (ret || tmp)
-- return -EINVAL;
-+ outputs = kcalloc(num_parents, sizeof(*outputs), GFP_KERNEL);
-+ if (!outputs)
-+ return -ENOMEM;
-
-- imap = of_get_property(node, "interrupt-map", &imaplen);
-- if (!imap || imaplen % 3)
-- return -EINVAL;
-+ for (p = 0; p < num_parents; p++) {
-+ output = outputs + p;
-
-- mips_irqs_set = 0;
-- memset(regs, 0, sizeof(regs));
-- for (i = 0; i < imaplen; i += 3 * sizeof(u32)) {
-- soc_int = be32_to_cpup(imap);
-- if (soc_int > 31)
-- return -EINVAL;
--
-- cpu_ictl = of_find_node_by_phandle(be32_to_cpup(imap + 1));
-- if (!cpu_ictl)
-- return -EINVAL;
-- ret = of_property_read_u32(cpu_ictl, "#interrupt-cells", &tmp);
-- of_node_put(cpu_ictl);
-- if (ret || tmp != 1)
-- return -EINVAL;
--
-- cpu_int = be32_to_cpup(imap + 2);
-- if (cpu_int > 7 || cpu_int < 2)
-- return -EINVAL;
--
-- if (!(mips_irqs_set & BIT(cpu_int))) {
-- irq_set_chained_handler_and_data(cpu_int, realtek_irq_dispatch,
-- domain);
-- mips_irqs_set |= BIT(cpu_int);
-- }
-+ domain = irq_domain_add_linear(node, RTL_ICTL_NUM_INPUTS, &irq_domain_ops, output);
-+ if (!domain)
-+ goto domain_err;
-
-- /* Use routing values (1..6) for CPU interrupts (2..7) */
-- regs[(soc_int * 4) / 32] |= (cpu_int - 1) << (soc_int * 4) % 32;
-- imap += 3;
-- }
-+ output->fwnode = of_node_to_fwnode(node);
-+ output->output_index = p;
-+ output->domain = domain;
-
-- for (i = 0; i < 4; i++)
-- writel(regs[i], REG(irr_regs[i]));
-+ irq_set_chained_handler_and_data(parents[p], realtek_irq_dispatch, output);
-+ }
-
- return 0;
-+
-+domain_err:
-+ while (p--) {
-+ irq_set_chained_handler_and_data(parents[p], NULL, NULL);
-+ irq_domain_remove(outputs[p].domain);
-+ }
-+
-+ kfree(outputs);
-+
-+ return -ENOMEM;
- }
-
- static int __init realtek_rtl_of_init(struct device_node *node, struct device_node *parent)
- {
-- struct irq_domain *domain;
-- int ret;
-+ int parent_irqs[RTL_ICTL_NUM_OUTPUTS];
-+ struct of_phandle_args oirq;
-+ unsigned int num_parents;
-+ unsigned int soc_irq;
-+ unsigned int p;
-+ int cpu;
-+
-+ cpumask_clear(&realtek_ictl_cpu_configurable);
-+
-+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
-+ realtek_ictl_base[cpu] = of_iomap(node, cpu);
-+ if (realtek_ictl_base[cpu]) {
-+ cpumask_set_cpu(cpu, &realtek_ictl_cpu_configurable);
-+
-+ /* Disable all cascaded interrupts and clear routing */
-+ writel(0, REG(RTL_ICTL_GIMR, cpu));
-+ for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++)
-+ write_irr(REG(RTL_ICTL_IRR0, cpu), soc_irq, 0);
-+ }
-+ }
-
-- realtek_ictl_base = of_iomap(node, 0);
-- if (!realtek_ictl_base)
-+ if (cpumask_empty(&realtek_ictl_cpu_configurable))
- return -ENXIO;
-
-- /* Disable all cascaded interrupts */
-- writel(0, REG(RTL_ICTL_GIMR));
-+ num_parents = of_irq_count(node);
-+ if (num_parents > RTL_ICTL_NUM_OUTPUTS) {
-+ pr_err("too many parent interrupts\n");
-+ return -EINVAL;
-+ }
-
-- domain = irq_domain_add_simple(node, 32, 0,
-- &irq_domain_ops, NULL);
-+ for (p = 0; p < num_parents; p++)
-+ parent_irqs[p] = of_irq_get(node, p);
-
-- ret = map_interrupts(node, domain);
-- if (ret) {
-- pr_err("invalid interrupt map\n");
-- return ret;
-+ if (WARN_ON(!num_parents)) {
-+ /*
-+ * If DT contains no parent interrupts, assume MIPS CPU IRQ 2
-+ * (HW0) is connected to the first output. This is the case for
-+ * all known hardware anyway. "interrupt-map" is deprecated, so
-+ * don't bother trying to parse that.
-+ * Since this is to account for old devicetrees with one-cell
-+ * interrupt specifiers, only one output domain is needed.
-+ */
-+ oirq.np = of_find_compatible_node(NULL, NULL, "mti,cpu-interrupt-controller");
-+ if (oirq.np) {
-+ oirq.args_count = 1;
-+ oirq.args[0] = 2;
-+
-+ parent_irqs[0] = irq_create_of_mapping(&oirq);
-+ num_parents = 1;
-+ }
-+
-+ of_node_put(oirq.np);
- }
-
-- return 0;
-+ /* Ensure we haven't collected any errors before proceeding */
-+ for (p = 0; p < num_parents; p++) {
-+ if (parent_irqs[p] < 0)
-+ return parent_irqs[p];
-+ if (!parent_irqs[p])
-+ return -ENODEV;
-+ }
-+
-+ return setup_parent_interrupts(node, &parent_irqs[0], num_parents);
- }
-
- IRQCHIP_DECLARE(realtek_rtl_intc, "realtek,rtl-intc", realtek_rtl_of_init);
diff --git a/target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch b/target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch
deleted file mode 100644
index a13d70d633..0000000000
--- a/target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From bde6311569ef25a00c3beaeabfd6b78b19651872 Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sun, 29 May 2022 19:38:09 +0200
-Subject: [PATCH] realtek: don't unmask non-maskable GPIO IRQs
-
-On uniprocessor builds, for_each_cpu(cpu, mask) will assume 'mask'
-always contains exactly one CPU, and ignore the actual mask contents.
-This causes the loop to run, even when it shouldn't on an empty mask,
-and tries to access an uninitialised pointer.
-
-Fix this by wrapping the loop in a cpumask_empty() check, to ensure it
-will not run on uniprocessor builds if the CPU mask is empty.
-
-Fixes: af6cd37f42f3 ("realtek: replace RTL93xx GPIO patches")
-Reported-by: INAGAKI Hiroshi <musashino.open@gmail.com>
-Reported-by: Robert Marko <robimarko@gmail.com>
-Tested-by: Robert Marko <robimarko@gmail.com>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
----
- drivers/gpio/gpio-realtek-otto.c | 9 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
---- a/drivers/gpio/gpio-realtek-otto.c
-+++ b/drivers/gpio/gpio-realtek-otto.c
-@@ -301,6 +301,7 @@ static int realtek_gpio_irq_set_affinity
- static int realtek_gpio_irq_init(struct gpio_chip *gc)
- {
- struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
-+ void __iomem *irq_cpu_mask;
- unsigned int port;
- int cpu;
-
-@@ -308,8 +309,16 @@ static int realtek_gpio_irq_init(struct
- realtek_gpio_write_imr(ctrl, port, 0, 0);
- realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0));
-
-- for_each_cpu(cpu, &ctrl->cpu_irq_maskable)
-- iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu));
-+ /*
-+ * Uniprocessor builds assume a mask always contains one CPU,
-+ * so only start the loop if we have at least one maskable CPU.
-+ */
-+ if(!cpumask_empty(&ctrl->cpu_irq_maskable)) {
-+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
-+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
-+ iowrite8(GENMASK(7, 0), irq_cpu_mask);
-+ }
-+ }
- }
-
- return 0;
diff --git a/target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch b/target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch
deleted file mode 100644
index 9f2c3b50b6..0000000000
--- a/target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch
+++ /dev/null
@@ -1,368 +0,0 @@
-From ee0175b3b44288c74d5292c2a9c2c154f6c0317e Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Sun, 7 Aug 2022 21:21:15 +0200
-Subject: [PATCH] gpio: realtek-otto: switch to 32-bit I/O
-
-By using 16-bit I/O on the GPIO peripheral, which is apparently not safe
-on MIPS, the IMR can end up containing garbage. This then results in
-interrupt triggers for lines that don't have an interrupt handler
-associated. The irq_desc lookup fails, and the ISR will not be cleared,
-keeping the CPU busy until reboot, or until another IMR operation
-restores the correct value. This situation appears to happen very
-rarely, for < 0.5% of IMR writes.
-
-Instead of using 8-bit or 16-bit I/O operations on the 32-bit memory
-mapped peripheral registers, switch to using 32-bit I/O only, operating
-on the entire bank for all single bit line settings. For 2-bit line
-settings, with 16-bit port values, stick to manual (un)packing.
-
-This issue has been seen on RTL8382M (HPE 1920-16G), RTL8391M (Netgear
-GS728TP v2), and RTL8393M (D-Link DGS-1210-52 F3, Zyxel GS1900-48).
-
-Reported-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> # DGS-1210-52
-Reported-by: Birger Koblitz <mail@birger-koblitz.de> # GS728TP
-Reported-by: Jan Hoffmann <jan@3e8.eu> # 1920-16G
-Fixes: 0d82fb1127fb ("gpio: Add Realtek Otto GPIO support")
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Cc: Paul Cercueil <paul@crapouillou.net>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
-
-Update patch for missing upstream changes:
- - commit a01a40e33499 ("gpio: realtek-otto: Make the irqchip immutable")
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-
----
- drivers/gpio/gpio-realtek-otto.c | 166 ++++++++++++++++---------------
- 1 file changed, 85 insertions(+), 81 deletions(-)
-
---- a/drivers/gpio/gpio-realtek-otto.c
-+++ b/drivers/gpio/gpio-realtek-otto.c
-@@ -46,10 +46,20 @@
- * @lock: Lock for accessing the IRQ registers and values
- * @intr_mask: Mask for interrupts lines
- * @intr_type: Interrupt type selection
-+ * @bank_read: Read a bank setting as a single 32-bit value
-+ * @bank_write: Write a bank setting as a single 32-bit value
-+ * @imr_line_pos: Bit shift of an IRQ line's IMR value.
-+ *
-+ * The DIR, DATA, and ISR registers consist of four 8-bit port values, packed
-+ * into a single 32-bit register. Use @bank_read (@bank_write) to get (assign)
-+ * a value from (to) these registers. The IMR register consists of four 16-bit
-+ * port values, packed into two 32-bit registers. Use @imr_line_pos to get the
-+ * bit shift of the 2-bit field for a line's IMR settings. Shifts larger than
-+ * 32 overflow into the second register.
- *
- * Because the interrupt mask register (IMR) combines the function of IRQ type
- * selection and masking, two extra values are stored. @intr_mask is used to
-- * mask/unmask the interrupts for a GPIO port, and @intr_type is used to store
-+ * mask/unmask the interrupts for a GPIO line, and @intr_type is used to store
- * the selected interrupt types. The logical AND of these values is written to
- * IMR on changes.
- */
-@@ -59,10 +69,11 @@ struct realtek_gpio_ctrl {
- void __iomem *cpumask_base;
- struct cpumask cpu_irq_maskable;
- raw_spinlock_t lock;
-- u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK];
-- u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK];
-- unsigned int (*port_offset_u8)(unsigned int port);
-- unsigned int (*port_offset_u16)(unsigned int port);
-+ u8 intr_mask[REALTEK_GPIO_MAX];
-+ u8 intr_type[REALTEK_GPIO_MAX];
-+ u32 (*bank_read)(void __iomem *reg);
-+ void (*bank_write)(void __iomem *reg, u32 value);
-+ unsigned int (*line_imr_pos)(unsigned int line);
- };
-
- /* Expand with more flags as devices with other quirks are added */
-@@ -101,14 +112,22 @@ static struct realtek_gpio_ctrl *irq_dat
- * port. The two interrupt mask registers store two bits per GPIO, so use u16
- * values.
- */
--static unsigned int realtek_gpio_port_offset_u8(unsigned int port)
-+static u32 realtek_gpio_bank_read_swapped(void __iomem *reg)
-+{
-+ return ioread32be(reg);
-+}
-+
-+static void realtek_gpio_bank_write_swapped(void __iomem *reg, u32 value)
- {
-- return port;
-+ iowrite32be(value, reg);
- }
-
--static unsigned int realtek_gpio_port_offset_u16(unsigned int port)
-+static unsigned int realtek_gpio_line_imr_pos_swapped(unsigned int line)
- {
-- return 2 * port;
-+ unsigned int port_pin = line % 8;
-+ unsigned int port = line / 8;
-+
-+ return 2 * (8 * (port ^ 1) + port_pin);
- }
-
- /*
-@@ -119,64 +138,65 @@ static unsigned int realtek_gpio_port_of
- * per GPIO, so use u16 values. The first register contains ports 1 and 0, the
- * second ports 3 and 2.
- */
--static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port)
-+static u32 realtek_gpio_bank_read(void __iomem *reg)
- {
-- return 3 - port;
-+ return ioread32(reg);
- }
-
--static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port)
-+static void realtek_gpio_bank_write(void __iomem *reg, u32 value)
- {
-- return 2 * (port ^ 1);
-+ iowrite32(value, reg);
- }
-
--static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl,
-- unsigned int port, u16 irq_type, u16 irq_mask)
-+static unsigned int realtek_gpio_line_imr_pos(unsigned int line)
- {
-- iowrite16(irq_type & irq_mask,
-- ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port));
-+ return 2 * line;
- }
-
--static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl,
-- unsigned int port, u8 mask)
-+static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, u32 mask)
- {
-- iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
-+ ctrl->bank_write(ctrl->base + REALTEK_GPIO_REG_ISR, mask);
- }
-
--static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port)
-+static u32 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl)
- {
-- return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
-+ return ctrl->bank_read(ctrl->base + REALTEK_GPIO_REG_ISR);
- }
-
--/* Set the rising and falling edge mask bits for a GPIO port pin */
--static u16 realtek_gpio_imr_bits(unsigned int pin, u16 value)
-+/* Set the rising and falling edge mask bits for a GPIO pin */
-+static void realtek_gpio_update_line_imr(struct realtek_gpio_ctrl *ctrl, unsigned int line)
- {
-- return (value & REALTEK_GPIO_IMR_LINE_MASK) << 2 * pin;
-+ void __iomem *reg = ctrl->base + REALTEK_GPIO_REG_IMR;
-+ unsigned int line_shift = ctrl->line_imr_pos(line);
-+ unsigned int shift = line_shift % 32;
-+ u32 irq_type = ctrl->intr_type[line];
-+ u32 irq_mask = ctrl->intr_mask[line];
-+ u32 reg_val;
-+
-+ reg += 4 * (line_shift / 32);
-+ reg_val = ioread32(reg);
-+ reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift);
-+ reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK) << shift;
-+ iowrite32(reg_val, reg);
- }
-
- static void realtek_gpio_irq_ack(struct irq_data *data)
- {
- struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
- irq_hw_number_t line = irqd_to_hwirq(data);
-- unsigned int port = line / 8;
-- unsigned int port_pin = line % 8;
-
-- realtek_gpio_clear_isr(ctrl, port, BIT(port_pin));
-+ realtek_gpio_clear_isr(ctrl, BIT(line));
- }
-
- static void realtek_gpio_irq_unmask(struct irq_data *data)
- {
- struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
- unsigned int line = irqd_to_hwirq(data);
-- unsigned int port = line / 8;
-- unsigned int port_pin = line % 8;
- unsigned long flags;
-- u16 m;
-
- raw_spin_lock_irqsave(&ctrl->lock, flags);
-- m = ctrl->intr_mask[port];
-- m |= realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
-- ctrl->intr_mask[port] = m;
-- realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m);
-+ ctrl->intr_mask[line] = REALTEK_GPIO_IMR_LINE_MASK;
-+ realtek_gpio_update_line_imr(ctrl, line);
- raw_spin_unlock_irqrestore(&ctrl->lock, flags);
- }
-
-@@ -184,16 +204,11 @@ static void realtek_gpio_irq_mask(struct
- {
- struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
- unsigned int line = irqd_to_hwirq(data);
-- unsigned int port = line / 8;
-- unsigned int port_pin = line % 8;
- unsigned long flags;
-- u16 m;
-
- raw_spin_lock_irqsave(&ctrl->lock, flags);
-- m = ctrl->intr_mask[port];
-- m &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
-- ctrl->intr_mask[port] = m;
-- realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m);
-+ ctrl->intr_mask[line] = 0;
-+ realtek_gpio_update_line_imr(ctrl, line);
- raw_spin_unlock_irqrestore(&ctrl->lock, flags);
- }
-
-@@ -201,10 +216,8 @@ static int realtek_gpio_irq_set_type(str
- {
- struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
- unsigned int line = irqd_to_hwirq(data);
-- unsigned int port = line / 8;
-- unsigned int port_pin = line % 8;
- unsigned long flags;
-- u16 type, t;
-+ u8 type;
-
- switch (flow_type & IRQ_TYPE_SENSE_MASK) {
- case IRQ_TYPE_EDGE_FALLING:
-@@ -223,11 +236,8 @@ static int realtek_gpio_irq_set_type(str
- irq_set_handler_locked(data, handle_edge_irq);
-
- raw_spin_lock_irqsave(&ctrl->lock, flags);
-- t = ctrl->intr_type[port];
-- t &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
-- t |= realtek_gpio_imr_bits(port_pin, type);
-- ctrl->intr_type[port] = t;
-- realtek_gpio_write_imr(ctrl, port, t, ctrl->intr_mask[port]);
-+ ctrl->intr_type[line] = type;
-+ realtek_gpio_update_line_imr(ctrl, line);
- raw_spin_unlock_irqrestore(&ctrl->lock, flags);
-
- return 0;
-@@ -238,28 +248,21 @@ static void realtek_gpio_irq_handler(str
- struct gpio_chip *gc = irq_desc_get_handler_data(desc);
- struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
- struct irq_chip *irq_chip = irq_desc_get_chip(desc);
-- unsigned int lines_done;
-- unsigned int port_pin_count;
- unsigned long status;
- int offset;
-
- chained_irq_enter(irq_chip, desc);
-
-- for (lines_done = 0; lines_done < gc->ngpio; lines_done += 8) {
-- status = realtek_gpio_read_isr(ctrl, lines_done / 8);
-- port_pin_count = min(gc->ngpio - lines_done, 8U);
-- for_each_set_bit(offset, &status, port_pin_count)
-- generic_handle_domain_irq(gc->irq.domain, offset + lines_done);
-- }
-+ status = realtek_gpio_read_isr(ctrl);
-+ for_each_set_bit(offset, &status, gc->ngpio)
-+ generic_handle_domain_irq(gc->irq.domain, offset);
-
- chained_irq_exit(irq_chip, desc);
- }
-
--static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl,
-- unsigned int port, int cpu)
-+static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, int cpu)
- {
-- return ctrl->cpumask_base + ctrl->port_offset_u8(port) +
-- REALTEK_GPIO_PORTS_PER_BANK * cpu;
-+ return ctrl->cpumask_base + REALTEK_GPIO_PORTS_PER_BANK * cpu;
- }
-
- static int realtek_gpio_irq_set_affinity(struct irq_data *data,
-@@ -267,12 +270,10 @@ static int realtek_gpio_irq_set_affinity
- {
- struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
- unsigned int line = irqd_to_hwirq(data);
-- unsigned int port = line / 8;
-- unsigned int port_pin = line % 8;
- void __iomem *irq_cpu_mask;
- unsigned long flags;
- int cpu;
-- u8 v;
-+ u32 v;
-
- if (!ctrl->cpumask_base)
- return -ENXIO;
-@@ -280,15 +281,15 @@ static int realtek_gpio_irq_set_affinity
- raw_spin_lock_irqsave(&ctrl->lock, flags);
-
- for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
-- irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
-- v = ioread8(irq_cpu_mask);
-+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu);
-+ v = ctrl->bank_read(irq_cpu_mask);
-
- if (cpumask_test_cpu(cpu, dest))
-- v |= BIT(port_pin);
-+ v |= BIT(line);
- else
-- v &= ~BIT(port_pin);
-+ v &= ~BIT(line);
-
-- iowrite8(v, irq_cpu_mask);
-+ ctrl->bank_write(irq_cpu_mask, v);
- }
-
- raw_spin_unlock_irqrestore(&ctrl->lock, flags);
-@@ -302,22 +303,23 @@ static int realtek_gpio_irq_init(struct
- {
- struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
- void __iomem *irq_cpu_mask;
-- unsigned int port;
-+ u32 mask_all = GENMASK(gc->ngpio - 1, 0);
-+ unsigned int line;
- int cpu;
-
-- for (port = 0; (port * 8) < gc->ngpio; port++) {
-- realtek_gpio_write_imr(ctrl, port, 0, 0);
-- realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0));
--
-- /*
-- * Uniprocessor builds assume a mask always contains one CPU,
-- * so only start the loop if we have at least one maskable CPU.
-- */
-- if(!cpumask_empty(&ctrl->cpu_irq_maskable)) {
-- for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
-- irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
-- iowrite8(GENMASK(7, 0), irq_cpu_mask);
-- }
-+ for (line = 0; line < gc->ngpio; line++)
-+ realtek_gpio_update_line_imr(ctrl, line);
-+
-+ realtek_gpio_clear_isr(ctrl, mask_all);
-+
-+ /*
-+ * Uniprocessor builds assume a mask always contains one CPU,
-+ * so only start the loop if we have at least one maskable CPU.
-+ */
-+ if(!cpumask_empty(&ctrl->cpu_irq_maskable)) {
-+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
-+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu);
-+ ctrl->bank_write(irq_cpu_mask, mask_all);
- }
- }
-
-@@ -390,12 +392,14 @@ static int realtek_gpio_probe(struct pla
-
- if (dev_flags & GPIO_PORTS_REVERSED) {
- bgpio_flags = 0;
-- ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev;
-- ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev;
-+ ctrl->bank_read = realtek_gpio_bank_read;
-+ ctrl->bank_write = realtek_gpio_bank_write;
-+ ctrl->line_imr_pos = realtek_gpio_line_imr_pos;
- } else {
- bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
-- ctrl->port_offset_u8 = realtek_gpio_port_offset_u8;
-- ctrl->port_offset_u16 = realtek_gpio_port_offset_u16;
-+ ctrl->bank_read = realtek_gpio_bank_read_swapped;
-+ ctrl->bank_write = realtek_gpio_bank_write_swapped;
-+ ctrl->line_imr_pos = realtek_gpio_line_imr_pos_swapped;
- }
-
- err = bgpio_init(&ctrl->gc, dev, 4,
diff --git a/target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch b/target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch
deleted file mode 100644
index 7d063d4faa..0000000000
--- a/target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 800d5fb3c6a16661932c932bacd660e38d06b727 Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Thu, 25 Aug 2022 08:22:36 +0200
-Subject: [PATCH] realtek: add patch to enable new clock driver in kernel
-
-Allow building the clock driver with kernel config options.
-
-Submitted-by: Markus Stockhausen <markus.stockhausen@gmx.de>
----
- drivers/clk/Kconfig | 1 +
- drivers/clk/Makefile | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/drivers/clk/Kconfig
-+++ b/drivers/clk/Kconfig
-@@ -406,6 +406,7 @@ source "drivers/clk/mstar/Kconfig"
- source "drivers/clk/mvebu/Kconfig"
- source "drivers/clk/pistachio/Kconfig"
- source "drivers/clk/qcom/Kconfig"
-+source "drivers/clk/realtek/Kconfig"
- source "drivers/clk/ralink/Kconfig"
- source "drivers/clk/renesas/Kconfig"
- source "drivers/clk/rockchip/Kconfig"
---- a/drivers/clk/Makefile
-+++ b/drivers/clk/Makefile
-@@ -101,6 +101,7 @@ obj-$(CONFIG_COMMON_CLK_PISTACHIO) += pi
- obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
- obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
- obj-y += ralink/
-+obj-$(CONFIG_COMMON_CLK_REALTEK) += realtek/
- obj-y += renesas/
- obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
- obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
diff --git a/target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch b/target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch
deleted file mode 100644
index 0c29b7739e..0000000000
--- a/target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch
+++ /dev/null
@@ -1,159 +0,0 @@
-From 2cd00b51470a30198b048a5fca48a04db77e29cc Mon Sep 17 00:00:00 2001
-From: INAGAKI Hiroshi <musashino.open@gmail.com>
-Date: Fri, 21 May 2021 23:16:37 +0900
-Subject: [PATCH] realtek: backport irq-realtek-rtl driver from 5.12 to 5.10
-
-This patch backports "irq-realtek-rtl" driver to Kernel 5.10 from 5.12.
-"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X"
-is used in OpenWrt, so update the dependency by the additional patch.
-
-Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
----
- drivers/irqchip/irq-realtek-rtl.c | 38 +++++++++++------
- 1 files changed, 58 insertions(+), 20 deletions(-)
-
---- a/drivers/irqchip/irq-realtek-rtl.c
-+++ b/drivers/irqchip/irq-realtek-rtl.c
-@@ -28,6 +28,7 @@ static DEFINE_RAW_SPINLOCK(irq_lock);
-
- #define REG(offset, cpu) (realtek_ictl_base[cpu] + offset)
-
-+static u32 realtek_ictl_unmask[NR_CPUS];
- static void __iomem *realtek_ictl_base[NR_CPUS];
- static cpumask_t realtek_ictl_cpu_configurable;
-
-@@ -41,11 +42,29 @@ struct realtek_ictl_output {
- };
-
- /*
-- * IRR0-IRR3 store 4 bits per interrupt, but Realtek uses inverted numbering,
-- * placing IRQ 31 in the first four bits. A routing value of '0' means the
-- * interrupt is left disconnected. Routing values {1..15} connect to output
-- * lines {0..14}.
-+ * Per CPU we have a set of 5 registers that determine interrupt handling for
-+ * 32 external interrupts. GIMR (enable/disable interrupt) plus IRR0-IRR3 that
-+ * contain "routing" or "priority" values. GIMR uses one bit for each interrupt
-+ * and IRRx store 4 bits per interrupt. Realtek uses inverted numbering,
-+ * placing IRQ 31 in the first four bits. The register combinations give the
-+ * following results for a single interrupt in the wild:
-+ *
-+ * a) GIMR = 0 / IRRx > 0 -> no interrupts
-+ * b) GIMR = 0 / IRRx = 0 -> no interrupts
-+ * c) GIMR = 1 / IRRx > 0 -> interrupts
-+ * d) GIMR = 1 / IRRx = 0 -> rare interrupts in SMP environment
-+ *
-+ * Combination d) seems to trigger interrupts only on a VPE if the other VPE
-+ * has GIMR = 0 and IRRx > 0. E.g. busy without interrupts allowed. To provide
-+ * IRQ balancing features in SMP this driver will handle the registers as
-+ * follows:
-+ *
-+ * 1) set IRRx > 0 for VPE where the interrupt is desired
-+ * 2) set IRRx = 0 for VPE where the interrupt is not desired
-+ * 3) set both GIMR = 0 to mask (disabled) interrupt
-+ * 4) set GIMR = 1 to unmask (enable) interrupt but only for VPE where IRRx > 0
- */
-+
- #define IRR_OFFSET(idx) (4 * (3 - (idx * 4) / 32))
- #define IRR_SHIFT(idx) ((idx * 4) % 32)
-
-@@ -65,19 +84,33 @@ static inline void write_irr(void __iome
- writel(irr, irr0 + offset);
- }
-
-+static inline void enable_gimr(int hwirq, int cpu)
-+{
-+ u32 value;
-+
-+ value = readl(REG(RTL_ICTL_GIMR, cpu));
-+ value |= (BIT(hwirq) & realtek_ictl_unmask[cpu]);
-+ writel(value, REG(RTL_ICTL_GIMR, cpu));
-+}
-+
-+static inline void disable_gimr(int hwirq, int cpu)
-+{
-+ u32 value;
-+
-+ value = readl(REG(RTL_ICTL_GIMR, cpu));
-+ value &= ~BIT(hwirq);
-+ writel(value, REG(RTL_ICTL_GIMR, cpu));
-+}
-+
- static void realtek_ictl_unmask_irq(struct irq_data *i)
- {
- unsigned long flags;
-- u32 value;
- int cpu;
-
- raw_spin_lock_irqsave(&irq_lock, flags);
-
-- for_each_cpu(cpu, &realtek_ictl_cpu_configurable) {
-- value = readl(REG(RTL_ICTL_GIMR, cpu));
-- value |= BIT(i->hwirq);
-- writel(value, REG(RTL_ICTL_GIMR, cpu));
-- }
-+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable)
-+ enable_gimr(i->hwirq, cpu);
-
- raw_spin_unlock_irqrestore(&irq_lock, flags);
- }
-@@ -85,16 +118,12 @@ static void realtek_ictl_unmask_irq(stru
- static void realtek_ictl_mask_irq(struct irq_data *i)
- {
- unsigned long flags;
-- u32 value;
- int cpu;
-
- raw_spin_lock_irqsave(&irq_lock, flags);
-
-- for_each_cpu(cpu, &realtek_ictl_cpu_configurable) {
-- value = readl(REG(RTL_ICTL_GIMR, cpu));
-- value &= ~BIT(i->hwirq);
-- writel(value, REG(RTL_ICTL_GIMR, cpu));
-- }
-+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable)
-+ disable_gimr(i->hwirq, cpu);
-
- raw_spin_unlock_irqrestore(&irq_lock, flags);
- }
-@@ -116,11 +145,17 @@ static int __maybe_unused realtek_ictl_i
- cpumask_and(&cpu_enable, &cpu_configure, dest);
- cpumask_andnot(&cpu_disable, &cpu_configure, dest);
-
-- for_each_cpu(cpu, &cpu_disable)
-+ for_each_cpu(cpu, &cpu_disable) {
- write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, 0);
-+ realtek_ictl_unmask[cpu] &= ~BIT(i->hwirq);
-+ disable_gimr(i->hwirq, cpu);
-+ }
-
-- for_each_cpu(cpu, &cpu_enable)
-+ for_each_cpu(cpu, &cpu_enable) {
- write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, output->output_index + 1);
-+ realtek_ictl_unmask[cpu] |= BIT(i->hwirq);
-+ enable_gimr(i->hwirq, cpu);
-+ }
-
- irq_data_update_effective_affinity(i, &cpu_enable);
-
-@@ -149,6 +184,7 @@ static int intc_map(struct irq_domain *d
-
- output->child_mask |= BIT(hw);
- write_irr(REG(RTL_ICTL_IRR0, 0), hw, output->output_index + 1);
-+ realtek_ictl_unmask[0] |= BIT(hw);
-
- raw_spin_unlock_irqrestore(&irq_lock, flags);
-
-@@ -285,9 +321,11 @@ static int __init realtek_rtl_of_init(st
- cpumask_set_cpu(cpu, &realtek_ictl_cpu_configurable);
-
- /* Disable all cascaded interrupts and clear routing */
-- writel(0, REG(RTL_ICTL_GIMR, cpu));
-- for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++)
-+ for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++) {
- write_irr(REG(RTL_ICTL_IRR0, cpu), soc_irq, 0);
-+ realtek_ictl_unmask[cpu] &= ~BIT(soc_irq);
-+ disable_gimr(soc_irq, cpu);
-+ }
- }
- }
-
diff --git a/target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch b/target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch
deleted file mode 100644
index 8c6a4c3639..0000000000
--- a/target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 26 Nov 2020 12:02:21 +0100
-Subject: net: dsa: Add support for rtl838x switch
-
-* rename the target to realtek
-* add refactored DSA driver
-* add latest gpio driver
-* lots of arch cleanups
-* new irq driver
-* additional boards
-
-Submitted-by: Bert Vermeulen <bert@biot.com>
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Submitted-by: Bjørn Mork <bjorn@mork.no>
-Submitted-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/rtl83xx/Kconfig | 2 ++
- drivers/net/dsa/rtl83xx/Makefile | 1 +
- 2 files changed, 3 insertions(+)
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -85,6 +85,8 @@ source "drivers/net/dsa/sja1105/Kconfig"
-
- source "drivers/net/dsa/xrs700x/Kconfig"
-
-+source "drivers/net/dsa/rtl83xx/Kconfig"
-+
- config NET_DSA_REALTEK_SMI
- tristate "Realtek SMI Ethernet switch family support"
- select NET_DSA_TAG_RTL4_A
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -24,5 +24,6 @@ obj-y += microchip/
- obj-y += mv88e6xxx/
- obj-y += ocelot/
- obj-y += qca/
-+obj-y += rtl83xx/
- obj-y += sja1105/
- obj-y += xrs700x/
diff --git a/target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch b/target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch
deleted file mode 100644
index 0cb784fcbf..0000000000
--- a/target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 26 Nov 2020 12:02:21 +0100
-Subject: net: dsa: Add rtl838x support for tag trailer
-
-* rename the target to realtek
-* add refactored DSA driver
-* add latest gpio driver
-* lots of arch cleanups
-* new irq driver
-* additional boards
-
-Submitted-by: Bert Vermeulen <bert@biot.com>
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Submitted-by: Bjørn Mork <bjorn@mork.no>
-Submitted-by: John Crispin <john@phrozen.org>
----
- net/dsa/tag_trailer.c | 16 +++++++++++++-
- 1 file changed, 17 insertions(+), 1 deletion(-)
-
---- a/net/dsa/tag_trailer.c
-+++ b/net/dsa/tag_trailer.c
-@@ -17,7 +17,12 @@ static struct sk_buff *trailer_xmit(stru
-
- trailer = skb_put(skb, 4);
- trailer[0] = 0x80;
-+
-+#ifdef CONFIG_NET_DSA_RTL83XX
-+ trailer[1] = dp->index;
-+#else
- trailer[1] = 1 << dp->index;
-+#endif /* CONFIG_NET_DSA_RTL838X */
- trailer[2] = 0x10;
- trailer[3] = 0x00;
-
-@@ -33,12 +38,23 @@ static struct sk_buff *trailer_rcv(struc
- return NULL;
-
- trailer = skb_tail_pointer(skb) - 4;
-+
-+#ifdef CONFIG_NET_DSA_RTL83XX
-+ if (trailer[0] != 0x80 || (trailer[1] & 0x80) != 0x00 ||
-+ (trailer[2] & 0xef) != 0x00 || trailer[3] != 0x00)
-+ return NULL;
-+
-+ if (trailer[1] & 0x40)
-+ skb->offload_fwd_mark = 1;
-+
-+ source_port = trailer[1] & 0x3f;
-+#else
- if (trailer[0] != 0x80 || (trailer[1] & 0xf8) != 0x00 ||
- (trailer[2] & 0xef) != 0x00 || trailer[3] != 0x00)
- return NULL;
-
- source_port = trailer[1] & 7;
--
-+#endif
- skb->dev = dsa_master_find_slave(dev, 0, source_port);
- if (!skb->dev)
- return NULL;
diff --git a/target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch b/target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch
deleted file mode 100644
index 1c25c42b91..0000000000
--- a/target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 26 Nov 2020 12:02:21 +0100
-Subject: net: ethernet: Add support for RTL838x ethernet
-
-* rename the target to realtek
-* add refactored DSA driver
-* add latest gpio driver
-* lots of arch cleanups
-* new irq driver
-* additional boards
-
-Submitted-by: Bert Vermeulen <bert@biot.com>
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Submitted-by: Bjørn Mork <bjorn@mork.no>
-Submitted-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/Kconfig | 7 +-
- drivers/net/ethernet/Makefile | 1 +
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/ethernet/Kconfig
-+++ b/drivers/net/ethernet/Kconfig
-@@ -166,6 +166,13 @@ source "drivers/net/ethernet/rdc/Kconfig
- source "drivers/net/ethernet/realtek/Kconfig"
- source "drivers/net/ethernet/renesas/Kconfig"
- source "drivers/net/ethernet/rocker/Kconfig"
-+
-+config NET_RTL838X
-+ tristate "Realtek rtl838x Ethernet MAC support"
-+ depends on RTL83XX
-+ help
-+ Say Y here if you want to use the Realtek rtl838x Gbps Ethernet MAC.
-+
- source "drivers/net/ethernet/samsung/Kconfig"
- source "drivers/net/ethernet/seeq/Kconfig"
- source "drivers/net/ethernet/sgi/Kconfig"
---- a/drivers/net/ethernet/Makefile
-+++ b/drivers/net/ethernet/Makefile
-@@ -77,6 +77,7 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += real
- obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/
- obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
- obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/
-+obj-$(CONFIG_NET_RTL838X) += rtl838x_eth.o
- obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/
- obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
- obj-$(CONFIG_NET_VENDOR_SILAN) += silan/
diff --git a/target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch b/target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch
deleted file mode 100644
index bf4d35764e..0000000000
--- a/target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 26 Nov 2020 12:02:21 +0100
-Subject: phy: Add PHY ops for rtl838x EEE
-
-* rename the target to realtek
-* add refactored DSA driver
-* add latest gpio driver
-* lots of arch cleanups
-* new irq driver
-* additional boards
-
-Submitted-by: Bert Vermeulen <bert@biot.com>
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Submitted-by: Bjørn Mork <bjorn@mork.no>
-Submitted-by: John Crispin <john@phrozen.org>
----
- include/linux/phy.h | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1009,6 +1009,10 @@ struct phy_driver {
- int (*led_blink_set)(struct phy_device *dev, u8 index,
- unsigned long *delay_on,
- unsigned long *delay_off);
-+ int (*get_port)(struct phy_device *dev);
-+ int (*set_port)(struct phy_device *dev, int port);
-+ int (*get_eee)(struct phy_device *dev, struct ethtool_eee *e);
-+ int (*set_eee)(struct phy_device *dev, struct ethtool_eee *e);
- };
- #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
- struct phy_driver, mdiodrv)
diff --git a/target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch b/target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch
deleted file mode 100644
index bf6e517cfb..0000000000
--- a/target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 26 Nov 2020 12:02:21 +0100
-Subject: net: phy: EEE support for rtl838x
-
-* rename the target to realtek
-* add refactored DSA driver
-* add latest gpio driver
-* lots of arch cleanups
-* new irq driver
-* additional boards
-
-Submitted-by: Bert Vermeulen <bert@biot.com>
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Submitted-by: Bjørn Mork <bjorn@mork.no>
-Submitted-by: John Crispin <john@phrozen.org>
----
- drivers/net/phy/phylink. | 14 +++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1994,6 +1994,11 @@ int phylink_ethtool_ksettings_set(struct
- * the presence of a PHY, this should not be changed as that
- * should be determined from the media side advertisement.
- */
-+ if (pl->phydev->drv->get_port && pl->phydev->drv->set_port) {
-+ if(pl->phydev->drv->get_port(pl->phydev) != kset->base.port) {
-+ pl->phydev->drv->set_port(pl->phydev, kset->base.port);
-+ }
-+ }
- return phy_ethtool_ksettings_set(pl->phydev, kset);
- }
-
-@@ -2297,8 +2302,11 @@ int phylink_ethtool_get_eee(struct phyli
-
- ASSERT_RTNL();
-
-- if (pl->phydev)
-+ if (pl->phydev) {
-+ if (pl->phydev->drv->get_eee)
-+ return pl->phydev->drv->get_eee(pl->phydev, eee);
- ret = phy_ethtool_get_eee(pl->phydev, eee);
-+ }
-
- return ret;
- }
-@@ -2315,8 +2323,11 @@ int phylink_ethtool_set_eee(struct phyli
-
- ASSERT_RTNL();
-
-- if (pl->phydev)
-+ if (pl->phydev) {
-+ if (pl->phydev->drv->set_eee)
-+ return pl->phydev->drv->set_eee(pl->phydev, eee);
- ret = phy_ethtool_set_eee(pl->phydev, eee);
-+ }
-
- return ret;
- }
diff --git a/target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch b/target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch
deleted file mode 100644
index 700ec97be8..0000000000
--- a/target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 9d9bf16aa8d966834ac1280f96c37d22552c33d1 Mon Sep 17 00:00:00 2001
-From: Birger Koblitz <git@birger-koblitz.de>
-Date: Wed, 8 Sep 2021 16:13:18 +0200
-Subject: phy: Add PHY hsgmii mode
-
-This adds RTL93xx-specific MAC configuration routines that allow also configuration
-of 10GBit links for phylink. There is support for the Realtek-specific HISGMI
-protocol.
-
-Submitted-by: Birger Koblitz <git@birger-koblitz.de>
----
- drivers/net/phy/phylink.c | 2 ++
- include/linux/phy.h | 3 +++
- 2 file changed, 5 insertions(+)
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -124,6 +124,7 @@ int phy_interface_num_ports(phy_interfac
- case PHY_INTERFACE_MODE_MOCA:
- case PHY_INTERFACE_MODE_TRGMII:
- case PHY_INTERFACE_MODE_USXGMII:
-+ case PHY_INTERFACE_MODE_HSGMII:
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_SMII:
- case PHY_INTERFACE_MODE_1000BASEX:
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -410,6 +410,7 @@ void phylink_get_linkmodes(unsigned long
-
- case PHY_INTERFACE_MODE_XGMII:
- case PHY_INTERFACE_MODE_RXAUI:
-+ case PHY_INTERFACE_MODE_HSGMII:
- case PHY_INTERFACE_MODE_XAUI:
- case PHY_INTERFACE_MODE_10GBASER:
- case PHY_INTERFACE_MODE_10GKR:
-@@ -665,6 +666,7 @@ static int phylink_parse_mode(struct phy
- fallthrough;
- case PHY_INTERFACE_MODE_USXGMII:
- case PHY_INTERFACE_MODE_10GKR:
-+ case PHY_INTERFACE_MODE_HSGMII:
- case PHY_INTERFACE_MODE_10GBASER:
- phylink_set(pl->supported, 10baseT_Half);
- phylink_set(pl->supported, 10baseT_Full);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -141,6 +141,7 @@ typedef enum {
- PHY_INTERFACE_MODE_XGMII,
- PHY_INTERFACE_MODE_XLGMII,
- PHY_INTERFACE_MODE_MOCA,
-+ PHY_INTERFACE_MODE_HSGMII,
- PHY_INTERFACE_MODE_QSGMII,
- PHY_INTERFACE_MODE_TRGMII,
- PHY_INTERFACE_MODE_100BASEX,
-@@ -248,6 +249,8 @@ static inline const char *phy_modes(phy_
- return "xlgmii";
- case PHY_INTERFACE_MODE_MOCA:
- return "moca";
-+ case PHY_INTERFACE_MODE_HSGMII:
-+ return "hsgmii";
- case PHY_INTERFACE_MODE_QSGMII:
- return "qsgmii";
- case PHY_INTERFACE_MODE_TRGMII:
diff --git a/target/linux/realtek/patches-5.15/705-add-rtl-phy.patch b/target/linux/realtek/patches-5.15/705-add-rtl-phy.patch
deleted file mode 100644
index c6f8e6508b..0000000000
--- a/target/linux/realtek/patches-5.15/705-add-rtl-phy.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 89f71ebb355c624320c2b0ace8ae9488ff53cbeb Mon Sep 17 00:00:00 2001
-From: Birger Koblitz <mail@birger-koblitz.de>
-Date: Tue, 5 Jan 2021 20:40:52 +0100
-Subject: PHY: Add realtek PHY
-
-This fixes the build problems for the REALTEK target by adding a proper
-configuration option for the phy module.
-
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
----
- drivers/net/phy/Kconfig | 6 ++++++
- drivers/net/phy/Makefile | 1 +
- 2 files changed, 7 insertions(+)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -354,6 +354,12 @@ config REALTEK_PHY
- help
- Supports the Realtek 821x PHY.
-
-+config REALTEK_SOC_PHY
-+ tristate "Realtek SoC PHYs"
-+ depends on RTL83XX
-+ help
-+ Supports the PHYs found in combination with Realtek Switch SoCs
-+
- config RENESAS_PHY
- tristate "Renesas PHYs"
- help
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -89,6 +89,7 @@ obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp
- obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o
- obj-$(CONFIG_QSEMI_PHY) += qsemi.o
- obj-$(CONFIG_REALTEK_PHY) += realtek.o
-+obj-$(CONFIG_REALTEK_SOC_PHY) += rtl83xx-phy.o
- obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
- obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
- obj-$(CONFIG_SMSC_PHY) += smsc.o
diff --git a/target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch b/target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch
deleted file mode 100644
index 9a6b00d7c0..0000000000
--- a/target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 26 Nov 2020 12:02:21 +0100
-Subject: PHY: Increase max PHY adddress number
-
-* rename the target to realtek
-* add refactored DSA driver
-* add latest gpio driver
-* lots of arch cleanups
-* new irq driver
-* additional boards
-
-Submitted-by: Bert Vermeulen <bert@biot.com>
-Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
-Submitted-by: Sander Vanheule <sander@svanheule.net>
-Submitted-by: Bjørn Mork <bjorn@mork.no>
-Submitted-by: John Crispin <john@phrozen.org>
----
- include/linux/phy.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -287,7 +287,7 @@ static inline const char *phy_modes(phy_
- #define PHY_INIT_TIMEOUT 100000
- #define PHY_FORCE_TIMEOUT 10
-
--#define PHY_MAX_ADDR 32
-+#define PHY_MAX_ADDR 64
-
- /* Used when trying to connect to a specific phy (mii bus id:phy device id) */
- #define PHY_ID_FMT "%s:%02x"
diff --git a/target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch b/target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch
deleted file mode 100644
index 378563a9e3..0000000000
--- a/target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From a381ac0aa281fdb0b41a39d8a2bc08fd88f6db92 Mon Sep 17 00:00:00 2001
-From: Antoine Tenart <antoine.tenart@bootlin.com>
-Date: Tue, 25 Feb 2020 16:32:37 +0100
-Subject: [PATCH 1/3] net: phy: sfp: re-probe modules on DEV_UP event
-
-Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
----
- drivers/net/phy/sfp.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -2160,6 +2160,13 @@ static void sfp_sm_module(struct sfp *sf
- return;
- }
-
-+ /* Re-probe the SFP modules when an interface is brought up, as the MAC
-+ * do not report its link status (This means Phylink wouldn't be
-+ * triggered if the PHY had a link before a MAC is brought up).
-+ */
-+ if (event == SFP_E_DEV_UP && sfp->sm_mod_state == SFP_MOD_PRESENT)
-+ sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL);
-+
- switch (sfp->sm_mod_state) {
- default:
- if (event == SFP_E_INSERT) {
diff --git a/target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch b/target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch
deleted file mode 100644
index 767a5d8ec5..0000000000
--- a/target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From d585c55b9f70cf9e8c66820d7efe7130c683f19e Mon Sep 17 00:00:00 2001
-From: Antoine Tenart <antoine.tenart@bootlin.com>
-Date: Fri, 21 Feb 2020 11:51:27 +0100
-Subject: [PATCH 2/3] net: phy: add an MDIO SMBus library
-
-Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
----
- drivers/net/mdio/Kconfig | 11 +++++++
- drivers/net/mdio/Makefile | 1 +
- drivers/net/mdio/mdio-smbus.c | 62 +++++++++++++++++++++++++++++++++++
- drivers/net/phy/Kconfig | 1 +
- include/linux/mdio/mdio-i2c.h | 16 +++++++++
- 5 files changed, 91 insertions(+)
- create mode 100644 drivers/net/mdio/mdio-smbus.c
-
---- a/drivers/net/mdio/Kconfig
-+++ b/drivers/net/mdio/Kconfig
-@@ -54,6 +54,17 @@ config MDIO_SUN4I
- interface units of the Allwinner SoC that have an EMAC (A10,
- A12, A10s, etc.)
-
-+config MDIO_SMBUS
-+ tristate
-+ depends on I2C_SMBUS
-+ help
-+ Support SMBus based PHYs. This provides a MDIO bus bridged
-+ to SMBus to allow PHYs connected in SMBus mode to be accessed
-+ using the existing infrastructure.
-+
-+ This is library mode.
-+
-+
- config MDIO_XGENE
- tristate "APM X-Gene SoC MDIO bus controller"
- depends on ARCH_XGENE || COMPILE_TEST
---- a/drivers/net/mdio/Makefile
-+++ b/drivers/net/mdio/Makefile
-@@ -19,6 +19,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxar
- obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
- obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
- obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
-+obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o
- obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
- obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
- obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
---- /dev/null
-+++ b/drivers/net/mdio/mdio-smbus.c
-@@ -0,0 +1,62 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * MDIO SMBus bridge
-+ *
-+ * Copyright (C) 2020 Antoine Tenart
-+ *
-+ * Network PHYs can appear on SMBus when they are part of SFP modules.
-+ */
-+#include <linux/i2c.h>
-+#include <linux/phy.h>
-+#include <linux/mdio/mdio-i2c.h>
-+
-+static int smbus_mii_read(struct mii_bus *mii, int phy_id, int reg)
-+{
-+ struct i2c_adapter *i2c = mii->priv;
-+ union i2c_smbus_data data;
-+ int ret;
-+
-+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_READ,
-+ reg, I2C_SMBUS_BYTE_DATA, &data);
-+ if (ret < 0)
-+ return 0xff;
-+
-+ return data.byte;
-+}
-+
-+static int smbus_mii_write(struct mii_bus *mii, int phy_id, int reg, u16 val)
-+{
-+ struct i2c_adapter *i2c = mii->priv;
-+ union i2c_smbus_data data;
-+ int ret;
-+
-+ data.byte = val;
-+
-+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_WRITE,
-+ reg, I2C_SMBUS_BYTE_DATA, &data);
-+ return ret < 0 ? ret : 0;
-+}
-+
-+struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c)
-+{
-+ struct mii_bus *mii;
-+
-+ if (!i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA))
-+ return ERR_PTR(-EINVAL);
-+
-+ mii = mdiobus_alloc();
-+ if (!mii)
-+ return ERR_PTR(-ENOMEM);
-+
-+ snprintf(mii->id, MII_BUS_ID_SIZE, "smbus:%s", dev_name(parent));
-+ mii->parent = parent;
-+ mii->read = smbus_mii_read;
-+ mii->write = smbus_mii_write;
-+ mii->priv = i2c;
-+
-+ return mii;
-+}
-+
-+MODULE_AUTHOR("Antoine Tenart");
-+MODULE_DESCRIPTION("MDIO SMBus bridge library");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -61,6 +61,7 @@ config SFP
- depends on I2C && PHYLINK
- depends on HWMON || HWMON=n
- select MDIO_I2C
-+ select MDIO_SMBUS
-
- comment "Switch configuration API + drivers"
-
---- a/include/linux/mdio/mdio-i2c.h
-+++ b/include/linux/mdio/mdio-i2c.h
-@@ -12,5 +12,8 @@ struct i2c_adapter;
- struct mii_bus;
-
- struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
-+struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c);
-+bool i2c_mii_valid_phy_id(int phy_id);
-+unsigned int i2c_mii_phy_addr(int phy_id);
-
- #endif
---- a/drivers/net/mdio/mdio-i2c.c
-+++ b/drivers/net/mdio/mdio-i2c.c
-@@ -18,12 +18,12 @@
- * specified to be present in SFP modules. These correspond with PHY
- * addresses 16 and 17. Disallow access to these "phy" addresses.
- */
--static bool i2c_mii_valid_phy_id(int phy_id)
-+bool i2c_mii_valid_phy_id(int phy_id)
- {
- return phy_id != 0x10 && phy_id != 0x11;
- }
-
--static unsigned int i2c_mii_phy_addr(int phy_id)
-+unsigned int i2c_mii_phy_addr(int phy_id)
- {
- return phy_id + 0x40;
- }
diff --git a/target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch b/target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch
deleted file mode 100644
index 53ec0fa1da..0000000000
--- a/target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 3cb0bde365d913c484d20224367a54a0eac780a7 Mon Sep 17 00:00:00 2001
-From: Antoine Tenart <antoine.tenart@bootlin.com>
-Date: Fri, 21 Feb 2020 11:55:29 +0100
-Subject: [PATCH 3/3] net: phy: sfp: add support for SMBus
-
-Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
----
- drivers/net/phy/sfp.c | 68 ++++++++++++++++++++++++++++++++++---------
- 1 file changed, 54 insertions(+), 14 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -556,32 +556,72 @@ static int sfp_i2c_write(struct sfp *sfp
- return ret == ARRAY_SIZE(msgs) ? len : 0;
- }
-
-+static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
-+ size_t len)
-+{
-+ u8 bus_addr = a2 ? 0x51 : 0x50, *val = buf;
-+
-+ bus_addr -= 0x40;
-+
-+ while (len > 0) {
-+ *val = sfp->i2c_mii->read(sfp->i2c_mii, bus_addr, dev_addr);
-+
-+ val++;
-+ dev_addr++;
-+ len--;
-+ }
-+
-+ return val - (u8 *)buf;
-+}
-+
-+static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
-+ size_t len)
-+{
-+ u8 bus_addr = a2 ? 0x51 : 0x50;
-+ u16 val;
-+
-+ memcpy(&val, buf, len);
-+
-+ return sfp->i2c_mii->write(sfp->i2c_mii, bus_addr, dev_addr, val);
-+}
-+
- static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
- {
-- struct mii_bus *i2c_mii;
-+ struct mii_bus *mii;
- int ret;
-
-- if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
-- return -EINVAL;
--
- sfp->i2c = i2c;
-- sfp->read = sfp_i2c_read;
-- sfp->write = sfp_i2c_write;
-
-- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
-- if (IS_ERR(i2c_mii))
-- return PTR_ERR(i2c_mii);
-+ if (i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
-+ sfp->read = sfp_i2c_read;
-+ sfp->write = sfp_i2c_write;
-+
-+ mii = mdio_i2c_alloc(sfp->dev, i2c);
-+ if (IS_ERR(mii))
-+ return PTR_ERR(mii);
-+
-+ mii->name = "SFP I2C Bus";
-+ } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) {
-+ sfp->read = sfp_smbus_read;
-+ sfp->write = sfp_smbus_write;
-+
-+ mii = mdio_smbus_alloc(sfp->dev, i2c);
-+ if (IS_ERR(mii))
-+ return PTR_ERR(mii);
-
-- i2c_mii->name = "SFP I2C Bus";
-- i2c_mii->phy_mask = ~0;
-+ mii->name = "SFP SMBus";
-+ } else {
-+ return -EINVAL;
-+ }
-
-- ret = mdiobus_register(i2c_mii);
-+ mii->phy_mask = ~0;
-+ ret = mdiobus_register(mii);
- if (ret < 0) {
-- mdiobus_free(i2c_mii);
-+ mdiobus_free(mii);
- return ret;
- }
-
-- sfp->i2c_mii = i2c_mii;
-+ sfp->i2c_mii = mii;
-
- return 0;
- }
diff --git a/target/linux/realtek/patches-5.15/800-net-mdio-support-hardware-assisted-indirect-access.patch b/target/linux/realtek/patches-5.15/800-net-mdio-support-hardware-assisted-indirect-access.patch
deleted file mode 100644
index 188d68b121..0000000000
--- a/target/linux/realtek/patches-5.15/800-net-mdio-support-hardware-assisted-indirect-access.patch
+++ /dev/null
@@ -1,840 +0,0 @@
-From 5d84f16b0036b33487b94abef15ad3c224c81ee9 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 3 Feb 2022 16:38:50 +0000
-Subject: [PATCH] net: mdio: support hardware-assisted indirect access
-
-MDIO controllers found in Switch-SoCs can offload some MDIO operations
-to the hardware:
- * MMD register access via Clause-22
- Instead of using multiple operations to access MMD registers via
- MII register MII_MMD_CTRL and MII_MMD_DATA some controllers
- allow transparent access to MMD PHY registers.
-
- * paged MII register access
- Some PHYs (namely RealTek and Vitesse) use vendor-defined MII
- register 0x1f for paged access. Some MDIO host controllers support
- transparent paged access when used with such PHYs.
-
- * add convenience accessors to fully support paged access also on
- multi-PHY packages (like the embedded PHYs in RTL83xx):
- phy_package_read_paged and phy_package_write_paged
- phy_package_port_read and phy_package_port_write
- phy_package_port_read_paged and phy_package_port_write_paged
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/mdio_bus.c | 335 ++++++++++++++++++++++++++++++++++++-
- drivers/net/phy/phy-core.c | 66 +++++++-
- include/linux/mdio.h | 59 +++++++
- include/linux/phy.h | 129 ++++++++++++++
- include/uapi/linux/mii.h | 1 +
- 5 files changed, 580 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/mdio_bus.c
-+++ b/drivers/net/phy/mdio_bus.c
-@@ -742,6 +742,32 @@ out:
- }
-
- /**
-+ * __mdiobus_select_page - Unlocked version of the mdiobus_select_page function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: register page to select
-+ *
-+ * Selects a MDIO bus register page. Caller must hold the mdio bus lock.
-+ *
-+ * NOTE: MUST NOT be called from interrupt context.
-+ */
-+int __mdiobus_select_page(struct mii_bus *bus, int addr, u16 page)
-+{
-+ lockdep_assert_held_once(&bus->mdio_lock);
-+
-+ if (bus->selected_page[addr] == page)
-+ return 0;
-+
-+ bus->selected_page[addr] = page;
-+ if (bus->read_paged)
-+ return 0;
-+
-+ return bus->write(bus, addr, MII_MAINPAGE, page);
-+
-+}
-+EXPORT_SYMBOL(__mdiobus_select_page);
-+
-+/**
- * __mdiobus_read - Unlocked version of the mdiobus_read function
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -757,7 +783,10 @@ int __mdiobus_read(struct mii_bus *bus,
-
- lockdep_assert_held_once(&bus->mdio_lock);
-
-- retval = bus->read(bus, addr, regnum);
-+ if (bus->read_paged)
-+ retval = bus->read_paged(bus, addr, bus->selected_page[addr], regnum);
-+ else
-+ retval = bus->read(bus, addr, regnum);
-
- trace_mdio_access(bus, 1, addr, regnum, retval, retval);
- mdiobus_stats_acct(&bus->stats[addr], true, retval);
-@@ -767,6 +796,40 @@ int __mdiobus_read(struct mii_bus *bus,
- EXPORT_SYMBOL(__mdiobus_read);
-
- /**
-+ * __mdiobus_read_paged - Unlocked version of the mdiobus_read_paged function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: the register page to access
-+ * @regnum: register number to read
-+ *
-+ * Read a MDIO bus register. Caller must hold the mdio bus lock.
-+ *
-+ * NOTE: MUST NOT be called from interrupt context.
-+ */
-+int __mdiobus_read_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum)
-+{
-+ int retval;
-+ int oldpage;
-+
-+ lockdep_assert_held_once(&bus->mdio_lock);
-+
-+ if (bus->read_paged) {
-+ retval = bus->read_paged(bus, addr, page, regnum);
-+ } else {
-+ oldpage = bus->selected_page[addr];
-+ __mdiobus_select_page(bus, addr, page);
-+ retval = bus->read(bus, addr, regnum);
-+ __mdiobus_select_page(bus, addr, oldpage);
-+ }
-+
-+ trace_mdio_access(bus, 1, addr, regnum, retval, retval);
-+ mdiobus_stats_acct(&bus->stats[addr], true, retval);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(__mdiobus_read_paged);
-+
-+/**
- * __mdiobus_write - Unlocked version of the mdiobus_write function
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -783,7 +846,10 @@ int __mdiobus_write(struct mii_bus *bus,
-
- lockdep_assert_held_once(&bus->mdio_lock);
-
-- err = bus->write(bus, addr, regnum, val);
-+ if (bus->write_paged)
-+ err = bus->write_paged(bus, addr, bus->selected_page[addr], regnum, val);
-+ else
-+ err = bus->write(bus, addr, regnum, val);
-
- trace_mdio_access(bus, 0, addr, regnum, val, err);
- mdiobus_stats_acct(&bus->stats[addr], false, err);
-@@ -793,6 +859,39 @@ int __mdiobus_write(struct mii_bus *bus,
- EXPORT_SYMBOL(__mdiobus_write);
-
- /**
-+ * __mdiobus_write_paged - Unlocked version of the mdiobus_write_paged function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: the register page to access
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * Write a MDIO bus register. Caller must hold the mdio bus lock.
-+ *
-+ * NOTE: MUST NOT be called from interrupt context.
-+ */
-+int __mdiobus_write_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 val)
-+{
-+ int err, oldpage;
-+
-+ lockdep_assert_held_once(&bus->mdio_lock);
-+
-+ if (bus->write_paged) {
-+ err = bus->write_paged(bus, addr, page, regnum, val);
-+ } else {
-+ oldpage = bus->selected_page[addr];
-+ __mdiobus_select_page(bus, addr, page);
-+ err = bus->write(bus, addr, regnum, val);
-+ __mdiobus_select_page(bus, addr, oldpage);
-+ }
-+ trace_mdio_access(bus, 0, addr, regnum, val, err);
-+ mdiobus_stats_acct(&bus->stats[addr], false, err);
-+ return err;
-+}
-+EXPORT_SYMBOL(__mdiobus_write_paged);
-+
-+
-+/**
- * __mdiobus_modify_changed - Unlocked version of the mdiobus_modify function
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -825,6 +924,43 @@ int __mdiobus_modify_changed(struct mii_
- EXPORT_SYMBOL_GPL(__mdiobus_modify_changed);
-
- /**
-+ * __mdiobus_modify_changed_paged - Unlocked version of the mdiobus_modify_paged function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @regnum: register number to modify
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ *
-+ * Read, modify, and if any change, write the register value back to the
-+ * device. Any error returns a negative number.
-+ *
-+ * NOTE: MUST NOT be called from interrupt context.
-+ */
-+int __mdiobus_modify_changed_paged(struct mii_bus *bus, int addr, u32 regnum, u16 page,
-+ u16 mask, u16 set)
-+{
-+ int new, ret, oldpage;
-+
-+ oldpage = bus->selected_page[addr];
-+ __mdiobus_select_page(bus, addr, page);
-+
-+ ret = __mdiobus_read_paged(bus, addr, page, regnum);
-+ if (ret < 0)
-+ return ret;
-+
-+ new = (ret & ~mask) | set;
-+ if (new == ret)
-+ return 0;
-+
-+ ret = __mdiobus_write_paged(bus, addr, page, regnum, new);
-+
-+ __mdiobus_select_page(bus, addr, oldpage);
-+
-+ return ret < 0 ? ret : 1;
-+}
-+EXPORT_SYMBOL_GPL(__mdiobus_modify_changed_paged);
-+
-+/**
- * mdiobus_read_nested - Nested version of the mdiobus_read function
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -850,6 +986,79 @@ int mdiobus_read_nested(struct mii_bus *
- EXPORT_SYMBOL(mdiobus_read_nested);
-
- /**
-+ * mdiobus_select_page_nested - Nested version of the mdiobus_select_page function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: register page to access
-+ *
-+ * In case of nested MDIO bus access avoid lockdep false positives by
-+ * using mutex_lock_nested().
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_select_page_nested(struct mii_bus *bus, int addr, u16 page)
-+{
-+ int retval;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ retval = __mdiobus_select_page(bus, addr, page);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(mdiobus_select_page_nested);
-+
-+/**
-+ * mdiobus_read_paged_nested - Nested version of the mdiobus_read_paged function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: register page to access
-+ * @regnum: register number to read
-+ *
-+ * In case of nested MDIO bus access avoid lockdep false positives by
-+ * using mutex_lock_nested().
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_read_paged_nested(struct mii_bus *bus, int addr, u16 page, u32 regnum)
-+{
-+ int retval;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ retval = __mdiobus_read_paged(bus, addr, page, regnum);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(mdiobus_read_paged_nested);
-+
-+/**
-+ * mdiobus_select_page - Convenience function for setting the MII register page
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: the register page to set
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_select_page(struct mii_bus *bus, int addr, u16 page)
-+{
-+ int retval;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ retval = __mdiobus_select_page(bus, addr, page);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(mdiobus_select_page);
-+
-+/**
- * mdiobus_read - Convenience function for reading a given MII mgmt register
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -872,6 +1081,29 @@ int mdiobus_read(struct mii_bus *bus, in
- EXPORT_SYMBOL(mdiobus_read);
-
- /**
-+ * mdiobus_read_paged - Convenience function for reading a given paged MII mgmt register
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: register page to access
-+ * @regnum: register number to read
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_read_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum)
-+{
-+ int retval;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ retval = __mdiobus_read_paged(bus, addr, page, regnum);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(mdiobus_read_paged);
-+
-+/**
- * mdiobus_write_nested - Nested version of the mdiobus_write function
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -898,6 +1130,33 @@ int mdiobus_write_nested(struct mii_bus
- EXPORT_SYMBOL(mdiobus_write_nested);
-
- /**
-+ * mdiobus_write_paged_nested - Nested version of the mdiobus_write_aged function
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: the register page to access
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * In case of nested MDIO bus access avoid lockdep false positives by
-+ * using mutex_lock_nested().
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_write_paged_nested(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 val)
-+{
-+ int err;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+ err = __mdiobus_write_paged(bus, addr, page, regnum, val);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL(mdiobus_write_paged_nested);
-+
-+/**
- * mdiobus_write - Convenience function for writing a given MII mgmt register
- * @bus: the mii_bus struct
- * @addr: the phy address
-@@ -921,6 +1180,30 @@ int mdiobus_write(struct mii_bus *bus, i
- EXPORT_SYMBOL(mdiobus_write);
-
- /**
-+ * mdiobus_write_paged - Convenience function for writing a given paged MII mgmt register
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: the register page to access
-+ * @regnum: register number to write
-+ * @val: value to write to @regnum
-+ *
-+ * NOTE: MUST NOT be called from interrupt context,
-+ * because the bus read/write functions may wait for an interrupt
-+ * to conclude the operation.
-+ */
-+int mdiobus_write_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 val)
-+{
-+ int err;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ err = __mdiobus_write_paged(bus, addr, page, regnum, val);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL(mdiobus_write_paged);
-+
-+/**
- * mdiobus_modify - Convenience function for modifying a given mdio device
- * register
- * @bus: the mii_bus struct
-@@ -942,6 +1225,51 @@ int mdiobus_modify(struct mii_bus *bus,
- EXPORT_SYMBOL_GPL(mdiobus_modify);
-
- /**
-+ * mdiobus_modify_paged - Convenience function for modifying a given mdio device
-+ * register
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: the register page to access
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ */
-+int mdiobus_modify_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 mask, u16 set)
-+{
-+ int err;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ err = __mdiobus_modify_changed_paged(bus, addr, page, regnum, mask, set);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return err < 0 ? err : 0;
-+}
-+EXPORT_SYMBOL_GPL(mdiobus_modify_paged);
-+
-+/**
-+ * mdiobus_modify_changed_paged - Convenience function for modifying a given paged
-+ * mdio device register and returning if it changed
-+ * @bus: the mii_bus struct
-+ * @addr: the phy address
-+ * @page: the register page to access
-+ * @regnum: register number to write
-+ * @mask: bit mask of bits to clear
-+ * @set: bit mask of bits to set
-+ */
-+int mdiobus_modify_changed_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum,
-+ u16 mask, u16 set)
-+{
-+ int err;
-+
-+ mutex_lock(&bus->mdio_lock);
-+ err = __mdiobus_modify_changed_paged(bus, addr, page, regnum, mask, set);
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL_GPL(mdiobus_modify_changed_paged);
-+
-+/**
- * mdio_bus_match - determine if given MDIO driver supports the given
- * MDIO device
- * @dev: target MDIO device
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -557,10 +557,16 @@ int __phy_read_mmd(struct phy_device *ph
- struct mii_bus *bus = phydev->mdio.bus;
- int phy_addr = phydev->mdio.addr;
-
-- mmd_phy_indirect(bus, phy_addr, devad, regnum);
--
-- /* Read the content of the MMD's selected register */
-- val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
-+ if (bus->access_capabilities & MDIOBUS_ACCESS_C22_MMD) {
-+ val = __mdiobus_c22_mmd_read(phydev->mdio.bus,
-+ phydev->mdio.addr,
-+ devad, regnum);
-+ } else {
-+ mmd_phy_indirect(bus, phy_addr, devad, regnum);
-+
-+ /* Read the content of the MMD's selected register */
-+ val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
-+ }
- }
- return val;
- }
-@@ -613,12 +619,18 @@ int __phy_write_mmd(struct phy_device *p
- struct mii_bus *bus = phydev->mdio.bus;
- int phy_addr = phydev->mdio.addr;
-
-- mmd_phy_indirect(bus, phy_addr, devad, regnum);
-+ if (bus->access_capabilities & MDIOBUS_ACCESS_C22_MMD) {
-+ ret = __mdiobus_c22_mmd_write(phydev->mdio.bus,
-+ phydev->mdio.addr,
-+ devad, regnum, val);
-+ } else {
-+ mmd_phy_indirect(bus, phy_addr, devad, regnum);
-
-- /* Write the data into MMD's selected register */
-- __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
-+ /* Write the data into MMD's selected register */
-+ __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
-
-- ret = 0;
-+ ret = 0;
-+ }
- }
- return ret;
- }
-@@ -824,6 +836,13 @@ EXPORT_SYMBOL_GPL(phy_modify_mmd);
-
- static int __phy_read_page(struct phy_device *phydev)
- {
-+ if (phydev->drv && phydev->drv->flags & PHY_HAS_REALTEK_PAGES) {
-+ struct mii_bus *bus = phydev->mdio.bus;
-+ int phy_addr = phydev->mdio.addr;
-+
-+ return bus->selected_page[phy_addr];
-+ }
-+
- if (WARN_ONCE(!phydev->drv->read_page, "read_page callback not available, PHY driver not loaded?\n"))
- return -EOPNOTSUPP;
-
-@@ -832,6 +851,13 @@ static int __phy_read_page(struct phy_de
-
- static int __phy_write_page(struct phy_device *phydev, int page)
- {
-+ if (phydev->drv && phydev->drv->flags & PHY_HAS_REALTEK_PAGES) {
-+ struct mii_bus *bus = phydev->mdio.bus;
-+ int phy_addr = phydev->mdio.addr;
-+
-+ return __mdiobus_select_page(bus, phy_addr, page);
-+ }
-+
- if (WARN_ONCE(!phydev->drv->write_page, "write_page callback not available, PHY driver not loaded?\n"))
- return -EOPNOTSUPP;
-
-@@ -933,6 +959,18 @@ int phy_read_paged(struct phy_device *ph
- {
- int ret = 0, oldpage;
-
-+ if (phydev->drv && phydev->drv->flags & PHY_HAS_REALTEK_PAGES) {
-+ struct mii_bus *bus = phydev->mdio.bus;
-+ int phy_addr = phydev->mdio.addr;
-+
-+ if (bus->read_paged) {
-+ phy_lock_mdio_bus(phydev);
-+ ret = bus->read_paged(bus, phy_addr, page, regnum);
-+ phy_unlock_mdio_bus(phydev);
-+ return ret;
-+ }
-+ }
-+
- oldpage = phy_select_page(phydev, page);
- if (oldpage >= 0)
- ret = __phy_read(phydev, regnum);
-@@ -954,6 +992,18 @@ int phy_write_paged(struct phy_device *p
- {
- int ret = 0, oldpage;
-
-+ if (phydev->drv && phydev->drv->flags & PHY_HAS_REALTEK_PAGES) {
-+ struct mii_bus *bus = phydev->mdio.bus;
-+ int phy_addr = phydev->mdio.addr;
-+
-+ if (bus->write_paged) {
-+ phy_lock_mdio_bus(phydev);
-+ ret = bus->write_paged(bus, phy_addr, page, regnum, val);
-+ phy_unlock_mdio_bus(phydev);
-+ return ret;
-+ }
-+ }
-+
- oldpage = phy_select_page(phydev, page);
- if (oldpage >= 0)
- ret = __phy_write(phydev, regnum, val);
---- a/include/linux/mdio.h
-+++ b/include/linux/mdio.h
-@@ -14,6 +14,7 @@
- * IEEE 802.3ae clause 45 addressing mode used by 10GIGE phy chips.
- */
- #define MII_ADDR_C45 (1<<30)
-+#define MII_ADDR_C22_MMD (1<<29)
- #define MII_DEVADDR_C45_SHIFT 16
- #define MII_DEVADDR_C45_MASK GENMASK(20, 16)
- #define MII_REGADDR_C45_MASK GENMASK(15, 0)
-@@ -340,11 +341,19 @@ static inline void mii_10gbt_stat_mod_li
- advertising, lpa & MDIO_AN_10GBT_STAT_LP10G);
- }
-
-+int __mdiobus_select_page(struct mii_bus *bus, int addr, u16 page);
- int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
- int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
- int __mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
- u16 mask, u16 set);
-
-+int __mdiobus_read_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum);
-+int __mdiobus_write_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 val);
-+int __mdiobus_modify_changed_paged(struct mii_bus *bus, int addr, u32 regnum, u16 page,
-+ u16 mask, u16 set);
-+
-+int mdiobus_select_page(struct mii_bus *bus, int addr, u16 page);
-+int mdiobus_select_page_nested(struct mii_bus *bus, int addr, u16 page);
- int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
- int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum);
- int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
-@@ -352,11 +361,51 @@ int mdiobus_write_nested(struct mii_bus
- int mdiobus_modify(struct mii_bus *bus, int addr, u32 regnum, u16 mask,
- u16 set);
-
-+int mdiobus_read_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum);
-+int mdiobus_read_nested_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum);
-+int mdiobus_write_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 val);
-+int mdiobus_write_nested_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 val);
-+int mdiobus_modify_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum, u16 mask,
-+ u16 set);
-+int mdiobus_modify_changed_paged(struct mii_bus *bus, int addr, u16 page, u32 regnum,
-+ u16 mask, u16 set);
-+
-+static inline int mdiodev_read_paged(struct mdio_device *mdiodev, u16 page,
-+ u32 regnum)
-+{
-+ return mdiobus_read_paged(mdiodev->bus, mdiodev->addr, page, regnum);
-+}
-+
-+static inline int mdiodev_write_paged(struct mdio_device *mdiodev, u16 page,
-+ u32 regnum, u16 val)
-+{
-+ return mdiobus_write_paged(mdiodev->bus, mdiodev->addr, page, regnum, val);
-+}
-+
-+static inline int mdiodev_modify_paged(struct mdio_device *mdiodev, u16 page,
-+ u32 regnum, u16 mask, u16 set)
-+{
-+ return mdiobus_modify_paged(mdiodev->bus, mdiodev->addr, page, regnum,
-+ mask, set);
-+}
-+
-+static inline int mdiodev_modify_changed_paged(struct mdio_device *mdiodev, u16 page,
-+ u32 regnum, u16 mask, u16 set)
-+{
-+ return mdiobus_modify_changed_paged(mdiodev->bus, mdiodev->addr, page, regnum,
-+ mask, set);
-+}
-+
- static inline u32 mdiobus_c45_addr(int devad, u16 regnum)
- {
- return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
- }
-
-+static inline u32 mdiobus_c22_mmd_addr(int devad, u16 regnum)
-+{
-+ return MII_ADDR_C22_MMD | devad << MII_DEVADDR_C45_SHIFT | regnum;
-+}
-+
- static inline u16 mdiobus_c45_regad(u32 regnum)
- {
- return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
-@@ -380,6 +429,19 @@ static inline int __mdiobus_c45_write(st
- val);
- }
-
-+static inline int __mdiobus_c22_mmd_read(struct mii_bus *bus, int prtad,
-+ int devad, u16 regnum)
-+{
-+ return __mdiobus_read(bus, prtad, mdiobus_c22_mmd_addr(devad, regnum));
-+}
-+
-+static inline int __mdiobus_c22_mmd_write(struct mii_bus *bus, int prtad,
-+ int devad, u16 regnum, u16 val)
-+{
-+ return __mdiobus_write(bus, prtad, mdiobus_c22_mmd_addr(devad, regnum),
-+ val);
-+}
-+
- static inline int mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
- u16 regnum)
- {
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -81,6 +81,7 @@ extern const int phy_10gbit_features_arr
- #define PHY_IS_INTERNAL 0x00000001
- #define PHY_RST_AFTER_CLK_EN 0x00000002
- #define PHY_POLL_CABLE_TEST 0x00000004
-+#define PHY_HAS_REALTEK_PAGES 0x00000010
- #define MDIO_DEVICE_IS_PHY 0x80000000
-
- /**
-@@ -428,6 +429,22 @@ struct mii_bus {
-
- /** @shared: shared state across different PHYs */
- struct phy_package_shared *shared[PHY_MAX_ADDR];
-+
-+ /** @access_capabilities: hardware-assisted access capabilties */
-+ enum {
-+ MDIOBUS_ACCESS_SOFTWARE_ONLY = 0,
-+ MDIOBUS_ACCESS_C22_MMD = 0x1,
-+ } access_capabilities;
-+
-+ /** @read: Perform a read transfer on the bus, offloading page access */
-+ int (*read_paged)(struct mii_bus *bus, int addr, u16 page, int regnum);
-+ /** @write: Perform a write transfer on the bus, offloading page access */
-+ int (*write_paged)(struct mii_bus *bus, int addr, u16 page, int regnum, u16 val);
-+ /** currently selected page when page access is offloaded
-+ * array should be PHY_MAX_ADDR+1size, but current design of the MDIO driver
-+ * uses port addresses as phy addresses and they are up to 6 bit.
-+ */
-+ u16 selected_page[64];
- };
- #define to_mii_bus(d) container_of(d, struct mii_bus, dev)
-
-@@ -1825,6 +1842,66 @@ static inline int __phy_package_read(str
- return __mdiobus_read(phydev->mdio.bus, shared->addr, regnum);
- }
-
-+static inline int phy_package_read_port(struct phy_device *phydev, u16 port, u32 regnum)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return mdiobus_read(phydev->mdio.bus, shared->addr + port, regnum);
-+}
-+
-+static inline int __phy_package_read_port(struct phy_device *phydev, u16 port, u32 regnum)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return __mdiobus_read(phydev->mdio.bus, shared->addr + port, regnum);
-+}
-+
-+static inline int phy_package_read_paged(struct phy_device *phydev, u16 page, u32 regnum)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return mdiobus_read_paged(phydev->mdio.bus, shared->addr, page, regnum);
-+}
-+
-+static inline int __phy_package_read_paged(struct phy_device *phydev, u16 page, u32 regnum)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return __mdiobus_read_paged(phydev->mdio.bus, shared->addr, page, regnum);
-+}
-+
-+static inline int phy_package_port_read_paged(struct phy_device *phydev, u16 port, u16 page, u32 regnum)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return mdiobus_read_paged(phydev->mdio.bus, shared->addr + port, page, regnum);
-+}
-+
-+static inline int __phy_package_port_read_paged(struct phy_device *phydev, u16 port, u16 page, u32 regnum)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return __mdiobus_read_paged(phydev->mdio.bus, shared->addr + port, page, regnum);
-+}
-+
- static inline int phy_package_write(struct phy_device *phydev,
- u32 regnum, u16 val)
- {
-@@ -1847,6 +1924,72 @@ static inline int __phy_package_write(st
- return __mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val);
- }
-
-+static inline int phy_package_port_write(struct phy_device *phydev,
-+ u16 port, u32 regnum, u16 val)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return mdiobus_write(phydev->mdio.bus, shared->addr + port, regnum, val);
-+}
-+
-+static inline int __phy_package_port_write(struct phy_device *phydev,
-+ u16 port, u32 regnum, u16 val)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return __mdiobus_write(phydev->mdio.bus, shared->addr + port, regnum, val);
-+}
-+
-+static inline int phy_package_port_write_paged(struct phy_device *phydev,
-+ u16 port, u16 page, u32 regnum, u16 val)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return mdiobus_write_paged(phydev->mdio.bus, shared->addr + port, page, regnum, val);
-+}
-+
-+static inline int __phy_package_port_write_paged(struct phy_device *phydev,
-+ u16 port, u16 page, u32 regnum, u16 val)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return __mdiobus_write_paged(phydev->mdio.bus, shared->addr + port, page, regnum, val);
-+}
-+
-+static inline int phy_package_write_paged(struct phy_device *phydev,
-+ u16 page, u32 regnum, u16 val)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return mdiobus_write_paged(phydev->mdio.bus, shared->addr, page, regnum, val);
-+}
-+
-+static inline int __phy_package_write_paged(struct phy_device *phydev,
-+ u16 page, u32 regnum, u16 val)
-+{
-+ struct phy_package_shared *shared = phydev->shared;
-+
-+ if (!shared)
-+ return -EIO;
-+
-+ return __mdiobus_write_paged(phydev->mdio.bus, shared->addr, page, regnum, val);
-+}
-+
- static inline bool __phy_package_set_once(struct phy_device *phydev,
- unsigned int b)
- {
---- a/include/uapi/linux/mii.h
-+++ b/include/uapi/linux/mii.h
-@@ -36,6 +36,7 @@
- #define MII_RESV2 0x1a /* Reserved... */
- #define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
- #define MII_NCONFIG 0x1c /* Network interface config */
-+#define MII_MAINPAGE 0x1f /* Page register */
-
- /* Basic mode control register. */
- #define BMCR_RESV 0x003f /* Unused... */
diff --git a/target/linux/realtek/patches-6.6/300-mips-add-rtl838x-platform.patch b/target/linux/realtek/patches-6.6/300-mips-add-rtl838x-platform.patch
new file mode 100644
index 0000000000..7adbbbc517
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/300-mips-add-rtl838x-platform.patch
@@ -0,0 +1,86 @@
+From fce11f68491b46b93df69de0630cd9edb90bc772 Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <git@birger-koblitz.de>
+Date: Wed, 29 Dec 2021 21:54:21 +0100
+Subject: [PATCH] realtek: Create 4 different Realtek Platforms
+
+Creates RTL83XX as a basic kernel config parameter for the
+RTL838X, RTL839x, RTL930X and RTL931X platforms with respective
+configurations for the SoCs, which are introduced in addition.
+
+Submitted-by: Birger Koblitz <git@birger-koblitz.de>
+---
+ arch/mips/Kbuild.platforms | 1 +
+ arch/mips/Kconfig | 57 ++++++++++++++
+ 2 files changed, 58 insertions(+)
+
+--- a/arch/mips/Kbuild.platforms
++++ b/arch/mips/Kbuild.platforms
+@@ -22,6 +22,7 @@ platform-$(CONFIG_MACH_NINTENDO64) += n6
+ platform-$(CONFIG_PIC32MZDA) += pic32/
+ platform-$(CONFIG_RALINK) += ralink/
+ platform-$(CONFIG_MIKROTIK_RB532) += rb532/
++platform-$(CONFIG_RTL83XX) += rtl838x/
+ platform-$(CONFIG_SGI_IP22) += sgi-ip22/
+ platform-$(CONFIG_SGI_IP27) += sgi-ip27/
+ platform-$(CONFIG_SGI_IP28) += sgi-ip22/
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -968,8 +968,58 @@ config CAVIUM_OCTEON_SOC
+ Hikari
+ Say Y here for most Octeon reference boards.
+
++config RTL83XX
++ bool "Realtek based platforms"
++ select DMA_NONCOHERENT
++ select IRQ_MIPS_CPU
++ select NO_EXCEPT_FILL
++ select SYS_HAS_CPU_MIPS32_R1
++ select SYS_HAS_CPU_MIPS32_R2
++ select SYS_SUPPORTS_BIG_ENDIAN
++ select SYS_SUPPORTS_HIGHMEM
++ select SYS_SUPPORTS_32BIT_KERNEL
++ select SYS_SUPPORTS_MIPS16
++ select SYS_HAS_EARLY_PRINTK
++ select SYS_HAS_EARLY_PRINTK_8250
++ select USE_GENERIC_EARLY_PRINTK_8250
++ select BOOT_RAW
++ select PINCTRL
++ select ARCH_HAS_RESET_CONTROLLER
++ select RESET_CONTROLLER
++ select USE_OF
++
+ endchoice
+
++config RTL838X
++ bool "Realtek RTL838X based platforms"
++ depends on RTL83XX
++ select CPU_SUPPORTS_CPUFREQ
++ select MIPS_EXTERNAL_TIMER
++
++config RTL839X
++ bool "Realtek RTL839X based platforms"
++ depends on RTL83XX
++ select CPU_SUPPORTS_CPUFREQ
++ select MIPS_EXTERNAL_TIMER
++ select SYS_SUPPORTS_MULTITHREADING
++
++config RTL930X
++ bool "Realtek RTL930X based platforms"
++ depends on RTL83XX
++ select MIPS_CPU_SCACHE
++ select MIPS_EXTERNAL_TIMER
++ select SYS_SUPPORTS_MULTITHREADING
++
++config RTL931X
++ bool "Realtek RTL931X based platforms"
++ depends on RTL930X
++ select MIPS_GIC
++ select COMMON_CLK
++ select CLKSRC_MIPS_GIC
++ select SYS_SUPPORTS_VPE_LOADER
++ select SYS_SUPPORTS_SMP
++ select SYS_SUPPORTS_MIPS_CPS
++
+ source "arch/mips/alchemy/Kconfig"
+ source "arch/mips/ath25/Kconfig"
+ source "arch/mips/ath79/Kconfig"
diff --git a/target/linux/realtek/patches-6.6/301-gpio-add-rtl8231-driver.patch b/target/linux/realtek/patches-6.6/301-gpio-add-rtl8231-driver.patch
new file mode 100644
index 0000000000..a177876420
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/301-gpio-add-rtl8231-driver.patch
@@ -0,0 +1,50 @@
+From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 26 Nov 2020 12:02:21 +0100
+Subject: [PATCH] realtek: update the tree to the latest refactored version
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+* rename the target to realtek
+* add refactored DSA driver
+* add latest gpio driver
+* lots of arch cleanups
+* new irq driver
+* additional boards
+
+Submitted-by: Bert Vermeulen <bert@biot.com>
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Submitted-by: Bjørn Mork <bjorn@mork.no>
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ drivers/gpio/Kconfig | 6 ++++++
+ drivers/gpio/Makefile | 1 +
+ 2 files changed, 7 insertions(+)
+
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -553,6 +553,12 @@ config GPIO_ROCKCHIP
+ help
+ Say yes here to support GPIO on Rockchip SoCs.
+
++config GPIO_RTL8231
++ tristate "RTL8231 GPIO"
++ depends on RTL83XX
++ help
++ Say yes here to support Realtek RTL8231 GPIO expansion chips.
++
+ config GPIO_SAMA5D2_PIOBU
+ tristate "SAMA5D2 PIOBU GPIO support"
+ depends on MFD_SYSCON
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -138,6 +138,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc3
+ obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o
+ obj-$(CONFIG_GPIO_REG) += gpio-reg.o
+ obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
++obj-$(CONFIG_GPIO_RTL8231) += gpio-rtl8231.o
+ obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
+ obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
+ obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
diff --git a/target/linux/realtek/patches-6.6/302-clocksource-add-otto-driver.patch b/target/linux/realtek/patches-6.6/302-clocksource-add-otto-driver.patch
new file mode 100644
index 0000000000..791ad0edb7
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/302-clocksource-add-otto-driver.patch
@@ -0,0 +1,93 @@
+From 3cc8011171186d906c547bc6f0c1f8e350edc7cf Mon Sep 17 00:00:00 2001
+From: Markus Stockhausen <markus.stockhausen@gmx.de>
+Date: Mon, 3 Oct 2022 14:45:21 +0200
+Subject: [PATCH] realtek: resurrect timer driver
+
+Now that we provide a clock driver for the Reltek SOCs the CPU frequency might
+change on demand. This has direct visible effects during operation
+
+- the CEVT 4K timer is no longer a stable clocksource
+- after CPU frequencies changes time calculation works wrong
+- sched_clock falls back to kernel default interval (100 Hz)
+- timestamps in dmesg have only 2 digits left
+
+[ 0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps ...
+[ 0.060000] pid_max: default: 32768 minimum: 301
+[ 0.070000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
+[ 0.070000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
+[ 0.080000] dyndbg: Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build
+[ 0.090000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, ...
+
+Looking around where we can start the CEVT timer for RTL930X is a good basis.
+Initially it was developed as a clocksource driver for the broken timer in that
+specific SOC series. Afterwards it was shifted around to the CEVT location,
+got SMP enablement and lost its clocksource feature. So we at least have
+something to copy from. As the timers on these devices are well understood
+the implementation follows this way:
+
+- leave the RTL930X implementation as is
+- provide a new driver for RTL83XX devices only
+- swap RTL930X driver at a later time
+
+Like the clock driver this patch contains a self contained module that is SOC
+independet and already provides full support for the RTL838X, RTL839X and
+RTL930X devices. Some of the new (or reestablished) features are:
+
+- simplified initialization routines
+- SMP setup with CPU hotplug framework
+- derived from LXB clock speed
+- supplied clocksource
+- dedicated register functions for better readability
+- documentation about some caveats
+
+Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
+[remove unused header includes, remove old CONFIG_MIPS dependency, add
+REALTEK_ prefix to driver symbol]
+Signed-off-by: Sander Vanheule <sander@svanheule.net>
+
+---
+ drivers/clocksource/Kconfig | 12 +++
+ drivers/clocksource/Makefile | 1 +
+ include/linux/cpuhotplug.h | 1 +
+ 3 files changed, 14 insertions(+)
+
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -134,6 +134,17 @@ config RDA_TIMER
+ help
+ Enables the support for the RDA Micro timer driver.
+
++config REALTEK_OTTO_TIMER
++ bool "Clocksource/timer for the Realtek Otto platform"
++ select COMMON_CLK
++ select TIMER_OF
++ help
++ This driver adds support for the timers found in the Realtek RTL83xx
++ and RTL93xx SoCs series. This includes chips such as RTL8380, RTL8381
++ and RTL832, as well as chips from the RTL839x series, such as RTL8390
++ RT8391, RTL8392, RTL8393 and RTL8396 and chips of the RTL930x series
++ such as RTL9301, RTL9302 or RTL9303.
++
+ config SUN4I_TIMER
+ bool "Sun4i timer driver" if COMPILE_TEST
+ depends on HAS_IOMEM
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -59,6 +59,7 @@ obj-$(CONFIG_MILBEAUT_TIMER) += timer-mi
+ obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o
+ obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o
+ obj-$(CONFIG_RDA_TIMER) += timer-rda.o
++obj-$(CONFIG_REALTEK_OTTO_TIMER) += timer-rtl-otto.o
+
+ obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
+ obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
+--- a/include/linux/cpuhotplug.h
++++ b/include/linux/cpuhotplug.h
+@@ -181,6 +181,7 @@ enum cpuhp_state {
+ CPUHP_AP_MARCO_TIMER_STARTING,
+ CPUHP_AP_MIPS_GIC_TIMER_STARTING,
+ CPUHP_AP_ARC_TIMER_STARTING,
++ CPUHP_AP_REALTEK_TIMER_STARTING,
+ CPUHP_AP_RISCV_TIMER_STARTING,
+ CPUHP_AP_CLINT_TIMER_STARTING,
+ CPUHP_AP_CSKY_TIMER_STARTING,
diff --git a/target/linux/realtek/patches-6.6/303-gpio-update-dependencies-for-gpio-realtek-otto.patch b/target/linux/realtek/patches-6.6/303-gpio-update-dependencies-for-gpio-realtek-otto.patch
new file mode 100644
index 0000000000..2b466340e6
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/303-gpio-update-dependencies-for-gpio-realtek-otto.patch
@@ -0,0 +1,26 @@
+From 9bac1c20b8f39f2e0e342b087add5093b94feaed Mon Sep 17 00:00:00 2001
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+Date: Wed, 5 May 2021 22:05:39 +0900
+Subject: realtek: backport gpio-realtek-otto driver from 5.13 to 5.10
+
+This patch backports "gpio-realtek-otto" driver to Kernel 5.10.
+"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X"
+is used in OpenWrt, so update the dependency by the additional patch.
+
+Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+---
+ drivers/gpio/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -527,8 +527,8 @@ config GPIO_RDA
+
+ config GPIO_REALTEK_OTTO
+ tristate "Realtek Otto GPIO support"
+- depends on MACH_REALTEK_RTL
+- default MACH_REALTEK_RTL
++ depends on RTL83XX
++ default RTL838X
+ select GPIO_GENERIC
+ select GPIOLIB_IRQCHIP
+ help
diff --git a/target/linux/realtek/patches-6.6/304-spi-update-dependency-for-spi-realtek-rtl.patch b/target/linux/realtek/patches-6.6/304-spi-update-dependency-for-spi-realtek-rtl.patch
new file mode 100644
index 0000000000..01530257b8
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/304-spi-update-dependency-for-spi-realtek-rtl.patch
@@ -0,0 +1,25 @@
+From 0b000cbfe0aa0323bffa855ef8449c0687a4c071 Mon Sep 17 00:00:00 2001
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+Date: Thu, 6 May 2021 19:30:58 +0900
+Subject: realtek: backport spi-realtek-rtl driver from 5.12 to 5.10
+
+This patch backports "spi-realtek-rtl" driver to Kernel 5.10 from 5.12.
+"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X"
+is used in OpenWrt, so update the dependency by the additional patch.
+
+Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+---
+ drivers/spi/Makefile | 2 +-
+ 1 files changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -114,7 +114,7 @@ obj-$(CONFIG_SPI_QUP) += spi-qup.o
+ obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
+ obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o
+ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
+-obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
++obj-$(CONFIG_RTL83XX) += spi-realtek-rtl.o
+ obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
+ obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
+ obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o
diff --git a/target/linux/realtek/patches-6.6/305-irqchip-update-dependency-for-irq-realtek-rtl.patch b/target/linux/realtek/patches-6.6/305-irqchip-update-dependency-for-irq-realtek-rtl.patch
new file mode 100644
index 0000000000..0ecc33376e
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/305-irqchip-update-dependency-for-irq-realtek-rtl.patch
@@ -0,0 +1,25 @@
+From 2cd00b51470a30198b048a5fca48a04db77e29cc Mon Sep 17 00:00:00 2001
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+Date: Fri, 21 May 2021 23:16:37 +0900
+Subject: [PATCH] realtek: backport irq-realtek-rtl driver from 5.12 to 5.10
+
+This patch backports "irq-realtek-rtl" driver to Kernel 5.10 from 5.12.
+"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X"
+is used in OpenWrt, so update the dependency by the additional patch.
+
+Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+---
+ drivers/irqchip/Makefile | 2 +-
+ 1 files changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/irqchip/Makefile
++++ b/drivers/irqchip/Makefile
+@@ -114,7 +114,7 @@ obj-$(CONFIG_LOONGSON_PCH_MSI) += irq-l
+ obj-$(CONFIG_LOONGSON_PCH_LPC) += irq-loongson-pch-lpc.o
+ obj-$(CONFIG_MST_IRQ) += irq-mst-intc.o
+ obj-$(CONFIG_SL28CPLD_INTC) += irq-sl28cpld.o
+-obj-$(CONFIG_MACH_REALTEK_RTL) += irq-realtek-rtl.o
++obj-$(CONFIG_RTL83XX) += irq-realtek-rtl.o
+ obj-$(CONFIG_WPCM450_AIC) += irq-wpcm450-aic.o
+ obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o
+ obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o
diff --git a/target/linux/realtek/patches-6.6/307-wdt-update-dependency-for-realtek-otto-wdt.patch b/target/linux/realtek/patches-6.6/307-wdt-update-dependency-for-realtek-otto-wdt.patch
new file mode 100644
index 0000000000..c9dab65b72
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/307-wdt-update-dependency-for-realtek-otto-wdt.patch
@@ -0,0 +1,32 @@
+From b8fc5eecdc5d33cf261986436597b5482ab856da Mon Sep 17 00:00:00 2001
+From: Sander Vanheule <sander@svanheule.net>
+Date: Sun, 14 Nov 2021 19:45:32 +0100
+Subject: [PATCH] realtek: Backport Realtek Otto WDT driver
+
+Add patch submitted upstream to linux-watchdog and replace the MIPS
+architecture symbols. Requires one extra patch for the DIV_ROUND_*
+macros, which have moved to a different header since 5.10.
+
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Tested-by: Stijn Segers <foss@volatilesystems.org>
+Tested-by: Paul Fertser <fercerpav@gmail.com>
+Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
+---
+ drivers/watchdog/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -977,10 +977,10 @@ config RTD119X_WATCHDOG
+
+ config REALTEK_OTTO_WDT
+ tristate "Realtek Otto MIPS watchdog support"
+- depends on MACH_REALTEK_RTL || COMPILE_TEST
++ depends on RTL83XX
+ depends on COMMON_CLK
+ select WATCHDOG_CORE
+- default MACH_REALTEK_RTL
++ default RTL83XX
+ help
+ Say Y here to include support for the watchdog timer on Realtek
+ RTL838x, RTL839x, RTL930x SoCs. This watchdog has pretimeout
diff --git a/target/linux/realtek/patches-6.6/310-add-i2c-rtl9300-support.patch b/target/linux/realtek/patches-6.6/310-add-i2c-rtl9300-support.patch
new file mode 100644
index 0000000000..71df91bdac
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/310-add-i2c-rtl9300-support.patch
@@ -0,0 +1,46 @@
+From 63a0a4d85bc900464c5b046b13808a582345f8c8 Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <git@birger-koblitz.de>
+Date: Sat, 11 Dec 2021 20:14:47 +0100
+Subject: [PATCH] realtek: Add support for RTL9300/RTL9310 I2C controller
+
+This adds support for the RTL9300 and RTL9310 I2C controller.
+The controller implements the SMBus protocol for SMBus transfers
+over an I2C bus. The driver supports selecting one of the 2 possible
+SCL pins and any of the 8 possible SDA pins. Bus speeds of
+100kHz (standard speed) and 400kHz (high speed I2C) are supported.
+
+Submitted-by: Birger Koblitz <git@birger-koblitz.de>
+---
+ drivers/i2c/busses/Kconfig | 10 +++++++++
+ drivers/i2c/busses/Makefile | 1 +
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -1021,6 +1021,16 @@ config I2C_RK3X
+ This driver can also be built as a module. If so, the module will
+ be called i2c-rk3x.
+
++config I2C_RTL9300
++ tristate "Realtek RTL9300 I2C adapter"
++ depends on OF
++ help
++ Say Y here to include support for the I2C adapter in Realtek RTL9300
++ and RTL9310 SoCs.
++
++ This driver can also be built as a module. If so, the module will
++ be called i2c-rtl9300.
++
+ config I2C_RZV2M
+ tristate "Renesas RZ/V2M adapter"
+ depends on ARCH_RENESAS || COMPILE_TEST
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -101,6 +101,7 @@ obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-
+ obj-$(CONFIG_I2C_QUP) += i2c-qup.o
+ obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
+ obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o
++obj-$(CONFIG_I2C_RTL9300) += i2c-rtl9300.o
+ obj-$(CONFIG_I2C_RZV2M) += i2c-rzv2m.o
+ obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
+ obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
diff --git a/target/linux/realtek/patches-5.15/311-add-i2c-mux-rtl9300-support.patch b/target/linux/realtek/patches-6.6/311-add-i2c-mux-rtl9300-support.patch
index d0bfba4538..d0bfba4538 100644
--- a/target/linux/realtek/patches-5.15/311-add-i2c-mux-rtl9300-support.patch
+++ b/target/linux/realtek/patches-6.6/311-add-i2c-mux-rtl9300-support.patch
diff --git a/target/linux/realtek/patches-6.6/314-irqchip-irq-realtek-rtl-add-VPE-support.patch b/target/linux/realtek/patches-6.6/314-irqchip-irq-realtek-rtl-add-VPE-support.patch
new file mode 100644
index 0000000000..4610ca8c19
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/314-irqchip-irq-realtek-rtl-add-VPE-support.patch
@@ -0,0 +1,427 @@
+From 6c18e9c491959ac0674ebe36b09f9ddc3f2c9bce Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <git@birger-koblitz.de>
+Date: Fri, 31 Dec 2021 11:56:49 +0100
+Subject: [PATCH] realtek: Add VPE support for the IRQ driver
+
+In order to support VSMP, enable support for both VPEs of the RTL839X
+and RTL930X SoCs in the irq-realtek-rtl driver. Add support for IRQ
+affinity setting.
+
+Up to kernel 5.15 this patch was divided into two parts
+
+315-irqchip-irq-realtek-rtl-add-VPE-support.patch
+319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch
+
+As both parts will only work in combination they have been merged into
+one patch.
+
+Submitted-by: Birger Koblitz <git@birger-koblitz.de>
+Submitted-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
+---
+ drivers/irqchip/irq-realtek-rtl.c | 296 +++++++++++++++++++++++++-----
+ 1 file changed, 249 insertions(+), 47 deletions(-)
+
+--- a/drivers/irqchip/irq-realtek-rtl.c
++++ b/drivers/irqchip/irq-realtek-rtl.c
+@@ -22,22 +22,58 @@
+ #define RTL_ICTL_IRR3 0x14
+
+ #define RTL_ICTL_NUM_INPUTS 32
+-
+-#define REG(x) (realtek_ictl_base + x)
++#define RTL_ICTL_NUM_OUTPUTS 15
+
+ static DEFINE_RAW_SPINLOCK(irq_lock);
+-static void __iomem *realtek_ictl_base;
++
++#define REG(offset, cpu) (realtek_ictl_base[cpu] + offset)
++
++static u32 realtek_ictl_unmask[NR_CPUS];
++static void __iomem *realtek_ictl_base[NR_CPUS];
++static cpumask_t realtek_ictl_cpu_configurable;
++
++struct realtek_ictl_output {
++ /* IRQ controller data */
++ struct fwnode_handle *fwnode;
++ /* Output specific data */
++ unsigned int output_index;
++ struct irq_domain *domain;
++ u32 child_mask;
++};
+
+ /*
+- * IRR0-IRR3 store 4 bits per interrupt, but Realtek uses inverted numbering,
+- * placing IRQ 31 in the first four bits. A routing value of '0' means the
+- * interrupt is left disconnected. Routing values {1..15} connect to output
+- * lines {0..14}.
++ * Per CPU we have a set of 5 registers that determine interrupt handling for
++ * 32 external interrupts. GIMR (enable/disable interrupt) plus IRR0-IRR3 that
++ * contain "routing" or "priority" values. GIMR uses one bit for each interrupt
++ * and IRRx store 4 bits per interrupt. Realtek uses inverted numbering,
++ * placing IRQ 31 in the first four bits. The register combinations give the
++ * following results for a single interrupt in the wild:
++ *
++ * a) GIMR = 0 / IRRx > 0 -> no interrupts
++ * b) GIMR = 0 / IRRx = 0 -> no interrupts
++ * c) GIMR = 1 / IRRx > 0 -> interrupts
++ * d) GIMR = 1 / IRRx = 0 -> rare interrupts in SMP environment
++ *
++ * Combination d) seems to trigger interrupts only on a VPE if the other VPE
++ * has GIMR = 0 and IRRx > 0. E.g. busy without interrupts allowed. To provide
++ * IRQ balancing features in SMP this driver will handle the registers as
++ * follows:
++ *
++ * 1) set IRRx > 0 for VPE where the interrupt is desired
++ * 2) set IRRx = 0 for VPE where the interrupt is not desired
++ * 3) set both GIMR = 0 to mask (disabled) interrupt
++ * 4) set GIMR = 1 to unmask (enable) interrupt but only for VPE where IRRx > 0
+ */
++
+ #define IRR_OFFSET(idx) (4 * (3 - (idx * 4) / 32))
+ #define IRR_SHIFT(idx) ((idx * 4) % 32)
+
+-static void write_irr(void __iomem *irr0, int idx, u32 value)
++static inline u32 read_irr(void __iomem *irr0, int idx)
++{
++ return (readl(irr0 + IRR_OFFSET(idx)) >> IRR_SHIFT(idx)) & 0xf;
++}
++
++static inline void write_irr(void __iomem *irr0, int idx, u32 value)
+ {
+ unsigned int offset = IRR_OFFSET(idx);
+ unsigned int shift = IRR_SHIFT(idx);
+@@ -48,16 +84,33 @@ static void write_irr(void __iomem *irr0
+ writel(irr, irr0 + offset);
+ }
+
++static inline void enable_gimr(int hwirq, int cpu)
++{
++ u32 value;
++
++ value = readl(REG(RTL_ICTL_GIMR, cpu));
++ value |= (BIT(hwirq) & realtek_ictl_unmask[cpu]);
++ writel(value, REG(RTL_ICTL_GIMR, cpu));
++}
++
++static inline void disable_gimr(int hwirq, int cpu)
++{
++ u32 value;
++
++ value = readl(REG(RTL_ICTL_GIMR, cpu));
++ value &= ~BIT(hwirq);
++ writel(value, REG(RTL_ICTL_GIMR, cpu));
++}
++
+ static void realtek_ictl_unmask_irq(struct irq_data *i)
+ {
+ unsigned long flags;
+- u32 value;
++ int cpu;
+
+ raw_spin_lock_irqsave(&irq_lock, flags);
+
+- value = readl(REG(RTL_ICTL_GIMR));
+- value |= BIT(i->hwirq);
+- writel(value, REG(RTL_ICTL_GIMR));
++ for_each_cpu(cpu, &realtek_ictl_cpu_configurable)
++ enable_gimr(i->hwirq, cpu);
+
+ raw_spin_unlock_irqrestore(&irq_lock, flags);
+ }
+@@ -65,110 +118,259 @@ static void realtek_ictl_unmask_irq(stru
+ static void realtek_ictl_mask_irq(struct irq_data *i)
+ {
+ unsigned long flags;
+- u32 value;
++ int cpu;
+
+ raw_spin_lock_irqsave(&irq_lock, flags);
+
+- value = readl(REG(RTL_ICTL_GIMR));
+- value &= ~BIT(i->hwirq);
+- writel(value, REG(RTL_ICTL_GIMR));
++ for_each_cpu(cpu, &realtek_ictl_cpu_configurable)
++ disable_gimr(i->hwirq, cpu);
+
+ raw_spin_unlock_irqrestore(&irq_lock, flags);
+ }
+
++static int __maybe_unused realtek_ictl_irq_affinity(struct irq_data *i,
++ const struct cpumask *dest, bool force)
++{
++ struct realtek_ictl_output *output = i->domain->host_data;
++ cpumask_t cpu_configure;
++ cpumask_t cpu_disable;
++ cpumask_t cpu_enable;
++ unsigned long flags;
++ int cpu;
++
++ raw_spin_lock_irqsave(&irq_lock, flags);
++
++ cpumask_and(&cpu_configure, cpu_present_mask, &realtek_ictl_cpu_configurable);
++
++ cpumask_and(&cpu_enable, &cpu_configure, dest);
++ cpumask_andnot(&cpu_disable, &cpu_configure, dest);
++
++ for_each_cpu(cpu, &cpu_disable) {
++ write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, 0);
++ realtek_ictl_unmask[cpu] &= ~BIT(i->hwirq);
++ disable_gimr(i->hwirq, cpu);
++ }
++
++ for_each_cpu(cpu, &cpu_enable) {
++ write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, output->output_index + 1);
++ realtek_ictl_unmask[cpu] |= BIT(i->hwirq);
++ enable_gimr(i->hwirq, cpu);
++ }
++
++ irq_data_update_effective_affinity(i, &cpu_enable);
++
++ raw_spin_unlock_irqrestore(&irq_lock, flags);
++
++ return IRQ_SET_MASK_OK;
++}
++
+ static struct irq_chip realtek_ictl_irq = {
+ .name = "realtek-rtl-intc",
+ .irq_mask = realtek_ictl_mask_irq,
+ .irq_unmask = realtek_ictl_unmask_irq,
++#ifdef CONFIG_SMP
++ .irq_set_affinity = realtek_ictl_irq_affinity,
++#endif
+ };
+
+ static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+ {
++ struct realtek_ictl_output *output = d->host_data;
+ unsigned long flags;
+
+ irq_set_chip_and_handler(irq, &realtek_ictl_irq, handle_level_irq);
+
+ raw_spin_lock_irqsave(&irq_lock, flags);
+- write_irr(REG(RTL_ICTL_IRR0), hw, 1);
++
++ output->child_mask |= BIT(hw);
++ write_irr(REG(RTL_ICTL_IRR0, 0), hw, output->output_index + 1);
++ realtek_ictl_unmask[0] |= BIT(hw);
++
+ raw_spin_unlock_irqrestore(&irq_lock, flags);
+
+ return 0;
+ }
+
++static int intc_select(struct irq_domain *d, struct irq_fwspec *fwspec,
++ enum irq_domain_bus_token bus_token)
++{
++ struct realtek_ictl_output *output = d->host_data;
++ bool routed_elsewhere;
++ unsigned long flags;
++ u32 routing_old;
++ int cpu;
++
++ if (fwspec->fwnode != output->fwnode)
++ return false;
++
++ /* Original specifiers had only one parameter */
++ if (fwspec->param_count < 2)
++ return true;
++
++ raw_spin_lock_irqsave(&irq_lock, flags);
++
++ /*
++ * Inputs can only be routed to one output, so they shouldn't be
++ * allowed to end up in multiple domains.
++ */
++ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) {
++ routing_old = read_irr(REG(RTL_ICTL_IRR0, cpu), fwspec->param[0]);
++ routed_elsewhere = routing_old && fwspec->param[1] != routing_old - 1;
++ if (routed_elsewhere) {
++ pr_warn("soc int %d already routed to output %d\n",
++ fwspec->param[0], routing_old - 1);
++ break;
++ }
++ }
++
++ raw_spin_unlock_irqrestore(&irq_lock, flags);
++
++ return !routed_elsewhere && fwspec->param[1] == output->output_index;
++}
++
+ static const struct irq_domain_ops irq_domain_ops = {
+ .map = intc_map,
++ .select = intc_select,
+ .xlate = irq_domain_xlate_onecell,
+ };
+
+ static void realtek_irq_dispatch(struct irq_desc *desc)
+ {
++ struct realtek_ictl_output *output = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct irq_domain *domain;
++ int cpu = smp_processor_id();
+ unsigned long pending;
+ unsigned int soc_int;
+
+ chained_irq_enter(chip, desc);
+- pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR));
++ pending = readl(REG(RTL_ICTL_GIMR, cpu)) & readl(REG(RTL_ICTL_GISR, cpu))
++ & output->child_mask;
+
+ if (unlikely(!pending)) {
+ spurious_interrupt();
+ goto out;
+ }
+
+- domain = irq_desc_get_handler_data(desc);
+- for_each_set_bit(soc_int, &pending, 32)
+- generic_handle_domain_irq(domain, soc_int);
++ for_each_set_bit(soc_int, &pending, RTL_ICTL_NUM_INPUTS)
++ generic_handle_domain_irq(output->domain, soc_int);
+
+ out:
+ chained_irq_exit(chip, desc);
+ }
+
++/*
++ * SoC interrupts are cascaded to MIPS CPU interrupts according to the
++ * interrupt-map in the device tree. Each SoC interrupt gets 4 bits for
++ * the CPU interrupt in an Interrupt Routing Register. Max 32 SoC interrupts
++ * thus go into 4 IRRs. A routing value of '0' means the interrupt is left
++ * disconnected. Routing values {1..15} connect to output lines {0..14}.
++ */
++static int __init setup_parent_interrupts(struct device_node *node, int *parents,
++ unsigned int num_parents)
++{
++ struct realtek_ictl_output *outputs;
++ struct realtek_ictl_output *output;
++ struct irq_domain *domain;
++ unsigned int p;
++
++ outputs = kcalloc(num_parents, sizeof(*outputs), GFP_KERNEL);
++ if (!outputs)
++ return -ENOMEM;
++
++ for (p = 0; p < num_parents; p++) {
++ output = outputs + p;
++
++ domain = irq_domain_add_linear(node, RTL_ICTL_NUM_INPUTS, &irq_domain_ops, output);
++ if (!domain)
++ goto domain_err;
++
++ output->fwnode = of_node_to_fwnode(node);
++ output->output_index = p;
++ output->domain = domain;
++
++ irq_set_chained_handler_and_data(parents[p], realtek_irq_dispatch, output);
++ }
++
++ return 0;
++
++domain_err:
++ while (p--) {
++ irq_set_chained_handler_and_data(parents[p], NULL, NULL);
++ irq_domain_remove(outputs[p].domain);
++ }
++
++ kfree(outputs);
++
++ return -ENOMEM;
++}
++
+ static int __init realtek_rtl_of_init(struct device_node *node, struct device_node *parent)
+ {
++ int parent_irqs[RTL_ICTL_NUM_OUTPUTS];
+ struct of_phandle_args oirq;
+- struct irq_domain *domain;
++ unsigned int num_parents;
+ unsigned int soc_irq;
+- int parent_irq;
++ unsigned int p;
++ int cpu;
++
++ cpumask_clear(&realtek_ictl_cpu_configurable);
+
+- realtek_ictl_base = of_iomap(node, 0);
+- if (!realtek_ictl_base)
++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
++ realtek_ictl_base[cpu] = of_iomap(node, cpu);
++ if (realtek_ictl_base[cpu]) {
++ cpumask_set_cpu(cpu, &realtek_ictl_cpu_configurable);
++
++ /* Disable all cascaded interrupts and clear routing */
++ for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++) {
++ write_irr(REG(RTL_ICTL_IRR0, cpu), soc_irq, 0);
++ realtek_ictl_unmask[cpu] &= ~BIT(soc_irq);
++ disable_gimr(soc_irq, cpu);
++ }
++ }
++ }
++
++ if (cpumask_empty(&realtek_ictl_cpu_configurable))
+ return -ENXIO;
+
+- /* Disable all cascaded interrupts and clear routing */
+- writel(0, REG(RTL_ICTL_GIMR));
+- for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++)
+- write_irr(REG(RTL_ICTL_IRR0), soc_irq, 0);
++ num_parents = of_irq_count(node);
++ if (num_parents > RTL_ICTL_NUM_OUTPUTS) {
++ pr_err("too many parent interrupts\n");
++ return -EINVAL;
++ }
+
+- if (WARN_ON(!of_irq_count(node))) {
++ for (p = 0; p < num_parents; p++)
++ parent_irqs[p] = of_irq_get(node, p);
++
++ if (WARN_ON(!num_parents)) {
+ /*
+ * If DT contains no parent interrupts, assume MIPS CPU IRQ 2
+ * (HW0) is connected to the first output. This is the case for
+ * all known hardware anyway. "interrupt-map" is deprecated, so
+ * don't bother trying to parse that.
++ * Since this is to account for old devicetrees with one-cell
++ * interrupt specifiers, only one output domain is needed.
+ */
+ oirq.np = of_find_compatible_node(NULL, NULL, "mti,cpu-interrupt-controller");
+- oirq.args_count = 1;
+- oirq.args[0] = 2;
+-
+- parent_irq = irq_create_of_mapping(&oirq);
++ if (oirq.np) {
++ oirq.args_count = 1;
++ oirq.args[0] = 2;
++
++ parent_irqs[0] = irq_create_of_mapping(&oirq);
++ num_parents = 1;
++ }
+
+ of_node_put(oirq.np);
+- } else {
+- parent_irq = of_irq_get(node, 0);
+ }
+
+- if (parent_irq < 0)
+- return parent_irq;
+- else if (!parent_irq)
+- return -ENODEV;
+-
+- domain = irq_domain_add_linear(node, RTL_ICTL_NUM_INPUTS, &irq_domain_ops, NULL);
+- if (!domain)
+- return -ENOMEM;
+-
+- irq_set_chained_handler_and_data(parent_irq, realtek_irq_dispatch, domain);
++ /* Ensure we haven't collected any errors before proceeding */
++ for (p = 0; p < num_parents; p++) {
++ if (parent_irqs[p] < 0)
++ return parent_irqs[p];
++ if (!parent_irqs[p])
++ return -ENODEV;
++ }
+
+- return 0;
++ return setup_parent_interrupts(node, &parent_irqs[0], num_parents);
+ }
+
+ IRQCHIP_DECLARE(realtek_rtl_intc, "realtek,rtl-intc", realtek_rtl_of_init);
diff --git a/target/linux/realtek/patches-6.6/318-add-rtl83xx-clk-support.patch b/target/linux/realtek/patches-6.6/318-add-rtl83xx-clk-support.patch
new file mode 100644
index 0000000000..e75260a638
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/318-add-rtl83xx-clk-support.patch
@@ -0,0 +1,33 @@
+From 800d5fb3c6a16661932c932bacd660e38d06b727 Mon Sep 17 00:00:00 2001
+From: Markus Stockhausen <markus.stockhausen@gmx.de>
+Date: Thu, 25 Aug 2022 08:22:36 +0200
+Subject: [PATCH] realtek: add patch to enable new clock driver in kernel
+
+Allow building the clock driver with kernel config options.
+
+Submitted-by: Markus Stockhausen <markus.stockhausen@gmx.de>
+---
+ drivers/clk/Kconfig | 1 +
+ drivers/clk/Makefile | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/clk/Kconfig
++++ b/drivers/clk/Kconfig
+@@ -484,6 +484,7 @@ source "drivers/clk/mvebu/Kconfig"
+ source "drivers/clk/nuvoton/Kconfig"
+ source "drivers/clk/pistachio/Kconfig"
+ source "drivers/clk/qcom/Kconfig"
++source "drivers/clk/realtek/Kconfig"
+ source "drivers/clk/ralink/Kconfig"
+ source "drivers/clk/renesas/Kconfig"
+ source "drivers/clk/rockchip/Kconfig"
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -112,6 +112,7 @@ obj-$(CONFIG_COMMON_CLK_PISTACHIO) += pi
+ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
+ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
+ obj-y += ralink/
++obj-$(CONFIG_COMMON_CLK_REALTEK) += realtek/
+ obj-y += renesas/
+ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
+ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
diff --git a/target/linux/realtek/patches-6.6/320-harden-fw_init_cmdline.patch b/target/linux/realtek/patches-6.6/320-harden-fw_init_cmdline.patch
new file mode 100644
index 0000000000..d45932b977
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/320-harden-fw_init_cmdline.patch
@@ -0,0 +1,38 @@
+From e813f48461b8011244b3e7dfe118cf94fd595f0d Mon Sep 17 00:00:00 2001
+From: Markus Stockhausen <markus.stockhausen@gmx.de>
+Date: Sun, 25 Aug 2024 13:09:48 -0400
+Subject: [PATCH] realtek: harden fw_init_cmdline()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some devices (e.g. HP JG924A) hand over other than expected kernel boot
+arguments. Looking at these one can see:
+
+fw_init_cmdline: fw_arg0=00020000
+fw_init_cmdline: fw_arg1=00060000
+fw_init_cmdline: fw_arg2=fffdffff
+fw_init_cmdline: fw_arg3=0000416c
+
+Especially fw_arg2 should be the pointer to the environment and it looks
+very suspicous. It is not aligned and the address is outside KSEG0 and
+KSEG1. Booting the device will result in a hang. Do better at verifying
+the address.
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
+---
+ arch/mips/fw/lib/cmdline.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/fw/lib/cmdline.c
++++ b/arch/mips/fw/lib/cmdline.c
+@@ -31,7 +31,7 @@ void __init fw_init_cmdline(void)
+ }
+
+ /* Validate environment pointer. */
+- if (fw_arg2 < CKSEG0)
++ if (fw_arg2 < CKSEG0 || fw_arg2 >= CKSEG2)
+ _fw_envp = NULL;
+ else
+ _fw_envp = (int *)fw_arg2;
diff --git a/target/linux/realtek/patches-5.15/702-net-dsa-increase-dsa-max-ports-for-rtl838x.patch b/target/linux/realtek/patches-6.6/700-net-dsa-increase-dsa-max-ports-for-rtl838x.patch
index 63991d373c..63991d373c 100644
--- a/target/linux/realtek/patches-5.15/702-net-dsa-increase-dsa-max-ports-for-rtl838x.patch
+++ b/target/linux/realtek/patches-6.6/700-net-dsa-increase-dsa-max-ports-for-rtl838x.patch
diff --git a/target/linux/realtek/patches-6.6/702-include-linux-add-phy-hsgmii-mode.patch b/target/linux/realtek/patches-6.6/702-include-linux-add-phy-hsgmii-mode.patch
new file mode 100644
index 0000000000..a43b49c1ff
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/702-include-linux-add-phy-hsgmii-mode.patch
@@ -0,0 +1,79 @@
+From 9d9bf16aa8d966834ac1280f96c37d22552c33d1 Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <git@birger-koblitz.de>
+Date: Wed, 8 Sep 2021 16:13:18 +0200
+Subject: realtek phy: Add PHY hsgmii mode
+
+This adds RTL93xx-specific MAC configuration routines that allow also configuration
+of 10GBit links for phylink. There is support for the Realtek-specific HSGMII
+protocol.
+
+Submitted-by: Birger Koblitz <git@birger-koblitz.de>
+---
+ drivers/net/phy/phy-core.c | 1 +
+ drivers/net/phy/phylink.c | 4 ++++
+ include/linux/phy.h | 3 +++
+ 3 files changed, 8 insertions(+)
+
+--- a/drivers/net/phy/phy-core.c
++++ b/drivers/net/phy/phy-core.c
+@@ -126,6 +126,7 @@ int phy_interface_num_ports(phy_interfac
+ case PHY_INTERFACE_MODE_MOCA:
+ case PHY_INTERFACE_MODE_TRGMII:
+ case PHY_INTERFACE_MODE_USXGMII:
++ case PHY_INTERFACE_MODE_HSGMII:
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_SMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -124,6 +124,7 @@ do { \
+ static const phy_interface_t phylink_sfp_interface_preference[] = {
+ PHY_INTERFACE_MODE_25GBASER,
+ PHY_INTERFACE_MODE_USXGMII,
++ PHY_INTERFACE_MODE_HSGMII,
+ PHY_INTERFACE_MODE_10GBASER,
+ PHY_INTERFACE_MODE_5GBASER,
+ PHY_INTERFACE_MODE_2500BASEX,
+@@ -238,6 +239,7 @@ static int phylink_interface_max_speed(p
+
+ case PHY_INTERFACE_MODE_XGMII:
+ case PHY_INTERFACE_MODE_RXAUI:
++ case PHY_INTERFACE_MODE_HSGMII:
+ case PHY_INTERFACE_MODE_XAUI:
+ case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_10GKR:
+@@ -547,6 +549,7 @@ unsigned long phylink_get_capabilities(p
+ break;
+
+ case PHY_INTERFACE_MODE_XGMII:
++ case PHY_INTERFACE_MODE_HSGMII:
+ case PHY_INTERFACE_MODE_RXAUI:
+ case PHY_INTERFACE_MODE_XAUI:
+ case PHY_INTERFACE_MODE_10GBASER:
+@@ -957,6 +960,7 @@ static int phylink_parse_mode(struct phy
+ fallthrough;
+ case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_10GKR:
++ case PHY_INTERFACE_MODE_HSGMII:
+ case PHY_INTERFACE_MODE_10GBASER:
+ phylink_set(pl->supported, 10baseT_Half);
+ phylink_set(pl->supported, 10baseT_Full);
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -148,6 +148,7 @@ typedef enum {
+ PHY_INTERFACE_MODE_XGMII,
+ PHY_INTERFACE_MODE_XLGMII,
+ PHY_INTERFACE_MODE_MOCA,
++ PHY_INTERFACE_MODE_HSGMII,
+ PHY_INTERFACE_MODE_PSGMII,
+ PHY_INTERFACE_MODE_QSGMII,
+ PHY_INTERFACE_MODE_TRGMII,
+@@ -256,6 +257,8 @@ static inline const char *phy_modes(phy_
+ return "xlgmii";
+ case PHY_INTERFACE_MODE_MOCA:
+ return "moca";
++ case PHY_INTERFACE_MODE_HSGMII:
++ return "hsgmii";
+ case PHY_INTERFACE_MODE_PSGMII:
+ return "psgmii";
+ case PHY_INTERFACE_MODE_QSGMII:
diff --git a/target/linux/realtek/patches-6.6/704-include-linux-phy-increase-phy-address-number-for-rtl839x.patch b/target/linux/realtek/patches-6.6/704-include-linux-phy-increase-phy-address-number-for-rtl839x.patch
new file mode 100644
index 0000000000..f0fd702a6e
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/704-include-linux-phy-increase-phy-address-number-for-rtl839x.patch
@@ -0,0 +1,32 @@
+From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 26 Nov 2020 12:02:21 +0100
+Subject: PHY: Increase max PHY adddress number
+
+* rename the target to realtek
+* add refactored DSA driver
+* add latest gpio driver
+* lots of arch cleanups
+* new irq driver
+* additional boards
+
+Submitted-by: Bert Vermeulen <bert@biot.com>
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Submitted-by: Bjørn Mork <bjorn@mork.no>
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ include/linux/phy.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -297,7 +297,7 @@ static inline const char *phy_modes(phy_
+ #define PHY_INIT_TIMEOUT 100000
+ #define PHY_FORCE_TIMEOUT 10
+
+-#define PHY_MAX_ADDR 32
++#define PHY_MAX_ADDR 64
+
+ /* Used when trying to connect to a specific phy (mii bus id:phy device id) */
+ #define PHY_ID_FMT "%s:%02x"
diff --git a/target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch b/target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch
new file mode 100644
index 0000000000..2a799551d6
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch
@@ -0,0 +1,34 @@
+From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 26 Nov 2020 12:02:21 +0100
+Subject: phy: Add PHY ops for rtl838x EEE
+
+* rename the target to realtek
+* add refactored DSA driver
+* add latest gpio driver
+* lots of arch cleanups
+* new irq driver
+* additional boards
+
+Submitted-by: Bert Vermeulen <bert@biot.com>
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Submitted-by: Bjørn Mork <bjorn@mork.no>
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ include/linux/phy.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -1180,6 +1180,10 @@ struct phy_driver {
+ */
+ int (*led_polarity_set)(struct phy_device *dev, int index,
+ unsigned long modes);
++ int (*get_port)(struct phy_device *dev);
++ int (*set_port)(struct phy_device *dev, int port);
++ int (*get_eee)(struct phy_device *dev, struct ethtool_eee *e);
++ int (*set_eee)(struct phy_device *dev, struct ethtool_eee *e);
+ };
+ #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
+ struct phy_driver, mdiodrv)
diff --git a/target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch b/target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch
new file mode 100644
index 0000000000..305981c3ee
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch
@@ -0,0 +1,61 @@
+From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 26 Nov 2020 12:02:21 +0100
+Subject: net: phy: EEE support for rtl838x
+
+* rename the target to realtek
+* add refactored DSA driver
+* add latest gpio driver
+* lots of arch cleanups
+* new irq driver
+* additional boards
+
+Submitted-by: Bert Vermeulen <bert@biot.com>
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Submitted-by: Bjørn Mork <bjorn@mork.no>
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/phy/phylink. | 14 +++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -2484,6 +2484,11 @@ int phylink_ethtool_ksettings_set(struct
+ * the presence of a PHY, this should not be changed as that
+ * should be determined from the media side advertisement.
+ */
++ if (pl->phydev->drv->get_port && pl->phydev->drv->set_port) {
++ if(pl->phydev->drv->get_port(pl->phydev) != kset->base.port) {
++ pl->phydev->drv->set_port(pl->phydev, kset->base.port);
++ }
++ }
+ return phy_ethtool_ksettings_set(pl->phydev, &phy_kset);
+ }
+
+@@ -2786,8 +2791,11 @@ int phylink_ethtool_get_eee(struct phyli
+
+ ASSERT_RTNL();
+
+- if (pl->phydev)
++ if (pl->phydev) {
++ if (pl->phydev->drv->get_eee)
++ return pl->phydev->drv->get_eee(pl->phydev, eee);
+ ret = phy_ethtool_get_eee(pl->phydev, eee);
++ }
+
+ return ret;
+ }
+@@ -2804,8 +2812,11 @@ int phylink_ethtool_set_eee(struct phyli
+
+ ASSERT_RTNL();
+
+- if (pl->phydev)
++ if (pl->phydev) {
++ if (pl->phydev->drv->set_eee)
++ return pl->phydev->drv->set_eee(pl->phydev, eee);
+ ret = phy_ethtool_set_eee(pl->phydev, eee);
++ }
+
+ return ret;
+ }
diff --git a/target/linux/realtek/patches-6.6/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch b/target/linux/realtek/patches-6.6/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch
new file mode 100644
index 0000000000..d7a232327d
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch
@@ -0,0 +1,26 @@
+From a381ac0aa281fdb0b41a39d8a2bc08fd88f6db92 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart@bootlin.com>
+Date: Tue, 25 Feb 2020 16:32:37 +0100
+Subject: [PATCH 1/3] net: phy: sfp: re-probe modules on DEV_UP event
+
+Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
+---
+ drivers/net/phy/sfp.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -2415,6 +2415,13 @@ static void sfp_sm_module(struct sfp *sf
+ return;
+ }
+
++ /* Re-probe the SFP modules when an interface is brought up, as the MAC
++ * do not report its link status (This means Phylink wouldn't be
++ * triggered if the PHY had a link before a MAC is brought up).
++ */
++ if (event == SFP_E_DEV_UP && sfp->sm_mod_state == SFP_MOD_PRESENT)
++ sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL);
++
+ switch (sfp->sm_mod_state) {
+ default:
+ if (event == SFP_E_INSERT) {
diff --git a/target/linux/realtek/patches-6.6/712-net-phy-add-an-MDIO-SMBus-library.patch b/target/linux/realtek/patches-6.6/712-net-phy-add-an-MDIO-SMBus-library.patch
new file mode 100644
index 0000000000..03c62b505d
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/712-net-phy-add-an-MDIO-SMBus-library.patch
@@ -0,0 +1,148 @@
+From d585c55b9f70cf9e8c66820d7efe7130c683f19e Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart@bootlin.com>
+Date: Fri, 21 Feb 2020 11:51:27 +0100
+Subject: [PATCH 2/3] net: phy: add an MDIO SMBus library
+
+Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
+---
+ drivers/net/mdio/Kconfig | 11 +++++++
+ drivers/net/mdio/Makefile | 1 +
+ drivers/net/mdio/mdio-smbus.c | 62 +++++++++++++++++++++++++++++++++++
+ drivers/net/phy/Kconfig | 1 +
+ include/linux/mdio/mdio-i2c.h | 16 +++++++++
+ 5 files changed, 91 insertions(+)
+ create mode 100644 drivers/net/mdio/mdio-smbus.c
+
+--- a/drivers/net/mdio/Kconfig
++++ b/drivers/net/mdio/Kconfig
+@@ -54,6 +54,17 @@ config MDIO_SUN4I
+ interface units of the Allwinner SoC that have an EMAC (A10,
+ A12, A10s, etc.)
+
++config MDIO_SMBUS
++ tristate
++ depends on I2C_SMBUS
++ help
++ Support SMBus based PHYs. This provides a MDIO bus bridged
++ to SMBus to allow PHYs connected in SMBus mode to be accessed
++ using the existing infrastructure.
++
++ This is library mode.
++
++
+ config MDIO_XGENE
+ tristate "APM X-Gene SoC MDIO bus controller"
+ depends on ARCH_XGENE || COMPILE_TEST
+--- a/drivers/net/mdio/Makefile
++++ b/drivers/net/mdio/Makefile
+@@ -20,6 +20,7 @@ obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-ms
+ obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
+ obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
+ obj-$(CONFIG_MDIO_REGMAP) += mdio-regmap.o
++obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o
+ obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
+ obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
+ obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
+--- /dev/null
++++ b/drivers/net/mdio/mdio-smbus.c
+@@ -0,0 +1,62 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * MDIO SMBus bridge
++ *
++ * Copyright (C) 2020 Antoine Tenart
++ *
++ * Network PHYs can appear on SMBus when they are part of SFP modules.
++ */
++#include <linux/i2c.h>
++#include <linux/phy.h>
++#include <linux/mdio/mdio-i2c.h>
++
++static int smbus_mii_read(struct mii_bus *mii, int phy_id, int reg)
++{
++ struct i2c_adapter *i2c = mii->priv;
++ union i2c_smbus_data data;
++ int ret;
++
++ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_READ,
++ reg, I2C_SMBUS_BYTE_DATA, &data);
++ if (ret < 0)
++ return 0xff;
++
++ return data.byte;
++}
++
++static int smbus_mii_write(struct mii_bus *mii, int phy_id, int reg, u16 val)
++{
++ struct i2c_adapter *i2c = mii->priv;
++ union i2c_smbus_data data;
++ int ret;
++
++ data.byte = val;
++
++ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_WRITE,
++ reg, I2C_SMBUS_BYTE_DATA, &data);
++ return ret < 0 ? ret : 0;
++}
++
++struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c)
++{
++ struct mii_bus *mii;
++
++ if (!i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA))
++ return ERR_PTR(-EINVAL);
++
++ mii = mdiobus_alloc();
++ if (!mii)
++ return ERR_PTR(-ENOMEM);
++
++ snprintf(mii->id, MII_BUS_ID_SIZE, "smbus:%s", dev_name(parent));
++ mii->parent = parent;
++ mii->read = smbus_mii_read;
++ mii->write = smbus_mii_write;
++ mii->priv = i2c;
++
++ return mii;
++}
++
++MODULE_AUTHOR("Antoine Tenart");
++MODULE_DESCRIPTION("MDIO SMBus bridge library");
++MODULE_LICENSE("GPL");
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -65,6 +65,7 @@ config SFP
+ depends on I2C && PHYLINK
+ depends on HWMON || HWMON=n
+ select MDIO_I2C
++ select MDIO_SMBUS
+
+ comment "Switch configuration API + drivers"
+
+--- a/include/linux/mdio/mdio-i2c.h
++++ b/include/linux/mdio/mdio-i2c.h
+@@ -20,5 +20,8 @@ enum mdio_i2c_proto {
+
+ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
+ enum mdio_i2c_proto protocol);
++struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c);
++bool i2c_mii_valid_phy_id(int phy_id);
++unsigned int i2c_mii_phy_addr(int phy_id);
+
+ #endif
+--- a/drivers/net/mdio/mdio-i2c.c
++++ b/drivers/net/mdio/mdio-i2c.c
+@@ -20,12 +20,12 @@
+ * specified to be present in SFP modules. These correspond with PHY
+ * addresses 16 and 17. Disallow access to these "phy" addresses.
+ */
+-static bool i2c_mii_valid_phy_id(int phy_id)
++bool i2c_mii_valid_phy_id(int phy_id)
+ {
+ return phy_id != 0x10 && phy_id != 0x11;
+ }
+
+-static unsigned int i2c_mii_phy_addr(int phy_id)
++unsigned int i2c_mii_phy_addr(int phy_id)
+ {
+ return phy_id + 0x40;
+ }
diff --git a/target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch b/target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch
new file mode 100644
index 0000000000..06d264d805
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch
@@ -0,0 +1,127 @@
+From 3cb0bde365d913c484d20224367a54a0eac780a7 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart@bootlin.com>
+Date: Fri, 21 Feb 2020 11:55:29 +0100
+Subject: [PATCH 3/3] net: phy: sfp: add support for SMBus
+
+Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
+---
+ drivers/net/phy/sfp.c | 92 +++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 88 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -662,10 +662,64 @@ static int sfp_i2c_write(struct sfp *sfp
+ return ret == ARRAY_SIZE(msgs) ? len : 0;
+ }
+
++static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
++ size_t len)
++{
++ u8 bus_addr = a2 ? 0x51 : 0x50, *val = buf;
++ union i2c_smbus_data data;
++ int ret;
++
++ bus_addr -= 0x40;
++
++ while (len > 0) {
++ ret = i2c_smbus_xfer(sfp->i2c, i2c_mii_phy_addr(bus_addr), 0,
++ I2C_SMBUS_READ, dev_addr,
++ I2C_SMBUS_BYTE_DATA, &data);
++ if (ret)
++ return ret;
++ *val++ = data.byte;
++ dev_addr++;
++ len--;
++ }
++
++ return val - (u8 *)buf;
++}
++
++static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
++ size_t len)
++{
++ u8 bus_addr = a2 ? 0x51 : 0x50, *val = buf;
++ union i2c_smbus_data data;
++ int ret;
++
++ bus_addr -= 0x40;
++
++ while (len > 0) {
++ data.byte = *val++;
++ ret = i2c_smbus_xfer(sfp->i2c, i2c_mii_phy_addr(bus_addr), 0,
++ I2C_SMBUS_WRITE, dev_addr,
++ I2C_SMBUS_BYTE_DATA, &data);
++ if (ret)
++ return ret;
++ dev_addr++;
++ len--;
++ }
++
++ return val - (u8 *)buf;
++}
++
+ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
+ {
+- if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
+- return -EINVAL;
++ if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
++ if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) {
++ sfp->i2c = i2c;
++ sfp->read = sfp_smbus_read;
++ sfp->write = sfp_smbus_write;
++
++ return 0;
++ } else
++ return -EINVAL;
++ }
+
+ sfp->i2c = i2c;
+ sfp->read = sfp_i2c_read;
+@@ -697,6 +751,29 @@ static int sfp_i2c_mdiobus_create(struct
+ return 0;
+ }
+
++static int sfp_sm_mdiobus_create(struct sfp *sfp)
++{
++ struct mii_bus *sm_mii;
++ int ret;
++
++ sm_mii = mdio_smbus_alloc(sfp->dev, sfp->i2c);
++ if (IS_ERR(sm_mii))
++ return PTR_ERR(sm_mii);
++
++ sm_mii->name = "SFP SMBus";
++ sm_mii->phy_mask = ~0;
++
++ ret = mdiobus_register(sm_mii);
++ if (ret < 0) {
++ mdiobus_free(sm_mii);
++ return ret;
++ }
++
++ sfp->i2c_mii = sm_mii;
++
++ return 0;
++}
++
+ static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
+ {
+ mdiobus_unregister(sfp->i2c_mii);
+@@ -1870,8 +1947,15 @@ static void sfp_sm_fault(struct sfp *sfp
+
+ static int sfp_sm_add_mdio_bus(struct sfp *sfp)
+ {
+- if (sfp->mdio_protocol != MDIO_I2C_NONE)
+- return sfp_i2c_mdiobus_create(sfp);
++ if (i2c_check_functionality(sfp->i2c, I2C_FUNC_I2C)) {
++ if (sfp->mdio_protocol != MDIO_I2C_NONE)
++ return sfp_i2c_mdiobus_create(sfp);
++
++ return 0;
++ }
++
++ if (i2c_check_functionality(sfp->i2c, I2C_FUNC_SMBUS_BYTE_DATA))
++ return sfp_sm_mdiobus_create(sfp);
+
+ return 0;
+ }
diff --git a/target/linux/realtek/patches-6.6/716-net-ethernet-add-support-for-rtl838x-ethernet.patch b/target/linux/realtek/patches-6.6/716-net-ethernet-add-support-for-rtl838x-ethernet.patch
new file mode 100644
index 0000000000..9d79ea565d
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/716-net-ethernet-add-support-for-rtl838x-ethernet.patch
@@ -0,0 +1,48 @@
+From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 26 Nov 2020 12:02:21 +0100
+Subject: net: ethernet: Add support for RTL838x ethernet
+
+* rename the target to realtek
+* add refactored DSA driver
+* add latest gpio driver
+* lots of arch cleanups
+* new irq driver
+* additional boards
+
+Submitted-by: Bert Vermeulen <bert@biot.com>
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Submitted-by: Bjørn Mork <bjorn@mork.no>
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/Kconfig | 7 +-
+ drivers/net/ethernet/Makefile | 1 +
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/net/ethernet/Kconfig
++++ b/drivers/net/ethernet/Kconfig
+@@ -170,6 +170,13 @@ source "drivers/net/ethernet/rdc/Kconfig
+ source "drivers/net/ethernet/realtek/Kconfig"
+ source "drivers/net/ethernet/renesas/Kconfig"
+ source "drivers/net/ethernet/rocker/Kconfig"
++
++config NET_RTL838X
++ tristate "Realtek rtl838x Ethernet MAC support"
++ depends on RTL83XX
++ help
++ Say Y here if you want to use the Realtek rtl838x Gbps Ethernet MAC.
++
+ source "drivers/net/ethernet/samsung/Kconfig"
+ source "drivers/net/ethernet/seeq/Kconfig"
+ source "drivers/net/ethernet/sgi/Kconfig"
+--- a/drivers/net/ethernet/Makefile
++++ b/drivers/net/ethernet/Makefile
+@@ -81,6 +81,7 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += real
+ obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/
+ obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
+ obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/
++obj-$(CONFIG_NET_RTL838X) += rtl838x_eth.o
+ obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/
+ obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
+ obj-$(CONFIG_NET_VENDOR_SILAN) += silan/
diff --git a/target/linux/realtek/patches-6.6/718-net-dsa-add-support-for-rtl838x-switch.patch b/target/linux/realtek/patches-6.6/718-net-dsa-add-support-for-rtl838x-switch.patch
new file mode 100644
index 0000000000..786fc37091
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/718-net-dsa-add-support-for-rtl838x-switch.patch
@@ -0,0 +1,42 @@
+From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 26 Nov 2020 12:02:21 +0100
+Subject: net: dsa: Add support for rtl838x switch
+
+* rename the target to realtek
+* add refactored DSA driver
+* add latest gpio driver
+* lots of arch cleanups
+* new irq driver
+* additional boards
+
+Submitted-by: Bert Vermeulen <bert@biot.com>
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Submitted-by: Bjørn Mork <bjorn@mork.no>
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/dsa/rtl83xx/Kconfig | 2 ++
+ drivers/net/dsa/rtl83xx/Makefile | 1 +
+ 2 files changed, 3 insertions(+)
+
+--- a/drivers/net/dsa/Kconfig
++++ b/drivers/net/dsa/Kconfig
+@@ -89,6 +89,8 @@ source "drivers/net/dsa/xrs700x/Kconfig"
+
+ source "drivers/net/dsa/realtek/Kconfig"
+
++source "drivers/net/dsa/rtl83xx/Kconfig"
++
+ config NET_DSA_RZN1_A5PSW
+ tristate "Renesas RZ/N1 A5PSW Ethernet switch support"
+ depends on OF && ARCH_RZN1
+--- a/drivers/net/dsa/Makefile
++++ b/drivers/net/dsa/Makefile
+@@ -24,5 +24,6 @@ obj-y += mv88e6xxx/
+ obj-y += ocelot/
+ obj-y += qca/
+ obj-y += realtek/
++obj-y += rtl83xx/
+ obj-y += sja1105/
+ obj-y += xrs700x/
diff --git a/target/linux/realtek/patches-6.6/720-add-rtl-phy.patch b/target/linux/realtek/patches-6.6/720-add-rtl-phy.patch
new file mode 100644
index 0000000000..78a57f0a3e
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/720-add-rtl-phy.patch
@@ -0,0 +1,39 @@
+From 89f71ebb355c624320c2b0ace8ae9488ff53cbeb Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <mail@birger-koblitz.de>
+Date: Tue, 5 Jan 2021 20:40:52 +0100
+Subject: PHY: Add realtek PHY
+
+This fixes the build problems for the REALTEK target by adding a proper
+configuration option for the phy module.
+
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+---
+ drivers/net/phy/Kconfig | 6 ++++++
+ drivers/net/phy/Makefile | 1 +
+ 2 files changed, 7 insertions(+)
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -410,6 +410,12 @@ config REALTEK_PHY
+ help
+ Supports the Realtek 821x PHY.
+
++config REALTEK_SOC_PHY
++ tristate "Realtek SoC PHYs"
++ depends on RTL83XX
++ help
++ Supports the PHYs found in combination with Realtek Switch SoCs
++
+ config RENESAS_PHY
+ tristate "Renesas PHYs"
+ help
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -100,6 +100,7 @@ obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja
+ obj-y += qcom/
+ obj-$(CONFIG_QSEMI_PHY) += qsemi.o
+ obj-$(CONFIG_REALTEK_PHY) += realtek.o
++obj-$(CONFIG_REALTEK_SOC_PHY) += rtl83xx-phy.o
+ obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
+ obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
+ obj-$(CONFIG_SMSC_PHY) += smsc.o
diff --git a/target/linux/realtek/patches-6.6/722-net-dsa-add-rtl838x-support-for-tag-trailer.patch b/target/linux/realtek/patches-6.6/722-net-dsa-add-rtl838x-support-for-tag-trailer.patch
new file mode 100644
index 0000000000..348c59092a
--- /dev/null
+++ b/target/linux/realtek/patches-6.6/722-net-dsa-add-rtl838x-support-for-tag-trailer.patch
@@ -0,0 +1,61 @@
+From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 26 Nov 2020 12:02:21 +0100
+Subject: net: dsa: Add rtl838x support for tag trailer
+
+* rename the target to realtek
+* add refactored DSA driver
+* add latest gpio driver
+* lots of arch cleanups
+* new irq driver
+* additional boards
+
+Submitted-by: Bert Vermeulen <bert@biot.com>
+Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
+Submitted-by: Sander Vanheule <sander@svanheule.net>
+Submitted-by: Bjørn Mork <bjorn@mork.no>
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ net/dsa/tag_trailer.c | 16 +++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/net/dsa/tag_trailer.c
++++ b/net/dsa/tag_trailer.c
+@@ -19,7 +19,12 @@ static struct sk_buff *trailer_xmit(stru
+
+ trailer = skb_put(skb, 4);
+ trailer[0] = 0x80;
++
++#ifdef CONFIG_NET_DSA_RTL83XX
++ trailer[1] = dp->index;
++#else
+ trailer[1] = 1 << dp->index;
++#endif /* CONFIG_NET_DSA_RTL838X */
+ trailer[2] = 0x10;
+ trailer[3] = 0x00;
+
+@@ -35,12 +40,23 @@ static struct sk_buff *trailer_rcv(struc
+ return NULL;
+
+ trailer = skb_tail_pointer(skb) - 4;
++
++#ifdef CONFIG_NET_DSA_RTL83XX
++ if (trailer[0] != 0x80 || (trailer[1] & 0x80) != 0x00 ||
++ (trailer[2] & 0xef) != 0x00 || trailer[3] != 0x00)
++ return NULL;
++
++ if (trailer[1] & 0x40)
++ skb->offload_fwd_mark = 1;
++
++ source_port = trailer[1] & 0x3f;
++#else
+ if (trailer[0] != 0x80 || (trailer[1] & 0xf8) != 0x00 ||
+ (trailer[2] & 0xef) != 0x00 || trailer[3] != 0x00)
+ return NULL;
+
+ source_port = trailer[1] & 7;
+-
++#endif
+ skb->dev = dsa_master_find_slave(dev, 0, source_port);
+ if (!skb->dev)
+ return NULL;
diff --git a/target/linux/realtek/rtl838x/config-5.15 b/target/linux/realtek/rtl838x/config-6.6
index ad2c1b43cc..ad2c1b43cc 100644
--- a/target/linux/realtek/rtl838x/config-5.15
+++ b/target/linux/realtek/rtl838x/config-6.6
diff --git a/target/linux/realtek/rtl839x/config-5.15 b/target/linux/realtek/rtl839x/config-5.15
deleted file mode 100644
index 5fa52ba882..0000000000
--- a/target/linux/realtek/rtl839x/config-5.15
+++ /dev/null
@@ -1,241 +0,0 @@
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BMIPS_CPUFREQ is not set
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_REALTEK=y
-CONFIG_COMMON_CLK_RTL83XX=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-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 is not set
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_CPUFREQ=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EARLY_PRINTK_8250=y
-CONFIG_FIXED_PHY=y
-CONFIG_FORCE_MAX_ZONEORDER=13
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=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_TIME_VSYSCALL=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_PCA953X=y
-CONFIG_GPIO_PCA953X_IRQ=y
-CONFIG_GPIO_REALTEK_OTTO=y
-CONFIG_GPIO_RTL8231=y
-CONFIG_GRO_CELLS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HWMON=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_GPIO=y
-# CONFIG_I2C_RTL9300 is not set
-# CONFIG_I2C_MUX_RTL9300 is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_I2C=y
-CONFIG_MDIO_SMBUS=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-CONFIG_MIPS_EBPF_JIT=y
-CONFIG_MIPS_EXTERNAL_TIMER=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-CONFIG_MIPS_MT=y
-# CONFIG_MIPS_MT_FPAFF is not set
-CONFIG_MIPS_MT_SMP=y
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
-CONFIG_MTD_SPLIT_EVA_FW=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_VIRT_CONCAT=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_RTL83XX=y
-CONFIG_NET_DSA_TAG_TRAILER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_RTL838X=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NO_EXCEPT_FILL=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PADATA=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-CONFIG_PM_OPP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO_RESTART=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RATIONAL=y
-CONFIG_REALTEK_OTTO_TIMER=y
-CONFIG_REALTEK_OTTO_WDT=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REALTEK_SOC_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-# CONFIG_RTL838X is not set
-CONFIG_RTL839X=y
-CONFIG_RTL83XX=y
-# CONFIG_RTL930X is not set
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SFP=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRAM=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/realtek/rtl839x/config-6.6 b/target/linux/realtek/rtl839x/config-6.6
new file mode 100644
index 0000000000..c8d841c01e
--- /dev/null
+++ b/target/linux/realtek/rtl839x/config-6.6
@@ -0,0 +1,244 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BMIPS_CPUFREQ is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_REALTEK=y
+CONFIG_COMMON_CLK_RTL83XX=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+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 is not set
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_DIEI=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_EI=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_CPUFREQ=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
+CONFIG_CRYPTO_RNG2=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EARLY_PRINTK_8250=y
+CONFIG_FIXED_PHY=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=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_TIME_VSYSCALL=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_REALTEK_OTTO=y
+CONFIG_GPIO_RTL8231=y
+CONFIG_GPIO_WATCHDOG=y
+# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
+CONFIG_GRO_CELLS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HWMON=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_RTL9300 is not set
+# CONFIG_I2C_MUX_RTL9300 is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_I2C=y
+CONFIG_MDIO_SMBUS=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+CONFIG_MIPS_EBPF_JIT=y
+CONFIG_MIPS_EXTERNAL_TIMER=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_MIPS_LD_CAN_LINK_VDSO=y
+CONFIG_MIPS_MT=y
+# CONFIG_MIPS_MT_FPAFF is not set
+CONFIG_MIPS_MT_SMP=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_NR_CPU_NR_MAP=2
+CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
+CONFIG_MTD_SPLIT_EVA_FW=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_H3C_VFS=y
+CONFIG_MTD_SPLIT_TPLINK_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_MTD_VIRT_CONCAT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_RTL83XX=y
+CONFIG_NET_DSA_TAG_TRAILER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_RTL838X=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NO_EXCEPT_FILL=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_NR_CPUS=2
+CONFIG_NVMEM=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_PADATA=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PINCTRL=y
+CONFIG_PM_OPP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RATIONAL=y
+CONFIG_REALTEK_OTTO_TIMER=y
+CONFIG_REALTEK_OTTO_WDT=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REALTEK_SOC_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+# CONFIG_RTL838X is not set
+CONFIG_RTL839X=y
+CONFIG_RTL83XX=y
+# CONFIG_RTL930X is not set
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SFP=y
+CONFIG_SMP=y
+CONFIG_SMP_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SRAM=y
+CONFIG_SRCU=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_R4K=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
+CONFIG_SYS_SUPPORTS_SCHED_SMT=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XPS=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/realtek/rtl930x/config-5.15 b/target/linux/realtek/rtl930x/config-6.6
index af5f2ca7a3..af5f2ca7a3 100644
--- a/target/linux/realtek/rtl930x/config-5.15
+++ b/target/linux/realtek/rtl930x/config-6.6
diff --git a/target/linux/realtek/rtl931x/config-5.15 b/target/linux/realtek/rtl931x/config-5.15
deleted file mode 100644
index 2da27941c7..0000000000
--- a/target/linux/realtek/rtl931x/config-5.15
+++ /dev/null
@@ -1,241 +0,0 @@
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BOARD_SCACHE=y
-CONFIG_CEVT_RTL9300=y
-CONFIG_CLKSRC_MIPS_GIC=y
-CONFIG_CLOCKSOURCE_WATCHDOG=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-# CONFIG_COMMON_CLK_REALTEK is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EARLY_PRINTK_8250=y
-CONFIG_FIXED_PHY=y
-CONFIG_FORCE_MAX_ZONEORDER=13
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=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_TIME_VSYSCALL=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_REALTEK_OTTO=y
-CONFIG_GPIO_RTL8231=y
-CONFIG_GRO_CELLS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HIGHMEM=y
-CONFIG_HWMON=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_I2C_MUX=y
-CONFIG_I2C_MUX_RTL9300=y
-CONFIG_I2C_RTL9300=y
-CONFIG_I2C_SMBUS=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_I2C=y
-CONFIG_MDIO_SMBUS=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-CONFIG_MIPS_CM=y
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-CONFIG_MIPS_CPC=y
-CONFIG_MIPS_CPS=y
-# CONFIG_MIPS_CPS_NS16550_BOOL is not set
-CONFIG_MIPS_CPU_SCACHE=y
-CONFIG_MIPS_EBPF_JIT=y
-CONFIG_MIPS_GIC=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-CONFIG_MIPS_MT=y
-CONFIG_MIPS_MT_FPAFF=y
-CONFIG_MIPS_MT_SMP=y
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
-CONFIG_MTD_SPLIT_EVA_FW=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_RTL83XX=y
-CONFIG_NET_DSA_TAG_TRAILER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_RTL838X=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NO_EXCEPT_FILL=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_PADATA=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RATIONAL=y
-# CONFIG_REALTEK_OTTO_TIMER is not set
-CONFIG_REALTEK_OTTO_WDT=y
-# CONFIG_REALTEK_PHY is not set
-CONFIG_REALTEK_SOC_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-# CONFIG_RTL838X is not set
-# CONFIG_RTL839X is not set
-CONFIG_RTL83XX=y
-CONFIG_RTL930X=y
-CONFIG_RTL931X=y
-CONFIG_SENSORS_GPIO_FAN=y
-CONFIG_SENSORS_LM75=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SFP=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_MIPS_CPS=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_SYS_SUPPORTS_VPE_LOADER=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WEAK_ORDERING=y
-CONFIG_XPS=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/realtek/rtl931x/config-6.6 b/target/linux/realtek/rtl931x/config-6.6
new file mode 100644
index 0000000000..736f472029
--- /dev/null
+++ b/target/linux/realtek/rtl931x/config-6.6
@@ -0,0 +1,242 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BOARD_SCACHE=y
+CONFIG_CEVT_RTL9300=y
+CONFIG_CLKSRC_MIPS_GIC=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=125
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+# CONFIG_COMMON_CLK_REALTEK is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_DIEI=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_EI=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EARLY_PRINTK_8250=y
+CONFIG_FIXED_PHY=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=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_TIME_VSYSCALL=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_REALTEK_OTTO=y
+CONFIG_GPIO_RTL8231=y
+CONFIG_GRO_CELLS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HIGHMEM=y
+CONFIG_HWMON=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_RTL9300=y
+CONFIG_I2C_RTL9300=y
+CONFIG_I2C_SMBUS=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_KMAP_LOCAL=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_I2C=y
+CONFIG_MDIO_SMBUS=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+CONFIG_MIPS_CM=y
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+CONFIG_MIPS_CPC=y
+CONFIG_MIPS_CPS=y
+# CONFIG_MIPS_CPS_NS16550_BOOL is not set
+CONFIG_MIPS_CPU_SCACHE=y
+CONFIG_MIPS_EBPF_JIT=y
+CONFIG_MIPS_GIC=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_MIPS_LD_CAN_LINK_VDSO=y
+CONFIG_MIPS_MT=y
+CONFIG_MIPS_MT_FPAFF=y
+CONFIG_MIPS_MT_SMP=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_NR_CPU_NR_MAP=2
+CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
+CONFIG_MTD_SPLIT_EVA_FW=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_TPLINK_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_RTL83XX=y
+CONFIG_NET_DSA_TAG_TRAILER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_RTL838X=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NO_EXCEPT_FILL=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_NR_CPUS=2
+CONFIG_NVMEM=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_PADATA=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PINCTRL=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RATIONAL=y
+# CONFIG_REALTEK_OTTO_TIMER is not set
+CONFIG_REALTEK_OTTO_WDT=y
+# CONFIG_REALTEK_PHY is not set
+CONFIG_REALTEK_SOC_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+# CONFIG_RTL838X is not set
+# CONFIG_RTL839X is not set
+CONFIG_RTL83XX=y
+CONFIG_RTL930X=y
+CONFIG_RTL931X=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SFP=y
+CONFIG_SMP=y
+CONFIG_SMP_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SRCU=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_R4K=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_SYS_SUPPORTS_MIPS_CPS=y
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
+CONFIG_SYS_SUPPORTS_SCHED_SMT=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_SYS_SUPPORTS_VPE_LOADER=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_XPS=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
index ef89461056..e28069cf7b 100644
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
@@ -13,6 +13,7 @@ friendlyarm,nanopi-r2c-plus|\
friendlyarm,nanopi-r2s|\
friendlyarm,nanopi-r4s|\
friendlyarm,nanopi-r4s-enterprise|\
+friendlyarm,nanopi-r6c|\
xunlong,orangepi-r1-plus|\
xunlong,orangepi-r1-plus-lts)
ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth0"
@@ -28,6 +29,11 @@ friendlyarm,nanopi-r5s)
ucidef_set_led_netdev "lan1" "LAN1" "green:lan-1" "eth1"
ucidef_set_led_netdev "lan2" "LAN2" "green:lan-2" "eth2"
;;
+friendlyarm,nanopi-r6s)
+ ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth1"
+ ucidef_set_led_netdev "lan1" "LAN1" "green:lan-1" "eth2"
+ ucidef_set_led_netdev "lan2" "LAN2" "green:lan-2" "eth0"
+ ;;
esac
board_config_flush
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
index 8729bd52f2..192b825244 100644
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
@@ -7,22 +7,30 @@ rockchip_setup_interfaces()
local board="$1"
case "$board" in
+ armsom,sige7|\
friendlyarm,nanopi-r2c|\
friendlyarm,nanopi-r2c-plus|\
friendlyarm,nanopi-r2s|\
friendlyarm,nanopi-r4s|\
friendlyarm,nanopi-r4s-enterprise|\
+ friendlyarm,nanopi-r6c|\
+ radxa,rockpi-e|\
xunlong,orangepi-r1-plus|\
xunlong,orangepi-r1-plus-lts)
ucidef_set_interfaces_lan_wan 'eth1' 'eth0'
;;
+ friendlyarm,nanopc-t6|\
friendlyarm,nanopi-r5c|\
- radxa,e25)
+ radxa,e25|\
+ radxa,rock-3b)
ucidef_set_interfaces_lan_wan 'eth0' 'eth1'
;;
friendlyarm,nanopi-r5s)
ucidef_set_interfaces_lan_wan 'eth1 eth2' 'eth0'
;;
+ friendlyarm,nanopi-r6s)
+ ucidef_set_interfaces_lan_wan 'eth0 eth2' 'eth1'
+ ;;
sinovoip,rk3568-bpi-r2pro)
ucidef_set_interfaces_lan_wan 'lan0 lan1 lan2 lan3' 'eth0'
;;
@@ -40,6 +48,8 @@ rockchip_setup_macs()
local label_mac=""
case "$board" in
+ armsom,sige7|\
+ friendlyarm,nanopc-t6|\
friendlyarm,nanopi-r2c|\
friendlyarm,nanopi-r2s)
wan_mac=$(macaddr_generate_from_mmc_cid mmcblk0)
@@ -56,7 +66,9 @@ rockchip_setup_macs()
wan_mac=$(get_mac_binary "/sys/bus/i2c/devices/2-0051/eeprom" 0xfa)
lan_mac=$(macaddr_setbit_la "$wan_mac")
;;
- friendlyarm,nanopi-r5c)
+ friendlyarm,nanopi-r5c|\
+ friendlyarm,nanopi-r6c|\
+ friendlyarm,nanopi-r6s)
wan_mac=$(macaddr_generate_from_mmc_cid mmcblk*)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
diff --git a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
index 8bbce1c328..f65d008ef4 100644
--- a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
+++ b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
@@ -29,6 +29,15 @@ set_interface_core() {
}
case "$(board_name)" in
+armsom,sige7|\
+friendlyarm,nanopc-t6|\
+friendlyarm,nanopi-r5c|\
+friendlyarm,nanopi-r6c|\
+radxa,e25|\
+sinovoip,rk3568-bpi-r2pro)
+ set_interface_core 2 "eth0"
+ set_interface_core 4 "eth1"
+ ;;
friendlyarm,nanopi-r2c|\
friendlyarm,nanopi-r2c-plus|\
friendlyarm,nanopi-r2s|\
@@ -43,13 +52,8 @@ friendlyarm,nanopi-r4s-enterprise)
set_interface_core 10 "eth0"
set_interface_core 20 "eth1"
;;
-friendlyarm,nanopi-r5c|\
-radxa,e25|\
-sinovoip,rk3568-bpi-r2pro)
- set_interface_core 2 "eth0"
- set_interface_core 4 "eth1"
- ;;
-friendlyarm,nanopi-r5s)
+friendlyarm,nanopi-r5s|\
+friendlyarm,nanopi-r6s)
set_interface_core 2 "eth0"
set_interface_core 4 "eth1"
set_interface_core 8 "eth2"
diff --git a/target/linux/rockchip/armv8/config-6.6 b/target/linux/rockchip/armv8/config-6.6
index fb57fc6260..c92f2b1c48 100644
--- a/target/linux/rockchip/armv8/config-6.6
+++ b/target/linux/rockchip/armv8/config-6.6
@@ -22,13 +22,20 @@ CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARC_EMAC_CORE=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
+CONFIG_ARM64_ERRATUM_1024718=y
+CONFIG_ARM64_ERRATUM_1165522=y
+CONFIG_ARM64_ERRATUM_1286807=y
+CONFIG_ARM64_ERRATUM_1319367=y
+CONFIG_ARM64_ERRATUM_1463225=y
+CONFIG_ARM64_ERRATUM_1530923=y
CONFIG_ARM64_ERRATUM_2051678=y
CONFIG_ARM64_ERRATUM_2054223=y
CONFIG_ARM64_ERRATUM_2067961=y
CONFIG_ARM64_ERRATUM_2077057=y
+CONFIG_ARM64_ERRATUM_2441007=y
+CONFIG_ARM64_ERRATUM_2441009=y
CONFIG_ARM64_ERRATUM_2658417=y
+CONFIG_ARM64_ERRATUM_3117295=y
CONFIG_ARM64_ERRATUM_819472=y
CONFIG_ARM64_ERRATUM_824069=y
CONFIG_ARM64_ERRATUM_826319=y
@@ -39,7 +46,6 @@ CONFIG_ARM64_ERRATUM_858921=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -52,6 +58,9 @@ CONFIG_ARM64_VA_BITS=48
# CONFIG_ARM64_VA_BITS_39 is not set
CONFIG_ARM64_VA_BITS_48=y
CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
+CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD=y
CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_ARCH_TIMER=y
@@ -163,6 +172,7 @@ CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
CONFIG_CPU_ISOLATION=y
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_PM=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_THERMAL=y
@@ -235,7 +245,6 @@ CONFIG_EMAC_ROCKCHIP=y
CONFIG_ENERGY_MODEL=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FANOTIFY=y
@@ -246,7 +255,6 @@ CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -442,7 +450,7 @@ CONFIG_NR_CPUS=256
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_ROCKCHIP_EFUSE=y
-# CONFIG_NVMEM_ROCKCHIP_OTP is not set
+CONFIG_NVMEM_ROCKCHIP_OTP=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVME_CORE=y
# CONFIG_NVME_HWMON is not set
@@ -507,6 +515,7 @@ CONFIG_PHY_ROCKCHIP_PCIE=y
CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
CONFIG_PHY_ROCKCHIP_TYPEC=y
CONFIG_PHY_ROCKCHIP_USB=y
+CONFIG_PHY_ROCKCHIP_USBDP=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_RK805=y
CONFIG_PINCTRL_ROCKCHIP=y
@@ -567,6 +576,7 @@ CONFIG_RELOCATABLE=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_SCMI=y
CONFIG_RFS_ACCEL=y
+CONFIG_ROCKCHIP_ERRATUM_3588001=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_IOMMU=y
diff --git a/target/linux/rockchip/armv8/target.mk b/target/linux/rockchip/armv8/target.mk
index 085b475c4b..2fd1292817 100644
--- a/target/linux/rockchip/armv8/target.mk
+++ b/target/linux/rockchip/armv8/target.mk
@@ -1,8 +1,8 @@
ARCH:=aarch64
SUBTARGET:=armv8
-BOARDNAME:=RK33xx/RK356x boards (64 bit)
+BOARDNAME:=RK33xx/RK35xx boards (64 bit)
define Target/Description
- Build firmware image for Rockchip RK33xx devices.
+ Build firmware image for Rockchip RK33xx/RK35xx devices.
This firmware features a 64 bit kernel.
endef
diff --git a/target/linux/rockchip/image/Makefile b/target/linux/rockchip/image/Makefile
index 5de053bdb6..5d90ef8cf8 100644
--- a/target/linux/rockchip/image/Makefile
+++ b/target/linux/rockchip/image/Makefile
@@ -29,7 +29,7 @@ define Build/pine64-img
# combining boot partition, root partition as well as the u-boot bootloader
# Generate a new partition table in $@ with 32 MiB of
- # alignment padding for the idbloader and u-boot to fit:
+ # alignment padding for the u-boot-rockchip.bin (idbloader + u-boot) to fit:
# http://opensource.rock-chips.com/wiki_Boot_option#Boot_flow
#
# U-Boot SPL expects the U-Boot ITB to be located at sector 0x4000 (8 MiB) on the MMC storage
@@ -39,9 +39,8 @@ define Build/pine64-img
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
32768
- # Copy the idbloader and the u-boot image to the image at sector 0x40 and 0x4000
- dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-idbloader.img of="$@" seek=64 conv=notrunc
- dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-u-boot.itb of="$@" seek=16384 conv=notrunc
+ # Copy the u-boot-rockchip.bin to the image at sector 0x40
+ dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-u-boot-rockchip.bin of="$@" seek=64 conv=notrunc
endef
### Devices ###
diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk
index df0ca6ffb5..39eb3bb034 100644
--- a/target/linux/rockchip/image/armv8.mk
+++ b/target/linux/rockchip/image/armv8.mk
@@ -1,10 +1,21 @@
# SPDX-License-Identifier: GPL-2.0-only
#
-# Copyright (C) 2020 Tobias Maedel
+# Copyright (C) 2020 Sarah Maedel
# FIT will be loaded at 0x02080000. Leave 16M for that, align it to 2M and load the kernel after it.
KERNEL_LOADADDR := 0x03200000
+define Device/armsom_sige7
+ DEVICE_VENDOR := ArmSoM
+ DEVICE_MODEL := Sige7
+ DEVICE_ALT0_VENDOR := Bananapi
+ DEVICE_ALT0_MODEL := BPi-M7
+ SOC := rk3588
+ DEVICE_DTS := rockchip/rk3588-armsom-sige7
+ DEVICE_PACKAGES := kmod-r8169
+endef
+TARGET_DEVICES += armsom_sige7
+
define Device/firefly_roc-rk3328-cc
DEVICE_VENDOR := Firefly
DEVICE_MODEL := ROC-RK3328-CC
@@ -22,6 +33,14 @@ define Device/friendlyarm_nanopc-t4
endef
TARGET_DEVICES += friendlyarm_nanopc-t4
+define Device/friendlyarm_nanopc-t6
+ DEVICE_VENDOR := FriendlyARM
+ DEVICE_MODEL := NanoPC T6
+ SOC := rk3588
+ DEVICE_PACKAGES := kmod-r8169
+endef
+TARGET_DEVICES += friendlyarm_nanopc-t6
+
define Device/friendlyarm_nanopi-r2c
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPi R2C
@@ -81,6 +100,22 @@ define Device/friendlyarm_nanopi-r5s
endef
TARGET_DEVICES += friendlyarm_nanopi-r5s
+define Device/friendlyarm_nanopi-r6c
+ DEVICE_VENDOR := FriendlyARM
+ DEVICE_MODEL := NanoPi R6C
+ SOC := rk3588s
+ DEVICE_PACKAGES := kmod-r8169
+endef
+TARGET_DEVICES += friendlyarm_nanopi-r6c
+
+define Device/friendlyarm_nanopi-r6s
+ DEVICE_VENDOR := FriendlyARM
+ DEVICE_MODEL := NanoPi R6S
+ SOC := rk3588s
+ DEVICE_PACKAGES := kmod-r8169
+endef
+TARGET_DEVICES += friendlyarm_nanopi-r6s
+
define Device/pine64_rock64
DEVICE_VENDOR := Pine64
DEVICE_MODEL := Rock64
@@ -109,11 +144,55 @@ define Device/radxa_e25
DEVICE_MODEL := E25
SOC := rk3568
DEVICE_DTS := rockchip/rk3568-radxa-e25
+ BOOT_SCRIPT := radxa-e25
UBOOT_DEVICE_NAME := radxa-e25-rk3568
- DEVICE_PACKAGES := kmod-r8169 kmod-ata-ahci-platform
+ DEVICE_PACKAGES := kmod-r8169 kmod-ata-ahci-dwc
endef
TARGET_DEVICES += radxa_e25
+define Device/radxa_rock-3a
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 3A
+ SOC := rk3568
+ SUPPORTED_DEVICES := radxa,rock3a
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_rock-3a
+
+define Device/radxa_rock-3b
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 3B
+ SOC := rk3568
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_rock-3b
+
+define Device/radxa_rock-3c
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 3C
+ SOC := rk3566
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_rock-3c
+
+define Device/radxa_rock-5a
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 5A
+ SOC := rk3588s
+ UBOOT_DEVICE_NAME := rock5a-rk3588s
+ DEVICE_PACKAGES := kmod-hwmon-pwmfan
+endef
+TARGET_DEVICES += radxa_rock-5a
+
+define Device/radxa_rock-5b
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 5B
+ SOC := rk3588
+ UBOOT_DEVICE_NAME := rock5b-rk3588
+ DEVICE_PACKAGES := kmod-r8169 kmod-hwmon-pwmfan
+endef
+TARGET_DEVICES += radxa_rock-5b
+
define Device/radxa_rock-pi-4a
DEVICE_VENDOR := Radxa
DEVICE_MODEL := ROCK Pi 4A
@@ -130,6 +209,45 @@ define Device/radxa_rock-pi-e
endef
TARGET_DEVICES += radxa_rock-pi-e
+define Device/radxa_rock-pi-e-v3
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK Pi E v3.0
+ SOC := rk3328
+ DEVICE_DTS := rockchip/rk3328-rock-pi-e
+ DEVICE_PACKAGES := kmod-rtw88-8723du kmod-usb-net-cdc-ncm kmod-usb-net-rndis wpad-basic-mbedtls
+endef
+TARGET_DEVICES += radxa_rock-pi-e-v3
+
+define Device/radxa_rock-pi-s
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK Pi S
+ SOC := rk3308
+ SUPPORTED_DEVICES := radxa,rockpis
+ BOOT_SCRIPT := rock-pi-s
+ DEVICE_PACKAGES := kmod-rtw88-8723ds kmod-usb-net-cdc-ncm kmod-usb-net-rndis wpad-basic-mbedtls
+endef
+TARGET_DEVICES += radxa_rock-pi-s
+
+define Device/radxa_zero-3e
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ZERO 3E
+ SOC := rk3566
+ DEVICE_DTS := rockchip/rk3566-radxa-zero-3e
+ UBOOT_DEVICE_NAME := radxa-zero-3-rk3566
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_zero-3e
+
+define Device/radxa_zero-3w
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ZERO 3W
+ SOC := rk3566
+ DEVICE_DTS := rockchip/rk3566-radxa-zero-3w
+ UBOOT_DEVICE_NAME := radxa-zero-3-rk3566
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_zero-3w
+
define Device/sinovoip_bpi-r2-pro
DEVICE_VENDOR := Sinovoip
DEVICE_MODEL := Bananapi-R2 Pro
diff --git a/target/linux/rockchip/image/default.bootscript b/target/linux/rockchip/image/default.bootscript
index cca0b8d4ac..10ca93ceda 100644
--- a/target/linux/rockchip/image/default.bootscript
+++ b/target/linux/rockchip/image/default.bootscript
@@ -2,6 +2,8 @@ part uuid ${devtype} ${devnum}:2 uuid
if test $stdout = 'serial@fe660000' ;
then serial_addr=',0xfe660000';
+elif test $stdout = 'serial@feb50000' ;
+then serial_addr=',0xfeb50000';
elif test $stdout = 'serial@ff130000' ;
then serial_addr=',0xff130000';
elif test $stdout = 'serial@ff1a0000' ;
diff --git a/target/linux/rockchip/image/radxa-e25.bootscript b/target/linux/rockchip/image/radxa-e25.bootscript
new file mode 100644
index 0000000000..c91319f7fc
--- /dev/null
+++ b/target/linux/rockchip/image/radxa-e25.bootscript
@@ -0,0 +1,7 @@
+part uuid ${devtype} ${devnum}:2 uuid
+
+setenv bootargs "console=ttyS2,115200 earlycon=uart8250,mmio32,0xfe660000 root=PARTUUID=${uuid} rw rootwait";
+
+load ${devtype} ${devnum}:1 ${kernel_addr_r} kernel.img
+
+bootm ${kernel_addr_r}
diff --git a/target/linux/rockchip/image/rock-pi-s.bootscript b/target/linux/rockchip/image/rock-pi-s.bootscript
new file mode 100644
index 0000000000..c968e53d81
--- /dev/null
+++ b/target/linux/rockchip/image/rock-pi-s.bootscript
@@ -0,0 +1,7 @@
+part uuid ${devtype} ${devnum}:2 uuid
+
+setenv bootargs "console=ttyS0,1500000 earlycon=uart8250,mmio32,0xff0a0000 root=PARTUUID=${uuid} rw rootwait";
+
+load ${devtype} ${devnum}:1 ${kernel_addr_r} kernel.img
+
+bootm ${kernel_addr_r}
diff --git a/target/linux/rockchip/patches-6.6/023-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch b/target/linux/rockchip/patches-6.6/001-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch
index fb5015cf6e..fb5015cf6e 100644
--- a/target/linux/rockchip/patches-6.6/023-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch
+++ b/target/linux/rockchip/patches-6.6/001-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch
diff --git a/target/linux/rockchip/patches-6.6/030-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch b/target/linux/rockchip/patches-6.6/002-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch
index 9be609f661..9be609f661 100644
--- a/target/linux/rockchip/patches-6.6/030-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch
+++ b/target/linux/rockchip/patches-6.6/002-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch
diff --git a/target/linux/rockchip/patches-6.6/031-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch b/target/linux/rockchip/patches-6.6/003-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch
index b23d7e06b9..b23d7e06b9 100644
--- a/target/linux/rockchip/patches-6.6/031-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch
+++ b/target/linux/rockchip/patches-6.6/003-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch
diff --git a/target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch b/target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch
new file mode 100644
index 0000000000..bb7f833977
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch
@@ -0,0 +1,86 @@
+From 0536fa6e6fa3e48f4ca11855b586c277be524fbe Mon Sep 17 00:00:00 2001
+From: David Wu <david.wu@rock-chips.com>
+Date: Tue, 21 May 2024 21:10:13 +0000
+Subject: [PATCH] soc: rockchip: io-domain: Add RK3308 IO voltage domains
+
+Add IO voltage domains support for the RK3308 SoC.
+
+Signed-off-by: David Wu <david.wu@rock-chips.com>
+Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521211029.1236094-11-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/soc/rockchip/io-domain.c | 40 ++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+--- a/drivers/soc/rockchip/io-domain.c
++++ b/drivers/soc/rockchip/io-domain.c
+@@ -39,6 +39,10 @@
+ #define RK3288_SOC_CON2_FLASH0 BIT(7)
+ #define RK3288_SOC_FLASH_SUPPLY_NUM 2
+
++#define RK3308_SOC_CON0 0x300
++#define RK3308_SOC_CON0_VCCIO3 BIT(8)
++#define RK3308_SOC_VCCIO3_SUPPLY_NUM 3
++
+ #define RK3328_SOC_CON4 0x410
+ #define RK3328_SOC_CON4_VCCIO2 BIT(7)
+ #define RK3328_SOC_VCCIO2_SUPPLY_NUM 1
+@@ -229,6 +233,25 @@ static void rk3288_iodomain_init(struct
+ dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
+ }
+
++static void rk3308_iodomain_init(struct rockchip_iodomain *iod)
++{
++ int ret;
++ u32 val;
++
++ /* if no vccio3 supply we should leave things alone */
++ if (!iod->supplies[RK3308_SOC_VCCIO3_SUPPLY_NUM].reg)
++ return;
++
++ /*
++ * set vccio3 iodomain to also use this framework
++ * instead of a special gpio.
++ */
++ val = RK3308_SOC_CON0_VCCIO3 | (RK3308_SOC_CON0_VCCIO3 << 16);
++ ret = regmap_write(iod->grf, RK3308_SOC_CON0, val);
++ if (ret < 0)
++ dev_warn(iod->dev, "couldn't update vccio3 vsel ctrl\n");
++}
++
+ static void rk3328_iodomain_init(struct rockchip_iodomain *iod)
+ {
+ int ret;
+@@ -376,6 +399,19 @@ static const struct rockchip_iodomain_so
+ .init = rk3288_iodomain_init,
+ };
+
++static const struct rockchip_iodomain_soc_data soc_data_rk3308 = {
++ .grf_offset = 0x300,
++ .supply_names = {
++ "vccio0",
++ "vccio1",
++ "vccio2",
++ "vccio3",
++ "vccio4",
++ "vccio5",
++ },
++ .init = rk3308_iodomain_init,
++};
++
+ static const struct rockchip_iodomain_soc_data soc_data_rk3328 = {
+ .grf_offset = 0x410,
+ .supply_names = {
+@@ -529,6 +565,10 @@ static const struct of_device_id rockchi
+ .data = &soc_data_rk3288
+ },
+ {
++ .compatible = "rockchip,rk3308-io-voltage-domain",
++ .data = &soc_data_rk3308
++ },
++ {
+ .compatible = "rockchip,rk3328-io-voltage-domain",
+ .data = &soc_data_rk3328
+ },
diff --git a/target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch b/target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch
new file mode 100644
index 0000000000..3565acd2e4
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch
@@ -0,0 +1,28 @@
+From d1829ba469d5743734e37d59fece73e3668ab084 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Tue, 21 May 2024 21:10:14 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add rk3308 IO voltage domains
+
+Add a disabled RK3308 IO voltage domains node to SoC DT.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521211029.1236094-12-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3308.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
+@@ -168,6 +168,11 @@
+ compatible = "rockchip,rk3308-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xff000000 0x0 0x08000>;
+
++ io_domains: io-domains {
++ compatible = "rockchip,rk3308-io-voltage-domain";
++ status = "disabled";
++ };
++
+ reboot-mode {
+ compatible = "syscon-reboot-mode";
+ offset = <0x500>;
diff --git a/target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch b/target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch
new file mode 100644
index 0000000000..83ebe67789
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch
@@ -0,0 +1,84 @@
+From c45de75d7a9ab44a15dedc7a121d6371d6891301 Mon Sep 17 00:00:00 2001
+From: Trevor Woerner <twoerner@gmail.com>
+Date: Mon, 20 Nov 2023 11:22:32 -0500
+Subject: [PATCH] arm64: dts: rockchip: add gpio-line-names to rk3308-rock-pi-s
+
+Add names to the pins of the general-purpose expansion header as given in the
+Radxa GPIO page[1] following the conventions in the kernel documentation[2] to
+make it easier for users to correlate the pins with functions when using
+utilities such as gpioinfo.
+
+[1] https://wiki.radxa.com/RockpiS/hardware/gpio
+[2] Documentation/devicetree/bindings/gpio/gpio.txt
+
+Signed-off-by: Trevor Woerner <twoerner@gmail.com>
+Link: https://lore.kernel.org/r/20231120162232.27653-1-twoerner@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 58 +++++++++++++++++++
+ 1 file changed, 58 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -315,3 +315,61 @@
+ &wdt {
+ status = "okay";
+ };
++
++&gpio0 {
++ gpio-line-names =
++ /* GPIO0_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_B0 - B7 */
++ "", "", "", "header1-pin3 [GPIO0_B3]", "header1-pin5 [GPIO0_B4]",
++ "", "", "header1-pin11 [GPIO0_B7]",
++ /* GPIO0_C0 - C7 */
++ "header1-pin13 [GPIO0_C0]", "header1-pin15 [GPIO0_C1]", "", "", "",
++ "", "", "",
++ /* GPIO0_D0 - D8 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio1 {
++ gpio-line-names =
++ /* GPIO1_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_C0 - C7 */
++ "", "", "", "", "", "", "header1-pin21 [GPIO1_C6]",
++ "header1-pin19 [GPIO1_C7]",
++ /* GPIO1_D0 - D8 */
++ "header1-pin23 [GPIO1_D0]", "header1-pin24 [GPIO1_D1]", "", "", "",
++ "", "", "";
++};
++
++&gpio2 {
++ gpio-line-names =
++ /* GPIO2_A0 - A7 */
++ "header1-pin10 [GPIO2_A0]", "header1-pin8 [GPIO2_A1]", "", "",
++ "header1-pin7 [GPIO2_A4]", "header1-pin12 [GPIO2_A5]",
++ "header2-pin46 [GPIO2_A6]", "header1-pin22 [GPIO1_A7]",
++ /* GPIO2_B0 - B7 */
++ "header2-pin45 [GPIO2_B0]", "header1-pin18 [GPIO2_B1]",
++ "header1-pin16 [GPIO2_B2]", "header2-pin44 [GPIO2_B3]",
++ "header2-pin43 [GPIO2_B4]", "header2-pin28 [GPIO2_B5]",
++ "header2-pin30 [GPIO2_B6]", "header2-pin32 [GPIO2_B7]",
++ /* GPIO2_C0 - C7 */
++ "header2-pin34 [GPIO2_C0]", "", "", "", "", "", "", "",
++ /* GPIO2_D0 - D8 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio3 {
++ gpio-line-names =
++ /* GPIO3_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_B0 - B7 */
++ "", "", "header2-pin42 [GPIO3_B2]", "header2-pin41 [GPIO3_B3]",
++ "header2-pin40 [GPIO3_B4]", "header2-pin39 [GPIO3_B5]", "", "",
++ /* GPIO3_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_D0 - D8 */
++ "", "", "", "", "", "", "", "";
++};
diff --git a/target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch b/target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch
new file mode 100644
index 0000000000..994644e142
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch
@@ -0,0 +1,152 @@
+From 085021cc825ed90a6ddc4406f608fb8a85745f81 Mon Sep 17 00:00:00 2001
+From: Trevor Woerner <twoerner@gmail.com>
+Date: Tue, 19 Dec 2023 12:38:13 -0500
+Subject: [PATCH] arm64: dts: rockchip: rk3308-rock-pi-s gpio-line-names
+ cleanup
+
+Perform the following cleanups on a previous patch:
+- indent lines after "gpio-line-names"
+- fix D0-D8 -> D0-D7
+- sort phandle references
+
+Fixes: c45de75d7a9a ("arm64: dts: rockchip: add gpio-line-names to rk3308-rock-pi-s")
+Signed-off-by: Trevor Woerner <twoerner@gmail.com>
+Link: https://lore.kernel.org/r/20231219173814.1569-1-twoerner@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 120 +++++++++---------
+ 1 file changed, 62 insertions(+), 58 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -166,6 +166,68 @@
+ };
+ };
+
++&gpio0 {
++ gpio-line-names =
++ /* GPIO0_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_B0 - B7 */
++ "", "", "", "header1-pin3 [GPIO0_B3]",
++ "header1-pin5 [GPIO0_B4]", "", "",
++ "header1-pin11 [GPIO0_B7]",
++ /* GPIO0_C0 - C7 */
++ "header1-pin13 [GPIO0_C0]",
++ "header1-pin15 [GPIO0_C1]", "", "", "",
++ "", "", "",
++ /* GPIO0_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio1 {
++ gpio-line-names =
++ /* GPIO1_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_C0 - C7 */
++ "", "", "", "", "", "", "header1-pin21 [GPIO1_C6]",
++ "header1-pin19 [GPIO1_C7]",
++ /* GPIO1_D0 - D7 */
++ "header1-pin23 [GPIO1_D0]", "header1-pin24 [GPIO1_D1]",
++ "", "", "", "", "", "";
++};
++
++&gpio2 {
++ gpio-line-names =
++ /* GPIO2_A0 - A7 */
++ "header1-pin10 [GPIO2_A0]", "header1-pin8 [GPIO2_A1]",
++ "", "",
++ "header1-pin7 [GPIO2_A4]", "header1-pin12 [GPIO2_A5]",
++ "header2-pin46 [GPIO2_A6]", "header1-pin22 [GPIO1_A7]",
++ /* GPIO2_B0 - B7 */
++ "header2-pin45 [GPIO2_B0]", "header1-pin18 [GPIO2_B1]",
++ "header1-pin16 [GPIO2_B2]", "header2-pin44 [GPIO2_B3]",
++ "header2-pin43 [GPIO2_B4]", "header2-pin28 [GPIO2_B5]",
++ "header2-pin30 [GPIO2_B6]", "header2-pin32 [GPIO2_B7]",
++ /* GPIO2_C0 - C7 */
++ "header2-pin34 [GPIO2_C0]", "", "", "", "", "", "", "",
++ /* GPIO2_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio3 {
++ gpio-line-names =
++ /* GPIO3_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_B0 - B7 */
++ "", "", "header2-pin42 [GPIO3_B2]",
++ "header2-pin41 [GPIO3_B3]", "header2-pin40 [GPIO3_B4]",
++ "header2-pin39 [GPIO3_B5]", "", "",
++ /* GPIO3_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
+ &i2c1 {
+ status = "okay";
+ };
+@@ -315,61 +377,3 @@
+ &wdt {
+ status = "okay";
+ };
+-
+-&gpio0 {
+- gpio-line-names =
+- /* GPIO0_A0 - A7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO0_B0 - B7 */
+- "", "", "", "header1-pin3 [GPIO0_B3]", "header1-pin5 [GPIO0_B4]",
+- "", "", "header1-pin11 [GPIO0_B7]",
+- /* GPIO0_C0 - C7 */
+- "header1-pin13 [GPIO0_C0]", "header1-pin15 [GPIO0_C1]", "", "", "",
+- "", "", "",
+- /* GPIO0_D0 - D8 */
+- "", "", "", "", "", "", "", "";
+-};
+-
+-&gpio1 {
+- gpio-line-names =
+- /* GPIO1_A0 - A7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO1_B0 - B7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO1_C0 - C7 */
+- "", "", "", "", "", "", "header1-pin21 [GPIO1_C6]",
+- "header1-pin19 [GPIO1_C7]",
+- /* GPIO1_D0 - D8 */
+- "header1-pin23 [GPIO1_D0]", "header1-pin24 [GPIO1_D1]", "", "", "",
+- "", "", "";
+-};
+-
+-&gpio2 {
+- gpio-line-names =
+- /* GPIO2_A0 - A7 */
+- "header1-pin10 [GPIO2_A0]", "header1-pin8 [GPIO2_A1]", "", "",
+- "header1-pin7 [GPIO2_A4]", "header1-pin12 [GPIO2_A5]",
+- "header2-pin46 [GPIO2_A6]", "header1-pin22 [GPIO1_A7]",
+- /* GPIO2_B0 - B7 */
+- "header2-pin45 [GPIO2_B0]", "header1-pin18 [GPIO2_B1]",
+- "header1-pin16 [GPIO2_B2]", "header2-pin44 [GPIO2_B3]",
+- "header2-pin43 [GPIO2_B4]", "header2-pin28 [GPIO2_B5]",
+- "header2-pin30 [GPIO2_B6]", "header2-pin32 [GPIO2_B7]",
+- /* GPIO2_C0 - C7 */
+- "header2-pin34 [GPIO2_C0]", "", "", "", "", "", "", "",
+- /* GPIO2_D0 - D8 */
+- "", "", "", "", "", "", "", "";
+-};
+-
+-&gpio3 {
+- gpio-line-names =
+- /* GPIO3_A0 - A7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO3_B0 - B7 */
+- "", "", "header2-pin42 [GPIO3_B2]", "header2-pin41 [GPIO3_B3]",
+- "header2-pin40 [GPIO3_B4]", "header2-pin39 [GPIO3_B5]", "", "",
+- /* GPIO3_C0 - C7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO3_D0 - D8 */
+- "", "", "", "", "", "", "", "";
+-};
diff --git a/target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch b/target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch
new file mode 100644
index 0000000000..ad746df3b0
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch
@@ -0,0 +1,35 @@
+From 100b3bdee6035192f6d4a1847970fe004bb505fb Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Tue, 21 May 2024 21:10:15 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add io-domains to rk3308-rock-pi-s
+
+The VCCIO4 io-domain used for WiFi/BT is using 1v8 IO signal voltage.
+
+Add io-domains node with the VCCIO supplies connected on the board.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521211029.1236094-13-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -232,6 +232,16 @@
+ status = "okay";
+ };
+
++&io_domains {
++ vccio0-supply = <&vcc_io>;
++ vccio1-supply = <&vcc_io>;
++ vccio2-supply = <&vcc_io>;
++ vccio3-supply = <&vcc_io>;
++ vccio4-supply = <&vcc_1v8>;
++ vccio5-supply = <&vcc_io>;
++ status = "okay";
++};
++
+ &pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_32k>;
diff --git a/target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch b/target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch
new file mode 100644
index 0000000000..9901d9fff0
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch
@@ -0,0 +1,769 @@
+From ee219017ddb50be14c60d3cbe3e51ac0b2008d40 Mon Sep 17 00:00:00 2001
+From: Chukun Pan <amadeus@jmu.edu.cn>
+Date: Sun, 28 Apr 2024 20:36:18 +0800
+Subject: [PATCH] arm64: dts: rockchip: Add Radxa ROCK 3C
+
+The Radxa ROCK 3C is a development board with the
+Rockchip RK3566 SoC. It has the following features:
+
+- 1/2/4GB LPDDR4
+- 1x HDMI Type A
+- 1x PCIE 2.0 slot
+- 1x FAN connector
+- 3.5mm jack with mic
+- 1GbE RTL8211F Ethernet
+- 1x USB 3.0, 3x USB 2.0
+- 40-pin expansion header
+- MicroSD card/eMMC socket
+- 16MB SPI NOR (gd25lq128d)
+- AP6256 or AIC8800 WiFi/BT
+
+Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
+Link: https://lore.kernel.org/r/20240428123618.72170-3-amadeus@jmu.edu.cn
+[dropped rk809-sound and not specified pmic sound properties]
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../boot/dts/rockchip/rk3566-rock-3c.dts | 726 ++++++++++++++++++
+ 2 files changed, 727 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -81,6 +81,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-qu
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rock-3c.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-model-a.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+@@ -0,0 +1,726 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/soc/rockchip,vop2.h>
++#include "rk3566.dtsi"
++
++/ {
++ model = "Radxa ROCK 3C";
++ compatible = "radxa,rock-3c", "rockchip,rk3566";
++
++ aliases {
++ ethernet0 = &gmac1;
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc0;
++ mmc2 = &sdmmc1;
++ };
++
++ chosen: chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ gmac1_clkin: external-gmac1-clock {
++ compatible = "fixed-clock";
++ clock-frequency = <125000000>;
++ clock-output-names = "gmac1_clkin";
++ #clock-cells = <0>;
++ };
++
++ hdmi-con {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con_in: endpoint {
++ remote-endpoint = <&hdmi_out_con>;
++ };
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-0 {
++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
++ function = LED_FUNCTION_HEARTBEAT;
++ color = <LED_COLOR_ID_BLUE>;
++ linux,default-trigger = "heartbeat";
++ pinctrl-names = "default";
++ pinctrl-0 = <&user_led2>;
++ };
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ clocks = <&rk809 1>;
++ clock-names = "ext_clock";
++ pinctrl-names = "default";
++ pinctrl-0 = <&wifi_reg_on_h>;
++ post-power-on-delay-ms = <100>;
++ power-off-delay-us = <5000000>;
++ reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++
++ vcc5v_dcin: vcc5v-dcin-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v_dcin";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ vcc3v3_pcie: vcc3v3-pcie-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_pwr_en>;
++ regulator-name = "vcc3v3_pcie";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++ };
++
++ vcc3v3_sys: vcc3v3-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_sys: vcc5v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v_dcin>;
++ };
++
++ vcc5v0_usb30_host: vcc5v0-usb30-host-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc5v0_usb30_host_en>;
++ regulator-name = "vcc5v0_usb30_host";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc5v0_usb_otg_en>;
++ regulator-name = "vcc5v0_usb_otg";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc_cam: vcc-cam-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc_cam_en>;
++ regulator-name = "vcc_cam";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_mipi: vcc-mipi-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc_mipi_en>;
++ regulator-name = "vcc_mipi";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&combphy1 {
++ status = "okay";
++};
++
++&combphy2 {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu1 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu2 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu3 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&gmac1 {
++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
++ clock_in_out = "input";
++ phy-handle = <&rgmii_phy1>;
++ phy-mode = "rgmii-id";
++ phy-supply = <&vcc_3v3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac1m1_miim
++ &gmac1m1_tx_bus2
++ &gmac1m1_rx_bus2
++ &gmac1m1_rgmii_clk
++ &gmac1m1_rgmii_bus
++ &gmac1m1_clkinout>;
++ status = "okay";
++};
++
++&gpu {
++ mali-supply = <&vdd_gpu>;
++ status = "okay";
++};
++
++&hdmi {
++ avdd-0v9-supply = <&vdda0v9_image>;
++ avdd-1v8-supply = <&vcca1v8_image>;
++ status = "okay";
++};
++
++&hdmi_in {
++ hdmi_in_vp0: endpoint {
++ remote-endpoint = <&vp0_out_hdmi>;
++ };
++};
++
++&hdmi_out {
++ hdmi_out_con: endpoint {
++ remote-endpoint = <&hdmi_con_in>;
++ };
++};
++
++&hdmi_sound {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++
++ vdd_cpu: regulator@1c {
++ compatible = "tcs,tcs4525";
++ reg = <0x1c>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <800000>;
++ regulator-max-microvolt = <1150000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ rk809: pmic@20 {
++ compatible = "rockchip,rk809";
++ reg = <0x20>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
++ clock-output-names = "rk808-clkout1", "rk808-clkout2";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
++ system-power-controller;
++ vcc1-supply = <&vcc3v3_sys>;
++ vcc2-supply = <&vcc3v3_sys>;
++ vcc3-supply = <&vcc3v3_sys>;
++ vcc4-supply = <&vcc3v3_sys>;
++ vcc5-supply = <&vcc3v3_sys>;
++ vcc6-supply = <&vcc3v3_sys>;
++ vcc7-supply = <&vcc3v3_sys>;
++ vcc8-supply = <&vcc3v3_sys>;
++ vcc9-supply = <&vcc3v3_sys>;
++ wakeup-source;
++ #clock-cells = <1>;
++
++ regulators {
++ vdd_logic: DCDC_REG1 {
++ regulator-name = "vdd_logic";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vdd_gpu: DCDC_REG2 {
++ regulator-name = "vdd_gpu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vcc_ddr: DCDC_REG3 {
++ regulator-name = "vcc_ddr";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vdd_npu: DCDC_REG4 {
++ regulator-name = "vdd_npu";
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_1v8: DCDC_REG5 {
++ regulator-name = "vcc_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda0v9_image: LDO_REG1 {
++ regulator-name = "vdda0v9_image";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda_0v9: LDO_REG2 {
++ regulator-name = "vdda_0v9";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda0v9_pmu: LDO_REG3 {
++ regulator-name = "vdda0v9_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vccio_acodec: LDO_REG4 {
++ regulator-name = "vccio_acodec";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vccio_sd: LDO_REG5 {
++ regulator-name = "vccio_sd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc3v3_pmu: LDO_REG6 {
++ regulator-name = "vcc3v3_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vcca_1v8: LDO_REG7 {
++ regulator-name = "vcca_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcca1v8_pmu: LDO_REG8 {
++ regulator-name = "vcca1v8_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vcca1v8_image: LDO_REG9 {
++ regulator-name = "vcca1v8_image";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_3v3: SWITCH_REG1 {
++ regulator-name = "vcc_3v3";
++ regulator-always-on;
++ regulator-boot-on;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc3v3_sd: SWITCH_REG2 {
++ regulator-name = "vcc3v3_sd";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++
++ eeprom: eeprom@50 {
++ compatible = "belling,bl24c16a", "atmel,24c16";
++ reg = <0x50>;
++ pagesize = <16>;
++ };
++};
++
++&i2s0_8ch {
++ status = "okay";
++};
++
++&i2s1_8ch {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
++ rockchip,trcm-sync-tx-only;
++ status = "okay";
++};
++
++&mdio1 {
++ rgmii_phy1: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <0x1>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <100000>;
++ reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pcie2x1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_reset_h>;
++ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie>;
++ status = "okay";
++};
++
++&pinctrl {
++ bluetooth {
++ bt_reg_on_h: bt-reg-on-h {
++ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_wake_host_h: bt-wake-host-h {
++ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_host_wake_h: bt-host-wake-h {
++ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ cam {
++ vcc_cam_en: vcc_cam_en {
++ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ display {
++ vcc_mipi_en: vcc_mipi_en {
++ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ leds {
++ user_led2: user-led2 {
++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pcie {
++ pcie_pwr_en: pcie-pwr-en {
++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie_reset_h: pcie-reset-h {
++ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ pmic_int_l: pmic-int-l {
++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ usb {
++ vcc5v0_usb30_host_en: vcc5v0-usb30-host-en {
++ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ vcc5v0_usb_otg_en: vcc5v0-usb-otg-en {
++ rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ wifi {
++ wifi_host_wake_h: wifi-host-wake-h {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wifi_reg_on_h: wifi-reg-on-h {
++ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&pmu_io_domains {
++ pmuio1-supply = <&vcc3v3_pmu>;
++ pmuio2-supply = <&vcca1v8_pmu>;
++ vccio1-supply = <&vccio_acodec>;
++ vccio2-supply = <&vcc_1v8>;
++ vccio3-supply = <&vccio_sd>;
++ vccio4-supply = <&vcca1v8_pmu>;
++ vccio5-supply = <&vcc_3v3>;
++ vccio6-supply = <&vcc_3v3>;
++ vccio7-supply = <&vcc_3v3>;
++ status = "okay";
++};
++
++&saradc {
++ vref-supply = <&vcca_1v8>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ max-frequency = <200000000>;
++ mmc-hs200-1_8v;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&sdmmc0 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ disable-wp;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
++ sd-uhs-sdr50;
++ vmmc-supply = <&vcc3v3_sys>;
++ vqmmc-supply = <&vccio_sd>;
++ status = "okay";
++};
++
++&sdmmc1 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ keep-power-in-suspend;
++ mmc-pwrseq = <&sdio_pwrseq>;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc3v3_sys>;
++ vqmmc-supply = <&vcca1v8_pmu>;
++ status = "okay";
++};
++
++&sfc {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ flash@0 {
++ compatible = "jedec,spi-nor";
++ reg = <0x0>;
++ spi-max-frequency = <120000000>;
++ spi-rx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
++ };
++};
++
++&tsadc {
++ rockchip,hw-tshut-mode = <1>;
++ rockchip,hw-tshut-polarity = <0>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1m0_ctsn &uart1m0_rtsn &uart1m0_xfer>;
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&usb_host0_ehci {
++ status = "okay";
++};
++
++&usb_host0_ohci {
++ status = "okay";
++};
++
++&usb_host0_xhci {
++ dr_mode = "host";
++ status = "okay";
++};
++
++&usb_host1_ehci {
++ status = "okay";
++};
++
++&usb_host1_ohci {
++ status = "okay";
++};
++
++&usb_host1_xhci {
++ status = "okay";
++};
++
++&usb2phy0 {
++ status = "okay";
++};
++
++&usb2phy0_host {
++ phy-supply = <&vcc5v0_usb30_host>;
++ status = "okay";
++};
++
++&usb2phy0_otg {
++ phy-supply = <&vcc5v0_usb_otg>;
++ status = "okay";
++};
++
++&usb2phy1 {
++ status = "okay";
++};
++
++&usb2phy1_host {
++ phy-supply = <&vcc5v0_usb30_host>;
++ status = "okay";
++};
++
++&usb2phy1_otg {
++ phy-supply = <&vcc5v0_usb30_host>;
++ status = "okay";
++};
++
++&vop {
++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
++ status = "okay";
++};
++
++&vop_mmu {
++ status = "okay";
++};
++
++&vp0 {
++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
++ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
++ remote-endpoint = <&hdmi_in_vp0>;
++ };
++};
diff --git a/target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch b/target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch
new file mode 100644
index 0000000000..936fe91c5d
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch
@@ -0,0 +1,26 @@
+From 06f6dd4d607766a527e37529f2f3f90dd1464293 Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Sun, 23 Jun 2024 11:33:29 +0900
+Subject: [PATCH] arm64: dts: rockchip: change spi-max-frequency for Radxa ROCK
+ 3C
+
+SPI NOR flash chip may vary, so use safe(lowest) spi-max-frequency.
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240623023329.1044-3-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+@@ -633,7 +633,7 @@
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+- spi-max-frequency = <120000000>;
++ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch b/target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch
new file mode 100644
index 0000000000..746078cf9e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch
@@ -0,0 +1,657 @@
+From 1a5c8d307c83c808a32686ed51afb4bac2092d39 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Tue, 21 May 2024 20:28:05 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add Radxa ZERO 3W/3E
+
+The Radxa ZERO 3W/3E is an ultra-small, high-performance single board
+computer based on the Rockchip RK3566, with a compact form factor and
+rich interfaces.
+
+The ZERO 3W and ZERO 3E are basically the same size and model, but
+differ only in storage and network interfaces.
+
+- eMMC (3W)
+- SD-card (both)
+- Ethernet (3E)
+- WiFi/BT (3W)
+
+Add initial support for eMMC, SD-card, Ethernet, HDMI and USB.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521202810.1225636-3-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 2 +
+ .../dts/rockchip/rk3566-radxa-zero-3.dtsi | 463 ++++++++++++++++++
+ .../dts/rockchip/rk3566-radxa-zero-3e.dts | 51 ++
+ .../dts/rockchip/rk3566-radxa-zero-3w.dts | 91 ++++
+ 4 files changed, 607 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -80,6 +80,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pi
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-zero-3e.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-zero-3w.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rock-3c.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -0,0 +1,463 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/soc/rockchip,vop2.h>
++#include "rk3566.dtsi"
++
++/ {
++ aliases {
++ mmc0 = &sdmmc0;
++ };
++
++ chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ hdmi-con {
++ compatible = "hdmi-connector";
++ type = "d";
++
++ port {
++ hdmi_con_in: endpoint {
++ remote-endpoint = <&hdmi_out_con>;
++ };
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&user_led2>;
++
++ led-green {
++ color = <LED_COLOR_ID_GREEN>;
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++
++ vcc_1v8: regulator-1v8-vcc {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_1v8_p>;
++ };
++
++ vcca_1v8: regulator-1v8-vcca {
++ compatible = "regulator-fixed";
++ regulator-name = "vcca_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_1v8_p>;
++ };
++
++ vcca1v8_image: regulator-1v8-vcca-image {
++ compatible = "regulator-fixed";
++ regulator-name = "vcca1v8_image";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_1v8_p>;
++ };
++
++ vcc_3v3: regulator-3v3-vcc {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_3v3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++ };
++
++ vcc_sys: regulator-5v0-vcc-sys {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++};
++
++&combphy1 {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu1 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu2 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu3 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&gpu {
++ mali-supply = <&vdd_gpu_npu>;
++ status = "okay";
++};
++
++&hdmi {
++ avdd-0v9-supply = <&vdda_0v9>;
++ 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";
++
++ rk817: pmic@20 {
++ compatible = "rockchip,rk817";
++ reg = <0x20>;
++ #clock-cells = <1>;
++ clock-output-names = "rk817-clkout1", "rk817-clkout2";
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_int_l>;
++ system-power-controller;
++ wakeup-source;
++
++ vcc1-supply = <&vcc_sys>;
++ vcc2-supply = <&vcc_sys>;
++ vcc3-supply = <&vcc_sys>;
++ vcc4-supply = <&vcc_sys>;
++ vcc5-supply = <&vcc_sys>;
++ vcc6-supply = <&vcc_sys>;
++ vcc7-supply = <&vcc_sys>;
++ vcc8-supply = <&vcc_sys>;
++ vcc9-supply = <&vcc5v_midu>;
++
++ regulators {
++ vdd_logic: DCDC_REG1 {
++ regulator-name = "vdd_logic";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vdd_gpu_npu: DCDC_REG2 {
++ regulator-name = "vdd_gpu_npu";
++ 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;
++ };
++ };
++
++ vcc3v3_sys: DCDC_REG4 {
++ regulator-name = "vcc3v3_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vcca1v8_pmu: LDO_REG1 {
++ 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>;
++ };
++ };
++
++ 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-always-on;
++ regulator-boot-on;
++ 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>;
++ };
++ };
++
++ vcc_1v8_p: LDO_REG7 {
++ regulator-name = "vcc_1v8_p";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc1v8_dvp: LDO_REG8 {
++ regulator-name = "vcc1v8_dvp";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc2v8_dvp: LDO_REG9 {
++ regulator-name = "vcc2v8_dvp";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc5v_midu: BOOST {
++ regulator-name = "vcc5v_midu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vbus: OTG_SWITCH {
++ regulator-name = "vbus";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++
++ vdd_cpu: regulator@40 {
++ compatible = "rockchip,rk8600";
++ reg = <0x40>;
++ 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 = <&vcc_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2s0_8ch {
++ status = "okay";
++};
++
++&pinctrl {
++ leds {
++ user_led2: user-led2 {
++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ pmic_int_l: pmic-int-l {
++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++};
++
++&pmu_io_domains {
++ pmuio1-supply = <&vcc3v3_pmu>;
++ pmuio2-supply = <&vcca1v8_pmu>;
++ vccio1-supply = <&vccio_acodec>;
++ vccio2-supply = <&vcc_1v8>;
++ vccio3-supply = <&vccio_sd>;
++ vccio4-supply = <&vcc_1v8>;
++ vccio5-supply = <&vcc_3v3>;
++ vccio6-supply = <&vcc_3v3>;
++ vccio7-supply = <&vcc_3v3>;
++ status = "okay";
++};
++
++&saradc {
++ vref-supply = <&vcca_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>;
++ vmmc-supply = <&vcc3v3_sys>;
++ vqmmc-supply = <&vccio_sd>;
++ status = "okay";
++};
++
++&tsadc {
++ rockchip,hw-tshut-mode = <1>;
++ rockchip,hw-tshut-polarity = <0>;
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&usb_host0_xhci {
++ dr_mode = "peripheral";
++ status = "okay";
++};
++
++&usb_host1_xhci {
++ status = "okay";
++};
++
++&usb2phy0 {
++ status = "okay";
++};
++
++&usb2phy0_host {
++ status = "okay";
++};
++
++&usb2phy0_otg {
++ status = "okay";
++};
++
++&vop {
++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
++ status = "okay";
++};
++
++&vop_mmu {
++ status = "okay";
++};
++
++&vp0 {
++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
++ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
++ remote-endpoint = <&hdmi_in_vp0>;
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
+@@ -0,0 +1,51 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include "rk3566-radxa-zero-3.dtsi"
++
++/ {
++ model = "Radxa ZERO 3E";
++ compatible = "radxa,zero-3e", "rockchip,rk3566";
++
++ aliases {
++ ethernet0 = &gmac1;
++ };
++};
++
++&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";
++};
++
++&mdio1 {
++ rgmii_phy1: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac1_rstn>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <50000>;
++ reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pinctrl {
++ gmac1 {
++ gmac1_rstn: gmac1-rstn {
++ rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
+@@ -0,0 +1,91 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include "rk3566-radxa-zero-3.dtsi"
++
++/ {
++ model = "Radxa ZERO 3W";
++ compatible = "radxa,zero-3w", "rockchip,rk3566";
++
++ aliases {
++ mmc1 = &sdhci;
++ mmc2 = &sdmmc1;
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ clocks = <&rk817 1>;
++ clock-names = "ext_clock";
++ pinctrl-names = "default";
++ pinctrl-0 = <&wifi_reg_on_h>;
++ post-power-on-delay-ms = <100>;
++ power-off-delay-us = <5000000>;
++ reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pinctrl {
++ bluetooth {
++ bt_reg_on_h: bt-reg-on-h {
++ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_wake_host_h: bt-wake-host-h {
++ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ host_wake_bt_h: host-wake-bt-h {
++ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ wifi {
++ wifi_reg_on_h: wifi-reg-on-h {
++ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wifi_wake_host_h: wifi-wake-host-h {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&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>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&sdmmc1 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ keep-power-in-suspend;
++ mmc-pwrseq = <&sdio_pwrseq>;
++ no-mmc;
++ no-sd;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
++ uart-has-rtscts;
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch b/target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch
new file mode 100644
index 0000000000..b96e8e1774
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch
@@ -0,0 +1,64 @@
+From 060c1950037e4c54ca4d8186a8f46269e35db901 Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Fri, 21 Jun 2024 07:44:35 +0900
+Subject: [PATCH] arm64: dts: rockchip: fix mmc aliases for Radxa ZERO 3E/3W
+
+align with other Radxa products.
+
+- mmc0 is eMMC
+- mmc1 is microSD
+
+for ZERO 3E, there is no eMMC, but aliases should start at 0, so mmc0
+is microSD as exception.
+
+Fixes: 1a5c8d307c83 ("arm64: dts: rockchip: Add Radxa ZERO 3W/3E")
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+
+Changes in v3:
+- fix syntax error in rk3566-radxa-zero-3e.dts
+Changes in v2:
+- microSD is mmc0 instead of mmc1 for ZERO 3E
+
+Link: https://lore.kernel.org/r/20240620224435.2752-1-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi | 4 ----
+ arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts | 1 +
+ arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts | 3 ++-
+ 3 files changed, 3 insertions(+), 5 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -6,10 +6,6 @@
+ #include "rk3566.dtsi"
+
+ / {
+- aliases {
+- mmc0 = &sdmmc0;
+- };
+-
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
+@@ -10,6 +10,7 @@
+
+ aliases {
+ ethernet0 = &gmac1;
++ mmc0 = &sdmmc0;
+ };
+ };
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
+@@ -9,7 +9,8 @@
+ compatible = "radxa,zero-3w", "rockchip,rk3566";
+
+ aliases {
+- mmc1 = &sdhci;
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch b/target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch
new file mode 100644
index 0000000000..4c5107ab35
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch
@@ -0,0 +1,101 @@
+From f7c742cbe664ebdedc075945e75443683d1175f7 Mon Sep 17 00:00:00 2001
+From: Trevor Woerner <twoerner@gmail.com>
+Date: Wed, 19 Jun 2024 21:32:49 -0400
+Subject: [PATCH] arm64: dts: rockchip: add gpio-line-names to radxa-zero-3
+
+Add names to the pins of the general-purpose expansion header as given
+in the Radxa documentation[1] following the conventions in the kernel[2]
+to make it easier for users to correlate pins with functions when using
+utilities such as 'gpioinfo'.
+
+[1] https://docs.radxa.com/en/zero/zero3/hardware-design/hardware-interface
+[2] https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt
+
+Signed-off-by: Trevor Woerner <twoerner@gmail.com>
+Link: https://lore.kernel.org/r/20240620013301.33653-1-twoerner@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../dts/rockchip/rk3566-radxa-zero-3.dtsi | 72 +++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -105,6 +105,78 @@
+ cpu-supply = <&vdd_cpu>;
+ };
+
++&gpio0 {
++ gpio-line-names =
++ /* GPIO0_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_D0 - D7 */
++ "pin-10 [GPIO0_D0]", "pin-08 [GPIO0_D1]", "",
++ "", "", "", "", "";
++};
++
++&gpio1 {
++ gpio-line-names =
++ /* GPIO1_A0 - A7 */
++ "pin-03 [GPIO1_A0]", "pin-05 [GPIO1_A1]", "",
++ "", "pin-37 [GPIO1_A4]", "",
++ "", "",
++ /* GPIO1_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio2 {
++ gpio-line-names =
++ /* GPIO2_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO2_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO2_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO2_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio3 {
++ gpio-line-names =
++ /* GPIO3_A0 - A7 */
++ "", "pin-11 [GPIO3_A1]", "pin-13 [GPIO3_A2]",
++ "pin-12 [GPIO3_A3]", "pin-35 [GPIO3_A4]", "pin-40 [GPIO3_A5]",
++ "pin-38 [GPIO3_A6]", "pin-36 [GPIO3_A7]",
++ /* GPIO3_B0 - B7 */
++ "pin-15 [GPIO3_B0]", "pin-16 [GPIO3_B1]", "pin-18 [GPIO3_B2]",
++ "pin-29 [GPIO3_B3]", "pin-31 [GPIO3_B4]", "",
++ "", "",
++ /* GPIO3_C0 - C7 */
++ "", "pin-22 [GPIO3_C1]", "pin-32 [GPIO3_C2]",
++ "pin-33 [GPIO3_C3]", "pin-07 [GPIO3_C4]", "",
++ "", "",
++ /* GPIO3_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio4 {
++ gpio-line-names =
++ /* GPIO4_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO4_B0 - B7 */
++ "", "", "pin-27 [GPIO4_B2]",
++ "pin-28 [GPIO4_B3]", "", "", "", "",
++ /* GPIO4_C0 - C7 */
++ "", "", "pin-23 [GPIO4_C2]",
++ "pin-19 [GPIO4_C3]", "", "pin-21 [GPIO4_C5]",
++ "pin-24 [GPIO4_C6]", "",
++ /* GPIO4_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
+ &gpu {
+ mali-supply = <&vdd_gpu_npu>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch b/target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch
new file mode 100644
index 0000000000..e93a055c3e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch
@@ -0,0 +1,815 @@
+From 846ef7748fa9124c8eea76e2d5e833fa69b3ef7c Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Thu, 27 Jun 2024 21:17:31 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add Radxa ROCK 3B
+
+The Radxa ROCK 3B is a single-board computer based on the Pico-ITX form
+factor (100mm x 75mm). Two versions of the ROCK 3B exists, a community
+version based on the RK3568 SoC and an industrial version based on the
+RK3568J SoC.
+
+Add initial support for eMMC, SD-card, Ethernet, HDMI, PCIe and USB.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240627211737.1985549-3-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../boot/dts/rockchip/rk3568-rock-3b.dts | 781 ++++++++++++++++++
+ 2 files changed, 782 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -100,6 +100,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-od
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+@@ -0,0 +1,781 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/soc/rockchip,vop2.h>
++#include "rk3568.dtsi"
++
++/ {
++ model = "Radxa ROCK 3B";
++ compatible = "radxa,rock-3b", "rockchip,rk3568";
++
++ aliases {
++ ethernet0 = &gmac0;
++ ethernet1 = &gmac1;
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc0;
++ mmc2 = &sdmmc2;
++ };
++
++ chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ hdmi-con {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con_in: endpoint {
++ remote-endpoint = <&hdmi_out_con>;
++ };
++ };
++ };
++
++ ir-receiver {
++ compatible = "gpio-ir-receiver";
++ gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm3_ir>;
++ };
++
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&led>;
++
++ led-0 {
++ color = <LED_COLOR_ID_GREEN>;
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++
++ /* pi6c pcie clock generator */
++ vcc3v3_pi6c_03: regulator-3v3-vcc-pi6c-03 {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_pwren_h>;
++ regulator-name = "vcc3v3_pi6c_03";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <10000>;
++ vin-supply = <&vcc5v0_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>;
++ };
++
++ vcc3v3_sys2: regulator-3v3-vcc-sys2 {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_sys2";
++ 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_usb_host: regulator-5v0-vcc-usb-host {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_host_pwren_h>;
++ regulator-name = "vcc5v0_usb_host";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_usb_otg: regulator-5v0-vcc-usb-otg {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_otg_pwren_h>;
++ regulator-name = "vcc5v0_usb_otg";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ clocks = <&rk809 1>;
++ clock-names = "ext_clock";
++ pinctrl-names = "default";
++ pinctrl-0 = <&wifi_reg_on_h>;
++ post-power-on-delay-ms = <100>;
++ power-off-delay-us = <5000000>;
++ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
++ };
++
++ 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>;
++ };
++ };
++};
++
++&combphy0 {
++ status = "okay";
++};
++
++&combphy1 {
++ status = "okay";
++};
++
++&combphy2 {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu1 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu2 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu3 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&gmac0 {
++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
++ clock_in_out = "input";
++ phy-handle = <&rgmii_phy0>;
++ phy-mode = "rgmii-id";
++ phy-supply = <&vcc_3v3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac0_miim
++ &gmac0_tx_bus2
++ &gmac0_rx_bus2
++ &gmac0_rgmii_clk
++ &gmac0_rgmii_bus
++ &gmac0_clkinout>;
++ status = "okay";
++};
++
++&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 = <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>;
++ 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 = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_int_l>, <&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-always-on;
++ regulator-boot-on;
++ 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-always-on;
++ regulator-boot-on;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++};
++
++&i2c5 {
++ status = "okay";
++
++ hym8563: rtc@51 {
++ compatible = "haoyu,hym8563";
++ reg = <0x51>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
++ #clock-cells = <0>;
++ clock-output-names = "rtcic_32kout";
++ pinctrl-names = "default";
++ pinctrl-0 = <&rtcic_int_l>;
++ wakeup-source;
++ };
++};
++
++&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";
++};
++
++&mdio0 {
++ rgmii_phy0: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <1>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <50000>;
++ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&mdio1 {
++ rgmii_phy1: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <1>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <50000>;
++ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pcie2x1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie20m1_pins>;
++ reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_sys2>;
++ status = "okay";
++};
++
++&pcie30phy {
++ status = "okay";
++};
++
++&pcie3x2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie30x2m1_pins>;
++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++};
++
++&pinctrl {
++ bluetooth {
++ bt_reg_on_h: bt-reg-on-h {
++ rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_wake_host_h: bt-wake-host-h {
++ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ host_wake_bt_h: host-wake-bt-h {
++ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ ir-receiver {
++ pwm3_ir: pwm3-ir {
++ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ leds {
++ led: led {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pcie {
++ pcie_pwren_h: pcie-pwren-h {
++ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pcie20 {
++ pcie20m1_pins: pcie20m1-pins {
++ rockchip,pins =
++ <2 RK_PD0 4 &pcfg_pull_none>,
++ <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>,
++ <2 RK_PD1 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x2 {
++ pcie30x2m1_pins: pcie30x2m1-pins {
++ rockchip,pins =
++ <2 RK_PD4 4 &pcfg_pull_none>,
++ <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>,
++ <2 RK_PD5 4 &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ pmic_int_l: pmic-int-l {
++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ rtc {
++ rtcic_int_l: rtcic-int-l {
++ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ usb {
++ usb_host_pwren_h: usb-host-pwren-h {
++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ usb_otg_pwren_h: usb-otg-pwren-h {
++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ wifi {
++ wifi_reg_on_h: wifi-reg-on-h {
++ rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wifi_wake_host_h: wifi-wake-host-h {
++ rockchip,pins = <3 RK_PD5 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";
++};
++
++&saradc {
++ vref-supply = <&vcca_1v8>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ max-frequency = <200000000>;
++ mmc-hs200-1_8v;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&sdmmc0 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ disable-wp;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
++ vmmc-supply = <&vcc3v3_sd>;
++ vqmmc-supply = <&vccio_sd>;
++ status = "okay";
++};
++
++&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_clk &sdmmc2m0_cmd>;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc3v3_sys2>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "disabled";
++};
++
++&sfc {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ flash@0 {
++ compatible = "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <104000000>;
++ spi-rx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
++ };
++};
++
++&tsadc {
++ rockchip,hw-tshut-mode = <1>;
++ rockchip,hw-tshut-polarity = <0>;
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&uart8 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn &uart8m0_rtsn>;
++ uart-has-rtscts;
++ status = "disabled";
++};
++
++&usb_host0_ehci {
++ status = "okay";
++};
++
++&usb_host0_ohci {
++ status = "okay";
++};
++
++&usb_host0_xhci {
++ extcon = <&usb2phy0>;
++ 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_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 = <ROCKCHIP_VOP2_EP_HDMI0>;
++ remote-endpoint = <&hdmi_in_vp0>;
++ };
++};
diff --git a/target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch b/target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch
new file mode 100644
index 0000000000..d03039d978
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch
@@ -0,0 +1,29 @@
+From 626a479873b6a680b3227c4852bde4a1f2c17fdf Mon Sep 17 00:00:00 2001
+From: Chukun Pan <amadeus@jmu.edu.cn>
+Date: Fri, 19 Apr 2024 18:30:19 +0800
+Subject: [PATCH] arm64: dts: rockchip: correct the model name for Radxa ROCK
+ 3A
+
+According to https://radxa.com/products/rock3/3a,
+the name of this board should be "Radxa ROCK 3A".
+
+Suggested-by: FUKAUMI Naoki <naoki@radxa.com>
+Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20240419103019.992586-3-amadeus@jmu.edu.cn
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+@@ -8,7 +8,7 @@
+ #include "rk3568.dtsi"
+
+ / {
+- model = "Radxa ROCK3 Model A";
++ model = "Radxa ROCK 3A";
+ compatible = "radxa,rock3a", "rockchip,rk3568";
+
+ aliases {
diff --git a/target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch b/target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch
new file mode 100644
index 0000000000..6becaf6e86
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch
@@ -0,0 +1,78 @@
+From 2dc66a5ab2c6fb532fbb16107ee7efcb0effbfa5 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:22 +0100
+Subject: [PATCH] clk: rockchip: rk3588: fix CLK_NR_CLKS usage
+
+CLK_NR_CLKS is not part of the DT bindings and needs to be removed
+from it, just like it recently happened for other platforms. This
+takes care of it by introducing a new function identifying the
+maximum used clock ID at runtime.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-2-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 5 ++++-
+ drivers/clk/rockchip/clk.c | 17 +++++++++++++++++
+ drivers/clk/rockchip/clk.h | 2 ++
+ 3 files changed, 23 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -2458,15 +2458,18 @@ static struct rockchip_clk_branch rk3588
+ static void __init rk3588_clk_init(struct device_node *np)
+ {
+ struct rockchip_clk_provider *ctx;
++ unsigned long clk_nr_clks;
+ void __iomem *reg_base;
+
++ clk_nr_clks = rockchip_clk_find_max_clk_id(rk3588_clk_branches,
++ ARRAY_SIZE(rk3588_clk_branches)) + 1;
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("%s: could not map cru region\n", __func__);
+ return;
+ }
+
+- ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
++ ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+ if (IS_ERR(ctx)) {
+ pr_err("%s: rockchip clk init failed\n", __func__);
+ iounmap(reg_base);
+--- a/drivers/clk/rockchip/clk.c
++++ b/drivers/clk/rockchip/clk.c
+@@ -429,6 +429,23 @@ void rockchip_clk_register_plls(struct r
+ }
+ EXPORT_SYMBOL_GPL(rockchip_clk_register_plls);
+
++unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
++ unsigned int nr_clk)
++{
++ unsigned long max = 0;
++ unsigned int idx;
++
++ for (idx = 0; idx < nr_clk; idx++, list++) {
++ if (list->id > max)
++ max = list->id;
++ if (list->child && list->child->id > max)
++ max = list->id;
++ }
++
++ return max;
++}
++EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id);
++
+ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+ struct rockchip_clk_branch *list,
+ unsigned int nr_clk)
+--- a/drivers/clk/rockchip/clk.h
++++ b/drivers/clk/rockchip/clk.h
+@@ -973,6 +973,8 @@ struct rockchip_clk_provider *rockchip_c
+ void __iomem *base, unsigned long nr_clks);
+ void rockchip_clk_of_add_provider(struct device_node *np,
+ struct rockchip_clk_provider *ctx);
++unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
++ unsigned int nr_clk);
+ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+ struct rockchip_clk_branch *list,
+ unsigned int nr_clk);
diff --git a/target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch b/target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch
new file mode 100644
index 0000000000..c8117f08c5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch
@@ -0,0 +1,27 @@
+From 11a29dc2e41ead2be78cfa9d532edf924b461acc Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:23 +0100
+Subject: [PATCH] dt-bindings: clock: rk3588: drop CLK_NR_CLKS
+
+CLK_NR_CLKS should not be part of the binding. Let's drop it, since
+the kernel code no longer uses it either.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-3-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ include/dt-bindings/clock/rockchip,rk3588-cru.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/include/dt-bindings/clock/rockchip,rk3588-cru.h
++++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
+@@ -734,8 +734,6 @@
+ #define PCLK_AV1_PRE 719
+ #define HCLK_SDIO_PRE 720
+
+-#define CLK_NR_CLKS (HCLK_SDIO_PRE + 1)
+-
+ /* scmi-clocks indices */
+
+ #define SCMI_CLK_CPUL 0
diff --git a/target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch b/target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch
new file mode 100644
index 0000000000..b960bc6197
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch
@@ -0,0 +1,26 @@
+From c81798cf9dd2f324934585b2b52a0398caefb88e Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:24 +0100
+Subject: [PATCH] dt-bindings: clock: rk3588: add missing PCLK_VO1GRF
+
+Add PCLK_VO1GRF to complement PCLK_VO0GRF. This will be needed
+for HDMI support.
+
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-4-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ include/dt-bindings/clock/rockchip,rk3588-cru.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/dt-bindings/clock/rockchip,rk3588-cru.h
++++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
+@@ -733,6 +733,7 @@
+ #define ACLK_AV1_PRE 718
+ #define PCLK_AV1_PRE 719
+ #define HCLK_SDIO_PRE 720
++#define PCLK_VO1GRF 721
+
+ /* scmi-clocks indices */
+
diff --git a/target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch b/target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch
new file mode 100644
index 0000000000..e12b73fb30
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch
@@ -0,0 +1,59 @@
+From 326be62eaf2e89767b7b9223f88eaf3c041b98d2 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:25 +0100
+Subject: [PATCH] clk: rockchip: rk3588: fix pclk_vo0grf and pclk_vo1grf
+
+Currently pclk_vo1grf is not exposed, but it should be referenced
+from the vo1_grf syscon, which needs it enabled. That syscon is
+required for HDMI RX and TX functionality among other things.
+
+Apart from that pclk_vo0grf and pclk_vo1grf are both linked gates
+and need the VO's hclk enabled in addition to their parent clock.
+
+No Fixes tag has been added, since the logic requiring these clocks
+is not yet upstream anyways.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-5-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -1851,8 +1851,6 @@ static struct rockchip_clk_branch rk3588
+ RK3588_CLKGATE_CON(56), 0, GFLAGS),
+ GATE(PCLK_TRNG0, "pclk_trng0", "pclk_vo0_root", 0,
+ RK3588_CLKGATE_CON(56), 1, GFLAGS),
+- GATE(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", CLK_IGNORE_UNUSED,
+- RK3588_CLKGATE_CON(55), 10, GFLAGS),
+ COMPOSITE(CLK_I2S4_8CH_TX_SRC, "clk_i2s4_8ch_tx_src", gpll_aupll_p, 0,
+ RK3588_CLKSEL_CON(118), 5, 1, MFLAGS, 0, 5, DFLAGS,
+ RK3588_CLKGATE_CON(56), 11, GFLAGS),
+@@ -1998,8 +1996,6 @@ static struct rockchip_clk_branch rk3588
+ RK3588_CLKGATE_CON(60), 9, GFLAGS),
+ GATE(PCLK_TRNG1, "pclk_trng1", "pclk_vo1_root", 0,
+ RK3588_CLKGATE_CON(60), 10, GFLAGS),
+- GATE(0, "pclk_vo1grf", "pclk_vo1_root", CLK_IGNORE_UNUSED,
+- RK3588_CLKGATE_CON(59), 12, GFLAGS),
+ GATE(PCLK_S_EDP0, "pclk_s_edp0", "pclk_vo1_s_root", 0,
+ RK3588_CLKGATE_CON(59), 14, GFLAGS),
+ GATE(PCLK_S_EDP1, "pclk_s_edp1", "pclk_vo1_s_root", 0,
+@@ -2447,12 +2443,14 @@ static struct rockchip_clk_branch rk3588
+ GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 4, GFLAGS),
+ GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 5, GFLAGS),
+ GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", "aclk_vop_low_root", 0, RK3588_CLKGATE_CON(55), 9, GFLAGS),
+- GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", "hclk_vop_root", 0, RK3588_CLKGATE_CON(55), 5, GFLAGS),
++ GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", "hclk_vop_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS),
+ GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", "aclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(59), 6, GFLAGS),
+- GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", "hclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(59), 9, GFLAGS),
++ GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", "hclk_vo1usb_top_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS),
+ GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 1, GFLAGS),
+ GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 4, GFLAGS),
+ GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", "hclk_nvm", 0, RK3588_CLKGATE_CON(75), 1, GFLAGS),
++ GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", "hclk_vo0", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
++ GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", "hclk_vo1", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
+ };
+
+ static void __init rk3588_clk_init(struct device_node *np)
diff --git a/target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch b/target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch
new file mode 100644
index 0000000000..27aa28edd5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch
@@ -0,0 +1,26 @@
+From 2a6e4710672242281347103b64e01693aa823a29 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:26 +0100
+Subject: [PATCH] clk: rockchip: rk3588: fix indent
+
+pclk_mailbox2 is the only RK3588 clock indented with one tab instead of
+two tabs. Let's fix this.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-6-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -1004,7 +1004,7 @@ static struct rockchip_clk_branch rk3588
+ GATE(PCLK_MAILBOX1, "pclk_mailbox1", "pclk_top_root", 0,
+ RK3588_CLKGATE_CON(16), 12, GFLAGS),
+ GATE(PCLK_MAILBOX2, "pclk_mailbox2", "pclk_top_root", 0,
+- RK3588_CLKGATE_CON(16), 13, GFLAGS),
++ RK3588_CLKGATE_CON(16), 13, GFLAGS),
+ GATE(PCLK_PMU2, "pclk_pmu2", "pclk_top_root", CLK_IS_CRITICAL,
+ RK3588_CLKGATE_CON(19), 3, GFLAGS),
+ GATE(PCLK_PMUCM0_INTMUX, "pclk_pmucm0_intmux", "pclk_top_root", CLK_IS_CRITICAL,
diff --git a/target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch b/target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch
new file mode 100644
index 0000000000..949041fb9f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch
@@ -0,0 +1,78 @@
+From dae3e57000fb2d6f491e3ee2956f5918326d6b72 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:27 +0100
+Subject: [PATCH] clk: rockchip: rk3588: use linked clock ID for GATE_LINK
+
+In preparation for properly supporting GATE_LINK switch the unused
+linked clock argument from the clock's name to its ID. This allows
+easy and fast lookup of the 'struct clk'.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-7-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 46 +++++++++++++++----------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -29,7 +29,7 @@
+ * power, but avoids leaking implementation details into DT or hanging the
+ * system.
+ */
+-#define GATE_LINK(_id, cname, pname, linkname, f, o, b, gf) \
++#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \
+ GATE(_id, cname, pname, f, o, b, gf)
+ #define RK3588_LINKED_CLK CLK_IS_CRITICAL
+
+@@ -2429,28 +2429,28 @@ static struct rockchip_clk_branch rk3588
+ GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0,
+ RK3588_CLKGATE_CON(68), 2, GFLAGS),
+
+- GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", "aclk_vi_root", 0, RK3588_CLKGATE_CON(26), 6, GFLAGS),
+- GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", "hclk_vi_root", 0, RK3588_CLKGATE_CON(26), 8, GFLAGS),
+- GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", "aclk_nvm_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS),
+- GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", "aclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(42), 2, GFLAGS),
+- GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", "hclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(42), 3, GFLAGS),
+- GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 7, GFLAGS),
+- GATE_LINK(ACLK_VDPU_LOW_PRE, "aclk_vdpu_low_pre", "aclk_vdpu_low_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 5, GFLAGS),
+- GATE_LINK(ACLK_RKVENC1_PRE, "aclk_rkvenc1_pre", "aclk_rkvenc1_root", "aclk_rkvenc0", 0, RK3588_CLKGATE_CON(48), 3, GFLAGS),
+- GATE_LINK(HCLK_RKVENC1_PRE, "hclk_rkvenc1_pre", "hclk_rkvenc1_root", "hclk_rkvenc0", 0, RK3588_CLKGATE_CON(48), 2, GFLAGS),
+- GATE_LINK(HCLK_RKVDEC0_PRE, "hclk_rkvdec0_pre", "hclk_rkvdec0_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(40), 5, GFLAGS),
+- GATE_LINK(ACLK_RKVDEC0_PRE, "aclk_rkvdec0_pre", "aclk_rkvdec0_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(40), 6, GFLAGS),
+- GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 4, GFLAGS),
+- GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 5, GFLAGS),
+- GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", "aclk_vop_low_root", 0, RK3588_CLKGATE_CON(55), 9, GFLAGS),
+- GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", "hclk_vop_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS),
+- GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", "aclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(59), 6, GFLAGS),
+- GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", "hclk_vo1usb_top_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS),
+- GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 1, GFLAGS),
+- GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 4, GFLAGS),
+- GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", "hclk_nvm", 0, RK3588_CLKGATE_CON(75), 1, GFLAGS),
+- GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", "hclk_vo0", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
+- GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", "hclk_vo1", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
++ GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", ACLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 6, GFLAGS),
++ GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", HCLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 8, GFLAGS),
++ GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS),
++ GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 2, GFLAGS),
++ GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 3, GFLAGS),
++ GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 7, GFLAGS),
++ GATE_LINK(ACLK_VDPU_LOW_PRE, "aclk_vdpu_low_pre", "aclk_vdpu_low_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 5, GFLAGS),
++ GATE_LINK(ACLK_RKVENC1_PRE, "aclk_rkvenc1_pre", "aclk_rkvenc1_root", ACLK_RKVENC0, 0, RK3588_CLKGATE_CON(48), 3, GFLAGS),
++ GATE_LINK(HCLK_RKVENC1_PRE, "hclk_rkvenc1_pre", "hclk_rkvenc1_root", HCLK_RKVENC0, 0, RK3588_CLKGATE_CON(48), 2, GFLAGS),
++ GATE_LINK(HCLK_RKVDEC0_PRE, "hclk_rkvdec0_pre", "hclk_rkvdec0_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(40), 5, GFLAGS),
++ GATE_LINK(ACLK_RKVDEC0_PRE, "aclk_rkvdec0_pre", "aclk_rkvdec0_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(40), 6, GFLAGS),
++ GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 4, GFLAGS),
++ GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 5, GFLAGS),
++ GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", ACLK_VOP_LOW_ROOT, 0, RK3588_CLKGATE_CON(55), 9, GFLAGS),
++ GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS),
++ GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 6, GFLAGS),
++ GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS),
++ GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 1, GFLAGS),
++ GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 4, GFLAGS),
++ GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", HCLK_NVM, 0, RK3588_CLKGATE_CON(75), 1, GFLAGS),
++ GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", HCLK_VO0, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
++ GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", HCLK_VO1, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
+ };
+
+ static void __init rk3588_clk_init(struct device_node *np)
diff --git a/target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch b/target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch
new file mode 100644
index 0000000000..0b9082f9b6
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch
@@ -0,0 +1,24 @@
+From ca151fd56b5736a7adbdba5675b9d87d70f20b23 Mon Sep 17 00:00:00 2001
+From: Shreeya Patel <shreeya.patel@collabora.com>
+Date: Thu, 28 Mar 2024 04:20:52 +0530
+Subject: [PATCH] dt-bindings: reset: Define reset id used for HDMI Receiver
+
+Add reset id used for HDMI Receiver in RK3588 SoCs
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
+Link: https://lore.kernel.org/r/20240327225057.672304-2-shreeya.patel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/dt-bindings/reset/rockchip,rk3588-cru.h
++++ b/include/dt-bindings/reset/rockchip,rk3588-cru.h
+@@ -751,4 +751,6 @@
+ #define SRST_P_TRNG_CHK 658
+ #define SRST_TRNG_S 659
+
++#define SRST_A_HDMIRX_BIU 660
++
+ #endif
diff --git a/target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch b/target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch
new file mode 100644
index 0000000000..6aa9c058a3
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch
@@ -0,0 +1,25 @@
+From 7af67019cd78d028ef377df689ac103d51905518 Mon Sep 17 00:00:00 2001
+From: Shreeya Patel <shreeya.patel@collabora.com>
+Date: Thu, 28 Mar 2024 04:20:53 +0530
+Subject: [PATCH] clk: rockchip: rk3588: Add reset line for HDMI Receiver
+
+Export hdmirx_biu reset line required by the Synopsys
+DesignWare HDMIRX Controller.
+
+Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
+Link: https://lore.kernel.org/r/20240327225057.672304-3-shreeya.patel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/rst-rk3588.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/clk/rockchip/rst-rk3588.c
++++ b/drivers/clk/rockchip/rst-rk3588.c
+@@ -577,6 +577,7 @@ static const int rk3588_register_offset[
+
+ /* SOFTRST_CON59 */
+ RK3588_CRU_RESET_OFFSET(SRST_A_HDCP1_BIU, 59, 6),
++ RK3588_CRU_RESET_OFFSET(SRST_A_HDMIRX_BIU, 59, 7),
+ RK3588_CRU_RESET_OFFSET(SRST_A_VO1_BIU, 59, 8),
+ RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_BIU, 59, 9),
+ RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_S_BIU, 59, 10),
diff --git a/target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch b/target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch
new file mode 100644
index 0000000000..94d998fe93
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch
@@ -0,0 +1,28 @@
+From 2a46cd97f401a669d71b3d36b78bd6653f8424ee Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Thu, 19 Oct 2023 18:57:25 +0200
+Subject: [PATCH] mfd: rk8xx: Add support for standard system-power-controller
+ property
+
+DT property rockchip,system-power-controller is now deprecated.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231019165732.3818789-4-megi@xff.cz
+Signed-off-by: Lee Jones <lee@kernel.org>
+---
+ drivers/mfd/rk8xx-core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/mfd/rk8xx-core.c
++++ b/drivers/mfd/rk8xx-core.c
+@@ -677,7 +677,8 @@ int rk8xx_probe(struct device *dev, int
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to add MFD devices\n");
+
+- if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
++ if (device_property_read_bool(dev, "rockchip,system-power-controller") ||
++ device_property_read_bool(dev, "system-power-controller")) {
+ ret = devm_register_sys_off_handler(dev,
+ SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
+ &rk808_power_off, rk808);
diff --git a/target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch b/target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch
new file mode 100644
index 0000000000..2ac0ff537e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch
@@ -0,0 +1,29 @@
+From b0227e7081404448a0059b8698fdffd2dec280d2 Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Thu, 19 Oct 2023 18:57:26 +0200
+Subject: [PATCH] mfd: rk8xx: Add support for RK806 power off
+
+Use DEV_OFF bit to power off the RK806 PMIC, when system-power-controller
+is used in DTS.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231019165732.3818789-5-megi@xff.cz
+Signed-off-by: Lee Jones <lee@kernel.org>
+---
+ drivers/mfd/rk8xx-core.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mfd/rk8xx-core.c
++++ b/drivers/mfd/rk8xx-core.c
+@@ -517,6 +517,10 @@ static int rk808_power_off(struct sys_of
+ reg = RK805_DEV_CTRL_REG;
+ bit = DEV_OFF;
+ break;
++ case RK806_ID:
++ reg = RK806_SYS_CFG3;
++ bit = DEV_OFF;
++ break;
+ case RK808_ID:
+ reg = RK808_DEVCTRL_REG,
+ bit = DEV_OFF_RST;
diff --git a/target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch b/target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch
new file mode 100644
index 0000000000..69b44deba3
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch
@@ -0,0 +1,1670 @@
+From 2f70bbddeb457580cef3ceb574506083b9272188 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:29 +0200
+Subject: [PATCH] phy: rockchip: add usbdp combo phy driver
+
+This adds a new USBDP combo PHY with Samsung IP block driver.
+
+The driver get lane mux and mapping info in 2 ways, supporting
+DisplayPort alternate mode or parsing from DT. When parsing from DT,
+the property "rockchip,dp-lane-mux" provide the DP mux and mapping
+info. This is needed when the PHY is not used with TypeC Alt-Mode.
+For example if the USB3 interface of the PHY is connected to a USB
+Type A connector and the DP interface is connected to a DisplayPort
+connector.
+
+When do DP link training, need to set lane number, link rate, swing,
+and pre-emphasis via PHY configure interface.
+
+Co-developed-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Co-developed-by: Zhang Yubing <yubing.zhang@rock-chips.com>
+Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
+Co-developed-by: Frank Wang <frank.wang@rock-chips.com>
+Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-3-sebastian.reichel@collabora.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/Kconfig | 12 +
+ drivers/phy/rockchip/Makefile | 1 +
+ drivers/phy/rockchip/phy-rockchip-usbdp.c | 1608 +++++++++++++++++++++
+ 3 files changed, 1621 insertions(+)
+ create mode 100644 drivers/phy/rockchip/phy-rockchip-usbdp.c
+
+--- a/drivers/phy/rockchip/Kconfig
++++ b/drivers/phy/rockchip/Kconfig
+@@ -107,3 +107,15 @@ config PHY_ROCKCHIP_USB
+ select GENERIC_PHY
+ help
+ Enable this to support the Rockchip USB 2.0 PHY.
++
++config PHY_ROCKCHIP_USBDP
++ tristate "Rockchip USBDP COMBO PHY Driver"
++ depends on ARCH_ROCKCHIP && OF
++ select GENERIC_PHY
++ select TYPEC
++ help
++ Enable this to support the Rockchip USB3.0/DP combo PHY with
++ Samsung IP block. This is required for USB3 support on RK3588.
++
++ To compile this driver as a module, choose M here: the module
++ will be called phy-rockchip-usbdp
+--- a/drivers/phy/rockchip/Makefile
++++ b/drivers/phy/rockchip/Makefile
+@@ -11,3 +11,4 @@ obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-
+ obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o
+ obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
+ obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
++obj-$(CONFIG_PHY_ROCKCHIP_USBDP) += phy-rockchip-usbdp.o
+--- /dev/null
++++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
+@@ -0,0 +1,1608 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Rockchip USBDP Combo PHY with Samsung IP block driver
++ *
++ * Copyright (C) 2021-2024 Rockchip Electronics Co., Ltd
++ * Copyright (C) 2024 Collabora Ltd
++ */
++
++#include <dt-bindings/phy/phy.h>
++#include <linux/bitfield.h>
++#include <linux/bits.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/mfd/syscon.h>
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/property.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/usb/ch9.h>
++#include <linux/usb/typec_dp.h>
++#include <linux/usb/typec_mux.h>
++
++/* USBDP PHY Register Definitions */
++#define UDPHY_PCS 0x4000
++#define UDPHY_PMA 0x8000
++
++/* VO0 GRF Registers */
++#define DP_SINK_HPD_CFG BIT(11)
++#define DP_SINK_HPD_SEL BIT(10)
++#define DP_AUX_DIN_SEL BIT(9)
++#define DP_AUX_DOUT_SEL BIT(8)
++#define DP_LANE_SEL_N(n) GENMASK(2 * (n) + 1, 2 * (n))
++#define DP_LANE_SEL_ALL GENMASK(7, 0)
++
++/* PMA CMN Registers */
++#define CMN_LANE_MUX_AND_EN_OFFSET 0x0288 /* cmn_reg00A2 */
++#define CMN_DP_LANE_MUX_N(n) BIT((n) + 4)
++#define CMN_DP_LANE_EN_N(n) BIT(n)
++#define CMN_DP_LANE_MUX_ALL GENMASK(7, 4)
++#define CMN_DP_LANE_EN_ALL GENMASK(3, 0)
++
++#define CMN_DP_LINK_OFFSET 0x28c /* cmn_reg00A3 */
++#define CMN_DP_TX_LINK_BW GENMASK(6, 5)
++#define CMN_DP_TX_LANE_SWAP_EN BIT(2)
++
++#define CMN_SSC_EN_OFFSET 0x2d0 /* cmn_reg00B4 */
++#define CMN_ROPLL_SSC_EN BIT(1)
++#define CMN_LCPLL_SSC_EN BIT(0)
++
++#define CMN_ANA_LCPLL_DONE_OFFSET 0x0350 /* cmn_reg00D4 */
++#define CMN_ANA_LCPLL_LOCK_DONE BIT(7)
++#define CMN_ANA_LCPLL_AFC_DONE BIT(6)
++
++#define CMN_ANA_ROPLL_DONE_OFFSET 0x0354 /* cmn_reg00D5 */
++#define CMN_ANA_ROPLL_LOCK_DONE BIT(1)
++#define CMN_ANA_ROPLL_AFC_DONE BIT(0)
++
++#define CMN_DP_RSTN_OFFSET 0x038c /* cmn_reg00E3 */
++#define CMN_DP_INIT_RSTN BIT(3)
++#define CMN_DP_CMN_RSTN BIT(2)
++#define CMN_CDR_WTCHDG_EN BIT(1)
++#define CMN_CDR_WTCHDG_MSK_CDR_EN BIT(0)
++
++#define TRSV_ANA_TX_CLK_OFFSET_N(n) (0x854 + (n) * 0x800) /* trsv_reg0215 */
++#define LN_ANA_TX_SER_TXCLK_INV BIT(1)
++
++#define TRSV_LN0_MON_RX_CDR_DONE_OFFSET 0x0b84 /* trsv_reg02E1 */
++#define TRSV_LN0_MON_RX_CDR_LOCK_DONE BIT(0)
++
++#define TRSV_LN2_MON_RX_CDR_DONE_OFFSET 0x1b84 /* trsv_reg06E1 */
++#define TRSV_LN2_MON_RX_CDR_LOCK_DONE BIT(0)
++
++#define BIT_WRITEABLE_SHIFT 16
++#define PHY_AUX_DP_DATA_POL_NORMAL 0
++#define PHY_AUX_DP_DATA_POL_INVERT 1
++#define PHY_LANE_MUX_USB 0
++#define PHY_LANE_MUX_DP 1
++
++enum {
++ DP_BW_RBR,
++ DP_BW_HBR,
++ DP_BW_HBR2,
++ DP_BW_HBR3,
++};
++
++enum {
++ UDPHY_MODE_NONE = 0,
++ UDPHY_MODE_USB = BIT(0),
++ UDPHY_MODE_DP = BIT(1),
++ UDPHY_MODE_DP_USB = BIT(1) | BIT(0),
++};
++
++struct rk_udphy_grf_reg {
++ unsigned int offset;
++ unsigned int disable;
++ unsigned int enable;
++};
++
++#define _RK_UDPHY_GEN_GRF_REG(offset, mask, disable, enable) \
++{\
++ offset, \
++ FIELD_PREP_CONST(mask, disable) | (mask << BIT_WRITEABLE_SHIFT), \
++ FIELD_PREP_CONST(mask, enable) | (mask << BIT_WRITEABLE_SHIFT), \
++}
++
++#define RK_UDPHY_GEN_GRF_REG(offset, bitend, bitstart, disable, enable) \
++ _RK_UDPHY_GEN_GRF_REG(offset, GENMASK(bitend, bitstart), disable, enable)
++
++struct rk_udphy_grf_cfg {
++ /* u2phy-grf */
++ struct rk_udphy_grf_reg bvalid_phy_con;
++ struct rk_udphy_grf_reg bvalid_grf_con;
++
++ /* usb-grf */
++ struct rk_udphy_grf_reg usb3otg0_cfg;
++ struct rk_udphy_grf_reg usb3otg1_cfg;
++
++ /* usbdpphy-grf */
++ struct rk_udphy_grf_reg low_pwrn;
++ struct rk_udphy_grf_reg rx_lfps;
++};
++
++struct rk_udphy_vogrf_cfg {
++ /* vo-grf */
++ struct rk_udphy_grf_reg hpd_trigger;
++ u32 dp_lane_reg;
++};
++
++struct rk_udphy_dp_tx_drv_ctrl {
++ u32 trsv_reg0204;
++ u32 trsv_reg0205;
++ u32 trsv_reg0206;
++ u32 trsv_reg0207;
++};
++
++struct rk_udphy_cfg {
++ unsigned int num_phys;
++ unsigned int phy_ids[2];
++ /* resets to be requested */
++ const char * const *rst_list;
++ int num_rsts;
++
++ struct rk_udphy_grf_cfg grfcfg;
++ struct rk_udphy_vogrf_cfg vogrfcfg[2];
++ const struct rk_udphy_dp_tx_drv_ctrl (*dp_tx_ctrl_cfg[4])[4];
++ const struct rk_udphy_dp_tx_drv_ctrl (*dp_tx_ctrl_cfg_typec[4])[4];
++};
++
++struct rk_udphy {
++ struct device *dev;
++ struct regmap *pma_regmap;
++ struct regmap *u2phygrf;
++ struct regmap *udphygrf;
++ struct regmap *usbgrf;
++ struct regmap *vogrf;
++ struct typec_switch_dev *sw;
++ struct typec_mux_dev *mux;
++ struct mutex mutex; /* mutex to protect access to individual PHYs */
++
++ /* clocks and rests */
++ int num_clks;
++ struct clk_bulk_data *clks;
++ struct clk *refclk;
++ int num_rsts;
++ struct reset_control_bulk_data *rsts;
++
++ /* PHY status management */
++ bool flip;
++ bool mode_change;
++ u8 mode;
++ u8 status;
++
++ /* utilized for USB */
++ bool hs; /* flag for high-speed */
++
++ /* utilized for DP */
++ struct gpio_desc *sbu1_dc_gpio;
++ struct gpio_desc *sbu2_dc_gpio;
++ u32 lane_mux_sel[4];
++ u32 dp_lane_sel[4];
++ u32 dp_aux_dout_sel;
++ u32 dp_aux_din_sel;
++ bool dp_sink_hpd_sel;
++ bool dp_sink_hpd_cfg;
++ u8 bw;
++ int id;
++
++ bool dp_in_use;
++
++ /* PHY const config */
++ const struct rk_udphy_cfg *cfgs;
++
++ /* PHY devices */
++ struct phy *phy_dp;
++ struct phy *phy_u3;
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x20, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x29, 0x18, 0x42, 0xe5 },
++ { 0x2b, 0x1c, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x23, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x17, 0x43, 0xe7 },
++ { 0x2b, 0x1a, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x27, 0x10, 0x42, 0xe7 },
++ { 0x2b, 0x17, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x29, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr_typec[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x20, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x29, 0x18, 0x42, 0xe5 },
++ { 0x2b, 0x1c, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x23, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x17, 0x43, 0xe7 },
++ { 0x2b, 0x1a, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x27, 0x10, 0x43, 0x67 },
++ { 0x2b, 0x17, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x29, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr2[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x21, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x26, 0x16, 0x43, 0xe5 },
++ { 0x2a, 0x19, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x24, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x17, 0x43, 0xe7 },
++ { 0x2b, 0x1a, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x28, 0x10, 0x42, 0xe7 },
++ { 0x2b, 0x17, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x28, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr3[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x21, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x26, 0x16, 0x43, 0xe5 },
++ { 0x29, 0x18, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x24, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x18, 0x43, 0xe7 },
++ { 0x2b, 0x1b, 0x43, 0xe7 }
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x27, 0x10, 0x42, 0xe7 },
++ { 0x2b, 0x18, 0x43, 0xe7 }
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x28, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct reg_sequence rk_udphy_24m_refclk_cfg[] = {
++ {0x0090, 0x68}, {0x0094, 0x68},
++ {0x0128, 0x24}, {0x012c, 0x44},
++ {0x0130, 0x3f}, {0x0134, 0x44},
++ {0x015c, 0xa9}, {0x0160, 0x71},
++ {0x0164, 0x71}, {0x0168, 0xa9},
++ {0x0174, 0xa9}, {0x0178, 0x71},
++ {0x017c, 0x71}, {0x0180, 0xa9},
++ {0x018c, 0x41}, {0x0190, 0x00},
++ {0x0194, 0x05}, {0x01ac, 0x2a},
++ {0x01b0, 0x17}, {0x01b4, 0x17},
++ {0x01b8, 0x2a}, {0x01c8, 0x04},
++ {0x01cc, 0x08}, {0x01d0, 0x08},
++ {0x01d4, 0x04}, {0x01d8, 0x20},
++ {0x01dc, 0x01}, {0x01e0, 0x09},
++ {0x01e4, 0x03}, {0x01f0, 0x29},
++ {0x01f4, 0x02}, {0x01f8, 0x02},
++ {0x01fc, 0x29}, {0x0208, 0x2a},
++ {0x020c, 0x17}, {0x0210, 0x17},
++ {0x0214, 0x2a}, {0x0224, 0x20},
++ {0x03f0, 0x0a}, {0x03f4, 0x07},
++ {0x03f8, 0x07}, {0x03fc, 0x0c},
++ {0x0404, 0x12}, {0x0408, 0x1a},
++ {0x040c, 0x1a}, {0x0410, 0x3f},
++ {0x0ce0, 0x68}, {0x0ce8, 0xd0},
++ {0x0cf0, 0x87}, {0x0cf8, 0x70},
++ {0x0d00, 0x70}, {0x0d08, 0xa9},
++ {0x1ce0, 0x68}, {0x1ce8, 0xd0},
++ {0x1cf0, 0x87}, {0x1cf8, 0x70},
++ {0x1d00, 0x70}, {0x1d08, 0xa9},
++ {0x0a3c, 0xd0}, {0x0a44, 0xd0},
++ {0x0a48, 0x01}, {0x0a4c, 0x0d},
++ {0x0a54, 0xe0}, {0x0a5c, 0xe0},
++ {0x0a64, 0xa8}, {0x1a3c, 0xd0},
++ {0x1a44, 0xd0}, {0x1a48, 0x01},
++ {0x1a4c, 0x0d}, {0x1a54, 0xe0},
++ {0x1a5c, 0xe0}, {0x1a64, 0xa8}
++};
++
++static const struct reg_sequence rk_udphy_26m_refclk_cfg[] = {
++ {0x0830, 0x07}, {0x085c, 0x80},
++ {0x1030, 0x07}, {0x105c, 0x80},
++ {0x1830, 0x07}, {0x185c, 0x80},
++ {0x2030, 0x07}, {0x205c, 0x80},
++ {0x0228, 0x38}, {0x0104, 0x44},
++ {0x0248, 0x44}, {0x038c, 0x02},
++ {0x0878, 0x04}, {0x1878, 0x04},
++ {0x0898, 0x77}, {0x1898, 0x77},
++ {0x0054, 0x01}, {0x00e0, 0x38},
++ {0x0060, 0x24}, {0x0064, 0x77},
++ {0x0070, 0x76}, {0x0234, 0xe8},
++ {0x0af4, 0x15}, {0x1af4, 0x15},
++ {0x081c, 0xe5}, {0x181c, 0xe5},
++ {0x099c, 0x48}, {0x199c, 0x48},
++ {0x09a4, 0x07}, {0x09a8, 0x22},
++ {0x19a4, 0x07}, {0x19a8, 0x22},
++ {0x09b8, 0x3e}, {0x19b8, 0x3e},
++ {0x09e4, 0x02}, {0x19e4, 0x02},
++ {0x0a34, 0x1e}, {0x1a34, 0x1e},
++ {0x0a98, 0x2f}, {0x1a98, 0x2f},
++ {0x0c30, 0x0e}, {0x0c48, 0x06},
++ {0x1c30, 0x0e}, {0x1c48, 0x06},
++ {0x028c, 0x18}, {0x0af0, 0x00},
++ {0x1af0, 0x00}
++};
++
++static const struct reg_sequence rk_udphy_init_sequence[] = {
++ {0x0104, 0x44}, {0x0234, 0xe8},
++ {0x0248, 0x44}, {0x028c, 0x18},
++ {0x081c, 0xe5}, {0x0878, 0x00},
++ {0x0994, 0x1c}, {0x0af0, 0x00},
++ {0x181c, 0xe5}, {0x1878, 0x00},
++ {0x1994, 0x1c}, {0x1af0, 0x00},
++ {0x0428, 0x60}, {0x0d58, 0x33},
++ {0x1d58, 0x33}, {0x0990, 0x74},
++ {0x0d64, 0x17}, {0x08c8, 0x13},
++ {0x1990, 0x74}, {0x1d64, 0x17},
++ {0x18c8, 0x13}, {0x0d90, 0x40},
++ {0x0da8, 0x40}, {0x0dc0, 0x40},
++ {0x0dd8, 0x40}, {0x1d90, 0x40},
++ {0x1da8, 0x40}, {0x1dc0, 0x40},
++ {0x1dd8, 0x40}, {0x03c0, 0x30},
++ {0x03c4, 0x06}, {0x0e10, 0x00},
++ {0x1e10, 0x00}, {0x043c, 0x0f},
++ {0x0d2c, 0xff}, {0x1d2c, 0xff},
++ {0x0d34, 0x0f}, {0x1d34, 0x0f},
++ {0x08fc, 0x2a}, {0x0914, 0x28},
++ {0x0a30, 0x03}, {0x0e38, 0x03},
++ {0x0ecc, 0x27}, {0x0ed0, 0x22},
++ {0x0ed4, 0x26}, {0x18fc, 0x2a},
++ {0x1914, 0x28}, {0x1a30, 0x03},
++ {0x1e38, 0x03}, {0x1ecc, 0x27},
++ {0x1ed0, 0x22}, {0x1ed4, 0x26},
++ {0x0048, 0x0f}, {0x0060, 0x3c},
++ {0x0064, 0xf7}, {0x006c, 0x20},
++ {0x0070, 0x7d}, {0x0074, 0x68},
++ {0x0af4, 0x1a}, {0x1af4, 0x1a},
++ {0x0440, 0x3f}, {0x10d4, 0x08},
++ {0x20d4, 0x08}, {0x00d4, 0x30},
++ {0x0024, 0x6e},
++};
++
++static inline int rk_udphy_grfreg_write(struct regmap *base,
++ const struct rk_udphy_grf_reg *reg, bool en)
++{
++ return regmap_write(base, reg->offset, en ? reg->enable : reg->disable);
++}
++
++static int rk_udphy_clk_init(struct rk_udphy *udphy, struct device *dev)
++{
++ int i;
++
++ udphy->num_clks = devm_clk_bulk_get_all(dev, &udphy->clks);
++ if (udphy->num_clks < 1)
++ return -ENODEV;
++
++ /* used for configure phy reference clock frequency */
++ for (i = 0; i < udphy->num_clks; i++) {
++ if (!strncmp(udphy->clks[i].id, "refclk", 6)) {
++ udphy->refclk = udphy->clks[i].clk;
++ break;
++ }
++ }
++
++ if (!udphy->refclk)
++ return dev_err_probe(udphy->dev, -EINVAL, "no refclk found\n");
++
++ return 0;
++}
++
++static int rk_udphy_reset_assert_all(struct rk_udphy *udphy)
++{
++ return reset_control_bulk_assert(udphy->num_rsts, udphy->rsts);
++}
++
++static int rk_udphy_reset_deassert_all(struct rk_udphy *udphy)
++{
++ return reset_control_bulk_deassert(udphy->num_rsts, udphy->rsts);
++}
++
++static int rk_udphy_reset_deassert(struct rk_udphy *udphy, char *name)
++{
++ struct reset_control_bulk_data *list = udphy->rsts;
++ int idx;
++
++ for (idx = 0; idx < udphy->num_rsts; idx++) {
++ if (!strcmp(list[idx].id, name))
++ return reset_control_deassert(list[idx].rstc);
++ }
++
++ return -EINVAL;
++}
++
++static int rk_udphy_reset_init(struct rk_udphy *udphy, struct device *dev)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ int idx;
++
++ udphy->num_rsts = cfg->num_rsts;
++ udphy->rsts = devm_kcalloc(dev, udphy->num_rsts,
++ sizeof(*udphy->rsts), GFP_KERNEL);
++ if (!udphy->rsts)
++ return -ENOMEM;
++
++ for (idx = 0; idx < cfg->num_rsts; idx++)
++ udphy->rsts[idx].id = cfg->rst_list[idx];
++
++ return devm_reset_control_bulk_get_exclusive(dev, cfg->num_rsts,
++ udphy->rsts);
++}
++
++static void rk_udphy_u3_port_disable(struct rk_udphy *udphy, u8 disable)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ const struct rk_udphy_grf_reg *preg;
++
++ preg = udphy->id ? &cfg->grfcfg.usb3otg1_cfg : &cfg->grfcfg.usb3otg0_cfg;
++ rk_udphy_grfreg_write(udphy->usbgrf, preg, disable);
++}
++
++static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++
++ rk_udphy_grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_phy_con, enable);
++ rk_udphy_grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_grf_con, enable);
++}
++
++/*
++ * In usb/dp combo phy driver, here are 2 ways to mapping lanes.
++ *
++ * 1 Type-C Mapping table (DP_Alt_Mode V1.0b remove ABF pin mapping)
++ * ---------------------------------------------------------------------------
++ * Type-C Pin B11-B10 A2-A3 A11-A10 B2-B3
++ * PHY Pad ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
++ * C/E(Normal) dpln3 dpln2 dpln0 dpln1
++ * C/E(Flip ) dpln0 dpln1 dpln3 dpln2
++ * D/F(Normal) usbrx usbtx dpln0 dpln1
++ * D/F(Flip ) dpln0 dpln1 usbrx usbtx
++ * A(Normal ) dpln3 dpln1 dpln2 dpln0
++ * A(Flip ) dpln2 dpln0 dpln3 dpln1
++ * B(Normal ) usbrx usbtx dpln1 dpln0
++ * B(Flip ) dpln1 dpln0 usbrx usbtx
++ * ---------------------------------------------------------------------------
++ *
++ * 2 Mapping the lanes in dtsi
++ * if all 4 lane assignment for dp function, define rockchip,dp-lane-mux = <x x x x>;
++ * sample as follow:
++ * ---------------------------------------------------------------------------
++ * B11-B10 A2-A3 A11-A10 B2-B3
++ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
++ * <0 1 2 3> dpln0 dpln1 dpln2 dpln3
++ * <2 3 0 1> dpln2 dpln3 dpln0 dpln1
++ * ---------------------------------------------------------------------------
++ * if 2 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = <x x>;
++ * sample as follow:
++ * ---------------------------------------------------------------------------
++ * B11-B10 A2-A3 A11-A10 B2-B3
++ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
++ * <0 1> dpln0 dpln1 usbrx usbtx
++ * <2 3> usbrx usbtx dpln0 dpln1
++ * ---------------------------------------------------------------------------
++ */
++
++static void rk_udphy_dplane_select(struct rk_udphy *udphy)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ u32 value = 0;
++
++ switch (udphy->mode) {
++ case UDPHY_MODE_DP:
++ value |= 2 << udphy->dp_lane_sel[2] * 2;
++ value |= 3 << udphy->dp_lane_sel[3] * 2;
++ fallthrough;
++
++ case UDPHY_MODE_DP_USB:
++ value |= 0 << udphy->dp_lane_sel[0] * 2;
++ value |= 1 << udphy->dp_lane_sel[1] * 2;
++ break;
++
++ case UDPHY_MODE_USB:
++ break;
++
++ default:
++ break;
++ }
++
++ regmap_write(udphy->vogrf, cfg->vogrfcfg[udphy->id].dp_lane_reg,
++ ((DP_AUX_DIN_SEL | DP_AUX_DOUT_SEL | DP_LANE_SEL_ALL) << 16) |
++ FIELD_PREP(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel) |
++ FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
++}
++
++static int rk_udphy_dplane_get(struct rk_udphy *udphy)
++{
++ int dp_lanes;
++
++ switch (udphy->mode) {
++ case UDPHY_MODE_DP:
++ dp_lanes = 4;
++ break;
++
++ case UDPHY_MODE_DP_USB:
++ dp_lanes = 2;
++ break;
++
++ case UDPHY_MODE_USB:
++ default:
++ dp_lanes = 0;
++ break;
++ }
++
++ return dp_lanes;
++}
++
++static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
++{
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < dp_lanes; i++)
++ val |= BIT(udphy->dp_lane_sel[i]);
++
++ regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, CMN_DP_LANE_EN_ALL,
++ FIELD_PREP(CMN_DP_LANE_EN_ALL, val));
++
++ if (!dp_lanes)
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
++ CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
++}
++
++static void rk_udphy_dp_hpd_event_trigger(struct rk_udphy *udphy, bool hpd)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++
++ udphy->dp_sink_hpd_sel = true;
++ udphy->dp_sink_hpd_cfg = hpd;
++
++ if (!udphy->dp_in_use)
++ return;
++
++ rk_udphy_grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd);
++}
++
++static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
++{
++ if (udphy->flip) {
++ udphy->dp_lane_sel[0] = 0;
++ udphy->dp_lane_sel[1] = 1;
++ udphy->dp_lane_sel[2] = 3;
++ udphy->dp_lane_sel[3] = 2;
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
++ udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_INVERT;
++ udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_INVERT;
++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 1);
++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0);
++ } else {
++ udphy->dp_lane_sel[0] = 2;
++ udphy->dp_lane_sel[1] = 3;
++ udphy->dp_lane_sel[2] = 1;
++ udphy->dp_lane_sel[3] = 0;
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
++ udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_NORMAL;
++ udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_NORMAL;
++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0);
++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1);
++ }
++
++ udphy->mode = UDPHY_MODE_DP_USB;
++}
++
++static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
++ enum typec_orientation orien)
++{
++ struct rk_udphy *udphy = typec_switch_get_drvdata(sw);
++
++ mutex_lock(&udphy->mutex);
++
++ if (orien == TYPEC_ORIENTATION_NONE) {
++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0);
++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0);
++ /* unattached */
++ rk_udphy_usb_bvalid_enable(udphy, false);
++ goto unlock_ret;
++ }
++
++ udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
++ rk_udphy_set_typec_default_mapping(udphy);
++ rk_udphy_usb_bvalid_enable(udphy, true);
++
++unlock_ret:
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static void rk_udphy_orien_switch_unregister(void *data)
++{
++ struct rk_udphy *udphy = data;
++
++ typec_switch_unregister(udphy->sw);
++}
++
++static int rk_udphy_setup_orien_switch(struct rk_udphy *udphy)
++{
++ struct typec_switch_desc sw_desc = { };
++
++ sw_desc.drvdata = udphy;
++ sw_desc.fwnode = dev_fwnode(udphy->dev);
++ sw_desc.set = rk_udphy_orien_sw_set;
++
++ udphy->sw = typec_switch_register(udphy->dev, &sw_desc);
++ if (IS_ERR(udphy->sw)) {
++ dev_err(udphy->dev, "Error register typec orientation switch: %ld\n",
++ PTR_ERR(udphy->sw));
++ return PTR_ERR(udphy->sw);
++ }
++
++ return devm_add_action_or_reset(udphy->dev,
++ rk_udphy_orien_switch_unregister, udphy);
++}
++
++static int rk_udphy_refclk_set(struct rk_udphy *udphy)
++{
++ unsigned long rate;
++ int ret;
++
++ /* configure phy reference clock */
++ rate = clk_get_rate(udphy->refclk);
++ dev_dbg(udphy->dev, "refclk freq %ld\n", rate);
++
++ switch (rate) {
++ case 24000000:
++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_24m_refclk_cfg,
++ ARRAY_SIZE(rk_udphy_24m_refclk_cfg));
++ if (ret)
++ return ret;
++ break;
++
++ case 26000000:
++ /* register default is 26MHz */
++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_26m_refclk_cfg,
++ ARRAY_SIZE(rk_udphy_26m_refclk_cfg));
++ if (ret)
++ return ret;
++ break;
++
++ default:
++ dev_err(udphy->dev, "unsupported refclk freq %ld\n", rate);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int rk_udphy_status_check(struct rk_udphy *udphy)
++{
++ unsigned int val;
++ int ret;
++
++ /* LCPLL check */
++ if (udphy->mode & UDPHY_MODE_USB) {
++ ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_LCPLL_DONE_OFFSET,
++ val, (val & CMN_ANA_LCPLL_AFC_DONE) &&
++ (val & CMN_ANA_LCPLL_LOCK_DONE), 200, 100000);
++ if (ret) {
++ dev_err(udphy->dev, "cmn ana lcpll lock timeout\n");
++ /*
++ * If earlier software (U-Boot) enabled USB once already
++ * the PLL may have problems locking on the first try.
++ * It will be successful on the second try, so for the
++ * time being a -EPROBE_DEFER will solve the issue.
++ *
++ * This requires further investigation to understand the
++ * root cause, especially considering that the driver is
++ * asserting all reset lines at probe time.
++ */
++ return -EPROBE_DEFER;
++ }
++
++ if (!udphy->flip) {
++ ret = regmap_read_poll_timeout(udphy->pma_regmap,
++ TRSV_LN0_MON_RX_CDR_DONE_OFFSET, val,
++ val & TRSV_LN0_MON_RX_CDR_LOCK_DONE,
++ 200, 100000);
++ if (ret)
++ dev_err(udphy->dev, "trsv ln0 mon rx cdr lock timeout\n");
++ } else {
++ ret = regmap_read_poll_timeout(udphy->pma_regmap,
++ TRSV_LN2_MON_RX_CDR_DONE_OFFSET, val,
++ val & TRSV_LN2_MON_RX_CDR_LOCK_DONE,
++ 200, 100000);
++ if (ret)
++ dev_err(udphy->dev, "trsv ln2 mon rx cdr lock timeout\n");
++ }
++ }
++
++ return 0;
++}
++
++static int rk_udphy_init(struct rk_udphy *udphy)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ int ret;
++
++ rk_udphy_reset_assert_all(udphy);
++ usleep_range(10000, 11000);
++
++ /* enable rx lfps for usb */
++ if (udphy->mode & UDPHY_MODE_USB)
++ rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.rx_lfps, true);
++
++ /* Step 1: power on pma and deassert apb rstn */
++ rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.low_pwrn, true);
++
++ rk_udphy_reset_deassert(udphy, "pma_apb");
++ rk_udphy_reset_deassert(udphy, "pcs_apb");
++
++ /* Step 2: set init sequence and phy refclk */
++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_init_sequence,
++ ARRAY_SIZE(rk_udphy_init_sequence));
++ if (ret) {
++ dev_err(udphy->dev, "init sequence set error %d\n", ret);
++ goto assert_resets;
++ }
++
++ ret = rk_udphy_refclk_set(udphy);
++ if (ret) {
++ dev_err(udphy->dev, "refclk set error %d\n", ret);
++ goto assert_resets;
++ }
++
++ /* Step 3: configure lane mux */
++ regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET,
++ CMN_DP_LANE_MUX_ALL | CMN_DP_LANE_EN_ALL,
++ FIELD_PREP(CMN_DP_LANE_MUX_N(3), udphy->lane_mux_sel[3]) |
++ FIELD_PREP(CMN_DP_LANE_MUX_N(2), udphy->lane_mux_sel[2]) |
++ FIELD_PREP(CMN_DP_LANE_MUX_N(1), udphy->lane_mux_sel[1]) |
++ FIELD_PREP(CMN_DP_LANE_MUX_N(0), udphy->lane_mux_sel[0]) |
++ FIELD_PREP(CMN_DP_LANE_EN_ALL, 0));
++
++ /* Step 4: deassert init rstn and wait for 200ns from datasheet */
++ if (udphy->mode & UDPHY_MODE_USB)
++ rk_udphy_reset_deassert(udphy, "init");
++
++ if (udphy->mode & UDPHY_MODE_DP) {
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
++ CMN_DP_INIT_RSTN,
++ FIELD_PREP(CMN_DP_INIT_RSTN, 0x1));
++ }
++
++ udelay(1);
++
++ /* Step 5: deassert cmn/lane rstn */
++ if (udphy->mode & UDPHY_MODE_USB) {
++ rk_udphy_reset_deassert(udphy, "cmn");
++ rk_udphy_reset_deassert(udphy, "lane");
++ }
++
++ /* Step 6: wait for lock done of pll */
++ ret = rk_udphy_status_check(udphy);
++ if (ret)
++ goto assert_resets;
++
++ return 0;
++
++assert_resets:
++ rk_udphy_reset_assert_all(udphy);
++ return ret;
++}
++
++static int rk_udphy_setup(struct rk_udphy *udphy)
++{
++ int ret;
++
++ ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks);
++ if (ret) {
++ dev_err(udphy->dev, "failed to enable clk\n");
++ return ret;
++ }
++
++ ret = rk_udphy_init(udphy);
++ if (ret) {
++ dev_err(udphy->dev, "failed to init combophy\n");
++ clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks);
++ return ret;
++ }
++
++ return 0;
++}
++
++static void rk_udphy_disable(struct rk_udphy *udphy)
++{
++ clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks);
++ rk_udphy_reset_assert_all(udphy);
++}
++
++static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
++{
++ int ret, i, num_lanes;
++
++ num_lanes = device_property_count_u32(udphy->dev, "rockchip,dp-lane-mux");
++ if (num_lanes < 0) {
++ dev_dbg(udphy->dev, "no dp-lane-mux, following dp alt mode\n");
++ udphy->mode = UDPHY_MODE_USB;
++ return 0;
++ }
++
++ if (num_lanes != 2 && num_lanes != 4)
++ return dev_err_probe(udphy->dev, -EINVAL,
++ "invalid number of lane mux\n");
++
++ ret = device_property_read_u32_array(udphy->dev, "rockchip,dp-lane-mux",
++ udphy->dp_lane_sel, num_lanes);
++ if (ret)
++ return dev_err_probe(udphy->dev, ret, "get dp lane mux failed\n");
++
++ for (i = 0; i < num_lanes; i++) {
++ int j;
++
++ if (udphy->dp_lane_sel[i] > 3)
++ return dev_err_probe(udphy->dev, -EINVAL,
++ "lane mux between 0 and 3, exceeding the range\n");
++
++ udphy->lane_mux_sel[udphy->dp_lane_sel[i]] = PHY_LANE_MUX_DP;
++
++ for (j = i + 1; j < num_lanes; j++) {
++ if (udphy->dp_lane_sel[i] == udphy->dp_lane_sel[j])
++ return dev_err_probe(udphy->dev, -EINVAL,
++ "set repeat lane mux value\n");
++ }
++ }
++
++ udphy->mode = UDPHY_MODE_DP;
++ if (num_lanes == 2) {
++ udphy->mode |= UDPHY_MODE_USB;
++ udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP);
++ }
++
++ return 0;
++}
++
++static int rk_udphy_get_initial_status(struct rk_udphy *udphy)
++{
++ int ret;
++ u32 value;
++
++ ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks);
++ if (ret) {
++ dev_err(udphy->dev, "failed to enable clk\n");
++ return ret;
++ }
++
++ rk_udphy_reset_deassert_all(udphy);
++
++ regmap_read(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, &value);
++ if (FIELD_GET(CMN_DP_LANE_MUX_ALL, value) && FIELD_GET(CMN_DP_LANE_EN_ALL, value))
++ udphy->status = UDPHY_MODE_DP;
++ else
++ rk_udphy_disable(udphy);
++
++ return 0;
++}
++
++static int rk_udphy_parse_dt(struct rk_udphy *udphy)
++{
++ struct device *dev = udphy->dev;
++ struct device_node *np = dev_of_node(dev);
++ enum usb_device_speed maximum_speed;
++ int ret;
++
++ udphy->u2phygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,u2phy-grf");
++ if (IS_ERR(udphy->u2phygrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->u2phygrf), "failed to get u2phy-grf\n");
++
++ udphy->udphygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbdpphy-grf");
++ if (IS_ERR(udphy->udphygrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->udphygrf), "failed to get usbdpphy-grf\n");
++
++ udphy->usbgrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usb-grf");
++ if (IS_ERR(udphy->usbgrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->usbgrf), "failed to get usb-grf\n");
++
++ udphy->vogrf = syscon_regmap_lookup_by_phandle(np, "rockchip,vo-grf");
++ if (IS_ERR(udphy->vogrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->vogrf), "failed to get vo-grf\n");
++
++ ret = rk_udphy_parse_lane_mux_data(udphy);
++ if (ret)
++ return ret;
++
++ udphy->sbu1_dc_gpio = devm_gpiod_get_optional(dev, "sbu1-dc", GPIOD_OUT_LOW);
++ if (IS_ERR(udphy->sbu1_dc_gpio))
++ return PTR_ERR(udphy->sbu1_dc_gpio);
++
++ udphy->sbu2_dc_gpio = devm_gpiod_get_optional(dev, "sbu2-dc", GPIOD_OUT_LOW);
++ if (IS_ERR(udphy->sbu2_dc_gpio))
++ return PTR_ERR(udphy->sbu2_dc_gpio);
++
++ if (device_property_present(dev, "maximum-speed")) {
++ maximum_speed = usb_get_maximum_speed(dev);
++ udphy->hs = maximum_speed <= USB_SPEED_HIGH ? true : false;
++ }
++
++ ret = rk_udphy_clk_init(udphy, dev);
++ if (ret)
++ return ret;
++
++ return rk_udphy_reset_init(udphy, dev);
++}
++
++static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
++{
++ int ret;
++
++ if (!(udphy->mode & mode)) {
++ dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
++ return 0;
++ }
++
++ if (udphy->status == UDPHY_MODE_NONE) {
++ udphy->mode_change = false;
++ ret = rk_udphy_setup(udphy);
++ if (ret)
++ return ret;
++
++ if (udphy->mode & UDPHY_MODE_USB)
++ rk_udphy_u3_port_disable(udphy, false);
++ } else if (udphy->mode_change) {
++ udphy->mode_change = false;
++ udphy->status = UDPHY_MODE_NONE;
++ if (udphy->mode == UDPHY_MODE_DP)
++ rk_udphy_u3_port_disable(udphy, true);
++
++ rk_udphy_disable(udphy);
++ ret = rk_udphy_setup(udphy);
++ if (ret)
++ return ret;
++ }
++
++ udphy->status |= mode;
++
++ return 0;
++}
++
++static void rk_udphy_power_off(struct rk_udphy *udphy, u8 mode)
++{
++ if (!(udphy->mode & mode)) {
++ dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
++ return;
++ }
++
++ if (!udphy->status)
++ return;
++
++ udphy->status &= ~mode;
++
++ if (udphy->status == UDPHY_MODE_NONE)
++ rk_udphy_disable(udphy);
++}
++
++static int rk_udphy_dp_phy_init(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++
++ udphy->dp_in_use = true;
++ rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg);
++
++ mutex_unlock(&udphy->mutex);
++
++ return 0;
++}
++
++static int rk_udphy_dp_phy_exit(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++ udphy->dp_in_use = false;
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static int rk_udphy_dp_phy_power_on(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++ int ret, dp_lanes;
++
++ mutex_lock(&udphy->mutex);
++
++ dp_lanes = rk_udphy_dplane_get(udphy);
++ phy_set_bus_width(phy, dp_lanes);
++
++ ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
++ if (ret)
++ goto unlock;
++
++ rk_udphy_dplane_enable(udphy, dp_lanes);
++
++ rk_udphy_dplane_select(udphy);
++
++unlock:
++ mutex_unlock(&udphy->mutex);
++ /*
++ * If data send by aux channel too fast after phy power on,
++ * the aux may be not ready which will cause aux error. Adding
++ * delay to avoid this issue.
++ */
++ usleep_range(10000, 11000);
++ return ret;
++}
++
++static int rk_udphy_dp_phy_power_off(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++ rk_udphy_dplane_enable(udphy, 0);
++ rk_udphy_power_off(udphy, UDPHY_MODE_DP);
++ mutex_unlock(&udphy->mutex);
++
++ return 0;
++}
++
++static int rk_udphy_dp_phy_verify_link_rate(unsigned int link_rate)
++{
++ switch (link_rate) {
++ case 1620:
++ case 2700:
++ case 5400:
++ case 8100:
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int rk_udphy_dp_phy_verify_config(struct rk_udphy *udphy,
++ struct phy_configure_opts_dp *dp)
++{
++ int i, ret;
++
++ /* If changing link rate was required, verify it's supported. */
++ ret = rk_udphy_dp_phy_verify_link_rate(dp->link_rate);
++ if (ret)
++ return ret;
++
++ /* Verify lane count. */
++ switch (dp->lanes) {
++ case 1:
++ case 2:
++ case 4:
++ /* valid lane count. */
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ /*
++ * If changing voltages is required, check swing and pre-emphasis
++ * levels, per-lane.
++ */
++ if (dp->set_voltages) {
++ /* Lane count verified previously. */
++ for (i = 0; i < dp->lanes; i++) {
++ if (dp->voltage[i] > 3 || dp->pre[i] > 3)
++ return -EINVAL;
++
++ /*
++ * Sum of voltage swing and pre-emphasis levels cannot
++ * exceed 3.
++ */
++ if (dp->voltage[i] + dp->pre[i] > 3)
++ return -EINVAL;
++ }
++ }
++
++ return 0;
++}
++
++static void rk_udphy_dp_set_voltage(struct rk_udphy *udphy, u8 bw,
++ u32 voltage, u32 pre, u32 lane)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ const struct rk_udphy_dp_tx_drv_ctrl (*dp_ctrl)[4];
++ u32 offset = 0x800 * lane;
++ u32 val;
++
++ if (udphy->mux)
++ dp_ctrl = cfg->dp_tx_ctrl_cfg_typec[bw];
++ else
++ dp_ctrl = cfg->dp_tx_ctrl_cfg[bw];
++
++ val = dp_ctrl[voltage][pre].trsv_reg0204;
++ regmap_write(udphy->pma_regmap, 0x0810 + offset, val);
++
++ val = dp_ctrl[voltage][pre].trsv_reg0205;
++ regmap_write(udphy->pma_regmap, 0x0814 + offset, val);
++
++ val = dp_ctrl[voltage][pre].trsv_reg0206;
++ regmap_write(udphy->pma_regmap, 0x0818 + offset, val);
++
++ val = dp_ctrl[voltage][pre].trsv_reg0207;
++ regmap_write(udphy->pma_regmap, 0x081c + offset, val);
++}
++
++static int rk_udphy_dp_phy_configure(struct phy *phy,
++ union phy_configure_opts *opts)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++ struct phy_configure_opts_dp *dp = &opts->dp;
++ u32 i, val, lane;
++ int ret;
++
++ ret = rk_udphy_dp_phy_verify_config(udphy, dp);
++ if (ret)
++ return ret;
++
++ if (dp->set_rate) {
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
++ CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
++
++ switch (dp->link_rate) {
++ case 1620:
++ udphy->bw = DP_BW_RBR;
++ break;
++
++ case 2700:
++ udphy->bw = DP_BW_HBR;
++ break;
++
++ case 5400:
++ udphy->bw = DP_BW_HBR2;
++ break;
++
++ case 8100:
++ udphy->bw = DP_BW_HBR3;
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_LINK_OFFSET, CMN_DP_TX_LINK_BW,
++ FIELD_PREP(CMN_DP_TX_LINK_BW, udphy->bw));
++ regmap_update_bits(udphy->pma_regmap, CMN_SSC_EN_OFFSET, CMN_ROPLL_SSC_EN,
++ FIELD_PREP(CMN_ROPLL_SSC_EN, dp->ssc));
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, CMN_DP_CMN_RSTN,
++ FIELD_PREP(CMN_DP_CMN_RSTN, 0x1));
++
++ ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_ROPLL_DONE_OFFSET, val,
++ FIELD_GET(CMN_ANA_ROPLL_LOCK_DONE, val) &&
++ FIELD_GET(CMN_ANA_ROPLL_AFC_DONE, val),
++ 0, 1000);
++ if (ret) {
++ dev_err(udphy->dev, "ROPLL is not lock, set_rate failed\n");
++ return ret;
++ }
++ }
++
++ if (dp->set_voltages) {
++ for (i = 0; i < dp->lanes; i++) {
++ lane = udphy->dp_lane_sel[i];
++ switch (dp->link_rate) {
++ case 1620:
++ case 2700:
++ regmap_update_bits(udphy->pma_regmap,
++ TRSV_ANA_TX_CLK_OFFSET_N(lane),
++ LN_ANA_TX_SER_TXCLK_INV,
++ FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV,
++ udphy->lane_mux_sel[lane]));
++ break;
++
++ case 5400:
++ case 8100:
++ regmap_update_bits(udphy->pma_regmap,
++ TRSV_ANA_TX_CLK_OFFSET_N(lane),
++ LN_ANA_TX_SER_TXCLK_INV,
++ FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV, 0x0));
++ break;
++ }
++
++ rk_udphy_dp_set_voltage(udphy, udphy->bw, dp->voltage[i],
++ dp->pre[i], lane);
++ }
++ }
++
++ return 0;
++}
++
++static const struct phy_ops rk_udphy_dp_phy_ops = {
++ .init = rk_udphy_dp_phy_init,
++ .exit = rk_udphy_dp_phy_exit,
++ .power_on = rk_udphy_dp_phy_power_on,
++ .power_off = rk_udphy_dp_phy_power_off,
++ .configure = rk_udphy_dp_phy_configure,
++ .owner = THIS_MODULE,
++};
++
++static int rk_udphy_usb3_phy_init(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++ int ret;
++
++ mutex_lock(&udphy->mutex);
++ /* DP only or high-speed, disable U3 port */
++ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) {
++ rk_udphy_u3_port_disable(udphy, true);
++ goto unlock;
++ }
++
++ ret = rk_udphy_power_on(udphy, UDPHY_MODE_USB);
++
++unlock:
++ mutex_unlock(&udphy->mutex);
++ return ret;
++}
++
++static int rk_udphy_usb3_phy_exit(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++ /* DP only or high-speed */
++ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs)
++ goto unlock;
++
++ rk_udphy_power_off(udphy, UDPHY_MODE_USB);
++
++unlock:
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static const struct phy_ops rk_udphy_usb3_phy_ops = {
++ .init = rk_udphy_usb3_phy_init,
++ .exit = rk_udphy_usb3_phy_exit,
++ .owner = THIS_MODULE,
++};
++
++static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
++ struct typec_mux_state *state)
++{
++ struct rk_udphy *udphy = typec_mux_get_drvdata(mux);
++ u8 mode;
++
++ mutex_lock(&udphy->mutex);
++
++ switch (state->mode) {
++ case TYPEC_DP_STATE_C:
++ case TYPEC_DP_STATE_E:
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
++ mode = UDPHY_MODE_DP;
++ break;
++
++ case TYPEC_DP_STATE_D:
++ default:
++ if (udphy->flip) {
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
++ } else {
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
++ }
++ mode = UDPHY_MODE_DP_USB;
++ break;
++ }
++
++ if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
++ struct typec_displayport_data *data = state->data;
++
++ if (!data) {
++ rk_udphy_dp_hpd_event_trigger(udphy, false);
++ } else if (data->status & DP_STATUS_IRQ_HPD) {
++ rk_udphy_dp_hpd_event_trigger(udphy, false);
++ usleep_range(750, 800);
++ rk_udphy_dp_hpd_event_trigger(udphy, true);
++ } else if (data->status & DP_STATUS_HPD_STATE) {
++ if (udphy->mode != mode) {
++ udphy->mode = mode;
++ udphy->mode_change = true;
++ }
++ rk_udphy_dp_hpd_event_trigger(udphy, true);
++ } else {
++ rk_udphy_dp_hpd_event_trigger(udphy, false);
++ }
++ }
++
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static void rk_udphy_typec_mux_unregister(void *data)
++{
++ struct rk_udphy *udphy = data;
++
++ typec_mux_unregister(udphy->mux);
++}
++
++static int rk_udphy_setup_typec_mux(struct rk_udphy *udphy)
++{
++ struct typec_mux_desc mux_desc = {};
++
++ mux_desc.drvdata = udphy;
++ mux_desc.fwnode = dev_fwnode(udphy->dev);
++ mux_desc.set = rk_udphy_typec_mux_set;
++
++ udphy->mux = typec_mux_register(udphy->dev, &mux_desc);
++ if (IS_ERR(udphy->mux)) {
++ dev_err(udphy->dev, "Error register typec mux: %ld\n",
++ PTR_ERR(udphy->mux));
++ return PTR_ERR(udphy->mux);
++ }
++
++ return devm_add_action_or_reset(udphy->dev, rk_udphy_typec_mux_unregister,
++ udphy);
++}
++
++static const struct regmap_config rk_udphy_pma_regmap_cfg = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .fast_io = true,
++ .max_register = 0x20dc,
++};
++
++static struct phy *rk_udphy_phy_xlate(struct device *dev, struct of_phandle_args *args)
++{
++ struct rk_udphy *udphy = dev_get_drvdata(dev);
++
++ if (args->args_count == 0)
++ return ERR_PTR(-EINVAL);
++
++ switch (args->args[0]) {
++ case PHY_TYPE_USB3:
++ return udphy->phy_u3;
++ case PHY_TYPE_DP:
++ return udphy->phy_dp;
++ }
++
++ return ERR_PTR(-EINVAL);
++}
++
++static int rk_udphy_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct phy_provider *phy_provider;
++ struct resource *res;
++ struct rk_udphy *udphy;
++ void __iomem *base;
++ int id, ret;
++
++ udphy = devm_kzalloc(dev, sizeof(*udphy), GFP_KERNEL);
++ if (!udphy)
++ return -ENOMEM;
++
++ udphy->cfgs = device_get_match_data(dev);
++ if (!udphy->cfgs)
++ return dev_err_probe(dev, -EINVAL, "missing match data\n");
++
++ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ /* find the phy-id from the io address */
++ udphy->id = -ENODEV;
++ for (id = 0; id < udphy->cfgs->num_phys; id++) {
++ if (res->start == udphy->cfgs->phy_ids[id]) {
++ udphy->id = id;
++ break;
++ }
++ }
++
++ if (udphy->id < 0)
++ return dev_err_probe(dev, -ENODEV, "no matching device found\n");
++
++ udphy->pma_regmap = devm_regmap_init_mmio(dev, base + UDPHY_PMA,
++ &rk_udphy_pma_regmap_cfg);
++ if (IS_ERR(udphy->pma_regmap))
++ return PTR_ERR(udphy->pma_regmap);
++
++ udphy->dev = dev;
++ ret = rk_udphy_parse_dt(udphy);
++ if (ret)
++ return ret;
++
++ ret = rk_udphy_get_initial_status(udphy);
++ if (ret)
++ return ret;
++
++ mutex_init(&udphy->mutex);
++ platform_set_drvdata(pdev, udphy);
++
++ if (device_property_present(dev, "orientation-switch")) {
++ ret = rk_udphy_setup_orien_switch(udphy);
++ if (ret)
++ return ret;
++ }
++
++ if (device_property_present(dev, "mode-switch")) {
++ ret = rk_udphy_setup_typec_mux(udphy);
++ if (ret)
++ return ret;
++ }
++
++ udphy->phy_u3 = devm_phy_create(dev, dev->of_node, &rk_udphy_usb3_phy_ops);
++ if (IS_ERR(udphy->phy_u3)) {
++ ret = PTR_ERR(udphy->phy_u3);
++ return dev_err_probe(dev, ret, "failed to create USB3 phy\n");
++ }
++ phy_set_drvdata(udphy->phy_u3, udphy);
++
++ udphy->phy_dp = devm_phy_create(dev, dev->of_node, &rk_udphy_dp_phy_ops);
++ if (IS_ERR(udphy->phy_dp)) {
++ ret = PTR_ERR(udphy->phy_dp);
++ return dev_err_probe(dev, ret, "failed to create DP phy\n");
++ }
++ phy_set_bus_width(udphy->phy_dp, rk_udphy_dplane_get(udphy));
++ udphy->phy_dp->attrs.max_link_rate = 8100;
++ phy_set_drvdata(udphy->phy_dp, udphy);
++
++ phy_provider = devm_of_phy_provider_register(dev, rk_udphy_phy_xlate);
++ if (IS_ERR(phy_provider)) {
++ ret = PTR_ERR(phy_provider);
++ return dev_err_probe(dev, ret, "failed to register phy provider\n");
++ }
++
++ return 0;
++}
++
++static int __maybe_unused rk_udphy_resume(struct device *dev)
++{
++ struct rk_udphy *udphy = dev_get_drvdata(dev);
++
++ if (udphy->dp_sink_hpd_sel)
++ rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg);
++
++ return 0;
++}
++
++static const struct dev_pm_ops rk_udphy_pm_ops = {
++ SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, rk_udphy_resume)
++};
++
++static const char * const rk_udphy_rst_list[] = {
++ "init", "cmn", "lane", "pcs_apb", "pma_apb"
++};
++
++static const struct rk_udphy_cfg rk3588_udphy_cfgs = {
++ .num_phys = 2,
++ .phy_ids = {
++ 0xfed80000,
++ 0xfed90000,
++ },
++ .num_rsts = ARRAY_SIZE(rk_udphy_rst_list),
++ .rst_list = rk_udphy_rst_list,
++ .grfcfg = {
++ /* u2phy-grf */
++ .bvalid_phy_con = RK_UDPHY_GEN_GRF_REG(0x0008, 1, 0, 0x2, 0x3),
++ .bvalid_grf_con = RK_UDPHY_GEN_GRF_REG(0x0010, 3, 2, 0x2, 0x3),
++
++ /* usb-grf */
++ .usb3otg0_cfg = RK_UDPHY_GEN_GRF_REG(0x001c, 15, 0, 0x1100, 0x0188),
++ .usb3otg1_cfg = RK_UDPHY_GEN_GRF_REG(0x0034, 15, 0, 0x1100, 0x0188),
++
++ /* usbdpphy-grf */
++ .low_pwrn = RK_UDPHY_GEN_GRF_REG(0x0004, 13, 13, 0, 1),
++ .rx_lfps = RK_UDPHY_GEN_GRF_REG(0x0004, 14, 14, 0, 1),
++ },
++ .vogrfcfg = {
++ {
++ .hpd_trigger = RK_UDPHY_GEN_GRF_REG(0x0000, 11, 10, 1, 3),
++ .dp_lane_reg = 0x0000,
++ },
++ {
++ .hpd_trigger = RK_UDPHY_GEN_GRF_REG(0x0008, 11, 10, 1, 3),
++ .dp_lane_reg = 0x0008,
++ },
++ },
++ .dp_tx_ctrl_cfg = {
++ rk3588_dp_tx_drv_ctrl_rbr_hbr,
++ rk3588_dp_tx_drv_ctrl_rbr_hbr,
++ rk3588_dp_tx_drv_ctrl_hbr2,
++ rk3588_dp_tx_drv_ctrl_hbr3,
++ },
++ .dp_tx_ctrl_cfg_typec = {
++ rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
++ rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
++ rk3588_dp_tx_drv_ctrl_hbr2,
++ rk3588_dp_tx_drv_ctrl_hbr3,
++ },
++};
++
++static const struct of_device_id rk_udphy_dt_match[] = {
++ {
++ .compatible = "rockchip,rk3588-usbdp-phy",
++ .data = &rk3588_udphy_cfgs
++ },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, rk_udphy_dt_match);
++
++static struct platform_driver rk_udphy_driver = {
++ .probe = rk_udphy_probe,
++ .driver = {
++ .name = "rockchip-usbdp-phy",
++ .of_match_table = rk_udphy_dt_match,
++ .pm = &rk_udphy_pm_ops,
++ },
++};
++module_platform_driver(rk_udphy_driver);
++
++MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
++MODULE_AUTHOR("Zhang Yubing <yubing.zhang@rock-chips.com>");
++MODULE_DESCRIPTION("Rockchip USBDP Combo PHY driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch b/target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch
new file mode 100644
index 0000000000..65bd8a7ed8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch
@@ -0,0 +1,35 @@
+From c9342d1a351ee1249fa98d936f756299a83d5684 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 16 Apr 2024 16:51:23 +0200
+Subject: [PATCH] phy: rockchip: usbdp: fix uninitialized variable
+
+The ret variable may not be initialized in rk_udphy_usb3_phy_init(), if
+the PHY is not using USB3 mode.
+
+Since the DisplayPort part is handled separately and the PHY does not
+support USB2 (which is routed to another PHY on Rockchip RK3588), the
+right exit code for this case is 0. Thus let's initialize the variable
+accordingly.
+
+Fixes: 2f70bbddeb457 ("phy: rockchip: add usbdp combo phy driver")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202404141048.qFAYDctQ-lkp@intel.com/
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Reviewed-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
+Link: https://lore.kernel.org/r/20240416145233.94687-1-sebastian.reichel@collabora.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-usbdp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
++++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
+@@ -1285,7 +1285,7 @@ static const struct phy_ops rk_udphy_dp_
+ static int rk_udphy_usb3_phy_init(struct phy *phy)
+ {
+ struct rk_udphy *udphy = phy_get_drvdata(phy);
+- int ret;
++ int ret = 0;
+
+ mutex_lock(&udphy->mutex);
+ /* DP only or high-speed, disable U3 port */
diff --git a/target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch b/target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch
new file mode 100644
index 0000000000..a8b9aa15fc
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch
@@ -0,0 +1,43 @@
+From 9c79b779643e56d4253bd3ba6998c58c819943af Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 15 Apr 2024 19:42:25 +0200
+Subject: [PATCH] phy: rockchip: fix CONFIG_TYPEC dependency
+
+The newly added driver causes a warning about missing dependencies
+by selecting CONFIG_TYPEC unconditionally:
+
+WARNING: unmet direct dependencies detected for TYPEC
+ Depends on [n]: USB_SUPPORT [=n]
+ Selected by [y]:
+ - PHY_ROCKCHIP_USBDP [=y] && ARCH_ROCKCHIP [=y] && OF [=y]
+
+WARNING: unmet direct dependencies detected for USB_COMMON
+ Depends on [n]: USB_SUPPORT [=n]
+ Selected by [y]:
+ - EXTCON_RTK_TYPE_C [=y] && EXTCON [=y] && (ARCH_REALTEK [=y] || COMPILE_TEST [=y]) && TYPEC [=y]
+
+Since that is a user-visible option, it should not really be selected
+in the first place. Replace the 'select' with a 'depends on' as
+we have for similar drivers.
+
+Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240415174241.77982-1-arnd@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/rockchip/Kconfig
++++ b/drivers/phy/rockchip/Kconfig
+@@ -111,8 +111,8 @@ config PHY_ROCKCHIP_USB
+ config PHY_ROCKCHIP_USBDP
+ tristate "Rockchip USBDP COMBO PHY Driver"
+ depends on ARCH_ROCKCHIP && OF
++ depends on TYPEC
+ select GENERIC_PHY
+- select TYPEC
+ help
+ Enable this to support the Rockchip USB3.0/DP combo PHY with
+ Samsung IP block. This is required for USB3 support on RK3588.
diff --git a/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch b/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch
new file mode 100644
index 0000000000..9495dd2b10
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch
@@ -0,0 +1,79 @@
+From 9b6bfad9070a95d19973be17177e5d9220cbbf1f Mon Sep 17 00:00:00 2001
+From: Rick Wertenbroek <rick.wertenbroek@gmail.com>
+Date: Thu, 7 Mar 2024 10:53:18 +0100
+Subject: [PATCH] phy: rockchip: Fix typo in function names
+
+Several functions had "rochchip" instead of "rockchip" in their name.
+Replace "rochchip" by "rockchip".
+
+Signed-off-By: Rick Wertenbroek <rick.wertenbroek@gmail.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240307095318.3651498-1-rick.wertenbroek@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 4 ++--
+ drivers/phy/rockchip/phy-rockchip-snps-pcie3.c | 12 ++++++------
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+@@ -248,7 +248,7 @@ static int rockchip_combphy_exit(struct
+ return 0;
+ }
+
+-static const struct phy_ops rochchip_combphy_ops = {
++static const struct phy_ops rockchip_combphy_ops = {
+ .init = rockchip_combphy_init,
+ .exit = rockchip_combphy_exit,
+ .owner = THIS_MODULE,
+@@ -364,7 +364,7 @@ static int rockchip_combphy_probe(struct
+ return ret;
+ }
+
+- priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops);
++ priv->phy = devm_phy_create(dev, NULL, &rockchip_combphy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(dev, "failed to create combphy\n");
+ return PTR_ERR(priv->phy);
+--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
++++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+@@ -182,7 +182,7 @@ static const struct rockchip_p3phy_ops r
+ .phy_init = rockchip_p3phy_rk3588_init,
+ };
+
+-static int rochchip_p3phy_init(struct phy *phy)
++static int rockchip_p3phy_init(struct phy *phy)
+ {
+ struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy);
+ int ret;
+@@ -205,7 +205,7 @@ static int rochchip_p3phy_init(struct ph
+ return ret;
+ }
+
+-static int rochchip_p3phy_exit(struct phy *phy)
++static int rockchip_p3phy_exit(struct phy *phy)
+ {
+ struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy);
+
+@@ -214,9 +214,9 @@ static int rochchip_p3phy_exit(struct ph
+ return 0;
+ }
+
+-static const struct phy_ops rochchip_p3phy_ops = {
+- .init = rochchip_p3phy_init,
+- .exit = rochchip_p3phy_exit,
++static const struct phy_ops rockchip_p3phy_ops = {
++ .init = rockchip_p3phy_init,
++ .exit = rockchip_p3phy_exit,
+ .set_mode = rockchip_p3phy_set_mode,
+ .owner = THIS_MODULE,
+ };
+@@ -275,7 +275,7 @@ static int rockchip_p3phy_probe(struct p
+ return priv->num_lanes;
+ }
+
+- priv->phy = devm_phy_create(dev, NULL, &rochchip_p3phy_ops);
++ priv->phy = devm_phy_create(dev, NULL, &rockchip_p3phy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(dev, "failed to create combphy\n");
+ return PTR_ERR(priv->phy);
diff --git a/target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch b/target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch
new file mode 100644
index 0000000000..61c3e0e53c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch
@@ -0,0 +1,106 @@
+From a1fe1eca0d8be69ccc1f3d615e5a529df1c82e66 Mon Sep 17 00:00:00 2001
+From: Niklas Cassel <cassel@kernel.org>
+Date: Fri, 12 Apr 2024 14:58:16 +0200
+Subject: [PATCH] phy: rockchip-snps-pcie3: add support for
+ rockchip,rx-common-refclk-mode
+
+>From the RK3588 Technical Reference Manual, Part1,
+section 6.19 PCIe3PHY_GRF Register Description:
+"rxX_cmn_refclk_mode"
+RX common reference clock mode for lane X. This mode should be enabled
+only when the far-end and near-end devices are running with a common
+reference clock.
+
+The hardware reset value for this field is 0x1 (enabled).
+Note that this register field is only available on RK3588, not on RK3568.
+
+The link training either fails or is highly unstable (link state will jump
+continuously between L0 and recovery) when this mode is enabled while
+using an endpoint running in Separate Reference Clock with No SSC (SRNS)
+mode or Separate Reference Clock with SSC (SRIS) mode.
+(Which is usually the case when using a real SoC as endpoint, e.g. the
+RK3588 PCIe controller can run in both Root Complex and Endpoint mode.)
+
+Add support for the device tree property rockchip,rx-common-refclk-mode,
+such that the PCIe PHY can be used in configurations where the Root
+Complex and Endpoint are not using a common reference clock.
+
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Link: https://lore.kernel.org/r/20240412125818.17052-3-cassel@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ .../phy/rockchip/phy-rockchip-snps-pcie3.c | 37 +++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
++++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+@@ -35,11 +35,17 @@
+ #define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0
+ #define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904
+ #define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04
++#define RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1 0x1004
++#define RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1 0x1104
++#define RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1 0x2004
++#define RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1 0x2104
+ #define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0))
+
+ #define RK3588_BIFURCATION_LANE_0_1 BIT(0)
+ #define RK3588_BIFURCATION_LANE_2_3 BIT(1)
+ #define RK3588_LANE_AGGREGATION BIT(2)
++#define RK3588_RX_CMN_REFCLK_MODE_EN ((BIT(7) << 16) | BIT(7))
++#define RK3588_RX_CMN_REFCLK_MODE_DIS (BIT(7) << 16)
+ #define RK3588_PCIE1LN_SEL_EN (GENMASK(1, 0) << 16)
+ #define RK3588_PCIE30_PHY_MODE_EN (GENMASK(2, 0) << 16)
+
+@@ -60,6 +66,7 @@ struct rockchip_p3phy_priv {
+ int num_clks;
+ int num_lanes;
+ u32 lanes[4];
++ u32 rx_cmn_refclk_mode[4];
+ };
+
+ struct rockchip_p3phy_ops {
+@@ -137,6 +144,19 @@ static int rockchip_p3phy_rk3588_init(st
+ u8 mode = RK3588_LANE_AGGREGATION; /* default */
+ int ret;
+
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1,
++ priv->rx_cmn_refclk_mode[0] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1,
++ priv->rx_cmn_refclk_mode[1] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1,
++ priv->rx_cmn_refclk_mode[2] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1,
++ priv->rx_cmn_refclk_mode[3] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++
+ /* Deassert PCIe PMA output clamp mode */
+ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24));
+
+@@ -275,6 +295,23 @@ static int rockchip_p3phy_probe(struct p
+ return priv->num_lanes;
+ }
+
++ ret = of_property_read_variable_u32_array(dev->of_node,
++ "rockchip,rx-common-refclk-mode",
++ priv->rx_cmn_refclk_mode, 1,
++ ARRAY_SIZE(priv->rx_cmn_refclk_mode));
++ /*
++ * if no rockchip,rx-common-refclk-mode, assume enabled for all lanes in
++ * order to be DT backwards compatible. (Since HW reset val is enabled.)
++ */
++ if (ret == -EINVAL) {
++ for (int i = 0; i < ARRAY_SIZE(priv->rx_cmn_refclk_mode); i++)
++ priv->rx_cmn_refclk_mode[i] = 1;
++ } else if (ret < 0) {
++ dev_err(dev, "failed to read rockchip,rx-common-refclk-mode property %d\n",
++ ret);
++ return ret;
++ }
++
+ priv->phy = devm_phy_create(dev, NULL, &rockchip_p3phy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(dev, "failed to create combphy\n");
diff --git a/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch b/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch
new file mode 100644
index 0000000000..0583b70f89
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch
@@ -0,0 +1,91 @@
+From 97789b93b792fc97ad4476b79e0f38ffa8e7e0ee Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 20 Oct 2023 16:11:41 +0200
+Subject: [PATCH] usb: dwc3: add optional PHY interface clocks
+
+On Rockchip RK3588 one of the DWC3 cores is integrated weirdly and
+requires two extra clocks to be enabled. Without these extra clocks
+hot-plugging USB devices is broken.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20231020150022.48725-3-sebastian.reichel@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/core.c | 28 ++++++++++++++++++++++++++++
+ drivers/usb/dwc3/core.h | 4 ++++
+ 2 files changed, 32 insertions(+)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -839,8 +839,20 @@ static int dwc3_clk_enable(struct dwc3 *
+ if (ret)
+ goto disable_ref_clk;
+
++ ret = clk_prepare_enable(dwc->utmi_clk);
++ if (ret)
++ goto disable_susp_clk;
++
++ ret = clk_prepare_enable(dwc->pipe_clk);
++ if (ret)
++ goto disable_utmi_clk;
++
+ return 0;
+
++disable_utmi_clk:
++ clk_disable_unprepare(dwc->utmi_clk);
++disable_susp_clk:
++ clk_disable_unprepare(dwc->susp_clk);
+ disable_ref_clk:
+ clk_disable_unprepare(dwc->ref_clk);
+ disable_bus_clk:
+@@ -850,6 +862,8 @@ disable_bus_clk:
+
+ static void dwc3_clk_disable(struct dwc3 *dwc)
+ {
++ clk_disable_unprepare(dwc->pipe_clk);
++ clk_disable_unprepare(dwc->utmi_clk);
+ clk_disable_unprepare(dwc->susp_clk);
+ clk_disable_unprepare(dwc->ref_clk);
+ clk_disable_unprepare(dwc->bus_clk);
+@@ -1878,6 +1892,20 @@ static int dwc3_get_clocks(struct dwc3 *
+ }
+ }
+
++ /* specific to Rockchip RK3588 */
++ dwc->utmi_clk = devm_clk_get_optional(dev, "utmi");
++ if (IS_ERR(dwc->utmi_clk)) {
++ return dev_err_probe(dev, PTR_ERR(dwc->utmi_clk),
++ "could not get utmi clock\n");
++ }
++
++ /* specific to Rockchip RK3588 */
++ dwc->pipe_clk = devm_clk_get_optional(dev, "pipe");
++ if (IS_ERR(dwc->pipe_clk)) {
++ return dev_err_probe(dev, PTR_ERR(dwc->pipe_clk),
++ "could not get pipe clock\n");
++ }
++
+ return 0;
+ }
+
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -997,6 +997,8 @@ struct dwc3_scratchpad_array {
+ * @bus_clk: clock for accessing the registers
+ * @ref_clk: reference clock
+ * @susp_clk: clock used when the SS phy is in low power (S3) state
++ * @utmi_clk: clock used for USB2 PHY communication
++ * @pipe_clk: clock used for USB3 PHY communication
+ * @reset: reset control
+ * @regs: base address for our registers
+ * @regs_size: address space size
+@@ -1167,6 +1169,8 @@ struct dwc3 {
+ struct clk *bus_clk;
+ struct clk *ref_clk;
+ struct clk *susp_clk;
++ struct clk *utmi_clk;
++ struct clk *pipe_clk;
+
+ struct reset_control *reset;
+
diff --git a/target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch
new file mode 100644
index 0000000000..fcbec5f63a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch
@@ -0,0 +1,35 @@
+From 3eaf2abd11aa7f3b2fb04d60c64b2c756fe030eb Mon Sep 17 00:00:00 2001
+From: Muhammed Efe Cetin <efectn@6tel.net>
+Date: Mon, 9 Oct 2023 22:27:26 +0300
+Subject: [PATCH] arm64: dts: rockchip: Add sfc node to rk3588s
+
+Add SFC (SPI Flash) to RK3588S SOC.
+
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Signed-off-by: Muhammed Efe Cetin <efectn@6tel.net>
+Link: https://lore.kernel.org/r/d36a64edfaede92ce2e158b0d9dc4f5998e019e3.1696878787.git.efectn@6tel.net
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -1425,6 +1425,17 @@
+ };
+ };
+
++ sfc: spi@fe2b0000 {
++ compatible = "rockchip,sfc";
++ reg = <0x0 0xfe2b0000 0x0 0x4000>;
++ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
++ clock-names = "clk_sfc", "hclk_sfc";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ sdmmc: mmc@fe2c0000 {
+ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xfe2c0000 0x0 0x4000>;
diff --git a/target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch
new file mode 100644
index 0000000000..25526ba23c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch
@@ -0,0 +1,58 @@
+From bf012368bb0ab69167d49715789fac34dfcd457e Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Sun, 8 Oct 2023 15:04:59 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add I2S2 M0 pin definitions to rk3588s
+
+This is used on Orange Pi 5 Plus.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Link: https://lore.kernel.org/r/20231008130515.1155664-2-megi@xff.cz
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588s-pinctrl.dtsi | 35 +++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
+@@ -1350,6 +1350,41 @@
+
+ i2s2 {
+ /omit-if-no-ref/
++ i2s2m0_lrck: i2s2m0-lrck {
++ rockchip,pins =
++ /* i2s2m0_lrck */
++ <2 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_mclk: i2s2m0-mclk {
++ rockchip,pins =
++ /* i2s2m0_mclk */
++ <2 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sclk: i2s2m0-sclk {
++ rockchip,pins =
++ /* i2s2m0_sclk */
++ <2 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdi: i2s2m0-sdi {
++ rockchip,pins =
++ /* i2s2m0_sdi */
++ <2 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdo: i2s2m0-sdo {
++ rockchip,pins =
++ /* i2s2m0_sdo */
++ <4 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
+ i2s2m1_lrck: i2s2m1-lrck {
+ rockchip,pins =
+ /* i2s2m1_lrck */
diff --git a/target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch b/target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch
new file mode 100644
index 0000000000..4a9cb6ea39
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch
@@ -0,0 +1,32 @@
+From 3d77a3e51b0faed820a8db985dce5af1cc4eae32 Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Sun, 8 Oct 2023 15:05:00 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add UART9 M0 pin definitions to rk3588s
+
+This is used on Orange Pi 5 Plus.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Link: https://lore.kernel.org/r/20231008130515.1155664-3-megi@xff.cz
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
+@@ -3343,6 +3343,15 @@
+
+ uart9 {
+ /omit-if-no-ref/
++ uart9m0_xfer: uart9m0-xfer {
++ rockchip,pins =
++ /* uart9_rx_m0 */
++ <2 RK_PC4 10 &pcfg_pull_up>,
++ /* uart9_tx_m0 */
++ <2 RK_PC2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
+ uart9m1_xfer: uart9m1-xfer {
+ rockchip,pins =
+ /* uart9_rx_m1 */
diff --git a/target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch
new file mode 100644
index 0000000000..6fce4f0f4c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch
@@ -0,0 +1,37 @@
+From dd6dc0c4c1265129c229e26917bf4de1d97ff91f Mon Sep 17 00:00:00 2001
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Date: Fri, 6 Oct 2023 08:53:34 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add AV1 decoder node to rk3588s
+
+Add node for AV1 video decoder.
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231006065334.8117-1-benjamin.gaignard@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -2314,6 +2314,19 @@
+ #interrupt-cells = <2>;
+ };
+ };
++
++ av1d: video-codec@fdc70000 {
++ compatible = "rockchip,rk3588-av1-vpu";
++ reg = <0x0 0xfdc70000 0x0 0x800>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "vdpu";
++ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ assigned-clock-rates = <400000000>, <400000000>;
++ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ clock-names = "aclk", "hclk";
++ power-domains = <&power RK3588_PD_AV1>;
++ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
++ };
+ };
+
+ #include "rk3588s-pinctrl.dtsi"
diff --git a/target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch
new file mode 100644
index 0000000000..714dc4883b
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch
@@ -0,0 +1,50 @@
+From 5a6976b1040a2f99ab84eddbfa7cd072ac5d10fc Mon Sep 17 00:00:00 2001
+From: Sascha Hauer <s.hauer@pengutronix.de>
+Date: Wed, 18 Oct 2023 08:17:14 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add DFI to rk3588s
+
+The DFI unit can be used to measure DRAM utilization using perf. Add the
+node to the device tree. The DFI needs a rockchip,pmu phandle to the pmu
+containing registers for SDRAM configuration details. This is added in
+this patch as well.
+
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Link: https://lore.kernel.org/r/20231018061714.3553817-27-s.hauer@pengutronix.de
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -443,6 +443,11 @@
+ status = "disabled";
+ };
+
++ pmu1grf: syscon@fd58a000 {
++ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd58a000 0x0 0x10000>;
++ };
++
+ sys_grf: syscon@fd58c000 {
+ compatible = "rockchip,rk3588-sys-grf", "syscon";
+ reg = <0x0 0xfd58c000 0x0 0x1000>;
+@@ -1330,6 +1335,17 @@
+ };
+ };
+
++ dfi: dfi@fe060000 {
++ reg = <0x00 0xfe060000 0x00 0x10000>;
++ compatible = "rockchip,rk3588-dfi";
++ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "ch0", "ch1", "ch2", "ch3";
++ rockchip,pmu = <&pmu1grf>;
++ };
++
+ gmac1: ethernet@fe1c0000 {
+ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+ reg = <0x0 0xfe1c0000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch b/target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch
new file mode 100644
index 0000000000..f4e835a9f5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch
@@ -0,0 +1,48 @@
+From bbd3778da16b3d448832b843f80bcde1aff26290 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 20 Oct 2023 16:11:42 +0200
+Subject: [PATCH] arm64: dts: rockchip: rk3588s: Add USB3 host controller
+
+RK3588 has three USB3 controllers. This adds the host-only controller,
+which is using the naneng-combphy shared with PCIe and SATA.
+
+The other two are dual-role and using a different PHY that is not yet
+supported upstream.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231020150022.48725-4-sebastian.reichel@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -443,6 +443,27 @@
+ status = "disabled";
+ };
+
++ usb_host2_xhci: usb@fcd00000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfcd00000 0x0 0x400000>;
++ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
++ <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
++ <&cru CLK_PIPEPHY2_PIPE_U3_G>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
++ dr_mode = "host";
++ phys = <&combphy2_psu PHY_TYPE_USB3>;
++ phy-names = "usb3-phy";
++ phy_type = "utmi_wide";
++ resets = <&cru SRST_A_USB3OTG2>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ snps,dis_rxdet_inp3_quirk;
++ status = "disabled";
++ };
++
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch b/target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch
new file mode 100644
index 0000000000..9076ca2d13
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch
@@ -0,0 +1,27 @@
+From 815f986f33eeb06652d59d8a4d405d4fdb4e59a8 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 1 Dec 2023 14:48:59 +0100
+Subject: [PATCH] arm64: dts: rockchip: drop interrupt-names property from
+ rk3588s dfi
+
+The dfi binding does not specify interrupt names, with the interrupts
+just specifying channels 0-x. So drop the unspecified property.
+
+Fixes: 5a6976b1040a ("arm64: dts: rockchip: Add DFI to rk3588s")
+Reported-by: Jagan Teki <jagan@edgeble.ai>
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Link: https://lore.kernel.org/r/20231201134859.322491-1-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -1363,7 +1363,6 @@
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "ch0", "ch1", "ch2", "ch3";
+ rockchip,pmu = <&pmu1grf>;
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..60c2b269b5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch
@@ -0,0 +1,139 @@
+From 9918d10d16665527e59fdb87c5acac70cc1cfe8f Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:39 +0100
+Subject: [PATCH] arm64: dts: rockchip: move rk3588 serial aliases to soc dtsi
+
+The serial ports on rk3588 are named uart0 - uart9. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+
+To prevent each board repeating their list of serial aliases, move them
+to the soc dtsi, as all previous Rockchip soc do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-2-heiko@sntech.de
+---
+ .../boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts | 4 ----
+ .../boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts | 4 ----
+ arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 1 -
+ .../boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi | 2 --
+ .../boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 1 -
+ .../boot/dts/rockchip/rk3588s-khadas-edge2.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 13 +++++++++++++
+ 13 files changed, 13 insertions(+), 19 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts
+@@ -12,10 +12,6 @@
+ compatible = "edgeble,neural-compute-module-6a-io",
+ "edgeble,neural-compute-module-6a", "rockchip,rk3588";
+
+- aliases {
+- serial2 = &uart2;
+- };
+-
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts
+@@ -12,10 +12,6 @@
+ compatible = "edgeble,neural-compute-module-6b-io",
+ "edgeble,neural-compute-module-6b", "rockchip,rk3588";
+
+- aliases {
+- serial2 = &uart2;
+- };
+-
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+@@ -16,7 +16,6 @@
+
+ aliases {
+ mmc0 = &sdhci;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -19,7 +19,6 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -12,7 +12,6 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+@@ -15,7 +15,6 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+@@ -12,7 +12,6 @@
+
+ aliases {
+ mmc0 = &sdhci;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -14,7 +14,6 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+- serial2 = &uart2;
+ };
+
+ analog-sound {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -18,6 +18,19 @@
+ #address-cells = <2>;
+ #size-cells = <2>;
+
++ aliases {
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial5 = &uart5;
++ serial6 = &uart6;
++ serial7 = &uart7;
++ serial8 = &uart8;
++ serial9 = &uart9;
++ };
++
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
diff --git a/target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..2daaec3953
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch
@@ -0,0 +1,38 @@
+From 328e901b7b03d292c1520ffb38e9164feef4f1ea Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:40 +0100
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 i2c aliases to soc dtsi
+
+The i2c controllers on rk3588 are named i2c0 - i2c8. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+Userspace i2c access is a thing afterall.
+
+To prevent each board repeating their list of i2c aliases, define them
+in the soc dtsi, as all previous Rockchip soc do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-3-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -19,6 +19,15 @@
+ #size-cells = <2>;
+
+ aliases {
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c7 = &i2c7;
++ i2c8 = &i2c8;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
diff --git a/target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..19e6c6a4f5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch
@@ -0,0 +1,34 @@
+From a024abedbca99a20aeb96f5beec9ded13c85dcb3 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:41 +0100
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 gpio aliases to soc dtsi
+
+The gpio controllers on rk3588 are named gpio0 - gpio4. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+Userspace gpio access is a thing afterall.
+
+To prevent each board repeating their list of gpio aliases, define them
+in the soc dtsi, as previous Rockchip soc like the rk356x do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-4-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -19,6 +19,11 @@
+ #size-cells = <2>;
+
+ aliases {
++ gpio0 = &gpio0;
++ gpio1 = &gpio1;
++ gpio2 = &gpio2;
++ gpio3 = &gpio3;
++ gpio4 = &gpio4;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
diff --git a/target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..6a66d99668
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch
@@ -0,0 +1,34 @@
+From a86e88043de929da76f7f6cf0990ba92aed8391a Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:42 +0100
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 spi aliases to soc dtsi
+
+The spi controllers on rk3588 are named spi0 - spi4. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+Userspace spi access is a thing afterall.
+
+To prevent each board repeating their list of spi aliases, define them
+in the soc dtsi, as previous Rockchip soc like the rk356x do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-5-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -43,6 +43,11 @@
+ serial7 = &uart7;
+ serial8 = &uart8;
+ serial9 = &uart9;
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
+ };
+
+ cpus {
diff --git a/target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch
new file mode 100644
index 0000000000..3936df7a73
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch
@@ -0,0 +1,120 @@
+From d895dbef3f3a31ab50491bb48552e798cf555987 Mon Sep 17 00:00:00 2001
+From: Andy Yan <andy.yan@rock-chips.com>
+Date: Mon, 11 Dec 2023 20:00:04 +0800
+Subject: [PATCH] arm64: dts: rockchip: Add vop on rk3588
+
+Add vop dt node for rk3588.
+
+Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
+Link: https://lore.kernel.org/r/20231211120004.1785616-1-andyshrk@163.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 83 +++++++++++++++++++++++
+ 1 file changed, 83 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -394,6 +394,11 @@
+ #clock-cells = <0>;
+ };
+
++ display_subsystem: display-subsystem {
++ compatible = "rockchip,display-subsystem";
++ ports = <&vop_out>;
++ };
++
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+@@ -506,6 +511,16 @@
+ reg = <0x0 0xfd58c000 0x0 0x1000>;
+ };
+
++ vop_grf: syscon@fd5a4000 {
++ compatible = "rockchip,rk3588-vop-grf", "syscon";
++ reg = <0x0 0xfd5a4000 0x0 0x2000>;
++ };
++
++ vo1_grf: syscon@fd5a8000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a8000 0x0 0x100>;
++ };
++
+ php_grf: syscon@fd5b0000 {
+ compatible = "rockchip,rk3588-php-grf", "syscon";
+ reg = <0x0 0xfd5b0000 0x0 0x1000>;
+@@ -625,6 +640,74 @@
+ status = "disabled";
+ };
+
++ vop: vop@fdd90000 {
++ compatible = "rockchip,rk3588-vop";
++ reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
++ reg-names = "vop", "gamma-lut";
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>,
++ <&cru HCLK_VOP>,
++ <&cru DCLK_VOP0>,
++ <&cru DCLK_VOP1>,
++ <&cru DCLK_VOP2>,
++ <&cru DCLK_VOP3>,
++ <&cru PCLK_VOP_ROOT>;
++ clock-names = "aclk",
++ "hclk",
++ "dclk_vp0",
++ "dclk_vp1",
++ "dclk_vp2",
++ "dclk_vp3",
++ "pclk_vop";
++ iommus = <&vop_mmu>;
++ power-domains = <&power RK3588_PD_VOP>;
++ rockchip,grf = <&sys_grf>;
++ rockchip,vop-grf = <&vop_grf>;
++ rockchip,vo1-grf = <&vo1_grf>;
++ rockchip,pmu = <&pmu>;
++ status = "disabled";
++
++ vop_out: ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ vp0: port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ };
++
++ vp1: port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ };
++
++ vp2: port@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ };
++
++ vp3: port@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ };
++ };
++ };
++
++ vop_mmu: iommu@fdd97e00 {
++ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
++ reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
++ clock-names = "aclk", "iface";
++ #iommu-cells = <0>;
++ power-domains = <&power RK3588_PD_VOP>;
++ status = "disabled";
++ };
++
+ uart0: serial@fd890000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfd890000 0x0 0x100>;
diff --git a/target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch b/target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch
new file mode 100644
index 0000000000..d9bd3ab019
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch
@@ -0,0 +1,51 @@
+From 11d28971aaaf5de6f50790fb21f1113fee21d320 Mon Sep 17 00:00:00 2001
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Date: Mon, 19 Feb 2024 22:46:25 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add HDMI0 PHY to rk3588
+
+Add DT nodes for HDMI0 PHY and related syscon found on RK3588 SoC.
+
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Link: https://lore.kernel.org/r/20240219204626.284399-1-cristian.ciocaltea@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -586,6 +586,11 @@
+ };
+ };
+
++ hdptxphy0_grf: syscon@fd5e0000 {
++ compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
++ reg = <0x0 0xfd5e0000 0x0 0x100>;
++ };
++
+ ioc: syscon@fd5f0000 {
+ compatible = "rockchip,rk3588-ioc", "syscon";
+ reg = <0x0 0xfd5f0000 0x0 0x10000>;
+@@ -2358,6 +2363,22 @@
+ #dma-cells = <1>;
+ };
+
++ hdptxphy_hdmi0: 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";
++ #phy-cells = <0>;
++ resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
++ <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
++ <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
++ <&cru SRST_HDPTX0_LCPLL>;
++ reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
++ "lcpll";
++ rockchip,grf = <&hdptxphy0_grf>;
++ status = "disabled";
++ };
++
+ combphy0_ps: phy@fee00000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee00000 0x0 0x100>;
diff --git a/target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch
new file mode 100644
index 0000000000..6ffc2c751a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch
@@ -0,0 +1,25 @@
+From 2047366b9eff8fada2a118588b0478de6e92d02c Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko@sntech.de>
+Date: Tue, 27 Feb 2024 22:05:21 +0100
+Subject: [PATCH] arm64: dts: rockchip: add clock to vo1-grf syscon on rk3588
+
+The VO*-general-register-files need a clock, so add the correct one.
+
+Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240227210521.724754-1-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -519,6 +519,7 @@
+ vo1_grf: syscon@fd5a8000 {
+ compatible = "rockchip,rk3588-vo-grf", "syscon";
+ reg = <0x0 0xfd5a8000 0x0 0x100>;
++ clocks = <&cru PCLK_VO1GRF>;
+ };
+
+ php_grf: syscon@fd5b0000 {
diff --git a/target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch b/target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch
new file mode 100644
index 0000000000..dafdd69d68
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch
@@ -0,0 +1,81 @@
+From 6fca4edb93d335f29f81e484936f38a5eed6a9b1 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@collabora.com>
+Date: Tue, 26 Mar 2024 17:52:06 +0100
+Subject: [PATCH] arm64: dts: rockchip: Add rk3588 GPU node
+
+Add Mali GPU Node to the RK3588 SoC DT including GPU clock
+operating points
+
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240326165232.73585-3-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 56 +++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -501,6 +501,62 @@
+ status = "disabled";
+ };
+
++ gpu: gpu@fb000000 {
++ compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
++ reg = <0x0 0xfb000000 0x0 0x200000>;
++ #cooling-cells = <2>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
++ assigned-clock-rates = <200000000>;
++ clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ clock-names = "core", "coregroup", "stacks";
++ dynamic-power-coefficient = <2982>;
++ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "job", "mmu", "gpu";
++ operating-points-v2 = <&gpu_opp_table>;
++ power-domains = <&power RK3588_PD_GPU>;
++ status = "disabled";
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
++ };
++
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch
new file mode 100644
index 0000000000..7b69e0a195
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch
@@ -0,0 +1,384 @@
+From cbb97fe18e299ece1c0074924c630de6a19b320f Mon Sep 17 00:00:00 2001
+From: Diederik de Haas <didi.debian@cknow.org>
+Date: Sat, 6 Apr 2024 19:28:04 +0200
+Subject: [PATCH] arm64: dts: rockchip: Fix ordering of nodes on rk3588s
+
+Fix the ordering of the main nodes by sorting them alphabetically and
+then the ones with a memory address sequentially by that address.
+
+Signed-off-by: Diederik de Haas <didi.debian@cknow.org>
+Link: https://lore.kernel.org/r/20240406172821.34173-1-didi.debian@cknow.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 304 +++++++++++-----------
+ 1 file changed, 152 insertions(+), 152 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -347,6 +347,11 @@
+ };
+ };
+
++ display_subsystem: display-subsystem {
++ compatible = "rockchip,display-subsystem";
++ ports = <&vop_out>;
++ };
++
+ firmware {
+ optee: optee {
+ compatible = "linaro,optee-tz";
+@@ -394,11 +399,6 @@
+ #clock-cells = <0>;
+ };
+
+- display_subsystem: display-subsystem {
+- compatible = "rockchip,display-subsystem";
+- ports = <&vop_out>;
+- };
+-
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+@@ -436,6 +436,62 @@
+ };
+ };
+
++ gpu: gpu@fb000000 {
++ compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
++ reg = <0x0 0xfb000000 0x0 0x200000>;
++ #cooling-cells = <2>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
++ assigned-clock-rates = <200000000>;
++ clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ clock-names = "core", "coregroup", "stacks";
++ dynamic-power-coefficient = <2982>;
++ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "job", "mmu", "gpu";
++ operating-points-v2 = <&gpu_opp_table>;
++ power-domains = <&power RK3588_PD_GPU>;
++ status = "disabled";
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
++ };
++
+ usb_host0_ehci: usb@fc800000 {
+ compatible = "rockchip,rk3588-ehci", "generic-ehci";
+ reg = <0x0 0xfc800000 0x0 0x40000>;
+@@ -501,62 +557,6 @@
+ status = "disabled";
+ };
+
+- gpu: gpu@fb000000 {
+- compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
+- reg = <0x0 0xfb000000 0x0 0x200000>;
+- #cooling-cells = <2>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+- assigned-clock-rates = <200000000>;
+- clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
+- <&cru CLK_GPU_STACKS>;
+- clock-names = "core", "coregroup", "stacks";
+- dynamic-power-coefficient = <2982>;
+- interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "job", "mmu", "gpu";
+- operating-points-v2 = <&gpu_opp_table>;
+- power-domains = <&power RK3588_PD_GPU>;
+- status = "disabled";
+-
+- gpu_opp_table: opp-table {
+- compatible = "operating-points-v2";
+-
+- opp-300000000 {
+- opp-hz = /bits/ 64 <300000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-400000000 {
+- opp-hz = /bits/ 64 <400000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-500000000 {
+- opp-hz = /bits/ 64 <500000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-600000000 {
+- opp-hz = /bits/ 64 <600000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-700000000 {
+- opp-hz = /bits/ 64 <700000000>;
+- opp-microvolt = <700000 700000 850000>;
+- };
+- opp-800000000 {
+- opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <750000 750000 850000>;
+- };
+- opp-900000000 {
+- opp-hz = /bits/ 64 <900000000>;
+- opp-microvolt = <800000 800000 850000>;
+- };
+- opp-1000000000 {
+- opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <850000 850000 850000>;
+- };
+- };
+- };
+-
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
+@@ -702,74 +702,6 @@
+ status = "disabled";
+ };
+
+- vop: vop@fdd90000 {
+- compatible = "rockchip,rk3588-vop";
+- reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
+- reg-names = "vop", "gamma-lut";
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>,
+- <&cru HCLK_VOP>,
+- <&cru DCLK_VOP0>,
+- <&cru DCLK_VOP1>,
+- <&cru DCLK_VOP2>,
+- <&cru DCLK_VOP3>,
+- <&cru PCLK_VOP_ROOT>;
+- clock-names = "aclk",
+- "hclk",
+- "dclk_vp0",
+- "dclk_vp1",
+- "dclk_vp2",
+- "dclk_vp3",
+- "pclk_vop";
+- iommus = <&vop_mmu>;
+- power-domains = <&power RK3588_PD_VOP>;
+- rockchip,grf = <&sys_grf>;
+- rockchip,vop-grf = <&vop_grf>;
+- rockchip,vo1-grf = <&vo1_grf>;
+- rockchip,pmu = <&pmu>;
+- status = "disabled";
+-
+- vop_out: ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- vp0: port@0 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <0>;
+- };
+-
+- vp1: port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <1>;
+- };
+-
+- vp2: port@2 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <2>;
+- };
+-
+- vp3: port@3 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <3>;
+- };
+- };
+- };
+-
+- vop_mmu: iommu@fdd97e00 {
+- compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
+- reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+- clock-names = "aclk", "iface";
+- #iommu-cells = <0>;
+- power-domains = <&power RK3588_PD_VOP>;
+- status = "disabled";
+- };
+-
+ uart0: serial@fd890000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfd890000 0x0 0x100>;
+@@ -1140,6 +1072,87 @@
+ };
+ };
+
++ av1d: video-codec@fdc70000 {
++ compatible = "rockchip,rk3588-av1-vpu";
++ reg = <0x0 0xfdc70000 0x0 0x800>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "vdpu";
++ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ assigned-clock-rates = <400000000>, <400000000>;
++ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ clock-names = "aclk", "hclk";
++ power-domains = <&power RK3588_PD_AV1>;
++ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
++ };
++
++ vop: vop@fdd90000 {
++ compatible = "rockchip,rk3588-vop";
++ reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
++ reg-names = "vop", "gamma-lut";
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>,
++ <&cru HCLK_VOP>,
++ <&cru DCLK_VOP0>,
++ <&cru DCLK_VOP1>,
++ <&cru DCLK_VOP2>,
++ <&cru DCLK_VOP3>,
++ <&cru PCLK_VOP_ROOT>;
++ clock-names = "aclk",
++ "hclk",
++ "dclk_vp0",
++ "dclk_vp1",
++ "dclk_vp2",
++ "dclk_vp3",
++ "pclk_vop";
++ iommus = <&vop_mmu>;
++ power-domains = <&power RK3588_PD_VOP>;
++ rockchip,grf = <&sys_grf>;
++ rockchip,vop-grf = <&vop_grf>;
++ rockchip,vo1-grf = <&vo1_grf>;
++ rockchip,pmu = <&pmu>;
++ status = "disabled";
++
++ vop_out: ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ vp0: port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ };
++
++ vp1: port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ };
++
++ vp2: port@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ };
++
++ vp3: port@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ };
++ };
++ };
++
++ vop_mmu: iommu@fdd97e00 {
++ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
++ reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
++ clock-names = "aclk", "iface";
++ #iommu-cells = <0>;
++ power-domains = <&power RK3588_PD_VOP>;
++ status = "disabled";
++ };
++
+ i2s4_8ch: i2s@fddc0000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddc0000 0x0 0x1000>;
+@@ -1431,6 +1444,16 @@
+ reg = <0x0 0xfdf82200 0x0 0x20>;
+ };
+
++ dfi: dfi@fe060000 {
++ reg = <0x00 0xfe060000 0x00 0x10000>;
++ compatible = "rockchip,rk3588-dfi";
++ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
++ rockchip,pmu = <&pmu1grf>;
++ };
++
+ pcie2x1l1: pcie@fe180000 {
+ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+ bus-range = <0x30 0x3f>;
+@@ -1533,16 +1556,6 @@
+ };
+ };
+
+- dfi: dfi@fe060000 {
+- reg = <0x00 0xfe060000 0x00 0x10000>;
+- compatible = "rockchip,rk3588-dfi";
+- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+- rockchip,pmu = <&pmu1grf>;
+- };
+-
+ gmac1: ethernet@fe1c0000 {
+ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+ reg = <0x0 0xfe1c0000 0x0 0x10000>;
+@@ -2543,19 +2556,6 @@
+ #interrupt-cells = <2>;
+ };
+ };
+-
+- av1d: video-codec@fdc70000 {
+- compatible = "rockchip,rk3588-av1-vpu";
+- reg = <0x0 0xfdc70000 0x0 0x800>;
+- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "vdpu";
+- assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- assigned-clock-rates = <400000000>, <400000000>;
+- clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- clock-names = "aclk", "hclk";
+- power-domains = <&power RK3588_PD_AV1>;
+- resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+- };
+ };
+
+ #include "rk3588s-pinctrl.dtsi"
diff --git a/target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch b/target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch
new file mode 100644
index 0000000000..065cb4b410
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch
@@ -0,0 +1,35 @@
+From 4e07a95f7402de092cd71b2cb96c69f85c98f251 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:31 +0200
+Subject: [PATCH] arm64: dts: rockchip: fix usb2phy nodename for rk3588
+
+usb2-phy should be named usb2phy according to the DT binding,
+so let's fix it up accordingly.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-5-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -599,7 +599,7 @@
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+- u2phy2: usb2-phy@8000 {
++ u2phy2: usb2phy@8000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0x8000 0x10>;
+ interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+@@ -624,7 +624,7 @@
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+- u2phy3: usb2-phy@c000 {
++ u2phy3: usb2phy@c000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0xc000 0x10>;
+ interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
diff --git a/target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch b/target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch
new file mode 100644
index 0000000000..81e8ed1011
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch
@@ -0,0 +1,53 @@
+From abe68e0ca71dddce0e5419e35507cb464d61870d Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:32 +0200
+Subject: [PATCH] arm64: dts: rockchip: reorder usb2phy properties for rk3588
+
+Reorder common DT properties alphabetically for usb2phy, according
+to latest DT style rules.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-6-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -602,13 +602,13 @@
+ u2phy2: usb2phy@8000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0x8000 0x10>;
+- interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
+- reset-names = "phy", "apb";
++ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy2";
+- #clock-cells = <0>;
++ interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
++ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy2_host: host-port {
+@@ -627,13 +627,13 @@
+ u2phy3: usb2phy@c000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0xc000 0x10>;
+- interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
+- reset-names = "phy", "apb";
++ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy3";
+- #clock-cells = <0>;
++ interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
++ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy3_host: host-port {
diff --git a/target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch
new file mode 100644
index 0000000000..985a799df1
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch
@@ -0,0 +1,175 @@
+From e18e5e8188f2671abf63abe7db5f21555705130f Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:33 +0200
+Subject: [PATCH] arm64: dts: rockchip: add USBDP phys on rk3588
+
+Add both USB3-DisplayPort PHYs to RK3588 SoC DT.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-7-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 52 +++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 63 +++++++++++++++++++++++
+ 2 files changed, 115 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -17,6 +17,36 @@
+ reg = <0x0 0xfd5c0000 0x0 0x100>;
+ };
+
++ usbdpphy1_grf: syscon@fd5cc000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5cc000 0x0 0x4000>;
++ };
++
++ usb2phy1_grf: syscon@fd5d4000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d4000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy1: usb2phy@4000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x4000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy1";
++ interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy1_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
+ i2s8_8ch: i2s@fddc8000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddc8000 0x0 0x1000>;
+@@ -310,6 +340,28 @@
+ };
+ };
+
++ usbdp_phy1: phy@fed90000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed90000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY1_IMMORTAL>,
++ <&cru PCLK_USBDPPHY1>,
++ <&u2phy1>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY1_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY1_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY1_PCS>,
++ <&cru SRST_P_USBDPPHY1>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy1_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
+ combphy1_ps: phy@fee10000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee10000 0x0 0x100>;
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -572,12 +572,23 @@
+ reg = <0x0 0xfd5a4000 0x0 0x2000>;
+ };
+
++ vo0_grf: syscon@fd5a6000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a6000 0x0 0x2000>;
++ clocks = <&cru PCLK_VO0GRF>;
++ };
++
+ vo1_grf: syscon@fd5a8000 {
+ compatible = "rockchip,rk3588-vo-grf", "syscon";
+ reg = <0x0 0xfd5a8000 0x0 0x100>;
+ clocks = <&cru PCLK_VO1GRF>;
+ };
+
++ usb_grf: syscon@fd5ac000 {
++ compatible = "rockchip,rk3588-usb-grf", "syscon";
++ reg = <0x0 0xfd5ac000 0x0 0x4000>;
++ };
++
+ php_grf: syscon@fd5b0000 {
+ compatible = "rockchip,rk3588-php-grf", "syscon";
+ reg = <0x0 0xfd5b0000 0x0 0x1000>;
+@@ -593,6 +604,36 @@
+ reg = <0x0 0xfd5c4000 0x0 0x100>;
+ };
+
++ usbdpphy0_grf: syscon@fd5c8000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5c8000 0x0 0x4000>;
++ };
++
++ usb2phy0_grf: syscon@fd5d0000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d0000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy0: usb2phy@0 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x0 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy0";
++ interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy0_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
+ usb2phy2_grf: syscon@fd5d8000 {
+ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd5d8000 0x0 0x4000>;
+@@ -2449,6 +2490,28 @@
+ status = "disabled";
+ };
+
++ usbdp_phy0: phy@fed80000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed80000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY0_IMMORTAL>,
++ <&cru PCLK_USBDPPHY0>,
++ <&u2phy0>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY0_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY0_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY0_PCS>,
++ <&cru SRST_P_USBDPPHY0>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy0_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
+ combphy0_ps: phy@fee00000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee00000 0x0 0x100>;
diff --git a/target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch
new file mode 100644
index 0000000000..7bfa205514
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch
@@ -0,0 +1,75 @@
+From 33f393a2a990e16f56931ca708295f31d2b44415 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:34 +0200
+Subject: [PATCH] arm64: dts: rockchip: add USB3 DRD controllers on rk3588
+
+Add both USB3 dual-role controllers to the RK3588 devicetree.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-8-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 20 ++++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 22 ++++++++++++++++++++++
+ 2 files changed, 42 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -7,6 +7,26 @@
+ #include "rk3588-pinctrl.dtsi"
+
+ / {
++ usb_host1_xhci: usb@fc400000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc400000 0x0 0x400000>;
++ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
++ <&cru ACLK_USB3OTG1>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG1>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
+ pcie30_phy_grf: syscon@fd5b8000 {
+ compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
+ reg = <0x0 0xfd5b8000 0x0 0x10000>;
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -492,6 +492,28 @@
+ };
+ };
+
++ usb_host0_xhci: usb@fc000000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc000000 0x0 0x400000>;
++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
++ <&cru ACLK_USB3OTG0>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG0>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u1-entry-quirk;
++ snps,dis-u2-entry-quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
+ usb_host0_ehci: usb@fc800000 {
+ compatible = "rockchip,rk3588-ehci", "generic-ehci";
+ reg = <0x0 0xfc800000 0x0 0x40000>;
diff --git a/target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch b/target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch
new file mode 100644
index 0000000000..fa98e5ec70
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch
@@ -0,0 +1,74 @@
+From cd81d3a0695cc54ad6ac0ef4bbb67a7c8f55d592 Mon Sep 17 00:00:00 2001
+From: Niklas Cassel <cassel@kernel.org>
+Date: Thu, 2 May 2024 16:02:32 +0200
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 pcie and php IOMMUs
+
+The mmu600_pcie is connected with the five PCIe controllers.
+The mmu600_php is connected with the USB3 controller, the GMAC
+controllers, and the SATA controllers.
+
+See 8.2 Block Diagram, in rk3588 TRM (Technical Reference Manual).
+
+The IOMMUs are disabled by default, as further patches are needed to
+program the SID/SSIDs in to the IOMMUs.
+
+iommu: Default domain type: Translated
+iommu: DMA domain TLB invalidation policy: strict mode
+arm-smmu-v3 fc900000.iommu: ias 48-bit, oas 48-bit (features 0x001c1eaf)
+arm-smmu-v3 fc900000.iommu: allocated 65536 entries for cmdq
+arm-smmu-v3 fc900000.iommu: allocated 32768 entries for evtq
+arm-smmu-v3 fc900000.iommu: msi_domain absent - falling back to wired irqs
+
+Additionally, the IOMMU correctly triggers an IOMMU fault when
+a PCIe device performs a write (since the device hasn't been
+assigned a SID/SSID):
+arm-smmu-v3 fc900000.iommu: event 0x02 received:
+arm-smmu-v3 fc900000.iommu: 0x0000010000000002
+arm-smmu-v3 fc900000.iommu: 0x0000000000000000
+arm-smmu-v3 fc900000.iommu: 0x0000000000000000
+arm-smmu-v3 fc900000.iommu: 0x0000000000000000
+
+While this doesn't provide much value as is, having the devices as
+disabled in the device tree will allow developers to see that the rk3588
+actually has IOMMUs on the SoC.
+
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Link: https://lore.kernel.org/r/20240502140231.477049-2-cassel@kernel.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 24 +++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -579,6 +579,30 @@
+ status = "disabled";
+ };
+
++ mmu600_pcie: iommu@fc900000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfc900000 0x0 0x200000>;
++ interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ mmu600_php: iommu@fcb00000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfcb00000 0x0 0x200000>;
++ interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch b/target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch
new file mode 100644
index 0000000000..08460b5b41
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch
@@ -0,0 +1,14208 @@
+From def88eb4d8365a4aa064d28405d03550a9d0a3be Mon Sep 17 00:00:00 2001
+From: Dragan Simic <dsimic@manjaro.org>
+Date: Sun, 9 Jun 2024 10:58:19 +0200
+Subject: [PATCH] arm64: dts: rockchip: Prepare RK3588 SoC dtsi files for
+ per-variant OPPs
+
+Rename the Rockchip RK3588 SoC dtsi files and, consequently, adjust their
+contents appropriately, to prepare them for the ability to specify different
+CPU and GPU OPPs for each of the supported RK3588 SoC variants.
+
+As already discussed, [1][2][3][4] some of the RK3588 SoC variants require
+different OPPs, and it makes more sense to have the OPPs already defined when
+a board dts(i) file includes one of the SoC variant dtsi files (rk3588.dtsi,
+rk3588j.dtsi or rk3588s.dtsi), rather than requiring the board dts(i) file
+to also include a separate rk3588*-opp.dtsi file. The choice of the SoC
+variant is already made by the inclusion of the SoC dtsi file into the board
+dts(i) file, and it doesn't make much sense to, effectively, allow the board
+dts(i) file to include and use an incompatible set of OPPs for the already
+selected RK3588 SoC variant.
+
+The new naming scheme for the RK3588 SoC dtsi files uses "-base" and "-extra"
+suffixes to denote the DT data shared between all RK5588 SoC variants, and
+the DT data shared between the unrestricted SoC variants, respectively.
+For example, the DT data for the RK3588 includes both rk3588-base.dtsi and
+rk3588-extra.dtsi, because it's an unrestricted SoC variant, while the DT
+data for the RK3588S variant includes rk3588-base.dtsi only, because it's
+a restricted SoC variant, feature- and interface-wise. This achieves a more
+logical naming of the RK3588 SoC dtsi files, which reflects the way DT data
+for the SoC variants is built by "stacking" the SoC variant features made
+available through the "-base" and "-extra" SoC dtsi files. Additionally,
+the SoC variant dtsi files (rk3588.dtsi, rk3588j.dtsi and rk3588s.dtsi) are
+no longer parents to any other SoC variant dtsi files, which should help with
+making the new "stacking" approach cleaner and easier to follow.
+
+The RK3588 pinctrl dtsi files are also renamed in the same way, for the sake
+of consistency. This also keeps the "-base" and "-extra" groups of the dtsi
+files together when looked at in a directory listing, which is helpful.
+
+The per-SoC-variant OPPs should go directly into the SoC dtsi files, if no
+more than one SoC variant uses those OPPs, or be put into a separate "-opp"
+dtsi file that's shared between and included from two or more SoC variant
+dtsi files. An example for the former is the non-shared OPP data that should
+go directly into the RK3588J SoC variant dtsi file (i.e. rk3588j.dtsi), and
+an example for the latter is the shared OPP data that should be put into
+rk3588-opp.dtsi and be included from the RK3588 and RK3588S SoC variant dtsi
+files (i.e. rk3588.dtsi and rk3588s.dtsi, respectively). Consequently, if
+the OPPs for the RK3588 and RK3588S SoC variants are ever made different,
+the shared rk3588-opp.dtsi file should be deleted and the new OPPs should
+be put directly into rk3588.dtsi and rk3588s.dtsi. [4]
+
+No functional changes are introduced, which was validated by decompiling and
+comparing all affected dtb files before and after these changes.
+
+As a side note, due to the nature of introduced changes, this commit is best
+viewed using the --break-rewrites option for git-log(1).
+
+[1] https://lore.kernel.org/linux-rockchip/646a33e0-5c1b-471c-8183-2c0df40ea51a@cherry.de/
+[2] https://lore.kernel.org/linux-rockchip/CABjd4Yxi=+3gkNnH3BysUzzYsji-=-yROtzEc8jM_g0roKB0-w@mail.gmail.com/
+[3] https://lore.kernel.org/linux-rockchip/035a274be262528012173d463e25b55f@manjaro.org/
+[4] https://lore.kernel.org/linux-rockchip/673dcf47596e7bc8ba065034e339bb1bbf9cdcb0.1716948159.git.dsimic@manjaro.org/T/#u
+
+Signed-off-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/9ffedc0e2ca7f167d9d795b2a8f43cb9f56a653b.1717923308.git.dsimic@manjaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ ...-pinctrl.dtsi => rk3588-base-pinctrl.dtsi} | 0
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 2670 +++++++++++++++++
+ ...pinctrl.dtsi => rk3588-extra-pinctrl.dtsi} | 0
+ .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 413 +++
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 412 +--
+ arch/arm64/boot/dts/rockchip/rk3588j.dtsi | 2 +-
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 2669 +---------------
+ 7 files changed, 3090 insertions(+), 3076 deletions(-)
+ rename arch/arm64/boot/dts/rockchip/{rk3588s-pinctrl.dtsi => rk3588-base-pinctrl.dtsi} (100%)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+ rename arch/arm64/boot/dts/rockchip/{rk3588-pinctrl.dtsi => rk3588-extra-pinctrl.dtsi} (100%)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -0,0 +1,2670 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include <dt-bindings/clock/rockchip,rk3588-cru.h>
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/power/rk3588-power.h>
++#include <dt-bindings/reset/rockchip,rk3588-cru.h>
++#include <dt-bindings/phy/phy.h>
++#include <dt-bindings/ata/ahci.h>
++
++/ {
++ compatible = "rockchip,rk3588";
++
++ interrupt-parent = <&gic>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ aliases {
++ gpio0 = &gpio0;
++ gpio1 = &gpio1;
++ gpio2 = &gpio2;
++ gpio3 = &gpio3;
++ gpio4 = &gpio4;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c7 = &i2c7;
++ i2c8 = &i2c8;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial5 = &uart5;
++ serial6 = &uart6;
++ serial7 = &uart7;
++ serial8 = &uart8;
++ serial9 = &uart9;
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ };
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ cpu-map {
++ cluster0 {
++ core0 {
++ cpu = <&cpu_l0>;
++ };
++ core1 {
++ cpu = <&cpu_l1>;
++ };
++ core2 {
++ cpu = <&cpu_l2>;
++ };
++ core3 {
++ cpu = <&cpu_l3>;
++ };
++ };
++ cluster1 {
++ core0 {
++ cpu = <&cpu_b0>;
++ };
++ core1 {
++ cpu = <&cpu_b1>;
++ };
++ };
++ cluster2 {
++ core0 {
++ cpu = <&cpu_b2>;
++ };
++ core1 {
++ cpu = <&cpu_b3>;
++ };
++ };
++ };
++
++ cpu_l0: cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x0>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ assigned-clock-rates = <816000000>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l0>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_l1: cpu@100 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x100>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l1>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_l2: cpu@200 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x200>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l2>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_l3: cpu@300 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x300>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l3>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b0: cpu@400 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x400>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB01>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
++ assigned-clock-rates = <816000000>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b0>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b1: cpu@500 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x500>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB01>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b1>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b2: cpu@600 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x600>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB23>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
++ assigned-clock-rates = <816000000>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b2>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b3: cpu@700 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x700>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB23>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b3>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ idle-states {
++ entry-method = "psci";
++ CPU_SLEEP: cpu-sleep {
++ compatible = "arm,idle-state";
++ local-timer-stop;
++ arm,psci-suspend-param = <0x0010000>;
++ entry-latency-us = <100>;
++ exit-latency-us = <120>;
++ min-residency-us = <1000>;
++ };
++ };
++
++ l2_cache_l0: l2-cache-l0 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l1: l2-cache-l1 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l2: l2-cache-l2 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l3: l2-cache-l3 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b0: l2-cache-b0 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b1: l2-cache-b1 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b2: l2-cache-b2 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b3: l2-cache-b3 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l3_cache: l3-cache {
++ compatible = "cache";
++ cache-size = <3145728>;
++ cache-line-size = <64>;
++ cache-sets = <4096>;
++ cache-level = <3>;
++ cache-unified;
++ };
++ };
++
++ display_subsystem: display-subsystem {
++ compatible = "rockchip,display-subsystem";
++ ports = <&vop_out>;
++ };
++
++ firmware {
++ optee: optee {
++ compatible = "linaro,optee-tz";
++ method = "smc";
++ };
++
++ scmi: scmi {
++ compatible = "arm,scmi-smc";
++ arm,smc-id = <0x82000010>;
++ shmem = <&scmi_shmem>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ scmi_clk: protocol@14 {
++ reg = <0x14>;
++ #clock-cells = <1>;
++ };
++
++ scmi_reset: protocol@16 {
++ reg = <0x16>;
++ #reset-cells = <1>;
++ };
++ };
++ };
++
++ pmu-a55 {
++ compatible = "arm,cortex-a55-pmu";
++ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition0>;
++ };
++
++ pmu-a76 {
++ compatible = "arm,cortex-a76-pmu";
++ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition1>;
++ };
++
++ psci {
++ compatible = "arm,psci-1.0";
++ method = "smc";
++ };
++
++ spll: clock-0 {
++ compatible = "fixed-clock";
++ clock-frequency = <702000000>;
++ clock-output-names = "spll";
++ #clock-cells = <0>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
++ };
++
++ xin24m: clock-1 {
++ compatible = "fixed-clock";
++ clock-frequency = <24000000>;
++ clock-output-names = "xin24m";
++ #clock-cells = <0>;
++ };
++
++ xin32k: clock-2 {
++ compatible = "fixed-clock";
++ clock-frequency = <32768>;
++ clock-output-names = "xin32k";
++ #clock-cells = <0>;
++ };
++
++ pmu_sram: sram@10f000 {
++ compatible = "mmio-sram";
++ reg = <0x0 0x0010f000 0x0 0x100>;
++ ranges = <0 0x0 0x0010f000 0x100>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ scmi_shmem: sram@0 {
++ compatible = "arm,scmi-shmem";
++ reg = <0x0 0x100>;
++ };
++ };
++
++ gpu: gpu@fb000000 {
++ compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
++ reg = <0x0 0xfb000000 0x0 0x200000>;
++ #cooling-cells = <2>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
++ assigned-clock-rates = <200000000>;
++ clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ clock-names = "core", "coregroup", "stacks";
++ dynamic-power-coefficient = <2982>;
++ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "job", "mmu", "gpu";
++ operating-points-v2 = <&gpu_opp_table>;
++ power-domains = <&power RK3588_PD_GPU>;
++ status = "disabled";
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
++ };
++
++ usb_host0_xhci: usb@fc000000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc000000 0x0 0x400000>;
++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
++ <&cru ACLK_USB3OTG0>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG0>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u1-entry-quirk;
++ snps,dis-u2-entry-quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
++ usb_host0_ehci: usb@fc800000 {
++ compatible = "rockchip,rk3588-ehci", "generic-ehci";
++ reg = <0x0 0xfc800000 0x0 0x40000>;
++ interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
++ phys = <&u2phy2_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host0_ohci: usb@fc840000 {
++ compatible = "rockchip,rk3588-ohci", "generic-ohci";
++ reg = <0x0 0xfc840000 0x0 0x40000>;
++ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
++ phys = <&u2phy2_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host1_ehci: usb@fc880000 {
++ compatible = "rockchip,rk3588-ehci", "generic-ehci";
++ reg = <0x0 0xfc880000 0x0 0x40000>;
++ interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
++ phys = <&u2phy3_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host1_ohci: usb@fc8c0000 {
++ compatible = "rockchip,rk3588-ohci", "generic-ohci";
++ reg = <0x0 0xfc8c0000 0x0 0x40000>;
++ interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
++ phys = <&u2phy3_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host2_xhci: usb@fcd00000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfcd00000 0x0 0x400000>;
++ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
++ <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
++ <&cru CLK_PIPEPHY2_PIPE_U3_G>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
++ dr_mode = "host";
++ phys = <&combphy2_psu PHY_TYPE_USB3>;
++ phy-names = "usb3-phy";
++ phy_type = "utmi_wide";
++ resets = <&cru SRST_A_USB3OTG2>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ snps,dis_rxdet_inp3_quirk;
++ status = "disabled";
++ };
++
++ mmu600_pcie: iommu@fc900000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfc900000 0x0 0x200000>;
++ interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ mmu600_php: iommu@fcb00000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfcb00000 0x0 0x200000>;
++ interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ pmu1grf: syscon@fd58a000 {
++ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd58a000 0x0 0x10000>;
++ };
++
++ sys_grf: syscon@fd58c000 {
++ compatible = "rockchip,rk3588-sys-grf", "syscon";
++ reg = <0x0 0xfd58c000 0x0 0x1000>;
++ };
++
++ vop_grf: syscon@fd5a4000 {
++ compatible = "rockchip,rk3588-vop-grf", "syscon";
++ reg = <0x0 0xfd5a4000 0x0 0x2000>;
++ };
++
++ vo0_grf: syscon@fd5a6000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a6000 0x0 0x2000>;
++ clocks = <&cru PCLK_VO0GRF>;
++ };
++
++ vo1_grf: syscon@fd5a8000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a8000 0x0 0x100>;
++ clocks = <&cru PCLK_VO1GRF>;
++ };
++
++ usb_grf: syscon@fd5ac000 {
++ compatible = "rockchip,rk3588-usb-grf", "syscon";
++ reg = <0x0 0xfd5ac000 0x0 0x4000>;
++ };
++
++ php_grf: syscon@fd5b0000 {
++ compatible = "rockchip,rk3588-php-grf", "syscon";
++ reg = <0x0 0xfd5b0000 0x0 0x1000>;
++ };
++
++ pipe_phy0_grf: syscon@fd5bc000 {
++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
++ reg = <0x0 0xfd5bc000 0x0 0x100>;
++ };
++
++ pipe_phy2_grf: syscon@fd5c4000 {
++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
++ reg = <0x0 0xfd5c4000 0x0 0x100>;
++ };
++
++ usbdpphy0_grf: syscon@fd5c8000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5c8000 0x0 0x4000>;
++ };
++
++ usb2phy0_grf: syscon@fd5d0000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d0000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy0: usb2phy@0 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x0 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy0";
++ interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy0_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ usb2phy2_grf: syscon@fd5d8000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d8000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy2: usb2phy@8000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x8000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy2";
++ interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy2_host: host-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ usb2phy3_grf: syscon@fd5dc000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5dc000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy3: usb2phy@c000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0xc000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy3";
++ interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy3_host: host-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ hdptxphy0_grf: syscon@fd5e0000 {
++ compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
++ reg = <0x0 0xfd5e0000 0x0 0x100>;
++ };
++
++ ioc: syscon@fd5f0000 {
++ compatible = "rockchip,rk3588-ioc", "syscon";
++ reg = <0x0 0xfd5f0000 0x0 0x10000>;
++ };
++
++ system_sram1: sram@fd600000 {
++ compatible = "mmio-sram";
++ reg = <0x0 0xfd600000 0x0 0x100000>;
++ ranges = <0x0 0x0 0xfd600000 0x100000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ };
++
++ cru: clock-controller@fd7c0000 {
++ compatible = "rockchip,rk3588-cru";
++ reg = <0x0 0xfd7c0000 0x0 0x5c000>;
++ assigned-clocks =
++ <&cru PLL_PPLL>, <&cru PLL_AUPLL>,
++ <&cru PLL_NPLL>, <&cru PLL_GPLL>,
++ <&cru ACLK_CENTER_ROOT>,
++ <&cru HCLK_CENTER_ROOT>, <&cru ACLK_CENTER_LOW_ROOT>,
++ <&cru ACLK_TOP_ROOT>, <&cru PCLK_TOP_ROOT>,
++ <&cru ACLK_LOW_TOP_ROOT>, <&cru PCLK_PMU0_ROOT>,
++ <&cru HCLK_PMU_CM0_ROOT>, <&cru ACLK_VOP>,
++ <&cru ACLK_BUS_ROOT>, <&cru CLK_150M_SRC>,
++ <&cru CLK_GPU>;
++ assigned-clock-rates =
++ <1100000000>, <786432000>,
++ <850000000>, <1188000000>,
++ <702000000>,
++ <400000000>, <500000000>,
++ <800000000>, <100000000>,
++ <400000000>, <100000000>,
++ <200000000>, <500000000>,
++ <375000000>, <150000000>,
++ <200000000>;
++ rockchip,grf = <&php_grf>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ i2c0: i2c@fd880000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfd880000 0x0 0x1000>;
++ interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>;
++ clock-names = "i2c", "pclk";
++ pinctrl-0 = <&i2c0m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ uart0: serial@fd890000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfd890000 0x0 0x100>;
++ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 6>, <&dmac0 7>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart0m1_xfer>;
++ pinctrl-names = "default";
++ reg-shift = <2>;
++ reg-io-width = <4>;
++ status = "disabled";
++ };
++
++ pwm0: pwm@fd8b0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0000 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm0m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@fd8b0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0010 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm1m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm2: pwm@fd8b0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0020 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm2m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm3: pwm@fd8b0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0030 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm3m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pmu: power-management@fd8d8000 {
++ compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd";
++ reg = <0x0 0xfd8d8000 0x0 0x400>;
++
++ power: power-controller {
++ compatible = "rockchip,rk3588-power-controller";
++ #address-cells = <1>;
++ #power-domain-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ /* These power domains are grouped by VD_NPU */
++ power-domain@RK3588_PD_NPU {
++ reg = <RK3588_PD_NPU>;
++ #power-domain-cells = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ power-domain@RK3588_PD_NPUTOP {
++ reg = <RK3588_PD_NPUTOP>;
++ clocks = <&cru HCLK_NPU_ROOT>,
++ <&cru PCLK_NPU_ROOT>,
++ <&cru CLK_NPU_DSU0>,
++ <&cru HCLK_NPU_CM0_ROOT>;
++ pm_qos = <&qos_npu0_mwr>,
++ <&qos_npu0_mro>,
++ <&qos_mcu_npu>;
++ #power-domain-cells = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ power-domain@RK3588_PD_NPU1 {
++ reg = <RK3588_PD_NPU1>;
++ clocks = <&cru HCLK_NPU_ROOT>,
++ <&cru PCLK_NPU_ROOT>,
++ <&cru CLK_NPU_DSU0>;
++ pm_qos = <&qos_npu1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_NPU2 {
++ reg = <RK3588_PD_NPU2>;
++ clocks = <&cru HCLK_NPU_ROOT>,
++ <&cru PCLK_NPU_ROOT>,
++ <&cru CLK_NPU_DSU0>;
++ pm_qos = <&qos_npu2>;
++ #power-domain-cells = <0>;
++ };
++ };
++ };
++ /* These power domains are grouped by VD_GPU */
++ power-domain@RK3588_PD_GPU {
++ reg = <RK3588_PD_GPU>;
++ clocks = <&cru CLK_GPU>,
++ <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ pm_qos = <&qos_gpu_m0>,
++ <&qos_gpu_m1>,
++ <&qos_gpu_m2>,
++ <&qos_gpu_m3>;
++ #power-domain-cells = <0>;
++ };
++ /* These power domains are grouped by VD_VCODEC */
++ power-domain@RK3588_PD_VCODEC {
++ reg = <RK3588_PD_VCODEC>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_RKVDEC0 {
++ reg = <RK3588_PD_RKVDEC0>;
++ clocks = <&cru HCLK_RKVDEC0>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_RKVDEC0>,
++ <&cru ACLK_RKVDEC_CCU>;
++ pm_qos = <&qos_rkvdec0>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RKVDEC1 {
++ reg = <RK3588_PD_RKVDEC1>;
++ clocks = <&cru HCLK_RKVDEC1>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_RKVDEC1>;
++ pm_qos = <&qos_rkvdec1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_VENC0 {
++ reg = <RK3588_PD_VENC0>;
++ clocks = <&cru HCLK_RKVENC0>,
++ <&cru ACLK_RKVENC0>;
++ pm_qos = <&qos_rkvenc0_m0ro>,
++ <&qos_rkvenc0_m1ro>,
++ <&qos_rkvenc0_m2wo>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_VENC1 {
++ reg = <RK3588_PD_VENC1>;
++ clocks = <&cru HCLK_RKVENC1>,
++ <&cru HCLK_RKVENC0>,
++ <&cru ACLK_RKVENC0>,
++ <&cru ACLK_RKVENC1>;
++ pm_qos = <&qos_rkvenc1_m0ro>,
++ <&qos_rkvenc1_m1ro>,
++ <&qos_rkvenc1_m2wo>;
++ #power-domain-cells = <0>;
++ };
++ };
++ };
++ /* These power domains are grouped by VD_LOGIC */
++ power-domain@RK3588_PD_VDPU {
++ reg = <RK3588_PD_VDPU>;
++ clocks = <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_LOW_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_JPEG_DECODER_ROOT>,
++ <&cru ACLK_IEP2P0>,
++ <&cru HCLK_IEP2P0>,
++ <&cru ACLK_JPEG_ENCODER0>,
++ <&cru HCLK_JPEG_ENCODER0>,
++ <&cru ACLK_JPEG_ENCODER1>,
++ <&cru HCLK_JPEG_ENCODER1>,
++ <&cru ACLK_JPEG_ENCODER2>,
++ <&cru HCLK_JPEG_ENCODER2>,
++ <&cru ACLK_JPEG_ENCODER3>,
++ <&cru HCLK_JPEG_ENCODER3>,
++ <&cru ACLK_JPEG_DECODER>,
++ <&cru HCLK_JPEG_DECODER>,
++ <&cru ACLK_RGA2>,
++ <&cru HCLK_RGA2>;
++ pm_qos = <&qos_iep>,
++ <&qos_jpeg_dec>,
++ <&qos_jpeg_enc0>,
++ <&qos_jpeg_enc1>,
++ <&qos_jpeg_enc2>,
++ <&qos_jpeg_enc3>,
++ <&qos_rga2_mro>,
++ <&qos_rga2_mwo>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++
++ power-domain@RK3588_PD_AV1 {
++ reg = <RK3588_PD_AV1>;
++ clocks = <&cru PCLK_AV1>,
++ <&cru ACLK_AV1>,
++ <&cru HCLK_VDPU_ROOT>;
++ pm_qos = <&qos_av1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RKVDEC0 {
++ reg = <RK3588_PD_RKVDEC0>;
++ clocks = <&cru HCLK_RKVDEC0>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_RKVDEC0>;
++ pm_qos = <&qos_rkvdec0>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RKVDEC1 {
++ reg = <RK3588_PD_RKVDEC1>;
++ clocks = <&cru HCLK_RKVDEC1>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>;
++ pm_qos = <&qos_rkvdec1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RGA30 {
++ reg = <RK3588_PD_RGA30>;
++ clocks = <&cru ACLK_RGA3_0>,
++ <&cru HCLK_RGA3_0>;
++ pm_qos = <&qos_rga3_0>;
++ #power-domain-cells = <0>;
++ };
++ };
++ power-domain@RK3588_PD_VOP {
++ reg = <RK3588_PD_VOP>;
++ clocks = <&cru PCLK_VOP_ROOT>,
++ <&cru HCLK_VOP_ROOT>,
++ <&cru ACLK_VOP>;
++ pm_qos = <&qos_vop_m0>,
++ <&qos_vop_m1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_VO0 {
++ reg = <RK3588_PD_VO0>;
++ clocks = <&cru PCLK_VO0_ROOT>,
++ <&cru PCLK_VO0_S_ROOT>,
++ <&cru HCLK_VO0_S_ROOT>,
++ <&cru ACLK_VO0_ROOT>,
++ <&cru HCLK_HDCP0>,
++ <&cru ACLK_HDCP0>,
++ <&cru HCLK_VOP_ROOT>;
++ pm_qos = <&qos_hdcp0>;
++ #power-domain-cells = <0>;
++ };
++ };
++ power-domain@RK3588_PD_VO1 {
++ reg = <RK3588_PD_VO1>;
++ clocks = <&cru PCLK_VO1_ROOT>,
++ <&cru PCLK_VO1_S_ROOT>,
++ <&cru HCLK_VO1_S_ROOT>,
++ <&cru HCLK_HDCP1>,
++ <&cru ACLK_HDCP1>,
++ <&cru ACLK_HDMIRX_ROOT>,
++ <&cru HCLK_VO1USB_TOP_ROOT>;
++ pm_qos = <&qos_hdcp1>,
++ <&qos_hdmirx>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_VI {
++ reg = <RK3588_PD_VI>;
++ clocks = <&cru HCLK_VI_ROOT>,
++ <&cru PCLK_VI_ROOT>,
++ <&cru HCLK_ISP0>,
++ <&cru ACLK_ISP0>,
++ <&cru HCLK_VICAP>,
++ <&cru ACLK_VICAP>;
++ pm_qos = <&qos_isp0_mro>,
++ <&qos_isp0_mwo>,
++ <&qos_vicap_m0>,
++ <&qos_vicap_m1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_ISP1 {
++ reg = <RK3588_PD_ISP1>;
++ clocks = <&cru HCLK_ISP1>,
++ <&cru ACLK_ISP1>,
++ <&cru HCLK_VI_ROOT>,
++ <&cru PCLK_VI_ROOT>;
++ pm_qos = <&qos_isp1_mwo>,
++ <&qos_isp1_mro>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_FEC {
++ reg = <RK3588_PD_FEC>;
++ clocks = <&cru HCLK_FISHEYE0>,
++ <&cru ACLK_FISHEYE0>,
++ <&cru HCLK_FISHEYE1>,
++ <&cru ACLK_FISHEYE1>,
++ <&cru PCLK_VI_ROOT>;
++ pm_qos = <&qos_fisheye0>,
++ <&qos_fisheye1>;
++ #power-domain-cells = <0>;
++ };
++ };
++ power-domain@RK3588_PD_RGA31 {
++ reg = <RK3588_PD_RGA31>;
++ clocks = <&cru HCLK_RGA3_1>,
++ <&cru ACLK_RGA3_1>;
++ pm_qos = <&qos_rga3_1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_USB {
++ reg = <RK3588_PD_USB>;
++ clocks = <&cru PCLK_PHP_ROOT>,
++ <&cru ACLK_USB_ROOT>,
++ <&cru ACLK_USB>,
++ <&cru HCLK_USB_ROOT>,
++ <&cru HCLK_HOST0>,
++ <&cru HCLK_HOST_ARB0>,
++ <&cru HCLK_HOST1>,
++ <&cru HCLK_HOST_ARB1>;
++ pm_qos = <&qos_usb3_0>,
++ <&qos_usb3_1>,
++ <&qos_usb2host_0>,
++ <&qos_usb2host_1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_GMAC {
++ reg = <RK3588_PD_GMAC>;
++ clocks = <&cru PCLK_PHP_ROOT>,
++ <&cru ACLK_PCIE_ROOT>,
++ <&cru ACLK_PHP_ROOT>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_PCIE {
++ reg = <RK3588_PD_PCIE>;
++ clocks = <&cru PCLK_PHP_ROOT>,
++ <&cru ACLK_PCIE_ROOT>,
++ <&cru ACLK_PHP_ROOT>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_SDIO {
++ reg = <RK3588_PD_SDIO>;
++ clocks = <&cru HCLK_SDIO>,
++ <&cru HCLK_NVM_ROOT>;
++ pm_qos = <&qos_sdio>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_AUDIO {
++ reg = <RK3588_PD_AUDIO>;
++ clocks = <&cru HCLK_AUDIO_ROOT>,
++ <&cru PCLK_AUDIO_ROOT>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_SDMMC {
++ reg = <RK3588_PD_SDMMC>;
++ pm_qos = <&qos_sdmmc>;
++ #power-domain-cells = <0>;
++ };
++ };
++ };
++
++ av1d: video-codec@fdc70000 {
++ compatible = "rockchip,rk3588-av1-vpu";
++ reg = <0x0 0xfdc70000 0x0 0x800>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "vdpu";
++ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ assigned-clock-rates = <400000000>, <400000000>;
++ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ clock-names = "aclk", "hclk";
++ power-domains = <&power RK3588_PD_AV1>;
++ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
++ };
++
++ vop: vop@fdd90000 {
++ compatible = "rockchip,rk3588-vop";
++ reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
++ reg-names = "vop", "gamma-lut";
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>,
++ <&cru HCLK_VOP>,
++ <&cru DCLK_VOP0>,
++ <&cru DCLK_VOP1>,
++ <&cru DCLK_VOP2>,
++ <&cru DCLK_VOP3>,
++ <&cru PCLK_VOP_ROOT>;
++ clock-names = "aclk",
++ "hclk",
++ "dclk_vp0",
++ "dclk_vp1",
++ "dclk_vp2",
++ "dclk_vp3",
++ "pclk_vop";
++ iommus = <&vop_mmu>;
++ power-domains = <&power RK3588_PD_VOP>;
++ rockchip,grf = <&sys_grf>;
++ rockchip,vop-grf = <&vop_grf>;
++ rockchip,vo1-grf = <&vo1_grf>;
++ rockchip,pmu = <&pmu>;
++ status = "disabled";
++
++ vop_out: ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ vp0: port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ };
++
++ vp1: port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ };
++
++ vp2: port@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ };
++
++ vp3: port@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ };
++ };
++ };
++
++ vop_mmu: iommu@fdd97e00 {
++ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
++ reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
++ clock-names = "aclk", "iface";
++ #iommu-cells = <0>;
++ power-domains = <&power RK3588_PD_VOP>;
++ status = "disabled";
++ };
++
++ i2s4_8ch: i2s@fddc0000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddc0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S4_8CH_TX>, <&cru MCLK_I2S4_8CH_TX>, <&cru HCLK_I2S4_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S4_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 0>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO0>;
++ resets = <&cru SRST_M_I2S4_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s5_8ch: i2s@fddf0000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddf0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S5_8CH_TX>, <&cru MCLK_I2S5_8CH_TX>, <&cru HCLK_I2S5_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S5_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 2>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S5_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s9_8ch: i2s@fddfc000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddfc000 0x0 0x1000>;
++ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S9_8CH_RX>, <&cru MCLK_I2S9_8CH_RX>, <&cru HCLK_I2S9_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S9_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 23>;
++ dma-names = "rx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S9_8CH_RX>;
++ reset-names = "rx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ qos_gpu_m0: qos@fdf35000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35000 0x0 0x20>;
++ };
++
++ qos_gpu_m1: qos@fdf35200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35200 0x0 0x20>;
++ };
++
++ qos_gpu_m2: qos@fdf35400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35400 0x0 0x20>;
++ };
++
++ qos_gpu_m3: qos@fdf35600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35600 0x0 0x20>;
++ };
++
++ qos_rga3_1: qos@fdf36000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf36000 0x0 0x20>;
++ };
++
++ qos_sdio: qos@fdf39000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf39000 0x0 0x20>;
++ };
++
++ qos_sdmmc: qos@fdf3d800 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3d800 0x0 0x20>;
++ };
++
++ qos_usb3_1: qos@fdf3e000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e000 0x0 0x20>;
++ };
++
++ qos_usb3_0: qos@fdf3e200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e200 0x0 0x20>;
++ };
++
++ qos_usb2host_0: qos@fdf3e400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e400 0x0 0x20>;
++ };
++
++ qos_usb2host_1: qos@fdf3e600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e600 0x0 0x20>;
++ };
++
++ qos_fisheye0: qos@fdf40000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40000 0x0 0x20>;
++ };
++
++ qos_fisheye1: qos@fdf40200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40200 0x0 0x20>;
++ };
++
++ qos_isp0_mro: qos@fdf40400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40400 0x0 0x20>;
++ };
++
++ qos_isp0_mwo: qos@fdf40500 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40500 0x0 0x20>;
++ };
++
++ qos_vicap_m0: qos@fdf40600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40600 0x0 0x20>;
++ };
++
++ qos_vicap_m1: qos@fdf40800 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40800 0x0 0x20>;
++ };
++
++ qos_isp1_mwo: qos@fdf41000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf41000 0x0 0x20>;
++ };
++
++ qos_isp1_mro: qos@fdf41100 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf41100 0x0 0x20>;
++ };
++
++ qos_rkvenc0_m0ro: qos@fdf60000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf60000 0x0 0x20>;
++ };
++
++ qos_rkvenc0_m1ro: qos@fdf60200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf60200 0x0 0x20>;
++ };
++
++ qos_rkvenc0_m2wo: qos@fdf60400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf60400 0x0 0x20>;
++ };
++
++ qos_rkvenc1_m0ro: qos@fdf61000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf61000 0x0 0x20>;
++ };
++
++ qos_rkvenc1_m1ro: qos@fdf61200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf61200 0x0 0x20>;
++ };
++
++ qos_rkvenc1_m2wo: qos@fdf61400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf61400 0x0 0x20>;
++ };
++
++ qos_rkvdec0: qos@fdf62000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf62000 0x0 0x20>;
++ };
++
++ qos_rkvdec1: qos@fdf63000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf63000 0x0 0x20>;
++ };
++
++ qos_av1: qos@fdf64000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf64000 0x0 0x20>;
++ };
++
++ qos_iep: qos@fdf66000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66000 0x0 0x20>;
++ };
++
++ qos_jpeg_dec: qos@fdf66200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66200 0x0 0x20>;
++ };
++
++ qos_jpeg_enc0: qos@fdf66400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66400 0x0 0x20>;
++ };
++
++ qos_jpeg_enc1: qos@fdf66600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66600 0x0 0x20>;
++ };
++
++ qos_jpeg_enc2: qos@fdf66800 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66800 0x0 0x20>;
++ };
++
++ qos_jpeg_enc3: qos@fdf66a00 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66a00 0x0 0x20>;
++ };
++
++ qos_rga2_mro: qos@fdf66c00 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66c00 0x0 0x20>;
++ };
++
++ qos_rga2_mwo: qos@fdf66e00 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66e00 0x0 0x20>;
++ };
++
++ qos_rga3_0: qos@fdf67000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf67000 0x0 0x20>;
++ };
++
++ qos_vdpu: qos@fdf67200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf67200 0x0 0x20>;
++ };
++
++ qos_npu1: qos@fdf70000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf70000 0x0 0x20>;
++ };
++
++ qos_npu2: qos@fdf71000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf71000 0x0 0x20>;
++ };
++
++ qos_npu0_mwr: qos@fdf72000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf72000 0x0 0x20>;
++ };
++
++ qos_npu0_mro: qos@fdf72200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf72200 0x0 0x20>;
++ };
++
++ qos_mcu_npu: qos@fdf72400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf72400 0x0 0x20>;
++ };
++
++ qos_hdcp0: qos@fdf80000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf80000 0x0 0x20>;
++ };
++
++ qos_hdcp1: qos@fdf81000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf81000 0x0 0x20>;
++ };
++
++ qos_hdmirx: qos@fdf81200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf81200 0x0 0x20>;
++ };
++
++ qos_vop_m0: qos@fdf82000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf82000 0x0 0x20>;
++ };
++
++ qos_vop_m1: qos@fdf82200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf82200 0x0 0x20>;
++ };
++
++ dfi: dfi@fe060000 {
++ reg = <0x00 0xfe060000 0x00 0x10000>;
++ compatible = "rockchip,rk3588-dfi";
++ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
++ rockchip,pmu = <&pmu1grf>;
++ };
++
++ pcie2x1l1: pcie@fe180000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ bus-range = <0x30 0x3f>;
++ clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>,
++ <&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>,
++ <&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie2x1l1_intc 0>,
++ <0 0 0 2 &pcie2x1l1_intc 1>,
++ <0 0 0 3 &pcie2x1l1_intc 2>,
++ <0 0 0 4 &pcie2x1l1_intc 3>;
++ linux,pci-domain = <3>;
++ max-link-speed = <2>;
++ msi-map = <0x3000 &its0 0x3000 0x1000>;
++ num-lanes = <1>;
++ phys = <&combphy2_psu PHY_TYPE_PCIE>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0xc0000000 0x0 0x40000000>;
++ reg = <0xa 0x40c00000 0x0 0x00400000>,
++ <0x0 0xfe180000 0x0 0x00010000>,
++ <0x0 0xf3000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>;
++ reset-names = "pwr", "pipe";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ status = "disabled";
++
++ pcie2x1l1_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 245 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ pcie2x1l2: pcie@fe190000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ bus-range = <0x40 0x4f>;
++ clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>,
++ <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>,
++ <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>,
++ <0 0 0 2 &pcie2x1l2_intc 1>,
++ <0 0 0 3 &pcie2x1l2_intc 2>,
++ <0 0 0 4 &pcie2x1l2_intc 3>;
++ linux,pci-domain = <4>;
++ max-link-speed = <2>;
++ msi-map = <0x4000 &its0 0x4000 0x1000>;
++ num-lanes = <1>;
++ phys = <&combphy0_ps PHY_TYPE_PCIE>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0xa 0x00000000 0x0 0x40000000>;
++ reg = <0xa 0x41000000 0x0 0x00400000>,
++ <0x0 0xfe190000 0x0 0x00010000>,
++ <0x0 0xf4000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>;
++ reset-names = "pwr", "pipe";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ status = "disabled";
++
++ pcie2x1l2_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ gmac1: ethernet@fe1c0000 {
++ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
++ reg = <0x0 0xfe1c0000 0x0 0x10000>;
++ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "macirq", "eth_wake_irq";
++ clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
++ <&cru PCLK_GMAC1>, <&cru ACLK_GMAC1>,
++ <&cru CLK_GMAC1_PTP_REF>;
++ clock-names = "stmmaceth", "clk_mac_ref",
++ "pclk_mac", "aclk_mac",
++ "ptp_ref";
++ power-domains = <&power RK3588_PD_GMAC>;
++ resets = <&cru SRST_A_GMAC1>;
++ reset-names = "stmmaceth";
++ rockchip,grf = <&sys_grf>;
++ rockchip,php-grf = <&php_grf>;
++ snps,axi-config = <&gmac1_stmmac_axi_setup>;
++ snps,mixed-burst;
++ snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
++ snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
++ snps,tso;
++ status = "disabled";
++
++ mdio1: mdio {
++ compatible = "snps,dwmac-mdio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ };
++
++ gmac1_stmmac_axi_setup: stmmac-axi-config {
++ snps,blen = <0 0 0 0 16 8 4>;
++ snps,wr_osr_lmt = <4>;
++ snps,rd_osr_lmt = <8>;
++ };
++
++ gmac1_mtl_rx_setup: rx-queues-config {
++ snps,rx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++
++ gmac1_mtl_tx_setup: tx-queues-config {
++ snps,tx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++ };
++
++ sata0: sata@fe210000 {
++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
++ reg = <0 0xfe210000 0 0x1000>;
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
++ <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>,
++ <&cru CLK_PIPEPHY0_PIPE_ASIC_G>;
++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
++ ports-implemented = <0x1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ sata-port@0 {
++ reg = <0>;
++ hba-port-cap = <HBA_PORT_FBSCP>;
++ phys = <&combphy0_ps PHY_TYPE_SATA>;
++ phy-names = "sata-phy";
++ snps,rx-ts-max = <32>;
++ snps,tx-ts-max = <32>;
++ };
++ };
++
++ sata2: sata@fe230000 {
++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
++ reg = <0 0xfe230000 0 0x1000>;
++ interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_SATA2>, <&cru CLK_PMALIVE2>,
++ <&cru CLK_RXOOB2>, <&cru CLK_PIPEPHY2_REF>,
++ <&cru CLK_PIPEPHY2_PIPE_ASIC_G>;
++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
++ ports-implemented = <0x1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ sata-port@0 {
++ reg = <0>;
++ hba-port-cap = <HBA_PORT_FBSCP>;
++ phys = <&combphy2_psu PHY_TYPE_SATA>;
++ phy-names = "sata-phy";
++ snps,rx-ts-max = <32>;
++ snps,tx-ts-max = <32>;
++ };
++ };
++
++ sfc: spi@fe2b0000 {
++ compatible = "rockchip,sfc";
++ reg = <0x0 0xfe2b0000 0x0 0x4000>;
++ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
++ clock-names = "clk_sfc", "hclk_sfc";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ sdmmc: mmc@fe2c0000 {
++ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
++ reg = <0x0 0xfe2c0000 0x0 0x4000>;
++ interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>,
++ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
++ fifo-depth = <0x100>;
++ max-frequency = <200000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
++ power-domains = <&power RK3588_PD_SDMMC>;
++ status = "disabled";
++ };
++
++ sdio: mmc@fe2d0000 {
++ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
++ reg = <0x00 0xfe2d0000 0x00 0x4000>;
++ interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_SDIO>, <&cru CCLK_SRC_SDIO>,
++ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
++ fifo-depth = <0x100>;
++ max-frequency = <200000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdiom1_pins>;
++ power-domains = <&power RK3588_PD_SDIO>;
++ status = "disabled";
++ };
++
++ sdhci: mmc@fe2e0000 {
++ compatible = "rockchip,rk3588-dwcmshc";
++ reg = <0x0 0xfe2e0000 0x0 0x10000>;
++ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH 0>;
++ assigned-clocks = <&cru BCLK_EMMC>, <&cru TMCLK_EMMC>, <&cru CCLK_EMMC>;
++ assigned-clock-rates = <200000000>, <24000000>, <200000000>;
++ clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
++ <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
++ <&cru TMCLK_EMMC>;
++ clock-names = "core", "bus", "axi", "block", "timer";
++ max-frequency = <200000000>;
++ pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>,
++ <&emmc_cmd>, <&emmc_data_strobe>;
++ pinctrl-names = "default";
++ resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>,
++ <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>,
++ <&cru SRST_T_EMMC>;
++ reset-names = "core", "bus", "axi", "block", "timer";
++ status = "disabled";
++ };
++
++ i2s0_8ch: i2s@fe470000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfe470000 0x0 0x1000>;
++ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>, <&cru PLL_AUPLL>;
++ dmas = <&dmac0 0>, <&dmac0 1>;
++ dma-names = "tx", "rx";
++ power-domains = <&power RK3588_PD_AUDIO>;
++ resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>;
++ reset-names = "tx-m", "rx-m";
++ rockchip,trcm-sync-tx-only;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s0_lrck
++ &i2s0_sclk
++ &i2s0_sdi0
++ &i2s0_sdi1
++ &i2s0_sdi2
++ &i2s0_sdi3
++ &i2s0_sdo0
++ &i2s0_sdo1
++ &i2s0_sdo2
++ &i2s0_sdo3>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s1_8ch: i2s@fe480000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfe480000 0x0 0x1000>;
++ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>, <&cru HCLK_I2S1_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ dmas = <&dmac0 2>, <&dmac0 3>;
++ dma-names = "tx", "rx";
++ resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
++ reset-names = "tx-m", "rx-m";
++ rockchip,trcm-sync-tx-only;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s1m0_lrck
++ &i2s1m0_sclk
++ &i2s1m0_sdi0
++ &i2s1m0_sdi1
++ &i2s1m0_sdi2
++ &i2s1m0_sdi3
++ &i2s1m0_sdo0
++ &i2s1m0_sdo1
++ &i2s1m0_sdo2
++ &i2s1m0_sdo3>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s2_2ch: i2s@fe490000 {
++ compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
++ reg = <0x0 0xfe490000 0x0 0x1000>;
++ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
++ clock-names = "i2s_clk", "i2s_hclk";
++ assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac1 0>, <&dmac1 1>;
++ dma-names = "tx", "rx";
++ power-domains = <&power RK3588_PD_AUDIO>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s2m1_lrck
++ &i2s2m1_sclk
++ &i2s2m1_sdi
++ &i2s2m1_sdo>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s3_2ch: i2s@fe4a0000 {
++ compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
++ reg = <0x0 0xfe4a0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S3_2CH>, <&cru HCLK_I2S3_2CH>;
++ clock-names = "i2s_clk", "i2s_hclk";
++ assigned-clocks = <&cru CLK_I2S3_2CH_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac1 2>, <&dmac1 3>;
++ dma-names = "tx", "rx";
++ power-domains = <&power RK3588_PD_AUDIO>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s3_lrck
++ &i2s3_sclk
++ &i2s3_sdi
++ &i2s3_sdo>;
++ #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 = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-controller;
++ mbi-alias = <0x0 0xfe610000>;
++ mbi-ranges = <424 56>;
++ msi-controller;
++ ranges;
++ #address-cells = <2>;
++ #interrupt-cells = <4>;
++ #size-cells = <2>;
++
++ its0: msi-controller@fe640000 {
++ compatible = "arm,gic-v3-its";
++ reg = <0x0 0xfe640000 0x0 0x20000>;
++ msi-controller;
++ #msi-cells = <1>;
++ };
++
++ its1: msi-controller@fe660000 {
++ compatible = "arm,gic-v3-its";
++ reg = <0x0 0xfe660000 0x0 0x20000>;
++ msi-controller;
++ #msi-cells = <1>;
++ };
++
++ ppi-partitions {
++ ppi_partition0: interrupt-partition-0 {
++ affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
++ };
++
++ ppi_partition1: interrupt-partition-1 {
++ affinity = <&cpu_b0 &cpu_b1 &cpu_b2 &cpu_b3>;
++ };
++ };
++ };
++
++ dmac0: dma-controller@fea10000 {
++ compatible = "arm,pl330", "arm,primecell";
++ reg = <0x0 0xfea10000 0x0 0x4000>;
++ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>;
++ arm,pl330-periph-burst;
++ clocks = <&cru ACLK_DMAC0>;
++ clock-names = "apb_pclk";
++ #dma-cells = <1>;
++ };
++
++ dmac1: dma-controller@fea30000 {
++ compatible = "arm,pl330", "arm,primecell";
++ reg = <0x0 0xfea30000 0x0 0x4000>;
++ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>;
++ arm,pl330-periph-burst;
++ clocks = <&cru ACLK_DMAC1>;
++ clock-names = "apb_pclk";
++ #dma-cells = <1>;
++ };
++
++ i2c1: i2c@fea90000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfea90000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c1m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@feaa0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeaa0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c2m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@feab0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeab0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c3m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@feac0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeac0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c4m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c5: i2c@fead0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfead0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c5m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ timer0: timer@feae0000 {
++ compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer";
++ reg = <0x0 0xfeae0000 0x0 0x20>;
++ interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>;
++ clock-names = "pclk", "timer";
++ };
++
++ wdt: watchdog@feaf0000 {
++ compatible = "rockchip,rk3588-wdt", "snps,dw-wdt";
++ reg = <0x0 0xfeaf0000 0x0 0x100>;
++ clocks = <&cru TCLK_WDT0>, <&cru PCLK_WDT0>;
++ clock-names = "tclk", "pclk";
++ interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH 0>;
++ };
++
++ spi0: spi@feb00000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb00000 0x0 0x1000>;
++ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac0 14>, <&dmac0 15>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi1: spi@feb10000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb10000 0x0 0x1000>;
++ interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac0 16>, <&dmac0 17>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi1m1_cs0 &spi1m1_cs1 &spi1m1_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi2: spi@feb20000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb20000 0x0 0x1000>;
++ interrupts = <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac1 15>, <&dmac1 16>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi2m2_cs0 &spi2m2_cs1 &spi2m2_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi3: spi@feb30000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb30000 0x0 0x1000>;
++ interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac1 17>, <&dmac1 18>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi3m1_cs0 &spi3m1_cs1 &spi3m1_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ uart1: serial@feb40000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb40000 0x0 0x100>;
++ interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 8>, <&dmac0 9>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart1m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart2: serial@feb50000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb50000 0x0 0x100>;
++ interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 10>, <&dmac0 11>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart2m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart3: serial@feb60000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb60000 0x0 0x100>;
++ interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 12>, <&dmac0 13>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart3m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart4: serial@feb70000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb70000 0x0 0x100>;
++ interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac1 9>, <&dmac1 10>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart4m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart5: serial@feb80000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb80000 0x0 0x100>;
++ interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac1 11>, <&dmac1 12>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart5m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart6: serial@feb90000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb90000 0x0 0x100>;
++ interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac1 13>, <&dmac1 14>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart6m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart7: serial@feba0000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeba0000 0x0 0x100>;
++ interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac2 7>, <&dmac2 8>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart7m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart8: serial@febb0000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfebb0000 0x0 0x100>;
++ interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac2 9>, <&dmac2 10>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart8m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart9: serial@febc0000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfebc0000 0x0 0x100>;
++ interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac2 11>, <&dmac2 12>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart9m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ pwm4: pwm@febd0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0000 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm4m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm5: pwm@febd0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0010 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm5m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm6: pwm@febd0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0020 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm6m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm7: pwm@febd0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0030 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm7m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm8: pwm@febe0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0000 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm8m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm9: pwm@febe0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0010 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm9m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm10: pwm@febe0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0020 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm10m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm11: pwm@febe0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0030 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm11m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm12: pwm@febf0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0000 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm12m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm13: pwm@febf0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0010 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm13m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm14: pwm@febf0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0020 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm14m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm15: pwm@febf0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0030 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm15m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ tsadc: tsadc@fec00000 {
++ compatible = "rockchip,rk3588-tsadc";
++ reg = <0x0 0xfec00000 0x0 0x400>;
++ interrupts = <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
++ clock-names = "tsadc", "apb_pclk";
++ assigned-clocks = <&cru CLK_TSADC>;
++ assigned-clock-rates = <2000000>;
++ resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>;
++ reset-names = "tsadc-apb", "tsadc";
++ 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";
++ #thermal-sensor-cells = <1>;
++ status = "disabled";
++ };
++
++ saradc: adc@fec10000 {
++ compatible = "rockchip,rk3588-saradc";
++ reg = <0x0 0xfec10000 0x0 0x10000>;
++ interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH 0>;
++ #io-channel-cells = <1>;
++ clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
++ clock-names = "saradc", "apb_pclk";
++ resets = <&cru SRST_P_SARADC>;
++ reset-names = "saradc-apb";
++ status = "disabled";
++ };
++
++ i2c6: i2c@fec80000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfec80000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c6m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c7: i2c@fec90000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfec90000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c7m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c8: i2c@feca0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeca0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C8>, <&cru PCLK_I2C8>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c8m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi4: spi@fecb0000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfecb0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI4>, <&cru PCLK_SPI4>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac2 13>, <&dmac2 14>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi4m0_cs0 &spi4m0_cs1 &spi4m0_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ otp: efuse@fecc0000 {
++ compatible = "rockchip,rk3588-otp";
++ reg = <0x0 0xfecc0000 0x0 0x400>;
++ clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>,
++ <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>;
++ clock-names = "otp", "apb_pclk", "phy", "arb";
++ resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>,
++ <&cru SRST_OTPC_ARB>;
++ reset-names = "otp", "apb", "arb";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ cpu_code: cpu-code@2 {
++ reg = <0x02 0x2>;
++ };
++
++ otp_id: id@7 {
++ reg = <0x07 0x10>;
++ };
++
++ cpub0_leakage: cpu-leakage@17 {
++ reg = <0x17 0x1>;
++ };
++
++ cpub1_leakage: cpu-leakage@18 {
++ reg = <0x18 0x1>;
++ };
++
++ cpul_leakage: cpu-leakage@19 {
++ reg = <0x19 0x1>;
++ };
++
++ log_leakage: log-leakage@1a {
++ reg = <0x1a 0x1>;
++ };
++
++ gpu_leakage: gpu-leakage@1b {
++ reg = <0x1b 0x1>;
++ };
++
++ otp_cpu_version: cpu-version@1c {
++ reg = <0x1c 0x1>;
++ bits = <3 3>;
++ };
++
++ npu_leakage: npu-leakage@28 {
++ reg = <0x28 0x1>;
++ };
++
++ codec_leakage: codec-leakage@29 {
++ reg = <0x29 0x1>;
++ };
++ };
++
++ dmac2: dma-controller@fed10000 {
++ compatible = "arm,pl330", "arm,primecell";
++ reg = <0x0 0xfed10000 0x0 0x4000>;
++ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>;
++ arm,pl330-periph-burst;
++ clocks = <&cru ACLK_DMAC2>;
++ clock-names = "apb_pclk";
++ #dma-cells = <1>;
++ };
++
++ hdptxphy_hdmi0: 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";
++ #phy-cells = <0>;
++ resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
++ <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
++ <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
++ <&cru SRST_HDPTX0_LCPLL>;
++ reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
++ "lcpll";
++ rockchip,grf = <&hdptxphy0_grf>;
++ status = "disabled";
++ };
++
++ usbdp_phy0: phy@fed80000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed80000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY0_IMMORTAL>,
++ <&cru PCLK_USBDPPHY0>,
++ <&u2phy0>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY0_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY0_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY0_PCS>,
++ <&cru SRST_P_USBDPPHY0>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy0_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
++ combphy0_ps: phy@fee00000 {
++ compatible = "rockchip,rk3588-naneng-combphy";
++ reg = <0x0 0xfee00000 0x0 0x100>;
++ clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>,
++ <&cru PCLK_PHP_ROOT>;
++ clock-names = "ref", "apb", "pipe";
++ assigned-clocks = <&cru CLK_REF_PIPE_PHY0>;
++ assigned-clock-rates = <100000000>;
++ #phy-cells = <1>;
++ resets = <&cru SRST_REF_PIPE_PHY0>, <&cru SRST_P_PCIE2_PHY0>;
++ reset-names = "phy", "apb";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
++ status = "disabled";
++ };
++
++ combphy2_psu: phy@fee20000 {
++ compatible = "rockchip,rk3588-naneng-combphy";
++ reg = <0x0 0xfee20000 0x0 0x100>;
++ clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
++ <&cru PCLK_PHP_ROOT>;
++ clock-names = "ref", "apb", "pipe";
++ assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
++ assigned-clock-rates = <100000000>;
++ #phy-cells = <1>;
++ resets = <&cru SRST_REF_PIPE_PHY2>, <&cru SRST_P_PCIE2_PHY2>;
++ reset-names = "phy", "apb";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
++ status = "disabled";
++ };
++
++ system_sram2: sram@ff001000 {
++ compatible = "mmio-sram";
++ reg = <0x0 0xff001000 0x0 0xef000>;
++ ranges = <0x0 0x0 0xff001000 0xef000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ };
++
++ pinctrl: pinctrl {
++ compatible = "rockchip,rk3588-pinctrl";
++ ranges;
++ rockchip,grf = <&ioc>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ gpio0: gpio@fd8a0000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfd8a0000 0x0 0x100>;
++ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio1: gpio@fec20000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec20000 0x0 0x100>;
++ interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 32 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio2: gpio@fec30000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec30000 0x0 0x100>;
++ interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 64 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio3: gpio@fec40000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec40000 0x0 0x100>;
++ interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 96 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio4: gpio@fec50000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec50000 0x0 0x100>;
++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 128 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++ };
++};
++
++#include "rk3588-base-pinctrl.dtsi"
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+@@ -0,0 +1,413 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include "rk3588-base.dtsi"
++#include "rk3588-extra-pinctrl.dtsi"
++
++/ {
++ usb_host1_xhci: usb@fc400000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc400000 0x0 0x400000>;
++ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
++ <&cru ACLK_USB3OTG1>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG1>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
++ pcie30_phy_grf: syscon@fd5b8000 {
++ compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
++ reg = <0x0 0xfd5b8000 0x0 0x10000>;
++ };
++
++ pipe_phy1_grf: syscon@fd5c0000 {
++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
++ reg = <0x0 0xfd5c0000 0x0 0x100>;
++ };
++
++ usbdpphy1_grf: syscon@fd5cc000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5cc000 0x0 0x4000>;
++ };
++
++ usb2phy1_grf: syscon@fd5d4000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d4000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy1: usb2phy@4000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x4000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy1";
++ interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy1_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ i2s8_8ch: i2s@fddc8000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddc8000 0x0 0x1000>;
++ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S8_8CH_TX>, <&cru MCLK_I2S8_8CH_TX>, <&cru HCLK_I2S8_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S8_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 22>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO0>;
++ resets = <&cru SRST_M_I2S8_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s6_8ch: i2s@fddf4000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddf4000 0x0 0x1000>;
++ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S6_8CH_TX>, <&cru MCLK_I2S6_8CH_TX>, <&cru HCLK_I2S6_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S6_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 4>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S6_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s7_8ch: i2s@fddf8000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddf8000 0x0 0x1000>;
++ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S7_8CH_RX>, <&cru MCLK_I2S7_8CH_RX>, <&cru HCLK_I2S7_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S7_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 21>;
++ dma-names = "rx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S7_8CH_RX>;
++ reset-names = "rx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s10_8ch: i2s@fde00000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfde00000 0x0 0x1000>;
++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S10_8CH_RX>, <&cru MCLK_I2S10_8CH_RX>, <&cru HCLK_I2S10_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S10_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 24>;
++ dma-names = "rx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S10_8CH_RX>;
++ reset-names = "rx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ pcie3x4: pcie@fe150000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x00 0x0f>;
++ clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
++ <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
++ <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie3x4_intc 0>,
++ <0 0 0 2 &pcie3x4_intc 1>,
++ <0 0 0 3 &pcie3x4_intc 2>,
++ <0 0 0 4 &pcie3x4_intc 3>;
++ linux,pci-domain = <0>;
++ max-link-speed = <3>;
++ msi-map = <0x0000 &its1 0x0000 0x1000>;
++ num-lanes = <4>;
++ phys = <&pcie30phy>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0x00000000 0x0 0x40000000>;
++ reg = <0xa 0x40000000 0x0 0x00400000>,
++ <0x0 0xfe150000 0x0 0x00010000>,
++ <0x0 0xf0000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
++ reset-names = "pwr", "pipe";
++ status = "disabled";
++
++ pcie3x4_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ pcie3x2: pcie@fe160000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x10 0x1f>;
++ clocks = <&cru ACLK_PCIE_2L_MSTR>, <&cru ACLK_PCIE_2L_SLV>,
++ <&cru ACLK_PCIE_2L_DBI>, <&cru PCLK_PCIE_2L>,
++ <&cru CLK_PCIE_AUX1>, <&cru CLK_PCIE2L_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
++ <0 0 0 2 &pcie3x2_intc 1>,
++ <0 0 0 3 &pcie3x2_intc 2>,
++ <0 0 0 4 &pcie3x2_intc 3>;
++ linux,pci-domain = <1>;
++ max-link-speed = <3>;
++ msi-map = <0x1000 &its1 0x1000 0x1000>;
++ num-lanes = <2>;
++ phys = <&pcie30phy>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf1100000 0x0 0xf1100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf1200000 0x0 0xf1200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0x40000000 0x0 0x40000000>;
++ reg = <0xa 0x40400000 0x0 0x00400000>,
++ <0x0 0xfe160000 0x0 0x00010000>,
++ <0x0 0xf1000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
++ reset-names = "pwr", "pipe";
++ status = "disabled";
++
++ pcie3x2_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 255 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ pcie2x1l0: pcie@fe170000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ bus-range = <0x20 0x2f>;
++ clocks = <&cru ACLK_PCIE_1L0_MSTR>, <&cru ACLK_PCIE_1L0_SLV>,
++ <&cru ACLK_PCIE_1L0_DBI>, <&cru PCLK_PCIE_1L0>,
++ <&cru CLK_PCIE_AUX2>, <&cru CLK_PCIE1L0_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie2x1l0_intc 0>,
++ <0 0 0 2 &pcie2x1l0_intc 1>,
++ <0 0 0 3 &pcie2x1l0_intc 2>,
++ <0 0 0 4 &pcie2x1l0_intc 3>;
++ linux,pci-domain = <2>;
++ max-link-speed = <2>;
++ msi-map = <0x2000 &its0 0x2000 0x1000>;
++ num-lanes = <1>;
++ phys = <&combphy1_ps PHY_TYPE_PCIE>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf2100000 0x0 0xf2100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf2200000 0x0 0xf2200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0x80000000 0x0 0x40000000>;
++ reg = <0xa 0x40800000 0x0 0x00400000>,
++ <0x0 0xfe170000 0x0 0x00010000>,
++ <0x0 0xf2000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE2_POWER_UP>, <&cru SRST_P_PCIE2>;
++ reset-names = "pwr", "pipe";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ status = "disabled";
++
++ pcie2x1l0_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 240 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ gmac0: ethernet@fe1b0000 {
++ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
++ reg = <0x0 0xfe1b0000 0x0 0x10000>;
++ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "macirq", "eth_wake_irq";
++ clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
++ <&cru PCLK_GMAC0>, <&cru ACLK_GMAC0>,
++ <&cru CLK_GMAC0_PTP_REF>;
++ clock-names = "stmmaceth", "clk_mac_ref",
++ "pclk_mac", "aclk_mac",
++ "ptp_ref";
++ power-domains = <&power RK3588_PD_GMAC>;
++ resets = <&cru SRST_A_GMAC0>;
++ reset-names = "stmmaceth";
++ rockchip,grf = <&sys_grf>;
++ rockchip,php-grf = <&php_grf>;
++ snps,axi-config = <&gmac0_stmmac_axi_setup>;
++ snps,mixed-burst;
++ snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
++ snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
++ snps,tso;
++ status = "disabled";
++
++ mdio0: mdio {
++ compatible = "snps,dwmac-mdio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ };
++
++ gmac0_stmmac_axi_setup: stmmac-axi-config {
++ snps,blen = <0 0 0 0 16 8 4>;
++ snps,wr_osr_lmt = <4>;
++ snps,rd_osr_lmt = <8>;
++ };
++
++ gmac0_mtl_rx_setup: rx-queues-config {
++ snps,rx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++
++ gmac0_mtl_tx_setup: tx-queues-config {
++ snps,tx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++ };
++
++ sata1: sata@fe220000 {
++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
++ reg = <0 0xfe220000 0 0x1000>;
++ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>,
++ <&cru CLK_RXOOB1>, <&cru CLK_PIPEPHY1_REF>,
++ <&cru CLK_PIPEPHY1_PIPE_ASIC_G>;
++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
++ ports-implemented = <0x1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ sata-port@0 {
++ reg = <0>;
++ hba-port-cap = <HBA_PORT_FBSCP>;
++ phys = <&combphy1_ps PHY_TYPE_SATA>;
++ phy-names = "sata-phy";
++ snps,rx-ts-max = <32>;
++ snps,tx-ts-max = <32>;
++ };
++ };
++
++ usbdp_phy1: phy@fed90000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed90000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY1_IMMORTAL>,
++ <&cru PCLK_USBDPPHY1>,
++ <&u2phy1>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY1_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY1_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY1_PCS>,
++ <&cru SRST_P_USBDPPHY1>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy1_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
++ combphy1_ps: phy@fee10000 {
++ compatible = "rockchip,rk3588-naneng-combphy";
++ reg = <0x0 0xfee10000 0x0 0x100>;
++ clocks = <&cru CLK_REF_PIPE_PHY1>, <&cru PCLK_PCIE_COMBO_PIPE_PHY1>,
++ <&cru PCLK_PHP_ROOT>;
++ clock-names = "ref", "apb", "pipe";
++ assigned-clocks = <&cru CLK_REF_PIPE_PHY1>;
++ assigned-clock-rates = <100000000>;
++ #phy-cells = <1>;
++ resets = <&cru SRST_REF_PIPE_PHY1>, <&cru SRST_P_PCIE2_PHY1>;
++ reset-names = "phy", "apb";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
++ status = "disabled";
++ };
++
++ pcie30phy: phy@fee80000 {
++ compatible = "rockchip,rk3588-pcie3-phy";
++ reg = <0x0 0xfee80000 0x0 0x20000>;
++ #phy-cells = <0>;
++ clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>;
++ clock-names = "pclk";
++ resets = <&cru SRST_PCIE30_PHY>;
++ reset-names = "phy";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,phy-grf = <&pcie30_phy_grf>;
++ status = "disabled";
++ };
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -1,413 +1,7 @@
+ // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ /*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
++ *
+ */
+
+-#include "rk3588s.dtsi"
+-#include "rk3588-pinctrl.dtsi"
+-
+-/ {
+- usb_host1_xhci: usb@fc400000 {
+- compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+- reg = <0x0 0xfc400000 0x0 0x400000>;
+- interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
+- <&cru ACLK_USB3OTG1>;
+- clock-names = "ref_clk", "suspend_clk", "bus_clk";
+- dr_mode = "otg";
+- phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
+- phy-names = "usb2-phy", "usb3-phy";
+- phy_type = "utmi_wide";
+- power-domains = <&power RK3588_PD_USB>;
+- resets = <&cru SRST_A_USB3OTG1>;
+- snps,dis_enblslpm_quirk;
+- snps,dis-u2-freeclk-exists-quirk;
+- snps,dis-del-phy-power-chg-quirk;
+- snps,dis-tx-ipgap-linecheck-quirk;
+- status = "disabled";
+- };
+-
+- pcie30_phy_grf: syscon@fd5b8000 {
+- compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
+- reg = <0x0 0xfd5b8000 0x0 0x10000>;
+- };
+-
+- pipe_phy1_grf: syscon@fd5c0000 {
+- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+- reg = <0x0 0xfd5c0000 0x0 0x100>;
+- };
+-
+- usbdpphy1_grf: syscon@fd5cc000 {
+- compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+- reg = <0x0 0xfd5cc000 0x0 0x4000>;
+- };
+-
+- usb2phy1_grf: syscon@fd5d4000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5d4000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy1: usb2phy@4000 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0x4000 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy1";
+- interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy1_otg: otg-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- i2s8_8ch: i2s@fddc8000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddc8000 0x0 0x1000>;
+- interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S8_8CH_TX>, <&cru MCLK_I2S8_8CH_TX>, <&cru HCLK_I2S8_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S8_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 22>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO0>;
+- resets = <&cru SRST_M_I2S8_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s6_8ch: i2s@fddf4000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddf4000 0x0 0x1000>;
+- interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S6_8CH_TX>, <&cru MCLK_I2S6_8CH_TX>, <&cru HCLK_I2S6_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S6_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 4>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S6_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s7_8ch: i2s@fddf8000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddf8000 0x0 0x1000>;
+- interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S7_8CH_RX>, <&cru MCLK_I2S7_8CH_RX>, <&cru HCLK_I2S7_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S7_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 21>;
+- dma-names = "rx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S7_8CH_RX>;
+- reset-names = "rx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s10_8ch: i2s@fde00000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfde00000 0x0 0x1000>;
+- interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S10_8CH_RX>, <&cru MCLK_I2S10_8CH_RX>, <&cru HCLK_I2S10_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S10_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 24>;
+- dma-names = "rx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S10_8CH_RX>;
+- reset-names = "rx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- pcie3x4: pcie@fe150000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- bus-range = <0x00 0x0f>;
+- clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
+- <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
+- <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie3x4_intc 0>,
+- <0 0 0 2 &pcie3x4_intc 1>,
+- <0 0 0 3 &pcie3x4_intc 2>,
+- <0 0 0 4 &pcie3x4_intc 3>;
+- linux,pci-domain = <0>;
+- max-link-speed = <3>;
+- msi-map = <0x0000 &its1 0x0000 0x1000>;
+- num-lanes = <4>;
+- phys = <&pcie30phy>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0x00000000 0x0 0x40000000>;
+- reg = <0xa 0x40000000 0x0 0x00400000>,
+- <0x0 0xfe150000 0x0 0x00010000>,
+- <0x0 0xf0000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
+- reset-names = "pwr", "pipe";
+- status = "disabled";
+-
+- pcie3x4_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- pcie3x2: pcie@fe160000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- bus-range = <0x10 0x1f>;
+- clocks = <&cru ACLK_PCIE_2L_MSTR>, <&cru ACLK_PCIE_2L_SLV>,
+- <&cru ACLK_PCIE_2L_DBI>, <&cru PCLK_PCIE_2L>,
+- <&cru CLK_PCIE_AUX1>, <&cru CLK_PCIE2L_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
+- <0 0 0 2 &pcie3x2_intc 1>,
+- <0 0 0 3 &pcie3x2_intc 2>,
+- <0 0 0 4 &pcie3x2_intc 3>;
+- linux,pci-domain = <1>;
+- max-link-speed = <3>;
+- msi-map = <0x1000 &its1 0x1000 0x1000>;
+- num-lanes = <2>;
+- phys = <&pcie30phy>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf1100000 0x0 0xf1100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf1200000 0x0 0xf1200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0x40000000 0x0 0x40000000>;
+- reg = <0xa 0x40400000 0x0 0x00400000>,
+- <0x0 0xfe160000 0x0 0x00010000>,
+- <0x0 0xf1000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
+- reset-names = "pwr", "pipe";
+- status = "disabled";
+-
+- pcie3x2_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 255 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- pcie2x1l0: pcie@fe170000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- bus-range = <0x20 0x2f>;
+- clocks = <&cru ACLK_PCIE_1L0_MSTR>, <&cru ACLK_PCIE_1L0_SLV>,
+- <&cru ACLK_PCIE_1L0_DBI>, <&cru PCLK_PCIE_1L0>,
+- <&cru CLK_PCIE_AUX2>, <&cru CLK_PCIE1L0_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie2x1l0_intc 0>,
+- <0 0 0 2 &pcie2x1l0_intc 1>,
+- <0 0 0 3 &pcie2x1l0_intc 2>,
+- <0 0 0 4 &pcie2x1l0_intc 3>;
+- linux,pci-domain = <2>;
+- max-link-speed = <2>;
+- msi-map = <0x2000 &its0 0x2000 0x1000>;
+- num-lanes = <1>;
+- phys = <&combphy1_ps PHY_TYPE_PCIE>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf2100000 0x0 0xf2100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf2200000 0x0 0xf2200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0x80000000 0x0 0x40000000>;
+- reg = <0xa 0x40800000 0x0 0x00400000>,
+- <0x0 0xfe170000 0x0 0x00010000>,
+- <0x0 0xf2000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE2_POWER_UP>, <&cru SRST_P_PCIE2>;
+- reset-names = "pwr", "pipe";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- status = "disabled";
+-
+- pcie2x1l0_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 240 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- gmac0: ethernet@fe1b0000 {
+- compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+- reg = <0x0 0xfe1b0000 0x0 0x10000>;
+- interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "macirq", "eth_wake_irq";
+- clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+- <&cru PCLK_GMAC0>, <&cru ACLK_GMAC0>,
+- <&cru CLK_GMAC0_PTP_REF>;
+- clock-names = "stmmaceth", "clk_mac_ref",
+- "pclk_mac", "aclk_mac",
+- "ptp_ref";
+- power-domains = <&power RK3588_PD_GMAC>;
+- resets = <&cru SRST_A_GMAC0>;
+- reset-names = "stmmaceth";
+- rockchip,grf = <&sys_grf>;
+- rockchip,php-grf = <&php_grf>;
+- snps,axi-config = <&gmac0_stmmac_axi_setup>;
+- snps,mixed-burst;
+- snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
+- snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
+- snps,tso;
+- status = "disabled";
+-
+- mdio0: mdio {
+- compatible = "snps,dwmac-mdio";
+- #address-cells = <0x1>;
+- #size-cells = <0x0>;
+- };
+-
+- gmac0_stmmac_axi_setup: stmmac-axi-config {
+- snps,blen = <0 0 0 0 16 8 4>;
+- snps,wr_osr_lmt = <4>;
+- snps,rd_osr_lmt = <8>;
+- };
+-
+- gmac0_mtl_rx_setup: rx-queues-config {
+- snps,rx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+-
+- gmac0_mtl_tx_setup: tx-queues-config {
+- snps,tx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+- };
+-
+- sata1: sata@fe220000 {
+- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+- reg = <0 0xfe220000 0 0x1000>;
+- interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>,
+- <&cru CLK_RXOOB1>, <&cru CLK_PIPEPHY1_REF>,
+- <&cru CLK_PIPEPHY1_PIPE_ASIC_G>;
+- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+- ports-implemented = <0x1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+-
+- sata-port@0 {
+- reg = <0>;
+- hba-port-cap = <HBA_PORT_FBSCP>;
+- phys = <&combphy1_ps PHY_TYPE_SATA>;
+- phy-names = "sata-phy";
+- snps,rx-ts-max = <32>;
+- snps,tx-ts-max = <32>;
+- };
+- };
+-
+- usbdp_phy1: phy@fed90000 {
+- compatible = "rockchip,rk3588-usbdp-phy";
+- reg = <0x0 0xfed90000 0x0 0x10000>;
+- #phy-cells = <1>;
+- clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+- <&cru CLK_USBDP_PHY1_IMMORTAL>,
+- <&cru PCLK_USBDPPHY1>,
+- <&u2phy1>;
+- clock-names = "refclk", "immortal", "pclk", "utmi";
+- resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
+- <&cru SRST_USBDP_COMBO_PHY1_CMN>,
+- <&cru SRST_USBDP_COMBO_PHY1_LANE>,
+- <&cru SRST_USBDP_COMBO_PHY1_PCS>,
+- <&cru SRST_P_USBDPPHY1>;
+- reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+- rockchip,u2phy-grf = <&usb2phy1_grf>;
+- rockchip,usb-grf = <&usb_grf>;
+- rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
+- rockchip,vo-grf = <&vo0_grf>;
+- status = "disabled";
+- };
+-
+- combphy1_ps: phy@fee10000 {
+- compatible = "rockchip,rk3588-naneng-combphy";
+- reg = <0x0 0xfee10000 0x0 0x100>;
+- clocks = <&cru CLK_REF_PIPE_PHY1>, <&cru PCLK_PCIE_COMBO_PIPE_PHY1>,
+- <&cru PCLK_PHP_ROOT>;
+- clock-names = "ref", "apb", "pipe";
+- assigned-clocks = <&cru CLK_REF_PIPE_PHY1>;
+- assigned-clock-rates = <100000000>;
+- #phy-cells = <1>;
+- resets = <&cru SRST_REF_PIPE_PHY1>, <&cru SRST_P_PCIE2_PHY1>;
+- reset-names = "phy", "apb";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
+- status = "disabled";
+- };
+-
+- pcie30phy: phy@fee80000 {
+- compatible = "rockchip,rk3588-pcie3-phy";
+- reg = <0x0 0xfee80000 0x0 0x20000>;
+- #phy-cells = <0>;
+- clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>;
+- clock-names = "pclk";
+- resets = <&cru SRST_PCIE30_PHY>;
+- reset-names = "phy";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,phy-grf = <&pcie30_phy_grf>;
+- status = "disabled";
+- };
+-};
++#include "rk3588-extra.dtsi"
+--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+@@ -4,4 +4,4 @@
+ *
+ */
+
+-#include "rk3588.dtsi"
++#include "rk3588-extra.dtsi"
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -1,2670 +1,7 @@
+ // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ /*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
++ *
+ */
+
+-#include <dt-bindings/clock/rockchip,rk3588-cru.h>
+-#include <dt-bindings/interrupt-controller/arm-gic.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/power/rk3588-power.h>
+-#include <dt-bindings/reset/rockchip,rk3588-cru.h>
+-#include <dt-bindings/phy/phy.h>
+-#include <dt-bindings/ata/ahci.h>
+-
+-/ {
+- compatible = "rockchip,rk3588";
+-
+- interrupt-parent = <&gic>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+-
+- aliases {
+- gpio0 = &gpio0;
+- gpio1 = &gpio1;
+- gpio2 = &gpio2;
+- gpio3 = &gpio3;
+- gpio4 = &gpio4;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c7 = &i2c7;
+- i2c8 = &i2c8;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial5 = &uart5;
+- serial6 = &uart6;
+- serial7 = &uart7;
+- serial8 = &uart8;
+- serial9 = &uart9;
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- };
+-
+- cpus {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- cpu-map {
+- cluster0 {
+- core0 {
+- cpu = <&cpu_l0>;
+- };
+- core1 {
+- cpu = <&cpu_l1>;
+- };
+- core2 {
+- cpu = <&cpu_l2>;
+- };
+- core3 {
+- cpu = <&cpu_l3>;
+- };
+- };
+- cluster1 {
+- core0 {
+- cpu = <&cpu_b0>;
+- };
+- core1 {
+- cpu = <&cpu_b1>;
+- };
+- };
+- cluster2 {
+- core0 {
+- cpu = <&cpu_b2>;
+- };
+- core1 {
+- cpu = <&cpu_b3>;
+- };
+- };
+- };
+-
+- cpu_l0: cpu@0 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x0>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- assigned-clock-rates = <816000000>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l0>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_l1: cpu@100 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x100>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l1>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_l2: cpu@200 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x200>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l2>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_l3: cpu@300 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x300>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l3>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b0: cpu@400 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x400>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+- assigned-clock-rates = <816000000>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b0>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b1: cpu@500 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x500>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b1>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b2: cpu@600 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x600>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+- assigned-clock-rates = <816000000>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b2>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b3: cpu@700 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x700>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b3>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- idle-states {
+- entry-method = "psci";
+- CPU_SLEEP: cpu-sleep {
+- compatible = "arm,idle-state";
+- local-timer-stop;
+- arm,psci-suspend-param = <0x0010000>;
+- entry-latency-us = <100>;
+- exit-latency-us = <120>;
+- min-residency-us = <1000>;
+- };
+- };
+-
+- l2_cache_l0: l2-cache-l0 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l1: l2-cache-l1 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l2: l2-cache-l2 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l3: l2-cache-l3 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b0: l2-cache-b0 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b1: l2-cache-b1 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b2: l2-cache-b2 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b3: l2-cache-b3 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l3_cache: l3-cache {
+- compatible = "cache";
+- cache-size = <3145728>;
+- cache-line-size = <64>;
+- cache-sets = <4096>;
+- cache-level = <3>;
+- cache-unified;
+- };
+- };
+-
+- display_subsystem: display-subsystem {
+- compatible = "rockchip,display-subsystem";
+- ports = <&vop_out>;
+- };
+-
+- firmware {
+- optee: optee {
+- compatible = "linaro,optee-tz";
+- method = "smc";
+- };
+-
+- scmi: scmi {
+- compatible = "arm,scmi-smc";
+- arm,smc-id = <0x82000010>;
+- shmem = <&scmi_shmem>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- scmi_clk: protocol@14 {
+- reg = <0x14>;
+- #clock-cells = <1>;
+- };
+-
+- scmi_reset: protocol@16 {
+- reg = <0x16>;
+- #reset-cells = <1>;
+- };
+- };
+- };
+-
+- pmu-a55 {
+- compatible = "arm,cortex-a55-pmu";
+- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition0>;
+- };
+-
+- pmu-a76 {
+- compatible = "arm,cortex-a76-pmu";
+- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition1>;
+- };
+-
+- psci {
+- compatible = "arm,psci-1.0";
+- method = "smc";
+- };
+-
+- spll: clock-0 {
+- compatible = "fixed-clock";
+- clock-frequency = <702000000>;
+- clock-output-names = "spll";
+- #clock-cells = <0>;
+- };
+-
+- timer {
+- compatible = "arm,armv8-timer";
+- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
+- };
+-
+- xin24m: clock-1 {
+- compatible = "fixed-clock";
+- clock-frequency = <24000000>;
+- clock-output-names = "xin24m";
+- #clock-cells = <0>;
+- };
+-
+- xin32k: clock-2 {
+- compatible = "fixed-clock";
+- clock-frequency = <32768>;
+- clock-output-names = "xin32k";
+- #clock-cells = <0>;
+- };
+-
+- pmu_sram: sram@10f000 {
+- compatible = "mmio-sram";
+- reg = <0x0 0x0010f000 0x0 0x100>;
+- ranges = <0 0x0 0x0010f000 0x100>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- scmi_shmem: sram@0 {
+- compatible = "arm,scmi-shmem";
+- reg = <0x0 0x100>;
+- };
+- };
+-
+- gpu: gpu@fb000000 {
+- compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
+- reg = <0x0 0xfb000000 0x0 0x200000>;
+- #cooling-cells = <2>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+- assigned-clock-rates = <200000000>;
+- clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
+- <&cru CLK_GPU_STACKS>;
+- clock-names = "core", "coregroup", "stacks";
+- dynamic-power-coefficient = <2982>;
+- interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "job", "mmu", "gpu";
+- operating-points-v2 = <&gpu_opp_table>;
+- power-domains = <&power RK3588_PD_GPU>;
+- status = "disabled";
+-
+- gpu_opp_table: opp-table {
+- compatible = "operating-points-v2";
+-
+- opp-300000000 {
+- opp-hz = /bits/ 64 <300000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-400000000 {
+- opp-hz = /bits/ 64 <400000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-500000000 {
+- opp-hz = /bits/ 64 <500000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-600000000 {
+- opp-hz = /bits/ 64 <600000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-700000000 {
+- opp-hz = /bits/ 64 <700000000>;
+- opp-microvolt = <700000 700000 850000>;
+- };
+- opp-800000000 {
+- opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <750000 750000 850000>;
+- };
+- opp-900000000 {
+- opp-hz = /bits/ 64 <900000000>;
+- opp-microvolt = <800000 800000 850000>;
+- };
+- opp-1000000000 {
+- opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <850000 850000 850000>;
+- };
+- };
+- };
+-
+- usb_host0_xhci: usb@fc000000 {
+- compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+- reg = <0x0 0xfc000000 0x0 0x400000>;
+- interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
+- <&cru ACLK_USB3OTG0>;
+- clock-names = "ref_clk", "suspend_clk", "bus_clk";
+- dr_mode = "otg";
+- phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
+- phy-names = "usb2-phy", "usb3-phy";
+- phy_type = "utmi_wide";
+- power-domains = <&power RK3588_PD_USB>;
+- resets = <&cru SRST_A_USB3OTG0>;
+- snps,dis_enblslpm_quirk;
+- snps,dis-u1-entry-quirk;
+- snps,dis-u2-entry-quirk;
+- snps,dis-u2-freeclk-exists-quirk;
+- snps,dis-del-phy-power-chg-quirk;
+- snps,dis-tx-ipgap-linecheck-quirk;
+- status = "disabled";
+- };
+-
+- usb_host0_ehci: usb@fc800000 {
+- compatible = "rockchip,rk3588-ehci", "generic-ehci";
+- reg = <0x0 0xfc800000 0x0 0x40000>;
+- interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
+- phys = <&u2phy2_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host0_ohci: usb@fc840000 {
+- compatible = "rockchip,rk3588-ohci", "generic-ohci";
+- reg = <0x0 0xfc840000 0x0 0x40000>;
+- interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
+- phys = <&u2phy2_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host1_ehci: usb@fc880000 {
+- compatible = "rockchip,rk3588-ehci", "generic-ehci";
+- reg = <0x0 0xfc880000 0x0 0x40000>;
+- interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
+- phys = <&u2phy3_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host1_ohci: usb@fc8c0000 {
+- compatible = "rockchip,rk3588-ohci", "generic-ohci";
+- reg = <0x0 0xfc8c0000 0x0 0x40000>;
+- interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
+- phys = <&u2phy3_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host2_xhci: usb@fcd00000 {
+- compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+- reg = <0x0 0xfcd00000 0x0 0x400000>;
+- interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
+- <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
+- <&cru CLK_PIPEPHY2_PIPE_U3_G>;
+- clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
+- dr_mode = "host";
+- phys = <&combphy2_psu PHY_TYPE_USB3>;
+- phy-names = "usb3-phy";
+- phy_type = "utmi_wide";
+- resets = <&cru SRST_A_USB3OTG2>;
+- snps,dis_enblslpm_quirk;
+- snps,dis-u2-freeclk-exists-quirk;
+- snps,dis-del-phy-power-chg-quirk;
+- snps,dis-tx-ipgap-linecheck-quirk;
+- snps,dis_rxdet_inp3_quirk;
+- status = "disabled";
+- };
+-
+- mmu600_pcie: iommu@fc900000 {
+- compatible = "arm,smmu-v3";
+- reg = <0x0 0xfc900000 0x0 0x200000>;
+- interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+- #iommu-cells = <1>;
+- status = "disabled";
+- };
+-
+- mmu600_php: iommu@fcb00000 {
+- compatible = "arm,smmu-v3";
+- reg = <0x0 0xfcb00000 0x0 0x200000>;
+- interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+- #iommu-cells = <1>;
+- status = "disabled";
+- };
+-
+- pmu1grf: syscon@fd58a000 {
+- compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd58a000 0x0 0x10000>;
+- };
+-
+- sys_grf: syscon@fd58c000 {
+- compatible = "rockchip,rk3588-sys-grf", "syscon";
+- reg = <0x0 0xfd58c000 0x0 0x1000>;
+- };
+-
+- vop_grf: syscon@fd5a4000 {
+- compatible = "rockchip,rk3588-vop-grf", "syscon";
+- reg = <0x0 0xfd5a4000 0x0 0x2000>;
+- };
+-
+- vo0_grf: syscon@fd5a6000 {
+- compatible = "rockchip,rk3588-vo-grf", "syscon";
+- reg = <0x0 0xfd5a6000 0x0 0x2000>;
+- clocks = <&cru PCLK_VO0GRF>;
+- };
+-
+- vo1_grf: syscon@fd5a8000 {
+- compatible = "rockchip,rk3588-vo-grf", "syscon";
+- reg = <0x0 0xfd5a8000 0x0 0x100>;
+- clocks = <&cru PCLK_VO1GRF>;
+- };
+-
+- usb_grf: syscon@fd5ac000 {
+- compatible = "rockchip,rk3588-usb-grf", "syscon";
+- reg = <0x0 0xfd5ac000 0x0 0x4000>;
+- };
+-
+- php_grf: syscon@fd5b0000 {
+- compatible = "rockchip,rk3588-php-grf", "syscon";
+- reg = <0x0 0xfd5b0000 0x0 0x1000>;
+- };
+-
+- pipe_phy0_grf: syscon@fd5bc000 {
+- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+- reg = <0x0 0xfd5bc000 0x0 0x100>;
+- };
+-
+- pipe_phy2_grf: syscon@fd5c4000 {
+- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+- reg = <0x0 0xfd5c4000 0x0 0x100>;
+- };
+-
+- usbdpphy0_grf: syscon@fd5c8000 {
+- compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+- reg = <0x0 0xfd5c8000 0x0 0x4000>;
+- };
+-
+- usb2phy0_grf: syscon@fd5d0000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5d0000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy0: usb2phy@0 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0x0 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy0";
+- interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy0_otg: otg-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- usb2phy2_grf: syscon@fd5d8000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5d8000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy2: usb2phy@8000 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0x8000 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy2";
+- interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy2_host: host-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- usb2phy3_grf: syscon@fd5dc000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5dc000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy3: usb2phy@c000 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0xc000 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy3";
+- interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy3_host: host-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- hdptxphy0_grf: syscon@fd5e0000 {
+- compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+- reg = <0x0 0xfd5e0000 0x0 0x100>;
+- };
+-
+- ioc: syscon@fd5f0000 {
+- compatible = "rockchip,rk3588-ioc", "syscon";
+- reg = <0x0 0xfd5f0000 0x0 0x10000>;
+- };
+-
+- system_sram1: sram@fd600000 {
+- compatible = "mmio-sram";
+- reg = <0x0 0xfd600000 0x0 0x100000>;
+- ranges = <0x0 0x0 0xfd600000 0x100000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+- };
+-
+- cru: clock-controller@fd7c0000 {
+- compatible = "rockchip,rk3588-cru";
+- reg = <0x0 0xfd7c0000 0x0 0x5c000>;
+- assigned-clocks =
+- <&cru PLL_PPLL>, <&cru PLL_AUPLL>,
+- <&cru PLL_NPLL>, <&cru PLL_GPLL>,
+- <&cru ACLK_CENTER_ROOT>,
+- <&cru HCLK_CENTER_ROOT>, <&cru ACLK_CENTER_LOW_ROOT>,
+- <&cru ACLK_TOP_ROOT>, <&cru PCLK_TOP_ROOT>,
+- <&cru ACLK_LOW_TOP_ROOT>, <&cru PCLK_PMU0_ROOT>,
+- <&cru HCLK_PMU_CM0_ROOT>, <&cru ACLK_VOP>,
+- <&cru ACLK_BUS_ROOT>, <&cru CLK_150M_SRC>,
+- <&cru CLK_GPU>;
+- assigned-clock-rates =
+- <1100000000>, <786432000>,
+- <850000000>, <1188000000>,
+- <702000000>,
+- <400000000>, <500000000>,
+- <800000000>, <100000000>,
+- <400000000>, <100000000>,
+- <200000000>, <500000000>,
+- <375000000>, <150000000>,
+- <200000000>;
+- rockchip,grf = <&php_grf>;
+- #clock-cells = <1>;
+- #reset-cells = <1>;
+- };
+-
+- i2c0: i2c@fd880000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfd880000 0x0 0x1000>;
+- interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>;
+- clock-names = "i2c", "pclk";
+- pinctrl-0 = <&i2c0m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- uart0: serial@fd890000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfd890000 0x0 0x100>;
+- interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 6>, <&dmac0 7>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart0m1_xfer>;
+- pinctrl-names = "default";
+- reg-shift = <2>;
+- reg-io-width = <4>;
+- status = "disabled";
+- };
+-
+- pwm0: pwm@fd8b0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0000 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm0m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm1: pwm@fd8b0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0010 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm1m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm2: pwm@fd8b0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0020 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm2m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm3: pwm@fd8b0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0030 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm3m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pmu: power-management@fd8d8000 {
+- compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd";
+- reg = <0x0 0xfd8d8000 0x0 0x400>;
+-
+- power: power-controller {
+- compatible = "rockchip,rk3588-power-controller";
+- #address-cells = <1>;
+- #power-domain-cells = <1>;
+- #size-cells = <0>;
+- status = "okay";
+-
+- /* These power domains are grouped by VD_NPU */
+- power-domain@RK3588_PD_NPU {
+- reg = <RK3588_PD_NPU>;
+- #power-domain-cells = <0>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- power-domain@RK3588_PD_NPUTOP {
+- reg = <RK3588_PD_NPUTOP>;
+- clocks = <&cru HCLK_NPU_ROOT>,
+- <&cru PCLK_NPU_ROOT>,
+- <&cru CLK_NPU_DSU0>,
+- <&cru HCLK_NPU_CM0_ROOT>;
+- pm_qos = <&qos_npu0_mwr>,
+- <&qos_npu0_mro>,
+- <&qos_mcu_npu>;
+- #power-domain-cells = <0>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- power-domain@RK3588_PD_NPU1 {
+- reg = <RK3588_PD_NPU1>;
+- clocks = <&cru HCLK_NPU_ROOT>,
+- <&cru PCLK_NPU_ROOT>,
+- <&cru CLK_NPU_DSU0>;
+- pm_qos = <&qos_npu1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_NPU2 {
+- reg = <RK3588_PD_NPU2>;
+- clocks = <&cru HCLK_NPU_ROOT>,
+- <&cru PCLK_NPU_ROOT>,
+- <&cru CLK_NPU_DSU0>;
+- pm_qos = <&qos_npu2>;
+- #power-domain-cells = <0>;
+- };
+- };
+- };
+- /* These power domains are grouped by VD_GPU */
+- power-domain@RK3588_PD_GPU {
+- reg = <RK3588_PD_GPU>;
+- clocks = <&cru CLK_GPU>,
+- <&cru CLK_GPU_COREGROUP>,
+- <&cru CLK_GPU_STACKS>;
+- pm_qos = <&qos_gpu_m0>,
+- <&qos_gpu_m1>,
+- <&qos_gpu_m2>,
+- <&qos_gpu_m3>;
+- #power-domain-cells = <0>;
+- };
+- /* These power domains are grouped by VD_VCODEC */
+- power-domain@RK3588_PD_VCODEC {
+- reg = <RK3588_PD_VCODEC>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_RKVDEC0 {
+- reg = <RK3588_PD_RKVDEC0>;
+- clocks = <&cru HCLK_RKVDEC0>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_RKVDEC0>,
+- <&cru ACLK_RKVDEC_CCU>;
+- pm_qos = <&qos_rkvdec0>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RKVDEC1 {
+- reg = <RK3588_PD_RKVDEC1>;
+- clocks = <&cru HCLK_RKVDEC1>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_RKVDEC1>;
+- pm_qos = <&qos_rkvdec1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_VENC0 {
+- reg = <RK3588_PD_VENC0>;
+- clocks = <&cru HCLK_RKVENC0>,
+- <&cru ACLK_RKVENC0>;
+- pm_qos = <&qos_rkvenc0_m0ro>,
+- <&qos_rkvenc0_m1ro>,
+- <&qos_rkvenc0_m2wo>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_VENC1 {
+- reg = <RK3588_PD_VENC1>;
+- clocks = <&cru HCLK_RKVENC1>,
+- <&cru HCLK_RKVENC0>,
+- <&cru ACLK_RKVENC0>,
+- <&cru ACLK_RKVENC1>;
+- pm_qos = <&qos_rkvenc1_m0ro>,
+- <&qos_rkvenc1_m1ro>,
+- <&qos_rkvenc1_m2wo>;
+- #power-domain-cells = <0>;
+- };
+- };
+- };
+- /* These power domains are grouped by VD_LOGIC */
+- power-domain@RK3588_PD_VDPU {
+- reg = <RK3588_PD_VDPU>;
+- clocks = <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_LOW_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_JPEG_DECODER_ROOT>,
+- <&cru ACLK_IEP2P0>,
+- <&cru HCLK_IEP2P0>,
+- <&cru ACLK_JPEG_ENCODER0>,
+- <&cru HCLK_JPEG_ENCODER0>,
+- <&cru ACLK_JPEG_ENCODER1>,
+- <&cru HCLK_JPEG_ENCODER1>,
+- <&cru ACLK_JPEG_ENCODER2>,
+- <&cru HCLK_JPEG_ENCODER2>,
+- <&cru ACLK_JPEG_ENCODER3>,
+- <&cru HCLK_JPEG_ENCODER3>,
+- <&cru ACLK_JPEG_DECODER>,
+- <&cru HCLK_JPEG_DECODER>,
+- <&cru ACLK_RGA2>,
+- <&cru HCLK_RGA2>;
+- pm_qos = <&qos_iep>,
+- <&qos_jpeg_dec>,
+- <&qos_jpeg_enc0>,
+- <&qos_jpeg_enc1>,
+- <&qos_jpeg_enc2>,
+- <&qos_jpeg_enc3>,
+- <&qos_rga2_mro>,
+- <&qos_rga2_mwo>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+-
+- power-domain@RK3588_PD_AV1 {
+- reg = <RK3588_PD_AV1>;
+- clocks = <&cru PCLK_AV1>,
+- <&cru ACLK_AV1>,
+- <&cru HCLK_VDPU_ROOT>;
+- pm_qos = <&qos_av1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RKVDEC0 {
+- reg = <RK3588_PD_RKVDEC0>;
+- clocks = <&cru HCLK_RKVDEC0>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_RKVDEC0>;
+- pm_qos = <&qos_rkvdec0>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RKVDEC1 {
+- reg = <RK3588_PD_RKVDEC1>;
+- clocks = <&cru HCLK_RKVDEC1>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>;
+- pm_qos = <&qos_rkvdec1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RGA30 {
+- reg = <RK3588_PD_RGA30>;
+- clocks = <&cru ACLK_RGA3_0>,
+- <&cru HCLK_RGA3_0>;
+- pm_qos = <&qos_rga3_0>;
+- #power-domain-cells = <0>;
+- };
+- };
+- power-domain@RK3588_PD_VOP {
+- reg = <RK3588_PD_VOP>;
+- clocks = <&cru PCLK_VOP_ROOT>,
+- <&cru HCLK_VOP_ROOT>,
+- <&cru ACLK_VOP>;
+- pm_qos = <&qos_vop_m0>,
+- <&qos_vop_m1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_VO0 {
+- reg = <RK3588_PD_VO0>;
+- clocks = <&cru PCLK_VO0_ROOT>,
+- <&cru PCLK_VO0_S_ROOT>,
+- <&cru HCLK_VO0_S_ROOT>,
+- <&cru ACLK_VO0_ROOT>,
+- <&cru HCLK_HDCP0>,
+- <&cru ACLK_HDCP0>,
+- <&cru HCLK_VOP_ROOT>;
+- pm_qos = <&qos_hdcp0>;
+- #power-domain-cells = <0>;
+- };
+- };
+- power-domain@RK3588_PD_VO1 {
+- reg = <RK3588_PD_VO1>;
+- clocks = <&cru PCLK_VO1_ROOT>,
+- <&cru PCLK_VO1_S_ROOT>,
+- <&cru HCLK_VO1_S_ROOT>,
+- <&cru HCLK_HDCP1>,
+- <&cru ACLK_HDCP1>,
+- <&cru ACLK_HDMIRX_ROOT>,
+- <&cru HCLK_VO1USB_TOP_ROOT>;
+- pm_qos = <&qos_hdcp1>,
+- <&qos_hdmirx>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_VI {
+- reg = <RK3588_PD_VI>;
+- clocks = <&cru HCLK_VI_ROOT>,
+- <&cru PCLK_VI_ROOT>,
+- <&cru HCLK_ISP0>,
+- <&cru ACLK_ISP0>,
+- <&cru HCLK_VICAP>,
+- <&cru ACLK_VICAP>;
+- pm_qos = <&qos_isp0_mro>,
+- <&qos_isp0_mwo>,
+- <&qos_vicap_m0>,
+- <&qos_vicap_m1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_ISP1 {
+- reg = <RK3588_PD_ISP1>;
+- clocks = <&cru HCLK_ISP1>,
+- <&cru ACLK_ISP1>,
+- <&cru HCLK_VI_ROOT>,
+- <&cru PCLK_VI_ROOT>;
+- pm_qos = <&qos_isp1_mwo>,
+- <&qos_isp1_mro>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_FEC {
+- reg = <RK3588_PD_FEC>;
+- clocks = <&cru HCLK_FISHEYE0>,
+- <&cru ACLK_FISHEYE0>,
+- <&cru HCLK_FISHEYE1>,
+- <&cru ACLK_FISHEYE1>,
+- <&cru PCLK_VI_ROOT>;
+- pm_qos = <&qos_fisheye0>,
+- <&qos_fisheye1>;
+- #power-domain-cells = <0>;
+- };
+- };
+- power-domain@RK3588_PD_RGA31 {
+- reg = <RK3588_PD_RGA31>;
+- clocks = <&cru HCLK_RGA3_1>,
+- <&cru ACLK_RGA3_1>;
+- pm_qos = <&qos_rga3_1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_USB {
+- reg = <RK3588_PD_USB>;
+- clocks = <&cru PCLK_PHP_ROOT>,
+- <&cru ACLK_USB_ROOT>,
+- <&cru ACLK_USB>,
+- <&cru HCLK_USB_ROOT>,
+- <&cru HCLK_HOST0>,
+- <&cru HCLK_HOST_ARB0>,
+- <&cru HCLK_HOST1>,
+- <&cru HCLK_HOST_ARB1>;
+- pm_qos = <&qos_usb3_0>,
+- <&qos_usb3_1>,
+- <&qos_usb2host_0>,
+- <&qos_usb2host_1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_GMAC {
+- reg = <RK3588_PD_GMAC>;
+- clocks = <&cru PCLK_PHP_ROOT>,
+- <&cru ACLK_PCIE_ROOT>,
+- <&cru ACLK_PHP_ROOT>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_PCIE {
+- reg = <RK3588_PD_PCIE>;
+- clocks = <&cru PCLK_PHP_ROOT>,
+- <&cru ACLK_PCIE_ROOT>,
+- <&cru ACLK_PHP_ROOT>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_SDIO {
+- reg = <RK3588_PD_SDIO>;
+- clocks = <&cru HCLK_SDIO>,
+- <&cru HCLK_NVM_ROOT>;
+- pm_qos = <&qos_sdio>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_AUDIO {
+- reg = <RK3588_PD_AUDIO>;
+- clocks = <&cru HCLK_AUDIO_ROOT>,
+- <&cru PCLK_AUDIO_ROOT>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_SDMMC {
+- reg = <RK3588_PD_SDMMC>;
+- pm_qos = <&qos_sdmmc>;
+- #power-domain-cells = <0>;
+- };
+- };
+- };
+-
+- av1d: video-codec@fdc70000 {
+- compatible = "rockchip,rk3588-av1-vpu";
+- reg = <0x0 0xfdc70000 0x0 0x800>;
+- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "vdpu";
+- assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- assigned-clock-rates = <400000000>, <400000000>;
+- clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- clock-names = "aclk", "hclk";
+- power-domains = <&power RK3588_PD_AV1>;
+- resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+- };
+-
+- vop: vop@fdd90000 {
+- compatible = "rockchip,rk3588-vop";
+- reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
+- reg-names = "vop", "gamma-lut";
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>,
+- <&cru HCLK_VOP>,
+- <&cru DCLK_VOP0>,
+- <&cru DCLK_VOP1>,
+- <&cru DCLK_VOP2>,
+- <&cru DCLK_VOP3>,
+- <&cru PCLK_VOP_ROOT>;
+- clock-names = "aclk",
+- "hclk",
+- "dclk_vp0",
+- "dclk_vp1",
+- "dclk_vp2",
+- "dclk_vp3",
+- "pclk_vop";
+- iommus = <&vop_mmu>;
+- power-domains = <&power RK3588_PD_VOP>;
+- rockchip,grf = <&sys_grf>;
+- rockchip,vop-grf = <&vop_grf>;
+- rockchip,vo1-grf = <&vo1_grf>;
+- rockchip,pmu = <&pmu>;
+- status = "disabled";
+-
+- vop_out: ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- vp0: port@0 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <0>;
+- };
+-
+- vp1: port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <1>;
+- };
+-
+- vp2: port@2 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <2>;
+- };
+-
+- vp3: port@3 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <3>;
+- };
+- };
+- };
+-
+- vop_mmu: iommu@fdd97e00 {
+- compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
+- reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+- clock-names = "aclk", "iface";
+- #iommu-cells = <0>;
+- power-domains = <&power RK3588_PD_VOP>;
+- status = "disabled";
+- };
+-
+- i2s4_8ch: i2s@fddc0000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddc0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S4_8CH_TX>, <&cru MCLK_I2S4_8CH_TX>, <&cru HCLK_I2S4_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S4_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 0>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO0>;
+- resets = <&cru SRST_M_I2S4_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s5_8ch: i2s@fddf0000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddf0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S5_8CH_TX>, <&cru MCLK_I2S5_8CH_TX>, <&cru HCLK_I2S5_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S5_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 2>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S5_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s9_8ch: i2s@fddfc000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddfc000 0x0 0x1000>;
+- interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S9_8CH_RX>, <&cru MCLK_I2S9_8CH_RX>, <&cru HCLK_I2S9_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S9_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 23>;
+- dma-names = "rx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S9_8CH_RX>;
+- reset-names = "rx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- qos_gpu_m0: qos@fdf35000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35000 0x0 0x20>;
+- };
+-
+- qos_gpu_m1: qos@fdf35200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35200 0x0 0x20>;
+- };
+-
+- qos_gpu_m2: qos@fdf35400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35400 0x0 0x20>;
+- };
+-
+- qos_gpu_m3: qos@fdf35600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35600 0x0 0x20>;
+- };
+-
+- qos_rga3_1: qos@fdf36000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf36000 0x0 0x20>;
+- };
+-
+- qos_sdio: qos@fdf39000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf39000 0x0 0x20>;
+- };
+-
+- qos_sdmmc: qos@fdf3d800 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3d800 0x0 0x20>;
+- };
+-
+- qos_usb3_1: qos@fdf3e000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e000 0x0 0x20>;
+- };
+-
+- qos_usb3_0: qos@fdf3e200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e200 0x0 0x20>;
+- };
+-
+- qos_usb2host_0: qos@fdf3e400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e400 0x0 0x20>;
+- };
+-
+- qos_usb2host_1: qos@fdf3e600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e600 0x0 0x20>;
+- };
+-
+- qos_fisheye0: qos@fdf40000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40000 0x0 0x20>;
+- };
+-
+- qos_fisheye1: qos@fdf40200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40200 0x0 0x20>;
+- };
+-
+- qos_isp0_mro: qos@fdf40400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40400 0x0 0x20>;
+- };
+-
+- qos_isp0_mwo: qos@fdf40500 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40500 0x0 0x20>;
+- };
+-
+- qos_vicap_m0: qos@fdf40600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40600 0x0 0x20>;
+- };
+-
+- qos_vicap_m1: qos@fdf40800 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40800 0x0 0x20>;
+- };
+-
+- qos_isp1_mwo: qos@fdf41000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf41000 0x0 0x20>;
+- };
+-
+- qos_isp1_mro: qos@fdf41100 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf41100 0x0 0x20>;
+- };
+-
+- qos_rkvenc0_m0ro: qos@fdf60000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf60000 0x0 0x20>;
+- };
+-
+- qos_rkvenc0_m1ro: qos@fdf60200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf60200 0x0 0x20>;
+- };
+-
+- qos_rkvenc0_m2wo: qos@fdf60400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf60400 0x0 0x20>;
+- };
+-
+- qos_rkvenc1_m0ro: qos@fdf61000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf61000 0x0 0x20>;
+- };
+-
+- qos_rkvenc1_m1ro: qos@fdf61200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf61200 0x0 0x20>;
+- };
+-
+- qos_rkvenc1_m2wo: qos@fdf61400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf61400 0x0 0x20>;
+- };
+-
+- qos_rkvdec0: qos@fdf62000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf62000 0x0 0x20>;
+- };
+-
+- qos_rkvdec1: qos@fdf63000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf63000 0x0 0x20>;
+- };
+-
+- qos_av1: qos@fdf64000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf64000 0x0 0x20>;
+- };
+-
+- qos_iep: qos@fdf66000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66000 0x0 0x20>;
+- };
+-
+- qos_jpeg_dec: qos@fdf66200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66200 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc0: qos@fdf66400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66400 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc1: qos@fdf66600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66600 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc2: qos@fdf66800 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66800 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc3: qos@fdf66a00 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66a00 0x0 0x20>;
+- };
+-
+- qos_rga2_mro: qos@fdf66c00 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66c00 0x0 0x20>;
+- };
+-
+- qos_rga2_mwo: qos@fdf66e00 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66e00 0x0 0x20>;
+- };
+-
+- qos_rga3_0: qos@fdf67000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf67000 0x0 0x20>;
+- };
+-
+- qos_vdpu: qos@fdf67200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf67200 0x0 0x20>;
+- };
+-
+- qos_npu1: qos@fdf70000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf70000 0x0 0x20>;
+- };
+-
+- qos_npu2: qos@fdf71000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf71000 0x0 0x20>;
+- };
+-
+- qos_npu0_mwr: qos@fdf72000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf72000 0x0 0x20>;
+- };
+-
+- qos_npu0_mro: qos@fdf72200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf72200 0x0 0x20>;
+- };
+-
+- qos_mcu_npu: qos@fdf72400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf72400 0x0 0x20>;
+- };
+-
+- qos_hdcp0: qos@fdf80000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf80000 0x0 0x20>;
+- };
+-
+- qos_hdcp1: qos@fdf81000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf81000 0x0 0x20>;
+- };
+-
+- qos_hdmirx: qos@fdf81200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf81200 0x0 0x20>;
+- };
+-
+- qos_vop_m0: qos@fdf82000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf82000 0x0 0x20>;
+- };
+-
+- qos_vop_m1: qos@fdf82200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf82200 0x0 0x20>;
+- };
+-
+- dfi: dfi@fe060000 {
+- reg = <0x00 0xfe060000 0x00 0x10000>;
+- compatible = "rockchip,rk3588-dfi";
+- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+- rockchip,pmu = <&pmu1grf>;
+- };
+-
+- pcie2x1l1: pcie@fe180000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- bus-range = <0x30 0x3f>;
+- clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>,
+- <&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>,
+- <&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie2x1l1_intc 0>,
+- <0 0 0 2 &pcie2x1l1_intc 1>,
+- <0 0 0 3 &pcie2x1l1_intc 2>,
+- <0 0 0 4 &pcie2x1l1_intc 3>;
+- linux,pci-domain = <3>;
+- max-link-speed = <2>;
+- msi-map = <0x3000 &its0 0x3000 0x1000>;
+- num-lanes = <1>;
+- phys = <&combphy2_psu PHY_TYPE_PCIE>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0xc0000000 0x0 0x40000000>;
+- reg = <0xa 0x40c00000 0x0 0x00400000>,
+- <0x0 0xfe180000 0x0 0x00010000>,
+- <0x0 0xf3000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>;
+- reset-names = "pwr", "pipe";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- status = "disabled";
+-
+- pcie2x1l1_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 245 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- pcie2x1l2: pcie@fe190000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- bus-range = <0x40 0x4f>;
+- clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>,
+- <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>,
+- <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>,
+- <0 0 0 2 &pcie2x1l2_intc 1>,
+- <0 0 0 3 &pcie2x1l2_intc 2>,
+- <0 0 0 4 &pcie2x1l2_intc 3>;
+- linux,pci-domain = <4>;
+- max-link-speed = <2>;
+- msi-map = <0x4000 &its0 0x4000 0x1000>;
+- num-lanes = <1>;
+- phys = <&combphy0_ps PHY_TYPE_PCIE>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0xa 0x00000000 0x0 0x40000000>;
+- reg = <0xa 0x41000000 0x0 0x00400000>,
+- <0x0 0xfe190000 0x0 0x00010000>,
+- <0x0 0xf4000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>;
+- reset-names = "pwr", "pipe";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- status = "disabled";
+-
+- pcie2x1l2_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- gmac1: ethernet@fe1c0000 {
+- compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+- reg = <0x0 0xfe1c0000 0x0 0x10000>;
+- interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "macirq", "eth_wake_irq";
+- clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+- <&cru PCLK_GMAC1>, <&cru ACLK_GMAC1>,
+- <&cru CLK_GMAC1_PTP_REF>;
+- clock-names = "stmmaceth", "clk_mac_ref",
+- "pclk_mac", "aclk_mac",
+- "ptp_ref";
+- power-domains = <&power RK3588_PD_GMAC>;
+- resets = <&cru SRST_A_GMAC1>;
+- reset-names = "stmmaceth";
+- rockchip,grf = <&sys_grf>;
+- rockchip,php-grf = <&php_grf>;
+- snps,axi-config = <&gmac1_stmmac_axi_setup>;
+- snps,mixed-burst;
+- snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
+- snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
+- snps,tso;
+- status = "disabled";
+-
+- mdio1: mdio {
+- compatible = "snps,dwmac-mdio";
+- #address-cells = <0x1>;
+- #size-cells = <0x0>;
+- };
+-
+- gmac1_stmmac_axi_setup: stmmac-axi-config {
+- snps,blen = <0 0 0 0 16 8 4>;
+- snps,wr_osr_lmt = <4>;
+- snps,rd_osr_lmt = <8>;
+- };
+-
+- gmac1_mtl_rx_setup: rx-queues-config {
+- snps,rx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+-
+- gmac1_mtl_tx_setup: tx-queues-config {
+- snps,tx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+- };
+-
+- sata0: sata@fe210000 {
+- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+- reg = <0 0xfe210000 0 0x1000>;
+- interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
+- <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>,
+- <&cru CLK_PIPEPHY0_PIPE_ASIC_G>;
+- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+- ports-implemented = <0x1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+-
+- sata-port@0 {
+- reg = <0>;
+- hba-port-cap = <HBA_PORT_FBSCP>;
+- phys = <&combphy0_ps PHY_TYPE_SATA>;
+- phy-names = "sata-phy";
+- snps,rx-ts-max = <32>;
+- snps,tx-ts-max = <32>;
+- };
+- };
+-
+- sata2: sata@fe230000 {
+- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+- reg = <0 0xfe230000 0 0x1000>;
+- interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_SATA2>, <&cru CLK_PMALIVE2>,
+- <&cru CLK_RXOOB2>, <&cru CLK_PIPEPHY2_REF>,
+- <&cru CLK_PIPEPHY2_PIPE_ASIC_G>;
+- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+- ports-implemented = <0x1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+-
+- sata-port@0 {
+- reg = <0>;
+- hba-port-cap = <HBA_PORT_FBSCP>;
+- phys = <&combphy2_psu PHY_TYPE_SATA>;
+- phy-names = "sata-phy";
+- snps,rx-ts-max = <32>;
+- snps,tx-ts-max = <32>;
+- };
+- };
+-
+- sfc: spi@fe2b0000 {
+- compatible = "rockchip,sfc";
+- reg = <0x0 0xfe2b0000 0x0 0x4000>;
+- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+- clock-names = "clk_sfc", "hclk_sfc";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- sdmmc: mmc@fe2c0000 {
+- compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+- reg = <0x0 0xfe2c0000 0x0 0x4000>;
+- interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>,
+- <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+- clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+- fifo-depth = <0x100>;
+- max-frequency = <200000000>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+- power-domains = <&power RK3588_PD_SDMMC>;
+- status = "disabled";
+- };
+-
+- sdio: mmc@fe2d0000 {
+- compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+- reg = <0x00 0xfe2d0000 0x00 0x4000>;
+- interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_SDIO>, <&cru CCLK_SRC_SDIO>,
+- <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+- clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+- fifo-depth = <0x100>;
+- max-frequency = <200000000>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdiom1_pins>;
+- power-domains = <&power RK3588_PD_SDIO>;
+- status = "disabled";
+- };
+-
+- sdhci: mmc@fe2e0000 {
+- compatible = "rockchip,rk3588-dwcmshc";
+- reg = <0x0 0xfe2e0000 0x0 0x10000>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH 0>;
+- assigned-clocks = <&cru BCLK_EMMC>, <&cru TMCLK_EMMC>, <&cru CCLK_EMMC>;
+- assigned-clock-rates = <200000000>, <24000000>, <200000000>;
+- clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
+- <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
+- <&cru TMCLK_EMMC>;
+- clock-names = "core", "bus", "axi", "block", "timer";
+- max-frequency = <200000000>;
+- pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>,
+- <&emmc_cmd>, <&emmc_data_strobe>;
+- pinctrl-names = "default";
+- resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>,
+- <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>,
+- <&cru SRST_T_EMMC>;
+- reset-names = "core", "bus", "axi", "block", "timer";
+- status = "disabled";
+- };
+-
+- i2s0_8ch: i2s@fe470000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfe470000 0x0 0x1000>;
+- interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>, <&cru PLL_AUPLL>;
+- dmas = <&dmac0 0>, <&dmac0 1>;
+- dma-names = "tx", "rx";
+- power-domains = <&power RK3588_PD_AUDIO>;
+- resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>;
+- reset-names = "tx-m", "rx-m";
+- rockchip,trcm-sync-tx-only;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s0_lrck
+- &i2s0_sclk
+- &i2s0_sdi0
+- &i2s0_sdi1
+- &i2s0_sdi2
+- &i2s0_sdi3
+- &i2s0_sdo0
+- &i2s0_sdo1
+- &i2s0_sdo2
+- &i2s0_sdo3>;
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s1_8ch: i2s@fe480000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfe480000 0x0 0x1000>;
+- interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>, <&cru HCLK_I2S1_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- dmas = <&dmac0 2>, <&dmac0 3>;
+- dma-names = "tx", "rx";
+- resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+- reset-names = "tx-m", "rx-m";
+- rockchip,trcm-sync-tx-only;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s1m0_lrck
+- &i2s1m0_sclk
+- &i2s1m0_sdi0
+- &i2s1m0_sdi1
+- &i2s1m0_sdi2
+- &i2s1m0_sdi3
+- &i2s1m0_sdo0
+- &i2s1m0_sdo1
+- &i2s1m0_sdo2
+- &i2s1m0_sdo3>;
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s2_2ch: i2s@fe490000 {
+- compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
+- reg = <0x0 0xfe490000 0x0 0x1000>;
+- interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
+- clock-names = "i2s_clk", "i2s_hclk";
+- assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac1 0>, <&dmac1 1>;
+- dma-names = "tx", "rx";
+- power-domains = <&power RK3588_PD_AUDIO>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s2m1_lrck
+- &i2s2m1_sclk
+- &i2s2m1_sdi
+- &i2s2m1_sdo>;
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s3_2ch: i2s@fe4a0000 {
+- compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
+- reg = <0x0 0xfe4a0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S3_2CH>, <&cru HCLK_I2S3_2CH>;
+- clock-names = "i2s_clk", "i2s_hclk";
+- assigned-clocks = <&cru CLK_I2S3_2CH_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac1 2>, <&dmac1 3>;
+- dma-names = "tx", "rx";
+- power-domains = <&power RK3588_PD_AUDIO>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s3_lrck
+- &i2s3_sclk
+- &i2s3_sdi
+- &i2s3_sdo>;
+- #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 = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-controller;
+- mbi-alias = <0x0 0xfe610000>;
+- mbi-ranges = <424 56>;
+- msi-controller;
+- ranges;
+- #address-cells = <2>;
+- #interrupt-cells = <4>;
+- #size-cells = <2>;
+-
+- its0: msi-controller@fe640000 {
+- compatible = "arm,gic-v3-its";
+- reg = <0x0 0xfe640000 0x0 0x20000>;
+- msi-controller;
+- #msi-cells = <1>;
+- };
+-
+- its1: msi-controller@fe660000 {
+- compatible = "arm,gic-v3-its";
+- reg = <0x0 0xfe660000 0x0 0x20000>;
+- msi-controller;
+- #msi-cells = <1>;
+- };
+-
+- ppi-partitions {
+- ppi_partition0: interrupt-partition-0 {
+- affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
+- };
+-
+- ppi_partition1: interrupt-partition-1 {
+- affinity = <&cpu_b0 &cpu_b1 &cpu_b2 &cpu_b3>;
+- };
+- };
+- };
+-
+- dmac0: dma-controller@fea10000 {
+- compatible = "arm,pl330", "arm,primecell";
+- reg = <0x0 0xfea10000 0x0 0x4000>;
+- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>;
+- arm,pl330-periph-burst;
+- clocks = <&cru ACLK_DMAC0>;
+- clock-names = "apb_pclk";
+- #dma-cells = <1>;
+- };
+-
+- dmac1: dma-controller@fea30000 {
+- compatible = "arm,pl330", "arm,primecell";
+- reg = <0x0 0xfea30000 0x0 0x4000>;
+- interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>;
+- arm,pl330-periph-burst;
+- clocks = <&cru ACLK_DMAC1>;
+- clock-names = "apb_pclk";
+- #dma-cells = <1>;
+- };
+-
+- i2c1: i2c@fea90000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfea90000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c1m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c2: i2c@feaa0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeaa0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c2m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c3: i2c@feab0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeab0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c3m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c4: i2c@feac0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeac0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c4m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c5: i2c@fead0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfead0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c5m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- timer0: timer@feae0000 {
+- compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer";
+- reg = <0x0 0xfeae0000 0x0 0x20>;
+- interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>;
+- clock-names = "pclk", "timer";
+- };
+-
+- wdt: watchdog@feaf0000 {
+- compatible = "rockchip,rk3588-wdt", "snps,dw-wdt";
+- reg = <0x0 0xfeaf0000 0x0 0x100>;
+- clocks = <&cru TCLK_WDT0>, <&cru PCLK_WDT0>;
+- clock-names = "tclk", "pclk";
+- interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH 0>;
+- };
+-
+- spi0: spi@feb00000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb00000 0x0 0x1000>;
+- interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac0 14>, <&dmac0 15>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi1: spi@feb10000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb10000 0x0 0x1000>;
+- interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac0 16>, <&dmac0 17>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi1m1_cs0 &spi1m1_cs1 &spi1m1_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi2: spi@feb20000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb20000 0x0 0x1000>;
+- interrupts = <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac1 15>, <&dmac1 16>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi2m2_cs0 &spi2m2_cs1 &spi2m2_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi3: spi@feb30000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb30000 0x0 0x1000>;
+- interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac1 17>, <&dmac1 18>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi3m1_cs0 &spi3m1_cs1 &spi3m1_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- uart1: serial@feb40000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb40000 0x0 0x100>;
+- interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 8>, <&dmac0 9>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart1m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart2: serial@feb50000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb50000 0x0 0x100>;
+- interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 10>, <&dmac0 11>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart2m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart3: serial@feb60000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb60000 0x0 0x100>;
+- interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 12>, <&dmac0 13>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart3m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart4: serial@feb70000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb70000 0x0 0x100>;
+- interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac1 9>, <&dmac1 10>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart4m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart5: serial@feb80000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb80000 0x0 0x100>;
+- interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac1 11>, <&dmac1 12>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart5m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart6: serial@feb90000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb90000 0x0 0x100>;
+- interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac1 13>, <&dmac1 14>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart6m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart7: serial@feba0000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeba0000 0x0 0x100>;
+- interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac2 7>, <&dmac2 8>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart7m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart8: serial@febb0000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfebb0000 0x0 0x100>;
+- interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac2 9>, <&dmac2 10>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart8m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart9: serial@febc0000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfebc0000 0x0 0x100>;
+- interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac2 11>, <&dmac2 12>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart9m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- pwm4: pwm@febd0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0000 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm4m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm5: pwm@febd0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0010 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm5m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm6: pwm@febd0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0020 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm6m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm7: pwm@febd0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0030 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm7m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm8: pwm@febe0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0000 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm8m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm9: pwm@febe0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0010 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm9m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm10: pwm@febe0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0020 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm10m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm11: pwm@febe0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0030 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm11m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm12: pwm@febf0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0000 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm12m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm13: pwm@febf0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0010 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm13m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm14: pwm@febf0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0020 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm14m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm15: pwm@febf0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0030 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm15m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- tsadc: tsadc@fec00000 {
+- compatible = "rockchip,rk3588-tsadc";
+- reg = <0x0 0xfec00000 0x0 0x400>;
+- interrupts = <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
+- clock-names = "tsadc", "apb_pclk";
+- assigned-clocks = <&cru CLK_TSADC>;
+- assigned-clock-rates = <2000000>;
+- resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>;
+- reset-names = "tsadc-apb", "tsadc";
+- 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";
+- #thermal-sensor-cells = <1>;
+- status = "disabled";
+- };
+-
+- saradc: adc@fec10000 {
+- compatible = "rockchip,rk3588-saradc";
+- reg = <0x0 0xfec10000 0x0 0x10000>;
+- interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH 0>;
+- #io-channel-cells = <1>;
+- clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
+- clock-names = "saradc", "apb_pclk";
+- resets = <&cru SRST_P_SARADC>;
+- reset-names = "saradc-apb";
+- status = "disabled";
+- };
+-
+- i2c6: i2c@fec80000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfec80000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c6m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c7: i2c@fec90000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfec90000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c7m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c8: i2c@feca0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeca0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C8>, <&cru PCLK_I2C8>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c8m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi4: spi@fecb0000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfecb0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI4>, <&cru PCLK_SPI4>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac2 13>, <&dmac2 14>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi4m0_cs0 &spi4m0_cs1 &spi4m0_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- otp: efuse@fecc0000 {
+- compatible = "rockchip,rk3588-otp";
+- reg = <0x0 0xfecc0000 0x0 0x400>;
+- clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>,
+- <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>;
+- clock-names = "otp", "apb_pclk", "phy", "arb";
+- resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>,
+- <&cru SRST_OTPC_ARB>;
+- reset-names = "otp", "apb", "arb";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- cpu_code: cpu-code@2 {
+- reg = <0x02 0x2>;
+- };
+-
+- otp_id: id@7 {
+- reg = <0x07 0x10>;
+- };
+-
+- cpub0_leakage: cpu-leakage@17 {
+- reg = <0x17 0x1>;
+- };
+-
+- cpub1_leakage: cpu-leakage@18 {
+- reg = <0x18 0x1>;
+- };
+-
+- cpul_leakage: cpu-leakage@19 {
+- reg = <0x19 0x1>;
+- };
+-
+- log_leakage: log-leakage@1a {
+- reg = <0x1a 0x1>;
+- };
+-
+- gpu_leakage: gpu-leakage@1b {
+- reg = <0x1b 0x1>;
+- };
+-
+- otp_cpu_version: cpu-version@1c {
+- reg = <0x1c 0x1>;
+- bits = <3 3>;
+- };
+-
+- npu_leakage: npu-leakage@28 {
+- reg = <0x28 0x1>;
+- };
+-
+- codec_leakage: codec-leakage@29 {
+- reg = <0x29 0x1>;
+- };
+- };
+-
+- dmac2: dma-controller@fed10000 {
+- compatible = "arm,pl330", "arm,primecell";
+- reg = <0x0 0xfed10000 0x0 0x4000>;
+- interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>;
+- arm,pl330-periph-burst;
+- clocks = <&cru ACLK_DMAC2>;
+- clock-names = "apb_pclk";
+- #dma-cells = <1>;
+- };
+-
+- hdptxphy_hdmi0: 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";
+- #phy-cells = <0>;
+- resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+- <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+- <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+- <&cru SRST_HDPTX0_LCPLL>;
+- reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+- "lcpll";
+- rockchip,grf = <&hdptxphy0_grf>;
+- status = "disabled";
+- };
+-
+- usbdp_phy0: phy@fed80000 {
+- compatible = "rockchip,rk3588-usbdp-phy";
+- reg = <0x0 0xfed80000 0x0 0x10000>;
+- #phy-cells = <1>;
+- clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+- <&cru CLK_USBDP_PHY0_IMMORTAL>,
+- <&cru PCLK_USBDPPHY0>,
+- <&u2phy0>;
+- clock-names = "refclk", "immortal", "pclk", "utmi";
+- resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
+- <&cru SRST_USBDP_COMBO_PHY0_CMN>,
+- <&cru SRST_USBDP_COMBO_PHY0_LANE>,
+- <&cru SRST_USBDP_COMBO_PHY0_PCS>,
+- <&cru SRST_P_USBDPPHY0>;
+- reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+- rockchip,u2phy-grf = <&usb2phy0_grf>;
+- rockchip,usb-grf = <&usb_grf>;
+- rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
+- rockchip,vo-grf = <&vo0_grf>;
+- status = "disabled";
+- };
+-
+- combphy0_ps: phy@fee00000 {
+- compatible = "rockchip,rk3588-naneng-combphy";
+- reg = <0x0 0xfee00000 0x0 0x100>;
+- clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>,
+- <&cru PCLK_PHP_ROOT>;
+- clock-names = "ref", "apb", "pipe";
+- assigned-clocks = <&cru CLK_REF_PIPE_PHY0>;
+- assigned-clock-rates = <100000000>;
+- #phy-cells = <1>;
+- resets = <&cru SRST_REF_PIPE_PHY0>, <&cru SRST_P_PCIE2_PHY0>;
+- reset-names = "phy", "apb";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
+- status = "disabled";
+- };
+-
+- combphy2_psu: phy@fee20000 {
+- compatible = "rockchip,rk3588-naneng-combphy";
+- reg = <0x0 0xfee20000 0x0 0x100>;
+- clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
+- <&cru PCLK_PHP_ROOT>;
+- clock-names = "ref", "apb", "pipe";
+- assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
+- assigned-clock-rates = <100000000>;
+- #phy-cells = <1>;
+- resets = <&cru SRST_REF_PIPE_PHY2>, <&cru SRST_P_PCIE2_PHY2>;
+- reset-names = "phy", "apb";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
+- status = "disabled";
+- };
+-
+- system_sram2: sram@ff001000 {
+- compatible = "mmio-sram";
+- reg = <0x0 0xff001000 0x0 0xef000>;
+- ranges = <0x0 0x0 0xff001000 0xef000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+- };
+-
+- pinctrl: pinctrl {
+- compatible = "rockchip,rk3588-pinctrl";
+- ranges;
+- rockchip,grf = <&ioc>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+-
+- gpio0: gpio@fd8a0000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfd8a0000 0x0 0x100>;
+- interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 0 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio1: gpio@fec20000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec20000 0x0 0x100>;
+- interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 32 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio2: gpio@fec30000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec30000 0x0 0x100>;
+- interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 64 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio3: gpio@fec40000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec40000 0x0 0x100>;
+- interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 96 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio4: gpio@fec50000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec50000 0x0 0x100>;
+- interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 128 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+- };
+-};
+-
+-#include "rk3588s-pinctrl.dtsi"
++#include "rk3588-base.dtsi"
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
+@@ -0,0 +1,3447 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include <dt-bindings/pinctrl/rockchip.h>
++#include "rockchip-pinconf.dtsi"
++
++/*
++ * This file is auto generated by pin2dts tool, please keep these code
++ * by adding changes at end of this file.
++ */
++&pinctrl {
++ auddsm {
++ /omit-if-no-ref/
++ auddsm_pins: auddsm-pins {
++ rockchip,pins =
++ /* auddsm_ln */
++ <3 RK_PA1 4 &pcfg_pull_none>,
++ /* auddsm_lp */
++ <3 RK_PA2 4 &pcfg_pull_none>,
++ /* auddsm_rn */
++ <3 RK_PA3 4 &pcfg_pull_none>,
++ /* auddsm_rp */
++ <3 RK_PA4 4 &pcfg_pull_none>;
++ };
++ };
++
++ bt1120 {
++ /omit-if-no-ref/
++ bt1120_pins: bt1120-pins {
++ rockchip,pins =
++ /* bt1120_clkout */
++ <4 RK_PB0 2 &pcfg_pull_none>,
++ /* bt1120_d0 */
++ <4 RK_PA0 2 &pcfg_pull_none>,
++ /* bt1120_d1 */
++ <4 RK_PA1 2 &pcfg_pull_none>,
++ /* bt1120_d2 */
++ <4 RK_PA2 2 &pcfg_pull_none>,
++ /* bt1120_d3 */
++ <4 RK_PA3 2 &pcfg_pull_none>,
++ /* bt1120_d4 */
++ <4 RK_PA4 2 &pcfg_pull_none>,
++ /* bt1120_d5 */
++ <4 RK_PA5 2 &pcfg_pull_none>,
++ /* bt1120_d6 */
++ <4 RK_PA6 2 &pcfg_pull_none>,
++ /* bt1120_d7 */
++ <4 RK_PA7 2 &pcfg_pull_none>,
++ /* bt1120_d8 */
++ <4 RK_PB2 2 &pcfg_pull_none>,
++ /* bt1120_d9 */
++ <4 RK_PB3 2 &pcfg_pull_none>,
++ /* bt1120_d10 */
++ <4 RK_PB4 2 &pcfg_pull_none>,
++ /* bt1120_d11 */
++ <4 RK_PB5 2 &pcfg_pull_none>,
++ /* bt1120_d12 */
++ <4 RK_PB6 2 &pcfg_pull_none>,
++ /* bt1120_d13 */
++ <4 RK_PB7 2 &pcfg_pull_none>,
++ /* bt1120_d14 */
++ <4 RK_PC0 2 &pcfg_pull_none>,
++ /* bt1120_d15 */
++ <4 RK_PC1 2 &pcfg_pull_none>;
++ };
++ };
++
++ can0 {
++ /omit-if-no-ref/
++ can0m0_pins: can0m0-pins {
++ rockchip,pins =
++ /* can0_rx_m0 */
++ <0 RK_PC0 11 &pcfg_pull_none>,
++ /* can0_tx_m0 */
++ <0 RK_PB7 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ can0m1_pins: can0m1-pins {
++ rockchip,pins =
++ /* can0_rx_m1 */
++ <4 RK_PD5 9 &pcfg_pull_none>,
++ /* can0_tx_m1 */
++ <4 RK_PD4 9 &pcfg_pull_none>;
++ };
++ };
++
++ can1 {
++ /omit-if-no-ref/
++ can1m0_pins: can1m0-pins {
++ rockchip,pins =
++ /* can1_rx_m0 */
++ <3 RK_PB5 9 &pcfg_pull_none>,
++ /* can1_tx_m0 */
++ <3 RK_PB6 9 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ can1m1_pins: can1m1-pins {
++ rockchip,pins =
++ /* can1_rx_m1 */
++ <4 RK_PB2 12 &pcfg_pull_none>,
++ /* can1_tx_m1 */
++ <4 RK_PB3 12 &pcfg_pull_none>;
++ };
++ };
++
++ can2 {
++ /omit-if-no-ref/
++ can2m0_pins: can2m0-pins {
++ rockchip,pins =
++ /* can2_rx_m0 */
++ <3 RK_PC4 9 &pcfg_pull_none>,
++ /* can2_tx_m0 */
++ <3 RK_PC5 9 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ can2m1_pins: can2m1-pins {
++ rockchip,pins =
++ /* can2_rx_m1 */
++ <0 RK_PD4 10 &pcfg_pull_none>,
++ /* can2_tx_m1 */
++ <0 RK_PD5 10 &pcfg_pull_none>;
++ };
++ };
++
++ cif {
++ /omit-if-no-ref/
++ cif_clk: cif-clk {
++ rockchip,pins =
++ /* cif_clkout */
++ <4 RK_PB4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ cif_dvp_clk: cif-dvp-clk {
++ rockchip,pins =
++ /* cif_clkin */
++ <4 RK_PB0 1 &pcfg_pull_none>,
++ /* cif_href */
++ <4 RK_PB2 1 &pcfg_pull_none>,
++ /* cif_vsync */
++ <4 RK_PB3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ cif_dvp_bus16: cif-dvp-bus16 {
++ rockchip,pins =
++ /* cif_d8 */
++ <3 RK_PC4 1 &pcfg_pull_none>,
++ /* cif_d9 */
++ <3 RK_PC5 1 &pcfg_pull_none>,
++ /* cif_d10 */
++ <3 RK_PC6 1 &pcfg_pull_none>,
++ /* cif_d11 */
++ <3 RK_PC7 1 &pcfg_pull_none>,
++ /* cif_d12 */
++ <3 RK_PD0 1 &pcfg_pull_none>,
++ /* cif_d13 */
++ <3 RK_PD1 1 &pcfg_pull_none>,
++ /* cif_d14 */
++ <3 RK_PD2 1 &pcfg_pull_none>,
++ /* cif_d15 */
++ <3 RK_PD3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ cif_dvp_bus8: cif-dvp-bus8 {
++ rockchip,pins =
++ /* cif_d0 */
++ <4 RK_PA0 1 &pcfg_pull_none>,
++ /* cif_d1 */
++ <4 RK_PA1 1 &pcfg_pull_none>,
++ /* cif_d2 */
++ <4 RK_PA2 1 &pcfg_pull_none>,
++ /* cif_d3 */
++ <4 RK_PA3 1 &pcfg_pull_none>,
++ /* cif_d4 */
++ <4 RK_PA4 1 &pcfg_pull_none>,
++ /* cif_d5 */
++ <4 RK_PA5 1 &pcfg_pull_none>,
++ /* cif_d6 */
++ <4 RK_PA6 1 &pcfg_pull_none>,
++ /* cif_d7 */
++ <4 RK_PA7 1 &pcfg_pull_none>;
++ };
++ };
++
++ clk32k {
++ /omit-if-no-ref/
++ clk32k_in: clk32k-in {
++ rockchip,pins =
++ /* clk32k_in */
++ <0 RK_PB2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ clk32k_out0: clk32k-out0 {
++ rockchip,pins =
++ /* clk32k_out0 */
++ <0 RK_PB2 2 &pcfg_pull_none>;
++ };
++ };
++
++ cpu {
++ /omit-if-no-ref/
++ cpu_pins: cpu-pins {
++ rockchip,pins =
++ /* cpu_big0_avs */
++ <0 RK_PD1 2 &pcfg_pull_none>,
++ /* cpu_big1_avs */
++ <0 RK_PD5 2 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych0 {
++ /omit-if-no-ref/
++ ddrphych0_pins: ddrphych0-pins {
++ rockchip,pins =
++ /* ddrphych0_dtb0 */
++ <4 RK_PA0 7 &pcfg_pull_none>,
++ /* ddrphych0_dtb1 */
++ <4 RK_PA1 7 &pcfg_pull_none>,
++ /* ddrphych0_dtb2 */
++ <4 RK_PA2 7 &pcfg_pull_none>,
++ /* ddrphych0_dtb3 */
++ <4 RK_PA3 7 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych1 {
++ /omit-if-no-ref/
++ ddrphych1_pins: ddrphych1-pins {
++ rockchip,pins =
++ /* ddrphych1_dtb0 */
++ <4 RK_PA4 7 &pcfg_pull_none>,
++ /* ddrphych1_dtb1 */
++ <4 RK_PA5 7 &pcfg_pull_none>,
++ /* ddrphych1_dtb2 */
++ <4 RK_PA6 7 &pcfg_pull_none>,
++ /* ddrphych1_dtb3 */
++ <4 RK_PA7 7 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych2 {
++ /omit-if-no-ref/
++ ddrphych2_pins: ddrphych2-pins {
++ rockchip,pins =
++ /* ddrphych2_dtb0 */
++ <4 RK_PB0 7 &pcfg_pull_none>,
++ /* ddrphych2_dtb1 */
++ <4 RK_PB1 7 &pcfg_pull_none>,
++ /* ddrphych2_dtb2 */
++ <4 RK_PB2 7 &pcfg_pull_none>,
++ /* ddrphych2_dtb3 */
++ <4 RK_PB3 7 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych3 {
++ /omit-if-no-ref/
++ ddrphych3_pins: ddrphych3-pins {
++ rockchip,pins =
++ /* ddrphych3_dtb0 */
++ <4 RK_PB4 7 &pcfg_pull_none>,
++ /* ddrphych3_dtb1 */
++ <4 RK_PB5 7 &pcfg_pull_none>,
++ /* ddrphych3_dtb2 */
++ <4 RK_PB6 7 &pcfg_pull_none>,
++ /* ddrphych3_dtb3 */
++ <4 RK_PB7 7 &pcfg_pull_none>;
++ };
++ };
++
++ dp0 {
++ /omit-if-no-ref/
++ dp0m0_pins: dp0m0-pins {
++ rockchip,pins =
++ /* dp0_hpdin_m0 */
++ <4 RK_PB4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp0m1_pins: dp0m1-pins {
++ rockchip,pins =
++ /* dp0_hpdin_m1 */
++ <0 RK_PC4 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp0m2_pins: dp0m2-pins {
++ rockchip,pins =
++ /* dp0_hpdin_m2 */
++ <1 RK_PA0 5 &pcfg_pull_none>;
++ };
++ };
++
++ dp1 {
++ /omit-if-no-ref/
++ dp1m0_pins: dp1m0-pins {
++ rockchip,pins =
++ /* dp1_hpdin_m0 */
++ <3 RK_PD5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp1m1_pins: dp1m1-pins {
++ rockchip,pins =
++ /* dp1_hpdin_m1 */
++ <0 RK_PC5 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp1m2_pins: dp1m2-pins {
++ rockchip,pins =
++ /* dp1_hpdin_m2 */
++ <1 RK_PA1 5 &pcfg_pull_none>;
++ };
++ };
++
++ emmc {
++ /omit-if-no-ref/
++ emmc_rstnout: emmc-rstnout {
++ rockchip,pins =
++ /* emmc_rstn */
++ <2 RK_PA3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ emmc_bus8: emmc-bus8 {
++ rockchip,pins =
++ /* emmc_d0 */
++ <2 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d1 */
++ <2 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d2 */
++ <2 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d3 */
++ <2 RK_PD3 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d4 */
++ <2 RK_PD4 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d5 */
++ <2 RK_PD5 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d6 */
++ <2 RK_PD6 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d7 */
++ <2 RK_PD7 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ emmc_clk: emmc-clk {
++ rockchip,pins =
++ /* emmc_clkout */
++ <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ emmc_cmd: emmc-cmd {
++ rockchip,pins =
++ /* emmc_cmd */
++ <2 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ emmc_data_strobe: emmc-data-strobe {
++ rockchip,pins =
++ /* emmc_data_strobe */
++ <2 RK_PA2 1 &pcfg_pull_down>;
++ };
++ };
++
++ eth1 {
++ /omit-if-no-ref/
++ eth1_pins: eth1-pins {
++ rockchip,pins =
++ /* eth1_refclko_25m */
++ <3 RK_PA6 1 &pcfg_pull_none>;
++ };
++ };
++
++ fspi {
++ /omit-if-no-ref/
++ fspim0_pins: fspim0-pins {
++ rockchip,pins =
++ /* fspi_clk_m0 */
++ <2 RK_PA0 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_cs0n_m0 */
++ <2 RK_PD6 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d0_m0 */
++ <2 RK_PD0 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d1_m0 */
++ <2 RK_PD1 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d2_m0 */
++ <2 RK_PD2 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d3_m0 */
++ <2 RK_PD3 2 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim0_cs1: fspim0-cs1 {
++ rockchip,pins =
++ /* fspi_cs1n_m0 */
++ <2 RK_PD7 2 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim2_pins: fspim2-pins {
++ rockchip,pins =
++ /* fspi_clk_m2 */
++ <3 RK_PA5 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_cs0n_m2 */
++ <3 RK_PC4 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d0_m2 */
++ <3 RK_PA0 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d1_m2 */
++ <3 RK_PA1 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d2_m2 */
++ <3 RK_PA2 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d3_m2 */
++ <3 RK_PA3 5 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim2_cs1: fspim2-cs1 {
++ rockchip,pins =
++ /* fspi_cs1n_m2 */
++ <3 RK_PC5 2 &pcfg_pull_up_drv_level_2>;
++ };
++ };
++
++ gmac1 {
++ /omit-if-no-ref/
++ gmac1_miim: gmac1-miim {
++ rockchip,pins =
++ /* gmac1_mdc */
++ <3 RK_PC2 1 &pcfg_pull_none>,
++ /* gmac1_mdio */
++ <3 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_clkinout: gmac1-clkinout {
++ rockchip,pins =
++ /* gmac1_mclkinout */
++ <3 RK_PB6 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_rx_bus2: gmac1-rx-bus2 {
++ rockchip,pins =
++ /* gmac1_rxd0 */
++ <3 RK_PA7 1 &pcfg_pull_none>,
++ /* gmac1_rxd1 */
++ <3 RK_PB0 1 &pcfg_pull_none>,
++ /* gmac1_rxdv_crs */
++ <3 RK_PB1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_tx_bus2: gmac1-tx-bus2 {
++ rockchip,pins =
++ /* gmac1_txd0 */
++ <3 RK_PB3 1 &pcfg_pull_none>,
++ /* gmac1_txd1 */
++ <3 RK_PB4 1 &pcfg_pull_none>,
++ /* gmac1_txen */
++ <3 RK_PB5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_rgmii_clk: gmac1-rgmii-clk {
++ rockchip,pins =
++ /* gmac1_rxclk */
++ <3 RK_PA5 1 &pcfg_pull_none>,
++ /* gmac1_txclk */
++ <3 RK_PA4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_rgmii_bus: gmac1-rgmii-bus {
++ rockchip,pins =
++ /* gmac1_rxd2 */
++ <3 RK_PA2 1 &pcfg_pull_none>,
++ /* gmac1_rxd3 */
++ <3 RK_PA3 1 &pcfg_pull_none>,
++ /* gmac1_txd2 */
++ <3 RK_PA0 1 &pcfg_pull_none>,
++ /* gmac1_txd3 */
++ <3 RK_PA1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_ppsclk: gmac1-ppsclk {
++ rockchip,pins =
++ /* gmac1_ppsclk */
++ <3 RK_PC1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_ppstrig: gmac1-ppstrig {
++ rockchip,pins =
++ /* gmac1_ppstrig */
++ <3 RK_PC0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_ptp_ref_clk: gmac1-ptp-ref-clk {
++ rockchip,pins =
++ /* gmac1_ptp_ref_clk */
++ <3 RK_PB7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_txer: gmac1-txer {
++ rockchip,pins =
++ /* gmac1_txer */
++ <3 RK_PB2 1 &pcfg_pull_none>;
++ };
++ };
++
++ gpu {
++ /omit-if-no-ref/
++ gpu_pins: gpu-pins {
++ rockchip,pins =
++ /* gpu_avs */
++ <0 RK_PC5 2 &pcfg_pull_none>;
++ };
++ };
++
++ hdmi {
++ /omit-if-no-ref/
++ hdmim0_rx_cec: hdmim0-rx-cec {
++ rockchip,pins =
++ /* hdmim0_rx_cec */
++ <4 RK_PB5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_rx_hpdin: hdmim0-rx-hpdin {
++ rockchip,pins =
++ /* hdmim0_rx_hpdin */
++ <4 RK_PB6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_rx_scl: hdmim0-rx-scl {
++ rockchip,pins =
++ /* hdmim0_rx_scl */
++ <0 RK_PD2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_rx_sda: hdmim0-rx-sda {
++ rockchip,pins =
++ /* hdmim0_rx_sda */
++ <0 RK_PD1 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_cec: hdmim0-tx0-cec {
++ rockchip,pins =
++ /* hdmim0_tx0_cec */
++ <4 RK_PC1 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_hpd: hdmim0-tx0-hpd {
++ rockchip,pins =
++ /* hdmim0_tx0_hpd */
++ <1 RK_PA5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_scl: hdmim0-tx0-scl {
++ rockchip,pins =
++ /* hdmim0_tx0_scl */
++ <4 RK_PB7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_sda: hdmim0-tx0-sda {
++ rockchip,pins =
++ /* hdmim0_tx0_sda */
++ <4 RK_PC0 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx1_hpd: hdmim0-tx1-hpd {
++ rockchip,pins =
++ /* hdmim0_tx1_hpd */
++ <1 RK_PA6 5 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ hdmim1_rx_cec: hdmim1-rx-cec {
++ rockchip,pins =
++ /* hdmim1_rx_cec */
++ <3 RK_PD1 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_rx_hpdin: hdmim1-rx-hpdin {
++ rockchip,pins =
++ /* hdmim1_rx_hpdin */
++ <3 RK_PD4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_rx_scl: hdmim1-rx-scl {
++ rockchip,pins =
++ /* hdmim1_rx_scl */
++ <3 RK_PD2 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_rx_sda: hdmim1-rx-sda {
++ rockchip,pins =
++ /* hdmim1_rx_sda */
++ <3 RK_PD3 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_cec: hdmim1-tx0-cec {
++ rockchip,pins =
++ /* hdmim1_tx0_cec */
++ <0 RK_PD1 13 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_hpd: hdmim1-tx0-hpd {
++ rockchip,pins =
++ /* hdmim1_tx0_hpd */
++ <3 RK_PD4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_scl: hdmim1-tx0-scl {
++ rockchip,pins =
++ /* hdmim1_tx0_scl */
++ <0 RK_PD5 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_sda: hdmim1-tx0-sda {
++ rockchip,pins =
++ /* hdmim1_tx0_sda */
++ <0 RK_PD4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_cec: hdmim1-tx1-cec {
++ rockchip,pins =
++ /* hdmim1_tx1_cec */
++ <0 RK_PD2 13 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_hpd: hdmim1-tx1-hpd {
++ rockchip,pins =
++ /* hdmim1_tx1_hpd */
++ <3 RK_PB7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_scl: hdmim1-tx1-scl {
++ rockchip,pins =
++ /* hdmim1_tx1_scl */
++ <3 RK_PC6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_sda: hdmim1-tx1-sda {
++ rockchip,pins =
++ /* hdmim1_tx1_sda */
++ <3 RK_PC5 5 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ hdmim2_rx_cec: hdmim2-rx-cec {
++ rockchip,pins =
++ /* hdmim2_rx_cec */
++ <1 RK_PB7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_rx_hpdin: hdmim2-rx-hpdin {
++ rockchip,pins =
++ /* hdmim2_rx_hpdin */
++ <1 RK_PB6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_rx_scl: hdmim2-rx-scl {
++ rockchip,pins =
++ /* hdmim2_rx_scl */
++ <1 RK_PD6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_rx_sda: hdmim2-rx-sda {
++ rockchip,pins =
++ /* hdmim2_rx_sda */
++ <1 RK_PD7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx0_scl: hdmim2-tx0-scl {
++ rockchip,pins =
++ /* hdmim2_tx0_scl */
++ <3 RK_PC7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx0_sda: hdmim2-tx0-sda {
++ rockchip,pins =
++ /* hdmim2_tx0_sda */
++ <3 RK_PD0 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx1_cec: hdmim2-tx1-cec {
++ rockchip,pins =
++ /* hdmim2_tx1_cec */
++ <3 RK_PC4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx1_scl: hdmim2-tx1-scl {
++ rockchip,pins =
++ /* hdmim2_tx1_scl */
++ <1 RK_PA4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx1_sda: hdmim2-tx1-sda {
++ rockchip,pins =
++ /* hdmim2_tx1_sda */
++ <1 RK_PA3 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug0: hdmi-debug0 {
++ rockchip,pins =
++ /* hdmi_debug0 */
++ <1 RK_PA7 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug1: hdmi-debug1 {
++ rockchip,pins =
++ /* hdmi_debug1 */
++ <1 RK_PB0 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug2: hdmi-debug2 {
++ rockchip,pins =
++ /* hdmi_debug2 */
++ <1 RK_PB1 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug3: hdmi-debug3 {
++ rockchip,pins =
++ /* hdmi_debug3 */
++ <1 RK_PB2 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug4: hdmi-debug4 {
++ rockchip,pins =
++ /* hdmi_debug4 */
++ <1 RK_PB3 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug5: hdmi-debug5 {
++ rockchip,pins =
++ /* hdmi_debug5 */
++ <1 RK_PB4 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug6: hdmi-debug6 {
++ rockchip,pins =
++ /* hdmi_debug6 */
++ <1 RK_PA0 7 &pcfg_pull_none>;
++ };
++ };
++
++ i2c0 {
++ /omit-if-no-ref/
++ i2c0m0_xfer: i2c0m0-xfer {
++ rockchip,pins =
++ /* i2c0_scl_m0 */
++ <0 RK_PB3 2 &pcfg_pull_none_smt>,
++ /* i2c0_sda_m0 */
++ <0 RK_PA6 2 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c0m2_xfer: i2c0m2-xfer {
++ rockchip,pins =
++ /* i2c0_scl_m2 */
++ <0 RK_PD1 3 &pcfg_pull_none_smt>,
++ /* i2c0_sda_m2 */
++ <0 RK_PD2 3 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c1 {
++ /omit-if-no-ref/
++ i2c1m0_xfer: i2c1m0-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m0 */
++ <0 RK_PB5 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m0 */
++ <0 RK_PB6 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m1_xfer: i2c1m1-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m1 */
++ <0 RK_PB0 2 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m1 */
++ <0 RK_PB1 2 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m2_xfer: i2c1m2-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m2 */
++ <0 RK_PD4 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m2 */
++ <0 RK_PD5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m3_xfer: i2c1m3-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m3 */
++ <2 RK_PD4 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m3 */
++ <2 RK_PD5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m4_xfer: i2c1m4-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m4 */
++ <1 RK_PD2 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m4 */
++ <1 RK_PD3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c2 {
++ /omit-if-no-ref/
++ i2c2m0_xfer: i2c2m0-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m0 */
++ <0 RK_PB7 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m0 */
++ <0 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c2m2_xfer: i2c2m2-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m2 */
++ <2 RK_PA3 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m2 */
++ <2 RK_PA2 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c2m3_xfer: i2c2m3-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m3 */
++ <1 RK_PC5 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m3 */
++ <1 RK_PC4 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c2m4_xfer: i2c2m4-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m4 */
++ <1 RK_PA1 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m4 */
++ <1 RK_PA0 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c3 {
++ /omit-if-no-ref/
++ i2c3m0_xfer: i2c3m0-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m0 */
++ <1 RK_PC1 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m0 */
++ <1 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c3m1_xfer: i2c3m1-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m1 */
++ <3 RK_PB7 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m1 */
++ <3 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c3m2_xfer: i2c3m2-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m2 */
++ <4 RK_PA4 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m2 */
++ <4 RK_PA5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c3m4_xfer: i2c3m4-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m4 */
++ <4 RK_PD0 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m4 */
++ <4 RK_PD1 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c4 {
++ /omit-if-no-ref/
++ i2c4m0_xfer: i2c4m0-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m0 */
++ <3 RK_PA6 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m0 */
++ <3 RK_PA5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c4m2_xfer: i2c4m2-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m2 */
++ <0 RK_PC5 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m2 */
++ <0 RK_PC4 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c4m3_xfer: i2c4m3-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m3 */
++ <1 RK_PA3 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m3 */
++ <1 RK_PA2 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c4m4_xfer: i2c4m4-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m4 */
++ <1 RK_PC7 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m4 */
++ <1 RK_PC6 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c5 {
++ /omit-if-no-ref/
++ i2c5m0_xfer: i2c5m0-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m0 */
++ <3 RK_PC7 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m0 */
++ <3 RK_PD0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c5m1_xfer: i2c5m1-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m1 */
++ <4 RK_PB6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m1 */
++ <4 RK_PB7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c5m2_xfer: i2c5m2-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m2 */
++ <4 RK_PA6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m2 */
++ <4 RK_PA7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c5m3_xfer: i2c5m3-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m3 */
++ <1 RK_PB6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m3 */
++ <1 RK_PB7 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c6 {
++ /omit-if-no-ref/
++ i2c6m0_xfer: i2c6m0-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m0 */
++ <0 RK_PD0 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m0 */
++ <0 RK_PC7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c6m1_xfer: i2c6m1-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m1 */
++ <1 RK_PC3 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m1 */
++ <1 RK_PC2 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c6m3_xfer: i2c6m3-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m3 */
++ <4 RK_PB1 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m3 */
++ <4 RK_PB0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c6m4_xfer: i2c6m4-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m4 */
++ <3 RK_PA1 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m4 */
++ <3 RK_PA0 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c7 {
++ /omit-if-no-ref/
++ i2c7m0_xfer: i2c7m0-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m0 */
++ <1 RK_PD0 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m0 */
++ <1 RK_PD1 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c7m2_xfer: i2c7m2-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m2 */
++ <3 RK_PD2 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m2 */
++ <3 RK_PD3 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c7m3_xfer: i2c7m3-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m3 */
++ <4 RK_PB2 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m3 */
++ <4 RK_PB3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c8 {
++ /omit-if-no-ref/
++ i2c8m0_xfer: i2c8m0-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m0 */
++ <4 RK_PD2 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m0 */
++ <4 RK_PD3 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c8m2_xfer: i2c8m2-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m2 */
++ <1 RK_PD6 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m2 */
++ <1 RK_PD7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c8m3_xfer: i2c8m3-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m3 */
++ <4 RK_PC0 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m3 */
++ <4 RK_PC1 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c8m4_xfer: i2c8m4-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m4 */
++ <3 RK_PC2 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m4 */
++ <3 RK_PC3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2s0 {
++ /omit-if-no-ref/
++ i2s0_lrck: i2s0-lrck {
++ rockchip,pins =
++ /* i2s0_lrck */
++ <1 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_mclk: i2s0-mclk {
++ rockchip,pins =
++ /* i2s0_mclk */
++ <1 RK_PC2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sclk: i2s0-sclk {
++ rockchip,pins =
++ /* i2s0_sclk */
++ <1 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi0: i2s0-sdi0 {
++ rockchip,pins =
++ /* i2s0_sdi0 */
++ <1 RK_PD4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi1: i2s0-sdi1 {
++ rockchip,pins =
++ /* i2s0_sdi1 */
++ <1 RK_PD3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi2: i2s0-sdi2 {
++ rockchip,pins =
++ /* i2s0_sdi2 */
++ <1 RK_PD2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi3: i2s0-sdi3 {
++ rockchip,pins =
++ /* i2s0_sdi3 */
++ <1 RK_PD1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo0: i2s0-sdo0 {
++ rockchip,pins =
++ /* i2s0_sdo0 */
++ <1 RK_PC7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo1: i2s0-sdo1 {
++ rockchip,pins =
++ /* i2s0_sdo1 */
++ <1 RK_PD0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo2: i2s0-sdo2 {
++ rockchip,pins =
++ /* i2s0_sdo2 */
++ <1 RK_PD1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo3: i2s0-sdo3 {
++ rockchip,pins =
++ /* i2s0_sdo3 */
++ <1 RK_PD2 1 &pcfg_pull_none>;
++ };
++ };
++
++ i2s1 {
++ /omit-if-no-ref/
++ i2s1m0_lrck: i2s1m0-lrck {
++ rockchip,pins =
++ /* i2s1m0_lrck */
++ <4 RK_PA2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_mclk: i2s1m0-mclk {
++ rockchip,pins =
++ /* i2s1m0_mclk */
++ <4 RK_PA0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sclk: i2s1m0-sclk {
++ rockchip,pins =
++ /* i2s1m0_sclk */
++ <4 RK_PA1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi0: i2s1m0-sdi0 {
++ rockchip,pins =
++ /* i2s1m0_sdi0 */
++ <4 RK_PA5 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi1: i2s1m0-sdi1 {
++ rockchip,pins =
++ /* i2s1m0_sdi1 */
++ <4 RK_PA6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi2: i2s1m0-sdi2 {
++ rockchip,pins =
++ /* i2s1m0_sdi2 */
++ <4 RK_PA7 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi3: i2s1m0-sdi3 {
++ rockchip,pins =
++ /* i2s1m0_sdi3 */
++ <4 RK_PB0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo0: i2s1m0-sdo0 {
++ rockchip,pins =
++ /* i2s1m0_sdo0 */
++ <4 RK_PB1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo1: i2s1m0-sdo1 {
++ rockchip,pins =
++ /* i2s1m0_sdo1 */
++ <4 RK_PB2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo2: i2s1m0-sdo2 {
++ rockchip,pins =
++ /* i2s1m0_sdo2 */
++ <4 RK_PB3 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo3: i2s1m0-sdo3 {
++ rockchip,pins =
++ /* i2s1m0_sdo3 */
++ <4 RK_PB4 3 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ i2s1m1_lrck: i2s1m1-lrck {
++ rockchip,pins =
++ /* i2s1m1_lrck */
++ <0 RK_PB7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_mclk: i2s1m1-mclk {
++ rockchip,pins =
++ /* i2s1m1_mclk */
++ <0 RK_PB5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sclk: i2s1m1-sclk {
++ rockchip,pins =
++ /* i2s1m1_sclk */
++ <0 RK_PB6 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi0: i2s1m1-sdi0 {
++ rockchip,pins =
++ /* i2s1m1_sdi0 */
++ <0 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi1: i2s1m1-sdi1 {
++ rockchip,pins =
++ /* i2s1m1_sdi1 */
++ <0 RK_PC6 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi2: i2s1m1-sdi2 {
++ rockchip,pins =
++ /* i2s1m1_sdi2 */
++ <0 RK_PC7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi3: i2s1m1-sdi3 {
++ rockchip,pins =
++ /* i2s1m1_sdi3 */
++ <0 RK_PD0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo0: i2s1m1-sdo0 {
++ rockchip,pins =
++ /* i2s1m1_sdo0 */
++ <0 RK_PD1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo1: i2s1m1-sdo1 {
++ rockchip,pins =
++ /* i2s1m1_sdo1 */
++ <0 RK_PD2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo2: i2s1m1-sdo2 {
++ rockchip,pins =
++ /* i2s1m1_sdo2 */
++ <0 RK_PD4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo3: i2s1m1-sdo3 {
++ rockchip,pins =
++ /* i2s1m1_sdo3 */
++ <0 RK_PD5 1 &pcfg_pull_none>;
++ };
++ };
++
++ i2s2 {
++ /omit-if-no-ref/
++ i2s2m0_lrck: i2s2m0-lrck {
++ rockchip,pins =
++ /* i2s2m0_lrck */
++ <2 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_mclk: i2s2m0-mclk {
++ rockchip,pins =
++ /* i2s2m0_mclk */
++ <2 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sclk: i2s2m0-sclk {
++ rockchip,pins =
++ /* i2s2m0_sclk */
++ <2 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdi: i2s2m0-sdi {
++ rockchip,pins =
++ /* i2s2m0_sdi */
++ <2 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdo: i2s2m0-sdo {
++ rockchip,pins =
++ /* i2s2m0_sdo */
++ <4 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_lrck: i2s2m1-lrck {
++ rockchip,pins =
++ /* i2s2m1_lrck */
++ <3 RK_PB6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_mclk: i2s2m1-mclk {
++ rockchip,pins =
++ /* i2s2m1_mclk */
++ <3 RK_PB4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_sclk: i2s2m1-sclk {
++ rockchip,pins =
++ /* i2s2m1_sclk */
++ <3 RK_PB5 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_sdi: i2s2m1-sdi {
++ rockchip,pins =
++ /* i2s2m1_sdi */
++ <3 RK_PB2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_sdo: i2s2m1-sdo {
++ rockchip,pins =
++ /* i2s2m1_sdo */
++ <3 RK_PB3 3 &pcfg_pull_none>;
++ };
++ };
++
++ i2s3 {
++ /omit-if-no-ref/
++ i2s3_lrck: i2s3-lrck {
++ rockchip,pins =
++ /* i2s3_lrck */
++ <3 RK_PA2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_mclk: i2s3-mclk {
++ rockchip,pins =
++ /* i2s3_mclk */
++ <3 RK_PA0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_sclk: i2s3-sclk {
++ rockchip,pins =
++ /* i2s3_sclk */
++ <3 RK_PA1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_sdi: i2s3-sdi {
++ rockchip,pins =
++ /* i2s3_sdi */
++ <3 RK_PA4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_sdo: i2s3-sdo {
++ rockchip,pins =
++ /* i2s3_sdo */
++ <3 RK_PA3 3 &pcfg_pull_none>;
++ };
++ };
++
++ jtag {
++ /omit-if-no-ref/
++ jtagm0_pins: jtagm0-pins {
++ rockchip,pins =
++ /* jtag_tck_m0 */
++ <4 RK_PD2 5 &pcfg_pull_none>,
++ /* jtag_tms_m0 */
++ <4 RK_PD3 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ jtagm1_pins: jtagm1-pins {
++ rockchip,pins =
++ /* jtag_tck_m1 */
++ <4 RK_PD0 5 &pcfg_pull_none>,
++ /* jtag_tms_m1 */
++ <4 RK_PD1 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ jtagm2_pins: jtagm2-pins {
++ rockchip,pins =
++ /* jtag_tck_m2 */
++ <0 RK_PB5 2 &pcfg_pull_none>,
++ /* jtag_tms_m2 */
++ <0 RK_PB6 2 &pcfg_pull_none>;
++ };
++ };
++
++ litcpu {
++ /omit-if-no-ref/
++ litcpu_pins: litcpu-pins {
++ rockchip,pins =
++ /* litcpu_avs */
++ <0 RK_PD3 1 &pcfg_pull_none>;
++ };
++ };
++
++ mcu {
++ /omit-if-no-ref/
++ mcum0_pins: mcum0-pins {
++ rockchip,pins =
++ /* mcu_jtag_tck_m0 */
++ <4 RK_PD4 5 &pcfg_pull_none>,
++ /* mcu_jtag_tms_m0 */
++ <4 RK_PD5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mcum1_pins: mcum1-pins {
++ rockchip,pins =
++ /* mcu_jtag_tck_m1 */
++ <3 RK_PD4 6 &pcfg_pull_none>,
++ /* mcu_jtag_tms_m1 */
++ <3 RK_PD5 6 &pcfg_pull_none>;
++ };
++ };
++
++ mipi {
++ /omit-if-no-ref/
++ mipim0_camera0_clk: mipim0-camera0-clk {
++ rockchip,pins =
++ /* mipim0_camera0_clk */
++ <4 RK_PB1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera1_clk: mipim0-camera1-clk {
++ rockchip,pins =
++ /* mipim0_camera1_clk */
++ <1 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera2_clk: mipim0-camera2-clk {
++ rockchip,pins =
++ /* mipim0_camera2_clk */
++ <1 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera3_clk: mipim0-camera3-clk {
++ rockchip,pins =
++ /* mipim0_camera3_clk */
++ <1 RK_PD6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera4_clk: mipim0-camera4-clk {
++ rockchip,pins =
++ /* mipim0_camera4_clk */
++ <1 RK_PD7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera0_clk: mipim1-camera0-clk {
++ rockchip,pins =
++ /* mipim1_camera0_clk */
++ <3 RK_PA5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera1_clk: mipim1-camera1-clk {
++ rockchip,pins =
++ /* mipim1_camera1_clk */
++ <3 RK_PA6 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera2_clk: mipim1-camera2-clk {
++ rockchip,pins =
++ /* mipim1_camera2_clk */
++ <3 RK_PA7 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera3_clk: mipim1-camera3-clk {
++ rockchip,pins =
++ /* mipim1_camera3_clk */
++ <3 RK_PB0 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera4_clk: mipim1-camera4-clk {
++ rockchip,pins =
++ /* mipim1_camera4_clk */
++ <3 RK_PB1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipi_te0: mipi-te0 {
++ rockchip,pins =
++ /* mipi_te0 */
++ <3 RK_PC2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipi_te1: mipi-te1 {
++ rockchip,pins =
++ /* mipi_te1 */
++ <3 RK_PC3 2 &pcfg_pull_none>;
++ };
++ };
++
++ npu {
++ /omit-if-no-ref/
++ npu_pins: npu-pins {
++ rockchip,pins =
++ /* npu_avs */
++ <0 RK_PC6 2 &pcfg_pull_none>;
++ };
++ };
++
++ pcie20x1 {
++ /omit-if-no-ref/
++ pcie20x1m0_pins: pcie20x1m0-pins {
++ rockchip,pins =
++ /* pcie20x1_2_clkreqn_m0 */
++ <3 RK_PC7 4 &pcfg_pull_none>,
++ /* pcie20x1_2_perstn_m0 */
++ <3 RK_PD1 4 &pcfg_pull_none>,
++ /* pcie20x1_2_waken_m0 */
++ <3 RK_PD0 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie20x1m1_pins: pcie20x1m1-pins {
++ rockchip,pins =
++ /* pcie20x1_2_clkreqn_m1 */
++ <4 RK_PB7 4 &pcfg_pull_none>,
++ /* pcie20x1_2_perstn_m1 */
++ <4 RK_PC1 4 &pcfg_pull_none>,
++ /* pcie20x1_2_waken_m1 */
++ <4 RK_PC0 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie20x1_2_button_rstn: pcie20x1-2-button-rstn {
++ rockchip,pins =
++ /* pcie20x1_2_button_rstn */
++ <4 RK_PB3 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30phy {
++ /omit-if-no-ref/
++ pcie30phy_pins: pcie30phy-pins {
++ rockchip,pins =
++ /* pcie30phy_dtb0 */
++ <1 RK_PC4 4 &pcfg_pull_none>,
++ /* pcie30phy_dtb1 */
++ <1 RK_PD1 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x1 {
++ /omit-if-no-ref/
++ pcie30x1m0_pins: pcie30x1m0-pins {
++ rockchip,pins =
++ /* pcie30x1_0_clkreqn_m0 */
++ <0 RK_PC0 12 &pcfg_pull_none>,
++ /* pcie30x1_0_perstn_m0 */
++ <0 RK_PC5 12 &pcfg_pull_none>,
++ /* pcie30x1_0_waken_m0 */
++ <0 RK_PC4 12 &pcfg_pull_none>,
++ /* pcie30x1_1_clkreqn_m0 */
++ <0 RK_PB5 12 &pcfg_pull_none>,
++ /* pcie30x1_1_perstn_m0 */
++ <0 RK_PB7 12 &pcfg_pull_none>,
++ /* pcie30x1_1_waken_m0 */
++ <0 RK_PB6 12 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1m1_pins: pcie30x1m1-pins {
++ rockchip,pins =
++ /* pcie30x1_0_clkreqn_m1 */
++ <4 RK_PA3 4 &pcfg_pull_none>,
++ /* pcie30x1_0_perstn_m1 */
++ <4 RK_PA5 4 &pcfg_pull_none>,
++ /* pcie30x1_0_waken_m1 */
++ <4 RK_PA4 4 &pcfg_pull_none>,
++ /* pcie30x1_1_clkreqn_m1 */
++ <4 RK_PA0 4 &pcfg_pull_none>,
++ /* pcie30x1_1_perstn_m1 */
++ <4 RK_PA2 4 &pcfg_pull_none>,
++ /* pcie30x1_1_waken_m1 */
++ <4 RK_PA1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1m2_pins: pcie30x1m2-pins {
++ rockchip,pins =
++ /* pcie30x1_0_clkreqn_m2 */
++ <1 RK_PB5 4 &pcfg_pull_none>,
++ /* pcie30x1_0_perstn_m2 */
++ <1 RK_PB4 4 &pcfg_pull_none>,
++ /* pcie30x1_0_waken_m2 */
++ <1 RK_PB3 4 &pcfg_pull_none>,
++ /* pcie30x1_1_clkreqn_m2 */
++ <1 RK_PA0 4 &pcfg_pull_none>,
++ /* pcie30x1_1_perstn_m2 */
++ <1 RK_PA7 4 &pcfg_pull_none>,
++ /* pcie30x1_1_waken_m2 */
++ <1 RK_PA1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1_0_button_rstn: pcie30x1-0-button-rstn {
++ rockchip,pins =
++ /* pcie30x1_0_button_rstn */
++ <4 RK_PB1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1_1_button_rstn: pcie30x1-1-button-rstn {
++ rockchip,pins =
++ /* pcie30x1_1_button_rstn */
++ <4 RK_PB2 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x2 {
++ /omit-if-no-ref/
++ pcie30x2m0_pins: pcie30x2m0-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m0 */
++ <0 RK_PD1 12 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m0 */
++ <0 RK_PD4 12 &pcfg_pull_none>,
++ /* pcie30x2_waken_m0 */
++ <0 RK_PD2 12 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2m1_pins: pcie30x2m1-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m1 */
++ <4 RK_PA6 4 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m1 */
++ <4 RK_PB0 4 &pcfg_pull_none>,
++ /* pcie30x2_waken_m1 */
++ <4 RK_PA7 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2m2_pins: pcie30x2m2-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m2 */
++ <3 RK_PD2 4 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m2 */
++ <3 RK_PD4 4 &pcfg_pull_none>,
++ /* pcie30x2_waken_m2 */
++ <3 RK_PD3 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2m3_pins: pcie30x2m3-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m3 */
++ <1 RK_PD7 4 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m3 */
++ <1 RK_PB7 4 &pcfg_pull_none>,
++ /* pcie30x2_waken_m3 */
++ <1 RK_PB6 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2_button_rstn: pcie30x2-button-rstn {
++ rockchip,pins =
++ /* pcie30x2_button_rstn */
++ <3 RK_PC1 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x4 {
++ /omit-if-no-ref/
++ pcie30x4m0_pins: pcie30x4m0-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m0 */
++ <0 RK_PC6 12 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m0 */
++ <0 RK_PD0 12 &pcfg_pull_none>,
++ /* pcie30x4_waken_m0 */
++ <0 RK_PC7 12 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4m1_pins: pcie30x4m1-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m1 */
++ <4 RK_PB4 4 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m1 */
++ <4 RK_PB6 4 &pcfg_pull_none>,
++ /* pcie30x4_waken_m1 */
++ <4 RK_PB5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4m2_pins: pcie30x4m2-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m2 */
++ <3 RK_PC4 4 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m2 */
++ <3 RK_PC6 4 &pcfg_pull_none>,
++ /* pcie30x4_waken_m2 */
++ <3 RK_PC5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4m3_pins: pcie30x4m3-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m3 */
++ <1 RK_PB0 4 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m3 */
++ <1 RK_PB2 4 &pcfg_pull_none>,
++ /* pcie30x4_waken_m3 */
++ <1 RK_PB1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4_button_rstn: pcie30x4-button-rstn {
++ rockchip,pins =
++ /* pcie30x4_button_rstn */
++ <3 RK_PD5 4 &pcfg_pull_none>;
++ };
++ };
++
++ pdm0 {
++ /omit-if-no-ref/
++ pdm0m0_clk: pdm0m0-clk {
++ rockchip,pins =
++ /* pdm0_clk0_m0 */
++ <1 RK_PC6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_clk1: pdm0m0-clk1 {
++ rockchip,pins =
++ /* pdm0m0_clk1 */
++ <1 RK_PC4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi0: pdm0m0-sdi0 {
++ rockchip,pins =
++ /* pdm0m0_sdi0 */
++ <1 RK_PD5 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi1: pdm0m0-sdi1 {
++ rockchip,pins =
++ /* pdm0m0_sdi1 */
++ <1 RK_PD1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi2: pdm0m0-sdi2 {
++ rockchip,pins =
++ /* pdm0m0_sdi2 */
++ <1 RK_PD2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi3: pdm0m0-sdi3 {
++ rockchip,pins =
++ /* pdm0m0_sdi3 */
++ <1 RK_PD3 3 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ pdm0m1_clk: pdm0m1-clk {
++ rockchip,pins =
++ /* pdm0_clk0_m1 */
++ <0 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_clk1: pdm0m1-clk1 {
++ rockchip,pins =
++ /* pdm0m1_clk1 */
++ <0 RK_PC4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi0: pdm0m1-sdi0 {
++ rockchip,pins =
++ /* pdm0m1_sdi0 */
++ <0 RK_PC7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi1: pdm0m1-sdi1 {
++ rockchip,pins =
++ /* pdm0m1_sdi1 */
++ <0 RK_PD0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi2: pdm0m1-sdi2 {
++ rockchip,pins =
++ /* pdm0m1_sdi2 */
++ <0 RK_PD4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi3: pdm0m1-sdi3 {
++ rockchip,pins =
++ /* pdm0m1_sdi3 */
++ <0 RK_PD6 2 &pcfg_pull_none>;
++ };
++ };
++
++ pdm1 {
++ /omit-if-no-ref/
++ pdm1m0_clk: pdm1m0-clk {
++ rockchip,pins =
++ /* pdm1_clk0_m0 */
++ <4 RK_PD5 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_clk1: pdm1m0-clk1 {
++ rockchip,pins =
++ /* pdm1m0_clk1 */
++ <4 RK_PD4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi0: pdm1m0-sdi0 {
++ rockchip,pins =
++ /* pdm1m0_sdi0 */
++ <4 RK_PD3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi1: pdm1m0-sdi1 {
++ rockchip,pins =
++ /* pdm1m0_sdi1 */
++ <4 RK_PD2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi2: pdm1m0-sdi2 {
++ rockchip,pins =
++ /* pdm1m0_sdi2 */
++ <4 RK_PD1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi3: pdm1m0-sdi3 {
++ rockchip,pins =
++ /* pdm1m0_sdi3 */
++ <4 RK_PD0 2 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ pdm1m1_clk: pdm1m1-clk {
++ rockchip,pins =
++ /* pdm1_clk0_m1 */
++ <1 RK_PB4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_clk1: pdm1m1-clk1 {
++ rockchip,pins =
++ /* pdm1m1_clk1 */
++ <1 RK_PB3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi0: pdm1m1-sdi0 {
++ rockchip,pins =
++ /* pdm1m1_sdi0 */
++ <1 RK_PA7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi1: pdm1m1-sdi1 {
++ rockchip,pins =
++ /* pdm1m1_sdi1 */
++ <1 RK_PB0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi2: pdm1m1-sdi2 {
++ rockchip,pins =
++ /* pdm1m1_sdi2 */
++ <1 RK_PB1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi3: pdm1m1-sdi3 {
++ rockchip,pins =
++ /* pdm1m1_sdi3 */
++ <1 RK_PB2 2 &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ /omit-if-no-ref/
++ pmic_pins: pmic-pins {
++ rockchip,pins =
++ /* pmic_int_l */
++ <0 RK_PA7 0 &pcfg_pull_up>,
++ /* pmic_sleep1 */
++ <0 RK_PA2 1 &pcfg_pull_none>,
++ /* pmic_sleep2 */
++ <0 RK_PA3 1 &pcfg_pull_none>,
++ /* pmic_sleep3 */
++ <0 RK_PC1 1 &pcfg_pull_none>,
++ /* pmic_sleep4 */
++ <0 RK_PC2 1 &pcfg_pull_none>,
++ /* pmic_sleep5 */
++ <0 RK_PC3 1 &pcfg_pull_none>,
++ /* pmic_sleep6 */
++ <0 RK_PD6 1 &pcfg_pull_none>;
++ };
++ };
++
++ pmu {
++ /omit-if-no-ref/
++ pmu_pins: pmu-pins {
++ rockchip,pins =
++ /* pmu_debug */
++ <0 RK_PA5 3 &pcfg_pull_none>;
++ };
++ };
++
++ pwm0 {
++ /omit-if-no-ref/
++ pwm0m0_pins: pwm0m0-pins {
++ rockchip,pins =
++ /* pwm0_m0 */
++ <0 RK_PB7 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm0m1_pins: pwm0m1-pins {
++ rockchip,pins =
++ /* pwm0_m1 */
++ <1 RK_PD2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm0m2_pins: pwm0m2-pins {
++ rockchip,pins =
++ /* pwm0_m2 */
++ <1 RK_PA2 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm1 {
++ /omit-if-no-ref/
++ pwm1m0_pins: pwm1m0-pins {
++ rockchip,pins =
++ /* pwm1_m0 */
++ <0 RK_PC0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm1m1_pins: pwm1m1-pins {
++ rockchip,pins =
++ /* pwm1_m1 */
++ <1 RK_PD3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm1m2_pins: pwm1m2-pins {
++ rockchip,pins =
++ /* pwm1_m2 */
++ <1 RK_PA3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm2 {
++ /omit-if-no-ref/
++ pwm2m0_pins: pwm2m0-pins {
++ rockchip,pins =
++ /* pwm2_m0 */
++ <0 RK_PC4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm2m1_pins: pwm2m1-pins {
++ rockchip,pins =
++ /* pwm2_m1 */
++ <3 RK_PB1 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm3 {
++ /omit-if-no-ref/
++ pwm3m0_pins: pwm3m0-pins {
++ rockchip,pins =
++ /* pwm3_ir_m0 */
++ <0 RK_PD4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm3m1_pins: pwm3m1-pins {
++ rockchip,pins =
++ /* pwm3_ir_m1 */
++ <3 RK_PB2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm3m2_pins: pwm3m2-pins {
++ rockchip,pins =
++ /* pwm3_ir_m2 */
++ <1 RK_PC2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm3m3_pins: pwm3m3-pins {
++ rockchip,pins =
++ /* pwm3_ir_m3 */
++ <1 RK_PA7 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm4 {
++ /omit-if-no-ref/
++ pwm4m0_pins: pwm4m0-pins {
++ rockchip,pins =
++ /* pwm4_m0 */
++ <0 RK_PC5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm5 {
++ /omit-if-no-ref/
++ pwm5m0_pins: pwm5m0-pins {
++ rockchip,pins =
++ /* pwm5_m0 */
++ <0 RK_PB1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm5m1_pins: pwm5m1-pins {
++ rockchip,pins =
++ /* pwm5_m1 */
++ <0 RK_PC6 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm6 {
++ /omit-if-no-ref/
++ pwm6m0_pins: pwm6m0-pins {
++ rockchip,pins =
++ /* pwm6_m0 */
++ <0 RK_PC7 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm6m1_pins: pwm6m1-pins {
++ rockchip,pins =
++ /* pwm6_m1 */
++ <4 RK_PC1 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm7 {
++ /omit-if-no-ref/
++ pwm7m0_pins: pwm7m0-pins {
++ rockchip,pins =
++ /* pwm7_ir_m0 */
++ <0 RK_PD0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm7m1_pins: pwm7m1-pins {
++ rockchip,pins =
++ /* pwm7_ir_m1 */
++ <4 RK_PD4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm7m2_pins: pwm7m2-pins {
++ rockchip,pins =
++ /* pwm7_ir_m2 */
++ <1 RK_PC3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm8 {
++ /omit-if-no-ref/
++ pwm8m0_pins: pwm8m0-pins {
++ rockchip,pins =
++ /* pwm8_m0 */
++ <3 RK_PA7 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm8m1_pins: pwm8m1-pins {
++ rockchip,pins =
++ /* pwm8_m1 */
++ <4 RK_PD0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm8m2_pins: pwm8m2-pins {
++ rockchip,pins =
++ /* pwm8_m2 */
++ <3 RK_PD0 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm9 {
++ /omit-if-no-ref/
++ pwm9m0_pins: pwm9m0-pins {
++ rockchip,pins =
++ /* pwm9_m0 */
++ <3 RK_PB0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm9m1_pins: pwm9m1-pins {
++ rockchip,pins =
++ /* pwm9_m1 */
++ <4 RK_PD1 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm9m2_pins: pwm9m2-pins {
++ rockchip,pins =
++ /* pwm9_m2 */
++ <3 RK_PD1 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm10 {
++ /omit-if-no-ref/
++ pwm10m0_pins: pwm10m0-pins {
++ rockchip,pins =
++ /* pwm10_m0 */
++ <3 RK_PA0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm10m1_pins: pwm10m1-pins {
++ rockchip,pins =
++ /* pwm10_m1 */
++ <4 RK_PD3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm10m2_pins: pwm10m2-pins {
++ rockchip,pins =
++ /* pwm10_m2 */
++ <3 RK_PD3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm11 {
++ /omit-if-no-ref/
++ pwm11m0_pins: pwm11m0-pins {
++ rockchip,pins =
++ /* pwm11_ir_m0 */
++ <3 RK_PA1 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm11m1_pins: pwm11m1-pins {
++ rockchip,pins =
++ /* pwm11_ir_m1 */
++ <4 RK_PB4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm11m2_pins: pwm11m2-pins {
++ rockchip,pins =
++ /* pwm11_ir_m2 */
++ <1 RK_PC4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm11m3_pins: pwm11m3-pins {
++ rockchip,pins =
++ /* pwm11_ir_m3 */
++ <3 RK_PD5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm12 {
++ /omit-if-no-ref/
++ pwm12m0_pins: pwm12m0-pins {
++ rockchip,pins =
++ /* pwm12_m0 */
++ <3 RK_PB5 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm12m1_pins: pwm12m1-pins {
++ rockchip,pins =
++ /* pwm12_m1 */
++ <4 RK_PB5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm13 {
++ /omit-if-no-ref/
++ pwm13m0_pins: pwm13m0-pins {
++ rockchip,pins =
++ /* pwm13_m0 */
++ <3 RK_PB6 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm13m1_pins: pwm13m1-pins {
++ rockchip,pins =
++ /* pwm13_m1 */
++ <4 RK_PB6 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm13m2_pins: pwm13m2-pins {
++ rockchip,pins =
++ /* pwm13_m2 */
++ <1 RK_PB7 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm14 {
++ /omit-if-no-ref/
++ pwm14m0_pins: pwm14m0-pins {
++ rockchip,pins =
++ /* pwm14_m0 */
++ <3 RK_PC2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm14m1_pins: pwm14m1-pins {
++ rockchip,pins =
++ /* pwm14_m1 */
++ <4 RK_PB2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm14m2_pins: pwm14m2-pins {
++ rockchip,pins =
++ /* pwm14_m2 */
++ <1 RK_PD6 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm15 {
++ /omit-if-no-ref/
++ pwm15m0_pins: pwm15m0-pins {
++ rockchip,pins =
++ /* pwm15_ir_m0 */
++ <3 RK_PC3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm15m1_pins: pwm15m1-pins {
++ rockchip,pins =
++ /* pwm15_ir_m1 */
++ <4 RK_PB3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm15m2_pins: pwm15m2-pins {
++ rockchip,pins =
++ /* pwm15_ir_m2 */
++ <1 RK_PC6 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm15m3_pins: pwm15m3-pins {
++ rockchip,pins =
++ /* pwm15_ir_m3 */
++ <1 RK_PD7 11 &pcfg_pull_none>;
++ };
++ };
++
++ refclk {
++ /omit-if-no-ref/
++ refclk_pins: refclk-pins {
++ rockchip,pins =
++ /* refclk_out */
++ <0 RK_PA0 1 &pcfg_pull_none>;
++ };
++ };
++
++ sata {
++ /omit-if-no-ref/
++ sata_pins: sata-pins {
++ rockchip,pins =
++ /* sata_cp_pod */
++ <0 RK_PC6 13 &pcfg_pull_none>,
++ /* sata_cpdet */
++ <0 RK_PD4 13 &pcfg_pull_none>,
++ /* sata_mp_switch */
++ <0 RK_PD5 13 &pcfg_pull_none>;
++ };
++ };
++
++ sata0 {
++ /omit-if-no-ref/
++ sata0m0_pins: sata0m0-pins {
++ rockchip,pins =
++ /* sata0_act_led_m0 */
++ <4 RK_PB6 6 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ sata0m1_pins: sata0m1-pins {
++ rockchip,pins =
++ /* sata0_act_led_m1 */
++ <1 RK_PB3 6 &pcfg_pull_none>;
++ };
++ };
++
++ sata1 {
++ /omit-if-no-ref/
++ sata1m0_pins: sata1m0-pins {
++ rockchip,pins =
++ /* sata1_act_led_m0 */
++ <4 RK_PB5 6 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ sata1m1_pins: sata1m1-pins {
++ rockchip,pins =
++ /* sata1_act_led_m1 */
++ <1 RK_PA1 6 &pcfg_pull_none>;
++ };
++ };
++
++ sata2 {
++ /omit-if-no-ref/
++ sata2m0_pins: sata2m0-pins {
++ rockchip,pins =
++ /* sata2_act_led_m0 */
++ <4 RK_PB1 6 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ sata2m1_pins: sata2m1-pins {
++ rockchip,pins =
++ /* sata2_act_led_m1 */
++ <1 RK_PB7 6 &pcfg_pull_none>;
++ };
++ };
++
++ sdio {
++ /omit-if-no-ref/
++ sdiom1_pins: sdiom1-pins {
++ rockchip,pins =
++ /* sdio_clk_m1 */
++ <3 RK_PA5 2 &pcfg_pull_none>,
++ /* sdio_cmd_m1 */
++ <3 RK_PA4 2 &pcfg_pull_none>,
++ /* sdio_d0_m1 */
++ <3 RK_PA0 2 &pcfg_pull_none>,
++ /* sdio_d1_m1 */
++ <3 RK_PA1 2 &pcfg_pull_none>,
++ /* sdio_d2_m1 */
++ <3 RK_PA2 2 &pcfg_pull_none>,
++ /* sdio_d3_m1 */
++ <3 RK_PA3 2 &pcfg_pull_none>;
++ };
++ };
++
++ sdmmc {
++ /omit-if-no-ref/
++ sdmmc_bus4: sdmmc-bus4 {
++ rockchip,pins =
++ /* sdmmc_d0 */
++ <4 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
++ /* sdmmc_d1 */
++ <4 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
++ /* sdmmc_d2 */
++ <4 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
++ /* sdmmc_d3 */
++ <4 RK_PD3 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_clk: sdmmc-clk {
++ rockchip,pins =
++ /* sdmmc_clk */
++ <4 RK_PD5 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_cmd: sdmmc-cmd {
++ rockchip,pins =
++ /* sdmmc_cmd */
++ <4 RK_PD4 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_det: sdmmc-det {
++ rockchip,pins =
++ /* sdmmc_det */
++ <0 RK_PA4 1 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_pwren: sdmmc-pwren {
++ rockchip,pins =
++ /* sdmmc_pwren */
++ <0 RK_PA5 2 &pcfg_pull_none>;
++ };
++ };
++
++ spdif0 {
++ /omit-if-no-ref/
++ spdif0m0_tx: spdif0m0-tx {
++ rockchip,pins =
++ /* spdif0m0_tx */
++ <1 RK_PB6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ spdif0m1_tx: spdif0m1-tx {
++ rockchip,pins =
++ /* spdif0m1_tx */
++ <4 RK_PB4 6 &pcfg_pull_none>;
++ };
++ };
++
++ spdif1 {
++ /omit-if-no-ref/
++ spdif1m0_tx: spdif1m0-tx {
++ rockchip,pins =
++ /* spdif1m0_tx */
++ <1 RK_PB7 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ spdif1m1_tx: spdif1m1-tx {
++ rockchip,pins =
++ /* spdif1m1_tx */
++ <4 RK_PB1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ spdif1m2_tx: spdif1m2-tx {
++ rockchip,pins =
++ /* spdif1m2_tx */
++ <4 RK_PC1 3 &pcfg_pull_none>;
++ };
++ };
++
++ spi0 {
++ /omit-if-no-ref/
++ spi0m0_pins: spi0m0-pins {
++ rockchip,pins =
++ /* spi0_clk_m0 */
++ <0 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m0 */
++ <0 RK_PC7 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m0 */
++ <0 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m0_cs0: spi0m0-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m0 */
++ <0 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m0_cs1: spi0m0-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m0 */
++ <0 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
++ };
++ /omit-if-no-ref/
++ spi0m1_pins: spi0m1-pins {
++ rockchip,pins =
++ /* spi0_clk_m1 */
++ <4 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m1 */
++ <4 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m1 */
++ <4 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m1_cs0: spi0m1-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m1 */
++ <4 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m1_cs1: spi0m1-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m1 */
++ <4 RK_PB1 8 &pcfg_pull_up_drv_level_1>;
++ };
++ /omit-if-no-ref/
++ spi0m2_pins: spi0m2-pins {
++ rockchip,pins =
++ /* spi0_clk_m2 */
++ <1 RK_PB3 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m2 */
++ <1 RK_PB1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m2 */
++ <1 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m2_cs0: spi0m2-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m2 */
++ <1 RK_PB4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m2_cs1: spi0m2-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m2 */
++ <1 RK_PB5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ /omit-if-no-ref/
++ spi0m3_pins: spi0m3-pins {
++ rockchip,pins =
++ /* spi0_clk_m3 */
++ <3 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m3 */
++ <3 RK_PD1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m3 */
++ <3 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m3_cs0: spi0m3-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m3 */
++ <3 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m3_cs1: spi0m3-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m3 */
++ <3 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi1 {
++ /omit-if-no-ref/
++ spi1m1_pins: spi1m1-pins {
++ rockchip,pins =
++ /* spi1_clk_m1 */
++ <3 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_miso_m1 */
++ <3 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_mosi_m1 */
++ <3 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m1_cs0: spi1m1-cs0 {
++ rockchip,pins =
++ /* spi1_cs0_m1 */
++ <3 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m1_cs1: spi1m1-cs1 {
++ rockchip,pins =
++ /* spi1_cs1_m1 */
++ <3 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m2_pins: spi1m2-pins {
++ rockchip,pins =
++ /* spi1_clk_m2 */
++ <1 RK_PD2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_miso_m2 */
++ <1 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_mosi_m2 */
++ <1 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m2_cs0: spi1m2-cs0 {
++ rockchip,pins =
++ /* spi1_cs0_m2 */
++ <1 RK_PD3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m2_cs1: spi1m2-cs1 {
++ rockchip,pins =
++ /* spi1_cs1_m2 */
++ <1 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi2 {
++ /omit-if-no-ref/
++ spi2m0_pins: spi2m0-pins {
++ rockchip,pins =
++ /* spi2_clk_m0 */
++ <1 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_miso_m0 */
++ <1 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_mosi_m0 */
++ <1 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m0_cs0: spi2m0-cs0 {
++ rockchip,pins =
++ /* spi2_cs0_m0 */
++ <1 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m0_cs1: spi2m0-cs1 {
++ rockchip,pins =
++ /* spi2_cs1_m0 */
++ <1 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m1_pins: spi2m1-pins {
++ rockchip,pins =
++ /* spi2_clk_m1 */
++ <4 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_miso_m1 */
++ <4 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_mosi_m1 */
++ <4 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m1_cs0: spi2m1-cs0 {
++ rockchip,pins =
++ /* spi2_cs0_m1 */
++ <4 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m1_cs1: spi2m1-cs1 {
++ rockchip,pins =
++ /* spi2_cs1_m1 */
++ <4 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m2_pins: spi2m2-pins {
++ rockchip,pins =
++ /* spi2_clk_m2 */
++ <0 RK_PA5 1 &pcfg_pull_up_drv_level_1>,
++ /* spi2_miso_m2 */
++ <0 RK_PB3 1 &pcfg_pull_up_drv_level_1>,
++ /* spi2_mosi_m2 */
++ <0 RK_PA6 1 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m2_cs0: spi2m2-cs0 {
++ rockchip,pins =
++ /* spi2_cs0_m2 */
++ <0 RK_PB1 1 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m2_cs1: spi2m2-cs1 {
++ rockchip,pins =
++ /* spi2_cs1_m2 */
++ <0 RK_PB0 1 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi3 {
++ /omit-if-no-ref/
++ spi3m1_pins: spi3m1-pins {
++ rockchip,pins =
++ /* spi3_clk_m1 */
++ <4 RK_PB7 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m1 */
++ <4 RK_PB5 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m1 */
++ <4 RK_PB6 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m1_cs0: spi3m1-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m1 */
++ <4 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m1_cs1: spi3m1-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m1 */
++ <4 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m2_pins: spi3m2-pins {
++ rockchip,pins =
++ /* spi3_clk_m2 */
++ <0 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m2 */
++ <0 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m2 */
++ <0 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m2_cs0: spi3m2-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m2 */
++ <0 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m2_cs1: spi3m2-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m2 */
++ <0 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m3_pins: spi3m3-pins {
++ rockchip,pins =
++ /* spi3_clk_m3 */
++ <3 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m3 */
++ <3 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m3 */
++ <3 RK_PC7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m3_cs0: spi3m3-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m3 */
++ <3 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m3_cs1: spi3m3-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m3 */
++ <3 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi4 {
++ /omit-if-no-ref/
++ spi4m0_pins: spi4m0-pins {
++ rockchip,pins =
++ /* spi4_clk_m0 */
++ <1 RK_PC2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_miso_m0 */
++ <1 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_mosi_m0 */
++ <1 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m0_cs0: spi4m0-cs0 {
++ rockchip,pins =
++ /* spi4_cs0_m0 */
++ <1 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m0_cs1: spi4m0-cs1 {
++ rockchip,pins =
++ /* spi4_cs1_m0 */
++ <1 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m1_pins: spi4m1-pins {
++ rockchip,pins =
++ /* spi4_clk_m1 */
++ <3 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_miso_m1 */
++ <3 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_mosi_m1 */
++ <3 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m1_cs0: spi4m1-cs0 {
++ rockchip,pins =
++ /* spi4_cs0_m1 */
++ <3 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m1_cs1: spi4m1-cs1 {
++ rockchip,pins =
++ /* spi4_cs1_m1 */
++ <3 RK_PA4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m2_pins: spi4m2-pins {
++ rockchip,pins =
++ /* spi4_clk_m2 */
++ <1 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_miso_m2 */
++ <1 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_mosi_m2 */
++ <1 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m2_cs0: spi4m2-cs0 {
++ rockchip,pins =
++ /* spi4_cs0_m2 */
++ <1 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ tsadc {
++ /omit-if-no-ref/
++ tsadcm1_shut: tsadcm1-shut {
++ rockchip,pins =
++ /* tsadcm1_shut */
++ <0 RK_PA2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ tsadc_shut: tsadc-shut {
++ rockchip,pins =
++ /* tsadc_shut */
++ <0 RK_PA1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ tsadc_shut_org: tsadc-shut-org {
++ rockchip,pins =
++ /* tsadc_shut_org */
++ <0 RK_PA1 1 &pcfg_pull_none>;
++ };
++ };
++
++ uart0 {
++ /omit-if-no-ref/
++ uart0m0_xfer: uart0m0-xfer {
++ rockchip,pins =
++ /* uart0_rx_m0 */
++ <0 RK_PC4 4 &pcfg_pull_up>,
++ /* uart0_tx_m0 */
++ <0 RK_PC5 4 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart0m1_xfer: uart0m1-xfer {
++ rockchip,pins =
++ /* uart0_rx_m1 */
++ <0 RK_PB0 4 &pcfg_pull_up>,
++ /* uart0_tx_m1 */
++ <0 RK_PB1 4 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart0m2_xfer: uart0m2-xfer {
++ rockchip,pins =
++ /* uart0_rx_m2 */
++ <4 RK_PA4 10 &pcfg_pull_up>,
++ /* uart0_tx_m2 */
++ <4 RK_PA3 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart0_ctsn: uart0-ctsn {
++ rockchip,pins =
++ /* uart0_ctsn */
++ <0 RK_PD1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart0_rtsn: uart0-rtsn {
++ rockchip,pins =
++ /* uart0_rtsn */
++ <0 RK_PC6 4 &pcfg_pull_none>;
++ };
++ };
++
++ uart1 {
++ /omit-if-no-ref/
++ uart1m1_xfer: uart1m1-xfer {
++ rockchip,pins =
++ /* uart1_rx_m1 */
++ <1 RK_PB7 10 &pcfg_pull_up>,
++ /* uart1_tx_m1 */
++ <1 RK_PB6 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart1m1_ctsn: uart1m1-ctsn {
++ rockchip,pins =
++ /* uart1m1_ctsn */
++ <1 RK_PD7 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m1_rtsn: uart1m1-rtsn {
++ rockchip,pins =
++ /* uart1m1_rtsn */
++ <1 RK_PD6 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m2_xfer: uart1m2-xfer {
++ rockchip,pins =
++ /* uart1_rx_m2 */
++ <0 RK_PD2 10 &pcfg_pull_up>,
++ /* uart1_tx_m2 */
++ <0 RK_PD1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart1m2_ctsn: uart1m2-ctsn {
++ rockchip,pins =
++ /* uart1m2_ctsn */
++ <0 RK_PD0 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m2_rtsn: uart1m2-rtsn {
++ rockchip,pins =
++ /* uart1m2_rtsn */
++ <0 RK_PC7 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart2 {
++ /omit-if-no-ref/
++ uart2m0_xfer: uart2m0-xfer {
++ rockchip,pins =
++ /* uart2_rx_m0 */
++ <0 RK_PB6 10 &pcfg_pull_up>,
++ /* uart2_tx_m0 */
++ <0 RK_PB5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart2m1_xfer: uart2m1-xfer {
++ rockchip,pins =
++ /* uart2_rx_m1 */
++ <4 RK_PD1 10 &pcfg_pull_up>,
++ /* uart2_tx_m1 */
++ <4 RK_PD0 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart2m2_xfer: uart2m2-xfer {
++ rockchip,pins =
++ /* uart2_rx_m2 */
++ <3 RK_PB2 10 &pcfg_pull_up>,
++ /* uart2_tx_m2 */
++ <3 RK_PB1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart2_ctsn: uart2-ctsn {
++ rockchip,pins =
++ /* uart2_ctsn */
++ <3 RK_PB4 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart2_rtsn: uart2-rtsn {
++ rockchip,pins =
++ /* uart2_rtsn */
++ <3 RK_PB3 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart3 {
++ /omit-if-no-ref/
++ uart3m0_xfer: uart3m0-xfer {
++ rockchip,pins =
++ /* uart3_rx_m0 */
++ <1 RK_PC0 10 &pcfg_pull_up>,
++ /* uart3_tx_m0 */
++ <1 RK_PC1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart3m1_xfer: uart3m1-xfer {
++ rockchip,pins =
++ /* uart3_rx_m1 */
++ <3 RK_PB6 10 &pcfg_pull_up>,
++ /* uart3_tx_m1 */
++ <3 RK_PB5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart3m2_xfer: uart3m2-xfer {
++ rockchip,pins =
++ /* uart3_rx_m2 */
++ <4 RK_PA6 10 &pcfg_pull_up>,
++ /* uart3_tx_m2 */
++ <4 RK_PA5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart3_ctsn: uart3-ctsn {
++ rockchip,pins =
++ /* uart3_ctsn */
++ <1 RK_PC3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart3_rtsn: uart3-rtsn {
++ rockchip,pins =
++ /* uart3_rtsn */
++ <1 RK_PC2 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart4 {
++ /omit-if-no-ref/
++ uart4m0_xfer: uart4m0-xfer {
++ rockchip,pins =
++ /* uart4_rx_m0 */
++ <1 RK_PD3 10 &pcfg_pull_up>,
++ /* uart4_tx_m0 */
++ <1 RK_PD2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart4m1_xfer: uart4m1-xfer {
++ rockchip,pins =
++ /* uart4_rx_m1 */
++ <3 RK_PD0 10 &pcfg_pull_up>,
++ /* uart4_tx_m1 */
++ <3 RK_PD1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart4m2_xfer: uart4m2-xfer {
++ rockchip,pins =
++ /* uart4_rx_m2 */
++ <1 RK_PB2 10 &pcfg_pull_up>,
++ /* uart4_tx_m2 */
++ <1 RK_PB3 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart4_ctsn: uart4-ctsn {
++ rockchip,pins =
++ /* uart4_ctsn */
++ <1 RK_PC7 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart4_rtsn: uart4-rtsn {
++ rockchip,pins =
++ /* uart4_rtsn */
++ <1 RK_PC5 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart5 {
++ /omit-if-no-ref/
++ uart5m0_xfer: uart5m0-xfer {
++ rockchip,pins =
++ /* uart5_rx_m0 */
++ <4 RK_PD4 10 &pcfg_pull_up>,
++ /* uart5_tx_m0 */
++ <4 RK_PD5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart5m0_ctsn: uart5m0-ctsn {
++ rockchip,pins =
++ /* uart5m0_ctsn */
++ <4 RK_PD2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m0_rtsn: uart5m0-rtsn {
++ rockchip,pins =
++ /* uart5m0_rtsn */
++ <4 RK_PD3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m1_xfer: uart5m1-xfer {
++ rockchip,pins =
++ /* uart5_rx_m1 */
++ <3 RK_PC5 10 &pcfg_pull_up>,
++ /* uart5_tx_m1 */
++ <3 RK_PC4 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart5m1_ctsn: uart5m1-ctsn {
++ rockchip,pins =
++ /* uart5m1_ctsn */
++ <2 RK_PA2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m1_rtsn: uart5m1-rtsn {
++ rockchip,pins =
++ /* uart5m1_rtsn */
++ <2 RK_PA3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m2_xfer: uart5m2-xfer {
++ rockchip,pins =
++ /* uart5_rx_m2 */
++ <2 RK_PD4 10 &pcfg_pull_up>,
++ /* uart5_tx_m2 */
++ <2 RK_PD5 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart6 {
++ /omit-if-no-ref/
++ uart6m1_xfer: uart6m1-xfer {
++ rockchip,pins =
++ /* uart6_rx_m1 */
++ <1 RK_PA0 10 &pcfg_pull_up>,
++ /* uart6_tx_m1 */
++ <1 RK_PA1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart6m1_ctsn: uart6m1-ctsn {
++ rockchip,pins =
++ /* uart6m1_ctsn */
++ <1 RK_PA3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart6m1_rtsn: uart6m1-rtsn {
++ rockchip,pins =
++ /* uart6m1_rtsn */
++ <1 RK_PA2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart6m2_xfer: uart6m2-xfer {
++ rockchip,pins =
++ /* uart6_rx_m2 */
++ <1 RK_PD1 10 &pcfg_pull_up>,
++ /* uart6_tx_m2 */
++ <1 RK_PD0 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart7 {
++ /omit-if-no-ref/
++ uart7m1_xfer: uart7m1-xfer {
++ rockchip,pins =
++ /* uart7_rx_m1 */
++ <3 RK_PC1 10 &pcfg_pull_up>,
++ /* uart7_tx_m1 */
++ <3 RK_PC0 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart7m1_ctsn: uart7m1-ctsn {
++ rockchip,pins =
++ /* uart7m1_ctsn */
++ <3 RK_PC3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart7m1_rtsn: uart7m1-rtsn {
++ rockchip,pins =
++ /* uart7m1_rtsn */
++ <3 RK_PC2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart7m2_xfer: uart7m2-xfer {
++ rockchip,pins =
++ /* uart7_rx_m2 */
++ <1 RK_PB4 10 &pcfg_pull_up>,
++ /* uart7_tx_m2 */
++ <1 RK_PB5 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart8 {
++ /omit-if-no-ref/
++ uart8m0_xfer: uart8m0-xfer {
++ rockchip,pins =
++ /* uart8_rx_m0 */
++ <4 RK_PB1 10 &pcfg_pull_up>,
++ /* uart8_tx_m0 */
++ <4 RK_PB0 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart8m0_ctsn: uart8m0-ctsn {
++ rockchip,pins =
++ /* uart8m0_ctsn */
++ <4 RK_PB3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8m0_rtsn: uart8m0-rtsn {
++ rockchip,pins =
++ /* uart8m0_rtsn */
++ <4 RK_PB2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8m1_xfer: uart8m1-xfer {
++ rockchip,pins =
++ /* uart8_rx_m1 */
++ <3 RK_PA3 10 &pcfg_pull_up>,
++ /* uart8_tx_m1 */
++ <3 RK_PA2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart8m1_ctsn: uart8m1-ctsn {
++ rockchip,pins =
++ /* uart8m1_ctsn */
++ <3 RK_PA5 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8m1_rtsn: uart8m1-rtsn {
++ rockchip,pins =
++ /* uart8m1_rtsn */
++ <3 RK_PA4 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8_xfer: uart8-xfer {
++ rockchip,pins =
++ /* uart8_rx_ */
++ <4 RK_PB1 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart9 {
++ /omit-if-no-ref/
++ uart9m0_xfer: uart9m0-xfer {
++ rockchip,pins =
++ /* uart9_rx_m0 */
++ <2 RK_PC4 10 &pcfg_pull_up>,
++ /* uart9_tx_m0 */
++ <2 RK_PC2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m1_xfer: uart9m1-xfer {
++ rockchip,pins =
++ /* uart9_rx_m1 */
++ <4 RK_PB5 10 &pcfg_pull_up>,
++ /* uart9_tx_m1 */
++ <4 RK_PB4 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m1_ctsn: uart9m1-ctsn {
++ rockchip,pins =
++ /* uart9m1_ctsn */
++ <4 RK_PA1 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m1_rtsn: uart9m1-rtsn {
++ rockchip,pins =
++ /* uart9m1_rtsn */
++ <4 RK_PA0 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m2_xfer: uart9m2-xfer {
++ rockchip,pins =
++ /* uart9_rx_m2 */
++ <3 RK_PD4 10 &pcfg_pull_up>,
++ /* uart9_tx_m2 */
++ <3 RK_PD5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m2_ctsn: uart9m2-ctsn {
++ rockchip,pins =
++ /* uart9m2_ctsn */
++ <3 RK_PD3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m2_rtsn: uart9m2-rtsn {
++ rockchip,pins =
++ /* uart9m2_rtsn */
++ <3 RK_PD2 10 &pcfg_pull_none>;
++ };
++ };
++
++ vop {
++ /omit-if-no-ref/
++ vop_pins: vop-pins {
++ rockchip,pins =
++ /* vop_post_empty */
++ <1 RK_PA2 1 &pcfg_pull_none>;
++ };
++ };
++};
++
++/*
++ * This part is edited handly.
++ */
++&pinctrl {
++ bt656 {
++ /omit-if-no-ref/
++ bt656_pins: bt656-pins {
++ rockchip,pins =
++ /* bt1120_clkout */
++ <4 RK_PB0 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d0 */
++ <4 RK_PA0 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d1 */
++ <4 RK_PA1 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d2 */
++ <4 RK_PA2 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d3 */
++ <4 RK_PA3 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d4 */
++ <4 RK_PA4 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d5 */
++ <4 RK_PA5 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d6 */
++ <4 RK_PA6 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d7 */
++ <4 RK_PA7 2 &pcfg_pull_none_drv_level_2>;
++ };
++ };
++
++ gpio-func {
++ /omit-if-no-ref/
++ tsadc_gpio_func: tsadc-gpio-func {
++ rockchip,pins =
++ <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-extra-pinctrl.dtsi
+@@ -0,0 +1,516 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include <dt-bindings/pinctrl/rockchip.h>
++#include "rockchip-pinconf.dtsi"
++
++/*
++ * This file is auto generated by pin2dts tool, please keep these code
++ * by adding changes at end of this file.
++ */
++&pinctrl {
++ clk32k {
++ /omit-if-no-ref/
++ clk32k_out1: clk32k-out1 {
++ rockchip,pins =
++ /* clk32k_out1 */
++ <2 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ };
++
++ eth0 {
++ /omit-if-no-ref/
++ eth0_pins: eth0-pins {
++ rockchip,pins =
++ /* eth0_refclko_25m */
++ <2 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ };
++
++ fspi {
++ /omit-if-no-ref/
++ fspim1_pins: fspim1-pins {
++ rockchip,pins =
++ /* fspi_clk_m1 */
++ <2 RK_PB3 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_cs0n_m1 */
++ <2 RK_PB4 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d0_m1 */
++ <2 RK_PA6 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d1_m1 */
++ <2 RK_PA7 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d2_m1 */
++ <2 RK_PB0 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d3_m1 */
++ <2 RK_PB1 3 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim1_cs1: fspim1-cs1 {
++ rockchip,pins =
++ /* fspi_cs1n_m1 */
++ <2 RK_PB5 3 &pcfg_pull_up_drv_level_2>;
++ };
++ };
++
++ gmac0 {
++ /omit-if-no-ref/
++ gmac0_miim: gmac0-miim {
++ rockchip,pins =
++ /* gmac0_mdc */
++ <4 RK_PC4 1 &pcfg_pull_none>,
++ /* gmac0_mdio */
++ <4 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_clkinout: gmac0-clkinout {
++ rockchip,pins =
++ /* gmac0_mclkinout */
++ <4 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_rx_bus2: gmac0-rx-bus2 {
++ rockchip,pins =
++ /* gmac0_rxd0 */
++ <2 RK_PC1 1 &pcfg_pull_none>,
++ /* gmac0_rxd1 */
++ <2 RK_PC2 1 &pcfg_pull_none>,
++ /* gmac0_rxdv_crs */
++ <4 RK_PC2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_tx_bus2: gmac0-tx-bus2 {
++ rockchip,pins =
++ /* gmac0_txd0 */
++ <2 RK_PB6 1 &pcfg_pull_none>,
++ /* gmac0_txd1 */
++ <2 RK_PB7 1 &pcfg_pull_none>,
++ /* gmac0_txen */
++ <2 RK_PC0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_rgmii_clk: gmac0-rgmii-clk {
++ rockchip,pins =
++ /* gmac0_rxclk */
++ <2 RK_PB0 1 &pcfg_pull_none>,
++ /* gmac0_txclk */
++ <2 RK_PB3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_rgmii_bus: gmac0-rgmii-bus {
++ rockchip,pins =
++ /* gmac0_rxd2 */
++ <2 RK_PA6 1 &pcfg_pull_none>,
++ /* gmac0_rxd3 */
++ <2 RK_PA7 1 &pcfg_pull_none>,
++ /* gmac0_txd2 */
++ <2 RK_PB1 1 &pcfg_pull_none>,
++ /* gmac0_txd3 */
++ <2 RK_PB2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_ppsclk: gmac0-ppsclk {
++ rockchip,pins =
++ /* gmac0_ppsclk */
++ <2 RK_PC4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_ppstring: gmac0-ppstring {
++ rockchip,pins =
++ /* gmac0_ppstring */
++ <2 RK_PB5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_ptp_refclk: gmac0-ptp-refclk {
++ rockchip,pins =
++ /* gmac0_ptp_refclk */
++ <2 RK_PB4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_txer: gmac0-txer {
++ rockchip,pins =
++ /* gmac0_txer */
++ <4 RK_PC6 1 &pcfg_pull_none>;
++ };
++
++ };
++
++ hdmi {
++ /omit-if-no-ref/
++ hdmim0_tx1_cec: hdmim0-tx1-cec {
++ rockchip,pins =
++ /* hdmim0_tx1_cec */
++ <2 RK_PC4 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx1_scl: hdmim0-tx1-scl {
++ rockchip,pins =
++ /* hdmim0_tx1_scl */
++ <2 RK_PB5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx1_sda: hdmim0-tx1-sda {
++ rockchip,pins =
++ /* hdmim0_tx1_sda */
++ <2 RK_PB4 4 &pcfg_pull_none>;
++ };
++ };
++
++ i2c0 {
++ /omit-if-no-ref/
++ i2c0m1_xfer: i2c0m1-xfer {
++ rockchip,pins =
++ /* i2c0_scl_m1 */
++ <4 RK_PC5 9 &pcfg_pull_none_smt>,
++ /* i2c0_sda_m1 */
++ <4 RK_PC6 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c2 {
++ /omit-if-no-ref/
++ i2c2m1_xfer: i2c2m1-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m1 */
++ <2 RK_PC1 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m1 */
++ <2 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c3 {
++ /omit-if-no-ref/
++ i2c3m3_xfer: i2c3m3-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m3 */
++ <2 RK_PB2 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m3 */
++ <2 RK_PB3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c4 {
++ /omit-if-no-ref/
++ i2c4m1_xfer: i2c4m1-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m1 */
++ <2 RK_PB5 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m1 */
++ <2 RK_PB4 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c5 {
++ /omit-if-no-ref/
++ i2c5m4_xfer: i2c5m4-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m4 */
++ <2 RK_PB6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m4 */
++ <2 RK_PB7 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c6 {
++ /omit-if-no-ref/
++ i2c6m2_xfer: i2c6m2-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m2 */
++ <2 RK_PC3 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m2 */
++ <2 RK_PC2 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c7 {
++ /omit-if-no-ref/
++ i2c7m1_xfer: i2c7m1-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m1 */
++ <4 RK_PC3 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m1 */
++ <4 RK_PC4 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c8 {
++ /omit-if-no-ref/
++ i2c8m1_xfer: i2c8m1-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m1 */
++ <2 RK_PB0 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m1 */
++ <2 RK_PB1 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2s2 {
++ /omit-if-no-ref/
++ i2s2m0_lrck: i2s2m0-lrck {
++ rockchip,pins =
++ /* i2s2m0_lrck */
++ <2 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_mclk: i2s2m0-mclk {
++ rockchip,pins =
++ /* i2s2m0_mclk */
++ <2 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sclk: i2s2m0-sclk {
++ rockchip,pins =
++ /* i2s2m0_sclk */
++ <2 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdi: i2s2m0-sdi {
++ rockchip,pins =
++ /* i2s2m0_sdi */
++ <2 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdo: i2s2m0-sdo {
++ rockchip,pins =
++ /* i2s2m0_sdo */
++ <4 RK_PC3 2 &pcfg_pull_none>;
++ };
++ };
++
++ pwm2 {
++ /omit-if-no-ref/
++ pwm2m2_pins: pwm2m2-pins {
++ rockchip,pins =
++ /* pwm2_m2 */
++ <4 RK_PC2 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm4 {
++ /omit-if-no-ref/
++ pwm4m1_pins: pwm4m1-pins {
++ rockchip,pins =
++ /* pwm4_m1 */
++ <4 RK_PC3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm5 {
++ /omit-if-no-ref/
++ pwm5m2_pins: pwm5m2-pins {
++ rockchip,pins =
++ /* pwm5_m2 */
++ <4 RK_PC4 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm6 {
++ /omit-if-no-ref/
++ pwm6m2_pins: pwm6m2-pins {
++ rockchip,pins =
++ /* pwm6_m2 */
++ <4 RK_PC5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm7 {
++ /omit-if-no-ref/
++ pwm7m3_pins: pwm7m3-pins {
++ rockchip,pins =
++ /* pwm7_ir_m3 */
++ <4 RK_PC6 11 &pcfg_pull_none>;
++ };
++ };
++
++ sdio {
++ /omit-if-no-ref/
++ sdiom0_pins: sdiom0-pins {
++ rockchip,pins =
++ /* sdio_clk_m0 */
++ <2 RK_PB3 2 &pcfg_pull_none>,
++ /* sdio_cmd_m0 */
++ <2 RK_PB2 2 &pcfg_pull_none>,
++ /* sdio_d0_m0 */
++ <2 RK_PA6 2 &pcfg_pull_none>,
++ /* sdio_d1_m0 */
++ <2 RK_PA7 2 &pcfg_pull_none>,
++ /* sdio_d2_m0 */
++ <2 RK_PB0 2 &pcfg_pull_none>,
++ /* sdio_d3_m0 */
++ <2 RK_PB1 2 &pcfg_pull_none>;
++ };
++ };
++
++ spi1 {
++ /omit-if-no-ref/
++ spi1m0_pins: spi1m0-pins {
++ rockchip,pins =
++ /* spi1_clk_m0 */
++ <2 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_miso_m0 */
++ <2 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_mosi_m0 */
++ <2 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m0_cs0: spi1m0-cs0 {
++ rockchip,pins =
++ /* spi1_cs0_m0 */
++ <2 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m0_cs1: spi1m0-cs1 {
++ rockchip,pins =
++ /* spi1_cs1_m0 */
++ <2 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi3 {
++ /omit-if-no-ref/
++ spi3m0_pins: spi3m0-pins {
++ rockchip,pins =
++ /* spi3_clk_m0 */
++ <4 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m0 */
++ <4 RK_PC4 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m0 */
++ <4 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m0_cs0: spi3m0-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m0 */
++ <4 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m0_cs1: spi3m0-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m0 */
++ <4 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ uart1 {
++ /omit-if-no-ref/
++ uart1m0_xfer: uart1m0-xfer {
++ rockchip,pins =
++ /* uart1_rx_m0 */
++ <2 RK_PB6 10 &pcfg_pull_up>,
++ /* uart1_tx_m0 */
++ <2 RK_PB7 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart1m0_ctsn: uart1m0-ctsn {
++ rockchip,pins =
++ /* uart1m0_ctsn */
++ <2 RK_PC1 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m0_rtsn: uart1m0-rtsn {
++ rockchip,pins =
++ /* uart1m0_rtsn */
++ <2 RK_PC0 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart6 {
++ /omit-if-no-ref/
++ uart6m0_xfer: uart6m0-xfer {
++ rockchip,pins =
++ /* uart6_rx_m0 */
++ <2 RK_PA6 10 &pcfg_pull_up>,
++ /* uart6_tx_m0 */
++ <2 RK_PA7 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart6m0_ctsn: uart6m0-ctsn {
++ rockchip,pins =
++ /* uart6m0_ctsn */
++ <2 RK_PB1 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart6m0_rtsn: uart6m0-rtsn {
++ rockchip,pins =
++ /* uart6m0_rtsn */
++ <2 RK_PB0 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart7 {
++ /omit-if-no-ref/
++ uart7m0_xfer: uart7m0-xfer {
++ rockchip,pins =
++ /* uart7_rx_m0 */
++ <2 RK_PB4 10 &pcfg_pull_up>,
++ /* uart7_tx_m0 */
++ <2 RK_PB5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart7m0_ctsn: uart7m0-ctsn {
++ rockchip,pins =
++ /* uart7m0_ctsn */
++ <4 RK_PC6 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart7m0_rtsn: uart7m0-rtsn {
++ rockchip,pins =
++ /* uart7m0_rtsn */
++ <4 RK_PC2 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart9 {
++ /omit-if-no-ref/
++ uart9m0_xfer: uart9m0-xfer {
++ rockchip,pins =
++ /* uart9_rx_m0 */
++ <2 RK_PC4 10 &pcfg_pull_up>,
++ /* uart9_tx_m0 */
++ <2 RK_PC2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m0_ctsn: uart9m0-ctsn {
++ rockchip,pins =
++ /* uart9m0_ctsn */
++ <4 RK_PC5 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m0_rtsn: uart9m0-rtsn {
++ rockchip,pins =
++ /* uart9m0_rtsn */
++ <4 RK_PC4 10 &pcfg_pull_none>;
++ };
++ };
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi
++++ /dev/null
+@@ -1,516 +0,0 @@
+-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+-/*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+- */
+-
+-#include <dt-bindings/pinctrl/rockchip.h>
+-#include "rockchip-pinconf.dtsi"
+-
+-/*
+- * This file is auto generated by pin2dts tool, please keep these code
+- * by adding changes at end of this file.
+- */
+-&pinctrl {
+- clk32k {
+- /omit-if-no-ref/
+- clk32k_out1: clk32k-out1 {
+- rockchip,pins =
+- /* clk32k_out1 */
+- <2 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- };
+-
+- eth0 {
+- /omit-if-no-ref/
+- eth0_pins: eth0-pins {
+- rockchip,pins =
+- /* eth0_refclko_25m */
+- <2 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- };
+-
+- fspi {
+- /omit-if-no-ref/
+- fspim1_pins: fspim1-pins {
+- rockchip,pins =
+- /* fspi_clk_m1 */
+- <2 RK_PB3 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_cs0n_m1 */
+- <2 RK_PB4 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d0_m1 */
+- <2 RK_PA6 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d1_m1 */
+- <2 RK_PA7 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d2_m1 */
+- <2 RK_PB0 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d3_m1 */
+- <2 RK_PB1 3 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim1_cs1: fspim1-cs1 {
+- rockchip,pins =
+- /* fspi_cs1n_m1 */
+- <2 RK_PB5 3 &pcfg_pull_up_drv_level_2>;
+- };
+- };
+-
+- gmac0 {
+- /omit-if-no-ref/
+- gmac0_miim: gmac0-miim {
+- rockchip,pins =
+- /* gmac0_mdc */
+- <4 RK_PC4 1 &pcfg_pull_none>,
+- /* gmac0_mdio */
+- <4 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_clkinout: gmac0-clkinout {
+- rockchip,pins =
+- /* gmac0_mclkinout */
+- <4 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_rx_bus2: gmac0-rx-bus2 {
+- rockchip,pins =
+- /* gmac0_rxd0 */
+- <2 RK_PC1 1 &pcfg_pull_none>,
+- /* gmac0_rxd1 */
+- <2 RK_PC2 1 &pcfg_pull_none>,
+- /* gmac0_rxdv_crs */
+- <4 RK_PC2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_tx_bus2: gmac0-tx-bus2 {
+- rockchip,pins =
+- /* gmac0_txd0 */
+- <2 RK_PB6 1 &pcfg_pull_none>,
+- /* gmac0_txd1 */
+- <2 RK_PB7 1 &pcfg_pull_none>,
+- /* gmac0_txen */
+- <2 RK_PC0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_rgmii_clk: gmac0-rgmii-clk {
+- rockchip,pins =
+- /* gmac0_rxclk */
+- <2 RK_PB0 1 &pcfg_pull_none>,
+- /* gmac0_txclk */
+- <2 RK_PB3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_rgmii_bus: gmac0-rgmii-bus {
+- rockchip,pins =
+- /* gmac0_rxd2 */
+- <2 RK_PA6 1 &pcfg_pull_none>,
+- /* gmac0_rxd3 */
+- <2 RK_PA7 1 &pcfg_pull_none>,
+- /* gmac0_txd2 */
+- <2 RK_PB1 1 &pcfg_pull_none>,
+- /* gmac0_txd3 */
+- <2 RK_PB2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_ppsclk: gmac0-ppsclk {
+- rockchip,pins =
+- /* gmac0_ppsclk */
+- <2 RK_PC4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_ppstring: gmac0-ppstring {
+- rockchip,pins =
+- /* gmac0_ppstring */
+- <2 RK_PB5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_ptp_refclk: gmac0-ptp-refclk {
+- rockchip,pins =
+- /* gmac0_ptp_refclk */
+- <2 RK_PB4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_txer: gmac0-txer {
+- rockchip,pins =
+- /* gmac0_txer */
+- <4 RK_PC6 1 &pcfg_pull_none>;
+- };
+-
+- };
+-
+- hdmi {
+- /omit-if-no-ref/
+- hdmim0_tx1_cec: hdmim0-tx1-cec {
+- rockchip,pins =
+- /* hdmim0_tx1_cec */
+- <2 RK_PC4 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx1_scl: hdmim0-tx1-scl {
+- rockchip,pins =
+- /* hdmim0_tx1_scl */
+- <2 RK_PB5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx1_sda: hdmim0-tx1-sda {
+- rockchip,pins =
+- /* hdmim0_tx1_sda */
+- <2 RK_PB4 4 &pcfg_pull_none>;
+- };
+- };
+-
+- i2c0 {
+- /omit-if-no-ref/
+- i2c0m1_xfer: i2c0m1-xfer {
+- rockchip,pins =
+- /* i2c0_scl_m1 */
+- <4 RK_PC5 9 &pcfg_pull_none_smt>,
+- /* i2c0_sda_m1 */
+- <4 RK_PC6 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c2 {
+- /omit-if-no-ref/
+- i2c2m1_xfer: i2c2m1-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m1 */
+- <2 RK_PC1 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m1 */
+- <2 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c3 {
+- /omit-if-no-ref/
+- i2c3m3_xfer: i2c3m3-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m3 */
+- <2 RK_PB2 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m3 */
+- <2 RK_PB3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c4 {
+- /omit-if-no-ref/
+- i2c4m1_xfer: i2c4m1-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m1 */
+- <2 RK_PB5 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m1 */
+- <2 RK_PB4 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c5 {
+- /omit-if-no-ref/
+- i2c5m4_xfer: i2c5m4-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m4 */
+- <2 RK_PB6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m4 */
+- <2 RK_PB7 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c6 {
+- /omit-if-no-ref/
+- i2c6m2_xfer: i2c6m2-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m2 */
+- <2 RK_PC3 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m2 */
+- <2 RK_PC2 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c7 {
+- /omit-if-no-ref/
+- i2c7m1_xfer: i2c7m1-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m1 */
+- <4 RK_PC3 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m1 */
+- <4 RK_PC4 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c8 {
+- /omit-if-no-ref/
+- i2c8m1_xfer: i2c8m1-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m1 */
+- <2 RK_PB0 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m1 */
+- <2 RK_PB1 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2s2 {
+- /omit-if-no-ref/
+- i2s2m0_lrck: i2s2m0-lrck {
+- rockchip,pins =
+- /* i2s2m0_lrck */
+- <2 RK_PC0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_mclk: i2s2m0-mclk {
+- rockchip,pins =
+- /* i2s2m0_mclk */
+- <2 RK_PB6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sclk: i2s2m0-sclk {
+- rockchip,pins =
+- /* i2s2m0_sclk */
+- <2 RK_PB7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdi: i2s2m0-sdi {
+- rockchip,pins =
+- /* i2s2m0_sdi */
+- <2 RK_PC3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdo: i2s2m0-sdo {
+- rockchip,pins =
+- /* i2s2m0_sdo */
+- <4 RK_PC3 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm2 {
+- /omit-if-no-ref/
+- pwm2m2_pins: pwm2m2-pins {
+- rockchip,pins =
+- /* pwm2_m2 */
+- <4 RK_PC2 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm4 {
+- /omit-if-no-ref/
+- pwm4m1_pins: pwm4m1-pins {
+- rockchip,pins =
+- /* pwm4_m1 */
+- <4 RK_PC3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm5 {
+- /omit-if-no-ref/
+- pwm5m2_pins: pwm5m2-pins {
+- rockchip,pins =
+- /* pwm5_m2 */
+- <4 RK_PC4 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm6 {
+- /omit-if-no-ref/
+- pwm6m2_pins: pwm6m2-pins {
+- rockchip,pins =
+- /* pwm6_m2 */
+- <4 RK_PC5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm7 {
+- /omit-if-no-ref/
+- pwm7m3_pins: pwm7m3-pins {
+- rockchip,pins =
+- /* pwm7_ir_m3 */
+- <4 RK_PC6 11 &pcfg_pull_none>;
+- };
+- };
+-
+- sdio {
+- /omit-if-no-ref/
+- sdiom0_pins: sdiom0-pins {
+- rockchip,pins =
+- /* sdio_clk_m0 */
+- <2 RK_PB3 2 &pcfg_pull_none>,
+- /* sdio_cmd_m0 */
+- <2 RK_PB2 2 &pcfg_pull_none>,
+- /* sdio_d0_m0 */
+- <2 RK_PA6 2 &pcfg_pull_none>,
+- /* sdio_d1_m0 */
+- <2 RK_PA7 2 &pcfg_pull_none>,
+- /* sdio_d2_m0 */
+- <2 RK_PB0 2 &pcfg_pull_none>,
+- /* sdio_d3_m0 */
+- <2 RK_PB1 2 &pcfg_pull_none>;
+- };
+- };
+-
+- spi1 {
+- /omit-if-no-ref/
+- spi1m0_pins: spi1m0-pins {
+- rockchip,pins =
+- /* spi1_clk_m0 */
+- <2 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_miso_m0 */
+- <2 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_mosi_m0 */
+- <2 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m0_cs0: spi1m0-cs0 {
+- rockchip,pins =
+- /* spi1_cs0_m0 */
+- <2 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m0_cs1: spi1m0-cs1 {
+- rockchip,pins =
+- /* spi1_cs1_m0 */
+- <2 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi3 {
+- /omit-if-no-ref/
+- spi3m0_pins: spi3m0-pins {
+- rockchip,pins =
+- /* spi3_clk_m0 */
+- <4 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m0 */
+- <4 RK_PC4 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m0 */
+- <4 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m0_cs0: spi3m0-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m0 */
+- <4 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m0_cs1: spi3m0-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m0 */
+- <4 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- uart1 {
+- /omit-if-no-ref/
+- uart1m0_xfer: uart1m0-xfer {
+- rockchip,pins =
+- /* uart1_rx_m0 */
+- <2 RK_PB6 10 &pcfg_pull_up>,
+- /* uart1_tx_m0 */
+- <2 RK_PB7 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m0_ctsn: uart1m0-ctsn {
+- rockchip,pins =
+- /* uart1m0_ctsn */
+- <2 RK_PC1 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m0_rtsn: uart1m0-rtsn {
+- rockchip,pins =
+- /* uart1m0_rtsn */
+- <2 RK_PC0 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart6 {
+- /omit-if-no-ref/
+- uart6m0_xfer: uart6m0-xfer {
+- rockchip,pins =
+- /* uart6_rx_m0 */
+- <2 RK_PA6 10 &pcfg_pull_up>,
+- /* uart6_tx_m0 */
+- <2 RK_PA7 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m0_ctsn: uart6m0-ctsn {
+- rockchip,pins =
+- /* uart6m0_ctsn */
+- <2 RK_PB1 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m0_rtsn: uart6m0-rtsn {
+- rockchip,pins =
+- /* uart6m0_rtsn */
+- <2 RK_PB0 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart7 {
+- /omit-if-no-ref/
+- uart7m0_xfer: uart7m0-xfer {
+- rockchip,pins =
+- /* uart7_rx_m0 */
+- <2 RK_PB4 10 &pcfg_pull_up>,
+- /* uart7_tx_m0 */
+- <2 RK_PB5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m0_ctsn: uart7m0-ctsn {
+- rockchip,pins =
+- /* uart7m0_ctsn */
+- <4 RK_PC6 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m0_rtsn: uart7m0-rtsn {
+- rockchip,pins =
+- /* uart7m0_rtsn */
+- <4 RK_PC2 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart9 {
+- /omit-if-no-ref/
+- uart9m0_xfer: uart9m0-xfer {
+- rockchip,pins =
+- /* uart9_rx_m0 */
+- <2 RK_PC4 10 &pcfg_pull_up>,
+- /* uart9_tx_m0 */
+- <2 RK_PC2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m0_ctsn: uart9m0-ctsn {
+- rockchip,pins =
+- /* uart9m0_ctsn */
+- <4 RK_PC5 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m0_rtsn: uart9m0-rtsn {
+- rockchip,pins =
+- /* uart9m0_rtsn */
+- <4 RK_PC4 10 &pcfg_pull_none>;
+- };
+- };
+-};
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
++++ /dev/null
+@@ -1,3447 +0,0 @@
+-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+-/*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+- */
+-
+-#include <dt-bindings/pinctrl/rockchip.h>
+-#include "rockchip-pinconf.dtsi"
+-
+-/*
+- * This file is auto generated by pin2dts tool, please keep these code
+- * by adding changes at end of this file.
+- */
+-&pinctrl {
+- auddsm {
+- /omit-if-no-ref/
+- auddsm_pins: auddsm-pins {
+- rockchip,pins =
+- /* auddsm_ln */
+- <3 RK_PA1 4 &pcfg_pull_none>,
+- /* auddsm_lp */
+- <3 RK_PA2 4 &pcfg_pull_none>,
+- /* auddsm_rn */
+- <3 RK_PA3 4 &pcfg_pull_none>,
+- /* auddsm_rp */
+- <3 RK_PA4 4 &pcfg_pull_none>;
+- };
+- };
+-
+- bt1120 {
+- /omit-if-no-ref/
+- bt1120_pins: bt1120-pins {
+- rockchip,pins =
+- /* bt1120_clkout */
+- <4 RK_PB0 2 &pcfg_pull_none>,
+- /* bt1120_d0 */
+- <4 RK_PA0 2 &pcfg_pull_none>,
+- /* bt1120_d1 */
+- <4 RK_PA1 2 &pcfg_pull_none>,
+- /* bt1120_d2 */
+- <4 RK_PA2 2 &pcfg_pull_none>,
+- /* bt1120_d3 */
+- <4 RK_PA3 2 &pcfg_pull_none>,
+- /* bt1120_d4 */
+- <4 RK_PA4 2 &pcfg_pull_none>,
+- /* bt1120_d5 */
+- <4 RK_PA5 2 &pcfg_pull_none>,
+- /* bt1120_d6 */
+- <4 RK_PA6 2 &pcfg_pull_none>,
+- /* bt1120_d7 */
+- <4 RK_PA7 2 &pcfg_pull_none>,
+- /* bt1120_d8 */
+- <4 RK_PB2 2 &pcfg_pull_none>,
+- /* bt1120_d9 */
+- <4 RK_PB3 2 &pcfg_pull_none>,
+- /* bt1120_d10 */
+- <4 RK_PB4 2 &pcfg_pull_none>,
+- /* bt1120_d11 */
+- <4 RK_PB5 2 &pcfg_pull_none>,
+- /* bt1120_d12 */
+- <4 RK_PB6 2 &pcfg_pull_none>,
+- /* bt1120_d13 */
+- <4 RK_PB7 2 &pcfg_pull_none>,
+- /* bt1120_d14 */
+- <4 RK_PC0 2 &pcfg_pull_none>,
+- /* bt1120_d15 */
+- <4 RK_PC1 2 &pcfg_pull_none>;
+- };
+- };
+-
+- can0 {
+- /omit-if-no-ref/
+- can0m0_pins: can0m0-pins {
+- rockchip,pins =
+- /* can0_rx_m0 */
+- <0 RK_PC0 11 &pcfg_pull_none>,
+- /* can0_tx_m0 */
+- <0 RK_PB7 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- can0m1_pins: can0m1-pins {
+- rockchip,pins =
+- /* can0_rx_m1 */
+- <4 RK_PD5 9 &pcfg_pull_none>,
+- /* can0_tx_m1 */
+- <4 RK_PD4 9 &pcfg_pull_none>;
+- };
+- };
+-
+- can1 {
+- /omit-if-no-ref/
+- can1m0_pins: can1m0-pins {
+- rockchip,pins =
+- /* can1_rx_m0 */
+- <3 RK_PB5 9 &pcfg_pull_none>,
+- /* can1_tx_m0 */
+- <3 RK_PB6 9 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- can1m1_pins: can1m1-pins {
+- rockchip,pins =
+- /* can1_rx_m1 */
+- <4 RK_PB2 12 &pcfg_pull_none>,
+- /* can1_tx_m1 */
+- <4 RK_PB3 12 &pcfg_pull_none>;
+- };
+- };
+-
+- can2 {
+- /omit-if-no-ref/
+- can2m0_pins: can2m0-pins {
+- rockchip,pins =
+- /* can2_rx_m0 */
+- <3 RK_PC4 9 &pcfg_pull_none>,
+- /* can2_tx_m0 */
+- <3 RK_PC5 9 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- can2m1_pins: can2m1-pins {
+- rockchip,pins =
+- /* can2_rx_m1 */
+- <0 RK_PD4 10 &pcfg_pull_none>,
+- /* can2_tx_m1 */
+- <0 RK_PD5 10 &pcfg_pull_none>;
+- };
+- };
+-
+- cif {
+- /omit-if-no-ref/
+- cif_clk: cif-clk {
+- rockchip,pins =
+- /* cif_clkout */
+- <4 RK_PB4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- cif_dvp_clk: cif-dvp-clk {
+- rockchip,pins =
+- /* cif_clkin */
+- <4 RK_PB0 1 &pcfg_pull_none>,
+- /* cif_href */
+- <4 RK_PB2 1 &pcfg_pull_none>,
+- /* cif_vsync */
+- <4 RK_PB3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- cif_dvp_bus16: cif-dvp-bus16 {
+- rockchip,pins =
+- /* cif_d8 */
+- <3 RK_PC4 1 &pcfg_pull_none>,
+- /* cif_d9 */
+- <3 RK_PC5 1 &pcfg_pull_none>,
+- /* cif_d10 */
+- <3 RK_PC6 1 &pcfg_pull_none>,
+- /* cif_d11 */
+- <3 RK_PC7 1 &pcfg_pull_none>,
+- /* cif_d12 */
+- <3 RK_PD0 1 &pcfg_pull_none>,
+- /* cif_d13 */
+- <3 RK_PD1 1 &pcfg_pull_none>,
+- /* cif_d14 */
+- <3 RK_PD2 1 &pcfg_pull_none>,
+- /* cif_d15 */
+- <3 RK_PD3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- cif_dvp_bus8: cif-dvp-bus8 {
+- rockchip,pins =
+- /* cif_d0 */
+- <4 RK_PA0 1 &pcfg_pull_none>,
+- /* cif_d1 */
+- <4 RK_PA1 1 &pcfg_pull_none>,
+- /* cif_d2 */
+- <4 RK_PA2 1 &pcfg_pull_none>,
+- /* cif_d3 */
+- <4 RK_PA3 1 &pcfg_pull_none>,
+- /* cif_d4 */
+- <4 RK_PA4 1 &pcfg_pull_none>,
+- /* cif_d5 */
+- <4 RK_PA5 1 &pcfg_pull_none>,
+- /* cif_d6 */
+- <4 RK_PA6 1 &pcfg_pull_none>,
+- /* cif_d7 */
+- <4 RK_PA7 1 &pcfg_pull_none>;
+- };
+- };
+-
+- clk32k {
+- /omit-if-no-ref/
+- clk32k_in: clk32k-in {
+- rockchip,pins =
+- /* clk32k_in */
+- <0 RK_PB2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- clk32k_out0: clk32k-out0 {
+- rockchip,pins =
+- /* clk32k_out0 */
+- <0 RK_PB2 2 &pcfg_pull_none>;
+- };
+- };
+-
+- cpu {
+- /omit-if-no-ref/
+- cpu_pins: cpu-pins {
+- rockchip,pins =
+- /* cpu_big0_avs */
+- <0 RK_PD1 2 &pcfg_pull_none>,
+- /* cpu_big1_avs */
+- <0 RK_PD5 2 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych0 {
+- /omit-if-no-ref/
+- ddrphych0_pins: ddrphych0-pins {
+- rockchip,pins =
+- /* ddrphych0_dtb0 */
+- <4 RK_PA0 7 &pcfg_pull_none>,
+- /* ddrphych0_dtb1 */
+- <4 RK_PA1 7 &pcfg_pull_none>,
+- /* ddrphych0_dtb2 */
+- <4 RK_PA2 7 &pcfg_pull_none>,
+- /* ddrphych0_dtb3 */
+- <4 RK_PA3 7 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych1 {
+- /omit-if-no-ref/
+- ddrphych1_pins: ddrphych1-pins {
+- rockchip,pins =
+- /* ddrphych1_dtb0 */
+- <4 RK_PA4 7 &pcfg_pull_none>,
+- /* ddrphych1_dtb1 */
+- <4 RK_PA5 7 &pcfg_pull_none>,
+- /* ddrphych1_dtb2 */
+- <4 RK_PA6 7 &pcfg_pull_none>,
+- /* ddrphych1_dtb3 */
+- <4 RK_PA7 7 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych2 {
+- /omit-if-no-ref/
+- ddrphych2_pins: ddrphych2-pins {
+- rockchip,pins =
+- /* ddrphych2_dtb0 */
+- <4 RK_PB0 7 &pcfg_pull_none>,
+- /* ddrphych2_dtb1 */
+- <4 RK_PB1 7 &pcfg_pull_none>,
+- /* ddrphych2_dtb2 */
+- <4 RK_PB2 7 &pcfg_pull_none>,
+- /* ddrphych2_dtb3 */
+- <4 RK_PB3 7 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych3 {
+- /omit-if-no-ref/
+- ddrphych3_pins: ddrphych3-pins {
+- rockchip,pins =
+- /* ddrphych3_dtb0 */
+- <4 RK_PB4 7 &pcfg_pull_none>,
+- /* ddrphych3_dtb1 */
+- <4 RK_PB5 7 &pcfg_pull_none>,
+- /* ddrphych3_dtb2 */
+- <4 RK_PB6 7 &pcfg_pull_none>,
+- /* ddrphych3_dtb3 */
+- <4 RK_PB7 7 &pcfg_pull_none>;
+- };
+- };
+-
+- dp0 {
+- /omit-if-no-ref/
+- dp0m0_pins: dp0m0-pins {
+- rockchip,pins =
+- /* dp0_hpdin_m0 */
+- <4 RK_PB4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp0m1_pins: dp0m1-pins {
+- rockchip,pins =
+- /* dp0_hpdin_m1 */
+- <0 RK_PC4 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp0m2_pins: dp0m2-pins {
+- rockchip,pins =
+- /* dp0_hpdin_m2 */
+- <1 RK_PA0 5 &pcfg_pull_none>;
+- };
+- };
+-
+- dp1 {
+- /omit-if-no-ref/
+- dp1m0_pins: dp1m0-pins {
+- rockchip,pins =
+- /* dp1_hpdin_m0 */
+- <3 RK_PD5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp1m1_pins: dp1m1-pins {
+- rockchip,pins =
+- /* dp1_hpdin_m1 */
+- <0 RK_PC5 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp1m2_pins: dp1m2-pins {
+- rockchip,pins =
+- /* dp1_hpdin_m2 */
+- <1 RK_PA1 5 &pcfg_pull_none>;
+- };
+- };
+-
+- emmc {
+- /omit-if-no-ref/
+- emmc_rstnout: emmc-rstnout {
+- rockchip,pins =
+- /* emmc_rstn */
+- <2 RK_PA3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_bus8: emmc-bus8 {
+- rockchip,pins =
+- /* emmc_d0 */
+- <2 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d1 */
+- <2 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d2 */
+- <2 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d3 */
+- <2 RK_PD3 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d4 */
+- <2 RK_PD4 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d5 */
+- <2 RK_PD5 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d6 */
+- <2 RK_PD6 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d7 */
+- <2 RK_PD7 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_clk: emmc-clk {
+- rockchip,pins =
+- /* emmc_clkout */
+- <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_cmd: emmc-cmd {
+- rockchip,pins =
+- /* emmc_cmd */
+- <2 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_data_strobe: emmc-data-strobe {
+- rockchip,pins =
+- /* emmc_data_strobe */
+- <2 RK_PA2 1 &pcfg_pull_down>;
+- };
+- };
+-
+- eth1 {
+- /omit-if-no-ref/
+- eth1_pins: eth1-pins {
+- rockchip,pins =
+- /* eth1_refclko_25m */
+- <3 RK_PA6 1 &pcfg_pull_none>;
+- };
+- };
+-
+- fspi {
+- /omit-if-no-ref/
+- fspim0_pins: fspim0-pins {
+- rockchip,pins =
+- /* fspi_clk_m0 */
+- <2 RK_PA0 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_cs0n_m0 */
+- <2 RK_PD6 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d0_m0 */
+- <2 RK_PD0 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d1_m0 */
+- <2 RK_PD1 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d2_m0 */
+- <2 RK_PD2 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d3_m0 */
+- <2 RK_PD3 2 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim0_cs1: fspim0-cs1 {
+- rockchip,pins =
+- /* fspi_cs1n_m0 */
+- <2 RK_PD7 2 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim2_pins: fspim2-pins {
+- rockchip,pins =
+- /* fspi_clk_m2 */
+- <3 RK_PA5 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_cs0n_m2 */
+- <3 RK_PC4 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d0_m2 */
+- <3 RK_PA0 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d1_m2 */
+- <3 RK_PA1 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d2_m2 */
+- <3 RK_PA2 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d3_m2 */
+- <3 RK_PA3 5 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim2_cs1: fspim2-cs1 {
+- rockchip,pins =
+- /* fspi_cs1n_m2 */
+- <3 RK_PC5 2 &pcfg_pull_up_drv_level_2>;
+- };
+- };
+-
+- gmac1 {
+- /omit-if-no-ref/
+- gmac1_miim: gmac1-miim {
+- rockchip,pins =
+- /* gmac1_mdc */
+- <3 RK_PC2 1 &pcfg_pull_none>,
+- /* gmac1_mdio */
+- <3 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_clkinout: gmac1-clkinout {
+- rockchip,pins =
+- /* gmac1_mclkinout */
+- <3 RK_PB6 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_rx_bus2: gmac1-rx-bus2 {
+- rockchip,pins =
+- /* gmac1_rxd0 */
+- <3 RK_PA7 1 &pcfg_pull_none>,
+- /* gmac1_rxd1 */
+- <3 RK_PB0 1 &pcfg_pull_none>,
+- /* gmac1_rxdv_crs */
+- <3 RK_PB1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_tx_bus2: gmac1-tx-bus2 {
+- rockchip,pins =
+- /* gmac1_txd0 */
+- <3 RK_PB3 1 &pcfg_pull_none>,
+- /* gmac1_txd1 */
+- <3 RK_PB4 1 &pcfg_pull_none>,
+- /* gmac1_txen */
+- <3 RK_PB5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_rgmii_clk: gmac1-rgmii-clk {
+- rockchip,pins =
+- /* gmac1_rxclk */
+- <3 RK_PA5 1 &pcfg_pull_none>,
+- /* gmac1_txclk */
+- <3 RK_PA4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_rgmii_bus: gmac1-rgmii-bus {
+- rockchip,pins =
+- /* gmac1_rxd2 */
+- <3 RK_PA2 1 &pcfg_pull_none>,
+- /* gmac1_rxd3 */
+- <3 RK_PA3 1 &pcfg_pull_none>,
+- /* gmac1_txd2 */
+- <3 RK_PA0 1 &pcfg_pull_none>,
+- /* gmac1_txd3 */
+- <3 RK_PA1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_ppsclk: gmac1-ppsclk {
+- rockchip,pins =
+- /* gmac1_ppsclk */
+- <3 RK_PC1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_ppstrig: gmac1-ppstrig {
+- rockchip,pins =
+- /* gmac1_ppstrig */
+- <3 RK_PC0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_ptp_ref_clk: gmac1-ptp-ref-clk {
+- rockchip,pins =
+- /* gmac1_ptp_ref_clk */
+- <3 RK_PB7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_txer: gmac1-txer {
+- rockchip,pins =
+- /* gmac1_txer */
+- <3 RK_PB2 1 &pcfg_pull_none>;
+- };
+- };
+-
+- gpu {
+- /omit-if-no-ref/
+- gpu_pins: gpu-pins {
+- rockchip,pins =
+- /* gpu_avs */
+- <0 RK_PC5 2 &pcfg_pull_none>;
+- };
+- };
+-
+- hdmi {
+- /omit-if-no-ref/
+- hdmim0_rx_cec: hdmim0-rx-cec {
+- rockchip,pins =
+- /* hdmim0_rx_cec */
+- <4 RK_PB5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_rx_hpdin: hdmim0-rx-hpdin {
+- rockchip,pins =
+- /* hdmim0_rx_hpdin */
+- <4 RK_PB6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_rx_scl: hdmim0-rx-scl {
+- rockchip,pins =
+- /* hdmim0_rx_scl */
+- <0 RK_PD2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_rx_sda: hdmim0-rx-sda {
+- rockchip,pins =
+- /* hdmim0_rx_sda */
+- <0 RK_PD1 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_cec: hdmim0-tx0-cec {
+- rockchip,pins =
+- /* hdmim0_tx0_cec */
+- <4 RK_PC1 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_hpd: hdmim0-tx0-hpd {
+- rockchip,pins =
+- /* hdmim0_tx0_hpd */
+- <1 RK_PA5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_scl: hdmim0-tx0-scl {
+- rockchip,pins =
+- /* hdmim0_tx0_scl */
+- <4 RK_PB7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_sda: hdmim0-tx0-sda {
+- rockchip,pins =
+- /* hdmim0_tx0_sda */
+- <4 RK_PC0 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx1_hpd: hdmim0-tx1-hpd {
+- rockchip,pins =
+- /* hdmim0_tx1_hpd */
+- <1 RK_PA6 5 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- hdmim1_rx_cec: hdmim1-rx-cec {
+- rockchip,pins =
+- /* hdmim1_rx_cec */
+- <3 RK_PD1 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_rx_hpdin: hdmim1-rx-hpdin {
+- rockchip,pins =
+- /* hdmim1_rx_hpdin */
+- <3 RK_PD4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_rx_scl: hdmim1-rx-scl {
+- rockchip,pins =
+- /* hdmim1_rx_scl */
+- <3 RK_PD2 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_rx_sda: hdmim1-rx-sda {
+- rockchip,pins =
+- /* hdmim1_rx_sda */
+- <3 RK_PD3 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_cec: hdmim1-tx0-cec {
+- rockchip,pins =
+- /* hdmim1_tx0_cec */
+- <0 RK_PD1 13 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_hpd: hdmim1-tx0-hpd {
+- rockchip,pins =
+- /* hdmim1_tx0_hpd */
+- <3 RK_PD4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_scl: hdmim1-tx0-scl {
+- rockchip,pins =
+- /* hdmim1_tx0_scl */
+- <0 RK_PD5 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_sda: hdmim1-tx0-sda {
+- rockchip,pins =
+- /* hdmim1_tx0_sda */
+- <0 RK_PD4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_cec: hdmim1-tx1-cec {
+- rockchip,pins =
+- /* hdmim1_tx1_cec */
+- <0 RK_PD2 13 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_hpd: hdmim1-tx1-hpd {
+- rockchip,pins =
+- /* hdmim1_tx1_hpd */
+- <3 RK_PB7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_scl: hdmim1-tx1-scl {
+- rockchip,pins =
+- /* hdmim1_tx1_scl */
+- <3 RK_PC6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_sda: hdmim1-tx1-sda {
+- rockchip,pins =
+- /* hdmim1_tx1_sda */
+- <3 RK_PC5 5 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- hdmim2_rx_cec: hdmim2-rx-cec {
+- rockchip,pins =
+- /* hdmim2_rx_cec */
+- <1 RK_PB7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_rx_hpdin: hdmim2-rx-hpdin {
+- rockchip,pins =
+- /* hdmim2_rx_hpdin */
+- <1 RK_PB6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_rx_scl: hdmim2-rx-scl {
+- rockchip,pins =
+- /* hdmim2_rx_scl */
+- <1 RK_PD6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_rx_sda: hdmim2-rx-sda {
+- rockchip,pins =
+- /* hdmim2_rx_sda */
+- <1 RK_PD7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx0_scl: hdmim2-tx0-scl {
+- rockchip,pins =
+- /* hdmim2_tx0_scl */
+- <3 RK_PC7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx0_sda: hdmim2-tx0-sda {
+- rockchip,pins =
+- /* hdmim2_tx0_sda */
+- <3 RK_PD0 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx1_cec: hdmim2-tx1-cec {
+- rockchip,pins =
+- /* hdmim2_tx1_cec */
+- <3 RK_PC4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx1_scl: hdmim2-tx1-scl {
+- rockchip,pins =
+- /* hdmim2_tx1_scl */
+- <1 RK_PA4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx1_sda: hdmim2-tx1-sda {
+- rockchip,pins =
+- /* hdmim2_tx1_sda */
+- <1 RK_PA3 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug0: hdmi-debug0 {
+- rockchip,pins =
+- /* hdmi_debug0 */
+- <1 RK_PA7 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug1: hdmi-debug1 {
+- rockchip,pins =
+- /* hdmi_debug1 */
+- <1 RK_PB0 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug2: hdmi-debug2 {
+- rockchip,pins =
+- /* hdmi_debug2 */
+- <1 RK_PB1 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug3: hdmi-debug3 {
+- rockchip,pins =
+- /* hdmi_debug3 */
+- <1 RK_PB2 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug4: hdmi-debug4 {
+- rockchip,pins =
+- /* hdmi_debug4 */
+- <1 RK_PB3 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug5: hdmi-debug5 {
+- rockchip,pins =
+- /* hdmi_debug5 */
+- <1 RK_PB4 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug6: hdmi-debug6 {
+- rockchip,pins =
+- /* hdmi_debug6 */
+- <1 RK_PA0 7 &pcfg_pull_none>;
+- };
+- };
+-
+- i2c0 {
+- /omit-if-no-ref/
+- i2c0m0_xfer: i2c0m0-xfer {
+- rockchip,pins =
+- /* i2c0_scl_m0 */
+- <0 RK_PB3 2 &pcfg_pull_none_smt>,
+- /* i2c0_sda_m0 */
+- <0 RK_PA6 2 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c0m2_xfer: i2c0m2-xfer {
+- rockchip,pins =
+- /* i2c0_scl_m2 */
+- <0 RK_PD1 3 &pcfg_pull_none_smt>,
+- /* i2c0_sda_m2 */
+- <0 RK_PD2 3 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c1 {
+- /omit-if-no-ref/
+- i2c1m0_xfer: i2c1m0-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m0 */
+- <0 RK_PB5 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m0 */
+- <0 RK_PB6 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m1_xfer: i2c1m1-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m1 */
+- <0 RK_PB0 2 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m1 */
+- <0 RK_PB1 2 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m2_xfer: i2c1m2-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m2 */
+- <0 RK_PD4 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m2 */
+- <0 RK_PD5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m3_xfer: i2c1m3-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m3 */
+- <2 RK_PD4 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m3 */
+- <2 RK_PD5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m4_xfer: i2c1m4-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m4 */
+- <1 RK_PD2 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m4 */
+- <1 RK_PD3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c2 {
+- /omit-if-no-ref/
+- i2c2m0_xfer: i2c2m0-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m0 */
+- <0 RK_PB7 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m0 */
+- <0 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c2m2_xfer: i2c2m2-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m2 */
+- <2 RK_PA3 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m2 */
+- <2 RK_PA2 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c2m3_xfer: i2c2m3-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m3 */
+- <1 RK_PC5 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m3 */
+- <1 RK_PC4 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c2m4_xfer: i2c2m4-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m4 */
+- <1 RK_PA1 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m4 */
+- <1 RK_PA0 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c3 {
+- /omit-if-no-ref/
+- i2c3m0_xfer: i2c3m0-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m0 */
+- <1 RK_PC1 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m0 */
+- <1 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c3m1_xfer: i2c3m1-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m1 */
+- <3 RK_PB7 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m1 */
+- <3 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c3m2_xfer: i2c3m2-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m2 */
+- <4 RK_PA4 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m2 */
+- <4 RK_PA5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c3m4_xfer: i2c3m4-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m4 */
+- <4 RK_PD0 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m4 */
+- <4 RK_PD1 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c4 {
+- /omit-if-no-ref/
+- i2c4m0_xfer: i2c4m0-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m0 */
+- <3 RK_PA6 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m0 */
+- <3 RK_PA5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c4m2_xfer: i2c4m2-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m2 */
+- <0 RK_PC5 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m2 */
+- <0 RK_PC4 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c4m3_xfer: i2c4m3-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m3 */
+- <1 RK_PA3 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m3 */
+- <1 RK_PA2 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c4m4_xfer: i2c4m4-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m4 */
+- <1 RK_PC7 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m4 */
+- <1 RK_PC6 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c5 {
+- /omit-if-no-ref/
+- i2c5m0_xfer: i2c5m0-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m0 */
+- <3 RK_PC7 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m0 */
+- <3 RK_PD0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c5m1_xfer: i2c5m1-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m1 */
+- <4 RK_PB6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m1 */
+- <4 RK_PB7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c5m2_xfer: i2c5m2-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m2 */
+- <4 RK_PA6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m2 */
+- <4 RK_PA7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c5m3_xfer: i2c5m3-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m3 */
+- <1 RK_PB6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m3 */
+- <1 RK_PB7 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c6 {
+- /omit-if-no-ref/
+- i2c6m0_xfer: i2c6m0-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m0 */
+- <0 RK_PD0 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m0 */
+- <0 RK_PC7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c6m1_xfer: i2c6m1-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m1 */
+- <1 RK_PC3 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m1 */
+- <1 RK_PC2 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c6m3_xfer: i2c6m3-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m3 */
+- <4 RK_PB1 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m3 */
+- <4 RK_PB0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c6m4_xfer: i2c6m4-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m4 */
+- <3 RK_PA1 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m4 */
+- <3 RK_PA0 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c7 {
+- /omit-if-no-ref/
+- i2c7m0_xfer: i2c7m0-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m0 */
+- <1 RK_PD0 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m0 */
+- <1 RK_PD1 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c7m2_xfer: i2c7m2-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m2 */
+- <3 RK_PD2 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m2 */
+- <3 RK_PD3 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c7m3_xfer: i2c7m3-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m3 */
+- <4 RK_PB2 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m3 */
+- <4 RK_PB3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c8 {
+- /omit-if-no-ref/
+- i2c8m0_xfer: i2c8m0-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m0 */
+- <4 RK_PD2 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m0 */
+- <4 RK_PD3 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c8m2_xfer: i2c8m2-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m2 */
+- <1 RK_PD6 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m2 */
+- <1 RK_PD7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c8m3_xfer: i2c8m3-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m3 */
+- <4 RK_PC0 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m3 */
+- <4 RK_PC1 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c8m4_xfer: i2c8m4-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m4 */
+- <3 RK_PC2 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m4 */
+- <3 RK_PC3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2s0 {
+- /omit-if-no-ref/
+- i2s0_lrck: i2s0-lrck {
+- rockchip,pins =
+- /* i2s0_lrck */
+- <1 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_mclk: i2s0-mclk {
+- rockchip,pins =
+- /* i2s0_mclk */
+- <1 RK_PC2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sclk: i2s0-sclk {
+- rockchip,pins =
+- /* i2s0_sclk */
+- <1 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi0: i2s0-sdi0 {
+- rockchip,pins =
+- /* i2s0_sdi0 */
+- <1 RK_PD4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi1: i2s0-sdi1 {
+- rockchip,pins =
+- /* i2s0_sdi1 */
+- <1 RK_PD3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi2: i2s0-sdi2 {
+- rockchip,pins =
+- /* i2s0_sdi2 */
+- <1 RK_PD2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi3: i2s0-sdi3 {
+- rockchip,pins =
+- /* i2s0_sdi3 */
+- <1 RK_PD1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo0: i2s0-sdo0 {
+- rockchip,pins =
+- /* i2s0_sdo0 */
+- <1 RK_PC7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo1: i2s0-sdo1 {
+- rockchip,pins =
+- /* i2s0_sdo1 */
+- <1 RK_PD0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo2: i2s0-sdo2 {
+- rockchip,pins =
+- /* i2s0_sdo2 */
+- <1 RK_PD1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo3: i2s0-sdo3 {
+- rockchip,pins =
+- /* i2s0_sdo3 */
+- <1 RK_PD2 1 &pcfg_pull_none>;
+- };
+- };
+-
+- i2s1 {
+- /omit-if-no-ref/
+- i2s1m0_lrck: i2s1m0-lrck {
+- rockchip,pins =
+- /* i2s1m0_lrck */
+- <4 RK_PA2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_mclk: i2s1m0-mclk {
+- rockchip,pins =
+- /* i2s1m0_mclk */
+- <4 RK_PA0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sclk: i2s1m0-sclk {
+- rockchip,pins =
+- /* i2s1m0_sclk */
+- <4 RK_PA1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi0: i2s1m0-sdi0 {
+- rockchip,pins =
+- /* i2s1m0_sdi0 */
+- <4 RK_PA5 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi1: i2s1m0-sdi1 {
+- rockchip,pins =
+- /* i2s1m0_sdi1 */
+- <4 RK_PA6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi2: i2s1m0-sdi2 {
+- rockchip,pins =
+- /* i2s1m0_sdi2 */
+- <4 RK_PA7 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi3: i2s1m0-sdi3 {
+- rockchip,pins =
+- /* i2s1m0_sdi3 */
+- <4 RK_PB0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo0: i2s1m0-sdo0 {
+- rockchip,pins =
+- /* i2s1m0_sdo0 */
+- <4 RK_PB1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo1: i2s1m0-sdo1 {
+- rockchip,pins =
+- /* i2s1m0_sdo1 */
+- <4 RK_PB2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo2: i2s1m0-sdo2 {
+- rockchip,pins =
+- /* i2s1m0_sdo2 */
+- <4 RK_PB3 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo3: i2s1m0-sdo3 {
+- rockchip,pins =
+- /* i2s1m0_sdo3 */
+- <4 RK_PB4 3 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- i2s1m1_lrck: i2s1m1-lrck {
+- rockchip,pins =
+- /* i2s1m1_lrck */
+- <0 RK_PB7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_mclk: i2s1m1-mclk {
+- rockchip,pins =
+- /* i2s1m1_mclk */
+- <0 RK_PB5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sclk: i2s1m1-sclk {
+- rockchip,pins =
+- /* i2s1m1_sclk */
+- <0 RK_PB6 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi0: i2s1m1-sdi0 {
+- rockchip,pins =
+- /* i2s1m1_sdi0 */
+- <0 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi1: i2s1m1-sdi1 {
+- rockchip,pins =
+- /* i2s1m1_sdi1 */
+- <0 RK_PC6 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi2: i2s1m1-sdi2 {
+- rockchip,pins =
+- /* i2s1m1_sdi2 */
+- <0 RK_PC7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi3: i2s1m1-sdi3 {
+- rockchip,pins =
+- /* i2s1m1_sdi3 */
+- <0 RK_PD0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo0: i2s1m1-sdo0 {
+- rockchip,pins =
+- /* i2s1m1_sdo0 */
+- <0 RK_PD1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo1: i2s1m1-sdo1 {
+- rockchip,pins =
+- /* i2s1m1_sdo1 */
+- <0 RK_PD2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo2: i2s1m1-sdo2 {
+- rockchip,pins =
+- /* i2s1m1_sdo2 */
+- <0 RK_PD4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo3: i2s1m1-sdo3 {
+- rockchip,pins =
+- /* i2s1m1_sdo3 */
+- <0 RK_PD5 1 &pcfg_pull_none>;
+- };
+- };
+-
+- i2s2 {
+- /omit-if-no-ref/
+- i2s2m0_lrck: i2s2m0-lrck {
+- rockchip,pins =
+- /* i2s2m0_lrck */
+- <2 RK_PC0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_mclk: i2s2m0-mclk {
+- rockchip,pins =
+- /* i2s2m0_mclk */
+- <2 RK_PB6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sclk: i2s2m0-sclk {
+- rockchip,pins =
+- /* i2s2m0_sclk */
+- <2 RK_PB7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdi: i2s2m0-sdi {
+- rockchip,pins =
+- /* i2s2m0_sdi */
+- <2 RK_PC3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdo: i2s2m0-sdo {
+- rockchip,pins =
+- /* i2s2m0_sdo */
+- <4 RK_PC3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_lrck: i2s2m1-lrck {
+- rockchip,pins =
+- /* i2s2m1_lrck */
+- <3 RK_PB6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_mclk: i2s2m1-mclk {
+- rockchip,pins =
+- /* i2s2m1_mclk */
+- <3 RK_PB4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_sclk: i2s2m1-sclk {
+- rockchip,pins =
+- /* i2s2m1_sclk */
+- <3 RK_PB5 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_sdi: i2s2m1-sdi {
+- rockchip,pins =
+- /* i2s2m1_sdi */
+- <3 RK_PB2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_sdo: i2s2m1-sdo {
+- rockchip,pins =
+- /* i2s2m1_sdo */
+- <3 RK_PB3 3 &pcfg_pull_none>;
+- };
+- };
+-
+- i2s3 {
+- /omit-if-no-ref/
+- i2s3_lrck: i2s3-lrck {
+- rockchip,pins =
+- /* i2s3_lrck */
+- <3 RK_PA2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_mclk: i2s3-mclk {
+- rockchip,pins =
+- /* i2s3_mclk */
+- <3 RK_PA0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_sclk: i2s3-sclk {
+- rockchip,pins =
+- /* i2s3_sclk */
+- <3 RK_PA1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_sdi: i2s3-sdi {
+- rockchip,pins =
+- /* i2s3_sdi */
+- <3 RK_PA4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_sdo: i2s3-sdo {
+- rockchip,pins =
+- /* i2s3_sdo */
+- <3 RK_PA3 3 &pcfg_pull_none>;
+- };
+- };
+-
+- jtag {
+- /omit-if-no-ref/
+- jtagm0_pins: jtagm0-pins {
+- rockchip,pins =
+- /* jtag_tck_m0 */
+- <4 RK_PD2 5 &pcfg_pull_none>,
+- /* jtag_tms_m0 */
+- <4 RK_PD3 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- jtagm1_pins: jtagm1-pins {
+- rockchip,pins =
+- /* jtag_tck_m1 */
+- <4 RK_PD0 5 &pcfg_pull_none>,
+- /* jtag_tms_m1 */
+- <4 RK_PD1 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- jtagm2_pins: jtagm2-pins {
+- rockchip,pins =
+- /* jtag_tck_m2 */
+- <0 RK_PB5 2 &pcfg_pull_none>,
+- /* jtag_tms_m2 */
+- <0 RK_PB6 2 &pcfg_pull_none>;
+- };
+- };
+-
+- litcpu {
+- /omit-if-no-ref/
+- litcpu_pins: litcpu-pins {
+- rockchip,pins =
+- /* litcpu_avs */
+- <0 RK_PD3 1 &pcfg_pull_none>;
+- };
+- };
+-
+- mcu {
+- /omit-if-no-ref/
+- mcum0_pins: mcum0-pins {
+- rockchip,pins =
+- /* mcu_jtag_tck_m0 */
+- <4 RK_PD4 5 &pcfg_pull_none>,
+- /* mcu_jtag_tms_m0 */
+- <4 RK_PD5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mcum1_pins: mcum1-pins {
+- rockchip,pins =
+- /* mcu_jtag_tck_m1 */
+- <3 RK_PD4 6 &pcfg_pull_none>,
+- /* mcu_jtag_tms_m1 */
+- <3 RK_PD5 6 &pcfg_pull_none>;
+- };
+- };
+-
+- mipi {
+- /omit-if-no-ref/
+- mipim0_camera0_clk: mipim0-camera0-clk {
+- rockchip,pins =
+- /* mipim0_camera0_clk */
+- <4 RK_PB1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera1_clk: mipim0-camera1-clk {
+- rockchip,pins =
+- /* mipim0_camera1_clk */
+- <1 RK_PB6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera2_clk: mipim0-camera2-clk {
+- rockchip,pins =
+- /* mipim0_camera2_clk */
+- <1 RK_PB7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera3_clk: mipim0-camera3-clk {
+- rockchip,pins =
+- /* mipim0_camera3_clk */
+- <1 RK_PD6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera4_clk: mipim0-camera4-clk {
+- rockchip,pins =
+- /* mipim0_camera4_clk */
+- <1 RK_PD7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera0_clk: mipim1-camera0-clk {
+- rockchip,pins =
+- /* mipim1_camera0_clk */
+- <3 RK_PA5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera1_clk: mipim1-camera1-clk {
+- rockchip,pins =
+- /* mipim1_camera1_clk */
+- <3 RK_PA6 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera2_clk: mipim1-camera2-clk {
+- rockchip,pins =
+- /* mipim1_camera2_clk */
+- <3 RK_PA7 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera3_clk: mipim1-camera3-clk {
+- rockchip,pins =
+- /* mipim1_camera3_clk */
+- <3 RK_PB0 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera4_clk: mipim1-camera4-clk {
+- rockchip,pins =
+- /* mipim1_camera4_clk */
+- <3 RK_PB1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipi_te0: mipi-te0 {
+- rockchip,pins =
+- /* mipi_te0 */
+- <3 RK_PC2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipi_te1: mipi-te1 {
+- rockchip,pins =
+- /* mipi_te1 */
+- <3 RK_PC3 2 &pcfg_pull_none>;
+- };
+- };
+-
+- npu {
+- /omit-if-no-ref/
+- npu_pins: npu-pins {
+- rockchip,pins =
+- /* npu_avs */
+- <0 RK_PC6 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie20x1 {
+- /omit-if-no-ref/
+- pcie20x1m0_pins: pcie20x1m0-pins {
+- rockchip,pins =
+- /* pcie20x1_2_clkreqn_m0 */
+- <3 RK_PC7 4 &pcfg_pull_none>,
+- /* pcie20x1_2_perstn_m0 */
+- <3 RK_PD1 4 &pcfg_pull_none>,
+- /* pcie20x1_2_waken_m0 */
+- <3 RK_PD0 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie20x1m1_pins: pcie20x1m1-pins {
+- rockchip,pins =
+- /* pcie20x1_2_clkreqn_m1 */
+- <4 RK_PB7 4 &pcfg_pull_none>,
+- /* pcie20x1_2_perstn_m1 */
+- <4 RK_PC1 4 &pcfg_pull_none>,
+- /* pcie20x1_2_waken_m1 */
+- <4 RK_PC0 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie20x1_2_button_rstn: pcie20x1-2-button-rstn {
+- rockchip,pins =
+- /* pcie20x1_2_button_rstn */
+- <4 RK_PB3 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30phy {
+- /omit-if-no-ref/
+- pcie30phy_pins: pcie30phy-pins {
+- rockchip,pins =
+- /* pcie30phy_dtb0 */
+- <1 RK_PC4 4 &pcfg_pull_none>,
+- /* pcie30phy_dtb1 */
+- <1 RK_PD1 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30x1 {
+- /omit-if-no-ref/
+- pcie30x1m0_pins: pcie30x1m0-pins {
+- rockchip,pins =
+- /* pcie30x1_0_clkreqn_m0 */
+- <0 RK_PC0 12 &pcfg_pull_none>,
+- /* pcie30x1_0_perstn_m0 */
+- <0 RK_PC5 12 &pcfg_pull_none>,
+- /* pcie30x1_0_waken_m0 */
+- <0 RK_PC4 12 &pcfg_pull_none>,
+- /* pcie30x1_1_clkreqn_m0 */
+- <0 RK_PB5 12 &pcfg_pull_none>,
+- /* pcie30x1_1_perstn_m0 */
+- <0 RK_PB7 12 &pcfg_pull_none>,
+- /* pcie30x1_1_waken_m0 */
+- <0 RK_PB6 12 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1m1_pins: pcie30x1m1-pins {
+- rockchip,pins =
+- /* pcie30x1_0_clkreqn_m1 */
+- <4 RK_PA3 4 &pcfg_pull_none>,
+- /* pcie30x1_0_perstn_m1 */
+- <4 RK_PA5 4 &pcfg_pull_none>,
+- /* pcie30x1_0_waken_m1 */
+- <4 RK_PA4 4 &pcfg_pull_none>,
+- /* pcie30x1_1_clkreqn_m1 */
+- <4 RK_PA0 4 &pcfg_pull_none>,
+- /* pcie30x1_1_perstn_m1 */
+- <4 RK_PA2 4 &pcfg_pull_none>,
+- /* pcie30x1_1_waken_m1 */
+- <4 RK_PA1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1m2_pins: pcie30x1m2-pins {
+- rockchip,pins =
+- /* pcie30x1_0_clkreqn_m2 */
+- <1 RK_PB5 4 &pcfg_pull_none>,
+- /* pcie30x1_0_perstn_m2 */
+- <1 RK_PB4 4 &pcfg_pull_none>,
+- /* pcie30x1_0_waken_m2 */
+- <1 RK_PB3 4 &pcfg_pull_none>,
+- /* pcie30x1_1_clkreqn_m2 */
+- <1 RK_PA0 4 &pcfg_pull_none>,
+- /* pcie30x1_1_perstn_m2 */
+- <1 RK_PA7 4 &pcfg_pull_none>,
+- /* pcie30x1_1_waken_m2 */
+- <1 RK_PA1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1_0_button_rstn: pcie30x1-0-button-rstn {
+- rockchip,pins =
+- /* pcie30x1_0_button_rstn */
+- <4 RK_PB1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1_1_button_rstn: pcie30x1-1-button-rstn {
+- rockchip,pins =
+- /* pcie30x1_1_button_rstn */
+- <4 RK_PB2 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30x2 {
+- /omit-if-no-ref/
+- pcie30x2m0_pins: pcie30x2m0-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m0 */
+- <0 RK_PD1 12 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m0 */
+- <0 RK_PD4 12 &pcfg_pull_none>,
+- /* pcie30x2_waken_m0 */
+- <0 RK_PD2 12 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2m1_pins: pcie30x2m1-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m1 */
+- <4 RK_PA6 4 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m1 */
+- <4 RK_PB0 4 &pcfg_pull_none>,
+- /* pcie30x2_waken_m1 */
+- <4 RK_PA7 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2m2_pins: pcie30x2m2-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m2 */
+- <3 RK_PD2 4 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m2 */
+- <3 RK_PD4 4 &pcfg_pull_none>,
+- /* pcie30x2_waken_m2 */
+- <3 RK_PD3 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2m3_pins: pcie30x2m3-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m3 */
+- <1 RK_PD7 4 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m3 */
+- <1 RK_PB7 4 &pcfg_pull_none>,
+- /* pcie30x2_waken_m3 */
+- <1 RK_PB6 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2_button_rstn: pcie30x2-button-rstn {
+- rockchip,pins =
+- /* pcie30x2_button_rstn */
+- <3 RK_PC1 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30x4 {
+- /omit-if-no-ref/
+- pcie30x4m0_pins: pcie30x4m0-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m0 */
+- <0 RK_PC6 12 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m0 */
+- <0 RK_PD0 12 &pcfg_pull_none>,
+- /* pcie30x4_waken_m0 */
+- <0 RK_PC7 12 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4m1_pins: pcie30x4m1-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m1 */
+- <4 RK_PB4 4 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m1 */
+- <4 RK_PB6 4 &pcfg_pull_none>,
+- /* pcie30x4_waken_m1 */
+- <4 RK_PB5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4m2_pins: pcie30x4m2-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m2 */
+- <3 RK_PC4 4 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m2 */
+- <3 RK_PC6 4 &pcfg_pull_none>,
+- /* pcie30x4_waken_m2 */
+- <3 RK_PC5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4m3_pins: pcie30x4m3-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m3 */
+- <1 RK_PB0 4 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m3 */
+- <1 RK_PB2 4 &pcfg_pull_none>,
+- /* pcie30x4_waken_m3 */
+- <1 RK_PB1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4_button_rstn: pcie30x4-button-rstn {
+- rockchip,pins =
+- /* pcie30x4_button_rstn */
+- <3 RK_PD5 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pdm0 {
+- /omit-if-no-ref/
+- pdm0m0_clk: pdm0m0-clk {
+- rockchip,pins =
+- /* pdm0_clk0_m0 */
+- <1 RK_PC6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_clk1: pdm0m0-clk1 {
+- rockchip,pins =
+- /* pdm0m0_clk1 */
+- <1 RK_PC4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi0: pdm0m0-sdi0 {
+- rockchip,pins =
+- /* pdm0m0_sdi0 */
+- <1 RK_PD5 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi1: pdm0m0-sdi1 {
+- rockchip,pins =
+- /* pdm0m0_sdi1 */
+- <1 RK_PD1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi2: pdm0m0-sdi2 {
+- rockchip,pins =
+- /* pdm0m0_sdi2 */
+- <1 RK_PD2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi3: pdm0m0-sdi3 {
+- rockchip,pins =
+- /* pdm0m0_sdi3 */
+- <1 RK_PD3 3 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- pdm0m1_clk: pdm0m1-clk {
+- rockchip,pins =
+- /* pdm0_clk0_m1 */
+- <0 RK_PC0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_clk1: pdm0m1-clk1 {
+- rockchip,pins =
+- /* pdm0m1_clk1 */
+- <0 RK_PC4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi0: pdm0m1-sdi0 {
+- rockchip,pins =
+- /* pdm0m1_sdi0 */
+- <0 RK_PC7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi1: pdm0m1-sdi1 {
+- rockchip,pins =
+- /* pdm0m1_sdi1 */
+- <0 RK_PD0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi2: pdm0m1-sdi2 {
+- rockchip,pins =
+- /* pdm0m1_sdi2 */
+- <0 RK_PD4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi3: pdm0m1-sdi3 {
+- rockchip,pins =
+- /* pdm0m1_sdi3 */
+- <0 RK_PD6 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pdm1 {
+- /omit-if-no-ref/
+- pdm1m0_clk: pdm1m0-clk {
+- rockchip,pins =
+- /* pdm1_clk0_m0 */
+- <4 RK_PD5 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_clk1: pdm1m0-clk1 {
+- rockchip,pins =
+- /* pdm1m0_clk1 */
+- <4 RK_PD4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi0: pdm1m0-sdi0 {
+- rockchip,pins =
+- /* pdm1m0_sdi0 */
+- <4 RK_PD3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi1: pdm1m0-sdi1 {
+- rockchip,pins =
+- /* pdm1m0_sdi1 */
+- <4 RK_PD2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi2: pdm1m0-sdi2 {
+- rockchip,pins =
+- /* pdm1m0_sdi2 */
+- <4 RK_PD1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi3: pdm1m0-sdi3 {
+- rockchip,pins =
+- /* pdm1m0_sdi3 */
+- <4 RK_PD0 2 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- pdm1m1_clk: pdm1m1-clk {
+- rockchip,pins =
+- /* pdm1_clk0_m1 */
+- <1 RK_PB4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_clk1: pdm1m1-clk1 {
+- rockchip,pins =
+- /* pdm1m1_clk1 */
+- <1 RK_PB3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi0: pdm1m1-sdi0 {
+- rockchip,pins =
+- /* pdm1m1_sdi0 */
+- <1 RK_PA7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi1: pdm1m1-sdi1 {
+- rockchip,pins =
+- /* pdm1m1_sdi1 */
+- <1 RK_PB0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi2: pdm1m1-sdi2 {
+- rockchip,pins =
+- /* pdm1m1_sdi2 */
+- <1 RK_PB1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi3: pdm1m1-sdi3 {
+- rockchip,pins =
+- /* pdm1m1_sdi3 */
+- <1 RK_PB2 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pmic {
+- /omit-if-no-ref/
+- pmic_pins: pmic-pins {
+- rockchip,pins =
+- /* pmic_int_l */
+- <0 RK_PA7 0 &pcfg_pull_up>,
+- /* pmic_sleep1 */
+- <0 RK_PA2 1 &pcfg_pull_none>,
+- /* pmic_sleep2 */
+- <0 RK_PA3 1 &pcfg_pull_none>,
+- /* pmic_sleep3 */
+- <0 RK_PC1 1 &pcfg_pull_none>,
+- /* pmic_sleep4 */
+- <0 RK_PC2 1 &pcfg_pull_none>,
+- /* pmic_sleep5 */
+- <0 RK_PC3 1 &pcfg_pull_none>,
+- /* pmic_sleep6 */
+- <0 RK_PD6 1 &pcfg_pull_none>;
+- };
+- };
+-
+- pmu {
+- /omit-if-no-ref/
+- pmu_pins: pmu-pins {
+- rockchip,pins =
+- /* pmu_debug */
+- <0 RK_PA5 3 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm0 {
+- /omit-if-no-ref/
+- pwm0m0_pins: pwm0m0-pins {
+- rockchip,pins =
+- /* pwm0_m0 */
+- <0 RK_PB7 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm0m1_pins: pwm0m1-pins {
+- rockchip,pins =
+- /* pwm0_m1 */
+- <1 RK_PD2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm0m2_pins: pwm0m2-pins {
+- rockchip,pins =
+- /* pwm0_m2 */
+- <1 RK_PA2 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm1 {
+- /omit-if-no-ref/
+- pwm1m0_pins: pwm1m0-pins {
+- rockchip,pins =
+- /* pwm1_m0 */
+- <0 RK_PC0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm1m1_pins: pwm1m1-pins {
+- rockchip,pins =
+- /* pwm1_m1 */
+- <1 RK_PD3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm1m2_pins: pwm1m2-pins {
+- rockchip,pins =
+- /* pwm1_m2 */
+- <1 RK_PA3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm2 {
+- /omit-if-no-ref/
+- pwm2m0_pins: pwm2m0-pins {
+- rockchip,pins =
+- /* pwm2_m0 */
+- <0 RK_PC4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm2m1_pins: pwm2m1-pins {
+- rockchip,pins =
+- /* pwm2_m1 */
+- <3 RK_PB1 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm3 {
+- /omit-if-no-ref/
+- pwm3m0_pins: pwm3m0-pins {
+- rockchip,pins =
+- /* pwm3_ir_m0 */
+- <0 RK_PD4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm3m1_pins: pwm3m1-pins {
+- rockchip,pins =
+- /* pwm3_ir_m1 */
+- <3 RK_PB2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm3m2_pins: pwm3m2-pins {
+- rockchip,pins =
+- /* pwm3_ir_m2 */
+- <1 RK_PC2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm3m3_pins: pwm3m3-pins {
+- rockchip,pins =
+- /* pwm3_ir_m3 */
+- <1 RK_PA7 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm4 {
+- /omit-if-no-ref/
+- pwm4m0_pins: pwm4m0-pins {
+- rockchip,pins =
+- /* pwm4_m0 */
+- <0 RK_PC5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm5 {
+- /omit-if-no-ref/
+- pwm5m0_pins: pwm5m0-pins {
+- rockchip,pins =
+- /* pwm5_m0 */
+- <0 RK_PB1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm5m1_pins: pwm5m1-pins {
+- rockchip,pins =
+- /* pwm5_m1 */
+- <0 RK_PC6 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm6 {
+- /omit-if-no-ref/
+- pwm6m0_pins: pwm6m0-pins {
+- rockchip,pins =
+- /* pwm6_m0 */
+- <0 RK_PC7 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm6m1_pins: pwm6m1-pins {
+- rockchip,pins =
+- /* pwm6_m1 */
+- <4 RK_PC1 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm7 {
+- /omit-if-no-ref/
+- pwm7m0_pins: pwm7m0-pins {
+- rockchip,pins =
+- /* pwm7_ir_m0 */
+- <0 RK_PD0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm7m1_pins: pwm7m1-pins {
+- rockchip,pins =
+- /* pwm7_ir_m1 */
+- <4 RK_PD4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm7m2_pins: pwm7m2-pins {
+- rockchip,pins =
+- /* pwm7_ir_m2 */
+- <1 RK_PC3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm8 {
+- /omit-if-no-ref/
+- pwm8m0_pins: pwm8m0-pins {
+- rockchip,pins =
+- /* pwm8_m0 */
+- <3 RK_PA7 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm8m1_pins: pwm8m1-pins {
+- rockchip,pins =
+- /* pwm8_m1 */
+- <4 RK_PD0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm8m2_pins: pwm8m2-pins {
+- rockchip,pins =
+- /* pwm8_m2 */
+- <3 RK_PD0 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm9 {
+- /omit-if-no-ref/
+- pwm9m0_pins: pwm9m0-pins {
+- rockchip,pins =
+- /* pwm9_m0 */
+- <3 RK_PB0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm9m1_pins: pwm9m1-pins {
+- rockchip,pins =
+- /* pwm9_m1 */
+- <4 RK_PD1 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm9m2_pins: pwm9m2-pins {
+- rockchip,pins =
+- /* pwm9_m2 */
+- <3 RK_PD1 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm10 {
+- /omit-if-no-ref/
+- pwm10m0_pins: pwm10m0-pins {
+- rockchip,pins =
+- /* pwm10_m0 */
+- <3 RK_PA0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm10m1_pins: pwm10m1-pins {
+- rockchip,pins =
+- /* pwm10_m1 */
+- <4 RK_PD3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm10m2_pins: pwm10m2-pins {
+- rockchip,pins =
+- /* pwm10_m2 */
+- <3 RK_PD3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm11 {
+- /omit-if-no-ref/
+- pwm11m0_pins: pwm11m0-pins {
+- rockchip,pins =
+- /* pwm11_ir_m0 */
+- <3 RK_PA1 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm11m1_pins: pwm11m1-pins {
+- rockchip,pins =
+- /* pwm11_ir_m1 */
+- <4 RK_PB4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm11m2_pins: pwm11m2-pins {
+- rockchip,pins =
+- /* pwm11_ir_m2 */
+- <1 RK_PC4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm11m3_pins: pwm11m3-pins {
+- rockchip,pins =
+- /* pwm11_ir_m3 */
+- <3 RK_PD5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm12 {
+- /omit-if-no-ref/
+- pwm12m0_pins: pwm12m0-pins {
+- rockchip,pins =
+- /* pwm12_m0 */
+- <3 RK_PB5 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm12m1_pins: pwm12m1-pins {
+- rockchip,pins =
+- /* pwm12_m1 */
+- <4 RK_PB5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm13 {
+- /omit-if-no-ref/
+- pwm13m0_pins: pwm13m0-pins {
+- rockchip,pins =
+- /* pwm13_m0 */
+- <3 RK_PB6 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm13m1_pins: pwm13m1-pins {
+- rockchip,pins =
+- /* pwm13_m1 */
+- <4 RK_PB6 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm13m2_pins: pwm13m2-pins {
+- rockchip,pins =
+- /* pwm13_m2 */
+- <1 RK_PB7 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm14 {
+- /omit-if-no-ref/
+- pwm14m0_pins: pwm14m0-pins {
+- rockchip,pins =
+- /* pwm14_m0 */
+- <3 RK_PC2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm14m1_pins: pwm14m1-pins {
+- rockchip,pins =
+- /* pwm14_m1 */
+- <4 RK_PB2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm14m2_pins: pwm14m2-pins {
+- rockchip,pins =
+- /* pwm14_m2 */
+- <1 RK_PD6 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm15 {
+- /omit-if-no-ref/
+- pwm15m0_pins: pwm15m0-pins {
+- rockchip,pins =
+- /* pwm15_ir_m0 */
+- <3 RK_PC3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm15m1_pins: pwm15m1-pins {
+- rockchip,pins =
+- /* pwm15_ir_m1 */
+- <4 RK_PB3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm15m2_pins: pwm15m2-pins {
+- rockchip,pins =
+- /* pwm15_ir_m2 */
+- <1 RK_PC6 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm15m3_pins: pwm15m3-pins {
+- rockchip,pins =
+- /* pwm15_ir_m3 */
+- <1 RK_PD7 11 &pcfg_pull_none>;
+- };
+- };
+-
+- refclk {
+- /omit-if-no-ref/
+- refclk_pins: refclk-pins {
+- rockchip,pins =
+- /* refclk_out */
+- <0 RK_PA0 1 &pcfg_pull_none>;
+- };
+- };
+-
+- sata {
+- /omit-if-no-ref/
+- sata_pins: sata-pins {
+- rockchip,pins =
+- /* sata_cp_pod */
+- <0 RK_PC6 13 &pcfg_pull_none>,
+- /* sata_cpdet */
+- <0 RK_PD4 13 &pcfg_pull_none>,
+- /* sata_mp_switch */
+- <0 RK_PD5 13 &pcfg_pull_none>;
+- };
+- };
+-
+- sata0 {
+- /omit-if-no-ref/
+- sata0m0_pins: sata0m0-pins {
+- rockchip,pins =
+- /* sata0_act_led_m0 */
+- <4 RK_PB6 6 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- sata0m1_pins: sata0m1-pins {
+- rockchip,pins =
+- /* sata0_act_led_m1 */
+- <1 RK_PB3 6 &pcfg_pull_none>;
+- };
+- };
+-
+- sata1 {
+- /omit-if-no-ref/
+- sata1m0_pins: sata1m0-pins {
+- rockchip,pins =
+- /* sata1_act_led_m0 */
+- <4 RK_PB5 6 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- sata1m1_pins: sata1m1-pins {
+- rockchip,pins =
+- /* sata1_act_led_m1 */
+- <1 RK_PA1 6 &pcfg_pull_none>;
+- };
+- };
+-
+- sata2 {
+- /omit-if-no-ref/
+- sata2m0_pins: sata2m0-pins {
+- rockchip,pins =
+- /* sata2_act_led_m0 */
+- <4 RK_PB1 6 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- sata2m1_pins: sata2m1-pins {
+- rockchip,pins =
+- /* sata2_act_led_m1 */
+- <1 RK_PB7 6 &pcfg_pull_none>;
+- };
+- };
+-
+- sdio {
+- /omit-if-no-ref/
+- sdiom1_pins: sdiom1-pins {
+- rockchip,pins =
+- /* sdio_clk_m1 */
+- <3 RK_PA5 2 &pcfg_pull_none>,
+- /* sdio_cmd_m1 */
+- <3 RK_PA4 2 &pcfg_pull_none>,
+- /* sdio_d0_m1 */
+- <3 RK_PA0 2 &pcfg_pull_none>,
+- /* sdio_d1_m1 */
+- <3 RK_PA1 2 &pcfg_pull_none>,
+- /* sdio_d2_m1 */
+- <3 RK_PA2 2 &pcfg_pull_none>,
+- /* sdio_d3_m1 */
+- <3 RK_PA3 2 &pcfg_pull_none>;
+- };
+- };
+-
+- sdmmc {
+- /omit-if-no-ref/
+- sdmmc_bus4: sdmmc-bus4 {
+- rockchip,pins =
+- /* sdmmc_d0 */
+- <4 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
+- /* sdmmc_d1 */
+- <4 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
+- /* sdmmc_d2 */
+- <4 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
+- /* sdmmc_d3 */
+- <4 RK_PD3 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_clk: sdmmc-clk {
+- rockchip,pins =
+- /* sdmmc_clk */
+- <4 RK_PD5 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_cmd: sdmmc-cmd {
+- rockchip,pins =
+- /* sdmmc_cmd */
+- <4 RK_PD4 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_det: sdmmc-det {
+- rockchip,pins =
+- /* sdmmc_det */
+- <0 RK_PA4 1 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_pwren: sdmmc-pwren {
+- rockchip,pins =
+- /* sdmmc_pwren */
+- <0 RK_PA5 2 &pcfg_pull_none>;
+- };
+- };
+-
+- spdif0 {
+- /omit-if-no-ref/
+- spdif0m0_tx: spdif0m0-tx {
+- rockchip,pins =
+- /* spdif0m0_tx */
+- <1 RK_PB6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- spdif0m1_tx: spdif0m1-tx {
+- rockchip,pins =
+- /* spdif0m1_tx */
+- <4 RK_PB4 6 &pcfg_pull_none>;
+- };
+- };
+-
+- spdif1 {
+- /omit-if-no-ref/
+- spdif1m0_tx: spdif1m0-tx {
+- rockchip,pins =
+- /* spdif1m0_tx */
+- <1 RK_PB7 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- spdif1m1_tx: spdif1m1-tx {
+- rockchip,pins =
+- /* spdif1m1_tx */
+- <4 RK_PB1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- spdif1m2_tx: spdif1m2-tx {
+- rockchip,pins =
+- /* spdif1m2_tx */
+- <4 RK_PC1 3 &pcfg_pull_none>;
+- };
+- };
+-
+- spi0 {
+- /omit-if-no-ref/
+- spi0m0_pins: spi0m0-pins {
+- rockchip,pins =
+- /* spi0_clk_m0 */
+- <0 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m0 */
+- <0 RK_PC7 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m0 */
+- <0 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m0_cs0: spi0m0-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m0 */
+- <0 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m0_cs1: spi0m0-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m0 */
+- <0 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
+- };
+- /omit-if-no-ref/
+- spi0m1_pins: spi0m1-pins {
+- rockchip,pins =
+- /* spi0_clk_m1 */
+- <4 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m1 */
+- <4 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m1 */
+- <4 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m1_cs0: spi0m1-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m1 */
+- <4 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m1_cs1: spi0m1-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m1 */
+- <4 RK_PB1 8 &pcfg_pull_up_drv_level_1>;
+- };
+- /omit-if-no-ref/
+- spi0m2_pins: spi0m2-pins {
+- rockchip,pins =
+- /* spi0_clk_m2 */
+- <1 RK_PB3 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m2 */
+- <1 RK_PB1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m2 */
+- <1 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m2_cs0: spi0m2-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m2 */
+- <1 RK_PB4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m2_cs1: spi0m2-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m2 */
+- <1 RK_PB5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- /omit-if-no-ref/
+- spi0m3_pins: spi0m3-pins {
+- rockchip,pins =
+- /* spi0_clk_m3 */
+- <3 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m3 */
+- <3 RK_PD1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m3 */
+- <3 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m3_cs0: spi0m3-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m3 */
+- <3 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m3_cs1: spi0m3-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m3 */
+- <3 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi1 {
+- /omit-if-no-ref/
+- spi1m1_pins: spi1m1-pins {
+- rockchip,pins =
+- /* spi1_clk_m1 */
+- <3 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_miso_m1 */
+- <3 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_mosi_m1 */
+- <3 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m1_cs0: spi1m1-cs0 {
+- rockchip,pins =
+- /* spi1_cs0_m1 */
+- <3 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m1_cs1: spi1m1-cs1 {
+- rockchip,pins =
+- /* spi1_cs1_m1 */
+- <3 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m2_pins: spi1m2-pins {
+- rockchip,pins =
+- /* spi1_clk_m2 */
+- <1 RK_PD2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_miso_m2 */
+- <1 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_mosi_m2 */
+- <1 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m2_cs0: spi1m2-cs0 {
+- rockchip,pins =
+- /* spi1_cs0_m2 */
+- <1 RK_PD3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m2_cs1: spi1m2-cs1 {
+- rockchip,pins =
+- /* spi1_cs1_m2 */
+- <1 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi2 {
+- /omit-if-no-ref/
+- spi2m0_pins: spi2m0-pins {
+- rockchip,pins =
+- /* spi2_clk_m0 */
+- <1 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_miso_m0 */
+- <1 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_mosi_m0 */
+- <1 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m0_cs0: spi2m0-cs0 {
+- rockchip,pins =
+- /* spi2_cs0_m0 */
+- <1 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m0_cs1: spi2m0-cs1 {
+- rockchip,pins =
+- /* spi2_cs1_m0 */
+- <1 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m1_pins: spi2m1-pins {
+- rockchip,pins =
+- /* spi2_clk_m1 */
+- <4 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_miso_m1 */
+- <4 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_mosi_m1 */
+- <4 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m1_cs0: spi2m1-cs0 {
+- rockchip,pins =
+- /* spi2_cs0_m1 */
+- <4 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m1_cs1: spi2m1-cs1 {
+- rockchip,pins =
+- /* spi2_cs1_m1 */
+- <4 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m2_pins: spi2m2-pins {
+- rockchip,pins =
+- /* spi2_clk_m2 */
+- <0 RK_PA5 1 &pcfg_pull_up_drv_level_1>,
+- /* spi2_miso_m2 */
+- <0 RK_PB3 1 &pcfg_pull_up_drv_level_1>,
+- /* spi2_mosi_m2 */
+- <0 RK_PA6 1 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m2_cs0: spi2m2-cs0 {
+- rockchip,pins =
+- /* spi2_cs0_m2 */
+- <0 RK_PB1 1 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m2_cs1: spi2m2-cs1 {
+- rockchip,pins =
+- /* spi2_cs1_m2 */
+- <0 RK_PB0 1 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi3 {
+- /omit-if-no-ref/
+- spi3m1_pins: spi3m1-pins {
+- rockchip,pins =
+- /* spi3_clk_m1 */
+- <4 RK_PB7 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m1 */
+- <4 RK_PB5 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m1 */
+- <4 RK_PB6 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m1_cs0: spi3m1-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m1 */
+- <4 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m1_cs1: spi3m1-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m1 */
+- <4 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m2_pins: spi3m2-pins {
+- rockchip,pins =
+- /* spi3_clk_m2 */
+- <0 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m2 */
+- <0 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m2 */
+- <0 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m2_cs0: spi3m2-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m2 */
+- <0 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m2_cs1: spi3m2-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m2 */
+- <0 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m3_pins: spi3m3-pins {
+- rockchip,pins =
+- /* spi3_clk_m3 */
+- <3 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m3 */
+- <3 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m3 */
+- <3 RK_PC7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m3_cs0: spi3m3-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m3 */
+- <3 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m3_cs1: spi3m3-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m3 */
+- <3 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi4 {
+- /omit-if-no-ref/
+- spi4m0_pins: spi4m0-pins {
+- rockchip,pins =
+- /* spi4_clk_m0 */
+- <1 RK_PC2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_miso_m0 */
+- <1 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_mosi_m0 */
+- <1 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m0_cs0: spi4m0-cs0 {
+- rockchip,pins =
+- /* spi4_cs0_m0 */
+- <1 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m0_cs1: spi4m0-cs1 {
+- rockchip,pins =
+- /* spi4_cs1_m0 */
+- <1 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m1_pins: spi4m1-pins {
+- rockchip,pins =
+- /* spi4_clk_m1 */
+- <3 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_miso_m1 */
+- <3 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_mosi_m1 */
+- <3 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m1_cs0: spi4m1-cs0 {
+- rockchip,pins =
+- /* spi4_cs0_m1 */
+- <3 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m1_cs1: spi4m1-cs1 {
+- rockchip,pins =
+- /* spi4_cs1_m1 */
+- <3 RK_PA4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m2_pins: spi4m2-pins {
+- rockchip,pins =
+- /* spi4_clk_m2 */
+- <1 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_miso_m2 */
+- <1 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_mosi_m2 */
+- <1 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m2_cs0: spi4m2-cs0 {
+- rockchip,pins =
+- /* spi4_cs0_m2 */
+- <1 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- tsadc {
+- /omit-if-no-ref/
+- tsadcm1_shut: tsadcm1-shut {
+- rockchip,pins =
+- /* tsadcm1_shut */
+- <0 RK_PA2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- tsadc_shut: tsadc-shut {
+- rockchip,pins =
+- /* tsadc_shut */
+- <0 RK_PA1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- tsadc_shut_org: tsadc-shut-org {
+- rockchip,pins =
+- /* tsadc_shut_org */
+- <0 RK_PA1 1 &pcfg_pull_none>;
+- };
+- };
+-
+- uart0 {
+- /omit-if-no-ref/
+- uart0m0_xfer: uart0m0-xfer {
+- rockchip,pins =
+- /* uart0_rx_m0 */
+- <0 RK_PC4 4 &pcfg_pull_up>,
+- /* uart0_tx_m0 */
+- <0 RK_PC5 4 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart0m1_xfer: uart0m1-xfer {
+- rockchip,pins =
+- /* uart0_rx_m1 */
+- <0 RK_PB0 4 &pcfg_pull_up>,
+- /* uart0_tx_m1 */
+- <0 RK_PB1 4 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart0m2_xfer: uart0m2-xfer {
+- rockchip,pins =
+- /* uart0_rx_m2 */
+- <4 RK_PA4 10 &pcfg_pull_up>,
+- /* uart0_tx_m2 */
+- <4 RK_PA3 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart0_ctsn: uart0-ctsn {
+- rockchip,pins =
+- /* uart0_ctsn */
+- <0 RK_PD1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart0_rtsn: uart0-rtsn {
+- rockchip,pins =
+- /* uart0_rtsn */
+- <0 RK_PC6 4 &pcfg_pull_none>;
+- };
+- };
+-
+- uart1 {
+- /omit-if-no-ref/
+- uart1m1_xfer: uart1m1-xfer {
+- rockchip,pins =
+- /* uart1_rx_m1 */
+- <1 RK_PB7 10 &pcfg_pull_up>,
+- /* uart1_tx_m1 */
+- <1 RK_PB6 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m1_ctsn: uart1m1-ctsn {
+- rockchip,pins =
+- /* uart1m1_ctsn */
+- <1 RK_PD7 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m1_rtsn: uart1m1-rtsn {
+- rockchip,pins =
+- /* uart1m1_rtsn */
+- <1 RK_PD6 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m2_xfer: uart1m2-xfer {
+- rockchip,pins =
+- /* uart1_rx_m2 */
+- <0 RK_PD2 10 &pcfg_pull_up>,
+- /* uart1_tx_m2 */
+- <0 RK_PD1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m2_ctsn: uart1m2-ctsn {
+- rockchip,pins =
+- /* uart1m2_ctsn */
+- <0 RK_PD0 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m2_rtsn: uart1m2-rtsn {
+- rockchip,pins =
+- /* uart1m2_rtsn */
+- <0 RK_PC7 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart2 {
+- /omit-if-no-ref/
+- uart2m0_xfer: uart2m0-xfer {
+- rockchip,pins =
+- /* uart2_rx_m0 */
+- <0 RK_PB6 10 &pcfg_pull_up>,
+- /* uart2_tx_m0 */
+- <0 RK_PB5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart2m1_xfer: uart2m1-xfer {
+- rockchip,pins =
+- /* uart2_rx_m1 */
+- <4 RK_PD1 10 &pcfg_pull_up>,
+- /* uart2_tx_m1 */
+- <4 RK_PD0 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart2m2_xfer: uart2m2-xfer {
+- rockchip,pins =
+- /* uart2_rx_m2 */
+- <3 RK_PB2 10 &pcfg_pull_up>,
+- /* uart2_tx_m2 */
+- <3 RK_PB1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart2_ctsn: uart2-ctsn {
+- rockchip,pins =
+- /* uart2_ctsn */
+- <3 RK_PB4 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart2_rtsn: uart2-rtsn {
+- rockchip,pins =
+- /* uart2_rtsn */
+- <3 RK_PB3 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart3 {
+- /omit-if-no-ref/
+- uart3m0_xfer: uart3m0-xfer {
+- rockchip,pins =
+- /* uart3_rx_m0 */
+- <1 RK_PC0 10 &pcfg_pull_up>,
+- /* uart3_tx_m0 */
+- <1 RK_PC1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart3m1_xfer: uart3m1-xfer {
+- rockchip,pins =
+- /* uart3_rx_m1 */
+- <3 RK_PB6 10 &pcfg_pull_up>,
+- /* uart3_tx_m1 */
+- <3 RK_PB5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart3m2_xfer: uart3m2-xfer {
+- rockchip,pins =
+- /* uart3_rx_m2 */
+- <4 RK_PA6 10 &pcfg_pull_up>,
+- /* uart3_tx_m2 */
+- <4 RK_PA5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart3_ctsn: uart3-ctsn {
+- rockchip,pins =
+- /* uart3_ctsn */
+- <1 RK_PC3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart3_rtsn: uart3-rtsn {
+- rockchip,pins =
+- /* uart3_rtsn */
+- <1 RK_PC2 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart4 {
+- /omit-if-no-ref/
+- uart4m0_xfer: uart4m0-xfer {
+- rockchip,pins =
+- /* uart4_rx_m0 */
+- <1 RK_PD3 10 &pcfg_pull_up>,
+- /* uart4_tx_m0 */
+- <1 RK_PD2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart4m1_xfer: uart4m1-xfer {
+- rockchip,pins =
+- /* uart4_rx_m1 */
+- <3 RK_PD0 10 &pcfg_pull_up>,
+- /* uart4_tx_m1 */
+- <3 RK_PD1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart4m2_xfer: uart4m2-xfer {
+- rockchip,pins =
+- /* uart4_rx_m2 */
+- <1 RK_PB2 10 &pcfg_pull_up>,
+- /* uart4_tx_m2 */
+- <1 RK_PB3 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart4_ctsn: uart4-ctsn {
+- rockchip,pins =
+- /* uart4_ctsn */
+- <1 RK_PC7 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart4_rtsn: uart4-rtsn {
+- rockchip,pins =
+- /* uart4_rtsn */
+- <1 RK_PC5 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart5 {
+- /omit-if-no-ref/
+- uart5m0_xfer: uart5m0-xfer {
+- rockchip,pins =
+- /* uart5_rx_m0 */
+- <4 RK_PD4 10 &pcfg_pull_up>,
+- /* uart5_tx_m0 */
+- <4 RK_PD5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m0_ctsn: uart5m0-ctsn {
+- rockchip,pins =
+- /* uart5m0_ctsn */
+- <4 RK_PD2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m0_rtsn: uart5m0-rtsn {
+- rockchip,pins =
+- /* uart5m0_rtsn */
+- <4 RK_PD3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m1_xfer: uart5m1-xfer {
+- rockchip,pins =
+- /* uart5_rx_m1 */
+- <3 RK_PC5 10 &pcfg_pull_up>,
+- /* uart5_tx_m1 */
+- <3 RK_PC4 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m1_ctsn: uart5m1-ctsn {
+- rockchip,pins =
+- /* uart5m1_ctsn */
+- <2 RK_PA2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m1_rtsn: uart5m1-rtsn {
+- rockchip,pins =
+- /* uart5m1_rtsn */
+- <2 RK_PA3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m2_xfer: uart5m2-xfer {
+- rockchip,pins =
+- /* uart5_rx_m2 */
+- <2 RK_PD4 10 &pcfg_pull_up>,
+- /* uart5_tx_m2 */
+- <2 RK_PD5 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart6 {
+- /omit-if-no-ref/
+- uart6m1_xfer: uart6m1-xfer {
+- rockchip,pins =
+- /* uart6_rx_m1 */
+- <1 RK_PA0 10 &pcfg_pull_up>,
+- /* uart6_tx_m1 */
+- <1 RK_PA1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m1_ctsn: uart6m1-ctsn {
+- rockchip,pins =
+- /* uart6m1_ctsn */
+- <1 RK_PA3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m1_rtsn: uart6m1-rtsn {
+- rockchip,pins =
+- /* uart6m1_rtsn */
+- <1 RK_PA2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m2_xfer: uart6m2-xfer {
+- rockchip,pins =
+- /* uart6_rx_m2 */
+- <1 RK_PD1 10 &pcfg_pull_up>,
+- /* uart6_tx_m2 */
+- <1 RK_PD0 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart7 {
+- /omit-if-no-ref/
+- uart7m1_xfer: uart7m1-xfer {
+- rockchip,pins =
+- /* uart7_rx_m1 */
+- <3 RK_PC1 10 &pcfg_pull_up>,
+- /* uart7_tx_m1 */
+- <3 RK_PC0 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m1_ctsn: uart7m1-ctsn {
+- rockchip,pins =
+- /* uart7m1_ctsn */
+- <3 RK_PC3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m1_rtsn: uart7m1-rtsn {
+- rockchip,pins =
+- /* uart7m1_rtsn */
+- <3 RK_PC2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m2_xfer: uart7m2-xfer {
+- rockchip,pins =
+- /* uart7_rx_m2 */
+- <1 RK_PB4 10 &pcfg_pull_up>,
+- /* uart7_tx_m2 */
+- <1 RK_PB5 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart8 {
+- /omit-if-no-ref/
+- uart8m0_xfer: uart8m0-xfer {
+- rockchip,pins =
+- /* uart8_rx_m0 */
+- <4 RK_PB1 10 &pcfg_pull_up>,
+- /* uart8_tx_m0 */
+- <4 RK_PB0 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m0_ctsn: uart8m0-ctsn {
+- rockchip,pins =
+- /* uart8m0_ctsn */
+- <4 RK_PB3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m0_rtsn: uart8m0-rtsn {
+- rockchip,pins =
+- /* uart8m0_rtsn */
+- <4 RK_PB2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m1_xfer: uart8m1-xfer {
+- rockchip,pins =
+- /* uart8_rx_m1 */
+- <3 RK_PA3 10 &pcfg_pull_up>,
+- /* uart8_tx_m1 */
+- <3 RK_PA2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m1_ctsn: uart8m1-ctsn {
+- rockchip,pins =
+- /* uart8m1_ctsn */
+- <3 RK_PA5 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m1_rtsn: uart8m1-rtsn {
+- rockchip,pins =
+- /* uart8m1_rtsn */
+- <3 RK_PA4 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8_xfer: uart8-xfer {
+- rockchip,pins =
+- /* uart8_rx_ */
+- <4 RK_PB1 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart9 {
+- /omit-if-no-ref/
+- uart9m0_xfer: uart9m0-xfer {
+- rockchip,pins =
+- /* uart9_rx_m0 */
+- <2 RK_PC4 10 &pcfg_pull_up>,
+- /* uart9_tx_m0 */
+- <2 RK_PC2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m1_xfer: uart9m1-xfer {
+- rockchip,pins =
+- /* uart9_rx_m1 */
+- <4 RK_PB5 10 &pcfg_pull_up>,
+- /* uart9_tx_m1 */
+- <4 RK_PB4 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m1_ctsn: uart9m1-ctsn {
+- rockchip,pins =
+- /* uart9m1_ctsn */
+- <4 RK_PA1 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m1_rtsn: uart9m1-rtsn {
+- rockchip,pins =
+- /* uart9m1_rtsn */
+- <4 RK_PA0 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m2_xfer: uart9m2-xfer {
+- rockchip,pins =
+- /* uart9_rx_m2 */
+- <3 RK_PD4 10 &pcfg_pull_up>,
+- /* uart9_tx_m2 */
+- <3 RK_PD5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m2_ctsn: uart9m2-ctsn {
+- rockchip,pins =
+- /* uart9m2_ctsn */
+- <3 RK_PD3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m2_rtsn: uart9m2-rtsn {
+- rockchip,pins =
+- /* uart9m2_rtsn */
+- <3 RK_PD2 10 &pcfg_pull_none>;
+- };
+- };
+-
+- vop {
+- /omit-if-no-ref/
+- vop_pins: vop-pins {
+- rockchip,pins =
+- /* vop_post_empty */
+- <1 RK_PA2 1 &pcfg_pull_none>;
+- };
+- };
+-};
+-
+-/*
+- * This part is edited handly.
+- */
+-&pinctrl {
+- bt656 {
+- /omit-if-no-ref/
+- bt656_pins: bt656-pins {
+- rockchip,pins =
+- /* bt1120_clkout */
+- <4 RK_PB0 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d0 */
+- <4 RK_PA0 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d1 */
+- <4 RK_PA1 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d2 */
+- <4 RK_PA2 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d3 */
+- <4 RK_PA3 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d4 */
+- <4 RK_PA4 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d5 */
+- <4 RK_PA5 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d6 */
+- <4 RK_PA6 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d7 */
+- <4 RK_PA7 2 &pcfg_pull_none_drv_level_2>;
+- };
+- };
+-
+- gpio-func {
+- /omit-if-no-ref/
+- tsadc_gpio_func: tsadc-gpio-func {
+- rockchip,pins =
+- <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+-};
diff --git a/target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch b/target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch
new file mode 100644
index 0000000000..1a18eb9358
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch
@@ -0,0 +1,193 @@
+From 510cd9e688453166b2bff3999ed21cac97385bb5 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:51 +0400
+Subject: [PATCH] arm64: dts: rockchip: add thermal zones information on RK3588
+
+This includes the necessary device tree data to allow thermal
+monitoring on RK3588(s) using the on-chip TSADC device, along with
+trip points for automatic thermal management.
+
+Each of the CPU clusters (one for the little cores and two for
+the big cores) get a passive cooling trip point at 85C, which
+will trigger DVFS throttling of the respective cluster upon
+reaching a high temperature condition.
+
+All zones also have a critical trip point at 115C, which will
+trigger a reset.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-1-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 153 ++++++++++++++++++
+ 1 file changed, 153 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -10,6 +10,7 @@
+ #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+ #include <dt-bindings/phy/phy.h>
+ #include <dt-bindings/ata/ahci.h>
++#include <dt-bindings/thermal/thermal.h>
+
+ / {
+ compatible = "rockchip,rk3588";
+@@ -2368,6 +2369,158 @@
+ status = "disabled";
+ };
+
++ thermal_zones: thermal-zones {
++ /* sensor near the center of the SoC */
++ package_thermal: package-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 0>;
++
++ trips {
++ package_crit: package-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++
++ /* sensor between A76 cores 0 and 1 */
++ bigcore0_thermal: bigcore0-thermal {
++ polling-delay-passive = <100>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 1>;
++
++ trips {
++ bigcore0_alert: bigcore0-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ bigcore0_crit: bigcore0-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&bigcore0_alert>;
++ cooling-device =
++ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
++ };
++
++ /* sensor between A76 cores 2 and 3 */
++ bigcore2_thermal: bigcore2-thermal {
++ polling-delay-passive = <100>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 2>;
++
++ trips {
++ bigcore2_alert: bigcore2-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ bigcore2_crit: bigcore2-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&bigcore2_alert>;
++ cooling-device =
++ <&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
++ };
++
++ /* sensor between the four A55 cores */
++ little_core_thermal: littlecore-thermal {
++ polling-delay-passive = <100>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 3>;
++
++ trips {
++ littlecore_alert: littlecore-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ littlecore_crit: littlecore-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&littlecore_alert>;
++ cooling-device =
++ <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
++ };
++
++ /* sensor near the PD_CENTER power domain */
++ center_thermal: center-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 4>;
++
++ trips {
++ center_crit: center-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++
++ gpu_thermal: gpu-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 5>;
++
++ trips {
++ gpu_crit: gpu-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++
++ npu_thermal: npu-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 6>;
++
++ trips {
++ npu_crit: npu-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++ };
++
+ tsadc: tsadc@fec00000 {
+ compatible = "rockchip,rk3588-tsadc";
+ reg = <0x0 0xfec00000 0x0 0x400>;
diff --git a/target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch b/target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch
new file mode 100644
index 0000000000..c7a8bb8aa9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch
@@ -0,0 +1,50 @@
+From b78f87940a79321a444083aca46ac3e8e53d1a90 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:53 +0400
+Subject: [PATCH] arm64: dts: rockchip: add passive GPU cooling on RK3588
+
+As the GPU support on RK3588 has been merged upstream, along with OPP
+values, add a corresponding cooling map for passive cooling using the GPU.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-3-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -2493,17 +2493,31 @@
+ };
+
+ gpu_thermal: gpu-thermal {
+- polling-delay-passive = <0>;
++ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 5>;
+
+ trips {
++ gpu_alert: gpu-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
+ gpu_crit: gpu-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
++
++ cooling-maps {
++ map0 {
++ trip = <&gpu_alert>;
++ cooling-device =
++ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
+ };
+
+ npu_thermal: npu-thermal {
diff --git a/target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch b/target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch
new file mode 100644
index 0000000000..cb5c254ffb
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch
@@ -0,0 +1,205 @@
+From 276856db91b46eaa7a4c19226c096a9dc899a3e9 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:56 +0400
+Subject: [PATCH] arm64: dts: rockchip: Add OPP data for CPU cores on RK3588
+
+By default the CPUs on RK3588 start up in a conservative performance
+mode. Add frequency and voltage mappings to the device tree to enable
+dynamic scaling via cpufreq.
+
+OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
+stripping them down to the minimum frequency and voltage combinations
+as expected by the generic upstream cpufreq-dt driver, and also dropping
+those OPPs that don't differ in voltage but only in frequency (keeping
+the top frequency OPP in each case).
+
+Note that this patch ignores voltage scaling for the CPU memory
+interface which the downstream kernel does through a custom cpufreq
+driver, and which is why the downstream version has two sets of voltage
+values for each OPP (the second one being meant for the memory
+interface supply regulator). This is done instead via regulator
+coupling between CPU and memory interface supplies on affected boards.
+
+This has been tested on Rock 5B with u-boot 2023.11 compiled from
+Collabora's integration tree [2] with binary bl31 and appears to be
+stable both under active cooling and passive cooling (with throttling)
+
+[1] https://github.com/radxa/kernel/blob/stable-5.10-rock5/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+[2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/u-boot
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-6-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi | 149 +++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 1 +
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 1 +
+ 3 files changed, 151 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
+@@ -0,0 +1,149 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/ {
++ cluster0_opp_table: opp-table-cluster0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1008000000 {
++ opp-hz = /bits/ 64 <1008000000>;
++ opp-microvolt = <675000 675000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <712500 712500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <762500 762500 950000>;
++ clock-latency-ns = <40000>;
++ opp-suspend;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <850000 850000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <950000 950000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster1_opp_table: opp-table-cluster1 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <675000 675000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <725000 725000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <762500 762500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <850000 850000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <925000 925000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2208000000 {
++ opp-hz = /bits/ 64 <2208000000>;
++ opp-microvolt = <987500 987500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2400000000 {
++ opp-hz = /bits/ 64 <2400000000>;
++ opp-microvolt = <1000000 1000000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster2_opp_table: opp-table-cluster2 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <675000 675000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <725000 725000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <762500 762500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <850000 850000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <925000 925000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2208000000 {
++ opp-hz = /bits/ 64 <2208000000>;
++ opp-microvolt = <987500 987500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2400000000 {
++ opp-hz = /bits/ 64 <2400000000>;
++ opp-microvolt = <1000000 1000000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++};
++
++&cpu_b0 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b1 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b2 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_b3 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_l0 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l1 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l2 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l3 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -5,3 +5,4 @@
+ */
+
+ #include "rk3588-extra.dtsi"
++#include "rk3588-opp.dtsi"
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -5,3 +5,4 @@
+ */
+
+ #include "rk3588-base.dtsi"
++#include "rk3588-opp.dtsi"
diff --git a/target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch b/target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch
new file mode 100644
index 0000000000..3b39a60ade
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch
@@ -0,0 +1,140 @@
+From 667885a6865832eb0678c7e02e47a3392f177ecb Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:57 +0400
+Subject: [PATCH] arm64: dts: rockchip: Add OPP data for CPU cores on RK3588j
+
+RK3588j is the 'industrial' variant of RK3588, and it uses a different
+set of OPPs both in terms of allowed frequencies and in terms of
+applicable voltages at each frequency setpoint.
+
+Add the OPPs that apply to RK3588j (and apparently RK3588m too) to
+enable dynamic CPU frequency scaling.
+
+OPP values are derived from Rockchip downstream sources [1] by taking
+only those OPPs which have the highest frequency for a given voltage
+level and dropping the rest (if they are included, the kernel complains
+at boot time about them being inefficient)
+
+[1] https://github.com/rockchip-linux/kernel/blob/604cec4004abe5a96c734f2fab7b74809d2d742f/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-7-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588j.dtsi | 108 ++++++++++++++++++++++
+ 1 file changed, 108 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+@@ -5,3 +5,111 @@
+ */
+
+ #include "rk3588-extra.dtsi"
++
++/ {
++ cluster0_opp_table: opp-table-cluster0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ opp-suspend;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <887500 887500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1704000000 {
++ opp-hz = /bits/ 64 <1704000000>;
++ opp-microvolt = <937500 937500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster1_opp_table: opp-table-cluster1 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <787500 787500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <875000 875000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <950000 950000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster2_opp_table: opp-table-cluster2 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <787500 787500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <875000 875000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <950000 950000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++};
++
++&cpu_b0 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b1 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b2 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_b3 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_l0 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l1 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l2 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l3 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
diff --git a/target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch b/target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch
new file mode 100644
index 0000000000..06befc8af9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch
@@ -0,0 +1,177 @@
+From a7b2070505a2a09ea65fa0c8c480c97f62d1978d Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:58 +0400
+Subject: [PATCH] arm64: dts: rockchip: Split GPU OPPs of RK3588 and RK3588j
+
+RK3588j uses a different set of OPPs for its GPU, both in terms of
+allowed frequencies and in terms of voltages.
+
+Move the GPU OPPs table into per-variant .dtsi files to accommodate
+for this difference.
+
+The table for RK3588j is adapted from Rockchip downstream sources [1],
+while RK3588 one is moved verbatim into the per-variant .dtsi file.
+The values provided for RK3588 in the downstream sources match those
+in the original commit.
+
+[1] https://github.com/rockchip-linux/kernel/blob/604cec4004abe5a96c734f2fab7b74809d2d742f/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+
+Fixes: 6fca4edb93d3 ("arm64: dts: rockchip: Add rk3588 GPU node")
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-8-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 38 -----------------
+ arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi | 41 +++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588j.dtsi | 33 +++++++++++++++
+ 3 files changed, 74 insertions(+), 38 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -451,46 +451,8 @@
+ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "job", "mmu", "gpu";
+- operating-points-v2 = <&gpu_opp_table>;
+ power-domains = <&power RK3588_PD_GPU>;
+ status = "disabled";
+-
+- gpu_opp_table: opp-table {
+- compatible = "operating-points-v2";
+-
+- opp-300000000 {
+- opp-hz = /bits/ 64 <300000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-400000000 {
+- opp-hz = /bits/ 64 <400000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-500000000 {
+- opp-hz = /bits/ 64 <500000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-600000000 {
+- opp-hz = /bits/ 64 <600000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-700000000 {
+- opp-hz = /bits/ 64 <700000000>;
+- opp-microvolt = <700000 700000 850000>;
+- };
+- opp-800000000 {
+- opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <750000 750000 850000>;
+- };
+- opp-900000000 {
+- opp-hz = /bits/ 64 <900000000>;
+- opp-microvolt = <800000 800000 850000>;
+- };
+- opp-1000000000 {
+- opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <850000 850000 850000>;
+- };
+- };
+ };
+
+ usb_host0_xhci: usb@fc000000 {
+--- a/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
+@@ -114,6 +114,43 @@
+ clock-latency-ns = <40000>;
+ };
+ };
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
+ };
+
+ &cpu_b0 {
+@@ -147,3 +184,7 @@
+ &cpu_l3 {
+ operating-points-v2 = <&cluster0_opp_table>;
+ };
++
++&gpu {
++ operating-points-v2 = <&gpu_opp_table>;
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+@@ -80,6 +80,35 @@
+ clock-latency-ns = <40000>;
+ };
+ };
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-850000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <787500 787500 850000>;
++ };
++ };
+ };
+
+ &cpu_b0 {
+@@ -113,3 +142,7 @@
+ &cpu_l3 {
+ operating-points-v2 = <&cluster0_opp_table>;
+ };
++
++&gpu {
++ operating-points-v2 = <&gpu_opp_table>;
++};
diff --git a/target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch b/target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch
new file mode 100644
index 0000000000..a9bf3986e2
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch
@@ -0,0 +1,39 @@
+From 0773a4a199aabb60afe50f5a19a6772abf4ad0bf Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 6 Nov 2023 16:54:32 +0100
+Subject: [PATCH] arm64: dts: rockchip: add USB3 host to rock-5a
+
+Enable USB3 host controller for the Radxa ROCK 5 Model A. This adds
+USB3 for the lower USB3 port (the one closer to the PCB).
+
+The upper USB3 port uses the RK3588 USB TypeC host controller, which
+use a different PHY without upstream support.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231106155934.80838-2-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -113,6 +113,10 @@
+ };
+ };
+
++&combphy2_psu {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -734,3 +738,7 @@
+ &usb_host1_ohci {
+ status = "okay";
+ };
++
++&usb_host2_xhci {
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch b/target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch
new file mode 100644
index 0000000000..5c1ebb85ea
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch
@@ -0,0 +1,56 @@
+From af7ec140ddc1815bc462109792d95bcad05cfbc4 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:36 +0200
+Subject: [PATCH] arm64: dts: rockchip: add upper USB3 port to rock-5a
+
+Enable full support (XHCI, EHCI, OHCI) for the upper USB3 port from
+Radxa Rock 5 Model A. The lower one is already supported.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-10-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588s-rock-5a.dts | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -698,6 +698,14 @@
+ };
+ };
+
++&u2phy0 {
++ status = "okay";
++};
++
++&u2phy0_otg {
++ status = "okay";
++};
++
+ &u2phy2 {
+ status = "okay";
+ };
+@@ -721,6 +729,11 @@
+ status = "okay";
+ };
+
++&usbdp_phy0 {
++ status = "okay";
++ rockchip,dp-lane-mux = <2 3>;
++};
++
+ &usb_host0_ehci {
+ status = "okay";
+ pinctrl-names = "default";
+@@ -731,6 +744,11 @@
+ status = "okay";
+ };
+
++&usb_host0_xhci {
++ dr_mode = "host";
++ status = "okay";
++};
++
+ &usb_host1_ehci {
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch b/target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch
new file mode 100644
index 0000000000..b71246f0ad
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch
@@ -0,0 +1,45 @@
+From 00224650dd45e166ea6eb1593f5f064583963ccf Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Sun, 23 Jun 2024 11:33:28 +0900
+Subject: [PATCH] arm64: dts: rockchip: add (but disabled) SFC node for Radxa
+ ROCK 5A
+
+This commit adds SFC node for Radxa ROCK 5A.
+
+since sdhci and sfc on RK3588s share pins(i.e. exclusive), it cannot
+be enabled both nodes at the same time. so status = "okay" is omitted
+here.
+
+you may be able to enable sfc (and disable sdhci) by fdt overlay.
+
+SPI NOR flash chip may vary, so use safe(lowest) spi-max-frequency.
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240623023329.1044-2-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -376,6 +376,19 @@
+ status = "okay";
+ };
+
++&sfc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&fspim0_pins>;
++
++ 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>;
diff --git a/target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch b/target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch
new file mode 100644
index 0000000000..e4fe686da9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch
@@ -0,0 +1,110 @@
+From b728d4c51f0ce9207daf502f3a85073785c46319 Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Mon, 26 Aug 2024 17:04:56 +0900
+Subject: [PATCH] arm64: dts: rockchip: enable PCIe on M.2 E key for Radxa ROCK
+ 5A
+
+Enable pcie2x1l2 and related combphy/regulator routed to M.2 E key
+connector on Radxa ROCK 5A.
+
+Tested with Radxa Wireless Module A8:
+
+$ lspci
+0004:40:00.0 PCI bridge: Rockchip Electronics Co., Ltd RK3588 (rev 01)
+0004:41:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8852BE PCIe 802.11ax Wireless Network Controller
+
+$ ip l
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+2: end0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
+ link/ether c2:58:fc:70:55:86 brd ff:ff:ff:ff:ff:ff
+3: wlP4p65s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
+ link/ether 2c:05:47:65:5b:ed brd ff:ff:ff:ff:ff:ff
+
+$ lsusb
+Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
+Bus 001 Device 003: ID 0bda:b85b Realtek Semiconductor Corp. Bluetooth Radio
+Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
+Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
+Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
+Bus 006 Device 002: ID 0789:0336 Logitec Corp. LMD USB Device
+Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
+
+$ hciconfig
+hci0: Type: Primary Bus: USB
+ BD Address: 2C:05:47:65:5B:EE ACL MTU: 1021:6 SCO MTU: 255:12
+ UP RUNNING
+ RX bytes:2698 acl:0 sco:0 events:329 errors:0
+ TX bytes:69393 acl:0 sco:0 commands:329 errors:0
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240826080456.525-1-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588s-rock-5a.dts | 30 +++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -64,6 +64,18 @@
+ regulator-max-microvolt = <12000000>;
+ };
+
++ vcc3v3_wf: vcc3v3-wf-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_wf";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ enable-active-high;
++ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
++ pinctrl-0 = <&pow_en>;
++ pinctrl-names = "default";
++ vin-supply = <&vcc5v0_sys>;
++ };
++
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+@@ -113,6 +125,10 @@
+ };
+ };
+
++&combphy0_ps {
++ status = "okay";
++};
++
+ &combphy2_psu {
+ status = "okay";
+ };
+@@ -292,6 +308,14 @@
+ };
+ };
+
++&pcie2x1l2 {
++ pinctrl-0 = <&pcie20x1m0_pins>;
++ pinctrl-names = "default";
++ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_wf>;
++ status = "okay";
++};
++
+ &pinctrl {
+ leds {
+ io_led: io-led {
+@@ -299,6 +323,12 @@
+ };
+ };
+
++ pcie {
++ pow_en: pow-en {
++ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ power {
+ vcc_5v0_en: vcc-5v0-en {
+ rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch
new file mode 100644
index 0000000000..7ce349d5d8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch
@@ -0,0 +1,72 @@
+From 42145b7a823530f57983fb6e6897f40c0be278d5 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 18 Sep 2023 16:14:49 +0200
+Subject: [PATCH] arm64: dts: rockchip: add PCIe network controller to rock-5b
+
+Enable the RTL8125 network controller, which is connected via
+PCIe.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230918141451.131247-2-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 27 +++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -43,6 +43,15 @@
+ #cooling-cells = <2>;
+ };
+
++ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_pcie2x1l2";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <5000>;
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+@@ -77,6 +86,10 @@
+ };
+ };
+
++&combphy0_ps {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -203,6 +216,14 @@
+ };
+ };
+
++&pcie2x1l2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie2_2_rst>;
++ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
++ status = "okay";
++};
++
+ &pinctrl {
+ hym8563 {
+ hym8563_int: hym8563-int {
+@@ -216,6 +237,12 @@
+ };
+ };
+
++ pcie2 {
++ pcie2_2_rst: pcie2-2-rst {
++ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch
new file mode 100644
index 0000000000..456474cb86
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch
@@ -0,0 +1,73 @@
+From 199cbd5f195adbc0e70ad218cdba82f45750f11b Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 18 Sep 2023 16:14:50 +0200
+Subject: [PATCH] arm64: dts: rockchip: add PCIe for M.2 M-key to rock-5b
+
+The Radxa Rock 5B has PCIe 3x4 routed to its M.2 M-key connector
+on the board's back.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230918141451.131247-3-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 35 +++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -52,6 +52,19 @@
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
++ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
++ 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: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+@@ -224,6 +237,18 @@
+ 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 {
+@@ -243,6 +268,16 @@
+ };
+ };
+
++ 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>;
diff --git a/target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch
new file mode 100644
index 0000000000..349a17eb77
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch
@@ -0,0 +1,80 @@
+From da447ec387800bdf2df1fb1d8c1522991d025952 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 18 Sep 2023 16:14:51 +0200
+Subject: [PATCH] arm64: dts: rockchip: add PCIe for M.2 E-Key to rock-5b
+
+Enable PCIe2_0 controller and its voltage supply, which is routed
+to the M.2 E-Key on the upper side of the Radxa Rock 5B.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230918141451.131247-4-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 35 +++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -43,6 +43,21 @@
+ #cooling-cells = <2>;
+ };
+
++ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
++ 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: vcc3v3-pcie2x1l2-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l2";
+@@ -103,6 +118,10 @@
+ status = "okay";
+ };
+
++&combphy1_ps {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -229,6 +248,14 @@
+ };
+ };
+
++&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>;
+@@ -263,6 +290,14 @@
+ };
+
+ 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>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch
new file mode 100644
index 0000000000..cdf555f450
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch
@@ -0,0 +1,93 @@
+From 1c9a53ff7ece056eb995332f0d9523ca43fdcb5a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tam=C3=A1s=20Sz=C5=B1cs?= <tszucs@protonmail.ch>
+Date: Sun, 24 Sep 2023 20:37:45 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add sdio node to rock-5b
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Enable SDIO on Radxa ROCK 5 Model B M.2 Key E. Add sdio node and alias as mmc2.
+Add regulator for the 3.3 V rail bringing it up during boot. Make sure EKEY_EN
+is muxed as GPIO.
+
+Signed-off-by: Tamás Szűcs <tszucs@protonmail.ch>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230924203740.65744-1-tszucs@protonmail.ch
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 43 +++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -12,6 +12,7 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
++ mmc2 = &sdio;
+ };
+
+ chosen {
+@@ -112,6 +113,21 @@
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
++
++ vcc3v3_wf: vcc3v3-wf-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_wf";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ enable-active-high;
++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc3v3_wf_en>;
++ startup-delay-us = <50000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
+ };
+
+ &combphy0_ps {
+@@ -318,6 +334,12 @@
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
++
++ m2e {
++ vcc3v3_wf_en: vcc3v3-wf-en {
++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
+ };
+
+ &pwm1 {
+@@ -354,6 +376,27 @@
+ status = "okay";
+ };
+
++&sdio {
++ max-frequency = <200000000>;
++ no-sd;
++ no-mmc;
++ non-removable;
++ bus-width = <4>;
++ cap-sdio-irq;
++ disable-wp;
++ keep-power-in-suspend;
++ wakeup-source;
++ sd-uhs-sdr12;
++ sd-uhs-sdr25;
++ sd-uhs-sdr50;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc3v3_wf>;
++ vqmmc-supply = <&vcc_1v8_s3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdiom0_pins>;
++ status = "okay";
++};
++
+ &spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
diff --git a/target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch b/target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch
new file mode 100644
index 0000000000..3d1283d31f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch
@@ -0,0 +1,65 @@
+From 0002c377e862140ad65b67b8b9dbf086d4578f95 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tam=C3=A1s=20Sz=C5=B1cs?= <tszucs@protonmail.ch>
+Date: Wed, 11 Oct 2023 18:18:05 +0000
+Subject: [PATCH] arm64: dts: rockchip: Remove duplicate regulator vcc3v3_wf
+ from rock-5b
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Regulator for VCC3V3_WF has been added as vcc3v3_pcie2x1l0 first. Clean this up.
+
+Fixes: 1c9a53ff7ece ("arm64: dts: rockchip: Add sdio node to rock-5b")
+Signed-off-by: Tamás Szűcs <tszucs@protonmail.ch>
+Link: https://lore.kernel.org/r/20231011181757.58047-1-tszucs@protonmail.ch
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 23 +------------------
+ 1 file changed, 1 insertion(+), 22 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -113,21 +113,6 @@
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+-
+- vcc3v3_wf: vcc3v3-wf-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc3v3_wf";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- enable-active-high;
+- gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&vcc3v3_wf_en>;
+- startup-delay-us = <50000>;
+- vin-supply = <&vcc5v0_sys>;
+- };
+ };
+
+ &combphy0_ps {
+@@ -334,12 +319,6 @@
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+-
+- m2e {
+- vcc3v3_wf_en: vcc3v3-wf-en {
+- rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+ };
+
+ &pwm1 {
+@@ -390,7 +369,7 @@
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+- vmmc-supply = <&vcc3v3_wf>;
++ vmmc-supply = <&vcc3v3_pcie2x1l0>;
+ vqmmc-supply = <&vcc_1v8_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdiom0_pins>;
diff --git a/target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch
new file mode 100644
index 0000000000..41c108f01a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch
@@ -0,0 +1,32 @@
+From a6169ab369236f15c79b45037074a2567d30b037 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tam=C3=A1s=20Sz=C5=B1cs?= <szucst@iit.uni-miskolc.hu>
+Date: Fri, 13 Oct 2023 23:51:53 +0200
+Subject: [PATCH] arm64: dts: rockchip: Enable UART6 on rock-5b
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Enable UART lines on Radxa ROCK 5 Model B M.2 Key E.
+
+Signed-off-by: Tamás Szűcs <szucst@iit.uni-miskolc.hu>
+Link: https://lore.kernel.org/r/20231013215208.81345-1-szucst@iit.uni-miskolc.hu
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -376,6 +376,12 @@
+ status = "okay";
+ };
+
++&uart6 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
++ status = "okay";
++};
++
+ &spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
diff --git a/target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch
new file mode 100644
index 0000000000..03d1ed860f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch
@@ -0,0 +1,57 @@
+From 7952cbbda301f7d297c6ac761f9dfafb90205358 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Thu, 5 Oct 2023 15:40:37 +0200
+Subject: [PATCH] arm64: dts: rockchip: add status LED to rock-5b
+
+Describe the Rock 5B status LED in its device tree.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231005134037.33231-1-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 20 +++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -3,6 +3,7 @@
+ /dts-v1/;
+
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
+ #include "rk3588.dtsi"
+
+ / {
+@@ -36,6 +37,19 @@
+ pinctrl-0 = <&hp_detect>;
+ };
+
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&led_rgb_b>;
++
++ led_rgb_b {
++ function = LED_FUNCTION_STATUS;
++ color = <LED_COLOR_ID_BLUE>;
++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 95 145 195 255>;
+@@ -284,6 +298,12 @@
+ };
+ };
+
++ 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>;
diff --git a/target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch
new file mode 100644
index 0000000000..b288ba858b
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch
@@ -0,0 +1,39 @@
+From f97d78b9f6cff4c680206a8c8b03f726f0dc2c8b Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 6 Nov 2023 16:54:31 +0100
+Subject: [PATCH] arm64: dts: rockchip: add USB3 host to rock-5b
+
+Enable USB3 host controller for the Radxa ROCK 5 Model B. This adds
+USB3 for the upper USB3 port (the one further away from the PCB).
+
+The lower USB3 and the USB-C ports use the RK3588 USB TypeC host
+controller, which use a different PHY without upstream support.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231106155934.80838-1-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -137,6 +137,10 @@
+ status = "okay";
+ };
+
++&combphy2_psu {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -764,3 +768,7 @@
+ &usb_host1_ohci {
+ status = "okay";
+ };
++
++&usb_host2_xhci {
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch
new file mode 100644
index 0000000000..a1d2b7fe10
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch
@@ -0,0 +1,31 @@
+From 7738f551173540b3daa63a91b384b167eacd24fd Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Mon, 25 Dec 2023 22:28:19 +0000
+Subject: [PATCH] arm64: dts: rockchip: support poweroff on the rock-5b
+
+Allow the rock-5b to poweroff its pmic. When issuing a "shutdown -h now"
+on the rock-5b it reboots instead. Defining 'system-power-controller'
+allows the rk806 to power down.
+
+Commit c699fbfdfd54 ("arm64: dts: rockchip: Support poweroff on
+NanoPC-T6") similarly resolves this issue for the nanopc-t6.
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231225222859.17153-1-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -426,6 +426,8 @@
+ 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>;
diff --git a/target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch
new file mode 100644
index 0000000000..616f7a742f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch
@@ -0,0 +1,27 @@
+From aed6514c4e3aee843385ded4c5ee0921b51c30fa Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Mon, 25 Dec 2023 22:28:20 +0000
+Subject: [PATCH] arm64: dts: rockchip: correct gpio_pwrctrl1 typo on rock-5b
+
+Both rk806_dvs1_null and rk806_dvs2_null duplicate gpio_pwrctrl2 and
+gpio_pwrctrl1 is not set. This patch sets gpio_pwrctrl1.
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231225222859.17153-2-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -448,7 +448,7 @@
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+- pins = "gpio_pwrctrl2";
++ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch b/target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch
new file mode 100644
index 0000000000..31ca0b8479
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch
@@ -0,0 +1,34 @@
+From 82d40b141a4c7ab6608a84a5ce0c58b747cb7163 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Sun, 7 Jan 2024 00:26:45 +0400
+Subject: [PATCH] arm64: dts: rockchip: add rfkill node for M.2 Key E WiFi on rock-5b
+
+By default the GPIO pin that connects to the WiFi enable signal
+inside the M.2 Key E slot is driven low, resulting in impossibility
+to connect to any network. Add a DT node to expose it as an RFKILL
+device, which lets the WiFi driver or userspace toggle it as
+required.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240106202650.22310-1-alchark@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -58,6 +58,13 @@
+ #cooling-cells = <2>;
+ };
+
++ rfkill {
++ compatible = "rfkill-gpio";
++ label = "rfkill-pcie-wlan";
++ radio-type = "wlan";
++ shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
++ };
++
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
diff --git a/target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch b/target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch
new file mode 100644
index 0000000000..69c0c2551e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch
@@ -0,0 +1,29 @@
+From 038347286941148b6fd0cc2c40afcd540315aa6f Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@collabora.com>
+Date: Tue, 26 Mar 2024 17:52:07 +0100
+Subject: [PATCH] arm64: dts: rockchip: Enable GPU on rk3588-rock5b
+
+Enable the Mali GPU in the Rock 5B.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240326165232.73585-4-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -180,6 +180,11 @@
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ };
+
++&gpu {
++ mali-supply = <&vdd_gpu_s0>;
++ status = "okay";
++};
++
+ &i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
diff --git a/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch
new file mode 100644
index 0000000000..99e98a8655
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch
@@ -0,0 +1,43 @@
+From 45e831033f7a00a14f64afa1e34c476a9ff0f9f0 Mon Sep 17 00:00:00 2001
+From: Dragan Simic <dsimic@manjaro.org>
+Date: Thu, 18 Apr 2024 18:26:20 +0200
+Subject: [PATCH] arm64: dts: rockchip: Correct the model names for Radxa ROCK
+ 5 boards
+
+Correct the descriptions of a few Radxa boards, according to the up-to-date
+documentation from Radxa and the detailed explanation from Naoki. [1] To sum
+it up, the short naming, as specified by Radxa, is preferred.
+
+[1] https://lore.kernel.org/linux-rockchip/B26C732A4DCEA9B3+282b8775-601b-4d4a-a513-4924b7940076@radxa.com/
+
+Suggested-by: FUKAUMI Naoki <naoki@radxa.com>
+Signed-off-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/6931289a252dc2d6c7bfd2388835c5e98ba0d8c9.1713457260.git.dsimic@manjaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 2 +-
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -7,7 +7,7 @@
+ #include "rk3588.dtsi"
+
+ / {
+- model = "Radxa ROCK 5 Model B";
++ model = "Radxa ROCK 5B";
+ compatible = "radxa,rock-5b", "rockchip,rk3588";
+
+ aliases {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -8,7 +8,7 @@
+ #include "rk3588s.dtsi"
+
+ / {
+- model = "Radxa ROCK 5 Model A";
++ model = "Radxa ROCK 5A";
+ compatible = "radxa,rock-5a", "rockchip,rk3588s";
+
+ aliases {
diff --git a/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch
new file mode 100644
index 0000000000..8a3fab1576
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch
@@ -0,0 +1,55 @@
+From 494532921aacb496529d544fedfdb3a7b43dfef0 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:37 +0200
+Subject: [PATCH] arm64: dts: rockchip: add lower USB3 port to rock-5b
+
+Enable full support (XHCI, EHCI, OHCI) for the lower USB3 port from
+Radxa Rock 5 Model B. The upper one is already supported.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-11-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -748,6 +748,14 @@
+ status = "okay";
+ };
+
++&u2phy1 {
++ status = "okay";
++};
++
++&u2phy1_otg {
++ status = "okay";
++};
++
+ &u2phy2 {
+ status = "okay";
+ };
+@@ -767,6 +775,10 @@
+ status = "okay";
+ };
+
++&usbdp_phy1 {
++ status = "okay";
++};
++
+ &usb_host0_ehci {
+ status = "okay";
+ };
+@@ -783,6 +795,11 @@
+ status = "okay";
+ };
+
++&usb_host1_xhci {
++ dr_mode = "host";
++ status = "okay";
++};
++
+ &usb_host2_xhci {
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch b/target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch
new file mode 100644
index 0000000000..0b2d0a3dec
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch
@@ -0,0 +1,67 @@
+From 4a152231b050590af771fa3cc8462ed08b691a24 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:54 +0400
+Subject: [PATCH] arm64: dts: rockchip: enable automatic fan control on Rock 5B
+
+This links the PWM fan on Radxa Rock 5B as an active cooling device
+managed automatically by the thermal subsystem, with a target SoC
+temperature of 65C and a minimum-spin interval from 55C to 65C to
+ensure airflow when the system gets warm
+
+Helped-by: Dragan Simic <dsimic@manjaro.org>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-4-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 32 ++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -52,7 +52,7 @@
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+- cooling-levels = <0 95 145 195 255>;
++ cooling-levels = <0 120 150 180 210 240 255>;
+ fan-supply = <&vcc5v0_sys>;
+ pwms = <&pwm1 0 50000 0>;
+ #cooling-cells = <2>;
+@@ -278,6 +278,36 @@
+ };
+ };
+ };
++
++&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 {
++ map1 {
++ trip = <&package_fan0>;
++ cooling-device = <&fan THERMAL_NO_LIMIT 1>;
++ };
++
++ map2 {
++ trip = <&package_fan1>;
++ cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
++ };
++ };
++};
+
+ &pcie2x1l0 {
+ pinctrl-names = "default";
diff --git a/target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch b/target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch
new file mode 100644
index 0000000000..043b983877
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch
@@ -0,0 +1,39 @@
+From 9204a7ecca96403ee3d61c14cb9eb87ec89b0fcd Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Sun, 23 Jun 2024 11:33:27 +0900
+Subject: [PATCH] arm64: dts: rockchip: add SFC support for Radxa ROCK 5B
+
+This commit adds support for SPI NOR flash on Radxa ROCK 5B.
+
+SPI NOR flash chip may vary, so use safe(lowest) spi-max-frequency.
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240623023329.1044-1-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -442,6 +442,20 @@
+ 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>;
diff --git a/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch b/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch
new file mode 100644
index 0000000000..d0243023fc
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch
@@ -0,0 +1,792 @@
+From f1b11f43b3e983b26d8010fc43ba6c2b979826f2 Mon Sep 17 00:00:00 2001
+From: Muhammed Efe Cetin <efectn@protonmail.com>
+Date: Sat, 30 Dec 2023 14:18:00 +0300
+Subject: [PATCH] arm64: dts: rockchip: Add support for NanoPi R6S
+
+Add basic NanoPi R6S support that comes with USB2, PCIe, SD card, eMMC
+support.
+
+Signed-off-by: Muhammed Efe Cetin <efectn@protonmail.com>
+Link: https://lore.kernel.org/r/6db3b653efc6f0a2dca8e96fdd0503906db72fb6.1703934548.git.efectn@protonmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../boot/dts/rockchip/rk3588s-nanopi-r6s.dts | 764 ++++++++++++++++++
+ 2 files changed, 765 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -108,4 +108,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-na
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
+@@ -0,0 +1,764 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include "rk3588s.dtsi"
++
++/ {
++ model = "FriendlyElec NanoPi R6S";
++ compatible = "friendlyarm,nanopi-r6s", "rockchip,rk3588s";
++
++ aliases {
++ ethernet0 = &gmac1;
++ mmc0 = &sdmmc;
++ mmc1 = &sdhci;
++ };
++
++ 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-maskrom {
++ label = "Maskrom";
++ linux,code = <KEY_VENDOR>;
++ press-threshold-microvolt = <1800>;
++ };
++ };
++
++ gpio-keys {
++ compatible = "gpio-keys";
++ pinctrl-names = "default";
++ pinctrl-0 = <&key1_pin>;
++
++ button-user {
++ label = "User";
++ linux,code = <BTN_1>;
++ gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
++ debounce-interval = <50>;
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ sys_led: led-0 {
++ label = "sys_led";
++ gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ pinctrl-names = "default";
++ pinctrl-0 = <&sys_led_pin>;
++ };
++
++ wan_led: led-1 {
++ label = "wan_led";
++ gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&wan_led_pin>;
++ };
++
++ lan1_led: led-2 {
++ label = "lan1_led";
++ gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&lan1_led_pin>;
++ };
++
++ lan2_led: led-3 {
++ label = "lan2_led";
++ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&lan2_led_pin>;
++ };
++ };
++
++ vcc5v0_sys: vcc5v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_1v1_nldo_s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1100000>;
++ regulator-max-microvolt = <1100000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc_3v3_s0: vcc-3v3-s0-regulator {
++ 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: vcc-3v3-sd-s0-regulator {
++ 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: 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>;
++ };
++
++ 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_usb_otg0: vcc5v0-usb-otg0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio1 RK_PD2 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>;
++ };
++
++ vcc5v0_host_20: vcc5v0-host-20-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&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>;
++ };
++};
++
++&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";
++};
++
++&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 = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
++ wakeup-source;
++ };
++};
++
++&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 {
++ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc_3v3_pcie20>;
++ status = "okay";
++};
++
++&pinctrl {
++ gpio-key {
++ key1_pin: key1-pin {
++ rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ gpio-leds {
++ sys_led_pin: sys-led-pin {
++ rockchip,pins =
++ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wan_led_pin: wan-led-pin {
++ rockchip,pins =
++ <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ lan1_led_pin: lan1-led-pin {
++ rockchip,pins =
++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ lan2_led_pin: lan2-led-pin {
++ rockchip,pins =
++ <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ 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 = <1 RK_PD2 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;
++ 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";
++};
++
++&u2phy2 {
++ status = "okay";
++};
++
++&u2phy2_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";
++};
diff --git a/target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch b/target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch
new file mode 100644
index 0000000000..7e2b083cf8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch
@@ -0,0 +1,42 @@
+From d5f1d7437451dbd86a91747793ecd7842e0ce88f Mon Sep 17 00:00:00 2001
+From: Muhammed Efe Cetin <efectn@protonmail.com>
+Date: Sat, 30 Dec 2023 14:18:01 +0300
+Subject: [PATCH] arm64: dts: rockchip: Add support for NanoPi R6C
+
+NanoPi R6C is mostly same as R6S variant. It has M2 port instead of a
+NIC port and different led labeling.
+
+Signed-off-by: Muhammed Efe Cetin <efectn@protonmail.com>
+Link: https://lore.kernel.org/r/0f9ee0baa6c9de4d54dd6d13957ca15a63ec934f.1703934548.git.efectn@protonmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts | 14 ++++++++++++++
+ 2 files changed, 15 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -109,4 +109,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-ro
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
+@@ -0,0 +1,14 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include "rk3588s-nanopi-r6s.dts"
++
++/ {
++ model = "FriendlyElec NanoPi R6C";
++ compatible = "friendlyarm,nanopi-r6c", "rockchip,rk3588s";
++};
++
++&lan2_led {
++ label = "user_led";
++};
diff --git a/target/linux/rockchip/patches-6.6/055-01-v6.8-arm64-dts-rockchip-Support-poweroff-on-NanoPC-T6.patch b/target/linux/rockchip/patches-6.6/055-01-v6.8-arm64-dts-rockchip-Support-poweroff-on-NanoPC-T6.patch
new file mode 100644
index 0000000000..e8c9924e86
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-01-v6.8-arm64-dts-rockchip-Support-poweroff-on-NanoPC-T6.patch
@@ -0,0 +1,26 @@
+From c699fbfdfd54630fc51b96da577f02e7b772eb37 Mon Sep 17 00:00:00 2001
+From: Hugh Cole-Baker <sigmaris@gmail.com>
+Date: Sat, 16 Dec 2023 21:21:34 +0000
+Subject: [PATCH] arm64: dts: rockchip: Support poweroff on NanoPC-T6
+
+The RK806 on the NanoPC-T6 can be used to power on/off the whole board.
+Mark it as the system power controller.
+
+Signed-off-by: Hugh Cole-Baker <sigmaris@gmail.com>
+Link: https://lore.kernel.org/r/20231216212134.23314-1-sigmaris@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -569,6 +569,8 @@
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
++ system-power-controller;
++
+ vcc1-supply = <&vcc4v0_sys>;
+ vcc2-supply = <&vcc4v0_sys>;
+ vcc3-supply = <&vcc4v0_sys>;
diff --git a/target/linux/rockchip/patches-6.6/055-02-v6.9-arm64-dts-rockchip-nanopc-t6-sdmmc-beautification.patch b/target/linux/rockchip/patches-6.6/055-02-v6.9-arm64-dts-rockchip-nanopc-t6-sdmmc-beautification.patch
new file mode 100644
index 0000000000..3f5dd481c9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-02-v6.9-arm64-dts-rockchip-nanopc-t6-sdmmc-beautification.patch
@@ -0,0 +1,33 @@
+From 9e1faff1cbc877903d019a7943d37ddc5042704d Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Thu, 28 Dec 2023 17:29:35 +0000
+Subject: [PATCH] arm64: dts: rockchip: nanopc-t6 sdmmc beautification
+
+drop max-frequency = <200000000> as it is already defined in rk3588s.dtsi
+order no-sdio & no-mmc properties while we are here
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Link: https://lore.kernel.org/r/20231228173011.2863-1-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -536,13 +536,12 @@
+ };
+
+ &sdmmc {
+- max-frequency = <200000000>;
+- no-sdio;
+- no-mmc;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
++ no-mmc;
++ no-sdio;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
diff --git a/target/linux/rockchip/patches-6.6/055-03-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-nanopc-t.patch b/target/linux/rockchip/patches-6.6/055-03-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-nanopc-t.patch
new file mode 100644
index 0000000000..beab9154f8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-03-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-nanopc-t.patch
@@ -0,0 +1,26 @@
+From 24559788384916041a0bbf54c32e2a16b612d247 Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Mon, 25 Dec 2023 22:32:16 +0000
+Subject: [PATCH] arm64: dts: rockchip: correct gpio_pwrctrl1 typo on nanopc-t6
+
+Both rk806_dvs1_null and rk806_dvs2_null duplicate gpio_pwrctrl2 and
+gpio_pwrctrl1 is not set. This patch sets gpio_pwrctrl1.
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Link: https://lore.kernel.org/r/20231225223226.17690-1-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -590,7 +590,7 @@
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+- pins = "gpio_pwrctrl2";
++ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/055-04-v6.9-arm64-dts-rockchip-enable-NanoPC-T6-MiniPCIe-power.patch b/target/linux/rockchip/patches-6.6/055-04-v6.9-arm64-dts-rockchip-enable-NanoPC-T6-MiniPCIe-power.patch
new file mode 100644
index 0000000000..1126bc3d38
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-04-v6.9-arm64-dts-rockchip-enable-NanoPC-T6-MiniPCIe-power.patch
@@ -0,0 +1,57 @@
+From d235e65adf00f6db09331874c5a987b7fe18023b Mon Sep 17 00:00:00 2001
+From: Hugh Cole-Baker <sigmaris@gmail.com>
+Date: Tue, 9 Jan 2024 20:27:28 +0000
+Subject: [PATCH] arm64: dts: rockchip: enable NanoPC-T6 MiniPCIe power
+
+The NanoPC-T6 has a Mini PCIe slot intended to be used for a 4G or LTE
+modem. This slot has no PCIe functionality, only USB 2.0 pins are wired
+to the SoC, and USIM pins are wired to a SIM card slot on the board.
+Define the 3.3v supply for the slot so it can be used.
+
+Signed-off-by: Hugh Cole-Baker <sigmaris@gmail.com>
+Link: https://lore.kernel.org/r/20240109202729.54292-1-sigmaris@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -159,6 +159,18 @@
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
++
++ vdd_4g_3v3: vdd-4g-3v3-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pin_4g_lte_pwren>;
++ regulator-name = "vdd_4g_3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
+ };
+
+ &combphy0_ps {
+@@ -504,6 +516,10 @@
+ };
+
+ usb {
++ pin_4g_lte_pwren: 4g-lte-pwren {
++ rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+@@ -884,6 +900,7 @@
+ };
+
+ &u2phy2_host {
++ phy-supply = <&vdd_4g_3v3>;
+ status = "okay";
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/055-05-v6.9-arm64-dts-rockchip-add-sdmmc-card-detect-to-the-nanopc-t6.patch b/target/linux/rockchip/patches-6.6/055-05-v6.9-arm64-dts-rockchip-add-sdmmc-card-detect-to-the-nanopc-t6.patch
new file mode 100644
index 0000000000..3709c10528
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-05-v6.9-arm64-dts-rockchip-add-sdmmc-card-detect-to-the-nanopc-t6.patch
@@ -0,0 +1,25 @@
+From d8bb6c2311b6b2aad11b937f96db1d6c3393246a Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Sat, 30 Dec 2023 11:50:53 -0500
+Subject: [PATCH] arm64: dts: rockchip: add sdmmc card detect to the nanopc-t6
+
+The nanopc-t6 has an sdmmc card detect connected to gpio0_a4 which is
+active low.
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Link: https://lore.kernel.org/r/20231230165053.3781-1-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -555,6 +555,7 @@
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ no-mmc;
+ no-sdio;
diff --git a/target/linux/rockchip/patches-6.6/055-06-v6.9-arm64-dts-rockchip-fix-nanopc-t6-sdmmc-regulator.patch b/target/linux/rockchip/patches-6.6/055-06-v6.9-arm64-dts-rockchip-fix-nanopc-t6-sdmmc-regulator.patch
new file mode 100644
index 0000000000..1c17bc638f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-06-v6.9-arm64-dts-rockchip-fix-nanopc-t6-sdmmc-regulator.patch
@@ -0,0 +1,44 @@
+From 6cb02674a061e4ef4f437ab60c91038d4c0d85ef Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Tue, 2 Jan 2024 02:40:53 +0000
+Subject: [PATCH] arm64: dts: rockchip: fix nanopc-t6 sdmmc regulator
+
+sdmmc on the nanopc-t6 is powered by vcc3v3_sd_s0, not vcc_3v3_s3
+add the vcc3v3_sd_s0 regulator, and control it with gpio4_a5
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Link: https://lore.kernel.org/r/20240102024054.1030313-1-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -160,6 +160,17 @@
+ vin-supply = <&vcc5v0_sys>;
+ };
+
++ vcc3v3_sd_s0: vcc3v3-sd-s0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-low;
++ gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_LOW>;
++ regulator-boot-on;
++ regulator-max-microvolt = <3300000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-name = "vcc3v3_sd_s0";
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
+ vdd_4g_3v3: vdd-4g-3v3-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+@@ -560,7 +571,7 @@
+ no-mmc;
+ no-sdio;
+ sd-uhs-sdr104;
+- vmmc-supply = <&vcc_3v3_s3>;
++ vmmc-supply = <&vcc3v3_sd_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/055-08-v6.12-arm64-dts-rockchip-prepare-NanoPC-T6-for-LTS-board.patch b/target/linux/rockchip/patches-6.6/055-08-v6.12-arm64-dts-rockchip-prepare-NanoPC-T6-for-LTS-board.patch
new file mode 100644
index 0000000000..415c34fff6
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-08-v6.12-arm64-dts-rockchip-prepare-NanoPC-T6-for-LTS-board.patch
@@ -0,0 +1,1916 @@
+From d14f3a4f1feabb6bb5935bf3b275a1e6bf2208eb Mon Sep 17 00:00:00 2001
+From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Date: Thu, 29 Aug 2024 14:26:53 +0200
+Subject: [PATCH] arm64: dts: rockchip: prepare NanoPC-T6 for LTS board
+
+FriendlyELEC introduced a second version of NanoPC-T6 SBC.
+
+Create common include file and make NanoPC-T6 use it. Following
+patches will add LTS version.
+
+Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Link: https://lore.kernel.org/r/20240829-friendlyelec-nanopc-t6-lts-v6-2-edff247e8c02@linaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-nanopc-t6.dts | 932 +----------------
+ .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 945 ++++++++++++++++++
+ 2 files changed, 947 insertions(+), 930 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -2,944 +2,16 @@
+ /*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Thomas McKahan
++ * Copyright (c) 2024 Linaro Ltd.
+ *
+ */
+
+ /dts-v1/;
+
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/pinctrl/rockchip.h>
+-#include <dt-bindings/usb/pd.h>
+-#include "rk3588.dtsi"
++#include "rk3588-nanopc-t6.dtsi"
+
+ / {
+ model = "FriendlyElec NanoPC-T6";
+ compatible = "friendlyarm,nanopc-t6", "rockchip,rk3588";
+
+- aliases {
+- mmc0 = &sdhci;
+- mmc1 = &sdmmc;
+- };
+-
+- chosen {
+- stdout-path = "serial2:1500000n8";
+- };
+-
+- leds {
+- compatible = "gpio-leds";
+-
+- sys_led: led-0 {
+- gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+- label = "system-led";
+- linux,default-trigger = "heartbeat";
+- pinctrl-names = "default";
+- pinctrl-0 = <&sys_led_pin>;
+- };
+-
+- usr_led: led-1 {
+- gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
+- label = "user-led";
+- pinctrl-names = "default";
+- pinctrl-0 = <&usr_led_pin>;
+- };
+- };
+-
+- sound {
+- compatible = "simple-audio-card";
+- pinctrl-names = "default";
+- pinctrl-0 = <&hp_det>;
+-
+- simple-audio-card,name = "realtek,rt5616-codec";
+- simple-audio-card,format = "i2s";
+- simple-audio-card,mclk-fs = <256>;
+-
+- simple-audio-card,hp-det-gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
+- simple-audio-card,hp-pin-name = "Headphones";
+-
+- simple-audio-card,widgets =
+- "Headphone", "Headphones",
+- "Microphone", "Microphone Jack";
+- simple-audio-card,routing =
+- "Headphones", "HPOL",
+- "Headphones", "HPOR",
+- "MIC1", "Microphone Jack",
+- "Microphone Jack", "micbias1";
+-
+- simple-audio-card,cpu {
+- sound-dai = <&i2s0_8ch>;
+- };
+- simple-audio-card,codec {
+- sound-dai = <&rt5616>;
+- };
+- };
+-
+- vcc12v_dcin: vcc12v-dcin-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc12v_dcin";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <12000000>;
+- regulator-max-microvolt = <12000000>;
+- };
+-
+- /* vcc5v0_sys powers peripherals */
+- vcc5v0_sys: vcc5v0-sys-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc5v0_sys";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- vin-supply = <&vcc12v_dcin>;
+- };
+-
+- /* vcc4v0_sys powers the RK806, RK860's */
+- vcc4v0_sys: vcc4v0-sys-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc4v0_sys";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <4000000>;
+- regulator-max-microvolt = <4000000>;
+- vin-supply = <&vcc12v_dcin>;
+- };
+-
+- vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc-1v1-nldo-s3";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <1100000>;
+- regulator-max-microvolt = <1100000>;
+- vin-supply = <&vcc4v0_sys>;
+- };
+-
+- 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>;
+- };
+-
+- vbus5v0_typec: vbus5v0-typec-regulator {
+- compatible = "regulator-fixed";
+- enable-active-high;
+- gpio = <&gpio1 RK_PD2 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_sys>;
+- };
+-
+- vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+- compatible = "regulator-fixed";
+- enable-active-high;
+- gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pcie_m2_1_pwren>;
+- regulator-name = "vcc3v3_pcie2x1l0";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- vin-supply = <&vcc5v0_sys>;
+- };
+-
+- vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+- compatible = "regulator-fixed";
+- enable-active-high;
+- gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pcie_m2_0_pwren>;
+- regulator-name = "vcc3v3_pcie30";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- vin-supply = <&vcc5v0_sys>;
+- };
+-
+- vcc3v3_sd_s0: vcc3v3-sd-s0-regulator {
+- compatible = "regulator-fixed";
+- enable-active-low;
+- gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_LOW>;
+- regulator-boot-on;
+- regulator-max-microvolt = <3300000>;
+- regulator-min-microvolt = <3300000>;
+- regulator-name = "vcc3v3_sd_s0";
+- vin-supply = <&vcc_3v3_s3>;
+- };
+-
+- vdd_4g_3v3: vdd-4g-3v3-regulator {
+- compatible = "regulator-fixed";
+- enable-active-high;
+- gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pin_4g_lte_pwren>;
+- regulator-name = "vdd_4g_3v3";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- vin-supply = <&vcc5v0_sys>;
+- };
+-};
+-
+-&combphy0_ps {
+- status = "okay";
+-};
+-
+-&combphy1_ps {
+- status = "okay";
+-};
+-
+-&combphy2_psu {
+- status = "okay";
+-};
+-
+-&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>;
+-};
+-
+-&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>;
+-};
+-
+-&gpio0 {
+- gpio-line-names = /* GPIO0 A0-A7 */
+- "", "", "", "",
+- "", "", "", "",
+- /* GPIO0 B0-B7 */
+- "", "", "", "",
+- "", "", "", "",
+- /* GPIO0 C0-C7 */
+- "", "", "", "",
+- "HEADER_10", "HEADER_08", "HEADER_32", "",
+- /* GPIO0 D0-D7 */
+- "", "", "", "",
+- "", "", "", "";
+-};
+-
+-&gpio1 {
+- gpio-line-names = /* GPIO1 A0-A7 */
+- "HEADER_27", "HEADER_28", "", "",
+- "", "", "", "HEADER_15",
+- /* GPIO1 B0-B7 */
+- "HEADER_26", "HEADER_21", "HEADER_19", "HEADER_23",
+- "HEADER_24", "HEADER_22", "", "",
+- /* GPIO1 C0-C7 */
+- "", "", "", "",
+- "", "", "", "",
+- /* GPIO1 D0-D7 */
+- "", "", "", "",
+- "", "", "HEADER_05", "HEADER_03";
+-};
+-
+-&gpio2 {
+- gpio-line-names = /* GPIO2 A0-A7 */
+- "", "", "", "",
+- "", "", "", "",
+- /* GPIO2 B0-B7 */
+- "", "", "", "",
+- "", "", "", "",
+- /* GPIO2 C0-C7 */
+- "", "CSI1_11", "CSI1_12", "",
+- "", "", "", "",
+- /* GPIO2 D0-D7 */
+- "", "", "", "",
+- "", "", "", "";
+-};
+-
+-&gpio3 {
+- gpio-line-names = /* GPIO3 A0-A7 */
+- "HEADER_35", "HEADER_38", "HEADER_40", "HEADER_36",
+- "HEADER_37", "", "DSI0_12", "",
+- /* GPIO3 B0-B7 */
+- "HEADER_33", "DSI0_10", "HEADER_07", "HEADER_16",
+- "HEADER_18", "HEADER_29", "HEADER_31", "HEADER_12",
+- /* GPIO3 C0-C7 */
+- "DSI0_08", "DSI0_14", "HEADER_11", "HEADER_13",
+- "", "", "", "",
+- /* GPIO3 D0-D7 */
+- "", "", "", "",
+- "", "DSI1_10", "", "";
+-};
+-
+-&gpio4 {
+- gpio-line-names = /* GPIO4 A0-A7 */
+- "DSI1_08", "DSI1_14", "", "DSI1_12",
+- "", "", "", "",
+- /* GPIO4 B0-B7 */
+- "", "", "", "",
+- "", "", "", "",
+- /* GPIO4 C0-C7 */
+- "", "", "", "",
+- "CSI0_11", "CSI0_12", "", "",
+- /* GPIO4 D0-D7 */
+- "", "", "", "",
+- "", "", "", "";
+-};
+-
+-&i2c0 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c0m2_xfer>;
+- status = "okay";
+-
+- vdd_cpu_big0_s0: regulator@42 {
+- compatible = "rockchip,rk8602";
+- reg = <0x42>;
+- fcs,suspend-voltage-selector = <1>;
+- regulator-name = "vdd_cpu_big0_s0";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <550000>;
+- regulator-max-microvolt = <1050000>;
+- regulator-ramp-delay = <2300>;
+- vin-supply = <&vcc4v0_sys>;
+-
+- regulator-state-mem {
+- regulator-off-in-suspend;
+- };
+- };
+-
+- vdd_cpu_big1_s0: regulator@43 {
+- compatible = "rockchip,rk8603", "rockchip,rk8602";
+- reg = <0x43>;
+- fcs,suspend-voltage-selector = <1>;
+- regulator-name = "vdd_cpu_big1_s0";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <550000>;
+- regulator-max-microvolt = <1050000>;
+- regulator-ramp-delay = <2300>;
+- vin-supply = <&vcc4v0_sys>;
+-
+- regulator-state-mem {
+- regulator-off-in-suspend;
+- };
+- };
+-};
+-
+-&i2c2 {
+- status = "okay";
+-
+- vdd_npu_s0: regulator@42 {
+- compatible = "rockchip,rk8602";
+- reg = <0x42>;
+- rockchip,suspend-voltage-selector = <1>;
+- regulator-name = "vdd_npu_s0";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <550000>;
+- regulator-max-microvolt = <950000>;
+- regulator-ramp-delay = <2300>;
+- vin-supply = <&vcc4v0_sys>;
+-
+- regulator-state-mem {
+- regulator-off-in-suspend;
+- };
+- };
+-};
+-
+-&i2c6 {
+- clock-frequency = <200000>;
+- status = "okay";
+-
+- fusb302: typec-portc@22 {
+- compatible = "fcs,fusb302";
+- reg = <0x22>;
+- interrupt-parent = <&gpio0>;
+- interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+- pinctrl-0 = <&usbc0_int>;
+- pinctrl-names = "default";
+- vbus-supply = <&vbus5v0_typec>;
+-
+- connector {
+- compatible = "usb-c-connector";
+- data-role = "dual";
+- label = "USB-C";
+- power-role = "dual";
+- try-power-role = "sink";
+- source-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
+- sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+- op-sink-microwatt = <1000000>;
+- };
+- };
+-
+- 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 = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+- wakeup-source;
+- };
+-};
+-
+-&i2c7 {
+- clock-frequency = <200000>;
+- status = "okay";
+-
+- rt5616: codec@1b {
+- compatible = "realtek,rt5616";
+- reg = <0x1b>;
+- clocks = <&cru I2S0_8CH_MCLKOUT>;
+- clock-names = "mclk";
+- #sound-dai-cells = <0>;
+- assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+- assigned-clock-rates = <12288000>;
+-
+- port {
+- rt5616_p0_0: endpoint {
+- remote-endpoint = <&i2s0_8ch_p0_0>;
+- };
+- };
+- };
+-
+- /* connected with MIPI-CSI1 */
+-};
+-
+-&i2c8 {
+- pinctrl-0 = <&i2c8m2_xfer>;
+-};
+-
+-&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 = <&rt5616_p0_0>;
+- };
+- };
+-};
+-
+-&pcie2x1l0 {
+- reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc_3v3_pcie20>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pcie2_0_rst>;
+- status = "okay";
+-};
+-
+-&pcie2x1l1 {
+- reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pcie2_1_rst>;
+- status = "okay";
+-};
+-
+-&pcie2x1l2 {
+- reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc_3v3_pcie20>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pcie2_2_rst>;
+- status = "okay";
+-};
+-
+-&pcie30phy {
+- status = "okay";
+-};
+-
+-&pcie3x4 {
+- reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc3v3_pcie30>;
+- status = "okay";
+-};
+-
+-&pinctrl {
+- gpio-leds {
+- sys_led_pin: sys-led-pin {
+- rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- usr_led_pin: usr-led-pin {
+- rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+-
+- headphone {
+- hp_det: hp-det {
+- rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+-
+- hym8563 {
+- hym8563_int: hym8563-int {
+- rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+- };
+- };
+-
+- pcie {
+- pcie2_0_rst: pcie2-0-rst {
+- rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- pcie2_1_rst: pcie2-1-rst {
+- rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- pcie2_2_rst: pcie2-2-rst {
+- rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- pcie_m2_0_pwren: pcie-m20-pwren {
+- rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- pcie_m2_1_pwren: pcie-m21-pwren {
+- rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+-
+- usb {
+- pin_4g_lte_pwren: 4g-lte-pwren {
+- rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- typec5v_pwren: typec5v-pwren {
+- rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- usbc0_int: usbc0-int {
+- rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+- };
+- };
+-};
+-
+-&pwm1 {
+- pinctrl-0 = <&pwm1m1_pins>;
+- status = "okay";
+-};
+-
+-&saradc {
+- vref-supply = <&avcc_1v8_s0>;
+- status = "okay";
+-};
+-
+-&sdhci {
+- bus-width = <8>;
+- no-sdio;
+- no-sd;
+- non-removable;
+- max-frequency = <200000000>;
+- mmc-hs400-1_8v;
+- mmc-hs400-enhanced-strobe;
+- status = "okay";
+-};
+-
+-&sdmmc {
+- bus-width = <4>;
+- cap-mmc-highspeed;
+- cap-sd-highspeed;
+- cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+- disable-wp;
+- no-mmc;
+- no-sdio;
+- sd-uhs-sdr104;
+- vmmc-supply = <&vcc3v3_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 = <&vcc4v0_sys>;
+- vcc2-supply = <&vcc4v0_sys>;
+- vcc3-supply = <&vcc4v0_sys>;
+- vcc4-supply = <&vcc4v0_sys>;
+- vcc5-supply = <&vcc4v0_sys>;
+- vcc6-supply = <&vcc4v0_sys>;
+- vcc7-supply = <&vcc4v0_sys>;
+- vcc8-supply = <&vcc4v0_sys>;
+- vcc9-supply = <&vcc4v0_sys>;
+- vcc10-supply = <&vcc4v0_sys>;
+- vcc11-supply = <&vcc_2v0_pldo_s3>;
+- vcc12-supply = <&vcc4v0_sys>;
+- vcc13-supply = <&vcc_1v1_nldo_s3>;
+- vcc14-supply = <&vcc_1v1_nldo_s3>;
+- vcca-supply = <&vcc4v0_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-init-microvolt = <750000>;
+- 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";
+-};
+-
+-&u2phy2_host {
+- phy-supply = <&vdd_4g_3v3>;
+- status = "okay";
+-};
+-
+-&u2phy3_host {
+- status = "okay";
+-};
+-
+-&u2phy2 {
+- status = "okay";
+-};
+-
+-&u2phy3 {
+- status = "okay";
+-};
+-
+-&usb_host0_ehci {
+- status = "okay";
+-};
+-
+-&usb_host0_ohci {
+- status = "okay";
+-};
+-
+-&usb_host1_ehci {
+- status = "okay";
+-};
+-
+-&usb_host1_ohci {
+- status = "okay";
+ };
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -0,0 +1,945 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ * Copyright (c) 2023 Thomas McKahan
++ *
++ */
++
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/usb/pd.h>
++#include "rk3588.dtsi"
++
++/ {
++ model = "FriendlyElec NanoPC-T6";
++ compatible = "friendlyarm,nanopc-t6", "rockchip,rk3588";
++
++ aliases {
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc;
++ };
++
++ chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ sys_led: led-0 {
++ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
++ label = "system-led";
++ linux,default-trigger = "heartbeat";
++ pinctrl-names = "default";
++ pinctrl-0 = <&sys_led_pin>;
++ };
++
++ usr_led: led-1 {
++ gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
++ label = "user-led";
++ pinctrl-names = "default";
++ pinctrl-0 = <&usr_led_pin>;
++ };
++ };
++
++ sound {
++ compatible = "simple-audio-card";
++ pinctrl-names = "default";
++ pinctrl-0 = <&hp_det>;
++
++ simple-audio-card,name = "realtek,rt5616-codec";
++ simple-audio-card,format = "i2s";
++ simple-audio-card,mclk-fs = <256>;
++
++ simple-audio-card,hp-det-gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
++ simple-audio-card,hp-pin-name = "Headphones";
++
++ simple-audio-card,widgets =
++ "Headphone", "Headphones",
++ "Microphone", "Microphone Jack";
++ simple-audio-card,routing =
++ "Headphones", "HPOL",
++ "Headphones", "HPOR",
++ "MIC1", "Microphone Jack",
++ "Microphone Jack", "micbias1";
++
++ simple-audio-card,cpu {
++ sound-dai = <&i2s0_8ch>;
++ };
++ simple-audio-card,codec {
++ sound-dai = <&rt5616>;
++ };
++ };
++
++ vcc12v_dcin: vcc12v-dcin-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc12v_dcin";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <12000000>;
++ regulator-max-microvolt = <12000000>;
++ };
++
++ /* vcc5v0_sys powers peripherals */
++ vcc5v0_sys: vcc5v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc12v_dcin>;
++ };
++
++ /* vcc4v0_sys powers the RK806, RK860's */
++ vcc4v0_sys: vcc4v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc4v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <4000000>;
++ regulator-max-microvolt = <4000000>;
++ vin-supply = <&vcc12v_dcin>;
++ };
++
++ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-1v1-nldo-s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1100000>;
++ regulator-max-microvolt = <1100000>;
++ vin-supply = <&vcc4v0_sys>;
++ };
++
++ 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>;
++ };
++
++ vbus5v0_typec: vbus5v0-typec-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio1 RK_PD2 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_sys>;
++ };
++
++ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_m2_1_pwren>;
++ regulator-name = "vcc3v3_pcie2x1l0";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_m2_0_pwren>;
++ regulator-name = "vcc3v3_pcie30";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc3v3_sd_s0: vcc3v3-sd-s0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-low;
++ gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_LOW>;
++ regulator-boot-on;
++ regulator-max-microvolt = <3300000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-name = "vcc3v3_sd_s0";
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
++ vdd_4g_3v3: vdd-4g-3v3-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pin_4g_lte_pwren>;
++ regulator-name = "vdd_4g_3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++};
++
++&combphy0_ps {
++ status = "okay";
++};
++
++&combphy1_ps {
++ status = "okay";
++};
++
++&combphy2_psu {
++ status = "okay";
++};
++
++&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>;
++};
++
++&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>;
++};
++
++&gpio0 {
++ gpio-line-names = /* GPIO0 A0-A7 */
++ "", "", "", "",
++ "", "", "", "",
++ /* GPIO0 B0-B7 */
++ "", "", "", "",
++ "", "", "", "",
++ /* GPIO0 C0-C7 */
++ "", "", "", "",
++ "HEADER_10", "HEADER_08", "HEADER_32", "",
++ /* GPIO0 D0-D7 */
++ "", "", "", "",
++ "", "", "", "";
++};
++
++&gpio1 {
++ gpio-line-names = /* GPIO1 A0-A7 */
++ "HEADER_27", "HEADER_28", "", "",
++ "", "", "", "HEADER_15",
++ /* GPIO1 B0-B7 */
++ "HEADER_26", "HEADER_21", "HEADER_19", "HEADER_23",
++ "HEADER_24", "HEADER_22", "", "",
++ /* GPIO1 C0-C7 */
++ "", "", "", "",
++ "", "", "", "",
++ /* GPIO1 D0-D7 */
++ "", "", "", "",
++ "", "", "HEADER_05", "HEADER_03";
++};
++
++&gpio2 {
++ gpio-line-names = /* GPIO2 A0-A7 */
++ "", "", "", "",
++ "", "", "", "",
++ /* GPIO2 B0-B7 */
++ "", "", "", "",
++ "", "", "", "",
++ /* GPIO2 C0-C7 */
++ "", "CSI1_11", "CSI1_12", "",
++ "", "", "", "",
++ /* GPIO2 D0-D7 */
++ "", "", "", "",
++ "", "", "", "";
++};
++
++&gpio3 {
++ gpio-line-names = /* GPIO3 A0-A7 */
++ "HEADER_35", "HEADER_38", "HEADER_40", "HEADER_36",
++ "HEADER_37", "", "DSI0_12", "",
++ /* GPIO3 B0-B7 */
++ "HEADER_33", "DSI0_10", "HEADER_07", "HEADER_16",
++ "HEADER_18", "HEADER_29", "HEADER_31", "HEADER_12",
++ /* GPIO3 C0-C7 */
++ "DSI0_08", "DSI0_14", "HEADER_11", "HEADER_13",
++ "", "", "", "",
++ /* GPIO3 D0-D7 */
++ "", "", "", "",
++ "", "DSI1_10", "", "";
++};
++
++&gpio4 {
++ gpio-line-names = /* GPIO4 A0-A7 */
++ "DSI1_08", "DSI1_14", "", "DSI1_12",
++ "", "", "", "",
++ /* GPIO4 B0-B7 */
++ "", "", "", "",
++ "", "", "", "",
++ /* GPIO4 C0-C7 */
++ "", "", "", "",
++ "CSI0_11", "CSI0_12", "", "",
++ /* GPIO4 D0-D7 */
++ "", "", "", "",
++ "", "", "", "";
++};
++
++&i2c0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0m2_xfer>;
++ status = "okay";
++
++ vdd_cpu_big0_s0: regulator@42 {
++ compatible = "rockchip,rk8602";
++ reg = <0x42>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu_big0_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <1050000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc4v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_cpu_big1_s0: regulator@43 {
++ compatible = "rockchip,rk8603", "rockchip,rk8602";
++ reg = <0x43>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu_big1_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <1050000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc4v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2c2 {
++ status = "okay";
++
++ vdd_npu_s0: regulator@42 {
++ compatible = "rockchip,rk8602";
++ reg = <0x42>;
++ rockchip,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_npu_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc4v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2c6 {
++ clock-frequency = <200000>;
++ status = "okay";
++
++ fusb302: typec-portc@22 {
++ compatible = "fcs,fusb302";
++ reg = <0x22>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
++ pinctrl-0 = <&usbc0_int>;
++ pinctrl-names = "default";
++ vbus-supply = <&vbus5v0_typec>;
++
++ connector {
++ compatible = "usb-c-connector";
++ data-role = "dual";
++ label = "USB-C";
++ power-role = "dual";
++ try-power-role = "sink";
++ source-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
++ sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
++ op-sink-microwatt = <1000000>;
++ };
++ };
++
++ 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 = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
++ wakeup-source;
++ };
++};
++
++&i2c7 {
++ clock-frequency = <200000>;
++ status = "okay";
++
++ rt5616: codec@1b {
++ compatible = "realtek,rt5616";
++ reg = <0x1b>;
++ clocks = <&cru I2S0_8CH_MCLKOUT>;
++ clock-names = "mclk";
++ #sound-dai-cells = <0>;
++ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
++ assigned-clock-rates = <12288000>;
++
++ port {
++ rt5616_p0_0: endpoint {
++ remote-endpoint = <&i2s0_8ch_p0_0>;
++ };
++ };
++ };
++
++ /* connected with MIPI-CSI1 */
++};
++
++&i2c8 {
++ pinctrl-0 = <&i2c8m2_xfer>;
++};
++
++&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 = <&rt5616_p0_0>;
++ };
++ };
++};
++
++&pcie2x1l0 {
++ reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc_3v3_pcie20>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie2_0_rst>;
++ status = "okay";
++};
++
++&pcie2x1l1 {
++ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie2_1_rst>;
++ status = "okay";
++};
++
++&pcie2x1l2 {
++ reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc_3v3_pcie20>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie2_2_rst>;
++ status = "okay";
++};
++
++&pcie30phy {
++ status = "okay";
++};
++
++&pcie3x4 {
++ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie30>;
++ status = "okay";
++};
++
++&pinctrl {
++ gpio-leds {
++ sys_led_pin: sys-led-pin {
++ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ usr_led_pin: usr-led-pin {
++ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ headphone {
++ hp_det: hp-det {
++ rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ hym8563 {
++ hym8563_int: hym8563-int {
++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ pcie {
++ pcie2_0_rst: pcie2-0-rst {
++ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie2_1_rst: pcie2-1-rst {
++ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie2_2_rst: pcie2-2-rst {
++ rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie_m2_0_pwren: pcie-m20-pwren {
++ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie_m2_1_pwren: pcie-m21-pwren {
++ rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ usb {
++ pin_4g_lte_pwren: 4g-lte-pwren {
++ rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ typec5v_pwren: typec5v-pwren {
++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ usbc0_int: usbc0-int {
++ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++};
++
++&pwm1 {
++ pinctrl-0 = <&pwm1m1_pins>;
++ status = "okay";
++};
++
++&saradc {
++ vref-supply = <&avcc_1v8_s0>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ no-sdio;
++ no-sd;
++ non-removable;
++ max-frequency = <200000000>;
++ mmc-hs400-1_8v;
++ mmc-hs400-enhanced-strobe;
++ status = "okay";
++};
++
++&sdmmc {
++ bus-width = <4>;
++ cap-mmc-highspeed;
++ cap-sd-highspeed;
++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
++ disable-wp;
++ no-mmc;
++ no-sdio;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc3v3_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 = <&vcc4v0_sys>;
++ vcc2-supply = <&vcc4v0_sys>;
++ vcc3-supply = <&vcc4v0_sys>;
++ vcc4-supply = <&vcc4v0_sys>;
++ vcc5-supply = <&vcc4v0_sys>;
++ vcc6-supply = <&vcc4v0_sys>;
++ vcc7-supply = <&vcc4v0_sys>;
++ vcc8-supply = <&vcc4v0_sys>;
++ vcc9-supply = <&vcc4v0_sys>;
++ vcc10-supply = <&vcc4v0_sys>;
++ vcc11-supply = <&vcc_2v0_pldo_s3>;
++ vcc12-supply = <&vcc4v0_sys>;
++ vcc13-supply = <&vcc_1v1_nldo_s3>;
++ vcc14-supply = <&vcc_1v1_nldo_s3>;
++ vcca-supply = <&vcc4v0_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-init-microvolt = <750000>;
++ 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";
++};
++
++&u2phy2_host {
++ phy-supply = <&vdd_4g_3v3>;
++ status = "okay";
++};
++
++&u2phy3_host {
++ status = "okay";
++};
++
++&u2phy2 {
++ status = "okay";
++};
++
++&u2phy3 {
++ status = "okay";
++};
++
++&usb_host0_ehci {
++ status = "okay";
++};
++
++&usb_host0_ohci {
++ status = "okay";
++};
++
++&usb_host1_ehci {
++ status = "okay";
++};
++
++&usb_host1_ohci {
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/055-09-v6.12-arm64-dts-rockchip-move-NanoPC-T6-parts-to-DTS.patch b/target/linux/rockchip/patches-6.6/055-09-v6.12-arm64-dts-rockchip-move-NanoPC-T6-parts-to-DTS.patch
new file mode 100644
index 0000000000..ce78982a58
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-09-v6.12-arm64-dts-rockchip-move-NanoPC-T6-parts-to-DTS.patch
@@ -0,0 +1,85 @@
+From aea8d84070fe0846961deb23228d9dd3f8caefb3 Mon Sep 17 00:00:00 2001
+From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Date: Thu, 29 Aug 2024 14:26:54 +0200
+Subject: [PATCH] arm64: dts: rockchip: move NanoPC-T6 parts to DTS
+
+MiniPCIe slot is present only in first version of NanoPC-T6 (2301).
+
+Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Link: https://lore.kernel.org/r/20240829-friendlyelec-nanopc-t6-lts-v6-3-edff247e8c02@linaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-nanopc-t6.dts | 23 +++++++++++++++++++
+ .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 17 --------------
+ 2 files changed, 23 insertions(+), 17 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -14,4 +14,27 @@
+ model = "FriendlyElec NanoPC-T6";
+ compatible = "friendlyarm,nanopc-t6", "rockchip,rk3588";
+
++ vdd_4g_3v3: vdd-4g-3v3-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pin_4g_lte_pwren>;
++ regulator-name = "vdd_4g_3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++};
++
++&pinctrl {
++ usb {
++ pin_4g_lte_pwren: 4g-lte-pwren {
++ rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&u2phy2_host {
++ phy-supply = <&vdd_4g_3v3>;
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -170,18 +170,6 @@
+ regulator-name = "vcc3v3_sd_s0";
+ vin-supply = <&vcc_3v3_s3>;
+ };
+-
+- vdd_4g_3v3: vdd-4g-3v3-regulator {
+- compatible = "regulator-fixed";
+- enable-active-high;
+- gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pin_4g_lte_pwren>;
+- regulator-name = "vdd_4g_3v3";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- vin-supply = <&vcc5v0_sys>;
+- };
+ };
+
+ &combphy0_ps {
+@@ -527,10 +515,6 @@
+ };
+
+ usb {
+- pin_4g_lte_pwren: 4g-lte-pwren {
+- rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+@@ -912,7 +896,6 @@
+ };
+
+ &u2phy2_host {
+- phy-supply = <&vdd_4g_3v3>;
+ status = "okay";
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/055-10-v6.12-arm64-dts-rockchip-add-SPI-flash-on-NanoPC-T6.patch b/target/linux/rockchip/patches-6.6/055-10-v6.12-arm64-dts-rockchip-add-SPI-flash-on-NanoPC-T6.patch
new file mode 100644
index 0000000000..61fa3639a9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-10-v6.12-arm64-dts-rockchip-add-SPI-flash-on-NanoPC-T6.patch
@@ -0,0 +1,40 @@
+From a22a629c63b1addcf2d81eaf30383c1deca5b7a9 Mon Sep 17 00:00:00 2001
+From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Date: Thu, 29 Aug 2024 14:26:56 +0200
+Subject: [PATCH] arm64: dts: rockchip: add SPI flash on NanoPC-T6
+
+FriendlyELEC NanoPC-T6 has optional SPI flash chip on-board.
+It is populated with 32MB one on LTS version.
+
+Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240829-friendlyelec-nanopc-t6-lts-v6-5-edff247e8c02@linaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -560,6 +560,21 @@
+ status = "okay";
+ };
+
++/* optional on non-LTS, populated on LTS version */
++&sfc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&fspim1_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>;
diff --git a/target/linux/rockchip/patches-6.6/055-11-v6.12-arm64-dts-rockchip-add-IR-receiver-to-NanoPC-T6.patch b/target/linux/rockchip/patches-6.6/055-11-v6.12-arm64-dts-rockchip-add-IR-receiver-to-NanoPC-T6.patch
new file mode 100644
index 0000000000..34b2d182b4
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-11-v6.12-arm64-dts-rockchip-add-IR-receiver-to-NanoPC-T6.patch
@@ -0,0 +1,53 @@
+From b70caff0f9592719b6c977e291c33192e959c9d4 Mon Sep 17 00:00:00 2001
+From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Date: Thu, 29 Aug 2024 14:26:57 +0200
+Subject: [PATCH] arm64: dts: rockchip: add IR-receiver to NanoPC-T6
+
+FriendlyELEC NanoPC-T6 has IR receiver connected to PWM3_IR_M0 line
+which ends as GPIO0_D4.
+
+Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Link: https://lore.kernel.org/r/20240829-friendlyelec-nanopc-t6-lts-v6-6-edff247e8c02@linaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -25,6 +25,13 @@
+ stdout-path = "serial2:1500000n8";
+ };
+
++ ir-receiver {
++ compatible = "gpio-ir-receiver";
++ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&ir_receiver_pin>;
++ };
++
+ leds {
+ compatible = "gpio-leds";
+
+@@ -228,7 +235,7 @@
+ "HEADER_10", "HEADER_08", "HEADER_32", "",
+ /* GPIO0 D0-D7 */
+ "", "", "", "",
+- "", "", "", "";
++ "IR receiver [PWM3_IR_M0]", "", "", "";
+ };
+
+ &gpio1 {
+@@ -492,6 +499,12 @@
+ };
+ };
+
++ ir-receiver {
++ ir_receiver_pin: ir-receiver-pin {
++ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ pcie {
+ pcie2_0_rst: pcie2-0-rst {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/target/linux/rockchip/patches-6.6/055-12-v6.12-arm64-dts-rockchip-enable-GPU-on-NanoPC-T6.patch b/target/linux/rockchip/patches-6.6/055-12-v6.12-arm64-dts-rockchip-enable-GPU-on-NanoPC-T6.patch
new file mode 100644
index 0000000000..40ebd638c1
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-12-v6.12-arm64-dts-rockchip-enable-GPU-on-NanoPC-T6.patch
@@ -0,0 +1,28 @@
+From e86cbf999cda2d44f32ec622537024e3b923080d Mon Sep 17 00:00:00 2001
+From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Date: Thu, 29 Aug 2024 14:26:58 +0200
+Subject: [PATCH] arm64: dts: rockchip: enable GPU on NanoPC-T6
+
+Enable the Mali GPU on FriendlyELEC NanoPC-T6
+
+Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Link: https://lore.kernel.org/r/20240829-friendlyelec-nanopc-t6-lts-v6-7-edff247e8c02@linaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -298,6 +298,11 @@
+ "", "", "", "";
+ };
+
++&gpu {
++ mali-supply = <&vdd_gpu_s0>;
++ status = "okay";
++};
++
+ &i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
diff --git a/target/linux/rockchip/patches-6.6/055-13-v6.12-arm64-dts-rockchip-enable-USB-C-on-NanoPC-T6.patch b/target/linux/rockchip/patches-6.6/055-13-v6.12-arm64-dts-rockchip-enable-USB-C-on-NanoPC-T6.patch
new file mode 100644
index 0000000000..89720c3825
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-13-v6.12-arm64-dts-rockchip-enable-USB-C-on-NanoPC-T6.patch
@@ -0,0 +1,130 @@
+From c9ba75320e5a12dc9d574603acf29b38a920b40c Mon Sep 17 00:00:00 2001
+From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Date: Thu, 29 Aug 2024 14:26:59 +0200
+Subject: [PATCH] arm64: dts: rockchip: enable USB-C on NanoPC-T6
+
+Enable the USB-C port on FriendlyELEC NanoPC-T6.
+
+Works one way so far but still better than before.
+
+Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Link: https://lore.kernel.org/r/20240829-friendlyelec-nanopc-t6-lts-v6-8-edff247e8c02@linaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 76 ++++++++++++++++++-
+ 1 file changed, 72 insertions(+), 4 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -137,6 +137,8 @@
+ gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec5v_pwren>;
++ regulator-always-on;
++ regulator-boot-on;
+ regulator-name = "vbus5v0_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+@@ -381,11 +383,34 @@
+ compatible = "usb-c-connector";
+ data-role = "dual";
+ label = "USB-C";
+- power-role = "dual";
+- try-power-role = "sink";
++ power-role = "source";
+ source-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
+- sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+- op-sink-microwatt = <1000000>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ usbc0_hs: endpoint {
++ remote-endpoint = <&usb_host0_xhci_drd_sw>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ usbc0_ss: endpoint {
++ remote-endpoint = <&usbdp_phy0_typec_ss>;
++ };
++ };
++
++ port@2 {
++ reg = <2>;
++ usbc0_sbu: endpoint {
++ remote-endpoint = <&usbdp_phy0_typec_sbu>;
++ };
++ };
++ };
+ };
+ };
+
+@@ -928,6 +953,14 @@
+ status = "okay";
+ };
+
++&u2phy0 {
++ status = "okay";
++};
++
++&u2phy0_otg {
++ status = "okay";
++};
++
+ &u2phy2_host {
+ status = "okay";
+ };
+@@ -944,6 +977,29 @@
+ 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_typec_ss: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&usbc0_ss>;
++ };
++
++ usbdp_phy0_typec_sbu: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&usbc0_sbu>;
++ };
++ };
++};
++
+ &usb_host0_ehci {
+ status = "okay";
+ };
+@@ -952,6 +1008,18 @@
+ status = "okay";
+ };
+
++&usb_host0_xhci {
++ dr_mode = "host";
++ status = "okay";
++ usb-role-switch;
++
++ port {
++ usb_host0_xhci_drd_sw: endpoint {
++ remote-endpoint = <&usbc0_hs>;
++ };
++ };
++};
++
+ &usb_host1_ehci {
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/055-14-v6.12-arm64-dts-rockchip-add-Mask-Rom-key-on-NanoPC-T6.patch b/target/linux/rockchip/patches-6.6/055-14-v6.12-arm64-dts-rockchip-add-Mask-Rom-key-on-NanoPC-T6.patch
new file mode 100644
index 0000000000..cf179d9fa9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-14-v6.12-arm64-dts-rockchip-add-Mask-Rom-key-on-NanoPC-T6.patch
@@ -0,0 +1,45 @@
+From da439eed06ff6806f22341ab0468226afc555305 Mon Sep 17 00:00:00 2001
+From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Date: Thu, 29 Aug 2024 14:27:00 +0200
+Subject: [PATCH] arm64: dts: rockchip: add Mask Rom key on NanoPC-T6
+
+Mask Rom key is connected to SARADC and can be read from OS.
+
+Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
+Link: https://lore.kernel.org/r/20240829-friendlyelec-nanopc-t6-lts-v6-9-edff247e8c02@linaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -8,6 +8,7 @@
+ /dts-v1/;
+
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/pinctrl/rockchip.h>
+ #include <dt-bindings/usb/pd.h>
+ #include "rk3588.dtsi"
+@@ -21,6 +22,20 @@
+ mmc1 = &sdmmc;
+ };
+
++ adc-keys-0 {
++ compatible = "adc-keys";
++ io-channels = <&saradc 0>;
++ io-channel-names = "buttons";
++ keyup-threshold-microvolt = <1800000>;
++ poll-interval = <100>;
++
++ button-maskrom {
++ label = "Mask Rom";
++ linux,code = <KEY_SETUP>;
++ press-threshold-microvolt = <2000>;
++ };
++ };
++
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
diff --git a/target/linux/rockchip/patches-6.6/055-15-v6.12-arm64-dts-rockchip-use-correct-fcs-suspend-voltage-selecto.patch b/target/linux/rockchip/patches-6.6/055-15-v6.12-arm64-dts-rockchip-use-correct-fcs-suspend-voltage-selecto.patch
new file mode 100644
index 0000000000..d7d87e22e8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/055-15-v6.12-arm64-dts-rockchip-use-correct-fcs-suspend-voltage-selecto.patch
@@ -0,0 +1,28 @@
+From 170c77276d470a63d22a2634a38846dd88538637 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko@sntech.de>
+Date: Thu, 29 Aug 2024 15:20:58 +0200
+Subject: [PATCH] arm64: dts: rockchip: use correct
+ fcs,suspend-voltage-selector on NanoPC-T6
+
+A remant from moving from the vendor kernel, the regulator is using
+a fairchild fcs prefix instead of rockchip,* in the mainline kernel
+according to its binding.
+
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240829132100.1723127-2-heiko@sntech.de
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -366,7 +366,7 @@
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+- rockchip,suspend-voltage-selector = <1>;
++ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
diff --git a/target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch b/target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch
new file mode 100644
index 0000000000..bc1845b0d3
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch
@@ -0,0 +1,778 @@
+From 81c828a67c78bb03ea75819c417c93c7f3d637b5 Mon Sep 17 00:00:00 2001
+From: Jianfeng Liu <liujianfeng1994@gmail.com>
+Date: Sat, 20 Apr 2024 11:43:00 +0800
+Subject: [PATCH] arm64: dts: rockchip: Add ArmSom Sige7 board
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Specification:
+ Rockchip Rk3588 SoC
+ 4x ARM Cortex-A76, 4x ARM Cortex-A55
+ 8/16/32GB Memory LPDDR4/LPDDR4x
+ Mali G610MP4 GPU
+ 2× MIPI-CSI Connector
+ 1× MIPI-DSI Connector
+ 1x M.2 Key M (PCIe 3.0 4-lanes)
+ 2x RTL8125 2.5G Ethernet
+ Onboard AP6275P for WIFI6/BT5
+ 32GB/64GB/128GB eMMC
+ MicroSD card slot
+ 1x USB2.0, 1x USB3.0 Type-A, 1x US3.0 Type-C
+ 1x HDMI Output, 1x type-C DP Output
+
+Functions work normally:
+ USB2.0 Host
+ USB3.0 Type-A Host
+ M.2 Key M (PCIe 3.0 4-lanes)
+ 2x RTL8125 2.5G Ethernet
+ eMMC
+ MicroSD card
+
+More information can be obtained from the following website
+ https://docs.armsom.org/armsom-sige7
+
+Signed-off-by: Jianfeng Liu <liujianfeng1994@gmail.com>
+Reviewed-by: Weizhao Ouyang <weizhao.ouyang@arm.com>
+Link: https://lore.kernel.org/r/20240420034300.176920-4-liujianfeng1994@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../boot/dts/rockchip/rk3588-armsom-sige7.dts | 721 ++++++++++++++++++
+ 2 files changed, 722 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -101,6 +101,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-ra
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3b.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
+@@ -0,0 +1,721 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include "rk3588.dtsi"
++
++/ {
++ model = "ArmSoM Sige7";
++ compatible = "armsom,sige7", "rockchip,rk3588";
++
++ aliases {
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc;
++ };
++
++ chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ analog-sound {
++ compatible = "audio-graph-card";
++ dais = <&i2s0_8ch_p0>;
++ label = "rk3588-es8316";
++ hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&hp_detect>;
++ routing = "MIC2", "Mic Jack",
++ "Headphones", "HPOL",
++ "Headphones", "HPOR";
++ widgets = "Microphone", "Mic Jack",
++ "Headphone", "Headphones";
++ };
++
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&led_rgb_g>;
++
++ led_green: led-0 {
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_STATUS;
++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++
++ led_red: led-1 {
++ color = <LED_COLOR_ID_RED>;
++ function = LED_FUNCTION_STATUS;
++ gpios = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "none";
++ };
++ };
++
++ fan: pwm-fan {
++ compatible = "pwm-fan";
++ cooling-levels = <0 95 145 195 255>;
++ fan-supply = <&vcc5v0_sys>;
++ pwms = <&pwm1 0 50000 0>;
++ #cooling-cells = <2>;
++ };
++
++ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_pcie2x1l2";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <5000>;
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
++ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
++ regulator-name = "vcc3v3_pcie30";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <5000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_host: vcc5v0-host-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_host";
++ regulator-boot-on;
++ regulator-always-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ enable-active-high;
++ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc5v0_host_en>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_sys: vcc5v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_1v1_nldo_s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1100000>;
++ regulator-max-microvolt = <1100000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++};
++
++&combphy0_ps {
++ status = "okay";
++};
++
++&combphy1_ps {
++ status = "okay";
++};
++
++&combphy2_psu {
++ status = "okay";
++};
++
++&cpu_b0 {
++ cpu-supply = <&vdd_cpu_big0_s0>;
++};
++
++&cpu_b1 {
++ cpu-supply = <&vdd_cpu_big0_s0>;
++};
++
++&cpu_b2 {
++ cpu-supply = <&vdd_cpu_big1_s0>;
++};
++
++&cpu_b3 {
++ cpu-supply = <&vdd_cpu_big1_s0>;
++};
++
++&cpu_l0 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&cpu_l1 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&cpu_l2 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&cpu_l3 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&gpu {
++ mali-supply = <&vdd_gpu_s0>;
++ status = "okay";
++};
++
++&i2c0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0m2_xfer>;
++ status = "okay";
++
++ vdd_cpu_big0_s0: regulator@42 {
++ compatible = "rockchip,rk8602";
++ reg = <0x42>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu_big0_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <1050000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_cpu_big1_s0: regulator@43 {
++ compatible = "rockchip,rk8603", "rockchip,rk8602";
++ reg = <0x43>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu_big1_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <1050000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2c6 {
++ status = "okay";
++
++ hym8563: rtc@51 {
++ compatible = "haoyu,hym8563";
++ reg = <0x51>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
++ #clock-cells = <0>;
++ clock-output-names = "hym8563";
++ pinctrl-names = "default";
++ pinctrl-0 = <&hym8563_int>;
++ wakeup-source;
++ };
++};
++
++&i2c7 {
++ status = "okay";
++
++ es8316: audio-codec@11 {
++ compatible = "everest,es8316";
++ reg = <0x11>;
++ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
++ assigned-clock-rates = <12288000>;
++ clocks = <&cru I2S0_8CH_MCLKOUT>;
++ clock-names = "mclk";
++ #sound-dai-cells = <0>;
++
++ port {
++ es8316_p0_0: endpoint {
++ remote-endpoint = <&i2s0_8ch_p0_0>;
++ };
++ };
++ };
++};
++
++&i2s0_8ch {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s0_lrck
++ &i2s0_mclk
++ &i2s0_sclk
++ &i2s0_sdi0
++ &i2s0_sdo0>;
++ status = "okay";
++
++ i2s0_8ch_p0: port {
++ i2s0_8ch_p0_0: endpoint {
++ dai-format = "i2s";
++ mclk-fs = <256>;
++ remote-endpoint = <&es8316_p0_0>;
++ };
++ };
++};
++
++/* phy1 - right ethernet port */
++&pcie2x1l0 {
++ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++};
++
++/* phy2 - WiFi */
++&pcie2x1l1 {
++ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++};
++
++/* phy0 - left ethernet port */
++&pcie2x1l2 {
++ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++};
++
++&pcie30phy {
++ status = "okay";
++};
++
++&pcie3x4 {
++ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie30>;
++ status = "okay";
++};
++
++&pinctrl {
++ hym8563 {
++ hym8563_int: hym8563-int {
++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ leds {
++ led_rgb_g: led-rgb-g {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ led_rgb_r: led-rgb-r {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ sound {
++ hp_detect: hp-detect {
++ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ usb {
++ vcc5v0_host_en: vcc5v0-host-en {
++ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&pwm1 {
++ status = "okay";
++};
++
++&saradc {
++ vref-supply = <&avcc_1v8_s0>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ no-sdio;
++ no-sd;
++ non-removable;
++ mmc-hs200-1_8v;
++ status = "okay";
++};
++
++&sdmmc {
++ bus-width = <4>;
++ cap-mmc-highspeed;
++ cap-sd-highspeed;
++ disable-wp;
++ max-frequency = <200000000>;
++ no-sdio;
++ no-mmc;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc_3v3_s3>;
++ vqmmc-supply = <&vccio_sd_s0>;
++ status = "okay";
++};
++
++&spi2 {
++ assigned-clocks = <&cru CLK_SPI2>;
++ assigned-clock-rates = <200000000>;
++ num-cs = <1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
++ status = "okay";
++
++ pmic@0 {
++ compatible = "rockchip,rk806";
++ spi-max-frequency = <1000000>;
++ reg = <0x0>;
++
++ interrupt-parent = <&gpio0>;
++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
++
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
++ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
++
++ system-power-controller;
++
++ vcc1-supply = <&vcc5v0_sys>;
++ vcc2-supply = <&vcc5v0_sys>;
++ vcc3-supply = <&vcc5v0_sys>;
++ vcc4-supply = <&vcc5v0_sys>;
++ vcc5-supply = <&vcc5v0_sys>;
++ vcc6-supply = <&vcc5v0_sys>;
++ vcc7-supply = <&vcc5v0_sys>;
++ vcc8-supply = <&vcc5v0_sys>;
++ vcc9-supply = <&vcc5v0_sys>;
++ vcc10-supply = <&vcc5v0_sys>;
++ vcc11-supply = <&vcc_2v0_pldo_s3>;
++ vcc12-supply = <&vcc5v0_sys>;
++ vcc13-supply = <&vcc_1v1_nldo_s3>;
++ vcc14-supply = <&vcc_1v1_nldo_s3>;
++ vcca-supply = <&vcc5v0_sys>;
++
++ rk806_dvs1_null: dvs1-null-pins {
++ pins = "gpio_pwrctrl1";
++ function = "pin_fun0";
++ };
++
++ rk806_dvs2_null: dvs2-null-pins {
++ pins = "gpio_pwrctrl2";
++ function = "pin_fun0";
++ };
++
++ rk806_dvs3_null: dvs3-null-pins {
++ pins = "gpio_pwrctrl3";
++ function = "pin_fun0";
++ };
++
++ regulators {
++ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_gpu_s0";
++ regulator-enable-ramp-delay = <400>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_cpu_lit_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_log_s0: dcdc-reg3 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <750000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_log_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <750000>;
++ };
++ };
++
++ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_vdenc_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_ddr_s0: dcdc-reg5 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <900000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_ddr_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <850000>;
++ };
++ };
++
++ vdd2_ddr_s3: dcdc-reg6 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-name = "vdd2_ddr_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vcc_2v0_pldo_s3: dcdc-reg7 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <2000000>;
++ regulator-max-microvolt = <2000000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_2v0_pldo_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <2000000>;
++ };
++ };
++
++ vcc_3v3_s3: dcdc-reg8 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-name = "vcc_3v3_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vddq_ddr_s0: dcdc-reg9 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-name = "vddq_ddr_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_1v8_s3: dcdc-reg10 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "vcc_1v8_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ avcc_1v8_s0: pldo-reg1 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "avcc_1v8_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_1v8_s0: pldo-reg2 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "vcc_1v8_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ avdd_1v2_s0: pldo-reg3 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ regulator-name = "avdd_1v2_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_3v3_s0: pldo-reg4 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vcc_3v3_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vccio_sd_s0: pldo-reg5 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vccio_sd_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ pldo6_s3: pldo-reg6 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "pldo6_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vdd_0v75_s3: nldo-reg1 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <750000>;
++ regulator-name = "vdd_0v75_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <750000>;
++ };
++ };
++
++ vdd_ddr_pll_s0: nldo-reg2 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <850000>;
++ regulator-max-microvolt = <850000>;
++ regulator-name = "vdd_ddr_pll_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <850000>;
++ };
++ };
++
++ avdd_0v75_s0: nldo-reg3 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <750000>;
++ regulator-name = "avdd_0v75_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_0v85_s0: nldo-reg4 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <850000>;
++ regulator-max-microvolt = <850000>;
++ regulator-name = "vdd_0v85_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_0v75_s0: nldo-reg5 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <750000>;
++ regulator-name = "vdd_0v75_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++};
++
++&u2phy0 {
++ status = "okay";
++};
++
++&u2phy0_otg {
++ status = "okay";
++};
++
++&u2phy1 {
++ status = "okay";
++};
++
++&u2phy1_otg {
++ status = "okay";
++};
++
++&u2phy3 {
++ status = "okay";
++};
++
++&u2phy3_host {
++ phy-supply = <&vcc5v0_host>;
++ status = "okay";
++};
++
++&uart2 {
++ pinctrl-0 = <&uart2m0_xfer>;
++ status = "okay";
++};
++
++&usbdp_phy1 {
++ status = "okay";
++};
++
++&usb_host1_ehci {
++ status = "okay";
++};
++
++&usb_host1_ohci {
++ status = "okay";
++};
++
++&usb_host1_xhci {
++ dr_mode = "host";
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/056-02-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch b/target/linux/rockchip/patches-6.6/056-02-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch
new file mode 100644
index 0000000000..d0b8336ef2
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/056-02-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch
@@ -0,0 +1,79 @@
+From 2f8064b9c4a012b4d4e8383818f13b682b6c156a Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:52 +0400
+Subject: [PATCH] arm64: dts: rockchip: enable thermal management on all RK3588
+ boards
+
+This enables the on-chip thermal monitoring sensor (TSADC) on all
+RK3588(s) boards that don't have it enabled yet. It provides temperature
+monitoring for the SoC and emergency thermal shutdowns, and is thus
+important to have in place before CPU DVFS is enabled, as high CPU
+operating performance points can overheat the chip quickly in the
+absence of thermal management.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-2-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 4 ++++
+ 8 files changed, 32 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
+@@ -673,6 +673,10 @@
+ };
+ };
+
++&tsadc {
++ status = "okay";
++};
++
+ &u2phy0 {
+ status = "okay";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+@@ -807,6 +807,10 @@
+ status = "okay";
+ };
+
++&tsadc {
++ status = "okay";
++};
++
+ &u2phy2 {
+ status = "okay";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -787,6 +787,10 @@
+ };
+ };
+
++&tsadc {
++ status = "okay";
++};
++
+ &uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -741,6 +741,10 @@
+ };
+ };
+
++&tsadc {
++ status = "okay";
++};
++
+ &u2phy0 {
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..6bcde5b8eb
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,35 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Marius Durbaca <mariusd84@gmail.com>
+Date: Tue Feb 27 16:25:27 2024 +0200
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
+E25
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Marius Durbaca <mariusd84@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
+@@ -9,6 +9,10 @@
+
+ aliases {
+ mmc1 = &sdmmc0;
++ led-boot = &led_user;
++ led-failsafe = &led_user;
++ led-running = &led_user;
++ led-upgrade = &led_user;
+ };
+
+ pwm-leds {
+--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
+@@ -23,7 +23,7 @@
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_HEARTBEAT;
+ color = <LED_COLOR_ID_GREEN>;
+- linux,default-trigger = "heartbeat";
++ default-state = "on";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_user_en>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases.patch b/target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases.patch
deleted file mode 100644
index 75038c7f39..0000000000
--- a/target/linux/rockchip/patches-6.6/112-radxa-e25-add-led-aliases.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Marius Durbaca <mariusd84@gmail.com>
-Date: Tue Feb 27 16:25:27 2024 +0200
-Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
-E25
-
-Add OpenWrt's LED aliases for showing system status.
-
-Signed-off-by: Marius Durbaca <mariusd84@gmail.com>
----
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-@@ -9,6 +9,10 @@
-
- aliases {
- mmc1 = &sdmmc0;
-+ led-boot = &led_user;
-+ led-failsafe = &led_user;
-+ led-running = &led_user;
-+ led-upgrade = &led_user;
- };
-
- pwm-leds {
diff --git a/target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..48a617b09a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,38 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -18,6 +18,10 @@
+ mmc0 = &emmc;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
++ led-boot = &blue_led;
++ led-failsafe = &blue_led;
++ led-running = &blue_led;
++ led-upgrade = &blue_led;
+ };
+
+ chosen {
+@@ -29,22 +33,19 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&green_led>, <&heartbeat_led>;
+
+- green-led {
++ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+- label = "rockpis:green:power";
+ linux,default-trigger = "default-on";
+ };
+
+- blue-led {
++ blue_led: led-1 {
+ color = <LED_COLOR_ID_BLUE>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+- label = "rockpis:blue:user";
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..e2ea7fdd63
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,27 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+@@ -23,6 +23,10 @@
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &emmc;
++ led-boot = &led_blue;
++ led-failsafe = &led_blue;
++ led-running = &led_blue;
++ led-upgrade = &led_blue;
+ };
+
+ chosen {
+@@ -55,10 +59,11 @@
+ pinctrl-0 = <&led_pin>;
+ pinctrl-names = "default";
+
+- led-0 {
++ led_blue: led-0 {
+ color = <LED_COLOR_ID_BLUE>;
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..bdcc96ce83
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,29 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+@@ -15,6 +15,10 @@
+ ethernet0 = &gmac1;
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
++ led-boot = &led_blue;
++ led-failsafe = &led_blue;
++ led-running = &led_blue;
++ led-upgrade = &led_blue;
+ };
+
+ chosen: chosen {
+@@ -42,11 +46,11 @@
+ leds {
+ compatible = "gpio-leds";
+
+- led_user: led-0 {
+- gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+- function = LED_FUNCTION_HEARTBEAT;
++ led_blue: led-0 {
+ color = <LED_COLOR_ID_BLUE>;
+- linux,default-trigger = "heartbeat";
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_user_en>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch b/target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
new file mode 100644
index 0000000000..c09915b0e8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
+ Rock 5A
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -14,6 +14,11 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
++
++ led-boot = &status_led;
++ led-failsafe = &status_led;
++ led-running = &status_led;
++ led-upgrade = &status_led;
+ };
+
+ analog-sound {
+@@ -39,11 +44,10 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&io_led>;
+
+- io-led {
++ status_led: io-led {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch b/target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch
new file mode 100644
index 0000000000..675d083a3a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: lower mmc speed for Radxa Rock 5A
+
+The previously stated speed of sdr-104 in is too high for the hardware
+to reliably communicate with some fast SD cards.
+Rockchip boards have a common bug when operating uhs speed, which will
+hang the system during a soft reboot.
+
+To be on the safe side, lower the speed to workaround.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -404,7 +404,7 @@
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+- sd-uhs-sdr104;
++ sd-uhs-sdr50;
+ vmmc-supply = <&vcc_3v3_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch b/target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
new file mode 100644
index 0000000000..5ac968aa75
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
+ Rock 5B
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -14,6 +14,11 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
++
++ led-boot = &status_led;
++ led-failsafe = &status_led;
++ led-running = &status_led;
++ led-upgrade = &status_led;
+ };
+
+ chosen {
+@@ -42,11 +47,10 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_rgb_b>;
+
+- led_rgb_b {
++ status_led: led_rgb_b {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch b/target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch
new file mode 100644
index 0000000000..496a2911e0
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: lower mmc speed for Radxa Rock 5B
+
+The previously stated speed of sdr-104 in is too high for the hardware
+to reliably communicate with some fast SD cards.
+Rockchip boards have a common bug when operating uhs speed, which will
+hang the system during a soft reboot.
+
+To be on the safe side, lower the speed to workaround.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -419,7 +419,7 @@
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+- sd-uhs-sdr104;
++ sd-uhs-sdr50;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch b/target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch
new file mode 100644
index 0000000000..006c8523c9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch
@@ -0,0 +1,22 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -20,6 +20,10 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
++ led-boot = &sys_led;
++ led-failsafe = &sys_led;
++ led-running = &sys_led;
++ led-upgrade = &sys_led;
+ };
+
+ adc-keys-0 {
+@@ -53,7 +57,7 @@
+ sys_led: led-0 {
+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ label = "system-led";
+- linux,default-trigger = "heartbeat";
++ default-state = "on";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sys_led_pin>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch b/target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch
new file mode 100644
index 0000000000..bbcff01790
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch
@@ -0,0 +1,11 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+@@ -616,7 +616,7 @@
+ disable-wp;
+ no-mmc;
+ no-sdio;
+- sd-uhs-sdr104;
++ sd-uhs-sdr50;
+ vmmc-supply = <&vcc3v3_sd_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..ee5a297887
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,29 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+@@ -16,6 +16,10 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
++ led-boot = &led_blue;
++ led-failsafe = &led_blue;
++ led-running = &led_blue;
++ led-upgrade = &led_blue;
+ };
+
+ chosen: chosen {
+@@ -43,11 +47,11 @@
+ leds {
+ compatible = "gpio-leds";
+
+- led-0 {
+- gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+- function = LED_FUNCTION_HEARTBEAT;
++ led_blue: led-0 {
+ color = <LED_COLOR_ID_BLUE>;
+- linux,default-trigger = "heartbeat";
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led2>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..81a86e5edb
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,30 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -6,6 +6,13 @@
+ #include "rk3566.dtsi"
+
+ / {
++ aliases {
++ led-boot = &led_green;
++ led-failsafe = &led_green;
++ led-running = &led_green;
++ led-upgrade = &led_green;
++ };
++
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+@@ -26,12 +33,11 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led2>;
+
+- led-green {
++ led_green: led-green {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..420f3ccc4c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,27 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+@@ -18,6 +18,10 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc2;
++ led-boot = &led_green;
++ led-failsafe = &led_green;
++ led-running = &led_green;
++ led-upgrade = &led_green;
+ };
+
+ chosen {
+@@ -47,12 +51,11 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&led>;
+
+- led-0 {
++ led_green: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/125-arm64-dts-rockchip-Update-LED-properties-for-ArmSom-Sige7.patch b/target/linux/rockchip/patches-6.6/125-arm64-dts-rockchip-Update-LED-properties-for-ArmSom-Sige7.patch
new file mode 100644
index 0000000000..051efa7dbd
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/125-arm64-dts-rockchip-Update-LED-properties-for-ArmSom-Sige7.patch
@@ -0,0 +1,25 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Sep 23 13:22:56 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for ArmSom
+ Sige7
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
+@@ -13,6 +13,11 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
++
++ led-boot = &led_red;
++ led-failsafe = &led_red;
++ led-running = &led_red;
++ led-upgrade = &led_red;
+ };
+
+ chosen {
diff --git a/target/linux/rockchip/patches-6.6/126-arm64-dts-rockchip-lower-mmc-speed-for-ArmSom-Sige7.patch b/target/linux/rockchip/patches-6.6/126-arm64-dts-rockchip-lower-mmc-speed-for-ArmSom-Sige7.patch
new file mode 100644
index 0000000000..01f1c74370
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/126-arm64-dts-rockchip-lower-mmc-speed-for-ArmSom-Sige7.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Sep 23 13:22:56 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: lower mmc speed for ArmSom Sige7
+
+The previously stated speed of sdr-104 in is too high for the hardware
+to reliably communicate with some fast SD cards.
+Rockchip boards have a common bug when operating uhs speed, which will
+hang the system during a soft reboot.
+
+To be on the safe side, lower the speed to workaround.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
+@@ -346,7 +346,7 @@
+ max-frequency = <200000000>;
+ no-sdio;
+ no-mmc;
+- sd-uhs-sdr104;
++ sd-uhs-sdr50;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch b/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch
deleted file mode 100644
index 0be9a7300b..0000000000
--- a/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch
+++ /dev/null
@@ -1,340 +0,0 @@
-From patchwork Sat Nov 12 14:10:58 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Aurelien Jarno <aurelien@aurel32.net>
-X-Patchwork-Id: 13041222
-Return-Path:
- <linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-From: Aurelien Jarno <aurelien@aurel32.net>
-To: Olivia Mackall <olivia@selenic.com>,
- Herbert Xu <herbert@gondor.apana.org.au>,
- Rob Herring <robh+dt@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Heiko Stuebner <heiko@sntech.de>,
- Philipp Zabel <p.zabel@pengutronix.de>,
- Lin Jinhan <troy.lin@rock-chips.com>
-Cc: linux-crypto@vger.kernel.org (open list:HARDWARE RANDOM NUMBER GENERATOR
- CORE),
- devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
- BINDINGS),
- linux-arm-kernel@lists.infradead.org (moderated list:ARM/Rockchip SoC
- support),
- linux-rockchip@lists.infradead.org (open list:ARM/Rockchip SoC support),
- linux-kernel@vger.kernel.org (open list),
- Aurelien Jarno <aurelien@aurel32.net>
-Subject: [PATCH v1 2/3] hwrng: add Rockchip SoC hwrng driver
-Date: Sat, 12 Nov 2022 15:10:58 +0100
-Message-Id: <20221112141059.3802506-3-aurelien@aurel32.net>
-In-Reply-To: <20221112141059.3802506-1-aurelien@aurel32.net>
-References: <20221112141059.3802506-1-aurelien@aurel32.net>
-MIME-Version: 1.0
-List-Id: <linux-arm-kernel.lists.infradead.org>
-
-Rockchip SoCs used to have a random number generator as part of their
-crypto device, and support for it has to be added to the corresponding
-driver. However newer Rockchip SoCs like the RK356x have an independent
-True Random Number Generator device. This patch adds a driver for it,
-greatly inspired from the downstream driver.
-
-The TRNG device does not seem to have a signal conditionner and the FIPS
-140-2 test returns a lot of failures. They can be reduced by increasing
-RK_RNG_SAMPLE_CNT, in a tradeoff between quality and speed. This value
-has been adjusted to get ~90% of successes and the quality value has
-been set accordingly.
-
-Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
----
- drivers/char/hw_random/Kconfig | 14 ++
- drivers/char/hw_random/Makefile | 1 +
- drivers/char/hw_random/rockchip-rng.c | 251 ++++++++++++++++++++++++++
- 3 files changed, 266 insertions(+)
- create mode 100644 drivers/char/hw_random/rockchip-rng.c
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -573,6 +573,20 @@ config HW_RANDOM_JH7110
- To compile this driver as a module, choose M here.
- The module will be called jh7110-trng.
-
-+config HW_RANDOM_ROCKCHIP
-+ tristate "Rockchip True Random Number Generator"
-+ depends on HW_RANDOM && (ARCH_ROCKCHIP || COMPILE_TEST)
-+ depends on HAS_IOMEM
-+ default HW_RANDOM
-+ help
-+ This driver provides kernel-side support for the True Random Number
-+ Generator hardware found on some Rockchip SoC like RK3566 or RK3568.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called rockchip-rng.
-+
-+ If unsure, say Y.
-+
- endif # HW_RANDOM
-
- config UML_RANDOM
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -48,4 +48,5 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphe
- obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
- obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
- obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
-+obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
- obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
---- /dev/null
-+++ b/drivers/char/hw_random/rockchip-rng.c
-@@ -0,0 +1,251 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * rockchip-rng.c True Random Number Generator driver for Rockchip SoCs
-+ *
-+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd.
-+ * Copyright (c) 2022, Aurelien Jarno
-+ * Authors:
-+ * Lin Jinhan <troy.lin@rock-chips.com>
-+ * Aurelien Jarno <aurelien@aurel32.net>
-+ */
-+#include <linux/clk.h>
-+#include <linux/hw_random.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+#include <linux/slab.h>
-+
-+#define RK_RNG_AUTOSUSPEND_DELAY 100
-+#define RK_RNG_MAX_BYTE 32
-+#define RK_RNG_POLL_PERIOD_US 100
-+#define RK_RNG_POLL_TIMEOUT_US 10000
-+
-+/*
-+ * TRNG collects osc ring output bit every RK_RNG_SAMPLE_CNT time. The value is
-+ * a tradeoff between speed and quality and has been adjusted to get a quality
-+ * of ~900 (~90% of FIPS 140-2 successes).
-+ */
-+#define RK_RNG_SAMPLE_CNT 1000
-+
-+/* TRNG registers from RK3568 TRM-Part2, section 5.4.1 */
-+#define TRNG_RST_CTL 0x0004
-+#define TRNG_RNG_CTL 0x0400
-+#define TRNG_RNG_CTL_LEN_64_BIT (0x00 << 4)
-+#define TRNG_RNG_CTL_LEN_128_BIT (0x01 << 4)
-+#define TRNG_RNG_CTL_LEN_192_BIT (0x02 << 4)
-+#define TRNG_RNG_CTL_LEN_256_BIT (0x03 << 4)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_0 (0x00 << 2)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_1 (0x01 << 2)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_2 (0x02 << 2)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_3 (0x03 << 2)
-+#define TRNG_RNG_CTL_ENABLE BIT(1)
-+#define TRNG_RNG_CTL_START BIT(0)
-+#define TRNG_RNG_SAMPLE_CNT 0x0404
-+#define TRNG_RNG_DOUT_0 0x0410
-+#define TRNG_RNG_DOUT_1 0x0414
-+#define TRNG_RNG_DOUT_2 0x0418
-+#define TRNG_RNG_DOUT_3 0x041c
-+#define TRNG_RNG_DOUT_4 0x0420
-+#define TRNG_RNG_DOUT_5 0x0424
-+#define TRNG_RNG_DOUT_6 0x0428
-+#define TRNG_RNG_DOUT_7 0x042c
-+
-+struct rk_rng {
-+ struct hwrng rng;
-+ void __iomem *base;
-+ struct reset_control *rst;
-+ int clk_num;
-+ struct clk_bulk_data *clk_bulks;
-+};
-+
-+/* The mask determine the bits that are updated */
-+static void rk_rng_write_ctl(struct rk_rng *rng, u32 val, u32 mask)
-+{
-+ writel_relaxed((mask << 16) | val, rng->base + TRNG_RNG_CTL);
-+}
-+
-+static int rk_rng_init(struct hwrng *rng)
-+{
-+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
-+ u32 reg;
-+ int ret;
-+
-+ /* start clocks */
-+ ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks);
-+ if (ret < 0) {
-+ dev_err((struct device *) rk_rng->rng.priv,
-+ "Failed to enable clks %d\n", ret);
-+ return ret;
-+ }
-+
-+ /* set the sample period */
-+ writel(RK_RNG_SAMPLE_CNT, rk_rng->base + TRNG_RNG_SAMPLE_CNT);
-+
-+ /* set osc ring speed and enable it */
-+ reg = TRNG_RNG_CTL_LEN_256_BIT |
-+ TRNG_RNG_CTL_OSC_RING_SPEED_0 |
-+ TRNG_RNG_CTL_ENABLE;
-+ rk_rng_write_ctl(rk_rng, reg, 0xffff);
-+
-+ return 0;
-+}
-+
-+static void rk_rng_cleanup(struct hwrng *rng)
-+{
-+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
-+ u32 reg;
-+
-+ /* stop TRNG */
-+ reg = 0;
-+ rk_rng_write_ctl(rk_rng, reg, 0xffff);
-+
-+ /* stop clocks */
-+ clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
-+}
-+
-+static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-+{
-+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
-+ u32 reg;
-+ int ret = 0;
-+ int i;
-+
-+ pm_runtime_get_sync((struct device *) rk_rng->rng.priv);
-+
-+ /* Start collecting random data */
-+ reg = TRNG_RNG_CTL_START;
-+ rk_rng_write_ctl(rk_rng, reg, reg);
-+
-+ ret = readl_poll_timeout(rk_rng->base + TRNG_RNG_CTL, reg,
-+ !(reg & TRNG_RNG_CTL_START),
-+ RK_RNG_POLL_PERIOD_US,
-+ RK_RNG_POLL_TIMEOUT_US);
-+ if (ret < 0)
-+ goto out;
-+
-+ /* Read random data stored in big endian in the registers */
-+ ret = min_t(size_t, max, RK_RNG_MAX_BYTE);
-+ for (i = 0; i < ret; i += 4) {
-+ reg = readl_relaxed(rk_rng->base + TRNG_RNG_DOUT_0 + i);
-+ *(u32 *)(buf + i) = be32_to_cpu(reg);
-+ }
-+
-+out:
-+ pm_runtime_mark_last_busy((struct device *) rk_rng->rng.priv);
-+ pm_runtime_put_sync_autosuspend((struct device *) rk_rng->rng.priv);
-+
-+ return ret;
-+}
-+
-+static int rk_rng_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct rk_rng *rk_rng;
-+ int ret;
-+
-+ rk_rng = devm_kzalloc(dev, sizeof(struct rk_rng), GFP_KERNEL);
-+ if (!rk_rng)
-+ return -ENOMEM;
-+
-+ rk_rng->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(rk_rng->base))
-+ return PTR_ERR(rk_rng->base);
-+
-+ rk_rng->clk_num = devm_clk_bulk_get_all(dev, &rk_rng->clk_bulks);
-+ if (rk_rng->clk_num < 0)
-+ return dev_err_probe(dev, rk_rng->clk_num,
-+ "Failed to get clks property\n");
-+
-+ rk_rng->rst = devm_reset_control_array_get(&pdev->dev, false, false);
-+ if (IS_ERR(rk_rng->rst))
-+ return dev_err_probe(dev, PTR_ERR(rk_rng->rst),
-+ "Failed to get reset property\n");
-+
-+ reset_control_assert(rk_rng->rst);
-+ udelay(2);
-+ reset_control_deassert(rk_rng->rst);
-+
-+ platform_set_drvdata(pdev, rk_rng);
-+
-+ rk_rng->rng.name = dev_driver_string(dev);
-+#ifndef CONFIG_PM
-+ rk_rng->rng.init = rk_rng_init;
-+ rk_rng->rng.cleanup = rk_rng_cleanup;
-+#endif
-+ rk_rng->rng.read = rk_rng_read;
-+ rk_rng->rng.priv = (unsigned long) dev;
-+ rk_rng->rng.quality = 900;
-+
-+ pm_runtime_set_autosuspend_delay(dev, RK_RNG_AUTOSUSPEND_DELAY);
-+ pm_runtime_use_autosuspend(dev);
-+ pm_runtime_enable(dev);
-+
-+ ret = devm_hwrng_register(dev, &rk_rng->rng);
-+ if (ret)
-+ return dev_err_probe(&pdev->dev, ret, "Failed to register Rockchip hwrng\n");
-+
-+ dev_info(&pdev->dev, "Registered Rockchip hwrng\n");
-+
-+ return 0;
-+}
-+
-+static int rk_rng_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int rk_rng_runtime_suspend(struct device *dev)
-+{
-+ struct rk_rng *rk_rng = dev_get_drvdata(dev);
-+
-+ rk_rng_cleanup(&rk_rng->rng);
-+
-+ return 0;
-+}
-+
-+static int rk_rng_runtime_resume(struct device *dev)
-+{
-+ struct rk_rng *rk_rng = dev_get_drvdata(dev);
-+
-+ return rk_rng_init(&rk_rng->rng);
-+}
-+#endif
-+
-+static const struct dev_pm_ops rk_rng_pm_ops = {
-+ SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend,
-+ rk_rng_runtime_resume, NULL)
-+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-+ pm_runtime_force_resume)
-+};
-+
-+static const struct of_device_id rk_rng_dt_match[] = {
-+ {
-+ .compatible = "rockchip,rk3568-rng",
-+ },
-+ {},
-+};
-+
-+MODULE_DEVICE_TABLE(of, rk_rng_dt_match);
-+
-+static struct platform_driver rk_rng_driver = {
-+ .driver = {
-+ .name = "rockchip-rng",
-+ .pm = &rk_rng_pm_ops,
-+ .of_match_table = rk_rng_dt_match,
-+ },
-+ .probe = rk_rng_probe,
-+ .remove = rk_rng_remove,
-+};
-+
-+module_platform_driver(rk_rng_driver);
-+
-+MODULE_DESCRIPTION("Rockchip True Random Number Generator driver");
-+MODULE_AUTHOR("Lin Jinhan <troy.lin@rock-chips.com>, Aurelien Jarno <aurelien@aurel32.net>");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch b/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch
new file mode 100644
index 0000000000..683d1b1d5e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch
@@ -0,0 +1,290 @@
+From cea47ad1fbd46d3096fcf5c6905db3d12b5da960 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sun, 21 Jul 2024 01:48:04 +0100
+Subject: [PATCH 2/3] hwrng: add hwrng driver for Rockchip RK3568 SoC
+
+Rockchip SoCs used to have a random number generator as part of their
+crypto device, and support for it has to be added to the corresponding
+driver. However newer Rockchip SoCs like the RK3568 have an independent
+True Random Number Generator device. This patch adds a driver for it,
+greatly inspired from the downstream driver.
+
+The TRNG device does not seem to have a signal conditionner and the FIPS
+140-2 test returns a lot of failures. They can be reduced by increasing
+rockchip,sample-count in DT, in a tradeoff between quality and speed.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+[daniel@makrotpia.org: code style fixes, add DT properties]
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+---
+ drivers/char/hw_random/Kconfig | 14 ++
+ drivers/char/hw_random/Makefile | 1 +
+ drivers/char/hw_random/rockchip-rng.c | 230 ++++++++++++++++++++++++++
+ 4 files changed, 246 insertions(+)
+ create mode 100644 drivers/char/hw_random/rockchip-rng.c
+
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -573,6 +573,20 @@ config HW_RANDOM_JH7110
+ To compile this driver as a module, choose M here.
+ The module will be called jh7110-trng.
+
++config HW_RANDOM_ROCKCHIP
++ tristate "Rockchip True Random Number Generator"
++ depends on HW_RANDOM && (ARCH_ROCKCHIP || COMPILE_TEST)
++ depends on HAS_IOMEM
++ default HW_RANDOM
++ help
++ This driver provides kernel-side support for the True Random Number
++ Generator hardware found on some Rockchip SoC like RK3566 or RK3568.
++
++ To compile this driver as a module, choose M here: the
++ module will be called rockchip-rng.
++
++ If unsure, say Y.
++
+ endif # HW_RANDOM
+
+ config UML_RANDOM
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -48,4 +48,5 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphe
+ obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
+ obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
+ obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
++obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
+ obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
+--- /dev/null
++++ b/drivers/char/hw_random/rockchip-rng.c
+@@ -0,0 +1,230 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * rockchip-rng.c True Random Number Generator driver for Rockchip RK3568 SoC
++ *
++ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd.
++ * Copyright (c) 2022, Aurelien Jarno
++ * Authors:
++ * Lin Jinhan <troy.lin@rock-chips.com>
++ * Aurelien Jarno <aurelien@aurel32.net>
++ */
++#include <linux/clk.h>
++#include <linux/hw_random.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++#define RK_RNG_AUTOSUSPEND_DELAY 100
++#define RK_RNG_MAX_BYTE 32
++#define RK_RNG_POLL_PERIOD_US 100
++#define RK_RNG_POLL_TIMEOUT_US 10000
++
++/* TRNG registers from RK3568 TRM-Part2, section 5.4.1 */
++#define TRNG_RST_CTL 0x0004
++#define TRNG_RNG_CTL 0x0400
++#define TRNG_RNG_CTL_LEN_64_BIT (0x00 << 4)
++#define TRNG_RNG_CTL_LEN_128_BIT (0x01 << 4)
++#define TRNG_RNG_CTL_LEN_192_BIT (0x02 << 4)
++#define TRNG_RNG_CTL_LEN_256_BIT (0x03 << 4)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_0 (0x00 << 2)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_1 (0x01 << 2)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_2 (0x02 << 2)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_3 (0x03 << 2)
++#define TRNG_RNG_CTL_MASK GENMASK(15, 0)
++#define TRNG_RNG_CTL_ENABLE BIT(1)
++#define TRNG_RNG_CTL_START BIT(0)
++#define TRNG_RNG_SAMPLE_CNT 0x0404
++#define TRNG_RNG_DOUT 0x0410
++
++struct rk_rng {
++ struct hwrng rng;
++ void __iomem *base;
++ struct reset_control *rst;
++ int clk_num;
++ struct clk_bulk_data *clk_bulks;
++ u32 sample_cnt;
++};
++
++/* The mask in the upper 16 bits determines the bits that are updated */
++static void rk_rng_write_ctl(struct rk_rng *rng, u32 val, u32 mask)
++{
++ writel((mask << 16) | val, rng->base + TRNG_RNG_CTL);
++}
++
++static int rk_rng_init(struct hwrng *rng)
++{
++ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
++ int ret;
++
++ /* start clocks */
++ ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks);
++ if (ret < 0) {
++ dev_err((struct device *) rk_rng->rng.priv,
++ "Failed to enable clks %d\n", ret);
++ return ret;
++ }
++
++ /* set the sample period */
++ writel(rk_rng->sample_cnt, rk_rng->base + TRNG_RNG_SAMPLE_CNT);
++
++ /* set osc ring speed and enable it */
++ rk_rng_write_ctl(rk_rng, TRNG_RNG_CTL_LEN_256_BIT |
++ TRNG_RNG_CTL_OSC_RING_SPEED_0 |
++ TRNG_RNG_CTL_ENABLE,
++ TRNG_RNG_CTL_MASK);
++
++ return 0;
++}
++
++static void rk_rng_cleanup(struct hwrng *rng)
++{
++ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
++
++ /* stop TRNG */
++ rk_rng_write_ctl(rk_rng, 0, TRNG_RNG_CTL_MASK);
++
++ /* stop clocks */
++ clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
++}
++
++static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
++{
++ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
++ size_t to_read = min_t(size_t, max, RK_RNG_MAX_BYTE);
++ u32 reg;
++ int ret = 0;
++
++ ret = pm_runtime_resume_and_get((struct device *) rk_rng->rng.priv);
++ if (ret < 0)
++ return ret;
++
++ /* Start collecting random data */
++ rk_rng_write_ctl(rk_rng, TRNG_RNG_CTL_START, TRNG_RNG_CTL_START);
++
++ ret = readl_poll_timeout(rk_rng->base + TRNG_RNG_CTL, reg,
++ !(reg & TRNG_RNG_CTL_START),
++ RK_RNG_POLL_PERIOD_US,
++ RK_RNG_POLL_TIMEOUT_US);
++ if (ret < 0)
++ goto out;
++
++ /* Read random data stored in the registers */
++ memcpy_fromio(buf, rk_rng->base + TRNG_RNG_DOUT, to_read);
++out:
++ pm_runtime_mark_last_busy((struct device *) rk_rng->rng.priv);
++ pm_runtime_put_sync_autosuspend((struct device *) rk_rng->rng.priv);
++
++ return (ret < 0) ? ret : to_read;
++}
++
++static int rk_rng_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct rk_rng *rk_rng;
++ u32 quality;
++ int ret;
++
++ rk_rng = devm_kzalloc(dev, sizeof(*rk_rng), GFP_KERNEL);
++ if (!rk_rng)
++ return -ENOMEM;
++
++ rk_rng->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(rk_rng->base))
++ return PTR_ERR(rk_rng->base);
++
++ rk_rng->clk_num = devm_clk_bulk_get_all(dev, &rk_rng->clk_bulks);
++ if (rk_rng->clk_num < 0)
++ return dev_err_probe(dev, rk_rng->clk_num,
++ "Failed to get clks property\n");
++
++ rk_rng->rst = devm_reset_control_array_get_exclusive(&pdev->dev);
++ if (IS_ERR(rk_rng->rst))
++ return dev_err_probe(dev, PTR_ERR(rk_rng->rst),
++ "Failed to get reset property\n");
++
++ ret = of_property_read_u32(dev->of_node, "rockchip,sample-count", &rk_rng->sample_cnt);
++ if (ret)
++ return dev_err_probe(dev, ret, "Failed to get sample-count property\n");
++
++ ret = of_property_read_u32(dev->of_node, "quality", &quality);
++ if (ret || quality > 1024)
++ return dev_err_probe(dev, ret, "Failed to get quality property\n");
++
++ reset_control_assert(rk_rng->rst);
++ udelay(2);
++ reset_control_deassert(rk_rng->rst);
++
++ platform_set_drvdata(pdev, rk_rng);
++
++ rk_rng->rng.name = dev_driver_string(dev);
++ if (!IS_ENABLED(CONFIG_PM)) {
++ rk_rng->rng.init = rk_rng_init;
++ rk_rng->rng.cleanup = rk_rng_cleanup;
++ }
++ rk_rng->rng.read = rk_rng_read;
++ rk_rng->rng.priv = (unsigned long) dev;
++ rk_rng->rng.quality = quality;
++
++ pm_runtime_set_autosuspend_delay(dev, RK_RNG_AUTOSUSPEND_DELAY);
++ pm_runtime_use_autosuspend(dev);
++ devm_pm_runtime_enable(dev);
++
++ ret = devm_hwrng_register(dev, &rk_rng->rng);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "Failed to register Rockchip hwrng\n");
++
++ return 0;
++}
++
++static int __maybe_unused rk_rng_runtime_suspend(struct device *dev)
++{
++ struct rk_rng *rk_rng = dev_get_drvdata(dev);
++
++ rk_rng_cleanup(&rk_rng->rng);
++
++ return 0;
++}
++
++static int __maybe_unused rk_rng_runtime_resume(struct device *dev)
++{
++ struct rk_rng *rk_rng = dev_get_drvdata(dev);
++
++ return rk_rng_init(&rk_rng->rng);
++}
++
++static const struct dev_pm_ops rk_rng_pm_ops = {
++ SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend,
++ rk_rng_runtime_resume, NULL)
++ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
++ pm_runtime_force_resume)
++};
++
++static const struct of_device_id rk_rng_dt_match[] = {
++ { .compatible = "rockchip,rk3568-rng", },
++ { /* sentinel */ },
++};
++
++MODULE_DEVICE_TABLE(of, rk_rng_dt_match);
++
++static struct platform_driver rk_rng_driver = {
++ .driver = {
++ .name = "rockchip-rng",
++ .pm = &rk_rng_pm_ops,
++ .of_match_table = rk_rng_dt_match,
++ },
++ .probe = rk_rng_probe,
++};
++
++module_platform_driver(rk_rng_driver);
++
++MODULE_DESCRIPTION("Rockchip RK3568 True Random Number Generator driver");
++MODULE_AUTHOR("Lin Jinhan <troy.lin@rock-chips.com>");
++MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch
new file mode 100644
index 0000000000..130bf6723c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch
@@ -0,0 +1,49 @@
+From 756e7d3251ad8f6c72e7bf4c476537a89f673e38 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sun, 21 Jul 2024 01:48:38 +0100
+Subject: [PATCH 3/3] arm64: dts: rockchip: add DT entry for RNG to RK356x
+
+Enable the just added Rockchip RNG driver for RK356x SoCs.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3568.dtsi | 7 +++++++
+ arch/arm64/boot/dts/rockchip/rk356x.dtsi | 10 ++++++++++
+ 2 files changed, 17 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+@@ -257,6 +257,13 @@
+ };
+ };
+
++&rng {
++ rockchip,sample-count = <1000>;
++ quality = <900>;
++
++ status = "okay";
++};
++
+ &usb_host0_xhci {
+ phys = <&usb2phy0_otg>, <&combphy0 PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+@@ -1106,6 +1106,16 @@
+ status = "disabled";
+ };
+
++ rng: rng@fe388000 {
++ compatible = "rockchip,rk3568-rng";
++ reg = <0x0 0xfe388000 0x0 0x4000>;
++ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>;
++ clock-names = "core", "ahb";
++ resets = <&cru SRST_TRNG_NS>;
++ reset-names = "reset";
++ status = "disabled";
++ };
++
+ i2s0_8ch: i2s@fe400000 {
+ compatible = "rockchip,rk3568-i2s-tdm";
+ reg = <0x0 0xfe400000 0x0 0x1000>;
diff --git a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch
deleted file mode 100644
index 3e65de7a20..0000000000
--- a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From patchwork Sat Nov 12 14:10:59 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Aurelien Jarno <aurelien@aurel32.net>
-X-Patchwork-Id: 13041221
-From: Aurelien Jarno <aurelien@aurel32.net>
-To: Olivia Mackall <olivia@selenic.com>,
- Herbert Xu <herbert@gondor.apana.org.au>,
- Rob Herring <robh+dt@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Heiko Stuebner <heiko@sntech.de>,
- Philipp Zabel <p.zabel@pengutronix.de>,
- Lin Jinhan <troy.lin@rock-chips.com>
-Cc: linux-crypto@vger.kernel.org (open list:HARDWARE RANDOM NUMBER GENERATOR
- CORE),
- devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
- BINDINGS),
- linux-arm-kernel@lists.infradead.org (moderated list:ARM/Rockchip SoC
- support),
- linux-rockchip@lists.infradead.org (open list:ARM/Rockchip SoC support),
- linux-kernel@vger.kernel.org (open list),
- Aurelien Jarno <aurelien@aurel32.net>
-Subject: [PATCH v1 3/3] arm64: dts: rockchip: add DT entry for RNG to RK356x
-Date: Sat, 12 Nov 2022 15:10:59 +0100
-Message-Id: <20221112141059.3802506-4-aurelien@aurel32.net>
-In-Reply-To: <20221112141059.3802506-1-aurelien@aurel32.net>
-References: <20221112141059.3802506-1-aurelien@aurel32.net>
-MIME-Version: 1.0
-List-Id: <linux-arm-kernel.lists.infradead.org>
-
-Enable the just added Rockchip RNG driver for RK356x SoCs.
-
-Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
----
- arch/arm64/boot/dts/rockchip/rk356x.dtsi | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
-@@ -1848,6 +1848,15 @@
- };
- };
-
-+ rng: rng@fe388000 {
-+ compatible = "rockchip,rk3568-rng";
-+ reg = <0x0 0xfe388000 0x0 0x4000>;
-+ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>;
-+ clock-names = "trng_clk", "trng_hclk";
-+ resets = <&cru SRST_TRNG_NS>;
-+ reset-names = "reset";
-+ };
-+
- pinctrl: pinctrl {
- compatible = "rockchip,rk3568-pinctrl";
- rockchip,grf = <&grf>;
diff --git a/target/linux/rockchip/patches-6.6/400-1-arm64-dts-rockchip-Add-common-definitions-for-NanoPi.patch b/target/linux/rockchip/patches-6.6/400-1-arm64-dts-rockchip-Add-common-definitions-for-NanoPi.patch
new file mode 100644
index 0000000000..37fb6693dc
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/400-1-arm64-dts-rockchip-Add-common-definitions-for-NanoPi.patch
@@ -0,0 +1,1573 @@
+From 93be10e4e180eeac9b6a57a4363e08c35bee3af9 Mon Sep 17 00:00:00 2001
+From: Sebastian Kropatsch <seb-dev@mail.de>
+Date: Wed, 12 Jun 2024 22:48:10 +0200
+Subject: [PATCH 1/5] arm64: dts: rockchip: Add common definitions for NanoPi
+ R6C and R6S
+
+The FriendlyElec NanoPi R6C and R6S are quite similar boards,
+although they differ in:
+- M.2 M-Key connector vs second RTL8125BG Ethernet port
+- One of the LEDs has a different function on each board
+- 12-pin GPIO FPC vs 30-pin GPIO header
+- R6S has a PWM-based IR receiver while the R6C has not
+- R6S has a 5V fan connector while the R6C has not
+
+Refactor their DT files by adding a common definitions file to
+improve differentiation clarity between both boards and to make
+hardware-specific DT changes easier in the long run.
+Do not introduce any functional changes.
+
+Signed-off-by: Sebastian Kropatsch <seb-dev@mail.de>
+---
+ .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 763 ++++++++++++++++++
+ .../boot/dts/rockchip/rk3588s-nanopi-r6c.dts | 2 +-
+ .../boot/dts/rockchip/rk3588s-nanopi-r6s.dts | 756 +----------------
+ 3 files changed, 767 insertions(+), 754 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+@@ -0,0 +1,763 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Common devicetree definitions for the NanoPi R6C and R6S
++ */
++
++/dts-v1/;
++
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include "rk3588s.dtsi"
++
++/ {
++ aliases {
++ ethernet0 = &gmac1;
++ mmc0 = &sdmmc;
++ mmc1 = &sdhci;
++ };
++
++ 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-maskrom {
++ label = "Maskrom";
++ linux,code = <KEY_VENDOR>;
++ press-threshold-microvolt = <1800>;
++ };
++ };
++
++ gpio-keys {
++ compatible = "gpio-keys";
++ pinctrl-names = "default";
++ pinctrl-0 = <&key1_pin>;
++
++ button-user {
++ label = "User";
++ linux,code = <BTN_1>;
++ gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
++ debounce-interval = <50>;
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ sys_led: led-0 {
++ label = "sys_led";
++ gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ pinctrl-names = "default";
++ pinctrl-0 = <&sys_led_pin>;
++ };
++
++ wan_led: led-1 {
++ label = "wan_led";
++ gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&wan_led_pin>;
++ };
++
++ lan1_led: led-2 {
++ label = "lan1_led";
++ gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&lan1_led_pin>;
++ };
++
++ lan2_led: led-3 {
++ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&lan2_led_pin>;
++ };
++ };
++
++ vcc5v0_sys: vcc5v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_1v1_nldo_s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1100000>;
++ regulator-max-microvolt = <1100000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc_3v3_s0: vcc-3v3-s0-regulator {
++ 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: vcc-3v3-sd-s0-regulator {
++ 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: 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>;
++ };
++
++ 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_usb_otg0: vcc5v0-usb-otg0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio1 RK_PD2 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>;
++ };
++
++ vcc5v0_host_20: vcc5v0-host-20-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&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>;
++ };
++};
++
++&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";
++};
++
++&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 = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
++ wakeup-source;
++ };
++};
++
++&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 {
++ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc_3v3_pcie20>;
++ status = "okay";
++};
++
++&pinctrl {
++ gpio-key {
++ key1_pin: key1-pin {
++ rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ gpio-leds {
++ sys_led_pin: sys-led-pin {
++ rockchip,pins =
++ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wan_led_pin: wan-led-pin {
++ rockchip,pins =
++ <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ lan1_led_pin: lan1-led-pin {
++ rockchip,pins =
++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ lan2_led_pin: lan2-led-pin {
++ rockchip,pins =
++ <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ 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 = <1 RK_PD2 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;
++ 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";
++};
++
++&u2phy2 {
++ status = "okay";
++};
++
++&u2phy2_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";
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
+@@ -2,7 +2,7 @@
+
+ /dts-v1/;
+
+-#include "rk3588s-nanopi-r6s.dts"
++#include "rk3588s-nanopi-r6.dtsi"
+
+ / {
+ model = "FriendlyElec NanoPi R6C";
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
+@@ -2,763 +2,13 @@
+
+ /dts-v1/;
+
+-#include <dt-bindings/pinctrl/rockchip.h>
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/input/input.h>
+-#include "rk3588s.dtsi"
++#include "rk3588s-nanopi-r6.dtsi"
+
+ / {
+ model = "FriendlyElec NanoPi R6S";
+ compatible = "friendlyarm,nanopi-r6s", "rockchip,rk3588s";
+-
+- aliases {
+- ethernet0 = &gmac1;
+- mmc0 = &sdmmc;
+- mmc1 = &sdhci;
+- };
+-
+- 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-maskrom {
+- label = "Maskrom";
+- linux,code = <KEY_VENDOR>;
+- press-threshold-microvolt = <1800>;
+- };
+- };
+-
+- gpio-keys {
+- compatible = "gpio-keys";
+- pinctrl-names = "default";
+- pinctrl-0 = <&key1_pin>;
+-
+- button-user {
+- label = "User";
+- linux,code = <BTN_1>;
+- gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
+- debounce-interval = <50>;
+- };
+- };
+-
+- leds {
+- compatible = "gpio-leds";
+-
+- sys_led: led-0 {
+- label = "sys_led";
+- gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+- pinctrl-names = "default";
+- pinctrl-0 = <&sys_led_pin>;
+- };
+-
+- wan_led: led-1 {
+- label = "wan_led";
+- gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&wan_led_pin>;
+- };
+-
+- lan1_led: led-2 {
+- label = "lan1_led";
+- gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&lan1_led_pin>;
+- };
+-
+- lan2_led: led-3 {
+- label = "lan2_led";
+- gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&lan2_led_pin>;
+- };
+- };
+-
+- vcc5v0_sys: vcc5v0-sys-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc5v0_sys";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- };
+-
+- vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc_1v1_nldo_s3";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <1100000>;
+- regulator-max-microvolt = <1100000>;
+- vin-supply = <&vcc5v0_sys>;
+- };
+-
+- vcc_3v3_s0: vcc-3v3-s0-regulator {
+- 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: vcc-3v3-sd-s0-regulator {
+- 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: 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>;
+- };
+-
+- 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_usb_otg0: vcc5v0-usb-otg0-regulator {
+- compatible = "regulator-fixed";
+- enable-active-high;
+- gpios = <&gpio1 RK_PD2 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>;
+- };
+-
+- vcc5v0_host_20: vcc5v0-host-20-regulator {
+- compatible = "regulator-fixed";
+- enable-active-high;
+- gpios = <&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>;
+- };
+-};
+-
+-&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";
+-};
+-
+-&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 = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+- wakeup-source;
+- };
+-};
+-
+-&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 {
+- reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc_3v3_pcie20>;
+- status = "okay";
+-};
+-
+-&pinctrl {
+- gpio-key {
+- key1_pin: key1-pin {
+- rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
+- };
+- };
+-
+- gpio-leds {
+- sys_led_pin: sys-led-pin {
+- rockchip,pins =
+- <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- wan_led_pin: wan-led-pin {
+- rockchip,pins =
+- <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- lan1_led_pin: lan1-led-pin {
+- rockchip,pins =
+- <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- lan2_led_pin: lan2-led-pin {
+- rockchip,pins =
+- <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+-
+- 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 = <1 RK_PD2 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;
+- 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";
+-};
+-
+-&u2phy2 {
+- status = "okay";
+-};
+-
+-&u2phy2_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";
++&lan2_led {
++ label = "lan2_led";
+ };
diff --git a/target/linux/rockchip/patches-6.6/400-2-arm64-dts-rockchip-Fix-regulators-gmac-and-naming-on.patch b/target/linux/rockchip/patches-6.6/400-2-arm64-dts-rockchip-Fix-regulators-gmac-and-naming-on.patch
new file mode 100644
index 0000000000..1ff8220bde
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/400-2-arm64-dts-rockchip-Fix-regulators-gmac-and-naming-on.patch
@@ -0,0 +1,470 @@
+From cd909b668132acd6f846336f15abf5185cfc4dbc Mon Sep 17 00:00:00 2001
+From: Sebastian Kropatsch <seb-dev@mail.de>
+Date: Wed, 12 Jun 2024 22:48:11 +0200
+Subject: [PATCH 2/5] arm64: dts: rockchip: Fix regulators, gmac and naming on
+ NanoPi R6C/R6S
+
+Fix the alphabetical ordering in some nodes and rename some regulators
+and pins to match the schematics [1][2] as well as to adhere to
+preferred naming schemes.
+
+In addition to that:
+* vcc_3v3_sd_s0: Fix voltage to be 3.3V
+* vcc3v3_pcie:
+ - Move to NanoPi R6C, this power switch is not available on R6S
+ - Fix vin-supply (is vcc_5v0 per schematics)
+ - Add gpios/pincrtl to enable power
+* vcc5v0_usb: Remove this regulator since according to the schematics,
+ vcc5v0_host_20 and vcc5v0_usb_otg0 are directly powered by vcc_5v0
+* gmac1: Add rx_delay of 0 (no delay since phy-mode = "rgmii-rxid")
+* rgmii_phy1: Add phy-supply as seen in schematics
+* pcie2*:
+ - Add pinctrl reset pins
+ - Update vpcie3v3-supply to match the schematics
+* sdhci: Add vmmc-supply and vqmmc-supply
+
+Links:
+[1] https://wiki.friendlyelec.com/wiki/images/f/f7/NanoPi_R6C_2302_SCH.PDF
+[2] https://wiki.friendlyelec.com/wiki/images/2/2f/NanoPi_R6S_2208_SCH.PDF
+
+Fixes: f1b11f43b3e9 ("arm64: dts: rockchip: Add support for NanoPi R6S")
+Signed-off-by: Sebastian Kropatsch <seb-dev@mail.de>
+---
+ .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 169 +++++++++---------
+ .../boot/dts/rockchip/rk3588s-nanopi-r6c.dts | 28 +++
+ .../boot/dts/rockchip/rk3588s-nanopi-r6s.dts | 5 +
+ 3 files changed, 122 insertions(+), 80 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+@@ -21,7 +21,7 @@
+ stdout-path = "serial2:1500000n8";
+ };
+
+- adc-keys {
++ adc-key-maskrom {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+@@ -41,10 +41,10 @@
+ pinctrl-0 = <&key1_pin>;
+
+ button-user {
+- label = "User";
+- linux,code = <BTN_1>;
+- gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <50>;
++ gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
++ label = "User Button";
++ linux,code = <BTN_1>;
+ };
+ };
+
+@@ -80,26 +80,27 @@
+ };
+ };
+
+- vcc5v0_sys: vcc5v0-sys-regulator {
++ vcc_5v0: regulator-vcc-5v0 {
+ compatible = "regulator-fixed";
+- regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
++ regulator-name = "vcc_5v0";
+ };
+
+- vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
++ 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>;
++ regulator-name = "vcc_1v1_nldo_s3";
++ vin-supply = <&vcc_5v0>;
+ };
+
+- vcc_3v3_s0: vcc-3v3-s0-regulator {
++ /* SY6280AAC power switch (U3824 in schematics) */
++ vcc_3v3_s0: regulator-vcc-3v3-s0 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+@@ -109,61 +110,45 @@
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+- vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
++ 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: 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>;
++ regulator-min-microvolt = <3300000>;
++ regulator-name = "vcc_3v3_sd_s0";
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+- 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_usb_otg0: vcc5v0-usb-otg0-regulator {
++ /* SY6280AAC power switch (U9539 in schematics) */
++ /* For USB 2.0 Type-A port */
++ vcc_5v0_host_20: regulator-vcc-5v0-host-20 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+- gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
++ gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+- pinctrl-0 = <&typec5v_pwren>;
+- regulator-name = "vcc5v0_usb_otg0";
++ pinctrl-0 = <&usb_host_pwren_h>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+- vin-supply = <&vcc5v0_usb>;
++ regulator-name = "vcc_5v0_host_20";
++ vin-supply = <&vcc_5v0>;
+ };
+
+- vcc5v0_host_20: vcc5v0-host-20-regulator {
++ /* SY6280AAC power switch (U9538 in schematics) */
++ /* For USB 3.0 Type-A port */
++ vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+- gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+- pinctrl-0 = <&vcc5v0_host20_en>;
+- regulator-name = "vcc5v0_host_20";
++ pinctrl-0 = <&typec5v_pwren_h>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+- vin-supply = <&vcc5v0_usb>;
++ regulator-name = "vcc5v0_usb_otg0";
++ vin-supply = <&vcc_5v0>;
+ };
+ };
+
+@@ -211,12 +196,13 @@
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-rxid";
++ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+- pinctrl-names = "default";
++ rx_delay = <0x00>;
+ tx_delay = <0x42>;
+ status = "okay";
+ };
+@@ -230,13 +216,13 @@
+ 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-name = "vdd_cpu_big0_s0";
+ regulator-ramp-delay = <2300>;
+- vin-supply = <&vcc5v0_sys>;
++ vin-supply = <&vcc_5v0>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+@@ -247,13 +233,13 @@
+ 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-name = "vdd_cpu_big1_s0";
+ regulator-ramp-delay = <2300>;
+- vin-supply = <&vcc5v0_sys>;
++ vin-supply = <&vcc_5v0>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+@@ -268,13 +254,13 @@
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+- regulator-name = "vdd_npu_s0";
++ regulator-always-on;
++ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
++ regulator-name = "vdd_npu_s0";
+ regulator-ramp-delay = <2300>;
+- regulator-boot-on;
+- regulator-always-on;
+- vin-supply = <&vcc5v0_sys>;
++ vin-supply = <&vcc_5v0>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+@@ -293,35 +279,43 @@
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+- pinctrl-names = "default";
+- pinctrl-0 = <&rtc_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&rtc_int>;
+ wakeup-source;
+ };
+ };
+
++/* RTL8211F-CG Ethernet */
+ &mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
++ phy-supply = <&vcc_3v3_s0>;
+ pinctrl-names = "default";
+- pinctrl-0 = <&rtl8211f_rst>;
++ pinctrl-0 = <&gmac1_rstn_l>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
++/* RTL8125BG Ethernet */
+ &pcie2x1l1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie20x1_1_perstn_m2>;
+ reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc_3v3_pcie20>;
++ vpcie3v3-supply = <&vcc_3v3_s3>;
+ status = "okay";
+ };
+
++/* R6C: M.2 M-Key socket */
++/* R6S: RTL8125BG Ethernet */
+ &pcie2x1l2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie20x1_2_perstn_m0>;
+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc_3v3_pcie20>;
+ status = "okay";
+ };
+
+@@ -360,24 +354,34 @@
+ };
+ };
+
++ pcie {
++ pcie20x1_1_perstn_m2: pcie2x1-1-rst {
++ rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie20x1_2_perstn_m0: pcie2x1-2-rst {
++ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ sdmmc {
+- sd_s0_pwr: sd-s0-pwr {
++ sd_s0_pwr: sd-pwr {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+- typec5v_pwren: typec5v-pwren {
++ typec5v_pwren_h: usb3-pwren {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+- vcc5v0_host20_en: vcc5v0-host20-en {
++ usb_host_pwren_h: usb2-pwren {
+ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ rtl8211f {
+- rtl8211f_rst: rtl8211f-rst {
++ gmac1_rstn_l: rtl8211f-rst {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+@@ -388,15 +392,19 @@
+ status = "okay";
+ };
+
++/* eMMC */
+ &sdhci {
+ bus-width = <8>;
+- no-sdio;
++ mmc-hs200-1_8v;
+ no-sd;
++ no-sdio;
+ non-removable;
+- mmc-hs200-1_8v;
++ vmmc-supply = <&vcc_3v3_s3>;
++ vqmmc-supply = <&vcc_1v8_s3>;
+ status = "okay";
+ };
+
++/* microSD card */
+ &sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+@@ -411,16 +419,15 @@
+ };
+
+ &spi2 {
+- status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
++ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+- num-cs = <1>;
++ status = "okay";
+
+- pmic@0 {
++ rk806_single: pmic@0 {
+ compatible = "rockchip,rk806";
+- spi-max-frequency = <1000000>;
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+@@ -430,23 +437,24 @@
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
++ spi-max-frequency = <1000000>;
+ system-power-controller;
+
+- vcc1-supply = <&vcc5v0_sys>;
+- vcc2-supply = <&vcc5v0_sys>;
+- vcc3-supply = <&vcc5v0_sys>;
+- vcc4-supply = <&vcc5v0_sys>;
+- vcc5-supply = <&vcc5v0_sys>;
+- vcc6-supply = <&vcc5v0_sys>;
+- vcc7-supply = <&vcc5v0_sys>;
+- vcc8-supply = <&vcc5v0_sys>;
+- vcc9-supply = <&vcc5v0_sys>;
+- vcc10-supply = <&vcc5v0_sys>;
++ vcc1-supply = <&vcc_5v0>;
++ vcc2-supply = <&vcc_5v0>;
++ vcc3-supply = <&vcc_5v0>;
++ vcc4-supply = <&vcc_5v0>;
++ vcc5-supply = <&vcc_5v0>;
++ vcc6-supply = <&vcc_5v0>;
++ vcc7-supply = <&vcc_5v0>;
++ vcc8-supply = <&vcc_5v0>;
++ vcc9-supply = <&vcc_5v0>;
++ vcc10-supply = <&vcc_5v0>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+- vcc12-supply = <&vcc5v0_sys>;
++ vcc12-supply = <&vcc_5v0>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+- vcca-supply = <&vcc5v0_sys>;
++ vcca-supply = <&vcc_5v0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+@@ -745,10 +753,11 @@
+ };
+
+ &u2phy2_host {
+- phy-supply = <&vcc5v0_host_20>;
++ phy-supply = <&vcc_5v0_host_20>;
+ status = "okay";
+ };
+
++/* Debug UART */
+ &uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
+@@ -7,8 +7,36 @@
+ / {
+ model = "FriendlyElec NanoPi R6C";
+ compatible = "friendlyarm,nanopi-r6c", "rockchip,rk3588s";
++
++ /* MP2143DJ power switch (U9536 in schematics) */
++ vcc3v3_pcie: regulator-vcc3v3-pcie {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie20x1_2_con_pwren>;
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-name = "vcc3v3_pcie";
++ vin-supply = <&vcc_5v0>;
++ };
+ };
+
+ &lan2_led {
+ label = "user_led";
+ };
++
++/* M.2 M-Key socket */
++&pcie2x1l2 {
++ vpcie3v3-supply = <&vcc3v3_pcie>;
++};
++
++&pinctrl {
++ pcie {
++ pcie20x1_2_con_pwren: pcie20x1-2-con-pwren {
++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
+@@ -12,3 +12,8 @@
+ &lan2_led {
+ label = "lan2_led";
+ };
++
++/* RTL8125BG Ethernet */
++&pcie2x1l2 {
++ vpcie3v3-supply = <&vcc_3v3_s3>;
++};
diff --git a/target/linux/rockchip/patches-6.6/400-3-arm64-dts-rockchip-Improve-LEDs-on-NanoPi-R6C-R6S.patch b/target/linux/rockchip/patches-6.6/400-3-arm64-dts-rockchip-Improve-LEDs-on-NanoPi-R6C-R6S.patch
new file mode 100644
index 0000000000..8ca0ed5880
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/400-3-arm64-dts-rockchip-Improve-LEDs-on-NanoPi-R6C-R6S.patch
@@ -0,0 +1,184 @@
+From dfa0e0a42f3e256189849a45203aac98a0b4d1aa Mon Sep 17 00:00:00 2001
+From: Sebastian Kropatsch <seb-dev@mail.de>
+Date: Wed, 12 Jun 2024 22:48:12 +0200
+Subject: [PATCH 3/5] arm64: dts: rockchip: Improve LEDs on NanoPi R6C/R6S
+
+Move led-3 node into NanoPi R6C/R6S's source files since they have
+different functionalities on each board: On the R6S this LED is used
+to signal LAN2 link up, while on the R6C this LED does not have a
+pre-defined purpose.
+
+In addition to that:
+ - Remove deprecated label property
+ - Add color and function properties
+ - Add linux,default-trigger to trigger on Ethernet link
+
+Signed-off-by: Sebastian Kropatsch <seb-dev@mail.de>
+---
+ .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 32 +++++++------------
+ .../boot/dts/rockchip/rk3588s-nanopi-r6c.dts | 22 ++++++++++---
+ .../boot/dts/rockchip/rk3588s-nanopi-r6s.dts | 26 +++++++++++++--
+ 3 files changed, 54 insertions(+), 26 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+@@ -8,6 +8,7 @@
+ #include <dt-bindings/pinctrl/rockchip.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
+ #include "rk3588s.dtsi"
+
+ / {
+@@ -52,7 +53,8 @@
+ compatible = "gpio-leds";
+
+ sys_led: led-0 {
+- label = "sys_led";
++ color = <LED_COLOR_ID_RED>;
++ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+@@ -60,24 +62,22 @@
+ };
+
+ wan_led: led-1 {
+- label = "wan_led";
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_WAN;
+ gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "stmmac-0:01:link";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wan_led_pin>;
+ };
+
+ lan1_led: led-2 {
+- label = "lan1_led";
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_LAN;
+ gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "r8169-3-3100:00:link";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan1_led_pin>;
+ };
+-
+- lan2_led: led-3 {
+- gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&lan2_led_pin>;
+- };
+ };
+
+ vcc_5v0: regulator-vcc-5v0 {
+@@ -328,23 +328,15 @@
+
+ gpio-leds {
+ sys_led_pin: sys-led-pin {
+- rockchip,pins =
+- <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wan_led_pin: wan-led-pin {
+- rockchip,pins =
+- <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ lan1_led_pin: lan1-led-pin {
+- rockchip,pins =
+- <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+-
+- lan2_led_pin: lan2-led-pin {
+- rockchip,pins =
+- <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
+@@ -8,6 +8,18 @@
+ model = "FriendlyElec NanoPi R6C";
+ compatible = "friendlyarm,nanopi-r6c", "rockchip,rk3588s";
+
++ leds {
++ compatible = "gpio-leds";
++
++ led1_led: led-3 {
++ color = <LED_COLOR_ID_GREEN>;
++ function = "led1";
++ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&led1_led_pin>;
++ };
++ };
++
+ /* MP2143DJ power switch (U9536 in schematics) */
+ vcc3v3_pcie: regulator-vcc3v3-pcie {
+ compatible = "regulator-fixed";
+@@ -24,16 +36,18 @@
+ };
+ };
+
+-&lan2_led {
+- label = "user_led";
+-};
+-
+ /* M.2 M-Key socket */
+ &pcie2x1l2 {
+ vpcie3v3-supply = <&vcc3v3_pcie>;
+ };
+
+ &pinctrl {
++ gpio-leds {
++ led1_led_pin: led1-led-pin {
++ rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ pcie {
+ pcie20x1_2_con_pwren: pcie20x1-2-con-pwren {
+ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
+@@ -7,13 +7,35 @@
+ / {
+ model = "FriendlyElec NanoPi R6S";
+ compatible = "friendlyarm,nanopi-r6s", "rockchip,rk3588s";
++
++ leds {
++ compatible = "gpio-leds";
++
++ lan2_led: led-3 {
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_LAN;
++ function-enumerator = <2>;
++ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "r8169-4-4100:00:link";
++ pinctrl-names = "default";
++ pinctrl-0 = <&lan2_led_pin>;
++ };
++ };
+ };
+
+-&lan2_led {
+- label = "lan2_led";
++&lan1_led {
++ function-enumerator = <1>;
+ };
+
+ /* RTL8125BG Ethernet */
+ &pcie2x1l2 {
+ vpcie3v3-supply = <&vcc_3v3_s3>;
+ };
++
++&pinctrl {
++ gpio-leds {
++ lan2_led_pin: lan2-led-pin {
++ rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
diff --git a/target/linux/rockchip/patches-6.6/400-4-arm64-dts-rockchip-Enable-lower-USB3-port-on-NanoPi-.patch b/target/linux/rockchip/patches-6.6/400-4-arm64-dts-rockchip-Enable-lower-USB3-port-on-NanoPi-.patch
new file mode 100644
index 0000000000..c154f97cd7
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/400-4-arm64-dts-rockchip-Enable-lower-USB3-port-on-NanoPi-.patch
@@ -0,0 +1,62 @@
+From e067643b4e321db4de3274198b13732cce37f5c1 Mon Sep 17 00:00:00 2001
+From: Sebastian Kropatsch <seb-dev@mail.de>
+Date: Wed, 12 Jun 2024 22:48:13 +0200
+Subject: [PATCH 4/5] arm64: dts: rockchip: Enable lower USB3 port on NanoPi
+ R6C/R6S
+
+Enable support for the lower USB 3.0 Type-A port on the NanoPi R6C and
+NanoPi R6S. The upper USB 2.0 Type-A port is already supported.
+
+Signed-off-by: Sebastian Kropatsch <seb-dev@mail.de>
+---
+ .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 28 +++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+@@ -740,6 +740,17 @@
+ status = "okay";
+ };
+
++/* USB2 PHY for USB 3.0 Type-A (lower port)*/
++&u2phy0 {
++ status = "okay";
++};
++
++&u2phy0_otg {
++ phy-supply = <&vcc5v0_usb_otg0>;
++ status = "okay";
++};
++
++/* USB2 PHY for USB 2.0 Type-A (upper port)*/
+ &u2phy2 {
+ status = "okay";
+ };
+@@ -755,10 +766,27 @@
+ status = "okay";
+ };
+
++/* USB 2.0 Type-A (upper port) */
++/* PHY: <&u2phy2_host> */
+ &usb_host0_ehci {
+ status = "okay";
+ };
+
++/* USB 2.0 Type-A (upper port) */
++/* PHY: <&u2phy2_host> */
+ &usb_host0_ohci {
+ status = "okay";
+ };
++
++/* USB 3.0 Type-A (lower port) */
++/* PHYs: <&u2phy0_otg>, <&usbdp_phy0> */
++&usb_host0_xhci {
++ dr_mode = "host";
++ extcon = <&u2phy0>;
++ status = "okay";
++};
++
++/* USB3 PHY for USB 3.0 Type-A (lower port)*/
++&usbdp_phy0 {
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/400-5-arm64-dts-rockchip-Enable-GPU-on-NanoPi-R6C-R6S.patch b/target/linux/rockchip/patches-6.6/400-5-arm64-dts-rockchip-Enable-GPU-on-NanoPi-R6C-R6S.patch
new file mode 100644
index 0000000000..5e2e70afbc
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/400-5-arm64-dts-rockchip-Enable-GPU-on-NanoPi-R6C-R6S.patch
@@ -0,0 +1,27 @@
+From 04cd713c3834b87fcd147e4bf7b7066cfe60fffc Mon Sep 17 00:00:00 2001
+From: Sebastian Kropatsch <seb-dev@mail.de>
+Date: Wed, 12 Jun 2024 22:48:14 +0200
+Subject: [PATCH 5/5] arm64: dts: rockchip: Enable GPU on NanoPi R6C/R6S
+
+Enable the Mali GPU on the FriendlyElec NanoPi R6C and R6S.
+
+Signed-off-by: Sebastian Kropatsch <seb-dev@mail.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+@@ -207,6 +207,12 @@
+ status = "okay";
+ };
+
++&gpu {
++ mali-supply = <&vdd_gpu_s0>;
++ sram-supply = <&vdd_gpu_mem_s0>;
++ status = "okay";
++};
++
+ &i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
diff --git a/target/linux/sifiveu/patches-6.6/0005-riscv-sifive-unleashed-define-opp-table-cpufreq.patch b/target/linux/sifiveu/patches-6.6/0005-riscv-sifive-unleashed-define-opp-table-cpufreq.patch
index f9ec6c4f82..90dcb0e3e4 100644
--- a/target/linux/sifiveu/patches-6.6/0005-riscv-sifive-unleashed-define-opp-table-cpufreq.patch
+++ b/target/linux/sifiveu/patches-6.6/0005-riscv-sifive-unleashed-define-opp-table-cpufreq.patch
@@ -14,7 +14,7 @@ Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
-@@ -896,6 +896,14 @@ config PORTABLE
+@@ -897,6 +897,14 @@ config PORTABLE
select MMU
select OF
diff --git a/target/linux/siflower/Makefile b/target/linux/siflower/Makefile
new file mode 100644
index 0000000000..d6cded021a
--- /dev/null
+++ b/target/linux/siflower/Makefile
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+include $(TOPDIR)/rules.mk
+
+ARCH:=mipsel
+BOARD:=siflower
+BOARDNAME:=Siflower SoCs
+FEATURES:=squashfs usb usbgadget source-only
+SUBTARGETS:=sf19a2890
+
+KERNEL_PATCHVER:=6.6
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += \
+ kmod-gpio-button-hotplug \
+ uboot-envtools
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/siflower/dts/sf19a2890.dtsi b/target/linux/siflower/dts/sf19a2890.dtsi
new file mode 100644
index 0000000000..b8f1cec83e
--- /dev/null
+++ b/target/linux/siflower/dts/sf19a2890.dtsi
@@ -0,0 +1,651 @@
+#include <dt-bindings/clock/siflower,sf19a2890-clk.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/mips-gic.h>
+
+/ {
+ compatible = "siflower,sf19a2890";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ chosen {
+ bootargs = "earlycon";
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ wlan24_dsp: wlandsp@1f00000 {
+ reg = <0x01f00000 0x200000>;
+ };
+
+ wlan5_dsp: wlandsp@2100000 {
+ reg = <0x02100000 0x200000>;
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "mti,interaptiv";
+ reg = <0>;
+ clocks = <&clk CLK_MUXDIV_CPU>;
+ clock-names = "cpu";
+ clock-latency = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "mti,interaptiv";
+ reg = <1>;
+ clocks = <&clk CLK_MUXDIV_CPU>;
+ clock-names = "cpu";
+ clock-latency = <0>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "mti,interaptiv";
+ reg = <2>;
+ clocks = <&clk CLK_MUXDIV_CPU>;
+ clock-names = "cpu";
+ clock-latency = <0>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "mti,interaptiv";
+ reg = <3>;
+ clocks = <&clk CLK_MUXDIV_CPU>;
+ clock-names = "cpu";
+ clock-latency = <0>;
+ };
+ };
+
+ osc32k: oscillator-32k {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ #clock-cells = <0>;
+ clock-output-names = "osc32k";
+ };
+
+ osc12m: oscillator-12m {
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ #clock-cells = <0>;
+ clock-output-names = "osc12m";
+ };
+
+ osc40m: oscillator-40m {
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ #clock-cells = <0>;
+ clock-output-names = "osc40m";
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ interrupt-parent = <&gic>;
+
+ gmac: ethernet@10800000 {
+ compatible = "siflower,sf19a2890-gmac", "snps,dwmac";
+ reg = <0x10800000 0x200000>,
+ <0x19e04440 0x10>;
+ interrupts = <GIC_SHARED 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 33 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+ clocks = <&gmacclk 0>, <&gmacclk 1>, <&gmacclk 3>, <&gmacclk 2>;
+ clock-names = "stmmaceth", "pclk", "ptp_ref", "gmac_byp_ref";
+ resets = <&gmacrst 0>;
+ reset-names = "stmmaceth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>, <&mdio_pins>;
+ status = "disabled";
+
+ mdio: mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ wlan_rf: phy@11c00000{
+ compatible = "siflower,sf19a2890-rf";
+ reg = <0x11c00000 0x600000>;
+ interrupts = <GIC_SHARED 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rfclk 1>, <&rfclk 2>, <&rfclk 3>;
+ clock-names = "axi", "boot", "lp";
+ resets = <&rfrst 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_pins>;
+ status = "disabled";
+ };
+
+ usb: usb@17000000 {
+ compatible = "siflower,sf19a2890-usb";
+ reg = <0x17000000 0x40000>;
+ interrupts = <GIC_SHARED 128 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usbclk 0>;
+ clock-names = "otg";
+ resets = <&usbrst 0>;
+ reset-names = "dwc2";
+ dr_mode = "otg";
+ phys = <&usb_phy>;
+ phy-names = "usb2-phy";
+ g-np-tx-fifo-size = <768>;
+ status = "disabled";
+ };
+
+ i2c: i2c@18100000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x18100000 0x1000>;
+ interrupts = <GIC_SHARED 217 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&i2cclk 0>;
+ clock-names = "ref";
+ resets = <&i2crst 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ };
+
+ spi: spi@18202000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x18202000 0x1000>;
+ cs-gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ clocks = <&spiclk 1>, <&spiclk 0>;
+ clock-names = "sspclk", "apb_pclk";
+ interrupts = <GIC_SHARED 225 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&spirst 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_pins>;
+ status = "disabled";
+ };
+
+ uart0: serial@18300000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x18300000 0x1000>;
+ interrupts = <GIC_SHARED 226 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk 3>, <&uartclk 0>;
+ clock-names = "uartclk", "apb_pclk";
+ resets = <&uartrst 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "disabled";
+ };
+
+ uart1: serial@18301000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x18301000 0x1000>;
+ interrupts = <GIC_SHARED 227 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk 4>, <&uartclk 1>;
+ clock-names = "uartclk", "apb_pclk";
+ resets = <&uartrst 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+ };
+
+ uart2: serial@18302000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x18302000 0x1000>;
+ interrupts = <GIC_SHARED 228 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk 5>, <&uartclk 2>;
+ clock-names = "uartclk", "apb_pclk";
+ resets = <&uartrst 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "disabled";
+ };
+
+ watchdog: watchdog@18700000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x18700000 0x1000>;
+ interrupts = <GIC_SHARED 238 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&wdtclk 0>;
+ resets = <&wdtrst 0>;
+ };
+
+ gpio: gpio@19d00000 {
+ compatible = "siflower,sf19a2890-gpio";
+ reg=<0x19d00000 0x100000>;
+ interrupts = <GIC_SHARED 246 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 247 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 248 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 249 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gpioclk 0>;
+ resets = <&gpiorst 0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 49>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ clk: clock-controller@19e01000 {
+ compatible = "siflower,sf19a2890-clk";
+ reg = <0x19e01000 0x800>;
+ clocks = <&osc12m>, <&osc40m>;
+ clock-names = "osc12m", "osc40m";
+ #clock-cells = <1>;
+ };
+
+ brom_sysm: syscon@19e02000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x19e02000 0x100>;
+
+ reboot {
+ compatible = "syscon-reboot";
+ offset = <0x30>;
+ value = <0x1>;
+ };
+ };
+
+ gmacrst: reset-controller@19e04400 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e04400 0x4>;
+ #reset-cells = <1>;
+ siflower,reset-masks = <0x3>;
+ };
+
+ gmacclk: clock-controller@19e04404 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e04404 0xc>;
+ clocks = <&clk CLK_MUXDIV_BUS1>, <&clk CLK_MUXDIV_CPU>, <&clk CLK_MUXDIV_GMAC_BYP_REF>, <&clk CLK_MUXDIV_ETH_TSU>;
+ clock-output-names = "gmac", "gmac_pclk", "gmac_byp_ref", "ethtsu";
+ #clock-cells = <1>;
+ };
+
+ wlan24rst: reset-controller@19e08000 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e08000 0x4>;
+ #reset-cells = <1>;
+ siflower,reset-masks = <0x7>;
+ };
+
+ wlan24clk: clock-controller@19e08004 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e08004 0xc>;
+ clocks = <&clk CLK_MUXDIV_CPU>, <&clk CLK_MUXDIV_BUS2>, <&clk CLK_MUXDIV_WLAN24_PLF>;
+ clock-output-names = "wlan24_axis", "wlan24_axim", "wlan24_plf";
+ #clock-cells = <1>;
+ };
+
+ rfrst: reset-controller@19e08800 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e08800 0x4>;
+ #reset-cells = <1>;
+ siflower,reset-masks = <0x7>;
+ };
+
+ rfclk: clock-controller@19e08804 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e08804 0xc>;
+ clocks = <&clk CLK_MUXDIV_BUS2>, <&clk CLK_MUXDIV_CPU>, <&osc12m>, <&osc32k>;
+ clock-output-names = "rf_dft", "rf_axis", "rf_boot", "rf_lp";
+ #clock-cells = <1>;
+ };
+
+ usbrst: reset-controller@19e0c000 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e0c000 0x4>;
+ #reset-cells = <1>;
+ siflower,reset-masks = <0x7 0x8 0x10>;
+ };
+
+ usbclk: clock-controller@19e0c004 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e0c004 0xc>;
+ clocks = <&clk CLK_MUXDIV_BUS3>, <&clk CLK_MUXDIV_CPU>, <&clk CLK_MUXDIV_USBPHY_REF>;
+ clock-output-names = "usb", "usb_axim", "usbphy_ref";
+ siflower,valid-gates = <0xd>;
+ siflower,critical-gates = <0x4>;
+ #clock-cells = <1>;
+ };
+
+ usb_phy: usb-phy@19e0c040 {
+ compatible = "siflower,sf19a2890-usb-phy";
+ reg = <0x19e0C040 0x60>;
+ clocks = <&usbclk 2>;
+ resets = <&usbrst 1>, <&usbrst 2>;
+ reset-names = "power_on_rst", "usb_phy_rst";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ wlan5rst: reset-controller@19e0c400 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e0c400 0x4>;
+ #reset-cells = <1>;
+ siflower,reset-masks = <0x7>;
+ };
+
+ wlan5clk: clock-controller@19e0c404 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e0c404 0xc>;
+ clocks = <&clk CLK_MUXDIV_CPU>, <&clk CLK_MUXDIV_BUS2>, <&clk CLK_MUXDIV_WLAN5_PLF>;
+ clock-output-names = "wlan5_axis", "wlan5_axim", "wlan5_plf";
+ #clock-cells = <1>;
+ };
+
+ i2crst: reset-controller@19e24400 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e24400 0x4>;
+ #reset-cells = <1>;
+ siflower,num-resets = <1>;
+ };
+
+ i2cclk: clock-controller@19e24404 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e24404 0xc>;
+ clocks = <&clk CLK_MUXDIV_PBUS>;
+ clock-output-names = "i2c0";
+ #clock-cells = <1>;
+ };
+
+ spirst: reset-controller@19e24800 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e24800 0x4>;
+ #reset-cells = <1>;
+ siflower,reset-masks = <0x30>;
+ };
+
+ spiclk: clock-controller@19e24804 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e24804 0xc>;
+ clocks = <&clk CLK_MUXDIV_PBUS>, <&clk CLK_MUXDIV_PBUS>;
+ clock-output-names = "spi_apb", "spi_ssp";
+ siflower,valid-gates = <0x30>;
+ #clock-cells = <1>;
+ };
+
+ uartrst: reset-controller@19e24c00 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e24c00 0x4>;
+ #reset-cells = <1>;
+ siflower,reset-masks = <0x11 0x22 0x44>;
+ };
+
+ uartclk: clock-controller@19e24c04 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e24c04 0xc>;
+ clocks = <&clk CLK_MUXDIV_PBUS>, <&clk CLK_MUXDIV_PBUS>, <&clk CLK_MUXDIV_PBUS>,
+ <&clk CLK_MUXDIV_UART>, <&clk CLK_MUXDIV_UART>, <&clk CLK_MUXDIV_UART>;
+ clock-output-names = "uart0_apb", "uart1_apb", "uart2_apb",
+ "uart0", "uart1","uart2";
+ siflower,valid-gates = <0x77>;
+ siflower,critical-gates = <0x11>;
+ #clock-cells = <1>;
+ };
+
+ pwmrst: reset-controller@19e25400 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e25400 0x4>;
+ #reset-cells = <1>;
+ siflower,num-resets = <1>;
+ };
+
+ pwmclk: clock-controller@19e25404 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e25404 0xc>;
+ clocks = <&clk CLK_MUXDIV_PBUS>;
+ clock-output-names = "pwm";
+ #clock-cells = <1>;
+ };
+
+ timerrst: reset-controller@19e25800 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e25800 0x4>;
+ #reset-cells = <1>;
+ siflower,num-resets = <1>;
+ };
+
+ timerclk: clock-controller@19e25804 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e25804 0xc>;
+ clocks = <&clk CLK_MUXDIV_PBUS>;
+ clock-output-names = "timer";
+ #clock-cells = <1>;
+ };
+
+ wdtrst: reset-controller@19e25c00 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e25c00 0x4>;
+ #reset-cells = <1>;
+ siflower,num-resets = <1>;
+ };
+
+ wdtclk: clock-controller@19e25c04 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e25c04 0xc>;
+ clocks = <&clk CLK_MUXDIV_PBUS>;
+ clock-output-names = "wdt";
+ #clock-cells = <1>;
+ };
+
+ gpiorst: reset-controller@19e2b400 {
+ compatible = "siflower,sf19a2890-periph-reset";
+ reg = <0x19e2b400 0x4>;
+ #reset-cells = <1>;
+ siflower,num-resets = <1>;
+ };
+
+ gpioclk: clock-controller@19e2b404 {
+ compatible = "siflower,sf19a2890-periph-clk";
+ reg = <0x19e2b404 0xc>;
+ clocks = <&clk CLK_MUXDIV_PBUS>;
+ clock-output-names = "gpio";
+ #clock-cells = <1>;
+ };
+
+ pinctrl: pinctrl@19e3fc00 {
+ compatible = "siflower,sf19a2890-pinctrl";
+ reg = <0x19e3fc00 0x400>;
+
+ jtag_pins: jtag-pins {
+ tdo {
+ pins = "JTAG_TDO";
+ function = "func0";
+ bias-disable;
+ };
+
+ input-pins {
+ pins = "JTAG_TDI", "JTAG_TMS", "JTAG_TCK";
+ function = "func0";
+ input-enable;
+ bias-disable;
+ };
+
+ trst {
+ pins = "JTAG_RST";
+ function = "func0";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+
+ spi_pins: spi-pins {
+ sck {
+ pins = "SPI_CLK";
+ function = "func0";
+ bias-disable;
+ };
+
+ mosi {
+ pins = "SPI_TXD";
+ function = "func0";
+ bias-pull-down;
+ };
+
+ miso {
+ pins = "SPI_RXD";
+ function = "func0";
+ input-enable;
+ bias-pull-down;
+ };
+
+ cs {
+ pins = "SPI_CSN";
+ bias-pull-up;
+ };
+ };
+
+ uart0_pins: uart0-pins {
+ tx {
+ pins = "UART_TX";
+ function = "func0";
+ bias-pull-up;
+ };
+
+ rx {
+ pins = "UART_RX";
+ function = "func0";
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
+ uart0_rtscts: uart0-rtscts-pins {
+ cts {
+ pins = "I2C_DAT";
+ function = "func0";
+ input-enable;
+ bias-pull-up;
+ };
+
+ rts {
+ pins = "I2C_CLK";
+ function = "func0";
+ bias-pull-up;
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ tx {
+ pins = "JATG_TDO";
+ function = "func1";
+ bias-pull-up;
+ };
+
+ rx {
+ pins = "JATG_TDI";
+ function = "func1";
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
+ uart1_rtscts: uart1-rtscts-pins {
+ cts {
+ pins = "JTAG_TMS";
+ function = "func1";
+ input-enable;
+ bias-pull-up;
+ };
+
+ rts {
+ pins = "JTAG_TCK";
+ function = "func1";
+ bias-pull-up;
+ };
+ };
+
+ uart2_pins: uart2-pins {
+ tx {
+ pins = "I2C_DAT";
+ function = "func1";
+ bias-pull-up;
+ };
+
+ rx {
+ pins = "I2C_CLK";
+ function = "func1";
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
+ rgmii_pins: rgmii-pins {
+ tx-pins {
+ pins = "RGMII_TXCLK", "RGMII_TXD0",
+ "RGMII_TXD1", "RGMII_TXD2",
+ "RGMII_TXD3", "RGMII_TXCTL";
+ function = "func0";
+ bias-disable;
+ };
+
+ rx-pins {
+ pins = "RGMII_RXCLK", "RGMII_RXD0",
+ "RGMII_RXD1", "RGMII_RXD2",
+ "RGMII_RXD3", "RGMII_RXCTL";
+ function = "func0";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ mdio_pins: mdio-pins {
+ pins {
+ pins = "RGMII_MDC", "RGMII_MDIO";
+ function = "func0";
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
+ wlan_pins: wlan-pins {
+ pins {
+ pins = "HB0_PA_EN", "HB0_LNA_EN",
+ "HB0_SW_CTRL0", "HB0_SW_CTRL1",
+ "HB1_PA_EN", "HB1_LNA_EN",
+ "HB1_SW_CTRL0", "HB1_SW_CTRL1",
+ "LB0_PA_EN", "LB0_LNA_EN",
+ "LB0_SW_CTRL0", "LB0_SW_CTRL1",
+ "LB1_PA_EN", "LB1_LNA_EN",
+ "LB1_SW_CTRL0", "LB1_SW_CTRL1";
+ function = "func0";
+ };
+ };
+
+
+ i2c0_pins: i2c0-pins {
+ pins {
+ pins = "I2C_CLK", "I2C_DAT";
+ function = "func2";
+ input-enable;
+ bias-pull-up;
+ };
+ };
+ };
+
+ gic: interrupt-controller@1bdc0000 {
+ compatible = "mti,gic";
+ reg = <0x1bdc0000 0x20000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ mti,reserved-ipi-vectors = <0 8>;
+
+ timer {
+ compatible = "mti,gic-timer";
+ interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
+ clocks = <&clk CLK_MUXDIV_CPU>;
+ };
+ };
+ };
+};
diff --git a/target/linux/siflower/dts/sf19a2890_evb.dts b/target/linux/siflower/dts/sf19a2890_evb.dts
new file mode 100644
index 0000000000..669a28b596
--- /dev/null
+++ b/target/linux/siflower/dts/sf19a2890_evb.dts
@@ -0,0 +1,140 @@
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "sf19a2890.dtsi"
+
+/ {
+ model = "Siflower SF19A2890 Evaluation Board";
+ compatible = "siflower,sf19a2890-evb", "siflower,sf19a2890";
+
+ aliases {
+ led-boot = &led_wlan;
+ led-failsafe = &led_wlan;
+ led-running = &led_wlan;
+ led-upgrade = &led_wlan;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x8000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_wlan: wlan {
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ rtl8367rb {
+ compatible = "realtek,rtl8367b";
+ realtek,extif = <6 0 0 1 1 1 1 1 1 2>;
+ mii-bus = <&mdio>;
+ phy-id = <0>;
+ };
+};
+
+&gmac {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ snps,ps-speed = <1000>;
+ nvmem-cells = <&macaddr_factory_0>, <&rgmii_delay_factory_b2>;
+ nvmem-cell-names = "mac-address", "rgmii-delay";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+};
+
+&wlan_rf {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&spi {
+ status = "okay";
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "spl-loader";
+ reg = <0x0 0x20000>; /* 128k */
+ read-only;
+ };
+
+ partition@20000 {
+ label = "u-boot";
+ reg = <0x20000 0x60000>; /* 384k */
+ };
+
+ partition@80000 {
+ label = "u-boot-env";
+ reg = <0x80000 0x10000>; /* 64k */
+ };
+
+ factory:partition@90000 {
+ label = "factory";
+ reg = <0x90000 0x10000>; /* 64k */
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_0: macaddr@0 {
+ reg = <0x0 0x6>;
+ };
+
+ rgmii_delay_factory_b2: rgmii-delay@b2 {
+ reg = <0xb2 0x4>;
+ };
+ };
+ };
+
+ partition@a0000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0xa0000 0x0>; /* 640k- */
+ };
+ };
+ };
+};
diff --git a/target/linux/siflower/files-6.6/arch/mips/include/asm/mach-siflower/kmalloc.h b/target/linux/siflower/files-6.6/arch/mips/include/asm/mach-siflower/kmalloc.h
new file mode 100644
index 0000000000..d0b270e2ec
--- /dev/null
+++ b/target/linux/siflower/files-6.6/arch/mips/include/asm/mach-siflower/kmalloc.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_SIFLOWER_KMALLOC_H
+#define __ASM_MACH_SIFLOWER_KMALLOC_H
+
+#ifdef CONFIG_DMA_NONCOHERENT
+#define ARCH_DMA_MINALIGN 32
+#endif
+
+#endif /* __ASM_MACH_SIFLOWER_KMALLOC_H */
diff --git a/target/linux/siflower/files-6.6/drivers/clk/siflower/Kconfig b/target/linux/siflower/files-6.6/drivers/clk/siflower/Kconfig
new file mode 100644
index 0000000000..8e1c5a8f26
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/clk/siflower/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menuconfig CLK_SIFLOWER
+ bool "Siflower SoC driver support"
+ depends on MIPS || COMPILE_TEST
+ help
+ SoC drivers for Siflower Linux-capable SoCs.
+
+if CLK_SIFLOWER
+
+config CLK_SF19A2890
+ bool "Clock driver for Siflower CLK_SF19A2890"
+ depends on MIPS || COMPILE_TEST
+ help
+ Supports the Top Clock Module found in SF19A2890. If this
+ kernel is meant to run on a Siflower SF19A2890 SoC,
+ enable this driver.
+
+config CLK_SF19A2890_PERIPH
+ bool "Clock driver for Siflower SF19A2890 peripheral clock gates"
+ depends on MIPS || COMPILE_TEST
+ help
+ Supports the clock gates for various peripherals in SF19A2890.
+ If this kernel is meant to run on a Siflower SF19A2890 SoC,
+ enable this driver.
+
+endif
diff --git a/target/linux/siflower/files-6.6/drivers/clk/siflower/Makefile b/target/linux/siflower/files-6.6/drivers/clk/siflower/Makefile
new file mode 100644
index 0000000000..d03a72ee25
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/clk/siflower/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CLK_SF19A2890) += clk-sf19a2890.o
+obj-$(CONFIG_CLK_SF19A2890_PERIPH) += clk-sf19a2890-periph.o
diff --git a/target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890-periph.c b/target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890-periph.c
new file mode 100644
index 0000000000..4679c714bd
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890-periph.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/of_clk.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#define REG_GATE 0x0
+/*
+ * A shared 'Bus Output Enable' signal for all APB peripherals. The peripheral
+ * only responds to bus requests if its dedicated clock is enabled and this
+ * shared BOE is set.
+ */
+#define REG_BOE 0x8
+#define BOE_EN GENMASK(1, 0)
+
+struct sf19a2890_periphclk {
+ void __iomem *base;
+ struct clk_hw hw;
+ u32 idx;
+};
+
+struct sf19a2890_periphclk_priv {
+ struct sf19a2890_periphclk *gates;
+ struct clk_hw_onecell_data clk_data;
+};
+
+static inline struct sf19a2890_periphclk *hw_to_periphclk(struct clk_hw *hw)
+{
+ return container_of(hw, struct sf19a2890_periphclk, hw);
+}
+
+static int sf19a2890_periphclk_enable(struct clk_hw *hw)
+{
+ struct sf19a2890_periphclk *priv = hw_to_periphclk(hw);
+ u32 reg = readl(priv->base + REG_GATE);
+
+ writel(reg | BIT(priv->idx), priv->base + REG_GATE);
+ writel(BOE_EN, priv->base + REG_BOE);
+ return 0;
+}
+
+static void sf19a2890_periphclk_disable(struct clk_hw *hw)
+{
+ struct sf19a2890_periphclk *priv = hw_to_periphclk(hw);
+ u32 reg = readl(priv->base + REG_GATE);
+
+ reg &= ~BIT(priv->idx);
+ writel(reg, priv->base + REG_GATE);
+ if (reg == 0)
+ writel(0, priv->base + REG_BOE);
+}
+
+static int sf19a2890_periphclk_is_enabled(struct clk_hw *hw)
+{
+ struct sf19a2890_periphclk *priv = hw_to_periphclk(hw);
+
+ return !!(readl(priv->base + REG_GATE) & BIT(priv->idx));
+}
+
+static const struct clk_ops sf19a28_periphclk_ops = {
+ .enable = sf19a2890_periphclk_enable,
+ .disable = sf19a2890_periphclk_disable,
+ .is_enabled = sf19a2890_periphclk_is_enabled,
+};
+
+static void __init sf19a2890_periphclk_init(struct device_node *node)
+{
+ struct clk_init_data init = {};
+ struct sf19a2890_periphclk_priv *priv;
+ u32 reg, valid_gates, critical_gates;
+ int num_clks, i, ret, idx;
+ const char *name, *parent;
+ void __iomem *base;
+
+ num_clks = of_count_phandle_with_args(node, "clocks", "#clock-cells");
+ if (num_clks < 1 || num_clks > 32)
+ return;
+
+ ret = of_property_read_u32(node, "siflower,valid-gates", &valid_gates);
+ if (ret < 0)
+ valid_gates = BIT(num_clks) - 1;
+
+ ret = of_property_read_u32(node, "siflower,critical-gates", &critical_gates);
+ if (ret < 0)
+ critical_gates = 0;
+
+ priv = kzalloc(struct_size(priv, clk_data.hws, num_clks), GFP_KERNEL);
+ if (!priv)
+ return;
+
+ priv->clk_data.num = num_clks;
+
+ priv->gates = kcalloc(num_clks, sizeof(struct sf19a2890_periphclk),
+ GFP_KERNEL);
+ if (!priv->gates)
+ goto err1;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("failed to map resources.\n");
+ goto err2;
+ }
+
+ /* clear unused higher bits for BOE check in disable call. */
+ reg = readl(base + REG_GATE);
+ reg &= valid_gates;
+ writel(reg, base + REG_GATE);
+
+ for (i = 0, idx = 0; i < num_clks && idx < 32; i++, idx++) {
+ ret = of_property_read_string_index(node, "clock-output-names",
+ i, &name);
+ if (ret != 0) {
+ pr_err("failed to read output name for the %dth gate.\n",
+ i);
+ goto err3;
+ }
+ parent = of_clk_get_parent_name(node, i);
+ if (!parent) {
+ pr_err("failed to get parent clock for the %dth gate.\n",
+ i);
+ goto err3;
+ }
+
+ while (!(valid_gates & BIT(idx))) {
+ idx++;
+ if (idx >= 32) {
+ pr_err("too few valid gates.");
+ goto err3;
+ }
+ }
+
+ priv->gates[i].base = base;
+ priv->gates[i].idx = idx;
+ init.name = name;
+ init.ops = &sf19a28_periphclk_ops;
+ init.parent_names = &parent;
+ init.num_parents = 1;
+ init.flags = (critical_gates & BIT(idx)) ? CLK_IS_CRITICAL : 0;
+ priv->gates[i].hw.init = &init;
+
+ ret = clk_hw_register(NULL, &priv->gates[i].hw);
+ if (ret) {
+ pr_err("failed to register the %dth gate: %d.\n", i,
+ ret);
+ goto err3;
+ }
+ priv->clk_data.hws[i] = &priv->gates[i].hw;
+ }
+
+ ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+ &priv->clk_data);
+ if (ret) {
+ pr_err("failed to add hw provider.\n");
+ goto err3;
+ }
+ return;
+err3:
+ for (i--; i >= 0; i--)
+ clk_hw_unregister_gate(priv->clk_data.hws[i]);
+err2:
+ kfree(priv->gates);
+err1:
+ kfree(priv);
+}
+
+CLK_OF_DECLARE(sf19a2890_periphclk, "siflower,sf19a2890-periph-clk",
+ sf19a2890_periphclk_init);
diff --git a/target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890.c b/target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890.c
new file mode 100644
index 0000000000..626fbe7b8e
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/clk/siflower/clk-sf19a2890.c
@@ -0,0 +1,414 @@
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/compiler.h>
+#include <linux/clk-provider.h>
+#include <linux/bitfield.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/bug.h>
+#include <dt-bindings/clock/siflower,sf19a2890-clk.h>
+
+#define REG_PLL_BASE 0x0
+#define REG_PLL_PD 0x0
+#define PLL_PD BIT(0)
+#define PLL_PD_VCO BIT(1)
+#define PLL_PD_POSTDIV BIT(2)
+#define PLL_PD_4PHASE BIT(3)
+#define PLL_PD_DAC BIT(4)
+#define PLL_PD_DSM BIT(5)
+
+/*
+ * PLL_PARAM is a 48-bit value put into 6 registers, 8-bit per register:
+ * REFDIV = PLL_PARAM[47:42]
+ * POSTDIV2 = PLL_PARAM[41:39]
+ * POSTDIV1 = PLL_PARAM[38:36]
+ * FRAC = PLL_PARAM[35:12]
+ * FBDIV = PLL_PARAM[11:0]
+ */
+
+#define REG_PLL_PARAM(_x) (0x4 + (_x) * 4)
+#define PLL_REFDIV_HI 47
+#define PLL_REFDIV_LO 42
+#define PLL_POSTDIV2_HI 41
+#define PLL_POSTDIV2_LO 39
+#define PLL_POSTDIV1_HI 38
+#define PLL_POSTDIV1_LO 36
+#define PLL_FRAC_HI 35
+#define PLL_FRAC_LO 12
+#define PLL_FRAC_BITS (PLL_FRAC_HI - PLL_FRAC_LO + 1)
+#define PLL_FBDIV_HI 11
+#define PLL_FBDIV_LO 0
+
+#define REG_PLL_CFG 0x1c
+#define PLL_CFG_BYPASS BIT(0)
+#define PLL_CFG_SRC GENMASK(2, 1)
+#define PLL_CFG_OCLK_SEL BIT(3)
+#define PLL_CFG_OCLK_GATE BIT(4)
+#define PLL_CFG_LOAD_DIVS BIT(5)
+
+#define REG_PLL_LOCK 0x20
+
+/*
+ * Read-only register indicating the value of the hardware clock source
+ * override pin. When the first bit of this register is set, PLL clock
+ * source is forced to the 40M oscillator regardless of PLL_CFG_SRC
+ * value.
+ */
+#define REG_PLL_SRC_OVERRIDE 0x24
+
+struct sf_clk_common {
+ void __iomem *base;
+ spinlock_t *lock;
+ struct clk_hw hw;
+};
+
+struct sf19a2890_clk {
+ struct sf_clk_common common;
+ ulong offset;
+};
+
+#define SF_CLK_COMMON(_name, _parents, _op, _flags) \
+ { \
+ .hw.init = CLK_HW_INIT_PARENTS(_name, _parents, _op, _flags), \
+ }
+
+static inline struct sf_clk_common *hw_to_sf_clk_common(struct clk_hw *hw)
+{
+ return container_of(hw, struct sf_clk_common, hw);
+}
+
+static inline struct sf19a2890_clk *cmn_to_clk(struct sf_clk_common *cmn_priv)
+{
+ return container_of(cmn_priv, struct sf19a2890_clk, common);
+}
+
+static inline u32 sf_readl(struct sf_clk_common *priv, u32 reg)
+{
+ return readl(priv->base + reg);
+}
+
+static inline void sf_writel(struct sf_clk_common *priv, u32 reg, u32 val)
+{
+ return writel(val, priv->base + reg);
+}
+
+static inline void sf_rmw(struct sf_clk_common *priv, u32 reg, u32 clr, u32 set)
+{
+ u32 val = sf_readl(priv, reg);
+
+ val &= ~clr;
+ val |= set;
+ sf_writel(priv, reg, val);
+}
+
+static u32 sf_pll_param_get(struct sf19a2890_clk *priv, u32 hi, u32 lo)
+{
+ struct sf_clk_common *cmn = &priv->common;
+ u32 ret = 0;
+ int reg_hi = hi / 8;
+ int reg_lo = lo / 8;
+ u32 reg_hi_pos = hi % 8;
+ u32 reg_lo_pos = lo % 8;
+ int i;
+
+ if (reg_hi == reg_lo) {
+ u32 mask = (BIT(reg_hi_pos - reg_lo_pos + 1)) - 1;
+ u32 reg_val =
+ sf_readl(cmn, priv->offset + REG_PLL_PARAM(reg_hi));
+ return (reg_val >> reg_lo_pos) & mask;
+ }
+
+ ret = sf_readl(cmn, priv->offset + REG_PLL_PARAM(reg_hi)) &
+ (BIT(reg_hi_pos + 1) - 1);
+ for (i = reg_hi - 1; i > reg_lo; i--)
+ ret = (ret << 8) |
+ sf_readl(cmn, priv->offset + REG_PLL_PARAM(i));
+ ret = (ret << (8 - reg_lo_pos)) |
+ (sf_readl(cmn, priv->offset + REG_PLL_PARAM(reg_lo)) >>
+ reg_lo_pos);
+
+ return ret;
+}
+
+static unsigned long sf19a28_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+ u32 refdiv = sf_pll_param_get(priv, PLL_REFDIV_HI, PLL_REFDIV_LO);
+ u32 fbdiv = sf_pll_param_get(priv, PLL_FBDIV_HI, PLL_FBDIV_LO);
+ u32 postdiv1 = sf_pll_param_get(priv, PLL_POSTDIV1_HI, PLL_POSTDIV1_LO);
+ u32 postdiv2 = sf_pll_param_get(priv, PLL_POSTDIV2_HI, PLL_POSTDIV2_LO);
+ u32 pll_pd = sf_readl(cmn_priv, PLL_PD);
+ u32 ref = parent_rate / refdiv;
+ u32 rate = ref * fbdiv;
+ u32 frac;
+ u64 frac_rate;
+
+ if (!(pll_pd & PLL_PD_DSM)) {
+ frac = sf_pll_param_get(priv, PLL_FRAC_HI, PLL_FRAC_LO);
+ frac_rate = ((u64)rate * frac) >> PLL_FRAC_BITS;
+ rate += frac_rate;
+ }
+ rate = rate / postdiv1 / postdiv2;
+ return rate;
+}
+
+static u8 sf19a28_pll_get_parent(struct clk_hw *hw)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+ u32 cfg;
+
+ if (sf_readl(cmn_priv, priv->offset + REG_PLL_SRC_OVERRIDE))
+ return 1;
+ cfg = sf_readl(cmn_priv, priv->offset + REG_PLL_CFG);
+ return (FIELD_GET(PLL_CFG_SRC, cfg) == 1);
+}
+
+static const struct clk_ops sf19a28_pll_ops = {
+ .recalc_rate = sf19a28_pll_recalc_rate,
+ .get_parent = sf19a28_pll_get_parent,
+};
+
+static const char * const clk_pll_parents[] = { "osc12m", "osc40m" };
+
+#define SF19A28_PLL(_name, _offset, _flags) \
+ struct sf19a2890_clk _name = { \
+ .common = SF_CLK_COMMON(#_name, clk_pll_parents, \
+ &sf19a28_pll_ops, _flags), \
+ .offset = REG_PLL_BASE + _offset, \
+ }
+
+static SF19A28_PLL(pll_cpu, 0x0, 0);
+static SF19A28_PLL(pll_ddr, 0x40, 0);
+static SF19A28_PLL(pll_cmn, 0x80, 0);
+
+#define REG_MUXDIV_BASE 0x400
+#define REG_MUXDIV_CFG 0x0
+#define MUXDIV_USE_NCO BIT(3)
+#define MUXDIV_SRC_SEL GENMASK(2, 0)
+#define REG_MUXDIV_RATIO 0x4
+#define MUXDIV_RATIO_MAX 0xff
+#define REG_MUXDIV_NCO_V 0x8
+#define REG_MUXDIV_EN 0xc
+#define REG_MUXDIV_XN_DIV_RATIO 0x10
+#define MUXDIV_XN_DIV_MAX 3
+
+static unsigned long sf19a28_muxdiv_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+ u32 div;
+
+ div = sf_readl(cmn_priv, priv->offset + REG_MUXDIV_RATIO) + 1;
+ return parent_rate / div;
+}
+
+int sf19a28_muxdiv_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ unsigned int div;
+
+ div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate);
+ if (!div)
+ div = 1;
+ else if (div > MUXDIV_RATIO_MAX + 1)
+ div = MUXDIV_RATIO_MAX + 1;
+
+ req->rate = req->best_parent_rate / div;
+ return 0;
+}
+
+static int sf19a28_muxdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+ unsigned int div;
+
+ div = DIV_ROUND_CLOSEST(parent_rate, rate);
+ if (div < 1)
+ div = 1;
+ else if (div > MUXDIV_RATIO_MAX + 1)
+ div = MUXDIV_RATIO_MAX + 1;
+ div -= 1;
+
+ sf_writel(cmn_priv, priv->offset + REG_MUXDIV_RATIO, div);
+
+ return 0;
+}
+
+static int sf19a28_muxdiv_enable(struct clk_hw *hw)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+
+ sf_writel(cmn_priv, priv->offset + REG_MUXDIV_EN, 1);
+ return 0;
+}
+
+static void sf19a28_muxdiv_disable(struct clk_hw *hw)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+
+ sf_writel(cmn_priv, priv->offset + REG_MUXDIV_EN, 0);
+}
+
+static int sf19a28_muxdiv_is_enabled(struct clk_hw *hw)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+
+ return !!sf_readl(cmn_priv, priv->offset + REG_MUXDIV_EN);
+}
+
+static u8 sf19a28_muxdiv_get_parent(struct clk_hw *hw)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+ u32 cfg = sf_readl(cmn_priv, priv->offset + REG_MUXDIV_CFG);
+ u32 src = FIELD_GET(MUXDIV_SRC_SEL, cfg);
+
+ if (src <= 2)
+ return src;
+ if (src == 4)
+ return 3;
+ return 4;
+}
+
+static int sf19a28_muxdiv_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct sf_clk_common *cmn_priv = hw_to_sf_clk_common(hw);
+ struct sf19a2890_clk *priv = cmn_to_clk(cmn_priv);
+ u32 src;
+
+ if (index <= 2)
+ src = index;
+ else if (index == 3)
+ src = 4;
+ else
+ src = 6;
+ sf_writel(cmn_priv, priv->offset + REG_MUXDIV_CFG, src);
+ return 0;
+}
+
+static const char * const clk_muxdiv_parents[] = { "pll_cpu", "pll_ddr", "pll_cmn",
+ "osc12m", "osc40m" };
+
+static const struct clk_ops sf19a28_muxdiv_ops = {
+ .recalc_rate = sf19a28_muxdiv_recalc_rate,
+ .determine_rate = sf19a28_muxdiv_determine_rate,
+ .set_rate = sf19a28_muxdiv_set_rate,
+ .enable = sf19a28_muxdiv_enable,
+ .disable = sf19a28_muxdiv_disable,
+ .is_enabled = sf19a28_muxdiv_is_enabled,
+ .get_parent = sf19a28_muxdiv_get_parent,
+ .set_parent = sf19a28_muxdiv_set_parent,
+};
+
+#define SF19A28_MUXDIV(_name, _offset, _flags) \
+ struct sf19a2890_clk _name = { \
+ .common = SF_CLK_COMMON(#_name, clk_muxdiv_parents, \
+ &sf19a28_muxdiv_ops, _flags), \
+ .offset = REG_MUXDIV_BASE + _offset, \
+ }
+
+static SF19A28_MUXDIV(muxdiv_bus1, 0x0, CLK_IS_CRITICAL);
+static SF19A28_MUXDIV(muxdiv_bus2, 0x20, CLK_IS_CRITICAL);
+static SF19A28_MUXDIV(muxdiv_bus3, 0x40, CLK_IS_CRITICAL);
+static SF19A28_MUXDIV(muxdiv_cpu, 0x100, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT);
+static SF19A28_MUXDIV(muxdiv_pbus, 0x120, CLK_IS_CRITICAL);
+static SF19A28_MUXDIV(muxdiv_mem_phy, 0x140, CLK_IS_CRITICAL);
+static SF19A28_MUXDIV(muxdiv_uart, 0x180, 0);
+static SF19A28_MUXDIV(muxdiv_eth_ref, 0x200, 0);
+static SF19A28_MUXDIV(muxdiv_eth_byp_ref, 0x220, 0);
+static SF19A28_MUXDIV(muxdiv_eth_tsu, 0x240, 0);
+static SF19A28_MUXDIV(muxdiv_gmac_byp_ref, 0x260, 0);
+static SF19A28_MUXDIV(muxdiv_m6250_0, 0x280, 0);
+static SF19A28_MUXDIV(muxdiv_m6250_1, 0x2a0, 0);
+static SF19A28_MUXDIV(muxdiv_wlan24_plf, 0x2c0, 0);
+static SF19A28_MUXDIV(muxdiv_wlan5_plf, 0x2e0, 0);
+static SF19A28_MUXDIV(muxdiv_usbphy_ref, 0x300, 0);
+static SF19A28_MUXDIV(muxdiv_tclk, 0x320, 0);
+static SF19A28_MUXDIV(muxdiv_npu_pe, 0x340, 0);
+
+static struct clk_hw_onecell_data sf19a2890_hw_clks = {
+ .num = CLK_SF19A2890_MAX,
+ .hws = {
+ [CLK_PLL_CPU] = &pll_cpu.common.hw,
+ [CLK_PLL_DDR] = &pll_ddr.common.hw,
+ [CLK_PLL_CMN] = &pll_cmn.common.hw,
+ [CLK_MUXDIV_BUS1] = &muxdiv_bus1.common.hw,
+ [CLK_MUXDIV_BUS2] = &muxdiv_bus2.common.hw,
+ [CLK_MUXDIV_BUS3] = &muxdiv_bus3.common.hw,
+ [CLK_MUXDIV_CPU] = &muxdiv_cpu.common.hw,
+ [CLK_MUXDIV_PBUS] = &muxdiv_pbus.common.hw,
+ [CLK_MUXDIV_MEM_PHY] = &muxdiv_mem_phy.common.hw,
+ [CLK_MUXDIV_UART] = &muxdiv_uart.common.hw,
+ [CLK_MUXDIV_ETH_REF] = &muxdiv_eth_ref.common.hw,
+ [CLK_MUXDIV_ETH_BYP_REF] = &muxdiv_eth_byp_ref.common.hw,
+ [CLK_MUXDIV_ETH_TSU] = &muxdiv_eth_tsu.common.hw,
+ [CLK_MUXDIV_GMAC_BYP_REF] = &muxdiv_gmac_byp_ref.common.hw,
+ [CLK_MUXDIV_M6250_0] = &muxdiv_m6250_0.common.hw,
+ [CLK_MUXDIV_M6250_1] = &muxdiv_m6250_1.common.hw,
+ [CLK_MUXDIV_WLAN24_PLF] = &muxdiv_wlan24_plf.common.hw,
+ [CLK_MUXDIV_WLAN5_PLF] = &muxdiv_wlan5_plf.common.hw,
+ [CLK_MUXDIV_USBPHY_REF] = &muxdiv_usbphy_ref.common.hw,
+ [CLK_MUXDIV_TCLK] = &muxdiv_tclk.common.hw,
+ [CLK_MUXDIV_NPU_PE_CLK] = &muxdiv_npu_pe.common.hw,
+ },
+};
+
+
+struct sf19a2890_clk_ctrl {
+ void __iomem *base;
+ spinlock_t lock;
+};
+
+static void __init sf19a2890_clk_init(struct device_node *node)
+{
+ struct sf19a2890_clk_ctrl *ctrl;
+ int i, ret;
+
+ ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
+ if (!ctrl)
+ return;
+
+ ctrl->base = of_iomap(node, 0);
+ if (!ctrl->base) {
+ pr_err("failed to map resources.\n");
+ return;
+ }
+
+ spin_lock_init(&ctrl->lock);
+
+ for (i = 0; i < sf19a2890_hw_clks.num; i++) {
+ struct clk_hw *hw = sf19a2890_hw_clks.hws[i];
+ struct sf_clk_common *common;
+
+ if (!hw)
+ continue;
+ common = hw_to_sf_clk_common(hw);
+ common->base = ctrl->base;
+ common->lock = &ctrl->lock;
+ ret = clk_hw_register(NULL, hw);
+ if (ret) {
+ pr_err("Couldn't register clock %d: %d\n", i, ret);
+ goto err;
+ }
+ }
+
+ ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, &sf19a2890_hw_clks);
+ if (ret) {
+ pr_err("failed to add hw provider.\n");
+ goto err;
+ }
+ return;
+err:
+ iounmap(ctrl->base);
+}
+
+CLK_OF_DECLARE(sf19a2890_clk, "siflower,sf19a2890-clk", sf19a2890_clk_init);
diff --git a/target/linux/siflower/files-6.6/drivers/gpio/gpio-siflower.c b/target/linux/siflower/files-6.6/drivers/gpio/gpio-siflower.c
new file mode 100644
index 0000000000..b28ecafec8
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/gpio/gpio-siflower.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/pinctrl/consumer.h>
+#include <linux/clk.h>
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <asm/div64.h>
+
+#define GPIO_IR(n) (0x40 * (n) + 0x00)
+#define GPIO_OR(n) (0x40 * (n) + 0x04)
+#define GPIO_OEN(n) (0x40 * (n) + 0x08)
+#define GPIO_IMR(n) (0x40 * (n) + 0x0c)
+#define GPIO_GPIMR(n) (0x40 * (n) + 0x10)
+#define GPIO_PIR(n) (0x40 * (n) + 0x14)
+#define GPIO_ITR(n) (0x40 * (n) + 0x18)
+#define GPIO_IFR(n) (0x40 * (n) + 0x1c)
+#define GPIO_ICR(n) (0x40 * (n) + 0x20)
+#define GPIO_GPxIR(n) (0x4 * (n) + 0x4000)
+
+#define GPIOS_PER_GROUP 16
+
+struct sf_gpio_priv {
+ struct gpio_chip gc;
+ void __iomem *base;
+ struct clk *clk;
+ struct reset_control *rstc;
+ unsigned int irq[];
+};
+
+#define to_sf_gpio(x) container_of(x, struct sf_gpio_priv, gc)
+
+static u32 sf_gpio_rd(struct sf_gpio_priv *priv, unsigned long reg)
+{
+ return readl_relaxed(priv->base + reg);
+}
+
+static void sf_gpio_wr(struct sf_gpio_priv *priv, unsigned long reg,
+ u32 val)
+{
+ writel_relaxed(val, priv->base + reg);
+}
+
+static int sf_gpio_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+
+ return sf_gpio_rd(priv, GPIO_IR(offset));
+}
+
+static void sf_gpio_set_value(struct gpio_chip *gc, unsigned int offset,
+ int value)
+{
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+
+ sf_gpio_wr(priv, GPIO_OR(offset), value);
+}
+
+static int sf_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+
+ if (sf_gpio_rd(priv, GPIO_OEN(offset)))
+ return GPIO_LINE_DIRECTION_IN;
+ else
+ return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int sf_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
+{
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+
+ sf_gpio_wr(priv, GPIO_OEN(offset), 1);
+ return 0;
+}
+
+static int sf_gpio_direction_output(struct gpio_chip *gc, unsigned int offset,
+ int value)
+{
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+
+ sf_gpio_wr(priv, GPIO_OR(offset), value);
+ sf_gpio_wr(priv, GPIO_OEN(offset), 0);
+ return 0;
+}
+
+static int sf_gpio_set_debounce(struct gpio_chip *gc, unsigned int offset,
+ u32 debounce)
+{
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+ unsigned long freq = clk_get_rate(priv->clk);
+ u64 mul;
+
+ /* (ICR + 1) * IFR = debounce_us * clkfreq_mhz / 4 */
+ mul = (u64)debounce * freq;
+ do_div(mul, 1000000 * 4);
+ if (mul > 0xff00)
+ return -EINVAL;
+
+ sf_gpio_wr(priv, GPIO_ICR(offset), 0xff);
+ sf_gpio_wr(priv, GPIO_IFR(offset), DIV_ROUND_UP(mul, 0x100));
+
+ return 0;
+}
+
+static int sf_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
+ unsigned long config)
+{
+ switch (pinconf_to_config_param(config)) {
+ case PIN_CONFIG_INPUT_DEBOUNCE:
+ return sf_gpio_set_debounce(gc, offset,
+ pinconf_to_config_argument(config));
+ default:
+ return gpiochip_generic_config(gc, offset, config);
+ }
+}
+
+static void sf_gpio_irq_ack(struct irq_data *data)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+ unsigned long offset = irqd_to_hwirq(data);
+
+ sf_gpio_wr(priv, GPIO_PIR(offset), 0);
+}
+
+static void sf_gpio_irq_mask(struct irq_data *data)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+ unsigned long offset = irqd_to_hwirq(data);
+
+ sf_gpio_wr(priv, GPIO_IMR(offset), 1);
+ sf_gpio_wr(priv, GPIO_GPIMR(offset), 1);
+}
+
+static void sf_gpio_irq_unmask(struct irq_data *data)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+ unsigned long offset = irqd_to_hwirq(data);
+
+ sf_gpio_wr(priv, GPIO_IMR(offset), 0);
+ sf_gpio_wr(priv, GPIO_GPIMR(offset), 0);
+}
+
+/* We are actually setting the parents' affinity. */
+static int sf_gpio_irq_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ unsigned long offset = irqd_to_hwirq(data);
+ const struct cpumask *pdest;
+ struct irq_desc *pdesc;
+ struct irq_data *pdata;
+ unsigned int group;
+ int ret;
+
+ /* Find the parent IRQ and call its irq_set_affinity */
+ group = offset / GPIOS_PER_GROUP;
+ if (group >= gc->irq.num_parents)
+ return -EINVAL;
+
+ pdesc = irq_to_desc(gc->irq.parents[group]);
+ if (!pdesc)
+ return -EINVAL;
+
+ pdata = irq_desc_get_irq_data(pdesc);
+ if (!pdata->chip->irq_set_affinity)
+ return -EINVAL;
+
+ ret = pdata->chip->irq_set_affinity(pdata, dest, force);
+ if (ret < 0)
+ return ret;
+
+ /* Copy its effective_affinity back */
+ pdest = irq_data_get_effective_affinity_mask(pdata);
+ irq_data_update_effective_affinity(data, pdest);
+ return ret;
+}
+
+static int sf_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+ unsigned long offset = irqd_to_hwirq(data);
+ u32 val;
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_RISING:
+ val = 4;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ val = 2;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ val = 6;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ val = 1;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ sf_gpio_wr(priv, GPIO_ITR(offset), val);
+
+ if (flow_type & IRQ_TYPE_LEVEL_MASK)
+ irq_set_handler_locked(data, handle_level_irq);
+ else
+ irq_set_handler_locked(data, handle_edge_irq);
+
+ return 0;
+}
+
+static const struct irq_chip sf_gpio_irqchip = {
+ .name = KBUILD_MODNAME,
+ .irq_ack = sf_gpio_irq_ack,
+ .irq_mask = sf_gpio_irq_mask,
+ .irq_unmask = sf_gpio_irq_unmask,
+ .irq_set_affinity = sf_gpio_irq_set_affinity,
+ .irq_set_type = sf_gpio_irq_set_type,
+ .flags = IRQCHIP_IMMUTABLE,
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
+static void sf_gpio_irq_handler(struct irq_desc *desc)
+{
+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+ struct irq_chip *ic = irq_desc_get_chip(desc);
+ struct sf_gpio_priv *priv = to_sf_gpio(gc);
+ unsigned int irq = irq_desc_get_irq(desc);
+ unsigned int group = irq - priv->irq[0];
+ unsigned long pending;
+ unsigned int n;
+
+ chained_irq_enter(ic, desc);
+
+ pending = sf_gpio_rd(priv, GPIO_GPxIR(group));
+ for_each_set_bit(n, &pending, GPIOS_PER_GROUP) {
+ generic_handle_domain_irq(gc->irq.domain,
+ n + group * GPIOS_PER_GROUP);
+ }
+
+ chained_irq_exit(ic, desc);
+}
+
+static int sf_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sf_gpio_priv *priv;
+ struct gpio_irq_chip *girq;
+ struct gpio_chip *gc;
+ u32 ngpios, ngroups;
+ int ret, i;
+
+ ngpios = (unsigned int) device_get_match_data(dev);
+ ngroups = DIV_ROUND_UP(ngpios, GPIOS_PER_GROUP);
+ priv = devm_kzalloc(dev, struct_size(priv, irq, ngroups), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, priv);
+
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ priv->clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ priv->rstc = devm_reset_control_get_optional(&pdev->dev, NULL);
+ if (IS_ERR(priv->rstc))
+ return PTR_ERR(priv->rstc);
+
+ ret = reset_control_deassert(priv->rstc);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < ngroups; i++) {
+ ret = platform_get_irq(pdev, i);
+ if (ret < 0)
+ return ret;
+
+ priv->irq[i] = ret;
+ }
+
+ gc = &priv->gc;
+ gc->label = KBUILD_MODNAME;
+ gc->parent = dev;
+ gc->owner = THIS_MODULE;
+ gc->request = gpiochip_generic_request;
+ gc->free = gpiochip_generic_free;
+ gc->get_direction = sf_gpio_get_direction;
+ gc->direction_input = sf_gpio_direction_input;
+ gc->direction_output = sf_gpio_direction_output;
+ gc->get = sf_gpio_get_value;
+ gc->set = sf_gpio_set_value;
+ gc->set_config = sf_gpio_set_config;
+ gc->base = -1;
+ gc->ngpio = ngpios;
+
+ girq = &gc->irq;
+ gpio_irq_chip_set_chip(girq, &sf_gpio_irqchip);
+ girq->num_parents = ngroups;
+ girq->parents = priv->irq;
+ girq->parent_handler = sf_gpio_irq_handler;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->handler = handle_bad_irq;
+
+ platform_set_drvdata(pdev, priv);
+ return devm_gpiochip_add_data(dev, gc, priv);
+}
+
+static int sf_gpio_remove(struct platform_device *pdev)
+{
+ struct sf_gpio_priv *priv = platform_get_drvdata(pdev);
+
+ reset_control_assert(priv->rstc);
+ return 0;
+}
+
+static const struct of_device_id sf_gpio_ids[] = {
+ { .compatible = "siflower,sf19a2890-gpio", .data = (void *)49 },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sf_gpio_ids);
+
+static struct platform_driver sf_gpio_driver = {
+ .probe = sf_gpio_probe,
+ .remove = sf_gpio_remove,
+ .driver = {
+ .name = "siflower_gpio",
+ .owner = THIS_MODULE,
+ .of_match_table = sf_gpio_ids,
+ },
+};
+module_platform_driver(sf_gpio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Qingfang Deng <qingfang.deng@siflower.com.cn>");
+MODULE_DESCRIPTION("GPIO driver for SiFlower SoCs");
diff --git a/target/linux/siflower/files-6.6/drivers/net/ethernet/stmicro/stmmac/dwmac-sf19a2890.c b/target/linux/siflower/files-6.6/drivers/net/ethernet/stmicro/stmmac/dwmac-sf19a2890.c
new file mode 100644
index 0000000000..05067e9a43
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/net/ethernet/stmicro/stmmac/dwmac-sf19a2890.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Siflower SF19A2890 GMAC glue layer
+ * SF19A2890 GMAC is a DWMAC 3.73a with a custom HNAT engine
+ * between its MAC and DMA engine.
+ *
+ * Copyright (C) 2024 Chuanhong Guo <gch981213@gmail.com>
+ */
+
+#include <linux/of_net.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/nvmem-consumer.h>
+
+#include "stmmac.h"
+#include "stmmac_platform.h"
+
+struct sf19a2890_gmac_priv {
+ struct device *dev;
+ void __iomem *gmac_cfg;
+ struct clk *gmac_byp_ref_clk;
+};
+
+#define REG_MISC 0x0
+#define MISC_PHY_INTF_SEL GENMASK(2, 0)
+#define PHY_IF_GMII_MII 0
+#define PHY_IF_RGMII 1
+#define PHY_IF_RMII 4
+#define MISC_PTP_AUX_TS_TRIG BIT(3)
+#define MISC_SBD_FLOWCTRL BIT(4)
+#define CLK_RMII_OEN BIT(5)
+
+#define REG_CLK_TX_DELAY 0x4
+#define REG_CLK_RX_PHY_DELAY 0x8
+#define REG_CLK_RX_PHY_DELAY_EN 0xc
+
+/* Siflower stores RGMII delay as a 4-byte hex string in MTD. */
+#define SFGMAC_DELAY_STR_LEN 4
+static int sfgmac_set_delay_from_nvmem(struct sf19a2890_gmac_priv *priv)
+{
+ struct device_node *np = priv->dev->of_node;
+ int ret = 0;
+ struct nvmem_cell *cell;
+ const void *data;
+ size_t retlen;
+ u16 gmac_delay;
+ u8 delay_tx, delay_rx;
+
+ cell = of_nvmem_cell_get(np, "rgmii-delay");
+ if (IS_ERR(cell))
+ return PTR_ERR(cell);
+
+ data = nvmem_cell_read(cell, &retlen);
+ nvmem_cell_put(cell);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ if (retlen < SFGMAC_DELAY_STR_LEN) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ ret = kstrtou16(data, 16, &gmac_delay);
+ if (ret == 0) {
+ delay_tx = (gmac_delay >> 8) & 0xff;
+ delay_rx = gmac_delay & 0xff;
+ writel(delay_tx, priv->gmac_cfg + REG_CLK_TX_DELAY);
+ writel(delay_rx, priv->gmac_cfg + REG_CLK_RX_PHY_DELAY);
+ if (delay_rx)
+ writel(1, priv->gmac_cfg + REG_CLK_RX_PHY_DELAY_EN);
+ }
+
+exit:
+ kfree(data);
+
+ return ret;
+}
+
+static int sfgmac_setup_phy_interface(struct sf19a2890_gmac_priv *priv)
+{
+ phy_interface_t phy_iface;
+ int mode;
+ u32 reg;
+
+ of_get_phy_mode(priv->dev->of_node, &phy_iface);
+ switch (phy_iface) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ mode = PHY_IF_GMII_MII;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ mode = PHY_IF_RMII;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ mode = PHY_IF_RGMII;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ reg = readl(priv->gmac_cfg + REG_MISC);
+ reg &= ~MISC_PHY_INTF_SEL;
+ reg |= FIELD_PREP(MISC_PHY_INTF_SEL, mode);
+ writel(reg, priv->gmac_cfg + REG_MISC);
+ return 0;
+}
+
+static int sf19a2890_gmac_probe(struct platform_device *pdev)
+{
+ struct plat_stmmacenet_data *plat_dat;
+ struct sf19a2890_gmac_priv *priv;
+ struct stmmac_resources stmmac_res;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &pdev->dev;
+
+ priv->gmac_byp_ref_clk = devm_clk_get_enabled(&pdev->dev, "gmac_byp_ref");
+ if (IS_ERR(priv->gmac_byp_ref_clk))
+ return PTR_ERR(priv->gmac_byp_ref_clk);
+
+ priv->gmac_cfg = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(priv->gmac_cfg)) {
+ dev_err(&pdev->dev, "failed to map regs for gmac config.\n");
+ return PTR_ERR(priv->gmac_cfg);
+ }
+
+ ret = sfgmac_set_delay_from_nvmem(priv);
+ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ ret = sfgmac_setup_phy_interface(priv);
+ if (ret)
+ return ret;
+
+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+ if (ret)
+ return ret;
+
+ plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+ if (IS_ERR(plat_dat)) {
+ dev_err(&pdev->dev, "dt configuration failed\n");
+ return PTR_ERR(plat_dat);
+ }
+
+ plat_dat->bsp_priv = priv;
+ /* This DWMAC has PCSSEL set, but it's not SGMII capable, and doesn't
+ * return anything in PCS registers under RGMII mode.
+ * Set this flag to bypass reading pcs regs stmmac_ethtool_get_link_ksettings.
+ * No idea if it's correct or not.
+ */
+ plat_dat->flags |= STMMAC_FLAG_HAS_INTEGRATED_PCS;
+
+ ret = stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
+ if (ret)
+ goto err_remove_config_dt;
+
+ return 0;
+
+err_remove_config_dt:
+ if (pdev->dev.of_node)
+ stmmac_remove_config_dt(pdev, plat_dat);
+
+ return ret;
+}
+
+static const struct of_device_id dwmac_sf19a2890_match[] = {
+ { .compatible = "siflower,sf19a2890-gmac"},
+ { }
+};
+MODULE_DEVICE_TABLE(of, dwmac_sf19a2890_match);
+
+static struct platform_driver sf19a2890_gmac_driver = {
+ .probe = sf19a2890_gmac_probe,
+ .remove_new = stmmac_pltfr_remove,
+ .driver = {
+ .name = "sf19a2890-gmac",
+ .pm = &stmmac_pltfr_pm_ops,
+ .of_match_table = dwmac_sf19a2890_match,
+ },
+};
+module_platform_driver(sf19a2890_gmac_driver);
+
+MODULE_DESCRIPTION("SF19A2890 GMAC driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/siflower/files-6.6/drivers/phy/siflower/Kconfig b/target/linux/siflower/files-6.6/drivers/phy/siflower/Kconfig
new file mode 100644
index 0000000000..000d1864e9
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/phy/siflower/Kconfig
@@ -0,0 +1,6 @@
+config PHY_SF19A2890_USB
+ tristate "SIFLOWER sf19a2890 USB2.0 PHY driver"
+ default n
+ select GENERIC_PHY
+ help
+ Enable this to support the USB2.0 PHY on the SIFLOWER SF19A2890.
diff --git a/target/linux/siflower/files-6.6/drivers/phy/siflower/Makefile b/target/linux/siflower/files-6.6/drivers/phy/siflower/Makefile
new file mode 100644
index 0000000000..0c65e8c866
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/phy/siflower/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PHY_SF19A2890_USB) += phy-sf19a2890-usb.o
+
diff --git a/target/linux/siflower/files-6.6/drivers/phy/siflower/phy-sf19a2890-usb.c b/target/linux/siflower/files-6.6/drivers/phy/siflower/phy-sf19a2890-usb.c
new file mode 100644
index 0000000000..21f65957be
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/phy/siflower/phy-sf19a2890-usb.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#define USB_SLEEPM 0x4
+
+struct sf19a2890_usb_phy {
+ struct device *dev;
+ struct clk *phy_clk;
+ struct reset_control *usb_phy_rst;
+ struct reset_control *power_on_rst;
+ void __iomem *base;
+};
+
+static int sf19a2890_usb_phy_power_on(struct phy *phy)
+{
+ struct sf19a2890_usb_phy *p_phy = phy_get_drvdata(phy);
+ int ret;
+
+ ret = clk_prepare_enable(p_phy->phy_clk);
+ if (ret < 0) {
+ dev_err(p_phy->dev, "Failed to enable PHY clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = reset_control_deassert(p_phy->usb_phy_rst);
+ if (ret)
+ goto err1;
+
+ ret = reset_control_deassert(p_phy->power_on_rst);
+ if (ret)
+ goto err2;
+
+ writel(1, p_phy->base + USB_SLEEPM);
+ return 0;
+err2:
+ reset_control_assert(p_phy->usb_phy_rst);
+err1:
+ clk_disable_unprepare(p_phy->phy_clk);
+ return ret;
+}
+
+static int sf19a2890_usb_phy_power_off(struct phy *phy)
+{
+ struct sf19a2890_usb_phy *p_phy = phy_get_drvdata(phy);
+
+ writel(0, p_phy->base + USB_SLEEPM);
+ reset_control_assert(p_phy->power_on_rst);
+ reset_control_assert(p_phy->usb_phy_rst);
+ clk_disable_unprepare(p_phy->phy_clk);
+ return 0;
+}
+
+static const struct phy_ops sf19a2890_usb_phy_ops = {
+ .power_on = sf19a2890_usb_phy_power_on,
+ .power_off = sf19a2890_usb_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int sf19a2890_usb_phy_probe(struct platform_device *pdev)
+{
+ struct sf19a2890_usb_phy *p_phy;
+ struct phy_provider *provider;
+ struct phy *phy;
+ int ret;
+
+ p_phy = devm_kzalloc(&pdev->dev, sizeof(*p_phy), GFP_KERNEL);
+ if (!p_phy)
+ return -ENOMEM;
+
+ p_phy->dev = &pdev->dev;
+
+ p_phy->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(p_phy->base))
+ return PTR_ERR(p_phy->base);
+
+ p_phy->phy_clk = devm_clk_get(p_phy->dev, NULL);
+ if (IS_ERR(p_phy->phy_clk))
+ return dev_err_probe(p_phy->dev, PTR_ERR(p_phy->phy_clk),
+ "failed to get usb phy clock\n");
+
+ p_phy->power_on_rst =
+ devm_reset_control_get_exclusive(&pdev->dev, "power_on_rst");
+ if (IS_ERR(p_phy->power_on_rst))
+ return PTR_ERR(p_phy->power_on_rst);
+
+ ret = reset_control_assert(p_phy->power_on_rst);
+ if (ret)
+ return ret;
+
+ p_phy->usb_phy_rst =
+ devm_reset_control_get_exclusive(&pdev->dev, "usb_phy_rst");
+ if (IS_ERR(p_phy->usb_phy_rst))
+ return PTR_ERR(p_phy->usb_phy_rst);
+
+ ret = reset_control_assert(p_phy->usb_phy_rst);
+ if (ret)
+ return ret;
+
+ phy = devm_phy_create(p_phy->dev, NULL, &sf19a2890_usb_phy_ops);
+ if (IS_ERR(phy))
+ return dev_err_probe(p_phy->dev, PTR_ERR(phy),
+ "Failed to create PHY\n");
+
+ phy_set_drvdata(phy, p_phy);
+
+ provider =
+ devm_of_phy_provider_register(p_phy->dev, of_phy_simple_xlate);
+ if (IS_ERR(provider))
+ return dev_err_probe(p_phy->dev, PTR_ERR(provider),
+ "Failed to register PHY provider\n");
+
+ platform_set_drvdata(pdev, p_phy);
+ return 0;
+}
+
+static const struct of_device_id sf19a2890_usb_phy_of_match[] = {
+ {
+ .compatible = "siflower,sf19a2890-usb-phy",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sf19a2890_usb_phy_of_match);
+
+static struct platform_driver sf19a2890_usb_phy_driver = {
+ .probe = sf19a2890_usb_phy_probe,
+ .driver = {
+ .name = "sf19a2890-usb-phy",
+ .of_match_table = sf19a2890_usb_phy_of_match,
+ },
+};
+module_platform_driver(sf19a2890_usb_phy_driver);
+
+MODULE_AUTHOR("Ziying Wu <ziying.wu@siflower.com.cn>");
+MODULE_DESCRIPTION("Siflower SF19A2890 USB2.0 PHY driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/siflower/files-6.6/drivers/pinctrl/pinctrl-sf19a2890.c b/target/linux/siflower/files-6.6/drivers/pinctrl/pinctrl-sf19a2890.c
new file mode 100644
index 0000000000..42f8cb9668
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/pinctrl/pinctrl-sf19a2890.c
@@ -0,0 +1,515 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Siflower SF19A2890 pinctrl.
+ *
+ * Based on:
+ * Driver for Broadcom BCM2835 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren
+ */
+
+#include <linux/bitmap.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define MODULE_NAME "sf19a2890-pinctrl"
+
+struct sf_pinctrl {
+ struct device *dev;
+ void __iomem *base;
+
+ struct pinctrl_dev *pctl_dev;
+ struct pinctrl_desc pctl_desc;
+ struct pinctrl_gpio_range gpio_range;
+};
+
+#define SF19A28_NUM_GPIOS 49
+
+#define SF19A28_REG_PC(pin) ((pin) * 0x8)
+#define PC_OEN BIT(7)
+#define PC_ST BIT(6)
+#define PC_IE BIT(5)
+#define PC_PD BIT(4)
+#define PC_PU BIT(3)
+#define PC_DS GENMASK(2, 0)
+
+#define DRIVE_MIN 6
+#define DRIVE_STEP 3
+#define DRIVE_MAX (7 * DRIVE_STEP)
+
+#define SF19A28_REG_PMX(pin) ((pin) * 0x8 + 0x4)
+/*
+ * FUNC_SW:
+ * 0: Override pad output enable with PC_OEN
+ * 1: take OEN from GPIO or alternative function
+ * FMUX_SEL:
+ * 0: Alternative function mode
+ * 1: GPIO mode
+ */
+#define PMX_FUNC_SW BIT(3)
+#define PMX_FMUX_SEL BIT(2)
+#define PMX_MODE GENMASK(1, 0)
+
+static struct pinctrl_pin_desc sf19a2890_gpio_pins[] = {
+ PINCTRL_PIN(0, "JTAG_TDO"),
+ PINCTRL_PIN(1, "JTAG_TDI"),
+ PINCTRL_PIN(2, "JTAG_TMS"),
+ PINCTRL_PIN(3, "JTAG_TCK"),
+ PINCTRL_PIN(4, "JTAG_RST"),
+ PINCTRL_PIN(5, "SPI_TXD"),
+ PINCTRL_PIN(6, "SPI_RXD"),
+ PINCTRL_PIN(7, "SPI_CLK"),
+ PINCTRL_PIN(8, "SPI_CSN"),
+ PINCTRL_PIN(9, "UART_TX"),
+ PINCTRL_PIN(10, "UART_RX"),
+ PINCTRL_PIN(11, "I2C_DAT"),
+ PINCTRL_PIN(12, "I2C_CLK"),
+ PINCTRL_PIN(13, "RGMII_GTX_CLK"),
+ PINCTRL_PIN(14, "RGMII_TXCLK"),
+ PINCTRL_PIN(15, "RGMII_TXD0"),
+ PINCTRL_PIN(16, "RGMII_TXD1"),
+ PINCTRL_PIN(17, "RGMII_TXD2"),
+ PINCTRL_PIN(18, "RGMII_TXD3"),
+ PINCTRL_PIN(19, "RGMII_TXCTL"),
+ PINCTRL_PIN(20, "RGMII_RXCLK"),
+ PINCTRL_PIN(21, "RGMII_RXD0"),
+ PINCTRL_PIN(22, "RGMII_RXD1"),
+ PINCTRL_PIN(23, "RGMII_RXD2"),
+ PINCTRL_PIN(24, "RGMII_RXD3"),
+ PINCTRL_PIN(25, "RGMII_RXCTL"),
+ PINCTRL_PIN(26, "RGMII_COL"),
+ PINCTRL_PIN(27, "RGMII_CRS"),
+ PINCTRL_PIN(28, "RGMII_MDC"),
+ PINCTRL_PIN(29, "RGMII_MDIO"),
+ PINCTRL_PIN(30, "HB0_PA_EN"),
+ PINCTRL_PIN(31, "HB0_LNA_EN"),
+ PINCTRL_PIN(32, "HB0_SW_CTRL0"),
+ PINCTRL_PIN(33, "HB0_SW_CTRL1"),
+ PINCTRL_PIN(34, "HB1_PA_EN"),
+ PINCTRL_PIN(35, "HB1_LNA_EN"),
+ PINCTRL_PIN(36, "HB1_SW_CTRL0"),
+ PINCTRL_PIN(37, "HB1_SW_CTRL1"),
+ PINCTRL_PIN(38, "LB0_PA_EN"),
+ PINCTRL_PIN(39, "LB0_LNA_EN"),
+ PINCTRL_PIN(40, "LB0_SW_CTRL0"),
+ PINCTRL_PIN(41, "LB0_SW_CTRL1"),
+ PINCTRL_PIN(42, "LB1_PA_EN"),
+ PINCTRL_PIN(43, "LB1_LNA_EN"),
+ PINCTRL_PIN(44, "LB1_SW_CTRL0"),
+ PINCTRL_PIN(45, "LB1_SW_CTRL1"),
+ PINCTRL_PIN(46, "CLK_OUT"),
+ PINCTRL_PIN(47, "EXT_CLK_IN"),
+ PINCTRL_PIN(48, "DRVVBUS0"),
+};
+
+static const char * const sf19a2890_gpio_groups[] = {
+ "JTAG_TDO",
+ "JTAG_TDI",
+ "JTAG_TMS",
+ "JTAG_TCK",
+ "JTAG_RST",
+ "SPI_TXD",
+ "SPI_RXD",
+ "SPI_CLK",
+ "SPI_CSN",
+ "UART_TX",
+ "UART_RX",
+ "I2C_DAT",
+ "I2C_CLK",
+ "RGMII_GTX_CLK",
+ "RGMII_TXCLK",
+ "RGMII_TXD0",
+ "RGMII_TXD1",
+ "RGMII_TXD2",
+ "RGMII_TXD3",
+ "RGMII_TXCTL",
+ "RGMII_RXCLK",
+ "RGMII_RXD0",
+ "RGMII_RXD1",
+ "RGMII_RXD2",
+ "RGMII_RXD3",
+ "RGMII_RXCTL",
+ "RGMII_COL",
+ "RGMII_CRS",
+ "RGMII_MDC",
+ "RGMII_MDIO",
+ "HB0_PA_EN",
+ "HB0_LNA_EN",
+ "HB0_SW_CTRL0",
+ "HB0_SW_CTRL1",
+ "HB1_PA_EN",
+ "HB1_LNA_EN",
+ "HB1_SW_CTRL0",
+ "HB1_SW_CTRL1",
+ "LB0_PA_EN",
+ "LB0_LNA_EN",
+ "LB0_SW_CTRL0",
+ "LB0_SW_CTRL1",
+ "LB1_PA_EN",
+ "LB1_LNA_EN",
+ "LB1_SW_CTRL0",
+ "LB1_SW_CTRL1",
+ "CLK_OUT",
+ "EXT_CLK_IN",
+ "DRVVBUS0",
+};
+
+#define SF19A28_FUNC0 0
+#define SF19A28_FUNC1 1
+#define SF19A28_FUNC2 2
+#define SF19A28_FUNC3 3
+#define SF19A28_NUM_FUNCS 4
+
+static const char * const sf19a2890_functions[] = {
+ "func0", "func1", "func2", "func3"
+};
+
+static inline u32 sf_pinctrl_rd(struct sf_pinctrl *pc, ulong reg)
+{
+ return readl(pc->base + reg);
+}
+
+static inline void sf_pinctrl_wr(struct sf_pinctrl *pc, ulong reg, u32 val)
+{
+ writel(val, pc->base + reg);
+}
+
+static inline void sf_pinctrl_rmw(struct sf_pinctrl *pc, ulong reg, u32 clr,
+ u32 set)
+{
+ u32 val;
+
+ val = sf_pinctrl_rd(pc, reg);
+ val &= ~clr;
+ val |= set;
+ sf_pinctrl_wr(pc, reg, val);
+}
+
+static int sf19a2890_pctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return SF19A28_NUM_GPIOS;
+}
+
+static const char *sf19a2890_pctl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ return sf19a2890_gpio_groups[selector];
+}
+
+static int sf19a2890_pctl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned selector,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ *pins = &sf19a2890_gpio_pins[selector].number;
+ *num_pins = 1;
+
+ return 0;
+}
+
+static void sf19a2890_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned offset)
+{
+ struct sf_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ u32 conf = sf_pinctrl_rd(pc, SF19A28_REG_PC(offset));
+ u32 mux = sf_pinctrl_rd(pc, SF19A28_REG_PMX(offset));
+
+ if (!(mux & PMX_FUNC_SW))
+ seq_puts(s, "Forced OE");
+ else if (mux & PMX_FMUX_SEL)
+ seq_puts(s, "GPIO");
+ else
+ seq_printf(s, "Func%lu", mux & PMX_MODE);
+ seq_puts(s, " |");
+
+ if (!(conf & PC_OEN) && !(mux & PMX_FUNC_SW))
+ seq_puts(s, " Output");
+ if ((conf & PC_ST))
+ seq_puts(s, " Schmitt_Trigger");
+ if ((conf & PC_IE))
+ seq_puts(s, " Input");
+ if ((conf & PC_PD))
+ seq_puts(s, " Pull_Down");
+ if ((conf & PC_PU))
+ seq_puts(s, " Pull_Up");
+
+ seq_printf(s, " Drive: %lu mA",
+ DRIVE_MIN + (conf & PC_DS) * DRIVE_STEP);
+}
+
+static const struct pinctrl_ops sf19a2890_pctl_ops = {
+ .get_groups_count = sf19a2890_pctl_get_groups_count,
+ .get_group_name = sf19a2890_pctl_get_group_name,
+ .get_group_pins = sf19a2890_pctl_get_group_pins,
+ .pin_dbg_show = sf19a2890_pctl_pin_dbg_show,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int sf19a2890_pmx_free(struct pinctrl_dev *pctldev, unsigned offset)
+{
+ struct sf_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ sf_pinctrl_rmw(pc, SF19A28_REG_PC(offset), PC_IE, PC_OEN);
+ sf_pinctrl_rmw(pc, SF19A28_REG_PMX(offset), PMX_FUNC_SW, 0);
+ return 0;
+}
+
+static int sf19a2890_pmx_get_functions_count(struct pinctrl_dev *pctldev)
+{
+ return SF19A28_NUM_FUNCS;
+}
+
+static const char *sf19a2890_pmx_get_function_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ return sf19a2890_functions[selector];
+}
+
+static int sf19a2890_pmx_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned selector,
+ const char *const **groups,
+ unsigned *const num_groups)
+{
+ /* every pin can do every function */
+ *groups = sf19a2890_gpio_groups;
+ *num_groups = SF19A28_NUM_GPIOS;
+
+ return 0;
+}
+
+static int sf19a2890_pmx_set(struct pinctrl_dev *pctldev,
+ unsigned func_selector, unsigned group_selector)
+{
+ struct sf_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ unsigned pin = group_selector;
+
+ sf_pinctrl_wr(pc, SF19A28_REG_PMX(pin),
+ PMX_FUNC_SW | FIELD_PREP(PMX_MODE, func_selector));
+ return 0;
+}
+
+static int sf19a2890_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
+{
+ struct sf_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ /* Set to GPIO mode & Let peripheral control OEN */
+ sf_pinctrl_wr(pc, SF19A28_REG_PMX(offset), PMX_FUNC_SW | PMX_FMUX_SEL);
+ /*
+ * Set PC_IE regardless of whether GPIO is in input mode.
+ * Otherwise GPIO driver can't read back its status in output mode.
+ */
+ sf_pinctrl_rmw(pc, SF19A28_REG_PC(offset), 0, PC_IE);
+ return 0;
+}
+
+static void sf19a2890_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
+{
+ sf19a2890_pmx_free(pctldev, offset);
+}
+
+static const struct pinmux_ops sf19a2890_pmx_ops = {
+ .free = sf19a2890_pmx_free,
+ .get_functions_count = sf19a2890_pmx_get_functions_count,
+ .get_function_name = sf19a2890_pmx_get_function_name,
+ .get_function_groups = sf19a2890_pmx_get_function_groups,
+ .set_mux = sf19a2890_pmx_set,
+ .gpio_request_enable = sf19a2890_pmx_gpio_request_enable,
+ .gpio_disable_free = sf19a2890_pmx_gpio_disable_free,
+};
+
+static int sf19a2890_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long *config)
+{
+ struct sf_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 arg = 0;
+ u32 val = 0;
+
+ if (pin >= SF19A28_NUM_GPIOS)
+ return -EINVAL;
+
+ val = sf_pinctrl_rd(pc, SF19A28_REG_PC(pin));
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_SCHMITT:
+ val &= PC_ST;
+ if (val)
+ arg = 1;
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ val &= PC_IE;
+ if (val)
+ arg = 1;
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ val &= PC_PD;
+ if (val)
+ arg = 1;
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+ val &= PC_PU;
+ if (val)
+ arg = 1;
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ arg = DRIVE_MIN + (val & PC_DS) * DRIVE_STEP;
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+ return 0;
+}
+
+static int sf19a2890_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long *configs, unsigned num_configs)
+{
+ struct sf_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param;
+ u32 arg, val;
+ int i;
+
+ val = sf_pinctrl_rd(pc, SF19A28_REG_PC(pin));
+
+ if (pin >= SF19A28_NUM_GPIOS)
+ return -EINVAL;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+ switch (param) {
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ if (arg)
+ val |= PC_ST;
+ else
+ val &= ~PC_ST;
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ if (arg)
+ val |= PC_IE;
+ else
+ val &= ~PC_IE;
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg) {
+ val |= PC_PD;
+ val &= ~PC_PU;
+ } else {
+ val &= ~PC_PD;
+ }
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (arg) {
+ val |= PC_PU;
+ val &= ~PC_PD;
+ } else {
+ val &= ~PC_PU;
+ }
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ val &= ~PC_DS;
+ if (arg > DRIVE_MAX)
+ val |= PC_DS;
+ else if (arg > DRIVE_MIN)
+ val |= FIELD_PREP(PC_DS, (arg - DRIVE_MIN) /
+ DRIVE_STEP);
+ break;
+ default:
+ break;
+ }
+ sf_pinctrl_wr(pc, SF19A28_REG_PC(pin), val);
+ }
+ return 0;
+}
+
+static const struct pinconf_ops sf19a2890_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = sf19a2890_pinconf_get,
+ .pin_config_set = sf19a2890_pinconf_set,
+};
+
+static const struct pinctrl_desc sf19a2890_pinctrl_desc = {
+ .name = MODULE_NAME,
+ .pins = sf19a2890_gpio_pins,
+ .npins = SF19A28_NUM_GPIOS,
+ .pctlops = &sf19a2890_pctl_ops,
+ .pmxops = &sf19a2890_pmx_ops,
+ .confops = &sf19a2890_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static const struct pinctrl_gpio_range sf_pinctrl_gpio_range = {
+ .name = MODULE_NAME,
+ .npins = SF19A28_NUM_GPIOS,
+};
+
+static const struct of_device_id sf_pinctrl_match[] = {
+ { .compatible = "siflower,sf19a2890-pinctrl" },
+ {}
+};
+
+static int sf_pinctrl_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sf_pinctrl *pc;
+
+ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
+ if (!pc)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pc);
+ pc->dev = dev;
+
+ pc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pc->base))
+ return PTR_ERR(pc->base);
+
+ pc->pctl_desc = sf19a2890_pinctrl_desc;
+ pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+ if (IS_ERR(pc->pctl_dev))
+ return PTR_ERR(pc->pctl_dev);
+
+ return 0;
+}
+
+static struct platform_driver sf_pinctrl_driver = {
+ .probe = sf_pinctrl_probe,
+ .driver = {
+ .name = MODULE_NAME,
+ .of_match_table = sf_pinctrl_match,
+ .suppress_bind_attrs = true,
+ },
+};
+module_platform_driver(sf_pinctrl_driver);
+
+MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>");
+MODULE_DESCRIPTION("Siflower SF19A2890 pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/siflower/files-6.6/drivers/reset/reset-sf19a2890-periph.c b/target/linux/siflower/files-6.6/drivers/reset/reset-sf19a2890-periph.c
new file mode 100644
index 0000000000..21874da517
--- /dev/null
+++ b/target/linux/siflower/files-6.6/drivers/reset/reset-sf19a2890-periph.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+
+struct reset_sf19a28_periph_data {
+ struct reset_controller_dev rcdev;
+ void __iomem *base;
+ spinlock_t lock;
+ u32 reset_masks[];
+};
+
+static inline struct reset_sf19a28_periph_data *
+to_reset_sf19a28_periph_data(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct reset_sf19a28_periph_data, rcdev);
+}
+
+static int reset_sf19a28_periph_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ struct reset_sf19a28_periph_data *data = to_reset_sf19a28_periph_data(rcdev);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&data->lock, flags);
+ reg = readl(data->base);
+ if (assert)
+ reg |= data->reset_masks[id];
+ else
+ reg &= ~data->reset_masks[id];
+ writel(reg, data->base);
+ spin_unlock_irqrestore(&data->lock, flags);
+ return 0;
+}
+
+static int reset_sf19a28_periph_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return reset_sf19a28_periph_update(rcdev, id, true);
+}
+
+static int reset_sf19a28_periph_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return reset_sf19a28_periph_update(rcdev, id, false);
+}
+
+static int reset_sf19a28_periph_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct reset_sf19a28_periph_data *data = to_reset_sf19a28_periph_data(rcdev);
+ u32 reg;
+
+ reg = readl(data->base);
+ return !!(reg & data->reset_masks[id]);
+}
+
+const struct reset_control_ops reset_sf19a28_periph_ops = {
+ .assert = reset_sf19a28_periph_assert,
+ .deassert = reset_sf19a28_periph_deassert,
+ .status = reset_sf19a28_periph_status,
+};
+
+static const struct of_device_id reset_sf19a28_periph_dt_ids[] = {
+ { .compatible = "siflower,sf19a2890-periph-reset", },
+ { /* sentinel */ },
+};
+
+static int reset_sf19a28_periph_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct reset_sf19a28_periph_data *data;
+ void __iomem *base;
+ int nr_resets;
+ int ret, i;
+ u32 tmp;
+
+ nr_resets = of_property_count_u32_elems(node, "siflower,reset-masks");
+
+ if (nr_resets < 1) {
+ ret = of_property_read_u32(node, "siflower,num-resets", &tmp);
+ if (ret < 0 || tmp < 1)
+ return -EINVAL;
+ nr_resets = tmp;
+ }
+
+ if (nr_resets >= 32) {
+ dev_err(dev, "too many resets.");
+ return -EINVAL;
+ }
+
+ data = devm_kzalloc(dev, struct_size(data, reset_masks, nr_resets), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(node, "siflower,reset-masks",
+ data->reset_masks, nr_resets);
+ if (ret)
+ for (i = 0; i < nr_resets; i++)
+ data->reset_masks[i] = BIT(i);
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ spin_lock_init(&data->lock);
+ data->base = base;
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.nr_resets = nr_resets;
+ data->rcdev.ops = &reset_sf19a28_periph_ops;
+ data->rcdev.of_node = dev->of_node;
+
+ return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static struct platform_driver reset_sf19a28_periph_driver = {
+ .probe = reset_sf19a28_periph_probe,
+ .driver = {
+ .name = "reset-sf19a2890-periph",
+ .of_match_table = reset_sf19a28_periph_dt_ids,
+ },
+};
+builtin_platform_driver(reset_sf19a28_periph_driver);
diff --git a/target/linux/siflower/files-6.6/include/dt-bindings/clock/siflower,sf19a2890-clk.h b/target/linux/siflower/files-6.6/include/dt-bindings/clock/siflower,sf19a2890-clk.h
new file mode 100644
index 0000000000..06bf0b007e
--- /dev/null
+++ b/target/linux/siflower/files-6.6/include/dt-bindings/clock/siflower,sf19a2890-clk.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+#ifndef __DT_BINDINGS_CLOCK_SIFLOWER_SF19A2890_CLK_H
+#define __DT_BINDINGS_CLOCK_SIFLOWER_SF19A2890_CLK_H
+#define CLK_PLL_CPU 0
+#define CLK_PLL_DDR 1
+#define CLK_PLL_CMN 2
+#define CLK_MUXDIV_BUS1 3
+#define CLK_MUXDIV_BUS2 4
+#define CLK_MUXDIV_BUS3 5
+#define CLK_MUXDIV_CPU 6
+#define CLK_MUXDIV_PBUS 7
+#define CLK_MUXDIV_MEM_PHY 8
+#define CLK_MUXDIV_UART 9
+#define CLK_MUXDIV_ETH_REF 10
+#define CLK_MUXDIV_ETH_BYP_REF 11
+#define CLK_MUXDIV_ETH_TSU 12
+#define CLK_MUXDIV_GMAC_BYP_REF 13
+#define CLK_MUXDIV_M6250_0 14
+#define CLK_MUXDIV_M6250_1 15
+#define CLK_MUXDIV_WLAN24_PLF 16
+#define CLK_MUXDIV_WLAN5_PLF 17
+#define CLK_MUXDIV_USBPHY_REF 18
+#define CLK_MUXDIV_TCLK 19
+#define CLK_MUXDIV_NPU_PE_CLK 20
+
+#define CLK_SF19A2890_MAX 21
+#endif /* __DT_BINDINGS_CLOCK_SIFLOWER_SF19A2890_CLK_H */
diff --git a/target/linux/siflower/image/Makefile b/target/linux/siflower/image/Makefile
new file mode 100644
index 0000000000..e86927dd78
--- /dev/null
+++ b/target/linux/siflower/image/Makefile
@@ -0,0 +1,28 @@
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+KERNEL_LOADADDR := 0x80100000
+
+define Device/Default
+ PROFILES := Default
+ BLOCKSIZE := 64k
+ FILESYSTEMS := squashfs
+ DEVICE_DTS_DIR := ../dts
+ KERNEL := kernel-bin | append-dtb | lzma | uImage lzma
+ KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | uImage lzma
+ IMAGES := sysupgrade.bin
+ IMAGE/sysupgrade.bin = append-kernel | pad-to $$$$(BLOCKSIZE) | \
+ append-rootfs | pad-rootfs | append-metadata
+endef
+
+define Device/siflower_sf19a2890-evb
+ DEVICE_VENDOR := Siflower
+ DEVICE_MODEL := SF19A2890 EVB
+ BOARD_NAME := siflower,sf19a2890-evb
+ DEVICE_DTS := sf19a2890_evb
+ DEVICE_PACKAGES := kmod-switch-rtl8367b swconfig
+endef
+TARGET_DEVICES += siflower_sf19a2890-evb
+
+$(eval $(call BuildImage))
diff --git a/target/linux/siflower/modules.mk b/target/linux/siflower/modules.mk
new file mode 100644
index 0000000000..e8aaf768e4
--- /dev/null
+++ b/target/linux/siflower/modules.mk
@@ -0,0 +1,15 @@
+define KernelPackage/phy-sf19a2890-usb
+ TITLE:=Siflower SF19A2890 USB 2.0 PHY Driver
+ KCONFIG:=CONFIG_PHY_SF19A2890_USB
+ DEPENDS:=@TARGET_siflower_sf19a2890
+ SUBMENU:=$(USB_MENU)
+ FILES:=$(LINUX_DIR)/drivers/phy/siflower/phy-sf19a2890-usb.ko
+ AUTOLOAD:=$(call AutoLoad,45,phy-sf19a2890-usb,1)
+endef
+
+define KernelPackage/phy-sf19a2890-usb/description
+ Support for Siflower SF19A2890 USB 2.0 PHY connected to the USB
+ controller.
+endef
+
+$(eval $(call KernelPackage,phy-sf19a2890-usb))
diff --git a/target/linux/siflower/patches-6.6/001-mips-add-support-for-Siflower-SF19A2890.patch b/target/linux/siflower/patches-6.6/001-mips-add-support-for-Siflower-SF19A2890.patch
new file mode 100644
index 0000000000..69bd0b83d7
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/001-mips-add-support-for-Siflower-SF19A2890.patch
@@ -0,0 +1,59 @@
+From c2ec4604afb39904c01dfe38ca8289c446b898bb Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 20 Aug 2024 08:32:17 +0800
+Subject: [PATCH 1/9] mips: add support for Siflower SF19A2890
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ arch/mips/Kconfig | 29 +++++++++++++++++++++++++++++
+ arch/mips/generic/Platform | 1 +
+ 2 files changed, 30 insertions(+)
+
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -861,6 +861,35 @@ config SIBYTE_BIGSUR
+ select ZONE_DMA32 if 64BIT
+ select SWIOTLB if ARCH_DMA_ADDR_T_64BIT && PCI
+
++config MACH_SIFLOWER_MIPS
++ bool "Siflower MIPS SoCs"
++ select MIPS_GENERIC
++ select ARM_AMBA
++ select BOOT_RAW
++ select CEVT_R4K
++ select CLKSRC_MIPS_GIC
++ select COMMON_CLK
++ select CPU_MIPSR2_IRQ_EI
++ select CPU_MIPSR2_IRQ_VI
++ select CSRC_R4K
++ select DMA_NONCOHERENT
++ select IRQ_MIPS_CPU
++ select MIPS_CPU_SCACHE
++ select MIPS_GIC
++ select MIPS_L1_CACHE_SHIFT_5
++ select NO_EXCEPT_FILL
++ select SMP_UP if SMP
++ select SYS_HAS_CPU_MIPS32_R2
++ select SYS_SUPPORTS_32BIT_KERNEL
++ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_SUPPORTS_MIPS16
++ select SYS_SUPPORTS_MIPS_CPS
++ select SYS_SUPPORTS_MULTITHREADING
++ select USE_OF
++ help
++ Select this to build a kernel which supports SoCs from Siflower
++ with MIPS InterAptiv cores, like Siflower SF19A2890.
++
+ config SNI_RM
+ bool "SNI RM200/300/400"
+ select ARC_MEMORY
+--- a/arch/mips/generic/Platform
++++ b/arch/mips/generic/Platform
+@@ -10,6 +10,7 @@
+
+ # Note: order matters, keep the asm/mach-generic include last.
+ cflags-$(CONFIG_MACH_INGENIC_SOC) += -I$(srctree)/arch/mips/include/asm/mach-ingenic
++cflags-$(CONFIG_MACH_SIFLOWER_MIPS) += -I$(srctree)/arch/mips/include/asm/mach-siflower
+ cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic
+
+ load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000
diff --git a/target/linux/siflower/patches-6.6/002-clk-add-drivers-for-sf19a2890.patch b/target/linux/siflower/patches-6.6/002-clk-add-drivers-for-sf19a2890.patch
new file mode 100644
index 0000000000..620e432a49
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/002-clk-add-drivers-for-sf19a2890.patch
@@ -0,0 +1,31 @@
+From fcb96cb774abf14375326c41cedd237d6c8f6e94 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 20 Aug 2024 08:33:01 +0800
+Subject: [PATCH 2/9] clk: add drivers for sf19a2890
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ drivers/clk/Kconfig | 1 +
+ drivers/clk/Makefile | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/clk/Kconfig
++++ b/drivers/clk/Kconfig
+@@ -489,6 +489,7 @@ source "drivers/clk/renesas/Kconfig"
+ source "drivers/clk/rockchip/Kconfig"
+ source "drivers/clk/samsung/Kconfig"
+ source "drivers/clk/sifive/Kconfig"
++source "drivers/clk/siflower/Kconfig"
+ source "drivers/clk/socfpga/Kconfig"
+ source "drivers/clk/sprd/Kconfig"
+ source "drivers/clk/starfive/Kconfig"
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -116,6 +116,7 @@ obj-y += renesas/
+ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
+ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
+ obj-$(CONFIG_CLK_SIFIVE) += sifive/
++obj-$(CONFIG_CLK_SIFLOWER) += siflower/
+ obj-y += socfpga/
+ obj-$(CONFIG_PLAT_SPEAR) += spear/
+ obj-y += sprd/
diff --git a/target/linux/siflower/patches-6.6/003-reset-add-support-for-sf19a2890.patch b/target/linux/siflower/patches-6.6/003-reset-add-support-for-sf19a2890.patch
new file mode 100644
index 0000000000..52992ac5dd
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/003-reset-add-support-for-sf19a2890.patch
@@ -0,0 +1,38 @@
+From 819d2a48d45f3734c876186e651917bae69be9ba Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 20 Aug 2024 08:33:43 +0800
+Subject: [PATCH 3/9] reset: add support for sf19a2890
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ drivers/reset/Kconfig | 8 ++++++++
+ drivers/reset/Makefile | 1 +
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/reset/Kconfig
++++ b/drivers/reset/Kconfig
+@@ -211,6 +211,14 @@ config RESET_SCMI
+ This driver uses SCMI Message Protocol to interact with the
+ firmware controlling all the reset signals.
+
++config RESET_SF19A2890_PERIPH
++ bool "Siflower SF19A2890 Peripheral Reset Controller Driver"
++ default MACH_SIFLOWER_MIPS
++ depends on HAS_IOMEM
++ help
++ This enables reset controller driver for peripheral reset blocks
++ found on Siflower SF19A2890 SoC.
++
+ config RESET_SIMPLE
+ bool "Simple Reset Controller Driver" if COMPILE_TEST || EXPERT
+ default ARCH_ASPEED || ARCH_BCMBCA || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || (ARCH_INTEL_SOCFPGA && ARM64) || ARCH_SUNXI || ARC
+--- a/drivers/reset/Makefile
++++ b/drivers/reset/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_QCOM_PDC) += reset-qc
+ obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
+ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
+ obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
++obj-$(CONFIG_RESET_SF19A2890_PERIPH) += reset-sf19a2890-periph.o
+ obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
+ obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+ obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
diff --git a/target/linux/siflower/patches-6.6/004-gpio-add-support-for-siflower-socs.patch b/target/linux/siflower/patches-6.6/004-gpio-add-support-for-siflower-socs.patch
new file mode 100644
index 0000000000..c381b86e14
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/004-gpio-add-support-for-siflower-socs.patch
@@ -0,0 +1,37 @@
+From 1d37455eacb1d0c262ae6aaecadf27964cbf97d8 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 20 Aug 2024 08:33:57 +0800
+Subject: [PATCH 4/9] gpio: add support for siflower socs
+
+---
+ drivers/gpio/Kconfig | 8 ++++++++
+ drivers/gpio/Makefile | 1 +
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -576,6 +576,14 @@ config GPIO_SIFIVE
+ help
+ Say yes here to support the GPIO device on SiFive SoCs.
+
++config GPIO_SIFLOWER
++ tristate "SiFlower GPIO support"
++ depends on OF_GPIO
++ depends on MACH_SIFLOWER_MIPS || COMPILE_TEST
++ select GPIOLIB_IRQCHIP
++ help
++ GPIO controller driver for SiFlower SoCs.
++
+ config GPIO_SIOX
+ tristate "SIOX GPIO support"
+ depends on SIOX
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -143,6 +143,7 @@ obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio
+ obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
+ obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
+ obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o
++obj-$(CONFIG_GPIO_SIFLOWER) += gpio-siflower.o
+ obj-$(CONFIG_GPIO_SIM) += gpio-sim.o
+ obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o
+ obj-$(CONFIG_GPIO_SL28CPLD) += gpio-sl28cpld.o
diff --git a/target/linux/siflower/patches-6.6/005-pinctrl-add-driver-for-siflower-sf19a2890.patch b/target/linux/siflower/patches-6.6/005-pinctrl-add-driver-for-siflower-sf19a2890.patch
new file mode 100644
index 0000000000..e9026476d3
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/005-pinctrl-add-driver-for-siflower-sf19a2890.patch
@@ -0,0 +1,39 @@
+From 59c6a4972b584d986f72fe8d7c55930fdf799bc8 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 20 Aug 2024 08:34:20 +0800
+Subject: [PATCH 5/9] pinctrl: add driver for siflower sf19a2890
+
+---
+ drivers/pinctrl/Kconfig | 10 ++++++++++
+ drivers/pinctrl/Makefile | 1 +
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -417,6 +417,16 @@ config PINCTRL_ROCKCHIP
+ help
+ This support pinctrl and GPIO driver for Rockchip SoCs.
+
++config PINCTRL_SF19A2890
++ tristate "Siflower SF19A2890 pinctrl driver"
++ depends on OF && (MACH_SIFLOWER_MIPS || COMPILE_TEST)
++ select PINMUX
++ select PINCONF
++ select GENERIC_PINCONF
++ default MACH_SIFLOWER_MIPS
++ help
++ Say Y here to enable the Siflower SF19A2890 pinctrl driver.
++
+ config PINCTRL_SINGLE
+ tristate "One-register-per-pin type device tree based pinctrl driver"
+ depends on OF
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -43,6 +43,7 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-p
+ obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
+ obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
+ obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
++obj-$(CONFIG_PINCTRL_SF19A2890) += pinctrl-sf19a2890.o
+ obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
+ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
+ obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o
diff --git a/target/linux/siflower/patches-6.6/006-stmmac-add-support-for-sf19a2890.patch b/target/linux/siflower/patches-6.6/006-stmmac-add-support-for-sf19a2890.patch
new file mode 100644
index 0000000000..b65cd3ed04
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/006-stmmac-add-support-for-sf19a2890.patch
@@ -0,0 +1,38 @@
+From baa6c00f7a88b28f6838a9743f66c9f7f4716e25 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 20 Aug 2024 08:34:42 +0800
+Subject: [PATCH 6/9] stmmac: add support for sf19a2890
+
+---
+ drivers/net/ethernet/stmicro/stmmac/Kconfig | 9 +++++++++
+ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
+ 2 files changed, 10 insertions(+)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+@@ -142,6 +142,15 @@ config DWMAC_ROCKCHIP
+ This selects the Rockchip RK3288 SoC glue layer support for
+ the stmmac device driver.
+
++config DWMAC_SF19A2890
++ tristate "Siflower SF19A2890 GMAC support"
++ default MACH_SIFLOWER_MIPS
++ help
++ Support for GMAC on Siflower SF19A2890 SoC.
++
++ This selects the Siflower SF19A2890 SoC glue layer support for
++ the stmmac device driver.
++
+ config DWMAC_SOCFPGA
+ tristate "SOCFPGA dwmac support"
+ default ARCH_INTEL_SOCFPGA
+--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
++++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
+@@ -21,6 +21,7 @@ obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-me
+ obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
+ obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
+ obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
++obj-$(CONFIG_DWMAC_SF19A2890) += dwmac-sf19a2890.o
+ obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
+ obj-$(CONFIG_DWMAC_STARFIVE) += dwmac-starfive.o
+ obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
diff --git a/target/linux/siflower/patches-6.6/007-phy-add-support-for-SF19A2890-USB-PHY.patch b/target/linux/siflower/patches-6.6/007-phy-add-support-for-SF19A2890-USB-PHY.patch
new file mode 100644
index 0000000000..97b7126e02
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/007-phy-add-support-for-SF19A2890-USB-PHY.patch
@@ -0,0 +1,31 @@
+From 68817a14ae9dff587cee8515e68c67cba89b39ab Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Mon, 9 Sep 2024 10:18:33 +0800
+Subject: [PATCH 7/9] phy: add support for SF19A2890 USB PHY
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ drivers/phy/Kconfig | 1 +
+ drivers/phy/Makefile | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -90,6 +90,7 @@ source "drivers/phy/ralink/Kconfig"
+ source "drivers/phy/renesas/Kconfig"
+ source "drivers/phy/rockchip/Kconfig"
+ source "drivers/phy/samsung/Kconfig"
++source "drivers/phy/siflower/Kconfig"
+ source "drivers/phy/socionext/Kconfig"
+ source "drivers/phy/st/Kconfig"
+ source "drivers/phy/starfive/Kconfig"
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -29,6 +29,7 @@ obj-y += allwinner/ \
+ renesas/ \
+ rockchip/ \
+ samsung/ \
++ siflower/ \
+ socionext/ \
+ st/ \
+ starfive/ \
diff --git a/target/linux/siflower/patches-6.6/008-usb-dwc2-add-support-for-Siflower-SF19A2890.patch b/target/linux/siflower/patches-6.6/008-usb-dwc2-add-support-for-Siflower-SF19A2890.patch
new file mode 100644
index 0000000000..b551e4f2ca
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/008-usb-dwc2-add-support-for-Siflower-SF19A2890.patch
@@ -0,0 +1,36 @@
+From 29282086f215ae723e6d2c139d23094e699ba5bb Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Mon, 9 Sep 2024 16:46:53 +0800
+Subject: [PATCH 8/9] usb: dwc2: add support for Siflower SF19A2890
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ drivers/usb/dwc2/params.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/usb/dwc2/params.c
++++ b/drivers/usb/dwc2/params.c
+@@ -200,6 +200,14 @@ static void dwc2_set_amcc_params(struct
+ p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT;
+ }
+
++static void dwc2_set_sf19a2890_params(struct dwc2_hsotg *hsotg)
++{
++ struct dwc2_core_params *p = &hsotg->params;
++
++ p->max_transfer_size = 65535;
++ p->ahbcfg = GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT;
++}
++
+ static void dwc2_set_stm32f4x9_fsotg_params(struct dwc2_hsotg *hsotg)
+ {
+ struct dwc2_core_params *p = &hsotg->params;
+@@ -294,6 +302,8 @@ const struct of_device_id dwc2_of_match_
+ .data = dwc2_set_amlogic_a1_params },
+ { .compatible = "amcc,dwc-otg", .data = dwc2_set_amcc_params },
+ { .compatible = "apm,apm82181-dwc-otg", .data = dwc2_set_amcc_params },
++ { .compatible = "siflower,sf19a2890-usb",
++ .data = dwc2_set_sf19a2890_params },
+ { .compatible = "st,stm32f4x9-fsotg",
+ .data = dwc2_set_stm32f4x9_fsotg_params },
+ { .compatible = "st,stm32f4x9-hsotg" },
diff --git a/target/linux/siflower/patches-6.6/009-usb-dwc2-handle-OTG-interrupt-regardless-of-GINTSTS.patch b/target/linux/siflower/patches-6.6/009-usb-dwc2-handle-OTG-interrupt-regardless-of-GINTSTS.patch
new file mode 100644
index 0000000000..03fb16879c
--- /dev/null
+++ b/target/linux/siflower/patches-6.6/009-usb-dwc2-handle-OTG-interrupt-regardless-of-GINTSTS.patch
@@ -0,0 +1,67 @@
+From 0b04c37a1aae523025195c29a6477cf26234d26c Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 10 Sep 2024 09:10:27 +0800
+Subject: [PATCH 9/9] usb: dwc2: handle OTG interrupt regardless of GINTSTS
+
+The DWC OTG 3.30a found on Siflower SF19A2890 has battery charger
+support enabled. It triggers MultVallpChng interrupt (bit 20 of
+GOTGINT) but doesn't set OTGInt in GINTSTS. As a result, this
+interrupt is never handled, and linux disables USB interrupt
+because "nobody cares".
+
+Handle OTG interrupt in IRQ handler regardless of whether the
+OTGInt bit in GINTSTS is set or not.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ drivers/usb/dwc2/core_intr.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/dwc2/core_intr.c
++++ b/drivers/usb/dwc2/core_intr.c
+@@ -79,7 +79,7 @@ static void dwc2_handle_mode_mismatch_in
+ *
+ * @hsotg: Programming view of DWC_otg controller
+ */
+-static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
++static irqreturn_t dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
+ {
+ u32 gotgint;
+ u32 gotgctl;
+@@ -87,6 +87,10 @@ static void dwc2_handle_otg_intr(struct
+
+ gotgint = dwc2_readl(hsotg, GOTGINT);
+ gotgctl = dwc2_readl(hsotg, GOTGCTL);
++
++ if (!gotgint)
++ return IRQ_NONE;
++
+ dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint,
+ dwc2_op_state_str(hsotg));
+
+@@ -229,6 +233,7 @@ static void dwc2_handle_otg_intr(struct
+
+ /* Clear GOTGINT */
+ dwc2_writel(hsotg, gotgint, GOTGINT);
++ return IRQ_HANDLED;
+ }
+
+ /**
+@@ -842,6 +847,8 @@ irqreturn_t dwc2_handle_common_intr(int
+ hsotg->frame_number = (dwc2_readl(hsotg, HFNUM)
+ & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
+
++ retval = dwc2_handle_otg_intr(hsotg);
++
+ gintsts = dwc2_read_common_intr(hsotg);
+ if (gintsts & ~GINTSTS_PRTINT)
+ retval = IRQ_HANDLED;
+@@ -855,8 +862,6 @@ irqreturn_t dwc2_handle_common_intr(int
+
+ if (gintsts & GINTSTS_MODEMIS)
+ dwc2_handle_mode_mismatch_intr(hsotg);
+- if (gintsts & GINTSTS_OTGINT)
+- dwc2_handle_otg_intr(hsotg);
+ if (gintsts & GINTSTS_CONIDSTSCHNG)
+ dwc2_handle_conn_id_status_change_intr(hsotg);
+ if (gintsts & GINTSTS_DISCONNINT)
diff --git a/target/linux/siflower/sf19a2890/base-files/etc/board.d/02_network b/target/linux/siflower/sf19a2890/base-files/etc/board.d/02_network
new file mode 100644
index 0000000000..f3da21444b
--- /dev/null
+++ b/target/linux/siflower/sf19a2890/base-files/etc/board.d/02_network
@@ -0,0 +1,42 @@
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+siflower_setup_interfaces()
+{
+ local board="$1"
+
+ case $board in
+ siflower,sf19a2890-evb)
+ ucidef_add_switch "switch0" \
+ "0:wan" "1:lan" "2:lan" "3:lan" "4:lan" "6@eth0"
+ ;;
+ esac
+}
+
+siflower_setup_macs()
+{
+ local board="$1"
+ local lan_mac=""
+ local wan_mac=""
+ local label_mac=""
+
+ case $board in
+ siflower,sf19a2890-evb)
+ wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x0)" 1)
+ ;;
+ esac
+
+ [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
+ [ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
+ [ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
+}
+
+board_config_update
+board=$(board_name)
+siflower_setup_interfaces $board
+siflower_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/siflower/sf19a2890/base-files/lib/upgrade/platform.sh b/target/linux/siflower/sf19a2890/base-files/lib/upgrade/platform.sh
new file mode 100644
index 0000000000..80cf1cdcf0
--- /dev/null
+++ b/target/linux/siflower/sf19a2890/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,22 @@
+PART_NAME=firmware
+REQUIRE_IMAGE_METADATA=1
+
+platform_check_image() {
+ local board=$(board_name)
+
+ case "$board" in
+ *)
+ return 0
+ ;;
+ esac
+}
+
+platform_do_upgrade() {
+ local board=$(board_name)
+
+ case "$board" in
+ *)
+ default_do_upgrade "$1"
+ ;;
+ esac
+}
diff --git a/target/linux/siflower/sf19a2890/config-6.6 b/target/linux/siflower/sf19a2890/config-6.6
new file mode 100644
index 0000000000..bec75436e0
--- /dev/null
+++ b/target/linux/siflower/sf19a2890/config-6.6
@@ -0,0 +1,266 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_AMBA=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BOARD_SCACHE=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLKSRC_MIPS_GIC=y
+CONFIG_CLK_SF19A2890=y
+CONFIG_CLK_SF19A2890_PERIPH=y
+CONFIG_CLK_SIFLOWER=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONNECTOR=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_COREDUMP=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_DIEI=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_EI=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_R4K_FPU=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRC16=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DTC=y
+# CONFIG_DWMAC_GENERIC is not set
+CONFIG_DWMAC_SF19A2890=y
+CONFIG_DW_WATCHDOG=y
+CONFIG_ELF_CORE=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_FANOTIFY=y
+CONFIG_FHANDLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FS_IOMAP=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_SIFLOWER=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MACH_SIFLOWER_MIPS=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MICREL_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+CONFIG_MIPS_CM=y
+CONFIG_MIPS_CMDLINE_DTB_EXTEND=y
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CPC=y
+CONFIG_MIPS_CPS=y
+# CONFIG_MIPS_CPS_NS16550_BOOL is not set
+CONFIG_MIPS_CPS_PM=y
+CONFIG_MIPS_CPU_SCACHE=y
+CONFIG_MIPS_FP_SUPPORT=y
+CONFIG_MIPS_GENERIC=y
+CONFIG_MIPS_GIC=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_MIPS_L1_CACHE_SHIFT_5=y
+CONFIG_MIPS_MT=y
+CONFIG_MIPS_MT_FPAFF=y
+CONFIG_MIPS_MT_SMP=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_NR_CPU_NR_MAP=4
+CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_TAG_NONE=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NO_EXCEPT_FILL=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+CONFIG_PCS_XPCS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+# CONFIG_PHY_SF19A2890_USB is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_SF19A2890=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_EVENTS=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_SF19A2890_PERIPH=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_INFO=y
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SMP=y
+CONFIG_SMP_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_PL022=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SRAM=y
+CONFIG_STACKPROTECTOR=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_R4K=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_SYS_SUPPORTS_MIPS_CPS=y
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
+CONFIG_SYS_SUPPORTS_SCHED_SMT=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_WERROR=y
+CONFIG_XPS=y
diff --git a/target/linux/siflower/sf19a2890/target.mk b/target/linux/siflower/sf19a2890/target.mk
new file mode 100644
index 0000000000..6c47709895
--- /dev/null
+++ b/target/linux/siflower/sf19a2890/target.mk
@@ -0,0 +1,12 @@
+ARCH:=mipsel
+SUBTARGET:=sf19a2890
+BOARDNAME:=Siflower SF19A2890 based boards
+FEATURES+=fpu
+CPU_TYPE:=24kc
+CPU_SUBTYPE:=24kf
+
+KERNELNAME:=vmlinux
+
+define Target/Description
+ Build firmware images for Siflower SF19A2890 based boards.
+endef
diff --git a/target/linux/starfive/Makefile b/target/linux/starfive/Makefile
index f71f57e7f7..22bd463858 100644
--- a/target/linux/starfive/Makefile
+++ b/target/linux/starfive/Makefile
@@ -10,7 +10,7 @@ BOARDNAME:=StarFive JH71x0 (7100/7110)
FEATURES:=ext4
KERNELNAME:=Image dtbs
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/starfive/config-6.1 b/target/linux/starfive/config-6.1
deleted file mode 100644
index 6da229ddb5..0000000000
--- a/target/linux/starfive/config-6.1
+++ /dev/null
@@ -1,555 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_AMBA_PL08X=y
-CONFIG_ARCH_CLOCKSOURCE_INIT=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=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_MAX=17
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_RV64I=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SIFIVE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_STARFIVE=y
-CONFIG_ARCH_WANTS_THP_SWAP=y
-CONFIG_ARM_AMBA=y
-# CONFIG_ARM_MHU_V2 is not set
-CONFIG_ASN1=y
-CONFIG_ASSOCIATIVE_ARRAY=y
-CONFIG_AUXILIARY_BUS=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
-CONFIG_CLK_SIFIVE=y
-CONFIG_CLK_SIFIVE_PRCI=y
-CONFIG_CLK_STARFIVE_JH7100=y
-CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
-CONFIG_CLK_STARFIVE_JH7110_AON=y
-CONFIG_CLK_STARFIVE_JH7110_ISP=y
-CONFIG_CLK_STARFIVE_JH7110_PLL=y
-CONFIG_CLK_STARFIVE_JH7110_STG=y
-CONFIG_CLK_STARFIVE_JH7110_SYS=y
-CONFIG_CLK_STARFIVE_JH7110_VOUT=y
-CONFIG_CLK_STARFIVE_JH71X0=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_CMODEL_MEDANY=y
-# CONFIG_CMODEL_MEDLOW is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=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_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRASH_CORE=y
-CONFIG_CRC16=y
-CONFIG_CRC7=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRYPTO_BLAKE2B=y
-CONFIG_CRYPTO_CMAC=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEV_JH7110=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_ENGINE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_SM3=y
-CONFIG_CRYPTO_SM3_GENERIC=y
-CONFIG_CRYPTO_USER=y
-CONFIG_CRYPTO_USER_API=y
-CONFIG_CRYPTO_USER_API_AEAD=y
-CONFIG_CRYPTO_USER_API_HASH=y
-CONFIG_CRYPTO_USER_API_RNG=y
-CONFIG_CRYPTO_USER_API_SKCIPHER=y
-CONFIG_CRYPTO_XXHASH=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DEBUG_RODATA_TEST=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_RWSEMS=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_DEBUG_SG=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_TIMEKEEPING=y
-CONFIG_DEBUG_WX=y
-CONFIG_DECOMPRESS_GZIP=y
-# CONFIG_DEVFREQ_GOV_PASSIVE is not set
-# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
-# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
-# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
-# CONFIG_DEVFREQ_GOV_USERSPACE is not set
-# CONFIG_DEVFREQ_THERMAL is not set
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_DEVTMPFS_SAFE is not set
-CONFIG_DMADEVICES=y
-CONFIG_DMADEVICES_DEBUG=y
-CONFIG_DMADEVICES_VDEBUG=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-# CONFIG_DPM_WATCHDOG is not set
-CONFIG_DTC=y
-CONFIG_DT_IDLE_GENPD=y
-CONFIG_DT_IDLE_STATES=y
-CONFIG_DWMAC_DWC_QOS_ETH=y
-# CONFIG_DWMAC_GENERIC is not set
-CONFIG_DWMAC_STARFIVE=y
-CONFIG_DW_AXI_DMAC=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-CONFIG_EFI=y
-CONFIG_EFIVAR_FS=y
-# CONFIG_EFI_BOOTLOADER_CONTROL is not set
-# CONFIG_EFI_CAPSULE_LOADER is not set
-# CONFIG_EFI_COCO_SECRET is not set
-# CONFIG_EFI_DISABLE_PCI_DMA is not set
-CONFIG_EFI_DISABLE_RUNTIME=y
-CONFIG_EFI_EARLYCON=y
-CONFIG_EFI_ESRT=y
-CONFIG_EFI_GENERIC_STUB=y
-CONFIG_EFI_PARAMS_FROM_FDT=y
-CONFIG_EFI_RUNTIME_WRAPPERS=y
-CONFIG_EFI_STUB=y
-# CONFIG_EFI_TEST is not set
-# CONFIG_EFI_ZBOOT is not set
-CONFIG_ERRATA_SIFIVE=y
-CONFIG_ERRATA_SIFIVE_CIP_1200=y
-CONFIG_ERRATA_SIFIVE_CIP_453=y
-# CONFIG_ERRATA_THEAD is not set
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXTCON=y
-CONFIG_FAILOVER=y
-CONFIG_FANOTIFY=y
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
-CONFIG_FAT_DEFAULT_UTF8=y
-CONFIG_FAT_FS=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FONT_8x16=y
-CONFIG_FONT_AUTOSELECT=y
-CONFIG_FONT_SUPPORT=y
-CONFIG_FPU=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=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_CSUM=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=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_PHY_MIPI_DPHY=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_FASTPATH_LIMIT=128
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_TPS65086=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_HVC_DRIVER=y
-CONFIG_HVC_RISCV_SBI=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_JH7110=y
-CONFIG_HW_RANDOM_STARFIVE_VIC=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_DESIGNWARE_CORE=y
-CONFIG_I2C_DESIGNWARE_PLATFORM=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_JH71XX_PMU=y
-CONFIG_JUMP_LABEL=y
-CONFIG_LIBFDT=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LSM=""
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MEMTEST=y
-CONFIG_MFD_AXP20X=y
-CONFIG_MFD_AXP20X_I2C=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MFD_TPS65086=y
-CONFIG_MICREL_PHY=y
-CONFIG_MICROCHIP_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DW=y
-# CONFIG_MMC_DW_BLUEFIELD is not set
-# CONFIG_MMC_DW_EXYNOS is not set
-# CONFIG_MMC_DW_HI3798CV200 is not set
-# CONFIG_MMC_DW_K3 is not set
-# CONFIG_MMC_DW_PCI is not set
-CONFIG_MMC_DW_PLTFM=y
-CONFIG_MMC_DW_STARFIVE=y
-CONFIG_MMIOWB=y
-CONFIG_MODULES_TREE_LOOKUP=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MODULE_SECTIONS=y
-CONFIG_MOTORCOMM_PHY=y
-CONFIG_MPILIB=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NAMESPACES=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_FAILOVER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_NS=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_DEFAULT="iso8859-15"
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-# CONFIG_NONPORTABLE is not set
-CONFIG_NR_CPUS=8
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_NVME_CORE=y
-CONFIG_NVME_HWMON=y
-# CONFIG_NVME_MULTIPATH is not set
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DMA_DEFAULT_COHERENT=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_OID_REGISTRY=y
-CONFIG_OVERLAY_FS_INDEX=y
-CONFIG_OVERLAY_FS_METACOPY=y
-CONFIG_OVERLAY_FS_REDIRECT_DIR=y
-CONFIG_PADATA=y
-CONFIG_PAGE_EXTENSION=y
-CONFIG_PAGE_OFFSET=0xff60000000000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_REPORTING=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCIE_CADENCE=y
-CONFIG_PCIE_CADENCE_HOST=y
-CONFIG_PCIE_CADENCE_PLAT=y
-CONFIG_PCIE_CADENCE_PLAT_HOST=y
-# CONFIG_PCIE_FU740 is not set
-# CONFIG_PCIE_STARFIVE is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCS_XPCS=y
-CONFIG_PERF_EVENTS=y
-CONFIG_PGTABLE_LEVELS=5
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PHY_STARFIVE_DPHY_RX=y
-CONFIG_PHY_STARFIVE_JH7110_PCIE=y
-CONFIG_PHY_STARFIVE_JH7110_USB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_STARFIVE_JH7100=y
-CONFIG_PINCTRL_STARFIVE_JH7110=y
-CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
-CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
-CONFIG_PM=y
-CONFIG_PM_ADVANCED_DEBUG=y
-CONFIG_PM_CLK=y
-CONFIG_PM_DEBUG=y
-CONFIG_PM_DEVFREQ=y
-# CONFIG_PM_DEVFREQ_EVENT is not set
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_PM_OPP=y
-CONFIG_PORTABLE=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO_RESTART=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_RESET_SYSCON_POWEROFF=y
-# CONFIG_POWER_RESET_TPS65086 is not set
-CONFIG_PPS=y
-CONFIG_PREEMPT_COUNT=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_CHILDREN=y
-CONFIG_PROC_KCORE=y
-CONFIG_PTDUMP_CORE=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-# CONFIG_PWM_SIFIVE is not set
-CONFIG_PWM_SIFIVE_PTC=y
-CONFIG_PWM_STARFIVE_PTC=y
-CONFIG_PWM_SYSFS=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_RCU_EQS_DEBUG=y
-CONFIG_RD_GZIP=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_IRQ=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_AXP20X=y
-CONFIG_REGULATOR_TPS65086=y
-# CONFIG_RESET_ATTACK_MITIGATION is not set
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_SIMPLE=y
-CONFIG_RESET_STARFIVE_JH7100=y
-CONFIG_RESET_STARFIVE_JH7100_AUDIO=y
-CONFIG_RESET_STARFIVE_JH7110=y
-CONFIG_RESET_STARFIVE_JH71X0=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RISCV=y
-CONFIG_RISCV_ALTERNATIVE=y
-CONFIG_RISCV_BOOT_SPINWAIT=y
-CONFIG_RISCV_DMA_NONCOHERENT=y
-CONFIG_RISCV_INTC=y
-CONFIG_RISCV_ISA_C=y
-# CONFIG_RISCV_ISA_SVPBMT is not set
-CONFIG_RISCV_ISA_ZICBOM=y
-CONFIG_RISCV_PMU=y
-CONFIG_RISCV_PMU_LEGACY=y
-CONFIG_RISCV_PMU_SBI=y
-CONFIG_RISCV_SBI=y
-CONFIG_RISCV_SBI_CPUIDLE=y
-CONFIG_RISCV_SBI_V01=y
-CONFIG_RISCV_TIMER=y
-CONFIG_RPMSG=y
-CONFIG_RPMSG_CHAR=y
-# CONFIG_RPMSG_CTRL is not set
-CONFIG_RPMSG_NS=y
-# CONFIG_RPMSG_TTY is not set
-CONFIG_RPMSG_VIRTIO=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_EFI is not set
-CONFIG_RTC_DRV_GOLDFISH=y
-CONFIG_RTC_DRV_HYM8563=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SCSI_VIRTIO=y
-CONFIG_SENSORS_SFCTEMP=y
-# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_RUNTIME_UARTS=6
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_SIFIVE=y
-CONFIG_SERIAL_SIFIVE_CONSOLE=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SIFIVE_CCACHE=y
-CONFIG_SIFIVE_PLIC=y
-CONFIG_SMP=y
-# CONFIG_SND_SOC_STARFIVE is not set
-CONFIG_SOCK_DIAG=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
-CONFIG_SOC_SIFIVE=y
-CONFIG_SOC_STARFIVE=y
-# CONFIG_SOC_VIRT is not set
-CONFIG_SOFTLOCKUP_DETECTOR=y
-CONFIG_SOUND=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_CADENCE_QUADSPI=y
-CONFIG_SPI_DYNAMIC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_SPIDEV=y
-CONFIG_SRCU=y
-CONFIG_STARFIVE_TIMER=y
-CONFIG_STARFIVE_WATCHDOG=y
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_STMMAC_SELFTESTS=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-# CONFIG_SYSFB_SIMPLEFB is not set
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TOOLCHAIN_HAS_ZICBOM=y
-CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y
-CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_TTY_PRINTK=y
-CONFIG_TTY_PRINTK_LEVEL=6
-CONFIG_TUNE_GENERIC=y
-CONFIG_UCS2_STRING=y
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_CONFIGFS=y
-# CONFIG_USB_CONFIGFS_ACM is not set
-# CONFIG_USB_CONFIGFS_ECM is not set
-# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
-# CONFIG_USB_CONFIGFS_EEM is not set
-CONFIG_USB_CONFIGFS_F_FS=y
-# CONFIG_USB_CONFIGFS_F_HID is not set
-# CONFIG_USB_CONFIGFS_F_LB_SS is not set
-# CONFIG_USB_CONFIGFS_F_MIDI is not set
-# CONFIG_USB_CONFIGFS_F_PRINTER is not set
-# CONFIG_USB_CONFIGFS_F_UAC1 is not set
-# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
-# CONFIG_USB_CONFIGFS_F_UAC2 is not set
-# CONFIG_USB_CONFIGFS_F_UVC is not set
-CONFIG_USB_CONFIGFS_MASS_STORAGE=y
-# CONFIG_USB_CONFIGFS_NCM is not set
-# CONFIG_USB_CONFIGFS_OBEX is not set
-# CONFIG_USB_CONFIGFS_RNDIS is not set
-# CONFIG_USB_CONFIGFS_SERIAL is not set
-CONFIG_USB_F_FS=y
-CONFIG_USB_F_MASS_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_LIBCOMPOSITE=y
-CONFIG_USB_PCI=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_SUPPORT=y
-# CONFIG_USB_UHCI_HCD is not set
-CONFIG_USELIB=y
-CONFIG_USER_NS=y
-CONFIG_VFAT_FS=y
-# CONFIG_VIRTIO_BLK is not set
-# CONFIG_VIRTIO_NET is not set
-CONFIG_VMAP_STACK=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WATCHDOG_SYSFS=y
-CONFIG_WERROR=y
-CONFIG_WQ_WATCHDOG=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
diff --git a/target/linux/starfive/config-6.6 b/target/linux/starfive/config-6.6
new file mode 100644
index 0000000000..cb39210a42
--- /dev/null
+++ b/target/linux/starfive/config-6.6
@@ -0,0 +1,579 @@
+CONFIG_64BIT=y
+# CONFIG_ACPI is not set
+CONFIG_AMBA_PL08X=y
+CONFIG_ARCH_CLOCKSOURCE_INIT=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=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_MAX=17
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+# CONFIG_ARCH_RV32I is not set
+CONFIG_ARCH_RV64I=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SIFIVE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_STARFIVE=y
+# CONFIG_ARCH_THEAD is not set
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_ARM_AMBA=y
+# CONFIG_ARM_MHU_V2 is not set
+CONFIG_ASN1=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_AUXILIARY_BUS=y
+# CONFIG_AX45MP_L2_CACHE is not set
+# CONFIG_BT_AICUSB is not set
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
+CONFIG_CLK_SIFIVE=y
+CONFIG_CLK_SIFIVE_PRCI=y
+CONFIG_CLK_STARFIVE_JH7100=y
+CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
+CONFIG_CLK_STARFIVE_JH7110_AON=y
+CONFIG_CLK_STARFIVE_JH7110_ISP=y
+CONFIG_CLK_STARFIVE_JH7110_PLL=y
+CONFIG_CLK_STARFIVE_JH7110_STG=y
+CONFIG_CLK_STARFIVE_JH7110_SYS=y
+CONFIG_CLK_STARFIVE_JH7110_VOUT=y
+CONFIG_CLK_STARFIVE_JH71X0=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CLZ_TAB=y
+CONFIG_CMODEL_MEDANY=y
+# CONFIG_CMODEL_MEDLOW is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=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_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRASH_CORE=y
+CONFIG_CRC16=y
+CONFIG_CRC7=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_BLAKE2B=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEV_JH7110=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_ENGINE=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SM3=y
+CONFIG_CRYPTO_SM3_GENERIC=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_AEAD=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_RNG=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_XXHASH=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DEBUG_RODATA_TEST=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_DEBUG_WX=y
+CONFIG_DECOMPRESS_GZIP=y
+# CONFIG_DEVFREQ_GOV_PASSIVE is not set
+# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
+# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
+# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
+# CONFIG_DEVFREQ_GOV_USERSPACE is not set
+# CONFIG_DEVFREQ_THERMAL is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_DEVTMPFS_SAFE is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMADEVICES_DEBUG=y
+CONFIG_DMADEVICES_VDEBUG=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+# CONFIG_DPM_WATCHDOG is not set
+CONFIG_DTC=y
+CONFIG_DT_IDLE_GENPD=y
+CONFIG_DT_IDLE_STATES=y
+CONFIG_DWMAC_DWC_QOS_ETH=y
+# CONFIG_DWMAC_GENERIC is not set
+CONFIG_DWMAC_STARFIVE=y
+CONFIG_DW_AXI_DMAC=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EFI=y
+CONFIG_EFIVAR_FS=y
+# CONFIG_EFI_BOOTLOADER_CONTROL is not set
+# CONFIG_EFI_CAPSULE_LOADER is not set
+# CONFIG_EFI_COCO_SECRET is not set
+# CONFIG_EFI_DISABLE_PCI_DMA is not set
+CONFIG_EFI_DISABLE_RUNTIME=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_EFI_ESRT=y
+CONFIG_EFI_GENERIC_STUB=y
+CONFIG_EFI_PARAMS_FROM_FDT=y
+CONFIG_EFI_RUNTIME_WRAPPERS=y
+CONFIG_EFI_STUB=y
+# CONFIG_EFI_TEST is not set
+# CONFIG_EFI_ZBOOT is not set
+# CONFIG_ERRATA_ANDES is not set
+CONFIG_ERRATA_STARFIVE_JH7100=y
+CONFIG_ERRATA_SIFIVE=y
+CONFIG_ERRATA_SIFIVE_CIP_1200=y
+CONFIG_ERRATA_SIFIVE_CIP_453=y
+# CONFIG_ERRATA_THEAD is not set
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_FAILOVER=y
+CONFIG_FANOTIFY=y
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_FAT_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FPU=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC11_NO_ARRAY_BOUNDS=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_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=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_PHY_MIPI_DPHY=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_FASTPATH_LIMIT=128
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_TPS65086=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_RISCV_SBI=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_JH7110=y
+CONFIG_HW_RANDOM_STARFIVE_VIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DESIGNWARE_CORE=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_IPMS_CAN is not set
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_STACKS=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_JH71XX_PMU=y
+CONFIG_JUMP_LABEL=y
+CONFIG_LIBFDT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LSM=""
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MEMTEST=y
+CONFIG_MFD_AXP20X=y
+CONFIG_MFD_AXP20X_I2C=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_TPS65086=y
+CONFIG_MICREL_PHY=y
+CONFIG_MICROCHIP_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
+# CONFIG_MMC_DW_EXYNOS is not set
+# CONFIG_MMC_DW_HI3798CV200 is not set
+# CONFIG_MMC_DW_K3 is not set
+# CONFIG_MMC_DW_PCI is not set
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_DW_STARFIVE=y
+CONFIG_MMIOWB=y
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MODULE_SECTIONS=y
+CONFIG_MOTORCOMM_PHY=y
+CONFIG_MPILIB=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_FAILOVER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_NS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NONPORTABLE=y
+CONFIG_NR_CPUS=8
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_NVME_CORE=y
+CONFIG_NVME_HWMON=y
+# CONFIG_NVME_MULTIPATH is not set
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+# CONFIG_OF_CONFIGFS is not set
+CONFIG_OF_DMA_DEFAULT_COHERENT=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_OID_REGISTRY=y
+CONFIG_OVERLAY_FS_INDEX=y
+CONFIG_OVERLAY_FS_METACOPY=y
+CONFIG_OVERLAY_FS_REDIRECT_DIR=y
+CONFIG_PADATA=y
+CONFIG_PAGE_EXTENSION=y
+CONFIG_PAGE_OFFSET=0xff60000000000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_REPORTING=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI=y
+CONFIG_PCIE_CADENCE=y
+CONFIG_PCIE_CADENCE_HOST=y
+CONFIG_PCIE_CADENCE_PLAT=y
+CONFIG_PCIE_CADENCE_PLAT_HOST=y
+# CONFIG_PCIE_FU740 is not set
+CONFIG_PCIE_STARFIVE_HOST=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PCS_XPCS=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PGTABLE_LEVELS=5
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHYS_RAM_BASE_FIXED is not set
+CONFIG_PHY_STARFIVE_DPHY_RX=y
+CONFIG_PHY_STARFIVE_JH7110_DPHY_RX=y
+CONFIG_PHY_STARFIVE_JH7110_PCIE=y
+CONFIG_PHY_STARFIVE_JH7110_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_STARFIVE_JH7100=y
+CONFIG_PINCTRL_STARFIVE_JH7110=y
+CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
+CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
+CONFIG_PM=y
+CONFIG_PM_ADVANCED_DEBUG=y
+CONFIG_PM_CLK=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_DEVFREQ=y
+# CONFIG_PM_DEVFREQ_EVENT is not set
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_OPP=y
+CONFIG_PORTABLE=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+# CONFIG_POWER_RESET_TPS65086 is not set
+CONFIG_PPS=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_CHILDREN=y
+CONFIG_PROC_KCORE=y
+CONFIG_PTDUMP_CORE=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_OCORES=y
+# CONFIG_PWM_SIFIVE is not set
+CONFIG_PWM_SIFIVE_PTC=y
+CONFIG_PWM_STARFIVE_PTC=y
+CONFIG_PWM_SYSFS=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_EQS_DEBUG=y
+CONFIG_RD_GZIP=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_IRQ=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_STARFIVE_JH7110=y
+CONFIG_REGULATOR_TPS65086=y
+# CONFIG_RESET_ATTACK_MITIGATION is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_SIMPLE=y
+CONFIG_RESET_STARFIVE_JH7100=y
+CONFIG_RESET_STARFIVE_JH7100_AUDIO=y
+CONFIG_RESET_STARFIVE_JH7110=y
+CONFIG_RESET_STARFIVE_JH71X0=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RISCV=y
+CONFIG_RISCV_ALTERNATIVE=y
+CONFIG_RISCV_BOOT_SPINWAIT=y
+CONFIG_RISCV_DMA_NONCOHERENT=y
+CONFIG_RISCV_INTC=y
+CONFIG_RISCV_ISA_C=y
+CONFIG_RISCV_ISA_FALLBACK=y
+CONFIG_RISCV_ISA_SVNAPOT=y
+# CONFIG_RISCV_ISA_SVPBMT is not set
+CONFIG_RISCV_ISA_V=y
+CONFIG_RISCV_ISA_V_DEFAULT_ENABLE=y
+CONFIG_RISCV_ISA_ZBB=y
+# CONFIG_RISCV_ISA_ZICBOM is not set
+CONFIG_RISCV_ISA_ZICBOZ=y
+CONFIG_RISCV_PMU=y
+CONFIG_RISCV_PMU_LEGACY=y
+CONFIG_RISCV_PMU_SBI=y
+CONFIG_RISCV_SBI=y
+CONFIG_RISCV_SBI_CPUIDLE=y
+CONFIG_RISCV_SBI_V01=y
+CONFIG_RISCV_TIMER=y
+CONFIG_RPMSG=y
+CONFIG_RPMSG_CHAR=y
+# CONFIG_RPMSG_CTRL is not set
+CONFIG_RPMSG_NS=y
+# CONFIG_RPMSG_TTY is not set
+CONFIG_RPMSG_VIRTIO=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_EFI is not set
+CONFIG_RTC_DRV_GOLDFISH=y
+CONFIG_RTC_DRV_HYM8563=y
+CONFIG_RTC_DRV_STARFIVE=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI_VIRTIO=y
+CONFIG_SENSORS_SFCTEMP=y
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_RUNTIME_UARTS=6
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_SIFIVE=y
+CONFIG_SERIAL_SIFIVE_CONSOLE=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SIFIVE_CCACHE=y
+CONFIG_SIFIVE_PLIC=y
+CONFIG_SMP=y
+# CONFIG_SND_SOC_AC108 is not set
+# CONFIG_SND_SOC_STARFIVE is not set
+CONFIG_SOCK_DIAG=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
+CONFIG_SOC_SIFIVE=y
+CONFIG_SOC_STARFIVE=y
+# CONFIG_SOC_VIRT is not set
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_SOUND=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_CADENCE_QUADSPI=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SRCU=y
+CONFIG_STARFIVE_TIMER=y
+CONFIG_STARFIVE_JH7110_TIMER=y
+CONFIG_STARFIVE_WATCHDOG=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_STMMAC_SELFTESTS=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_SYSFB_SIMPLEFB is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_THREAD_SIZE_ORDER=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TOOLCHAIN_HAS_ZICBOM=y
+CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y
+CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
+# CONFIG_TOUCHSCREEN_TINKER_FT5406 is not set
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TTY_PRINTK=y
+CONFIG_TTY_PRINTK_LEVEL=6
+CONFIG_TUNE_GENERIC=y
+CONFIG_UCS2_STRING=y
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_CONFIGFS=y
+# CONFIG_USB_CONFIGFS_ACM is not set
+# CONFIG_USB_CONFIGFS_ECM is not set
+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
+# CONFIG_USB_CONFIGFS_EEM is not set
+CONFIG_USB_CONFIGFS_F_FS=y
+# CONFIG_USB_CONFIGFS_F_HID is not set
+# CONFIG_USB_CONFIGFS_F_LB_SS is not set
+# CONFIG_USB_CONFIGFS_F_MIDI is not set
+# CONFIG_USB_CONFIGFS_F_MIDI2 is not set
+# CONFIG_USB_CONFIGFS_F_PRINTER is not set
+# CONFIG_USB_CONFIGFS_F_UAC1 is not set
+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
+# CONFIG_USB_CONFIGFS_F_UAC2 is not set
+# CONFIG_USB_CONFIGFS_F_UVC is not set
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+# CONFIG_USB_CONFIGFS_NCM is not set
+# CONFIG_USB_CONFIGFS_OBEX is not set
+# CONFIG_USB_CONFIGFS_RNDIS is not set
+# CONFIG_USB_CONFIGFS_SERIAL is not set
+CONFIG_USB_F_FS=y
+CONFIG_USB_F_MASS_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_LIBCOMPOSITE=y
+CONFIG_USB_PCI=y
+CONFIG_USB_PHY=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USELIB=y
+CONFIG_USER_NS=y
+CONFIG_VFAT_FS=y
+# CONFIG_VIDEO_STF_VIN is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_VIRTIO_NET is not set
+CONFIG_VMAP_STACK=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_WERROR=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
diff --git a/target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch b/target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch
deleted file mode 100644
index 3e06d5a681..0000000000
--- a/target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch
+++ /dev/null
@@ -1,482 +0,0 @@
-From c960c73ee9fdaae51fcd8a14d44d576b1cf522b7 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:13 +0800
-Subject: [PATCH 001/122] dt-bindings: clock: Add StarFive JH7110 system clock
- and reset generator
-
-Add bindings for the system clock and reset generator (SYSCRG) on the
-JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../clock/starfive,jh7110-syscrg.yaml | 104 +++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 203 ++++++++++++++++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 142 ++++++++++++
- 3 files changed, 449 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
- create mode 100644 include/dt-bindings/clock/starfive,jh7110-crg.h
- create mode 100644 include/dt-bindings/reset/starfive,jh7110-crg.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
-@@ -0,0 +1,104 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-syscrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 System Clock and Reset Generator
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-syscrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ oneOf:
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC1 RMII reference or GMAC1 RGMII RX
-+ - description: External I2S TX bit clock
-+ - description: External I2S TX left/right channel clock
-+ - description: External I2S RX bit clock
-+ - description: External I2S RX left/right channel clock
-+ - description: External TDM clock
-+ - description: External audio master clock
-+
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC1 RMII reference
-+ - description: GMAC1 RGMII RX
-+ - description: External I2S TX bit clock
-+ - description: External I2S TX left/right channel clock
-+ - description: External I2S RX bit clock
-+ - description: External I2S RX left/right channel clock
-+ - description: External TDM clock
-+ - description: External audio master clock
-+
-+ clock-names:
-+ oneOf:
-+ - items:
-+ - const: osc
-+ - enum:
-+ - gmac1_rmii_refin
-+ - gmac1_rgmii_rxin
-+ - const: i2stx_bclk_ext
-+ - const: i2stx_lrck_ext
-+ - const: i2srx_bclk_ext
-+ - const: i2srx_lrck_ext
-+ - const: tdm_ext
-+ - const: mclk_ext
-+
-+ - items:
-+ - const: osc
-+ - const: gmac1_rmii_refin
-+ - const: gmac1_rgmii_rxin
-+ - const: i2stx_bclk_ext
-+ - const: i2stx_lrck_ext
-+ - const: i2srx_bclk_ext
-+ - const: i2srx_lrck_ext
-+ - const: tdm_ext
-+ - const: mclk_ext
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ clock-controller@13020000 {
-+ compatible = "starfive,jh7110-syscrg";
-+ reg = <0x13020000 0x10000>;
-+ clocks = <&osc>, <&gmac1_rmii_refin>,
-+ <&gmac1_rgmii_rxin>,
-+ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
-+ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-+ <&tdm_ext>, <&mclk_ext>;
-+ clock-names = "osc", "gmac1_rmii_refin",
-+ "gmac1_rgmii_rxin",
-+ "i2stx_bclk_ext", "i2stx_lrck_ext",
-+ "i2srx_bclk_ext", "i2srx_lrck_ext",
-+ "tdm_ext", "mclk_ext";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
---- /dev/null
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -0,0 +1,203 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-+
-+/* SYSCRG clocks */
-+#define JH7110_SYSCLK_CPU_ROOT 0
-+#define JH7110_SYSCLK_CPU_CORE 1
-+#define JH7110_SYSCLK_CPU_BUS 2
-+#define JH7110_SYSCLK_GPU_ROOT 3
-+#define JH7110_SYSCLK_PERH_ROOT 4
-+#define JH7110_SYSCLK_BUS_ROOT 5
-+#define JH7110_SYSCLK_NOCSTG_BUS 6
-+#define JH7110_SYSCLK_AXI_CFG0 7
-+#define JH7110_SYSCLK_STG_AXIAHB 8
-+#define JH7110_SYSCLK_AHB0 9
-+#define JH7110_SYSCLK_AHB1 10
-+#define JH7110_SYSCLK_APB_BUS 11
-+#define JH7110_SYSCLK_APB0 12
-+#define JH7110_SYSCLK_PLL0_DIV2 13
-+#define JH7110_SYSCLK_PLL1_DIV2 14
-+#define JH7110_SYSCLK_PLL2_DIV2 15
-+#define JH7110_SYSCLK_AUDIO_ROOT 16
-+#define JH7110_SYSCLK_MCLK_INNER 17
-+#define JH7110_SYSCLK_MCLK 18
-+#define JH7110_SYSCLK_MCLK_OUT 19
-+#define JH7110_SYSCLK_ISP_2X 20
-+#define JH7110_SYSCLK_ISP_AXI 21
-+#define JH7110_SYSCLK_GCLK0 22
-+#define JH7110_SYSCLK_GCLK1 23
-+#define JH7110_SYSCLK_GCLK2 24
-+#define JH7110_SYSCLK_CORE 25
-+#define JH7110_SYSCLK_CORE1 26
-+#define JH7110_SYSCLK_CORE2 27
-+#define JH7110_SYSCLK_CORE3 28
-+#define JH7110_SYSCLK_CORE4 29
-+#define JH7110_SYSCLK_DEBUG 30
-+#define JH7110_SYSCLK_RTC_TOGGLE 31
-+#define JH7110_SYSCLK_TRACE0 32
-+#define JH7110_SYSCLK_TRACE1 33
-+#define JH7110_SYSCLK_TRACE2 34
-+#define JH7110_SYSCLK_TRACE3 35
-+#define JH7110_SYSCLK_TRACE4 36
-+#define JH7110_SYSCLK_TRACE_COM 37
-+#define JH7110_SYSCLK_NOC_BUS_CPU_AXI 38
-+#define JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI 39
-+#define JH7110_SYSCLK_OSC_DIV2 40
-+#define JH7110_SYSCLK_PLL1_DIV4 41
-+#define JH7110_SYSCLK_PLL1_DIV8 42
-+#define JH7110_SYSCLK_DDR_BUS 43
-+#define JH7110_SYSCLK_DDR_AXI 44
-+#define JH7110_SYSCLK_GPU_CORE 45
-+#define JH7110_SYSCLK_GPU_CORE_CLK 46
-+#define JH7110_SYSCLK_GPU_SYS_CLK 47
-+#define JH7110_SYSCLK_GPU_APB 48
-+#define JH7110_SYSCLK_GPU_RTC_TOGGLE 49
-+#define JH7110_SYSCLK_NOC_BUS_GPU_AXI 50
-+#define JH7110_SYSCLK_ISP_TOP_CORE 51
-+#define JH7110_SYSCLK_ISP_TOP_AXI 52
-+#define JH7110_SYSCLK_NOC_BUS_ISP_AXI 53
-+#define JH7110_SYSCLK_HIFI4_CORE 54
-+#define JH7110_SYSCLK_HIFI4_AXI 55
-+#define JH7110_SYSCLK_AXI_CFG1_MAIN 56
-+#define JH7110_SYSCLK_AXI_CFG1_AHB 57
-+#define JH7110_SYSCLK_VOUT_SRC 58
-+#define JH7110_SYSCLK_VOUT_AXI 59
-+#define JH7110_SYSCLK_NOC_BUS_DISP_AXI 60
-+#define JH7110_SYSCLK_VOUT_TOP_AHB 61
-+#define JH7110_SYSCLK_VOUT_TOP_AXI 62
-+#define JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK 63
-+#define JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF 64
-+#define JH7110_SYSCLK_JPEGC_AXI 65
-+#define JH7110_SYSCLK_CODAJ12_AXI 66
-+#define JH7110_SYSCLK_CODAJ12_CORE 67
-+#define JH7110_SYSCLK_CODAJ12_APB 68
-+#define JH7110_SYSCLK_VDEC_AXI 69
-+#define JH7110_SYSCLK_WAVE511_AXI 70
-+#define JH7110_SYSCLK_WAVE511_BPU 71
-+#define JH7110_SYSCLK_WAVE511_VCE 72
-+#define JH7110_SYSCLK_WAVE511_APB 73
-+#define JH7110_SYSCLK_VDEC_JPG 74
-+#define JH7110_SYSCLK_VDEC_MAIN 75
-+#define JH7110_SYSCLK_NOC_BUS_VDEC_AXI 76
-+#define JH7110_SYSCLK_VENC_AXI 77
-+#define JH7110_SYSCLK_WAVE420L_AXI 78
-+#define JH7110_SYSCLK_WAVE420L_BPU 79
-+#define JH7110_SYSCLK_WAVE420L_VCE 80
-+#define JH7110_SYSCLK_WAVE420L_APB 81
-+#define JH7110_SYSCLK_NOC_BUS_VENC_AXI 82
-+#define JH7110_SYSCLK_AXI_CFG0_MAIN_DIV 83
-+#define JH7110_SYSCLK_AXI_CFG0_MAIN 84
-+#define JH7110_SYSCLK_AXI_CFG0_HIFI4 85
-+#define JH7110_SYSCLK_AXIMEM2_AXI 86
-+#define JH7110_SYSCLK_QSPI_AHB 87
-+#define JH7110_SYSCLK_QSPI_APB 88
-+#define JH7110_SYSCLK_QSPI_REF_SRC 89
-+#define JH7110_SYSCLK_QSPI_REF 90
-+#define JH7110_SYSCLK_SDIO0_AHB 91
-+#define JH7110_SYSCLK_SDIO1_AHB 92
-+#define JH7110_SYSCLK_SDIO0_SDCARD 93
-+#define JH7110_SYSCLK_SDIO1_SDCARD 94
-+#define JH7110_SYSCLK_USB_125M 95
-+#define JH7110_SYSCLK_NOC_BUS_STG_AXI 96
-+#define JH7110_SYSCLK_GMAC1_AHB 97
-+#define JH7110_SYSCLK_GMAC1_AXI 98
-+#define JH7110_SYSCLK_GMAC_SRC 99
-+#define JH7110_SYSCLK_GMAC1_GTXCLK 100
-+#define JH7110_SYSCLK_GMAC1_RMII_RTX 101
-+#define JH7110_SYSCLK_GMAC1_PTP 102
-+#define JH7110_SYSCLK_GMAC1_RX 103
-+#define JH7110_SYSCLK_GMAC1_RX_INV 104
-+#define JH7110_SYSCLK_GMAC1_TX 105
-+#define JH7110_SYSCLK_GMAC1_TX_INV 106
-+#define JH7110_SYSCLK_GMAC1_GTXC 107
-+#define JH7110_SYSCLK_GMAC0_GTXCLK 108
-+#define JH7110_SYSCLK_GMAC0_PTP 109
-+#define JH7110_SYSCLK_GMAC_PHY 110
-+#define JH7110_SYSCLK_GMAC0_GTXC 111
-+#define JH7110_SYSCLK_IOMUX_APB 112
-+#define JH7110_SYSCLK_MAILBOX_APB 113
-+#define JH7110_SYSCLK_INT_CTRL_APB 114
-+#define JH7110_SYSCLK_CAN0_APB 115
-+#define JH7110_SYSCLK_CAN0_TIMER 116
-+#define JH7110_SYSCLK_CAN0_CAN 117
-+#define JH7110_SYSCLK_CAN1_APB 118
-+#define JH7110_SYSCLK_CAN1_TIMER 119
-+#define JH7110_SYSCLK_CAN1_CAN 120
-+#define JH7110_SYSCLK_PWM_APB 121
-+#define JH7110_SYSCLK_WDT_APB 122
-+#define JH7110_SYSCLK_WDT_CORE 123
-+#define JH7110_SYSCLK_TIMER_APB 124
-+#define JH7110_SYSCLK_TIMER0 125
-+#define JH7110_SYSCLK_TIMER1 126
-+#define JH7110_SYSCLK_TIMER2 127
-+#define JH7110_SYSCLK_TIMER3 128
-+#define JH7110_SYSCLK_TEMP_APB 129
-+#define JH7110_SYSCLK_TEMP_CORE 130
-+#define JH7110_SYSCLK_SPI0_APB 131
-+#define JH7110_SYSCLK_SPI1_APB 132
-+#define JH7110_SYSCLK_SPI2_APB 133
-+#define JH7110_SYSCLK_SPI3_APB 134
-+#define JH7110_SYSCLK_SPI4_APB 135
-+#define JH7110_SYSCLK_SPI5_APB 136
-+#define JH7110_SYSCLK_SPI6_APB 137
-+#define JH7110_SYSCLK_I2C0_APB 138
-+#define JH7110_SYSCLK_I2C1_APB 139
-+#define JH7110_SYSCLK_I2C2_APB 140
-+#define JH7110_SYSCLK_I2C3_APB 141
-+#define JH7110_SYSCLK_I2C4_APB 142
-+#define JH7110_SYSCLK_I2C5_APB 143
-+#define JH7110_SYSCLK_I2C6_APB 144
-+#define JH7110_SYSCLK_UART0_APB 145
-+#define JH7110_SYSCLK_UART0_CORE 146
-+#define JH7110_SYSCLK_UART1_APB 147
-+#define JH7110_SYSCLK_UART1_CORE 148
-+#define JH7110_SYSCLK_UART2_APB 149
-+#define JH7110_SYSCLK_UART2_CORE 150
-+#define JH7110_SYSCLK_UART3_APB 151
-+#define JH7110_SYSCLK_UART3_CORE 152
-+#define JH7110_SYSCLK_UART4_APB 153
-+#define JH7110_SYSCLK_UART4_CORE 154
-+#define JH7110_SYSCLK_UART5_APB 155
-+#define JH7110_SYSCLK_UART5_CORE 156
-+#define JH7110_SYSCLK_PWMDAC_APB 157
-+#define JH7110_SYSCLK_PWMDAC_CORE 158
-+#define JH7110_SYSCLK_SPDIF_APB 159
-+#define JH7110_SYSCLK_SPDIF_CORE 160
-+#define JH7110_SYSCLK_I2STX0_APB 161
-+#define JH7110_SYSCLK_I2STX0_BCLK_MST 162
-+#define JH7110_SYSCLK_I2STX0_BCLK_MST_INV 163
-+#define JH7110_SYSCLK_I2STX0_LRCK_MST 164
-+#define JH7110_SYSCLK_I2STX0_BCLK 165
-+#define JH7110_SYSCLK_I2STX0_BCLK_INV 166
-+#define JH7110_SYSCLK_I2STX0_LRCK 167
-+#define JH7110_SYSCLK_I2STX1_APB 168
-+#define JH7110_SYSCLK_I2STX1_BCLK_MST 169
-+#define JH7110_SYSCLK_I2STX1_BCLK_MST_INV 170
-+#define JH7110_SYSCLK_I2STX1_LRCK_MST 171
-+#define JH7110_SYSCLK_I2STX1_BCLK 172
-+#define JH7110_SYSCLK_I2STX1_BCLK_INV 173
-+#define JH7110_SYSCLK_I2STX1_LRCK 174
-+#define JH7110_SYSCLK_I2SRX_APB 175
-+#define JH7110_SYSCLK_I2SRX_BCLK_MST 176
-+#define JH7110_SYSCLK_I2SRX_BCLK_MST_INV 177
-+#define JH7110_SYSCLK_I2SRX_LRCK_MST 178
-+#define JH7110_SYSCLK_I2SRX_BCLK 179
-+#define JH7110_SYSCLK_I2SRX_BCLK_INV 180
-+#define JH7110_SYSCLK_I2SRX_LRCK 181
-+#define JH7110_SYSCLK_PDM_DMIC 182
-+#define JH7110_SYSCLK_PDM_APB 183
-+#define JH7110_SYSCLK_TDM_AHB 184
-+#define JH7110_SYSCLK_TDM_APB 185
-+#define JH7110_SYSCLK_TDM_INTERNAL 186
-+#define JH7110_SYSCLK_TDM_TDM 187
-+#define JH7110_SYSCLK_TDM_TDM_INV 188
-+#define JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG 189
-+
-+#define JH7110_SYSCLK_END 190
-+
-+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- /dev/null
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -0,0 +1,142 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
-+#define __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
-+
-+/* SYSCRG resets */
-+#define JH7110_SYSRST_JTAG_APB 0
-+#define JH7110_SYSRST_SYSCON_APB 1
-+#define JH7110_SYSRST_IOMUX_APB 2
-+#define JH7110_SYSRST_BUS 3
-+#define JH7110_SYSRST_DEBUG 4
-+#define JH7110_SYSRST_CORE0 5
-+#define JH7110_SYSRST_CORE1 6
-+#define JH7110_SYSRST_CORE2 7
-+#define JH7110_SYSRST_CORE3 8
-+#define JH7110_SYSRST_CORE4 9
-+#define JH7110_SYSRST_CORE0_ST 10
-+#define JH7110_SYSRST_CORE1_ST 11
-+#define JH7110_SYSRST_CORE2_ST 12
-+#define JH7110_SYSRST_CORE3_ST 13
-+#define JH7110_SYSRST_CORE4_ST 14
-+#define JH7110_SYSRST_TRACE0 15
-+#define JH7110_SYSRST_TRACE1 16
-+#define JH7110_SYSRST_TRACE2 17
-+#define JH7110_SYSRST_TRACE3 18
-+#define JH7110_SYSRST_TRACE4 19
-+#define JH7110_SYSRST_TRACE_COM 20
-+#define JH7110_SYSRST_GPU_APB 21
-+#define JH7110_SYSRST_GPU_DOMA 22
-+#define JH7110_SYSRST_NOC_BUS_APB 23
-+#define JH7110_SYSRST_NOC_BUS_AXICFG0_AXI 24
-+#define JH7110_SYSRST_NOC_BUS_CPU_AXI 25
-+#define JH7110_SYSRST_NOC_BUS_DISP_AXI 26
-+#define JH7110_SYSRST_NOC_BUS_GPU_AXI 27
-+#define JH7110_SYSRST_NOC_BUS_ISP_AXI 28
-+#define JH7110_SYSRST_NOC_BUS_DDRC 29
-+#define JH7110_SYSRST_NOC_BUS_STG_AXI 30
-+#define JH7110_SYSRST_NOC_BUS_VDEC_AXI 31
-+
-+#define JH7110_SYSRST_NOC_BUS_VENC_AXI 32
-+#define JH7110_SYSRST_AXI_CFG1_AHB 33
-+#define JH7110_SYSRST_AXI_CFG1_MAIN 34
-+#define JH7110_SYSRST_AXI_CFG0_MAIN 35
-+#define JH7110_SYSRST_AXI_CFG0_MAIN_DIV 36
-+#define JH7110_SYSRST_AXI_CFG0_HIFI4 37
-+#define JH7110_SYSRST_DDR_AXI 38
-+#define JH7110_SYSRST_DDR_OSC 39
-+#define JH7110_SYSRST_DDR_APB 40
-+#define JH7110_SYSRST_ISP_TOP 41
-+#define JH7110_SYSRST_ISP_TOP_AXI 42
-+#define JH7110_SYSRST_VOUT_TOP_SRC 43
-+#define JH7110_SYSRST_CODAJ12_AXI 44
-+#define JH7110_SYSRST_CODAJ12_CORE 45
-+#define JH7110_SYSRST_CODAJ12_APB 46
-+#define JH7110_SYSRST_WAVE511_AXI 47
-+#define JH7110_SYSRST_WAVE511_BPU 48
-+#define JH7110_SYSRST_WAVE511_VCE 49
-+#define JH7110_SYSRST_WAVE511_APB 50
-+#define JH7110_SYSRST_VDEC_JPG 51
-+#define JH7110_SYSRST_VDEC_MAIN 52
-+#define JH7110_SYSRST_AXIMEM0_AXI 53
-+#define JH7110_SYSRST_WAVE420L_AXI 54
-+#define JH7110_SYSRST_WAVE420L_BPU 55
-+#define JH7110_SYSRST_WAVE420L_VCE 56
-+#define JH7110_SYSRST_WAVE420L_APB 57
-+#define JH7110_SYSRST_AXIMEM1_AXI 58
-+#define JH7110_SYSRST_AXIMEM2_AXI 59
-+#define JH7110_SYSRST_INTMEM 60
-+#define JH7110_SYSRST_QSPI_AHB 61
-+#define JH7110_SYSRST_QSPI_APB 62
-+#define JH7110_SYSRST_QSPI_REF 63
-+
-+#define JH7110_SYSRST_SDIO0_AHB 64
-+#define JH7110_SYSRST_SDIO1_AHB 65
-+#define JH7110_SYSRST_GMAC1_AXI 66
-+#define JH7110_SYSRST_GMAC1_AHB 67
-+#define JH7110_SYSRST_MAILBOX_APB 68
-+#define JH7110_SYSRST_SPI0_APB 69
-+#define JH7110_SYSRST_SPI1_APB 70
-+#define JH7110_SYSRST_SPI2_APB 71
-+#define JH7110_SYSRST_SPI3_APB 72
-+#define JH7110_SYSRST_SPI4_APB 73
-+#define JH7110_SYSRST_SPI5_APB 74
-+#define JH7110_SYSRST_SPI6_APB 75
-+#define JH7110_SYSRST_I2C0_APB 76
-+#define JH7110_SYSRST_I2C1_APB 77
-+#define JH7110_SYSRST_I2C2_APB 78
-+#define JH7110_SYSRST_I2C3_APB 79
-+#define JH7110_SYSRST_I2C4_APB 80
-+#define JH7110_SYSRST_I2C5_APB 81
-+#define JH7110_SYSRST_I2C6_APB 82
-+#define JH7110_SYSRST_UART0_APB 83
-+#define JH7110_SYSRST_UART0_CORE 84
-+#define JH7110_SYSRST_UART1_APB 85
-+#define JH7110_SYSRST_UART1_CORE 86
-+#define JH7110_SYSRST_UART2_APB 87
-+#define JH7110_SYSRST_UART2_CORE 88
-+#define JH7110_SYSRST_UART3_APB 89
-+#define JH7110_SYSRST_UART3_CORE 90
-+#define JH7110_SYSRST_UART4_APB 91
-+#define JH7110_SYSRST_UART4_CORE 92
-+#define JH7110_SYSRST_UART5_APB 93
-+#define JH7110_SYSRST_UART5_CORE 94
-+#define JH7110_SYSRST_SPDIF_APB 95
-+
-+#define JH7110_SYSRST_PWMDAC_APB 96
-+#define JH7110_SYSRST_PDM_DMIC 97
-+#define JH7110_SYSRST_PDM_APB 98
-+#define JH7110_SYSRST_I2SRX_APB 99
-+#define JH7110_SYSRST_I2SRX_BCLK 100
-+#define JH7110_SYSRST_I2STX0_APB 101
-+#define JH7110_SYSRST_I2STX0_BCLK 102
-+#define JH7110_SYSRST_I2STX1_APB 103
-+#define JH7110_SYSRST_I2STX1_BCLK 104
-+#define JH7110_SYSRST_TDM_AHB 105
-+#define JH7110_SYSRST_TDM_CORE 106
-+#define JH7110_SYSRST_TDM_APB 107
-+#define JH7110_SYSRST_PWM_APB 108
-+#define JH7110_SYSRST_WDT_APB 109
-+#define JH7110_SYSRST_WDT_CORE 110
-+#define JH7110_SYSRST_CAN0_APB 111
-+#define JH7110_SYSRST_CAN0_CORE 112
-+#define JH7110_SYSRST_CAN0_TIMER 113
-+#define JH7110_SYSRST_CAN1_APB 114
-+#define JH7110_SYSRST_CAN1_CORE 115
-+#define JH7110_SYSRST_CAN1_TIMER 116
-+#define JH7110_SYSRST_TIMER_APB 117
-+#define JH7110_SYSRST_TIMER0 118
-+#define JH7110_SYSRST_TIMER1 119
-+#define JH7110_SYSRST_TIMER2 120
-+#define JH7110_SYSRST_TIMER3 121
-+#define JH7110_SYSRST_INT_CTRL_APB 122
-+#define JH7110_SYSRST_TEMP_APB 123
-+#define JH7110_SYSRST_TEMP_CORE 124
-+#define JH7110_SYSRST_JTAG_CERTIFICATION 125
-+
-+#define JH7110_SYSRST_END 126
-+
-+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch b/target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch
deleted file mode 100644
index 94cb575a71..0000000000
--- a/target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From cd833f484009f37be57a2aa09257af6e8c1b25b6 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:14 +0800
-Subject: [PATCH 002/122] dt-bindings: clock: Add StarFive JH7110 always-on
- clock and reset generator
-
-Add bindings for the always-on clock and reset generator (AONCRG) on the
-JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../clock/starfive,jh7110-aoncrg.yaml | 107 ++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 18 +++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 12 ++
- 3 files changed, 137 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
-@@ -0,0 +1,107 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-aoncrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Always-On Clock and Reset Generator
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-aoncrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ oneOf:
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC0 RMII reference or GMAC0 RGMII RX
-+ - description: STG AXI/AHB
-+ - description: APB Bus
-+ - description: GMAC0 GTX
-+
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC0 RMII reference or GMAC0 RGMII RX
-+ - description: STG AXI/AHB or GMAC0 RGMII RX
-+ - description: APB Bus or STG AXI/AHB
-+ - description: GMAC0 GTX or APB Bus
-+ - description: RTC Oscillator (32.768 kHz) or GMAC0 GTX
-+
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC0 RMII reference
-+ - description: GMAC0 RGMII RX
-+ - description: STG AXI/AHB
-+ - description: APB Bus
-+ - description: GMAC0 GTX
-+ - description: RTC Oscillator (32.768 kHz)
-+
-+ clock-names:
-+ oneOf:
-+ - minItems: 5
-+ items:
-+ - const: osc
-+ - enum:
-+ - gmac0_rmii_refin
-+ - gmac0_rgmii_rxin
-+ - const: stg_axiahb
-+ - const: apb_bus
-+ - const: gmac0_gtxclk
-+ - const: rtc_osc
-+
-+ - minItems: 6
-+ items:
-+ - const: osc
-+ - const: gmac0_rmii_refin
-+ - const: gmac0_rgmii_rxin
-+ - const: stg_axiahb
-+ - const: apb_bus
-+ - const: gmac0_gtxclk
-+ - const: rtc_osc
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+ clock-controller@17000000 {
-+ compatible = "starfive,jh7110-aoncrg";
-+ reg = <0x17000000 0x10000>;
-+ clocks = <&osc>, <&gmac0_rmii_refin>,
-+ <&gmac0_rgmii_rxin>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
-+ <&rtc_osc>;
-+ clock-names = "osc", "gmac0_rmii_refin",
-+ "gmac0_rgmii_rxin", "stg_axiahb",
-+ "apb_bus", "gmac0_gtxclk",
-+ "rtc_osc";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -200,4 +200,22 @@
-
- #define JH7110_SYSCLK_END 190
-
-+/* AONCRG clocks */
-+#define JH7110_AONCLK_OSC_DIV4 0
-+#define JH7110_AONCLK_APB_FUNC 1
-+#define JH7110_AONCLK_GMAC0_AHB 2
-+#define JH7110_AONCLK_GMAC0_AXI 3
-+#define JH7110_AONCLK_GMAC0_RMII_RTX 4
-+#define JH7110_AONCLK_GMAC0_TX 5
-+#define JH7110_AONCLK_GMAC0_TX_INV 6
-+#define JH7110_AONCLK_GMAC0_RX 7
-+#define JH7110_AONCLK_GMAC0_RX_INV 8
-+#define JH7110_AONCLK_OTPC_APB 9
-+#define JH7110_AONCLK_RTC_APB 10
-+#define JH7110_AONCLK_RTC_INTERNAL 11
-+#define JH7110_AONCLK_RTC_32K 12
-+#define JH7110_AONCLK_RTC_CAL 13
-+
-+#define JH7110_AONCLK_END 14
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -139,4 +139,16 @@
-
- #define JH7110_SYSRST_END 126
-
-+/* AONCRG resets */
-+#define JH7110_AONRST_GMAC0_AXI 0
-+#define JH7110_AONRST_GMAC0_AHB 1
-+#define JH7110_AONRST_IOMUX 2
-+#define JH7110_AONRST_PMU_APB 3
-+#define JH7110_AONRST_PMU_WKUP 4
-+#define JH7110_AONRST_RTC_APB 5
-+#define JH7110_AONRST_RTC_CAL 6
-+#define JH7110_AONRST_RTC_32K 7
-+
-+#define JH7110_AONRST_END 8
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch b/target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
deleted file mode 100644
index 1cedd313d9..0000000000
--- a/target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 124f322d1c42232e439ea9a356d68caf1d0656f3 Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:15 +0800
-Subject: [PATCH 003/122] clk: starfive: Replace SOC_STARFIVE with
- ARCH_STARFIVE
-
-Using ARCH_FOO symbol is preferred than SOC_FOO.
-Set obj-y for starfive/ in Makefile, so the StarFive drivers
-can be compiled with COMPILE_TEST=y but ARCH_STARFIVE=n.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/Makefile | 2 +-
- drivers/clk/starfive/Kconfig | 6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/clk/Makefile
-+++ b/drivers/clk/Makefile
-@@ -117,7 +117,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
- obj-y += sprd/
- obj-$(CONFIG_ARCH_STI) += st/
- obj-$(CONFIG_ARCH_STM32) += stm32/
--obj-$(CONFIG_SOC_STARFIVE) += starfive/
-+obj-y += starfive/
- obj-$(CONFIG_ARCH_SUNXI) += sunxi/
- obj-y += sunxi-ng/
- obj-$(CONFIG_ARCH_TEGRA) += tegra/
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -2,8 +2,8 @@
-
- config CLK_STARFIVE_JH7100
- bool "StarFive JH7100 clock support"
-- depends on SOC_STARFIVE || COMPILE_TEST
-- default SOC_STARFIVE
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
- help
- Say yes here to support the clock controller on the StarFive JH7100
- SoC.
-@@ -11,7 +11,7 @@ config CLK_STARFIVE_JH7100
- config CLK_STARFIVE_JH7100_AUDIO
- tristate "StarFive JH7100 audio clock support"
- depends on CLK_STARFIVE_JH7100
-- default m if SOC_STARFIVE
-+ default m if ARCH_STARFIVE
- help
- Say Y or M here to support the audio clocks on the StarFive JH7100
- SoC.
diff --git a/target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch b/target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch
deleted file mode 100644
index 72375bb0d9..0000000000
--- a/target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch
+++ /dev/null
@@ -1,749 +0,0 @@
-From 6f14eb919e5b92076e17aec5388655348963eef7 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:16 +0800
-Subject: [PATCH 004/122] clk: starfive: Factor out common JH7100 and JH7110
- code
-
-The clock control registers on the StarFive JH7100 and JH7110 work
-identically, so factor out the code then drivers for the two SoCs
-can share it without depending on each other. No functional change.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/Kconfig | 5 +
- drivers/clk/starfive/Makefile | 3 +-
- drivers/clk/starfive/clk-starfive-jh7100.c | 325 --------------------
- drivers/clk/starfive/clk-starfive-jh7100.h | 2 +
- drivers/clk/starfive/clk-starfive-jh71x0.c | 333 +++++++++++++++++++++
- 5 files changed, 342 insertions(+), 326 deletions(-)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh71x0.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -1,8 +1,12 @@
- # SPDX-License-Identifier: GPL-2.0
-
-+config CLK_STARFIVE_JH71X0
-+ bool
-+
- config CLK_STARFIVE_JH7100
- bool "StarFive JH7100 clock support"
- depends on ARCH_STARFIVE || COMPILE_TEST
-+ select CLK_STARFIVE_JH71X0
- default ARCH_STARFIVE
- help
- Say yes here to support the clock controller on the StarFive JH7100
-@@ -11,6 +15,7 @@ config CLK_STARFIVE_JH7100
- config CLK_STARFIVE_JH7100_AUDIO
- tristate "StarFive JH7100 audio clock support"
- depends on CLK_STARFIVE_JH7100
-+ select CLK_STARFIVE_JH71X0
- default m if ARCH_STARFIVE
- help
- Say Y or M here to support the audio clocks on the StarFive JH7100
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -1,4 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
--# StarFive Clock
-+obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk-starfive-jh71x0.o
-+
- obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -7,15 +7,10 @@
- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
- */
-
--#include <linux/bits.h>
- #include <linux/clk-provider.h>
--#include <linux/debugfs.h>
- #include <linux/device.h>
- #include <linux/init.h>
--#include <linux/io.h>
--#include <linux/kernel.h>
- #include <linux/mod_devicetable.h>
--#include <linux/module.h>
- #include <linux/platform_device.h>
-
- #include <dt-bindings/clock/starfive-jh7100.h>
-@@ -269,326 +264,6 @@ static const struct jh7100_clk_data jh71
- JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
- };
-
--static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
--{
-- return container_of(hw, struct jh7100_clk, hw);
--}
--
--static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
--{
-- return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
--}
--
--static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
--{
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-- void __iomem *reg = priv->base + 4 * clk->idx;
--
-- return readl_relaxed(reg);
--}
--
--static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
--{
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-- void __iomem *reg = priv->base + 4 * clk->idx;
-- unsigned long flags;
--
-- spin_lock_irqsave(&priv->rmw_lock, flags);
-- value |= readl_relaxed(reg) & ~mask;
-- writel_relaxed(value, reg);
-- spin_unlock_irqrestore(&priv->rmw_lock, flags);
--}
--
--static int jh7100_clk_enable(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
-- return 0;
--}
--
--static void jh7100_clk_disable(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
--}
--
--static int jh7100_clk_is_enabled(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
--
-- return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
--}
--
--static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
--
-- return div ? parent_rate / div : 0;
--}
--
--static int jh7100_clk_determine_rate(struct clk_hw *hw,
-- struct clk_rate_request *req)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- unsigned long parent = req->best_parent_rate;
-- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-- unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
-- unsigned long result = parent / div;
--
-- /*
-- * we want the result clamped by min_rate and max_rate if possible:
-- * case 1: div hits the max divider value, which means it's less than
-- * parent / rate, so the result is greater than rate and min_rate in
-- * particular. we can't do anything about result > max_rate because the
-- * divider doesn't go any further.
-- * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
-- * always lower or equal to rate and max_rate. however the result may
-- * turn out lower than min_rate, but then the next higher rate is fine:
-- * div - 1 = ceil(parent / rate) - 1 < parent / rate
-- * and thus
-- * min_rate <= rate < parent / (div - 1)
-- */
-- if (result < req->min_rate && div > 1)
-- result = parent / (div - 1);
--
-- req->rate = result;
-- return 0;
--}
--
--static int jh7100_clk_set_rate(struct clk_hw *hw,
-- unsigned long rate,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
-- 1UL, (unsigned long)clk->max_div);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
-- return 0;
--}
--
--static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 reg = jh7100_clk_reg_get(clk);
-- unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
-- ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
--
-- return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
--}
--
--static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
-- struct clk_rate_request *req)
--{
-- unsigned long parent100 = 100 * req->best_parent_rate;
-- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-- unsigned long result = parent100 / div100;
--
-- /* clamp the result as in jh7100_clk_determine_rate() above */
-- if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
-- result = parent100 / (div100 + 1);
-- if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
-- result = parent100 / (div100 - 1);
--
-- req->rate = result;
-- return 0;
--}
--
--static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
-- unsigned long rate,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-- u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
-- return 0;
--}
--
--static u8 jh7100_clk_get_parent(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
--
-- return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
--}
--
--static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
-- return 0;
--}
--
--static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
-- struct clk_rate_request *req)
--{
-- return clk_mux_determine_rate_flags(hw, req, 0);
--}
--
--static int jh7100_clk_get_phase(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
--
-- return (value & JH7100_CLK_INVERT) ? 180 : 0;
--}
--
--static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value;
--
-- if (degrees == 0)
-- value = 0;
-- else if (degrees == 180)
-- value = JH7100_CLK_INVERT;
-- else
-- return -EINVAL;
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
-- return 0;
--}
--
--#ifdef CONFIG_DEBUG_FS
--static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
--{
-- static const struct debugfs_reg32 jh7100_clk_reg = {
-- .name = "CTRL",
-- .offset = 0,
-- };
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-- struct debugfs_regset32 *regset;
--
-- regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
-- if (!regset)
-- return;
--
-- regset->regs = &jh7100_clk_reg;
-- regset->nregs = 1;
-- regset->base = priv->base + 4 * clk->idx;
--
-- debugfs_create_regset32("registers", 0400, dentry, regset);
--}
--#else
--#define jh7100_clk_debug_init NULL
--#endif
--
--static const struct clk_ops jh7100_clk_gate_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_div_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_fdiv_ops = {
-- .recalc_rate = jh7100_clk_frac_recalc_rate,
-- .determine_rate = jh7100_clk_frac_determine_rate,
-- .set_rate = jh7100_clk_frac_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_gdiv_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_mux_ops = {
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_gmux_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_mdiv_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_gmd_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_inv_ops = {
-- .get_phase = jh7100_clk_get_phase,
-- .set_phase = jh7100_clk_set_phase,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
--{
-- if (max & JH7100_CLK_DIV_MASK) {
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmd_ops;
-- return &jh7100_clk_mdiv_ops;
-- }
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gdiv_ops;
-- if (max == JH7100_CLK_FRAC_MAX)
-- return &jh7100_clk_fdiv_ops;
-- return &jh7100_clk_div_ops;
-- }
--
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmux_ops;
-- return &jh7100_clk_mux_ops;
-- }
--
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gate_ops;
--
-- return &jh7100_clk_inv_ops;
--}
--EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
--
- static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
- {
- struct jh7100_clk_priv *priv = data;
---- a/drivers/clk/starfive/clk-starfive-jh7100.h
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.h
-@@ -4,6 +4,8 @@
-
- #include <linux/bits.h>
- #include <linux/clk-provider.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-
- /* register fields */
- #define JH7100_CLK_ENABLE BIT(31)
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
-@@ -0,0 +1,333 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7100 Clock Generator Driver
-+ *
-+ * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/debugfs.h>
-+#include <linux/device.h>
-+#include <linux/io.h>
-+
-+#include "clk-starfive-jh7100.h"
-+
-+static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct jh7100_clk, hw);
-+}
-+
-+static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
-+{
-+ return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
-+}
-+
-+static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
-+{
-+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ void __iomem *reg = priv->base + 4 * clk->idx;
-+
-+ return readl_relaxed(reg);
-+}
-+
-+static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
-+{
-+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ void __iomem *reg = priv->base + 4 * clk->idx;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&priv->rmw_lock, flags);
-+ value |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(value, reg);
-+ spin_unlock_irqrestore(&priv->rmw_lock, flags);
-+}
-+
-+static int jh7100_clk_enable(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
-+ return 0;
-+}
-+
-+static void jh7100_clk_disable(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
-+}
-+
-+static int jh7100_clk_is_enabled(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+
-+ return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
-+}
-+
-+static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
-+
-+ return div ? parent_rate / div : 0;
-+}
-+
-+static int jh7100_clk_determine_rate(struct clk_hw *hw,
-+ struct clk_rate_request *req)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ unsigned long parent = req->best_parent_rate;
-+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-+ unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
-+ unsigned long result = parent / div;
-+
-+ /*
-+ * we want the result clamped by min_rate and max_rate if possible:
-+ * case 1: div hits the max divider value, which means it's less than
-+ * parent / rate, so the result is greater than rate and min_rate in
-+ * particular. we can't do anything about result > max_rate because the
-+ * divider doesn't go any further.
-+ * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
-+ * always lower or equal to rate and max_rate. however the result may
-+ * turn out lower than min_rate, but then the next higher rate is fine:
-+ * div - 1 = ceil(parent / rate) - 1 < parent / rate
-+ * and thus
-+ * min_rate <= rate < parent / (div - 1)
-+ */
-+ if (result < req->min_rate && div > 1)
-+ result = parent / (div - 1);
-+
-+ req->rate = result;
-+ return 0;
-+}
-+
-+static int jh7100_clk_set_rate(struct clk_hw *hw,
-+ unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
-+ 1UL, (unsigned long)clk->max_div);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
-+ return 0;
-+}
-+
-+static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 reg = jh7100_clk_reg_get(clk);
-+ unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
-+ ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
-+
-+ return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
-+}
-+
-+static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
-+ struct clk_rate_request *req)
-+{
-+ unsigned long parent100 = 100 * req->best_parent_rate;
-+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
-+ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-+ unsigned long result = parent100 / div100;
-+
-+ /* clamp the result as in jh7100_clk_determine_rate() above */
-+ if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
-+ result = parent100 / (div100 + 1);
-+ if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
-+ result = parent100 / (div100 - 1);
-+
-+ req->rate = result;
-+ return 0;
-+}
-+
-+static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
-+ unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
-+ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-+ u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
-+ return 0;
-+}
-+
-+static u8 jh7100_clk_get_parent(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value = jh7100_clk_reg_get(clk);
-+
-+ return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
-+}
-+
-+static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
-+ return 0;
-+}
-+
-+static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
-+ struct clk_rate_request *req)
-+{
-+ return clk_mux_determine_rate_flags(hw, req, 0);
-+}
-+
-+static int jh7100_clk_get_phase(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value = jh7100_clk_reg_get(clk);
-+
-+ return (value & JH7100_CLK_INVERT) ? 180 : 0;
-+}
-+
-+static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value;
-+
-+ if (degrees == 0)
-+ value = 0;
-+ else if (degrees == 180)
-+ value = JH7100_CLK_INVERT;
-+ else
-+ return -EINVAL;
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
-+ return 0;
-+}
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
-+{
-+ static const struct debugfs_reg32 jh7100_clk_reg = {
-+ .name = "CTRL",
-+ .offset = 0,
-+ };
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct debugfs_regset32 *regset;
-+
-+ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
-+ if (!regset)
-+ return;
-+
-+ regset->regs = &jh7100_clk_reg;
-+ regset->nregs = 1;
-+ regset->base = priv->base + 4 * clk->idx;
-+
-+ debugfs_create_regset32("registers", 0400, dentry, regset);
-+}
-+#else
-+#define jh7100_clk_debug_init NULL
-+#endif
-+
-+static const struct clk_ops jh7100_clk_gate_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_div_ops = {
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_fdiv_ops = {
-+ .recalc_rate = jh7100_clk_frac_recalc_rate,
-+ .determine_rate = jh7100_clk_frac_determine_rate,
-+ .set_rate = jh7100_clk_frac_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_gdiv_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_mux_ops = {
-+ .determine_rate = jh7100_clk_mux_determine_rate,
-+ .set_parent = jh7100_clk_set_parent,
-+ .get_parent = jh7100_clk_get_parent,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_gmux_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .determine_rate = jh7100_clk_mux_determine_rate,
-+ .set_parent = jh7100_clk_set_parent,
-+ .get_parent = jh7100_clk_get_parent,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_mdiv_ops = {
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .get_parent = jh7100_clk_get_parent,
-+ .set_parent = jh7100_clk_set_parent,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_gmd_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .get_parent = jh7100_clk_get_parent,
-+ .set_parent = jh7100_clk_set_parent,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_inv_ops = {
-+ .get_phase = jh7100_clk_get_phase,
-+ .set_phase = jh7100_clk_set_phase,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
-+{
-+ if (max & JH7100_CLK_DIV_MASK) {
-+ if (max & JH7100_CLK_MUX_MASK) {
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gmd_ops;
-+ return &jh7100_clk_mdiv_ops;
-+ }
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gdiv_ops;
-+ if (max == JH7100_CLK_FRAC_MAX)
-+ return &jh7100_clk_fdiv_ops;
-+ return &jh7100_clk_div_ops;
-+ }
-+
-+ if (max & JH7100_CLK_MUX_MASK) {
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gmux_ops;
-+ return &jh7100_clk_mux_ops;
-+ }
-+
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gate_ops;
-+
-+ return &jh7100_clk_inv_ops;
-+}
-+EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
diff --git a/target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch b/target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch
deleted file mode 100644
index e9d0e7a71f..0000000000
--- a/target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch
+++ /dev/null
@@ -1,290 +0,0 @@
-From 8daa4c812f3b32a4d56ab48945e552a137fca9b7 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:17 +0800
-Subject: [PATCH 005/122] clk: starfive: Rename clk-starfive-jh7100.h to
- clk-starfive-jh71x0.h
-
-Rename clk-starfive-jh7100.h to clk-starfive-jh71x0.h for making
-the code to be common.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
- drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
- drivers/clk/starfive/clk-starfive-jh71x0.c | 2 +-
- .../starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} | 0
- 4 files changed, 3 insertions(+), 3 deletions(-)
- rename drivers/clk/starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} (100%)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-@@ -16,7 +16,7 @@
-
- #include <dt-bindings/clock/starfive-jh7100-audio.h>
-
--#include "clk-starfive-jh7100.h"
-+#include "clk-starfive-jh71x0.h"
-
- /* external clocks */
- #define JH7100_AUDCLK_AUDIO_SRC (JH7100_AUDCLK_END + 0)
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -15,7 +15,7 @@
-
- #include <dt-bindings/clock/starfive-jh7100.h>
-
--#include "clk-starfive-jh7100.h"
-+#include "clk-starfive-jh71x0.h"
-
- /* external clocks */
- #define JH7100_CLK_OSC_SYS (JH7100_CLK_END + 0)
---- a/drivers/clk/starfive/clk-starfive-jh71x0.c
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
-@@ -10,7 +10,7 @@
- #include <linux/device.h>
- #include <linux/io.h>
-
--#include "clk-starfive-jh7100.h"
-+#include "clk-starfive-jh71x0.h"
-
- static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
- {
---- a/drivers/clk/starfive/clk-starfive-jh7100.h
-+++ /dev/null
-@@ -1,114 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 */
--#ifndef __CLK_STARFIVE_JH7100_H
--#define __CLK_STARFIVE_JH7100_H
--
--#include <linux/bits.h>
--#include <linux/clk-provider.h>
--#include <linux/device.h>
--#include <linux/spinlock.h>
--
--/* register fields */
--#define JH7100_CLK_ENABLE BIT(31)
--#define JH7100_CLK_INVERT BIT(30)
--#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
--#define JH7100_CLK_MUX_SHIFT 24
--#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
--#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
--#define JH7100_CLK_FRAC_SHIFT 8
--#define JH7100_CLK_INT_MASK GENMASK(7, 0)
--
--/* fractional divider min/max */
--#define JH7100_CLK_FRAC_MIN 100UL
--#define JH7100_CLK_FRAC_MAX 25599UL
--
--/* clock data */
--struct jh7100_clk_data {
-- const char *name;
-- unsigned long flags;
-- u32 max;
-- u8 parents[4];
--};
--
--#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = CLK_SET_RATE_PARENT | (_flags), \
-- .max = JH7100_CLK_ENABLE, \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = _max, \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | (_max), \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = JH7100_CLK_FRAC_MAX, \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = CLK_SET_RATE_PARENT, \
-- .max = JH7100_CLK_INVERT, \
-- .parents = { [0] = _parent }, \
--}
--
--struct jh7100_clk {
-- struct clk_hw hw;
-- unsigned int idx;
-- unsigned int max_div;
--};
--
--struct jh7100_clk_priv {
-- /* protect clk enable and set rate/parent from happening at the same time */
-- spinlock_t rmw_lock;
-- struct device *dev;
-- void __iomem *base;
-- struct clk_hw *pll[3];
-- struct jh7100_clk reg[];
--};
--
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
--
--#endif
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
-@@ -0,0 +1,114 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __CLK_STARFIVE_JH7100_H
-+#define __CLK_STARFIVE_JH7100_H
-+
-+#include <linux/bits.h>
-+#include <linux/clk-provider.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-+
-+/* register fields */
-+#define JH7100_CLK_ENABLE BIT(31)
-+#define JH7100_CLK_INVERT BIT(30)
-+#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
-+#define JH7100_CLK_MUX_SHIFT 24
-+#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
-+#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
-+#define JH7100_CLK_FRAC_SHIFT 8
-+#define JH7100_CLK_INT_MASK GENMASK(7, 0)
-+
-+/* fractional divider min/max */
-+#define JH7100_CLK_FRAC_MIN 100UL
-+#define JH7100_CLK_FRAC_MAX 25599UL
-+
-+/* clock data */
-+struct jh7100_clk_data {
-+ const char *name;
-+ unsigned long flags;
-+ u32 max;
-+ u8 parents[4];
-+};
-+
-+#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = CLK_SET_RATE_PARENT | (_flags), \
-+ .max = JH7100_CLK_ENABLE, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = _max, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = _flags, \
-+ .max = JH7100_CLK_ENABLE | (_max), \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = JH7100_CLK_FRAC_MAX, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = _flags, \
-+ .max = JH7100_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = _flags, \
-+ .max = JH7100_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = CLK_SET_RATE_PARENT, \
-+ .max = JH7100_CLK_INVERT, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+struct jh7100_clk {
-+ struct clk_hw hw;
-+ unsigned int idx;
-+ unsigned int max_div;
-+};
-+
-+struct jh7100_clk_priv {
-+ /* protect clk enable and set rate/parent from happening at the same time */
-+ spinlock_t rmw_lock;
-+ struct device *dev;
-+ void __iomem *base;
-+ struct clk_hw *pll[3];
-+ struct jh7100_clk reg[];
-+};
-+
-+const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch b/target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch
deleted file mode 100644
index 60ebf2cc0a..0000000000
--- a/target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch
+++ /dev/null
@@ -1,1249 +0,0 @@
-From 674fa25b207e4bef6c27af2acfbca3a0d765a45b Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:18 +0800
-Subject: [PATCH 006/122] clk: starfive: Rename "jh7100" to "jh71x0" for the
- common code
-
-Rename some variables from "jh7100" or "JH7100" to "jh71x0"
-or "JH71X0".
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../clk/starfive/clk-starfive-jh7100-audio.c | 72 ++--
- drivers/clk/starfive/clk-starfive-jh7100.c | 389 +++++++++---------
- drivers/clk/starfive/clk-starfive-jh71x0.c | 282 ++++++-------
- drivers/clk/starfive/clk-starfive-jh71x0.h | 81 ++--
- 4 files changed, 418 insertions(+), 406 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-@@ -28,66 +28,66 @@
- #define JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD (JH7100_AUDCLK_END + 6)
- #define JH7100_AUDCLK_VAD_INTMEM (JH7100_AUDCLK_END + 7)
-
--static const struct jh7100_clk_data jh7100_audclk_data[] = {
-- JH7100__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
-+static const struct jh71x0_clk_data jh7100_audclk_data[] = {
-+ JH71X0__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
-+ JH71X0__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
- JH7100_AUDCLK_ADC_MCLK,
- JH7100_AUDCLK_I2SADC_BCLK_IOPAD),
-- JH7100__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
-- JH7100_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
-+ JH71X0__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
- JH7100_AUDCLK_I2SADC_BCLK_N,
- JH7100_AUDCLK_I2SADC_LRCLK_IOPAD,
- JH7100_AUDCLK_I2SADC_BCLK),
-- JH7100_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
- JH7100_AUDCLK_DAC_MCLK,
- JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
-- JH7100__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
-- JH7100_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
-+ JH71X0__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
- JH7100_AUDCLK_I2S1_MCLK,
- JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
-- JH7100_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
- JH7100_AUDCLK_I2S1_MCLK,
- JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
-- JH7100__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
-- JH7100_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
-+ JH71X0__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
- JH7100_AUDCLK_I2S1_BCLK_N,
- JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD),
-- JH7100_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH7100_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH7100_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
-- JH7100_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
-- JH7100_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
-- JH7100__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH7100__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-+ JH71X0_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
-+ JH71X0_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
-+ JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
-+ JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
-+ JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-+ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
- JH7100_AUDCLK_VAD_INTMEM,
- JH7100_AUDCLK_AUDIO_12288),
- };
-
- static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *data)
- {
-- struct jh7100_clk_priv *priv = data;
-+ struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7100_AUDCLK_END)
-@@ -98,7 +98,7 @@ static struct clk_hw *jh7100_audclk_get(
-
- static int jh7100_audclk_probe(struct platform_device *pdev)
- {
-- struct jh7100_clk_priv *priv;
-+ struct jh71x0_clk_priv *priv;
- unsigned int idx;
- int ret;
-
-@@ -117,12 +117,12 @@ static int jh7100_audclk_probe(struct pl
- struct clk_parent_data parents[4] = {};
- struct clk_init_data init = {
- .name = jh7100_audclk_data[idx].name,
-- .ops = starfive_jh7100_clk_ops(max),
-+ .ops = starfive_jh71x0_clk_ops(max),
- .parent_data = parents,
-- .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
-+ .num_parents = ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
- .flags = jh7100_audclk_data[idx].flags,
- };
-- struct jh7100_clk *clk = &priv->reg[idx];
-+ struct jh71x0_clk *clk = &priv->reg[idx];
- unsigned int i;
-
- for (i = 0; i < init.num_parents; i++) {
-@@ -140,7 +140,7 @@ static int jh7100_audclk_probe(struct pl
-
- clk->hw.init = &init;
- clk->idx = idx;
-- clk->max_div = max & JH7100_CLK_DIV_MASK;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-
- ret = devm_clk_hw_register(priv->dev, &clk->hw);
- if (ret)
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -23,250 +23,253 @@
- #define JH7100_CLK_GMAC_RMII_REF (JH7100_CLK_END + 2)
- #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
-
--static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
-- JH7100__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
-+static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
-+ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
-+ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
-+ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
-+ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT),
-- JH7100__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
-- JH7100__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
-+ JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
-+ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
-+ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT),
-- JH7100__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div", 2, JH7100_CLK_CPUNDBUS_ROOT),
-- JH7100__DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, JH7100_CLK_DSP_ROOT),
-- JH7100__DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, JH7100_CLK_PERH0_ROOT),
-- JH7100__DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, JH7100_CLK_PERH1_ROOT),
-- JH7100_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
-- JH7100_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
-- JH7100__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
-+ JH71X0__DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div", 2, JH7100_CLK_CPUNDBUS_ROOT),
-+ JH71X0__DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, JH7100_CLK_DSP_ROOT),
-+ JH71X0__DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, JH7100_CLK_PERH0_ROOT),
-+ JH71X0__DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, JH7100_CLK_PERH1_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
-+ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_OSC_AUD),
-- JH7100__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, JH7100_CLK_CPU_CORE),
-- JH7100__DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_DOM3AHB_BUS, "dom3ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_U74_CORE0, "u74_core0", CLK_IS_CRITICAL, JH7100_CLK_CPU_CORE),
-- JH7100_GDIV(JH7100_CLK_U74_CORE1, "u74_core1", CLK_IS_CRITICAL, 8, JH7100_CLK_CPU_CORE),
-- JH7100_GATE(JH7100_CLK_U74_AXI, "u74_axi", CLK_IS_CRITICAL, JH7100_CLK_CPU_AXI),
-- JH7100_GATE(JH7100_CLK_U74RTC_TOGGLE, "u74rtc_toggle", CLK_IS_CRITICAL, JH7100_CLK_OSC_SYS),
-- JH7100_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", 0, JH7100_CLK_CPU_AXI),
-- JH7100_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
-- JH7100_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
-- JH7100_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
-- JH7100_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
-- JH7100_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
-- JH7100_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
-- JH7100__DIV(JH7100_CLK_VCDECBUS_SRC, "vcdecbus_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-- JH7100__DIV(JH7100_CLK_VDEC_BUS, "vdec_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GATE(JH7100_CLK_VDEC_AXI, "vdec_axi", 0, JH7100_CLK_VDEC_BUS),
-- JH7100_GATE(JH7100_CLK_VDECBRG_MAIN, "vdecbrg_mainclk", 0, JH7100_CLK_VDEC_BUS),
-- JH7100_GDIV(JH7100_CLK_VDEC_BCLK, "vdec_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GDIV(JH7100_CLK_VDEC_CCLK, "vdec_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-- JH7100_GATE(JH7100_CLK_VDEC_APB, "vdec_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_JPEG_AXI, "jpeg_axi", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GDIV(JH7100_CLK_JPEG_CCLK, "jpeg_cclk", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_GC300_2X, "gc300_2x", 0, 8, JH7100_CLK_CDECHIFI4_ROOT),
-- JH7100_GATE(JH7100_CLK_GC300_AHB, "gc300_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_JPCGC300_AXIBUS, "jpcgc300_axibus", 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GATE(JH7100_CLK_GC300_AXI, "gc300_axi", 0, JH7100_CLK_JPCGC300_AXIBUS),
-- JH7100_GATE(JH7100_CLK_JPCGC300_MAIN, "jpcgc300_mainclk", 0, JH7100_CLK_JPCGC300_AXIBUS),
-- JH7100__DIV(JH7100_CLK_VENC_BUS, "venc_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GATE(JH7100_CLK_VENC_AXI, "venc_axi", 0, JH7100_CLK_VENC_BUS),
-- JH7100_GATE(JH7100_CLK_VENCBRG_MAIN, "vencbrg_mainclk", 0, JH7100_CLK_VENC_BUS),
-- JH7100_GDIV(JH7100_CLK_VENC_BCLK, "venc_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GDIV(JH7100_CLK_VENC_CCLK, "venc_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-- JH7100_GATE(JH7100_CLK_VENC_APB, "venc_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV2, "ddrpll_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_PLL1_OUT),
-- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV4, "ddrpll_div4", CLK_IS_CRITICAL, 2, JH7100_CLK_DDRPLL_DIV2),
-- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV8, "ddrpll_div8", CLK_IS_CRITICAL, 2, JH7100_CLK_DDRPLL_DIV4),
-- JH7100_GDIV(JH7100_CLK_DDROSC_DIV2, "ddrosc_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_OSC_SYS),
-- JH7100_GMUX(JH7100_CLK_DDRC0, "ddrc0", CLK_IS_CRITICAL, 4,
-+ JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, JH7100_CLK_CPU_CORE),
-+ JH71X0__DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_DOM3AHB_BUS, "dom3ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_U74_CORE0, "u74_core0", CLK_IS_CRITICAL, JH7100_CLK_CPU_CORE),
-+ JH71X0_GDIV(JH7100_CLK_U74_CORE1, "u74_core1", CLK_IS_CRITICAL, 8, JH7100_CLK_CPU_CORE),
-+ JH71X0_GATE(JH7100_CLK_U74_AXI, "u74_axi", CLK_IS_CRITICAL, JH7100_CLK_CPU_AXI),
-+ JH71X0_GATE(JH7100_CLK_U74RTC_TOGGLE, "u74rtc_toggle", CLK_IS_CRITICAL, JH7100_CLK_OSC_SYS),
-+ JH71X0_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", 0, JH7100_CLK_CPU_AXI),
-+ JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
-+ JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
-+ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
-+ JH71X0__DIV(JH7100_CLK_VCDECBUS_SRC, "vcdecbus_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-+ JH71X0__DIV(JH7100_CLK_VDEC_BUS, "vdec_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_VDEC_AXI, "vdec_axi", 0, JH7100_CLK_VDEC_BUS),
-+ JH71X0_GATE(JH7100_CLK_VDECBRG_MAIN, "vdecbrg_mainclk", 0, JH7100_CLK_VDEC_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VDEC_BCLK, "vdec_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GDIV(JH7100_CLK_VDEC_CCLK, "vdec_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-+ JH71X0_GATE(JH7100_CLK_VDEC_APB, "vdec_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_JPEG_AXI, "jpeg_axi", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_JPEG_CCLK, "jpeg_cclk", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_GC300_2X, "gc300_2x", 0, 8, JH7100_CLK_CDECHIFI4_ROOT),
-+ JH71X0_GATE(JH7100_CLK_GC300_AHB, "gc300_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_JPCGC300_AXIBUS, "jpcgc300_axibus", 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_GC300_AXI, "gc300_axi", 0, JH7100_CLK_JPCGC300_AXIBUS),
-+ JH71X0_GATE(JH7100_CLK_JPCGC300_MAIN, "jpcgc300_mainclk", 0, JH7100_CLK_JPCGC300_AXIBUS),
-+ JH71X0__DIV(JH7100_CLK_VENC_BUS, "venc_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_VENC_AXI, "venc_axi", 0, JH7100_CLK_VENC_BUS),
-+ JH71X0_GATE(JH7100_CLK_VENCBRG_MAIN, "vencbrg_mainclk", 0, JH7100_CLK_VENC_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VENC_BCLK, "venc_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GDIV(JH7100_CLK_VENC_CCLK, "venc_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-+ JH71X0_GATE(JH7100_CLK_VENC_APB, "venc_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV2, "ddrpll_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_PLL1_OUT),
-+ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV4, "ddrpll_div4", CLK_IS_CRITICAL, 2,
-+ JH7100_CLK_DDRPLL_DIV2),
-+ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV8, "ddrpll_div8", CLK_IS_CRITICAL, 2,
-+ JH7100_CLK_DDRPLL_DIV4),
-+ JH71X0_GDIV(JH7100_CLK_DDROSC_DIV2, "ddrosc_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_OSC_SYS),
-+ JH71X0_GMUX(JH7100_CLK_DDRC0, "ddrc0", CLK_IS_CRITICAL, 4,
- JH7100_CLK_DDROSC_DIV2,
- JH7100_CLK_DDRPLL_DIV2,
- JH7100_CLK_DDRPLL_DIV4,
- JH7100_CLK_DDRPLL_DIV8),
-- JH7100_GMUX(JH7100_CLK_DDRC1, "ddrc1", CLK_IS_CRITICAL, 4,
-+ JH71X0_GMUX(JH7100_CLK_DDRC1, "ddrc1", CLK_IS_CRITICAL, 4,
- JH7100_CLK_DDROSC_DIV2,
- JH7100_CLK_DDRPLL_DIV2,
- JH7100_CLK_DDRPLL_DIV4,
- JH7100_CLK_DDRPLL_DIV8),
-- JH7100_GATE(JH7100_CLK_DDRPHY_APB, "ddrphy_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100__DIV(JH7100_CLK_NOC_ROB, "noc_rob", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
-- JH7100_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
-- JH7100__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
-+ JH71X0_GATE(JH7100_CLK_DDRPHY_APB, "ddrphy_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0__DIV(JH7100_CLK_NOC_ROB, "noc_rob", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
-+ JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
-+ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
- JH7100_CLK_CPU_AXI,
- JH7100_CLK_NNEBUS_SRC1),
-- JH7100_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
-- JH7100_GATE(JH7100_CLK_NNENOC_AXI, "nnenoc_axi", 0, JH7100_CLK_NNE_BUS),
-- JH7100_GATE(JH7100_CLK_DLASLV_AXI, "dlaslv_axi", 0, JH7100_CLK_NNE_BUS),
-- JH7100_GATE(JH7100_CLK_DSPX2C_AXI, "dspx2c_axi", CLK_IS_CRITICAL, JH7100_CLK_NNE_BUS),
-- JH7100__DIV(JH7100_CLK_HIFI4_SRC, "hifi4_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-- JH7100__DIV(JH7100_CLK_HIFI4_COREFREE, "hifi4_corefree", 8, JH7100_CLK_HIFI4_SRC),
-- JH7100_GATE(JH7100_CLK_HIFI4_CORE, "hifi4_core", 0, JH7100_CLK_HIFI4_COREFREE),
-- JH7100__DIV(JH7100_CLK_HIFI4_BUS, "hifi4_bus", 8, JH7100_CLK_HIFI4_COREFREE),
-- JH7100_GATE(JH7100_CLK_HIFI4_AXI, "hifi4_axi", 0, JH7100_CLK_HIFI4_BUS),
-- JH7100_GATE(JH7100_CLK_HIFI4NOC_AXI, "hifi4noc_axi", 0, JH7100_CLK_HIFI4_BUS),
-- JH7100__DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-- JH7100_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-- JH7100_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
-- JH7100_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
-- JH7100__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
-- JH7100_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
-- JH7100_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32, JH7100_CLK_USBPHY_ROOTDIV),
-- JH7100__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
-+ JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
-+ JH71X0_GATE(JH7100_CLK_NNENOC_AXI, "nnenoc_axi", 0, JH7100_CLK_NNE_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLASLV_AXI, "dlaslv_axi", 0, JH7100_CLK_NNE_BUS),
-+ JH71X0_GATE(JH7100_CLK_DSPX2C_AXI, "dspx2c_axi", CLK_IS_CRITICAL, JH7100_CLK_NNE_BUS),
-+ JH71X0__DIV(JH7100_CLK_HIFI4_SRC, "hifi4_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-+ JH71X0__DIV(JH7100_CLK_HIFI4_COREFREE, "hifi4_corefree", 8, JH7100_CLK_HIFI4_SRC),
-+ JH71X0_GATE(JH7100_CLK_HIFI4_CORE, "hifi4_core", 0, JH7100_CLK_HIFI4_COREFREE),
-+ JH71X0__DIV(JH7100_CLK_HIFI4_BUS, "hifi4_bus", 8, JH7100_CLK_HIFI4_COREFREE),
-+ JH71X0_GATE(JH7100_CLK_HIFI4_AXI, "hifi4_axi", 0, JH7100_CLK_HIFI4_BUS),
-+ JH71X0_GATE(JH7100_CLK_HIFI4NOC_AXI, "hifi4noc_axi", 0, JH7100_CLK_HIFI4_BUS),
-+ JH71X0__DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-+ JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-+ JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
-+ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
-+ JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
-+ JH7100_CLK_USBPHY_ROOTDIV),
-+ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_USBPHY_PLLDIV25M),
-- JH7100_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
-- JH7100_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", 0, JH7100_CLK_AUDIO_DIV),
-- JH7100_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", 0, JH7100_CLK_OSC_AUD),
-- JH7100_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
-- JH7100__DIV(JH7100_CLK_ISP0_BUS, "isp0_bus", 8, JH7100_CLK_VIN_SRC),
-- JH7100_GATE(JH7100_CLK_ISP0_AXI, "isp0_axi", 0, JH7100_CLK_ISP0_BUS),
-- JH7100_GATE(JH7100_CLK_ISP0NOC_AXI, "isp0noc_axi", 0, JH7100_CLK_ISP0_BUS),
-- JH7100_GATE(JH7100_CLK_ISPSLV_AXI, "ispslv_axi", 0, JH7100_CLK_ISP0_BUS),
-- JH7100__DIV(JH7100_CLK_ISP1_BUS, "isp1_bus", 8, JH7100_CLK_VIN_SRC),
-- JH7100_GATE(JH7100_CLK_ISP1_AXI, "isp1_axi", 0, JH7100_CLK_ISP1_BUS),
-- JH7100_GATE(JH7100_CLK_ISP1NOC_AXI, "isp1noc_axi", 0, JH7100_CLK_ISP1_BUS),
-- JH7100__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
-- JH7100_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
-- JH7100_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
-- JH7100_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
-- JH7100__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
-- JH7100__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
-- JH7100_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
-- JH7100_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
-- JH7100_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
-- JH7100__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
-- JH7100_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
-- JH7100__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
-- JH7100_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
-- JH7100_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
-- JH7100_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
-- JH7100_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH7100_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH7100__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
-+ JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
-+ JH71X0_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", 0, JH7100_CLK_AUDIO_DIV),
-+ JH71X0_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", 0, JH7100_CLK_OSC_AUD),
-+ JH71X0_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
-+ JH71X0__DIV(JH7100_CLK_ISP0_BUS, "isp0_bus", 8, JH7100_CLK_VIN_SRC),
-+ JH71X0_GATE(JH7100_CLK_ISP0_AXI, "isp0_axi", 0, JH7100_CLK_ISP0_BUS),
-+ JH71X0_GATE(JH7100_CLK_ISP0NOC_AXI, "isp0noc_axi", 0, JH7100_CLK_ISP0_BUS),
-+ JH71X0_GATE(JH7100_CLK_ISPSLV_AXI, "ispslv_axi", 0, JH7100_CLK_ISP0_BUS),
-+ JH71X0__DIV(JH7100_CLK_ISP1_BUS, "isp1_bus", 8, JH7100_CLK_VIN_SRC),
-+ JH71X0_GATE(JH7100_CLK_ISP1_AXI, "isp1_axi", 0, JH7100_CLK_ISP1_BUS),
-+ JH71X0_GATE(JH7100_CLK_ISP1NOC_AXI, "isp1noc_axi", 0, JH7100_CLK_ISP1_BUS),
-+ JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
-+ JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
-+ JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
-+ JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
-+ JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
-+ JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
-+ JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
-+ JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
-+ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
- JH7100_CLK_GMAC_RMII_TX),
-- JH7100__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
-- JH7100__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
-+ JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
-+ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
- JH7100_CLK_GMAC_GR_MII_RX,
- JH7100_CLK_GMAC_RMII_RX),
-- JH7100__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
-- JH7100_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
-- JH7100_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_E24_AHB, "e24_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_E24RTC_TOGGLE, "e24rtc_toggle", 0, JH7100_CLK_OSC_SYS),
-- JH7100_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_QSPI_APB, "qspi_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_QSPI_REF, "qspi_refclk", 0, 31, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
-- JH7100_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
-- JH7100_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
-- JH7100_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_UART1_APB, "uart1_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_UART1_CORE, "uart1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GATE(JH7100_CLK_UART2_APB, "uart2_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_UART2_CORE, "uart2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_UART3_APB, "uart3_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_UART3_CORE, "uart3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER0_CORE, "timer0_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER1_CORE, "timer1_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER2_CORE, "timer2_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER3_CORE, "timer3_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER4_CORE, "timer4_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER5_CORE, "timer5_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER6_CORE, "timer6_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_VP6INTC_APB, "vp6intc_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GATE(JH7100_CLK_PWM_APB, "pwm_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GATE(JH7100_CLK_MSI_APB, "msi_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GATE(JH7100_CLK_TEMP_APB, "temp_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", 0, 31, JH7100_CLK_OSC_SYS),
-- JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
-+ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_E24_AHB, "e24_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_E24RTC_TOGGLE, "e24rtc_toggle", 0, JH7100_CLK_OSC_SYS),
-+ JH71X0_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_QSPI_APB, "qspi_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_QSPI_REF, "qspi_refclk", 0, 31, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
-+ JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
-+ JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
-+ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_UART1_APB, "uart1_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART1_CORE, "uart1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_UART2_APB, "uart2_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART2_CORE, "uart2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_UART3_APB, "uart3_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART3_CORE, "uart3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER0_CORE, "timer0_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER1_CORE, "timer1_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER2_CORE, "timer2_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER3_CORE, "timer3_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER4_CORE, "timer4_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER5_CORE, "timer5_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER6_CORE, "timer6_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_VP6INTC_APB, "vp6intc_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GATE(JH7100_CLK_PWM_APB, "pwm_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GATE(JH7100_CLK_MSI_APB, "msi_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GATE(JH7100_CLK_TEMP_APB, "temp_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", 0, 31, JH7100_CLK_OSC_SYS),
-+ JH71X0_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
- };
-
- static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
- {
-- struct jh7100_clk_priv *priv = data;
-+ struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7100_CLK_PLL0_OUT)
-@@ -280,7 +283,7 @@ static struct clk_hw *jh7100_clk_get(str
-
- static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
- {
-- struct jh7100_clk_priv *priv;
-+ struct jh71x0_clk_priv *priv;
- unsigned int idx;
- int ret;
-
-@@ -314,12 +317,12 @@ static int __init clk_starfive_jh7100_pr
- struct clk_parent_data parents[4] = {};
- struct clk_init_data init = {
- .name = jh7100_clk_data[idx].name,
-- .ops = starfive_jh7100_clk_ops(max),
-+ .ops = starfive_jh71x0_clk_ops(max),
- .parent_data = parents,
-- .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
-+ .num_parents = ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
- .flags = jh7100_clk_data[idx].flags,
- };
-- struct jh7100_clk *clk = &priv->reg[idx];
-+ struct jh71x0_clk *clk = &priv->reg[idx];
- unsigned int i;
-
- for (i = 0; i < init.num_parents; i++) {
-@@ -341,7 +344,7 @@ static int __init clk_starfive_jh7100_pr
-
- clk->hw.init = &init;
- clk->idx = idx;
-- clk->max_div = max & JH7100_CLK_DIV_MASK;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-
- ret = devm_clk_hw_register(priv->dev, &clk->hw);
- if (ret)
---- a/drivers/clk/starfive/clk-starfive-jh71x0.c
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0
- /*
-- * StarFive JH7100 Clock Generator Driver
-+ * StarFive JH71X0 Clock Generator Driver
- *
- * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
- */
-@@ -12,27 +12,27 @@
-
- #include "clk-starfive-jh71x0.h"
-
--static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
-+static struct jh71x0_clk *jh71x0_clk_from(struct clk_hw *hw)
- {
-- return container_of(hw, struct jh7100_clk, hw);
-+ return container_of(hw, struct jh71x0_clk, hw);
- }
-
--static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
-+static struct jh71x0_clk_priv *jh71x0_priv_from(struct jh71x0_clk *clk)
- {
-- return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
-+ return container_of(clk, struct jh71x0_clk_priv, reg[clk->idx]);
- }
-
--static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
-+static u32 jh71x0_clk_reg_get(struct jh71x0_clk *clk)
- {
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
- void __iomem *reg = priv->base + 4 * clk->idx;
-
- return readl_relaxed(reg);
- }
-
--static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
-+static void jh71x0_clk_reg_rmw(struct jh71x0_clk *clk, u32 mask, u32 value)
- {
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
- void __iomem *reg = priv->base + 4 * clk->idx;
- unsigned long flags;
-
-@@ -42,41 +42,41 @@ static void jh7100_clk_reg_rmw(struct jh
- spin_unlock_irqrestore(&priv->rmw_lock, flags);
- }
-
--static int jh7100_clk_enable(struct clk_hw *hw)
-+static int jh71x0_clk_enable(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, JH71X0_CLK_ENABLE);
- return 0;
- }
-
--static void jh7100_clk_disable(struct clk_hw *hw)
-+static void jh71x0_clk_disable(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, 0);
- }
-
--static int jh7100_clk_is_enabled(struct clk_hw *hw)
-+static int jh71x0_clk_is_enabled(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-
-- return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
-+ return !!(jh71x0_clk_reg_get(clk) & JH71X0_CLK_ENABLE);
- }
-
--static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
-+static unsigned long jh71x0_clk_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 div = jh71x0_clk_reg_get(clk) & JH71X0_CLK_DIV_MASK;
-
- return div ? parent_rate / div : 0;
- }
-
--static int jh7100_clk_determine_rate(struct clk_hw *hw,
-+static int jh71x0_clk_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- unsigned long parent = req->best_parent_rate;
- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
- unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
-@@ -102,232 +102,232 @@ static int jh7100_clk_determine_rate(str
- return 0;
- }
-
--static int jh7100_clk_set_rate(struct clk_hw *hw,
-+static int jh71x0_clk_set_rate(struct clk_hw *hw,
- unsigned long rate,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
- 1UL, (unsigned long)clk->max_div);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, div);
- return 0;
- }
-
--static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
-+static unsigned long jh71x0_clk_frac_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 reg = jh7100_clk_reg_get(clk);
-- unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
-- ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 reg = jh71x0_clk_reg_get(clk);
-+ unsigned long div100 = 100 * (reg & JH71X0_CLK_INT_MASK) +
-+ ((reg & JH71X0_CLK_FRAC_MASK) >> JH71X0_CLK_FRAC_SHIFT);
-
-- return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
-+ return (div100 >= JH71X0_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
- }
-
--static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
-+static int jh71x0_clk_frac_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
- {
- unsigned long parent100 = 100 * req->best_parent_rate;
- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-+ JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
- unsigned long result = parent100 / div100;
-
-- /* clamp the result as in jh7100_clk_determine_rate() above */
-- if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
-+ /* clamp the result as in jh71x0_clk_determine_rate() above */
-+ if (result > req->max_rate && div100 < JH71X0_CLK_FRAC_MAX)
- result = parent100 / (div100 + 1);
-- if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
-+ if (result < req->min_rate && div100 > JH71X0_CLK_FRAC_MIN)
- result = parent100 / (div100 - 1);
-
- req->rate = result;
- return 0;
- }
-
--static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
-+static int jh71x0_clk_frac_set_rate(struct clk_hw *hw,
- unsigned long rate,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-- u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
-+ JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
-+ u32 value = ((div100 % 100) << JH71X0_CLK_FRAC_SHIFT) | (div100 / 100);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, value);
- return 0;
- }
-
--static u8 jh7100_clk_get_parent(struct clk_hw *hw)
-+static u8 jh71x0_clk_get_parent(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 value = jh71x0_clk_reg_get(clk);
-
-- return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
-+ return (value & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT;
- }
-
--static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
-+static int jh71x0_clk_set_parent(struct clk_hw *hw, u8 index)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 value = (u32)index << JH71X0_CLK_MUX_SHIFT;
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_MUX_MASK, value);
- return 0;
- }
-
--static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
-+static int jh71x0_clk_mux_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
- {
- return clk_mux_determine_rate_flags(hw, req, 0);
- }
-
--static int jh7100_clk_get_phase(struct clk_hw *hw)
-+static int jh71x0_clk_get_phase(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 value = jh71x0_clk_reg_get(clk);
-
-- return (value & JH7100_CLK_INVERT) ? 180 : 0;
-+ return (value & JH71X0_CLK_INVERT) ? 180 : 0;
- }
-
--static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
-+static int jh71x0_clk_set_phase(struct clk_hw *hw, int degrees)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- u32 value;
-
- if (degrees == 0)
- value = 0;
- else if (degrees == 180)
-- value = JH7100_CLK_INVERT;
-+ value = JH71X0_CLK_INVERT;
- else
- return -EINVAL;
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_INVERT, value);
- return 0;
- }
-
- #ifdef CONFIG_DEBUG_FS
--static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
-+static void jh71x0_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
- {
-- static const struct debugfs_reg32 jh7100_clk_reg = {
-+ static const struct debugfs_reg32 jh71x0_clk_reg = {
- .name = "CTRL",
- .offset = 0,
- };
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
- struct debugfs_regset32 *regset;
-
- regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
- if (!regset)
- return;
-
-- regset->regs = &jh7100_clk_reg;
-+ regset->regs = &jh71x0_clk_reg;
- regset->nregs = 1;
- regset->base = priv->base + 4 * clk->idx;
-
- debugfs_create_regset32("registers", 0400, dentry, regset);
- }
- #else
--#define jh7100_clk_debug_init NULL
-+#define jh71x0_clk_debug_init NULL
- #endif
-
--static const struct clk_ops jh7100_clk_gate_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gate_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_div_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_div_ops = {
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_fdiv_ops = {
-- .recalc_rate = jh7100_clk_frac_recalc_rate,
-- .determine_rate = jh7100_clk_frac_determine_rate,
-- .set_rate = jh7100_clk_frac_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_fdiv_ops = {
-+ .recalc_rate = jh71x0_clk_frac_recalc_rate,
-+ .determine_rate = jh71x0_clk_frac_determine_rate,
-+ .set_rate = jh71x0_clk_frac_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_gdiv_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gdiv_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_mux_ops = {
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_mux_ops = {
-+ .determine_rate = jh71x0_clk_mux_determine_rate,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_gmux_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gmux_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .determine_rate = jh71x0_clk_mux_determine_rate,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_mdiv_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_mdiv_ops = {
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_gmd_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gmd_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_inv_ops = {
-- .get_phase = jh7100_clk_get_phase,
-- .set_phase = jh7100_clk_set_phase,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_inv_ops = {
-+ .get_phase = jh71x0_clk_get_phase,
-+ .set_phase = jh71x0_clk_set_phase,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
-+const struct clk_ops *starfive_jh71x0_clk_ops(u32 max)
- {
-- if (max & JH7100_CLK_DIV_MASK) {
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmd_ops;
-- return &jh7100_clk_mdiv_ops;
-+ if (max & JH71X0_CLK_DIV_MASK) {
-+ if (max & JH71X0_CLK_MUX_MASK) {
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gmd_ops;
-+ return &jh71x0_clk_mdiv_ops;
- }
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gdiv_ops;
-- if (max == JH7100_CLK_FRAC_MAX)
-- return &jh7100_clk_fdiv_ops;
-- return &jh7100_clk_div_ops;
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gdiv_ops;
-+ if (max == JH71X0_CLK_FRAC_MAX)
-+ return &jh71x0_clk_fdiv_ops;
-+ return &jh71x0_clk_div_ops;
- }
-
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmux_ops;
-- return &jh7100_clk_mux_ops;
-+ if (max & JH71X0_CLK_MUX_MASK) {
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gmux_ops;
-+ return &jh71x0_clk_mux_ops;
- }
-
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gate_ops;
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gate_ops;
-
-- return &jh7100_clk_inv_ops;
-+ return &jh71x0_clk_inv_ops;
- }
--EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
-+EXPORT_SYMBOL_GPL(starfive_jh71x0_clk_ops);
---- a/drivers/clk/starfive/clk-starfive-jh71x0.h
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
-@@ -1,6 +1,6 @@
- /* SPDX-License-Identifier: GPL-2.0 */
--#ifndef __CLK_STARFIVE_JH7100_H
--#define __CLK_STARFIVE_JH7100_H
-+#ifndef __CLK_STARFIVE_JH71X0_H
-+#define __CLK_STARFIVE_JH71X0_H
-
- #include <linux/bits.h>
- #include <linux/clk-provider.h>
-@@ -8,107 +8,116 @@
- #include <linux/spinlock.h>
-
- /* register fields */
--#define JH7100_CLK_ENABLE BIT(31)
--#define JH7100_CLK_INVERT BIT(30)
--#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
--#define JH7100_CLK_MUX_SHIFT 24
--#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
--#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
--#define JH7100_CLK_FRAC_SHIFT 8
--#define JH7100_CLK_INT_MASK GENMASK(7, 0)
-+#define JH71X0_CLK_ENABLE BIT(31)
-+#define JH71X0_CLK_INVERT BIT(30)
-+#define JH71X0_CLK_MUX_MASK GENMASK(27, 24)
-+#define JH71X0_CLK_MUX_SHIFT 24
-+#define JH71X0_CLK_DIV_MASK GENMASK(23, 0)
-+#define JH71X0_CLK_FRAC_MASK GENMASK(15, 8)
-+#define JH71X0_CLK_FRAC_SHIFT 8
-+#define JH71X0_CLK_INT_MASK GENMASK(7, 0)
-
- /* fractional divider min/max */
--#define JH7100_CLK_FRAC_MIN 100UL
--#define JH7100_CLK_FRAC_MAX 25599UL
-+#define JH71X0_CLK_FRAC_MIN 100UL
-+#define JH71X0_CLK_FRAC_MAX 25599UL
-
- /* clock data */
--struct jh7100_clk_data {
-+struct jh71x0_clk_data {
- const char *name;
- unsigned long flags;
- u32 max;
- u8 parents[4];
- };
-
--#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
-+#define JH71X0_GATE(_idx, _name, _flags, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = CLK_SET_RATE_PARENT | (_flags), \
-- .max = JH7100_CLK_ENABLE, \
-+ .max = JH71X0_CLK_ENABLE, \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
-+#define JH71X0__DIV(_idx, _name, _max, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
- .max = _max, \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
-+#define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | (_max), \
-+ .max = JH71X0_CLK_ENABLE | (_max), \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
-+#define JH71X0_FDIV(_idx, _name, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
-- .max = JH7100_CLK_FRAC_MAX, \
-+ .max = JH71X0_CLK_FRAC_MAX, \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
-+#define JH71X0__MUX(_idx, _name, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
-- .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
-+ .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
-+#define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
-+ .max = JH71X0_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT), \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
-+#define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
-- .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
-+#define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .max = JH71X0_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
-+#define JH71X0__INV(_idx, _name, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = CLK_SET_RATE_PARENT, \
-- .max = JH7100_CLK_INVERT, \
-+ .max = JH71X0_CLK_INVERT, \
- .parents = { [0] = _parent }, \
- }
-
--struct jh7100_clk {
-+struct jh71x0_clk {
- struct clk_hw hw;
- unsigned int idx;
- unsigned int max_div;
- };
-
--struct jh7100_clk_priv {
-+struct jh71x0_clk_priv {
- /* protect clk enable and set rate/parent from happening at the same time */
- spinlock_t rmw_lock;
- struct device *dev;
- void __iomem *base;
- struct clk_hw *pll[3];
-- struct jh7100_clk reg[];
-+ struct jh71x0_clk reg[];
- };
-
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
-+const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
-
- #endif
diff --git a/target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch b/target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch
deleted file mode 100644
index e5281b85e9..0000000000
--- a/target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0ee5a7565601fa785d7e55c57f26ff5d79473eb2 Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:19 +0800
-Subject: [PATCH 007/122] reset: starfive: Replace SOC_STARFIVE with
- ARCH_STARFIVE
-
-Using ARCH_FOO symbol is preferred than SOC_FOO.
-
-Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/reset/Kconfig
-+++ b/drivers/reset/Kconfig
-@@ -234,8 +234,8 @@ config RESET_SOCFPGA
-
- config RESET_STARFIVE_JH7100
- bool "StarFive JH7100 Reset Driver"
-- depends on SOC_STARFIVE || COMPILE_TEST
-- default SOC_STARFIVE
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
-
diff --git a/target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch b/target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch
deleted file mode 100644
index 2e44f38e59..0000000000
--- a/target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch
+++ /dev/null
@@ -1,436 +0,0 @@
-From ea9e5879793f9743fbfe613174900ab0c431ac0e Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:20 +0800
-Subject: [PATCH 008/122] reset: Create subdirectory for StarFive drivers
-
-This moves the StarFive JH7100 reset driver to a new subdirectory in
-preparation for adding more StarFive reset drivers.
-
-Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/Kconfig | 8 +-------
- drivers/reset/Makefile | 2 +-
- drivers/reset/starfive/Kconfig | 8 ++++++++
- drivers/reset/starfive/Makefile | 2 ++
- drivers/reset/{ => starfive}/reset-starfive-jh7100.c | 0
- 5 files changed, 12 insertions(+), 8 deletions(-)
- create mode 100644 drivers/reset/starfive/Kconfig
- create mode 100644 drivers/reset/starfive/Makefile
- rename drivers/reset/{ => starfive}/reset-starfive-jh7100.c (100%)
-
---- a/drivers/reset/Kconfig
-+++ b/drivers/reset/Kconfig
-@@ -232,13 +232,6 @@ config RESET_SOCFPGA
- This enables the reset driver for the SoCFPGA ARMv7 platforms. This
- driver gets initialized early during platform init calls.
-
--config RESET_STARFIVE_JH7100
-- bool "StarFive JH7100 Reset Driver"
-- depends on ARCH_STARFIVE || COMPILE_TEST
-- default ARCH_STARFIVE
-- help
-- This enables the reset controller driver for the StarFive JH7100 SoC.
--
- config RESET_SUNPLUS
- bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
- default ARCH_SUNPLUS
-@@ -320,6 +313,7 @@ config RESET_ZYNQ
- help
- This enables the reset controller driver for Xilinx Zynq SoCs.
-
-+source "drivers/reset/starfive/Kconfig"
- source "drivers/reset/sti/Kconfig"
- source "drivers/reset/hisilicon/Kconfig"
- source "drivers/reset/tegra/Kconfig"
---- a/drivers/reset/Makefile
-+++ b/drivers/reset/Makefile
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-y += core.o
- obj-y += hisilicon/
-+obj-y += starfive/
- obj-$(CONFIG_ARCH_STI) += sti/
- obj-$(CONFIG_ARCH_TEGRA) += tegra/
- obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
-@@ -30,7 +31,6 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) +=
- obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
- obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
- obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
--obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
- obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
- obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
- obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
---- /dev/null
-+++ b/drivers/reset/starfive/Kconfig
-@@ -0,0 +1,8 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+
-+config RESET_STARFIVE_JH7100
-+ bool "StarFive JH7100 Reset Driver"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
-+ help
-+ This enables the reset controller driver for the StarFive JH7100 SoC.
---- /dev/null
-+++ b/drivers/reset/starfive/Makefile
-@@ -0,0 +1,2 @@
-+# SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
---- a/drivers/reset/reset-starfive-jh7100.c
-+++ /dev/null
-@@ -1,173 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- * Reset driver for the StarFive JH7100 SoC
-- *
-- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-- */
--
--#include <linux/bitmap.h>
--#include <linux/io.h>
--#include <linux/io-64-nonatomic-lo-hi.h>
--#include <linux/iopoll.h>
--#include <linux/mod_devicetable.h>
--#include <linux/platform_device.h>
--#include <linux/reset-controller.h>
--#include <linux/spinlock.h>
--
--#include <dt-bindings/reset/starfive-jh7100.h>
--
--/* register offsets */
--#define JH7100_RESET_ASSERT0 0x00
--#define JH7100_RESET_ASSERT1 0x04
--#define JH7100_RESET_ASSERT2 0x08
--#define JH7100_RESET_ASSERT3 0x0c
--#define JH7100_RESET_STATUS0 0x10
--#define JH7100_RESET_STATUS1 0x14
--#define JH7100_RESET_STATUS2 0x18
--#define JH7100_RESET_STATUS3 0x1c
--
--/*
-- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-- * line 32m + n, and writing a 0 deasserts the same line.
-- * Most reset lines have their status inverted so a 0 bit in the STATUS
-- * register means the line is asserted and a 1 means it's deasserted. A few
-- * lines don't though, so store the expected value of the status registers when
-- * all lines are asserted.
-- */
--static const u64 jh7100_reset_asserted[2] = {
-- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-- /* STATUS3 */
-- 0,
--};
--
--struct jh7100_reset {
-- struct reset_controller_dev rcdev;
-- /* protect registers against concurrent read-modify-write */
-- spinlock_t lock;
-- void __iomem *base;
--};
--
--static inline struct jh7100_reset *
--jh7100_reset_from(struct reset_controller_dev *rcdev)
--{
-- return container_of(rcdev, struct jh7100_reset, rcdev);
--}
--
--static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-- unsigned long id, bool assert)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 done = jh7100_reset_asserted[offset] & mask;
-- u64 value;
-- unsigned long flags;
-- int ret;
--
-- if (!assert)
-- done ^= mask;
--
-- spin_lock_irqsave(&data->lock, flags);
--
-- value = readq(reg_assert);
-- if (assert)
-- value |= mask;
-- else
-- value &= ~mask;
-- writeq(value, reg_assert);
--
-- /* if the associated clock is gated, deasserting might otherwise hang forever */
-- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
--
-- spin_unlock_irqrestore(&data->lock, flags);
-- return ret;
--}
--
--static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, true);
--}
--
--static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, false);
--}
--
--static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- int ret;
--
-- ret = jh7100_reset_assert(rcdev, id);
-- if (ret)
-- return ret;
--
-- return jh7100_reset_deassert(rcdev, id);
--}
--
--static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 value = readq(reg_status);
--
-- return !((value ^ jh7100_reset_asserted[offset]) & mask);
--}
--
--static const struct reset_control_ops jh7100_reset_ops = {
-- .assert = jh7100_reset_assert,
-- .deassert = jh7100_reset_deassert,
-- .reset = jh7100_reset_reset,
-- .status = jh7100_reset_status,
--};
--
--static int __init jh7100_reset_probe(struct platform_device *pdev)
--{
-- struct jh7100_reset *data;
--
-- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-- if (!data)
-- return -ENOMEM;
--
-- data->base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(data->base))
-- return PTR_ERR(data->base);
--
-- data->rcdev.ops = &jh7100_reset_ops;
-- data->rcdev.owner = THIS_MODULE;
-- data->rcdev.nr_resets = JH7100_RSTN_END;
-- data->rcdev.dev = &pdev->dev;
-- data->rcdev.of_node = pdev->dev.of_node;
-- spin_lock_init(&data->lock);
--
-- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
--}
--
--static const struct of_device_id jh7100_reset_dt_ids[] = {
-- { .compatible = "starfive,jh7100-reset" },
-- { /* sentinel */ }
--};
--
--static struct platform_driver jh7100_reset_driver = {
-- .driver = {
-- .name = "jh7100-reset",
-- .of_match_table = jh7100_reset_dt_ids,
-- .suppress_bind_attrs = true,
-- },
--};
--builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -0,0 +1,173 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Reset driver for the StarFive JH7100 SoC
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/bitmap.h>
-+#include <linux/io.h>
-+#include <linux/io-64-nonatomic-lo-hi.h>
-+#include <linux/iopoll.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset-controller.h>
-+#include <linux/spinlock.h>
-+
-+#include <dt-bindings/reset/starfive-jh7100.h>
-+
-+/* register offsets */
-+#define JH7100_RESET_ASSERT0 0x00
-+#define JH7100_RESET_ASSERT1 0x04
-+#define JH7100_RESET_ASSERT2 0x08
-+#define JH7100_RESET_ASSERT3 0x0c
-+#define JH7100_RESET_STATUS0 0x10
-+#define JH7100_RESET_STATUS1 0x14
-+#define JH7100_RESET_STATUS2 0x18
-+#define JH7100_RESET_STATUS3 0x1c
-+
-+/*
-+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-+ * line 32m + n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u64 jh7100_reset_asserted[2] = {
-+ /* STATUS0 */
-+ BIT_ULL_MASK(JH7100_RST_U74) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ /* STATUS1 */
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ /* STATUS2 */
-+ BIT_ULL_MASK(JH7100_RST_E24) |
-+ /* STATUS3 */
-+ 0,
-+};
-+
-+struct jh7100_reset {
-+ struct reset_controller_dev rcdev;
-+ /* protect registers against concurrent read-modify-write */
-+ spinlock_t lock;
-+ void __iomem *base;
-+};
-+
-+static inline struct jh7100_reset *
-+jh7100_reset_from(struct reset_controller_dev *rcdev)
-+{
-+ return container_of(rcdev, struct jh7100_reset, rcdev);
-+}
-+
-+static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-+ unsigned long id, bool assert)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 done = jh7100_reset_asserted[offset] & mask;
-+ u64 value;
-+ unsigned long flags;
-+ int ret;
-+
-+ if (!assert)
-+ done ^= mask;
-+
-+ spin_lock_irqsave(&data->lock, flags);
-+
-+ value = readq(reg_assert);
-+ if (assert)
-+ value |= mask;
-+ else
-+ value &= ~mask;
-+ writeq(value, reg_assert);
-+
-+ /* if the associated clock is gated, deasserting might otherwise hang forever */
-+ ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-+
-+ spin_unlock_irqrestore(&data->lock, flags);
-+ return ret;
-+}
-+
-+static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, true);
-+}
-+
-+static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, false);
-+}
-+
-+static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ int ret;
-+
-+ ret = jh7100_reset_assert(rcdev, id);
-+ if (ret)
-+ return ret;
-+
-+ return jh7100_reset_deassert(rcdev, id);
-+}
-+
-+static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 value = readq(reg_status);
-+
-+ return !((value ^ jh7100_reset_asserted[offset]) & mask);
-+}
-+
-+static const struct reset_control_ops jh7100_reset_ops = {
-+ .assert = jh7100_reset_assert,
-+ .deassert = jh7100_reset_deassert,
-+ .reset = jh7100_reset_reset,
-+ .status = jh7100_reset_status,
-+};
-+
-+static int __init jh7100_reset_probe(struct platform_device *pdev)
-+{
-+ struct jh7100_reset *data;
-+
-+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ data->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(data->base))
-+ return PTR_ERR(data->base);
-+
-+ data->rcdev.ops = &jh7100_reset_ops;
-+ data->rcdev.owner = THIS_MODULE;
-+ data->rcdev.nr_resets = JH7100_RSTN_END;
-+ data->rcdev.dev = &pdev->dev;
-+ data->rcdev.of_node = pdev->dev.of_node;
-+ spin_lock_init(&data->lock);
-+
-+ return devm_reset_controller_register(&pdev->dev, &data->rcdev);
-+}
-+
-+static const struct of_device_id jh7100_reset_dt_ids[] = {
-+ { .compatible = "starfive,jh7100-reset" },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver jh7100_reset_driver = {
-+ .driver = {
-+ .name = "jh7100-reset",
-+ .of_match_table = jh7100_reset_dt_ids,
-+ .suppress_bind_attrs = true,
-+ },
-+};
-+builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
diff --git a/target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch b/target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch
deleted file mode 100644
index cd192f80af..0000000000
--- a/target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch
+++ /dev/null
@@ -1,390 +0,0 @@
-From a8051a7daa45056f469686286886968bc62b94df Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:21 +0800
-Subject: [PATCH 009/122] reset: starfive: Factor out common JH71X0 reset code
-
-The StarFive JH7100 SoC has additional reset controllers for audio and
-video, but the registers follow the same structure. On the JH7110 the
-reset registers don't get their own memory range, but instead follow the
-clock control registers. The registers still follow the same structure
-though, so let's factor out the common code to handle all these cases.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/starfive/Kconfig | 4 +
- drivers/reset/starfive/Makefile | 2 +
- .../reset/starfive/reset-starfive-jh7100.c | 150 +---------------
- .../reset/starfive/reset-starfive-jh71x0.c | 162 ++++++++++++++++++
- .../reset/starfive/reset-starfive-jh71x0.h | 11 ++
- 5 files changed, 180 insertions(+), 149 deletions(-)
- create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.c
- create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.h
-
---- a/drivers/reset/starfive/Kconfig
-+++ b/drivers/reset/starfive/Kconfig
-@@ -1,8 +1,12 @@
- # SPDX-License-Identifier: GPL-2.0-only
-
-+config RESET_STARFIVE_JH71X0
-+ bool
-+
- config RESET_STARFIVE_JH7100
- bool "StarFive JH7100 Reset Driver"
- depends on ARCH_STARFIVE || COMPILE_TEST
-+ select RESET_STARFIVE_JH71X0
- default ARCH_STARFIVE
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
---- a/drivers/reset/starfive/Makefile
-+++ b/drivers/reset/starfive/Makefile
-@@ -1,2 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
-+
- obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -5,158 +5,10 @@
- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
- */
-
--#include <linux/bitmap.h>
--#include <linux/io.h>
--#include <linux/io-64-nonatomic-lo-hi.h>
--#include <linux/iopoll.h>
- #include <linux/mod_devicetable.h>
- #include <linux/platform_device.h>
--#include <linux/reset-controller.h>
--#include <linux/spinlock.h>
-
--#include <dt-bindings/reset/starfive-jh7100.h>
--
--/* register offsets */
--#define JH7100_RESET_ASSERT0 0x00
--#define JH7100_RESET_ASSERT1 0x04
--#define JH7100_RESET_ASSERT2 0x08
--#define JH7100_RESET_ASSERT3 0x0c
--#define JH7100_RESET_STATUS0 0x10
--#define JH7100_RESET_STATUS1 0x14
--#define JH7100_RESET_STATUS2 0x18
--#define JH7100_RESET_STATUS3 0x1c
--
--/*
-- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-- * line 32m + n, and writing a 0 deasserts the same line.
-- * Most reset lines have their status inverted so a 0 bit in the STATUS
-- * register means the line is asserted and a 1 means it's deasserted. A few
-- * lines don't though, so store the expected value of the status registers when
-- * all lines are asserted.
-- */
--static const u64 jh7100_reset_asserted[2] = {
-- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-- /* STATUS3 */
-- 0,
--};
--
--struct jh7100_reset {
-- struct reset_controller_dev rcdev;
-- /* protect registers against concurrent read-modify-write */
-- spinlock_t lock;
-- void __iomem *base;
--};
--
--static inline struct jh7100_reset *
--jh7100_reset_from(struct reset_controller_dev *rcdev)
--{
-- return container_of(rcdev, struct jh7100_reset, rcdev);
--}
--
--static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-- unsigned long id, bool assert)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 done = jh7100_reset_asserted[offset] & mask;
-- u64 value;
-- unsigned long flags;
-- int ret;
--
-- if (!assert)
-- done ^= mask;
--
-- spin_lock_irqsave(&data->lock, flags);
--
-- value = readq(reg_assert);
-- if (assert)
-- value |= mask;
-- else
-- value &= ~mask;
-- writeq(value, reg_assert);
--
-- /* if the associated clock is gated, deasserting might otherwise hang forever */
-- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
--
-- spin_unlock_irqrestore(&data->lock, flags);
-- return ret;
--}
--
--static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, true);
--}
--
--static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, false);
--}
--
--static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- int ret;
--
-- ret = jh7100_reset_assert(rcdev, id);
-- if (ret)
-- return ret;
--
-- return jh7100_reset_deassert(rcdev, id);
--}
--
--static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 value = readq(reg_status);
--
-- return !((value ^ jh7100_reset_asserted[offset]) & mask);
--}
--
--static const struct reset_control_ops jh7100_reset_ops = {
-- .assert = jh7100_reset_assert,
-- .deassert = jh7100_reset_deassert,
-- .reset = jh7100_reset_reset,
-- .status = jh7100_reset_status,
--};
--
--static int __init jh7100_reset_probe(struct platform_device *pdev)
--{
-- struct jh7100_reset *data;
--
-- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-- if (!data)
-- return -ENOMEM;
--
-- data->base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(data->base))
-- return PTR_ERR(data->base);
--
-- data->rcdev.ops = &jh7100_reset_ops;
-- data->rcdev.owner = THIS_MODULE;
-- data->rcdev.nr_resets = JH7100_RSTN_END;
-- data->rcdev.dev = &pdev->dev;
-- data->rcdev.of_node = pdev->dev.of_node;
-- spin_lock_init(&data->lock);
--
-- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
--}
-+#include "reset-starfive-jh71x0.h"
-
- static const struct of_device_id jh7100_reset_dt_ids[] = {
- { .compatible = "starfive,jh7100-reset" },
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -0,0 +1,162 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Reset driver for the StarFive JH7100 SoC
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/bitmap.h>
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/io-64-nonatomic-lo-hi.h>
-+#include <linux/iopoll.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset-controller.h>
-+#include <linux/spinlock.h>
-+
-+#include "reset-starfive-jh71x0.h"
-+
-+#include <dt-bindings/reset/starfive-jh7100.h>
-+
-+/* register offsets */
-+#define JH7100_RESET_ASSERT0 0x00
-+#define JH7100_RESET_ASSERT1 0x04
-+#define JH7100_RESET_ASSERT2 0x08
-+#define JH7100_RESET_ASSERT3 0x0c
-+#define JH7100_RESET_STATUS0 0x10
-+#define JH7100_RESET_STATUS1 0x14
-+#define JH7100_RESET_STATUS2 0x18
-+#define JH7100_RESET_STATUS3 0x1c
-+
-+/*
-+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-+ * line 32m + n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u64 jh7100_reset_asserted[2] = {
-+ /* STATUS0 */
-+ BIT_ULL_MASK(JH7100_RST_U74) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ /* STATUS1 */
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ /* STATUS2 */
-+ BIT_ULL_MASK(JH7100_RST_E24) |
-+ /* STATUS3 */
-+ 0,
-+};
-+
-+struct jh7100_reset {
-+ struct reset_controller_dev rcdev;
-+ /* protect registers against concurrent read-modify-write */
-+ spinlock_t lock;
-+ void __iomem *base;
-+};
-+
-+static inline struct jh7100_reset *
-+jh7100_reset_from(struct reset_controller_dev *rcdev)
-+{
-+ return container_of(rcdev, struct jh7100_reset, rcdev);
-+}
-+
-+static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-+ unsigned long id, bool assert)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 done = jh7100_reset_asserted[offset] & mask;
-+ u64 value;
-+ unsigned long flags;
-+ int ret;
-+
-+ if (!assert)
-+ done ^= mask;
-+
-+ spin_lock_irqsave(&data->lock, flags);
-+
-+ value = readq(reg_assert);
-+ if (assert)
-+ value |= mask;
-+ else
-+ value &= ~mask;
-+ writeq(value, reg_assert);
-+
-+ /* if the associated clock is gated, deasserting might otherwise hang forever */
-+ ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-+
-+ spin_unlock_irqrestore(&data->lock, flags);
-+ return ret;
-+}
-+
-+static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, true);
-+}
-+
-+static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, false);
-+}
-+
-+static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ int ret;
-+
-+ ret = jh7100_reset_assert(rcdev, id);
-+ if (ret)
-+ return ret;
-+
-+ return jh7100_reset_deassert(rcdev, id);
-+}
-+
-+static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 value = readq(reg_status);
-+
-+ return !((value ^ jh7100_reset_asserted[offset]) & mask);
-+}
-+
-+static const struct reset_control_ops jh7100_reset_ops = {
-+ .assert = jh7100_reset_assert,
-+ .deassert = jh7100_reset_deassert,
-+ .reset = jh7100_reset_reset,
-+ .status = jh7100_reset_status,
-+};
-+
-+int jh7100_reset_probe(struct platform_device *pdev)
-+{
-+ struct jh7100_reset *data;
-+
-+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ data->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(data->base))
-+ return PTR_ERR(data->base);
-+
-+ data->rcdev.ops = &jh7100_reset_ops;
-+ data->rcdev.owner = THIS_MODULE;
-+ data->rcdev.nr_resets = JH7100_RSTN_END;
-+ data->rcdev.dev = &pdev->dev;
-+ data->rcdev.of_node = pdev->dev.of_node;
-+ spin_lock_init(&data->lock);
-+
-+ return devm_reset_controller_register(&pdev->dev, &data->rcdev);
-+}
-+EXPORT_SYMBOL_GPL(jh7100_reset_probe);
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -0,0 +1,11 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef __RESET_STARFIVE_JH71X0_H
-+#define __RESET_STARFIVE_JH71X0_H
-+
-+int jh7100_reset_probe(struct platform_device *pdev);
-+
-+#endif /* __RESET_STARFIVE_JH71X0_H */
diff --git a/target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch b/target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch
deleted file mode 100644
index 0a932f57b2..0000000000
--- a/target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch
+++ /dev/null
@@ -1,215 +0,0 @@
-From dbee38aac9811a25e3e3204f813048bf64155248 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:22 +0800
-Subject: [PATCH 010/122] reset: starfive: Extract the common JH71X0 reset code
-
-Extract the common JH71X0 reset code for reusing them to
-support JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../reset/starfive/reset-starfive-jh7100.c | 49 ++++++++++++
- .../reset/starfive/reset-starfive-jh71x0.c | 76 ++++++-------------
- .../reset/starfive/reset-starfive-jh71x0.h | 5 +-
- 3 files changed, 76 insertions(+), 54 deletions(-)
-
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -10,6 +10,55 @@
-
- #include "reset-starfive-jh71x0.h"
-
-+#include <dt-bindings/reset/starfive-jh7100.h>
-+
-+/* register offsets */
-+#define JH7100_RESET_ASSERT0 0x00
-+#define JH7100_RESET_ASSERT1 0x04
-+#define JH7100_RESET_ASSERT2 0x08
-+#define JH7100_RESET_ASSERT3 0x0c
-+#define JH7100_RESET_STATUS0 0x10
-+#define JH7100_RESET_STATUS1 0x14
-+#define JH7100_RESET_STATUS2 0x18
-+#define JH7100_RESET_STATUS3 0x1c
-+
-+/*
-+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-+ * line 32m + n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u64 jh7100_reset_asserted[2] = {
-+ /* STATUS0 */
-+ BIT_ULL_MASK(JH7100_RST_U74) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ /* STATUS1 */
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ /* STATUS2 */
-+ BIT_ULL_MASK(JH7100_RST_E24) |
-+ /* STATUS3 */
-+ 0,
-+};
-+
-+static int __init jh7100_reset_probe(struct platform_device *pdev)
-+{
-+ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
-+
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
-+ base + JH7100_RESET_ASSERT0,
-+ base + JH7100_RESET_STATUS0,
-+ jh7100_reset_asserted,
-+ JH7100_RSTN_END,
-+ THIS_MODULE);
-+}
-+
- static const struct of_device_id jh7100_reset_dt_ids[] = {
- { .compatible = "starfive,jh7100-reset" },
- { /* sentinel */ }
---- a/drivers/reset/starfive/reset-starfive-jh71x0.c
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -10,51 +10,18 @@
- #include <linux/io.h>
- #include <linux/io-64-nonatomic-lo-hi.h>
- #include <linux/iopoll.h>
--#include <linux/platform_device.h>
- #include <linux/reset-controller.h>
- #include <linux/spinlock.h>
-
- #include "reset-starfive-jh71x0.h"
-
--#include <dt-bindings/reset/starfive-jh7100.h>
--
--/* register offsets */
--#define JH7100_RESET_ASSERT0 0x00
--#define JH7100_RESET_ASSERT1 0x04
--#define JH7100_RESET_ASSERT2 0x08
--#define JH7100_RESET_ASSERT3 0x0c
--#define JH7100_RESET_STATUS0 0x10
--#define JH7100_RESET_STATUS1 0x14
--#define JH7100_RESET_STATUS2 0x18
--#define JH7100_RESET_STATUS3 0x1c
--
--/*
-- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-- * line 32m + n, and writing a 0 deasserts the same line.
-- * Most reset lines have their status inverted so a 0 bit in the STATUS
-- * register means the line is asserted and a 1 means it's deasserted. A few
-- * lines don't though, so store the expected value of the status registers when
-- * all lines are asserted.
-- */
--static const u64 jh7100_reset_asserted[2] = {
-- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-- /* STATUS3 */
-- 0,
--};
--
- struct jh7100_reset {
- struct reset_controller_dev rcdev;
- /* protect registers against concurrent read-modify-write */
- spinlock_t lock;
-- void __iomem *base;
-+ void __iomem *assert;
-+ void __iomem *status;
-+ const u64 *asserted;
- };
-
- static inline struct jh7100_reset *
-@@ -69,9 +36,9 @@ static int jh7100_reset_update(struct re
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 done = jh7100_reset_asserted[offset] & mask;
-+ void __iomem *reg_assert = data->assert + offset * sizeof(u64);
-+ void __iomem *reg_status = data->status + offset * sizeof(u64);
-+ u64 done = data->asserted ? data->asserted[offset] & mask : 0;
- u64 value;
- unsigned long flags;
- int ret;
-@@ -125,10 +92,10 @@ static int jh7100_reset_status(struct re
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ void __iomem *reg_status = data->status + offset * sizeof(u64);
- u64 value = readq(reg_status);
-
-- return !((value ^ jh7100_reset_asserted[offset]) & mask);
-+ return !((value ^ data->asserted[offset]) & mask);
- }
-
- static const struct reset_control_ops jh7100_reset_ops = {
-@@ -138,25 +105,28 @@ static const struct reset_control_ops jh
- .status = jh7100_reset_status,
- };
-
--int jh7100_reset_probe(struct platform_device *pdev)
-+int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+ void __iomem *assert, void __iomem *status,
-+ const u64 *asserted, unsigned int nr_resets,
-+ struct module *owner)
- {
- struct jh7100_reset *data;
-
-- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
-- data->base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(data->base))
-- return PTR_ERR(data->base);
--
- data->rcdev.ops = &jh7100_reset_ops;
-- data->rcdev.owner = THIS_MODULE;
-- data->rcdev.nr_resets = JH7100_RSTN_END;
-- data->rcdev.dev = &pdev->dev;
-- data->rcdev.of_node = pdev->dev.of_node;
-+ data->rcdev.owner = owner;
-+ data->rcdev.nr_resets = nr_resets;
-+ data->rcdev.dev = dev;
-+ data->rcdev.of_node = of_node;
-+
- spin_lock_init(&data->lock);
-+ data->assert = assert;
-+ data->status = status;
-+ data->asserted = asserted;
-
-- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
-+ return devm_reset_controller_register(dev, &data->rcdev);
- }
--EXPORT_SYMBOL_GPL(jh7100_reset_probe);
-+EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
---- a/drivers/reset/starfive/reset-starfive-jh71x0.h
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -6,6 +6,9 @@
- #ifndef __RESET_STARFIVE_JH71X0_H
- #define __RESET_STARFIVE_JH71X0_H
-
--int jh7100_reset_probe(struct platform_device *pdev);
-+int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+ void __iomem *assert, void __iomem *status,
-+ const u64 *asserted, unsigned int nr_resets,
-+ struct module *owner);
-
- #endif /* __RESET_STARFIVE_JH71X0_H */
diff --git a/target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch b/target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch
deleted file mode 100644
index 144d847725..0000000000
--- a/target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From 798b9b4681be53ddbf1d8db8a88ff19aaaca500f Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:23 +0800
-Subject: [PATCH 011/122] reset: starfive: Rename "jh7100" to "jh71x0" for the
- common code
-
-For the common code will be shared with the StarFive JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../reset/starfive/reset-starfive-jh7100.c | 2 +-
- .../reset/starfive/reset-starfive-jh71x0.c | 50 +++++++++----------
- .../reset/starfive/reset-starfive-jh71x0.h | 2 +-
- 3 files changed, 27 insertions(+), 27 deletions(-)
-
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -51,7 +51,7 @@ static int __init jh7100_reset_probe(str
- if (IS_ERR(base))
- return PTR_ERR(base);
-
-- return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
-+ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
- base + JH7100_RESET_ASSERT0,
- base + JH7100_RESET_STATUS0,
- jh7100_reset_asserted,
---- a/drivers/reset/starfive/reset-starfive-jh71x0.c
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
-- * Reset driver for the StarFive JH7100 SoC
-+ * Reset driver for the StarFive JH71X0 SoCs
- *
- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
- */
-@@ -15,7 +15,7 @@
-
- #include "reset-starfive-jh71x0.h"
-
--struct jh7100_reset {
-+struct jh71x0_reset {
- struct reset_controller_dev rcdev;
- /* protect registers against concurrent read-modify-write */
- spinlock_t lock;
-@@ -24,16 +24,16 @@ struct jh7100_reset {
- const u64 *asserted;
- };
-
--static inline struct jh7100_reset *
--jh7100_reset_from(struct reset_controller_dev *rcdev)
-+static inline struct jh71x0_reset *
-+jh71x0_reset_from(struct reset_controller_dev *rcdev)
- {
-- return container_of(rcdev, struct jh7100_reset, rcdev);
-+ return container_of(rcdev, struct jh71x0_reset, rcdev);
- }
-
--static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
- unsigned long id, bool assert)
- {
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
- void __iomem *reg_assert = data->assert + offset * sizeof(u64);
-@@ -62,34 +62,34 @@ static int jh7100_reset_update(struct re
- return ret;
- }
-
--static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_assert(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
-- return jh7100_reset_update(rcdev, id, true);
-+ return jh71x0_reset_update(rcdev, id, true);
- }
-
--static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_deassert(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
-- return jh7100_reset_update(rcdev, id, false);
-+ return jh71x0_reset_update(rcdev, id, false);
- }
-
--static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_reset(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
- int ret;
-
-- ret = jh7100_reset_assert(rcdev, id);
-+ ret = jh71x0_reset_assert(rcdev, id);
- if (ret)
- return ret;
-
-- return jh7100_reset_deassert(rcdev, id);
-+ return jh71x0_reset_deassert(rcdev, id);
- }
-
--static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
- void __iomem *reg_status = data->status + offset * sizeof(u64);
-@@ -98,25 +98,25 @@ static int jh7100_reset_status(struct re
- return !((value ^ data->asserted[offset]) & mask);
- }
-
--static const struct reset_control_ops jh7100_reset_ops = {
-- .assert = jh7100_reset_assert,
-- .deassert = jh7100_reset_deassert,
-- .reset = jh7100_reset_reset,
-- .status = jh7100_reset_status,
-+static const struct reset_control_ops jh71x0_reset_ops = {
-+ .assert = jh71x0_reset_assert,
-+ .deassert = jh71x0_reset_deassert,
-+ .reset = jh71x0_reset_reset,
-+ .status = jh71x0_reset_status,
- };
-
--int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
- const u64 *asserted, unsigned int nr_resets,
- struct module *owner)
- {
-- struct jh7100_reset *data;
-+ struct jh71x0_reset *data;
-
- data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
-- data->rcdev.ops = &jh7100_reset_ops;
-+ data->rcdev.ops = &jh71x0_reset_ops;
- data->rcdev.owner = owner;
- data->rcdev.nr_resets = nr_resets;
- data->rcdev.dev = dev;
-@@ -129,4 +129,4 @@ int reset_starfive_jh7100_register(struc
-
- return devm_reset_controller_register(dev, &data->rcdev);
- }
--EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
-+EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register);
---- a/drivers/reset/starfive/reset-starfive-jh71x0.h
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -6,7 +6,7 @@
- #ifndef __RESET_STARFIVE_JH71X0_H
- #define __RESET_STARFIVE_JH71X0_H
-
--int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
- const u64 *asserted, unsigned int nr_resets,
- struct module *owner);
diff --git a/target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch b/target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch
deleted file mode 100644
index 459ac5a3b6..0000000000
--- a/target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 365bb978e5e11a16c362d9c2c64d7bf8d04999df Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:24 +0800
-Subject: [PATCH 012/122] reset: starfive: jh71x0: Use 32bit I/O on 32bit
- registers
-
-We currently use 64bit I/O on the 32bit registers. This works because
-there are an even number of assert and status registers, so they're only
-ever accessed in pairs on 64bit boundaries.
-
-There are however other reset controllers for audio and video on the
-JH7100 SoC with only one status register that isn't 64bit aligned so
-64bit I/O results in an unaligned access exception.
-
-Switch to 32bit I/O in preparation for supporting these resets too.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../reset/starfive/reset-starfive-jh7100.c | 14 ++++-----
- .../reset/starfive/reset-starfive-jh71x0.c | 31 +++++++++----------
- .../reset/starfive/reset-starfive-jh71x0.h | 2 +-
- 3 files changed, 23 insertions(+), 24 deletions(-)
-
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -30,16 +30,16 @@
- * lines don't though, so store the expected value of the status registers when
- * all lines are asserted.
- */
--static const u64 jh7100_reset_asserted[2] = {
-+static const u32 jh7100_reset_asserted[4] = {
- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ BIT(JH7100_RST_U74 % 32) |
-+ BIT(JH7100_RST_VP6_DRESET % 32) |
-+ BIT(JH7100_RST_VP6_BRESET % 32),
- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ BIT(JH7100_RST_HIFI4_DRESET % 32) |
-+ BIT(JH7100_RST_HIFI4_BRESET % 32),
- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-+ BIT(JH7100_RST_E24 % 32),
- /* STATUS3 */
- 0,
- };
---- a/drivers/reset/starfive/reset-starfive-jh71x0.c
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -8,7 +8,6 @@
- #include <linux/bitmap.h>
- #include <linux/device.h>
- #include <linux/io.h>
--#include <linux/io-64-nonatomic-lo-hi.h>
- #include <linux/iopoll.h>
- #include <linux/reset-controller.h>
- #include <linux/spinlock.h>
-@@ -21,7 +20,7 @@ struct jh71x0_reset {
- spinlock_t lock;
- void __iomem *assert;
- void __iomem *status;
-- const u64 *asserted;
-+ const u32 *asserted;
- };
-
- static inline struct jh71x0_reset *
-@@ -34,12 +33,12 @@ static int jh71x0_reset_update(struct re
- unsigned long id, bool assert)
- {
- struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->assert + offset * sizeof(u64);
-- void __iomem *reg_status = data->status + offset * sizeof(u64);
-- u64 done = data->asserted ? data->asserted[offset] & mask : 0;
-- u64 value;
-+ unsigned long offset = id / 32;
-+ u32 mask = BIT(id % 32);
-+ void __iomem *reg_assert = data->assert + offset * sizeof(u32);
-+ void __iomem *reg_status = data->status + offset * sizeof(u32);
-+ u32 done = data->asserted ? data->asserted[offset] & mask : 0;
-+ u32 value;
- unsigned long flags;
- int ret;
-
-@@ -48,15 +47,15 @@ static int jh71x0_reset_update(struct re
-
- spin_lock_irqsave(&data->lock, flags);
-
-- value = readq(reg_assert);
-+ value = readl(reg_assert);
- if (assert)
- value |= mask;
- else
- value &= ~mask;
-- writeq(value, reg_assert);
-+ writel(value, reg_assert);
-
- /* if the associated clock is gated, deasserting might otherwise hang forever */
-- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-+ ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-
- spin_unlock_irqrestore(&data->lock, flags);
- return ret;
-@@ -90,10 +89,10 @@ static int jh71x0_reset_status(struct re
- unsigned long id)
- {
- struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->status + offset * sizeof(u64);
-- u64 value = readq(reg_status);
-+ unsigned long offset = id / 32;
-+ u32 mask = BIT(id % 32);
-+ void __iomem *reg_status = data->status + offset * sizeof(u32);
-+ u32 value = readl(reg_status);
-
- return !((value ^ data->asserted[offset]) & mask);
- }
-@@ -107,7 +106,7 @@ static const struct reset_control_ops jh
-
- int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
-- const u64 *asserted, unsigned int nr_resets,
-+ const u32 *asserted, unsigned int nr_resets,
- struct module *owner)
- {
- struct jh71x0_reset *data;
---- a/drivers/reset/starfive/reset-starfive-jh71x0.h
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -8,7 +8,7 @@
-
- int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
-- const u64 *asserted, unsigned int nr_resets,
-+ const u32 *asserted, unsigned int nr_resets,
- struct module *owner);
-
- #endif /* __RESET_STARFIVE_JH71X0_H */
diff --git a/target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch b/target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch
deleted file mode 100644
index f272d5179b..0000000000
--- a/target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch
+++ /dev/null
@@ -1,557 +0,0 @@
-From eea853275c704f6c24a418a50715bc5ad68a6283 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:25 +0800
-Subject: [PATCH 013/122] clk: starfive: Add StarFive JH7110 system clock
- driver
-
-Add driver for the StarFive JH7110 system clock controller and
-register an auxiliary device for system reset controller which
-is named as "rst-sys".
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/Kconfig | 11 +
- drivers/clk/starfive/Makefile | 2 +
- .../clk/starfive/clk-starfive-jh7110-sys.c | 490 ++++++++++++++++++
- drivers/clk/starfive/clk-starfive-jh7110.h | 11 +
- 4 files changed, 514 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-sys.c
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110.h
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -20,3 +20,14 @@ config CLK_STARFIVE_JH7100_AUDIO
- help
- Say Y or M here to support the audio clocks on the StarFive JH7100
- SoC.
-+
-+config CLK_STARFIVE_JH7110_SYS
-+ bool "StarFive JH7110 system clock support"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default ARCH_STARFIVE
-+ help
-+ Say yes here to support the system clock controller on the
-+ StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -3,3 +3,5 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk
-
- obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
-+
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -0,0 +1,490 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 System Clock Driver
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/auxiliary_bus.h>
-+#include <linux/clk-provider.h>
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_SYSCLK_OSC (JH7110_SYSCLK_END + 0)
-+#define JH7110_SYSCLK_GMAC1_RMII_REFIN (JH7110_SYSCLK_END + 1)
-+#define JH7110_SYSCLK_GMAC1_RGMII_RXIN (JH7110_SYSCLK_END + 2)
-+#define JH7110_SYSCLK_I2STX_BCLK_EXT (JH7110_SYSCLK_END + 3)
-+#define JH7110_SYSCLK_I2STX_LRCK_EXT (JH7110_SYSCLK_END + 4)
-+#define JH7110_SYSCLK_I2SRX_BCLK_EXT (JH7110_SYSCLK_END + 5)
-+#define JH7110_SYSCLK_I2SRX_LRCK_EXT (JH7110_SYSCLK_END + 6)
-+#define JH7110_SYSCLK_TDM_EXT (JH7110_SYSCLK_END + 7)
-+#define JH7110_SYSCLK_MCLK_EXT (JH7110_SYSCLK_END + 8)
-+#define JH7110_SYSCLK_PLL0_OUT (JH7110_SYSCLK_END + 9)
-+#define JH7110_SYSCLK_PLL1_OUT (JH7110_SYSCLK_END + 10)
-+#define JH7110_SYSCLK_PLL2_OUT (JH7110_SYSCLK_END + 11)
-+
-+static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
-+ /* root */
-+ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
-+ JH7110_SYSCLK_OSC,
-+ JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
-+ JH7110_SYSCLK_PLL2_OUT,
-+ JH7110_SYSCLK_PLL1_OUT),
-+ JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
-+ JH7110_SYSCLK_PLL0_OUT,
-+ JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
-+ JH7110_SYSCLK_OSC,
-+ JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_AXI_CFG0, "axi_cfg0", 3, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_STG_AXIAHB, "stg_axiahb", 2, JH7110_SYSCLK_AXI_CFG0),
-+ JH71X0_GATE(JH7110_SYSCLK_AHB0, "ahb0", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_SYSCLK_AHB1, "ahb1", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0__DIV(JH7110_SYSCLK_APB_BUS, "apb_bus", 8, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_SYSCLK_APB0, "apb0", CLK_IS_CRITICAL, JH7110_SYSCLK_APB_BUS),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL0_DIV2, "pll0_div2", 2, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV2, "pll1_div2", 2, JH7110_SYSCLK_PLL1_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
-+ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
-+ JH7110_SYSCLK_MCLK_INNER,
-+ JH7110_SYSCLK_MCLK_EXT),
-+ JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
-+ JH71X0_MDIV(JH7110_SYSCLK_ISP_2X, "isp_2x", 8, 2,
-+ JH7110_SYSCLK_PLL2_OUT,
-+ JH7110_SYSCLK_PLL1_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_ISP_AXI, "isp_axi", 4, JH7110_SYSCLK_ISP_2X),
-+ JH71X0_GDIV(JH7110_SYSCLK_GCLK0, "gclk0", 0, 62, JH7110_SYSCLK_PLL0_DIV2),
-+ JH71X0_GDIV(JH7110_SYSCLK_GCLK1, "gclk1", 0, 62, JH7110_SYSCLK_PLL1_DIV2),
-+ JH71X0_GDIV(JH7110_SYSCLK_GCLK2, "gclk2", 0, 62, JH7110_SYSCLK_PLL2_DIV2),
-+ /* cores */
-+ JH71X0_GATE(JH7110_SYSCLK_CORE, "core", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE1, "core1", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE2, "core2", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE3, "core3", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE4, "core4", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_DEBUG, "debug", 0, JH7110_SYSCLK_CPU_BUS),
-+ JH71X0__DIV(JH7110_SYSCLK_RTC_TOGGLE, "rtc_toggle", 6, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE0, "trace0", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE1, "trace1", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE2, "trace2", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE3, "trace3", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE4, "trace4", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE_COM, "trace_com", 0, JH7110_SYSCLK_CPU_BUS),
-+ /* noc */
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_CPU_AXI, "noc_bus_cpu_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_CPU_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI, "noc_bus_axicfg0_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AXI_CFG0),
-+ /* ddr */
-+ JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
-+ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
-+ JH7110_SYSCLK_OSC_DIV2,
-+ JH7110_SYSCLK_PLL1_DIV2,
-+ JH7110_SYSCLK_PLL1_DIV4,
-+ JH7110_SYSCLK_PLL1_DIV8),
-+ JH71X0_GATE(JH7110_SYSCLK_DDR_AXI, "ddr_axi", CLK_IS_CRITICAL, JH7110_SYSCLK_DDR_BUS),
-+ /* gpu */
-+ JH71X0__DIV(JH7110_SYSCLK_GPU_CORE, "gpu_core", 7, JH7110_SYSCLK_GPU_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_GPU_CORE_CLK, "gpu_core_clk", 0, JH7110_SYSCLK_GPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_GPU_SYS_CLK, "gpu_sys_clk", 0, JH7110_SYSCLK_ISP_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_GPU_APB, "gpu_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_GPU_RTC_TOGGLE, "gpu_rtc_toggle", 0, 12, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_GPU_AXI, "noc_bus_gpu_axi", 0, JH7110_SYSCLK_GPU_CORE),
-+ /* isp */
-+ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_CORE, "isp_top_core", 0, JH7110_SYSCLK_ISP_2X),
-+ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_AXI, "isp_top_axi", 0, JH7110_SYSCLK_ISP_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_ISP_AXI, "noc_bus_isp_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_ISP_AXI),
-+ /* hifi4 */
-+ JH71X0__DIV(JH7110_SYSCLK_HIFI4_CORE, "hifi4_core", 15, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_HIFI4_AXI, "hifi4_axi", 2, JH7110_SYSCLK_HIFI4_CORE),
-+ /* axi_cfg1 */
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_MAIN, "axi_cfg1_main", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_ISP_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_AHB, "axi_cfg1_ahb", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AHB0),
-+ /* vout */
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_SRC, "vout_src", 0, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_VOUT_AXI, "vout_axi", 7, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_DISP_AXI, "noc_bus_disp_axi", 0, JH7110_SYSCLK_VOUT_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AHB, "vout_top_ahb", 0, JH7110_SYSCLK_AHB1),
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AXI, "vout_top_axi", 0, JH7110_SYSCLK_VOUT_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK, "vout_top_hdmitx0_mclk", 0,
-+ JH7110_SYSCLK_MCLK),
-+ JH71X0__DIV(JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF, "vout_top_mipiphy_ref", 2,
-+ JH7110_SYSCLK_OSC),
-+ /* jpegc */
-+ JH71X0__DIV(JH7110_SYSCLK_JPEGC_AXI, "jpegc_axi", 16, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_AXI, "codaj12_axi", 0, JH7110_SYSCLK_JPEGC_AXI),
-+ JH71X0_GDIV(JH7110_SYSCLK_CODAJ12_CORE, "codaj12_core", 0, 16, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_APB, "codaj12_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* vdec */
-+ JH71X0__DIV(JH7110_SYSCLK_VDEC_AXI, "vdec_axi", 7, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE511_AXI, "wave511_axi", 0, JH7110_SYSCLK_VDEC_AXI),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_BPU, "wave511_bpu", 0, 7, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_VCE, "wave511_vce", 0, 7, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE511_APB, "wave511_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_VDEC_JPG, "vdec_jpg", 0, JH7110_SYSCLK_JPEGC_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_VDEC_MAIN, "vdec_main", 0, JH7110_SYSCLK_VDEC_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VDEC_AXI, "noc_bus_vdec_axi", 0, JH7110_SYSCLK_VDEC_AXI),
-+ /* venc */
-+ JH71X0__DIV(JH7110_SYSCLK_VENC_AXI, "venc_axi", 15, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_AXI, "wave420l_axi", 0, JH7110_SYSCLK_VENC_AXI),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_BPU, "wave420l_bpu", 0, 15, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_VCE, "wave420l_vce", 0, 15, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_APB, "wave420l_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VENC_AXI, "noc_bus_venc_axi", 0, JH7110_SYSCLK_VENC_AXI),
-+ /* axi_cfg0 */
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN_DIV, "axi_cfg0_main_div", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AHB1),
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN, "axi_cfg0_main", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AXI_CFG0),
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_HIFI4, "axi_cfg0_hifi4", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_HIFI4_AXI),
-+ /* intmem */
-+ JH71X0_GATE(JH7110_SYSCLK_AXIMEM2_AXI, "aximem2_axi", 0, JH7110_SYSCLK_AXI_CFG0),
-+ /* qspi */
-+ JH71X0_GATE(JH7110_SYSCLK_QSPI_AHB, "qspi_ahb", 0, JH7110_SYSCLK_AHB1),
-+ JH71X0_GATE(JH7110_SYSCLK_QSPI_APB, "qspi_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0__DIV(JH7110_SYSCLK_QSPI_REF_SRC, "qspi_ref_src", 16, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GMUX(JH7110_SYSCLK_QSPI_REF, "qspi_ref", 0, 2,
-+ JH7110_SYSCLK_OSC,
-+ JH7110_SYSCLK_QSPI_REF_SRC),
-+ /* sdio */
-+ JH71X0_GATE(JH7110_SYSCLK_SDIO0_AHB, "sdio0_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SDIO1_AHB, "sdio1_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_SDIO0_SDCARD, "sdio0_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
-+ JH71X0_GDIV(JH7110_SYSCLK_SDIO1_SDCARD, "sdio1_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
-+ /* stg */
-+ JH71X0__DIV(JH7110_SYSCLK_USB_125M, "usb_125m", 15, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_STG_AXI, "noc_bus_stg_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_NOCSTG_BUS),
-+ /* gmac1 */
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AHB, "gmac1_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AXI, "gmac1_axi", 0, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0__DIV(JH7110_SYSCLK_GMAC_SRC, "gmac_src", 7, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_GTXCLK, "gmac1_gtxclk", 15, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
-+ JH7110_SYSCLK_GMAC1_RMII_REFIN),
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-+ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
-+ JH7110_SYSCLK_GMAC1_RGMII_RXIN,
-+ JH7110_SYSCLK_GMAC1_RMII_RTX),
-+ JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
-+ JH71X0_GMUX(JH7110_SYSCLK_GMAC1_TX, "gmac1_tx",
-+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
-+ JH7110_SYSCLK_GMAC1_GTXCLK,
-+ JH7110_SYSCLK_GMAC1_RMII_RTX),
-+ JH71X0__INV(JH7110_SYSCLK_GMAC1_TX_INV, "gmac1_tx_inv", JH7110_SYSCLK_GMAC1_TX),
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_GTXC, "gmac1_gtxc", 0, JH7110_SYSCLK_GMAC1_GTXCLK),
-+ /* gmac0 */
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_GTXCLK, "gmac0_gtxclk", 0, 15, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_PTP, "gmac0_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC_PHY, "gmac_phy", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC0_GTXC, "gmac0_gtxc", 0, JH7110_SYSCLK_GMAC0_GTXCLK),
-+ /* apb misc */
-+ JH71X0_GATE(JH7110_SYSCLK_IOMUX_APB, "iomux_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_MAILBOX_APB, "mailbox_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_INT_CTRL_APB, "int_ctrl_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* can0 */
-+ JH71X0_GATE(JH7110_SYSCLK_CAN0_APB, "can0_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN0_TIMER, "can0_timer", 0, 24, JH7110_SYSCLK_OSC),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN0_CAN, "can0_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
-+ /* can1 */
-+ JH71X0_GATE(JH7110_SYSCLK_CAN1_APB, "can1_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN1_TIMER, "can1_timer", 0, 24, JH7110_SYSCLK_OSC),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN1_CAN, "can1_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
-+ /* pwm */
-+ JH71X0_GATE(JH7110_SYSCLK_PWM_APB, "pwm_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* wdt */
-+ JH71X0_GATE(JH7110_SYSCLK_WDT_APB, "wdt_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_WDT_CORE, "wdt_core", 0, JH7110_SYSCLK_OSC),
-+ /* timer */
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER_APB, "timer_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER0, "timer0", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER1, "timer1", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER2, "timer2", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER3, "timer3", 0, JH7110_SYSCLK_OSC),
-+ /* temp sensor */
-+ JH71X0_GATE(JH7110_SYSCLK_TEMP_APB, "temp_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_TEMP_CORE, "temp_core", 0, 24, JH7110_SYSCLK_OSC),
-+ /* spi */
-+ JH71X0_GATE(JH7110_SYSCLK_SPI0_APB, "spi0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI1_APB, "spi1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI2_APB, "spi2_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI3_APB, "spi3_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI4_APB, "spi4_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI5_APB, "spi5_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI6_APB, "spi6_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* i2c */
-+ JH71X0_GATE(JH7110_SYSCLK_I2C0_APB, "i2c0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C1_APB, "i2c1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C2_APB, "i2c2_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C3_APB, "i2c3_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C4_APB, "i2c4_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C5_APB, "i2c5_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C6_APB, "i2c6_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* uart */
-+ JH71X0_GATE(JH7110_SYSCLK_UART0_APB, "uart0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_UART0_CORE, "uart0_core", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_UART1_APB, "uart1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_UART1_CORE, "uart1_core", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_UART2_APB, "uart2_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_UART2_CORE, "uart2_core", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_UART3_APB, "uart3_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_UART3_CORE, "uart3_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_UART4_APB, "uart4_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_UART4_CORE, "uart4_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_UART5_APB, "uart5_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_UART5_CORE, "uart5_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
-+ /* pwmdac */
-+ JH71X0_GATE(JH7110_SYSCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_PWMDAC_CORE, "pwmdac_core", 0, 256, JH7110_SYSCLK_AUDIO_ROOT),
-+ /* spdif */
-+ JH71X0_GATE(JH7110_SYSCLK_SPDIF_APB, "spdif_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPDIF_CORE, "spdif_core", 0, JH7110_SYSCLK_MCLK),
-+ /* i2stx0 */
-+ JH71X0_GATE(JH7110_SYSCLK_I2STX0_APB, "i2stx0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_I2STX0_BCLK_MST, "i2stx0_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_MST_INV, "i2stx0_bclk_mst_inv",
-+ JH7110_SYSCLK_I2STX0_BCLK_MST),
-+ JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
-+ JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
-+ JH7110_SYSCLK_I2STX0_BCLK_MST),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
-+ JH7110_SYSCLK_I2STX0_BCLK_MST,
-+ JH7110_SYSCLK_I2STX_BCLK_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
-+ JH7110_SYSCLK_I2STX0_LRCK_MST,
-+ JH7110_SYSCLK_I2STX_LRCK_EXT),
-+ /* i2stx1 */
-+ JH71X0_GATE(JH7110_SYSCLK_I2STX1_APB, "i2stx1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_I2STX1_BCLK_MST, "i2stx1_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_MST_INV, "i2stx1_bclk_mst_inv",
-+ JH7110_SYSCLK_I2STX1_BCLK_MST),
-+ JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
-+ JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
-+ JH7110_SYSCLK_I2STX1_BCLK_MST),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
-+ JH7110_SYSCLK_I2STX1_BCLK_MST,
-+ JH7110_SYSCLK_I2STX_BCLK_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
-+ JH7110_SYSCLK_I2STX1_LRCK_MST,
-+ JH7110_SYSCLK_I2STX_LRCK_EXT),
-+ /* i2srx */
-+ JH71X0_GATE(JH7110_SYSCLK_I2SRX_APB, "i2srx_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_I2SRX_BCLK_MST, "i2srx_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
-+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_MST_INV, "i2srx_bclk_mst_inv",
-+ JH7110_SYSCLK_I2SRX_BCLK_MST),
-+ JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
-+ JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
-+ JH7110_SYSCLK_I2SRX_BCLK_MST),
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
-+ JH7110_SYSCLK_I2SRX_BCLK_MST,
-+ JH7110_SYSCLK_I2SRX_BCLK_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
-+ JH7110_SYSCLK_I2SRX_LRCK_MST,
-+ JH7110_SYSCLK_I2SRX_LRCK_EXT),
-+ /* pdm */
-+ JH71X0_GDIV(JH7110_SYSCLK_PDM_DMIC, "pdm_dmic", 0, 64, JH7110_SYSCLK_MCLK),
-+ JH71X0_GATE(JH7110_SYSCLK_PDM_APB, "pdm_apb", 0, JH7110_SYSCLK_APB0),
-+ /* tdm */
-+ JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
-+ JH7110_SYSCLK_TDM_INTERNAL,
-+ JH7110_SYSCLK_TDM_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
-+ /* jtag */
-+ JH71X0__DIV(JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG, "jtag_certification_trng", 4,
-+ JH7110_SYSCLK_OSC),
-+};
-+
-+static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_SYSCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static void jh7110_reset_unregister_adev(void *_adev)
-+{
-+ struct auxiliary_device *adev = _adev;
-+
-+ auxiliary_device_delete(adev);
-+}
-+
-+static void jh7110_reset_adev_release(struct device *dev)
-+{
-+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
-+
-+ auxiliary_device_uninit(adev);
-+}
-+
-+int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
-+ const char *adev_name,
-+ u32 adev_id)
-+{
-+ struct auxiliary_device *adev;
-+ int ret;
-+
-+ adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
-+ if (!adev)
-+ return -ENOMEM;
-+
-+ adev->name = adev_name;
-+ adev->dev.parent = priv->dev;
-+ adev->dev.release = jh7110_reset_adev_release;
-+ adev->id = adev_id;
-+
-+ ret = auxiliary_device_init(adev);
-+ if (ret)
-+ return ret;
-+
-+ ret = auxiliary_device_add(adev);
-+ if (ret) {
-+ auxiliary_device_uninit(adev);
-+ return ret;
-+ }
-+
-+ return devm_add_action_or_reset(priv->dev,
-+ jh7110_reset_unregister_adev, adev);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);
-+
-+static int __init jh7110_syscrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_SYSCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ dev_set_drvdata(priv->dev, (void *)(&priv->base));
-+
-+ /*
-+ * These PLL clocks are not actually fixed factor clocks and can be
-+ * controlled by the syscon registers of JH7110. They will be dropped
-+ * and registered in the PLL clock driver instead.
-+ */
-+ /* 24MHz -> 1000.0MHz */
-+ priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",
-+ "osc", 0, 125, 3);
-+ if (IS_ERR(priv->pll[0]))
-+ return PTR_ERR(priv->pll[0]);
-+
-+ /* 24MHz -> 1066.0MHz */
-+ priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",
-+ "osc", 0, 533, 12);
-+ if (IS_ERR(priv->pll[1]))
-+ return PTR_ERR(priv->pll[1]);
-+
-+ /* 24MHz -> 1188.0MHz */
-+ priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",
-+ "osc", 0, 99, 2);
-+ if (IS_ERR(priv->pll[2]))
-+ return PTR_ERR(priv->pll[2]);
-+
-+ for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {
-+ u32 max = jh7110_sysclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_sysclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_sysclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_sysclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_SYSCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx == JH7110_SYSCLK_OSC)
-+ parents[i].fw_name = "osc";
-+ else if (pidx == JH7110_SYSCLK_GMAC1_RMII_REFIN)
-+ parents[i].fw_name = "gmac1_rmii_refin";
-+ else if (pidx == JH7110_SYSCLK_GMAC1_RGMII_RXIN)
-+ parents[i].fw_name = "gmac1_rgmii_rxin";
-+ else if (pidx == JH7110_SYSCLK_I2STX_BCLK_EXT)
-+ parents[i].fw_name = "i2stx_bclk_ext";
-+ else if (pidx == JH7110_SYSCLK_I2STX_LRCK_EXT)
-+ parents[i].fw_name = "i2stx_lrck_ext";
-+ else if (pidx == JH7110_SYSCLK_I2SRX_BCLK_EXT)
-+ parents[i].fw_name = "i2srx_bclk_ext";
-+ else if (pidx == JH7110_SYSCLK_I2SRX_LRCK_EXT)
-+ parents[i].fw_name = "i2srx_lrck_ext";
-+ else if (pidx == JH7110_SYSCLK_TDM_EXT)
-+ parents[i].fw_name = "tdm_ext";
-+ else if (pidx == JH7110_SYSCLK_MCLK_EXT)
-+ parents[i].fw_name = "mclk_ext";
-+ else
-+ parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_sysclk_get, priv);
-+ if (ret)
-+ return ret;
-+
-+ return jh7110_reset_controller_register(priv, "rst-sys", 0);
-+}
-+
-+static const struct of_device_id jh7110_syscrg_match[] = {
-+ { .compatible = "starfive,jh7110-syscrg" },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver jh7110_syscrg_driver = {
-+ .driver = {
-+ .name = "clk-starfive-jh7110-sys",
-+ .of_match_table = jh7110_syscrg_match,
-+ .suppress_bind_attrs = true,
-+ },
-+};
-+builtin_platform_driver_probe(jh7110_syscrg_driver, jh7110_syscrg_probe);
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
-@@ -0,0 +1,11 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __CLK_STARFIVE_JH7110_H
-+#define __CLK_STARFIVE_JH7110_H
-+
-+#include "clk-starfive-jh71x0.h"
-+
-+int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
-+ const char *adev_name,
-+ u32 adev_id);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch b/target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch
deleted file mode 100644
index 4986c110f7..0000000000
--- a/target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From 6b9f7a65cd2e9cc4bdc2ee3c3fb46bef4568af0a Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:26 +0800
-Subject: [PATCH 014/122] clk: starfive: Add StarFive JH7110 always-on clock
- driver
-
-Add driver for the StarFive JH7110 always-on clock controller
-and register an auxiliary device for always-on reset controller
-which is named as "rst-aon".
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/Kconfig | 11 ++
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-aon.c | 156 ++++++++++++++++++
- 3 files changed, 168 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-aon.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -31,3 +31,14 @@ config CLK_STARFIVE_JH7110_SYS
- help
- Say yes here to support the system clock controller on the
- StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_AON
-+ tristate "StarFive JH7110 always-on clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the always-on clock controller on the
-+ StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -5,3 +5,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
-
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
-@@ -0,0 +1,156 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 Always-On Clock Driver
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_AONCLK_OSC (JH7110_AONCLK_END + 0)
-+#define JH7110_AONCLK_GMAC0_RMII_REFIN (JH7110_AONCLK_END + 1)
-+#define JH7110_AONCLK_GMAC0_RGMII_RXIN (JH7110_AONCLK_END + 2)
-+#define JH7110_AONCLK_STG_AXIAHB (JH7110_AONCLK_END + 3)
-+#define JH7110_AONCLK_APB_BUS (JH7110_AONCLK_END + 4)
-+#define JH7110_AONCLK_GMAC0_GTXCLK (JH7110_AONCLK_END + 5)
-+#define JH7110_AONCLK_RTC_OSC (JH7110_AONCLK_END + 6)
-+
-+static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
-+ /* source */
-+ JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
-+ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
-+ JH7110_AONCLK_OSC_DIV4,
-+ JH7110_AONCLK_OSC),
-+ /* gmac0 */
-+ JH71X0_GATE(JH7110_AONCLK_GMAC0_AHB, "gmac0_ahb", 0, JH7110_AONCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_AONCLK_GMAC0_AXI, "gmac0_axi", 0, JH7110_AONCLK_STG_AXIAHB),
-+ JH71X0__DIV(JH7110_AONCLK_GMAC0_RMII_RTX, "gmac0_rmii_rtx", 30,
-+ JH7110_AONCLK_GMAC0_RMII_REFIN),
-+ JH71X0_GMUX(JH7110_AONCLK_GMAC0_TX, "gmac0_tx",
-+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
-+ JH7110_AONCLK_GMAC0_GTXCLK,
-+ JH7110_AONCLK_GMAC0_RMII_RTX),
-+ JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
-+ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
-+ JH7110_AONCLK_GMAC0_RGMII_RXIN,
-+ JH7110_AONCLK_GMAC0_RMII_RTX),
-+ JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
-+ /* otpc */
-+ JH71X0_GATE(JH7110_AONCLK_OTPC_APB, "otpc_apb", 0, JH7110_AONCLK_APB_BUS),
-+ /* rtc */
-+ JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
-+ JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
-+ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
-+ JH7110_AONCLK_RTC_OSC,
-+ JH7110_AONCLK_RTC_INTERNAL),
-+ JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
-+};
-+
-+static struct clk_hw *jh7110_aonclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_AONCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static int jh7110_aoncrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_AONCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ dev_set_drvdata(priv->dev, (void *)(&priv->base));
-+
-+ for (idx = 0; idx < JH7110_AONCLK_END; idx++) {
-+ u32 max = jh7110_aonclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_aonclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_aonclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_aonclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_AONCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx == JH7110_AONCLK_OSC)
-+ parents[i].fw_name = "osc";
-+ else if (pidx == JH7110_AONCLK_GMAC0_RMII_REFIN)
-+ parents[i].fw_name = "gmac0_rmii_refin";
-+ else if (pidx == JH7110_AONCLK_GMAC0_RGMII_RXIN)
-+ parents[i].fw_name = "gmac0_rgmii_rxin";
-+ else if (pidx == JH7110_AONCLK_STG_AXIAHB)
-+ parents[i].fw_name = "stg_axiahb";
-+ else if (pidx == JH7110_AONCLK_APB_BUS)
-+ parents[i].fw_name = "apb_bus";
-+ else if (pidx == JH7110_AONCLK_GMAC0_GTXCLK)
-+ parents[i].fw_name = "gmac0_gtxclk";
-+ else if (pidx == JH7110_AONCLK_RTC_OSC)
-+ parents[i].fw_name = "rtc_osc";
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_aonclk_get, priv);
-+ if (ret)
-+ return ret;
-+
-+ return jh7110_reset_controller_register(priv, "rst-aon", 1);
-+}
-+
-+static const struct of_device_id jh7110_aoncrg_match[] = {
-+ { .compatible = "starfive,jh7110-aoncrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_aoncrg_match);
-+
-+static struct platform_driver jh7110_aoncrg_driver = {
-+ .probe = jh7110_aoncrg_probe,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-aon",
-+ .of_match_table = jh7110_aoncrg_match,
-+ },
-+};
-+module_platform_driver(jh7110_aoncrg_driver);
-+
-+MODULE_AUTHOR("Emil Renner Berthing");
-+MODULE_DESCRIPTION("StarFive JH7110 always-on clock driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch b/target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch
deleted file mode 100644
index 1a2a9d9991..0000000000
--- a/target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From ea2f40c943f4a6d39a2f3ea4660266250d37c95a Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:27 +0800
-Subject: [PATCH 015/122] reset: starfive: Add StarFive JH7110 reset driver
-
-Add auxiliary driver to support StarFive JH7110 system
-and always-on resets.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/starfive/Kconfig | 8 +++
- drivers/reset/starfive/Makefile | 1 +
- .../reset/starfive/reset-starfive-jh7110.c | 70 +++++++++++++++++++
- 3 files changed, 79 insertions(+)
- create mode 100644 drivers/reset/starfive/reset-starfive-jh7110.c
-
---- a/drivers/reset/starfive/Kconfig
-+++ b/drivers/reset/starfive/Kconfig
-@@ -10,3 +10,11 @@ config RESET_STARFIVE_JH7100
- default ARCH_STARFIVE
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
-+
-+config RESET_STARFIVE_JH7110
-+ bool "StarFive JH7110 Reset Driver"
-+ depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
-+ select RESET_STARFIVE_JH71X0
-+ default ARCH_STARFIVE
-+ help
-+ This enables the reset controller driver for the StarFive JH7110 SoC.
---- a/drivers/reset/starfive/Makefile
-+++ b/drivers/reset/starfive/Makefile
-@@ -2,3 +2,4 @@
- obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
-
- obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
-+obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
-@@ -0,0 +1,70 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Reset driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/auxiliary_bus.h>
-+
-+#include "reset-starfive-jh71x0.h"
-+
-+#include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+struct jh7110_reset_info {
-+ unsigned int nr_resets;
-+ unsigned int assert_offset;
-+ unsigned int status_offset;
-+};
-+
-+static const struct jh7110_reset_info jh7110_sys_info = {
-+ .nr_resets = JH7110_SYSRST_END,
-+ .assert_offset = 0x2F8,
-+ .status_offset = 0x308,
-+};
-+
-+static const struct jh7110_reset_info jh7110_aon_info = {
-+ .nr_resets = JH7110_AONRST_END,
-+ .assert_offset = 0x38,
-+ .status_offset = 0x3C,
-+};
-+
-+static int jh7110_reset_probe(struct auxiliary_device *adev,
-+ const struct auxiliary_device_id *id)
-+{
-+ struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
-+ void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
-+
-+ if (!info || !base)
-+ return -ENODEV;
-+
-+ return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
-+ *base + info->assert_offset,
-+ *base + info->status_offset,
-+ NULL,
-+ info->nr_resets,
-+ NULL);
-+}
-+
-+static const struct auxiliary_device_id jh7110_reset_ids[] = {
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-sys",
-+ .driver_data = (kernel_ulong_t)&jh7110_sys_info,
-+ },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-aon",
-+ .driver_data = (kernel_ulong_t)&jh7110_aon_info,
-+ },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
-+
-+static struct auxiliary_driver jh7110_reset_driver = {
-+ .probe = jh7110_reset_probe,
-+ .id_table = jh7110_reset_ids,
-+};
-+module_auxiliary_driver(jh7110_reset_driver);
-+
-+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH7110 reset driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch b/target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch
deleted file mode 100644
index d3f9a9cf22..0000000000
--- a/target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 17fecb06e9de3ae5bbf7aecc4d91e14517982f5c Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 17 May 2023 20:41:51 -0700
-Subject: [PATCH 016/122] MAINTAINERS: generalise StarFive clk/reset entries
-
-Update the MAINTAINERS entry for StarFive's clock and reset drivers to
-account for the addition of JH7110 support and Hal's role in that.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- MAINTAINERS | 16 +++++++++-------
- 1 file changed, 9 insertions(+), 7 deletions(-)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19657,12 +19657,13 @@ M: Emil Renner Berthing <kernel@esmil.dk
- S: Maintained
- F: arch/riscv/boot/dts/starfive/
-
--STARFIVE JH7100 CLOCK DRIVERS
-+STARFIVE JH71X0 CLOCK DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Hal Feng <hal.feng@starfivetech.com>
- S: Maintained
--F: Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
--F: drivers/clk/starfive/clk-starfive-jh7100*
--F: include/dt-bindings/clock/starfive-jh7100*.h
-+F: Documentation/devicetree/bindings/clock/starfive,jh71*.yaml
-+F: drivers/clk/starfive/clk-starfive-jh71*
-+F: include/dt-bindings/clock/starfive?jh71*.h
-
- STARFIVE JH7100 PINCTRL DRIVER
- M: Emil Renner Berthing <kernel@esmil.dk>
-@@ -19672,12 +19673,13 @@ F: Documentation/devicetree/bindings/pin
- F: drivers/pinctrl/starfive/
- F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
-
--STARFIVE JH7100 RESET CONTROLLER DRIVER
-+STARFIVE JH71X0 RESET CONTROLLER DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Hal Feng <hal.feng@starfivetech.com>
- S: Maintained
- F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
--F: drivers/reset/reset-starfive-jh7100.c
--F: include/dt-bindings/reset/starfive-jh7100.h
-+F: drivers/reset/starfive/reset-starfive-jh71*
-+F: include/dt-bindings/reset/starfive?jh71*.h
-
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
diff --git a/target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch b/target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch
deleted file mode 100644
index 9667f7256c..0000000000
--- a/target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From d9d4e0fb44a50cace195e1639cfb23e518e17e88 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@kernel.org>
-Date: Thu, 13 Apr 2023 13:55:28 -0700
-Subject: [PATCH 017/122] clk: starfive: Avoid casting iomem pointers
-
-Let's use a wrapper struct for the auxiliary_device made in
-jh7110_reset_controller_register() so that we can stop casting iomem
-pointers. The casts trip up tools like sparse, and make for some awkward
-casts that are largely unnecessary. While we're here, change the
-allocation from devm and actually free the auxiliary_device memory in
-the release function. This avoids any use after free problems where the
-parent device driver is unbound from the device but the
-auxiliuary_device is still in use accessing devm freed memory.
-
-Cc: Tommaso Merciai <tomm.merciai@gmail.com>
-Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Cc: Hal Feng <hal.feng@starfivetech.com>
-Cc: Conor Dooley <conor.dooley@microchip.com>
-Cc: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Fixes: edab7204afe5 ("clk: starfive: Add StarFive JH7110 system clock driver")
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-Link: https://lore.kernel.org/r/20230413205528.4044216-1-sboyd@kernel.org
----
- drivers/clk/starfive/clk-starfive-jh7110-sys.c | 15 ++++++++++++---
- drivers/reset/starfive/reset-starfive-jh7110.c | 9 ++++++---
- include/soc/starfive/reset-starfive-jh71x0.h | 17 +++++++++++++++++
- 3 files changed, 35 insertions(+), 6 deletions(-)
- create mode 100644 include/soc/starfive/reset-starfive-jh71x0.h
-
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -11,6 +11,9 @@
- #include <linux/init.h>
- #include <linux/io.h>
- #include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+#include <soc/starfive/reset-starfive-jh71x0.h>
-
- #include <dt-bindings/clock/starfive,jh7110-crg.h>
-
-@@ -335,26 +338,32 @@ static void jh7110_reset_unregister_adev
- struct auxiliary_device *adev = _adev;
-
- auxiliary_device_delete(adev);
-+ auxiliary_device_uninit(adev);
- }
-
- static void jh7110_reset_adev_release(struct device *dev)
- {
- struct auxiliary_device *adev = to_auxiliary_dev(dev);
-+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
-
-- auxiliary_device_uninit(adev);
-+ kfree(rdev);
- }
-
- int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
- const char *adev_name,
- u32 adev_id)
- {
-+ struct jh71x0_reset_adev *rdev;
- struct auxiliary_device *adev;
- int ret;
-
-- adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
-- if (!adev)
-+ rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
-+ if (!rdev)
- return -ENOMEM;
-
-+ rdev->base = priv->base;
-+
-+ adev = &rdev->adev;
- adev->name = adev_name;
- adev->dev.parent = priv->dev;
- adev->dev.release = jh7110_reset_adev_release;
---- a/drivers/reset/starfive/reset-starfive-jh7110.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
-@@ -7,6 +7,8 @@
-
- #include <linux/auxiliary_bus.h>
-
-+#include <soc/starfive/reset-starfive-jh71x0.h>
-+
- #include "reset-starfive-jh71x0.h"
-
- #include <dt-bindings/reset/starfive,jh7110-crg.h>
-@@ -33,14 +35,15 @@ static int jh7110_reset_probe(struct aux
- const struct auxiliary_device_id *id)
- {
- struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
-- void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
-+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
-+ void __iomem *base = rdev->base;
-
- if (!info || !base)
- return -ENODEV;
-
- return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
-- *base + info->assert_offset,
-- *base + info->status_offset,
-+ base + info->assert_offset,
-+ base + info->status_offset,
- NULL,
- info->nr_resets,
- NULL);
---- /dev/null
-+++ b/include/soc/starfive/reset-starfive-jh71x0.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __SOC_STARFIVE_RESET_JH71X0_H
-+#define __SOC_STARFIVE_RESET_JH71X0_H
-+
-+#include <linux/auxiliary_bus.h>
-+#include <linux/compiler_types.h>
-+#include <linux/container_of.h>
-+
-+struct jh71x0_reset_adev {
-+ void __iomem *base;
-+ struct auxiliary_device adev;
-+};
-+
-+#define to_jh71x0_reset_adev(_adev) \
-+ container_of((_adev), struct jh71x0_reset_adev, adev)
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch b/target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch
deleted file mode 100644
index 83de87edfc..0000000000
--- a/target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From f043ba93a8f22fda312574eb98217be15468b7ef Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:28 +0800
-Subject: [PATCH 018/122] dt-bindings: timer: Add StarFive JH7110 clint
-
-Add compatible string for the StarFive JH7110 clint.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
-+++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
-@@ -27,6 +27,7 @@ properties:
- - enum:
- - sifive,fu540-c000-clint
- - starfive,jh7100-clint
-+ - starfive,jh7110-clint
- - canaan,k210-clint
- - const: sifive,clint0
- - items:
diff --git a/target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch b/target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch
deleted file mode 100644
index bb604fee54..0000000000
--- a/target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From dba83b8b65b4ef47e8986739b6734894f3979c52 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:29 +0800
-Subject: [PATCH 019/122] dt-bindings: interrupt-controller: Add StarFive
- JH7110 plic
-
-Add compatible string for StarFive JH7110 plic.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
-+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
-@@ -60,6 +60,7 @@ properties:
- - enum:
- - sifive,fu540-c000-plic
- - starfive,jh7100-plic
-+ - starfive,jh7110-plic
- - canaan,k210-plic
- - const: sifive,plic-1.0.0
- - items:
diff --git a/target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch b/target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch
deleted file mode 100644
index c8e282e04f..0000000000
--- a/target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From fccbb0c52438762999ea16c85d4ebf4cc7e2deff Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:30 +0800
-Subject: [PATCH 020/122] dt-bindings: riscv: Add SiFive S7 compatible
-
-Add a new compatible string in cpu.yaml for SiFive S7 CPU
-core which is used on SiFive U74-MC core complex etc.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- Documentation/devicetree/bindings/riscv/cpus.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/riscv/cpus.yaml
-+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
-@@ -33,6 +33,7 @@ properties:
- - sifive,e5
- - sifive,e7
- - sifive,e71
-+ - sifive,s7
- - sifive,u74-mc
- - sifive,u54
- - sifive,u74
diff --git a/target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch b/target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch
deleted file mode 100644
index d1e1cfc8cd..0000000000
--- a/target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch
+++ /dev/null
@@ -1,549 +0,0 @@
-From ca57ce82224c21f93ad43754474fb8de1baf5caa Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:31 +0800
-Subject: [PATCH 021/122] riscv: dts: starfive: Add initial StarFive JH7110
- device tree
-
-Add initial device tree for the JH7110 RISC-V SoC by StarFive
-Technology Ltd.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-[conor: squashed in the removal of the S7's non-existent mmu]
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/Kconfig.socs | 5 +
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 500 +++++++++++++++++++++++
- 2 files changed, 505 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110.dtsi
-
---- a/arch/riscv/Kconfig.socs
-+++ b/arch/riscv/Kconfig.socs
-@@ -7,6 +7,8 @@ config SOC_MICROCHIP_POLARFIRE
- help
- This enables support for Microchip PolarFire SoC platforms.
-
-+config ARCH_SIFIVE
-+ def_bool SOC_SIFIVE
- config SOC_SIFIVE
- bool "SiFive SoCs"
- select SERIAL_SIFIVE if TTY
-@@ -18,6 +20,9 @@ config SOC_SIFIVE
- help
- This enables support for SiFive SoC platform hardware.
-
-+config ARCH_STARFIVE
-+ def_bool SOC_STARFIVE
-+
- config SOC_STARFIVE
- bool "StarFive SoCs"
- select PINCTRL
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -0,0 +1,500 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+#include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+/ {
-+ compatible = "starfive,jh7110";
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ S7_0: cpu@0 {
-+ compatible = "sifive,s7", "riscv";
-+ reg = <0>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <16384>;
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imac_zba_zbb";
-+ status = "disabled";
-+
-+ cpu0_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_1: cpu@1 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <1>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu1_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_2: cpu@2 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <2>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu2_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_3: cpu@3 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <3>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu3_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_4: cpu@4 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <4>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu4_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ cpu-map {
-+ cluster0 {
-+ core0 {
-+ cpu = <&S7_0>;
-+ };
-+
-+ core1 {
-+ cpu = <&U74_1>;
-+ };
-+
-+ core2 {
-+ cpu = <&U74_2>;
-+ };
-+
-+ core3 {
-+ cpu = <&U74_3>;
-+ };
-+
-+ core4 {
-+ cpu = <&U74_4>;
-+ };
-+ };
-+ };
-+ };
-+
-+ gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac0_rgmii_rxin";
-+ #clock-cells = <0>;
-+ };
-+
-+ gmac0_rmii_refin: gmac0-rmii-refin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac0_rmii_refin";
-+ #clock-cells = <0>;
-+ };
-+
-+ gmac1_rgmii_rxin: gmac1-rgmii-rxin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac1_rgmii_rxin";
-+ #clock-cells = <0>;
-+ };
-+
-+ gmac1_rmii_refin: gmac1-rmii-refin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac1_rmii_refin";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2srx_bclk_ext: i2srx-bclk-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2srx_bclk_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2srx_lrck_ext: i2srx-lrck-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2srx_lrck_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2stx_bclk_ext: i2stx-bclk-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2stx_bclk_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2stx_lrck_ext: i2stx-lrck-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2stx_lrck_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ mclk_ext: mclk-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "mclk_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ osc: oscillator {
-+ compatible = "fixed-clock";
-+ clock-output-names = "osc";
-+ #clock-cells = <0>;
-+ };
-+
-+ rtc_osc: rtc-oscillator {
-+ compatible = "fixed-clock";
-+ clock-output-names = "rtc_osc";
-+ #clock-cells = <0>;
-+ };
-+
-+ tdm_ext: tdm-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "tdm_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ soc {
-+ compatible = "simple-bus";
-+ interrupt-parent = <&plic>;
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ clint: timer@2000000 {
-+ compatible = "starfive,jh7110-clint", "sifive,clint0";
-+ reg = <0x0 0x2000000 0x0 0x10000>;
-+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
-+ <&cpu1_intc 3>, <&cpu1_intc 7>,
-+ <&cpu2_intc 3>, <&cpu2_intc 7>,
-+ <&cpu3_intc 3>, <&cpu3_intc 7>,
-+ <&cpu4_intc 3>, <&cpu4_intc 7>;
-+ };
-+
-+ ccache: cache-controller@2010000 {
-+ compatible = "starfive,jh7110-ccache", "sifive,ccache0", "cache";
-+ reg = <0x0 0x2010000 0x0 0x4000>;
-+ interrupts = <1>, <3>, <4>, <2>;
-+ cache-block-size = <64>;
-+ cache-level = <2>;
-+ cache-sets = <2048>;
-+ cache-size = <2097152>;
-+ cache-unified;
-+ };
-+
-+ plic: interrupt-controller@c000000 {
-+ compatible = "starfive,jh7110-plic", "sifive,plic-1.0.0";
-+ reg = <0x0 0xc000000 0x0 0x4000000>;
-+ interrupts-extended = <&cpu0_intc 11>,
-+ <&cpu1_intc 11>, <&cpu1_intc 9>,
-+ <&cpu2_intc 11>, <&cpu2_intc 9>,
-+ <&cpu3_intc 11>, <&cpu3_intc 9>,
-+ <&cpu4_intc 11>, <&cpu4_intc 9>;
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ #address-cells = <0>;
-+ riscv,ndev = <136>;
-+ };
-+
-+ uart0: serial@10000000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x10000000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART0_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART0_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART0_APB>;
-+ interrupts = <32>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@10010000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x10010000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART1_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART1_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART1_APB>;
-+ interrupts = <33>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart2: serial@10020000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x10020000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART2_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART2_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART2_APB>;
-+ interrupts = <34>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ i2c0: i2c@10030000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x10030000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C0_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C0_APB>;
-+ interrupts = <35>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c1: i2c@10040000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x10040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C1_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C1_APB>;
-+ interrupts = <36>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c2: i2c@10050000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x10050000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C2_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C2_APB>;
-+ interrupts = <37>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ uart3: serial@12000000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x12000000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART3_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART3_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART3_APB>;
-+ interrupts = <45>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart4: serial@12010000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x12010000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART4_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART4_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART4_APB>;
-+ interrupts = <46>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart5: serial@12020000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x12020000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART5_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART5_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART5_APB>;
-+ interrupts = <47>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ i2c3: i2c@12030000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12030000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C3_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C3_APB>;
-+ interrupts = <48>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c4: i2c@12040000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C4_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C4_APB>;
-+ interrupts = <49>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c5: i2c@12050000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12050000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C5_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C5_APB>;
-+ interrupts = <50>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c6: i2c@12060000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12060000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C6_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C6_APB>;
-+ interrupts = <51>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ syscrg: clock-controller@13020000 {
-+ compatible = "starfive,jh7110-syscrg";
-+ reg = <0x0 0x13020000 0x0 0x10000>;
-+ clocks = <&osc>, <&gmac1_rmii_refin>,
-+ <&gmac1_rgmii_rxin>,
-+ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
-+ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-+ <&tdm_ext>, <&mclk_ext>;
-+ clock-names = "osc", "gmac1_rmii_refin",
-+ "gmac1_rgmii_rxin",
-+ "i2stx_bclk_ext", "i2stx_lrck_ext",
-+ "i2srx_bclk_ext", "i2srx_lrck_ext",
-+ "tdm_ext", "mclk_ext";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
-+ sysgpio: pinctrl@13040000 {
-+ compatible = "starfive,jh7110-sys-pinctrl";
-+ reg = <0x0 0x13040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_IOMUX_APB>;
-+ resets = <&syscrg JH7110_SYSRST_IOMUX_APB>;
-+ interrupts = <86>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+
-+ aoncrg: clock-controller@17000000 {
-+ compatible = "starfive,jh7110-aoncrg";
-+ reg = <0x0 0x17000000 0x0 0x10000>;
-+ clocks = <&osc>, <&gmac0_rmii_refin>,
-+ <&gmac0_rgmii_rxin>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
-+ <&rtc_osc>;
-+ clock-names = "osc", "gmac0_rmii_refin",
-+ "gmac0_rgmii_rxin", "stg_axiahb",
-+ "apb_bus", "gmac0_gtxclk",
-+ "rtc_osc";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
-+ aongpio: pinctrl@17020000 {
-+ compatible = "starfive,jh7110-aon-pinctrl";
-+ reg = <0x0 0x17020000 0x0 0x10000>;
-+ resets = <&aoncrg JH7110_AONRST_IOMUX>;
-+ interrupts = <85>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+ };
-+};
diff --git a/target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch b/target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch
deleted file mode 100644
index 9c329d019f..0000000000
--- a/target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch
+++ /dev/null
@@ -1,331 +0,0 @@
-From 878c16d22c0feb52c3af65139734b8bb45e349e1 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:32 +0800
-Subject: [PATCH 022/122] riscv: dts: starfive: Add StarFive JH7110 pin
- function definitions
-
-Add pin function definitions for StarFive JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/boot/dts/starfive/jh7110-pinfunc.h | 308 ++++++++++++++++++
- 1 file changed, 308 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
-
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
-@@ -0,0 +1,308 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __JH7110_PINFUNC_H__
-+#define __JH7110_PINFUNC_H__
-+
-+/*
-+ * mux bits:
-+ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
-+ * | din | dout | doen | function | gpio nr |
-+ *
-+ * dout: output signal
-+ * doen: output enable signal
-+ * din: optional input signal, 0xff = none
-+ * function: function selector
-+ * gpio nr: gpio number, 0 - 63
-+ */
-+#define GPIOMUX(n, dout, doen, din) ( \
-+ (((din) & 0xff) << 24) | \
-+ (((dout) & 0xff) << 16) | \
-+ (((doen) & 0x3f) << 10) | \
-+ ((n) & 0x3f))
-+
-+#define PINMUX(n, func) ((1 << 10) | (((func) & 0x3) << 8) | ((n) & 0xff))
-+
-+/* sys_iomux dout */
-+#define GPOUT_LOW 0
-+#define GPOUT_HIGH 1
-+#define GPOUT_SYS_WAVE511_UART_TX 2
-+#define GPOUT_SYS_CAN0_STBY 3
-+#define GPOUT_SYS_CAN0_TST_NEXT_BIT 4
-+#define GPOUT_SYS_CAN0_TST_SAMPLE_POINT 5
-+#define GPOUT_SYS_CAN0_TXD 6
-+#define GPOUT_SYS_USB_DRIVE_VBUS 7
-+#define GPOUT_SYS_QSPI_CS1 8
-+#define GPOUT_SYS_SPDIF 9
-+#define GPOUT_SYS_HDMI_CEC_SDA 10
-+#define GPOUT_SYS_HDMI_DDC_SCL 11
-+#define GPOUT_SYS_HDMI_DDC_SDA 12
-+#define GPOUT_SYS_WATCHDOG 13
-+#define GPOUT_SYS_I2C0_CLK 14
-+#define GPOUT_SYS_I2C0_DATA 15
-+#define GPOUT_SYS_SDIO0_BACK_END_POWER 16
-+#define GPOUT_SYS_SDIO0_CARD_POWER_EN 17
-+#define GPOUT_SYS_SDIO0_CCMD_OD_PULLUP_EN 18
-+#define GPOUT_SYS_SDIO0_RST 19
-+#define GPOUT_SYS_UART0_TX 20
-+#define GPOUT_SYS_HIFI4_JTAG_TDO 21
-+#define GPOUT_SYS_JTAG_TDO 22
-+#define GPOUT_SYS_PDM_MCLK 23
-+#define GPOUT_SYS_PWM_CHANNEL0 24
-+#define GPOUT_SYS_PWM_CHANNEL1 25
-+#define GPOUT_SYS_PWM_CHANNEL2 26
-+#define GPOUT_SYS_PWM_CHANNEL3 27
-+#define GPOUT_SYS_PWMDAC_LEFT 28
-+#define GPOUT_SYS_PWMDAC_RIGHT 29
-+#define GPOUT_SYS_SPI0_CLK 30
-+#define GPOUT_SYS_SPI0_FSS 31
-+#define GPOUT_SYS_SPI0_TXD 32
-+#define GPOUT_SYS_GMAC_PHYCLK 33
-+#define GPOUT_SYS_I2SRX_BCLK 34
-+#define GPOUT_SYS_I2SRX_LRCK 35
-+#define GPOUT_SYS_I2STX0_BCLK 36
-+#define GPOUT_SYS_I2STX0_LRCK 37
-+#define GPOUT_SYS_MCLK 38
-+#define GPOUT_SYS_TDM_CLK 39
-+#define GPOUT_SYS_TDM_SYNC 40
-+#define GPOUT_SYS_TDM_TXD 41
-+#define GPOUT_SYS_TRACE_DATA0 42
-+#define GPOUT_SYS_TRACE_DATA1 43
-+#define GPOUT_SYS_TRACE_DATA2 44
-+#define GPOUT_SYS_TRACE_DATA3 45
-+#define GPOUT_SYS_TRACE_REF 46
-+#define GPOUT_SYS_CAN1_STBY 47
-+#define GPOUT_SYS_CAN1_TST_NEXT_BIT 48
-+#define GPOUT_SYS_CAN1_TST_SAMPLE_POINT 49
-+#define GPOUT_SYS_CAN1_TXD 50
-+#define GPOUT_SYS_I2C1_CLK 51
-+#define GPOUT_SYS_I2C1_DATA 52
-+#define GPOUT_SYS_SDIO1_BACK_END_POWER 53
-+#define GPOUT_SYS_SDIO1_CARD_POWER_EN 54
-+#define GPOUT_SYS_SDIO1_CLK 55
-+#define GPOUT_SYS_SDIO1_CMD_OD_PULLUP_EN 56
-+#define GPOUT_SYS_SDIO1_CMD 57
-+#define GPOUT_SYS_SDIO1_DATA0 58
-+#define GPOUT_SYS_SDIO1_DATA1 59
-+#define GPOUT_SYS_SDIO1_DATA2 60
-+#define GPOUT_SYS_SDIO1_DATA3 61
-+#define GPOUT_SYS_SDIO1_DATA4 63
-+#define GPOUT_SYS_SDIO1_DATA5 63
-+#define GPOUT_SYS_SDIO1_DATA6 64
-+#define GPOUT_SYS_SDIO1_DATA7 65
-+#define GPOUT_SYS_SDIO1_RST 66
-+#define GPOUT_SYS_UART1_RTS 67
-+#define GPOUT_SYS_UART1_TX 68
-+#define GPOUT_SYS_I2STX1_SDO0 69
-+#define GPOUT_SYS_I2STX1_SDO1 70
-+#define GPOUT_SYS_I2STX1_SDO2 71
-+#define GPOUT_SYS_I2STX1_SDO3 72
-+#define GPOUT_SYS_SPI1_CLK 73
-+#define GPOUT_SYS_SPI1_FSS 74
-+#define GPOUT_SYS_SPI1_TXD 75
-+#define GPOUT_SYS_I2C2_CLK 76
-+#define GPOUT_SYS_I2C2_DATA 77
-+#define GPOUT_SYS_UART2_RTS 78
-+#define GPOUT_SYS_UART2_TX 79
-+#define GPOUT_SYS_SPI2_CLK 80
-+#define GPOUT_SYS_SPI2_FSS 81
-+#define GPOUT_SYS_SPI2_TXD 82
-+#define GPOUT_SYS_I2C3_CLK 83
-+#define GPOUT_SYS_I2C3_DATA 84
-+#define GPOUT_SYS_UART3_TX 85
-+#define GPOUT_SYS_SPI3_CLK 86
-+#define GPOUT_SYS_SPI3_FSS 87
-+#define GPOUT_SYS_SPI3_TXD 88
-+#define GPOUT_SYS_I2C4_CLK 89
-+#define GPOUT_SYS_I2C4_DATA 90
-+#define GPOUT_SYS_UART4_RTS 91
-+#define GPOUT_SYS_UART4_TX 92
-+#define GPOUT_SYS_SPI4_CLK 93
-+#define GPOUT_SYS_SPI4_FSS 94
-+#define GPOUT_SYS_SPI4_TXD 95
-+#define GPOUT_SYS_I2C5_CLK 96
-+#define GPOUT_SYS_I2C5_DATA 97
-+#define GPOUT_SYS_UART5_RTS 98
-+#define GPOUT_SYS_UART5_TX 99
-+#define GPOUT_SYS_SPI5_CLK 100
-+#define GPOUT_SYS_SPI5_FSS 101
-+#define GPOUT_SYS_SPI5_TXD 102
-+#define GPOUT_SYS_I2C6_CLK 103
-+#define GPOUT_SYS_I2C6_DATA 104
-+#define GPOUT_SYS_SPI6_CLK 105
-+#define GPOUT_SYS_SPI6_FSS 106
-+#define GPOUT_SYS_SPI6_TXD 107
-+
-+/* aon_iomux dout */
-+#define GPOUT_AON_CLK_32K_OUT 2
-+#define GPOUT_AON_PTC0_PWM4 3
-+#define GPOUT_AON_PTC0_PWM5 4
-+#define GPOUT_AON_PTC0_PWM6 5
-+#define GPOUT_AON_PTC0_PWM7 6
-+#define GPOUT_AON_CLK_GCLK0 7
-+#define GPOUT_AON_CLK_GCLK1 8
-+#define GPOUT_AON_CLK_GCLK2 9
-+
-+/* sys_iomux doen */
-+#define GPOEN_ENABLE 0
-+#define GPOEN_DISABLE 1
-+#define GPOEN_SYS_HDMI_CEC_SDA 2
-+#define GPOEN_SYS_HDMI_DDC_SCL 3
-+#define GPOEN_SYS_HDMI_DDC_SDA 4
-+#define GPOEN_SYS_I2C0_CLK 5
-+#define GPOEN_SYS_I2C0_DATA 6
-+#define GPOEN_SYS_HIFI4_JTAG_TDO 7
-+#define GPOEN_SYS_JTAG_TDO 8
-+#define GPOEN_SYS_PWM0_CHANNEL0 9
-+#define GPOEN_SYS_PWM0_CHANNEL1 10
-+#define GPOEN_SYS_PWM0_CHANNEL2 11
-+#define GPOEN_SYS_PWM0_CHANNEL3 12
-+#define GPOEN_SYS_SPI0_NSSPCTL 13
-+#define GPOEN_SYS_SPI0_NSSP 14
-+#define GPOEN_SYS_TDM_SYNC 15
-+#define GPOEN_SYS_TDM_TXD 16
-+#define GPOEN_SYS_I2C1_CLK 17
-+#define GPOEN_SYS_I2C1_DATA 18
-+#define GPOEN_SYS_SDIO1_CMD 19
-+#define GPOEN_SYS_SDIO1_DATA0 20
-+#define GPOEN_SYS_SDIO1_DATA1 21
-+#define GPOEN_SYS_SDIO1_DATA2 22
-+#define GPOEN_SYS_SDIO1_DATA3 23
-+#define GPOEN_SYS_SDIO1_DATA4 24
-+#define GPOEN_SYS_SDIO1_DATA5 25
-+#define GPOEN_SYS_SDIO1_DATA6 26
-+#define GPOEN_SYS_SDIO1_DATA7 27
-+#define GPOEN_SYS_SPI1_NSSPCTL 28
-+#define GPOEN_SYS_SPI1_NSSP 29
-+#define GPOEN_SYS_I2C2_CLK 30
-+#define GPOEN_SYS_I2C2_DATA 31
-+#define GPOEN_SYS_SPI2_NSSPCTL 32
-+#define GPOEN_SYS_SPI2_NSSP 33
-+#define GPOEN_SYS_I2C3_CLK 34
-+#define GPOEN_SYS_I2C3_DATA 35
-+#define GPOEN_SYS_SPI3_NSSPCTL 36
-+#define GPOEN_SYS_SPI3_NSSP 37
-+#define GPOEN_SYS_I2C4_CLK 38
-+#define GPOEN_SYS_I2C4_DATA 39
-+#define GPOEN_SYS_SPI4_NSSPCTL 40
-+#define GPOEN_SYS_SPI4_NSSP 41
-+#define GPOEN_SYS_I2C5_CLK 42
-+#define GPOEN_SYS_I2C5_DATA 43
-+#define GPOEN_SYS_SPI5_NSSPCTL 44
-+#define GPOEN_SYS_SPI5_NSSP 45
-+#define GPOEN_SYS_I2C6_CLK 46
-+#define GPOEN_SYS_I2C6_DATA 47
-+#define GPOEN_SYS_SPI6_NSSPCTL 48
-+#define GPOEN_SYS_SPI6_NSSP 49
-+
-+/* aon_iomux doen */
-+#define GPOEN_AON_PTC0_OE_N_4 2
-+#define GPOEN_AON_PTC0_OE_N_5 3
-+#define GPOEN_AON_PTC0_OE_N_6 4
-+#define GPOEN_AON_PTC0_OE_N_7 5
-+
-+/* sys_iomux gin */
-+#define GPI_NONE 255
-+
-+#define GPI_SYS_WAVE511_UART_RX 0
-+#define GPI_SYS_CAN0_RXD 1
-+#define GPI_SYS_USB_OVERCURRENT 2
-+#define GPI_SYS_SPDIF 3
-+#define GPI_SYS_JTAG_RST 4
-+#define GPI_SYS_HDMI_CEC_SDA 5
-+#define GPI_SYS_HDMI_DDC_SCL 6
-+#define GPI_SYS_HDMI_DDC_SDA 7
-+#define GPI_SYS_HDMI_HPD 8
-+#define GPI_SYS_I2C0_CLK 9
-+#define GPI_SYS_I2C0_DATA 10
-+#define GPI_SYS_SDIO0_CD 11
-+#define GPI_SYS_SDIO0_INT 12
-+#define GPI_SYS_SDIO0_WP 13
-+#define GPI_SYS_UART0_RX 14
-+#define GPI_SYS_HIFI4_JTAG_TCK 15
-+#define GPI_SYS_HIFI4_JTAG_TDI 16
-+#define GPI_SYS_HIFI4_JTAG_TMS 17
-+#define GPI_SYS_HIFI4_JTAG_RST 18
-+#define GPI_SYS_JTAG_TDI 19
-+#define GPI_SYS_JTAG_TMS 20
-+#define GPI_SYS_PDM_DMIC0 21
-+#define GPI_SYS_PDM_DMIC1 22
-+#define GPI_SYS_I2SRX_SDIN0 23
-+#define GPI_SYS_I2SRX_SDIN1 24
-+#define GPI_SYS_I2SRX_SDIN2 25
-+#define GPI_SYS_SPI0_CLK 26
-+#define GPI_SYS_SPI0_FSS 27
-+#define GPI_SYS_SPI0_RXD 28
-+#define GPI_SYS_JTAG_TCK 29
-+#define GPI_SYS_MCLK_EXT 30
-+#define GPI_SYS_I2SRX_BCLK 31
-+#define GPI_SYS_I2SRX_LRCK 32
-+#define GPI_SYS_I2STX0_BCLK 33
-+#define GPI_SYS_I2STX0_LRCK 34
-+#define GPI_SYS_TDM_CLK 35
-+#define GPI_SYS_TDM_RXD 36
-+#define GPI_SYS_TDM_SYNC 37
-+#define GPI_SYS_CAN1_RXD 38
-+#define GPI_SYS_I2C1_CLK 39
-+#define GPI_SYS_I2C1_DATA 40
-+#define GPI_SYS_SDIO1_CD 41
-+#define GPI_SYS_SDIO1_INT 42
-+#define GPI_SYS_SDIO1_WP 43
-+#define GPI_SYS_SDIO1_CMD 44
-+#define GPI_SYS_SDIO1_DATA0 45
-+#define GPI_SYS_SDIO1_DATA1 46
-+#define GPI_SYS_SDIO1_DATA2 47
-+#define GPI_SYS_SDIO1_DATA3 48
-+#define GPI_SYS_SDIO1_DATA4 49
-+#define GPI_SYS_SDIO1_DATA5 50
-+#define GPI_SYS_SDIO1_DATA6 51
-+#define GPI_SYS_SDIO1_DATA7 52
-+#define GPI_SYS_SDIO1_STRB 53
-+#define GPI_SYS_UART1_CTS 54
-+#define GPI_SYS_UART1_RX 55
-+#define GPI_SYS_SPI1_CLK 56
-+#define GPI_SYS_SPI1_FSS 57
-+#define GPI_SYS_SPI1_RXD 58
-+#define GPI_SYS_I2C2_CLK 59
-+#define GPI_SYS_I2C2_DATA 60
-+#define GPI_SYS_UART2_CTS 61
-+#define GPI_SYS_UART2_RX 62
-+#define GPI_SYS_SPI2_CLK 63
-+#define GPI_SYS_SPI2_FSS 64
-+#define GPI_SYS_SPI2_RXD 65
-+#define GPI_SYS_I2C3_CLK 66
-+#define GPI_SYS_I2C3_DATA 67
-+#define GPI_SYS_UART3_RX 68
-+#define GPI_SYS_SPI3_CLK 69
-+#define GPI_SYS_SPI3_FSS 70
-+#define GPI_SYS_SPI3_RXD 71
-+#define GPI_SYS_I2C4_CLK 72
-+#define GPI_SYS_I2C4_DATA 73
-+#define GPI_SYS_UART4_CTS 74
-+#define GPI_SYS_UART4_RX 75
-+#define GPI_SYS_SPI4_CLK 76
-+#define GPI_SYS_SPI4_FSS 77
-+#define GPI_SYS_SPI4_RXD 78
-+#define GPI_SYS_I2C5_CLK 79
-+#define GPI_SYS_I2C5_DATA 80
-+#define GPI_SYS_UART5_CTS 81
-+#define GPI_SYS_UART5_RX 82
-+#define GPI_SYS_SPI5_CLK 83
-+#define GPI_SYS_SPI5_FSS 84
-+#define GPI_SYS_SPI5_RXD 85
-+#define GPI_SYS_I2C6_CLK 86
-+#define GPI_SYS_I2C6_DATA 87
-+#define GPI_SYS_SPI6_CLK 88
-+#define GPI_SYS_SPI6_FSS 89
-+#define GPI_SYS_SPI6_RXD 90
-+
-+/* aon_iomux gin */
-+#define GPI_AON_PMU_GPIO_WAKEUP_0 0
-+#define GPI_AON_PMU_GPIO_WAKEUP_1 1
-+#define GPI_AON_PMU_GPIO_WAKEUP_2 2
-+#define GPI_AON_PMU_GPIO_WAKEUP_3 3
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch b/target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch
deleted file mode 100644
index 9e311bf527..0000000000
--- a/target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch
+++ /dev/null
@@ -1,290 +0,0 @@
-From 76bc84c399f11c7d6a37fe68cbd5f182e4c18369 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:33 +0800
-Subject: [PATCH 023/122] riscv: dts: starfive: Add StarFive JH7110 VisionFive
- 2 board device tree
-
-Add a minimal device tree for StarFive JH7110 VisionFive 2 board
-which has version A and version B. Support booting and basic
-clock/reset/pinctrl/uart drivers.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/boot/dts/starfive/Makefile | 6 +-
- .../jh7110-starfive-visionfive-2-v1.2a.dts | 13 ++
- .../jh7110-starfive-visionfive-2-v1.3b.dts | 13 ++
- .../jh7110-starfive-visionfive-2.dtsi | 215 ++++++++++++++++++
- 4 files changed, 246 insertions(+), 1 deletion(-)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-
---- a/arch/riscv/boot/dts/starfive/Makefile
-+++ b/arch/riscv/boot/dts/starfive/Makefile
-@@ -1,2 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0
--dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
-+
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
-@@ -0,0 +1,13 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7110-starfive-visionfive-2.dtsi"
-+
-+/ {
-+ model = "StarFive VisionFive 2 v1.2A";
-+ compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
-+};
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -0,0 +1,13 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7110-starfive-visionfive-2.dtsi"
-+
-+/ {
-+ model = "StarFive VisionFive 2 v1.3B";
-+ compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
-+};
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -0,0 +1,215 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7110.dtsi"
-+#include "jh7110-pinfunc.h"
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/ {
-+ aliases {
-+ i2c0 = &i2c0;
-+ i2c2 = &i2c2;
-+ i2c5 = &i2c5;
-+ i2c6 = &i2c6;
-+ serial0 = &uart0;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ cpus {
-+ timebase-frequency = <4000000>;
-+ };
-+
-+ memory@40000000 {
-+ device_type = "memory";
-+ reg = <0x0 0x40000000 0x1 0x0>;
-+ };
-+
-+ gpio-restart {
-+ compatible = "gpio-restart";
-+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
-+ priority = <224>;
-+ };
-+};
-+
-+&gmac0_rgmii_rxin {
-+ clock-frequency = <125000000>;
-+};
-+
-+&gmac0_rmii_refin {
-+ clock-frequency = <50000000>;
-+};
-+
-+&gmac1_rgmii_rxin {
-+ clock-frequency = <125000000>;
-+};
-+
-+&gmac1_rmii_refin {
-+ clock-frequency = <50000000>;
-+};
-+
-+&i2srx_bclk_ext {
-+ clock-frequency = <12288000>;
-+};
-+
-+&i2srx_lrck_ext {
-+ clock-frequency = <192000>;
-+};
-+
-+&i2stx_bclk_ext {
-+ clock-frequency = <12288000>;
-+};
-+
-+&i2stx_lrck_ext {
-+ clock-frequency = <192000>;
-+};
-+
-+&mclk_ext {
-+ clock-frequency = <12288000>;
-+};
-+
-+&osc {
-+ clock-frequency = <24000000>;
-+};
-+
-+&rtc_osc {
-+ clock-frequency = <32768>;
-+};
-+
-+&tdm_ext {
-+ clock-frequency = <49152000>;
-+};
-+
-+&i2c0 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c0_pins>;
-+ status = "okay";
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c2_pins>;
-+ status = "okay";
-+};
-+
-+&i2c5 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c5_pins>;
-+ status = "okay";
-+};
-+
-+&i2c6 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c6_pins>;
-+ status = "okay";
-+};
-+
-+&sysgpio {
-+ i2c0_pins: i2c0-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(57, GPOUT_LOW,
-+ GPOEN_SYS_I2C0_CLK,
-+ GPI_SYS_I2C0_CLK)>,
-+ <GPIOMUX(58, GPOUT_LOW,
-+ GPOEN_SYS_I2C0_DATA,
-+ GPI_SYS_I2C0_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c2_pins: i2c2-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(3, GPOUT_LOW,
-+ GPOEN_SYS_I2C2_CLK,
-+ GPI_SYS_I2C2_CLK)>,
-+ <GPIOMUX(2, GPOUT_LOW,
-+ GPOEN_SYS_I2C2_DATA,
-+ GPI_SYS_I2C2_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c5_pins: i2c5-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(19, GPOUT_LOW,
-+ GPOEN_SYS_I2C5_CLK,
-+ GPI_SYS_I2C5_CLK)>,
-+ <GPIOMUX(20, GPOUT_LOW,
-+ GPOEN_SYS_I2C5_DATA,
-+ GPI_SYS_I2C5_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c6_pins: i2c6-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(16, GPOUT_LOW,
-+ GPOEN_SYS_I2C6_CLK,
-+ GPI_SYS_I2C6_CLK)>,
-+ <GPIOMUX(17, GPOUT_LOW,
-+ GPOEN_SYS_I2C6_DATA,
-+ GPI_SYS_I2C6_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ uart0_pins: uart0-0 {
-+ tx-pins {
-+ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
-+ GPOEN_ENABLE,
-+ GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+
-+ rx-pins {
-+ pinmux = <GPIOMUX(6, GPOUT_LOW,
-+ GPOEN_DISABLE,
-+ GPI_SYS_UART0_RX)>;
-+ bias-disable; /* external pull-up */
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins>;
-+ status = "okay";
-+};
diff --git a/target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch b/target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch
deleted file mode 100644
index f823aff9a1..0000000000
--- a/target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From cbb348ddbc68fe4fc8ac80bed11c298149e7893f Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Tue, 18 Oct 2022 00:05:42 +0300
-Subject: [PATCH 024/122] riscv: dts: starfive: Add StarFive VisionFive V1
- device tree
-
-Add initial device tree for the StarFive VisionFive V1 SBC, which
-is similar with the already supported BeagleV Starlight Beta board,
-both being based on the StarFive JH7100 SoC.
-
-Link: https://github.com/starfive-tech/VisionFive
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Matthias Brugger <mbrugger@suse.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../jh7100-starfive-visionfive-v1.dts | 20 +++++++++++++++++++
- 1 file changed, 20 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-@@ -0,0 +1,20 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7100-common.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/ {
-+ model = "StarFive VisionFive V1";
-+ compatible = "starfive,visionfive-v1", "starfive,jh7100";
-+
-+ gpio-restart {
-+ compatible = "gpio-restart";
-+ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
-+ priority = <224>;
-+ };
-+};
diff --git a/target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch b/target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch
deleted file mode 100644
index 44b5836c34..0000000000
--- a/target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch
+++ /dev/null
@@ -1,349 +0,0 @@
-From 2101233d71b74e33de33e4cc292c6a8cf5da9d42 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Tue, 18 Oct 2022 00:05:41 +0300
-Subject: [PATCH 025/122] riscv: dts: starfive: Add common DT for JH7100 based
- boards
-
-In preparation for adding initial device tree support for the StarFive
-VisionFive board, which is similar with BeagleV Starlight, move most
-of the content from jh7100-beaglev-starlight.dts to a new file, to be
-shared between the two boards.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Matthias Brugger <mbrugger@suse.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../dts/starfive/jh7100-beaglev-starlight.dts | 153 +----------------
- .../boot/dts/starfive/jh7100-common.dtsi | 161 ++++++++++++++++++
- 2 files changed, 162 insertions(+), 152 deletions(-)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-
---- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-@@ -5,160 +5,9 @@
- */
-
- /dts-v1/;
--#include "jh7100.dtsi"
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/leds/common.h>
--#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
-+#include "jh7100-common.dtsi"
-
- / {
- model = "BeagleV Starlight Beta";
- compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
--
-- aliases {
-- serial0 = &uart3;
-- };
--
-- chosen {
-- stdout-path = "serial0:115200n8";
-- };
--
-- cpus {
-- timebase-frequency = <6250000>;
-- };
--
-- memory@80000000 {
-- device_type = "memory";
-- reg = <0x0 0x80000000 0x2 0x0>;
-- };
--
-- leds {
-- compatible = "gpio-leds";
--
-- led-ack {
-- gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
-- color = <LED_COLOR_ID_GREEN>;
-- function = LED_FUNCTION_HEARTBEAT;
-- linux,default-trigger = "heartbeat";
-- label = "ack";
-- };
-- };
--};
--
--&gpio {
-- i2c0_pins: i2c0-0 {
-- i2c-pins {
-- pinmux = <GPIOMUX(62, GPO_LOW,
-- GPO_I2C0_PAD_SCK_OEN,
-- GPI_I2C0_PAD_SCK_IN)>,
-- <GPIOMUX(61, GPO_LOW,
-- GPO_I2C0_PAD_SDA_OEN,
-- GPI_I2C0_PAD_SDA_IN)>;
-- bias-disable; /* external pull-up */
-- input-enable;
-- input-schmitt-enable;
-- };
-- };
--
-- i2c1_pins: i2c1-0 {
-- i2c-pins {
-- pinmux = <GPIOMUX(47, GPO_LOW,
-- GPO_I2C1_PAD_SCK_OEN,
-- GPI_I2C1_PAD_SCK_IN)>,
-- <GPIOMUX(48, GPO_LOW,
-- GPO_I2C1_PAD_SDA_OEN,
-- GPI_I2C1_PAD_SDA_IN)>;
-- bias-pull-up;
-- input-enable;
-- input-schmitt-enable;
-- };
-- };
--
-- i2c2_pins: i2c2-0 {
-- i2c-pins {
-- pinmux = <GPIOMUX(60, GPO_LOW,
-- GPO_I2C2_PAD_SCK_OEN,
-- GPI_I2C2_PAD_SCK_IN)>,
-- <GPIOMUX(59, GPO_LOW,
-- GPO_I2C2_PAD_SDA_OEN,
-- GPI_I2C2_PAD_SDA_IN)>;
-- bias-disable; /* external pull-up */
-- input-enable;
-- input-schmitt-enable;
-- };
-- };
--
-- uart3_pins: uart3-0 {
-- rx-pins {
-- pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
-- GPI_UART3_PAD_SIN)>;
-- bias-pull-up;
-- drive-strength = <14>;
-- input-enable;
-- input-schmitt-enable;
-- slew-rate = <0>;
-- };
-- tx-pins {
-- pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
-- GPO_ENABLE, GPI_NONE)>;
-- bias-disable;
-- drive-strength = <35>;
-- input-disable;
-- input-schmitt-disable;
-- slew-rate = <0>;
-- };
-- };
--};
--
--&i2c0 {
-- clock-frequency = <100000>;
-- i2c-sda-hold-time-ns = <300>;
-- i2c-sda-falling-time-ns = <500>;
-- i2c-scl-falling-time-ns = <500>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&i2c0_pins>;
-- status = "okay";
--
-- pmic@5e {
-- compatible = "ti,tps65086";
-- reg = <0x5e>;
-- gpio-controller;
-- #gpio-cells = <2>;
--
-- regulators {
-- };
-- };
--};
--
--&i2c1 {
-- clock-frequency = <400000>;
-- i2c-sda-hold-time-ns = <300>;
-- i2c-sda-falling-time-ns = <100>;
-- i2c-scl-falling-time-ns = <100>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&i2c1_pins>;
-- status = "okay";
--};
--
--&i2c2 {
-- clock-frequency = <100000>;
-- i2c-sda-hold-time-ns = <300>;
-- i2c-sda-falling-time-ns = <500>;
-- i2c-scl-falling-time-ns = <500>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&i2c2_pins>;
-- status = "okay";
--};
--
--&osc_sys {
-- clock-frequency = <25000000>;
--};
--
--&osc_aud {
-- clock-frequency = <27000000>;
--};
--
--&uart3 {
-- pinctrl-names = "default";
-- pinctrl-0 = <&uart3_pins>;
-- status = "okay";
- };
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-@@ -0,0 +1,161 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7100.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
-+
-+/ {
-+ aliases {
-+ serial0 = &uart3;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ cpus {
-+ timebase-frequency = <6250000>;
-+ };
-+
-+ memory@80000000 {
-+ device_type = "memory";
-+ reg = <0x0 0x80000000 0x2 0x0>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-ack {
-+ gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_HEARTBEAT;
-+ linux,default-trigger = "heartbeat";
-+ label = "ack";
-+ };
-+ };
-+};
-+
-+&gpio {
-+ i2c0_pins: i2c0-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(62, GPO_LOW,
-+ GPO_I2C0_PAD_SCK_OEN,
-+ GPI_I2C0_PAD_SCK_IN)>,
-+ <GPIOMUX(61, GPO_LOW,
-+ GPO_I2C0_PAD_SDA_OEN,
-+ GPI_I2C0_PAD_SDA_IN)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c1_pins: i2c1-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(47, GPO_LOW,
-+ GPO_I2C1_PAD_SCK_OEN,
-+ GPI_I2C1_PAD_SCK_IN)>,
-+ <GPIOMUX(48, GPO_LOW,
-+ GPO_I2C1_PAD_SDA_OEN,
-+ GPI_I2C1_PAD_SDA_IN)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c2_pins: i2c2-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(60, GPO_LOW,
-+ GPO_I2C2_PAD_SCK_OEN,
-+ GPI_I2C2_PAD_SCK_IN)>,
-+ <GPIOMUX(59, GPO_LOW,
-+ GPO_I2C2_PAD_SDA_OEN,
-+ GPI_I2C2_PAD_SDA_IN)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ uart3_pins: uart3-0 {
-+ rx-pins {
-+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
-+ GPI_UART3_PAD_SIN)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ tx-pins {
-+ pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+};
-+
-+&i2c0 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <500>;
-+ i2c-scl-falling-time-ns = <500>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c0_pins>;
-+ status = "okay";
-+
-+ pmic@5e {
-+ compatible = "ti,tps65086";
-+ reg = <0x5e>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ regulators {
-+ };
-+ };
-+};
-+
-+&i2c1 {
-+ clock-frequency = <400000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <100>;
-+ i2c-scl-falling-time-ns = <100>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ status = "okay";
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <500>;
-+ i2c-scl-falling-time-ns = <500>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c2_pins>;
-+ status = "okay";
-+};
-+
-+&osc_sys {
-+ clock-frequency = <25000000>;
-+};
-+
-+&osc_aud {
-+ clock-frequency = <27000000>;
-+};
-+
-+&uart3 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart3_pins>;
-+ status = "okay";
-+};
diff --git a/target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch b/target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch
deleted file mode 100644
index 9b3f41ec1e..0000000000
--- a/target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch
+++ /dev/null
@@ -1,303 +0,0 @@
-From 28518a9637fee6b84464beff9d4308edc3efba72 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:36:59 +0800
-Subject: [PATCH 026/122] dt-bindings: pinctrl: Add StarFive JH7110 sys pinctrl
-
-Add pinctrl bindings for StarFive JH7110 SoC sys pinctrl controller.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- .../pinctrl/starfive,jh7110-sys-pinctrl.yaml | 142 ++++++++++++++++++
- MAINTAINERS | 6 +-
- .../pinctrl/starfive,jh7110-pinctrl.h | 115 ++++++++++++++
- 3 files changed, 261 insertions(+), 2 deletions(-)
- create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
- create mode 100644 include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
-@@ -0,0 +1,142 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-sys-pinctrl.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 SYS Pin Controller
-+
-+description: |
-+ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
-+
-+ Out of the SoC's many pins only the ones named PAD_GPIO0 to PAD_GPIO63
-+ can be multiplexed and have configurable bias, drive strength,
-+ schmitt trigger etc.
-+ Some peripherals have their I/O go through the 64 "GPIOs". This also
-+ includes a number of other UARTs, I2Cs, SPIs, PWMs etc.
-+ All these peripherals are connected to all 64 GPIOs such that
-+ any GPIO can be set up to be controlled by any of the peripherals.
-+
-+maintainers:
-+ - Jianlong Huang <jianlong.huang@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-sys-pinctrl
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ interrupt-controller: true
-+
-+ '#interrupt-cells':
-+ const: 2
-+
-+ gpio-controller: true
-+
-+ '#gpio-cells':
-+ const: 2
-+
-+patternProperties:
-+ '-[0-9]+$':
-+ type: object
-+ additionalProperties: false
-+ patternProperties:
-+ '-pins$':
-+ type: object
-+ description: |
-+ A pinctrl node should contain at least one subnode representing the
-+ pinctrl groups available on the machine. Each subnode will list the
-+ pins it needs, and how they should be configured, with regard to
-+ muxer configuration, bias, input enable/disable, input schmitt
-+ trigger enable/disable, slew-rate and drive strength.
-+ allOf:
-+ - $ref: /schemas/pinctrl/pincfg-node.yaml
-+ - $ref: /schemas/pinctrl/pinmux-node.yaml
-+ additionalProperties: false
-+
-+ properties:
-+ pinmux:
-+ description: |
-+ The list of GPIOs and their mux settings that properties in the
-+ node apply to. This should be set using the GPIOMUX or PINMUX
-+ macros.
-+
-+ bias-disable: true
-+
-+ bias-pull-up:
-+ type: boolean
-+
-+ bias-pull-down:
-+ type: boolean
-+
-+ drive-strength:
-+ enum: [ 2, 4, 8, 12 ]
-+
-+ input-enable: true
-+
-+ input-disable: true
-+
-+ input-schmitt-enable: true
-+
-+ input-schmitt-disable: true
-+
-+ slew-rate:
-+ maximum: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - interrupts
-+ - interrupt-controller
-+ - '#interrupt-cells'
-+ - gpio-controller
-+ - '#gpio-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pinctrl@13040000 {
-+ compatible = "starfive,jh7110-sys-pinctrl";
-+ reg = <0x13040000 0x10000>;
-+ clocks = <&syscrg 112>;
-+ resets = <&syscrg 2>;
-+ interrupts = <86>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ uart0-0 {
-+ tx-pins {
-+ pinmux = <0xff140005>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+
-+ rx-pins {
-+ pinmux = <0x0E000406>;
-+ bias-pull-up;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ };
-+ };
-+
-+...
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19665,13 +19665,15 @@ F: Documentation/devicetree/bindings/clo
- F: drivers/clk/starfive/clk-starfive-jh71*
- F: include/dt-bindings/clock/starfive?jh71*.h
-
--STARFIVE JH7100 PINCTRL DRIVER
-+STARFIVE JH71X0 PINCTRL DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Jianlong Huang <jianlong.huang@starfivetech.com>
- L: linux-gpio@vger.kernel.org
- S: Maintained
--F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
-+F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
- F: drivers/pinctrl/starfive/
- F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
-+F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-
- STARFIVE JH71X0 RESET CONTROLLER DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
---- /dev/null
-+++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-@@ -0,0 +1,115 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
-+#define __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
-+
-+/* sys_iomux pins */
-+#define PAD_GPIO0 0
-+#define PAD_GPIO1 1
-+#define PAD_GPIO2 2
-+#define PAD_GPIO3 3
-+#define PAD_GPIO4 4
-+#define PAD_GPIO5 5
-+#define PAD_GPIO6 6
-+#define PAD_GPIO7 7
-+#define PAD_GPIO8 8
-+#define PAD_GPIO9 9
-+#define PAD_GPIO10 10
-+#define PAD_GPIO11 11
-+#define PAD_GPIO12 12
-+#define PAD_GPIO13 13
-+#define PAD_GPIO14 14
-+#define PAD_GPIO15 15
-+#define PAD_GPIO16 16
-+#define PAD_GPIO17 17
-+#define PAD_GPIO18 18
-+#define PAD_GPIO19 19
-+#define PAD_GPIO20 20
-+#define PAD_GPIO21 21
-+#define PAD_GPIO22 22
-+#define PAD_GPIO23 23
-+#define PAD_GPIO24 24
-+#define PAD_GPIO25 25
-+#define PAD_GPIO26 26
-+#define PAD_GPIO27 27
-+#define PAD_GPIO28 28
-+#define PAD_GPIO29 29
-+#define PAD_GPIO30 30
-+#define PAD_GPIO31 31
-+#define PAD_GPIO32 32
-+#define PAD_GPIO33 33
-+#define PAD_GPIO34 34
-+#define PAD_GPIO35 35
-+#define PAD_GPIO36 36
-+#define PAD_GPIO37 37
-+#define PAD_GPIO38 38
-+#define PAD_GPIO39 39
-+#define PAD_GPIO40 40
-+#define PAD_GPIO41 41
-+#define PAD_GPIO42 42
-+#define PAD_GPIO43 43
-+#define PAD_GPIO44 44
-+#define PAD_GPIO45 45
-+#define PAD_GPIO46 46
-+#define PAD_GPIO47 47
-+#define PAD_GPIO48 48
-+#define PAD_GPIO49 49
-+#define PAD_GPIO50 50
-+#define PAD_GPIO51 51
-+#define PAD_GPIO52 52
-+#define PAD_GPIO53 53
-+#define PAD_GPIO54 54
-+#define PAD_GPIO55 55
-+#define PAD_GPIO56 56
-+#define PAD_GPIO57 57
-+#define PAD_GPIO58 58
-+#define PAD_GPIO59 59
-+#define PAD_GPIO60 60
-+#define PAD_GPIO61 61
-+#define PAD_GPIO62 62
-+#define PAD_GPIO63 63
-+#define PAD_SD0_CLK 64
-+#define PAD_SD0_CMD 65
-+#define PAD_SD0_DATA0 66
-+#define PAD_SD0_DATA1 67
-+#define PAD_SD0_DATA2 68
-+#define PAD_SD0_DATA3 69
-+#define PAD_SD0_DATA4 70
-+#define PAD_SD0_DATA5 71
-+#define PAD_SD0_DATA6 72
-+#define PAD_SD0_DATA7 73
-+#define PAD_SD0_STRB 74
-+#define PAD_GMAC1_MDC 75
-+#define PAD_GMAC1_MDIO 76
-+#define PAD_GMAC1_RXD0 77
-+#define PAD_GMAC1_RXD1 78
-+#define PAD_GMAC1_RXD2 79
-+#define PAD_GMAC1_RXD3 80
-+#define PAD_GMAC1_RXDV 81
-+#define PAD_GMAC1_RXC 82
-+#define PAD_GMAC1_TXD0 83
-+#define PAD_GMAC1_TXD1 84
-+#define PAD_GMAC1_TXD2 85
-+#define PAD_GMAC1_TXD3 86
-+#define PAD_GMAC1_TXEN 87
-+#define PAD_GMAC1_TXC 88
-+#define PAD_QSPI_SCLK 89
-+#define PAD_QSPI_CS0 90
-+#define PAD_QSPI_DATA0 91
-+#define PAD_QSPI_DATA1 92
-+#define PAD_QSPI_DATA2 93
-+#define PAD_QSPI_DATA3 94
-+
-+#define GPOUT_LOW 0
-+#define GPOUT_HIGH 1
-+
-+#define GPOEN_ENABLE 0
-+#define GPOEN_DISABLE 1
-+
-+#define GPI_NONE 255
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch b/target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch
deleted file mode 100644
index 8ef08efca1..0000000000
--- a/target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From 514cae455122c799638226f4358e8e6f5e155248 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:37:00 +0800
-Subject: [PATCH 027/122] dt-bindings: pinctrl: Add StarFive JH7110 aon pinctrl
-
-Add pinctrl bindings for StarFive JH7110 SoC aon pinctrl controller.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- .../pinctrl/starfive,jh7110-aon-pinctrl.yaml | 124 ++++++++++++++++++
- .../pinctrl/starfive,jh7110-pinctrl.h | 22 ++++
- 2 files changed, 146 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
-@@ -0,0 +1,124 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-aon-pinctrl.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 AON Pin Controller
-+
-+description: |
-+ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
-+
-+ Out of the SoC's many pins only the ones named PAD_RGPIO0 to PAD_RGPIO3
-+ can be multiplexed and have configurable bias, drive strength,
-+ schmitt trigger etc.
-+ Some peripherals such as PWM have their I/O go through the 4 "GPIOs".
-+
-+maintainers:
-+ - Jianlong Huang <jianlong.huang@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-aon-pinctrl
-+
-+ reg:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ interrupt-controller: true
-+
-+ '#interrupt-cells':
-+ const: 2
-+
-+ gpio-controller: true
-+
-+ '#gpio-cells':
-+ const: 2
-+
-+patternProperties:
-+ '-[0-9]+$':
-+ type: object
-+ additionalProperties: false
-+ patternProperties:
-+ '-pins$':
-+ type: object
-+ description: |
-+ A pinctrl node should contain at least one subnode representing the
-+ pinctrl groups available on the machine. Each subnode will list the
-+ pins it needs, and how they should be configured, with regard to
-+ muxer configuration, bias, input enable/disable, input schmitt
-+ trigger enable/disable, slew-rate and drive strength.
-+ allOf:
-+ - $ref: /schemas/pinctrl/pincfg-node.yaml
-+ - $ref: /schemas/pinctrl/pinmux-node.yaml
-+ additionalProperties: false
-+
-+ properties:
-+ pinmux:
-+ description: |
-+ The list of GPIOs and their mux settings that properties in the
-+ node apply to. This should be set using the GPIOMUX macro.
-+
-+ bias-disable: true
-+
-+ bias-pull-up:
-+ type: boolean
-+
-+ bias-pull-down:
-+ type: boolean
-+
-+ drive-strength:
-+ enum: [ 2, 4, 8, 12 ]
-+
-+ input-enable: true
-+
-+ input-disable: true
-+
-+ input-schmitt-enable: true
-+
-+ input-schmitt-disable: true
-+
-+ slew-rate:
-+ maximum: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - interrupt-controller
-+ - '#interrupt-cells'
-+ - gpio-controller
-+ - '#gpio-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pinctrl@17020000 {
-+ compatible = "starfive,jh7110-aon-pinctrl";
-+ reg = <0x17020000 0x10000>;
-+ resets = <&aoncrg 2>;
-+ interrupts = <85>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ pwm-0 {
-+ pwm-pins {
-+ pinmux = <0xff030802>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+ };
-+
-+...
---- a/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-+++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-@@ -104,6 +104,28 @@
- #define PAD_QSPI_DATA2 93
- #define PAD_QSPI_DATA3 94
-
-+/* aon_iomux pins */
-+#define PAD_TESTEN 0
-+#define PAD_RGPIO0 1
-+#define PAD_RGPIO1 2
-+#define PAD_RGPIO2 3
-+#define PAD_RGPIO3 4
-+#define PAD_RSTN 5
-+#define PAD_GMAC0_MDC 6
-+#define PAD_GMAC0_MDIO 7
-+#define PAD_GMAC0_RXD0 8
-+#define PAD_GMAC0_RXD1 9
-+#define PAD_GMAC0_RXD2 10
-+#define PAD_GMAC0_RXD3 11
-+#define PAD_GMAC0_RXDV 12
-+#define PAD_GMAC0_RXC 13
-+#define PAD_GMAC0_TXD0 14
-+#define PAD_GMAC0_TXD1 15
-+#define PAD_GMAC0_TXD2 16
-+#define PAD_GMAC0_TXD3 17
-+#define PAD_GMAC0_TXEN 18
-+#define PAD_GMAC0_TXC 19
-+
- #define GPOUT_LOW 0
- #define GPOUT_HIGH 1
-
diff --git a/target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch b/target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch
deleted file mode 100644
index d5735b5980..0000000000
--- a/target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch
+++ /dev/null
@@ -1,1581 +0,0 @@
-From 4dba3156173e59131d234d702388ee7283bac8a9 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:37:01 +0800
-Subject: [PATCH 028/122] pinctrl: starfive: Add StarFive JH7110 sys controller
- driver
-
-Add pinctrl driver for StarFive JH7110 SoC sys pinctrl controller.
-
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- MAINTAINERS | 2 +-
- drivers/pinctrl/starfive/Kconfig | 21 +
- drivers/pinctrl/starfive/Makefile | 3 +
- .../starfive/pinctrl-starfive-jh7110-sys.c | 449 ++++++++
- .../starfive/pinctrl-starfive-jh7110.c | 982 ++++++++++++++++++
- .../starfive/pinctrl-starfive-jh7110.h | 70 ++
- 6 files changed, 1526 insertions(+), 1 deletion(-)
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19671,7 +19671,7 @@ M: Jianlong Huang <jianlong.huang@starfi
- L: linux-gpio@vger.kernel.org
- S: Maintained
- F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
--F: drivers/pinctrl/starfive/
-+F: drivers/pinctrl/starfive/pinctrl-starfive-jh71*
- F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
- F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-
---- a/drivers/pinctrl/starfive/Kconfig
-+++ b/drivers/pinctrl/starfive/Kconfig
-@@ -16,3 +16,24 @@ config PINCTRL_STARFIVE_JH7100
- This also provides an interface to the GPIO pins not used by other
- peripherals supporting inputs, outputs, configuring pull-up/pull-down
- and interrupts on input changes.
-+
-+config PINCTRL_STARFIVE_JH7110
-+ bool
-+ select GENERIC_PINCTRL_GROUPS
-+ select GENERIC_PINMUX_FUNCTIONS
-+ select GENERIC_PINCONF
-+ select GPIOLIB
-+ select GPIOLIB_IRQCHIP
-+ select OF_GPIO
-+
-+config PINCTRL_STARFIVE_JH7110_SYS
-+ tristate "System pinctrl and GPIO driver for the StarFive JH7110 SoC"
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ depends on OF
-+ select PINCTRL_STARFIVE_JH7110
-+ default SOC_STARFIVE
-+ help
-+ Say yes here to support system pin control on the StarFive JH7110 SoC.
-+ This also provides an interface to the GPIO pins not used by other
-+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
-+ and interrupts on input changes.
---- a/drivers/pinctrl/starfive/Makefile
-+++ b/drivers/pinctrl/starfive/Makefile
-@@ -1,3 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0
-
- obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o
-+
-+obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
-+obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
-@@ -0,0 +1,449 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC sys controller
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/gpio/driver.h>
-+#include <linux/io.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/pinctrl/pinmux.h>
-+
-+#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
-+
-+#include "../core.h"
-+#include "../pinctrl-utils.h"
-+#include "../pinmux.h"
-+#include "../pinconf.h"
-+#include "pinctrl-starfive-jh7110.h"
-+
-+#define JH7110_SYS_NGPIO 64
-+#define JH7110_SYS_GC_BASE 0
-+
-+/* registers */
-+#define JH7110_SYS_DOEN 0x000
-+#define JH7110_SYS_DOUT 0x040
-+#define JH7110_SYS_GPI 0x080
-+#define JH7110_SYS_GPIOIN 0x118
-+
-+#define JH7110_SYS_GPIOEN 0x0dc
-+#define JH7110_SYS_GPIOIS0 0x0e0
-+#define JH7110_SYS_GPIOIS1 0x0e4
-+#define JH7110_SYS_GPIOIC0 0x0e8
-+#define JH7110_SYS_GPIOIC1 0x0ec
-+#define JH7110_SYS_GPIOIBE0 0x0f0
-+#define JH7110_SYS_GPIOIBE1 0x0f4
-+#define JH7110_SYS_GPIOIEV0 0x0f8
-+#define JH7110_SYS_GPIOIEV1 0x0fc
-+#define JH7110_SYS_GPIOIE0 0x100
-+#define JH7110_SYS_GPIOIE1 0x104
-+#define JH7110_SYS_GPIORIS0 0x108
-+#define JH7110_SYS_GPIORIS1 0x10c
-+#define JH7110_SYS_GPIOMIS0 0x110
-+#define JH7110_SYS_GPIOMIS1 0x114
-+
-+#define JH7110_SYS_GPO_PDA_0_74_CFG 0x120
-+#define JH7110_SYS_GPO_PDA_89_94_CFG 0x284
-+
-+static const struct pinctrl_pin_desc jh7110_sys_pins[] = {
-+ PINCTRL_PIN(PAD_GPIO0, "GPIO0"),
-+ PINCTRL_PIN(PAD_GPIO1, "GPIO1"),
-+ PINCTRL_PIN(PAD_GPIO2, "GPIO2"),
-+ PINCTRL_PIN(PAD_GPIO3, "GPIO3"),
-+ PINCTRL_PIN(PAD_GPIO4, "GPIO4"),
-+ PINCTRL_PIN(PAD_GPIO5, "GPIO5"),
-+ PINCTRL_PIN(PAD_GPIO6, "GPIO6"),
-+ PINCTRL_PIN(PAD_GPIO7, "GPIO7"),
-+ PINCTRL_PIN(PAD_GPIO8, "GPIO8"),
-+ PINCTRL_PIN(PAD_GPIO9, "GPIO9"),
-+ PINCTRL_PIN(PAD_GPIO10, "GPIO10"),
-+ PINCTRL_PIN(PAD_GPIO11, "GPIO11"),
-+ PINCTRL_PIN(PAD_GPIO12, "GPIO12"),
-+ PINCTRL_PIN(PAD_GPIO13, "GPIO13"),
-+ PINCTRL_PIN(PAD_GPIO14, "GPIO14"),
-+ PINCTRL_PIN(PAD_GPIO15, "GPIO15"),
-+ PINCTRL_PIN(PAD_GPIO16, "GPIO16"),
-+ PINCTRL_PIN(PAD_GPIO17, "GPIO17"),
-+ PINCTRL_PIN(PAD_GPIO18, "GPIO18"),
-+ PINCTRL_PIN(PAD_GPIO19, "GPIO19"),
-+ PINCTRL_PIN(PAD_GPIO20, "GPIO20"),
-+ PINCTRL_PIN(PAD_GPIO21, "GPIO21"),
-+ PINCTRL_PIN(PAD_GPIO22, "GPIO22"),
-+ PINCTRL_PIN(PAD_GPIO23, "GPIO23"),
-+ PINCTRL_PIN(PAD_GPIO24, "GPIO24"),
-+ PINCTRL_PIN(PAD_GPIO25, "GPIO25"),
-+ PINCTRL_PIN(PAD_GPIO26, "GPIO26"),
-+ PINCTRL_PIN(PAD_GPIO27, "GPIO27"),
-+ PINCTRL_PIN(PAD_GPIO28, "GPIO28"),
-+ PINCTRL_PIN(PAD_GPIO29, "GPIO29"),
-+ PINCTRL_PIN(PAD_GPIO30, "GPIO30"),
-+ PINCTRL_PIN(PAD_GPIO31, "GPIO31"),
-+ PINCTRL_PIN(PAD_GPIO32, "GPIO32"),
-+ PINCTRL_PIN(PAD_GPIO33, "GPIO33"),
-+ PINCTRL_PIN(PAD_GPIO34, "GPIO34"),
-+ PINCTRL_PIN(PAD_GPIO35, "GPIO35"),
-+ PINCTRL_PIN(PAD_GPIO36, "GPIO36"),
-+ PINCTRL_PIN(PAD_GPIO37, "GPIO37"),
-+ PINCTRL_PIN(PAD_GPIO38, "GPIO38"),
-+ PINCTRL_PIN(PAD_GPIO39, "GPIO39"),
-+ PINCTRL_PIN(PAD_GPIO40, "GPIO40"),
-+ PINCTRL_PIN(PAD_GPIO41, "GPIO41"),
-+ PINCTRL_PIN(PAD_GPIO42, "GPIO42"),
-+ PINCTRL_PIN(PAD_GPIO43, "GPIO43"),
-+ PINCTRL_PIN(PAD_GPIO44, "GPIO44"),
-+ PINCTRL_PIN(PAD_GPIO45, "GPIO45"),
-+ PINCTRL_PIN(PAD_GPIO46, "GPIO46"),
-+ PINCTRL_PIN(PAD_GPIO47, "GPIO47"),
-+ PINCTRL_PIN(PAD_GPIO48, "GPIO48"),
-+ PINCTRL_PIN(PAD_GPIO49, "GPIO49"),
-+ PINCTRL_PIN(PAD_GPIO50, "GPIO50"),
-+ PINCTRL_PIN(PAD_GPIO51, "GPIO51"),
-+ PINCTRL_PIN(PAD_GPIO52, "GPIO52"),
-+ PINCTRL_PIN(PAD_GPIO53, "GPIO53"),
-+ PINCTRL_PIN(PAD_GPIO54, "GPIO54"),
-+ PINCTRL_PIN(PAD_GPIO55, "GPIO55"),
-+ PINCTRL_PIN(PAD_GPIO56, "GPIO56"),
-+ PINCTRL_PIN(PAD_GPIO57, "GPIO57"),
-+ PINCTRL_PIN(PAD_GPIO58, "GPIO58"),
-+ PINCTRL_PIN(PAD_GPIO59, "GPIO59"),
-+ PINCTRL_PIN(PAD_GPIO60, "GPIO60"),
-+ PINCTRL_PIN(PAD_GPIO61, "GPIO61"),
-+ PINCTRL_PIN(PAD_GPIO62, "GPIO62"),
-+ PINCTRL_PIN(PAD_GPIO63, "GPIO63"),
-+ PINCTRL_PIN(PAD_SD0_CLK, "SD0_CLK"),
-+ PINCTRL_PIN(PAD_SD0_CMD, "SD0_CMD"),
-+ PINCTRL_PIN(PAD_SD0_DATA0, "SD0_DATA0"),
-+ PINCTRL_PIN(PAD_SD0_DATA1, "SD0_DATA1"),
-+ PINCTRL_PIN(PAD_SD0_DATA2, "SD0_DATA2"),
-+ PINCTRL_PIN(PAD_SD0_DATA3, "SD0_DATA3"),
-+ PINCTRL_PIN(PAD_SD0_DATA4, "SD0_DATA4"),
-+ PINCTRL_PIN(PAD_SD0_DATA5, "SD0_DATA5"),
-+ PINCTRL_PIN(PAD_SD0_DATA6, "SD0_DATA6"),
-+ PINCTRL_PIN(PAD_SD0_DATA7, "SD0_DATA7"),
-+ PINCTRL_PIN(PAD_SD0_STRB, "SD0_STRB"),
-+ PINCTRL_PIN(PAD_GMAC1_MDC, "GMAC1_MDC"),
-+ PINCTRL_PIN(PAD_GMAC1_MDIO, "GMAC1_MDIO"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD0, "GMAC1_RXD0"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD1, "GMAC1_RXD1"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD2, "GMAC1_RXD2"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD3, "GMAC1_RXD3"),
-+ PINCTRL_PIN(PAD_GMAC1_RXDV, "GMAC1_RXDV"),
-+ PINCTRL_PIN(PAD_GMAC1_RXC, "GMAC1_RXC"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD0, "GMAC1_TXD0"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD1, "GMAC1_TXD1"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD2, "GMAC1_TXD2"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD3, "GMAC1_TXD3"),
-+ PINCTRL_PIN(PAD_GMAC1_TXEN, "GMAC1_TXEN"),
-+ PINCTRL_PIN(PAD_GMAC1_TXC, "GMAC1_TXC"),
-+ PINCTRL_PIN(PAD_QSPI_SCLK, "QSPI_SCLK"),
-+ PINCTRL_PIN(PAD_QSPI_CS0, "QSPI_CS0"),
-+ PINCTRL_PIN(PAD_QSPI_DATA0, "QSPI_DATA0"),
-+ PINCTRL_PIN(PAD_QSPI_DATA1, "QSPI_DATA1"),
-+ PINCTRL_PIN(PAD_QSPI_DATA2, "QSPI_DATA2"),
-+ PINCTRL_PIN(PAD_QSPI_DATA3, "QSPI_DATA3"),
-+};
-+
-+struct jh7110_func_sel {
-+ u16 offset;
-+ u8 shift;
-+ u8 max;
-+};
-+
-+static const struct jh7110_func_sel
-+ jh7110_sys_func_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
-+ [PAD_GMAC1_RXC] = { 0x29c, 0, 1 },
-+ [PAD_GPIO10] = { 0x29c, 2, 3 },
-+ [PAD_GPIO11] = { 0x29c, 5, 3 },
-+ [PAD_GPIO12] = { 0x29c, 8, 3 },
-+ [PAD_GPIO13] = { 0x29c, 11, 3 },
-+ [PAD_GPIO14] = { 0x29c, 14, 3 },
-+ [PAD_GPIO15] = { 0x29c, 17, 3 },
-+ [PAD_GPIO16] = { 0x29c, 20, 3 },
-+ [PAD_GPIO17] = { 0x29c, 23, 3 },
-+ [PAD_GPIO18] = { 0x29c, 26, 3 },
-+ [PAD_GPIO19] = { 0x29c, 29, 3 },
-+
-+ [PAD_GPIO20] = { 0x2a0, 0, 3 },
-+ [PAD_GPIO21] = { 0x2a0, 3, 3 },
-+ [PAD_GPIO22] = { 0x2a0, 6, 3 },
-+ [PAD_GPIO23] = { 0x2a0, 9, 3 },
-+ [PAD_GPIO24] = { 0x2a0, 12, 3 },
-+ [PAD_GPIO25] = { 0x2a0, 15, 3 },
-+ [PAD_GPIO26] = { 0x2a0, 18, 3 },
-+ [PAD_GPIO27] = { 0x2a0, 21, 3 },
-+ [PAD_GPIO28] = { 0x2a0, 24, 3 },
-+ [PAD_GPIO29] = { 0x2a0, 27, 3 },
-+
-+ [PAD_GPIO30] = { 0x2a4, 0, 3 },
-+ [PAD_GPIO31] = { 0x2a4, 3, 3 },
-+ [PAD_GPIO32] = { 0x2a4, 6, 3 },
-+ [PAD_GPIO33] = { 0x2a4, 9, 3 },
-+ [PAD_GPIO34] = { 0x2a4, 12, 3 },
-+ [PAD_GPIO35] = { 0x2a4, 15, 3 },
-+ [PAD_GPIO36] = { 0x2a4, 17, 3 },
-+ [PAD_GPIO37] = { 0x2a4, 20, 3 },
-+ [PAD_GPIO38] = { 0x2a4, 23, 3 },
-+ [PAD_GPIO39] = { 0x2a4, 26, 3 },
-+ [PAD_GPIO40] = { 0x2a4, 29, 3 },
-+
-+ [PAD_GPIO41] = { 0x2a8, 0, 3 },
-+ [PAD_GPIO42] = { 0x2a8, 3, 3 },
-+ [PAD_GPIO43] = { 0x2a8, 6, 3 },
-+ [PAD_GPIO44] = { 0x2a8, 9, 3 },
-+ [PAD_GPIO45] = { 0x2a8, 12, 3 },
-+ [PAD_GPIO46] = { 0x2a8, 15, 3 },
-+ [PAD_GPIO47] = { 0x2a8, 18, 3 },
-+ [PAD_GPIO48] = { 0x2a8, 21, 3 },
-+ [PAD_GPIO49] = { 0x2a8, 24, 3 },
-+ [PAD_GPIO50] = { 0x2a8, 27, 3 },
-+ [PAD_GPIO51] = { 0x2a8, 30, 3 },
-+
-+ [PAD_GPIO52] = { 0x2ac, 0, 3 },
-+ [PAD_GPIO53] = { 0x2ac, 2, 3 },
-+ [PAD_GPIO54] = { 0x2ac, 4, 3 },
-+ [PAD_GPIO55] = { 0x2ac, 6, 3 },
-+ [PAD_GPIO56] = { 0x2ac, 9, 3 },
-+ [PAD_GPIO57] = { 0x2ac, 12, 3 },
-+ [PAD_GPIO58] = { 0x2ac, 15, 3 },
-+ [PAD_GPIO59] = { 0x2ac, 18, 3 },
-+ [PAD_GPIO60] = { 0x2ac, 21, 3 },
-+ [PAD_GPIO61] = { 0x2ac, 24, 3 },
-+ [PAD_GPIO62] = { 0x2ac, 27, 3 },
-+ [PAD_GPIO63] = { 0x2ac, 30, 3 },
-+
-+ [PAD_GPIO6] = { 0x2b0, 0, 3 },
-+ [PAD_GPIO7] = { 0x2b0, 2, 3 },
-+ [PAD_GPIO8] = { 0x2b0, 5, 3 },
-+ [PAD_GPIO9] = { 0x2b0, 8, 3 },
-+};
-+
-+struct jh7110_vin_group_sel {
-+ u16 offset;
-+ u8 shift;
-+ u8 group;
-+};
-+
-+static const struct jh7110_vin_group_sel
-+ jh7110_sys_vin_group_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
-+ [PAD_GPIO6] = { 0x2b4, 21, 0 },
-+ [PAD_GPIO7] = { 0x2b4, 18, 0 },
-+ [PAD_GPIO8] = { 0x2b4, 15, 0 },
-+ [PAD_GPIO9] = { 0x2b0, 11, 0 },
-+ [PAD_GPIO10] = { 0x2b0, 20, 0 },
-+ [PAD_GPIO11] = { 0x2b0, 23, 0 },
-+ [PAD_GPIO12] = { 0x2b0, 26, 0 },
-+ [PAD_GPIO13] = { 0x2b0, 29, 0 },
-+ [PAD_GPIO14] = { 0x2b4, 0, 0 },
-+ [PAD_GPIO15] = { 0x2b4, 3, 0 },
-+ [PAD_GPIO16] = { 0x2b4, 6, 0 },
-+ [PAD_GPIO17] = { 0x2b4, 9, 0 },
-+ [PAD_GPIO18] = { 0x2b4, 12, 0 },
-+ [PAD_GPIO19] = { 0x2b0, 14, 0 },
-+ [PAD_GPIO20] = { 0x2b0, 17, 0 },
-+
-+ [PAD_GPIO21] = { 0x2b4, 21, 1 },
-+ [PAD_GPIO22] = { 0x2b4, 18, 1 },
-+ [PAD_GPIO23] = { 0x2b4, 15, 1 },
-+ [PAD_GPIO24] = { 0x2b0, 11, 1 },
-+ [PAD_GPIO25] = { 0x2b0, 20, 1 },
-+ [PAD_GPIO26] = { 0x2b0, 23, 1 },
-+ [PAD_GPIO27] = { 0x2b0, 26, 1 },
-+ [PAD_GPIO28] = { 0x2b0, 29, 1 },
-+ [PAD_GPIO29] = { 0x2b4, 0, 1 },
-+ [PAD_GPIO30] = { 0x2b4, 3, 1 },
-+ [PAD_GPIO31] = { 0x2b4, 6, 1 },
-+ [PAD_GPIO32] = { 0x2b4, 9, 1 },
-+ [PAD_GPIO33] = { 0x2b4, 12, 1 },
-+ [PAD_GPIO34] = { 0x2b0, 14, 1 },
-+ [PAD_GPIO35] = { 0x2b0, 17, 1 },
-+
-+ [PAD_GPIO36] = { 0x2b4, 21, 2 },
-+ [PAD_GPIO37] = { 0x2b4, 18, 2 },
-+ [PAD_GPIO38] = { 0x2b4, 15, 2 },
-+ [PAD_GPIO39] = { 0x2b0, 11, 2 },
-+ [PAD_GPIO40] = { 0x2b0, 20, 2 },
-+ [PAD_GPIO41] = { 0x2b0, 23, 2 },
-+ [PAD_GPIO42] = { 0x2b0, 26, 2 },
-+ [PAD_GPIO43] = { 0x2b0, 29, 2 },
-+ [PAD_GPIO44] = { 0x2b4, 0, 2 },
-+ [PAD_GPIO45] = { 0x2b4, 3, 2 },
-+ [PAD_GPIO46] = { 0x2b4, 6, 2 },
-+ [PAD_GPIO47] = { 0x2b4, 9, 2 },
-+ [PAD_GPIO48] = { 0x2b4, 12, 2 },
-+ [PAD_GPIO49] = { 0x2b0, 14, 2 },
-+ [PAD_GPIO50] = { 0x2b0, 17, 2 },
-+};
-+
-+static void jh7110_set_function(struct jh7110_pinctrl *sfp,
-+ unsigned int pin, u32 func)
-+{
-+ const struct jh7110_func_sel *fs = &jh7110_sys_func_sel[pin];
-+ unsigned long flags;
-+ void __iomem *reg;
-+ u32 mask;
-+
-+ if (!fs->offset)
-+ return;
-+
-+ if (func > fs->max)
-+ return;
-+
-+ reg = sfp->base + fs->offset;
-+ func = func << fs->shift;
-+ mask = 0x3U << fs->shift;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ func |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(func, reg);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static void jh7110_set_vin_group(struct jh7110_pinctrl *sfp,
-+ unsigned int pin)
-+{
-+ const struct jh7110_vin_group_sel *gs = &jh7110_sys_vin_group_sel[pin];
-+ unsigned long flags;
-+ void __iomem *reg;
-+ u32 mask;
-+ u32 grp;
-+
-+ if (!gs->offset)
-+ return;
-+
-+ reg = sfp->base + gs->offset;
-+ grp = gs->group << gs->shift;
-+ mask = 0x3U << gs->shift;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ grp |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(grp, reg);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_sys_set_one_pin_mux(struct jh7110_pinctrl *sfp,
-+ unsigned int pin,
-+ unsigned int din, u32 dout,
-+ u32 doen, u32 func)
-+{
-+ if (pin < sfp->gc.ngpio && func == 0)
-+ jh7110_set_gpiomux(sfp, pin, din, dout, doen);
-+
-+ jh7110_set_function(sfp, pin, func);
-+
-+ if (pin < sfp->gc.ngpio && func == 2)
-+ jh7110_set_vin_group(sfp, pin);
-+
-+ return 0;
-+}
-+
-+static int jh7110_sys_get_padcfg_base(struct jh7110_pinctrl *sfp,
-+ unsigned int pin)
-+{
-+ if (pin < PAD_GMAC1_MDC)
-+ return JH7110_SYS_GPO_PDA_0_74_CFG;
-+ else if (pin > PAD_GMAC1_TXC && pin <= PAD_QSPI_DATA3)
-+ return JH7110_SYS_GPO_PDA_89_94_CFG;
-+ else
-+ return -1;
-+}
-+
-+static void jh7110_sys_irq_handler(struct irq_desc *desc)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ unsigned long mis;
-+ unsigned int pin;
-+
-+ chained_irq_enter(chip, desc);
-+
-+ mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS0);
-+ for_each_set_bit(pin, &mis, 32)
-+ generic_handle_domain_irq(sfp->gc.irq.domain, pin);
-+
-+ mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS1);
-+ for_each_set_bit(pin, &mis, 32)
-+ generic_handle_domain_irq(sfp->gc.irq.domain, pin + 32);
-+
-+ chained_irq_exit(chip, desc);
-+}
-+
-+static int jh7110_sys_init_hw(struct gpio_chip *gc)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+
-+ /* mask all GPIO interrupts */
-+ writel(0U, sfp->base + JH7110_SYS_GPIOIE0);
-+ writel(0U, sfp->base + JH7110_SYS_GPIOIE1);
-+ /* clear edge interrupt flags */
-+ writel(~0U, sfp->base + JH7110_SYS_GPIOIC0);
-+ writel(~0U, sfp->base + JH7110_SYS_GPIOIC1);
-+ /* enable GPIO interrupts */
-+ writel(1U, sfp->base + JH7110_SYS_GPIOEN);
-+ return 0;
-+}
-+
-+static const struct jh7110_gpio_irq_reg jh7110_sys_irq_reg = {
-+ .is_reg_base = JH7110_SYS_GPIOIS0,
-+ .ic_reg_base = JH7110_SYS_GPIOIC0,
-+ .ibe_reg_base = JH7110_SYS_GPIOIBE0,
-+ .iev_reg_base = JH7110_SYS_GPIOIEV0,
-+ .ie_reg_base = JH7110_SYS_GPIOIE0,
-+ .ris_reg_base = JH7110_SYS_GPIORIS0,
-+ .mis_reg_base = JH7110_SYS_GPIOMIS0,
-+};
-+
-+static const struct jh7110_pinctrl_soc_info jh7110_sys_pinctrl_info = {
-+ .pins = jh7110_sys_pins,
-+ .npins = ARRAY_SIZE(jh7110_sys_pins),
-+ .ngpios = JH7110_SYS_NGPIO,
-+ .gc_base = JH7110_SYS_GC_BASE,
-+ .dout_reg_base = JH7110_SYS_DOUT,
-+ .dout_mask = GENMASK(6, 0),
-+ .doen_reg_base = JH7110_SYS_DOEN,
-+ .doen_mask = GENMASK(5, 0),
-+ .gpi_reg_base = JH7110_SYS_GPI,
-+ .gpi_mask = GENMASK(6, 0),
-+ .gpioin_reg_base = JH7110_SYS_GPIOIN,
-+ .irq_reg = &jh7110_sys_irq_reg,
-+ .jh7110_set_one_pin_mux = jh7110_sys_set_one_pin_mux,
-+ .jh7110_get_padcfg_base = jh7110_sys_get_padcfg_base,
-+ .jh7110_gpio_irq_handler = jh7110_sys_irq_handler,
-+ .jh7110_gpio_init_hw = jh7110_sys_init_hw,
-+};
-+
-+static const struct of_device_id jh7110_sys_pinctrl_of_match[] = {
-+ {
-+ .compatible = "starfive,jh7110-sys-pinctrl",
-+ .data = &jh7110_sys_pinctrl_info,
-+ },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_sys_pinctrl_of_match);
-+
-+static struct platform_driver jh7110_sys_pinctrl_driver = {
-+ .probe = jh7110_pinctrl_probe,
-+ .driver = {
-+ .name = "starfive-jh7110-sys-pinctrl",
-+ .of_match_table = jh7110_sys_pinctrl_of_match,
-+ },
-+};
-+module_platform_driver(jh7110_sys_pinctrl_driver);
-+
-+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC sys controller");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
-@@ -0,0 +1,982 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/gpio/driver.h>
-+#include <linux/io.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+#include <linux/seq_file.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/pinctrl/consumer.h>
-+#include <linux/pinctrl/pinconf.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/pinctrl/pinmux.h>
-+
-+#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
-+
-+#include "../core.h"
-+#include "../pinctrl-utils.h"
-+#include "../pinmux.h"
-+#include "../pinconf.h"
-+#include "pinctrl-starfive-jh7110.h"
-+
-+/* pad control bits */
-+#define JH7110_PADCFG_POS BIT(7)
-+#define JH7110_PADCFG_SMT BIT(6)
-+#define JH7110_PADCFG_SLEW BIT(5)
-+#define JH7110_PADCFG_PD BIT(4)
-+#define JH7110_PADCFG_PU BIT(3)
-+#define JH7110_PADCFG_BIAS (JH7110_PADCFG_PD | JH7110_PADCFG_PU)
-+#define JH7110_PADCFG_DS_MASK GENMASK(2, 1)
-+#define JH7110_PADCFG_DS_2MA (0U << 1)
-+#define JH7110_PADCFG_DS_4MA BIT(1)
-+#define JH7110_PADCFG_DS_8MA (2U << 1)
-+#define JH7110_PADCFG_DS_12MA (3U << 1)
-+#define JH7110_PADCFG_IE BIT(0)
-+
-+/*
-+ * The packed pinmux values from the device tree look like this:
-+ *
-+ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
-+ * | din | dout | doen | function | pin |
-+ */
-+static unsigned int jh7110_pinmux_din(u32 v)
-+{
-+ return (v & GENMASK(31, 24)) >> 24;
-+}
-+
-+static u32 jh7110_pinmux_dout(u32 v)
-+{
-+ return (v & GENMASK(23, 16)) >> 16;
-+}
-+
-+static u32 jh7110_pinmux_doen(u32 v)
-+{
-+ return (v & GENMASK(15, 10)) >> 10;
-+}
-+
-+static u32 jh7110_pinmux_function(u32 v)
-+{
-+ return (v & GENMASK(9, 8)) >> 8;
-+}
-+
-+static unsigned int jh7110_pinmux_pin(u32 v)
-+{
-+ return v & GENMASK(7, 0);
-+}
-+
-+static struct jh7110_pinctrl *jh7110_from_irq_data(struct irq_data *d)
-+{
-+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-+
-+ return container_of(gc, struct jh7110_pinctrl, gc);
-+}
-+
-+struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc)
-+{
-+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-+
-+ return container_of(gc, struct jh7110_pinctrl, gc);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_from_irq_desc);
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7110_pin_dbg_show(struct pinctrl_dev *pctldev,
-+ struct seq_file *s, unsigned int pin)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ seq_printf(s, "%s", dev_name(pctldev->dev));
-+
-+ if (pin < sfp->gc.ngpio) {
-+ unsigned int offset = 4 * (pin / 4);
-+ unsigned int shift = 8 * (pin % 4);
-+ u32 dout = readl_relaxed(sfp->base + info->dout_reg_base + offset);
-+ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
-+ u32 gpi = readl_relaxed(sfp->base + info->gpi_reg_base + offset);
-+
-+ dout = (dout >> shift) & info->dout_mask;
-+ doen = (doen >> shift) & info->doen_mask;
-+ gpi = ((gpi >> shift) - 2) & info->gpi_mask;
-+
-+ seq_printf(s, " dout=%u doen=%u din=%u", dout, doen, gpi);
-+ }
-+}
-+#else
-+#define jh7110_pin_dbg_show NULL
-+#endif
-+
-+static int jh7110_dt_node_to_map(struct pinctrl_dev *pctldev,
-+ struct device_node *np,
-+ struct pinctrl_map **maps,
-+ unsigned int *num_maps)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ struct device *dev = sfp->gc.parent;
-+ struct device_node *child;
-+ struct pinctrl_map *map;
-+ const char **pgnames;
-+ const char *grpname;
-+ int ngroups;
-+ int nmaps;
-+ int ret;
-+
-+ ngroups = 0;
-+ for_each_child_of_node(np, child)
-+ ngroups += 1;
-+ nmaps = 2 * ngroups;
-+
-+ pgnames = devm_kcalloc(dev, ngroups, sizeof(*pgnames), GFP_KERNEL);
-+ if (!pgnames)
-+ return -ENOMEM;
-+
-+ map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
-+ if (!map)
-+ return -ENOMEM;
-+
-+ nmaps = 0;
-+ ngroups = 0;
-+ mutex_lock(&sfp->mutex);
-+ for_each_child_of_node(np, child) {
-+ int npins = of_property_count_u32_elems(child, "pinmux");
-+ int *pins;
-+ u32 *pinmux;
-+ int i;
-+
-+ if (npins < 1) {
-+ dev_err(dev,
-+ "invalid pinctrl group %pOFn.%pOFn: pinmux not set\n",
-+ np, child);
-+ ret = -EINVAL;
-+ goto put_child;
-+ }
-+
-+ grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", np, child);
-+ if (!grpname) {
-+ ret = -ENOMEM;
-+ goto put_child;
-+ }
-+
-+ pgnames[ngroups++] = grpname;
-+
-+ pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
-+ if (!pins) {
-+ ret = -ENOMEM;
-+ goto put_child;
-+ }
-+
-+ pinmux = devm_kcalloc(dev, npins, sizeof(*pinmux), GFP_KERNEL);
-+ if (!pinmux) {
-+ ret = -ENOMEM;
-+ goto put_child;
-+ }
-+
-+ ret = of_property_read_u32_array(child, "pinmux", pinmux, npins);
-+ if (ret)
-+ goto put_child;
-+
-+ for (i = 0; i < npins; i++)
-+ pins[i] = jh7110_pinmux_pin(pinmux[i]);
-+
-+ map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
-+ map[nmaps].data.mux.function = np->name;
-+ map[nmaps].data.mux.group = grpname;
-+ nmaps += 1;
-+
-+ ret = pinctrl_generic_add_group(pctldev, grpname,
-+ pins, npins, pinmux);
-+ if (ret < 0) {
-+ dev_err(dev, "error adding group %s: %d\n", grpname, ret);
-+ goto put_child;
-+ }
-+
-+ ret = pinconf_generic_parse_dt_config(child, pctldev,
-+ &map[nmaps].data.configs.configs,
-+ &map[nmaps].data.configs.num_configs);
-+ if (ret) {
-+ dev_err(dev, "error parsing pin config of group %s: %d\n",
-+ grpname, ret);
-+ goto put_child;
-+ }
-+
-+ /* don't create a map if there are no pinconf settings */
-+ if (map[nmaps].data.configs.num_configs == 0)
-+ continue;
-+
-+ map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
-+ map[nmaps].data.configs.group_or_pin = grpname;
-+ nmaps += 1;
-+ }
-+
-+ ret = pinmux_generic_add_function(pctldev, np->name,
-+ pgnames, ngroups, NULL);
-+ if (ret < 0) {
-+ dev_err(dev, "error adding function %s: %d\n", np->name, ret);
-+ goto free_map;
-+ }
-+ mutex_unlock(&sfp->mutex);
-+
-+ *maps = map;
-+ *num_maps = nmaps;
-+ return 0;
-+
-+put_child:
-+ of_node_put(child);
-+free_map:
-+ pinctrl_utils_free_map(pctldev, map, nmaps);
-+ mutex_unlock(&sfp->mutex);
-+ return ret;
-+}
-+
-+static const struct pinctrl_ops jh7110_pinctrl_ops = {
-+ .get_groups_count = pinctrl_generic_get_group_count,
-+ .get_group_name = pinctrl_generic_get_group_name,
-+ .get_group_pins = pinctrl_generic_get_group_pins,
-+ .pin_dbg_show = jh7110_pin_dbg_show,
-+ .dt_node_to_map = jh7110_dt_node_to_map,
-+ .dt_free_map = pinctrl_utils_free_map,
-+};
-+
-+void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
-+ unsigned int din, u32 dout, u32 doen)
-+{
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ unsigned int offset = 4 * (pin / 4);
-+ unsigned int shift = 8 * (pin % 4);
-+ u32 dout_mask = info->dout_mask << shift;
-+ u32 done_mask = info->doen_mask << shift;
-+ u32 ival, imask;
-+ void __iomem *reg_dout;
-+ void __iomem *reg_doen;
-+ void __iomem *reg_din;
-+ unsigned long flags;
-+
-+ reg_dout = sfp->base + info->dout_reg_base + offset;
-+ reg_doen = sfp->base + info->doen_reg_base + offset;
-+ dout <<= shift;
-+ doen <<= shift;
-+ if (din != GPI_NONE) {
-+ unsigned int ioffset = 4 * (din / 4);
-+ unsigned int ishift = 8 * (din % 4);
-+
-+ reg_din = sfp->base + info->gpi_reg_base + ioffset;
-+ ival = (pin + 2) << ishift;
-+ imask = info->gpi_mask << ishift;
-+ } else {
-+ reg_din = NULL;
-+ }
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ dout |= readl_relaxed(reg_dout) & ~dout_mask;
-+ writel_relaxed(dout, reg_dout);
-+ doen |= readl_relaxed(reg_doen) & ~done_mask;
-+ writel_relaxed(doen, reg_doen);
-+ if (reg_din) {
-+ ival |= readl_relaxed(reg_din) & ~imask;
-+ writel_relaxed(ival, reg_din);
-+ }
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_set_gpiomux);
-+
-+static int jh7110_set_mux(struct pinctrl_dev *pctldev,
-+ unsigned int fsel, unsigned int gsel)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ const struct group_desc *group;
-+ const u32 *pinmux;
-+ unsigned int i;
-+
-+ group = pinctrl_generic_get_group(pctldev, gsel);
-+ if (!group)
-+ return -EINVAL;
-+
-+ pinmux = group->data;
-+ for (i = 0; i < group->num_pins; i++) {
-+ u32 v = pinmux[i];
-+
-+ if (info->jh7110_set_one_pin_mux)
-+ info->jh7110_set_one_pin_mux(sfp,
-+ jh7110_pinmux_pin(v),
-+ jh7110_pinmux_din(v),
-+ jh7110_pinmux_dout(v),
-+ jh7110_pinmux_doen(v),
-+ jh7110_pinmux_function(v));
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct pinmux_ops jh7110_pinmux_ops = {
-+ .get_functions_count = pinmux_generic_get_function_count,
-+ .get_function_name = pinmux_generic_get_function_name,
-+ .get_function_groups = pinmux_generic_get_function_groups,
-+ .set_mux = jh7110_set_mux,
-+ .strict = true,
-+};
-+
-+static const u8 jh7110_drive_strength_mA[4] = { 2, 4, 8, 12 };
-+
-+static u32 jh7110_padcfg_ds_to_mA(u32 padcfg)
-+{
-+ return jh7110_drive_strength_mA[(padcfg >> 1) & 3U];
-+}
-+
-+static u32 jh7110_padcfg_ds_from_mA(u32 v)
-+{
-+ int i;
-+
-+ for (i = 0; i < 3; i++) {
-+ if (v <= jh7110_drive_strength_mA[i])
-+ break;
-+ }
-+ return i << 1;
-+}
-+
-+static void jh7110_padcfg_rmw(struct jh7110_pinctrl *sfp,
-+ unsigned int pin, u32 mask, u32 value)
-+{
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ void __iomem *reg;
-+ unsigned long flags;
-+ int padcfg_base;
-+
-+ if (!info->jh7110_get_padcfg_base)
-+ return;
-+
-+ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
-+ if (padcfg_base < 0)
-+ return;
-+
-+ reg = sfp->base + padcfg_base + 4 * pin;
-+ value &= mask;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(value, reg);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_pinconf_get(struct pinctrl_dev *pctldev,
-+ unsigned int pin, unsigned long *config)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ int param = pinconf_to_config_param(*config);
-+ u32 padcfg, arg;
-+ bool enabled;
-+ int padcfg_base;
-+
-+ if (!info->jh7110_get_padcfg_base)
-+ return 0;
-+
-+ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
-+ if (padcfg_base < 0)
-+ return 0;
-+
-+ padcfg = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
-+ switch (param) {
-+ case PIN_CONFIG_BIAS_DISABLE:
-+ enabled = !(padcfg & JH7110_PADCFG_BIAS);
-+ arg = 0;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_DOWN:
-+ enabled = padcfg & JH7110_PADCFG_PD;
-+ arg = 1;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_UP:
-+ enabled = padcfg & JH7110_PADCFG_PU;
-+ arg = 1;
-+ break;
-+ case PIN_CONFIG_DRIVE_STRENGTH:
-+ enabled = true;
-+ arg = jh7110_padcfg_ds_to_mA(padcfg);
-+ break;
-+ case PIN_CONFIG_INPUT_ENABLE:
-+ enabled = padcfg & JH7110_PADCFG_IE;
-+ arg = enabled;
-+ break;
-+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-+ enabled = padcfg & JH7110_PADCFG_SMT;
-+ arg = enabled;
-+ break;
-+ case PIN_CONFIG_SLEW_RATE:
-+ enabled = true;
-+ arg = !!(padcfg & JH7110_PADCFG_SLEW);
-+ break;
-+ default:
-+ return -ENOTSUPP;
-+ }
-+
-+ *config = pinconf_to_config_packed(param, arg);
-+ return enabled ? 0 : -EINVAL;
-+}
-+
-+static int jh7110_pinconf_group_get(struct pinctrl_dev *pctldev,
-+ unsigned int gsel,
-+ unsigned long *config)
-+{
-+ const struct group_desc *group;
-+
-+ group = pinctrl_generic_get_group(pctldev, gsel);
-+ if (!group)
-+ return -EINVAL;
-+
-+ return jh7110_pinconf_get(pctldev, group->pins[0], config);
-+}
-+
-+static int jh7110_pinconf_group_set(struct pinctrl_dev *pctldev,
-+ unsigned int gsel,
-+ unsigned long *configs,
-+ unsigned int num_configs)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct group_desc *group;
-+ u16 mask, value;
-+ int i;
-+
-+ group = pinctrl_generic_get_group(pctldev, gsel);
-+ if (!group)
-+ return -EINVAL;
-+
-+ mask = 0;
-+ value = 0;
-+ for (i = 0; i < num_configs; i++) {
-+ int param = pinconf_to_config_param(configs[i]);
-+ u32 arg = pinconf_to_config_argument(configs[i]);
-+
-+ switch (param) {
-+ case PIN_CONFIG_BIAS_DISABLE:
-+ mask |= JH7110_PADCFG_BIAS;
-+ value &= ~JH7110_PADCFG_BIAS;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_DOWN:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask |= JH7110_PADCFG_BIAS;
-+ value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PD;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_UP:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask |= JH7110_PADCFG_BIAS;
-+ value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PU;
-+ break;
-+ case PIN_CONFIG_DRIVE_STRENGTH:
-+ mask |= JH7110_PADCFG_DS_MASK;
-+ value = (value & ~JH7110_PADCFG_DS_MASK) |
-+ jh7110_padcfg_ds_from_mA(arg);
-+ break;
-+ case PIN_CONFIG_INPUT_ENABLE:
-+ mask |= JH7110_PADCFG_IE;
-+ if (arg)
-+ value |= JH7110_PADCFG_IE;
-+ else
-+ value &= ~JH7110_PADCFG_IE;
-+ break;
-+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-+ mask |= JH7110_PADCFG_SMT;
-+ if (arg)
-+ value |= JH7110_PADCFG_SMT;
-+ else
-+ value &= ~JH7110_PADCFG_SMT;
-+ break;
-+ case PIN_CONFIG_SLEW_RATE:
-+ mask |= JH7110_PADCFG_SLEW;
-+ if (arg)
-+ value |= JH7110_PADCFG_SLEW;
-+ else
-+ value &= ~JH7110_PADCFG_SLEW;
-+ break;
-+ default:
-+ return -ENOTSUPP;
-+ }
-+ }
-+
-+ for (i = 0; i < group->num_pins; i++)
-+ jh7110_padcfg_rmw(sfp, group->pins[i], mask, value);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7110_pinconf_dbg_show(struct pinctrl_dev *pctldev,
-+ struct seq_file *s, unsigned int pin)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ u32 value;
-+ int padcfg_base;
-+
-+ if (!info->jh7110_get_padcfg_base)
-+ return;
-+
-+ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
-+ if (padcfg_base < 0)
-+ return;
-+
-+ value = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
-+ seq_printf(s, " (0x%02x)", value);
-+}
-+#else
-+#define jh7110_pinconf_dbg_show NULL
-+#endif
-+
-+static const struct pinconf_ops jh7110_pinconf_ops = {
-+ .pin_config_get = jh7110_pinconf_get,
-+ .pin_config_group_get = jh7110_pinconf_group_get,
-+ .pin_config_group_set = jh7110_pinconf_group_set,
-+ .pin_config_dbg_show = jh7110_pinconf_dbg_show,
-+ .is_generic = true,
-+};
-+
-+static int jh7110_gpio_request(struct gpio_chip *gc, unsigned int gpio)
-+{
-+ return pinctrl_gpio_request(gc->base + gpio);
-+}
-+
-+static void jh7110_gpio_free(struct gpio_chip *gc, unsigned int gpio)
-+{
-+ pinctrl_gpio_free(gc->base + gpio);
-+}
-+
-+static int jh7110_gpio_get_direction(struct gpio_chip *gc,
-+ unsigned int gpio)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ unsigned int offset = 4 * (gpio / 4);
-+ unsigned int shift = 8 * (gpio % 4);
-+ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
-+
-+ doen = (doen >> shift) & info->doen_mask;
-+
-+ return doen == GPOEN_ENABLE ?
-+ GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
-+}
-+
-+static int jh7110_gpio_direction_input(struct gpio_chip *gc,
-+ unsigned int gpio)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ /* enable input and schmitt trigger */
-+ jh7110_padcfg_rmw(sfp, gpio,
-+ JH7110_PADCFG_IE | JH7110_PADCFG_SMT,
-+ JH7110_PADCFG_IE | JH7110_PADCFG_SMT);
-+
-+ if (info->jh7110_set_one_pin_mux)
-+ info->jh7110_set_one_pin_mux(sfp, gpio,
-+ GPI_NONE, GPOUT_LOW, GPOEN_DISABLE, 0);
-+
-+ return 0;
-+}
-+
-+static int jh7110_gpio_direction_output(struct gpio_chip *gc,
-+ unsigned int gpio, int value)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ if (info->jh7110_set_one_pin_mux)
-+ info->jh7110_set_one_pin_mux(sfp, gpio,
-+ GPI_NONE, value ? GPOUT_HIGH : GPOUT_LOW,
-+ GPOEN_ENABLE, 0);
-+
-+ /* disable input, schmitt trigger and bias */
-+ jh7110_padcfg_rmw(sfp, gpio,
-+ JH7110_PADCFG_IE | JH7110_PADCFG_SMT |
-+ JH7110_PADCFG_BIAS, 0);
-+ return 0;
-+}
-+
-+static int jh7110_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ void __iomem *reg = sfp->base + info->gpioin_reg_base
-+ + 4 * (gpio / 32);
-+
-+ return !!(readl_relaxed(reg) & BIT(gpio % 32));
-+}
-+
-+static void jh7110_gpio_set(struct gpio_chip *gc,
-+ unsigned int gpio, int value)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ unsigned int offset = 4 * (gpio / 4);
-+ unsigned int shift = 8 * (gpio % 4);
-+ void __iomem *reg_dout = sfp->base + info->dout_reg_base + offset;
-+ u32 dout = (value ? GPOUT_HIGH : GPOUT_LOW) << shift;
-+ u32 mask = info->dout_mask << shift;
-+ unsigned long flags;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ dout |= readl_relaxed(reg_dout) & ~mask;
-+ writel_relaxed(dout, reg_dout);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_gpio_set_config(struct gpio_chip *gc,
-+ unsigned int gpio, unsigned long config)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ u32 arg = pinconf_to_config_argument(config);
-+ u32 value;
-+ u32 mask;
-+
-+ switch (pinconf_to_config_param(config)) {
-+ case PIN_CONFIG_BIAS_DISABLE:
-+ mask = JH7110_PADCFG_BIAS;
-+ value = 0;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_DOWN:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask = JH7110_PADCFG_BIAS;
-+ value = JH7110_PADCFG_PD;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_UP:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask = JH7110_PADCFG_BIAS;
-+ value = JH7110_PADCFG_PU;
-+ break;
-+ case PIN_CONFIG_DRIVE_PUSH_PULL:
-+ return 0;
-+ case PIN_CONFIG_INPUT_ENABLE:
-+ mask = JH7110_PADCFG_IE;
-+ value = arg ? JH7110_PADCFG_IE : 0;
-+ break;
-+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-+ mask = JH7110_PADCFG_SMT;
-+ value = arg ? JH7110_PADCFG_SMT : 0;
-+ break;
-+ default:
-+ return -ENOTSUPP;
-+ }
-+
-+ jh7110_padcfg_rmw(sfp, gpio, mask, value);
-+ return 0;
-+}
-+
-+static int jh7110_gpio_add_pin_ranges(struct gpio_chip *gc)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+
-+ sfp->gpios.name = sfp->gc.label;
-+ sfp->gpios.base = sfp->gc.base;
-+ sfp->gpios.pin_base = 0;
-+ sfp->gpios.npins = sfp->gc.ngpio;
-+ sfp->gpios.gc = &sfp->gc;
-+ pinctrl_add_gpio_range(sfp->pctl, &sfp->gpios);
-+ return 0;
-+}
-+
-+static void jh7110_irq_ack(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ic) & ~mask;
-+ writel_relaxed(value, ic);
-+ writel_relaxed(value | mask, ic);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static void jh7110_irq_mask(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ie) & ~mask;
-+ writel_relaxed(value, ie);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+
-+ gpiochip_disable_irq(&sfp->gc, d->hwirq);
-+}
-+
-+static void jh7110_irq_mask_ack(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
-+ + 4 * (gpio / 32);
-+ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ie) & ~mask;
-+ writel_relaxed(value, ie);
-+
-+ value = readl_relaxed(ic) & ~mask;
-+ writel_relaxed(value, ic);
-+ writel_relaxed(value | mask, ic);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static void jh7110_irq_unmask(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ gpiochip_enable_irq(&sfp->gc, d->hwirq);
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ie) | mask;
-+ writel_relaxed(value, ie);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_irq_set_type(struct irq_data *d, unsigned int trigger)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *base = sfp->base + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ u32 irq_type, edge_both, polarity;
-+ unsigned long flags;
-+
-+ switch (trigger) {
-+ case IRQ_TYPE_EDGE_RISING:
-+ irq_type = mask; /* 1: edge triggered */
-+ edge_both = 0; /* 0: single edge */
-+ polarity = mask; /* 1: rising edge */
-+ break;
-+ case IRQ_TYPE_EDGE_FALLING:
-+ irq_type = mask; /* 1: edge triggered */
-+ edge_both = 0; /* 0: single edge */
-+ polarity = 0; /* 0: falling edge */
-+ break;
-+ case IRQ_TYPE_EDGE_BOTH:
-+ irq_type = mask; /* 1: edge triggered */
-+ edge_both = mask; /* 1: both edges */
-+ polarity = 0; /* 0: ignored */
-+ break;
-+ case IRQ_TYPE_LEVEL_HIGH:
-+ irq_type = 0; /* 0: level triggered */
-+ edge_both = 0; /* 0: ignored */
-+ polarity = mask; /* 1: high level */
-+ break;
-+ case IRQ_TYPE_LEVEL_LOW:
-+ irq_type = 0; /* 0: level triggered */
-+ edge_both = 0; /* 0: ignored */
-+ polarity = 0; /* 0: low level */
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (trigger & IRQ_TYPE_EDGE_BOTH)
-+ irq_set_handler_locked(d, handle_edge_irq);
-+ else
-+ irq_set_handler_locked(d, handle_level_irq);
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ irq_type |= readl_relaxed(base + irq_reg->is_reg_base) & ~mask;
-+ writel_relaxed(irq_type, base + irq_reg->is_reg_base);
-+
-+ edge_both |= readl_relaxed(base + irq_reg->ibe_reg_base) & ~mask;
-+ writel_relaxed(edge_both, base + irq_reg->ibe_reg_base);
-+
-+ polarity |= readl_relaxed(base + irq_reg->iev_reg_base) & ~mask;
-+ writel_relaxed(polarity, base + irq_reg->iev_reg_base);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+ return 0;
-+}
-+
-+static struct irq_chip jh7110_irq_chip = {
-+ .irq_ack = jh7110_irq_ack,
-+ .irq_mask = jh7110_irq_mask,
-+ .irq_mask_ack = jh7110_irq_mask_ack,
-+ .irq_unmask = jh7110_irq_unmask,
-+ .irq_set_type = jh7110_irq_set_type,
-+ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED,
-+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
-+};
-+
-+static void jh7110_disable_clock(void *data)
-+{
-+ clk_disable_unprepare(data);
-+}
-+
-+int jh7110_pinctrl_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ const struct jh7110_pinctrl_soc_info *info;
-+ struct jh7110_pinctrl *sfp;
-+ struct pinctrl_desc *jh7110_pinctrl_desc;
-+ struct reset_control *rst;
-+ struct clk *clk;
-+ int ret;
-+
-+ info = of_device_get_match_data(&pdev->dev);
-+ if (!info)
-+ return -ENODEV;
-+
-+ if (!info->pins || !info->npins) {
-+ dev_err(dev, "wrong pinctrl info\n");
-+ return -EINVAL;
-+ }
-+
-+ sfp = devm_kzalloc(dev, sizeof(*sfp), GFP_KERNEL);
-+ if (!sfp)
-+ return -ENOMEM;
-+
-+ sfp->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(sfp->base))
-+ return PTR_ERR(sfp->base);
-+
-+ clk = devm_clk_get_optional(dev, NULL);
-+ if (IS_ERR(clk))
-+ return dev_err_probe(dev, PTR_ERR(clk), "could not get clock\n");
-+
-+ rst = devm_reset_control_get_exclusive(dev, NULL);
-+ if (IS_ERR(rst))
-+ return dev_err_probe(dev, PTR_ERR(rst), "could not get reset\n");
-+
-+ /*
-+ * we don't want to assert reset and risk undoing pin muxing for the
-+ * early boot serial console, but let's make sure the reset line is
-+ * deasserted in case someone runs a really minimal bootloader.
-+ */
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "could not deassert reset\n");
-+
-+ if (clk) {
-+ ret = clk_prepare_enable(clk);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "could not enable clock\n");
-+
-+ ret = devm_add_action_or_reset(dev, jh7110_disable_clock, clk);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ jh7110_pinctrl_desc = devm_kzalloc(&pdev->dev,
-+ sizeof(*jh7110_pinctrl_desc),
-+ GFP_KERNEL);
-+ if (!jh7110_pinctrl_desc)
-+ return -ENOMEM;
-+
-+ jh7110_pinctrl_desc->name = dev_name(dev);
-+ jh7110_pinctrl_desc->pins = info->pins;
-+ jh7110_pinctrl_desc->npins = info->npins;
-+ jh7110_pinctrl_desc->pctlops = &jh7110_pinctrl_ops;
-+ jh7110_pinctrl_desc->pmxops = &jh7110_pinmux_ops;
-+ jh7110_pinctrl_desc->confops = &jh7110_pinconf_ops;
-+ jh7110_pinctrl_desc->owner = THIS_MODULE;
-+
-+ sfp->info = info;
-+ sfp->dev = dev;
-+ platform_set_drvdata(pdev, sfp);
-+ sfp->gc.parent = dev;
-+ raw_spin_lock_init(&sfp->lock);
-+ mutex_init(&sfp->mutex);
-+
-+ ret = devm_pinctrl_register_and_init(dev,
-+ jh7110_pinctrl_desc,
-+ sfp, &sfp->pctl);
-+ if (ret)
-+ return dev_err_probe(dev, ret,
-+ "could not register pinctrl driver\n");
-+
-+ sfp->gc.label = dev_name(dev);
-+ sfp->gc.owner = THIS_MODULE;
-+ sfp->gc.request = jh7110_gpio_request;
-+ sfp->gc.free = jh7110_gpio_free;
-+ sfp->gc.get_direction = jh7110_gpio_get_direction;
-+ sfp->gc.direction_input = jh7110_gpio_direction_input;
-+ sfp->gc.direction_output = jh7110_gpio_direction_output;
-+ sfp->gc.get = jh7110_gpio_get;
-+ sfp->gc.set = jh7110_gpio_set;
-+ sfp->gc.set_config = jh7110_gpio_set_config;
-+ sfp->gc.add_pin_ranges = jh7110_gpio_add_pin_ranges;
-+ sfp->gc.base = info->gc_base;
-+ sfp->gc.ngpio = info->ngpios;
-+
-+ jh7110_irq_chip.name = sfp->gc.label;
-+ gpio_irq_chip_set_chip(&sfp->gc.irq, &jh7110_irq_chip);
-+ sfp->gc.irq.parent_handler = info->jh7110_gpio_irq_handler;
-+ sfp->gc.irq.num_parents = 1;
-+ sfp->gc.irq.parents = devm_kcalloc(dev, sfp->gc.irq.num_parents,
-+ sizeof(*sfp->gc.irq.parents),
-+ GFP_KERNEL);
-+ if (!sfp->gc.irq.parents)
-+ return -ENOMEM;
-+ sfp->gc.irq.default_type = IRQ_TYPE_NONE;
-+ sfp->gc.irq.handler = handle_bad_irq;
-+ sfp->gc.irq.init_hw = info->jh7110_gpio_init_hw;
-+
-+ ret = platform_get_irq(pdev, 0);
-+ if (ret < 0)
-+ return ret;
-+ sfp->gc.irq.parents[0] = ret;
-+
-+ ret = devm_gpiochip_add_data(dev, &sfp->gc, sfp);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "could not register gpiochip\n");
-+
-+ irq_domain_set_pm_device(sfp->gc.irq.domain, dev);
-+
-+ dev_info(dev, "StarFive GPIO chip registered %d GPIOs\n", sfp->gc.ngpio);
-+
-+ return pinctrl_enable(sfp->pctl);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_pinctrl_probe);
-+
-+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
-@@ -0,0 +1,70 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __PINCTRL_STARFIVE_JH7110_H__
-+#define __PINCTRL_STARFIVE_JH7110_H__
-+
-+#include <linux/pinctrl/pinconf-generic.h>
-+#include <linux/pinctrl/pinmux.h>
-+
-+struct jh7110_pinctrl {
-+ struct device *dev;
-+ struct gpio_chip gc;
-+ struct pinctrl_gpio_range gpios;
-+ raw_spinlock_t lock;
-+ void __iomem *base;
-+ struct pinctrl_dev *pctl;
-+ /* register read/write mutex */
-+ struct mutex mutex;
-+ const struct jh7110_pinctrl_soc_info *info;
-+};
-+
-+struct jh7110_gpio_irq_reg {
-+ unsigned int is_reg_base;
-+ unsigned int ic_reg_base;
-+ unsigned int ibe_reg_base;
-+ unsigned int iev_reg_base;
-+ unsigned int ie_reg_base;
-+ unsigned int ris_reg_base;
-+ unsigned int mis_reg_base;
-+};
-+
-+struct jh7110_pinctrl_soc_info {
-+ const struct pinctrl_pin_desc *pins;
-+ unsigned int npins;
-+ unsigned int ngpios;
-+ unsigned int gc_base;
-+
-+ /* gpio dout/doen/din/gpioinput register */
-+ unsigned int dout_reg_base;
-+ unsigned int dout_mask;
-+ unsigned int doen_reg_base;
-+ unsigned int doen_mask;
-+ unsigned int gpi_reg_base;
-+ unsigned int gpi_mask;
-+ unsigned int gpioin_reg_base;
-+
-+ const struct jh7110_gpio_irq_reg *irq_reg;
-+
-+ /* generic pinmux */
-+ int (*jh7110_set_one_pin_mux)(struct jh7110_pinctrl *sfp,
-+ unsigned int pin,
-+ unsigned int din, u32 dout,
-+ u32 doen, u32 func);
-+ /* gpio chip */
-+ int (*jh7110_get_padcfg_base)(struct jh7110_pinctrl *sfp,
-+ unsigned int pin);
-+ void (*jh7110_gpio_irq_handler)(struct irq_desc *desc);
-+ int (*jh7110_gpio_init_hw)(struct gpio_chip *gc);
-+};
-+
-+void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
-+ unsigned int din, u32 dout, u32 doen);
-+int jh7110_pinctrl_probe(struct platform_device *pdev);
-+struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc);
-+
-+#endif /* __PINCTRL_STARFIVE_JH7110_H__ */
diff --git a/target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch b/target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch
deleted file mode 100644
index 54e2c7c53b..0000000000
--- a/target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch
+++ /dev/null
@@ -1,224 +0,0 @@
-From 9c1a9d6dfd6a9c28794536c8af002746a20d840f Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:37:02 +0800
-Subject: [PATCH 029/122] pinctrl: starfive: Add StarFive JH7110 aon controller
- driver
-
-Add pinctrl driver for StarFive JH7110 SoC aon pinctrl controller.
-
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- drivers/pinctrl/starfive/Kconfig | 12 ++
- drivers/pinctrl/starfive/Makefile | 1 +
- .../starfive/pinctrl-starfive-jh7110-aon.c | 177 ++++++++++++++++++
- 3 files changed, 190 insertions(+)
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
-
---- a/drivers/pinctrl/starfive/Kconfig
-+++ b/drivers/pinctrl/starfive/Kconfig
-@@ -37,3 +37,15 @@ config PINCTRL_STARFIVE_JH7110_SYS
- This also provides an interface to the GPIO pins not used by other
- peripherals supporting inputs, outputs, configuring pull-up/pull-down
- and interrupts on input changes.
-+
-+config PINCTRL_STARFIVE_JH7110_AON
-+ tristate "Always-on pinctrl and GPIO driver for the StarFive JH7110 SoC"
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ depends on OF
-+ select PINCTRL_STARFIVE_JH7110
-+ default SOC_STARFIVE
-+ help
-+ Say yes here to support always-on pin control on the StarFive JH7110 SoC.
-+ This also provides an interface to the GPIO pins not used by other
-+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
-+ and interrupts on input changes.
---- a/drivers/pinctrl/starfive/Makefile
-+++ b/drivers/pinctrl/starfive/Makefile
-@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) +=
-
- obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
- obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
-+obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
-@@ -0,0 +1,177 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC aon controller
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/gpio/driver.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_platform.h>
-+#include <linux/pinctrl/pinconf.h>
-+#include <linux/pinctrl/pinconf-generic.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/pinctrl/pinmux.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+#include <linux/slab.h>
-+
-+#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
-+
-+#include "../core.h"
-+#include "../pinconf.h"
-+#include "../pinmux.h"
-+#include "pinctrl-starfive-jh7110.h"
-+
-+#define JH7110_AON_NGPIO 4
-+#define JH7110_AON_GC_BASE 64
-+
-+/* registers */
-+#define JH7110_AON_DOEN 0x0
-+#define JH7110_AON_DOUT 0x4
-+#define JH7110_AON_GPI 0x8
-+#define JH7110_AON_GPIOIN 0x2c
-+
-+#define JH7110_AON_GPIOEN 0xc
-+#define JH7110_AON_GPIOIS 0x10
-+#define JH7110_AON_GPIOIC 0x14
-+#define JH7110_AON_GPIOIBE 0x18
-+#define JH7110_AON_GPIOIEV 0x1c
-+#define JH7110_AON_GPIOIE 0x20
-+#define JH7110_AON_GPIORIS 0x28
-+#define JH7110_AON_GPIOMIS 0x28
-+
-+#define JH7110_AON_GPO_PDA_0_5_CFG 0x30
-+
-+static const struct pinctrl_pin_desc jh7110_aon_pins[] = {
-+ PINCTRL_PIN(PAD_TESTEN, "TESTEN"),
-+ PINCTRL_PIN(PAD_RGPIO0, "RGPIO0"),
-+ PINCTRL_PIN(PAD_RGPIO1, "RGPIO1"),
-+ PINCTRL_PIN(PAD_RGPIO2, "RGPIO2"),
-+ PINCTRL_PIN(PAD_RGPIO3, "RGPIO3"),
-+ PINCTRL_PIN(PAD_RSTN, "RSTN"),
-+ PINCTRL_PIN(PAD_GMAC0_MDC, "GMAC0_MDC"),
-+ PINCTRL_PIN(PAD_GMAC0_MDIO, "GMAC0_MDIO"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD0, "GMAC0_RXD0"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD1, "GMAC0_RXD1"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD2, "GMAC0_RXD2"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD3, "GMAC0_RXD3"),
-+ PINCTRL_PIN(PAD_GMAC0_RXDV, "GMAC0_RXDV"),
-+ PINCTRL_PIN(PAD_GMAC0_RXC, "GMAC0_RXC"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD0, "GMAC0_TXD0"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD1, "GMAC0_TXD1"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD2, "GMAC0_TXD2"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD3, "GMAC0_TXD3"),
-+ PINCTRL_PIN(PAD_GMAC0_TXEN, "GMAC0_TXEN"),
-+ PINCTRL_PIN(PAD_GMAC0_TXC, "GMAC0_TXC"),
-+};
-+
-+static int jh7110_aon_set_one_pin_mux(struct jh7110_pinctrl *sfp,
-+ unsigned int pin,
-+ unsigned int din, u32 dout,
-+ u32 doen, u32 func)
-+{
-+ if (pin < sfp->gc.ngpio && func == 0)
-+ jh7110_set_gpiomux(sfp, pin, din, dout, doen);
-+
-+ return 0;
-+}
-+
-+static int jh7110_aon_get_padcfg_base(struct jh7110_pinctrl *sfp,
-+ unsigned int pin)
-+{
-+ if (pin < PAD_GMAC0_MDC)
-+ return JH7110_AON_GPO_PDA_0_5_CFG;
-+
-+ return -1;
-+}
-+
-+static void jh7110_aon_irq_handler(struct irq_desc *desc)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ unsigned long mis;
-+ unsigned int pin;
-+
-+ chained_irq_enter(chip, desc);
-+
-+ mis = readl_relaxed(sfp->base + JH7110_AON_GPIOMIS);
-+ for_each_set_bit(pin, &mis, JH7110_AON_NGPIO)
-+ generic_handle_domain_irq(sfp->gc.irq.domain, pin);
-+
-+ chained_irq_exit(chip, desc);
-+}
-+
-+static int jh7110_aon_init_hw(struct gpio_chip *gc)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+
-+ /* mask all GPIO interrupts */
-+ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIE);
-+ /* clear edge interrupt flags */
-+ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIC);
-+ writel_relaxed(0x0f, sfp->base + JH7110_AON_GPIOIC);
-+ /* enable GPIO interrupts */
-+ writel_relaxed(1, sfp->base + JH7110_AON_GPIOEN);
-+ return 0;
-+}
-+
-+static const struct jh7110_gpio_irq_reg jh7110_aon_irq_reg = {
-+ .is_reg_base = JH7110_AON_GPIOIS,
-+ .ic_reg_base = JH7110_AON_GPIOIC,
-+ .ibe_reg_base = JH7110_AON_GPIOIBE,
-+ .iev_reg_base = JH7110_AON_GPIOIEV,
-+ .ie_reg_base = JH7110_AON_GPIOIE,
-+ .ris_reg_base = JH7110_AON_GPIORIS,
-+ .mis_reg_base = JH7110_AON_GPIOMIS,
-+};
-+
-+static const struct jh7110_pinctrl_soc_info jh7110_aon_pinctrl_info = {
-+ .pins = jh7110_aon_pins,
-+ .npins = ARRAY_SIZE(jh7110_aon_pins),
-+ .ngpios = JH7110_AON_NGPIO,
-+ .gc_base = JH7110_AON_GC_BASE,
-+ .dout_reg_base = JH7110_AON_DOUT,
-+ .dout_mask = GENMASK(3, 0),
-+ .doen_reg_base = JH7110_AON_DOEN,
-+ .doen_mask = GENMASK(2, 0),
-+ .gpi_reg_base = JH7110_AON_GPI,
-+ .gpi_mask = GENMASK(3, 0),
-+ .gpioin_reg_base = JH7110_AON_GPIOIN,
-+ .irq_reg = &jh7110_aon_irq_reg,
-+ .jh7110_set_one_pin_mux = jh7110_aon_set_one_pin_mux,
-+ .jh7110_get_padcfg_base = jh7110_aon_get_padcfg_base,
-+ .jh7110_gpio_irq_handler = jh7110_aon_irq_handler,
-+ .jh7110_gpio_init_hw = jh7110_aon_init_hw,
-+};
-+
-+static const struct of_device_id jh7110_aon_pinctrl_of_match[] = {
-+ {
-+ .compatible = "starfive,jh7110-aon-pinctrl",
-+ .data = &jh7110_aon_pinctrl_info,
-+ },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_aon_pinctrl_of_match);
-+
-+static struct platform_driver jh7110_aon_pinctrl_driver = {
-+ .probe = jh7110_pinctrl_probe,
-+ .driver = {
-+ .name = "starfive-jh7110-aon-pinctrl",
-+ .of_match_table = jh7110_aon_pinctrl_of_match,
-+ },
-+};
-+module_platform_driver(jh7110_aon_pinctrl_driver);
-+
-+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC aon controller");
-+MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch b/target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch
deleted file mode 100644
index 6c6afb853d..0000000000
--- a/target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch
+++ /dev/null
@@ -1,228 +0,0 @@
-From 537ee9e5bb7b4ebee4ad5a607098c8200af6c261 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:28 -0700
-Subject: [PATCH 030/122] config: add jh7110 defconfig for test mini
-
-add jh7110 defconfig for test mini
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- arch/riscv/configs/jh7110_defconfig | 212 ++++++++++++++++++++++++++++
- 1 file changed, 212 insertions(+)
- create mode 100755 arch/riscv/configs/jh7110_defconfig
-
---- /dev/null
-+++ b/arch/riscv/configs/jh7110_defconfig
-@@ -0,0 +1,212 @@
-+CONFIG_WERROR=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_CROSS_MEMORY_ATTACH is not set
-+CONFIG_NO_HZ_IDLE=y
-+CONFIG_HIGH_RES_TIMERS=y
-+CONFIG_PSI=y
-+# CONFIG_CPU_ISOLATION is not set
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
-+CONFIG_CGROUPS=y
-+CONFIG_CGROUP_SCHED=y
-+CONFIG_CGROUP_PIDS=y
-+CONFIG_CGROUP_CPUACCT=y
-+CONFIG_NAMESPACES=y
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_RD_GZIP=y
-+# CONFIG_RD_BZIP2 is not set
-+# CONFIG_RD_LZMA is not set
-+# CONFIG_RD_XZ is not set
-+# CONFIG_RD_LZO is not set
-+# CONFIG_RD_LZ4 is not set
-+CONFIG_EXPERT=y
-+# CONFIG_SYSFS_SYSCALL is not set
-+CONFIG_KCMP=y
-+CONFIG_PERF_EVENTS=y
-+CONFIG_ARCH_STARFIVE=y
-+CONFIG_SOC_STARFIVE=y
-+CONFIG_ERRATA_SIFIVE=y
-+CONFIG_SMP=y
-+# CONFIG_RISCV_ISA_SVPBMT is not set
-+# CONFIG_COMPAT is not set
-+CONFIG_CPU_IDLE=y
-+CONFIG_RISCV_SBI_CPUIDLE=y
-+CONFIG_JUMP_LABEL=y
-+# CONFIG_STACKPROTECTOR is not set
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+CONFIG_MODULE_COMPRESS_ZSTD=y
-+# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
-+CONFIG_BLK_WBT=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=y
-+CONFIG_KSM=y
-+# CONFIG_VM_EVENT_COUNTERS is not set
-+CONFIG_NET=y
-+CONFIG_PACKET=y
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+CONFIG_IP_ADVANCED_ROUTER=y
-+CONFIG_IP_MULTIPLE_TABLES=y
-+CONFIG_INET_DIAG=m
-+# CONFIG_IPV6_SIT is not set
-+CONFIG_IPV6_MULTIPLE_TABLES=y
-+# CONFIG_WIRELESS is not set
-+# CONFIG_ETHTOOL_NETLINK is not set
-+CONFIG_DEVTMPFS=y
-+CONFIG_DEVTMPFS_MOUNT=y
-+# CONFIG_STANDALONE is not set
-+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-+# CONFIG_FW_LOADER is not set
-+CONFIG_EFI_DISABLE_RUNTIME=y
-+CONFIG_ZRAM=y
-+CONFIG_ZRAM_MEMORY_TRACKING=y
-+CONFIG_BLK_DEV_LOOP=y
-+CONFIG_BLK_DEV_LOOP_MIN_COUNT=1
-+CONFIG_NETDEVICES=y
-+CONFIG_STMMAC_ETH=y
-+CONFIG_DWMAC_DWC_QOS_ETH=y
-+# CONFIG_DWMAC_GENERIC is not set
-+CONFIG_DWMAC_STARFIVE=y
-+CONFIG_MICROCHIP_PHY=y
-+CONFIG_MOTORCOMM_PHY=y
-+# CONFIG_WLAN is not set
-+# CONFIG_INPUT_KEYBOARD is not set
-+# CONFIG_INPUT_MOUSE is not set
-+# CONFIG_SERIO is not set
-+# CONFIG_VT is not set
-+# CONFIG_LEGACY_PTYS is not set
-+# CONFIG_LDISC_AUTOLOAD is not set
-+CONFIG_SERIAL_8250=y
-+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
-+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_DW=y
-+CONFIG_SERIAL_OF_PLATFORM=y
-+# CONFIG_DEVMEM is not set
-+# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
-+CONFIG_I2C=y
-+# CONFIG_I2C_COMPAT is not set
-+CONFIG_I2C_CHARDEV=y
-+# CONFIG_I2C_HELPER_AUTO is not set
-+CONFIG_I2C_DESIGNWARE_PLATFORM=y
-+# CONFIG_PTP_1588_CLOCK is not set
-+CONFIG_PINCTRL_STARFIVE_JH7110=y
-+CONFIG_GPIOLIB_FASTPATH_LIMIT=128
-+CONFIG_GPIO_SYSFS=y
-+CONFIG_POWER_RESET=y
-+CONFIG_POWER_RESET_GPIO_RESTART=y
-+CONFIG_SENSORS_SFCTEMP=y
-+# CONFIG_HID is not set
-+CONFIG_MMC=y
-+# CONFIG_PWRSEQ_EMMC is not set
-+# CONFIG_PWRSEQ_SIMPLE is not set
-+CONFIG_MMC_DW=y
-+# CONFIG_VIRTIO_MENU is not set
-+CONFIG_CLK_STARFIVE_JH7110_AON=y
-+# CONFIG_VHOST_MENU is not set
-+# CONFIG_IOMMU_SUPPORT is not set
-+CONFIG_BTRFS_FS=y
-+CONFIG_BTRFS_FS_POSIX_ACL=y
-+# CONFIG_DNOTIFY is not set
-+CONFIG_FANOTIFY=y
-+CONFIG_AUTOFS_FS=y
-+CONFIG_VFAT_FS=y
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
-+CONFIG_FAT_DEFAULT_UTF8=y
-+CONFIG_PROC_KCORE=y
-+CONFIG_PROC_CHILDREN=y
-+CONFIG_TMPFS=y
-+CONFIG_TMPFS_POSIX_ACL=y
-+CONFIG_EFIVAR_FS=y
-+# CONFIG_MISC_FILESYSTEMS is not set
-+# CONFIG_NETWORK_FILESYSTEMS is not set
-+CONFIG_NLS_DEFAULT="iso8859-15"
-+CONFIG_NLS_CODEPAGE_437=y
-+CONFIG_NLS_ISO8859_15=y
-+CONFIG_LSM=""
-+CONFIG_CRYPTO_ZSTD=y
-+# CONFIG_RAID6_PQ_BENCHMARK is not set
-+# CONFIG_DEBUG_MISC is not set
-+CONFIG_STRIP_ASM_SYMS=y
-+CONFIG_DEBUG_SECTION_MISMATCH=y
-+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
-+CONFIG_DEBUG_FS=y
-+# CONFIG_SLUB_DEBUG is not set
-+CONFIG_PAGE_TABLE_CHECK=y
-+CONFIG_DEBUG_RODATA_TEST=y
-+CONFIG_DEBUG_WX=y
-+CONFIG_SOFTLOCKUP_DETECTOR=y
-+CONFIG_WQ_WATCHDOG=y
-+# CONFIG_SCHED_DEBUG is not set
-+CONFIG_STACKTRACE=y
-+CONFIG_RCU_CPU_STALL_TIMEOUT=60
-+# CONFIG_RCU_TRACE is not set
-+# CONFIG_FTRACE is not set
-+# CONFIG_RUNTIME_TESTING_MENU is not set
-+CONFIG_EXT4_FS=y
-+CONFIG_CPUFREQ_DT_PLATDEV=y
-+CONFIG_CPUFREQ_DT=y
-+CONFIG_CPU_FREQ=y
-+CONFIG_HIBERNATION=y
-+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-+CONFIG_SWAP=y
-+CONFIG_PCIE_STARFIVE=y
-+CONFIG_PCI_MSI=y
-+CONFIG_PCI=y
-+CONFIG_USB_CDNS3_STARFIVE=y
-+CONFIG_PHY_STARFIVE_JH7110_PCIE=y
-+CONFIG_PHY_STARFIVE_JH7110_USB=y
-+CONFIG_USB_CDNS_SUPPORT=y
-+CONFIG_USB_CDNS3=y
-+CONFIG_USB=y
-+CONFIG_USB_SUPPORT=y
-+CONFIG_VIDEO_STARFIVE_CAMSS=y
-+CONFIG_VIDEO_CADENCE_CSI2RX=y
-+CONFIG_VIDEO_DEV=y
-+CONFIG_V4L_PLATFORM_DRIVERS=y
-+CONFIG_MEDIA_PLATFORM_DRIVERS=y
-+CONFIG_MEDIA_PLATFORM_SUPPORT=y
-+CONFIG_MEDIA_SUPPORT=y
-+CONFIG_PHY_STARFIVE_DPHY_RX=y
-+CONFIG_CRYPTO_DEV_JH7110=y
-+CONFIG_CRYPTO_HW=y
-+CONFIG_CRYPTO=y
-+CONFIG_SND_SOC_JH7110_TDM=y
-+CONFIG_SND_SOC_STARFIVE=y
-+CONFIG_SND_SOC=y
-+CONFIG_SND=y
-+CONFIG_SOUND=y
-+CONFIG_DW_AXI_DMAC=y
-+CONFIG_DMADEVICES=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_PWM_STARFIVE_PTC=y
-+CONFIG_PWM=y
-+CONFIG_STARFIVE_TIMER=y
-+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
-+CONFIG_GENERIC_CLOCKEVENTS=y
-+CONFIG_STARFIVE_WATCHDOG=y
-+CONFIG_WATCHDOG=y
-+CONFIG_HW_RANDOM_JH7110=y
-+CONFIG_HW_RANDOM=y
-+CONFIG_STMMAC_PLATFORM=y
-+CONFIG_SPI_CADENCE_QUADSPI=y
-+CONFIG_SPI_MASTER=y
-+CONFIG_SPI=y
-+CONFIG_MMC_DW_STARFIVE=y
-+CONFIG_CLK_STARFIVE_JH7110_PLL=y
-+CONFIG_CLK_STARFIVE_JH7110_VOUT=y
-+CONFIG_CLK_STARFIVE_JH7110_ISP=y
-+CONFIG_CLK_STARFIVE_JH7110_STG=y
-+CONFIG_JH71XX_PMU=y
-+CONFIG_PM=y
-+CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
-+CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
-+CONFIG_CLK_STARFIVE_JH7110_AON=y
-+CONFIG_CLK_STARFIVE_JH7110_SYS=y
-+CONFIG_SIFIVE_CCACHE=y
-+CONFIG_CLINT_TIMER=y
-+CONFIG_SIFIVE_PLIC=y
diff --git a/target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch b/target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch
deleted file mode 100644
index 74eb4b2f18..0000000000
--- a/target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 07f62b08668c0295b1c6342f9708b7e36093ff59 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 21 Feb 2023 17:13:48 +0800
-Subject: [PATCH 031/122] dt-bindings: clock: Add StarFive JH7110 PLL clock
- generator
-
-Add bindings for the PLL clock generator on the JH7110 RISC-V SoC.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../bindings/clock/starfive,jh7110-pll.yaml | 46 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 6 +++
- 2 files changed, 52 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
-@@ -0,0 +1,46 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-pll.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 PLL Clock Generator
-+
-+description:
-+ This PLL are high speed, low jitter frequency synthesizers in JH7110.
-+ Each PLL clocks work in integer mode or fraction mode by some dividers,
-+ and the configuration registers and dividers are set in several syscon
-+ registers. So pll node should be a child of SYS-SYSCON node.
-+ The formula for calculating frequency is that,
-+ Fvco = Fref * (NI + NF) / M / Q1
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pll
-+
-+ clocks:
-+ maxItems: 1
-+ description: Main Oscillator (24 MHz)
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - clocks
-+ - '#clock-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pll-clock-controller {
-+ compatible = "starfive,jh7110-pll";
-+ clocks = <&osc>;
-+ #clock-cells = <1>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -6,6 +6,12 @@
- #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
- #define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-
-+/* PLL clocks */
-+#define JH7110_CLK_PLL0_OUT 0
-+#define JH7110_CLK_PLL1_OUT 1
-+#define JH7110_CLK_PLL2_OUT 2
-+#define JH7110_PLLCLK_END 3
-+
- /* SYSCRG clocks */
- #define JH7110_SYSCLK_CPU_ROOT 0
- #define JH7110_SYSCLK_CPU_CORE 1
diff --git a/target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch b/target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch
deleted file mode 100644
index 69dc662f10..0000000000
--- a/target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch
+++ /dev/null
@@ -1,786 +0,0 @@
-From 0bc7aa28dcdee75a52b1874a02dfbf0107c2d448 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Fri, 17 Feb 2023 17:30:09 +0800
-Subject: [PATCH 032/122] clk: starfive: Add StarFive JH7110 PLL clock driver
-
-Add driver for the StarFive JH7110 PLL clock controller
-and they work by reading and setting syscon registers.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- MAINTAINERS | 6 +
- drivers/clk/starfive/Kconfig | 8 +
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-pll.c | 427 ++++++++++++++++++
- .../clk/starfive/clk-starfive-jh7110-pll.h | 293 ++++++++++++
- 5 files changed, 735 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.c
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19657,6 +19657,12 @@ M: Emil Renner Berthing <kernel@esmil.dk
- S: Maintained
- F: arch/riscv/boot/dts/starfive/
-
-+STARFIVE JH7110 PLL CLOCK DRIVER
-+M: Xingyu Wu <xingyu.wu@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
-+F: drivers/clk/starfive/clk-starfive-jh7110-pll.*
-+
- STARFIVE JH71X0 CLOCK DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
- M: Hal Feng <hal.feng@starfivetech.com>
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -21,6 +21,14 @@ config CLK_STARFIVE_JH7100_AUDIO
- Say Y or M here to support the audio clocks on the StarFive JH7100
- SoC.
-
-+config CLK_STARFIVE_JH7110_PLL
-+ bool "StarFive JH7110 PLL clock support"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
-+ help
-+ Say yes here to support the PLL clock controller on the
-+ StarFive JH7110 SoC.
-+
- config CLK_STARFIVE_JH7110_SYS
- bool "StarFive JH7110 system clock support"
- depends on ARCH_STARFIVE || COMPILE_TEST
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -4,5 +4,6 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk
- obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
-
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) += clk-starfive-jh7110-pll.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
-@@ -0,0 +1,427 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 PLL Clock Generator Driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * This driver is about to register JH7110 PLL clock generator and support ops.
-+ * The JH7110 have three PLL clock, PLL0, PLL1 and PLL2.
-+ * Each PLL clocks work in integer mode or fraction mode by some dividers,
-+ * and the configuration registers and dividers are set in several syscon registers.
-+ * The formula for calculating frequency is:
-+ * Fvco = Fref * (NI + NF) / M / Q1
-+ * Fref: OSC source clock rate
-+ * NI: integer frequency dividing ratio of feedback divider, set by fbdiv[11:0].
-+ * NF: fractional frequency dividing ratio, set by frac[23:0]. NF = frac[23:0] / 2^24 = 0 ~ 0.999.
-+ * M: frequency dividing ratio of pre-divider, set by prediv[5:0].
-+ * Q1: frequency dividing ratio of post divider, set by postdiv1[1:0], Q1= 1,2,4,8.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/debugfs.h>
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110-pll.h"
-+
-+static struct jh7110_clk_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct jh7110_clk_pll_data, hw);
-+}
-+
-+static struct jh7110_clk_pll_priv *jh7110_pll_priv_from(struct jh7110_clk_pll_data *data)
-+{
-+ return container_of(data, struct jh7110_clk_pll_priv, data[data->idx]);
-+}
-+
-+/* Read register value from syscon and calculate PLL(x) frequency */
-+static unsigned long jh7110_pll_get_freq(struct jh7110_clk_pll_data *data,
-+ unsigned long parent_rate)
-+{
-+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-+ struct jh7110_pll_syscon_offset *offset = &data->offset;
-+ struct jh7110_pll_syscon_mask *mask = &data->mask;
-+ struct jh7110_pll_syscon_shift *shift = &data->shift;
-+ unsigned long freq = 0;
-+ unsigned long frac_cal;
-+ u32 dacpd;
-+ u32 dsmpd;
-+ u32 fbdiv;
-+ u32 prediv;
-+ u32 postdiv1;
-+ u32 frac;
-+ u32 reg_val;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->dacpd, &reg_val))
-+ goto read_error;
-+ dacpd = (reg_val & mask->dacpd) >> shift->dacpd;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->dsmpd, &reg_val))
-+ goto read_error;
-+ dsmpd = (reg_val & mask->dsmpd) >> shift->dsmpd;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->fbdiv, &reg_val))
-+ goto read_error;
-+ fbdiv = (reg_val & mask->fbdiv) >> shift->fbdiv;
-+ /* fbdiv value should be 8 to 4095 */
-+ if (fbdiv < 8)
-+ goto read_error;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->prediv, &reg_val))
-+ goto read_error;
-+ prediv = (reg_val & mask->prediv) >> shift->prediv;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->postdiv1, &reg_val))
-+ goto read_error;
-+ /* postdiv1 = 2 ^ reg_val */
-+ postdiv1 = 1 << ((reg_val & mask->postdiv1) >> shift->postdiv1);
-+
-+ if (regmap_read(priv->syscon_regmap, offset->frac, &reg_val))
-+ goto read_error;
-+ frac = (reg_val & mask->frac) >> shift->frac;
-+
-+ /*
-+ * Integer Mode (Both 1) or Fraction Mode (Both 0).
-+ * And the decimal places are counted by expanding them by
-+ * a factor of STARFIVE_PLL_FRAC_PATR_SIZE.
-+ */
-+ if (dacpd == 1 && dsmpd == 1)
-+ frac_cal = 0;
-+ else if (dacpd == 0 && dsmpd == 0)
-+ frac_cal = (unsigned long)frac * STARFIVE_PLL_FRAC_PATR_SIZE / (1 << 24);
-+ else
-+ goto read_error;
-+
-+ /* Fvco = Fref * (NI + NF) / M / Q1 */
-+ freq = parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
-+ (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1;
-+
-+read_error:
-+ return freq;
-+}
-+
-+static unsigned long jh7110_pll_rate_sub_fabs(unsigned long rate1, unsigned long rate2)
-+{
-+ return rate1 > rate2 ? (rate1 - rate2) : (rate2 - rate1);
-+}
-+
-+/* Select the appropriate frequency from the already configured registers value */
-+static void jh7110_pll_select_near_freq_id(struct jh7110_clk_pll_data *data,
-+ unsigned long rate)
-+{
-+ const struct starfive_pll_syscon_value *syscon_val;
-+ unsigned int id;
-+ unsigned int pll_arry_size;
-+ unsigned long rate_diff;
-+
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ pll_arry_size = ARRAY_SIZE(jh7110_pll0_syscon_freq);
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ pll_arry_size = ARRAY_SIZE(jh7110_pll1_syscon_freq);
-+ else
-+ pll_arry_size = ARRAY_SIZE(jh7110_pll2_syscon_freq);
-+
-+ /* compare the frequency one by one from small to large in order */
-+ for (id = 0; id < pll_arry_size; id++) {
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ syscon_val = &jh7110_pll0_syscon_freq[id];
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ syscon_val = &jh7110_pll1_syscon_freq[id];
-+ else
-+ syscon_val = &jh7110_pll2_syscon_freq[id];
-+
-+ if (rate == syscon_val->freq)
-+ goto match_end;
-+
-+ /* select near frequency */
-+ if (rate < syscon_val->freq) {
-+ /* The last frequency is closer to the target rate than this time. */
-+ if (id > 0)
-+ if (rate_diff < jh7110_pll_rate_sub_fabs(rate, syscon_val->freq))
-+ id--;
-+
-+ goto match_end;
-+ } else {
-+ rate_diff = jh7110_pll_rate_sub_fabs(rate, syscon_val->freq);
-+ }
-+ }
-+
-+match_end:
-+ data->freq_select_idx = id;
-+}
-+
-+static int jh7110_pll_set_freq_syscon(struct jh7110_clk_pll_data *data)
-+{
-+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-+ struct jh7110_pll_syscon_offset *offset = &data->offset;
-+ struct jh7110_pll_syscon_mask *mask = &data->mask;
-+ struct jh7110_pll_syscon_shift *shift = &data->shift;
-+ unsigned int freq_idx = data->freq_select_idx;
-+ const struct starfive_pll_syscon_value *syscon_val;
-+ int ret;
-+
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ syscon_val = &jh7110_pll0_syscon_freq[freq_idx];
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ syscon_val = &jh7110_pll1_syscon_freq[freq_idx];
-+ else
-+ syscon_val = &jh7110_pll2_syscon_freq[freq_idx];
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
-+ (syscon_val->dacpd << shift->dacpd));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
-+ (syscon_val->dsmpd << shift->dsmpd));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
-+ (syscon_val->prediv << shift->prediv));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
-+ (syscon_val->fbdiv << shift->fbdiv));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
-+ ((syscon_val->postdiv1 >> 1) << shift->postdiv1));
-+ if (ret)
-+ goto set_failed;
-+
-+ /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
-+ if (syscon_val->dacpd == 0 && syscon_val->dsmpd == 0)
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
-+ (syscon_val->frac << shift->frac));
-+ else if (syscon_val->dacpd != syscon_val->dsmpd)
-+ ret = -EINVAL;
-+
-+set_failed:
-+ return ret;
-+}
-+
-+static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-+{
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+
-+ return jh7110_pll_get_freq(data, parent_rate);
-+}
-+
-+static int jh7110_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
-+{
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+
-+ jh7110_pll_select_near_freq_id(data, req->rate);
-+
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ req->rate = jh7110_pll0_syscon_freq[data->freq_select_idx].freq;
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ req->rate = jh7110_pll1_syscon_freq[data->freq_select_idx].freq;
-+ else
-+ req->rate = jh7110_pll2_syscon_freq[data->freq_select_idx].freq;
-+
-+ return 0;
-+}
-+
-+static int jh7110_pll_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+
-+ return jh7110_pll_set_freq_syscon(data);
-+}
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7110_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
-+{
-+ static const struct debugfs_reg32 jh7110_clk_pll_reg = {
-+ .name = "CTRL",
-+ .offset = 0,
-+ };
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-+ struct debugfs_regset32 *regset;
-+
-+ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
-+ if (!regset)
-+ return;
-+
-+ regset->regs = &jh7110_clk_pll_reg;
-+ regset->nregs = 1;
-+
-+ debugfs_create_regset32("registers", 0400, dentry, regset);
-+}
-+#else
-+#define jh7110_pll_debug_init NULL
-+#endif
-+
-+static const struct clk_ops jh7110_pll_ops = {
-+ .recalc_rate = jh7110_pll_recalc_rate,
-+ .determine_rate = jh7110_pll_determine_rate,
-+ .set_rate = jh7110_pll_set_rate,
-+ .debug_init = jh7110_pll_debug_init,
-+};
-+
-+/* get offset, mask and shift of PLL(x) syscon */
-+static int jh7110_pll_data_get(struct jh7110_clk_pll_data *data, int index)
-+{
-+ struct jh7110_pll_syscon_offset *offset = &data->offset;
-+ struct jh7110_pll_syscon_mask *mask = &data->mask;
-+ struct jh7110_pll_syscon_shift *shift = &data->shift;
-+
-+ if (index == JH7110_CLK_PLL0_OUT) {
-+ offset->dacpd = STARFIVE_JH7110_PLL0_DACPD_OFFSET;
-+ offset->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_OFFSET;
-+ offset->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_OFFSET;
-+ offset->frac = STARFIVE_JH7110_PLL0_FRAC_OFFSET;
-+ offset->prediv = STARFIVE_JH7110_PLL0_PREDIV_OFFSET;
-+ offset->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET;
-+
-+ mask->dacpd = STARFIVE_JH7110_PLL0_DACPD_MASK;
-+ mask->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_MASK;
-+ mask->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_MASK;
-+ mask->frac = STARFIVE_JH7110_PLL0_FRAC_MASK;
-+ mask->prediv = STARFIVE_JH7110_PLL0_PREDIV_MASK;
-+ mask->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_MASK;
-+
-+ shift->dacpd = STARFIVE_JH7110_PLL0_DACPD_SHIFT;
-+ shift->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_SHIFT;
-+ shift->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_SHIFT;
-+ shift->frac = STARFIVE_JH7110_PLL0_FRAC_SHIFT;
-+ shift->prediv = STARFIVE_JH7110_PLL0_PREDIV_SHIFT;
-+ shift->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT;
-+
-+ } else if (index == JH7110_CLK_PLL1_OUT) {
-+ offset->dacpd = STARFIVE_JH7110_PLL1_DACPD_OFFSET;
-+ offset->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_OFFSET;
-+ offset->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_OFFSET;
-+ offset->frac = STARFIVE_JH7110_PLL1_FRAC_OFFSET;
-+ offset->prediv = STARFIVE_JH7110_PLL1_PREDIV_OFFSET;
-+ offset->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET;
-+
-+ mask->dacpd = STARFIVE_JH7110_PLL1_DACPD_MASK;
-+ mask->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_MASK;
-+ mask->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_MASK;
-+ mask->frac = STARFIVE_JH7110_PLL1_FRAC_MASK;
-+ mask->prediv = STARFIVE_JH7110_PLL1_PREDIV_MASK;
-+ mask->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_MASK;
-+
-+ shift->dacpd = STARFIVE_JH7110_PLL1_DACPD_SHIFT;
-+ shift->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_SHIFT;
-+ shift->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_SHIFT;
-+ shift->frac = STARFIVE_JH7110_PLL1_FRAC_SHIFT;
-+ shift->prediv = STARFIVE_JH7110_PLL1_PREDIV_SHIFT;
-+ shift->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT;
-+
-+ } else if (index == JH7110_CLK_PLL2_OUT) {
-+ offset->dacpd = STARFIVE_JH7110_PLL2_DACPD_OFFSET;
-+ offset->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_OFFSET;
-+ offset->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_OFFSET;
-+ offset->frac = STARFIVE_JH7110_PLL2_FRAC_OFFSET;
-+ offset->prediv = STARFIVE_JH7110_PLL2_PREDIV_OFFSET;
-+ offset->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET;
-+
-+ mask->dacpd = STARFIVE_JH7110_PLL2_DACPD_MASK;
-+ mask->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_MASK;
-+ mask->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_MASK;
-+ mask->frac = STARFIVE_JH7110_PLL2_FRAC_MASK;
-+ mask->prediv = STARFIVE_JH7110_PLL2_PREDIV_MASK;
-+ mask->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_MASK;
-+
-+ shift->dacpd = STARFIVE_JH7110_PLL2_DACPD_SHIFT;
-+ shift->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_SHIFT;
-+ shift->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_SHIFT;
-+ shift->frac = STARFIVE_JH7110_PLL2_FRAC_SHIFT;
-+ shift->prediv = STARFIVE_JH7110_PLL2_PREDIV_SHIFT;
-+ shift->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT;
-+
-+ } else {
-+ return -ENOENT;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh7110_clk_pll_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_PLLCLK_END)
-+ return &priv->data[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static int jh7110_pll_probe(struct platform_device *pdev)
-+{
-+ const char *pll_name[JH7110_PLLCLK_END] = {
-+ "pll0_out",
-+ "pll1_out",
-+ "pll2_out"
-+ };
-+ struct jh7110_clk_pll_priv *priv;
-+ struct jh7110_clk_pll_data *data;
-+ int ret;
-+ unsigned int idx;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, JH7110_PLLCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->dev = &pdev->dev;
-+ priv->syscon_regmap = syscon_node_to_regmap(priv->dev->of_node->parent);
-+ if (IS_ERR(priv->syscon_regmap))
-+ return PTR_ERR(priv->syscon_regmap);
-+
-+ for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
-+ struct clk_parent_data parents = {
-+ .index = 0,
-+ };
-+ struct clk_init_data init = {
-+ .name = pll_name[idx],
-+ .ops = &jh7110_pll_ops,
-+ .parent_data = &parents,
-+ .num_parents = 1,
-+ .flags = 0,
-+ };
-+
-+ data = &priv->data[idx];
-+
-+ ret = jh7110_pll_data_get(data, idx);
-+ if (ret)
-+ return ret;
-+
-+ data->hw.init = &init;
-+ data->idx = idx;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &data->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return devm_of_clk_add_hw_provider(&pdev->dev, jh7110_pll_get, priv);
-+}
-+
-+static const struct of_device_id jh7110_pll_match[] = {
-+ { .compatible = "starfive,jh7110-pll" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_pll_match);
-+
-+static struct platform_driver jh7110_pll_driver = {
-+ .driver = {
-+ .name = "clk-starfive-jh7110-pll",
-+ .of_match_table = jh7110_pll_match,
-+ },
-+};
-+builtin_platform_driver_probe(jh7110_pll_driver, jh7110_pll_probe);
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.h
-@@ -0,0 +1,293 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * StarFive JH7110 PLL Clock Generator Driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef _CLK_STARFIVE_JH7110_PLL_H_
-+#define _CLK_STARFIVE_JH7110_PLL_H_
-+
-+#include <linux/bits.h>
-+
-+/* The decimal places are counted by expanding them by a factor of STARFIVE_PLL_FRAC_PATR_SIZE */
-+#define STARFIVE_PLL_FRAC_PATR_SIZE 1000
-+
-+#define STARFIVE_JH7110_PLL0_DACPD_OFFSET 0x18
-+#define STARFIVE_JH7110_PLL0_DACPD_SHIFT 24
-+#define STARFIVE_JH7110_PLL0_DACPD_MASK BIT(24)
-+#define STARFIVE_JH7110_PLL0_DSMPD_OFFSET 0x18
-+#define STARFIVE_JH7110_PLL0_DSMPD_SHIFT 25
-+#define STARFIVE_JH7110_PLL0_DSMPD_MASK BIT(25)
-+#define STARFIVE_JH7110_PLL0_FBDIV_OFFSET 0x1c
-+#define STARFIVE_JH7110_PLL0_FBDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL0_FBDIV_MASK GENMASK(11, 0)
-+#define STARFIVE_JH7110_PLL0_FRAC_OFFSET 0x20
-+#define STARFIVE_JH7110_PLL0_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_PLL0_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET 0x20
-+#define STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_PLL0_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_PLL0_PREDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL0_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL0_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_PLL1_DACPD_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL1_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_PLL1_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_PLL1_DSMPD_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL1_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_PLL1_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_PLL1_FBDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL1_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_PLL1_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_PLL1_FRAC_OFFSET 0x28
-+#define STARFIVE_JH7110_PLL1_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_PLL1_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET 0x28
-+#define STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_PLL1_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_PLL1_PREDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL1_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL1_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_PLL2_DACPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL2_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_PLL2_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_PLL2_DSMPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL2_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_PLL2_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_PLL2_FBDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL2_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_PLL2_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_PLL2_FRAC_OFFSET 0x30
-+#define STARFIVE_JH7110_PLL2_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_PLL2_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET 0x30
-+#define STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_PLL2_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_PLL2_PREDIV_OFFSET 0x34
-+#define STARFIVE_JH7110_PLL2_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL2_PREDIV_MASK GENMASK(5, 0)
-+
-+struct jh7110_pll_syscon_offset {
-+ unsigned int dacpd;
-+ unsigned int dsmpd;
-+ unsigned int fbdiv;
-+ unsigned int frac;
-+ unsigned int prediv;
-+ unsigned int postdiv1;
-+};
-+
-+struct jh7110_pll_syscon_mask {
-+ u32 dacpd;
-+ u32 dsmpd;
-+ u32 fbdiv;
-+ u32 frac;
-+ u32 prediv;
-+ u32 postdiv1;
-+};
-+
-+struct jh7110_pll_syscon_shift {
-+ char dacpd;
-+ char dsmpd;
-+ char fbdiv;
-+ char frac;
-+ char prediv;
-+ char postdiv1;
-+};
-+
-+struct jh7110_clk_pll_data {
-+ struct clk_hw hw;
-+ unsigned int idx;
-+ unsigned int freq_select_idx;
-+
-+ struct jh7110_pll_syscon_offset offset;
-+ struct jh7110_pll_syscon_mask mask;
-+ struct jh7110_pll_syscon_shift shift;
-+};
-+
-+struct jh7110_clk_pll_priv {
-+ struct device *dev;
-+ struct regmap *syscon_regmap;
-+ struct jh7110_clk_pll_data data[];
-+};
-+
-+struct starfive_pll_syscon_value {
-+ unsigned long freq;
-+ u32 prediv;
-+ u32 fbdiv;
-+ u32 postdiv1;
-+/* Both daxpd and dsmpd set 1 while integer mode */
-+/* Both daxpd and dsmpd set 0 while fraction mode */
-+ u32 dacpd;
-+ u32 dsmpd;
-+/* frac value should be decimals multiplied by 2^24 */
-+ u32 frac;
-+};
-+
-+enum starfive_pll0_freq_index {
-+ PLL0_FREQ_375 = 0,
-+ PLL0_FREQ_500,
-+ PLL0_FREQ_625,
-+ PLL0_FREQ_750,
-+ PLL0_FREQ_875,
-+ PLL0_FREQ_1000,
-+ PLL0_FREQ_1250,
-+ PLL0_FREQ_1375,
-+ PLL0_FREQ_1500,
-+ PLL0_FREQ_MAX
-+};
-+
-+enum starfive_pll1_freq_index {
-+ PLL1_FREQ_1066 = 0,
-+ PLL1_FREQ_1200,
-+ PLL1_FREQ_1400,
-+ PLL1_FREQ_1600,
-+ PLL1_FREQ_MAX
-+};
-+
-+enum starfive_pll2_freq_index {
-+ PLL2_FREQ_1188 = 0,
-+ PLL2_FREQ_12288,
-+ PLL2_FREQ_MAX
-+};
-+
-+/*
-+ * Because the pll frequency is relatively fixed,
-+ * it cannot be set arbitrarily, so it needs a specific configuration.
-+ * PLL0 frequency should be multiple of 125MHz (USB frequency).
-+ */
-+static const struct starfive_pll_syscon_value
-+ jh7110_pll0_syscon_freq[PLL0_FREQ_MAX] = {
-+ [PLL0_FREQ_375] = {
-+ .freq = 375000000,
-+ .prediv = 8,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_500] = {
-+ .freq = 500000000,
-+ .prediv = 6,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_625] = {
-+ .freq = 625000000,
-+ .prediv = 24,
-+ .fbdiv = 625,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_750] = {
-+ .freq = 750000000,
-+ .prediv = 4,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_875] = {
-+ .freq = 875000000,
-+ .prediv = 24,
-+ .fbdiv = 875,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1000] = {
-+ .freq = 1000000000,
-+ .prediv = 3,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1250] = {
-+ .freq = 1250000000,
-+ .prediv = 12,
-+ .fbdiv = 625,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1375] = {
-+ .freq = 1375000000,
-+ .prediv = 24,
-+ .fbdiv = 1375,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1500] = {
-+ .freq = 1500000000,
-+ .prediv = 2,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+};
-+
-+static const struct starfive_pll_syscon_value
-+ jh7110_pll1_syscon_freq[PLL1_FREQ_MAX] = {
-+ [PLL1_FREQ_1066] = {
-+ .freq = 1066000000,
-+ .prediv = 12,
-+ .fbdiv = 533,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL1_FREQ_1200] = {
-+ .freq = 1200000000,
-+ .prediv = 1,
-+ .fbdiv = 50,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL1_FREQ_1400] = {
-+ .freq = 1400000000,
-+ .prediv = 6,
-+ .fbdiv = 350,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL1_FREQ_1600] = {
-+ .freq = 1600000000,
-+ .prediv = 3,
-+ .fbdiv = 200,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+};
-+
-+static const struct starfive_pll_syscon_value
-+ jh7110_pll2_syscon_freq[PLL2_FREQ_MAX] = {
-+ [PLL2_FREQ_1188] = {
-+ .freq = 1188000000,
-+ .prediv = 2,
-+ .fbdiv = 99,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL2_FREQ_12288] = {
-+ .freq = 1228800000,
-+ .prediv = 5,
-+ .fbdiv = 256,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+};
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch b/target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch
deleted file mode 100644
index 4fd78cd5bb..0000000000
--- a/target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 1f788a0a5092b1e1cfd02aa7f31ceb551befa7e6 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 16:43:50 +0800
-Subject: [PATCH 033/122] dt-bindings: clock: jh7110-syscrg: Add PLL clock
- inputs
-
-Add PLL clock inputs from PLL clock generator.
-
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-syscrg.yaml | 20 +++++++++++++++++--
- 1 file changed, 18 insertions(+), 2 deletions(-)
-
---- a/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
-@@ -27,6 +27,9 @@ properties:
- - description: External I2S RX left/right channel clock
- - description: External TDM clock
- - description: External audio master clock
-+ - description: PLL0
-+ - description: PLL1
-+ - description: PLL2
-
- - items:
- - description: Main Oscillator (24 MHz)
-@@ -38,6 +41,9 @@ properties:
- - description: External I2S RX left/right channel clock
- - description: External TDM clock
- - description: External audio master clock
-+ - description: PLL0
-+ - description: PLL1
-+ - description: PLL2
-
- clock-names:
- oneOf:
-@@ -52,6 +58,9 @@ properties:
- - const: i2srx_lrck_ext
- - const: tdm_ext
- - const: mclk_ext
-+ - const: pll0_out
-+ - const: pll1_out
-+ - const: pll2_out
-
- - items:
- - const: osc
-@@ -63,6 +72,9 @@ properties:
- - const: i2srx_lrck_ext
- - const: tdm_ext
- - const: mclk_ext
-+ - const: pll0_out
-+ - const: pll1_out
-+ - const: pll2_out
-
- '#clock-cells':
- const: 1
-@@ -93,12 +105,16 @@ examples:
- <&gmac1_rgmii_rxin>,
- <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
- <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-- <&tdm_ext>, <&mclk_ext>;
-+ <&tdm_ext>, <&mclk_ext>,
-+ <&pllclk JH7110_CLK_PLL0_OUT>,
-+ <&pllclk JH7110_CLK_PLL1_OUT>,
-+ <&pllclk JH7110_CLK_PLL2_OUT>;
- clock-names = "osc", "gmac1_rmii_refin",
- "gmac1_rgmii_rxin",
- "i2stx_bclk_ext", "i2stx_lrck_ext",
- "i2srx_bclk_ext", "i2srx_lrck_ext",
-- "tdm_ext", "mclk_ext";
-+ "tdm_ext", "mclk_ext",
-+ "pll0_out", "pll1_out", "pll2_out";
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
diff --git a/target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch b/target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch
deleted file mode 100644
index 3e6237681f..0000000000
--- a/target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From ffd7ee4fbd69d477a2156d9cba6ae80434a4c894 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 17:16:07 +0800
-Subject: [PATCH 034/122] clk: starfive: jh7110-sys: Modify PLL clocks source
-
-Modify PLL clocks source to be got from dts instead of
-the fixed factor clocks.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clk/starfive/Kconfig | 1 +
- .../clk/starfive/clk-starfive-jh7110-sys.c | 31 ++++---------------
- 2 files changed, 7 insertions(+), 25 deletions(-)
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -35,6 +35,7 @@ config CLK_STARFIVE_JH7110_SYS
- select AUXILIARY_BUS
- select CLK_STARFIVE_JH71X0
- select RESET_STARFIVE_JH7110
-+ select CLK_STARFIVE_JH7110_PLL
- default ARCH_STARFIVE
- help
- Say yes here to support the system clock controller on the
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -404,29 +404,6 @@ static int __init jh7110_syscrg_probe(st
-
- dev_set_drvdata(priv->dev, (void *)(&priv->base));
-
-- /*
-- * These PLL clocks are not actually fixed factor clocks and can be
-- * controlled by the syscon registers of JH7110. They will be dropped
-- * and registered in the PLL clock driver instead.
-- */
-- /* 24MHz -> 1000.0MHz */
-- priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",
-- "osc", 0, 125, 3);
-- if (IS_ERR(priv->pll[0]))
-- return PTR_ERR(priv->pll[0]);
--
-- /* 24MHz -> 1066.0MHz */
-- priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",
-- "osc", 0, 533, 12);
-- if (IS_ERR(priv->pll[1]))
-- return PTR_ERR(priv->pll[1]);
--
-- /* 24MHz -> 1188.0MHz */
-- priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",
-- "osc", 0, 99, 2);
-- if (IS_ERR(priv->pll[2]))
-- return PTR_ERR(priv->pll[2]);
--
- for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {
- u32 max = jh7110_sysclk_data[idx].max;
- struct clk_parent_data parents[4] = {};
-@@ -464,8 +441,12 @@ static int __init jh7110_syscrg_probe(st
- parents[i].fw_name = "tdm_ext";
- else if (pidx == JH7110_SYSCLK_MCLK_EXT)
- parents[i].fw_name = "mclk_ext";
-- else
-- parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];
-+ else if (pidx == JH7110_SYSCLK_PLL0_OUT)
-+ parents[i].fw_name = "pll0_out";
-+ else if (pidx == JH7110_SYSCLK_PLL1_OUT)
-+ parents[i].fw_name = "pll1_out";
-+ else if (pidx == JH7110_SYSCLK_PLL2_OUT)
-+ parents[i].fw_name = "pll2_out";
- }
-
- clk->hw.init = &init;
diff --git a/target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch b/target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch
deleted file mode 100644
index cf5fc7cbba..0000000000
--- a/target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 35bc6491a7b24872155a616f7770d3a5d6e40344 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Thu, 19 Jan 2023 17:44:46 +0800
-Subject: [PATCH 035/122] dt-bindings: power: Add starfive,jh7110-pmu
-
-Add bindings for the Power Management Unit on the StarFive JH7110 SoC.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
----
- .../bindings/power/starfive,jh7110-pmu.yaml | 45 +++++++++++++++++++
- .../dt-bindings/power/starfive,jh7110-pmu.h | 17 +++++++
- 2 files changed, 62 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
- create mode 100644 include/dt-bindings/power/starfive,jh7110-pmu.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
-@@ -0,0 +1,45 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/power/starfive,jh7110-pmu.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Power Management Unit
-+
-+maintainers:
-+ - Walker Chen <walker.chen@starfivetech.com>
-+
-+description: |
-+ StarFive JH7110 SoC includes support for multiple power domains which can be
-+ powered on/off by software based on different application scenes to save power.
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7110-pmu
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ "#power-domain-cells":
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - "#power-domain-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pwrc: power-controller@17030000 {
-+ compatible = "starfive,jh7110-pmu";
-+ reg = <0x17030000 0x10000>;
-+ interrupts = <111>;
-+ #power-domain-cells = <1>;
-+ };
---- /dev/null
-+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Author: Walker Chen <walker.chen@starfivetech.com>
-+ */
-+#ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
-+#define __DT_BINDINGS_POWER_JH7110_POWER_H__
-+
-+#define JH7110_PD_SYSTOP 0
-+#define JH7110_PD_CPU 1
-+#define JH7110_PD_GPUA 2
-+#define JH7110_PD_VDEC 3
-+#define JH7110_PD_VOUT 4
-+#define JH7110_PD_ISP 5
-+#define JH7110_PD_VENC 6
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch b/target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch
deleted file mode 100644
index 81c7548aa0..0000000000
--- a/target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch
+++ /dev/null
@@ -1,478 +0,0 @@
-From 3e3b85a1064b07a5107504af1e8f0a42ff9d1fc1 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Thu, 19 Jan 2023 17:44:47 +0800
-Subject: [PATCH 036/122] soc: starfive: Add StarFive JH71XX pmu driver
-
-Add pmu driver for the StarFive JH71XX SoC.
-
-As the power domains provider, the Power Management Unit (PMU) is
-designed for including multiple PM domains that can be used for power
-gating of selected IP blocks for power saving by reduced leakage
-current. It accepts software encourage command to switch the power mode
-of SoC.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
----
- MAINTAINERS | 14 ++
- drivers/soc/Kconfig | 1 +
- drivers/soc/Makefile | 1 +
- drivers/soc/starfive/Kconfig | 12 +
- drivers/soc/starfive/Makefile | 3 +
- drivers/soc/starfive/jh71xx_pmu.c | 383 ++++++++++++++++++++++++++++++
- 6 files changed, 414 insertions(+)
- create mode 100644 drivers/soc/starfive/Kconfig
- create mode 100644 drivers/soc/starfive/Makefile
- create mode 100644 drivers/soc/starfive/jh71xx_pmu.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19689,6 +19689,20 @@ F: Documentation/devicetree/bindings/res
- F: drivers/reset/starfive/reset-starfive-jh71*
- F: include/dt-bindings/reset/starfive?jh71*.h
-
-+STARFIVE SOC DRIVER
-+M: Conor Dooley <conor@kernel.org>
-+S: Maintained
-+T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
-+F: drivers/soc/starfive/
-+F: include/soc/starfive/
-+
-+STARFIVE JH71XX PMU CONTROLLER DRIVER
-+M: Walker Chen <walker.chen@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/power/starfive*
-+F: drivers/soc/starfive/jh71xx_pmu.c
-+F: include/dt-bindings/power/starfive,jh7110-pmu.h
-+
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
- M: Josh Poimboeuf <jpoimboe@kernel.org>
---- a/drivers/soc/Kconfig
-+++ b/drivers/soc/Kconfig
-@@ -21,6 +21,7 @@ source "drivers/soc/renesas/Kconfig"
- source "drivers/soc/rockchip/Kconfig"
- source "drivers/soc/samsung/Kconfig"
- source "drivers/soc/sifive/Kconfig"
-+source "drivers/soc/starfive/Kconfig"
- source "drivers/soc/sunxi/Kconfig"
- source "drivers/soc/tegra/Kconfig"
- source "drivers/soc/ti/Kconfig"
---- a/drivers/soc/Makefile
-+++ b/drivers/soc/Makefile
-@@ -27,6 +27,7 @@ obj-y += renesas/
- obj-y += rockchip/
- obj-$(CONFIG_SOC_SAMSUNG) += samsung/
- obj-$(CONFIG_SOC_SIFIVE) += sifive/
-+obj-$(CONFIG_SOC_STARFIVE) += starfive/
- obj-y += sunxi/
- obj-$(CONFIG_ARCH_TEGRA) += tegra/
- obj-y += ti/
---- /dev/null
-+++ b/drivers/soc/starfive/Kconfig
-@@ -0,0 +1,12 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+config JH71XX_PMU
-+ bool "Support PMU for StarFive JH71XX Soc"
-+ depends on PM
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ default SOC_STARFIVE
-+ select PM_GENERIC_DOMAINS
-+ help
-+ Say 'y' here to enable support power domain support.
-+ In order to meet low power requirements, a Power Management Unit (PMU)
-+ is designed for controlling power resources in StarFive JH71XX SoCs.
---- /dev/null
-+++ b/drivers/soc/starfive/Makefile
-@@ -0,0 +1,3 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+obj-$(CONFIG_JH71XX_PMU) += jh71xx_pmu.o
---- /dev/null
-+++ b/drivers/soc/starfive/jh71xx_pmu.c
-@@ -0,0 +1,383 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * StarFive JH71XX PMU (Power Management Unit) Controller Driver
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_domain.h>
-+#include <dt-bindings/power/starfive,jh7110-pmu.h>
-+
-+/* register offset */
-+#define JH71XX_PMU_SW_TURN_ON_POWER 0x0C
-+#define JH71XX_PMU_SW_TURN_OFF_POWER 0x10
-+#define JH71XX_PMU_SW_ENCOURAGE 0x44
-+#define JH71XX_PMU_TIMER_INT_MASK 0x48
-+#define JH71XX_PMU_CURR_POWER_MODE 0x80
-+#define JH71XX_PMU_EVENT_STATUS 0x88
-+#define JH71XX_PMU_INT_STATUS 0x8C
-+
-+/* sw encourage cfg */
-+#define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
-+#define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
-+#define JH71XX_PMU_SW_ENCOURAGE_DIS_LO 0x0A
-+#define JH71XX_PMU_SW_ENCOURAGE_DIS_HI 0xA0
-+#define JH71XX_PMU_SW_ENCOURAGE_ON 0xFF
-+
-+/* pmu int status */
-+#define JH71XX_PMU_INT_SEQ_DONE BIT(0)
-+#define JH71XX_PMU_INT_HW_REQ BIT(1)
-+#define JH71XX_PMU_INT_SW_FAIL GENMASK(3, 2)
-+#define JH71XX_PMU_INT_HW_FAIL GENMASK(5, 4)
-+#define JH71XX_PMU_INT_PCH_FAIL GENMASK(8, 6)
-+#define JH71XX_PMU_INT_ALL_MASK GENMASK(8, 0)
-+
-+/*
-+ * The time required for switching power status is based on the time
-+ * to turn on the largest domain's power, which is at microsecond level
-+ */
-+#define JH71XX_PMU_TIMEOUT_US 100
-+
-+struct jh71xx_domain_info {
-+ const char * const name;
-+ unsigned int flags;
-+ u8 bit;
-+};
-+
-+struct jh71xx_pmu_match_data {
-+ const struct jh71xx_domain_info *domain_info;
-+ int num_domains;
-+};
-+
-+struct jh71xx_pmu {
-+ struct device *dev;
-+ const struct jh71xx_pmu_match_data *match_data;
-+ void __iomem *base;
-+ struct generic_pm_domain **genpd;
-+ struct genpd_onecell_data genpd_data;
-+ int irq;
-+ spinlock_t lock; /* protects pmu reg */
-+};
-+
-+struct jh71xx_pmu_dev {
-+ const struct jh71xx_domain_info *domain_info;
-+ struct jh71xx_pmu *pmu;
-+ struct generic_pm_domain genpd;
-+};
-+
-+static int jh71xx_pmu_get_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool *is_on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+
-+ if (!mask)
-+ return -EINVAL;
-+
-+ *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
-+
-+ return 0;
-+}
-+
-+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+ unsigned long flags;
-+ u32 val;
-+ u32 mode;
-+ u32 encourage_lo;
-+ u32 encourage_hi;
-+ bool is_on;
-+ int ret;
-+
-+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
-+ if (ret) {
-+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
-+ pmd->genpd.name);
-+ return ret;
-+ }
-+
-+ if (is_on == on) {
-+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
-+ pmd->genpd.name, on ? "en" : "dis");
-+ return 0;
-+ }
-+
-+ spin_lock_irqsave(&pmu->lock, flags);
-+
-+ /*
-+ * The PMU accepts software encourage to switch power mode in the following 2 steps:
-+ *
-+ * 1.Configure the register SW_TURN_ON_POWER (offset 0x0c) by writing 1 to
-+ * the bit corresponding to the power domain that will be turned on
-+ * and writing 0 to the others.
-+ * Likewise, configure the register SW_TURN_OFF_POWER (offset 0x10) by
-+ * writing 1 to the bit corresponding to the power domain that will be
-+ * turned off and writing 0 to the others.
-+ */
-+ if (on) {
-+ mode = JH71XX_PMU_SW_TURN_ON_POWER;
-+ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_EN_LO;
-+ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_EN_HI;
-+ } else {
-+ mode = JH71XX_PMU_SW_TURN_OFF_POWER;
-+ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_DIS_LO;
-+ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_DIS_HI;
-+ }
-+
-+ writel(mask, pmu->base + mode);
-+
-+ /*
-+ * 2.Write SW encourage command sequence to the Software Encourage Reg (offset 0x44)
-+ * First write SW_MODE_ENCOURAGE_ON to JH71XX_PMU_SW_ENCOURAGE. This will reset
-+ * the state machine which parses the command sequence. This register must be
-+ * written every time software wants to power on/off a domain.
-+ * Then write the lower bits of the command sequence, followed by the upper
-+ * bits. The sequence differs between powering on & off a domain.
-+ */
-+ writel(JH71XX_PMU_SW_ENCOURAGE_ON, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
-+ writel(encourage_lo, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
-+ writel(encourage_hi, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
-+
-+ spin_unlock_irqrestore(&pmu->lock, flags);
-+
-+ /* Wait for the power domain bit to be enabled / disabled */
-+ if (on) {
-+ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
-+ val, val & mask,
-+ 1, JH71XX_PMU_TIMEOUT_US);
-+ } else {
-+ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
-+ val, !(val & mask),
-+ 1, JH71XX_PMU_TIMEOUT_US);
-+ }
-+
-+ if (ret) {
-+ dev_err(pmu->dev, "%s: failed to power %s\n",
-+ pmd->genpd.name, on ? "on" : "off");
-+ return -ETIMEDOUT;
-+ }
-+
-+ return 0;
-+}
-+
-+static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
-+{
-+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
-+ struct jh71xx_pmu_dev, genpd);
-+ u32 pwr_mask = BIT(pmd->domain_info->bit);
-+
-+ return jh71xx_pmu_set_state(pmd, pwr_mask, true);
-+}
-+
-+static int jh71xx_pmu_off(struct generic_pm_domain *genpd)
-+{
-+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
-+ struct jh71xx_pmu_dev, genpd);
-+ u32 pwr_mask = BIT(pmd->domain_info->bit);
-+
-+ return jh71xx_pmu_set_state(pmd, pwr_mask, false);
-+}
-+
-+static void jh71xx_pmu_int_enable(struct jh71xx_pmu *pmu, u32 mask, bool enable)
-+{
-+ u32 val;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&pmu->lock, flags);
-+ val = readl(pmu->base + JH71XX_PMU_TIMER_INT_MASK);
-+
-+ if (enable)
-+ val &= ~mask;
-+ else
-+ val |= mask;
-+
-+ writel(val, pmu->base + JH71XX_PMU_TIMER_INT_MASK);
-+ spin_unlock_irqrestore(&pmu->lock, flags);
-+}
-+
-+static irqreturn_t jh71xx_pmu_interrupt(int irq, void *data)
-+{
-+ struct jh71xx_pmu *pmu = data;
-+ u32 val;
-+
-+ val = readl(pmu->base + JH71XX_PMU_INT_STATUS);
-+
-+ if (val & JH71XX_PMU_INT_SEQ_DONE)
-+ dev_dbg(pmu->dev, "sequence done.\n");
-+ if (val & JH71XX_PMU_INT_HW_REQ)
-+ dev_dbg(pmu->dev, "hardware encourage requestion.\n");
-+ if (val & JH71XX_PMU_INT_SW_FAIL)
-+ dev_err(pmu->dev, "software encourage fail.\n");
-+ if (val & JH71XX_PMU_INT_HW_FAIL)
-+ dev_err(pmu->dev, "hardware encourage fail.\n");
-+ if (val & JH71XX_PMU_INT_PCH_FAIL)
-+ dev_err(pmu->dev, "p-channel fail event.\n");
-+
-+ /* clear interrupts */
-+ writel(val, pmu->base + JH71XX_PMU_INT_STATUS);
-+ writel(val, pmu->base + JH71XX_PMU_EVENT_STATUS);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
-+{
-+ struct jh71xx_pmu_dev *pmd;
-+ u32 pwr_mask;
-+ int ret;
-+ bool is_on = false;
-+
-+ pmd = devm_kzalloc(pmu->dev, sizeof(*pmd), GFP_KERNEL);
-+ if (!pmd)
-+ return -ENOMEM;
-+
-+ pmd->domain_info = &pmu->match_data->domain_info[index];
-+ pmd->pmu = pmu;
-+ pwr_mask = BIT(pmd->domain_info->bit);
-+
-+ pmd->genpd.name = pmd->domain_info->name;
-+ pmd->genpd.flags = pmd->domain_info->flags;
-+
-+ ret = jh71xx_pmu_get_state(pmd, pwr_mask, &is_on);
-+ if (ret)
-+ dev_warn(pmu->dev, "unable to get current state for %s\n",
-+ pmd->genpd.name);
-+
-+ pmd->genpd.power_on = jh71xx_pmu_on;
-+ pmd->genpd.power_off = jh71xx_pmu_off;
-+ pm_genpd_init(&pmd->genpd, NULL, !is_on);
-+
-+ pmu->genpd_data.domains[index] = &pmd->genpd;
-+
-+ return 0;
-+}
-+
-+static int jh71xx_pmu_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ const struct jh71xx_pmu_match_data *match_data;
-+ struct jh71xx_pmu *pmu;
-+ unsigned int i;
-+ int ret;
-+
-+ pmu = devm_kzalloc(dev, sizeof(*pmu), GFP_KERNEL);
-+ if (!pmu)
-+ return -ENOMEM;
-+
-+ pmu->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(pmu->base))
-+ return PTR_ERR(pmu->base);
-+
-+ pmu->irq = platform_get_irq(pdev, 0);
-+ if (pmu->irq < 0)
-+ return pmu->irq;
-+
-+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
-+ 0, pdev->name, pmu);
-+ if (ret)
-+ dev_err(dev, "failed to request irq\n");
-+
-+ match_data = of_device_get_match_data(dev);
-+ if (!match_data)
-+ return -EINVAL;
-+
-+ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
-+ sizeof(struct generic_pm_domain *),
-+ GFP_KERNEL);
-+ if (!pmu->genpd)
-+ return -ENOMEM;
-+
-+ pmu->dev = dev;
-+ pmu->match_data = match_data;
-+ pmu->genpd_data.domains = pmu->genpd;
-+ pmu->genpd_data.num_domains = match_data->num_domains;
-+
-+ for (i = 0; i < match_data->num_domains; i++) {
-+ ret = jh71xx_pmu_init_domain(pmu, i);
-+ if (ret) {
-+ dev_err(dev, "failed to initialize power domain\n");
-+ return ret;
-+ }
-+ }
-+
-+ spin_lock_init(&pmu->lock);
-+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
-+
-+ ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
-+ if (ret) {
-+ dev_err(dev, "failed to register genpd driver: %d\n", ret);
-+ return ret;
-+ }
-+
-+ dev_dbg(dev, "registered %u power domains\n", i);
-+
-+ return 0;
-+}
-+
-+static const struct jh71xx_domain_info jh7110_power_domains[] = {
-+ [JH7110_PD_SYSTOP] = {
-+ .name = "SYSTOP",
-+ .bit = 0,
-+ .flags = GENPD_FLAG_ALWAYS_ON,
-+ },
-+ [JH7110_PD_CPU] = {
-+ .name = "CPU",
-+ .bit = 1,
-+ .flags = GENPD_FLAG_ALWAYS_ON,
-+ },
-+ [JH7110_PD_GPUA] = {
-+ .name = "GPUA",
-+ .bit = 2,
-+ },
-+ [JH7110_PD_VDEC] = {
-+ .name = "VDEC",
-+ .bit = 3,
-+ },
-+ [JH7110_PD_VOUT] = {
-+ .name = "VOUT",
-+ .bit = 4,
-+ },
-+ [JH7110_PD_ISP] = {
-+ .name = "ISP",
-+ .bit = 5,
-+ },
-+ [JH7110_PD_VENC] = {
-+ .name = "VENC",
-+ .bit = 6,
-+ },
-+};
-+
-+static const struct jh71xx_pmu_match_data jh7110_pmu = {
-+ .num_domains = ARRAY_SIZE(jh7110_power_domains),
-+ .domain_info = jh7110_power_domains,
-+};
-+
-+static const struct of_device_id jh71xx_pmu_of_match[] = {
-+ {
-+ .compatible = "starfive,jh7110-pmu",
-+ .data = (void *)&jh7110_pmu,
-+ }, {
-+ /* sentinel */
-+ }
-+};
-+
-+static struct platform_driver jh71xx_pmu_driver = {
-+ .probe = jh71xx_pmu_probe,
-+ .driver = {
-+ .name = "jh71xx-pmu",
-+ .of_match_table = jh71xx_pmu_of_match,
-+ .suppress_bind_attrs = true,
-+ },
-+};
-+builtin_platform_driver(jh71xx_pmu_driver);
-+
-+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch b/target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch
deleted file mode 100644
index 75b1d947b0..0000000000
--- a/target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 27d38dda7527414eb84ef471425e96c9d2566b38 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 6 Apr 2023 15:46:13 +0800
-Subject: [PATCH 037/122] dt-bindings: soc: starfive: Add StarFive syscon
- module
-
-Add documentation to describe StarFive System Controller Registers.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- .../soc/starfive/starfive,jh7110-syscon.yaml | 58 +++++++++++++++++++
- MAINTAINERS | 6 ++
- 2 files changed, 64 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
-@@ -0,0 +1,58 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/soc/starfive/starfive,jh7110-syscon.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 SoC system controller
-+
-+maintainers:
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+description: |
-+ The StarFive JH7110 SoC system controller provides register information such
-+ as offset, mask and shift to configure related modules such as MMC and PCIe.
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - items:
-+ - enum:
-+ - starfive,jh7110-aon-syscon
-+ - starfive,jh7110-sys-syscon
-+ - const: syscon
-+ - const: simple-mfd
-+ - items:
-+ - const: starfive,jh7110-stg-syscon
-+ - const: syscon
-+
-+ reg:
-+ maxItems: 1
-+
-+ clock-controller:
-+ $ref: /schemas/clock/starfive,jh7110-pll.yaml#
-+ type: object
-+
-+ power-controller:
-+ $ref: /schemas/power/starfive,jh7110-pmu.yaml#
-+ type: object
-+
-+required:
-+ - compatible
-+ - reg
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ syscon@10240000 {
-+ compatible = "starfive,jh7110-stg-syscon", "syscon";
-+ reg = <0x10240000 0x1000>;
-+ };
-+
-+ syscon@13030000 {
-+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
-+ reg = <0x13030000 0x1000>;
-+ };
-+
-+...
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19663,6 +19663,11 @@ S: Supported
- F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
- F: drivers/clk/starfive/clk-starfive-jh7110-pll.*
-
-+STARFIVE JH7110 SYSCON
-+M: William Qiu <william.qiu@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
-+
- STARFIVE JH71X0 CLOCK DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
- M: Hal Feng <hal.feng@starfivetech.com>
-@@ -19693,6 +19698,7 @@ STARFIVE SOC DRIVER
- M: Conor Dooley <conor@kernel.org>
- S: Maintained
- T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
-+F: Documentation/devicetree/bindings/soc/starfive/
- F: drivers/soc/starfive/
- F: include/soc/starfive/
-
diff --git a/target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch b/target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch
deleted file mode 100644
index ad748151c7..0000000000
--- a/target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 40098f3d986dc90f6a7be0e5a35ddaccd1ded0b5 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 6 Apr 2023 15:46:34 +0800
-Subject: [PATCH 038/122] riscv: dts: starfive: jh7110: Add syscon nodes
-
-Add stg_syscon/sys_syscon/aon_syscon nodes for JH7110 Soc.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -353,6 +353,11 @@
- status = "disabled";
- };
-
-+ stg_syscon: syscon@10240000 {
-+ compatible = "starfive,jh7110-stg-syscon", "syscon";
-+ reg = <0x0 0x10240000 0x0 0x1000>;
-+ };
-+
- uart3: serial@12000000 {
- compatible = "snps,dw-apb-uart";
- reg = <0x0 0x12000000 0x0 0x10000>;
-@@ -457,6 +462,11 @@
- #reset-cells = <1>;
- };
-
-+ sys_syscon: syscon@13030000 {
-+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
-+ reg = <0x0 0x13030000 0x0 0x1000>;
-+ };
-+
- sysgpio: pinctrl@13040000 {
- compatible = "starfive,jh7110-sys-pinctrl";
- reg = <0x0 0x13040000 0x0 0x10000>;
-@@ -486,6 +496,11 @@
- #reset-cells = <1>;
- };
-
-+ aon_syscon: syscon@17010000 {
-+ compatible = "starfive,jh7110-aon-syscon", "syscon", "simple-mfd";
-+ reg = <0x0 0x17010000 0x0 0x1000>;
-+ };
-+
- aongpio: pinctrl@17020000 {
- compatible = "starfive,jh7110-aon-pinctrl";
- reg = <0x0 0x17020000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch b/target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch
deleted file mode 100644
index c771512bd3..0000000000
--- a/target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f0548ab9212ef35abe79f46e5f509f4fc9d78699 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 20 Feb 2023 14:33:33 +0800
-Subject: [PATCH 039/122] riscv: dts: starfive: jh7110: Add PLL clock node and
- modify syscrg node
-
-Add the PLL clock node for the Starfive JH7110 SoC and
-modify the SYSCRG node to add PLL clocks input.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -452,12 +452,16 @@
- <&gmac1_rgmii_rxin>,
- <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
- <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-- <&tdm_ext>, <&mclk_ext>;
-+ <&tdm_ext>, <&mclk_ext>,
-+ <&pllclk JH7110_CLK_PLL0_OUT>,
-+ <&pllclk JH7110_CLK_PLL1_OUT>,
-+ <&pllclk JH7110_CLK_PLL2_OUT>;
- clock-names = "osc", "gmac1_rmii_refin",
- "gmac1_rgmii_rxin",
- "i2stx_bclk_ext", "i2stx_lrck_ext",
- "i2srx_bclk_ext", "i2srx_lrck_ext",
-- "tdm_ext", "mclk_ext";
-+ "tdm_ext", "mclk_ext",
-+ "pll0_out", "pll1_out", "pll2_out";
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
-@@ -465,6 +469,12 @@
- sys_syscon: syscon@13030000 {
- compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
- reg = <0x0 0x13030000 0x0 0x1000>;
-+
-+ pllclk: clock-controller {
-+ compatible = "starfive,jh7110-pll";
-+ clocks = <&osc>;
-+ #clock-cells = <1>;
-+ };
- };
-
- sysgpio: pinctrl@13040000 {
diff --git a/target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch b/target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch
deleted file mode 100644
index 139cd8445b..0000000000
--- a/target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 5866a8486a261decacd19769556d1b79b5d1269d Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Mon, 8 Aug 2022 17:13:34 +0200
-Subject: [PATCH 040/122] dt-bindings: net: snps,dwmac: Add dwmac-5.20 version
-
-Add dwmac-5.20 IP version to snps.dwmac.yaml
-
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- Documentation/devicetree/bindings/net/snps,dwmac.yaml | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-@@ -30,6 +30,7 @@ select:
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
- - snps,dwmac-5.10a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
-
-@@ -87,6 +88,7 @@ properties:
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
- - snps,dwmac-5.10a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
-
-@@ -393,6 +395,7 @@ allOf:
- - snps,dwmac-3.50a
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
- - st,spear600-gmac
-@@ -447,6 +450,7 @@ allOf:
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
- - snps,dwmac-5.10a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
- - st,spear600-gmac
diff --git a/target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch b/target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch
deleted file mode 100644
index 077f161dcd..0000000000
--- a/target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From cb00f835fc9f3ece473e7081f17c8613bf08a8ef Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sun, 7 Aug 2022 22:26:00 +0200
-Subject: [PATCH 041/122] net: stmmac: platform: Add snps,dwmac-5.20 IP
- compatible string
-
-Add "snps,dwmac-5.20" compatible string for 5.20 version that can avoid
-to define some platform data in the glue layer.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-@@ -519,7 +519,8 @@ stmmac_probe_config_dt(struct platform_d
- if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
- of_device_is_compatible(np, "snps,dwmac-4.10a") ||
- of_device_is_compatible(np, "snps,dwmac-4.20a") ||
-- of_device_is_compatible(np, "snps,dwmac-5.10a")) {
-+ of_device_is_compatible(np, "snps,dwmac-5.10a") ||
-+ of_device_is_compatible(np, "snps,dwmac-5.20")) {
- plat->has_gmac4 = 1;
- plat->has_gmac = 0;
- plat->pmt = 1;
diff --git a/target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch b/target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch
deleted file mode 100644
index 5b73752fd6..0000000000
--- a/target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 3b0609e57e031a3b680131b3fc25bc1165e3360f Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Mon, 27 Feb 2023 18:26:04 +0800
-Subject: [PATCH 042/122] dt-bindings: net: snps,dwmac: Add 'ahb'
- reset/reset-name
-
-According to:
-stmmac_platform.c: stmmac_probe_config_dt
-stmmac_main.c: stmmac_dvr_probe
-
-dwmac controller may require one (stmmaceth) or two (stmmaceth+ahb)
-reset signals, and the maxItems of resets/reset-names is going to be 2.
-
-The gmac of Starfive Jh7110 SOC must have two resets.
-it uses snps,dwmac-5.20 IP.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../devicetree/bindings/net/snps,dwmac.yaml | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
---- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-@@ -133,12 +133,16 @@ properties:
- - ptp_ref
-
- resets:
-- maxItems: 1
-- description:
-- MAC Reset signal.
-+ minItems: 1
-+ items:
-+ - description: GMAC stmmaceth reset
-+ - description: AHB reset
-
- reset-names:
-- const: stmmaceth
-+ minItems: 1
-+ items:
-+ - const: stmmaceth
-+ - const: ahb
-
- power-domains:
- maxItems: 1
diff --git a/target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch b/target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch
deleted file mode 100644
index a66452c382..0000000000
--- a/target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-From 6bef17fa124f20723724e2a9a1d890fd1a9d5eaa Mon Sep 17 00:00:00 2001
-From: Yanhong Wang <yanhong.wang@starfivetech.com>
-Date: Mon, 31 Oct 2022 18:08:15 +0800
-Subject: [PATCH 043/122] dt-bindings: net: Add support StarFive dwmac
-
-Add documentation to describe StarFive dwmac driver(GMAC).
-
-Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../devicetree/bindings/net/snps,dwmac.yaml | 1 +
- .../bindings/net/starfive,jh7110-dwmac.yaml | 144 ++++++++++++++++++
- MAINTAINERS | 6 +
- 3 files changed, 151 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-
---- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-@@ -91,6 +91,7 @@ properties:
- - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
-+ - starfive,jh7110-dwmac
-
- reg:
- minItems: 1
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-@@ -0,0 +1,144 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+# Copyright (C) 2022 StarFive Technology Co., Ltd.
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/starfive,jh7110-dwmac.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 DWMAC glue layer
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+ - Samin Guo <samin.guo@starfivetech.com>
-+
-+select:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - starfive,jh7110-dwmac
-+ required:
-+ - compatible
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
-+ - starfive,jh7110-dwmac
-+ - const: snps,dwmac-5.20
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: GMAC main clock
-+ - description: GMAC AHB clock
-+ - description: PTP clock
-+ - description: TX clock
-+ - description: GTX clock
-+
-+ clock-names:
-+ items:
-+ - const: stmmaceth
-+ - const: pclk
-+ - const: ptp_ref
-+ - const: tx
-+ - const: gtx
-+
-+ interrupts:
-+ minItems: 3
-+ maxItems: 3
-+
-+ interrupt-names:
-+ minItems: 3
-+ maxItems: 3
-+
-+ resets:
-+ items:
-+ - description: MAC Reset signal.
-+ - description: AHB Reset signal.
-+
-+ reset-names:
-+ items:
-+ - const: stmmaceth
-+ - const: ahb
-+
-+ starfive,tx-use-rgmii-clk:
-+ description:
-+ Tx clock is provided by external rgmii clock.
-+ type: boolean
-+
-+ starfive,syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to syscon that configures phy mode
-+ - description: Offset of phy mode selection
-+ - description: Shift of phy mode selection
-+ description:
-+ A phandle to syscon with two arguments that configure phy mode.
-+ The argument one is the offset of phy mode selection, the
-+ argument two is the shift of phy mode selection.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - interrupts
-+ - interrupt-names
-+ - resets
-+ - reset-names
-+
-+allOf:
-+ - $ref: snps,dwmac.yaml#
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ ethernet@16030000 {
-+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
-+ reg = <0x16030000 0x10000>;
-+ clocks = <&clk 3>, <&clk 2>, <&clk 109>,
-+ <&clk 6>, <&clk 111>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref",
-+ "tx", "gtx";
-+ resets = <&rst 1>, <&rst 2>;
-+ reset-names = "stmmaceth", "ahb";
-+ interrupts = <7>, <6>, <5>;
-+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-+ phy-mode = "rgmii-id";
-+ snps,multicast-filter-bins = <64>;
-+ snps,perfect-filter-entries = <8>;
-+ rx-fifo-depth = <2048>;
-+ tx-fifo-depth = <2048>;
-+ snps,fixed-burst;
-+ snps,no-pbl-x8;
-+ snps,tso;
-+ snps,force_thresh_dma_mode;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,en-tx-lpi-clockgating;
-+ snps,txpbl = <16>;
-+ snps,rxpbl = <16>;
-+ starfive,syscon = <&aon_syscon 0xc 0x12>;
-+ phy-handle = <&phy0>;
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+
-+ phy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+
-+ stmmac_axi_setup: stmmac-axi-config {
-+ snps,lpi_en;
-+ snps,wr_osr_lmt = <4>;
-+ snps,rd_osr_lmt = <4>;
-+ snps,blen = <256 128 64 32 0 0 0>;
-+ };
-+ };
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19657,6 +19657,12 @@ M: Emil Renner Berthing <kernel@esmil.dk
- S: Maintained
- F: arch/riscv/boot/dts/starfive/
-
-+STARFIVE DWMAC GLUE LAYER
-+M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Samin Guo <samin.guo@starfivetech.com>
-+S: Maintained
-+F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-+
- STARFIVE JH7110 PLL CLOCK DRIVER
- M: Xingyu Wu <xingyu.wu@starfivetech.com>
- S: Supported
diff --git a/target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch b/target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch
deleted file mode 100644
index 59609809c1..0000000000
--- a/target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From 7c82049adb0460985dd6a1e5c9b6954d901247d2 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Fri, 3 Mar 2023 16:50:58 +0800
-Subject: [PATCH 044/122] net: stmmac: Add glue layer for StarFive JH7110 SoC
-
-This adds StarFive dwmac driver support on the StarFive JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- MAINTAINERS | 1 +
- drivers/net/ethernet/stmicro/stmmac/Kconfig | 12 ++
- drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
- .../ethernet/stmicro/stmmac/dwmac-starfive.c | 123 ++++++++++++++++++
- 4 files changed, 137 insertions(+)
- create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19662,6 +19662,7 @@ M: Emil Renner Berthing <kernel@esmil.dk
- M: Samin Guo <samin.guo@starfivetech.com>
- S: Maintained
- F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-+F: drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-
- STARFIVE JH7110 PLL CLOCK DRIVER
- M: Xingyu Wu <xingyu.wu@starfivetech.com>
---- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
-+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
-@@ -165,6 +165,18 @@ config DWMAC_SOCFPGA
- for the stmmac device driver. This driver is used for
- arria5 and cyclone5 FPGA SoCs.
-
-+config DWMAC_STARFIVE
-+ tristate "StarFive dwmac support"
-+ depends on OF && (ARCH_STARFIVE || COMPILE_TEST)
-+ select MFD_SYSCON
-+ default m if ARCH_STARFIVE
-+ help
-+ Support for ethernet controllers on StarFive RISC-V SoCs
-+
-+ This selects the StarFive platform specific glue layer support for
-+ the stmmac device driver. This driver is used for StarFive JH7110
-+ ethernet controller.
-+
- config DWMAC_STI
- tristate "STi GMAC support"
- default ARCH_STI
---- a/drivers/net/ethernet/stmicro/stmmac/Makefile
-+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
-@@ -23,6 +23,7 @@ obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas
- obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
- obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
- obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
-+obj-$(CONFIG_DWMAC_STARFIVE) += dwmac-starfive.o
- obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
- obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
- obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-@@ -0,0 +1,123 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * StarFive DWMAC platform driver
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ *
-+ */
-+
-+#include <linux/mfd/syscon.h>
-+#include <linux/of_device.h>
-+#include <linux/regmap.h>
-+
-+#include "stmmac_platform.h"
-+
-+struct starfive_dwmac {
-+ struct device *dev;
-+ struct clk *clk_tx;
-+};
-+
-+static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed)
-+{
-+ struct starfive_dwmac *dwmac = priv;
-+ unsigned long rate;
-+ int err;
-+
-+ rate = clk_get_rate(dwmac->clk_tx);
-+
-+ switch (speed) {
-+ case SPEED_1000:
-+ rate = 125000000;
-+ break;
-+ case SPEED_100:
-+ rate = 25000000;
-+ break;
-+ case SPEED_10:
-+ rate = 2500000;
-+ break;
-+ default:
-+ dev_err(dwmac->dev, "invalid speed %u\n", speed);
-+ break;
-+ }
-+
-+ err = clk_set_rate(dwmac->clk_tx, rate);
-+ if (err)
-+ dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
-+}
-+
-+static int starfive_dwmac_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ struct starfive_dwmac *dwmac;
-+ struct clk *clk_gtx;
-+ int err;
-+
-+ err = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (err)
-+ return dev_err_probe(&pdev->dev, err,
-+ "failed to get resources\n");
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
-+ "dt configuration failed\n");
-+
-+ dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-+ if (!dwmac)
-+ return -ENOMEM;
-+
-+ dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
-+ if (IS_ERR(dwmac->clk_tx))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
-+ "error getting tx clock\n");
-+
-+ clk_gtx = devm_clk_get_enabled(&pdev->dev, "gtx");
-+ if (IS_ERR(clk_gtx))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(clk_gtx),
-+ "error getting gtx clock\n");
-+
-+ /* Generally, the rgmii_tx clock is provided by the internal clock,
-+ * which needs to match the corresponding clock frequency according
-+ * to different speeds. If the rgmii_tx clock is provided by the
-+ * external rgmii_rxin, there is no need to configure the clock
-+ * internally, because rgmii_rxin will be adaptively adjusted.
-+ */
-+ if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
-+ plat_dat->fix_mac_speed = starfive_dwmac_fix_mac_speed;
-+
-+ dwmac->dev = &pdev->dev;
-+ plat_dat->bsp_priv = dwmac;
-+ plat_dat->dma_cfg->dche = true;
-+
-+ err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+ if (err) {
-+ stmmac_remove_config_dt(pdev, plat_dat);
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id starfive_dwmac_match[] = {
-+ { .compatible = "starfive,jh7110-dwmac" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_dwmac_match);
-+
-+static struct platform_driver starfive_dwmac_driver = {
-+ .probe = starfive_dwmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "starfive-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = starfive_dwmac_match,
-+ },
-+};
-+module_platform_driver(starfive_dwmac_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("StarFive DWMAC platform driver");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
diff --git a/target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch b/target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch
deleted file mode 100644
index a532c0e4dd..0000000000
--- a/target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 20886cd583e8d569d78ea0e723f98384a61ab54b Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Thu, 2 Mar 2023 19:52:37 +0800
-Subject: [PATCH 045/122] net: stmmac: dwmac-starfive: Add phy interface
- settings
-
-dwmac supports multiple modess. When working under rmii and rgmii,
-you need to set different phy interfaces.
-
-According to the dwmac document, when working in rmii, it needs to be
-set to 0x4, and rgmii needs to be set to 0x1.
-
-The phy interface needs to be set in syscon, the format is as follows:
-starfive,syscon: <&syscon, offset, shift>
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../ethernet/stmicro/stmmac/dwmac-starfive.c | 48 +++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-@@ -13,6 +13,10 @@
-
- #include "stmmac_platform.h"
-
-+#define STARFIVE_DWMAC_PHY_INFT_RGMII 0x1
-+#define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
-+#define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
-+
- struct starfive_dwmac {
- struct device *dev;
- struct clk *clk_tx;
-@@ -46,6 +50,46 @@ static void starfive_dwmac_fix_mac_speed
- dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
- }
-
-+static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
-+{
-+ struct starfive_dwmac *dwmac = plat_dat->bsp_priv;
-+ struct regmap *regmap;
-+ unsigned int args[2];
-+ unsigned int mode;
-+ int err;
-+
-+ switch (plat_dat->interface) {
-+ case PHY_INTERFACE_MODE_RMII:
-+ mode = STARFIVE_DWMAC_PHY_INFT_RMII;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
-+ break;
-+
-+ default:
-+ dev_err(dwmac->dev, "unsupported interface %d\n",
-+ plat_dat->interface);
-+ return -EINVAL;
-+ }
-+
-+ regmap = syscon_regmap_lookup_by_phandle_args(dwmac->dev->of_node,
-+ "starfive,syscon",
-+ 2, args);
-+ if (IS_ERR(regmap))
-+ return dev_err_probe(dwmac->dev, PTR_ERR(regmap), "getting the regmap failed\n");
-+
-+ /* args[0]:offset args[1]: shift */
-+ err = regmap_update_bits(regmap, args[0],
-+ STARFIVE_DWMAC_PHY_INFT_FIELD << args[1],
-+ mode << args[1]);
-+ if (err)
-+ return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");
-+
-+ return 0;
-+}
-+
- static int starfive_dwmac_probe(struct platform_device *pdev)
- {
- struct plat_stmmacenet_data *plat_dat;
-@@ -91,6 +135,10 @@ static int starfive_dwmac_probe(struct p
- plat_dat->bsp_priv = dwmac;
- plat_dat->dma_cfg->dche = true;
-
-+ err = starfive_dwmac_set_mode(plat_dat);
-+ if (err)
-+ return err;
-+
- err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- if (err) {
- stmmac_remove_config_dt(pdev, plat_dat);
diff --git a/target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch b/target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch
deleted file mode 100644
index 50ad56f568..0000000000
--- a/target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From cad740398f4cb6604abf1ddcc70121b2634ac233 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Fri, 3 Mar 2023 16:49:31 +0800
-Subject: [PATCH 046/122] riscv: dts: starfive: jh7110: Add ethernet device
- nodes
-
-Add JH7110 ethernet device node to support gmac driver for the JH7110
-RISC-V SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 69 ++++++++++++++++++++++++
- 1 file changed, 69 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -230,6 +230,13 @@
- #clock-cells = <0>;
- };
-
-+ stmmac_axi_setup: stmmac-axi-config {
-+ snps,lpi_en;
-+ snps,wr_osr_lmt = <4>;
-+ snps,rd_osr_lmt = <4>;
-+ snps,blen = <256 128 64 32 0 0 0>;
-+ };
-+
- tdm_ext: tdm-ext-clock {
- compatible = "fixed-clock";
- clock-output-names = "tdm_ext";
-@@ -489,6 +496,68 @@
- #gpio-cells = <2>;
- };
-
-+ gmac0: ethernet@16030000 {
-+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
-+ reg = <0x0 0x16030000 0x0 0x10000>;
-+ clocks = <&aoncrg JH7110_AONCLK_GMAC0_AXI>,
-+ <&aoncrg JH7110_AONCLK_GMAC0_AHB>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_PTP>,
-+ <&aoncrg JH7110_AONCLK_GMAC0_TX_INV>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_GTXC>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref",
-+ "tx", "gtx";
-+ resets = <&aoncrg JH7110_AONRST_GMAC0_AXI>,
-+ <&aoncrg JH7110_AONRST_GMAC0_AHB>;
-+ reset-names = "stmmaceth", "ahb";
-+ interrupts = <7>, <6>, <5>;
-+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-+ rx-fifo-depth = <2048>;
-+ tx-fifo-depth = <2048>;
-+ snps,multicast-filter-bins = <64>;
-+ snps,perfect-filter-entries = <8>;
-+ snps,fixed-burst;
-+ snps,no-pbl-x8;
-+ snps,force_thresh_dma_mode;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,tso;
-+ snps,en-tx-lpi-clockgating;
-+ snps,txpbl = <16>;
-+ snps,rxpbl = <16>;
-+ starfive,syscon = <&aon_syscon 0xc 0x12>;
-+ status = "disabled";
-+ };
-+
-+ gmac1: ethernet@16040000 {
-+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
-+ reg = <0x0 0x16040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_GMAC1_AXI>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_AHB>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_PTP>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_TX_INV>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_GTXC>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref",
-+ "tx", "gtx";
-+ resets = <&syscrg JH7110_SYSRST_GMAC1_AXI>,
-+ <&syscrg JH7110_SYSRST_GMAC1_AHB>;
-+ reset-names = "stmmaceth", "ahb";
-+ interrupts = <78>, <77>, <76>;
-+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-+ rx-fifo-depth = <2048>;
-+ tx-fifo-depth = <2048>;
-+ snps,multicast-filter-bins = <64>;
-+ snps,perfect-filter-entries = <8>;
-+ snps,fixed-burst;
-+ snps,no-pbl-x8;
-+ snps,force_thresh_dma_mode;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,tso;
-+ snps,en-tx-lpi-clockgating;
-+ snps,txpbl = <16>;
-+ snps,rxpbl = <16>;
-+ starfive,syscon = <&sys_syscon 0x90 0x2>;
-+ status = "disabled";
-+ };
-+
- aoncrg: clock-controller@17000000 {
- compatible = "starfive,jh7110-aoncrg";
- reg = <0x0 0x17000000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch b/target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch
deleted file mode 100644
index 9fbdebf5f4..0000000000
--- a/target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 6fd84cb9cceaa711671500a92dcee5b1072ab95a Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Tue, 1 Nov 2022 18:11:02 +0800
-Subject: [PATCH 047/122] riscv: dts: starfive: visionfive 2: Add configuration
- of gmac and phy
-
-v1.3B:
- v1.3B uses motorcomm YT8531(rgmii-id phy) x2, need delay and
- inverse configurations.
- The tx_clk of v1.3B uses an external clock and needs to be
- switched to an external clock source.
-
-v1.2A:
- v1.2A gmac0 uses motorcomm YT8531(rgmii-id) PHY, and needs delay
- configurations.
- v1.2A gmac1 uses motorcomm YT8512(rmii) PHY, and needs to
- switch rx and rx to external clock sources.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../jh7110-starfive-visionfive-2-v1.2a.dts | 13 +++++++
- .../jh7110-starfive-visionfive-2-v1.3b.dts | 27 +++++++++++++++
- .../jh7110-starfive-visionfive-2.dtsi | 34 +++++++++++++++++++
- 3 files changed, 74 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
-@@ -11,3 +11,16 @@
- model = "StarFive VisionFive 2 v1.2A";
- compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
- };
-+
-+&gmac1 {
-+ phy-mode = "rmii";
-+ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_RX>;
-+ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
-+};
-+
-+&phy0 {
-+ rx-internal-delay-ps = <1900>;
-+ tx-internal-delay-ps = <1350>;
-+};
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -11,3 +11,30 @@
- model = "StarFive VisionFive 2 v1.3B";
- compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
- };
-+
-+&gmac0 {
-+ starfive,tx-use-rgmii-clk;
-+ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
-+ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
-+};
-+
-+&gmac1 {
-+ starfive,tx-use-rgmii-clk;
-+ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>;
-+ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
-+};
-+
-+&phy0 {
-+ motorcomm,tx-clk-adj-enabled;
-+ motorcomm,tx-clk-100-inverted;
-+ motorcomm,tx-clk-1000-inverted;
-+ rx-internal-delay-ps = <1500>;
-+ tx-internal-delay-ps = <1500>;
-+};
-+
-+&phy1 {
-+ motorcomm,tx-clk-adj-enabled;
-+ motorcomm,tx-clk-100-inverted;
-+ rx-internal-delay-ps = <300>;
-+ tx-internal-delay-ps = <0>;
-+};
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -11,6 +11,8 @@
-
- / {
- aliases {
-+ ethernet0 = &gmac0;
-+ ethernet1 = &gmac1;
- i2c0 = &i2c0;
- i2c2 = &i2c2;
- i2c5 = &i2c5;
-@@ -86,6 +88,38 @@
- clock-frequency = <49152000>;
- };
-
-+&gmac0 {
-+ phy-handle = <&phy0>;
-+ phy-mode = "rgmii-id";
-+ status = "okay";
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+
-+ phy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
-+
-+&gmac1 {
-+ phy-handle = <&phy1>;
-+ phy-mode = "rgmii-id";
-+ status = "okay";
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+
-+ phy1: ethernet-phy@1 {
-+ reg = <0>;
-+ };
-+ };
-+};
-+
- &i2c0 {
- clock-frequency = <100000>;
- i2c-sda-hold-time-ns = <300>;
diff --git a/target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch b/target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch
deleted file mode 100644
index 376481ee0f..0000000000
--- a/target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From 96edc2f71ea7ac6683011609f6d1f51ae9ea0b7a Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:33 +0800
-Subject: [PATCH 048/122] dt-bindings: net: Add Motorcomm yt8xxx ethernet phy
-
-Add a YAML binding document for the Motorcomm yt8xxx Ethernet phy.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../bindings/net/motorcomm,yt8xxx.yaml | 117 ++++++++++++++++++
- .../devicetree/bindings/vendor-prefixes.yaml | 2 +
- 2 files changed, 119 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-@@ -0,0 +1,117 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/motorcomm,yt8xxx.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MotorComm yt8xxx Ethernet PHY
-+
-+maintainers:
-+ - Frank Sae <frank.sae@motor-comm.com>
-+
-+allOf:
-+ - $ref: ethernet-phy.yaml#
-+
-+properties:
-+ compatible:
-+ enum:
-+ - ethernet-phy-id4f51.e91a
-+ - ethernet-phy-id4f51.e91b
-+
-+ rx-internal-delay-ps:
-+ description: |
-+ RGMII RX Clock Delay used only when PHY operates in RGMII mode with
-+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
-+ enum: [ 0, 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500, 1650,
-+ 1800, 1900, 1950, 2050, 2100, 2200, 2250, 2350, 2500, 2650, 2800,
-+ 2950, 3100, 3250, 3400, 3550, 3700, 3850, 4000, 4150 ]
-+ default: 1950
-+
-+ tx-internal-delay-ps:
-+ description: |
-+ RGMII TX Clock Delay used only when PHY operates in RGMII mode with
-+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
-+ enum: [ 0, 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500, 1650, 1800,
-+ 1950, 2100, 2250 ]
-+ default: 1950
-+
-+ motorcomm,clk-out-frequency-hz:
-+ description: clock output on clock output pin.
-+ enum: [0, 25000000, 125000000]
-+ default: 0
-+
-+ motorcomm,keep-pll-enabled:
-+ description: |
-+ If set, keep the PLL enabled even if there is no link. Useful if you
-+ want to use the clock output without an ethernet link.
-+ type: boolean
-+
-+ motorcomm,auto-sleep-disabled:
-+ description: |
-+ If set, PHY will not enter sleep mode and close AFE after unplug cable
-+ for a timer.
-+ type: boolean
-+
-+ motorcomm,tx-clk-adj-enabled:
-+ description: |
-+ This configuration is mainly to adapt to VF2 with JH7110 SoC.
-+ Useful if you want to use tx-clk-xxxx-inverted to adj the delay of tx clk.
-+ type: boolean
-+
-+ motorcomm,tx-clk-10-inverted:
-+ description: |
-+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
-+ Transmit PHY Clock delay train configuration when speed is 10Mbps.
-+ type: boolean
-+
-+ motorcomm,tx-clk-100-inverted:
-+ description: |
-+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
-+ Transmit PHY Clock delay train configuration when speed is 100Mbps.
-+ type: boolean
-+
-+ motorcomm,tx-clk-1000-inverted:
-+ description: |
-+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
-+ Transmit PHY Clock delay train configuration when speed is 1000Mbps.
-+ type: boolean
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ phy-mode = "rgmii-id";
-+ ethernet-phy@4 {
-+ /* Only needed to make DT lint tools work. Do not copy/paste
-+ * into real DTS files.
-+ */
-+ compatible = "ethernet-phy-id4f51.e91a";
-+
-+ reg = <4>;
-+ rx-internal-delay-ps = <2100>;
-+ tx-internal-delay-ps = <150>;
-+ motorcomm,clk-out-frequency-hz = <0>;
-+ motorcomm,keep-pll-enabled;
-+ motorcomm,auto-sleep-disabled;
-+ };
-+ };
-+ - |
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ phy-mode = "rgmii";
-+ ethernet-phy@5 {
-+ /* Only needed to make DT lint tools work. Do not copy/paste
-+ * into real DTS files.
-+ */
-+ compatible = "ethernet-phy-id4f51.e91a";
-+
-+ reg = <5>;
-+ motorcomm,clk-out-frequency-hz = <125000000>;
-+ motorcomm,keep-pll-enabled;
-+ motorcomm,auto-sleep-disabled;
-+ };
-+ };
---- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
-+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
-@@ -831,6 +831,8 @@ patternProperties:
- description: Moortec Semiconductor Ltd.
- "^mosaixtech,.*":
- description: Mosaix Technologies, Inc.
-+ "^motorcomm,.*":
-+ description: MotorComm, Inc.
- "^motorola,.*":
- description: Motorola, Inc.
- "^moxa,.*":
diff --git a/target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch b/target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
deleted file mode 100644
index b9e9c65251..0000000000
--- a/target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 2d146c6e550a4fb7f24ca44739cf14594cc2f892 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Tue, 25 Apr 2023 18:51:15 +0800
-Subject: [PATCH 049/122] dt-bindings: net: motorcomm: Add pad driver strength
- cfg
-
-The motorcomm phy (YT8531) supports the ability to adjust the drive
-strength of the rx_clk/rx_data, the value range of pad driver
-strength is 0 to 7.
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../devicetree/bindings/net/motorcomm,yt8xxx.yaml | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-@@ -18,6 +18,16 @@ properties:
- - ethernet-phy-id4f51.e91a
- - ethernet-phy-id4f51.e91b
-
-+ rx-clk-driver-strength:
-+ description: drive strength of rx_clk pad.
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
-+ rx-data-driver-strength:
-+ description: drive strength of rxd/rx_ctl rgmii pad.
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
- rx-internal-delay-ps:
- description: |
- RGMII RX Clock Delay used only when PHY operates in RGMII mode with
diff --git a/target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch b/target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch
deleted file mode 100644
index 8dca72ad16..0000000000
--- a/target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From c156cb9ec64669600c96dbb01bf38dd2370b1850 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Wed, 26 Apr 2023 14:41:12 +0800
-Subject: [PATCH 050/122] riscv: dts: starfive: visionfive-2-v1.3B: Set the
- driver strength of RXC/RXD
-
-VisionFive 2 v1.3B needs to increase the driver strength of rxd/rxc
-to increase the stability of gmac's transmission.
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -28,6 +28,8 @@
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
- motorcomm,tx-clk-1000-inverted;
-+ rx-clk-driver-strength = <0x6>;
-+ rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <1500>;
- tx-internal-delay-ps = <1500>;
- };
-@@ -35,6 +37,8 @@
- &phy1 {
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
-+ rx-clk-driver-strength = <0x6>;
-+ rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <300>;
- tx-internal-delay-ps = <0>;
- };
diff --git a/target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch b/target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch
deleted file mode 100644
index 6617e79965..0000000000
--- a/target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-From 84575863e4cf1a5dd877a11d31115c19004ac36a Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:24 +0800
-Subject: [PATCH 051/122] dt-bindings: clock: Add StarFive JH7110
- System-Top-Group clock and reset generator
-
-Add bindings for the System-Top-Group clock and reset generator (STGCRG)
-on the JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-stgcrg.yaml | 82 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 34 ++++++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 28 +++++++
- 3 files changed, 144 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
-@@ -0,0 +1,82 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-stgcrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 System-Top-Group Clock and Reset Generator
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-stgcrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: HIFI4 core
-+ - description: STG AXI/AHB
-+ - description: USB (125 MHz)
-+ - description: CPU Bus
-+ - description: HIFI4 Axi
-+ - description: NOC STG Bus
-+ - description: APB Bus
-+
-+ clock-names:
-+ items:
-+ - const: osc
-+ - const: hifi4_core
-+ - const: stg_axiahb
-+ - const: usb_125m
-+ - const: cpu_bus
-+ - const: hifi4_axi
-+ - const: nocstg_bus
-+ - const: apb_bus
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+ stgcrg: clock-controller@10230000 {
-+ compatible = "starfive,jh7110-stgcrg";
-+ reg = <0x10230000 0x10000>;
-+ clocks = <&osc>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_USB_125M>,
-+ <&syscrg JH7110_SYSCLK_CPU_BUS>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>;
-+ clock-names = "osc", "hifi4_core",
-+ "stg_axiahb", "usb_125m",
-+ "cpu_bus", "hifi4_axi",
-+ "nocstg_bus", "apb_bus";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -1,6 +1,7 @@
- /* SPDX-License-Identifier: GPL-2.0 OR MIT */
- /*
- * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright 2022 StarFive Technology Co., Ltd.
- */
-
- #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-@@ -224,4 +225,37 @@
-
- #define JH7110_AONCLK_END 14
-
-+/* STGCRG clocks */
-+#define JH7110_STGCLK_HIFI4_CLK_CORE 0
-+#define JH7110_STGCLK_USB0_APB 1
-+#define JH7110_STGCLK_USB0_UTMI_APB 2
-+#define JH7110_STGCLK_USB0_AXI 3
-+#define JH7110_STGCLK_USB0_LPM 4
-+#define JH7110_STGCLK_USB0_STB 5
-+#define JH7110_STGCLK_USB0_APP_125 6
-+#define JH7110_STGCLK_USB0_REFCLK 7
-+#define JH7110_STGCLK_PCIE0_AXI_MST0 8
-+#define JH7110_STGCLK_PCIE0_APB 9
-+#define JH7110_STGCLK_PCIE0_TL 10
-+#define JH7110_STGCLK_PCIE1_AXI_MST0 11
-+#define JH7110_STGCLK_PCIE1_APB 12
-+#define JH7110_STGCLK_PCIE1_TL 13
-+#define JH7110_STGCLK_PCIE_SLV_MAIN 14
-+#define JH7110_STGCLK_SEC_AHB 15
-+#define JH7110_STGCLK_SEC_MISC_AHB 16
-+#define JH7110_STGCLK_GRP0_MAIN 17
-+#define JH7110_STGCLK_GRP0_BUS 18
-+#define JH7110_STGCLK_GRP0_STG 19
-+#define JH7110_STGCLK_GRP1_MAIN 20
-+#define JH7110_STGCLK_GRP1_BUS 21
-+#define JH7110_STGCLK_GRP1_STG 22
-+#define JH7110_STGCLK_GRP1_HIFI 23
-+#define JH7110_STGCLK_E2_RTC 24
-+#define JH7110_STGCLK_E2_CORE 25
-+#define JH7110_STGCLK_E2_DBG 26
-+#define JH7110_STGCLK_DMA1P_AXI 27
-+#define JH7110_STGCLK_DMA1P_AHB 28
-+
-+#define JH7110_STGCLK_END 29
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -1,6 +1,7 @@
- /* SPDX-License-Identifier: GPL-2.0 OR MIT */
- /*
- * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
- */
-
- #ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
-@@ -151,4 +152,31 @@
-
- #define JH7110_AONRST_END 8
-
-+/* STGCRG resets */
-+#define JH7110_STGRST_SYSCON 0
-+#define JH7110_STGRST_HIFI4_CORE 1
-+#define JH7110_STGRST_HIFI4_AXI 2
-+#define JH7110_STGRST_SEC_AHB 3
-+#define JH7110_STGRST_E24_CORE 4
-+#define JH7110_STGRST_DMA1P_AXI 5
-+#define JH7110_STGRST_DMA1P_AHB 6
-+#define JH7110_STGRST_USB0_AXI 7
-+#define JH7110_STGRST_USB0_APB 8
-+#define JH7110_STGRST_USB0_UTMI_APB 9
-+#define JH7110_STGRST_USB0_PWRUP 10
-+#define JH7110_STGRST_PCIE0_AXI_MST0 11
-+#define JH7110_STGRST_PCIE0_AXI_SLV0 12
-+#define JH7110_STGRST_PCIE0_AXI_SLV 13
-+#define JH7110_STGRST_PCIE0_BRG 14
-+#define JH7110_STGRST_PCIE0_CORE 15
-+#define JH7110_STGRST_PCIE0_APB 16
-+#define JH7110_STGRST_PCIE1_AXI_MST0 17
-+#define JH7110_STGRST_PCIE1_AXI_SLV0 18
-+#define JH7110_STGRST_PCIE1_AXI_SLV 19
-+#define JH7110_STGRST_PCIE1_BRG 20
-+#define JH7110_STGRST_PCIE1_CORE 21
-+#define JH7110_STGRST_PCIE1_APB 22
-+
-+#define JH7110_STGRST_END 23
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch b/target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch
deleted file mode 100644
index 88b24a9c6d..0000000000
--- a/target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch
+++ /dev/null
@@ -1,218 +0,0 @@
-From 9a02d66b0515d987037d0229b99367412b9eb38c Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Date: Thu, 18 May 2023 18:12:25 +0800
-Subject: [PATCH 052/122] clk: starfive: Add StarFive JH7110 System-Top-Group
- clock driver
-
-Add driver for the StarFive JH7110 System-Top-Group clock controller.
-
-Co-developed-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- drivers/clk/starfive/Kconfig | 11 ++
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-stg.c | 173 ++++++++++++++++++
- 3 files changed, 185 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-stg.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -51,3 +51,14 @@ config CLK_STARFIVE_JH7110_AON
- help
- Say yes here to support the always-on clock controller on the
- StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_STG
-+ tristate "StarFive JH7110 System-Top-Group clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the System-Top-Group clock controller
-+ on the StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)
- obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) += clk-starfive-jh7110-pll.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
-@@ -0,0 +1,173 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 System-Top-Group Clock Driver
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_STGCLK_OSC (JH7110_STGCLK_END + 0)
-+#define JH7110_STGCLK_HIFI4_CORE (JH7110_STGCLK_END + 1)
-+#define JH7110_STGCLK_STG_AXIAHB (JH7110_STGCLK_END + 2)
-+#define JH7110_STGCLK_USB_125M (JH7110_STGCLK_END + 3)
-+#define JH7110_STGCLK_CPU_BUS (JH7110_STGCLK_END + 4)
-+#define JH7110_STGCLK_HIFI4_AXI (JH7110_STGCLK_END + 5)
-+#define JH7110_STGCLK_NOCSTG_BUS (JH7110_STGCLK_END + 6)
-+#define JH7110_STGCLK_APB_BUS (JH7110_STGCLK_END + 7)
-+#define JH7110_STGCLK_EXT_END (JH7110_STGCLK_END + 8)
-+
-+static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
-+ /* hifi4 */
-+ JH71X0_GATE(JH7110_STGCLK_HIFI4_CLK_CORE, "hifi4_clk_core", 0,
-+ JH7110_STGCLK_HIFI4_CORE),
-+ /* usb */
-+ JH71X0_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", 0, 2, JH7110_STGCLK_OSC),
-+ JH71X0_GDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", 0, 4, JH7110_STGCLK_OSC),
-+ JH71X0_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", 0, JH7110_STGCLK_USB_125M),
-+ JH71X0__DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", 2, JH7110_STGCLK_OSC),
-+ /* pci-e */
-+ JH71X0_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0", 0,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0", 0,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE_SLV_MAIN, "pcie_slv_main", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ /* security */
-+ JH71X0_GATE(JH7110_STGCLK_SEC_AHB, "sec_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_SEC_MISC_AHB, "sec_misc_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
-+ /* stg mtrx */
-+ JH71X0_GATE(JH7110_STGCLK_GRP0_MAIN, "mtrx_grp0_main", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_CPU_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP0_BUS, "mtrx_grp0_bus", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_NOCSTG_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP0_STG, "mtrx_grp0_stg", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_MAIN, "mtrx_grp1_main", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_CPU_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_BUS, "mtrx_grp1_bus", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_NOCSTG_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_STG, "mtrx_grp1_stg", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_HIFI, "mtrx_grp1_hifi", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_HIFI4_AXI),
-+ /* e24_rvpi */
-+ JH71X0_GDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", 0, 24, JH7110_STGCLK_OSC),
-+ JH71X0_GATE(JH7110_STGCLK_E2_CORE, "e2_core", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", 0, JH7110_STGCLK_STG_AXIAHB),
-+ /* dw_sgdma1p */
-+ JH71X0_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
-+};
-+
-+static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_STGCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static int jh7110_stgcrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7110_STGCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ for (idx = 0; idx < JH7110_STGCLK_END; idx++) {
-+ u32 max = jh7110_stgclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_stgclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_stgclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ const char *fw_name[JH7110_STGCLK_EXT_END - JH7110_STGCLK_END] = {
-+ "osc",
-+ "hifi4_core",
-+ "stg_axiahb",
-+ "usb_125m",
-+ "cpu_bus",
-+ "hifi4_axi",
-+ "nocstg_bus",
-+ "apb_bus"
-+ };
-+ unsigned int i;
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_stgclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_STGCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx < JH7110_STGCLK_EXT_END)
-+ parents[i].fw_name = fw_name[pidx - JH7110_STGCLK_END];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_stgclk_get, priv);
-+ if (ret)
-+ return ret;
-+
-+ return jh7110_reset_controller_register(priv, "rst-stg", 2);
-+}
-+
-+static const struct of_device_id jh7110_stgcrg_match[] = {
-+ { .compatible = "starfive,jh7110-stgcrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_stgcrg_match);
-+
-+static struct platform_driver jh7110_stgcrg_driver = {
-+ .probe = jh7110_stgcrg_probe,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-stg",
-+ .of_match_table = jh7110_stgcrg_match,
-+ },
-+};
-+module_platform_driver(jh7110_stgcrg_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_DESCRIPTION("StarFive JH7110 System-Top-Group clock driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch b/target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch
deleted file mode 100644
index eda4a0280a..0000000000
--- a/target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From 70df2590923e262ce8bf2b4f497f3481511d4fd6 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:26 +0800
-Subject: [PATCH 053/122] dt-bindings: clock: Add StarFive JH7110
- Image-Signal-Process clock and reset generator
-
-Add bindings for the Image-Signal-Process clock and reset
-generator (ISPCRG) on the JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-ispcrg.yaml | 87 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 18 ++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
- 3 files changed, 121 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
-@@ -0,0 +1,87 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-ispcrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Image-Signal-Process Clock and Reset Generator
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-ispcrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: ISP Top core
-+ - description: ISP Top Axi
-+ - description: NOC ISP Bus
-+ - description: external DVP
-+
-+ clock-names:
-+ items:
-+ - const: isp_top_core
-+ - const: isp_top_axi
-+ - const: noc_bus_isp_axi
-+ - const: dvp_clk
-+
-+ resets:
-+ items:
-+ - description: ISP Top core
-+ - description: ISP Top Axi
-+ - description: NOC ISP Bus
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+ power-domains:
-+ maxItems: 1
-+ description:
-+ ISP domain power
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - '#clock-cells'
-+ - '#reset-cells'
-+ - power-domains
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
-+ #include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+ ispcrg: clock-controller@19810000 {
-+ compatible = "starfive,jh7110-ispcrg";
-+ reg = <0x19810000 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
-+ <&dvp_clk>;
-+ clock-names = "isp_top_core", "isp_top_axi",
-+ "noc_bus_isp_axi", "dvp_clk";
-+ resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_ISP>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -258,4 +258,22 @@
-
- #define JH7110_STGCLK_END 29
-
-+/* ISPCRG clocks */
-+#define JH7110_ISPCLK_DOM4_APB_FUNC 0
-+#define JH7110_ISPCLK_MIPI_RX0_PXL 1
-+#define JH7110_ISPCLK_DVP_INV 2
-+#define JH7110_ISPCLK_M31DPHY_CFG_IN 3
-+#define JH7110_ISPCLK_M31DPHY_REF_IN 4
-+#define JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0 5
-+#define JH7110_ISPCLK_VIN_APB 6
-+#define JH7110_ISPCLK_VIN_SYS 7
-+#define JH7110_ISPCLK_VIN_PIXEL_IF0 8
-+#define JH7110_ISPCLK_VIN_PIXEL_IF1 9
-+#define JH7110_ISPCLK_VIN_PIXEL_IF2 10
-+#define JH7110_ISPCLK_VIN_PIXEL_IF3 11
-+#define JH7110_ISPCLK_VIN_P_AXI_WR 12
-+#define JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C 13
-+
-+#define JH7110_ISPCLK_END 14
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -179,4 +179,20 @@
-
- #define JH7110_STGRST_END 23
-
-+/* ISPCRG resets */
-+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_P 0
-+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_C 1
-+#define JH7110_ISPRST_M31DPHY_HW 2
-+#define JH7110_ISPRST_M31DPHY_B09_AON 3
-+#define JH7110_ISPRST_VIN_APB 4
-+#define JH7110_ISPRST_VIN_PIXEL_IF0 5
-+#define JH7110_ISPRST_VIN_PIXEL_IF1 6
-+#define JH7110_ISPRST_VIN_PIXEL_IF2 7
-+#define JH7110_ISPRST_VIN_PIXEL_IF3 8
-+#define JH7110_ISPRST_VIN_SYS 9
-+#define JH7110_ISPRST_VIN_P_AXI_RD 10
-+#define JH7110_ISPRST_VIN_P_AXI_WR 11
-+
-+#define JH7110_ISPRST_END 12
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch b/target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch
deleted file mode 100644
index 2e049e77dd..0000000000
--- a/target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From 003c13d81b525a184c5ca551e536e6786e2d2f5c Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:27 +0800
-Subject: [PATCH 054/122] clk: starfive: Add StarFive JH7110
- Image-Signal-Process clock driver
-
-Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
-And these clock controllers should power on and enable the clocks from
-SYSCRG first before registering.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clk/starfive/Kconfig | 11 +
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-isp.c | 232 ++++++++++++++++++
- drivers/clk/starfive/clk-starfive-jh7110.h | 6 +
- 4 files changed, 250 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -62,3 +62,14 @@ config CLK_STARFIVE_JH7110_STG
- help
- Say yes here to support the System-Top-Group clock controller
- on the StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_ISP
-+ tristate "StarFive JH7110 Image-Signal-Process clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the Image-Signal-Process clock controller
-+ on the StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) +=
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
-@@ -0,0 +1,232 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 Image-Signal-Process Clock Driver
-+ *
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_ISPCLK_ISP_TOP_CORE (JH7110_ISPCLK_END + 0)
-+#define JH7110_ISPCLK_ISP_TOP_AXI (JH7110_ISPCLK_END + 1)
-+#define JH7110_ISPCLK_NOC_BUS_ISP_AXI (JH7110_ISPCLK_END + 2)
-+#define JH7110_ISPCLK_DVP_CLK (JH7110_ISPCLK_END + 3)
-+#define JH7110_ISPCLK_EXT_END (JH7110_ISPCLK_END + 4)
-+
-+static struct clk_bulk_data jh7110_isp_top_clks[] = {
-+ { .id = "isp_top_core" },
-+ { .id = "isp_top_axi" }
-+};
-+
-+static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
-+ /* syscon */
-+ JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
-+ JH7110_ISPCLK_ISP_TOP_AXI),
-+ JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
-+ /* vin */
-+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFG_IN, "m31dphy_cfg_in", 16,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REF_IN, "m31dphy_ref_in", 16,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0, "m31dphy_tx_esc_lan0", 60,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_APB, "vin_apb", 0,
-+ JH7110_ISPCLK_DOM4_APB_FUNC),
-+ JH71X0__DIV(JH7110_ISPCLK_VIN_SYS, "vin_sys", 8, JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF0, "vin_pixel_if0", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF1, "vin_pixel_if1", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF2, "vin_pixel_if2", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
-+ JH7110_ISPCLK_MIPI_RX0_PXL,
-+ JH7110_ISPCLK_DVP_INV),
-+ /* ispv2_top_wrapper */
-+ JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C, "ispv2_top_wrapper_c", 0, 2,
-+ JH7110_ISPCLK_MIPI_RX0_PXL,
-+ JH7110_ISPCLK_DVP_INV),
-+};
-+
-+static inline int jh7110_isp_top_rst_init(struct jh71x0_clk_priv *priv)
-+{
-+ struct reset_control *top_rsts;
-+
-+ /* The resets should be shared and other ISP modules will use its. */
-+ top_rsts = devm_reset_control_array_get_shared(priv->dev);
-+ if (IS_ERR(top_rsts))
-+ return dev_err_probe(priv->dev, PTR_ERR(top_rsts),
-+ "failed to get top resets\n");
-+
-+ return reset_control_deassert(top_rsts);
-+}
-+
-+static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_ISPCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+#ifdef CONFIG_PM
-+static int jh7110_ispcrg_suspend(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
-+
-+ return 0;
-+}
-+
-+static int jh7110_ispcrg_resume(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
-+}
-+#endif
-+
-+static const struct dev_pm_ops jh7110_ispcrg_pm_ops = {
-+ SET_RUNTIME_PM_OPS(jh7110_ispcrg_suspend, jh7110_ispcrg_resume, NULL)
-+};
-+
-+static int jh7110_ispcrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ struct top_sysclk *top;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_ISPCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
-+ if (!top)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ top->top_clks = jh7110_isp_top_clks;
-+ top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
-+ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
-+ if (ret)
-+ return dev_err_probe(priv->dev, ret, "failed to get main clocks\n");
-+ dev_set_drvdata(priv->dev, top);
-+
-+ /* enable power domain and clocks */
-+ pm_runtime_enable(priv->dev);
-+ ret = pm_runtime_get_sync(priv->dev);
-+ if (ret < 0)
-+ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
-+
-+ ret = jh7110_isp_top_rst_init(priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
-+ u32 max = jh7110_ispclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_ispclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_ispclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+ const char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
-+ "isp_top_core",
-+ "isp_top_axi",
-+ "noc_bus_isp_axi",
-+ "dvp_clk"
-+ };
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_ISPCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else
-+ parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ goto err_exit;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ ret = jh7110_reset_controller_register(priv, "rst-isp", 3);
-+ if (ret)
-+ goto err_exit;
-+
-+ return 0;
-+
-+err_exit:
-+ pm_runtime_put_sync(priv->dev);
-+ pm_runtime_disable(priv->dev);
-+ return ret;
-+}
-+
-+static int jh7110_ispcrg_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id jh7110_ispcrg_match[] = {
-+ { .compatible = "starfive,jh7110-ispcrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
-+
-+static struct platform_driver jh7110_ispcrg_driver = {
-+ .probe = jh7110_ispcrg_probe,
-+ .remove = jh7110_ispcrg_remove,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-isp",
-+ .of_match_table = jh7110_ispcrg_match,
-+ .pm = &jh7110_ispcrg_pm_ops,
-+ },
-+};
-+module_platform_driver(jh7110_ispcrg_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
-+MODULE_LICENSE("GPL");
---- a/drivers/clk/starfive/clk-starfive-jh7110.h
-+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
-@@ -4,6 +4,12 @@
-
- #include "clk-starfive-jh71x0.h"
-
-+/* top clocks of ISP/VOUT domain from SYSCRG */
-+struct top_sysclk {
-+ struct clk_bulk_data *top_clks;
-+ int top_clks_num;
-+};
-+
- int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
- const char *adev_name,
- u32 adev_id);
diff --git a/target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch b/target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch
deleted file mode 100644
index fabc6aac17..0000000000
--- a/target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-From 06fa910083f37ecbc9234c7230dcbbd4d83e2f02 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:28 +0800
-Subject: [PATCH 055/122] dt-bindings: clock: Add StarFive JH7110 Video-Output
- clock and reset generator
-
-Add bindings for the Video-Output clock and reset generator (VOUTCRG)
-on the JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-voutcrg.yaml | 90 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 22 +++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
- 3 files changed, 128 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
-@@ -0,0 +1,90 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-voutcrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Video-Output Clock and Reset Generator
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-voutcrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Vout Top core
-+ - description: Vout Top Ahb
-+ - description: Vout Top Axi
-+ - description: Vout Top HDMI MCLK
-+ - description: I2STX0 BCLK
-+ - description: external HDMI pixel
-+
-+ clock-names:
-+ items:
-+ - const: vout_src
-+ - const: vout_top_ahb
-+ - const: vout_top_axi
-+ - const: vout_top_hdmitx0_mclk
-+ - const: i2stx0_bclk
-+ - const: hdmitx0_pixelclk
-+
-+ resets:
-+ maxItems: 1
-+ description: Vout Top core
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+ power-domains:
-+ maxItems: 1
-+ description:
-+ Vout domain power
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - '#clock-cells'
-+ - '#reset-cells'
-+ - power-domains
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
-+ #include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+ voutcrg: clock-controller@295C0000 {
-+ compatible = "starfive,jh7110-voutcrg";
-+ reg = <0x295C0000 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
-+ <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
-+ <&hdmitx0_pixelclk>;
-+ clock-names = "vout_src", "vout_top_ahb",
-+ "vout_top_axi", "vout_top_hdmitx0_mclk",
-+ "i2stx0_bclk", "hdmitx0_pixelclk";
-+ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_VOUT>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -276,4 +276,26 @@
-
- #define JH7110_ISPCLK_END 14
-
-+/* VOUTCRG clocks */
-+#define JH7110_VOUTCLK_APB 0
-+#define JH7110_VOUTCLK_DC8200_PIX 1
-+#define JH7110_VOUTCLK_DSI_SYS 2
-+#define JH7110_VOUTCLK_TX_ESC 3
-+#define JH7110_VOUTCLK_DC8200_AXI 4
-+#define JH7110_VOUTCLK_DC8200_CORE 5
-+#define JH7110_VOUTCLK_DC8200_AHB 6
-+#define JH7110_VOUTCLK_DC8200_PIX0 7
-+#define JH7110_VOUTCLK_DC8200_PIX1 8
-+#define JH7110_VOUTCLK_DOM_VOUT_TOP_LCD 9
-+#define JH7110_VOUTCLK_DSITX_APB 10
-+#define JH7110_VOUTCLK_DSITX_SYS 11
-+#define JH7110_VOUTCLK_DSITX_DPI 12
-+#define JH7110_VOUTCLK_DSITX_TXESC 13
-+#define JH7110_VOUTCLK_MIPITX_DPHY_TXESC 14
-+#define JH7110_VOUTCLK_HDMI_TX_MCLK 15
-+#define JH7110_VOUTCLK_HDMI_TX_BCLK 16
-+#define JH7110_VOUTCLK_HDMI_TX_SYS 17
-+
-+#define JH7110_VOUTCLK_END 18
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -195,4 +195,20 @@
-
- #define JH7110_ISPRST_END 12
-
-+/* VOUTCRG resets */
-+#define JH7110_VOUTRST_DC8200_AXI 0
-+#define JH7110_VOUTRST_DC8200_AHB 1
-+#define JH7110_VOUTRST_DC8200_CORE 2
-+#define JH7110_VOUTRST_DSITX_DPI 3
-+#define JH7110_VOUTRST_DSITX_APB 4
-+#define JH7110_VOUTRST_DSITX_RXESC 5
-+#define JH7110_VOUTRST_DSITX_SYS 6
-+#define JH7110_VOUTRST_DSITX_TXBYTEHS 7
-+#define JH7110_VOUTRST_DSITX_TXESC 8
-+#define JH7110_VOUTRST_HDMI_TX_HDMI 9
-+#define JH7110_VOUTRST_MIPITX_DPHY_SYS 10
-+#define JH7110_VOUTRST_MIPITX_DPHY_TXBYTEHS 11
-+
-+#define JH7110_VOUTRST_END 12
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch b/target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch
deleted file mode 100644
index 8c31af5089..0000000000
--- a/target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch
+++ /dev/null
@@ -1,284 +0,0 @@
-From 2e632d5c5f8b4577ac823f6a9dcf3eacdb14a0ba Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:29 +0800
-Subject: [PATCH 056/122] clk: starfive: Add StarFive JH7110 Video-Output clock
- driver
-
-Add driver for the StarFive JH7110 Video-Output clock controller.
-And these clock controllers should power on and enable the clocks from
-SYSCRG first before registering.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clk/starfive/Kconfig | 11 +
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-vout.c | 239 ++++++++++++++++++
- 3 files changed, 251 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -73,3 +73,14 @@ config CLK_STARFIVE_JH7110_ISP
- help
- Say yes here to support the Image-Signal-Process clock controller
- on the StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_VOUT
-+ tristate "StarFive JH7110 Video-Output clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the Video-Output clock controller
-+ on the StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -9,3 +9,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) +=
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
-@@ -0,0 +1,239 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 Video-Output Clock Driver
-+ *
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_VOUTCLK_VOUT_SRC (JH7110_VOUTCLK_END + 0)
-+#define JH7110_VOUTCLK_VOUT_TOP_AHB (JH7110_VOUTCLK_END + 1)
-+#define JH7110_VOUTCLK_VOUT_TOP_AXI (JH7110_VOUTCLK_END + 2)
-+#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK (JH7110_VOUTCLK_END + 3)
-+#define JH7110_VOUTCLK_I2STX0_BCLK (JH7110_VOUTCLK_END + 4)
-+#define JH7110_VOUTCLK_HDMITX0_PIXELCLK (JH7110_VOUTCLK_END + 5)
-+#define JH7110_VOUTCLK_EXT_END (JH7110_VOUTCLK_END + 6)
-+
-+static struct clk_bulk_data jh7110_vout_top_clks[] = {
-+ { .id = "vout_src" },
-+ { .id = "vout_top_ahb" }
-+};
-+
-+static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
-+ /* divider */
-+ JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
-+ JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
-+ JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
-+ JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
-+ /* dc8200 */
-+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
-+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
-+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
-+ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX,
-+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
-+ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX,
-+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
-+ /* LCD */
-+ JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX0,
-+ JH7110_VOUTCLK_DC8200_PIX1),
-+ /* dsiTx */
-+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
-+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
-+ JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX,
-+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
-+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
-+ /* mipitx DPHY */
-+ JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
-+ JH7110_VOUTCLK_TX_ESC),
-+ /* hdmi */
-+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
-+ JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
-+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
-+ JH7110_VOUTCLK_I2STX0_BCLK),
-+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
-+};
-+
-+static int jh7110_vout_top_rst_init(struct jh71x0_clk_priv *priv)
-+{
-+ struct reset_control *top_rst;
-+
-+ /* The reset should be shared and other Vout modules will use its. */
-+ top_rst = devm_reset_control_get_shared(priv->dev, NULL);
-+ if (IS_ERR(top_rst))
-+ return dev_err_probe(priv->dev, PTR_ERR(top_rst), "failed to get top reset\n");
-+
-+ return reset_control_deassert(top_rst);
-+}
-+
-+static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_VOUTCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+#ifdef CONFIG_PM
-+static int jh7110_voutcrg_suspend(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
-+
-+ return 0;
-+}
-+
-+static int jh7110_voutcrg_resume(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
-+}
-+#endif
-+
-+static const struct dev_pm_ops jh7110_voutcrg_pm_ops = {
-+ SET_RUNTIME_PM_OPS(jh7110_voutcrg_suspend, jh7110_voutcrg_resume, NULL)
-+};
-+
-+static int jh7110_voutcrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ struct top_sysclk *top;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_VOUTCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
-+ if (!top)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ top->top_clks = jh7110_vout_top_clks;
-+ top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
-+ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
-+ if (ret)
-+ return dev_err_probe(priv->dev, ret, "failed to get top clocks\n");
-+ dev_set_drvdata(priv->dev, top);
-+
-+ /* enable power domain and clocks */
-+ pm_runtime_enable(priv->dev);
-+ ret = pm_runtime_get_sync(priv->dev);
-+ if (ret < 0)
-+ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
-+
-+ ret = jh7110_vout_top_rst_init(priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
-+ u32 max = jh7110_voutclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_voutclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_voutclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+ const char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
-+ "vout_src",
-+ "vout_top_ahb",
-+ "vout_top_axi",
-+ "vout_top_hdmitx0_mclk",
-+ "i2stx0_bclk",
-+ "hdmitx0_pixelclk"
-+ };
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_VOUTCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx < JH7110_VOUTCLK_EXT_END)
-+ parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ goto err_exit;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ ret = jh7110_reset_controller_register(priv, "rst-vo", 4);
-+ if (ret)
-+ goto err_exit;
-+
-+ return 0;
-+
-+err_exit:
-+ pm_runtime_put_sync(priv->dev);
-+ pm_runtime_disable(priv->dev);
-+ return ret;
-+}
-+
-+static int jh7110_voutcrg_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id jh7110_voutcrg_match[] = {
-+ { .compatible = "starfive,jh7110-voutcrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
-+
-+static struct platform_driver jh7110_voutcrg_driver = {
-+ .probe = jh7110_voutcrg_probe,
-+ .remove = jh7110_voutcrg_remove,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-vout",
-+ .of_match_table = jh7110_voutcrg_match,
-+ .pm = &jh7110_voutcrg_pm_ops,
-+ },
-+};
-+module_platform_driver(jh7110_voutcrg_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch b/target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch
deleted file mode 100644
index 197337bb70..0000000000
--- a/target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From a04a6eb3b4d112f3600bbd783249f24a43797e7a Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:31 +0800
-Subject: [PATCH 057/122] reset: starfive: jh7110: Add StarFive STG/ISP/VOUT
- resets support
-
-Add new struct members and auxiliary_device_id of resets to support
-System-Top-Group, Image-Signal-Process and Video-Output on the StarFive
-JH7110 SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../reset/starfive/reset-starfive-jh7110.c | 30 +++++++++++++++++++
- 1 file changed, 30 insertions(+)
-
---- a/drivers/reset/starfive/reset-starfive-jh7110.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
-@@ -31,6 +31,24 @@ static const struct jh7110_reset_info jh
- .status_offset = 0x3C,
- };
-
-+static const struct jh7110_reset_info jh7110_stg_info = {
-+ .nr_resets = JH7110_STGRST_END,
-+ .assert_offset = 0x74,
-+ .status_offset = 0x78,
-+};
-+
-+static const struct jh7110_reset_info jh7110_isp_info = {
-+ .nr_resets = JH7110_ISPRST_END,
-+ .assert_offset = 0x38,
-+ .status_offset = 0x3C,
-+};
-+
-+static const struct jh7110_reset_info jh7110_vout_info = {
-+ .nr_resets = JH7110_VOUTRST_END,
-+ .assert_offset = 0x48,
-+ .status_offset = 0x4C,
-+};
-+
- static int jh7110_reset_probe(struct auxiliary_device *adev,
- const struct auxiliary_device_id *id)
- {
-@@ -58,6 +76,18 @@ static const struct auxiliary_device_id
- .name = "clk_starfive_jh7110_sys.rst-aon",
- .driver_data = (kernel_ulong_t)&jh7110_aon_info,
- },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-stg",
-+ .driver_data = (kernel_ulong_t)&jh7110_stg_info,
-+ },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-isp",
-+ .driver_data = (kernel_ulong_t)&jh7110_isp_info,
-+ },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-vo",
-+ .driver_data = (kernel_ulong_t)&jh7110_vout_info,
-+ },
- { /* sentinel */ }
- };
- MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
diff --git a/target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch b/target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch
deleted file mode 100644
index fc3da897a5..0000000000
--- a/target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch
+++ /dev/null
@@ -1,819 +0,0 @@
-From 758c8c4c30f495465f34735aef2458c0cc255a75 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:03:02 -0700
-Subject: [PATCH 058/122] clk: starfive: update jh7110 PLL clock driver
-
-Update the StarFive JH7110 PLL clock controller
-and they work by reading and setting syscon registers.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- .../clk/starfive/clk-starfive-jh7110-pll.c | 269 +++++-------------
- .../clk/starfive/clk-starfive-jh7110-pll.h | 264 +++++++++--------
- 2 files changed, 227 insertions(+), 306 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7110-pll.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
-@@ -24,11 +24,29 @@
- #include <linux/mfd/syscon.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
-+#include <linux/of_platform.h>
-
- #include <dt-bindings/clock/starfive,jh7110-crg.h>
-
- #include "clk-starfive-jh7110-pll.h"
-
-+struct jh7110_pll_conf_variant {
-+ unsigned int pll_nums;
-+ struct jh7110_pll_syscon_conf conf[];
-+};
-+
-+static const struct jh7110_pll_conf_variant jh7110_pll_variant = {
-+ .pll_nums = JH7110_PLLCLK_END,
-+ .conf = {
-+ JH7110_PLL(JH7110_CLK_PLL0_OUT, "pll0_out",
-+ JH7110_PLL0_FREQ_MAX, jh7110_pll0_syscon_val_preset),
-+ JH7110_PLL(JH7110_CLK_PLL1_OUT, "pll1_out",
-+ JH7110_PLL1_FREQ_MAX, jh7110_pll1_syscon_val_preset),
-+ JH7110_PLL(JH7110_CLK_PLL2_OUT, "pll2_out",
-+ JH7110_PLL2_FREQ_MAX, jh7110_pll2_syscon_val_preset),
-+ },
-+};
-+
- static struct jh7110_clk_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
- {
- return container_of(hw, struct jh7110_clk_pll_data, hw);
-@@ -44,10 +62,9 @@ static unsigned long jh7110_pll_get_freq
- unsigned long parent_rate)
- {
- struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-- struct jh7110_pll_syscon_offset *offset = &data->offset;
-- struct jh7110_pll_syscon_mask *mask = &data->mask;
-- struct jh7110_pll_syscon_shift *shift = &data->shift;
-- unsigned long freq = 0;
-+ struct jh7110_pll_syscon_offset *offset = &data->conf.offsets;
-+ struct jh7110_pll_syscon_mask *mask = &data->conf.masks;
-+ struct jh7110_pll_syscon_shift *shift = &data->conf.shifts;
- unsigned long frac_cal;
- u32 dacpd;
- u32 dsmpd;
-@@ -57,32 +74,23 @@ static unsigned long jh7110_pll_get_freq
- u32 frac;
- u32 reg_val;
-
-- if (regmap_read(priv->syscon_regmap, offset->dacpd, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->dacpd, &reg_val);
- dacpd = (reg_val & mask->dacpd) >> shift->dacpd;
-
-- if (regmap_read(priv->syscon_regmap, offset->dsmpd, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->dsmpd, &reg_val);
- dsmpd = (reg_val & mask->dsmpd) >> shift->dsmpd;
-
-- if (regmap_read(priv->syscon_regmap, offset->fbdiv, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->fbdiv, &reg_val);
- fbdiv = (reg_val & mask->fbdiv) >> shift->fbdiv;
-- /* fbdiv value should be 8 to 4095 */
-- if (fbdiv < 8)
-- goto read_error;
-
-- if (regmap_read(priv->syscon_regmap, offset->prediv, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->prediv, &reg_val);
- prediv = (reg_val & mask->prediv) >> shift->prediv;
-
-- if (regmap_read(priv->syscon_regmap, offset->postdiv1, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->postdiv1, &reg_val);
- /* postdiv1 = 2 ^ reg_val */
- postdiv1 = 1 << ((reg_val & mask->postdiv1) >> shift->postdiv1);
-
-- if (regmap_read(priv->syscon_regmap, offset->frac, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->frac, &reg_val);
- frac = (reg_val & mask->frac) >> shift->frac;
-
- /*
-@@ -95,14 +103,11 @@ static unsigned long jh7110_pll_get_freq
- else if (dacpd == 0 && dsmpd == 0)
- frac_cal = (unsigned long)frac * STARFIVE_PLL_FRAC_PATR_SIZE / (1 << 24);
- else
-- goto read_error;
-+ return 0;
-
- /* Fvco = Fref * (NI + NF) / M / Q1 */
-- freq = parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
-- (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1;
--
--read_error:
-- return freq;
-+ return (parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
-+ (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1);
- }
-
- static unsigned long jh7110_pll_rate_sub_fabs(unsigned long rate1, unsigned long rate2)
-@@ -114,40 +119,27 @@ static unsigned long jh7110_pll_rate_sub
- static void jh7110_pll_select_near_freq_id(struct jh7110_clk_pll_data *data,
- unsigned long rate)
- {
-- const struct starfive_pll_syscon_value *syscon_val;
-+ const struct jh7110_pll_syscon_val *val;
- unsigned int id;
-- unsigned int pll_arry_size;
- unsigned long rate_diff;
-
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- pll_arry_size = ARRAY_SIZE(jh7110_pll0_syscon_freq);
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- pll_arry_size = ARRAY_SIZE(jh7110_pll1_syscon_freq);
-- else
-- pll_arry_size = ARRAY_SIZE(jh7110_pll2_syscon_freq);
--
- /* compare the frequency one by one from small to large in order */
-- for (id = 0; id < pll_arry_size; id++) {
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- syscon_val = &jh7110_pll0_syscon_freq[id];
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- syscon_val = &jh7110_pll1_syscon_freq[id];
-- else
-- syscon_val = &jh7110_pll2_syscon_freq[id];
-+ for (id = 0; id < data->conf.preset_val_nums; id++) {
-+ val = &data->conf.preset_val[id];
-
-- if (rate == syscon_val->freq)
-+ if (rate == val->freq)
- goto match_end;
-
- /* select near frequency */
-- if (rate < syscon_val->freq) {
-+ if (rate < val->freq) {
- /* The last frequency is closer to the target rate than this time. */
- if (id > 0)
-- if (rate_diff < jh7110_pll_rate_sub_fabs(rate, syscon_val->freq))
-+ if (rate_diff < jh7110_pll_rate_sub_fabs(rate, val->freq))
- id--;
-
- goto match_end;
- } else {
-- rate_diff = jh7110_pll_rate_sub_fabs(rate, syscon_val->freq);
-+ rate_diff = jh7110_pll_rate_sub_fabs(rate, val->freq);
- }
- }
-
-@@ -158,54 +150,34 @@ match_end:
- static int jh7110_pll_set_freq_syscon(struct jh7110_clk_pll_data *data)
- {
- struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-- struct jh7110_pll_syscon_offset *offset = &data->offset;
-- struct jh7110_pll_syscon_mask *mask = &data->mask;
-- struct jh7110_pll_syscon_shift *shift = &data->shift;
-- unsigned int freq_idx = data->freq_select_idx;
-- const struct starfive_pll_syscon_value *syscon_val;
-- int ret;
-+ struct jh7110_pll_syscon_offset *offset = &data->conf.offsets;
-+ struct jh7110_pll_syscon_mask *mask = &data->conf.masks;
-+ struct jh7110_pll_syscon_shift *shift = &data->conf.shifts;
-+ const struct jh7110_pll_syscon_val *val = &data->conf.preset_val[data->freq_select_idx];
-
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- syscon_val = &jh7110_pll0_syscon_freq[freq_idx];
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- syscon_val = &jh7110_pll1_syscon_freq[freq_idx];
-- else
-- syscon_val = &jh7110_pll2_syscon_freq[freq_idx];
-+ /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
-+ if (val->dacpd == 0 && val->dsmpd == 0)
-+ regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
-+ (val->frac << shift->frac));
-+ else if (val->dacpd != val->dsmpd)
-+ return -EINVAL;
-
-- ret = regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
-- (syscon_val->dacpd << shift->dacpd));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
-- (syscon_val->dsmpd << shift->dsmpd));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
-- (syscon_val->prediv << shift->prediv));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
-- (syscon_val->fbdiv << shift->fbdiv));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
-- ((syscon_val->postdiv1 >> 1) << shift->postdiv1));
-- if (ret)
-- goto set_failed;
-+ /* fbdiv value should be 8 to 4095 */
-+ if (val->fbdiv < 8)
-+ return -EINVAL;
-
-- /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
-- if (syscon_val->dacpd == 0 && syscon_val->dsmpd == 0)
-- ret = regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
-- (syscon_val->frac << shift->frac));
-- else if (syscon_val->dacpd != syscon_val->dsmpd)
-- ret = -EINVAL;
-+ regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
-+ (val->dacpd << shift->dacpd));
-+ regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
-+ (val->dsmpd << shift->dsmpd));
-+ regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
-+ (val->prediv << shift->prediv));
-+ regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
-+ (val->fbdiv << shift->fbdiv));
-+ regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
-+ ((val->postdiv1 >> 1) << shift->postdiv1));
-
--set_failed:
-- return ret;
-+ return 0;
- }
-
- static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-@@ -220,13 +192,7 @@ static int jh7110_pll_determine_rate(str
- struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-
- jh7110_pll_select_near_freq_id(data, req->rate);
--
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- req->rate = jh7110_pll0_syscon_freq[data->freq_select_idx].freq;
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- req->rate = jh7110_pll1_syscon_freq[data->freq_select_idx].freq;
-- else
-- req->rate = jh7110_pll2_syscon_freq[data->freq_select_idx].freq;
-+ req->rate = data->conf.preset_val[data->freq_select_idx].freq;
-
- return 0;
- }
-@@ -270,92 +236,12 @@ static const struct clk_ops jh7110_pll_o
- .debug_init = jh7110_pll_debug_init,
- };
-
--/* get offset, mask and shift of PLL(x) syscon */
--static int jh7110_pll_data_get(struct jh7110_clk_pll_data *data, int index)
--{
-- struct jh7110_pll_syscon_offset *offset = &data->offset;
-- struct jh7110_pll_syscon_mask *mask = &data->mask;
-- struct jh7110_pll_syscon_shift *shift = &data->shift;
--
-- if (index == JH7110_CLK_PLL0_OUT) {
-- offset->dacpd = STARFIVE_JH7110_PLL0_DACPD_OFFSET;
-- offset->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_OFFSET;
-- offset->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_OFFSET;
-- offset->frac = STARFIVE_JH7110_PLL0_FRAC_OFFSET;
-- offset->prediv = STARFIVE_JH7110_PLL0_PREDIV_OFFSET;
-- offset->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET;
--
-- mask->dacpd = STARFIVE_JH7110_PLL0_DACPD_MASK;
-- mask->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_MASK;
-- mask->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_MASK;
-- mask->frac = STARFIVE_JH7110_PLL0_FRAC_MASK;
-- mask->prediv = STARFIVE_JH7110_PLL0_PREDIV_MASK;
-- mask->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_MASK;
--
-- shift->dacpd = STARFIVE_JH7110_PLL0_DACPD_SHIFT;
-- shift->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_SHIFT;
-- shift->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_SHIFT;
-- shift->frac = STARFIVE_JH7110_PLL0_FRAC_SHIFT;
-- shift->prediv = STARFIVE_JH7110_PLL0_PREDIV_SHIFT;
-- shift->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT;
--
-- } else if (index == JH7110_CLK_PLL1_OUT) {
-- offset->dacpd = STARFIVE_JH7110_PLL1_DACPD_OFFSET;
-- offset->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_OFFSET;
-- offset->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_OFFSET;
-- offset->frac = STARFIVE_JH7110_PLL1_FRAC_OFFSET;
-- offset->prediv = STARFIVE_JH7110_PLL1_PREDIV_OFFSET;
-- offset->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET;
--
-- mask->dacpd = STARFIVE_JH7110_PLL1_DACPD_MASK;
-- mask->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_MASK;
-- mask->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_MASK;
-- mask->frac = STARFIVE_JH7110_PLL1_FRAC_MASK;
-- mask->prediv = STARFIVE_JH7110_PLL1_PREDIV_MASK;
-- mask->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_MASK;
--
-- shift->dacpd = STARFIVE_JH7110_PLL1_DACPD_SHIFT;
-- shift->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_SHIFT;
-- shift->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_SHIFT;
-- shift->frac = STARFIVE_JH7110_PLL1_FRAC_SHIFT;
-- shift->prediv = STARFIVE_JH7110_PLL1_PREDIV_SHIFT;
-- shift->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT;
--
-- } else if (index == JH7110_CLK_PLL2_OUT) {
-- offset->dacpd = STARFIVE_JH7110_PLL2_DACPD_OFFSET;
-- offset->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_OFFSET;
-- offset->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_OFFSET;
-- offset->frac = STARFIVE_JH7110_PLL2_FRAC_OFFSET;
-- offset->prediv = STARFIVE_JH7110_PLL2_PREDIV_OFFSET;
-- offset->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET;
--
-- mask->dacpd = STARFIVE_JH7110_PLL2_DACPD_MASK;
-- mask->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_MASK;
-- mask->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_MASK;
-- mask->frac = STARFIVE_JH7110_PLL2_FRAC_MASK;
-- mask->prediv = STARFIVE_JH7110_PLL2_PREDIV_MASK;
-- mask->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_MASK;
--
-- shift->dacpd = STARFIVE_JH7110_PLL2_DACPD_SHIFT;
-- shift->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_SHIFT;
-- shift->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_SHIFT;
-- shift->frac = STARFIVE_JH7110_PLL2_FRAC_SHIFT;
-- shift->prediv = STARFIVE_JH7110_PLL2_PREDIV_SHIFT;
-- shift->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT;
--
-- } else {
-- return -ENOENT;
-- }
--
-- return 0;
--}
--
- static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
- {
- struct jh7110_clk_pll_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
-- if (idx < JH7110_PLLCLK_END)
-+ if (idx < priv->pll_nums)
- return &priv->data[idx].hw;
-
- return ERR_PTR(-EINVAL);
-@@ -363,17 +249,17 @@ static struct clk_hw *jh7110_pll_get(str
-
- static int jh7110_pll_probe(struct platform_device *pdev)
- {
-- const char *pll_name[JH7110_PLLCLK_END] = {
-- "pll0_out",
-- "pll1_out",
-- "pll2_out"
-- };
-+ const struct jh7110_pll_conf_variant *variant;
- struct jh7110_clk_pll_priv *priv;
- struct jh7110_clk_pll_data *data;
- int ret;
- unsigned int idx;
-
-- priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, JH7110_PLLCLK_END),
-+ variant = of_device_get_match_data(&pdev->dev);
-+ if (!variant)
-+ return -ENOMEM;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, variant->pll_nums),
- GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-@@ -383,12 +269,13 @@ static int jh7110_pll_probe(struct platf
- if (IS_ERR(priv->syscon_regmap))
- return PTR_ERR(priv->syscon_regmap);
-
-- for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
-+ priv->pll_nums = variant->pll_nums;
-+ for (idx = 0; idx < priv->pll_nums; idx++) {
- struct clk_parent_data parents = {
- .index = 0,
- };
- struct clk_init_data init = {
-- .name = pll_name[idx],
-+ .name = variant->conf[idx].name,
- .ops = &jh7110_pll_ops,
- .parent_data = &parents,
- .num_parents = 1,
-@@ -396,11 +283,7 @@ static int jh7110_pll_probe(struct platf
- };
-
- data = &priv->data[idx];
--
-- ret = jh7110_pll_data_get(data, idx);
-- if (ret)
-- return ret;
--
-+ data->conf = variant->conf[idx];
- data->hw.init = &init;
- data->idx = idx;
-
-@@ -413,7 +296,7 @@ static int jh7110_pll_probe(struct platf
- }
-
- static const struct of_device_id jh7110_pll_match[] = {
-- { .compatible = "starfive,jh7110-pll" },
-+ { .compatible = "starfive,jh7110-pll", .data = &jh7110_pll_variant },
- { /* sentinel */ }
- };
- MODULE_DEVICE_TABLE(of, jh7110_pll_match);
---- a/drivers/clk/starfive/clk-starfive-jh7110-pll.h
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.h
-@@ -13,62 +13,93 @@
- /* The decimal places are counted by expanding them by a factor of STARFIVE_PLL_FRAC_PATR_SIZE */
- #define STARFIVE_PLL_FRAC_PATR_SIZE 1000
-
--#define STARFIVE_JH7110_PLL0_DACPD_OFFSET 0x18
--#define STARFIVE_JH7110_PLL0_DACPD_SHIFT 24
--#define STARFIVE_JH7110_PLL0_DACPD_MASK BIT(24)
--#define STARFIVE_JH7110_PLL0_DSMPD_OFFSET 0x18
--#define STARFIVE_JH7110_PLL0_DSMPD_SHIFT 25
--#define STARFIVE_JH7110_PLL0_DSMPD_MASK BIT(25)
--#define STARFIVE_JH7110_PLL0_FBDIV_OFFSET 0x1c
--#define STARFIVE_JH7110_PLL0_FBDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL0_FBDIV_MASK GENMASK(11, 0)
--#define STARFIVE_JH7110_PLL0_FRAC_OFFSET 0x20
--#define STARFIVE_JH7110_PLL0_FRAC_SHIFT 0
--#define STARFIVE_JH7110_PLL0_FRAC_MASK GENMASK(23, 0)
--#define STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET 0x20
--#define STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT 28
--#define STARFIVE_JH7110_PLL0_POSTDIV1_MASK GENMASK(29, 28)
--#define STARFIVE_JH7110_PLL0_PREDIV_OFFSET 0x24
--#define STARFIVE_JH7110_PLL0_PREDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL0_PREDIV_MASK GENMASK(5, 0)
--
--#define STARFIVE_JH7110_PLL1_DACPD_OFFSET 0x24
--#define STARFIVE_JH7110_PLL1_DACPD_SHIFT 15
--#define STARFIVE_JH7110_PLL1_DACPD_MASK BIT(15)
--#define STARFIVE_JH7110_PLL1_DSMPD_OFFSET 0x24
--#define STARFIVE_JH7110_PLL1_DSMPD_SHIFT 16
--#define STARFIVE_JH7110_PLL1_DSMPD_MASK BIT(16)
--#define STARFIVE_JH7110_PLL1_FBDIV_OFFSET 0x24
--#define STARFIVE_JH7110_PLL1_FBDIV_SHIFT 17
--#define STARFIVE_JH7110_PLL1_FBDIV_MASK GENMASK(28, 17)
--#define STARFIVE_JH7110_PLL1_FRAC_OFFSET 0x28
--#define STARFIVE_JH7110_PLL1_FRAC_SHIFT 0
--#define STARFIVE_JH7110_PLL1_FRAC_MASK GENMASK(23, 0)
--#define STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET 0x28
--#define STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT 28
--#define STARFIVE_JH7110_PLL1_POSTDIV1_MASK GENMASK(29, 28)
--#define STARFIVE_JH7110_PLL1_PREDIV_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL1_PREDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL1_PREDIV_MASK GENMASK(5, 0)
--
--#define STARFIVE_JH7110_PLL2_DACPD_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL2_DACPD_SHIFT 15
--#define STARFIVE_JH7110_PLL2_DACPD_MASK BIT(15)
--#define STARFIVE_JH7110_PLL2_DSMPD_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL2_DSMPD_SHIFT 16
--#define STARFIVE_JH7110_PLL2_DSMPD_MASK BIT(16)
--#define STARFIVE_JH7110_PLL2_FBDIV_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL2_FBDIV_SHIFT 17
--#define STARFIVE_JH7110_PLL2_FBDIV_MASK GENMASK(28, 17)
--#define STARFIVE_JH7110_PLL2_FRAC_OFFSET 0x30
--#define STARFIVE_JH7110_PLL2_FRAC_SHIFT 0
--#define STARFIVE_JH7110_PLL2_FRAC_MASK GENMASK(23, 0)
--#define STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET 0x30
--#define STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT 28
--#define STARFIVE_JH7110_PLL2_POSTDIV1_MASK GENMASK(29, 28)
--#define STARFIVE_JH7110_PLL2_PREDIV_OFFSET 0x34
--#define STARFIVE_JH7110_PLL2_PREDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL2_PREDIV_MASK GENMASK(5, 0)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_OFFSET 0x18
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_SHIFT 24
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_MASK BIT(24)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_OFFSET 0x18
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_SHIFT 25
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_MASK BIT(25)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_OFFSET 0x1c
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_MASK GENMASK(11, 0)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_OFFSET 0x20
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_OFFSET 0x20
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_OFFSET 0x28
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_OFFSET 0x28
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_OFFSET 0x30
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_OFFSET 0x30
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_OFFSET 0x34
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_MASK GENMASK(5, 0)
-+
-+#define JH7110_PLL(_idx, _name, _nums, _val) \
-+[_idx] = { \
-+ .name = _name, \
-+ .offsets = { \
-+ .dacpd = STARFIVE_##_idx##_DACPD_OFFSET, \
-+ .dsmpd = STARFIVE_##_idx##_DSMPD_OFFSET, \
-+ .fbdiv = STARFIVE_##_idx##_FBDIV_OFFSET, \
-+ .frac = STARFIVE_##_idx##_FRAC_OFFSET, \
-+ .prediv = STARFIVE_##_idx##_PREDIV_OFFSET, \
-+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_OFFSET, \
-+ }, \
-+ .masks = { \
-+ .dacpd = STARFIVE_##_idx##_DACPD_MASK, \
-+ .dsmpd = STARFIVE_##_idx##_DSMPD_MASK, \
-+ .fbdiv = STARFIVE_##_idx##_FBDIV_MASK, \
-+ .frac = STARFIVE_##_idx##_FRAC_MASK, \
-+ .prediv = STARFIVE_##_idx##_PREDIV_MASK, \
-+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_MASK, \
-+ }, \
-+ .shifts = { \
-+ .dacpd = STARFIVE_##_idx##_DACPD_SHIFT, \
-+ .dsmpd = STARFIVE_##_idx##_DSMPD_SHIFT, \
-+ .fbdiv = STARFIVE_##_idx##_FBDIV_SHIFT, \
-+ .frac = STARFIVE_##_idx##_FRAC_SHIFT, \
-+ .prediv = STARFIVE_##_idx##_PREDIV_SHIFT, \
-+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_SHIFT, \
-+ }, \
-+ .preset_val_nums = _nums, \
-+ .preset_val = _val, \
-+}
-
- struct jh7110_pll_syscon_offset {
- unsigned int dacpd;
-@@ -97,23 +128,7 @@ struct jh7110_pll_syscon_shift {
- char postdiv1;
- };
-
--struct jh7110_clk_pll_data {
-- struct clk_hw hw;
-- unsigned int idx;
-- unsigned int freq_select_idx;
--
-- struct jh7110_pll_syscon_offset offset;
-- struct jh7110_pll_syscon_mask mask;
-- struct jh7110_pll_syscon_shift shift;
--};
--
--struct jh7110_clk_pll_priv {
-- struct device *dev;
-- struct regmap *syscon_regmap;
-- struct jh7110_clk_pll_data data[];
--};
--
--struct starfive_pll_syscon_value {
-+struct jh7110_pll_syscon_val {
- unsigned long freq;
- u32 prediv;
- u32 fbdiv;
-@@ -126,31 +141,54 @@ struct starfive_pll_syscon_value {
- u32 frac;
- };
-
--enum starfive_pll0_freq_index {
-- PLL0_FREQ_375 = 0,
-- PLL0_FREQ_500,
-- PLL0_FREQ_625,
-- PLL0_FREQ_750,
-- PLL0_FREQ_875,
-- PLL0_FREQ_1000,
-- PLL0_FREQ_1250,
-- PLL0_FREQ_1375,
-- PLL0_FREQ_1500,
-- PLL0_FREQ_MAX
--};
--
--enum starfive_pll1_freq_index {
-- PLL1_FREQ_1066 = 0,
-- PLL1_FREQ_1200,
-- PLL1_FREQ_1400,
-- PLL1_FREQ_1600,
-- PLL1_FREQ_MAX
--};
--
--enum starfive_pll2_freq_index {
-- PLL2_FREQ_1188 = 0,
-- PLL2_FREQ_12288,
-- PLL2_FREQ_MAX
-+struct jh7110_pll_syscon_conf {
-+ char *name;
-+ struct jh7110_pll_syscon_offset offsets;
-+ struct jh7110_pll_syscon_mask masks;
-+ struct jh7110_pll_syscon_shift shifts;
-+ unsigned int preset_val_nums;
-+ const struct jh7110_pll_syscon_val *preset_val;
-+};
-+
-+struct jh7110_clk_pll_data {
-+ struct clk_hw hw;
-+ unsigned int idx;
-+ unsigned int freq_select_idx;
-+ struct jh7110_pll_syscon_conf conf;
-+};
-+
-+struct jh7110_clk_pll_priv {
-+ unsigned int pll_nums;
-+ struct device *dev;
-+ struct regmap *syscon_regmap;
-+ struct jh7110_clk_pll_data data[];
-+};
-+
-+enum jh7110_pll0_freq_index {
-+ JH7110_PLL0_FREQ_375 = 0,
-+ JH7110_PLL0_FREQ_500,
-+ JH7110_PLL0_FREQ_625,
-+ JH7110_PLL0_FREQ_750,
-+ JH7110_PLL0_FREQ_875,
-+ JH7110_PLL0_FREQ_1000,
-+ JH7110_PLL0_FREQ_1250,
-+ JH7110_PLL0_FREQ_1375,
-+ JH7110_PLL0_FREQ_1500,
-+ JH7110_PLL0_FREQ_MAX
-+};
-+
-+enum jh7110_pll1_freq_index {
-+ JH7110_PLL1_FREQ_1066 = 0,
-+ JH7110_PLL1_FREQ_1200,
-+ JH7110_PLL1_FREQ_1400,
-+ JH7110_PLL1_FREQ_1600,
-+ JH7110_PLL1_FREQ_MAX
-+};
-+
-+enum jh7110_pll2_freq_index {
-+ JH7110_PLL2_FREQ_1188 = 0,
-+ JH7110_PLL2_FREQ_12288,
-+ JH7110_PLL2_FREQ_MAX
- };
-
- /*
-@@ -158,9 +196,9 @@ enum starfive_pll2_freq_index {
- * it cannot be set arbitrarily, so it needs a specific configuration.
- * PLL0 frequency should be multiple of 125MHz (USB frequency).
- */
--static const struct starfive_pll_syscon_value
-- jh7110_pll0_syscon_freq[PLL0_FREQ_MAX] = {
-- [PLL0_FREQ_375] = {
-+static const struct jh7110_pll_syscon_val
-+ jh7110_pll0_syscon_val_preset[] = {
-+ [JH7110_PLL0_FREQ_375] = {
- .freq = 375000000,
- .prediv = 8,
- .fbdiv = 125,
-@@ -168,7 +206,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_500] = {
-+ [JH7110_PLL0_FREQ_500] = {
- .freq = 500000000,
- .prediv = 6,
- .fbdiv = 125,
-@@ -176,7 +214,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_625] = {
-+ [JH7110_PLL0_FREQ_625] = {
- .freq = 625000000,
- .prediv = 24,
- .fbdiv = 625,
-@@ -184,7 +222,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_750] = {
-+ [JH7110_PLL0_FREQ_750] = {
- .freq = 750000000,
- .prediv = 4,
- .fbdiv = 125,
-@@ -192,7 +230,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_875] = {
-+ [JH7110_PLL0_FREQ_875] = {
- .freq = 875000000,
- .prediv = 24,
- .fbdiv = 875,
-@@ -200,7 +238,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1000] = {
-+ [JH7110_PLL0_FREQ_1000] = {
- .freq = 1000000000,
- .prediv = 3,
- .fbdiv = 125,
-@@ -208,7 +246,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1250] = {
-+ [JH7110_PLL0_FREQ_1250] = {
- .freq = 1250000000,
- .prediv = 12,
- .fbdiv = 625,
-@@ -216,7 +254,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1375] = {
-+ [JH7110_PLL0_FREQ_1375] = {
- .freq = 1375000000,
- .prediv = 24,
- .fbdiv = 1375,
-@@ -224,7 +262,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1500] = {
-+ [JH7110_PLL0_FREQ_1500] = {
- .freq = 1500000000,
- .prediv = 2,
- .fbdiv = 125,
-@@ -234,9 +272,9 @@ static const struct starfive_pll_syscon_
- },
- };
-
--static const struct starfive_pll_syscon_value
-- jh7110_pll1_syscon_freq[PLL1_FREQ_MAX] = {
-- [PLL1_FREQ_1066] = {
-+static const struct jh7110_pll_syscon_val
-+ jh7110_pll1_syscon_val_preset[] = {
-+ [JH7110_PLL1_FREQ_1066] = {
- .freq = 1066000000,
- .prediv = 12,
- .fbdiv = 533,
-@@ -244,7 +282,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL1_FREQ_1200] = {
-+ [JH7110_PLL1_FREQ_1200] = {
- .freq = 1200000000,
- .prediv = 1,
- .fbdiv = 50,
-@@ -252,7 +290,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL1_FREQ_1400] = {
-+ [JH7110_PLL1_FREQ_1400] = {
- .freq = 1400000000,
- .prediv = 6,
- .fbdiv = 350,
-@@ -260,7 +298,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL1_FREQ_1600] = {
-+ [JH7110_PLL1_FREQ_1600] = {
- .freq = 1600000000,
- .prediv = 3,
- .fbdiv = 200,
-@@ -270,9 +308,9 @@ static const struct starfive_pll_syscon_
- },
- };
-
--static const struct starfive_pll_syscon_value
-- jh7110_pll2_syscon_freq[PLL2_FREQ_MAX] = {
-- [PLL2_FREQ_1188] = {
-+static const struct jh7110_pll_syscon_val
-+ jh7110_pll2_syscon_val_preset[] = {
-+ [JH7110_PLL2_FREQ_1188] = {
- .freq = 1188000000,
- .prediv = 2,
- .fbdiv = 99,
-@@ -280,7 +318,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL2_FREQ_12288] = {
-+ [JH7110_PLL2_FREQ_12288] = {
- .freq = 1228800000,
- .prediv = 5,
- .fbdiv = 256,
diff --git a/target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch b/target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
deleted file mode 100644
index f0b5b98610..0000000000
--- a/target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 944b96d734199642e2ede978c48d754109ca334c Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 20 Mar 2023 21:54:31 +0800
-Subject: [PATCH 059/122] dt-bindings: timer: Add timer for StarFive JH7110 SoC
-
-Add bindings for the timer on the JH7110 RISC-V SoC
-by StarFive Technology Ltd.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
----
- .../bindings/timer/starfive,jh7110-timer.yaml | 95 +++++++++++++++++++
- 1 file changed, 95 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
-@@ -0,0 +1,95 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/timer/starfive,jh7110-timer.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Timer
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+ - Samin Guo <samin.guo@starfivetech.com>
-+
-+description:
-+ This timer has four free-running 32 bit counters in StarFive JH7110 SoC.
-+ And each channel(counter) triggers an interrupt when timeout. They support
-+ one-shot mode and continuous-run mode.
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-timer
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ items:
-+ - description: channel 0
-+ - description: channel 1
-+ - description: channel 2
-+ - description: channel 3
-+
-+ clocks:
-+ items:
-+ - description: timer APB
-+ - description: channel 0
-+ - description: channel 1
-+ - description: channel 2
-+ - description: channel 3
-+
-+ clock-names:
-+ items:
-+ - const: apb
-+ - const: ch0
-+ - const: ch1
-+ - const: ch2
-+ - const: ch3
-+
-+ resets:
-+ items:
-+ - description: timer APB
-+ - description: channel 0
-+ - description: channel 1
-+ - description: channel 2
-+ - description: channel 3
-+
-+ reset-names:
-+ items:
-+ - const: apb
-+ - const: ch0
-+ - const: ch1
-+ - const: ch2
-+ - const: ch3
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - clocks
-+ - clock-names
-+ - resets
-+ - reset-names
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ timer@13050000 {
-+ compatible = "starfive,jh7110-timer";
-+ reg = <0x13050000 0x10000>;
-+ interrupts = <69>, <70>, <71> ,<72>;
-+ clocks = <&clk 124>,
-+ <&clk 125>,
-+ <&clk 126>,
-+ <&clk 127>,
-+ <&clk 128>;
-+ clock-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ resets = <&rst 117>,
-+ <&rst 118>,
-+ <&rst 119>,
-+ <&rst 120>,
-+ <&rst 121>;
-+ reset-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ };
-+
diff --git a/target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch b/target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch
deleted file mode 100644
index dc6f1e0bf8..0000000000
--- a/target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch
+++ /dev/null
@@ -1,540 +0,0 @@
-From 3fbdabd59bac0978536fb11b1b9deb81559f1c54 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 20 Mar 2023 21:54:32 +0800
-Subject: [PATCH 060/122] clocksource: Add StarFive timer driver
-
-Add timer driver for the StarFive JH7110 SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clocksource/Kconfig | 12 +
- drivers/clocksource/Makefile | 1 +
- drivers/clocksource/timer-starfive.c | 390 +++++++++++++++++++++++++++
- drivers/clocksource/timer-starfive.h | 96 +++++++
- 4 files changed, 499 insertions(+)
- create mode 100644 drivers/clocksource/timer-starfive.c
- create mode 100644 drivers/clocksource/timer-starfive.h
-
---- a/drivers/clocksource/Kconfig
-+++ b/drivers/clocksource/Kconfig
-@@ -630,6 +630,18 @@ config RISCV_TIMER
- is accessed via both the SBI and the rdcycle instruction. This is
- required for all RISC-V systems.
-
-+config STARFIVE_TIMER
-+ bool "Timer for the STARFIVE SoCs"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ select TIMER_OF
-+ select CLKSRC_MMIO
-+ default ARCH_STARFIVE
-+ help
-+ This enables the timer for StarFive SoCs. On RISC-V platform,
-+ the system has started RISCV_TIMER. But you can also use this timer
-+ to do a lot more on StarFive SoCs. This timer can provide high
-+ precision and four channels to use in JH7110 SoC.
-+
- config CLINT_TIMER
- bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
- depends on GENERIC_SCHED_CLOCK && RISCV
---- a/drivers/clocksource/Makefile
-+++ b/drivers/clocksource/Makefile
-@@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-
- obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
- obj-$(CONFIG_X86_NUMACHIP) += numachip.o
- obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
-+obj-$(CONFIG_STARFIVE_TIMER) += timer-starfive.o
- obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
- obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
- obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
---- /dev/null
-+++ b/drivers/clocksource/timer-starfive.c
-@@ -0,0 +1,390 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Starfive Timer driver
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ *
-+ * Author:
-+ * Xingyu Wu <xingyu.wu@starfivetech.com>
-+ * Samin Guo <samin.guo@starfivetech.com>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clockchips.h>
-+#include <linux/clocksource.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/irq.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+#include <linux/sched_clock.h>
-+
-+#include "timer-starfive.h"
-+
-+static const struct starfive_timer_chan_base starfive_timer_jh7110_base = {
-+ .ctrl = STARFIVE_TIMER_JH7110_CTL,
-+ .load = STARFIVE_TIMER_JH7110_LOAD,
-+ .enable = STARFIVE_TIMER_JH7110_ENABLE,
-+ .reload = STARFIVE_TIMER_JH7110_RELOAD,
-+ .value = STARFIVE_TIMER_JH7110_VALUE,
-+ .intclr = STARFIVE_TIMER_JH7110_INT_CLR,
-+ .intmask = STARFIVE_TIMER_JH7110_INT_MASK,
-+ .channel_num = STARFIVE_TIMER_CH_4,
-+ .channel_base = {STARFIVE_TIMER_CH_BASE(0), STARFIVE_TIMER_CH_BASE(1),
-+ STARFIVE_TIMER_CH_BASE(2), STARFIVE_TIMER_CH_BASE(3)},
-+};
-+
-+static inline struct starfive_clkevt *to_starfive_clkevt(struct clock_event_device *evt)
-+{
-+ return container_of(evt, struct starfive_clkevt, evt);
-+}
-+
-+/* 0:continuous-run mode, 1:single-run mode */
-+static inline void starfive_timer_set_mod(struct starfive_clkevt *clkevt, int mod)
-+{
-+ writel(mod, clkevt->ctrl);
-+}
-+
-+/* Interrupt Mask Register, 0:Unmask, 1:Mask */
-+static inline void starfive_timer_int_enable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_INTMASK_DIS, clkevt->intmask);
-+}
-+
-+static inline void starfive_timer_int_disable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_INTMASK_ENA, clkevt->intmask);
-+}
-+
-+/*
-+ * BIT(0): Read value represent channel intr status.
-+ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
-+ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
-+ */
-+static inline int starfive_timer_int_clear(struct starfive_clkevt *clkevt)
-+{
-+ u32 value;
-+ int ret;
-+
-+ /* waiting interrupt can be to clearing */
-+ ret = readl_poll_timeout_atomic(clkevt->intclr, value,
-+ !(value & STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK),
-+ STARFIVE_DELAY_US, STARFIVE_TIMEOUT_US);
-+ if (!ret)
-+ writel(0x1, clkevt->intclr);
-+
-+ return ret;
-+}
-+
-+/*
-+ * The initial value to be loaded into the
-+ * counter and is also used as the reload value.
-+ * val = clock rate --> 1s
-+ */
-+static inline void starfive_timer_set_load(struct starfive_clkevt *clkevt, u32 val)
-+{
-+ writel(val, clkevt->load);
-+}
-+
-+static inline u32 starfive_timer_get_val(struct starfive_clkevt *clkevt)
-+{
-+ return readl(clkevt->value);
-+}
-+
-+/*
-+ * Write RELOAD register to reload preset value to counter.
-+ * (Write 0 and write 1 are both ok)
-+ */
-+static inline void starfive_timer_set_reload(struct starfive_clkevt *clkevt)
-+{
-+ writel(0, clkevt->reload);
-+}
-+
-+static inline void starfive_timer_enable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_ENA, clkevt->enable);
-+}
-+
-+static inline void starfive_timer_disable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_DIS, clkevt->enable);
-+}
-+
-+static int starfive_timer_int_init_enable(struct starfive_clkevt *clkevt)
-+{
-+ int ret;
-+
-+ starfive_timer_int_disable(clkevt);
-+ ret = starfive_timer_int_clear(clkevt);
-+ if (ret)
-+ return ret;
-+
-+ starfive_timer_int_enable(clkevt);
-+ starfive_timer_enable(clkevt);
-+
-+ return 0;
-+}
-+
-+static int starfive_timer_shutdown(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ return starfive_timer_int_clear(clkevt);
-+}
-+
-+static void starfive_timer_suspend(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ clkevt->reload_val = starfive_timer_get_val(clkevt);
-+ starfive_timer_shutdown(evt);
-+}
-+
-+static void starfive_timer_resume(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_set_load(clkevt, clkevt->reload_val);
-+ starfive_timer_set_reload(clkevt);
-+ starfive_timer_int_enable(clkevt);
-+ starfive_timer_enable(clkevt);
-+}
-+
-+static int starfive_timer_tick_resume(struct clock_event_device *evt)
-+{
-+ starfive_timer_resume(evt);
-+
-+ return 0;
-+}
-+
-+static int starfive_clocksource_init(struct starfive_clkevt *clkevt)
-+{
-+ int ret;
-+
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
-+ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
-+ ret = starfive_timer_int_init_enable(clkevt);
-+ if (ret)
-+ return ret;
-+
-+ return clocksource_mmio_init(clkevt->value, clkevt->name, clkevt->rate,
-+ STARFIVE_CLOCK_SOURCE_RATING, STARFIVE_VALID_BITS,
-+ clocksource_mmio_readl_down);
-+}
-+
-+/* IRQ handler for the timer */
-+static irqreturn_t starfive_timer_interrupt(int irq, void *priv)
-+{
-+ struct clock_event_device *evt = (struct clock_event_device *)priv;
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ if (starfive_timer_int_clear(clkevt))
-+ return IRQ_NONE;
-+
-+ if (evt->event_handler)
-+ evt->event_handler(evt);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int starfive_timer_set_periodic(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
-+ starfive_timer_set_load(clkevt, clkevt->periodic);
-+
-+ return starfive_timer_int_init_enable(clkevt);
-+}
-+
-+static int starfive_timer_set_oneshot(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
-+ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
-+
-+ return starfive_timer_int_init_enable(clkevt);
-+}
-+
-+static int starfive_timer_set_next_event(unsigned long next,
-+ struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
-+ starfive_timer_set_load(clkevt, next);
-+ starfive_timer_enable(clkevt);
-+
-+ return 0;
-+}
-+
-+static void starfive_set_clockevent(struct clock_event_device *evt)
-+{
-+ evt->features = CLOCK_EVT_FEAT_PERIODIC |
-+ CLOCK_EVT_FEAT_ONESHOT |
-+ CLOCK_EVT_FEAT_DYNIRQ;
-+ evt->set_state_shutdown = starfive_timer_shutdown;
-+ evt->set_state_periodic = starfive_timer_set_periodic;
-+ evt->set_state_oneshot = starfive_timer_set_oneshot;
-+ evt->set_state_oneshot_stopped = starfive_timer_shutdown;
-+ evt->tick_resume = starfive_timer_tick_resume;
-+ evt->set_next_event = starfive_timer_set_next_event;
-+ evt->suspend = starfive_timer_suspend;
-+ evt->resume = starfive_timer_resume;
-+ evt->rating = STARFIVE_CLOCKEVENT_RATING;
-+}
-+
-+static void starfive_clockevents_register(struct starfive_clkevt *clkevt)
-+{
-+ clkevt->rate = clk_get_rate(clkevt->clk);
-+ clkevt->periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
-+
-+ starfive_set_clockevent(&clkevt->evt);
-+ clkevt->evt.name = clkevt->name;
-+ clkevt->evt.irq = clkevt->irq;
-+ clkevt->evt.cpumask = cpu_possible_mask;
-+
-+ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
-+ STARFIVE_TIMER_MIN_TICKS, STARFIVE_TIMER_MAX_TICKS);
-+}
-+
-+static void __init starfive_clkevt_base_init(const struct starfive_timer_chan_base *timer,
-+ struct starfive_clkevt *clkevt,
-+ void __iomem *base, int ch)
-+{
-+ void __iomem *channel_base;
-+
-+ channel_base = base + timer->channel_base[ch];
-+ clkevt->base = channel_base;
-+ clkevt->ctrl = channel_base + timer->ctrl;
-+ clkevt->load = channel_base + timer->load;
-+ clkevt->enable = channel_base + timer->enable;
-+ clkevt->reload = channel_base + timer->reload;
-+ clkevt->value = channel_base + timer->value;
-+ clkevt->intclr = channel_base + timer->intclr;
-+ clkevt->intmask = channel_base + timer->intmask;
-+}
-+
-+static int __init starfive_timer_probe(struct platform_device *pdev)
-+{
-+ const struct starfive_timer_chan_base *timer_base = of_device_get_match_data(&pdev->dev);
-+ char name[10];
-+ struct starfive_timer_priv *priv;
-+ struct starfive_clkevt *clkevt;
-+ struct clk *pclk;
-+ struct reset_control *rst;
-+ int ch;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, clkevt, timer_base->channel_num),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->base),
-+ "failed to map registers\n");
-+
-+ rst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
-+ if (IS_ERR(rst))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(rst), "failed to get apb reset\n");
-+
-+ pclk = devm_clk_get_enabled(&pdev->dev, "apb");
-+ if (IS_ERR(pclk))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
-+ "failed to get & enable apb clock\n");
-+
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ goto err;
-+
-+ priv->dev = &pdev->dev;
-+ platform_set_drvdata(pdev, priv);
-+
-+ for (ch = 0; ch < timer_base->channel_num; ch++) {
-+ clkevt = &priv->clkevt[ch];
-+ snprintf(name, sizeof(name), "ch%d", ch);
-+
-+ starfive_clkevt_base_init(timer_base, clkevt, priv->base, ch);
-+ /* Ensure timers are disabled */
-+ starfive_timer_disable(clkevt);
-+
-+ rst = devm_reset_control_get_exclusive(&pdev->dev, name);
-+ if (IS_ERR(rst)) {
-+ ret = PTR_ERR(rst);
-+ goto err;
-+ }
-+
-+ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
-+ if (IS_ERR(clkevt->clk)) {
-+ ret = PTR_ERR(clkevt->clk);
-+ goto err;
-+ }
-+
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ goto ch_err;
-+
-+ clkevt->irq = platform_get_irq(pdev, ch);
-+ if (clkevt->irq < 0) {
-+ ret = clkevt->irq;
-+ goto ch_err;
-+ }
-+
-+ snprintf(clkevt->name, sizeof(clkevt->name), "%s.ch%d", pdev->name, ch);
-+ starfive_clockevents_register(clkevt);
-+
-+ ret = devm_request_irq(&pdev->dev, clkevt->irq, starfive_timer_interrupt,
-+ IRQF_TIMER | IRQF_IRQPOLL,
-+ clkevt->name, &clkevt->evt);
-+ if (ret)
-+ goto ch_err;
-+
-+ ret = starfive_clocksource_init(clkevt);
-+ if (ret)
-+ goto ch_err;
-+ }
-+
-+ return 0;
-+
-+ch_err:
-+ /* Only unregister the failed channel and the rest timer channels continue to work. */
-+ clk_disable_unprepare(clkevt->clk);
-+err:
-+ /* If no other channel successfully registers, pclk should be disabled. */
-+ if (!ch)
-+ clk_disable_unprepare(pclk);
-+
-+ return ret;
-+}
-+
-+static const struct of_device_id starfive_timer_match[] = {
-+ { .compatible = "starfive,jh7110-timer", .data = &starfive_timer_jh7110_base },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_timer_match);
-+
-+static struct platform_driver starfive_timer_driver = {
-+ .probe = starfive_timer_probe,
-+ .driver = {
-+ .name = "starfive-timer",
-+ .of_match_table = starfive_timer_match,
-+ },
-+};
-+module_platform_driver(starfive_timer_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive timer driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/clocksource/timer-starfive.h
-@@ -0,0 +1,96 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __STARFIVE_TIMER_H__
-+#define __STARFIVE_TIMER_H__
-+
-+/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
-+#define STARFIVE_TIMER_CH_LEN 0x40
-+#define STARFIVE_TIMER_CH_BASE(x) ((STARFIVE_TIMER_CH_##x) * STARFIVE_TIMER_CH_LEN)
-+
-+#define STARFIVE_CLOCK_SOURCE_RATING 200
-+#define STARFIVE_VALID_BITS 32
-+#define STARFIVE_DELAY_US 0
-+#define STARFIVE_TIMEOUT_US 10000
-+#define STARFIVE_CLOCKEVENT_RATING 300
-+#define STARFIVE_TIMER_MAX_TICKS 0xffffffff
-+#define STARFIVE_TIMER_MIN_TICKS 0xf
-+
-+#define STARFIVE_TIMER_JH7110_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
-+#define STARFIVE_TIMER_JH7110_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
-+#define STARFIVE_TIMER_JH7110_LOAD 0x08 /* RW: load value to counter */
-+#define STARFIVE_TIMER_JH7110_ENABLE 0x10 /* RW[0]: timer enable register */
-+#define STARFIVE_TIMER_JH7110_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
-+#define STARFIVE_TIMER_JH7110_VALUE 0x18 /* RO: timer value register */
-+#define STARFIVE_TIMER_JH7110_INT_CLR 0x20 /* RW: timer interrupt clear register */
-+#define STARFIVE_TIMER_JH7110_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
-+#define STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK BIT(1)
-+
-+enum STARFIVE_TIMER_CH {
-+ STARFIVE_TIMER_CH_0 = 0,
-+ STARFIVE_TIMER_CH_1,
-+ STARFIVE_TIMER_CH_2,
-+ STARFIVE_TIMER_CH_3,
-+ STARFIVE_TIMER_CH_4,
-+ STARFIVE_TIMER_CH_5,
-+ STARFIVE_TIMER_CH_6,
-+ STARFIVE_TIMER_CH_7,
-+ STARFIVE_TIMER_CH_MAX
-+};
-+
-+enum STARFIVE_TIMER_INTMASK {
-+ STARFIVE_TIMER_INTMASK_DIS = 0,
-+ STARFIVE_TIMER_INTMASK_ENA = 1
-+};
-+
-+enum STARFIVE_TIMER_MOD {
-+ STARFIVE_TIMER_MOD_CONTIN = 0,
-+ STARFIVE_TIMER_MOD_SINGLE = 1
-+};
-+
-+enum STARFIVE_TIMER_CTL_EN {
-+ STARFIVE_TIMER_DIS = 0,
-+ STARFIVE_TIMER_ENA = 1
-+};
-+
-+struct starfive_timer_chan_base {
-+ /* Resgister */
-+ unsigned int ctrl;
-+ unsigned int load;
-+ unsigned int enable;
-+ unsigned int reload;
-+ unsigned int value;
-+ unsigned int intclr;
-+ unsigned int intmask;
-+
-+ unsigned int channel_num; /* timer channel numbers */
-+ unsigned int channel_base[];
-+};
-+
-+struct starfive_clkevt {
-+ struct clock_event_device evt;
-+ struct clk *clk;
-+ char name[20];
-+ int irq;
-+ u32 periodic;
-+ u32 rate;
-+ u32 reload_val;
-+ void __iomem *base;
-+ void __iomem *ctrl;
-+ void __iomem *load;
-+ void __iomem *enable;
-+ void __iomem *reload;
-+ void __iomem *value;
-+ void __iomem *intclr;
-+ void __iomem *intmask;
-+};
-+
-+struct starfive_timer_priv {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct starfive_clkevt clkevt[];
-+};
-+
-+#endif /* __STARFIVE_TIMER_H__ */
diff --git a/target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch b/target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
deleted file mode 100644
index 58f29cda8f..0000000000
--- a/target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 16214121afaadb8ae9aaf73351e874405eb47c15 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Tue, 25 Apr 2023 18:51:15 +0800
-Subject: [PATCH 061/122] dt-bindings: net: motorcomm: Add pad driver strength
- cfg
-
-The motorcomm phy (YT8531) supports the ability to adjust the drive
-strength of the rx_clk/rx_data, the value range of pad driver
-strength is 0 to 7.
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../devicetree/bindings/net/motorcomm,yt8xxx.yaml | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-@@ -62,6 +62,18 @@ properties:
- for a timer.
- type: boolean
-
-+ motorcomm,rx-clk-driver-strength:
-+ description: drive strength of rx_clk pad.
-+ $ref: /schemas/types.yaml#/definitions/uint32
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
-+ motorcomm,rx-data-driver-strength:
-+ description: drive strength of rx_data/rx_ctl rgmii pad.
-+ $ref: /schemas/types.yaml#/definitions/uint32
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
- motorcomm,tx-clk-adj-enabled:
- description: |
- This configuration is mainly to adapt to VF2 with JH7110 SoC.
diff --git a/target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch b/target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch
deleted file mode 100644
index 20546650a3..0000000000
--- a/target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 99f0bf43994dada29e33fd8718fd25484634da3a Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Tue, 21 Mar 2023 13:52:27 +0800
-Subject: [PATCH 062/122] dt-bindings: PWM: Add StarFive PWM module
-
-Add documentation to describe StarFive Pulse Width Modulation
-controller driver.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
----
- .../bindings/pwm/starfive,jh7110-pwm.yaml | 53 +++++++++++++++++++
- 1 file changed, 53 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pwm/starfive,jh7110-pwm.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pwm/starfive,jh7110-pwm.yaml
-@@ -0,0 +1,53 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pwm/starfive,jh7110-pwm.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive PWM controller
-+
-+maintainers:
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+description:
-+ StarFive SoCs contain PWM and when operating in PWM mode, the PTC core generates
-+ binary signal with user-programmable low and high periods. Clock source for the
-+ PWM can be either system clockor external clock. Each PWM timer block provides 8
-+ PWM channels.
-+
-+allOf:
-+ - $ref: pwm.yaml#
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pwm
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ "#pwm-cells":
-+ const: 3
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - resets
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pwm@120d0000 {
-+ compatible = "starfive,jh7110-pwm";
-+ reg = <0x120d0000 0x10000>;
-+ clocks = <&syscrg 121>;
-+ resets = <&syscrg 108>;
-+ #pwm-cells = <3>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch b/target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch
deleted file mode 100644
index 0433160a20..0000000000
--- a/target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From fddea961e7ce1f26dd549e3d92ede624246690c0 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Tue, 21 Mar 2023 13:52:28 +0800
-Subject: [PATCH 063/122] pwm: starfive: Add PWM driver support
-
-Add Pulse Width Modulation driver support for StarFive
-JH7110 soc.
-
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- drivers/pwm/Kconfig | 10 ++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-starfive-ptc.c | 245 +++++++++++++++++++++++++++++++++
- 3 files changed, 256 insertions(+)
- create mode 100644 drivers/pwm/pwm-starfive-ptc.c
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -536,6 +536,16 @@ config PWM_SPRD
- To compile this driver as a module, choose M here: the module
- will be called pwm-sprd.
-
-+config PWM_STARFIVE_PTC
-+ tristate "StarFive PWM PTC support"
-+ depends on OF
-+ depends on COMMON_CLK
-+ help
-+ Generic PWM framework driver for StarFive SoCs.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-starfive-ptc.
-+
- config PWM_STI
- tristate "STiH4xx PWM support"
- depends on ARCH_STI || COMPILE_TEST
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -49,6 +49,7 @@ obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
- obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
- obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
- obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
-+obj-$(CONFIG_PWM_STARFIVE_PTC) += pwm-starfive-ptc.o
- obj-$(CONFIG_PWM_STI) += pwm-sti.o
- obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
- obj-$(CONFIG_PWM_STM32_LP) += pwm-stm32-lp.o
---- /dev/null
-+++ b/drivers/pwm/pwm-starfive-ptc.c
-@@ -0,0 +1,245 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * PWM driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2018 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <dt-bindings/pwm/pwm.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/slab.h>
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <linux/io.h>
-+
-+/* how many parameters can be transferred to ptc */
-+#define OF_PWM_N_CELLS 3
-+
-+/* PTC Register offsets */
-+#define REG_RPTC_CNTR 0x0
-+#define REG_RPTC_HRC 0x4
-+#define REG_RPTC_LRC 0x8
-+#define REG_RPTC_CTRL 0xC
-+
-+/* Bit for PWM clock */
-+#define BIT_PWM_CLOCK_EN 31
-+
-+/* Bit for clock gen soft reset */
-+#define BIT_CLK_GEN_SOFT_RESET 13
-+
-+#define NS_PER_SECOND 1000000000
-+
-+/*
-+ * Access PTC register (cntr hrc lrc and ctrl),
-+ * need to replace PWM_BASE_ADDR
-+ */
-+#define REG_PTC_BASE_ADDR_SUB(base, N) \
-+((base) + (((N) > 3) ? (((N) % 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
-+#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
-+#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
-+#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
-+#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
-+
-+/* PTC_RPTC_CTRL */
-+#define PTC_EN BIT(0)
-+#define PTC_ECLK BIT(1)
-+#define PTC_NEC BIT(2)
-+#define PTC_OE BIT(3)
-+#define PTC_SIGNLE BIT(4)
-+#define PTC_INTE BIT(5)
-+#define PTC_INT BIT(6)
-+#define PTC_CNTRRST BIT(7)
-+#define PTC_CAPTE BIT(8)
-+
-+struct starfive_pwm_ptc_device {
-+ struct pwm_chip chip;
-+ struct clk *clk;
-+ struct reset_control *rst;
-+ void __iomem *regs;
-+ int irq;
-+ unsigned int approx_freq;/*pwm apb clock frequency*/
-+};
-+
-+static inline
-+struct starfive_pwm_ptc_device *chip_to_starfive_ptc(struct pwm_chip *c)
-+{
-+ return container_of(c, struct starfive_pwm_ptc_device, chip);
-+}
-+
-+static int starfive_pwm_ptc_get_state(struct pwm_chip *chip,
-+ struct pwm_device *dev,
-+ struct pwm_state *state)
-+{
-+ struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
-+ u32 data_lrc, data_hrc;
-+ u32 pwm_clk_ns = 0;
-+
-+ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
-+ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
-+
-+ pwm_clk_ns = NS_PER_SECOND / pwm->approx_freq;
-+
-+ state->period = data_lrc * pwm_clk_ns;
-+ state->duty_cycle = data_hrc * pwm_clk_ns;
-+ state->polarity = PWM_POLARITY_NORMAL;
-+ state->enabled = 1;
-+
-+ return 0;
-+}
-+
-+static int starfive_pwm_ptc_apply(struct pwm_chip *chip,
-+ struct pwm_device *dev,
-+ struct pwm_state *state)
-+{
-+ struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
-+ u32 data_hrc = 0;
-+ u32 data_lrc = 0;
-+ u32 period_data = 0;
-+ u32 duty_data = 0;
-+ s64 multi = pwm->approx_freq;
-+ s64 div = NS_PER_SECOND;
-+ void __iomem *reg_addr;
-+
-+ if (state->duty_cycle > state->period)
-+ state->duty_cycle = state->period;
-+
-+ while (multi % 10 == 0 && div % 10 == 0 && multi > 0 && div > 0) {
-+ multi /= 10;
-+ div /= 10;
-+ }
-+
-+ period_data = (u32)(state->period * multi / div);
-+ if (abs(period_data * div / multi - state->period)
-+ > abs((period_data + 1) * div / multi - state->period) ||
-+ (state->period > 0 && period_data == 0))
-+ period_data += 1;
-+
-+ if (state->enabled) {
-+ duty_data = (u32)(state->duty_cycle * multi / div);
-+ if (abs(duty_data * div / multi - state->duty_cycle)
-+ > abs((duty_data + 1) * div / multi - state->duty_cycle) ||
-+ (state->duty_cycle > 0 && duty_data == 0))
-+ duty_data += 1;
-+ } else {
-+ duty_data = 0;
-+ }
-+
-+ if (state->polarity == PWM_POLARITY_NORMAL)
-+ data_hrc = period_data - duty_data;
-+ else
-+ data_hrc = duty_data;
-+
-+ data_lrc = period_data;
-+
-+ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
-+ iowrite32(data_hrc, reg_addr);
-+
-+ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
-+ iowrite32(data_lrc, reg_addr);
-+
-+ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
-+ iowrite32(0, reg_addr);
-+
-+ reg_addr = REG_PTC_RPTC_CTRL(pwm->regs, dev->hwpwm);
-+ iowrite32(PTC_EN | PTC_OE, reg_addr);
-+
-+ return 0;
-+}
-+
-+static const struct pwm_ops starfive_pwm_ptc_ops = {
-+ .get_state = starfive_pwm_ptc_get_state,
-+ .apply = (void *)starfive_pwm_ptc_apply,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int starfive_pwm_ptc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct starfive_pwm_ptc_device *pwm;
-+ struct pwm_chip *chip;
-+ int ret;
-+
-+ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
-+ if (!pwm)
-+ return -ENOMEM;
-+
-+ chip = &pwm->chip;
-+ chip->dev = dev;
-+ chip->ops = &starfive_pwm_ptc_ops;
-+ chip->npwm = 8;
-+
-+ chip->of_pwm_n_cells = OF_PWM_N_CELLS;
-+ chip->base = -1;
-+
-+ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(pwm->regs))
-+ return dev_err_probe(dev, PTR_ERR(pwm->regs),
-+ "Unable to map IO resources\n");
-+
-+ pwm->clk = devm_clk_get(dev, NULL);
-+ if (IS_ERR(pwm->clk))
-+ return dev_err_probe(dev, PTR_ERR(pwm->clk),
-+ "Unable to get pwm clock\n");
-+
-+ pwm->rst = devm_reset_control_get_exclusive(dev, NULL);
-+ if (IS_ERR(pwm->rst))
-+ return dev_err_probe(dev, PTR_ERR(pwm->rst),
-+ "Unable to get pwm reset\n");
-+
-+ ret = clk_prepare_enable(pwm->clk);
-+ if (ret) {
-+ dev_err(dev,
-+ "Failed to enable pwm clock, %d\n", ret);
-+ return ret;
-+ }
-+
-+ reset_control_deassert(pwm->rst);
-+
-+ pwm->approx_freq = (unsigned int)clk_get_rate(pwm->clk);
-+ if (!pwm->approx_freq)
-+ dev_err(dev, "get pwm apb clock rate failed.\n");
-+
-+ ret = devm_pwmchip_add(dev, chip);
-+ if (ret < 0) {
-+ dev_err(dev, "cannot register PTC: %d\n", ret);
-+ clk_disable_unprepare(pwm->clk);
-+ return ret;
-+ }
-+
-+ platform_set_drvdata(pdev, pwm);
-+
-+ return 0;
-+}
-+
-+static int starfive_pwm_ptc_remove(struct platform_device *dev)
-+{
-+ struct starfive_pwm_ptc_device *pwm = platform_get_drvdata(dev);
-+ struct pwm_chip *chip = &pwm->chip;
-+
-+ pwmchip_remove(chip);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id starfive_pwm_ptc_of_match[] = {
-+ { .compatible = "starfive,jh7110-pwm" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, starfive_pwm_ptc_of_match);
-+
-+static struct platform_driver starfive_pwm_ptc_driver = {
-+ .probe = starfive_pwm_ptc_probe,
-+ .remove = starfive_pwm_ptc_remove,
-+ .driver = {
-+ .name = "pwm-starfive-ptc",
-+ .of_match_table = starfive_pwm_ptc_of_match,
-+ },
-+};
-+module_platform_driver(starfive_pwm_ptc_driver);
-+
-+MODULE_AUTHOR("Jenny Zhang <jenny.zhang@starfivetech.com>");
-+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive PWM PTC driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch b/target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch
deleted file mode 100644
index 09b2dccef9..0000000000
--- a/target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 207dde3ed123613cd84c8f706a24d75cefece67c Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Mon, 15 May 2023 20:53:52 +0800
-Subject: [PATCH 064/122] dt-bindings: crypto: Add StarFive crypto module
-
-Add documentation to describe StarFive cryptographic engine.
-
-Co-developed-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- .../crypto/starfive,jh7110-crypto.yaml | 70 +++++++++++++++++++
- 1 file changed, 70 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml
-@@ -0,0 +1,70 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/crypto/starfive,jh7110-crypto.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive Cryptographic Module
-+
-+maintainers:
-+ - Jia Jie Ho <jiajie.ho@starfivetech.com>
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-crypto
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Hardware reference clock
-+ - description: AHB reference clock
-+
-+ clock-names:
-+ items:
-+ - const: hclk
-+ - const: ahb
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ dmas:
-+ items:
-+ - description: TX DMA channel
-+ - description: RX DMA channel
-+
-+ dma-names:
-+ items:
-+ - const: tx
-+ - const: rx
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - dmas
-+ - dma-names
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ crypto: crypto@16000000 {
-+ compatible = "starfive,jh7110-crypto";
-+ reg = <0x16000000 0x4000>;
-+ clocks = <&clk 15>, <&clk 16>;
-+ clock-names = "hclk", "ahb";
-+ interrupts = <28>;
-+ resets = <&reset 3>;
-+ dmas = <&dma 1 2>,
-+ <&dma 0 2>;
-+ dma-names = "tx", "rx";
-+ };
-+...
diff --git a/target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch b/target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch
deleted file mode 100644
index 5aa3bc10f6..0000000000
--- a/target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch
+++ /dev/null
@@ -1,337 +0,0 @@
-From 8b1069fcc1dbb524556d851f3dedf0629a71f17b Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Mon, 15 May 2023 20:53:53 +0800
-Subject: [PATCH 065/122] crypto: starfive - Add crypto engine support
-
-Adding device probe and DMA init for StarFive cryptographic module.
-
-Co-developed-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- drivers/crypto/Kconfig | 1 +
- drivers/crypto/Makefile | 1 +
- drivers/crypto/starfive/Kconfig | 17 +++
- drivers/crypto/starfive/Makefile | 4 +
- drivers/crypto/starfive/jh7110-cryp.c | 201 ++++++++++++++++++++++++++
- drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++
- 6 files changed, 287 insertions(+)
- create mode 100644 drivers/crypto/starfive/Kconfig
- create mode 100644 drivers/crypto/starfive/Makefile
- create mode 100644 drivers/crypto/starfive/jh7110-cryp.c
- create mode 100644 drivers/crypto/starfive/jh7110-cryp.h
-
---- a/drivers/crypto/Kconfig
-+++ b/drivers/crypto/Kconfig
-@@ -823,5 +823,6 @@ config CRYPTO_DEV_SA2UL
-
- source "drivers/crypto/keembay/Kconfig"
- source "drivers/crypto/aspeed/Kconfig"
-+source "drivers/crypto/starfive/Kconfig"
-
- endif # CRYPTO_HW
---- a/drivers/crypto/Makefile
-+++ b/drivers/crypto/Makefile
-@@ -53,3 +53,4 @@ obj-y += xilinx/
- obj-y += hisilicon/
- obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
- obj-y += keembay/
-+obj-y += starfive/
---- /dev/null
-+++ b/drivers/crypto/starfive/Kconfig
-@@ -0,0 +1,17 @@
-+#
-+# StarFive crypto drivers configuration
-+#
-+
-+config CRYPTO_DEV_JH7110
-+ tristate "StarFive JH7110 cryptographic engine driver"
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ select CRYPTO_ENGINE
-+ select ARM_AMBA
-+ select DMADEVICES
-+ select AMBA_PL08X
-+ help
-+ Support for StarFive JH7110 crypto hardware acceleration engine.
-+ This module provides acceleration for public key algo,
-+ skciphers, AEAD and hash functions.
-+
-+ If you choose 'M' here, this module will be called jh7110-crypto.
---- /dev/null
-+++ b/drivers/crypto/starfive/Makefile
-@@ -0,0 +1,4 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o
-+jh7110-crypto-objs := jh7110-cryp.o
---- /dev/null
-+++ b/drivers/crypto/starfive/jh7110-cryp.c
-@@ -0,0 +1,201 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Cryptographic API.
-+ *
-+ * Support for StarFive hardware cryptographic engine.
-+ * Copyright (c) 2022 StarFive Technology
-+ *
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#include "jh7110-cryp.h"
-+
-+#define DRIVER_NAME "jh7110-crypto"
-+
-+struct starfive_dev_list {
-+ struct list_head dev_list;
-+ spinlock_t lock; /* protect dev_list */
-+};
-+
-+static struct starfive_dev_list dev_list = {
-+ .dev_list = LIST_HEAD_INIT(dev_list.dev_list),
-+ .lock = __SPIN_LOCK_UNLOCKED(dev_list.lock),
-+};
-+
-+struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx)
-+{
-+ struct starfive_cryp_dev *cryp = NULL, *tmp;
-+
-+ spin_lock_bh(&dev_list.lock);
-+ if (!ctx->cryp) {
-+ list_for_each_entry(tmp, &dev_list.dev_list, list) {
-+ cryp = tmp;
-+ break;
-+ }
-+ ctx->cryp = cryp;
-+ } else {
-+ cryp = ctx->cryp;
-+ }
-+
-+ spin_unlock_bh(&dev_list.lock);
-+
-+ return cryp;
-+}
-+
-+static int starfive_dma_init(struct starfive_cryp_dev *cryp)
-+{
-+ dma_cap_mask_t mask;
-+
-+ dma_cap_zero(mask);
-+ dma_cap_set(DMA_SLAVE, mask);
-+
-+ cryp->tx = dma_request_chan(cryp->dev, "tx");
-+ if (IS_ERR(cryp->tx))
-+ return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx),
-+ "Error requesting tx dma channel.\n");
-+
-+ cryp->rx = dma_request_chan(cryp->dev, "rx");
-+ if (IS_ERR(cryp->rx)) {
-+ dma_release_channel(cryp->tx);
-+ return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx),
-+ "Error requesting rx dma channel.\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp)
-+{
-+ dma_release_channel(cryp->tx);
-+ dma_release_channel(cryp->rx);
-+}
-+
-+static int starfive_cryp_probe(struct platform_device *pdev)
-+{
-+ struct starfive_cryp_dev *cryp;
-+ struct resource *res;
-+ int ret;
-+
-+ cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL);
-+ if (!cryp)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, cryp);
-+ cryp->dev = &pdev->dev;
-+
-+ cryp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(cryp->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base),
-+ "Error remapping memory for platform device\n");
-+
-+ cryp->phys_base = res->start;
-+ cryp->dma_maxburst = 32;
-+
-+ cryp->hclk = devm_clk_get(&pdev->dev, "hclk");
-+ if (IS_ERR(cryp->hclk))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->hclk),
-+ "Error getting hardware reference clock\n");
-+
-+ cryp->ahb = devm_clk_get(&pdev->dev, "ahb");
-+ if (IS_ERR(cryp->ahb))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->ahb),
-+ "Error getting ahb reference clock\n");
-+
-+ cryp->rst = devm_reset_control_get_shared(cryp->dev, NULL);
-+ if (IS_ERR(cryp->rst))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
-+ "Error getting hardware reset line\n");
-+
-+ clk_prepare_enable(cryp->hclk);
-+ clk_prepare_enable(cryp->ahb);
-+ reset_control_deassert(cryp->rst);
-+
-+ spin_lock(&dev_list.lock);
-+ list_add(&cryp->list, &dev_list.dev_list);
-+ spin_unlock(&dev_list.lock);
-+
-+ ret = starfive_dma_init(cryp);
-+ if (ret) {
-+ if (ret == -EPROBE_DEFER)
-+ goto err_probe_defer;
-+ else
-+ goto err_dma_init;
-+ }
-+
-+ /* Initialize crypto engine */
-+ cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1);
-+ if (!cryp->engine) {
-+ ret = -ENOMEM;
-+ goto err_engine;
-+ }
-+
-+ ret = crypto_engine_start(cryp->engine);
-+ if (ret)
-+ goto err_engine_start;
-+
-+ return 0;
-+
-+err_engine_start:
-+ crypto_engine_exit(cryp->engine);
-+err_engine:
-+ starfive_dma_cleanup(cryp);
-+err_dma_init:
-+ spin_lock(&dev_list.lock);
-+ list_del(&cryp->list);
-+ spin_unlock(&dev_list.lock);
-+
-+ clk_disable_unprepare(cryp->hclk);
-+ clk_disable_unprepare(cryp->ahb);
-+ reset_control_assert(cryp->rst);
-+err_probe_defer:
-+ return ret;
-+}
-+
-+static int starfive_cryp_remove(struct platform_device *pdev)
-+{
-+ struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);
-+
-+ crypto_engine_stop(cryp->engine);
-+ crypto_engine_exit(cryp->engine);
-+
-+ starfive_dma_cleanup(cryp);
-+
-+ spin_lock(&dev_list.lock);
-+ list_del(&cryp->list);
-+ spin_unlock(&dev_list.lock);
-+
-+ clk_disable_unprepare(cryp->hclk);
-+ clk_disable_unprepare(cryp->ahb);
-+ reset_control_assert(cryp->rst);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id starfive_dt_ids[] __maybe_unused = {
-+ { .compatible = "starfive,jh7110-crypto", .data = NULL},
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, starfive_dt_ids);
-+
-+static struct platform_driver starfive_cryp_driver = {
-+ .probe = starfive_cryp_probe,
-+ .remove = starfive_cryp_remove,
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ .of_match_table = starfive_dt_ids,
-+ },
-+};
-+
-+module_platform_driver(starfive_cryp_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("StarFive JH7110 Cryptographic Module");
---- /dev/null
-+++ b/drivers/crypto/starfive/jh7110-cryp.h
-@@ -0,0 +1,63 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __STARFIVE_STR_H__
-+#define __STARFIVE_STR_H__
-+
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmaengine.h>
-+
-+#include <crypto/engine.h>
-+
-+#define STARFIVE_ALG_CR_OFFSET 0x0
-+#define STARFIVE_ALG_FIFO_OFFSET 0x4
-+#define STARFIVE_IE_MASK_OFFSET 0x8
-+#define STARFIVE_IE_FLAG_OFFSET 0xc
-+#define STARFIVE_DMA_IN_LEN_OFFSET 0x10
-+#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14
-+
-+#define STARFIVE_MSG_BUFFER_SIZE SZ_16K
-+
-+union starfive_alg_cr {
-+ u32 v;
-+ struct {
-+ u32 start :1;
-+ u32 aes_dma_en :1;
-+ u32 rsvd_0 :1;
-+ u32 hash_dma_en :1;
-+ u32 alg_done :1;
-+ u32 rsvd_1 :3;
-+ u32 clear :1;
-+ u32 rsvd_2 :23;
-+ };
-+};
-+
-+struct starfive_cryp_ctx {
-+ struct crypto_engine_ctx enginectx;
-+ struct starfive_cryp_dev *cryp;
-+};
-+
-+struct starfive_cryp_dev {
-+ struct list_head list;
-+ struct device *dev;
-+
-+ struct clk *hclk;
-+ struct clk *ahb;
-+ struct reset_control *rst;
-+
-+ void __iomem *base;
-+ phys_addr_t phys_base;
-+
-+ u32 dma_maxburst;
-+ struct dma_chan *tx;
-+ struct dma_chan *rx;
-+ struct dma_slave_config cfg_in;
-+ struct dma_slave_config cfg_out;
-+
-+ struct crypto_engine *engine;
-+
-+ union starfive_alg_cr alg_cr;
-+};
-+
-+struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch b/target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch
deleted file mode 100644
index fc8e86bad5..0000000000
--- a/target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0d3ee821ed469a787e8007de2d87e98a2370e087 Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Fri, 19 May 2023 21:42:33 +0800
-Subject: [PATCH 066/122] crypto: starfive - Fix driver dependencies
-
-Kconfig updated to depend on DMADEVICES instead of selecting it.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Link: https://lore.kernel.org/oe-kbuild-all/202305191929.Eq4OVZ6D-lkp@intel.com/
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- drivers/crypto/starfive/Kconfig | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/crypto/starfive/Kconfig
-+++ b/drivers/crypto/starfive/Kconfig
-@@ -4,10 +4,9 @@
-
- config CRYPTO_DEV_JH7110
- tristate "StarFive JH7110 cryptographic engine driver"
-- depends on SOC_STARFIVE || COMPILE_TEST
-+ depends on (SOC_STARFIVE || COMPILE_TEST) && DMADEVICES
- select CRYPTO_ENGINE
- select ARM_AMBA
-- select DMADEVICES
- select AMBA_PL08X
- help
- Support for StarFive JH7110 crypto hardware acceleration engine.
diff --git a/target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch b/target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch
deleted file mode 100644
index 2deca609e1..0000000000
--- a/target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From e8d070e2eb856856055566d3515072a8346446f3 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:37:41 -0700
-Subject: [PATCH 067/122] riscv: Kconfig: Add select ARM_AMBA to SOC_STARFIVE
-
-Selects ARM_AMBA platform support for StarFive SoCs required by spi and
-crypto dma engine.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- arch/riscv/Kconfig.socs | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/riscv/Kconfig.socs
-+++ b/arch/riscv/Kconfig.socs
-@@ -4,6 +4,7 @@ config SOC_MICROCHIP_POLARFIRE
- bool "Microchip PolarFire SoCs"
- select MCHP_CLK_MPFS
- select SIFIVE_PLIC
-+ select ARM_AMBA
- help
- This enables support for Microchip PolarFire SoC platforms.
-
diff --git a/target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch b/target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch
deleted file mode 100644
index 41d0a8fe11..0000000000
--- a/target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 3b90e0fb53c31c50e64d2039e30ec25c1d8a8d5c Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Fri, 26 May 2023 22:54:00 +0800
-Subject: [PATCH 068/122] ASoC: dt-bindings: Add TDM controller bindings for
- StarFive JH7110
-
-Add bindings for TDM driver which supports multi-channel audio playback
-and capture on JH7110 platform.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- .../bindings/sound/starfive,jh7110-tdm.yaml | 98 +++++++++++++++++++
- 1 file changed, 98 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml
-@@ -0,0 +1,98 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/sound/starfive,jh7110-tdm.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 TDM Controller
-+
-+description: |
-+ The TDM Controller is a Time Division Multiplexed audio interface
-+ integrated in StarFive JH7110 SoC, allowing up to 8 channels of
-+ audio over a serial interface. The TDM controller can operate both
-+ in master and slave mode.
-+
-+maintainers:
-+ - Walker Chen <walker.chen@starfivetech.com>
-+
-+allOf:
-+ - $ref: dai-common.yaml#
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7110-tdm
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: TDM AHB Clock
-+ - description: TDM APB Clock
-+ - description: TDM Internal Clock
-+ - description: TDM Clock
-+ - description: Inner MCLK
-+ - description: TDM External Clock
-+
-+ clock-names:
-+ items:
-+ - const: tdm_ahb
-+ - const: tdm_apb
-+ - const: tdm_internal
-+ - const: tdm
-+ - const: mclk_inner
-+ - const: tdm_ext
-+
-+ resets:
-+ items:
-+ - description: tdm ahb reset line
-+ - description: tdm apb reset line
-+ - description: tdm core reset line
-+
-+ dmas:
-+ items:
-+ - description: RX DMA Channel
-+ - description: TX DMA Channel
-+
-+ dma-names:
-+ items:
-+ - const: rx
-+ - const: tx
-+
-+ "#sound-dai-cells":
-+ const: 0
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - dmas
-+ - dma-names
-+ - "#sound-dai-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ tdm@10090000 {
-+ compatible = "starfive,jh7110-tdm";
-+ reg = <0x10090000 0x1000>;
-+ clocks = <&syscrg 184>,
-+ <&syscrg 185>,
-+ <&syscrg 186>,
-+ <&syscrg 187>,
-+ <&syscrg 17>,
-+ <&tdm_ext>;
-+ clock-names = "tdm_ahb", "tdm_apb",
-+ "tdm_internal", "tdm",
-+ "mclk_inner", "tdm_ext";
-+ resets = <&syscrg 105>,
-+ <&syscrg 107>,
-+ <&syscrg 106>;
-+ dmas = <&dma 20>, <&dma 21>;
-+ dma-names = "rx","tx";
-+ #sound-dai-cells = <0>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch b/target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch
deleted file mode 100644
index 57ea99d685..0000000000
--- a/target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch
+++ /dev/null
@@ -1,744 +0,0 @@
-From 9d90936b0f69d891001a11d3f6c0c3728d8b6d85 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Fri, 26 May 2023 22:54:01 +0800
-Subject: [PATCH 069/122] ASoC: starfive: Add JH7110 TDM driver
-
-Add tdm driver support for the StarFive JH7110 SoC.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- sound/soc/Kconfig | 1 +
- sound/soc/Makefile | 1 +
- sound/soc/starfive/Kconfig | 15 +
- sound/soc/starfive/Makefile | 2 +
- sound/soc/starfive/jh7110_tdm.c | 679 ++++++++++++++++++++++++++++++++
- 5 files changed, 698 insertions(+)
- create mode 100644 sound/soc/starfive/Kconfig
- create mode 100644 sound/soc/starfive/Makefile
- create mode 100644 sound/soc/starfive/jh7110_tdm.c
-
---- a/sound/soc/Kconfig
-+++ b/sound/soc/Kconfig
-@@ -91,6 +91,7 @@ source "sound/soc/sh/Kconfig"
- source "sound/soc/sof/Kconfig"
- source "sound/soc/spear/Kconfig"
- source "sound/soc/sprd/Kconfig"
-+source "sound/soc/starfive/Kconfig"
- source "sound/soc/sti/Kconfig"
- source "sound/soc/stm/Kconfig"
- source "sound/soc/sunxi/Kconfig"
---- a/sound/soc/Makefile
-+++ b/sound/soc/Makefile
-@@ -59,6 +59,7 @@ obj-$(CONFIG_SND_SOC) += sh/
- obj-$(CONFIG_SND_SOC) += sof/
- obj-$(CONFIG_SND_SOC) += spear/
- obj-$(CONFIG_SND_SOC) += sprd/
-+obj-$(CONFIG_SND_SOC) += starfive/
- obj-$(CONFIG_SND_SOC) += sti/
- obj-$(CONFIG_SND_SOC) += stm/
- obj-$(CONFIG_SND_SOC) += sunxi/
---- /dev/null
-+++ b/sound/soc/starfive/Kconfig
-@@ -0,0 +1,15 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+config SND_SOC_STARFIVE
-+ tristate "Audio support for StarFive SoC"
-+ depends on COMPILE_TEST || ARCH_STARFIVE
-+ help
-+ Say Y or M if you want to add support for codecs attached to
-+ the Starfive SoCs' Audio interfaces. You will also need to
-+ select the audio interfaces to support below.
-+
-+config SND_SOC_JH7110_TDM
-+ tristate "JH7110 TDM device driver"
-+ depends on HAVE_CLK && SND_SOC_STARFIVE
-+ select SND_SOC_GENERIC_DMAENGINE_PCM
-+ help
-+ Say Y or M if you want to add support for StarFive TDM driver.
---- /dev/null
-+++ b/sound/soc/starfive/Makefile
-@@ -0,0 +1,2 @@
-+# StarFive Platform Support
-+obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
---- /dev/null
-+++ b/sound/soc/starfive/jh7110_tdm.c
-@@ -0,0 +1,679 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * jh7110_tdm.c -- StarFive JH7110 TDM driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Walker Chen <walker.chen@starfivetech.com>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/device.h>
-+#include <linux/dmaengine.h>
-+#include <linux/module.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_platform.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/types.h>
-+#include <sound/dmaengine_pcm.h>
-+#include <sound/initval.h>
-+#include <sound/pcm.h>
-+#include <sound/pcm_params.h>
-+#include <sound/soc.h>
-+#include <sound/soc-dai.h>
-+
-+#define TDM_PCMGBCR 0x00
-+ #define PCMGBCR_MASK 0x1e
-+ #define PCMGBCR_ENABLE BIT(0)
-+ #define PCMGBCR_TRITXEN BIT(4)
-+ #define CLKPOL_BIT 5
-+ #define TRITXEN_BIT 4
-+ #define ELM_BIT 3
-+ #define SYNCM_BIT 2
-+ #define MS_BIT 1
-+#define TDM_PCMTXCR 0x04
-+ #define PCMTXCR_TXEN BIT(0)
-+ #define IFL_BIT 11
-+ #define WL_BIT 8
-+ #define SSCALE_BIT 4
-+ #define SL_BIT 2
-+ #define LRJ_BIT 1
-+#define TDM_PCMRXCR 0x08
-+ #define PCMRXCR_RXEN BIT(0)
-+ #define PCMRXCR_RXSL_MASK 0xc
-+ #define PCMRXCR_RXSL_16BIT 0x4
-+ #define PCMRXCR_RXSL_32BIT 0x8
-+ #define PCMRXCR_SCALE_MASK 0xf0
-+ #define PCMRXCR_SCALE_1CH 0x10
-+#define TDM_PCMDIV 0x0c
-+
-+#define JH7110_TDM_FIFO 0x170c0000
-+#define JH7110_TDM_FIFO_DEPTH 32
-+
-+enum TDM_MASTER_SLAVE_MODE {
-+ TDM_AS_MASTER = 0,
-+ TDM_AS_SLAVE,
-+};
-+
-+enum TDM_CLKPOL {
-+ /* tx raising and rx falling */
-+ TDM_TX_RASING_RX_FALLING = 0,
-+ /* tx falling and rx raising */
-+ TDM_TX_FALLING_RX_RASING,
-+};
-+
-+enum TDM_ELM {
-+ /* only work while SYNCM=0 */
-+ TDM_ELM_LATE = 0,
-+ TDM_ELM_EARLY,
-+};
-+
-+enum TDM_SYNCM {
-+ /* short frame sync */
-+ TDM_SYNCM_SHORT = 0,
-+ /* long frame sync */
-+ TDM_SYNCM_LONG,
-+};
-+
-+enum TDM_IFL {
-+ /* FIFO to send or received : half-1/2, Quarter-1/4 */
-+ TDM_FIFO_HALF = 0,
-+ TDM_FIFO_QUARTER,
-+};
-+
-+enum TDM_WL {
-+ /* send or received word length */
-+ TDM_8BIT_WORD_LEN = 0,
-+ TDM_16BIT_WORD_LEN,
-+ TDM_20BIT_WORD_LEN,
-+ TDM_24BIT_WORD_LEN,
-+ TDM_32BIT_WORD_LEN,
-+};
-+
-+enum TDM_SL {
-+ /* send or received slot length */
-+ TDM_8BIT_SLOT_LEN = 0,
-+ TDM_16BIT_SLOT_LEN,
-+ TDM_32BIT_SLOT_LEN,
-+};
-+
-+enum TDM_LRJ {
-+ /* left-justify or right-justify */
-+ TDM_RIGHT_JUSTIFY = 0,
-+ TDM_LEFT_JUSTIFT,
-+};
-+
-+struct tdm_chan_cfg {
-+ enum TDM_IFL ifl;
-+ enum TDM_WL wl;
-+ unsigned char sscale;
-+ enum TDM_SL sl;
-+ enum TDM_LRJ lrj;
-+ unsigned char enable;
-+};
-+
-+struct jh7110_tdm_dev {
-+ void __iomem *tdm_base;
-+ struct device *dev;
-+ struct clk_bulk_data clks[6];
-+ struct reset_control *resets;
-+
-+ enum TDM_CLKPOL clkpolity;
-+ enum TDM_ELM elm;
-+ enum TDM_SYNCM syncm;
-+ enum TDM_MASTER_SLAVE_MODE ms_mode;
-+
-+ struct tdm_chan_cfg tx;
-+ struct tdm_chan_cfg rx;
-+
-+ u16 syncdiv;
-+ u32 samplerate;
-+ u32 pcmclk;
-+
-+ /* data related to DMA transfers b/w tdm and DMAC */
-+ struct snd_dmaengine_dai_dma_data play_dma_data;
-+ struct snd_dmaengine_dai_dma_data capture_dma_data;
-+ u32 saved_pcmgbcr;
-+ u32 saved_pcmtxcr;
-+ u32 saved_pcmrxcr;
-+ u32 saved_pcmdiv;
-+};
-+
-+static inline u32 jh7110_tdm_readl(struct jh7110_tdm_dev *tdm, u16 reg)
-+{
-+ return readl_relaxed(tdm->tdm_base + reg);
-+}
-+
-+static inline void jh7110_tdm_writel(struct jh7110_tdm_dev *tdm, u16 reg, u32 val)
-+{
-+ writel_relaxed(val, tdm->tdm_base + reg);
-+}
-+
-+static void jh7110_tdm_save_context(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ tdm->saved_pcmtxcr = jh7110_tdm_readl(tdm, TDM_PCMTXCR);
-+ else
-+ tdm->saved_pcmrxcr = jh7110_tdm_readl(tdm, TDM_PCMRXCR);
-+}
-+
-+static void jh7110_tdm_start(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ u32 data;
-+
-+ data = jh7110_tdm_readl(tdm, TDM_PCMGBCR);
-+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, data | PCMGBCR_ENABLE);
-+
-+ /* restore context */
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, tdm->saved_pcmtxcr | PCMTXCR_TXEN);
-+ else
-+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, tdm->saved_pcmrxcr | PCMRXCR_RXEN);
-+}
-+
-+static void jh7110_tdm_stop(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ unsigned int val;
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-+ val = jh7110_tdm_readl(tdm, TDM_PCMTXCR);
-+ val &= ~PCMTXCR_TXEN;
-+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, val);
-+ } else {
-+ val = jh7110_tdm_readl(tdm, TDM_PCMRXCR);
-+ val &= ~PCMRXCR_RXEN;
-+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, val);
-+ }
-+}
-+
-+static int jh7110_tdm_syncdiv(struct jh7110_tdm_dev *tdm)
-+{
-+ u32 sl, sscale, syncdiv;
-+
-+ if (tdm->rx.sl >= tdm->tx.sl)
-+ sl = tdm->rx.sl;
-+ else
-+ sl = tdm->tx.sl;
-+
-+ if (tdm->rx.sscale >= tdm->tx.sscale)
-+ sscale = tdm->rx.sscale;
-+ else
-+ sscale = tdm->tx.sscale;
-+
-+ syncdiv = tdm->pcmclk / tdm->samplerate - 1;
-+
-+ if ((syncdiv + 1) < (sl * sscale)) {
-+ dev_err(tdm->dev, "Failed to set syncdiv!\n");
-+ return -EINVAL;
-+ }
-+
-+ if (tdm->syncm == TDM_SYNCM_LONG &&
-+ (tdm->rx.sscale <= 1 || tdm->tx.sscale <= 1) &&
-+ ((syncdiv + 1) <= sl)) {
-+ dev_err(tdm->dev, "Wrong syncdiv! It must be (syncdiv+1) > max[tx.sl, rx.sl]\n");
-+ return -EINVAL;
-+ }
-+
-+ jh7110_tdm_writel(tdm, TDM_PCMDIV, syncdiv);
-+ return 0;
-+}
-+
-+static int jh7110_tdm_config(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ u32 datarx, datatx;
-+ int ret;
-+
-+ ret = jh7110_tdm_syncdiv(tdm);
-+ if (ret)
-+ return ret;
-+
-+ datarx = (tdm->rx.ifl << IFL_BIT) |
-+ (tdm->rx.wl << WL_BIT) |
-+ (tdm->rx.sscale << SSCALE_BIT) |
-+ (tdm->rx.sl << SL_BIT) |
-+ (tdm->rx.lrj << LRJ_BIT);
-+
-+ datatx = (tdm->tx.ifl << IFL_BIT) |
-+ (tdm->tx.wl << WL_BIT) |
-+ (tdm->tx.sscale << SSCALE_BIT) |
-+ (tdm->tx.sl << SL_BIT) |
-+ (tdm->tx.lrj << LRJ_BIT);
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, datatx);
-+ else
-+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, datarx);
-+
-+ return 0;
-+}
-+
-+static void jh7110_tdm_clk_disable(struct jh7110_tdm_dev *tdm)
-+{
-+ clk_bulk_disable_unprepare(ARRAY_SIZE(tdm->clks), tdm->clks);
-+}
-+
-+static int jh7110_tdm_clk_enable(struct jh7110_tdm_dev *tdm)
-+{
-+ int ret;
-+
-+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(tdm->clks), tdm->clks);
-+ if (ret) {
-+ dev_err(tdm->dev, "Failed to enable tdm clocks\n");
-+ return ret;
-+ }
-+
-+ ret = reset_control_deassert(tdm->resets);
-+ if (ret) {
-+ dev_err(tdm->dev, "Failed to deassert tdm resets\n");
-+ goto dis_tdm_clk;
-+ }
-+
-+ /* select tdm_ext clock as the clock source for tdm */
-+ ret = clk_set_parent(tdm->clks[5].clk, tdm->clks[4].clk);
-+ if (ret) {
-+ dev_err(tdm->dev, "Can't set extern clock source for clk_tdm\n");
-+ goto dis_tdm_clk;
-+ }
-+
-+ return 0;
-+
-+dis_tdm_clk:
-+ clk_bulk_disable_unprepare(ARRAY_SIZE(tdm->clks), tdm->clks);
-+
-+ return ret;
-+}
-+
-+static int jh7110_tdm_runtime_suspend(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ jh7110_tdm_clk_disable(tdm);
-+ return 0;
-+}
-+
-+static int jh7110_tdm_runtime_resume(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ return jh7110_tdm_clk_enable(tdm);
-+}
-+
-+static int jh7110_tdm_system_suspend(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ /* save context */
-+ tdm->saved_pcmgbcr = jh7110_tdm_readl(tdm, TDM_PCMGBCR);
-+ tdm->saved_pcmdiv = jh7110_tdm_readl(tdm, TDM_PCMDIV);
-+
-+ return pm_runtime_force_suspend(dev);
-+}
-+
-+static int jh7110_tdm_system_resume(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ /* restore context */
-+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, tdm->saved_pcmgbcr);
-+ jh7110_tdm_writel(tdm, TDM_PCMDIV, tdm->saved_pcmdiv);
-+
-+ return pm_runtime_force_resume(dev);
-+}
-+
-+static const struct snd_soc_component_driver jh7110_tdm_component = {
-+ .name = "jh7110-tdm",
-+};
-+
-+static int jh7110_tdm_startup(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *cpu_dai)
-+{
-+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
-+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
-+
-+ dai_link->stop_dma_first = 1;
-+
-+ return 0;
-+}
-+
-+static int jh7110_tdm_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params,
-+ struct snd_soc_dai *dai)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
-+ int chan_wl, chan_sl, chan_nr;
-+ unsigned int data_width;
-+ unsigned int dma_bus_width;
-+ struct snd_dmaengine_dai_dma_data *dma_data = NULL;
-+ int ret;
-+
-+ data_width = params_width(params);
-+
-+ tdm->samplerate = params_rate(params);
-+ tdm->pcmclk = params_channels(params) * tdm->samplerate * data_width;
-+
-+ switch (params_format(params)) {
-+ case SNDRV_PCM_FORMAT_S16_LE:
-+ chan_wl = TDM_16BIT_WORD_LEN;
-+ chan_sl = TDM_16BIT_SLOT_LEN;
-+ dma_bus_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-+ break;
-+
-+ case SNDRV_PCM_FORMAT_S32_LE:
-+ chan_wl = TDM_32BIT_WORD_LEN;
-+ chan_sl = TDM_32BIT_SLOT_LEN;
-+ dma_bus_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+ break;
-+
-+ default:
-+ dev_err(tdm->dev, "tdm: unsupported PCM fmt");
-+ return -EINVAL;
-+ }
-+
-+ chan_nr = params_channels(params);
-+ switch (chan_nr) {
-+ case 1:
-+ case 2:
-+ case 4:
-+ case 6:
-+ case 8:
-+ break;
-+ default:
-+ dev_err(tdm->dev, "channel not supported\n");
-+ return -EINVAL;
-+ }
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-+ tdm->tx.wl = chan_wl;
-+ tdm->tx.sl = chan_sl;
-+ tdm->tx.sscale = chan_nr;
-+ tdm->play_dma_data.addr_width = dma_bus_width;
-+ dma_data = &tdm->play_dma_data;
-+ } else {
-+ tdm->rx.wl = chan_wl;
-+ tdm->rx.sl = chan_sl;
-+ tdm->rx.sscale = chan_nr;
-+ tdm->capture_dma_data.addr_width = dma_bus_width;
-+ dma_data = &tdm->capture_dma_data;
-+ }
-+
-+ snd_soc_dai_set_dma_data(dai, substream, dma_data);
-+
-+ ret = jh7110_tdm_config(tdm, substream);
-+ if (ret)
-+ return ret;
-+
-+ jh7110_tdm_save_context(tdm, substream);
-+ return 0;
-+}
-+
-+static int jh7110_tdm_trigger(struct snd_pcm_substream *substream,
-+ int cmd, struct snd_soc_dai *dai)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
-+ int ret = 0;
-+
-+ switch (cmd) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_RESUME:
-+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-+ jh7110_tdm_start(tdm, substream);
-+ break;
-+
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-+ jh7110_tdm_stop(tdm, substream);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static int jh7110_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-+ unsigned int fmt)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(cpu_dai);
-+ unsigned int gbcr;
-+
-+ /* set master/slave audio interface */
-+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
-+ case SND_SOC_DAIFMT_BP_FP:
-+ /* cpu is master */
-+ tdm->ms_mode = TDM_AS_MASTER;
-+ break;
-+ case SND_SOC_DAIFMT_BC_FC:
-+ /* codec is master */
-+ tdm->ms_mode = TDM_AS_SLAVE;
-+ break;
-+ case SND_SOC_DAIFMT_BC_FP:
-+ case SND_SOC_DAIFMT_BP_FC:
-+ return -EINVAL;
-+ default:
-+ dev_dbg(tdm->dev, "dwc : Invalid clock provider format\n");
-+ return -EINVAL;
-+ }
-+
-+ gbcr = (tdm->clkpolity << CLKPOL_BIT) |
-+ (tdm->elm << ELM_BIT) |
-+ (tdm->syncm << SYNCM_BIT) |
-+ (tdm->ms_mode << MS_BIT);
-+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, gbcr);
-+
-+ return 0;
-+}
-+
-+static const struct snd_soc_dai_ops jh7110_tdm_dai_ops = {
-+ .startup = jh7110_tdm_startup,
-+ .hw_params = jh7110_tdm_hw_params,
-+ .trigger = jh7110_tdm_trigger,
-+ .set_fmt = jh7110_tdm_set_dai_fmt,
-+};
-+
-+static int jh7110_tdm_dai_probe(struct snd_soc_dai *dai)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
-+
-+ snd_soc_dai_init_dma_data(dai, &tdm->play_dma_data, &tdm->capture_dma_data);
-+ snd_soc_dai_set_drvdata(dai, tdm);
-+ return 0;
-+}
-+
-+#define JH7110_TDM_RATES SNDRV_PCM_RATE_8000_48000
-+
-+#define JH7110_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
-+ SNDRV_PCM_FMTBIT_S32_LE)
-+
-+static struct snd_soc_dai_driver jh7110_tdm_dai = {
-+ .name = "sf_tdm",
-+ .id = 0,
-+ .playback = {
-+ .stream_name = "Playback",
-+ .channels_min = 1,
-+ .channels_max = 8,
-+ .rates = JH7110_TDM_RATES,
-+ .formats = JH7110_TDM_FORMATS,
-+ },
-+ .capture = {
-+ .stream_name = "Capture",
-+ .channels_min = 1,
-+ .channels_max = 8,
-+ .rates = JH7110_TDM_RATES,
-+ .formats = JH7110_TDM_FORMATS,
-+ },
-+ .ops = &jh7110_tdm_dai_ops,
-+ .probe = jh7110_tdm_dai_probe,
-+ .symmetric_rate = 1,
-+};
-+
-+static const struct snd_pcm_hardware jh7110_pcm_hardware = {
-+ .info = (SNDRV_PCM_INFO_MMAP |
-+ SNDRV_PCM_INFO_MMAP_VALID |
-+ SNDRV_PCM_INFO_PAUSE |
-+ SNDRV_PCM_INFO_RESUME |
-+ SNDRV_PCM_INFO_INTERLEAVED |
-+ SNDRV_PCM_INFO_BLOCK_TRANSFER),
-+ .buffer_bytes_max = 192512,
-+ .period_bytes_min = 4096,
-+ .period_bytes_max = 32768,
-+ .periods_min = 1,
-+ .periods_max = 48,
-+ .fifo_size = 16,
-+};
-+
-+static const struct snd_dmaengine_pcm_config jh7110_dmaengine_pcm_config = {
-+ .pcm_hardware = &jh7110_pcm_hardware,
-+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-+ .prealloc_buffer_size = 192512,
-+};
-+
-+static void jh7110_tdm_init_params(struct jh7110_tdm_dev *tdm)
-+{
-+ tdm->clkpolity = TDM_TX_RASING_RX_FALLING;
-+ tdm->elm = TDM_ELM_LATE;
-+ tdm->syncm = TDM_SYNCM_SHORT;
-+
-+ tdm->rx.ifl = TDM_FIFO_HALF;
-+ tdm->tx.ifl = TDM_FIFO_HALF;
-+ tdm->rx.wl = TDM_16BIT_WORD_LEN;
-+ tdm->tx.wl = TDM_16BIT_WORD_LEN;
-+ tdm->rx.sscale = 2;
-+ tdm->tx.sscale = 2;
-+ tdm->rx.lrj = TDM_LEFT_JUSTIFT;
-+ tdm->tx.lrj = TDM_LEFT_JUSTIFT;
-+
-+ tdm->play_dma_data.addr = JH7110_TDM_FIFO;
-+ tdm->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-+ tdm->play_dma_data.fifo_size = JH7110_TDM_FIFO_DEPTH / 2;
-+ tdm->play_dma_data.maxburst = 16;
-+
-+ tdm->capture_dma_data.addr = JH7110_TDM_FIFO;
-+ tdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-+ tdm->capture_dma_data.fifo_size = JH7110_TDM_FIFO_DEPTH / 2;
-+ tdm->capture_dma_data.maxburst = 8;
-+}
-+
-+static int jh7110_tdm_clk_reset_get(struct platform_device *pdev,
-+ struct jh7110_tdm_dev *tdm)
-+{
-+ int ret;
-+
-+ tdm->clks[0].id = "mclk_inner";
-+ tdm->clks[1].id = "tdm_ahb";
-+ tdm->clks[2].id = "tdm_apb";
-+ tdm->clks[3].id = "tdm_internal";
-+ tdm->clks[4].id = "tdm_ext";
-+ tdm->clks[5].id = "tdm";
-+
-+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(tdm->clks), tdm->clks);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to get tdm clocks\n");
-+ return ret;
-+ }
-+
-+ tdm->resets = devm_reset_control_array_get_exclusive(&pdev->dev);
-+ if (IS_ERR_OR_NULL(tdm->resets)) {
-+ ret = PTR_ERR(tdm->resets);
-+ dev_err(&pdev->dev, "Failed to get tdm resets");
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int jh7110_tdm_probe(struct platform_device *pdev)
-+{
-+ struct jh7110_tdm_dev *tdm;
-+ int ret;
-+
-+ tdm = devm_kzalloc(&pdev->dev, sizeof(*tdm), GFP_KERNEL);
-+ if (!tdm)
-+ return -ENOMEM;
-+
-+ tdm->tdm_base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(tdm->tdm_base))
-+ return PTR_ERR(tdm->tdm_base);
-+
-+ tdm->dev = &pdev->dev;
-+
-+ ret = jh7110_tdm_clk_reset_get(pdev, tdm);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to enable audio-tdm clock\n");
-+ return ret;
-+ }
-+
-+ jh7110_tdm_init_params(tdm);
-+
-+ dev_set_drvdata(&pdev->dev, tdm);
-+ ret = devm_snd_soc_register_component(&pdev->dev, &jh7110_tdm_component,
-+ &jh7110_tdm_dai, 1);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to register dai\n");
-+ return ret;
-+ }
-+
-+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
-+ &jh7110_dmaengine_pcm_config,
-+ SND_DMAENGINE_PCM_FLAG_COMPAT);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Could not register pcm: %d\n", ret);
-+ return ret;
-+ }
-+
-+ pm_runtime_enable(&pdev->dev);
-+ if (!pm_runtime_enabled(&pdev->dev)) {
-+ ret = jh7110_tdm_runtime_resume(&pdev->dev);
-+ if (ret)
-+ goto err_pm_disable;
-+ }
-+
-+ return 0;
-+
-+err_pm_disable:
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return ret;
-+}
-+
-+static int jh7110_tdm_dev_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_disable(&pdev->dev);
-+ return 0;
-+}
-+
-+static const struct of_device_id jh7110_tdm_of_match[] = {
-+ { .compatible = "starfive,jh7110-tdm", },
-+ {}
-+};
-+
-+MODULE_DEVICE_TABLE(of, jh7110_tdm_of_match);
-+
-+static const struct dev_pm_ops jh7110_tdm_pm_ops = {
-+ RUNTIME_PM_OPS(jh7110_tdm_runtime_suspend,
-+ jh7110_tdm_runtime_resume, NULL)
-+ SYSTEM_SLEEP_PM_OPS(jh7110_tdm_system_suspend,
-+ jh7110_tdm_system_resume)
-+};
-+
-+static struct platform_driver jh7110_tdm_driver = {
-+ .driver = {
-+ .name = "jh7110-tdm",
-+ .of_match_table = jh7110_tdm_of_match,
-+ .pm = pm_ptr(&jh7110_tdm_pm_ops),
-+ },
-+ .probe = jh7110_tdm_probe,
-+ .remove = jh7110_tdm_dev_remove,
-+};
-+module_platform_driver(jh7110_tdm_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 TDM ASoC Driver");
-+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch b/target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
deleted file mode 100644
index d8ba979f55..0000000000
--- a/target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 598083825494088f927fa42c5a7bb2872029a7bc Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:01:59 -0700
-Subject: [PATCH 070/122] dt-bindings: power: Add power-domain header for
- JH7110
-
-Add power-domain header for JH7110 SoC, it can use to operate dphy
-power.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- include/dt-bindings/power/starfive,jh7110-pmu.h | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/include/dt-bindings/power/starfive,jh7110-pmu.h
-+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
-@@ -1,6 +1,6 @@
- /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
- /*
-- * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
- * Author: Walker Chen <walker.chen@starfivetech.com>
- */
- #ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
-@@ -14,4 +14,7 @@
- #define JH7110_PD_ISP 5
- #define JH7110_PD_VENC 6
-
-+#define JH7110_PD_DPHY_TX 0
-+#define JH7110_PD_DPHY_RX 1
-+
- #endif
diff --git a/target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch b/target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
deleted file mode 100644
index fa0201b6ca..0000000000
--- a/target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From d83b51f60997365b80637f71924ab3dec91d5b77 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:02:00 -0700
-Subject: [PATCH 071/122] soc: starfive: Replace SOC_STARFIVE with
- ARCH_STARFIVE
-
-Using ARCH_FOO symbol is preferred than SOC_FOO.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- drivers/soc/starfive/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/soc/starfive/Kconfig
-+++ b/drivers/soc/starfive/Kconfig
-@@ -3,8 +3,8 @@
- config JH71XX_PMU
- bool "Support PMU for StarFive JH71XX Soc"
- depends on PM
-- depends on SOC_STARFIVE || COMPILE_TEST
-- default SOC_STARFIVE
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
- select PM_GENERIC_DOMAINS
- help
- Say 'y' here to enable support power domain support.
diff --git a/target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch b/target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch
deleted file mode 100644
index 5f2cb2810f..0000000000
--- a/target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch
+++ /dev/null
@@ -1,175 +0,0 @@
-From 52e2ade50f3ec212468e284b1236aaa521ba5913 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:02:01 -0700
-Subject: [PATCH 072/122] soc: starfive: Extract JH7110 pmu private operations
-
-Move JH7110 private operation into private data of compatible. Convenient
-to add AON PMU which would not have interrupts property.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
-Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
----
- drivers/soc/starfive/jh71xx_pmu.c | 89 +++++++++++++++++++++----------
- 1 file changed, 62 insertions(+), 27 deletions(-)
-
---- a/drivers/soc/starfive/jh71xx_pmu.c
-+++ b/drivers/soc/starfive/jh71xx_pmu.c
-@@ -51,9 +51,17 @@ struct jh71xx_domain_info {
- u8 bit;
- };
-
-+struct jh71xx_pmu;
-+struct jh71xx_pmu_dev;
-+
- struct jh71xx_pmu_match_data {
- const struct jh71xx_domain_info *domain_info;
- int num_domains;
-+ unsigned int pmu_status;
-+ int (*pmu_parse_irq)(struct platform_device *pdev,
-+ struct jh71xx_pmu *pmu);
-+ int (*pmu_set_state)(struct jh71xx_pmu_dev *pmd,
-+ u32 mask, bool on);
- };
-
- struct jh71xx_pmu {
-@@ -79,12 +87,12 @@ static int jh71xx_pmu_get_state(struct j
- if (!mask)
- return -EINVAL;
-
-- *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
-+ *is_on = readl(pmu->base + pmu->match_data->pmu_status) & mask;
-
- return 0;
- }
-
--static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+static int jh7110_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
- {
- struct jh71xx_pmu *pmu = pmd->pmu;
- unsigned long flags;
-@@ -92,22 +100,8 @@ static int jh71xx_pmu_set_state(struct j
- u32 mode;
- u32 encourage_lo;
- u32 encourage_hi;
-- bool is_on;
- int ret;
-
-- ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
-- if (ret) {
-- dev_dbg(pmu->dev, "unable to get current state for %s\n",
-- pmd->genpd.name);
-- return ret;
-- }
--
-- if (is_on == on) {
-- dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
-- pmd->genpd.name, on ? "en" : "dis");
-- return 0;
-- }
--
- spin_lock_irqsave(&pmu->lock, flags);
-
- /*
-@@ -166,6 +160,29 @@ static int jh71xx_pmu_set_state(struct j
- return 0;
- }
-
-+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+ const struct jh71xx_pmu_match_data *match_data = pmu->match_data;
-+ bool is_on;
-+ int ret;
-+
-+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
-+ if (ret) {
-+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
-+ pmd->genpd.name);
-+ return ret;
-+ }
-+
-+ if (is_on == on) {
-+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
-+ pmd->genpd.name, on ? "en" : "dis");
-+ return 0;
-+ }
-+
-+ return match_data->pmu_set_state(pmd, mask, on);
-+}
-+
- static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
- {
- struct jh71xx_pmu_dev *pmd = container_of(genpd,
-@@ -226,6 +243,25 @@ static irqreturn_t jh71xx_pmu_interrupt(
- return IRQ_HANDLED;
- }
-
-+static int jh7110_pmu_parse_irq(struct platform_device *pdev, struct jh71xx_pmu *pmu)
-+{
-+ struct device *dev = &pdev->dev;
-+ int ret;
-+
-+ pmu->irq = platform_get_irq(pdev, 0);
-+ if (pmu->irq < 0)
-+ return pmu->irq;
-+
-+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
-+ 0, pdev->name, pmu);
-+ if (ret)
-+ dev_err(dev, "failed to request irq\n");
-+
-+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
-+
-+ return 0;
-+}
-+
- static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
- {
- struct jh71xx_pmu_dev *pmd;
-@@ -275,19 +311,18 @@ static int jh71xx_pmu_probe(struct platf
- if (IS_ERR(pmu->base))
- return PTR_ERR(pmu->base);
-
-- pmu->irq = platform_get_irq(pdev, 0);
-- if (pmu->irq < 0)
-- return pmu->irq;
--
-- ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
-- 0, pdev->name, pmu);
-- if (ret)
-- dev_err(dev, "failed to request irq\n");
-+ spin_lock_init(&pmu->lock);
-
- match_data = of_device_get_match_data(dev);
- if (!match_data)
- return -EINVAL;
-
-+ ret = match_data->pmu_parse_irq(pdev, pmu);
-+ if (ret) {
-+ dev_err(dev, "failed to parse irq\n");
-+ return ret;
-+ }
-+
- pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
- sizeof(struct generic_pm_domain *),
- GFP_KERNEL);
-@@ -307,9 +342,6 @@ static int jh71xx_pmu_probe(struct platf
- }
- }
-
-- spin_lock_init(&pmu->lock);
-- jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
--
- ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
- if (ret) {
- dev_err(dev, "failed to register genpd driver: %d\n", ret);
-@@ -357,6 +389,9 @@ static const struct jh71xx_domain_info j
- static const struct jh71xx_pmu_match_data jh7110_pmu = {
- .num_domains = ARRAY_SIZE(jh7110_power_domains),
- .domain_info = jh7110_power_domains,
-+ .pmu_status = JH71XX_PMU_CURR_POWER_MODE,
-+ .pmu_parse_irq = jh7110_pmu_parse_irq,
-+ .pmu_set_state = jh7110_pmu_set_state,
- };
-
- static const struct of_device_id jh71xx_pmu_of_match[] = {
diff --git a/target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch b/target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch
deleted file mode 100644
index ec7a476b8f..0000000000
--- a/target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 3124d653318c50e20eadbb3998eafa5928ac9b63 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:02:02 -0700
-Subject: [PATCH 073/122] soc: starfive: Add JH7110 AON PMU support
-
-Add AON PMU for StarFive JH7110 SoC. It can be used to turn on/off the
-dphy rx/tx power switch.
-
-Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- drivers/soc/starfive/jh71xx_pmu.c | 57 ++++++++++++++++++++++++++++---
- 1 file changed, 52 insertions(+), 5 deletions(-)
-
---- a/drivers/soc/starfive/jh71xx_pmu.c
-+++ b/drivers/soc/starfive/jh71xx_pmu.c
-@@ -2,7 +2,7 @@
- /*
- * StarFive JH71XX PMU (Power Management Unit) Controller Driver
- *
-- * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
- */
-
- #include <linux/interrupt.h>
-@@ -24,6 +24,9 @@
- #define JH71XX_PMU_EVENT_STATUS 0x88
- #define JH71XX_PMU_INT_STATUS 0x8C
-
-+/* aon pmu register offset */
-+#define JH71XX_AON_PMU_SWITCH 0x00
-+
- /* sw encourage cfg */
- #define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
- #define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
-@@ -160,6 +163,26 @@ static int jh7110_pmu_set_state(struct j
- return 0;
- }
-
-+static int jh7110_aon_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+ unsigned long flags;
-+ u32 val;
-+
-+ spin_lock_irqsave(&pmu->lock, flags);
-+ val = readl(pmu->base + JH71XX_AON_PMU_SWITCH);
-+
-+ if (on)
-+ val |= mask;
-+ else
-+ val &= ~mask;
-+
-+ writel(val, pmu->base + JH71XX_AON_PMU_SWITCH);
-+ spin_unlock_irqrestore(&pmu->lock, flags);
-+
-+ return 0;
-+}
-+
- static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
- {
- struct jh71xx_pmu *pmu = pmd->pmu;
-@@ -317,10 +340,12 @@ static int jh71xx_pmu_probe(struct platf
- if (!match_data)
- return -EINVAL;
-
-- ret = match_data->pmu_parse_irq(pdev, pmu);
-- if (ret) {
-- dev_err(dev, "failed to parse irq\n");
-- return ret;
-+ if (match_data->pmu_parse_irq) {
-+ ret = match_data->pmu_parse_irq(pdev, pmu);
-+ if (ret) {
-+ dev_err(dev, "failed to parse irq\n");
-+ return ret;
-+ }
- }
-
- pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
-@@ -394,11 +419,32 @@ static const struct jh71xx_pmu_match_dat
- .pmu_set_state = jh7110_pmu_set_state,
- };
-
-+static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
-+ [JH7110_PD_DPHY_TX] = {
-+ .name = "DPHY-TX",
-+ .bit = 30,
-+ },
-+ [JH7110_PD_DPHY_RX] = {
-+ .name = "DPHY-RX",
-+ .bit = 31,
-+ },
-+};
-+
-+static const struct jh71xx_pmu_match_data jh7110_aon_pmu = {
-+ .num_domains = ARRAY_SIZE(jh7110_aon_power_domains),
-+ .domain_info = jh7110_aon_power_domains,
-+ .pmu_status = JH71XX_AON_PMU_SWITCH,
-+ .pmu_set_state = jh7110_aon_pmu_set_state,
-+};
-+
- static const struct of_device_id jh71xx_pmu_of_match[] = {
- {
- .compatible = "starfive,jh7110-pmu",
- .data = (void *)&jh7110_pmu,
- }, {
-+ .compatible = "starfive,jh7110-aon-syscon",
-+ .data = (void *)&jh7110_aon_pmu,
-+ }, {
- /* sentinel */
- }
- };
-@@ -414,5 +460,6 @@ static struct platform_driver jh71xx_pmu
- builtin_platform_driver(jh71xx_pmu_driver);
-
- MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
-+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
- MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
- MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch b/target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch
deleted file mode 100644
index 6368e53d84..0000000000
--- a/target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 7492ebbdd926da258f9abea5c41a9f8c4ec48631 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Mon, 29 May 2023 05:15:01 -0700
-Subject: [PATCH 074/122] dt-bindings: phy: Add starfive,jh7110-dphy-rx
-
-StarFive SoCs like the jh7110 use a MIPI D-PHY RX controller based on
-a M31 IP. Add a binding for it.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- .../bindings/phy/starfive,jh7110-dphy-rx.yaml | 71 +++++++++++++++++++
- 1 file changed, 71 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
-@@ -0,0 +1,71 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/phy/starfive,jh7110-dphy-rx.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive SoC MIPI D-PHY Rx Controller
-+
-+maintainers:
-+ - Jack Zhu <jack.zhu@starfivetech.com>
-+ - Changhuang Liang <changhuang.liang@starfivetech.com>
-+
-+description:
-+ The StarFive SoC uses the MIPI CSI D-PHY based on M31 IP to transfer
-+ CSI camera data.
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-dphy-rx
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: config clock
-+ - description: reference clock
-+ - description: escape mode transmit clock
-+
-+ clock-names:
-+ items:
-+ - const: cfg
-+ - const: ref
-+ - const: tx
-+
-+ resets:
-+ items:
-+ - description: DPHY_HW reset
-+ - description: DPHY_B09_ALWAYS_ON reset
-+
-+ power-domains:
-+ maxItems: 1
-+
-+ "#phy-cells":
-+ const: 0
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - power-domains
-+ - "#phy-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ phy@19820000 {
-+ compatible = "starfive,jh7110-dphy-rx";
-+ reg = <0x19820000 0x10000>;
-+ clocks = <&ispcrg 3>,
-+ <&ispcrg 4>,
-+ <&ispcrg 5>;
-+ clock-names = "cfg", "ref", "tx";
-+ resets = <&ispcrg 2>,
-+ <&ispcrg 3>;
-+ power-domains = <&dphy_pwrc 1>;
-+ #phy-cells = <0>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch b/target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch
deleted file mode 100644
index d5db36a1e6..0000000000
--- a/target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch
+++ /dev/null
@@ -1,365 +0,0 @@
-From f6fbb431f9e3ac5c9144edf05340db9a96dffa59 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Mon, 29 May 2023 05:15:02 -0700
-Subject: [PATCH 075/122] phy: starfive: Add mipi dphy rx support
-
-Add mipi dphy rx support for the StarFive JH7110 SoC. It is used to
-transfer CSI camera data.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- drivers/phy/Kconfig | 1 +
- drivers/phy/Makefile | 1 +
- drivers/phy/starfive/Kconfig | 13 +
- drivers/phy/starfive/Makefile | 2 +
- drivers/phy/starfive/phy-starfive-dphy-rx.c | 301 ++++++++++++++++++++
- 5 files changed, 318 insertions(+)
- create mode 100644 drivers/phy/starfive/Kconfig
- create mode 100644 drivers/phy/starfive/Makefile
- create mode 100644 drivers/phy/starfive/phy-starfive-dphy-rx.c
-
---- a/drivers/phy/Kconfig
-+++ b/drivers/phy/Kconfig
-@@ -91,6 +91,7 @@ source "drivers/phy/rockchip/Kconfig"
- source "drivers/phy/samsung/Kconfig"
- source "drivers/phy/socionext/Kconfig"
- source "drivers/phy/st/Kconfig"
-+source "drivers/phy/starfive/Kconfig"
- source "drivers/phy/sunplus/Kconfig"
- source "drivers/phy/tegra/Kconfig"
- source "drivers/phy/ti/Kconfig"
---- a/drivers/phy/Makefile
-+++ b/drivers/phy/Makefile
-@@ -31,6 +31,7 @@ obj-y += allwinner/ \
- samsung/ \
- socionext/ \
- st/ \
-+ starfive/ \
- sunplus/ \
- tegra/ \
- ti/ \
---- /dev/null
-+++ b/drivers/phy/starfive/Kconfig
-@@ -0,0 +1,13 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+#
-+# Phy drivers for StarFive platforms
-+#
-+
-+config PHY_STARFIVE_DPHY_RX
-+ tristate "StarFive D-PHY RX Support"
-+ select GENERIC_PHY
-+ select GENERIC_PHY_MIPI_DPHY
-+ help
-+ Choose this option if you have a StarFive D-PHY in your
-+ system. If M is selected, the module will be called
-+ phy-starfive-dphy-rx.
---- /dev/null
-+++ b/drivers/phy/starfive/Makefile
-@@ -0,0 +1,2 @@
-+# SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_PHY_STARFIVE_DPHY_RX) += phy-starfive-dphy-rx.o
---- /dev/null
-+++ b/drivers/phy/starfive/phy-starfive-dphy-rx.c
-@@ -0,0 +1,301 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * DPHY driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/bitops.h>
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/phy/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#define STF_DPHY_APBCFGSAIF_SYSCFG(x) (x)
-+
-+#define STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_EN BIT(6)
-+#define STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_IN GENMASK(12, 7)
-+#define STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_EN BIT(19)
-+#define STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_IN GENMASK(25, 20)
-+
-+#define STF_DPHY_DATA_BUS16_8 BIT(8)
-+#define STF_DPHY_DEBUG_MODE_SEL GENMASK(15, 9)
-+
-+#define STF_DPHY_ENABLE_CLK BIT(6)
-+#define STF_DPHY_ENABLE_CLK1 BIT(7)
-+#define STF_DPHY_ENABLE_LAN0 BIT(8)
-+#define STF_DPHY_ENABLE_LAN1 BIT(9)
-+#define STF_DPHY_ENABLE_LAN2 BIT(10)
-+#define STF_DPHY_ENABLE_LAN3 BIT(11)
-+#define STF_DPHY_GPI_EN GENMASK(17, 12)
-+#define STF_DPHY_HS_FREQ_CHANGE_CLK BIT(18)
-+#define STF_DPHY_HS_FREQ_CHANGE_CLK1 BIT(19)
-+#define STF_DPHY_LANE_SWAP_CLK GENMASK(22, 20)
-+#define STF_DPHY_LANE_SWAP_CLK1 GENMASK(25, 23)
-+#define STF_DPHY_LANE_SWAP_LAN0 GENMASK(28, 26)
-+#define STF_DPHY_LANE_SWAP_LAN1 GENMASK(31, 29)
-+
-+#define STF_DPHY_LANE_SWAP_LAN2 GENMASK(2, 0)
-+#define STF_DPHY_LANE_SWAP_LAN3 GENMASK(5, 3)
-+#define STF_DPHY_MP_TEST_EN BIT(6)
-+#define STF_DPHY_MP_TEST_MODE_SEL GENMASK(11, 7)
-+#define STF_DPHY_PLL_CLK_SEL GENMASK(21, 12)
-+#define STF_DPHY_PRECOUNTER_IN_CLK GENMASK(29, 22)
-+
-+#define STF_DPHY_PRECOUNTER_IN_CLK1 GENMASK(7, 0)
-+#define STF_DPHY_PRECOUNTER_IN_LAN0 GENMASK(15, 8)
-+#define STF_DPHY_PRECOUNTER_IN_LAN1 GENMASK(23, 16)
-+#define STF_DPHY_PRECOUNTER_IN_LAN2 GENMASK(31, 24)
-+
-+#define STF_DPHY_PRECOUNTER_IN_LAN3 GENMASK(7, 0)
-+#define STF_DPHY_RX_1C2C_SEL BIT(8)
-+
-+#define STF_MAP_LANES_NUM 6
-+
-+struct regval {
-+ u32 addr;
-+ u32 val;
-+};
-+
-+struct stf_dphy_info {
-+ /**
-+ * @maps:
-+ *
-+ * Physical lanes and logic lanes mapping table.
-+ *
-+ * The default order is:
-+ * [clk lane0, data lane 0, data lane 1, data lane 2, date lane 3, clk lane 1]
-+ */
-+ u8 maps[STF_MAP_LANES_NUM];
-+};
-+
-+struct stf_dphy {
-+ struct device *dev;
-+ void __iomem *regs;
-+ struct clk *cfg_clk;
-+ struct clk *ref_clk;
-+ struct clk *tx_clk;
-+ struct reset_control *rstc;
-+ struct regulator *mipi_0p9;
-+ struct phy *phy;
-+ const struct stf_dphy_info *info;
-+};
-+
-+static const struct regval stf_dphy_init_list[] = {
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(4), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(8), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(12), 0x0000fff0 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(16), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(20), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(24), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(28), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(32), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(36), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(40), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(40), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(48), 0x24000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(52), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(56), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(60), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(64), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(68), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(72), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(76), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(80), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(84), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(88), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(92), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(96), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(100), 0x02000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(104), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(108), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(112), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(116), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(120), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(124), 0x0000000c },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(128), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(132), 0xcc500000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(136), 0x000000cc },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(140), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(144), 0x00000000 },
-+};
-+
-+static int stf_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
-+{
-+ struct stf_dphy *dphy = phy_get_drvdata(phy);
-+ const struct stf_dphy_info *info = dphy->info;
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(stf_dphy_init_list); i++)
-+ writel(stf_dphy_init_list[i].val,
-+ dphy->regs + stf_dphy_init_list[i].addr);
-+
-+ writel(FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_EN, 1) |
-+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_IN, 0x1b) |
-+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_EN, 1) |
-+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_IN, 0x1b),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(0));
-+
-+ writel(FIELD_PREP(STF_DPHY_DATA_BUS16_8, 0) |
-+ FIELD_PREP(STF_DPHY_DEBUG_MODE_SEL, 0x5a),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(184));
-+
-+ writel(FIELD_PREP(STF_DPHY_ENABLE_CLK, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_CLK1, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN0, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN1, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN2, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN3, 1) |
-+ FIELD_PREP(STF_DPHY_GPI_EN, 0) |
-+ FIELD_PREP(STF_DPHY_HS_FREQ_CHANGE_CLK, 0) |
-+ FIELD_PREP(STF_DPHY_HS_FREQ_CHANGE_CLK1, 0) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_CLK, info->maps[0]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_CLK1, info->maps[5]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN0, info->maps[1]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN1, info->maps[2]),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(188));
-+
-+ writel(FIELD_PREP(STF_DPHY_LANE_SWAP_LAN2, info->maps[3]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN3, info->maps[4]) |
-+ FIELD_PREP(STF_DPHY_MP_TEST_EN, 0) |
-+ FIELD_PREP(STF_DPHY_MP_TEST_MODE_SEL, 0) |
-+ FIELD_PREP(STF_DPHY_PLL_CLK_SEL, 0x37c) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK, 8),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(192));
-+
-+ writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK1, 8) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN0, 7) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN1, 7) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN2, 7),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(196));
-+
-+ writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN3, 7) |
-+ FIELD_PREP(STF_DPHY_RX_1C2C_SEL, 0),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(200));
-+
-+ return 0;
-+}
-+
-+static int stf_dphy_power_on(struct phy *phy)
-+{
-+ struct stf_dphy *dphy = phy_get_drvdata(phy);
-+ int ret;
-+
-+ pm_runtime_get_sync(dphy->dev);
-+
-+ ret = regulator_enable(dphy->mipi_0p9);
-+ if (ret)
-+ return ret;
-+
-+ clk_set_rate(dphy->cfg_clk, 99000000);
-+ clk_set_rate(dphy->ref_clk, 49500000);
-+ clk_set_rate(dphy->tx_clk, 19800000);
-+ reset_control_deassert(dphy->rstc);
-+
-+ return 0;
-+}
-+
-+static int stf_dphy_power_off(struct phy *phy)
-+{
-+ struct stf_dphy *dphy = phy_get_drvdata(phy);
-+
-+ reset_control_assert(dphy->rstc);
-+
-+ regulator_disable(dphy->mipi_0p9);
-+
-+ pm_runtime_put_sync(dphy->dev);
-+
-+ return 0;
-+}
-+
-+static const struct phy_ops stf_dphy_ops = {
-+ .configure = stf_dphy_configure,
-+ .power_on = stf_dphy_power_on,
-+ .power_off = stf_dphy_power_off,
-+};
-+
-+static int stf_dphy_probe(struct platform_device *pdev)
-+{
-+ struct phy_provider *phy_provider;
-+ struct stf_dphy *dphy;
-+
-+ dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
-+ if (!dphy)
-+ return -ENOMEM;
-+
-+ dphy->info = of_device_get_match_data(&pdev->dev);
-+
-+ dev_set_drvdata(&pdev->dev, dphy);
-+ dphy->dev = &pdev->dev;
-+
-+ dphy->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(dphy->regs))
-+ return PTR_ERR(dphy->regs);
-+
-+ dphy->cfg_clk = devm_clk_get(&pdev->dev, "cfg");
-+ if (IS_ERR(dphy->cfg_clk))
-+ return PTR_ERR(dphy->cfg_clk);
-+
-+ dphy->ref_clk = devm_clk_get(&pdev->dev, "ref");
-+ if (IS_ERR(dphy->ref_clk))
-+ return PTR_ERR(dphy->ref_clk);
-+
-+ dphy->tx_clk = devm_clk_get(&pdev->dev, "tx");
-+ if (IS_ERR(dphy->tx_clk))
-+ return PTR_ERR(dphy->tx_clk);
-+
-+ dphy->rstc = devm_reset_control_array_get_exclusive(&pdev->dev);
-+ if (IS_ERR(dphy->rstc))
-+ return PTR_ERR(dphy->rstc);
-+
-+ dphy->mipi_0p9 = devm_regulator_get(&pdev->dev, "mipi_0p9");
-+ if (IS_ERR(dphy->mipi_0p9))
-+ return PTR_ERR(dphy->mipi_0p9);
-+
-+ dphy->phy = devm_phy_create(&pdev->dev, NULL, &stf_dphy_ops);
-+ if (IS_ERR(dphy->phy)) {
-+ dev_err(&pdev->dev, "Failed to create PHY\n");
-+ return PTR_ERR(dphy->phy);
-+ }
-+
-+ pm_runtime_enable(&pdev->dev);
-+
-+ phy_set_drvdata(dphy->phy, dphy);
-+ phy_provider = devm_of_phy_provider_register(&pdev->dev,
-+ of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct stf_dphy_info starfive_dphy_info = {
-+ .maps = {4, 0, 1, 2, 3, 5},
-+};
-+
-+static const struct of_device_id stf_dphy_dt_ids[] = {
-+ {
-+ .compatible = "starfive,jh7110-dphy-rx",
-+ .data = &starfive_dphy_info,
-+ },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, stf_dphy_dt_ids);
-+
-+static struct platform_driver stf_dphy_driver = {
-+ .probe = stf_dphy_probe,
-+ .driver = {
-+ .name = "starfive-dphy-rx",
-+ .of_match_table = stf_dphy_dt_ids,
-+ },
-+};
-+module_platform_driver(stf_dphy_driver);
-+
-+MODULE_AUTHOR("Jack Zhu <jack.zhu@starfivetech.com>");
-+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive DPHY RX driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch b/target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch
deleted file mode 100644
index 4cabffbe53..0000000000
--- a/target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch
+++ /dev/null
@@ -1,306 +0,0 @@
-From 243b040c3517093309a41877e3c1c6e8a7540071 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:22 +0800
-Subject: [PATCH 076/122] media: dt-bindings: cadence-csi2rx: Convert to DT
- schema
-
-Convert DT bindings document for Cadence MIPI-CSI2 RX controller to
-DT schema format.
-
-For compatible, new compatibles should not be messed with conversion,
-but the original binding did not specify any SoC-specific compatible
-string, so add the StarFive compatible string.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../devicetree/bindings/media/cdns,csi2rx.txt | 100 ----------
- .../bindings/media/cdns,csi2rx.yaml | 177 ++++++++++++++++++
- 2 files changed, 177 insertions(+), 100 deletions(-)
- delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
- create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-
---- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
-+++ /dev/null
-@@ -1,100 +0,0 @@
--Cadence MIPI-CSI2 RX controller
--===============================
--
--The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
--lanes in input, and 4 different pixel streams in output.
--
--Required properties:
-- - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
-- - reg: base address and size of the memory mapped region
-- - clocks: phandles to the clocks driving the controller
-- - clock-names: must contain:
-- * sys_clk: main clock
-- * p_clk: register bank clock
-- * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
-- implemented in hardware, between 0 and 3
--
--Optional properties:
-- - phys: phandle to the external D-PHY, phy-names must be provided
-- - phy-names: must contain "dphy", if the implementation uses an
-- external D-PHY
--
--Required subnodes:
-- - ports: A ports node with one port child node per device input and output
-- port, in accordance with the video interface bindings defined in
-- Documentation/devicetree/bindings/media/video-interfaces.txt. The
-- port nodes are numbered as follows:
--
-- Port Description
-- -----------------------------
-- 0 CSI-2 input
-- 1 Stream 0 output
-- 2 Stream 1 output
-- 3 Stream 2 output
-- 4 Stream 3 output
--
-- The stream output port nodes are optional if they are not
-- connected to anything at the hardware level or implemented
-- in the design.Since there is only one endpoint per port,
-- the endpoints are not numbered.
--
--
--Example:
--
--csi2rx: csi-bridge@0d060000 {
-- compatible = "cdns,csi2rx";
-- reg = <0x0d060000 0x1000>;
-- clocks = <&byteclock>, <&byteclock>
-- <&coreclock>, <&coreclock>,
-- <&coreclock>, <&coreclock>;
-- clock-names = "sys_clk", "p_clk",
-- "pixel_if0_clk", "pixel_if1_clk",
-- "pixel_if2_clk", "pixel_if3_clk";
--
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- port@0 {
-- reg = <0>;
--
-- csi2rx_in_sensor: endpoint {
-- remote-endpoint = <&sensor_out_csi2rx>;
-- clock-lanes = <0>;
-- data-lanes = <1 2>;
-- };
-- };
--
-- port@1 {
-- reg = <1>;
--
-- csi2rx_out_grabber0: endpoint {
-- remote-endpoint = <&grabber0_in_csi2rx>;
-- };
-- };
--
-- port@2 {
-- reg = <2>;
--
-- csi2rx_out_grabber1: endpoint {
-- remote-endpoint = <&grabber1_in_csi2rx>;
-- };
-- };
--
-- port@3 {
-- reg = <3>;
--
-- csi2rx_out_grabber2: endpoint {
-- remote-endpoint = <&grabber2_in_csi2rx>;
-- };
-- };
--
-- port@4 {
-- reg = <4>;
--
-- csi2rx_out_grabber3: endpoint {
-- remote-endpoint = <&grabber3_in_csi2rx>;
-- };
-- };
-- };
--};
---- /dev/null
-+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-@@ -0,0 +1,177 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Cadence MIPI-CSI2 RX controller
-+
-+maintainers:
-+ - Maxime Ripard <mripard@kernel.org>
-+
-+description:
-+ The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
-+ lanes in input, and 4 different pixel streams in output.
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
-+ - starfive,jh7110-csi2rx
-+ - const: cdns,csi2rx
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: CSI2Rx system clock
-+ - description: Gated Register bank clock for APB interface
-+ - description: pixel Clock for Stream interface 0
-+ - description: pixel Clock for Stream interface 1
-+ - description: pixel Clock for Stream interface 2
-+ - description: pixel Clock for Stream interface 3
-+
-+ clock-names:
-+ items:
-+ - const: sys_clk
-+ - const: p_clk
-+ - const: pixel_if0_clk
-+ - const: pixel_if1_clk
-+ - const: pixel_if2_clk
-+ - const: pixel_if3_clk
-+
-+ phys:
-+ maxItems: 1
-+ description: MIPI D-PHY
-+
-+ phy-names:
-+ items:
-+ - const: dphy
-+
-+ ports:
-+ $ref: /schemas/graph.yaml#/properties/ports
-+
-+ properties:
-+ port@0:
-+ $ref: /schemas/graph.yaml#/$defs/port-base
-+ unevaluatedProperties: false
-+ description:
-+ Input port node, single endpoint describing the CSI-2 transmitter.
-+
-+ properties:
-+ endpoint:
-+ $ref: video-interfaces.yaml#
-+ unevaluatedProperties: false
-+
-+ properties:
-+ bus-type:
-+ const: 4
-+
-+ clock-lanes:
-+ const: 0
-+
-+ data-lanes:
-+ minItems: 1
-+ maxItems: 4
-+ items:
-+ maximum: 4
-+
-+ required:
-+ - data-lanes
-+
-+ port@1:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 0 Output port node
-+
-+ port@2:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 1 Output port node
-+
-+ port@3:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 2 Output port node
-+
-+ port@4:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 3 Output port node
-+
-+ required:
-+ - port@0
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - ports
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ csi@d060000 {
-+ compatible = "starfive,jh7110-csi2rx", "cdns,csi2rx";
-+ reg = <0x0d060000 0x1000>;
-+ clocks = <&byteclock 7>, <&byteclock 6>,
-+ <&coreclock 8>, <&coreclock 9>,
-+ <&coreclock 10>, <&coreclock 11>;
-+ clock-names = "sys_clk", "p_clk",
-+ "pixel_if0_clk", "pixel_if1_clk",
-+ "pixel_if2_clk", "pixel_if3_clk";
-+ phys = <&csi_phy>;
-+ phy-names = "dphy";
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+
-+ csi2rx_in_sensor: endpoint {
-+ remote-endpoint = <&sensor_out_csi2rx>;
-+ clock-lanes = <0>;
-+ data-lanes = <1 2>;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+
-+ csi2rx_out_grabber0: endpoint {
-+ remote-endpoint = <&grabber0_in_csi2rx>;
-+ };
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+
-+ csi2rx_out_grabber1: endpoint {
-+ remote-endpoint = <&grabber1_in_csi2rx>;
-+ };
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+
-+ csi2rx_out_grabber2: endpoint {
-+ remote-endpoint = <&grabber2_in_csi2rx>;
-+ };
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+
-+ csi2rx_out_grabber3: endpoint {
-+ remote-endpoint = <&grabber3_in_csi2rx>;
-+ };
-+ };
-+ };
-+ };
-+
-+...
diff --git a/target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch b/target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch
deleted file mode 100644
index 55b3fade7d..0000000000
--- a/target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 60817a4e755c6e98092fdceec35fcda94d35e4b1 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:23 +0800
-Subject: [PATCH 077/122] media: dt-bindings: cadence-csi2rx: Add resets
- property
-
-Add resets property for Cadence MIPI-CSI2 RX controller
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../bindings/media/cdns,csi2rx.yaml | 24 +++++++++++++++++++
- 1 file changed, 24 insertions(+)
-
---- a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-@@ -41,6 +41,24 @@ properties:
- - const: pixel_if2_clk
- - const: pixel_if3_clk
-
-+ resets:
-+ items:
-+ - description: CSI2Rx system reset
-+ - description: Gated Register bank reset for APB interface
-+ - description: pixel reset for Stream interface 0
-+ - description: pixel reset for Stream interface 1
-+ - description: pixel reset for Stream interface 2
-+ - description: pixel reset for Stream interface 3
-+
-+ reset-names:
-+ items:
-+ - const: sys
-+ - const: reg_bank
-+ - const: pixel_if0
-+ - const: pixel_if1
-+ - const: pixel_if2
-+ - const: pixel_if3
-+
- phys:
- maxItems: 1
- description: MIPI D-PHY
-@@ -123,6 +141,12 @@ examples:
- clock-names = "sys_clk", "p_clk",
- "pixel_if0_clk", "pixel_if1_clk",
- "pixel_if2_clk", "pixel_if3_clk";
-+ resets = <&bytereset 9>, <&bytereset 4>,
-+ <&corereset 5>, <&corereset 6>,
-+ <&corereset 7>, <&corereset 8>;
-+ reset-names = "sys", "reg_bank",
-+ "pixel_if0", "pixel_if1",
-+ "pixel_if2", "pixel_if3";
- phys = <&csi_phy>;
- phy-names = "dphy";
-
diff --git a/target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch b/target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch
deleted file mode 100644
index 2cc7b69089..0000000000
--- a/target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 2fbf4d367b25de4fa2f2d9cec57c88766c37d9de Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:24 +0800
-Subject: [PATCH 078/122] media: cadence: Add operation on reset
-
-Add operation on reset for Cadence MIPI-CSI2 RX Controller.
-
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/cadence/cdns-csi2rx.c | 40 +++++++++++++++++---
- 1 file changed, 35 insertions(+), 5 deletions(-)
-
---- a/drivers/media/platform/cadence/cdns-csi2rx.c
-+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
-@@ -13,6 +13,7 @@
- #include <linux/of_graph.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-+#include <linux/reset.h>
- #include <linux/slab.h>
-
- #include <media/v4l2-ctrls.h>
-@@ -68,6 +69,9 @@ struct csi2rx_priv {
- struct clk *sys_clk;
- struct clk *p_clk;
- struct clk *pixel_clk[CSI2RX_STREAMS_MAX];
-+ struct reset_control *sys_rst;
-+ struct reset_control *p_rst;
-+ struct reset_control *pixel_rst[CSI2RX_STREAMS_MAX];
- struct phy *dphy;
-
- u8 lanes[CSI2RX_LANES_MAX];
-@@ -112,6 +116,7 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- return ret;
-
-+ reset_control_deassert(csi2rx->p_rst);
- csi2rx_reset(csi2rx);
-
- reg = csi2rx->num_lanes << 8;
-@@ -154,6 +159,8 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- goto err_disable_pixclk;
-
-+ reset_control_deassert(csi2rx->pixel_rst[i]);
-+
- writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
- csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
-
-@@ -169,13 +176,16 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- goto err_disable_pixclk;
-
-+ reset_control_deassert(csi2rx->sys_rst);
- clk_disable_unprepare(csi2rx->p_clk);
-
- return 0;
-
- err_disable_pixclk:
-- for (; i > 0; i--)
-+ for (; i > 0; i--) {
-+ reset_control_assert(csi2rx->pixel_rst[i - 1]);
- clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
-+ }
-
- err_disable_pclk:
- clk_disable_unprepare(csi2rx->p_clk);
-@@ -188,14 +198,17 @@ static void csi2rx_stop(struct csi2rx_pr
- unsigned int i;
-
- clk_prepare_enable(csi2rx->p_clk);
-+ reset_control_assert(csi2rx->sys_rst);
- clk_disable_unprepare(csi2rx->sys_clk);
-
- for (i = 0; i < csi2rx->max_streams; i++) {
- writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
-
-+ reset_control_assert(csi2rx->pixel_rst[i]);
- clk_disable_unprepare(csi2rx->pixel_clk[i]);
- }
-
-+ reset_control_assert(csi2rx->p_rst);
- clk_disable_unprepare(csi2rx->p_clk);
-
- if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
-@@ -299,6 +312,16 @@ static int csi2rx_get_resources(struct c
- return PTR_ERR(csi2rx->p_clk);
- }
-
-+ csi2rx->sys_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
-+ "sys");
-+ if (IS_ERR(csi2rx->sys_rst))
-+ return PTR_ERR(csi2rx->sys_rst);
-+
-+ csi2rx->p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
-+ "reg_bank");
-+ if (IS_ERR(csi2rx->p_rst))
-+ return PTR_ERR(csi2rx->p_rst);
-+
- csi2rx->dphy = devm_phy_optional_get(&pdev->dev, "dphy");
- if (IS_ERR(csi2rx->dphy)) {
- dev_err(&pdev->dev, "Couldn't get external D-PHY\n");
-@@ -349,14 +372,21 @@ static int csi2rx_get_resources(struct c
- }
-
- for (i = 0; i < csi2rx->max_streams; i++) {
-- char clk_name[16];
-+ char name[16];
-
-- snprintf(clk_name, sizeof(clk_name), "pixel_if%u_clk", i);
-- csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name);
-+ snprintf(name, sizeof(name), "pixel_if%u_clk", i);
-+ csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, name);
- if (IS_ERR(csi2rx->pixel_clk[i])) {
-- dev_err(&pdev->dev, "Couldn't get clock %s\n", clk_name);
-+ dev_err(&pdev->dev, "Couldn't get clock %s\n", name);
- return PTR_ERR(csi2rx->pixel_clk[i]);
- }
-+
-+ snprintf(name, sizeof(name), "pixel_if%u", i);
-+ csi2rx->pixel_rst[i] =
-+ devm_reset_control_get_optional_exclusive(&pdev->dev,
-+ name);
-+ if (IS_ERR(csi2rx->pixel_rst[i]))
-+ return PTR_ERR(csi2rx->pixel_rst[i]);
- }
-
- return 0;
diff --git a/target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch b/target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch
deleted file mode 100644
index 77e506eb47..0000000000
--- a/target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From e97eb58b321b5b25b7d5c40880e6eb133d381581 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:25 +0800
-Subject: [PATCH 079/122] media: cadence: Add support for external dphy
-
-Add support for external MIPI D-PHY.
-
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/cadence/cdns-csi2rx.c | 66 +++++++++++++++++---
- 1 file changed, 56 insertions(+), 10 deletions(-)
-
---- a/drivers/media/platform/cadence/cdns-csi2rx.c
-+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
-@@ -31,6 +31,12 @@
- #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane) ((plane) << (16 + (llane) * 4))
- #define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8)
-
-+#define CSI2RX_DPHY_LANE_CTRL_REG 0x40
-+#define CSI2RX_DPHY_CL_RST BIT(16)
-+#define CSI2RX_DPHY_DL_RST(i) BIT((i) + 12)
-+#define CSI2RX_DPHY_CL_EN BIT(4)
-+#define CSI2RX_DPHY_DL_EN(i) BIT(i)
-+
- #define CSI2RX_STREAM_BASE(n) (((n) + 1) * 0x100)
-
- #define CSI2RX_STREAM_CTRL_REG(n) (CSI2RX_STREAM_BASE(n) + 0x000)
-@@ -105,6 +111,24 @@ static void csi2rx_reset(struct csi2rx_p
- writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
- }
-
-+static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx)
-+{
-+ union phy_configure_opts opts = { };
-+ int ret;
-+
-+ ret = phy_power_on(csi2rx->dphy);
-+ if (ret)
-+ return ret;
-+
-+ ret = phy_configure(csi2rx->dphy, &opts);
-+ if (ret) {
-+ phy_power_off(csi2rx->dphy);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int csi2rx_start(struct csi2rx_priv *csi2rx)
- {
- unsigned int i;
-@@ -144,6 +168,17 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- goto err_disable_pclk;
-
-+ /* Enable DPHY clk and data lanes. */
-+ if (csi2rx->dphy) {
-+ reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST;
-+ for (i = 0; i < csi2rx->num_lanes; i++) {
-+ reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1);
-+ reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1);
-+ }
-+
-+ writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
-+ }
-+
- /*
- * Create a static mapping between the CSI virtual channels
- * and the output stream.
-@@ -177,10 +212,22 @@ static int csi2rx_start(struct csi2rx_pr
- goto err_disable_pixclk;
-
- reset_control_deassert(csi2rx->sys_rst);
-+
-+ if (csi2rx->dphy) {
-+ ret = csi2rx_configure_ext_dphy(csi2rx);
-+ if (ret) {
-+ dev_err(csi2rx->dev,
-+ "Failed to configure external DPHY: %d\n", ret);
-+ goto err_disable_sysclk;
-+ }
-+ }
-+
- clk_disable_unprepare(csi2rx->p_clk);
-
- return 0;
-
-+err_disable_sysclk:
-+ clk_disable_unprepare(csi2rx->sys_clk);
- err_disable_pixclk:
- for (; i > 0; i--) {
- reset_control_assert(csi2rx->pixel_rst[i - 1]);
-@@ -213,6 +260,13 @@ static void csi2rx_stop(struct csi2rx_pr
-
- if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
- dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
-+
-+ if (csi2rx->dphy) {
-+ writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
-+
-+ if (phy_power_off(csi2rx->dphy))
-+ dev_warn(csi2rx->dev, "Couldn't power off DPHY\n");
-+ }
- }
-
- static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
-@@ -328,15 +382,6 @@ static int csi2rx_get_resources(struct c
- return PTR_ERR(csi2rx->dphy);
- }
-
-- /*
-- * FIXME: Once we'll have external D-PHY support, the check
-- * will need to be removed.
-- */
-- if (csi2rx->dphy) {
-- dev_err(&pdev->dev, "External D-PHY not supported yet\n");
-- return -EINVAL;
-- }
--
- ret = clk_prepare_enable(csi2rx->p_clk);
- if (ret) {
- dev_err(&pdev->dev, "Couldn't prepare and enable P clock\n");
-@@ -366,7 +411,7 @@ static int csi2rx_get_resources(struct c
- * FIXME: Once we'll have internal D-PHY support, the check
- * will need to be removed.
- */
-- if (csi2rx->has_internal_dphy) {
-+ if (!csi2rx->dphy && csi2rx->has_internal_dphy) {
- dev_err(&pdev->dev, "Internal D-PHY not supported yet\n");
- return -EINVAL;
- }
-@@ -494,6 +539,7 @@ static int csi2rx_probe(struct platform_
- dev_info(&pdev->dev,
- "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n",
- csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams,
-+ csi2rx->dphy ? "external" :
- csi2rx->has_internal_dphy ? "internal" : "no");
-
- return 0;
diff --git a/target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch b/target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch
deleted file mode 100644
index f3527840b6..0000000000
--- a/target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From d541f0ab42983dbc856f2229ee471677e80945a3 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:26 +0800
-Subject: [PATCH 080/122] media: cadence: Add support for JH7110 SoC
-
-Add support for Starfive JH7110 SoC which has the cadence csi2 receiver.
-
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/media/platform/cadence/cdns-csi2rx.c
-+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
-@@ -565,6 +565,7 @@ static int csi2rx_remove(struct platform
- }
-
- static const struct of_device_id csi2rx_of_table[] = {
-+ { .compatible = "starfive,jh7110-csi2rx" },
- { .compatible = "cdns,csi2rx" },
- { },
- };
diff --git a/target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch b/target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch
deleted file mode 100644
index 0b3bf80b46..0000000000
--- a/target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch
+++ /dev/null
@@ -1,197 +0,0 @@
-From f3195b45a3845fd3892ca932a9cc8e352942dbcd Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:39 +0800
-Subject: [PATCH 081/122] media: dt-bindings: Add JH7110 Camera Subsystem
-
-Add the bindings documentation for Starfive JH7110 Camera Subsystem
-which is used for handing image sensor data.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../bindings/media/starfive,jh7110-camss.yaml | 179 ++++++++++++++++++
- 1 file changed, 179 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
-@@ -0,0 +1,179 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/media/starfive,jh7110-camss.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Starfive SoC CAMSS ISP
-+
-+maintainers:
-+ - Jack Zhu <jack.zhu@starfivetech.com>
-+ - Changhuang Liang <changhuang.liang@starfivetech.com>
-+
-+description:
-+ The Starfive CAMSS ISP is a Camera interface for Starfive JH7110 SoC. It
-+ consists of a VIN controller (Video In Controller, a top-level control until)
-+ and an ISP.
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-camss
-+
-+ reg:
-+ maxItems: 2
-+
-+ reg-names:
-+ items:
-+ - const: syscon
-+ - const: isp
-+
-+ clocks:
-+ maxItems: 7
-+
-+ clock-names:
-+ items:
-+ - const: apb_func
-+ - const: wrapper_clk_c
-+ - const: dvp_inv
-+ - const: axiwr
-+ - const: mipi_rx0_pxl
-+ - const: ispcore_2x
-+ - const: isp_axi
-+
-+ resets:
-+ maxItems: 6
-+
-+ reset-names:
-+ items:
-+ - const: wrapper_p
-+ - const: wrapper_c
-+ - const: axird
-+ - const: axiwr
-+ - const: isp_top_n
-+ - const: isp_top_axi
-+
-+ power-domains:
-+ items:
-+ - description: JH7110 ISP Power Domain Switch Controller.
-+
-+ interrupts:
-+ maxItems: 4
-+
-+ ports:
-+ $ref: /schemas/graph.yaml#/properties/ports
-+
-+ properties:
-+ port@0:
-+ $ref: /schemas/graph.yaml#/$defs/port-base
-+ unevaluatedProperties: false
-+ description: Input port for receiving DVP data.
-+
-+ properties:
-+ endpoint:
-+ $ref: video-interfaces.yaml#
-+ unevaluatedProperties: false
-+
-+ properties:
-+ bus-type:
-+ enum: [5, 6]
-+
-+ bus-width:
-+ enum: [8, 10, 12]
-+
-+ data-shift:
-+ enum: [0, 2]
-+ default: 0
-+
-+ hsync-active:
-+ enum: [0, 1]
-+ default: 1
-+
-+ vsync-active:
-+ enum: [0, 1]
-+ default: 1
-+
-+ required:
-+ - bus-type
-+ - bus-width
-+
-+ port@1:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description: Input port for receiving CSI data.
-+
-+ required:
-+ - port@0
-+ - port@1
-+
-+required:
-+ - compatible
-+ - reg
-+ - reg-names
-+ - clocks
-+ - clock-names
-+ - resets
-+ - reset-names
-+ - power-domains
-+ - interrupts
-+ - ports
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ isp@19840000 {
-+ compatible = "starfive,jh7110-camss";
-+ reg = <0x19840000 0x10000>,
-+ <0x19870000 0x30000>;
-+ reg-names = "syscon", "isp";
-+ clocks = <&ispcrg 0>,
-+ <&ispcrg 13>,
-+ <&ispcrg 2>,
-+ <&ispcrg 12>,
-+ <&ispcrg 1>,
-+ <&syscrg 51>,
-+ <&syscrg 52>;
-+ clock-names = "apb_func",
-+ "wrapper_clk_c",
-+ "dvp_inv",
-+ "axiwr",
-+ "mipi_rx0_pxl",
-+ "ispcore_2x",
-+ "isp_axi";
-+ resets = <&ispcrg 0>,
-+ <&ispcrg 1>,
-+ <&ispcrg 10>,
-+ <&ispcrg 11>,
-+ <&syscrg 41>,
-+ <&syscrg 42>;
-+ reset-names = "wrapper_p",
-+ "wrapper_c",
-+ "axird",
-+ "axiwr",
-+ "isp_top_n",
-+ "isp_top_axi";
-+ power-domains = <&pwrc 5>;
-+ interrupts = <92>, <87>, <88>, <90>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ port@0 {
-+ reg = <0>;
-+ vin_from_sc2235: endpoint {
-+ remote-endpoint = <&sc2235_to_vin>;
-+ bus-width = <8>;
-+ data-shift = <2>;
-+ hsync-active = <1>;
-+ vsync-active = <0>;
-+ pclk-sample = <1>;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ vin_from_csi2rx: endpoint {
-+ remote-endpoint = <&csi2rx_to_vin>;
-+ };
-+ };
-+ };
-+ };
diff --git a/target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch b/target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch
deleted file mode 100644
index 7d59112e8e..0000000000
--- a/target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 949807343300a75b6e7c3e47463f817a7b6bc790 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:40 +0800
-Subject: [PATCH 082/122] media: admin-guide: Add starfive_camss.rst for
- Starfive Camera Subsystem
-
-Add starfive_camss.rst file that documents the Starfive Camera
-Subsystem driver which is used for handing image sensor data.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../admin-guide/media/starfive_camss.rst | 57 +++++++++++++++++++
- .../media/starfive_camss_graph.dot | 16 ++++++
- .../admin-guide/media/v4l-drivers.rst | 1 +
- 3 files changed, 74 insertions(+)
- create mode 100644 Documentation/admin-guide/media/starfive_camss.rst
- create mode 100644 Documentation/admin-guide/media/starfive_camss_graph.dot
-
---- /dev/null
-+++ b/Documentation/admin-guide/media/starfive_camss.rst
-@@ -0,0 +1,57 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+
-+.. include:: <isonum.txt>
-+
-+================================
-+Starfive Camera Subsystem driver
-+================================
-+
-+Introduction
-+------------
-+
-+This file documents the driver for the Starfive Camera Subsystem found on
-+Starfive JH7110 SoC. The driver is located under drivers/media/platform/
-+starfive.
-+
-+The driver implements V4L2, Media controller and v4l2_subdev interfaces.
-+Camera sensor using V4L2 subdev interface in the kernel is supported.
-+
-+The driver has been successfully used on the Gstreamer 1.18.5 with
-+v4l2src plugin.
-+
-+
-+Starfive Camera Subsystem hardware
-+----------------------------------
-+
-+The Starfive Camera Subsystem hardware consists of:
-+
-+- MIPI DPHY Receiver: receives mipi data from a MIPI camera sensor.
-+- MIPI CSIRx Controller: is responsible for handling and decoding CSI2 protocol
-+ based camera sensor data stream.
-+- ISP: handles the image data streams from the MIPI CSIRx Controller.
-+- VIN(Video In): a top-level module, is responsible for controlling power
-+ and clocks to other modules, dumps the input data to memory or transfers the
-+ input data to ISP.
-+
-+
-+Topology
-+--------
-+
-+The media controller pipeline graph is as follows:
-+
-+.. _starfive_camss_graph:
-+
-+.. kernel-figure:: starfive_camss_graph.dot
-+ :alt: starfive_camss_graph.dot
-+ :align: center
-+
-+The driver has 2 video devices:
-+
-+- stf_vin0_wr_video0: capture device for images directly from the VIN module.
-+- stf_vin0_isp0_video1: capture device for images without scaling.
-+
-+The driver has 3 subdevices:
-+
-+- stf_isp0: is responsible for all the isp operations.
-+- stf_vin0_wr: used to dump RAW images to memory.
-+- stf_vin0_isp0: used to capture images for the stf_vin0_isp0_video1 device.
---- /dev/null
-+++ b/Documentation/admin-guide/media/starfive_camss_graph.dot
-@@ -0,0 +1,16 @@
-+digraph board {
-+ rankdir=TB
-+ n00000001 [label="{{<port0> 0} | stf_isp0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000001:port1 -> n0000000d:port0
-+ n00000004 [label="{{<port0> 0} | stf_vin0_wr\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000004:port1 -> n00000007 [style=bold]
-+ n00000007 [label="stf_vin0_wr_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
-+ n0000000d [label="{{<port0> 0} | stf_vin0_isp0\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n0000000d:port1 -> n00000010 [style=bold]
-+ n00000010 [label="stf_vin0_isp0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
-+ n00000018 [label="{{<port0> 0} | cdns_csi2rx.19800000.csi-bridge\n | {<port1> 1 | <port2> 2 | <port3> 3 | <port4> 4}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000018:port1 -> n00000004:port0 [style=dashed]
-+ n00000018:port1 -> n00000001:port0
-+ n00000028 [label="{{} | imx219 6-0010\n | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000028:port0 -> n00000018:port0 [style=bold]
-+}
---- a/Documentation/admin-guide/media/v4l-drivers.rst
-+++ b/Documentation/admin-guide/media/v4l-drivers.rst
-@@ -30,5 +30,6 @@ Video4Linux (V4L) driver-specific docume
- si470x
- si4713
- si476x
-+ starfive_camss
- vimc
- vivid
diff --git a/target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch b/target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch
deleted file mode 100644
index bc5141cfbc..0000000000
--- a/target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch
+++ /dev/null
@@ -1,630 +0,0 @@
-From 0dc93c9321ba947ac429baeb58202496e4b0f219 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:41 +0800
-Subject: [PATCH 083/122] media: starfive: Add basic driver
-
-Add basic platform driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
-Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
----
- drivers/media/platform/Kconfig | 1 +
- drivers/media/platform/Makefile | 1 +
- drivers/media/platform/starfive/Kconfig | 19 +
- drivers/media/platform/starfive/Makefile | 9 +
- drivers/media/platform/starfive/stf_camss.c | 372 +++++++++++++++++++
- drivers/media/platform/starfive/stf_camss.h | 153 ++++++++
- drivers/media/platform/starfive/stf_common.h | 18 +
- 7 files changed, 573 insertions(+)
- create mode 100644 drivers/media/platform/starfive/Kconfig
- create mode 100644 drivers/media/platform/starfive/Makefile
- create mode 100644 drivers/media/platform/starfive/stf_camss.c
- create mode 100644 drivers/media/platform/starfive/stf_camss.h
- create mode 100644 drivers/media/platform/starfive/stf_common.h
-
---- a/drivers/media/platform/Kconfig
-+++ b/drivers/media/platform/Kconfig
-@@ -79,6 +79,7 @@ source "drivers/media/platform/renesas/K
- source "drivers/media/platform/rockchip/Kconfig"
- source "drivers/media/platform/samsung/Kconfig"
- source "drivers/media/platform/st/Kconfig"
-+source "drivers/media/platform/starfive/Kconfig"
- source "drivers/media/platform/sunxi/Kconfig"
- source "drivers/media/platform/ti/Kconfig"
- source "drivers/media/platform/verisilicon/Kconfig"
---- a/drivers/media/platform/Makefile
-+++ b/drivers/media/platform/Makefile
-@@ -22,6 +22,7 @@ obj-y += renesas/
- obj-y += rockchip/
- obj-y += samsung/
- obj-y += st/
-+obj-y += starfive/
- obj-y += sunxi/
- obj-y += ti/
- obj-y += verisilicon/
---- /dev/null
-+++ b/drivers/media/platform/starfive/Kconfig
-@@ -0,0 +1,19 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+
-+comment "Starfive media platform drivers"
-+
-+config VIDEO_STARFIVE_CAMSS
-+ tristate "Starfive Camera Subsystem driver"
-+ depends on V4L_PLATFORM_DRIVERS
-+ depends on VIDEO_DEV && OF
-+ depends on DMA_CMA
-+ select MEDIA_CONTROLLER
-+ select VIDEO_V4L2_SUBDEV_API
-+ select VIDEOBUF2_DMA_CONTIG
-+ select V4L2_FWNODE
-+ help
-+ Enable this to support for the Starfive Camera subsystem
-+ found on Starfive JH7110 SoC.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called stf-camss.
---- /dev/null
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -0,0 +1,9 @@
-+# SPDX-License-Identifier: GPL-2.0
-+#
-+# Makefile for StarFive camera subsystem driver.
-+#
-+
-+starfive-camss-objs += \
-+ stf_camss.o
-+
-+obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_camss.c
-@@ -0,0 +1,372 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_camss.c
-+ *
-+ * Starfive Camera Subsystem driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_graph.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/videodev2.h>
-+#include <media/media-device.h>
-+#include <media/v4l2-async.h>
-+#include <media/v4l2-fwnode.h>
-+#include <media/v4l2-mc.h>
-+
-+#include "stf_camss.h"
-+
-+static const char * const stfcamss_clocks[] = {
-+ "clk_apb_func",
-+ "clk_wrapper_clk_c",
-+ "clk_dvp_inv",
-+ "clk_axiwr",
-+ "clk_mipi_rx0_pxl",
-+ "clk_ispcore_2x",
-+ "clk_isp_axi",
-+};
-+
-+static const char * const stfcamss_resets[] = {
-+ "rst_wrapper_p",
-+ "rst_wrapper_c",
-+ "rst_axird",
-+ "rst_axiwr",
-+ "rst_isp_top_n",
-+ "rst_isp_top_axi",
-+};
-+
-+static int stfcamss_get_mem_res(struct platform_device *pdev,
-+ struct stfcamss *stfcamss)
-+{
-+ stfcamss->syscon_base =
-+ devm_platform_ioremap_resource_byname(pdev, "syscon");
-+ if (IS_ERR(stfcamss->syscon_base))
-+ return PTR_ERR(stfcamss->syscon_base);
-+
-+ stfcamss->isp_base =
-+ devm_platform_ioremap_resource_byname(pdev, "isp");
-+ if (IS_ERR(stfcamss->isp_base))
-+ return PTR_ERR(stfcamss->isp_base);
-+
-+ return 0;
-+}
-+
-+/*
-+ * stfcamss_of_parse_endpoint_node - Parse port endpoint node
-+ * @dev: Device
-+ * @node: Device node to be parsed
-+ * @csd: Parsed data from port endpoint node
-+ *
-+ * Return 0 on success or a negative error code on failure
-+ */
-+static int stfcamss_of_parse_endpoint_node(struct device *dev,
-+ struct device_node *node,
-+ struct stfcamss_async_subdev *csd)
-+{
-+ struct v4l2_fwnode_endpoint vep = { { 0 } };
-+
-+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
-+ dev_dbg(dev, "vep.base.port = 0x%x, id = 0x%x\n",
-+ vep.base.port, vep.base.id);
-+
-+ csd->port = vep.base.port;
-+
-+ return 0;
-+}
-+
-+/*
-+ * stfcamss_of_parse_ports - Parse ports node
-+ * @stfcamss: STFCAMSS device
-+ *
-+ * Return number of "port" nodes found in "ports" node
-+ */
-+static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
-+{
-+ struct device *dev = stfcamss->dev;
-+ struct device_node *node = NULL;
-+ struct device_node *remote = NULL;
-+ int ret, num_subdevs = 0;
-+
-+ for_each_endpoint_of_node(dev->of_node, node) {
-+ struct stfcamss_async_subdev *csd;
-+
-+ if (!of_device_is_available(node))
-+ continue;
-+
-+ remote = of_graph_get_remote_port_parent(node);
-+ if (!remote) {
-+ dev_err(dev, "Cannot get remote parent\n");
-+ ret = -EINVAL;
-+ goto err_cleanup;
-+ }
-+
-+ csd = v4l2_async_nf_add_fwnode(&stfcamss->notifier,
-+ of_fwnode_handle(remote),
-+ struct stfcamss_async_subdev);
-+ of_node_put(remote);
-+ if (IS_ERR(csd)) {
-+ ret = PTR_ERR(csd);
-+ goto err_cleanup;
-+ }
-+
-+ ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
-+ if (ret < 0)
-+ goto err_cleanup;
-+
-+ num_subdevs++;
-+ }
-+
-+ return num_subdevs;
-+
-+err_cleanup:
-+ of_node_put(node);
-+ return ret;
-+}
-+
-+static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
-+ struct v4l2_subdev *subdev,
-+ struct v4l2_async_subdev *asd)
-+{
-+ struct stfcamss *stfcamss =
-+ container_of(async, struct stfcamss, notifier);
-+ struct host_data *host_data = &stfcamss->host_data;
-+ struct media_entity *source;
-+ int i, j;
-+
-+ source = &subdev->entity;
-+
-+ for (i = 0; i < source->num_pads; i++) {
-+ if (source->pads[i].flags & MEDIA_PAD_FL_SOURCE)
-+ break;
-+ }
-+
-+ if (i == source->num_pads) {
-+ dev_err(stfcamss->dev, "No source pad in external entity\n");
-+ return -EINVAL;
-+ }
-+
-+ for (j = 0; host_data->host_entity[j] && (j < HOST_ENTITY_MAX); j++) {
-+ struct media_entity *input;
-+ int ret;
-+
-+ input = host_data->host_entity[j];
-+
-+ ret = media_create_pad_link(
-+ source,
-+ i,
-+ input,
-+ STF_PAD_SINK,
-+ source->function == MEDIA_ENT_F_CAM_SENSOR ?
-+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED :
-+ 0);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to link %s->%s entities: %d\n",
-+ source->name, input->name, ret);
-+ return ret;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int stfcamss_subdev_notifier_complete(struct v4l2_async_notifier *ntf)
-+{
-+ struct stfcamss *stfcamss =
-+ container_of(ntf, struct stfcamss, notifier);
-+
-+ return v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
-+}
-+
-+static const struct v4l2_async_notifier_operations
-+stfcamss_subdev_notifier_ops = {
-+ .bound = stfcamss_subdev_notifier_bound,
-+ .complete = stfcamss_subdev_notifier_complete,
-+};
-+
-+static const struct media_device_ops stfcamss_media_ops = {
-+ .link_notify = v4l2_pipeline_link_notify,
-+};
-+
-+static void stfcamss_mc_init(struct platform_device *pdev,
-+ struct stfcamss *stfcamss)
-+{
-+ stfcamss->media_dev.dev = stfcamss->dev;
-+ strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
-+ sizeof(stfcamss->media_dev.model));
-+ snprintf(stfcamss->media_dev.bus_info,
-+ sizeof(stfcamss->media_dev.bus_info),
-+ "%s:%s", dev_bus_name(&pdev->dev), pdev->name);
-+ stfcamss->media_dev.hw_revision = 0x01;
-+ stfcamss->media_dev.ops = &stfcamss_media_ops;
-+ media_device_init(&stfcamss->media_dev);
-+
-+ stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
-+}
-+
-+/*
-+ * stfcamss_probe - Probe STFCAMSS platform device
-+ * @pdev: Pointer to STFCAMSS platform device
-+ *
-+ * Return 0 on success or a negative error code on failure
-+ */
-+static int stfcamss_probe(struct platform_device *pdev)
-+{
-+ struct stfcamss *stfcamss;
-+ struct device *dev = &pdev->dev;
-+ int ret = 0, i, num_subdevs;
-+
-+ stfcamss = devm_kzalloc(dev, sizeof(*stfcamss), GFP_KERNEL);
-+ if (!stfcamss)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < ARRAY_SIZE(stfcamss->irq); ++i) {
-+ stfcamss->irq[i] = platform_get_irq(pdev, i);
-+ if (stfcamss->irq[i] < 0)
-+ return dev_err_probe(&pdev->dev, stfcamss->irq[i],
-+ "Failed to get clock%d", i);
-+ }
-+
-+ stfcamss->nclks = ARRAY_SIZE(stfcamss->sys_clk);
-+ for (i = 0; i < ARRAY_SIZE(stfcamss->sys_clk); ++i)
-+ stfcamss->sys_clk[i].id = stfcamss_clocks[i];
-+ ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
-+ if (ret) {
-+ dev_err(dev, "Failed to get clk controls\n");
-+ return ret;
-+ }
-+
-+ stfcamss->nrsts = ARRAY_SIZE(stfcamss->sys_rst);
-+ for (i = 0; i < ARRAY_SIZE(stfcamss->sys_rst); ++i)
-+ stfcamss->sys_rst[i].id = stfcamss_resets[i];
-+ ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
-+ stfcamss->sys_rst);
-+ if (ret) {
-+ dev_err(dev, "Failed to get reset controls\n");
-+ return ret;
-+ }
-+
-+ ret = stfcamss_get_mem_res(pdev, stfcamss);
-+ if (ret) {
-+ dev_err(dev, "Could not map registers\n");
-+ return ret;
-+ }
-+
-+ stfcamss->dev = dev;
-+ platform_set_drvdata(pdev, stfcamss);
-+
-+ v4l2_async_nf_init(&stfcamss->notifier);
-+
-+ num_subdevs = stfcamss_of_parse_ports(stfcamss);
-+ if (num_subdevs < 0) {
-+ dev_err(dev, "Failed to find subdevices\n");
-+ return -ENODEV;
-+ }
-+
-+ stfcamss_mc_init(pdev, stfcamss);
-+
-+ ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
-+ goto err_cleanup_notifier;
-+ }
-+
-+ ret = media_device_register(&stfcamss->media_dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to register media device: %d\n", ret);
-+ goto err_unregister_device;
-+ }
-+
-+ stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
-+ ret = v4l2_async_nf_register(&stfcamss->v4l2_dev, &stfcamss->notifier);
-+ if (ret) {
-+ dev_err(dev, "Failed to register async subdev nodes: %d\n",
-+ ret);
-+ goto err_unregister_media_dev;
-+ }
-+
-+ pm_runtime_enable(dev);
-+
-+ return 0;
-+
-+err_unregister_media_dev:
-+ media_device_unregister(&stfcamss->media_dev);
-+err_unregister_device:
-+ v4l2_device_unregister(&stfcamss->v4l2_dev);
-+err_cleanup_notifier:
-+ v4l2_async_nf_cleanup(&stfcamss->notifier);
-+ return ret;
-+}
-+
-+/*
-+ * stfcamss_remove - Remove STFCAMSS platform device
-+ * @pdev: Pointer to STFCAMSS platform device
-+ *
-+ * Always returns 0.
-+ */
-+static int stfcamss_remove(struct platform_device *pdev)
-+{
-+ struct stfcamss *stfcamss = platform_get_drvdata(pdev);
-+
-+ v4l2_device_unregister(&stfcamss->v4l2_dev);
-+ media_device_cleanup(&stfcamss->media_dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id stfcamss_of_match[] = {
-+ { .compatible = "starfive,jh7110-camss" },
-+ { /* sentinel */ },
-+};
-+
-+MODULE_DEVICE_TABLE(of, stfcamss_of_match);
-+
-+static int __maybe_unused stfcamss_runtime_suspend(struct device *dev)
-+{
-+ struct stfcamss *stfcamss = dev_get_drvdata(dev);
-+
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
-+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
-+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused stfcamss_runtime_resume(struct device *dev)
-+{
-+ struct stfcamss *stfcamss = dev_get_drvdata(dev);
-+
-+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
-+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
-+
-+ return 0;
-+}
-+
-+static const struct dev_pm_ops stfcamss_pm_ops = {
-+ SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend,
-+ stfcamss_runtime_resume,
-+ NULL)
-+};
-+
-+static struct platform_driver stfcamss_driver = {
-+ .probe = stfcamss_probe,
-+ .remove = stfcamss_remove,
-+ .driver = {
-+ .name = DRV_NAME,
-+ .pm = &stfcamss_pm_ops,
-+ .of_match_table = of_match_ptr(stfcamss_of_match),
-+ },
-+};
-+
-+module_platform_driver(stfcamss_driver);
-+
-+MODULE_AUTHOR("StarFive Corporation");
-+MODULE_DESCRIPTION("StarFive Camera Subsystem driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_camss.h
-@@ -0,0 +1,153 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_camss.h
-+ *
-+ * Starfive Camera Subsystem driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_CAMSS_H
-+#define STF_CAMSS_H
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/reset.h>
-+#include <media/v4l2-device.h>
-+
-+#include "stf_common.h"
-+
-+#define DRV_NAME "starfive-camss"
-+#define STF_DVP_NAME "stf_dvp"
-+#define STF_CSI_NAME "cdns_csi2rx"
-+#define STF_ISP_NAME "stf_isp"
-+#define STF_VIN_NAME "stf_vin"
-+
-+#define STF_PAD_SINK 0
-+#define STF_PAD_SRC 1
-+#define STF_PADS_NUM 2
-+
-+enum port_num {
-+ PORT_NUMBER_DVP_SENSOR = 0,
-+ PORT_NUMBER_CSI2RX
-+};
-+
-+enum stf_clk {
-+ STF_CLK_APB_FUNC = 0,
-+ STF_CLK_WRAPPER_CLK_C,
-+ STF_CLK_DVP_INV,
-+ STF_CLK_AXIWR,
-+ STF_CLK_MIPI_RX0_PXL,
-+ STF_CLK_ISPCORE_2X,
-+ STF_CLK_ISP_AXI,
-+ STF_CLK_NUM
-+};
-+
-+enum stf_rst {
-+ STF_RST_WRAPPER_P = 0,
-+ STF_RST_WRAPPER_C,
-+ STF_RST_AXIRD,
-+ STF_RST_AXIWR,
-+ STF_RST_ISP_TOP_N,
-+ STF_RST_ISP_TOP_AXI,
-+ STF_RST_NUM
-+};
-+
-+enum stf_irq {
-+ STF_IRQ_VINWR = 0,
-+ STF_IRQ_ISP,
-+ STF_IRQ_ISPCSIL,
-+ STF_IRQ_NUM
-+};
-+
-+#define HOST_ENTITY_MAX 2
-+
-+struct host_data {
-+ struct media_entity *host_entity[HOST_ENTITY_MAX];
-+};
-+
-+struct stfcamss {
-+ struct v4l2_device v4l2_dev;
-+ struct media_device media_dev;
-+ struct media_pipeline pipe;
-+ struct device *dev;
-+ struct v4l2_async_notifier notifier;
-+ struct host_data host_data;
-+ void __iomem *syscon_base;
-+ void __iomem *isp_base;
-+ int irq[STF_IRQ_NUM];
-+ struct clk_bulk_data sys_clk[STF_CLK_NUM];
-+ int nclks;
-+ struct reset_control_bulk_data sys_rst[STF_RST_NUM];
-+ int nrsts;
-+};
-+
-+struct stfcamss_async_subdev {
-+ struct v4l2_async_subdev asd; /* must be first */
-+ enum port_num port;
-+};
-+
-+static inline u32 stf_isp_reg_read(struct stfcamss *stfcamss, u32 reg)
-+{
-+ return ioread32(stfcamss->isp_base + reg);
-+}
-+
-+static inline void stf_isp_reg_write(struct stfcamss *stfcamss,
-+ u32 reg, u32 val)
-+{
-+ iowrite32(val, stfcamss->isp_base + reg);
-+}
-+
-+static inline void stf_isp_reg_write_delay(struct stfcamss *stfcamss,
-+ u32 reg, u32 val, u32 delay)
-+{
-+ iowrite32(val, stfcamss->isp_base + reg);
-+ usleep_range(1000 * delay, 1000 * delay + 100);
-+}
-+
-+static inline void stf_isp_reg_set_bit(struct stfcamss *stfcamss,
-+ u32 reg, u32 mask, u32 val)
-+{
-+ u32 value;
-+
-+ value = ioread32(stfcamss->isp_base + reg) & ~mask;
-+ val &= mask;
-+ val |= value;
-+ iowrite32(val, stfcamss->isp_base + reg);
-+}
-+
-+static inline void stf_isp_reg_set(struct stfcamss *stfcamss, u32 reg, u32 mask)
-+{
-+ iowrite32(ioread32(stfcamss->isp_base + reg) | mask,
-+ stfcamss->isp_base + reg);
-+}
-+
-+static inline u32 stf_syscon_reg_read(struct stfcamss *stfcamss, u32 reg)
-+{
-+ return ioread32(stfcamss->syscon_base + reg);
-+}
-+
-+static inline void stf_syscon_reg_write(struct stfcamss *stfcamss,
-+ u32 reg, u32 val)
-+{
-+ iowrite32(val, stfcamss->syscon_base + reg);
-+}
-+
-+static inline void stf_syscon_reg_set_bit(struct stfcamss *stfcamss,
-+ u32 reg, u32 bit_mask)
-+{
-+ u32 value;
-+
-+ value = ioread32(stfcamss->syscon_base + reg);
-+ iowrite32(value | bit_mask, stfcamss->syscon_base + reg);
-+}
-+
-+static inline void stf_syscon_reg_clear_bit(struct stfcamss *stfcamss,
-+ u32 reg, u32 bit_mask)
-+{
-+ u32 value;
-+
-+ value = ioread32(stfcamss->syscon_base + reg);
-+ iowrite32(value & ~bit_mask, stfcamss->syscon_base + reg);
-+}
-+#endif /* STF_CAMSS_H */
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_common.h
-@@ -0,0 +1,18 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_common.h
-+ *
-+ * StarFive Camera Subsystem - Common definitions
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_COMMON_H
-+#define STF_COMMON_H
-+
-+enum stf_subdev_type {
-+ STF_SUBDEV_TYPE_VIN,
-+ STF_SUBDEV_TYPE_ISP,
-+};
-+
-+#endif /* STF_COMMON_H */
diff --git a/target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch b/target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch
deleted file mode 100644
index f9317485a2..0000000000
--- a/target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch
+++ /dev/null
@@ -1,992 +0,0 @@
-From 70a588f7daefe34697ccd04fa6ac3a6d4b63be88 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:42 +0800
-Subject: [PATCH 084/122] media: starfive: Add video driver
-
-Add video driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/starfive/Makefile | 3 +-
- drivers/media/platform/starfive/stf_video.c | 864 ++++++++++++++++++++
- drivers/media/platform/starfive/stf_video.h | 95 +++
- 3 files changed, 961 insertions(+), 1 deletion(-)
- create mode 100644 drivers/media/platform/starfive/stf_video.c
- create mode 100644 drivers/media/platform/starfive/stf_video.h
-
---- a/drivers/media/platform/starfive/Makefile
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -4,6 +4,7 @@
- #
-
- starfive-camss-objs += \
-- stf_camss.o
-+ stf_camss.o \
-+ stf_video.o
-
- obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_video.c
-@@ -0,0 +1,864 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_video.c
-+ *
-+ * StarFive Camera Subsystem - V4L2 device node
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <media/media-entity.h>
-+#include <media/v4l2-ctrls.h>
-+#include <media/v4l2-event.h>
-+#include <media/v4l2-mc.h>
-+#include <media/videobuf2-dma-contig.h>
-+
-+#include "stf_camss.h"
-+#include "stf_video.h"
-+
-+static const struct stfcamss_format_info formats_pix_wr[] = {
-+ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+};
-+
-+static const struct stfcamss_format_info formats_pix_isp[] = {
-+ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV12, 1,
-+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * Helper functions
-+ */
-+
-+static int video_find_format(u32 code, u32 pixelformat,
-+ const struct stfcamss_format_info *formats,
-+ unsigned int nformats)
-+{
-+ int i;
-+
-+ for (i = 0; i < nformats; i++) {
-+ if (formats[i].code == code &&
-+ formats[i].pixelformat == pixelformat)
-+ return i;
-+ }
-+
-+ for (i = 0; i < nformats; i++)
-+ if (formats[i].code == code)
-+ return i;
-+
-+ for (i = 0; i < nformats; i++)
-+ if (formats[i].pixelformat == pixelformat)
-+ return i;
-+
-+ return -EINVAL;
-+}
-+
-+static int __video_try_fmt(struct stfcamss_video *video, struct v4l2_format *f)
-+{
-+ struct v4l2_pix_format *pix;
-+ const struct stfcamss_format_info *fi;
-+ u32 width, height;
-+ u32 bpl;
-+ int i;
-+
-+ pix = &f->fmt.pix;
-+
-+ for (i = 0; i < video->nformats; i++)
-+ if (pix->pixelformat == video->formats[i].pixelformat)
-+ break;
-+
-+ if (i == video->nformats)
-+ i = 0; /* default format */
-+
-+ fi = &video->formats[i];
-+ width = pix->width;
-+ height = pix->height;
-+
-+ memset(pix, 0, sizeof(*pix));
-+
-+ pix->pixelformat = fi->pixelformat;
-+ pix->width = clamp_t(u32, width, STFCAMSS_FRAME_MIN_WIDTH,
-+ STFCAMSS_FRAME_MAX_WIDTH);
-+ pix->height = clamp_t(u32, height, STFCAMSS_FRAME_MIN_HEIGHT,
-+ STFCAMSS_FRAME_MAX_HEIGHT);
-+ bpl = pix->width / fi->hsub[0].numerator *
-+ fi->hsub[0].denominator * fi->bpp[0] / 8;
-+ bpl = ALIGN(bpl, video->bpl_alignment);
-+ pix->bytesperline = bpl;
-+ pix->sizeimage = pix->height / fi->vsub[0].numerator *
-+ fi->vsub[0].denominator * bpl;
-+
-+ pix->field = V4L2_FIELD_NONE;
-+ pix->colorspace = V4L2_COLORSPACE_SRGB;
-+ pix->flags = 0;
-+ pix->ycbcr_enc =
-+ V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
-+ pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
-+ pix->colorspace,
-+ pix->ycbcr_enc);
-+ pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
-+
-+ return 0;
-+}
-+
-+static int stf_video_init_format(struct stfcamss_video *video)
-+{
-+ int ret;
-+ struct v4l2_format format = {
-+ .type = video->type,
-+ .fmt.pix = {
-+ .width = 1920,
-+ .height = 1080,
-+ .pixelformat = V4L2_PIX_FMT_RGB565,
-+ },
-+ };
-+
-+ ret = __video_try_fmt(video, &format);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ video->active_fmt = format;
-+
-+ return 0;
-+}
-+
-+/* -----------------------------------------------------------------------------
-+ * Video queue operations
-+ */
-+
-+static int video_queue_setup(struct vb2_queue *q,
-+ unsigned int *num_buffers,
-+ unsigned int *num_planes,
-+ unsigned int sizes[],
-+ struct device *alloc_devs[])
-+{
-+ struct stfcamss_video *video = vb2_get_drv_priv(q);
-+ const struct v4l2_pix_format *format = &video->active_fmt.fmt.pix;
-+
-+ if (*num_planes) {
-+ if (*num_planes != 1)
-+ return -EINVAL;
-+
-+ if (sizes[0] < format->sizeimage)
-+ return -EINVAL;
-+ }
-+
-+ *num_planes = 1;
-+ sizes[0] = format->sizeimage;
-+ if (!sizes[0])
-+ dev_err(video->stfcamss->dev,
-+ "%s: error size is zero!!!\n", __func__);
-+
-+ dev_dbg(video->stfcamss->dev, "planes = %d, size = %d\n",
-+ *num_planes, sizes[0]);
-+
-+ return 0;
-+}
-+
-+static int video_buf_init(struct vb2_buffer *vb)
-+{
-+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
-+ struct stfcamss_buffer *buffer =
-+ container_of(vbuf, struct stfcamss_buffer, vb);
-+ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
-+ dma_addr_t *paddr;
-+
-+ buffer->sizeimage = 0;
-+
-+ paddr = vb2_plane_cookie(vb, 0);
-+ buffer->sizeimage = vb2_plane_size(vb, 0);
-+ buffer->addr[0] = *paddr;
-+ if (fmt->pixelformat == V4L2_PIX_FMT_NV12 ||
-+ fmt->pixelformat == V4L2_PIX_FMT_NV21 ||
-+ fmt->pixelformat == V4L2_PIX_FMT_NV16 ||
-+ fmt->pixelformat == V4L2_PIX_FMT_NV61)
-+ buffer->addr[1] =
-+ buffer->addr[0] + fmt->bytesperline * fmt->height;
-+
-+ return 0;
-+}
-+
-+static int video_buf_prepare(struct vb2_buffer *vb)
-+{
-+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
-+ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
-+
-+ if (fmt->sizeimage > vb2_plane_size(vb, 0)) {
-+ dev_err(video->stfcamss->dev,
-+ "sizeimage = %d, plane size = %d\n",
-+ fmt->sizeimage, (unsigned int)vb2_plane_size(vb, 0));
-+ return -EINVAL;
-+ }
-+ vb2_set_plane_payload(vb, 0, fmt->sizeimage);
-+
-+ vbuf->field = V4L2_FIELD_NONE;
-+
-+ return 0;
-+}
-+
-+static void video_buf_queue(struct vb2_buffer *vb)
-+{
-+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
-+ struct stfcamss_buffer *buffer =
-+ container_of(vbuf, struct stfcamss_buffer, vb);
-+
-+ video->ops->queue_buffer(video, buffer);
-+}
-+
-+/*
-+ * video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
-+ * @mbus: v4l2_mbus_framefmt format (input)
-+ * @pix: v4l2_pix_format_mplane format (output)
-+ * @f: a pointer to formats array element to be used for the conversion
-+ * @alignment: bytesperline alignment value
-+ *
-+ * Fill the output pix structure with information from the input mbus format.
-+ *
-+ * Return 0 on success or a negative error code otherwise
-+ */
-+static int video_mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
-+ struct v4l2_pix_format *pix,
-+ const struct stfcamss_format_info *f,
-+ unsigned int alignment)
-+{
-+ u32 bytesperline;
-+
-+ memset(pix, 0, sizeof(*pix));
-+ v4l2_fill_pix_format(pix, mbus);
-+ pix->pixelformat = f->pixelformat;
-+ bytesperline = pix->width / f->hsub[0].numerator *
-+ f->hsub[0].denominator * f->bpp[0] / 8;
-+ bytesperline = ALIGN(bytesperline, alignment);
-+ pix->bytesperline = bytesperline;
-+ pix->sizeimage = pix->height / f->vsub[0].numerator *
-+ f->vsub[0].denominator * bytesperline;
-+ return 0;
-+}
-+
-+static struct v4l2_subdev *video_remote_subdev(struct stfcamss_video *video,
-+ u32 *pad)
-+{
-+ struct media_pad *remote;
-+
-+ remote = media_pad_remote_pad_first(&video->pad);
-+
-+ if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
-+ return NULL;
-+
-+ if (pad)
-+ *pad = remote->index;
-+
-+ return media_entity_to_v4l2_subdev(remote->entity);
-+}
-+
-+static int video_get_subdev_format(struct stfcamss_video *video,
-+ struct v4l2_format *format)
-+{
-+ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
-+ struct v4l2_subdev_format fmt;
-+ struct v4l2_subdev *subdev;
-+ u32 pixelformat;
-+ u32 pad;
-+ int ret;
-+
-+ subdev = video_remote_subdev(video, &pad);
-+ if (!subdev)
-+ return -EPIPE;
-+
-+ fmt.pad = pad;
-+ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-+
-+ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
-+ if (ret)
-+ return ret;
-+
-+ pixelformat = pix->pixelformat;
-+ ret = video_find_format(fmt.format.code, pixelformat,
-+ video->formats, video->nformats);
-+ if (ret < 0)
-+ return ret;
-+
-+ format->type = video->type;
-+
-+ return video_mbus_to_pix(&fmt.format, &format->fmt.pix,
-+ &video->formats[ret], video->bpl_alignment);
-+}
-+
-+static int video_check_format(struct stfcamss_video *video)
-+{
-+ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
-+ struct v4l2_format format;
-+ struct v4l2_pix_format *sd_pix = &format.fmt.pix;
-+ int ret;
-+
-+ sd_pix->pixelformat = pix->pixelformat;
-+ ret = video_get_subdev_format(video, &format);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (pix->pixelformat != sd_pix->pixelformat ||
-+ pix->height > sd_pix->height ||
-+ pix->width > sd_pix->width ||
-+ pix->field != format.fmt.pix.field) {
-+ dev_err(video->stfcamss->dev,
-+ "%s, not match:\n"
-+ "0x%x 0x%x\n0x%x 0x%x\n0x%x 0x%x\n",
-+ __func__,
-+ pix->pixelformat, sd_pix->pixelformat,
-+ pix->height, sd_pix->height,
-+ pix->field, format.fmt.pix.field);
-+ return -EPIPE;
-+ }
-+
-+ return 0;
-+}
-+
-+static int video_start_streaming(struct vb2_queue *q, unsigned int count)
-+{
-+ struct stfcamss_video *video = vb2_get_drv_priv(q);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct media_pad *pad;
-+ struct v4l2_subdev *subdev;
-+ int ret;
-+
-+ ret = video_device_pipeline_start(vdev, &video->stfcamss->pipe);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to media_pipeline_start: %d\n", ret);
-+ return ret;
-+ }
-+
-+ ret = video_check_format(video);
-+ if (ret < 0)
-+ goto error;
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ ret = v4l2_subdev_call(subdev, video, s_stream, 1);
-+ if (ret < 0 && ret != -ENOIOCTLCMD)
-+ goto error;
-+ }
-+ return 0;
-+
-+error:
-+ video_device_pipeline_stop(vdev);
-+ video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
-+ return ret;
-+}
-+
-+static void video_stop_streaming(struct vb2_queue *q)
-+{
-+ struct stfcamss_video *video = vb2_get_drv_priv(q);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct media_pad *pad;
-+ struct v4l2_subdev *subdev;
-+
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ v4l2_subdev_call(subdev, video, s_stream, 0);
-+ }
-+
-+ video_device_pipeline_stop(vdev);
-+ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
-+}
-+
-+static const struct vb2_ops stf_video_vb2_q_ops = {
-+ .queue_setup = video_queue_setup,
-+ .wait_prepare = vb2_ops_wait_prepare,
-+ .wait_finish = vb2_ops_wait_finish,
-+ .buf_init = video_buf_init,
-+ .buf_prepare = video_buf_prepare,
-+ .buf_queue = video_buf_queue,
-+ .start_streaming = video_start_streaming,
-+ .stop_streaming = video_stop_streaming,
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * V4L2 ioctls
-+ */
-+
-+static int video_querycap(struct file *file, void *fh,
-+ struct v4l2_capability *cap)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+
-+ strscpy(cap->driver, "stf camss", sizeof(cap->driver));
-+ strscpy(cap->card, "Starfive Camera Subsystem", sizeof(cap->card));
-+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
-+ dev_name(video->stfcamss->dev));
-+ return 0;
-+}
-+
-+static int video_get_pfmt_by_index(struct stfcamss_video *video, int ndx)
-+{
-+ int i, j, k;
-+
-+ /* find index "i" of "k"th unique pixelformat in formats array */
-+ k = -1;
-+ for (i = 0; i < video->nformats; i++) {
-+ for (j = 0; j < i; j++) {
-+ if (video->formats[i].pixelformat ==
-+ video->formats[j].pixelformat)
-+ break;
-+ }
-+
-+ if (j == i)
-+ k++;
-+
-+ if (k == ndx)
-+ return i;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int video_get_pfmt_by_mcode(struct stfcamss_video *video, u32 mcode)
-+{
-+ int i;
-+
-+ for (i = 0; i < video->nformats; i++) {
-+ if (video->formats[i].code == mcode)
-+ return i;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ int i;
-+
-+ if (f->type != video->type)
-+ return -EINVAL;
-+ if (f->index >= video->nformats)
-+ return -EINVAL;
-+
-+ if (f->mbus_code) {
-+ /* Each entry in formats[] table has unique mbus_code */
-+ if (f->index > 0)
-+ return -EINVAL;
-+
-+ i = video_get_pfmt_by_mcode(video, f->mbus_code);
-+ } else {
-+ i = video_get_pfmt_by_index(video, f->index);
-+ }
-+
-+ if (i < 0)
-+ return -EINVAL;
-+
-+ f->pixelformat = video->formats[i].pixelformat;
-+
-+ return 0;
-+}
-+
-+static int video_enum_framesizes(struct file *file, void *fh,
-+ struct v4l2_frmsizeenum *fsize)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ int i;
-+
-+ if (fsize->index)
-+ return -EINVAL;
-+
-+ for (i = 0; i < video->nformats; i++) {
-+ if (video->formats[i].pixelformat == fsize->pixel_format)
-+ break;
-+ }
-+
-+ if (i == video->nformats)
-+ return -EINVAL;
-+
-+ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
-+ fsize->stepwise.min_width = STFCAMSS_FRAME_MIN_WIDTH;
-+ fsize->stepwise.max_width = STFCAMSS_FRAME_MAX_WIDTH;
-+ fsize->stepwise.min_height = STFCAMSS_FRAME_MIN_HEIGHT;
-+ fsize->stepwise.max_height = STFCAMSS_FRAME_MAX_HEIGHT;
-+ fsize->stepwise.step_width = 1;
-+ fsize->stepwise.step_height = 1;
-+
-+ return 0;
-+}
-+
-+static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+
-+ *f = video->active_fmt;
-+
-+ return 0;
-+}
-+
-+static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ int ret;
-+
-+ if (vb2_is_busy(&video->vb2_q))
-+ return -EBUSY;
-+
-+ ret = __video_try_fmt(video, f);
-+ if (ret < 0)
-+ return ret;
-+
-+ video->active_fmt = *f;
-+
-+ return 0;
-+}
-+
-+static int video_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+
-+ return __video_try_fmt(video, f);
-+}
-+
-+static int video_enum_input(struct file *file, void *fh,
-+ struct v4l2_input *input)
-+{
-+ if (input->index > 0)
-+ return -EINVAL;
-+
-+ strscpy(input->name, "camera", sizeof(input->name));
-+ input->type = V4L2_INPUT_TYPE_CAMERA;
-+
-+ return 0;
-+}
-+
-+static int video_g_input(struct file *file, void *fh, unsigned int *input)
-+{
-+ *input = 0;
-+
-+ return 0;
-+}
-+
-+static int video_s_input(struct file *file, void *fh, unsigned int input)
-+{
-+ return input == 0 ? 0 : -EINVAL;
-+}
-+
-+static int video_g_parm(struct file *file, void *priv,
-+ struct v4l2_streamparm *p)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct v4l2_subdev *subdev;
-+ struct media_pad *pad;
-+ int ret, is_support = 0;
-+
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ ret = v4l2_g_parm_cap(vdev, subdev, p);
-+ if (ret < 0 && ret != -ENOIOCTLCMD)
-+ break;
-+ if (!ret)
-+ is_support = 1;
-+ }
-+
-+ return is_support ? 0 : ret;
-+}
-+
-+static int video_s_parm(struct file *file, void *priv,
-+ struct v4l2_streamparm *p)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct v4l2_subdev *subdev;
-+ struct media_pad *pad;
-+ struct v4l2_streamparm tmp_p;
-+ int ret, is_support = 0;
-+
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ tmp_p = *p;
-+ ret = v4l2_s_parm_cap(vdev, subdev, &tmp_p);
-+ if (ret < 0 && ret != -ENOIOCTLCMD)
-+ break;
-+ if (!ret) {
-+ is_support = 1;
-+ *p = tmp_p;
-+ }
-+ }
-+
-+ return is_support ? 0 : ret;
-+}
-+
-+static const struct v4l2_ioctl_ops stf_vid_vin_ioctl_ops = {
-+ .vidioc_querycap = video_querycap,
-+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
-+ .vidioc_enum_fmt_vid_out = video_enum_fmt,
-+ .vidioc_enum_framesizes = video_enum_framesizes,
-+ .vidioc_g_fmt_vid_cap = video_g_fmt,
-+ .vidioc_s_fmt_vid_cap = video_s_fmt,
-+ .vidioc_try_fmt_vid_cap = video_try_fmt,
-+ .vidioc_g_fmt_vid_out = video_g_fmt,
-+ .vidioc_s_fmt_vid_out = video_s_fmt,
-+ .vidioc_try_fmt_vid_out = video_try_fmt,
-+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
-+ .vidioc_querybuf = vb2_ioctl_querybuf,
-+ .vidioc_qbuf = vb2_ioctl_qbuf,
-+ .vidioc_expbuf = vb2_ioctl_expbuf,
-+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
-+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
-+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-+ .vidioc_streamon = vb2_ioctl_streamon,
-+ .vidioc_streamoff = vb2_ioctl_streamoff,
-+ .vidioc_enum_input = video_enum_input,
-+ .vidioc_g_input = video_g_input,
-+ .vidioc_s_input = video_s_input,
-+ .vidioc_g_parm = video_g_parm,
-+ .vidioc_s_parm = video_s_parm,
-+};
-+
-+static const struct v4l2_ioctl_ops stf_vid_isp_ioctl_ops = {
-+ .vidioc_querycap = video_querycap,
-+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
-+ .vidioc_enum_fmt_vid_out = video_enum_fmt,
-+ .vidioc_enum_framesizes = video_enum_framesizes,
-+ .vidioc_g_fmt_vid_cap = video_g_fmt,
-+ .vidioc_s_fmt_vid_cap = video_s_fmt,
-+ .vidioc_try_fmt_vid_cap = video_try_fmt,
-+ .vidioc_g_fmt_vid_out = video_g_fmt,
-+ .vidioc_s_fmt_vid_out = video_s_fmt,
-+ .vidioc_try_fmt_vid_out = video_try_fmt,
-+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
-+ .vidioc_querybuf = vb2_ioctl_querybuf,
-+ .vidioc_qbuf = vb2_ioctl_qbuf,
-+ .vidioc_expbuf = vb2_ioctl_expbuf,
-+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
-+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
-+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-+ .vidioc_streamon = vb2_ioctl_streamon,
-+ .vidioc_streamoff = vb2_ioctl_streamoff,
-+ .vidioc_enum_input = video_enum_input,
-+ .vidioc_g_input = video_g_input,
-+ .vidioc_s_input = video_s_input,
-+ .vidioc_g_parm = video_g_parm,
-+ .vidioc_s_parm = video_s_parm,
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * V4L2 file operations
-+ */
-+
-+static int video_open(struct file *file)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+ struct stfcamss_video *video = video_drvdata(file);
-+ struct v4l2_fh *vfh;
-+ int ret;
-+
-+ mutex_lock(&video->lock);
-+
-+ vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
-+ if (!vfh) {
-+ ret = -ENOMEM;
-+ goto error_alloc;
-+ }
-+
-+ v4l2_fh_init(vfh, vdev);
-+ v4l2_fh_add(vfh);
-+
-+ file->private_data = vfh;
-+
-+ ret = v4l2_pipeline_pm_get(&vdev->entity);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to power up pipeline: %d\n", ret);
-+ goto error_pm_use;
-+ }
-+ mutex_unlock(&video->lock);
-+
-+ return 0;
-+
-+error_pm_use:
-+ v4l2_fh_release(file);
-+error_alloc:
-+ mutex_unlock(&video->lock);
-+ return ret;
-+}
-+
-+static int video_release(struct file *file)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+
-+ vb2_fop_release(file);
-+ v4l2_pipeline_pm_put(&vdev->entity);
-+ file->private_data = NULL;
-+
-+ return 0;
-+}
-+
-+static const struct v4l2_file_operations stf_vid_fops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = video_ioctl2,
-+ .open = video_open,
-+ .release = video_release,
-+ .poll = vb2_fop_poll,
-+ .mmap = vb2_fop_mmap,
-+ .read = vb2_fop_read,
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * STFCAMSS video core
-+ */
-+
-+static void stf_video_release(struct video_device *vdev)
-+{
-+ struct stfcamss_video *video = video_get_drvdata(vdev);
-+
-+ media_entity_cleanup(&vdev->entity);
-+
-+ mutex_destroy(&video->q_lock);
-+ mutex_destroy(&video->lock);
-+}
-+
-+int stf_video_register(struct stfcamss_video *video,
-+ struct v4l2_device *v4l2_dev, const char *name)
-+{
-+ struct video_device *vdev;
-+ struct vb2_queue *q;
-+ struct media_pad *pad = &video->pad;
-+ int ret;
-+
-+ vdev = &video->vdev;
-+
-+ mutex_init(&video->q_lock);
-+
-+ q = &video->vb2_q;
-+ q->drv_priv = video;
-+ q->mem_ops = &vb2_dma_contig_memops;
-+ q->ops = &stf_video_vb2_q_ops;
-+ q->type = video->type;
-+ q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ;
-+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-+ q->buf_struct_size = sizeof(struct stfcamss_buffer);
-+ q->dev = video->stfcamss->dev;
-+ q->lock = &video->q_lock;
-+ q->min_buffers_needed = STFCAMSS_MIN_BUFFERS;
-+ ret = vb2_queue_init(q);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to init vb2 queue: %d\n", ret);
-+ goto err_vb2_init;
-+ }
-+
-+ pad->flags = MEDIA_PAD_FL_SINK;
-+ ret = media_entity_pads_init(&vdev->entity, 1, pad);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to init video entity: %d\n", ret);
-+ goto err_vb2_init;
-+ }
-+
-+ mutex_init(&video->lock);
-+
-+ if (video->id == STF_V_LINE_WR) {
-+ video->formats = formats_pix_wr;
-+ video->nformats = ARRAY_SIZE(formats_pix_wr);
-+ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
-+ vdev->ioctl_ops = &stf_vid_vin_ioctl_ops;
-+ } else {
-+ video->formats = formats_pix_isp;
-+ video->nformats = ARRAY_SIZE(formats_pix_isp);
-+ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
-+ vdev->ioctl_ops = &stf_vid_isp_ioctl_ops;
-+ }
-+
-+ ret = stf_video_init_format(video);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to init format: %d\n", ret);
-+ goto err_vid_init_format;
-+ }
-+
-+ vdev->fops = &stf_vid_fops;
-+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE;
-+ vdev->vfl_dir = VFL_DIR_RX;
-+ vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-+ vdev->release = stf_video_release;
-+ vdev->v4l2_dev = v4l2_dev;
-+ vdev->queue = &video->vb2_q;
-+ vdev->lock = &video->lock;
-+ strscpy(vdev->name, name, sizeof(vdev->name));
-+
-+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, video->id);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to register video device: %d\n", ret);
-+ goto err_vid_reg;
-+ }
-+
-+ video_set_drvdata(vdev, video);
-+ return 0;
-+
-+err_vid_reg:
-+err_vid_init_format:
-+ media_entity_cleanup(&vdev->entity);
-+ mutex_destroy(&video->lock);
-+err_vb2_init:
-+ mutex_destroy(&video->q_lock);
-+ return ret;
-+}
-+
-+void stf_video_unregister(struct stfcamss_video *video)
-+{
-+ vb2_video_unregister_device(&video->vdev);
-+}
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_video.h
-@@ -0,0 +1,95 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_video.h
-+ *
-+ * StarFive Camera Subsystem - V4L2 device node
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_VIDEO_H
-+#define STF_VIDEO_H
-+
-+#include <linux/mutex.h>
-+#include <linux/videodev2.h>
-+#include <media/v4l2-dev.h>
-+#include <media/v4l2-fh.h>
-+#include <media/v4l2-ioctl.h>
-+#include <media/videobuf2-v4l2.h>
-+
-+#define STFCAMSS_FRAME_MIN_WIDTH 64
-+#define STFCAMSS_FRAME_MAX_WIDTH 1920
-+#define STFCAMSS_FRAME_MIN_HEIGHT 64
-+#define STFCAMSS_FRAME_MAX_HEIGHT 1080
-+#define STFCAMSS_FRAME_WIDTH_ALIGN_8 8
-+#define STFCAMSS_FRAME_WIDTH_ALIGN_128 128
-+#define STFCAMSS_MIN_BUFFERS 2
-+
-+#define STFCAMSS_MAX_ENTITY_NAME_LEN 27
-+
-+enum stf_v_line_id {
-+ STF_V_LINE_WR = 0,
-+ STF_V_LINE_ISP,
-+ STF_V_LINE_MAX,
-+};
-+
-+struct stfcamss_buffer {
-+ struct vb2_v4l2_buffer vb;
-+ dma_addr_t addr[3];
-+ struct list_head queue;
-+ int sizeimage;
-+};
-+
-+struct fract {
-+ u8 numerator;
-+ u8 denominator;
-+};
-+
-+/*
-+ * struct stfcamss_format_info - ISP media bus format information
-+ * @code: V4L2 media bus format code
-+ * @pixelformat: V4L2 pixel format FCC identifier
-+ * @planes: Number of planes
-+ * @hsub: Horizontal subsampling (for each plane)
-+ * @vsub: Vertical subsampling (for each plane)
-+ * @bpp: Bits per pixel when stored in memory (for each plane)
-+ */
-+struct stfcamss_format_info {
-+ u32 code;
-+ u32 pixelformat;
-+ u8 planes;
-+ struct fract hsub[3];
-+ struct fract vsub[3];
-+ u8 bpp[3];
-+};
-+
-+struct stfcamss_video {
-+ struct stfcamss *stfcamss;
-+ u8 id;
-+ struct vb2_queue vb2_q;
-+ struct video_device vdev;
-+ struct media_pad pad;
-+ struct media_pipeline pipe;
-+ struct v4l2_format active_fmt;
-+ enum v4l2_buf_type type;
-+ const struct stfcamss_video_ops *ops;
-+ struct mutex lock; /* serialize device access */
-+ struct mutex q_lock; /* protects the queue */
-+ unsigned int bpl_alignment;
-+ const struct stfcamss_format_info *formats;
-+ unsigned int nformats;
-+};
-+
-+struct stfcamss_video_ops {
-+ int (*queue_buffer)(struct stfcamss_video *vid,
-+ struct stfcamss_buffer *buf);
-+ int (*flush_buffers)(struct stfcamss_video *vid,
-+ enum vb2_buffer_state state);
-+};
-+
-+int stf_video_register(struct stfcamss_video *video,
-+ struct v4l2_device *v4l2_dev, const char *name);
-+
-+void stf_video_unregister(struct stfcamss_video *video);
-+
-+#endif /* STF_VIDEO_H */
diff --git a/target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch b/target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch
deleted file mode 100644
index 3a871b5a7f..0000000000
--- a/target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch
+++ /dev/null
@@ -1,1667 +0,0 @@
-From 3b814965133cd53b1f30a34e4425294726cb0087 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:43 +0800
-Subject: [PATCH 085/122] media: starfive: Add ISP driver
-
-Add ISP driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/starfive/Makefile | 2 +
- drivers/media/platform/starfive/stf_camss.c | 71 ++-
- drivers/media/platform/starfive/stf_camss.h | 2 +
- drivers/media/platform/starfive/stf_isp.c | 550 ++++++++++++++++++
- drivers/media/platform/starfive/stf_isp.h | 476 +++++++++++++++
- .../media/platform/starfive/stf_isp_hw_ops.c | 452 ++++++++++++++
- 6 files changed, 1551 insertions(+), 2 deletions(-)
- create mode 100644 drivers/media/platform/starfive/stf_isp.c
- create mode 100644 drivers/media/platform/starfive/stf_isp.h
- create mode 100644 drivers/media/platform/starfive/stf_isp_hw_ops.c
-
---- a/drivers/media/platform/starfive/Makefile
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -5,6 +5,8 @@
-
- starfive-camss-objs += \
- stf_camss.o \
-+ stf_isp.o \
-+ stf_isp_hw_ops.o \
- stf_video.o
-
- obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- a/drivers/media/platform/starfive/stf_camss.c
-+++ b/drivers/media/platform/starfive/stf_camss.c
-@@ -126,16 +126,66 @@ err_cleanup:
- return ret;
- }
-
-+/*
-+ * stfcamss_init_subdevices - Initialize subdev structures and resources
-+ * @stfcamss: STFCAMSS device
-+ *
-+ * Return 0 on success or a negative error code on failure
-+ */
-+static int stfcamss_init_subdevices(struct stfcamss *stfcamss)
-+{
-+ int ret;
-+
-+ ret = stf_isp_subdev_init(stfcamss);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev, "Failed to init isp subdev: %d\n", ret);
-+ return ret;
-+ }
-+
-+ return ret;
-+}
-+
-+static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
-+{
-+ int ret;
-+ struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-+
-+ ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to register stf isp%d entity: %d\n", 0, ret);
-+ return ret;
-+ }
-+
-+ return ret;
-+}
-+
-+static void stfcamss_unregister_subdevices(struct stfcamss *stfcamss)
-+{
-+ stf_isp_unregister(&stfcamss->isp_dev);
-+}
-+
- static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
- struct v4l2_subdev *subdev,
- struct v4l2_async_subdev *asd)
- {
- struct stfcamss *stfcamss =
- container_of(async, struct stfcamss, notifier);
-+ struct stfcamss_async_subdev *csd =
-+ container_of(asd, struct stfcamss_async_subdev, asd);
-+ enum port_num port = csd->port;
-+ struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
- struct host_data *host_data = &stfcamss->host_data;
- struct media_entity *source;
- int i, j;
-
-+ if (port == PORT_NUMBER_CSI2RX) {
-+ host_data->host_entity[1] = &isp_dev->subdev.entity;
-+ } else if (port == PORT_NUMBER_DVP_SENSOR) {
-+ dev_err(stfcamss->dev, "Not support DVP sensor\n");
-+ return -EPERM;
-+ }
-+
- source = &subdev->entity;
-
- for (i = 0; i < source->num_pads; i++) {
-@@ -266,12 +316,18 @@ static int stfcamss_probe(struct platfor
- return -ENODEV;
- }
-
-+ ret = stfcamss_init_subdevices(stfcamss);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to init subdevice: %d\n", ret);
-+ goto err_cleanup_notifier;
-+ }
-+
- stfcamss_mc_init(pdev, stfcamss);
-
- ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
- if (ret < 0) {
- dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
-- goto err_cleanup_notifier;
-+ goto err_cleanup_media_device;
- }
-
- ret = media_device_register(&stfcamss->media_dev);
-@@ -280,22 +336,32 @@ static int stfcamss_probe(struct platfor
- goto err_unregister_device;
- }
-
-+ ret = stfcamss_register_subdevices(stfcamss);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to register subdevice: %d\n", ret);
-+ goto err_unregister_media_dev;
-+ }
-+
- stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
- ret = v4l2_async_nf_register(&stfcamss->v4l2_dev, &stfcamss->notifier);
- if (ret) {
- dev_err(dev, "Failed to register async subdev nodes: %d\n",
- ret);
-- goto err_unregister_media_dev;
-+ goto err_unregister_subdevs;
- }
-
- pm_runtime_enable(dev);
-
- return 0;
-
-+err_unregister_subdevs:
-+ stfcamss_unregister_subdevices(stfcamss);
- err_unregister_media_dev:
- media_device_unregister(&stfcamss->media_dev);
- err_unregister_device:
- v4l2_device_unregister(&stfcamss->v4l2_dev);
-+err_cleanup_media_device:
-+ media_device_cleanup(&stfcamss->media_dev);
- err_cleanup_notifier:
- v4l2_async_nf_cleanup(&stfcamss->notifier);
- return ret;
-@@ -311,6 +377,7 @@ static int stfcamss_remove(struct platfo
- {
- struct stfcamss *stfcamss = platform_get_drvdata(pdev);
-
-+ stfcamss_unregister_subdevices(stfcamss);
- v4l2_device_unregister(&stfcamss->v4l2_dev);
- media_device_cleanup(&stfcamss->media_dev);
- pm_runtime_disable(&pdev->dev);
---- a/drivers/media/platform/starfive/stf_camss.h
-+++ b/drivers/media/platform/starfive/stf_camss.h
-@@ -16,6 +16,7 @@
- #include <media/v4l2-device.h>
-
- #include "stf_common.h"
-+#include "stf_isp.h"
-
- #define DRV_NAME "starfive-camss"
- #define STF_DVP_NAME "stf_dvp"
-@@ -71,6 +72,7 @@ struct stfcamss {
- struct media_device media_dev;
- struct media_pipeline pipe;
- struct device *dev;
-+ struct stf_isp_dev isp_dev;
- struct v4l2_async_notifier notifier;
- struct host_data host_data;
- void __iomem *syscon_base;
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_isp.c
-@@ -0,0 +1,550 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_isp.c
-+ *
-+ * StarFive Camera Subsystem - ISP Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include <linux/firmware.h>
-+#include <media/v4l2-event.h>
-+
-+#include "stf_camss.h"
-+
-+#define SINK_FORMATS_INDEX 0
-+#define UO_FORMATS_INDEX 1
-+
-+static int isp_set_selection(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_selection *sel);
-+
-+static const struct isp_format isp_formats_sink[] = {
-+ { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
-+ { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
-+ { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
-+ { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
-+};
-+
-+static const struct isp_format isp_formats_uo[] = {
-+ { MEDIA_BUS_FMT_Y12_1X12, 8 },
-+};
-+
-+static const struct isp_format_table isp_formats_st7110[] = {
-+ { isp_formats_sink, ARRAY_SIZE(isp_formats_sink) },
-+ { isp_formats_uo, ARRAY_SIZE(isp_formats_uo) },
-+};
-+
-+int stf_isp_subdev_init(struct stfcamss *stfcamss)
-+{
-+ struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-+
-+ isp_dev->sdev_type = STF_SUBDEV_TYPE_ISP;
-+ isp_dev->stfcamss = stfcamss;
-+ isp_dev->formats = isp_formats_st7110;
-+ isp_dev->nformats = ARRAY_SIZE(isp_formats_st7110);
-+
-+ mutex_init(&isp_dev->stream_lock);
-+ mutex_init(&isp_dev->power_lock);
-+ return 0;
-+}
-+
-+static int isp_set_power(struct v4l2_subdev *sd, int on)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+
-+ mutex_lock(&isp_dev->power_lock);
-+ if (on) {
-+ if (isp_dev->power_count == 0)
-+ dev_dbg(isp_dev->stfcamss->dev, "turn on isp\n");
-+ isp_dev->power_count++;
-+ } else {
-+ if (isp_dev->power_count == 0)
-+ goto exit;
-+ isp_dev->power_count--;
-+ }
-+exit:
-+ mutex_unlock(&isp_dev->power_lock);
-+
-+ return 0;
-+}
-+
-+static struct v4l2_mbus_framefmt *
-+__isp_get_format(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ if (which == V4L2_SUBDEV_FORMAT_TRY)
-+ return v4l2_subdev_get_try_format(&isp_dev->subdev, state, pad);
-+
-+ return &isp_dev->fmt[pad];
-+}
-+
-+static int isp_set_stream(struct v4l2_subdev *sd, int enable)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ int ret = 0;
-+ struct v4l2_mbus_framefmt *fmt;
-+ struct v4l2_event src_ch = { 0 };
-+
-+ fmt = __isp_get_format(isp_dev, NULL, STF_ISP_PAD_SINK,
-+ V4L2_SUBDEV_FORMAT_ACTIVE);
-+ mutex_lock(&isp_dev->stream_lock);
-+ if (enable) {
-+ if (isp_dev->stream_count == 0) {
-+ stf_isp_clk_enable(isp_dev);
-+ stf_isp_reset(isp_dev);
-+ stf_isp_init_cfg(isp_dev);
-+ stf_isp_settings(isp_dev, isp_dev->rect, fmt->code);
-+ stf_isp_stream_set(isp_dev);
-+ }
-+ isp_dev->stream_count++;
-+ } else {
-+ if (isp_dev->stream_count == 0)
-+ goto exit;
-+
-+ if (isp_dev->stream_count == 1)
-+ stf_isp_clk_disable(isp_dev);
-+
-+ isp_dev->stream_count--;
-+ }
-+ src_ch.type = V4L2_EVENT_SOURCE_CHANGE,
-+ src_ch.u.src_change.changes = isp_dev->stream_count,
-+
-+ v4l2_subdev_notify_event(sd, &src_ch);
-+exit:
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ return ret;
-+}
-+
-+static void isp_try_format(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ struct v4l2_mbus_framefmt *fmt,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ const struct isp_format_table *formats;
-+ struct stf_isp_crop *rect;
-+ int i;
-+
-+ switch (pad) {
-+ case STF_ISP_PAD_SINK:
-+ /* Set format on sink pad */
-+ formats = &isp_dev->formats[SINK_FORMATS_INDEX];
-+ rect = &isp_dev->rect[SINK_FORMATS_INDEX];
-+ fmt->width = clamp_t(u32,
-+ fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
-+ STFCAMSS_FRAME_MAX_WIDTH);
-+ fmt->height = clamp_t(u32,
-+ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
-+ STFCAMSS_FRAME_MAX_HEIGHT);
-+ fmt->height &= ~0x1;
-+ fmt->field = V4L2_FIELD_NONE;
-+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
-+ fmt->flags = 0;
-+ break;
-+
-+ case STF_ISP_PAD_SRC:
-+ formats = &isp_dev->formats[UO_FORMATS_INDEX];
-+ rect = &isp_dev->rect[UO_FORMATS_INDEX];
-+ *fmt = *__isp_get_format(isp_dev, state,
-+ STF_ISP_PAD_SINK, which);
-+ break;
-+ }
-+
-+ for (i = 0; i < formats->nfmts; i++) {
-+ if (fmt->code == formats->fmts[i].code)
-+ break;
-+ }
-+
-+ if (i >= formats->nfmts) {
-+ fmt->code = formats->fmts[0].code;
-+ rect->bpp = formats->fmts[0].bpp;
-+ } else {
-+ rect->bpp = formats->fmts[i].bpp;
-+ }
-+}
-+
-+static int isp_enum_mbus_code(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_mbus_code_enum *code)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ const struct isp_format_table *formats;
-+
-+ if (code->index >= isp_dev->nformats)
-+ return -EINVAL;
-+ if (code->pad == STF_ISP_PAD_SINK) {
-+ formats = &isp_dev->formats[SINK_FORMATS_INDEX];
-+ code->code = formats->fmts[code->index].code;
-+ } else {
-+ struct v4l2_mbus_framefmt *sink_fmt;
-+
-+ sink_fmt = __isp_get_format(isp_dev, state, STF_ISP_PAD_SINK,
-+ code->which);
-+
-+ code->code = sink_fmt->code;
-+ if (!code->code)
-+ return -EINVAL;
-+ }
-+ code->flags = 0;
-+
-+ return 0;
-+}
-+
-+static int isp_enum_frame_size(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_frame_size_enum *fse)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt format;
-+
-+ if (fse->index != 0)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = 1;
-+ format.height = 1;
-+ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
-+ fse->min_width = format.width;
-+ fse->min_height = format.height;
-+
-+ if (format.code != fse->code)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = -1;
-+ format.height = -1;
-+ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
-+ fse->max_width = format.width;
-+ fse->max_height = format.height;
-+
-+ return 0;
-+}
-+
-+static int isp_get_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ fmt->format = *format;
-+
-+ return 0;
-+}
-+
-+static int isp_set_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp_dev->stream_lock);
-+
-+ isp_try_format(isp_dev, state, fmt->pad, &fmt->format, fmt->which);
-+ *format = fmt->format;
-+
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ /* Propagate to in crop */
-+ if (fmt->pad == STF_ISP_PAD_SINK) {
-+ struct v4l2_subdev_selection sel = { 0 };
-+ int ret;
-+
-+ /* Reset sink pad compose selection */
-+ sel.which = fmt->which;
-+ sel.pad = STF_ISP_PAD_SINK;
-+ sel.target = V4L2_SEL_TGT_CROP;
-+ sel.r.width = fmt->format.width;
-+ sel.r.height = fmt->format.height;
-+ ret = isp_set_selection(sd, state, &sel);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct v4l2_rect *
-+__isp_get_crop(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ if (which == V4L2_SUBDEV_FORMAT_TRY)
-+ return v4l2_subdev_get_try_crop(&isp_dev->subdev, state,
-+ STF_ISP_PAD_SINK);
-+
-+ return &isp_dev->rect[pad].rect;
-+}
-+
-+static void isp_try_crop(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_rect *rect,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ struct v4l2_mbus_framefmt *fmt;
-+
-+ fmt = __isp_get_format(isp_dev, state, STF_ISP_PAD_SINK, which);
-+
-+ if (rect->width > fmt->width)
-+ rect->width = fmt->width;
-+
-+ if (rect->width + rect->left > fmt->width)
-+ rect->left = fmt->width - rect->width;
-+
-+ if (rect->height > fmt->height)
-+ rect->height = fmt->height;
-+
-+ if (rect->height + rect->top > fmt->height)
-+ rect->top = fmt->height - rect->height;
-+
-+ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
-+ rect->left = 0;
-+ rect->width = STFCAMSS_FRAME_MAX_WIDTH;
-+ }
-+
-+ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
-+ rect->top = 0;
-+ rect->height = STFCAMSS_FRAME_MAX_HEIGHT;
-+ }
-+ rect->height &= ~0x1;
-+}
-+
-+static int isp_get_selection(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_selection *sel)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_subdev_format fmt = { 0 };
-+ struct v4l2_rect *rect;
-+ int ret;
-+
-+ switch (sel->target) {
-+ case V4L2_SEL_TGT_CROP_BOUNDS:
-+ if (sel->pad == STF_ISP_PAD_SINK) {
-+ fmt.pad = sel->pad;
-+ fmt.which = sel->which;
-+ ret = isp_get_format(sd, state, &fmt);
-+ if (ret < 0)
-+ return ret;
-+
-+ sel->r.left = 0;
-+ sel->r.top = 0;
-+ sel->r.width = fmt.format.width;
-+ sel->r.height = fmt.format.height;
-+ } else if (sel->pad == STF_ISP_PAD_SRC) {
-+ rect = __isp_get_crop(isp_dev, state,
-+ sel->pad, sel->which);
-+ sel->r = *rect;
-+ }
-+ break;
-+
-+ case V4L2_SEL_TGT_CROP:
-+ rect = __isp_get_crop(isp_dev, state, sel->pad, sel->which);
-+ if (!rect)
-+ return -EINVAL;
-+
-+ sel->r = *rect;
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int isp_set_selection(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_selection *sel)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_rect *rect;
-+ int ret = 0;
-+
-+ if (sel->target == V4L2_SEL_TGT_CROP &&
-+ sel->pad == STF_ISP_PAD_SINK) {
-+ struct v4l2_subdev_selection crop = { 0 };
-+
-+ rect = __isp_get_crop(isp_dev, state, sel->pad, sel->which);
-+ if (!rect)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp_dev->stream_lock);
-+ isp_try_crop(isp_dev, state, &sel->r, sel->which);
-+ *rect = sel->r;
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ /* Reset source crop selection */
-+ crop.which = sel->which;
-+ crop.pad = STF_ISP_PAD_SRC;
-+ crop.target = V4L2_SEL_TGT_CROP;
-+ crop.r = *rect;
-+ ret = isp_set_selection(sd, state, &crop);
-+ } else if (sel->target == V4L2_SEL_TGT_CROP &&
-+ sel->pad == STF_ISP_PAD_SRC) {
-+ struct v4l2_subdev_format fmt = { 0 };
-+
-+ rect = __isp_get_crop(isp_dev, state, sel->pad, sel->which);
-+ if (!rect)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp_dev->stream_lock);
-+ isp_try_crop(isp_dev, state, &sel->r, sel->which);
-+ *rect = sel->r;
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ /* Reset source pad format width and height */
-+ fmt.which = sel->which;
-+ fmt.pad = STF_ISP_PAD_SRC;
-+ fmt.format.width = rect->width;
-+ fmt.format.height = rect->height;
-+ ret = isp_set_format(sd, state, &fmt);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ dev_dbg(isp_dev->stfcamss->dev, "pad: %d sel(%d,%d)/%dx%d\n",
-+ sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
-+
-+ return 0;
-+}
-+
-+static int isp_init_formats(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_fh *fh)
-+{
-+ struct v4l2_subdev_format format = {
-+ .pad = STF_ISP_PAD_SINK,
-+ .which =
-+ fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE,
-+ .format = {
-+ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
-+ .width = 1920,
-+ .height = 1080
-+ }
-+ };
-+
-+ return isp_set_format(sd, fh ? fh->state : NULL, &format);
-+}
-+
-+static int isp_link_setup(struct media_entity *entity,
-+ const struct media_pad *local,
-+ const struct media_pad *remote, u32 flags)
-+{
-+ if (flags & MEDIA_LNK_FL_ENABLED)
-+ if (media_pad_remote_pad_first(local))
-+ return -EBUSY;
-+ return 0;
-+}
-+
-+static int stf_isp_subscribe_event(struct v4l2_subdev *sd,
-+ struct v4l2_fh *fh,
-+ struct v4l2_event_subscription *sub)
-+{
-+ switch (sub->type) {
-+ case V4L2_EVENT_SOURCE_CHANGE:
-+ return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static const struct v4l2_subdev_core_ops isp_core_ops = {
-+ .s_power = isp_set_power,
-+ .subscribe_event = stf_isp_subscribe_event,
-+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-+};
-+
-+static const struct v4l2_subdev_video_ops isp_video_ops = {
-+ .s_stream = isp_set_stream,
-+};
-+
-+static const struct v4l2_subdev_pad_ops isp_pad_ops = {
-+ .enum_mbus_code = isp_enum_mbus_code,
-+ .enum_frame_size = isp_enum_frame_size,
-+ .get_fmt = isp_get_format,
-+ .set_fmt = isp_set_format,
-+ .get_selection = isp_get_selection,
-+ .set_selection = isp_set_selection,
-+};
-+
-+static const struct v4l2_subdev_ops isp_v4l2_ops = {
-+ .core = &isp_core_ops,
-+ .video = &isp_video_ops,
-+ .pad = &isp_pad_ops,
-+};
-+
-+static const struct v4l2_subdev_internal_ops isp_v4l2_internal_ops = {
-+ .open = isp_init_formats,
-+};
-+
-+static const struct media_entity_operations isp_media_ops = {
-+ .link_setup = isp_link_setup,
-+ .link_validate = v4l2_subdev_link_validate,
-+};
-+
-+int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2_dev)
-+{
-+ struct v4l2_subdev *sd = &isp_dev->subdev;
-+ struct media_pad *pads = isp_dev->pads;
-+ int ret;
-+
-+ v4l2_subdev_init(sd, &isp_v4l2_ops);
-+ sd->internal_ops = &isp_v4l2_internal_ops;
-+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
-+ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", STF_ISP_NAME, 0);
-+ v4l2_set_subdevdata(sd, isp_dev);
-+
-+ ret = isp_init_formats(sd, NULL);
-+ if (ret < 0) {
-+ dev_err(isp_dev->stfcamss->dev, "Failed to init format: %d\n",
-+ ret);
-+ return ret;
-+ }
-+
-+ pads[STF_ISP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-+ pads[STF_ISP_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
-+
-+ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
-+ sd->entity.ops = &isp_media_ops;
-+ ret = media_entity_pads_init(&sd->entity, STF_ISP_PAD_MAX, pads);
-+ if (ret < 0) {
-+ dev_err(isp_dev->stfcamss->dev,
-+ "Failed to init media entity: %d\n", ret);
-+ return ret;
-+ }
-+
-+ ret = v4l2_device_register_subdev(v4l2_dev, sd);
-+ if (ret < 0) {
-+ dev_err(isp_dev->stfcamss->dev,
-+ "Failed to register subdev: %d\n", ret);
-+ goto err_sreg;
-+ }
-+
-+ return 0;
-+
-+err_sreg:
-+ media_entity_cleanup(&sd->entity);
-+ return ret;
-+}
-+
-+int stf_isp_unregister(struct stf_isp_dev *isp_dev)
-+{
-+ v4l2_device_unregister_subdev(&isp_dev->subdev);
-+ media_entity_cleanup(&isp_dev->subdev.entity);
-+ mutex_destroy(&isp_dev->stream_lock);
-+ mutex_destroy(&isp_dev->power_lock);
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_isp.h
-@@ -0,0 +1,476 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_isp.h
-+ *
-+ * StarFive Camera Subsystem - ISP Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_ISP_H
-+#define STF_ISP_H
-+
-+#include <media/media-entity.h>
-+#include <media/v4l2-subdev.h>
-+
-+#include "stf_video.h"
-+
-+#define ISP_RAW_DATA_BITS 12
-+#define SCALER_RATIO_MAX 1
-+#define STF_ISP_REG_OFFSET_MAX 0x0fff
-+#define STF_ISP_REG_DELAY_MAX 100
-+
-+/* isp registers */
-+#define ISP_REG_CSI_INPUT_EN_AND_STATUS 0x000
-+#define CSI_SCD_ERR BIT(6)
-+#define CSI_ITU656_ERR BIT(4)
-+#define CSI_ITU656_F BIT(3)
-+#define CSI_SCD_DONE BIT(2)
-+#define CSI_BUSY_S BIT(1)
-+#define CSI_EN_S BIT(0)
-+
-+#define ISP_REG_CSIINTS 0x008
-+#define CSI_INTS(n) ((n) << 16)
-+#define CSI_SHA_M(n) ((n) << 0)
-+#define CSI_INTS_MASK GENMASK(17, 16)
-+
-+#define ISP_REG_CSI_MODULE_CFG 0x010
-+#define CSI_DUMP_EN BIT(19)
-+#define CSI_VS_EN BIT(18)
-+#define CSI_SC_EN BIT(17)
-+#define CSI_OBA_EN BIT(16)
-+#define CSI_AWB_EN BIT(7)
-+#define CSI_LCCF_EN BIT(6)
-+#define CSI_OECFHM_EN BIT(5)
-+#define CSI_OECF_EN BIT(4)
-+#define CSI_LCBQ_EN BIT(3)
-+#define CSI_OBC_EN BIT(2)
-+#define CSI_DEC_EN BIT(1)
-+#define CSI_DC_EN BIT(0)
-+
-+#define ISP_REG_SENSOR 0x014
-+#define DVP_SYNC_POL(n) ((n) << 2)
-+#define ITU656_EN(n) ((n) << 1)
-+#define IMAGER_SEL(n) ((n) << 0)
-+
-+#define ISP_REG_RAW_FORMAT_CFG 0x018
-+#define SMY13(n) ((n) << 14)
-+#define SMY12(n) ((n) << 12)
-+#define SMY11(n) ((n) << 10)
-+#define SMY10(n) ((n) << 8)
-+#define SMY3(n) ((n) << 6)
-+#define SMY2(n) ((n) << 4)
-+#define SMY1(n) ((n) << 2)
-+#define SMY0(n) ((n) << 0)
-+
-+#define ISP_REG_PIC_CAPTURE_START_CFG 0x01c
-+#define VSTART_CAP(n) ((n) << 16)
-+#define HSTART_CAP(n) ((n) << 0)
-+
-+#define ISP_REG_PIC_CAPTURE_END_CFG 0x020
-+#define VEND_CAP(n) ((n) << 16)
-+#define HEND_CAP(n) ((n) << 0)
-+
-+#define ISP_REG_DUMP_CFG_0 0x024
-+#define ISP_REG_DUMP_CFG_1 0x028
-+#define DUMP_ID(n) ((n) << 24)
-+#define DUMP_SHT(n) ((n) << 20)
-+#define DUMP_BURST_LEN(n) ((n) << 16)
-+#define DUMP_SD(n) ((n) << 0)
-+#define DUMP_BURST_LEN_MASK GENMASK(17, 16)
-+#define DUMP_SD_MASK GENMASK(15, 0)
-+
-+#define ISP_REG_DEC_CFG 0x030
-+#define DEC_V_KEEP(n) ((n) << 24)
-+#define DEC_V_PERIOD(n) ((n) << 16)
-+#define DEC_H_KEEP(n) ((n) << 8)
-+#define DEC_H_PERIOD(n) ((n) << 0)
-+
-+#define ISP_REG_OBC_CFG 0x034
-+#define OBC_W_H(y) ((y) << 4)
-+#define OBC_W_W(x) ((x) << 0)
-+
-+#define ISP_REG_DC_CFG_1 0x044
-+#define DC_AXI_ID(n) ((n) << 0)
-+
-+#define ISP_REG_LCCF_CFG_0 0x050
-+#define Y_DISTANCE(y) ((y) << 16)
-+#define X_DISTANCE(x) ((x) << 16)
-+
-+#define ISP_REG_LCCF_CFG_1 0x058
-+#define LCCF_MAX_DIS(n) ((n) << 0)
-+
-+#define ISP_REG_LCBQ_CFG_0 0x074
-+#define H_LCBQ(y) ((y) << 12)
-+#define W_LCBQ(x) ((x) << 8)
-+
-+#define ISP_REG_LCBQ_CFG_1 0x07c
-+#define Y_COOR(y) ((y) << 16)
-+#define X_COOR(x) ((x) << 0)
-+
-+#define ISP_REG_OECF_X0_CFG0 0x100
-+#define ISP_REG_OECF_X0_CFG1 0x104
-+#define ISP_REG_OECF_X0_CFG2 0x108
-+#define ISP_REG_OECF_X0_CFG3 0x10c
-+#define ISP_REG_OECF_X0_CFG4 0x110
-+#define ISP_REG_OECF_X0_CFG5 0x114
-+#define ISP_REG_OECF_X0_CFG6 0x118
-+#define ISP_REG_OECF_X0_CFG7 0x11c
-+
-+#define ISP_REG_OECF_Y3_CFG0 0x1e0
-+#define ISP_REG_OECF_Y3_CFG1 0x1e4
-+#define ISP_REG_OECF_Y3_CFG2 0x1e8
-+#define ISP_REG_OECF_Y3_CFG3 0x1ec
-+#define ISP_REG_OECF_Y3_CFG4 0x1f0
-+#define ISP_REG_OECF_Y3_CFG5 0x1f4
-+#define ISP_REG_OECF_Y3_CFG6 0x1f8
-+#define ISP_REG_OECF_Y3_CFG7 0x1fc
-+
-+#define ISP_REG_OECF_S0_CFG0 0x200
-+#define ISP_REG_OECF_S3_CFG7 0x27c
-+#define OCEF_PAR_H(n) ((n) << 16)
-+#define OCEF_PAR_L(n) ((n) << 0)
-+
-+#define ISP_REG_AWB_X0_CFG_0 0x280
-+#define ISP_REG_AWB_X0_CFG_1 0x284
-+#define ISP_REG_AWB_X1_CFG_0 0x288
-+#define ISP_REG_AWB_X1_CFG_1 0x28c
-+#define ISP_REG_AWB_X2_CFG_0 0x290
-+#define ISP_REG_AWB_X2_CFG_1 0x294
-+#define ISP_REG_AWB_X3_CFG_0 0x298
-+#define ISP_REG_AWB_X3_CFG_1 0x29c
-+#define AWB_X_SYMBOL_H(n) ((n) << 16)
-+#define AWB_X_SYMBOL_L(n) ((n) << 0)
-+
-+#define ISP_REG_AWB_Y0_CFG_0 0x2a0
-+#define ISP_REG_AWB_Y0_CFG_1 0x2a4
-+#define ISP_REG_AWB_Y1_CFG_0 0x2a8
-+#define ISP_REG_AWB_Y1_CFG_1 0x2ac
-+#define ISP_REG_AWB_Y2_CFG_0 0x2b0
-+#define ISP_REG_AWB_Y2_CFG_1 0x2b4
-+#define ISP_REG_AWB_Y3_CFG_0 0x2b8
-+#define ISP_REG_AWB_Y3_CFG_1 0x2bc
-+#define AWB_Y_SYMBOL_H(n) ((n) << 16)
-+#define AWB_Y_SYMBOL_L(n) ((n) << 0)
-+
-+#define ISP_REG_AWB_S0_CFG_0 0x2c0
-+#define ISP_REG_AWB_S0_CFG_1 0x2c4
-+#define ISP_REG_AWB_S1_CFG_0 0x2c8
-+#define ISP_REG_AWB_S1_CFG_1 0x2cc
-+#define ISP_REG_AWB_S2_CFG_0 0x2d0
-+#define ISP_REG_AWB_S2_CFG_1 0x2d4
-+#define ISP_REG_AWB_S3_CFG_0 0x2d8
-+#define ISP_REG_AWB_S3_CFG_1 0x2dc
-+#define AWB_S_SYMBOL_H(n) ((n) << 16)
-+#define AWB_S_SYMBOL_L(n) ((n) << 0)
-+
-+#define ISP_REG_OBCG_CFG_0 0x2e0
-+#define ISP_REG_OBCG_CFG_1 0x2e4
-+#define ISP_REG_OBCG_CFG_2 0x2e8
-+#define ISP_REG_OBCG_CFG_3 0x2ec
-+#define ISP_REG_OBCO_CFG_0 0x2f0
-+#define ISP_REG_OBCO_CFG_1 0x2f4
-+#define ISP_REG_OBCO_CFG_2 0x2f8
-+#define ISP_REG_OBCO_CFG_3 0x2fc
-+#define GAIN_D_POINT(x) ((x) << 24)
-+#define GAIN_C_POINT(x) ((x) << 16)
-+#define GAIN_B_POINT(x) ((x) << 8)
-+#define GAIN_A_POINT(x) ((x) << 0)
-+#define OFFSET_D_POINT(x) ((x) << 24)
-+#define OFFSET_C_POINT(x) ((x) << 16)
-+#define OFFSET_B_POINT(x) ((x) << 8)
-+#define OFFSET_A_POINT(x) ((x) << 0)
-+
-+#define ISP_REG_ISP_CTRL_0 0xa00
-+#define ISPC_SCFEINT BIT(27)
-+#define ISPC_VSFWINT BIT(26)
-+#define ISPC_VSINT BIT(25)
-+#define ISPC_INTS BIT(24)
-+#define ISPC_ENUO BIT(20)
-+#define ISPC_ENLS BIT(17)
-+#define ISPC_ENSS1 BIT(12)
-+#define ISPC_ENSS0 BIT(11)
-+#define ISPC_RST BIT(1)
-+#define ISPC_EN BIT(0)
-+#define ISPC_RST_MASK BIT(1)
-+
-+#define ISP_REG_ISP_CTRL_1 0xa08
-+#define CTRL_SAT(n) ((n) << 28)
-+#define CTRL_DBC BIT(22)
-+#define CTRL_CTC BIT(21)
-+#define CTRL_YHIST BIT(20)
-+#define CTRL_YCURVE BIT(19)
-+#define CTRL_CTM BIT(18)
-+#define CTRL_BIYUV BIT(17)
-+#define CTRL_SCE BIT(8)
-+#define CTRL_EE BIT(7)
-+#define CTRL_CCE BIT(5)
-+#define CTRL_RGE BIT(4)
-+#define CTRL_CME BIT(3)
-+#define CTRL_AE BIT(2)
-+#define CTRL_CE BIT(1)
-+#define CTRL_SAT_MASK GENMASK(31, 28)
-+
-+#define ISP_REG_PIPELINE_XY_SIZE 0xa0c
-+#define H_ACT_CAP(n) ((n) << 16)
-+#define W_ACT_CAP(n) ((n) << 0)
-+
-+#define ISP_REG_ICTC 0xa10
-+#define GF_MODE(n) ((n) << 30)
-+#define MAXGT(n) ((n) << 16)
-+#define MINGT(n) ((n) << 0)
-+
-+#define ISP_REG_IDBC 0xa14
-+#define BADGT(n) ((n) << 16)
-+#define BADXT(n) ((n) << 0)
-+
-+#define ISP_REG_ICFAM 0xa1c
-+#define CROSS_COV(n) ((n) << 4)
-+#define HV_W(n) ((n) << 0)
-+
-+#define ISP_REG_CS_GAIN 0xa30
-+#define CMAD(n) ((n) << 16)
-+#define CMAB(n) ((n) << 0)
-+
-+#define ISP_REG_CS_THRESHOLD 0xa34
-+#define CMD(n) ((n) << 16)
-+#define CMB(n) ((n) << 0)
-+
-+#define ISP_REG_CS_OFFSET 0xa38
-+#define VOFF(n) ((n) << 16)
-+#define UOFF(n) ((n) << 0)
-+
-+#define ISP_REG_CS_HUE_F 0xa3c
-+#define SIN(n) ((n) << 16)
-+#define COS(n) ((n) << 0)
-+
-+#define ISP_REG_CS_SCALE 0xa40
-+#define CMSF(n) ((n) << 0)
-+
-+#define ISP_REG_IESHD 0xa50
-+#define SHAD_UP_M BIT(1)
-+#define SHAD_UP_EN BIT(0)
-+
-+#define ISP_REG_YADJ0 0xa54
-+#define YOIR(n) ((n) << 16)
-+#define YIMIN(n) ((n) << 0)
-+
-+#define ISP_REG_YADJ1 0xa58
-+#define YOMAX(n) ((n) << 16)
-+#define YOMIN(n) ((n) << 0)
-+
-+#define ISP_REG_Y_PLANE_START_ADDR 0xa80
-+#define ISP_REG_UV_PLANE_START_ADDR 0xa84
-+
-+#define ISP_REG_STRIDE 0xa88
-+#define IMG_STR(n) ((n) << 0)
-+
-+#define ISP_REG_ITIIWSR 0xb20
-+#define ITI_HSIZE(n) ((n) << 16)
-+#define ITI_WSIZE(n) ((n) << 0)
-+
-+#define ISP_REG_ITIDWLSR 0xb24
-+#define ITI_WSTRIDE(n) ((n) << 0)
-+
-+#define ISP_REG_ITIPDFR 0xb38
-+#define ITI_PACKAGE_FMT(n) ((n) << 0)
-+
-+#define ISP_REG_ITIDRLSR 0xb3C
-+#define ITI_STRIDE_L(n) ((n) << 0)
-+
-+#define ISP_REG_DNYUV_YSWR0 0xc00
-+#define ISP_REG_DNYUV_YSWR1 0xc04
-+#define ISP_REG_DNYUV_CSWR0 0xc08
-+#define ISP_REG_DNYUV_CSWR1 0xc0c
-+#define YUVSW5(n) ((n) << 20)
-+#define YUVSW4(n) ((n) << 16)
-+#define YUVSW3(n) ((n) << 12)
-+#define YUVSW2(n) ((n) << 8)
-+#define YUVSW1(n) ((n) << 4)
-+#define YUVSW0(n) ((n) << 0)
-+
-+#define ISP_REG_DNYUV_YDR0 0xc10
-+#define ISP_REG_DNYUV_YDR1 0xc14
-+#define ISP_REG_DNYUV_YDR2 0xc18
-+#define ISP_REG_DNYUV_CDR0 0xc1c
-+#define ISP_REG_DNYUV_CDR1 0xc20
-+#define ISP_REG_DNYUV_CDR2 0xc24
-+#define CURVE_D_H(n) ((n) << 16)
-+#define CURVE_D_L(n) ((n) << 0)
-+
-+#define ISP_REG_ICAMD_0 0xc40
-+#define DNRM_F(n) ((n) << 16)
-+#define ISP_REG_ICAMD_12 0xc70
-+#define ISP_REG_ICAMD_20 0xc90
-+#define ISP_REG_ICAMD_24 0xca0
-+#define ISP_REG_ICAMD_25 0xca4
-+#define CCM_M_DAT(n) ((n) << 0)
-+
-+#define ISP_REG_GAMMA_VAL0 0xe00
-+#define ISP_REG_GAMMA_VAL1 0xe04
-+#define ISP_REG_GAMMA_VAL2 0xe08
-+#define ISP_REG_GAMMA_VAL3 0xe0c
-+#define ISP_REG_GAMMA_VAL4 0xe10
-+#define ISP_REG_GAMMA_VAL5 0xe14
-+#define ISP_REG_GAMMA_VAL6 0xe18
-+#define ISP_REG_GAMMA_VAL7 0xe1c
-+#define ISP_REG_GAMMA_VAL8 0xe20
-+#define ISP_REG_GAMMA_VAL9 0xe24
-+#define ISP_REG_GAMMA_VAL10 0xe28
-+#define ISP_REG_GAMMA_VAL11 0xe2c
-+#define ISP_REG_GAMMA_VAL12 0xe30
-+#define ISP_REG_GAMMA_VAL13 0xe34
-+#define ISP_REG_GAMMA_VAL14 0xe38
-+#define GAMMA_S_VAL(n) ((n) << 16)
-+#define GAMMA_VAL(n) ((n) << 0)
-+
-+#define ISP_REG_R2Y_0 0xe40
-+#define ISP_REG_R2Y_1 0xe44
-+#define ISP_REG_R2Y_2 0xe48
-+#define ISP_REG_R2Y_3 0xe4c
-+#define ISP_REG_R2Y_4 0xe50
-+#define ISP_REG_R2Y_5 0xe54
-+#define ISP_REG_R2Y_6 0xe58
-+#define ISP_REG_R2Y_7 0xe5c
-+#define ISP_REG_R2Y_8 0xe60
-+#define CSC_M(n) ((n) << 0)
-+
-+#define ISP_REG_SHARPEN0 0xe80
-+#define ISP_REG_SHARPEN1 0xe84
-+#define ISP_REG_SHARPEN2 0xe88
-+#define ISP_REG_SHARPEN3 0xe8c
-+#define ISP_REG_SHARPEN4 0xe90
-+#define ISP_REG_SHARPEN5 0xe94
-+#define ISP_REG_SHARPEN6 0xe98
-+#define ISP_REG_SHARPEN7 0xe9c
-+#define ISP_REG_SHARPEN8 0xea0
-+#define ISP_REG_SHARPEN9 0xea4
-+#define ISP_REG_SHARPEN10 0xea8
-+#define ISP_REG_SHARPEN11 0xeac
-+#define ISP_REG_SHARPEN12 0xeb0
-+#define ISP_REG_SHARPEN13 0xeb4
-+#define ISP_REG_SHARPEN14 0xeb8
-+#define S_DELTA(n) ((n) << 16)
-+#define S_WEIGHT(n) ((n) << 8)
-+
-+#define ISP_REG_SHARPEN_FS0 0xebc
-+#define ISP_REG_SHARPEN_FS1 0xec0
-+#define ISP_REG_SHARPEN_FS2 0xec4
-+#define ISP_REG_SHARPEN_FS3 0xec8
-+#define ISP_REG_SHARPEN_FS4 0xecc
-+#define ISP_REG_SHARPEN_FS5 0xed0
-+#define S_FACTOR(n) ((n) << 24)
-+#define S_SLOPE(n) ((n) << 0)
-+
-+#define ISP_REG_SHARPEN_WN 0xed4
-+#define PDIRF(n) ((n) << 28)
-+#define NDIRF(n) ((n) << 24)
-+#define WSUM(n) ((n) << 0)
-+
-+#define ISP_REG_IUVS1 0xed8
-+#define UVDIFF2(n) ((n) << 16)
-+#define UVDIFF1(n) ((n) << 0)
-+
-+#define ISP_REG_IUVS2 0xedc
-+#define UVF(n) ((n) << 24)
-+#define UVSLOPE(n) ((n) << 0)
-+
-+#define ISP_REG_IUVCKS1 0xee0
-+#define UVCKDIFF2(n) ((n) << 16)
-+#define UVCKDIFF1(n) ((n) << 0)
-+
-+#define ISP_REG_IUVCKS2 0xee4
-+#define UVCKSLOPE(n) ((n) << 0)
-+
-+#define ISP_REG_ISHRPET 0xee8
-+#define TH(n) ((n) << 8)
-+#define EN(n) ((n) << 0)
-+
-+#define ISP_REG_YCURVE_0 0xf00
-+#define ISP_REG_YCURVE_63 0xffc
-+#define L_PARAM(n) ((n) << 0)
-+
-+#define IMAGE_MAX_WIDTH 1920
-+#define IMAGE_MAX_HEIGH 1080
-+
-+/* The output line of ISP */
-+enum isp_line_id {
-+ STF_ISP_LINE_INVALID = -1,
-+ STF_ISP_LINE_SRC = 1,
-+ STF_ISP_LINE_MAX = STF_ISP_LINE_SRC
-+};
-+
-+/* pad id for media framework */
-+enum isp_pad_id {
-+ STF_ISP_PAD_SINK = 0,
-+ STF_ISP_PAD_SRC,
-+ STF_ISP_PAD_MAX
-+};
-+
-+enum {
-+ EN_INT_NONE = 0,
-+ EN_INT_ISP_DONE = (0x1 << 24),
-+ EN_INT_CSI_DONE = (0x1 << 25),
-+ EN_INT_SC_DONE = (0x1 << 26),
-+ EN_INT_LINE_INT = (0x1 << 27),
-+ EN_INT_ALL = (0xF << 24),
-+};
-+
-+enum {
-+ INTERFACE_DVP = 0,
-+ INTERFACE_CSI,
-+};
-+
-+struct isp_format {
-+ u32 code;
-+ u8 bpp;
-+};
-+
-+struct isp_format_table {
-+ const struct isp_format *fmts;
-+ int nfmts;
-+};
-+
-+struct regval_t {
-+ u32 addr;
-+ u32 val;
-+ u32 delay_ms;
-+};
-+
-+struct reg_table {
-+ const struct regval_t *regval;
-+ int regval_num;
-+};
-+
-+struct stf_isp_crop {
-+ struct v4l2_rect rect;
-+ u32 bpp;
-+};
-+
-+struct stf_isp_dev {
-+ enum stf_subdev_type sdev_type; /* This member must be first */
-+ struct stfcamss *stfcamss;
-+ struct v4l2_subdev subdev;
-+ struct media_pad pads[STF_ISP_PAD_MAX];
-+ struct v4l2_mbus_framefmt fmt[STF_ISP_PAD_MAX];
-+ struct stf_isp_crop rect[STF_ISP_PAD_MAX];
-+ const struct isp_format_table *formats;
-+ unsigned int nformats;
-+ struct mutex power_lock; /* serialize power control*/
-+ int power_count;
-+ struct mutex stream_lock; /* serialize stream control */
-+ int stream_count;
-+};
-+
-+int stf_isp_clk_enable(struct stf_isp_dev *isp_dev);
-+int stf_isp_clk_disable(struct stf_isp_dev *isp_dev);
-+int stf_isp_reset(struct stf_isp_dev *isp_dev);
-+void stf_isp_init_cfg(struct stf_isp_dev *isp_dev);
-+void stf_isp_settings(struct stf_isp_dev *isp_dev,
-+ struct stf_isp_crop *crop_array, u32 mcode);
-+void stf_isp_stream_set(struct stf_isp_dev *isp_dev);
-+int stf_isp_subdev_init(struct stfcamss *stfcamss);
-+int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2_dev);
-+int stf_isp_unregister(struct stf_isp_dev *isp_dev);
-+
-+#endif /* STF_ISP_H */
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_isp_hw_ops.c
-@@ -0,0 +1,452 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_isp_hw_ops.c
-+ *
-+ * Register interface file for StarFive ISP driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ *
-+ */
-+
-+#include "stf_camss.h"
-+
-+static void stf_isp_config_obc(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val, reg_add;
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_OBC_CFG, OBC_W_H(11) | OBC_W_W(11));
-+
-+ reg_val = GAIN_D_POINT(0x40) | GAIN_C_POINT(0x40) |
-+ GAIN_B_POINT(0x40) | GAIN_A_POINT(0x40);
-+ for (reg_add = ISP_REG_OBCG_CFG_0; reg_add <= ISP_REG_OBCG_CFG_3;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+
-+ reg_val = OFFSET_D_POINT(0) | OFFSET_C_POINT(0) |
-+ OFFSET_B_POINT(0) | OFFSET_A_POINT(0);
-+ for (reg_add = ISP_REG_OBCO_CFG_0; reg_add <= ISP_REG_OBCO_CFG_3;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+}
-+
-+static void stf_isp_config_oecf(struct stfcamss *stfcamss)
-+{
-+ u32 reg_add, par_val;
-+ u16 par_h, par_l;
-+
-+ par_h = 0x10; par_l = 0;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG0; reg_add <= ISP_REG_OECF_Y3_CFG0;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x40; par_l = 0x20;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG1; reg_add <= ISP_REG_OECF_Y3_CFG1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x80; par_l = 0x60;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG2; reg_add <= ISP_REG_OECF_Y3_CFG2;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0xc0; par_l = 0xa0;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG3; reg_add <= ISP_REG_OECF_Y3_CFG3;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x100; par_l = 0xe0;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG4; reg_add <= ISP_REG_OECF_Y3_CFG4;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x200; par_l = 0x180;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG5; reg_add <= ISP_REG_OECF_Y3_CFG5;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x300; par_l = 0x280;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG6; reg_add <= ISP_REG_OECF_Y3_CFG6;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x3fe; par_l = 0x380;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG7; reg_add <= ISP_REG_OECF_Y3_CFG7;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x80; par_l = 0x80;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_S0_CFG0; reg_add <= ISP_REG_OECF_S3_CFG7;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 4;
-+ }
-+}
-+
-+static void stf_isp_config_awb(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val, reg_add;
-+ u16 symbol_h, symbol_l;
-+
-+ symbol_h = 0x0; symbol_l = 0x0;
-+ reg_val = AWB_X_SYMBOL_H(symbol_h) | AWB_X_SYMBOL_L(symbol_l);
-+
-+ for (reg_add = ISP_REG_AWB_X0_CFG_0; reg_add <= ISP_REG_AWB_X3_CFG_1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+
-+ symbol_h = 0x0, symbol_l = 0x0;
-+ reg_val = AWB_Y_SYMBOL_H(symbol_h) | AWB_Y_SYMBOL_L(symbol_l);
-+
-+ for (reg_add = ISP_REG_AWB_Y0_CFG_0; reg_add <= ISP_REG_AWB_Y3_CFG_1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+
-+ symbol_h = 0x80, symbol_l = 0x80;
-+ reg_val = AWB_S_SYMBOL_H(symbol_h) | AWB_S_SYMBOL_L(symbol_l);
-+
-+ for (reg_add = ISP_REG_AWB_S0_CFG_0; reg_add <= ISP_REG_AWB_S3_CFG_1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+}
-+
-+static void stf_isp_config_grgb(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICTC,
-+ GF_MODE(1) | MAXGT(0x140) | MINGT(0x40));
-+ stf_isp_reg_write(stfcamss, ISP_REG_IDBC, BADGT(0x200) | BADXT(0x200));
-+}
-+
-+static void stf_isp_config_cfa(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_RAW_FORMAT_CFG,
-+ SMY13(0) | SMY12(1) | SMY11(0) | SMY10(1) | SMY3(2) |
-+ SMY2(3) | SMY1(2) | SMY0(3));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICFAM, CROSS_COV(3) | HV_W(2));
-+}
-+
-+static void stf_isp_config_ccm(struct stfcamss *stfcamss)
-+{
-+ u32 reg_add;
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_0, DNRM_F(6) | CCM_M_DAT(0));
-+
-+ for (reg_add = ISP_REG_ICAMD_12; reg_add <= ISP_REG_ICAMD_20;) {
-+ stf_isp_reg_write(stfcamss, reg_add, CCM_M_DAT(0x80));
-+ reg_add += 0x10;
-+ }
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_24, CCM_M_DAT(0x700));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_25, CCM_M_DAT(0x200));
-+}
-+
-+static void stf_isp_config_gamma(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val, reg_add;
-+ u16 gamma_slope_v, gamma_v;
-+
-+ gamma_slope_v = 0x2400; gamma_v = 0x0;
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, ISP_REG_GAMMA_VAL0, reg_val);
-+
-+ gamma_slope_v = 0x800; gamma_v = 0x20;
-+ for (reg_add = ISP_REG_GAMMA_VAL1; reg_add <= ISP_REG_GAMMA_VAL7;) {
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ gamma_v += 0x20;
-+ }
-+
-+ gamma_v = 0x100;
-+ for (reg_add = ISP_REG_GAMMA_VAL8; reg_add <= ISP_REG_GAMMA_VAL13;) {
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ gamma_v += 0x80;
-+ }
-+
-+ gamma_v = 0x3fe;
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, ISP_REG_GAMMA_VAL14, reg_val);
-+}
-+
-+static void stf_isp_config_r2y(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_0, CSC_M(0x4C));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_1, CSC_M(0x97));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_2, CSC_M(0x1d));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_3, CSC_M(0x1d5));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_4, CSC_M(0x1ac));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_5, CSC_M(0x80));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_6, CSC_M(0x80));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_7, CSC_M(0x194));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_8, CSC_M(0x1ec));
-+}
-+
-+static void stf_isp_config_y_curve(struct stfcamss *stfcamss)
-+{
-+ u32 reg_add;
-+ u16 y_curve;
-+
-+ y_curve = 0x0;
-+ for (reg_add = ISP_REG_YCURVE_0; reg_add <= ISP_REG_YCURVE_63;) {
-+ stf_isp_reg_write(stfcamss, reg_add, y_curve);
-+ reg_add += 4;
-+ y_curve += 0x10;
-+ }
-+}
-+
-+static void stf_isp_config_sharpen(struct stfcamss *sc)
-+{
-+ u32 reg_add;
-+
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN0, S_DELTA(0x7) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN1, S_DELTA(0x18) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN2, S_DELTA(0x80) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN3, S_DELTA(0x100) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN4, S_DELTA(0x10) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN5, S_DELTA(0x60) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN6, S_DELTA(0x100) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN7, S_DELTA(0x190) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN8, S_DELTA(0x0) | S_WEIGHT(0xf));
-+
-+ for (reg_add = ISP_REG_SHARPEN9; reg_add <= ISP_REG_SHARPEN14;) {
-+ stf_isp_reg_write(sc, reg_add, S_WEIGHT(0xf));
-+ reg_add += 4;
-+ }
-+
-+ for (reg_add = ISP_REG_SHARPEN_FS0; reg_add <= ISP_REG_SHARPEN_FS5;) {
-+ stf_isp_reg_write(sc, reg_add, S_FACTOR(0x10) | S_SLOPE(0x0));
-+ reg_add += 4;
-+ }
-+
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN_WN,
-+ PDIRF(0x8) | NDIRF(0x8) | WSUM(0xd7c));
-+ stf_isp_reg_write(sc, ISP_REG_IUVS1, UVDIFF2(0xC0) | UVDIFF1(0x40));
-+ stf_isp_reg_write(sc, ISP_REG_IUVS2, UVF(0xff) | UVSLOPE(0x0));
-+ stf_isp_reg_write(sc, ISP_REG_IUVCKS1,
-+ UVCKDIFF2(0xa0) | UVCKDIFF1(0x40));
-+}
-+
-+static void stf_isp_config_dnyuv(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val;
-+
-+ reg_val = YUVSW5(7) | YUVSW4(7) | YUVSW3(7) | YUVSW2(7) |
-+ YUVSW1(7) | YUVSW0(7);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YSWR0, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CSWR0, reg_val);
-+
-+ reg_val = YUVSW3(7) | YUVSW2(7) | YUVSW1(7) | YUVSW0(7);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YSWR1, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CSWR1, reg_val);
-+
-+ reg_val = CURVE_D_H(0x60) | CURVE_D_L(0x40);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR0, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR0, reg_val);
-+
-+ reg_val = CURVE_D_H(0xd8) | CURVE_D_L(0x90);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR1, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR1, reg_val);
-+
-+ reg_val = CURVE_D_H(0x1e6) | CURVE_D_L(0x144);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR2, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR2, reg_val);
-+}
-+
-+static void stf_isp_config_sat(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_GAIN, CMAD(0x0) | CMAB(0x100));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_THRESHOLD, CMD(0x1f) | CMB(0x1));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_OFFSET, VOFF(0x0) | UOFF(0x0));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_HUE_F, SIN(0x0) | COS(0x100));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_SCALE, CMSF(0x8));
-+ stf_isp_reg_write(stfcamss, ISP_REG_YADJ0, YOIR(0x401) | YIMIN(0x1));
-+ stf_isp_reg_write(stfcamss, ISP_REG_YADJ1, YOMAX(0x3ff) | YOMIN(0x1));
-+}
-+
-+int stf_isp_clk_enable(struct stf_isp_dev *isp_dev)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_WRAPPER_CLK_C].clk);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_WRAPPER_C].rstc);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_WRAPPER_P].rstc);
-+
-+ return 0;
-+}
-+
-+int stf_isp_clk_disable(struct stf_isp_dev *isp_dev)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_WRAPPER_C].rstc);
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_WRAPPER_P].rstc);
-+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_WRAPPER_CLK_C].clk);
-+
-+ return 0;
-+}
-+
-+int stf_isp_reset(struct stf_isp_dev *isp_dev)
-+{
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_RST_MASK, ISPC_RST);
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_RST_MASK, 0);
-+
-+ return 0;
-+}
-+
-+void stf_isp_init_cfg(struct stf_isp_dev *isp_dev)
-+{
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_DC_CFG_1, DC_AXI_ID(0x0));
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_DEC_CFG,
-+ DEC_V_KEEP(0x0) |
-+ DEC_V_PERIOD(0x0) |
-+ DEC_H_KEEP(0x0) |
-+ DEC_H_PERIOD(0x0));
-+
-+ stf_isp_config_obc(isp_dev->stfcamss);
-+ stf_isp_config_oecf(isp_dev->stfcamss);
-+ stf_isp_config_awb(isp_dev->stfcamss);
-+ stf_isp_config_grgb(isp_dev->stfcamss);
-+ stf_isp_config_cfa(isp_dev->stfcamss);
-+ stf_isp_config_ccm(isp_dev->stfcamss);
-+ stf_isp_config_gamma(isp_dev->stfcamss);
-+ stf_isp_config_r2y(isp_dev->stfcamss);
-+ stf_isp_config_y_curve(isp_dev->stfcamss);
-+ stf_isp_config_sharpen(isp_dev->stfcamss);
-+ stf_isp_config_dnyuv(isp_dev->stfcamss);
-+ stf_isp_config_sat(isp_dev->stfcamss);
-+
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_CSI_MODULE_CFG,
-+ CSI_DUMP_EN | CSI_SC_EN | CSI_AWB_EN |
-+ CSI_LCCF_EN | CSI_OECF_EN | CSI_OBC_EN | CSI_DEC_EN);
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_ISP_CTRL_1,
-+ CTRL_SAT(1) | CTRL_DBC | CTRL_CTC | CTRL_YHIST |
-+ CTRL_YCURVE | CTRL_BIYUV | CTRL_SCE | CTRL_EE |
-+ CTRL_CCE | CTRL_RGE | CTRL_CME | CTRL_AE | CTRL_CE);
-+}
-+
-+static void stf_isp_config_crop(struct stfcamss *stfcamss,
-+ struct stf_isp_crop *crop)
-+{
-+ struct v4l2_rect *rect = &crop[STF_ISP_PAD_SRC].rect;
-+ u32 bpp = crop[STF_ISP_PAD_SRC].bpp;
-+ u32 val;
-+
-+ val = VSTART_CAP(rect->top) | HSTART_CAP(rect->left);
-+ stf_isp_reg_write(stfcamss, ISP_REG_PIC_CAPTURE_START_CFG, val);
-+
-+ val = VEND_CAP(rect->height + rect->top - 1) |
-+ HEND_CAP(rect->width + rect->left - 1);
-+ stf_isp_reg_write(stfcamss, ISP_REG_PIC_CAPTURE_END_CFG, val);
-+
-+ val = H_ACT_CAP(rect->height) | W_ACT_CAP(rect->width);
-+ stf_isp_reg_write(stfcamss, ISP_REG_PIPELINE_XY_SIZE, val);
-+
-+ val = ALIGN(rect->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
-+ stf_isp_reg_write(stfcamss, ISP_REG_STRIDE, val);
-+}
-+
-+static void stf_isp_config_raw_fmt(struct stfcamss *stfcamss, u32 mcode)
-+{
-+ u32 val, val1;
-+
-+ switch (mcode) {
-+ case MEDIA_BUS_FMT_SRGGB10_1X10:
-+ case MEDIA_BUS_FMT_SRGGB8_1X8:
-+ /* 3 2 3 2 1 0 1 0 B Gb B Gb Gr R Gr R */
-+ val = SMY13(3) | SMY12(2) | SMY11(3) | SMY10(2) |
-+ SMY3(1) | SMY2(0) | SMY1(1) | SMY0(0);
-+ val1 = CTRL_SAT(0x0);
-+ break;
-+ case MEDIA_BUS_FMT_SGRBG10_1X10:
-+ case MEDIA_BUS_FMT_SGRBG8_1X8:
-+ /* 2 3 2 3 0 1 0 1, Gb B Gb B R Gr R Gr */
-+ val = SMY13(2) | SMY12(3) | SMY11(2) | SMY10(3) |
-+ SMY3(0) | SMY2(1) | SMY1(0) | SMY0(1);
-+ val1 = CTRL_SAT(0x2);
-+ break;
-+ case MEDIA_BUS_FMT_SGBRG10_1X10:
-+ case MEDIA_BUS_FMT_SGBRG8_1X8:
-+ /* 1 0 1 0 3 2 3 2, Gr R Gr R B Gb B Gb */
-+ val = SMY13(1) | SMY12(0) | SMY11(1) | SMY10(0) |
-+ SMY3(3) | SMY2(2) | SMY1(3) | SMY0(2);
-+ val1 = CTRL_SAT(0x3);
-+ break;
-+ case MEDIA_BUS_FMT_SBGGR10_1X10:
-+ case MEDIA_BUS_FMT_SBGGR8_1X8:
-+ /* 0 1 0 1 2 3 2 3 R Gr R Gr Gb B Gb B */
-+ val = SMY13(0) | SMY12(1) | SMY11(0) | SMY10(1) |
-+ SMY3(2) | SMY2(3) | SMY1(2) | SMY0(3);
-+ val1 = CTRL_SAT(0x1);
-+ break;
-+ default:
-+ val = SMY13(0) | SMY12(1) | SMY11(0) | SMY10(1) |
-+ SMY3(2) | SMY2(3) | SMY1(2) | SMY0(3);
-+ val1 = CTRL_SAT(0x1);
-+ break;
-+ }
-+ stf_isp_reg_write(stfcamss, ISP_REG_RAW_FORMAT_CFG, val);
-+ stf_isp_reg_set_bit(stfcamss, ISP_REG_ISP_CTRL_1, CTRL_SAT_MASK, val1);
-+}
-+
-+void stf_isp_settings(struct stf_isp_dev *isp_dev,
-+ struct stf_isp_crop *crop, u32 mcode)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ stf_isp_config_crop(stfcamss, crop);
-+ stf_isp_config_raw_fmt(stfcamss, mcode);
-+
-+ stf_isp_reg_set_bit(stfcamss, ISP_REG_DUMP_CFG_1,
-+ DUMP_BURST_LEN_MASK | DUMP_SD_MASK,
-+ DUMP_BURST_LEN(3));
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_ITIIWSR,
-+ ITI_HSIZE(IMAGE_MAX_HEIGH) |
-+ ITI_WSIZE(IMAGE_MAX_WIDTH));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ITIDWLSR, ITI_WSTRIDE(0x960));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ITIDRLSR, ITI_STRIDE_L(0x960));
-+ stf_isp_reg_write(stfcamss, ISP_REG_SENSOR, 0x1);
-+}
-+
-+void stf_isp_stream_set(struct stf_isp_dev *isp_dev)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_ENUO | ISPC_ENLS | ISPC_RST, 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_ENUO | ISPC_ENLS, 10);
-+ stf_isp_reg_write(stfcamss, ISP_REG_IESHD, SHAD_UP_M);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_ENUO | ISPC_ENLS | ISPC_EN, 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_CSIINTS,
-+ CSI_INTS(1) | CSI_SHA_M(4), 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_CSIINTS,
-+ CSI_INTS(2) | CSI_SHA_M(4), 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_CSI_INPUT_EN_AND_STATUS,
-+ CSI_EN_S, 10);
-+}
diff --git a/target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch b/target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch
deleted file mode 100644
index 2ab822ae96..0000000000
--- a/target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch
+++ /dev/null
@@ -1,1694 +0,0 @@
-From 030f0312433a85899fab4dccada5b2cbceb3bad5 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:44 +0800
-Subject: [PATCH 086/122] media: starfive: Add VIN driver
-
-Add Video In Controller driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/starfive/Makefile | 4 +-
- drivers/media/platform/starfive/stf_camss.c | 39 +-
- drivers/media/platform/starfive/stf_camss.h | 2 +
- drivers/media/platform/starfive/stf_vin.c | 1134 +++++++++++++++++
- drivers/media/platform/starfive/stf_vin.h | 180 +++
- .../media/platform/starfive/stf_vin_hw_ops.c | 241 ++++
- 6 files changed, 1598 insertions(+), 2 deletions(-)
- create mode 100644 drivers/media/platform/starfive/stf_vin.c
- create mode 100644 drivers/media/platform/starfive/stf_vin.h
- create mode 100644 drivers/media/platform/starfive/stf_vin_hw_ops.c
-
---- a/drivers/media/platform/starfive/Makefile
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -7,6 +7,8 @@ starfive-camss-objs += \
- stf_camss.o \
- stf_isp.o \
- stf_isp_hw_ops.o \
-- stf_video.o
-+ stf_video.o \
-+ stf_vin.o \
-+ stf_vin_hw_ops.o
-
- obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- a/drivers/media/platform/starfive/stf_camss.c
-+++ b/drivers/media/platform/starfive/stf_camss.c
-@@ -142,27 +142,61 @@ static int stfcamss_init_subdevices(stru
- return ret;
- }
-
-+ ret = stf_vin_subdev_init(stfcamss);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev, "Failed to init vin subdev: %d\n", ret);
-+ return ret;
-+ }
- return ret;
- }
-
- static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
- {
- int ret;
-+ struct stf_vin_dev *vin_dev = &stfcamss->vin_dev;
- struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-
- ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
- if (ret < 0) {
- dev_err(stfcamss->dev,
- "Failed to register stf isp%d entity: %d\n", 0, ret);
-- return ret;
-+ goto err_reg_isp;
-+ }
-+
-+ ret = stf_vin_register(vin_dev, &stfcamss->v4l2_dev);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to register vin entity: %d\n", ret);
-+ goto err_reg_vin;
- }
-
-+ ret = media_create_pad_link(&isp_dev->subdev.entity,
-+ STF_ISP_PAD_SRC,
-+ &vin_dev->line[VIN_LINE_ISP].subdev.entity,
-+ STF_VIN_PAD_SINK,
-+ 0);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to link %s->%s entities: %d\n",
-+ isp_dev->subdev.entity.name,
-+ vin_dev->line[VIN_LINE_ISP].subdev.entity.name, ret);
-+ goto err_link;
-+ }
-+
-+ return ret;
-+
-+err_link:
-+ stf_vin_unregister(&stfcamss->vin_dev);
-+err_reg_vin:
-+ stf_isp_unregister(&stfcamss->isp_dev);
-+err_reg_isp:
- return ret;
- }
-
- static void stfcamss_unregister_subdevices(struct stfcamss *stfcamss)
- {
- stf_isp_unregister(&stfcamss->isp_dev);
-+ stf_vin_unregister(&stfcamss->vin_dev);
- }
-
- static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
-@@ -175,11 +209,14 @@ static int stfcamss_subdev_notifier_boun
- container_of(asd, struct stfcamss_async_subdev, asd);
- enum port_num port = csd->port;
- struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-+ struct stf_vin_dev *vin_dev = &stfcamss->vin_dev;
- struct host_data *host_data = &stfcamss->host_data;
- struct media_entity *source;
- int i, j;
-
- if (port == PORT_NUMBER_CSI2RX) {
-+ host_data->host_entity[0] =
-+ &vin_dev->line[VIN_LINE_WR].subdev.entity;
- host_data->host_entity[1] = &isp_dev->subdev.entity;
- } else if (port == PORT_NUMBER_DVP_SENSOR) {
- dev_err(stfcamss->dev, "Not support DVP sensor\n");
---- a/drivers/media/platform/starfive/stf_camss.h
-+++ b/drivers/media/platform/starfive/stf_camss.h
-@@ -17,6 +17,7 @@
-
- #include "stf_common.h"
- #include "stf_isp.h"
-+#include "stf_vin.h"
-
- #define DRV_NAME "starfive-camss"
- #define STF_DVP_NAME "stf_dvp"
-@@ -72,6 +73,7 @@ struct stfcamss {
- struct media_device media_dev;
- struct media_pipeline pipe;
- struct device *dev;
-+ struct stf_vin_dev vin_dev;
- struct stf_isp_dev isp_dev;
- struct v4l2_async_notifier notifier;
- struct host_data host_data;
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_vin.c
-@@ -0,0 +1,1134 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_vin.c
-+ *
-+ * StarFive Camera Subsystem - VIN Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include <linux/pm_runtime.h>
-+
-+#include "stf_camss.h"
-+
-+#define vin_line_array(ptr_line) \
-+ ((const struct vin_line (*)[]) &(ptr_line)[-((ptr_line)->id)])
-+
-+#define line_to_vin_dev(ptr_line) \
-+ container_of(vin_line_array(ptr_line), struct stf_vin_dev, line)
-+
-+#define VIN_FRAME_DROP_MAX_VAL 90
-+#define VIN_FRAME_DROP_MIN_VAL 4
-+#define VIN_FRAME_PER_SEC_MAX_VAL 90
-+
-+/* ISP ctrl need 1 sec to let frames become stable. */
-+#define VIN_FRAME_DROP_SEC_FOR_ISP_CTRL 1
-+
-+static const struct vin_format vin_formats_wr[] = {
-+ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
-+ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
-+ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
-+ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
-+};
-+
-+static const struct vin_format vin_formats_uo[] = {
-+ { MEDIA_BUS_FMT_Y12_1X12, 8},
-+};
-+
-+static const struct vin_format_table vin_formats_table[] = {
-+ /* VIN_LINE_WR */
-+ { vin_formats_wr, ARRAY_SIZE(vin_formats_wr) },
-+ /* VIN_LINE_ISP */
-+ { vin_formats_uo, ARRAY_SIZE(vin_formats_uo) },
-+};
-+
-+static void vin_buffer_done(struct vin_line *line);
-+static void vin_change_buffer(struct vin_line *line);
-+static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output);
-+static void vin_output_init_addrs(struct vin_line *line);
-+static void vin_init_outputs(struct vin_line *line);
-+static struct v4l2_mbus_framefmt *
-+__vin_get_format(struct vin_line *line,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which);
-+
-+static char *vin_get_line_subdevname(int line_id)
-+{
-+ char *name = NULL;
-+
-+ switch (line_id) {
-+ case VIN_LINE_WR:
-+ name = "wr";
-+ break;
-+ case VIN_LINE_ISP:
-+ name = "isp0";
-+ break;
-+ default:
-+ name = "unknown";
-+ break;
-+ }
-+ return name;
-+}
-+
-+static enum isp_line_id vin_map_isp_line(enum vin_line_id line)
-+{
-+ enum isp_line_id line_id;
-+
-+ if (line > VIN_LINE_WR && line < VIN_LINE_MAX)
-+ line_id = STF_ISP_LINE_SRC;
-+ else
-+ line_id = STF_ISP_LINE_INVALID;
-+
-+ return line_id;
-+}
-+
-+enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line, enum isp_pad_id def)
-+{
-+ enum isp_pad_id pad_id;
-+
-+ if (line == VIN_LINE_WR)
-+ pad_id = STF_ISP_PAD_SINK;
-+ else if ((line > VIN_LINE_WR) && (line < VIN_LINE_MAX))
-+ pad_id = (enum isp_pad_id)vin_map_isp_line(line);
-+ else
-+ pad_id = def;
-+
-+ return pad_id;
-+}
-+
-+int stf_vin_subdev_init(struct stfcamss *stfcamss)
-+{
-+ struct device *dev = stfcamss->dev;
-+ struct stf_vin_dev *vin_dev = &stfcamss->vin_dev;
-+ int i, ret = 0;
-+
-+ vin_dev->stfcamss = stfcamss;
-+
-+ vin_dev->isr_ops = devm_kzalloc(dev, sizeof(*vin_dev->isr_ops),
-+ GFP_KERNEL);
-+ if (!vin_dev->isr_ops)
-+ return -ENOMEM;
-+ vin_dev->isr_ops->isr_buffer_done = vin_buffer_done;
-+ vin_dev->isr_ops->isr_change_buffer = vin_change_buffer;
-+
-+ atomic_set(&vin_dev->ref_count, 0);
-+
-+ ret = devm_request_irq(dev,
-+ stfcamss->irq[STF_IRQ_VINWR],
-+ stf_vin_wr_irq_handler,
-+ 0, "vin_axiwr_irq", vin_dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to request irq\n");
-+ goto out;
-+ }
-+
-+ ret = devm_request_irq(dev,
-+ stfcamss->irq[STF_IRQ_ISP],
-+ stf_vin_isp_irq_handler,
-+ 0, "vin_isp_irq", vin_dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to request isp irq\n");
-+ goto out;
-+ }
-+
-+ ret = devm_request_irq(dev,
-+ stfcamss->irq[STF_IRQ_ISPCSIL],
-+ stf_vin_isp_irq_csiline_handler,
-+ 0, "vin_isp_irq_csiline", vin_dev);
-+ if (ret) {
-+ dev_err(dev, "failed to request isp irq csiline\n");
-+ goto out;
-+ }
-+
-+ mutex_init(&vin_dev->power_lock);
-+ vin_dev->power_count = 0;
-+
-+ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++) {
-+ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[i];
-+
-+ mutex_init(&dummy_buffer->stream_lock);
-+ dummy_buffer->nums =
-+ i == 0 ? VIN_DUMMY_BUFFER_NUMS : ISP_DUMMY_BUFFER_NUMS;
-+ dummy_buffer->stream_count = 0;
-+ dummy_buffer->buffer =
-+ devm_kzalloc(dev,
-+ dummy_buffer->nums * sizeof(struct vin_dummy_buffer),
-+ GFP_KERNEL);
-+ atomic_set(&dummy_buffer->frame_skip, 0);
-+ }
-+
-+ for (i = VIN_LINE_WR; i < STF_ISP_LINE_MAX + 1; i++) {
-+ struct vin_line *l = &vin_dev->line[i];
-+
-+ l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ l->video_out.stfcamss = stfcamss;
-+ l->id = i;
-+ l->sdev_type = STF_SUBDEV_TYPE_VIN;
-+ l->formats = vin_formats_table[i].fmts;
-+ l->nformats = vin_formats_table[i].nfmts;
-+ spin_lock_init(&l->output_lock);
-+
-+ mutex_init(&l->stream_lock);
-+ l->stream_count = 0;
-+ mutex_init(&l->power_lock);
-+ l->power_count = 0;
-+ }
-+
-+ return 0;
-+out:
-+ return ret;
-+}
-+
-+static enum link vin_get_link(struct media_entity *entity)
-+{
-+ struct v4l2_subdev *subdev;
-+ struct media_pad *pad;
-+ bool isp = false;
-+
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ return LINK_ERROR;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ return LINK_ERROR;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ if (!strncmp(subdev->name, STF_CSI_NAME,
-+ strlen(STF_CSI_NAME))) {
-+ if (isp)
-+ return LINK_CSI_TO_ISP;
-+ else
-+ return LINK_CSI_TO_WR;
-+ } else if (!strncmp(subdev->name, STF_DVP_NAME,
-+ strlen(STF_DVP_NAME))) {
-+ if (isp)
-+ return LINK_DVP_TO_ISP;
-+ else
-+ return LINK_DVP_TO_WR;
-+ } else if (!strncmp(subdev->name, STF_ISP_NAME,
-+ strlen(STF_ISP_NAME))) {
-+ isp = true;
-+ } else {
-+ return LINK_ERROR;
-+ }
-+ }
-+}
-+
-+static int vin_set_power(struct v4l2_subdev *sd, int on)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+ enum link link;
-+
-+ mutex_lock(&line->power_lock);
-+ if (on) {
-+ if (line->power_count == 0)
-+ vin_init_outputs(line);
-+ line->power_count++;
-+ } else {
-+ if (line->power_count == 0) {
-+ dev_err(stfcamss->dev,
-+ "line power off on power_count = 0\n");
-+ goto exit_line;
-+ }
-+ line->power_count--;
-+ }
-+exit_line:
-+ mutex_unlock(&line->power_lock);
-+
-+ mutex_lock(&vin_dev->power_lock);
-+ link = vin_get_link(&sd->entity);
-+ if (link == LINK_ERROR)
-+ goto exit;
-+
-+ if (on) {
-+ if (vin_dev->power_count == 0) {
-+ pm_runtime_get_sync(stfcamss->dev);
-+ stf_vin_clk_enable(vin_dev, link);
-+ }
-+ vin_dev->power_count++;
-+ } else {
-+ if (vin_dev->power_count == 0) {
-+ dev_err(stfcamss->dev,
-+ "vin_dev power off on power_count=0\n");
-+ goto exit;
-+ }
-+ if (vin_dev->power_count == 1) {
-+ stf_vin_clk_disable(vin_dev, link);
-+ pm_runtime_put_sync(stfcamss->dev);
-+ }
-+ vin_dev->power_count--;
-+ }
-+exit:
-+
-+ mutex_unlock(&vin_dev->power_lock);
-+
-+ return 0;
-+}
-+
-+static int vin_enable_output(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ output->state = VIN_OUTPUT_IDLE;
-+
-+ output->buf[0] = vin_buf_get_pending(output);
-+
-+ if (!output->buf[0] && output->buf[1]) {
-+ output->buf[0] = output->buf[1];
-+ output->buf[1] = NULL;
-+ }
-+
-+ if (output->buf[0])
-+ output->state = VIN_OUTPUT_SINGLE;
-+
-+ output->sequence = 0;
-+
-+ vin_output_init_addrs(line);
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return 0;
-+}
-+
-+static int vin_disable_output(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ output->state = VIN_OUTPUT_OFF;
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return 0;
-+}
-+
-+static u32 vin_line_to_dummy_module(struct vin_line *line)
-+{
-+ u32 dummy_module = 0;
-+
-+ switch (line->id) {
-+ case VIN_LINE_WR:
-+ dummy_module = STF_DUMMY_VIN;
-+ break;
-+ case VIN_LINE_ISP:
-+ dummy_module = STF_DUMMY_ISP;
-+ break;
-+ default:
-+ dummy_module = STF_DUMMY_VIN;
-+ break;
-+ }
-+
-+ return dummy_module;
-+}
-+
-+static int vin_alloc_dummy_buffer(struct stf_vin_dev *vin_dev,
-+ struct v4l2_mbus_framefmt *fmt,
-+ int dummy_module)
-+{
-+ struct device *dev = vin_dev->stfcamss->dev;
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct vin_dummy_buffer *buffer = NULL;
-+ int ret = 0, i;
-+ u32 aligns;
-+
-+ for (i = 0; i < dummy_buffer->nums; i++) {
-+ buffer = &vin_dev->dummy_buffer[dummy_module].buffer[i];
-+ buffer->width = fmt->width;
-+ buffer->height = fmt->height;
-+ buffer->mcode = fmt->code;
-+ if (i == STF_VIN_PAD_SINK) {
-+ aligns = ALIGN(fmt->width * 4,
-+ STFCAMSS_FRAME_WIDTH_ALIGN_8);
-+ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height);
-+ } else if (i == STF_ISP_PAD_SRC) {
-+ aligns = ALIGN(fmt->width,
-+ STFCAMSS_FRAME_WIDTH_ALIGN_8);
-+ buffer->buffer_size =
-+ PAGE_ALIGN(aligns * fmt->height * 3 / 2);
-+ } else {
-+ continue;
-+ }
-+
-+ buffer->vaddr = dma_alloc_coherent(dev,
-+ buffer->buffer_size,
-+ &buffer->paddr[0],
-+ GFP_DMA | GFP_KERNEL);
-+
-+ if (buffer->vaddr) {
-+ if (i == STF_ISP_PAD_SRC)
-+ buffer->paddr[1] =
-+ (dma_addr_t)(buffer->paddr[0] + aligns * fmt->height);
-+ else
-+ dev_dbg(dev, "signal plane\n");
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+static void vin_free_dummy_buffer(struct stf_vin_dev *vin_dev, int dummy_module)
-+{
-+ struct device *dev = vin_dev->stfcamss->dev;
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct vin_dummy_buffer *buffer = NULL;
-+ int i;
-+
-+ for (i = 0; i < dummy_buffer->nums; i++) {
-+ buffer = &dummy_buffer->buffer[i];
-+ if (buffer->vaddr)
-+ dma_free_coherent(dev, buffer->buffer_size,
-+ buffer->vaddr, buffer->paddr[0]);
-+ memset(buffer, 0, sizeof(struct vin_dummy_buffer));
-+ }
-+}
-+
-+static void vin_set_dummy_buffer(struct vin_line *line, u32 pad)
-+{
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ int dummy_module = vin_line_to_dummy_module(line);
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct vin_dummy_buffer *buffer = NULL;
-+
-+ switch (pad) {
-+ case STF_VIN_PAD_SINK:
-+ if (line->id == VIN_LINE_WR) {
-+ buffer = &dummy_buffer->buffer[STF_VIN_PAD_SINK];
-+ stf_vin_wr_set_ping_addr(vin_dev, buffer->paddr[0]);
-+ stf_vin_wr_set_pong_addr(vin_dev, buffer->paddr[0]);
-+ } else {
-+ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
-+ stf_vin_isp_set_yuv_addr(vin_dev,
-+ buffer->paddr[0],
-+ buffer->paddr[1]);
-+ }
-+ break;
-+ case STF_ISP_PAD_SRC:
-+ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
-+ stf_vin_isp_set_yuv_addr(vin_dev,
-+ buffer->paddr[0],
-+ buffer->paddr[1]);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static int vin_set_stream(struct v4l2_subdev *sd, int enable)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ int dummy_module = vin_line_to_dummy_module(line);
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct v4l2_mbus_framefmt *fmt;
-+ enum link link;
-+
-+ fmt = __vin_get_format(line, NULL,
-+ STF_VIN_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE);
-+ mutex_lock(&dummy_buffer->stream_lock);
-+ if (enable) {
-+ if (dummy_buffer->stream_count == 0) {
-+ vin_alloc_dummy_buffer(vin_dev, fmt, dummy_module);
-+ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
-+ atomic_set(&dummy_buffer->frame_skip,
-+ VIN_FRAME_DROP_MIN_VAL + 30);
-+ }
-+ dummy_buffer->stream_count++;
-+ } else {
-+ if (dummy_buffer->stream_count == 1) {
-+ vin_free_dummy_buffer(vin_dev, dummy_module);
-+ /* set buffer addr to zero */
-+ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
-+ } else {
-+ vin_set_dummy_buffer(line,
-+ stf_vin_map_isp_pad(line->id, STF_ISP_PAD_SINK));
-+ }
-+
-+ dummy_buffer->stream_count--;
-+ }
-+ mutex_unlock(&dummy_buffer->stream_lock);
-+
-+ mutex_lock(&line->stream_lock);
-+ link = vin_get_link(&sd->entity);
-+ if (link == LINK_ERROR)
-+ goto exit;
-+
-+ if (enable) {
-+ if (line->stream_count == 0) {
-+ stf_vin_stream_set(vin_dev, link);
-+ if (line->id == VIN_LINE_WR) {
-+ stf_vin_wr_irq_enable(vin_dev, 1);
-+ stf_vin_wr_stream_set(vin_dev);
-+ }
-+ }
-+ line->stream_count++;
-+ } else {
-+ if (line->stream_count == 1 && line->id == VIN_LINE_WR)
-+ stf_vin_wr_irq_enable(vin_dev, 0);
-+ line->stream_count--;
-+ }
-+exit:
-+ mutex_unlock(&line->stream_lock);
-+
-+ if (enable)
-+ vin_enable_output(line);
-+ else
-+ vin_disable_output(line);
-+
-+ return 0;
-+}
-+
-+static struct v4l2_mbus_framefmt *
-+__vin_get_format(struct vin_line *line,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ if (which == V4L2_SUBDEV_FORMAT_TRY)
-+ return v4l2_subdev_get_try_format(&line->subdev, state, pad);
-+ return &line->fmt[pad];
-+}
-+
-+static void vin_try_format(struct vin_line *line,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ struct v4l2_mbus_framefmt *fmt,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ unsigned int i;
-+
-+ switch (pad) {
-+ case STF_VIN_PAD_SINK:
-+ /* Set format on sink pad */
-+ for (i = 0; i < line->nformats; i++)
-+ if (fmt->code == line->formats[i].code)
-+ break;
-+
-+ /* If not found, use UYVY as default */
-+ if (i >= line->nformats)
-+ fmt->code = line->formats[0].code;
-+
-+ fmt->width = clamp_t(u32, fmt->width,
-+ STFCAMSS_FRAME_MIN_WIDTH,
-+ STFCAMSS_FRAME_MAX_WIDTH);
-+ fmt->height = clamp_t(u32, fmt->height,
-+ STFCAMSS_FRAME_MIN_HEIGHT,
-+ STFCAMSS_FRAME_MAX_HEIGHT);
-+
-+ fmt->field = V4L2_FIELD_NONE;
-+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
-+ fmt->flags = 0;
-+ break;
-+
-+ case STF_VIN_PAD_SRC:
-+ /* Set and return a format same as sink pad */
-+ *fmt = *__vin_get_format(line, state, STF_VIN_PAD_SINK, which);
-+ break;
-+ }
-+
-+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
-+}
-+
-+static int vin_enum_mbus_code(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_mbus_code_enum *code)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+
-+ if (code->index >= line->nformats)
-+ return -EINVAL;
-+ if (code->pad == STF_VIN_PAD_SINK) {
-+ code->code = line->formats[code->index].code;
-+ } else {
-+ struct v4l2_mbus_framefmt *sink_fmt;
-+
-+ sink_fmt = __vin_get_format(line, state, STF_VIN_PAD_SINK,
-+ code->which);
-+
-+ code->code = sink_fmt->code;
-+ if (!code->code)
-+ return -EINVAL;
-+ }
-+ code->flags = 0;
-+
-+ return 0;
-+}
-+
-+static int vin_enum_frame_size(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_frame_size_enum *fse)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt format;
-+
-+ if (fse->index != 0)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = 1;
-+ format.height = 1;
-+ vin_try_format(line, state, fse->pad, &format, fse->which);
-+ fse->min_width = format.width;
-+ fse->min_height = format.height;
-+
-+ if (format.code != fse->code)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = -1;
-+ format.height = -1;
-+ vin_try_format(line, state, fse->pad, &format, fse->which);
-+ fse->max_width = format.width;
-+ fse->max_height = format.height;
-+
-+ return 0;
-+}
-+
-+static int vin_get_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __vin_get_format(line, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ fmt->format = *format;
-+
-+ return 0;
-+}
-+
-+static int vin_set_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __vin_get_format(line, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ mutex_lock(&line->stream_lock);
-+ if (line->stream_count) {
-+ fmt->format = *format;
-+ mutex_unlock(&line->stream_lock);
-+ goto out;
-+ } else {
-+ vin_try_format(line, state, fmt->pad, &fmt->format, fmt->which);
-+ *format = fmt->format;
-+ }
-+ mutex_unlock(&line->stream_lock);
-+
-+ if (fmt->pad == STF_VIN_PAD_SINK) {
-+ /* Propagate the format from sink to source */
-+ format = __vin_get_format(line, state, STF_VIN_PAD_SRC,
-+ fmt->which);
-+
-+ *format = fmt->format;
-+ vin_try_format(line, state, STF_VIN_PAD_SRC, format,
-+ fmt->which);
-+ }
-+
-+out:
-+ return 0;
-+}
-+
-+static int vin_init_formats(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_fh *fh)
-+{
-+ struct v4l2_subdev_format format = {
-+ .pad = STF_VIN_PAD_SINK,
-+ .which = fh ?
-+ V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE,
-+ .format = {
-+ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
-+ .width = 1920,
-+ .height = 1080
-+ }
-+ };
-+
-+ return vin_set_format(sd, fh ? fh->state : NULL, &format);
-+}
-+
-+static void vin_output_init_addrs(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ dma_addr_t ping_addr;
-+ dma_addr_t y_addr, uv_addr;
-+
-+ output->active_buf = 0;
-+
-+ if (output->buf[0]) {
-+ ping_addr = output->buf[0]->addr[0];
-+ y_addr = output->buf[0]->addr[0];
-+ uv_addr = output->buf[0]->addr[1];
-+ } else {
-+ return;
-+ }
-+
-+ switch (vin_map_isp_line(line->id)) {
-+ case STF_ISP_LINE_SRC:
-+ stf_vin_isp_set_yuv_addr(vin_dev, y_addr, uv_addr);
-+ break;
-+ default:
-+ if (line->id == VIN_LINE_WR) {
-+ stf_vin_wr_set_ping_addr(vin_dev, ping_addr);
-+ stf_vin_wr_set_pong_addr(vin_dev, ping_addr);
-+ }
-+ break;
-+ }
-+}
-+
-+static void vin_init_outputs(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+
-+ output->state = VIN_OUTPUT_OFF;
-+ output->buf[0] = NULL;
-+ output->buf[1] = NULL;
-+ output->active_buf = 0;
-+ INIT_LIST_HEAD(&output->pending_bufs);
-+ INIT_LIST_HEAD(&output->ready_bufs);
-+}
-+
-+static void vin_buf_add_ready(struct vin_output *output,
-+ struct stfcamss_buffer *buffer)
-+{
-+ INIT_LIST_HEAD(&buffer->queue);
-+ list_add_tail(&buffer->queue, &output->ready_bufs);
-+}
-+
-+static struct stfcamss_buffer *vin_buf_get_ready(struct vin_output *output)
-+{
-+ struct stfcamss_buffer *buffer = NULL;
-+
-+ if (!list_empty(&output->ready_bufs)) {
-+ buffer = list_first_entry(&output->ready_bufs,
-+ struct stfcamss_buffer,
-+ queue);
-+ list_del(&buffer->queue);
-+ }
-+
-+ return buffer;
-+}
-+
-+static void vin_buf_add_pending(struct vin_output *output,
-+ struct stfcamss_buffer *buffer)
-+{
-+ INIT_LIST_HEAD(&buffer->queue);
-+ list_add_tail(&buffer->queue, &output->pending_bufs);
-+}
-+
-+static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output)
-+{
-+ struct stfcamss_buffer *buffer = NULL;
-+
-+ if (!list_empty(&output->pending_bufs)) {
-+ buffer = list_first_entry(&output->pending_bufs,
-+ struct stfcamss_buffer,
-+ queue);
-+ list_del(&buffer->queue);
-+ }
-+
-+ return buffer;
-+}
-+
-+static void vin_buf_update_on_last(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+
-+ switch (output->state) {
-+ case VIN_OUTPUT_CONTINUOUS:
-+ output->state = VIN_OUTPUT_SINGLE;
-+ output->active_buf = !output->active_buf;
-+ break;
-+ case VIN_OUTPUT_SINGLE:
-+ output->state = VIN_OUTPUT_STOPPING;
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static void vin_buf_update_on_next(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+
-+ switch (output->state) {
-+ case VIN_OUTPUT_CONTINUOUS:
-+ output->active_buf = !output->active_buf;
-+ break;
-+ case VIN_OUTPUT_SINGLE:
-+ default:
-+ break;
-+ }
-+}
-+
-+static void vin_buf_update_on_new(struct vin_line *line,
-+ struct vin_output *output,
-+ struct stfcamss_buffer *new_buf)
-+{
-+ switch (output->state) {
-+ case VIN_OUTPUT_SINGLE:
-+ vin_buf_add_pending(output, new_buf);
-+ break;
-+ case VIN_OUTPUT_IDLE:
-+ if (!output->buf[0]) {
-+ output->buf[0] = new_buf;
-+ vin_output_init_addrs(line);
-+ output->state = VIN_OUTPUT_SINGLE;
-+ } else {
-+ vin_buf_add_pending(output, new_buf);
-+ }
-+ break;
-+ case VIN_OUTPUT_STOPPING:
-+ if (output->last_buffer) {
-+ output->buf[output->active_buf] = output->last_buffer;
-+ output->last_buffer = NULL;
-+ }
-+
-+ output->state = VIN_OUTPUT_SINGLE;
-+ vin_buf_add_pending(output, new_buf);
-+ break;
-+ case VIN_OUTPUT_CONTINUOUS:
-+ default:
-+ vin_buf_add_pending(output, new_buf);
-+ break;
-+ }
-+}
-+
-+static void vin_buf_flush(struct vin_output *output,
-+ enum vb2_buffer_state state)
-+{
-+ struct stfcamss_buffer *buf;
-+ struct stfcamss_buffer *t;
-+
-+ list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
-+ vb2_buffer_done(&buf->vb.vb2_buf, state);
-+ list_del(&buf->queue);
-+ }
-+ list_for_each_entry_safe(buf, t, &output->ready_bufs, queue) {
-+ vb2_buffer_done(&buf->vb.vb2_buf, state);
-+ list_del(&buf->queue);
-+ }
-+}
-+
-+static void vin_buffer_done(struct vin_line *line)
-+{
-+ struct stfcamss_buffer *ready_buf;
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+ u64 ts = ktime_get_ns();
-+
-+ if (output->state == VIN_OUTPUT_OFF ||
-+ output->state == VIN_OUTPUT_RESERVED)
-+ return;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ while ((ready_buf = vin_buf_get_ready(output))) {
-+ ready_buf->vb.vb2_buf.timestamp = ts;
-+ ready_buf->vb.sequence = output->sequence++;
-+
-+ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-+ }
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+}
-+
-+static void vin_change_buffer(struct vin_line *line)
-+{
-+ struct stfcamss_buffer *ready_buf;
-+ struct vin_output *output = &line->output;
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ dma_addr_t *new_addr;
-+ unsigned long flags;
-+ u32 active_index;
-+
-+ if (output->state == VIN_OUTPUT_OFF ||
-+ output->state == VIN_OUTPUT_STOPPING ||
-+ output->state == VIN_OUTPUT_RESERVED ||
-+ output->state == VIN_OUTPUT_IDLE)
-+ return;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ active_index = output->active_buf;
-+
-+ ready_buf = output->buf[active_index];
-+ if (!ready_buf) {
-+ dev_warn(vin_dev->stfcamss->dev, "Missing ready buf %d %d!\n",
-+ active_index, output->state);
-+ active_index = !active_index;
-+ ready_buf = output->buf[active_index];
-+ if (!ready_buf) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Missing ready buf2 %d %d!\n",
-+ active_index, output->state);
-+ goto out_unlock;
-+ }
-+ }
-+
-+ /* Get next buffer */
-+ output->buf[active_index] = vin_buf_get_pending(output);
-+ if (!output->buf[active_index]) {
-+ /* No next buffer - set same address */
-+ new_addr = ready_buf->addr;
-+ vin_buf_update_on_last(line);
-+ } else {
-+ new_addr = output->buf[active_index]->addr;
-+ vin_buf_update_on_next(line);
-+ }
-+
-+ if (output->state == VIN_OUTPUT_STOPPING) {
-+ output->last_buffer = ready_buf;
-+ } else {
-+ switch (vin_map_isp_line(line->id)) {
-+ case STF_ISP_LINE_SRC:
-+ stf_vin_isp_set_yuv_addr(vin_dev,
-+ new_addr[0],
-+ new_addr[1]);
-+ break;
-+ default:
-+ if (line->id == VIN_LINE_WR) {
-+ stf_vin_wr_set_ping_addr(vin_dev, new_addr[0]);
-+ stf_vin_wr_set_pong_addr(vin_dev, new_addr[0]);
-+ }
-+ break;
-+ }
-+
-+ vin_buf_add_ready(output, ready_buf);
-+ }
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return;
-+
-+out_unlock:
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+}
-+
-+static int vin_queue_buffer(struct stfcamss_video *vid,
-+ struct stfcamss_buffer *buf)
-+{
-+ struct vin_line *line = container_of(vid, struct vin_line, video_out);
-+ struct vin_output *output;
-+ unsigned long flags;
-+
-+ output = &line->output;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ vin_buf_update_on_new(line, output, buf);
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+
-+ return 0;
-+}
-+
-+static int vin_flush_buffers(struct stfcamss_video *vid,
-+ enum vb2_buffer_state state)
-+{
-+ struct vin_line *line = container_of(vid, struct vin_line, video_out);
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ vin_buf_flush(output, state);
-+ if (output->buf[0])
-+ vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
-+
-+ if (output->buf[1])
-+ vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
-+
-+ if (output->last_buffer) {
-+ vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
-+ output->last_buffer = NULL;
-+ }
-+ output->buf[0] = NULL;
-+ output->buf[1] = NULL;
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return 0;
-+}
-+
-+static int vin_link_setup(struct media_entity *entity,
-+ const struct media_pad *local,
-+ const struct media_pad *remote, u32 flags)
-+{
-+ if (flags & MEDIA_LNK_FL_ENABLED)
-+ if (media_pad_remote_pad_first(local))
-+ return -EBUSY;
-+ return 0;
-+}
-+
-+static const struct v4l2_subdev_core_ops vin_core_ops = {
-+ .s_power = vin_set_power,
-+};
-+
-+static const struct v4l2_subdev_video_ops vin_video_ops = {
-+ .s_stream = vin_set_stream,
-+};
-+
-+static const struct v4l2_subdev_pad_ops vin_pad_ops = {
-+ .enum_mbus_code = vin_enum_mbus_code,
-+ .enum_frame_size = vin_enum_frame_size,
-+ .get_fmt = vin_get_format,
-+ .set_fmt = vin_set_format,
-+};
-+
-+static const struct v4l2_subdev_ops vin_v4l2_ops = {
-+ .core = &vin_core_ops,
-+ .video = &vin_video_ops,
-+ .pad = &vin_pad_ops,
-+};
-+
-+static const struct v4l2_subdev_internal_ops vin_v4l2_internal_ops = {
-+ .open = vin_init_formats,
-+};
-+
-+static const struct stfcamss_video_ops stfcamss_vin_video_ops = {
-+ .queue_buffer = vin_queue_buffer,
-+ .flush_buffers = vin_flush_buffers,
-+};
-+
-+static const struct media_entity_operations vin_media_ops = {
-+ .link_setup = vin_link_setup,
-+ .link_validate = v4l2_subdev_link_validate,
-+};
-+
-+int stf_vin_register(struct stf_vin_dev *vin_dev, struct v4l2_device *v4l2_dev)
-+{
-+ struct v4l2_subdev *sd;
-+ struct stfcamss_video *video_out;
-+ struct media_pad *pads;
-+ int ret;
-+ int i;
-+
-+ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
-+ char name[32];
-+ char *sub_name = vin_get_line_subdevname(i);
-+
-+ sd = &vin_dev->line[i].subdev;
-+ pads = vin_dev->line[i].pads;
-+ video_out = &vin_dev->line[i].video_out;
-+ video_out->id = i;
-+
-+ v4l2_subdev_init(sd, &vin_v4l2_ops);
-+ sd->internal_ops = &vin_v4l2_internal_ops;
-+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-+ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
-+ STF_VIN_NAME, 0, sub_name);
-+ v4l2_set_subdevdata(sd, &vin_dev->line[i]);
-+
-+ ret = vin_init_formats(sd, NULL);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to init format: %d\n", ret);
-+ goto err_init;
-+ }
-+
-+ pads[STF_VIN_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-+ pads[STF_VIN_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
-+
-+ sd->entity.function =
-+ MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
-+ sd->entity.ops = &vin_media_ops;
-+ ret = media_entity_pads_init(&sd->entity,
-+ STF_VIN_PADS_NUM, pads);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to init media entity: %d\n",
-+ ret);
-+ goto err_init;
-+ }
-+
-+ ret = v4l2_device_register_subdev(v4l2_dev, sd);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to register subdev: %d\n", ret);
-+ goto err_reg_subdev;
-+ }
-+
-+ video_out->ops = &stfcamss_vin_video_ops;
-+ video_out->bpl_alignment = 16 * 8;
-+
-+ snprintf(name, ARRAY_SIZE(name), "%s_%s%d",
-+ sd->name, "video", i);
-+ ret = stf_video_register(video_out, v4l2_dev, name);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to register video node: %d\n", ret);
-+ goto err_vid_reg;
-+ }
-+
-+ ret = media_create_pad_link(
-+ &sd->entity, STF_VIN_PAD_SRC,
-+ &video_out->vdev.entity, 0,
-+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to link %s->%s entities: %d\n",
-+ sd->entity.name, video_out->vdev.entity.name,
-+ ret);
-+ goto err_create_link;
-+ }
-+ }
-+
-+ return 0;
-+
-+err_create_link:
-+ stf_video_unregister(video_out);
-+err_vid_reg:
-+ v4l2_device_unregister_subdev(sd);
-+err_reg_subdev:
-+ media_entity_cleanup(&sd->entity);
-+err_init:
-+ for (i--; i >= 0; i--) {
-+ sd = &vin_dev->line[i].subdev;
-+ video_out = &vin_dev->line[i].video_out;
-+
-+ stf_video_unregister(video_out);
-+ v4l2_device_unregister_subdev(sd);
-+ media_entity_cleanup(&sd->entity);
-+ }
-+ return ret;
-+}
-+
-+int stf_vin_unregister(struct stf_vin_dev *vin_dev)
-+{
-+ struct v4l2_subdev *sd;
-+ struct stfcamss_video *video_out;
-+ int i;
-+
-+ mutex_destroy(&vin_dev->power_lock);
-+ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++)
-+ mutex_destroy(&vin_dev->dummy_buffer[i].stream_lock);
-+
-+ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
-+ sd = &vin_dev->line[i].subdev;
-+ video_out = &vin_dev->line[i].video_out;
-+
-+ stf_video_unregister(video_out);
-+ v4l2_device_unregister_subdev(sd);
-+ media_entity_cleanup(&sd->entity);
-+ mutex_destroy(&vin_dev->line[i].stream_lock);
-+ mutex_destroy(&vin_dev->line[i].power_lock);
-+ }
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_vin.h
-@@ -0,0 +1,180 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_vin.h
-+ *
-+ * StarFive Camera Subsystem - VIN Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_VIN_H
-+#define STF_VIN_H
-+
-+#include <linux/interrupt.h>
-+#include <linux/spinlock_types.h>
-+#include <media/v4l2-subdev.h>
-+
-+#include "stf_video.h"
-+
-+#define SYSCONSAIF_SYSCFG(x) (x)
-+
-+/* syscon offset 0 */
-+#define U0_VIN_CNFG_AXI_DVP_EN BIT(2)
-+
-+/* syscon offset 20 */
-+#define U0_VIN_CHANNEL_SEL_MASK GENMASK(3, 0)
-+#define U0_VIN_AXIWR0_EN BIT(4)
-+#define CHANNEL(x) ((x) << 0)
-+
-+/* syscon offset 32 */
-+#define U0_VIN_INTR_CLEAN BIT(0)
-+#define U0_VIN_INTR_M BIT(1)
-+#define U0_VIN_PIX_CNT_END_MASK GENMASK(12, 2)
-+#define U0_VIN_PIX_CT_MASK GENMASK(14, 13)
-+#define U0_VIN_PIXEL_HEIGH_BIT_SEL_MAKS GENMASK(16, 15)
-+
-+#define PIX_CNT_END(x) ((x) << 2)
-+#define PIX_CT(x) ((x) << 13)
-+#define PIXEL_HEIGH_BIT_SEL(x) ((x) << 15)
-+
-+/* syscon offset 36 */
-+#define U0_VIN_CNFG_DVP_HS_POS BIT(1)
-+#define U0_VIN_CNFG_DVP_SWAP_EN BIT(2)
-+#define U0_VIN_CNFG_DVP_VS_POS BIT(3)
-+#define U0_VIN_CNFG_GEN_EN_AXIRD BIT(4)
-+#define U0_VIN_CNFG_ISP_DVP_EN0 BIT(5)
-+#define U0_VIN_MIPI_BYTE_EN_ISP0(n) ((n) << 6)
-+#define U0_VIN_MIPI_CHANNEL_SEL0(n) ((n) << 8)
-+#define U0_VIN_P_I_MIPI_HAEDER_EN0(n) ((n) << 12)
-+#define U0_VIN_PIX_NUM(n) ((n) << 13)
-+#define U0_VIN_MIPI_BYTE_EN_ISP0_MASK GENMASK(7, 6)
-+#define U0_VIN_MIPI_CHANNEL_SEL0_MASK GENMASK(11, 8)
-+#define U0_VIN_P_I_MIPI_HAEDER_EN0_MASK BIT(12)
-+#define U0_VIN_PIX_NUM_MASK GENMASK(16, 13)
-+
-+#define STF_VIN_PAD_SINK 0
-+#define STF_VIN_PAD_SRC 1
-+#define STF_VIN_PADS_NUM 2
-+
-+#define ISP_DUMMY_BUFFER_NUMS STF_ISP_PAD_MAX
-+#define VIN_DUMMY_BUFFER_NUMS 1
-+
-+enum {
-+ STF_DUMMY_VIN,
-+ STF_DUMMY_ISP,
-+ STF_DUMMY_MODULE_NUMS,
-+};
-+
-+enum link {
-+ LINK_ERROR = -1,
-+ LINK_DVP_TO_WR,
-+ LINK_DVP_TO_ISP,
-+ LINK_CSI_TO_WR,
-+ LINK_CSI_TO_ISP,
-+};
-+
-+struct vin_format {
-+ u32 code;
-+ u8 bpp;
-+};
-+
-+struct vin_format_table {
-+ const struct vin_format *fmts;
-+ int nfmts;
-+};
-+
-+enum vin_output_state {
-+ VIN_OUTPUT_OFF,
-+ VIN_OUTPUT_RESERVED,
-+ VIN_OUTPUT_SINGLE,
-+ VIN_OUTPUT_CONTINUOUS,
-+ VIN_OUTPUT_IDLE,
-+ VIN_OUTPUT_STOPPING
-+};
-+
-+struct vin_output {
-+ int active_buf;
-+ struct stfcamss_buffer *buf[2];
-+ struct stfcamss_buffer *last_buffer;
-+ struct list_head pending_bufs;
-+ struct list_head ready_bufs;
-+ enum vin_output_state state;
-+ unsigned int sequence;
-+ unsigned int frame_skip;
-+};
-+
-+/* The vin output lines */
-+enum vin_line_id {
-+ VIN_LINE_NONE = -1,
-+ VIN_LINE_WR = 0,
-+ VIN_LINE_ISP,
-+ VIN_LINE_MAX,
-+};
-+
-+struct vin_line {
-+ enum stf_subdev_type sdev_type; /* must be frist */
-+ enum vin_line_id id;
-+ struct v4l2_subdev subdev;
-+ struct media_pad pads[STF_VIN_PADS_NUM];
-+ struct v4l2_mbus_framefmt fmt[STF_VIN_PADS_NUM];
-+ struct stfcamss_video video_out;
-+ struct mutex stream_lock; /* serialize stream control */
-+ int stream_count;
-+ struct mutex power_lock; /* serialize pipeline control in power process*/
-+ int power_count;
-+ struct vin_output output; /* pipeline and stream states */
-+ spinlock_t output_lock;
-+ const struct vin_format *formats;
-+ unsigned int nformats;
-+};
-+
-+struct vin_dummy_buffer {
-+ dma_addr_t paddr[3];
-+ void *vaddr;
-+ u32 buffer_size;
-+ u32 width;
-+ u32 height;
-+ u32 mcode;
-+};
-+
-+struct dummy_buffer {
-+ struct vin_dummy_buffer *buffer;
-+ u32 nums;
-+ struct mutex stream_lock; /* protects buffer data */
-+ int stream_count;
-+ atomic_t frame_skip;
-+};
-+
-+struct vin_isr_ops {
-+ void (*isr_buffer_done)(struct vin_line *line);
-+ void (*isr_change_buffer)(struct vin_line *line);
-+};
-+
-+struct stf_vin_dev {
-+ struct stfcamss *stfcamss;
-+ struct vin_line line[VIN_LINE_MAX];
-+ struct dummy_buffer dummy_buffer[STF_DUMMY_MODULE_NUMS];
-+ struct vin_isr_ops *isr_ops;
-+ atomic_t ref_count;
-+ struct mutex power_lock; /* serialize power control*/
-+ int power_count;
-+};
-+
-+int stf_vin_clk_enable(struct stf_vin_dev *vin_dev, enum link link);
-+int stf_vin_clk_disable(struct stf_vin_dev *vin_dev, enum link link);
-+int stf_vin_wr_stream_set(struct stf_vin_dev *vin_dev);
-+int stf_vin_stream_set(struct stf_vin_dev *vin_dev, enum link link);
-+void stf_vin_wr_irq_enable(struct stf_vin_dev *vin_dev, int enable);
-+void stf_vin_wr_set_ping_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr);
-+void stf_vin_wr_set_pong_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr);
-+void stf_vin_isp_set_yuv_addr(struct stf_vin_dev *vin_dev,
-+ dma_addr_t y_addr, dma_addr_t uv_addr);
-+irqreturn_t stf_vin_wr_irq_handler(int irq, void *priv);
-+irqreturn_t stf_vin_isp_irq_handler(int irq, void *priv);
-+irqreturn_t stf_vin_isp_irq_csiline_handler(int irq, void *priv);
-+int stf_vin_subdev_init(struct stfcamss *stfcamss);
-+int stf_vin_register(struct stf_vin_dev *vin_dev, struct v4l2_device *v4l2_dev);
-+int stf_vin_unregister(struct stf_vin_dev *vin_dev);
-+enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line, enum isp_pad_id def);
-+
-+#endif /* STF_VIN_H */
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_vin_hw_ops.c
-@@ -0,0 +1,241 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_vin_hw_ops.c
-+ *
-+ * Register interface file for StarFive VIN module driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include "stf_camss.h"
-+
-+static void vin_intr_clear(struct stfcamss *stfcamss)
-+{
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+ stf_syscon_reg_clear_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+}
-+
-+irqreturn_t stf_vin_wr_irq_handler(int irq, void *priv)
-+{
-+ struct stf_vin_dev *vin_dev = priv;
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[STF_DUMMY_VIN];
-+
-+ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
-+ vin_dev->isr_ops->isr_change_buffer(&vin_dev->line[VIN_LINE_WR]);
-+ vin_dev->isr_ops->isr_buffer_done(&vin_dev->line[VIN_LINE_WR]);
-+ }
-+
-+ vin_intr_clear(stfcamss);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+irqreturn_t stf_vin_isp_irq_handler(int irq, void *priv)
-+{
-+ struct stf_vin_dev *vin_dev = priv;
-+ u32 int_status;
-+
-+ int_status = stf_isp_reg_read(vin_dev->stfcamss, ISP_REG_ISP_CTRL_0);
-+
-+ if (int_status & ISPC_INTS) {
-+ if ((int_status & ISPC_ENUO))
-+ vin_dev->isr_ops->isr_buffer_done(
-+ &vin_dev->line[VIN_LINE_ISP]);
-+
-+ /* clear interrupt */
-+ stf_isp_reg_write(vin_dev->stfcamss,
-+ ISP_REG_ISP_CTRL_0,
-+ (int_status & ~EN_INT_ALL) |
-+ EN_INT_ISP_DONE |
-+ EN_INT_CSI_DONE |
-+ EN_INT_SC_DONE);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+irqreturn_t stf_vin_isp_irq_csiline_handler(int irq, void *priv)
-+{
-+ struct stf_vin_dev *vin_dev = priv;
-+ struct stf_isp_dev *isp_dev;
-+ u32 int_status;
-+
-+ isp_dev = &vin_dev->stfcamss->isp_dev;
-+
-+ int_status = stf_isp_reg_read(vin_dev->stfcamss, ISP_REG_ISP_CTRL_0);
-+ if (int_status & ISPC_SCFEINT) {
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[STF_DUMMY_ISP];
-+
-+ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
-+ if ((int_status & ISPC_ENUO))
-+ vin_dev->isr_ops->isr_change_buffer(
-+ &vin_dev->line[VIN_LINE_ISP]);
-+ }
-+
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_CSIINTS,
-+ CSI_INTS_MASK, CSI_INTS(0x3));
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_IESHD,
-+ SHAD_UP_M | SHAD_UP_EN, 0x3);
-+
-+ /* clear interrupt */
-+ stf_isp_reg_write(vin_dev->stfcamss, ISP_REG_ISP_CTRL_0,
-+ (int_status & ~EN_INT_ALL) | EN_INT_LINE_INT);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+int stf_vin_clk_enable(struct stf_vin_dev *vin_dev, enum link link)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ clk_set_rate(stfcamss->sys_clk[STF_CLK_APB_FUNC].clk, 49500000);
-+
-+ switch (link) {
-+ case LINK_CSI_TO_WR:
-+ clk_set_rate(stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk,
-+ 198000000);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_AXIWR].rstc);
-+ clk_set_parent(stfcamss->sys_clk[STF_CLK_AXIWR].clk,
-+ stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk);
-+ break;
-+ case LINK_CSI_TO_ISP:
-+ clk_set_rate(stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk,
-+ 198000000);
-+ clk_set_parent(stfcamss->sys_clk[STF_CLK_WRAPPER_CLK_C].clk,
-+ stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk);
-+ break;
-+ case LINK_DVP_TO_WR:
-+ case LINK_DVP_TO_ISP:
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+int stf_vin_clk_disable(struct stf_vin_dev *vin_dev, enum link link)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ switch (link) {
-+ case LINK_CSI_TO_WR:
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_AXIWR].rstc);
-+ break;
-+ case LINK_CSI_TO_ISP:
-+ break;
-+ case LINK_DVP_TO_WR:
-+ case LINK_DVP_TO_ISP:
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+int stf_vin_wr_stream_set(struct stf_vin_dev *vin_dev)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ /* make the axiwr alway on */
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(20),
-+ U0_VIN_AXIWR0_EN);
-+
-+ return 0;
-+}
-+
-+int stf_vin_stream_set(struct stf_vin_dev *vin_dev, enum link link)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+ u32 val;
-+
-+ switch (link) {
-+ case LINK_CSI_TO_WR:
-+ val = stf_syscon_reg_read(stfcamss, SYSCONSAIF_SYSCFG(20));
-+ val &= ~U0_VIN_CHANNEL_SEL_MASK;
-+ val |= CHANNEL(0);
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(20), val);
-+
-+ val = stf_syscon_reg_read(stfcamss, SYSCONSAIF_SYSCFG(28));
-+ val &= ~U0_VIN_PIX_CT_MASK;
-+ val |= PIX_CT(1);
-+
-+ val &= ~U0_VIN_PIXEL_HEIGH_BIT_SEL_MAKS;
-+ val |= PIXEL_HEIGH_BIT_SEL(0);
-+
-+ val &= ~U0_VIN_PIX_CNT_END_MASK;
-+ val |= PIX_CNT_END(IMAGE_MAX_WIDTH / 4 - 1);
-+
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(28), val);
-+ break;
-+ case LINK_CSI_TO_ISP:
-+ val = stf_syscon_reg_read(stfcamss, SYSCONSAIF_SYSCFG(36));
-+ val &= ~U0_VIN_MIPI_BYTE_EN_ISP0_MASK;
-+ val |= U0_VIN_MIPI_BYTE_EN_ISP0(0);
-+
-+ val &= ~U0_VIN_MIPI_CHANNEL_SEL0_MASK;
-+ val |= U0_VIN_MIPI_CHANNEL_SEL0(0);
-+
-+ val &= ~U0_VIN_PIX_NUM_MASK;
-+ val |= U0_VIN_PIX_NUM(0);
-+
-+ val &= ~U0_VIN_P_I_MIPI_HAEDER_EN0_MASK;
-+ val |= U0_VIN_P_I_MIPI_HAEDER_EN0(1);
-+
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(36), val);
-+ break;
-+ case LINK_DVP_TO_WR:
-+ case LINK_DVP_TO_ISP:
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+void stf_vin_wr_irq_enable(struct stf_vin_dev *vin_dev, int enable)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ if (enable) {
-+ stf_syscon_reg_clear_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_M);
-+ } else {
-+ /* clear vin interrupt */
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+ stf_syscon_reg_clear_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_M);
-+ }
-+}
-+
-+void stf_vin_wr_set_ping_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ /* set the start address */
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(32), (long)addr);
-+}
-+
-+void stf_vin_wr_set_pong_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ /* set the start address */
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(24), (long)addr);
-+}
-+
-+void stf_vin_isp_set_yuv_addr(struct stf_vin_dev *vin_dev,
-+ dma_addr_t y_addr, dma_addr_t uv_addr)
-+{
-+ stf_isp_reg_write(vin_dev->stfcamss,
-+ ISP_REG_Y_PLANE_START_ADDR, y_addr);
-+ stf_isp_reg_write(vin_dev->stfcamss,
-+ ISP_REG_UV_PLANE_START_ADDR, uv_addr);
-+}
diff --git a/target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch b/target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch
deleted file mode 100644
index 08eee9ca9e..0000000000
--- a/target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 2ebd77fa8fb95f60b275cefb98ea7d6f4df06e55 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:44 +0800
-Subject: [PATCH 087/122] dt-bindings: phy: Add StarFive JH7110 USB PHY
-
-Add StarFive JH7110 SoC USB 2.0 PHY dt-binding.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- .../bindings/phy/starfive,jh7110-usb-phy.yaml | 50 +++++++++++++++++++
- 1 file changed, 50 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
-@@ -0,0 +1,50 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/phy/starfive,jh7110-usb-phy.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 USB 2.0 PHY
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-usb-phy
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#phy-cells":
-+ const: 0
-+
-+ clocks:
-+ items:
-+ - description: PHY 125m
-+ - description: app 125m
-+
-+ clock-names:
-+ items:
-+ - const: 125m
-+ - const: app_125m
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - "#phy-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ phy@10200000 {
-+ compatible = "starfive,jh7110-usb-phy";
-+ reg = <0x10200000 0x10000>;
-+ clocks = <&syscrg 95>,
-+ <&stgcrg 6>;
-+ clock-names = "125m", "app_125m";
-+ #phy-cells = <0>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch b/target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch
deleted file mode 100644
index 6911bba9d2..0000000000
--- a/target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From d57245d420a2ced6a588cc6e03e2eaacbbf1bfb2 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:45 +0800
-Subject: [PATCH 088/122] dt-bindings: phy: Add StarFive JH7110 PCIe PHY
-
-Add StarFive JH7110 SoC PCIe 2.0 PHY dt-binding.
-PCIe PHY0 (phy@10210000) can be used as USB 3.0 PHY.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- .../phy/starfive,jh7110-pcie-phy.yaml | 58 +++++++++++++++++++
- 1 file changed, 58 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
-@@ -0,0 +1,58 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/phy/starfive,jh7110-pcie-phy.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 PCIe 2.0 PHY
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pcie-phy
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#phy-cells":
-+ const: 0
-+
-+ starfive,sys-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller sys_syscon node.
-+ - description: PHY connect offset of SYS_SYSCONSAIF__SYSCFG register for USB PHY.
-+ description:
-+ The phandle to System Register Controller syscon node and the PHY connect offset
-+ of SYS_SYSCONSAIF__SYSCFG register. Connect PHY to USB3 controller.
-+
-+ starfive,stg-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller stg_syscon node.
-+ - description: PHY mode offset of STG_SYSCONSAIF__SYSCFG register.
-+ - description: PHY enable for USB offset of STG_SYSCONSAIF__SYSCFG register.
-+ description:
-+ The phandle to System Register Controller syscon node and the offset
-+ of STG_SYSCONSAIF__SYSCFG register for PCIe PHY. Total 2 regsisters offset.
-+
-+required:
-+ - compatible
-+ - reg
-+ - "#phy-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ phy@10210000 {
-+ compatible = "starfive,jh7110-pcie-phy";
-+ reg = <0x10210000 0x10000>;
-+ #phy-cells = <0>;
-+ starfive,sys-syscon = <&sys_syscon 0x18>;
-+ starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch b/target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch
deleted file mode 100644
index 0b608868c1..0000000000
--- a/target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From 3d74980ca3ba91dae6e84fbc23750e702e71d41a Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:46 +0800
-Subject: [PATCH 089/122] phy: starfive: Add JH7110 USB 2.0 PHY driver
-
-Add Starfive JH7110 SoC USB 2.0 PHY driver support.
-USB 2.0 PHY default connect to Cadence USB controller.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- drivers/phy/starfive/Kconfig | 11 ++
- drivers/phy/starfive/Makefile | 1 +
- drivers/phy/starfive/phy-jh7110-usb.c | 150 ++++++++++++++++++++++++++
- 3 files changed, 162 insertions(+)
- create mode 100644 drivers/phy/starfive/phy-jh7110-usb.c
-
---- a/drivers/phy/starfive/Kconfig
-+++ b/drivers/phy/starfive/Kconfig
-@@ -11,3 +11,14 @@ config PHY_STARFIVE_DPHY_RX
- Choose this option if you have a StarFive D-PHY in your
- system. If M is selected, the module will be called
- phy-starfive-dphy-rx.
-+
-+config PHY_STARFIVE_JH7110_USB
-+ tristate "Starfive JH7110 USB 2.0 PHY support"
-+ depends on USB_SUPPORT
-+ select GENERIC_PHY
-+ select USB_PHY
-+ help
-+ Enable this to support the StarFive USB 2.0 PHY,
-+ used with the Cadence USB controller.
-+ If M is selected, the module will be called
-+ phy-jh7110-usb.ko.
---- a/drivers/phy/starfive/Makefile
-+++ b/drivers/phy/starfive/Makefile
-@@ -1,2 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_PHY_STARFIVE_DPHY_RX) += phy-starfive-dphy-rx.o
-+obj-$(CONFIG_PHY_STARFIVE_JH7110_USB) += phy-jh7110-usb.o
---- /dev/null
-+++ b/drivers/phy/starfive/phy-jh7110-usb.c
-@@ -0,0 +1,150 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * StarFive JH7110 USB 2.0 PHY driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ * Author: Minda Chen <minda.chen@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/phy/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/usb/of.h>
-+
-+#define USB_125M_CLK_RATE 125000000
-+#define USB_LS_KEEPALIVE_OFF 0x4
-+#define USB_LS_KEEPALIVE_ENABLE BIT(4)
-+
-+struct jh7110_usb2_phy {
-+ struct phy *phy;
-+ void __iomem *regs;
-+ struct clk *usb_125m_clk;
-+ struct clk *app_125m;
-+ enum phy_mode mode;
-+};
-+
-+static void jh7110_usb2_mode_set(struct jh7110_usb2_phy *phy)
-+{
-+ unsigned int val;
-+
-+ if (phy->mode != PHY_MODE_USB_HOST) {
-+ /* Enable the LS speed keep-alive signal */
-+ val = readl(phy->regs + USB_LS_KEEPALIVE_OFF);
-+ val |= USB_LS_KEEPALIVE_ENABLE;
-+ writel(val, phy->regs + USB_LS_KEEPALIVE_OFF);
-+ }
-+}
-+
-+static int jh7110_usb2_phy_set_mode(struct phy *_phy,
-+ enum phy_mode mode, int submode)
-+{
-+ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
-+
-+ switch (mode) {
-+ case PHY_MODE_USB_HOST:
-+ case PHY_MODE_USB_DEVICE:
-+ case PHY_MODE_USB_OTG:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (mode != phy->mode) {
-+ dev_dbg(&_phy->dev, "Changing phy to %d\n", mode);
-+ phy->mode = mode;
-+ jh7110_usb2_mode_set(phy);
-+ }
-+
-+ return 0;
-+}
-+
-+static int jh7110_usb2_phy_init(struct phy *_phy)
-+{
-+ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
-+ int ret;
-+
-+ ret = clk_set_rate(phy->usb_125m_clk, USB_125M_CLK_RATE);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_prepare_enable(phy->app_125m);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int jh7110_usb2_phy_exit(struct phy *_phy)
-+{
-+ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
-+
-+ clk_disable_unprepare(phy->app_125m);
-+
-+ return 0;
-+}
-+
-+static const struct phy_ops jh7110_usb2_phy_ops = {
-+ .init = jh7110_usb2_phy_init,
-+ .exit = jh7110_usb2_phy_exit,
-+ .set_mode = jh7110_usb2_phy_set_mode,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int jh7110_usb_phy_probe(struct platform_device *pdev)
-+{
-+ struct jh7110_usb2_phy *phy;
-+ struct device *dev = &pdev->dev;
-+ struct phy_provider *phy_provider;
-+
-+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
-+ if (!phy)
-+ return -ENOMEM;
-+
-+ phy->usb_125m_clk = devm_clk_get(dev, "125m");
-+ if (IS_ERR(phy->usb_125m_clk))
-+ return dev_err_probe(dev, PTR_ERR(phy->usb_125m_clk),
-+ "Failed to get 125m clock\n");
-+
-+ phy->app_125m = devm_clk_get(dev, "app_125m");
-+ if (IS_ERR(phy->app_125m))
-+ return dev_err_probe(dev, PTR_ERR(phy->app_125m),
-+ "Failed to get app 125m clock\n");
-+
-+ phy->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(phy->regs))
-+ return dev_err_probe(dev, PTR_ERR(phy->regs),
-+ "Failed to map phy base\n");
-+
-+ phy->phy = devm_phy_create(dev, NULL, &jh7110_usb2_phy_ops);
-+ if (IS_ERR(phy->phy))
-+ return dev_err_probe(dev, PTR_ERR(phy->phy),
-+ "Failed to create phy\n");
-+
-+ phy_set_drvdata(phy->phy, phy);
-+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct of_device_id jh7110_usb_phy_of_match[] = {
-+ { .compatible = "starfive,jh7110-usb-phy" },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_usb_phy_of_match);
-+
-+static struct platform_driver jh7110_usb_phy_driver = {
-+ .probe = jh7110_usb_phy_probe,
-+ .driver = {
-+ .of_match_table = jh7110_usb_phy_of_match,
-+ .name = "jh7110-usb-phy",
-+ }
-+};
-+module_platform_driver(jh7110_usb_phy_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 USB 2.0 PHY driver");
-+MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch b/target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch
deleted file mode 100644
index 452ffd25c6..0000000000
--- a/target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-From d900724fdae7c41a663b31e1ed9b8ba10b998e6f Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:47 +0800
-Subject: [PATCH 090/122] phy: starfive: Add JH7110 PCIE 2.0 PHY driver
-
-Add Starfive JH7110 SoC PCIe 2.0 PHY driver support.
-PCIe 2.0 PHY default connect to PCIe controller.
-PCIe PHY can connect to USB 3.0 controller.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- drivers/phy/starfive/Kconfig | 10 ++
- drivers/phy/starfive/Makefile | 1 +
- drivers/phy/starfive/phy-jh7110-pcie.c | 204 +++++++++++++++++++++++++
- 3 files changed, 215 insertions(+)
- create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c
-
---- a/drivers/phy/starfive/Kconfig
-+++ b/drivers/phy/starfive/Kconfig
-@@ -12,6 +12,16 @@ config PHY_STARFIVE_DPHY_RX
- system. If M is selected, the module will be called
- phy-starfive-dphy-rx.
-
-+config PHY_STARFIVE_JH7110_PCIE
-+ tristate "Starfive JH7110 PCIE 2.0/USB 3.0 PHY support"
-+ select GENERIC_PHY
-+ select USB_PHY
-+ help
-+ Enable this to support the StarFive PCIe 2.0 PHY,
-+ or used as USB 3.0 PHY.
-+ If M is selected, the module will be called
-+ phy-jh7110-pcie.ko.
-+
- config PHY_STARFIVE_JH7110_USB
- tristate "Starfive JH7110 USB 2.0 PHY support"
- depends on USB_SUPPORT
---- a/drivers/phy/starfive/Makefile
-+++ b/drivers/phy/starfive/Makefile
-@@ -1,3 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_PHY_STARFIVE_DPHY_RX) += phy-starfive-dphy-rx.o
-+obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o
- obj-$(CONFIG_PHY_STARFIVE_JH7110_USB) += phy-jh7110-usb.o
---- /dev/null
-+++ b/drivers/phy/starfive/phy-jh7110-pcie.c
-@@ -0,0 +1,204 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * StarFive JH7110 PCIe 2.0 PHY driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ * Author: Minda Chen <minda.chen@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/phy/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+#define PCIE_KVCO_LEVEL_OFF 0x28
-+#define PCIE_USB3_PHY_PLL_CTL_OFF 0x7c
-+#define PCIE_KVCO_TUNE_SIGNAL_OFF 0x80
-+#define PCIE_USB3_PHY_ENABLE BIT(4)
-+#define PHY_KVCO_FINE_TUNE_LEVEL 0x91
-+#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc
-+
-+#define USB_PDRSTN_SPLIT BIT(17)
-+
-+#define PCIE_PHY_MODE BIT(20)
-+#define PCIE_PHY_MODE_MASK GENMASK(21, 20)
-+#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2)
-+#define PCIE_USB3_BUS_WIDTH BIT(3)
-+#define PCIE_USB3_RATE_MASK GENMASK(6, 5)
-+#define PCIE_USB3_RX_STANDBY_MASK BIT(7)
-+#define PCIE_USB3_PHY_ENABLE BIT(4)
-+
-+struct jh7110_pcie_phy {
-+ struct phy *phy;
-+ struct regmap *stg_syscon;
-+ struct regmap *sys_syscon;
-+ void __iomem *regs;
-+ u32 sys_phy_connect;
-+ u32 stg_pcie_mode;
-+ u32 stg_pcie_usb;
-+ enum phy_mode mode;
-+};
-+
-+static int phy_usb3_mode_set(struct jh7110_pcie_phy *data)
-+{
-+ if (!data->stg_syscon || !data->sys_syscon) {
-+ dev_err(&data->phy->dev, "doesn't support usb3 mode\n");
-+ return -EINVAL;
-+ }
-+
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
-+ PCIE_PHY_MODE_MASK, PCIE_PHY_MODE);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_BUS_WIDTH_MASK, 0);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_PHY_ENABLE, PCIE_USB3_PHY_ENABLE);
-+
-+ /* Connect usb 3.0 phy mode */
-+ regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
-+ USB_PDRSTN_SPLIT, 0);
-+
-+ /* Configuare spread-spectrum mode: down-spread-spectrum */
-+ writel(PCIE_USB3_PHY_ENABLE, data->regs + PCIE_USB3_PHY_PLL_CTL_OFF);
-+
-+ return 0;
-+}
-+
-+static void phy_pcie_mode_set(struct jh7110_pcie_phy *data)
-+{
-+ u32 val;
-+
-+ /* default is PCIe mode */
-+ if (!data->stg_syscon || !data->sys_syscon)
-+ return;
-+
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
-+ PCIE_PHY_MODE_MASK, 0);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_BUS_WIDTH_MASK,
-+ PCIE_USB3_BUS_WIDTH);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_PHY_ENABLE, 0);
-+
-+ regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
-+ USB_PDRSTN_SPLIT, 0);
-+
-+ val = readl(data->regs + PCIE_USB3_PHY_PLL_CTL_OFF);
-+ val &= ~PCIE_USB3_PHY_ENABLE;
-+ writel(val, data->regs + PCIE_USB3_PHY_PLL_CTL_OFF);
-+}
-+
-+static void phy_kvco_gain_set(struct jh7110_pcie_phy *phy)
-+{
-+ /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */
-+ writel(PHY_KVCO_FINE_TUNE_LEVEL, phy->regs + PCIE_KVCO_LEVEL_OFF);
-+ writel(PHY_KVCO_FINE_TUNE_SIGNALS, phy->regs + PCIE_KVCO_TUNE_SIGNAL_OFF);
-+}
-+
-+static int jh7110_pcie_phy_set_mode(struct phy *_phy,
-+ enum phy_mode mode, int submode)
-+{
-+ struct jh7110_pcie_phy *phy = phy_get_drvdata(_phy);
-+ int ret;
-+
-+ if (mode == phy->mode)
-+ return 0;
-+
-+ switch (mode) {
-+ case PHY_MODE_USB_HOST:
-+ case PHY_MODE_USB_DEVICE:
-+ case PHY_MODE_USB_OTG:
-+ ret = phy_usb3_mode_set(phy);
-+ if (ret)
-+ return ret;
-+ break;
-+ case PHY_MODE_PCIE:
-+ phy_pcie_mode_set(phy);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ dev_dbg(&_phy->dev, "Changing phy mode to %d\n", mode);
-+ phy->mode = mode;
-+
-+ return 0;
-+}
-+
-+static const struct phy_ops jh7110_pcie_phy_ops = {
-+ .set_mode = jh7110_pcie_phy_set_mode,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int jh7110_pcie_phy_probe(struct platform_device *pdev)
-+{
-+ struct jh7110_pcie_phy *phy;
-+ struct device *dev = &pdev->dev;
-+ struct phy_provider *phy_provider;
-+ u32 args[2];
-+
-+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
-+ if (!phy)
-+ return -ENOMEM;
-+
-+ phy->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(phy->regs))
-+ return PTR_ERR(phy->regs);
-+
-+ phy->phy = devm_phy_create(dev, NULL, &jh7110_pcie_phy_ops);
-+ if (IS_ERR(phy->phy))
-+ return dev_err_probe(dev, PTR_ERR(phy->regs),
-+ "Failed to map phy base\n");
-+
-+ phy->sys_syscon =
-+ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,sys-syscon",
-+ 1, args);
-+
-+ if (!IS_ERR_OR_NULL(phy->sys_syscon))
-+ phy->sys_phy_connect = args[0];
-+ else
-+ phy->sys_syscon = NULL;
-+
-+ phy->stg_syscon =
-+ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,stg-syscon",
-+ 2, args);
-+
-+ if (!IS_ERR_OR_NULL(phy->stg_syscon)) {
-+ phy->stg_pcie_mode = args[0];
-+ phy->stg_pcie_usb = args[1];
-+ } else {
-+ phy->stg_syscon = NULL;
-+ }
-+
-+ phy_kvco_gain_set(phy);
-+
-+ phy_set_drvdata(phy->phy, phy);
-+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct of_device_id jh7110_pcie_phy_of_match[] = {
-+ { .compatible = "starfive,jh7110-pcie-phy" },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_pcie_phy_of_match);
-+
-+static struct platform_driver jh7110_pcie_phy_driver = {
-+ .probe = jh7110_pcie_phy_probe,
-+ .driver = {
-+ .of_match_table = jh7110_pcie_phy_of_match,
-+ .name = "jh7110-pcie-phy",
-+ }
-+};
-+module_platform_driver(jh7110_pcie_phy_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 PCIe 2.0 PHY driver");
-+MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch b/target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch
deleted file mode 100644
index 8a7575094c..0000000000
--- a/target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 6a2392c96041d0599d33799a9aedbcdbfb4030b6 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:48 +0800
-Subject: [PATCH 091/122] dt-bindings: usb: Add StarFive JH7110 USB controller
-
-StarFive JH7110 platforms USB have a wrapper module around
-the Cadence USBSS-DRD controller. Add binding information doc
-for that.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Reviewed-by: Peter Chen <peter.chen@kernel.org>
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
----
- .../bindings/usb/starfive,jh7110-usb.yaml | 115 ++++++++++++++++++
- 1 file changed, 115 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
-@@ -0,0 +1,115 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/usb/starfive,jh7110-usb.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 wrapper module for the Cadence USBSS-DRD controller
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-usb
-+
-+ ranges: true
-+
-+ starfive,stg-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller stg_syscon node.
-+ - description: dr mode register offset of STG_SYSCONSAIF__SYSCFG register for USB.
-+ description:
-+ The phandle to System Register Controller syscon node and the offset
-+ of STG_SYSCONSAIF__SYSCFG register for USB.
-+
-+ dr_mode:
-+ enum: [host, otg, peripheral]
-+
-+ "#address-cells":
-+ enum: [1, 2]
-+
-+ "#size-cells":
-+ enum: [1, 2]
-+
-+ clocks:
-+ items:
-+ - description: link power management clock
-+ - description: standby clock
-+ - description: APB clock
-+ - description: AXI clock
-+ - description: UTMI APB clock
-+
-+ clock-names:
-+ items:
-+ - const: lpm
-+ - const: stb
-+ - const: apb
-+ - const: axi
-+ - const: utmi_apb
-+
-+ resets:
-+ items:
-+ - description: Power up reset
-+ - description: APB clock reset
-+ - description: AXI clock reset
-+ - description: UTMI APB clock reset
-+
-+ reset-names:
-+ items:
-+ - const: pwrup
-+ - const: apb
-+ - const: axi
-+ - const: utmi_apb
-+
-+patternProperties:
-+ "^usb@[0-9a-f]+$":
-+ $ref: cdns,usb3.yaml#
-+ description: Required child node
-+
-+required:
-+ - compatible
-+ - ranges
-+ - starfive,stg-syscon
-+ - '#address-cells'
-+ - '#size-cells'
-+ - dr_mode
-+ - clocks
-+ - resets
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ usb@10100000 {
-+ compatible = "starfive,jh7110-usb";
-+ ranges = <0x0 0x10100000 0x100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ starfive,stg-syscon = <&stg_syscon 0x4>;
-+ clocks = <&syscrg 4>,
-+ <&stgcrg 5>,
-+ <&stgcrg 1>,
-+ <&stgcrg 3>,
-+ <&stgcrg 2>;
-+ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
-+ resets = <&stgcrg 10>,
-+ <&stgcrg 8>,
-+ <&stgcrg 7>,
-+ <&stgcrg 9>;
-+ reset-names = "pwrup", "apb", "axi", "utmi_apb";
-+ dr_mode = "host";
-+
-+ usb@0 {
-+ compatible = "cdns,usb3";
-+ reg = <0x0 0x10000>,
-+ <0x10000 0x10000>,
-+ <0x20000 0x10000>;
-+ reg-names = "otg", "xhci", "dev";
-+ interrupts = <100>, <108>, <110>;
-+ interrupt-names = "host", "peripheral", "otg";
-+ maximum-speed = "super-speed";
-+ };
-+ };
diff --git a/target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch b/target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch
deleted file mode 100644
index 650545cf3c..0000000000
--- a/target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 464fa29e8f3fb2c209647efbb365470b35daec38 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 2 Mar 2023 18:52:20 +0800
-Subject: [PATCH 092/122] dt-bindings: qspi: cdns,qspi-nor: constrain
- minItems/maxItems of resets
-
-The QSPI controller needs three reset items to work properly on JH7110 SoC,
-so there is need to change the maxItems's value to 3 and add minItems
-whose value is equal to 2. Other platforms do not have this constraint.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- .../bindings/spi/cdns,qspi-nor.yaml | 37 +++++++++++++++++--
- 1 file changed, 33 insertions(+), 4 deletions(-)
-
---- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
-+++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
-@@ -19,6 +19,33 @@ allOf:
- then:
- required:
- - power-domains
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ const: starfive,jh7110-qspi
-+ then:
-+ properties:
-+ resets:
-+ minItems: 2
-+ maxItems: 3
-+
-+ reset-names:
-+ minItems: 2
-+ maxItems: 3
-+ items:
-+ enum: [ qspi, qspi-ocp, rstc_ref ]
-+
-+ else:
-+ properties:
-+ resets:
-+ maxItems: 2
-+
-+ reset-names:
-+ minItems: 1
-+ maxItems: 2
-+ items:
-+ enum: [ qspi, qspi-ocp ]
-
- properties:
- compatible:
-@@ -30,6 +57,7 @@ properties:
- - intel,lgm-qspi
- - xlnx,versal-ospi-1.0
- - intel,socfpga-qspi
-+ - starfive,jh7110-qspi
- - const: cdns,qspi-nor
- - const: cdns,qspi-nor
-
-@@ -79,13 +107,14 @@ properties:
- maxItems: 1
-
- resets:
-- maxItems: 2
-+ minItems: 2
-+ maxItems: 3
-
- reset-names:
-- minItems: 1
-- maxItems: 2
-+ minItems: 2
-+ maxItems: 3
- items:
-- enum: [ qspi, qspi-ocp ]
-+ enum: [ qspi, qspi-ocp, rstc_ref ]
-
- required:
- - compatible
diff --git a/target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch b/target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch
deleted file mode 100644
index 2431dc45dd..0000000000
--- a/target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch
+++ /dev/null
@@ -1,298 +0,0 @@
-From 27c75f360a76084ee6a249876483cfa8d0bedd65 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:49 +0800
-Subject: [PATCH 093/122] usb: cdns3: Add StarFive JH7110 USB driver
-
-Adds Specific Glue layer to support USB peripherals on
-StarFive JH7110 SoC.
-There is a Cadence USB3 core for JH7110 SoCs, the cdns
-core is the child of this USB wrapper module device.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Acked-by: Peter Chen <peter.chen@kernel.org>
----
- drivers/usb/cdns3/Kconfig | 11 ++
- drivers/usb/cdns3/Makefile | 1 +
- drivers/usb/cdns3/cdns3-starfive.c | 246 +++++++++++++++++++++++++++++
- 3 files changed, 258 insertions(+)
- create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
-
---- a/drivers/usb/cdns3/Kconfig
-+++ b/drivers/usb/cdns3/Kconfig
-@@ -78,6 +78,17 @@ config USB_CDNS3_IMX
-
- For example, imx8qm and imx8qxp.
-
-+config USB_CDNS3_STARFIVE
-+ tristate "Cadence USB3 support on StarFive SoC platforms"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ help
-+ Say 'Y' or 'M' here if you are building for StarFive SoCs
-+ platforms that contain Cadence USB3 controller core.
-+
-+ e.g. JH7110.
-+
-+ If you choose to build this driver as module it will
-+ be dynamically linked and module will be called cdns3-starfive.ko
- endif
-
- if USB_CDNS_SUPPORT
---- a/drivers/usb/cdns3/Makefile
-+++ b/drivers/usb/cdns3/Makefile
-@@ -24,6 +24,7 @@ endif
- obj-$(CONFIG_USB_CDNS3_PCI_WRAP) += cdns3-pci-wrap.o
- obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o
- obj-$(CONFIG_USB_CDNS3_IMX) += cdns3-imx.o
-+obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o
-
- cdnsp-udc-pci-y := cdnsp-pci.o
-
---- /dev/null
-+++ b/drivers/usb/cdns3/cdns3-starfive.c
-@@ -0,0 +1,246 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/**
-+ * cdns3-starfive.c - StarFive specific Glue layer for Cadence USB Controller
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Minda Chen <minda.chen@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/module.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/kernel.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/of_platform.h>
-+#include <linux/reset.h>
-+#include <linux/regmap.h>
-+#include <linux/usb/otg.h>
-+#include "core.h"
-+
-+#define USB_STRAP_HOST BIT(17)
-+#define USB_STRAP_DEVICE BIT(18)
-+#define USB_STRAP_MASK GENMASK(18, 16)
-+
-+#define USB_SUSPENDM_HOST BIT(19)
-+#define USB_SUSPENDM_MASK BIT(19)
-+
-+#define USB_MISC_CFG_MASK GENMASK(23, 20)
-+#define USB_SUSPENDM_BYPS BIT(20)
-+#define USB_PLL_EN BIT(22)
-+#define USB_REFCLK_MODE BIT(23)
-+
-+struct cdns_starfive {
-+ struct device *dev;
-+ struct regmap *stg_syscon;
-+ struct reset_control *resets;
-+ struct clk_bulk_data *clks;
-+ int num_clks;
-+ u32 stg_usb_mode;
-+};
-+
-+static void cdns_mode_init(struct platform_device *pdev,
-+ struct cdns_starfive *data)
-+{
-+ enum usb_dr_mode mode;
-+
-+ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
-+ USB_MISC_CFG_MASK,
-+ USB_SUSPENDM_BYPS | USB_PLL_EN | USB_REFCLK_MODE);
-+
-+ /* dr mode setting */
-+ mode = usb_get_dr_mode(&pdev->dev);
-+
-+ switch (mode) {
-+ case USB_DR_MODE_HOST:
-+ regmap_update_bits(data->stg_syscon,
-+ data->stg_usb_mode,
-+ USB_STRAP_MASK,
-+ USB_STRAP_HOST);
-+ regmap_update_bits(data->stg_syscon,
-+ data->stg_usb_mode,
-+ USB_SUSPENDM_MASK,
-+ USB_SUSPENDM_HOST);
-+ break;
-+
-+ case USB_DR_MODE_PERIPHERAL:
-+ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
-+ USB_STRAP_MASK, USB_STRAP_DEVICE);
-+ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
-+ USB_SUSPENDM_MASK, 0);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static int cdns_clk_rst_init(struct cdns_starfive *data)
-+{
-+ int ret;
-+
-+ ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
-+ if (ret)
-+ return dev_err_probe(data->dev, ret,
-+ "failed to enable clocks\n");
-+
-+ ret = reset_control_deassert(data->resets);
-+ if (ret) {
-+ dev_err(data->dev, "failed to reset clocks\n");
-+ goto err_clk_init;
-+ }
-+
-+ return ret;
-+
-+err_clk_init:
-+ clk_bulk_disable_unprepare(data->num_clks, data->clks);
-+ return ret;
-+}
-+
-+static void cdns_clk_rst_deinit(struct cdns_starfive *data)
-+{
-+ reset_control_assert(data->resets);
-+ clk_bulk_disable_unprepare(data->num_clks, data->clks);
-+}
-+
-+static int cdns_starfive_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct cdns_starfive *data;
-+ unsigned int args;
-+ int ret;
-+
-+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ data->dev = dev;
-+
-+ data->stg_syscon =
-+ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,stg-syscon", 1, &args);
-+
-+ if (IS_ERR(data->stg_syscon))
-+ return dev_err_probe(dev, PTR_ERR(data->stg_syscon),
-+ "Failed to parse starfive,stg-syscon\n");
-+
-+ data->stg_usb_mode = args;
-+
-+ data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
-+ if (data->num_clks < 0)
-+ return dev_err_probe(data->dev, -ENODEV,
-+ "Failed to get clocks\n");
-+
-+ data->resets = devm_reset_control_array_get_exclusive(data->dev);
-+ if (IS_ERR(data->resets))
-+ return dev_err_probe(data->dev, PTR_ERR(data->resets),
-+ "Failed to get resets");
-+
-+ cdns_mode_init(pdev, data);
-+ ret = cdns_clk_rst_init(data);
-+ if (ret)
-+ return ret;
-+
-+ ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to create children\n");
-+ cdns_clk_rst_deinit(data);
-+ return ret;
-+ }
-+
-+ device_set_wakeup_capable(dev, true);
-+ pm_runtime_set_active(dev);
-+ pm_runtime_enable(dev);
-+ platform_set_drvdata(pdev, data);
-+
-+ return 0;
-+}
-+
-+static int cdns_starfive_remove_core(struct device *dev, void *c)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+
-+ platform_device_unregister(pdev);
-+
-+ return 0;
-+}
-+
-+static int cdns_starfive_remove(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ pm_runtime_get_sync(dev);
-+ device_for_each_child(dev, NULL, cdns_starfive_remove_core);
-+
-+ pm_runtime_disable(dev);
-+ pm_runtime_put_noidle(dev);
-+ cdns_clk_rst_deinit(data);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int cdns_starfive_runtime_resume(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ return clk_bulk_prepare_enable(data->num_clks, data->clks);
-+}
-+
-+static int cdns_starfive_runtime_suspend(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ clk_bulk_disable_unprepare(data->num_clks, data->clks);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int cdns_starfive_resume(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ return cdns_clk_rst_init(data);
-+}
-+
-+static int cdns_starfive_suspend(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ cdns_clk_rst_deinit(data);
-+
-+ return 0;
-+}
-+#endif
-+#endif
-+
-+static const struct dev_pm_ops cdns_starfive_pm_ops = {
-+ SET_RUNTIME_PM_OPS(cdns_starfive_runtime_suspend,
-+ cdns_starfive_runtime_resume, NULL)
-+ SET_SYSTEM_SLEEP_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume)
-+};
-+
-+static const struct of_device_id cdns_starfive_of_match[] = {
-+ { .compatible = "starfive,jh7110-usb", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);
-+
-+static struct platform_driver cdns_starfive_driver = {
-+ .probe = cdns_starfive_probe,
-+ .remove = cdns_starfive_remove,
-+ .driver = {
-+ .name = "cdns3-starfive",
-+ .of_match_table = cdns_starfive_of_match,
-+ .pm = &cdns_starfive_pm_ops,
-+ },
-+};
-+module_platform_driver(cdns_starfive_driver);
-+
-+MODULE_ALIAS("platform:cdns3-starfive");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("Cadence USB3 StarFive Glue Layer");
diff --git a/target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch b/target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch
deleted file mode 100644
index 150fef8eb4..0000000000
--- a/target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From 3d555cfd72df1a02849565f281149d321e0f8425 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 6 Apr 2023 19:11:40 +0800
-Subject: [PATCH 094/122] dt-binding: pci: add JH7110 PCIe dt-binding
- documents.
-
-Add PCIe controller driver dt-binding documents
-for StarFive JH7110 SoC platform.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- .../bindings/pci/starfive,jh7110-pcie.yaml | 163 ++++++++++++++++++
- 1 file changed, 163 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
-@@ -0,0 +1,163 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 PCIe 2.0 host controller
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+allOf:
-+ - $ref: /schemas/pci/pci-bus.yaml#
-+ - $ref: /schemas/interrupt-controller/msi-controller.yaml#
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pcie
-+
-+ reg:
-+ maxItems: 2
-+
-+ reg-names:
-+ items:
-+ - const: reg
-+ - const: config
-+
-+ msi-parent: true
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ clocks:
-+ maxItems: 4
-+
-+ clock-names:
-+ items:
-+ - const: noc
-+ - const: tl
-+ - const: axi_mst0
-+ - const: apb
-+
-+ resets:
-+ items:
-+ - description: AXI MST0 reset
-+ - description: AXI SLAVE reset
-+ - description: AXI SLAVE0 reset
-+ - description: PCIE BRIDGE reset
-+ - description: PCIE CORE reset
-+ - description: PCIE APB reset
-+
-+ reset-names:
-+ items:
-+ - const: mst0
-+ - const: slv0
-+ - const: slv
-+ - const: brg
-+ - const: core
-+ - const: apb
-+
-+ starfive,stg-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ items:
-+ - description: phandle to System Register Controller stg_syscon node.
-+ - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ description:
-+ The phandle to System Register Controller syscon node and the offset
-+ of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
-+ for PCIe.
-+
-+ pwren-gpios:
-+ description: Should specify the GPIO for controlling the PCI bus device power on.
-+ maxItems: 1
-+
-+ reset-gpios:
-+ maxItems: 1
-+
-+ phys:
-+ maxItems: 1
-+
-+ interrupt-controller:
-+ type: object
-+ properties:
-+ '#address-cells':
-+ const: 0
-+
-+ '#interrupt-cells':
-+ const: 1
-+
-+ interrupt-controller: true
-+
-+ required:
-+ - '#address-cells'
-+ - '#interrupt-cells'
-+ - interrupt-controller
-+
-+ additionalProperties: false
-+
-+required:
-+ - reg
-+ - reg-names
-+ - "#interrupt-cells"
-+ - interrupts
-+ - interrupt-map-mask
-+ - interrupt-map
-+ - clocks
-+ - clock-names
-+ - resets
-+ - msi-controller
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ bus {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+
-+ pcie0: pcie@2B000000 {
-+ compatible = "starfive,jh7110-pcie";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ #interrupt-cells = <1>;
-+ reg = <0x0 0x2B000000 0x0 0x1000000>,
-+ <0x9 0x40000000 0x0 0x10000000>;
-+ reg-names = "reg", "config";
-+ device_type = "pci";
-+ starfive,stg-syscon = <&stg_syscon 0xc0 0xc4 0x130 0x1b8>;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
-+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
-+ interrupt-parent = <&plic>;
-+ interrupts = <56>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
-+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
-+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
-+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
-+ msi-parent = <&pcie0>;
-+ msi-controller;
-+ clocks = <&syscrg 86>,
-+ <&stgcrg 10>,
-+ <&stgcrg 8>,
-+ <&stgcrg 9>;
-+ clock-names = "noc", "tl", "axi_mst0", "apb";
-+ resets = <&stgcrg 11>,
-+ <&stgcrg 12>,
-+ <&stgcrg 13>,
-+ <&stgcrg 14>,
-+ <&stgcrg 15>,
-+ <&stgcrg 16>;
-+
-+ pcie_intc0: interrupt-controller {
-+ #address-cells = <0>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ };
-+ };
-+ };
diff --git a/target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch b/target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch
deleted file mode 100644
index de701baaa9..0000000000
--- a/target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From a3749d68d81488ae07878393485278eab24a5818 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 2 Mar 2023 18:52:21 +0800
-Subject: [PATCH 095/122] spi: cadence-quadspi: Add support for StarFive JH7110
- QSPI
-
-Add QSPI reset operation in device probe and add RISCV support to
-QUAD SPI Kconfig.
-
-Co-developed-by: Ziv Xu <ziv.xu@starfivetech.com>
-Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- drivers/spi/Kconfig | 2 +-
- drivers/spi/spi-cadence-quadspi.c | 21 ++++++++++++++++++++-
- 2 files changed, 21 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -230,7 +230,7 @@ config SPI_CADENCE
-
- config SPI_CADENCE_QUADSPI
- tristate "Cadence Quad SPI controller"
-- depends on OF && (ARM || ARM64 || X86 || COMPILE_TEST)
-+ depends on OF && (ARM || ARM64 || X86 || RISCV || COMPILE_TEST)
- help
- Enable support for the Cadence Quad SPI Flash controller.
-
---- a/drivers/spi/spi-cadence-quadspi.c
-+++ b/drivers/spi/spi-cadence-quadspi.c
-@@ -1575,7 +1575,7 @@ static int cqspi_setup_flash(struct cqsp
- static int cqspi_probe(struct platform_device *pdev)
- {
- const struct cqspi_driver_platdata *ddata;
-- struct reset_control *rstc, *rstc_ocp;
-+ struct reset_control *rstc, *rstc_ocp, *rstc_ref;
- struct device *dev = &pdev->dev;
- struct spi_master *master;
- struct resource *res_ahb;
-@@ -1668,6 +1668,17 @@ static int cqspi_probe(struct platform_d
- goto probe_reset_failed;
- }
-
-+ if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi")) {
-+ rstc_ref = devm_reset_control_get_optional_exclusive(dev, "rstc_ref");
-+ if (IS_ERR(rstc_ref)) {
-+ ret = PTR_ERR(rstc_ref);
-+ dev_err(dev, "Cannot get QSPI REF reset.\n");
-+ goto probe_reset_failed;
-+ }
-+ reset_control_assert(rstc_ref);
-+ reset_control_deassert(rstc_ref);
-+ }
-+
- reset_control_assert(rstc);
- reset_control_deassert(rstc);
-
-@@ -1827,6 +1838,10 @@ static const struct cqspi_driver_platdat
- .get_dma_status = cqspi_get_versal_dma_status,
- };
-
-+static const struct cqspi_driver_platdata jh7110_qspi = {
-+ .quirks = CQSPI_DISABLE_DAC_MODE,
-+};
-+
- static const struct of_device_id cqspi_dt_ids[] = {
- {
- .compatible = "cdns,qspi-nor",
-@@ -1852,6 +1867,10 @@ static const struct of_device_id cqspi_d
- .compatible = "intel,socfpga-qspi",
- .data = &socfpga_qspi,
- },
-+ {
-+ .compatible = "starfive,jh7110-qspi",
-+ .data = &jh7110_qspi,
-+ },
- { /* end of table */ }
- };
-
diff --git a/target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch b/target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch
deleted file mode 100644
index ffd413c088..0000000000
--- a/target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch
+++ /dev/null
@@ -1,1004 +0,0 @@
-From e0cd43bcbc9b74343e529fde66a3ec20b533ac61 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 6 Apr 2023 19:11:41 +0800
-Subject: [PATCH 096/122] pcie: starfive: add StarFive JH7110 PCIe driver.
-
-Add PCIe controller driver for StarFive JH7110
-SoC platform. The PCIe controller is PCIe 2.0, single lane.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- drivers/pci/controller/Kconfig | 8 +
- drivers/pci/controller/Makefile | 1 +
- drivers/pci/controller/pcie-starfive.c | 958 +++++++++++++++++++++++++
- 3 files changed, 967 insertions(+)
- create mode 100644 drivers/pci/controller/pcie-starfive.c
-
---- a/drivers/pci/controller/Kconfig
-+++ b/drivers/pci/controller/Kconfig
-@@ -343,6 +343,14 @@ config PCIE_MT7621
- help
- This selects a driver for the MediaTek MT7621 PCIe Controller.
-
-+config PCIE_STARFIVE
-+ tristate "StarFive JH7110 PCIe controller"
-+ depends on PCI_MSI && OF
-+ select PCI_MSI_IRQ_DOMAIN
-+ help
-+ Say 'Y' here if you want kernel to support the StarFive JH7110
-+ PCIe Host driver.
-+
- source "drivers/pci/controller/dwc/Kconfig"
- source "drivers/pci/controller/mobiveil/Kconfig"
- source "drivers/pci/controller/cadence/Kconfig"
---- a/drivers/pci/controller/Makefile
-+++ b/drivers/pci/controller/Makefile
-@@ -39,6 +39,7 @@ obj-$(CONFIG_PCI_LOONGSON) += pci-loongs
- obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
- obj-$(CONFIG_PCIE_APPLE) += pcie-apple.o
- obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o
-+obj-$(CONFIG_PCIE_STARFIVE) += pcie-starfive.o
-
- # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
- obj-y += dwc/
---- /dev/null
-+++ b/drivers/pci/controller/pcie-starfive.c
-@@ -0,0 +1,958 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * PCIe host controller driver for Starfive JH7110 Soc.
-+ *
-+ * Based on pcie-altera.c, pcie-altera-msi.c.
-+ *
-+ * Copyright (C) StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/gpio/consumer.h>
-+#include <linux/interrupt.h>
-+#include <linux/irqchip/chained_irq.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/msi.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_pci.h>
-+#include <linux/pci.h>
-+#include <linux/pci-ecam.h>
-+#include <linux/phy/phy.h>
-+#include <linux/pinctrl/consumer.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/slab.h>
-+#include "../pci.h"
-+
-+#define IMASK_LOCAL 0x180
-+#define ISTATUS_LOCAL 0x184
-+#define IMSI_ADDR 0x190
-+#define ISTATUS_MSI 0x194
-+#define GEN_SETTINGS 0x80
-+#define PCIE_PCI_IDS 0x9C
-+#define PCIE_WINROM 0xFC
-+#define PMSG_SUPPORT_RX 0x3F0
-+
-+#define PCI_MISC 0xB4
-+
-+#define RP_ENABLE 1
-+
-+#define IDS_CLASS_CODE_SHIFT 16
-+
-+#define DATA_LINK_ACTIVE BIT(5)
-+#define PREF_MEM_WIN_64_SUPPORT BIT(3)
-+#define PMSG_LTR_SUPPORT BIT(2)
-+#define LINK_SPEED_GEN2 BIT(12)
-+#define PHY_FUNCTION_DIS BIT(15)
-+#define PCIE_FUNC_NUM 4
-+#define PHY_FUNC_SHIFT 9
-+
-+#define XR3PCI_ATR_AXI4_SLV0 0x800
-+#define XR3PCI_ATR_SRC_ADDR_LOW 0x0
-+#define XR3PCI_ATR_SRC_ADDR_HIGH 0x4
-+#define XR3PCI_ATR_TRSL_ADDR_LOW 0x8
-+#define XR3PCI_ATR_TRSL_ADDR_HIGH 0xc
-+#define XR3PCI_ATR_TRSL_PARAM 0x10
-+#define XR3PCI_ATR_TABLE_OFFSET 0x20
-+#define XR3PCI_ATR_MAX_TABLE_NUM 8
-+
-+#define XR3PCI_ATR_SRC_WIN_SIZE_SHIFT 1
-+#define XR3PCI_ATR_SRC_ADDR_MASK GENMASK(31, 12)
-+#define XR3PCI_ATR_TRSL_ADDR_MASK GENMASK(31, 12)
-+#define XR3PCI_ECAM_SIZE BIT(28)
-+#define XR3PCI_ATR_TRSL_DIR BIT(22)
-+/* IDs used in the XR3PCI_ATR_TRSL_PARAM */
-+#define XR3PCI_ATR_TRSLID_PCIE_MEMORY 0x0
-+#define XR3PCI_ATR_TRSLID_PCIE_CONFIG 0x1
-+
-+#define INT_AXI_POST_ERROR BIT(16)
-+#define INT_AXI_FETCH_ERROR BIT(17)
-+#define INT_AXI_DISCARD_ERROR BIT(18)
-+#define INT_PCIE_POST_ERROR BIT(20)
-+#define INT_PCIE_FETCH_ERROR BIT(21)
-+#define INT_PCIE_DISCARD_ERROR BIT(22)
-+#define INT_ERRORS (INT_AXI_POST_ERROR | INT_AXI_FETCH_ERROR | \
-+ INT_AXI_DISCARD_ERROR | INT_PCIE_POST_ERROR | \
-+ INT_PCIE_FETCH_ERROR | INT_PCIE_DISCARD_ERROR)
-+
-+#define INTA_OFFSET 24
-+#define INTA BIT(24)
-+#define INTB BIT(25)
-+#define INTC BIT(26)
-+#define INTD BIT(27)
-+#define INT_MSI BIT(28)
-+#define INT_INTX_MASK (INTA | INTB | INTC | INTD)
-+#define INT_MASK (INT_INTX_MASK | INT_MSI | INT_ERRORS)
-+
-+#define INT_PCI_MSI_NR 32
-+
-+/* system control */
-+#define STG_SYSCON_K_RP_NEP BIT(8)
-+#define STG_SYSCON_AXI4_SLVL_ARFUNC_MASK GENMASK(22, 8)
-+#define STG_SYSCON_AXI4_SLVL_ARFUNC_SHIFT 8
-+#define STG_SYSCON_AXI4_SLVL_AWFUNC_MASK GENMASK(14, 0)
-+#define STG_SYSCON_CLKREQ BIT(22)
-+#define STG_SYSCON_CKREF_SRC_SHIFT 18
-+#define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18)
-+
-+/* MSI information */
-+struct jh7110_pcie_msi {
-+ DECLARE_BITMAP(used, INT_PCI_MSI_NR);
-+ struct irq_domain *msi_domain;
-+ struct irq_domain *inner_domain;
-+ /* Protect bitmap variable */
-+ struct mutex lock;
-+};
-+
-+struct starfive_jh7110_pcie {
-+ struct platform_device *pdev;
-+ void __iomem *reg_base;
-+ void __iomem *config_base;
-+ phys_addr_t config_phyaddr;
-+ struct regmap *reg_syscon;
-+ struct phy *phy;
-+ u32 stg_arfun;
-+ u32 stg_awfun;
-+ u32 stg_rp_nep;
-+ u32 stg_lnksta;
-+ int irq;
-+ struct irq_domain *legacy_irq_domain;
-+ struct pci_host_bridge *bridge;
-+ struct jh7110_pcie_msi msi;
-+ struct reset_control *resets;
-+ struct clk_bulk_data *clks;
-+ int num_clks;
-+ int atr_table_num;
-+ struct gpio_desc *power_gpio;
-+ struct gpio_desc *reset_gpio;
-+};
-+
-+/*
-+ * StarFive PCIe port uses BAR0-BAR1 of RC's configuration space as
-+ * the translation from PCI bus to native BUS. Entire DDR region
-+ * is mapped into PCIe space using these registers, so it can be
-+ * reached by DMA from EP devices. The BAR0/1 of bridge should be
-+ * hidden during enumeration to avoid the sizing and resource allocation
-+ * by PCIe core.
-+ */
-+static bool starfive_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
-+ int offset)
-+{
-+ if (pci_is_root_bus(bus) && (devfn == 0)
-+ && ((offset == PCI_BASE_ADDRESS_0)
-+ || (offset == PCI_BASE_ADDRESS_1)))
-+ return true;
-+
-+ return false;
-+}
-+
-+void __iomem *starfive_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
-+ int where)
-+{
-+ struct starfive_jh7110_pcie *pcie = bus->sysdata;
-+
-+ return pcie->config_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
-+}
-+
-+int starfive_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
-+ int where, int size, u32 value)
-+{
-+ if (starfive_pcie_hide_rc_bar(bus, devfn, where))
-+ return PCIBIOS_BAD_REGISTER_NUMBER;
-+
-+ return pci_generic_config_write(bus, devfn, where, size, value);
-+}
-+
-+static void starfive_pcie_handle_msi_irq(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ u32 bit;
-+ u32 virq;
-+ unsigned long status = readl(pcie->reg_base + ISTATUS_MSI);
-+
-+ for_each_set_bit(bit, &status, INT_PCI_MSI_NR) {
-+ /* Clear interrupts */
-+ writel(1 << bit, pcie->reg_base + ISTATUS_MSI);
-+ virq = irq_find_mapping(msi->inner_domain, bit);
-+ if (virq) {
-+ if (test_bit(bit, msi->used))
-+ generic_handle_irq(virq);
-+ else
-+ dev_err(&pcie->pdev->dev,
-+ "Unhandled MSI, MSI%d virq %d\n", bit,
-+ virq);
-+ } else
-+ dev_err(&pcie->pdev->dev, "Unexpected MSI, MSI%d\n",
-+ bit);
-+ }
-+ writel(INT_MSI, pcie->reg_base + ISTATUS_LOCAL);
-+}
-+
-+static void starfive_pcie_handle_intx_irq(struct starfive_jh7110_pcie *pcie,
-+ unsigned long status)
-+{
-+ u32 bit;
-+ u32 virq;
-+
-+ status >>= INTA_OFFSET;
-+
-+ for_each_set_bit(bit, &status, PCI_NUM_INTX) {
-+ /* Clear interrupts */
-+ writel(1 << (bit + INTA_OFFSET), pcie->reg_base + ISTATUS_LOCAL);
-+
-+ virq = irq_find_mapping(pcie->legacy_irq_domain, bit);
-+ if (virq)
-+ generic_handle_irq(virq);
-+ else
-+ dev_err(&pcie->pdev->dev,
-+ "unexpected IRQ, INT%d\n", bit);
-+ }
-+}
-+
-+static void starfive_pcie_handle_errors_irq(struct starfive_jh7110_pcie *pcie, u32 status)
-+{
-+ if (status & INT_AXI_POST_ERROR)
-+ dev_err(&pcie->pdev->dev, "AXI post error\n");
-+ if (status & INT_AXI_FETCH_ERROR)
-+ dev_err(&pcie->pdev->dev, "AXI fetch error\n");
-+ if (status & INT_AXI_DISCARD_ERROR)
-+ dev_err(&pcie->pdev->dev, "AXI discard error\n");
-+ if (status & INT_PCIE_POST_ERROR)
-+ dev_err(&pcie->pdev->dev, "PCIe post error\n");
-+ if (status & INT_PCIE_FETCH_ERROR)
-+ dev_err(&pcie->pdev->dev, "PCIe fetch error\n");
-+ if (status & INT_PCIE_DISCARD_ERROR)
-+ dev_err(&pcie->pdev->dev, "PCIe discard error\n");
-+
-+ writel(INT_ERRORS, pcie->reg_base + ISTATUS_LOCAL);
-+}
-+
-+static void starfive_pcie_isr(struct irq_desc *desc)
-+{
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ struct starfive_jh7110_pcie *pcie;
-+ u32 status;
-+
-+ chained_irq_enter(chip, desc);
-+ pcie = irq_desc_get_handler_data(desc);
-+
-+ status = readl(pcie->reg_base + ISTATUS_LOCAL);
-+ while ((status = (readl(pcie->reg_base + ISTATUS_LOCAL) & INT_MASK))) {
-+ if (status & INT_INTX_MASK)
-+ starfive_pcie_handle_intx_irq(pcie, status);
-+
-+ if (status & INT_MSI)
-+ starfive_pcie_handle_msi_irq(pcie);
-+
-+ if (status & INT_ERRORS)
-+ starfive_pcie_handle_errors_irq(pcie, status);
-+ }
-+
-+ chained_irq_exit(chip, desc);
-+}
-+
-+#ifdef CONFIG_PCI_MSI
-+static struct irq_chip starfive_pcie_msi_irq_chip = {
-+ .name = "StarFive PCIe MSI",
-+ .irq_mask = pci_msi_mask_irq,
-+ .irq_unmask = pci_msi_unmask_irq,
-+};
-+
-+static struct msi_domain_info starfive_pcie_msi_domain_info = {
-+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-+ MSI_FLAG_PCI_MSIX),
-+ .chip = &starfive_pcie_msi_irq_chip,
-+};
-+#endif
-+
-+static void starfive_pcie_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
-+{
-+ struct starfive_jh7110_pcie *pcie = irq_data_get_irq_chip_data(data);
-+ phys_addr_t msi_addr = readl(pcie->reg_base + IMSI_ADDR);
-+
-+ msg->address_lo = lower_32_bits(msi_addr);
-+ msg->address_hi = upper_32_bits(msi_addr);
-+ msg->data = data->hwirq;
-+
-+ dev_info(&pcie->pdev->dev, "msi#%d address_hi %#x address_lo %#x\n",
-+ (int)data->hwirq, msg->address_hi, msg->address_lo);
-+}
-+
-+static int starfive_pcie_msi_set_affinity(struct irq_data *irq_data,
-+ const struct cpumask *mask, bool force)
-+{
-+ return -EINVAL;
-+}
-+
-+static struct irq_chip starfive_irq_chip = {
-+ .name = "StarFive MSI",
-+ .irq_compose_msi_msg = starfive_pcie_compose_msi_msg,
-+ .irq_set_affinity = starfive_pcie_msi_set_affinity,
-+};
-+
-+static int starfive_pcie_msi_alloc(struct irq_domain *domain, unsigned int virq,
-+ unsigned int nr_irqs, void *args)
-+{
-+ struct starfive_jh7110_pcie *pcie = domain->host_data;
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ int bit;
-+
-+ WARN_ON(nr_irqs != 1);
-+ mutex_lock(&msi->lock);
-+
-+ bit = find_first_zero_bit(msi->used, INT_PCI_MSI_NR);
-+ if (bit >= INT_PCI_MSI_NR) {
-+ mutex_unlock(&msi->lock);
-+ return -ENOSPC;
-+ }
-+
-+ set_bit(bit, msi->used);
-+
-+ irq_domain_set_info(domain, virq, bit, &starfive_irq_chip,
-+ domain->host_data, handle_simple_irq,
-+ NULL, NULL);
-+ mutex_unlock(&msi->lock);
-+
-+ return 0;
-+}
-+
-+static void starfive_pcie_msi_free(struct irq_domain *domain, unsigned int virq,
-+ unsigned int nr_irqs)
-+{
-+ struct irq_data *data = irq_domain_get_irq_data(domain, virq);
-+ struct starfive_jh7110_pcie *pcie = irq_data_get_irq_chip_data(data);
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+
-+ mutex_lock(&msi->lock);
-+
-+ if (!test_bit(data->hwirq, msi->used))
-+ dev_err(&pcie->pdev->dev, "Trying to free unused MSI#%lu\n",
-+ data->hwirq);
-+ else
-+ __clear_bit(data->hwirq, msi->used);
-+
-+ writel(0xffffffff, pcie->reg_base + ISTATUS_MSI);
-+ mutex_unlock(&msi->lock);
-+}
-+
-+static const struct irq_domain_ops dev_msi_domain_ops = {
-+ .alloc = starfive_pcie_msi_alloc,
-+ .free = starfive_pcie_msi_free,
-+};
-+
-+static void starfive_pcie_msi_free_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+#ifdef CONFIG_PCI_MSI
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ u32 irq;
-+ int i;
-+
-+ for (i = 0; i < INT_PCI_MSI_NR; i++) {
-+ irq = irq_find_mapping(msi->inner_domain, i);
-+ if (irq > 0)
-+ irq_dispose_mapping(irq);
-+ }
-+
-+ if (msi->msi_domain)
-+ irq_domain_remove(msi->msi_domain);
-+
-+ if (msi->inner_domain)
-+ irq_domain_remove(msi->inner_domain);
-+#endif
-+}
-+
-+static void starfive_pcie_free_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+ int i;
-+ u32 irq;
-+
-+ /* Disable all interrupts */
-+ writel(0, pcie->reg_base + IMASK_LOCAL);
-+
-+ if (pcie->legacy_irq_domain) {
-+ for (i = 0; i < PCI_NUM_INTX; i++) {
-+ irq = irq_find_mapping(pcie->legacy_irq_domain, i);
-+ if (irq > 0)
-+ irq_dispose_mapping(irq);
-+ }
-+ irq_domain_remove(pcie->legacy_irq_domain);
-+ }
-+
-+ if (pci_msi_enabled())
-+ starfive_pcie_msi_free_irq_domain(pcie);
-+ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
-+}
-+
-+static int starfive_pcie_init_msi_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+#ifdef CONFIG_PCI_MSI
-+ struct fwnode_handle *fwn = of_node_to_fwnode(pcie->pdev->dev.of_node);
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+
-+ msi->inner_domain = irq_domain_add_linear(NULL, INT_PCI_MSI_NR,
-+ &dev_msi_domain_ops, pcie);
-+ if (!msi->inner_domain) {
-+ dev_err(&pcie->pdev->dev, "Failed to create dev IRQ domain\n");
-+ return -ENOMEM;
-+ }
-+ msi->msi_domain = pci_msi_create_irq_domain(fwn, &starfive_pcie_msi_domain_info,
-+ msi->inner_domain);
-+ if (!msi->msi_domain) {
-+ dev_err(&pcie->pdev->dev, "Failed to create msi IRQ domain\n");
-+ irq_domain_remove(msi->inner_domain);
-+ return -ENOMEM;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+static int starfive_pcie_enable_msi(struct starfive_jh7110_pcie *pcie, struct pci_bus *bus)
-+{
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ u32 reg;
-+
-+ mutex_init(&msi->lock);
-+
-+ /* Enable MSI */
-+ reg = readl(pcie->reg_base + IMASK_LOCAL);
-+ reg |= INT_MSI;
-+ writel(reg, pcie->reg_base + IMASK_LOCAL);
-+ return 0;
-+}
-+
-+static int starfive_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
-+ irq_hw_number_t hwirq)
-+{
-+ irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
-+ irq_set_chip_data(irq, domain->host_data);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops intx_domain_ops = {
-+ .map = starfive_pcie_intx_map,
-+ .xlate = pci_irqd_intx_xlate,
-+};
-+
-+static int starfive_pcie_init_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct device *dev = &pcie->pdev->dev;
-+ struct device_node *node = dev->of_node;
-+ int ret;
-+
-+ if (pci_msi_enabled()) {
-+ ret = starfive_pcie_init_msi_irq_domain(pcie);
-+ if (ret != 0)
-+ return -ENOMEM;
-+ }
-+
-+ /* Setup INTx */
-+ pcie->legacy_irq_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
-+ &intx_domain_ops, pcie);
-+
-+ if (!pcie->legacy_irq_domain) {
-+ dev_err(dev, "Failed to get a INTx IRQ domain\n");
-+ return -ENOMEM;
-+ }
-+
-+ irq_set_chained_handler_and_data(pcie->irq, starfive_pcie_isr, pcie);
-+
-+ return 0;
-+}
-+
-+static int starfive_pcie_parse_dt(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct resource *cfg_res;
-+ struct platform_device *pdev = pcie->pdev;
-+ unsigned int args[4];
-+
-+ pcie->reg_base =
-+ devm_platform_ioremap_resource_byname(pdev, "reg");
-+
-+ if (IS_ERR(pcie->reg_base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->reg_base),
-+ "Failed to map reg memory\n");
-+
-+ cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
-+ if (!cfg_res)
-+ return dev_err_probe(&pdev->dev, -ENODEV,
-+ "Failed to get config memory\n");
-+
-+ pcie->config_base = devm_ioremap_resource(&pdev->dev, cfg_res);
-+ if (IS_ERR(pcie->config_base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->config_base),
-+ "Failed to map config memory\n");
-+
-+ pcie->config_phyaddr = cfg_res->start;
-+
-+ pcie->phy = devm_phy_optional_get(&pdev->dev, NULL);
-+ if (IS_ERR(pcie->phy))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->phy),
-+ "Failed to get pcie phy\n");
-+
-+ pcie->irq = platform_get_irq(pdev, 0);
-+ if (pcie->irq < 0)
-+ return dev_err_probe(&pdev->dev, -EINVAL,
-+ "Failed to get IRQ: %d\n", pcie->irq);
-+
-+ pcie->reg_syscon = syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,stg-syscon", 4, args);
-+
-+ if (IS_ERR(pcie->reg_syscon))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->reg_syscon),
-+ "Failed to parse starfive,stg-syscon\n");
-+
-+ pcie->stg_arfun = args[0];
-+ pcie->stg_awfun = args[1];
-+ pcie->stg_rp_nep = args[2];
-+ pcie->stg_lnksta = args[3];
-+
-+ /* Clear all interrupts */
-+ writel(0xffffffff, pcie->reg_base + ISTATUS_LOCAL);
-+ writel(INT_INTX_MASK | INT_ERRORS, pcie->reg_base + IMASK_LOCAL);
-+
-+ return 0;
-+}
-+
-+static struct pci_ops starfive_pcie_ops = {
-+ .map_bus = starfive_pcie_map_bus,
-+ .read = pci_generic_config_read,
-+ .write = starfive_pcie_config_write,
-+};
-+
-+static void starfive_pcie_set_atr_entry(struct starfive_jh7110_pcie *pcie,
-+ phys_addr_t src_addr, phys_addr_t trsl_addr,
-+ size_t window_size, int trsl_param)
-+{
-+ void __iomem *base =
-+ pcie->reg_base + XR3PCI_ATR_AXI4_SLV0;
-+
-+ /* Support AXI4 Slave 0 Address Translation Tables 0-7. */
-+ if (pcie->atr_table_num >= XR3PCI_ATR_MAX_TABLE_NUM)
-+ pcie->atr_table_num = XR3PCI_ATR_MAX_TABLE_NUM - 1;
-+ base += XR3PCI_ATR_TABLE_OFFSET * pcie->atr_table_num;
-+ pcie->atr_table_num++;
-+
-+ /*
-+ * X3PCI_ATR_SRC_ADDR_LOW:
-+ * - bit 0: enable entry,
-+ * - bits 1-6: ATR window size: total size in bytes: 2^(ATR_WSIZE + 1)
-+ * - bits 7-11: reserved
-+ * - bits 12-31: start of source address
-+ */
-+ writel((lower_32_bits(src_addr) & XR3PCI_ATR_SRC_ADDR_MASK) |
-+ (fls(window_size) - 1) << XR3PCI_ATR_SRC_WIN_SIZE_SHIFT | 1,
-+ base + XR3PCI_ATR_SRC_ADDR_LOW);
-+ writel(upper_32_bits(src_addr), base + XR3PCI_ATR_SRC_ADDR_HIGH);
-+ writel((lower_32_bits(trsl_addr) & XR3PCI_ATR_TRSL_ADDR_MASK),
-+ base + XR3PCI_ATR_TRSL_ADDR_LOW);
-+ writel(upper_32_bits(trsl_addr), base + XR3PCI_ATR_TRSL_ADDR_HIGH);
-+ writel(trsl_param, base + XR3PCI_ATR_TRSL_PARAM);
-+
-+ dev_info(&pcie->pdev->dev, "ATR entry: 0x%010llx %s 0x%010llx [0x%010llx] (param: 0x%06x)\n",
-+ src_addr, (trsl_param & XR3PCI_ATR_TRSL_DIR) ? "<-" : "->",
-+ trsl_addr, (u64)window_size, trsl_param);
-+}
-+
-+static int starfive_pcie_setup_windows(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct pci_host_bridge *bridge = pcie->bridge;
-+ struct resource_entry *entry;
-+ u64 pci_addr;
-+
-+ resource_list_for_each_entry(entry, &bridge->windows) {
-+ if (resource_type(entry->res) == IORESOURCE_MEM) {
-+ pci_addr = entry->res->start - entry->offset;
-+ starfive_pcie_set_atr_entry(pcie,
-+ entry->res->start, pci_addr,
-+ resource_size(entry->res),
-+ XR3PCI_ATR_TRSLID_PCIE_MEMORY);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int starfive_pcie_clk_rst_init(struct starfive_jh7110_pcie *pcie)
-+{
-+ int ret;
-+ struct device *dev = &pcie->pdev->dev;
-+
-+ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
-+ if (pcie->num_clks < 0)
-+ return dev_err_probe(dev, -ENODEV,
-+ "Failed to get pcie clocks\n");
-+
-+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
-+ if (ret)
-+ return dev_err_probe(&pcie->pdev->dev, ret,
-+ "Failed to enable clocks\n");
-+
-+ pcie->resets = devm_reset_control_array_get_exclusive(dev);
-+ if (IS_ERR(pcie->resets)) {
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+ return dev_err_probe(dev, PTR_ERR(pcie->resets),
-+ "Failed to get pcie resets");
-+ }
-+
-+ return reset_control_deassert(pcie->resets);
-+}
-+
-+static void starfive_pcie_clk_rst_deinit(struct starfive_jh7110_pcie *pcie)
-+{
-+ reset_control_assert(pcie->resets);
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+}
-+
-+int starfive_pcie_gpio_init(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct device *dev = &pcie->pdev->dev;
-+
-+ pcie->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
-+ if (IS_ERR_OR_NULL(pcie->reset_gpio)) {
-+ dev_warn(dev, "Failed to get reset-gpio.\n");
-+ return -EINVAL;
-+ }
-+
-+ pcie->power_gpio = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
-+ if (IS_ERR_OR_NULL(pcie->power_gpio))
-+ pcie->power_gpio = NULL;
-+
-+ return 0;
-+}
-+
-+static void starfive_pcie_hw_init(struct starfive_jh7110_pcie *pcie)
-+{
-+ unsigned int value;
-+ int i;
-+
-+ if (pcie->power_gpio)
-+ gpiod_set_value_cansleep(pcie->power_gpio, 1);
-+
-+ if (pcie->reset_gpio)
-+ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
-+
-+ /* Disable physical functions except #0 */
-+ for (i = 1; i < PCIE_FUNC_NUM; i++) {
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_arfun,
-+ STG_SYSCON_AXI4_SLVL_ARFUNC_MASK,
-+ (i << PHY_FUNC_SHIFT) <<
-+ STG_SYSCON_AXI4_SLVL_ARFUNC_SHIFT);
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_AXI4_SLVL_AWFUNC_MASK,
-+ i << PHY_FUNC_SHIFT);
-+
-+ value = readl(pcie->reg_base + PCI_MISC);
-+ value |= PHY_FUNCTION_DIS;
-+ writel(value, pcie->reg_base + PCI_MISC);
-+ }
-+
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_arfun,
-+ STG_SYSCON_AXI4_SLVL_ARFUNC_MASK,
-+ 0);
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_AXI4_SLVL_AWFUNC_MASK,
-+ 0);
-+
-+ /* Enable root port */
-+ value = readl(pcie->reg_base + GEN_SETTINGS);
-+ value |= RP_ENABLE;
-+ writel(value, pcie->reg_base + GEN_SETTINGS);
-+
-+ /* PCIe PCI Standard Configuration Identification Settings. */
-+ value = (PCI_CLASS_BRIDGE_PCI << IDS_CLASS_CODE_SHIFT);
-+ writel(value, pcie->reg_base + PCIE_PCI_IDS);
-+
-+ /*
-+ * The LTR message forwarding of PCIe Message Reception was set by core
-+ * as default, but the forward id & addr are also need to be reset.
-+ * If we do not disable LTR message forwarding here, or set a legal
-+ * forwarding address, the kernel will get stuck after this driver probe.
-+ * To workaround, disable the LTR message forwarding support on
-+ * PCIe Message Reception.
-+ */
-+ value = readl(pcie->reg_base + PMSG_SUPPORT_RX);
-+ value &= ~PMSG_LTR_SUPPORT;
-+ writel(value, pcie->reg_base + PMSG_SUPPORT_RX);
-+
-+ /* Prefetchable memory window 64-bit addressing support */
-+ value = readl(pcie->reg_base + PCIE_WINROM);
-+ value |= PREF_MEM_WIN_64_SUPPORT;
-+ writel(value, pcie->reg_base + PCIE_WINROM);
-+
-+ /*
-+ * As the two host bridges in JH7110 soc have the same default
-+ * address translation table, this cause the second root port can't
-+ * access it's host bridge config space correctly.
-+ * To workaround, config the ATR of host bridge config space by SW.
-+ */
-+ starfive_pcie_set_atr_entry(pcie,
-+ pcie->config_phyaddr, 0,
-+ XR3PCI_ECAM_SIZE,
-+ XR3PCI_ATR_TRSLID_PCIE_CONFIG);
-+
-+ starfive_pcie_setup_windows(pcie);
-+
-+ /* Ensure that PERST has been asserted for at least 100 ms */
-+ msleep(300);
-+ if (pcie->reset_gpio)
-+ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
-+}
-+
-+static bool starfive_pcie_is_link_up(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct device *dev = &pcie->pdev->dev;
-+ int ret;
-+ u32 stg_reg_val;
-+
-+ /* 100ms timeout value should be enough for Gen1/2 training */
-+ ret = regmap_read_poll_timeout(pcie->reg_syscon,
-+ pcie->stg_lnksta,
-+ stg_reg_val,
-+ stg_reg_val & DATA_LINK_ACTIVE,
-+ 10 * 1000, 100 * 1000);
-+
-+ /* If the link is down (no device in slot), then exit. */
-+ if (ret == -ETIMEDOUT) {
-+ dev_info(dev, "Port link down, exit.\n");
-+ return false;
-+ } else if (ret == 0) {
-+ dev_info(dev, "Port link up.\n");
-+ return true;
-+ }
-+
-+ dev_warn(dev, "Read stg_linksta failed.\n");
-+
-+ return false;
-+}
-+
-+static int starfive_pcie_enable_phy(struct device *dev,
-+ struct starfive_jh7110_pcie *pcie)
-+{
-+ int ret;
-+
-+ if (!pcie->phy)
-+ return 0;
-+
-+ ret = phy_init(pcie->phy);
-+ if (ret)
-+ return dev_err_probe(dev, ret,
-+ "failed to initialize pcie phy\n");
-+
-+ ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
-+ if (ret) {
-+ ret = dev_err_probe(dev, ret,
-+ "failed to set pcie mode\n");
-+ goto err_phy_on;
-+ }
-+
-+ ret = phy_power_on(pcie->phy);
-+ if (ret) {
-+ ret = dev_err_probe(dev, ret, "failed to power on pcie phy\n");
-+ goto err_phy_on;
-+ }
-+
-+ return 0;
-+
-+err_phy_on:
-+ phy_exit(pcie->phy);
-+ return ret;
-+}
-+
-+static void starfive_pcie_disable_phy(struct starfive_jh7110_pcie *pcie)
-+{
-+ phy_power_off(pcie->phy);
-+ phy_exit(pcie->phy);
-+}
-+
-+static int starfive_pcie_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct starfive_jh7110_pcie *pcie;
-+ struct pci_bus *bus;
-+ struct pci_host_bridge *bridge;
-+ int ret;
-+
-+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
-+ if (!pcie)
-+ return -ENOMEM;
-+
-+ pcie->pdev = pdev;
-+ pcie->atr_table_num = 0;
-+
-+ ret = starfive_pcie_parse_dt(pcie);
-+ if (ret)
-+ return ret;
-+
-+ platform_set_drvdata(pdev, pcie);
-+
-+ ret = starfive_pcie_gpio_init(pcie);
-+ if (ret)
-+ return ret;
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_rp_nep,
-+ STG_SYSCON_K_RP_NEP,
-+ STG_SYSCON_K_RP_NEP);
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_CKREF_SRC_MASK,
-+ 2 << STG_SYSCON_CKREF_SRC_SHIFT);
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_CLKREQ,
-+ STG_SYSCON_CLKREQ);
-+
-+ ret = starfive_pcie_clk_rst_init(pcie);
-+ if (ret)
-+ return ret;
-+
-+ ret = starfive_pcie_init_irq_domain(pcie);
-+ if (ret)
-+ return ret;
-+
-+ bridge = devm_pci_alloc_host_bridge(dev, 0);
-+ if (!bridge)
-+ return -ENOMEM;
-+
-+ pm_runtime_enable(&pdev->dev);
-+ pm_runtime_get_sync(&pdev->dev);
-+
-+ /* Set default bus ops */
-+ bridge->ops = &starfive_pcie_ops;
-+ bridge->sysdata = pcie;
-+ pcie->bridge = bridge;
-+
-+ starfive_pcie_hw_init(pcie);
-+
-+ if (starfive_pcie_is_link_up(pcie) == false)
-+ goto release;
-+
-+ if (IS_ENABLED(CONFIG_PCI_MSI)) {
-+ ret = starfive_pcie_enable_msi(pcie, bus);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to enable MSI support: %d\n", ret);
-+ goto release;
-+ }
-+ }
-+
-+ ret = starfive_pcie_enable_phy(dev, pcie);
-+ if (ret)
-+ goto release;
-+
-+ ret = pci_host_probe(bridge);
-+ if (ret < 0) {
-+ dev_err_probe(dev, ret, "Failed to pci host probe: %d\n", ret);
-+ goto err_phy_on;
-+ }
-+
-+ return ret;
-+
-+err_phy_on:
-+ starfive_pcie_disable_phy(pcie);
-+release:
-+ if (pcie->power_gpio)
-+ gpiod_set_value_cansleep(pcie->power_gpio, 0);
-+
-+ starfive_pcie_clk_rst_deinit(pcie);
-+
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ pci_free_host_bridge(pcie->bridge);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return ret;
-+}
-+
-+static int starfive_pcie_remove(struct platform_device *pdev)
-+{
-+ struct starfive_jh7110_pcie *pcie = platform_get_drvdata(pdev);
-+
-+ starfive_pcie_disable_phy(pcie);
-+ if (pcie->power_gpio)
-+ gpiod_set_value_cansleep(pcie->power_gpio, 0);
-+ starfive_pcie_free_irq_domain(pcie);
-+ starfive_pcie_clk_rst_deinit(pcie);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int __maybe_unused starfive_pcie_suspend_noirq(struct device *dev)
-+{
-+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
-+
-+ if (!pcie)
-+ return 0;
-+
-+ starfive_pcie_disable_phy(pcie);
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused starfive_pcie_resume_noirq(struct device *dev)
-+{
-+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
-+ int ret;
-+
-+ if (!pcie)
-+ return 0;
-+
-+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
-+ if (ret)
-+ return dev_err_probe(dev, ret,
-+ "Failed to enable clocks\n");
-+
-+ ret = starfive_pcie_enable_phy(dev, pcie);
-+ if (ret)
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+
-+ return ret;
-+}
-+
-+static const struct dev_pm_ops starfive_pcie_pm_ops = {
-+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(starfive_pcie_suspend_noirq,
-+ starfive_pcie_resume_noirq)
-+};
-+#endif
-+
-+static const struct of_device_id starfive_pcie_of_match[] = {
-+ { .compatible = "starfive,jh7110-pcie"},
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_pcie_of_match);
-+
-+static struct platform_driver starfive_pcie_driver = {
-+ .driver = {
-+ .name = "pcie-starfive",
-+ .of_match_table = of_match_ptr(starfive_pcie_of_match),
-+#ifdef CONFIG_PM_SLEEP
-+ .pm = &starfive_pcie_pm_ops,
-+#endif
-+ },
-+ .probe = starfive_pcie_probe,
-+ .remove = starfive_pcie_remove,
-+};
-+module_platform_driver(starfive_pcie_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 PCIe host driver");
-+MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
-+MODULE_AUTHOR("Kevin Xie <kevin.xie@starfivetech.com>");
-+MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch b/target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch
deleted file mode 100644
index cc629f06d2..0000000000
--- a/target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 214c40d5393cdf08c8b0746224e76bfd2a8d9cf7 Mon Sep 17 00:00:00 2001
-From: Mason Huo <mason.huo@starfivetech.com>
-Date: Fri, 21 Apr 2023 11:14:30 +0800
-Subject: [PATCH 097/122] cpufreq: dt-platdev: Add JH7110 SOC to the allowlist
-
-Add the compatible strings for supporting the generic
-cpufreq driver on the StarFive JH7110 SoC.
-
-Signed-off-by: Mason Huo <mason.huo@starfivetech.com>
----
- drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/cpufreq/cpufreq-dt-platdev.c
-+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
-@@ -86,6 +86,8 @@ static const struct of_device_id allowli
- { .compatible = "st-ericsson,u9500", },
- { .compatible = "st-ericsson,u9540", },
-
-+ { .compatible = "starfive,jh7110", },
-+
- { .compatible = "ti,omap2", },
- { .compatible = "ti,omap4", },
- { .compatible = "ti,omap5", },
diff --git a/target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch b/target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch
deleted file mode 100644
index 168782a280..0000000000
--- a/target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch
+++ /dev/null
@@ -1,1034 +0,0 @@
-From 16e358dcf5e072c82f643d11add5b7e55b36a6f8 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:53:31 -0700
-Subject: [PATCH 098/122] riscv: dts: starfive: Add full support for JH7110 and
- VisionFive 2 board
-
-Merge all StarFive dts patches together.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- .../jh7110-starfive-visionfive-2-v1.3b.dts | 8 +-
- .../jh7110-starfive-visionfive-2.dtsi | 338 ++++++++++++
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 506 +++++++++++++++++-
- 3 files changed, 847 insertions(+), 5 deletions(-)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -28,8 +28,8 @@
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
- motorcomm,tx-clk-1000-inverted;
-- rx-clk-driver-strength = <0x6>;
-- rx-data-driver-strength = <0x3>;
-+ motorcomm,rx-clk-driver-strength = <0x6>;
-+ motorcomm,rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <1500>;
- tx-internal-delay-ps = <1500>;
- };
-@@ -37,8 +37,8 @@
- &phy1 {
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
-- rx-clk-driver-strength = <0x6>;
-- rx-data-driver-strength = <0x3>;
-+ motorcomm,rx-clk-driver-strength = <0x6>;
-+ motorcomm,rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <300>;
- tx-internal-delay-ps = <0>;
- };
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -33,11 +33,64 @@
- reg = <0x0 0x40000000 0x1 0x0>;
- };
-
-+ reserved-memory {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ linux,cma {
-+ compatible = "shared-dma-pool";
-+ reusable;
-+ size = <0x0 0x20000000>;
-+ alignment = <0x0 0x1000>;
-+ alloc-ranges = <0x0 0x80000000 0x0 0x20000000>;
-+ linux,cma-default;
-+ };
-+ };
-+
-+ thermal-zones {
-+ cpu-thermal {
-+ polling-delay-passive = <250>;
-+ polling-delay = <15000>;
-+
-+ thermal-sensors = <&sfctemp>;
-+
-+ cooling-maps {
-+ };
-+
-+ trips {
-+ cpu_alert0: cpu_alert0 {
-+ /* milliCelsius */
-+ temperature = <75000>;
-+ hysteresis = <2000>;
-+ type = "passive";
-+ };
-+
-+ cpu_crit: cpu_crit {
-+ /* milliCelsius */
-+ temperature = <90000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+ };
-+ };
-+ };
-+
- gpio-restart {
- compatible = "gpio-restart";
- gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
- priority = <224>;
- };
-+
-+ clk_ext_camera: clk_ext_camera {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <24000000>;
-+ };
-+};
-+
-+&dvp_clk {
-+ clock-frequency = <74250000>;
- };
-
- &gmac0_rgmii_rxin {
-@@ -56,6 +109,10 @@
- clock-frequency = <50000000>;
- };
-
-+&hdmitx0_pixelclk {
-+ clock-frequency = <297000000>;
-+};
-+
- &i2srx_bclk_ext {
- clock-frequency = <12288000>;
- };
-@@ -88,6 +145,39 @@
- clock-frequency = <49152000>;
- };
-
-+&csi2rx {
-+ status = "okay";
-+
-+ assigned-clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>;
-+ assigned-clock-rates = <297000000>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+
-+ csi2rx_from_imx219: endpoint {
-+ remote-endpoint = <&imx219_to_csi2rx>;
-+ bus-type = <4>;
-+ clock-lanes = <0>;
-+ data-lanes = <1 2>;
-+ status = "okay";
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+
-+ csi2rx_to_vin: endpoint {
-+ remote-endpoint = <&vin_from_csi2rx>;
-+ status = "okay";
-+ };
-+ };
-+ };
-+};
-+
- &gmac0 {
- phy-handle = <&phy0>;
- phy-mode = "rgmii-id";
-@@ -148,6 +238,20 @@
- pinctrl-names = "default";
- pinctrl-0 = <&i2c5_pins>;
- status = "okay";
-+
-+ axp15060: pmic@36 {
-+ compatible = "x-powers,axp15060";
-+ reg = <0x36>;
-+
-+ regulators {
-+ vdd_cpu: dcdc2 {
-+ regulator-always-on;
-+ regulator-min-microvolt = <500000>;
-+ regulator-max-microvolt = <1540000>;
-+ regulator-name = "vdd-cpu";
-+ };
-+ };
-+ };
- };
-
- &i2c6 {
-@@ -158,6 +262,121 @@
- pinctrl-names = "default";
- pinctrl-0 = <&i2c6_pins>;
- status = "okay";
-+
-+ imx219: imx219@10 {
-+ compatible = "sony,imx219";
-+ reg = <0x10>;
-+ clocks = <&clk_ext_camera>;
-+ reset-gpio = <&sysgpio 18 0>;
-+ rotation = <0>;
-+ orientation = <1>;
-+
-+ port {
-+ imx219_to_csi2rx: endpoint {
-+ remote-endpoint = <&csi2rx_from_imx219>;
-+ bus-type = <4>;
-+ clock-lanes = <0>;
-+ data-lanes = <1 2>;
-+ link-frequencies = /bits/ 64 <456000000>;
-+ };
-+ };
-+ };
-+};
-+
-+&mmc0 {
-+ max-frequency = <100000000>;
-+ bus-width = <8>;
-+ cap-mmc-highspeed;
-+ mmc-ddr-1_8v;
-+ mmc-hs200-1_8v;
-+ non-removable;
-+ cap-mmc-hw-reset;
-+ post-power-on-delay-ms = <200>;
-+ status = "okay";
-+};
-+
-+&mmc1 {
-+ max-frequency = <100000000>;
-+ bus-width = <4>;
-+ no-sdio;
-+ no-mmc;
-+ broken-cd;
-+ cap-sd-highspeed;
-+ post-power-on-delay-ms = <200>;
-+ status = "okay";
-+};
-+
-+&pcie0 {
-+ pinctrl-names = "default";
-+ reset-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
-+ phys = <&pciephy0>;
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ pinctrl-names = "default";
-+ reset-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
-+ phys = <&pciephy1>;
-+ status = "okay";
-+};
-+
-+&ptc {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_pins>;
-+ status = "okay";
-+};
-+
-+&qspi {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ nor_flash: flash@0 {
-+ compatible = "jedec,spi-nor";
-+ reg=<0>;
-+ cdns,read-delay = <5>;
-+ spi-max-frequency = <12000000>;
-+ cdns,tshsl-ns = <1>;
-+ cdns,tsd2d-ns = <1>;
-+ cdns,tchsh-ns = <1>;
-+ cdns,tslch-ns = <1>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ spl@0 {
-+ reg = <0x0 0x20000>;
-+ };
-+ uboot@100000 {
-+ reg = <0x100000 0x300000>;
-+ };
-+ data@f00000 {
-+ reg = <0xf00000 0x100000>;
-+ };
-+ };
-+ };
-+};
-+
-+&stfcamss {
-+ status = "okay";
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@1 {
-+ reg = <1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ vin_from_csi2rx: endpoint@1 {
-+ reg = <1>;
-+ remote-endpoint = <&csi2rx_to_vin>;
-+ status = "okay";
-+ };
-+ };
-+ };
- };
-
- &sysgpio {
-@@ -217,6 +436,98 @@
- };
- };
-
-+ pcie0_wake_default: pcie0_wake_default {
-+ wake-pins {
-+ pinmux = <GPIOMUX(32, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pcie0_clkreq_default: pcie0_clkreq_default {
-+ clkreq-pins {
-+ bias-disable;
-+ pinmux = <GPIOMUX(27, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pcie1_wake_default: pcie1_wake_default {
-+ wake-pins {
-+ bias-disable;
-+ pinmux = <GPIOMUX(21, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pcie1_clkreq_default: pcie1_clkreq_default {
-+ clkreq-pins {
-+ bias-disable;
-+ pinmux = <GPIOMUX(29, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pwm_pins: pwm-0 {
-+ pwm-pins {
-+ pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
-+ GPOEN_SYS_PWM0_CHANNEL0, GPI_NONE)>,
-+ <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
-+ GPOEN_SYS_PWM0_CHANNEL1, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ tdm0_pins: tdm0-pins {
-+ tdm0-pins-tx {
-+ pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
-+ GPOEN_ENABLE,
-+ GPI_NONE)>;
-+ bias-pull-up;
-+ drive-strength = <2>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+
-+ tdm0-pins-rx {
-+ pinmux = <GPIOMUX(61, GPOUT_HIGH,
-+ GPOEN_DISABLE,
-+ GPI_SYS_TDM_RXD)>;
-+ input-enable;
-+ };
-+
-+ tdm0-pins-sync {
-+ pinmux = <GPIOMUX(63, GPOUT_HIGH,
-+ GPOEN_DISABLE,
-+ GPI_SYS_TDM_SYNC)>;
-+ input-enable;
-+ };
-+
-+ tdm0-pins-pcmclk {
-+ pinmux = <GPIOMUX(38, GPOUT_HIGH,
-+ GPOEN_DISABLE,
-+ GPI_SYS_TDM_CLK)>;
-+ input-enable;
-+ };
-+ };
-+
- uart0_pins: uart0-0 {
- tx-pins {
- pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
-@@ -242,8 +553,35 @@
- };
- };
-
-+&tdm {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&tdm0_pins>;
-+ status = "okay";
-+};
-+
- &uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
- status = "okay";
- };
-+
-+&usb0 {
-+ dr_mode = "peripheral";
-+ status = "okay";
-+};
-+
-+&U74_1 {
-+ cpu-supply = <&vdd_cpu>;
-+};
-+
-+&U74_2 {
-+ cpu-supply = <&vdd_cpu>;
-+};
-+
-+&U74_3 {
-+ cpu-supply = <&vdd_cpu>;
-+};
-+
-+&U74_4 {
-+ cpu-supply = <&vdd_cpu>;
-+};
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -6,6 +6,7 @@
-
- /dts-v1/;
- #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+#include <dt-bindings/power/starfive,jh7110-pmu.h>
- #include <dt-bindings/reset/starfive,jh7110-crg.h>
-
- / {
-@@ -53,6 +54,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu1_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -79,6 +83,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu2_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -105,6 +112,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu3_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -131,6 +141,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu4_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -164,6 +177,33 @@
- };
- };
-
-+ cpu_opp: opp-table-0 {
-+ compatible = "operating-points-v2";
-+ opp-shared;
-+ opp-375000000 {
-+ opp-hz = /bits/ 64 <375000000>;
-+ opp-microvolt = <800000>;
-+ };
-+ opp-500000000 {
-+ opp-hz = /bits/ 64 <500000000>;
-+ opp-microvolt = <800000>;
-+ };
-+ opp-750000000 {
-+ opp-hz = /bits/ 64 <750000000>;
-+ opp-microvolt = <800000>;
-+ };
-+ opp-1500000000 {
-+ opp-hz = /bits/ 64 <1500000000>;
-+ opp-microvolt = <1040000>;
-+ };
-+ };
-+
-+ dvp_clk: dvp-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "dvp_clk";
-+ #clock-cells = <0>;
-+ };
-+
- gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
- compatible = "fixed-clock";
- clock-output-names = "gmac0_rgmii_rxin";
-@@ -188,6 +228,12 @@
- #clock-cells = <0>;
- };
-
-+ hdmitx0_pixelclk: hdmitx0-pixel-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "hdmitx0_pixelclk";
-+ #clock-cells = <0>;
-+ };
-+
- i2srx_bclk_ext: i2srx-bclk-ext-clock {
- compatible = "fixed-clock";
- clock-output-names = "i2srx_bclk_ext";
-@@ -360,6 +406,99 @@
- status = "disabled";
- };
-
-+ tdm: tdm@10090000 {
-+ compatible = "starfive,jh7110-tdm";
-+ reg = <0x0 0x10090000 0x0 0x1000>;
-+ clocks = <&syscrg JH7110_SYSCLK_TDM_AHB>,
-+ <&syscrg JH7110_SYSCLK_TDM_APB>,
-+ <&syscrg JH7110_SYSCLK_TDM_INTERNAL>,
-+ <&syscrg JH7110_SYSCLK_TDM_TDM>,
-+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
-+ <&tdm_ext>;
-+ clock-names = "tdm_ahb", "tdm_apb",
-+ "tdm_internal", "tdm",
-+ "mclk_inner", "tdm_ext";
-+ resets = <&syscrg JH7110_SYSRST_TDM_AHB>,
-+ <&syscrg JH7110_SYSRST_TDM_APB>,
-+ <&syscrg JH7110_SYSRST_TDM_CORE>;
-+ dmas = <&dma 20>, <&dma 21>;
-+ dma-names = "rx","tx";
-+ #sound-dai-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ usb0: usb@10100000 {
-+ compatible = "starfive,jh7110-usb";
-+ ranges = <0x0 0x0 0x10100000 0x100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ starfive,stg-syscon = <&stg_syscon 0x4>;
-+ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
-+ <&stgcrg JH7110_STGCLK_USB0_STB>,
-+ <&stgcrg JH7110_STGCLK_USB0_APB>,
-+ <&stgcrg JH7110_STGCLK_USB0_AXI>,
-+ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>;
-+ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
-+ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
-+ <&stgcrg JH7110_STGRST_USB0_APB>,
-+ <&stgcrg JH7110_STGRST_USB0_AXI>,
-+ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>;
-+ reset-names = "pwrup", "apb", "axi", "utmi_apb";
-+ status = "disabled";
-+
-+ usb_cdns3: usb@0 {
-+ compatible = "cdns,usb3";
-+ reg = <0x0 0x10000>,
-+ <0x10000 0x10000>,
-+ <0x20000 0x10000>;
-+ reg-names = "otg", "xhci", "dev";
-+ interrupts = <100>, <108>, <110>;
-+ interrupt-names = "host", "peripheral", "otg";
-+ phys = <&usbphy0>;
-+ phy-names = "cdns3,usb2-phy";
-+ };
-+ };
-+
-+ usbphy0: phy@10200000 {
-+ compatible = "starfive,jh7110-usb-phy";
-+ reg = <0x0 0x10200000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_USB_125M>,
-+ <&stgcrg JH7110_STGCLK_USB0_APP_125>;
-+ clock-names = "125m", "app_125m";
-+ #phy-cells = <0>;
-+ };
-+
-+ pciephy0: phy@10210000 {
-+ compatible = "starfive,jh7110-pcie-phy";
-+ reg = <0x0 0x10210000 0x0 0x10000>;
-+ #phy-cells = <0>;
-+ };
-+
-+ pciephy1: phy@10220000 {
-+ compatible = "starfive,jh7110-pcie-phy";
-+ reg = <0x0 0x10220000 0x0 0x10000>;
-+ #phy-cells = <0>;
-+ };
-+
-+ stgcrg: clock-controller@10230000 {
-+ compatible = "starfive,jh7110-stgcrg";
-+ reg = <0x0 0x10230000 0x0 0x10000>;
-+ clocks = <&osc>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_USB_125M>,
-+ <&syscrg JH7110_SYSCLK_CPU_BUS>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>;
-+ clock-names = "osc", "hifi4_core",
-+ "stg_axiahb", "usb_125m",
-+ "cpu_bus", "hifi4_axi",
-+ "nocstg_bus", "apb_bus";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
- stg_syscon: syscon@10240000 {
- compatible = "starfive,jh7110-stg-syscon", "syscon";
- reg = <0x0 0x10240000 0x0 0x1000>;
-@@ -452,6 +591,45 @@
- status = "disabled";
- };
-
-+ ptc: pwm@120d0000 {
-+ compatible = "starfive,jh7110-pwm";
-+ reg = <0x0 0x120d0000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
-+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
-+ #pwm-cells=<3>;
-+ status = "disabled";
-+ };
-+
-+ sfctemp: temperature-sensor@120e0000 {
-+ compatible = "starfive,jh7110-temp";
-+ reg = <0x0 0x120e0000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_TEMP_CORE>,
-+ <&syscrg JH7110_SYSCLK_TEMP_APB>;
-+ clock-names = "sense", "bus";
-+ resets = <&syscrg JH7110_SYSRST_TEMP_CORE>,
-+ <&syscrg JH7110_SYSRST_TEMP_APB>;
-+ reset-names = "sense", "bus";
-+ #thermal-sensor-cells = <0>;
-+ };
-+
-+ qspi: spi@13010000 {
-+ compatible = "starfive,jh7110-qspi", "cdns,qspi-nor";
-+ reg = <0x0 0x13010000 0x0 0x10000
-+ 0x0 0x21000000 0x0 0x400000>;
-+ interrupts = <25>;
-+ clocks = <&syscrg JH7110_SYSCLK_QSPI_REF>,
-+ <&syscrg JH7110_SYSCLK_QSPI_AHB>,
-+ <&syscrg JH7110_SYSCLK_QSPI_APB>;
-+ clock-names = "qspi-ref", "qspi-ahb", "qspi-apb";
-+ resets = <&syscrg JH7110_SYSRST_QSPI_APB>,
-+ <&syscrg JH7110_SYSRST_QSPI_AHB>,
-+ <&syscrg JH7110_SYSRST_QSPI_REF>;
-+ reset-names = "qspi", "qspi-ocp", "rstc_ref";
-+ cdns,fifo-depth = <256>;
-+ cdns,fifo-width = <4>;
-+ cdns,trigger-address = <0x0>;
-+ };
-+
- syscrg: clock-controller@13020000 {
- compatible = "starfive,jh7110-syscrg";
- reg = <0x0 0x13020000 0x0 0x10000>;
-@@ -496,6 +674,107 @@
- #gpio-cells = <2>;
- };
-
-+ timer@13050000 {
-+ compatible = "starfive,jh7110-timer";
-+ reg = <0x0 0x13050000 0x0 0x10000>;
-+ interrupts = <69>, <70>, <71> ,<72>;
-+ clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>,
-+ <&syscrg JH7110_SYSCLK_TIMER0>,
-+ <&syscrg JH7110_SYSCLK_TIMER1>,
-+ <&syscrg JH7110_SYSCLK_TIMER2>,
-+ <&syscrg JH7110_SYSCLK_TIMER3>;
-+ clock-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ resets = <&syscrg JH7110_SYSRST_TIMER_APB>,
-+ <&syscrg JH7110_SYSRST_TIMER0>,
-+ <&syscrg JH7110_SYSRST_TIMER1>,
-+ <&syscrg JH7110_SYSRST_TIMER2>,
-+ <&syscrg JH7110_SYSRST_TIMER3>;
-+ reset-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ };
-+
-+ watchdog@13070000 {
-+ compatible = "starfive,jh7110-wdt";
-+ reg = <0x0 0x13070000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_WDT_APB>,
-+ <&syscrg JH7110_SYSCLK_WDT_CORE>;
-+ clock-names = "apb", "core";
-+ resets = <&syscrg JH7110_SYSRST_WDT_APB>,
-+ <&syscrg JH7110_SYSRST_WDT_CORE>;
-+ };
-+
-+ crypto: crypto@16000000 {
-+ compatible = "starfive,jh7110-crypto";
-+ reg = <0x0 0x16000000 0x0 0x4000>;
-+ clocks = <&stgcrg JH7110_STGCLK_SEC_AHB>,
-+ <&stgcrg JH7110_STGCLK_SEC_MISC_AHB>;
-+ clock-names = "hclk", "ahb";
-+ interrupts = <28>;
-+ resets = <&stgcrg JH7110_STGRST_SEC_AHB>;
-+ dmas = <&sdma 1 2>, <&sdma 0 2>;
-+ dma-names = "tx", "rx";
-+ status = "disabled";
-+ };
-+
-+ sdma: dma@16008000 {
-+ compatible = "arm,pl080", "arm,primecell";
-+ arm,primecell-periphid = <0x00041080>;
-+ reg = <0x0 0x16008000 0x0 0x4000>;
-+ interrupts = <29>;
-+ clocks = <&stgcrg JH7110_STGCLK_SEC_AHB>,
-+ <&stgcrg JH7110_STGCLK_SEC_MISC_AHB>;
-+ clock-names = "hclk", "apb_pclk";
-+ resets = <&stgcrg JH7110_STGRST_SEC_AHB>;
-+ lli-bus-interface-ahb1;
-+ mem-bus-interface-ahb1;
-+ memcpy-burst-size = <256>;
-+ memcpy-bus-width = <32>;
-+ #dma-cells = <2>;
-+ };
-+
-+ rng: rng@1600c000 {
-+ compatible = "starfive,jh7110-trng";
-+ reg = <0x0 0x1600C000 0x0 0x4000>;
-+ clocks = <&stgcrg JH7110_STGCLK_SEC_AHB>,
-+ <&stgcrg JH7110_STGCLK_SEC_MISC_AHB>;
-+ clock-names = "hclk", "ahb";
-+ resets = <&stgcrg JH7110_STGRST_SEC_AHB>;
-+ interrupts = <30>;
-+ };
-+
-+ mmc0: mmc@16010000 {
-+ compatible = "starfive,jh7110-mmc";
-+ reg = <0x0 0x16010000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_SDIO0_AHB>,
-+ <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
-+ clock-names = "biu","ciu";
-+ resets = <&syscrg JH7110_SYSRST_SDIO0_AHB>;
-+ reset-names = "reset";
-+ interrupts = <74>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ data-addr = <0>;
-+ starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
-+ status = "disabled";
-+ };
-+
-+ mmc1: mmc@16020000 {
-+ compatible = "starfive,jh7110-mmc";
-+ reg = <0x0 0x16020000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_SDIO1_AHB>,
-+ <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
-+ clock-names = "biu","ciu";
-+ resets = <&syscrg JH7110_SYSRST_SDIO1_AHB>;
-+ reset-names = "reset";
-+ interrupts = <75>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ data-addr = <0>;
-+ starfive,sysreg = <&sys_syscon 0x9c 0x1 0x3e>;
-+ status = "disabled";
-+ };
-+
- gmac0: ethernet@16030000 {
- compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
- reg = <0x0 0x16030000 0x0 0x10000>;
-@@ -558,6 +837,24 @@
- status = "disabled";
- };
-
-+ dma: dma-controller@16050000 {
-+ compatible = "starfive,jh7110-axi-dma";
-+ reg = <0x0 0x16050000 0x0 0x10000>;
-+ clocks = <&stgcrg JH7110_STGCLK_DMA1P_AXI>,
-+ <&stgcrg JH7110_STGCLK_DMA1P_AHB>;
-+ clock-names = "core-clk", "cfgr-clk";
-+ resets = <&stgcrg JH7110_STGRST_DMA1P_AXI>,
-+ <&stgcrg JH7110_STGRST_DMA1P_AHB>;
-+ interrupts = <73>;
-+ #dma-cells = <1>;
-+ dma-channels = <4>;
-+ snps,dma-masters = <1>;
-+ snps,data-width = <3>;
-+ snps,block-size = <65536 65536 65536 65536>;
-+ snps,priority = <0 1 2 3>;
-+ snps,axi-max-burst-len = <16>;
-+ };
-+
- aoncrg: clock-controller@17000000 {
- compatible = "starfive,jh7110-aoncrg";
- reg = <0x0 0x17000000 0x0 0x10000>;
-@@ -576,8 +873,9 @@
- };
-
- aon_syscon: syscon@17010000 {
-- compatible = "starfive,jh7110-aon-syscon", "syscon", "simple-mfd";
-+ compatible = "starfive,jh7110-aon-syscon", "syscon";
- reg = <0x0 0x17010000 0x0 0x1000>;
-+ #power-domain-cells = <1>;
- };
-
- aongpio: pinctrl@17020000 {
-@@ -590,5 +888,211 @@
- gpio-controller;
- #gpio-cells = <2>;
- };
-+
-+ pwrc: power-controller@17030000 {
-+ compatible = "starfive,jh7110-pmu";
-+ reg = <0x0 0x17030000 0x0 0x10000>;
-+ interrupts = <111>;
-+ #power-domain-cells = <1>;
-+ };
-+
-+ csi2rx: csi-bridge@19800000 {
-+ compatible = "starfive,jh7110-csi2rx";
-+ reg = <0x0 0x19800000 0x0 0x10000>;
-+ clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>,
-+ <&ispcrg JH7110_ISPCLK_VIN_APB>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>;
-+ clock-names = "sys_clk", "p_clk",
-+ "pixel_if0_clk", "pixel_if1_clk",
-+ "pixel_if2_clk", "pixel_if3_clk";
-+ resets = <&ispcrg JH7110_ISPRST_VIN_SYS>,
-+ <&ispcrg JH7110_ISPRST_VIN_APB>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>;
-+ reset-names = "sys", "reg_bank",
-+ "pixel_if0", "pixel_if1",
-+ "pixel_if2", "pixel_if3";
-+ phys = <&csi_phy>;
-+ phy-names = "dphy";
-+ status = "disabled";
-+ };
-+
-+ ispcrg: clock-controller@19810000 {
-+ compatible = "starfive,jh7110-ispcrg";
-+ reg = <0x0 0x19810000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
-+ <&dvp_clk>;
-+ clock-names = "isp_top_core", "isp_top_axi",
-+ "noc_bus_isp_axi", "dvp_clk";
-+ resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_ISP>;
-+ };
-+
-+ csi_phy: phy@19820000 {
-+ compatible = "starfive,jh7110-dphy-rx";
-+ reg = <0x0 0x19820000 0x0 0x10000>;
-+ clocks = <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
-+ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
-+ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>;
-+ clock-names = "cfg", "ref", "tx";
-+ resets = <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
-+ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>;
-+ power-domains = <&aon_syscon JH7110_PD_DPHY_RX>;
-+ #phy-cells = <0>;
-+ };
-+
-+ stfcamss: camss@19840000 {
-+ compatible = "starfive,jh7110-camss";
-+ reg = <0x0 0x19840000 0x0 0x10000>,
-+ <0x0 0x19870000 0x0 0x30000>;
-+ reg-names = "syscon", "isp";
-+ clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
-+ <&ispcrg JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C>,
-+ <&ispcrg JH7110_ISPCLK_DVP_INV>,
-+ <&ispcrg JH7110_ISPCLK_VIN_P_AXI_WR>,
-+ <&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>;
-+ clock-names = "clk_apb_func",
-+ "clk_wrapper_clk_c",
-+ "clk_dvp_inv",
-+ "clk_axiwr",
-+ "clk_mipi_rx0_pxl",
-+ "clk_ispcore_2x",
-+ "clk_isp_axi";
-+ resets = <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_P>,
-+ <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_C>,
-+ <&ispcrg JH7110_ISPRST_VIN_P_AXI_RD>,
-+ <&ispcrg JH7110_ISPRST_VIN_P_AXI_WR>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>;
-+ reset-names = "rst_wrapper_p",
-+ "rst_wrapper_c",
-+ "rst_axird",
-+ "rst_axiwr",
-+ "rst_isp_top_n",
-+ "rst_isp_top_axi";
-+ power-domains = <&pwrc JH7110_PD_ISP>;
-+ /* irq nr: vin, isp, isp_csi, isp_csiline */
-+ interrupts = <92>, <87>, <90>;
-+ status = "disabled";
-+ };
-+
-+ voutcrg: clock-controller@295c0000 {
-+ compatible = "starfive,jh7110-voutcrg";
-+ reg = <0x0 0x295c0000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
-+ <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
-+ <&hdmitx0_pixelclk>;
-+ clock-names = "vout_src", "vout_top_ahb",
-+ "vout_top_axi", "vout_top_hdmitx0_mclk",
-+ "i2stx0_bclk", "hdmitx0_pixelclk";
-+ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_VOUT>;
-+ };
-+
-+ pcie0: pcie@2B000000 {
-+ compatible = "starfive,jh7110-pcie";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ #interrupt-cells = <1>;
-+ reg = <0x0 0x2B000000 0x0 0x1000000
-+ 0x9 0x40000000 0x0 0x10000000>;
-+ reg-names = "reg", "config";
-+ device_type = "pci";
-+ starfive,stg-syscon = <&stg_syscon 0xc0 0xc4 0x130 0x1b8>;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
-+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
-+ interrupts = <56>;
-+ interrupt-parent = <&plic>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
-+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
-+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
-+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
-+ msi-parent = <&pcie0>;
-+ msi-controller;
-+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
-+ <&stgcrg JH7110_STGCLK_PCIE0_TL>,
-+ <&stgcrg JH7110_STGCLK_PCIE0_AXI_MST0>,
-+ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
-+ clock-names = "noc", "tl", "axi_mst0", "apb";
-+ resets = <&stgcrg JH7110_STGRST_PCIE0_AXI_MST0>,
-+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV0>,
-+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV>,
-+ <&stgcrg JH7110_STGRST_PCIE0_BRG>,
-+ <&stgcrg JH7110_STGRST_PCIE0_CORE>,
-+ <&stgcrg JH7110_STGRST_PCIE0_APB>;
-+ reset-names = "mst0", "slv0", "slv", "brg",
-+ "core", "apb";
-+ status = "disabled";
-+
-+ pcie_intc0: interrupt-controller {
-+ #address-cells = <0>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ };
-+ };
-+
-+ pcie1: pcie@2C000000 {
-+ compatible = "starfive,jh7110-pcie";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ #interrupt-cells = <1>;
-+ reg = <0x0 0x2C000000 0x0 0x1000000
-+ 0x9 0xc0000000 0x0 0x10000000>;
-+ reg-names = "reg", "config";
-+ device_type = "pci";
-+ starfive,stg-syscon = <&stg_syscon 0x270 0x274 0x2e0 0x368>;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>,
-+ <0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>;
-+ interrupts = <57>;
-+ interrupt-parent = <&plic>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc1 0x1>,
-+ <0x0 0x0 0x0 0x2 &pcie_intc1 0x2>,
-+ <0x0 0x0 0x0 0x3 &pcie_intc1 0x3>,
-+ <0x0 0x0 0x0 0x4 &pcie_intc1 0x4>;
-+ msi-parent = <&pcie1>;
-+ msi-controller;
-+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
-+ <&stgcrg JH7110_STGCLK_PCIE1_TL>,
-+ <&stgcrg JH7110_STGCLK_PCIE1_AXI_MST0>,
-+ <&stgcrg JH7110_STGCLK_PCIE1_APB>;
-+ clock-names = "noc", "tl", "axi_mst0", "apb";
-+ resets = <&stgcrg JH7110_STGRST_PCIE1_AXI_MST0>,
-+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV0>,
-+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV>,
-+ <&stgcrg JH7110_STGRST_PCIE1_BRG>,
-+ <&stgcrg JH7110_STGRST_PCIE1_CORE>,
-+ <&stgcrg JH7110_STGRST_PCIE1_APB>;
-+ reset-names = "mst0", "slv0", "slv", "brg",
-+ "core", "apb";
-+ status = "disabled";
-+
-+ pcie_intc1: interrupt-controller {
-+ #address-cells = <0>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ };
-+ };
- };
- };
diff --git a/target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch b/target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch
deleted file mode 100644
index d63efb93dd..0000000000
--- a/target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From d91e8a78ce8d6a1f60a3f5c16b4f7c013ba40257 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:56:22 -0700
-Subject: [PATCH 099/122] update jh7110_defconfig for test
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- arch/riscv/configs/jh7110_defconfig | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/arch/riscv/configs/jh7110_defconfig
-+++ b/arch/riscv/configs/jh7110_defconfig
-@@ -106,7 +106,6 @@ CONFIG_MMC=y
- # CONFIG_PWRSEQ_SIMPLE is not set
- CONFIG_MMC_DW=y
- # CONFIG_VIRTIO_MENU is not set
--CONFIG_CLK_STARFIVE_JH7110_AON=y
- # CONFIG_VHOST_MENU is not set
- # CONFIG_IOMMU_SUPPORT is not set
- CONFIG_BTRFS_FS=y
-@@ -160,6 +159,19 @@ CONFIG_PCI=y
- CONFIG_USB_CDNS3_STARFIVE=y
- CONFIG_PHY_STARFIVE_JH7110_PCIE=y
- CONFIG_PHY_STARFIVE_JH7110_USB=y
-+CONFIG_USB_XHCI_HCD=y
-+CONFIG_USB_EHCI_HCD=y
-+CONFIG_USB_EHCI_HCD_PLATFORM=y
-+CONFIG_USB_OHCI_HCD=y
-+CONFIG_USB_OHCI_HCD_PLATFORM=y
-+CONFIG_SCSI=y
-+CONFIG_USB_STORAGE=y
-+CONFIG_USB_UAS=y
-+CONFIG_USB_CDNS3_GADGET=y
-+CONFIG_USB_CDNS3_HOST=y
-+CONFIG_USB_GADGET=y
-+CONFIG_USB_CONFIGFS=y
-+CONFIG_USB_CONFIGFS_F_FS=y
- CONFIG_USB_CDNS_SUPPORT=y
- CONFIG_USB_CDNS3=y
- CONFIG_USB=y
-@@ -177,6 +189,7 @@ CONFIG_CRYPTO_HW=y
- CONFIG_CRYPTO=y
- CONFIG_SND_SOC_JH7110_TDM=y
- CONFIG_SND_SOC_STARFIVE=y
-+CONFIG_SND_SIMPLE_CARD=y
- CONFIG_SND_SOC=y
- CONFIG_SND=y
- CONFIG_SOUND=y
diff --git a/target/linux/starfive/patches-6.1/0100-Add-readme.patch b/target/linux/starfive/patches-6.1/0100-Add-readme.patch
deleted file mode 100644
index 82db368796..0000000000
--- a/target/linux/starfive/patches-6.1/0100-Add-readme.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 13c570f2350f59a7994c26a51f749a50fa9b4726 Mon Sep 17 00:00:00 2001
-From: Hal Feng <87058983+hal-feng@users.noreply.github.com>
-Date: Tue, 20 Dec 2022 16:18:35 +0800
-Subject: [PATCH 100/122] Add readme
-
----
- README.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 62 insertions(+)
- create mode 100644 README.md
-
---- /dev/null
-+++ b/README.md
-@@ -0,0 +1,62 @@
-+## JH7110 Upstream Status ##
-+
-+To get the latest status of each upstreaming patch series, please visit
-+our RVspace.
-+
-+https://rvspace.org/en/project/JH7110_Upstream_Plan
-+
-+## Build Instructions ##
-+
-+1. Configure Kconfig options
-+
-+```shell
-+# Use default selections
-+make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
-+```
-+
-+or
-+
-+```shell
-+# Select options manually
-+make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- nconfig
-+```
-+
-+To boot up the VisionFive 2 board, please make sure **SOC_STARFIVE**,
-+**CLK_STARFIVE_JH7110_SYS**, **PINCTRL_STARFIVE_JH7110_SYS**,
-+**SERIAL_8250_DW** are selected.
-+> If you need MMC and GMAC drivers, you should also select
-+**MMC_DW_STARFIVE** and **DWMAC_STARFIVE**.
-+
-+2. Build
-+```shell
-+make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu-
-+```
-+
-+## How to Run on VisionFive 2 Board via Network ##
-+
-+1. Power on, enter u-boot and set enviroment parameters
-+```
-+setenv fdt_high 0xffffffffffffffff; setenv initrd_high 0xffffffffffffffff;
-+setenv scriptaddr 0x88100000; setenv script_offset_f 0x1fff000; setenv script_size_f 0x1000;
-+setenv kernel_addr_r 0x84000000; setenv kernel_comp_addr_r 0x90000000; setenv kernel_comp_size 0x10000000;
-+setenv fdt_addr_r 0x88000000; setenv ramdisk_addr_r 0x88300000;
-+```
-+2. Set IP addresses for the board and your tftp server
-+```
-+setenv serverip 192.168.w.x; setenv gatewayip 192.168.w.y; setenv ipaddr 192.168.w.z; setenv hostname starfive; setenv netdev eth0;
-+```
-+3. Upload dtb, image and file system to DDR from your tftp server
-+```
-+tftpboot ${fdt_addr_r} jh7110-starfive-visionfive-2-v1.3b.dtb; tftpboot ${kernel_addr_r} Image.gz; tftpboot ${ramdisk_addr_r} initramfs.cpio.gz;
-+```
-+> If your VisionFive 2 is v1.2A, you should upload jh7110-starfive-visionfive-2-v1.2a.dtb instead.
-+4. Load and boot the kernel
-+```
-+booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r};
-+```
-+When you see the message "buildroot login:", the launch was successful.
-+You can just input the following accout and password, then continue.
-+```
-+buildroot login: root
-+Password: starfive
-+```
diff --git a/target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch b/target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch
deleted file mode 100644
index 60cb6cc433..0000000000
--- a/target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 0b99a4626c7e148df128c6a8cb686d500431189b Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Tue, 17 Jan 2023 09:54:43 +0800
-Subject: [PATCH 101/122] dt-bindings: rng: Add StarFive TRNG module
-
-Add documentation to describe Starfive true random number generator
-module.
-
-Co-developed-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../bindings/rng/starfive,jh7110-trng.yaml | 55 +++++++++++++++++++
- 1 file changed, 55 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml
-@@ -0,0 +1,55 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/rng/starfive,jh7110-trng.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive SoC TRNG Module
-+
-+maintainers:
-+ - Jia Jie Ho <jiajie.ho@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-trng
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Hardware reference clock
-+ - description: AHB reference clock
-+
-+ clock-names:
-+ items:
-+ - const: hclk
-+ - const: ahb
-+
-+ resets:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - interrupts
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ rng: rng@1600C000 {
-+ compatible = "starfive,jh7110-trng";
-+ reg = <0x1600C000 0x4000>;
-+ clocks = <&clk 15>, <&clk 16>;
-+ clock-names = "hclk", "ahb";
-+ resets = <&reset 3>;
-+ interrupts = <30>;
-+ };
-+...
diff --git a/target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch b/target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch
deleted file mode 100644
index 1ab18838e6..0000000000
--- a/target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch
+++ /dev/null
@@ -1,457 +0,0 @@
-From 99a7ca1d1320288efc5b4532ce4ea637d622aa00 Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Tue, 17 Jan 2023 09:54:44 +0800
-Subject: [PATCH 102/122] hwrng: starfive - Add TRNG driver for StarFive SoC
-
-This adds driver support for the hardware random number generator in
-Starfive SoCs and adds StarFive TRNG entry to MAINTAINERS.
-
-Co-developed-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
----
- MAINTAINERS | 6 +
- drivers/char/hw_random/Kconfig | 11 +
- drivers/char/hw_random/Makefile | 1 +
- drivers/char/hw_random/jh7110-trng.c | 393 +++++++++++++++++++++++++++
- 4 files changed, 411 insertions(+)
- create mode 100644 drivers/char/hw_random/jh7110-trng.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19716,6 +19716,12 @@ F: Documentation/devicetree/bindings/pow
- F: drivers/soc/starfive/jh71xx_pmu.c
- F: include/dt-bindings/power/starfive,jh7110-pmu.h
-
-+STARFIVE TRNG DRIVER
-+M: Jia Jie Ho <jiajie.ho@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/rng/starfive*
-+F: drivers/char/hw_random/starfive-trng.c
-+
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
- M: Josh Poimboeuf <jpoimboe@kernel.org>
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -549,6 +549,17 @@ config HW_RANDOM_CN10K
- To compile this driver as a module, choose M here.
- The module will be called cn10k_rng. If unsure, say Y.
-
-+config HW_RANDOM_JH7110
-+ tristate "StarFive JH7110 Random Number Generator support"
-+ depends on SOC_STARFIVE
-+ depends on HW_RANDOM
-+ help
-+ This driver provides support for the True Random Number
-+ Generator in StarFive JH7110 SoCs.
-+
-+ To compile this driver as a module, choose M here.
-+ The module will be called jh7110-trng.
-+
- endif # HW_RANDOM
-
- config UML_RANDOM
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -47,3 +47,4 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphe
- obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
- obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
- obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
-+obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
---- /dev/null
-+++ b/drivers/char/hw_random/jh7110-trng.c
-@@ -0,0 +1,393 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * TRNG driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/hw_random.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/random.h>
-+#include <linux/reset.h>
-+
-+/* trng register offset */
-+#define STARFIVE_CTRL 0x00
-+#define STARFIVE_STAT 0x04
-+#define STARFIVE_MODE 0x08
-+#define STARFIVE_SMODE 0x0C
-+#define STARFIVE_IE 0x10
-+#define STARFIVE_ISTAT 0x14
-+#define STARFIVE_RAND0 0x20
-+#define STARFIVE_RAND1 0x24
-+#define STARFIVE_RAND2 0x28
-+#define STARFIVE_RAND3 0x2C
-+#define STARFIVE_RAND4 0x30
-+#define STARFIVE_RAND5 0x34
-+#define STARFIVE_RAND6 0x38
-+#define STARFIVE_RAND7 0x3C
-+#define STARFIVE_AUTO_RQSTS 0x60
-+#define STARFIVE_AUTO_AGE 0x64
-+
-+/* CTRL CMD */
-+#define STARFIVE_CTRL_EXEC_NOP 0x0
-+#define STARFIVE_CTRL_GENE_RANDNUM 0x1
-+#define STARFIVE_CTRL_EXEC_RANDRESEED 0x2
-+
-+/* STAT */
-+#define STARFIVE_STAT_NONCE_MODE BIT(2)
-+#define STARFIVE_STAT_R256 BIT(3)
-+#define STARFIVE_STAT_MISSION_MODE BIT(8)
-+#define STARFIVE_STAT_SEEDED BIT(9)
-+#define STARFIVE_STAT_LAST_RESEED(x) ((x) << 16)
-+#define STARFIVE_STAT_SRVC_RQST BIT(27)
-+#define STARFIVE_STAT_RAND_GENERATING BIT(30)
-+#define STARFIVE_STAT_RAND_SEEDING BIT(31)
-+
-+/* MODE */
-+#define STARFIVE_MODE_R256 BIT(3)
-+
-+/* SMODE */
-+#define STARFIVE_SMODE_NONCE_MODE BIT(2)
-+#define STARFIVE_SMODE_MISSION_MODE BIT(8)
-+#define STARFIVE_SMODE_MAX_REJECTS(x) ((x) << 16)
-+
-+/* IE */
-+#define STARFIVE_IE_RAND_RDY_EN BIT(0)
-+#define STARFIVE_IE_SEED_DONE_EN BIT(1)
-+#define STARFIVE_IE_LFSR_LOCKUP_EN BIT(4)
-+#define STARFIVE_IE_GLBL_EN BIT(31)
-+
-+#define STARFIVE_IE_ALL (STARFIVE_IE_GLBL_EN | \
-+ STARFIVE_IE_RAND_RDY_EN | \
-+ STARFIVE_IE_SEED_DONE_EN | \
-+ STARFIVE_IE_LFSR_LOCKUP_EN)
-+
-+/* ISTAT */
-+#define STARFIVE_ISTAT_RAND_RDY BIT(0)
-+#define STARFIVE_ISTAT_SEED_DONE BIT(1)
-+#define STARFIVE_ISTAT_LFSR_LOCKUP BIT(4)
-+
-+#define STARFIVE_RAND_LEN sizeof(u32)
-+
-+#define to_trng(p) container_of(p, struct starfive_trng, rng)
-+
-+enum reseed {
-+ RANDOM_RESEED,
-+ NONCE_RESEED,
-+};
-+
-+enum mode {
-+ PRNG_128BIT,
-+ PRNG_256BIT,
-+};
-+
-+struct starfive_trng {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct clk *hclk;
-+ struct clk *ahb;
-+ struct reset_control *rst;
-+ struct hwrng rng;
-+ struct completion random_done;
-+ struct completion reseed_done;
-+ u32 mode;
-+ u32 mission;
-+ u32 reseed;
-+ /* protects against concurrent write to ctrl register */
-+ spinlock_t write_lock;
-+};
-+
-+static u16 autoreq;
-+module_param(autoreq, ushort, 0);
-+MODULE_PARM_DESC(autoreq, "Auto-reseeding after random number requests by host reaches specified counter:\n"
-+ " 0 - disable counter\n"
-+ " other - reload value for internal counter");
-+
-+static u16 autoage;
-+module_param(autoage, ushort, 0);
-+MODULE_PARM_DESC(autoage, "Auto-reseeding after specified timer countdowns to 0:\n"
-+ " 0 - disable timer\n"
-+ " other - reload value for internal timer");
-+
-+static inline int starfive_trng_wait_idle(struct starfive_trng *trng)
-+{
-+ u32 stat;
-+
-+ return readl_relaxed_poll_timeout(trng->base + STARFIVE_STAT, stat,
-+ !(stat & (STARFIVE_STAT_RAND_GENERATING |
-+ STARFIVE_STAT_RAND_SEEDING)),
-+ 10, 100000);
-+}
-+
-+static inline void starfive_trng_irq_mask_clear(struct starfive_trng *trng)
-+{
-+ /* clear register: ISTAT */
-+ u32 data = readl(trng->base + STARFIVE_ISTAT);
-+
-+ writel(data, trng->base + STARFIVE_ISTAT);
-+}
-+
-+static int starfive_trng_cmd(struct starfive_trng *trng, u32 cmd, bool wait)
-+{
-+ int wait_time = 1000;
-+
-+ /* allow up to 40 us for wait == 0 */
-+ if (!wait)
-+ wait_time = 40;
-+
-+ switch (cmd) {
-+ case STARFIVE_CTRL_GENE_RANDNUM:
-+ reinit_completion(&trng->random_done);
-+ spin_lock_irq(&trng->write_lock);
-+ writel(cmd, trng->base + STARFIVE_CTRL);
-+ spin_unlock_irq(&trng->write_lock);
-+ if (!wait_for_completion_timeout(&trng->random_done, usecs_to_jiffies(wait_time)))
-+ return -ETIMEDOUT;
-+ break;
-+ case STARFIVE_CTRL_EXEC_RANDRESEED:
-+ reinit_completion(&trng->reseed_done);
-+ spin_lock_irq(&trng->write_lock);
-+ writel(cmd, trng->base + STARFIVE_CTRL);
-+ spin_unlock_irq(&trng->write_lock);
-+ if (!wait_for_completion_timeout(&trng->reseed_done, usecs_to_jiffies(wait_time)))
-+ return -ETIMEDOUT;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int starfive_trng_init(struct hwrng *rng)
-+{
-+ struct starfive_trng *trng = to_trng(rng);
-+ u32 mode, intr = 0;
-+
-+ /* setup Auto Request/Age register */
-+ writel(autoage, trng->base + STARFIVE_AUTO_AGE);
-+ writel(autoreq, trng->base + STARFIVE_AUTO_RQSTS);
-+
-+ /* clear register: ISTAT */
-+ starfive_trng_irq_mask_clear(trng);
-+
-+ intr |= STARFIVE_IE_ALL;
-+ writel(intr, trng->base + STARFIVE_IE);
-+
-+ mode = readl(trng->base + STARFIVE_MODE);
-+
-+ switch (trng->mode) {
-+ case PRNG_128BIT:
-+ mode &= ~STARFIVE_MODE_R256;
-+ break;
-+ case PRNG_256BIT:
-+ mode |= STARFIVE_MODE_R256;
-+ break;
-+ default:
-+ mode |= STARFIVE_MODE_R256;
-+ break;
-+ }
-+
-+ writel(mode, trng->base + STARFIVE_MODE);
-+
-+ return starfive_trng_cmd(trng, STARFIVE_CTRL_EXEC_RANDRESEED, 1);
-+}
-+
-+static irqreturn_t starfive_trng_irq(int irq, void *priv)
-+{
-+ u32 status;
-+ struct starfive_trng *trng = (struct starfive_trng *)priv;
-+
-+ status = readl(trng->base + STARFIVE_ISTAT);
-+ if (status & STARFIVE_ISTAT_RAND_RDY) {
-+ writel(STARFIVE_ISTAT_RAND_RDY, trng->base + STARFIVE_ISTAT);
-+ complete(&trng->random_done);
-+ }
-+
-+ if (status & STARFIVE_ISTAT_SEED_DONE) {
-+ writel(STARFIVE_ISTAT_SEED_DONE, trng->base + STARFIVE_ISTAT);
-+ complete(&trng->reseed_done);
-+ }
-+
-+ if (status & STARFIVE_ISTAT_LFSR_LOCKUP) {
-+ writel(STARFIVE_ISTAT_LFSR_LOCKUP, trng->base + STARFIVE_ISTAT);
-+ /* SEU occurred, reseeding required*/
-+ spin_lock(&trng->write_lock);
-+ writel(STARFIVE_CTRL_EXEC_RANDRESEED, trng->base + STARFIVE_CTRL);
-+ spin_unlock(&trng->write_lock);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void starfive_trng_cleanup(struct hwrng *rng)
-+{
-+ struct starfive_trng *trng = to_trng(rng);
-+
-+ writel(0, trng->base + STARFIVE_CTRL);
-+
-+ reset_control_assert(trng->rst);
-+ clk_disable_unprepare(trng->hclk);
-+ clk_disable_unprepare(trng->ahb);
-+}
-+
-+static int starfive_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-+{
-+ struct starfive_trng *trng = to_trng(rng);
-+ int ret;
-+
-+ pm_runtime_get_sync(trng->dev);
-+
-+ if (trng->mode == PRNG_256BIT)
-+ max = min_t(size_t, max, (STARFIVE_RAND_LEN * 8));
-+ else
-+ max = min_t(size_t, max, (STARFIVE_RAND_LEN * 4));
-+
-+ if (wait) {
-+ ret = starfive_trng_wait_idle(trng);
-+ if (ret)
-+ return -ETIMEDOUT;
-+ }
-+
-+ ret = starfive_trng_cmd(trng, STARFIVE_CTRL_GENE_RANDNUM, wait);
-+ if (ret)
-+ return ret;
-+
-+ memcpy_fromio(buf, trng->base + STARFIVE_RAND0, max);
-+
-+ pm_runtime_put_sync_autosuspend(trng->dev);
-+
-+ return max;
-+}
-+
-+static int starfive_trng_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int irq;
-+ struct starfive_trng *trng;
-+
-+ trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
-+ if (!trng)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, trng);
-+ trng->dev = &pdev->dev;
-+
-+ trng->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(trng->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->base),
-+ "Error remapping memory for platform device.\n");
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0)
-+ return irq;
-+
-+ init_completion(&trng->random_done);
-+ init_completion(&trng->reseed_done);
-+ spin_lock_init(&trng->write_lock);
-+
-+ ret = devm_request_irq(&pdev->dev, irq, starfive_trng_irq, 0, pdev->name,
-+ (void *)trng);
-+ if (ret)
-+ return dev_err_probe(&pdev->dev, irq,
-+ "Failed to register interrupt handler\n");
-+
-+ trng->hclk = devm_clk_get(&pdev->dev, "hclk");
-+ if (IS_ERR(trng->hclk))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->hclk),
-+ "Error getting hardware reference clock\n");
-+
-+ trng->ahb = devm_clk_get(&pdev->dev, "ahb");
-+ if (IS_ERR(trng->ahb))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->ahb),
-+ "Error getting ahb reference clock\n");
-+
-+ trng->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
-+ if (IS_ERR(trng->rst))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->rst),
-+ "Error getting hardware reset line\n");
-+
-+ clk_prepare_enable(trng->hclk);
-+ clk_prepare_enable(trng->ahb);
-+ reset_control_deassert(trng->rst);
-+
-+ trng->rng.name = dev_driver_string(&pdev->dev);
-+ trng->rng.init = starfive_trng_init;
-+ trng->rng.cleanup = starfive_trng_cleanup;
-+ trng->rng.read = starfive_trng_read;
-+
-+ trng->mode = PRNG_256BIT;
-+ trng->mission = 1;
-+ trng->reseed = RANDOM_RESEED;
-+
-+ pm_runtime_use_autosuspend(&pdev->dev);
-+ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
-+ pm_runtime_enable(&pdev->dev);
-+
-+ ret = devm_hwrng_register(&pdev->dev, &trng->rng);
-+ if (ret) {
-+ pm_runtime_disable(&pdev->dev);
-+
-+ reset_control_assert(trng->rst);
-+ clk_disable_unprepare(trng->ahb);
-+ clk_disable_unprepare(trng->hclk);
-+
-+ return dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused starfive_trng_suspend(struct device *dev)
-+{
-+ struct starfive_trng *trng = dev_get_drvdata(dev);
-+
-+ clk_disable_unprepare(trng->hclk);
-+ clk_disable_unprepare(trng->ahb);
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused starfive_trng_resume(struct device *dev)
-+{
-+ struct starfive_trng *trng = dev_get_drvdata(dev);
-+
-+ clk_prepare_enable(trng->hclk);
-+ clk_prepare_enable(trng->ahb);
-+
-+ return 0;
-+}
-+
-+static DEFINE_SIMPLE_DEV_PM_OPS(starfive_trng_pm_ops, starfive_trng_suspend,
-+ starfive_trng_resume);
-+
-+static const struct of_device_id trng_dt_ids[] __maybe_unused = {
-+ { .compatible = "starfive,jh7110-trng" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, trng_dt_ids);
-+
-+static struct platform_driver starfive_trng_driver = {
-+ .probe = starfive_trng_probe,
-+ .driver = {
-+ .name = "jh7110-trng",
-+ .pm = &starfive_trng_pm_ops,
-+ .of_match_table = of_match_ptr(trng_dt_ids),
-+ },
-+};
-+
-+module_platform_driver(starfive_trng_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("StarFive True Random Number Generator");
diff --git a/target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch b/target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch
deleted file mode 100644
index 39b4bc6ad9..0000000000
--- a/target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 4b02d00911c2e6bd31d8160b0337174dd55dc644 Mon Sep 17 00:00:00 2001
-From: Herbert Xu <herbert@gondor.apana.org.au>
-Date: Fri, 27 Jan 2023 19:03:21 +0800
-Subject: [PATCH 103/122] hwrng: starfive - Enable compile testing
-
-Enable compile testing for jh7110. Also remove the dependency on
-HW_RANDOM.
-
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- drivers/char/hw_random/Kconfig | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -551,8 +551,7 @@ config HW_RANDOM_CN10K
-
- config HW_RANDOM_JH7110
- tristate "StarFive JH7110 Random Number Generator support"
-- depends on SOC_STARFIVE
-- depends on HW_RANDOM
-+ depends on SOC_STARFIVE || COMPILE_TEST
- help
- This driver provides support for the True Random Number
- Generator in StarFive JH7110 SoCs.
diff --git a/target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch b/target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch
deleted file mode 100644
index f68232f035..0000000000
--- a/target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 8559b2db6aecbee62cf9e02c17349379d72edcfb Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 21:24:35 +0800
-Subject: [PATCH 104/122] dt-bindings: watchdog: Add watchdog for StarFive
- JH7100 and JH7110
-
-Add bindings to describe the watchdog for the StarFive JH7100/JH7110 SoC.
-And Use JH7100 as first StarFive SoC with watchdog.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
----
- .../watchdog/starfive,jh7100-wdt.yaml | 71 +++++++++++++++++++
- 1 file changed, 71 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
-@@ -0,0 +1,71 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/watchdog/starfive,jh7100-wdt.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive Watchdog for JH7100 and JH7110 SoC
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+ - Samin Guo <samin.guo@starfivetech.com>
-+
-+description:
-+ The JH7100 and JH7110 watchdog both are 32 bit counters. JH7100 watchdog
-+ has only one timeout phase and reboots. And JH7110 watchdog has two
-+ timeout phases. At the first phase, the signal of watchdog interrupt
-+ output(WDOGINT) will rise when counter is 0. The counter will reload
-+ the timeout value. And then, if counter decreases to 0 again and WDOGINT
-+ isn't cleared, the watchdog will reset the system unless the watchdog
-+ reset is disabled.
-+
-+allOf:
-+ - $ref: watchdog.yaml#
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7100-wdt
-+ - starfive,jh7110-wdt
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: APB clock
-+ - description: Core clock
-+
-+ clock-names:
-+ items:
-+ - const: apb
-+ - const: core
-+
-+ resets:
-+ items:
-+ - description: APB reset
-+ - description: Core reset
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ watchdog@12480000 {
-+ compatible = "starfive,jh7100-wdt";
-+ reg = <0x12480000 0x10000>;
-+ clocks = <&clk 171>,
-+ <&clk 172>;
-+ clock-names = "apb", "core";
-+ resets = <&rst 99>,
-+ <&rst 100>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch b/target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch
deleted file mode 100644
index d7113de0ec..0000000000
--- a/target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch
+++ /dev/null
@@ -1,675 +0,0 @@
-From e835861823130ae47665db5e8039a7097ede14e4 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 21:24:36 +0800
-Subject: [PATCH 105/122] drivers: watchdog: Add StarFive Watchdog driver
-
-Add watchdog driver for the StarFive JH7100 and JH7110 SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
----
- MAINTAINERS | 7 +
- drivers/watchdog/Kconfig | 11 +
- drivers/watchdog/Makefile | 3 +
- drivers/watchdog/starfive-wdt.c | 606 ++++++++++++++++++++++++++++++++
- 4 files changed, 627 insertions(+)
- create mode 100644 drivers/watchdog/starfive-wdt.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19722,6 +19722,13 @@ S: Supported
- F: Documentation/devicetree/bindings/rng/starfive*
- F: drivers/char/hw_random/starfive-trng.c
-
-+STARFIVE WATCHDOG DRIVER
-+M: Xingyu Wu <xingyu.wu@starfivetech.com>
-+M: Samin Guo <samin.guo@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/watchdog/starfive*
-+F: drivers/watchdog/starfive-wdt.c
-+
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
- M: Josh Poimboeuf <jpoimboe@kernel.org>
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -1991,6 +1991,17 @@ config WATCHDOG_RTAS
- To compile this driver as a module, choose M here. The module
- will be called wdrtas.
-
-+# RISC-V Architecture
-+
-+config STARFIVE_WATCHDOG
-+ tristate "StarFive Watchdog support"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ select WATCHDOG_CORE
-+ default ARCH_STARFIVE
-+ help
-+ Say Y here to support the watchdog of StarFive JH7100 and JH7110
-+ SoC. This driver can also be built as a module if choose M.
-+
- # S390 Architecture
-
- config DIAG288_WATCHDOG
---- a/drivers/watchdog/Makefile
-+++ b/drivers/watchdog/Makefile
-@@ -191,6 +191,9 @@ obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.
- obj-$(CONFIG_PSERIES_WDT) += pseries-wdt.o
- obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
-
-+# RISC-V Architecture
-+obj-$(CONFIG_STARFIVE_WATCHDOG) += starfive-wdt.o
-+
- # S390 Architecture
- obj-$(CONFIG_DIAG288_WATCHDOG) += diag288_wdt.o
-
---- /dev/null
-+++ b/drivers/watchdog/starfive-wdt.c
-@@ -0,0 +1,606 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Starfive Watchdog driver
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+#include <linux/watchdog.h>
-+
-+/* JH7100 Watchdog register define */
-+#define STARFIVE_WDT_JH7100_INTSTAUS 0x000
-+#define STARFIVE_WDT_JH7100_CONTROL 0x104
-+#define STARFIVE_WDT_JH7100_LOAD 0x108
-+#define STARFIVE_WDT_JH7100_EN 0x110
-+#define STARFIVE_WDT_JH7100_RELOAD 0x114 /* Write 0 or 1 to reload preset value */
-+#define STARFIVE_WDT_JH7100_VALUE 0x118
-+#define STARFIVE_WDT_JH7100_INTCLR 0x120 /*
-+ * [0]: Write 1 to clear interrupt
-+ * [1]: 1 mean clearing and 0 mean complete
-+ * [31:2]: reserved.
-+ */
-+#define STARFIVE_WDT_JH7100_LOCK 0x13c /* write 0x378f0765 to unlock */
-+
-+/* JH7110 Watchdog register define */
-+#define STARFIVE_WDT_JH7110_LOAD 0x000
-+#define STARFIVE_WDT_JH7110_VALUE 0x004
-+#define STARFIVE_WDT_JH7110_CONTROL 0x008 /*
-+ * [0]: reset enable;
-+ * [1]: interrupt enable && watchdog enable
-+ * [31:2]: reserved.
-+ */
-+#define STARFIVE_WDT_JH7110_INTCLR 0x00c /* clear intterupt and reload the counter */
-+#define STARFIVE_WDT_JH7110_IMS 0x014
-+#define STARFIVE_WDT_JH7110_LOCK 0xc00 /* write 0x1ACCE551 to unlock */
-+
-+/* WDOGCONTROL */
-+#define STARFIVE_WDT_ENABLE 0x1
-+#define STARFIVE_WDT_EN_SHIFT 0
-+#define STARFIVE_WDT_RESET_EN 0x1
-+#define STARFIVE_WDT_JH7100_RST_EN_SHIFT 0
-+#define STARFIVE_WDT_JH7110_RST_EN_SHIFT 1
-+
-+/* WDOGLOCK */
-+#define STARFIVE_WDT_JH7100_UNLOCK_KEY 0x378f0765
-+#define STARFIVE_WDT_JH7110_UNLOCK_KEY 0x1acce551
-+
-+/* WDOGINTCLR */
-+#define STARFIVE_WDT_INTCLR 0x1
-+#define STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT 1 /* Watchdog can clear interrupt when 0 */
-+
-+#define STARFIVE_WDT_MAXCNT 0xffffffff
-+#define STARFIVE_WDT_DEFAULT_TIME (15)
-+#define STARFIVE_WDT_DELAY_US 0
-+#define STARFIVE_WDT_TIMEOUT_US 10000
-+
-+/* module parameter */
-+#define STARFIVE_WDT_EARLY_ENA 0
-+
-+static bool nowayout = WATCHDOG_NOWAYOUT;
-+static int heartbeat;
-+static bool early_enable = STARFIVE_WDT_EARLY_ENA;
-+
-+module_param(heartbeat, int, 0);
-+module_param(early_enable, bool, 0);
-+module_param(nowayout, bool, 0);
-+
-+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default="
-+ __MODULE_STRING(STARFIVE_WDT_DEFAULT_TIME) ")");
-+MODULE_PARM_DESC(early_enable,
-+ "Watchdog is started at boot time if set to 1, default="
-+ __MODULE_STRING(STARFIVE_WDT_EARLY_ENA));
-+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
-+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-+
-+struct starfive_wdt_variant {
-+ unsigned int control; /* Watchdog Control Resgister for reset enable */
-+ unsigned int load; /* Watchdog Load register */
-+ unsigned int reload; /* Watchdog Reload Control register */
-+ unsigned int enable; /* Watchdog Enable Register */
-+ unsigned int value; /* Watchdog Counter Value Register */
-+ unsigned int int_clr; /* Watchdog Interrupt Clear Register */
-+ unsigned int unlock; /* Watchdog Lock Register */
-+ unsigned int int_status; /* Watchdog Interrupt Status Register */
-+
-+ u32 unlock_key;
-+ char enrst_shift;
-+ char en_shift;
-+ bool intclr_check; /* whether need to check it before clearing interrupt */
-+ char intclr_ava_shift;
-+ bool double_timeout; /* The watchdog need twice timeout to reboot */
-+};
-+
-+struct starfive_wdt {
-+ struct watchdog_device wdd;
-+ spinlock_t lock; /* spinlock for register handling */
-+ void __iomem *base;
-+ struct clk *core_clk;
-+ struct clk *apb_clk;
-+ const struct starfive_wdt_variant *variant;
-+ unsigned long freq;
-+ u32 count; /* count of timeout */
-+ u32 reload; /* restore the count */
-+};
-+
-+/* Register layout and configuration for the JH7100 */
-+static const struct starfive_wdt_variant starfive_wdt_jh7100_variant = {
-+ .control = STARFIVE_WDT_JH7100_CONTROL,
-+ .load = STARFIVE_WDT_JH7100_LOAD,
-+ .reload = STARFIVE_WDT_JH7100_RELOAD,
-+ .enable = STARFIVE_WDT_JH7100_EN,
-+ .value = STARFIVE_WDT_JH7100_VALUE,
-+ .int_clr = STARFIVE_WDT_JH7100_INTCLR,
-+ .unlock = STARFIVE_WDT_JH7100_LOCK,
-+ .unlock_key = STARFIVE_WDT_JH7100_UNLOCK_KEY,
-+ .int_status = STARFIVE_WDT_JH7100_INTSTAUS,
-+ .enrst_shift = STARFIVE_WDT_JH7100_RST_EN_SHIFT,
-+ .en_shift = STARFIVE_WDT_EN_SHIFT,
-+ .intclr_check = true,
-+ .intclr_ava_shift = STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT,
-+ .double_timeout = false,
-+};
-+
-+/* Register layout and configuration for the JH7110 */
-+static const struct starfive_wdt_variant starfive_wdt_jh7110_variant = {
-+ .control = STARFIVE_WDT_JH7110_CONTROL,
-+ .load = STARFIVE_WDT_JH7110_LOAD,
-+ .enable = STARFIVE_WDT_JH7110_CONTROL,
-+ .value = STARFIVE_WDT_JH7110_VALUE,
-+ .int_clr = STARFIVE_WDT_JH7110_INTCLR,
-+ .unlock = STARFIVE_WDT_JH7110_LOCK,
-+ .unlock_key = STARFIVE_WDT_JH7110_UNLOCK_KEY,
-+ .int_status = STARFIVE_WDT_JH7110_IMS,
-+ .enrst_shift = STARFIVE_WDT_JH7110_RST_EN_SHIFT,
-+ .en_shift = STARFIVE_WDT_EN_SHIFT,
-+ .intclr_check = false,
-+ .double_timeout = true,
-+};
-+
-+static int starfive_wdt_enable_clock(struct starfive_wdt *wdt)
-+{
-+ int ret;
-+
-+ ret = clk_prepare_enable(wdt->apb_clk);
-+ if (ret)
-+ return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n");
-+
-+ ret = clk_prepare_enable(wdt->core_clk);
-+ if (ret)
-+ return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n");
-+
-+ return 0;
-+}
-+
-+static void starfive_wdt_disable_clock(struct starfive_wdt *wdt)
-+{
-+ clk_disable_unprepare(wdt->core_clk);
-+ clk_disable_unprepare(wdt->apb_clk);
-+}
-+
-+static inline int starfive_wdt_get_clock(struct starfive_wdt *wdt)
-+{
-+ struct device *dev = wdt->wdd.parent;
-+
-+ wdt->apb_clk = devm_clk_get(dev, "apb");
-+ if (IS_ERR(wdt->apb_clk))
-+ return dev_err_probe(dev, PTR_ERR(wdt->apb_clk), "failed to get apb clock\n");
-+
-+ wdt->core_clk = devm_clk_get(dev, "core");
-+ if (IS_ERR(wdt->core_clk))
-+ return dev_err_probe(dev, PTR_ERR(wdt->core_clk), "failed to get core clock\n");
-+
-+ return 0;
-+}
-+
-+static inline int starfive_wdt_reset_init(struct device *dev)
-+{
-+ struct reset_control *rsts;
-+ int ret;
-+
-+ rsts = devm_reset_control_array_get_exclusive(dev);
-+ if (IS_ERR(rsts))
-+ return dev_err_probe(dev, PTR_ERR(rsts), "failed to get resets\n");
-+
-+ ret = reset_control_deassert(rsts);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "failed to deassert resets\n");
-+
-+ return 0;
-+}
-+
-+static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks)
-+{
-+ return DIV_ROUND_CLOSEST(ticks, wdt->freq);
-+}
-+
-+/* Write unlock-key to unlock. Write other value to lock. */
-+static void starfive_wdt_unlock(struct starfive_wdt *wdt)
-+{
-+ spin_lock(&wdt->lock);
-+ writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
-+}
-+
-+static void starfive_wdt_lock(struct starfive_wdt *wdt)
-+{
-+ writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
-+ spin_unlock(&wdt->lock);
-+}
-+
-+/* enable watchdog interrupt to reset/reboot */
-+static void starfive_wdt_enable_reset(struct starfive_wdt *wdt)
-+{
-+ u32 val;
-+
-+ val = readl(wdt->base + wdt->variant->control);
-+ val |= STARFIVE_WDT_RESET_EN << wdt->variant->enrst_shift;
-+ writel(val, wdt->base + wdt->variant->control);
-+}
-+
-+/* interrupt status whether has been raised from the counter */
-+static bool starfive_wdt_raise_irq_status(struct starfive_wdt *wdt)
-+{
-+ return !!readl(wdt->base + wdt->variant->int_status);
-+}
-+
-+/* waiting interrupt can be free to clear */
-+static int starfive_wdt_wait_int_free(struct starfive_wdt *wdt)
-+{
-+ u32 value;
-+
-+ return readl_poll_timeout_atomic(wdt->base + wdt->variant->int_clr, value,
-+ !(value & BIT(wdt->variant->intclr_ava_shift)),
-+ STARFIVE_WDT_DELAY_US, STARFIVE_WDT_TIMEOUT_US);
-+}
-+
-+/* clear interrupt signal before initialization or reload */
-+static int starfive_wdt_int_clr(struct starfive_wdt *wdt)
-+{
-+ int ret;
-+
-+ if (wdt->variant->intclr_check) {
-+ ret = starfive_wdt_wait_int_free(wdt);
-+ if (ret)
-+ return dev_err_probe(wdt->wdd.parent, ret,
-+ "watchdog is not ready to clear interrupt.\n");
-+ }
-+ writel(STARFIVE_WDT_INTCLR, wdt->base + wdt->variant->int_clr);
-+
-+ return 0;
-+}
-+
-+static inline void starfive_wdt_set_count(struct starfive_wdt *wdt, u32 val)
-+{
-+ writel(val, wdt->base + wdt->variant->load);
-+}
-+
-+static inline u32 starfive_wdt_get_count(struct starfive_wdt *wdt)
-+{
-+ return readl(wdt->base + wdt->variant->value);
-+}
-+
-+/* enable watchdog */
-+static inline void starfive_wdt_enable(struct starfive_wdt *wdt)
-+{
-+ u32 val;
-+
-+ val = readl(wdt->base + wdt->variant->enable);
-+ val |= STARFIVE_WDT_ENABLE << wdt->variant->en_shift;
-+ writel(val, wdt->base + wdt->variant->enable);
-+}
-+
-+/* disable watchdog */
-+static inline void starfive_wdt_disable(struct starfive_wdt *wdt)
-+{
-+ u32 val;
-+
-+ val = readl(wdt->base + wdt->variant->enable);
-+ val &= ~(STARFIVE_WDT_ENABLE << wdt->variant->en_shift);
-+ writel(val, wdt->base + wdt->variant->enable);
-+}
-+
-+static inline void starfive_wdt_set_reload_count(struct starfive_wdt *wdt, u32 count)
-+{
-+ starfive_wdt_set_count(wdt, count);
-+
-+ /* 7100 need set any value to reload register and could reload value to counter */
-+ if (wdt->variant->reload)
-+ writel(0x1, wdt->base + wdt->variant->reload);
-+}
-+
-+static unsigned int starfive_wdt_max_timeout(struct starfive_wdt *wdt)
-+{
-+ if (wdt->variant->double_timeout)
-+ return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, (wdt->freq / 2)) - 1;
-+
-+ return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, wdt->freq) - 1;
-+}
-+
-+static unsigned int starfive_wdt_get_timeleft(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ u32 count;
-+
-+ /*
-+ * If the watchdog takes twice timeout and set half count value,
-+ * timeleft value should add the count value before first timeout.
-+ */
-+ count = starfive_wdt_get_count(wdt);
-+ if (wdt->variant->double_timeout && !starfive_wdt_raise_irq_status(wdt))
-+ count += wdt->count;
-+
-+ return starfive_wdt_ticks_to_sec(wdt, count);
-+}
-+
-+static int starfive_wdt_keepalive(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ int ret;
-+
-+ starfive_wdt_unlock(wdt);
-+ ret = starfive_wdt_int_clr(wdt);
-+ if (ret)
-+ goto exit;
-+
-+ starfive_wdt_set_reload_count(wdt, wdt->count);
-+
-+exit:
-+ /* exit with releasing spinlock and locking registers */
-+ starfive_wdt_lock(wdt);
-+ return ret;
-+}
-+
-+static int starfive_wdt_start(struct starfive_wdt *wdt)
-+{
-+ int ret;
-+
-+ starfive_wdt_unlock(wdt);
-+ /* disable watchdog, to be safe */
-+ starfive_wdt_disable(wdt);
-+
-+ starfive_wdt_enable_reset(wdt);
-+ ret = starfive_wdt_int_clr(wdt);
-+ if (ret)
-+ goto exit;
-+
-+ starfive_wdt_set_count(wdt, wdt->count);
-+ starfive_wdt_enable(wdt);
-+
-+exit:
-+ starfive_wdt_lock(wdt);
-+ return ret;
-+}
-+
-+static void starfive_wdt_stop(struct starfive_wdt *wdt)
-+{
-+ starfive_wdt_unlock(wdt);
-+ starfive_wdt_disable(wdt);
-+ starfive_wdt_lock(wdt);
-+}
-+
-+static int starfive_wdt_pm_start(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ int ret = pm_runtime_get_sync(wdd->parent);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ return starfive_wdt_start(wdt);
-+}
-+
-+static int starfive_wdt_pm_stop(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+
-+ starfive_wdt_stop(wdt);
-+ return pm_runtime_put_sync(wdd->parent);
-+}
-+
-+static int starfive_wdt_set_timeout(struct watchdog_device *wdd,
-+ unsigned int timeout)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ unsigned long count = timeout * wdt->freq;
-+
-+ /* some watchdogs take two timeouts to reset */
-+ if (wdt->variant->double_timeout)
-+ count /= 2;
-+
-+ wdt->count = count;
-+ wdd->timeout = timeout;
-+
-+ starfive_wdt_unlock(wdt);
-+ starfive_wdt_disable(wdt);
-+ starfive_wdt_set_reload_count(wdt, wdt->count);
-+ starfive_wdt_enable(wdt);
-+ starfive_wdt_lock(wdt);
-+
-+ return 0;
-+}
-+
-+#define STARFIVE_WDT_OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
-+
-+static const struct watchdog_info starfive_wdt_info = {
-+ .options = STARFIVE_WDT_OPTIONS,
-+ .identity = "StarFive Watchdog",
-+};
-+
-+static const struct watchdog_ops starfive_wdt_ops = {
-+ .owner = THIS_MODULE,
-+ .start = starfive_wdt_pm_start,
-+ .stop = starfive_wdt_pm_stop,
-+ .ping = starfive_wdt_keepalive,
-+ .set_timeout = starfive_wdt_set_timeout,
-+ .get_timeleft = starfive_wdt_get_timeleft,
-+};
-+
-+static int starfive_wdt_probe(struct platform_device *pdev)
-+{
-+ struct starfive_wdt *wdt;
-+ int ret;
-+
-+ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
-+ if (!wdt)
-+ return -ENOMEM;
-+
-+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(wdt->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(wdt->base), "error mapping registers\n");
-+
-+ wdt->wdd.parent = &pdev->dev;
-+ ret = starfive_wdt_get_clock(wdt);
-+ if (ret)
-+ return ret;
-+
-+ platform_set_drvdata(pdev, wdt);
-+ pm_runtime_enable(&pdev->dev);
-+ if (pm_runtime_enabled(&pdev->dev)) {
-+ ret = pm_runtime_get_sync(&pdev->dev);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ /* runtime PM is disabled but clocks need to be enabled */
-+ ret = starfive_wdt_enable_clock(wdt);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = starfive_wdt_reset_init(&pdev->dev);
-+ if (ret)
-+ goto err_exit;
-+
-+ watchdog_set_drvdata(&wdt->wdd, wdt);
-+ wdt->wdd.info = &starfive_wdt_info;
-+ wdt->wdd.ops = &starfive_wdt_ops;
-+ wdt->variant = of_device_get_match_data(&pdev->dev);
-+ spin_lock_init(&wdt->lock);
-+
-+ wdt->freq = clk_get_rate(wdt->core_clk);
-+ if (!wdt->freq) {
-+ dev_err(&pdev->dev, "get clock rate failed.\n");
-+ ret = -EINVAL;
-+ goto err_exit;
-+ }
-+
-+ wdt->wdd.min_timeout = 1;
-+ wdt->wdd.max_timeout = starfive_wdt_max_timeout(wdt);
-+ wdt->wdd.timeout = STARFIVE_WDT_DEFAULT_TIME;
-+ watchdog_init_timeout(&wdt->wdd, heartbeat, &pdev->dev);
-+ starfive_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
-+
-+ watchdog_set_nowayout(&wdt->wdd, nowayout);
-+ watchdog_stop_on_reboot(&wdt->wdd);
-+ watchdog_stop_on_unregister(&wdt->wdd);
-+
-+ if (early_enable) {
-+ ret = starfive_wdt_start(wdt);
-+ if (ret)
-+ goto err_exit;
-+ set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
-+ } else {
-+ starfive_wdt_stop(wdt);
-+ }
-+
-+ ret = watchdog_register_device(&wdt->wdd);
-+ if (ret)
-+ goto err_exit;
-+
-+ if (!early_enable)
-+ return pm_runtime_put_sync(&pdev->dev);
-+
-+ return 0;
-+
-+err_exit:
-+ starfive_wdt_disable_clock(wdt);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return ret;
-+}
-+
-+static int starfive_wdt_remove(struct platform_device *pdev)
-+{
-+ struct starfive_wdt *wdt = platform_get_drvdata(pdev);
-+
-+ starfive_wdt_stop(wdt);
-+ watchdog_unregister_device(&wdt->wdd);
-+
-+ if (pm_runtime_enabled(&pdev->dev))
-+ pm_runtime_disable(&pdev->dev);
-+ else
-+ /* disable clock without PM */
-+ starfive_wdt_disable_clock(wdt);
-+
-+ return 0;
-+}
-+
-+static void starfive_wdt_shutdown(struct platform_device *pdev)
-+{
-+ struct starfive_wdt *wdt = platform_get_drvdata(pdev);
-+
-+ starfive_wdt_pm_stop(&wdt->wdd);
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int starfive_wdt_suspend(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+
-+ /* Save watchdog state, and turn it off. */
-+ wdt->reload = starfive_wdt_get_count(wdt);
-+
-+ /* Note that WTCNT doesn't need to be saved. */
-+ starfive_wdt_stop(wdt);
-+
-+ return pm_runtime_force_suspend(dev);
-+}
-+
-+static int starfive_wdt_resume(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+ int ret;
-+
-+ ret = pm_runtime_force_resume(dev);
-+ if (ret)
-+ return ret;
-+
-+ starfive_wdt_unlock(wdt);
-+ /* Restore watchdog state. */
-+ starfive_wdt_set_reload_count(wdt, wdt->reload);
-+ starfive_wdt_lock(wdt);
-+
-+ return starfive_wdt_start(wdt);
-+}
-+#endif /* CONFIG_PM_SLEEP */
-+
-+#ifdef CONFIG_PM
-+static int starfive_wdt_runtime_suspend(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+
-+ starfive_wdt_disable_clock(wdt);
-+
-+ return 0;
-+}
-+
-+static int starfive_wdt_runtime_resume(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+
-+ return starfive_wdt_enable_clock(wdt);
-+}
-+#endif /* CONFIG_PM */
-+
-+static const struct dev_pm_ops starfive_wdt_pm_ops = {
-+ SET_RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL)
-+ SET_SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume)
-+};
-+
-+static const struct of_device_id starfive_wdt_match[] = {
-+ { .compatible = "starfive,jh7100-wdt", .data = &starfive_wdt_jh7100_variant },
-+ { .compatible = "starfive,jh7110-wdt", .data = &starfive_wdt_jh7110_variant },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_wdt_match);
-+
-+static struct platform_driver starfive_wdt_driver = {
-+ .probe = starfive_wdt_probe,
-+ .remove = starfive_wdt_remove,
-+ .shutdown = starfive_wdt_shutdown,
-+ .driver = {
-+ .name = "starfive-wdt",
-+ .pm = &starfive_wdt_pm_ops,
-+ .of_match_table = of_match_ptr(starfive_wdt_match),
-+ },
-+};
-+module_platform_driver(starfive_wdt_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive Watchdog Device Driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch b/target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch
deleted file mode 100644
index a7b7bd88db..0000000000
--- a/target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b085b6233065b1e5145fbf93d75264b2042c0eb5 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 21:24:37 +0800
-Subject: [PATCH 106/122] riscv: dts: starfive: jh7100: Add watchdog node
-
-Add watchdog node for the StarFive JH7100 RISC-V SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -238,5 +238,15 @@
- #size-cells = <0>;
- status = "disabled";
- };
-+
-+ watchdog@12480000 {
-+ compatible = "starfive,jh7100-wdt";
-+ reg = <0x0 0x12480000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_WDTIMER_APB>,
-+ <&clkgen JH7100_CLK_WDT_CORE>;
-+ clock-names = "apb", "core";
-+ resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
-+ <&rstgen JH7100_RSTN_WDT>;
-+ };
- };
- };
diff --git a/target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch b/target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch
deleted file mode 100644
index 39844b5b77..0000000000
--- a/target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From fc157f3d411ac570e8261e4238c6e6aac74a6cc6 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Wed, 15 Feb 2023 19:32:46 +0800
-Subject: [PATCH 107/122] dt-bindings: mmc: Add StarFive MMC module
-
-Add documentation to describe StarFive designware mobile storage
-host controller driver.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
----
- .../bindings/mmc/starfive,jh7110-mmc.yaml | 77 +++++++++++++++++++
- 1 file changed, 77 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
-@@ -0,0 +1,77 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mmc/starfive,jh7110-mmc.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive Designware Mobile Storage Host Controller
-+
-+description:
-+ StarFive uses the Synopsys designware mobile storage host controller
-+ to interface a SoC with storage medium such as eMMC or SD/MMC cards.
-+
-+allOf:
-+ - $ref: synopsys-dw-mshc-common.yaml#
-+
-+maintainers:
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-mmc
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: biu clock
-+ - description: ciu clock
-+
-+ clock-names:
-+ items:
-+ - const: biu
-+ - const: ciu
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ starfive,sysreg:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller syscon node
-+ - description: offset of SYS_SYSCONSAIF__SYSCFG register for MMC controller
-+ - description: shift of SYS_SYSCONSAIF__SYSCFG register for MMC controller
-+ - description: mask of SYS_SYSCONSAIF__SYSCFG register for MMC controller
-+ description:
-+ Should be four parameters, the phandle to System Register Controller
-+ syscon node and the offset/shift/mask of SYS_SYSCONSAIF__SYSCFG register
-+ for MMC controller.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - interrupts
-+ - starfive,sysreg
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ mmc@16010000 {
-+ compatible = "starfive,jh7110-mmc";
-+ reg = <0x16010000 0x10000>;
-+ clocks = <&syscrg 91>,
-+ <&syscrg 93>;
-+ clock-names = "biu","ciu";
-+ resets = <&syscrg 64>;
-+ reset-names = "reset";
-+ interrupts = <74>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ data-addr = <0>;
-+ starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch b/target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch
deleted file mode 100644
index fecad30928..0000000000
--- a/target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-From ee990c664fad993275b2615d0ff06af5d04922f0 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Wed, 15 Feb 2023 19:32:47 +0800
-Subject: [PATCH 108/122] mmc: starfive: Add sdio/emmc driver support
-
-Add sdio/emmc driver support for StarFive JH7110 soc.
-
-Tested-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- MAINTAINERS | 6 +
- drivers/mmc/host/Kconfig | 10 ++
- drivers/mmc/host/Makefile | 1 +
- drivers/mmc/host/dw_mmc-starfive.c | 186 +++++++++++++++++++++++++++++
- 4 files changed, 203 insertions(+)
- create mode 100644 drivers/mmc/host/dw_mmc-starfive.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19664,6 +19664,12 @@ S: Maintained
- F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
- F: drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-
-+STARFIVE JH7110 MMC/SD/SDIO DRIVER
-+M: William Qiu <william.qiu@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/mmc/starfive*
-+F: drivers/mmc/host/dw_mmc-starfive.c
-+
- STARFIVE JH7110 PLL CLOCK DRIVER
- M: Xingyu Wu <xingyu.wu@starfivetech.com>
- S: Supported
---- a/drivers/mmc/host/Kconfig
-+++ b/drivers/mmc/host/Kconfig
-@@ -872,6 +872,16 @@ config MMC_DW_ROCKCHIP
- Synopsys DesignWare Memory Card Interface driver. Select this option
- for platforms based on RK3066, RK3188 and RK3288 SoC's.
-
-+config MMC_DW_STARFIVE
-+ tristate "StarFive specific extensions for Synopsys DW Memory Card Interface"
-+ depends on SOC_STARFIVE
-+ depends on MMC_DW
-+ select MMC_DW_PLTFM
-+ help
-+ This selects support for StarFive JH7110 SoC specific extensions to the
-+ Synopsys DesignWare Memory Card Interface driver. Select this option
-+ for platforms based on StarFive JH7110 SoC.
-+
- config MMC_SH_MMCIF
- tristate "SuperH Internal MMCIF support"
- depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
---- a/drivers/mmc/host/Makefile
-+++ b/drivers/mmc/host/Makefile
-@@ -56,6 +56,7 @@ obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_m
- obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
- obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
- obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
-+obj-$(CONFIG_MMC_DW_STARFIVE) += dw_mmc-starfive.o
- obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
- obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
- obj-$(CONFIG_MMC_VUB300) += vub300.o
---- /dev/null
-+++ b/drivers/mmc/host/dw_mmc-starfive.c
-@@ -0,0 +1,186 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive Designware Mobile Storage Host Controller Driver
-+ *
-+ * Copyright (c) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/mmc/host.h>
-+#include <linux/module.h>
-+#include <linux/of_address.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+#include "dw_mmc.h"
-+#include "dw_mmc-pltfm.h"
-+
-+#define ALL_INT_CLR 0x1ffff
-+#define MAX_DELAY_CHAIN 32
-+
-+struct starfive_priv {
-+ struct device *dev;
-+ struct regmap *reg_syscon;
-+ u32 syscon_offset;
-+ u32 syscon_shift;
-+ u32 syscon_mask;
-+};
-+
-+static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
-+{
-+ int ret;
-+ unsigned int clock;
-+
-+ if (ios->timing == MMC_TIMING_MMC_DDR52 || ios->timing == MMC_TIMING_UHS_DDR50) {
-+ clock = (ios->clock > 50000000 && ios->clock <= 52000000) ? 100000000 : ios->clock;
-+ ret = clk_set_rate(host->ciu_clk, clock);
-+ if (ret)
-+ dev_dbg(host->dev, "Use an external frequency divider %uHz\n", ios->clock);
-+ host->bus_hz = clk_get_rate(host->ciu_clk);
-+ } else {
-+ dev_dbg(host->dev, "Using the internal divider\n");
-+ }
-+}
-+
-+static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
-+ u32 opcode)
-+{
-+ static const int grade = MAX_DELAY_CHAIN;
-+ struct dw_mci *host = slot->host;
-+ struct starfive_priv *priv = host->priv;
-+ int rise_point = -1, fall_point = -1;
-+ int err, prev_err;
-+ int i;
-+ bool found = 0;
-+ u32 regval;
-+
-+ /*
-+ * Use grade as the max delay chain, and use the rise_point and
-+ * fall_point to ensure the best sampling point of a data input
-+ * signals.
-+ */
-+ for (i = 0; i < grade; i++) {
-+ regval = i << priv->syscon_shift;
-+ err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
-+ priv->syscon_mask, regval);
-+ if (err)
-+ return err;
-+ mci_writel(host, RINTSTS, ALL_INT_CLR);
-+
-+ err = mmc_send_tuning(slot->mmc, opcode, NULL);
-+ if (!err)
-+ found = 1;
-+
-+ if (i > 0) {
-+ if (err && !prev_err)
-+ fall_point = i - 1;
-+ if (!err && prev_err)
-+ rise_point = i;
-+ }
-+
-+ if (rise_point != -1 && fall_point != -1)
-+ goto tuning_out;
-+
-+ prev_err = err;
-+ err = 0;
-+ }
-+
-+tuning_out:
-+ if (found) {
-+ if (rise_point == -1)
-+ rise_point = 0;
-+ if (fall_point == -1)
-+ fall_point = grade - 1;
-+ if (fall_point < rise_point) {
-+ if ((rise_point + fall_point) >
-+ (grade - 1))
-+ i = fall_point / 2;
-+ else
-+ i = (rise_point + grade - 1) / 2;
-+ } else {
-+ i = (rise_point + fall_point) / 2;
-+ }
-+
-+ regval = i << priv->syscon_shift;
-+ err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
-+ priv->syscon_mask, regval);
-+ if (err)
-+ return err;
-+ mci_writel(host, RINTSTS, ALL_INT_CLR);
-+
-+ dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i);
-+ } else {
-+ dev_err(host->dev, "No valid delay chain! use default\n");
-+ err = -EINVAL;
-+ }
-+
-+ mci_writel(host, RINTSTS, ALL_INT_CLR);
-+ return err;
-+}
-+
-+static int dw_mci_starfive_parse_dt(struct dw_mci *host)
-+{
-+ struct of_phandle_args args;
-+ struct starfive_priv *priv;
-+ int ret;
-+
-+ priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ ret = of_parse_phandle_with_fixed_args(host->dev->of_node,
-+ "starfive,sysreg", 3, 0, &args);
-+ if (ret) {
-+ dev_err(host->dev, "Failed to parse starfive,sysreg\n");
-+ return -EINVAL;
-+ }
-+
-+ priv->reg_syscon = syscon_node_to_regmap(args.np);
-+ of_node_put(args.np);
-+ if (IS_ERR(priv->reg_syscon))
-+ return PTR_ERR(priv->reg_syscon);
-+
-+ priv->syscon_offset = args.args[0];
-+ priv->syscon_shift = args.args[1];
-+ priv->syscon_mask = args.args[2];
-+
-+ host->priv = priv;
-+
-+ return 0;
-+}
-+
-+static const struct dw_mci_drv_data starfive_data = {
-+ .common_caps = MMC_CAP_CMD23,
-+ .set_ios = dw_mci_starfive_set_ios,
-+ .parse_dt = dw_mci_starfive_parse_dt,
-+ .execute_tuning = dw_mci_starfive_execute_tuning,
-+};
-+
-+static const struct of_device_id dw_mci_starfive_match[] = {
-+ { .compatible = "starfive,jh7110-mmc",
-+ .data = &starfive_data },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, dw_mci_starfive_match);
-+
-+static int dw_mci_starfive_probe(struct platform_device *pdev)
-+{
-+ return dw_mci_pltfm_register(pdev, &starfive_data);
-+}
-+
-+static struct platform_driver dw_mci_starfive_driver = {
-+ .probe = dw_mci_starfive_probe,
-+ .remove = dw_mci_pltfm_remove,
-+ .driver = {
-+ .name = "dwmmc_starfive",
-+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-+ .of_match_table = dw_mci_starfive_match,
-+ },
-+};
-+module_platform_driver(dw_mci_starfive_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 Specific DW-MSHC Driver Extension");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:dwmmc_starfive");
diff --git a/target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch b/target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch
deleted file mode 100644
index 9f6c4128f3..0000000000
--- a/target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From a0f2b48b5433d2fbcf87e4edf52e5cc26d0c29c8 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Tue, 21 Mar 2023 10:26:43 +0800
-Subject: [PATCH 109/122] dt-bindings: hwmon: Add starfive,jh71x0-temp
-
-Add bindings for the temperature sensor on the StarFive JH7100 and
-JH7110 SoCs.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- .../bindings/hwmon/starfive,jh71x0-temp.yaml | 70 +++++++++++++++++++
- 1 file changed, 70 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
-@@ -0,0 +1,70 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/hwmon/starfive,jh71x0-temp.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH71x0 Temperature Sensor
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+description: |
-+ StarFive Technology Co. JH71x0 embedded temperature sensor
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7100-temp
-+ - starfive,jh7110-temp
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ minItems: 2
-+ maxItems: 2
-+
-+ clock-names:
-+ items:
-+ - const: "sense"
-+ - const: "bus"
-+
-+ '#thermal-sensor-cells':
-+ const: 0
-+
-+ resets:
-+ minItems: 2
-+ maxItems: 2
-+
-+ reset-names:
-+ items:
-+ - const: "sense"
-+ - const: "bus"
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - reset-names
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive-jh7100.h>
-+ #include <dt-bindings/reset/starfive-jh7100.h>
-+
-+ temperature-sensor@124a0000 {
-+ compatible = "starfive,jh7100-temp";
-+ reg = <0x124a0000 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_TEMP_SENSE>,
-+ <&clkgen JH7100_CLK_TEMP_APB>;
-+ clock-names = "sense", "bus";
-+ #thermal-sensor-cells = <0>;
-+ resets = <&rstgen JH7100_RSTN_TEMP_SENSE>,
-+ <&rstgen JH7100_RSTN_TEMP_APB>;
-+ reset-names = "sense", "bus";
-+ };
diff --git a/target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch b/target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch
deleted file mode 100644
index aa062021ac..0000000000
--- a/target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch
+++ /dev/null
@@ -1,451 +0,0 @@
-From 3f68f5d0a8c598a09d26a3908cbbff7312b31487 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Tue, 21 Mar 2023 10:26:44 +0800
-Subject: [PATCH 110/122] hwmon: (sfctemp) Add StarFive JH71x0 temperature
- sensor
-
-Add driver for the StarFive JH71x0 temperature sensor. You
-can enable/disable it and read temperature in milli Celcius
-through sysfs.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- Documentation/hwmon/index.rst | 1 +
- Documentation/hwmon/sfctemp.rst | 33 ++++
- MAINTAINERS | 8 +
- drivers/hwmon/Kconfig | 10 +
- drivers/hwmon/Makefile | 1 +
- drivers/hwmon/sfctemp.c | 331 ++++++++++++++++++++++++++++++++
- 6 files changed, 384 insertions(+)
- create mode 100644 Documentation/hwmon/sfctemp.rst
- create mode 100644 drivers/hwmon/sfctemp.c
-
---- a/Documentation/hwmon/index.rst
-+++ b/Documentation/hwmon/index.rst
-@@ -179,6 +179,7 @@ Hardware Monitoring Kernel Drivers
- sch5627
- sch5636
- scpi-hwmon
-+ sfctemp
- sht15
- sht21
- sht3x
---- /dev/null
-+++ b/Documentation/hwmon/sfctemp.rst
-@@ -0,0 +1,33 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+
-+Kernel driver sfctemp
-+=====================
-+
-+Supported chips:
-+ - StarFive JH7100
-+ - StarFive JH7110
-+
-+Authors:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+Description
-+-----------
-+
-+This driver adds support for reading the built-in temperature sensor on the
-+JH7100 and JH7110 RISC-V SoCs by StarFive Technology Co. Ltd.
-+
-+``sysfs`` interface
-+-------------------
-+
-+The temperature sensor can be enabled, disabled and queried via the standard
-+hwmon interface in sysfs under ``/sys/class/hwmon/hwmonX`` for some value of
-+``X``:
-+
-+================ ==== =============================================
-+Name Perm Description
-+================ ==== =============================================
-+temp1_enable RW Enable or disable temperature sensor.
-+ Automatically enabled by the driver,
-+ but may be disabled to save power.
-+temp1_input RO Temperature reading in milli-degrees Celsius.
-+================ ==== =============================================
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -18686,6 +18686,14 @@ L: netdev@vger.kernel.org
- S: Supported
- F: drivers/net/ethernet/sfc/
-
-+SFCTEMP HWMON DRIVER
-+M: Emil Renner Berthing <kernel@esmil.dk>
-+L: linux-hwmon@vger.kernel.org
-+S: Maintained
-+F: Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
-+F: Documentation/hwmon/sfctemp.rst
-+F: drivers/hwmon/sfctemp.c
-+
- SFF/SFP/SFP+ MODULE SUPPORT
- M: Russell King <linux@armlinux.org.uk>
- L: netdev@vger.kernel.org
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -1911,6 +1911,16 @@ config SENSORS_STTS751
- This driver can also be built as a module. If so, the module
- will be called stts751.
-
-+config SENSORS_SFCTEMP
-+ tristate "Starfive JH71x0 temperature sensor"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ help
-+ If you say yes here you get support for temperature sensor
-+ on the Starfive JH71x0 SoCs.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called sfctemp.
-+
- config SENSORS_SMM665
- tristate "Summit Microelectronics SMM665"
- depends on I2C
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -179,6 +179,7 @@ obj-$(CONFIG_SENSORS_SBRMI) += sbrmi.o
- obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
- obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
- obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o
-+obj-$(CONFIG_SENSORS_SFCTEMP) += sfctemp.o
- obj-$(CONFIG_SENSORS_SL28CPLD) += sl28cpld-hwmon.o
- obj-$(CONFIG_SENSORS_SHT15) += sht15.o
- obj-$(CONFIG_SENSORS_SHT21) += sht21.o
---- /dev/null
-+++ b/drivers/hwmon/sfctemp.c
-@@ -0,0 +1,331 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/hwmon.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+
-+/*
-+ * TempSensor reset. The RSTN can be de-asserted once the analog core has
-+ * powered up. Trst(min 100ns)
-+ * 0:reset 1:de-assert
-+ */
-+#define SFCTEMP_RSTN BIT(0)
-+
-+/*
-+ * TempSensor analog core power down. The analog core will be powered up
-+ * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the
-+ * analog core is powered up.
-+ * 0:power up 1:power down
-+ */
-+#define SFCTEMP_PD BIT(1)
-+
-+/*
-+ * TempSensor start conversion enable.
-+ * 0:disable 1:enable
-+ */
-+#define SFCTEMP_RUN BIT(2)
-+
-+/*
-+ * TempSensor conversion value output.
-+ * Temp(C)=DOUT*Y/4094 - K
-+ */
-+#define SFCTEMP_DOUT_POS 16
-+#define SFCTEMP_DOUT_MSK GENMASK(27, 16)
-+
-+/* DOUT to Celcius conversion constants */
-+#define SFCTEMP_Y1000 237500L
-+#define SFCTEMP_Z 4094L
-+#define SFCTEMP_K1000 81100L
-+
-+struct sfctemp {
-+ /* serialize access to hardware register and enabled below */
-+ struct mutex lock;
-+ void __iomem *regs;
-+ struct clk *clk_sense;
-+ struct clk *clk_bus;
-+ struct reset_control *rst_sense;
-+ struct reset_control *rst_bus;
-+ bool enabled;
-+};
-+
-+static void sfctemp_power_up(struct sfctemp *sfctemp)
-+{
-+ /* make sure we're powered down first */
-+ writel(SFCTEMP_PD, sfctemp->regs);
-+ udelay(1);
-+
-+ writel(0, sfctemp->regs);
-+ /* wait t_pu(50us) + t_rst(100ns) */
-+ usleep_range(60, 200);
-+
-+ /* de-assert reset */
-+ writel(SFCTEMP_RSTN, sfctemp->regs);
-+ udelay(1); /* wait t_su(500ps) */
-+}
-+
-+static void sfctemp_power_down(struct sfctemp *sfctemp)
-+{
-+ writel(SFCTEMP_PD, sfctemp->regs);
-+}
-+
-+static void sfctemp_run(struct sfctemp *sfctemp)
-+{
-+ writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs);
-+ udelay(1);
-+}
-+
-+static void sfctemp_stop(struct sfctemp *sfctemp)
-+{
-+ writel(SFCTEMP_RSTN, sfctemp->regs);
-+}
-+
-+static int sfctemp_enable(struct sfctemp *sfctemp)
-+{
-+ int ret = 0;
-+
-+ mutex_lock(&sfctemp->lock);
-+ if (sfctemp->enabled)
-+ goto done;
-+
-+ ret = clk_prepare_enable(sfctemp->clk_bus);
-+ if (ret)
-+ goto err;
-+ ret = reset_control_deassert(sfctemp->rst_bus);
-+ if (ret)
-+ goto err_disable_bus;
-+
-+ ret = clk_prepare_enable(sfctemp->clk_sense);
-+ if (ret)
-+ goto err_assert_bus;
-+ ret = reset_control_deassert(sfctemp->rst_sense);
-+ if (ret)
-+ goto err_disable_sense;
-+
-+ sfctemp_power_up(sfctemp);
-+ sfctemp_run(sfctemp);
-+ sfctemp->enabled = true;
-+done:
-+ mutex_unlock(&sfctemp->lock);
-+ return ret;
-+
-+err_disable_sense:
-+ clk_disable_unprepare(sfctemp->clk_sense);
-+err_assert_bus:
-+ reset_control_assert(sfctemp->rst_bus);
-+err_disable_bus:
-+ clk_disable_unprepare(sfctemp->clk_bus);
-+err:
-+ mutex_unlock(&sfctemp->lock);
-+ return ret;
-+}
-+
-+static int sfctemp_disable(struct sfctemp *sfctemp)
-+{
-+ mutex_lock(&sfctemp->lock);
-+ if (!sfctemp->enabled)
-+ goto done;
-+
-+ sfctemp_stop(sfctemp);
-+ sfctemp_power_down(sfctemp);
-+ reset_control_assert(sfctemp->rst_sense);
-+ clk_disable_unprepare(sfctemp->clk_sense);
-+ reset_control_assert(sfctemp->rst_bus);
-+ clk_disable_unprepare(sfctemp->clk_bus);
-+ sfctemp->enabled = false;
-+done:
-+ mutex_unlock(&sfctemp->lock);
-+ return 0;
-+}
-+
-+static void sfctemp_disable_action(void *data)
-+{
-+ sfctemp_disable(data);
-+}
-+
-+static int sfctemp_convert(struct sfctemp *sfctemp, long *val)
-+{
-+ int ret;
-+
-+ mutex_lock(&sfctemp->lock);
-+ if (!sfctemp->enabled) {
-+ ret = -ENODATA;
-+ goto out;
-+ }
-+
-+ /* calculate temperature in milli Celcius */
-+ *val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS)
-+ * SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
-+
-+ ret = 0;
-+out:
-+ mutex_unlock(&sfctemp->lock);
-+ return ret;
-+}
-+
-+static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type,
-+ u32 attr, int channel)
-+{
-+ switch (type) {
-+ case hwmon_temp:
-+ switch (attr) {
-+ case hwmon_temp_enable:
-+ return 0644;
-+ case hwmon_temp_input:
-+ return 0444;
-+ default:
-+ return 0;
-+ }
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *val)
-+{
-+ struct sfctemp *sfctemp = dev_get_drvdata(dev);
-+
-+ switch (type) {
-+ case hwmon_temp:
-+ switch (attr) {
-+ case hwmon_temp_enable:
-+ *val = sfctemp->enabled;
-+ return 0;
-+ case hwmon_temp_input:
-+ return sfctemp_convert(sfctemp, val);
-+ default:
-+ return -EINVAL;
-+ }
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long val)
-+{
-+ struct sfctemp *sfctemp = dev_get_drvdata(dev);
-+
-+ switch (type) {
-+ case hwmon_temp:
-+ switch (attr) {
-+ case hwmon_temp_enable:
-+ if (val == 0)
-+ return sfctemp_disable(sfctemp);
-+ if (val == 1)
-+ return sfctemp_enable(sfctemp);
-+ return -EINVAL;
-+ default:
-+ return -EINVAL;
-+ }
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static const struct hwmon_channel_info *sfctemp_info[] = {
-+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
-+ HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT),
-+ NULL
-+};
-+
-+static const struct hwmon_ops sfctemp_hwmon_ops = {
-+ .is_visible = sfctemp_is_visible,
-+ .read = sfctemp_read,
-+ .write = sfctemp_write,
-+};
-+
-+static const struct hwmon_chip_info sfctemp_chip_info = {
-+ .ops = &sfctemp_hwmon_ops,
-+ .info = sfctemp_info,
-+};
-+
-+static int sfctemp_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device *hwmon_dev;
-+ struct sfctemp *sfctemp;
-+ int ret;
-+
-+ sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL);
-+ if (!sfctemp)
-+ return -ENOMEM;
-+
-+ dev_set_drvdata(dev, sfctemp);
-+ mutex_init(&sfctemp->lock);
-+
-+ sfctemp->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(sfctemp->regs))
-+ return PTR_ERR(sfctemp->regs);
-+
-+ sfctemp->clk_sense = devm_clk_get(dev, "sense");
-+ if (IS_ERR(sfctemp->clk_sense))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense),
-+ "error getting sense clock\n");
-+
-+ sfctemp->clk_bus = devm_clk_get(dev, "bus");
-+ if (IS_ERR(sfctemp->clk_bus))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus),
-+ "error getting bus clock\n");
-+
-+ sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense");
-+ if (IS_ERR(sfctemp->rst_sense))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense),
-+ "error getting sense reset\n");
-+
-+ sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus");
-+ if (IS_ERR(sfctemp->rst_bus))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
-+ "error getting busreset\n");
-+
-+ ret = reset_control_assert(sfctemp->rst_sense);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "error asserting sense reset\n");
-+
-+ ret = reset_control_assert(sfctemp->rst_bus);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "error asserting bus reset\n");
-+
-+ ret = devm_add_action(dev, sfctemp_disable_action, sfctemp);
-+ if (ret)
-+ return ret;
-+
-+ ret = sfctemp_enable(sfctemp);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "error enabling temperature sensor: %d\n", ret);
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(dev, "sfctemp", sfctemp,
-+ &sfctemp_chip_info, NULL);
-+ return PTR_ERR_OR_ZERO(hwmon_dev);
-+}
-+
-+static const struct of_device_id sfctemp_of_match[] = {
-+ { .compatible = "starfive,jh7100-temp" },
-+ { .compatible = "starfive,jh7110-temp" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, sfctemp_of_match);
-+
-+static struct platform_driver sfctemp_driver = {
-+ .probe = sfctemp_probe,
-+ .driver = {
-+ .name = "sfctemp",
-+ .of_match_table = sfctemp_of_match,
-+ },
-+};
-+module_platform_driver(sfctemp_driver);
-+
-+MODULE_AUTHOR("Emil Renner Berthing");
-+MODULE_DESCRIPTION("StarFive JH71x0 temperature sensor driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch b/target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch
deleted file mode 100644
index 860c6c0885..0000000000
--- a/target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From c2f59eeeee68bb66a3db8555474fe94e73b65b02 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Wed, 22 Mar 2023 17:48:17 +0800
-Subject: [PATCH 111/122] dt-bindings: dma: snps,dw-axi-dmac: constrain the
- items of resets for JH7110 dma
-
-The DMA controller needs two reset items to work properly on JH7110 SoC,
-so there is need to constrain the items' value to 2, other platforms
-have 1 reset item at most.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- .../bindings/dma/snps,dw-axi-dmac.yaml | 23 ++++++++++++++++++-
- 1 file changed, 22 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
-+++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
-@@ -21,6 +21,7 @@ properties:
- enum:
- - snps,axi-dma-1.01a
- - intel,kmb-axi-dma
-+ - starfive,jh7110-axi-dma
-
- reg:
- minItems: 1
-@@ -59,7 +60,8 @@ properties:
- maximum: 8
-
- resets:
-- maxItems: 1
-+ minItems: 1
-+ maxItems: 2
-
- snps,dma-masters:
- description: |
-@@ -110,6 +112,25 @@ required:
- - snps,priority
- - snps,block-size
-
-+if:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - starfive,jh7110-axi-dma
-+then:
-+ properties:
-+ resets:
-+ minItems: 2
-+ items:
-+ - description: AXI reset line
-+ - description: AHB reset line
-+ - description: module reset
-+else:
-+ properties:
-+ resets:
-+ maxItems: 1
-+
- additionalProperties: false
-
- examples:
diff --git a/target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch b/target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch
deleted file mode 100644
index 8b15fc213a..0000000000
--- a/target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 69ed990fda6795039a2b5b37d8ad5df785f4d97b Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Wed, 22 Mar 2023 17:48:18 +0800
-Subject: [PATCH 112/122] dmaengine: dw-axi-dmac: Add support for StarFive
- JH7110 DMA
-
-Add DMA reset operation in device probe and use different configuration
-on CH_CFG registers according to match data. Update all uses of
-of_device_is_compatible with of_device_get_match_data.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 38 ++++++++++++++++---
- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
- 2 files changed, 34 insertions(+), 5 deletions(-)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -21,10 +21,12 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/of.h>
-+#include <linux/of_device.h>
- #include <linux/of_dma.h>
- #include <linux/platform_device.h>
- #include <linux/pm_runtime.h>
- #include <linux/property.h>
-+#include <linux/reset.h>
- #include <linux/slab.h>
- #include <linux/types.h>
-
-@@ -46,6 +48,10 @@
- DMA_SLAVE_BUSWIDTH_32_BYTES | \
- DMA_SLAVE_BUSWIDTH_64_BYTES)
-
-+#define AXI_DMA_FLAG_HAS_APB_REGS BIT(0)
-+#define AXI_DMA_FLAG_HAS_RESETS BIT(1)
-+#define AXI_DMA_FLAG_USE_CFG2 BIT(2)
-+
- static inline void
- axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val)
- {
-@@ -86,7 +92,8 @@ static inline void axi_chan_config_write
-
- cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
- config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
-- if (chan->chip->dw->hdata->reg_map_8_channels) {
-+ if (chan->chip->dw->hdata->reg_map_8_channels &&
-+ !chan->chip->dw->hdata->use_cfg2) {
- cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
- config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
- config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
-@@ -1367,11 +1374,12 @@ static int parse_device_properties(struc
-
- static int dw_probe(struct platform_device *pdev)
- {
-- struct device_node *node = pdev->dev.of_node;
- struct axi_dma_chip *chip;
- struct resource *mem;
- struct dw_axi_dma *dw;
- struct dw_axi_dma_hcfg *hdata;
-+ struct reset_control *resets;
-+ unsigned int flags;
- u32 i;
- int ret;
-
-@@ -1400,12 +1408,25 @@ static int dw_probe(struct platform_devi
- if (IS_ERR(chip->regs))
- return PTR_ERR(chip->regs);
-
-- if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
-+ flags = (uintptr_t)of_device_get_match_data(&pdev->dev);
-+ if (flags & AXI_DMA_FLAG_HAS_APB_REGS) {
- chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(chip->apb_regs))
- return PTR_ERR(chip->apb_regs);
- }
-
-+ if (flags & AXI_DMA_FLAG_HAS_RESETS) {
-+ resets = devm_reset_control_array_get_exclusive(&pdev->dev);
-+ if (IS_ERR(resets))
-+ return PTR_ERR(resets);
-+
-+ ret = reset_control_deassert(resets);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ chip->dw->hdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2);
-+
- chip->core_clk = devm_clk_get(chip->dev, "core-clk");
- if (IS_ERR(chip->core_clk))
- return PTR_ERR(chip->core_clk);
-@@ -1556,8 +1577,15 @@ static const struct dev_pm_ops dw_axi_dm
- };
-
- static const struct of_device_id dw_dma_of_id_table[] = {
-- { .compatible = "snps,axi-dma-1.01a" },
-- { .compatible = "intel,kmb-axi-dma" },
-+ {
-+ .compatible = "snps,axi-dma-1.01a"
-+ }, {
-+ .compatible = "intel,kmb-axi-dma",
-+ .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
-+ }, {
-+ .compatible = "starfive,jh7110-axi-dma",
-+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
-+ },
- {}
- };
- MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-@@ -33,6 +33,7 @@ struct dw_axi_dma_hcfg {
- /* Register map for DMAX_NUM_CHANNELS <= 8 */
- bool reg_map_8_channels;
- bool restrict_axi_burst_len;
-+ bool use_cfg2;
- };
-
- struct axi_dma_chan {
diff --git a/target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch b/target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch
deleted file mode 100644
index 903efb43c1..0000000000
--- a/target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 92c2dc96af79b2f181cc97157ce3ef2be5b48f4c Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Wed, 22 Mar 2023 17:48:19 +0800
-Subject: [PATCH 113/122] dmaengine: dw-axi-dmac: Increase polling time to DMA
- transmission completion status
-
-The bit DMAC_CHEN[0] is automatically cleared by hardware to disable the
-channel after the last AMBA transfer of the DMA transfer to the
-destination has completed. Software can therefore poll this bit to
-determine when this channel is free for a new DMA transfer.
-This time requires at least 40 milliseconds on JH7110 SoC, otherwise an
-error message 'failed to stop' will be reported.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -1147,7 +1147,7 @@ static int dma_chan_terminate_all(struct
- axi_chan_disable(chan);
-
- ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val,
-- !(val & chan_active), 1000, 10000);
-+ !(val & chan_active), 1000, 50000);
- if (ret == -ETIMEDOUT)
- dev_warn(dchan2dev(dchan),
- "%s failed to stop\n", axi_chan_name(chan));
diff --git a/target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch b/target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch
deleted file mode 100644
index 6c4745462a..0000000000
--- a/target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From ba1b6ccbf68183b0d9e633ef930c7974144c7b56 Mon Sep 17 00:00:00 2001
-From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Date: Thu, 30 Mar 2023 14:43:18 +0800
-Subject: [PATCH 114/122] RISC-V: Change suspend_save_csrs and
- suspend_restore_csrs to public function
-
-Currently suspend_save_csrs() and suspend_restore_csrs() functions are
-statically defined in the suspend.c. Change the function's attribute
-to public so that the functions can be used by hibernation as well.
-
-Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
-Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
----
- arch/riscv/include/asm/suspend.h | 3 +++
- arch/riscv/kernel/suspend.c | 4 ++--
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
---- a/arch/riscv/include/asm/suspend.h
-+++ b/arch/riscv/include/asm/suspend.h
-@@ -33,4 +33,7 @@ int cpu_suspend(unsigned long arg,
- /* Low-level CPU resume entry function */
- int __cpu_resume_enter(unsigned long hartid, unsigned long context);
-
-+/* Used to save and restore the CSRs */
-+void suspend_save_csrs(struct suspend_context *context);
-+void suspend_restore_csrs(struct suspend_context *context);
- #endif
---- a/arch/riscv/kernel/suspend.c
-+++ b/arch/riscv/kernel/suspend.c
-@@ -8,7 +8,7 @@
- #include <asm/csr.h>
- #include <asm/suspend.h>
-
--static void suspend_save_csrs(struct suspend_context *context)
-+void suspend_save_csrs(struct suspend_context *context)
- {
- context->scratch = csr_read(CSR_SCRATCH);
- context->tvec = csr_read(CSR_TVEC);
-@@ -29,7 +29,7 @@ static void suspend_save_csrs(struct sus
- #endif
- }
-
--static void suspend_restore_csrs(struct suspend_context *context)
-+void suspend_restore_csrs(struct suspend_context *context)
- {
- csr_write(CSR_SCRATCH, context->scratch);
- csr_write(CSR_TVEC, context->tvec);
diff --git a/target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch b/target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch
deleted file mode 100644
index ccdb77b05c..0000000000
--- a/target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From f0e2b8f9bb240d7391d3eeca55534160fd385ea8 Mon Sep 17 00:00:00 2001
-From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Date: Thu, 30 Mar 2023 14:43:19 +0800
-Subject: [PATCH 115/122] RISC-V: Factor out common code of
- __cpu_resume_enter()
-
-The cpu_resume() function is very similar for the suspend to disk and
-suspend to ram cases. Factor out the common code into suspend_restore_csrs
-macro and suspend_restore_regs macro.
-
-Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/include/asm/assembler.h | 62 ++++++++++++++++++++++++++++++
- arch/riscv/kernel/suspend_entry.S | 34 ++--------------
- 2 files changed, 65 insertions(+), 31 deletions(-)
- create mode 100644 arch/riscv/include/asm/assembler.h
-
---- /dev/null
-+++ b/arch/riscv/include/asm/assembler.h
-@@ -0,0 +1,62 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
-+ */
-+
-+#ifndef __ASSEMBLY__
-+#error "Only include this from assembly code"
-+#endif
-+
-+#ifndef __ASM_ASSEMBLER_H
-+#define __ASM_ASSEMBLER_H
-+
-+#include <asm/asm.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/csr.h>
-+
-+/*
-+ * suspend_restore_csrs - restore CSRs
-+ */
-+ .macro suspend_restore_csrs
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
-+ csrw CSR_EPC, t0
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
-+ csrw CSR_STATUS, t0
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
-+ csrw CSR_TVAL, t0
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
-+ csrw CSR_CAUSE, t0
-+ .endm
-+
-+/*
-+ * suspend_restore_regs - Restore registers (except A0 and T0-T6)
-+ */
-+ .macro suspend_restore_regs
-+ REG_L ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
-+ REG_L sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
-+ REG_L gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
-+ REG_L tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
-+ REG_L s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
-+ REG_L s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
-+ REG_L a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
-+ REG_L a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
-+ REG_L a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
-+ REG_L a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
-+ REG_L a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
-+ REG_L a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
-+ REG_L a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
-+ REG_L s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
-+ REG_L s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
-+ REG_L s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
-+ REG_L s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
-+ REG_L s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
-+ REG_L s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
-+ REG_L s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
-+ REG_L s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
-+ REG_L s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
-+ REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
-+ .endm
-+
-+#endif /* __ASM_ASSEMBLER_H */
---- a/arch/riscv/kernel/suspend_entry.S
-+++ b/arch/riscv/kernel/suspend_entry.S
-@@ -7,6 +7,7 @@
- #include <linux/linkage.h>
- #include <asm/asm.h>
- #include <asm/asm-offsets.h>
-+#include <asm/assembler.h>
- #include <asm/csr.h>
- #include <asm/xip_fixup.h>
-
-@@ -83,39 +84,10 @@ ENTRY(__cpu_resume_enter)
- add a0, a1, zero
-
- /* Restore CSRs */
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
-- csrw CSR_EPC, t0
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
-- csrw CSR_STATUS, t0
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
-- csrw CSR_TVAL, t0
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
-- csrw CSR_CAUSE, t0
-+ suspend_restore_csrs
-
- /* Restore registers (except A0 and T0-T6) */
-- REG_L ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
-- REG_L sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
-- REG_L gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
-- REG_L tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
-- REG_L s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
-- REG_L s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
-- REG_L a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
-- REG_L a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
-- REG_L a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
-- REG_L a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
-- REG_L a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
-- REG_L a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
-- REG_L a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
-- REG_L s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
-- REG_L s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
-- REG_L s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
-- REG_L s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
-- REG_L s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
-- REG_L s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
-- REG_L s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
-- REG_L s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
-- REG_L s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
-- REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
-+ suspend_restore_regs
-
- /* Return zero value */
- add a0, zero, zero
diff --git a/target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch b/target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch
deleted file mode 100644
index a47c49d968..0000000000
--- a/target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch
+++ /dev/null
@@ -1,673 +0,0 @@
-From 06f1d699e923c3f09869439cdb603e36302c2611 Mon Sep 17 00:00:00 2001
-From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Date: Thu, 30 Mar 2023 14:43:21 +0800
-Subject: [PATCH 116/122] RISC-V: Add arch functions to support
- hibernation/suspend-to-disk
-
-Low level Arch functions were created to support hibernation.
-swsusp_arch_suspend() relies code from __cpu_suspend_enter() to write
-cpu state onto the stack, then calling swsusp_save() to save the memory
-image.
-
-Arch specific hibernation header is implemented and is utilized by the
-arch_hibernation_header_restore() and arch_hibernation_header_save()
-functions. The arch specific hibernation header consists of satp, hartid,
-and the cpu_resume address. The kernel built version is also need to be
-saved into the hibernation image header to making sure only the same
-kernel is restore when resume.
-
-swsusp_arch_resume() creates a temporary page table that covering only
-the linear map. It copies the restore code to a 'safe' page, then start
-to restore the memory image. Once completed, it restores the original
-kernel's page table. It then calls into __hibernate_cpu_resume()
-to restore the CPU context. Finally, it follows the normal hibernation
-path back to the hibernation core.
-
-To enable hibernation/suspend to disk into RISCV, the below config
-need to be enabled:
-- CONFIG_HIBERNATION
-- CONFIG_ARCH_HIBERNATION_HEADER
-- CONFIG_ARCH_HIBERNATION_POSSIBLE
-
-Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
-Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
----
- arch/riscv/Kconfig | 8 +-
- arch/riscv/include/asm/assembler.h | 20 ++
- arch/riscv/include/asm/suspend.h | 19 ++
- arch/riscv/kernel/Makefile | 1 +
- arch/riscv/kernel/asm-offsets.c | 5 +
- arch/riscv/kernel/hibernate-asm.S | 77 ++++++
- arch/riscv/kernel/hibernate.c | 427 +++++++++++++++++++++++++++++
- 7 files changed, 556 insertions(+), 1 deletion(-)
- create mode 100644 arch/riscv/kernel/hibernate-asm.S
- create mode 100644 arch/riscv/kernel/hibernate.c
-
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -52,7 +52,7 @@ config RISCV
- select CLONE_BACKWARDS
- select CLINT_TIMER if !MMU
- select COMMON_CLK
-- select CPU_PM if CPU_IDLE
-+ select CPU_PM if CPU_IDLE || HIBERNATION
- select EDAC_SUPPORT
- select GENERIC_ARCH_TOPOLOGY
- select GENERIC_ATOMIC64 if !64BIT
-@@ -715,6 +715,12 @@ menu "Power management options"
-
- source "kernel/power/Kconfig"
-
-+config ARCH_HIBERNATION_POSSIBLE
-+ def_bool y
-+
-+config ARCH_HIBERNATION_HEADER
-+ def_bool HIBERNATION
-+
- endmenu # "Power management options"
-
- menu "CPU Power Management"
---- a/arch/riscv/include/asm/assembler.h
-+++ b/arch/riscv/include/asm/assembler.h
-@@ -59,4 +59,24 @@
- REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
- .endm
-
-+/*
-+ * copy_page - copy 1 page (4KB) of data from source to destination
-+ * @a0 - destination
-+ * @a1 - source
-+ */
-+ .macro copy_page a0, a1
-+ lui a2, 0x1
-+ add a2, a2, a0
-+1 :
-+ REG_L t0, 0(a1)
-+ REG_L t1, SZREG(a1)
-+
-+ REG_S t0, 0(a0)
-+ REG_S t1, SZREG(a0)
-+
-+ addi a0, a0, 2 * SZREG
-+ addi a1, a1, 2 * SZREG
-+ bne a2, a0, 1b
-+ .endm
-+
- #endif /* __ASM_ASSEMBLER_H */
---- a/arch/riscv/include/asm/suspend.h
-+++ b/arch/riscv/include/asm/suspend.h
-@@ -21,6 +21,11 @@ struct suspend_context {
- #endif
- };
-
-+/*
-+ * Used by hibernation core and cleared during resume sequence
-+ */
-+extern int in_suspend;
-+
- /* Low-level CPU suspend entry function */
- int __cpu_suspend_enter(struct suspend_context *context);
-
-@@ -36,4 +41,18 @@ int __cpu_resume_enter(unsigned long har
- /* Used to save and restore the CSRs */
- void suspend_save_csrs(struct suspend_context *context);
- void suspend_restore_csrs(struct suspend_context *context);
-+
-+/* Low-level API to support hibernation */
-+int swsusp_arch_suspend(void);
-+int swsusp_arch_resume(void);
-+int arch_hibernation_header_save(void *addr, unsigned int max_size);
-+int arch_hibernation_header_restore(void *addr);
-+int __hibernate_cpu_resume(void);
-+
-+/* Used to resume on the CPU we hibernated on */
-+int hibernate_resume_nonboot_cpu_disable(void);
-+
-+asmlinkage void hibernate_restore_image(unsigned long resume_satp, unsigned long satp_temp,
-+ unsigned long cpu_resume);
-+asmlinkage int hibernate_core_restore_code(void);
- #endif
---- a/arch/riscv/kernel/Makefile
-+++ b/arch/riscv/kernel/Makefile
-@@ -67,6 +67,7 @@ obj-$(CONFIG_MODULES) += module.o
- obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o
-
- obj-$(CONFIG_CPU_PM) += suspend_entry.o suspend.o
-+obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o
-
- obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
- obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o
---- a/arch/riscv/kernel/asm-offsets.c
-+++ b/arch/riscv/kernel/asm-offsets.c
-@@ -9,6 +9,7 @@
- #include <linux/kbuild.h>
- #include <linux/mm.h>
- #include <linux/sched.h>
-+#include <linux/suspend.h>
- #include <asm/kvm_host.h>
- #include <asm/thread_info.h>
- #include <asm/ptrace.h>
-@@ -116,6 +117,10 @@ void asm_offsets(void)
-
- OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs);
-
-+ OFFSET(HIBERN_PBE_ADDR, pbe, address);
-+ OFFSET(HIBERN_PBE_ORIG, pbe, orig_address);
-+ OFFSET(HIBERN_PBE_NEXT, pbe, next);
-+
- OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero);
- OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra);
- OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp);
---- /dev/null
-+++ b/arch/riscv/kernel/hibernate-asm.S
-@@ -0,0 +1,77 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Hibernation low level support for RISCV.
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
-+ */
-+
-+#include <asm/asm.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/assembler.h>
-+#include <asm/csr.h>
-+
-+#include <linux/linkage.h>
-+
-+/*
-+ * int __hibernate_cpu_resume(void)
-+ * Switch back to the hibernated image's page table prior to restoring the CPU
-+ * context.
-+ *
-+ * Always returns 0
-+ */
-+ENTRY(__hibernate_cpu_resume)
-+ /* switch to hibernated image's page table. */
-+ csrw CSR_SATP, s0
-+ sfence.vma
-+
-+ REG_L a0, hibernate_cpu_context
-+
-+ suspend_restore_csrs
-+ suspend_restore_regs
-+
-+ /* Return zero value. */
-+ mv a0, zero
-+
-+ ret
-+END(__hibernate_cpu_resume)
-+
-+/*
-+ * Prepare to restore the image.
-+ * a0: satp of saved page tables.
-+ * a1: satp of temporary page tables.
-+ * a2: cpu_resume.
-+ */
-+ENTRY(hibernate_restore_image)
-+ mv s0, a0
-+ mv s1, a1
-+ mv s2, a2
-+ REG_L s4, restore_pblist
-+ REG_L a1, relocated_restore_code
-+
-+ jalr a1
-+END(hibernate_restore_image)
-+
-+/*
-+ * The below code will be executed from a 'safe' page.
-+ * It first switches to the temporary page table, then starts to copy the pages
-+ * back to the original memory location. Finally, it jumps to __hibernate_cpu_resume()
-+ * to restore the CPU context.
-+ */
-+ENTRY(hibernate_core_restore_code)
-+ /* switch to temp page table. */
-+ csrw satp, s1
-+ sfence.vma
-+.Lcopy:
-+ /* The below code will restore the hibernated image. */
-+ REG_L a1, HIBERN_PBE_ADDR(s4)
-+ REG_L a0, HIBERN_PBE_ORIG(s4)
-+
-+ copy_page a0, a1
-+
-+ REG_L s4, HIBERN_PBE_NEXT(s4)
-+ bnez s4, .Lcopy
-+
-+ jalr s2
-+END(hibernate_core_restore_code)
---- /dev/null
-+++ b/arch/riscv/kernel/hibernate.c
-@@ -0,0 +1,427 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Hibernation support for RISCV
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
-+ */
-+
-+#include <asm/barrier.h>
-+#include <asm/cacheflush.h>
-+#include <asm/mmu_context.h>
-+#include <asm/page.h>
-+#include <asm/pgalloc.h>
-+#include <asm/pgtable.h>
-+#include <asm/sections.h>
-+#include <asm/set_memory.h>
-+#include <asm/smp.h>
-+#include <asm/suspend.h>
-+
-+#include <linux/cpu.h>
-+#include <linux/memblock.h>
-+#include <linux/pm.h>
-+#include <linux/sched.h>
-+#include <linux/suspend.h>
-+#include <linux/utsname.h>
-+
-+/* The logical cpu number we should resume on, initialised to a non-cpu number. */
-+static int sleep_cpu = -EINVAL;
-+
-+/* Pointer to the temporary resume page table. */
-+static pgd_t *resume_pg_dir;
-+
-+/* CPU context to be saved. */
-+struct suspend_context *hibernate_cpu_context;
-+EXPORT_SYMBOL_GPL(hibernate_cpu_context);
-+
-+unsigned long relocated_restore_code;
-+EXPORT_SYMBOL_GPL(relocated_restore_code);
-+
-+/**
-+ * struct arch_hibernate_hdr_invariants - container to store kernel build version.
-+ * @uts_version: to save the build number and date so that we do not resume with
-+ * a different kernel.
-+ */
-+struct arch_hibernate_hdr_invariants {
-+ char uts_version[__NEW_UTS_LEN + 1];
-+};
-+
-+/**
-+ * struct arch_hibernate_hdr - helper parameters that help us to restore the image.
-+ * @invariants: container to store kernel build version.
-+ * @hartid: to make sure same boot_cpu executes the hibernate/restore code.
-+ * @saved_satp: original page table used by the hibernated image.
-+ * @restore_cpu_addr: the kernel's image address to restore the CPU context.
-+ */
-+static struct arch_hibernate_hdr {
-+ struct arch_hibernate_hdr_invariants invariants;
-+ unsigned long hartid;
-+ unsigned long saved_satp;
-+ unsigned long restore_cpu_addr;
-+} resume_hdr;
-+
-+static void arch_hdr_invariants(struct arch_hibernate_hdr_invariants *i)
-+{
-+ memset(i, 0, sizeof(*i));
-+ memcpy(i->uts_version, init_utsname()->version, sizeof(i->uts_version));
-+}
-+
-+/*
-+ * Check if the given pfn is in the 'nosave' section.
-+ */
-+int pfn_is_nosave(unsigned long pfn)
-+{
-+ unsigned long nosave_begin_pfn = sym_to_pfn(&__nosave_begin);
-+ unsigned long nosave_end_pfn = sym_to_pfn(&__nosave_end - 1);
-+
-+ return ((pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn));
-+}
-+
-+void notrace save_processor_state(void)
-+{
-+ WARN_ON(num_online_cpus() != 1);
-+}
-+
-+void notrace restore_processor_state(void)
-+{
-+}
-+
-+/*
-+ * Helper parameters need to be saved to the hibernation image header.
-+ */
-+int arch_hibernation_header_save(void *addr, unsigned int max_size)
-+{
-+ struct arch_hibernate_hdr *hdr = addr;
-+
-+ if (max_size < sizeof(*hdr))
-+ return -EOVERFLOW;
-+
-+ arch_hdr_invariants(&hdr->invariants);
-+
-+ hdr->hartid = cpuid_to_hartid_map(sleep_cpu);
-+ hdr->saved_satp = csr_read(CSR_SATP);
-+ hdr->restore_cpu_addr = (unsigned long)__hibernate_cpu_resume;
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(arch_hibernation_header_save);
-+
-+/*
-+ * Retrieve the helper parameters from the hibernation image header.
-+ */
-+int arch_hibernation_header_restore(void *addr)
-+{
-+ struct arch_hibernate_hdr_invariants invariants;
-+ struct arch_hibernate_hdr *hdr = addr;
-+ int ret = 0;
-+
-+ arch_hdr_invariants(&invariants);
-+
-+ if (memcmp(&hdr->invariants, &invariants, sizeof(invariants))) {
-+ pr_crit("Hibernate image not generated by this kernel!\n");
-+ return -EINVAL;
-+ }
-+
-+ sleep_cpu = riscv_hartid_to_cpuid(hdr->hartid);
-+ if (sleep_cpu < 0) {
-+ pr_crit("Hibernated on a CPU not known to this kernel!\n");
-+ sleep_cpu = -EINVAL;
-+ return -EINVAL;
-+ }
-+
-+#ifdef CONFIG_SMP
-+ ret = bringup_hibernate_cpu(sleep_cpu);
-+ if (ret) {
-+ sleep_cpu = -EINVAL;
-+ return ret;
-+ }
-+#endif
-+ resume_hdr = *hdr;
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(arch_hibernation_header_restore);
-+
-+int swsusp_arch_suspend(void)
-+{
-+ int ret = 0;
-+
-+ if (__cpu_suspend_enter(hibernate_cpu_context)) {
-+ sleep_cpu = smp_processor_id();
-+ suspend_save_csrs(hibernate_cpu_context);
-+ ret = swsusp_save();
-+ } else {
-+ suspend_restore_csrs(hibernate_cpu_context);
-+ flush_tlb_all();
-+ flush_icache_all();
-+
-+ /*
-+ * Tell the hibernation core that we've just restored the memory.
-+ */
-+ in_suspend = 0;
-+ sleep_cpu = -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static int temp_pgtable_map_pte(pmd_t *dst_pmdp, pmd_t *src_pmdp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ pte_t *src_ptep;
-+ pte_t *dst_ptep;
-+
-+ if (pmd_none(READ_ONCE(*dst_pmdp))) {
-+ dst_ptep = (pte_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_ptep)
-+ return -ENOMEM;
-+
-+ pmd_populate_kernel(NULL, dst_pmdp, dst_ptep);
-+ }
-+
-+ dst_ptep = pte_offset_kernel(dst_pmdp, start);
-+ src_ptep = pte_offset_kernel(src_pmdp, start);
-+
-+ do {
-+ pte_t pte = READ_ONCE(*src_ptep);
-+
-+ if (pte_present(pte))
-+ set_pte(dst_ptep, __pte(pte_val(pte) | pgprot_val(prot)));
-+ } while (dst_ptep++, src_ptep++, start += PAGE_SIZE, start < end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_map_pmd(pud_t *dst_pudp, pud_t *src_pudp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ unsigned long next;
-+ unsigned long ret;
-+ pmd_t *src_pmdp;
-+ pmd_t *dst_pmdp;
-+
-+ if (pud_none(READ_ONCE(*dst_pudp))) {
-+ dst_pmdp = (pmd_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_pmdp)
-+ return -ENOMEM;
-+
-+ pud_populate(NULL, dst_pudp, dst_pmdp);
-+ }
-+
-+ dst_pmdp = pmd_offset(dst_pudp, start);
-+ src_pmdp = pmd_offset(src_pudp, start);
-+
-+ do {
-+ pmd_t pmd = READ_ONCE(*src_pmdp);
-+
-+ next = pmd_addr_end(start, end);
-+
-+ if (pmd_none(pmd))
-+ continue;
-+
-+ if (pmd_leaf(pmd)) {
-+ set_pmd(dst_pmdp, __pmd(pmd_val(pmd) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_pte(dst_pmdp, src_pmdp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_pmdp++, src_pmdp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_map_pud(p4d_t *dst_p4dp, p4d_t *src_p4dp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ unsigned long next;
-+ unsigned long ret;
-+ pud_t *dst_pudp;
-+ pud_t *src_pudp;
-+
-+ if (p4d_none(READ_ONCE(*dst_p4dp))) {
-+ dst_pudp = (pud_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_pudp)
-+ return -ENOMEM;
-+
-+ p4d_populate(NULL, dst_p4dp, dst_pudp);
-+ }
-+
-+ dst_pudp = pud_offset(dst_p4dp, start);
-+ src_pudp = pud_offset(src_p4dp, start);
-+
-+ do {
-+ pud_t pud = READ_ONCE(*src_pudp);
-+
-+ next = pud_addr_end(start, end);
-+
-+ if (pud_none(pud))
-+ continue;
-+
-+ if (pud_leaf(pud)) {
-+ set_pud(dst_pudp, __pud(pud_val(pud) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_pmd(dst_pudp, src_pudp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_pudp++, src_pudp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_map_p4d(pgd_t *dst_pgdp, pgd_t *src_pgdp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ unsigned long next;
-+ unsigned long ret;
-+ p4d_t *dst_p4dp;
-+ p4d_t *src_p4dp;
-+
-+ if (pgd_none(READ_ONCE(*dst_pgdp))) {
-+ dst_p4dp = (p4d_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_p4dp)
-+ return -ENOMEM;
-+
-+ pgd_populate(NULL, dst_pgdp, dst_p4dp);
-+ }
-+
-+ dst_p4dp = p4d_offset(dst_pgdp, start);
-+ src_p4dp = p4d_offset(src_pgdp, start);
-+
-+ do {
-+ p4d_t p4d = READ_ONCE(*src_p4dp);
-+
-+ next = p4d_addr_end(start, end);
-+
-+ if (p4d_none(p4d))
-+ continue;
-+
-+ if (p4d_leaf(p4d)) {
-+ set_p4d(dst_p4dp, __p4d(p4d_val(p4d) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_pud(dst_p4dp, src_p4dp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_p4dp++, src_p4dp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_mapping(pgd_t *pgdp, unsigned long start, unsigned long end, pgprot_t prot)
-+{
-+ pgd_t *dst_pgdp = pgd_offset_pgd(pgdp, start);
-+ pgd_t *src_pgdp = pgd_offset_k(start);
-+ unsigned long next;
-+ unsigned long ret;
-+
-+ do {
-+ pgd_t pgd = READ_ONCE(*src_pgdp);
-+
-+ next = pgd_addr_end(start, end);
-+
-+ if (pgd_none(pgd))
-+ continue;
-+
-+ if (pgd_leaf(pgd)) {
-+ set_pgd(dst_pgdp, __pgd(pgd_val(pgd) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_p4d(dst_pgdp, src_pgdp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_pgdp++, src_pgdp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static unsigned long relocate_restore_code(void)
-+{
-+ void *page = (void *)get_safe_page(GFP_ATOMIC);
-+
-+ if (!page)
-+ return -ENOMEM;
-+
-+ copy_page(page, hibernate_core_restore_code);
-+
-+ /* Make the page containing the relocated code executable. */
-+ set_memory_x((unsigned long)page, 1);
-+
-+ return (unsigned long)page;
-+}
-+
-+int swsusp_arch_resume(void)
-+{
-+ unsigned long end = (unsigned long)pfn_to_virt(max_low_pfn);
-+ unsigned long start = PAGE_OFFSET;
-+ int ret;
-+
-+ /*
-+ * Memory allocated by get_safe_page() will be dealt with by the hibernation core,
-+ * we don't need to free it here.
-+ */
-+ resume_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC);
-+ if (!resume_pg_dir)
-+ return -ENOMEM;
-+
-+ /*
-+ * Create a temporary page table and map the whole linear region as executable and
-+ * writable.
-+ */
-+ ret = temp_pgtable_mapping(resume_pg_dir, start, end, __pgprot(_PAGE_WRITE | _PAGE_EXEC));
-+ if (ret)
-+ return ret;
-+
-+ /* Move the restore code to a new page so that it doesn't get overwritten by itself. */
-+ relocated_restore_code = relocate_restore_code();
-+ if (relocated_restore_code == -ENOMEM)
-+ return -ENOMEM;
-+
-+ /*
-+ * Map the __hibernate_cpu_resume() address to the temporary page table so that the
-+ * restore code can jumps to it after finished restore the image. The next execution
-+ * code doesn't find itself in a different address space after switching over to the
-+ * original page table used by the hibernated image.
-+ * The __hibernate_cpu_resume() mapping is unnecessary for RV32 since the kernel and
-+ * linear addresses are identical, but different for RV64. To ensure consistency, we
-+ * map it for both RV32 and RV64 kernels.
-+ * Additionally, we should ensure that the page is writable before restoring the image.
-+ */
-+ start = (unsigned long)resume_hdr.restore_cpu_addr;
-+ end = start + PAGE_SIZE;
-+
-+ ret = temp_pgtable_mapping(resume_pg_dir, start, end, __pgprot(_PAGE_WRITE));
-+ if (ret)
-+ return ret;
-+
-+ hibernate_restore_image(resume_hdr.saved_satp, (PFN_DOWN(__pa(resume_pg_dir)) | satp_mode),
-+ resume_hdr.restore_cpu_addr);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP_SMP
-+int hibernate_resume_nonboot_cpu_disable(void)
-+{
-+ if (sleep_cpu < 0) {
-+ pr_err("Failing to resume from hibernate on an unknown CPU\n");
-+ return -ENODEV;
-+ }
-+
-+ return freeze_secondary_cpus(sleep_cpu);
-+}
-+#endif
-+
-+static int __init riscv_hibernate_init(void)
-+{
-+ hibernate_cpu_context = kzalloc(sizeof(*hibernate_cpu_context), GFP_KERNEL);
-+
-+ if (WARN_ON(!hibernate_cpu_context))
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+
-+early_initcall(riscv_hibernate_init);
diff --git a/target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch b/target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch
deleted file mode 100644
index 8aec7fb7e5..0000000000
--- a/target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 6d91484ec63526def63be4097c28790f25d647b8 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Thu, 10 Aug 2023 23:23:15 +0200
-Subject: [PATCH 119/122] riscv: dts: visionfive2: add EEPROM node
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- .../boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -239,6 +239,12 @@
- pinctrl-0 = <&i2c5_pins>;
- status = "okay";
-
-+ eeprom@50 {
-+ compatible = "atmel,24c04";
-+ reg = <0x50>;
-+ pagesize = <16>;
-+ };
-+
- axp15060: pmic@36 {
- compatible = "x-powers,axp15060";
- reg = <0x36>;
diff --git a/target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch b/target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch
deleted file mode 100644
index e8067e1dcb..0000000000
--- a/target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From aa5fcd525c1a01ca07a6fdb631dbd304e22c9669 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Thu, 10 Aug 2023 23:23:45 +0200
-Subject: [PATCH 120/122] riscv: dts: visionfive2: add mmc aliases
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -13,6 +13,8 @@
- aliases {
- ethernet0 = &gmac0;
- ethernet1 = &gmac1;
-+ mmc0 = &mmc0;
-+ mmc1 = &mmc1;
- i2c0 = &i2c0;
- i2c2 = &i2c2;
- i2c5 = &i2c5;
diff --git a/target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch b/target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch
deleted file mode 100644
index 231a844b41..0000000000
--- a/target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 22b82c89dac3fadaa8c50760c25be7c78a2782a3 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Thu, 10 Aug 2023 23:42:13 +0200
-Subject: [PATCH] drivers: include cpufreq/Kconfig for riscv
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- drivers/Kconfig | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -237,6 +237,8 @@ source "drivers/most/Kconfig"
-
- source "drivers/peci/Kconfig"
-
-+source "drivers/cpufreq/Kconfig"
-+
- source "drivers/hte/Kconfig"
-
- endmenu
diff --git a/target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch b/target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
deleted file mode 100644
index d057797bb2..0000000000
--- a/target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 8a2d9c6decdbd042b3475d5ab69c1a79f0fd54aa Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 21 Aug 2023 23:29:15 +0800
-Subject: [PATCH] clk: starfive: jh7110-sys: Fix lower rate of CPUfreq by
- setting PLL0 rate to 1.5GHz
-
-CPUfreq supports 4 cpu frequency loads on 375/500/750/1500MHz.
-But now PLL0 rate is 1GHz and the cpu frequency loads become
-333/500/500/1000MHz in fact.
-
-So PLL0 rate should be set to 1.5GHz. Change the parent of cpu_root clock
-and the divider of cpu_core before the setting.
-
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC")
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clk/starfive/clk-starfive-jh7110-sys.c | 49 ++++++++++++++++++-
- 1 file changed, 48 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -7,6 +7,7 @@
- */
-
- #include <linux/auxiliary_bus.h>
-+#include <linux/clk.h>
- #include <linux/clk-provider.h>
- #include <linux/init.h>
- #include <linux/io.h>
-@@ -389,6 +390,7 @@ static int __init jh7110_syscrg_probe(st
- struct jh71x0_clk_priv *priv;
- unsigned int idx;
- int ret;
-+ struct clk *pllclk;
-
- priv = devm_kzalloc(&pdev->dev,
- struct_size(priv, reg, JH7110_SYSCLK_END),
-@@ -462,7 +464,52 @@ static int __init jh7110_syscrg_probe(st
- if (ret)
- return ret;
-
-- return jh7110_reset_controller_register(priv, "rst-sys", 0);
-+ ret = jh7110_reset_controller_register(priv, "rst-sys", 0);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * Set PLL0 rate to 1.5GHz
-+ * In order to not affect the cpu when the PLL0 rate is changing,
-+ * we need to switch the parent of cpu_root clock to osc clock first,
-+ * and then switch back after setting the PLL0 rate.
-+ */
-+ pllclk = clk_get(priv->dev, "pll0_out");
-+ if (!IS_ERR(pllclk)) {
-+ struct clk *osc = clk_get(&pdev->dev, "osc");
-+ struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;
-+ struct clk *cpu_core = priv->reg[JH7110_SYSCLK_CPU_CORE].hw.clk;
-+
-+ if (IS_ERR(osc)) {
-+ clk_put(pllclk);
-+ return PTR_ERR(osc);
-+ }
-+
-+ /*
-+ * CPU need voltage regulation by CPUfreq if set 1.5GHz.
-+ * So in this driver, cpu_core need to be set the divider to be 2 first
-+ * and will be 750M after setting parent.
-+ */
-+ ret = clk_set_rate(cpu_core, clk_get_rate(cpu_core) / 2);
-+ if (ret)
-+ goto failed_set;
-+
-+ ret = clk_set_parent(cpu_root, osc);
-+ if (ret)
-+ goto failed_set;
-+
-+ ret = clk_set_rate(pllclk, 1500000000);
-+ if (ret)
-+ goto failed_set;
-+
-+ ret = clk_set_parent(cpu_root, pllclk);
-+
-+failed_set:
-+ clk_put(pllclk);
-+ clk_put(osc);
-+ }
-+
-+ return ret;
- }
-
- static const struct of_device_id jh7110_syscrg_match[] = {
diff --git a/target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch b/target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch
deleted file mode 100644
index d009d375ca..0000000000
--- a/target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 22885637d0976473b04d4bae191fcf88e28b3df5 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 29 Sep 2021 20:50:22 +0200
-Subject: [PATCH 1000/1024] net: stmmac: dwmac-starfive: Add JH7100 support
-
-This adds support for setting the phy interface and delay chains on the
-StarFive JH7100 SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../net/ethernet/stmicro/stmmac/dwmac-starfive.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-@@ -17,6 +17,10 @@
- #define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
- #define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
-
-+#define JH7100_SYSMAIN_REGISTER28 0x70
-+/* The value below is not a typo, just really bad naming by StarFive ¯\_(ツ)_/¯ */
-+#define JH7100_SYSMAIN_REGISTER49 0xc8
-+
- struct starfive_dwmac {
- struct device *dev;
- struct clk *clk_tx;
-@@ -56,6 +60,7 @@ static int starfive_dwmac_set_mode(struc
- struct regmap *regmap;
- unsigned int args[2];
- unsigned int mode;
-+ u32 gtxclk_dlychain;
- int err;
-
- switch (plat_dat->interface) {
-@@ -65,6 +70,7 @@ static int starfive_dwmac_set_mode(struc
-
- case PHY_INTERFACE_MODE_RGMII:
- case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
- mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
- break;
-
-@@ -87,6 +93,12 @@ static int starfive_dwmac_set_mode(struc
- if (err)
- return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");
-
-+ if (!of_property_read_u32(dwmac->dev->of_node, "starfive,gtxclk-dlychain", &gtxclk_dlychain)) {
-+ err = regmap_write(regmap, JH7100_SYSMAIN_REGISTER49, gtxclk_dlychain);
-+ if (err)
-+ return dev_err_probe(dwmac->dev, err, "error selecting gtxclk delay chain\n");
-+ }
-+
- return 0;
- }
-
-@@ -149,6 +161,7 @@ static int starfive_dwmac_probe(struct p
- }
-
- static const struct of_device_id starfive_dwmac_match[] = {
-+ { .compatible = "starfive,jh7100-dwmac" },
- { .compatible = "starfive,jh7110-dwmac" },
- { /* sentinel */ }
- };
diff --git a/target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch b/target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch
deleted file mode 100644
index 5d46eab3f7..0000000000
--- a/target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From a5f12fe4b640281c04a9b8b6ad676df9eeba9aa6 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 6 Oct 2021 20:42:34 +0200
-Subject: [PATCH 1001/1024] dt-bindings: mfd: syscon: Add StarFive JH7100
- sysmain compatible
-
-Document StarFive JH7100 SoC compatible for sysmain registers.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/mfd/syscon.yaml
-+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
-@@ -69,6 +69,7 @@ properties:
- - samsung,exynos5433-sysreg
- - samsung,exynos850-sysreg
- - samsung,exynosautov9-sysreg
-+ - starfive,jh7100-sysmain
-
- - const: syscon
-
diff --git a/target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch b/target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
deleted file mode 100644
index 4a68ebdff8..0000000000
--- a/target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From a3e9dc73758c378dd471fb6b1458f39592b020fe Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Thu, 14 Oct 2021 20:56:54 +0200
-Subject: [PATCH 1002/1024] serial: 8250_dw: Add starfive,jh7100-hsuart
- compatible
-
-This adds a compatible for the high speed UARTs on the StarFive JH7100
-RISC-V SoC. Just like the regular uarts we also need to keep the input
-clocks at their default rate and rely only on the divisor in the UART.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/tty/serial/8250/8250_dw.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/tty/serial/8250/8250_dw.c
-+++ b/drivers/tty/serial/8250/8250_dw.c
-@@ -780,6 +780,7 @@ static const struct of_device_id dw8250_
- { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
- { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
- { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
-+ { .compatible = "starfive,jh7100-hsuart", .data = &dw8250_starfive_jh7100_data },
- { .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
- { /* Sentinel */ }
- };
diff --git a/target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch b/target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch
deleted file mode 100644
index a202950455..0000000000
--- a/target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 790e1157753b4dcc9bad4521987fe09aa6657876 Mon Sep 17 00:00:00 2001
-From: Geert Uytterhoeven <geert@linux-m68k.org>
-Date: Thu, 25 Nov 2021 14:21:18 +0100
-Subject: [PATCH 1003/1024] riscv: dts: starfive: Group tuples in interrupt
- properties
-
-To improve human readability and enable automatic validation, the tuples
-in the various properties containing interrupt specifiers should be
-grouped.
-
-Fix this by grouping the tuples of "interrupts-extended" properties
-using angle brackets.
-
-Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -118,15 +118,15 @@
- clint: clint@2000000 {
- compatible = "starfive,jh7100-clint", "sifive,clint0";
- reg = <0x0 0x2000000 0x0 0x10000>;
-- interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
-- &cpu1_intc 3 &cpu1_intc 7>;
-+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
-+ <&cpu1_intc 3>, <&cpu1_intc 7>;
- };
-
- plic: interrupt-controller@c000000 {
- compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
- reg = <0x0 0xc000000 0x0 0x4000000>;
-- interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9
-- &cpu1_intc 11 &cpu1_intc 9>;
-+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
-+ <&cpu1_intc 11>, <&cpu1_intc 9>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
diff --git a/target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch b/target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
deleted file mode 100644
index b57ec9121e..0000000000
--- a/target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 6a9196186f9630006c3db022bcc0bd5796f4fae5 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 17:13:22 +0100
-Subject: [PATCH 1004/1024] RISC-V: Add StarFive JH7100 audio clock node
-
-Add device tree node for the audio clocks on the StarFive JH7100 RISC-V
-SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -133,6 +133,16 @@
- riscv,ndev = <133>;
- };
-
-+ audclk: clock-controller@10480000 {
-+ compatible = "starfive,jh7100-audclk";
-+ reg = <0x0 0x10480000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
-+ <&clkgen JH7100_CLK_AUDIO_12288>,
-+ <&clkgen JH7100_CLK_DOM7AHB_BUS>;
-+ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
-+ #clock-cells = <1>;
-+ };
-+
- clkgen: clock-controller@11800000 {
- compatible = "starfive,jh7100-clkgen";
- reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch b/target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch
deleted file mode 100644
index 11fa1155d6..0000000000
--- a/target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From a22e1110a6ffcc2cf4b3b598f037879cbd0915d3 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 31 Aug 2022 22:54:07 +0200
-Subject: [PATCH 1005/1024] RISC-V: Mark StarFive JH7100 as having non-coherent
- DMAs
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -111,6 +111,7 @@
- soc {
- compatible = "simple-bus";
- interrupt-parent = <&plic>;
-+ dma-noncoherent;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
diff --git a/target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch b/target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch
deleted file mode 100644
index feb52591b3..0000000000
--- a/target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From d0c1660c9e88748c9eba81ff3839de54dffba6ad Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Fri, 8 Jan 2021 03:11:04 +0800
-Subject: [PATCH 1006/1024] drivers/tty/serial/8250: update driver for JH7100
-
----
- drivers/tty/serial/8250/8250_port.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/tty/serial/8250/8250_port.c
-+++ b/drivers/tty/serial/8250/8250_port.c
-@@ -72,8 +72,16 @@ static const struct serial8250_config ua
- },
- [PORT_16550] = {
- .name = "16550",
-+#ifdef CONFIG_SOC_STARFIVE
-+ .fifo_size = 16,
-+ .tx_loadsz = 16,
-+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
-+ .rxtrig_bytes = {1, 4, 8, 14},
-+ .flags = UART_CAP_FIFO,
-+#else
- .fifo_size = 1,
- .tx_loadsz = 1,
-+#endif
- },
- [PORT_16550A] = {
- .name = "16550A",
diff --git a/target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch b/target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
deleted file mode 100644
index 1599e8a2ca..0000000000
--- a/target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 5fdd2623dd3eed156fa1ec65b2096da735bb0cde Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Wed, 17 Nov 2021 14:50:45 +0800
-Subject: [PATCH 1007/1024] dmaengine: dw-axi-dmac: Handle xfer start while
- non-idle
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
----
- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 +++++++++++-
- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
- 2 files changed, 12 insertions(+), 1 deletion(-)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -382,11 +382,13 @@ static void axi_chan_block_xfer_start(st
- u32 irq_mask;
- u8 lms = 0; /* Select AXI0 master for LLI fetching */
-
-+ chan->is_err = false;
- if (unlikely(axi_chan_is_hw_enable(chan))) {
- dev_err(chan2dev(chan), "%s is non-idle!\n",
- axi_chan_name(chan));
-
-- return;
-+ axi_chan_disable(chan);
-+ chan->is_err = true;
- }
-
- axi_dma_enable(chan->chip);
-@@ -1028,6 +1030,14 @@ static noinline void axi_chan_handle_err
- axi_chan_name(chan));
- goto out;
- }
-+ if (chan->is_err) {
-+ struct axi_dma_desc *desc = vd_to_axi_desc(vd);
-+
-+ axi_chan_block_xfer_start(chan, desc);
-+ chan->is_err = false;
-+ goto out;
-+ }
-+
- /* Remove the completed descriptor from issued list */
- list_del(&vd->node);
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-@@ -50,6 +50,7 @@ struct axi_dma_chan {
- struct dma_slave_config config;
- enum dma_transfer_direction direction;
- bool cyclic;
-+ bool is_err;
- /* these other elements are all protected by vc.lock */
- bool is_paused;
- };
diff --git a/target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch b/target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
deleted file mode 100644
index e01c37fd76..0000000000
--- a/target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From c06352c09ce55999d41036e593293a3aaf0cf70c Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Wed, 17 Nov 2021 14:50:45 +0800
-Subject: [PATCH 1008/1024] dmaengine: dw-axi-dmac: Add StarFive JH7100 support
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 ++++++++++++
- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 4 ++++
- 2 files changed, 16 insertions(+)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -677,8 +677,13 @@ static int dw_axi_dma_set_hw_desc(struct
-
- hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
-
-+#ifdef CONFIG_SOC_STARFIVE
-+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
-+ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
-+#else
- ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
-+#endif
- hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
-
- set_desc_src_master(hw_desc);
-@@ -1508,7 +1513,11 @@ static int dw_probe(struct platform_devi
- * Therefore, set constraint to 1024 * 4.
- */
- dw->dma.dev->dma_parms = &dw->dma_parms;
-+#ifdef CONFIG_SOC_STARFIVE
-+ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
-+#else
- dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
-+#endif
- platform_set_drvdata(pdev, chip);
-
- pm_runtime_enable(chip->dev);
-@@ -1593,6 +1602,9 @@ static const struct of_device_id dw_dma_
- .compatible = "intel,kmb-axi-dma",
- .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
- }, {
-+ .compatible = "starfive,jh7100-axi-dma",
-+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
-+ }, {
- .compatible = "starfive,jh7110-axi-dma",
- .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
- },
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-@@ -283,7 +283,11 @@ enum {
- #define CH_CTL_L_SRC_MAST BIT(0)
-
- /* CH_CFG_H */
-+#ifdef CONFIG_SOC_STARFIVE
-+#define CH_CFG_H_PRIORITY_POS 15
-+#else
- #define CH_CFG_H_PRIORITY_POS 17
-+#endif
- #define CH_CFG_H_DST_PER_POS 12
- #define CH_CFG_H_SRC_PER_POS 7
- #define CH_CFG_H_HS_SEL_DST_POS 4
diff --git a/target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch b/target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch
deleted file mode 100644
index d2873ff968..0000000000
--- a/target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 89c86fda8cee5b93ce213dcc46b2cf27e5ee3312 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 17 Jul 2021 21:50:38 +0200
-Subject: [PATCH 1009/1024] pinctrl: starfive: Reset pinmux settings
-
-Current u-boot doesn't seem to take into account that some GPIOs are
-configured as inputs/outputs of certain peripherals on power-up. This
-means it ends up configuring some GPIOs as inputs to more than one
-peripheral which the documentation explicitly says is illegal. Similarly
-it also ends up configuring more than one GPIO as output of the same
-peripheral. While not explicitly mentioned by the documentation this
-also seems like a bad idea.
-
-The easiest way to remedy this mess is to just disconnect all GPIOs from
-peripherals and have our pinmux configuration set everything up
-properly. This, however, means that we'd disconnect the serial console
-from its pins for a while, so add a device tree property to keep
-certain GPIOs from being reset.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../pinctrl/starfive,jh7100-pinctrl.yaml | 4 ++
- .../starfive/pinctrl-starfive-jh7100.c | 66 +++++++++++++++++++
- 2 files changed, 70 insertions(+)
-
---- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
-+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
-@@ -88,6 +88,10 @@ properties:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [0, 1, 2, 3, 4, 5, 6]
-
-+ starfive,keep-gpiomux:
-+ description: Keep pinmux for these GPIOs from being reset at boot.
-+ $ref: /schemas/types.yaml#/definitions/uint32-array
-+
- required:
- - compatible
- - reg
---- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
-@@ -200,6 +200,10 @@ static u16 starfive_drive_strength_from_
- return (clamp(i, 14U, 63U) - 14) / 7;
- }
-
-+static bool keepmux;
-+module_param(keepmux, bool, 0644);
-+MODULE_PARM_DESC(keepmux, "Keep pinmux settings from previous boot stage");
-+
- struct starfive_pinctrl {
- struct gpio_chip gc;
- struct pinctrl_gpio_range gpios;
-@@ -1222,6 +1226,65 @@ static void starfive_disable_clock(void
- clk_disable_unprepare(data);
- }
-
-+#define GPI_END (GPI_USB_OVER_CURRENT + 1)
-+static void starfive_pinmux_reset(struct starfive_pinctrl *sfp)
-+{
-+ static const DECLARE_BITMAP(defaults, GPI_END) = {
-+ BIT_MASK(GPI_I2C0_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C0_PAD_SDA_IN) |
-+ BIT_MASK(GPI_I2C1_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C1_PAD_SDA_IN) |
-+ BIT_MASK(GPI_I2C2_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C2_PAD_SDA_IN) |
-+ BIT_MASK(GPI_I2C3_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C3_PAD_SDA_IN) |
-+ BIT_MASK(GPI_SDIO0_PAD_CARD_DETECT_N) |
-+
-+ BIT_MASK(GPI_SDIO1_PAD_CARD_DETECT_N) |
-+ BIT_MASK(GPI_SPI0_PAD_SS_IN_N) |
-+ BIT_MASK(GPI_SPI1_PAD_SS_IN_N) |
-+ BIT_MASK(GPI_SPI2_PAD_SS_IN_N) |
-+ BIT_MASK(GPI_SPI2AHB_PAD_SS_N) |
-+ BIT_MASK(GPI_SPI3_PAD_SS_IN_N),
-+
-+ BIT_MASK(GPI_UART0_PAD_SIN) |
-+ BIT_MASK(GPI_UART1_PAD_SIN) |
-+ BIT_MASK(GPI_UART2_PAD_SIN) |
-+ BIT_MASK(GPI_UART3_PAD_SIN) |
-+ BIT_MASK(GPI_USB_OVER_CURRENT)
-+ };
-+ DECLARE_BITMAP(keep, NR_GPIOS) = {};
-+ struct device_node *np = sfp->gc.parent->of_node;
-+ int len = of_property_count_u32_elems(np, "starfive,keep-gpiomux");
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ u32 gpio;
-+
-+ of_property_read_u32_index(np, "starfive,keep-gpiomux", i, &gpio);
-+ if (gpio < NR_GPIOS)
-+ set_bit(gpio, keep);
-+ }
-+
-+ for (i = 0; i < NR_GPIOS; i++) {
-+ if (test_bit(i, keep))
-+ continue;
-+
-+ writel_relaxed(GPO_DISABLE, sfp->base + GPON_DOEN_CFG + 8 * i);
-+ writel_relaxed(GPO_LOW, sfp->base + GPON_DOUT_CFG + 8 * i);
-+ }
-+
-+ for (i = 0; i < GPI_END; i++) {
-+ void __iomem *reg = sfp->base + GPI_CFG_OFFSET + 4 * i;
-+ u32 din = readl_relaxed(reg);
-+
-+ if (din >= 2 && din < (NR_GPIOS + 2) && test_bit(din - 2, keep))
-+ continue;
-+
-+ writel_relaxed(test_bit(i, defaults), reg);
-+ }
-+}
-+
- static int starfive_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -1283,6 +1346,9 @@ static int starfive_probe(struct platfor
- writel(value, sfp->padctl + IO_PADSHARE_SEL);
- }
-
-+ if (!keepmux)
-+ starfive_pinmux_reset(sfp);
-+
- value = readl(sfp->padctl + IO_PADSHARE_SEL);
- switch (value) {
- case 0:
diff --git a/target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch b/target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
deleted file mode 100644
index a12be8b979..0000000000
--- a/target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
+++ /dev/null
@@ -1,302 +0,0 @@
-From f6c0c8639c7424f915f2f2f18cf86b6b97c7d32a Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Date: Sat, 25 Mar 2023 22:57:06 +0100
-Subject: [PATCH 1010/1024] clk: starfive: Add flags argument to JH71X0__MUX
- macro
-
-This flag is needed to add the CLK_SET_RATE_PARENT flag on the gmac_tx
-clock on the JH7100, which in turn is needed by the dwmac-starfive
-driver to set the clock properly for 1000, 100 and 10 Mbps links.
-
-This change was mostly made using coccinelle:
-
-@ match @
-expression idx, name, nparents;
-@@
- JH71X0__MUX(
--idx, name, nparents,
-+idx, name, 0, nparents,
- ...)
-
-Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- .../clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
- drivers/clk/starfive/clk-starfive-jh7100.c | 32 +++++++++----------
- .../clk/starfive/clk-starfive-jh7110-aon.c | 6 ++--
- .../clk/starfive/clk-starfive-jh7110-isp.c | 2 +-
- .../clk/starfive/clk-starfive-jh7110-sys.c | 26 +++++++--------
- drivers/clk/starfive/clk-starfive-jh71x0.h | 4 +--
- 6 files changed, 36 insertions(+), 36 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-@@ -80,7 +80,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
- JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
- JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
-+ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 0, 2,
- JH7100_AUDCLK_VAD_INTMEM,
- JH7100_AUDCLK_AUDIO_12288),
- };
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -24,48 +24,48 @@
- #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
-
- static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
-- JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
-+ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 0, 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
-+ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
-+ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 0, 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
-+ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT),
-- JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 0, 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
- JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
-- JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
-+ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
-+ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT),
-- JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 0, 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-@@ -76,7 +76,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
- JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
- JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
-- JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
-+ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_OSC_AUD),
- JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-@@ -142,7 +142,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
- JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
-- JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
-+ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 0, 2,
- JH7100_CLK_CPU_AXI,
- JH7100_CLK_NNEBUS_SRC1),
- JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
-@@ -166,7 +166,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
- JH7100_CLK_USBPHY_ROOTDIV),
-- JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
-+ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_USBPHY_PLLDIV25M),
- JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
-@@ -200,12 +200,12 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
-+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
- JH7100_CLK_GMAC_RMII_TX),
- JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
-- JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
-+ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 0, 2,
- JH7100_CLK_GMAC_GR_MII_RX,
- JH7100_CLK_GMAC_RMII_RX),
- JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
---- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
-@@ -26,7 +26,7 @@
- static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
- /* source */
- JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
-- JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
-+ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 0, 2,
- JH7110_AONCLK_OSC_DIV4,
- JH7110_AONCLK_OSC),
- /* gmac0 */
-@@ -39,7 +39,7 @@ static const struct jh71x0_clk_data jh71
- JH7110_AONCLK_GMAC0_GTXCLK,
- JH7110_AONCLK_GMAC0_RMII_RTX),
- JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
-- JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
-+ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 0, 2,
- JH7110_AONCLK_GMAC0_RGMII_RXIN,
- JH7110_AONCLK_GMAC0_RMII_RTX),
- JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
-@@ -48,7 +48,7 @@ static const struct jh71x0_clk_data jh71
- /* rtc */
- JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
- JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
-- JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
-+ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 0, 2,
- JH7110_AONCLK_RTC_OSC,
- JH7110_AONCLK_RTC_INTERNAL),
- JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
---- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
-@@ -53,7 +53,7 @@ static const struct jh71x0_clk_data jh71
- JH7110_ISPCLK_MIPI_RX0_PXL),
- JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
- JH7110_ISPCLK_MIPI_RX0_PXL),
-- JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
-+ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 0, 2,
- JH7110_ISPCLK_MIPI_RX0_PXL,
- JH7110_ISPCLK_DVP_INV),
- /* ispv2_top_wrapper */
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -36,18 +36,18 @@
-
- static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
- /* root */
-- JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 0, 2,
- JH7110_SYSCLK_OSC,
- JH7110_SYSCLK_PLL0_OUT),
- JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
- JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
-- JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 0, 2,
- JH7110_SYSCLK_PLL2_OUT,
- JH7110_SYSCLK_PLL1_OUT),
- JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
- JH7110_SYSCLK_PLL0_OUT,
- JH7110_SYSCLK_PLL2_OUT),
-- JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 0, 2,
- JH7110_SYSCLK_OSC,
- JH7110_SYSCLK_PLL2_OUT),
- JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
-@@ -62,7 +62,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
- JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
- JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
-- JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 0, 2,
- JH7110_SYSCLK_MCLK_INNER,
- JH7110_SYSCLK_MCLK_EXT),
- JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
-@@ -96,7 +96,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
- JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
- JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
-- JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
-+ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 0, 4,
- JH7110_SYSCLK_OSC_DIV2,
- JH7110_SYSCLK_PLL1_DIV2,
- JH7110_SYSCLK_PLL1_DIV4,
-@@ -186,7 +186,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
- JH7110_SYSCLK_GMAC1_RMII_REFIN),
- JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-- JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 0, 2,
- JH7110_SYSCLK_GMAC1_RGMII_RXIN,
- JH7110_SYSCLK_GMAC1_RMII_RTX),
- JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
-@@ -270,11 +270,11 @@ static const struct jh71x0_clk_data jh71
- JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
- JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
- JH7110_SYSCLK_I2STX0_BCLK_MST),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 0, 2,
- JH7110_SYSCLK_I2STX0_BCLK_MST,
- JH7110_SYSCLK_I2STX_BCLK_EXT),
- JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 0, 2,
- JH7110_SYSCLK_I2STX0_LRCK_MST,
- JH7110_SYSCLK_I2STX_LRCK_EXT),
- /* i2stx1 */
-@@ -285,11 +285,11 @@ static const struct jh71x0_clk_data jh71
- JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
- JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
- JH7110_SYSCLK_I2STX1_BCLK_MST),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 0, 2,
- JH7110_SYSCLK_I2STX1_BCLK_MST,
- JH7110_SYSCLK_I2STX_BCLK_EXT),
- JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 0, 2,
- JH7110_SYSCLK_I2STX1_LRCK_MST,
- JH7110_SYSCLK_I2STX_LRCK_EXT),
- /* i2srx */
-@@ -300,11 +300,11 @@ static const struct jh71x0_clk_data jh71
- JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
- JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
- JH7110_SYSCLK_I2SRX_BCLK_MST),
-- JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 0, 2,
- JH7110_SYSCLK_I2SRX_BCLK_MST,
- JH7110_SYSCLK_I2SRX_BCLK_EXT),
- JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
-- JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 0, 2,
- JH7110_SYSCLK_I2SRX_LRCK_MST,
- JH7110_SYSCLK_I2SRX_LRCK_EXT),
- /* pdm */
-@@ -314,7 +314,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
- JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
- JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
-- JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 0, 2,
- JH7110_SYSCLK_TDM_INTERNAL,
- JH7110_SYSCLK_TDM_EXT),
- JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
---- a/drivers/clk/starfive/clk-starfive-jh71x0.h
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
-@@ -61,10 +61,10 @@ struct jh71x0_clk_data {
- .parents = { [0] = _parent }, \
- }
-
--#define JH71X0__MUX(_idx, _name, _nparents, ...) \
-+#define JH71X0__MUX(_idx, _name, _flags, _nparents, ...) \
- [_idx] = { \
- .name = _name, \
-- .flags = 0, \
-+ .flags = _flags, \
- .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
- .parents = { __VA_ARGS__ }, \
- }
diff --git a/target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch b/target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
deleted file mode 100644
index e5e750820e..0000000000
--- a/target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 38d50c243d2d4176b88ad732f4948cca9629251b Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Date: Sat, 25 Mar 2023 23:04:31 +0100
-Subject: [PATCH 1011/1024] clk: starfive: jh7100: Add CLK_SET_RATE_PARENT to
- gmac_tx
-
-This is needed by the dwmac-starfive ethernet driver to set the clock
-for 1000, 100 and 10 Mbps links properly.
-
-Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -200,7 +200,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
-+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
- JH7100_CLK_GMAC_RMII_TX),
diff --git a/target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch b/target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch
deleted file mode 100644
index 3afdf1d9a6..0000000000
--- a/target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 3e73731c113fbe6f319403d5e2e64a656fcb17ce Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Thu, 14 Oct 2021 20:35:43 +0200
-Subject: [PATCH 1012/1024] clk: starfive: jh7100: Keep more clocks alive
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/clk/starfive/clk-starfive-jh7100.c | 37 +++++++++++-----------
- 1 file changed, 19 insertions(+), 18 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -94,9 +94,9 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
- JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
-- JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
-- JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
-- JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
- JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
- JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
- JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
-@@ -160,11 +160,12 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
- JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
- JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
-- JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
-+ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
-+ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
- JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
-- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
-- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", CLK_IGNORE_UNUSED, 8,
-+ JH7100_CLK_USBPHY_ROOTDIV),
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", CLK_IGNORE_UNUSED, 32,
- JH7100_CLK_USBPHY_ROOTDIV),
- JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
- JH7100_CLK_OSC_SYS,
-@@ -183,23 +184,23 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
- JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
- JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
-- JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", CLK_IGNORE_UNUSED, 4, JH7100_CLK_VOUT_ROOT),
- JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
- JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
-- JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
-- JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
- JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
- JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
- JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
- JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
-- JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", CLK_IGNORE_UNUSED, JH7100_CLK_AHB_BUS),
- JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
-- JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
-- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
-- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", CLK_IGNORE_UNUSED, 31, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", CLK_IGNORE_UNUSED, 255, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
-@@ -209,8 +210,8 @@ static const struct jh71x0_clk_data jh71
- JH7100_CLK_GMAC_GR_MII_RX,
- JH7100_CLK_GMAC_RMII_RX),
- JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
-- JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", CLK_IGNORE_UNUSED, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", CLK_IGNORE_UNUSED, 127, JH7100_CLK_GMAC_ROOT_DIV),
- JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
- JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
-@@ -223,7 +224,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
- JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
- JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
-- JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
- JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
- JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
- JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
diff --git a/target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch b/target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch
deleted file mode 100644
index 5bbb4cc4c5..0000000000
--- a/target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 1889527687432bd63942c86dbebf8686b6515aad Mon Sep 17 00:00:00 2001
-From: Matteo Croce <technoboy85@gmail.com>
-Date: Fri, 21 May 2021 03:26:38 +0200
-Subject: [PATCH 1013/1024] net: stmmac: use GFP_DMA32
-
-Signed-off-by: Matteo Croce <mcroce@microsoft.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -1436,7 +1436,7 @@ static int stmmac_init_rx_buffers(struct
- {
- struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
-+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
-
- if (priv->dma_cap.host_dma_width <= 32)
- gfp |= GFP_DMA32;
-@@ -4615,7 +4615,7 @@ static inline void stmmac_rx_refill(stru
- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int dirty = stmmac_rx_dirty(priv, queue);
- unsigned int entry = rx_q->dirty_rx;
-- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
-+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
-
- if (priv->dma_cap.host_dma_width <= 32)
- gfp |= GFP_DMA32;
diff --git a/target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch b/target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
deleted file mode 100644
index 86d3b1d839..0000000000
--- a/target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
+++ /dev/null
@@ -1,477 +0,0 @@
-From 919bcebc58044a266e953ac302c8e068e255e2a6 Mon Sep 17 00:00:00 2001
-From: Huan Feng <huan.feng@starfivetech.com>
-Date: Fri, 8 Jan 2021 03:35:42 +0800
-Subject: [PATCH 1014/1024] hwrng: Add StarFive JH7100 Random Number Generator
- driver
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/char/hw_random/Kconfig | 13 ++
- drivers/char/hw_random/Makefile | 1 +
- drivers/char/hw_random/starfive-vic-rng.c | 256 ++++++++++++++++++++++
- drivers/char/hw_random/starfive-vic-rng.h | 167 ++++++++++++++
- 4 files changed, 437 insertions(+)
- create mode 100644 drivers/char/hw_random/starfive-vic-rng.c
- create mode 100644 drivers/char/hw_random/starfive-vic-rng.h
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -322,6 +322,19 @@ config HW_RANDOM_POWERNV
-
- If unsure, say Y.
-
-+config HW_RANDOM_STARFIVE_VIC
-+ tristate "Starfive VIC Random Number Generator support"
-+ depends on HW_RANDOM && (SOC_STARFIVE || COMPILE_TEST)
-+ default SOC_STARFIVE
-+ help
-+ This driver provides kernel-side support for the Random Number
-+ Generator hardware found on Starfive VIC SoC.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called starfive-vic-rng.
-+
-+ If unsure, say Y.
-+
- config HW_RANDOM_HISI
- tristate "Hisilicon Random Number Generator support"
- depends on HW_RANDOM && ARCH_HISI
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -28,6 +28,7 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon
- obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
- obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
- obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
-+obj-$(CONFIG_HW_RANDOM_STARFIVE_VIC) += starfive-vic-rng.o
- obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
- obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
- obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
---- /dev/null
-+++ b/drivers/char/hw_random/starfive-vic-rng.c
-@@ -0,0 +1,256 @@
-+/*
-+ ******************************************************************************
-+ * @file starfive-vic-rng.c
-+ * @author StarFive Technology
-+ * @version V1.0
-+ * @date 08/13/2020
-+ * @brief
-+ ******************************************************************************
-+ * @copy
-+ *
-+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
-+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
-+ *
-+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
-+ */
-+#include <linux/err.h>
-+#include <linux/kernel.h>
-+#include <linux/hw_random.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/random.h>
-+
-+#include "starfive-vic-rng.h"
-+
-+#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
-+
-+struct vic_rng {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct hwrng rng;
-+};
-+
-+static inline void vic_wait_till_idle(struct vic_rng *hrng)
-+{
-+ while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
-+ ;
-+}
-+
-+static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
-+{
-+ // clear register: ISTAT
-+ u32 data = readl(hrng->base + VIC_ISTAT);
-+ writel(data, hrng->base + VIC_ISTAT);
-+ writel(0, hrng->base + VIC_ALARM);
-+}
-+
-+static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd) {
-+ int res = 0;
-+ // wait till idle
-+ vic_wait_till_idle(hrng);
-+ switch (cmd) {
-+ case VIC_CTRL_CMD_NOP:
-+ case VIC_CTRL_CMD_GEN_NOISE:
-+ case VIC_CTRL_CMD_GEN_NONCE:
-+ case VIC_CTRL_CMD_CREATE_STATE:
-+ case VIC_CTRL_CMD_RENEW_STATE:
-+ case VIC_CTRL_CMD_REFRESH_ADDIN:
-+ case VIC_CTRL_CMD_GEN_RANDOM:
-+ case VIC_CTRL_CMD_ADVANCE_STATE:
-+ case VIC_CTRL_CMD_KAT:
-+ case VIC_CTRL_CMD_ZEROIZE:
-+ writel(cmd, hrng->base + VIC_CTRL);
-+ break;
-+ default:
-+ res = -1;
-+ break;
-+ }
-+
-+ return res;
-+}
-+
-+static int vic_rng_init(struct hwrng *rng)
-+{
-+ struct vic_rng *hrng = to_vic_rng(rng);
-+
-+ // wait till idle
-+
-+ // clear register: ISTAT
-+ vic_rng_irq_mask_clear(hrng);
-+
-+ // set mission mode
-+ writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
-+
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
-+ vic_wait_till_idle(hrng);
-+
-+ // set interrupt
-+ writel(VIC_IE_ALL, hrng->base + VIC_IE);
-+
-+ // zeroize
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
-+
-+ vic_wait_till_idle(hrng);
-+
-+ return 0;
-+}
-+
-+static irqreturn_t vic_rng_irq(int irq, void *priv)
-+{
-+ u32 status, val;
-+ struct vic_rng *hrng = (struct vic_rng *)priv;
-+
-+ /*
-+ * clearing the interrupt will also clear the error register
-+ * read error and status before clearing
-+ */
-+ status = readl(hrng->base + VIC_ISTAT);
-+
-+ if (status & VIC_ISTAT_ALARMS) {
-+ writel(VIC_ISTAT_ALARMS, hrng->base + VIC_ISTAT);
-+ val = readl(hrng->base + VIC_ALARM);
-+ if (val & VIC_ALARM_ILLEGAL_CMD_SEQ) {
-+ writel(VIC_ALARM_ILLEGAL_CMD_SEQ, hrng->base + VIC_ALARM);
-+ //dev_info(hrng->dev, "ILLEGAL CMD SEQ: LAST_CMD=0x%x\r\n",
-+ //VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)));
-+ } else {
-+ dev_info(hrng->dev, "Failed test: %x\r\n", val);
-+ }
-+ }
-+
-+ if (status & VIC_ISTAT_ZEROIZE) {
-+ writel(VIC_ISTAT_ZEROIZE, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "zeroized\r\n");
-+ }
-+
-+ if (status & VIC_ISTAT_KAT_COMPLETE) {
-+ writel(VIC_ISTAT_KAT_COMPLETE, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "kat_completed\r\n");
-+ }
-+
-+ if (status & VIC_ISTAT_NOISE_RDY) {
-+ writel(VIC_ISTAT_NOISE_RDY, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "noise_rdy\r\n");
-+ }
-+
-+ if (status & VIC_ISTAT_DONE) {
-+ writel(VIC_ISTAT_DONE, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "done\r\n");
-+ /*
-+ if (VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)) ==
-+ VIC_CTRL_CMD_GEN_RANDOM) {
-+ dev_info(hrng->dev, "Need Update Buffer\r\n");
-+ }
-+ */
-+ }
-+ vic_rng_irq_mask_clear(hrng);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void vic_rng_cleanup(struct hwrng *rng)
-+{
-+ struct vic_rng *hrng = to_vic_rng(rng);
-+
-+ writel(0, hrng->base + VIC_CTRL);
-+}
-+
-+static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-+{
-+ struct vic_rng *hrng = to_vic_rng(rng);
-+
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
-+
-+ vic_wait_till_idle(hrng);
-+ max = min_t(size_t, max, (VIC_RAND_LEN * 4));
-+
-+ writel(0x0, hrng->base + VIC_MODE);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
-+
-+ vic_wait_till_idle(hrng);
-+ memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
-+
-+ vic_wait_till_idle(hrng);
-+ return max;
-+}
-+
-+static int vic_rng_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int irq;
-+ struct vic_rng *rng;
-+ struct resource *res;
-+
-+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
-+ if (!rng){
-+ return -ENOMEM;
-+ }
-+
-+ platform_set_drvdata(pdev, rng);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ rng->base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(rng->base)){
-+ return PTR_ERR(rng->base);
-+ }
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq <= 0) {
-+ dev_err(&pdev->dev, "Couldn't get irq %d\n", irq);
-+ return irq;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irq, vic_rng_irq, 0, pdev->name,
-+ (void *)rng);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Can't get interrupt working.\n");
-+ return ret;
-+ }
-+
-+ rng->rng.name = pdev->name;
-+ rng->rng.init = vic_rng_init;
-+ rng->rng.cleanup = vic_rng_cleanup;
-+ rng->rng.read = vic_rng_read;
-+
-+ rng->dev = &pdev->dev;
-+
-+ ret = devm_hwrng_register(&pdev->dev, &rng->rng);
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to register hwrng\n");
-+ return ret;
-+ }
-+
-+ dev_info(&pdev->dev, "Initialized\n");
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id vic_rng_dt_ids[] = {
-+ { .compatible = "starfive,vic-rng" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, vic_rng_dt_ids);
-+
-+static struct platform_driver vic_rng_driver = {
-+ .probe = vic_rng_probe,
-+ .driver = {
-+ .name = "vic-rng",
-+ .of_match_table = vic_rng_dt_ids,
-+ },
-+};
-+
-+module_platform_driver(vic_rng_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
-+MODULE_DESCRIPTION("Starfive VIC random number generator driver");
---- /dev/null
-+++ b/drivers/char/hw_random/starfive-vic-rng.h
-@@ -0,0 +1,167 @@
-+/*
-+ ******************************************************************************
-+ * @file starfive-vic-rng.h
-+ * @author StarFive Technology
-+ * @version V1.0
-+ * @date 08/13/2020
-+ * @brief
-+ ******************************************************************************
-+ * @copy
-+ *
-+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
-+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
-+ *
-+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
-+ */
-+
-+#define VIC_CTRL 0x00
-+#define VIC_MODE 0x04
-+#define VIC_SMODE 0x08
-+#define VIC_STAT 0x0C
-+#define VIC_IE 0x10
-+#define VIC_ISTAT 0x14
-+#define VIC_ALARM 0x18
-+#define VIC_BUILD_ID 0x1C
-+#define VIC_FEATURES 0x20
-+#define VIC_RAND0 0x24
-+#define VIC_NPA_DATA0 0x34
-+#define VIC_SEED0 0x74
-+#define VIC_IA_RDATA 0xA4
-+#define VIC_IA_WDATA 0xA8
-+#define VIC_IA_ADDR 0xAC
-+#define VIC_IA_CMD 0xB0
-+
-+/* CTRL */
-+#define VIC_CTRL_CMD_NOP 0
-+#define VIC_CTRL_CMD_GEN_NOISE 1
-+#define VIC_CTRL_CMD_GEN_NONCE 2
-+#define VIC_CTRL_CMD_CREATE_STATE 3
-+#define VIC_CTRL_CMD_RENEW_STATE 4
-+#define VIC_CTRL_CMD_REFRESH_ADDIN 5
-+#define VIC_CTRL_CMD_GEN_RANDOM 6
-+#define VIC_CTRL_CMD_ADVANCE_STATE 7
-+#define VIC_CTRL_CMD_KAT 8
-+#define VIC_CTRL_CMD_ZEROIZE 15
-+
-+/* MODE */
-+#define _VIC_MODE_ADDIN_PRESENT 4
-+#define _VIC_MODE_PRED_RESIST 3
-+#define _VIC_MODE_KAT_SEL 2
-+#define _VIC_MODE_KAT_VEC 1
-+#define _VIC_MODE_SEC_ALG 0
-+
-+#define VIC_MODE_ADDIN_PRESENT (1UL << _VIC_MODE_ADDIN_PRESENT)
-+#define VIC_MODE_PRED_RESIST (1UL << _VIC_MODE_PRED_RESIST)
-+#define VIC_MODE_KAT_SEL (1UL << _VIC_MODE_KAT_SEL)
-+#define VIC_MODE_KAT_VEC (1UL << _VIC_MODE_KAT_VEC)
-+#define VIC_MODE_SEC_ALG (1UL << _VIC_MODE_SEC_ALG)
-+
-+/* SMODE */
-+#define _VIC_SMODE_MAX_REJECTS 2
-+#define _VIC_SMODE_SECURE_EN 1
-+#define _VIC_SMODE_NONCE 0
-+
-+#define VIC_SMODE_MAX_REJECTS(x) ((x) << _VIC_SMODE_MAX_REJECTS)
-+#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
-+#define VIC_SMODE_NONCE (1UL << _VIC_SMODE_NONCE)
-+
-+/* STAT */
-+#define _VIC_STAT_BUSY 31
-+#define _VIC_STAT_DRBG_STATE 7
-+#define _VIC_STAT_SECURE 6
-+#define _VIC_STAT_NONCE_MODE 5
-+#define _VIC_STAT_SEC_ALG 4
-+#define _VIC_STAT_LAST_CMD 0
-+
-+#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
-+#define VIC_STAT_DRBG_STATE (1UL << _VIC_STAT_DRBG_STATE)
-+#define VIC_STAT_SECURE (1UL << _VIC_STAT_SECURE)
-+#define VIC_STAT_NONCE_MODE (1UL << _VIC_STAT_NONCE_MODE)
-+#define VIC_STAT_SEC_ALG (1UL << _VIC_STAT_SEC_ALG)
-+#define VIC_STAT_LAST_CMD(x) (((x) >> _VIC_STAT_LAST_CMD) & 0xF)
-+
-+/* IE */
-+#define _VIC_IE_GLBL 31
-+#define _VIC_IE_DONE 4
-+#define _VIC_IE_ALARMS 3
-+#define _VIC_IE_NOISE_RDY 2
-+#define _VIC_IE_KAT_COMPLETE 1
-+#define _VIC_IE_ZEROIZE 0
-+
-+#define VIC_IE_GLBL (1UL << _VIC_IE_GLBL)
-+#define VIC_IE_DONE (1UL << _VIC_IE_DONE)
-+#define VIC_IE_ALARMS (1UL << _VIC_IE_ALARMS)
-+#define VIC_IE_NOISE_RDY (1UL << _VIC_IE_NOISE_RDY)
-+#define VIC_IE_KAT_COMPLETE (1UL << _VIC_IE_KAT_COMPLETE)
-+#define VIC_IE_ZEROIZE (1UL << _VIC_IE_ZEROIZE)
-+#define VIC_IE_ALL (VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
-+ VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
-+
-+/* ISTAT */
-+#define _VIC_ISTAT_DONE 4
-+#define _VIC_ISTAT_ALARMS 3
-+#define _VIC_ISTAT_NOISE_RDY 2
-+#define _VIC_ISTAT_KAT_COMPLETE 1
-+#define _VIC_ISTAT_ZEROIZE 0
-+
-+#define VIC_ISTAT_DONE (1UL << _VIC_ISTAT_DONE)
-+#define VIC_ISTAT_ALARMS (1UL << _VIC_ISTAT_ALARMS)
-+#define VIC_ISTAT_NOISE_RDY (1UL << _VIC_ISTAT_NOISE_RDY)
-+#define VIC_ISTAT_KAT_COMPLETE (1UL << _VIC_ISTAT_KAT_COMPLETE)
-+#define VIC_ISTAT_ZEROIZE (1UL << _VIC_ISTAT_ZEROIZE)
-+
-+/* ALARMS */
-+#define VIC_ALARM_ILLEGAL_CMD_SEQ (1UL << 4)
-+#define VIC_ALARM_FAILED_TEST_ID_OK 0
-+#define VIC_ALARM_FAILED_TEST_ID_KAT_STAT 1
-+#define VIC_ALARM_FAILED_TEST_ID_KAT 2
-+#define VIC_ALARM_FAILED_TEST_ID_MONOBIT 3
-+#define VIC_ALARM_FAILED_TEST_ID_RUN 4
-+#define VIC_ALARM_FAILED_TEST_ID_LONGRUN 5
-+#define VIC_ALARM_FAILED_TEST_ID_AUTOCORRELATION 6
-+#define VIC_ALARM_FAILED_TEST_ID_POKER 7
-+#define VIC_ALARM_FAILED_TEST_ID_REPETITION_COUNT 8
-+#define VIC_ALARM_FAILED_TEST_ID_ADAPATIVE_PROPORTION 9
-+
-+/* BUILD_ID */
-+#define VIC_BUILD_ID_STEPPING(x) (((x) >> 28) & 0xF)
-+#define VIC_BUILD_ID_EPN(x) ((x) & 0xFFFF)
-+
-+/* FEATURES */
-+#define VIC_FEATURES_AES_256(x) (((x) >> 9) & 1)
-+#define VIC_FEATURES_EXTRA_PS_PRESENT(x) (((x) >> 8) & 1)
-+#define VIC_FEATURES_DIAG_LEVEL_NS(x) (((x) >> 7) & 1)
-+#define VIC_FEATURES_DIAG_LEVEL_CLP800(x) (((x) >> 4) & 7)
-+#define VIC_FEATURES_DIAG_LEVEL_ST_HLT(x) (((x) >> 1) & 7)
-+#define VIC_FEATURES_SECURE_RST_STATE(x) ((x) & 1)
-+
-+/* IA_CMD */
-+#define VIC_IA_CMD_GO (1UL << 31)
-+#define VIC_IA_CMD_WR (1)
-+
-+#define _VIC_SMODE_MAX_REJECTS_MASK 255UL
-+#define _VIC_SMODE_SECURE_EN_MASK 1UL
-+#define _VIC_SMODE_NONCE_MASK 1UL
-+#define _VIC_MODE_SEC_ALG_MASK 1UL
-+#define _VIC_MODE_ADDIN_PRESENT_MASK 1UL
-+#define _VIC_MODE_PRED_RESIST_MASK 1UL
-+
-+#define VIC_SMODE_SET_MAX_REJECTS(y, x) (((y) & ~(_VIC_SMODE_MAX_REJECTS_MASK << _VIC_SMODE_MAX_REJECTS)) | ((x) << _VIC_SMODE_MAX_REJECTS))
-+#define VIC_SMODE_SET_SECURE_EN(y, x) (((y) & ~(_VIC_SMODE_SECURE_EN_MASK << _VIC_SMODE_SECURE_EN)) | ((x) << _VIC_SMODE_SECURE_EN))
-+#define VIC_SMODE_SET_NONCE(y, x) (((y) & ~(_VIC_SMODE_NONCE_MASK << _VIC_SMODE_NONCE)) | ((x) << _VIC_SMODE_NONCE))
-+#define VIC_SMODE_GET_MAX_REJECTS(x) (((x) >> _VIC_SMODE_MAX_REJECTS) & _VIC_SMODE_MAX_REJECTS_MASK)
-+#define VIC_SMODE_GET_SECURE_EN(x) (((x) >> _VIC_SMODE_SECURE_EN) & _VIC_SMODE_SECURE_EN_MASK)
-+#define VIC_SMODE_GET_NONCE(x) (((x) >> _VIC_SMODE_NONCE) & _VIC_SMODE_NONCE_MASK)
-+
-+#define VIC_MODE_SET_SEC_ALG(y, x) (((y) & ~(_VIC_MODE_SEC_ALG_MASK << _VIC_MODE_SEC_ALG)) | ((x) << _VIC_MODE_SEC_ALG))
-+#define VIC_MODE_SET_PRED_RESIST(y, x) (((y) & ~(_VIC_MODE_PRED_RESIST_MASK << _VIC_MODE_PRED_RESIST)) | ((x) << _VIC_MODE_PRED_RESIST))
-+#define VIC_MODE_SET_ADDIN_PRESENT(y, x) (((y) & ~(_VIC_MODE_ADDIN_PRESENT_MASK << _VIC_MODE_ADDIN_PRESENT)) | ((x) << _VIC_MODE_ADDIN_PRESENT))
-+#define VIC_MODE_GET_SEC_ALG(x) (((x) >> _VIC_MODE_SEC_ALG) & _VIC_MODE_SEC_ALG_MASK)
-+#define VIC_MODE_GET_PRED_RESIST(x) (((x) >> _VIC_MODE_PRED_RESIST) & _VIC_MODE_PRED_RESIST_MASK)
-+#define VIC_MODE_GET_ADDIN_PRESENT(x) (((x) >> _VIC_MODE_ADDIN_PRESENT) & _VIC_MODE_ADDIN_PRESENT_MASK)
-+
-+#define VIC_RAND_LEN 4
diff --git a/target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch b/target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
deleted file mode 100644
index 7f47f31fc2..0000000000
--- a/target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
+++ /dev/null
@@ -1,309 +0,0 @@
-From 8b3a02992094b5995d5a3e0d6d575aa852961c61 Mon Sep 17 00:00:00 2001
-From: Chenjieqin <Jessica.Chen@starfivetech.com>
-Date: Fri, 8 Jan 2021 03:56:54 +0800
-Subject: [PATCH 1015/1024] pwm: sifive-ptc: Add SiFive PWM PTC driver
-
-yiming.li: clear CNTR of PWM after setting period & duty_cycle
-Emil: cleanups, clock, reset and div_u64
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/pwm/Kconfig | 11 ++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-sifive-ptc.c | 260 +++++++++++++++++++++++++++++++++++
- 3 files changed, 272 insertions(+)
- create mode 100644 drivers/pwm/pwm-sifive-ptc.c
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -504,6 +504,17 @@ config PWM_SIFIVE
- To compile this driver as a module, choose M here: the module
- will be called pwm-sifive.
-
-+config PWM_SIFIVE_PTC
-+ tristate "SiFive PWM PTC support"
-+ depends on SOC_SIFIVE || SOC_STARFIVE || COMPILE_TEST
-+ depends on OF
-+ depends on COMMON_CLK
-+ help
-+ Generic PWM framework driver for SiFive SoCs.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-sifive-ptc.
-+
- config PWM_SL28CPLD
- tristate "Kontron sl28cpld PWM support"
- depends on MFD_SL28CPLD || COMPILE_TEST
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -46,6 +46,7 @@ obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-ren
- obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
- obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
- obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
-+obj-$(CONFIG_PWM_SIFIVE_PTC) += pwm-sifive-ptc.o
- obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
- obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
- obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
---- /dev/null
-+++ b/drivers/pwm/pwm-sifive-ptc.c
-@@ -0,0 +1,260 @@
-+/*
-+ * Copyright (C) 2018 SiFive, Inc
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2, as published by
-+ * the Free Software Foundation.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/math64.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/reset.h>
-+
-+#include <dt-bindings/pwm/pwm.h>
-+
-+/* max channel of pwm */
-+#define MAX_PWM 8
-+
-+/* PTC Register offsets */
-+#define REG_RPTC_CNTR 0x0
-+#define REG_RPTC_HRC 0x4
-+#define REG_RPTC_LRC 0x8
-+#define REG_RPTC_CTRL 0xC
-+
-+/* Bit for PWM clock */
-+#define BIT_PWM_CLOCK_EN 31
-+
-+/* Bit for clock gen soft reset */
-+#define BIT_CLK_GEN_SOFT_RESET 13
-+
-+#define NS_1 1000000000U
-+
-+/* Access PTC register (cntr hrc lrc and ctrl), need to replace PWM_BASE_ADDR */
-+#define REG_PTC_BASE_ADDR_SUB(base, N) \
-+ ((base) + (((N) > 3) ? (((N) - 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
-+#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
-+#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
-+#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
-+#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
-+
-+/* pwm ptc device */
-+struct sifive_pwm_ptc_device {
-+ struct pwm_chip chip;
-+ struct clk *clk;
-+ void __iomem *regs;
-+};
-+
-+static inline struct sifive_pwm_ptc_device *chip_to_sifive_ptc(struct pwm_chip *c)
-+{
-+ return container_of(c, struct sifive_pwm_ptc_device, chip);
-+}
-+
-+static int sifive_pwm_ptc_get_state(struct pwm_chip *chip, struct pwm_device *dev,
-+ struct pwm_state *state)
-+{
-+ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
-+ u32 data_lrc;
-+ u32 data_hrc;
-+ u32 pwm_clk_ns = 0;
-+
-+ /* get lrc and hrc data from registe */
-+ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
-+ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
-+
-+ /* how many ns does apb clock elapse */
-+ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
-+
-+ /* pwm period(ns) */
-+ state->period = data_lrc * pwm_clk_ns;
-+
-+ /* duty cycle(ns) means high level eclapse ns if it is normal polarity */
-+ state->duty_cycle = data_hrc * pwm_clk_ns;
-+
-+ /* polarity, we don't use it now because it is not in dts */
-+ state->polarity = PWM_POLARITY_NORMAL;
-+
-+ /* enabled or not */
-+ state->enabled = 1;
-+
-+ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "data_hrc:0x%x 0x%x\n", data_hrc, data_lrc);
-+ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
-+ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
-+ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
-+ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
-+
-+ return 0;
-+}
-+
-+static int sifive_pwm_ptc_apply(struct pwm_chip *chip, struct pwm_device *dev,
-+ const struct pwm_state *state)
-+{
-+ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
-+ void __iomem *reg_addr;
-+ u32 pwm_clk_ns = 0;
-+ u32 data_hrc = 0;
-+ u32 data_lrc = 0;
-+ u32 period_data = 0;
-+ u32 duty_data = 0;
-+
-+ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
-+ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
-+ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
-+ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
-+
-+ /* duty_cycle should be less or equal than period */
-+ if (state->duty_cycle > state->period)
-+ return -EINVAL;
-+
-+ /* calculate pwm real period (ns) */
-+ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
-+
-+ dev_dbg(pwm->chip.dev, "pwm_clk_ns:%u\n", pwm_clk_ns);
-+
-+ /* calculate period count */
-+ period_data = div_u64(state->period, pwm_clk_ns);
-+
-+ if (!state->enabled)
-+ /* if disabled, just set duty_data to 0, which means low level always */
-+ duty_data = 0;
-+ else
-+ /* calculate duty count */
-+ duty_data = div_u64(state->duty_cycle, pwm_clk_ns);
-+
-+ dev_dbg(pwm->chip.dev, "period_data:%u, duty_data:%u\n",
-+ period_data, duty_data);
-+
-+ if (state->polarity == PWM_POLARITY_NORMAL)
-+ /* calculate data_hrc */
-+ data_hrc = period_data - duty_data;
-+ else
-+ /* calculate data_hrc */
-+ data_hrc = duty_data;
-+
-+ data_lrc = period_data;
-+
-+ /* set hrc */
-+ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
-+ __func__, reg_addr, data_hrc);
-+
-+ iowrite32(data_hrc, reg_addr);
-+
-+ dev_dbg(pwm->chip.dev, "%s: hrc ok\n", __func__);
-+
-+ /* set lrc */
-+ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
-+ __func__, reg_addr, data_lrc);
-+
-+ iowrite32(data_lrc, reg_addr);
-+ dev_dbg(pwm->chip.dev, "%s: lrc ok\n", __func__);
-+
-+ /* Clear REG_RPTC_CNTR after setting period & duty_cycle */
-+ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
-+ iowrite32(0, reg_addr);
-+ return 0;
-+}
-+
-+static const struct pwm_ops sifive_pwm_ptc_ops = {
-+ .get_state = sifive_pwm_ptc_get_state,
-+ .apply = sifive_pwm_ptc_apply,
-+ .owner = THIS_MODULE,
-+};
-+
-+static void sifive_pwm_ptc_disable_action(void *data)
-+{
-+ clk_disable_unprepare(data);
-+}
-+
-+static int sifive_pwm_ptc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *node = pdev->dev.of_node;
-+ struct sifive_pwm_ptc_device *pwm;
-+ struct pwm_chip *chip;
-+ struct reset_control *rst;
-+ int ret;
-+
-+ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
-+ if (!pwm)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, pwm);
-+
-+ chip = &pwm->chip;
-+ chip->dev = dev;
-+ chip->ops = &sifive_pwm_ptc_ops;
-+
-+ /* how many parameters can be transferred to ptc, need to fix */
-+ chip->of_pwm_n_cells = 3;
-+ chip->base = -1;
-+
-+ /* get pwm channels count, max value is 8 */
-+ ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
-+ if (ret < 0 || chip->npwm > MAX_PWM)
-+ chip->npwm = MAX_PWM;
-+
-+ dev_dbg(dev, "%s: npwm:0x%x\n", __func__, chip->npwm);
-+
-+ /* get IO base address */
-+ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(pwm->regs))
-+ return dev_err_probe(dev, PTR_ERR(pwm->regs),
-+ "Unable to map IO resources\n");
-+
-+ pwm->clk = devm_clk_get(dev, NULL);
-+ if (IS_ERR(pwm->clk))
-+ return dev_err_probe(dev, PTR_ERR(pwm->clk),
-+ "Unable to get controller clock\n");
-+
-+ ret = clk_prepare_enable(pwm->clk);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Unable to enable clock\n");
-+
-+ ret = devm_add_action_or_reset(dev, sifive_pwm_ptc_disable_action, pwm->clk);
-+ if (ret)
-+ return ret;
-+
-+ rst = devm_reset_control_get_exclusive(dev, NULL);
-+ if (IS_ERR(rst))
-+ return dev_err_probe(dev, PTR_ERR(rst), "Unable to get reset\n");
-+
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Unable to deassert reset\n");
-+
-+ /*
-+ * after pwmchip_add it will show up as /sys/class/pwm/pwmchip0,
-+ * 0 is chip->base, pwm0 can be seen after running echo 0 > export
-+ */
-+ ret = devm_pwmchip_add(dev, chip);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "cannot register PTC: %d\n", ret);
-+
-+ dev_dbg(dev, "SiFive PWM PTC chip registered %d PWMs\n", chip->npwm);
-+ return 0;
-+}
-+
-+static const struct of_device_id sifive_pwm_ptc_of_match[] = {
-+ { .compatible = "starfive,pwm0" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, sifive_pwm_ptc_of_match);
-+
-+static struct platform_driver sifive_pwm_ptc_driver = {
-+ .probe = sifive_pwm_ptc_probe,
-+ .driver = {
-+ .name = "pwm-sifive-ptc",
-+ .of_match_table = sifive_pwm_ptc_of_match,
-+ },
-+};
-+module_platform_driver(sifive_pwm_ptc_driver);
-+
-+MODULE_DESCRIPTION("SiFive PWM PTC driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch b/target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch
deleted file mode 100644
index d8a2befe64..0000000000
--- a/target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From d30b864417ea3ad1bc4fcf675ea072cb19011930 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 12 Jun 2021 16:48:31 -0700
-Subject: [PATCH 1016/1024] riscv: Implement non-coherent DMA support via
- SiFive cache flushing
-
-This variant is used on the StarFive JH7100 SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/Kconfig | 6 ++++--
- arch/riscv/mm/dma-noncoherent.c | 37 +++++++++++++++++++++++++++++++--
- 2 files changed, 39 insertions(+), 4 deletions(-)
-
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -225,12 +225,14 @@ config LOCKDEP_SUPPORT
- def_bool y
-
- config RISCV_DMA_NONCOHERENT
-- bool
-+ bool "Support non-coherent DMA"
-+ default SOC_STARFIVE
- select ARCH_HAS_DMA_PREP_COHERENT
-+ select ARCH_HAS_DMA_SET_UNCACHED
-+ select ARCH_HAS_DMA_CLEAR_UNCACHED
- select ARCH_HAS_SYNC_DMA_FOR_DEVICE
- select ARCH_HAS_SYNC_DMA_FOR_CPU
- select ARCH_HAS_SETUP_DMA_OPS
-- select DMA_DIRECT_REMAP
-
- config AS_HAS_INSN
- def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
---- a/arch/riscv/mm/dma-noncoherent.c
-+++ b/arch/riscv/mm/dma-noncoherent.c
-@@ -9,14 +9,21 @@
- #include <linux/dma-map-ops.h>
- #include <linux/mm.h>
- #include <asm/cacheflush.h>
-+#include <soc/sifive/sifive_ccache.h>
-
- static bool noncoherent_supported;
-
- void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
- {
-- void *vaddr = phys_to_virt(paddr);
-+ void *vaddr;
-
-+ if (sifive_ccache_handle_noncoherent()) {
-+ sifive_ccache_flush_range(paddr, size);
-+ return;
-+ }
-+
-+ vaddr = phys_to_virt(paddr);
- switch (dir) {
- case DMA_TO_DEVICE:
- ALT_CMO_OP(clean, vaddr, size, riscv_cbom_block_size);
-@@ -35,8 +42,14 @@ void arch_sync_dma_for_device(phys_addr_
- void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
- {
-- void *vaddr = phys_to_virt(paddr);
-+ void *vaddr;
-+
-+ if (sifive_ccache_handle_noncoherent()) {
-+ sifive_ccache_flush_range(paddr, size);
-+ return;
-+ }
-
-+ vaddr = phys_to_virt(paddr);
- switch (dir) {
- case DMA_TO_DEVICE:
- break;
-@@ -49,10 +62,30 @@ void arch_sync_dma_for_cpu(phys_addr_t p
- }
- }
-
-+void *arch_dma_set_uncached(void *addr, size_t size)
-+{
-+ if (sifive_ccache_handle_noncoherent())
-+ return sifive_ccache_set_uncached(addr, size);
-+
-+ return addr;
-+}
-+
-+void arch_dma_clear_uncached(void *addr, size_t size)
-+{
-+ if (sifive_ccache_handle_noncoherent())
-+ sifive_ccache_clear_uncached(addr, size);
-+}
-+
- void arch_dma_prep_coherent(struct page *page, size_t size)
- {
- void *flush_addr = page_address(page);
-
-+ if (sifive_ccache_handle_noncoherent()) {
-+ memset(flush_addr, 0, size);
-+ sifive_ccache_flush_range(__pa(flush_addr), size);
-+ return;
-+ }
-+
- ALT_CMO_OP(flush, flush_addr, size, riscv_cbom_block_size);
- }
-
diff --git a/target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch b/target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch
deleted file mode 100644
index 7de04411ed..0000000000
--- a/target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 3b83b32e16fa431c76a5da1ac59c268ca2fecbb5 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sat, 11 Feb 2023 05:18:11 +0200
-Subject: [PATCH 1017/1024] dt-bindings: riscv: sifive-ccache: Add
- 'uncached-offset' property
-
-Add the 'uncached-offset' property to be used for specifying the
-uncached memory offset required for handling non-coherent DMA
-transactions.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Link: https://lore.kernel.org/r/20230211031821.976408-3-cristian.ciocaltea@collabora.com
----
- Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml
-+++ b/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml
-@@ -70,6 +70,11 @@ properties:
-
- next-level-cache: true
-
-+ uncached-offset:
-+ $ref: /schemas/types.yaml#/definitions/uint64
-+ description: |
-+ Uncached memory offset for handling non-coherent DMA transactions.
-+
- memory-region:
- maxItems: 1
- description: |
diff --git a/target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch b/target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch
deleted file mode 100644
index 04d1e5aa1e..0000000000
--- a/target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From cde57aebfd86b3b062ce0bcf71395d735d05b2f6 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 6 Apr 2022 00:38:05 +0200
-Subject: [PATCH 1018/1024] soc: sifive: ccache: Add StarFive JH71x0 support
-
-This adds support for the StarFive JH7100 and JH7110 SoCs which also
-feature this SiFive cache controller.
-
-Unfortunately the interrupt for uncorrected data is broken on the JH7100
-and fires continuously, so add a quirk to not register a handler for it.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/Kconfig.socs | 1 +
- drivers/soc/sifive/Kconfig | 2 +-
- drivers/soc/sifive/sifive_ccache.c | 12 +++++++++++-
- 3 files changed, 13 insertions(+), 2 deletions(-)
-
---- a/arch/riscv/Kconfig.socs
-+++ b/arch/riscv/Kconfig.socs
-@@ -28,6 +28,7 @@ config SOC_STARFIVE
- bool "StarFive SoCs"
- select PINCTRL
- select RESET_CONTROLLER
-+ select SIFIVE_CCACHE
- select SIFIVE_PLIC
- select ARM_AMBA
- help
---- a/drivers/soc/sifive/Kconfig
-+++ b/drivers/soc/sifive/Kconfig
-@@ -1,6 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0
-
--if SOC_SIFIVE
-+if SOC_SIFIVE || SOC_STARFIVE
-
- config SIFIVE_CCACHE
- bool "Sifive Composable Cache controller"
---- a/drivers/soc/sifive/sifive_ccache.c
-+++ b/drivers/soc/sifive/sifive_ccache.c
-@@ -106,6 +106,8 @@ static void ccache_config_read(void)
- static const struct of_device_id sifive_ccache_ids[] = {
- { .compatible = "sifive,fu540-c000-ccache" },
- { .compatible = "sifive,fu740-c000-ccache" },
-+ { .compatible = "starfive,jh7100-ccache", .data = (void *)BIT(DATA_UNCORR) },
-+ { .compatible = "starfive,jh7110-ccache" },
- { .compatible = "sifive,ccache0" },
- { /* end of table */ }
- };
-@@ -210,11 +212,15 @@ static int __init sifive_ccache_init(voi
- struct device_node *np;
- struct resource res;
- int i, rc, intr_num;
-+ const struct of_device_id *match;
-+ unsigned long broken_irqs;
-
-- np = of_find_matching_node(NULL, sifive_ccache_ids);
-+ np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
- if (!np)
- return -ENODEV;
-
-+ broken_irqs = (uintptr_t)match->data;
-+
- if (of_address_to_resource(np, 0, &res)) {
- rc = -ENODEV;
- goto err_node_put;
-@@ -240,6 +246,10 @@ static int __init sifive_ccache_init(voi
-
- for (i = 0; i < intr_num; i++) {
- g_irq[i] = irq_of_parse_and_map(np, i);
-+
-+ if (broken_irqs & BIT(i))
-+ continue;
-+
- rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
- NULL);
- if (rc) {
diff --git a/target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch b/target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch
deleted file mode 100644
index 0713739b5f..0000000000
--- a/target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch
+++ /dev/null
@@ -1,159 +0,0 @@
-From 335c32d2653f2415e042c8ad1ae2a6b33019b96f Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 12 Jun 2021 16:48:31 -0700
-Subject: [PATCH 1019/1024] soc: sifive: ccache: Add non-coherent DMA handling
-
-Add functions to flush the caches and handle non-coherent DMA.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/soc/sifive/sifive_ccache.c | 60 +++++++++++++++++++++++++++++-
- include/soc/sifive/sifive_ccache.h | 21 +++++++++++
- 2 files changed, 80 insertions(+), 1 deletion(-)
-
---- a/drivers/soc/sifive/sifive_ccache.c
-+++ b/drivers/soc/sifive/sifive_ccache.c
-@@ -8,13 +8,16 @@
-
- #define pr_fmt(fmt) "CCACHE: " fmt
-
-+#include <linux/align.h>
- #include <linux/debugfs.h>
- #include <linux/interrupt.h>
- #include <linux/of_irq.h>
- #include <linux/of_address.h>
- #include <linux/device.h>
- #include <linux/bitfield.h>
-+#include <asm/cacheflush.h>
- #include <asm/cacheinfo.h>
-+#include <asm/page.h>
- #include <soc/sifive/sifive_ccache.h>
-
- #define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100
-@@ -39,10 +42,14 @@
- #define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16)
- #define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24)
-
-+#define SIFIVE_CCACHE_FLUSH64 0x200
-+#define SIFIVE_CCACHE_FLUSH32 0x240
-+
- #define SIFIVE_CCACHE_WAYENABLE 0x08
- #define SIFIVE_CCACHE_ECCINJECTERR 0x40
-
- #define SIFIVE_CCACHE_MAX_ECCINTR 4
-+#define SIFIVE_CCACHE_LINE_SIZE 64
-
- static void __iomem *ccache_base;
- static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
-@@ -126,6 +133,47 @@ int unregister_sifive_ccache_error_notif
- }
- EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
-
-+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
-+static phys_addr_t uncached_offset;
-+DEFINE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
-+
-+void sifive_ccache_flush_range(phys_addr_t start, size_t len)
-+{
-+ phys_addr_t end = start + len;
-+ phys_addr_t line;
-+
-+ if (!len)
-+ return;
-+
-+ mb();
-+ for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end;
-+ line += SIFIVE_CCACHE_LINE_SIZE) {
-+#ifdef CONFIG_32BIT
-+ writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
-+#else
-+ writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
-+#endif
-+ mb();
-+ }
-+}
-+EXPORT_SYMBOL_GPL(sifive_ccache_flush_range);
-+
-+void *sifive_ccache_set_uncached(void *addr, size_t size)
-+{
-+ phys_addr_t phys_addr = __pa(addr) + uncached_offset;
-+ void *mem_base;
-+
-+ mem_base = memremap(phys_addr, size, MEMREMAP_WT);
-+ if (!mem_base) {
-+ pr_err("%s memremap failed for addr %p\n", __func__, addr);
-+ return ERR_PTR(-EINVAL);
-+ }
-+
-+ return mem_base;
-+}
-+EXPORT_SYMBOL_GPL(sifive_ccache_set_uncached);
-+#endif /* CONFIG_RISCV_DMA_NONCOHERENT */
-+
- static int ccache_largest_wayenabled(void)
- {
- return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
-@@ -214,6 +262,7 @@ static int __init sifive_ccache_init(voi
- int i, rc, intr_num;
- const struct of_device_id *match;
- unsigned long broken_irqs;
-+ u64 __maybe_unused offset;
-
- np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
- if (!np)
-@@ -259,6 +308,15 @@ static int __init sifive_ccache_init(voi
- }
- of_node_put(np);
-
-+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
-+ if (!of_property_read_u64(np, "uncached-offset", &offset)) {
-+ uncached_offset = offset;
-+ static_branch_enable(&sifive_ccache_handle_noncoherent_key);
-+ riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
-+ riscv_noncoherent_supported();
-+ }
-+#endif
-+
- ccache_config_read();
-
- ccache_cache_ops.get_priv_group = ccache_get_priv_group;
-@@ -279,4 +337,4 @@ err_node_put:
- return rc;
- }
-
--device_initcall(sifive_ccache_init);
-+arch_initcall(sifive_ccache_init);
---- a/include/soc/sifive/sifive_ccache.h
-+++ b/include/soc/sifive/sifive_ccache.h
-@@ -7,10 +7,31 @@
- #ifndef __SOC_SIFIVE_CCACHE_H
- #define __SOC_SIFIVE_CCACHE_H
-
-+#include <linux/io.h>
-+#include <linux/jump_label.h>
-+
- extern int register_sifive_ccache_error_notifier(struct notifier_block *nb);
- extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb);
-
- #define SIFIVE_CCACHE_ERR_TYPE_CE 0
- #define SIFIVE_CCACHE_ERR_TYPE_UE 1
-
-+DECLARE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
-+
-+static inline bool sifive_ccache_handle_noncoherent(void)
-+{
-+#ifdef CONFIG_SIFIVE_CCACHE
-+ return static_branch_unlikely(&sifive_ccache_handle_noncoherent_key);
-+#else
-+ return false;
-+#endif
-+}
-+
-+void sifive_ccache_flush_range(phys_addr_t start, size_t len);
-+void *sifive_ccache_set_uncached(void *addr, size_t size);
-+static inline void sifive_ccache_clear_uncached(void *addr, size_t size)
-+{
-+ memunmap(addr);
-+}
-+
- #endif /* __SOC_SIFIVE_CCACHE_H */
diff --git a/target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch b/target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
deleted file mode 100644
index 7641c559d5..0000000000
--- a/target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f684a12dac29522c6ce9d504522f75dcf024fc5f Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 19:29:25 +0100
-Subject: [PATCH 1020/1024] dt-bindings: reset: Add StarFive JH7100 audio reset
- definitions
-
-Add all resets for the StarFive JH7100 audio reset controller.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../dt-bindings/reset/starfive-jh7100-audio.h | 31 +++++++++++++++++++
- 1 file changed, 31 insertions(+)
- create mode 100644 include/dt-bindings/reset/starfive-jh7100-audio.h
-
---- /dev/null
-+++ b/include/dt-bindings/reset/starfive-jh7100-audio.h
-@@ -0,0 +1,31 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing
-+ */
-+
-+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
-+#define __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
-+
-+#define JH7100_AUDRSTN_APB_BUS 0
-+#define JH7100_AUDRSTN_I2SADC_APB 1
-+#define JH7100_AUDRSTN_I2SADC_SRST 2
-+#define JH7100_AUDRSTN_PDM_APB 3
-+#define JH7100_AUDRSTN_I2SVAD_APB 4
-+#define JH7100_AUDRSTN_I2SVAD_SRST 5
-+#define JH7100_AUDRSTN_SPDIF_APB 6
-+#define JH7100_AUDRSTN_PWMDAC_APB 7
-+#define JH7100_AUDRSTN_I2SDAC_APB 8
-+#define JH7100_AUDRSTN_I2SDAC_SRST 9
-+#define JH7100_AUDRSTN_I2S1_APB 10
-+#define JH7100_AUDRSTN_I2S1_SRST 11
-+#define JH7100_AUDRSTN_I2SDAC16K_APB 12
-+#define JH7100_AUDRSTN_I2SDAC16K_SRST 13
-+#define JH7100_AUDRSTN_DMA1P_AHB 14
-+#define JH7100_AUDRSTN_USB_APB 15
-+#define JH7100_AUDRST_USB_AXI 16
-+#define JH7100_AUDRST_USB_PWRUP_RST_N 17
-+#define JH7100_AUDRST_USB_PONRST 18
-+
-+#define JH7100_AUDRSTN_END 19
-+
-+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__ */
diff --git a/target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch b/target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
deleted file mode 100644
index 413833707a..0000000000
--- a/target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 9220294c675a111651ff12b2389a81f0935553fd Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Tue, 7 Dec 2021 21:48:51 +0100
-Subject: [PATCH 1021/1024] dt-bindings: reset: Add starfive,jh7100-audrst
- bindings
-
-Add bindings for the audio reset controller on the StarFive JH7100
-RISC-V SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../reset/starfive,jh7100-audrst.yaml | 38 +++++++++++++++++++
- 1 file changed, 38 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
-@@ -0,0 +1,38 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/reset/starfive,jh7100-audrst.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7100 SoC Audio Reset Controller Device Tree Bindings
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7100-audrst
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#reset-cells":
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - "#reset-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ reset-controller@10490000 {
-+ compatible = "starfive,jh7100-audrst";
-+ reg = <0x10490000 0x10000>;
-+ #reset-cells = <1>;
-+ };
-+
-+...
diff --git a/target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch b/target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch
deleted file mode 100644
index bf3eff0157..0000000000
--- a/target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From ff806bda9b04bcf73350e319f3efde5cd049b77a Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 19:30:49 +0100
-Subject: [PATCH 1022/1024] reset: starfive: Add JH7100 audio reset driver
-
-The audio resets are almost identical to the system resets, there are
-just fewer of them. So factor out and export a generic probe function,
-so most of the reset controller implementation can be shared.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- MAINTAINERS | 2 +-
- drivers/reset/starfive/Kconfig | 7 ++
- drivers/reset/starfive/Makefile | 2 +
- .../starfive/reset-starfive-jh7100-audio.c | 66 +++++++++++++++++++
- .../reset/starfive/reset-starfive-jh7100.h | 16 +++++
- 5 files changed, 92 insertions(+), 1 deletion(-)
- create mode 100644 drivers/reset/starfive/reset-starfive-jh7100-audio.c
- create mode 100644 drivers/reset/starfive/reset-starfive-jh7100.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19711,7 +19711,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
- M: Hal Feng <hal.feng@starfivetech.com>
- S: Maintained
--F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
-+F: Documentation/devicetree/bindings/reset/starfive,jh7100-*.yaml
- F: drivers/reset/starfive/reset-starfive-jh71*
- F: include/dt-bindings/reset/starfive?jh71*.h
-
---- a/drivers/reset/starfive/Kconfig
-+++ b/drivers/reset/starfive/Kconfig
-@@ -11,6 +11,13 @@ config RESET_STARFIVE_JH7100
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
-
-+config RESET_STARFIVE_JH7100_AUDIO
-+ tristate "StarFive JH7100 Audio Reset Driver"
-+ depends on RESET_STARFIVE_JH7100
-+ default m if SOC_STARFIVE
-+ help
-+ This enables the audio reset driver for the StarFive JH7100 SoC.
-+
- config RESET_STARFIVE_JH7110
- bool "StarFive JH7110 Reset Driver"
- depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
---- a/drivers/reset/starfive/Makefile
-+++ b/drivers/reset/starfive/Makefile
-@@ -2,4 +2,6 @@
- obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
-
- obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
-+obj-$(CONFIG_RESET_STARFIVE_JH7100_AUDIO) += reset-starfive-jh7100-audio.o
-+
- obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7100-audio.c
-@@ -0,0 +1,66 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Audio reset driver for the StarFive JH7100 SoC
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+
-+#include "reset-starfive-jh71x0.h"
-+
-+#include <dt-bindings/reset/starfive-jh7100-audio.h>
-+
-+/* register offsets */
-+#define JH7100_AUDRST_ASSERT0 0x00
-+#define JH7100_AUDRST_STATUS0 0x04
-+
-+/*
-+ * Writing a 1 to the n'th bit of the ASSERT register asserts
-+ * line n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u32 jh7100_audrst_asserted[1] = {
-+ BIT(JH7100_AUDRST_USB_AXI) |
-+ BIT(JH7100_AUDRST_USB_PWRUP_RST_N) |
-+ BIT(JH7100_AUDRST_USB_PONRST)
-+};
-+
-+static int jh7100_audrst_probe(struct platform_device *pdev)
-+{
-+ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
-+
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
-+ base + JH7100_AUDRST_ASSERT0,
-+ base + JH7100_AUDRST_STATUS0,
-+ jh7100_audrst_asserted,
-+ JH7100_AUDRSTN_END,
-+ THIS_MODULE);
-+}
-+
-+static const struct of_device_id jh7100_audrst_dt_ids[] = {
-+ { .compatible = "starfive,jh7100-audrst" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7100_audrst_dt_ids);
-+
-+static struct platform_driver jh7100_audrst_driver = {
-+ .probe = jh7100_audrst_probe,
-+ .driver = {
-+ .name = "jh7100-reset-audio",
-+ .of_match_table = jh7100_audrst_dt_ids,
-+ },
-+};
-+module_platform_driver(jh7100_audrst_driver);
-+
-+MODULE_AUTHOR("Emil Renner Berthing");
-+MODULE_DESCRIPTION("StarFive JH7100 audio reset driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.h
-@@ -0,0 +1,16 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef _RESET_STARFIVE_JH7100_H_
-+#define _RESET_STARFIVE_JH7100_H_
-+
-+#include <linux/platform_device.h>
-+
-+int reset_starfive_jh7100_generic_probe(struct platform_device *pdev,
-+ const u32 *asserted,
-+ unsigned int status_offset,
-+ unsigned int nr_resets);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch b/target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
deleted file mode 100644
index 0ef6fa485e..0000000000
--- a/target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From f7ab709727e845ffdfc428ec2f236d0c1997b153 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 21:33:08 +0100
-Subject: [PATCH 1023/1024] RISC-V: Add StarFive JH7100 audio reset node
-
-Add device tree node for the audio resets on the StarFive JH7100 RISC-V
-SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -144,6 +144,12 @@
- #clock-cells = <1>;
- };
-
-+ audrst: reset-controller@10490000 {
-+ compatible = "starfive,jh7100-audrst";
-+ reg = <0x0 0x10490000 0x0 0x10000>;
-+ #reset-cells = <1>;
-+ };
-+
- clkgen: clock-controller@11800000 {
- compatible = "starfive,jh7100-clkgen";
- reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch b/target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
deleted file mode 100644
index 92176679de..0000000000
--- a/target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
+++ /dev/null
@@ -1,1265 +0,0 @@
-From 9912cdc9038c40fbcb1f121445519efb55dec046 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sun, 31 Oct 2021 17:15:58 +0100
-Subject: [PATCH 1024/1024] riscv: dts: Add full JH7100, Starlight and
- VisionFive support
-
-Based on the device tree in https://github.com/starfive-tech/u-boot/
-with contributions from:
-yanhong.wang <yanhong.wang@starfivetech.com>
-Huan.Feng <huan.feng@starfivetech.com>
-ke.zhu <ke.zhu@starfivetech.com>
-yiming.li <yiming.li@starfivetech.com>
-jack.zhu <jack.zhu@starfivetech.com>
-Samin Guo <samin.guo@starfivetech.com>
-Chenjieqin <Jessica.Chen@starfivetech.com>
-bo.li <bo.li@starfivetech.com>
-
-Rearranged, cleanups, fixes, pins and resets added by Emil.
-Cleanups, fixes, clocks added by Geert.
-Cleanups and GPIO fixes from Drew.
-Thermal zone added by Stephen.
-PWM pins added by Jianlong.
-cpu-map added by Jonas.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-Signed-off-by: Stephen L Arnold <nerdboy@gentoo.org>
-Signed-off-by: Drew Fustini <drew@beagleboard.org>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Jonas Hahnfeld <hahnjo@hahnjo.de>
----
- arch/riscv/boot/dts/starfive/Makefile | 1 +
- .../starfive/jh7100-beaglev-starlight-a1.dts | 30 +
- .../dts/starfive/jh7100-beaglev-starlight.dts | 16 +
- .../boot/dts/starfive/jh7100-common.dtsi | 434 ++++++++++++++
- .../jh7100-starfive-visionfive-v1.dts | 19 +
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 561 ++++++++++++++++++
- 6 files changed, 1061 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
-
---- a/arch/riscv/boot/dts/starfive/Makefile
-+++ b/arch/riscv/boot/dts/starfive/Makefile
-@@ -1,4 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight-a1.dtb
- dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
- dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
-
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
-@@ -0,0 +1,30 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7100-common.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/ {
-+ model = "BeagleV Starlight Beta A1";
-+ compatible = "beagle,beaglev-starlight-jh7100-a1", "starfive,jh7100";
-+
-+ gpio-restart {
-+ compatible = "gpio-restart";
-+ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
-+ priority = <224>;
-+ };
-+};
-+
-+&gpio {
-+ /* don't reset gpio mux for serial console and reset gpio */
-+ starfive,keep-gpiomux = <13 14 63>;
-+};
-+
-+&mdio {
-+ phy: ethernet-phy@7 {
-+ reg = <7>;
-+ };
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-@@ -6,8 +6,24 @@
-
- /dts-v1/;
- #include "jh7100-common.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-
- / {
- model = "BeagleV Starlight Beta";
- compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
- };
-+
-+&gmac {
-+ snps,reset-gpios = <&gpio 63 GPIO_ACTIVE_LOW>;
-+};
-+
-+&gpio {
-+ /* don't reset gpio mux for serial console on uart3 */
-+ starfive,keep-gpiomux = <13 14>;
-+};
-+
-+&mdio {
-+ phy: ethernet-phy@7 {
-+ reg = <7>;
-+ };
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-@@ -12,7 +12,10 @@
-
- / {
- aliases {
-+ mmc0 = &sdio0;
-+ mmc1 = &sdio1;
- serial0 = &uart3;
-+ serial1 = &uart0;
- };
-
- chosen {
-@@ -39,9 +42,174 @@
- label = "ack";
- };
- };
-+
-+ reserved-memory {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ linux,cma {
-+ compatible = "shared-dma-pool";
-+ reusable;
-+ size = <0x0 0x28000000>;
-+ alignment = <0x0 0x1000>;
-+ alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
-+ linux,cma-default;
-+ };
-+
-+ jpu_reserved: framebuffer@c9000000 {
-+ reg = <0x0 0xc9000000 0x0 0x4000000>;
-+ };
-+
-+ nvdla_reserved: framebuffer@d0000000 {
-+ no-map;
-+ reg = <0x0 0xd0000000 0x0 0x28000000>;
-+ };
-+
-+ vin_reserved: framebuffer@f9000000 {
-+ compatible = "shared-dma-pool";
-+ no-map;
-+ reg = <0x0 0xf9000000 0x0 0x1000000>;
-+ };
-+
-+ sffb_reserved: framebuffer@fb000000 {
-+ compatible = "shared-dma-pool";
-+ no-map;
-+ reg = <0x0 0xfb000000 0x0 0x2000000>;
-+ };
-+ };
-+
-+ wifi_pwrseq: wifi-pwrseq {
-+ compatible = "mmc-pwrseq-simple";
-+ reset-gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&display {
-+ memory-region = <&sffb_reserved>;
-+ status = "okay";
-+};
-+
-+&crtc {
-+ ddr-format = <4>; //<WIN_FMT_RGB565>;
-+ status = "okay";
-+
-+ port: port@0 {
-+ reg = <0>;
-+
-+ crtc_0_out: endpoint {
-+ remote-endpoint = <&hdmi_input0>;
-+ };
-+ };
-+};
-+
-+&encoder {
-+ encoder-type = <2>; // 2-TMDS, 3-LVDS, 6-DSI, 8-DPI
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ hdmi_out: endpoint {
-+ remote-endpoint = <&tda998x_0_input>;
-+ };
-+ };
-+
-+ port@1 {
-+ hdmi_input0: endpoint {
-+ remote-endpoint = <&crtc_0_out>;
-+ };
-+ };
-+
-+ };
-+};
-+
-+&gmac {
-+ starfive,gtxclk-dlychain = <4>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&gmac_pins>;
-+ phy-mode = "rgmii-txid";
-+ phy-handle = <&phy>;
-+ status = "okay";
-+
-+ mdio: mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+ };
- };
-
- &gpio {
-+ gmac_pins: gmac-0 {
-+ gtxclk-pins {
-+ pins = <PAD_FUNC_SHARE(115)>;
-+ bias-pull-up;
-+ drive-strength = <35>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ miitxclk-pins {
-+ pins = <PAD_FUNC_SHARE(116)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ tx-pins {
-+ pins = <PAD_FUNC_SHARE(117)>,
-+ <PAD_FUNC_SHARE(119)>,
-+ <PAD_FUNC_SHARE(120)>,
-+ <PAD_FUNC_SHARE(121)>,
-+ <PAD_FUNC_SHARE(122)>,
-+ <PAD_FUNC_SHARE(123)>,
-+ <PAD_FUNC_SHARE(124)>,
-+ <PAD_FUNC_SHARE(125)>,
-+ <PAD_FUNC_SHARE(126)>;
-+ bias-pull-up;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ rxclk-pins {
-+ pins = <PAD_FUNC_SHARE(127)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <6>;
-+ };
-+ rxer-pins {
-+ pins = <PAD_FUNC_SHARE(129)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ rx-pins {
-+ pins = <PAD_FUNC_SHARE(128)>,
-+ <PAD_FUNC_SHARE(130)>,
-+ <PAD_FUNC_SHARE(131)>,
-+ <PAD_FUNC_SHARE(132)>,
-+ <PAD_FUNC_SHARE(133)>,
-+ <PAD_FUNC_SHARE(134)>,
-+ <PAD_FUNC_SHARE(135)>,
-+ <PAD_FUNC_SHARE(136)>,
-+ <PAD_FUNC_SHARE(137)>,
-+ <PAD_FUNC_SHARE(138)>,
-+ <PAD_FUNC_SHARE(139)>,
-+ <PAD_FUNC_SHARE(140)>,
-+ <PAD_FUNC_SHARE(141)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
- i2c0_pins: i2c0-0 {
- i2c-pins {
- pinmux = <GPIOMUX(62, GPO_LOW,
-@@ -84,6 +252,166 @@
- };
- };
-
-+ pwmdac_pins: pwmdac-0 {
-+ pwmdac-pins {
-+ pinmux = <GPIOMUX(23, GPO_PWMDAC_LEFT_OUT,
-+ GPO_ENABLE, GPI_NONE)>,
-+ <GPIOMUX(24, GPO_PWMDAC_RIGHT_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pwm_pins: pwm-0 {
-+ pwm-pins {
-+ pinmux = <GPIOMUX(7,
-+ GPO_PWM_PAD_OUT_BIT0,
-+ GPO_PWM_PAD_OE_N_BIT0,
-+ GPI_NONE)>,
-+ <GPIOMUX(5,
-+ GPO_PWM_PAD_OUT_BIT1,
-+ GPO_PWM_PAD_OE_N_BIT1,
-+ GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ sdio0_pins: sdio0-0 {
-+ clk-pins {
-+ pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ sdio-pins {
-+ pinmux = <GPIOMUX(55, GPO_LOW, GPO_DISABLE,
-+ GPI_SDIO0_PAD_CARD_DETECT_N)>,
-+ <GPIOMUX(53,
-+ GPO_SDIO0_PAD_CCMD_OUT,
-+ GPO_SDIO0_PAD_CCMD_OEN,
-+ GPI_SDIO0_PAD_CCMD_IN)>,
-+ <GPIOMUX(49,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT0,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT0,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT0)>,
-+ <GPIOMUX(50,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT1,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT1,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT1)>,
-+ <GPIOMUX(51,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT2,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT2,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT2)>,
-+ <GPIOMUX(52,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT3,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT3,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT3)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ sdio1_pins: sdio1-0 {
-+ clk-pins {
-+ pinmux = <GPIOMUX(33, GPO_SDIO1_PAD_CCLK_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ sdio-pins {
-+ pinmux = <GPIOMUX(29,
-+ GPO_SDIO1_PAD_CCMD_OUT,
-+ GPO_SDIO1_PAD_CCMD_OEN,
-+ GPI_SDIO1_PAD_CCMD_IN)>,
-+ <GPIOMUX(36,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT0,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT0,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT0)>,
-+ <GPIOMUX(30,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT1,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT1,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT1)>,
-+ <GPIOMUX(34,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT2,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT2,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT2)>,
-+ <GPIOMUX(31,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT3,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT3,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT3)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ spi2_pins: spi2-0 {
-+ mosi-pins {
-+ pinmux = <GPIOMUX(18, GPO_SPI2_PAD_TXD,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ miso-pins {
-+ pinmux = <GPIOMUX(16, GPO_LOW, GPO_DISABLE,
-+ GPI_SPI2_PAD_RXD)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ sck-pins {
-+ pinmux = <GPIOMUX(12, GPO_SPI2_PAD_SCK_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ ss-pins {
-+ pinmux = <GPIOMUX(15, GPO_SPI2_PAD_SS_0_N,
-+ GPO_ENABLE, GPI_NONE)>,
-+ <GPIOMUX(11, GPO_SPI2_PAD_SS_1_N,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ };
-+
-+ uart0_pins: uart0-0 {
-+ rx-pins {
-+ pinmux = <GPIOMUX(40, GPO_LOW, GPO_DISABLE,
-+ GPI_UART0_PAD_SIN)>,
-+ <GPIOMUX(39, GPO_LOW, GPO_DISABLE,
-+ GPI_UART0_PAD_CTSN)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ tx-pins {
-+ pinmux = <GPIOMUX(41, GPO_UART0_PAD_SOUT,
-+ GPO_ENABLE, GPI_NONE)>,
-+ <GPIOMUX(42, GPO_UART0_PAD_RTSN,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ };
-+
- uart3_pins: uart3-0 {
- rx-pins {
- pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
-@@ -124,6 +452,17 @@
- regulators {
- };
- };
-+
-+ tda998x@70 {
-+ compatible = "nxp,tda998x";
-+ reg = <0x70>;
-+
-+ port {
-+ tda998x_0_input: endpoint {
-+ remote-endpoint = <&hdmi_out>;
-+ };
-+ };
-+ };
- };
-
- &i2c1 {
-@@ -154,8 +493,103 @@
- clock-frequency = <27000000>;
- };
-
-+&ptc {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_pins>;
-+ status = "okay";
-+};
-+
-+&pwmdac {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwmdac_pins>;
-+ status = "okay";
-+};
-+
-+&qspi {
-+ nor_flash: nor-flash@0 {
-+ compatible = "spi-flash";
-+ reg = <0>;
-+ spi-max-frequency = <31250000>;
-+ page-size = <256>;
-+ block-size = <16>;
-+ cdns,read-delay = <4>;
-+ cdns,tshsl-ns = <1>;
-+ cdns,tsd2d-ns = <1>;
-+ cdns,tchsh-ns = <1>;
-+ cdns,tslch-ns = <1>;
-+ spi-tx-bus-width = <1>;
-+ spi-rx-bus-width = <1>;
-+ };
-+
-+ nand_flash: nand-flash@1 {
-+ compatible = "spi-flash-nand";
-+ reg = <1>;
-+ spi-max-frequency = <31250000>;
-+ page-size = <2048>;
-+ block-size = <17>;
-+ cdns,read-delay = <4>;
-+ cdns,tshsl-ns = <1>;
-+ cdns,tsd2d-ns = <1>;
-+ cdns,tchsh-ns = <1>;
-+ cdns,tslch-ns = <1>;
-+ spi-tx-bus-width = <1>;
-+ spi-rx-bus-width = <1>;
-+ };
-+};
-+
-+&sdio0 {
-+ broken-cd;
-+ bus-width = <4>;
-+ cap-sd-highspeed;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio0_pins>;
-+ status = "okay";
-+};
-+
-+&sdio1 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ bus-width = <4>;
-+ cap-sd-highspeed;
-+ cap-sdio-irq;
-+ cap-power-off-card;
-+ mmc-pwrseq = <&wifi_pwrseq>;
-+ non-removable;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio1_pins>;
-+ status = "okay";
-+
-+ wifi@1 {
-+ compatible = "brcm,bcm4329-fmac";
-+ reg = <1>;
-+ };
-+};
-+
-+&spi2 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi2_pins>;
-+ status = "okay";
-+
-+ spi_dev0: spi@0 {
-+ compatible = "rohm,dh2228fv";
-+ spi-max-frequency = <10000000>;
-+ reg = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins>;
-+ status = "okay";
-+};
-+
- &uart3 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart3_pins>;
- status = "okay";
- };
-+
-+&usb3 {
-+ dr_mode = "host";
-+ status = "okay";
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-@@ -18,3 +18,22 @@
- priority = <224>;
- };
- };
-+
-+&gpio {
-+ /* don't reset gpio mux for serial console and reset gpio */
-+ starfive,keep-gpiomux = <13 14 63>;
-+};
-+
-+&i2c0 {
-+ eeprom@50 {
-+ compatible = "atmel,24c04";
-+ reg = <0x50>;
-+ pagesize = <16>;
-+ };
-+};
-+
-+&mdio {
-+ phy: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -6,7 +6,9 @@
-
- /dts-v1/;
- #include <dt-bindings/clock/starfive-jh7100.h>
-+#include <dt-bindings/clock/starfive-jh7100-audio.h>
- #include <dt-bindings/reset/starfive-jh7100.h>
-+#include <dt-bindings/reset/starfive-jh7100-audio.h>
-
- / {
- compatible = "starfive,jh7100";
-@@ -32,7 +34,9 @@
- i-tlb-sets = <1>;
- i-tlb-size = <32>;
- mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc";
-+ starfive,itim = <&itim0>;
- tlb-split;
-
- cpu0_intc: interrupt-controller {
-@@ -57,7 +61,9 @@
- i-tlb-sets = <1>;
- i-tlb-size = <32>;
- mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc";
-+ starfive,itim = <&itim1>;
- tlb-split;
-
- cpu1_intc: interrupt-controller {
-@@ -108,6 +114,13 @@
- clock-frequency = <0>;
- };
-
-+ /* gmac device configuration */
-+ stmmac_axi_setup: stmmac-axi-config {
-+ snps,wr_osr_lmt = <0xf>;
-+ snps,rd_osr_lmt = <0xf>;
-+ snps,blen = <256 128 64 32 0 0 0>;
-+ };
-+
- soc {
- compatible = "simple-bus";
- interrupt-parent = <&plic>;
-@@ -116,6 +129,24 @@
- #size-cells = <2>;
- ranges;
-
-+ dtim: dtim@1000000 {
-+ compatible = "starfive,dtim0";
-+ reg = <0x0 0x1000000 0x0 0x2000>;
-+ reg-names = "mem";
-+ };
-+
-+ itim0: itim@1808000 {
-+ compatible = "starfive,itim0";
-+ reg = <0x0 0x1808000 0x0 0x8000>;
-+ reg-names = "mem";
-+ };
-+
-+ itim1: itim@1820000 {
-+ compatible = "starfive,itim0";
-+ reg = <0x0 0x1820000 0x0 0x8000>;
-+ reg-names = "mem";
-+ };
-+
- clint: clint@2000000 {
- compatible = "starfive,jh7100-clint", "sifive,clint0";
- reg = <0x0 0x2000000 0x0 0x10000>;
-@@ -123,6 +154,21 @@
- <&cpu1_intc 3>, <&cpu1_intc 7>;
- };
-
-+ ccache: cache-controller@2010000 {
-+ compatible = "starfive,jh7100-ccache", "cache";
-+ reg = <0x0 0x2010000 0x0 0x1000>,
-+ <0x0 0x8000000 0x0 0x2000000>;
-+ reg-names = "control", "sideband";
-+ interrupts = <128>, <130>, <131>, <129>;
-+ cache-block-size = <64>;
-+ cache-level = <2>;
-+ cache-sets = <2048>;
-+ cache-size = <2097152>;
-+ cache-unified;
-+ /*next-level-cache = <&L40 &L36>;*/
-+ uncached-offset = <0xf 0x80000000>;
-+ };
-+
- plic: interrupt-controller@c000000 {
- compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
- reg = <0x0 0xc000000 0x0 0x4000000>;
-@@ -134,6 +180,177 @@
- riscv,ndev = <133>;
- };
-
-+ sdio0: mmc@10000000 {
-+ compatible = "snps,dw-mshc";
-+ reg = <0x0 0x10000000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SDIO0_AHB>,
-+ <&clkgen JH7100_CLK_SDIO0_CCLKINT_INV>;
-+ clock-names = "biu", "ciu";
-+ interrupts = <4>;
-+ data-addr = <0>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ status = "disabled";
-+ };
-+
-+ sdio1: mmc@10010000 {
-+ compatible = "snps,dw-mshc";
-+ reg = <0x0 0x10010000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SDIO1_AHB>,
-+ <&clkgen JH7100_CLK_SDIO1_CCLKINT_INV>;
-+ clock-names = "biu", "ciu";
-+ interrupts = <5>;
-+ data-addr = <0>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ status = "disabled";
-+ };
-+
-+ gmac: ethernet@10020000 {
-+ compatible = "starfive,jh7100-dwmac", "snps,dwmac";
-+ reg = <0x0 0x10020000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_GMAC_ROOT_DIV>,
-+ <&clkgen JH7100_CLK_GMAC_AHB>,
-+ <&clkgen JH7100_CLK_GMAC_PTP_REF>,
-+ <&clkgen JH7100_CLK_GMAC_TX_INV>,
-+ <&clkgen JH7100_CLK_GMAC_GTX>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref", "tx", "gtx";
-+ resets = <&rstgen JH7100_RSTN_GMAC_AHB>;
-+ reset-names = "ahb";
-+ interrupts = <6>, <7>;
-+ interrupt-names = "macirq", "eth_wake_irq";
-+ max-frame-size = <9000>;
-+ snps,multicast-filter-bins = <0>;
-+ snps,perfect-filter-entries = <128>;
-+ starfive,syscon = <&sysmain 0x70 0>;
-+ rx-fifo-depth = <32768>;
-+ tx-fifo-depth = <16384>;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,fixed-burst;
-+ /*snps,force_sf_dma_mode;*/
-+ snps,force_thresh_dma_mode;
-+ snps,no-pbl-x8;
-+ status = "disabled";
-+ };
-+
-+ dma2p: dma-controller@100b0000 {
-+ compatible = "starfive,jh7100-axi-dma";
-+ reg = <0x0 0x100b0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SGDMA2P_AXI>,
-+ <&clkgen JH7100_CLK_SGDMA2P_AHB>;
-+ clock-names = "core-clk", "cfgr-clk";
-+ resets = <&rstgen JH7100_RSTN_SGDMA2P_AXI>,
-+ <&rstgen JH7100_RSTN_SGDMA2P_AHB>;
-+ reset-names = "axi", "ahb";
-+ interrupts = <2>;
-+ #dma-cells = <1>;
-+ dma-channels = <4>;
-+ snps,dma-masters = <1>;
-+ snps,data-width = <4>;
-+ snps,block-size = <4096 4096 4096 4096>;
-+ snps,priority = <0 1 2 3>;
-+ snps,axi-max-burst-len = <128>;
-+ dma-coherent;
-+ };
-+
-+ crypto: crypto@100d0000 {
-+ compatible = "starfive,vic-sec";
-+ reg = <0x0 0x100d0000 0x0 0x20000>,
-+ <0x0 0x11800234 0x0 0xc>;
-+ reg-names = "secmem", "secclk";
-+ clocks = <&clkgen JH7100_CLK_SEC_AHB>;
-+ interrupts = <31>;
-+ };
-+
-+ i2sadc0: i2sadc0@10400000 {
-+ compatible = "snps,designware-i2sadc0";
-+ reg = <0x0 0x10400000 0x0 0x1000>;
-+ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
-+ clock-names = "i2sclk";
-+ interrupt-parent = <&plic>;
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 28>;
-+ dma-names = "rx";
-+ };
-+
-+ i2svad: i2svad@10420000 {
-+ compatible = "starfive,sf-i2svad";
-+ reg = <0x0 0x10420000 0x0 0x1000> ;
-+ clocks = <&audclk JH7100_AUDCLK_I2SVAD_APB>;
-+ clock-names = "i2svad_apb";
-+ resets = <&audrst JH7100_AUDRSTN_I2SVAD_APB>,
-+ <&audrst JH7100_AUDRSTN_I2SVAD_SRST>;
-+ reset-names = "apb_i2svad", "i2svad_srst";
-+ interrupts = <60>, <61>;
-+ interrupt-names = "spintr", "slintr";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ pwmdac: pwmdac@10440000 {
-+ compatible = "starfive,pwmdac";
-+ reg = <0x0 0x10440000 0x0 0x1000>;
-+ clocks = <&clkgen JH7100_CLK_AUDIO_ROOT>,
-+ <&clkgen JH7100_CLK_AUDIO_SRC>,
-+ <&clkgen JH7100_CLK_AUDIO_12288>,
-+ <&audclk JH7100_AUDCLK_DMA1P_AHB>,
-+ <&audclk JH7100_AUDCLK_PWMDAC_APB>,
-+ <&audclk JH7100_AUDCLK_DAC_MCLK>;
-+ clock-names = "audio_root",
-+ "audio_src",
-+ "audio_12288",
-+ "dma1p_ahb",
-+ "pwmdac_apb",
-+ "dac_mclk";
-+ resets = <&audrst JH7100_AUDRSTN_APB_BUS>,
-+ <&audrst JH7100_AUDRSTN_DMA1P_AHB>,
-+ <&audrst JH7100_AUDRSTN_PWMDAC_APB>;
-+ reset-names = "apb_bus", "dma1p_ahb", "apb_pwmdac";
-+ dmas = <&dma2p 23>;
-+ dma-names = "tx";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ i2sdac0: i2sdac0@10450000 {
-+ compatible = "snps,designware-i2sdac0";
-+ reg = <0x0 0x10450000 0x0 0x1000>;
-+ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
-+ <&audclk JH7100_AUDCLK_I2SDAC_BCLK>,
-+ <&audclk JH7100_AUDCLK_I2SDAC_LRCLK>,
-+ <&audclk JH7100_AUDCLK_I2SDAC_APB>;
-+ clock-names = "dac_mclk", "i2sdac0_bclk", "i2sdac0_lrclk", "i2sdac_apb";
-+ resets = <&audrst JH7100_AUDRSTN_I2SDAC_APB>,
-+ <&audrst JH7100_AUDRSTN_I2SDAC_SRST>;
-+ reset-names = "apb_i2sdac", "i2sdac_srst";
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 30>;
-+ dma-names = "tx";
-+ };
-+
-+ i2sdac1: i2sdac1@10460000 {
-+ compatible = "snps,designware-i2sdac1";
-+ reg = <0x0 0x10460000 0x0 0x1000>;
-+ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
-+ <&audclk JH7100_AUDCLK_I2S1_BCLK>,
-+ <&audclk JH7100_AUDCLK_I2S1_LRCLK>,
-+ <&audclk JH7100_AUDCLK_I2S1_APB>;
-+ clock-names = "dac_mclk", "i2sdac1_bclk", "i2sdac1_lrclk", "i2s1_apb";
-+ resets = <&audrst JH7100_AUDRSTN_I2S1_APB>,
-+ <&audrst JH7100_AUDRSTN_I2S1_SRST>;
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 31>;
-+ dma-names = "tx";
-+ };
-+
-+ i2sdac16k: i2sdac16k@10470000 {
-+ compatible = "snps,designware-i2sdac16k";
-+ reg = <0x0 0x10470000 0x0 0x1000>;
-+ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
-+ clock-names = "i2sclk";
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 29>;
-+ dma-names = "tx";
-+ };
-+
- audclk: clock-controller@10480000 {
- compatible = "starfive,jh7100-audclk";
- reg = <0x0 0x10480000 0x0 0x10000>;
-@@ -150,6 +367,82 @@
- #reset-cells = <1>;
- };
-
-+ spdif_transmitter: spdif-transmitter {
-+ compatible = "linux,spdif-dit";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ spdif_receiver: spdif-receiver {
-+ compatible = "linux,spdif-dir";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ pwmdac_codec: pwmdac-transmitter {
-+ compatible = "linux,pwmdac-dit";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ dmic_codec: dmic {
-+ compatible = "dmic-codec";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ sound: snd-card {
-+ compatible = "simple-audio-card";
-+ simple-audio-card,name = "Starfive-Multi-Sound-Card";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ /* pwmdac */
-+ simple-audio-card,dai-link@0 {
-+ reg = <0>;
-+ status = "okay";
-+ format = "left_j";
-+ bitclock-master = <&sndcpu0>;
-+ frame-master = <&sndcpu0>;
-+
-+ sndcpu0: cpu {
-+ sound-dai = <&pwmdac>;
-+ };
-+
-+ codec {
-+ sound-dai = <&pwmdac_codec>;
-+ };
-+ };
-+ };
-+
-+ usb3: usb@104c0000 {
-+ compatible = "cdns,usb3";
-+ reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers
-+ <0x0 0x104d0000 0x0 0x10000>, // memory area for DEVICE registers
-+ <0x0 0x104e0000 0x0 0x10000>; // memory area for OTG/DRD registers
-+ reg-names = "otg", "xhci", "dev";
-+ interrupts = <44>, <52>, <43>;
-+ interrupt-names = "host", "peripheral", "otg";
-+ phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy";
-+ maximum-speed = "super-speed";
-+ status = "disabled";
-+ };
-+
-+ dma1p: dma-controller@10500000 {
-+ compatible = "starfive,jh7100-axi-dma";
-+ reg = <0x0 0x10500000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SGDMA1P_AXI>,
-+ <&clkgen JH7100_CLK_SGDMA1P_BUS>;
-+ clock-names = "core-clk", "cfgr-clk";
-+ resets = <&rstgen JH7100_RSTN_DMA1P_AXI>,
-+ <&rstgen JH7100_RSTN_SGDMA1P_AXI>;
-+ reset-names = "axi", "ahb";
-+ interrupts = <1>;
-+ #dma-cells = <1>;
-+ dma-channels = <16>;
-+ snps,dma-masters = <1>;
-+ snps,data-width = <3>;
-+ snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
-+ snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
-+ snps,axi-max-burst-len = <64>;
-+ };
-+
- clkgen: clock-controller@11800000 {
- compatible = "starfive,jh7100-clkgen";
- reg = <0x0 0x11800000 0x0 0x10000>;
-@@ -158,12 +451,93 @@
- #clock-cells = <1>;
- };
-
-+ otp: otp@11810000 {
-+ compatible = "starfive,fu740-otp";
-+ reg = <0x0 0x11810000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_OTP_APB>;
-+ fuse-count = <0x200>;
-+ };
-+
- rstgen: reset-controller@11840000 {
- compatible = "starfive,jh7100-reset";
- reg = <0x0 0x11840000 0x0 0x10000>;
- #reset-cells = <1>;
- };
-
-+ sysmain: syscon@11850000 {
-+ compatible = "starfive,jh7100-sysmain", "syscon";
-+ reg = <0x0 0x11850000 0x0 0x10000>;
-+ };
-+
-+ qspi: spi@11860000 {
-+ compatible = "cdns,qspi-nor";
-+ reg = <0x0 0x11860000 0x0 0x10000>,
-+ <0x0 0x20000000 0x0 0x20000000>;
-+ clocks = <&clkgen JH7100_CLK_QSPI_AHB>;
-+ interrupts = <3>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ cdns,fifo-depth = <256>;
-+ cdns,fifo-width = <4>;
-+ cdns,trigger-address = <0x0>;
-+ spi-max-frequency = <250000000>;
-+ status = "disabled";
-+ };
-+
-+ uart0: serial@11870000 {
-+ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
-+ reg = <0x0 0x11870000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_UART0_CORE>,
-+ <&clkgen JH7100_CLK_UART0_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&rstgen JH7100_RSTN_UART0_APB>;
-+ interrupts = <92>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@11880000 {
-+ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
-+ reg = <0x0 0x11880000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_UART1_CORE>,
-+ <&clkgen JH7100_CLK_UART1_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&rstgen JH7100_RSTN_UART1_APB>;
-+ interrupts = <93>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ spi0: spi@11890000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x11890000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI0_CORE>,
-+ <&clkgen JH7100_CLK_SPI0_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI0_APB>;
-+ reset-names = "spi";
-+ interrupts = <94>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ spi1: spi@118a0000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x118a0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI1_CORE>,
-+ <&clkgen JH7100_CLK_SPI1_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI1_APB>;
-+ reset-names = "spi";
-+ interrupts = <95>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- i2c0: i2c@118b0000 {
- compatible = "snps,designware-i2c";
- reg = <0x0 0x118b0000 0x0 0x10000>;
-@@ -190,6 +564,41 @@
- status = "disabled";
- };
-
-+ trng: trng@118d0000 {
-+ compatible = "starfive,vic-rng";
-+ reg = <0x0 0x118d0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_TRNG_APB>;
-+ interrupts = <98>;
-+ };
-+
-+ vpu_enc: vpu_enc@118e0000 {
-+ compatible = "cm,cm521-vpu";
-+ reg = <0x0 0x118e0000 0x0 0x4000>;
-+ reg-names = "control";
-+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
-+ clock-names = "vcodec";
-+ interrupts = <26>;
-+ };
-+
-+ vpu_dec: vpu_dec@118f0000 {
-+ compatible = "c&m,cm511-vpu";
-+ reg = <0 0x118f0000 0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
-+ clock-names = "vcodec";
-+ interrupts = <23>;
-+ //memory-region = <&vpu_reserved>;
-+ };
-+
-+ jpu: coadj12@11900000 {
-+ compatible = "cm,codaj12-jpu-1";
-+ reg = <0x0 0x11900000 0x0 0x300>;
-+ reg-names = "control";
-+ clocks = <&clkgen JH7100_CLK_JPEG_APB>;
-+ clock-names = "jpege";
-+ interrupts = <24>;
-+ memory-region = <&jpu_reserved>;
-+ };
-+
- gpio: pinctrl@11910000 {
- compatible = "starfive,jh7100-pinctrl";
- reg = <0x0 0x11910000 0x0 0x10000>,
-@@ -204,6 +613,86 @@
- #interrupt-cells = <2>;
- };
-
-+ nvdla@11940000 {
-+ compatible = "nvidia,nvdla_os_initial";
-+ interrupts = <22>;
-+ memory-region = <&nvdla_reserved>;
-+ reg = <0x0 0x11940000 0x0 0x40000>;
-+ status = "okay";
-+ };
-+
-+ display: display-subsystem {
-+ compatible = "starfive,display-subsystem";
-+ dma-coherent;
-+ status = "disabled";
-+ };
-+
-+ encoder: display-encoder {
-+ compatible = "starfive,display-encoder";
-+ status = "disabled";
-+ };
-+
-+ crtc: crtc@12000000 {
-+ compatible = "starfive,jh7100-crtc";
-+ reg = <0x0 0x12000000 0x0 0x10000>,
-+ <0x0 0x12040000 0x0 0x10000>,
-+ <0x0 0x12080000 0x0 0x10000>,
-+ <0x0 0x120c0000 0x0 0x10000>,
-+ <0x0 0x12240000 0x0 0x10000>,
-+ <0x0 0x12250000 0x0 0x10000>,
-+ <0x0 0x12260000 0x0 0x10000>;
-+ reg-names = "lcdc", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
-+ clocks = <&clkgen JH7100_CLK_DISP_AXI>, <&clkgen JH7100_CLK_VOUT_SRC>;
-+ clock-names = "disp_axi", "vout_src";
-+ resets = <&rstgen JH7100_RSTN_DISP_AXI>, <&rstgen JH7100_RSTN_VOUT_SRC>;
-+ reset-names = "disp_axi", "vout_src";
-+ interrupts = <101>, <103>;
-+ interrupt-names = "lcdc_irq", "vpp1_irq";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+
-+ pp1 {
-+ pp-id = <1>;
-+ fifo-out;
-+ //sys-bus-out;
-+ src-format = <11>; //<COLOR_RGB565>;
-+ src-width = <1920>;
-+ src-height = <1080>;
-+ dst-format = <7>; //<COLOR_RGB888_ARGB>;
-+ dst-width = <1920>;
-+ dst-height = <1080>;
-+ };
-+ };
-+
-+ spi2: spi@12410000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x12410000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI2_CORE>,
-+ <&clkgen JH7100_CLK_SPI2_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI2_APB>;
-+ reset-names = "spi";
-+ interrupts = <70>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ spi3: spi@12420000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x12420000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI3_CORE>,
-+ <&clkgen JH7100_CLK_SPI3_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI3_APB>;
-+ reset-names = "spi";
-+ interrupts = <71>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- uart2: serial@12430000 {
- compatible = "starfive,jh7100-uart", "snps,dw-apb-uart";
- reg = <0x0 0x12430000 0x0 0x10000>;
-@@ -265,5 +754,77 @@
- resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
- <&rstgen JH7100_RSTN_WDT>;
- };
-+
-+ ptc: pwm@12490000 {
-+ compatible = "starfive,pwm0";
-+ reg = <0x0 0x12490000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
-+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
-+ #pwm-cells = <3>;
-+ sifive,npwm = <8>;
-+ status = "disabled";
-+ };
-+
-+ sfctemp: tmon@124a0000 {
-+ compatible = "starfive,jh7100-temp";
-+ reg = <0x0 0x124a0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_TEMP_SENSE>,
-+ <&clkgen JH7100_CLK_TEMP_APB>;
-+ clock-names = "sense", "bus";
-+ resets = <&rstgen JH7100_RSTN_TEMP_SENSE>,
-+ <&rstgen JH7100_RSTN_TEMP_APB>;
-+ reset-names = "sense", "bus";
-+ interrupts = <122>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+
-+ thermal-zones {
-+ cpu-thermal {
-+ polling-delay-passive = <250>;
-+ polling-delay = <15000>;
-+
-+ thermal-sensors = <&sfctemp>;
-+
-+ cooling-maps {
-+ };
-+
-+ trips {
-+ cpu_alert0: cpu_alert0 {
-+ /* milliCelsius */
-+ temperature = <75000>;
-+ hysteresis = <2000>;
-+ type = "passive";
-+ };
-+
-+ cpu_crit: cpu_crit {
-+ /* milliCelsius */
-+ temperature = <90000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+ };
-+ };
-+ };
-+
-+ xrp@f0000000 {
-+ compatible = "cdns,xrp";
-+ reg = <0x0 0xf0000000 0x0 0x01ffffff>,
-+ <0x10 0x72000000 0x0 0x00001000>,
-+ <0x10 0x72001000 0x0 0x00fff000>,
-+ <0x0 0x124b0000 0x0 0x00010000>;
-+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
-+ interrupts = <27>, <28>;
-+ firmware-name = "vp6_elf";
-+ dsp-irq = <19 20>;
-+ dsp-irq-src = <0x20 0x21>;
-+ intc-irq-mode = <1>;
-+ intc-irq = <0 1>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges = <0x40000000 0x0 0x40000000 0x01000000>,
-+ <0xb0000000 0x10 0x70000000 0x3000000>;
-+ dsp@0 {
-+ };
-+ };
- };
- };
diff --git a/target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch b/target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch
deleted file mode 100644
index 7d190a5fc0..0000000000
--- a/target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From 21e0e009b1bffea86890fcbf6e1be4c4121258ef Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Fri, 11 Aug 2023 11:28:27 +0200
-Subject: [PATCH 1025/1025] riscv: dts: visionfive1: enable QSPI
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- .../riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-@@ -37,3 +37,7 @@
- reg = <0>;
- };
- };
-+
-+&qspi {
-+ status = "okay";
-+};
diff --git a/target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch b/target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
new file mode 100644
index 0000000000..e98e6dfaaf
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
@@ -0,0 +1,76 @@
+From 69275b667bd930cf5d5f577ba0ab1987c9d13987 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Mon, 21 Aug 2023 23:29:15 +0800
+Subject: [PATCH 001/116] clk: starfive: jh7110-sys: Fix lower rate of CPUfreq
+ by setting PLL0 rate to 1.5GHz
+
+CPUfreq supports 4 cpu frequency loads on 375/500/750/1500MHz.
+But now PLL0 rate is 1GHz and the cpu frequency loads become
+333/500/500/1000MHz in fact.
+
+So PLL0 rate should be set to 1.5GHz. Change the parent of cpu_root clock
+and the divider of cpu_core before the setting.
+
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC")
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../clk/starfive/clk-starfive-jh7110-sys.c | 47 ++++++++++++++++++-
+ 1 file changed, 46 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+@@ -530,7 +530,52 @@ static int __init jh7110_syscrg_probe(st
+ if (ret)
+ return ret;
+
+- return jh7110_reset_controller_register(priv, "rst-sys", 0);
++ ret = jh7110_reset_controller_register(priv, "rst-sys", 0);
++ if (ret)
++ return ret;
++
++ /*
++ * Set PLL0 rate to 1.5GHz
++ * In order to not affect the cpu when the PLL0 rate is changing,
++ * we need to switch the parent of cpu_root clock to osc clock first,
++ * and then switch back after setting the PLL0 rate.
++ */
++ pllclk = clk_get(priv->dev, "pll0_out");
++ if (!IS_ERR(pllclk)) {
++ struct clk *osc = clk_get(&pdev->dev, "osc");
++ struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;
++ struct clk *cpu_core = priv->reg[JH7110_SYSCLK_CPU_CORE].hw.clk;
++
++ if (IS_ERR(osc)) {
++ clk_put(pllclk);
++ return PTR_ERR(osc);
++ }
++
++ /*
++ * CPU need voltage regulation by CPUfreq if set 1.5GHz.
++ * So in this driver, cpu_core need to be set the divider to be 2 first
++ * and will be 750M after setting parent.
++ */
++ ret = clk_set_rate(cpu_core, clk_get_rate(cpu_core) / 2);
++ if (ret)
++ goto failed_set;
++
++ ret = clk_set_parent(cpu_root, osc);
++ if (ret)
++ goto failed_set;
++
++ ret = clk_set_rate(pllclk, 1500000000);
++ if (ret)
++ goto failed_set;
++
++ ret = clk_set_parent(cpu_root, pllclk);
++
++failed_set:
++ clk_put(pllclk);
++ clk_put(osc);
++ }
++
++ return ret;
+ }
+
+ static const struct of_device_id jh7110_syscrg_match[] = {
diff --git a/target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch b/target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
new file mode 100644
index 0000000000..2b5318bb44
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
@@ -0,0 +1,114 @@
+From 7d0dbcbc079e4f72b69f53442b7759da6ebc4f87 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 19 Oct 2023 13:34:59 +0800
+Subject: [PATCH 002/116] dt-bindings: timer: Add timer for StarFive JH7110 SoC
+
+Add bindings for the timer on the JH7110 RISC-V SoC
+by StarFive Technology Ltd.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../bindings/timer/starfive,jh7110-timer.yaml | 96 +++++++++++++++++++
+ 1 file changed, 96 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
+@@ -0,0 +1,96 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/timer/starfive,jh7110-timer.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 Timer
++
++maintainers:
++ - Xingyu Wu <xingyu.wu@starfivetech.com>
++ - Samin Guo <samin.guo@starfivetech.com>
++
++description:
++ This timer has four free-running 32 bit counters in StarFive JH7110 SoC.
++ And each channel(counter) triggers an interrupt when timeout. They support
++ one-shot mode and continuous-run mode.
++
++properties:
++ compatible:
++ const: starfive,jh7110-timer
++
++ reg:
++ maxItems: 1
++
++ interrupts:
++ items:
++ - description: channel 0
++ - description: channel 1
++ - description: channel 2
++ - description: channel 3
++
++ clocks:
++ items:
++ - description: timer APB
++ - description: channel 0
++ - description: channel 1
++ - description: channel 2
++ - description: channel 3
++
++ clock-names:
++ items:
++ - const: apb
++ - const: ch0
++ - const: ch1
++ - const: ch2
++ - const: ch3
++
++ resets:
++ items:
++ - description: timer APB
++ - description: channel 0
++ - description: channel 1
++ - description: channel 2
++ - description: channel 3
++
++ reset-names:
++ items:
++ - const: apb
++ - const: ch0
++ - const: ch1
++ - const: ch2
++ - const: ch3
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++
++additionalProperties: false
++
++examples:
++ - |
++ timer@13050000 {
++ compatible = "starfive,jh7110-timer";
++ reg = <0x13050000 0x10000>;
++ interrupts = <69>, <70>, <71> ,<72>;
++ clocks = <&clk 124>,
++ <&clk 125>,
++ <&clk 126>,
++ <&clk 127>,
++ <&clk 128>;
++ clock-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ resets = <&rst 117>,
++ <&rst 118>,
++ <&rst 119>,
++ <&rst 120>,
++ <&rst 121>;
++ reset-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ };
++
diff --git a/target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch b/target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch
new file mode 100644
index 0000000000..68b9c38d5b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch
@@ -0,0 +1,428 @@
+From 7cb47848f8a10aed6e050c0ea483b4bb5eaa62a4 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 19 Oct 2023 13:35:00 +0800
+Subject: [PATCH 003/116] clocksource: Add JH7110 timer driver
+
+Add timer driver for the StarFive JH7110 SoC.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ drivers/clocksource/Kconfig | 11 +
+ drivers/clocksource/Makefile | 1 +
+ drivers/clocksource/timer-jh7110.c | 380 +++++++++++++++++++++++++++++
+ 3 files changed, 392 insertions(+)
+ create mode 100644 drivers/clocksource/timer-jh7110.c
+
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -641,6 +641,17 @@ config RISCV_TIMER
+ is accessed via both the SBI and the rdcycle instruction. This is
+ required for all RISC-V systems.
+
++config STARFIVE_JH7110_TIMER
++ bool "Timer for the STARFIVE JH7110 SoC"
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ select TIMER_OF
++ select CLKSRC_MMIO
++ default ARCH_STARFIVE
++ help
++ This enables the timer for StarFive JH7110 SoC. On RISC-V platform,
++ the system has started RISCV_TIMER, but you can also use this timer
++ which can provide four channels to do a lot more things on JH7110 SoC.
++
+ config CLINT_TIMER
+ bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
+ depends on GENERIC_SCHED_CLOCK && RISCV
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-
+ obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
+ obj-$(CONFIG_X86_NUMACHIP) += numachip.o
+ obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
++obj-$(CONFIG_STARFIVE_JH7110_TIMER) += timer-jh7110.o
+ obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
+ obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
+ obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
+--- /dev/null
++++ b/drivers/clocksource/timer-jh7110.c
+@@ -0,0 +1,380 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Starfive JH7110 Timer driver
++ *
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
++ *
++ * Author:
++ * Xingyu Wu <xingyu.wu@starfivetech.com>
++ * Samin Guo <samin.guo@starfivetech.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/clockchips.h>
++#include <linux/clocksource.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/irq.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++#include <linux/sched_clock.h>
++
++/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
++#define JH7110_TIMER_CH_LEN 0x40
++#define JH7110_TIMER_CH_BASE(x) ((x) * JH7110_TIMER_CH_LEN)
++#define JH7110_TIMER_CH_MAX 4
++
++#define JH7110_CLOCK_SOURCE_RATING 200
++#define JH7110_VALID_BITS 32
++#define JH7110_DELAY_US 0
++#define JH7110_TIMEOUT_US 10000
++#define JH7110_CLOCKEVENT_RATING 300
++#define JH7110_TIMER_MAX_TICKS 0xffffffff
++#define JH7110_TIMER_MIN_TICKS 0xf
++#define JH7110_TIMER_RELOAD_VALUE 0
++
++#define JH7110_TIMER_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
++#define JH7110_TIMER_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
++#define JH7110_TIMER_LOAD 0x08 /* RW: load value to counter */
++#define JH7110_TIMER_ENABLE 0x10 /* RW[0]: timer enable register */
++#define JH7110_TIMER_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
++#define JH7110_TIMER_VALUE 0x18 /* RO: timer value register */
++#define JH7110_TIMER_INT_CLR 0x20 /* RW: timer interrupt clear register */
++#define JH7110_TIMER_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
++
++#define JH7110_TIMER_INT_CLR_ENA BIT(0)
++#define JH7110_TIMER_INT_CLR_AVA_MASK BIT(1)
++
++struct jh7110_clkevt {
++ struct clock_event_device evt;
++ struct clocksource cs;
++ bool cs_is_valid;
++ struct clk *clk;
++ struct reset_control *rst;
++ u32 rate;
++ u32 reload_val;
++ void __iomem *base;
++ char name[sizeof("jh7110-timer.chX")];
++};
++
++struct jh7110_timer_priv {
++ struct clk *pclk;
++ struct reset_control *prst;
++ struct jh7110_clkevt clkevt[JH7110_TIMER_CH_MAX];
++};
++
++/* 0:continuous-run mode, 1:single-run mode */
++enum jh7110_timer_mode {
++ JH7110_TIMER_MODE_CONTIN,
++ JH7110_TIMER_MODE_SINGLE,
++};
++
++/* Interrupt Mask, 0:Unmask, 1:Mask */
++enum jh7110_timer_int_mask {
++ JH7110_TIMER_INT_ENA,
++ JH7110_TIMER_INT_DIS,
++};
++
++enum jh7110_timer_enable {
++ JH7110_TIMER_DIS,
++ JH7110_TIMER_ENA,
++};
++
++static inline struct jh7110_clkevt *to_jh7110_clkevt(struct clock_event_device *evt)
++{
++ return container_of(evt, struct jh7110_clkevt, evt);
++}
++
++/*
++ * BIT(0): Read value represent channel int status.
++ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
++ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
++ */
++static inline int jh7110_timer_int_clear(struct jh7110_clkevt *clkevt)
++{
++ u32 value;
++ int ret;
++
++ /* Waiting interrupt can be cleared */
++ ret = readl_poll_timeout_atomic(clkevt->base + JH7110_TIMER_INT_CLR, value,
++ !(value & JH7110_TIMER_INT_CLR_AVA_MASK),
++ JH7110_DELAY_US, JH7110_TIMEOUT_US);
++ if (!ret)
++ writel(JH7110_TIMER_INT_CLR_ENA, clkevt->base + JH7110_TIMER_INT_CLR);
++
++ return ret;
++}
++
++static int jh7110_timer_start(struct jh7110_clkevt *clkevt)
++{
++ int ret;
++
++ /* Disable and clear interrupt first */
++ writel(JH7110_TIMER_INT_DIS, clkevt->base + JH7110_TIMER_INT_MASK);
++ ret = jh7110_timer_int_clear(clkevt);
++ if (ret)
++ return ret;
++
++ writel(JH7110_TIMER_INT_ENA, clkevt->base + JH7110_TIMER_INT_MASK);
++ writel(JH7110_TIMER_ENA, clkevt->base + JH7110_TIMER_ENABLE);
++
++ return 0;
++}
++
++static int jh7110_timer_shutdown(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
++ return jh7110_timer_int_clear(clkevt);
++}
++
++static void jh7110_timer_suspend(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ clkevt->reload_val = readl(clkevt->base + JH7110_TIMER_LOAD);
++ jh7110_timer_shutdown(evt);
++}
++
++static void jh7110_timer_resume(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(clkevt->reload_val, clkevt->base + JH7110_TIMER_LOAD);
++ writel(JH7110_TIMER_RELOAD_VALUE, clkevt->base + JH7110_TIMER_RELOAD);
++ jh7110_timer_start(clkevt);
++}
++
++static int jh7110_timer_tick_resume(struct clock_event_device *evt)
++{
++ jh7110_timer_resume(evt);
++
++ return 0;
++}
++
++/* IRQ handler for the timer */
++static irqreturn_t jh7110_timer_interrupt(int irq, void *priv)
++{
++ struct clock_event_device *evt = (struct clock_event_device *)priv;
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ if (jh7110_timer_int_clear(clkevt))
++ return IRQ_NONE;
++
++ if (evt->event_handler)
++ evt->event_handler(evt);
++
++ return IRQ_HANDLED;
++}
++
++static int jh7110_timer_set_periodic(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++ u32 periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
++
++ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
++ writel(periodic, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static int jh7110_timer_set_oneshot(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
++ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static int jh7110_timer_set_next_event(unsigned long next,
++ struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
++ writel(next, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static void jh7110_set_clockevent(struct clock_event_device *evt)
++{
++ evt->features = CLOCK_EVT_FEAT_PERIODIC |
++ CLOCK_EVT_FEAT_ONESHOT |
++ CLOCK_EVT_FEAT_DYNIRQ;
++ evt->set_state_shutdown = jh7110_timer_shutdown;
++ evt->set_state_periodic = jh7110_timer_set_periodic;
++ evt->set_state_oneshot = jh7110_timer_set_oneshot;
++ evt->set_state_oneshot_stopped = jh7110_timer_shutdown;
++ evt->tick_resume = jh7110_timer_tick_resume;
++ evt->set_next_event = jh7110_timer_set_next_event;
++ evt->suspend = jh7110_timer_suspend;
++ evt->resume = jh7110_timer_resume;
++ evt->rating = JH7110_CLOCKEVENT_RATING;
++}
++
++static u64 jh7110_timer_clocksource_read(struct clocksource *cs)
++{
++ struct jh7110_clkevt *clkevt = container_of(cs, struct jh7110_clkevt, cs);
++
++ return (u64)readl(clkevt->base + JH7110_TIMER_VALUE);
++}
++
++static int jh7110_clocksource_init(struct jh7110_clkevt *clkevt)
++{
++ int ret;
++
++ clkevt->cs.name = clkevt->name;
++ clkevt->cs.rating = JH7110_CLOCK_SOURCE_RATING;
++ clkevt->cs.read = jh7110_timer_clocksource_read;
++ clkevt->cs.mask = CLOCKSOURCE_MASK(JH7110_VALID_BITS);
++ clkevt->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
++
++ ret = clocksource_register_hz(&clkevt->cs, clkevt->rate);
++ if (ret)
++ return ret;
++
++ clkevt->cs_is_valid = true; /* clocksource register done */
++ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
++ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static void jh7110_clockevents_register(struct jh7110_clkevt *clkevt)
++{
++ clkevt->rate = clk_get_rate(clkevt->clk);
++
++ jh7110_set_clockevent(&clkevt->evt);
++ clkevt->evt.name = clkevt->name;
++ clkevt->evt.cpumask = cpu_possible_mask;
++
++ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
++ JH7110_TIMER_MIN_TICKS, JH7110_TIMER_MAX_TICKS);
++}
++
++static void jh7110_timer_release(void *data)
++{
++ struct jh7110_timer_priv *priv = data;
++ int i;
++
++ for (i = 0; i < JH7110_TIMER_CH_MAX; i++) {
++ /* Disable each channel of timer */
++ if (priv->clkevt[i].base)
++ writel(JH7110_TIMER_DIS, priv->clkevt[i].base + JH7110_TIMER_ENABLE);
++
++ /* Avoid no initialization in the loop of the probe */
++ if (!IS_ERR_OR_NULL(priv->clkevt[i].rst))
++ reset_control_assert(priv->clkevt[i].rst);
++
++ if (priv->clkevt[i].cs_is_valid)
++ clocksource_unregister(&priv->clkevt[i].cs);
++ }
++
++ reset_control_assert(priv->prst);
++}
++
++static int jh7110_timer_probe(struct platform_device *pdev)
++{
++ struct jh7110_timer_priv *priv;
++ struct jh7110_clkevt *clkevt;
++ char name[sizeof("chX")];
++ int ch;
++ int ret;
++ void __iomem *base;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(base))
++ return dev_err_probe(&pdev->dev, PTR_ERR(base),
++ "failed to map registers\n");
++
++ priv->prst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
++ if (IS_ERR(priv->prst))
++ return dev_err_probe(&pdev->dev, PTR_ERR(priv->prst),
++ "failed to get apb reset\n");
++
++ priv->pclk = devm_clk_get_enabled(&pdev->dev, "apb");
++ if (IS_ERR(priv->pclk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk),
++ "failed to get & enable apb clock\n");
++
++ ret = reset_control_deassert(priv->prst);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "failed to deassert apb reset\n");
++
++ ret = devm_add_action_or_reset(&pdev->dev, jh7110_timer_release, priv);
++ if (ret)
++ return ret;
++
++ for (ch = 0; ch < JH7110_TIMER_CH_MAX; ch++) {
++ clkevt = &priv->clkevt[ch];
++ snprintf(name, sizeof(name), "ch%d", ch);
++
++ clkevt->base = base + JH7110_TIMER_CH_BASE(ch);
++ /* Ensure timer is disabled */
++ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
++
++ clkevt->rst = devm_reset_control_get_exclusive(&pdev->dev, name);
++ if (IS_ERR(clkevt->rst))
++ return PTR_ERR(clkevt->rst);
++
++ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
++ if (IS_ERR(clkevt->clk))
++ return PTR_ERR(clkevt->clk);
++
++ ret = reset_control_deassert(clkevt->rst);
++ if (ret)
++ return ret;
++
++ clkevt->evt.irq = platform_get_irq(pdev, ch);
++ if (clkevt->evt.irq < 0)
++ return clkevt->evt.irq;
++
++ snprintf(clkevt->name, sizeof(clkevt->name), "jh7110-timer.ch%d", ch);
++ jh7110_clockevents_register(clkevt);
++
++ ret = devm_request_irq(&pdev->dev, clkevt->evt.irq, jh7110_timer_interrupt,
++ IRQF_TIMER | IRQF_IRQPOLL,
++ clkevt->name, &clkevt->evt);
++ if (ret)
++ return ret;
++
++ ret = jh7110_clocksource_init(clkevt);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct of_device_id jh7110_timer_match[] = {
++ { .compatible = "starfive,jh7110-timer", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_timer_match);
++
++static struct platform_driver jh7110_timer_driver = {
++ .probe = jh7110_timer_probe,
++ .driver = {
++ .name = "jh7110-timer",
++ .of_match_table = jh7110_timer_match,
++ },
++};
++module_platform_driver(jh7110_timer_driver);
++
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH7110 timer driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch b/target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch
new file mode 100644
index 0000000000..9c1e78b29b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch
@@ -0,0 +1,34 @@
+From b513eb2cabee212ba1a23839f18c0026a21e653e Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Sep 2023 14:28:32 +0800
+Subject: [PATCH 004/116] dt-bindings: mmc: starfive: Remove properties from
+ required
+
+Due to the change of tuning implementation, it's no longer necessary to
+use the "starfive,sysreg" property in dts, so remove it from required.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Link: https://lore.kernel.org/r/20230922062834.39212-2-william.qiu@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
++++ b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
+@@ -55,7 +55,6 @@ required:
+ - clocks
+ - clock-names
+ - interrupts
+- - starfive,sysreg
+
+ unevaluatedProperties: false
+
+@@ -73,5 +72,4 @@ examples:
+ fifo-depth = <32>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+- starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
+ };
diff --git a/target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch b/target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch
new file mode 100644
index 0000000000..b8ea96f3c8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch
@@ -0,0 +1,199 @@
+From 3ae8cec8fd28e18847edb67dfea04718c2f3369f Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Sep 2023 14:28:33 +0800
+Subject: [PATCH 005/116] mmc: starfive: Change tuning implementation
+
+Before, we used syscon to achieve tuning, but the actual measurement
+showed little effect, so the tuning implementation was modified here,
+and it was realized by reading and writing the UHS_REG_EXT register.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Link: https://lore.kernel.org/r/20230922062834.39212-3-william.qiu@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/dw_mmc-starfive.c | 137 +++++++++--------------------
+ 1 file changed, 40 insertions(+), 97 deletions(-)
+
+--- a/drivers/mmc/host/dw_mmc-starfive.c
++++ b/drivers/mmc/host/dw_mmc-starfive.c
+@@ -5,6 +5,7 @@
+ * Copyright (c) 2022 StarFive Technology Co., Ltd.
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/mfd/syscon.h>
+@@ -20,13 +21,7 @@
+ #define ALL_INT_CLR 0x1ffff
+ #define MAX_DELAY_CHAIN 32
+
+-struct starfive_priv {
+- struct device *dev;
+- struct regmap *reg_syscon;
+- u32 syscon_offset;
+- u32 syscon_shift;
+- u32 syscon_mask;
+-};
++#define STARFIVE_SMPL_PHASE GENMASK(20, 16)
+
+ static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+ {
+@@ -44,117 +39,65 @@ static void dw_mci_starfive_set_ios(stru
+ }
+ }
+
++static void dw_mci_starfive_set_sample_phase(struct dw_mci *host, u32 smpl_phase)
++{
++ /* change driver phase and sample phase */
++ u32 reg_value = mci_readl(host, UHS_REG_EXT);
++
++ /* In UHS_REG_EXT, only 5 bits valid in DRV_PHASE and SMPL_PHASE */
++ reg_value &= ~STARFIVE_SMPL_PHASE;
++ reg_value |= FIELD_PREP(STARFIVE_SMPL_PHASE, smpl_phase);
++ mci_writel(host, UHS_REG_EXT, reg_value);
++
++ /* We should delay 1ms wait for timing setting finished. */
++ mdelay(1);
++}
++
+ static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
+ u32 opcode)
+ {
+ static const int grade = MAX_DELAY_CHAIN;
+ struct dw_mci *host = slot->host;
+- struct starfive_priv *priv = host->priv;
+- int rise_point = -1, fall_point = -1;
+- int err, prev_err = 0;
+- int i;
+- bool found = 0;
+- u32 regval;
+-
+- /*
+- * Use grade as the max delay chain, and use the rise_point and
+- * fall_point to ensure the best sampling point of a data input
+- * signals.
+- */
+- for (i = 0; i < grade; i++) {
+- regval = i << priv->syscon_shift;
+- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
+- priv->syscon_mask, regval);
+- if (err)
+- return err;
+- mci_writel(host, RINTSTS, ALL_INT_CLR);
+-
+- err = mmc_send_tuning(slot->mmc, opcode, NULL);
+- if (!err)
+- found = 1;
+-
+- if (i > 0) {
+- if (err && !prev_err)
+- fall_point = i - 1;
+- if (!err && prev_err)
+- rise_point = i;
+- }
++ int smpl_phase, smpl_raise = -1, smpl_fall = -1;
++ int ret;
+
+- if (rise_point != -1 && fall_point != -1)
+- goto tuning_out;
++ for (smpl_phase = 0; smpl_phase < grade; smpl_phase++) {
++ dw_mci_starfive_set_sample_phase(host, smpl_phase);
++ mci_writel(host, RINTSTS, ALL_INT_CLR);
+
+- prev_err = err;
+- err = 0;
+- }
++ ret = mmc_send_tuning(slot->mmc, opcode, NULL);
+
+-tuning_out:
+- if (found) {
+- if (rise_point == -1)
+- rise_point = 0;
+- if (fall_point == -1)
+- fall_point = grade - 1;
+- if (fall_point < rise_point) {
+- if ((rise_point + fall_point) >
+- (grade - 1))
+- i = fall_point / 2;
+- else
+- i = (rise_point + grade - 1) / 2;
+- } else {
+- i = (rise_point + fall_point) / 2;
++ if (!ret && smpl_raise < 0) {
++ smpl_raise = smpl_phase;
++ } else if (ret && smpl_raise >= 0) {
++ smpl_fall = smpl_phase - 1;
++ break;
+ }
+-
+- regval = i << priv->syscon_shift;
+- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
+- priv->syscon_mask, regval);
+- if (err)
+- return err;
+- mci_writel(host, RINTSTS, ALL_INT_CLR);
+-
+- dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i);
+- } else {
+- dev_err(host->dev, "No valid delay chain! use default\n");
+- err = -EINVAL;
+ }
+
+- mci_writel(host, RINTSTS, ALL_INT_CLR);
+- return err;
+-}
+-
+-static int dw_mci_starfive_parse_dt(struct dw_mci *host)
+-{
+- struct of_phandle_args args;
+- struct starfive_priv *priv;
+- int ret;
++ if (smpl_phase >= grade)
++ smpl_fall = grade - 1;
+
+- priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- ret = of_parse_phandle_with_fixed_args(host->dev->of_node,
+- "starfive,sysreg", 3, 0, &args);
+- if (ret) {
+- dev_err(host->dev, "Failed to parse starfive,sysreg\n");
+- return -EINVAL;
++ if (smpl_raise < 0) {
++ smpl_phase = 0;
++ dev_err(host->dev, "No valid delay chain! use default\n");
++ ret = -EINVAL;
++ goto out;
+ }
+
+- priv->reg_syscon = syscon_node_to_regmap(args.np);
+- of_node_put(args.np);
+- if (IS_ERR(priv->reg_syscon))
+- return PTR_ERR(priv->reg_syscon);
+-
+- priv->syscon_offset = args.args[0];
+- priv->syscon_shift = args.args[1];
+- priv->syscon_mask = args.args[2];
+-
+- host->priv = priv;
++ smpl_phase = (smpl_raise + smpl_fall) / 2;
++ dev_dbg(host->dev, "Found valid delay chain! use it [delay=%d]\n", smpl_phase);
++ ret = 0;
+
+- return 0;
++out:
++ dw_mci_starfive_set_sample_phase(host, smpl_phase);
++ mci_writel(host, RINTSTS, ALL_INT_CLR);
++ return ret;
+ }
+
+ static const struct dw_mci_drv_data starfive_data = {
+ .common_caps = MMC_CAP_CMD23,
+ .set_ios = dw_mci_starfive_set_ios,
+- .parse_dt = dw_mci_starfive_parse_dt,
+ .execute_tuning = dw_mci_starfive_execute_tuning,
+ };
+
diff --git a/target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch b/target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch
new file mode 100644
index 0000000000..aafbee5d42
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch
@@ -0,0 +1,79 @@
+From e366df2ff64e9f93a5b35eea6a198b005d5a0911 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Dec 2023 17:45:45 +0800
+Subject: [PATCH 006/116] dt-bindings: pwm: Add bindings for OpenCores PWM
+ Controller
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add bindings for OpenCores PWM Controller.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ .../bindings/pwm/opencores,pwm.yaml | 55 +++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
+@@ -0,0 +1,55 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pwm/opencores,pwm.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: OpenCores PWM controller
++
++maintainers:
++ - William Qiu <william.qiu@starfivetech.com>
++
++description:
++ The OpenCores PTC ip core contains a PWM controller. When operating in PWM
++ mode, the PTC core generates binary signal with user-programmable low and
++ high periods. All PTC counters and registers are 32-bit.
++
++allOf:
++ - $ref: pwm.yaml#
++
++properties:
++ compatible:
++ items:
++ - enum:
++ - starfive,jh7100-pwm
++ - starfive,jh7110-pwm
++ - const: opencores,pwm-v1
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ resets:
++ maxItems: 1
++
++ "#pwm-cells":
++ const: 3
++
++required:
++ - compatible
++ - reg
++ - clocks
++
++additionalProperties: false
++
++examples:
++ - |
++ pwm@12490000 {
++ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
++ reg = <0x12490000 0x10000>;
++ clocks = <&clkgen 181>;
++ resets = <&rstgen 109>;
++ #pwm-cells = <3>;
++ };
diff --git a/target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch b/target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch
new file mode 100644
index 0000000000..27e510d86a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch
@@ -0,0 +1,285 @@
+From 644bfe581dde9b762460a4916da4d71c148be06e Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Dec 2023 17:45:46 +0800
+Subject: [PATCH 007/116] pwm: opencores: Add PWM driver support
+
+Add driver for OpenCores PWM Controller. And add compatibility code
+which based on StarFive SoC.
+
+Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ drivers/pwm/Kconfig | 12 ++
+ drivers/pwm/Makefile | 1 +
+ drivers/pwm/pwm-ocores.c | 233 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 246 insertions(+)
+ create mode 100644 drivers/pwm/pwm-ocores.c
+
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -434,6 +434,18 @@ config PWM_NTXEC
+ controller found in certain e-book readers designed by the original
+ design manufacturer Netronix.
+
++config PWM_OCORES
++ tristate "OpenCores PWM support"
++ depends on HAS_IOMEM && OF
++ depends on COMMON_CLK
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ help
++ If you say yes to this option, support will be included for the
++ OpenCores PWM. For details see https://opencores.org/projects/ptc.
++
++ To compile this driver as a module, choose M here: the module
++ will be called pwm-ocores.
++
+ config PWM_OMAP_DMTIMER
+ tristate "OMAP Dual-Mode Timer PWM support"
+ depends on OF
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -39,6 +39,7 @@ obj-$(CONFIG_PWM_MICROCHIP_CORE) += pwm-
+ obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
+ obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
+ obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
++obj-$(CONFIG_PWM_OCORES) += pwm-ocores.o
+ obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
+ obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
+ obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
+--- /dev/null
++++ b/drivers/pwm/pwm-ocores.c
+@@ -0,0 +1,233 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * OpenCores PWM Driver
++ *
++ * https://opencores.org/projects/ptc
++ *
++ * Copyright (C) 2018-2023 StarFive Technology Co., Ltd.
++ *
++ * Limitations:
++ * - The hardware only do inverted polarity.
++ * - The hardware minimum period / duty_cycle is (1 / pwm_apb clock frequency) ns.
++ * - The hardware maximum period / duty_cycle is (U32_MAX / pwm_apb clock frequency) ns.
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++/* OCPWM_CTRL register bits*/
++#define REG_OCPWM_EN BIT(0)
++#define REG_OCPWM_ECLK BIT(1)
++#define REG_OCPWM_NEC BIT(2)
++#define REG_OCPWM_OE BIT(3)
++#define REG_OCPWM_SIGNLE BIT(4)
++#define REG_OCPWM_INTE BIT(5)
++#define REG_OCPWM_INT BIT(6)
++#define REG_OCPWM_CNTRRST BIT(7)
++#define REG_OCPWM_CAPTE BIT(8)
++
++struct ocores_pwm_device {
++ struct pwm_chip chip;
++ struct clk *clk;
++ struct reset_control *rst;
++ const struct ocores_pwm_data *data;
++ void __iomem *regs;
++ u32 clk_rate; /* PWM APB clock frequency */
++};
++
++struct ocores_pwm_data {
++ void __iomem *(*get_ch_base)(void __iomem *base, unsigned int channel);
++};
++
++static inline u32 ocores_readl(struct ocores_pwm_device *ddata,
++ unsigned int channel,
++ unsigned int offset)
++{
++ void __iomem *base = ddata->data->get_ch_base ?
++ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
++
++ return readl(base + offset);
++}
++
++static inline void ocores_writel(struct ocores_pwm_device *ddata,
++ unsigned int channel,
++ unsigned int offset, u32 val)
++{
++ void __iomem *base = ddata->data->get_ch_base ?
++ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
++
++ writel(val, base + offset);
++}
++
++static inline struct ocores_pwm_device *chip_to_ocores(struct pwm_chip *chip)
++{
++ return container_of(chip, struct ocores_pwm_device, chip);
++}
++
++static void __iomem *starfive_jh71x0_get_ch_base(void __iomem *base,
++ unsigned int channel)
++{
++ unsigned int offset = (channel > 3 ? 1 << 15 : 0) + (channel & 3) * 0x10;
++
++ return base + offset;
++}
++
++static int ocores_pwm_get_state(struct pwm_chip *chip,
++ struct pwm_device *pwm,
++ struct pwm_state *state)
++{
++ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
++ u32 period_data, duty_data, ctrl_data;
++
++ period_data = ocores_readl(ddata, pwm->hwpwm, 0x8);
++ duty_data = ocores_readl(ddata, pwm->hwpwm, 0x4);
++ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
++
++ state->period = DIV_ROUND_UP_ULL((u64)period_data * NSEC_PER_SEC, ddata->clk_rate);
++ state->duty_cycle = DIV_ROUND_UP_ULL((u64)duty_data * NSEC_PER_SEC, ddata->clk_rate);
++ state->polarity = PWM_POLARITY_INVERSED;
++ state->enabled = (ctrl_data & REG_OCPWM_EN) ? true : false;
++
++ return 0;
++}
++
++static int ocores_pwm_apply(struct pwm_chip *chip,
++ struct pwm_device *pwm,
++ const struct pwm_state *state)
++{
++ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
++ u32 ctrl_data = 0;
++ u64 period_data, duty_data;
++
++ if (state->polarity != PWM_POLARITY_INVERSED)
++ return -EINVAL;
++
++ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
++ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
++
++ period_data = DIV_ROUND_DOWN_ULL(state->period * ddata->clk_rate, NSEC_PER_SEC);
++ if (period_data <= U32_MAX)
++ ocores_writel(ddata, pwm->hwpwm, 0x8, (u32)period_data);
++ else
++ return -EINVAL;
++
++ duty_data = DIV_ROUND_DOWN_ULL(state->duty_cycle * ddata->clk_rate, NSEC_PER_SEC);
++ if (duty_data <= U32_MAX)
++ ocores_writel(ddata, pwm->hwpwm, 0x4, (u32)duty_data);
++ else
++ return -EINVAL;
++
++ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
++
++ if (state->enabled) {
++ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
++ ocores_writel(ddata, pwm->hwpwm, 0xC, ctrl_data | REG_OCPWM_EN | REG_OCPWM_OE);
++ }
++
++ return 0;
++}
++
++static const struct pwm_ops ocores_pwm_ops = {
++ .get_state = ocores_pwm_get_state,
++ .apply = ocores_pwm_apply,
++};
++
++static const struct ocores_pwm_data jh7100_pwm_data = {
++ .get_ch_base = starfive_jh71x0_get_ch_base,
++};
++
++static const struct ocores_pwm_data jh7110_pwm_data = {
++ .get_ch_base = starfive_jh71x0_get_ch_base,
++};
++
++static const struct of_device_id ocores_pwm_of_match[] = {
++ { .compatible = "opencores,pwm-v1" },
++ { .compatible = "starfive,jh7100-pwm", .data = &jh7100_pwm_data},
++ { .compatible = "starfive,jh7110-pwm", .data = &jh7110_pwm_data},
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ocores_pwm_of_match);
++
++static void ocores_reset_control_assert(void *data)
++{
++ reset_control_assert(data);
++}
++
++static int ocores_pwm_probe(struct platform_device *pdev)
++{
++ const struct of_device_id *id;
++ struct device *dev = &pdev->dev;
++ struct ocores_pwm_device *ddata;
++ struct pwm_chip *chip;
++ int ret;
++
++ id = of_match_device(ocores_pwm_of_match, dev);
++ if (!id)
++ return -EINVAL;
++
++ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
++ if (!ddata)
++ return -ENOMEM;
++
++ ddata->data = id->data;
++ chip = &ddata->chip;
++ chip->dev = dev;
++ chip->ops = &ocores_pwm_ops;
++ chip->npwm = 8;
++ chip->of_pwm_n_cells = 3;
++
++ ddata->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(ddata->regs))
++ return dev_err_probe(dev, PTR_ERR(ddata->regs),
++ "Unable to map IO resources\n");
++
++ ddata->clk = devm_clk_get_enabled(dev, NULL);
++ if (IS_ERR(ddata->clk))
++ return dev_err_probe(dev, PTR_ERR(ddata->clk),
++ "Unable to get pwm's clock\n");
++
++ ddata->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
++ if (IS_ERR(ddata->rst))
++ return dev_err_probe(dev, PTR_ERR(ddata->rst),
++ "Unable to get pwm's reset\n");
++
++ reset_control_deassert(ddata->rst);
++
++ ret = devm_add_action_or_reset(dev, ocores_reset_control_assert, ddata->rst);
++ if (ret)
++ return ret;
++
++ ddata->clk_rate = clk_get_rate(ddata->clk);
++ if (ddata->clk_rate <= 0)
++ return dev_err_probe(dev, ddata->clk_rate,
++ "Unable to get clock's rate\n");
++
++ ret = devm_pwmchip_add(dev, chip);
++ if (ret < 0)
++ return dev_err_probe(dev, ret, "Could not register PWM chip\n");
++
++ platform_set_drvdata(pdev, ddata);
++
++ return ret;
++}
++
++static struct platform_driver ocores_pwm_driver = {
++ .probe = ocores_pwm_probe,
++ .driver = {
++ .name = "ocores-pwm",
++ .of_match_table = ocores_pwm_of_match,
++ },
++};
++module_platform_driver(ocores_pwm_driver);
++
++MODULE_AUTHOR("Jieqin Chen");
++MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
++MODULE_DESCRIPTION("OpenCores PWM PTC driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch b/target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch
new file mode 100644
index 0000000000..a6ede31342
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch
@@ -0,0 +1,117 @@
+From 7d9521cad6474d45e9056176982e6da54d40bc19 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Sun, 22 Oct 2023 01:10:42 -0700
+Subject: [PATCH 008/116] crypto: starfive - remove unnecessary alignmask for
+ ahashes
+
+The crypto API's support for alignmasks for ahash algorithms is nearly
+useless, as its only effect is to cause the API to align the key and
+result buffers. The drivers that happen to be specifying an alignmask
+for ahash rarely actually need it. When they do, it's easily fixable,
+especially considering that these buffers cannot be used for DMA.
+
+In preparation for removing alignmask support from ahash, this patch
+makes the starfive driver no longer use it. This driver did actually
+rely on it, but only for storing to the result buffer using int stores
+in starfive_hash_copy_hash(). This patch makes
+starfive_hash_copy_hash() use put_unaligned() instead. (It really
+should use a specific endianness, but that's an existing bug.)
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-hash.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-hash.c
++++ b/drivers/crypto/starfive/jh7110-hash.c
+@@ -209,7 +209,8 @@ static int starfive_hash_copy_hash(struc
+ data = (u32 *)req->result;
+
+ for (count = 0; count < mlen; count++)
+- data[count] = readl(ctx->cryp->base + STARFIVE_HASH_SHARDR);
++ put_unaligned(readl(ctx->cryp->base + STARFIVE_HASH_SHARDR),
++ &data[count]);
+
+ return 0;
+ }
+@@ -628,7 +629,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -658,7 +658,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -687,7 +686,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -717,7 +715,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -746,7 +743,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -776,7 +772,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -805,7 +800,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -835,7 +829,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -864,7 +857,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SM3_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -894,7 +886,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SM3_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
diff --git a/target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch b/target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch
new file mode 100644
index 0000000000..145c01377d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch
@@ -0,0 +1,25 @@
+From 52de0270ed6453727936b5a793dc367d75280e84 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Wed, 15 Nov 2023 01:12:13 +0800
+Subject: [PATCH 009/116] crypto: starfive - Update driver dependencies
+
+Change AMBA_PL08X to required dependency as the hash ops depends on it
+for data transfer.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/starfive/Kconfig
++++ b/drivers/crypto/starfive/Kconfig
+@@ -4,7 +4,7 @@
+
+ config CRYPTO_DEV_JH7110
+ tristate "StarFive JH7110 cryptographic engine driver"
+- depends on SOC_STARFIVE || AMBA_PL08X || COMPILE_TEST
++ depends on (SOC_STARFIVE && AMBA_PL08X) || COMPILE_TEST
+ depends on HAS_DMA
+ select CRYPTO_ENGINE
+ select CRYPTO_HMAC
diff --git a/target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch b/target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch
new file mode 100644
index 0000000000..5e353e35ad
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch
@@ -0,0 +1,200 @@
+From 68a1bbb99455fd5ea80b7e21ec726f369abc9572 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Wed, 15 Nov 2023 01:12:14 +0800
+Subject: [PATCH 010/116] crypto: starfive - RSA poll csr for done status
+
+Hardware could not clear irq status without resetting the entire module.
+Driver receives irq immediately when mask bit is cleared causing
+intermittent errors in RSA calculations. Switch to use csr polling for
+done status instead.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-cryp.c | 8 -----
+ drivers/crypto/starfive/jh7110-cryp.h | 10 +++++-
+ drivers/crypto/starfive/jh7110-rsa.c | 49 +++++++--------------------
+ 3 files changed, 22 insertions(+), 45 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-cryp.c
++++ b/drivers/crypto/starfive/jh7110-cryp.c
+@@ -109,12 +109,6 @@ static irqreturn_t starfive_cryp_irq(int
+ tasklet_schedule(&cryp->hash_done);
+ }
+
+- if (status & STARFIVE_IE_FLAG_PKA_DONE) {
+- mask |= STARFIVE_IE_MASK_PKA_DONE;
+- writel(mask, cryp->base + STARFIVE_IE_MASK_OFFSET);
+- complete(&cryp->pka_done);
+- }
+-
+ return IRQ_HANDLED;
+ }
+
+@@ -159,8 +153,6 @@ static int starfive_cryp_probe(struct pl
+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
+ "Error getting hardware reset line\n");
+
+- init_completion(&cryp->pka_done);
+-
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+--- a/drivers/crypto/starfive/jh7110-cryp.h
++++ b/drivers/crypto/starfive/jh7110-cryp.h
+@@ -126,6 +126,15 @@ union starfive_pka_cacr {
+ };
+ };
+
++union starfive_pka_casr {
++ u32 v;
++ struct {
++#define STARFIVE_PKA_DONE BIT(0)
++ u32 done :1;
++ u32 rsvd_0 :31;
++ };
++};
++
+ struct starfive_rsa_key {
+ u8 *n;
+ u8 *e;
+@@ -184,7 +193,6 @@ struct starfive_cryp_dev {
+ struct crypto_engine *engine;
+ struct tasklet_struct aes_done;
+ struct tasklet_struct hash_done;
+- struct completion pka_done;
+ size_t assoclen;
+ size_t total_in;
+ size_t total_out;
+--- a/drivers/crypto/starfive/jh7110-rsa.c
++++ b/drivers/crypto/starfive/jh7110-rsa.c
+@@ -6,13 +6,7 @@
+ */
+
+ #include <linux/crypto.h>
+-#include <linux/delay.h>
+-#include <linux/device.h>
+-#include <linux/dma-direct.h>
+-#include <linux/interrupt.h>
+ #include <linux/iopoll.h>
+-#include <linux/io.h>
+-#include <linux/mod_devicetable.h>
+ #include <crypto/akcipher.h>
+ #include <crypto/algapi.h>
+ #include <crypto/internal/akcipher.h>
+@@ -28,13 +22,13 @@
+ #define STARFIVE_PKA_CAER_OFFSET (STARFIVE_PKA_REGS_OFFSET + 0x108)
+ #define STARFIVE_PKA_CANR_OFFSET (STARFIVE_PKA_REGS_OFFSET + 0x208)
+
+-// R^2 mod N and N0'
++/* R ^ 2 mod N and N0' */
+ #define CRYPTO_CMD_PRE 0x0
+-// A * R mod N ==> A
++/* A * R mod N ==> A */
+ #define CRYPTO_CMD_ARN 0x5
+-// A * E * R mod N ==> A
++/* A * E * R mod N ==> A */
+ #define CRYPTO_CMD_AERN 0x6
+-// A * A * R mod N ==> A
++/* A * A * R mod N ==> A */
+ #define CRYPTO_CMD_AARN 0x7
+
+ #define STARFIVE_RSA_RESET 0x2
+@@ -42,21 +36,10 @@
+ static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx)
+ {
+ struct starfive_cryp_dev *cryp = ctx->cryp;
++ u32 status;
+
+- return wait_for_completion_timeout(&cryp->pka_done,
+- usecs_to_jiffies(100000));
+-}
+-
+-static inline void starfive_pka_irq_mask_clear(struct starfive_cryp_ctx *ctx)
+-{
+- struct starfive_cryp_dev *cryp = ctx->cryp;
+- u32 stat;
+-
+- stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
+- stat &= ~STARFIVE_IE_MASK_PKA_DONE;
+- writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET);
+-
+- reinit_completion(&cryp->pka_done);
++ return readl_relaxed_poll_timeout(cryp->base + STARFIVE_PKA_CASR_OFFSET, status,
++ status & STARFIVE_PKA_DONE, 10, 100000);
+ }
+
+ static void starfive_rsa_free_key(struct starfive_rsa_key *key)
+@@ -113,10 +96,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.not_r2 = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+
+ for (loop = 0; loop <= opsize; loop++)
+@@ -135,10 +117,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+ } else {
+ rctx->csr.pka.v = 0;
+@@ -150,10 +131,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.pre_expf = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+
+ for (loop = 0; loop <= count; loop++)
+@@ -171,10 +151,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+ }
+
+@@ -225,11 +204,10 @@ static int starfive_rsa_cpu_start(struct
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+ ret = -ETIMEDOUT;
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ goto rsa_err;
+
+ if (mlen) {
+@@ -241,10 +219,9 @@ static int starfive_rsa_cpu_start(struct
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ goto rsa_err;
+ }
+ }
diff --git a/target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch b/target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch
new file mode 100644
index 0000000000..268e4055e0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch
@@ -0,0 +1,46 @@
+From eea9f2c55cf944bbd5cdd43eb655416a867846af Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Mon, 20 Nov 2023 11:12:42 +0800
+Subject: [PATCH 011/116] crypto: starfive - Pad adata with zeroes
+
+Aad requires padding with zeroes up to 15 bytes in some cases. This
+patch increases the allocated buffer size for aad and prevents the
+driver accessing uninitialized memory region.
+
+v1->v2: Specify reason for alloc size change in descriptions.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-aes.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-aes.c
++++ b/drivers/crypto/starfive/jh7110-aes.c
+@@ -500,7 +500,7 @@ static int starfive_aes_prepare_req(stru
+ scatterwalk_start(&cryp->out_walk, rctx->out_sg);
+
+ if (cryp->assoclen) {
+- rctx->adata = kzalloc(ALIGN(cryp->assoclen, AES_BLOCK_SIZE), GFP_KERNEL);
++ rctx->adata = kzalloc(cryp->assoclen + AES_BLOCK_SIZE, GFP_KERNEL);
+ if (!rctx->adata)
+ return dev_err_probe(cryp->dev, -ENOMEM,
+ "Failed to alloc memory for adata");
+@@ -569,7 +569,7 @@ static int starfive_aes_aead_do_one_req(
+ struct starfive_cryp_ctx *ctx =
+ crypto_aead_ctx(crypto_aead_reqtfm(req));
+ struct starfive_cryp_dev *cryp = ctx->cryp;
+- struct starfive_cryp_request_ctx *rctx = ctx->rctx;
++ struct starfive_cryp_request_ctx *rctx;
+ u32 block[AES_BLOCK_32];
+ u32 stat;
+ int err;
+@@ -579,6 +579,8 @@ static int starfive_aes_aead_do_one_req(
+ if (err)
+ return err;
+
++ rctx = ctx->rctx;
++
+ if (!cryp->assoclen)
+ goto write_text;
+
diff --git a/target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch b/target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch
new file mode 100644
index 0000000000..102fbabf37
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch
@@ -0,0 +1,125 @@
+From 922b213ad22f93fb2788ce119084622ab3d25bf8 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Thu, 30 Nov 2023 18:12:55 +0800
+Subject: [PATCH 012/116] crypto: starfive - Remove cfb and ofb
+
+Remove the unused CFB/OFB implementation.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-aes.c | 71 +--------------------------
+ drivers/crypto/starfive/jh7110-cryp.h | 2 -
+ 2 files changed, 1 insertion(+), 72 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-aes.c
++++ b/drivers/crypto/starfive/jh7110-aes.c
+@@ -262,12 +262,7 @@ static int starfive_aes_hw_init(struct s
+ rctx->csr.aes.mode = hw_mode;
+ rctx->csr.aes.cmode = !is_encrypt(cryp);
+ rctx->csr.aes.ie = 1;
+-
+- if (hw_mode == STARFIVE_AES_MODE_CFB ||
+- hw_mode == STARFIVE_AES_MODE_OFB)
+- rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_128;
+- else
+- rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_1;
++ rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_1;
+
+ if (cryp->side_chan) {
+ rctx->csr.aes.delay_aes = 1;
+@@ -294,8 +289,6 @@ static int starfive_aes_hw_init(struct s
+ starfive_aes_ccm_init(ctx);
+ starfive_aes_aead_hw_start(ctx, hw_mode);
+ break;
+- case STARFIVE_AES_MODE_OFB:
+- case STARFIVE_AES_MODE_CFB:
+ case STARFIVE_AES_MODE_CBC:
+ case STARFIVE_AES_MODE_CTR:
+ starfive_aes_write_iv(ctx, (void *)cryp->req.sreq->iv);
+@@ -785,26 +778,6 @@ static int starfive_aes_cbc_decrypt(stru
+ return starfive_aes_crypt(req, STARFIVE_AES_MODE_CBC);
+ }
+
+-static int starfive_aes_cfb_encrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB | FLG_ENCRYPT);
+-}
+-
+-static int starfive_aes_cfb_decrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB);
+-}
+-
+-static int starfive_aes_ofb_encrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB | FLG_ENCRYPT);
+-}
+-
+-static int starfive_aes_ofb_decrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB);
+-}
+-
+ static int starfive_aes_ctr_encrypt(struct skcipher_request *req)
+ {
+ return starfive_aes_crypt(req, STARFIVE_AES_MODE_CTR | FLG_ENCRYPT);
+@@ -903,48 +876,6 @@ static struct skcipher_engine_alg skciph
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+- .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 0xf,
+- .cra_module = THIS_MODULE,
+- },
+- .op = {
+- .do_one_request = starfive_aes_do_one_req,
+- },
+-}, {
+- .base.init = starfive_aes_init_tfm,
+- .base.setkey = starfive_aes_setkey,
+- .base.encrypt = starfive_aes_cfb_encrypt,
+- .base.decrypt = starfive_aes_cfb_decrypt,
+- .base.min_keysize = AES_MIN_KEY_SIZE,
+- .base.max_keysize = AES_MAX_KEY_SIZE,
+- .base.ivsize = AES_BLOCK_SIZE,
+- .base.base = {
+- .cra_name = "cfb(aes)",
+- .cra_driver_name = "starfive-cfb-aes",
+- .cra_priority = 200,
+- .cra_flags = CRYPTO_ALG_ASYNC,
+- .cra_blocksize = 1,
+- .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 0xf,
+- .cra_module = THIS_MODULE,
+- },
+- .op = {
+- .do_one_request = starfive_aes_do_one_req,
+- },
+-}, {
+- .base.init = starfive_aes_init_tfm,
+- .base.setkey = starfive_aes_setkey,
+- .base.encrypt = starfive_aes_ofb_encrypt,
+- .base.decrypt = starfive_aes_ofb_decrypt,
+- .base.min_keysize = AES_MIN_KEY_SIZE,
+- .base.max_keysize = AES_MAX_KEY_SIZE,
+- .base.ivsize = AES_BLOCK_SIZE,
+- .base.base = {
+- .cra_name = "ofb(aes)",
+- .cra_driver_name = "starfive-ofb-aes",
+- .cra_priority = 200,
+- .cra_flags = CRYPTO_ALG_ASYNC,
+- .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+ .cra_alignmask = 0xf,
+ .cra_module = THIS_MODULE,
+--- a/drivers/crypto/starfive/jh7110-cryp.h
++++ b/drivers/crypto/starfive/jh7110-cryp.h
+@@ -51,8 +51,6 @@ union starfive_aes_csr {
+ u32 ccm_start :1;
+ #define STARFIVE_AES_MODE_ECB 0x0
+ #define STARFIVE_AES_MODE_CBC 0x1
+-#define STARFIVE_AES_MODE_CFB 0x2
+-#define STARFIVE_AES_MODE_OFB 0x3
+ #define STARFIVE_AES_MODE_CTR 0x4
+ #define STARFIVE_AES_MODE_CCM 0x5
+ #define STARFIVE_AES_MODE_GCM 0x6
diff --git a/target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch b/target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch
new file mode 100644
index 0000000000..2e12cfa09e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch
@@ -0,0 +1,33 @@
+From 0dbdc763f10c5cfa968dffc290a7c060ee740172 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Mon, 4 Dec 2023 11:02:39 +0800
+Subject: [PATCH 013/116] crypto: starfive - Remove unneeded NULL checks
+
+NULL check before kfree_sensitive function is not needed.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202311301702.LxswfETY-lkp@intel.com/
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-rsa.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-rsa.c
++++ b/drivers/crypto/starfive/jh7110-rsa.c
+@@ -44,12 +44,9 @@ static inline int starfive_pka_wait_done
+
+ static void starfive_rsa_free_key(struct starfive_rsa_key *key)
+ {
+- if (key->d)
+- kfree_sensitive(key->d);
+- if (key->e)
+- kfree_sensitive(key->e);
+- if (key->n)
+- kfree_sensitive(key->n);
++ kfree_sensitive(key->d);
++ kfree_sensitive(key->e);
++ kfree_sensitive(key->n);
+ memset(key, 0, sizeof(*key));
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch b/target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch
new file mode 100644
index 0000000000..430571565a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch
@@ -0,0 +1,183 @@
+From 708695ebf1a779de9a1fd2f72f7938afa6c14ada Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:51 +0800
+Subject: [PATCH 014/116] dt-bindings: PCI: Add PLDA XpressRICH PCIe host
+ common properties
+
+Add PLDA XpressRICH PCIe host common properties dt-binding doc.
+PolarFire PCIe host using PLDA IP. Move common properties from Microchip
+PolarFire PCIe host to PLDA files.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Tested-by: John Clark <inindev@gmail.com>
+---
+ .../bindings/pci/microchip,pcie-host.yaml | 55 +-------------
+ .../pci/plda,xpressrich3-axi-common.yaml | 75 +++++++++++++++++++
+ 2 files changed, 76 insertions(+), 54 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
+
+--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
++++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
+@@ -10,21 +10,13 @@ maintainers:
+ - Daire McNamara <daire.mcnamara@microchip.com>
+
+ allOf:
+- - $ref: /schemas/pci/pci-bus.yaml#
++ - $ref: plda,xpressrich3-axi-common.yaml#
+ - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+
+ properties:
+ compatible:
+ const: microchip,pcie-host-1.0 # PolarFire
+
+- reg:
+- maxItems: 2
+-
+- reg-names:
+- items:
+- - const: cfg
+- - const: apb
+-
+ clocks:
+ description:
+ Fabric Interface Controllers, FICs, are the interface between the FPGA
+@@ -52,18 +44,6 @@ properties:
+ items:
+ pattern: '^fic[0-3]$'
+
+- interrupts:
+- minItems: 1
+- items:
+- - description: PCIe host controller
+- - description: builtin MSI controller
+-
+- interrupt-names:
+- minItems: 1
+- items:
+- - const: pcie
+- - const: msi
+-
+ ranges:
+ maxItems: 1
+
+@@ -71,39 +51,6 @@ properties:
+ minItems: 1
+ maxItems: 6
+
+- msi-controller:
+- description: Identifies the node as an MSI controller.
+-
+- msi-parent:
+- description: MSI controller the device is capable of using.
+-
+- interrupt-controller:
+- type: object
+- properties:
+- '#address-cells':
+- const: 0
+-
+- '#interrupt-cells':
+- const: 1
+-
+- interrupt-controller: true
+-
+- required:
+- - '#address-cells'
+- - '#interrupt-cells'
+- - interrupt-controller
+-
+- additionalProperties: false
+-
+-required:
+- - reg
+- - reg-names
+- - "#interrupt-cells"
+- - interrupts
+- - interrupt-map-mask
+- - interrupt-map
+- - msi-controller
+-
+ unevaluatedProperties: false
+
+ examples:
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
+@@ -0,0 +1,75 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pci/plda,xpressrich3-axi-common.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: PLDA XpressRICH PCIe host common properties
++
++maintainers:
++ - Daire McNamara <daire.mcnamara@microchip.com>
++ - Kevin Xie <kevin.xie@starfivetech.com>
++
++description:
++ Generic PLDA XpressRICH PCIe host common properties.
++
++allOf:
++ - $ref: /schemas/pci/pci-bus.yaml#
++
++properties:
++ reg:
++ maxItems: 2
++
++ reg-names:
++ items:
++ - const: cfg
++ - const: apb
++
++ interrupts:
++ minItems: 1
++ items:
++ - description: PCIe host controller
++ - description: builtin MSI controller
++
++ interrupt-names:
++ minItems: 1
++ items:
++ - const: pcie
++ - const: msi
++
++ msi-controller:
++ description: Identifies the node as an MSI controller.
++
++ msi-parent:
++ description: MSI controller the device is capable of using.
++
++ interrupt-controller:
++ type: object
++ properties:
++ '#address-cells':
++ const: 0
++
++ '#interrupt-cells':
++ const: 1
++
++ interrupt-controller: true
++
++ required:
++ - '#address-cells'
++ - '#interrupt-cells'
++ - interrupt-controller
++
++ additionalProperties: false
++
++required:
++ - reg
++ - reg-names
++ - interrupts
++ - msi-controller
++ - "#interrupt-cells"
++ - interrupt-map-mask
++ - interrupt-map
++
++additionalProperties: true
++
++...
diff --git a/target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch b/target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch
new file mode 100644
index 0000000000..9e7717fa5d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch
@@ -0,0 +1,2523 @@
+From df67154aa92efdc774a8536ece6f431e7850aca2 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:52 +0800
+Subject: [PATCH 015/116] PCI: microchip: Move pcie-microchip-host.c to plda
+ directory
+
+For Microchip Polarfire PCIe host is PLDA XpressRich IP, move to plda
+directory. Prepare for refactoring the codes.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/Kconfig | 9 +--------
+ drivers/pci/controller/Makefile | 2 +-
+ drivers/pci/controller/plda/Kconfig | 14 ++++++++++++++
+ drivers/pci/controller/plda/Makefile | 2 ++
+ .../controller/{ => plda}/pcie-microchip-host.c | 2 +-
+ 5 files changed, 19 insertions(+), 10 deletions(-)
+ create mode 100644 drivers/pci/controller/plda/Kconfig
+ create mode 100644 drivers/pci/controller/plda/Makefile
+ rename drivers/pci/controller/{ => plda}/pcie-microchip-host.c (99%)
+
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -215,14 +215,6 @@ config PCIE_MT7621
+ help
+ This selects a driver for the MediaTek MT7621 PCIe Controller.
+
+-config PCIE_MICROCHIP_HOST
+- tristate "Microchip AXI PCIe controller"
+- depends on PCI_MSI && OF
+- select PCI_HOST_COMMON
+- help
+- Say Y here if you want kernel to support the Microchip AXI PCIe
+- Host Bridge driver.
+-
+ config PCI_HYPERV_INTERFACE
+ tristate "Microsoft Hyper-V PCI Interface"
+ depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI
+@@ -345,4 +337,5 @@ config PCIE_XILINX_CPM
+ source "drivers/pci/controller/cadence/Kconfig"
+ source "drivers/pci/controller/dwc/Kconfig"
+ source "drivers/pci/controller/mobiveil/Kconfig"
++source "drivers/pci/controller/plda/Kconfig"
+ endmenu
+--- a/drivers/pci/controller/Makefile
++++ b/drivers/pci/controller/Makefile
+@@ -32,7 +32,6 @@ obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-r
+ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
+ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
+ obj-$(CONFIG_PCIE_MEDIATEK_GEN3) += pcie-mediatek-gen3.o
+-obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+ obj-$(CONFIG_VMD) += vmd.o
+ obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+ obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+@@ -43,6 +42,7 @@ obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621
+ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
+ obj-y += dwc/
+ obj-y += mobiveil/
++obj-y += plda/
+
+
+ # The following drivers are for devices that use the generic ACPI
+--- /dev/null
++++ b/drivers/pci/controller/plda/Kconfig
+@@ -0,0 +1,14 @@
++# SPDX-License-Identifier: GPL-2.0
++
++menu "PLDA-based PCIe controllers"
++ depends on PCI
++
++config PCIE_MICROCHIP_HOST
++ tristate "Microchip AXI PCIe controller"
++ depends on PCI_MSI && OF
++ select PCI_HOST_COMMON
++ help
++ Say Y here if you want kernel to support the Microchip AXI PCIe
++ Host Bridge driver.
++
++endmenu
+--- /dev/null
++++ b/drivers/pci/controller/plda/Makefile
+@@ -0,0 +1,2 @@
++# SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+--- a/drivers/pci/controller/pcie-microchip-host.c
++++ /dev/null
+@@ -1,1216 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/*
+- * Microchip AXI PCIe Bridge host controller driver
+- *
+- * Copyright (c) 2018 - 2020 Microchip Corporation. All rights reserved.
+- *
+- * Author: Daire McNamara <daire.mcnamara@microchip.com>
+- */
+-
+-#include <linux/bitfield.h>
+-#include <linux/clk.h>
+-#include <linux/irqchip/chained_irq.h>
+-#include <linux/irqdomain.h>
+-#include <linux/module.h>
+-#include <linux/msi.h>
+-#include <linux/of_address.h>
+-#include <linux/of_pci.h>
+-#include <linux/pci-ecam.h>
+-#include <linux/platform_device.h>
+-
+-#include "../pci.h"
+-
+-/* Number of MSI IRQs */
+-#define MC_MAX_NUM_MSI_IRQS 32
+-
+-/* PCIe Bridge Phy and Controller Phy offsets */
+-#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
+-#define MC_PCIE1_CTRL_ADDR 0x0000a000u
+-
+-#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
+-#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
+-
+-/* PCIe Bridge Phy Regs */
+-#define PCIE_PCI_IRQ_DW0 0xa8
+-#define MSIX_CAP_MASK BIT(31)
+-#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
+-#define NUM_MSI_MSGS_SHIFT 4
+-
+-#define IMASK_LOCAL 0x180
+-#define DMA_END_ENGINE_0_MASK 0x00000000u
+-#define DMA_END_ENGINE_0_SHIFT 0
+-#define DMA_END_ENGINE_1_MASK 0x00000000u
+-#define DMA_END_ENGINE_1_SHIFT 1
+-#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
+-#define DMA_ERROR_ENGINE_0_SHIFT 8
+-#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
+-#define DMA_ERROR_ENGINE_1_SHIFT 9
+-#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
+-#define A_ATR_EVT_POST_ERR_SHIFT 16
+-#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
+-#define A_ATR_EVT_FETCH_ERR_SHIFT 17
+-#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
+-#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
+-#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define A_ATR_EVT_DOORBELL_SHIFT 19
+-#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
+-#define P_ATR_EVT_POST_ERR_SHIFT 20
+-#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
+-#define P_ATR_EVT_FETCH_ERR_SHIFT 21
+-#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
+-#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
+-#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define P_ATR_EVT_DOORBELL_SHIFT 23
+-#define PM_MSI_INT_INTA_MASK 0x01000000u
+-#define PM_MSI_INT_INTA_SHIFT 24
+-#define PM_MSI_INT_INTB_MASK 0x02000000u
+-#define PM_MSI_INT_INTB_SHIFT 25
+-#define PM_MSI_INT_INTC_MASK 0x04000000u
+-#define PM_MSI_INT_INTC_SHIFT 26
+-#define PM_MSI_INT_INTD_MASK 0x08000000u
+-#define PM_MSI_INT_INTD_SHIFT 27
+-#define PM_MSI_INT_INTX_MASK 0x0f000000u
+-#define PM_MSI_INT_INTX_SHIFT 24
+-#define PM_MSI_INT_MSI_MASK 0x10000000u
+-#define PM_MSI_INT_MSI_SHIFT 28
+-#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
+-#define PM_MSI_INT_AER_EVT_SHIFT 29
+-#define PM_MSI_INT_EVENTS_MASK 0x40000000u
+-#define PM_MSI_INT_EVENTS_SHIFT 30
+-#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
+-#define PM_MSI_INT_SYS_ERR_SHIFT 31
+-#define NUM_LOCAL_EVENTS 15
+-#define ISTATUS_LOCAL 0x184
+-#define IMASK_HOST 0x188
+-#define ISTATUS_HOST 0x18c
+-#define IMSI_ADDR 0x190
+-#define ISTATUS_MSI 0x194
+-
+-/* PCIe Master table init defines */
+-#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+-#define ATR0_PCIE_ATR_SIZE 0x25
+-#define ATR0_PCIE_ATR_SIZE_SHIFT 1
+-#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
+-#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
+-
+-/* PCIe AXI slave table init defines */
+-#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
+-#define ATR_SIZE_SHIFT 1
+-#define ATR_IMPL_ENABLE 1
+-#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
+-#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
+-#define PCIE_TX_RX_INTERFACE 0x00000000u
+-#define PCIE_CONFIG_INTERFACE 0x00000001u
+-
+-#define ATR_ENTRY_SIZE 32
+-
+-/* PCIe Controller Phy Regs */
+-#define SEC_ERROR_EVENT_CNT 0x20
+-#define DED_ERROR_EVENT_CNT 0x24
+-#define SEC_ERROR_INT 0x28
+-#define SEC_ERROR_INT_TX_RAM_SEC_ERR_INT GENMASK(3, 0)
+-#define SEC_ERROR_INT_RX_RAM_SEC_ERR_INT GENMASK(7, 4)
+-#define SEC_ERROR_INT_PCIE2AXI_RAM_SEC_ERR_INT GENMASK(11, 8)
+-#define SEC_ERROR_INT_AXI2PCIE_RAM_SEC_ERR_INT GENMASK(15, 12)
+-#define SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT GENMASK(15, 0)
+-#define NUM_SEC_ERROR_INTS (4)
+-#define SEC_ERROR_INT_MASK 0x2c
+-#define DED_ERROR_INT 0x30
+-#define DED_ERROR_INT_TX_RAM_DED_ERR_INT GENMASK(3, 0)
+-#define DED_ERROR_INT_RX_RAM_DED_ERR_INT GENMASK(7, 4)
+-#define DED_ERROR_INT_PCIE2AXI_RAM_DED_ERR_INT GENMASK(11, 8)
+-#define DED_ERROR_INT_AXI2PCIE_RAM_DED_ERR_INT GENMASK(15, 12)
+-#define DED_ERROR_INT_ALL_RAM_DED_ERR_INT GENMASK(15, 0)
+-#define NUM_DED_ERROR_INTS (4)
+-#define DED_ERROR_INT_MASK 0x34
+-#define ECC_CONTROL 0x38
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_0 BIT(0)
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_1 BIT(1)
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_2 BIT(2)
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_3 BIT(3)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_0 BIT(4)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_1 BIT(5)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_2 BIT(6)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_3 BIT(7)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_0 BIT(8)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_1 BIT(9)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_2 BIT(10)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_3 BIT(11)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_0 BIT(12)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_1 BIT(13)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_2 BIT(14)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_3 BIT(15)
+-#define ECC_CONTROL_TX_RAM_ECC_BYPASS BIT(24)
+-#define ECC_CONTROL_RX_RAM_ECC_BYPASS BIT(25)
+-#define ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS BIT(26)
+-#define ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS BIT(27)
+-#define PCIE_EVENT_INT 0x14c
+-#define PCIE_EVENT_INT_L2_EXIT_INT BIT(0)
+-#define PCIE_EVENT_INT_HOTRST_EXIT_INT BIT(1)
+-#define PCIE_EVENT_INT_DLUP_EXIT_INT BIT(2)
+-#define PCIE_EVENT_INT_MASK GENMASK(2, 0)
+-#define PCIE_EVENT_INT_L2_EXIT_INT_MASK BIT(16)
+-#define PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK BIT(17)
+-#define PCIE_EVENT_INT_DLUP_EXIT_INT_MASK BIT(18)
+-#define PCIE_EVENT_INT_ENB_MASK GENMASK(18, 16)
+-#define PCIE_EVENT_INT_ENB_SHIFT 16
+-#define NUM_PCIE_EVENTS (3)
+-
+-/* PCIe Config space MSI capability structure */
+-#define MC_MSI_CAP_CTRL_OFFSET 0xe0u
+-
+-/* Events */
+-#define EVENT_PCIE_L2_EXIT 0
+-#define EVENT_PCIE_HOTRST_EXIT 1
+-#define EVENT_PCIE_DLUP_EXIT 2
+-#define EVENT_SEC_TX_RAM_SEC_ERR 3
+-#define EVENT_SEC_RX_RAM_SEC_ERR 4
+-#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 5
+-#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 6
+-#define EVENT_DED_TX_RAM_DED_ERR 7
+-#define EVENT_DED_RX_RAM_DED_ERR 8
+-#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 9
+-#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 10
+-#define EVENT_LOCAL_DMA_END_ENGINE_0 11
+-#define EVENT_LOCAL_DMA_END_ENGINE_1 12
+-#define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
+-#define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
+-#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
+-#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
+-#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
+-#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
+-#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
+-#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
+-#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
+-#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
+-#define EVENT_LOCAL_PM_MSI_INT_INTX 23
+-#define EVENT_LOCAL_PM_MSI_INT_MSI 24
+-#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
+-#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
+-#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
+-#define NUM_EVENTS 28
+-
+-#define PCIE_EVENT_CAUSE(x, s) \
+- [EVENT_PCIE_ ## x] = { __stringify(x), s }
+-
+-#define SEC_ERROR_CAUSE(x, s) \
+- [EVENT_SEC_ ## x] = { __stringify(x), s }
+-
+-#define DED_ERROR_CAUSE(x, s) \
+- [EVENT_DED_ ## x] = { __stringify(x), s }
+-
+-#define LOCAL_EVENT_CAUSE(x, s) \
+- [EVENT_LOCAL_ ## x] = { __stringify(x), s }
+-
+-#define PCIE_EVENT(x) \
+- .base = MC_PCIE_CTRL_ADDR, \
+- .offset = PCIE_EVENT_INT, \
+- .mask_offset = PCIE_EVENT_INT, \
+- .mask_high = 1, \
+- .mask = PCIE_EVENT_INT_ ## x ## _INT, \
+- .enb_mask = PCIE_EVENT_INT_ENB_MASK
+-
+-#define SEC_EVENT(x) \
+- .base = MC_PCIE_CTRL_ADDR, \
+- .offset = SEC_ERROR_INT, \
+- .mask_offset = SEC_ERROR_INT_MASK, \
+- .mask = SEC_ERROR_INT_ ## x ## _INT, \
+- .mask_high = 1, \
+- .enb_mask = 0
+-
+-#define DED_EVENT(x) \
+- .base = MC_PCIE_CTRL_ADDR, \
+- .offset = DED_ERROR_INT, \
+- .mask_offset = DED_ERROR_INT_MASK, \
+- .mask_high = 1, \
+- .mask = DED_ERROR_INT_ ## x ## _INT, \
+- .enb_mask = 0
+-
+-#define LOCAL_EVENT(x) \
+- .base = MC_PCIE_BRIDGE_ADDR, \
+- .offset = ISTATUS_LOCAL, \
+- .mask_offset = IMASK_LOCAL, \
+- .mask_high = 0, \
+- .mask = x ## _MASK, \
+- .enb_mask = 0
+-
+-#define PCIE_EVENT_TO_EVENT_MAP(x) \
+- { PCIE_EVENT_INT_ ## x ## _INT, EVENT_PCIE_ ## x }
+-
+-#define SEC_ERROR_TO_EVENT_MAP(x) \
+- { SEC_ERROR_INT_ ## x ## _INT, EVENT_SEC_ ## x }
+-
+-#define DED_ERROR_TO_EVENT_MAP(x) \
+- { DED_ERROR_INT_ ## x ## _INT, EVENT_DED_ ## x }
+-
+-#define LOCAL_STATUS_TO_EVENT_MAP(x) \
+- { x ## _MASK, EVENT_LOCAL_ ## x }
+-
+-struct event_map {
+- u32 reg_mask;
+- u32 event_bit;
+-};
+-
+-struct mc_msi {
+- struct mutex lock; /* Protect used bitmap */
+- struct irq_domain *msi_domain;
+- struct irq_domain *dev_domain;
+- u32 num_vectors;
+- u64 vector_phy;
+- DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
+-};
+-
+-struct mc_pcie {
+- void __iomem *axi_base_addr;
+- struct device *dev;
+- struct irq_domain *intx_domain;
+- struct irq_domain *event_domain;
+- raw_spinlock_t lock;
+- struct mc_msi msi;
+-};
+-
+-struct cause {
+- const char *sym;
+- const char *str;
+-};
+-
+-static const struct cause event_cause[NUM_EVENTS] = {
+- PCIE_EVENT_CAUSE(L2_EXIT, "L2 exit event"),
+- PCIE_EVENT_CAUSE(HOTRST_EXIT, "Hot reset exit event"),
+- PCIE_EVENT_CAUSE(DLUP_EXIT, "DLUP exit event"),
+- SEC_ERROR_CAUSE(TX_RAM_SEC_ERR, "sec error in tx buffer"),
+- SEC_ERROR_CAUSE(RX_RAM_SEC_ERR, "sec error in rx buffer"),
+- SEC_ERROR_CAUSE(PCIE2AXI_RAM_SEC_ERR, "sec error in pcie2axi buffer"),
+- SEC_ERROR_CAUSE(AXI2PCIE_RAM_SEC_ERR, "sec error in axi2pcie buffer"),
+- DED_ERROR_CAUSE(TX_RAM_DED_ERR, "ded error in tx buffer"),
+- DED_ERROR_CAUSE(RX_RAM_DED_ERR, "ded error in rx buffer"),
+- DED_ERROR_CAUSE(PCIE2AXI_RAM_DED_ERR, "ded error in pcie2axi buffer"),
+- DED_ERROR_CAUSE(AXI2PCIE_RAM_DED_ERR, "ded error in axi2pcie buffer"),
+- LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_0, "dma engine 0 error"),
+- LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_1, "dma engine 1 error"),
+- LOCAL_EVENT_CAUSE(A_ATR_EVT_POST_ERR, "axi write request error"),
+- LOCAL_EVENT_CAUSE(A_ATR_EVT_FETCH_ERR, "axi read request error"),
+- LOCAL_EVENT_CAUSE(A_ATR_EVT_DISCARD_ERR, "axi read timeout"),
+- LOCAL_EVENT_CAUSE(P_ATR_EVT_POST_ERR, "pcie write request error"),
+- LOCAL_EVENT_CAUSE(P_ATR_EVT_FETCH_ERR, "pcie read request error"),
+- LOCAL_EVENT_CAUSE(P_ATR_EVT_DISCARD_ERR, "pcie read timeout"),
+- LOCAL_EVENT_CAUSE(PM_MSI_INT_AER_EVT, "aer event"),
+- LOCAL_EVENT_CAUSE(PM_MSI_INT_EVENTS, "pm/ltr/hotplug event"),
+- LOCAL_EVENT_CAUSE(PM_MSI_INT_SYS_ERR, "system error"),
+-};
+-
+-static struct event_map pcie_event_to_event[] = {
+- PCIE_EVENT_TO_EVENT_MAP(L2_EXIT),
+- PCIE_EVENT_TO_EVENT_MAP(HOTRST_EXIT),
+- PCIE_EVENT_TO_EVENT_MAP(DLUP_EXIT),
+-};
+-
+-static struct event_map sec_error_to_event[] = {
+- SEC_ERROR_TO_EVENT_MAP(TX_RAM_SEC_ERR),
+- SEC_ERROR_TO_EVENT_MAP(RX_RAM_SEC_ERR),
+- SEC_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_SEC_ERR),
+- SEC_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_SEC_ERR),
+-};
+-
+-static struct event_map ded_error_to_event[] = {
+- DED_ERROR_TO_EVENT_MAP(TX_RAM_DED_ERR),
+- DED_ERROR_TO_EVENT_MAP(RX_RAM_DED_ERR),
+- DED_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_DED_ERR),
+- DED_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_DED_ERR),
+-};
+-
+-static struct event_map local_status_to_event[] = {
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_0),
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_1),
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_0),
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_1),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_POST_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_FETCH_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DISCARD_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DOORBELL),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_POST_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_FETCH_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DISCARD_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DOORBELL),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_INTX),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_MSI),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_AER_EVT),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_EVENTS),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_SYS_ERR),
+-};
+-
+-static struct {
+- u32 base;
+- u32 offset;
+- u32 mask;
+- u32 shift;
+- u32 enb_mask;
+- u32 mask_high;
+- u32 mask_offset;
+-} event_descs[] = {
+- { PCIE_EVENT(L2_EXIT) },
+- { PCIE_EVENT(HOTRST_EXIT) },
+- { PCIE_EVENT(DLUP_EXIT) },
+- { SEC_EVENT(TX_RAM_SEC_ERR) },
+- { SEC_EVENT(RX_RAM_SEC_ERR) },
+- { SEC_EVENT(PCIE2AXI_RAM_SEC_ERR) },
+- { SEC_EVENT(AXI2PCIE_RAM_SEC_ERR) },
+- { DED_EVENT(TX_RAM_DED_ERR) },
+- { DED_EVENT(RX_RAM_DED_ERR) },
+- { DED_EVENT(PCIE2AXI_RAM_DED_ERR) },
+- { DED_EVENT(AXI2PCIE_RAM_DED_ERR) },
+- { LOCAL_EVENT(DMA_END_ENGINE_0) },
+- { LOCAL_EVENT(DMA_END_ENGINE_1) },
+- { LOCAL_EVENT(DMA_ERROR_ENGINE_0) },
+- { LOCAL_EVENT(DMA_ERROR_ENGINE_1) },
+- { LOCAL_EVENT(A_ATR_EVT_POST_ERR) },
+- { LOCAL_EVENT(A_ATR_EVT_FETCH_ERR) },
+- { LOCAL_EVENT(A_ATR_EVT_DISCARD_ERR) },
+- { LOCAL_EVENT(A_ATR_EVT_DOORBELL) },
+- { LOCAL_EVENT(P_ATR_EVT_POST_ERR) },
+- { LOCAL_EVENT(P_ATR_EVT_FETCH_ERR) },
+- { LOCAL_EVENT(P_ATR_EVT_DISCARD_ERR) },
+- { LOCAL_EVENT(P_ATR_EVT_DOORBELL) },
+- { LOCAL_EVENT(PM_MSI_INT_INTX) },
+- { LOCAL_EVENT(PM_MSI_INT_MSI) },
+- { LOCAL_EVENT(PM_MSI_INT_AER_EVT) },
+- { LOCAL_EVENT(PM_MSI_INT_EVENTS) },
+- { LOCAL_EVENT(PM_MSI_INT_SYS_ERR) },
+-};
+-
+-static char poss_clks[][5] = { "fic0", "fic1", "fic2", "fic3" };
+-
+-static struct mc_pcie *port;
+-
+-static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
+-{
+- struct mc_msi *msi = &port->msi;
+- u16 reg;
+- u8 queue_size;
+-
+- /* Fixup MSI enable flag */
+- reg = readw_relaxed(ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
+- reg |= PCI_MSI_FLAGS_ENABLE;
+- writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
+-
+- /* Fixup PCI MSI queue flags */
+- queue_size = FIELD_GET(PCI_MSI_FLAGS_QMASK, reg);
+- reg |= FIELD_PREP(PCI_MSI_FLAGS_QSIZE, queue_size);
+- writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
+-
+- /* Fixup MSI addr fields */
+- writel_relaxed(lower_32_bits(msi->vector_phy),
+- ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_LO);
+- writel_relaxed(upper_32_bits(msi->vector_phy),
+- ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
+-}
+-
+-static void mc_handle_msi(struct irq_desc *desc)
+-{
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- struct mc_msi *msi = &port->msi;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_MSI_MASK) {
+- writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
+- status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
+- for_each_set_bit(bit, &status, msi->num_vectors) {
+- ret = generic_handle_domain_irq(msi->dev_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void mc_msi_bottom_irq_ack(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- u32 bitpos = data->hwirq;
+-
+- writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+-}
+-
+-static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- phys_addr_t addr = port->msi.vector_phy;
+-
+- msg->address_lo = lower_32_bits(addr);
+- msg->address_hi = upper_32_bits(addr);
+- msg->data = data->hwirq;
+-
+- dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
+- (int)data->hwirq, msg->address_hi, msg->address_lo);
+-}
+-
+-static int mc_msi_set_affinity(struct irq_data *irq_data,
+- const struct cpumask *mask, bool force)
+-{
+- return -EINVAL;
+-}
+-
+-static struct irq_chip mc_msi_bottom_irq_chip = {
+- .name = "Microchip MSI",
+- .irq_ack = mc_msi_bottom_irq_ack,
+- .irq_compose_msi_msg = mc_compose_msi_msg,
+- .irq_set_affinity = mc_msi_set_affinity,
+-};
+-
+-static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs, void *args)
+-{
+- struct mc_pcie *port = domain->host_data;
+- struct mc_msi *msi = &port->msi;
+- unsigned long bit;
+-
+- mutex_lock(&msi->lock);
+- bit = find_first_zero_bit(msi->used, msi->num_vectors);
+- if (bit >= msi->num_vectors) {
+- mutex_unlock(&msi->lock);
+- return -ENOSPC;
+- }
+-
+- set_bit(bit, msi->used);
+-
+- irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
+- domain->host_data, handle_edge_irq, NULL, NULL);
+-
+- mutex_unlock(&msi->lock);
+-
+- return 0;
+-}
+-
+-static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs)
+-{
+- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+- struct mc_pcie *port = irq_data_get_irq_chip_data(d);
+- struct mc_msi *msi = &port->msi;
+-
+- mutex_lock(&msi->lock);
+-
+- if (test_bit(d->hwirq, msi->used))
+- __clear_bit(d->hwirq, msi->used);
+- else
+- dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
+-
+- mutex_unlock(&msi->lock);
+-}
+-
+-static const struct irq_domain_ops msi_domain_ops = {
+- .alloc = mc_irq_msi_domain_alloc,
+- .free = mc_irq_msi_domain_free,
+-};
+-
+-static struct irq_chip mc_msi_irq_chip = {
+- .name = "Microchip PCIe MSI",
+- .irq_ack = irq_chip_ack_parent,
+- .irq_mask = pci_msi_mask_irq,
+- .irq_unmask = pci_msi_unmask_irq,
+-};
+-
+-static struct msi_domain_info mc_msi_domain_info = {
+- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+- MSI_FLAG_PCI_MSIX),
+- .chip = &mc_msi_irq_chip,
+-};
+-
+-static int mc_allocate_msi_domains(struct mc_pcie *port)
+-{
+- struct device *dev = port->dev;
+- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+- struct mc_msi *msi = &port->msi;
+-
+- mutex_init(&port->msi.lock);
+-
+- msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
+- &msi_domain_ops, port);
+- if (!msi->dev_domain) {
+- dev_err(dev, "failed to create IRQ domain\n");
+- return -ENOMEM;
+- }
+-
+- msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
+- msi->dev_domain);
+- if (!msi->msi_domain) {
+- dev_err(dev, "failed to create MSI domain\n");
+- irq_domain_remove(msi->dev_domain);
+- return -ENOMEM;
+- }
+-
+- return 0;
+-}
+-
+-static void mc_handle_intx(struct irq_desc *desc)
+-{
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_INTX_MASK) {
+- status &= PM_MSI_INT_INTX_MASK;
+- status >>= PM_MSI_INT_INTX_SHIFT;
+- for_each_set_bit(bit, &status, PCI_NUM_INTX) {
+- ret = generic_handle_domain_irq(port->intx_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void mc_ack_intx_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+-
+- writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+-}
+-
+-static void mc_mask_intx_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val &= ~mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static void mc_unmask_intx_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val |= mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static struct irq_chip mc_intx_irq_chip = {
+- .name = "Microchip PCIe INTx",
+- .irq_ack = mc_ack_intx_irq,
+- .irq_mask = mc_mask_intx_irq,
+- .irq_unmask = mc_unmask_intx_irq,
+-};
+-
+-static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops intx_domain_ops = {
+- .map = mc_pcie_intx_map,
+-};
+-
+-static inline u32 reg_to_event(u32 reg, struct event_map field)
+-{
+- return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
+-}
+-
+-static u32 pcie_events(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 reg = readl_relaxed(ctrl_base_addr + PCIE_EVENT_INT);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(pcie_event_to_event); i++)
+- val |= reg_to_event(reg, pcie_event_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 sec_errors(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 reg = readl_relaxed(ctrl_base_addr + SEC_ERROR_INT);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(sec_error_to_event); i++)
+- val |= reg_to_event(reg, sec_error_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 ded_errors(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 reg = readl_relaxed(ctrl_base_addr + DED_ERROR_INT);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(ded_error_to_event); i++)
+- val |= reg_to_event(reg, ded_error_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 local_events(struct mc_pcie *port)
+-{
+- void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- u32 reg = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(local_status_to_event); i++)
+- val |= reg_to_event(reg, local_status_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 get_events(struct mc_pcie *port)
+-{
+- u32 events = 0;
+-
+- events |= pcie_events(port);
+- events |= sec_errors(port);
+- events |= ded_errors(port);
+- events |= local_events(port);
+-
+- return events;
+-}
+-
+-static irqreturn_t mc_event_handler(int irq, void *dev_id)
+-{
+- struct mc_pcie *port = dev_id;
+- struct device *dev = port->dev;
+- struct irq_data *data;
+-
+- data = irq_domain_get_irq_data(port->event_domain, irq);
+-
+- if (event_cause[data->hwirq].str)
+- dev_err_ratelimited(dev, "%s\n", event_cause[data->hwirq].str);
+- else
+- dev_err_ratelimited(dev, "bad event IRQ %ld\n", data->hwirq);
+-
+- return IRQ_HANDLED;
+-}
+-
+-static void mc_handle_event(struct irq_desc *desc)
+-{
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
+- unsigned long events;
+- u32 bit;
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+-
+- chained_irq_enter(chip, desc);
+-
+- events = get_events(port);
+-
+- for_each_set_bit(bit, &events, NUM_EVENTS)
+- generic_handle_domain_irq(port->event_domain, bit);
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void mc_ack_event_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- u32 event = data->hwirq;
+- void __iomem *addr;
+- u32 mask;
+-
+- addr = port->axi_base_addr + event_descs[event].base +
+- event_descs[event].offset;
+- mask = event_descs[event].mask;
+- mask |= event_descs[event].enb_mask;
+-
+- writel_relaxed(mask, addr);
+-}
+-
+-static void mc_mask_event_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- u32 event = data->hwirq;
+- void __iomem *addr;
+- u32 mask;
+- u32 val;
+-
+- addr = port->axi_base_addr + event_descs[event].base +
+- event_descs[event].mask_offset;
+- mask = event_descs[event].mask;
+- if (event_descs[event].enb_mask) {
+- mask <<= PCIE_EVENT_INT_ENB_SHIFT;
+- mask &= PCIE_EVENT_INT_ENB_MASK;
+- }
+-
+- if (!event_descs[event].mask_high)
+- mask = ~mask;
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(addr);
+- if (event_descs[event].mask_high)
+- val |= mask;
+- else
+- val &= mask;
+-
+- writel_relaxed(val, addr);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static void mc_unmask_event_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- u32 event = data->hwirq;
+- void __iomem *addr;
+- u32 mask;
+- u32 val;
+-
+- addr = port->axi_base_addr + event_descs[event].base +
+- event_descs[event].mask_offset;
+- mask = event_descs[event].mask;
+-
+- if (event_descs[event].enb_mask)
+- mask <<= PCIE_EVENT_INT_ENB_SHIFT;
+-
+- if (event_descs[event].mask_high)
+- mask = ~mask;
+-
+- if (event_descs[event].enb_mask)
+- mask &= PCIE_EVENT_INT_ENB_MASK;
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(addr);
+- if (event_descs[event].mask_high)
+- val &= mask;
+- else
+- val |= mask;
+- writel_relaxed(val, addr);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static struct irq_chip mc_event_irq_chip = {
+- .name = "Microchip PCIe EVENT",
+- .irq_ack = mc_ack_event_irq,
+- .irq_mask = mc_mask_event_irq,
+- .irq_unmask = mc_unmask_event_irq,
+-};
+-
+-static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops event_domain_ops = {
+- .map = mc_pcie_event_map,
+-};
+-
+-static inline void mc_pcie_deinit_clk(void *data)
+-{
+- struct clk *clk = data;
+-
+- clk_disable_unprepare(clk);
+-}
+-
+-static inline struct clk *mc_pcie_init_clk(struct device *dev, const char *id)
+-{
+- struct clk *clk;
+- int ret;
+-
+- clk = devm_clk_get_optional(dev, id);
+- if (IS_ERR(clk))
+- return clk;
+- if (!clk)
+- return clk;
+-
+- ret = clk_prepare_enable(clk);
+- if (ret)
+- return ERR_PTR(ret);
+-
+- devm_add_action_or_reset(dev, mc_pcie_deinit_clk, clk);
+-
+- return clk;
+-}
+-
+-static int mc_pcie_init_clks(struct device *dev)
+-{
+- int i;
+- struct clk *fic;
+-
+- /*
+- * PCIe may be clocked via Fabric Interface using between 1 and 4
+- * clocks. Scan DT for clocks and enable them if present
+- */
+- for (i = 0; i < ARRAY_SIZE(poss_clks); i++) {
+- fic = mc_pcie_init_clk(dev, poss_clks[i]);
+- if (IS_ERR(fic))
+- return PTR_ERR(fic);
+- }
+-
+- return 0;
+-}
+-
+-static int mc_pcie_init_irq_domains(struct mc_pcie *port)
+-{
+- struct device *dev = port->dev;
+- struct device_node *node = dev->of_node;
+- struct device_node *pcie_intc_node;
+-
+- /* Setup INTx */
+- pcie_intc_node = of_get_next_child(node, NULL);
+- if (!pcie_intc_node) {
+- dev_err(dev, "failed to find PCIe Intc node\n");
+- return -EINVAL;
+- }
+-
+- port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
+- &event_domain_ops, port);
+- if (!port->event_domain) {
+- dev_err(dev, "failed to get event domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
+-
+- port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
+- &intx_domain_ops, port);
+- if (!port->intx_domain) {
+- dev_err(dev, "failed to get an INTx IRQ domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
+-
+- of_node_put(pcie_intc_node);
+- raw_spin_lock_init(&port->lock);
+-
+- return mc_allocate_msi_domains(port);
+-}
+-
+-static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+- phys_addr_t axi_addr, phys_addr_t pci_addr,
+- size_t size)
+-{
+- u32 atr_sz = ilog2(size) - 1;
+- u32 val;
+-
+- if (index == 0)
+- val = PCIE_CONFIG_INTERFACE;
+- else
+- val = PCIE_TX_RX_INTERFACE;
+-
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_PARAM);
+-
+- val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
+- ATR_IMPL_ENABLE;
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRCADDR_PARAM);
+-
+- val = upper_32_bits(axi_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRC_ADDR);
+-
+- val = lower_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
+-
+- val = upper_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
+-
+- val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
+- writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+-}
+-
+-static int mc_pcie_setup_windows(struct platform_device *pdev,
+- struct mc_pcie *port)
+-{
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+- struct resource_entry *entry;
+- u64 pci_addr;
+- u32 index = 1;
+-
+- resource_list_for_each_entry(entry, &bridge->windows) {
+- if (resource_type(entry->res) == IORESOURCE_MEM) {
+- pci_addr = entry->res->start - entry->offset;
+- mc_pcie_setup_window(bridge_base_addr, index,
+- entry->res->start, pci_addr,
+- resource_size(entry->res));
+- index++;
+- }
+- }
+-
+- return 0;
+-}
+-
+-static inline void mc_clear_secs(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+-
+- writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
+- SEC_ERROR_INT);
+- writel_relaxed(0, ctrl_base_addr + SEC_ERROR_EVENT_CNT);
+-}
+-
+-static inline void mc_clear_deds(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+-
+- writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
+- DED_ERROR_INT);
+- writel_relaxed(0, ctrl_base_addr + DED_ERROR_EVENT_CNT);
+-}
+-
+-static void mc_disable_interrupts(struct mc_pcie *port)
+-{
+- void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 val;
+-
+- /* Ensure ECC bypass is enabled */
+- val = ECC_CONTROL_TX_RAM_ECC_BYPASS |
+- ECC_CONTROL_RX_RAM_ECC_BYPASS |
+- ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
+- ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS;
+- writel_relaxed(val, ctrl_base_addr + ECC_CONTROL);
+-
+- /* Disable SEC errors and clear any outstanding */
+- writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
+- SEC_ERROR_INT_MASK);
+- mc_clear_secs(port);
+-
+- /* Disable DED errors and clear any outstanding */
+- writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
+- DED_ERROR_INT_MASK);
+- mc_clear_deds(port);
+-
+- /* Disable local interrupts and clear any outstanding */
+- writel_relaxed(0, bridge_base_addr + IMASK_LOCAL);
+- writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_LOCAL);
+- writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_MSI);
+-
+- /* Disable PCIe events and clear any outstanding */
+- val = PCIE_EVENT_INT_L2_EXIT_INT |
+- PCIE_EVENT_INT_HOTRST_EXIT_INT |
+- PCIE_EVENT_INT_DLUP_EXIT_INT |
+- PCIE_EVENT_INT_L2_EXIT_INT_MASK |
+- PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
+- PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
+- writel_relaxed(val, ctrl_base_addr + PCIE_EVENT_INT);
+-
+- /* Disable host interrupts and clear any outstanding */
+- writel_relaxed(0, bridge_base_addr + IMASK_HOST);
+- writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+-}
+-
+-static int mc_init_interrupts(struct platform_device *pdev, struct mc_pcie *port)
+-{
+- struct device *dev = &pdev->dev;
+- int irq;
+- int i, intx_irq, msi_irq, event_irq;
+- int ret;
+-
+- ret = mc_pcie_init_irq_domains(port);
+- if (ret) {
+- dev_err(dev, "failed creating IRQ domains\n");
+- return ret;
+- }
+-
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
+- return -ENODEV;
+-
+- for (i = 0; i < NUM_EVENTS; i++) {
+- event_irq = irq_create_mapping(port->event_domain, i);
+- if (!event_irq) {
+- dev_err(dev, "failed to map hwirq %d\n", i);
+- return -ENXIO;
+- }
+-
+- ret = devm_request_irq(dev, event_irq, mc_event_handler,
+- 0, event_cause[i].sym, port);
+- if (ret) {
+- dev_err(dev, "failed to request IRQ %d\n", event_irq);
+- return ret;
+- }
+- }
+-
+- intx_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_INTX);
+- if (!intx_irq) {
+- dev_err(dev, "failed to map INTx interrupt\n");
+- return -ENXIO;
+- }
+-
+- /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, mc_handle_intx, port);
+-
+- msi_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_MSI);
+- if (!msi_irq)
+- return -ENXIO;
+-
+- /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
+-
+- /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, mc_handle_event, port);
+-
+- return 0;
+-}
+-
+-static int mc_platform_init(struct pci_config_window *cfg)
+-{
+- struct device *dev = cfg->parent;
+- struct platform_device *pdev = to_platform_device(dev);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- int ret;
+-
+- /* Configure address translation table 0 for PCIe config space */
+- mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
+- cfg->res.start,
+- resource_size(&cfg->res));
+-
+- /* Need some fixups in config space */
+- mc_pcie_enable_msi(port, cfg->win);
+-
+- /* Configure non-config space outbound ranges */
+- ret = mc_pcie_setup_windows(pdev, port);
+- if (ret)
+- return ret;
+-
+- /* Address translation is up; safe to enable interrupts */
+- ret = mc_init_interrupts(pdev, port);
+- if (ret)
+- return ret;
+-
+- return 0;
+-}
+-
+-static int mc_host_probe(struct platform_device *pdev)
+-{
+- struct device *dev = &pdev->dev;
+- void __iomem *bridge_base_addr;
+- int ret;
+- u32 val;
+-
+- port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+- if (!port)
+- return -ENOMEM;
+-
+- port->dev = dev;
+-
+- port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
+- if (IS_ERR(port->axi_base_addr))
+- return PTR_ERR(port->axi_base_addr);
+-
+- mc_disable_interrupts(port);
+-
+- bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+-
+- /* Allow enabling MSI by disabling MSI-X */
+- val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+- val &= ~MSIX_CAP_MASK;
+- writel(val, bridge_base_addr + PCIE_PCI_IRQ_DW0);
+-
+- /* Pick num vectors from bitfile programmed onto FPGA fabric */
+- val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+- val &= NUM_MSI_MSGS_MASK;
+- val >>= NUM_MSI_MSGS_SHIFT;
+-
+- port->msi.num_vectors = 1 << val;
+-
+- /* Pick vector address from design */
+- port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
+-
+- ret = mc_pcie_init_clks(dev);
+- if (ret) {
+- dev_err(dev, "failed to get clock resources, error %d\n", ret);
+- return -ENODEV;
+- }
+-
+- return pci_host_common_probe(pdev);
+-}
+-
+-static const struct pci_ecam_ops mc_ecam_ops = {
+- .init = mc_platform_init,
+- .pci_ops = {
+- .map_bus = pci_ecam_map_bus,
+- .read = pci_generic_config_read,
+- .write = pci_generic_config_write,
+- }
+-};
+-
+-static const struct of_device_id mc_pcie_of_match[] = {
+- {
+- .compatible = "microchip,pcie-host-1.0",
+- .data = &mc_ecam_ops,
+- },
+- {},
+-};
+-
+-MODULE_DEVICE_TABLE(of, mc_pcie_of_match);
+-
+-static struct platform_driver mc_pcie_driver = {
+- .probe = mc_host_probe,
+- .driver = {
+- .name = "microchip-pcie",
+- .of_match_table = mc_pcie_of_match,
+- .suppress_bind_attrs = true,
+- },
+-};
+-
+-builtin_platform_driver(mc_pcie_driver);
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Microchip PCIe host controller driver");
+-MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -0,0 +1,1216 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Microchip AXI PCIe Bridge host controller driver
++ *
++ * Copyright (c) 2018 - 2020 Microchip Corporation. All rights reserved.
++ *
++ * Author: Daire McNamara <daire.mcnamara@microchip.com>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/irqchip/chained_irq.h>
++#include <linux/irqdomain.h>
++#include <linux/module.h>
++#include <linux/msi.h>
++#include <linux/of_address.h>
++#include <linux/of_pci.h>
++#include <linux/pci-ecam.h>
++#include <linux/platform_device.h>
++
++#include "../../pci.h"
++
++/* Number of MSI IRQs */
++#define MC_MAX_NUM_MSI_IRQS 32
++
++/* PCIe Bridge Phy and Controller Phy offsets */
++#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
++#define MC_PCIE1_CTRL_ADDR 0x0000a000u
++
++#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
++#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
++
++/* PCIe Bridge Phy Regs */
++#define PCIE_PCI_IRQ_DW0 0xa8
++#define MSIX_CAP_MASK BIT(31)
++#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
++#define NUM_MSI_MSGS_SHIFT 4
++
++#define IMASK_LOCAL 0x180
++#define DMA_END_ENGINE_0_MASK 0x00000000u
++#define DMA_END_ENGINE_0_SHIFT 0
++#define DMA_END_ENGINE_1_MASK 0x00000000u
++#define DMA_END_ENGINE_1_SHIFT 1
++#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
++#define DMA_ERROR_ENGINE_0_SHIFT 8
++#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
++#define DMA_ERROR_ENGINE_1_SHIFT 9
++#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
++#define A_ATR_EVT_POST_ERR_SHIFT 16
++#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
++#define A_ATR_EVT_FETCH_ERR_SHIFT 17
++#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
++#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
++#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define A_ATR_EVT_DOORBELL_SHIFT 19
++#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
++#define P_ATR_EVT_POST_ERR_SHIFT 20
++#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
++#define P_ATR_EVT_FETCH_ERR_SHIFT 21
++#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
++#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
++#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define P_ATR_EVT_DOORBELL_SHIFT 23
++#define PM_MSI_INT_INTA_MASK 0x01000000u
++#define PM_MSI_INT_INTA_SHIFT 24
++#define PM_MSI_INT_INTB_MASK 0x02000000u
++#define PM_MSI_INT_INTB_SHIFT 25
++#define PM_MSI_INT_INTC_MASK 0x04000000u
++#define PM_MSI_INT_INTC_SHIFT 26
++#define PM_MSI_INT_INTD_MASK 0x08000000u
++#define PM_MSI_INT_INTD_SHIFT 27
++#define PM_MSI_INT_INTX_MASK 0x0f000000u
++#define PM_MSI_INT_INTX_SHIFT 24
++#define PM_MSI_INT_MSI_MASK 0x10000000u
++#define PM_MSI_INT_MSI_SHIFT 28
++#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
++#define PM_MSI_INT_AER_EVT_SHIFT 29
++#define PM_MSI_INT_EVENTS_MASK 0x40000000u
++#define PM_MSI_INT_EVENTS_SHIFT 30
++#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
++#define PM_MSI_INT_SYS_ERR_SHIFT 31
++#define NUM_LOCAL_EVENTS 15
++#define ISTATUS_LOCAL 0x184
++#define IMASK_HOST 0x188
++#define ISTATUS_HOST 0x18c
++#define IMSI_ADDR 0x190
++#define ISTATUS_MSI 0x194
++
++/* PCIe Master table init defines */
++#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
++#define ATR0_PCIE_ATR_SIZE 0x25
++#define ATR0_PCIE_ATR_SIZE_SHIFT 1
++#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
++#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
++
++/* PCIe AXI slave table init defines */
++#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
++#define ATR_SIZE_SHIFT 1
++#define ATR_IMPL_ENABLE 1
++#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
++#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
++#define PCIE_TX_RX_INTERFACE 0x00000000u
++#define PCIE_CONFIG_INTERFACE 0x00000001u
++
++#define ATR_ENTRY_SIZE 32
++
++/* PCIe Controller Phy Regs */
++#define SEC_ERROR_EVENT_CNT 0x20
++#define DED_ERROR_EVENT_CNT 0x24
++#define SEC_ERROR_INT 0x28
++#define SEC_ERROR_INT_TX_RAM_SEC_ERR_INT GENMASK(3, 0)
++#define SEC_ERROR_INT_RX_RAM_SEC_ERR_INT GENMASK(7, 4)
++#define SEC_ERROR_INT_PCIE2AXI_RAM_SEC_ERR_INT GENMASK(11, 8)
++#define SEC_ERROR_INT_AXI2PCIE_RAM_SEC_ERR_INT GENMASK(15, 12)
++#define SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT GENMASK(15, 0)
++#define NUM_SEC_ERROR_INTS (4)
++#define SEC_ERROR_INT_MASK 0x2c
++#define DED_ERROR_INT 0x30
++#define DED_ERROR_INT_TX_RAM_DED_ERR_INT GENMASK(3, 0)
++#define DED_ERROR_INT_RX_RAM_DED_ERR_INT GENMASK(7, 4)
++#define DED_ERROR_INT_PCIE2AXI_RAM_DED_ERR_INT GENMASK(11, 8)
++#define DED_ERROR_INT_AXI2PCIE_RAM_DED_ERR_INT GENMASK(15, 12)
++#define DED_ERROR_INT_ALL_RAM_DED_ERR_INT GENMASK(15, 0)
++#define NUM_DED_ERROR_INTS (4)
++#define DED_ERROR_INT_MASK 0x34
++#define ECC_CONTROL 0x38
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_0 BIT(0)
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_1 BIT(1)
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_2 BIT(2)
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_3 BIT(3)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_0 BIT(4)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_1 BIT(5)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_2 BIT(6)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_3 BIT(7)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_0 BIT(8)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_1 BIT(9)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_2 BIT(10)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_3 BIT(11)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_0 BIT(12)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_1 BIT(13)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_2 BIT(14)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_3 BIT(15)
++#define ECC_CONTROL_TX_RAM_ECC_BYPASS BIT(24)
++#define ECC_CONTROL_RX_RAM_ECC_BYPASS BIT(25)
++#define ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS BIT(26)
++#define ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS BIT(27)
++#define PCIE_EVENT_INT 0x14c
++#define PCIE_EVENT_INT_L2_EXIT_INT BIT(0)
++#define PCIE_EVENT_INT_HOTRST_EXIT_INT BIT(1)
++#define PCIE_EVENT_INT_DLUP_EXIT_INT BIT(2)
++#define PCIE_EVENT_INT_MASK GENMASK(2, 0)
++#define PCIE_EVENT_INT_L2_EXIT_INT_MASK BIT(16)
++#define PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK BIT(17)
++#define PCIE_EVENT_INT_DLUP_EXIT_INT_MASK BIT(18)
++#define PCIE_EVENT_INT_ENB_MASK GENMASK(18, 16)
++#define PCIE_EVENT_INT_ENB_SHIFT 16
++#define NUM_PCIE_EVENTS (3)
++
++/* PCIe Config space MSI capability structure */
++#define MC_MSI_CAP_CTRL_OFFSET 0xe0u
++
++/* Events */
++#define EVENT_PCIE_L2_EXIT 0
++#define EVENT_PCIE_HOTRST_EXIT 1
++#define EVENT_PCIE_DLUP_EXIT 2
++#define EVENT_SEC_TX_RAM_SEC_ERR 3
++#define EVENT_SEC_RX_RAM_SEC_ERR 4
++#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 5
++#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 6
++#define EVENT_DED_TX_RAM_DED_ERR 7
++#define EVENT_DED_RX_RAM_DED_ERR 8
++#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 9
++#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 10
++#define EVENT_LOCAL_DMA_END_ENGINE_0 11
++#define EVENT_LOCAL_DMA_END_ENGINE_1 12
++#define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
++#define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
++#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
++#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
++#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
++#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
++#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
++#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
++#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
++#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
++#define EVENT_LOCAL_PM_MSI_INT_INTX 23
++#define EVENT_LOCAL_PM_MSI_INT_MSI 24
++#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
++#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
++#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
++#define NUM_EVENTS 28
++
++#define PCIE_EVENT_CAUSE(x, s) \
++ [EVENT_PCIE_ ## x] = { __stringify(x), s }
++
++#define SEC_ERROR_CAUSE(x, s) \
++ [EVENT_SEC_ ## x] = { __stringify(x), s }
++
++#define DED_ERROR_CAUSE(x, s) \
++ [EVENT_DED_ ## x] = { __stringify(x), s }
++
++#define LOCAL_EVENT_CAUSE(x, s) \
++ [EVENT_LOCAL_ ## x] = { __stringify(x), s }
++
++#define PCIE_EVENT(x) \
++ .base = MC_PCIE_CTRL_ADDR, \
++ .offset = PCIE_EVENT_INT, \
++ .mask_offset = PCIE_EVENT_INT, \
++ .mask_high = 1, \
++ .mask = PCIE_EVENT_INT_ ## x ## _INT, \
++ .enb_mask = PCIE_EVENT_INT_ENB_MASK
++
++#define SEC_EVENT(x) \
++ .base = MC_PCIE_CTRL_ADDR, \
++ .offset = SEC_ERROR_INT, \
++ .mask_offset = SEC_ERROR_INT_MASK, \
++ .mask = SEC_ERROR_INT_ ## x ## _INT, \
++ .mask_high = 1, \
++ .enb_mask = 0
++
++#define DED_EVENT(x) \
++ .base = MC_PCIE_CTRL_ADDR, \
++ .offset = DED_ERROR_INT, \
++ .mask_offset = DED_ERROR_INT_MASK, \
++ .mask_high = 1, \
++ .mask = DED_ERROR_INT_ ## x ## _INT, \
++ .enb_mask = 0
++
++#define LOCAL_EVENT(x) \
++ .base = MC_PCIE_BRIDGE_ADDR, \
++ .offset = ISTATUS_LOCAL, \
++ .mask_offset = IMASK_LOCAL, \
++ .mask_high = 0, \
++ .mask = x ## _MASK, \
++ .enb_mask = 0
++
++#define PCIE_EVENT_TO_EVENT_MAP(x) \
++ { PCIE_EVENT_INT_ ## x ## _INT, EVENT_PCIE_ ## x }
++
++#define SEC_ERROR_TO_EVENT_MAP(x) \
++ { SEC_ERROR_INT_ ## x ## _INT, EVENT_SEC_ ## x }
++
++#define DED_ERROR_TO_EVENT_MAP(x) \
++ { DED_ERROR_INT_ ## x ## _INT, EVENT_DED_ ## x }
++
++#define LOCAL_STATUS_TO_EVENT_MAP(x) \
++ { x ## _MASK, EVENT_LOCAL_ ## x }
++
++struct event_map {
++ u32 reg_mask;
++ u32 event_bit;
++};
++
++struct mc_msi {
++ struct mutex lock; /* Protect used bitmap */
++ struct irq_domain *msi_domain;
++ struct irq_domain *dev_domain;
++ u32 num_vectors;
++ u64 vector_phy;
++ DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
++};
++
++struct mc_pcie {
++ void __iomem *axi_base_addr;
++ struct device *dev;
++ struct irq_domain *intx_domain;
++ struct irq_domain *event_domain;
++ raw_spinlock_t lock;
++ struct mc_msi msi;
++};
++
++struct cause {
++ const char *sym;
++ const char *str;
++};
++
++static const struct cause event_cause[NUM_EVENTS] = {
++ PCIE_EVENT_CAUSE(L2_EXIT, "L2 exit event"),
++ PCIE_EVENT_CAUSE(HOTRST_EXIT, "Hot reset exit event"),
++ PCIE_EVENT_CAUSE(DLUP_EXIT, "DLUP exit event"),
++ SEC_ERROR_CAUSE(TX_RAM_SEC_ERR, "sec error in tx buffer"),
++ SEC_ERROR_CAUSE(RX_RAM_SEC_ERR, "sec error in rx buffer"),
++ SEC_ERROR_CAUSE(PCIE2AXI_RAM_SEC_ERR, "sec error in pcie2axi buffer"),
++ SEC_ERROR_CAUSE(AXI2PCIE_RAM_SEC_ERR, "sec error in axi2pcie buffer"),
++ DED_ERROR_CAUSE(TX_RAM_DED_ERR, "ded error in tx buffer"),
++ DED_ERROR_CAUSE(RX_RAM_DED_ERR, "ded error in rx buffer"),
++ DED_ERROR_CAUSE(PCIE2AXI_RAM_DED_ERR, "ded error in pcie2axi buffer"),
++ DED_ERROR_CAUSE(AXI2PCIE_RAM_DED_ERR, "ded error in axi2pcie buffer"),
++ LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_0, "dma engine 0 error"),
++ LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_1, "dma engine 1 error"),
++ LOCAL_EVENT_CAUSE(A_ATR_EVT_POST_ERR, "axi write request error"),
++ LOCAL_EVENT_CAUSE(A_ATR_EVT_FETCH_ERR, "axi read request error"),
++ LOCAL_EVENT_CAUSE(A_ATR_EVT_DISCARD_ERR, "axi read timeout"),
++ LOCAL_EVENT_CAUSE(P_ATR_EVT_POST_ERR, "pcie write request error"),
++ LOCAL_EVENT_CAUSE(P_ATR_EVT_FETCH_ERR, "pcie read request error"),
++ LOCAL_EVENT_CAUSE(P_ATR_EVT_DISCARD_ERR, "pcie read timeout"),
++ LOCAL_EVENT_CAUSE(PM_MSI_INT_AER_EVT, "aer event"),
++ LOCAL_EVENT_CAUSE(PM_MSI_INT_EVENTS, "pm/ltr/hotplug event"),
++ LOCAL_EVENT_CAUSE(PM_MSI_INT_SYS_ERR, "system error"),
++};
++
++static struct event_map pcie_event_to_event[] = {
++ PCIE_EVENT_TO_EVENT_MAP(L2_EXIT),
++ PCIE_EVENT_TO_EVENT_MAP(HOTRST_EXIT),
++ PCIE_EVENT_TO_EVENT_MAP(DLUP_EXIT),
++};
++
++static struct event_map sec_error_to_event[] = {
++ SEC_ERROR_TO_EVENT_MAP(TX_RAM_SEC_ERR),
++ SEC_ERROR_TO_EVENT_MAP(RX_RAM_SEC_ERR),
++ SEC_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_SEC_ERR),
++ SEC_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_SEC_ERR),
++};
++
++static struct event_map ded_error_to_event[] = {
++ DED_ERROR_TO_EVENT_MAP(TX_RAM_DED_ERR),
++ DED_ERROR_TO_EVENT_MAP(RX_RAM_DED_ERR),
++ DED_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_DED_ERR),
++ DED_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_DED_ERR),
++};
++
++static struct event_map local_status_to_event[] = {
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_0),
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_1),
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_0),
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_1),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_POST_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_FETCH_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DISCARD_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DOORBELL),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_POST_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_FETCH_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DISCARD_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DOORBELL),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_INTX),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_MSI),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_AER_EVT),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_EVENTS),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_SYS_ERR),
++};
++
++static struct {
++ u32 base;
++ u32 offset;
++ u32 mask;
++ u32 shift;
++ u32 enb_mask;
++ u32 mask_high;
++ u32 mask_offset;
++} event_descs[] = {
++ { PCIE_EVENT(L2_EXIT) },
++ { PCIE_EVENT(HOTRST_EXIT) },
++ { PCIE_EVENT(DLUP_EXIT) },
++ { SEC_EVENT(TX_RAM_SEC_ERR) },
++ { SEC_EVENT(RX_RAM_SEC_ERR) },
++ { SEC_EVENT(PCIE2AXI_RAM_SEC_ERR) },
++ { SEC_EVENT(AXI2PCIE_RAM_SEC_ERR) },
++ { DED_EVENT(TX_RAM_DED_ERR) },
++ { DED_EVENT(RX_RAM_DED_ERR) },
++ { DED_EVENT(PCIE2AXI_RAM_DED_ERR) },
++ { DED_EVENT(AXI2PCIE_RAM_DED_ERR) },
++ { LOCAL_EVENT(DMA_END_ENGINE_0) },
++ { LOCAL_EVENT(DMA_END_ENGINE_1) },
++ { LOCAL_EVENT(DMA_ERROR_ENGINE_0) },
++ { LOCAL_EVENT(DMA_ERROR_ENGINE_1) },
++ { LOCAL_EVENT(A_ATR_EVT_POST_ERR) },
++ { LOCAL_EVENT(A_ATR_EVT_FETCH_ERR) },
++ { LOCAL_EVENT(A_ATR_EVT_DISCARD_ERR) },
++ { LOCAL_EVENT(A_ATR_EVT_DOORBELL) },
++ { LOCAL_EVENT(P_ATR_EVT_POST_ERR) },
++ { LOCAL_EVENT(P_ATR_EVT_FETCH_ERR) },
++ { LOCAL_EVENT(P_ATR_EVT_DISCARD_ERR) },
++ { LOCAL_EVENT(P_ATR_EVT_DOORBELL) },
++ { LOCAL_EVENT(PM_MSI_INT_INTX) },
++ { LOCAL_EVENT(PM_MSI_INT_MSI) },
++ { LOCAL_EVENT(PM_MSI_INT_AER_EVT) },
++ { LOCAL_EVENT(PM_MSI_INT_EVENTS) },
++ { LOCAL_EVENT(PM_MSI_INT_SYS_ERR) },
++};
++
++static char poss_clks[][5] = { "fic0", "fic1", "fic2", "fic3" };
++
++static struct mc_pcie *port;
++
++static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
++{
++ struct mc_msi *msi = &port->msi;
++ u16 reg;
++ u8 queue_size;
++
++ /* Fixup MSI enable flag */
++ reg = readw_relaxed(ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
++ reg |= PCI_MSI_FLAGS_ENABLE;
++ writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
++
++ /* Fixup PCI MSI queue flags */
++ queue_size = FIELD_GET(PCI_MSI_FLAGS_QMASK, reg);
++ reg |= FIELD_PREP(PCI_MSI_FLAGS_QSIZE, queue_size);
++ writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
++
++ /* Fixup MSI addr fields */
++ writel_relaxed(lower_32_bits(msi->vector_phy),
++ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_LO);
++ writel_relaxed(upper_32_bits(msi->vector_phy),
++ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
++}
++
++static void mc_handle_msi(struct irq_desc *desc)
++{
++ struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ struct mc_msi *msi = &port->msi;
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_MSI_MASK) {
++ writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
++ status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
++ for_each_set_bit(bit, &status, msi->num_vectors) {
++ ret = generic_handle_domain_irq(msi->dev_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void mc_msi_bottom_irq_ack(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ u32 bitpos = data->hwirq;
++
++ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
++}
++
++static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ phys_addr_t addr = port->msi.vector_phy;
++
++ msg->address_lo = lower_32_bits(addr);
++ msg->address_hi = upper_32_bits(addr);
++ msg->data = data->hwirq;
++
++ dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
++ (int)data->hwirq, msg->address_hi, msg->address_lo);
++}
++
++static int mc_msi_set_affinity(struct irq_data *irq_data,
++ const struct cpumask *mask, bool force)
++{
++ return -EINVAL;
++}
++
++static struct irq_chip mc_msi_bottom_irq_chip = {
++ .name = "Microchip MSI",
++ .irq_ack = mc_msi_bottom_irq_ack,
++ .irq_compose_msi_msg = mc_compose_msi_msg,
++ .irq_set_affinity = mc_msi_set_affinity,
++};
++
++static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
++ unsigned int nr_irqs, void *args)
++{
++ struct mc_pcie *port = domain->host_data;
++ struct mc_msi *msi = &port->msi;
++ unsigned long bit;
++
++ mutex_lock(&msi->lock);
++ bit = find_first_zero_bit(msi->used, msi->num_vectors);
++ if (bit >= msi->num_vectors) {
++ mutex_unlock(&msi->lock);
++ return -ENOSPC;
++ }
++
++ set_bit(bit, msi->used);
++
++ irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
++ domain->host_data, handle_edge_irq, NULL, NULL);
++
++ mutex_unlock(&msi->lock);
++
++ return 0;
++}
++
++static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
++ unsigned int nr_irqs)
++{
++ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
++ struct mc_pcie *port = irq_data_get_irq_chip_data(d);
++ struct mc_msi *msi = &port->msi;
++
++ mutex_lock(&msi->lock);
++
++ if (test_bit(d->hwirq, msi->used))
++ __clear_bit(d->hwirq, msi->used);
++ else
++ dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
++
++ mutex_unlock(&msi->lock);
++}
++
++static const struct irq_domain_ops msi_domain_ops = {
++ .alloc = mc_irq_msi_domain_alloc,
++ .free = mc_irq_msi_domain_free,
++};
++
++static struct irq_chip mc_msi_irq_chip = {
++ .name = "Microchip PCIe MSI",
++ .irq_ack = irq_chip_ack_parent,
++ .irq_mask = pci_msi_mask_irq,
++ .irq_unmask = pci_msi_unmask_irq,
++};
++
++static struct msi_domain_info mc_msi_domain_info = {
++ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
++ MSI_FLAG_PCI_MSIX),
++ .chip = &mc_msi_irq_chip,
++};
++
++static int mc_allocate_msi_domains(struct mc_pcie *port)
++{
++ struct device *dev = port->dev;
++ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++ struct mc_msi *msi = &port->msi;
++
++ mutex_init(&port->msi.lock);
++
++ msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
++ &msi_domain_ops, port);
++ if (!msi->dev_domain) {
++ dev_err(dev, "failed to create IRQ domain\n");
++ return -ENOMEM;
++ }
++
++ msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
++ msi->dev_domain);
++ if (!msi->msi_domain) {
++ dev_err(dev, "failed to create MSI domain\n");
++ irq_domain_remove(msi->dev_domain);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static void mc_handle_intx(struct irq_desc *desc)
++{
++ struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_INTX_MASK) {
++ status &= PM_MSI_INT_INTX_MASK;
++ status >>= PM_MSI_INT_INTX_SHIFT;
++ for_each_set_bit(bit, &status, PCI_NUM_INTX) {
++ ret = generic_handle_domain_irq(port->intx_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void mc_ack_intx_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++
++ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
++}
++
++static void mc_mask_intx_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void mc_unmask_intx_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static struct irq_chip mc_intx_irq_chip = {
++ .name = "Microchip PCIe INTx",
++ .irq_ack = mc_ack_intx_irq,
++ .irq_mask = mc_mask_intx_irq,
++ .irq_unmask = mc_unmask_intx_irq,
++};
++
++static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops intx_domain_ops = {
++ .map = mc_pcie_intx_map,
++};
++
++static inline u32 reg_to_event(u32 reg, struct event_map field)
++{
++ return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
++}
++
++static u32 pcie_events(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 reg = readl_relaxed(ctrl_base_addr + PCIE_EVENT_INT);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(pcie_event_to_event); i++)
++ val |= reg_to_event(reg, pcie_event_to_event[i]);
++
++ return val;
++}
++
++static u32 sec_errors(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 reg = readl_relaxed(ctrl_base_addr + SEC_ERROR_INT);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(sec_error_to_event); i++)
++ val |= reg_to_event(reg, sec_error_to_event[i]);
++
++ return val;
++}
++
++static u32 ded_errors(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 reg = readl_relaxed(ctrl_base_addr + DED_ERROR_INT);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(ded_error_to_event); i++)
++ val |= reg_to_event(reg, ded_error_to_event[i]);
++
++ return val;
++}
++
++static u32 local_events(struct mc_pcie *port)
++{
++ void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ u32 reg = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(local_status_to_event); i++)
++ val |= reg_to_event(reg, local_status_to_event[i]);
++
++ return val;
++}
++
++static u32 get_events(struct mc_pcie *port)
++{
++ u32 events = 0;
++
++ events |= pcie_events(port);
++ events |= sec_errors(port);
++ events |= ded_errors(port);
++ events |= local_events(port);
++
++ return events;
++}
++
++static irqreturn_t mc_event_handler(int irq, void *dev_id)
++{
++ struct mc_pcie *port = dev_id;
++ struct device *dev = port->dev;
++ struct irq_data *data;
++
++ data = irq_domain_get_irq_data(port->event_domain, irq);
++
++ if (event_cause[data->hwirq].str)
++ dev_err_ratelimited(dev, "%s\n", event_cause[data->hwirq].str);
++ else
++ dev_err_ratelimited(dev, "bad event IRQ %ld\n", data->hwirq);
++
++ return IRQ_HANDLED;
++}
++
++static void mc_handle_event(struct irq_desc *desc)
++{
++ struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ unsigned long events;
++ u32 bit;
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++
++ chained_irq_enter(chip, desc);
++
++ events = get_events(port);
++
++ for_each_set_bit(bit, &events, NUM_EVENTS)
++ generic_handle_domain_irq(port->event_domain, bit);
++
++ chained_irq_exit(chip, desc);
++}
++
++static void mc_ack_event_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ u32 event = data->hwirq;
++ void __iomem *addr;
++ u32 mask;
++
++ addr = port->axi_base_addr + event_descs[event].base +
++ event_descs[event].offset;
++ mask = event_descs[event].mask;
++ mask |= event_descs[event].enb_mask;
++
++ writel_relaxed(mask, addr);
++}
++
++static void mc_mask_event_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ u32 event = data->hwirq;
++ void __iomem *addr;
++ u32 mask;
++ u32 val;
++
++ addr = port->axi_base_addr + event_descs[event].base +
++ event_descs[event].mask_offset;
++ mask = event_descs[event].mask;
++ if (event_descs[event].enb_mask) {
++ mask <<= PCIE_EVENT_INT_ENB_SHIFT;
++ mask &= PCIE_EVENT_INT_ENB_MASK;
++ }
++
++ if (!event_descs[event].mask_high)
++ mask = ~mask;
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(addr);
++ if (event_descs[event].mask_high)
++ val |= mask;
++ else
++ val &= mask;
++
++ writel_relaxed(val, addr);
++ raw_spin_unlock(&port->lock);
++}
++
++static void mc_unmask_event_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ u32 event = data->hwirq;
++ void __iomem *addr;
++ u32 mask;
++ u32 val;
++
++ addr = port->axi_base_addr + event_descs[event].base +
++ event_descs[event].mask_offset;
++ mask = event_descs[event].mask;
++
++ if (event_descs[event].enb_mask)
++ mask <<= PCIE_EVENT_INT_ENB_SHIFT;
++
++ if (event_descs[event].mask_high)
++ mask = ~mask;
++
++ if (event_descs[event].enb_mask)
++ mask &= PCIE_EVENT_INT_ENB_MASK;
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(addr);
++ if (event_descs[event].mask_high)
++ val &= mask;
++ else
++ val |= mask;
++ writel_relaxed(val, addr);
++ raw_spin_unlock(&port->lock);
++}
++
++static struct irq_chip mc_event_irq_chip = {
++ .name = "Microchip PCIe EVENT",
++ .irq_ack = mc_ack_event_irq,
++ .irq_mask = mc_mask_event_irq,
++ .irq_unmask = mc_unmask_event_irq,
++};
++
++static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops event_domain_ops = {
++ .map = mc_pcie_event_map,
++};
++
++static inline void mc_pcie_deinit_clk(void *data)
++{
++ struct clk *clk = data;
++
++ clk_disable_unprepare(clk);
++}
++
++static inline struct clk *mc_pcie_init_clk(struct device *dev, const char *id)
++{
++ struct clk *clk;
++ int ret;
++
++ clk = devm_clk_get_optional(dev, id);
++ if (IS_ERR(clk))
++ return clk;
++ if (!clk)
++ return clk;
++
++ ret = clk_prepare_enable(clk);
++ if (ret)
++ return ERR_PTR(ret);
++
++ devm_add_action_or_reset(dev, mc_pcie_deinit_clk, clk);
++
++ return clk;
++}
++
++static int mc_pcie_init_clks(struct device *dev)
++{
++ int i;
++ struct clk *fic;
++
++ /*
++ * PCIe may be clocked via Fabric Interface using between 1 and 4
++ * clocks. Scan DT for clocks and enable them if present
++ */
++ for (i = 0; i < ARRAY_SIZE(poss_clks); i++) {
++ fic = mc_pcie_init_clk(dev, poss_clks[i]);
++ if (IS_ERR(fic))
++ return PTR_ERR(fic);
++ }
++
++ return 0;
++}
++
++static int mc_pcie_init_irq_domains(struct mc_pcie *port)
++{
++ struct device *dev = port->dev;
++ struct device_node *node = dev->of_node;
++ struct device_node *pcie_intc_node;
++
++ /* Setup INTx */
++ pcie_intc_node = of_get_next_child(node, NULL);
++ if (!pcie_intc_node) {
++ dev_err(dev, "failed to find PCIe Intc node\n");
++ return -EINVAL;
++ }
++
++ port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
++ &event_domain_ops, port);
++ if (!port->event_domain) {
++ dev_err(dev, "failed to get event domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
++
++ port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
++ &intx_domain_ops, port);
++ if (!port->intx_domain) {
++ dev_err(dev, "failed to get an INTx IRQ domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
++
++ of_node_put(pcie_intc_node);
++ raw_spin_lock_init(&port->lock);
++
++ return mc_allocate_msi_domains(port);
++}
++
++static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size)
++{
++ u32 atr_sz = ilog2(size) - 1;
++ u32 val;
++
++ if (index == 0)
++ val = PCIE_CONFIG_INTERFACE;
++ else
++ val = PCIE_TX_RX_INTERFACE;
++
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_PARAM);
++
++ val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
++ ATR_IMPL_ENABLE;
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRCADDR_PARAM);
++
++ val = upper_32_bits(axi_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRC_ADDR);
++
++ val = lower_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
++
++ val = upper_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
++
++ val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
++ writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
++}
++
++static int mc_pcie_setup_windows(struct platform_device *pdev,
++ struct mc_pcie *port)
++{
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
++ struct resource_entry *entry;
++ u64 pci_addr;
++ u32 index = 1;
++
++ resource_list_for_each_entry(entry, &bridge->windows) {
++ if (resource_type(entry->res) == IORESOURCE_MEM) {
++ pci_addr = entry->res->start - entry->offset;
++ mc_pcie_setup_window(bridge_base_addr, index,
++ entry->res->start, pci_addr,
++ resource_size(entry->res));
++ index++;
++ }
++ }
++
++ return 0;
++}
++
++static inline void mc_clear_secs(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++
++ writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
++ SEC_ERROR_INT);
++ writel_relaxed(0, ctrl_base_addr + SEC_ERROR_EVENT_CNT);
++}
++
++static inline void mc_clear_deds(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++
++ writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
++ DED_ERROR_INT);
++ writel_relaxed(0, ctrl_base_addr + DED_ERROR_EVENT_CNT);
++}
++
++static void mc_disable_interrupts(struct mc_pcie *port)
++{
++ void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 val;
++
++ /* Ensure ECC bypass is enabled */
++ val = ECC_CONTROL_TX_RAM_ECC_BYPASS |
++ ECC_CONTROL_RX_RAM_ECC_BYPASS |
++ ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
++ ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS;
++ writel_relaxed(val, ctrl_base_addr + ECC_CONTROL);
++
++ /* Disable SEC errors and clear any outstanding */
++ writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
++ SEC_ERROR_INT_MASK);
++ mc_clear_secs(port);
++
++ /* Disable DED errors and clear any outstanding */
++ writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
++ DED_ERROR_INT_MASK);
++ mc_clear_deds(port);
++
++ /* Disable local interrupts and clear any outstanding */
++ writel_relaxed(0, bridge_base_addr + IMASK_LOCAL);
++ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_LOCAL);
++ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_MSI);
++
++ /* Disable PCIe events and clear any outstanding */
++ val = PCIE_EVENT_INT_L2_EXIT_INT |
++ PCIE_EVENT_INT_HOTRST_EXIT_INT |
++ PCIE_EVENT_INT_DLUP_EXIT_INT |
++ PCIE_EVENT_INT_L2_EXIT_INT_MASK |
++ PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
++ PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
++ writel_relaxed(val, ctrl_base_addr + PCIE_EVENT_INT);
++
++ /* Disable host interrupts and clear any outstanding */
++ writel_relaxed(0, bridge_base_addr + IMASK_HOST);
++ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
++}
++
++static int mc_init_interrupts(struct platform_device *pdev, struct mc_pcie *port)
++{
++ struct device *dev = &pdev->dev;
++ int irq;
++ int i, intx_irq, msi_irq, event_irq;
++ int ret;
++
++ ret = mc_pcie_init_irq_domains(port);
++ if (ret) {
++ dev_err(dev, "failed creating IRQ domains\n");
++ return ret;
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ return -ENODEV;
++
++ for (i = 0; i < NUM_EVENTS; i++) {
++ event_irq = irq_create_mapping(port->event_domain, i);
++ if (!event_irq) {
++ dev_err(dev, "failed to map hwirq %d\n", i);
++ return -ENXIO;
++ }
++
++ ret = devm_request_irq(dev, event_irq, mc_event_handler,
++ 0, event_cause[i].sym, port);
++ if (ret) {
++ dev_err(dev, "failed to request IRQ %d\n", event_irq);
++ return ret;
++ }
++ }
++
++ intx_irq = irq_create_mapping(port->event_domain,
++ EVENT_LOCAL_PM_MSI_INT_INTX);
++ if (!intx_irq) {
++ dev_err(dev, "failed to map INTx interrupt\n");
++ return -ENXIO;
++ }
++
++ /* Plug the INTx chained handler */
++ irq_set_chained_handler_and_data(intx_irq, mc_handle_intx, port);
++
++ msi_irq = irq_create_mapping(port->event_domain,
++ EVENT_LOCAL_PM_MSI_INT_MSI);
++ if (!msi_irq)
++ return -ENXIO;
++
++ /* Plug the MSI chained handler */
++ irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
++
++ /* Plug the main event chained handler */
++ irq_set_chained_handler_and_data(irq, mc_handle_event, port);
++
++ return 0;
++}
++
++static int mc_platform_init(struct pci_config_window *cfg)
++{
++ struct device *dev = cfg->parent;
++ struct platform_device *pdev = to_platform_device(dev);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ int ret;
++
++ /* Configure address translation table 0 for PCIe config space */
++ mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
++ cfg->res.start,
++ resource_size(&cfg->res));
++
++ /* Need some fixups in config space */
++ mc_pcie_enable_msi(port, cfg->win);
++
++ /* Configure non-config space outbound ranges */
++ ret = mc_pcie_setup_windows(pdev, port);
++ if (ret)
++ return ret;
++
++ /* Address translation is up; safe to enable interrupts */
++ ret = mc_init_interrupts(pdev, port);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static int mc_host_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ void __iomem *bridge_base_addr;
++ int ret;
++ u32 val;
++
++ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
++ if (!port)
++ return -ENOMEM;
++
++ port->dev = dev;
++
++ port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
++ if (IS_ERR(port->axi_base_addr))
++ return PTR_ERR(port->axi_base_addr);
++
++ mc_disable_interrupts(port);
++
++ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++
++ /* Allow enabling MSI by disabling MSI-X */
++ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
++ val &= ~MSIX_CAP_MASK;
++ writel(val, bridge_base_addr + PCIE_PCI_IRQ_DW0);
++
++ /* Pick num vectors from bitfile programmed onto FPGA fabric */
++ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
++ val &= NUM_MSI_MSGS_MASK;
++ val >>= NUM_MSI_MSGS_SHIFT;
++
++ port->msi.num_vectors = 1 << val;
++
++ /* Pick vector address from design */
++ port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
++
++ ret = mc_pcie_init_clks(dev);
++ if (ret) {
++ dev_err(dev, "failed to get clock resources, error %d\n", ret);
++ return -ENODEV;
++ }
++
++ return pci_host_common_probe(pdev);
++}
++
++static const struct pci_ecam_ops mc_ecam_ops = {
++ .init = mc_platform_init,
++ .pci_ops = {
++ .map_bus = pci_ecam_map_bus,
++ .read = pci_generic_config_read,
++ .write = pci_generic_config_write,
++ }
++};
++
++static const struct of_device_id mc_pcie_of_match[] = {
++ {
++ .compatible = "microchip,pcie-host-1.0",
++ .data = &mc_ecam_ops,
++ },
++ {},
++};
++
++MODULE_DEVICE_TABLE(of, mc_pcie_of_match);
++
++static struct platform_driver mc_pcie_driver = {
++ .probe = mc_host_probe,
++ .driver = {
++ .name = "microchip-pcie",
++ .of_match_table = mc_pcie_of_match,
++ .suppress_bind_attrs = true,
++ },
++};
++
++builtin_platform_driver(mc_pcie_driver);
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Microchip PCIe host controller driver");
++MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
diff --git a/target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch b/target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch
new file mode 100644
index 0000000000..0aacec2769
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch
@@ -0,0 +1,259 @@
+From eca1b864bb2d4e8d9811506979560a89351c2e37 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:53 +0800
+Subject: [PATCH 016/116] PCI: microchip: Move PLDA IP register macros to
+ pcie-plda.h
+
+Move PLDA PCIe host controller IP registers macros to pcie-plda.h,
+including bridge registers and local IRQ event number.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 108 +++---------------
+ drivers/pci/controller/plda/pcie-plda.h | 108 ++++++++++++++++++
+ 2 files changed, 124 insertions(+), 92 deletions(-)
+ create mode 100644 drivers/pci/controller/plda/pcie-plda.h
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -19,6 +19,7 @@
+ #include <linux/platform_device.h>
+
+ #include "../../pci.h"
++#include "pcie-plda.h"
+
+ /* Number of MSI IRQs */
+ #define MC_MAX_NUM_MSI_IRQS 32
+@@ -30,84 +31,6 @@
+ #define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
+ #define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
+
+-/* PCIe Bridge Phy Regs */
+-#define PCIE_PCI_IRQ_DW0 0xa8
+-#define MSIX_CAP_MASK BIT(31)
+-#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
+-#define NUM_MSI_MSGS_SHIFT 4
+-
+-#define IMASK_LOCAL 0x180
+-#define DMA_END_ENGINE_0_MASK 0x00000000u
+-#define DMA_END_ENGINE_0_SHIFT 0
+-#define DMA_END_ENGINE_1_MASK 0x00000000u
+-#define DMA_END_ENGINE_1_SHIFT 1
+-#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
+-#define DMA_ERROR_ENGINE_0_SHIFT 8
+-#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
+-#define DMA_ERROR_ENGINE_1_SHIFT 9
+-#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
+-#define A_ATR_EVT_POST_ERR_SHIFT 16
+-#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
+-#define A_ATR_EVT_FETCH_ERR_SHIFT 17
+-#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
+-#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
+-#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define A_ATR_EVT_DOORBELL_SHIFT 19
+-#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
+-#define P_ATR_EVT_POST_ERR_SHIFT 20
+-#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
+-#define P_ATR_EVT_FETCH_ERR_SHIFT 21
+-#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
+-#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
+-#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define P_ATR_EVT_DOORBELL_SHIFT 23
+-#define PM_MSI_INT_INTA_MASK 0x01000000u
+-#define PM_MSI_INT_INTA_SHIFT 24
+-#define PM_MSI_INT_INTB_MASK 0x02000000u
+-#define PM_MSI_INT_INTB_SHIFT 25
+-#define PM_MSI_INT_INTC_MASK 0x04000000u
+-#define PM_MSI_INT_INTC_SHIFT 26
+-#define PM_MSI_INT_INTD_MASK 0x08000000u
+-#define PM_MSI_INT_INTD_SHIFT 27
+-#define PM_MSI_INT_INTX_MASK 0x0f000000u
+-#define PM_MSI_INT_INTX_SHIFT 24
+-#define PM_MSI_INT_MSI_MASK 0x10000000u
+-#define PM_MSI_INT_MSI_SHIFT 28
+-#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
+-#define PM_MSI_INT_AER_EVT_SHIFT 29
+-#define PM_MSI_INT_EVENTS_MASK 0x40000000u
+-#define PM_MSI_INT_EVENTS_SHIFT 30
+-#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
+-#define PM_MSI_INT_SYS_ERR_SHIFT 31
+-#define NUM_LOCAL_EVENTS 15
+-#define ISTATUS_LOCAL 0x184
+-#define IMASK_HOST 0x188
+-#define ISTATUS_HOST 0x18c
+-#define IMSI_ADDR 0x190
+-#define ISTATUS_MSI 0x194
+-
+-/* PCIe Master table init defines */
+-#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+-#define ATR0_PCIE_ATR_SIZE 0x25
+-#define ATR0_PCIE_ATR_SIZE_SHIFT 1
+-#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
+-#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
+-
+-/* PCIe AXI slave table init defines */
+-#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
+-#define ATR_SIZE_SHIFT 1
+-#define ATR_IMPL_ENABLE 1
+-#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
+-#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
+-#define PCIE_TX_RX_INTERFACE 0x00000000u
+-#define PCIE_CONFIG_INTERFACE 0x00000001u
+-
+-#define ATR_ENTRY_SIZE 32
+-
+ /* PCIe Controller Phy Regs */
+ #define SEC_ERROR_EVENT_CNT 0x20
+ #define DED_ERROR_EVENT_CNT 0x24
+@@ -179,20 +102,21 @@
+ #define EVENT_LOCAL_DMA_END_ENGINE_1 12
+ #define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
+ #define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
+-#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
+-#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
+-#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
+-#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
+-#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
+-#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
+-#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
+-#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
+-#define EVENT_LOCAL_PM_MSI_INT_INTX 23
+-#define EVENT_LOCAL_PM_MSI_INT_MSI 24
+-#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
+-#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
+-#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
+-#define NUM_EVENTS 28
++#define NUM_MC_EVENTS 15
++#define EVENT_LOCAL_A_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_AXI_POST_ERR)
++#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_AXI_FETCH_ERR)
++#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_AXI_DISCARD_ERR)
++#define EVENT_LOCAL_A_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_AXI_DOORBELL)
++#define EVENT_LOCAL_P_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_PCIE_POST_ERR)
++#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_PCIE_FETCH_ERR)
++#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_PCIE_DISCARD_ERR)
++#define EVENT_LOCAL_P_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_PCIE_DOORBELL)
++#define EVENT_LOCAL_PM_MSI_INT_INTX (NUM_MC_EVENTS + PLDA_INTX)
++#define EVENT_LOCAL_PM_MSI_INT_MSI (NUM_MC_EVENTS + PLDA_MSI)
++#define EVENT_LOCAL_PM_MSI_INT_AER_EVT (NUM_MC_EVENTS + PLDA_AER_EVENT)
++#define EVENT_LOCAL_PM_MSI_INT_EVENTS (NUM_MC_EVENTS + PLDA_MISC_EVENTS)
++#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR (NUM_MC_EVENTS + PLDA_SYS_ERR)
++#define NUM_EVENTS (NUM_MC_EVENTS + PLDA_INT_EVENT_NUM)
+
+ #define PCIE_EVENT_CAUSE(x, s) \
+ [EVENT_PCIE_ ## x] = { __stringify(x), s }
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -0,0 +1,108 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * PLDA PCIe host controller driver
++ */
++
++#ifndef _PCIE_PLDA_H
++#define _PCIE_PLDA_H
++
++/* PCIe Bridge Phy Regs */
++#define PCIE_PCI_IRQ_DW0 0xa8
++#define MSIX_CAP_MASK BIT(31)
++#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
++#define NUM_MSI_MSGS_SHIFT 4
++
++#define IMASK_LOCAL 0x180
++#define DMA_END_ENGINE_0_MASK 0x00000000u
++#define DMA_END_ENGINE_0_SHIFT 0
++#define DMA_END_ENGINE_1_MASK 0x00000000u
++#define DMA_END_ENGINE_1_SHIFT 1
++#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
++#define DMA_ERROR_ENGINE_0_SHIFT 8
++#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
++#define DMA_ERROR_ENGINE_1_SHIFT 9
++#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
++#define A_ATR_EVT_POST_ERR_SHIFT 16
++#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
++#define A_ATR_EVT_FETCH_ERR_SHIFT 17
++#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
++#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
++#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define A_ATR_EVT_DOORBELL_SHIFT 19
++#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
++#define P_ATR_EVT_POST_ERR_SHIFT 20
++#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
++#define P_ATR_EVT_FETCH_ERR_SHIFT 21
++#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
++#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
++#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define P_ATR_EVT_DOORBELL_SHIFT 23
++#define PM_MSI_INT_INTA_MASK 0x01000000u
++#define PM_MSI_INT_INTA_SHIFT 24
++#define PM_MSI_INT_INTB_MASK 0x02000000u
++#define PM_MSI_INT_INTB_SHIFT 25
++#define PM_MSI_INT_INTC_MASK 0x04000000u
++#define PM_MSI_INT_INTC_SHIFT 26
++#define PM_MSI_INT_INTD_MASK 0x08000000u
++#define PM_MSI_INT_INTD_SHIFT 27
++#define PM_MSI_INT_INTX_MASK 0x0f000000u
++#define PM_MSI_INT_INTX_SHIFT 24
++#define PM_MSI_INT_MSI_MASK 0x10000000u
++#define PM_MSI_INT_MSI_SHIFT 28
++#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
++#define PM_MSI_INT_AER_EVT_SHIFT 29
++#define PM_MSI_INT_EVENTS_MASK 0x40000000u
++#define PM_MSI_INT_EVENTS_SHIFT 30
++#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
++#define PM_MSI_INT_SYS_ERR_SHIFT 31
++#define NUM_LOCAL_EVENTS 15
++#define ISTATUS_LOCAL 0x184
++#define IMASK_HOST 0x188
++#define ISTATUS_HOST 0x18c
++#define IMSI_ADDR 0x190
++#define ISTATUS_MSI 0x194
++
++/* PCIe Master table init defines */
++#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
++#define ATR0_PCIE_ATR_SIZE 0x25
++#define ATR0_PCIE_ATR_SIZE_SHIFT 1
++#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
++#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
++
++/* PCIe AXI slave table init defines */
++#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
++#define ATR_SIZE_SHIFT 1
++#define ATR_IMPL_ENABLE 1
++#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
++#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
++#define PCIE_TX_RX_INTERFACE 0x00000000u
++#define PCIE_CONFIG_INTERFACE 0x00000001u
++
++#define ATR_ENTRY_SIZE 32
++
++enum plda_int_event {
++ PLDA_AXI_POST_ERR,
++ PLDA_AXI_FETCH_ERR,
++ PLDA_AXI_DISCARD_ERR,
++ PLDA_AXI_DOORBELL,
++ PLDA_PCIE_POST_ERR,
++ PLDA_PCIE_FETCH_ERR,
++ PLDA_PCIE_DISCARD_ERR,
++ PLDA_PCIE_DOORBELL,
++ PLDA_INTX,
++ PLDA_MSI,
++ PLDA_AER_EVENT,
++ PLDA_MISC_EVENTS,
++ PLDA_SYS_ERR,
++ PLDA_INT_EVENT_NUM
++};
++
++#define PLDA_NUM_DMA_EVENTS 16
++
++#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
++
++#endif
diff --git a/target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch b/target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch
new file mode 100644
index 0000000000..bc3f909116
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch
@@ -0,0 +1,107 @@
+From 6ee4d4568314425079ae88229bb9abbff9b92b8b Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:54 +0800
+Subject: [PATCH 017/116] PCI: microchip: Add bridge_addr field to struct
+ mc_pcie
+
+For bridge address base is common PLDA field, Add this to struct mc_pcie
+first.
+
+INTx and MSI codes interrupts codes will get the bridge base address from
+port->bridge_addr. These codes will be changed to common codes.
+axi_base_addr is Microchip its own data.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 23 ++++++++-----------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -195,6 +195,7 @@ struct mc_pcie {
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+ struct mc_msi msi;
++ void __iomem *bridge_addr;
+ };
+
+ struct cause {
+@@ -339,8 +340,7 @@ static void mc_handle_msi(struct irq_des
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+ struct mc_msi *msi = &port->msi;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long status;
+ u32 bit;
+ int ret;
+@@ -365,8 +365,7 @@ static void mc_handle_msi(struct irq_des
+ static void mc_msi_bottom_irq_ack(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 bitpos = data->hwirq;
+
+ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+@@ -488,8 +487,7 @@ static void mc_handle_intx(struct irq_de
+ struct mc_pcie *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long status;
+ u32 bit;
+ int ret;
+@@ -514,8 +512,7 @@ static void mc_handle_intx(struct irq_de
+ static void mc_ack_intx_irq(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+
+ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+@@ -524,8 +521,7 @@ static void mc_ack_intx_irq(struct irq_d
+ static void mc_mask_intx_irq(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+ u32 val;
+@@ -540,8 +536,7 @@ static void mc_mask_intx_irq(struct irq_
+ static void mc_unmask_intx_irq(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+ u32 val;
+@@ -896,8 +891,7 @@ static void mc_pcie_setup_window(void __
+ static int mc_pcie_setup_windows(struct platform_device *pdev,
+ struct mc_pcie *port)
+ {
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+ struct resource_entry *entry;
+ u64 pci_addr;
+@@ -1081,6 +1075,7 @@ static int mc_host_probe(struct platform
+ mc_disable_interrupts(port);
+
+ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ port->bridge_addr = bridge_base_addr;
+
+ /* Allow enabling MSI by disabling MSI-X */
+ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
diff --git a/target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch b/target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch
new file mode 100644
index 0000000000..a9e7b8975b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch
@@ -0,0 +1,347 @@
+From 7c1c679bdd0b6b727248edbee77836024c935f91 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:55 +0800
+Subject: [PATCH 018/116] PCI: microchip: Rename two PCIe data structures
+
+Add PLDA PCIe related data structures by rename data structure name from
+mc_* to plda_*.
+
+axi_base_addr is stayed in struct mc_pcie for it's microchip its own data.
+
+The event interrupt codes is still using struct mc_pcie because the event
+interrupt codes can not be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 96 ++++++++++---------
+ 1 file changed, 53 insertions(+), 43 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -22,7 +22,7 @@
+ #include "pcie-plda.h"
+
+ /* Number of MSI IRQs */
+-#define MC_MAX_NUM_MSI_IRQS 32
++#define PLDA_MAX_NUM_MSI_IRQS 32
+
+ /* PCIe Bridge Phy and Controller Phy offsets */
+ #define MC_PCIE1_BRIDGE_ADDR 0x00008000u
+@@ -179,25 +179,29 @@ struct event_map {
+ u32 event_bit;
+ };
+
+-struct mc_msi {
++struct plda_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+ struct irq_domain *dev_domain;
+ u32 num_vectors;
+ u64 vector_phy;
+- DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
++ DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
+ };
+
+-struct mc_pcie {
+- void __iomem *axi_base_addr;
++struct plda_pcie_rp {
+ struct device *dev;
+ struct irq_domain *intx_domain;
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+- struct mc_msi msi;
++ struct plda_msi msi;
+ void __iomem *bridge_addr;
+ };
+
++struct mc_pcie {
++ struct plda_pcie_rp plda;
++ void __iomem *axi_base_addr;
++};
++
+ struct cause {
+ const char *sym;
+ const char *str;
+@@ -313,7 +317,7 @@ static struct mc_pcie *port;
+
+ static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
+ {
+- struct mc_msi *msi = &port->msi;
++ struct plda_msi *msi = &port->plda.msi;
+ u16 reg;
+ u8 queue_size;
+
+@@ -336,10 +340,10 @@ static void mc_pcie_enable_msi(struct mc
+
+ static void mc_handle_msi(struct irq_desc *desc)
+ {
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+- struct mc_msi *msi = &port->msi;
++ struct plda_msi *msi = &port->msi;
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long status;
+ u32 bit;
+@@ -364,7 +368,7 @@ static void mc_handle_msi(struct irq_des
+
+ static void mc_msi_bottom_irq_ack(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 bitpos = data->hwirq;
+
+@@ -373,7 +377,7 @@ static void mc_msi_bottom_irq_ack(struct
+
+ static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ phys_addr_t addr = port->msi.vector_phy;
+
+ msg->address_lo = lower_32_bits(addr);
+@@ -400,8 +404,8 @@ static struct irq_chip mc_msi_bottom_irq
+ static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs, void *args)
+ {
+- struct mc_pcie *port = domain->host_data;
+- struct mc_msi *msi = &port->msi;
++ struct plda_pcie_rp *port = domain->host_data;
++ struct plda_msi *msi = &port->msi;
+ unsigned long bit;
+
+ mutex_lock(&msi->lock);
+@@ -425,8 +429,8 @@ static void mc_irq_msi_domain_free(struc
+ unsigned int nr_irqs)
+ {
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+- struct mc_pcie *port = irq_data_get_irq_chip_data(d);
+- struct mc_msi *msi = &port->msi;
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
++ struct plda_msi *msi = &port->msi;
+
+ mutex_lock(&msi->lock);
+
+@@ -456,11 +460,11 @@ static struct msi_domain_info mc_msi_dom
+ .chip = &mc_msi_irq_chip,
+ };
+
+-static int mc_allocate_msi_domains(struct mc_pcie *port)
++static int mc_allocate_msi_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+- struct mc_msi *msi = &port->msi;
++ struct plda_msi *msi = &port->msi;
+
+ mutex_init(&port->msi.lock);
+
+@@ -484,7 +488,7 @@ static int mc_allocate_msi_domains(struc
+
+ static void mc_handle_intx(struct irq_desc *desc)
+ {
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -511,7 +515,7 @@ static void mc_handle_intx(struct irq_de
+
+ static void mc_ack_intx_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+
+@@ -520,7 +524,7 @@ static void mc_ack_intx_irq(struct irq_d
+
+ static void mc_mask_intx_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+@@ -535,7 +539,7 @@ static void mc_mask_intx_irq(struct irq_
+
+ static void mc_unmask_intx_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+@@ -625,21 +629,22 @@ static u32 local_events(struct mc_pcie *
+ return val;
+ }
+
+-static u32 get_events(struct mc_pcie *port)
++static u32 get_events(struct plda_pcie_rp *port)
+ {
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 events = 0;
+
+- events |= pcie_events(port);
+- events |= sec_errors(port);
+- events |= ded_errors(port);
+- events |= local_events(port);
++ events |= pcie_events(mc_port);
++ events |= sec_errors(mc_port);
++ events |= ded_errors(mc_port);
++ events |= local_events(mc_port);
+
+ return events;
+ }
+
+ static irqreturn_t mc_event_handler(int irq, void *dev_id)
+ {
+- struct mc_pcie *port = dev_id;
++ struct plda_pcie_rp *port = dev_id;
+ struct device *dev = port->dev;
+ struct irq_data *data;
+
+@@ -655,7 +660,7 @@ static irqreturn_t mc_event_handler(int
+
+ static void mc_handle_event(struct irq_desc *desc)
+ {
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ unsigned long events;
+ u32 bit;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+@@ -672,12 +677,13 @@ static void mc_handle_event(struct irq_d
+
+ static void mc_ack_event_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 event = data->hwirq;
+ void __iomem *addr;
+ u32 mask;
+
+- addr = port->axi_base_addr + event_descs[event].base +
++ addr = mc_port->axi_base_addr + event_descs[event].base +
+ event_descs[event].offset;
+ mask = event_descs[event].mask;
+ mask |= event_descs[event].enb_mask;
+@@ -687,13 +693,14 @@ static void mc_ack_event_irq(struct irq_
+
+ static void mc_mask_event_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 event = data->hwirq;
+ void __iomem *addr;
+ u32 mask;
+ u32 val;
+
+- addr = port->axi_base_addr + event_descs[event].base +
++ addr = mc_port->axi_base_addr + event_descs[event].base +
+ event_descs[event].mask_offset;
+ mask = event_descs[event].mask;
+ if (event_descs[event].enb_mask) {
+@@ -717,13 +724,14 @@ static void mc_mask_event_irq(struct irq
+
+ static void mc_unmask_event_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 event = data->hwirq;
+ void __iomem *addr;
+ u32 mask;
+ u32 val;
+
+- addr = port->axi_base_addr + event_descs[event].base +
++ addr = mc_port->axi_base_addr + event_descs[event].base +
+ event_descs[event].mask_offset;
+ mask = event_descs[event].mask;
+
+@@ -811,7 +819,7 @@ static int mc_pcie_init_clks(struct devi
+ return 0;
+ }
+
+-static int mc_pcie_init_irq_domains(struct mc_pcie *port)
++static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct device_node *node = dev->of_node;
+@@ -889,7 +897,7 @@ static void mc_pcie_setup_window(void __
+ }
+
+ static int mc_pcie_setup_windows(struct platform_device *pdev,
+- struct mc_pcie *port)
++ struct plda_pcie_rp *port)
+ {
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+@@ -970,7 +978,7 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int mc_init_interrupts(struct platform_device *pdev, struct mc_pcie *port)
++static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+@@ -1043,12 +1051,12 @@ static int mc_platform_init(struct pci_c
+ mc_pcie_enable_msi(port, cfg->win);
+
+ /* Configure non-config space outbound ranges */
+- ret = mc_pcie_setup_windows(pdev, port);
++ ret = mc_pcie_setup_windows(pdev, &port->plda);
+ if (ret)
+ return ret;
+
+ /* Address translation is up; safe to enable interrupts */
+- ret = mc_init_interrupts(pdev, port);
++ ret = mc_init_interrupts(pdev, &port->plda);
+ if (ret)
+ return ret;
+
+@@ -1059,6 +1067,7 @@ static int mc_host_probe(struct platform
+ {
+ struct device *dev = &pdev->dev;
+ void __iomem *bridge_base_addr;
++ struct plda_pcie_rp *plda;
+ int ret;
+ u32 val;
+
+@@ -1066,7 +1075,8 @@ static int mc_host_probe(struct platform
+ if (!port)
+ return -ENOMEM;
+
+- port->dev = dev;
++ plda = &port->plda;
++ plda->dev = dev;
+
+ port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(port->axi_base_addr))
+@@ -1075,7 +1085,7 @@ static int mc_host_probe(struct platform
+ mc_disable_interrupts(port);
+
+ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- port->bridge_addr = bridge_base_addr;
++ plda->bridge_addr = bridge_base_addr;
+
+ /* Allow enabling MSI by disabling MSI-X */
+ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+@@ -1087,10 +1097,10 @@ static int mc_host_probe(struct platform
+ val &= NUM_MSI_MSGS_MASK;
+ val >>= NUM_MSI_MSGS_SHIFT;
+
+- port->msi.num_vectors = 1 << val;
++ plda->msi.num_vectors = 1 << val;
+
+ /* Pick vector address from design */
+- port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
++ plda->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
+
+ ret = mc_pcie_init_clks(dev);
+ if (ret) {
diff --git a/target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch b/target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch
new file mode 100644
index 0000000000..0823502cfd
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch
@@ -0,0 +1,87 @@
+From a53cf9b237dd53c9538b51a8df592888935c8411 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:56 +0800
+Subject: [PATCH 019/116] PCI: microchip: Move PCIe host data structures to
+ plda-pcie.h
+
+Move the common data structures definition to head file for these two data
+structures can be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 20 ------------------
+ drivers/pci/controller/plda/pcie-plda.h | 21 +++++++++++++++++++
+ 2 files changed, 21 insertions(+), 20 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -21,9 +21,6 @@
+ #include "../../pci.h"
+ #include "pcie-plda.h"
+
+-/* Number of MSI IRQs */
+-#define PLDA_MAX_NUM_MSI_IRQS 32
+-
+ /* PCIe Bridge Phy and Controller Phy offsets */
+ #define MC_PCIE1_BRIDGE_ADDR 0x00008000u
+ #define MC_PCIE1_CTRL_ADDR 0x0000a000u
+@@ -179,23 +176,6 @@ struct event_map {
+ u32 event_bit;
+ };
+
+-struct plda_msi {
+- struct mutex lock; /* Protect used bitmap */
+- struct irq_domain *msi_domain;
+- struct irq_domain *dev_domain;
+- u32 num_vectors;
+- u64 vector_phy;
+- DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
+-};
+-
+-struct plda_pcie_rp {
+- struct device *dev;
+- struct irq_domain *intx_domain;
+- struct irq_domain *event_domain;
+- raw_spinlock_t lock;
+- struct plda_msi msi;
+- void __iomem *bridge_addr;
+-};
+
+ struct mc_pcie {
+ struct plda_pcie_rp plda;
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -6,6 +6,9 @@
+ #ifndef _PCIE_PLDA_H
+ #define _PCIE_PLDA_H
+
++/* Number of MSI IRQs */
++#define PLDA_MAX_NUM_MSI_IRQS 32
++
+ /* PCIe Bridge Phy Regs */
+ #define PCIE_PCI_IRQ_DW0 0xa8
+ #define MSIX_CAP_MASK BIT(31)
+@@ -105,4 +108,22 @@ enum plda_int_event {
+
+ #define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
+
++struct plda_msi {
++ struct mutex lock; /* Protect used bitmap */
++ struct irq_domain *msi_domain;
++ struct irq_domain *dev_domain;
++ u32 num_vectors;
++ u64 vector_phy;
++ DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
++};
++
++struct plda_pcie_rp {
++ struct device *dev;
++ struct irq_domain *intx_domain;
++ struct irq_domain *event_domain;
++ raw_spinlock_t lock;
++ struct plda_msi msi;
++ void __iomem *bridge_addr;
++};
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch b/target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch
new file mode 100644
index 0000000000..2bed600216
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch
@@ -0,0 +1,76 @@
+From d0e56d1ef7398bbf76be6e48d77943cbf644688e Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:57 +0800
+Subject: [PATCH 020/116] PCI: microchip: Rename two setup functions
+
+Rename two setup functions to plda prefix. Prepare to re-use these two
+setup function.
+
+For two setup functions names are similar, rename mc_pcie_setup_windows()
+to plda_pcie_setup_iomems().
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 24 +++++++++----------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -838,9 +838,9 @@ static int mc_pcie_init_irq_domains(stru
+ return mc_allocate_msi_domains(port);
+ }
+
+-static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+- phys_addr_t axi_addr, phys_addr_t pci_addr,
+- size_t size)
++static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size)
+ {
+ u32 atr_sz = ilog2(size) - 1;
+ u32 val;
+@@ -876,8 +876,8 @@ static void mc_pcie_setup_window(void __
+ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+ }
+
+-static int mc_pcie_setup_windows(struct platform_device *pdev,
+- struct plda_pcie_rp *port)
++static int plda_pcie_setup_iomems(struct platform_device *pdev,
++ struct plda_pcie_rp *port)
+ {
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+@@ -888,9 +888,9 @@ static int mc_pcie_setup_windows(struct
+ resource_list_for_each_entry(entry, &bridge->windows) {
+ if (resource_type(entry->res) == IORESOURCE_MEM) {
+ pci_addr = entry->res->start - entry->offset;
+- mc_pcie_setup_window(bridge_base_addr, index,
+- entry->res->start, pci_addr,
+- resource_size(entry->res));
++ plda_pcie_setup_window(bridge_base_addr, index,
++ entry->res->start, pci_addr,
++ resource_size(entry->res));
+ index++;
+ }
+ }
+@@ -1023,15 +1023,15 @@ static int mc_platform_init(struct pci_c
+ int ret;
+
+ /* Configure address translation table 0 for PCIe config space */
+- mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
+- cfg->res.start,
+- resource_size(&cfg->res));
++ plda_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
++ cfg->res.start,
++ resource_size(&cfg->res));
+
+ /* Need some fixups in config space */
+ mc_pcie_enable_msi(port, cfg->win);
+
+ /* Configure non-config space outbound ranges */
+- ret = mc_pcie_setup_windows(pdev, &port->plda);
++ ret = plda_pcie_setup_iomems(pdev, &port->plda);
+ if (ret)
+ return ret;
+
diff --git a/target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch b/target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch
new file mode 100644
index 0000000000..de6868b9f6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch
@@ -0,0 +1,49 @@
+From 2fd7c88ef318fd39023ce1eb73f37a29fbd25d74 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:58 +0800
+Subject: [PATCH 021/116] PCI: microchip: Change the argument of
+ plda_pcie_setup_iomems()
+
+If other vendor do not select PCI_HOST_COMMON, the driver data is not
+struct pci_host_bridge.
+
+Move calling platform_get_drvdata() to mc_platform_init().
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(void
+ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+ }
+
+-static int plda_pcie_setup_iomems(struct platform_device *pdev,
++static int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
+ struct plda_pcie_rp *port)
+ {
+ void __iomem *bridge_base_addr = port->bridge_addr;
+- struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+ struct resource_entry *entry;
+ u64 pci_addr;
+ u32 index = 1;
+@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_c
+ {
+ struct device *dev = cfg->parent;
+ struct platform_device *pdev = to_platform_device(dev);
++ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+ void __iomem *bridge_base_addr =
+ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+ int ret;
+@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct pci_c
+ mc_pcie_enable_msi(port, cfg->win);
+
+ /* Configure non-config space outbound ranges */
+- ret = plda_pcie_setup_iomems(pdev, &port->plda);
++ ret = plda_pcie_setup_iomems(bridge, &port->plda);
+ if (ret)
+ return ret;
+
diff --git a/target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch b/target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch
new file mode 100644
index 0000000000..62f458be4a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch
@@ -0,0 +1,200 @@
+From 201ce99897ff5fff2612cb633406e90c1b2acbcf Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:59 +0800
+Subject: [PATCH 022/116] PCI: microchip: Move setup functions to
+ pcie-plda-host.c
+
+Move setup functions to common pcie-plda-host.c. So these two functions
+can be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/Kconfig | 4 +
+ drivers/pci/controller/plda/Makefile | 1 +
+ .../pci/controller/plda/pcie-microchip-host.c | 59 ---------------
+ drivers/pci/controller/plda/pcie-plda-host.c | 74 +++++++++++++++++++
+ drivers/pci/controller/plda/pcie-plda.h | 5 ++
+ 5 files changed, 84 insertions(+), 59 deletions(-)
+ create mode 100644 drivers/pci/controller/plda/pcie-plda-host.c
+
+--- a/drivers/pci/controller/plda/Kconfig
++++ b/drivers/pci/controller/plda/Kconfig
+@@ -3,10 +3,14 @@
+ menu "PLDA-based PCIe controllers"
+ depends on PCI
+
++config PCIE_PLDA_HOST
++ bool
++
+ config PCIE_MICROCHIP_HOST
+ tristate "Microchip AXI PCIe controller"
+ depends on PCI_MSI && OF
+ select PCI_HOST_COMMON
++ select PCIE_PLDA_HOST
+ help
+ Say Y here if you want kernel to support the Microchip AXI PCIe
+ Host Bridge driver.
+--- a/drivers/pci/controller/plda/Makefile
++++ b/drivers/pci/controller/plda/Makefile
+@@ -1,2 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o
+ obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -838,65 +838,6 @@ static int mc_pcie_init_irq_domains(stru
+ return mc_allocate_msi_domains(port);
+ }
+
+-static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+- phys_addr_t axi_addr, phys_addr_t pci_addr,
+- size_t size)
+-{
+- u32 atr_sz = ilog2(size) - 1;
+- u32 val;
+-
+- if (index == 0)
+- val = PCIE_CONFIG_INTERFACE;
+- else
+- val = PCIE_TX_RX_INTERFACE;
+-
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_PARAM);
+-
+- val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
+- ATR_IMPL_ENABLE;
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRCADDR_PARAM);
+-
+- val = upper_32_bits(axi_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRC_ADDR);
+-
+- val = lower_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
+-
+- val = upper_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
+-
+- val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
+- writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+-}
+-
+-static int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
+- struct plda_pcie_rp *port)
+-{
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- struct resource_entry *entry;
+- u64 pci_addr;
+- u32 index = 1;
+-
+- resource_list_for_each_entry(entry, &bridge->windows) {
+- if (resource_type(entry->res) == IORESOURCE_MEM) {
+- pci_addr = entry->res->start - entry->offset;
+- plda_pcie_setup_window(bridge_base_addr, index,
+- entry->res->start, pci_addr,
+- resource_size(entry->res));
+- index++;
+- }
+- }
+-
+- return 0;
+-}
+-
+ static inline void mc_clear_secs(struct mc_pcie *port)
+ {
+ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -0,0 +1,74 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * PLDA PCIe XpressRich host controller driver
++ *
++ * Copyright (C) 2023 Microchip Co. Ltd
++ *
++ * Author: Daire McNamara <daire.mcnamara@microchip.com>
++ */
++
++#include <linux/pci_regs.h>
++#include <linux/pci-ecam.h>
++
++#include "pcie-plda.h"
++
++void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size)
++{
++ u32 atr_sz = ilog2(size) - 1;
++ u32 val;
++
++ if (index == 0)
++ val = PCIE_CONFIG_INTERFACE;
++ else
++ val = PCIE_TX_RX_INTERFACE;
++
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_PARAM);
++
++ val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
++ ATR_IMPL_ENABLE;
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRCADDR_PARAM);
++
++ val = upper_32_bits(axi_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRC_ADDR);
++
++ val = lower_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
++
++ val = upper_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
++
++ val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
++ writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
++}
++EXPORT_SYMBOL_GPL(plda_pcie_setup_window);
++
++int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
++ struct plda_pcie_rp *port)
++{
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ struct resource_entry *entry;
++ u64 pci_addr;
++ u32 index = 1;
++
++ resource_list_for_each_entry(entry, &bridge->windows) {
++ if (resource_type(entry->res) == IORESOURCE_MEM) {
++ pci_addr = entry->res->start - entry->offset;
++ plda_pcie_setup_window(bridge_base_addr, index,
++ entry->res->start, pci_addr,
++ resource_size(entry->res));
++ index++;
++ }
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -126,4 +126,9 @@ struct plda_pcie_rp {
+ void __iomem *bridge_addr;
+ };
+
++void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size);
++int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
++ struct plda_pcie_rp *port);
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch b/target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch
new file mode 100644
index 0000000000..09c1633b6f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch
@@ -0,0 +1,336 @@
+From 2a48bc45dcf8cbe736b594d013cfa9d682214c43 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:00 +0800
+Subject: [PATCH 023/116] PCI: microchip: Rename interrupt related functions
+
+Rename mc_* to plda_* for IRQ functions and related IRQ domain ops data
+instances.
+
+MSI, INTx interrupt code and IRQ init code are all can be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 109 +++++++++---------
+ 1 file changed, 57 insertions(+), 52 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -318,7 +318,7 @@ static void mc_pcie_enable_msi(struct mc
+ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
+ }
+
+-static void mc_handle_msi(struct irq_desc *desc)
++static void plda_handle_msi(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+@@ -346,7 +346,7 @@ static void mc_handle_msi(struct irq_des
+ chained_irq_exit(chip, desc);
+ }
+
+-static void mc_msi_bottom_irq_ack(struct irq_data *data)
++static void plda_msi_bottom_irq_ack(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -355,7 +355,7 @@ static void mc_msi_bottom_irq_ack(struct
+ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+ }
+
+-static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
++static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ phys_addr_t addr = port->msi.vector_phy;
+@@ -368,21 +368,23 @@ static void mc_compose_msi_msg(struct ir
+ (int)data->hwirq, msg->address_hi, msg->address_lo);
+ }
+
+-static int mc_msi_set_affinity(struct irq_data *irq_data,
+- const struct cpumask *mask, bool force)
++static int plda_msi_set_affinity(struct irq_data *irq_data,
++ const struct cpumask *mask, bool force)
+ {
+ return -EINVAL;
+ }
+
+-static struct irq_chip mc_msi_bottom_irq_chip = {
+- .name = "Microchip MSI",
+- .irq_ack = mc_msi_bottom_irq_ack,
+- .irq_compose_msi_msg = mc_compose_msi_msg,
+- .irq_set_affinity = mc_msi_set_affinity,
++static struct irq_chip plda_msi_bottom_irq_chip = {
++ .name = "PLDA MSI",
++ .irq_ack = plda_msi_bottom_irq_ack,
++ .irq_compose_msi_msg = plda_compose_msi_msg,
++ .irq_set_affinity = plda_msi_set_affinity,
+ };
+
+-static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs, void *args)
++static int plda_irq_msi_domain_alloc(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs,
++ void *args)
+ {
+ struct plda_pcie_rp *port = domain->host_data;
+ struct plda_msi *msi = &port->msi;
+@@ -397,7 +399,7 @@ static int mc_irq_msi_domain_alloc(struc
+
+ set_bit(bit, msi->used);
+
+- irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
++ irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,
+ domain->host_data, handle_edge_irq, NULL, NULL);
+
+ mutex_unlock(&msi->lock);
+@@ -405,8 +407,9 @@ static int mc_irq_msi_domain_alloc(struc
+ return 0;
+ }
+
+-static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs)
++static void plda_irq_msi_domain_free(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs)
+ {
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
+@@ -423,24 +426,24 @@ static void mc_irq_msi_domain_free(struc
+ }
+
+ static const struct irq_domain_ops msi_domain_ops = {
+- .alloc = mc_irq_msi_domain_alloc,
+- .free = mc_irq_msi_domain_free,
++ .alloc = plda_irq_msi_domain_alloc,
++ .free = plda_irq_msi_domain_free,
+ };
+
+-static struct irq_chip mc_msi_irq_chip = {
+- .name = "Microchip PCIe MSI",
++static struct irq_chip plda_msi_irq_chip = {
++ .name = "PLDA PCIe MSI",
+ .irq_ack = irq_chip_ack_parent,
+ .irq_mask = pci_msi_mask_irq,
+ .irq_unmask = pci_msi_unmask_irq,
+ };
+
+-static struct msi_domain_info mc_msi_domain_info = {
++static struct msi_domain_info plda_msi_domain_info = {
+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+ MSI_FLAG_PCI_MSIX),
+- .chip = &mc_msi_irq_chip,
++ .chip = &plda_msi_irq_chip,
+ };
+
+-static int mc_allocate_msi_domains(struct plda_pcie_rp *port)
++static int plda_allocate_msi_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+@@ -455,7 +458,8 @@ static int mc_allocate_msi_domains(struc
+ return -ENOMEM;
+ }
+
+- msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
++ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
++ &plda_msi_domain_info,
+ msi->dev_domain);
+ if (!msi->msi_domain) {
+ dev_err(dev, "failed to create MSI domain\n");
+@@ -466,7 +470,7 @@ static int mc_allocate_msi_domains(struc
+ return 0;
+ }
+
+-static void mc_handle_intx(struct irq_desc *desc)
++static void plda_handle_intx(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+@@ -493,7 +497,7 @@ static void mc_handle_intx(struct irq_de
+ chained_irq_exit(chip, desc);
+ }
+
+-static void mc_ack_intx_irq(struct irq_data *data)
++static void plda_ack_intx_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -502,7 +506,7 @@ static void mc_ack_intx_irq(struct irq_d
+ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+ }
+
+-static void mc_mask_intx_irq(struct irq_data *data)
++static void plda_mask_intx_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -517,7 +521,7 @@ static void mc_mask_intx_irq(struct irq_
+ raw_spin_unlock_irqrestore(&port->lock, flags);
+ }
+
+-static void mc_unmask_intx_irq(struct irq_data *data)
++static void plda_unmask_intx_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -532,24 +536,24 @@ static void mc_unmask_intx_irq(struct ir
+ raw_spin_unlock_irqrestore(&port->lock, flags);
+ }
+
+-static struct irq_chip mc_intx_irq_chip = {
+- .name = "Microchip PCIe INTx",
+- .irq_ack = mc_ack_intx_irq,
+- .irq_mask = mc_mask_intx_irq,
+- .irq_unmask = mc_unmask_intx_irq,
++static struct irq_chip plda_intx_irq_chip = {
++ .name = "PLDA PCIe INTx",
++ .irq_ack = plda_ack_intx_irq,
++ .irq_mask = plda_mask_intx_irq,
++ .irq_unmask = plda_unmask_intx_irq,
+ };
+
+-static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
++static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
+ {
+- irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
++ irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, domain->host_data);
+
+ return 0;
+ }
+
+ static const struct irq_domain_ops intx_domain_ops = {
+- .map = mc_pcie_intx_map,
++ .map = plda_pcie_intx_map,
+ };
+
+ static inline u32 reg_to_event(u32 reg, struct event_map field)
+@@ -609,7 +613,7 @@ static u32 local_events(struct mc_pcie *
+ return val;
+ }
+
+-static u32 get_events(struct plda_pcie_rp *port)
++static u32 mc_get_events(struct plda_pcie_rp *port)
+ {
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 events = 0;
+@@ -638,7 +642,7 @@ static irqreturn_t mc_event_handler(int
+ return IRQ_HANDLED;
+ }
+
+-static void mc_handle_event(struct irq_desc *desc)
++static void plda_handle_event(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ unsigned long events;
+@@ -647,7 +651,7 @@ static void mc_handle_event(struct irq_d
+
+ chained_irq_enter(chip, desc);
+
+- events = get_events(port);
++ events = mc_get_events(port);
+
+ for_each_set_bit(bit, &events, NUM_EVENTS)
+ generic_handle_domain_irq(port->event_domain, bit);
+@@ -741,8 +745,8 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
+-static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
++static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
+ {
+ irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, domain->host_data);
+@@ -750,8 +754,8 @@ static int mc_pcie_event_map(struct irq_
+ return 0;
+ }
+
+-static const struct irq_domain_ops event_domain_ops = {
+- .map = mc_pcie_event_map,
++static const struct irq_domain_ops plda_event_domain_ops = {
++ .map = plda_pcie_event_map,
+ };
+
+ static inline void mc_pcie_deinit_clk(void *data)
+@@ -799,7 +803,7 @@ static int mc_pcie_init_clks(struct devi
+ return 0;
+ }
+
+-static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)
++static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct device_node *node = dev->of_node;
+@@ -813,7 +817,8 @@ static int mc_pcie_init_irq_domains(stru
+ }
+
+ port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
+- &event_domain_ops, port);
++ &plda_event_domain_ops,
++ port);
+ if (!port->event_domain) {
+ dev_err(dev, "failed to get event domain\n");
+ of_node_put(pcie_intc_node);
+@@ -835,7 +840,7 @@ static int mc_pcie_init_irq_domains(stru
+ of_node_put(pcie_intc_node);
+ raw_spin_lock_init(&port->lock);
+
+- return mc_allocate_msi_domains(port);
++ return plda_allocate_msi_domains(port);
+ }
+
+ static inline void mc_clear_secs(struct mc_pcie *port)
+@@ -898,14 +903,14 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
++static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+ int i, intx_irq, msi_irq, event_irq;
+ int ret;
+
+- ret = mc_pcie_init_irq_domains(port);
++ ret = plda_pcie_init_irq_domains(port);
+ if (ret) {
+ dev_err(dev, "failed creating IRQ domains\n");
+ return ret;
+@@ -938,7 +943,7 @@ static int mc_init_interrupts(struct pla
+ }
+
+ /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, mc_handle_intx, port);
++ irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
+
+ msi_irq = irq_create_mapping(port->event_domain,
+ EVENT_LOCAL_PM_MSI_INT_MSI);
+@@ -946,10 +951,10 @@ static int mc_init_interrupts(struct pla
+ return -ENXIO;
+
+ /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
++ irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
+
+ /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, mc_handle_event, port);
++ irq_set_chained_handler_and_data(irq, plda_handle_event, port);
+
+ return 0;
+ }
+@@ -977,7 +982,7 @@ static int mc_platform_init(struct pci_c
+ return ret;
+
+ /* Address translation is up; safe to enable interrupts */
+- ret = mc_init_interrupts(pdev, &port->plda);
++ ret = plda_init_interrupts(pdev, &port->plda);
+ if (ret)
+ return ret;
+
diff --git a/target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch b/target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch
new file mode 100644
index 0000000000..4071feb1b5
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch
@@ -0,0 +1,65 @@
+From ab04dadb45a4150c9fd55b97fdd7397f4739a629 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:01 +0800
+Subject: [PATCH 024/116] PCI: microchip: Add num_events field to struct
+ plda_pcie_rp
+
+The number of events is different across platforms. In order to share
+interrupt processing code, add a variable that defines the number of
+events so that it can be set per-platform instead of hardcoding it.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 8 +++++---
+ drivers/pci/controller/plda/pcie-plda.h | 1 +
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -653,7 +653,7 @@ static void plda_handle_event(struct irq
+
+ events = mc_get_events(port);
+
+- for_each_set_bit(bit, &events, NUM_EVENTS)
++ for_each_set_bit(bit, &events, port->num_events)
+ generic_handle_domain_irq(port->event_domain, bit);
+
+ chained_irq_exit(chip, desc);
+@@ -816,7 +816,8 @@ static int plda_pcie_init_irq_domains(st
+ return -EINVAL;
+ }
+
+- port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
++ port->event_domain = irq_domain_add_linear(pcie_intc_node,
++ port->num_events,
+ &plda_event_domain_ops,
+ port);
+ if (!port->event_domain) {
+@@ -920,7 +921,7 @@ static int plda_init_interrupts(struct p
+ if (irq < 0)
+ return -ENODEV;
+
+- for (i = 0; i < NUM_EVENTS; i++) {
++ for (i = 0; i < port->num_events; i++) {
+ event_irq = irq_create_mapping(port->event_domain, i);
+ if (!event_irq) {
+ dev_err(dev, "failed to map hwirq %d\n", i);
+@@ -1012,6 +1013,7 @@ static int mc_host_probe(struct platform
+
+ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+ plda->bridge_addr = bridge_base_addr;
++ plda->num_events = NUM_EVENTS;
+
+ /* Allow enabling MSI by disabling MSI-X */
+ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -124,6 +124,7 @@ struct plda_pcie_rp {
+ raw_spinlock_t lock;
+ struct plda_msi msi;
+ void __iomem *bridge_addr;
++ int num_events;
+ };
+
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
diff --git a/target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch b/target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch
new file mode 100644
index 0000000000..2b299e01e9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch
@@ -0,0 +1,114 @@
+From 9f202f211cc79eefecbb03715c884e54eb95a62c Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:02 +0800
+Subject: [PATCH 025/116] PCI: microchip: Add request_event_irq() callback
+ function
+
+As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
+plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
+controller. Microchip Polarfire PCIe add some PCIe interrupts base on
+PLDA IP interrupt controller.
+
+Microchip Polarfire PCIe additional intrerrupts:
+EVENT_PCIE_L2_EXIT
+EVENT_PCIE_HOTRST_EXIT
+EVENT_PCIE_DLUP_EXIT
+EVENT_SEC_TX_RAM_SEC_ERR
+EVENT_SEC_RX_RAM_SEC_ERR
+....
+
+Both codes of register interrupts and mc_event_handler() contain
+additional interrupts symbol names, these can not be re-used. So add a
+new plda_event_handler() functions, which implements PLDA interrupt
+defalt handler. Add request_event_irq() callback function to
+compat Microchip Polorfire PCIe additional interrupts.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 31 ++++++++++++++++---
+ drivers/pci/controller/plda/pcie-plda.h | 5 +++
+ 2 files changed, 32 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -642,6 +642,11 @@ static irqreturn_t mc_event_handler(int
+ return IRQ_HANDLED;
+ }
+
++static irqreturn_t plda_event_handler(int irq, void *dev_id)
++{
++ return IRQ_HANDLED;
++}
++
+ static void plda_handle_event(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+@@ -803,6 +808,17 @@ static int mc_pcie_init_clks(struct devi
+ return 0;
+ }
+
++static int mc_request_event_irq(struct plda_pcie_rp *plda, int event_irq,
++ int event)
++{
++ return devm_request_irq(plda->dev, event_irq, mc_event_handler,
++ 0, event_cause[event].sym, plda);
++}
++
++static const struct plda_event mc_event = {
++ .request_event_irq = mc_request_event_irq,
++};
++
+ static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+@@ -904,7 +920,9 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
++static int plda_init_interrupts(struct platform_device *pdev,
++ struct plda_pcie_rp *port,
++ const struct plda_event *event)
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+@@ -928,8 +946,13 @@ static int plda_init_interrupts(struct p
+ return -ENXIO;
+ }
+
+- ret = devm_request_irq(dev, event_irq, mc_event_handler,
+- 0, event_cause[i].sym, port);
++ if (event->request_event_irq)
++ ret = event->request_event_irq(port, event_irq, i);
++ else
++ ret = devm_request_irq(dev, event_irq,
++ plda_event_handler,
++ 0, NULL, port);
++
+ if (ret) {
+ dev_err(dev, "failed to request IRQ %d\n", event_irq);
+ return ret;
+@@ -983,7 +1006,7 @@ static int mc_platform_init(struct pci_c
+ return ret;
+
+ /* Address translation is up; safe to enable interrupts */
+- ret = plda_init_interrupts(pdev, &port->plda);
++ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+ if (ret)
+ return ret;
+
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -127,6 +127,11 @@ struct plda_pcie_rp {
+ int num_events;
+ };
+
++struct plda_event {
++ int (*request_event_irq)(struct plda_pcie_rp *pcie,
++ int event_irq, int event);
++};
++
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
+ size_t size);
diff --git a/target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch b/target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch
new file mode 100644
index 0000000000..85b8143268
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch
@@ -0,0 +1,56 @@
+From 3cdc20d9cc029ba9444be111bf4e55fd5331ccbe Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:03 +0800
+Subject: [PATCH 026/116] PCI: microchip: Add INTx and MSI event num to struct
+ plda_event
+
+The INTx and MSI interrupt event num is different in Microchip and
+StarFive platform.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 6 ++++--
+ drivers/pci/controller/plda/pcie-plda.h | 2 ++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -817,6 +817,8 @@ static int mc_request_event_irq(struct p
+
+ static const struct plda_event mc_event = {
+ .request_event_irq = mc_request_event_irq,
++ .intx_event = EVENT_LOCAL_PM_MSI_INT_INTX,
++ .msi_event = EVENT_LOCAL_PM_MSI_INT_MSI,
+ };
+
+ static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+@@ -960,7 +962,7 @@ static int plda_init_interrupts(struct p
+ }
+
+ intx_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_INTX);
++ event->intx_event);
+ if (!intx_irq) {
+ dev_err(dev, "failed to map INTx interrupt\n");
+ return -ENXIO;
+@@ -970,7 +972,7 @@ static int plda_init_interrupts(struct p
+ irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
+
+ msi_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_MSI);
++ event->msi_event);
+ if (!msi_irq)
+ return -ENXIO;
+
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -130,6 +130,8 @@ struct plda_pcie_rp {
+ struct plda_event {
+ int (*request_event_irq)(struct plda_pcie_rp *pcie,
+ int event_irq, int event);
++ int intx_event;
++ int msi_event;
+ };
+
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
diff --git a/target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch b/target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch
new file mode 100644
index 0000000000..a0cb4789b8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch
@@ -0,0 +1,167 @@
+From b4a38ef87661f21fe2fb3e085ae98f25f78aaf99 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:04 +0800
+Subject: [PATCH 027/116] PCI: microchip: Add get_events() callback and add
+ PLDA get_event()
+
+As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
+plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
+controller.
+
+PolarFire implements its own PCIe interrupts, additional to the regular
+PCIe interrupts, due to lack of an MSI controller, so the interrupt to
+event number mapping is different to the PLDA regular interrupts,
+necessitating a custom get_events() implementation.
+
+Microchip Polarfire PCIe additional intrerrupts:
+EVENT_PCIE_L2_EXIT
+EVENT_PCIE_HOTRST_EXIT
+EVENT_PCIE_DLUP_EXIT
+EVENT_SEC_TX_RAM_SEC_ERR
+EVENT_SEC_RX_RAM_SEC_ERR
+....
+
+plda_get_events() adds interrupt register to PLDA local event num mapping
+codes. All The PLDA interrupts can be seen in new added graph.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 35 ++++++++++++++++++-
+ drivers/pci/controller/plda/pcie-plda.h | 32 +++++++++++++++++
+ 2 files changed, 66 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -626,6 +626,26 @@ static u32 mc_get_events(struct plda_pci
+ return events;
+ }
+
++static u32 plda_get_events(struct plda_pcie_rp *port)
++{
++ u32 events, val, origin;
++
++ origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
++
++ /* MSI event and sys events */
++ val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;
++ events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);
++
++ /* INTx events */
++ if (origin & PM_MSI_INT_INTX_MASK)
++ events |= BIT(PM_MSI_INT_INTX_SHIFT);
++
++ /* remains are same with register */
++ events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);
++
++ return events;
++}
++
+ static irqreturn_t mc_event_handler(int irq, void *dev_id)
+ {
+ struct plda_pcie_rp *port = dev_id;
+@@ -656,7 +676,7 @@ static void plda_handle_event(struct irq
+
+ chained_irq_enter(chip, desc);
+
+- events = mc_get_events(port);
++ events = port->event_ops->get_events(port);
+
+ for_each_set_bit(bit, &events, port->num_events)
+ generic_handle_domain_irq(port->event_domain, bit);
+@@ -750,6 +770,10 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
++static const struct plda_event_ops plda_event_ops = {
++ .get_events = plda_get_events,
++};
++
+ static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+ {
+@@ -815,6 +839,10 @@ static int mc_request_event_irq(struct p
+ 0, event_cause[event].sym, plda);
+ }
+
++static const struct plda_event_ops mc_event_ops = {
++ .get_events = mc_get_events,
++};
++
+ static const struct plda_event mc_event = {
+ .request_event_irq = mc_request_event_irq,
+ .intx_event = EVENT_LOCAL_PM_MSI_INT_INTX,
+@@ -931,6 +959,9 @@ static int plda_init_interrupts(struct p
+ int i, intx_irq, msi_irq, event_irq;
+ int ret;
+
++ if (!port->event_ops)
++ port->event_ops = &plda_event_ops;
++
+ ret = plda_pcie_init_irq_domains(port);
+ if (ret) {
+ dev_err(dev, "failed creating IRQ domains\n");
+@@ -1007,6 +1038,8 @@ static int mc_platform_init(struct pci_c
+ if (ret)
+ return ret;
+
++ port->plda.event_ops = &mc_event_ops;
++
+ /* Address translation is up; safe to enable interrupts */
+ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+ if (ret)
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -58,6 +58,7 @@
+ #define PM_MSI_INT_EVENTS_SHIFT 30
+ #define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
+ #define PM_MSI_INT_SYS_ERR_SHIFT 31
++#define SYS_AND_MSI_MASK GENMASK(31, 28)
+ #define NUM_LOCAL_EVENTS 15
+ #define ISTATUS_LOCAL 0x184
+ #define IMASK_HOST 0x188
+@@ -108,6 +109,36 @@ enum plda_int_event {
+
+ #define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
+
++/*
++ * PLDA interrupt register
++ *
++ * 31 27 23 15 7 0
++ * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+
++ * |12|11|10|9| intx |7|6|5|4|3|2|1|0| DMA error | DMA end |
++ * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+
++ * bit 0-7 DMA interrupt end : reserved for vendor implement
++ * bit 8-15 DMA error : reserved for vendor implement
++ * 0: AXI post error (PLDA_AXI_POST_ERR)
++ * 1: AXI fetch error (PLDA_AXI_FETCH_ERR)
++ * 2: AXI discard error (PLDA_AXI_DISCARD_ERR)
++ * 3: AXI doorbell (PLDA_PCIE_DOORBELL)
++ * 4: PCIe post error (PLDA_PCIE_POST_ERR)
++ * 5: PCIe fetch error (PLDA_PCIE_FETCH_ERR)
++ * 6: PCIe discard error (PLDA_PCIE_DISCARD_ERR)
++ * 7: PCIe doorbell (PLDA_PCIE_DOORBELL)
++ * 8: 4 INTx interruts (PLDA_INTX)
++ * 9: MSI interrupt (PLDA_MSI)
++ * 10: AER event (PLDA_AER_EVENT)
++ * 11: PM/LTR/Hotplug (PLDA_MISC_EVENTS)
++ * 12: System error (PLDA_SYS_ERR)
++ */
++
++struct plda_pcie_rp;
++
++struct plda_event_ops {
++ u32 (*get_events)(struct plda_pcie_rp *pcie);
++};
++
+ struct plda_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+@@ -123,6 +154,7 @@ struct plda_pcie_rp {
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+ struct plda_msi msi;
++ const struct plda_event_ops *event_ops;
+ void __iomem *bridge_addr;
+ int num_events;
+ };
diff --git a/target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch b/target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch
new file mode 100644
index 0000000000..9ed8119b1e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch
@@ -0,0 +1,144 @@
+From 229ea8e7b674eb5c9bc4f70d43df1bd02a79862a Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:05 +0800
+Subject: [PATCH 028/116] PCI: microchip: Add event irqchip field to host port
+ and add PLDA irqchip
+
+As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
+plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
+controller.
+
+Microchip PolarFire PCIE event IRQs includes PLDA interrupts and
+Polarfire their own interrupts. The interrupt irqchip ops includes
+ack/mask/unmask interrupt ops, which will write correct registers.
+Microchip Polarfire PCIe additional interrupts require to write Polarfire
+SoC self-defined registers. So Microchip PCIe event irqchip ops can not
+be re-used.
+
+To support PLDA its own event IRQ process, implements PLDA irqchip ops and
+add event irqchip field to struct pcie_plda_rp.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 66 ++++++++++++++++++-
+ drivers/pci/controller/plda/pcie-plda.h | 5 +-
+ 2 files changed, 69 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -770,6 +770,64 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
++static u32 plda_hwirq_to_mask(int hwirq)
++{
++ u32 mask;
++
++ /* hwirq 23 - 0 are the same with register */
++ if (hwirq < EVENT_PM_MSI_INT_INTX)
++ mask = BIT(hwirq);
++ else if (hwirq == EVENT_PM_MSI_INT_INTX)
++ mask = PM_MSI_INT_INTX_MASK;
++ else
++ mask = BIT(hwirq + PCI_NUM_INTX - 1);
++
++ return mask;
++}
++
++static void plda_ack_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++
++ writel_relaxed(plda_hwirq_to_mask(data->hwirq),
++ port->bridge_addr + ISTATUS_LOCAL);
++}
++
++static void plda_mask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static void plda_unmask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static struct irq_chip plda_event_irq_chip = {
++ .name = "PLDA PCIe EVENT",
++ .irq_ack = plda_ack_event_irq,
++ .irq_mask = plda_mask_event_irq,
++ .irq_unmask = plda_unmask_event_irq,
++};
++
+ static const struct plda_event_ops plda_event_ops = {
+ .get_events = plda_get_events,
+ };
+@@ -777,7 +835,9 @@ static const struct plda_event_ops plda_
+ static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+ {
+- irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
++ struct plda_pcie_rp *port = (void *)domain->host_data;
++
++ irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, domain->host_data);
+
+ return 0;
+@@ -962,6 +1022,9 @@ static int plda_init_interrupts(struct p
+ if (!port->event_ops)
+ port->event_ops = &plda_event_ops;
+
++ if (!port->event_irq_chip)
++ port->event_irq_chip = &plda_event_irq_chip;
++
+ ret = plda_pcie_init_irq_domains(port);
+ if (ret) {
+ dev_err(dev, "failed creating IRQ domains\n");
+@@ -1039,6 +1102,7 @@ static int mc_platform_init(struct pci_c
+ return ret;
+
+ port->plda.event_ops = &mc_event_ops;
++ port->plda.event_irq_chip = &mc_event_irq_chip;
+
+ /* Address translation is up; safe to enable interrupts */
+ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -107,7 +107,9 @@ enum plda_int_event {
+
+ #define PLDA_NUM_DMA_EVENTS 16
+
+-#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
++#define EVENT_PM_MSI_INT_INTX (PLDA_NUM_DMA_EVENTS + PLDA_INTX)
++#define EVENT_PM_MSI_INT_MSI (PLDA_NUM_DMA_EVENTS + PLDA_MSI)
++#define PLDA_MAX_EVENT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
+
+ /*
+ * PLDA interrupt register
+@@ -155,6 +157,7 @@ struct plda_pcie_rp {
+ raw_spinlock_t lock;
+ struct plda_msi msi;
+ const struct plda_event_ops *event_ops;
++ const struct irq_chip *event_irq_chip;
+ void __iomem *bridge_addr;
+ int num_events;
+ };
diff --git a/target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch b/target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch
new file mode 100644
index 0000000000..840e334d20
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch
@@ -0,0 +1,1028 @@
+From 6be452d8e61594790ae57b282a612ec0df473e61 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:06 +0800
+Subject: [PATCH 029/116] PCI: microchip: Move IRQ functions to
+ pcie-plda-host.c
+
+Move IRQ related functions to pcie-plda-host.c for re-use these codes.
+Now Refactoring codes complete.
+
+Including MSI, INTx, event interrupts and IRQ init functions.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 467 -----------------
+ drivers/pci/controller/plda/pcie-plda-host.c | 472 ++++++++++++++++++
+ drivers/pci/controller/plda/pcie-plda.h | 3 +
+ 3 files changed, 475 insertions(+), 467 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -318,244 +318,6 @@ static void mc_pcie_enable_msi(struct mc
+ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
+ }
+
+-static void plda_handle_msi(struct irq_desc *desc)
+-{
+- struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- struct plda_msi *msi = &port->msi;
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_MSI_MASK) {
+- writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
+- status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
+- for_each_set_bit(bit, &status, msi->num_vectors) {
+- ret = generic_handle_domain_irq(msi->dev_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void plda_msi_bottom_irq_ack(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- u32 bitpos = data->hwirq;
+-
+- writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+-}
+-
+-static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- phys_addr_t addr = port->msi.vector_phy;
+-
+- msg->address_lo = lower_32_bits(addr);
+- msg->address_hi = upper_32_bits(addr);
+- msg->data = data->hwirq;
+-
+- dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
+- (int)data->hwirq, msg->address_hi, msg->address_lo);
+-}
+-
+-static int plda_msi_set_affinity(struct irq_data *irq_data,
+- const struct cpumask *mask, bool force)
+-{
+- return -EINVAL;
+-}
+-
+-static struct irq_chip plda_msi_bottom_irq_chip = {
+- .name = "PLDA MSI",
+- .irq_ack = plda_msi_bottom_irq_ack,
+- .irq_compose_msi_msg = plda_compose_msi_msg,
+- .irq_set_affinity = plda_msi_set_affinity,
+-};
+-
+-static int plda_irq_msi_domain_alloc(struct irq_domain *domain,
+- unsigned int virq,
+- unsigned int nr_irqs,
+- void *args)
+-{
+- struct plda_pcie_rp *port = domain->host_data;
+- struct plda_msi *msi = &port->msi;
+- unsigned long bit;
+-
+- mutex_lock(&msi->lock);
+- bit = find_first_zero_bit(msi->used, msi->num_vectors);
+- if (bit >= msi->num_vectors) {
+- mutex_unlock(&msi->lock);
+- return -ENOSPC;
+- }
+-
+- set_bit(bit, msi->used);
+-
+- irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,
+- domain->host_data, handle_edge_irq, NULL, NULL);
+-
+- mutex_unlock(&msi->lock);
+-
+- return 0;
+-}
+-
+-static void plda_irq_msi_domain_free(struct irq_domain *domain,
+- unsigned int virq,
+- unsigned int nr_irqs)
+-{
+- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
+- struct plda_msi *msi = &port->msi;
+-
+- mutex_lock(&msi->lock);
+-
+- if (test_bit(d->hwirq, msi->used))
+- __clear_bit(d->hwirq, msi->used);
+- else
+- dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
+-
+- mutex_unlock(&msi->lock);
+-}
+-
+-static const struct irq_domain_ops msi_domain_ops = {
+- .alloc = plda_irq_msi_domain_alloc,
+- .free = plda_irq_msi_domain_free,
+-};
+-
+-static struct irq_chip plda_msi_irq_chip = {
+- .name = "PLDA PCIe MSI",
+- .irq_ack = irq_chip_ack_parent,
+- .irq_mask = pci_msi_mask_irq,
+- .irq_unmask = pci_msi_unmask_irq,
+-};
+-
+-static struct msi_domain_info plda_msi_domain_info = {
+- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+- MSI_FLAG_PCI_MSIX),
+- .chip = &plda_msi_irq_chip,
+-};
+-
+-static int plda_allocate_msi_domains(struct plda_pcie_rp *port)
+-{
+- struct device *dev = port->dev;
+- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+- struct plda_msi *msi = &port->msi;
+-
+- mutex_init(&port->msi.lock);
+-
+- msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
+- &msi_domain_ops, port);
+- if (!msi->dev_domain) {
+- dev_err(dev, "failed to create IRQ domain\n");
+- return -ENOMEM;
+- }
+-
+- msi->msi_domain = pci_msi_create_irq_domain(fwnode,
+- &plda_msi_domain_info,
+- msi->dev_domain);
+- if (!msi->msi_domain) {
+- dev_err(dev, "failed to create MSI domain\n");
+- irq_domain_remove(msi->dev_domain);
+- return -ENOMEM;
+- }
+-
+- return 0;
+-}
+-
+-static void plda_handle_intx(struct irq_desc *desc)
+-{
+- struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_INTX_MASK) {
+- status &= PM_MSI_INT_INTX_MASK;
+- status >>= PM_MSI_INT_INTX_SHIFT;
+- for_each_set_bit(bit, &status, PCI_NUM_INTX) {
+- ret = generic_handle_domain_irq(port->intx_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void plda_ack_intx_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+-
+- writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+-}
+-
+-static void plda_mask_intx_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val &= ~mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static void plda_unmask_intx_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val |= mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static struct irq_chip plda_intx_irq_chip = {
+- .name = "PLDA PCIe INTx",
+- .irq_ack = plda_ack_intx_irq,
+- .irq_mask = plda_mask_intx_irq,
+- .irq_unmask = plda_unmask_intx_irq,
+-};
+-
+-static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops intx_domain_ops = {
+- .map = plda_pcie_intx_map,
+-};
+-
+ static inline u32 reg_to_event(u32 reg, struct event_map field)
+ {
+ return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
+@@ -626,26 +388,6 @@ static u32 mc_get_events(struct plda_pci
+ return events;
+ }
+
+-static u32 plda_get_events(struct plda_pcie_rp *port)
+-{
+- u32 events, val, origin;
+-
+- origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
+-
+- /* MSI event and sys events */
+- val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;
+- events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);
+-
+- /* INTx events */
+- if (origin & PM_MSI_INT_INTX_MASK)
+- events |= BIT(PM_MSI_INT_INTX_SHIFT);
+-
+- /* remains are same with register */
+- events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);
+-
+- return events;
+-}
+-
+ static irqreturn_t mc_event_handler(int irq, void *dev_id)
+ {
+ struct plda_pcie_rp *port = dev_id;
+@@ -662,28 +404,6 @@ static irqreturn_t mc_event_handler(int
+ return IRQ_HANDLED;
+ }
+
+-static irqreturn_t plda_event_handler(int irq, void *dev_id)
+-{
+- return IRQ_HANDLED;
+-}
+-
+-static void plda_handle_event(struct irq_desc *desc)
+-{
+- struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+- unsigned long events;
+- u32 bit;
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+-
+- chained_irq_enter(chip, desc);
+-
+- events = port->event_ops->get_events(port);
+-
+- for_each_set_bit(bit, &events, port->num_events)
+- generic_handle_domain_irq(port->event_domain, bit);
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+ static void mc_ack_event_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+@@ -770,83 +490,6 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
+-static u32 plda_hwirq_to_mask(int hwirq)
+-{
+- u32 mask;
+-
+- /* hwirq 23 - 0 are the same with register */
+- if (hwirq < EVENT_PM_MSI_INT_INTX)
+- mask = BIT(hwirq);
+- else if (hwirq == EVENT_PM_MSI_INT_INTX)
+- mask = PM_MSI_INT_INTX_MASK;
+- else
+- mask = BIT(hwirq + PCI_NUM_INTX - 1);
+-
+- return mask;
+-}
+-
+-static void plda_ack_event_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+-
+- writel_relaxed(plda_hwirq_to_mask(data->hwirq),
+- port->bridge_addr + ISTATUS_LOCAL);
+-}
+-
+-static void plda_mask_event_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- u32 mask, val;
+-
+- mask = plda_hwirq_to_mask(data->hwirq);
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
+- val &= ~mask;
+- writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static void plda_unmask_event_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- u32 mask, val;
+-
+- mask = plda_hwirq_to_mask(data->hwirq);
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
+- val |= mask;
+- writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static struct irq_chip plda_event_irq_chip = {
+- .name = "PLDA PCIe EVENT",
+- .irq_ack = plda_ack_event_irq,
+- .irq_mask = plda_mask_event_irq,
+- .irq_unmask = plda_unmask_event_irq,
+-};
+-
+-static const struct plda_event_ops plda_event_ops = {
+- .get_events = plda_get_events,
+-};
+-
+-static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- struct plda_pcie_rp *port = (void *)domain->host_data;
+-
+- irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops plda_event_domain_ops = {
+- .map = plda_pcie_event_map,
+-};
+-
+ static inline void mc_pcie_deinit_clk(void *data)
+ {
+ struct clk *clk = data;
+@@ -909,47 +552,6 @@ static const struct plda_event mc_event
+ .msi_event = EVENT_LOCAL_PM_MSI_INT_MSI,
+ };
+
+-static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+-{
+- struct device *dev = port->dev;
+- struct device_node *node = dev->of_node;
+- struct device_node *pcie_intc_node;
+-
+- /* Setup INTx */
+- pcie_intc_node = of_get_next_child(node, NULL);
+- if (!pcie_intc_node) {
+- dev_err(dev, "failed to find PCIe Intc node\n");
+- return -EINVAL;
+- }
+-
+- port->event_domain = irq_domain_add_linear(pcie_intc_node,
+- port->num_events,
+- &plda_event_domain_ops,
+- port);
+- if (!port->event_domain) {
+- dev_err(dev, "failed to get event domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
+-
+- port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
+- &intx_domain_ops, port);
+- if (!port->intx_domain) {
+- dev_err(dev, "failed to get an INTx IRQ domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
+-
+- of_node_put(pcie_intc_node);
+- raw_spin_lock_init(&port->lock);
+-
+- return plda_allocate_msi_domains(port);
+-}
+-
+ static inline void mc_clear_secs(struct mc_pcie *port)
+ {
+ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+@@ -1010,75 +612,6 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int plda_init_interrupts(struct platform_device *pdev,
+- struct plda_pcie_rp *port,
+- const struct plda_event *event)
+-{
+- struct device *dev = &pdev->dev;
+- int irq;
+- int i, intx_irq, msi_irq, event_irq;
+- int ret;
+-
+- if (!port->event_ops)
+- port->event_ops = &plda_event_ops;
+-
+- if (!port->event_irq_chip)
+- port->event_irq_chip = &plda_event_irq_chip;
+-
+- ret = plda_pcie_init_irq_domains(port);
+- if (ret) {
+- dev_err(dev, "failed creating IRQ domains\n");
+- return ret;
+- }
+-
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
+- return -ENODEV;
+-
+- for (i = 0; i < port->num_events; i++) {
+- event_irq = irq_create_mapping(port->event_domain, i);
+- if (!event_irq) {
+- dev_err(dev, "failed to map hwirq %d\n", i);
+- return -ENXIO;
+- }
+-
+- if (event->request_event_irq)
+- ret = event->request_event_irq(port, event_irq, i);
+- else
+- ret = devm_request_irq(dev, event_irq,
+- plda_event_handler,
+- 0, NULL, port);
+-
+- if (ret) {
+- dev_err(dev, "failed to request IRQ %d\n", event_irq);
+- return ret;
+- }
+- }
+-
+- intx_irq = irq_create_mapping(port->event_domain,
+- event->intx_event);
+- if (!intx_irq) {
+- dev_err(dev, "failed to map INTx interrupt\n");
+- return -ENXIO;
+- }
+-
+- /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
+-
+- msi_irq = irq_create_mapping(port->event_domain,
+- event->msi_event);
+- if (!msi_irq)
+- return -ENXIO;
+-
+- /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
+-
+- /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, plda_handle_event, port);
+-
+- return 0;
+-}
+-
+ static int mc_platform_init(struct pci_config_window *cfg)
+ {
+ struct device *dev = cfg->parent;
+--- a/drivers/pci/controller/plda/pcie-plda-host.c
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -7,11 +7,483 @@
+ * Author: Daire McNamara <daire.mcnamara@microchip.com>
+ */
+
++#include <linux/irqchip/chained_irq.h>
++#include <linux/irqdomain.h>
++#include <linux/msi.h>
+ #include <linux/pci_regs.h>
+ #include <linux/pci-ecam.h>
+
+ #include "pcie-plda.h"
+
++static void plda_handle_msi(struct irq_desc *desc)
++{
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ struct plda_msi *msi = &port->msi;
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_MSI_MASK) {
++ writel_relaxed(status & PM_MSI_INT_MSI_MASK,
++ bridge_base_addr + ISTATUS_LOCAL);
++ status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
++ for_each_set_bit(bit, &status, msi->num_vectors) {
++ ret = generic_handle_domain_irq(msi->dev_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void plda_msi_bottom_irq_ack(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ u32 bitpos = data->hwirq;
++
++ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
++}
++
++static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ phys_addr_t addr = port->msi.vector_phy;
++
++ msg->address_lo = lower_32_bits(addr);
++ msg->address_hi = upper_32_bits(addr);
++ msg->data = data->hwirq;
++
++ dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
++ (int)data->hwirq, msg->address_hi, msg->address_lo);
++}
++
++static int plda_msi_set_affinity(struct irq_data *irq_data,
++ const struct cpumask *mask, bool force)
++{
++ return -EINVAL;
++}
++
++static struct irq_chip plda_msi_bottom_irq_chip = {
++ .name = "PLDA MSI",
++ .irq_ack = plda_msi_bottom_irq_ack,
++ .irq_compose_msi_msg = plda_compose_msi_msg,
++ .irq_set_affinity = plda_msi_set_affinity,
++};
++
++static int plda_irq_msi_domain_alloc(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs,
++ void *args)
++{
++ struct plda_pcie_rp *port = domain->host_data;
++ struct plda_msi *msi = &port->msi;
++ unsigned long bit;
++
++ mutex_lock(&msi->lock);
++ bit = find_first_zero_bit(msi->used, msi->num_vectors);
++ if (bit >= msi->num_vectors) {
++ mutex_unlock(&msi->lock);
++ return -ENOSPC;
++ }
++
++ set_bit(bit, msi->used);
++
++ irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,
++ domain->host_data, handle_edge_irq, NULL, NULL);
++
++ mutex_unlock(&msi->lock);
++
++ return 0;
++}
++
++static void plda_irq_msi_domain_free(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs)
++{
++ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
++ struct plda_msi *msi = &port->msi;
++
++ mutex_lock(&msi->lock);
++
++ if (test_bit(d->hwirq, msi->used))
++ __clear_bit(d->hwirq, msi->used);
++ else
++ dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
++
++ mutex_unlock(&msi->lock);
++}
++
++static const struct irq_domain_ops msi_domain_ops = {
++ .alloc = plda_irq_msi_domain_alloc,
++ .free = plda_irq_msi_domain_free,
++};
++
++static struct irq_chip plda_msi_irq_chip = {
++ .name = "PLDA PCIe MSI",
++ .irq_ack = irq_chip_ack_parent,
++ .irq_mask = pci_msi_mask_irq,
++ .irq_unmask = pci_msi_unmask_irq,
++};
++
++static struct msi_domain_info plda_msi_domain_info = {
++ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
++ MSI_FLAG_PCI_MSIX),
++ .chip = &plda_msi_irq_chip,
++};
++
++static int plda_allocate_msi_domains(struct plda_pcie_rp *port)
++{
++ struct device *dev = port->dev;
++ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++ struct plda_msi *msi = &port->msi;
++
++ mutex_init(&port->msi.lock);
++
++ msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
++ &msi_domain_ops, port);
++ if (!msi->dev_domain) {
++ dev_err(dev, "failed to create IRQ domain\n");
++ return -ENOMEM;
++ }
++
++ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
++ &plda_msi_domain_info,
++ msi->dev_domain);
++ if (!msi->msi_domain) {
++ dev_err(dev, "failed to create MSI domain\n");
++ irq_domain_remove(msi->dev_domain);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static void plda_handle_intx(struct irq_desc *desc)
++{
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_INTX_MASK) {
++ status &= PM_MSI_INT_INTX_MASK;
++ status >>= PM_MSI_INT_INTX_SHIFT;
++ for_each_set_bit(bit, &status, PCI_NUM_INTX) {
++ ret = generic_handle_domain_irq(port->intx_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void plda_ack_intx_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++
++ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
++}
++
++static void plda_mask_intx_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void plda_unmask_intx_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static struct irq_chip plda_intx_irq_chip = {
++ .name = "PLDA PCIe INTx",
++ .irq_ack = plda_ack_intx_irq,
++ .irq_mask = plda_mask_intx_irq,
++ .irq_unmask = plda_unmask_intx_irq,
++};
++
++static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops intx_domain_ops = {
++ .map = plda_pcie_intx_map,
++};
++
++static u32 plda_get_events(struct plda_pcie_rp *port)
++{
++ u32 events, val, origin;
++
++ origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
++
++ /* MSI event and sys events */
++ val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;
++ events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);
++
++ /* INTx events */
++ if (origin & PM_MSI_INT_INTX_MASK)
++ events |= BIT(PM_MSI_INT_INTX_SHIFT);
++
++ /* remains are same with register */
++ events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);
++
++ return events;
++}
++
++static irqreturn_t plda_event_handler(int irq, void *dev_id)
++{
++ return IRQ_HANDLED;
++}
++
++static void plda_handle_event(struct irq_desc *desc)
++{
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
++ unsigned long events;
++ u32 bit;
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++
++ chained_irq_enter(chip, desc);
++
++ events = port->event_ops->get_events(port);
++
++ for_each_set_bit(bit, &events, port->num_events)
++ generic_handle_domain_irq(port->event_domain, bit);
++
++ chained_irq_exit(chip, desc);
++}
++
++static u32 plda_hwirq_to_mask(int hwirq)
++{
++ u32 mask;
++
++ /* hwirq 23 - 0 are the same with register */
++ if (hwirq < EVENT_PM_MSI_INT_INTX)
++ mask = BIT(hwirq);
++ else if (hwirq == EVENT_PM_MSI_INT_INTX)
++ mask = PM_MSI_INT_INTX_MASK;
++ else
++ mask = BIT(hwirq + PCI_NUM_INTX - 1);
++
++ return mask;
++}
++
++static void plda_ack_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++
++ writel_relaxed(plda_hwirq_to_mask(data->hwirq),
++ port->bridge_addr + ISTATUS_LOCAL);
++}
++
++static void plda_mask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static void plda_unmask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static struct irq_chip plda_event_irq_chip = {
++ .name = "PLDA PCIe EVENT",
++ .irq_ack = plda_ack_event_irq,
++ .irq_mask = plda_mask_event_irq,
++ .irq_unmask = plda_unmask_event_irq,
++};
++
++static const struct plda_event_ops plda_event_ops = {
++ .get_events = plda_get_events,
++};
++
++static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ struct plda_pcie_rp *port = (void *)domain->host_data;
++
++ irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops plda_event_domain_ops = {
++ .map = plda_pcie_event_map,
++};
++
++static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
++{
++ struct device *dev = port->dev;
++ struct device_node *node = dev->of_node;
++ struct device_node *pcie_intc_node;
++
++ /* Setup INTx */
++ pcie_intc_node = of_get_next_child(node, NULL);
++ if (!pcie_intc_node) {
++ dev_err(dev, "failed to find PCIe Intc node\n");
++ return -EINVAL;
++ }
++
++ port->event_domain = irq_domain_add_linear(pcie_intc_node,
++ port->num_events,
++ &plda_event_domain_ops,
++ port);
++ if (!port->event_domain) {
++ dev_err(dev, "failed to get event domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
++
++ port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
++ &intx_domain_ops, port);
++ if (!port->intx_domain) {
++ dev_err(dev, "failed to get an INTx IRQ domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
++
++ of_node_put(pcie_intc_node);
++ raw_spin_lock_init(&port->lock);
++
++ return plda_allocate_msi_domains(port);
++}
++
++int plda_init_interrupts(struct platform_device *pdev,
++ struct plda_pcie_rp *port,
++ const struct plda_event *event)
++{
++ struct device *dev = &pdev->dev;
++ int irq;
++ int i, intx_irq, msi_irq, event_irq;
++ int ret;
++
++ if (!port->event_ops)
++ port->event_ops = &plda_event_ops;
++
++ if (!port->event_irq_chip)
++ port->event_irq_chip = &plda_event_irq_chip;
++
++ ret = plda_pcie_init_irq_domains(port);
++ if (ret) {
++ dev_err(dev, "failed creating IRQ domains\n");
++ return ret;
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ return -ENODEV;
++
++ for (i = 0; i < port->num_events; i++) {
++ event_irq = irq_create_mapping(port->event_domain, i);
++ if (!event_irq) {
++ dev_err(dev, "failed to map hwirq %d\n", i);
++ return -ENXIO;
++ }
++
++ if (event->request_event_irq)
++ ret = event->request_event_irq(port, event_irq, i);
++ else
++ ret = devm_request_irq(dev, event_irq,
++ plda_event_handler,
++ 0, NULL, port);
++
++ if (ret) {
++ dev_err(dev, "failed to request IRQ %d\n", event_irq);
++ return ret;
++ }
++ }
++
++ intx_irq = irq_create_mapping(port->event_domain,
++ event->intx_event);
++ if (!intx_irq) {
++ dev_err(dev, "failed to map INTx interrupt\n");
++ return -ENXIO;
++ }
++
++ /* Plug the INTx chained handler */
++ irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
++
++ msi_irq = irq_create_mapping(port->event_domain,
++ event->msi_event);
++ if (!msi_irq)
++ return -ENXIO;
++
++ /* Plug the MSI chained handler */
++ irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
++
++ /* Plug the main event chained handler */
++ irq_set_chained_handler_and_data(irq, plda_handle_event, port);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(plda_init_interrupts);
++
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
+ size_t size)
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -169,6 +169,9 @@ struct plda_event {
+ int msi_event;
+ };
+
++int plda_init_interrupts(struct platform_device *pdev,
++ struct plda_pcie_rp *port,
++ const struct plda_event *event);
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
+ size_t size);
diff --git a/target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch b/target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch
new file mode 100644
index 0000000000..dcd2310e5e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch
@@ -0,0 +1,67 @@
+From 142fc300fd7511a217783dcfa342031d8ad70188 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:07 +0800
+Subject: [PATCH 030/116] pci: plda: Add event bitmap field to struct
+ plda_pcie_rp
+
+For PLDA DMA interrupts are not all implemented. The non-implemented
+interrupts should be masked. So add a bitmap field to mask the non-
+implemented interrupts.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 1 +
+ drivers/pci/controller/plda/pcie-plda-host.c | 6 ++++--
+ drivers/pci/controller/plda/pcie-plda.h | 1 +
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -636,6 +636,7 @@ static int mc_platform_init(struct pci_c
+
+ port->plda.event_ops = &mc_event_ops;
+ port->plda.event_irq_chip = &mc_event_irq_chip;
++ port->plda.events_bitmap = GENMASK(NUM_EVENTS - 1, 0);
+
+ /* Address translation is up; safe to enable interrupts */
+ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+--- a/drivers/pci/controller/plda/pcie-plda-host.c
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -290,6 +290,7 @@ static void plda_handle_event(struct irq
+
+ events = port->event_ops->get_events(port);
+
++ events &= port->events_bitmap;
+ for_each_set_bit(bit, &events, port->num_events)
+ generic_handle_domain_irq(port->event_domain, bit);
+
+@@ -420,8 +421,9 @@ int plda_init_interrupts(struct platform
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+- int i, intx_irq, msi_irq, event_irq;
++ int intx_irq, msi_irq, event_irq;
+ int ret;
++ u32 i;
+
+ if (!port->event_ops)
+ port->event_ops = &plda_event_ops;
+@@ -439,7 +441,7 @@ int plda_init_interrupts(struct platform
+ if (irq < 0)
+ return -ENODEV;
+
+- for (i = 0; i < port->num_events; i++) {
++ for_each_set_bit(i, &port->events_bitmap, port->num_events) {
+ event_irq = irq_create_mapping(port->event_domain, i);
+ if (!event_irq) {
+ dev_err(dev, "failed to map hwirq %d\n", i);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -159,6 +159,7 @@ struct plda_pcie_rp {
+ const struct plda_event_ops *event_ops;
+ const struct irq_chip *event_irq_chip;
+ void __iomem *bridge_addr;
++ unsigned long events_bitmap;
+ int num_events;
+ };
+
diff --git a/target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch b/target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch
new file mode 100644
index 0000000000..eb22849da6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch
@@ -0,0 +1,256 @@
+From 3b9991438094dc472dacb4555603bdc379653411 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:08 +0800
+Subject: [PATCH 031/116] PCI: plda: Add host init/deinit and map bus functions
+
+Add PLDA host plda_pcie_host_init()/plda_pcie_host_deinit() and map bus
+function. So vendor can use it to init PLDA PCIe host core.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
+---
+ drivers/pci/controller/plda/pcie-plda-host.c | 131 +++++++++++++++++--
+ drivers/pci/controller/plda/pcie-plda.h | 22 ++++
+ 2 files changed, 139 insertions(+), 14 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-plda-host.c
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -3,6 +3,7 @@
+ * PLDA PCIe XpressRich host controller driver
+ *
+ * Copyright (C) 2023 Microchip Co. Ltd
++ * StarFive Co. Ltd
+ *
+ * Author: Daire McNamara <daire.mcnamara@microchip.com>
+ */
+@@ -15,6 +16,15 @@
+
+ #include "pcie-plda.h"
+
++void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
++ int where)
++{
++ struct plda_pcie_rp *pcie = bus->sysdata;
++
++ return pcie->config_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
++}
++EXPORT_SYMBOL_GPL(plda_pcie_map_bus);
++
+ static void plda_handle_msi(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+@@ -420,9 +430,7 @@ int plda_init_interrupts(struct platform
+ const struct plda_event *event)
+ {
+ struct device *dev = &pdev->dev;
+- int irq;
+- int intx_irq, msi_irq, event_irq;
+- int ret;
++ int event_irq, ret;
+ u32 i;
+
+ if (!port->event_ops)
+@@ -437,8 +445,8 @@ int plda_init_interrupts(struct platform
+ return ret;
+ }
+
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
++ port->irq = platform_get_irq(pdev, 0);
++ if (port->irq < 0)
+ return -ENODEV;
+
+ for_each_set_bit(i, &port->events_bitmap, port->num_events) {
+@@ -461,26 +469,26 @@ int plda_init_interrupts(struct platform
+ }
+ }
+
+- intx_irq = irq_create_mapping(port->event_domain,
+- event->intx_event);
+- if (!intx_irq) {
++ port->intx_irq = irq_create_mapping(port->event_domain,
++ event->intx_event);
++ if (!port->intx_irq) {
+ dev_err(dev, "failed to map INTx interrupt\n");
+ return -ENXIO;
+ }
+
+ /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
++ irq_set_chained_handler_and_data(port->intx_irq, plda_handle_intx, port);
+
+- msi_irq = irq_create_mapping(port->event_domain,
+- event->msi_event);
+- if (!msi_irq)
++ port->msi_irq = irq_create_mapping(port->event_domain,
++ event->msi_event);
++ if (!port->msi_irq)
+ return -ENXIO;
+
+ /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
++ irq_set_chained_handler_and_data(port->msi_irq, plda_handle_msi, port);
+
+ /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, plda_handle_event, port);
++ irq_set_chained_handler_and_data(port->irq, plda_handle_event, port);
+
+ return 0;
+ }
+@@ -546,3 +554,98 @@ int plda_pcie_setup_iomems(struct pci_ho
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
++
++static void plda_pcie_irq_domain_deinit(struct plda_pcie_rp *pcie)
++{
++ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
++ irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL);
++ irq_set_chained_handler_and_data(pcie->intx_irq, NULL, NULL);
++
++ irq_domain_remove(pcie->msi.msi_domain);
++ irq_domain_remove(pcie->msi.dev_domain);
++
++ irq_domain_remove(pcie->intx_domain);
++ irq_domain_remove(pcie->event_domain);
++}
++
++int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops,
++ const struct plda_event *plda_event)
++{
++ struct device *dev = port->dev;
++ struct pci_host_bridge *bridge;
++ struct platform_device *pdev = to_platform_device(dev);
++ struct resource *cfg_res;
++ int ret;
++
++ pdev = to_platform_device(dev);
++
++ port->bridge_addr =
++ devm_platform_ioremap_resource_byname(pdev, "apb");
++
++ if (IS_ERR(port->bridge_addr))
++ return dev_err_probe(dev, PTR_ERR(port->bridge_addr),
++ "failed to map reg memory\n");
++
++ cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
++ if (!cfg_res)
++ return dev_err_probe(dev, -ENODEV,
++ "failed to get config memory\n");
++
++ port->config_base = devm_ioremap_resource(dev, cfg_res);
++ if (IS_ERR(port->config_base))
++ return dev_err_probe(dev, PTR_ERR(port->config_base),
++ "failed to map config memory\n");
++
++ bridge = devm_pci_alloc_host_bridge(dev, 0);
++ if (!bridge)
++ return dev_err_probe(dev, -ENOMEM,
++ "failed to alloc bridge\n");
++
++ if (port->host_ops && port->host_ops->host_init) {
++ ret = port->host_ops->host_init(port);
++ if (ret)
++ return ret;
++ }
++
++ port->bridge = bridge;
++ plda_pcie_setup_window(port->bridge_addr, 0, cfg_res->start, 0,
++ resource_size(cfg_res));
++ plda_pcie_setup_iomems(bridge, port);
++ plda_set_default_msi(&port->msi);
++ ret = plda_init_interrupts(pdev, port, plda_event);
++ if (ret)
++ goto err_host;
++
++ /* Set default bus ops */
++ bridge->ops = ops;
++ bridge->sysdata = port;
++
++ ret = pci_host_probe(bridge);
++ if (ret < 0) {
++ dev_err_probe(dev, ret, "failed to probe pci host\n");
++ goto err_probe;
++ }
++
++ return ret;
++
++err_probe:
++ plda_pcie_irq_domain_deinit(port);
++err_host:
++ if (port->host_ops && port->host_ops->host_deinit)
++ port->host_ops->host_deinit(port);
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(plda_pcie_host_init);
++
++void plda_pcie_host_deinit(struct plda_pcie_rp *port)
++{
++ pci_stop_root_bus(port->bridge->bus);
++ pci_remove_root_bus(port->bridge->bus);
++
++ plda_pcie_irq_domain_deinit(port);
++
++ if (port->host_ops && port->host_ops->host_deinit)
++ port->host_ops->host_deinit(port);
++}
++EXPORT_SYMBOL_GPL(plda_pcie_host_deinit);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -141,6 +141,11 @@ struct plda_event_ops {
+ u32 (*get_events)(struct plda_pcie_rp *pcie);
+ };
+
++struct plda_pcie_host_ops {
++ int (*host_init)(struct plda_pcie_rp *pcie);
++ void (*host_deinit)(struct plda_pcie_rp *pcie);
++};
++
+ struct plda_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+@@ -152,14 +157,20 @@ struct plda_msi {
+
+ struct plda_pcie_rp {
+ struct device *dev;
++ struct pci_host_bridge *bridge;
+ struct irq_domain *intx_domain;
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+ struct plda_msi msi;
+ const struct plda_event_ops *event_ops;
+ const struct irq_chip *event_irq_chip;
++ const struct plda_pcie_host_ops *host_ops;
+ void __iomem *bridge_addr;
++ void __iomem *config_base;
+ unsigned long events_bitmap;
++ int irq;
++ int msi_irq;
++ int intx_irq;
+ int num_events;
+ };
+
+@@ -170,6 +181,8 @@ struct plda_event {
+ int msi_event;
+ };
+
++void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
++ int where);
+ int plda_init_interrupts(struct platform_device *pdev,
+ struct plda_pcie_rp *port,
+ const struct plda_event *event);
+@@ -178,4 +191,13 @@ void plda_pcie_setup_window(void __iomem
+ size_t size);
+ int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
+ struct plda_pcie_rp *port);
++int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops,
++ const struct plda_event *plda_event);
++void plda_pcie_host_deinit(struct plda_pcie_rp *pcie);
++
++static inline void plda_set_default_msi(struct plda_msi *msi)
++{
++ msi->vector_phy = IMSI_ADDR;
++ msi->num_vectors = PLDA_MAX_NUM_MSI_IRQS;
++}
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch b/target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch
new file mode 100644
index 0000000000..9e33f7d68a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch
@@ -0,0 +1,140 @@
+From bc3f8207d9f0af3cb96a7eae232074a644a175f6 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:09 +0800
+Subject: [PATCH 032/116] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
+
+Add StarFive JH7110 SoC PCIe controller dt-bindings. JH7110 using PLDA
+XpressRICH PCIe host controller IP.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ .../bindings/pci/starfive,jh7110-pcie.yaml | 120 ++++++++++++++++++
+ 1 file changed, 120 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
+@@ -0,0 +1,120 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 PCIe host controller
++
++maintainers:
++ - Kevin Xie <kevin.xie@starfivetech.com>
++
++allOf:
++ - $ref: plda,xpressrich3-axi-common.yaml#
++
++properties:
++ compatible:
++ const: starfive,jh7110-pcie
++
++ clocks:
++ items:
++ - description: NOC bus clock
++ - description: Transport layer clock
++ - description: AXI MST0 clock
++ - description: APB clock
++
++ clock-names:
++ items:
++ - const: noc
++ - const: tl
++ - const: axi_mst0
++ - const: apb
++
++ resets:
++ items:
++ - description: AXI MST0 reset
++ - description: AXI SLAVE0 reset
++ - description: AXI SLAVE reset
++ - description: PCIE BRIDGE reset
++ - description: PCIE CORE reset
++ - description: PCIE APB reset
++
++ reset-names:
++ items:
++ - const: mst0
++ - const: slv0
++ - const: slv
++ - const: brg
++ - const: core
++ - const: apb
++
++ starfive,stg-syscon:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ description:
++ The phandle to System Register Controller syscon node.
++
++ perst-gpios:
++ description: GPIO controlled connection to PERST# signal
++ maxItems: 1
++
++ phys:
++ description:
++ Specified PHY is attached to PCIe controller.
++ maxItems: 1
++
++required:
++ - clocks
++ - resets
++ - starfive,stg-syscon
++
++unevaluatedProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/gpio/gpio.h>
++ soc {
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ pcie@940000000 {
++ compatible = "starfive,jh7110-pcie";
++ reg = <0x9 0x40000000 0x0 0x10000000>,
++ <0x0 0x2b000000 0x0 0x1000000>;
++ reg-names = "cfg", "apb";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ #interrupt-cells = <1>;
++ device_type = "pci";
++ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
++ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
++ starfive,stg-syscon = <&stg_syscon>;
++ bus-range = <0x0 0xff>;
++ interrupt-parent = <&plic>;
++ interrupts = <56>;
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
++ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
++ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
++ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
++ msi-controller;
++ clocks = <&syscrg 86>,
++ <&stgcrg 10>,
++ <&stgcrg 8>,
++ <&stgcrg 9>;
++ clock-names = "noc", "tl", "axi_mst0", "apb";
++ resets = <&stgcrg 11>,
++ <&stgcrg 12>,
++ <&stgcrg 13>,
++ <&stgcrg 14>,
++ <&stgcrg 15>,
++ <&stgcrg 16>;
++ perst-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy0>;
++
++ pcie_intc0: interrupt-controller {
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-controller;
++ };
++ };
++ };
diff --git a/target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch b/target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch
new file mode 100644
index 0000000000..cc50dfe68e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch
@@ -0,0 +1,55 @@
+From abb20b7b8f5e3a7f36dbd6264e6d346275434154 Mon Sep 17 00:00:00 2001
+From: Kevin Xie <kevin.xie@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:10 +0800
+Subject: [PATCH 033/116] PCI: Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS waiting
+ time value
+
+Add the PCIE_RESET_CONFIG_DEVICE_WAIT_MS macro to define the minimum
+waiting time between exit from a conventional reset and sending the
+first configuration request to the device.
+
+As described in PCI base specification r6.0, section 6.6.1 <Conventional
+Reset>, there are two different use cases of the value:
+
+ - "With a Downstream Port that does not support Link speeds greater
+ than 5.0 GT/s, software must wait a minimum of 100 ms following exit
+ from a Conventional Reset before sending a Configuration Request to
+ the device immediately below that Port."
+
+ - "With a Downstream Port that supports Link speeds greater than
+ 5.0 GT/s, software must wait a minimum of 100 ms after Link training
+ completes before sending a Configuration Request to the device
+ immediately below that Port."
+
+Signed-off-by: Kevin Xie <kevin.xie@starfivetech.com>
+Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/pci.h | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -19,6 +19,22 @@
+ */
+ #define PCIE_PME_TO_L2_TIMEOUT_US 10000
+
++/*
++ * As described in PCI base specification r6.0, section 6.6.1 <Conventional
++ * Reset>, there are two different use cases of the value:
++ *
++ * - "With a Downstream Port that does not support Link speeds greater
++ * than 5.0 GT/s, software must wait a minimum of 100 ms following exit
++ * from a Conventional Reset before sending a Configuration Request to
++ * the device immediately below that Port."
++ *
++ * - "With a Downstream Port that supports Link speeds greater than
++ * 5.0 GT/s, software must wait a minimum of 100 ms after Link training
++ * completes before sending a Configuration Request to the device
++ * immediately below that Port."
++ */
++#define PCIE_RESET_CONFIG_DEVICE_WAIT_MS 100
++
+ extern const unsigned char pcie_link_speed[];
+ extern bool pci_early_dump;
+
diff --git a/target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch b/target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch
new file mode 100644
index 0000000000..45a549f489
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch
@@ -0,0 +1,623 @@
+From 323aedef34315b758dc30ba23e2cabca259bb4b2 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:11 +0800
+Subject: [PATCH 034/116] PCI: starfive: Add JH7110 PCIe controller
+
+Add StarFive JH7110 SoC PCIe controller platform driver codes, JH7110
+with PLDA host PCIe core.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Co-developed-by: Kevin Xie <kevin.xie@starfivetech.com>
+Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
+---
+ drivers/pci/controller/plda/Kconfig | 12 +
+ drivers/pci/controller/plda/Makefile | 1 +
+ drivers/pci/controller/plda/pcie-plda.h | 71 ++-
+ drivers/pci/controller/plda/pcie-starfive.c | 473 ++++++++++++++++++++
+ 4 files changed, 556 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/pci/controller/plda/pcie-starfive.c
+
+--- a/drivers/pci/controller/plda/Kconfig
++++ b/drivers/pci/controller/plda/Kconfig
+@@ -15,4 +15,16 @@ config PCIE_MICROCHIP_HOST
+ Say Y here if you want kernel to support the Microchip AXI PCIe
+ Host Bridge driver.
+
++config PCIE_STARFIVE_HOST
++ tristate "StarFive PCIe host controller"
++ depends on PCI_MSI && OF
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ select PCIE_PLDA_HOST
++ help
++ Say Y here if you want to support the StarFive PCIe controller in
++ host mode. StarFive PCIe controller uses PLDA PCIe core.
++
++ If you choose to build this driver as module it will be dynamically
++ linked and module will be called pcie-starfive.ko.
++
+ endmenu
+--- a/drivers/pci/controller/plda/Makefile
++++ b/drivers/pci/controller/plda/Makefile
+@@ -1,3 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0
+ obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o
+ obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
++obj-$(CONFIG_PCIE_STARFIVE_HOST) += pcie-starfive.o
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -10,10 +10,20 @@
+ #define PLDA_MAX_NUM_MSI_IRQS 32
+
+ /* PCIe Bridge Phy Regs */
++#define GEN_SETTINGS 0x80
++#define RP_ENABLE 1
++#define PCIE_PCI_IDS_DW1 0x9c
++#define IDS_CLASS_CODE_SHIFT 16
++#define REVISION_ID_MASK GENMASK(7, 0)
++#define CLASS_CODE_ID_MASK GENMASK(31, 8)
+ #define PCIE_PCI_IRQ_DW0 0xa8
+ #define MSIX_CAP_MASK BIT(31)
+ #define NUM_MSI_MSGS_MASK GENMASK(6, 4)
+ #define NUM_MSI_MSGS_SHIFT 4
++#define PCI_MISC 0xb4
++#define PHY_FUNCTION_DIS BIT(15)
++#define PCIE_WINROM 0xfc
++#define PREF_MEM_WIN_64_SUPPORT BIT(3)
+
+ #define IMASK_LOCAL 0x180
+ #define DMA_END_ENGINE_0_MASK 0x00000000u
+@@ -65,6 +75,8 @@
+ #define ISTATUS_HOST 0x18c
+ #define IMSI_ADDR 0x190
+ #define ISTATUS_MSI 0x194
++#define PMSG_SUPPORT_RX 0x3f0
++#define PMSG_LTR_SUPPORT BIT(2)
+
+ /* PCIe Master table init defines */
+ #define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+@@ -86,6 +98,8 @@
+ #define PCIE_TX_RX_INTERFACE 0x00000000u
+ #define PCIE_CONFIG_INTERFACE 0x00000001u
+
++#define CONFIG_SPACE_ADDR_OFFSET 0x1000u
++
+ #define ATR_ENTRY_SIZE 32
+
+ enum plda_int_event {
+@@ -200,4 +214,59 @@ static inline void plda_set_default_msi(
+ msi->vector_phy = IMSI_ADDR;
+ msi->num_vectors = PLDA_MAX_NUM_MSI_IRQS;
+ }
+-#endif
++
++static inline void plda_pcie_enable_root_port(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + GEN_SETTINGS);
++ value |= RP_ENABLE;
++ writel_relaxed(value, plda->bridge_addr + GEN_SETTINGS);
++}
++
++static inline void plda_pcie_set_standard_class(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ /* set class code and reserve revision id */
++ value = readl_relaxed(plda->bridge_addr + PCIE_PCI_IDS_DW1);
++ value &= REVISION_ID_MASK;
++ value |= (PCI_CLASS_BRIDGE_PCI << IDS_CLASS_CODE_SHIFT);
++ writel_relaxed(value, plda->bridge_addr + PCIE_PCI_IDS_DW1);
++}
++
++static inline void plda_pcie_set_pref_win_64bit(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + PCIE_WINROM);
++ value |= PREF_MEM_WIN_64_SUPPORT;
++ writel_relaxed(value, plda->bridge_addr + PCIE_WINROM);
++}
++
++static inline void plda_pcie_disable_ltr(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + PMSG_SUPPORT_RX);
++ value &= ~PMSG_LTR_SUPPORT;
++ writel_relaxed(value, plda->bridge_addr + PMSG_SUPPORT_RX);
++}
++
++static inline void plda_pcie_disable_func(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + PCI_MISC);
++ value |= PHY_FUNCTION_DIS;
++ writel_relaxed(value, plda->bridge_addr + PCI_MISC);
++}
++
++static inline void plda_pcie_write_rc_bar(struct plda_pcie_rp *plda, u64 val)
++{
++ void __iomem *addr = plda->bridge_addr + CONFIG_SPACE_ADDR_OFFSET;
++
++ writel_relaxed(lower_32_bits(val), addr + PCI_BASE_ADDRESS_0);
++ writel_relaxed(upper_32_bits(val), addr + PCI_BASE_ADDRESS_1);
++}
++#endif /* _PCIE_PLDA_H */
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-starfive.c
+@@ -0,0 +1,473 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * PCIe host controller driver for StarFive JH7110 Soc.
++ *
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++#include <linux/of_pci.h>
++#include <linux/pci.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include "../../pci.h"
++
++#include "pcie-plda.h"
++
++#define PCIE_FUNC_NUM 4
++
++/* system control */
++#define STG_SYSCON_PCIE0_BASE 0x48
++#define STG_SYSCON_PCIE1_BASE 0x1f8
++
++#define STG_SYSCON_AR_OFFSET 0x78
++#define STG_SYSCON_AXI4_SLVL_AR_MASK GENMASK(22, 8)
++#define STG_SYSCON_AXI4_SLVL_PHY_AR(x) FIELD_PREP(GENMASK(20, 17), x)
++#define STG_SYSCON_AW_OFFSET 0x7c
++#define STG_SYSCON_AXI4_SLVL_AW_MASK GENMASK(14, 0)
++#define STG_SYSCON_AXI4_SLVL_PHY_AW(x) FIELD_PREP(GENMASK(12, 9), x)
++#define STG_SYSCON_CLKREQ BIT(22)
++#define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18)
++#define STG_SYSCON_RP_NEP_OFFSET 0xe8
++#define STG_SYSCON_K_RP_NEP BIT(8)
++#define STG_SYSCON_LNKSTA_OFFSET 0x170
++#define DATA_LINK_ACTIVE BIT(5)
++
++/* Parameters for the waiting for link up routine */
++#define LINK_WAIT_MAX_RETRIES 10
++#define LINK_WAIT_USLEEP_MIN 90000
++#define LINK_WAIT_USLEEP_MAX 100000
++
++struct starfive_jh7110_pcie {
++ struct plda_pcie_rp plda;
++ struct reset_control *resets;
++ struct clk_bulk_data *clks;
++ struct regmap *reg_syscon;
++ struct gpio_desc *power_gpio;
++ struct gpio_desc *reset_gpio;
++ struct phy *phy;
++
++ unsigned int stg_pcie_base;
++ int num_clks;
++};
++
++/*
++ * The BAR0/1 of bridge should be hidden during enumeration to
++ * avoid the sizing and resource allocation by PCIe core.
++ */
++static bool starfive_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
++ int offset)
++{
++ if (pci_is_root_bus(bus) && !devfn &&
++ (offset == PCI_BASE_ADDRESS_0 || offset == PCI_BASE_ADDRESS_1))
++ return true;
++
++ return false;
++}
++
++static int starfive_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
++ int where, int size, u32 value)
++{
++ if (starfive_pcie_hide_rc_bar(bus, devfn, where))
++ return PCIBIOS_SUCCESSFUL;
++
++ return pci_generic_config_write(bus, devfn, where, size, value);
++}
++
++static int starfive_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
++ int where, int size, u32 *value)
++{
++ if (starfive_pcie_hide_rc_bar(bus, devfn, where)) {
++ *value = 0;
++ return PCIBIOS_SUCCESSFUL;
++ }
++
++ return pci_generic_config_read(bus, devfn, where, size, value);
++}
++
++static int starfive_pcie_parse_dt(struct starfive_jh7110_pcie *pcie,
++ struct device *dev)
++{
++ int domain_nr;
++
++ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
++ if (pcie->num_clks < 0)
++ return dev_err_probe(dev, pcie->num_clks,
++ "failed to get pcie clocks\n");
++
++ pcie->resets = devm_reset_control_array_get_exclusive(dev);
++ if (IS_ERR(pcie->resets))
++ return dev_err_probe(dev, PTR_ERR(pcie->resets),
++ "failed to get pcie resets");
++
++ pcie->reg_syscon =
++ syscon_regmap_lookup_by_phandle(dev->of_node,
++ "starfive,stg-syscon");
++
++ if (IS_ERR(pcie->reg_syscon))
++ return dev_err_probe(dev, PTR_ERR(pcie->reg_syscon),
++ "failed to parse starfive,stg-syscon\n");
++
++ pcie->phy = devm_phy_optional_get(dev, NULL);
++ if (IS_ERR(pcie->phy))
++ return dev_err_probe(dev, PTR_ERR(pcie->phy),
++ "failed to get pcie phy\n");
++
++ domain_nr = of_get_pci_domain_nr(dev->of_node);
++
++ if (domain_nr < 0 || domain_nr > 1)
++ return dev_err_probe(dev, -ENODEV,
++ "failed to get valid pcie domain\n");
++
++ if (domain_nr == 0)
++ pcie->stg_pcie_base = STG_SYSCON_PCIE0_BASE;
++ else
++ pcie->stg_pcie_base = STG_SYSCON_PCIE1_BASE;
++
++ pcie->reset_gpio = devm_gpiod_get_optional(dev, "perst",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(pcie->reset_gpio))
++ return dev_err_probe(dev, PTR_ERR(pcie->reset_gpio),
++ "failed to get perst-gpio\n");
++
++ pcie->power_gpio = devm_gpiod_get_optional(dev, "enable",
++ GPIOD_OUT_LOW);
++ if (IS_ERR(pcie->power_gpio))
++ return dev_err_probe(dev, PTR_ERR(pcie->power_gpio),
++ "failed to get power-gpio\n");
++
++ return 0;
++}
++
++static struct pci_ops starfive_pcie_ops = {
++ .map_bus = plda_pcie_map_bus,
++ .read = starfive_pcie_config_read,
++ .write = starfive_pcie_config_write,
++};
++
++static int starfive_pcie_clk_rst_init(struct starfive_jh7110_pcie *pcie)
++{
++ struct device *dev = pcie->plda.dev;
++ int ret;
++
++ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
++ if (ret)
++ return dev_err_probe(dev, ret, "failed to enable clocks\n");
++
++ ret = reset_control_deassert(pcie->resets);
++ if (ret) {
++ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
++ dev_err_probe(dev, ret, "failed to deassert resets\n");
++ }
++
++ return ret;
++}
++
++static void starfive_pcie_clk_rst_deinit(struct starfive_jh7110_pcie *pcie)
++{
++ reset_control_assert(pcie->resets);
++ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
++}
++
++static bool starfive_pcie_link_up(struct plda_pcie_rp *plda)
++{
++ struct starfive_jh7110_pcie *pcie =
++ container_of(plda, struct starfive_jh7110_pcie, plda);
++ int ret;
++ u32 stg_reg_val;
++
++ ret = regmap_read(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_LNKSTA_OFFSET,
++ &stg_reg_val);
++ if (ret) {
++ dev_err(pcie->plda.dev, "failed to read link status\n");
++ return false;
++ }
++
++ return !!(stg_reg_val & DATA_LINK_ACTIVE);
++}
++
++static int starfive_pcie_host_wait_for_link(struct starfive_jh7110_pcie *pcie)
++{
++ int retries;
++
++ /* Check if the link is up or not */
++ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
++ if (starfive_pcie_link_up(&pcie->plda)) {
++ dev_info(pcie->plda.dev, "port link up\n");
++ return 0;
++ }
++ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
++ }
++
++ return -ETIMEDOUT;
++}
++
++static int starfive_pcie_enable_phy(struct device *dev,
++ struct starfive_jh7110_pcie *pcie)
++{
++ int ret;
++
++ if (!pcie->phy)
++ return 0;
++
++ ret = phy_init(pcie->phy);
++ if (ret)
++ return dev_err_probe(dev, ret,
++ "failed to initialize pcie phy\n");
++
++ ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
++ if (ret) {
++ dev_err_probe(dev, ret, "failed to set pcie mode\n");
++ goto err_phy_on;
++ }
++
++ ret = phy_power_on(pcie->phy);
++ if (ret) {
++ dev_err_probe(dev, ret, "failed to power on pcie phy\n");
++ goto err_phy_on;
++ }
++
++ return 0;
++
++err_phy_on:
++ phy_exit(pcie->phy);
++ return ret;
++}
++
++static void starfive_pcie_disable_phy(struct starfive_jh7110_pcie *pcie)
++{
++ phy_power_off(pcie->phy);
++ phy_exit(pcie->phy);
++}
++
++static void starfive_pcie_host_deinit(struct plda_pcie_rp *plda)
++{
++ struct starfive_jh7110_pcie *pcie =
++ container_of(plda, struct starfive_jh7110_pcie, plda);
++
++ starfive_pcie_clk_rst_deinit(pcie);
++ if (pcie->power_gpio)
++ gpiod_set_value_cansleep(pcie->power_gpio, 0);
++ starfive_pcie_disable_phy(pcie);
++}
++
++static int starfive_pcie_host_init(struct plda_pcie_rp *plda)
++{
++ struct starfive_jh7110_pcie *pcie =
++ container_of(plda, struct starfive_jh7110_pcie, plda);
++ struct device *dev = plda->dev;
++ int ret;
++ int i;
++
++ ret = starfive_pcie_enable_phy(dev, pcie);
++ if (ret)
++ return ret;
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_RP_NEP_OFFSET,
++ STG_SYSCON_K_RP_NEP, STG_SYSCON_K_RP_NEP);
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_CKREF_SRC_MASK,
++ FIELD_PREP(STG_SYSCON_CKREF_SRC_MASK, 2));
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_CLKREQ, STG_SYSCON_CLKREQ);
++
++ ret = starfive_pcie_clk_rst_init(pcie);
++ if (ret)
++ return ret;
++
++ if (pcie->power_gpio)
++ gpiod_set_value_cansleep(pcie->power_gpio, 1);
++
++ if (pcie->reset_gpio)
++ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
++
++ /* Disable physical functions except #0 */
++ for (i = 1; i < PCIE_FUNC_NUM; i++) {
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AR_MASK,
++ STG_SYSCON_AXI4_SLVL_PHY_AR(i));
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AW_MASK,
++ STG_SYSCON_AXI4_SLVL_PHY_AW(i));
++
++ plda_pcie_disable_func(plda);
++ }
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AR_MASK, 0);
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AW_MASK, 0);
++
++ plda_pcie_enable_root_port(plda);
++ plda_pcie_write_rc_bar(plda, 0);
++
++ /* PCIe PCI Standard Configuration Identification Settings. */
++ plda_pcie_set_standard_class(plda);
++
++ /*
++ * The LTR message forwarding of PCIe Message Reception was set by core
++ * as default, but the forward id & addr are also need to be reset.
++ * If we do not disable LTR message forwarding here, or set a legal
++ * forwarding address, the kernel will get stuck after the driver probe.
++ * To workaround, disable the LTR message forwarding support on
++ * PCIe Message Reception.
++ */
++ plda_pcie_disable_ltr(plda);
++
++ /* Prefetchable memory window 64-bit addressing support */
++ plda_pcie_set_pref_win_64bit(plda);
++
++ /*
++ * Ensure that PERST has been asserted for at least 100 ms,
++ * the sleep value is T_PVPERL from PCIe CEM spec r2.0 (Table 2-4)
++ */
++ msleep(100);
++ if (pcie->reset_gpio)
++ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
++
++ /*
++ * With a Downstream Port (<=5GT/s), software must wait a minimum
++ * of 100ms following exit from a conventional reset before
++ * sending a configuration request to the device.
++ */
++ msleep(PCIE_RESET_CONFIG_DEVICE_WAIT_MS);
++
++ if (starfive_pcie_host_wait_for_link(pcie))
++ dev_info(dev, "port link down\n");
++
++ return 0;
++}
++
++static const struct plda_pcie_host_ops sf_host_ops = {
++ .host_init = starfive_pcie_host_init,
++ .host_deinit = starfive_pcie_host_deinit,
++};
++
++static const struct plda_event stf_pcie_event = {
++ .intx_event = EVENT_PM_MSI_INT_INTX,
++ .msi_event = EVENT_PM_MSI_INT_MSI
++};
++
++static int starfive_pcie_probe(struct platform_device *pdev)
++{
++ struct starfive_jh7110_pcie *pcie;
++ struct device *dev = &pdev->dev;
++ struct plda_pcie_rp *plda;
++ int ret;
++
++ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
++ if (!pcie)
++ return -ENOMEM;
++
++ plda = &pcie->plda;
++ plda->dev = dev;
++
++ ret = starfive_pcie_parse_dt(pcie, dev);
++ if (ret)
++ return ret;
++
++ plda->host_ops = &sf_host_ops;
++ plda->num_events = PLDA_MAX_EVENT_NUM;
++ /* mask doorbell event */
++ plda->events_bitmap = GENMASK(PLDA_INT_EVENT_NUM - 1, 0)
++ & ~BIT(PLDA_AXI_DOORBELL)
++ & ~BIT(PLDA_PCIE_DOORBELL);
++ plda->events_bitmap <<= PLDA_NUM_DMA_EVENTS;
++ ret = plda_pcie_host_init(&pcie->plda, &starfive_pcie_ops,
++ &stf_pcie_event);
++ if (ret)
++ return ret;
++
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_get_sync(&pdev->dev);
++ platform_set_drvdata(pdev, pcie);
++
++ return 0;
++}
++
++static void starfive_pcie_remove(struct platform_device *pdev)
++{
++ struct starfive_jh7110_pcie *pcie = platform_get_drvdata(pdev);
++
++ pm_runtime_put(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++ plda_pcie_host_deinit(&pcie->plda);
++ platform_set_drvdata(pdev, NULL);
++}
++
++static int starfive_pcie_suspend_noirq(struct device *dev)
++{
++ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
++
++ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
++ starfive_pcie_disable_phy(pcie);
++
++ return 0;
++}
++
++static int starfive_pcie_resume_noirq(struct device *dev)
++{
++ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
++ int ret;
++
++ ret = starfive_pcie_enable_phy(dev, pcie);
++ if (ret)
++ return ret;
++
++ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
++ if (ret) {
++ dev_err(dev, "failed to enable clocks\n");
++ starfive_pcie_disable_phy(pcie);
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct dev_pm_ops starfive_pcie_pm_ops = {
++ NOIRQ_SYSTEM_SLEEP_PM_OPS(starfive_pcie_suspend_noirq,
++ starfive_pcie_resume_noirq)
++};
++
++static const struct of_device_id starfive_pcie_of_match[] = {
++ { .compatible = "starfive,jh7110-pcie", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, starfive_pcie_of_match);
++
++static struct platform_driver starfive_pcie_driver = {
++ .driver = {
++ .name = "pcie-starfive",
++ .of_match_table = of_match_ptr(starfive_pcie_of_match),
++ .pm = pm_sleep_ptr(&starfive_pcie_pm_ops),
++ },
++ .probe = starfive_pcie_probe,
++ .remove_new = starfive_pcie_remove,
++};
++module_platform_driver(starfive_pcie_driver);
++
++MODULE_DESCRIPTION("StarFive JH7110 PCIe host driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch b/target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch
new file mode 100644
index 0000000000..cf14242f4a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch
@@ -0,0 +1,97 @@
+From a306724fd4f32808d1e27efbd87019d56f60db20 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 14 Aug 2023 16:06:16 +0800
+Subject: [PATCH 035/116] ASoC: dt-bindings: Add StarFive JH7110 PWM-DAC
+ controller
+
+Add bindings for the PWM-DAC controller on the JH7110
+RISC-V SoC by StarFive Ltd.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+Link: https://lore.kernel.org/r/20230814080618.10036-2-hal.feng@starfivetech.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ .../sound/starfive,jh7110-pwmdac.yaml | 76 +++++++++++++++++++
+ 1 file changed, 76 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
+@@ -0,0 +1,76 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/sound/starfive,jh7110-pwmdac.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 PWM-DAC Controller
++
++description:
++ The PWM-DAC Controller uses PWM square wave generators plus RC filters to
++ form a DAC for audio play in StarFive JH7110 SoC. This audio play controller
++ supports 16 bit audio format, up to 48K sampling frequency, up to left and
++ right dual channels.
++
++maintainers:
++ - Hal Feng <hal.feng@starfivetech.com>
++
++allOf:
++ - $ref: dai-common.yaml#
++
++properties:
++ compatible:
++ const: starfive,jh7110-pwmdac
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: PWMDAC APB
++ - description: PWMDAC CORE
++
++ clock-names:
++ items:
++ - const: apb
++ - const: core
++
++ resets:
++ maxItems: 1
++ description: PWMDAC APB
++
++ dmas:
++ maxItems: 1
++ description: TX DMA Channel
++
++ dma-names:
++ const: tx
++
++ "#sound-dai-cells":
++ const: 0
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - resets
++ - dmas
++ - dma-names
++ - "#sound-dai-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ pwmdac@100b0000 {
++ compatible = "starfive,jh7110-pwmdac";
++ reg = <0x100b0000 0x1000>;
++ clocks = <&syscrg 157>,
++ <&syscrg 158>;
++ clock-names = "apb", "core";
++ resets = <&syscrg 96>;
++ dmas = <&dma 22>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ };
diff --git a/target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch b/target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch
new file mode 100644
index 0000000000..acc859317b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch
@@ -0,0 +1,574 @@
+From a79d2ec524012e35e32a2c4ae2401d0aa763697d Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 14 Aug 2023 16:06:17 +0800
+Subject: [PATCH 036/116] ASoC: starfive: Add JH7110 PWM-DAC driver
+
+Add PWM-DAC driver support for the StarFive JH7110 SoC.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+Link: https://lore.kernel.org/r/20230814080618.10036-3-hal.feng@starfivetech.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/starfive/Kconfig | 9 +
+ sound/soc/starfive/Makefile | 1 +
+ sound/soc/starfive/jh7110_pwmdac.c | 529 +++++++++++++++++++++++++++++
+ 3 files changed, 539 insertions(+)
+ create mode 100644 sound/soc/starfive/jh7110_pwmdac.c
+
+--- a/sound/soc/starfive/Kconfig
++++ b/sound/soc/starfive/Kconfig
+@@ -7,6 +7,15 @@ config SND_SOC_STARFIVE
+ the Starfive SoCs' Audio interfaces. You will also need to
+ select the audio interfaces to support below.
+
++config SND_SOC_JH7110_PWMDAC
++ tristate "JH7110 PWM-DAC device driver"
++ depends on HAVE_CLK && SND_SOC_STARFIVE
++ select SND_SOC_GENERIC_DMAENGINE_PCM
++ select SND_SOC_SPDIF
++ help
++ Say Y or M if you want to add support for StarFive JH7110
++ PWM-DAC driver.
++
+ config SND_SOC_JH7110_TDM
+ tristate "JH7110 TDM device driver"
+ depends on HAVE_CLK && SND_SOC_STARFIVE
+--- a/sound/soc/starfive/Makefile
++++ b/sound/soc/starfive/Makefile
+@@ -1,2 +1,3 @@
+ # StarFive Platform Support
++obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
+ obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_pwmdac.c
+@@ -0,0 +1,529 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * jh7110_pwmdac.c -- StarFive JH7110 PWM-DAC driver
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ * Authors: Jenny Zhang
++ * Curry Zhang
++ * Xingyu Wu <xingyu.wu@starfivetech.com>
++ * Hal Feng <hal.feng@starfivetech.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++
++#define JH7110_PWMDAC_WDATA 0x00
++#define JH7110_PWMDAC_CTRL 0x04
++ #define JH7110_PWMDAC_ENABLE BIT(0)
++ #define JH7110_PWMDAC_SHIFT BIT(1)
++ #define JH7110_PWMDAC_DUTY_CYCLE_SHIFT 2
++ #define JH7110_PWMDAC_DUTY_CYCLE_MASK GENMASK(3, 2)
++ #define JH7110_PWMDAC_CNT_N_SHIFT 4
++ #define JH7110_PWMDAC_CNT_N_MASK GENMASK(12, 4)
++ #define JH7110_PWMDAC_DATA_CHANGE BIT(13)
++ #define JH7110_PWMDAC_DATA_MODE BIT(14)
++ #define JH7110_PWMDAC_DATA_SHIFT_SHIFT 15
++ #define JH7110_PWMDAC_DATA_SHIFT_MASK GENMASK(17, 15)
++
++enum JH7110_PWMDAC_SHIFT_VAL {
++ PWMDAC_SHIFT_8 = 0,
++ PWMDAC_SHIFT_10,
++};
++
++enum JH7110_PWMDAC_DUTY_CYCLE_VAL {
++ PWMDAC_CYCLE_LEFT = 0,
++ PWMDAC_CYCLE_RIGHT,
++ PWMDAC_CYCLE_CENTER,
++};
++
++enum JH7110_PWMDAC_CNT_N_VAL {
++ PWMDAC_SAMPLE_CNT_1 = 1,
++ PWMDAC_SAMPLE_CNT_2,
++ PWMDAC_SAMPLE_CNT_3,
++ PWMDAC_SAMPLE_CNT_512 = 512, /* max */
++};
++
++enum JH7110_PWMDAC_DATA_CHANGE_VAL {
++ NO_CHANGE = 0,
++ CHANGE,
++};
++
++enum JH7110_PWMDAC_DATA_MODE_VAL {
++ UNSIGNED_DATA = 0,
++ INVERTER_DATA_MSB,
++};
++
++enum JH7110_PWMDAC_DATA_SHIFT_VAL {
++ PWMDAC_DATA_LEFT_SHIFT_BIT_0 = 0,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_1,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_2,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_3,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_4,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_5,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_6,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_7,
++};
++
++struct jh7110_pwmdac_cfg {
++ enum JH7110_PWMDAC_SHIFT_VAL shift;
++ enum JH7110_PWMDAC_DUTY_CYCLE_VAL duty_cycle;
++ u16 cnt_n;
++ enum JH7110_PWMDAC_DATA_CHANGE_VAL data_change;
++ enum JH7110_PWMDAC_DATA_MODE_VAL data_mode;
++ enum JH7110_PWMDAC_DATA_SHIFT_VAL data_shift;
++};
++
++struct jh7110_pwmdac_dev {
++ void __iomem *base;
++ resource_size_t mapbase;
++ struct jh7110_pwmdac_cfg cfg;
++
++ struct clk_bulk_data clks[2];
++ struct reset_control *rst_apb;
++ struct device *dev;
++ struct snd_dmaengine_dai_dma_data play_dma_data;
++ u32 saved_ctrl;
++};
++
++static inline void jh7110_pwmdac_write_reg(void __iomem *io_base, int reg, u32 val)
++{
++ writel(val, io_base + reg);
++}
++
++static inline u32 jh7110_pwmdac_read_reg(void __iomem *io_base, int reg)
++{
++ return readl(io_base + reg);
++}
++
++static void jh7110_pwmdac_set_enable(struct jh7110_pwmdac_dev *dev, bool enable)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (enable)
++ value |= JH7110_PWMDAC_ENABLE;
++ else
++ value &= ~JH7110_PWMDAC_ENABLE;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_shift(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (dev->cfg.shift == PWMDAC_SHIFT_8)
++ value &= ~JH7110_PWMDAC_SHIFT;
++ else if (dev->cfg.shift == PWMDAC_SHIFT_10)
++ value |= JH7110_PWMDAC_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_duty_cycle(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ value &= ~JH7110_PWMDAC_DUTY_CYCLE_MASK;
++ value |= (dev->cfg.duty_cycle & 0x3) << JH7110_PWMDAC_DUTY_CYCLE_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_cnt_n(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ value &= ~JH7110_PWMDAC_CNT_N_MASK;
++ value |= ((dev->cfg.cnt_n - 1) & 0x1ff) << JH7110_PWMDAC_CNT_N_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_data_change(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (dev->cfg.data_change == NO_CHANGE)
++ value &= ~JH7110_PWMDAC_DATA_CHANGE;
++ else if (dev->cfg.data_change == CHANGE)
++ value |= JH7110_PWMDAC_DATA_CHANGE;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_data_mode(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (dev->cfg.data_mode == UNSIGNED_DATA)
++ value &= ~JH7110_PWMDAC_DATA_MODE;
++ else if (dev->cfg.data_mode == INVERTER_DATA_MSB)
++ value |= JH7110_PWMDAC_DATA_MODE;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_data_shift(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ value &= ~JH7110_PWMDAC_DATA_SHIFT_MASK;
++ value |= (dev->cfg.data_shift & 0x7) << JH7110_PWMDAC_DATA_SHIFT_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set(struct jh7110_pwmdac_dev *dev)
++{
++ jh7110_pwmdac_set_shift(dev);
++ jh7110_pwmdac_set_duty_cycle(dev);
++ jh7110_pwmdac_set_cnt_n(dev);
++ jh7110_pwmdac_set_enable(dev, true);
++
++ jh7110_pwmdac_set_data_change(dev);
++ jh7110_pwmdac_set_data_mode(dev);
++ jh7110_pwmdac_set_data_shift(dev);
++}
++
++static void jh7110_pwmdac_stop(struct jh7110_pwmdac_dev *dev)
++{
++ jh7110_pwmdac_set_enable(dev, false);
++}
++
++static int jh7110_pwmdac_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++ struct snd_soc_dai_link *dai_link = rtd->dai_link;
++
++ dai_link->trigger_stop = SND_SOC_TRIGGER_ORDER_LDC;
++
++ return 0;
++}
++
++static int jh7110_pwmdac_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *dai)
++{
++ struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
++ unsigned long core_clk_rate;
++ int ret;
++
++ switch (params_rate(params)) {
++ case 8000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
++ core_clk_rate = 6144000;
++ break;
++ case 11025:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_2;
++ core_clk_rate = 5644800;
++ break;
++ case 16000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
++ core_clk_rate = 12288000;
++ break;
++ case 22050:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 5644800;
++ break;
++ case 32000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 8192000;
++ break;
++ case 44100:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 11289600;
++ break;
++ case 48000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 12288000;
++ break;
++ default:
++ dev_err(dai->dev, "%d rate not supported\n",
++ params_rate(params));
++ return -EINVAL;
++ }
++
++ switch (params_channels(params)) {
++ case 1:
++ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
++ break;
++ case 2:
++ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ break;
++ default:
++ dev_err(dai->dev, "%d channels not supported\n",
++ params_channels(params));
++ return -EINVAL;
++ }
++
++ /*
++ * The clock rate always rounds down when using clk_set_rate()
++ * so increase the rate a bit
++ */
++ core_clk_rate += 64;
++ jh7110_pwmdac_set(dev);
++
++ ret = clk_set_rate(dev->clks[1].clk, core_clk_rate);
++ if (ret)
++ return dev_err_probe(dai->dev, ret,
++ "failed to set rate %lu for core clock\n",
++ core_clk_rate);
++
++ return 0;
++}
++
++static int jh7110_pwmdac_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct jh7110_pwmdac_dev *dev = snd_soc_dai_get_drvdata(dai);
++ int ret = 0;
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ jh7110_pwmdac_set(dev);
++ break;
++
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ jh7110_pwmdac_stop(dev);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static int jh7110_pwmdac_crg_enable(struct jh7110_pwmdac_dev *dev, bool enable)
++{
++ int ret;
++
++ if (enable) {
++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(dev->clks), dev->clks);
++ if (ret)
++ return dev_err_probe(dev->dev, ret,
++ "failed to enable pwmdac clocks\n");
++
++ ret = reset_control_deassert(dev->rst_apb);
++ if (ret) {
++ dev_err(dev->dev, "failed to deassert pwmdac apb reset\n");
++ goto err_rst_apb;
++ }
++ } else {
++ clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
++ }
++
++ return 0;
++
++err_rst_apb:
++ clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
++
++ return ret;
++}
++
++static int jh7110_pwmdac_dai_probe(struct snd_soc_dai *dai)
++{
++ struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
++
++ snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, NULL);
++ snd_soc_dai_set_drvdata(dai, dev);
++
++ return 0;
++}
++
++static const struct snd_soc_dai_ops jh7110_pwmdac_dai_ops = {
++ .startup = jh7110_pwmdac_startup,
++ .hw_params = jh7110_pwmdac_hw_params,
++ .trigger = jh7110_pwmdac_trigger,
++};
++
++static const struct snd_soc_component_driver jh7110_pwmdac_component = {
++ .name = "jh7110-pwmdac",
++};
++
++static struct snd_soc_dai_driver jh7110_pwmdac_dai = {
++ .name = "jh7110-pwmdac",
++ .id = 0,
++ .probe = jh7110_pwmdac_dai_probe,
++ .playback = {
++ .channels_min = 1,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_8000_48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++ .ops = &jh7110_pwmdac_dai_ops,
++};
++
++static int jh7110_pwmdac_runtime_suspend(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++
++ return jh7110_pwmdac_crg_enable(pwmdac, false);
++}
++
++static int jh7110_pwmdac_runtime_resume(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++
++ return jh7110_pwmdac_crg_enable(pwmdac, true);
++}
++
++static int jh7110_pwmdac_system_suspend(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++
++ /* save the CTRL register value */
++ pwmdac->saved_ctrl = jh7110_pwmdac_read_reg(pwmdac->base,
++ JH7110_PWMDAC_CTRL);
++ return pm_runtime_force_suspend(dev);
++}
++
++static int jh7110_pwmdac_system_resume(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++ int ret;
++
++ ret = pm_runtime_force_resume(dev);
++ if (ret)
++ return ret;
++
++ /* restore the CTRL register value */
++ jh7110_pwmdac_write_reg(pwmdac->base, JH7110_PWMDAC_CTRL,
++ pwmdac->saved_ctrl);
++ return 0;
++}
++
++static const struct dev_pm_ops jh7110_pwmdac_pm_ops = {
++ RUNTIME_PM_OPS(jh7110_pwmdac_runtime_suspend,
++ jh7110_pwmdac_runtime_resume, NULL)
++ SYSTEM_SLEEP_PM_OPS(jh7110_pwmdac_system_suspend,
++ jh7110_pwmdac_system_resume)
++};
++
++static void jh7110_pwmdac_init_params(struct jh7110_pwmdac_dev *dev)
++{
++ dev->cfg.shift = PWMDAC_SHIFT_8;
++ dev->cfg.duty_cycle = PWMDAC_CYCLE_CENTER;
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ dev->cfg.data_change = NO_CHANGE;
++ dev->cfg.data_mode = INVERTER_DATA_MSB;
++ dev->cfg.data_shift = PWMDAC_DATA_LEFT_SHIFT_BIT_0;
++
++ dev->play_dma_data.addr = dev->mapbase + JH7110_PWMDAC_WDATA;
++ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ dev->play_dma_data.fifo_size = 1;
++ dev->play_dma_data.maxburst = 16;
++}
++
++static int jh7110_pwmdac_probe(struct platform_device *pdev)
++{
++ struct jh7110_pwmdac_dev *dev;
++ struct resource *res;
++ int ret;
++
++ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
++ if (!dev)
++ return -ENOMEM;
++
++ dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
++ if (IS_ERR(dev->base))
++ return PTR_ERR(dev->base);
++
++ dev->mapbase = res->start;
++
++ dev->clks[0].id = "apb";
++ dev->clks[1].id = "core";
++
++ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(dev->clks), dev->clks);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret,
++ "failed to get pwmdac clocks\n");
++
++ dev->rst_apb = devm_reset_control_get_exclusive(&pdev->dev, NULL);
++ if (IS_ERR(dev->rst_apb))
++ return dev_err_probe(&pdev->dev, PTR_ERR(dev->rst_apb),
++ "failed to get pwmdac apb reset\n");
++
++ jh7110_pwmdac_init_params(dev);
++
++ dev->dev = &pdev->dev;
++ dev_set_drvdata(&pdev->dev, dev);
++ ret = devm_snd_soc_register_component(&pdev->dev,
++ &jh7110_pwmdac_component,
++ &jh7110_pwmdac_dai, 1);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "failed to register dai\n");
++
++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "failed to register pcm\n");
++
++ pm_runtime_enable(dev->dev);
++ if (!pm_runtime_enabled(&pdev->dev)) {
++ ret = jh7110_pwmdac_runtime_resume(&pdev->dev);
++ if (ret)
++ goto err_pm_disable;
++ }
++
++ return 0;
++
++err_pm_disable:
++ pm_runtime_disable(&pdev->dev);
++
++ return ret;
++}
++
++static int jh7110_pwmdac_remove(struct platform_device *pdev)
++{
++ pm_runtime_disable(&pdev->dev);
++ return 0;
++}
++
++static const struct of_device_id jh7110_pwmdac_of_match[] = {
++ { .compatible = "starfive,jh7110-pwmdac" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_pwmdac_of_match);
++
++static struct platform_driver jh7110_pwmdac_driver = {
++ .driver = {
++ .name = "jh7110-pwmdac",
++ .of_match_table = jh7110_pwmdac_of_match,
++ .pm = pm_ptr(&jh7110_pwmdac_pm_ops),
++ },
++ .probe = jh7110_pwmdac_probe,
++ .remove = jh7110_pwmdac_remove,
++};
++module_platform_driver(jh7110_pwmdac_driver);
++
++MODULE_AUTHOR("Jenny Zhang");
++MODULE_AUTHOR("Curry Zhang");
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH7110 PWM-DAC driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch b/target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch
new file mode 100644
index 0000000000..4833067bac
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch
@@ -0,0 +1,32 @@
+From c6b693f990e1f89ab5af0a139da31401b8cda74f Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 11 Sep 2023 23:48:39 +0100
+Subject: [PATCH 037/116] ASoC: Update jh7110 PWM DAC for ops move
+
+For some reason the JH7110 PWM DAC driver made it through build testing
+in spite of not being updated for the move of probe() to the ops struct.
+Make the required update.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/starfive/jh7110_pwmdac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/starfive/jh7110_pwmdac.c
++++ b/sound/soc/starfive/jh7110_pwmdac.c
+@@ -357,6 +357,7 @@ static int jh7110_pwmdac_dai_probe(struc
+ }
+
+ static const struct snd_soc_dai_ops jh7110_pwmdac_dai_ops = {
++ .probe = jh7110_pwmdac_dai_probe,
+ .startup = jh7110_pwmdac_startup,
+ .hw_params = jh7110_pwmdac_hw_params,
+ .trigger = jh7110_pwmdac_trigger,
+@@ -369,7 +370,6 @@ static const struct snd_soc_component_dr
+ static struct snd_soc_dai_driver jh7110_pwmdac_dai = {
+ .name = "jh7110-pwmdac",
+ .id = 0,
+- .probe = jh7110_pwmdac_dai_probe,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 2,
diff --git a/target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch b/target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch
new file mode 100644
index 0000000000..9b5f553f8c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch
@@ -0,0 +1,52 @@
+From 312c3c407c363f0ec7417d2d389cbe936c503729 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Sat, 14 Oct 2023 00:19:49 +0200
+Subject: [PATCH 038/116] ASoC: starfive/jh7110-pwmdac: Convert to platform
+ remove callback returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20231013221945.1489203-12-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/starfive/jh7110_pwmdac.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/starfive/jh7110_pwmdac.c
++++ b/sound/soc/starfive/jh7110_pwmdac.c
+@@ -498,10 +498,9 @@ err_pm_disable:
+ return ret;
+ }
+
+-static int jh7110_pwmdac_remove(struct platform_device *pdev)
++static void jh7110_pwmdac_remove(struct platform_device *pdev)
+ {
+ pm_runtime_disable(&pdev->dev);
+- return 0;
+ }
+
+ static const struct of_device_id jh7110_pwmdac_of_match[] = {
+@@ -517,7 +516,7 @@ static struct platform_driver jh7110_pwm
+ .pm = pm_ptr(&jh7110_pwmdac_pm_ops),
+ },
+ .probe = jh7110_pwmdac_probe,
+- .remove = jh7110_pwmdac_remove,
++ .remove_new = jh7110_pwmdac_remove,
+ };
+ module_platform_driver(jh7110_pwmdac_driver);
+
diff --git a/target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch b/target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
new file mode 100644
index 0000000000..bcc9af2d2c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
@@ -0,0 +1,35 @@
+From 8d84bac6d7471ba2e29b33d19a2ef887822e9cce Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:25 +0100
+Subject: [PATCH 039/116] dt-bindings: power: Add power-domain header for
+ JH7110
+
+Add power-domain header for JH7110 SoC, it can use to operate dphy
+power.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-grumbly-rewrite-34c85539f2ed@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ include/dt-bindings/power/starfive,jh7110-pmu.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
++++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+ /*
+- * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ * Author: Walker Chen <walker.chen@starfivetech.com>
+ */
+ #ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
+@@ -14,4 +14,7 @@
+ #define JH7110_PD_ISP 5
+ #define JH7110_PD_VENC 6
+
++#define JH7110_PD_DPHY_TX 0
++#define JH7110_PD_DPHY_RX 1
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch b/target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch
new file mode 100644
index 0000000000..335193fbb6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch
@@ -0,0 +1,31 @@
+From 0ac8e8b0e65d242f455401df0cc6c6d4772216e6 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:26 +0100
+Subject: [PATCH 040/116] pmdomain: starfive: Replace SOC_STARFIVE with
+ ARCH_STARFIVE
+
+Using ARCH_FOO symbol is preferred than SOC_FOO.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-legibly-treachery-567cffcb5604@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/soc/starfive/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/soc/starfive/Kconfig
++++ b/drivers/soc/starfive/Kconfig
+@@ -3,8 +3,8 @@
+ config JH71XX_PMU
+ bool "Support PMU for StarFive JH71XX Soc"
+ depends on PM
+- depends on SOC_STARFIVE || COMPILE_TEST
+- default SOC_STARFIVE
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ default ARCH_STARFIVE
+ select PM_GENERIC_DOMAINS
+ help
+ Say 'y' here to enable support power domain support.
diff --git a/target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch b/target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch
new file mode 100644
index 0000000000..7425dd6dbb
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch
@@ -0,0 +1,179 @@
+From a1ba60e35ca7f1b85243054556ecde2e259619e1 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:27 +0100
+Subject: [PATCH 041/116] pmdomain: starfive: Extract JH7110 pmu private
+ operations
+
+Move JH7110 private operation into private data of compatible. Convenient
+to add AON PMU which would not have interrupts property.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-slideshow-luckiness-38ff17de84c6@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 89 ++++++++++++++++++--------
+ 1 file changed, 62 insertions(+), 27 deletions(-)
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -51,9 +51,17 @@ struct jh71xx_domain_info {
+ u8 bit;
+ };
+
++struct jh71xx_pmu;
++struct jh71xx_pmu_dev;
++
+ struct jh71xx_pmu_match_data {
+ const struct jh71xx_domain_info *domain_info;
+ int num_domains;
++ unsigned int pmu_status;
++ int (*pmu_parse_irq)(struct platform_device *pdev,
++ struct jh71xx_pmu *pmu);
++ int (*pmu_set_state)(struct jh71xx_pmu_dev *pmd,
++ u32 mask, bool on);
+ };
+
+ struct jh71xx_pmu {
+@@ -79,12 +87,12 @@ static int jh71xx_pmu_get_state(struct j
+ if (!mask)
+ return -EINVAL;
+
+- *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
++ *is_on = readl(pmu->base + pmu->match_data->pmu_status) & mask;
+
+ return 0;
+ }
+
+-static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
++static int jh7110_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
+ {
+ struct jh71xx_pmu *pmu = pmd->pmu;
+ unsigned long flags;
+@@ -92,22 +100,8 @@ static int jh71xx_pmu_set_state(struct j
+ u32 mode;
+ u32 encourage_lo;
+ u32 encourage_hi;
+- bool is_on;
+ int ret;
+
+- ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
+- if (ret) {
+- dev_dbg(pmu->dev, "unable to get current state for %s\n",
+- pmd->genpd.name);
+- return ret;
+- }
+-
+- if (is_on == on) {
+- dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
+- pmd->genpd.name, on ? "en" : "dis");
+- return 0;
+- }
+-
+ spin_lock_irqsave(&pmu->lock, flags);
+
+ /*
+@@ -166,6 +160,29 @@ static int jh71xx_pmu_set_state(struct j
+ return 0;
+ }
+
++static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
++{
++ struct jh71xx_pmu *pmu = pmd->pmu;
++ const struct jh71xx_pmu_match_data *match_data = pmu->match_data;
++ bool is_on;
++ int ret;
++
++ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
++ if (ret) {
++ dev_dbg(pmu->dev, "unable to get current state for %s\n",
++ pmd->genpd.name);
++ return ret;
++ }
++
++ if (is_on == on) {
++ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
++ pmd->genpd.name, on ? "en" : "dis");
++ return 0;
++ }
++
++ return match_data->pmu_set_state(pmd, mask, on);
++}
++
+ static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
+ {
+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
+@@ -226,6 +243,25 @@ static irqreturn_t jh71xx_pmu_interrupt(
+ return IRQ_HANDLED;
+ }
+
++static int jh7110_pmu_parse_irq(struct platform_device *pdev, struct jh71xx_pmu *pmu)
++{
++ struct device *dev = &pdev->dev;
++ int ret;
++
++ pmu->irq = platform_get_irq(pdev, 0);
++ if (pmu->irq < 0)
++ return pmu->irq;
++
++ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
++ 0, pdev->name, pmu);
++ if (ret)
++ dev_err(dev, "failed to request irq\n");
++
++ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
++
++ return 0;
++}
++
+ static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
+ {
+ struct jh71xx_pmu_dev *pmd;
+@@ -275,19 +311,18 @@ static int jh71xx_pmu_probe(struct platf
+ if (IS_ERR(pmu->base))
+ return PTR_ERR(pmu->base);
+
+- pmu->irq = platform_get_irq(pdev, 0);
+- if (pmu->irq < 0)
+- return pmu->irq;
+-
+- ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
+- 0, pdev->name, pmu);
+- if (ret)
+- dev_err(dev, "failed to request irq\n");
++ spin_lock_init(&pmu->lock);
+
+ match_data = of_device_get_match_data(dev);
+ if (!match_data)
+ return -EINVAL;
+
++ ret = match_data->pmu_parse_irq(pdev, pmu);
++ if (ret) {
++ dev_err(dev, "failed to parse irq\n");
++ return ret;
++ }
++
+ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
+ sizeof(struct generic_pm_domain *),
+ GFP_KERNEL);
+@@ -307,9 +342,6 @@ static int jh71xx_pmu_probe(struct platf
+ }
+ }
+
+- spin_lock_init(&pmu->lock);
+- jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
+-
+ ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+ if (ret) {
+ dev_err(dev, "failed to register genpd driver: %d\n", ret);
+@@ -357,6 +389,9 @@ static const struct jh71xx_domain_info j
+ static const struct jh71xx_pmu_match_data jh7110_pmu = {
+ .num_domains = ARRAY_SIZE(jh7110_power_domains),
+ .domain_info = jh7110_power_domains,
++ .pmu_status = JH71XX_PMU_CURR_POWER_MODE,
++ .pmu_parse_irq = jh7110_pmu_parse_irq,
++ .pmu_set_state = jh7110_pmu_set_state,
+ };
+
+ static const struct of_device_id jh71xx_pmu_of_match[] = {
diff --git a/target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch b/target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch
new file mode 100644
index 0000000000..2563d5421c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch
@@ -0,0 +1,122 @@
+From 1bf849b606d0b4cae643f96685d3d3981643683d Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:28 +0100
+Subject: [PATCH 042/116] pmdomain: starfive: Add JH7110 AON PMU support
+
+Add AON PMU for StarFive JH7110 SoC. It can be used to turn on/off the
+dphy rx/tx power switch.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-dude-imprecise-fc32622bc947@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 57 +++++++++++++++++++++++---
+ 1 file changed, 52 insertions(+), 5 deletions(-)
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -2,7 +2,7 @@
+ /*
+ * StarFive JH71XX PMU (Power Management Unit) Controller Driver
+ *
+- * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ */
+
+ #include <linux/interrupt.h>
+@@ -24,6 +24,9 @@
+ #define JH71XX_PMU_EVENT_STATUS 0x88
+ #define JH71XX_PMU_INT_STATUS 0x8C
+
++/* aon pmu register offset */
++#define JH71XX_AON_PMU_SWITCH 0x00
++
+ /* sw encourage cfg */
+ #define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
+ #define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
+@@ -160,6 +163,26 @@ static int jh7110_pmu_set_state(struct j
+ return 0;
+ }
+
++static int jh7110_aon_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
++{
++ struct jh71xx_pmu *pmu = pmd->pmu;
++ unsigned long flags;
++ u32 val;
++
++ spin_lock_irqsave(&pmu->lock, flags);
++ val = readl(pmu->base + JH71XX_AON_PMU_SWITCH);
++
++ if (on)
++ val |= mask;
++ else
++ val &= ~mask;
++
++ writel(val, pmu->base + JH71XX_AON_PMU_SWITCH);
++ spin_unlock_irqrestore(&pmu->lock, flags);
++
++ return 0;
++}
++
+ static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
+ {
+ struct jh71xx_pmu *pmu = pmd->pmu;
+@@ -317,10 +340,12 @@ static int jh71xx_pmu_probe(struct platf
+ if (!match_data)
+ return -EINVAL;
+
+- ret = match_data->pmu_parse_irq(pdev, pmu);
+- if (ret) {
+- dev_err(dev, "failed to parse irq\n");
+- return ret;
++ if (match_data->pmu_parse_irq) {
++ ret = match_data->pmu_parse_irq(pdev, pmu);
++ if (ret) {
++ dev_err(dev, "failed to parse irq\n");
++ return ret;
++ }
+ }
+
+ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
+@@ -394,11 +419,32 @@ static const struct jh71xx_pmu_match_dat
+ .pmu_set_state = jh7110_pmu_set_state,
+ };
+
++static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
++ [JH7110_PD_DPHY_TX] = {
++ .name = "DPHY-TX",
++ .bit = 30,
++ },
++ [JH7110_PD_DPHY_RX] = {
++ .name = "DPHY-RX",
++ .bit = 31,
++ },
++};
++
++static const struct jh71xx_pmu_match_data jh7110_aon_pmu = {
++ .num_domains = ARRAY_SIZE(jh7110_aon_power_domains),
++ .domain_info = jh7110_aon_power_domains,
++ .pmu_status = JH71XX_AON_PMU_SWITCH,
++ .pmu_set_state = jh7110_aon_pmu_set_state,
++};
++
+ static const struct of_device_id jh71xx_pmu_of_match[] = {
+ {
+ .compatible = "starfive,jh7110-pmu",
+ .data = (void *)&jh7110_pmu,
+ }, {
++ .compatible = "starfive,jh7110-aon-syscon",
++ .data = (void *)&jh7110_aon_pmu,
++ }, {
+ /* sentinel */
+ }
+ };
+@@ -414,5 +460,6 @@ static struct platform_driver jh71xx_pmu
+ builtin_platform_driver(jh71xx_pmu_driver);
+
+ MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
++MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
+ MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
+ MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch b/target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch
new file mode 100644
index 0000000000..52be89f29e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch
@@ -0,0 +1,36 @@
+From dff6605dcd1fc1e2af1437e59187a6f71ce389cd Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@linaro.org>
+Date: Mon, 11 Sep 2023 17:22:15 +0200
+Subject: [PATCH 043/116] pmdomain: Prepare to move Kconfig files into the
+ pmdomain subsystem
+
+Rather than having the various Kconfig files for the genpd providers
+sprinkled across subsystems, let's prepare to move them into the pmdomain
+subsystem along with the implementations.
+
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/Kconfig | 2 ++
+ drivers/pmdomain/Kconfig | 4 ++++
+ 2 files changed, 6 insertions(+)
+ create mode 100644 drivers/pmdomain/Kconfig
+
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -175,6 +175,8 @@ source "drivers/soundwire/Kconfig"
+
+ source "drivers/soc/Kconfig"
+
++source "drivers/pmdomain/Kconfig"
++
+ source "drivers/devfreq/Kconfig"
+
+ source "drivers/extcon/Kconfig"
+--- /dev/null
++++ b/drivers/pmdomain/Kconfig
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0-only
++menu "PM Domains"
++
++endmenu
diff --git a/target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch b/target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch
new file mode 100644
index 0000000000..909f4cc63a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch
@@ -0,0 +1,69 @@
+From de12fe43dbd0ea9fa980ffa05822bd7fd5eed330 Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@linaro.org>
+Date: Tue, 12 Sep 2023 13:31:44 +0200
+Subject: [PATCH 044/116] pmdomain: starfive: Move Kconfig file to the pmdomain
+ subsystem
+
+The Kconfig belongs closer to the corresponding implementation, hence let's
+move it from the soc subsystem to the pmdomain subsystem.
+
+Cc: Walker Chen <walker.chen@starfivetech.com>
+Cc: Conor Dooley <conor@kernel.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/Kconfig | 2 ++
+ drivers/{soc => pmdomain}/starfive/Kconfig | 0
+ drivers/soc/Kconfig | 1 -
+ 3 files changed, 2 insertions(+), 1 deletion(-)
+ rename drivers/{soc => pmdomain}/starfive/Kconfig (100%)
+
+--- a/drivers/pmdomain/Kconfig
++++ b/drivers/pmdomain/Kconfig
+@@ -1,4 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ menu "PM Domains"
+
++source "drivers/pmdomain/starfive/Kconfig"
++
+ endmenu
+--- a/drivers/soc/Kconfig
++++ b/drivers/soc/Kconfig
+@@ -24,7 +24,6 @@ source "drivers/soc/renesas/Kconfig"
+ source "drivers/soc/rockchip/Kconfig"
+ source "drivers/soc/samsung/Kconfig"
+ source "drivers/soc/sifive/Kconfig"
+-source "drivers/soc/starfive/Kconfig"
+ source "drivers/soc/sunxi/Kconfig"
+ source "drivers/soc/tegra/Kconfig"
+ source "drivers/soc/ti/Kconfig"
+--- /dev/null
++++ b/drivers/pmdomain/starfive/Kconfig
+@@ -0,0 +1,12 @@
++# SPDX-License-Identifier: GPL-2.0
++
++config JH71XX_PMU
++ bool "Support PMU for StarFive JH71XX Soc"
++ depends on PM
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ default ARCH_STARFIVE
++ select PM_GENERIC_DOMAINS
++ help
++ Say 'y' here to enable support power domain support.
++ In order to meet low power requirements, a Power Management Unit (PMU)
++ is designed for controlling power resources in StarFive JH71XX SoCs.
+--- a/drivers/soc/starfive/Kconfig
++++ /dev/null
+@@ -1,12 +0,0 @@
+-# SPDX-License-Identifier: GPL-2.0
+-
+-config JH71XX_PMU
+- bool "Support PMU for StarFive JH71XX Soc"
+- depends on PM
+- depends on ARCH_STARFIVE || COMPILE_TEST
+- default ARCH_STARFIVE
+- select PM_GENERIC_DOMAINS
+- help
+- Say 'y' here to enable support power domain support.
+- In order to meet low power requirements, a Power Management Unit (PMU)
+- is designed for controlling power resources in StarFive JH71XX SoCs.
diff --git a/target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch b/target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch
new file mode 100644
index 0000000000..c6e0012528
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch
@@ -0,0 +1,31 @@
+From cac9ce9c7f388a741389b1ec47af65420254db55 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 27 Sep 2023 06:07:33 -0700
+Subject: [PATCH 045/116] dt-bindings: power: Update prefixes for AON power
+ domain
+
+Use "JH7110_AON_PD_" prefix for AON power domain for JH7110 SoC.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230927130734.9921-2-changhuang.liang@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ include/dt-bindings/power/starfive,jh7110-pmu.h | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
++++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
+@@ -14,7 +14,8 @@
+ #define JH7110_PD_ISP 5
+ #define JH7110_PD_VENC 6
+
+-#define JH7110_PD_DPHY_TX 0
+-#define JH7110_PD_DPHY_RX 1
++/* AON Power Domain */
++#define JH7110_AON_PD_DPHY_TX 0
++#define JH7110_AON_PD_DPHY_RX 1
+
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch b/target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch
new file mode 100644
index 0000000000..5cb89ae052
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch
@@ -0,0 +1,32 @@
+From 3ea89ffbd6cc5a15acca6bc2130572f8bd85b9d4 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 27 Sep 2023 06:07:34 -0700
+Subject: [PATCH 046/116] pmdomain: starfive: Update prefixes for AON power
+ domain
+
+Use "JH7110_AON_PD_" prefix for AON power doamin for JH7110 SoC.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Link: https://lore.kernel.org/r/20230927130734.9921-3-changhuang.liang@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -420,11 +420,11 @@ static const struct jh71xx_pmu_match_dat
+ };
+
+ static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
+- [JH7110_PD_DPHY_TX] = {
++ [JH7110_AON_PD_DPHY_TX] = {
+ .name = "DPHY-TX",
+ .bit = 30,
+ },
+- [JH7110_PD_DPHY_RX] = {
++ [JH7110_AON_PD_DPHY_RX] = {
+ .name = "DPHY-RX",
+ .bit = 31,
+ },
diff --git a/target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch b/target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch
new file mode 100644
index 0000000000..782e71a0eb
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch
@@ -0,0 +1,30 @@
+From e7e3d62b7a470ddf15e30574232b52b2e23ba606 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Mon, 21 Aug 2023 22:41:50 +0800
+Subject: [PATCH 047/116] riscv: dts: starfive: pinfunc: Fix the pins name of
+ I2STX1
+
+These pins are actually I2STX1 clock input, not I2STX0,
+so their names should be changed.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-pinfunc.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
++++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
+@@ -240,8 +240,8 @@
+ #define GPI_SYS_MCLK_EXT 30
+ #define GPI_SYS_I2SRX_BCLK 31
+ #define GPI_SYS_I2SRX_LRCK 32
+-#define GPI_SYS_I2STX0_BCLK 33
+-#define GPI_SYS_I2STX0_LRCK 34
++#define GPI_SYS_I2STX1_BCLK 33
++#define GPI_SYS_I2STX1_LRCK 34
+ #define GPI_SYS_TDM_CLK 35
+ #define GPI_SYS_TDM_RXD 36
+ #define GPI_SYS_TDM_SYNC 37
diff --git a/target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch b/target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch
new file mode 100644
index 0000000000..75dd965c94
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch
@@ -0,0 +1,536 @@
+From a3d3f611f31fa2dca3deefa7cd443abca02e03fa Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 11 Apr 2023 16:31:15 +0800
+Subject: [PATCH 048/116] riscv: dts: starfive: Add full support (except VIN
+ and VOUT) for JH7110 and VisionFive 2 board
+
+Merge all StarFive dts patches together except VIN and VOUT.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../jh7110-starfive-visionfive-2.dtsi | 199 +++++++++++++++
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 233 ++++++++++++++++++
+ 2 files changed, 432 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -19,6 +19,8 @@
+ i2c6 = &i2c6;
+ mmc0 = &mmc0;
+ mmc1 = &mmc1;
++ pcie0 = &pcie0;
++ pcie1 = &pcie1;
+ serial0 = &uart0;
+ };
+
+@@ -40,6 +42,33 @@
+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
+ priority = <224>;
+ };
++
++ pwmdac_codec: pwmdac-codec {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ sound-pwmdac {
++ compatible = "simple-audio-card";
++ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&pwmdac>;
++ };
++
++ codec {
++ sound-dai = <&pwmdac_codec>;
++ };
++ };
++ };
+ };
+
+ &dvp_clk {
+@@ -202,6 +231,24 @@
+ status = "okay";
+ };
+
++&i2srx {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2srx_pins>;
++ status = "okay";
++};
++
++&i2stx0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&mclk_ext_pins>;
++ status = "okay";
++};
++
++&i2stx1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2stx1_pins>;
++ status = "okay";
++};
++
+ &mmc0 {
+ max-frequency = <100000000>;
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
+@@ -235,6 +282,34 @@
+ status = "okay";
+ };
+
++&pcie0 {
++ perst-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie0_pins>;
++ status = "okay";
++};
++
++&pcie1 {
++ perst-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie1_pins>;
++ status = "okay";
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_pins>;
++ status = "okay";
++};
++
++&pwmdac {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwmdac_pins>;
++ status = "okay";
++};
++
+ &qspi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -340,6 +415,46 @@
+ };
+ };
+
++ i2srx_pins: i2srx-0 {
++ clk-sd-pins {
++ pinmux = <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_BCLK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_LRCK)>,
++ <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_BCLK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_LRCK)>,
++ <GPIOMUX(61, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_SDIN0)>;
++ input-enable;
++ };
++ };
++
++ i2stx1_pins: i2stx1-0 {
++ sd-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ };
++ };
++
++ mclk_ext_pins: mclk-ext-0 {
++ mclk-ext-pins {
++ pinmux = <GPIOMUX(4, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_MCLK_EXT)>;
++ input-enable;
++ };
++ };
++
+ mmc0_pins: mmc0-0 {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+@@ -404,6 +519,86 @@
+ slew-rate = <0>;
+ };
+ };
++
++ pcie0_pins: pcie0-0 {
++ clkreq-pins {
++ pinmux = <GPIOMUX(27, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-down;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ wake-pins {
++ pinmux = <GPIOMUX(32, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pcie1_pins: pcie1-0 {
++ clkreq-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-down;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ wake-pins {
++ pinmux = <GPIOMUX(21, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pwm_pins: pwm-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
++ GPOEN_SYS_PWM0_CHANNEL0,
++ GPI_NONE)>,
++ <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
++ GPOEN_SYS_PWM0_CHANNEL1,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pwmdac_pins: pwmdac-0 {
++ pwmdac-pins {
++ pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(34, GPOUT_SYS_PWMDAC_RIGHT,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <2>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
+
+ spi0_pins: spi0-0 {
+ mosi-pins {
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -244,6 +244,7 @@
+ clock-output-names = "dvp_clk";
+ #clock-cells = <0>;
+ };
++
+ gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
+ compatible = "fixed-clock";
+ clock-output-names = "gmac0_rgmii_rxin";
+@@ -512,6 +513,43 @@
+ status = "disabled";
+ };
+
++ pwmdac: pwmdac@100b0000 {
++ compatible = "starfive,jh7110-pwmdac";
++ reg = <0x0 0x100b0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_PWMDAC_APB>,
++ <&syscrg JH7110_SYSCLK_PWMDAC_CORE>;
++ clock-names = "apb", "core";
++ resets = <&syscrg JH7110_SYSRST_PWMDAC_APB>;
++ dmas = <&dma 22>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2srx: i2s@100e0000 {
++ compatible = "starfive,jh7110-i2srx";
++ reg = <0x0 0x100e0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2SRX_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2SRX_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>,
++ <&syscrg JH7110_SYSCLK_I2SRX_BCLK>,
++ <&syscrg JH7110_SYSCLK_I2SRX_LRCK>,
++ <&i2srx_bclk_ext>,
++ <&i2srx_lrck_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner", "mclk_ext", "bclk",
++ "lrck", "bclk_ext", "lrck_ext";
++ resets = <&syscrg JH7110_SYSRST_I2SRX_APB>,
++ <&syscrg JH7110_SYSRST_I2SRX_BCLK>;
++ dmas = <0>, <&dma 24>;
++ dma-names = "tx", "rx";
++ starfive,syscon = <&sys_syscon 0x18 0x2>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
+ usb0: usb@10100000 {
+ compatible = "starfive,jh7110-usb";
+ ranges = <0x0 0x0 0x10100000 0x100000>;
+@@ -736,6 +774,56 @@
+ status = "disabled";
+ };
+
++ i2stx0: i2s@120b0000 {
++ compatible = "starfive,jh7110-i2stx0";
++ reg = <0x0 0x120b0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2STX0_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2STX0_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner","mclk_ext";
++ resets = <&syscrg JH7110_SYSRST_I2STX0_APB>,
++ <&syscrg JH7110_SYSRST_I2STX0_BCLK>;
++ dmas = <&dma 47>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2stx1: i2s@120c0000 {
++ compatible = "starfive,jh7110-i2stx1";
++ reg = <0x0 0x120c0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2STX1_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2STX1_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>,
++ <&syscrg JH7110_SYSCLK_I2STX1_BCLK>,
++ <&syscrg JH7110_SYSCLK_I2STX1_LRCK>,
++ <&i2stx_bclk_ext>,
++ <&i2stx_lrck_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner", "mclk_ext", "bclk",
++ "lrck", "bclk_ext", "lrck_ext";
++ resets = <&syscrg JH7110_SYSRST_I2STX1_APB>,
++ <&syscrg JH7110_SYSRST_I2STX1_BCLK>;
++ dmas = <&dma 48>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ pwm: pwm@120d0000 {
++ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
++ reg = <0x0 0x120d0000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
++ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
+ sfctemp: temperature-sensor@120e0000 {
+ compatible = "starfive,jh7110-temp";
+ reg = <0x0 0x120e0000 0x0 0x10000>;
+@@ -811,6 +899,26 @@
+ #gpio-cells = <2>;
+ };
+
++ timer@13050000 {
++ compatible = "starfive,jh7110-timer";
++ reg = <0x0 0x13050000 0x0 0x10000>;
++ interrupts = <69>, <70>, <71>, <72>;
++ clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>,
++ <&syscrg JH7110_SYSCLK_TIMER0>,
++ <&syscrg JH7110_SYSCLK_TIMER1>,
++ <&syscrg JH7110_SYSCLK_TIMER2>,
++ <&syscrg JH7110_SYSCLK_TIMER3>;
++ clock-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ resets = <&syscrg JH7110_SYSRST_TIMER_APB>,
++ <&syscrg JH7110_SYSRST_TIMER0>,
++ <&syscrg JH7110_SYSRST_TIMER1>,
++ <&syscrg JH7110_SYSRST_TIMER2>,
++ <&syscrg JH7110_SYSRST_TIMER3>;
++ reset-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ };
++
+ watchdog@13070000 {
+ compatible = "starfive,jh7110-wdt";
+ reg = <0x0 0x13070000 0x0 0x10000>;
+@@ -1011,6 +1119,32 @@
+ #power-domain-cells = <1>;
+ };
+
++ csi2rx: csi-bridge@19800000 {
++ compatible = "starfive,jh7110-csi2rx";
++ reg = <0x0 0x19800000 0x0 0x10000>;
++ clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>,
++ <&ispcrg JH7110_ISPCLK_VIN_APB>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>;
++ clock-names = "sys_clk", "p_clk",
++ "pixel_if0_clk", "pixel_if1_clk",
++ "pixel_if2_clk", "pixel_if3_clk";
++ resets = <&ispcrg JH7110_ISPRST_VIN_SYS>,
++ <&ispcrg JH7110_ISPRST_VIN_APB>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>;
++ reset-names = "sys", "reg_bank",
++ "pixel_if0", "pixel_if1",
++ "pixel_if2", "pixel_if3";
++ phys = <&csi_phy>;
++ phy-names = "dphy";
++ status = "disabled";
++ };
++
+ ispcrg: clock-controller@19810000 {
+ compatible = "starfive,jh7110-ispcrg";
+ reg = <0x0 0x19810000 0x0 0x10000>;
+@@ -1028,6 +1162,19 @@
+ power-domains = <&pwrc JH7110_PD_ISP>;
+ };
+
++ csi_phy: phy@19820000 {
++ compatible = "starfive,jh7110-dphy-rx";
++ reg = <0x0 0x19820000 0x0 0x10000>;
++ clocks = <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>;
++ clock-names = "cfg", "ref", "tx";
++ resets = <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
++ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>;
++ power-domains = <&aon_syscon JH7110_AON_PD_DPHY_RX>;
++ #phy-cells = <0>;
++ };
++
+ voutcrg: clock-controller@295c0000 {
+ compatible = "starfive,jh7110-voutcrg";
+ reg = <0x0 0x295c0000 0x0 0x10000>;
+@@ -1045,5 +1192,91 @@
+ #reset-cells = <1>;
+ power-domains = <&pwrc JH7110_PD_VOUT>;
+ };
++
++ pcie0: pcie@940000000 {
++ compatible = "starfive,jh7110-pcie";
++ reg = <0x9 0x40000000 0x0 0x1000000>,
++ <0x0 0x2b000000 0x0 0x100000>;
++ reg-names = "cfg", "apb";
++ linux,pci-domain = <0>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++ #interrupt-cells = <1>;
++ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
++ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
++ interrupts = <56>;
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
++ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
++ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
++ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
++ msi-controller;
++ device_type = "pci";
++ starfive,stg-syscon = <&stg_syscon>;
++ bus-range = <0x0 0xff>;
++ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
++ <&stgcrg JH7110_STGCLK_PCIE0_TL>,
++ <&stgcrg JH7110_STGCLK_PCIE0_AXI_MST0>,
++ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
++ clock-names = "noc", "tl", "axi_mst0", "apb";
++ resets = <&stgcrg JH7110_STGRST_PCIE0_AXI_MST0>,
++ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV0>,
++ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV>,
++ <&stgcrg JH7110_STGRST_PCIE0_BRG>,
++ <&stgcrg JH7110_STGRST_PCIE0_CORE>,
++ <&stgcrg JH7110_STGRST_PCIE0_APB>;
++ reset-names = "mst0", "slv0", "slv", "brg",
++ "core", "apb";
++ status = "disabled";
++
++ pcie_intc0: interrupt-controller {
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-controller;
++ };
++ };
++
++ pcie1: pcie@9c0000000 {
++ compatible = "starfive,jh7110-pcie";
++ reg = <0x9 0xc0000000 0x0 0x1000000>,
++ <0x0 0x2c000000 0x0 0x100000>;
++ reg-names = "cfg", "apb";
++ linux,pci-domain = <1>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++ #interrupt-cells = <1>;
++ ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>,
++ <0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>;
++ interrupts = <57>;
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc1 0x1>,
++ <0x0 0x0 0x0 0x2 &pcie_intc1 0x2>,
++ <0x0 0x0 0x0 0x3 &pcie_intc1 0x3>,
++ <0x0 0x0 0x0 0x4 &pcie_intc1 0x4>;
++ msi-controller;
++ device_type = "pci";
++ starfive,stg-syscon = <&stg_syscon>;
++ bus-range = <0x0 0xff>;
++ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
++ <&stgcrg JH7110_STGCLK_PCIE1_TL>,
++ <&stgcrg JH7110_STGCLK_PCIE1_AXI_MST0>,
++ <&stgcrg JH7110_STGCLK_PCIE1_APB>;
++ clock-names = "noc", "tl", "axi_mst0", "apb";
++ resets = <&stgcrg JH7110_STGRST_PCIE1_AXI_MST0>,
++ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV0>,
++ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV>,
++ <&stgcrg JH7110_STGRST_PCIE1_BRG>,
++ <&stgcrg JH7110_STGRST_PCIE1_CORE>,
++ <&stgcrg JH7110_STGRST_PCIE1_APB>;
++ reset-names = "mst0", "slv0", "slv", "brg",
++ "core", "apb";
++ status = "disabled";
++
++ pcie_intc1: interrupt-controller {
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-controller;
++ };
++ };
+ };
+ };
diff --git a/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch
new file mode 100644
index 0000000000..a7a832dce2
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch
@@ -0,0 +1,147 @@
+From ae7b57a0c69953f5ec06a378aedeed4c86637998 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 11 Apr 2023 16:25:57 +0800
+Subject: [PATCH 049/116] MAINTAINERS: Update all StarFive entries
+
+Merge all StarFive maintainers changes together.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ MAINTAINERS | 61 +++++++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 57 insertions(+), 4 deletions(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -7053,6 +7053,14 @@ T: git git://anongit.freedesktop.org/drm
+ F: Documentation/devicetree/bindings/display/rockchip/
+ F: drivers/gpu/drm/rockchip/
+
++DRM DRIVERS FOR STARFIVE
++M: Keith Zhao <keith.zhao@starfivetech.com>
++L: dri-devel@lists.freedesktop.org
++S: Maintained
++T: git git://anongit.freedesktop.org/drm/drm-misc
++F: Documentation/devicetree/bindings/display/starfive/
++F: drivers/gpu/drm/verisilicon/
++
+ DRM DRIVERS FOR STI
+ M: Alain Volmat <alain.volmat@foss.st.com>
+ L: dri-devel@lists.freedesktop.org
+@@ -16016,6 +16024,13 @@ F: Documentation/i2c/busses/i2c-ocores.r
+ F: drivers/i2c/busses/i2c-ocores.c
+ F: include/linux/platform_data/i2c-ocores.h
+
++OPENCORES PWM DRIVER
++M: William Qiu <william.qiu@starfivetech.com>
++M: Hal Feng <hal.feng@starfivetech.com>
++S: Supported
++F: Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
++F: drivers/pwm/pwm-ocores.c
++
+ OPENRISC ARCHITECTURE
+ M: Jonas Bonn <jonas@southpole.se>
+ M: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+@@ -16427,6 +16442,14 @@ S: Maintained
+ F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
+ F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
+
++PCI DRIVER FOR PLDA PCIE IP
++M: Daire McNamara <daire.mcnamara@microchip.com>
++M: Kevin Xie <kevin.xie@starfivetech.com>
++L: linux-pci@vger.kernel.org
++S: Maintained
++F: Documentation/devicetree/bindings/pci/plda,*
++F: drivers/pci/controller/plda/*plda*
++
+ PCI DRIVER FOR RENESAS R-CAR
+ M: Marek Vasut <marek.vasut+renesas@gmail.com>
+ M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+@@ -16658,7 +16681,7 @@ M: Daire McNamara <daire.mcnamara@microc
+ L: linux-pci@vger.kernel.org
+ S: Supported
+ F: Documentation/devicetree/bindings/pci/microchip*
+-F: drivers/pci/controller/*microchip*
++F: drivers/pci/controller/plda/*microchip*
+
+ PCIE DRIVER FOR QUALCOMM MSM
+ M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+@@ -16682,6 +16705,13 @@ S: Maintained
+ F: Documentation/devicetree/bindings/pci/socionext,uniphier-pcie*
+ F: drivers/pci/controller/dwc/pcie-uniphier*
+
++PCIE DRIVER FOR STARFIVE JH71x0
++M: Kevin Xie <kevin.xie@starfivetech.com>
++L: linux-pci@vger.kernel.org
++S: Maintained
++F: Documentation/devicetree/bindings/pci/starfive*
++F: drivers/pci/controller/plda/pcie-starfive.c
++
+ PCIE DRIVER FOR ST SPEAR13XX
+ M: Pratyush Anand <pratyush.anand@gmail.com>
+ L: linux-pci@vger.kernel.org
+@@ -18454,7 +18484,7 @@ F: drivers/char/hw_random/mpfs-rng.c
+ F: drivers/clk/microchip/clk-mpfs*.c
+ F: drivers/i2c/busses/i2c-microchip-corei2c.c
+ F: drivers/mailbox/mailbox-mpfs.c
+-F: drivers/pci/controller/pcie-microchip-host.c
++F: drivers/pci/controller/plda/pcie-microchip-host.c
+ F: drivers/pwm/pwm-microchip-core.c
+ F: drivers/reset/reset-mpfs.c
+ F: drivers/rtc/rtc-mpfs.c
+@@ -20435,6 +20465,15 @@ M: Ion Badulescu <ionut@badula.org>
+ S: Odd Fixes
+ F: drivers/net/ethernet/adaptec/starfire*
+
++STARFIVE CAMERA SUBSYSTEM DRIVER
++M: Jack Zhu <jack.zhu@starfivetech.com>
++M: Changhuang Liang <changhuang.liang@starfivetech.com>
++L: linux-media@vger.kernel.org
++S: Maintained
++F: Documentation/admin-guide/media/starfive_camss.rst
++F: Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
++F: drivers/staging/media/starfive/camss
++
+ STARFIVE CRYPTO DRIVER
+ M: Jia Jie Ho <jiajie.ho@starfivetech.com>
+ M: William Qiu <william.qiu@starfivetech.com>
+@@ -20473,6 +20512,13 @@ S: Supported
+ F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
+ F: drivers/clk/starfive/clk-starfive-jh7110-pll.c
+
++STARFIVE JH7110 PWMDAC DRIVER
++M: Hal Feng <hal.feng@starfivetech.com>
++M: Xingyu Wu <xingyu.wu@starfivetech.com>
++S: Supported
++F: Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
++F: sound/soc/starfive/jh7110_pwmdac.c
++
+ STARFIVE JH7110 SYSCON
+ M: William Qiu <william.qiu@starfivetech.com>
+ M: Xingyu Wu <xingyu.wu@starfivetech.com>
+@@ -20520,9 +20566,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c
+
+ STARFIVE JH71XX PMU CONTROLLER DRIVER
+ M: Walker Chen <walker.chen@starfivetech.com>
++M: Changhuang Liang <changhuang.liang@starfivetech.com>
+ S: Supported
+ F: Documentation/devicetree/bindings/power/starfive*
+-F: drivers/pmdomain/starfive/jh71xx-pmu.c
++F: drivers/pmdomain/starfive/
+ F: include/dt-bindings/power/starfive,jh7110-pmu.h
+
+ STARFIVE SOC DRIVERS
+@@ -20530,7 +20577,13 @@ M: Conor Dooley <conor@kernel.org>
+ S: Maintained
+ T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
+ F: Documentation/devicetree/bindings/soc/starfive/
+-F: drivers/soc/starfive/
++
++STARFIVE JH7110 TIMER DRIVER
++M: Samin Guo <samin.guo@starfivetech.com>
++M: Xingyu Wu <xingyu.wu@starfivetech.com>
++S: Supported
++F: Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
++F: drivers/clocksource/timer-jh7110.c
+
+ STARFIVE TRNG DRIVER
+ M: Jia Jie Ho <jiajie.ho@starfivetech.com>
diff --git a/target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch b/target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch
new file mode 100644
index 0000000000..a38a885894
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch
@@ -0,0 +1,64 @@
+From e394195396995456ef98f52ac123c0cb64687748 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Mon, 9 Oct 2023 10:59:03 +0800
+Subject: [PATCH 050/116] mmc: starfive: Change the voltage to adapt to JH7110
+ EVB
+
+Change the voltage, so the driver can adapt to JH7110 EVB.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/mmc/host/dw_mmc-starfive.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/drivers/mmc/host/dw_mmc-starfive.c
++++ b/drivers/mmc/host/dw_mmc-starfive.c
+@@ -8,6 +8,7 @@
+ #include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
++#include <linux/gpio.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/mmc/host.h>
+ #include <linux/module.h>
+@@ -95,10 +96,39 @@ out:
+ return ret;
+ }
+
++static int dw_mci_starfive_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++
++ struct dw_mci_slot *slot = mmc_priv(mmc);
++ struct dw_mci *host = slot->host;
++ u32 ret;
++
++ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
++ ret = gpio_direction_output(25, 0);
++ else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
++ ret = gpio_direction_output(25, 1);
++ if (ret)
++ return ret;
++
++ if (!IS_ERR(mmc->supply.vqmmc)) {
++ ret = mmc_regulator_set_vqmmc(mmc, ios);
++ if (ret < 0) {
++ dev_err(host->dev, "Regulator set error %d\n", ret);
++ return ret;
++ }
++ }
++
++ /* We should delay 20ms wait for timing setting finished. */
++ mdelay(20);
++
++ return 0;
++}
++
+ static const struct dw_mci_drv_data starfive_data = {
+ .common_caps = MMC_CAP_CMD23,
+ .set_ios = dw_mci_starfive_set_ios,
+ .execute_tuning = dw_mci_starfive_execute_tuning,
++ .switch_voltage = dw_mci_starfive_switch_voltage,
+ };
+
+ static const struct of_device_id dw_mci_starfive_match[] = {
diff --git a/target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch b/target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch
new file mode 100644
index 0000000000..485ab0d9e1
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch
@@ -0,0 +1,60 @@
+From 2cd3e51cb76d49d8db6274ebdc1ba1eb5c872f10 Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfivetech.com>
+Date: Sun, 4 Feb 2024 10:35:24 +0800
+Subject: [PATCH 051/116] spi: spl022: Get and deassert reset in probe()
+
+This fix spi1~6 communication time out.
+
+Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -33,6 +33,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/of.h>
+ #include <linux/pinctrl/consumer.h>
++#include <linux/reset.h>
+
+ /*
+ * This macro is used to define some register default values.
+@@ -370,6 +371,7 @@ struct pl022 {
+ resource_size_t phybase;
+ void __iomem *virtbase;
+ struct clk *clk;
++ struct reset_control *rst;
+ struct spi_controller *host;
+ struct pl022_ssp_controller *host_info;
+ /* Message per-transfer pump */
+@@ -2181,6 +2183,19 @@ static int pl022_probe(struct amba_devic
+ goto err_no_clk_en;
+ }
+
++ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
++ if (IS_ERR(pl022->rst)) {
++ status = PTR_ERR(pl022->rst);
++ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
++ goto err_no_rst;
++ }
++
++ status = reset_control_deassert(pl022->rst);
++ if (status) {
++ dev_err(&adev->dev, "could not deassert SSP/SPI bus reset\n");
++ goto err_no_rst_de;
++ }
++
+ /* Initialize transfer pump */
+ tasklet_init(&pl022->pump_transfers, pump_transfers,
+ (unsigned long)pl022);
+@@ -2240,6 +2255,8 @@ static int pl022_probe(struct amba_devic
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+ err_no_irq:
++ err_no_rst_de:
++ err_no_rst:
+ clk_disable_unprepare(pl022->clk);
+ err_no_clk_en:
+ err_no_clk:
diff --git a/target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch b/target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch
new file mode 100644
index 0000000000..e274e84a25
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch
@@ -0,0 +1,30 @@
+From 9cc8de0cdc1600f460f618e342e1f524adad07c4 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Wed, 21 Feb 2024 10:23:48 +0800
+Subject: [PATCH 052/116] ASoC: dwc: i2s: Fix getting platform data error for
+ StarFive JH7110
+
+JH7110 need to use a DT specific function to get the platform data,
+otherwise, it fails in probe().
+
+Fixes: 9c97790a07dc ("ASoC: dwc: Fix non-DT instantiation")
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/dwc/dwc-i2s.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/soc/dwc/dwc-i2s.c
++++ b/sound/soc/dwc/dwc-i2s.c
+@@ -917,7 +917,11 @@ static int jh7110_i2stx0_clk_cfg(struct
+
+ static int dw_i2s_probe(struct platform_device *pdev)
+ {
++#ifdef CONFIG_OF
++ const struct i2s_platform_data *pdata = of_device_get_match_data(&pdev->dev);
++#else
+ const struct i2s_platform_data *pdata = pdev->dev.platform_data;
++#endif
+ struct dw_i2s_dev *dev;
+ struct resource *res;
+ int ret, irq;
diff --git a/target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch b/target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch
new file mode 100644
index 0000000000..8203beca52
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch
@@ -0,0 +1,67 @@
+From 1be9bd37fdb5f50162dba0158e1fee295ebca9aa Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Tue, 17 Oct 2023 17:22:52 +0800
+Subject: [PATCH 053/116] ASoC: dwc: i2s: Add RX master support for StarFive
+ JH7110 SoC
+
+Add JH7110 I2S RX master support, so the PDM can work on JH7110
+EVB board.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/dwc/dwc-i2s.c | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/sound/soc/dwc/dwc-i2s.c
++++ b/sound/soc/dwc/dwc-i2s.c
+@@ -906,6 +906,27 @@ static int jh7110_i2srx_crg_init(struct
+ return jh7110_i2s_crg_slave_init(dev);
+ }
+
++/* Special syscon initialization about RX channel with master mode on JH7110 SoC */
++static int jh7110_i2srx_mst_crg_init(struct dw_i2s_dev *dev)
++{
++ struct regmap *regmap;
++ unsigned int args[5];
++
++ regmap = syscon_regmap_lookup_by_phandle_args(dev->dev->of_node,
++ "starfive,syscon",
++ 5, args);
++ if (IS_ERR(regmap))
++ return dev_err_probe(dev->dev, PTR_ERR(regmap), "getting the regmap failed\n");
++
++ /* Enable I2Srx with syscon register, args[0]: offset, args[1]: mask */
++ regmap_update_bits(regmap, args[0], args[1], args[1]);
++
++ /* Change I2Srx source (PDM) with syscon register, args[0]: offset, args[1]: mask */
++ regmap_update_bits(regmap, args[2], args[3], args[4]);
++
++ return jh7110_i2s_crg_master_init(dev);
++}
++
+ static int jh7110_i2stx0_clk_cfg(struct i2s_clk_config_data *config)
+ {
+ struct dw_i2s_dev *dev = container_of(config, struct dw_i2s_dev, config);
+@@ -1086,11 +1107,21 @@ static const struct i2s_platform_data jh
+ .i2s_pd_init = jh7110_i2srx_crg_init,
+ };
+
++static const struct i2s_platform_data jh7110_i2srx_mst_data = {
++ .cap = DWC_I2S_RECORD | DW_I2S_MASTER,
++ .channel = TWO_CHANNEL_SUPPORT,
++ .snd_fmts = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
++ .snd_rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000,
++ .i2s_clk_cfg = jh7110_i2stx0_clk_cfg,
++ .i2s_pd_init = jh7110_i2srx_mst_crg_init,
++};
++
+ static const struct of_device_id dw_i2s_of_match[] = {
+ { .compatible = "snps,designware-i2s", },
+ { .compatible = "starfive,jh7110-i2stx0", .data = &jh7110_i2stx0_data, },
+ { .compatible = "starfive,jh7110-i2stx1", .data = &jh7110_i2stx1_data,},
+ { .compatible = "starfive,jh7110-i2srx", .data = &jh7110_i2srx_data,},
++ { .compatible = "starfive,jh7110-i2srx-master", .data = &jh7110_i2srx_mst_data,},
+ {},
+ };
+
diff --git a/target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch b/target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch
new file mode 100644
index 0000000000..51976c656e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch
@@ -0,0 +1,24 @@
+From 1ec26ba377d8ae59cd09811ec78623a750a9c150 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 26 Feb 2024 11:35:44 +0800
+Subject: [PATCH 054/116] pinctrl: starfive: jh7110: Unset .strict in
+ pinmux_ops
+
+Allow simultaneous use of the same pin for GPIO and another function.
+This feature is used in HDMI hot plug detect.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
+@@ -327,7 +327,6 @@ static const struct pinmux_ops jh7110_pi
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .set_mux = jh7110_set_mux,
+- .strict = true,
+ };
+
+ static const u8 jh7110_drive_strength_mA[4] = { 2, 4, 8, 12 };
diff --git a/target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch b/target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch
new file mode 100644
index 0000000000..39699e8b97
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch
@@ -0,0 +1,22 @@
+From 005549a2bd839335b0e3dc4152f00f642b524f07 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sat, 7 Oct 2023 18:10:20 +0800
+Subject: [PATCH 055/116] mm/pgtable-generic.c: Export symbol __pte_offset_map
+
+So JH7110 vdec can call pte_offset_map() when it is built as a module.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ mm/pgtable-generic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/mm/pgtable-generic.c
++++ b/mm/pgtable-generic.c
+@@ -304,6 +304,7 @@ nomap:
+ rcu_read_unlock();
+ return NULL;
+ }
++EXPORT_SYMBOL(__pte_offset_map);
+
+ pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long addr, spinlock_t **ptlp)
diff --git a/target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch b/target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch
new file mode 100644
index 0000000000..7b803d3997
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch
@@ -0,0 +1,2623 @@
+From 9f46b0d43f8945ff3a8b81ddc6567df370b60911 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 28 Jul 2023 17:19:12 +0800
+Subject: [PATCH 056/116] riscv: dts: starfive: Add JH7110 EVB device tree
+
+Add JH7110 evaluation board device tree.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 3 +
+ arch/riscv/boot/dts/starfive/jh7110-clk.dtsi | 80 ++
+ .../boot/dts/starfive/jh7110-evb-pinctrl.dtsi | 997 ++++++++++++++++++
+ arch/riscv/boot/dts/starfive/jh7110-evb.dts | 35 +
+ arch/riscv/boot/dts/starfive/jh7110-evb.dtsi | 854 +++++++++++++++
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 482 ++++++++-
+ 6 files changed, 2444 insertions(+), 7 deletions(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-clk.dtsi
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-pinctrl.dtsi
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -4,9 +4,12 @@ DTC_FLAGS_jh7100-beaglev-starlight := -@
+ DTC_FLAGS_jh7100-starfive-visionfive-v1 := -@
+ DTC_FLAGS_jh7110-starfive-visionfive-2-v1.2a := -@
+ DTC_FLAGS_jh7110-starfive-visionfive-2-v1.3b := -@
++DTC_FLAGS_jh7110-evb := -@
+
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
++
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-clk.dtsi
+@@ -0,0 +1,80 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++/ {
++ ac108_mclk: ac108_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ clk_ext_camera: clk-ext-camera {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ wm8960_mclk: wm8960_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ };
++};
++
++&dvp_clk {
++ clock-frequency = <74250000>;
++};
++
++&gmac0_rgmii_rxin {
++ clock-frequency = <125000000>;
++};
++
++&gmac0_rmii_refin {
++ clock-frequency = <50000000>;
++};
++
++&gmac1_rgmii_rxin {
++ clock-frequency = <125000000>;
++};
++
++&gmac1_rmii_refin {
++ clock-frequency = <50000000>;
++};
++
++&hdmitx0_pixelclk {
++ clock-frequency = <297000000>;
++};
++
++&i2srx_bclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&i2srx_lrck_ext {
++ clock-frequency = <192000>;
++};
++
++&i2stx_bclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&i2stx_lrck_ext {
++ clock-frequency = <192000>;
++};
++
++&mclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&osc {
++ clock-frequency = <24000000>;
++};
++
++&rtc_osc {
++ clock-frequency = <32768>;
++};
++
++&tdm_ext {
++ clock-frequency = <49152000>;
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-pinctrl.dtsi
+@@ -0,0 +1,997 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ * Author: Hal Feng <hal.feng@starfivetech.com>
++ */
++
++#include "jh7110-pinfunc.h"
++
++&sysgpio {
++ can0_pins: can0-0 {
++ can-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_CAN0_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_CAN0_RXD)>,
++ <GPIOMUX(32, GPOUT_SYS_CAN0_STBY,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ can1_pins: can1-0 {
++ can-pins {
++ pinmux = <GPIOMUX(29, GPOUT_SYS_CAN1_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(27, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_CAN1_RXD)>,
++ <GPIOMUX(45, GPOUT_SYS_CAN1_STBY,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ input-enable;
++ };
++ };
++
++ dvp_pins: dvp-0 {
++ dvp-pins{
++ pinmux = <PINMUX(21, 2)>,
++ <PINMUX(22, 2)>,
++ <PINMUX(23, 2)>,
++ <PINMUX(24, 2)>,
++ <PINMUX(25, 2)>,
++ <PINMUX(26, 2)>,
++ <PINMUX(27, 2)>,
++ <PINMUX(28, 2)>,
++ <PINMUX(29, 2)>,
++ <PINMUX(30, 2)>,
++ <PINMUX(31, 2)>,
++ <PINMUX(32, 2)>,
++ <PINMUX(33, 2)>,
++ <PINMUX(34, 2)>,
++ <PINMUX(35, 2)>;
++ input-enable;
++ };
++ };
++
++ emmc0_pins: emmc0-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(22, GPOUT_SYS_SDIO0_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <PINMUX(64, 0)>,
++ <PINMUX(65, 0)>,
++ <PINMUX(66, 0)>,
++ <PINMUX(67, 0)>,
++ <PINMUX(68, 0)>,
++ <PINMUX(69, 0)>,
++ <PINMUX(70, 0)>,
++ <PINMUX(71, 0)>,
++ <PINMUX(72, 0)>,
++ <PINMUX(73, 0)>;
++ bias-pull-up;
++ drive-strength = <12>;
++ input-enable;
++ slew-rate = <1>;
++ };
++ };
++
++ emmc1_pins: emmc1-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(51, GPOUT_SYS_SDIO1_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(38, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(36, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(43, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(48, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(53, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(63, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>,
++ <GPIOMUX(52, GPOUT_SYS_SDIO1_DATA4,
++ GPOEN_SYS_SDIO1_DATA4,
++ GPI_SYS_SDIO1_DATA4)>,
++ <GPIOMUX(39, GPOUT_SYS_SDIO1_DATA5,
++ GPOEN_SYS_SDIO1_DATA5,
++ GPI_SYS_SDIO1_DATA5)>,
++ <GPIOMUX(46, GPOUT_SYS_SDIO1_DATA6,
++ GPOEN_SYS_SDIO1_DATA6,
++ GPI_SYS_SDIO1_DATA6)>,
++ <GPIOMUX(47, GPOUT_SYS_SDIO1_DATA7,
++ GPOEN_SYS_SDIO1_DATA7,
++ GPI_SYS_SDIO1_DATA7)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++
++ gmac0_pins: gmac0-0 {
++ reset-pins {
++ pinmux = <GPIOMUX(13, GPOUT_HIGH,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ };
++ };
++
++ gmac1_pins: gmac1-0 {
++ mdc-pins {
++ pinmux = <PINMUX(75, 0)>;
++ };
++ };
++
++ hdmi_pins: hdmi-0 {
++ scl-pins {
++ pinmux = <GPIOMUX(7, GPOUT_SYS_HDMI_DDC_SCL,
++ GPOEN_SYS_HDMI_DDC_SCL,
++ GPI_SYS_HDMI_DDC_SCL)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ sda-pins {
++ pinmux = <GPIOMUX(8, GPOUT_SYS_HDMI_DDC_SDA,
++ GPOEN_SYS_HDMI_DDC_SDA,
++ GPI_SYS_HDMI_DDC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ cec-pins {
++ pinmux = <GPIOMUX(14, GPOUT_SYS_HDMI_CEC_SDA,
++ GPOEN_SYS_HDMI_CEC_SDA,
++ GPI_SYS_HDMI_CEC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ hpd-pins {
++ pinmux = <GPIOMUX(15, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_HDMI_HPD)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ };
++ };
++
++ i2c0_pins: i2c0-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(57, GPOUT_LOW,
++ GPOEN_SYS_I2C0_CLK,
++ GPI_SYS_I2C0_CLK)>,
++ <GPIOMUX(58, GPOUT_LOW,
++ GPOEN_SYS_I2C0_DATA,
++ GPI_SYS_I2C0_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c1_pins: i2c1-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(49, GPOUT_LOW,
++ GPOEN_SYS_I2C1_CLK,
++ GPI_SYS_I2C1_CLK)>,
++ <GPIOMUX(50, GPOUT_LOW,
++ GPOEN_SYS_I2C1_DATA,
++ GPI_SYS_I2C1_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c2_pins: i2c2-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(11, GPOUT_LOW,
++ GPOEN_SYS_I2C2_CLK,
++ GPI_SYS_I2C2_CLK)>,
++ <GPIOMUX(9, GPOUT_LOW,
++ GPOEN_SYS_I2C2_DATA,
++ GPI_SYS_I2C2_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c3_pins: i2c3-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(51, GPOUT_LOW,
++ GPOEN_SYS_I2C3_CLK,
++ GPI_SYS_I2C3_CLK)>,
++ <GPIOMUX(52, GPOUT_LOW,
++ GPOEN_SYS_I2C3_DATA,
++ GPI_SYS_I2C3_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c4_pins: i2c4-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(18, GPOUT_LOW,
++ GPOEN_SYS_I2C4_CLK,
++ GPI_SYS_I2C4_CLK)>,
++ <GPIOMUX(12, GPOUT_LOW,
++ GPOEN_SYS_I2C4_DATA,
++ GPI_SYS_I2C4_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c5_pins: i2c5-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(19, GPOUT_LOW,
++ GPOEN_SYS_I2C5_CLK,
++ GPI_SYS_I2C5_CLK)>,
++ <GPIOMUX(20, GPOUT_LOW,
++ GPOEN_SYS_I2C5_DATA,
++ GPI_SYS_I2C5_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c6_pins: i2c6-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(16, GPOUT_LOW,
++ GPOEN_SYS_I2C6_CLK,
++ GPI_SYS_I2C6_CLK)>,
++ <GPIOMUX(17, GPOUT_LOW,
++ GPOEN_SYS_I2C6_DATA,
++ GPI_SYS_I2C6_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2s_clk_pins: i2s-clk-0 {
++ bclk-lrck-pins {
++ pinmux = <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_BCLK)>,
++ <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_BCLK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_LRCK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_LRCK)>;
++ input-enable;
++ };
++ };
++
++ i2srx_clk_pins: i2srx-clk-0 {
++ mclk-pins {
++ pinmux = <GPIOMUX(58, GPOUT_SYS_MCLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ i2srx_pins: i2srx-0 {
++ i2srx-pins {
++ pinmux = <GPIOMUX(61, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_SDIN0)>;
++ input-enable;
++ };
++ };
++
++ i2stx_pins: i2stx-0 {
++ i2stx-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ mclk_ext_pins: mclk-ext-0 {
++ mclk-ext-pins {
++ pinmux = <GPIOMUX(4, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_MCLK_EXT)>;
++ input-enable;
++ };
++ };
++
++ pdm_pins: pdm-0 {
++ pdm-pins {
++ pinmux = <GPIOMUX(54, GPOUT_SYS_PDM_MCLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(60, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_PDM_DMIC0)>;
++ input-enable;
++ };
++ };
++
++ pwm_ch0to3_pins: pwm-ch0to3-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(45, GPOUT_SYS_PWM_CHANNEL0,
++ GPOEN_SYS_PWM0_CHANNEL0,
++ GPI_NONE)>,
++ <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL1,
++ GPOEN_SYS_PWM0_CHANNEL1,
++ GPI_NONE)>,
++ <GPIOMUX(47, GPOUT_SYS_PWM_CHANNEL2,
++ GPOEN_SYS_PWM0_CHANNEL2,
++ GPI_NONE)>,
++ <GPIOMUX(48, GPOUT_SYS_PWM_CHANNEL3,
++ GPOEN_SYS_PWM0_CHANNEL3,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++
++ pwmdac_pins: pwmdac-0 {
++ pwmdac-pins {
++ pinmux = <GPIOMUX(57, GPOUT_SYS_PWMDAC_LEFT,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(42, GPOUT_SYS_PWMDAC_RIGHT,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ };
++ };
++
++ rgb_pad_pins: rgb-pad-pins {
++ rgb-0-pins {
++ pinmux = <PINMUX(36, 1)>;
++ drive-strength = <12>;
++ input-disable;
++ slew-rate = <1>;
++ };
++
++ rgb-pins {
++ pinmux = <PINMUX(37, 1)>,
++ <PINMUX(38, 1)>,
++ <PINMUX(39, 1)>,
++ <PINMUX(40, 1)>,
++ <PINMUX(41, 1)>,
++ <PINMUX(42, 1)>,
++ <PINMUX(43, 1)>,
++ <PINMUX(44, 1)>,
++ <PINMUX(45, 1)>,
++ <PINMUX(46, 1)>,
++ <PINMUX(47, 1)>,
++ <PINMUX(48, 1)>,
++ <PINMUX(49, 1)>,
++ <PINMUX(50, 1)>,
++ <PINMUX(51, 1)>,
++ <PINMUX(52, 1)>,
++ <PINMUX(53, 1)>,
++ <PINMUX(54, 1)>,
++ <PINMUX(55, 1)>,
++ <PINMUX(56, 1)>,
++ <PINMUX(57, 1)>,
++ <PINMUX(58, 1)>,
++ <PINMUX(59, 1)>,
++ <PINMUX(60, 1)>,
++ <PINMUX(61, 1)>,
++ <PINMUX(62, 1)>,
++ <PINMUX(63, 1)>;
++ drive-strength = <12>;
++ input-disable;
++ };
++ };
++
++ sdcard0_pins: sdcard0-0 {
++ sdcard-pins {
++ pinmux = <GPIOMUX(24, GPOUT_SYS_SDIO0_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <PINMUX(64, 0)>,
++ <PINMUX(65, 0)>,
++ <PINMUX(66, 0)>,
++ <PINMUX(67, 0)>,
++ <PINMUX(68, 0)>,
++ <PINMUX(69, 0)>;
++ bias-pull-up;
++ drive-strength = <12>;
++ input-enable;
++ slew-rate = <1>;
++ };
++ };
++
++ sdcard1_pins: sdcard1-0 {
++ sdcard-pins {
++ pinmux = <GPIOMUX(56, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(50, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(49, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(45, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(62, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(40, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++
++ spdif_pins: spdif-0 {
++ spdif-pins {
++ pinmux = <GPIOMUX(57, GPOUT_SYS_SPDIF,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++
++ spi0_pins: spi0-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(38, GPOUT_SYS_SPI0_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(39, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI0_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(36, GPOUT_SYS_SPI0_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI0_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(37, GPOUT_SYS_SPI0_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI0_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi1_pins: spi1-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(42, GPOUT_SYS_SPI1_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(43, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI1_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(40, GPOUT_SYS_SPI1_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI1_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(41, GPOUT_SYS_SPI1_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI1_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi2_pins: spi2-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(46, GPOUT_SYS_SPI2_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(47, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI2_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_SPI2_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI2_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(45, GPOUT_SYS_SPI2_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI2_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi3_pins: spi3-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(50, GPOUT_SYS_SPI3_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(51, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI3_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(48, GPOUT_SYS_SPI3_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI3_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(49, GPOUT_SYS_SPI3_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI3_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi4_pins: spi4-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(54, GPOUT_SYS_SPI4_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(55, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI4_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(52, GPOUT_SYS_SPI4_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI4_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(53, GPOUT_SYS_SPI4_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI4_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi5_pins: spi5-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(58, GPOUT_SYS_SPI5_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(59, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI5_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(56, GPOUT_SYS_SPI5_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI5_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(57, GPOUT_SYS_SPI5_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI5_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi6_pins: spi6-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(62, GPOUT_SYS_SPI6_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI6_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(60, GPOUT_SYS_SPI6_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI6_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(61, GPOUT_SYS_SPI6_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI6_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ tdm_pins: tdm-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(61, GPOUT_HIGH,
++ GPOEN_DISABLE,
++ GPI_SYS_TDM_RXD)>;
++ input-enable;
++ };
++
++ sync-pins {
++ pinmux = <GPIOMUX(63, GPOUT_HIGH,
++ GPOEN_DISABLE,
++ GPI_SYS_TDM_SYNC)>;
++ input-enable;
++ };
++
++ pcmclk-pins {
++ pinmux = <GPIOMUX(38, GPOUT_HIGH,
++ GPOEN_DISABLE,
++ GPI_SYS_TDM_CLK)>;
++ input-enable;
++ };
++ };
++
++ uart0_pins: uart0-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(6, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART0_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
++ uart1_pins: uart1-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART1_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART1_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART1_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART1_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ uart2_pins: uart2-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART2_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART2_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART2_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART2_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ uart3_pins: uart3-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART3_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART3_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
++ uart4_pins: uart4-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART4_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART4_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART4_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART4_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ uart5_pins: uart5-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART5_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART5_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART5_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART5_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ usb_pins: usb-0 {
++ usb-pins {
++ pinmux = <GPIOMUX(33, GPOUT_HIGH,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(34, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_USB_OVERCURRENT)>;
++ input-enable;
++ };
++ };
++};
++
++&aongpio {
++ pwm_ch4to5_pins: pwm-ch4to5-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM4, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_4,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM5, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_5,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++
++ pwm_ch6to7_pins: pwm-ch6to7-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM6, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_6,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM7, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_7,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dts
+@@ -0,0 +1,35 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ no-sdio;
++ no-mmc;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
+@@ -0,0 +1,854 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110.dtsi"
++#include "jh7110-clk.dtsi"
++#include "jh7110-evb-pinctrl.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ aliases {
++ ethernet0 = &gmac0;
++ ethernet1 = &gmac1;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ pcie0 = &pcie0;
++ pcie1 = &pcie1;
++ serial0 = &uart0;
++ serial3 = &uart3;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ cpus {
++ timebase-frequency = <4000000>;
++ };
++
++ memory@40000000 {
++ device_type = "memory";
++ reg = <0x0 0x40000000 0x1 0x0>;
++ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ size = <0x0 0x20000000>;
++ alignment = <0x0 0x1000>;
++ alloc-ranges = <0x0 0x70000000 0x0 0x20000000>;
++ linux,cma-default;
++ };
++
++ e24_mem: e24@c0000000 {
++ reg = <0x0 0x6ce00000 0x0 0x1600000>;
++ };
++
++ xrp_reserved: xrpbuffer@f0000000 {
++ reg = <0x0 0x69c00000 0x0 0x01ffffff
++ 0x0 0x6bc00000 0x0 0x00001000
++ 0x0 0x6bc01000 0x0 0x00fff000
++ 0x0 0x6cc00000 0x0 0x00001000>;
++ };
++ };
++
++ /* i2s + hdmi */
++ sound1: snd-card1 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-HDMI-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndi2s0>;
++ frame-master = <&sndi2s0>;
++ mclk-fs = <256>;
++ status = "okay";
++
++ sndi2s0: cpu {
++ sound-dai = <&i2stx0>;
++ };
++
++ codec {
++ sound-dai = <&hdmi>;
++ };
++ };
++ };
++};
++
++&U74_1 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&U74_2 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&U74_3 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&U74_4 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&can0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&can0_pins>;
++ status = "disabled";
++};
++
++&can1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&can1_pins>;
++ status = "disabled";
++};
++
++&co_process {
++ memory-region = <&e24_mem>;
++ status = "okay";
++};
++
++&dc8200 {
++ status = "okay";
++
++ dc_out: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ dc_out_dpi0: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&hdmi_input0>;
++ };
++ dc_out_dpi1: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&hdmi_in_lcdc>;
++ };
++ dc_out_dpi2: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&mipi_in>;
++ };
++ };
++};
++
++&display {
++ ports = <&dc_out_dpi0>;
++ status = "okay";
++};
++
++&dsi_output {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ mipi_in: endpoint {
++ remote-endpoint = <&dc_out_dpi2>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ mipi_out: endpoint {
++ remote-endpoint = <&dsi_in_port>;
++ };
++ };
++ };
++};
++
++&gmac0 {
++ phy-handle = <&phy0>;
++ phy-mode = "rgmii-id";
++ status = "okay";
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "snps,dwmac-mdio";
++
++ phy0: ethernet-phy@0 {
++ reg = <0>;
++ rx-internal-delay-ps = <1900>;
++ tx-internal-delay-ps = <1650>;
++ };
++ };
++};
++
++&gmac1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ phy1: ethernet-phy@1 {
++ reg = <0>;
++ rxc-skew-ps = <1060>;
++ txc-skew-ps = <1800>;
++ };
++};
++
++&gpu {
++ status = "okay";
++};
++
++&hdmi {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&hdmi_pins>;
++ hpd-gpio = <&sysgpio 15 GPIO_ACTIVE_HIGH>;
++
++ hdmi_in: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ hdmi_in_lcdc: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi1>;
++ };
++ };
++};
++
++&i2c0 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0_pins>;
++ status = "disabled";
++
++ wm8960: codec@1a {
++ compatible = "wlf,wm8960";
++ reg = <0x1a>;
++ wlf,shared-lrclk;
++ #sound-dai-cells = <0>;
++ };
++
++ ac108: ac108@3b {
++ compatible = "x-power,ac108_0";
++ reg = <0x3b>;
++ #sound-dai-cells = <0>;
++ data-protocol = <0>;
++ };
++};
++
++&i2c1 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ status = "disabled";
++};
++
++&i2c2 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
++ status = "okay";
++
++ tinker_ft5406: tinker_ft5406@38 {
++ compatible = "tinker_ft5406";
++ reg = <0x38>;
++ };
++
++ seeed_plane_i2c@45 {
++ compatible = "seeed_panel";
++ reg = <0x45>;
++
++ port {
++ panel_dsi_port: endpoint {
++ remote-endpoint = <&dsi_out_port>;
++ };
++ };
++ };
++};
++
++&i2c3 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c3_pins>;
++ status = "disabled";
++};
++
++&i2c4 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c4_pins>;
++ status = "okay";
++
++ sc2235: sc2235@30 {
++ compatible = "smartsens,sc2235";
++ reg = <0x30>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++
++ port {
++ /* Parallel bus endpoint */
++ sc2235_to_parallel: endpoint {
++ remote-endpoint = <&parallel_from_sc2235>;
++ bus-type = <5>; /* Parallel */
++ bus-width = <8>;
++ data-shift = <2>; /* lines 13:6 are used */
++ hsync-active = <1>;
++ vsync-active = <1>;
++ pclk-sample = <1>;
++ };
++ };
++ };
++
++ tda998x@70 {
++ compatible = "nxp,tda998x";
++ reg = <0x70>;
++
++ port {
++ tda998x_0_input: endpoint {
++ remote-endpoint = <&hdmi_out>;
++ };
++ };
++ };
++};
++
++&i2c5 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c5_pins>;
++ status = "okay";
++
++ pmic: jh7110_evb_reg@50 {
++ compatible = "starfive,jh7110-evb-regulator";
++ reg = <0x50>;
++
++ regulators {
++ hdmi_1p8: LDO_REG1 {
++ regulator-name = "hdmi_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ mipitx_1p8: LDO_REG2 {
++ regulator-name = "mipitx_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ mipirx_1p8: LDO_REG3 {
++ regulator-name = "mipirx_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ hdmi_0p9: LDO_REG4 {
++ regulator-name = "hdmi_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++ mipitx_0p9: LDO_REG5 {
++ regulator-name = "mipitx_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++ mipirx_0p9: LDO_REG6 {
++ regulator-name = "mipirx_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++ sdio_vdd: LDO_REG7 {
++ regulator-name = "sdio_vdd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ };
++ };
++ };
++};
++
++&i2c6 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c6_pins>;
++ status = "okay";
++
++ ov4689: ov4689@36 {
++ compatible = "ovti,ov4689";
++ reg = <0x36>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ //reset-gpio = <&sysgpio 18 0>;
++ rotation = <180>;
++
++ port {
++ /* Parallel bus endpoint */
++ ov4689_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_ov4689>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ };
++
++ imx219: imx219@10 {
++ compatible = "sony,imx219";
++ reg = <0x10>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ reset-gpio = <&sysgpio 10 0>;
++ //DOVDD-supply = <&v2v8>;
++ rotation = <0>;
++ orientation = <1>; //CAMERA_ORIENTATION_BACK
++
++ port {
++ /* CSI2 bus endpoint */
++ imx219_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx219>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <2 1>;
++ lane-polarities = <1 1 1>;
++ link-frequencies = /bits/ 64 <456000000>;
++ };
++ };
++ };
++
++ imx708: imx708@1a {
++ compatible = "sony,imx708";
++ reg = <0x1a>;
++ clocks = <&clk_ext_camera>;
++ reset-gpio = <&sysgpio 10 0>;
++
++ port {
++ imx708_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx708>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies = /bits/ 64 <450000000>;
++ };
++ };
++ };
++};
++
++&i2srx {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s_clk_pins &i2srx_pins>;
++};
++
++&i2srx_mst {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2srx_clk_pins>;
++};
++
++&i2stx0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&mclk_ext_pins>;
++ status = "okay";
++};
++
++&i2stx1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2stx_pins>;
++};
++
++&jpu {
++ status = "okay";
++};
++
++&mailbox_contrl0 {
++ status = "okay";
++};
++
++&mailbox_client0 {
++ status = "okay";
++};
++
++&mipi_dphy {
++ status = "okay";
++};
++
++&mipi_dsi {
++ status = "okay";
++
++ port {
++ dsi_out_port: endpoint@0 {
++ remote-endpoint = <&panel_dsi_port>;
++ };
++ dsi_in_port: endpoint@1 {
++ remote-endpoint = <&mipi_out>;
++ };
++ };
++
++ mipi_panel: panel@0 {
++ /*compatible = "";*/
++ status = "okay";
++ };
++};
++
++&pcie0 {
++ enable-gpios = <&sysgpio 32 GPIO_ACTIVE_HIGH>;
++ perst-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy0>;
++ status = "disabled";
++};
++
++&pcie1 {
++ enable-gpios = <&sysgpio 21 GPIO_ACTIVE_HIGH>;
++ perst-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy1>;
++ status = "disabled";
++};
++
++&pciephy0 {
++ starfive,sys-syscon = <&sys_syscon 0x18>;
++ starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
++};
++
++&pdm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pdm_pins>;
++ status = "disabled";
++};
++
++&pwmdac {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwmdac_pins>;
++};
++
++&qspi {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ nor_flash: flash@0 {
++ compatible = "jedec,spi-nor";
++ reg=<0>;
++ cdns,read-delay = <5>;
++ spi-max-frequency = <4687500>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ spl@0 {
++ reg = <0x0 0x40000>;
++ };
++ uboot@100000 {
++ reg = <0x100000 0x300000>;
++ };
++ data@f00000 {
++ reg = <0xf00000 0x100000>;
++ };
++ };
++ };
++};
++
++&rgb_output {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ hdmi_input0:endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi0>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++
++ hdmi_out:endpoint {
++ remote-endpoint = <&tda998x_0_input>;
++ };
++ };
++ };
++};
++
++&spdif {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spdif_pins>;
++};
++
++&spi0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi0_pins>;
++ status = "disabled";
++
++ spi_dev0: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi1_pins>;
++ status = "disabled";
++
++ spi_dev1: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins>;
++ status = "disabled";
++
++ spi_dev2: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi3_pins>;
++ status = "disabled";
++
++ spi_dev3: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi4_pins>;
++ status = "disabled";
++
++ spi_dev4: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi5 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi5_pins>;
++ status = "disabled";
++
++ spi_dev5: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi6 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi6_pins>;
++ status = "disabled";
++
++ spi_dev6: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&tda988x_pin {
++ pinctrl-names = "default";
++ pinctrl-0 = <&rgb_pad_pins>;
++ status = "disabled";
++};
++
++&tdm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&tdm_pins>;
++ status = "disabled";
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_pins>;
++ status = "disabled";
++};
++
++&uart2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart2_pins>;
++ status = "disabled";
++};
++
++&uart3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart3_pins>;
++ status = "disabled";
++};
++
++&uart4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart4_pins>;
++ status = "disabled";
++};
++
++&uart5 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart5_pins>;
++ status = "disabled";
++};
++
++&usb0 {
++ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
++ <&stgcrg JH7110_STGCLK_USB0_STB>,
++ <&stgcrg JH7110_STGCLK_USB0_APB>,
++ <&stgcrg JH7110_STGCLK_USB0_AXI>,
++ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>,
++ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
++ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb", "phy";
++ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
++ <&stgcrg JH7110_STGRST_USB0_APB>,
++ <&stgcrg JH7110_STGRST_USB0_AXI>,
++ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>,
++ <&stgcrg JH7110_STGRST_PCIE0_APB>;
++ reset-names = "pwrup", "apb", "axi", "utmi_apb", "phy";
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_pins>;
++ dr_mode = "host"; /* host or peripheral */
++ status = "disabled";
++};
++
++&usb_cdns3 {
++ phys = <&usbphy0>, <&pciephy0>;
++ phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy";
++};
++
++&vin_sysctl {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* Parallel bus endpoint */
++ parallel_from_sc2235: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&sc2235_to_parallel>;
++ bus-type = <5>; /* Parallel */
++ bus-width = <8>;
++ data-shift = <2>; /* lines 9:2 are used */
++ hsync-active = <1>;
++ vsync-active = <0>;
++ pclk-sample = <1>;
++ status = "okay";
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* CSI2 bus endpoint */
++ csi2rx0_from_ov4689: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&ov4689_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ status = "okay";
++ };
++
++ /* CSI2 bus endpoint */
++ csi2rx0_from_imx219: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&imx219_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <2 1>;
++ lane-polarities = <1 1 1>;
++ status = "okay";
++ };
++
++ csi2rx0_from_imx708: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&imx708_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <2 1>;
++ lane-polarities = <1 1 1>;
++ status = "okay";
++ };
++ };
++ };
++};
++
++&vpu_dec {
++ status = "okay";
++};
++
++&vpu_enc {
++ status = "okay";
++};
++
++&xrp {
++ memory-region = <&xrp_reserved>;
++ status = "okay";
++};
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -196,11 +196,60 @@
+ opp-750000000 {
+ opp-hz = /bits/ 64 <750000000>;
+ opp-microvolt = <800000>;
++ opp-suspend;
+ };
+ opp-1500000000 {
+ opp-hz = /bits/ 64 <1500000000>;
+ opp-microvolt = <1040000>;
+ };
++ /* CPU opp table for 1.25GHz */
++ opp-312500000 {
++ opp-hz = /bits/ 64 <312500000>;
++ opp-microvolt = <800000>;
++ };
++ opp-417000000 {
++ opp-hz = /bits/ 64 <417000000>;
++ opp-microvolt = <800000>;
++ };
++ opp-625000000 {
++ opp-hz = /bits/ 64 <625000000>;
++ opp-microvolt = <800000>;
++ opp-suspend;
++ };
++ opp-1250000000 {
++ opp-hz = /bits/ 64 <1250000000>;
++ opp-microvolt = <1000000>;
++ };
++ };
++
++ display: display-subsystem {
++ compatible = "starfive,jh7110-display","verisilicon,display-subsystem";
++ status = "disabled";
++ };
++
++ dsi_output: dsi-output {
++ compatible = "starfive,jh7110-display-encoder","verisilicon,dsi-encoder";
++ status = "disabled";
++ };
++
++ mailbox_client0: mailbox_client {
++ compatible = "starfive,mailbox-test";
++ mbox-names = "rx", "tx";
++ mboxes = <&mailbox_contrl0 0 1>,<&mailbox_contrl0 1 0>;
++ status = "disabled";
++ };
++
++ rgb_output: rgb-output {
++ compatible = "starfive,jh7110-rgb_output","verisilicon,rgb-encoder";
++ //verisilicon,dss-syscon = <&dssctrl>;
++ //verisilicon,mux-mask = <0x70 0x380>;
++ //verisilicon,mux-val = <0x40 0x280>;
++ status = "disabled";
++ };
++
++ tda988x_pin: tda988x_pin {
++ compatible = "starfive,tda998x_rgb_pin";
++ status = "disabled";
+ };
+
+ thermal-zones {
+@@ -349,7 +398,9 @@
+
+ ccache: cache-controller@2010000 {
+ compatible = "starfive,jh7110-ccache", "sifive,ccache0", "cache";
+- reg = <0x0 0x2010000 0x0 0x4000>;
++ reg = <0x0 0x2010000 0x0 0x4000>,
++ <0x0 0x8000000 0x0 0x2000000>,
++ <0x0 0xa000000 0x0 0x2000000>;
+ interrupts = <1>, <3>, <4>, <2>;
+ cache-block-size = <64>;
+ cache-level = <2>;
+@@ -378,7 +429,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART0_CORE>,
+ <&syscrg JH7110_SYSCLK_UART0_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART0_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART0_APB>,
++ <&syscrg JH7110_SYSRST_UART0_CORE>;
+ interrupts = <32>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -391,7 +443,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART1_CORE>,
+ <&syscrg JH7110_SYSCLK_UART1_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART1_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART1_APB>,
++ <&syscrg JH7110_SYSRST_UART1_CORE>;
+ interrupts = <33>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -404,7 +457,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART2_CORE>,
+ <&syscrg JH7110_SYSCLK_UART2_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART2_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART2_APB>,
++ <&syscrg JH7110_SYSRST_UART2_CORE>;
+ interrupts = <34>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -513,6 +567,25 @@
+ status = "disabled";
+ };
+
++ spdif: spdif@100a0000 {
++ compatible = "starfive,jh7110-spdif";
++ reg = <0x0 0x100a0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_SPDIF_APB>,
++ <&syscrg JH7110_SYSCLK_SPDIF_CORE>,
++ <&syscrg JH7110_SYSCLK_AUDIO_ROOT>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>, <&syscrg JH7110_SYSCLK_MCLK>;
++ clock-names = "apb", "core",
++ "audroot", "mclk_inner",
++ "mclk_ext", "mclk";
++ resets = <&syscrg JH7110_SYSRST_SPDIF_APB>;
++ reset-names = "apb";
++ interrupts = <84>;
++ interrupt-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
+ pwmdac: pwmdac@100b0000 {
+ compatible = "starfive,jh7110-pwmdac";
+ reg = <0x0 0x100b0000 0x0 0x1000>;
+@@ -526,6 +599,42 @@
+ status = "disabled";
+ };
+
++ pdm: pdm@100d0000 {
++ compatible = "starfive,jh7110-pdm";
++ reg = <0x0 0x100d0000 0x0 0x1000>;
++ reg-names = "pdm";
++ clocks = <&syscrg JH7110_SYSCLK_PDM_DMIC>,
++ <&syscrg JH7110_SYSCLK_PDM_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&mclk_ext>;
++ clock-names = "pdm_mclk", "pdm_apb",
++ "clk_mclk", "mclk_ext";
++ resets = <&syscrg JH7110_SYSRST_PDM_DMIC>,
++ <&syscrg JH7110_SYSRST_PDM_APB>;
++ reset-names = "pdm_dmic", "pdm_apb";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2srx_mst: i2srx_mst@100e0000 {
++ compatible = "starfive,jh7110-i2srx-master";
++ reg = <0x0 0x100e0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2SRX_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2SRX_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner","mclk_ext";
++ resets = <&syscrg JH7110_SYSRST_I2SRX_APB>,
++ <&syscrg JH7110_SYSRST_I2SRX_BCLK>;
++ dmas = <&dma 24>;
++ dma-names = "rx";
++ starfive,syscon = <&sys_syscon 0x18 0x2 0x34 0x3FC00 0x24400>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
+ i2srx: i2s@100e0000 {
+ compatible = "starfive,jh7110-i2srx";
+ reg = <0x0 0x100e0000 0x0 0x1000>;
+@@ -622,6 +731,26 @@
+ #reset-cells = <1>;
+ };
+
++ xrp: xrp@10230000 {
++ compatible = "cdns,xrp";
++ dma-coherent;
++ reg = <0x0 0x10230000 0x0 0x00010000
++ 0x0 0x10240000 0x0 0x00010000>;
++ clocks = <&stgcrg JH7110_STGCLK_HIFI4_CLK_CORE>;
++ clock-names = "core_clk";
++ resets = <&stgcrg JH7110_STGRST_HIFI4_CORE>,
++ <&stgcrg JH7110_STGRST_HIFI4_AXI>;
++ reset-names = "rst_core","rst_axi";
++ starfive,stg-syscon = <&stg_syscon>;
++ firmware-name = "hifi4_elf";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x40000000 0x0 0x20000000 0x040000
++ 0x69c00000 0x0 0x69c00000 0x03000000>;
++ status = "disabled";
++ dsp@0 {};
++ };
++
+ stg_syscon: syscon@10240000 {
+ compatible = "starfive,jh7110-stg-syscon", "syscon";
+ reg = <0x0 0x10240000 0x0 0x1000>;
+@@ -633,7 +762,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART3_CORE>,
+ <&syscrg JH7110_SYSCLK_UART3_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART3_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART3_APB>,
++ <&syscrg JH7110_SYSRST_UART3_CORE>;
+ interrupts = <45>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -646,7 +776,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART4_CORE>,
+ <&syscrg JH7110_SYSCLK_UART4_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART4_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART4_APB>,
++ <&syscrg JH7110_SYSRST_UART4_CORE>;
+ interrupts = <46>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -659,7 +790,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART5_CORE>,
+ <&syscrg JH7110_SYSCLK_UART5_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART5_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART5_APB>,
++ <&syscrg JH7110_SYSRST_UART5_CORE>;
+ interrupts = <47>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -919,6 +1051,18 @@
+ "ch2", "ch3";
+ };
+
++ mailbox_contrl0: mailbox@13060000 {
++ compatible = "starfive,mail_box";
++ reg = <0x0 0x13060000 0x0 0x0001000>;
++ clocks = <&syscrg JH7110_SYSCLK_MAILBOX_APB>;
++ clock-names = "clk_apb";
++ resets = <&syscrg JH7110_SYSRST_MAILBOX_APB>;
++ reset-names = "mbx_rre";
++ interrupts = <26 27>;
++ #mbox-cells = <2>;
++ status = "disabled";
++ };
++
+ watchdog@13070000 {
+ compatible = "starfive,jh7110-wdt";
+ reg = <0x0 0x13070000 0x0 0x10000>;
+@@ -929,6 +1073,112 @@
+ <&syscrg JH7110_SYSRST_WDT_CORE>;
+ };
+
++ jpu: jpu@13090000 {
++ compatible = "starfive,jpu";
++ dma-coherent;
++ reg = <0x0 0x13090000 0x0 0x300>;
++ interrupts = <14>;
++ clocks = <&syscrg JH7110_SYSCLK_CODAJ12_AXI>,
++ <&syscrg JH7110_SYSCLK_CODAJ12_CORE>,
++ <&syscrg JH7110_SYSCLK_CODAJ12_APB>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_VDEC_AXI>,
++ <&syscrg JH7110_SYSCLK_VDEC_MAIN>,
++ <&syscrg JH7110_SYSCLK_VDEC_JPG>;
++ clock-names = "axi_clk", "core_clk", "apb_clk",
++ "noc_bus", "main_clk", "dec_clk";
++ resets = <&syscrg JH7110_SYSRST_CODAJ12_AXI>,
++ <&syscrg JH7110_SYSRST_CODAJ12_CORE>,
++ <&syscrg JH7110_SYSRST_CODAJ12_APB>;
++ reset-names = "rst_axi", "rst_core", "rst_apb";
++ power-domains = <&pwrc JH7110_PD_VDEC>;
++ status = "disabled";
++ };
++
++ vpu_dec: vpu_dec@130a0000 {
++ compatible = "starfive,vdec";
++ dma-coherent;
++ reg = <0x0 0x130a0000 0x0 0x10000>;
++ interrupts = <13>;
++ clocks = <&syscrg JH7110_SYSCLK_WAVE511_AXI>,
++ <&syscrg JH7110_SYSCLK_WAVE511_BPU>,
++ <&syscrg JH7110_SYSCLK_WAVE511_VCE>,
++ <&syscrg JH7110_SYSCLK_WAVE511_APB>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_VDEC_AXI>,
++ <&syscrg JH7110_SYSCLK_VDEC_MAIN>;
++ clock-names = "axi_clk", "bpu_clk", "vce_clk",
++ "apb_clk", "noc_bus", "main_clk";
++ resets = <&syscrg JH7110_SYSRST_WAVE511_AXI>,
++ <&syscrg JH7110_SYSRST_WAVE511_BPU>,
++ <&syscrg JH7110_SYSRST_WAVE511_VCE>,
++ <&syscrg JH7110_SYSRST_WAVE511_APB>,
++ <&syscrg JH7110_SYSRST_AXIMEM0_AXI>;
++ reset-names = "rst_axi", "rst_bpu", "rst_vce",
++ "rst_apb", "rst_sram";
++ starfive,vdec_noc_ctrl;
++ power-domains = <&pwrc JH7110_PD_VDEC>;
++ status = "disabled";
++ };
++
++ vpu_enc: vpu_enc@130b0000 {
++ compatible = "starfive,venc";
++ dma-coherent;
++ reg = <0x0 0x130b0000 0x0 0x10000>;
++ interrupts = <15>;
++ clocks = <&syscrg JH7110_SYSCLK_WAVE420L_AXI>,
++ <&syscrg JH7110_SYSCLK_WAVE420L_BPU>,
++ <&syscrg JH7110_SYSCLK_WAVE420L_VCE>,
++ <&syscrg JH7110_SYSCLK_WAVE420L_APB>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_VENC_AXI>;
++ clock-names = "axi_clk", "bpu_clk", "vce_clk",
++ "apb_clk", "noc_bus";
++ resets = <&syscrg JH7110_SYSRST_WAVE420L_AXI>,
++ <&syscrg JH7110_SYSRST_WAVE420L_BPU>,
++ <&syscrg JH7110_SYSRST_WAVE420L_VCE>,
++ <&syscrg JH7110_SYSRST_WAVE420L_APB>,
++ <&syscrg JH7110_SYSRST_AXIMEM1_AXI>;
++ reset-names = "rst_axi", "rst_bpu", "rst_vce",
++ "rst_apb", "rst_sram";
++ starfive,venc_noc_ctrl;
++ power-domains = <&pwrc JH7110_PD_VENC>;
++ status = "disabled";
++ };
++
++ can0: can@130d0000 {
++ compatible = "starfive,jh7110-can", "ipms,can";
++ reg = <0x0 0x130d0000 0x0 0x1000>;
++ interrupts = <112>;
++ clocks = <&syscrg JH7110_SYSCLK_CAN0_APB>,
++ <&syscrg JH7110_SYSCLK_CAN0_CAN>,
++ <&syscrg JH7110_SYSCLK_CAN0_TIMER>;
++ clock-names = "apb_clk", "core_clk", "timer_clk";
++ resets = <&syscrg JH7110_SYSRST_CAN0_APB>,
++ <&syscrg JH7110_SYSRST_CAN0_CORE>,
++ <&syscrg JH7110_SYSRST_CAN0_TIMER>;
++ reset-names = "rst_apb", "rst_core", "rst_timer";
++ frequency = <40000000>;
++ starfive,sys-syscon = <&sys_syscon 0x10 0x3 0x8>;
++ syscon,can_or_canfd = <0>;
++ status = "disabled";
++ };
++
++ can1: can@130e0000 {
++ compatible = "starfive,jh7110-can", "ipms,can";
++ reg = <0x0 0x130e0000 0x0 0x1000>;
++ interrupts = <113>;
++ clocks = <&syscrg JH7110_SYSCLK_CAN1_APB>,
++ <&syscrg JH7110_SYSCLK_CAN1_CAN>,
++ <&syscrg JH7110_SYSCLK_CAN1_TIMER>;
++ clock-names = "apb_clk", "core_clk", "timer_clk";
++ resets = <&syscrg JH7110_SYSRST_CAN1_APB>,
++ <&syscrg JH7110_SYSRST_CAN1_CORE>,
++ <&syscrg JH7110_SYSRST_CAN1_TIMER>;
++ reset-names = "rst_apb", "rst_core", "rst_timer";
++ frequency = <40000000>;
++ starfive,sys-syscon = <&sys_syscon 0x88 0x12 0x40000>;
++ syscon,can_or_canfd = <0>;
++ status = "disabled";
++ };
++
+ crypto: crypto@16000000 {
+ compatible = "starfive,jh7110-crypto";
+ reg = <0x0 0x16000000 0x0 0x4000>;
+@@ -1119,6 +1369,42 @@
+ #power-domain-cells = <1>;
+ };
+
++ rtc: rtc@17040000 {
++ compatible = "starfive,jh7110-rtc";
++ reg = <0x0 0x17040000 0x0 0x10000>;
++ interrupts = <10>, <11>, <12>;
++ interrupt-names = "rtc_ms_pulse", "rtc_sec_pulse", "rtc";
++ clocks = <&aoncrg JH7110_AONCLK_RTC_APB>,
++ <&aoncrg JH7110_AONCLK_RTC_CAL>;
++ clock-names = "pclk", "cal_clk";
++ resets = <&aoncrg JH7110_AONRST_RTC_32K>,
++ <&aoncrg JH7110_AONRST_RTC_APB>,
++ <&aoncrg JH7110_AONRST_RTC_CAL>;
++ reset-names = "rst_osc", "rst_apb", "rst_cal";
++ rtc,cal-clock-freq = <1000000>;
++ };
++
++ gpu: gpu@18000000 {
++ compatible = "img-gpu";
++ reg = <0x0 0x18000000 0x0 0x100000>,
++ <0x0 0x130C000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_GPU_CORE>,
++ <&syscrg JH7110_SYSCLK_GPU_APB>,
++ <&syscrg JH7110_SYSCLK_GPU_RTC_TOGGLE>,
++ <&syscrg JH7110_SYSCLK_GPU_CORE_CLK>,
++ <&syscrg JH7110_SYSCLK_GPU_SYS_CLK>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_GPU_AXI>;
++ clock-names = "clk_bv", "clk_apb", "clk_rtc",
++ "clk_core", "clk_sys", "clk_axi";
++ resets = <&syscrg JH7110_SYSRST_GPU_APB>,
++ <&syscrg JH7110_SYSRST_GPU_DOMA>;
++ reset-names = "rst_apb", "rst_doma";
++ power-domains = <&pwrc JH7110_PD_GPUA>;
++ interrupts = <82>;
++ current-clock = <8000000>;
++ status = "disabled";
++ };
++
+ csi2rx: csi-bridge@19800000 {
+ compatible = "starfive,jh7110-csi2rx";
+ reg = <0x0 0x19800000 0x0 0x10000>;
+@@ -1145,6 +1431,67 @@
+ status = "disabled";
+ };
+
++ vin_sysctl: vin_sysctl@19800000 {
++ compatible = "starfive,jh7110-vin";
++ reg = <0x0 0x19800000 0x0 0x10000>,
++ <0x0 0x19810000 0x0 0x10000>,
++ <0x0 0x19820000 0x0 0x10000>,
++ <0x0 0x19840000 0x0 0x10000>,
++ <0x0 0x19870000 0x0 0x30000>,
++ <0x0 0x11840000 0x0 0x10000>,
++ <0x0 0x17030000 0x0 0x10000>,
++ <0x0 0x13020000 0x0 0x10000>;
++ reg-names = "csi2rx", "vclk", "vrst", "sctrl",
++ "isp", "trst", "pmu", "syscrg";
++ clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
++ <&ispcrg JH7110_ISPCLK_VIN_APB>,
++ <&ispcrg JH7110_ISPCLK_VIN_SYS>,
++ <&ispcrg JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C>,
++ <&ispcrg JH7110_ISPCLK_DVP_INV>,
++ <&ispcrg JH7110_ISPCLK_VIN_P_AXI_WR>,
++ <&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>,
++ <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
++ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>;
++ clock-names = "clk_apb_func", "clk_pclk", "clk_sys_clk",
++ "clk_wrapper_clk_c", "clk_dvp_inv", "clk_axiwr",
++ "clk_mipi_rx0_pxl", "clk_pixel_clk_if0",
++ "clk_pixel_clk_if1", "clk_pixel_clk_if2",
++ "clk_pixel_clk_if3", "clk_m31dphy_cfgclk_in",
++ "clk_m31dphy_refclk_in", "clk_m31dphy_txclkesc_lan0",
++ "clk_ispcore_2x", "clk_isp_axi";
++ resets = <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_P>,
++ <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_C>,
++ <&ispcrg JH7110_ISPRST_VIN_APB>,
++ <&ispcrg JH7110_ISPRST_VIN_SYS>,
++ <&ispcrg JH7110_ISPRST_VIN_P_AXI_RD>,
++ <&ispcrg JH7110_ISPRST_VIN_P_AXI_WR>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>,
++ <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
++ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>,
++ <&syscrg JH7110_SYSRST_ISP_TOP>,
++ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>;
++ reset-names = "rst_wrapper_p", "rst_wrapper_c", "rst_pclk",
++ "rst_sys_clk", "rst_axird", "rst_axiwr", "rst_pixel_clk_if0",
++ "rst_pixel_clk_if1", "rst_pixel_clk_if2", "rst_pixel_clk_if3",
++ "rst_m31dphy_hw", "rst_m31dphy_b09_always_on",
++ "rst_isp_top_n", "rst_isp_top_axi";
++ starfive,aon-syscon = <&aon_syscon 0x00>;
++ power-domains = <&pwrc JH7110_PD_ISP>;
++ /* irq nr: vin, isp, isp_csi, isp_scd, isp_csiline */
++ interrupts = <92 87 88 89 90>;
++ status = "disabled";
++ };
++
+ ispcrg: clock-controller@19810000 {
+ compatible = "starfive,jh7110-ispcrg";
+ reg = <0x0 0x19810000 0x0 0x10000>;
+@@ -1175,6 +1522,66 @@
+ #phy-cells = <0>;
+ };
+
++ dc8200: dc8200@29400000 {
++ compatible = "starfive,jh7110-dc8200","verisilicon,dc8200";
++ verisilicon,dss-syscon = <&dssctrl>;//20220624 panel syscon
++ reg = <0x0 0x29400000 0x0 0x100>,
++ <0x0 0x29400800 0x0 0x2000>,
++ <0x0 0x17030000 0x0 0x1000>;
++ interrupts = <95>;
++ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_DISP_AXI>,
++ <&syscrg JH7110_SYSCLK_VOUT_SRC>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_PIX0>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_PIX1>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_AXI>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_CORE>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_AHB>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
++ <&voutcrg JH7110_VOUTCLK_DOM_VOUT_TOP_LCD>,
++ <&hdmitx0_pixelclk>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_PIX>;
++ clock-names = "noc_disp","vout_src",
++ "top_vout_axi","top_vout_ahb",
++ "pix_clk","vout_pix1",
++ "axi_clk","core_clk","vout_ahb",
++ "vout_top_axi","vout_top_lcd","hdmitx0_pixelclk","dc8200_pix0";
++ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>,
++ <&voutcrg JH7110_VOUTRST_DC8200_AXI>,
++ <&voutcrg JH7110_VOUTRST_DC8200_AHB>,
++ <&voutcrg JH7110_VOUTRST_DC8200_CORE>,
++ <&syscrg JH7110_SYSRST_NOC_BUS_DISP_AXI>;
++ reset-names = "rst_vout_src","rst_axi","rst_ahb","rst_core",
++ "rst_noc_disp";
++ status = "disabled";
++ };
++
++ hdmi: hdmi@29590000 {
++ compatible = "starfive,jh7110-hdmi","inno,hdmi";
++ reg = <0x0 0x29590000 0x0 0x4000>;
++ interrupts = <99>;
++ /*interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;*/
++ /*clocks = <&cru PCLK_HDMI>;*/
++ /*clock-names = "pclk";*/
++ /*pinctrl-names = "default";*/
++ /*pinctrl-0 = <&hdmi_ctl>;*/
++ clocks = <&voutcrg JH7110_VOUTCLK_HDMI_TX_SYS>,
++ <&voutcrg JH7110_VOUTCLK_HDMI_TX_MCLK>,
++ <&voutcrg JH7110_VOUTCLK_HDMI_TX_BCLK>,
++ <&hdmitx0_pixelclk>;
++ clock-names = "sysclk", "mclk","bclk","pclk";
++ resets = <&voutcrg JH7110_VOUTRST_HDMI_TX_HDMI>;
++ reset-names = "hdmi_tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ dssctrl: dssctrl@295B0000 {
++ compatible = "starfive,jh7110-dssctrl","verisilicon,dss-ctrl", "syscon";
++ reg = <0 0x295B0000 0 0x90>;
++ };
++
+ voutcrg: clock-controller@295c0000 {
+ compatible = "starfive,jh7110-voutcrg";
+ reg = <0x0 0x295c0000 0x0 0x10000>;
+@@ -1193,6 +1600,67 @@
+ power-domains = <&pwrc JH7110_PD_VOUT>;
+ };
+
++ mipi_dsi: mipi@295d0000 {
++ compatible = "starfive,jh7110-mipi_dsi","cdns,dsi";
++ reg = <0x0 0x295d0000 0x0 0x10000>;
++ interrupts = <98>;
++ reg-names = "dsi";
++ clocks = <&voutcrg JH7110_VOUTCLK_DSITX_SYS>,
++ <&voutcrg JH7110_VOUTCLK_DSITX_APB>,
++ <&voutcrg JH7110_VOUTCLK_DSITX_TXESC>,
++ <&voutcrg JH7110_VOUTCLK_DSITX_DPI>;
++ clock-names = "dpi", "apb", "txesc", "sys";
++ resets = <&voutcrg JH7110_VOUTRST_DSITX_DPI>,
++ <&voutcrg JH7110_VOUTRST_DSITX_APB>,
++ <&voutcrg JH7110_VOUTRST_DSITX_RXESC>,
++ <&voutcrg JH7110_VOUTRST_DSITX_SYS>,
++ <&voutcrg JH7110_VOUTRST_DSITX_TXBYTEHS>,
++ <&voutcrg JH7110_VOUTRST_DSITX_TXESC>;
++ reset-names = "dsi_dpi", "dsi_apb", "dsi_rxesc",
++ "dsi_sys", "dsi_txbytehs", "dsi_txesc";
++ phys = <&mipi_dphy>;
++ phy-names = "dphy";
++ status = "disabled";
++ };
++
++ mipi_dphy: mipi-dphy@295e0000{
++ compatible = "starfive,jh7110-mipi-dphy-tx","m31,mipi-dphy-tx";
++ reg = <0x0 0x295e0000 0x0 0x10000>;
++ clocks = <&voutcrg JH7110_VOUTCLK_MIPITX_DPHY_TXESC>;
++ clock-names = "dphy_txesc";
++ resets = <&voutcrg JH7110_VOUTRST_MIPITX_DPHY_SYS>,
++ <&voutcrg JH7110_VOUTRST_MIPITX_DPHY_TXBYTEHS>;
++ reset-names = "dphy_sys", "dphy_txbytehs";
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++
++ co_process: e24@6e210000 {
++ compatible = "starfive,e24";
++ dma-coherent;
++ reg = <0x0 0x6e210000 0x0 0x00001000>,
++ <0x0 0x6e211000 0x0 0x0003f000>;
++ reg-names = "ecmd", "espace";
++ clocks = <&stgcrg JH7110_STGCLK_E2_RTC>,
++ <&stgcrg JH7110_STGCLK_E2_CORE>,
++ <&stgcrg JH7110_STGCLK_E2_DBG>;
++ clock-names = "clk_rtc", "clk_core", "clk_dbg";
++ resets = <&stgcrg JH7110_STGRST_E24_CORE>;
++ reset-names = "e24_core";
++ starfive,stg-syscon = <&stg_syscon>;
++ interrupt-parent = <&plic>;
++ firmware-name = "e24_elf";
++ irq-mode = <1>;
++ mbox-names = "tx", "rx";
++ mboxes = <&mailbox_contrl0 0 2>,
++ <&mailbox_contrl0 2 0>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x6ce00000 0x0 0x6ce00000 0x1600000>;
++ status = "disabled";
++ dsp@0 {};
++ };
++
+ pcie0: pcie@940000000 {
+ compatible = "starfive,jh7110-pcie";
+ reg = <0x9 0x40000000 0x0 0x1000000>,
diff --git a/target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch b/target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch
new file mode 100644
index 0000000000..7a23bf931b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch
@@ -0,0 +1,728 @@
+From cae7550054ca0cd940bbc1501ae5611f5d2957e6 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Wed, 20 Sep 2023 14:53:22 +0800
+Subject: [PATCH 057/116] riscv: dts: starfive: Add JH7110 EVB expanded device
+ tree
+
+Add JH7110 EVB expanded device tree.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 11 +-
+ .../starfive/jh7110-evb-can-pdm-pwmdac.dts | 102 ++++++++++++++++
+ .../dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts | 37 ++++++
+ .../dts/starfive/jh7110-evb-i2s-ac108.dts | 72 ++++++++++++
+ .../dts/starfive/jh7110-evb-pcie-i2s-sd.dts | 111 ++++++++++++++++++
+ .../dts/starfive/jh7110-evb-spi-uart2.dts | 65 ++++++++++
+ .../starfive/jh7110-evb-uart1-rgb2hdmi.dts | 57 +++++++++
+ .../starfive/jh7110-evb-uart4-emmc-spdif.dts | 78 ++++++++++++
+ .../starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts | 95 +++++++++++++++
+ .../dts/starfive/jh7110-evb-usbdevice.dts | 35 ++++++
+ 10 files changed, 662 insertions(+), 1 deletion(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-can-pdm-pwmdac.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-i2s-ac108.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-pcie-i2s-sd.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-spi-uart2.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart1-rgb2hdmi.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart4-emmc-spdif.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -12,4 +12,13 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-st
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
+
+-dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
++ jh7110-evb-pcie-i2s-sd.dtb \
++ jh7110-evb-spi-uart2.dtb \
++ jh7110-evb-uart4-emmc-spdif.dtb \
++ jh7110-evb-uart5-pwm-i2c-tdm.dtb \
++ jh7110-evb-dvp-rgb2hdmi.dtb \
++ jh7110-evb-can-pdm-pwmdac.dtb \
++ jh7110-evb-i2s-ac108.dtb \
++ jh7110-evb-usbdevice.dtb \
++ jh7110-evb-uart1-rgb2hdmi.dtb
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-can-pdm-pwmdac.dts
+@@ -0,0 +1,102 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ sound2: snd-card2 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-PDM-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&dailink_master>;
++ frame-master = <&dailink_master>;
++
++ dailink_master:cpu {
++ sound-dai = <&i2srx_mst>;
++ };
++
++ dailink_slave:codec {
++ sound-dai = <&pdm>;
++ };
++ };
++ };
++
++ pwmdac_codec: pwmdac-codec {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ sound3: snd-card3 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&pwmdac>;
++ };
++
++ codec {
++ sound-dai = <&pwmdac_codec>;
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&can0 {
++ status = "okay";
++};
++
++&can1 {
++ status = "okay";
++};
++
++&i2srx_mst {
++ status = "okay";
++};
++
++&pwmdac {
++ status = "okay";
++};
++
++&pdm {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts
+@@ -0,0 +1,37 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&vin_sysctl {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dvp_pins>;
++};
++
++&rgb_output {
++ status = "okay";
++};
++
++&tda988x_pin {
++ status = "okay";
++};
++
++&dsi_output {
++ status = "disabled";
++};
++
++&mipi_dsi {
++ status = "disabled";
++};
++
++&mipi_dphy {
++ status = "disabled";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-i2s-ac108.dts
+@@ -0,0 +1,72 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ /* i2s + ac108 */
++ sound0: snd-card0 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-AC108-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ cpu {
++ sound-dai = <&i2srx>;
++ };
++
++ sndcodec1: codec {
++ sound-dai = <&ac108>;
++ clocks = <&ac108_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++};
++
++&i2srx {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-pcie-i2s-sd.dts
+@@ -0,0 +1,111 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ /* i2s + wm8960 */
++ sound6: snd-card6 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-WM8960-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ status = "okay";
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++ cpu0 {
++ sound-dai = <&i2srx>;
++ };
++ cpu1 {
++ sound-dai = <&i2stx1>;
++ };
++
++ sndcodec1:codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&pcie0 {
++ status = "okay";
++};
++
++&uart3 {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++};
++
++&usb0 {
++ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
++ <&stgcrg JH7110_STGCLK_USB0_STB>,
++ <&stgcrg JH7110_STGCLK_USB0_APB>,
++ <&stgcrg JH7110_STGCLK_USB0_AXI>,
++ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>;
++ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
++ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
++ <&stgcrg JH7110_STGRST_USB0_APB>,
++ <&stgcrg JH7110_STGRST_USB0_AXI>,
++ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>;
++ reset-names = "pwrup", "apb", "axi", "utmi_apb";
++ dr_mode = "host"; /*host or peripheral*/
++ starfive,usb2-only;
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_pins>;
++ status = "okay";
++};
++
++&i2srx {
++ status = "okay";
++};
++
++&i2stx1 {
++ status = "okay";
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-spi-uart2.dts
+@@ -0,0 +1,65 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&spi0 {
++ status = "okay";
++};
++
++&spi1 {
++ status = "okay";
++};
++
++&spi2 {
++ status = "okay";
++};
++
++&spi3 {
++ status = "okay";
++};
++
++&spi4 {
++ status = "okay";
++};
++
++&spi5 {
++ status = "okay";
++};
++
++&spi6 {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart1-rgb2hdmi.dts
+@@ -0,0 +1,57 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart1 {
++ status = "okay";
++};
++
++&rgb_output {
++ status = "okay";
++};
++
++&tda988x_pin {
++ status = "okay";
++};
++
++&dsi_output {
++ status = "disabled";
++};
++
++&mipi_dsi {
++ status = "disabled";
++};
++
++&mipi_dphy {
++ status = "disabled";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart4-emmc-spdif.dts
+@@ -0,0 +1,78 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ spdif_transmitter: spdif_transmitter {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ sound4: snd-card4 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-SPDIF-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&spdif>;
++ };
++
++ codec {
++ sound-dai = <&spdif_transmitter>;
++ };
++ };
++ };
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart4 {
++ status = "okay";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ mmc-hs200-1_8v;
++ non-removable;
++ cap-mmc-hw-reset;
++ board-is-evb;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_ch6to7_pins>;
++ status = "okay";
++};
++
++&spdif {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts
+@@ -0,0 +1,95 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ sound5: snd-card5 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-TDM-Sound-Card";
++ simple-audio-card,widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ simple-audio-card,routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "dsp_a";
++ bitclock-master = <&dailink_master>;
++ frame-master = <&dailink_master>;
++
++ cpu {
++ sound-dai = <&tdm>;
++ };
++ dailink_master: codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart5 {
++ status = "okay";
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_ch0to3_pins &pwm_ch4to5_pins>;
++ status = "okay";
++};
++
++&tdm {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++};
++
++&i2c1 {
++ status = "okay";
++};
++
++&i2c3 {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
+@@ -0,0 +1,35 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++/* default sd card */
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ dr_mode = "peripheral"; /*host or peripheral*/
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
diff --git a/target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch b/target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch
new file mode 100644
index 0000000000..a75ffc2aff
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch
@@ -0,0 +1,485 @@
+From e9122ceaf2d8767753e2a126c14b29b78280446d Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 19 Sep 2023 21:35:39 +0800
+Subject: [PATCH 058/116] riscv: dts: starfive: Add evb-overlay dtso subdir
+
+Create subdir evb-overlay/ and add overlay .dtso for JH7110 EVB.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 1 +
+ .../boot/dts/starfive/evb-overlay/Makefile | 7 +
+ .../evb-overlay/jh7110-evb-overlay-can.dtso | 24 ++++
+ .../jh7110-evb-overlay-rgb2hdmi.dtso | 24 ++++
+ .../evb-overlay/jh7110-evb-overlay-sdio.dtso | 78 +++++++++++
+ .../evb-overlay/jh7110-evb-overlay-spi.dtso | 72 ++++++++++
+ .../jh7110-evb-overlay-uart4-emmc.dtso | 130 ++++++++++++++++++
+ .../jh7110-evb-overlay-uart5-pwm.dtso | 92 +++++++++++++
+ 8 files changed, 428 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/Makefile
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-can.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-rgb2hdmi.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-sdio.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart4-emmc.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart5-pwm.dtso
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-st
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
+
++subdir-y += evb-overlay
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
+ jh7110-evb-pcie-i2s-sd.dtb \
+ jh7110-evb-spi-uart2.dtb \
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/Makefile
+@@ -0,0 +1,7 @@
++# SPDX-License-Identifier: GPL-2.0
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb-overlay-can.dtbo \
++ jh7110-evb-overlay-sdio.dtbo \
++ jh7110-evb-overlay-spi.dtbo \
++ jh7110-evb-overlay-uart4-emmc.dtbo \
++ jh7110-evb-overlay-uart5-pwm.dtbo \
++ jh7110-evb-overlay-rgb2hdmi.dtbo
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-can.dtso
+@@ -0,0 +1,24 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //can0
++ fragment@0 {
++ target-path = "/soc/can@130d0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //can1
++ fragment@1 {
++ target-path = "/soc/can@130e0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-rgb2hdmi.dtso
+@@ -0,0 +1,24 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //hdmi_output
++ fragment@0 {
++ target-path = "/tda988x_pin";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //uart1
++ fragment@1 {
++ target-path = "/soc/serial@10010000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-sdio.dtso
+@@ -0,0 +1,78 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_sdcard1_pins: dt-sdcard1-0 {
++ sdcard-pins {
++ pinmux = <GPIOMUX(56, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(50, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(49, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(45, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(62, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(40, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++ };
++ };
++
++ //uart3
++ fragment@1 {
++ target-path = "/soc/serial@12000000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //i2c0
++ fragment@2 {
++ target-path = "/soc/i2c@10030000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //mmc1
++ fragment@3 {
++ target-path = "/soc/mmc@16020000";
++ __overlay__ {
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ no-sdio;
++ no-mmc;
++ broken-cd;
++ sd-uhs-sdr12;
++ sd-uhs-sdr25;
++ sd-uhs-sdr50;
++ sd-uhs-sdr104;
++ sd-uhs-ddr50;
++ cap-sd-highspeed;
++ post-power-on-delay-ms = <200>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_sdcard1_pins>;
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
+@@ -0,0 +1,72 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //spi0
++ fragment@0 {
++ target-path = "/soc/spi@10060000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi1
++ fragment@1 {
++ target-path = "/soc/spi@10070000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi2
++ fragment@2 {
++ target-path = "/soc/spi@10080000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi3
++ fragment@3 {
++ target-path = "/soc/spi@12070000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi4
++ fragment@4 {
++ target-path = "/soc/spi@12080000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi5
++ fragment@5 {
++ target-path = "/soc/spi@12090000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi6
++ fragment@6 {
++ target-path = "/soc/spi@120a0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //uart2
++ fragment@7 {
++ target-path = "/soc/serial@10020000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart4-emmc.dtso
+@@ -0,0 +1,130 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_emmc0_pins: dt-emmc0-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(22, GPOUT_SYS_SDIO0_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <PINMUX(64, 0)>,
++ <PINMUX(65, 0)>,
++ <PINMUX(66, 0)>,
++ <PINMUX(67, 0)>,
++ <PINMUX(68, 0)>,
++ <PINMUX(69, 0)>,
++ <PINMUX(70, 0)>,
++ <PINMUX(71, 0)>,
++ <PINMUX(72, 0)>,
++ <PINMUX(73, 0)>;
++ bias-pull-up;
++ drive-strength = <12>;
++ input-enable;
++ slew-rate = <1>;
++ };
++ };
++
++ dt_emmc1_pins: dt-emmc1-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(51, GPOUT_SYS_SDIO1_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(38, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(36, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(43, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(48, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(53, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(63, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>,
++ <GPIOMUX(52, GPOUT_SYS_SDIO1_DATA4,
++ GPOEN_SYS_SDIO1_DATA4,
++ GPI_SYS_SDIO1_DATA4)>,
++ <GPIOMUX(39, GPOUT_SYS_SDIO1_DATA5,
++ GPOEN_SYS_SDIO1_DATA5,
++ GPI_SYS_SDIO1_DATA5)>,
++ <GPIOMUX(46, GPOUT_SYS_SDIO1_DATA6,
++ GPOEN_SYS_SDIO1_DATA6,
++ GPI_SYS_SDIO1_DATA6)>,
++ <GPIOMUX(47, GPOUT_SYS_SDIO1_DATA7,
++ GPOEN_SYS_SDIO1_DATA7,
++ GPI_SYS_SDIO1_DATA7)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++ };
++ };
++
++ //aongpio
++ fragment@1 {
++ target-path = "/soc/pinctrl@17020000";
++ __overlay__ {
++ dt_pwm_ch6to7_pins: dt-pwm-ch6to7-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM6, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_6,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM7, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_7,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++ };
++ };
++
++ //uart4
++ fragment@2 {
++ target-path = "/soc/serial@12010000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //mmc1
++ fragment@3 {
++ target-path = "/soc/mmc@16020000";
++ __overlay__ {
++ clock-frequency = <102400000>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <8>;
++ cap-mmc-hw-reset;
++ non-removable;
++ cap-mmc-highspeed;
++ post-power-on-delay-ms = <200>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_emmc1_pins>;
++ status = "okay";
++ };
++ };
++
++ //ptc
++ fragment@4 {
++ target-path = "/soc/pwm@120d0000";
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_pwm_ch6to7_pins>;
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart5-pwm.dtso
+@@ -0,0 +1,92 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_pwm_ch0to3_pins: dt-pwm-ch0to3-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(45, GPOUT_SYS_PWM_CHANNEL0,
++ GPOEN_SYS_PWM0_CHANNEL0,
++ GPI_NONE)>,
++ <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL1,
++ GPOEN_SYS_PWM0_CHANNEL1,
++ GPI_NONE)>,
++ <GPIOMUX(47, GPOUT_SYS_PWM_CHANNEL2,
++ GPOEN_SYS_PWM0_CHANNEL2,
++ GPI_NONE)>,
++ <GPIOMUX(48, GPOUT_SYS_PWM_CHANNEL3,
++ GPOEN_SYS_PWM0_CHANNEL3,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++ };
++ };
++
++ //aongpio
++ fragment@1 {
++ target-path = "/soc/pinctrl@17020000";
++ __overlay__ {
++ dt_pwm_ch4to5_pins: dt-pwm-ch4to5-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM4, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_4,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM5, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_5,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++ };
++ };
++
++ //uart5
++ fragment@2 {
++ target-path = "/soc/serial@12020000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //ptc
++ fragment@3 {
++ target-path = "/soc/pwm@120d0000";
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_pwm_ch0to3_pins &dt_pwm_ch4to5_pins>;
++ status = "okay";
++ };
++ };
++
++ //i2c0
++ fragment@4 {
++ target-path = "/soc/i2c@10030000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //i2c1
++ fragment@5 {
++ target-path = "/soc/i2c@10040000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //i2c3
++ fragment@6 {
++ target-path = "/soc/i2c@12030000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
diff --git a/target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch b/target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch
new file mode 100644
index 0000000000..ddf72454eb
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch
@@ -0,0 +1,385 @@
+From 5c888fa081caf5d9473e733931d1c7b3d4b61e61 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 28 Jul 2023 18:42:55 +0800
+Subject: [PATCH 059/116] riscv: configs: Add starfive_jh7110_defconfig
+
+Add starfive_jh7110_defconfig for JH7110 EVB.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/configs/starfive_jh7110_defconfig | 368 +++++++++++++++++++
+ 1 file changed, 368 insertions(+)
+ create mode 100644 arch/riscv/configs/starfive_jh7110_defconfig
+
+--- /dev/null
++++ b/arch/riscv/configs/starfive_jh7110_defconfig
+@@ -0,0 +1,368 @@
++CONFIG_COMPILE_TEST=y
++# CONFIG_WERROR is not set
++CONFIG_DEFAULT_HOSTNAME="StarFive"
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_USELIB=y
++CONFIG_NO_HZ_IDLE=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_BPF_SYSCALL=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_CGROUPS=y
++CONFIG_MEMCG=y
++CONFIG_CGROUP_SCHED=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_CHECKPOINT_RESTORE=y
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_EXPERT=y
++# CONFIG_SYSFS_SYSCALL is not set
++CONFIG_PROFILING=y
++CONFIG_SOC_MICROCHIP_POLARFIRE=y
++CONFIG_SOC_STARFIVE=y
++CONFIG_SOC_VIRT=y
++CONFIG_ERRATA_SIFIVE=y
++CONFIG_NONPORTABLE=y
++CONFIG_SMP=y
++CONFIG_RISCV_SBI_V01=y
++# CONFIG_RISCV_BOOT_SPINWAIT is not set
++CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION="PARTLABEL=hibernation"
++CONFIG_PM_DEBUG=y
++CONFIG_PM_ADVANCED_DEBUG=y
++CONFIG_PM_TEST_SUSPEND=y
++CONFIG_ENERGY_MODEL=y
++CONFIG_CPU_IDLE=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_VIRTUALIZATION=y
++CONFIG_KVM=m
++CONFIG_JUMP_LABEL=y
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_BINFMT_MISC=y
++CONFIG_CMA=y
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_XFRM_USER=m
++CONFIG_IP_MULTICAST=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_INET_ESP=m
++CONFIG_NETFILTER=y
++CONFIG_BRIDGE_NETFILTER=m
++CONFIG_NF_CONNTRACK=m
++CONFIG_NF_CONNTRACK_FTP=m
++CONFIG_NF_CONNTRACK_TFTP=m
++CONFIG_NETFILTER_XT_MARK=m
++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
++CONFIG_NETFILTER_XT_MATCH_IPVS=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_NF_LOG_ARP=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_TARGET_REDIRECT=m
++CONFIG_IP_NF_MANGLE=m
++CONFIG_NF_LOG_IPV6=m
++CONFIG_IP6_NF_IPTABLES=m
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++CONFIG_IP6_NF_FILTER=m
++CONFIG_IP6_NF_TARGET_REJECT=m
++CONFIG_IP6_NF_MANGLE=m
++CONFIG_BRIDGE=m
++CONFIG_BRIDGE_VLAN_FILTERING=y
++CONFIG_VLAN_8021Q=m
++CONFIG_NET_SCHED=y
++CONFIG_NET_CLS_CGROUP=m
++CONFIG_NETLINK_DIAG=y
++CONFIG_CGROUP_NET_PRIO=y
++CONFIG_CAN=y
++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_HCIUART=y
++CONFIG_BT_HCIUART_H4=y
++CONFIG_CFG80211=y
++CONFIG_MAC80211=y
++CONFIG_RFKILL=y
++CONFIG_NET_9P=y
++CONFIG_NET_9P_VIRTIO=y
++CONFIG_PCI=y
++CONFIG_PCIEPORTBUS=y
++# CONFIG_PCIEASPM is not set
++CONFIG_PCI_HOST_GENERIC=y
++CONFIG_PCIE_FU740=y
++CONFIG_PCIE_STARFIVE_HOST=y
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_MTD=y
++CONFIG_MTD_BLOCK=y
++CONFIG_MTD_SPI_NOR=y
++CONFIG_OF_CONFIGFS=y
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_VIRTIO_BLK=y
++CONFIG_BLK_DEV_NVME=y
++CONFIG_BLK_DEV_SD=y
++CONFIG_BLK_DEV_SR=y
++CONFIG_SCSI_VIRTIO=y
++CONFIG_ATA=y
++CONFIG_SATA_AHCI=y
++CONFIG_SATA_AHCI_PLATFORM=y
++CONFIG_MD=y
++CONFIG_BLK_DEV_DM=m
++CONFIG_DM_THIN_PROVISIONING=m
++CONFIG_NETDEVICES=y
++CONFIG_DUMMY=m
++CONFIG_MACVLAN=m
++CONFIG_IPVLAN=m
++CONFIG_VXLAN=m
++CONFIG_VETH=m
++CONFIG_VIRTIO_NET=y
++CONFIG_MACB=y
++CONFIG_E1000E=y
++CONFIG_R8169=y
++CONFIG_STMMAC_ETH=y
++CONFIG_DWMAC_DWC_QOS_ETH=y
++# CONFIG_DWMAC_GENERIC is not set
++CONFIG_DWMAC_STARFIVE=y
++CONFIG_MARVELL_PHY=y
++CONFIG_MICREL_PHY=y
++CONFIG_MICROCHIP_PHY=y
++CONFIG_MICROSEMI_PHY=y
++CONFIG_MOTORCOMM_PHY=y
++CONFIG_IPMS_CAN=y
++CONFIG_IWLWIFI=y
++CONFIG_IWLDVM=y
++CONFIG_IWLMVM=y
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_EVDEV=y
++CONFIG_INPUT_TOUCHSCREEN=y
++CONFIG_TOUCHSCREEN_TINKER_FT5406=y
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=6
++CONFIG_SERIAL_8250_RUNTIME_UARTS=6
++CONFIG_SERIAL_8250_EXTENDED=y
++CONFIG_SERIAL_8250_MANY_PORTS=y
++CONFIG_SERIAL_8250_DW=y
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
++CONFIG_TTY_PRINTK=y
++CONFIG_VIRTIO_CONSOLE=y
++CONFIG_HW_RANDOM=y
++CONFIG_HW_RANDOM_VIRTIO=y
++CONFIG_HW_RANDOM_JH7110=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_DESIGNWARE_PLATFORM=y
++CONFIG_SPI=y
++CONFIG_SPI_CADENCE_QUADSPI=y
++CONFIG_SPI_PL022=y
++CONFIG_SPI_SIFIVE=y
++CONFIG_SPI_SPIDEV=y
++# CONFIG_PTP_1588_CLOCK is not set
++CONFIG_GPIO_SYSFS=y
++CONFIG_GPIO_SIFIVE=y
++CONFIG_SENSORS_SFCTEMP=y
++CONFIG_THERMAL=y
++CONFIG_THERMAL_WRITABLE_TRIPS=y
++CONFIG_CPU_THERMAL=y
++CONFIG_THERMAL_EMULATION=y
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_SYSFS=y
++CONFIG_MFD_AXP20X_I2C=y
++CONFIG_REGULATOR=y
++CONFIG_REGULATOR_AXP20X=y
++CONFIG_REGULATOR_STARFIVE_JH7110=y
++# CONFIG_MEDIA_CEC_SUPPORT is not set
++CONFIG_MEDIA_SUPPORT=y
++CONFIG_MEDIA_USB_SUPPORT=y
++CONFIG_USB_VIDEO_CLASS=y
++CONFIG_V4L_PLATFORM_DRIVERS=y
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++CONFIG_VIDEO_WAVE_VPU=m
++CONFIG_VIN_SENSOR_SC2235=y
++CONFIG_VIN_SENSOR_OV4689=y
++CONFIG_VIN_SENSOR_IMX219=y
++CONFIG_VIDEO_STF_VIN=y
++CONFIG_VIDEO_IMX708=y
++CONFIG_DRM_I2C_NXP_TDA998X=y
++CONFIG_DRM_I2C_NXP_TDA9950=y
++CONFIG_DRM_RADEON=m
++CONFIG_DRM_VIRTIO_GPU=m
++CONFIG_DRM_VERISILICON=y
++CONFIG_STARFIVE_INNO_HDMI=y
++CONFIG_STARFIVE_DSI=y
++CONFIG_DRM_IMG_ROGUE=y
++CONFIG_DRM_LEGACY=y
++CONFIG_FB=y
++CONFIG_SOUND=y
++CONFIG_SND=y
++CONFIG_SND_USB_AUDIO=y
++CONFIG_SND_SOC=y
++CONFIG_SND_DESIGNWARE_I2S=y
++# CONFIG_SND_SOC_INTEL_SST_TOPLEVEL is not set
++CONFIG_SND_SOC_STARFIVE=y
++CONFIG_SND_SOC_JH7110_PDM=y
++CONFIG_SND_SOC_JH7110_PWMDAC=y
++CONFIG_SND_SOC_JH7110_SPDIF=y
++CONFIG_SND_SOC_JH7110_TDM=y
++CONFIG_SND_SOC_AC108=y
++CONFIG_SND_SOC_WM8960=y
++CONFIG_SND_SIMPLE_CARD=y
++CONFIG_USB=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_HCD_PLATFORM=y
++CONFIG_USB_OHCI_HCD=y
++CONFIG_USB_OHCI_HCD_PLATFORM=y
++CONFIG_USB_STORAGE=y
++CONFIG_USB_UAS=y
++CONFIG_USB_CDNS_SUPPORT=y
++CONFIG_USB_CDNS3=y
++CONFIG_USB_CDNS3_GADGET=y
++CONFIG_USB_CDNS3_HOST=y
++CONFIG_USB_CDNS3_STARFIVE=y
++CONFIG_USB_GADGET=y
++CONFIG_USB_CONFIGFS=y
++CONFIG_USB_CONFIGFS_MASS_STORAGE=y
++CONFIG_USB_CONFIGFS_F_FS=y
++CONFIG_MMC=y
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_PLTFM=y
++CONFIG_MMC_SDHCI_CADENCE=y
++CONFIG_MMC_SPI=y
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_STARFIVE=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_DRV_SPEAR is not set
++CONFIG_RTC_DRV_STARFIVE=y
++CONFIG_DMADEVICES=y
++CONFIG_AMBA_PL08X=y
++CONFIG_DW_AXI_DMAC=y
++# CONFIG_SH_DMAE_BASE is not set
++# CONFIG_TI_EDMA is not set
++# CONFIG_DMA_OMAP is not set
++CONFIG_DMATEST=y
++CONFIG_VIRTIO_PCI=y
++CONFIG_VIRTIO_BALLOON=y
++CONFIG_VIRTIO_INPUT=y
++CONFIG_VIRTIO_MMIO=y
++CONFIG_STAGING=y
++CONFIG_STAGING_MEDIA=y
++CONFIG_CLK_STARFIVE_JH7110_AON=y
++CONFIG_CLK_STARFIVE_JH7110_STG=y
++CONFIG_CLK_STARFIVE_JH7110_ISP=y
++CONFIG_CLK_STARFIVE_JH7110_VOUT=y
++CONFIG_MAILBOX=y
++CONFIG_STARFIVE_MBOX=m
++CONFIG_STARFIVE_MBOX_TEST=m
++CONFIG_RPMSG_CHAR=y
++CONFIG_RPMSG_CTRL=y
++CONFIG_RPMSG_VIRTIO=y
++CONFIG_SIFIVE_CCACHE=y
++CONFIG_PWM=y
++CONFIG_PWM_OCORES=y
++CONFIG_PHY_STARFIVE_JH7110_PCIE=y
++CONFIG_PHY_STARFIVE_JH7110_USB=y
++CONFIG_PHY_M31_DPHY_RX0=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_AUTOFS_FS=y
++CONFIG_FUSE_FS=y
++CONFIG_OVERLAY_FS=y
++CONFIG_OVERLAY_FS_INDEX=y
++CONFIG_OVERLAY_FS_XINO_AUTO=y
++CONFIG_OVERLAY_FS_METACOPY=y
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++CONFIG_ZISOFS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_EXFAT_FS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_HUGETLBFS=y
++CONFIG_JFFS2_FS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V4=y
++CONFIG_NFS_V4_1=y
++CONFIG_NFS_V4_2=y
++CONFIG_ROOT_NFS=y
++CONFIG_9P_FS=y
++CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_ISO8859_1=m
++CONFIG_SECURITY=y
++CONFIG_SECURITY_SELINUX=y
++CONFIG_SECURITY_APPARMOR=y
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_LSM=""
++CONFIG_INIT_STACK_NONE=y
++CONFIG_CRYPTO_USER=y
++CONFIG_CRYPTO_ZSTD=y
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_USER_API_AEAD=y
++CONFIG_CRYPTO_STATS=y
++CONFIG_CRYPTO_DEV_VIRTIO=y
++CONFIG_CRYPTO_DEV_JH7110=y
++CONFIG_DMA_CMA=y
++CONFIG_PRINTK_TIME=y
++CONFIG_DEBUG_FS=y
++CONFIG_DEBUG_PAGEALLOC=y
++CONFIG_SCHED_STACK_END_CHECK=y
++CONFIG_DEBUG_VM=y
++CONFIG_DEBUG_VM_PGFLAGS=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_DEBUG_PER_CPU_MAPS=y
++CONFIG_SOFTLOCKUP_DETECTOR=y
++CONFIG_WQ_WATCHDOG=y
++CONFIG_DEBUG_TIMEKEEPING=y
++CONFIG_DEBUG_RT_MUTEXES=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_MUTEXES=y
++CONFIG_DEBUG_RWSEMS=y
++CONFIG_DEBUG_LIST=y
++CONFIG_DEBUG_PLIST=y
++CONFIG_DEBUG_SG=y
++CONFIG_RCU_CPU_STALL_TIMEOUT=60
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_EQS_DEBUG=y
++# CONFIG_FTRACE is not set
++# CONFIG_RUNTIME_TESTING_MENU is not set
++CONFIG_MEMTEST=y
diff --git a/target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch b/target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch
new file mode 100644
index 0000000000..68deb70c9b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch
@@ -0,0 +1,318 @@
+From 95c702022f5e4cb786719fcf90170334b1e562cc Mon Sep 17 00:00:00 2001
+From: Jianlong Huang <jianlong.huang@starfivetech.com>
+Date: Thu, 16 Jun 2022 17:13:57 +0800
+Subject: [PATCH 060/116] of: configfs: Add configfs function
+
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/of/Kconfig | 7 ++
+ drivers/of/Makefile | 1 +
+ drivers/of/configfs.c | 277 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 285 insertions(+)
+ create mode 100644 drivers/of/configfs.c
+
+--- a/drivers/of/Kconfig
++++ b/drivers/of/Kconfig
+@@ -102,4 +102,11 @@ config OF_OVERLAY
+ config OF_NUMA
+ bool
+
++config OF_CONFIGFS
++ bool "Device Tree Overlay ConfigFS interface"
++ select CONFIGFS_FS
++ select OF_OVERLAY
++ help
++ Enable a simple user-space driven DT overlay interface.
++
+ endif # OF
+--- a/drivers/of/Makefile
++++ b/drivers/of/Makefile
+@@ -11,6 +11,7 @@ obj-$(CONFIG_OF_UNITTEST) += unittest.o
+ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+ obj-$(CONFIG_OF_RESOLVE) += resolver.o
+ obj-$(CONFIG_OF_OVERLAY) += overlay.o
++obj-$(CONFIG_OF_CONFIGFS) += configfs.o
+ obj-$(CONFIG_OF_NUMA) += of_numa.o
+
+ ifdef CONFIG_KEXEC_FILE
+--- /dev/null
++++ b/drivers/of/configfs.c
+@@ -0,0 +1,277 @@
++/*
++ * Configfs entries for device-tree
++ *
++ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <linux/ctype.h>
++#include <linux/cpu.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_fdt.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/configfs.h>
++#include <linux/types.h>
++#include <linux/stat.h>
++#include <linux/limits.h>
++#include <linux/file.h>
++#include <linux/vmalloc.h>
++#include <linux/firmware.h>
++#include <linux/sizes.h>
++
++#include "of_private.h"
++
++struct cfs_overlay_item {
++ struct config_item item;
++
++ char path[PATH_MAX];
++
++ const struct firmware *fw;
++ struct device_node *overlay;
++ int ov_id;
++
++ void *dtbo;
++ int dtbo_size;
++};
++
++static inline struct cfs_overlay_item *to_cfs_overlay_item(
++ struct config_item *item)
++{
++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL;
++}
++
++static ssize_t cfs_overlay_item_path_show(struct config_item *item,
++ char *page)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++ return sprintf(page, "%s\n", overlay->path);
++}
++
++static ssize_t cfs_overlay_item_path_store(struct config_item *item,
++ const char *page, size_t count)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++ const char *p = page;
++ char *s;
++ int err;
++
++ /* if it's set do not allow changes */
++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
++ return -EPERM;
++
++ /* copy to path buffer (and make sure it's always zero terminated */
++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
++ overlay->path[sizeof(overlay->path) - 1] = '\0';
++
++ /* strip trailing newlines */
++ s = overlay->path + strlen(overlay->path);
++ while (s > overlay->path && *--s == '\n')
++ *s = '\0';
++
++ pr_debug("%s: path is '%s'\n", __func__, overlay->path);
++
++ err = request_firmware(&overlay->fw, overlay->path, NULL);
++ if (err != 0)
++ return err;
++
++ err = of_overlay_fdt_apply((void *)overlay->fw->data,
++ (u32)overlay->fw->size, &overlay->ov_id, NULL);
++ if (err != 0)
++ goto out_err;
++
++ return count;
++
++out_err:
++
++ release_firmware(overlay->fw);
++ overlay->fw = NULL;
++
++ overlay->path[0] = '\0';
++ return err;
++}
++
++static ssize_t cfs_overlay_item_status_show(struct config_item *item,
++ char *page)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ return sprintf(page, "%s\n",
++ overlay->ov_id > 0 ? "applied" : "unapplied");
++}
++
++CONFIGFS_ATTR(cfs_overlay_item_, path);
++CONFIGFS_ATTR_RO(cfs_overlay_item_, status);
++
++static struct configfs_attribute *cfs_overlay_attrs[] = {
++ &cfs_overlay_item_attr_path,
++ &cfs_overlay_item_attr_status,
++ NULL,
++};
++
++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
++ void *buf, size_t max_count)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ pr_debug("%s: buf=%p max_count=%zu\n", __func__,
++ buf, max_count);
++
++ if (overlay->dtbo == NULL)
++ return 0;
++
++ /* copy if buffer provided */
++ if (buf != NULL) {
++ /* the buffer must be large enough */
++ if (overlay->dtbo_size > max_count)
++ return -ENOSPC;
++
++ memcpy(buf, overlay->dtbo, overlay->dtbo_size);
++ }
++
++ return overlay->dtbo_size;
++}
++
++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
++ const void *buf, size_t count)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++ int err;
++
++ /* if it's set do not allow changes */
++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
++ return -EPERM;
++
++ /* copy the contents */
++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
++ if (overlay->dtbo == NULL)
++ return -ENOMEM;
++
++ overlay->dtbo_size = count;
++
++ err = of_overlay_fdt_apply(overlay->dtbo, overlay->dtbo_size,
++ &overlay->ov_id, NULL);
++ if (err != 0)
++ goto out_err;
++
++ return count;
++
++out_err:
++ kfree(overlay->dtbo);
++ overlay->dtbo = NULL;
++ overlay->dtbo_size = 0;
++ overlay->ov_id = 0;
++
++ return err;
++}
++
++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M);
++
++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = {
++ &cfs_overlay_item_attr_dtbo,
++ NULL,
++};
++
++static void cfs_overlay_release(struct config_item *item)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ if (overlay->ov_id > 0)
++ of_overlay_remove(&overlay->ov_id);
++ if (overlay->fw)
++ release_firmware(overlay->fw);
++ /* kfree with NULL is safe */
++ kfree(overlay->dtbo);
++ kfree(overlay);
++}
++
++static struct configfs_item_operations cfs_overlay_item_ops = {
++ .release = cfs_overlay_release,
++};
++
++static struct config_item_type cfs_overlay_type = {
++ .ct_item_ops = &cfs_overlay_item_ops,
++ .ct_attrs = cfs_overlay_attrs,
++ .ct_bin_attrs = cfs_overlay_bin_attrs,
++ .ct_owner = THIS_MODULE,
++};
++
++static struct config_item *cfs_overlay_group_make_item(
++ struct config_group *group, const char *name)
++{
++ struct cfs_overlay_item *overlay;
++
++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
++ if (!overlay)
++ return ERR_PTR(-ENOMEM);
++
++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type);
++ return &overlay->item;
++}
++
++static void cfs_overlay_group_drop_item(struct config_group *group,
++ struct config_item *item)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ config_item_put(&overlay->item);
++}
++
++static struct configfs_group_operations overlays_ops = {
++ .make_item = cfs_overlay_group_make_item,
++ .drop_item = cfs_overlay_group_drop_item,
++};
++
++static struct config_item_type overlays_type = {
++ .ct_group_ops = &overlays_ops,
++ .ct_owner = THIS_MODULE,
++};
++
++static struct configfs_group_operations of_cfs_ops = {
++ /* empty - we don't allow anything to be created */
++};
++
++static struct config_item_type of_cfs_type = {
++ .ct_group_ops = &of_cfs_ops,
++ .ct_owner = THIS_MODULE,
++};
++
++struct config_group of_cfs_overlay_group;
++
++static struct configfs_subsystem of_cfs_subsys = {
++ .su_group = {
++ .cg_item = {
++ .ci_namebuf = "device-tree",
++ .ci_type = &of_cfs_type,
++ },
++ },
++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex),
++};
++
++static int __init of_cfs_init(void)
++{
++ int ret;
++
++ pr_info("%s\n", __func__);
++
++ config_group_init(&of_cfs_subsys.su_group);
++ config_group_init_type_name(&of_cfs_overlay_group, "overlays",
++ &overlays_type);
++ configfs_add_default_group(&of_cfs_overlay_group,
++ &of_cfs_subsys.su_group);
++
++ ret = configfs_register_subsystem(&of_cfs_subsys);
++ if (ret != 0) {
++ pr_err("%s: failed to register subsys\n", __func__);
++ goto out;
++ }
++ pr_info("%s: OK\n", __func__);
++out:
++ return ret;
++}
++late_initcall(of_cfs_init);
diff --git a/target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch b/target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch
new file mode 100644
index 0000000000..ade0f467a0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch
@@ -0,0 +1,344 @@
+From 7891826f8c2de9ee0f6459cf969f7b082e29b154 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Thu, 1 Jun 2023 23:10:09 -0700
+Subject: [PATCH 061/116] usr: Add gen_initramfs_list.sh
+
+Add gen_initramfs_list.sh
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ usr/gen_initramfs_list.sh | 328 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 328 insertions(+)
+ create mode 100644 usr/gen_initramfs_list.sh
+
+--- /dev/null
++++ b/usr/gen_initramfs_list.sh
+@@ -0,0 +1,328 @@
++#!/bin/sh
++# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
++# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
++#
++# Released under the terms of the GNU GPL
++#
++# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
++# the cpio archive, and then compresses it.
++# The script may also be used to generate the inputfile used for gen_init_cpio
++# This script assumes that gen_init_cpio is located in usr/ directory
++
++# error out on errors
++set -e
++
++usage() {
++cat << EOF
++Usage:
++$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
++ -o <file> Create compressed initramfs file named <file> using
++ gen_init_cpio and compressor depending on the extension
++ -u <uid> User ID to map to user ID 0 (root).
++ <uid> is only meaningful if <cpio_source> is a
++ directory. "squash" forces all files to uid 0.
++ -g <gid> Group ID to map to group ID 0 (root).
++ <gid> is only meaningful if <cpio_source> is a
++ directory. "squash" forces all files to gid 0.
++ <cpio_source> File list or directory for cpio archive.
++ If <cpio_source> is a .cpio file it will be used
++ as direct input to initramfs.
++ -d Output the default cpio list.
++
++All options except -o and -l may be repeated and are interpreted
++sequentially and immediately. -u and -g states are preserved across
++<cpio_source> options so an explicit "-u 0 -g 0" is required
++to reset the root/group mapping.
++EOF
++}
++
++# awk style field access
++# $1 - field number; rest is argument string
++field() {
++ shift $1 ; echo $1
++}
++
++list_default_initramfs() {
++ # echo usr/kinit/kinit
++ :
++}
++
++default_initramfs() {
++ cat <<-EOF >> ${output}
++ # This is a very simple, default initramfs
++
++ dir /dev 0755 0 0
++ nod /dev/console 0600 0 0 c 5 1
++ dir /root 0700 0 0
++ # file /kinit usr/kinit/kinit 0755 0 0
++ # slink /init kinit 0755 0 0
++ EOF
++}
++
++filetype() {
++ local argv1="$1"
++
++ # symlink test must come before file test
++ if [ -L "${argv1}" ]; then
++ echo "slink"
++ elif [ -f "${argv1}" ]; then
++ echo "file"
++ elif [ -d "${argv1}" ]; then
++ echo "dir"
++ elif [ -b "${argv1}" -o -c "${argv1}" ]; then
++ echo "nod"
++ elif [ -p "${argv1}" ]; then
++ echo "pipe"
++ elif [ -S "${argv1}" ]; then
++ echo "sock"
++ else
++ echo "invalid"
++ fi
++ return 0
++}
++
++list_print_mtime() {
++ :
++}
++
++print_mtime() {
++ local my_mtime="0"
++
++ if [ -e "$1" ]; then
++ my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
++ fi
++
++ echo "# Last modified: ${my_mtime}" >> ${output}
++ echo "" >> ${output}
++}
++
++list_parse() {
++ if [ -L "$1" ]; then
++ return
++ fi
++ echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
++}
++
++# for each file print a line in following format
++# <filetype> <name> <path to file> <octal mode> <uid> <gid>
++# for links, devices etc the format differs. See gen_init_cpio for details
++parse() {
++ local location="$1"
++ local name="/${location#${srcdir}}"
++ # change '//' into '/'
++ name=$(echo "$name" | sed -e 's://*:/:g')
++ local mode="$2"
++ local uid="$3"
++ local gid="$4"
++ local ftype=$(filetype "${location}")
++ # remap uid/gid to 0 if necessary
++ [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
++ [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
++ local str="${mode} ${uid} ${gid}"
++
++ [ "${ftype}" = "invalid" ] && return 0
++ [ "${location}" = "${srcdir}" ] && return 0
++
++ case "${ftype}" in
++ "file")
++ str="${ftype} ${name} ${location} ${str}"
++ ;;
++ "nod")
++ local dev=`LC_ALL=C ls -l "${location}"`
++ local maj=`field 5 ${dev}`
++ local min=`field 6 ${dev}`
++ maj=${maj%,}
++
++ [ -b "${location}" ] && dev="b" || dev="c"
++
++ str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
++ ;;
++ "slink")
++ local target=`readlink "${location}"`
++ str="${ftype} ${name} ${target} ${str}"
++ ;;
++ *)
++ str="${ftype} ${name} ${str}"
++ ;;
++ esac
++
++ echo "${str}" >> ${output}
++
++ return 0
++}
++
++unknown_option() {
++ printf "ERROR: unknown option \"$arg\"\n" >&2
++ printf "If the filename validly begins with '-', " >&2
++ printf "then it must be prefixed\n" >&2
++ printf "by './' so that it won't be interpreted as an option." >&2
++ printf "\n" >&2
++ usage >&2
++ exit 1
++}
++
++list_header() {
++ :
++}
++
++header() {
++ printf "\n#####################\n# $1\n" >> ${output}
++}
++
++# process one directory (incl sub-directories)
++dir_filelist() {
++ ${dep_list}header "$1"
++
++ srcdir=$(echo "$1" | sed -e 's://*:/:g')
++ dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort)
++
++ # If $dirlist is only one line, then the directory is empty
++ if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
++ ${dep_list}print_mtime "$1"
++
++ echo "${dirlist}" | \
++ while read x; do
++ ${dep_list}parse ${x}
++ done
++ fi
++}
++
++# if only one file is specified and it is .cpio file then use it direct as fs
++# if a directory is specified then add all files in given direcotry to fs
++# if a regular file is specified assume it is in gen_initramfs format
++input_file() {
++ source="$1"
++ if [ -f "$1" ]; then
++ ${dep_list}header "$1"
++ is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')"
++ if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
++ cpio_file=$1
++ echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
++ [ ! -z ${dep_list} ] && echo "$1"
++ return 0
++ fi
++ if [ -z ${dep_list} ]; then
++ print_mtime "$1" >> ${output}
++ cat "$1" >> ${output}
++ else
++ echo "$1 \\"
++ cat "$1" | while read type dir file perm ; do
++ if [ "$type" = "file" ]; then
++ echo "$file \\";
++ fi
++ done
++ fi
++ elif [ -d "$1" ]; then
++ dir_filelist "$1"
++ else
++ echo " ${prog}: Cannot open '$1'" >&2
++ exit 1
++ fi
++}
++
++prog=$0
++root_uid=0
++root_gid=0
++dep_list=
++cpio_file=
++cpio_list=
++output="/dev/stdout"
++output_file=""
++is_cpio_compressed=
++compr="gzip -n -9 -f"
++
++arg="$1"
++case "$arg" in
++ "-l") # files included in initramfs - used by kbuild
++ dep_list="list_"
++ echo "deps_initramfs := $0 \\"
++ shift
++ ;;
++ "-o") # generate compressed cpio image named $1
++ shift
++ output_file="$1"
++ cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
++ output=${cpio_list}
++ echo "$output_file" | grep -q "\.gz$" \
++ && [ -x "`which gzip 2> /dev/null`" ] \
++ && compr="gzip -n -9 -f"
++ echo "$output_file" | grep -q "\.bz2$" \
++ && [ -x "`which bzip2 2> /dev/null`" ] \
++ && compr="bzip2 -9 -f"
++ echo "$output_file" | grep -q "\.lzma$" \
++ && [ -x "`which lzma 2> /dev/null`" ] \
++ && compr="lzma -9 -f"
++ echo "$output_file" | grep -q "\.xz$" \
++ && [ -x "`which xz 2> /dev/null`" ] \
++ && compr="xz --check=crc32 --lzma2=dict=1MiB"
++ echo "$output_file" | grep -q "\.lzo$" \
++ && [ -x "`which lzop 2> /dev/null`" ] \
++ && compr="lzop -9 -f"
++ echo "$output_file" | grep -q "\.lz4$" \
++ && [ -x "`which lz4 2> /dev/null`" ] \
++ && compr="lz4 -l -9 -f"
++ echo "$output_file" | grep -q "\.cpio$" && compr="cat"
++ shift
++ ;;
++esac
++while [ $# -gt 0 ]; do
++ arg="$1"
++ shift
++ case "$arg" in
++ "-u") # map $1 to uid=0 (root)
++ root_uid="$1"
++ [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
++ shift
++ ;;
++ "-g") # map $1 to gid=0 (root)
++ root_gid="$1"
++ [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
++ shift
++ ;;
++ "-d") # display default initramfs list
++ default_list="$arg"
++ ${dep_list}default_initramfs
++ ;;
++ "-h")
++ usage
++ exit 0
++ ;;
++ *)
++ case "$arg" in
++ "-"*)
++ unknown_option
++ ;;
++ *) # input file/dir - process it
++ input_file "$arg" "$#"
++ ;;
++ esac
++ ;;
++ esac
++done
++
++# If output_file is set we will generate cpio archive and compress it
++# we are careful to delete tmp files
++if [ ! -z ${output_file} ]; then
++ if [ -z ${cpio_file} ]; then
++ timestamp=
++ if test -n "$KBUILD_BUILD_TIMESTAMP"; then
++ timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
++ if test -n "$timestamp"; then
++ timestamp="-t $timestamp"
++ fi
++ fi
++ cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
++ usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
++ else
++ cpio_tfile=${cpio_file}
++ fi
++ rm ${cpio_list}
++ if [ "${is_cpio_compressed}" = "compressed" ]; then
++ cat ${cpio_tfile} > ${output_file}
++ else
++ (cat ${cpio_tfile} | ${compr} - > ${output_file}) \
++ || (rm -f ${output_file} ; false)
++ fi
++ [ -z ${cpio_file} ] && rm ${cpio_tfile}
++fi
++exit 0
diff --git a/target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch b/target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch
new file mode 100644
index 0000000000..05561f1c51
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch
@@ -0,0 +1,33 @@
+From dcc2827ed6e701a65731c05b0297745559837217 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 12 May 2023 17:33:20 +0800
+Subject: [PATCH 062/116] i2c: designware: Delete SMBus functionalities
+
+The driver didn't implement the smbus interface,
+so replace the SMBus functionalities with
+I2C_FUNC_SMBUS_EMUL.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/i2c/busses/i2c-designware-core.h | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-designware-core.h
++++ b/drivers/i2c/busses/i2c-designware-core.h
+@@ -18,12 +18,10 @@
+ #include <linux/regmap.h>
+ #include <linux/types.h>
+
+-#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
+- I2C_FUNC_SMBUS_BYTE | \
+- I2C_FUNC_SMBUS_BYTE_DATA | \
+- I2C_FUNC_SMBUS_WORD_DATA | \
+- I2C_FUNC_SMBUS_BLOCK_DATA | \
+- I2C_FUNC_SMBUS_I2C_BLOCK)
++#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL \
++ & ~I2C_FUNC_SMBUS_QUICK \
++ & ~I2C_FUNC_SMBUS_PROC_CALL \
++ & ~I2C_FUNC_SMBUS_PEC))
+
+ #define DW_IC_CON_MASTER BIT(0)
+ #define DW_IC_CON_SPEED_STD (1 << 1)
diff --git a/target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch b/target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch
new file mode 100644
index 0000000000..43a7e5ba0d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch
@@ -0,0 +1,26 @@
+From b61cefc6c785aa8a7177a0b535db746fd0047bd8 Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Fri, 19 Jan 2024 15:22:55 +0800
+Subject: [PATCH 063/116] drivers: mtd: gigadevice: add gd25lq256d 32M flash
+ support
+
+add gd25lq256d 32M flash support
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ drivers/mtd/spi-nor/gigadevice.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mtd/spi-nor/gigadevice.c
++++ b/drivers/mtd/spi-nor/gigadevice.c
+@@ -66,6 +66,10 @@ static const struct flash_info gigadevic
+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
+ SPI_NOR_QUAD_READ) },
++ { "gd25lq256d", INFO(0xc86019, 0, 64 * 1024, 512)
++ FLAGS( SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_QUAD_PP)
++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
++ SPI_NOR_QUAD_READ) },
+ { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512)
+ PARSE_SFDP
+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
diff --git a/target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch b/target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch
new file mode 100644
index 0000000000..b733110f7d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch
@@ -0,0 +1,808 @@
+From 76bc13aa12bd111f5da01e107f8d487b20b5a40c Mon Sep 17 00:00:00 2001
+From: "shanlong.li" <shanlong.li@starfivetech.com>
+Date: Thu, 8 Jun 2023 00:07:15 -0700
+Subject: [PATCH 064/116] driver: mailbox: Add mailbox driver
+
+Add mailbox driver.
+
+Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/mailbox/Kconfig | 13 +
+ drivers/mailbox/Makefile | 4 +
+ drivers/mailbox/starfive_mailbox-test.c | 407 ++++++++++++++++++++++++
+ drivers/mailbox/starfive_mailbox.c | 347 ++++++++++++++++++++
+ 4 files changed, 771 insertions(+)
+ create mode 100644 drivers/mailbox/starfive_mailbox-test.c
+ create mode 100644 drivers/mailbox/starfive_mailbox.c
+
+--- a/drivers/mailbox/Kconfig
++++ b/drivers/mailbox/Kconfig
+@@ -295,4 +295,17 @@ config QCOM_IPCC
+ acts as an interrupt controller for receiving interrupts from clients.
+ Say Y here if you want to build this driver.
+
++config STARFIVE_MBOX
++ tristate "Platform Starfive Mailbox"
++ depends on OF
++ help
++ Say Y here if you want to build a platform specific variant RISCV
++ controller driver.
++
++config STARFIVE_MBOX_TEST
++ tristate "Starfive Mailbox Test Client"
++ depends on OF
++ depends on HAS_IOMEM
++ help
++ Test client to help with testing new Controller driver implementations.
+ endif
+--- a/drivers/mailbox/Makefile
++++ b/drivers/mailbox/Makefile
+@@ -62,3 +62,7 @@ obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox
+ obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
+
+ obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o
++
++obj-$(CONFIG_STARFIVE_MBOX) += starfive_mailbox.o
++
++obj-$(CONFIG_STARFIVE_MBOX_TEST) += starfive_mailbox-test.o
+--- /dev/null
++++ b/drivers/mailbox/starfive_mailbox-test.c
+@@ -0,0 +1,407 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2015 ST Microelectronics
++ *
++ * Author: Lee Jones <lee.jones@linaro.org>
++ */
++
++#include <linux/debugfs.h>
++#include <linux/err.h>
++#include <linux/fs.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/mailbox_client.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/poll.h>
++#include <linux/slab.h>
++#include <linux/uaccess.h>
++#include <linux/sched/signal.h>
++
++#include <linux/mailbox_controller.h>
++
++#define MBOX_MAX_SIG_LEN 8
++#define MBOX_MAX_MSG_LEN 16
++#define MBOX_BYTES_PER_LINE 16
++#define MBOX_HEXDUMP_LINE_LEN ((MBOX_BYTES_PER_LINE * 4) + 2)
++#define MBOX_HEXDUMP_MAX_LEN (MBOX_HEXDUMP_LINE_LEN * (MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
++
++static bool mbox_data_ready;
++
++struct mbox_test_device {
++ struct device *dev;
++ void __iomem *tx_mmio;
++ void __iomem *rx_mmio;
++ struct mbox_chan *tx_channel;
++ struct mbox_chan *rx_channel;
++ char *rx_buffer;
++ char *signal;
++ char *message;
++ spinlock_t lock;
++ wait_queue_head_t waitq;
++ struct fasync_struct *async_queue;
++ struct dentry *root_debugfs_dir;
++};
++
++static ssize_t mbox_test_signal_write(struct file *filp,
++ const char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++
++ if (!tdev->tx_channel) {
++ dev_err(tdev->dev, "Channel cannot do Tx\n");
++ return -EINVAL;
++ }
++
++ if (count > MBOX_MAX_SIG_LEN) {
++ dev_err(tdev->dev,
++ "Signal length %zd greater than max allowed %d\n",
++ count, MBOX_MAX_SIG_LEN);
++ return -EINVAL;
++ }
++
++ /* Only allocate memory if we need to */
++ if (!tdev->signal) {
++ tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
++ if (!tdev->signal)
++ return -ENOMEM;
++ }
++
++ if (copy_from_user(tdev->signal, userbuf, count)) {
++ kfree(tdev->signal);
++ tdev->signal = NULL;
++ return -EFAULT;
++ }
++
++ return count;
++}
++
++static const struct file_operations mbox_test_signal_ops = {
++ .write = mbox_test_signal_write,
++ .open = simple_open,
++ .llseek = generic_file_llseek,
++};
++
++static int mbox_test_message_fasync(int fd, struct file *filp, int on)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++
++ return fasync_helper(fd, filp, on, &tdev->async_queue);
++}
++
++static ssize_t mbox_test_message_write(struct file *filp,
++ const char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++ void *data;
++ int ret;
++
++ if (!tdev->tx_channel) {
++ dev_err(tdev->dev, "Channel cannot do Tx\n");
++ return -EINVAL;
++ }
++
++ if (count > MBOX_MAX_MSG_LEN) {
++ dev_err(tdev->dev,
++ "Message length %zd greater than max allowed %d\n",
++ count, MBOX_MAX_MSG_LEN);
++ return -EINVAL;
++ }
++
++ tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
++ if (!tdev->message)
++ return -ENOMEM;
++
++ ret = copy_from_user(tdev->message, userbuf, count);
++ if (ret) {
++ ret = -EFAULT;
++ goto out;
++ }
++
++ if (tdev->tx_mmio && tdev->signal) {
++ print_hex_dump_bytes("Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
++ tdev->signal, MBOX_MAX_SIG_LEN);
++
++ data = tdev->signal;
++ } else
++ data = tdev->message;
++
++ print_hex_dump_bytes("Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
++ tdev->message, MBOX_MAX_MSG_LEN);
++
++ ret = mbox_send_message(tdev->tx_channel, data);
++ mbox_chan_txdone(tdev->tx_channel, ret);
++ if (ret < 0)
++ dev_err(tdev->dev, "Failed to send message via mailbox\n");
++
++out:
++ kfree(tdev->signal);
++ kfree(tdev->message);
++ tdev->signal = NULL;
++
++ return ret < 0 ? ret : count;
++}
++
++static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
++{
++ bool data_ready;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tdev->lock, flags);
++ data_ready = mbox_data_ready;
++ spin_unlock_irqrestore(&tdev->lock, flags);
++
++ return data_ready;
++}
++
++static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++ unsigned long flags;
++ char *touser, *ptr;
++ int ret;
++
++ touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
++ if (!touser)
++ return -ENOMEM;
++
++ if (!tdev->rx_channel) {
++ ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
++ ret = simple_read_from_buffer(userbuf, count, ppos,
++ touser, ret);
++ goto kfree_err;
++ }
++
++ do {
++ if (mbox_test_message_data_ready(tdev))
++ break;
++
++ if (filp->f_flags & O_NONBLOCK) {
++ ret = -EAGAIN;
++ goto waitq_err;
++ }
++
++ if (signal_pending(current)) {
++ ret = -ERESTARTSYS;
++ goto waitq_err;
++ }
++ schedule();
++
++ } while (1);
++
++ spin_lock_irqsave(&tdev->lock, flags);
++
++ ptr = tdev->rx_buffer;
++
++ mbox_data_ready = false;
++
++ spin_unlock_irqrestore(&tdev->lock, flags);
++ if (copy_to_user((void __user *)userbuf, ptr, 4))
++ ret = -EFAULT;
++
++waitq_err:
++ __set_current_state(TASK_RUNNING);
++kfree_err:
++ kfree(touser);
++ return ret;
++}
++
++static __poll_t
++mbox_test_message_poll(struct file *filp, struct poll_table_struct *wait)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++
++ poll_wait(filp, &tdev->waitq, wait);
++
++ if (mbox_test_message_data_ready(tdev))
++ return EPOLLIN | EPOLLRDNORM;
++ return 0;
++}
++
++static const struct file_operations mbox_test_message_ops = {
++ .write = mbox_test_message_write,
++ .read = mbox_test_message_read,
++ .fasync = mbox_test_message_fasync,
++ .poll = mbox_test_message_poll,
++ .open = simple_open,
++ .llseek = generic_file_llseek,
++};
++
++static int mbox_test_add_debugfs(struct platform_device *pdev,
++ struct mbox_test_device *tdev)
++{
++ if (!debugfs_initialized())
++ return 0;
++
++ tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
++ if (!tdev->root_debugfs_dir) {
++ dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
++ return -EINVAL;
++ }
++
++ debugfs_create_file("message", 0600, tdev->root_debugfs_dir,
++ tdev, &mbox_test_message_ops);
++
++ debugfs_create_file("signal", 0200, tdev->root_debugfs_dir,
++ tdev, &mbox_test_signal_ops);
++
++ return 0;
++}
++
++static void mbox_test_receive_message(struct mbox_client *client, void *message)
++{
++ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
++ unsigned long flags;
++
++ spin_lock_irqsave(&tdev->lock, flags);
++ if (tdev->rx_mmio) {
++ memcpy_fromio(tdev->rx_buffer, tdev->rx_mmio, MBOX_MAX_MSG_LEN);
++ print_hex_dump_bytes("Client: Received [MMIO]: ", DUMP_PREFIX_ADDRESS,
++ tdev->rx_buffer, MBOX_MAX_MSG_LEN);
++ } else if (message) {
++ print_hex_dump_bytes("Client: Received [API]: ", DUMP_PREFIX_ADDRESS,
++ message, MBOX_MAX_MSG_LEN);
++ memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
++ }
++ mbox_data_ready = true;
++ spin_unlock_irqrestore(&tdev->lock, flags);
++}
++
++static void mbox_test_prepare_message(struct mbox_client *client, void *message)
++{
++ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
++
++ if (tdev->tx_mmio) {
++ if (tdev->signal)
++ memcpy_toio(tdev->tx_mmio, tdev->message, MBOX_MAX_MSG_LEN);
++ else
++ memcpy_toio(tdev->tx_mmio, message, MBOX_MAX_MSG_LEN);
++ }
++}
++
++static struct mbox_chan *
++mbox_test_request_channel(struct platform_device *pdev, const char *name)
++{
++ struct mbox_client *client;
++ struct mbox_chan *channel;
++
++ client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
++ if (!client)
++ return ERR_PTR(-ENOMEM);
++
++ client->dev = &pdev->dev;
++ client->rx_callback = mbox_test_receive_message;
++ client->tx_prepare = mbox_test_prepare_message;
++ client->tx_block = false;
++ client->knows_txdone = false;
++ client->tx_tout = 500;
++
++ channel = mbox_request_channel_byname(client, name);
++ if (IS_ERR(channel)) {
++ dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
++ return NULL;
++ }
++
++ return channel;
++}
++
++static int mbox_test_probe(struct platform_device *pdev)
++{
++ struct mbox_test_device *tdev;
++ struct resource *res;
++ resource_size_t size;
++ int ret;
++
++ tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
++ if (!tdev)
++ return -ENOMEM;
++
++ /* It's okay for MMIO to be NULL */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res);
++ if (PTR_ERR(tdev->tx_mmio) == -EBUSY) {
++ /* if reserved area in SRAM, try just ioremap */
++ size = resource_size(res);
++ tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size);
++ } else if (IS_ERR(tdev->tx_mmio)) {
++ tdev->tx_mmio = NULL;
++ }
++
++ /* If specified, second reg entry is Rx MMIO */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res);
++ if (PTR_ERR(tdev->rx_mmio) == -EBUSY) {
++ size = resource_size(res);
++ tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size);
++ } else if (IS_ERR(tdev->rx_mmio)) {
++ tdev->rx_mmio = tdev->tx_mmio;
++ }
++
++ tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
++ tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
++
++ if (!tdev->tx_channel && !tdev->rx_channel)
++ return -EPROBE_DEFER;
++
++ /* If Rx is not specified but has Rx MMIO, then Rx = Tx */
++ if (!tdev->rx_channel && (tdev->rx_mmio != tdev->tx_mmio))
++ tdev->rx_channel = tdev->tx_channel;
++
++ tdev->dev = &pdev->dev;
++ platform_set_drvdata(pdev, tdev);
++
++ spin_lock_init(&tdev->lock);
++
++ if (tdev->rx_channel) {
++ tdev->rx_buffer = devm_kzalloc(&pdev->dev,
++ MBOX_MAX_MSG_LEN, GFP_KERNEL);
++ if (!tdev->rx_buffer)
++ return -ENOMEM;
++ }
++
++ ret = mbox_test_add_debugfs(pdev, tdev);
++ if (ret)
++ return ret;
++
++ dev_info(&pdev->dev, "Successfully registered\n");
++
++ return 0;
++}
++
++static int mbox_test_remove(struct platform_device *pdev)
++{
++ struct mbox_test_device *tdev = platform_get_drvdata(pdev);
++
++ debugfs_remove_recursive(tdev->root_debugfs_dir);
++
++ if (tdev->tx_channel)
++ mbox_free_channel(tdev->tx_channel);
++ if (tdev->rx_channel)
++ mbox_free_channel(tdev->rx_channel);
++
++ return 0;
++}
++
++static const struct of_device_id mbox_test_match[] = {
++ { .compatible = "starfive,mailbox-test" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, mbox_test_match);
++
++static struct platform_driver mbox_test_driver = {
++ .driver = {
++ .name = "mailbox_test",
++ .of_match_table = mbox_test_match,
++ },
++ .probe = mbox_test_probe,
++ .remove = mbox_test_remove,
++};
++module_platform_driver(mbox_test_driver);
++
++MODULE_DESCRIPTION("Generic Mailbox Testing Facility");
++MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/mailbox/starfive_mailbox.c
+@@ -0,0 +1,347 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * mailbox driver for StarFive JH7110 SoC
++ *
++ * Copyright (c) 2021 StarFive Technology Co., Ltd.
++ * Author: Shanlong Li <shanlong.li@starfivetech.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/mailbox_controller.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/pm_runtime.h>
++
++#include "mailbox.h"
++
++#define MBOX_CHAN_MAX 4
++
++#define MBOX_BASE(mbox, ch) ((mbox)->base + ((ch) * 0x10))
++#define MBOX_IRQ_REG 0x00
++#define MBOX_SET_REG 0x04
++#define MBOX_CLR_REG 0x08
++#define MBOX_CMD_REG 0x0c
++#define MBC_PEND_SMRY 0x100
++
++typedef enum {
++ MAILBOX_CORE_U7 = 0,
++ MAILBOX_CORE_HIFI4,
++ MAILBOX_CORE_E2,
++ MAILBOX_CORE_RSVD0,
++ MAILBOX_CORE_NUM,
++} mailbox_core_t;
++
++struct mailbox_irq_name_c{
++ int id;
++ char name[16];
++};
++
++static const struct mailbox_irq_name_c irq_peer_name[MBOX_CHAN_MAX] = {
++ {MAILBOX_CORE_U7, "u74_core"},
++ {MAILBOX_CORE_HIFI4, "hifi4_core"},
++ {MAILBOX_CORE_E2, "e24_core"},
++ {MAILBOX_CORE_RSVD0, "" },
++};
++
++/**
++ * starfive mailbox channel information
++ *
++ * A channel can be used for TX or RX, it can trigger remote
++ * processor interrupt to notify remote processor and can receive
++ * interrupt if has incoming message.
++ *
++ * @dst_irq: Interrupt vector for remote processor
++ * @core_id: id for remote processor
++ */
++struct starfive_chan_info {
++ unsigned int dst_irq;
++ mailbox_core_t core_id;
++};
++
++/**
++ * starfive mailbox controller data
++ *
++ * Mailbox controller includes 4 channels and can allocate
++ * channel for message transferring.
++ *
++ * @dev: Device to which it is attached
++ * @base: Base address of the register mapping region
++ * @chan: Representation of channels in mailbox controller
++ * @mchan: Representation of channel info
++ * @controller: Representation of a communication channel controller
++ */
++struct starfive_mbox {
++ struct device *dev;
++ void __iomem *base;
++ struct mbox_chan chan[MBOX_CHAN_MAX];
++ struct starfive_chan_info mchan[MBOX_CHAN_MAX];
++ struct mbox_controller controller;
++ struct clk *clk;
++ struct reset_control *rst_rresetn;
++};
++
++static struct starfive_mbox *to_starfive_mbox(struct mbox_controller *mbox)
++{
++ return container_of(mbox, struct starfive_mbox, controller);
++}
++
++static struct mbox_chan *
++starfive_of_mbox_index_xlate(struct mbox_controller *mbox,
++ const struct of_phandle_args *sp)
++{
++ struct starfive_mbox *sbox;
++
++ int ind = sp->args[0];
++ int core_id = sp->args[1];
++
++ if (ind >= mbox->num_chans || core_id >= MAILBOX_CORE_NUM)
++ return ERR_PTR(-EINVAL);
++
++ sbox = to_starfive_mbox(mbox);
++
++ sbox->mchan[ind].core_id = core_id;
++
++ return &mbox->chans[ind];
++}
++
++static irqreturn_t starfive_rx_irq_handler(int irq, void *p)
++{
++ struct mbox_chan *chan = p;
++ unsigned long ch = (unsigned long)chan->con_priv;
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ void __iomem *base = MBOX_BASE(mbox, ch);
++ u32 val;
++
++ val = readl(base + MBOX_CMD_REG);
++ if (!val)
++ return IRQ_NONE;
++
++ mbox_chan_received_data(chan, (void *)&val);
++ writel(val, base + MBOX_CLR_REG);
++ return IRQ_HANDLED;
++}
++
++static int starfive_mbox_check_state(struct mbox_chan *chan)
++{
++ unsigned long ch = (unsigned long)chan->con_priv;
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ unsigned long irq_flag = IRQF_SHARED;
++ long ret = 0;
++
++ pm_runtime_get_sync(mbox->dev);
++ /* MAILBOX should be with IRQF_NO_SUSPEND set */
++ if (!mbox->dev->pm_domain)
++ irq_flag |= IRQF_NO_SUSPEND;
++
++ /* Mailbox is idle so directly bail out */
++ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch))
++ return -EBUSY;
++
++ if (mbox->mchan[ch].dst_irq > 0) {
++ dev_dbg(mbox->dev, "%s: host IRQ = %d, ch:%ld", __func__, mbox->mchan[ch].dst_irq, ch);
++ ret = devm_request_irq(mbox->dev, mbox->mchan[ch].dst_irq, starfive_rx_irq_handler,
++ irq_flag, irq_peer_name[ch].name, chan);
++ if (ret < 0)
++ dev_err(mbox->dev, "request_irq %d failed\n", mbox->mchan[ch].dst_irq);
++ }
++
++ return ret;
++}
++
++static int starfive_mbox_startup(struct mbox_chan *chan)
++{
++ return starfive_mbox_check_state(chan);
++}
++
++static void starfive_mbox_shutdown(struct mbox_chan *chan)
++{
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ unsigned long ch = (unsigned long)chan->con_priv;
++ void __iomem *base = MBOX_BASE(mbox, ch);
++
++ writel(0x0, base + MBOX_IRQ_REG);
++ writel(0x0, base + MBOX_CLR_REG);
++
++ if (mbox->mchan[ch].dst_irq > 0)
++ devm_free_irq(mbox->dev, mbox->mchan[ch].dst_irq, chan);
++ pm_runtime_put_sync(mbox->dev);
++}
++
++static int starfive_mbox_send_data(struct mbox_chan *chan, void *msg)
++{
++ unsigned long ch = (unsigned long)chan->con_priv;
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ struct starfive_chan_info *mchan = &mbox->mchan[ch];
++ void __iomem *base = MBOX_BASE(mbox, ch);
++ u32 *buf = msg;
++
++ /* Ensure channel is released */
++ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch)) {
++ pr_debug("%s:%d. busy\n", __func__, __LINE__);
++ return -EBUSY;
++ }
++
++ /* Clear mask for destination interrupt */
++ writel(BIT(mchan->core_id), base + MBOX_IRQ_REG);
++
++ /* Fill message data */
++ writel(*buf, base + MBOX_SET_REG);
++ return 0;
++}
++
++static struct mbox_chan_ops starfive_mbox_ops = {
++ .startup = starfive_mbox_startup,
++ .send_data = starfive_mbox_send_data,
++ .shutdown = starfive_mbox_shutdown,
++};
++
++static const struct of_device_id starfive_mbox_of_match[] = {
++ { .compatible = "starfive,mail_box",},
++ {},
++};
++
++MODULE_DEVICE_TABLE(of, starfive_mbox_of_match);
++
++void starfive_mailbox_init(struct starfive_mbox *mbox)
++{
++ mbox->clk = devm_clk_get_optional(mbox->dev, "clk_apb");
++ if (IS_ERR(mbox->clk)) {
++ dev_err(mbox->dev, "failed to get mailbox\n");
++ return;
++ }
++
++ mbox->rst_rresetn = devm_reset_control_get_exclusive(mbox->dev, "mbx_rre");
++ if (IS_ERR(mbox->rst_rresetn)) {
++ dev_err(mbox->dev, "failed to get mailbox reset\n");
++ return;
++ }
++
++ clk_prepare_enable(mbox->clk);
++ reset_control_deassert(mbox->rst_rresetn);
++}
++
++static int starfive_mbox_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct starfive_mbox *mbox;
++ struct mbox_chan *chan;
++ struct resource *res;
++ unsigned long ch;
++ int err;
++
++ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
++ if (!mbox)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ mbox->base = devm_ioremap_resource(dev, res);
++ mbox->dev = dev;
++
++ if (IS_ERR(mbox->base))
++ return PTR_ERR(mbox->base);
++
++ starfive_mailbox_init(mbox);
++
++ mbox->controller.dev = dev;
++ mbox->controller.chans = mbox->chan;
++ mbox->controller.num_chans = MBOX_CHAN_MAX;
++ mbox->controller.ops = &starfive_mbox_ops;
++ mbox->controller.of_xlate = starfive_of_mbox_index_xlate;
++ mbox->controller.txdone_irq = true;
++ mbox->controller.txdone_poll = false;
++
++ /* Initialize mailbox channel data */
++ chan = mbox->chan;
++ for (ch = 0; ch < MBOX_CHAN_MAX; ch++) {
++ mbox->mchan[ch].dst_irq = 0;
++ mbox->mchan[ch].core_id = (mailbox_core_t)ch;
++ chan[ch].con_priv = (void *)ch;
++ }
++ mbox->mchan[MAILBOX_CORE_HIFI4].dst_irq = platform_get_irq(pdev, 0);
++ mbox->mchan[MAILBOX_CORE_E2].dst_irq = platform_get_irq(pdev, 1);
++
++ err = mbox_controller_register(&mbox->controller);
++ if (err) {
++ dev_err(dev, "Failed to register mailbox %d\n", err);
++ return err;
++ }
++
++ platform_set_drvdata(pdev, mbox);
++ dev_info(dev, "Mailbox enabled\n");
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
++ return 0;
++}
++
++static int starfive_mbox_remove(struct platform_device *pdev)
++{
++ struct starfive_mbox *mbox = platform_get_drvdata(pdev);
++
++ mbox_controller_unregister(&mbox->controller);
++ devm_clk_put(mbox->dev, mbox->clk);
++ pm_runtime_disable(mbox->dev);
++
++ return 0;
++}
++
++static int __maybe_unused starfive_mbox_suspend(struct device *dev)
++{
++ struct starfive_mbox *mbox = dev_get_drvdata(dev);
++
++ clk_disable_unprepare(mbox->clk);
++
++ return 0;
++}
++
++static int __maybe_unused starfive_mbox_resume(struct device *dev)
++{
++ struct starfive_mbox *mbox = dev_get_drvdata(dev);
++ int ret;
++
++ ret = clk_prepare_enable(mbox->clk);
++ if (ret)
++ dev_err(dev, "failed to enable clock\n");
++
++ return ret;
++}
++
++static const struct dev_pm_ops starfive_mbox_pm_ops = {
++ .suspend = starfive_mbox_suspend,
++ .resume = starfive_mbox_resume,
++ SET_RUNTIME_PM_OPS(starfive_mbox_suspend, starfive_mbox_resume, NULL)
++};
++static struct platform_driver starfive_mbox_driver = {
++ .probe = starfive_mbox_probe,
++ .remove = starfive_mbox_remove,
++ .driver = {
++ .name = "mailbox",
++ .of_match_table = starfive_mbox_of_match,
++ .pm = &starfive_mbox_pm_ops,
++ },
++};
++
++static int __init starfive_mbox_init(void)
++{
++ return platform_driver_register(&starfive_mbox_driver);
++}
++core_initcall(starfive_mbox_init);
++
++static void __exit starfive_mbox_exit(void)
++{
++ platform_driver_unregister(&starfive_mbox_driver);
++}
++module_exit(starfive_mbox_exit);
++
++MODULE_DESCRIPTION("StarFive Mailbox Controller driver");
++MODULE_AUTHOR("Shanlong Li <shanlong.li@starfivetech.com>");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch b/target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch
new file mode 100644
index 0000000000..0257cb004b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch
@@ -0,0 +1,789 @@
+From 0f44bd6bec708782f38bba4d03deecf927d1c83d Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfivetech.com>
+Date: Fri, 9 Jun 2023 15:31:53 +0800
+Subject: [PATCH 065/116] driver: rtc: Add StarFive JH7110 rtc driver
+
+Add RTC driver and support for StarFive JH7110 SoC.
+
+Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/rtc/Kconfig | 8 +
+ drivers/rtc/Makefile | 1 +
+ drivers/rtc/rtc-starfive.c | 743 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 752 insertions(+)
+ create mode 100644 drivers/rtc/rtc-starfive.c
+
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -1327,6 +1327,14 @@ config RTC_DRV_NTXEC
+ embedded controller found in certain e-book readers designed by the
+ original design manufacturer Netronix.
+
++config RTC_DRV_STARFIVE
++ tristate "StarFive 32.768k-RTC"
++ depends on ARCH_STARFIVE
++ depends on OF
++ help
++ If you say Y here you will get support for the RTC found on
++ StarFive SOCS.
++
+ comment "on-CPU RTC drivers"
+
+ config RTC_DRV_ASM9260
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -163,6 +163,7 @@ obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
+ obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
+ obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
+ obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
++obj-$(CONFIG_RTC_DRV_STARFIVE) += rtc-starfive.o
+ obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
+ obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
+ obj-$(CONFIG_RTC_DRV_STM32) += rtc-stm32.o
+--- /dev/null
++++ b/drivers/rtc/rtc-starfive.c
+@@ -0,0 +1,743 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * RTC driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2021 StarFive Technology Co., Ltd.
++ */
++
++#include <asm/delay.h>
++#include <linux/bcd.h>
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/completion.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/iopoll.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++
++/* Registers */
++#define SFT_RTC_CFG 0x00
++#define SFT_RTC_SW_CAL_VALUE 0x04
++#define SFT_RTC_HW_CAL_CFG 0x08
++#define SFT_RTC_CMP_CFG 0x0C
++#define SFT_RTC_IRQ_EN 0x10
++#define SFT_RTC_IRQ_EVEVT 0x14
++#define SFT_RTC_IRQ_STATUS 0x18
++#define SFT_RTC_CAL_VALUE 0x24
++#define SFT_RTC_CFG_TIME 0x28
++#define SFT_RTC_CFG_DATE 0x2C
++#define SFT_RTC_ACT_TIME 0x34
++#define SFT_RTC_ACT_DATE 0x38
++#define SFT_RTC_TIME 0x3C
++#define SFT_RTC_DATE 0x40
++#define SFT_RTC_TIME_LATCH 0x44
++#define SFT_RTC_DATE_LATCH 0x48
++
++/* RTC_CFG */
++#define RTC_CFG_ENABLE_SHIFT 0 /* RW: RTC Enable. */
++#define RTC_CFG_CAL_EN_HW_SHIFT 1 /* RW: Enable of hardware calibretion. */
++#define RTC_CFG_CAL_SEL_SHIFT 2 /* RW: select the hw/sw calibretion mode.*/
++#define RTC_CFG_HOUR_MODE_SHIFT 3 /* RW: time hour mode. 24h|12h */
++
++/* RTC_SW_CAL_VALUE */
++#define RTC_SW_CAL_VALUE_MASK GENMASK(15, 0)
++#define RTC_SW_CAL_MAX RTC_SW_CAL_VALUE_MASK
++#define RTC_SW_CAL_MIN 0
++#define RTC_TICKS_PER_SEC 32768 /* Number of ticks per second */
++#define RTC_PPB_MULT 1000000000LL /* Multiplier for ppb conversions */
++
++/* RTC_HW_CAL_CFG */
++#define RTC_HW_CAL_REF_SEL_SHIFT 0
++#define RTC_HW_CAL_FRQ_SEL_SHIFT 1
++
++/* IRQ_EN/IRQ_EVEVT/IRQ_STATUS */
++#define RTC_IRQ_CAL_START BIT(0)
++#define RTC_IRQ_CAL_FINISH BIT(1)
++#define RTC_IRQ_CMP BIT(2)
++#define RTC_IRQ_1SEC BIT(3)
++#define RTC_IRQ_ALAEM BIT(4)
++#define RTC_IRQ_EVT_UPDATE_PSE BIT(31) /* WO: Enable of update time&&date, IRQ_EVEVT only */
++#define RTC_IRQ_ALL (RTC_IRQ_CAL_START \
++ | RTC_IRQ_CAL_FINISH \
++ | RTC_IRQ_CMP \
++ | RTC_IRQ_1SEC \
++ | RTC_IRQ_ALAEM)
++
++/* CAL_VALUE */
++#define RTC_CAL_VALUE_MASK GENMASK(15, 0)
++
++/* CFG_TIME/ACT_TIME/RTC_TIME */
++#define TIME_SEC_MASK GENMASK(6, 0)
++#define TIME_MIN_MASK GENMASK(13, 7)
++#define TIME_HOUR_MASK GENMASK(20, 14)
++
++/* CFG_DATE/ACT_DATE/RTC_DATE */
++#define DATE_DAY_MASK GENMASK(5, 0)
++#define DATE_MON_MASK GENMASK(10, 6)
++#define DATE_YEAR_MASK GENMASK(18, 11)
++
++#define INT_TIMEOUT_US 180
++
++enum RTC_HOUR_MODE {
++ RTC_HOUR_MODE_12H = 0,
++ RTC_HOUR_MODE_24H = 1
++};
++
++enum RTC_CAL_MODE {
++ RTC_CAL_MODE_SW = 0,
++ RTC_CAL_MODE_HW = 1
++};
++
++enum RTC_HW_CAL_REF_MODE {
++ RTC_CAL_CLK_REF = 0,
++ RTC_CAL_CLK_MARK = 1
++};
++
++static const unsigned long refclk_list[] = {
++ 1000000,
++ 2000000,
++ 4000000,
++ 5927000,
++ 6000000,
++ 7200000,
++ 8000000,
++ 10250000,
++ 11059200,
++ 12000000,
++ 12288000,
++ 13560000,
++ 16000000,
++ 19200000,
++ 20000000,
++ 22118000,
++ 24000000,
++ 24567000,
++ 25000000,
++ 26000000,
++ 27000000,
++ 30000000,
++ 32000000,
++ 33868800,
++ 36000000,
++ 36860000,
++ 40000000,
++ 44000000,
++ 50000000,
++ 54000000,
++ 28224000,
++ 28000000,
++};
++
++struct sft_rtc {
++ struct rtc_device *rtc_dev;
++ struct completion cal_done;
++ struct completion onesec_done;
++ struct clk *pclk;
++ struct clk *cal_clk;
++ struct reset_control *rst_array;
++ int hw_cal_map;
++ void __iomem *regs;
++ int rtc_irq;
++ int ms_pulse_irq;
++ int one_sec_pulse_irq;
++};
++
++static inline void sft_rtc_set_enabled(struct sft_rtc *srtc, bool enabled)
++{
++ u32 val;
++
++ if (enabled) {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= BIT(RTC_CFG_ENABLE_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ } else {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val &= ~BIT(RTC_CFG_ENABLE_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ }
++}
++
++static inline bool sft_rtc_get_enabled(struct sft_rtc *srtc)
++{
++ return !!(readl(srtc->regs + SFT_RTC_CFG) & BIT(RTC_CFG_ENABLE_SHIFT));
++}
++
++static inline void sft_rtc_set_mode(struct sft_rtc *srtc, enum RTC_HOUR_MODE mode)
++{
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= mode << RTC_CFG_HOUR_MODE_SHIFT;
++ writel(val, srtc->regs + SFT_RTC_CFG);
++}
++
++static inline int sft_rtc_irq_enable(struct sft_rtc *srtc, u32 irq, bool enable)
++{
++ u32 val;
++
++ if (!(irq & RTC_IRQ_ALL))
++ return -EINVAL;
++
++ if (enable) {
++ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
++ val |= irq;
++ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
++ } else {
++ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
++ val &= ~irq;
++ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
++ }
++ return 0;
++}
++
++static inline void
++sft_rtc_set_cal_hw_enable(struct sft_rtc *srtc, bool enable)
++{
++ u32 val;
++
++ if (enable) {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= BIT(RTC_CFG_CAL_EN_HW_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ } else {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val &= ~BIT(RTC_CFG_CAL_EN_HW_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ }
++}
++
++static inline void
++sft_rtc_set_cal_mode(struct sft_rtc *srtc, enum RTC_CAL_MODE mode)
++{
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= mode << RTC_CFG_CAL_SEL_SHIFT;
++ writel(val, srtc->regs + SFT_RTC_CFG);
++}
++
++static int sft_rtc_get_hw_calclk(struct device *dev, unsigned long freq)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(refclk_list); i++)
++ if (refclk_list[i] == freq)
++ return i;
++
++ dev_err(dev, "refclk: %ldHz do not support.\n", freq);
++ return -EINVAL;
++}
++
++static inline void sft_rtc_reg2time(struct rtc_time *tm, u32 reg)
++{
++ tm->tm_hour = bcd2bin(FIELD_GET(TIME_HOUR_MASK, reg));
++ tm->tm_min = bcd2bin(FIELD_GET(TIME_MIN_MASK, reg));
++ tm->tm_sec = bcd2bin(FIELD_GET(TIME_SEC_MASK, reg));
++}
++
++static inline void sft_rtc_reg2date(struct rtc_time *tm, u32 reg)
++{
++ tm->tm_year = bcd2bin(FIELD_GET(DATE_YEAR_MASK, reg)) + 100;
++ tm->tm_mon = bcd2bin(FIELD_GET(DATE_MON_MASK, reg)) - 1;
++ tm->tm_mday = bcd2bin(FIELD_GET(DATE_DAY_MASK, reg));
++}
++
++static inline u32 sft_rtc_time2reg(struct rtc_time *tm)
++{
++ return FIELD_PREP(TIME_HOUR_MASK, bin2bcd(tm->tm_hour)) |
++ FIELD_PREP(TIME_MIN_MASK, bin2bcd(tm->tm_min)) |
++ FIELD_PREP(TIME_SEC_MASK, bin2bcd(tm->tm_sec));
++}
++
++static inline u32 sft_rtc_date2reg(struct rtc_time *tm)
++{
++ return FIELD_PREP(DATE_YEAR_MASK, bin2bcd(tm->tm_year - 100)) |
++ FIELD_PREP(DATE_MON_MASK, bin2bcd(tm->tm_mon + 1)) |
++ FIELD_PREP(DATE_DAY_MASK, bin2bcd(tm->tm_mday));
++}
++
++static inline void sft_rtc_update_pulse(struct sft_rtc *srtc)
++{
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
++ val |= RTC_IRQ_EVT_UPDATE_PSE;
++ writel(val, srtc->regs + SFT_RTC_IRQ_EVEVT);
++}
++
++static irqreturn_t sft_rtc_irq_handler(int irq, void *data)
++{
++ struct sft_rtc *srtc = data;
++ struct timerqueue_node *next;
++ u32 irq_flags = 0;
++ u32 irq_mask = 0;
++ u32 val;
++ int ret = 0;
++
++ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
++ if (val & RTC_IRQ_CAL_START)
++ irq_mask |= RTC_IRQ_CAL_START;
++
++ if (val & RTC_IRQ_CAL_FINISH) {
++ irq_mask |= RTC_IRQ_CAL_FINISH;
++ complete(&srtc->cal_done);
++ }
++
++ if (val & RTC_IRQ_CMP)
++ irq_mask |= RTC_IRQ_CMP;
++
++ if (val & RTC_IRQ_1SEC) {
++ irq_flags |= RTC_PF;
++ irq_mask |= RTC_IRQ_1SEC;
++ complete(&srtc->onesec_done);
++ }
++
++ if (val & RTC_IRQ_ALAEM) {
++ irq_flags |= RTC_AF;
++ irq_mask |= RTC_IRQ_ALAEM;
++
++ next = timerqueue_getnext(&srtc->rtc_dev->timerqueue);
++ if (next == &srtc->rtc_dev->aie_timer.node)
++ dev_info(&srtc->rtc_dev->dev, "alarm expires");
++ }
++
++ writel(irq_mask, srtc->regs + SFT_RTC_IRQ_EVEVT);
++
++ /* Wait interrupt flag clear */
++ ret = readl_poll_timeout_atomic(srtc->regs + SFT_RTC_IRQ_EVEVT, val,
++ (val & irq_mask) == 0, 0, INT_TIMEOUT_US);
++ if (ret)
++ dev_warn(&srtc->rtc_dev->dev, "fail to clear rtc interrupt flag\n");
++
++ if (irq_flags)
++ rtc_update_irq(srtc->rtc_dev, 1, irq_flags | RTC_IRQF);
++
++ return IRQ_HANDLED;
++}
++
++static int sft_rtc_read_time(struct device *dev, struct rtc_time *tm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++ int irq_1sec_state_start, irq_1sec_state_end;
++
++ /* If the RTC is disabled, assume the values are invalid */
++ if (!sft_rtc_get_enabled(srtc))
++ return -EINVAL;
++
++ irq_1sec_state_start =
++ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
++
++read_again:
++ val = readl(srtc->regs + SFT_RTC_TIME);
++ sft_rtc_reg2time(tm, val);
++
++ val = readl(srtc->regs + SFT_RTC_DATE);
++ sft_rtc_reg2date(tm, val);
++
++ if (irq_1sec_state_start == 0) {
++ irq_1sec_state_end =
++ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
++ if (irq_1sec_state_end == 1) {
++ irq_1sec_state_start = 1;
++ goto read_again;
++ }
++ }
++
++ return 0;
++}
++
++static int sft_rtc_set_time(struct device *dev, struct rtc_time *tm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++ int ret;
++
++ val = sft_rtc_time2reg(tm);
++ writel(val, srtc->regs + SFT_RTC_CFG_TIME);
++
++ val = sft_rtc_date2reg(tm);
++ writel(val, srtc->regs + SFT_RTC_CFG_DATE);
++
++ /* Update pulse */
++ sft_rtc_update_pulse(srtc);
++
++ /* Ensure that data is fully written */
++ ret = wait_for_completion_interruptible_timeout(&srtc->onesec_done,
++ usecs_to_jiffies(120));
++ if (ret) {
++ dev_warn(dev,
++ "rtc wait for completion interruptible timeout.\n");
++ }
++ return 0;
++}
++
++static int sft_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++
++ return sft_rtc_irq_enable(srtc, RTC_IRQ_ALAEM, enabled);
++}
++
++static int sft_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_ACT_TIME);
++ sft_rtc_reg2time(&alarm->time, val);
++
++ val = readl(srtc->regs + SFT_RTC_ACT_DATE);
++ sft_rtc_reg2date(&alarm->time, val);
++
++ return 0;
++}
++
++static int sft_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++
++ sft_rtc_alarm_irq_enable(dev, 0);
++
++ val = sft_rtc_time2reg(&alarm->time);
++ writel(val, srtc->regs + SFT_RTC_ACT_TIME);
++
++ val = sft_rtc_date2reg(&alarm->time);
++ writel(val, srtc->regs + SFT_RTC_ACT_DATE);
++
++ sft_rtc_alarm_irq_enable(dev, alarm->enabled);
++
++ return 0;
++}
++
++static int sft_rtc_get_offset(struct device *dev, long *offset)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ s64 tmp;
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_CAL_VALUE)
++ & RTC_SW_CAL_VALUE_MASK;
++ val += 1;
++ /*
++ * the adjust val range is [0x0000-0xffff],
++ * the default val is 0x7fff (32768-1),mapping offset=0 ;
++ */
++ tmp = (s64)val - RTC_TICKS_PER_SEC;
++ tmp *= RTC_PPB_MULT;
++ tmp = div_s64(tmp, RTC_TICKS_PER_SEC);
++
++ /* Offset value operates in negative way, so swap sign */
++ *offset = -tmp;
++
++ return 0;
++}
++
++static int sft_rtc_set_offset(struct device *dev, long offset)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ s64 tmp;
++ u32 val;
++
++ tmp = offset * RTC_TICKS_PER_SEC;
++ tmp = div_s64(tmp, RTC_PPB_MULT);
++
++ tmp = RTC_TICKS_PER_SEC - tmp;
++ tmp -= 1;
++ if (tmp > RTC_SW_CAL_MAX || tmp < RTC_SW_CAL_MIN) {
++ dev_err(dev, "offset is out of range.\n");
++ return -EINVAL;
++ }
++
++ val = tmp & RTC_SW_CAL_VALUE_MASK;
++ /* set software calibration value */
++ writel(val, srtc->regs + SFT_RTC_SW_CAL_VALUE);
++
++ /* set CFG_RTC-cal_sel to select calibretion by software. */
++ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
++
++ return 0;
++}
++
++static __maybe_unused int
++sft_rtc_hw_adjustment(struct device *dev, unsigned int enable)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++
++ if (srtc->hw_cal_map <= 0) {
++ dev_err(dev, "fail to get cal-clock-freq.\n");
++ return -EFAULT;
++ }
++
++ if (enable) {
++ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, true);
++
++ /* Set reference clock frequency value */
++ val = readl(srtc->regs + SFT_RTC_HW_CAL_CFG);
++ val |= (srtc->hw_cal_map << RTC_HW_CAL_FRQ_SEL_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_HW_CAL_CFG);
++
++ /* Set CFG_RTC-cal_sel to select calibretion by hardware. */
++ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_HW);
++
++ /* Set CFG_RTC-cal_en_hw to launch hardware calibretion.*/
++ sft_rtc_set_cal_hw_enable(srtc, true);
++
++ wait_for_completion_interruptible_timeout(&srtc->cal_done,
++ usecs_to_jiffies(100));
++
++ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, false);
++ } else {
++ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
++ sft_rtc_set_cal_hw_enable(srtc, false);
++ }
++
++ return 0;
++}
++
++static int sft_rtc_get_cal_clk(struct device *dev, struct sft_rtc *srtc)
++{
++ struct device_node *np = dev->of_node;
++ unsigned long cal_clk_freq;
++ u32 freq;
++ int ret;
++
++ srtc->cal_clk = devm_clk_get(dev, "cal_clk");
++ if (IS_ERR(srtc->cal_clk))
++ return PTR_ERR(srtc->cal_clk);
++
++ clk_prepare_enable(srtc->cal_clk);
++
++ cal_clk_freq = clk_get_rate(srtc->cal_clk);
++ if (!cal_clk_freq) {
++ dev_warn(dev,
++ "get rate failed, next try to get from dts.\n");
++ ret = of_property_read_u32(np, "rtc,cal-clock-freq", &freq);
++ if (!ret) {
++ cal_clk_freq = (u64)freq;
++ } else {
++ dev_err(dev,
++ "Need rtc,cal-clock-freq define in dts.\n");
++ goto err_disable_cal_clk;
++ }
++ }
++
++ srtc->hw_cal_map = sft_rtc_get_hw_calclk(dev, cal_clk_freq);
++ if (srtc->hw_cal_map < 0) {
++ ret = srtc->hw_cal_map;
++ goto err_disable_cal_clk;
++ }
++
++ return 0;
++
++err_disable_cal_clk:
++ clk_disable_unprepare(srtc->cal_clk);
++
++ return ret;
++}
++
++static int sft_rtc_get_irq(struct platform_device *pdev, struct sft_rtc *srtc)
++{
++ int ret;
++
++ srtc->rtc_irq = platform_get_irq_byname(pdev, "rtc");
++ if (srtc->rtc_irq < 0)
++ return -EINVAL;
++
++ ret = devm_request_irq(&pdev->dev, srtc->rtc_irq,
++ sft_rtc_irq_handler, 0,
++ KBUILD_MODNAME, srtc);
++ if (ret)
++ dev_err(&pdev->dev, "Failed to request interrupt, %d\n", ret);
++
++ return ret;
++}
++
++static const struct rtc_class_ops starfive_rtc_ops = {
++ .read_time = sft_rtc_read_time,
++ .set_time = sft_rtc_set_time,
++ .read_alarm = sft_rtc_read_alarm,
++ .set_alarm = sft_rtc_set_alarm,
++ .alarm_irq_enable = sft_rtc_alarm_irq_enable,
++ .set_offset = sft_rtc_set_offset,
++ .read_offset = sft_rtc_get_offset,
++};
++
++static int sft_rtc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct sft_rtc *srtc;
++ struct rtc_time tm;
++ struct irq_desc *desc;
++ int ret;
++
++ srtc = devm_kzalloc(dev, sizeof(*srtc), GFP_KERNEL);
++ if (!srtc)
++ return -ENOMEM;
++
++ srtc->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(srtc->regs))
++ return PTR_ERR(srtc->regs);
++
++ srtc->pclk = devm_clk_get(dev, "pclk");
++ if (IS_ERR(srtc->pclk)) {
++ ret = PTR_ERR(srtc->pclk);
++ dev_err(dev,
++ "Failed to retrieve the peripheral clock, %d\n", ret);
++ return ret;
++ }
++
++ srtc->rst_array = devm_reset_control_array_get_exclusive(dev);
++ if (IS_ERR(srtc->rst_array)) {
++ ret = PTR_ERR(srtc->rst_array);
++ dev_err(dev,
++ "Failed to retrieve the rtc reset, %d\n", ret);
++ return ret;
++ }
++
++ init_completion(&srtc->cal_done);
++ init_completion(&srtc->onesec_done);
++
++ ret = clk_prepare_enable(srtc->pclk);
++ if (ret) {
++ dev_err(dev,
++ "Failed to enable the peripheral clock, %d\n", ret);
++ return ret;
++ }
++
++ ret = sft_rtc_get_cal_clk(dev, srtc);
++ if (ret)
++ goto err_disable_pclk;
++
++ ret = reset_control_deassert(srtc->rst_array);
++ if (ret) {
++ dev_err(dev,
++ "Failed to deassert rtc resets, %d\n", ret);
++ goto err_disable_cal_clk;
++ }
++
++ ret = sft_rtc_get_irq(pdev, srtc);
++ if (ret)
++ goto err_disable_cal_clk;
++
++ srtc->rtc_dev = devm_rtc_allocate_device(dev);
++ if (IS_ERR(srtc->rtc_dev))
++ return PTR_ERR(srtc->rtc_dev);
++
++ platform_set_drvdata(pdev, srtc);
++
++ /* The RTC supports 01.01.2001 - 31.12.2099 */
++ srtc->rtc_dev->range_min = mktime64(2001, 1, 1, 0, 0, 0);
++ srtc->rtc_dev->range_max = mktime64(2099, 12, 31, 23, 59, 59);
++
++ srtc->rtc_dev->ops = &starfive_rtc_ops;
++ device_init_wakeup(dev, true);
++
++ desc = irq_to_desc(srtc->rtc_irq);
++ irq_desc_get_chip(desc)->flags = IRQCHIP_SKIP_SET_WAKE;
++
++ /* Always use 24-hour mode and keep the RTC values */
++ sft_rtc_set_mode(srtc, RTC_HOUR_MODE_24H);
++
++ sft_rtc_set_enabled(srtc, true);
++
++ if (device_property_read_bool(dev, "rtc,hw-adjustment"))
++ sft_rtc_hw_adjustment(dev, true);
++
++ /*
++ * If rtc time is out of supported range, reset it to the minimum time.
++ * notice that, actual year = 1900 + tm.tm_year
++ * actual month = 1 + tm.tm_mon
++ */
++ sft_rtc_read_time(dev, &tm);
++ if (tm.tm_year < 101 || tm.tm_year > 199 || tm.tm_mon < 0 || tm.tm_mon > 11 ||
++ tm.tm_mday < 1 || tm.tm_mday > 31 || tm.tm_hour < 0 || tm.tm_hour > 23 ||
++ tm.tm_min < 0 || tm.tm_min > 59 || tm.tm_sec < 0 || tm.tm_sec > 59) {
++ rtc_time64_to_tm(srtc->rtc_dev->range_min, &tm);
++ sft_rtc_set_time(dev, &tm);
++ }
++
++ ret = devm_rtc_register_device(srtc->rtc_dev);
++ if (ret)
++ goto err_disable_wakeup;
++
++ return 0;
++
++err_disable_wakeup:
++ device_init_wakeup(dev, false);
++
++err_disable_cal_clk:
++ clk_disable_unprepare(srtc->cal_clk);
++
++err_disable_pclk:
++ clk_disable_unprepare(srtc->pclk);
++
++ return ret;
++}
++
++static int sft_rtc_remove(struct platform_device *pdev)
++{
++ struct sft_rtc *srtc = platform_get_drvdata(pdev);
++
++ sft_rtc_alarm_irq_enable(&pdev->dev, 0);
++ device_init_wakeup(&pdev->dev, 0);
++
++ clk_disable_unprepare(srtc->pclk);
++ clk_disable_unprepare(srtc->cal_clk);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int sft_rtc_suspend(struct device *dev)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++
++ if (device_may_wakeup(dev))
++ enable_irq_wake(srtc->rtc_irq);
++
++ return 0;
++}
++
++static int sft_rtc_resume(struct device *dev)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++
++ if (device_may_wakeup(dev))
++ disable_irq_wake(srtc->rtc_irq);
++
++ return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(sft_rtc_pm_ops, sft_rtc_suspend, sft_rtc_resume);
++
++static const struct of_device_id sft_rtc_of_match[] = {
++ { .compatible = "starfive,jh7110-rtc" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, sft_rtc_of_match);
++
++static struct platform_driver starfive_rtc_driver = {
++ .driver = {
++ .name = "starfive-rtc",
++ .of_match_table = sft_rtc_of_match,
++ .pm = &sft_rtc_pm_ops,
++ },
++ .probe = sft_rtc_probe,
++ .remove = sft_rtc_remove,
++};
++module_platform_driver(starfive_rtc_driver);
++
++MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
++MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive RTC driver");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:starfive-rtc");
diff --git a/target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch b/target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch
new file mode 100644
index 0000000000..c88008a604
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch
@@ -0,0 +1,96 @@
+From 552114b8cbbd956ad8466261b5f11b059eba82ca Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Sun, 25 Jun 2023 09:40:29 +0800
+Subject: [PATCH 066/116] uart: 8250: Add dw auto flow ctrl support
+
+Add designeware 8250 auto flow ctrl support. Enable
+it by add auto-flow-control in dts.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/tty/serial/8250/8250_core.c | 2 ++
+ drivers/tty/serial/8250/8250_dw.c | 3 +++
+ drivers/tty/serial/8250/8250_port.c | 14 +++++++++++++-
+ include/linux/serial_8250.h | 1 +
+ include/uapi/linux/serial_core.h | 2 ++
+ 5 files changed, 21 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -1129,6 +1129,8 @@ int serial8250_register_8250_port(const
+ uart->dl_read = up->dl_read;
+ if (up->dl_write)
+ uart->dl_write = up->dl_write;
++ if (up->probe)
++ uart->probe = up->probe;
+
+ if (uart->port.type != PORT_8250_CIR) {
+ if (serial8250_isa_config != NULL)
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -612,6 +612,9 @@ static int dw8250_probe(struct platform_
+ data->msr_mask_off |= UART_MSR_TERI;
+ }
+
++ if (device_property_read_bool(dev, "auto-flow-control"))
++ up->probe |= UART_PROBE_AFE;
++
+ /* If there is separate baudclk, get the rate from it. */
+ data->clk = devm_clk_get_optional(dev, "baudclk");
+ if (data->clk == NULL)
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -330,6 +330,14 @@ static const struct serial8250_config ua
+ .rxtrig_bytes = {1, 8, 16, 30},
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
++ [PORT_16550A_AFE] = {
++ .name = "16550A_AFE",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .rxtrig_bytes = {1, 4, 8, 14},
++ .flags = UART_CAP_FIFO | UART_CAP_AFE,
++ },
+ };
+
+ /* Uart divisor latch read */
+@@ -1143,6 +1151,11 @@ static void autoconfig_16550a(struct uar
+ up->port.type = PORT_U6_16550A;
+ up->capabilities |= UART_CAP_AFE;
+ }
++
++ if ((up->port.type == PORT_16550A) && (up->probe & UART_PROBE_AFE)) {
++ up->port.type = PORT_16550A_AFE;
++ up->capabilities |= UART_CAP_AFE;
++ }
+ }
+
+ /*
+@@ -2813,7 +2826,6 @@ serial8250_do_set_termios(struct uart_po
+ if (termios->c_cflag & CRTSCTS)
+ up->mcr |= UART_MCR_AFE;
+ }
+-
+ /*
+ * Update the per-port timeout.
+ */
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -141,6 +141,7 @@ struct uart_8250_port {
+ unsigned char probe;
+ struct mctrl_gpios *gpios;
+ #define UART_PROBE_RSA (1 << 0)
++#define UART_PROBE_AFE (1 << 1)
+
+ /*
+ * Some bits in registers are cleared on a read, so they must
+--- a/include/uapi/linux/serial_core.h
++++ b/include/uapi/linux/serial_core.h
+@@ -245,4 +245,6 @@
+ /* Sunplus UART */
+ #define PORT_SUNPLUS 123
+
++#define PORT_16550A_AFE 124
++
+ #endif /* _UAPILINUX_SERIAL_CORE_H */
diff --git a/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch b/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch
new file mode 100644
index 0000000000..18d735b92d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch
@@ -0,0 +1,29 @@
+From 6edee93a89254f30c3387c88231e7ecec06ba84a Mon Sep 17 00:00:00 2001
+From: "shanlong.li" <shanlong.li@starfivetech.com>
+Date: Mon, 10 Jul 2023 03:07:57 -0700
+Subject: [PATCH 067/116] driver:uart: fix up uart communicate fail
+
+fix up uart communicate fail
+
+Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
+---
+ drivers/tty/serial/8250/8250_dw.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -652,10 +652,10 @@ static int dw8250_probe(struct platform_
+ if (err)
+ return err;
+
+- data->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
+- if (IS_ERR(data->rst))
+- return PTR_ERR(data->rst);
+-
++ data->rst = devm_reset_control_array_get_exclusive(dev);
++ if (IS_ERR(data->rst)) {
++ err = PTR_ERR(data->rst);
++ }
+ reset_control_deassert(data->rst);
+
+ err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst);
diff --git a/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch b/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch
new file mode 100644
index 0000000000..56efebda6c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch
@@ -0,0 +1,32 @@
+From 777d288f03a0b350f6c2d4367b01a80d9f25cd6e Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Wed, 20 Sep 2023 17:19:59 +0800
+Subject: [PATCH 068/116] uart: 8250: add reset operation in runtime PM
+
+add reset operation in runtime PM
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ drivers/tty/serial/8250/8250_dw.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -745,6 +745,8 @@ static int dw8250_runtime_suspend(struct
+ {
+ struct dw8250_data *data = dev_get_drvdata(dev);
+
++ reset_control_assert(data->rst);
++
+ clk_disable_unprepare(data->clk);
+
+ clk_disable_unprepare(data->pclk);
+@@ -760,6 +762,8 @@ static int dw8250_runtime_resume(struct
+
+ clk_prepare_enable(data->clk);
+
++ reset_control_deassert(data->rst);
++
+ return 0;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch b/target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch
new file mode 100644
index 0000000000..eb46a96314
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch
@@ -0,0 +1,113 @@
+From 5eda2331a252436756fb40861f01a7a38b1502c7 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Thu, 15 Jun 2023 20:14:22 +0800
+Subject: [PATCH 069/116] dt-bindings: CAN: Add StarFive CAN module
+
+Add documentation to describe StarFive CAN engine.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ .../devicetree/bindings/net/can/ipms-can.yaml | 97 +++++++++++++++++++
+ 1 file changed, 97 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/can/ipms-can.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/can/ipms-can.yaml
+@@ -0,0 +1,97 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++#$id: http://devicetree.org/schemas/net/can/ipms-can.yaml#
++#$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: IPMS CAN/CANFD controller Device Tree Bindings
++
++properties:
++ compatible:
++ const:ipms,can
++
++ reg:
++ maxItems: 1
++ items:
++ - description:CAN controller registers
++
++ interrupts:
++ maxItems: 1
++
++ clocks:
++ minItems: 1
++ items:
++ - description:apb_clk clock
++ - description:core_clk clock
++ - description:timer_clk clock
++
++ clock-names:
++ minItems: 1
++ items:
++ - const:apb_clk
++ - const:core_clk
++ - const:timer_clk
++ resets:
++ minItems: 1
++ items:
++ - description:apb_clk reset
++ - description:core_clk reset
++ - description:timer_clk reset
++ reset-names:
++ minItems: 1
++ items:
++ - const:rst_apb
++ - const:rst_core
++ - const:rst_timer
++ starfive,sys-syscon:
++ format:
++ starfive,sys-syscon = <&arg0 arg1 arg2 arg3>
++ description:
++ arg0:arg0 is sys_syscon.
++ arg1:arg1 is syscon register offset, used to enable can2.0/canfd function, can0 is 0x10, can1 is 0x88.
++ arg2:arg2 is used to enable the register shift of the can2.0/canfd function, can0 is 0x3, can1 is 0x12.
++ arg3:arg3 is used to enable the register mask of the can2.0/canfd function, can0 is 0x8, can1 is 0x40000
++
++ syscon,can_or_canfd:
++ description:
++ IPMS CAN-CTRL core is a serial communications controller that performs serial communication according to the CAN protocol.
++ This CAN bus interface uses the basic CAN principle and meets all constraints of the CAN-specification 2.0B active.
++ Furthermore this CAN core can be configured to meet the specification of CAN with flexible data rate CAN FD.
++ When syscon,can_or_canfd is set to 0, use CAN2.0B.
++ when syscon,can_or_canfd is set to 1, use CAN FD.
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - starfive,sys-syscon
++ - syscon,can_or_canfd
++additionalProperties:false
++
++examples:
++ - |
++ can0: can@130d0000{
++ compatible = "ipms,can";
++ reg = <0x0 0x130d0000 0x0 0x1000>;
++ interrupts = <112>;
++ interrupt-parent = <&plic>;
++ clocks = <&clkgen JH7110_CAN0_CTRL_CLK_APB>,
++ <&clkgen JH7110_CAN0_CTRL_CLK_CAN>,
++ <&clkgen JH7110_CAN0_CTRL_CLK_TIMER>;
++ clock-names = "apb_clk",
++ "core_clk",
++ "timer_clk";
++ resets = <&rstgen RSTN_U0_CAN_CTRL_APB>,
++ <&rstgen RSTN_U0_CAN_CTRL_CORE>,
++ <&rstgen RSTN_U0_CAN_CTRL_TIMER>;
++ reset-names = "rst_apb",
++ "rst_core",
++ "rst_timer";
++ starfive,sys-syscon = <&sys_syscon, 0x10 0x3 0x8>;
++ syscon,can_or_canfd = <0>;
++ };
++
++...
diff --git a/target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch b/target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch
new file mode 100644
index 0000000000..1bb41dd079
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch
@@ -0,0 +1,1317 @@
+From b1fbe15b87be654b1b280a76ec1470917d79f720 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Thu, 15 Jun 2023 20:15:25 +0800
+Subject: [PATCH 070/116] CAN: starfive - Add CAN engine support
+
+Adding device probe StarFive CAN module.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/net/can/Kconfig | 5 +
+ drivers/net/can/Makefile | 1 +
+ drivers/net/can/ipms_canfd.c | 1275 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 1281 insertions(+)
+ create mode 100644 drivers/net/can/ipms_canfd.c
+
+--- a/drivers/net/can/Kconfig
++++ b/drivers/net/can/Kconfig
+@@ -214,6 +214,11 @@ config CAN_XILINXCAN
+ Xilinx CAN driver. This driver supports both soft AXI CAN IP and
+ Zynq CANPS IP.
+
++config IPMS_CAN
++ tristate "IPMS CAN"
++ help
++ IPMS CANFD driver. This driver supports IPMS CANFD IP.
++
+ source "drivers/net/can/c_can/Kconfig"
+ source "drivers/net/can/cc770/Kconfig"
+ source "drivers/net/can/ctucanfd/Kconfig"
+--- a/drivers/net/can/Makefile
++++ b/drivers/net/can/Makefile
+@@ -31,5 +31,6 @@ obj-$(CONFIG_CAN_SJA1000) += sja1000/
+ obj-$(CONFIG_CAN_SUN4I) += sun4i_can.o
+ obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
+ obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o
++obj-$(CONFIG_IPMS_CAN) += ipms_canfd.o
+
+ subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) += -DDEBUG
+--- /dev/null
++++ b/drivers/net/can/ipms_canfd.c
+@@ -0,0 +1,1275 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive Controller Area Network Host Controller Driver
++ *
++ * Copyright (c) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/skbuff.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/can/dev.h>
++#include <linux/can/error.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_device.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
++
++#define DRIVER_NAME "ipms_canfd"
++
++/* CAN registers set */
++enum canfd_device_reg {
++ CANFD_RUBF_OFFSET = 0x00, /* Receive Buffer Registers 0x00-0x4f */
++ CANFD_RUBF_ID_OFFSET = 0x00,
++ CANFD_RBUF_CTL_OFFSET = 0x04,
++ CANFD_RBUF_DATA_OFFSET = 0x08,
++ CANFD_TBUF_OFFSET = 0x50, /* Transmit Buffer Registers 0x50-0x97 */
++ CANFD_TBUF_ID_OFFSET = 0x50,
++ CANFD_TBUF_CTL_OFFSET = 0x54,
++ CANFD_TBUF_DATA_OFFSET = 0x58,
++ CANFD_TTS_OFFSET = 0x98, /* Transmission Time Stamp 0x98-0x9f */
++ CANFD_CFG_STAT_OFFSET = 0xa0,
++ CANFD_TCMD_OFFSET = 0xa1,
++ CANFD_TCTRL_OFFSET = 0xa2,
++ CANFD_RCTRL_OFFSET = 0xa3,
++ CANFD_RTIE_OFFSET = 0xa4,
++ CANFD_RTIF_OFFSET = 0xa5,
++ CANFD_ERRINT_OFFSET = 0xa6,
++ CANFD_LIMIT_OFFSET = 0xa7,
++ CANFD_S_SEG_1_OFFSET = 0xa8,
++ CANFD_S_SEG_2_OFFSET = 0xa9,
++ CANFD_S_SJW_OFFSET = 0xaa,
++ CANFD_S_PRESC_OFFSET = 0xab,
++ CANFD_F_SEG_1_OFFSET = 0xac,
++ CANFD_F_SEG_2_OFFSET = 0xad,
++ CANFD_F_SJW_OFFSET = 0xae,
++ CANFD_F_PRESC_OFFSET = 0xaf,
++ CANFD_EALCAP_OFFSET = 0xb0,
++ CANFD_RECNT_OFFSET = 0xb2,
++ CANFD_TECNT_OFFSET = 0xb3,
++};
++
++enum canfd_reg_bitchange {
++ CAN_FD_SET_RST_MASK = 0x80, /* Set Reset Bit */
++ CAN_FD_OFF_RST_MASK = 0x7f, /* Reset Off Bit */
++ CAN_FD_SET_FULLCAN_MASK = 0x10, /* set TTTBM as 1->full TTCAN mode */
++ CAN_FD_OFF_FULLCAN_MASK = 0xef, /* set TTTBM as 0->separate PTB and STB mode */
++ CAN_FD_SET_FIFO_MASK = 0x20, /* set TSMODE as 1->FIFO mode */
++ CAN_FD_OFF_FIFO_MASK = 0xdf, /* set TSMODE as 0->Priority mode */
++ CAN_FD_SET_TSONE_MASK = 0x04,
++ CAN_FD_OFF_TSONE_MASK = 0xfb,
++ CAN_FD_SET_TSALL_MASK = 0x02,
++ CAN_FD_OFF_TSALL_MASK = 0xfd,
++ CAN_FD_LBMEMOD_MASK = 0x40, /* set loop back mode, external */
++ CAN_FD_LBMIMOD_MASK = 0x20, /* set loopback internal mode */
++ CAN_FD_SET_BUSOFF_MASK = 0x01,
++ CAN_FD_OFF_BUSOFF_MASK = 0xfe,
++ CAN_FD_SET_TTSEN_MASK = 0x80, /* set ttsen, tts update enable */
++ CAN_FD_SET_BRS_MASK = 0x10, /* can fd Bit Rate Switch mask */
++ CAN_FD_OFF_BRS_MASK = 0xef,
++ CAN_FD_SET_EDL_MASK = 0x20, /* Extended Data Length */
++ CAN_FD_OFF_EDL_MASK = 0xdf,
++ CAN_FD_SET_DLC_MASK = 0x0f,
++ CAN_FD_SET_TENEXT_MASK = 0x40,
++ CAN_FD_SET_IDE_MASK = 0x80,
++ CAN_FD_OFF_IDE_MASK = 0x7f,
++ CAN_FD_SET_RTR_MASK = 0x40,
++ CAN_FD_OFF_RTR_MASK = 0xbf,
++ CAN_FD_INTR_ALL_MASK = 0xff, /* all interrupts enable mask */
++ CAN_FD_SET_RIE_MASK = 0x80,
++ CAN_FD_OFF_RIE_MASK = 0x7f,
++ CAN_FD_SET_RFIE_MASK = 0x20,
++ CAN_FD_OFF_RFIE_MASK = 0xdf,
++ CAN_FD_SET_RAFIE_MASK = 0x10,
++ CAN_FD_OFF_RAFIE_MASK = 0xef,
++ CAN_FD_SET_EIE_MASK = 0x02,
++ CAN_FD_OFF_EIE_MASK = 0xfd,
++ CAN_FD_TASCTIVE_MASK = 0x02,
++ CAN_FD_RASCTIVE_MASK = 0x04,
++ CAN_FD_SET_TBSEL_MASK = 0x80, /* message writen in STB */
++ CAN_FD_OFF_TBSEL_MASK = 0x7f, /* message writen in PTB */
++ CAN_FD_SET_STBY_MASK = 0x20,
++ CAN_FD_OFF_STBY_MASK = 0xdf,
++ CAN_FD_SET_TPE_MASK = 0x10, /* Transmit primary enable */
++ CAN_FD_SET_TPA_MASK = 0x08,
++ CAN_FD_SET_SACK_MASK = 0x80,
++ CAN_FD_SET_RREL_MASK = 0x10,
++ CAN_FD_RSTAT_NOT_EMPTY_MASK = 0x03,
++ CAN_FD_SET_RIF_MASK = 0x80,
++ CAN_FD_OFF_RIF_MASK = 0x7f,
++ CAN_FD_SET_RAFIF_MASK = 0x10,
++ CAN_FD_SET_RFIF_MASK = 0x20,
++ CAN_FD_SET_TPIF_MASK = 0x08, /* Transmission Primary Interrupt Flag */
++ CAN_FD_SET_TSIF_MASK = 0x04,
++ CAN_FD_SET_EIF_MASK = 0x02,
++ CAN_FD_SET_AIF_MASK = 0x01,
++ CAN_FD_SET_EWARN_MASK = 0x80,
++ CAN_FD_SET_EPASS_MASK = 0x40,
++ CAN_FD_SET_EPIE_MASK = 0x20,
++ CAN_FD_SET_EPIF_MASK = 0x10,
++ CAN_FD_SET_ALIE_MASK = 0x08,
++ CAN_FD_SET_ALIF_MASK = 0x04,
++ CAN_FD_SET_BEIE_MASK = 0x02,
++ CAN_FD_SET_BEIF_MASK = 0x01,
++ CAN_FD_OFF_EPIE_MASK = 0xdf,
++ CAN_FD_OFF_BEIE_MASK = 0xfd,
++ CAN_FD_SET_AFWL_MASK = 0x40,
++ CAN_FD_SET_EWL_MASK = 0x0b,
++ CAN_FD_SET_KOER_MASK = 0xe0,
++ CAN_FD_SET_BIT_ERROR_MASK = 0x20,
++ CAN_FD_SET_FORM_ERROR_MASK = 0x40,
++ CAN_FD_SET_STUFF_ERROR_MASK = 0x60,
++ CAN_FD_SET_ACK_ERROR_MASK = 0x80,
++ CAN_FD_SET_CRC_ERROR_MASK = 0xa0,
++ CAN_FD_SET_OTH_ERROR_MASK = 0xc0,
++};
++
++/* seg1,seg2,sjw,prescaler all have 8 bits */
++#define BITS_OF_BITTIMING_REG 8
++
++/* in can_bittiming strucure every field has 32 bits---->u32 */
++#define FBITS_IN_BITTIMING_STR 32
++#define SEG_1_SHIFT 0
++#define SEG_2_SHIFT 8
++#define SJW_SHIFT 16
++#define PRESC_SHIFT 24
++
++/* TTSEN bit used for 32 bit register read or write */
++#define TTSEN_8_32_SHIFT 24
++#define RTR_32_8_SHIFT 24
++
++/* transmit mode */
++#define XMIT_FULL 0
++#define XMIT_SEP_FIFO 1
++#define XMIT_SEP_PRIO 2
++#define XMIT_PTB_MODE 3
++
++enum IPMS_CAN_TYPE {
++ IPMS_CAN_TYPY_CAN = 0,
++ IPMS_CAN_TYPE_CANFD,
++};
++
++struct ipms_canfd_priv {
++ struct can_priv can;
++ struct napi_struct napi;
++ struct device *dev;
++ struct regmap *reg_syscon;
++ void __iomem *reg_base;
++ u32 (*read_reg)(const struct ipms_canfd_priv *priv, enum canfd_device_reg reg);
++ void (*write_reg)(const struct ipms_canfd_priv *priv, enum canfd_device_reg reg, u32 val);
++ struct clk *can_clk;
++ u32 tx_mode;
++ struct reset_control *resets;
++ struct clk_bulk_data *clks;
++ int nr_clks;
++ u32 can_or_canfd;
++};
++
++static struct can_bittiming_const canfd_bittiming_const = {
++ .name = DRIVER_NAME,
++ .tseg1_min = 2,
++ .tseg1_max = 16,
++ .tseg2_min = 2,
++ .tseg2_max = 8,
++ .sjw_max = 4,
++ .brp_min = 1,
++ .brp_max = 512,
++ .brp_inc = 1,
++
++};
++
++static struct can_bittiming_const canfd_data_bittiming_const = {
++ .name = DRIVER_NAME,
++ .tseg1_min = 1,
++ .tseg1_max = 16,
++ .tseg2_min = 2,
++ .tseg2_max = 8,
++ .sjw_max = 8,
++ .brp_min = 1,
++ .brp_max = 512,
++ .brp_inc = 1,
++};
++
++static void canfd_write_reg_le(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg, u32 val)
++{
++ iowrite32(val, priv->reg_base + reg);
++}
++
++static u32 canfd_read_reg_le(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg)
++{
++ return ioread32(priv->reg_base + reg);
++}
++
++static inline unsigned char can_ioread8(const void *addr)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u32 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)addr, 4);
++ offset = addr - addr_down;
++ val.val_32 = ioread32(addr_down);
++ return val.val_8[offset];
++}
++
++static inline void can_iowrite8(unsigned char value, void *addr)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u8 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)addr, 4);
++ offset = addr - addr_down;
++ val.val_32 = ioread32(addr_down);
++ val.val_8[offset] = value;
++ iowrite32(val.val_32, addr_down);
++}
++
++static void canfd_reigister_set_bit(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg,
++ enum canfd_reg_bitchange set_mask)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u8 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
++ offset = (priv->reg_base + reg) - addr_down;
++ val.val_32 = ioread32(addr_down);
++ val.val_8[offset] |= set_mask;
++ iowrite32(val.val_32, addr_down);
++}
++
++static void canfd_reigister_off_bit(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg,
++ enum canfd_reg_bitchange set_mask)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u8 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
++ offset = (priv->reg_base + reg) - addr_down;
++ val.val_32 = ioread32(addr_down);
++ val.val_8[offset] &= set_mask;
++ iowrite32(val.val_32, addr_down);
++}
++
++static int canfd_device_driver_bittime_configuration(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct can_bittiming *bt = &priv->can.bittiming;
++ struct can_bittiming *dbt = &priv->can.data_bittiming;
++ u32 reset_test, bittiming_temp, dat_bittiming;
++
++ reset_test = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ if (!(reset_test & CAN_FD_SET_RST_MASK)) {
++ netdev_alert(ndev, "Not in reset mode, cannot set bit timing\n");
++ return -EPERM;
++ }
++
++ bittiming_temp = ((bt->phase_seg1 + bt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
++ ((bt->phase_seg2 - 1) << SEG_2_SHIFT) |
++ ((bt->sjw - 1) << SJW_SHIFT) |
++ ((bt->brp - 1) << PRESC_SHIFT);
++
++ /* Check the bittime parameter */
++ if ((((int)(bt->phase_seg1 + bt->prop_seg + 1) - 2) < 0) ||
++ (((int)(bt->phase_seg2) - 1) < 0) ||
++ (((int)(bt->sjw) - 1) < 0) ||
++ (((int)(bt->brp) - 1) < 0))
++ return -EINVAL;
++
++ priv->write_reg(priv, CANFD_S_SEG_1_OFFSET, bittiming_temp);
++
++ if (priv->can_or_canfd == IPMS_CAN_TYPE_CANFD) {
++ dat_bittiming = ((dbt->phase_seg1 + dbt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
++ ((dbt->phase_seg2 - 1) << SEG_2_SHIFT) |
++ ((dbt->sjw - 1) << SJW_SHIFT) |
++ ((dbt->brp - 1) << PRESC_SHIFT);
++
++ if ((((int)(dbt->phase_seg1 + dbt->prop_seg + 1) - 2) < 0) ||
++ (((int)(dbt->phase_seg2) - 1) < 0) ||
++ (((int)(dbt->sjw) - 1) < 0) ||
++ (((int)(dbt->brp) - 1) < 0))
++ return -EINVAL;
++
++ priv->write_reg(priv, CANFD_F_SEG_1_OFFSET, dat_bittiming);
++ }
++
++ canfd_reigister_off_bit(priv, CANFD_CFG_STAT_OFFSET, CAN_FD_OFF_RST_MASK);
++
++ netdev_dbg(ndev, "Slow bit rate: %08x\n", priv->read_reg(priv, CANFD_S_SEG_1_OFFSET));
++ netdev_dbg(ndev, "Fast bit rate: %08x\n", priv->read_reg(priv, CANFD_F_SEG_1_OFFSET));
++
++ return 0;
++}
++
++int canfd_get_freebuffer(struct ipms_canfd_priv *priv)
++{
++ /* Get next transmit buffer */
++ canfd_reigister_set_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_SET_TENEXT_MASK);
++
++ if (can_ioread8(priv->reg_base + CANFD_TCTRL_OFFSET) & CAN_FD_SET_TENEXT_MASK)
++ return -1;
++
++ return 0;
++}
++
++static void canfd_tx_interrupt(struct net_device *ndev, u8 isr)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ /* wait till transmission of the PTB or STB finished */
++ while (isr & (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK)) {
++ if (isr & CAN_FD_SET_TPIF_MASK)
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_TPIF_MASK);
++
++ if (isr & CAN_FD_SET_TSIF_MASK)
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_TSIF_MASK);
++
++ isr = can_ioread8(priv->reg_base + CANFD_RTIF_OFFSET);
++ }
++ netif_wake_queue(ndev);
++}
++
++static int can_rx(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct net_device_stats *stats = &ndev->stats;
++ struct can_frame *cf;
++ struct sk_buff *skb;
++ u32 can_id;
++ u8 dlc, control, rx_status;
++
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++
++ if (!(rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK))
++ return 0;
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ can_id = priv->read_reg(priv, CANFD_RUBF_ID_OFFSET);
++ dlc = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET) & CAN_FD_SET_DLC_MASK;
++
++ skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
++ if (!skb) {
++ stats->rx_dropped++;
++ return 0;
++ }
++ cf->can_dlc = can_cc_dlc2len(dlc);
++
++ /* change the CANFD id into socketcan id format */
++ if (control & CAN_FD_SET_IDE_MASK) {
++ cf->can_id = can_id;
++ cf->can_id |= CAN_EFF_FLAG;
++ } else {
++ cf->can_id = can_id;
++ cf->can_id &= (~CAN_EFF_FLAG);
++ }
++
++ if (control & CAN_FD_SET_RTR_MASK)
++ cf->can_id |= CAN_RTR_FLAG;
++
++ if (!(control & CAN_FD_SET_RTR_MASK)) {
++ *((u32 *)(cf->data + 0)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET);
++ *((u32 *)(cf->data + 4)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET + 4);
++ }
++
++ canfd_reigister_set_bit(priv, CANFD_RCTRL_OFFSET, CAN_FD_SET_RREL_MASK);
++ stats->rx_bytes += can_fd_dlc2len(cf->can_dlc);
++ stats->rx_packets++;
++ netif_receive_skb(skb);
++
++ return 1;
++}
++
++static int canfd_rx(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct net_device_stats *stats = &ndev->stats;
++ struct canfd_frame *cf;
++ struct sk_buff *skb;
++ u32 can_id;
++ u8 dlc, control, rx_status;
++ int i;
++
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++
++ if (!(rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK))
++ return 0;
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ can_id = priv->read_reg(priv, CANFD_RUBF_ID_OFFSET);
++ dlc = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET) & CAN_FD_SET_DLC_MASK;
++
++ if (control & CAN_FD_SET_EDL_MASK)
++ /* allocate sk_buffer for canfd frame */
++ skb = alloc_canfd_skb(ndev, &cf);
++ else
++ /* allocate sk_buffer for can frame */
++ skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
++
++ if (!skb) {
++ stats->rx_dropped++;
++ return 0;
++ }
++
++ /* change the CANFD or CAN2.0 data into socketcan data format */
++ if (control & CAN_FD_SET_EDL_MASK)
++ cf->len = can_fd_dlc2len(dlc);
++ else
++ cf->len = can_cc_dlc2len(dlc);
++
++ /* change the CANFD id into socketcan id format */
++ if (control & CAN_FD_SET_EDL_MASK) {
++ cf->can_id = can_id;
++ if (control & CAN_FD_SET_IDE_MASK)
++ cf->can_id |= CAN_EFF_FLAG;
++ else
++ cf->can_id &= (~CAN_EFF_FLAG);
++ } else {
++ cf->can_id = can_id;
++ if (control & CAN_FD_SET_IDE_MASK)
++ cf->can_id |= CAN_EFF_FLAG;
++ else
++ cf->can_id &= (~CAN_EFF_FLAG);
++
++ if (control & CAN_FD_SET_RTR_MASK)
++ cf->can_id |= CAN_RTR_FLAG;
++ }
++
++ /* CANFD frames handed over to SKB */
++ if (control & CAN_FD_SET_EDL_MASK) {
++ for (i = 0; i < cf->len; i += 4)
++ *((u32 *)(cf->data + i)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET + i);
++ } else {
++ /* skb reads the received datas, if the RTR bit not set */
++ if (!(control & CAN_FD_SET_RTR_MASK)) {
++ *((u32 *)(cf->data + 0)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET);
++ *((u32 *)(cf->data + 4)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET + 4);
++ }
++ }
++
++ canfd_reigister_set_bit(priv, CANFD_RCTRL_OFFSET, CAN_FD_SET_RREL_MASK);
++
++ stats->rx_bytes += cf->len;
++ stats->rx_packets++;
++ netif_receive_skb(skb);
++
++ return 1;
++}
++
++static int canfd_rx_poll(struct napi_struct *napi, int quota)
++{
++ struct net_device *ndev = napi->dev;
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int work_done = 0;
++ u8 rx_status = 0, control = 0;
++
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++
++ /* clear receive interrupt and deal with all the received frames */
++ while ((rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK) && (work_done < quota)) {
++ (control & CAN_FD_SET_EDL_MASK) ? (work_done += canfd_rx(ndev)) : (work_done += can_rx(ndev));
++
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++ }
++ napi_complete(napi);
++ canfd_reigister_set_bit(priv, CANFD_RTIE_OFFSET, CAN_FD_SET_RIE_MASK);
++ return work_done;
++}
++
++static void canfd_rxfull_interrupt(struct net_device *ndev, u8 isr)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ if (isr & CAN_FD_SET_RAFIF_MASK)
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_RAFIF_MASK);
++
++ if (isr & (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK))
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET,
++ (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK));
++}
++
++static int set_canfd_xmit_mode(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ switch (priv->tx_mode) {
++ case XMIT_FULL:
++ canfd_reigister_set_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_SET_FULLCAN_MASK);
++ break;
++ case XMIT_SEP_FIFO:
++ canfd_reigister_off_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_OFF_FULLCAN_MASK);
++ canfd_reigister_set_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_SET_FIFO_MASK);
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_SET_TBSEL_MASK);
++ break;
++ case XMIT_SEP_PRIO:
++ canfd_reigister_off_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_OFF_FULLCAN_MASK);
++ canfd_reigister_off_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_OFF_FIFO_MASK);
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_SET_TBSEL_MASK);
++ break;
++ case XMIT_PTB_MODE:
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_OFF_TBSEL_MASK);
++ break;
++ default:
++ break;
++ }
++ return 0;
++}
++
++static netdev_tx_t canfd_driver_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct canfd_frame *cf = (struct canfd_frame *)skb->data;
++ struct net_device_stats *stats = &ndev->stats;
++ u32 ttsen, id, ctl, addr_off;
++ int i;
++
++ priv->tx_mode = XMIT_PTB_MODE;
++
++ if (can_dropped_invalid_skb(ndev, skb))
++ return NETDEV_TX_OK;
++
++ switch (priv->tx_mode) {
++ case XMIT_FULL:
++ return NETDEV_TX_BUSY;
++ case XMIT_PTB_MODE:
++ set_canfd_xmit_mode(ndev);
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_OFF_STBY_MASK);
++
++ if (cf->can_id & CAN_EFF_FLAG) {
++ id = (cf->can_id & CAN_EFF_MASK);
++ ttsen = 0 << TTSEN_8_32_SHIFT;
++ id |= ttsen;
++ } else {
++ id = (cf->can_id & CAN_SFF_MASK);
++ ttsen = 0 << TTSEN_8_32_SHIFT;
++ id |= ttsen;
++ }
++
++ ctl = can_fd_len2dlc(cf->len);
++
++ /* transmit can fd frame */
++ if (priv->can_or_canfd == IPMS_CAN_TYPE_CANFD) {
++ if (can_is_canfd_skb(skb)) {
++ if (cf->can_id & CAN_EFF_FLAG)
++ ctl |= CAN_FD_SET_IDE_MASK;
++ else
++ ctl &= CAN_FD_OFF_IDE_MASK;
++
++ if (cf->flags & CANFD_BRS)
++ ctl |= CAN_FD_SET_BRS_MASK;
++
++ ctl |= CAN_FD_SET_EDL_MASK;
++
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++
++ for (i = 0; i < cf->len; i += 4) {
++ priv->write_reg(priv, addr_off,
++ *((u32 *)(cf->data + i)));
++ addr_off += 4;
++ }
++ } else {
++ ctl &= CAN_FD_OFF_EDL_MASK;
++ ctl &= CAN_FD_OFF_BRS_MASK;
++
++ if (cf->can_id & CAN_EFF_FLAG)
++ ctl |= CAN_FD_SET_IDE_MASK;
++ else
++ ctl &= CAN_FD_OFF_IDE_MASK;
++
++ if (cf->can_id & CAN_RTR_FLAG) {
++ ctl |= CAN_FD_SET_RTR_MASK;
++ priv->write_reg(priv,
++ CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv,
++ CANFD_TBUF_CTL_OFFSET, ctl);
++ } else {
++ ctl &= CAN_FD_OFF_RTR_MASK;
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++ priv->write_reg(priv, addr_off,
++ *((u32 *)(cf->data + 0)));
++ priv->write_reg(priv, addr_off + 4,
++ *((u32 *)(cf->data + 4)));
++ }
++ }
++ priv->write_reg(priv, CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv, CANFD_TBUF_CTL_OFFSET, ctl);
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++ } else {
++ ctl &= CAN_FD_OFF_EDL_MASK;
++ ctl &= CAN_FD_OFF_BRS_MASK;
++
++ if (cf->can_id & CAN_EFF_FLAG)
++ ctl |= CAN_FD_SET_IDE_MASK;
++ else
++ ctl &= CAN_FD_OFF_IDE_MASK;
++
++ if (cf->can_id & CAN_RTR_FLAG) {
++ ctl |= CAN_FD_SET_RTR_MASK;
++ priv->write_reg(priv, CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv, CANFD_TBUF_CTL_OFFSET, ctl);
++ } else {
++ ctl &= CAN_FD_OFF_RTR_MASK;
++ priv->write_reg(priv, CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv, CANFD_TBUF_CTL_OFFSET, ctl);
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++ priv->write_reg(priv, addr_off,
++ *((u32 *)(cf->data + 0)));
++ priv->write_reg(priv, addr_off + 4,
++ *((u32 *)(cf->data + 4)));
++ }
++ }
++ canfd_reigister_set_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_SET_TPE_MASK);
++ stats->tx_bytes += cf->len;
++ break;
++ default:
++ break;
++ }
++
++ /*Due to cache blocking, we need call dev_kfree_skb() here to free the socket
++ buffer and return NETDEV_TX_OK */
++ dev_kfree_skb(skb);
++
++ return NETDEV_TX_OK;
++}
++
++static int set_reset_mode(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ u8 ret;
++
++ ret = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++ ret |= CAN_FD_SET_RST_MASK;
++ can_iowrite8(ret, priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ return 0;
++}
++
++static void canfd_driver_stop(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int ret;
++
++ ret = set_reset_mode(ndev);
++ if (ret)
++ netdev_err(ndev, "Mode Resetting Failed!\n");
++
++ priv->can.state = CAN_STATE_STOPPED;
++}
++
++static int canfd_driver_close(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ netif_stop_queue(ndev);
++ napi_disable(&priv->napi);
++ canfd_driver_stop(ndev);
++
++ free_irq(ndev->irq, ndev);
++ close_candev(ndev);
++
++ pm_runtime_put(priv->dev);
++
++ return 0;
++}
++
++static enum can_state get_of_chip_status(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ u8 can_stat, eir;
++
++ can_stat = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++ eir = can_ioread8(priv->reg_base + CANFD_ERRINT_OFFSET);
++
++ if (can_stat & CAN_FD_SET_BUSOFF_MASK)
++ return CAN_STATE_BUS_OFF;
++
++ if ((eir & CAN_FD_SET_EPASS_MASK) && ~(can_stat & CAN_FD_SET_BUSOFF_MASK))
++ return CAN_STATE_ERROR_PASSIVE;
++
++ if (eir & CAN_FD_SET_EWARN_MASK && ~(eir & CAN_FD_SET_EPASS_MASK))
++ return CAN_STATE_ERROR_WARNING;
++
++ if (~(eir & CAN_FD_SET_EPASS_MASK))
++ return CAN_STATE_ERROR_ACTIVE;
++
++ return CAN_STATE_ERROR_ACTIVE;
++}
++
++static void canfd_error_interrupt(struct net_device *ndev, u8 isr, u8 eir)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct net_device_stats *stats = &ndev->stats;
++ struct can_frame *cf;
++ struct sk_buff *skb;
++ u8 koer, recnt = 0, tecnt = 0, can_stat = 0;
++
++ skb = alloc_can_err_skb(ndev, &cf);
++
++ koer = can_ioread8(priv->reg_base + CANFD_EALCAP_OFFSET) & CAN_FD_SET_KOER_MASK;
++ recnt = can_ioread8(priv->reg_base + CANFD_RECNT_OFFSET);
++ tecnt = can_ioread8(priv->reg_base + CANFD_TECNT_OFFSET);
++
++ /*Read can status*/
++ can_stat = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ /* Bus off --->active error mode */
++ if ((isr & CAN_FD_SET_EIF_MASK) && priv->can.state == CAN_STATE_BUS_OFF)
++ priv->can.state = get_of_chip_status(ndev);
++
++ /* State selection */
++ if (can_stat & CAN_FD_SET_BUSOFF_MASK) {
++ priv->can.state = get_of_chip_status(ndev);
++ priv->can.can_stats.bus_off++;
++ canfd_reigister_set_bit(priv, CANFD_CFG_STAT_OFFSET, CAN_FD_SET_BUSOFF_MASK);
++ can_bus_off(ndev);
++ if (skb)
++ cf->can_id |= CAN_ERR_BUSOFF;
++
++ } else if ((eir & CAN_FD_SET_EPASS_MASK) && ~(can_stat & CAN_FD_SET_BUSOFF_MASK)) {
++ priv->can.state = get_of_chip_status(ndev);
++ priv->can.can_stats.error_passive++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_CRTL;
++ cf->data[1] |= (recnt > 127) ? CAN_ERR_CRTL_RX_PASSIVE : 0;
++ cf->data[1] |= (tecnt > 127) ? CAN_ERR_CRTL_TX_PASSIVE : 0;
++ cf->data[6] = tecnt;
++ cf->data[7] = recnt;
++ }
++ } else if (eir & CAN_FD_SET_EWARN_MASK && ~(eir & CAN_FD_SET_EPASS_MASK)) {
++ priv->can.state = get_of_chip_status(ndev);
++ priv->can.can_stats.error_warning++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_CRTL;
++ cf->data[1] |= (recnt > 95) ? CAN_ERR_CRTL_RX_WARNING : 0;
++ cf->data[1] |= (tecnt > 95) ? CAN_ERR_CRTL_TX_WARNING : 0;
++ cf->data[6] = tecnt;
++ cf->data[7] = recnt;
++ }
++ }
++
++ /* Check for in protocol defined error interrupt */
++ if (eir & CAN_FD_SET_BEIF_MASK) {
++ if (skb)
++ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
++
++ /* bit error interrupt */
++ if (koer == CAN_FD_SET_BIT_ERROR_MASK) {
++ stats->tx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_BIT;
++ }
++ }
++ /* format error interrupt */
++ if (koer == CAN_FD_SET_FORM_ERROR_MASK) {
++ stats->rx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_FORM;
++ }
++ }
++ /* stuffing error interrupt */
++ if (koer == CAN_FD_SET_STUFF_ERROR_MASK) {
++ stats->rx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[3] = CAN_ERR_PROT_STUFF;
++ }
++ }
++ /* ack error interrupt */
++ if (koer == CAN_FD_SET_ACK_ERROR_MASK) {
++ stats->tx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_LOC_ACK;
++ }
++ }
++ /* crc error interrupt */
++ if (koer == CAN_FD_SET_CRC_ERROR_MASK) {
++ stats->rx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_LOC_CRC_SEQ;
++ }
++ }
++ priv->can.can_stats.bus_error++;
++ }
++ if (skb) {
++ stats->rx_packets++;
++ stats->rx_bytes += cf->can_dlc;
++ netif_rx(skb);
++ }
++
++ netdev_dbg(ndev, "Recnt is 0x%02x", can_ioread8(priv->reg_base + CANFD_RECNT_OFFSET));
++ netdev_dbg(ndev, "Tecnt is 0x%02x", can_ioread8(priv->reg_base + CANFD_TECNT_OFFSET));
++}
++
++static irqreturn_t canfd_interrupt(int irq, void *dev_id)
++{
++ struct net_device *ndev = (struct net_device *)dev_id;
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ u8 isr, eir;
++ u8 isr_handled = 0, eir_handled = 0;
++
++ /* read the value of interrupt status register */
++ isr = can_ioread8(priv->reg_base + CANFD_RTIF_OFFSET);
++
++ /* read the value of error interrupt register */
++ eir = can_ioread8(priv->reg_base + CANFD_ERRINT_OFFSET);
++
++ /* Check for Tx interrupt and Processing it */
++ if (isr & (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK)) {
++ canfd_tx_interrupt(ndev, isr);
++ isr_handled |= (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK);
++ }
++ if (isr & (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK)) {
++ canfd_rxfull_interrupt(ndev, isr);
++ isr_handled |= (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK);
++ }
++ /* Check Rx interrupt and Processing the receive interrupt routine */
++ if (isr & CAN_FD_SET_RIF_MASK) {
++ canfd_reigister_off_bit(priv, CANFD_RTIE_OFFSET, CAN_FD_OFF_RIE_MASK);
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_RIF_MASK);
++
++ napi_schedule(&priv->napi);
++ isr_handled |= CAN_FD_SET_RIF_MASK;
++ }
++ if ((isr & CAN_FD_SET_EIF_MASK) | (eir & (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK))) {
++ /* reset EPIF and BEIF. Reset EIF */
++ canfd_reigister_set_bit(priv, CANFD_ERRINT_OFFSET,
++ eir & (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK));
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET,
++ isr & CAN_FD_SET_EIF_MASK);
++
++ canfd_error_interrupt(ndev, isr, eir);
++
++ isr_handled |= CAN_FD_SET_EIF_MASK;
++ eir_handled |= (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK);
++ }
++ if ((isr_handled == 0) && (eir_handled == 0)) {
++ netdev_err(ndev, "Unhandled interrupt!\n");
++ return IRQ_NONE;
++ }
++
++ return IRQ_HANDLED;
++}
++
++static int canfd_chip_start(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int err;
++ u8 ret;
++
++ err = set_reset_mode(ndev);
++ if (err) {
++ netdev_err(ndev, "Mode Resetting Failed!\n");
++ return err;
++ }
++
++ err = canfd_device_driver_bittime_configuration(ndev);
++ if (err) {
++ netdev_err(ndev, "Bittime Setting Failed!\n");
++ return err;
++ }
++
++ /* Set Almost Full Warning Limit */
++ canfd_reigister_set_bit(priv, CANFD_LIMIT_OFFSET, CAN_FD_SET_AFWL_MASK);
++
++ /* Programmable Error Warning Limit = (EWL+1)*8. Set EWL=11->Error Warning=96 */
++ canfd_reigister_set_bit(priv, CANFD_LIMIT_OFFSET, CAN_FD_SET_EWL_MASK);
++
++ /* Interrupts enable */
++ can_iowrite8(CAN_FD_INTR_ALL_MASK, priv->reg_base + CANFD_RTIE_OFFSET);
++
++ /* Error Interrupts enable(Error Passive and Bus Error) */
++ canfd_reigister_set_bit(priv, CANFD_ERRINT_OFFSET, CAN_FD_SET_EPIE_MASK);
++
++ ret = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ /* Check whether it is loopback mode or normal mode */
++ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
++ ret |= CAN_FD_LBMIMOD_MASK;
++ } else {
++ ret &= ~CAN_FD_LBMEMOD_MASK;
++ ret &= ~CAN_FD_LBMIMOD_MASK;
++ }
++
++ can_iowrite8(ret, priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ priv->can.state = CAN_STATE_ERROR_ACTIVE;
++
++ return 0;
++}
++
++static int canfd_do_set_mode(struct net_device *ndev, enum can_mode mode)
++{
++ int ret;
++
++ switch (mode) {
++ case CAN_MODE_START:
++ ret = canfd_chip_start(ndev);
++ if (ret) {
++ netdev_err(ndev, "Could Not Start CAN device !!\n");
++ return ret;
++ }
++ netif_wake_queue(ndev);
++ break;
++ default:
++ ret = -EOPNOTSUPP;
++ break;
++ }
++
++ return ret;
++}
++
++static int canfd_driver_open(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int ret;
++
++ ret = pm_runtime_get_sync(priv->dev);
++ if (ret < 0) {
++ netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
++ __func__, ret);
++ goto err;
++ }
++
++ /* Set chip into reset mode */
++ ret = set_reset_mode(ndev);
++ if (ret) {
++ netdev_err(ndev, "Mode Resetting Failed!\n");
++ return ret;
++ }
++
++ /* Common open */
++ ret = open_candev(ndev);
++ if (ret)
++ return ret;
++
++ /* Register interrupt handler */
++ ret = request_irq(ndev->irq, canfd_interrupt, IRQF_SHARED, ndev->name, ndev);
++ if (ret) {
++ netdev_err(ndev, "Request_irq err: %d\n", ret);
++ goto exit_irq;
++ }
++
++ ret = canfd_chip_start(ndev);
++ if (ret) {
++ netdev_err(ndev, "Could Not Start CAN device !\n");
++ goto exit_can_start;
++ }
++
++ napi_enable(&priv->napi);
++ netif_start_queue(ndev);
++
++ return 0;
++
++exit_can_start:
++ free_irq(ndev->irq, ndev);
++err:
++ pm_runtime_put(priv->dev);
++exit_irq:
++ close_candev(ndev);
++ return ret;
++}
++
++static int canfd_control_parse_dt(struct ipms_canfd_priv *priv)
++{
++ struct of_phandle_args args;
++ u32 syscon_mask, syscon_shift;
++ u32 can_or_canfd;
++ u32 syscon_offset, regval;
++ int ret;
++
++ ret = of_parse_phandle_with_fixed_args(priv->dev->of_node,
++ "starfive,sys-syscon", 3, 0, &args);
++ if (ret) {
++ dev_err(priv->dev, "Failed to parse starfive,sys-syscon\n");
++ return -EINVAL;
++ }
++
++ priv->reg_syscon = syscon_node_to_regmap(args.np);
++ of_node_put(args.np);
++ if (IS_ERR(priv->reg_syscon))
++ return PTR_ERR(priv->reg_syscon);
++
++ syscon_offset = args.args[0];
++ syscon_shift = args.args[1];
++ syscon_mask = args.args[2];
++
++ ret = device_property_read_u32(priv->dev, "syscon,can_or_canfd", &can_or_canfd);
++ if (ret)
++ goto exit_parse;
++
++ priv->can_or_canfd = can_or_canfd;
++
++ /* enable can2.0/canfd function */
++ regval = can_or_canfd << syscon_shift;
++ ret = regmap_update_bits(priv->reg_syscon, syscon_offset, syscon_mask, regval);
++ if (ret)
++ return ret;
++ return 0;
++exit_parse:
++ return ret;
++}
++
++static const struct net_device_ops canfd_netdev_ops = {
++ .ndo_open = canfd_driver_open,
++ .ndo_stop = canfd_driver_close,
++ .ndo_start_xmit = canfd_driver_start_xmit,
++ .ndo_change_mtu = can_change_mtu,
++};
++
++static int canfd_driver_probe(struct platform_device *pdev)
++{
++ struct net_device *ndev;
++ struct ipms_canfd_priv *priv;
++ void __iomem *addr;
++ int ret;
++ u32 frq;
++
++ addr = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(addr)) {
++ ret = PTR_ERR(addr);
++ goto exit;
++ }
++
++ ndev = alloc_candev(sizeof(struct ipms_canfd_priv), 1);
++ if (!ndev) {
++ ret = -ENOMEM;
++ goto exit;
++ }
++
++ priv = netdev_priv(ndev);
++ priv->dev = &pdev->dev;
++
++ ret = canfd_control_parse_dt(priv);
++ if (ret)
++ goto free_exit;
++
++ priv->nr_clks = devm_clk_bulk_get_all(priv->dev, &priv->clks);
++ if (priv->nr_clks < 0) {
++ dev_err(priv->dev, "Failed to get can clocks\n");
++ ret = -ENODEV;
++ goto free_exit;
++ }
++
++ ret = clk_bulk_prepare_enable(priv->nr_clks, priv->clks);
++ if (ret) {
++ dev_err(priv->dev, "Failed to enable clocks\n");
++ goto free_exit;
++ }
++
++ priv->resets = devm_reset_control_array_get_exclusive(priv->dev);
++ if (IS_ERR(priv->resets)) {
++ ret = PTR_ERR(priv->resets);
++ dev_err(priv->dev, "Failed to get can resets");
++ goto clk_exit;
++ }
++
++ ret = reset_control_deassert(priv->resets);
++ if (ret)
++ goto clk_exit;
++ priv->can.bittiming_const = &canfd_bittiming_const;
++ priv->can.data_bittiming_const = &canfd_data_bittiming_const;
++ priv->can.do_set_mode = canfd_do_set_mode;
++
++ /* in user space the execution mode can be chosen */
++ if (priv->can_or_canfd == IPMS_CAN_TYPE_CANFD)
++ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_FD;
++ else
++ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK;
++ priv->reg_base = addr;
++ priv->write_reg = canfd_write_reg_le;
++ priv->read_reg = canfd_read_reg_le;
++
++ pm_runtime_enable(&pdev->dev);
++
++ priv->can_clk = devm_clk_get(&pdev->dev, "core_clk");
++ if (IS_ERR(priv->can_clk)) {
++ dev_err(&pdev->dev, "Device clock not found.\n");
++ ret = PTR_ERR(priv->can_clk);
++ goto reset_exit;
++ }
++
++ device_property_read_u32(priv->dev, "frequency", &frq);
++ clk_set_rate(priv->can_clk, frq);
++
++ priv->can.clock.freq = clk_get_rate(priv->can_clk);
++ ndev->irq = platform_get_irq(pdev, 0);
++
++ /* we support local echo */
++ ndev->flags |= IFF_ECHO;
++ ndev->netdev_ops = &canfd_netdev_ops;
++
++ platform_set_drvdata(pdev, ndev);
++ SET_NETDEV_DEV(ndev, &pdev->dev);
++
++ netif_napi_add(ndev, &priv->napi, canfd_rx_poll);
++ ret = register_candev(ndev);
++ if (ret) {
++ dev_err(&pdev->dev, "Fail to register failed (err=%d)\n", ret);
++ goto reset_exit;
++ }
++
++ dev_dbg(&pdev->dev, "Driver registered: regs=%p, irp=%d, clock=%d\n",
++ priv->reg_base, ndev->irq, priv->can.clock.freq);
++
++ return 0;
++
++reset_exit:
++ reset_control_assert(priv->resets);
++clk_exit:
++ clk_bulk_disable_unprepare(priv->nr_clks, priv->clks);
++free_exit:
++ free_candev(ndev);
++exit:
++ return ret;
++}
++
++static int canfd_driver_remove(struct platform_device *pdev)
++{
++ struct net_device *ndev = platform_get_drvdata(pdev);
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ reset_control_assert(priv->resets);
++ clk_bulk_disable_unprepare(priv->nr_clks, priv->clks);
++ pm_runtime_disable(&pdev->dev);
++
++ unregister_candev(ndev);
++ netif_napi_del(&priv->napi);
++ free_candev(ndev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int __maybe_unused canfd_suspend(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++
++ if (netif_running(ndev)) {
++ netif_stop_queue(ndev);
++ netif_device_detach(ndev);
++ canfd_driver_stop(ndev);
++ }
++
++ return pm_runtime_force_suspend(dev);
++}
++
++static int __maybe_unused canfd_resume(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++ int ret;
++
++ ret = pm_runtime_force_resume(dev);
++ if (ret) {
++ dev_err(dev, "pm_runtime_force_resume failed on resume\n");
++ return ret;
++ }
++
++ if (netif_running(ndev)) {
++ ret = canfd_chip_start(ndev);
++ if (ret) {
++ dev_err(dev, "canfd_chip_start failed on resume\n");
++ return ret;
++ }
++
++ netif_device_attach(ndev);
++ netif_start_queue(ndev);
++ }
++
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_PM
++static int canfd_runtime_suspend(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ reset_control_assert(priv->resets);
++ clk_bulk_disable_unprepare(priv->nr_clks, priv->clks);
++
++ return 0;
++}
++
++static int canfd_runtime_resume(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int ret;
++
++ ret = clk_bulk_prepare_enable(priv->nr_clks, priv->clks);
++ if (ret) {
++ dev_err(dev, "Failed to prepare_enable clk\n");
++ return ret;
++ }
++
++ ret = reset_control_deassert(priv->resets);
++ if (ret) {
++ dev_err(dev, "Failed to deassert reset\n");
++ return ret;
++ }
++
++ return 0;
++}
++#endif
++
++static const struct dev_pm_ops canfd_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(canfd_suspend, canfd_resume)
++ SET_RUNTIME_PM_OPS(canfd_runtime_suspend,
++ canfd_runtime_resume, NULL)
++};
++
++static const struct of_device_id canfd_of_match[] = {
++ { .compatible = "ipms,can" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, canfd_of_match);
++
++static struct platform_driver can_driver = {
++ .probe = canfd_driver_probe,
++ .remove = canfd_driver_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .pm = &canfd_pm_ops,
++ .of_match_table = canfd_of_match,
++ },
++};
++
++module_platform_driver(can_driver);
++
++MODULE_DESCRIPTION("ipms can controller driver for StarFive jh7110 SoC");
++MODULE_AUTHOR("William Qiu<william.qiu@starfivetech.com");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch b/target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch
new file mode 100644
index 0000000000..cf1e62386d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch
@@ -0,0 +1,204 @@
+From b12213d474966fbf47e7afa36a6655b5b241cf36 Mon Sep 17 00:00:00 2001
+From: "Kevin.xie" <kevin.xie@starfivetech.com>
+Date: Fri, 9 Jun 2023 14:57:13 +0800
+Subject: [PATCH 071/116] regulator: starfive-jh7110: Add regulator support for
+ JH7110 A type EVB.
+
+Add 7 regulators base on regulator framework for
+JH7110 evb HW design.
+
+Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
+---
+ drivers/regulator/Kconfig | 10 ++
+ drivers/regulator/Makefile | 1 +
+ drivers/regulator/starfive-jh7110-regulator.c | 126 ++++++++++++++++++
+ include/linux/regulator/jh7110.h | 24 ++++
+ 4 files changed, 161 insertions(+)
+ create mode 100644 drivers/regulator/starfive-jh7110-regulator.c
+ create mode 100644 include/linux/regulator/jh7110.h
+
+--- a/drivers/regulator/Kconfig
++++ b/drivers/regulator/Kconfig
+@@ -1335,6 +1335,16 @@ config REGULATOR_SM5703
+ This driver provides support for voltage regulators of SM5703
+ multi-function device.
+
++config REGULATOR_STARFIVE_JH7110
++ tristate "Starfive JH7110 PMIC"
++ depends on I2C
++ select REGMAP_I2C
++ help
++ Say y here to select this option to enable the power regulator of
++ Starfive JH7110 PMIC.
++ This driver supports the control of different power rails of device
++ through regulator interface.
++
+ config REGULATOR_STM32_BOOSTER
+ tristate "STMicroelectronics STM32 BOOSTER"
+ depends on ARCH_STM32 || COMPILE_TEST
+--- a/drivers/regulator/Makefile
++++ b/drivers/regulator/Makefile
+@@ -156,6 +156,7 @@ obj-$(CONFIG_REGULATOR_SC2731) += sc2731
+ obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
+ obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
+ obj-$(CONFIG_REGULATOR_SM5703) += sm5703-regulator.o
++obj-$(CONFIG_REGULATOR_STARFIVE_JH7110) += starfive-jh7110-regulator.o
+ obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
+ obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
+ obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
+--- /dev/null
++++ b/drivers/regulator/starfive-jh7110-regulator.c
+@@ -0,0 +1,126 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2022 Starfive Technology Co., Ltd.
++ * Author: Mason Huo <mason.huo@starfivetech.com>
++ */
++
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/regmap.h>
++#include <linux/regulator/driver.h>
++#include <linux/regulator/machine.h>
++#include <linux/regulator/of_regulator.h>
++#include <linux/regulator/jh7110.h>
++#include <linux/slab.h>
++
++#define JH7110_PM_POWER_SW_0 0x80
++#define JH7110_PM_POWER_SW_1 0x81
++#define ENABLE_MASK(id) BIT(id)
++
++
++static const struct regmap_config jh7110_regmap_config = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .max_register = JH7110_PM_POWER_SW_1,
++ .cache_type = REGCACHE_FLAT,
++};
++
++static const struct regulator_ops jh7110_ldo_ops = {
++ .enable = regulator_enable_regmap,
++ .disable = regulator_disable_regmap,
++ .is_enabled = regulator_is_enabled_regmap,
++};
++
++#define JH7110_LDO(_id, _name, en_reg, en_mask) \
++{\
++ .name = (_name),\
++ .ops = &jh7110_ldo_ops,\
++ .of_match = of_match_ptr(_name),\
++ .regulators_node = of_match_ptr("regulators"),\
++ .type = REGULATOR_VOLTAGE,\
++ .id = JH7110_ID_##_id,\
++ .owner = THIS_MODULE,\
++ .enable_reg = JH7110_PM_POWER_SW_##en_reg,\
++ .enable_mask = ENABLE_MASK(en_mask),\
++}
++
++static const struct regulator_desc jh7110_regulators[] = {
++ JH7110_LDO(LDO_REG1, "hdmi_1p8", 0, 0),
++ JH7110_LDO(LDO_REG2, "mipitx_1p8", 0, 1),
++ JH7110_LDO(LDO_REG3, "mipirx_1p8", 0, 2),
++ JH7110_LDO(LDO_REG4, "hdmi_0p9", 0, 3),
++ JH7110_LDO(LDO_REG5, "mipitx_0p9", 0, 4),
++ JH7110_LDO(LDO_REG6, "mipirx_0p9", 0, 5),
++ JH7110_LDO(LDO_REG7, "sdio_vdd", 1, 0),
++};
++
++static int jh7110_i2c_probe(struct i2c_client *i2c)
++{
++ struct regulator_config config = { };
++ struct regulator_dev *rdev;
++ struct regulator_init_data *init_data;
++ struct regmap *regmap;
++ int i, ret;
++
++ regmap = devm_regmap_init_i2c(i2c, &jh7110_regmap_config);
++ if (IS_ERR(regmap)) {
++ ret = PTR_ERR(regmap);
++ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
++ ret);
++ return ret;
++ }
++
++ init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node, NULL);
++ if (!init_data)
++ return -ENOMEM;
++ config.init_data = init_data;
++
++ for (i = 0; i < JH7110_MAX_REGULATORS; i++) {
++ config.dev = &i2c->dev;
++ config.regmap = regmap;
++
++ rdev = devm_regulator_register(&i2c->dev,
++ &jh7110_regulators[i], &config);
++ if (IS_ERR(rdev)) {
++ dev_err(&i2c->dev,
++ "Failed to register JH7110 regulator\n");
++ return PTR_ERR(rdev);
++ }
++ }
++
++ return 0;
++}
++
++static const struct i2c_device_id jh7110_i2c_id[] = {
++ {"jh7110_evb_reg", 0},
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, jh7110_i2c_id);
++
++#ifdef CONFIG_OF
++static const struct of_device_id jh7110_dt_ids[] = {
++ { .compatible = "starfive,jh7110-evb-regulator",
++ .data = &jh7110_i2c_id[0] },
++ {},
++};
++MODULE_DEVICE_TABLE(of, jh7110_dt_ids);
++#endif
++
++static struct i2c_driver jh7110_regulator_driver = {
++ .driver = {
++ .name = "jh7110-evb-regulator",
++ .of_match_table = of_match_ptr(jh7110_dt_ids),
++ },
++ .probe = jh7110_i2c_probe,
++ .id_table = jh7110_i2c_id,
++};
++
++module_i2c_driver(jh7110_regulator_driver);
++
++MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
++MODULE_DESCRIPTION("Regulator device driver for Starfive JH7110");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/include/linux/regulator/jh7110.h
+@@ -0,0 +1,24 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (c) 2022 Starfive Technology Co., Ltd.
++ * Author: Mason Huo <mason.huo@starfivetech.com>
++ */
++
++#ifndef __LINUX_REGULATOR_JH7110_H
++#define __LINUX_REGULATOR_JH7110_H
++
++#define JH7110_MAX_REGULATORS 7
++
++
++enum jh7110_reg_id {
++ JH7110_ID_LDO_REG1 = 0,
++ JH7110_ID_LDO_REG2,
++ JH7110_ID_LDO_REG3,
++ JH7110_ID_LDO_REG4,
++ JH7110_ID_LDO_REG5,
++ JH7110_ID_LDO_REG6,
++ JH7110_ID_LDO_REG7,
++};
++
++
++#endif /* __LINUX_REGULATOR_JH7110_H */
diff --git a/target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch b/target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch
new file mode 100644
index 0000000000..d602df9e4c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch
@@ -0,0 +1,40 @@
+From f0b4cffe4d1813305f783d208f260747ecc56c50 Mon Sep 17 00:00:00 2001
+From: "Kevin.xie" <kevin.xie@starfivetech.com>
+Date: Thu, 24 Nov 2022 16:59:12 +0800
+Subject: [PATCH 072/116] drivers: nvme: Add precheck and delay for CQE pending
+ status.
+
+To workaroud the NVMe I/O timeout problem in bootup S10udev case
+which caused by the CQE update lantancy.
+
+Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
+---
+ drivers/nvme/host/pci.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -28,6 +28,7 @@
+ #include <linux/io-64-nonatomic-hi-lo.h>
+ #include <linux/sed-opal.h>
+ #include <linux/pci-p2pdma.h>
++#include <linux/delay.h>
+
+ #include "trace.h"
+ #include "nvme.h"
+@@ -1062,6 +1063,15 @@ static inline int nvme_poll_cq(struct nv
+ {
+ int found = 0;
+
++ /*
++ * In some cases, such as udev trigger, cqe status may update
++ * a little bit later than MSI, which cause an irq handle missing.
++ * To workaound, here we will prefetch the status first, and wait
++ * 1us if we get nothing.
++ */
++ if (!nvme_cqe_pending(nvmeq))
++ udelay(1);
++
+ while (nvme_cqe_pending(nvmeq)) {
+ found++;
+ /*
diff --git a/target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch b/target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch
new file mode 100644
index 0000000000..fff01c4c8f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch
@@ -0,0 +1,93 @@
+From eb294df4b9fab46bc5dbf676edf51e28e06d1968 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
+ <joao.mario@tecnico.ulisboa.pt>
+Date: Tue, 16 Nov 2021 15:48:09 +0000
+Subject: [PATCH 073/116] RISC-V: Create unique identification for SoC PMU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The SBI PMU platform driver did not provide any identification for
+perf events matching. This patch introduces a new sysfs file inside the
+platform device (soc:pmu/id) for pmu identification.
+
+The identification is a 64-bit value generated as:
+[63-32]: mvendorid;
+[31]: marchid[MSB];
+[30-16]: marchid[15-0];
+[15-0]: mimpid[15MSBs];
+
+The CSRs are detailed in the RISC-V privileged spec [1].
+The marchid is split in MSB + 15LSBs, due to the MSB being used for
+open-source architecture identification.
+
+[1] https://github.com/riscv/riscv-isa-manual
+
+Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
+---
+ drivers/perf/riscv_pmu_sbi.c | 47 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -1019,6 +1019,46 @@ static struct ctl_table sbi_pmu_sysctl_t
+ { }
+ };
+
++static uint64_t pmu_sbi_get_pmu_id(void)
++{
++ union sbi_pmu_id {
++ uint64_t value;
++ struct {
++ uint16_t imp:16;
++ uint16_t arch:16;
++ uint32_t vendor:32;
++ };
++ } pmuid;
++
++ pmuid.value = 0;
++ pmuid.vendor = (uint32_t) sbi_get_mvendorid();
++ pmuid.arch = (sbi_get_marchid() >> (63 - 15) & (1 << 15)) | (sbi_get_marchid() & 0x7FFF);
++ pmuid.imp = (sbi_get_mimpid() >> 16);
++
++ return pmuid.value;
++}
++
++static ssize_t pmu_sbi_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ int len;
++
++ len = sprintf(buf, "0x%llx\n", pmu_sbi_get_pmu_id());
++ if (len <= 0)
++ dev_err(dev, "mydrv: Invalid sprintf len: %dn", len);
++
++ return len;
++}
++
++static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, pmu_sbi_id_show, 0);
++
++static struct attribute *pmu_sbi_attrs[] = {
++ &dev_attr_id.attr,
++ NULL
++};
++
++ATTRIBUTE_GROUPS(pmu_sbi);
++
+ static int pmu_sbi_device_probe(struct platform_device *pdev)
+ {
+ struct riscv_pmu *pmu = NULL;
+@@ -1067,6 +1107,13 @@ static int pmu_sbi_device_probe(struct p
+ pmu->event_unmapped = pmu_sbi_event_unmapped;
+ pmu->csr_index = pmu_sbi_csr_index;
+
++ ret = sysfs_create_group(&pdev->dev.kobj, &pmu_sbi_group);
++ if (ret) {
++ dev_err(&pdev->dev, "sysfs creation failed\n");
++ return ret;
++ }
++ pdev->dev.groups = pmu_sbi_groups;
++
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
+ if (ret)
+ return ret;
diff --git a/target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch b/target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch
new file mode 100644
index 0000000000..177b3b32d8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch
@@ -0,0 +1,55 @@
+From 1dc069ffadf4ce7817a716f9df2f480254e9b01d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
+ <joao.mario@tecnico.ulisboa.pt>
+Date: Tue, 16 Nov 2021 15:48:10 +0000
+Subject: [PATCH 074/116] RISC-V: Support CPUID for risc-v in perf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch creates the header.c file for the risc-v architecture and introduces support for
+PMU identification through sysfs.
+It is now possible to configure pmu-events in risc-v.
+
+Depends on patch [1], that introduces the id sysfs file.
+
+Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
+Signed-off-by: minda.chen <minda.chen@starfivetech.com>
+---
+ drivers/perf/riscv_pmu.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/drivers/perf/riscv_pmu.c
++++ b/drivers/perf/riscv_pmu.c
+@@ -18,6 +18,23 @@
+
+ #include <asm/sbi.h>
+
++PMU_FORMAT_ATTR(event, "config:0-63");
++
++static struct attribute *riscv_arch_formats_attr[] = {
++ &format_attr_event.attr,
++ NULL,
++};
++
++static struct attribute_group riscv_pmu_format_group = {
++ .name = "format",
++ .attrs = riscv_arch_formats_attr,
++};
++
++static const struct attribute_group *riscv_pmu_attr_groups[] = {
++ &riscv_pmu_format_group,
++ NULL,
++};
++
+ static bool riscv_perf_user_access(struct perf_event *event)
+ {
+ return ((event->attr.type == PERF_TYPE_HARDWARE) ||
+@@ -410,6 +427,7 @@ struct riscv_pmu *riscv_pmu_alloc(void)
+ cpuc->events[i] = NULL;
+ }
+ pmu->pmu = (struct pmu) {
++ .attr_groups = riscv_pmu_attr_groups,
+ .event_init = riscv_pmu_event_init,
+ .event_mapped = riscv_pmu_event_mapped,
+ .event_unmapped = riscv_pmu_event_unmapped,
diff --git a/target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch b/target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch
new file mode 100644
index 0000000000..01bb4f19ca
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch
@@ -0,0 +1,42 @@
+From 3e6ea12dda276c01a756764fcafa315b19860c33 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
+ <joao.mario@tecnico.ulisboa.pt>
+Date: Tue, 16 Nov 2021 15:48:11 +0000
+Subject: [PATCH 075/116] RISC-V: Added generic pmu-events mapfile
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The pmu-events now supports custom events for RISC-V, plus the cycle,
+time and instret events were defined.
+
+Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
+---
+ .../pmu-events/arch/riscv/riscv-generic.json | 20 +++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+ create mode 100644 tools/perf/pmu-events/arch/riscv/riscv-generic.json
+
+--- /dev/null
++++ b/tools/perf/pmu-events/arch/riscv/riscv-generic.json
+@@ -0,0 +1,20 @@
++[
++ {
++ "PublicDescription": "CPU Cycles",
++ "EventCode": "0x00",
++ "EventName": "riscv_cycles",
++ "BriefDescription": "CPU cycles RISC-V generic counter"
++ },
++ {
++ "PublicDescription": "CPU Time",
++ "EventCode": "0x01",
++ "EventName": "riscv_time",
++ "BriefDescription": "CPU time RISC-V generic counter"
++ },
++ {
++ "PublicDescription": "CPU Instructions",
++ "EventCode": "0x02",
++ "EventName": "riscv_instret",
++ "BriefDescription": "CPU retired instructions RISC-V generic counter"
++ }
++]
+\ No newline at end of file
diff --git a/target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch b/target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch
new file mode 100644
index 0000000000..152a60cfda
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch
@@ -0,0 +1,30 @@
+From 30e0cdcf9e05faa65ecde4ed8b70039568fdb660 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 2 Mar 2023 17:16:01 +0800
+Subject: [PATCH 076/116] perf: sbi: disable cpu hotplug callback.
+
+register cpu hotplug callback will cause dhrystone
+and coremark benchmark reduce the scores. this CPU
+hotplug ops will do in sbi cpu/on and off. So disable
+this no side effect.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/perf/riscv_pmu_sbi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -1114,9 +1114,11 @@ static int pmu_sbi_device_probe(struct p
+ }
+ pdev->dev.groups = pmu_sbi_groups;
+
++#ifndef CONFIG_ARCH_STARFIVE
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
+ if (ret)
+ return ret;
++#endif
+
+ ret = riscv_pm_pmu_register(pmu);
+ if (ret)
diff --git a/target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch b/target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch
new file mode 100644
index 0000000000..cdc6e4ec26
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch
@@ -0,0 +1,24 @@
+From fc4b5c7c27e1b56b1f848e50511c4fd081b1b6c5 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Mon, 12 Jun 2023 21:21:45 +0800
+Subject: [PATCH 077/116] dmaengine: dw-axi-dmac: Drop unused print message
+
+Removed printing information which is not related to StarFive
+platform.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -523,7 +523,7 @@ static void dw_axi_dma_set_hw_channel(st
+ unsigned long reg_value, val;
+
+ if (!chip->apb_regs) {
+- dev_err(chip->dev, "apb_regs not initialized\n");
++ dev_dbg(chip->dev, "apb_regs not initialized\n");
+ return;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch b/target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch
new file mode 100644
index 0000000000..2a828974ce
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch
@@ -0,0 +1,4748 @@
+From cd2254c6be9441ebacaa35693ecb5ce116b90622 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Fri, 16 Jun 2023 16:27:46 +0800
+Subject: [PATCH 079/116] ASoC: codecs: Add AC108 Codec driver
+
+Add AC108 Codec driver and AC101 driver for AC10x.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/codecs/Kconfig | 5 +
+ sound/soc/codecs/Makefile | 2 +
+ sound/soc/codecs/ac101.c | 1716 +++++++++++++++++++++++++++++++++
+ sound/soc/codecs/ac101_regs.h | 431 +++++++++
+ sound/soc/codecs/ac108.c | 1622 +++++++++++++++++++++++++++++++
+ sound/soc/codecs/ac108.h | 749 ++++++++++++++
+ sound/soc/codecs/ac10x.h | 152 +++
+ 7 files changed, 4677 insertions(+)
+ create mode 100644 sound/soc/codecs/ac101.c
+ create mode 100644 sound/soc/codecs/ac101_regs.h
+ create mode 100644 sound/soc/codecs/ac108.c
+ create mode 100644 sound/soc/codecs/ac108.h
+ create mode 100644 sound/soc/codecs/ac10x.h
+
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -16,6 +16,7 @@ config SND_SOC_ALL_CODECS
+ depends on COMPILE_TEST
+ imply SND_SOC_88PM860X
+ imply SND_SOC_AB8500_CODEC
++ imply SND_SOC_AC108
+ imply SND_SOC_AC97_CODEC
+ imply SND_SOC_AD1836
+ imply SND_SOC_AD193X_SPI
+@@ -397,6 +398,10 @@ config SND_SOC_AB8500_CODEC
+ tristate
+ depends on ABX500_CORE
+
++config SND_SOC_AC108
++ tristate "AC108"
++ depends on I2C
++
+ config SND_SOC_AC97_CODEC
+ tristate "Build generic ASoC AC97 CODEC driver"
+ select SND_AC97_CODEC
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -2,6 +2,7 @@
+ snd-soc-88pm860x-objs := 88pm860x-codec.o
+ snd-soc-ab8500-codec-objs := ab8500-codec.o
+ snd-soc-ac97-objs := ac97.o
++snd-soc-ac108-objs := ac108.o ac101.o
+ snd-soc-ad1836-objs := ad1836.o
+ snd-soc-ad193x-objs := ad193x.o
+ snd-soc-ad193x-spi-objs := ad193x-spi.o
+@@ -386,6 +387,7 @@ snd-soc-simple-mux-objs := simple-mux.o
+
+ obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
+ obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
++obj-$(CONFIG_SND_SOC_AC108) += snd-soc-ac108.o
+ obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
+ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
+ obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
+--- /dev/null
++++ b/sound/soc/codecs/ac101.c
+@@ -0,0 +1,1716 @@
++/*
++ * ac101.c
++ *
++ * (C) Copyright 2017-2018
++ * Seeed Technology Co., Ltd. <www.seeedstudio.com>
++ *
++ * PeterYang <linsheng.yang@seeed.cc>
++ *
++ * (C) Copyright 2014-2017
++ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
++ *
++ * huangxin <huangxin@Reuuimllatech.com>
++ * liushaohua <liushaohua@allwinnertech.com>
++ *
++ * X-Powers AC101 codec driver
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/input.h>
++#include <linux/irq.h>
++#include <linux/module.h>
++#include <linux/regmap.h>
++#include <sound/tlv.h>
++#include <linux/workqueue.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include "ac101_regs.h"
++#include "ac10x.h"
++
++/* #undef AC101_DEBG
++ * use 'make DEBUG=1' to enable debugging
++ */
++
++/*
++ * *** To sync channels ***
++ *
++ * 1. disable clock in codec hw_params()
++ * 2. clear fifo in bcm2835 hw_params()
++ * 3. clear fifo in bcm2385 prepare()
++ * 4. enable RX in bcm2835 trigger()
++ * 5. enable clock in machine trigger()
++ */
++
++/*Default initialize configuration*/
++static bool speaker_double_used = 1;
++static int double_speaker_val = 0x1B;
++static int single_speaker_val = 0x19;
++static int headset_val = 0x3B;
++static int mainmic_val = 0x4;
++static int headsetmic_val = 0x4;
++static bool dmic_used = 0;
++static int adc_digital_val = 0xb0b0;
++static bool drc_used = false;
++
++#define AC101_RATES (SNDRV_PCM_RATE_8000_96000 & \
++ ~(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_64000 | \
++ SNDRV_PCM_RATE_88200))
++#define AC101_FORMATS (/*SNDRV_PCM_FMTBIT_S16_LE | \
++ SNDRV_PCM_FMTBIT_S24_LE |*/ \
++ SNDRV_PCM_FMTBIT_S32_LE | \
++ 0)
++
++static struct ac10x_priv* static_ac10x;
++
++
++int ac101_read(struct snd_soc_codec *codec, unsigned reg) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int r, v = 0;
++
++ if ((r = regmap_read(ac10x->regmap101, reg, &v)) < 0) {
++ dev_err(codec->dev, "read reg %02X fail\n",
++ reg);
++ return r;
++ }
++ return v;
++}
++
++int ac101_write(struct snd_soc_codec *codec, unsigned reg, unsigned val) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int v;
++
++ v = regmap_write(ac10x->regmap101, reg, val);
++ return v;
++}
++
++int ac101_update_bits(struct snd_soc_codec *codec, unsigned reg,
++ unsigned mask, unsigned value
++) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int v;
++
++ v = regmap_update_bits(ac10x->regmap101, reg, mask, value);
++ return v;
++}
++
++
++
++#ifdef CONFIG_AC101_SWITCH_DETECT
++/******************************************************************************/
++/********************************switch****************************************/
++/******************************************************************************/
++#define KEY_HEADSETHOOK 226 /* key define */
++#define HEADSET_FILTER_CNT (10)
++
++/*
++ * switch_hw_config:config the 53 codec register
++ */
++static void switch_hw_config(struct snd_soc_codec *codec)
++{
++ int r;
++
++ AC101_DBG();
++
++ /*HMIC/MMIC BIAS voltage level select:2.5v*/
++ ac101_update_bits(codec, OMIXER_BST1_CTRL, (0xf<<BIASVOLTAGE), (0xf<<BIASVOLTAGE));
++ /*debounce when Key down or keyup*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0xf<<HMIC_M), (0x0<<HMIC_M));
++ /*debounce when earphone plugin or pullout*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0xf<<HMIC_N), (0x0<<HMIC_N));
++ /*Down Sample Setting Select: Downby 4,32Hz*/
++ ac101_update_bits(codec, HMIC_CTRL2, (0x3<<HMIC_SAMPLE_SELECT),
++ (0x02<<HMIC_SAMPLE_SELECT));
++ /*Hmic_th2 for detecting Keydown or Keyup.*/
++ ac101_update_bits(codec, HMIC_CTRL2, (0x1f<<HMIC_TH2), (0x8<<HMIC_TH2));
++ /*Hmic_th1[4:0],detecting eraphone plugin or pullout*/
++ ac101_update_bits(codec, HMIC_CTRL2, (0x1f<<HMIC_TH1), (0x1<<HMIC_TH1));
++ /*Headset microphone BIAS working mode: when HBIASEN = 1 */
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASMOD), (0x1<<HBIASMOD));
++ /*Headset microphone BIAS Enable*/
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASEN), (0x1<<HBIASEN));
++ /*Headset microphone BIAS Current sensor & ADC Enable*/
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASADCEN), (0x1<<HBIASADCEN));
++ /*Earphone Plugin/out Irq Enable*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_PULLOUT_IRQ), (0x1<<HMIC_PULLOUT_IRQ));
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_PLUGIN_IRQ), (0x1<<HMIC_PLUGIN_IRQ));
++
++ /*Hmic KeyUp/key down Irq Enable*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_KEYDOWN_IRQ), (0x1<<HMIC_KEYDOWN_IRQ));
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_KEYUP_IRQ), (0x1<<HMIC_KEYUP_IRQ));
++
++ /*headphone calibration clock frequency select*/
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x7<<HPCALICKS), (0x7<<HPCALICKS));
++
++ /*clear hmic interrupt */
++ r = HMIC_PEND_ALL;
++ ac101_write(codec, HMIC_STS, r);
++
++ return;
++}
++
++/*
++ * switch_status_update: update the switch state.
++ */
++static void switch_status_update(struct ac10x_priv *ac10x)
++{
++ AC101_DBG("ac10x->state:%d\n", ac10x->state);
++
++ input_report_switch(ac10x->inpdev, SW_HEADPHONE_INSERT, ac10x->state);
++ input_sync(ac10x->inpdev);
++ return;
++}
++
++/*
++ * work_cb_clear_irq: clear audiocodec pending and Record the interrupt.
++ */
++static void work_cb_clear_irq(struct work_struct *work)
++{
++ int reg_val = 0;
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, work_clear_irq);
++ struct snd_soc_codec *codec = ac10x->codec;
++
++ ac10x->irq_cntr++;
++
++ reg_val = ac101_read(codec, HMIC_STS);
++ if (BIT(HMIC_PULLOUT_PEND) & reg_val) {
++ ac10x->pullout_cntr++;
++ AC101_DBG("ac10x->pullout_cntr: %d\n", ac10x->pullout_cntr);
++ }
++
++ reg_val |= HMIC_PEND_ALL;
++ ac101_write(codec, HMIC_STS, reg_val);
++
++ reg_val = ac101_read(codec, HMIC_STS);
++ if ((reg_val & HMIC_PEND_ALL) != 0){
++ reg_val |= HMIC_PEND_ALL;
++ ac101_write(codec, HMIC_STS, reg_val);
++ }
++
++ if (cancel_work_sync(&ac10x->work_switch) != 0) {
++ ac10x->irq_cntr--;
++ }
++
++ if (0 == schedule_work(&ac10x->work_switch)) {
++ ac10x->irq_cntr--;
++ AC101_DBG("[work_cb_clear_irq] add work struct failed!\n");
++ }
++}
++
++enum {
++ HBIAS_LEVEL_1 = 0x02,
++ HBIAS_LEVEL_2 = 0x0B,
++ HBIAS_LEVEL_3 = 0x13,
++ HBIAS_LEVEL_4 = 0x17,
++ HBIAS_LEVEL_5 = 0x19,
++};
++
++static int __ac101_get_hmic_data(struct snd_soc_codec *codec) {
++ #ifdef AC101_DEBG
++ static long counter;
++ #endif
++ int r, d;
++
++ d = GET_HMIC_DATA(ac101_read(codec, HMIC_STS));
++
++ r = 0x1 << HMIC_DATA_PEND;
++ ac101_write(codec, HMIC_STS, r);
++
++ /* prevent i2c accessing too frequently */
++ usleep_range(1500, 3000);
++
++ AC101_DBG("HMIC_DATA(%3ld): %02X\n", counter++, d);
++ return d;
++}
++
++/*
++ * work_cb_earphone_switch: judge the status of the headphone
++ */
++static void work_cb_earphone_switch(struct work_struct *work)
++{
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, work_switch);
++ struct snd_soc_codec *codec = ac10x->codec;
++
++ static int hook_flag1 = 0, hook_flag2 = 0;
++ static int KEY_VOLUME_FLAG = 0;
++
++ unsigned filter_buf = 0;
++ int filt_index = 0;
++ int t = 0;
++
++ ac10x->irq_cntr--;
++
++ /* read HMIC_DATA */
++ t = __ac101_get_hmic_data(codec);
++
++ if ((t >= HBIAS_LEVEL_2) && (ac10x->mode == FOUR_HEADPHONE_PLUGIN)) {
++ t = __ac101_get_hmic_data(codec);
++
++ if (t >= HBIAS_LEVEL_5){
++ msleep(150);
++ t = __ac101_get_hmic_data(codec);
++ if (((t < HBIAS_LEVEL_2 && t >= HBIAS_LEVEL_1 - 1) || t >= HBIAS_LEVEL_5)
++ && (ac10x->pullout_cntr == 0)) {
++ input_report_key(ac10x->inpdev, KEY_HEADSETHOOK, 1);
++ input_sync(ac10x->inpdev);
++
++ AC101_DBG("KEY_HEADSETHOOK1\n");
++
++ if (hook_flag1 != hook_flag2)
++ hook_flag1 = hook_flag2 = 0;
++ hook_flag1++;
++ }
++ if (ac10x->pullout_cntr)
++ ac10x->pullout_cntr--;
++ } else if (t >= HBIAS_LEVEL_4) {
++ msleep(80);
++ t = __ac101_get_hmic_data(codec);
++ if (t < HBIAS_LEVEL_5 && t >= HBIAS_LEVEL_4 && (ac10x->pullout_cntr == 0)) {
++ KEY_VOLUME_FLAG = 1;
++ input_report_key(ac10x->inpdev, KEY_VOLUMEUP, 1);
++ input_sync(ac10x->inpdev);
++ input_report_key(ac10x->inpdev, KEY_VOLUMEUP, 0);
++ input_sync(ac10x->inpdev);
++
++ AC101_DBG("HMIC_DATA: %d KEY_VOLUMEUP\n", t);
++ }
++ if (ac10x->pullout_cntr)
++ ac10x->pullout_cntr--;
++ } else if (t >= HBIAS_LEVEL_3){
++ msleep(80);
++ t = __ac101_get_hmic_data(codec);
++ if (t < HBIAS_LEVEL_4 && t >= HBIAS_LEVEL_3 && (ac10x->pullout_cntr == 0)) {
++ KEY_VOLUME_FLAG = 1;
++ input_report_key(ac10x->inpdev, KEY_VOLUMEDOWN, 1);
++ input_sync(ac10x->inpdev);
++ input_report_key(ac10x->inpdev, KEY_VOLUMEDOWN, 0);
++ input_sync(ac10x->inpdev);
++ AC101_DBG("KEY_VOLUMEDOWN\n");
++ }
++ if (ac10x->pullout_cntr)
++ ac10x->pullout_cntr--;
++ }
++ } else if ((t < HBIAS_LEVEL_2 && t >= HBIAS_LEVEL_1) &&
++ (ac10x->mode == FOUR_HEADPHONE_PLUGIN)) {
++ t = __ac101_get_hmic_data(codec);
++ if (t < HBIAS_LEVEL_2 && t >= HBIAS_LEVEL_1) {
++ if (KEY_VOLUME_FLAG) {
++ KEY_VOLUME_FLAG = 0;
++ }
++ if (hook_flag1 == (++hook_flag2)) {
++ hook_flag1 = hook_flag2 = 0;
++ input_report_key(ac10x->inpdev, KEY_HEADSETHOOK, 0);
++ input_sync(ac10x->inpdev);
++
++ AC101_DBG("KEY_HEADSETHOOK0\n");
++ }
++ }
++ } else {
++ while (ac10x->irq_cntr == 0 && ac10x->irq != 0) {
++ msleep(20);
++
++ t = __ac101_get_hmic_data(codec);
++
++ if (filt_index <= HEADSET_FILTER_CNT) {
++ if (filt_index++ == 0) {
++ filter_buf = t;
++ } else if (filter_buf != t) {
++ filt_index = 0;
++ }
++ continue;
++ }
++
++ filt_index = 0;
++ if (filter_buf >= HBIAS_LEVEL_2) {
++ ac10x->mode = THREE_HEADPHONE_PLUGIN;
++ ac10x->state = 2;
++ } else if (filter_buf >= HBIAS_LEVEL_1 - 1) {
++ ac10x->mode = FOUR_HEADPHONE_PLUGIN;
++ ac10x->state = 1;
++ } else {
++ ac10x->mode = HEADPHONE_IDLE;
++ ac10x->state = 0;
++ }
++ switch_status_update(ac10x);
++ ac10x->pullout_cntr = 0;
++ break;
++ }
++ }
++}
++
++/*
++ * audio_hmic_irq: the interrupt handlers
++ */
++static irqreturn_t audio_hmic_irq(int irq, void *para)
++{
++ struct ac10x_priv *ac10x = (struct ac10x_priv *)para;
++ if (ac10x == NULL) {
++ return -EINVAL;
++ }
++
++ if (0 == schedule_work(&ac10x->work_clear_irq)){
++ AC101_DBG("[audio_hmic_irq] work already in queue_codec_irq, adding failed!\n");
++ }
++ return IRQ_HANDLED;
++}
++
++static int ac101_switch_probe(struct ac10x_priv *ac10x) {
++ struct i2c_client *i2c = ac10x->i2c101;
++ long ret;
++
++ ac10x->gpiod_irq = devm_gpiod_get_optional(&i2c->dev, "switch-irq", GPIOD_IN);
++ if (IS_ERR(ac10x->gpiod_irq)) {
++ ac10x->gpiod_irq = NULL;
++ dev_err(&i2c->dev, "failed get switch-irq in device tree\n");
++ goto _err_irq;
++ }
++
++ gpiod_direction_input(ac10x->gpiod_irq);
++
++ ac10x->irq = gpiod_to_irq(ac10x->gpiod_irq);
++ if (IS_ERR_VALUE(ac10x->irq)) {
++ pr_info("[ac101] map gpio to irq failed, errno = %ld\n", ac10x->irq);
++ ac10x->irq = 0;
++ goto _err_irq;
++ }
++
++ /* request irq, set irq type to falling edge trigger */
++ ret = devm_request_irq(ac10x->codec->dev, ac10x->irq, audio_hmic_irq,
++ IRQF_TRIGGER_FALLING, "SWTICH_EINT", ac10x);
++ if (IS_ERR_VALUE(ret)) {
++ pr_info("[ac101] request virq %ld failed, errno = %ld\n", ac10x->irq, ret);
++ goto _err_irq;
++ }
++
++ ac10x->mode = HEADPHONE_IDLE;
++ ac10x->state = -1;
++
++ /*use for judge the state of switch*/
++ INIT_WORK(&ac10x->work_switch, work_cb_earphone_switch);
++ INIT_WORK(&ac10x->work_clear_irq, work_cb_clear_irq);
++
++ /********************create input device************************/
++ ac10x->inpdev = devm_input_allocate_device(ac10x->codec->dev);
++ if (!ac10x->inpdev) {
++ AC101_DBG("input_allocate_device: not enough memory for input device\n");
++ ret = -ENOMEM;
++ goto _err_input_allocate_device;
++ }
++
++ ac10x->inpdev->name = "seed-voicecard-headset";
++ ac10x->inpdev->phys = dev_name(ac10x->codec->dev);
++ ac10x->inpdev->id.bustype = BUS_I2C;
++ ac10x->inpdev->dev.parent = ac10x->codec->dev;
++ input_set_drvdata(ac10x->inpdev, ac10x->codec);
++
++ ac10x->inpdev->evbit[0] = BIT_MASK(EV_KEY) | BIT(EV_SW);
++
++ set_bit(KEY_HEADSETHOOK, ac10x->inpdev->keybit);
++ set_bit(KEY_VOLUMEUP, ac10x->inpdev->keybit);
++ set_bit(KEY_VOLUMEDOWN, ac10x->inpdev->keybit);
++ input_set_capability(ac10x->inpdev, EV_SW, SW_HEADPHONE_INSERT);
++
++ ret = input_register_device(ac10x->inpdev);
++ if (ret) {
++ AC101_DBG("input_register_device: input_register_device failed\n");
++ goto _err_input_register_device;
++ }
++
++ /* the first headset state checking */
++ switch_hw_config(ac10x->codec);
++ ac10x->irq_cntr = 1;
++ schedule_work(&ac10x->work_switch);
++
++ return 0;
++
++_err_input_register_device:
++_err_input_allocate_device:
++
++ if (ac10x->irq) {
++ devm_free_irq(&i2c->dev, ac10x->irq, ac10x);
++ ac10x->irq = 0;
++ }
++_err_irq:
++ return ret;
++}
++/******************************************************************************/
++/********************************switch****************************************/
++/******************************************************************************/
++#endif
++
++
++
++void drc_config(struct snd_soc_codec *codec)
++{
++ int reg_val;
++ reg_val = ac101_read(codec, 0xa3);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= 1<<0;
++ ac101_write(codec, 0xa3, reg_val);
++ ac101_write(codec, 0xa4, 0x2baf);
++
++ reg_val = ac101_read(codec, 0xa5);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= 1<<0;
++ ac101_write(codec, 0xa5, reg_val);
++ ac101_write(codec, 0xa6, 0x2baf);
++
++ reg_val = ac101_read(codec, 0xa7);
++ reg_val &= ~(0x7ff<<0);
++ ac101_write(codec, 0xa7, reg_val);
++ ac101_write(codec, 0xa8, 0x44a);
++
++ reg_val = ac101_read(codec, 0xa9);
++ reg_val &= ~(0x7ff<<0);
++ ac101_write(codec, 0xa9, reg_val);
++ ac101_write(codec, 0xaa, 0x1e06);
++
++ reg_val = ac101_read(codec, 0xab);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= (0x352<<0);
++ ac101_write(codec, 0xab, reg_val);
++ ac101_write(codec, 0xac, 0x6910);
++
++ reg_val = ac101_read(codec, 0xad);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= (0x77a<<0);
++ ac101_write(codec, 0xad, reg_val);
++ ac101_write(codec, 0xae, 0xaaaa);
++
++ reg_val = ac101_read(codec, 0xaf);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= (0x2de<<0);
++ ac101_write(codec, 0xaf, reg_val);
++ ac101_write(codec, 0xb0, 0xc982);
++
++ ac101_write(codec, 0x16, 0x9f9f);
++
++}
++
++void drc_enable(struct snd_soc_codec *codec,bool on)
++{
++ int reg_val;
++ if (on) {
++ ac101_write(codec, 0xb5, 0xA080);
++ reg_val = ac101_read(codec, MOD_CLK_ENA);
++ reg_val |= (0x1<<6);
++ ac101_write(codec, MOD_CLK_ENA, reg_val);
++ reg_val = ac101_read(codec, MOD_RST_CTRL);
++ reg_val |= (0x1<<6);
++ ac101_write(codec, MOD_RST_CTRL, reg_val);
++
++ reg_val = ac101_read(codec, 0xa0);
++ reg_val |= (0x7<<0);
++ ac101_write(codec, 0xa0, reg_val);
++ } else {
++ ac101_write(codec, 0xb5, 0x0);
++ reg_val = ac101_read(codec, MOD_CLK_ENA);
++ reg_val &= ~(0x1<<6);
++ ac101_write(codec, MOD_CLK_ENA, reg_val);
++ reg_val = ac101_read(codec, MOD_RST_CTRL);
++ reg_val &= ~(0x1<<6);
++ ac101_write(codec, MOD_RST_CTRL, reg_val);
++
++ reg_val = ac101_read(codec, 0xa0);
++ reg_val &= ~(0x7<<0);
++ ac101_write(codec, 0xa0, reg_val);
++ }
++}
++
++void set_configuration(struct snd_soc_codec *codec)
++{
++ if (speaker_double_used) {
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1f<<SPK_VOL),
++ (double_speaker_val<<SPK_VOL));
++ } else {
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1f<<SPK_VOL),
++ (single_speaker_val<<SPK_VOL));
++ }
++ ac101_update_bits(codec, HPOUT_CTRL, (0x3f<<HP_VOL), (headset_val<<HP_VOL));
++ ac101_update_bits(codec, ADC_SRCBST_CTRL, (0x7<<ADC_MIC1G), (mainmic_val<<ADC_MIC1G));
++ ac101_update_bits(codec, ADC_SRCBST_CTRL, (0x7<<ADC_MIC2G), (headsetmic_val<<ADC_MIC2G));
++ if (dmic_used) {
++ ac101_write(codec, ADC_VOL_CTRL, adc_digital_val);
++ }
++ if (drc_used) {
++ drc_config(codec);
++ }
++ /*headphone calibration clock frequency select*/
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x7<<HPCALICKS), (0x7<<HPCALICKS));
++
++ /* I2S1 DAC Timeslot 0 data <- I2S1 DAC channel 0 */
++ // "AIF1IN0L Mux" <= "AIF1DACL"
++ // "AIF1IN0R Mux" <= "AIF1DACR"
++ ac101_update_bits(codec, AIF1_DACDAT_CTRL, 0x3 << AIF1_DA0L_SRC, 0x0 << AIF1_DA0L_SRC);
++ ac101_update_bits(codec, AIF1_DACDAT_CTRL, 0x3 << AIF1_DA0R_SRC, 0x0 << AIF1_DA0R_SRC);
++ /* Timeslot 0 Left & Right Channel enable */
++ ac101_update_bits(codec, AIF1_DACDAT_CTRL, 0x3 << AIF1_DA0R_ENA, 0x3 << AIF1_DA0R_ENA);
++
++ /* DAC Digital Mixer Source Select <- I2S1 DA0 */
++ // "DACL Mixer" += "AIF1IN0L Mux"
++ // "DACR Mixer" += "AIF1IN0R Mux"
++ ac101_update_bits(codec, DAC_MXR_SRC, 0xF << DACL_MXR_ADCL, 0x8 << DACL_MXR_ADCL);
++ ac101_update_bits(codec, DAC_MXR_SRC, 0xF << DACR_MXR_ADCR, 0x8 << DACR_MXR_ADCR);
++ /* Internal DAC Analog Left & Right Channel enable */
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, 0x3 << DACALEN, 0x3 << DACALEN);
++
++ /* Output Mixer Source Select */
++ // "Left Output Mixer" += "DACL Mixer"
++ // "Right Output Mixer" += "DACR Mixer"
++ ac101_update_bits(codec, OMIXER_SR, 0x1 << LMIXMUTEDACL, 0x1 << LMIXMUTEDACL);
++ ac101_update_bits(codec, OMIXER_SR, 0x1 << RMIXMUTEDACR, 0x1 << RMIXMUTEDACR);
++ /* Left & Right Analog Output Mixer enable */
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, 0x3 << LMIXEN, 0x3 << LMIXEN);
++
++ /* Headphone Ouput Control */
++ // "HP_R Mux" <= "DACR Mixer"
++ // "HP_L Mux" <= "DACL Mixer"
++ ac101_update_bits(codec, HPOUT_CTRL, 0x1 << LHPS, 0x0 << LHPS);
++ ac101_update_bits(codec, HPOUT_CTRL, 0x1 << RHPS, 0x0 << RHPS);
++
++ /* Speaker Output Control */
++ // "SPK_L Mux" <= "SPK_LR Adder"
++ // "SPK_R Mux" <= "SPK_LR Adder"
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPKS) | (0x1 << RSPKS),
++ (0x1 << LSPKS) | (0x1 << RSPKS));
++ /* Enable Left & Right Speaker */
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPK_EN) | (0x1 << RSPK_EN),
++ (0x1 << LSPK_EN) | (0x1 << RSPK_EN));
++ return;
++}
++
++static int late_enable_dac(struct snd_soc_codec* codec, int event) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ mutex_lock(&ac10x->dac_mutex);
++ switch (event) {
++ case SND_SOC_DAPM_PRE_PMU:
++ AC101_DBG();
++ if (ac10x->dac_enable == 0){
++ /*enable dac module clk*/
++ ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG),
++ (0x1<<MOD_CLK_DAC_DIG));
++ ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_DAC_DIG),
++ (0x1<<MOD_RESET_DAC_DIG));
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x1<<ENDA));
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENHPF),(0x1<<ENHPF));
++ }
++ ac10x->dac_enable++;
++ break;
++ case SND_SOC_DAPM_POST_PMD:
++ if (ac10x->dac_enable != 0){
++ ac10x->dac_enable = 0;
++
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENHPF),(0x0<<ENHPF));
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x0<<ENDA));
++ /*disable dac module clk*/
++ ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG),
++ (0x0<<MOD_CLK_DAC_DIG));
++ ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_DAC_DIG),
++ (0x0<<MOD_RESET_DAC_DIG));
++ }
++ break;
++ }
++ mutex_unlock(&ac10x->dac_mutex);
++ return 0;
++}
++
++static int ac101_headphone_event(struct snd_soc_codec* codec, int event) {
++ switch (event) {
++ case SND_SOC_DAPM_POST_PMU:
++ /*open*/
++ AC101_DBG("post:open\n");
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, (0xf<<HPOUTPUTENABLE),
++ (0xf<<HPOUTPUTENABLE));
++ msleep(10);
++ ac101_update_bits(codec, HPOUT_CTRL, (0x1<<HPPA_EN), (0x1<<HPPA_EN));
++ ac101_update_bits(codec, HPOUT_CTRL, (0x3<<LHPPA_MUTE), (0x3<<LHPPA_MUTE));
++ break;
++ case SND_SOC_DAPM_PRE_PMD:
++ /*close*/
++ AC101_DBG("pre:close\n");
++ ac101_update_bits(codec, HPOUT_CTRL, (0x3<<LHPPA_MUTE), (0x0<<LHPPA_MUTE));
++ msleep(10);
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, (0xf<<HPOUTPUTENABLE),
++ (0x0<<HPOUTPUTENABLE));
++ ac101_update_bits(codec, HPOUT_CTRL, (0x1<<HPPA_EN), (0x0<<HPPA_EN));
++ break;
++ }
++ return 0;
++}
++
++static int ac101_sysclk_started(void) {
++ int reg_val;
++
++ reg_val = ac101_read(static_ac10x->codec, SYSCLK_CTRL);
++ return (reg_val & (0x1<<SYSCLK_ENA));
++}
++
++static int ac101_aif1clk(struct snd_soc_codec* codec, int event, int quick) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int ret = 0;
++
++ switch (event) {
++ case SND_SOC_DAPM_PRE_PMU:
++ if (ac10x->aif1_clken == 0){
++ ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA),
++ (0x1<<AIF1CLK_ENA));
++ if(!quick || _MASTER_MULTI_CODEC != _MASTER_AC101) {
++ /* enable aif1clk & sysclk */
++ ret = ret || ac101_update_bits(codec, MOD_CLK_ENA,
++ (0x1<<MOD_CLK_AIF1),
++ (0x1<<MOD_CLK_AIF1));
++ ret = ret || ac101_update_bits(codec, MOD_RST_CTRL,
++ (0x1<<MOD_RESET_AIF1),
++ (0x1<<MOD_RESET_AIF1));
++ }
++ ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA),
++ (0x1<<SYSCLK_ENA));
++
++ if (ret) {
++ AC101_DBG("start sysclk failed\n");
++ } else {
++ AC101_DBG("hw sysclk enable\n");
++ ac10x->aif1_clken++;
++ }
++ }
++ break;
++ case SND_SOC_DAPM_POST_PMD:
++ if (ac10x->aif1_clken != 0) {
++ /* disable aif1clk & sysclk */
++ ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA),
++ (0x0<<AIF1CLK_ENA));
++ ret = ret || ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_AIF1),
++ (0x0<<MOD_CLK_AIF1));
++ ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1),
++ (0x0<<MOD_RESET_AIF1));
++ ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA),
++ (0x0<<SYSCLK_ENA));
++
++ if (ret) {
++ AC101_DBG("stop sysclk failed\n");
++ } else {
++ AC101_DBG("hw sysclk disable\n");
++ ac10x->aif1_clken = 0;
++ }
++ break;
++ }
++ }
++
++ AC101_DBG("event=%d pre_up/%d post_down/%d\n", event, SND_SOC_DAPM_PRE_PMU,
++ SND_SOC_DAPM_POST_PMD);
++
++ return ret;
++}
++
++/**
++ * snd_ac101_get_volsw - single mixer get callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to get the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac101_get_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol
++){
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int val, mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret;
++
++ if ((ret = ac101_read(static_ac10x->codec, mc->reg)) < 0)
++ return ret;
++
++ val = (ret >> mc->shift) & mask;
++ ucontrol->value.integer.value[0] = val - mc->min;
++ if (invert) {
++ ucontrol->value.integer.value[0] =
++ mc->max - ucontrol->value.integer.value[0];
++ }
++
++ if (snd_soc_volsw_is_stereo(mc)) {
++ val = (ret >> mc->rshift) & mask;
++ ucontrol->value.integer.value[1] = val - mc->min;
++ if (invert) {
++ ucontrol->value.integer.value[1] =
++ mc->max - ucontrol->value.integer.value[1];
++ }
++ }
++ return 0;
++}
++
++/**
++ * snd_ac101_put_volsw - single mixer put callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to set the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac101_put_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol
++){
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int sign_bit = mc->sign_bit;
++ unsigned int val, mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret;
++
++ if (sign_bit)
++ mask = BIT(sign_bit + 1) - 1;
++
++ val = ((ucontrol->value.integer.value[0] + mc->min) & mask);
++ if (invert) {
++ val = mc->max - val;
++ }
++
++ ret = ac101_update_bits(static_ac10x->codec, mc->reg, mask << mc->shift, val << mc->shift);
++
++ if (! snd_soc_volsw_is_stereo(mc)) {
++ return ret;
++ }
++ val = ((ucontrol->value.integer.value[1] + mc->min) & mask);
++ if (invert) {
++ val = mc->max - val;
++ }
++
++ ret = ac101_update_bits(static_ac10x->codec, mc->reg, mask << mc->rshift,
++ val << mc->rshift);
++ return ret;
++}
++
++
++static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -11925, 75, 0);
++static const DECLARE_TLV_DB_SCALE(dac_mix_vol_tlv, -600, 600, 0);
++static const DECLARE_TLV_DB_SCALE(dig_vol_tlv, -7308, 116, 0);
++static const DECLARE_TLV_DB_SCALE(speaker_vol_tlv, -4800, 150, 0);
++static const DECLARE_TLV_DB_SCALE(headphone_vol_tlv, -6300, 100, 0);
++
++static struct snd_kcontrol_new ac101_controls[] = {
++ /*DAC*/
++ SOC_DOUBLE_TLV("DAC volume", DAC_VOL_CTRL, DAC_VOL_L, DAC_VOL_R, 0xff, 0, dac_vol_tlv),
++ SOC_DOUBLE_TLV("DAC mixer gain", DAC_MXR_GAIN, DACL_MXR_GAIN, DACR_MXR_GAIN,
++ 0xf, 0, dac_mix_vol_tlv),
++ SOC_SINGLE_TLV("digital volume", DAC_DBG_CTRL, DVC, 0x3f, 1, dig_vol_tlv),
++ SOC_SINGLE_TLV("speaker volume", SPKOUT_CTRL, SPK_VOL, 0x1f, 0, speaker_vol_tlv),
++ SOC_SINGLE_TLV("headphone volume", HPOUT_CTRL, HP_VOL, 0x3f, 0, headphone_vol_tlv),
++};
++
++/* PLL divisors */
++struct pll_div {
++ unsigned int pll_in;
++ unsigned int pll_out;
++ int m;
++ int n_i;
++ int n_f;
++};
++
++struct aif1_fs {
++ unsigned samp_rate;
++ int bclk_div;
++ int srbit;
++ #define _SERIES_24_576K 0
++ #define _SERIES_22_579K 1
++ int series;
++};
++
++struct kv_map {
++ int val;
++ int bit;
++};
++
++/*
++ * Note : pll code from original tdm/i2s driver.
++ * freq_out = freq_in * N/(M*(2k+1)) , k=1,N=N_i+N_f,N_f=factor*0.2;
++ * N_i[0,1023], N_f_factor[0,7], m[1,64]=REG_VAL[1-63,0]
++ */
++static const struct pll_div codec_pll_div[] = {
++ {128000, _FREQ_22_579K, 1, 529, 1},
++ {192000, _FREQ_22_579K, 1, 352, 4},
++ {256000, _FREQ_22_579K, 1, 264, 3},
++ {384000, _FREQ_22_579K, 1, 176, 2}, /*((176+2*0.2)*6000000)/(38*(2*1+1))*/
++ {1411200, _FREQ_22_579K, 1, 48, 0},
++ {2822400, _FREQ_22_579K, 1, 24, 0}, /* accurate, 11025 * 256 */
++ {5644800, _FREQ_22_579K, 1, 12, 0}, /* accurate, 22050 * 256 */
++ {6000000, _FREQ_22_579K, 38, 429, 0}, /*((429+0*0.2)*6000000)/(38*(2*1+1))*/
++ {11289600, _FREQ_22_579K, 1, 6, 0}, /* accurate, 44100 * 256 */
++ {13000000, _FREQ_22_579K, 19, 99, 0},
++ {19200000, _FREQ_22_579K, 25, 88, 1},
++ {24000000, _FREQ_22_579K, 63, 177, 4}, /* 22577778 Hz */
++
++ {128000, _FREQ_24_576K, 1, 576, 0},
++ {192000, _FREQ_24_576K, 1, 384, 0},
++ {256000, _FREQ_24_576K, 1, 288, 0},
++ {384000, _FREQ_24_576K, 1, 192, 0},
++ {2048000, _FREQ_24_576K, 1, 36, 0}, /* accurate, 8000 * 256 */
++ {3072000, _FREQ_24_576K, 1, 24, 0}, /* accurate, 12000 * 256 */
++ {4096000, _FREQ_24_576K, 1, 18, 0}, /* accurate, 16000 * 256 */
++ {6000000, _FREQ_24_576K, 25, 307, 1},
++ {6144000, _FREQ_24_576K, 4, 48, 0}, /* accurate, 24000 * 256 */
++ {12288000, _FREQ_24_576K, 8, 48, 0}, /* accurate, 48000 * 256 */
++ {13000000, _FREQ_24_576K, 42, 238, 1},
++ {19200000, _FREQ_24_576K, 25, 96, 0},
++ {24000000, _FREQ_24_576K, 25, 76, 4}, /* accurate */
++
++ {_FREQ_22_579K, _FREQ_22_579K, 8, 24, 0}, /* accurate, 88200 * 256 */
++ {_FREQ_24_576K, _FREQ_24_576K, 8, 24, 0}, /* accurate, 96000 * 256 */
++};
++
++static const struct aif1_fs codec_aif1_fs[] = {
++ {8000, 12, 0},
++ {11025, 8, 1, _SERIES_22_579K},
++ {12000, 8, 2},
++ {16000, 6, 3},
++ {22050, 4, 4, _SERIES_22_579K},
++ {24000, 4, 5},
++ /* {32000, 3, 6}, dividing by 3 is not support */
++ {44100, 2, 7, _SERIES_22_579K},
++ {48000, 2, 8},
++ {96000, 1, 9},
++};
++
++static const struct kv_map codec_aif1_lrck[] = {
++ {16, 0},
++ {32, 1},
++ {64, 2},
++ {128, 3},
++ {256, 4},
++};
++
++static const struct kv_map codec_aif1_wsize[] = {
++ {8, 0},
++ {16, 1},
++ {20, 2},
++ {24, 3},
++ {32, 3},
++};
++
++static const unsigned ac101_bclkdivs[] = {
++ 1, 2, 4, 6,
++ 8, 12, 16, 24,
++ 32, 48, 64, 96,
++ 128, 192, 0, 0,
++};
++
++static int ac101_aif_play(struct ac10x_priv* ac10x) {
++ struct snd_soc_codec * codec = ac10x->codec;
++
++ late_enable_dac(codec, SND_SOC_DAPM_PRE_PMU);
++ ac101_headphone_event(codec, SND_SOC_DAPM_POST_PMU);
++ if (drc_used) {
++ drc_enable(codec, 1);
++ }
++
++ /* Enable Left & Right Speaker */
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPK_EN) | (0x1 << RSPK_EN),
++ (0x1 << LSPK_EN) | (0x1 << RSPK_EN));
++ if (ac10x->gpiod_spk_amp_gate) {
++ gpiod_set_value(ac10x->gpiod_spk_amp_gate, 1);
++ }
++ return 0;
++}
++
++static void ac10x_work_aif_play(struct work_struct *work) {
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, dlywork.work);
++
++ ac101_aif_play(ac10x);
++ return;
++}
++
++int ac101_aif_mute(struct snd_soc_dai *codec_dai, int mute)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("mute=%d\n", mute);
++
++ ac101_write(codec, DAC_VOL_CTRL, mute? 0: 0xA0A0);
++
++ if (!mute) {
++ #if _MASTER_MULTI_CODEC != _MASTER_AC101
++ /* enable global clock */
++ ac10x->aif1_clken = 0;
++ ac101_aif1clk(codec, SND_SOC_DAPM_PRE_PMU, 0);
++ ac101_aif_play(ac10x);
++ #else
++ schedule_delayed_work(&ac10x->dlywork, msecs_to_jiffies(50));
++ #endif
++ } else {
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ cancel_delayed_work_sync(&ac10x->dlywork);
++ #endif
++
++ if (ac10x->gpiod_spk_amp_gate) {
++ gpiod_set_value(ac10x->gpiod_spk_amp_gate, 0);
++ }
++ /* Disable Left & Right Speaker */
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPK_EN) | (0x1 << RSPK_EN),
++ (0x0 << LSPK_EN) | (0x0 << RSPK_EN));
++ if (drc_used) {
++ drc_enable(codec, 0);
++ }
++ ac101_headphone_event(codec, SND_SOC_DAPM_PRE_PMD);
++ late_enable_dac(codec, SND_SOC_DAPM_POST_PMD);
++
++ #if _MASTER_MULTI_CODEC != _MASTER_AC101
++ ac10x->aif1_clken = 1;
++ ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
++ #endif
++ }
++ return 0;
++}
++
++void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("stream = %s, play: %d, capt: %d, active: %d\n",
++ snd_pcm_stream_str(substream),
++ codec_dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active,
++ codec_dai->stream[SNDRV_PCM_STREAM_CAPTURE].active,
++ snd_soc_dai_active(codec_dai));
++
++ if (!snd_soc_dai_active(codec_dai)) {
++ ac10x->aif1_clken = 1;
++ ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
++ } else {
++ ac101_aif1clk(codec, SND_SOC_DAPM_PRE_PMU, 0);
++ }
++}
++
++static int ac101_set_pll(struct snd_soc_dai *codec_dai, int pll_id, int source,
++ unsigned int freq_in, unsigned int freq_out)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ int i, m, n_i, n_f;
++
++ AC101_DBG("pll_id:%d\n", pll_id);
++
++ /* clear volatile reserved bits*/
++ ac101_update_bits(codec, SYSCLK_CTRL, 0xFF & ~(0x1 << SYSCLK_ENA), 0x0);
++
++ /* select aif1 clk srouce from mclk1 */
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x0<<AIF1CLK_SRC));
++ /* disable pll */
++ ac101_update_bits(codec, PLL_CTRL2, (0x1<<PLL_EN), (0<<PLL_EN));
++
++ if (!freq_out)
++ return 0;
++ if ((freq_in < 128000) || (freq_in > _FREQ_24_576K)) {
++ return -EINVAL;
++ } else if ((freq_in == _FREQ_24_576K) || (freq_in == _FREQ_22_579K)) {
++ if (pll_id == AC101_MCLK1) {
++ /*select aif1 clk source from mclk1*/
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC),
++ (0x0<<AIF1CLK_SRC));
++ return 0;
++ }
++ }
++
++ switch (pll_id) {
++ case AC101_MCLK1:
++ /*pll source from MCLK1*/
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<PLLCLK_SRC), (0x0<<PLLCLK_SRC));
++ break;
++ case AC101_BCLK1:
++ /*pll source from BCLK1*/
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<PLLCLK_SRC), (0x2<<PLLCLK_SRC));
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ /* freq_out = freq_in * n/(m*(2k+1)) , k=1,N=N_i+N_f */
++ for (i = m = n_i = n_f = 0; i < ARRAY_SIZE(codec_pll_div); i++) {
++ if ((codec_pll_div[i].pll_in == freq_in) &&
++ (codec_pll_div[i].pll_out == freq_out)) {
++ m = codec_pll_div[i].m;
++ n_i = codec_pll_div[i].n_i;
++ n_f = codec_pll_div[i].n_f;
++ break;
++ }
++ }
++ /* config pll m */
++ if (m == 64) m = 0;
++ ac101_update_bits(codec, PLL_CTRL1, (0x3f<<PLL_POSTDIV_M), (m<<PLL_POSTDIV_M));
++ /* config pll n */
++ ac101_update_bits(codec, PLL_CTRL2, (0x3ff<<PLL_PREDIV_NI), (n_i<<PLL_PREDIV_NI));
++ ac101_update_bits(codec, PLL_CTRL2, (0x7<<PLL_POSTDIV_NF), (n_f<<PLL_POSTDIV_NF));
++ /* enable pll */
++ ac101_update_bits(codec, PLL_CTRL2, (0x1<<PLL_EN), (1<<PLL_EN));
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<PLLCLK_ENA), (0x1<<PLLCLK_ENA));
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x3<<AIF1CLK_SRC));
++
++ return 0;
++}
++
++int ac101_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *codec_dai)
++{
++ int i = 0;
++ int AIF_CLK_CTRL = AIF1_CLK_CTRL;
++ int aif1_word_size = 24;
++ int aif1_slot_size = 32;
++ int aif1_lrck_div;
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int reg_val, freq_out;
++ unsigned channels;
++
++ AC101_DBG("+++\n");
++
++ if (_MASTER_MULTI_CODEC == _MASTER_AC101 && ac101_sysclk_started()) {
++ /* not configure hw_param twice if stream is playback, tell the caller it's started */
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ return 1;
++ }
++ }
++
++ /* get channels count & slot size */
++ channels = params_channels(params);
++
++ switch (params_format(params)) {
++ case SNDRV_PCM_FORMAT_S24_LE:
++ case SNDRV_PCM_FORMAT_S32_LE:
++ aif1_slot_size = 32;
++ break;
++ case SNDRV_PCM_FORMAT_S16_LE:
++ default:
++ aif1_slot_size = 16;
++ break;
++ }
++
++ /* set LRCK/BCLK ratio */
++ aif1_lrck_div = aif1_slot_size * channels;
++ for (i = 0; i < ARRAY_SIZE(codec_aif1_lrck); i++) {
++ if (codec_aif1_lrck[i].val == aif1_lrck_div) {
++ break;
++ }
++ }
++ ac101_update_bits(codec, AIF_CLK_CTRL, (0x7 << AIF1_LRCK_DIV),
++ codec_aif1_lrck[i].bit << AIF1_LRCK_DIV);
++
++ /* set PLL output freq */
++ freq_out = _FREQ_24_576K;
++ for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
++ if (codec_aif1_fs[i].samp_rate == params_rate(params)) {
++ if (codec_dai->stream[SNDRV_PCM_STREAM_CAPTURE].active && dmic_used &&
++ codec_aif1_fs[i].samp_rate == 44100) {
++ ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS),
++ (0x4<<AIF1_FS));
++ } else {
++ ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS),
++ ((codec_aif1_fs[i].srbit)<<AIF1_FS));
++ }
++ if (codec_aif1_fs[i].series == _SERIES_22_579K)
++ freq_out = _FREQ_22_579K;
++ break;
++ }
++ }
++
++ /* set I2S word size */
++ for (i = 0; i < ARRAY_SIZE(codec_aif1_wsize); i++) {
++ if (codec_aif1_wsize[i].val == aif1_word_size) {
++ break;
++ }
++ }
++ ac101_update_bits(codec, AIF_CLK_CTRL, (0x3<<AIF1_WORK_SIZ),
++ ((codec_aif1_wsize[i].bit)<<AIF1_WORK_SIZ));
++
++ /* set TDM slot size */
++ if ((reg_val = codec_aif1_wsize[i].bit) > 2) reg_val = 2;
++ ac101_update_bits(codec, AIF1_ADCDAT_CTRL, 0x3 << AIF1_SLOT_SIZ, reg_val << AIF1_SLOT_SIZ);
++
++ /* setting pll if it's master mode */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ if ((reg_val & (0x1 << AIF1_MSTR_MOD)) == 0) {
++ unsigned bclkdiv;
++
++ ac101_set_pll(codec_dai, AC101_MCLK1, 0, ac10x->sysclk, freq_out);
++
++ bclkdiv = freq_out / (aif1_lrck_div * params_rate(params));
++ for (i = 0; i < ARRAY_SIZE(ac101_bclkdivs) - 1; i++) {
++ if (ac101_bclkdivs[i] >= bclkdiv) {
++ break;
++ }
++ }
++ ac101_update_bits(codec, AIF_CLK_CTRL, (0xf<<AIF1_BCLK_DIV), i<<AIF1_BCLK_DIV);
++ } else {
++ /* set pll clock source to BCLK if slave mode */
++ ac101_set_pll(codec_dai, AC101_BCLK1, 0, aif1_lrck_div * params_rate(params),
++ freq_out);
++ }
++
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ /* Master mode, to clear cpu_dai fifos, disable output bclk & lrck */
++ ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
++ #endif
++
++ AC101_DBG("rate: %d , channels: %d , samp_res: %d",
++ params_rate(params), channels, aif1_slot_size);
++
++ AC101_DBG("---\n");
++ return 0;
++}
++
++int ac101_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
++{
++ int reg_val;
++ int AIF_CLK_CTRL = AIF1_CLK_CTRL;
++ struct snd_soc_codec *codec = codec_dai->codec;
++
++ AC101_DBG();
++
++ /*
++ * master or slave selection
++ * 0 = Master mode
++ * 1 = Slave mode
++ */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ reg_val &= ~(0x1<<AIF1_MSTR_MOD);
++ switch(fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++ case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master, ap is slave*/
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ pr_warn("AC101 as Master\n");
++ reg_val |= (0x0<<AIF1_MSTR_MOD);
++ break;
++ #else
++ pr_warn("AC108 as Master\n");
++ #endif
++ case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave, ap is master*/
++ pr_warn("AC101 as Slave\n");
++ reg_val |= (0x1<<AIF1_MSTR_MOD);
++ break;
++ default:
++ pr_err("unknwon master/slave format\n");
++ return -EINVAL;
++ }
++
++ /*
++ * Enable TDM mode
++ */
++ reg_val |= (0x1 << AIF1_TDMM_ENA);
++ ac101_write(codec, AIF_CLK_CTRL, reg_val);
++
++ /* i2s mode selection */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ reg_val&=~(3<<AIF1_DATA_FMT);
++ switch(fmt & SND_SOC_DAIFMT_FORMAT_MASK){
++ case SND_SOC_DAIFMT_I2S: /* I2S1 mode */
++ reg_val |= (0x0<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_RIGHT_J: /* Right Justified mode */
++ reg_val |= (0x2<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_LEFT_J: /* Left Justified mode */
++ reg_val |= (0x1<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_DSP_A: /* L reg_val msb after FRM LRC */
++ reg_val |= (0x3<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_DSP_B:
++ /* TODO: data offset set to 0 */
++ reg_val |= (0x3<<AIF1_DATA_FMT);
++ break;
++ default:
++ pr_err("%s, line:%d\n", __func__, __LINE__);
++ return -EINVAL;
++ }
++ ac101_write(codec, AIF_CLK_CTRL, reg_val);
++
++ /* DAI signal inversions */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ switch(fmt & SND_SOC_DAIFMT_INV_MASK){
++ case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + nor frame */
++ reg_val &= ~(0x1<<AIF1_LRCK_INV);
++ reg_val &= ~(0x1<<AIF1_BCLK_INV);
++ break;
++ case SND_SOC_DAIFMT_NB_IF: /* normal bclk + inv frm */
++ reg_val |= (0x1<<AIF1_LRCK_INV);
++ reg_val &= ~(0x1<<AIF1_BCLK_INV);
++ break;
++ case SND_SOC_DAIFMT_IB_NF: /* invert bclk + nor frm */
++ reg_val &= ~(0x1<<AIF1_LRCK_INV);
++ reg_val |= (0x1<<AIF1_BCLK_INV);
++ break;
++ case SND_SOC_DAIFMT_IB_IF: /* invert bclk + inv frm */
++ reg_val |= (0x1<<AIF1_LRCK_INV);
++ reg_val |= (0x1<<AIF1_BCLK_INV);
++ break;
++ }
++ ac101_write(codec, AIF_CLK_CTRL, reg_val);
++
++ return 0;
++}
++
++int ac101_audio_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *codec_dai)
++{
++ // struct snd_soc_codec *codec = codec_dai->codec;
++
++ AC101_DBG("\n\n\n");
++
++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
++ }
++ return 0;
++}
++
++int ac101_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int ret = 0;
++
++ AC101_DBG("stream=%s cmd=%d\n",
++ snd_pcm_stream_str(substream),
++ cmd);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ if (ac10x->aif1_clken == 0){
++ /*
++ * enable aif1clk, it' here due to reduce time between 'AC108 Sysclk Enable' and 'AC101 Sysclk Enable'
++ * Or else the two AC108 chips lost the sync.
++ */
++ ret = 0;
++ ret = ret || ac101_update_bits(codec, MOD_CLK_ENA,
++ (0x1<<MOD_CLK_AIF1), (0x1<<MOD_CLK_AIF1));
++ ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1),
++ (0x1<<MOD_RESET_AIF1));
++ }
++ #endif
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ break;
++ default:
++ ret = -EINVAL;
++ }
++ return ret;
++}
++
++#if 0
++static int ac101_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++ int clk_id, unsigned int freq, int dir)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("id=%d freq=%d, dir=%d\n",
++ clk_id, freq, dir);
++
++ ac10x->sysclk = freq;
++
++ return 0;
++}
++
++static const struct snd_soc_dai_ops ac101_aif1_dai_ops = {
++ //.startup = ac101_audio_startup,
++ //.shutdown = ac101_aif_shutdown,
++ //.set_sysclk = ac101_set_dai_sysclk,
++ //.set_pll = ac101_set_pll,
++ //.set_fmt = ac101_set_dai_fmt,
++ //.hw_params = ac101_hw_params,
++ //.trigger = ac101_trigger,
++ //.digital_mute = ac101_aif_mute,
++};
++
++static struct snd_soc_dai_driver ac101_dai[] = {
++ {
++ .name = "ac10x-aif1",
++ .id = AIF1_CLK,
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = AC101_RATES,
++ .formats = AC101_FORMATS,
++ },
++ #if 0
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = AC101_RATES,
++ .formats = AC101_FORMATS,
++ },
++ #endif
++ .ops = &ac101_aif1_dai_ops,
++ }
++};
++#endif
++
++static void codec_resume_work(struct work_struct *work)
++{
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, codec_resume);
++ struct snd_soc_codec *codec = ac10x->codec;
++
++ AC101_DBG("+++\n");
++
++ set_configuration(codec);
++ if (drc_used) {
++ drc_config(codec);
++ }
++ /*enable this bit to prevent leakage from ldoin*/
++ ac101_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0x1<<OSCEN));
++
++ AC101_DBG("---\n");
++ return;
++}
++
++int ac101_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level)
++{
++ switch (level) {
++ case SND_SOC_BIAS_ON:
++ AC101_DBG("SND_SOC_BIAS_ON\n");
++ break;
++ case SND_SOC_BIAS_PREPARE:
++ AC101_DBG("SND_SOC_BIAS_PREPARE\n");
++ break;
++ case SND_SOC_BIAS_STANDBY:
++ AC101_DBG("SND_SOC_BIAS_STANDBY\n");
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ switch_hw_config(codec);
++ #endif
++ break;
++ case SND_SOC_BIAS_OFF:
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASEN), (0<<HBIASEN));
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASADCEN), (0<<HBIASADCEN));
++ #endif
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, (0xf<<HPOUTPUTENABLE),
++ (0<<HPOUTPUTENABLE));
++ ac101_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0<<OSCEN));
++ AC101_DBG("SND_SOC_BIAS_OFF\n");
++ break;
++ }
++ snd_soc_codec_get_dapm(codec)->bias_level = level;
++ return 0;
++}
++
++int ac101_codec_probe(struct snd_soc_codec *codec)
++{
++ int ret = 0;
++ struct ac10x_priv *ac10x;
++
++ ac10x = dev_get_drvdata(codec->dev);
++ if (ac10x == NULL) {
++ AC101_DBG("not set client data!\n");
++ return -ENOMEM;
++ }
++ ac10x->codec = codec;
++
++ INIT_DELAYED_WORK(&ac10x->dlywork, ac10x_work_aif_play);
++ INIT_WORK(&ac10x->codec_resume, codec_resume_work);
++ ac10x->dac_enable = 0;
++ ac10x->aif1_clken = 0;
++ mutex_init(&ac10x->dac_mutex);
++
++ set_configuration(ac10x->codec);
++
++ /*enable this bit to prevent leakage from ldoin*/
++ ac101_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0x1<<OSCEN));
++ ac101_write(codec, DAC_VOL_CTRL, 0);
++
++ /* customized get/put inteface */
++ for (ret = 0; ret < ARRAY_SIZE(ac101_controls); ret++) {
++ struct snd_kcontrol_new* skn = &ac101_controls[ret];
++
++ skn->get = snd_ac101_get_volsw;
++ skn->put = snd_ac101_put_volsw;
++ }
++ ret = snd_soc_add_codec_controls(codec, ac101_controls, ARRAY_SIZE(ac101_controls));
++ if (ret) {
++ pr_err("[ac10x] Failed to register audio mode control, "
++ "will continue without it.\n");
++ }
++
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ ret = ac101_switch_probe(ac10x);
++ if (ret) {
++ // not care the switch return value
++ }
++ #endif
++
++ return 0;
++}
++
++/* power down chip */
++int ac101_codec_remove(struct snd_soc_codec *codec)
++{
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (ac10x->irq) {
++ devm_free_irq(codec->dev, ac10x->irq, ac10x);
++ ac10x->irq = 0;
++ }
++
++ if (cancel_work_sync(&ac10x->work_switch) != 0) {
++ }
++
++ if (cancel_work_sync(&ac10x->work_clear_irq) != 0) {
++ }
++
++ if (ac10x->inpdev) {
++ input_unregister_device(ac10x->inpdev);
++ ac10x->inpdev = NULL;
++ }
++ #endif
++
++ return 0;
++}
++
++int ac101_codec_suspend(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("[codec]:suspend\n");
++ regcache_cache_only(ac10x->regmap101, true);
++ return 0;
++}
++
++int ac101_codec_resume(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int ret;
++
++ AC101_DBG("[codec]:resume");
++
++ /* Sync reg_cache with the hardware */
++ regcache_cache_only(ac10x->regmap101, false);
++ ret = regcache_sync(ac10x->regmap101);
++ if (ret != 0) {
++ dev_err(codec->dev, "Failed to sync register cache: %d\n", ret);
++ regcache_cache_only(ac10x->regmap101, true);
++ return ret;
++ }
++
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ ac10x->mode = HEADPHONE_IDLE;
++ ac10x->state = -1;
++ #endif
++
++ ac101_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++ schedule_work(&ac10x->codec_resume);
++ return 0;
++}
++
++/***************************************************************************/
++static ssize_t ac101_debug_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct ac10x_priv *ac10x = dev_get_drvdata(dev);
++ int val = 0, flag = 0;
++ u16 value_w, value_r;
++ u8 reg, num, i=0;
++
++ val = simple_strtol(buf, NULL, 16);
++ flag = (val >> 24) & 0xF;
++ if (flag) {
++ reg = (val >> 16) & 0xFF;
++ value_w = val & 0xFFFF;
++ ac101_write(ac10x->codec, reg, value_w);
++ printk("write 0x%x to reg:0x%x\n", value_w, reg);
++ } else {
++ reg = (val >> 8) & 0xFF;
++ num = val & 0xff;
++ printk("\n");
++ printk("read:start add:0x%x,count:0x%x\n", reg, num);
++
++ regcache_cache_bypass(ac10x->regmap101, true);
++ do {
++ value_r = ac101_read(ac10x->codec, reg);
++ printk("0x%x: 0x%04x ", reg++, value_r);
++ if (++i % 4 == 0 || i == num)
++ printk("\n");
++ } while (i < num);
++ regcache_cache_bypass(ac10x->regmap101, false);
++ }
++ return count;
++}
++static ssize_t ac101_debug_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ printk("echo flag|reg|val > ac10x\n");
++ printk("eg read star addres=0x06,count 0x10:echo 0610 >ac10x\n");
++ printk("eg write value:0x13fe to address:0x06 :echo 10613fe > ac10x\n");
++ return 0;
++}
++static DEVICE_ATTR(ac10x, 0644, ac101_debug_show, ac101_debug_store);
++
++static struct attribute *audio_debug_attrs[] = {
++ &dev_attr_ac10x.attr,
++ NULL,
++};
++
++static struct attribute_group audio_debug_attr_group = {
++ .name = "ac101_debug",
++ .attrs = audio_debug_attrs,
++};
++/***************************************************************************/
++
++/************************************************************/
++static bool ac101_volatile_reg(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case PLL_CTRL2:
++ case HMIC_STS:
++ return true;
++ }
++ return false;
++}
++
++static const struct regmap_config ac101_regmap = {
++ .reg_bits = 8,
++ .val_bits = 16,
++ .reg_stride = 1,
++ .max_register = 0xB5,
++ .cache_type = REGCACHE_FLAT,
++ .volatile_reg = ac101_volatile_reg,
++};
++
++/* Sync reg_cache from the hardware */
++int ac10x_fill_regcache(struct device* dev, struct regmap* map) {
++ int r, i, n;
++ int v;
++
++ n = regmap_get_max_register(map);
++ for (i = 0; i < n; i++) {
++ regcache_cache_bypass(map, true);
++ r = regmap_read(map, i, &v);
++ if (r) {
++ dev_dbg(dev, "failed to read register %d\n", i);
++ continue;
++ }
++ regcache_cache_bypass(map, false);
++
++ regcache_cache_only(map, true);
++ r = regmap_write(map, i, v);
++ regcache_cache_only(map, false);
++ }
++ regcache_cache_bypass(map, false);
++ regcache_cache_only(map, false);
++
++ return 0;
++}
++
++int ac101_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
++{
++ struct ac10x_priv *ac10x = i2c_get_clientdata(i2c);
++ int ret = 0;
++ unsigned v = 0;
++
++ AC101_DBG();
++
++ static_ac10x = ac10x;
++
++ ac10x->regmap101 = devm_regmap_init_i2c(i2c, &ac101_regmap);
++ if (IS_ERR(ac10x->regmap101)) {
++ ret = PTR_ERR(ac10x->regmap101);
++ dev_err(&i2c->dev, "Fail to initialize I/O: %d\n", ret);
++ return ret;
++ }
++
++ /* Chip reset */
++ regcache_cache_only(ac10x->regmap101, false);
++ ret = regmap_write(ac10x->regmap101, CHIP_AUDIO_RST, 0);
++ msleep(50);
++
++ /* sync regcache for FLAT type */
++ ac10x_fill_regcache(&i2c->dev, ac10x->regmap101);
++
++ ret = regmap_read(ac10x->regmap101, CHIP_AUDIO_RST, &v);
++ if (ret < 0) {
++ dev_err(&i2c->dev, "failed to read vendor ID: %d\n", ret);
++ return ret;
++ }
++
++ if (v != AC101_CHIP_ID) {
++ dev_err(&i2c->dev, "chip is not AC101 (%X)\n", v);
++ dev_err(&i2c->dev, "Expected %X\n", AC101_CHIP_ID);
++ return -ENODEV;
++ }
++
++ ret = sysfs_create_group(&i2c->dev.kobj, &audio_debug_attr_group);
++ if (ret) {
++ pr_err("failed to create attr group\n");
++ }
++
++ ac10x->gpiod_spk_amp_gate = devm_gpiod_get_optional(&i2c->dev, "spk-amp-switch",
++ GPIOD_OUT_LOW);
++ if (IS_ERR(ac10x->gpiod_spk_amp_gate)) {
++ ac10x->gpiod_spk_amp_gate = NULL;
++ dev_err(&i2c->dev, "failed get spk-amp-switch in device tree\n");
++ }
++
++ return 0;
++}
++
++void ac101_shutdown(struct i2c_client *i2c)
++{
++ struct ac10x_priv *ac10x = i2c_get_clientdata(i2c);
++ struct snd_soc_codec *codec = ac10x->codec;
++ int reg_val;
++
++ if (codec == NULL) {
++ pr_err(": no sound card.\n");
++ return;
++ }
++
++ /*set headphone volume to 0*/
++ reg_val = ac101_read(codec, HPOUT_CTRL);
++ reg_val &= ~(0x3f<<HP_VOL);
++ ac101_write(codec, HPOUT_CTRL, reg_val);
++
++ /*disable pa*/
++ reg_val = ac101_read(codec, HPOUT_CTRL);
++ reg_val &= ~(0x1<<HPPA_EN);
++ ac101_write(codec, HPOUT_CTRL, reg_val);
++
++ /*hardware xzh support*/
++ reg_val = ac101_read(codec, OMIXER_DACA_CTRL);
++ reg_val &= ~(0xf<<HPOUTPUTENABLE);
++ ac101_write(codec, OMIXER_DACA_CTRL, reg_val);
++
++ /*unmute l/r headphone pa*/
++ reg_val = ac101_read(codec, HPOUT_CTRL);
++ reg_val &= ~((0x1<<RHPPA_MUTE)|(0x1<<LHPPA_MUTE));
++ ac101_write(codec, HPOUT_CTRL, reg_val);
++ return;
++}
++
++int ac101_remove(struct i2c_client *i2c)
++{
++ sysfs_remove_group(&i2c->dev.kobj, &audio_debug_attr_group);
++ return 0;
++}
++
++MODULE_DESCRIPTION("ASoC ac10x driver");
++MODULE_AUTHOR("huangxin,liushaohua");
++MODULE_AUTHOR("PeterYang<linsheng.yang@seeed.cc>");
+--- /dev/null
++++ b/sound/soc/codecs/ac101_regs.h
+@@ -0,0 +1,431 @@
++/*
++ * ac101_regs.h
++ *
++ * (C) Copyright 2017-2018
++ * Seeed Technology Co., Ltd. <www.seeedstudio.com>
++ *
++ * PeterYang <linsheng.yang@seeed.cc>
++ *
++ * (C) Copyright 2010-2017
++ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
++ * huangxin <huangxin@reuuimllatech.com>
++ *
++ * some simple description for this code
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ */
++#ifndef __AC101_REGS_H__
++#define __AC101_REGS_H__
++
++/*pll source*/
++#define AC101_MCLK1 1
++#define AC101_MCLK2 2
++#define AC101_BCLK1 3
++#define AC101_BCLK2 4
++
++#define AIF1_CLK 1
++#define AIF2_CLK 2
++
++#define CHIP_AUDIO_RST 0x0
++#define PLL_CTRL1 0x1
++#define PLL_CTRL2 0x2
++#define SYSCLK_CTRL 0x3
++#define MOD_CLK_ENA 0x4
++#define MOD_RST_CTRL 0x5
++#define AIF_SR_CTRL 0x6
++
++#define AIF1_CLK_CTRL 0x10
++#define AIF1_ADCDAT_CTRL 0x11
++#define AIF1_DACDAT_CTRL 0x12
++#define AIF1_MXR_SRC 0x13
++#define AIF1_VOL_CTRL1 0x14
++#define AIF1_VOL_CTRL2 0x15
++#define AIF1_VOL_CTRL3 0x16
++#define AIF1_VOL_CTRL4 0x17
++#define AIF1_MXR_GAIN 0x18
++#define AIF1_RXD_CTRL 0x19
++#define ADC_DIG_CTRL 0x40
++#define ADC_VOL_CTRL 0x41
++#define ADC_DBG_CTRL 0x42
++
++#define HMIC_CTRL1 0x44
++#define HMIC_CTRL2 0x45
++#define HMIC_STS 0x46
++
++#define DAC_DIG_CTRL 0x48
++#define DAC_VOL_CTRL 0x49
++#define DAC_DBG_CTRL 0x4a
++#define DAC_MXR_SRC 0x4c
++#define DAC_MXR_GAIN 0x4d
++
++#define ADC_APC_CTRL 0x50
++#define ADC_SRC 0x51
++#define ADC_SRCBST_CTRL 0x52
++#define OMIXER_DACA_CTRL 0x53
++#define OMIXER_SR 0x54
++#define OMIXER_BST1_CTRL 0x55
++#define HPOUT_CTRL 0x56
++#define ESPKOUT_CTRL 0x57
++#define SPKOUT_CTRL 0x58
++#define LOUT_CTRL 0x59
++#define ADDA_TUNE1 0x5a
++#define ADDA_TUNE2 0x5b
++#define ADDA_TUNE3 0x5c
++#define HPOUT_STR 0x5d
++
++/*CHIP_AUDIO_RST*/
++#define AC101_CHIP_ID 0x0101
++
++/*PLL_CTRL1*/
++#define DPLL_DAC_BIAS 14
++#define PLL_POSTDIV_M 8
++#define CLOSE_LOOP 6
++#define INT 0
++
++/*PLL_CTRL2*/
++#define PLL_EN 15
++#define PLL_LOCK_STATUS 14
++#define PLL_PREDIV_NI 4
++#define PLL_POSTDIV_NF 0
++
++/*SYSCLK_CTRL*/
++#define PLLCLK_ENA 15
++#define PLLCLK_SRC 12
++#define AIF1CLK_ENA 11
++#define AIF1CLK_SRC 8
++#define AIF2CLK_ENA 7
++#define AIF2CLK_SRC 4
++#define SYSCLK_ENA 3
++#define SYSCLK_SRC 0
++
++/*MOD_CLK_ENA*/
++#define MOD_CLK_AIF1 15
++#define MOD_CLK_AIF2 14
++#define MOD_CLK_AIF3 13
++#define MOD_CLK_SRC1 11
++#define MOD_CLK_SRC2 10
++#define MOD_CLK_HPF_AGC 7
++#define MOD_CLK_HPF_DRC 6
++#define MOD_CLK_ADC_DIG 3
++#define MOD_CLK_DAC_DIG 2
++
++/*MOD_RST_CTRL*/
++#define MOD_RESET_CTL 0
++#define MOD_RESET_AIF1 15
++#define MOD_RESET_AIF2 14
++#define MOD_RESET_AIF3 13
++#define MOD_RESET_SRC1 11
++#define MOD_RESET_SRC2 10
++#define MOD_RESET_HPF_AGC 7
++#define MOD_RESET_HPF_DRC 6
++#define MOD_RESET_ADC_DIG 3
++#define MOD_RESET_DAC_DIG 2
++
++/*AIF_SR_CTRL*/
++#define AIF1_FS 12 //AIF1 Sample Rate
++#define AIF2_FS 8 //AIF2 Sample Rate
++#define SRC1_ENA 3
++#define SRC1_SRC 2
++#define SRC2_ENA 1
++#define SRC2_SRC 0
++
++/*AIF1LCK_CTRL*/
++#define AIF1_MSTR_MOD 15
++#define AIF1_BCLK_INV 14
++#define AIF1_LRCK_INV 13
++#define AIF1_BCLK_DIV 9
++#define AIF1_LRCK_DIV 6
++#define AIF1_WORK_SIZ 4
++#define AIF1_DATA_FMT 2
++#define DSP_MONO_PCM 1
++#define AIF1_TDMM_ENA 0
++
++/*AIF1_ADCDAT_CTRL*/
++#define AIF1_AD0L_ENA 15
++#define AIF1_AD0R_ENA 14
++#define AIF1_AD1L_ENA 13
++#define AIF1_AD1R_ENA 12
++#define AIF1_AD0L_SRC 10
++#define AIF1_AD0R_SRC 8
++#define AIF1_AD1L_SRC 6
++#define AIF1_AD1R_SRC 4
++#define AIF1_ADCP_ENA 3
++#define AIF1_ADUL_ENA 2
++#define AIF1_SLOT_SIZ 0
++
++/*AIF1_DACDAT_CTRL*/
++#define AIF1_DA0L_ENA 15
++#define AIF1_DA0R_ENA 14
++#define AIF1_DA1L_ENA 13
++#define AIF1_DA1R_ENA 12
++#define AIF1_DA0L_SRC 10
++#define AIF1_DA0R_SRC 8
++#define AIF1_DA1L_SRC 6
++#define AIF1_DA1R_SRC 4
++#define AIF1_DACP_ENA 3
++#define AIF1_DAUL_ENA 2
++#define AIF1_SLOT_SIZ 0
++
++/*AIF1_MXR_SRC*/
++#define AIF1_AD0L_AIF1_DA0L_MXR 15
++#define AIF1_AD0L_AIF2_DACL_MXR 14
++#define AIF1_AD0L_ADCL_MXR 13
++#define AIF1_AD0L_AIF2_DACR_MXR 12
++#define AIF1_AD0R_AIF1_DA0R_MXR 11
++#define AIF1_AD0R_AIF2_DACR_MXR 10
++#define AIF1_AD0R_ADCR_MXR 9
++#define AIF1_AD0R_AIF2_DACL_MXR 8
++#define AIF1_AD1L_AIF2_DACL_MXR 7
++#define AIF1_AD1L_ADCL_MXR 6
++#define AIF1_AD1L_MXR_SRC 6
++#define AIF1_AD1R_AIF2_DACR_MXR 3
++#define AIF1_AD1R_ADCR_MXR 2
++#define AIF1_AD1R_MXR_SRC 2
++
++/*AIF1_VOL_CTRL1*/
++#define AIF1_AD0L_VOL 8
++#define AIF1_AD0R_VOL 0
++
++/*AIF1_VOL_CTRL2*/
++#define AIF1_AD1L_VOL 8
++#define AIF1_AD1R_VOL 0
++
++/*AIF1_VOL_CTRL3*/
++#define AIF1_DA0L_VOL 8
++#define AIF1_DA0R_VOL 0
++
++/*AIF1_VOL_CTRL4*/
++#define AIF1_DA1L_VOL 8
++#define AIF1_DA1R_VOL 0
++
++/*AIF1_MXR_GAIN*/
++#define AIF1_AD0L_MXR_GAIN 12
++#define AIF1_AD0R_MXR_GAIN 8
++#define AIF1_AD1L_MXR_GAIN 6
++#define AIF1_AD1R_MXR_GAIN 2
++
++/*AIF1_RXD_CTRL*/
++#define AIF1_N_DATA_DISCARD 8
++
++/*ADC_DIG_CTRL*/
++#define ENAD 15
++#define ENDM 14
++#define ADFIR32 13
++#define ADOUT_DTS 2
++#define ADOUT_DLY 1
++
++/*ADC_VOL_CTRL*/
++#define ADC_VOL_L 8
++#define ADC_VOL_R 0
++
++/*ADC_DBG_CTRL*/
++#define ADSW 15
++#define DMIC_CLK_PIN_CTRL 12
++
++/*HMIC_CTRL1*/
++#define HMIC_M 12
++#define HMIC_N 8
++#define HMIC_DATA_IRQ_MODE 7
++#define HMIC_TH1_HYSTERESIS 5
++#define HMIC_PULLOUT_IRQ 4
++#define HMIC_PLUGIN_IRQ 3
++#define HMIC_KEYUP_IRQ 2
++#define HMIC_KEYDOWN_IRQ 1
++#define HMIC_DATA_IRQ_EN 0
++
++/*HMIC_CTRL2*/
++#define HMIC_SAMPLE_SELECT 14
++#define HMIC_TH2_HYSTERESIS 13
++#define HMIC_TH2 8
++#define HMIC_SF 6
++#define KEYUP_CLEAR 5
++#define HMIC_TH1 0
++
++/*HMIC_STS*/
++#define HMIC_DATA 8
++#define GET_HMIC_DATA(r) (((r) >> HMIC_DATA) & 0x1F)
++#define HMIC_PULLOUT_PEND 4
++#define HMIC_PLUGIN_PEND 3
++#define HMIC_KEYUP_PEND 2
++#define HMKC_KEYDOWN_PEND 1
++#define HMIC_DATA_PEND 0
++#define HMIC_PEND_ALL (0x1F)
++
++/*DAC_DIG_CTRL*/
++#define ENDA 15
++#define ENHPF 14
++#define DAFIR32 13
++#define MODQU 8
++
++/*DAC_VOL_CTRL*/
++#define DAC_VOL_L 8
++#define DAC_VOL_R 0
++
++/*DAC_DBG_CTRL*/
++#define DASW 15
++#define ENDWA_N 14
++#define DAC_MOD_DBG 13
++#define DAC_PTN_SEL 6
++#define DVC 0
++
++/*DAC_MXR_SRC*/
++#define DACL_MXR_AIF1_DA0L 15
++#define DACL_MXR_AIF1_DA1L 14
++#define DACL_MXR_AIF2_DACL 13
++#define DACL_MXR_ADCL 12
++#define DACL_MXR_SRC 12
++#define DACR_MXR_AIF1_DA0R 11
++#define DACR_MXR_AIF1_DA1R 10
++#define DACR_MXR_AIF2_DACR 9
++#define DACR_MXR_ADCR 8
++#define DACR_MXR_SRC 8
++
++/*DAC_MXR_GAIN*/
++#define DACL_MXR_GAIN 12
++#define DACR_MXR_GAIN 8
++
++/*ADC_APC_CTRL*/
++#define ADCREN 15
++#define ADCRG 12
++#define ADCLEN 11
++#define ADCLG 8
++#define MBIASEN 7
++#define MMIC_BIAS_CHOP_EN 6
++#define MMIC_BIAS_CHOP_CKS 4
++#define HBIASMOD 2
++#define HBIASEN 1
++#define HBIASADCEN 0
++
++/*ADC_SRC*/
++#define RADCMIXMUTEMIC1BOOST (13)
++#define RADCMIXMUTEMIC2BOOST (12)
++#define RADCMIXMUTELINEINLR (11)
++#define RADCMIXMUTELINEINR (10)
++#define RADCMIXMUTEAUXINR (9)
++#define RADCMIXMUTEROUTPUT (8)
++#define RADCMIXMUTELOUTPUT (7)
++#define LADCMIXMUTEMIC1BOOST (6)
++#define LADCMIXMUTEMIC2BOOST (5)
++#define LADCMIXMUTELINEINLR (4)
++#define LADCMIXMUTELINEINL (3)
++#define LADCMIXMUTEAUXINL (2)
++#define LADCMIXMUTELOUTPUT (1)
++#define LADCMIXMUTEROUTPUT (0)
++
++/*ADC_SRCBST_CTRL*/
++#define MIC1AMPEN 15
++#define ADC_MIC1G 12
++#define MIC2AMPEN 11
++#define ADC_MIC2G 8
++#define MIC2SLT 7
++#define LINEIN_PREG 4
++#define AUXI_PREG 0
++
++/*OMIXER_DACA_CTRL*/
++#define DACAREN 15
++#define DACALEN 14
++#define RMIXEN 13
++#define LMIXEN 12
++#define HPOUTPUTENABLE 8
++
++/*OMIXER_SR*/
++#define RMIXMUTEMIC1BOOST (13)
++#define RMIXMUTEMIC2BOOST (12)
++#define RMIXMUTELINEINLR (11)
++#define RMIXMUTELINEINR (10)
++#define RMIXMUTEAUXINR (9)
++#define RMIXMUTEDACR (8)
++#define RMIXMUTEDACL (7)
++#define LMIXMUTEMIC1BOOST (6)
++#define LMIXMUTEMIC2BOOST (5)
++#define LMIXMUTELINEINLR (4)
++#define LMIXMUTELINEINL (3)
++#define LMIXMUTEAUXINL (2)
++#define LMIXMUTEDACL (1)
++#define LMIXMUTEDACR (0)
++
++/*OMIXER_BST1_CTRL*/
++#define BIASVOLTAGE 12
++#define AXG 9
++#define OMIXER_MIC1G 6
++#define OMIXER_MIC2G 3
++#define LINEING 0
++
++/*HPOUT_CTRL*/
++#define RHPS 15
++#define LHPS 14
++#define RHPPA_MUTE 13
++#define LHPPA_MUTE 12
++#define HPPA_EN 11
++#define HP_VOL 4
++#define HPPA_DEL 2
++#define HPPA_IS 0
++
++/*ESPKOUT_CTRL*/
++#define EAR_RAMP_TIME 11
++#define ESPA_OUT_CURRENT 9
++#define ESPSR 7
++#define ESPPA_MUTE 6
++#define ESPPA_EN 5
++#define ESP_VOL 0
++
++/*SPKOUT_CTRL*/
++#define HPCALICKS 13
++#define RSPKS 12
++#define RSPKINVEN 11
++#define RSPK_EN 9
++#define LSPKS 8
++#define LSPKINVEN 7
++#define LSPK_EN 5
++#define SPK_VOL 0
++
++/*LOUT_CTRL*/
++#define LINEOUTG 5
++#define LINEOUTEN 4
++#define LINEOUTS0 3
++#define LINEOUTS1 2
++#define LINEOUTS2 1
++#define LINEOUTS3 0
++
++/*ADDA_TUNE1*/
++#define CURRENT_TEST_SELECT 14
++#define BIHE_CTRL 12
++#define DITHER 11
++#define DITHER_CLK 9
++#define ZERO_CROSSOVER_EN 8
++#define ZERO_CROSSOVER_TIME 7
++#define EAR_SPEED_SELECT 6
++#define REF_CHOPPEN_CKS 4
++#define OPMIC_BIAS_CUR 0
++
++/*ADDA_TUNE2*/
++#define OPDAC_BIAS_CUR 14
++#define OPDRV_BIAS_CUR 12
++#define OPMIX_BIAS_CUR 10
++#define OPEAR_BIAS_CUR 8
++#define OPVR_BIAS_CUR 6
++#define OPAAF_BIAS_CUR 4
++#define OPADC1_BIAS_CUR 2
++#define OPADC2_BIAS_CUR 0
++
++/*ADDA_TUNE3*/
++#define LDOEN 15
++#define LDO_SEL 12
++#define BIASCALIVERIFY 11
++#define BIASMODE 10
++#define BIASCALIDATA 9
++#define OSCS 1
++#define OSCEN 0
++
++/*HPOUT_STR*/
++#define HPVL_SOFT_MOD 14
++#define HPVL_STEP_CTRL 8
++#define DACA_CHND_ENA 7
++#define HPPA_MXRD_ENA 6
++#define HPVL_CTRL_OUT 0
++
++#endif//__AC101_REGS_H__
+--- /dev/null
++++ b/sound/soc/codecs/ac108.c
+@@ -0,0 +1,1622 @@
++/*
++ * ac10x.c -- ac10x ALSA SoC Audio driver
++ *
++ *
++ * Author: Baozhu Zuo<zuobaozhu@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pm.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++#include <linux/workqueue.h>
++#include <sound/core.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/tlv.h>
++
++#include "ac108.h"
++#include "ac10x.h"
++
++#define _USE_CAPTURE 1
++#define _MASTER_INDEX 0
++
++/* #undef DEBUG
++ * use 'make DEBUG=1' to enable debugging
++ */
++
++/**
++ * TODO:
++ * 1, add PM API: ac108_suspend,ac108_resume
++ * 2,0x65-0x6a
++ * 3,0x76-0x79 high 4bit
++ */
++struct pll_div {
++ unsigned int freq_in;
++ unsigned int freq_out;
++ unsigned int m1;
++ unsigned int m2;
++ unsigned int n;
++ unsigned int k1;
++ unsigned int k2;
++};
++
++static struct ac10x_priv *ac10x;
++
++struct real_val_to_reg_val {
++ unsigned int real_val;
++ unsigned int reg_val;
++};
++
++static const struct real_val_to_reg_val ac108_sample_rate[] = {
++ { 8000, 0 },
++ { 11025, 1 },
++ { 12000, 2 },
++ { 16000, 3 },
++ { 22050, 4 },
++ { 24000, 5 },
++ { 32000, 6 },
++ { 44100, 7 },
++ { 48000, 8 },
++ { 96000, 9 },
++};
++
++/* Sample resolution */
++static const struct real_val_to_reg_val ac108_samp_res[] = {
++ { 8, 1 },
++ { 12, 2 },
++ { 16, 3 },
++ { 20, 4 },
++ { 24, 5 },
++ { 28, 6 },
++ { 32, 7 },
++};
++
++static const unsigned int ac108_bclkdivs[] = {
++ 0, 1, 2, 4,
++ 6, 8, 12, 16,
++ 24, 32, 48, 64,
++ 96, 128, 176, 192,
++};
++
++/* FOUT =(FIN * N) / [(M1+1) * (M2+1)*(K1+1)*(K2+1)] ; M1[0,31], M2[0,1], N[0,1023], K1[0,31], K2[0,1] */
++static const struct pll_div ac108_pll_div_list[] = {
++ { 400000, _FREQ_24_576K, 0, 0, 614, 4, 1 },
++ { 512000, _FREQ_24_576K, 0, 0, 960, 9, 1 }, /* _FREQ_24_576K/48 */
++ { 768000, _FREQ_24_576K, 0, 0, 640, 9, 1 }, /* _FREQ_24_576K/32 */
++ { 800000, _FREQ_24_576K, 0, 0, 614, 9, 1 },
++ { 1024000, _FREQ_24_576K, 0, 0, 480, 9, 1 }, /* _FREQ_24_576K/24 */
++ { 1600000, _FREQ_24_576K, 0, 0, 307, 9, 1 },
++ { 2048000, _FREQ_24_576K, 0, 0, 240, 9, 1 }, /* accurate, 8000 * 256 */
++ { 3072000, _FREQ_24_576K, 0, 0, 160, 9, 1 }, /* accurate, 12000 * 256 */
++ { 4096000, _FREQ_24_576K, 2, 0, 360, 9, 1 }, /* accurate, 16000 * 256 */
++ { 6000000, _FREQ_24_576K, 4, 0, 410, 9, 1 },
++ { 12000000, _FREQ_24_576K, 9, 0, 410, 9, 1 },
++ { 13000000, _FREQ_24_576K, 8, 0, 340, 9, 1 },
++ { 15360000, _FREQ_24_576K, 12, 0, 415, 9, 1 },
++ { 16000000, _FREQ_24_576K, 12, 0, 400, 9, 1 },
++ { 19200000, _FREQ_24_576K, 15, 0, 410, 9, 1 },
++ { 19680000, _FREQ_24_576K, 15, 0, 400, 9, 1 },
++ { 24000000, _FREQ_24_576K, 9, 0, 256,24, 0 }, /* accurate, 24M -> 24.576M */
++
++ { 400000, _FREQ_22_579K, 0, 0, 566, 4, 1 },
++ { 512000, _FREQ_22_579K, 0, 0, 880, 9, 1 },
++ { 768000, _FREQ_22_579K, 0, 0, 587, 9, 1 },
++ { 800000, _FREQ_22_579K, 0, 0, 567, 9, 1 },
++ { 1024000, _FREQ_22_579K, 0, 0, 440, 9, 1 },
++ { 1600000, _FREQ_22_579K, 1, 0, 567, 9, 1 },
++ { 2048000, _FREQ_22_579K, 0, 0, 220, 9, 1 },
++ { 3072000, _FREQ_22_579K, 0, 0, 148, 9, 1 },
++ { 4096000, _FREQ_22_579K, 2, 0, 330, 9, 1 },
++ { 6000000, _FREQ_22_579K, 2, 0, 227, 9, 1 },
++ { 12000000, _FREQ_22_579K, 8, 0, 340, 9, 1 },
++ { 13000000, _FREQ_22_579K, 9, 0, 350, 9, 1 },
++ { 15360000, _FREQ_22_579K, 10, 0, 325, 9, 1 },
++ { 16000000, _FREQ_22_579K, 11, 0, 340, 9, 1 },
++ { 19200000, _FREQ_22_579K, 13, 0, 330, 9, 1 },
++ { 19680000, _FREQ_22_579K, 14, 0, 345, 9, 1 },
++ { 24000000, _FREQ_22_579K, 24, 0, 588,24, 0 }, /* accurate, 24M -> 22.5792M */
++
++
++ { _FREQ_24_576K / 1, _FREQ_24_576K, 9, 0, 200, 9, 1 }, /* _FREQ_24_576K */
++ { _FREQ_24_576K / 2, _FREQ_24_576K, 9, 0, 400, 9, 1 }, /* 12288000,accurate, 48000 * 256 */
++ { _FREQ_24_576K / 4, _FREQ_24_576K, 4, 0, 400, 9, 1 }, /* 6144000, accurate, 24000 * 256 */
++ { _FREQ_24_576K / 16, _FREQ_24_576K, 0, 0, 320, 9, 1 }, /* 1536000 */
++ { _FREQ_24_576K / 64, _FREQ_24_576K, 0, 0, 640, 4, 1 }, /* 384000 */
++ { _FREQ_24_576K / 96, _FREQ_24_576K, 0, 0, 960, 4, 1 }, /* 256000 */
++ { _FREQ_24_576K / 128, _FREQ_24_576K, 0, 0, 512, 1, 1 }, /* 192000 */
++ { _FREQ_24_576K / 176, _FREQ_24_576K, 0, 0, 880, 4, 0 }, /* 140000 */
++ { _FREQ_24_576K / 192, _FREQ_24_576K, 0, 0, 960, 4, 0 }, /* 128000 */
++
++ { _FREQ_22_579K / 1, _FREQ_22_579K, 9, 0, 200, 9, 1 }, /* _FREQ_22_579K */
++ { _FREQ_22_579K / 2, _FREQ_22_579K, 9, 0, 400, 9, 1 }, /* 11289600,accurate, 44100 * 256 */
++ { _FREQ_22_579K / 4, _FREQ_22_579K, 4, 0, 400, 9, 1 }, /* 5644800, accurate, 22050 * 256 */
++ { _FREQ_22_579K / 16, _FREQ_22_579K, 0, 0, 320, 9, 1 }, /* 1411200 */
++ { _FREQ_22_579K / 64, _FREQ_22_579K, 0, 0, 640, 4, 1 }, /* 352800 */
++ { _FREQ_22_579K / 96, _FREQ_22_579K, 0, 0, 960, 4, 1 }, /* 235200 */
++ { _FREQ_22_579K / 128, _FREQ_22_579K, 0, 0, 512, 1, 1 }, /* 176400 */
++ { _FREQ_22_579K / 176, _FREQ_22_579K, 0, 0, 880, 4, 0 }, /* 128290 */
++ { _FREQ_22_579K / 192, _FREQ_22_579K, 0, 0, 960, 4, 0 }, /* 117600 */
++
++ { _FREQ_22_579K / 6, _FREQ_22_579K, 2, 0, 360, 9, 1 }, /* 3763200 */
++ { _FREQ_22_579K / 8, _FREQ_22_579K, 0, 0, 160, 9, 1 }, /* 2822400, accurate, 11025 * 256 */
++ { _FREQ_22_579K / 12, _FREQ_22_579K, 0, 0, 240, 9, 1 }, /* 1881600 */
++ { _FREQ_22_579K / 24, _FREQ_22_579K, 0, 0, 480, 9, 1 }, /* 940800 */
++ { _FREQ_22_579K / 32, _FREQ_22_579K, 0, 0, 640, 9, 1 }, /* 705600 */
++ { _FREQ_22_579K / 48, _FREQ_22_579K, 0, 0, 960, 9, 1 }, /* 470400 */
++};
++
++
++/* AC108 definition */
++#define AC108_CHANNELS_MAX 8 /* range[1, 16] */
++#define AC108_RATES (SNDRV_PCM_RATE_8000_96000 & \
++ ~(SNDRV_PCM_RATE_64000 | \
++ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000))
++#define AC108_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
++ /*SNDRV_PCM_FMTBIT_S20_3LE | \
++ SNDRV_PCM_FMTBIT_S24_LE |*/ \
++ SNDRV_PCM_FMTBIT_S32_LE)
++
++static const DECLARE_TLV_DB_SCALE(tlv_adc_pga_gain, 0, 100, 0);
++static const DECLARE_TLV_DB_SCALE(tlv_ch_digital_vol, -11925, 75, 0);
++
++int ac10x_read(u8 reg, u8* rt_val, struct regmap* i2cm)
++{
++ int r, v = 0;
++
++ if ((r = regmap_read(i2cm, reg, &v)) < 0)
++ pr_info("ac10x_read info->[REG-0x%02x]\n", reg);
++ else
++ *rt_val = v;
++ return r;
++}
++
++int ac10x_write(u8 reg, u8 val, struct regmap* i2cm)
++{
++ int r;
++
++ if ((r = regmap_write(i2cm, reg, val)) < 0)
++ pr_info("ac10x_write info->[REG-0x%02x,val-0x%02x]\n", reg, val);
++ return r;
++}
++
++int ac10x_update_bits(u8 reg, u8 mask, u8 val, struct regmap* i2cm)
++{
++ int r;
++
++ if ((r = regmap_update_bits(i2cm, reg, mask, val)) < 0)
++ pr_info("%s() info->[REG-0x%02x,val-0x%02x]\n", __func__, reg, val);
++ return r;
++}
++
++/**
++ * snd_ac108_get_volsw - single mixer get callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to get the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac108_get_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret, chip = mc->autodisable;
++ u8 val;
++
++ if ((ret = ac10x_read(mc->reg, &val, ac10x->i2cmap[chip])) < 0)
++ return ret;
++
++ val = ((val >> mc->shift) & mask) - mc->min;
++ if (invert) {
++ val = mc->max - val;
++ }
++ ucontrol->value.integer.value[0] = val;
++ return 0;
++}
++
++/**
++ * snd_ac108_put_volsw - single mixer put callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to set the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac108_put_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int sign_bit = mc->sign_bit;
++ unsigned int val, mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret, chip = mc->autodisable;
++
++ if (sign_bit)
++ mask = BIT(sign_bit + 1) - 1;
++
++ val = ((ucontrol->value.integer.value[0] + mc->min) & mask);
++ if (invert) {
++ val = mc->max - val;
++ }
++
++ mask = mask << mc->shift;
++ val = val << mc->shift;
++
++ ret = ac10x_update_bits(mc->reg, mask, val, ac10x->i2cmap[chip]);
++ return ret;
++}
++
++#define SOC_AC108_SINGLE_TLV(xname, reg, shift, max, invert, chip, tlv_array) \
++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
++ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
++ SNDRV_CTL_ELEM_ACCESS_READWRITE,\
++ .tlv.p = (tlv_array), \
++ .info = snd_soc_info_volsw, .get = snd_ac108_get_volsw,\
++ .put = snd_ac108_put_volsw, \
++ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, chip) }
++
++/* single ac108 */
++static const struct snd_kcontrol_new ac108_snd_controls[] = {
++ /* ### chip 0 ### */
++ /*0x70: ADC1 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH1 digital volume", ADC1_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x71: ADC2 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH2 digital volume", ADC2_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x72: ADC3 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH3 digital volume", ADC3_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x73: ADC4 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH4 digital volume", ADC4_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++
++ /*0x90: Analog PGA1 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC1 PGA gain", ANA_PGA1_CTRL,
++ ADC1_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x91: Analog PGA2 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC2 PGA gain", ANA_PGA2_CTRL,
++ ADC2_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x92: Analog PGA3 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC3 PGA gain", ANA_PGA3_CTRL,
++ ADC3_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x93: Analog PGA4 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC4 PGA gain", ANA_PGA4_CTRL,
++ ADC4_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++};
++/* multiple ac108s */
++static const struct snd_kcontrol_new ac108tdm_snd_controls[] = {
++ /* ### chip 1 ### */
++ /*0x70: ADC1 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH1 digital volume", ADC1_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++ /*0x71: ADC2 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH2 digital volume", ADC2_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++ /*0x72: ADC3 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH3 digital volume", ADC3_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++ /*0x73: ADC4 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH4 digital volume", ADC4_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++
++ /*0x90: Analog PGA1 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC1 PGA gain", ANA_PGA1_CTRL,
++ ADC1_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++ /*0x91: Analog PGA2 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC2 PGA gain", ANA_PGA2_CTRL,
++ ADC2_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++ /*0x92: Analog PGA3 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC3 PGA gain", ANA_PGA3_CTRL,
++ ADC3_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++ /*0x93: Analog PGA4 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC4 PGA gain", ANA_PGA4_CTRL,
++ ADC4_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++
++ /* ### chip 0 ### */
++ /*0x70: ADC1 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH5 digital volume", ADC1_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x71: ADC2 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH6 digital volume", ADC2_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x72: ADC3 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH7 digital volume", ADC3_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x73: ADC4 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH8 digital volume", ADC4_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++
++ /*0x90: Analog PGA1 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC5 PGA gain", ANA_PGA1_CTRL,
++ ADC1_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x91: Analog PGA2 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC6 PGA gain", ANA_PGA2_CTRL,
++ ADC2_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x92: Analog PGA3 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC7 PGA gain", ANA_PGA3_CTRL,
++ ADC3_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x93: Analog PGA4 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC8 PGA gain", ANA_PGA4_CTRL,
++ ADC4_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++};
++
++
++static const struct snd_soc_dapm_widget ac108_dapm_widgets[] = {
++ /* input widgets */
++ SND_SOC_DAPM_INPUT("MIC1P"),
++ SND_SOC_DAPM_INPUT("MIC1N"),
++
++ SND_SOC_DAPM_INPUT("MIC2P"),
++ SND_SOC_DAPM_INPUT("MIC2N"),
++
++ SND_SOC_DAPM_INPUT("MIC3P"),
++ SND_SOC_DAPM_INPUT("MIC3N"),
++
++ SND_SOC_DAPM_INPUT("MIC4P"),
++ SND_SOC_DAPM_INPUT("MIC4N"),
++
++ SND_SOC_DAPM_INPUT("DMIC1"),
++ SND_SOC_DAPM_INPUT("DMIC2"),
++
++ /*0xa0: ADC1 Analog Control 1 Register*/
++ /*0xa1-0xa6:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 1 AAF", "Capture", 0, ANA_ADC1_CTRL1, ADC1_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 1 EN", ANA_ADC1_CTRL1, ADC1_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC1BIAS", ANA_ADC1_CTRL1, ADC1_MICBIAS_EN, 1),
++
++ /*0xa7: ADC2 Analog Control 1 Register*/
++ /*0xa8-0xad:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 2 AAF", "Capture", 0, ANA_ADC2_CTRL1, ADC2_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 2 EN", ANA_ADC2_CTRL1, ADC2_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC2BIAS", ANA_ADC2_CTRL1, ADC2_MICBIAS_EN, 1),
++
++ /*0xae: ADC3 Analog Control 1 Register*/
++ /*0xaf-0xb4:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 3 AAF", "Capture", 0, ANA_ADC3_CTRL1, ADC3_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 3 EN", ANA_ADC3_CTRL1, ADC3_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC3BIAS", ANA_ADC3_CTRL1, ADC3_MICBIAS_EN, 1),
++
++ /*0xb5: ADC4 Analog Control 1 Register*/
++ /*0xb6-0xbb:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 4 AAF", "Capture", 0, ANA_ADC4_CTRL1, ADC4_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 4 EN", ANA_ADC4_CTRL1, ADC4_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC4BIAS", ANA_ADC4_CTRL1, ADC4_MICBIAS_EN, 1),
++
++
++ /*0x61: ADC Digital Part Enable Register*/
++ SND_SOC_DAPM_SUPPLY("ADC EN", ADC_DIG_EN, 4, 1, NULL, 0),
++ SND_SOC_DAPM_ADC("ADC1", "Capture", ADC_DIG_EN, 0, 1),
++ SND_SOC_DAPM_ADC("ADC2", "Capture", ADC_DIG_EN, 1, 1),
++ SND_SOC_DAPM_ADC("ADC3", "Capture", ADC_DIG_EN, 2, 1),
++ SND_SOC_DAPM_ADC("ADC4", "Capture", ADC_DIG_EN, 3, 1),
++
++ SND_SOC_DAPM_SUPPLY("ADC1 CLK", ANA_ADC4_CTRL7, ADC1_CLK_GATING, 1, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("ADC2 CLK", ANA_ADC4_CTRL7, ADC2_CLK_GATING, 1, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("ADC3 CLK", ANA_ADC4_CTRL7, ADC3_CLK_GATING, 1, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("ADC4 CLK", ANA_ADC4_CTRL7, ADC4_CLK_GATING, 1, NULL, 0),
++
++ SND_SOC_DAPM_SUPPLY("DSM EN", ANA_ADC4_CTRL6, DSM_DEMOFF, 1, NULL, 0),
++
++ /*0x62:Digital MIC Enable Register*/
++ SND_SOC_DAPM_MICBIAS("DMIC1 enable", DMIC_EN, 0, 0),
++ SND_SOC_DAPM_MICBIAS("DMIC2 enable", DMIC_EN, 1, 0),
++};
++
++static const struct snd_soc_dapm_route ac108_dapm_routes[] = {
++
++ { "ADC1", NULL, "Channel 1 AAF" },
++ { "ADC2", NULL, "Channel 2 AAF" },
++ { "ADC3", NULL, "Channel 3 AAF" },
++ { "ADC4", NULL, "Channel 4 AAF" },
++
++ { "Channel 1 AAF", NULL, "MIC1BIAS" },
++ { "Channel 2 AAF", NULL, "MIC2BIAS" },
++ { "Channel 3 AAF", NULL, "MIC3BIAS" },
++ { "Channel 4 AAF", NULL, "MIC4BIAS" },
++
++ { "MIC1BIAS", NULL, "ADC1 CLK" },
++ { "MIC2BIAS", NULL, "ADC2 CLK" },
++ { "MIC3BIAS", NULL, "ADC3 CLK" },
++ { "MIC4BIAS", NULL, "ADC4 CLK" },
++
++
++ { "ADC1 CLK", NULL, "DSM EN" },
++ { "ADC2 CLK", NULL, "DSM EN" },
++ { "ADC3 CLK", NULL, "DSM EN" },
++ { "ADC4 CLK", NULL, "DSM EN" },
++
++
++ { "DSM EN", NULL, "ADC EN" },
++
++ { "Channel 1 EN", NULL, "DSM EN" },
++ { "Channel 2 EN", NULL, "DSM EN" },
++ { "Channel 3 EN", NULL, "DSM EN" },
++ { "Channel 4 EN", NULL, "DSM EN" },
++
++
++ { "MIC1P", NULL, "Channel 1 EN" },
++ { "MIC1N", NULL, "Channel 1 EN" },
++
++ { "MIC2P", NULL, "Channel 2 EN" },
++ { "MIC2N", NULL, "Channel 2 EN" },
++
++ { "MIC3P", NULL, "Channel 3 EN" },
++ { "MIC3N", NULL, "Channel 3 EN" },
++
++ { "MIC4P", NULL, "Channel 4 EN" },
++ { "MIC4N", NULL, "Channel 4 EN" },
++
++};
++
++static int ac108_multi_write(u8 reg, u8 val, struct ac10x_priv *ac10x)
++{
++ u8 i;
++ for (i = 0; i < ac10x->codec_cnt; i++)
++ ac10x_write(reg, val, ac10x->i2cmap[i]);
++ return 0;
++}
++
++static int ac108_multi_update_bits(u8 reg, u8 mask, u8 val, struct ac10x_priv *ac10x)
++{
++ int r = 0;
++ u8 i;
++ for (i = 0; i < ac10x->codec_cnt; i++)
++ r |= ac10x_update_bits(reg, mask, val, ac10x->i2cmap[i]);
++ return r;
++}
++
++static unsigned int ac108_codec_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++ unsigned char val_r;
++ struct ac10x_priv *ac10x = dev_get_drvdata(codec->dev);
++ /*read one chip is fine*/
++ ac10x_read(reg, &val_r, ac10x->i2cmap[_MASTER_INDEX]);
++ return val_r;
++}
++
++static int ac108_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val)
++{
++ struct ac10x_priv *ac10x = dev_get_drvdata(codec->dev);
++ ac108_multi_write(reg, val, ac10x);
++ return 0;
++}
++
++/**
++ * The Power management related registers are Reg01h~Reg09h
++ * 0x01-0x05,0x08,use the default value
++ * @author baozhu (17-6-21)
++ *
++ * @param ac10x
++ */
++static void ac108_configure_power(struct ac10x_priv *ac10x)
++{
++ /**
++ * 0x06:Enable Analog LDO
++ */
++ ac108_multi_update_bits(PWR_CTRL6, 0x01 << LDO33ANA_ENABLE, 0x01 << LDO33ANA_ENABLE, ac10x);
++ /**
++ * 0x07:
++ * Control VREF output and micbias voltage ?
++ * REF faststart disable, enable Enable VREF (needed for Analog
++ * LDO and MICBIAS)
++ */
++ ac108_multi_update_bits(PWR_CTRL7,
++ 0x1f << VREF_SEL | 0x01 << VREF_FASTSTART_ENABLE |
++ 0x01 << VREF_ENABLE,
++ 0x13 << VREF_SEL | 0x00 << VREF_FASTSTART_ENABLE |
++ 0x01 << VREF_ENABLE,
++ ac10x);
++ /**
++ * 0x09:
++ * Disable fast-start circuit on VREFP
++ * VREFP_RESCTRL=00=1 MOhm
++ * IGEN_TRIM=100=+25%
++ * Enable VREFP (needed by all audio input channels)
++ */
++ ac108_multi_update_bits(PWR_CTRL9,
++ 0x01 << VREFP_FASTSTART_ENABLE | 0x03 << VREFP_RESCTRL |
++ 0x07 << IGEN_TRIM | 0x01 << VREFP_ENABLE,
++ 0x00 << VREFP_FASTSTART_ENABLE | 0x00 << VREFP_RESCTRL |
++ 0x04 << IGEN_TRIM | 0x01 << VREFP_ENABLE,
++ ac10x);
++}
++
++/**
++ * The clock management related registers are Reg20h~Reg25h
++ * The PLL management related registers are Reg10h~Reg18h.
++ * @author baozhu (17-6-20)
++ *
++ * @param ac10x
++ * @param rate : sample rate
++ *
++ * @return int : fail or success
++ */
++static int ac108_config_pll(struct ac10x_priv *ac10x, unsigned rate, unsigned lrck_ratio)
++{
++ unsigned int i = 0;
++ struct pll_div ac108_pll_div = { 0 };
++
++ if (ac10x->clk_id == SYSCLK_SRC_PLL) {
++ unsigned pll_src, pll_freq_in;
++
++ if (lrck_ratio == 0) {
++ /* PLL clock source from MCLK */
++ pll_freq_in = ac10x->sysclk;
++ pll_src = 0x0;
++ } else {
++ /* PLL clock source from BCLK */
++ pll_freq_in = rate * lrck_ratio;
++ pll_src = 0x1;
++ }
++
++ /* FOUT =(FIN * N) / [(M1+1) * (M2+1)*(K1+1)*(K2+1)] */
++ for (i = 0; i < ARRAY_SIZE(ac108_pll_div_list); i++) {
++ if (ac108_pll_div_list[i].freq_in == pll_freq_in &&
++ ac108_pll_div_list[i].freq_out % rate == 0) {
++ ac108_pll_div = ac108_pll_div_list[i];
++ dev_info(&ac10x->i2c[_MASTER_INDEX]->dev,
++ "AC108 PLL freq_in match:%u, freq_out:%u\n\n",
++ ac108_pll_div.freq_in, ac108_pll_div.freq_out);
++ break;
++ }
++ }
++ /* 0x11,0x12,0x13,0x14: Config PLL DIV param M1/M2/N/K1/K2 */
++ ac108_multi_update_bits(PLL_CTRL5,
++ 0x1f << PLL_POSTDIV1 | 0x01 << PLL_POSTDIV2,
++ ac108_pll_div.k1 << PLL_POSTDIV1 |
++ ac108_pll_div.k2 << PLL_POSTDIV2, ac10x);
++ ac108_multi_update_bits(PLL_CTRL4, 0xff << PLL_LOOPDIV_LSB,
++ (unsigned char)ac108_pll_div.n << PLL_LOOPDIV_LSB, ac10x);
++ ac108_multi_update_bits(PLL_CTRL3, 0x03 << PLL_LOOPDIV_MSB,
++ (ac108_pll_div.n >> 8) << PLL_LOOPDIV_MSB, ac10x);
++ ac108_multi_update_bits(PLL_CTRL2, 0x1f << PLL_PREDIV1 | 0x01 << PLL_PREDIV2,
++ ac108_pll_div.m1 << PLL_PREDIV1 |
++ ac108_pll_div.m2 << PLL_PREDIV2, ac10x);
++
++ /*0x18: PLL clk lock enable*/
++ ac108_multi_update_bits(PLL_LOCK_CTRL, 0x1 << PLL_LOCK_EN,
++ 0x1 << PLL_LOCK_EN, ac10x);
++
++ /**
++ * 0x20: enable pll, pll source from mclk/bclk, sysclk source from pll, enable sysclk
++ */
++ ac108_multi_update_bits(SYSCLK_CTRL,
++ 0x01 << PLLCLK_EN | 0x03 << PLLCLK_SRC |
++ 0x01 << SYSCLK_SRC | 0x01 << SYSCLK_EN,
++ 0x01 << PLLCLK_EN | pll_src << PLLCLK_SRC |
++ 0x01 << SYSCLK_SRC | 0x01 << SYSCLK_EN, ac10x);
++ ac10x->mclk = ac108_pll_div.freq_out;
++ }
++ if (ac10x->clk_id == SYSCLK_SRC_MCLK) {
++ /**
++ *0x20: sysclk source from mclk, enable sysclk
++ */
++ ac108_multi_update_bits(SYSCLK_CTRL,
++ 0x01 << PLLCLK_EN | 0x01 << SYSCLK_SRC | 0x01 << SYSCLK_EN,
++ 0x00 << PLLCLK_EN | 0x00 << SYSCLK_SRC | 0x01 << SYSCLK_EN,
++ ac10x);
++ ac10x->mclk = ac10x->sysclk;
++ }
++
++ return 0;
++}
++
++/*
++ * support no more than 16 slots.
++ */
++static int ac108_multi_chips_slots(struct ac10x_priv *ac, int slots)
++{
++ int i;
++
++ /*
++ * codec0 enable slots 2,3,0,1 when 1 codec
++ *
++ * codec0 enable slots 6,7,0,1 when 2 codec
++ * codec1 enable slots 2,3,4,5
++ *
++ * ...
++ */
++ for (i = 0; i < ac->codec_cnt; i++) {
++ /* rotate map, due to channels rotated by CPU_DAI */
++ const unsigned vec_mask[] = {
++ 0x3 << 6 | 0x3, // slots 6,7,0,1
++ 0xF << 2, // slots 2,3,4,5
++ 0,
++ 0,
++ };
++ const unsigned vec_maps[] = {
++ /*
++ * chip 0,
++ * mic 0 sample -> slot 6
++ * mic 1 sample -> slot 7
++ * mic 2 sample -> slot 0
++ * mic 3 sample -> slot 1
++ */
++ 0x0 << 12 | 0x1 << 14 | 0x2 << 0 | 0x3 << 2,
++ /*
++ * chip 1,
++ * mic 0 sample -> slot 2
++ * mic 1 sample -> slot 3
++ * mic 2 sample -> slot 4
++ * mic 3 sample -> slot 5
++ */
++ 0x0 << 4 | 0x1 << 6 | 0x2 << 8 | 0x3 << 10,
++ 0,
++ 0,
++ };
++ unsigned vec;
++
++ /* 0x38-0x3A I2S_TX1_CTRLx */
++ if (ac->codec_cnt == 1) {
++ vec = 0xFUL;
++ } else {
++ vec = vec_mask[i];
++ }
++ ac10x_write(I2S_TX1_CTRL1, slots - 1, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CTRL2, (vec >> 0) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CTRL3, (vec >> 8) & 0xFF, ac->i2cmap[i]);
++
++ /* 0x3C-0x3F I2S_TX1_CHMP_CTRLx */
++ if (ac->codec_cnt == 1) {
++ vec = (0x2 << 0 | 0x3 << 2 | 0x0 << 4 | 0x1 << 6);
++ } else if (ac->codec_cnt == 2) {
++ vec = vec_maps[i];
++ }
++
++ ac10x_write(I2S_TX1_CHMP_CTRL1, (vec >> 0) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CHMP_CTRL2, (vec >> 8) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CHMP_CTRL3, (vec >> 16) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CHMP_CTRL4, (vec >> 24) & 0xFF, ac->i2cmap[i]);
++ }
++ return 0;
++}
++
++static int ac108_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++{
++ unsigned int i, channels, samp_res, rate;
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ unsigned bclkdiv;
++ int ret = 0;
++ u8 v;
++
++ dev_dbg(dai->dev, "%s() stream=%s play:%d capt:%d +++\n", __func__,
++ snd_pcm_stream_str(substream),
++ dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active,
++ dai->stream[SNDRV_PCM_STREAM_CAPTURE].active);
++
++ if (ac10x->i2c101) {
++ ret = ac101_hw_params(substream, params, dai);
++ if (ret > 0) {
++ dev_dbg(dai->dev, "%s() L%d returned\n", __func__, __LINE__);
++ /* not configure hw_param twice */
++ return 0;
++ }
++ }
++
++ if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
++ dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active)
++ || (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
++ dai->stream[SNDRV_PCM_STREAM_CAPTURE].active)) {
++ /* not configure hw_param twice */
++ /* return 0; */
++ }
++
++ channels = params_channels(params);
++
++ /* Master mode, to clear cpu_dai fifos, output bclk without lrck */
++ ac10x_read(I2S_CTRL, &v, ac10x->i2cmap[_MASTER_INDEX]);
++ if (v & (0x01 << BCLK_IOEN)) {
++ ac10x_update_bits(I2S_CTRL, 0x1 << LRCK_IOEN,
++ 0x0 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
++ }
++
++ switch (params_format(params)) {
++ case SNDRV_PCM_FORMAT_S8:
++ samp_res = 0;
++ break;
++ case SNDRV_PCM_FORMAT_S16_LE:
++ samp_res = 2;
++ break;
++ case SNDRV_PCM_FORMAT_S20_3LE:
++ samp_res = 3;
++ break;
++ case SNDRV_PCM_FORMAT_S24_LE:
++ samp_res = 4;
++ break;
++ case SNDRV_PCM_FORMAT_S32_LE:
++ samp_res = 6;
++ break;
++ default:
++ dev_err(dai->dev, "AC108 don't supported the sample resolution: %u\n",
++ params_format(params));
++ return -EINVAL;
++ }
++
++ for (i = 0; i < ARRAY_SIZE(ac108_sample_rate); i++) {
++ if (ac108_sample_rate[i].real_val == params_rate(params) /
++ (ac10x->data_protocol + 1UL)) {
++ rate = i;
++ break;
++ }
++ }
++ if (i >= ARRAY_SIZE(ac108_sample_rate)) {
++ return -EINVAL;
++ }
++
++ if (channels == 8 && ac108_sample_rate[rate].real_val == 96000) {
++ /* 24.576M bit clock is not support by ac108 */
++ return -EINVAL;
++ }
++
++ dev_dbg(dai->dev, "rate: %d , channels: %d , samp_res: %d",
++ ac108_sample_rate[rate].real_val,
++ channels,
++ ac108_samp_res[samp_res].real_val);
++
++ /**
++ * 0x33:
++ * The 8-Low bit of LRCK period value. It is used to program
++ * the number of BCLKs per channel of sample frame. This value
++ * is interpreted as follow:
++ * The 8-Low bit of LRCK period value. It is used to program
++ * the number of BCLKs per channel of sample frame. This value
++ * is interpreted as follow: PCM mode: Number of BCLKs within
++ * (Left + Right) channel width I2S / Left-Justified /
++ * Right-Justified mode: Number of BCLKs within each individual
++ * channel width (Left or Right) N+1
++ * For example:
++ * n = 7: 8 BCLK width
++ * …
++ * n = 1023: 1024 BCLKs width
++ * 0X32[0:1]:
++ * The 2-High bit of LRCK period value.
++ */
++ if (ac10x->i2s_mode != PCM_FORMAT) {
++ if (ac10x->data_protocol) {
++ ac108_multi_write(I2S_LRCK_CTRL2, ac108_samp_res[samp_res].real_val - 1,
++ ac10x);
++ /*encoding mode, the max LRCK period value < 32,so the 2-High bit is zero*/
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, 0x00, ac10x);
++ } else {
++ /*TDM mode or normal mode*/
++ //ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, 0x00, ac10x);
++ ac108_multi_write(I2S_LRCK_CTRL2, ac108_samp_res[samp_res].real_val - 1,
++ ac10x);
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, 0x00, ac10x);
++ }
++ } else {
++ unsigned div;
++
++ /*TDM mode or normal mode*/
++ div = ac108_samp_res[samp_res].real_val * channels - 1;
++ ac108_multi_write(I2S_LRCK_CTRL2, (div & 0xFF), ac10x);
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, (div >> 8) << 0, ac10x);
++ }
++
++ /**
++ * 0x35:
++ * TX Encoding mode will add 4bits to mark channel number
++ * TODO: need a chat to explain this
++ */
++ ac108_multi_update_bits(I2S_FMT_CTRL2, 0x07 << SAMPLE_RESOLUTION | 0x07 << SLOT_WIDTH_SEL,
++ ac108_samp_res[samp_res].reg_val << SAMPLE_RESOLUTION |
++ ac108_samp_res[samp_res].reg_val << SLOT_WIDTH_SEL, ac10x);
++
++ /**
++ * 0x60:
++ * ADC Sample Rate synchronised with I2S1 clock zone
++ */
++ ac108_multi_update_bits(ADC_SPRC, 0x0f << ADC_FS_I2S1,
++ ac108_sample_rate[rate].reg_val << ADC_FS_I2S1, ac10x);
++ ac108_multi_write(HPF_EN, 0x0F, ac10x);
++
++ if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
++ ac108_config_pll(ac10x, ac108_sample_rate[rate].real_val,
++ ac108_samp_res[samp_res].real_val * channels);
++ } else {
++ ac108_config_pll(ac10x, ac108_sample_rate[rate].real_val, 0);
++ }
++
++ /*
++ * master mode only
++ */
++ bclkdiv = ac10x->mclk / (ac108_sample_rate[rate].real_val * channels *
++ ac108_samp_res[samp_res].real_val);
++ for (i = 0; i < ARRAY_SIZE(ac108_bclkdivs) - 1; i++) {
++ if (ac108_bclkdivs[i] >= bclkdiv) {
++ break;
++ }
++ }
++ ac108_multi_update_bits(I2S_BCLK_CTRL, 0x0F << BCLKDIV, i << BCLKDIV, ac10x);
++
++ /*
++ * slots allocation for each chip
++ */
++ ac108_multi_chips_slots(ac10x, channels);
++
++ /*0x21: Module clock enable<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_CLK_EN, 1 << I2S | 1 << ADC_DIGITAL |
++ 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
++ /*0x22: Module reset de-asserted<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_RST_CTRL, 1 << I2S | 1 << ADC_DIGITAL |
++ 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
++
++ ac108_multi_write(I2S_TX1_CHMP_CTRL1, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX1_CHMP_CTRL2, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX1_CHMP_CTRL3, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX1_CHMP_CTRL4, 0xE4, ac10x);
++
++ ac108_multi_write(I2S_TX2_CHMP_CTRL1, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX2_CHMP_CTRL2, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX2_CHMP_CTRL3, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX2_CHMP_CTRL4, 0xE4, ac10x);
++
++ dev_dbg(dai->dev, "%s() stream=%s ---\n", __func__,
++ snd_pcm_stream_str(substream));
++
++ return 0;
++}
++
++static int ac108_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir)
++{
++
++ struct ac10x_priv *ac10x = snd_soc_dai_get_drvdata(dai);
++
++ freq = 24000000;
++ clk_id = SYSCLK_SRC_PLL;
++
++ switch (clk_id) {
++ case SYSCLK_SRC_MCLK:
++ ac108_multi_update_bits(SYSCLK_CTRL, 0x1 << SYSCLK_SRC,
++ SYSCLK_SRC_MCLK << SYSCLK_SRC, ac10x);
++ break;
++ case SYSCLK_SRC_PLL:
++ ac108_multi_update_bits(SYSCLK_CTRL, 0x1 << SYSCLK_SRC,
++ SYSCLK_SRC_PLL << SYSCLK_SRC, ac10x);
++ break;
++ default:
++ return -EINVAL;
++ }
++ ac10x->sysclk = freq;
++ ac10x->clk_id = clk_id;
++
++ return 0;
++}
++
++/**
++ * The i2s format management related registers are Reg
++ * 30h~Reg36h
++ * 33h,35h will be set in ac108_hw_params, It's BCLK width and
++ * Sample Resolution.
++ * @author baozhu (17-6-20)
++ *
++ * @param dai
++ * @param fmt
++ *
++ * @return int
++ */
++static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++ unsigned char tx_offset, lrck_polarity, brck_polarity;
++ struct ac10x_priv *ac10x = dev_get_drvdata(dai->dev);
++
++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++ case SND_SOC_DAIFMT_CBM_CFM: /* AC108 Master */
++ if (! ac10x->i2c101 || _MASTER_MULTI_CODEC == _MASTER_AC108) {
++ /**
++ * 0x30:chip is master mode ,BCLK & LRCK output
++ */
++ ac108_multi_update_bits(I2S_CTRL,
++ 0x03 << LRCK_IOEN | 0x03 << SDO1_EN |
++ 0x1 << TXEN | 0x1 << GEN,
++ 0x03 << LRCK_IOEN | 0x01 << SDO1_EN |
++ 0x1 << TXEN | 0x1 << GEN, ac10x);
++ /* multi_chips: only one chip set as Master, and the others also need to set as Slave */
++ ac10x_update_bits(I2S_CTRL, 0x3 << LRCK_IOEN, 0x01 << BCLK_IOEN,
++ ac10x->i2cmap[_MASTER_INDEX]);
++ } else {
++ /* TODO: Both cpu_dai and codec_dai(AC108) be set as slave in DTS */
++ dev_err(dai->dev, "used as slave when AC101 is master\n");
++ }
++ break;
++ case SND_SOC_DAIFMT_CBS_CFS: /* AC108 Slave */
++ /**
++ * 0x30:chip is slave mode, BCLK & LRCK input,enable SDO1_EN and
++ * SDO2_EN, Transmitter Block Enable, Globe Enable
++ */
++ ac108_multi_update_bits(I2S_CTRL,
++ 0x03 << LRCK_IOEN | 0x03 << SDO1_EN |
++ 0x1 << TXEN | 0x1 << GEN,
++ 0x00 << LRCK_IOEN | 0x03 << SDO1_EN |
++ 0x0 << TXEN | 0x0 << GEN, ac10x);
++ break;
++ default:
++ dev_err(dai->dev, "AC108 Master/Slave mode config error:%u\n\n",
++ (fmt & SND_SOC_DAIFMT_MASTER_MASK) >> 12);
++ return -EINVAL;
++ }
++
++ /*AC108 config I2S/LJ/RJ/PCM format*/
++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++ case SND_SOC_DAIFMT_I2S:
++ ac10x->i2s_mode = LEFT_JUSTIFIED_FORMAT;
++ tx_offset = 1;
++ break;
++ case SND_SOC_DAIFMT_RIGHT_J:
++ ac10x->i2s_mode = RIGHT_JUSTIFIED_FORMAT;
++ tx_offset = 0;
++ break;
++ case SND_SOC_DAIFMT_LEFT_J:
++ ac10x->i2s_mode = LEFT_JUSTIFIED_FORMAT;
++ tx_offset = 0;
++ break;
++ case SND_SOC_DAIFMT_DSP_A:
++ ac10x->i2s_mode = PCM_FORMAT;
++ tx_offset = 1;
++ break;
++ case SND_SOC_DAIFMT_DSP_B:
++ ac10x->i2s_mode = PCM_FORMAT;
++ tx_offset = 0;
++ break;
++ default:
++ dev_err(dai->dev, "AC108 I2S format config error:%u\n\n",
++ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
++ return -EINVAL;
++ }
++
++ /*AC108 config BCLK&LRCK polarity*/
++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++ case SND_SOC_DAIFMT_NB_NF:
++ brck_polarity = BCLK_NORMAL_DRIVE_N_SAMPLE_P;
++ lrck_polarity = LRCK_LEFT_HIGH_RIGHT_LOW;
++ break;
++ case SND_SOC_DAIFMT_NB_IF:
++ brck_polarity = BCLK_NORMAL_DRIVE_N_SAMPLE_P;
++ lrck_polarity = LRCK_LEFT_LOW_RIGHT_HIGH;
++ break;
++ case SND_SOC_DAIFMT_IB_NF:
++ brck_polarity = BCLK_INVERT_DRIVE_P_SAMPLE_N;
++ lrck_polarity = LRCK_LEFT_HIGH_RIGHT_LOW;
++ break;
++ case SND_SOC_DAIFMT_IB_IF:
++ brck_polarity = BCLK_INVERT_DRIVE_P_SAMPLE_N;
++ lrck_polarity = LRCK_LEFT_LOW_RIGHT_HIGH;
++ break;
++ default:
++ dev_err(dai->dev, "AC108 config BCLK/LRCLK polarity error:%u\n\n",
++ (fmt & SND_SOC_DAIFMT_INV_MASK) >> 8);
++ return -EINVAL;
++ }
++
++ ac108_configure_power(ac10x);
++
++ /**
++ *0x31: 0: normal mode, negative edge drive and positive edge sample
++ 1: invert mode, positive edge drive and negative edge sample
++ */
++ ac108_multi_update_bits(I2S_BCLK_CTRL, 0x01 << BCLK_POLARITY,
++ brck_polarity << BCLK_POLARITY, ac10x);
++ /**
++ * 0x32: same as 0x31
++ */
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x01 << LRCK_POLARITY,
++ lrck_polarity << LRCK_POLARITY, ac10x);
++ /**
++ * 0x34:Encoding Mode Selection,Mode
++ * Selection,data is offset by 1 BCLKs to LRCK
++ * normal mode for the last half cycle of BCLK in the slot ?
++ * turn to hi-z state (TDM) when not transferring slot ?
++ */
++ ac108_multi_update_bits(I2S_FMT_CTRL1,
++ 0x01 << ENCD_SEL | 0x03 << MODE_SEL | 0x01 << TX2_OFFSET |
++ 0x01 << TX1_OFFSET | 0x01 << TX_SLOT_HIZ | 0x01 << TX_STATE,
++ ac10x->data_protocol << ENCD_SEL | ac10x->i2s_mode << MODE_SEL |
++ tx_offset << TX2_OFFSET | tx_offset << TX1_OFFSET |
++ 0x00 << TX_SLOT_HIZ | 0x01 << TX_STATE, ac10x);
++
++ /**
++ * 0x60:
++ * MSB / LSB First Select: This driver only support MSB First Select .
++ * OUT2_MUTE,OUT1_MUTE shoule be set in widget.
++ * LRCK = 1 BCLK width
++ * Linear PCM
++ *
++ * TODO:pcm mode, bit[0:1] and bit[2] is special
++ */
++ ac108_multi_update_bits(I2S_FMT_CTRL3,
++ 0x01 << TX_MLS | 0x03 << SEXT |
++ 0x01 << LRCK_WIDTH | 0x03 << TX_PDM,
++ 0x00 << TX_MLS | 0x03 << SEXT |
++ 0x00 << LRCK_WIDTH | 0x00 << TX_PDM, ac10x);
++
++ ac108_multi_write(HPF_EN, 0x00, ac10x);
++
++ if (ac10x->i2c101) {
++ return ac101_set_dai_fmt(dai, fmt);
++ }
++ return 0;
++}
++
++/*
++ * due to miss channels order in cpu_dai, we meed defer the clock starting.
++ */
++static int ac108_set_clock(int y_start_n_stop)
++{
++ u8 reg;
++ int ret = 0;
++
++ dev_dbg(ac10x->codec->dev, "%s() L%d cmd:%d\n", __func__, __LINE__, y_start_n_stop);
++
++ /* spin_lock move to machine trigger */
++
++ if (y_start_n_stop && ac10x->sysclk_en == 0) {
++ /* enable lrck clock */
++ ac10x_read(I2S_CTRL, &reg, ac10x->i2cmap[_MASTER_INDEX]);
++ if (reg & (0x01 << BCLK_IOEN)) {
++ ret = ret || ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN,
++ 0x03 << LRCK_IOEN,
++ ac10x->i2cmap[_MASTER_INDEX]);
++ }
++
++ /*0x10: PLL Common voltage enable, PLL enable */
++ ret = ret || ac108_multi_update_bits(PLL_CTRL1,
++ 0x01 << PLL_EN | 0x01 << PLL_COM_EN,
++ 0x01 << PLL_EN | 0x01 << PLL_COM_EN, ac10x);
++ /* enable global clock */
++ ret = ret || ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN,
++ 0x1 << TXEN | 0x1 << GEN, ac10x);
++
++ ac10x->sysclk_en = 1UL;
++ } else if (!y_start_n_stop && ac10x->sysclk_en != 0) {
++ /* disable global clock */
++ ret = ret || ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN,
++ 0x0 << TXEN | 0x0 << GEN, ac10x);
++
++ /*0x10: PLL Common voltage disable, PLL disable */
++ ret = ret || ac108_multi_update_bits(PLL_CTRL1, 0x01 << PLL_EN | 0x01 << PLL_COM_EN,
++ 0x00 << PLL_EN | 0x00 << PLL_COM_EN, ac10x);
++
++ /* disable lrck clock if it's enabled */
++ ac10x_read(I2S_CTRL, &reg, ac10x->i2cmap[_MASTER_INDEX]);
++ if (reg & (0x01 << LRCK_IOEN)) {
++ ret = ret || ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN,
++ 0x01 << BCLK_IOEN,
++ ac10x->i2cmap[_MASTER_INDEX]);
++ }
++ if (!ret) {
++ ac10x->sysclk_en = 0UL;
++ }
++ }
++
++ return ret;
++}
++
++static int ac108_prepare(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ u8 r;
++
++ dev_dbg(dai->dev, "%s() stream=%s\n",
++ __func__,
++ snd_pcm_stream_str(substream));
++
++ if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
++ ac101_trigger(substream, SNDRV_PCM_TRIGGER_START, dai);
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ return 0;
++ }
++ }
++
++ ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
++ if ((r & (0x01 << BCLK_IOEN)) && (r & (0x01 << LRCK_IOEN)) == 0) {
++ /* disable global clock */
++ ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN,
++ 0x0 << TXEN | 0x0 << GEN, ac10x);
++ }
++
++ /* delayed clock starting, move to machine trigger() */
++ ac108_set_clock(1);
++
++ return 0;
++}
++
++int ac108_audio_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (ac10x->i2c101) {
++ return ac101_audio_startup(substream, dai);
++ }
++ return 0;
++}
++
++void ac108_aif_shutdown(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ ac108_set_clock(0);
++
++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
++ /*0x21: Module clock disable <I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_CLK_EN, 0x0, ac10x);
++ /*0x22: Module reset asserted <I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_RST_CTRL, 0x0, ac10x);
++ }
++
++ if (ac10x->i2c101) {
++ ac101_aif_shutdown(substream, dai);
++ }
++}
++
++int ac108_aif_mute(struct snd_soc_dai *dai, int mute, int stream)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (ac10x->i2c101) {
++ return ac101_aif_mute(dai, mute);
++ }
++ return 0;
++}
++
++static const struct snd_soc_dai_ops ac108_dai_ops = {
++ .startup = ac108_audio_startup,
++ .shutdown = ac108_aif_shutdown,
++
++ /*DAI clocking configuration*/
++ .set_sysclk = ac108_set_sysclk,
++
++ /*ALSA PCM audio operations*/
++ .hw_params = ac108_hw_params,
++ .prepare = ac108_prepare,
++ .mute_stream = ac108_aif_mute,
++
++ /*DAI format configuration*/
++ .set_fmt = ac108_set_fmt,
++};
++
++static struct snd_soc_dai_driver ac108_dai0 = {
++ .name = "ac10x-codec0",
++ #if _USE_CAPTURE
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ #endif
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ .ops = &ac108_dai_ops,
++};
++
++static struct snd_soc_dai_driver ac108_dai1 = {
++ .name = "ac10x-codec1",
++ #if _USE_CAPTURE
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ #endif
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ .ops = &ac108_dai_ops,
++};
++
++static struct snd_soc_dai_driver *ac108_dai[] = {
++ &ac108_dai0,
++ &ac108_dai1,
++};
++
++static int ac108_add_widgets(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
++ const struct snd_kcontrol_new* snd_kcntl = ac108_snd_controls;
++ int ctrl_cnt = ARRAY_SIZE(ac108_snd_controls);
++
++ /* only register controls correspond to exist chips */
++ if (ac10x->tdm_chips_cnt >= 2) {
++ snd_kcntl = ac108tdm_snd_controls;
++ ctrl_cnt = ARRAY_SIZE(ac108tdm_snd_controls);
++ }
++ snd_soc_add_codec_controls(codec, snd_kcntl, ctrl_cnt);
++
++ snd_soc_dapm_new_controls(dapm, ac108_dapm_widgets,ARRAY_SIZE(ac108_dapm_widgets));
++ snd_soc_dapm_add_routes(dapm, ac108_dapm_routes, ARRAY_SIZE(ac108_dapm_routes));
++
++ return 0;
++}
++
++static int ac108_codec_probe(struct snd_soc_codec *codec)
++{
++ spin_lock_init(&ac10x->lock);
++
++ ac10x->codec = codec;
++ dev_set_drvdata(codec->dev, ac10x);
++ ac108_add_widgets(codec);
++
++ if (ac10x->i2c101) {
++ ac101_codec_probe(codec);
++ }
++
++ /* change default volume */
++ ac108_multi_update_bits(ADC1_DVOL_CTRL, 0xff, 0xc8, ac10x);
++ ac108_multi_update_bits(ADC2_DVOL_CTRL, 0xff, 0xc8, ac10x);
++ ac108_multi_update_bits(ADC3_DVOL_CTRL, 0xff, 0xc8, ac10x);
++ ac108_multi_update_bits(ADC4_DVOL_CTRL, 0xff, 0xc8, ac10x);
++
++ return 0;
++}
++
++static int ac108_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ dev_dbg(codec->dev, "AC108 level:%d\n", level);
++
++ switch (level) {
++ case SND_SOC_BIAS_ON:
++ ac108_multi_update_bits(ANA_ADC1_CTRL1, 0x01 << ADC1_MICBIAS_EN,
++ 0x01 << ADC1_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC2_CTRL1, 0x01 << ADC2_MICBIAS_EN,
++ 0x01 << ADC2_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC3_CTRL1, 0x01 << ADC3_MICBIAS_EN,
++ 0x01 << ADC3_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC4_CTRL1, 0x01 << ADC4_MICBIAS_EN,
++ 0x01 << ADC4_MICBIAS_EN, ac10x);
++ break;
++
++ case SND_SOC_BIAS_PREPARE:
++ /* Put the MICBIASes into regulating mode */
++ break;
++
++ case SND_SOC_BIAS_STANDBY:
++ break;
++
++ case SND_SOC_BIAS_OFF:
++ ac108_multi_update_bits(ANA_ADC1_CTRL1, 0x01 << ADC1_MICBIAS_EN,
++ 0x00 << ADC1_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC2_CTRL1, 0x01 << ADC2_MICBIAS_EN,
++ 0x00 << ADC2_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC3_CTRL1, 0x01 << ADC3_MICBIAS_EN,
++ 0x00 << ADC3_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC4_CTRL1, 0x01 << ADC4_MICBIAS_EN,
++ 0x00 << ADC4_MICBIAS_EN, ac10x);
++ break;
++ }
++
++ if (ac10x->i2c101) {
++ ac101_set_bias_level(codec, level);
++ }
++ return 0;
++}
++
++int ac108_codec_remove(struct snd_soc_codec *codec) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (! ac10x->i2c101) {
++ return 0;
++ }
++ return ac101_codec_remove(codec);
++}
++#if __NO_SND_SOC_CODEC_DRV
++void ac108_codec_remove_void(struct snd_soc_codec *codec)
++{
++ ac108_codec_remove(codec);
++}
++#define ac108_codec_remove ac108_codec_remove_void
++#endif
++
++int ac108_codec_suspend(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int i;
++
++ for (i = 0; i < ac10x->codec_cnt; i++) {
++ regcache_cache_only(ac10x->i2cmap[i], true);
++ }
++
++ if (! ac10x->i2c101) {
++ return 0;
++ }
++ return ac101_codec_suspend(codec);
++}
++
++int ac108_codec_resume(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int i, ret;
++
++ /* Sync reg_cache with the hardware */
++ for (i = 0; i < ac10x->codec_cnt; i++) {
++ regcache_cache_only(ac10x->i2cmap[i], false);
++ ret = regcache_sync(ac10x->i2cmap[i]);
++ if (ret != 0) {
++ dev_err(codec->dev, "Failed to sync i2cmap%d register cache: %d\n",
++ i, ret);
++ regcache_cache_only(ac10x->i2cmap[i], true);
++ }
++ }
++
++ if (! ac10x->i2c101) {
++ return 0;
++ }
++ return ac101_codec_resume(codec);
++}
++
++static struct snd_soc_codec_driver ac10x_soc_codec_driver = {
++ .probe = ac108_codec_probe,
++ .remove = ac108_codec_remove,
++ .suspend = ac108_codec_suspend,
++ .resume = ac108_codec_resume,
++ .set_bias_level = ac108_set_bias_level,
++ .read = ac108_codec_read,
++ .write = ac108_codec_write,
++};
++
++static ssize_t ac108_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ int val = 0, flag = 0;
++ u8 i = 0, reg, num, value_w, value_r[4];
++
++ val = simple_strtol(buf, NULL, 16);
++ flag = (val >> 16) & 0xF;
++
++ if (flag) {
++ reg = (val >> 8) & 0xFF;
++ value_w = val & 0xFF;
++ ac108_multi_write(reg, value_w, ac10x);
++ dev_info(dev, "Write 0x%02x to REG:0x%02x\n", value_w, reg);
++ } else {
++ int k;
++
++ reg = (val >> 8) & 0xFF;
++ num = val & 0xff;
++ dev_info(dev, "\nRead: start REG:0x%02x,count:0x%02x\n", reg, num);
++
++ for (k = 0; k < ac10x->codec_cnt; k++)
++ regcache_cache_bypass(ac10x->i2cmap[k], true);
++
++ do {
++ memset(value_r, 0, sizeof value_r);
++
++ for (k = 0; k < ac10x->codec_cnt; k++)
++ ac10x_read(reg, &value_r[k], ac10x->i2cmap[k]);
++
++ if (ac10x->codec_cnt >= 2)
++ dev_info(dev, "REG[0x%02x]: 0x%02x 0x%02x", reg,
++ value_r[0], value_r[1]);
++ else
++ dev_info(dev, "REG[0x%02x]: 0x%02x", reg, value_r[0]);
++ reg++;
++
++ if ((++i == num) || (i % 4 == 0))
++ dev_info(dev, "\n");
++ } while (i < num);
++
++ for (k = 0; k < ac10x->codec_cnt; k++)
++ regcache_cache_bypass(ac10x->i2cmap[k], false);
++ }
++
++ return count;
++}
++
++static ssize_t ac108_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ dev_info(dev, "echo flag|reg|val > ac108\n");
++ dev_info(dev, "eg read star addres=0x06,count 0x10:echo 0610 >ac108\n");
++ dev_info(dev, "eg write value:0xfe to address:0x06 :echo 106fe > ac108\n");
++ return 0;
++}
++
++static DEVICE_ATTR(ac108, 0644, ac108_show, ac108_store);
++static struct attribute *ac108_debug_attrs[] = {
++ &dev_attr_ac108.attr,
++ NULL,
++};
++static struct attribute_group ac108_debug_attr_group = {
++ .name = "ac108_debug",
++ .attrs = ac108_debug_attrs,
++};
++
++static const struct i2c_device_id ac108_i2c_id[] = {
++ { "ac108_0", 0 },
++ { "ac108_1", 1 },
++ { "ac108_2", 2 },
++ { "ac108_3", 3 },
++ { "ac101", AC101_I2C_ID },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ac108_i2c_id);
++
++static const struct regmap_config ac108_regmap = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .reg_stride = 1,
++ .max_register = 0xDF,
++ .cache_type = REGCACHE_FLAT,
++};
++static int ac108_i2c_probe(struct i2c_client *i2c)
++{
++ struct device_node *np = i2c->dev.of_node;
++ const struct i2c_device_id *i2c_id;
++ unsigned int val = 0;
++ int ret = 0, index;
++
++ if (ac10x == NULL) {
++ ac10x = kzalloc(sizeof(struct ac10x_priv), GFP_KERNEL);
++ if (ac10x == NULL) {
++ dev_err(&i2c->dev, "Unable to allocate ac10x private data\n");
++ return -ENOMEM;
++ }
++ }
++
++ i2c_id = i2c_match_id(ac108_i2c_id, i2c);
++ index = (int)i2c_id->driver_data;
++ if (index == AC101_I2C_ID) {
++ ac10x->i2c101 = i2c;
++ i2c_set_clientdata(i2c, ac10x);
++ ret = ac101_probe(i2c, i2c_id);
++ if (ret) {
++ ac10x->i2c101 = NULL;
++ return ret;
++ }
++ goto __ret;
++ }
++
++ ret = of_property_read_u32(np, "data-protocol", &val);
++ if (ret) {
++ dev_err(&i2c->dev, "Please set data-protocol.\n");
++ return -EINVAL;
++ }
++ ac10x->data_protocol = val;
++
++ if (of_property_read_u32(np, "tdm-chips-count", &val)) val = 1;
++ ac10x->tdm_chips_cnt = val;
++
++ dev_info(&i2c->dev, " ac10x i2c_id number: %d\n", index);
++ dev_info(&i2c->dev, " ac10x data protocol: %d\n", ac10x->data_protocol);
++
++ ac10x->i2c[index] = i2c;
++ ac10x->i2cmap[index] = devm_regmap_init_i2c(i2c, &ac108_regmap);
++ if (IS_ERR(ac10x->i2cmap[index])) {
++ ret = PTR_ERR(ac10x->i2cmap[index]);
++ dev_err(&i2c->dev, "Fail to initialize i2cmap%d I/O: %d\n", index, ret);
++ return ret;
++ }
++
++ /*
++ * Writing this register with 0x12
++ * will resets all register to their default state.
++ */
++ regcache_cache_only(ac10x->i2cmap[index], false);
++
++ ret = regmap_write(ac10x->i2cmap[index], CHIP_RST, CHIP_RST_VAL);
++ msleep(1);
++
++ /* sync regcache for FLAT type */
++ ac10x_fill_regcache(&i2c->dev, ac10x->i2cmap[index]);
++
++ ac10x->codec_cnt++;
++ dev_info(&i2c->dev, " ac10x codec count : %d\n", ac10x->codec_cnt);
++
++ ret = sysfs_create_group(&i2c->dev.kobj, &ac108_debug_attr_group);
++ if (ret) {
++ dev_err(&i2c->dev, "failed to create attr group\n");
++ }
++
++__ret:
++ /* It's time to bind codec to i2c[_MASTER_INDEX] when all i2c are ready */
++ if ((ac10x->codec_cnt != 0 && ac10x->tdm_chips_cnt < 2)
++ || (ac10x->i2c[0] && ac10x->i2c[1] && ac10x->i2c101)) {
++ /* no playback stream */
++ if (! ac10x->i2c101) {
++ memset(&ac108_dai[_MASTER_INDEX]->playback, '\0',
++ sizeof ac108_dai[_MASTER_INDEX]->playback);
++ }
++ ret = snd_soc_register_codec(&ac10x->i2c[_MASTER_INDEX]->dev,
++ &ac10x_soc_codec_driver,
++ ac108_dai[_MASTER_INDEX], 1);
++ if (ret < 0) {
++ dev_err(&i2c->dev, "Failed to register ac10x codec: %d\n", ret);
++ }
++ }
++ return ret;
++}
++
++static void ac108_i2c_remove(struct i2c_client *i2c)
++{
++ if (ac10x->codec != NULL) {
++ snd_soc_unregister_codec(&ac10x->i2c[_MASTER_INDEX]->dev);
++ ac10x->codec = NULL;
++ }
++ if (i2c == ac10x->i2c101) {
++ ac101_remove(ac10x->i2c101);
++ ac10x->i2c101 = NULL;
++ goto __ret;
++ }
++
++ if (i2c == ac10x->i2c[0]) {
++ ac10x->i2c[0] = NULL;
++ }
++ if (i2c == ac10x->i2c[1]) {
++ ac10x->i2c[1] = NULL;
++ }
++
++ sysfs_remove_group(&i2c->dev.kobj, &ac108_debug_attr_group);
++
++__ret:
++ if (!ac10x->i2c[0] && !ac10x->i2c[1] && !ac10x->i2c101) {
++ kfree(ac10x);
++ ac10x = NULL;
++ }
++}
++
++static const struct of_device_id ac108_of_match[] = {
++ { .compatible = "x-power,ac108_0", },
++ { .compatible = "x-power,ac108_1", },
++ { .compatible = "x-power,ac108_2", },
++ { .compatible = "x-power,ac108_3", },
++ { .compatible = "x-power,ac101", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ac108_of_match);
++
++static struct i2c_driver ac108_i2c_driver = {
++ .driver = {
++ .name = "ac10x-codec",
++ .of_match_table = ac108_of_match,
++ },
++ .probe = ac108_i2c_probe,
++ .remove = ac108_i2c_remove,
++ .id_table = ac108_i2c_id,
++};
++
++module_i2c_driver(ac108_i2c_driver);
++
++MODULE_DESCRIPTION("ASoC AC108 driver");
++MODULE_AUTHOR("Baozhu Zuo<zuobaozhu@gmail.com>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/sound/soc/codecs/ac108.h
+@@ -0,0 +1,749 @@
++/*
++ * ac108.h -- ac108 ALSA Soc Audio driver
++ *
++ * Author: panjunwen
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#ifndef _AC108_H
++#define _AC108_H
++
++/*** AC108 Codec Register Define***/
++
++//Chip Reset
++#define CHIP_RST 0x00
++#define CHIP_RST_VAL 0x12
++
++//Power Control
++#define PWR_CTRL1 0x01
++#define PWR_CTRL2 0x02
++#define PWR_CTRL3 0x03
++#define PWR_CTRL4 0x04
++#define PWR_CTRL5 0x05
++#define PWR_CTRL6 0x06
++#define PWR_CTRL7 0x07
++#define PWR_CTRL8 0x08
++#define PWR_CTRL9 0x09
++
++//PLL Configure Control
++#define PLL_CTRL1 0x10
++#define PLL_CTRL2 0x11
++#define PLL_CTRL3 0x12
++#define PLL_CTRL4 0x13
++#define PLL_CTRL5 0x14
++#define PLL_CTRL6 0x16
++#define PLL_CTRL7 0x17
++#define PLL_LOCK_CTRL 0x18
++
++//System Clock Control
++#define SYSCLK_CTRL 0x20
++#define MOD_CLK_EN 0x21
++#define MOD_RST_CTRL 0x22
++#define DSM_CLK_CTRL 0x25
++
++//I2S Common Control
++#define I2S_CTRL 0x30
++#define I2S_BCLK_CTRL 0x31
++#define I2S_LRCK_CTRL1 0x32
++#define I2S_LRCK_CTRL2 0x33
++#define I2S_FMT_CTRL1 0x34
++#define I2S_FMT_CTRL2 0x35
++#define I2S_FMT_CTRL3 0x36
++
++//I2S TX1 Control
++#define I2S_TX1_CTRL1 0x38
++#define I2S_TX1_CTRL2 0x39
++#define I2S_TX1_CTRL3 0x3A
++#define I2S_TX1_CHMP_CTRL1 0x3C
++#define I2S_TX1_CHMP_CTRL2 0x3D
++#define I2S_TX1_CHMP_CTRL3 0x3E
++#define I2S_TX1_CHMP_CTRL4 0x3F
++
++//I2S TX2 Control
++#define I2S_TX2_CTRL1 0x40
++#define I2S_TX2_CTRL2 0x41
++#define I2S_TX2_CTRL3 0x42
++#define I2S_TX2_CHMP_CTRL1 0x44
++#define I2S_TX2_CHMP_CTRL2 0x45
++#define I2S_TX2_CHMP_CTRL3 0x46
++#define I2S_TX2_CHMP_CTRL4 0x47
++
++//I2S RX1 Control
++#define I2S_RX1_CTRL1 0x50
++#define I2S_RX1_CHMP_CTRL1 0x54
++#define I2S_RX1_CHMP_CTRL2 0x55
++#define I2S_RX1_CHMP_CTRL3 0x56
++#define I2S_RX1_CHMP_CTRL4 0x57
++
++//I2S Loopback Debug
++#define I2S_LPB_DEBUG 0x58
++
++//ADC Common Control
++#define ADC_SPRC 0x60
++#define ADC_DIG_EN 0x61
++#define DMIC_EN 0x62
++#define ADC_DSR 0x63
++#define ADC_FIR 0x64
++#define ADC_DDT_CTRL 0x65
++
++//HPF Control
++#define HPF_EN 0x66
++#define HPF_COEF_REGH1 0x67
++#define HPF_COEF_REGH2 0x68
++#define HPF_COEF_REGL1 0x69
++#define HPF_COEF_REGL2 0x6A
++#define HPF_GAIN_REGH1 0x6B
++#define HPF_GAIN_REGH2 0x6C
++#define HPF_GAIN_REGL1 0x6D
++#define HPF_GAIN_REGL2 0x6E
++
++//ADC Digital Channel Volume Control
++#define ADC1_DVOL_CTRL 0x70
++#define ADC2_DVOL_CTRL 0x71
++#define ADC3_DVOL_CTRL 0x72
++#define ADC4_DVOL_CTRL 0x73
++
++//ADC Digital Mixer Source and Gain Control
++#define ADC1_DMIX_SRC 0x76
++#define ADC2_DMIX_SRC 0x77
++#define ADC3_DMIX_SRC 0x78
++#define ADC4_DMIX_SRC 0x79
++
++//ADC Digital Debug Control
++#define ADC_DIG_DEBUG 0x7F
++
++//I2S Pad Drive Control
++#define I2S_DAT_PADDRV_CTRL 0x80
++#define I2S_CLK_PADDRV_CTRL 0x81
++
++//Analog PGA Control
++#define ANA_PGA1_CTRL 0x90
++#define ANA_PGA2_CTRL 0x91
++#define ANA_PGA3_CTRL 0x92
++#define ANA_PGA4_CTRL 0x93
++
++//MIC Offset Control
++#define MIC_OFFSET_CTRL1 0x96
++#define MIC_OFFSET_CTRL2 0x97
++#define MIC1_OFFSET_STATU1 0x98
++#define MIC1_OFFSET_STATU2 0x99
++#define MIC2_OFFSET_STATU1 0x9A
++#define MIC2_OFFSET_STATU2 0x9B
++#define MIC3_OFFSET_STATU1 0x9C
++#define MIC3_OFFSET_STATU2 0x9D
++#define MIC4_OFFSET_STATU1 0x9E
++#define MIC4_OFFSET_STATU2 0x9F
++
++//ADC1 Analog Control
++#define ANA_ADC1_CTRL1 0xA0
++#define ANA_ADC1_CTRL2 0xA1
++#define ANA_ADC1_CTRL3 0xA2
++#define ANA_ADC1_CTRL4 0xA3
++#define ANA_ADC1_CTRL5 0xA4
++#define ANA_ADC1_CTRL6 0xA5
++#define ANA_ADC1_CTRL7 0xA6
++
++//ADC2 Analog Control
++#define ANA_ADC2_CTRL1 0xA7
++#define ANA_ADC2_CTRL2 0xA8
++#define ANA_ADC2_CTRL3 0xA9
++#define ANA_ADC2_CTRL4 0xAA
++#define ANA_ADC2_CTRL5 0xAB
++#define ANA_ADC2_CTRL6 0xAC
++#define ANA_ADC2_CTRL7 0xAD
++
++//ADC3 Analog Control
++#define ANA_ADC3_CTRL1 0xAE
++#define ANA_ADC3_CTRL2 0xAF
++#define ANA_ADC3_CTRL3 0xB0
++#define ANA_ADC3_CTRL4 0xB1
++#define ANA_ADC3_CTRL5 0xB2
++#define ANA_ADC3_CTRL6 0xB3
++#define ANA_ADC3_CTRL7 0xB4
++
++//ADC4 Analog Control
++#define ANA_ADC4_CTRL1 0xB5
++#define ANA_ADC4_CTRL2 0xB6
++#define ANA_ADC4_CTRL3 0xB7
++#define ANA_ADC4_CTRL4 0xB8
++#define ANA_ADC4_CTRL5 0xB9
++#define ANA_ADC4_CTRL6 0xBA
++#define ANA_ADC4_CTRL7 0xBB
++
++//GPIO Configure
++#define GPIO_CFG1 0xC0
++#define GPIO_CFG2 0xC1
++#define GPIO_DAT 0xC2
++#define GPIO_DRV 0xC3
++#define GPIO_PULL 0xC4
++#define GPIO_INT_CFG 0xC5
++#define GPIO_INT_EN 0xC6
++#define GPIO_INT_STATUS 0xC7
++
++//Misc
++#define BGTC_DAT 0xD1
++#define BGVC_DAT 0xD2
++#define PRNG_CLK_CTRL 0xDF
++
++/*** AC108 Codec Register Bit Define***/
++
++/*PWR_CTRL1*/
++#define CP12_CTRL 4
++#define CP12_SENSE_SELECT 3
++
++/*PWR_CTRL2*/
++#define CP12_SENSE_FILT 6
++#define CP12_COMP_FF_EN 3
++#define CP12_FORCE_ENABLE 2
++#define CP12_FORCE_RSTB 1
++
++/*PWR_CTRL3*/
++#define LDO33DIG_CTRL 0
++
++/*PWR_CTRL6*/
++#define LDO33ANA_2XHDRM 2
++#define LDO33ANA_ENABLE 0
++
++/*PWR_CTRL7*/
++#define VREF_SEL 3
++#define VREF_FASTSTART_ENABLE 1
++#define VREF_ENABLE 0
++
++/*PWR_CTRL9*/
++#define VREFP_FASTSTART_ENABLE 7
++#define VREFP_RESCTRL 5
++#define VREFP_LPMODE 4
++#define IGEN_TRIM 1
++#define VREFP_ENABLE 0
++
++/*PLL_CTRL1*/
++#define PLL_IBIAS 4
++#define PLL_NDET 3
++#define PLL_LOCKED_STATUS 2
++#define PLL_COM_EN 1
++#define PLL_EN 0
++
++/*PLL_CTRL2*/
++#define PLL_PREDIV2 5
++#define PLL_PREDIV1 0
++
++/*PLL_CTRL3*/
++#define PLL_LOOPDIV_MSB 0
++
++/*PLL_CTRL4*/
++#define PLL_LOOPDIV_LSB 0
++
++/*PLL_CTRL5*/
++#define PLL_POSTDIV2 5
++#define PLL_POSTDIV1 0
++
++/*PLL_CTRL6*/
++#define PLL_LDO 6
++#define PLL_CP 0
++
++/*PLL_CTRL7*/
++#define PLL_CAP 6
++#define PLL_RES 4
++#define PLL_TEST_EN 0
++
++/*PLL_LOCK_CTRL*/
++#define LOCK_LEVEL1 2
++#define LOCK_LEVEL2 1
++#define PLL_LOCK_EN 0
++
++/*SYSCLK_CTRL*/
++#define PLLCLK_EN 7
++#define PLLCLK_SRC 4
++#define SYSCLK_SRC 3
++#define SYSCLK_EN 0
++
++/*MOD_CLK_EN & MOD_RST_CTRL*/
++#define I2S 7
++#define ADC_DIGITAL 4
++#define MIC_OFFSET_CALIBRATION 1
++#define ADC_ANALOG 0
++
++/*DSM_CLK_CTRL*/
++#define MIC_OFFSET_DIV 4
++#define DSM_CLK_SEL 0
++
++/*I2S_CTRL*/
++#define BCLK_IOEN 7
++#define LRCK_IOEN 6
++#define SDO2_EN 5
++#define SDO1_EN 4
++#define TXEN 2
++#define RXEN 1
++#define GEN 0
++
++/*I2S_BCLK_CTRL*/
++#define EDGE_TRANSFER 5
++#define BCLK_POLARITY 4
++#define BCLKDIV 0
++
++/*I2S_LRCK_CTRL1*/
++#define LRCK_POLARITY 4
++#define LRCK_PERIODH 0
++
++/*I2S_LRCK_CTRL2*/
++#define LRCK_PERIODL 0
++
++/*I2S_FMT_CTRL1*/
++#define ENCD_SEL 6
++#define MODE_SEL 4
++#define TX2_OFFSET 3
++#define TX1_OFFSET 2
++#define TX_SLOT_HIZ 1
++#define TX_STATE 0
++
++/*I2S_FMT_CTRL2*/
++#define SLOT_WIDTH_SEL 4
++#define SAMPLE_RESOLUTION 0
++
++/*I2S_FMT_CTRL3*/
++#define TX_MLS 7
++#define SEXT 5
++#define OUT2_MUTE 4
++#define OUT1_MUTE 3
++#define LRCK_WIDTH 2
++#define TX_PDM 0
++
++/*I2S_TX1_CTRL1*/
++#define TX1_CHSEL 0
++
++/*I2S_TX1_CTRL2*/
++#define TX1_CH8_EN 7
++#define TX1_CH7_EN 6
++#define TX1_CH6_EN 5
++#define TX1_CH5_EN 4
++#define TX1_CH4_EN 3
++#define TX1_CH3_EN 2
++#define TX1_CH2_EN 1
++#define TX1_CH1_EN 0
++
++/*I2S_TX1_CTRL3*/
++#define TX1_CH16_EN 7
++#define TX1_CH15_EN 6
++#define TX1_CH14_EN 5
++#define TX1_CH13_EN 4
++#define TX1_CH12_EN 3
++#define TX1_CH11_EN 2
++#define TX1_CH10_EN 1
++#define TX1_CH9_EN 0
++
++/*I2S_TX1_CHMP_CTRL1*/
++#define TX1_CH4_MAP 6
++#define TX1_CH3_MAP 4
++#define TX1_CH2_MAP 2
++#define TX1_CH1_MAP 0
++
++/*I2S_TX1_CHMP_CTRL2*/
++#define TX1_CH8_MAP 6
++#define TX1_CH7_MAP 4
++#define TX1_CH6_MAP 2
++#define TX1_CH5_MAP 0
++
++/*I2S_TX1_CHMP_CTRL3*/
++#define TX1_CH12_MAP 6
++#define TX1_CH11_MAP 4
++#define TX1_CH10_MAP 2
++#define TX1_CH9_MAP 0
++
++/*I2S_TX1_CHMP_CTRL4*/
++#define TX1_CH16_MAP 6
++#define TX1_CH15_MAP 4
++#define TX1_CH14_MAP 2
++#define TX1_CH13_MAP 0
++
++/*I2S_TX2_CTRL1*/
++#define TX2_CHSEL 0
++
++/*I2S_TX2_CHMP_CTRL1*/
++#define TX2_CH4_MAP 6
++#define TX2_CH3_MAP 4
++#define TX2_CH2_MAP 2
++#define TX2_CH1_MAP 0
++
++/*I2S_TX2_CHMP_CTRL2*/
++#define TX2_CH8_MAP 6
++#define TX2_CH7_MAP 4
++#define TX2_CH6_MAP 2
++#define TX2_CH5_MAP 0
++
++/*I2S_TX2_CHMP_CTRL3*/
++#define TX2_CH12_MAP 6
++#define TX2_CH11_MAP 4
++#define TX2_CH10_MAP 2
++#define TX2_CH9_MAP 0
++
++/*I2S_TX2_CHMP_CTRL4*/
++#define TX2_CH16_MAP 6
++#define TX2_CH15_MAP 4
++#define TX2_CH14_MAP 2
++#define TX2_CH13_MAP 0
++
++/*I2S_RX1_CTRL1*/
++#define RX1_CHSEL 0
++
++/*I2S_RX1_CHMP_CTRL1*/
++#define RX1_CH4_MAP 6
++#define RX1_CH3_MAP 4
++#define RX1_CH2_MAP 2
++#define RX1_CH1_MAP 0
++
++/*I2S_RX1_CHMP_CTRL2*/
++#define RX1_CH8_MAP 6
++#define RX1_CH7_MAP 4
++#define RX1_CH6_MAP 2
++#define RX1_CH5_MAP 0
++
++/*I2S_RX1_CHMP_CTRL3*/
++#define RX1_CH12_MAP 6
++#define RX1_CH11_MAP 4
++#define RX1_CH10_MAP 2
++#define RX1_CH9_MAP 0
++
++/*I2S_RX1_CHMP_CTRL4*/
++#define RX1_CH16_MAP 6
++#define RX1_CH15_MAP 4
++#define RX1_CH14_MAP 2
++#define RX1_CH13_MAP 0
++
++/*I2S_LPB_DEBUG*/
++#define I2S_LPB_DEBUG_EN 0
++
++/*ADC_SPRC*/
++#define ADC_FS_I2S1 0
++
++/*ADC_DIG_EN*/
++#define DG_EN 4
++#define ENAD4 3
++#define ENAD3 2
++#define ENAD2 1
++#define ENAD1 0
++
++/*DMIC_EN*/
++#define DMIC2_EN 1
++#define DMIC1_EN 0
++
++/*ADC_DSR*/
++#define DIG_ADC4_SRS 6
++#define DIG_ADC3_SRS 4
++#define DIG_ADC2_SRS 2
++#define DIG_ADC1_SRS 0
++
++/*ADC_DDT_CTRL*/
++#define ADOUT_DLY_EN 2
++#define ADOUT_DTS 0
++
++/*HPF_EN*/
++#define DIG_ADC4_HPF_EN 3
++#define DIG_ADC3_HPF_EN 2
++#define DIG_ADC2_HPF_EN 1
++#define DIG_ADC1_HPF_EN 0
++
++/*ADC1_DMIX_SRC*/
++#define ADC1_ADC4_DMXL_GC 7
++#define ADC1_ADC3_DMXL_GC 6
++#define ADC1_ADC2_DMXL_GC 5
++#define ADC1_ADC1_DMXL_GC 4
++#define ADC1_ADC4_DMXL_SRC 3
++#define ADC1_ADC3_DMXL_SRC 2
++#define ADC1_ADC2_DMXL_SRC 1
++#define ADC1_ADC1_DMXL_SRC 0
++
++/*ADC2_DMIX_SRC*/
++#define ADC2_ADC4_DMXL_GC 7
++#define ADC2_ADC3_DMXL_GC 6
++#define ADC2_ADC2_DMXL_GC 5
++#define ADC2_ADC1_DMXL_GC 4
++#define ADC2_ADC4_DMXL_SRC 3
++#define ADC2_ADC3_DMXL_SRC 2
++#define ADC2_ADC2_DMXL_SRC 1
++#define ADC2_ADC1_DMXL_SRC 0
++
++/*ADC3_DMIX_SRC*/
++#define ADC3_ADC4_DMXL_GC 7
++#define ADC3_ADC3_DMXL_GC 6
++#define ADC3_ADC2_DMXL_GC 5
++#define ADC3_ADC1_DMXL_GC 4
++#define ADC3_ADC4_DMXL_SRC 3
++#define ADC3_ADC3_DMXL_SRC 2
++#define ADC3_ADC2_DMXL_SRC 1
++#define ADC3_ADC1_DMXL_SRC 0
++
++/*ADC4_DMIX_SRC*/
++#define ADC4_ADC4_DMXL_GC 7
++#define ADC4_ADC3_DMXL_GC 6
++#define ADC4_ADC2_DMXL_GC 5
++#define ADC4_ADC1_DMXL_GC 4
++#define ADC4_ADC4_DMXL_SRC 3
++#define ADC4_ADC3_DMXL_SRC 2
++#define ADC4_ADC2_DMXL_SRC 1
++#define ADC4_ADC1_DMXL_SRC 0
++
++/*ADC_DIG_DEBUG*/
++#define ADC_PTN_SEL 0
++
++/*I2S_DAT_PADDRV_CTRL*/
++#define TX2_DAT_DRV 4
++#define TX1_DAT_DRV 0
++
++/*I2S_CLK_PADDRV_CTRL*/
++#define LRCK_DRV 4
++#define BCLK_DRV 0
++
++/*ANA_PGA1_CTRL*/
++#define ADC1_ANALOG_PGA 1
++#define ADC1_ANALOG_PGA_STEP 0
++
++/*ANA_PGA2_CTRL*/
++#define ADC2_ANALOG_PGA 1
++#define ADC2_ANALOG_PGA_STEP 0
++
++/*ANA_PGA3_CTRL*/
++#define ADC3_ANALOG_PGA 1
++#define ADC3_ANALOG_PGA_STEP 0
++
++/*ANA_PGA4_CTRL*/
++#define ADC4_ANALOG_PGA 1
++#define ADC4_ANALOG_PGA_STEP 0
++
++
++/*MIC_OFFSET_CTRL1*/
++#define MIC_OFFSET_CAL_EN4 3
++#define MIC_OFFSET_CAL_EN3 2
++#define MIC_OFFSET_CAL_EN2 1
++#define MIC_OFFSET_CAL_EN1 0
++
++/*MIC_OFFSET_CTRL2*/
++#define MIC_OFFSET_CAL_GAIN 3
++#define MIC_OFFSET_CAL_CHANNEL 1
++#define MIC_OFFSET_CAL_EN_ONCE 0
++
++/*MIC1_OFFSET_STATU1*/
++#define MIC1_OFFSET_CAL_DONE 7
++#define MIC1_OFFSET_CAL_RUN_STA 6
++#define MIC1_OFFSET_MSB 0
++
++/*MIC1_OFFSET_STATU2*/
++#define MIC1_OFFSET_LSB 0
++
++/*MIC2_OFFSET_STATU1*/
++#define MIC2_OFFSET_CAL_DONE 7
++#define MIC2_OFFSET_CAL_RUN_STA 6
++#define MIC2_OFFSET_MSB 0
++
++/*MIC2_OFFSET_STATU2*/
++#define MIC2_OFFSET_LSB 0
++
++/*MIC3_OFFSET_STATU1*/
++#define MIC3_OFFSET_CAL_DONE 7
++#define MIC3_OFFSET_CAL_RUN_STA 6
++#define MIC3_OFFSET_MSB 0
++
++/*MIC3_OFFSET_STATU2*/
++#define MIC3_OFFSET_LSB 0
++
++/*MIC4_OFFSET_STATU1*/
++#define MIC4_OFFSET_CAL_DONE 7
++#define MIC4_OFFSET_CAL_RUN_STA 6
++#define MIC4_OFFSET_MSB 0
++
++/*MIC4_OFFSET_STATU2*/
++#define MIC4_OFFSET_LSB 0
++
++/*ANA_ADC1_CTRL1*/
++#define ADC1_PGA_BYPASS 7
++#define ADC1_PGA_BYP_RCM 6
++#define ADC1_PGA_CTRL_RCM 4
++#define ADC1_PGA_MUTE 3
++#define ADC1_DSM_ENABLE 2
++#define ADC1_PGA_ENABLE 1
++#define ADC1_MICBIAS_EN 0
++
++/*ANA_ADC1_CTRL3*/
++#define ADC1_ANA_CAL_EN 5
++#define ADC1_SEL_OUT_EDGE 3
++#define ADC1_DSM_DISABLE 2
++#define ADC1_VREFP_DISABLE 1
++#define ADC1_AAF_DISABLE 0
++
++/*ANA_ADC1_CTRL6*/
++#define PGA_CTRL_TC 6
++#define PGA_CTRL_RC 4
++#define PGA_CTRL_I_LIN 2
++#define PGA_CTRL_I_IN 0
++
++/*ANA_ADC1_CTRL7*/
++#define PGA_CTRL_HI_Z 7
++#define PGA_CTRL_SHORT_RF 6
++#define PGA_CTRL_VCM_VG 4
++#define PGA_CTRL_VCM_IN 0
++
++/*ANA_ADC2_CTRL1*/
++#define ADC2_PGA_BYPASS 7
++#define ADC2_PGA_BYP_RCM 6
++#define ADC2_PGA_CTRL_RCM 4
++#define ADC2_PGA_MUTE 3
++#define ADC2_DSM_ENABLE 2
++#define ADC2_PGA_ENABLE 1
++#define ADC2_MICBIAS_EN 0
++
++/*ANA_ADC2_CTRL3*/
++#define ADC2_ANA_CAL_EN 5
++#define ADC2_SEL_OUT_EDGE 3
++#define ADC2_DSM_DISABLE 2
++#define ADC2_VREFP_DISABLE 1
++#define ADC2_AAF_DISABLE 0
++
++/*ANA_ADC2_CTRL6*/
++#define PGA_CTRL_IBOOST 7
++#define PGA_CTRL_IQCTRL 6
++#define PGA_CTRL_OABIAS 4
++#define PGA_CTRL_CMLP_DIS 3
++#define PGA_CTRL_PDB_RIN 2
++#define PGA_CTRL_PEAKDET 0
++
++/*ANA_ADC2_CTRL7*/
++#define AAF_LPMODE_EN 7
++#define AAF_STG2_IB_SEL 4
++#define AAFDSM_IB_DIV2 3
++#define AAF_STG1_IB_SEL 0
++
++/*ANA_ADC3_CTRL1*/
++#define ADC3_PGA_BYPASS 7
++#define ADC3_PGA_BYP_RCM 6
++#define ADC3_PGA_CTRL_RCM 4
++#define ADC3_PGA_MUTE 3
++#define ADC3_DSM_ENABLE 2
++#define ADC3_PGA_ENABLE 1
++#define ADC3_MICBIAS_EN 0
++
++/*ANA_ADC3_CTRL3*/
++#define ADC3_ANA_CAL_EN 5
++#define ADC3_INVERT_CLK 4
++#define ADC3_SEL_OUT_EDGE 3
++#define ADC3_DSM_DISABLE 2
++#define ADC3_VREFP_DISABLE 1
++#define ADC3_AAF_DISABLE 0
++
++/*ANA_ADC3_CTRL7*/
++#define DSM_COMP_IB_SEL 6
++#define DSM_OTA_CTRL 4
++#define DSM_LPMODE 3
++#define DSM_OTA_IB_SEL 0
++
++/*ANA_ADC4_CTRL1*/
++#define ADC4_PGA_BYPASS 7
++#define ADC4_PGA_BYP_RCM 6
++#define ADC4_PGA_CTRL_RCM 4
++#define ADC4_PGA_MUTE 3
++#define ADC4_DSM_ENABLE 2
++#define ADC4_PGA_ENABLE 1
++#define ADC4_MICBIAS_EN 0
++
++/*ANA_ADC4_CTRL3*/
++#define ADC4_ANA_CAL_EN 5
++#define ADC4_SEL_OUT_EDGE 3
++#define ADC4_DSM_DISABLE 2
++#define ADC4_VREFP_DISABLE 1
++#define ADC4_AAF_DISABLE 0
++
++/*ANA_ADC4_CTRL6*/
++#define DSM_DEMOFF 5
++#define DSM_EN_DITHER 4
++#define DSM_VREFP_LPMODE 2
++#define DSM_VREFP_OUTCTRL 0
++
++/*ANA_ADC4_CTRL7*/
++#define CK8M_EN 5
++#define OSC_EN 4
++#define ADC4_CLK_GATING 3
++#define ADC3_CLK_GATING 2
++#define ADC2_CLK_GATING 1
++#define ADC1_CLK_GATING 0
++
++/*GPIO_CFG1*/
++#define GPIO2_SELECT 4
++#define GPIO1_SELECT 0
++
++/*GPIO_CFG2*/
++#define GPIO4_SELECT 4
++#define GPIO3_SELECT 0
++
++/*GPIO_DAT*///order???
++#define GPIO4_DAT 3
++#define GPIO3_DAT 2
++#define GPIO2_DAT 1
++#define GPIO1_DAT 0
++
++/*GPIO_DRV*/
++#define GPIO4_DRV 6
++#define GPIO3_DRV 4
++#define GPIO2_DRV 2
++#define GPIO1_DRV 0
++
++/*GPIO_PULL*/
++#define GPIO4_PULL 6
++#define GPIO3_PULL 4
++#define GPIO2_PULL 2
++#define GPIO1_PULL 0
++
++/*GPIO_INT_CFG*/
++#define GPIO4_EINT_CFG 6
++#define GPIO3_EINT_CFG 4
++#define GPIO2_EINT_CFG 2
++#define GPIO1_EINT_CFG 0
++
++/*GPIO_INT_EN*///order???
++#define GPIO4_EINT_EN 3
++#define GPIO3_EINT_EN 2
++#define GPIO2_EINT_EN 1
++#define GPIO1_EINT_EN 0
++
++/*GPIO_INT_STATUS*///order???
++#define GPIO4_EINT_STA 3
++#define GPIO3_EINT_STA 2
++#define GPIO2_EINT_STA 1
++#define GPIO1_EINT_STA 0
++
++/*PRNG_CLK_CTRL*/
++#define PRNG_CLK_EN 1
++#define PRNG_CLK_POS 0
++
++/*** Some Config Value ***/
++
++//[SYSCLK_CTRL]: PLLCLK_SRC
++#define PLLCLK_SRC_MCLK 0
++#define PLLCLK_SRC_BCLK 1
++#define PLLCLK_SRC_GPIO2 2
++#define PLLCLK_SRC_GPIO3 3
++
++//[SYSCLK_CTRL]: SYSCLK_SRC
++#define SYSCLK_SRC_MCLK 0
++#define SYSCLK_SRC_PLL 1
++
++//I2S BCLK POLARITY Control
++#define BCLK_NORMAL_DRIVE_N_SAMPLE_P 0
++#define BCLK_INVERT_DRIVE_P_SAMPLE_N 1
++
++//I2S LRCK POLARITY Control
++#define LRCK_LEFT_LOW_RIGHT_HIGH 0
++#define LRCK_LEFT_HIGH_RIGHT_LOW 1
++
++//I2S Format Selection
++#define PCM_FORMAT 0
++#define LEFT_JUSTIFIED_FORMAT 1
++#define RIGHT_JUSTIFIED_FORMAT 2
++
++//I2S data protocol types
++
++#define IS_ENCODING_MODE 0
++
++#endif
++
+--- /dev/null
++++ b/sound/soc/codecs/ac10x.h
+@@ -0,0 +1,152 @@
++/*
++ * ac10x.h
++ *
++ * (C) Copyright 2017-2018
++ * Seeed Technology Co., Ltd. <www.seeedstudio.com>
++ *
++ * PeterYang <linsheng.yang@seeed.cc>
++ *
++ * (C) Copyright 2010-2017
++ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
++ * huangxin <huangxin@reuuimllatech.com>
++ *
++ * some simple description for this code
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ */
++#ifndef __AC10X_H__
++#define __AC10X_H__
++
++#define AC101_I2C_ID 4
++#define _MASTER_AC108 0
++#define _MASTER_AC101 1
++#define _MASTER_MULTI_CODEC _MASTER_AC101
++
++/* enable headset detecting & headset button pressing */
++#define CONFIG_AC101_SWITCH_DETECT
++
++/* obsolete */
++#define CONFIG_AC10X_TRIG_LOCK 0
++
++#ifdef AC101_DEBG
++ #define AC101_DBG(format,args...) printk("[AC101] %s() L%d " format, __func__, __LINE__, ##args)
++#else
++ #define AC101_DBG(...)
++#endif
++
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,0)
++#define __NO_SND_SOC_CODEC_DRV 1
++#else
++#define __NO_SND_SOC_CODEC_DRV 0
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
++#if __has_attribute(__fallthrough__)
++# define fallthrough __attribute__((__fallthrough__))
++#else
++# define fallthrough do {} while (0) /* fallthrough */
++#endif
++#endif
++
++#if __NO_SND_SOC_CODEC_DRV
++#define codec component
++#define snd_soc_codec snd_soc_component
++#define snd_soc_codec_driver snd_soc_component_driver
++#define snd_soc_codec_get_drvdata snd_soc_component_get_drvdata
++#define snd_soc_codec_get_dapm snd_soc_component_get_dapm
++#define snd_soc_codec_get_bias_level snd_soc_component_get_bias_level
++#define snd_soc_kcontrol_codec snd_soc_kcontrol_component
++#define snd_soc_read snd_soc_component_read32
++#define snd_soc_register_codec snd_soc_register_component
++#define snd_soc_unregister_codec snd_soc_unregister_component
++#define snd_soc_update_bits snd_soc_component_update_bits
++#define snd_soc_write snd_soc_component_write
++#define snd_soc_add_codec_controls snd_soc_add_component_controls
++#endif
++
++
++#ifdef CONFIG_AC101_SWITCH_DETECT
++enum headphone_mode_u {
++ HEADPHONE_IDLE,
++ FOUR_HEADPHONE_PLUGIN,
++ THREE_HEADPHONE_PLUGIN,
++};
++#endif
++
++struct ac10x_priv {
++ struct i2c_client *i2c[4];
++ struct regmap* i2cmap[4];
++ int codec_cnt;
++ unsigned sysclk;
++#define _FREQ_24_576K 24576000
++#define _FREQ_22_579K 22579200
++ unsigned mclk; /* master clock or aif_clock/aclk */
++ int clk_id;
++ unsigned char i2s_mode;
++ unsigned char data_protocol;
++ struct delayed_work dlywork;
++ int tdm_chips_cnt;
++ int sysclk_en;
++
++ /* member for ac101 .begin */
++ struct snd_soc_codec *codec;
++ struct i2c_client *i2c101;
++ struct regmap* regmap101;
++
++ struct mutex dac_mutex;
++ u8 dac_enable;
++ spinlock_t lock;
++ u8 aif1_clken;
++
++ struct work_struct codec_resume;
++ struct gpio_desc* gpiod_spk_amp_gate;
++
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ struct gpio_desc* gpiod_irq;
++ long irq;
++ volatile int irq_cntr;
++ volatile int pullout_cntr;
++ volatile int state;
++
++ enum headphone_mode_u mode;
++ struct work_struct work_switch;
++ struct work_struct work_clear_irq;
++
++ struct input_dev* inpdev;
++ #endif
++ /* member for ac101 .end */
++};
++
++
++/* AC101 DAI operations */
++int ac101_audio_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai);
++void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai);
++int ac101_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt);
++int ac101_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *codec_dai);
++int ac101_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai);
++int ac101_aif_mute(struct snd_soc_dai *codec_dai, int mute);
++
++/* codec driver specific */
++int ac101_codec_probe(struct snd_soc_codec *codec);
++int ac101_codec_remove(struct snd_soc_codec *codec);
++int ac101_codec_suspend(struct snd_soc_codec *codec);
++int ac101_codec_resume(struct snd_soc_codec *codec);
++int ac101_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level);
++
++/* i2c device specific */
++int ac101_probe(struct i2c_client *i2c, const struct i2c_device_id *id);
++void ac101_shutdown(struct i2c_client *i2c);
++int ac101_remove(struct i2c_client *i2c);
++
++int ac10x_fill_regcache(struct device* dev, struct regmap* map);
++
++#endif//__AC10X_H__
diff --git a/target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch b/target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch
new file mode 100644
index 0000000000..f2fb206947
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch
@@ -0,0 +1,1169 @@
+From f03b7c834baef87e4f740e10a8bbcbfc57bd985a Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 15 Jun 2023 11:32:50 +0800
+Subject: [PATCH 080/116] ASoC: starfive: Add SPDIF and PCM driver
+
+Add SPDIF and SPDIF-PCM driver for StarFive JH7110.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/starfive/Kconfig | 17 +
+ sound/soc/starfive/Makefile | 5 +
+ sound/soc/starfive/jh7110_spdif.c | 568 ++++++++++++++++++++++++++
+ sound/soc/starfive/jh7110_spdif.h | 196 +++++++++
+ sound/soc/starfive/jh7110_spdif_pcm.c | 339 +++++++++++++++
+ 5 files changed, 1125 insertions(+)
+ create mode 100644 sound/soc/starfive/jh7110_spdif.c
+ create mode 100644 sound/soc/starfive/jh7110_spdif.h
+ create mode 100644 sound/soc/starfive/jh7110_spdif_pcm.c
+
+--- a/sound/soc/starfive/Kconfig
++++ b/sound/soc/starfive/Kconfig
+@@ -16,6 +16,23 @@ config SND_SOC_JH7110_PWMDAC
+ Say Y or M if you want to add support for StarFive JH7110
+ PWM-DAC driver.
+
++config SND_SOC_JH7110_SPDIF
++ tristate "JH7110 SPDIF module"
++ depends on HAVE_CLK && SND_SOC_STARFIVE
++ select SND_SOC_GENERIC_DMAENGINE_PCM
++ select REGMAP_MMIO
++ help
++ Say Y or M if you want to add support for SPDIF driver of StarFive
++ JH7110 SoC.
++
++config SND_SOC_JH7110_SPDIF_PCM
++ bool "PCM PIO extension for JH7110 SPDIF"
++ depends on SND_SOC_JH7110_SPDIF
++ default y if SND_SOC_JH7110_SPDIF
++ help
++ Say Y or N if you want to add a custom ALSA extension that registers
++ a PCM and uses PIO to transfer data.
++
+ config SND_SOC_JH7110_TDM
+ tristate "JH7110 TDM device driver"
+ depends on HAVE_CLK && SND_SOC_STARFIVE
+--- a/sound/soc/starfive/Makefile
++++ b/sound/soc/starfive/Makefile
+@@ -1,3 +1,8 @@
+ # StarFive Platform Support
+ obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
++
++obj-$(CONFIG_SND_SOC_JH7110_SPDIF) += spdif.o
++spdif-y := jh7110_spdif.o
++spdif-$(CONFIG_SND_SOC_JH7110_SPDIF_PCM) += jh7110_spdif_pcm.o
++
+ obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_spdif.c
+@@ -0,0 +1,568 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * SPDIF driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++#include <sound/core.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++
++#include "jh7110_spdif.h"
++
++static irqreturn_t spdif_irq_handler(int irq, void *dev_id)
++{
++ struct sf_spdif_dev *dev = dev_id;
++ bool irq_valid = false;
++ unsigned int intr;
++ unsigned int stat;
++
++ regmap_read(dev->regmap, SPDIF_INT_REG, &intr);
++ regmap_read(dev->regmap, SPDIF_STAT_REG, &stat);
++ regmap_update_bits(dev->regmap, SPDIF_CTRL, SPDIF_MASK_ENABLE, 0);
++ regmap_update_bits(dev->regmap, SPDIF_INT_REG, SPDIF_INT_REG_BIT, 0);
++
++ if ((stat & SPDIF_EMPTY_FLAG) || (stat & SPDIF_AEMPTY_FLAG)) {
++ sf_spdif_pcm_push_tx(dev);
++ irq_valid = true;
++ }
++
++ if ((stat & SPDIF_FULL_FLAG) || (stat & SPDIF_AFULL_FLAG)) {
++ sf_spdif_pcm_pop_rx(dev);
++ irq_valid = true;
++ }
++
++ if (stat & SPDIF_PARITY_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_UNDERR_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_OVRERR_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_SYNCERR_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_LOCK_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_BEGIN_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_RIGHT_LEFT)
++ irq_valid = true;
++
++ regmap_update_bits(dev->regmap, SPDIF_CTRL,
++ SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
++
++ if (irq_valid)
++ return IRQ_HANDLED;
++ else
++ return IRQ_NONE;
++}
++
++static int sf_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
++ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
++
++ if (tx) {
++ /* tx mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_TR_MODE, SPDIF_TR_MODE);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_MASK_FIFO, SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK);
++ } else {
++ /* rx mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_TR_MODE, 0);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_MASK_FIFO, SPDIF_FULL_MASK | SPDIF_AFULL_MASK);
++ }
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ /* clock recovery form the SPDIF data stream 0:clk_enable */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, 0);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_ENABLE, SPDIF_ENABLE);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ /* clock recovery form the SPDIF data stream 1:power save mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_ENABLE, 0);
++ break;
++ default:
++ dev_err(dai->dev, "%s L.%d cmd:%d\n", __func__, __LINE__, cmd);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int sf_spdif_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++{
++ struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
++ unsigned int channels = params_channels(params);
++ unsigned int rate = params_rate(params);
++ unsigned int format = params_format(params);
++ unsigned int tsamplerate;
++ unsigned int mclk;
++ unsigned int audio_root;
++ int ret;
++
++ switch (channels) {
++ case 1:
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CHANNEL_MODE, SPDIF_CHANNEL_MODE);
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_DUPLICATE, SPDIF_DUPLICATE);
++ spdif->channels = false;
++ break;
++ case 2:
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CHANNEL_MODE, 0);
++ spdif->channels = true;
++ break;
++ default:
++ dev_err(dai->dev, "invalid channels number\n");
++ return -EINVAL;
++ }
++
++ switch (format) {
++ case SNDRV_PCM_FORMAT_S16_LE:
++ case SNDRV_PCM_FORMAT_S24_LE:
++ case SNDRV_PCM_FORMAT_S24_3LE:
++ case SNDRV_PCM_FORMAT_S32_LE:
++ break;
++ default:
++ dev_err(dai->dev, "invalid format\n");
++ return -EINVAL;
++ }
++
++ switch (rate) {
++ case 8000:
++ break;
++ case 11025:
++ audio_root = 148500000;
++ /* 11025 * 512 = 5644800 */
++ /* But now pll2 is 1188m and mclk should be 5711539 closely. */
++ mclk = 5711539;
++ break;
++ case 16000:
++ break;
++ case 22050:
++ audio_root = 148500000;
++ mclk = 11423077;
++ break;
++ default:
++ dev_err(dai->dev, "channel:%d sample rate:%d\n", channels, rate);
++ return -EINVAL;
++ }
++
++ /* use mclk_inner clock from 1188m PLL2 will be better about 11k and 22k*/
++ if ((rate == 11025) || (rate == 22050)) {
++ ret = clk_set_parent(spdif->mclk, spdif->mclk_inner);
++ if (ret) {
++ dev_err(dai->dev,
++ "failed to set parent to mclk_inner ret=%d\n", ret);
++ goto fail_ext;
++ }
++
++ ret = clk_set_rate(spdif->audio_root, audio_root);
++ if (ret) {
++ dev_err(dai->dev, "failed to set audio_root rate :%d\n", ret);
++ goto fail_ext;
++ }
++
++ ret = clk_set_rate(spdif->mclk_inner, mclk);
++ if (ret) {
++ dev_err(dai->dev, "failed to set mclk_inner rate :%d\n", ret);
++ goto fail_ext;
++ }
++
++ mclk = clk_get_rate(spdif->mclk_inner);
++ } else {
++ ret = clk_set_parent(spdif->mclk, spdif->mclk_ext);
++ if (ret) {
++ dev_err(dai->dev,
++ "failed to set parent to mclk_ext ret=%d\n", ret);
++ goto fail_ext;
++ }
++
++ mclk = clk_get_rate(spdif->mclk_ext);
++ }
++
++ /* (FCLK)4096000/128=32000 */
++ tsamplerate = (mclk / 128 + rate / 2) / rate - 1;
++ if (tsamplerate < 3)
++ tsamplerate = 3;
++
++ /* transmission sample rate */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL, 0xFF, tsamplerate);
++
++ return 0;
++
++fail_ext:
++ return ret;
++}
++
++static int sf_spdif_clks_get(struct platform_device *pdev,
++ struct sf_spdif_dev *spdif)
++{
++ static struct clk_bulk_data clks[] = {
++ { .id = "apb" }, /* clock-names in dts file */
++ { .id = "core" },
++ { .id = "audroot" },
++ { .id = "mclk_inner"},
++ { .id = "mclk_ext"},
++ { .id = "mclk"},
++ };
++ int ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
++
++ spdif->spdif_apb = clks[0].clk;
++ spdif->spdif_core = clks[1].clk;
++ spdif->audio_root = clks[2].clk;
++ spdif->mclk_inner = clks[3].clk;
++ spdif->mclk_ext = clks[4].clk;
++ spdif->mclk = clks[5].clk;
++
++ return ret;
++}
++
++static int sf_spdif_resets_get(struct platform_device *pdev,
++ struct sf_spdif_dev *spdif)
++{
++ struct reset_control_bulk_data resets[] = {
++ { .id = "apb" },
++ };
++ int ret = devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(resets), resets);
++
++ if (ret)
++ return ret;
++
++ spdif->rst_apb = resets[0].rstc;
++
++ return 0;
++}
++
++static int starfive_spdif_crg_enable(struct sf_spdif_dev *spdif, bool enable)
++{
++ int ret;
++
++ dev_dbg(spdif->dev, "starfive_spdif clk&rst %sable.\n", enable ? "en":"dis");
++ if (enable) {
++ ret = clk_prepare_enable(spdif->spdif_apb);
++ if (ret) {
++ dev_err(spdif->dev, "failed to prepare enable spdif_apb\n");
++ goto failed_apb_clk;
++ }
++
++ ret = clk_prepare_enable(spdif->spdif_core);
++ if (ret) {
++ dev_err(spdif->dev, "failed to prepare enable spdif_core\n");
++ goto failed_core_clk;
++ }
++
++ ret = reset_control_deassert(spdif->rst_apb);
++ if (ret) {
++ dev_err(spdif->dev, "failed to deassert apb\n");
++ goto failed_rst;
++ }
++ } else {
++ clk_disable_unprepare(spdif->spdif_core);
++ clk_disable_unprepare(spdif->spdif_apb);
++ }
++
++ return 0;
++
++failed_rst:
++ clk_disable_unprepare(spdif->spdif_core);
++failed_core_clk:
++ clk_disable_unprepare(spdif->spdif_apb);
++failed_apb_clk:
++ return ret;
++}
++
++static int sf_spdif_dai_probe(struct snd_soc_dai *dai)
++{
++ struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
++
++ pm_runtime_get_sync(spdif->dev);
++
++ /* reset */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_ENABLE | SPDIF_SFR_ENABLE | SPDIF_FIFO_ENABLE, 0);
++
++ /* clear irq */
++ regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
++ SPDIF_INT_REG_BIT, 0);
++
++ /* power save mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
++
++ /* power save mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE,
++ SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_SETPREAMBB, SPDIF_SETPREAMBB);
++
++ regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
++ BIT8TO20MASK<<SPDIF_PREAMBLEDEL, 0x3<<SPDIF_PREAMBLEDEL);
++
++ regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
++ ALLBITMASK, 0x20|(0x20<<SPDIF_AFULL_THRESHOLD));
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_PARITYGEN, SPDIF_PARITYGEN);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
++
++ /* APB access to FIFO enable, disable if use DMA/FIFO */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_USE_FIFO_IF, 0);
++
++ /* two channel */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CHANNEL_MODE, 0);
++
++ pm_runtime_put_sync(spdif->dev);
++ return 0;
++}
++
++static const struct snd_soc_dai_ops sf_spdif_dai_ops = {
++ .probe = sf_spdif_dai_probe,
++ .trigger = sf_spdif_trigger,
++ .hw_params = sf_spdif_hw_params,
++};
++
++#ifdef CONFIG_PM_SLEEP
++static int spdif_system_suspend(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++
++ /* save the register value */
++ regmap_read(spdif->regmap, SPDIF_CTRL, &spdif->reg_spdif_ctrl);
++ regmap_read(spdif->regmap, SPDIF_INT_REG, &spdif->reg_spdif_int);
++ regmap_read(spdif->regmap, SPDIF_FIFO_CTRL, &spdif->reg_spdif_fifo_ctrl);
++
++ return pm_runtime_force_suspend(dev);
++}
++
++static int spdif_system_resume(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++ int ret = pm_runtime_force_resume(dev);
++
++ if (ret)
++ return ret;
++
++ /* restore the register value */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ ALLBITMASK, spdif->reg_spdif_ctrl);
++ regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
++ ALLBITMASK, spdif->reg_spdif_int);
++ regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
++ ALLBITMASK, spdif->reg_spdif_fifo_ctrl);
++
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_PM
++static int spdif_runtime_suspend(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++
++ return starfive_spdif_crg_enable(spdif, false);
++}
++
++static int spdif_runtime_resume(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++
++ return starfive_spdif_crg_enable(spdif, true);
++}
++#endif
++
++static const struct dev_pm_ops spdif_pm_ops = {
++ SET_RUNTIME_PM_OPS(spdif_runtime_suspend, spdif_runtime_resume, NULL)
++ SET_SYSTEM_SLEEP_PM_OPS(spdif_system_suspend, spdif_system_resume)
++};
++
++#define SF_PCM_RATE_44100_192000 (SNDRV_PCM_RATE_44100 | \
++ SNDRV_PCM_RATE_48000 | \
++ SNDRV_PCM_RATE_96000 | \
++ SNDRV_PCM_RATE_192000)
++
++#define SF_PCM_RATE_8000_22050 (SNDRV_PCM_RATE_8000 | \
++ SNDRV_PCM_RATE_11025 | \
++ SNDRV_PCM_RATE_16000 | \
++ SNDRV_PCM_RATE_22050)
++
++static struct snd_soc_dai_driver sf_spdif_dai = {
++ .name = "spdif",
++ .id = 0,
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = 2,
++ .rates = SF_PCM_RATE_8000_22050,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE |
++ SNDRV_PCM_FMTBIT_S24_LE |
++ SNDRV_PCM_FMTBIT_S24_3LE |
++ SNDRV_PCM_FMTBIT_S32_LE,
++ },
++ .ops = &sf_spdif_dai_ops,
++ .symmetric_rate = 1,
++};
++
++static const struct snd_soc_component_driver sf_spdif_component = {
++ .name = "starfive-spdif",
++};
++
++static const struct regmap_config sf_spdif_regmap_config = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .max_register = 0x200,
++};
++
++static int sf_spdif_probe(struct platform_device *pdev)
++{
++ struct sf_spdif_dev *spdif;
++ struct resource *res;
++ void __iomem *base;
++ int ret;
++ int irq;
++
++ spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
++ if (!spdif)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, spdif);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ spdif->spdif_base = base;
++ spdif->regmap = devm_regmap_init_mmio(&pdev->dev, spdif->spdif_base,
++ &sf_spdif_regmap_config);
++ if (IS_ERR(spdif->regmap))
++ return PTR_ERR(spdif->regmap);
++
++ spdif->dev = &pdev->dev;
++
++ ret = sf_spdif_clks_get(pdev, spdif);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to get audio clock\n");
++ return ret;
++ }
++
++ ret = sf_spdif_resets_get(pdev, spdif);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to get audio reset controls\n");
++ return ret;
++ }
++
++ ret = starfive_spdif_crg_enable(spdif, true);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to enable audio clock\n");
++ return ret;
++ }
++
++ spdif->fifo_th = 16;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq >= 0) {
++ ret = devm_request_irq(&pdev->dev, irq, spdif_irq_handler, 0,
++ pdev->name, spdif);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "failed to request irq\n");
++ return ret;
++ }
++ }
++
++ ret = devm_snd_soc_register_component(&pdev->dev, &sf_spdif_component,
++ &sf_spdif_dai, 1);
++ if (ret)
++ goto err_clk_disable;
++
++ if (irq >= 0) {
++ ret = sf_spdif_pcm_register(pdev);
++ spdif->use_pio = true;
++ } else {
++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
++ 0);
++ spdif->use_pio = false;
++ }
++
++ if (ret)
++ goto err_clk_disable;
++
++ starfive_spdif_crg_enable(spdif, false);
++ pm_runtime_enable(&pdev->dev);
++ dev_dbg(&pdev->dev, "spdif register done.\n");
++
++ return 0;
++
++err_clk_disable:
++ return ret;
++}
++
++static const struct of_device_id sf_spdif_of_match[] = {
++ { .compatible = "starfive,jh7110-spdif", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, sf_spdif_of_match);
++
++static struct platform_driver sf_spdif_driver = {
++ .driver = {
++ .name = "starfive-spdif",
++ .of_match_table = sf_spdif_of_match,
++ .pm = &spdif_pm_ops,
++ },
++ .probe = sf_spdif_probe,
++};
++module_platform_driver(sf_spdif_driver);
++
++MODULE_AUTHOR("curry.zhang <curry.zhang@starfive.com>");
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_DESCRIPTION("starfive SPDIF driver");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_spdif.h
+@@ -0,0 +1,196 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * SPDIF driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#ifndef __SND_SOC_JH7110_SPDIF_H
++#define __SND_SOC_JH7110_SPDIF_H
++
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/dmaengine.h>
++#include <linux/types.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/pcm.h>
++
++#define SPDIF_CTRL 0x0
++#define SPDIF_INT_REG 0x4
++#define SPDIF_FIFO_CTRL 0x8
++#define SPDIF_STAT_REG 0xC
++
++#define SPDIF_FIFO_ADDR 0x100
++#define DMAC_SPDIF_POLLING_LEN 256
++
++/* ctrl: sampled on the rising clock edge */
++#define SPDIF_TSAMPLERATE 0 /* [SRATEW-1:0] */
++/* 0:SFR reg reset to defualt value; auto set back to '1' after reset */
++#define SPDIF_SFR_ENABLE (1<<8)
++/* 0:reset of SPDIF block, SRF bits are unchanged; 1:enables SPDIF module */
++#define SPDIF_ENABLE (1<<9)
++/* 0:FIFO pointers are reset to zero,threshold levels for FIFO are unchaned; auto set back to 1 */
++#define SPDIF_FIFO_ENABLE (1<<10)
++/* 1:blocked and the modules are in power save mode; 0:block feeds the modules */
++#define SPDIF_CLK_ENABLE (1<<11)
++#define SPDIF_TR_MODE (1<<12) /* 0:rx; 1:tx */
++/* 0:party bit rx in a sub-frame is repeated on the parity; 1:check on a parity error */
++#define SPDIF_PARITCHECK (1<<13)
++/*
++ * 0:parity bit from FIFO is transmitted in sub-frame;
++ * 1:parity bit generated inside the core and added to a transmitted sub-frame
++ */
++#define SPDIF_PARITYGEN (1<<14)
++/* 0:validity bit in frame isn't checked and all frame are written; 1:validity bit rx is checked */
++#define SPDIF_VALIDITYCHECK (1<<15)
++#define SPDIF_CHANNEL_MODE (1<<16) /* 0:two-channel; 1:single-channel */
++/* only tx -single-channel mode; 0:secondary channel; 1: left(primary) channel */
++#define SPDIF_DUPLICATE (1<<17)
++/*
++ * only tx;
++ * 0:first preamble B after reset tx valid sub-frame;
++ * 1:first preamble B is tx after preambleddel(INT_REG)
++ */
++#define SPDIF_SETPREAMBB (1<<18)
++/* 0:FIFO disabled ,APB accese FIFO; 1:FIFO enable, APB access to FIFO disable; */
++#define SPDIF_USE_FIFO_IF (1<<19)
++#define SPDIF_PARITY_MASK (1<<21)
++#define SPDIF_UNDERR_MASK (1<<22)
++#define SPDIF_OVRERR_MASK (1<<23)
++#define SPDIF_EMPTY_MASK (1<<24)
++#define SPDIF_AEMPTY_MASK (1<<25)
++#define SPDIF_FULL_MASK (1<<26)
++#define SPDIF_AFULL_MASK (1<<27)
++#define SPDIF_SYNCERR_MASK (1<<28)
++#define SPDIF_LOCK_MASK (1<<29)
++#define SPDIF_BEGIN_MASK (1<<30)
++#define SPDIF_INTEREQ_MAKS (1<<31)
++
++#define SPDIF_MASK_ENABLE (SPDIF_PARITY_MASK | SPDIF_UNDERR_MASK | \
++ SPDIF_OVRERR_MASK | SPDIF_EMPTY_MASK | \
++ SPDIF_AEMPTY_MASK | SPDIF_FULL_MASK | \
++ SPDIF_AFULL_MASK | SPDIF_SYNCERR_MASK | \
++ SPDIF_LOCK_MASK | SPDIF_BEGIN_MASK | \
++ SPDIF_INTEREQ_MAKS)
++
++#define SPDIF_MASK_FIFO (SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK | \
++ SPDIF_FULL_MASK | SPDIF_AFULL_MASK)
++
++/* INT_REG */
++#define SPDIF_RSAMPLERATE 0 /* [SRATEW-1:0] */
++#define SPDIF_PREAMBLEDEL 8 /* [PDELAYW+7:8] first B delay */
++#define SPDIF_PARITYO (1<<21) /* 0:clear parity error */
++#define SPDIF_TDATA_UNDERR (1<<22) /* tx data underrun error;0:clear */
++#define SPDIF_RDATA_OVRERR (1<<23) /* rx data overrun error; 0:clear */
++#define SPDIF_FIFO_EMPTY (1<<24) /* empty; 0:clear */
++#define SPDIF_FIOF_AEMPTY (1<<25) /* almost empty; 0:clear */
++#define SPDIF_FIFO_FULL (1<<26) /* FIFO full; 0:clear */
++#define SPDIF_FIFO_AFULL (1<<27) /* FIFO almost full; 0:clear */
++#define SPDIF_SYNCERR (1<<28) /* sync error; 0:clear */
++#define SPDIF_LOCK (1<<29) /* sync; 0:clear */
++#define SPDIF_BLOCK_BEGIN (1<<30) /* new start block rx data */
++
++#define SPDIF_INT_REG_BIT (SPDIF_PARITYO | SPDIF_TDATA_UNDERR | \
++ SPDIF_RDATA_OVRERR | SPDIF_FIFO_EMPTY | \
++ SPDIF_FIOF_AEMPTY | SPDIF_FIFO_FULL | \
++ SPDIF_FIFO_AFULL | SPDIF_SYNCERR | \
++ SPDIF_LOCK | SPDIF_BLOCK_BEGIN)
++
++#define SPDIF_ERROR_INT_STATUS (SPDIF_PARITYO | \
++ SPDIF_TDATA_UNDERR | SPDIF_RDATA_OVRERR)
++#define SPDIF_FIFO_INT_STATUS (SPDIF_FIFO_EMPTY | SPDIF_FIOF_AEMPTY | \
++ SPDIF_FIFO_FULL | SPDIF_FIFO_AFULL)
++
++#define SPDIF_INT_PARITY_ERROR (-1)
++#define SPDIF_INT_TDATA_UNDERR (-2)
++#define SPDIF_INT_RDATA_OVRERR (-3)
++#define SPDIF_INT_FIFO_EMPTY 1
++#define SPDIF_INT_FIFO_AEMPTY 2
++#define SPDIF_INT_FIFO_FULL 3
++#define SPDIF_INT_FIFO_AFULL 4
++#define SPDIF_INT_SYNCERR (-4)
++#define SPDIF_INT_LOCK 5 /* reciever has become synchronized with input data stream */
++#define SPDIF_INT_BLOCK_BEGIN 6 /* start a new block in recieve data, written into FIFO */
++
++/* FIFO_CTRL */
++#define SPDIF_AEMPTY_THRESHOLD 0 /* [depth-1:0] */
++#define SPDIF_AFULL_THRESHOLD 16 /* [depth+15:16] */
++
++/* STAT_REG */
++#define SPDIF_FIFO_LEVEL (1<<0)
++#define SPDIF_PARITY_FLAG (1<<21) /* 1:error; 0:repeated */
++#define SPDIF_UNDERR_FLAG (1<<22) /* 1:error */
++#define SPDIF_OVRERR_FLAG (1<<23) /* 1:error */
++#define SPDIF_EMPTY_FLAG (1<<24) /* 1:fifo empty */
++#define SPDIF_AEMPTY_FLAG (1<<25) /* 1:fifo almost empty */
++#define SPDIF_FULL_FLAG (1<<26) /* 1:fifo full */
++#define SPDIF_AFULL_FLAG (1<<27) /* 1:fifo almost full */
++#define SPDIF_SYNCERR_FLAG (1<<28) /* 1:rx sync error */
++#define SPDIF_LOCK_FLAG (1<<29) /* 1:RX sync */
++#define SPDIF_BEGIN_FLAG (1<<30) /* 1:start a new block */
++/* 1:left channel received and tx into FIFO; 0:right channel received and tx into FIFO */
++#define SPDIF_RIGHT_LEFT (1<<31)
++
++#define BIT8TO20MASK 0x1FFF
++#define ALLBITMASK 0xFFFFFFFF
++
++#define SPDIF_STAT (SPDIF_PARITY_FLAG | SPDIF_UNDERR_FLAG | \
++ SPDIF_OVRERR_FLAG | SPDIF_EMPTY_FLAG | \
++ SPDIF_AEMPTY_FLAG | SPDIF_FULL_FLAG | \
++ SPDIF_AFULL_FLAG | SPDIF_SYNCERR_FLAG | \
++ SPDIF_LOCK_FLAG | SPDIF_BEGIN_FLAG | \
++ SPDIF_RIGHT_LEFT)
++struct sf_spdif_dev {
++ void __iomem *spdif_base;
++ struct regmap *regmap;
++ struct device *dev;
++ u32 fifo_th;
++ int active;
++
++ /* data related to DMA transfers b/w i2s and DMAC */
++ struct snd_dmaengine_dai_dma_data play_dma_data;
++ struct snd_dmaengine_dai_dma_data capture_dma_data;
++
++ bool use_pio;
++ struct snd_pcm_substream __rcu *tx_substream;
++ struct snd_pcm_substream __rcu *rx_substream;
++
++ unsigned int (*tx_fn)(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format);
++ unsigned int (*rx_fn)(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format);
++
++ snd_pcm_format_t format;
++ bool channels;
++ unsigned int tx_ptr;
++ unsigned int rx_ptr;
++ struct clk *spdif_apb;
++ struct clk *spdif_core;
++ struct clk *audio_root;
++ struct clk *mclk_inner;
++ struct clk *mclk;
++ struct clk *mclk_ext;
++ struct reset_control *rst_apb;
++ unsigned int reg_spdif_ctrl;
++ unsigned int reg_spdif_int;
++ unsigned int reg_spdif_fifo_ctrl;
++
++ struct snd_dmaengine_dai_dma_data dma_data;
++};
++
++#if IS_ENABLED(CONFIG_SND_SOC_JH7110_SPDIF_PCM)
++void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev);
++void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev);
++int sf_spdif_pcm_register(struct platform_device *pdev);
++#else
++void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev) { }
++void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev) { }
++int sf_spdif_pcm_register(struct platform_device *pdev)
++{
++ return -EINVAL;
++}
++#endif
++
++#endif /* __SND_SOC_JH7110_SPDIF_H */
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_spdif_pcm.c
+@@ -0,0 +1,339 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * SPDIF PCM driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/io.h>
++#include <linux/rcupdate.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++
++#include "jh7110_spdif.h"
++
++#define BUFFER_BYTES_MAX (3 * 2 * 8 * PERIOD_BYTES_MIN)
++#define PERIOD_BYTES_MIN 4096
++#define PERIODS_MIN 2
++
++static unsigned int sf_spdif_pcm_tx(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format)
++{
++ unsigned int period_pos = tx_ptr % runtime->period_size;
++ u32 data[2];
++ int i;
++
++ /* two- channel and signal-channel mode */
++ if (dev->channels) {
++ const u16 (*p16)[2] = (void *)runtime->dma_area;
++ const u32 (*p32)[2] = (void *)runtime->dma_area;
++
++ for (i = 0; i < dev->fifo_th; i++) {
++ if (format == SNDRV_PCM_FORMAT_S16_LE) {
++ data[0] = p16[tx_ptr][0];
++ data[0] = data[0]<<8;
++ data[0] &= 0x00ffff00;
++ data[1] = p16[tx_ptr][1];
++ data[1] = data[1]<<8;
++ data[1] &= 0x00ffff00;
++ } else if (format == SNDRV_PCM_FORMAT_S24_LE) {
++ data[0] = p32[tx_ptr][0];
++ data[1] = p32[tx_ptr][1];
++
++ /*
++ * To adapt S24_3LE and ALSA pass parameter of S24_LE.
++ * operation of S24_LE should be same to S24_3LE.
++ * So it would wrong when playback S24_LE file.
++ * when want to playback S24_LE file, should add in there:
++ * data[0] = data[0]>>8;
++ * data[1] = data[1]>>8;
++ */
++
++ data[0] &= 0x00ffffff;
++ data[1] &= 0x00ffffff;
++ } else if (format == SNDRV_PCM_FORMAT_S24_3LE) {
++ data[0] = p32[tx_ptr][0];
++ data[1] = p32[tx_ptr][1];
++ data[0] &= 0x00ffffff;
++ data[1] &= 0x00ffffff;
++ } else if (format == SNDRV_PCM_FORMAT_S32_LE) {
++ data[0] = p32[tx_ptr][0];
++ data[0] = data[0]>>8;
++ data[1] = p32[tx_ptr][1];
++ data[1] = data[1]>>8;
++ }
++
++ iowrite32(data[0], dev->spdif_base + SPDIF_FIFO_ADDR);
++ iowrite32(data[1], dev->spdif_base + SPDIF_FIFO_ADDR);
++ period_pos++;
++ if (++tx_ptr >= runtime->buffer_size)
++ tx_ptr = 0;
++ }
++ } else {
++ const u16 (*p16) = (void *)runtime->dma_area;
++ const u32 (*p32) = (void *)runtime->dma_area;
++
++ for (i = 0; i < dev->fifo_th; i++) {
++ if (format == SNDRV_PCM_FORMAT_S16_LE) {
++ data[0] = p16[tx_ptr];
++ data[0] = data[0]<<8;
++ data[0] &= 0x00ffff00;
++ } else if (format == SNDRV_PCM_FORMAT_S24_LE ||
++ format == SNDRV_PCM_FORMAT_S24_3LE) {
++ data[0] = p32[tx_ptr];
++ data[0] &= 0x00ffffff;
++ } else if (format == SNDRV_PCM_FORMAT_S32_LE) {
++ data[0] = p32[tx_ptr];
++ data[0] = data[0]>>8;
++ }
++
++ iowrite32(data[0], dev->spdif_base + SPDIF_FIFO_ADDR);
++ period_pos++;
++ if (++tx_ptr >= runtime->buffer_size)
++ tx_ptr = 0;
++ }
++ }
++
++ *period_elapsed = period_pos >= runtime->period_size;
++ return tx_ptr;
++}
++
++static unsigned int sf_spdif_pcm_rx(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format)
++{
++ u16 (*p16)[2] = (void *)runtime->dma_area;
++ u32 (*p32)[2] = (void *)runtime->dma_area;
++ unsigned int period_pos = rx_ptr % runtime->period_size;
++ u32 data[2];
++ int i;
++
++ for (i = 0; i < dev->fifo_th; i++) {
++ data[0] = ioread32(dev->spdif_base + SPDIF_FIFO_ADDR);
++ data[1] = ioread32(dev->spdif_base + SPDIF_FIFO_ADDR);
++ if (format == SNDRV_PCM_FORMAT_S16_LE) {
++ p16[rx_ptr][0] = data[0]>>8;
++ p16[rx_ptr][1] = data[1]>>8;
++ } else if (format == SNDRV_PCM_FORMAT_S24_LE) {
++ p32[rx_ptr][0] = data[0];
++ p32[rx_ptr][1] = data[1];
++ } else if (format == SNDRV_PCM_FORMAT_S32_LE) {
++ p32[rx_ptr][0] = data[0]<<8;
++ p32[rx_ptr][1] = data[1]<<8;
++ }
++
++ period_pos++;
++ if (++rx_ptr >= runtime->buffer_size)
++ rx_ptr = 0;
++ }
++
++ *period_elapsed = period_pos >= runtime->period_size;
++ return rx_ptr;
++}
++
++static const struct snd_pcm_hardware sf_pcm_hardware = {
++ .info = SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_MMAP |
++ SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER |
++ SNDRV_PCM_INFO_PAUSE |
++ SNDRV_PCM_INFO_RESUME,
++ .rates = SNDRV_PCM_RATE_8000 |
++ SNDRV_PCM_RATE_11025 |
++ SNDRV_PCM_RATE_16000 |
++ SNDRV_PCM_RATE_22050 |
++ SNDRV_PCM_RATE_32000 |
++ SNDRV_PCM_RATE_44100 |
++ SNDRV_PCM_RATE_48000,
++ .rate_min = 8000,
++ .rate_max = 48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE |
++ SNDRV_PCM_FMTBIT_S24_LE |
++ SNDRV_PCM_FMTBIT_S24_3LE |
++ SNDRV_PCM_FMTBIT_S32_LE,
++ .channels_min = 1,
++ .channels_max = 2,
++ .buffer_bytes_max = BUFFER_BYTES_MAX,
++ .period_bytes_min = PERIOD_BYTES_MIN,
++ .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
++ .periods_min = PERIODS_MIN,
++ .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
++ .fifo_size = 16,
++};
++
++static void sf_spdif_pcm_transfer(struct sf_spdif_dev *dev, bool push)
++{
++ struct snd_pcm_substream *substream;
++ bool active, period_elapsed;
++
++ rcu_read_lock();
++ if (push)
++ substream = rcu_dereference(dev->tx_substream);
++ else
++ substream = rcu_dereference(dev->rx_substream);
++
++ active = substream && snd_pcm_running(substream);
++ if (active) {
++ unsigned int ptr;
++ unsigned int new_ptr;
++
++ if (push) {
++ ptr = READ_ONCE(dev->tx_ptr);
++ new_ptr = dev->tx_fn(dev, substream->runtime, ptr,
++ &period_elapsed, dev->format);
++ cmpxchg(&dev->tx_ptr, ptr, new_ptr);
++ } else {
++ ptr = READ_ONCE(dev->rx_ptr);
++ new_ptr = dev->rx_fn(dev, substream->runtime, ptr,
++ &period_elapsed, dev->format);
++ cmpxchg(&dev->rx_ptr, ptr, new_ptr);
++ }
++
++ if (period_elapsed)
++ snd_pcm_period_elapsed(substream);
++ }
++ rcu_read_unlock();
++}
++
++void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev)
++{
++ sf_spdif_pcm_transfer(dev, true);
++}
++
++void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev)
++{
++ sf_spdif_pcm_transfer(dev, false);
++}
++
++static int sf_pcm_open(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++ struct sf_spdif_dev *dev = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
++
++ snd_soc_set_runtime_hwparams(substream, &sf_pcm_hardware);
++ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
++ runtime->private_data = dev;
++
++ return 0;
++}
++
++static int sf_pcm_close(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream)
++{
++ synchronize_rcu();
++ return 0;
++}
++
++static int sf_pcm_hw_params(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *hw_params)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct sf_spdif_dev *dev = runtime->private_data;
++
++ switch (params_channels(hw_params)) {
++ case 1:
++ case 2:
++ break;
++ default:
++ dev_err(dev->dev, "invalid channels number\n");
++ return -EINVAL;
++ }
++
++ dev->format = params_format(hw_params);
++ switch (dev->format) {
++ case SNDRV_PCM_FORMAT_S16_LE:
++ case SNDRV_PCM_FORMAT_S24_LE:
++ case SNDRV_PCM_FORMAT_S24_3LE:
++ case SNDRV_PCM_FORMAT_S32_LE:
++ break;
++ default:
++ dev_err(dev->dev, "invalid format\n");
++ return -EINVAL;
++ }
++
++ dev->tx_fn = sf_spdif_pcm_tx;
++ dev->rx_fn = sf_spdif_pcm_rx;
++
++ return 0;
++}
++
++static int sf_pcm_trigger(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream, int cmd)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct sf_spdif_dev *dev = runtime->private_data;
++ int ret = 0;
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ WRITE_ONCE(dev->tx_ptr, 0);
++ rcu_assign_pointer(dev->tx_substream, substream);
++ } else {
++ WRITE_ONCE(dev->rx_ptr, 0);
++ rcu_assign_pointer(dev->rx_substream, substream);
++ }
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ rcu_assign_pointer(dev->tx_substream, NULL);
++ else
++ rcu_assign_pointer(dev->rx_substream, NULL);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static snd_pcm_uframes_t sf_pcm_pointer(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct sf_spdif_dev *dev = runtime->private_data;
++ snd_pcm_uframes_t pos;
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ pos = READ_ONCE(dev->tx_ptr);
++ else
++ pos = READ_ONCE(dev->rx_ptr);
++
++ return pos < runtime->buffer_size ? pos : 0;
++}
++
++static int sf_pcm_new(struct snd_soc_component *component,
++ struct snd_soc_pcm_runtime *rtd)
++{
++ size_t size = sf_pcm_hardware.buffer_bytes_max;
++
++ snd_pcm_set_managed_buffer_all(rtd->pcm,
++ SNDRV_DMA_TYPE_CONTINUOUS,
++ NULL, size, size);
++
++ return 0;
++}
++
++static const struct snd_soc_component_driver sf_pcm_component = {
++ .open = sf_pcm_open,
++ .close = sf_pcm_close,
++ .hw_params = sf_pcm_hw_params,
++ .trigger = sf_pcm_trigger,
++ .pointer = sf_pcm_pointer,
++ .pcm_construct = sf_pcm_new,
++};
++
++int sf_spdif_pcm_register(struct platform_device *pdev)
++{
++ return devm_snd_soc_register_component(&pdev->dev, &sf_pcm_component,
++ NULL, 0);
++}
diff --git a/target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch b/target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch
new file mode 100644
index 0000000000..006760d754
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch
@@ -0,0 +1,537 @@
+From 9c4858f9fe4d8f8fe5cf347b3ca727016b7ba492 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Tue, 20 Jun 2023 15:57:53 +0800
+Subject: [PATCH 081/116] ASoC: starfive: Add JH7110 PDM driver
+
+Add pdm driver support for the StarFive JH7110 SoC.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+---
+ sound/soc/starfive/Kconfig | 8 +
+ sound/soc/starfive/Makefile | 2 +
+ sound/soc/starfive/jh7110_pdm.c | 493 ++++++++++++++++++++++++++++++++
+ 3 files changed, 503 insertions(+)
+ create mode 100644 sound/soc/starfive/jh7110_pdm.c
+
+--- a/sound/soc/starfive/Kconfig
++++ b/sound/soc/starfive/Kconfig
+@@ -7,6 +7,14 @@ config SND_SOC_STARFIVE
+ the Starfive SoCs' Audio interfaces. You will also need to
+ select the audio interfaces to support below.
+
++config SND_SOC_JH7110_PDM
++ tristate "JH7110 PDM device driver"
++ depends on HAVE_CLK && SND_SOC_STARFIVE
++ select SND_SOC_JH7110_I2S
++ select REGMAP_MMIO
++ help
++ Say Y or M if you want to add support for StarFive pdm driver.
++
+ config SND_SOC_JH7110_PWMDAC
+ tristate "JH7110 PWM-DAC device driver"
+ depends on HAVE_CLK && SND_SOC_STARFIVE
+--- a/sound/soc/starfive/Makefile
++++ b/sound/soc/starfive/Makefile
+@@ -1,4 +1,6 @@
+ # StarFive Platform Support
++obj-$(CONFIG_SND_SOC_JH7110_PDM) += jh7110_pdm.o
++
+ obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
+
+ obj-$(CONFIG_SND_SOC_JH7110_SPDIF) += spdif.o
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_pdm.c
+@@ -0,0 +1,493 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * PDM driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/dmaengine.h>
++#include <linux/reset.h>
++#include <linux/module.h>
++#include <linux/of_irq.h>
++#include <linux/of_platform.h>
++#include <linux/regmap.h>
++#include <linux/pm_runtime.h>
++#include <linux/types.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dai.h>
++#include <sound/tlv.h>
++
++#define PDM_DMIC_CTRL0 0x00
++#define PDM_DC_SCALE0 0x04
++#define PDM_DMIC_CTRL1 0x10
++#define PDM_DC_SCALE1 0x14
++
++/* PDM CTRL OFFSET */
++#define PDM_DMIC_MSB_SHIFT 1
++#define PDM_DMIC_MSB_MASK (0x7 << PDM_DMIC_MSB_SHIFT)
++#define PDM_DMIC_VOL_SHIFT 16
++#define PDM_DMIC_VOL_MASK (0x3f << PDM_DMIC_VOL_SHIFT)
++#define PDM_VOL_DB_MUTE (0x3f << PDM_DMIC_VOL_SHIFT)
++#define PDM_VOL_DB_MAX 0
++
++#define PDM_DMIC_RVOL_MASK BIT(22)
++#define PDM_DMIC_LVOL_MASK BIT(23)
++#define PDM_DMIC_I2S_SLAVE BIT(24)
++#define PDM_DMIC_HPF_EN BIT(28)
++#define PDM_DMIC_FASTMODE_MASK BIT(29)
++#define PDM_DMIC_DC_BYPASS_MASK BIT(30)
++#define PDM_SW_RST_MASK BIT(31)
++#define PDM_SW_RST_RELEASE BIT(31)
++
++/* PDM SCALE OFFSET */
++#define DMIC_DCOFF3_SHIFT 24
++#define DMIC_DCOFF2_SHIFT 16
++#define DMIC_DCOFF1_SHIFT 8
++
++#define DMIC_DCOFF3_MASK (0xf << DMIC_DCOFF3_SHIFT)
++#define DMIC_DCOFF3_VAL (0xc << DMIC_DCOFF3_SHIFT)
++#define DMIC_DCOFF1_MASK (0xff << DMIC_DCOFF1_SHIFT)
++#define DMIC_DCOFF1_VAL (0x5 << DMIC_DCOFF1_SHIFT)
++#define DMIC_SCALE_MASK 0x3f
++#define DMIC_SCALE_DEF_VAL 0x8
++
++enum PDM_MSB_SHIFT {
++ PDM_MSB_SHIFT_NONE = 0,
++ PDM_MSB_SHIFT_1,
++ PDM_MSB_SHIFT_2,
++ PDM_MSB_SHIFT_3,
++ PDM_MSB_SHIFT_4,
++ PDM_MSB_SHIFT_5,
++ PDM_MSB_SHIFT_6,
++ PDM_MSB_SHIFT_7,
++};
++
++struct sf_pdm {
++ struct regmap *pdm_map;
++ struct device *dev;
++ struct clk *clk_pdm_apb;
++ struct clk *clk_pdm_mclk;
++ struct clk *clk_mclk;
++ struct clk *clk_mclk_ext;
++ struct reset_control *rst_pdm_dmic;
++ struct reset_control *rst_pdm_apb;
++ unsigned char flag_first;
++ unsigned int saved_ctrl0;
++ unsigned int saved_scale0;
++};
++
++static const DECLARE_TLV_DB_SCALE(volume_tlv, -9450, 150, 0);
++
++static const struct snd_kcontrol_new sf_pdm_snd_controls[] = {
++ SOC_SINGLE("DC compensation Control", PDM_DMIC_CTRL0, 30, 1, 0),
++ SOC_SINGLE("High Pass Filter Control", PDM_DMIC_CTRL0, 28, 1, 0),
++ SOC_SINGLE("Left Channel Volume Control", PDM_DMIC_CTRL0, 23, 1, 0),
++ SOC_SINGLE("Right Channel Volume Control", PDM_DMIC_CTRL0, 22, 1, 0),
++ SOC_SINGLE_TLV("Volume", PDM_DMIC_CTRL0, 16, 0x3F, 1, volume_tlv),
++ SOC_SINGLE("Data MSB Shift", PDM_DMIC_CTRL0, 1, 7, 0),
++ SOC_SINGLE("SCALE", PDM_DC_SCALE0, 0, 0x3F, 0),
++ SOC_SINGLE("DC offset", PDM_DC_SCALE0, 8, 0xFFFFF, 0),
++};
++
++static void sf_pdm_enable(struct regmap *map)
++{
++ /* Left and Right Channel Volume Control Enable */
++ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_RVOL_MASK, 0);
++ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_LVOL_MASK, 0);
++}
++
++static void sf_pdm_disable(struct regmap *map)
++{
++ /* Left and Right Channel Volume Control Disable */
++ regmap_update_bits(map, PDM_DMIC_CTRL0,
++ PDM_DMIC_RVOL_MASK, PDM_DMIC_RVOL_MASK);
++ regmap_update_bits(map, PDM_DMIC_CTRL0,
++ PDM_DMIC_LVOL_MASK, PDM_DMIC_LVOL_MASK);
++}
++
++static int sf_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ if (priv->flag_first) {
++ priv->flag_first = 0;
++ mdelay(200);
++ }
++
++ sf_pdm_enable(priv->pdm_map);
++ return 0;
++
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ sf_pdm_disable(priv->pdm_map);
++ return 0;
++
++ default:
++ return -EINVAL;
++ }
++}
++
++static int sf_pdm_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *dai)
++{
++ struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
++ unsigned int sample_rate;
++ unsigned int data_width;
++ int ret;
++ const int pdm_mul = 128;
++
++ sample_rate = params_rate(params);
++ switch (sample_rate) {
++ case 8000:
++ case 11025:
++ case 16000:
++ break;
++ default:
++ dev_err(priv->dev, "can't support sample rate:%d\n", sample_rate);
++ return -EINVAL;
++ }
++
++ data_width = params_width(params);
++ switch (data_width) {
++ case 16:
++ case 32:
++ break;
++ default:
++ dev_err(priv->dev, "can't support bit width %d\n", data_width);
++ return -EINVAL;
++ }
++
++ /* set pdm_mclk, PDM MCLK = 128 * LRCLK */
++ ret = clk_set_rate(priv->clk_pdm_mclk, pdm_mul * sample_rate);
++ if (ret) {
++ dev_err(priv->dev, "Can't set pdm_mclk: %d\n", ret);
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct snd_soc_dai_ops sf_pdm_dai_ops = {
++ .trigger = sf_pdm_trigger,
++ .hw_params = sf_pdm_hw_params,
++};
++
++static void sf_pdm_module_init(struct sf_pdm *priv)
++{
++ /* Reset */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_SW_RST_MASK, 0x00);
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_SW_RST_MASK, PDM_SW_RST_RELEASE);
++
++ /* Make sure the device is initially disabled */
++ sf_pdm_disable(priv->pdm_map);
++
++ /* MUTE */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_VOL_MASK, PDM_VOL_DB_MUTE);
++
++ /* UNMUTE */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_VOL_MASK, PDM_VOL_DB_MAX);
++
++ /* enable high pass filter */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_HPF_EN, PDM_DMIC_HPF_EN);
++
++ /* PDM work as slave mode */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_I2S_SLAVE, PDM_DMIC_I2S_SLAVE);
++
++ /* disable fast mode */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_FASTMODE_MASK, 0);
++
++ /* dmic msb shift 0 */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_MSB_MASK, 0);
++
++ /* scale: 0x8 */
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_SCALE_MASK, DMIC_SCALE_DEF_VAL);
++
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_DCOFF1_MASK, DMIC_DCOFF1_VAL);
++
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_DCOFF3_MASK, DMIC_DCOFF3_VAL);
++
++ /* scale: 0x3f */
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_SCALE_MASK, DMIC_SCALE_MASK);
++
++ /* dmic msb shift 2 */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_MSB_MASK, PDM_MSB_SHIFT_4);
++}
++
++#define SF_PDM_RATES (SNDRV_PCM_RATE_8000 | \
++ SNDRV_PCM_RATE_11025 | \
++ SNDRV_PCM_RATE_16000)
++
++#define SF_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
++ SNDRV_PCM_FMTBIT_S32_LE)
++
++static struct snd_soc_dai_driver sf_pdm_dai_drv = {
++ .name = "PDM",
++ .id = 0,
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SF_PDM_RATES,
++ .formats = SF_PDM_FORMATS,
++ },
++ .ops = &sf_pdm_dai_ops,
++ .symmetric_rate = 1,
++};
++
++static int sf_pdm_component_probe(struct snd_soc_component *component)
++{
++ struct sf_pdm *priv = snd_soc_component_get_drvdata(component);
++
++ snd_soc_component_init_regmap(component, priv->pdm_map);
++ snd_soc_add_component_controls(component, sf_pdm_snd_controls,
++ ARRAY_SIZE(sf_pdm_snd_controls));
++
++ return 0;
++}
++
++static int sf_pdm_clock_enable(struct sf_pdm *priv)
++{
++ int ret;
++
++ ret = clk_prepare_enable(priv->clk_pdm_mclk);
++ if (ret) {
++ dev_err(priv->dev, "failed to prepare enable clk_pdm_mclk\n");
++ return ret;
++ }
++
++ ret = clk_prepare_enable(priv->clk_pdm_apb);
++ if (ret) {
++ dev_err(priv->dev, "failed to prepare enable clk_pdm_apb\n");
++ goto disable_pdm_mclk;
++ }
++
++ ret = reset_control_deassert(priv->rst_pdm_dmic);
++ if (ret) {
++ dev_err(priv->dev, "failed to deassert pdm_dmic\n");
++ goto disable_pdm_apb;
++ }
++
++ ret = reset_control_deassert(priv->rst_pdm_apb);
++ if (ret) {
++ dev_err(priv->dev, "failed to deassert pdm_apb\n");
++ goto disable_pdm_apb;
++ }
++
++ ret = clk_set_parent(priv->clk_mclk, priv->clk_mclk_ext);
++ if (ret) {
++ dev_err(priv->dev, "failed to set parent clk_mclk ret=%d\n", ret);
++ goto disable_pdm_apb;
++ }
++
++ return 0;
++
++disable_pdm_apb:
++ clk_disable_unprepare(priv->clk_pdm_apb);
++disable_pdm_mclk:
++ clk_disable_unprepare(priv->clk_pdm_mclk);
++
++ return ret;
++}
++
++#ifdef CONFIG_PM
++static int sf_pdm_runtime_suspend(struct device *dev)
++{
++ struct sf_pdm *priv = dev_get_drvdata(dev);
++
++ clk_disable_unprepare(priv->clk_pdm_apb);
++ clk_disable_unprepare(priv->clk_pdm_mclk);
++
++ return 0;
++}
++
++static int sf_pdm_runtime_resume(struct device *dev)
++{
++ struct sf_pdm *priv = dev_get_drvdata(dev);
++ int ret;
++
++ ret = sf_pdm_clock_enable(priv);
++ if (!ret)
++ sf_pdm_module_init(priv);
++
++ return ret;
++}
++#endif
++
++#ifdef CONFIG_PM_SLEEP
++static int sf_pdm_suspend(struct snd_soc_component *component)
++{
++ return pm_runtime_force_suspend(component->dev);
++}
++
++static int sf_pdm_resume(struct snd_soc_component *component)
++{
++ return pm_runtime_force_resume(component->dev);
++}
++
++#else
++#define sf_pdm_suspend NULL
++#define sf_pdm_resume NULL
++#endif
++
++static const struct snd_soc_component_driver sf_pdm_component_drv = {
++ .name = "jh7110-pdm",
++ .probe = sf_pdm_component_probe,
++ .suspend = sf_pdm_suspend,
++ .resume = sf_pdm_resume,
++};
++
++static const struct regmap_config sf_pdm_regmap_cfg = {
++ .reg_bits = 32,
++ .val_bits = 32,
++ .reg_stride = 4,
++ .max_register = 0x20,
++};
++
++static int sf_pdm_clock_get(struct platform_device *pdev, struct sf_pdm *priv)
++{
++ int ret;
++
++ static struct clk_bulk_data clks[] = {
++ { .id = "pdm_mclk" },
++ { .id = "pdm_apb" },
++ { .id = "clk_mclk" },
++ { .id = "mclk_ext" },
++ };
++
++ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to get pdm clocks\n");
++ goto exit;
++ }
++
++ priv->clk_pdm_mclk = clks[0].clk;
++ priv->clk_pdm_apb = clks[1].clk;
++ priv->clk_mclk = clks[2].clk;
++ priv->clk_mclk_ext = clks[3].clk;
++
++ priv->rst_pdm_dmic = devm_reset_control_get_exclusive(&pdev->dev, "pdm_dmic");
++ if (IS_ERR(priv->rst_pdm_dmic)) {
++ dev_err(&pdev->dev, "failed to get pdm_dmic reset control\n");
++ ret = PTR_ERR(priv->rst_pdm_dmic);
++ goto exit;
++ }
++
++ priv->rst_pdm_apb = devm_reset_control_get_exclusive(&pdev->dev, "pdm_apb");
++ if (IS_ERR(priv->rst_pdm_apb)) {
++ dev_err(&pdev->dev, "failed to get pdm_apb reset control\n");
++ ret = PTR_ERR(priv->rst_pdm_apb);
++ goto exit;
++ }
++
++ /*
++ * pdm clock must always be enabled as hardware issue that
++ * no data in the first 4 seconds of the first recording
++ */
++ ret = sf_pdm_clock_enable(priv);
++
++exit:
++ return ret;
++}
++
++static int sf_pdm_probe(struct platform_device *pdev)
++{
++ struct sf_pdm *priv;
++ struct resource *res;
++ void __iomem *regs;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++ platform_set_drvdata(pdev, priv);
++
++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pdm");
++ regs = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(regs))
++ return PTR_ERR(regs);
++
++ priv->pdm_map = devm_regmap_init_mmio(&pdev->dev, regs, &sf_pdm_regmap_cfg);
++ if (IS_ERR(priv->pdm_map)) {
++ dev_err(&pdev->dev, "failed to init regmap: %ld\n",
++ PTR_ERR(priv->pdm_map));
++ return PTR_ERR(priv->pdm_map);
++ }
++
++ priv->dev = &pdev->dev;
++ priv->flag_first = 1;
++
++ ret = sf_pdm_clock_get(pdev, priv);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to enable audio-pdm clock\n");
++ return ret;
++ }
++
++ dev_set_drvdata(&pdev->dev, priv);
++
++ ret = devm_snd_soc_register_component(&pdev->dev, &sf_pdm_component_drv,
++ &sf_pdm_dai_drv, 1);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to register pdm dai\n");
++ return ret;
++ }
++ pm_runtime_enable(&pdev->dev);
++
++ return 0;
++}
++
++static int sf_pdm_dev_remove(struct platform_device *pdev)
++{
++ pm_runtime_disable(&pdev->dev);
++ return 0;
++}
++
++static const struct of_device_id sf_pdm_of_match[] = {
++ {.compatible = "starfive,jh7110-pdm",},
++ {}
++};
++MODULE_DEVICE_TABLE(of, sf_pdm_of_match);
++
++static const struct dev_pm_ops sf_pdm_pm_ops = {
++ SET_RUNTIME_PM_OPS(sf_pdm_runtime_suspend,
++ sf_pdm_runtime_resume, NULL)
++};
++
++static struct platform_driver sf_pdm_driver = {
++ .driver = {
++ .name = "jh7110-pdm",
++ .of_match_table = sf_pdm_of_match,
++ .pm = &sf_pdm_pm_ops,
++ },
++ .probe = sf_pdm_probe,
++ .remove = sf_pdm_dev_remove,
++};
++module_platform_driver(sf_pdm_driver);
++
++MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
++MODULE_DESCRIPTION("Starfive PDM Controller Driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch b/target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch
new file mode 100644
index 0000000000..ed8a3af308
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch
@@ -0,0 +1,55 @@
+From 59cbdfeee0fc1ad382a0bc8f7fa897a9f5d03df0 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Fri, 9 Jun 2023 16:54:36 +0800
+Subject: [PATCH 082/116] dt-binding: input: Add tink_ft5406
+
+Add tink_ft5406.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ .../bindings/input/tinker_ft5406.yaml | 39 +++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/input/tinker_ft5406.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/input/tinker_ft5406.yaml
+@@ -0,0 +1,39 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/input/touchscreen/goodix.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Tinker FT5406 touchscreen controller Bindings
++
++maintainers:
++ - Changhuang Liang <changhuang.liang@starfivetech.com>
++
++allOf:
++ - $ref: touchscreen.yaml#
++
++properties:
++ compatible:
++ const: tinker_ft5406
++
++ reg:
++ const: 0x38
++
++additionalProperties: false
++
++required:
++ - compatible
++ - reg
++
++examples:
++ - |
++ i2c {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ tinker_ft5406@38 {
++ compatible = "tinker_ft5406";
++ reg = <0x38>;
++ };
++ };
++
++...
diff --git a/target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch b/target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch
new file mode 100644
index 0000000000..f45085f495
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch
@@ -0,0 +1,444 @@
+From 4800b6e0f2190d991cd4e5352167a9422841f195 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 21 Dec 2022 16:20:04 +0800
+Subject: [PATCH 083/116] input: touchscreen: Add tinker_ft5406 driver support
+
+Add tinker_ft5406 driver support
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/input/touchscreen/Kconfig | 6 +
+ drivers/input/touchscreen/Makefile | 1 +
+ drivers/input/touchscreen/tinker_ft5406.c | 406 ++++++++++++++++++++++
+ 3 files changed, 413 insertions(+)
+ create mode 100644 drivers/input/touchscreen/tinker_ft5406.c
+
+--- a/drivers/input/touchscreen/Kconfig
++++ b/drivers/input/touchscreen/Kconfig
+@@ -1399,4 +1399,10 @@ config TOUCHSCREEN_HIMAX_HX83112B
+ To compile this driver as a module, choose M here: the
+ module will be called himax_hx83112b.
+
++config TOUCHSCREEN_TINKER_FT5406
++ tristate "tinker ft5406"
++ depends on I2C
++ help
++ Control ft5406 touch ic.
++
+ endif
+--- a/drivers/input/touchscreen/Makefile
++++ b/drivers/input/touchscreen/Makefile
+@@ -118,3 +118,4 @@ obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5
+ obj-$(CONFIG_TOUCHSCREEN_IQS7211) += iqs7211.o
+ obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o
+ obj-$(CONFIG_TOUCHSCREEN_HIMAX_HX83112B) += himax_hx83112b.o
++obj-$(CONFIG_TOUCHSCREEN_TINKER_FT5406) += tinker_ft5406.o
+--- /dev/null
++++ b/drivers/input/touchscreen/tinker_ft5406.c
+@@ -0,0 +1,406 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ *
++ * TINKER BOARD FT5406 touch driver.
++ *
++ * Copyright (c) 2016 ASUSTek Computer Inc.
++ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
++ *
++ * 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.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/input.h>
++#include <linux/input/mt.h>
++#include <linux/module.h>
++#include <linux/workqueue.h>
++
++#define RETRY_COUNT 10
++#define FT_ONE_TCH_LEN 6
++
++#define FT_REG_FW_VER 0xA6
++#define FT_REG_FW_MIN_VER 0xB2
++#define FT_REG_FW_SUB_MIN_VER 0xB3
++
++#define VALID_TD_STATUS_VAL 10
++#define MAX_TOUCH_POINTS 5
++
++#define FT_PRESS 0x7F
++#define FT_MAX_ID 0x0F
++
++#define FT_TOUCH_X_H 0
++#define FT_TOUCH_X_L 1
++#define FT_TOUCH_Y_H 2
++#define FT_TOUCH_Y_L 3
++#define FT_TOUCH_EVENT 0
++#define FT_TOUCH_ID 2
++
++#define FT_TOUCH_X_H_REG 3
++#define FT_TOUCH_X_L_REG 4
++#define FT_TOUCH_Y_H_REG 5
++#define FT_TOUCH_Y_L_REG 6
++#define FT_TD_STATUS_REG 2
++#define FT_TOUCH_EVENT_REG 3
++#define FT_TOUCH_ID_REG 5
++
++#define FT_TOUCH_DOWN 0
++#define FT_TOUCH_CONTACT 2
++
++struct ts_event {
++ u16 au16_x[MAX_TOUCH_POINTS]; /*x coordinate */
++ u16 au16_y[MAX_TOUCH_POINTS]; /*y coordinate */
++ u8 au8_touch_event[MAX_TOUCH_POINTS]; /*touch event: 0:down; 1:up; 2:contact */
++ u8 au8_finger_id[MAX_TOUCH_POINTS]; /*touch ID */
++ u16 pressure;
++ u8 touch_point;
++ u8 point_num;
++};
++
++struct tinker_ft5406_data {
++ struct device *dev;
++ struct i2c_client *client;
++ struct input_dev *input_dev;
++ struct ts_event event;
++ struct work_struct ft5406_work;
++
++ int screen_width;
++ int screen_height;
++ int xy_reverse;
++ int known_ids;
++ int retry_count;
++ bool finish_work;
++};
++
++struct tinker_ft5406_data *g_ts_data;
++
++static int fts_i2c_read(struct i2c_client *client, char *writebuf,
++ int writelen, char *readbuf, int readlen)
++{
++ int ret;
++
++ if (writelen > 0) {
++ struct i2c_msg msgs[] = {
++ {
++ .addr = client->addr,
++ .flags = 0,
++ .len = writelen,
++ .buf = writebuf,
++ },
++ {
++ .addr = client->addr,
++ .flags = I2C_M_RD,
++ .len = readlen,
++ .buf = readbuf,
++ },
++ };
++ ret = i2c_transfer(client->adapter, msgs, 2);
++ if (ret < 0)
++ dev_err(&client->dev, "i2c read error, %d\n", ret);
++ } else {
++ struct i2c_msg msgs[] = {
++ {
++ .addr = client->addr,
++ .flags = I2C_M_RD,
++ .len = readlen,
++ .buf = readbuf,
++ },
++ };
++ ret = i2c_transfer(client->adapter, msgs, 1);
++ if (ret < 0)
++ dev_err(&client->dev, "i2c read error, %d\n", ret);
++ }
++
++ return ret;
++}
++
++static int fts_read_reg(struct i2c_client *client, u8 addr, u8 *val)
++{
++ return fts_i2c_read(client, &addr, 1, val, 1);
++}
++
++static int fts_check_fw_ver(struct i2c_client *client)
++{
++ u8 reg_addr, fw_ver[3];
++ int ret;
++
++ reg_addr = FT_REG_FW_VER;
++ ret = fts_i2c_read(client, &reg_addr, 1, &fw_ver[0], 1);
++ if (ret < 0)
++ goto error;
++
++ reg_addr = FT_REG_FW_MIN_VER;
++ ret = fts_i2c_read(client, &reg_addr, 1, &fw_ver[1], 1);
++ if (ret < 0)
++ goto error;
++
++ reg_addr = FT_REG_FW_SUB_MIN_VER;
++ ret = fts_i2c_read(client, &reg_addr, 1, &fw_ver[2], 1);
++ if (ret < 0)
++ goto error;
++
++ dev_info(&client->dev, "Firmware version = %d.%d.%d\n",
++ fw_ver[0], fw_ver[1], fw_ver[2]);
++ return 0;
++
++error:
++ return ret;
++}
++
++static int fts_read_td_status(struct tinker_ft5406_data *ts_data)
++{
++ u8 td_status;
++ int ret = -1;
++
++ ret = fts_read_reg(ts_data->client, FT_TD_STATUS_REG, &td_status);
++ if (ret < 0) {
++ dev_err(&ts_data->client->dev,
++ "Get reg td_status failed, %d\n", ret);
++ return ret;
++ }
++ return (int)td_status;
++}
++
++static int fts_read_touchdata(struct tinker_ft5406_data *ts_data)
++{
++ struct ts_event *event = &ts_data->event;
++ int ret = -1, i;
++ u8 buf[FT_ONE_TCH_LEN-2] = { 0 };
++ u8 reg_addr, pointid = FT_MAX_ID;
++
++ for (i = 0; i < event->touch_point && i < MAX_TOUCH_POINTS; i++) {
++ reg_addr = FT_TOUCH_X_H_REG + (i * FT_ONE_TCH_LEN);
++ ret = fts_i2c_read(ts_data->client, &reg_addr, 1, buf, FT_ONE_TCH_LEN-2);
++ if (ret < 0) {
++ dev_err(&ts_data->client->dev, "Read touchdata failed.\n");
++ return ret;
++ }
++
++ pointid = (buf[FT_TOUCH_ID]) >> 4;
++ if (pointid >= MAX_TOUCH_POINTS)
++ break;
++ event->au8_finger_id[i] = pointid;
++ event->au16_x[i] = (s16) (buf[FT_TOUCH_X_H] & 0x0F) << 8 | (s16) buf[FT_TOUCH_X_L];
++ event->au16_y[i] = (s16) (buf[FT_TOUCH_Y_H] & 0x0F) << 8 | (s16) buf[FT_TOUCH_Y_L];
++ event->au8_touch_event[i] = buf[FT_TOUCH_EVENT] >> 6;
++
++ if (ts_data->xy_reverse) {
++ event->au16_x[i] = ts_data->screen_width - event->au16_x[i] - 1;
++ event->au16_y[i] = ts_data->screen_height - event->au16_y[i] - 1;
++ }
++ }
++ event->pressure = FT_PRESS;
++
++ return 0;
++}
++
++static void fts_report_value(struct tinker_ft5406_data *ts_data)
++{
++ struct ts_event *event = &ts_data->event;
++ int i, modified_ids = 0, released_ids;
++
++ for (i = 0; i < event->touch_point && i < MAX_TOUCH_POINTS; i++) {
++ if (event->au8_touch_event[i] == FT_TOUCH_DOWN ||
++ event->au8_touch_event[i] == FT_TOUCH_CONTACT) {
++ modified_ids |= 1 << event->au8_finger_id[i];
++ input_mt_slot(ts_data->input_dev, event->au8_finger_id[i]);
++ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER,
++ true);
++ input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR,
++ event->pressure);
++ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_X,
++ event->au16_x[i]);
++ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_Y,
++ event->au16_y[i]);
++
++ if (!((1 << event->au8_finger_id[i]) & ts_data->known_ids))
++ dev_dbg(&ts_data->client->dev, "Touch id-%d: x = %d, y = %d\n",
++ event->au8_finger_id[i],
++ event->au16_x[i],
++ event->au16_y[i]);
++ }
++ }
++
++ released_ids = ts_data->known_ids & ~modified_ids;
++ for (i = 0; released_ids && i < MAX_TOUCH_POINTS; i++) {
++ if (released_ids & (1<<i)) {
++ dev_dbg(&ts_data->client->dev, "Release id-%d, known = %x modified = %x\n",
++ i, ts_data->known_ids, modified_ids);
++ input_mt_slot(ts_data->input_dev, i);
++ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, false);
++ modified_ids &= ~(1 << i);
++ }
++ }
++ ts_data->known_ids = modified_ids;
++ input_mt_report_pointer_emulation(ts_data->input_dev, true);
++ input_sync(ts_data->input_dev);
++}
++
++static void fts_retry_clear(struct tinker_ft5406_data *ts_data)
++{
++ if (ts_data->retry_count != 0)
++ ts_data->retry_count = 0;
++}
++
++static int fts_retry_wait(struct tinker_ft5406_data *ts_data)
++{
++ if (ts_data->retry_count < RETRY_COUNT) {
++ dev_info(&ts_data->client->dev,
++ "Wait and retry, count = %d\n", ts_data->retry_count);
++ ts_data->retry_count++;
++ msleep(1000);
++ return 1;
++ }
++ dev_err(&ts_data->client->dev, "Attach retry count\n");
++ return 0;
++}
++
++static void tinker_ft5406_work(struct work_struct *work)
++{
++ struct ts_event *event = &g_ts_data->event;
++ int ret = 0, td_status;
++
++ /* polling 60fps */
++ while (!g_ts_data->finish_work) {
++ td_status = fts_read_td_status(g_ts_data);
++ if (td_status < 0) {
++ ret = fts_retry_wait(g_ts_data);
++ if (ret == 0) {
++ dev_err(&g_ts_data->client->dev, "Stop touch polling\n");
++ break;
++ }
++ } else if (td_status < VALID_TD_STATUS_VAL + 1 &&
++ (td_status > 0 || g_ts_data->known_ids != 0)) {
++ fts_retry_clear(g_ts_data);
++ memset(event, -1, sizeof(struct ts_event));
++ event->touch_point = td_status;
++ ret = fts_read_touchdata(g_ts_data);
++ if (ret == 0)
++ fts_report_value(g_ts_data);
++ }
++ msleep_interruptible(17);
++ }
++}
++
++static int tinker_ft5406_open(struct input_dev *dev)
++{
++ schedule_work(&g_ts_data->ft5406_work);
++ return 0;
++}
++
++static void tinker_ft5406_close(struct input_dev *dev)
++{
++ g_ts_data->finish_work = true;
++ cancel_work_sync(&g_ts_data->ft5406_work);
++ g_ts_data->finish_work = false;
++}
++
++static int tinker_ft5406_probe(struct i2c_client *client)
++{
++ struct input_dev *input_dev;
++ int ret = 0;
++
++ dev_info(&client->dev, "Address = 0x%x\n", client->addr);
++
++ g_ts_data = kzalloc(sizeof(struct tinker_ft5406_data), GFP_KERNEL);
++ if (g_ts_data == NULL) {
++ dev_err(&client->dev, "No memory for device\n");
++ return -ENOMEM;
++ }
++
++ g_ts_data->client = client;
++ i2c_set_clientdata(client, g_ts_data);
++
++ g_ts_data->screen_width = 800;
++ g_ts_data->screen_height = 480;
++ g_ts_data->xy_reverse = 1;
++
++ dev_info(&client->dev, "width = %d, height = %d, reverse = %d\n",
++ g_ts_data->screen_width, g_ts_data->screen_height, g_ts_data->xy_reverse);
++
++ ret = fts_check_fw_ver(g_ts_data->client);
++ if (ret) {
++ dev_err(&client->dev, "Checking touch ic failed\n");
++ goto check_fw_err;
++ }
++
++ input_dev = input_allocate_device();
++ if (!input_dev) {
++ dev_err(&client->dev, "Failed to allocate input device\n");
++ goto input_allocate_failed;
++ }
++ input_dev->name = "fts_ts";
++ input_dev->id.bustype = BUS_I2C;
++ input_dev->dev.parent = &g_ts_data->client->dev;
++ input_dev->open = tinker_ft5406_open;
++ input_dev->close = tinker_ft5406_close;
++
++ g_ts_data->input_dev = input_dev;
++ input_set_drvdata(input_dev, g_ts_data);
++
++ __set_bit(EV_SYN, input_dev->evbit);
++ __set_bit(EV_KEY, input_dev->evbit);
++ __set_bit(EV_ABS, input_dev->evbit);
++ __set_bit(BTN_TOUCH, input_dev->keybit);
++
++ input_mt_init_slots(input_dev, MAX_TOUCH_POINTS, 0);
++ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, g_ts_data->screen_width, 0, 0);
++ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, g_ts_data->screen_height, 0, 0);
++
++ ret = input_register_device(input_dev);
++ if (ret) {
++ dev_err(&client->dev, "Input device registration failed\n");
++ goto input_register_failed;
++ }
++
++ INIT_WORK(&g_ts_data->ft5406_work, tinker_ft5406_work);
++
++ return 0;
++
++input_register_failed:
++ input_free_device(input_dev);
++input_allocate_failed:
++check_fw_err:
++ kfree(g_ts_data);
++ g_ts_data = NULL;
++ return ret;
++}
++
++static void tinker_ft5406_remove(struct i2c_client *client)
++{
++ cancel_work_sync(&g_ts_data->ft5406_work);
++ if (g_ts_data->input_dev) {
++ input_unregister_device(g_ts_data->input_dev);
++ input_free_device(g_ts_data->input_dev);
++ }
++ kfree(g_ts_data);
++ g_ts_data = NULL;
++}
++
++static const struct i2c_device_id tinker_ft5406_id[] = {
++ {"tinker_ft5406", 0},
++ {},
++};
++
++static struct i2c_driver tinker_ft5406_driver = {
++ .driver = {
++ .name = "tinker_ft5406",
++ },
++ .probe = tinker_ft5406_probe,
++ .remove = tinker_ft5406_remove,
++ .id_table = tinker_ft5406_id,
++};
++module_i2c_driver(tinker_ft5406_driver);
++
++MODULE_DESCRIPTION("TINKER BOARD FT5406 Touch driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch b/target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch
new file mode 100644
index 0000000000..69d7c7f494
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch
@@ -0,0 +1,246 @@
+From b477a1a53553336edcfeb83be1b35817928daed8 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 5 Jun 2023 14:46:16 +0800
+Subject: [PATCH 084/116] dt-binding: media: Add JH7110 Camera Subsystem.
+
+Add the bindings documentation for Starfive JH7110 Camera Subsystem
+which is used for handing image sensor data.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
+---
+ .../bindings/media/starfive,jh7110-camss.yaml | 228 ++++++++++++++++++
+ 1 file changed, 228 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
+@@ -0,0 +1,228 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/media/starfive,jh7110-camss.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Starfive SoC CAMSS ISP
++
++maintainers:
++ - Jack Zhu <jack.zhu@starfivetech.com>
++ - Changhuang Liang <changhuang.liang@starfivetech.com>
++
++description:
++ The Starfive CAMSS ISP is a Camera interface for Starfive JH7110 SoC. It
++ consists of a VIN controller (Video In Controller, a top-level control unit)
++ and an ISP.
++
++properties:
++ compatible:
++ const: starfive,jh7110-vin
++
++ reg:
++ maxItems: 8
++
++ reg-names:
++ items:
++ - const: csi2rx
++ - const: vclk
++ - const: vrst
++ - const: sctrl
++ - const: isp
++ - const: trst
++ - const: pmu
++ - const: syscrg
++
++ clocks:
++ maxItems: 16
++
++ clock-names:
++ items:
++ - const: clk_apb_func
++ - const: clk_pclk
++ - const: clk_sys_clk
++ - const: clk_wrapper_clk_c
++ - const: clk_dvp_inv
++ - const: clk_axiwr
++ - const: clk_mipi_rx0_pxl
++ - const: clk_pixel_clk_if0
++ - const: clk_pixel_clk_if1
++ - const: clk_pixel_clk_if2
++ - const: clk_pixel_clk_if3
++ - const: clk_m31dphy_cfgclk_in
++ - const: clk_m31dphy_refclk_in
++ - const: clk_m31dphy_txclkesc_lan0
++ - const: clk_ispcore_2x
++ - const: clk_isp_axi
++
++ resets:
++ maxItems: 14
++
++ reset-names:
++ items:
++ - const: rst_wrapper_p
++ - const: rst_wrapper_c
++ - const: rst_pclk
++ - const: rst_sys_clk
++ - const: rst_axird
++ - const: rst_axiwr
++ - const: rst_pixel_clk_if0
++ - const: rst_pixel_clk_if1
++ - const: rst_pixel_clk_if2
++ - const: rst_pixel_clk_if3
++ - const: rst_m31dphy_hw
++ - const: rst_m31dphy_b09_always_on
++ - const: rst_isp_top_n
++ - const: rst_isp_top_axi
++
++ power-domains:
++ items:
++ - description: JH7110 ISP Power Domain Switch Controller.
++
++ interrupts:
++ maxItems: 5
++
++ ports:
++ $ref: /schemas/graph.yaml#/properties/ports
++
++ properties:
++ port@0:
++ $ref: /schemas/graph.yaml#/$defs/port-base
++ unevaluatedProperties: false
++ description: Input port for receiving DVP data.
++
++ properties:
++ endpoint:
++ $ref: video-interfaces.yaml#
++ unevaluatedProperties: false
++
++ properties:
++ bus-type:
++ enum: [5, 6]
++
++ bus-width:
++ enum: [8, 10, 12]
++
++ data-shift:
++ enum: [0, 2]
++ default: 0
++
++ hsync-active:
++ enum: [0, 1]
++ default: 1
++
++ vsync-active:
++ enum: [0, 1]
++ default: 1
++
++ required:
++ - bus-type
++ - bus-width
++
++ port@1:
++ $ref: /schemas/graph.yaml#/properties/port
++ description: Input port for receiving CSI data.
++
++ required:
++ - port@0
++ - port@1
++
++required:
++ - compatible
++ - reg
++ - reg-names
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - power-domains
++ - interrupts
++ - ports
++
++additionalProperties: false
++
++examples:
++ - |
++ vin_sysctl: vin_sysctl@19800000 {
++ compatible = "starfive,jh7110-vin";
++ reg = <0x0 0x19800000 0x0 0x10000>,
++ <0x0 0x19810000 0x0 0x10000>,
++ <0x0 0x19820000 0x0 0x10000>,
++ <0x0 0x19840000 0x0 0x10000>,
++ <0x0 0x19870000 0x0 0x30000>,
++ <0x0 0x11840000 0x0 0x10000>,
++ <0x0 0x17030000 0x0 0x10000>,
++ <0x0 0x13020000 0x0 0x10000>;
++ reg-names = "csi2rx", "vclk", "vrst", "sctrl",
++ "isp", "trst", "pmu", "syscrg";
++ clocks = <&clkisp JH7110_DOM4_APB_FUNC>,
++ <&clkisp JH7110_U0_VIN_PCLK>,
++ <&clkisp JH7110_U0_VIN_SYS_CLK>,
++ <&clkisp JH7110_U0_ISPV2_TOP_WRAPPER_CLK_C>,
++ <&clkisp JH7110_DVP_INV>,
++ <&clkisp JH7110_U0_VIN_CLK_P_AXIWR>,
++ <&clkisp JH7110_MIPI_RX0_PXL>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF0>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF1>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF2>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF3>,
++ <&clkisp JH7110_U0_M31DPHY_CFGCLK_IN>,
++ <&clkisp JH7110_U0_M31DPHY_REFCLK_IN>,
++ <&clkisp JH7110_U0_M31DPHY_TXCLKESC_LAN0>,
++ <&clkgen JH7110_ISP_TOP_CLK_ISPCORE_2X>,
++ <&clkgen JH7110_ISP_TOP_CLK_ISP_AXI>;
++ clock-names = "clk_apb_func", "clk_pclk", "clk_sys_clk",
++ "clk_wrapper_clk_c", "clk_dvp_inv", "clk_axiwr",
++ "clk_mipi_rx0_pxl", "clk_pixel_clk_if0",
++ "clk_pixel_clk_if1", "clk_pixel_clk_if2",
++ "clk_pixel_clk_if3", "clk_m31dphy_cfgclk_in",
++ "clk_m31dphy_refclk_in", "clk_m31dphy_txclkesc_lan0",
++ "clk_ispcore_2x", "clk_isp_axi";
++ resets = <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_P>,
++ <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_C>,
++ <&rstgen RSTN_U0_VIN_N_PCLK>,
++ <&rstgen RSTN_U0_VIN_N_SYS_CLK>,
++ <&rstgen RSTN_U0_VIN_P_AXIRD>,
++ <&rstgen RSTN_U0_VIN_P_AXIWR>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF0>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF1>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF2>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF3>,
++ <&rstgen RSTN_U0_M31DPHY_HW>,
++ <&rstgen RSTN_U0_M31DPHY_B09_ALWAYS_ON>,
++ <&rstgen RSTN_U0_DOM_ISP_TOP_N>,
++ <&rstgen RSTN_U0_DOM_ISP_TOP_AXI>;
++ reset-names = "rst_wrapper_p", "rst_wrapper_c", "rst_pclk",
++ "rst_sys_clk", "rst_axird", "rst_axiwr", "rst_pixel_clk_if0",
++ "rst_pixel_clk_if1", "rst_pixel_clk_if2", "rst_pixel_clk_if3",
++ "rst_m31dphy_hw", "rst_m31dphy_b09_always_on",
++ "rst_isp_top_n", "rst_isp_top_axi";
++ starfive,aon-syscon = <&aon_syscon 0x00>;
++ power-domains = <&pwrc JH7110_PD_ISP>;
++ /* irq nr: vin, isp, isp_csi, isp_scd, isp_csiline */
++ interrupts = <92>, <87>, <88>, <89>, <90>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ vin_from_sc2235: endpoint {
++ remote-endpoint = <&sc2235_to_vin>;
++ bus-type = <5>;
++ bus-width = <8>;
++ data-shift = <2>;
++ hsync-active = <1>;
++ vsync-active = <0>;
++ pclk-sample = <1>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ vin_from_csi2rx: endpoint {
++ remote-endpoint = <&csi2rx_to_vin>;
++ };
++ };
++ };
++ };
diff --git a/target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch b/target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch
new file mode 100644
index 0000000000..b5d5f73f9d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch
@@ -0,0 +1,24014 @@
+From 908b10ebc95eb29caae8c4737b23a29af5c6298f Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 5 Jun 2023 13:54:16 +0800
+Subject: [PATCH 085/116] media: starfive: Add vin driver support
+
+Add vin driver support.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/media/platform/Kconfig | 1 +
+ drivers/media/platform/Makefile | 1 +
+ drivers/media/platform/starfive/Kconfig | 56 +
+ drivers/media/platform/starfive/Makefile | 24 +
+ .../platform/starfive/v4l2_driver/Readme.txt | 11 +
+ .../starfive/v4l2_driver/imx219_mipi.c | 1583 ++++++++
+ .../starfive/v4l2_driver/ov13850_mipi.c | 1921 ++++++++++
+ .../starfive/v4l2_driver/ov4689_mipi.c | 2975 +++++++++++++++
+ .../platform/starfive/v4l2_driver/ov5640.c | 3227 +++++++++++++++++
+ .../platform/starfive/v4l2_driver/sc2235.c | 1914 ++++++++++
+ .../starfive/v4l2_driver/stf_common.h | 185 +
+ .../platform/starfive/v4l2_driver/stf_csi.c | 465 +++
+ .../platform/starfive/v4l2_driver/stf_csi.h | 61 +
+ .../starfive/v4l2_driver/stf_csi_hw_ops.c | 310 ++
+ .../starfive/v4l2_driver/stf_csiphy.c | 357 ++
+ .../starfive/v4l2_driver/stf_csiphy.h | 188 +
+ .../starfive/v4l2_driver/stf_csiphy_hw_ops.c | 335 ++
+ .../starfive/v4l2_driver/stf_dmabuf.c | 123 +
+ .../starfive/v4l2_driver/stf_dmabuf.h | 12 +
+ .../platform/starfive/v4l2_driver/stf_dvp.c | 385 ++
+ .../platform/starfive/v4l2_driver/stf_dvp.h | 67 +
+ .../starfive/v4l2_driver/stf_dvp_hw_ops.c | 187 +
+ .../platform/starfive/v4l2_driver/stf_event.c | 36 +
+ .../platform/starfive/v4l2_driver/stf_isp.c | 1521 ++++++++
+ .../platform/starfive/v4l2_driver/stf_isp.h | 222 ++
+ .../starfive/v4l2_driver/stf_isp_hw_ops.c | 1550 ++++++++
+ .../starfive/v4l2_driver/stf_isp_ioctl.h | 133 +
+ .../platform/starfive/v4l2_driver/stf_video.c | 1552 ++++++++
+ .../platform/starfive/v4l2_driver/stf_video.h | 83 +
+ .../platform/starfive/v4l2_driver/stf_vin.c | 1515 ++++++++
+ .../platform/starfive/v4l2_driver/stf_vin.h | 182 +
+ .../starfive/v4l2_driver/stf_vin_hw_ops.c | 433 +++
+ .../platform/starfive/v4l2_driver/stfcamss.c | 1369 +++++++
+ .../platform/starfive/v4l2_driver/stfcamss.h | 117 +
+ include/uapi/linux/jh7110-isp.h | 253 ++
+ include/uapi/linux/v4l2-controls.h | 6 +
+ include/video/stf-vin.h | 443 +++
+ 37 files changed, 23803 insertions(+)
+ create mode 100644 drivers/media/platform/starfive/Kconfig
+ create mode 100644 drivers/media/platform/starfive/Makefile
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/Readme.txt
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/imx219_mipi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/ov13850_mipi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/ov4689_mipi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/ov5640.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/sc2235.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_common.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csi.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csiphy.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csiphy_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dvp.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dvp.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dvp_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_event.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp_ioctl.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_video.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_video.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_vin.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stfcamss.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stfcamss.h
+ create mode 100644 include/uapi/linux/jh7110-isp.h
+ create mode 100644 include/video/stf-vin.h
+
+--- a/drivers/media/platform/Kconfig
++++ b/drivers/media/platform/Kconfig
+@@ -80,6 +80,7 @@ source "drivers/media/platform/renesas/K
+ source "drivers/media/platform/rockchip/Kconfig"
+ source "drivers/media/platform/samsung/Kconfig"
+ source "drivers/media/platform/st/Kconfig"
++source "drivers/media/platform/starfive/Kconfig"
+ source "drivers/media/platform/sunxi/Kconfig"
+ source "drivers/media/platform/ti/Kconfig"
+ source "drivers/media/platform/verisilicon/Kconfig"
+--- a/drivers/media/platform/Makefile
++++ b/drivers/media/platform/Makefile
+@@ -23,6 +23,7 @@ obj-y += renesas/
+ obj-y += rockchip/
+ obj-y += samsung/
+ obj-y += st/
++obj-y += starfive/
+ obj-y += sunxi/
+ obj-y += ti/
+ obj-y += verisilicon/
+--- /dev/null
++++ b/drivers/media/platform/starfive/Kconfig
+@@ -0,0 +1,56 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++comment "Starfive media platform drivers"
++
++config VIN_SENSOR_OV5640
++ tristate "VIN SENSOR support OV5640"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor OV5640
++
++config VIN_SENSOR_SC2235
++ tristate "VIN SENSOR support SC2235"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor SC2235
++
++config VIN_SENSOR_OV4689
++ tristate "VIN SENSOR support OV4689"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++
++ help
++ Say Y here if you want to have support for VIN sensor OV4689
++
++config VIN_SENSOR_OV13850
++ bool "VIN SENSOR support OV13850"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor OV13850
++
++config VIN_SENSOR_IMX219
++ tristate "VIN SENSOR support IMX219"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor IMX219
++
++config VIDEO_STF_VIN
++ tristate "starfive VIC video in support"
++ depends on V4L_PLATFORM_DRIVERS
++ depends on VIDEO_DEV
++ select MEDIA_CONTROLLER
++ select VIDEOBUF2_DMA_CONTIG
++ select VIDEO_V4L2_SUBDEV_API
++ select V4L2_FWNODE
++ help
++ To compile this driver as a module, choose M here: the module
++ will be called stf-vin.
+--- /dev/null
++++ b/drivers/media/platform/starfive/Makefile
+@@ -0,0 +1,24 @@
++# SPDX-License-Identifier: GPL-2.0
++
++obj-$(CONFIG_VIN_SENSOR_OV5640) += v4l2_driver/ov5640.o
++obj-$(CONFIG_VIN_SENSOR_SC2235) += v4l2_driver/sc2235.o
++obj-$(CONFIG_VIN_SENSOR_OV4689) += v4l2_driver/ov4689_mipi.o
++obj-$(CONFIG_VIN_SENSOR_OV13850) += v4l2_driver/ov13850_mipi.o
++obj-$(CONFIG_VIN_SENSOR_IMX219) += v4l2_driver/imx219_mipi.o
++
++starfivecamss-objs += v4l2_driver/stfcamss.o \
++ v4l2_driver/stf_event.o \
++ v4l2_driver/stf_dvp.o \
++ v4l2_driver/stf_csi.o \
++ v4l2_driver/stf_csiphy.o \
++ v4l2_driver/stf_isp.o \
++ v4l2_driver/stf_video.o \
++ v4l2_driver/stf_vin.o \
++ v4l2_driver/stf_vin_hw_ops.o \
++ v4l2_driver/stf_csi_hw_ops.o \
++ v4l2_driver/stf_csiphy_hw_ops.o \
++ v4l2_driver/stf_isp_hw_ops.o \
++ v4l2_driver/stf_dvp_hw_ops.o \
++ v4l2_driver/stf_dmabuf.o
++
++obj-$(CONFIG_VIDEO_STF_VIN) += starfivecamss.o \
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/Readme.txt
+@@ -0,0 +1,11 @@
++
++/dev/video0: Output the camera data directly.
++/dev/video1: Output the data of the camera converted by isp.
++
++ensure linux/arch/riscv/configs/starfive_jh7110_defconfig:
++CONFIG_VIDEO_STF_VIN=y
++CONFIG_VIN_SENSOR_SC2235=y
++CONFIG_VIN_SENSOR_OV4689=y
++
++Only support the lane0/lane5 of dphy as clock lane, lane1/lane2/lane3/lane4
++as data lane.
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/imx219_mipi.c
+@@ -0,0 +1,1583 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * A V4L2 driver for Sony IMX219 cameras.
++ * Copyright (C) 2019, Raspberry Pi (Trading) Ltd
++ *
++ * Based on Sony imx258 camera driver
++ * Copyright (C) 2018 Intel Corporation
++ *
++ * DT / fwnode changes, and regulator / GPIO control taken from imx214 driver
++ * Copyright 2018 Qtechnology A/S
++ *
++ * Flip handling taken from the Sony IMX319 driver.
++ * Copyright (C) 2018 Intel Corporation
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-mediabus.h>
++#include <asm/unaligned.h>
++
++#define IMX219_REG_VALUE_08BIT 1
++#define IMX219_REG_VALUE_16BIT 2
++
++#define IMX219_REG_MODE_SELECT 0x0100
++#define IMX219_MODE_STANDBY 0x00
++#define IMX219_MODE_STREAMING 0x01
++
++/* Chip ID */
++#define IMX219_REG_CHIP_ID 0x0000
++#define IMX219_CHIP_ID 0x0219
++
++/* External clock frequency is 24.0M */
++#define IMX219_XCLK_FREQ 24000000
++
++/* Pixel rate is fixed at 182.4M for all the modes */
++#define IMX219_PIXEL_RATE 182400000
++
++#define IMX219_DEFAULT_LINK_FREQ 456000000
++
++/* V_TIMING internal */
++#define IMX219_REG_VTS 0x0160
++#define IMX219_VTS_15FPS 0x0dc6
++#define IMX219_VTS_30FPS_1080P 0x06e3
++#define IMX219_VTS_30FPS_BINNED 0x06e3
++#define IMX219_VTS_30FPS_1280x720 0x06e3
++#define IMX219_VTS_30FPS_640x480 0x06e3
++#define IMX219_VTS_MAX 0xffff
++
++#define IMX219_VBLANK_MIN 4
++
++/*Frame Length Line*/
++#define IMX219_FLL_MIN 0x08a6
++#define IMX219_FLL_MAX 0xffff
++#define IMX219_FLL_STEP 1
++#define IMX219_FLL_DEFAULT 0x0c98
++
++/* HBLANK control - read only */
++#define IMX219_PPL_DEFAULT 3448
++
++/* Exposure control */
++#define IMX219_REG_EXPOSURE 0x015a
++#define IMX219_EXPOSURE_MIN 4
++#define IMX219_EXPOSURE_STEP 1
++#define IMX219_EXPOSURE_DEFAULT 0x640
++#define IMX219_EXPOSURE_MAX 65535
++
++/* Analog gain control */
++#define IMX219_REG_ANALOG_GAIN 0x0157
++#define IMX219_ANA_GAIN_MIN 0
++#define IMX219_ANA_GAIN_MAX 232
++#define IMX219_ANA_GAIN_STEP 1
++#define IMX219_ANA_GAIN_DEFAULT 0xd0
++
++/* Digital gain control */
++#define IMX219_REG_DIGITAL_GAIN 0x0158
++#define IMX219_DGTL_GAIN_MIN 0x0100
++#define IMX219_DGTL_GAIN_MAX 0x0fff
++#define IMX219_DGTL_GAIN_DEFAULT 0x0100
++#define IMX219_DGTL_GAIN_STEP 1
++
++#define IMX219_REG_ORIENTATION 0x0172
++
++/* Test Pattern Control */
++#define IMX219_REG_TEST_PATTERN 0x0600
++#define IMX219_TEST_PATTERN_DISABLE 0
++#define IMX219_TEST_PATTERN_SOLID_COLOR 1
++#define IMX219_TEST_PATTERN_COLOR_BARS 2
++#define IMX219_TEST_PATTERN_GREY_COLOR 3
++#define IMX219_TEST_PATTERN_PN9 4
++
++/* Test pattern colour components */
++#define IMX219_REG_TESTP_RED 0x0602
++#define IMX219_REG_TESTP_GREENR 0x0604
++#define IMX219_REG_TESTP_BLUE 0x0606
++#define IMX219_REG_TESTP_GREENB 0x0608
++#define IMX219_TESTP_COLOUR_MIN 0
++#define IMX219_TESTP_COLOUR_MAX 0x03ff
++#define IMX219_TESTP_COLOUR_STEP 1
++#define IMX219_TESTP_RED_DEFAULT IMX219_TESTP_COLOUR_MAX
++#define IMX219_TESTP_GREENR_DEFAULT 0
++#define IMX219_TESTP_BLUE_DEFAULT 0
++#define IMX219_TESTP_GREENB_DEFAULT 0
++
++/* IMX219 native and active pixel array size. */
++#define IMX219_NATIVE_WIDTH 3296U
++#define IMX219_NATIVE_HEIGHT 2480U
++#define IMX219_PIXEL_ARRAY_LEFT 8U
++#define IMX219_PIXEL_ARRAY_TOP 8U
++#define IMX219_PIXEL_ARRAY_WIDTH 3280U
++#define IMX219_PIXEL_ARRAY_HEIGHT 2464U
++
++struct imx219_reg {
++ u16 address;
++ u8 val;
++};
++
++struct imx219_reg_list {
++ unsigned int num_of_regs;
++ const struct imx219_reg *regs;
++};
++
++/* Mode : resolution and related config&values */
++struct imx219_mode {
++ /* Frame width */
++ unsigned int width;
++ /* Frame height */
++ unsigned int height;
++
++ unsigned int fps;
++
++ /* Analog crop rectangle. */
++ struct v4l2_rect crop;
++
++ /* V-timing */
++ unsigned int vts_def;
++
++ /* Default register values */
++ struct imx219_reg_list reg_list;
++};
++
++/*
++ * Register sets lifted off the i2C interface from the Raspberry Pi firmware
++ * driver.
++ * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
++ */
++
++static const struct imx219_reg mode_1920_1080_regs[] = {
++ {0x0100, 0x00},
++ {0x30eb, 0x05},
++ {0x30eb, 0x0c},
++ {0x300a, 0xff},
++ {0x300b, 0xff},
++ {0x30eb, 0x05},
++ {0x30eb, 0x09},
++ {0x0114, 0x01},
++ {0x0128, 0x00},
++ {0x012a, 0x18},
++ {0x012b, 0x00},
++ {0x0162, 0x0d},
++ {0x0163, 0x78},
++ {0x0164, 0x02},
++ {0x0165, 0xa8},
++ {0x0166, 0x0a},
++ {0x0167, 0x27},
++ {0x0168, 0x02},
++ {0x0169, 0xb4},
++ {0x016a, 0x06},
++ {0x016b, 0xeb},
++ {0x016c, 0x07},
++ {0x016d, 0x80},
++ {0x016e, 0x04},
++ {0x016f, 0x38},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x00},
++ {0x0175, 0x00},
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x030b, 0x01},
++ {0x030c, 0x00},
++ {0x030d, 0x72},
++ {0x0624, 0x07},
++ {0x0625, 0x80},
++ {0x0626, 0x04},
++ {0x0627, 0x38},
++ {0x455e, 0x00},
++ {0x471e, 0x4b},
++ {0x4767, 0x0f},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47b4, 0x14},
++ {0x4713, 0x30},
++ {0x478b, 0x10},
++ {0x478f, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0e},
++ {0x479b, 0x0e},
++};
++
++static const struct imx219_reg mode_1280_720_regs[] = {
++ {0x0100, 0x00},
++ {0x30eb, 0x05},
++ {0x30eb, 0x0c},
++ {0x300a, 0xff},
++ {0x300b, 0xff},
++ {0x30eb, 0x05},
++ {0x30eb, 0x09},
++ {0x0114, 0x01},
++ {0x0128, 0x00},
++ {0x012a, 0x18},
++ {0x012b, 0x00},
++ {0x0162, 0x0d},
++ {0x0163, 0x78},
++ {0x0164, 0x01},
++ {0x0165, 0x68},
++ {0x0166, 0x0b},
++ {0x0167, 0x67},
++ {0x0168, 0x02},
++ {0x0169, 0x00},
++ {0x016a, 0x07},
++ {0x016b, 0x9f},
++ {0x016c, 0x05},
++ {0x016d, 0x00},
++ {0x016e, 0x02},
++ {0x016f, 0xd0},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x01},
++ {0x0175, 0x01},
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x030b, 0x01},
++ {0x030c, 0x00},
++ {0x030d, 0x72},
++ {0x0624, 0x06},
++ {0x0625, 0x68},
++ {0x0626, 0x04},
++ {0x0627, 0xd0},
++ {0x455e, 0x00},
++ {0x471e, 0x4b},
++ {0x4767, 0x0f},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47b4, 0x14},
++ {0x4713, 0x30},
++ {0x478b, 0x10},
++ {0x478f, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0e},
++ {0x479b, 0x0e},
++};
++
++static const struct imx219_reg mode_640_480_regs[] = {
++ {0x0100, 0x00},
++ {0x30eb, 0x05},
++ {0x30eb, 0x0c},
++ {0x300a, 0xff},
++ {0x300b, 0xff},
++ {0x30eb, 0x05},
++ {0x30eb, 0x09},
++ {0x0114, 0x01},
++ {0x0128, 0x00},
++ {0x012a, 0x18},
++ {0x012b, 0x00},
++ {0x0162, 0x0d},
++ {0x0163, 0x78},
++ {0x0164, 0x03},
++ {0x0165, 0xe8},
++ {0x0166, 0x08},
++ {0x0167, 0xe7},
++ {0x0168, 0x02},
++ {0x0169, 0xf0},
++ {0x016a, 0x06},
++ {0x016b, 0xaf},
++ {0x016c, 0x02},
++ {0x016d, 0x80},
++ {0x016e, 0x01},
++ {0x016f, 0xe0},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x03},
++ {0x0175, 0x03},
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x030b, 0x01},
++ {0x030c, 0x00},
++ {0x030d, 0x72},
++ {0x0624, 0x06},
++ {0x0625, 0x68},
++ {0x0626, 0x04},
++ {0x0627, 0xd0},
++ {0x455e, 0x00},
++ {0x471e, 0x4b},
++ {0x4767, 0x0f},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47b4, 0x14},
++ {0x4713, 0x30},
++ {0x478b, 0x10},
++ {0x478f, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0e},
++ {0x479b, 0x0e},
++};
++
++static const struct imx219_reg raw8_framefmt_regs[] = {
++ {0x018c, 0x08},
++ {0x018d, 0x08},
++ {0x0309, 0x08},
++};
++
++static const struct imx219_reg raw10_framefmt_regs[] = {
++ {0x018c, 0x0a},
++ {0x018d, 0x0a},
++ {0x0309, 0x0a},
++};
++
++static const s64 imx219_link_freq_menu[] = {
++ IMX219_DEFAULT_LINK_FREQ,
++};
++
++static const char * const imx219_test_pattern_menu[] = {
++ "Disabled",
++ "Color Bars",
++ "Solid Color",
++ "Grey Color Bars",
++ "PN9"
++};
++
++static const int imx219_test_pattern_val[] = {
++ IMX219_TEST_PATTERN_DISABLE,
++ IMX219_TEST_PATTERN_COLOR_BARS,
++ IMX219_TEST_PATTERN_SOLID_COLOR,
++ IMX219_TEST_PATTERN_GREY_COLOR,
++ IMX219_TEST_PATTERN_PN9,
++};
++
++/* regulator supplies */
++static const char * const imx219_supply_name[] = {
++ /* Supplies can be enabled in any order */
++ "VANA", /* Analog (2.8V) supply */
++ "VDIG", /* Digital Core (1.8V) supply */
++ "VDDL", /* IF (1.2V) supply */
++};
++
++#define IMX219_NUM_SUPPLIES ARRAY_SIZE(imx219_supply_name)
++
++/*
++ * The supported formats.
++ * This table MUST contain 4 entries per format, to cover the various flip
++ * combinations in the order
++ * - no flip
++ * - h flip
++ * - v flip
++ * - h&v flips
++ */
++static const u32 codes[] = {
++ MEDIA_BUS_FMT_SRGGB10_1X10,
++ MEDIA_BUS_FMT_SGRBG10_1X10,
++ MEDIA_BUS_FMT_SGBRG10_1X10,
++ MEDIA_BUS_FMT_SBGGR10_1X10,
++
++ MEDIA_BUS_FMT_SRGGB8_1X8,
++ MEDIA_BUS_FMT_SGRBG8_1X8,
++ MEDIA_BUS_FMT_SGBRG8_1X8,
++ MEDIA_BUS_FMT_SBGGR8_1X8,
++};
++
++/*
++ * Initialisation delay between XCLR low->high and the moment when the sensor
++ * can start capture (i.e. can leave software stanby) must be not less than:
++ * t4 + max(t5, t6 + <time to initialize the sensor register over I2C>)
++ * where
++ * t4 is fixed, and is max 200uS,
++ * t5 is fixed, and is 6000uS,
++ * t6 depends on the sensor external clock, and is max 32000 clock periods.
++ * As per sensor datasheet, the external clock must be from 6MHz to 27MHz.
++ * So for any acceptable external clock t6 is always within the range of
++ * 1185 to 5333 uS, and is always less than t5.
++ * For this reason this is always safe to wait (t4 + t5) = 6200 uS, then
++ * initialize the sensor over I2C, and then exit the software standby.
++ *
++ * This start-up time can be optimized a bit more, if we start the writes
++ * over I2C after (t4+t6), but before (t4+t5) expires. But then sensor
++ * initialization over I2C may complete before (t4+t5) expires, and we must
++ * ensure that capture is not started before (t4+t5).
++ *
++ * This delay doesn't account for the power supply startup time. If needed,
++ * this should be taken care of via the regulator framework. E.g. in the
++ * case of DT for regulator-fixed one should define the startup-delay-us
++ * property.
++ */
++#define IMX219_XCLR_MIN_DELAY_US 6200
++#define IMX219_XCLR_DELAY_RANGE_US 1000
++
++/* Mode configs */
++static const struct imx219_mode supported_modes[] = {
++ {
++ /* 1080P 30fps cropped */
++ .width = 1920,
++ .height = 1080,
++ .fps = 30,
++ .crop = {
++ .left = 688,
++ .top = 700,
++ .width = 1920,
++ .height = 1080
++ },
++ .vts_def = IMX219_VTS_30FPS_1080P,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
++ .regs = mode_1920_1080_regs,
++ },
++ },
++ {
++ /* 1280x720 30fps mode */
++ .width = 1280,
++ .height = 720,
++ .fps = 30,
++ .crop = {
++ .left = 360,
++ .top = 512,
++ .width = 2560,
++ .height = 1440
++ },
++ .vts_def = IMX219_VTS_30FPS_1280x720,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_1280_720_regs),
++ .regs = mode_1280_720_regs,
++ },
++ },
++ {
++ /* 640x480 30fps mode */
++ .width = 640,
++ .height = 480,
++ .fps = 30,
++ .crop = {
++ .left = 1008,
++ .top = 760,
++ .width = 1280,
++ .height = 960
++ },
++ .vts_def = IMX219_VTS_30FPS_640x480,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_640_480_regs),
++ .regs = mode_640_480_regs,
++ },
++ },
++};
++
++struct imx219 {
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ //struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++
++ struct v4l2_mbus_framefmt fmt;
++
++ struct clk *xclk; /* system clock to IMX219 */
++ u32 xclk_freq;
++
++ struct gpio_desc *reset_gpio;
++ struct regulator_bulk_data supplies[IMX219_NUM_SUPPLIES];
++
++ struct v4l2_ctrl_handler ctrl_handler;
++ /* V4L2 Controls */
++ struct v4l2_ctrl *pixel_rate;
++ struct v4l2_ctrl *link_freq;
++ struct v4l2_ctrl *exposure;
++ struct v4l2_ctrl *vflip;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *hblank;
++
++ /* Current mode */
++ const struct imx219_mode *mode;
++ struct v4l2_fract frame_interval;
++
++ /*
++ * Mutex for serialized access:
++ * Protect sensor module set pad format and start/stop streaming safely.
++ */
++ struct mutex mutex;
++
++ /* Streaming on/off */
++ int streaming;
++};
++
++static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd)
++{
++ return container_of(_sd, struct imx219, sd);
++}
++
++/* Read registers up to 2 at a time */
++static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ struct i2c_msg msgs[2];
++ u8 addr_buf[2] = { reg >> 8, reg & 0xff };
++ u8 data_buf[4] = { 0, };
++ int ret;
++
++ if (len > 4)
++ return -EINVAL;
++
++ /* Write register address */
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = ARRAY_SIZE(addr_buf);
++ msgs[0].buf = addr_buf;
++
++ /* Read data from register */
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = len;
++ msgs[1].buf = &data_buf[4 - len];
++
++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
++ if (ret != ARRAY_SIZE(msgs))
++ return -EIO;
++
++ *val = get_unaligned_be32(data_buf);
++
++ return 0;
++}
++
++/* Write registers up to 2 at a time */
++static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ u8 buf[6];
++
++ if (len > 4)
++ return -EINVAL;
++
++ put_unaligned_be16(reg, buf);
++ put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
++ if (i2c_master_send(client, buf, len + 2) != len + 2)
++ return -EIO;
++
++ return 0;
++}
++
++/* Write a list of registers */
++static int imx219_write_regs(struct imx219 *imx219,
++ const struct imx219_reg *regs, u32 len)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ unsigned int i;
++ int ret;
++
++ for (i = 0; i < len; i++) {
++ ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val);
++ if (ret) {
++ dev_err_ratelimited(&client->dev,
++ "Failed to write reg 0x%4.4x. error = %d\n",
++ regs[i].address, ret);
++
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++/* Get bayer order based on flip setting. */
++static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
++{
++ unsigned int i;
++
++ lockdep_assert_held(&imx219->mutex);
++
++ for (i = 0; i < ARRAY_SIZE(codes); i++)
++ if (codes[i] == code)
++ break;
++
++ if (i >= ARRAY_SIZE(codes))
++ i = 0;
++
++ i = (i & ~3) | (imx219->vflip->val ? 2 : 0) |
++ (imx219->hflip->val ? 1 : 0);
++
++ return codes[i];
++}
++
++static void imx219_set_default_format(struct imx219 *imx219)
++{
++ struct v4l2_mbus_framefmt *fmt;
++
++ fmt = &imx219->fmt;
++ fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace, fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = supported_modes[0].width;
++ fmt->height = supported_modes[0].height;
++ fmt->field = V4L2_FIELD_NONE;
++}
++
++static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(sd, fh->state, 0);
++ struct v4l2_rect *try_crop;
++
++ mutex_lock(&imx219->mutex);
++
++ /* Initialize try_fmt */
++ try_fmt->width = supported_modes[0].width;
++ try_fmt->height = supported_modes[0].height;
++ try_fmt->code = imx219_get_format_code(imx219, MEDIA_BUS_FMT_SRGGB10_1X10);
++ try_fmt->field = V4L2_FIELD_NONE;
++
++ /* Initialize try_crop rectangle. */
++ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
++ try_crop->top = IMX219_PIXEL_ARRAY_TOP;
++ try_crop->left = IMX219_PIXEL_ARRAY_LEFT;
++ try_crop->width = IMX219_PIXEL_ARRAY_WIDTH;
++ try_crop->height = IMX219_PIXEL_ARRAY_HEIGHT;
++
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct imx219 *imx219 =
++ container_of(ctrl->handler, struct imx219, ctrl_handler);
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ int ret;
++
++ if (ctrl->id == V4L2_CID_VBLANK) {
++ int exposure_max, exposure_def;
++
++ /* Update max exposure while meeting expected vblanking */
++ exposure_max = imx219->mode->height + ctrl->val - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ __v4l2_ctrl_modify_range(imx219->exposure, imx219->exposure->minimum,
++ exposure_max, imx219->exposure->step, exposure_def);
++ }
++
++ /*
++ * Applying V4L2 control value only happens
++ * when power is up for streaming
++ */
++ if (pm_runtime_get_if_in_use(&client->dev) == 0)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN,
++ IMX219_REG_VALUE_08BIT, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_DIGITAL_GAIN:
++ ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN,
++ IMX219_REG_VALUE_16BIT, imx219_test_pattern_val[ctrl->val]);
++ break;
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1,
++ imx219->hflip->val | imx219->vflip->val << 1);
++ break;
++ case V4L2_CID_VBLANK:
++ ret = imx219_write_reg(imx219, IMX219_REG_VTS, IMX219_REG_VALUE_16BIT,
++ imx219->mode->height + ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_RED:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENR:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_BLUE:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENB:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ default:
++ dev_info(&client->dev,
++ "ctrl(id:0x%x,val:0x%x) is not handled\n", ctrl->id, ctrl->val);
++ ret = -EINVAL;
++ break;
++ }
++
++ pm_runtime_put(&client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops imx219_ctrl_ops = {
++ .s_ctrl = imx219_set_ctrl,
++};
++
++static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++
++ if (code->index >= (ARRAY_SIZE(codes) / 4))
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++ code->code = imx219_get_format_code(imx219, codes[code->index * 4]);
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ u32 code;
++
++ if (fse->index >= ARRAY_SIZE(supported_modes))
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++ code = imx219_get_format_code(imx219, fse->code);
++ mutex_unlock(&imx219->mutex);
++ if (fse->code != code)
++ return -EINVAL;
++
++ fse->min_width = supported_modes[fse->index].width;
++ fse->max_width = fse->min_width;
++ fse->min_height = supported_modes[fse->index].height;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int imx219_try_frame_interval(struct imx219 *imx219,
++ struct v4l2_fract *fi,
++ u32 w, u32 h)
++{
++ const struct imx219_mode *mode;
++
++ mode = v4l2_find_nearest_size(supported_modes, ARRAY_SIZE(supported_modes),
++ width, height, w, h);
++ if (!mode || (mode->width != w || mode->height != h))
++ return -EINVAL;
++
++ fi->numerator = 1;
++ fi->denominator = mode->fps;
++
++ return mode->fps;
++}
++
++static int imx219_enum_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ struct v4l2_fract tpf;
++ u32 code;
++ int ret;
++
++ if (fie->index >= ARRAY_SIZE(supported_modes))
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++ code = imx219_get_format_code(imx219, fie->code);
++ if (fie->code != code) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ ret = imx219_try_frame_interval(imx219, &tpf,
++ fie->width, fie->height);
++ if (ret < 0) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ mutex_unlock(&imx219->mutex);
++ fie->interval = tpf;
++
++ return 0;
++
++out:
++ mutex_unlock(&imx219->mutex);
++ return ret;
++}
++
++static int imx219_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++
++ mutex_lock(&imx219->mutex);
++ fi->interval = imx219->frame_interval;
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ const struct imx219_mode *mode = imx219->mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++
++ if (imx219->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ frame_rate = imx219_try_frame_interval(imx219, &fi->interval,
++ mode->width, mode->height);
++ if (frame_rate < 0) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ imx219->frame_interval = fi->interval;
++
++out:
++ mutex_unlock(&imx219->mutex);
++ return ret;
++}
++
++static void imx219_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
++{
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace, fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++}
++
++static void imx219_update_pad_format(struct imx219 *imx219,
++ const struct imx219_mode *mode,
++ struct v4l2_subdev_format *fmt)
++{
++ fmt->format.width = mode->width;
++ fmt->format.height = mode->height;
++ fmt->format.field = V4L2_FIELD_NONE;
++ imx219_reset_colorspace(&fmt->format);
++}
++
++static int __imx219_get_pad_format(struct imx219 *imx219,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(&imx219->sd, state, fmt->pad);
++ /* update the code which could change due to vflip or hflip: */
++ try_fmt->code = imx219_get_format_code(imx219, try_fmt->code);
++ fmt->format = *try_fmt;
++ } else {
++ imx219_update_pad_format(imx219, imx219->mode, fmt);
++ fmt->format.code = imx219_get_format_code(imx219, imx219->fmt.code);
++ }
++
++ return 0;
++}
++
++static int imx219_get_pad_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ int ret;
++
++ mutex_lock(&imx219->mutex);
++ ret = __imx219_get_pad_format(imx219, state, fmt);
++ mutex_unlock(&imx219->mutex);
++
++ return ret;
++}
++
++static int imx219_set_pad_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ const struct imx219_mode *mode;
++ struct v4l2_mbus_framefmt *framefmt;
++ int exposure_max, exposure_def, hblank;
++ unsigned int i;
++
++ mutex_lock(&imx219->mutex);
++
++ for (i = 0; i < ARRAY_SIZE(codes); i++)
++ if (codes[i] == fmt->format.code)
++ break;
++ if (i >= ARRAY_SIZE(codes))
++ i = 0;
++
++ /* Bayer order varies with flips */
++ fmt->format.code = imx219_get_format_code(imx219, codes[i]);
++
++ mode = v4l2_find_nearest_size(supported_modes, ARRAY_SIZE(supported_modes),
++ width, height, fmt->format.width, fmt->format.height);
++ imx219_update_pad_format(imx219, mode, fmt);
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ framefmt = v4l2_subdev_get_try_format(sd, state, fmt->pad);
++ *framefmt = fmt->format;
++ } else if (imx219->mode != mode ||
++ imx219->fmt.code != fmt->format.code) {
++ imx219->fmt = fmt->format;
++ imx219->mode = mode;
++ /* Update limits and set FPS to default */
++ __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
++ IMX219_VTS_MAX - mode->height, 1,
++ mode->vts_def - mode->height);
++ __v4l2_ctrl_s_ctrl(imx219->vblank, mode->vts_def - mode->height);
++ /* Update max exposure while meeting expected vblanking */
++ exposure_max = mode->vts_def - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ __v4l2_ctrl_modify_range(imx219->exposure, imx219->exposure->minimum,
++ exposure_max, imx219->exposure->step, exposure_def);
++ /*
++ * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
++ * depends on mode->width only, and is not changeble in any
++ * way other than changing the mode.
++ */
++ hblank = IMX219_PPL_DEFAULT - mode->width;
++ __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, hblank);
++ }
++
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_set_framefmt(struct imx219 *imx219)
++{
++ switch (imx219->fmt.code) {
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ return imx219_write_regs(imx219, raw8_framefmt_regs,
++ ARRAY_SIZE(raw8_framefmt_regs));
++
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ return imx219_write_regs(imx219, raw10_framefmt_regs,
++ ARRAY_SIZE(raw10_framefmt_regs));
++ }
++
++ return -EINVAL;
++}
++
++static const struct v4l2_rect *
++__imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_state *state,
++ unsigned int pad, enum v4l2_subdev_format_whence which)
++{
++ switch (which) {
++ case V4L2_SUBDEV_FORMAT_TRY:
++ return v4l2_subdev_get_try_crop(&imx219->sd, state, pad);
++ case V4L2_SUBDEV_FORMAT_ACTIVE:
++ return &imx219->mode->crop;
++ }
++
++ return NULL;
++}
++
++static int imx219_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP: {
++ struct imx219 *imx219 = to_imx219(sd);
++
++ mutex_lock(&imx219->mutex);
++ sel->r = *__imx219_get_pad_crop(imx219, state, sel->pad, sel->which);
++ mutex_unlock(&imx219->mutex);
++ return 0;
++ }
++
++ case V4L2_SEL_TGT_NATIVE_SIZE:
++ sel->r.top = 0;
++ sel->r.left = 0;
++ sel->r.width = IMX219_NATIVE_WIDTH;
++ sel->r.height = IMX219_NATIVE_HEIGHT;
++ return 0;
++
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.top = IMX219_PIXEL_ARRAY_TOP;
++ sel->r.left = IMX219_PIXEL_ARRAY_LEFT;
++ sel->r.width = IMX219_PIXEL_ARRAY_WIDTH;
++ sel->r.height = IMX219_PIXEL_ARRAY_HEIGHT;
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++static int imx219_start_streaming(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ const struct imx219_reg_list *reg_list;
++ int ret;
++
++ /* Apply default values of current mode */
++ reg_list = &imx219->mode->reg_list;
++ ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set mode\n", __func__);
++ goto err;
++ }
++
++ ret = imx219_set_framefmt(imx219);
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set frame format: %d\n",
++ __func__, ret);
++ goto err;
++ }
++
++ /* Apply customized values from user */
++ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
++ if (ret)
++ goto err;
++
++ /* set stream on register */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
++ if (ret)
++ goto err;
++
++ /* vflip and hflip cannot change during streaming */
++ __v4l2_ctrl_grab(imx219->vflip, true);
++ __v4l2_ctrl_grab(imx219->hflip, true);
++
++ return 0;
++
++err:
++ return ret;
++}
++
++static void imx219_stop_streaming(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ int ret;
++
++ /* set stream off register */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
++ if (ret)
++ dev_err(&client->dev, "%s failed to set stream\n", __func__);
++
++ __v4l2_ctrl_grab(imx219->vflip, false);
++ __v4l2_ctrl_grab(imx219->hflip, false);
++}
++
++static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret = 0;
++
++ mutex_lock(&imx219->mutex);
++
++ if (enable) {
++ ret = pm_runtime_get_sync(&client->dev);
++ if (ret < 0) {
++ pm_runtime_put_noidle(&client->dev);
++ mutex_unlock(&imx219->mutex);
++ return ret;
++ }
++
++ if (imx219->streaming)
++ goto unlock;
++
++ /*
++ * Apply default & customized values
++ * and then start streaming.
++ */
++ ret = imx219_start_streaming(imx219);
++ if (ret)
++ goto err_unlock;
++ } else {
++ imx219_stop_streaming(imx219);
++ pm_runtime_put(&client->dev);
++ }
++
++unlock:
++ imx219->streaming += enable ? 1 : -1;
++ WARN_ON(imx219->streaming < 0);
++
++ mutex_unlock(&imx219->mutex);
++
++ return ret;
++
++err_unlock:
++ pm_runtime_put(&client->dev);
++ mutex_unlock(&imx219->mutex);
++
++ return ret;
++}
++
++/* Power/clock management functions */
++static int imx219_power_on(struct device *dev)
++{
++ struct v4l2_subdev *sd = dev_get_drvdata(dev);
++ struct imx219 *imx219 = to_imx219(sd);
++ int ret;
++
++ ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES, imx219->supplies);
++ if (ret) {
++ dev_err(dev, "%s: failed to enable regulators\n",
++ __func__);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(imx219->xclk);
++ if (ret) {
++ dev_err(dev, "%s: failed to enable clock\n", __func__);
++ goto reg_off;
++ }
++
++ gpiod_set_value_cansleep(imx219->reset_gpio, 1);
++ usleep_range(IMX219_XCLR_MIN_DELAY_US,
++ IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
++
++ return 0;
++
++reg_off:
++ regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
++
++ return ret;
++}
++
++static int imx219_power_off(struct device *dev)
++{
++ struct v4l2_subdev *sd = dev_get_drvdata(dev);
++ struct imx219 *imx219 = to_imx219(sd);
++
++ gpiod_set_value_cansleep(imx219->reset_gpio, 0);
++ regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
++ clk_disable_unprepare(imx219->xclk);
++
++ return 0;
++}
++
++static int imx219_get_regulators(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ unsigned int i;
++
++ for (i = 0; i < IMX219_NUM_SUPPLIES; i++)
++ imx219->supplies[i].supply = imx219_supply_name[i];
++
++ return devm_regulator_bulk_get(&client->dev,
++ IMX219_NUM_SUPPLIES, imx219->supplies);
++}
++
++/* Verify chip ID */
++static int imx219_identify_module(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ int ret;
++ u32 val;
++
++ ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID,
++ IMX219_REG_VALUE_16BIT, &val);
++ if (ret) {
++ dev_err(&client->dev, "failed to read chip id %x\n",
++ IMX219_CHIP_ID);
++ return ret;
++ }
++
++ if (val != IMX219_CHIP_ID) {
++ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
++ IMX219_CHIP_ID, val);
++ return -EIO;
++ }
++
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, IMX219_CHIP_ID);
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops imx219_core_ops = {
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops imx219_video_ops = {
++ .g_frame_interval = imx219_g_frame_interval,
++ .s_frame_interval = imx219_s_frame_interval,
++ .s_stream = imx219_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
++ .enum_mbus_code = imx219_enum_mbus_code,
++ .get_fmt = imx219_get_pad_format,
++ .set_fmt = imx219_set_pad_format,
++ .get_selection = imx219_get_selection,
++ .enum_frame_size = imx219_enum_frame_size,
++ .enum_frame_interval = imx219_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops imx219_subdev_ops = {
++ .core = &imx219_core_ops,
++ .video = &imx219_video_ops,
++ .pad = &imx219_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
++ .open = imx219_open,
++};
++
++/* Initialize control handlers */
++static int imx219_init_controls(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ struct v4l2_ctrl_handler *ctrl_hdlr;
++ unsigned int height = imx219->mode->height;
++ struct v4l2_fwnode_device_properties props;
++ int exposure_max, exposure_def, hblank;
++ int i, ret;
++
++ ctrl_hdlr = &imx219->ctrl_handler;
++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
++ if (ret)
++ return ret;
++
++ mutex_init(&imx219->mutex);
++ ctrl_hdlr->lock = &imx219->mutex;
++
++ /* By default, PIXEL_RATE is read only */
++ imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_PIXEL_RATE, IMX219_PIXEL_RATE,
++ IMX219_PIXEL_RATE, 1, IMX219_PIXEL_RATE);
++
++ imx219->link_freq =
++ v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_LINK_FREQ,
++ ARRAY_SIZE(imx219_link_freq_menu) - 1, 0, imx219_link_freq_menu);
++ if (imx219->link_freq)
++ imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++
++ /* Initial vblank/hblank/exposure parameters based on current mode */
++ imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
++ IMX219_VTS_MAX - height, 1,
++ imx219->mode->vts_def - height);
++ hblank = IMX219_PPL_DEFAULT - imx219->mode->width;
++ imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_HBLANK, hblank, hblank, 1, hblank);
++ if (imx219->hblank)
++ imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ exposure_max = imx219->mode->vts_def - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_EXPOSURE, IMX219_EXPOSURE_MIN, exposure_max,
++ IMX219_EXPOSURE_STEP, exposure_def);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
++ IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX,
++ IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
++ IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX,
++ IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT);
++
++ imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ if (imx219->hflip)
++ imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
++ imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ if (imx219->vflip)
++ imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
++ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(imx219_test_pattern_menu) - 1,
++ 0, 0, imx219_test_pattern_menu);
++ for (i = 0; i < 4; i++) {
++ /*
++ * The assumption is that
++ * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
++ * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
++ * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
++ */
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_TEST_PATTERN_RED + i,
++ IMX219_TESTP_COLOUR_MIN,
++ IMX219_TESTP_COLOUR_MAX,
++ IMX219_TESTP_COLOUR_STEP,
++ IMX219_TESTP_COLOUR_MAX);
++ /* The "Solid color" pattern is white by default */
++ }
++
++ if (ctrl_hdlr->error) {
++ ret = ctrl_hdlr->error;
++ dev_err(&client->dev, "%s control init failed (%d)\n",
++ __func__, ret);
++ goto error;
++ }
++
++ ret = v4l2_fwnode_device_parse(&client->dev, &props);
++ if (ret)
++ goto error;
++
++ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops, &props);
++ if (ret)
++ goto error;
++
++ imx219->sd.ctrl_handler = ctrl_hdlr;
++
++ return 0;
++
++error:
++ v4l2_ctrl_handler_free(ctrl_hdlr);
++ mutex_destroy(&imx219->mutex);
++
++ return ret;
++}
++
++static void imx219_free_controls(struct imx219 *imx219)
++{
++ v4l2_ctrl_handler_free(imx219->sd.ctrl_handler);
++ mutex_destroy(&imx219->mutex);
++}
++
++static int imx219_check_hwcfg(struct device *dev)
++{
++ struct fwnode_handle *endpoint;
++ struct v4l2_fwnode_endpoint ep_cfg = {
++ .bus_type = V4L2_MBUS_CSI2_DPHY
++ };
++ int ret = -EINVAL;
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) {
++ dev_err(dev, "could not parse endpoint\n");
++ goto error_out;
++ }
++
++ /* Check the number of MIPI CSI2 data lanes */
++ if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) {
++ dev_err(dev, "only 2 data lanes are currently supported\n");
++ goto error_out;
++ }
++
++ /* Check the link frequency set in device tree */
++ if (!ep_cfg.nr_of_link_frequencies) {
++ dev_err(dev, "link-frequency property not found in DT\n");
++ goto error_out;
++ }
++
++ if (ep_cfg.nr_of_link_frequencies != 1 ||
++ ep_cfg.link_frequencies[0] != IMX219_DEFAULT_LINK_FREQ) {
++ dev_err(dev, "Link frequency not supported: %lld\n",
++ ep_cfg.link_frequencies[0]);
++ goto error_out;
++ }
++
++ ret = 0;
++
++error_out:
++ v4l2_fwnode_endpoint_free(&ep_cfg);
++ fwnode_handle_put(endpoint);
++
++ return ret;
++}
++
++static int imx219_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct imx219 *imx219;
++ int ret;
++
++ imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL);
++ if (!imx219)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
++
++ /* Check the hardware configuration in device tree */
++ if (imx219_check_hwcfg(dev))
++ return -EINVAL;
++
++ /* Get system clock (xclk) */
++ imx219->xclk = devm_clk_get(dev, NULL);
++ if (IS_ERR(imx219->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(imx219->xclk);
++ }
++
++ imx219->xclk_freq = clk_get_rate(imx219->xclk);
++ if (imx219->xclk_freq != IMX219_XCLK_FREQ) {
++ dev_err(dev, "xclk frequency not supported: %d Hz\n",
++ imx219->xclk_freq);
++ return -EINVAL;
++ }
++
++ ret = imx219_get_regulators(imx219);
++ if (ret) {
++ dev_err(dev, "failed to get regulators\n");
++ return ret;
++ }
++
++ /* Request optional enable pin */
++ imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
++ usleep_range(IMX219_XCLR_MIN_DELAY_US,
++ IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
++
++ /*
++ * The sensor must be powered for imx219_identify_module()
++ * to be able to read the CHIP_ID register
++ */
++ ret = imx219_power_on(dev);
++ if (ret)
++ return ret;
++
++ ret = imx219_identify_module(imx219);
++ if (ret)
++ goto error_power_off;
++
++ /* Set default mode to max resolution */
++ imx219->mode = &supported_modes[0];
++ imx219->frame_interval.numerator = 1;
++ imx219->frame_interval.denominator = supported_modes[0].fps;
++
++ /* sensor doesn't enter LP-11 state upon power up until and unless
++ * streaming is started, so upon power up switch the modes to:
++ * streaming -> standby
++ */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
++ if (ret < 0)
++ goto error_power_off;
++ usleep_range(100, 110);
++
++ /* put sensor back to standby mode */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
++ if (ret < 0)
++ goto error_power_off;
++ usleep_range(100, 110);
++
++ ret = imx219_init_controls(imx219);
++ if (ret)
++ goto error_power_off;
++
++ /* Initialize subdev */
++ imx219->sd.internal_ops = &imx219_internal_ops;
++ imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
++ imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++
++ /* Initialize source pad */
++ imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
++
++ /* Initialize default format */
++ imx219_set_default_format(imx219);
++
++ ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
++ if (ret) {
++ dev_err(dev, "failed to init entity pads: %d\n", ret);
++ goto error_handler_free;
++ }
++
++ ret = v4l2_async_register_subdev_sensor(&imx219->sd);
++ if (ret < 0) {
++ dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
++ goto error_media_entity;
++ }
++
++ /* Enable runtime PM and turn off the device */
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_idle(dev);
++
++ return 0;
++
++error_media_entity:
++ media_entity_cleanup(&imx219->sd.entity);
++
++error_handler_free:
++ imx219_free_controls(imx219);
++
++error_power_off:
++ imx219_power_off(dev);
++
++ return ret;
++}
++
++static void imx219_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx219 *imx219 = to_imx219(sd);
++
++ v4l2_async_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ imx219_free_controls(imx219);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ imx219_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct of_device_id imx219_dt_ids[] = {
++ { .compatible = "sony,imx219" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, imx219_dt_ids);
++
++static const struct dev_pm_ops imx219_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
++ SET_RUNTIME_PM_OPS(imx219_power_off, imx219_power_on, NULL)
++};
++
++static struct i2c_driver imx219_i2c_driver = {
++ .driver = {
++ .name = "imx219",
++ .of_match_table = imx219_dt_ids,
++ .pm = &imx219_pm_ops,
++ },
++ .probe = imx219_probe,
++ .remove = imx219_remove,
++};
++
++module_i2c_driver(imx219_i2c_driver);
++
++MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com");
++MODULE_DESCRIPTION("Sony IMX219 sensor driver");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/ov13850_mipi.c
+@@ -0,0 +1,1921 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++#define OV13850_XCLK_MIN 6000000
++#define OV13850_XCLK_MAX 54000000
++
++#define OV13850_LINK_FREQ_500MHZ 500000000LL
++
++/**
++ *OV13850 PLL
++ *
++ *PLL1:
++ *
++ *REF_CLK -> /PREDIVP[0] -> /PREDIV[2:0] -> *DIVP[9:8,7:0] -> /DIVM[3:0] -> /DIV_MIPI[1:0] -> PCLK
++ *(6-64M) 0x030A 0x0300 0x0301,0x302 0x0303 0x0304
++ * `-> MIPI_PHY_CLK
++ *
++ *
++ *PLL2:
++ * 000: 1
++ * 001: 1.5
++ * 010: 2
++ * 011: 2.5
++ * 100: 3
++ * 101: 4
++ * 0: /1 110: 6
++ * 1: /2 111: 8
++ *REF_CLK -> /PREDIVP[3] -> /PREDIV[2:0] -> /DIVP[9:0] -> /DIVDAC[3:0] -> DAC_CLK =
++ *(6~64M) 0x3611
++ * -> /DIVSP[3:0] -> /DIVS[2:0] -> SCLK
++ *
++ * -> /(1+DIVSRAM[3:0]) -> SRAM_CLK
++ */
++
++// PREDIVP
++#define OV13850_REG_PLL1_PREDIVP 0x030a
++#define OV13850_PREDIVP_1 0
++#define OV13850_PREDIVP_2 1
++
++// PREDIV
++#define OV13850_REG_PLL1_PREDIV 0x0300
++#define OV13850_PREDIV_1 0
++#define OV13850_PREDIV_1_5 1
++#define OV13850_PREDIV_2 2
++#define OV13850_PREDIV_2_5 3
++#define OV13850_PREDIV_3 4
++#define OV13850_PREDIV_4 5
++#define OV13850_PREDIV_6 6
++#define OV13850_PREDIV_8 7
++
++// DIVP
++#define OV13850_REG_PLL1_DIVP_H 0x0301
++#define OV13850_REG_PLL1_DIVP_L 0x0302
++#define OV13850_REG_PLL1_DIVP OV13850_REG_PLL1_DIVP_H
++
++// DIVM
++#define OV13850_REG_PLL1_DIVM 0x0303
++#define OV13850_DIVM(n) ((n)-1) // n=1~16
++
++// DIV_MIPI
++#define OV13850_REG_PLL1_DIV_MIPI 0x0304
++#define OV13850_DIV_MIPI_4 0
++#define OV13850_DIV_MIPI_5 1
++#define OV13850_DIV_MIPI_6 2
++#define OV13850_DIV_MIPI_8 3
++
++// system control
++#define OV13850_STREAM_CTRL 0x0100
++#define OV13850_REG_MIPI_SC 0x300f
++#define OV13850_MIPI_SC_8_BIT 0x0
++#define OV13850_MIPI_SC_10_BIT 0x1
++#define OV13850_MIPI_SC_12_BIT 0x2
++#define OV13850_GET_MIPI_SC_MIPI_BIT(v) ((v) & 0x3)
++#define OV13850_REG_MIPI_SC_CTRL0 0x3012
++#define OV13850_GET_MIPI_SC_CTRL0_LANE_NUM(v) ((v)>>4 & 0xf)
++
++// timing
++#define OV13850_REG_H_CROP_START_H 0x3800
++#define OV13850_REG_H_CROP_START_L 0x3801
++#define OV13850_REG_H_CROP_START OV13850_REG_H_CROP_START_H
++#define OV13850_REG_V_CROP_START_H 0x3802
++#define OV13850_REG_V_CROP_START_L 0x3803
++#define OV13850_REG_V_CROP_START OV13850_REG_V_CROP_START_H
++
++#define OV13850_REG_H_CROP_END_H 0x3804
++#define OV13850_REG_H_CROP_END_L 0x3805
++#define OV13850_REG_H_CROP_END OV13850_REG_H_CROP_END_H
++#define OV13850_REG_V_CROP_END_H 0x3806
++#define OV13850_REG_V_CROP_END_L 0x3807
++#define OV13850_REG_V_CROP_END OV13850_REG_V_CROP_END_H
++
++#define OV13850_REG_H_OUTPUT_SIZE_H 0x3808
++#define OV13850_REG_H_OUTPUT_SIZE_L 0x3809
++#define OV13850_REG_H_OUTPUT_SIZE OV13850_REG_H_OUTPUT_SIZE_H
++#define OV13850_REG_V_OUTPUT_SIZE_H 0x380a
++#define OV13850_REG_V_OUTPUT_SIZE_L 0x380b
++#define OV13850_REG_V_OUTPUT_SIZE OV13850_REG_V_OUTPUT_SIZE_H
++
++#define OV13850_REG_TIMING_HTS_H 0x380c
++#define OV13850_REG_TIMING_HTS_L 0x380d
++#define OV13850_REG_TIMING_HTS OV13850_REG_TIMING_HTS_H
++#define OV13850_REG_TIMING_VTS_H 0x380e
++#define OV13850_REG_TIMING_VTS_L 0x380f
++#define OV13850_REG_TIMING_VTS OV13850_REG_TIMING_VTS_H
++
++
++#define OV13850_REG_H_WIN_OFF_H 0x3810
++#define OV13850_REG_H_WIN_OFF_L 0x3811
++#define OV13850_REG_V_WIN_OFF_H 0x3812
++#define OV13850_REG_V_WIN_OFF_L 0x3813
++
++#define OV13850_REG_H_INC 0x3814
++#define OV13850_REG_V_INC 0x3815
++
++enum ov13850_mode_id {
++ OV13850_MODE_1080P_1920_1080 = 0,
++ OV13850_NUM_MODES,
++};
++
++enum ov13850_frame_rate {
++ OV13850_15_FPS = 0,
++ OV13850_30_FPS,
++ OV13850_60_FPS,
++ OV13850_NUM_FRAMERATES,
++};
++
++static const int ov13850_framerates[] = {
++ [OV13850_15_FPS] = 15,
++ [OV13850_30_FPS] = 30,
++ [OV13850_60_FPS] = 60,
++};
++
++struct ov13850_pixfmt {
++ u32 code;
++ u32 colorspace;
++};
++
++static const struct ov13850_pixfmt ov13850_formats[] = {
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, },
++};
++
++/* regulator supplies */
++static const char * const ov13850_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define OV13850_NUM_SUPPLIES ARRAY_SIZE(ov13850_supply_name)
++
++/*
++ * Image size under 1280 * 960 are SUBSAMPLING
++ * Image size upper 1280 * 960 are SCALING
++ */
++enum ov13850_downsize_mode {
++ SUBSAMPLING,
++ SCALING,
++};
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct ov13850_mode_info {
++ enum ov13850_mode_id id;
++ enum ov13850_downsize_mode dn_mode;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct ov13850_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *anal_gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *link_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct ov13850_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to OV13850 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[OV13850_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ int power_count;
++
++ struct v4l2_mbus_framefmt fmt;
++ bool pending_fmt_change;
++
++ const struct ov13850_mode_info *current_mode;
++ const struct ov13850_mode_info *last_mode;
++ enum ov13850_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct ov13850_ctrls ctrls;
++
++ u32 prev_sysclk, prev_hts;
++ u32 ae_low, ae_high, ae_target;
++
++ bool pending_mode_change;
++ bool streaming;
++};
++
++static inline struct ov13850_dev *to_ov13850_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct ov13850_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov13850_dev,
++ ctrls.handler)->sd;
++}
++
++/* ov13850 initial register */
++static const struct reg_value ov13850_init_setting_30fps_1080P[] = {
++
++};
++
++static const struct reg_value ov13850_setting_1080P_1920_1080[] = {
++//;XVCLK=24Mhz, SCLK=4x120Mhz, MIPI 640Mbps, DACCLK=240Mhz
++/*
++ * using quarter size to scale down
++ */
++ {0x0103, 0x01, 0, 0}, // ; software reset
++
++ {0x0300, 0x01, 0, 0}, //; PLL
++ {0x0301, 0x00, 0, 0}, //; PLL1_DIVP_hi
++ {0x0302, 0x28, 0, 0}, //; PLL1_DIVP_lo
++ {0x0303, 0x00, 0, 0}, // ; PLL
++ {0x030a, 0x00, 0, 0}, // ; PLL
++ //{0xffff, 20, 0, 0},
++ {0x300f, 0x11, 0, 0}, // SFC modified, MIPI_SRC, [1:0] 00-8bit, 01-10bit, 10-12bit
++ {0x3010, 0x01, 0, 0}, // ; MIPI PHY
++ {0x3011, 0x76, 0, 0}, // ; MIPI PHY
++ {0x3012, 0x41, 0, 0}, // ; MIPI 4 lane
++ {0x3013, 0x12, 0, 0}, // ; MIPI control
++ {0x3014, 0x11, 0, 0}, // ; MIPI control
++ {0x301f, 0x03, 0, 0}, //
++ {0x3106, 0x00, 0, 0}, //
++ {0x3210, 0x47, 0, 0}, //
++ {0x3500, 0x00, 0, 0}, // ; exposure HH
++ {0x3501, 0x67, 0, 0}, // ; exposure H
++ {0x3502, 0x80, 0, 0}, // ; exposure L
++ {0x3506, 0x00, 0, 0}, // ; short exposure HH
++ {0x3507, 0x02, 0, 0}, // ; short exposure H
++ {0x3508, 0x00, 0, 0}, // ; shour exposure L
++ {0x3509, 0x10, 0, 0},//00},//8},
++ {0x350a, 0x00, 0, 0}, // ; gain H
++ {0x350b, 0x10, 0, 0}, // ; gain L
++ {0x350e, 0x00, 0, 0}, // ; short gain H
++ {0x350f, 0x10, 0, 0}, // ; short gain L
++ {0x3600, 0x40, 0, 0}, // ; analog control
++ {0x3601, 0xfc, 0, 0}, // ; analog control
++ {0x3602, 0x02, 0, 0}, // ; analog control
++ {0x3603, 0x48, 0, 0}, // ; analog control
++ {0x3604, 0xa5, 0, 0}, // ; analog control
++ {0x3605, 0x9f, 0, 0}, // ; analog control
++ {0x3607, 0x00, 0, 0}, // ; analog control
++ {0x360a, 0x40, 0, 0}, // ; analog control
++ {0x360b, 0x91, 0, 0}, // ; analog control
++ {0x360c, 0x49, 0, 0}, // ; analog control
++ {0x360f, 0x8a, 0, 0}, //
++ {0x3611, 0x10, 0, 0}, // ; PLL2
++ //{0x3612, 0x23, 0, 0}, // ; PLL2
++ {0x3612, 0x13, 0, 0}, // ; PLL2
++ //{0x3613, 0x33, 0, 0}, // ; PLL2
++ {0x3613, 0x22, 0, 0}, // ; PLL2
++ //{0xffff, 50, 0, 0},
++ {0x3614, 0x28, 0, 0}, //[7:0] PLL2_DIVP lo
++ {0x3615, 0x08, 0, 0}, //[7:6] Debug mode, [5:4] N_pump clock div, [3:2] P_pump clock div, [1:0] PLL2_DIVP hi
++ {0x3641, 0x02, 0, 0},
++ {0x3660, 0x82, 0, 0},
++ {0x3668, 0x54, 0, 0},
++ {0x3669, 0x40, 0, 0},
++ {0x3667, 0xa0, 0, 0},
++ {0x3702, 0x40, 0, 0},
++ {0x3703, 0x44, 0, 0},
++ {0x3704, 0x2c, 0, 0},
++ {0x3705, 0x24, 0, 0},
++ {0x3706, 0x50, 0, 0},
++ {0x3707, 0x44, 0, 0},
++ {0x3708, 0x3c, 0, 0},
++ {0x3709, 0x1f, 0, 0},
++ {0x370a, 0x26, 0, 0},
++ {0x370b, 0x3c, 0, 0},
++ {0x3720, 0x66, 0, 0},
++ {0x3722, 0x84, 0, 0},
++ {0x3728, 0x40, 0, 0},
++ {0x372a, 0x00, 0, 0},
++ {0x372f, 0x90, 0, 0},
++ {0x3710, 0x28, 0, 0},
++ {0x3716, 0x03, 0, 0},
++ {0x3718, 0x10, 0, 0},
++ {0x3719, 0x08, 0, 0},
++ {0x371c, 0xfc, 0, 0},
++ {0x3760, 0x13, 0, 0},
++ {0x3761, 0x34, 0, 0},
++ {0x3767, 0x24, 0, 0},
++ {0x3768, 0x06, 0, 0},
++ {0x3769, 0x45, 0, 0},
++ {0x376c, 0x23, 0, 0},
++ {0x3d84, 0x00, 0, 0}, // ; OTP program disable
++ {0x3d85, 0x17, 0, 0}, // ; OTP power up load data enable, power load setting enable, software load setting
++ {0x3d8c, 0x73, 0, 0}, // ; OTP start address H
++ {0x3d8d, 0xbf, 0, 0}, // ; OTP start address L
++ {0x3800, 0x00, 0, 0}, // ; H crop start H
++ {0x3801, 0x08, 0, 0}, // ; H crop start L
++ {0x3802, 0x00, 0, 0}, // ; V crop start H
++ {0x3803, 0x04, 0, 0}, // ; V crop start L
++ {0x3804, 0x10, 0, 0}, // ; H crop end H
++ {0x3805, 0x97, 0, 0}, // ; H crop end L
++ {0x3806, 0x0c, 0, 0}, // ; V crop end H
++ {0x3807, 0x4b, 0, 0}, // ; V crop end L
++ {0x3808, 0x08, 0, 0}, // ; H output size H
++ {0x3809, 0x40, 0, 0}, // ; H output size L
++ {0x380a, 0x06, 0, 0}, // ; V output size H
++ {0x380b, 0x20, 0, 0}, // ; V output size L
++ {0x380c, 0x25, 0, 0}, // ; HTS H
++ {0x380d, 0x80, 0, 0}, // ; HTS L
++ {0x380e, 0x06, 0, 0}, // ; VTS H
++ {0x380f, 0x80, 0, 0}, // ; VTS L
++ {0x3810, 0x00, 0, 0}, // ; H win off H
++ {0x3811, 0x04, 0, 0}, // ; H win off L
++ {0x3812, 0x00, 0, 0}, // ; V win off H
++ {0x3813, 0x02, 0, 0}, // ; V win off L
++ {0x3814, 0x31, 0, 0}, // ; H inc
++ {0x3815, 0x31, 0, 0}, // ; V inc
++ {0x3820, 0x02, 0, 0}, // ; V flip off, V bin on
++ {0x3821, 0x05, 0, 0}, // ; H mirror on, H bin on
++ {0x3834, 0x00, 0, 0}, //
++ {0x3835, 0x1c, 0, 0}, // ; cut_en, vts_auto, blk_col_dis
++ {0x3836, 0x08, 0, 0}, //
++ {0x3837, 0x02, 0, 0}, //
++ {0x4000, 0xf1, 0, 0},//c1}, // ; BLC offset trig en, format change trig en, gain trig en, exp trig en, median en
++ {0x4001, 0x00, 0, 0}, // ; BLC
++ {0x400b, 0x0c, 0, 0}, // ; BLC
++ {0x4011, 0x00, 0, 0}, // ; BLC
++ {0x401a, 0x00, 0, 0}, // ; BLC
++ {0x401b, 0x00, 0, 0}, // ; BLC
++ {0x401c, 0x00, 0, 0}, // ; BLC
++ {0x401d, 0x00, 0, 0}, // ; BLC
++ {0x4020, 0x00, 0, 0}, // ; BLC
++ {0x4021, 0xe4, 0, 0}, // ; BLC
++ {0x4022, 0x07, 0, 0}, // ; BLC
++ {0x4023, 0x5f, 0, 0}, // ; BLC
++ {0x4024, 0x08, 0, 0}, // ; BLC
++ {0x4025, 0x44, 0, 0}, // ; BLC
++ {0x4026, 0x08, 0, 0}, // ; BLC
++ {0x4027, 0x47, 0, 0}, // ; BLC
++ {0x4028, 0x00, 0, 0}, // ; BLC
++ {0x4029, 0x02, 0, 0}, // ; BLC
++ {0x402a, 0x04, 0, 0}, // ; BLC
++ {0x402b, 0x08, 0, 0}, // ; BLC
++ {0x402c, 0x02, 0, 0}, // ; BLC
++ {0x402d, 0x02, 0, 0}, // ; BLC
++ {0x402e, 0x0c, 0, 0}, // ; BLC
++ {0x402f, 0x08, 0, 0}, // ; BLC
++ {0x403d, 0x2c, 0, 0}, //
++ {0x403f, 0x7f, 0, 0}, //
++ {0x4500, 0x82, 0, 0}, // ; BLC
++ {0x4501, 0x38, 0, 0}, // ; BLC
++ {0x4601, 0x04, 0, 0}, //
++ {0x4602, 0x22, 0, 0}, //
++ {0x4603, 0x01, 0, 0}, //; VFIFO
++ {0x4837, 0x19, 0, 0}, //; MIPI global timing
++ {0x4d00, 0x04, 0, 0}, // ; temperature monitor
++ {0x4d01, 0x42, 0, 0}, // ; temperature monitor
++ {0x4d02, 0xd1, 0, 0}, // ; temperature monitor
++ {0x4d03, 0x90, 0, 0}, // ; temperature monitor
++ {0x4d04, 0x66, 0, 0}, // ; temperature monitor
++ {0x4d05, 0x65, 0, 0}, // ; temperature monitor
++ {0x5000, 0x0e, 0, 0}, // ; windowing enable, BPC on, WPC on, Lenc on
++ {0x5001, 0x03, 0, 0}, // ; BLC enable, MWB on
++ {0x5002, 0x07, 0, 0}, //
++ {0x5013, 0x40, 0, 0},
++ {0x501c, 0x00, 0, 0},
++ {0x501d, 0x10, 0, 0},
++ //{0x5057, 0x56, 0, 0},//add
++ {0x5056, 0x08, 0, 0},
++ {0x5058, 0x08, 0, 0},
++ {0x505a, 0x08, 0, 0},
++ {0x5242, 0x00, 0, 0},
++ {0x5243, 0xb8, 0, 0},
++ {0x5244, 0x00, 0, 0},
++ {0x5245, 0xf9, 0, 0},
++ {0x5246, 0x00, 0, 0},
++ {0x5247, 0xf6, 0, 0},
++ {0x5248, 0x00, 0, 0},
++ {0x5249, 0xa6, 0, 0},
++ {0x5300, 0xfc, 0, 0},
++ {0x5301, 0xdf, 0, 0},
++ {0x5302, 0x3f, 0, 0},
++ {0x5303, 0x08, 0, 0},
++ {0x5304, 0x0c, 0, 0},
++ {0x5305, 0x10, 0, 0},
++ {0x5306, 0x20, 0, 0},
++ {0x5307, 0x40, 0, 0},
++ {0x5308, 0x08, 0, 0},
++ {0x5309, 0x08, 0, 0},
++ {0x530a, 0x02, 0, 0},
++ {0x530b, 0x01, 0, 0},
++ {0x530c, 0x01, 0, 0},
++ {0x530d, 0x0c, 0, 0},
++ {0x530e, 0x02, 0, 0},
++ {0x530f, 0x01, 0, 0},
++ {0x5310, 0x01, 0, 0},
++ {0x5400, 0x00, 0, 0},
++ {0x5401, 0x61, 0, 0},
++ {0x5402, 0x00, 0, 0},
++ {0x5403, 0x00, 0, 0},
++ {0x5404, 0x00, 0, 0},
++ {0x5405, 0x40, 0, 0},
++ {0x540c, 0x05, 0, 0},
++ {0x5b00, 0x00, 0, 0},
++ {0x5b01, 0x00, 0, 0},
++ {0x5b02, 0x01, 0, 0},
++ {0x5b03, 0xff, 0, 0},
++ {0x5b04, 0x02, 0, 0},
++ {0x5b05, 0x6c, 0, 0},
++ {0x5b09, 0x02, 0, 0}, //
++ //{0x5e00, 0x00, 0, 0}, // ; test pattern disable
++ //{0x5e00, 0x80, 0, 0}, // ; test pattern enable
++ {0x5e10, 0x1c, 0, 0}, // ; ISP test disable
++
++ //{0x0300, 0x01, 0, 0},// ; PLL
++ //{0x0302, 0x28, 0, 0},// ; PLL
++ //{0xffff, 50, 0, 0},
++ {0x3501, 0x67, 0, 0},// ; Exposure H
++ {0x370a, 0x26, 0, 0},//
++ {0x372a, 0x00, 0, 0},
++ {0x372f, 0x90, 0, 0},
++ {0x3801, 0x08, 0, 0}, //; H crop start L
++ {0x3803, 0x04, 0, 0}, //; V crop start L
++ {0x3805, 0x97, 0, 0}, //; H crop end L
++ {0x3807, 0x4b, 0, 0}, //; V crop end L
++ {0x3808, 0x08, 0, 0}, //; H output size H
++ {0x3809, 0x40, 0, 0}, //; H output size L
++ {0x380a, 0x06, 0, 0}, //; V output size H
++ {0x380b, 0x20, 0, 0}, //; V output size L
++ {0x380c, 0x25, 0, 0}, //; HTS H
++ {0x380d, 0x80, 0, 0}, //; HTS L
++ {0x380e, 0x0a, 0, 0},//6}, //; VTS H
++ {0x380f, 0x80, 0, 0}, //; VTS L
++ {0x3813, 0x02, 0, 0}, //; V win off
++ {0x3814, 0x31, 0, 0}, //; H inc
++ {0x3815, 0x31, 0, 0}, //; V inc
++ {0x3820, 0x02, 0, 0}, //; V flip off, V bin on
++ {0x3821, 0x05, 0, 0}, //; H mirror on, H bin on
++ {0x3836, 0x08, 0, 0}, //
++ {0x3837, 0x02, 0, 0}, //
++ {0x4020, 0x00, 0, 0}, //
++ {0x4021, 0xe4, 0, 0}, //
++ {0x4022, 0x07, 0, 0}, //
++ {0x4023, 0x5f, 0, 0}, //
++ {0x4024, 0x08, 0, 0}, //
++ {0x4025, 0x44, 0, 0}, //
++ {0x4026, 0x08, 0, 0}, //
++ {0x4027, 0x47, 0, 0}, //
++ {0x4603, 0x01, 0, 0}, //; VFIFO
++ {0x4837, 0x19, 0, 0}, //; MIPI global timing
++ {0x4802, 0x42, 0, 0}, //default 0x00
++ {0x481a, 0x00, 0, 0},
++ {0x481b, 0x1c, 0, 0}, //default 0x3c prepare
++ {0x4826, 0x12, 0, 0}, //default 0x32 trail
++ {0x5401, 0x61, 0, 0}, //
++ {0x5405, 0x40, 0, 0}, //
++
++ //{0xffff, 200, 0, 0},
++ //{0xffff, 200, 0, 0},
++ //{0xffff, 200, 0, 0},
++
++ //{0x0100, 0x01, 0, 0}, //; wake up, streaming
++};
++
++/* power-on sensor init reg table */
++static const struct ov13850_mode_info ov13850_mode_init_data = {
++ OV13850_MODE_1080P_1920_1080, SCALING,
++ 1920, 0x6e0, 1080, 0x470,
++ ov13850_init_setting_30fps_1080P,
++ ARRAY_SIZE(ov13850_init_setting_30fps_1080P),
++ OV13850_30_FPS,
++};
++
++static const struct ov13850_mode_info
++ov13850_mode_data[OV13850_NUM_MODES] = {
++ {OV13850_MODE_1080P_1920_1080, SCALING,
++ 1920, 0x6e0, 1080, 0x470,
++ ov13850_setting_1080P_1920_1080,
++ ARRAY_SIZE(ov13850_setting_1080P_1920_1080),
++ OV13850_30_FPS},
++};
++
++static int ov13850_write_reg(struct ov13850_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov13850_read_reg(struct ov13850_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int ov13850_read_reg16(struct ov13850_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = ov13850_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = ov13850_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int ov13850_write_reg16(struct ov13850_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = ov13850_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return ov13850_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int ov13850_mod_reg(struct ov13850_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = ov13850_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return ov13850_write_reg(sensor, reg, val);
++}
++
++static int ov13850_set_timings(struct ov13850_dev *sensor,
++ const struct ov13850_mode_info *mode)
++{
++ int ret;
++
++ ret = ov13850_write_reg16(sensor, OV13850_REG_H_OUTPUT_SIZE, mode->hact);
++ if (ret < 0)
++ return ret;
++
++ ret = ov13850_write_reg16(sensor, OV13850_REG_V_OUTPUT_SIZE, mode->vact);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int ov13850_load_regs(struct ov13850_dev *sensor,
++ const struct ov13850_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ st_info(ST_SENSOR, "%s, mode = 0x%x\n", __func__, mode->id);
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ if (mask)
++ ret = ov13850_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = ov13850_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return ov13850_set_timings(sensor, mode);
++}
++
++
++
++static int ov13850_get_gain(struct ov13850_dev *sensor)
++{
++ u32 gain = 0;
++ return gain;
++}
++
++static int ov13850_set_gain(struct ov13850_dev *sensor, int gain)
++{
++ return 0;
++}
++
++static int ov13850_set_stream_mipi(struct ov13850_dev *sensor, bool on)
++{
++ return 0;
++}
++
++static int ov13850_get_sysclk(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_night_mode(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_get_hts(struct ov13850_dev *sensor)
++{
++ /* read HTS from register settings */
++ u16 hts;
++ int ret;
++
++ ret = ov13850_read_reg16(sensor, OV13850_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++
++static int ov13850_set_hts(struct ov13850_dev *sensor, int hts)
++{
++ return ov13850_write_reg16(sensor, OV13850_REG_TIMING_HTS, hts);
++}
++
++
++static int ov13850_get_vts(struct ov13850_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = ov13850_read_reg16(sensor, OV13850_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++static int ov13850_set_vts(struct ov13850_dev *sensor, int vts)
++{
++ return ov13850_write_reg16(sensor, OV13850_REG_TIMING_VTS, vts);
++}
++
++static int ov13850_get_light_freq(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_bandingfilter(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_ae_target(struct ov13850_dev *sensor, int target)
++{
++ return 0;
++}
++
++static int ov13850_get_binning(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_binning(struct ov13850_dev *sensor, bool enable)
++{
++ return 0;
++}
++
++static const struct ov13850_mode_info *
++ov13850_find_mode(struct ov13850_dev *sensor, enum ov13850_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct ov13850_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(ov13850_mode_data,
++ ARRAY_SIZE(ov13850_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (ov13850_framerates[fr] > ov13850_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 ov13850_calc_pixel_rate(struct ov13850_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vact * sensor->current_mode->hact;
++ rate *= ov13850_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++/*
++ * After trying the various combinations, reading various
++ * documentations spread around the net, and from the various
++ * feedback, the clock tree is probably as follows:
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL1 | - reg 0x030a, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x0300, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x0301~0x0302, for the multiplier
++ * | +--------------+
++ * +->| MIPI Divider | - reg 0x0303, bits 0-3 for the pre-divider
++ * | +---------> MIPI PHY CLK
++ * | +-----+
++ * | +->| PLL1_DIV_MIPI | - reg 0x0304, bits 0-1 for the divider
++ * | +----------------> PCLK
++ * | +-----+
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL2 | - reg 0x0311, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x030b, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x030c~0x030d, for the multiplier
++ * | +--------------+
++ * +->| SCLK Divider | - reg 0x030F, bits 0-3 for the pre-divider
++ * +-+--------+ - reg 0x030E, bits 0-2 for the divider
++ * | +---------> SCLK
++ *
++ * | +-----+
++ * +->| DAC Divider | - reg 0x0312, bits 0-3 for the divider
++ * | +----------------> DACCLK
++ **
++ */
++
++/*
++ * ov13850_set_mipi_pclk() - Calculate the clock tree configuration values
++ * for the MIPI CSI-2 output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * bpl = HTOT * VTOT * FPS * bpp / num_lanes;
++ *
++ * This function use the requested bandwidth to calculate:
++ *
++ * - mipi_pclk = bpl / 2; ( / 2 is for CSI-2 DDR)
++ * - mipi_phy_clk = mipi_pclk * PLL1_DIV_MIPI;
++ *
++ * with these fixed parameters:
++ * PLL1_PREDIVP = 1;
++ * PLL1_PREDIV = 1; (MIPI_BIT_MODE == 8 ? 2 : 2,5);
++ * PLL1_DIVM = 1;
++ * PLL1_DIV_MIPI = 4;
++ *
++ * FIXME: this have been tested with 10-bit raw and 2 lanes setup only.
++ * MIPI_DIV is fixed to value 2, but it -might- be changed according to the
++ * above formula for setups with 1 lane or image formats with different bpp.
++ *
++ * FIXME: this deviates from the sensor manual documentation which is quite
++ * thin on the MIPI clock tree generation part.
++ */
++
++
++
++static int ov13850_set_mipi_pclk(struct ov13850_dev *sensor,
++ unsigned long rate)
++{
++
++ return 0;
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int ov13850_set_mode_direct(struct ov13850_dev *sensor,
++ const struct ov13850_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return ov13850_load_regs(sensor, mode);
++}
++
++static int ov13850_set_mode(struct ov13850_dev *sensor)
++{
++ const struct ov13850_mode_info *mode = sensor->current_mode;
++ const struct ov13850_mode_info *orig_mode = sensor->last_mode;
++ int ret = 0;
++
++ ret = ov13850_set_mode_direct(sensor, mode);
++ if (ret < 0)
++ return ret;
++
++ /*
++ * we support have 10 bits raw RGB(mipi)
++ */
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov13850_set_mipi_pclk(sensor, 0);
++
++ if (ret < 0)
++ return 0;
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++ return 0;
++}
++
++static int ov13850_set_framefmt(struct ov13850_dev *sensor,
++ struct v4l2_mbus_framefmt *format);
++
++/* restore the last set video mode after chip power-on */
++static int ov13850_restore_mode(struct ov13850_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = ov13850_load_regs(sensor, &ov13850_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &ov13850_mode_init_data;
++
++ /* now restore the last capture mode */
++ ret = ov13850_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return ov13850_set_framefmt(sensor, &sensor->fmt);
++}
++
++static void ov13850_power(struct ov13850_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ if (enable) {
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, 0);
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, 1);
++ } else {
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, 0);
++ }
++
++ mdelay(100);
++}
++
++static void ov13850_reset(struct ov13850_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ mdelay(100);
++}
++
++static int ov13850_set_power_on(struct ov13850_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(OV13850_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ ov13850_reset(sensor);
++ ov13850_power(sensor, true);
++
++ return 0;
++
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static void ov13850_set_power_off(struct ov13850_dev *sensor)
++{
++ ov13850_power(sensor, false);
++ regulator_bulk_disable(OV13850_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++}
++
++static int ov13850_set_power_mipi(struct ov13850_dev *sensor, bool on)
++{
++ return 0;
++}
++
++static int ov13850_set_power(struct ov13850_dev *sensor, bool on)
++{
++ int ret = 0;
++ u16 chip_id;
++
++ if (on) {
++ ret = ov13850_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++#ifdef UNUSED_CODE
++ ret = ov13850_read_reg16(sensor, OV13850_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&sensor->i2c_client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ ret = -ENODEV;
++ goto power_off;
++ }
++
++ if (chip_id != OV13850_CHIP_ID) {
++ dev_err(&sensor->i2c_client->dev,
++ "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV13850_CHIP_ID, chip_id);
++ ret = -ENXIO;
++ goto power_off;
++ }
++ dev_err(&sensor->i2c_client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++#endif
++
++ ret = ov13850_restore_mode(sensor);
++ if (ret)
++ goto power_off;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov13850_set_power_mipi(sensor, on);
++ if (ret)
++ goto power_off;
++
++ if (!on)
++ ov13850_set_power_off(sensor);
++
++ return 0;
++
++power_off:
++ ov13850_set_power_off(sensor);
++ return ret;
++}
++
++static int ov13850_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ /*
++ * If the power count is modified from 0 to != 0 or from != 0 to 0,
++ * update the power state.
++ */
++ if (sensor->power_count == !on) {
++ ret = ov13850_set_power(sensor, !!on);
++ if (ret)
++ goto out;
++ }
++
++ /* Update the power count. */
++ sensor->power_count += on ? 1 : -1;
++ WARN_ON(sensor->power_count < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ if (on && !ret && sensor->power_count == 1) {
++ /* restore controls */
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ }
++
++ return ret;
++}
++
++static int ov13850_try_frame_interval(struct ov13850_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct ov13850_mode_info *mode;
++ enum ov13850_frame_rate rate = OV13850_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = ov13850_framerates[OV13850_15_FPS];
++ maxfps = ov13850_framerates[OV13850_NUM_FRAMERATES - 1];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = OV13850_60_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(ov13850_framerates); i++) {
++ int curr_fps = ov13850_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++ st_info(ST_SENSOR, "best_fps = %d, fps = %d\n", best_fps, fps);
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = ov13850_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int ov13850_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++
++ if (code->index >= ARRAY_SIZE(ov13850_formats))
++ return -EINVAL;
++
++ code->code = ov13850_formats[code->index].code;
++ return 0;
++}
++
++static int ov13850_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov13850_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum ov13850_frame_rate fr,
++ const struct ov13850_mode_info **new_mode)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ const struct ov13850_mode_info *mode;
++ int i;
++
++ mode = ov13850_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ for (i = 0; i < ARRAY_SIZE(ov13850_formats); i++)
++ if (ov13850_formats[i].code == fmt->code)
++ break;
++ if (i >= ARRAY_SIZE(ov13850_formats))
++ i = 0;
++
++ fmt->code = ov13850_formats[i].code;
++ fmt->colorspace = ov13850_formats[i].colorspace;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++
++ return 0;
++}
++
++static int ov13850_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ const struct ov13850_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = ov13850_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ if (mbus_fmt->code != sensor->fmt.code)
++ sensor->pending_fmt_change = true;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ ov13850_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov13850_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov13850_set_framefmt(struct ov13850_dev *sensor,
++ struct v4l2_mbus_framefmt *format)
++{
++ u8 fmt;
++
++ switch (format->code) {
++ /* Raw, BGBG... / GRGR... */
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ fmt = 0x0;
++ break;
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ fmt = 0x1;
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ case MEDIA_BUS_FMT_SGBRG12_1X12:
++ case MEDIA_BUS_FMT_SGRBG12_1X12:
++ case MEDIA_BUS_FMT_SRGGB12_1X12:
++ fmt = 0x2;
++ default:
++ return -EINVAL;
++ }
++
++ return ov13850_mod_reg(sensor, OV13850_REG_MIPI_SC,
++ BIT(1) | BIT(0), fmt);
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int ov13850_set_ctrl_hue(struct ov13850_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_contrast(struct ov13850_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_saturation(struct ov13850_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_white_balance(struct ov13850_dev *sensor, int awb)
++{
++ struct ov13850_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_exposure(struct ov13850_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct ov13850_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ return ret;
++}
++
++static const s64 link_freq_menu_items[] = {
++ OV13850_LINK_FREQ_500MHZ
++};
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++static int ov13850_set_ctrl_test_pattern(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_set_ctrl_light_freq(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_set_ctrl_hflip(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_set_ctrl_vflip(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ val = ov13850_get_gain(sensor);
++ break;
++ }
++
++ return 0;
++}
++
++static int ov13850_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored right after power-up.
++ */
++ if (sensor->power_count == 0)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = ov13850_set_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = ov13850_set_ctrl_exposure(sensor, V4L2_EXPOSURE_MANUAL);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = ov13850_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = ov13850_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = ov13850_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = ov13850_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = ov13850_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = ov13850_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = ov13850_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = ov13850_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov13850_ctrl_ops = {
++ .g_volatile_ctrl = ov13850_g_volatile_ctrl,
++ .s_ctrl = ov13850_s_ctrl,
++};
++
++static int ov13850_init_controls(struct ov13850_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &ov13850_ctrl_ops;
++ struct ov13850_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ ov13850_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 0);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 1024);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 1024);
++
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 4, 0xfff8, 1, 0x4c00);
++ ctrls->anal_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
++ 0x10, 0xfff8, 1, 0x0080);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++ ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ,
++ 0, 0, link_freq_menu_items);
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ // ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ // ctrls->anal_gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int ov13850_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= OV13850_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ ov13850_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ ov13850_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int ov13850_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ struct v4l2_fract tpf;
++ int ret;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++ if (fie->index >= OV13850_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = ov13850_framerates[fie->index];
++
++/* ret = ov13850_try_frame_interval(sensor, &tpf,
++ * fie->width, fie->height);
++ * if (ret < 0)
++ * return -EINVAL;
++ */
++ fie->interval = tpf;
++
++ return 0;
++}
++
++static int ov13850_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov13850_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ const struct ov13850_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = ov13850_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = ov13850_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov13850_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov13850_stream_start(struct ov13850_dev *sensor, int enable)
++{
++ int ret;
++
++ if (enable) { //stream on
++ mdelay(1000);
++ ret = ov13850_write_reg(sensor, OV13850_STREAM_CTRL, enable);
++ } else { //stream off
++ ret = ov13850_write_reg(sensor, OV13850_STREAM_CTRL, enable);
++ mdelay(100);
++ }
++
++ return ret;
++}
++
++static int ov13850_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable && sensor->pending_mode_change) {
++ ret = ov13850_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_fmt_change) {
++ ret = ov13850_set_framefmt(sensor, &sensor->fmt);
++ if (ret)
++ goto out;
++ sensor->pending_fmt_change = false;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov13850_set_stream_mipi(sensor, enable);
++
++ ret = ov13850_stream_start(sensor, enable);
++
++ if (!ret)
++ sensor->streaming = enable;
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static const struct v4l2_subdev_core_ops ov13850_core_ops = {
++ .s_power = ov13850_s_power,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops ov13850_video_ops = {
++ .g_frame_interval = ov13850_g_frame_interval,
++ .s_frame_interval = ov13850_s_frame_interval,
++ .s_stream = ov13850_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops ov13850_pad_ops = {
++ .enum_mbus_code = ov13850_enum_mbus_code,
++ .get_fmt = ov13850_get_fmt,
++ .set_fmt = ov13850_set_fmt,
++ .enum_frame_size = ov13850_enum_frame_size,
++ .enum_frame_interval = ov13850_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops ov13850_subdev_ops = {
++ .core = &ov13850_core_ops,
++ .video = &ov13850_video_ops,
++ .pad = &ov13850_pad_ops,
++};
++
++static int ov13850_get_regulators(struct ov13850_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < OV13850_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = ov13850_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ OV13850_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int ov13850_check_chip_id(struct ov13850_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = ov13850_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++#ifdef UNUSED_CODE
++ ret = ov13850_read_reg16(sensor, OV13850_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ goto power_off;
++ }
++
++ if (chip_id != OV13850_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV13850_CHIP_ID, chip_id);
++ ret = -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++#endif
++
++power_off:
++ ov13850_set_power_off(sensor);
++ return ret;
++}
++
++static int ov13850_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct ov13850_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++ u8 chip_id_high, chip_id_low;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 1920;
++ fmt->height = 1080;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = ov13850_framerates[OV13850_30_FPS];
++ sensor->current_fr = OV13850_30_FPS;
++ sensor->current_mode =
++ &ov13850_mode_data[OV13850_MODE_1080P_1920_1080];
++ sensor->last_mode = sensor->current_mode;
++
++ sensor->ae_target = 52;
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_PARALLEL &&
++ sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY &&
++ sensor->ep.bus_type != V4L2_MBUS_BT656) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < OV13850_XCLK_MIN ||
++ sensor->xclk_freq > OV13850_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ /* request optional power down pin */
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ /* request optional reset pin */
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &ov13850_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = ov13850_get_regulators(sensor);
++ if (ret)
++ return ret;
++
++ mutex_init(&sensor->lock);
++
++ ret = ov13850_check_chip_id(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = ov13850_init_controls(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static int ov13850_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ return 0;
++}
++
++static const struct i2c_device_id ov13850_id[] = {
++ {"ov13850", 0},
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, ov13850_id);
++
++static const struct of_device_id ov13850_dt_ids[] = {
++ { .compatible = "ovti,ov13850" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ov13850_dt_ids);
++
++static struct i2c_driver ov13850_i2c_driver = {
++ .driver = {
++ .name = "ov13850",
++ .of_match_table = ov13850_dt_ids,
++ },
++ .id_table = ov13850_id,
++ .probe_new = ov13850_probe,
++ .remove = ov13850_remove,
++};
++
++module_i2c_driver(ov13850_i2c_driver);
++
++MODULE_DESCRIPTION("OV13850 MIPI Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/ov4689_mipi.c
+@@ -0,0 +1,2975 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++
++#define OV4689_LANES 4
++
++#define OV4689_LINK_FREQ_500MHZ 500000000LL
++
++/* min/typical/max system clock (xclk) frequencies */
++#define OV4689_XCLK_MIN 6000000
++#define OV4689_XCLK_MAX 64000000
++
++#define OV4689_CHIP_ID (0x4688)
++
++#define OV4689_CHIP_ID_HIGH_BYTE 0x300a // max should be 0x46
++#define OV4689_CHIP_ID_LOW_BYTE 0x300b // max should be 0x88
++#define OV4689_REG_CHIP_ID 0x300a
++
++#define OV4689_REG_H_OUTPUT_SIZE 0x3808
++#define OV4689_REG_V_OUTPUT_SIZE 0x380a
++#define OV4689_REG_TIMING_HTS 0x380c
++#define OV4689_REG_TIMING_VTS 0x380e
++
++#define OV4689_REG_EXPOSURE_HI 0x3500
++#define OV4689_REG_EXPOSURE_MED 0x3501
++#define OV4689_REG_EXPOSURE_LO 0x3502
++#define OV4689_REG_GAIN_H 0x3507
++#define OV4689_REG_GAIN_M 0x3508
++#define OV4689_REG_GAIN_L 0x3509
++#define OV4689_REG_TEST_PATTERN 0x5040
++#define OV4689_REG_TIMING_TC_REG20 0x3820
++#define OV4689_REG_TIMING_TC_REG21 0x3821
++
++#define OV4689_REG_AWB_R_GAIN 0x500C
++#define OV4689_REG_AWB_B_GAIN 0x5010
++#define OV4689_REG_STREAM_ON 0x0100
++
++#define OV4689_REG_MIPI_SC_CTRL_HI 0x3018
++#define OV4689_REG_MIPI_SC_CTRL_LOW 0x3019
++
++enum ov4689_mode_id {
++ //OV4689_MODE_720P_1280_720 = 0,
++ OV4689_MODE_1080P_1920_1080 = 0,
++ //OV4689_MODE_4M_2688_1520,
++ OV4689_NUM_MODES,
++};
++
++enum ov4689_frame_rate {
++ OV4689_15_FPS = 0,
++ OV4689_30_FPS,
++ OV4689_45_FPS,
++ OV4689_60_FPS,
++ OV4689_90_FPS,
++ OV4689_120_FPS,
++ OV4689_150_FPS,
++ OV4689_180_FPS,
++ OV4689_330_FPS,
++ OV4689_NUM_FRAMERATES,
++};
++
++enum ov4689_format_mux {
++ OV4689_FMT_MUX_RAW,
++};
++
++static const int ov4689_framerates[] = {
++ [OV4689_15_FPS] = 15,
++ [OV4689_30_FPS] = 30,
++ [OV4689_45_FPS] = 45,
++ [OV4689_60_FPS] = 60,
++ [OV4689_90_FPS] = 90,
++ [OV4689_120_FPS] = 120,
++ [OV4689_150_FPS] = 150,
++ [OV4689_180_FPS] = 180,
++ [OV4689_330_FPS] = 330,
++};
++
++/* regulator supplies */
++static const char * const ov4689_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define OV4689_NUM_SUPPLIES ARRAY_SIZE(ov4689_supply_name)
++
++/*
++ * Image size under 1280 * 960 are SUBSAMPLING
++ * Image size upper 1280 * 960 are SCALING
++ */
++enum ov4689_downsize_mode {
++ SUBSAMPLING,
++ SCALING,
++};
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct ov4689_mode_info {
++ enum ov4689_mode_id id;
++ enum ov4689_downsize_mode dn_mode;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct ov4689_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *anal_gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *link_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct ov4689_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to OV4689 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[OV4689_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ struct v4l2_mbus_framefmt fmt;
++
++ const struct ov4689_mode_info *current_mode;
++ const struct ov4689_mode_info *last_mode;
++ enum ov4689_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct ov4689_ctrls ctrls;
++
++ bool pending_mode_change;
++ int streaming;
++};
++
++static inline struct ov4689_dev *to_ov4689_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct ov4689_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov4689_dev,
++ ctrls.handler)->sd;
++}
++
++/* ov4689 initial register */
++static const struct reg_value ov4689_init_setting_30fps_1080P[] = {
++/* ov4689_1080p_30fps_4d */
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x02, 0, 0},
++ {0x0302, 0x32, 0, 0},
++ {0x0303, 0x00, 0, 0},
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x4c, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0},
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x00, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x20, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x01, 0, 0},
++ {0x3801, 0x88, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0xe0, 0, 0},
++ {0x3804, 0x09, 0, 0},
++ {0x3805, 0x17, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0x1f, 0, 0},
++ {0x3808, 0x07, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x04, 0, 0},
++ {0x380b, 0x38, 0, 0},
++ {0x380c, 0x0d, 0, 0},
++ {0x380d, 0x70, 0, 0},
++ {0x380e, 0x04, 0, 0},
++ {0x380f, 0x8A, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x08, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x04, 0, 0},
++ {0x3814, 0x01, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x01, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x04, 0, 0},
++ {0x3836, 0x01, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0xf1, 0, 0},
++ {0x4001, 0x40, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x06, 0, 0},
++ {0x4023, 0x13, 0, 0},
++ {0x4024, 0x07, 0, 0},
++ {0x4025, 0x40, 0, 0},
++ {0x4026, 0x07, 0, 0},
++ {0x4027, 0x50, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x40, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4601, 0x77, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0},
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x0c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_VGA_640_480[] = {
++ //@@ RES_640x480_2x_Bin_330fps_816Mbps
++ //OV4689_AM01B_640x480_24M_2lane_816Mbps_330fps_20140210.txt
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0}, // 00
++ {0x0302, 0x22, 0, 0}, // 816Mbps 5a ; 64 ; 5a ; 78 ; 78 ; 2a
++ {0x0303, 0x00, 0, 0}, // 03 ; 01 ; 02 ;
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x4c, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0}, // 8X
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x05, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x40, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x00, 0, 0},
++ {0x3801, 0x48, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0x2C, 0, 0},
++ {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x57, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0xD3, 0, 0},
++ {0x3808, 0x02, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x01, 0, 0},
++ {0x380b, 0xe0, 0, 0},
++
++ {0x380c, 0x02, 0, 0}, // 0a ; 03
++ {0x380d, 0x04, 0, 0}, // 1c ; 5C
++
++ {0x380e, 0x03, 0, 0},
++ {0x380f, 0x05, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x04, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x02, 0, 0},
++ {0x3814, 0x03, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x03, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x08, 0, 0},
++ {0x3836, 0x02, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0x71, 0, 0},
++ {0x4001, 0x50, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x03, 0, 0},
++ {0x4023, 0x93, 0, 0},
++ {0x4024, 0x04, 0, 0},
++ {0x4025, 0xC0, 0, 0},
++ {0x4026, 0x04, 0, 0},
++ {0x4027, 0xD0, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x44, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4600, 0x00, 0, 0},
++ {0x4601, 0x4F, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0}, // 20 ; 10
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x3c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_720P_1280_720[] = {
++ //@@ RES_1280x720_2x_Bin_150fps_816Mbps
++ //OV4689_AM01B_1280x720_24M_2lane_816Mbps_150fps_20140210.txt
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0}, // 00
++ {0x0302, 0x22, 0, 0}, // 816Mbps 5a ; 64 ; 5a ; 78 ; 78 ; 2a
++ {0x0303, 0x00, 0, 0}, // 03 ; 01 ; 02 ;
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x30, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x07, 0, 0},
++ {0x3509, 0x78, 0, 0}, // 8X
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x05, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x40, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x00, 0, 0},
++ {0x3801, 0x48, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0x2C, 0, 0},
++ {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x57, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0xD3, 0, 0},
++ {0x3808, 0x05, 0, 0},
++ {0x3809, 0x00, 0, 0},
++ {0x380a, 0x02, 0, 0},
++ {0x380b, 0xD0, 0, 0},
++#ifndef UNUSED_CODE
++ {0x380c, 0x04, 0, 0}, // 0a ; 03
++ {0x380d, 0x08, 0, 0}, // 1c ; 5C
++#else
++ {0x380c, 0x05, 0, 0}, // 120fps
++ {0x380d, 0x0A, 0, 0},
++#endif
++ {0x380e, 0x03, 0, 0},
++ {0x380f, 0x05, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x04, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x02, 0, 0},
++ {0x3814, 0x03, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x03, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x08, 0, 0},
++ {0x3836, 0x02, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0x71, 0, 0},
++ {0x4001, 0x50, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x03, 0, 0},
++ {0x4023, 0x93, 0, 0},
++ {0x4024, 0x04, 0, 0},
++ {0x4025, 0xC0, 0, 0},
++ {0x4026, 0x04, 0, 0},
++ {0x4027, 0xD0, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x44, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4600, 0x00, 0, 0},
++ {0x4601, 0x4F, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0}, // 20 ; 10
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x3c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_1080P_1920_1080[] = {
++ //@@ RES_1920x1080_60fps_816Mbps 2lanes
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0}, // clk
++ {0x0302, 0x22, 0, 0},
++ {0x0303, 0x00, 0, 0},
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0}, // AEC
++ {0x3501, 0x4c, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0},
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x00, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x20, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x01, 0, 0}, // timings
++ {0x3801, 0x88, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0xe0, 0, 0},
++ {0x3804, 0x09, 0, 0},
++ {0x3805, 0x17, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0x1f, 0, 0},
++ {0x3808, 0x07, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x04, 0, 0},
++ {0x380b, 0x38, 0, 0},
++ {0x380c, 0x06, 0, 0},
++ {0x380d, 0xe0, 0, 0},
++ {0x380e, 0x04, 0, 0},
++ {0x380f, 0x70, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x08, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x04, 0, 0},
++ {0x3814, 0x01, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x01, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x04, 0, 0},
++ {0x3836, 0x01, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0xf1, 0, 0},
++ {0x4001, 0x40, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x06, 0, 0},
++ {0x4023, 0x13, 0, 0},
++ {0x4024, 0x07, 0, 0},
++ {0x4025, 0x40, 0, 0},
++ {0x4026, 0x07, 0, 0},
++ {0x4027, 0x50, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x40, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4601, 0x77, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0},
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x0c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_4M_2688_1520[] = {
++ //@@ 0 10 RES_2688x1520_default(60fps)
++ //102 2630 960
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0},
++ {0x0302, 0x22, 0, 0}, // 2a ;1008Mbps,23 ;; 840Mbps
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x60, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0},
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x00, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x20, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x00, 0, 0},
++ {0x3801, 0x08, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0x04, 0, 0},
++ {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x97, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0xfb, 0, 0},
++ {0x3808, 0x0a, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x05, 0, 0},
++ {0x380b, 0xf0, 0, 0},
++ {0x380c, 0x03, 0, 0},
++ {0x380d, 0x5c, 0, 0},
++ {0x380e, 0x06, 0, 0},
++ {0x380f, 0x12, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x08, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x04, 0, 0},
++ {0x3814, 0x01, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x00, 0, 0},
++ {0x3821, 0x06, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x01, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x04, 0, 0},
++ {0x3836, 0x01, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0x71, 0, 0},
++ {0x4001, 0x40, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x07, 0, 0},
++ {0x4023, 0xcf, 0, 0},
++ {0x4024, 0x09, 0, 0},
++ {0x4025, 0x60, 0, 0},
++ {0x4026, 0x09, 0, 0},
++ {0x4027, 0x6f, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x40, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4601, 0x04, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x14, 0, 0}, // 10
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x0c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++// {0x0100, 0x01, 0, 0},
++
++// {0x0100, 0x00, 0, 0},
++ {0x380c, 0x0A, 0, 0}, // 05
++ {0x380d, 0x0A, 0, 0}, // 10
++ {0x380e, 0x06, 0, 0},
++ {0x380f, 0x12, 0, 0},
++// {0x0100, 0x01, 0, 0},
++ {0x3105, 0x31, 0, 0},
++ {0x301a, 0xf9, 0, 0},
++ {0x3508, 0x07, 0, 0},
++ {0x484b, 0x05, 0, 0},
++ {0x4805, 0x03, 0, 0},
++ {0x3601, 0x01, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++// {0x0100, 0x01, 0, 0},
++ {0xffff, 0x0a, 0, 0},
++ {0x3105, 0x11, 0, 0},
++ {0x301a, 0xf1, 0, 0},
++ {0x4805, 0x00, 0, 0},
++ {0x301a, 0xf0, 0, 0},
++ {0x3208, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x3601, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x3208, 0x10, 0, 0},
++ {0x3208, 0xa0, 0, 0},
++};
++
++/* power-on sensor init reg table */
++static const struct ov4689_mode_info ov4689_mode_init_data = {
++
++};
++
++static const struct ov4689_mode_info
++ov4689_mode_data[OV4689_NUM_MODES] = {
++ // {OV4689_MODE_720P_1280_720, SUBSAMPLING,
++ // 1280, 0x408, 720, 0x305,
++ // ov4689_setting_720P_1280_720,
++ // ARRAY_SIZE(ov4689_setting_720P_1280_720),
++ // OV4689_150_FPS},
++ // {OV4689_MODE_1080P_1920_1080, SCALING,
++ // 1920, 0x6e0, 1080, 0x470,
++ // ov4689_setting_1080P_1920_1080,
++ // ARRAY_SIZE(ov4689_setting_1080P_1920_1080),
++ // OV4689_60_FPS},
++ // {OV4689_MODE_4M_2688_1520, SCALING,
++ // 2688, 0xa0a, 1520, 0x612,
++ // ov4689_setting_4M_2688_1520,
++ // ARRAY_SIZE(ov4689_setting_4M_2688_1520),
++ // OV4689_60_FPS},
++
++ {OV4689_MODE_1080P_1920_1080, SCALING,
++ 1920, 0x6e0, 1080, 0x470,
++ ov4689_init_setting_30fps_1080P,
++ ARRAY_SIZE(ov4689_init_setting_30fps_1080P),
++ OV4689_60_FPS},
++};
++
++static int ov4689_write_reg(struct ov4689_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov4689_read_reg(struct ov4689_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int ov4689_read_reg16(struct ov4689_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = ov4689_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = ov4689_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int ov4689_write_reg16(struct ov4689_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = ov4689_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return ov4689_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int ov4689_mod_reg(struct ov4689_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = ov4689_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return ov4689_write_reg(sensor, reg, val);
++}
++
++static int ov4689_set_timings(struct ov4689_dev *sensor,
++ const struct ov4689_mode_info *mode)
++{
++ return 0;
++}
++
++static int ov4689_load_regs(struct ov4689_dev *sensor,
++ const struct ov4689_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ st_info(ST_SENSOR, "%s, mode = 0x%x\n", __func__, mode->id);
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ if (mask)
++ ret = ov4689_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = ov4689_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return ov4689_set_timings(sensor, mode);
++}
++
++#ifdef UNUSED_CODE
++static int ov4689_get_exposure(struct ov4689_dev *sensor)
++{
++ int exp, ret;
++ u8 temp;
++
++ ret = ov4689_read_reg(sensor, OV4689_REG_EXPOSURE_HI, &temp);
++ if (ret)
++ return ret;
++ exp = ((int)temp & 0x0f) << 16;
++ ret = ov4689_read_reg(sensor, OV4689_REG_EXPOSURE_MED, &temp);
++ if (ret)
++ return ret;
++ exp |= ((int)temp << 8);
++ ret = ov4689_read_reg(sensor, OV4689_REG_EXPOSURE_LO, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp;
++
++ return exp >> 4;
++}
++#endif
++
++static int ov4689_set_exposure(struct ov4689_dev *sensor, u32 exposure)
++{
++ int ret;
++
++ st_info(ST_SENSOR, "%s, exposure = 0x%x\n", __func__, exposure);
++ exposure <<= 4;
++
++ ret = ov4689_write_reg(sensor,
++ OV4689_REG_EXPOSURE_LO,
++ exposure & 0xff);
++ if (ret)
++ return ret;
++ ret = ov4689_write_reg(sensor,
++ OV4689_REG_EXPOSURE_MED,
++ (exposure >> 8) & 0xff);
++ if (ret)
++ return ret;
++ return ov4689_write_reg(sensor,
++ OV4689_REG_EXPOSURE_HI,
++ (exposure >> 16) & 0x0f);
++}
++
++static int ov4689_get_gain(struct ov4689_dev *sensor)
++{
++ u32 gain = 0;
++ u8 val;
++
++ ov4689_read_reg(sensor, OV4689_REG_GAIN_H, &val);
++ gain = (val & 0x3) << 16;
++ ov4689_read_reg(sensor, OV4689_REG_GAIN_M, &val);
++ gain |= val << 8;
++ ov4689_read_reg(sensor, OV4689_REG_GAIN_L, &val);
++ gain |= val;
++
++ return gain;
++}
++
++static int ov4689_set_gain(struct ov4689_dev *sensor, int gain)
++{
++ ov4689_write_reg(sensor, OV4689_REG_GAIN_H,
++ (gain >> 16) & 0x3);
++ ov4689_write_reg(sensor, OV4689_REG_GAIN_M,
++ (gain >> 8) & 0xff);
++ ov4689_write_reg(sensor, OV4689_REG_GAIN_L,
++ gain & 0xff);
++ return 0;
++}
++
++#ifdef UNUSED_CODE
++static int ov4689_get_sysclk(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_night_mode(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_get_hts(struct ov4689_dev *sensor)
++{
++ /* read HTS from register settings */
++ u16 hts;
++ int ret;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++#endif
++
++static int ov4689_get_vts(struct ov4689_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++#ifdef UNUSED_CODE
++static int ov4689_set_vts(struct ov4689_dev *sensor, int vts)
++{
++ return ov4689_write_reg16(sensor, OV4689_REG_TIMING_VTS, vts);
++}
++
++static int ov4689_get_light_freq(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_bandingfilter(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_ae_target(struct ov4689_dev *sensor, int target)
++{
++ return 0;
++}
++
++static int ov4689_get_binning(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_binning(struct ov4689_dev *sensor, bool enable)
++{
++ return 0;
++}
++#endif
++
++static const struct ov4689_mode_info *
++ov4689_find_mode(struct ov4689_dev *sensor, enum ov4689_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct ov4689_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(ov4689_mode_data,
++ ARRAY_SIZE(ov4689_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (ov4689_framerates[fr] > ov4689_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 ov4689_calc_pixel_rate(struct ov4689_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vact * sensor->current_mode->hact;
++ rate *= ov4689_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++/*
++ * After trying the various combinations, reading various
++ * documentations spread around the net, and from the various
++ * feedback, the clock tree is probably as follows:
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL1 | - reg 0x030a, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x0300, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x0301~0x0302, for the multiplier
++ * | +--------------+
++ * +->| MIPI Divider | - reg 0x0303, bits 0-3 for the pre-divider
++ * | +---------> MIPI PHY CLK
++ * | +-----+
++ * | +->| PLL1_DIV_MIPI | - reg 0x0304, bits 0-1 for the divider
++ * | +----------------> PCLK
++ * | +-----+
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL2 | - reg 0x0311, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x030b, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x030c~0x030d, for the multiplier
++ * | +--------------+
++ * +->| SCLK Divider | - reg 0x030F, bits 0-3 for the pre-divider
++ * +-+--------+ - reg 0x030E, bits 0-2 for the divider
++ * | +---------> SCLK
++ *
++ * | +-----+
++ * +->| DAC Divider | - reg 0x0312, bits 0-3 for the divider
++ * | +----------------> DACCLK
++ **
++ */
++
++/*
++ * ov4689_set_mipi_pclk() - Calculate the clock tree configuration values
++ * for the MIPI CSI-2 output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * bpl = HTOT * VTOT * FPS * bpp / num_lanes;
++ *
++ * This function use the requested bandwidth to calculate:
++ *
++ * - mipi_pclk = bpl / 2; ( / 2 is for CSI-2 DDR)
++ * - mipi_phy_clk = mipi_pclk * PLL1_DIV_MIPI;
++ *
++ * with these fixed parameters:
++ * PLL1_PREDIVP = 1;
++ * PLL1_PREDIV = 1; (MIPI_BIT_MODE == 8 ? 2 : 2,5);
++ * PLL1_DIVM = 1;
++ * PLL1_DIV_MIPI = 4;
++ *
++ * FIXME: this have been tested with 10-bit raw and 2 lanes setup only.
++ * MIPI_DIV is fixed to value 2, but it -might- be changed according to the
++ * above formula for setups with 1 lane or image formats with different bpp.
++ *
++ * FIXME: this deviates from the sensor manual documentation which is quite
++ * thin on the MIPI clock tree generation part.
++ */
++
++#define PLL1_PREDIVP 1 // bypass
++#define PLL1_PREDIV 1 // bypass
++#define PLL1_DIVM 1 // bypass
++#define PLL1_DIV_MIPI 3 // div
++#define PLL1_DIV_MIPI_BASE 1 // div
++
++#define PLL1_DIVSP 1 // no use
++#define PLL1_DIVS 1 // no use
++
++#define PLL2_PREDIVP 0
++#define PLL2_PREDIV 0
++#define PLL2_DIVSP 1
++#define PLL2_DIVS 4
++#define PLL2_DIVDAC 1
++
++#define OV4689_PLL1_PREDIVP 0x030a // bits[0]
++#define OV4689_PLL1_PREDIV 0x0300 // bits[2:0]
++#define OV4689_PLL1_MULTIPLIER 0x0301 // bits[9:8] 0x0302 bits[7:0]
++#define OV4689_PLL1_DIVM 0x0303 // bits[3:0]
++#define OV4689_PLL1_DIV_MIPI 0x0304 // bits[1:0]
++
++#define OV4689_PLL1_DIVSP 0x0305 //bits[1:0]
++#define OV4689_PLL1_DIVS 0x0306 // bits[0]
++
++#define OV4689_PLL2_PREDIVP 0x0311 // bits[0]
++#define OV4689_PLL2_PREDIV 0x030b // bits[2:0]
++#define OV4689_PLL2_MULTIPLIER 0x030c // bits[9:8] 0x030d bits[7:0]
++#define OV4689_PLL2_DIVSP 0x030f // bits[3:0]
++#define OV4689_PLL2_DIVS 0x030e // bits[2:0]
++#define OV4689_PLL2_DIVDAC 0x0312 // bits[3:0]
++
++static int ov4689_set_mipi_pclk(struct ov4689_dev *sensor,
++ unsigned long rate)
++{
++ const struct ov4689_mode_info *mode = sensor->current_mode;
++ //const struct ov4689_mode_info *orig_mode = sensor->last_mode;
++ u8 val;
++ int ret = 0;
++ int fps = ov4689_framerates[sensor->current_fr];
++ u16 htot, val16;
++
++ htot = mode->htot * ov4689_framerates[mode->max_fps] / fps;
++
++ ret = ov4689_write_reg16(sensor, OV4689_REG_TIMING_HTS, htot);
++
++ ret = ov4689_read_reg(sensor, OV4689_REG_TIMING_HTS, &val);
++ val16 = val << 8;
++ ret = ov4689_read_reg(sensor, OV4689_REG_TIMING_HTS + 1, &val);
++ val16 |= val;
++
++ st_info(ST_SENSOR, "fps = %d, max_fps = %d\n", fps, mode->max_fps);
++ st_info(ST_SENSOR, "mode->htot = 0x%x, htot = 0x%x\n", mode->htot,
++ htot);
++ st_info(ST_SENSOR, "reg: 0x%x = 0x%x\n", OV4689_REG_TIMING_HTS, val16);
++
++ return 0;
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int ov4689_set_mode_direct(struct ov4689_dev *sensor,
++ const struct ov4689_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return ov4689_load_regs(sensor, mode);
++}
++
++static int ov4689_set_mode(struct ov4689_dev *sensor)
++{
++ const struct ov4689_mode_info *mode = sensor->current_mode;
++
++ int ret = 0;
++
++ ret = ov4689_set_mode_direct(sensor, mode);
++ if (ret < 0)
++ return ret;
++
++ ret = ov4689_set_mipi_pclk(sensor, 0);
++ if (ret < 0)
++ return 0;
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++ return 0;
++}
++
++/* restore the last set video mode after chip power-on */
++static int ov4689_restore_mode(struct ov4689_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = ov4689_load_regs(sensor, &ov4689_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &ov4689_mode_init_data;
++
++ /* now restore the last capture mode */
++ ret = ov4689_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return ret;
++}
++
++static void ov4689_power(struct ov4689_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
++}
++
++static void ov4689_reset(struct ov4689_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++
++ usleep_range(5000, 25000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ usleep_range(1000, 2000);
++}
++
++static int ov4689_set_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(OV4689_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ ov4689_reset(sensor);
++ ov4689_power(sensor, true);
++
++ return 0;
++
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static int ov4689_set_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++
++ ov4689_power(sensor, false);
++ regulator_bulk_disable(OV4689_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++
++ return 0;
++}
++
++static int ov4689_try_frame_interval(struct ov4689_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct ov4689_mode_info *mode;
++ enum ov4689_frame_rate rate = OV4689_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = ov4689_framerates[OV4689_15_FPS];
++ maxfps = ov4689_framerates[OV4689_NUM_FRAMERATES - 1];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = OV4689_60_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(ov4689_framerates); i++) {
++ int curr_fps = ov4689_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++ st_info(ST_SENSOR, "best_fps = %d, fps = %d\n", best_fps, fps);
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = ov4689_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int ov4689_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++
++ if (code->index)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ return 0;
++}
++
++static int ov4689_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov4689_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum ov4689_frame_rate fr,
++ const struct ov4689_mode_info **new_mode)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ const struct ov4689_mode_info *mode;
++
++ mode = ov4689_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++
++ return 0;
++}
++
++static int ov4689_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ const struct ov4689_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = ov4689_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ ov4689_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov4689_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int ov4689_set_ctrl_hue(struct ov4689_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov4689_set_ctrl_contrast(struct ov4689_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov4689_set_ctrl_saturation(struct ov4689_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov4689_set_ctrl_white_balance(struct ov4689_dev *sensor, int awb)
++{
++ struct ov4689_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ if (!awb && (ctrls->red_balance->is_new
++ || ctrls->blue_balance->is_new)) {
++ u16 red = (u16)ctrls->red_balance->val;
++ u16 blue = (u16)ctrls->blue_balance->val;
++
++ st_info(ST_SENSOR, "red = 0x%x, blue = 0x%x\n", red, blue);
++ ret = ov4689_write_reg16(sensor, OV4689_REG_AWB_R_GAIN, red);
++ if (ret)
++ return ret;
++ ret = ov4689_write_reg16(sensor, OV4689_REG_AWB_B_GAIN, blue);
++ }
++ return ret;
++}
++
++static int ov4689_set_ctrl_exposure(struct ov4689_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct ov4689_ctrls *ctrls = &sensor->ctrls;
++ bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
++ int ret = 0;
++
++ if (!auto_exp && ctrls->exposure->is_new) {
++ u16 max_exp = 0;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_V_OUTPUT_SIZE,
++ &max_exp);
++
++ ret = ov4689_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ max_exp += ret;
++ ret = 0;
++
++ st_info(ST_SENSOR, "%s, max_exp = 0x%x\n", __func__, max_exp);
++ if (ctrls->exposure->val < max_exp)
++ ret = ov4689_set_exposure(sensor, ctrls->exposure->val);
++ }
++
++ return ret;
++}
++
++static const s64 link_freq_menu_items[] = {
++ OV4689_LINK_FREQ_500MHZ
++};
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++#define OV4689_TEST_ENABLE BIT(7)
++#define OV4689_TEST_ROLLING BIT(6) /* rolling horizontal bar */
++#define OV4689_TEST_TRANSPARENT BIT(5)
++#define OV4689_TEST_SQUARE_BW BIT(4) /* black & white squares */
++#define OV4689_TEST_BAR_STANDARD (0 << 2)
++#define OV4689_TEST_BAR_DARKER_1 (1 << 2)
++#define OV4689_TEST_BAR_DARKER_2 (2 << 2)
++#define OV4689_TEST_BAR_DARKER_3 (3 << 2)
++#define OV4689_TEST_BAR (0 << 0)
++#define OV4689_TEST_RANDOM (1 << 0)
++#define OV4689_TEST_SQUARE (2 << 0)
++#define OV4689_TEST_BLACK (3 << 0)
++
++static const u8 test_pattern_val[] = {
++ 0,
++ OV4689_TEST_ENABLE | OV4689_TEST_BAR_STANDARD |
++ OV4689_TEST_BAR,
++ OV4689_TEST_ENABLE | OV4689_TEST_ROLLING |
++ OV4689_TEST_BAR_DARKER_1 | OV4689_TEST_BAR,
++ OV4689_TEST_ENABLE | OV4689_TEST_SQUARE,
++ OV4689_TEST_ENABLE | OV4689_TEST_ROLLING | OV4689_TEST_SQUARE,
++};
++
++static int ov4689_set_ctrl_test_pattern(struct ov4689_dev *sensor, int value)
++{
++ return ov4689_write_reg(sensor, OV4689_REG_TEST_PATTERN,
++ test_pattern_val[value]);
++}
++
++static int ov4689_set_ctrl_light_freq(struct ov4689_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov4689_set_ctrl_hflip(struct ov4689_dev *sensor, int value)
++{
++ /*
++ * TIMING TC REG21:
++ * - [2]: Digital mirror
++ * - [1]: Array mirror
++ */
++ return ov4689_mod_reg(sensor, OV4689_REG_TIMING_TC_REG21,
++ BIT(2) | BIT(1),
++ (!(value ^ sensor->upside_down)) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov4689_set_ctrl_vflip(struct ov4689_dev *sensor, int value)
++{
++ /*
++ * TIMING TC REG20:
++ * - [2]: Digital vflip
++ * - [1]: Array vflip
++ */
++ return ov4689_mod_reg(sensor, OV4689_REG_TIMING_TC_REG20,
++ BIT(2) | BIT(1),
++ (value ^ sensor->upside_down) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov4689_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ val = ov4689_get_gain(sensor);
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return 0;
++}
++
++static int ov4689_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored at start streaming time.
++ */
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = ov4689_set_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = ov4689_set_ctrl_exposure(sensor, V4L2_EXPOSURE_MANUAL);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = ov4689_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = ov4689_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = ov4689_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = ov4689_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = ov4689_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = ov4689_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = ov4689_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = ov4689_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov4689_ctrl_ops = {
++ .g_volatile_ctrl = ov4689_g_volatile_ctrl,
++ .s_ctrl = ov4689_s_ctrl,
++};
++
++static int ov4689_init_controls(struct ov4689_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &ov4689_ctrl_ops;
++ struct ov4689_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ ov4689_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 0);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 1024);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 1024);
++
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 4, 0xfff8, 1, 0x4c00);
++ ctrls->anal_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
++ 0x10, 0xfff8, 1, 0x0080);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++ ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ,
++ 0, 0, link_freq_menu_items);
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ // ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ // ctrls->anal_gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int ov4689_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= OV4689_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ ov4689_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ ov4689_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int ov4689_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ //struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ struct v4l2_fract tpf;
++ int i = 0;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++ if (fie->index >= OV4689_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = ov4689_framerates[fie->index];
++
++ // ret = ov4689_try_frame_interval(sensor, &tpf,
++ // fie->width, fie->height);
++ // if (ret < 0)
++ // return -EINVAL;
++
++ pr_debug("fie->width = %d, fie->height = %d\n", fie->width, fie->height);
++ for (i = 0; i < OV4689_NUM_MODES; i++) {
++ if (fie->width == ov4689_mode_data[i].hact &&
++ fie->height == ov4689_mode_data[i].vact)
++ break;
++ }
++ if (i == OV4689_NUM_MODES)
++ return -ENOTTY;
++
++ fie->interval = tpf;
++ fie->width = ov4689_mode_data[i].hact;
++ fie->height = ov4689_mode_data[i].vact;
++
++ return 0;
++}
++
++static int ov4689_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov4689_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ const struct ov4689_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = ov4689_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = ov4689_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov4689_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov4689_stream_start(struct ov4689_dev *sensor, int enable)
++{
++ return ov4689_write_reg(sensor, OV4689_REG_STREAM_ON, enable);
++}
++
++static int ov4689_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int ret = 0;
++
++ if (enable) {
++ pm_runtime_get_sync(&sensor->i2c_client->dev);
++
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ if (ret) {
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++ return ret;
++ }
++ }
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable) {
++ ret = ov4689_restore_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_mode_change) {
++ ret = ov4689_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (sensor->ep.bus.mipi_csi2.num_data_lanes == 2) {
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_HI, 0x32);
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_LOW, 0x0c);
++ } else if (sensor->ep.bus.mipi_csi2.num_data_lanes == 4) {
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_HI, 0x72);
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_LOW, 0x00);
++ } else {
++ dev_err(&sensor->i2c_client->dev, "Unsupport lane num\n");
++ }
++
++ ret = ov4689_stream_start(sensor, enable);
++ if (ret)
++ goto out;
++ }
++ sensor->streaming += enable ? 1 : -1;
++ WARN_ON(sensor->streaming < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ if (!enable || ret)
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_subdev_core_ops ov4689_core_ops = {
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops ov4689_video_ops = {
++ .g_frame_interval = ov4689_g_frame_interval,
++ .s_frame_interval = ov4689_s_frame_interval,
++ .s_stream = ov4689_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops ov4689_pad_ops = {
++ .enum_mbus_code = ov4689_enum_mbus_code,
++ .get_fmt = ov4689_get_fmt,
++ .set_fmt = ov4689_set_fmt,
++ .enum_frame_size = ov4689_enum_frame_size,
++ .enum_frame_interval = ov4689_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops ov4689_subdev_ops = {
++ .core = &ov4689_core_ops,
++ .video = &ov4689_video_ops,
++ .pad = &ov4689_pad_ops,
++};
++
++static int ov4689_get_regulators(struct ov4689_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < OV4689_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = ov4689_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ OV4689_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int ov4689_check_chip_id(struct ov4689_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ return ret;
++ }
++
++ if (chip_id != OV4689_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV4689_CHIP_ID, chip_id);
++ return -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++
++ return 0;
++}
++
++static int ov4689_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct ov4689_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 1920;
++ fmt->height = 1080;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = ov4689_framerates[OV4689_30_FPS];
++ sensor->current_fr = OV4689_30_FPS;
++ sensor->current_mode =
++ &ov4689_mode_data[OV4689_MODE_1080P_1920_1080];
++ sensor->last_mode = sensor->current_mode;
++
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < OV4689_XCLK_MIN ||
++ sensor->xclk_freq > OV4689_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ /* request optional power down pin */
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ /* request optional reset pin */
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &ov4689_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = ov4689_get_regulators(sensor);
++ if (ret)
++ return ret;
++
++ mutex_init(&sensor->lock);
++
++ ret = ov4689_set_power_on(dev);
++ if (ret) {
++ dev_err(dev, "failed to power on\n");
++ goto entity_cleanup;
++ }
++
++ ret = ov4689_check_chip_id(sensor);
++ if (ret)
++ goto error_power_off;
++
++ ret = ov4689_init_controls(sensor);
++ if (ret)
++ goto error_power_off;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++error_power_off:
++ ov4689_set_power_off(dev);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static void ov4689_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ ov4689_set_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct i2c_device_id ov4689_id[] = {
++ { "ov4689", 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, ov4689_id);
++
++static const struct of_device_id ov4689_dt_ids[] = {
++ { .compatible = "ovti,ov4689" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ov4689_dt_ids);
++
++static const struct dev_pm_ops ov4689_pm_ops = {
++ SET_RUNTIME_PM_OPS(ov4689_set_power_off, ov4689_set_power_on, NULL)
++};
++
++static struct i2c_driver ov4689_i2c_driver = {
++ .driver = {
++ .name = "ov4689",
++ .of_match_table = ov4689_dt_ids,
++ .pm = &ov4689_pm_ops,
++ },
++ .id_table = ov4689_id,
++ .probe = ov4689_probe,
++ .remove = ov4689_remove,
++};
++
++module_i2c_driver(ov4689_i2c_driver);
++
++MODULE_DESCRIPTION("OV4689 MIPI Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/ov5640.c
+@@ -0,0 +1,3227 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Copyright (C) 2014-2017 Mentor Graphics Inc.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++/* min/typical/max system clock (xclk) frequencies */
++#define OV5640_XCLK_MIN 6000000
++#define OV5640_XCLK_MAX 54000000
++
++#define OV5640_SKIP_FRAMES 4
++
++#define OV5640_CHIP_ID 0x5640
++#define OV5640_DEFAULT_SLAVE_ID 0x3c
++
++#define OV5640_REG_SYS_RESET02 0x3002
++#define OV5640_REG_SYS_CLOCK_ENABLE02 0x3006
++#define OV5640_REG_SYS_CTRL0 0x3008
++#define OV5640_REG_SYS_CTRL0_SW_PWDN 0x42
++#define OV5640_REG_SYS_CTRL0_SW_PWUP 0x02
++#define OV5640_REG_CHIP_ID 0x300a
++#define OV5640_REG_IO_MIPI_CTRL00 0x300e
++#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017
++#define OV5640_REG_PAD_OUTPUT_ENABLE02 0x3018
++#define OV5640_REG_PAD_OUTPUT00 0x3019
++#define OV5640_REG_SYSTEM_CONTROL1 0x302e
++#define OV5640_REG_SC_PLL_CTRL0 0x3034
++#define OV5640_REG_SC_PLL_CTRL1 0x3035
++#define OV5640_REG_SC_PLL_CTRL2 0x3036
++#define OV5640_REG_SC_PLL_CTRL3 0x3037
++#define OV5640_REG_SLAVE_ID 0x3100
++#define OV5640_REG_SCCB_SYS_CTRL1 0x3103
++#define OV5640_REG_SYS_ROOT_DIVIDER 0x3108
++#define OV5640_REG_AWB_R_GAIN 0x3400
++#define OV5640_REG_AWB_G_GAIN 0x3402
++#define OV5640_REG_AWB_B_GAIN 0x3404
++#define OV5640_REG_AWB_MANUAL_CTRL 0x3406
++#define OV5640_REG_AEC_PK_EXPOSURE_HI 0x3500
++#define OV5640_REG_AEC_PK_EXPOSURE_MED 0x3501
++#define OV5640_REG_AEC_PK_EXPOSURE_LO 0x3502
++#define OV5640_REG_AEC_PK_MANUAL 0x3503
++#define OV5640_REG_AEC_PK_REAL_GAIN 0x350a
++#define OV5640_REG_AEC_PK_VTS 0x350c
++#define OV5640_REG_TIMING_DVPHO 0x3808
++#define OV5640_REG_TIMING_DVPVO 0x380a
++#define OV5640_REG_TIMING_HTS 0x380c
++#define OV5640_REG_TIMING_VTS 0x380e
++#define OV5640_REG_TIMING_TC_REG20 0x3820
++#define OV5640_REG_TIMING_TC_REG21 0x3821
++#define OV5640_REG_AEC_CTRL00 0x3a00
++#define OV5640_REG_AEC_B50_STEP 0x3a08
++#define OV5640_REG_AEC_B60_STEP 0x3a0a
++#define OV5640_REG_AEC_CTRL0D 0x3a0d
++#define OV5640_REG_AEC_CTRL0E 0x3a0e
++#define OV5640_REG_AEC_CTRL0F 0x3a0f
++#define OV5640_REG_AEC_CTRL10 0x3a10
++#define OV5640_REG_AEC_CTRL11 0x3a11
++#define OV5640_REG_AEC_CTRL1B 0x3a1b
++#define OV5640_REG_AEC_CTRL1E 0x3a1e
++#define OV5640_REG_AEC_CTRL1F 0x3a1f
++#define OV5640_REG_HZ5060_CTRL00 0x3c00
++#define OV5640_REG_HZ5060_CTRL01 0x3c01
++#define OV5640_REG_SIGMADELTA_CTRL0C 0x3c0c
++#define OV5640_REG_FRAME_CTRL01 0x4202
++#define OV5640_REG_FORMAT_CONTROL00 0x4300
++#define OV5640_REG_VFIFO_HSIZE 0x4602
++#define OV5640_REG_VFIFO_VSIZE 0x4604
++#define OV5640_REG_JPG_MODE_SELECT 0x4713
++#define OV5640_REG_CCIR656_CTRL00 0x4730
++#define OV5640_REG_POLARITY_CTRL00 0x4740
++#define OV5640_REG_MIPI_CTRL00 0x4800
++#define OV5640_REG_DEBUG_MODE 0x4814
++#define OV5640_REG_ISP_FORMAT_MUX_CTRL 0x501f
++#define OV5640_REG_PRE_ISP_TEST_SET1 0x503d
++#define OV5640_REG_SDE_CTRL0 0x5580
++#define OV5640_REG_SDE_CTRL1 0x5581
++#define OV5640_REG_SDE_CTRL3 0x5583
++#define OV5640_REG_SDE_CTRL4 0x5584
++#define OV5640_REG_SDE_CTRL5 0x5585
++#define OV5640_REG_AVG_READOUT 0x56a1
++
++enum ov5640_mode_id {
++ OV5640_MODE_QCIF_176_144 = 0,
++ OV5640_MODE_QVGA_320_240,
++ OV5640_MODE_VGA_640_480,
++ OV5640_MODE_NTSC_720_480,
++ OV5640_MODE_PAL_720_576,
++ OV5640_MODE_XGA_1024_768,
++ OV5640_MODE_720P_1280_720,
++ OV5640_MODE_1080P_1920_1080,
++ OV5640_MODE_QSXGA_2592_1944,
++ OV5640_NUM_MODES,
++};
++
++enum ov5640_frame_rate {
++ OV5640_15_FPS = 0,
++ OV5640_30_FPS,
++ OV5640_60_FPS,
++ OV5640_NUM_FRAMERATES,
++};
++
++enum ov5640_format_mux {
++ OV5640_FMT_MUX_YUV422 = 0,
++ OV5640_FMT_MUX_RGB,
++ OV5640_FMT_MUX_DITHER,
++ OV5640_FMT_MUX_RAW_DPC,
++ OV5640_FMT_MUX_SNR_RAW,
++ OV5640_FMT_MUX_RAW_CIP,
++};
++
++struct ov5640_pixfmt {
++ u32 code;
++ u32 colorspace;
++};
++
++static const struct ov5640_pixfmt ov5640_formats[] = {
++ { MEDIA_BUS_FMT_JPEG_1X8, V4L2_COLORSPACE_JPEG, },
++ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_COLORSPACE_SRGB, },
++};
++
++/*
++ * FIXME: remove this when a subdev API becomes available
++ * to set the MIPI CSI-2 virtual channel.
++ */
++static unsigned int virtual_channel;
++module_param(virtual_channel, uint, 0444);
++MODULE_PARM_DESC(virtual_channel,
++ "MIPI CSI-2 virtual channel (0..3), default 0");
++
++static const int ov5640_framerates[] = {
++ [OV5640_15_FPS] = 15,
++ [OV5640_30_FPS] = 30,
++ [OV5640_60_FPS] = 60,
++};
++
++/* regulator supplies */
++static const char * const ov5640_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define OV5640_NUM_SUPPLIES ARRAY_SIZE(ov5640_supply_name)
++
++/*
++ * Image size under 1280 * 960 are SUBSAMPLING
++ * Image size upper 1280 * 960 are SCALING
++ */
++enum ov5640_downsize_mode {
++ SUBSAMPLING,
++ SCALING,
++};
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct ov5640_mode_info {
++ enum ov5640_mode_id id;
++ enum ov5640_downsize_mode dn_mode;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct ov5640_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *auto_exp;
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *auto_gain;
++ struct v4l2_ctrl *gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct ov5640_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to OV5640 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[OV5640_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ int power_count;
++
++ struct v4l2_mbus_framefmt fmt;
++ bool pending_fmt_change;
++
++ const struct ov5640_mode_info *current_mode;
++ const struct ov5640_mode_info *last_mode;
++ enum ov5640_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct ov5640_ctrls ctrls;
++
++ u32 prev_sysclk, prev_hts;
++ u32 ae_low, ae_high, ae_target;
++
++ bool pending_mode_change;
++ int streaming;
++};
++
++static inline struct ov5640_dev *to_ov5640_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct ov5640_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov5640_dev,
++ ctrls.handler)->sd;
++}
++
++/*
++ * FIXME: all of these register tables are likely filled with
++ * entries that set the register to their power-on default values,
++ * and which are otherwise not touched by this driver. Those entries
++ * should be identified and removed to speed register load time
++ * over i2c.
++ */
++/* YUV422 UYVY VGA@30fps */
++static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
++ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
++ {0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0},
++ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
++ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
++ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
++ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
++ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
++ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
++ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
++ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
++ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
++ {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
++ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
++ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
++ {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
++ {0x501f, 0x00, 0, 0}, {0x4407, 0x04, 0, 0},
++ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x4837, 0x0a, 0, 0}, {0x3824, 0x02, 0, 0},
++ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
++ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
++ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
++ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
++ {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
++ {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
++ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
++ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
++ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
++ {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
++ {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
++ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
++ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
++ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
++ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
++ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
++ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
++ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
++ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
++ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
++ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
++ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
++ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
++ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
++ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
++ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
++ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
++ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
++ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
++ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
++ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
++ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
++ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
++ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
++ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
++ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
++ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
++ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
++ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
++ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
++ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
++ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
++ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
++ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
++ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
++ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
++ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
++ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
++ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
++ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
++};
++
++static const struct reg_value ov5640_setting_VGA_640_480[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_XGA_1024_768[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_QVGA_320_240[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_QCIF_176_144[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_NTSC_720_480[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_PAL_720_576[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_720P_1280_720[] = {
++ {0x3c07, 0x07, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
++ {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
++ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
++ {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
++ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_1080P_1920_1080[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x11, 0, 0},
++ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
++ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
++ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0},
++ {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
++ {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
++ {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0},
++ {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
++ {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
++ {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
++ {0x3a15, 0x60, 0, 0}, {0x4407, 0x04, 0, 0},
++ {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
++ {0x4005, 0x1a, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_QSXGA_2592_1944[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x11, 0, 0},
++ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
++ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
++ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
++ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 70},
++};
++
++/* power-on sensor init reg table */
++static const struct ov5640_mode_info ov5640_mode_init_data = {
++ 0, SUBSAMPLING, 640, 1896, 480, 984,
++ ov5640_init_setting_30fps_VGA,
++ ARRAY_SIZE(ov5640_init_setting_30fps_VGA),
++ OV5640_30_FPS,
++};
++
++static const struct ov5640_mode_info
++ov5640_mode_data[OV5640_NUM_MODES] = {
++ {OV5640_MODE_QCIF_176_144, SUBSAMPLING,
++ 176, 1896, 144, 984,
++ ov5640_setting_QCIF_176_144,
++ ARRAY_SIZE(ov5640_setting_QCIF_176_144),
++ OV5640_30_FPS},
++ {OV5640_MODE_QVGA_320_240, SUBSAMPLING,
++ 320, 1896, 240, 984,
++ ov5640_setting_QVGA_320_240,
++ ARRAY_SIZE(ov5640_setting_QVGA_320_240),
++ OV5640_30_FPS},
++ {OV5640_MODE_VGA_640_480, SUBSAMPLING,
++ 640, 1896, 480, 1080,
++ ov5640_setting_VGA_640_480,
++ ARRAY_SIZE(ov5640_setting_VGA_640_480),
++ OV5640_60_FPS},
++ {OV5640_MODE_NTSC_720_480, SUBSAMPLING,
++ 720, 1896, 480, 984,
++ ov5640_setting_NTSC_720_480,
++ ARRAY_SIZE(ov5640_setting_NTSC_720_480),
++ OV5640_30_FPS},
++ {OV5640_MODE_PAL_720_576, SUBSAMPLING,
++ 720, 1896, 576, 984,
++ ov5640_setting_PAL_720_576,
++ ARRAY_SIZE(ov5640_setting_PAL_720_576),
++ OV5640_30_FPS},
++ {OV5640_MODE_XGA_1024_768, SUBSAMPLING,
++ 1024, 1896, 768, 1080,
++ ov5640_setting_XGA_1024_768,
++ ARRAY_SIZE(ov5640_setting_XGA_1024_768),
++ OV5640_30_FPS},
++ {OV5640_MODE_720P_1280_720, SUBSAMPLING,
++ 1280, 1892, 720, 740,
++ ov5640_setting_720P_1280_720,
++ ARRAY_SIZE(ov5640_setting_720P_1280_720),
++ OV5640_30_FPS},
++ {OV5640_MODE_1080P_1920_1080, SCALING,
++ 1920, 2500, 1080, 1120,
++ ov5640_setting_1080P_1920_1080,
++ ARRAY_SIZE(ov5640_setting_1080P_1920_1080),
++ OV5640_30_FPS},
++ {OV5640_MODE_QSXGA_2592_1944, SCALING,
++ 2592, 2844, 1944, 1968,
++ ov5640_setting_QSXGA_2592_1944,
++ ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944),
++ OV5640_15_FPS},
++};
++
++static int ov5640_init_slave_id(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ if (client->addr == OV5640_DEFAULT_SLAVE_ID)
++ return 0;
++
++ buf[0] = OV5640_REG_SLAVE_ID >> 8;
++ buf[1] = OV5640_REG_SLAVE_ID & 0xff;
++ buf[2] = client->addr << 1;
++
++ msg.addr = OV5640_DEFAULT_SLAVE_ID;
++ msg.flags = 0;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: failed with %d\n", __func__, ret);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov5640_write_reg(struct ov5640_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov5640_read_reg(struct ov5640_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int ov5640_read_reg16(struct ov5640_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = ov5640_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int ov5640_write_reg16(struct ov5640_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = ov5640_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return ov5640_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return ov5640_write_reg(sensor, reg, val);
++}
++
++/*
++ * After trying the various combinations, reading various
++ * documentations spread around the net, and from the various
++ * feedback, the clock tree is probably as follows:
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL1 | - reg 0x3036, for the multiplier
++ * +-+--------+ - reg 0x3037, bits 0-3 for the pre-divider
++ * | +--------------+
++ * +->| System Clock | - reg 0x3035, bits 4-7
++ * +-+------------+
++ * | +--------------+
++ * +->| MIPI Divider | - reg 0x3035, bits 0-3
++ * | +-+------------+
++ * | +----------------> MIPI SCLK
++ * | + +-----+
++ * | +->| / 2 |-------> MIPI BIT CLK
++ * | +-----+
++ * | +--------------+
++ * +->| PLL Root Div | - reg 0x3037, bit 4
++ * +-+------------+
++ * | +---------+
++ * +->| Bit Div | - reg 0x3034, bits 0-3
++ * +-+-------+
++ * | +-------------+
++ * +->| SCLK Div | - reg 0x3108, bits 0-1
++ * | +-+-----------+
++ * | +---------------> SCLK
++ * | +-------------+
++ * +->| SCLK 2X Div | - reg 0x3108, bits 2-3
++ * | +-+-----------+
++ * | +---------------> SCLK 2X
++ * | +-------------+
++ * +->| PCLK Div | - reg 0x3108, bits 4-5
++ * ++------------+
++ * + +-----------+
++ * +->| P_DIV | - reg 0x3035, bits 0-3
++ * +-----+-----+
++ * +------------> PCLK
++ *
++ * This is deviating from the datasheet at least for the register
++ * 0x3108, since it's said here that the PCLK would be clocked from
++ * the PLL.
++ *
++ * There seems to be also (unverified) constraints:
++ * - the PLL pre-divider output rate should be in the 4-27MHz range
++ * - the PLL multiplier output rate should be in the 500-1000MHz range
++ * - PCLK >= SCLK * 2 in YUV, >= SCLK in Raw or JPEG
++ *
++ * In the two latter cases, these constraints are met since our
++ * factors are hardcoded. If we were to change that, we would need to
++ * take this into account. The only varying parts are the PLL
++ * multiplier and the system clock divider, which are shared between
++ * all these clocks so won't cause any issue.
++ */
++
++/*
++ * This is supposed to be ranging from 1 to 8, but the value is always
++ * set to 3 in the vendor kernels.
++ */
++#define OV5640_PLL_PREDIV 3
++
++#define OV5640_PLL_MULT_MIN 4
++#define OV5640_PLL_MULT_MAX 252
++
++/*
++ * This is supposed to be ranging from 1 to 16, but the value is
++ * always set to either 1 or 2 in the vendor kernels.
++ */
++#define OV5640_SYSDIV_MIN 1
++#define OV5640_SYSDIV_MAX 16
++
++/*
++ * Hardcode these values for scaler and non-scaler modes.
++ * FIXME: to be re-calcualted for 1 data lanes setups
++ */
++#define OV5640_MIPI_DIV_PCLK 2
++#define OV5640_MIPI_DIV_SCLK 1
++
++/*
++ * This is supposed to be ranging from 1 to 2, but the value is always
++ * set to 2 in the vendor kernels.
++ */
++#define OV5640_PLL_ROOT_DIV 2
++#define OV5640_PLL_CTRL3_PLL_ROOT_DIV_2 BIT(4)
++
++/*
++ * We only supports 8-bit formats at the moment
++ */
++#define OV5640_BIT_DIV 2
++#define OV5640_PLL_CTRL0_MIPI_MODE_8BIT 0x08
++
++/*
++ * This is supposed to be ranging from 1 to 8, but the value is always
++ * set to 2 in the vendor kernels.
++ */
++#define OV5640_SCLK_ROOT_DIV 2
++
++/*
++ * This is hardcoded so that the consistency is maintained between SCLK and
++ * SCLK 2x.
++ */
++#define OV5640_SCLK2X_ROOT_DIV (OV5640_SCLK_ROOT_DIV / 2)
++
++/*
++ * This is supposed to be ranging from 1 to 8, but the value is always
++ * set to 1 in the vendor kernels.
++ */
++#define OV5640_PCLK_ROOT_DIV 1
++#define OV5640_PLL_SYS_ROOT_DIVIDER_BYPASS 0x00
++
++static unsigned long ov5640_compute_sys_clk(struct ov5640_dev *sensor,
++ u8 pll_prediv, u8 pll_mult,
++ u8 sysdiv)
++{
++ unsigned long sysclk = sensor->xclk_freq / pll_prediv * pll_mult;
++
++ /* PLL1 output cannot exceed 1GHz. */
++ if (sysclk / 1000000 > 1000)
++ return 0;
++
++ return sysclk / sysdiv;
++}
++
++static unsigned long ov5640_calc_sys_clk(struct ov5640_dev *sensor,
++ unsigned long rate,
++ u8 *pll_prediv, u8 *pll_mult,
++ u8 *sysdiv)
++{
++ unsigned long best = ~0;
++ u8 best_sysdiv = 1, best_mult = 1;
++ u8 _sysdiv, _pll_mult;
++
++ for (_sysdiv = OV5640_SYSDIV_MIN;
++ _sysdiv <= OV5640_SYSDIV_MAX;
++ _sysdiv++) {
++ for (_pll_mult = OV5640_PLL_MULT_MIN;
++ _pll_mult <= OV5640_PLL_MULT_MAX;
++ _pll_mult++) {
++ unsigned long _rate;
++
++ /*
++ * The PLL multiplier cannot be odd if above
++ * 127.
++ */
++ if (_pll_mult > 127 && (_pll_mult % 2))
++ continue;
++
++ _rate = ov5640_compute_sys_clk(sensor,
++ OV5640_PLL_PREDIV,
++ _pll_mult, _sysdiv);
++
++ /*
++ * We have reached the maximum allowed PLL1 output,
++ * increase sysdiv.
++ */
++ if (!_rate)
++ break;
++
++ /*
++ * Prefer rates above the expected clock rate than
++ * below, even if that means being less precise.
++ */
++ if (_rate < rate)
++ continue;
++
++ if (abs(rate - _rate) < abs(rate - best)) {
++ best = _rate;
++ best_sysdiv = _sysdiv;
++ best_mult = _pll_mult;
++ }
++
++ if (_rate == rate)
++ goto out;
++ }
++ }
++
++out:
++ *sysdiv = best_sysdiv;
++ *pll_prediv = OV5640_PLL_PREDIV;
++ *pll_mult = best_mult;
++
++ return best;
++}
++
++/*
++ * ov5640_set_mipi_pclk() - Calculate the clock tree configuration values
++ * for the MIPI CSI-2 output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * bpl = HTOT * VTOT * FPS * bpp / num_lanes;
++ *
++ * This function use the requested bandwidth to calculate:
++ * - sample_rate = bpl / (bpp / num_lanes);
++ * = bpl / (PLL_RDIV * BIT_DIV * PCLK_DIV * MIPI_DIV / num_lanes);
++ *
++ * - mipi_sclk = bpl / MIPI_DIV / 2; ( / 2 is for CSI-2 DDR)
++ *
++ * with these fixed parameters:
++ * PLL_RDIV = 2;
++ * BIT_DIVIDER = 2; (MIPI_BIT_MODE == 8 ? 2 : 2,5);
++ * PCLK_DIV = 1;
++ *
++ * The MIPI clock generation differs for modes that use the scaler and modes
++ * that do not. In case the scaler is in use, the MIPI_SCLK generates the MIPI
++ * BIT CLk, and thus:
++ *
++ * - mipi_sclk = bpl / MIPI_DIV / 2;
++ * MIPI_DIV = 1;
++ *
++ * For modes that do not go through the scaler, the MIPI BIT CLOCK is generated
++ * from the pixel clock, and thus:
++ *
++ * - sample_rate = bpl / (bpp / num_lanes);
++ * = bpl / (2 * 2 * 1 * MIPI_DIV / num_lanes);
++ * = bpl / (4 * MIPI_DIV / num_lanes);
++ * - MIPI_DIV = bpp / (4 * num_lanes);
++ *
++ * FIXME: this have been tested with 16bpp and 2 lanes setup only.
++ * MIPI_DIV is fixed to value 2, but it -might- be changed according to the
++ * above formula for setups with 1 lane or image formats with different bpp.
++ *
++ * FIXME: this deviates from the sensor manual documentation which is quite
++ * thin on the MIPI clock tree generation part.
++ */
++static int ov5640_set_mipi_pclk(struct ov5640_dev *sensor,
++ unsigned long rate)
++{
++ const struct ov5640_mode_info *mode = sensor->current_mode;
++ u8 prediv, mult, sysdiv;
++ u8 mipi_div;
++ int ret;
++
++ /*
++ * 1280x720 is reported to use 'SUBSAMPLING' only,
++ * but according to the sensor manual it goes through the
++ * scaler before subsampling.
++ */
++ if (mode->dn_mode == SCALING ||
++ (mode->id == OV5640_MODE_720P_1280_720))
++ mipi_div = OV5640_MIPI_DIV_SCLK;
++ else
++ mipi_div = OV5640_MIPI_DIV_PCLK;
++
++ ov5640_calc_sys_clk(sensor, rate, &prediv, &mult, &sysdiv);
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL0,
++ 0x0f, OV5640_PLL_CTRL0_MIPI_MODE_8BIT);
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1,
++ 0xff, sysdiv << 4 | mipi_div);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL2, 0xff, mult);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL3,
++ 0x1f, OV5640_PLL_CTRL3_PLL_ROOT_DIV_2 | prediv);
++ if (ret)
++ return ret;
++
++ return ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER,
++ 0x30, OV5640_PLL_SYS_ROOT_DIVIDER_BYPASS);
++}
++
++static unsigned long ov5640_calc_pclk(struct ov5640_dev *sensor,
++ unsigned long rate,
++ u8 *pll_prediv, u8 *pll_mult, u8 *sysdiv,
++ u8 *pll_rdiv, u8 *bit_div, u8 *pclk_div)
++{
++ unsigned long _rate = rate * OV5640_PLL_ROOT_DIV * OV5640_BIT_DIV *
++ OV5640_PCLK_ROOT_DIV;
++
++ _rate = ov5640_calc_sys_clk(sensor, _rate, pll_prediv, pll_mult,
++ sysdiv);
++ *pll_rdiv = OV5640_PLL_ROOT_DIV;
++ *bit_div = OV5640_BIT_DIV;
++ *pclk_div = OV5640_PCLK_ROOT_DIV;
++
++ return _rate / *pll_rdiv / *bit_div / *pclk_div;
++}
++
++static int ov5640_set_dvp_pclk(struct ov5640_dev *sensor, unsigned long rate)
++{
++ u8 prediv, mult, sysdiv, pll_rdiv, bit_div, pclk_div;
++ int ret;
++
++ ov5640_calc_pclk(sensor, rate, &prediv, &mult, &sysdiv, &pll_rdiv,
++ &bit_div, &pclk_div);
++
++#ifndef CONFIG_VIN_SENSOR_OV5640
++ if (bit_div == 2)
++ bit_div = 8;
++#else
++ bit_div = 0xa;
++#endif
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL0,
++ 0x0f, bit_div);
++ if (ret)
++ return ret;
++
++ /*
++ * We need to set sysdiv according to the clock, and to clear
++ * the MIPI divider.
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1,
++ 0xff, sysdiv << 4);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL2,
++ 0xff, mult);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL3,
++ 0x1f, prediv | ((pll_rdiv - 1) << 4));
++ if (ret)
++ return ret;
++
++ return ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x30,
++ (ilog2(pclk_div) << 4));
++}
++
++/* set JPEG framing sizes */
++static int ov5640_set_jpeg_timings(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ int ret;
++
++ /*
++ * compression mode 3 timing
++ *
++ * Data is transmitted with programmable width (VFIFO_HSIZE).
++ * No padding done. Last line may have less data. Varying
++ * number of lines per frame, depending on amount of data.
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_JPG_MODE_SELECT, 0x7, 0x3);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_VFIFO_HSIZE, mode->hact);
++ if (ret < 0)
++ return ret;
++
++ return ov5640_write_reg16(sensor, OV5640_REG_VFIFO_VSIZE, mode->vact);
++}
++
++/* download ov5640 settings to sensor through i2c */
++static int ov5640_set_timings(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ int ret;
++
++ if (sensor->fmt.code == MEDIA_BUS_FMT_JPEG_1X8) {
++ ret = ov5640_set_jpeg_timings(sensor, mode);
++ if (ret < 0)
++ return ret;
++ }
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
++ if (ret < 0)
++ return ret;
++
++ return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
++}
++
++static int ov5640_load_regs(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ st_info(ST_SENSOR, "%s, mode = 0x%x\n", __func__, mode->id);
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ /* remain in power down mode for DVP */
++ if (regs->reg_addr == OV5640_REG_SYS_CTRL0 &&
++ val == OV5640_REG_SYS_CTRL0_SW_PWUP &&
++ sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY)
++ continue;
++
++ if (mask)
++ ret = ov5640_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = ov5640_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return ov5640_set_timings(sensor, mode);
++}
++
++static int ov5640_set_autoexposure(struct ov5640_dev *sensor, bool on)
++{
++ return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
++ BIT(0), on ? 0 : BIT(0));
++}
++
++/* read exposure, in number of line periods */
++static int ov5640_get_exposure(struct ov5640_dev *sensor)
++{
++ int exp, ret;
++ u8 temp;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_PK_EXPOSURE_HI, &temp);
++ if (ret)
++ return ret;
++ exp = ((int)temp & 0x0f) << 16;
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_PK_EXPOSURE_MED, &temp);
++ if (ret)
++ return ret;
++ exp |= ((int)temp << 8);
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_PK_EXPOSURE_LO, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp;
++
++ return exp >> 4;
++}
++
++/* write exposure, given number of line periods */
++static int ov5640_set_exposure(struct ov5640_dev *sensor, u32 exposure)
++{
++ int ret;
++
++ exposure <<= 4;
++
++ ret = ov5640_write_reg(sensor,
++ OV5640_REG_AEC_PK_EXPOSURE_LO,
++ exposure & 0xff);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor,
++ OV5640_REG_AEC_PK_EXPOSURE_MED,
++ (exposure >> 8) & 0xff);
++ if (ret)
++ return ret;
++ return ov5640_write_reg(sensor,
++ OV5640_REG_AEC_PK_EXPOSURE_HI,
++ (exposure >> 16) & 0x0f);
++}
++
++static int ov5640_get_gain(struct ov5640_dev *sensor)
++{
++ u16 gain;
++ int ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN, &gain);
++ if (ret)
++ return ret;
++
++ return gain & 0x3ff;
++}
++
++static int ov5640_set_gain(struct ov5640_dev *sensor, int gain)
++{
++ return ov5640_write_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN,
++ (u16)gain & 0x3ff);
++}
++
++static int ov5640_set_autogain(struct ov5640_dev *sensor, bool on)
++{
++ return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
++ BIT(1), on ? 0 : BIT(1));
++}
++
++static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
++{
++ return ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, on ?
++ OV5640_REG_SYS_CTRL0_SW_PWUP :
++ OV5640_REG_SYS_CTRL0_SW_PWDN);
++}
++
++static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
++{
++ int ret;
++
++ /*
++ * Enable/disable the MIPI interface
++ *
++ * 0x300e = on ? 0x45 : 0x40
++ *
++ * FIXME: the sensor manual (version 2.03) reports
++ * [7:5] = 000 : 1 data lane mode
++ * [7:5] = 001 : 2 data lanes mode
++ * But this settings do not work, while the following ones
++ * have been validated for 2 data lanes mode.
++ *
++ * [7:5] = 010 : 2 data lanes mode
++ * [4] = 0 : Power up MIPI HS Tx
++ * [3] = 0 : Power up MIPI LS Rx
++ * [2] = 1/0 : MIPI interface enable/disable
++ * [1:0] = 01/00: FIXME: 'debug'
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00,
++ on ? 0x45 : 0x40);
++ if (ret)
++ return ret;
++
++ return ov5640_write_reg(sensor, OV5640_REG_FRAME_CTRL01,
++ on ? 0x00 : 0x0f);
++}
++
++static int ov5640_get_sysclk(struct ov5640_dev *sensor)
++{
++ /* calculate sysclk */
++ u32 xvclk = sensor->xclk_freq / 10000;
++ u32 multiplier, prediv, VCO, sysdiv, pll_rdiv;
++ u32 sclk_rdiv_map[] = {1, 2, 4, 8};
++ u32 bit_div2x = 1, sclk_rdiv, sysclk;
++ u8 temp1, temp2;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL0, &temp1);
++ if (ret)
++ return ret;
++ temp2 = temp1 & 0x0f;
++ if (temp2 == 8 || temp2 == 10)
++ bit_div2x = temp2 / 2;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL1, &temp1);
++ if (ret)
++ return ret;
++ sysdiv = temp1 >> 4;
++ if (sysdiv == 0)
++ sysdiv = 16;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL2, &temp1);
++ if (ret)
++ return ret;
++ multiplier = temp1;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL3, &temp1);
++ if (ret)
++ return ret;
++ prediv = temp1 & 0x0f;
++ pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, &temp1);
++ if (ret)
++ return ret;
++ temp2 = temp1 & 0x03;
++ sclk_rdiv = sclk_rdiv_map[temp2];
++
++ if (!prediv || !sysdiv || !pll_rdiv || !bit_div2x)
++ return -EINVAL;
++
++ VCO = xvclk * multiplier / prediv;
++
++ sysclk = VCO / sysdiv / pll_rdiv * 2 / bit_div2x / sclk_rdiv;
++
++ return sysclk;
++}
++
++static int ov5640_set_night_mode(struct ov5640_dev *sensor)
++{
++ /* read HTS from register settings */
++ u8 mode;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_CTRL00, &mode);
++ if (ret)
++ return ret;
++ mode &= 0xfb;
++ return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL00, mode);
++}
++
++static int ov5640_get_hts(struct ov5640_dev *sensor)
++{
++ /* read HTS from register settings */
++ u16 hts;
++ int ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++
++static int ov5640_get_vts(struct ov5640_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++static int ov5640_set_vts(struct ov5640_dev *sensor, int vts)
++{
++ return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, vts);
++}
++
++static int ov5640_get_light_freq(struct ov5640_dev *sensor)
++{
++ /* get banding filter value */
++ int ret, light_freq = 0;
++ u8 temp, temp1;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_HZ5060_CTRL01, &temp);
++ if (ret)
++ return ret;
++
++ if (temp & 0x80) {
++ /* manual */
++ ret = ov5640_read_reg(sensor, OV5640_REG_HZ5060_CTRL00,
++ &temp1);
++ if (ret)
++ return ret;
++ if (temp1 & 0x04) {
++ /* 50Hz */
++ light_freq = 50;
++ } else {
++ /* 60Hz */
++ light_freq = 60;
++ }
++ } else {
++ /* auto */
++ ret = ov5640_read_reg(sensor, OV5640_REG_SIGMADELTA_CTRL0C,
++ &temp1);
++ if (ret)
++ return ret;
++
++ if (temp1 & 0x01) {
++ /* 50Hz */
++ light_freq = 50;
++ } else {
++ /* 60Hz */
++ }
++ }
++
++ return light_freq;
++}
++
++static int ov5640_set_bandingfilter(struct ov5640_dev *sensor)
++{
++ u32 band_step60, max_band60, band_step50, max_band50, prev_vts;
++ int ret;
++
++ /* read preview PCLK */
++ ret = ov5640_get_sysclk(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ sensor->prev_sysclk = ret;
++ /* read preview HTS */
++ ret = ov5640_get_hts(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ sensor->prev_hts = ret;
++
++ /* read preview VTS */
++ ret = ov5640_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ prev_vts = ret;
++
++ /* calculate banding filter */
++ /* 60Hz */
++ band_step60 = sensor->prev_sysclk * 100 / sensor->prev_hts * 100 / 120;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AEC_B60_STEP, band_step60);
++ if (ret)
++ return ret;
++ if (!band_step60)
++ return -EINVAL;
++ max_band60 = (int)((prev_vts - 4) / band_step60);
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL0D, max_band60);
++ if (ret)
++ return ret;
++
++ /* 50Hz */
++ band_step50 = sensor->prev_sysclk * 100 / sensor->prev_hts;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AEC_B50_STEP, band_step50);
++ if (ret)
++ return ret;
++ if (!band_step50)
++ return -EINVAL;
++ max_band50 = (int)((prev_vts - 4) / band_step50);
++ return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL0E, max_band50);
++}
++
++static int ov5640_set_ae_target(struct ov5640_dev *sensor, int target)
++{
++ /* stable in high */
++ u32 fast_high, fast_low;
++ int ret;
++
++ sensor->ae_low = target * 23 / 25; /* 0.92 */
++ sensor->ae_high = target * 27 / 25; /* 1.08 */
++
++ fast_high = sensor->ae_high << 1;
++ if (fast_high > 255)
++ fast_high = 255;
++
++ fast_low = sensor->ae_low >> 1;
++
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL0F, sensor->ae_high);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL10, sensor->ae_low);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1B, sensor->ae_high);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1E, sensor->ae_low);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL11, fast_high);
++ if (ret)
++ return ret;
++ return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1F, fast_low);
++}
++
++static int ov5640_get_binning(struct ov5640_dev *sensor)
++{
++ u8 temp;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_TIMING_TC_REG21, &temp);
++ if (ret)
++ return ret;
++
++ return temp & BIT(0);
++}
++
++static int ov5640_set_binning(struct ov5640_dev *sensor, bool enable)
++{
++ int ret;
++
++ /*
++ * TIMING TC REG21:
++ * - [0]: Horizontal binning enable
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG21,
++ BIT(0), enable ? BIT(0) : 0);
++ if (ret)
++ return ret;
++ /*
++ * TIMING TC REG20:
++ * - [0]: Undocumented, but hardcoded init sequences
++ * are always setting REG21/REG20 bit 0 to same value...
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG20,
++ BIT(0), enable ? BIT(0) : 0);
++}
++
++static int ov5640_set_virtual_channel(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ u8 temp, channel = virtual_channel;
++ int ret;
++
++ if (channel > 3) {
++ dev_err(&client->dev,
++ "%s: wrong virtual_channel parameter, expected (0..3), got %d\n",
++ __func__, channel);
++ return -EINVAL;
++ }
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_DEBUG_MODE, &temp);
++ if (ret)
++ return ret;
++ temp &= ~(3 << 6);
++ temp |= (channel << 6);
++ return ov5640_write_reg(sensor, OV5640_REG_DEBUG_MODE, temp);
++}
++
++static const struct ov5640_mode_info *
++ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct ov5640_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(ov5640_mode_data,
++ ARRAY_SIZE(ov5640_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (ov5640_framerates[fr] > ov5640_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 ov5640_calc_pixel_rate(struct ov5640_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vtot * sensor->current_mode->htot;
++ rate *= ov5640_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++/*
++ * sensor changes between scaling and subsampling, go through
++ * exposure calculation
++ */
++static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ u32 prev_shutter, prev_gain16;
++ u32 cap_shutter, cap_gain16;
++ u32 cap_sysclk, cap_hts, cap_vts;
++ u32 light_freq, cap_bandfilt, cap_maxband;
++ u32 cap_gain16_shutter;
++ u8 average;
++ int ret;
++
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* read preview shutter */
++ ret = ov5640_get_exposure(sensor);
++ if (ret < 0)
++ return ret;
++ prev_shutter = ret;
++ ret = ov5640_get_binning(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret && mode->id != OV5640_MODE_720P_1280_720 &&
++ mode->id != OV5640_MODE_1080P_1920_1080)
++ prev_shutter *= 2;
++
++ /* read preview gain */
++ ret = ov5640_get_gain(sensor);
++ if (ret < 0)
++ return ret;
++ prev_gain16 = ret;
++
++ /* get average */
++ ret = ov5640_read_reg(sensor, OV5640_REG_AVG_READOUT, &average);
++ if (ret)
++ return ret;
++
++ /* turn off night mode for capture */
++ ret = ov5640_set_night_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ /* Write capture setting */
++ ret = ov5640_load_regs(sensor, mode);
++ if (ret < 0)
++ return ret;
++
++ /* read capture VTS */
++ ret = ov5640_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ cap_vts = ret;
++ ret = ov5640_get_hts(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ cap_hts = ret;
++
++ ret = ov5640_get_sysclk(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ cap_sysclk = ret;
++
++ /* calculate capture banding filter */
++ ret = ov5640_get_light_freq(sensor);
++ if (ret < 0)
++ return ret;
++ light_freq = ret;
++
++ if (light_freq == 60) {
++ /* 60Hz */
++ cap_bandfilt = cap_sysclk * 100 / cap_hts * 100 / 120;
++ } else {
++ /* 50Hz */
++ cap_bandfilt = cap_sysclk * 100 / cap_hts;
++ }
++
++ if (!sensor->prev_sysclk) {
++ ret = ov5640_get_sysclk(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ sensor->prev_sysclk = ret;
++ }
++
++ if (!cap_bandfilt)
++ return -EINVAL;
++
++ cap_maxband = (int)((cap_vts - 4) / cap_bandfilt);
++
++ /* calculate capture shutter/gain16 */
++ if (average > sensor->ae_low && average < sensor->ae_high) {
++ /* in stable range */
++ cap_gain16_shutter =
++ prev_gain16 * prev_shutter *
++ cap_sysclk / sensor->prev_sysclk *
++ sensor->prev_hts / cap_hts *
++ sensor->ae_target / average;
++ } else {
++ cap_gain16_shutter =
++ prev_gain16 * prev_shutter *
++ cap_sysclk / sensor->prev_sysclk *
++ sensor->prev_hts / cap_hts;
++ }
++
++ /* gain to shutter */
++ if (cap_gain16_shutter < (cap_bandfilt * 16)) {
++ /* shutter < 1/100 */
++ cap_shutter = cap_gain16_shutter / 16;
++ if (cap_shutter < 1)
++ cap_shutter = 1;
++
++ cap_gain16 = cap_gain16_shutter / cap_shutter;
++ if (cap_gain16 < 16)
++ cap_gain16 = 16;
++ } else {
++ if (cap_gain16_shutter > (cap_bandfilt * cap_maxband * 16)) {
++ /* exposure reach max */
++ cap_shutter = cap_bandfilt * cap_maxband;
++ if (!cap_shutter)
++ return -EINVAL;
++
++ cap_gain16 = cap_gain16_shutter / cap_shutter;
++ } else {
++ /* 1/100 < (cap_shutter = n/100) =< max */
++ cap_shutter =
++ ((int)(cap_gain16_shutter / 16 / cap_bandfilt))
++ * cap_bandfilt;
++ if (!cap_shutter)
++ return -EINVAL;
++
++ cap_gain16 = cap_gain16_shutter / cap_shutter;
++ }
++ }
++
++ /* set capture gain */
++ ret = ov5640_set_gain(sensor, cap_gain16);
++ if (ret)
++ return ret;
++
++ /* write capture shutter */
++ if (cap_shutter > (cap_vts - 4)) {
++ cap_vts = cap_shutter + 4;
++ ret = ov5640_set_vts(sensor, cap_vts);
++ if (ret < 0)
++ return ret;
++ }
++
++ /* set exposure */
++ return ov5640_set_exposure(sensor, cap_shutter);
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int ov5640_set_mode_direct(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return ov5640_load_regs(sensor, mode);
++}
++
++static int ov5640_set_mode(struct ov5640_dev *sensor)
++{
++ const struct ov5640_mode_info *mode = sensor->current_mode;
++ const struct ov5640_mode_info *orig_mode = sensor->last_mode;
++ enum ov5640_downsize_mode dn_mode, orig_dn_mode;
++ bool auto_gain = sensor->ctrls.auto_gain->val == 1;
++ bool auto_exp = sensor->ctrls.auto_exp->val == V4L2_EXPOSURE_AUTO;
++ unsigned long rate;
++ int ret;
++
++ dn_mode = mode->dn_mode;
++ orig_dn_mode = orig_mode->dn_mode;
++
++ /* auto gain and exposure must be turned off when changing modes */
++ if (auto_gain) {
++ ret = ov5640_set_autogain(sensor, false);
++ if (ret)
++ return ret;
++ }
++
++ if (auto_exp) {
++ ret = ov5640_set_autoexposure(sensor, false);
++ if (ret)
++ goto restore_auto_gain;
++ }
++
++ /*
++ * All the formats we support have 16 bits per pixel, seems to require
++ * the same rate than YUV, so we can just use 16 bpp all the time.
++ */
++ rate = ov5640_calc_pixel_rate(sensor) * 16;
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
++ rate = rate / sensor->ep.bus.mipi_csi2.num_data_lanes;
++ ret = ov5640_set_mipi_pclk(sensor, rate);
++ } else {
++ rate = rate / sensor->ep.bus.parallel.bus_width;
++ ret = ov5640_set_dvp_pclk(sensor, rate);
++ }
++
++ if (ret < 0)
++ return 0;
++
++ if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
++ (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
++ /*
++ * change between subsampling and scaling
++ * go through exposure calculation
++ */
++ ret = ov5640_set_mode_exposure_calc(sensor, mode);
++ } else {
++ /*
++ * change inside subsampling or scaling
++ * download firmware directly
++ */
++ ret = ov5640_set_mode_direct(sensor, mode);
++ }
++ if (ret < 0)
++ goto restore_auto_exp_gain;
++
++ /* restore auto gain and exposure */
++ if (auto_gain)
++ ov5640_set_autogain(sensor, true);
++ if (auto_exp)
++ ov5640_set_autoexposure(sensor, true);
++
++ ret = ov5640_set_binning(sensor, dn_mode != SCALING);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_set_ae_target(sensor, sensor->ae_target);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_get_light_freq(sensor);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_set_bandingfilter(sensor);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_set_virtual_channel(sensor);
++ if (ret < 0)
++ return ret;
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++
++ return 0;
++
++restore_auto_exp_gain:
++ if (auto_exp)
++ ov5640_set_autoexposure(sensor, true);
++restore_auto_gain:
++ if (auto_gain)
++ ov5640_set_autogain(sensor, true);
++
++ return ret;
++}
++
++static int ov5640_set_framefmt(struct ov5640_dev *sensor,
++ struct v4l2_mbus_framefmt *format);
++
++/* restore the last set video mode after chip power-on */
++static int ov5640_restore_mode(struct ov5640_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = ov5640_load_regs(sensor, &ov5640_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &ov5640_mode_init_data;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x3f,
++ (ilog2(OV5640_SCLK2X_ROOT_DIV) << 2) |
++ ilog2(OV5640_SCLK_ROOT_DIV));
++ if (ret)
++ return ret;
++
++ /* now restore the last capture mode */
++ ret = ov5640_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return ov5640_set_framefmt(sensor, &sensor->fmt);
++}
++
++static void ov5640_power(struct ov5640_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
++}
++
++static void ov5640_reset(struct ov5640_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++
++ /* camera power cycle */
++ ov5640_power(sensor, false);
++ usleep_range(5000, 10000);
++ ov5640_power(sensor, true);
++ usleep_range(5000, 10000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ usleep_range(1000, 2000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++ usleep_range(20000, 25000);
++}
++
++static int ov5640_set_power_on(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ ov5640_reset(sensor);
++ ov5640_power(sensor, true);
++
++ ret = ov5640_init_slave_id(sensor);
++ if (ret)
++ goto power_off;
++
++ return 0;
++
++power_off:
++ ov5640_power(sensor, false);
++ regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static void ov5640_set_power_off(struct ov5640_dev *sensor)
++{
++ ov5640_power(sensor, false);
++ regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++}
++
++static int ov5640_set_power_mipi(struct ov5640_dev *sensor, bool on)
++{
++ int ret;
++
++ if (!on) {
++ /* Reset MIPI bus settings to their default values. */
++ ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
++ ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x04);
++ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x00);
++ return 0;
++ }
++
++ /*
++ * Power up MIPI HS Tx and LS Rx; 2 data lanes mode
++ *
++ * 0x300e = 0x40
++ * [7:5] = 010 : 2 data lanes mode (see FIXME note in
++ * "ov5640_set_stream_mipi()")
++ * [4] = 0 : Power up MIPI HS Tx
++ * [3] = 0 : Power up MIPI LS Rx
++ * [2] = 0 : MIPI interface disabled
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x40);
++ if (ret)
++ return ret;
++
++ /*
++ * Gate clock and set LP11 in 'no packets mode' (idle)
++ *
++ * 0x4800 = 0x24
++ * [5] = 1 : Gate clock when 'no packets'
++ * [2] = 1 : MIPI bus in LP11 when 'no packets'
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x24);
++ if (ret)
++ return ret;
++
++ /*
++ * Set data lanes and clock in LP11 when 'sleeping'
++ *
++ * 0x3019 = 0x70
++ * [6] = 1 : MIPI data lane 2 in LP11 when 'sleeping'
++ * [5] = 1 : MIPI data lane 1 in LP11 when 'sleeping'
++ * [4] = 1 : MIPI clock lane in LP11 when 'sleeping'
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x70);
++ if (ret)
++ return ret;
++
++ /* Give lanes some time to coax into LP11 state. */
++ usleep_range(500, 1000);
++
++ return 0;
++}
++
++static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on)
++{
++ unsigned int flags = sensor->ep.bus.parallel.flags;
++ bool bt656 = sensor->ep.bus_type == V4L2_MBUS_BT656;
++ u8 polarities = 0;
++ int ret;
++
++ if (!on) {
++ /* Reset settings to their default values. */
++ ov5640_write_reg(sensor, OV5640_REG_CCIR656_CTRL00, 0x00);
++ ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
++ ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, 0x20);
++ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x00);
++ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0x00);
++ return 0;
++ }
++
++ /*
++ * Note about parallel port configuration.
++ *
++ * When configured in parallel mode, the OV5640 will
++ * output 10 bits data on DVP data lines [9:0].
++ * If only 8 bits data are wanted, the 8 bits data lines
++ * of the camera interface must be physically connected
++ * on the DVP data lines [9:2].
++ *
++ * Control lines polarity can be configured through
++ * devicetree endpoint control lines properties.
++ * If no endpoint control lines properties are set,
++ * polarity will be as below:
++ * - VSYNC: active high
++ * - HREF: active low
++ * - PCLK: active low
++ *
++ * VSYNC & HREF are not configured if BT656 bus mode is selected
++ */
++
++ /*
++ * BT656 embedded synchronization configuration
++ *
++ * CCIR656 CTRL00
++ * - [7]: SYNC code selection (0: auto generate sync code,
++ * 1: sync code from regs 0x4732-0x4735)
++ * - [6]: f value in CCIR656 SYNC code when fixed f value
++ * - [5]: Fixed f value
++ * - [4:3]: Blank toggle data options (00: data=1'h040/1'h200,
++ * 01: data from regs 0x4736-0x4738, 10: always keep 0)
++ * - [1]: Clip data disable
++ * - [0]: CCIR656 mode enable
++ *
++ * Default CCIR656 SAV/EAV mode with default codes
++ * SAV=0xff000080 & EAV=0xff00009d is enabled here with settings:
++ * - CCIR656 mode enable
++ * - auto generation of sync codes
++ * - blank toggle data 1'h040/1'h200
++ * - clip reserved data (0x00 & 0xff changed to 0x01 & 0xfe)
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_CCIR656_CTRL00,
++ bt656 ? 0x01 : 0x00);
++ if (ret)
++ return ret;
++
++ /*
++ * configure parallel port control lines polarity
++ *
++ * POLARITY CTRL0
++ * - [5]: PCLK polarity (0: active low, 1: active high)
++ * - [1]: HREF polarity (0: active low, 1: active high)
++ * - [0]: VSYNC polarity (mismatch here between
++ * datasheet and hardware, 0 is active high
++ * and 1 is active low...)
++ */
++ if (!bt656) {
++ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
++ polarities |= BIT(1);
++ if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
++ polarities |= BIT(0);
++ }
++ if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
++ polarities |= BIT(5);
++
++ ret = ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, polarities);
++ if (ret)
++ return ret;
++
++ /*
++ * powerdown MIPI TX/RX PHY & enable DVP
++ *
++ * MIPI CONTROL 00
++ * [4] = 1 : Power down MIPI HS Tx
++ * [3] = 1 : Power down MIPI LS Rx
++ * [2] = 0 : DVP enable (MIPI disable)
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
++ if (ret)
++ return ret;
++
++ /*
++ * enable VSYNC/HREF/PCLK DVP control lines
++ * & D[9:6] DVP data lines
++ *
++ * PAD OUTPUT ENABLE 01
++ * - 6: VSYNC output enable
++ * - 5: HREF output enable
++ * - 4: PCLK output enable
++ * - [3:0]: D[9:6] output enable
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01,
++ bt656 ? 0x1f : 0x7f);
++ if (ret)
++ return ret;
++
++ /*
++ * enable D[5:0] DVP data lines
++ *
++ * PAD OUTPUT ENABLE 02
++ * - [7:2]: D[5:0] output enable
++ */
++ return ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0xfc);
++}
++
++static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
++{
++ int ret = 0;
++
++ if (on) {
++ ret = ov5640_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++ ret = ov5640_restore_mode(sensor);
++ if (ret)
++ goto power_off;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov5640_set_power_mipi(sensor, on);
++ else
++ ret = ov5640_set_power_dvp(sensor, on);
++ if (ret)
++ goto power_off;
++
++ if (!on)
++ ov5640_set_power_off(sensor);
++
++ return 0;
++
++power_off:
++ ov5640_set_power_off(sensor);
++ return ret;
++}
++
++/* --------------- Subdev Operations --------------- */
++
++static int ov5640_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ /*
++ * If the power count is modified from 0 to != 0 or from != 0 to 0,
++ * update the power state.
++ */
++ if (sensor->power_count == !on) {
++ ret = ov5640_set_power(sensor, !!on);
++ if (ret)
++ goto out;
++ }
++
++ /* Update the power count. */
++ sensor->power_count += on ? 1 : -1;
++ WARN_ON(sensor->power_count < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ if (on && !ret && sensor->power_count == 1) {
++ /* restore controls */
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ }
++
++ return ret;
++}
++
++static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct ov5640_mode_info *mode;
++ enum ov5640_frame_rate rate = OV5640_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = ov5640_framerates[OV5640_15_FPS];
++ maxfps = ov5640_framerates[OV5640_60_FPS];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = OV5640_60_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(ov5640_framerates); i++) {
++ int curr_fps = ov5640_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = ov5640_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int ov5640_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov5640_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum ov5640_frame_rate fr,
++ const struct ov5640_mode_info **new_mode)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ const struct ov5640_mode_info *mode;
++ int i;
++
++ mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ for (i = 0; i < ARRAY_SIZE(ov5640_formats); i++)
++ if (ov5640_formats[i].code == fmt->code)
++ break;
++ if (i >= ARRAY_SIZE(ov5640_formats))
++ i = 0;
++
++ fmt->code = ov5640_formats[i].code;
++ fmt->colorspace = ov5640_formats[i].colorspace;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++
++ return 0;
++}
++
++static int ov5640_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ const struct ov5640_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = ov5640_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ if (mbus_fmt->code != sensor->fmt.code)
++ sensor->pending_fmt_change = true;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ ov5640_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov5640_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov5640_set_framefmt(struct ov5640_dev *sensor,
++ struct v4l2_mbus_framefmt *format)
++{
++ int ret = 0;
++ bool is_jpeg = false;
++ u8 fmt, mux;
++
++ switch (format->code) {
++ case MEDIA_BUS_FMT_UYVY8_2X8:
++ /* YUV422, UYVY */
++ fmt = 0x3f;
++ mux = OV5640_FMT_MUX_YUV422;
++ break;
++ case MEDIA_BUS_FMT_YUYV8_2X8:
++ /* YUV422, YUYV */
++ fmt = 0x30;
++ mux = OV5640_FMT_MUX_YUV422;
++ break;
++ case MEDIA_BUS_FMT_RGB565_2X8_LE:
++ /* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */
++ fmt = 0x6F;
++ mux = OV5640_FMT_MUX_RGB;
++ break;
++ case MEDIA_BUS_FMT_RGB565_2X8_BE:
++ /* RGB565 {r[4:0],g[5:3]},{g[2:0],b[4:0]} */
++ fmt = 0x61;
++ mux = OV5640_FMT_MUX_RGB;
++ break;
++ case MEDIA_BUS_FMT_JPEG_1X8:
++ /* YUV422, YUYV */
++ fmt = 0x30;
++ mux = OV5640_FMT_MUX_YUV422;
++ is_jpeg = true;
++ break;
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ /* Raw, BGBG... / GRGR... */
++ fmt = 0x00;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ /* Raw bayer, GBGB... / RGRG... */
++ fmt = 0x01;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ /* Raw bayer, GRGR... / BGBG... */
++ fmt = 0x02;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ /* Raw bayer, RGRG... / GBGB... */
++ fmt = 0x03;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ /* FORMAT CONTROL00: YUV and RGB formatting */
++ ret = ov5640_write_reg(sensor, OV5640_REG_FORMAT_CONTROL00, fmt);
++ if (ret)
++ return ret;
++
++ /* FORMAT MUX CONTROL: ISP YUV or RGB */
++ ret = ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL, mux);
++ if (ret)
++ return ret;
++
++ /*
++ * TIMING TC REG21:
++ * - [5]: JPEG enable
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG21,
++ BIT(5), is_jpeg ? BIT(5) : 0);
++ if (ret)
++ return ret;
++
++ /*
++ * SYSTEM RESET02:
++ * - [4]: Reset JFIFO
++ * - [3]: Reset SFIFO
++ * - [2]: Reset JPEG
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_RESET02,
++ BIT(4) | BIT(3) | BIT(2),
++ is_jpeg ? 0 : (BIT(4) | BIT(3) | BIT(2)));
++ if (ret)
++ return ret;
++
++ /*
++ * CLOCK ENABLE02:
++ * - [5]: Enable JPEG 2x clock
++ * - [3]: Enable JPEG clock
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_SYS_CLOCK_ENABLE02,
++ BIT(5) | BIT(3),
++ is_jpeg ? (BIT(5) | BIT(3)) : 0);
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int ov5640_set_ctrl_hue(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ if (value) {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0,
++ BIT(0), BIT(0));
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_SDE_CTRL1, value);
++ } else {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0, BIT(0), 0);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_contrast(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ if (value) {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0,
++ BIT(2), BIT(2));
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_SDE_CTRL5,
++ value & 0xff);
++ } else {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0, BIT(2), 0);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_saturation(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ if (value) {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0,
++ BIT(1), BIT(1));
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_SDE_CTRL3,
++ value & 0xff);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_SDE_CTRL4,
++ value & 0xff);
++ } else {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0, BIT(1), 0);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_white_balance(struct ov5640_dev *sensor, int awb)
++{
++ int ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_AWB_MANUAL_CTRL,
++ BIT(0), awb ? 0 : 1);
++ if (ret)
++ return ret;
++
++ if (!awb) {
++ u16 red = (u16)sensor->ctrls.red_balance->val;
++ u16 blue = (u16)sensor->ctrls.blue_balance->val;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AWB_R_GAIN, red);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AWB_B_GAIN, blue);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct ov5640_ctrls *ctrls = &sensor->ctrls;
++ bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
++ int ret = 0;
++
++ if (ctrls->auto_exp->is_new) {
++ ret = ov5640_set_autoexposure(sensor, auto_exp);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_exp && ctrls->exposure->is_new) {
++ u16 max_exp;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_AEC_PK_VTS,
++ &max_exp);
++ if (ret)
++ return ret;
++ ret = ov5640_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ max_exp += ret;
++ ret = 0;
++
++ if (ctrls->exposure->val < max_exp)
++ ret = ov5640_set_exposure(sensor, ctrls->exposure->val);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, bool auto_gain)
++{
++ struct ov5640_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ if (ctrls->auto_gain->is_new) {
++ ret = ov5640_set_autogain(sensor, auto_gain);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_gain && ctrls->gain->is_new)
++ ret = ov5640_set_gain(sensor, ctrls->gain->val);
++
++ return ret;
++}
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++#define OV5640_TEST_ENABLE BIT(7)
++#define OV5640_TEST_ROLLING BIT(6) /* rolling horizontal bar */
++#define OV5640_TEST_TRANSPARENT BIT(5)
++#define OV5640_TEST_SQUARE_BW BIT(4) /* black & white squares */
++#define OV5640_TEST_BAR_STANDARD (0 << 2)
++#define OV5640_TEST_BAR_VERT_CHANGE_1 (1 << 2)
++#define OV5640_TEST_BAR_HOR_CHANGE (2 << 2)
++#define OV5640_TEST_BAR_VERT_CHANGE_2 (3 << 2)
++#define OV5640_TEST_BAR (0 << 0)
++#define OV5640_TEST_RANDOM (1 << 0)
++#define OV5640_TEST_SQUARE (2 << 0)
++#define OV5640_TEST_BLACK (3 << 0)
++
++static const u8 test_pattern_val[] = {
++ 0,
++ OV5640_TEST_ENABLE | OV5640_TEST_BAR_VERT_CHANGE_1 |
++ OV5640_TEST_BAR,
++ OV5640_TEST_ENABLE | OV5640_TEST_ROLLING |
++ OV5640_TEST_BAR_VERT_CHANGE_1 | OV5640_TEST_BAR,
++ OV5640_TEST_ENABLE | OV5640_TEST_SQUARE,
++ OV5640_TEST_ENABLE | OV5640_TEST_ROLLING | OV5640_TEST_SQUARE,
++};
++
++static int ov5640_set_ctrl_test_pattern(struct ov5640_dev *sensor, int value)
++{
++ return ov5640_write_reg(sensor, OV5640_REG_PRE_ISP_TEST_SET1,
++ test_pattern_val[value]);
++}
++
++static int ov5640_set_ctrl_light_freq(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_HZ5060_CTRL01, BIT(7),
++ (value == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) ?
++ 0 : BIT(7));
++ if (ret)
++ return ret;
++
++ return ov5640_mod_reg(sensor, OV5640_REG_HZ5060_CTRL00, BIT(2),
++ (value == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) ?
++ BIT(2) : 0);
++}
++
++static int ov5640_set_ctrl_hflip(struct ov5640_dev *sensor, int value)
++{
++ /*
++ * If sensor is mounted upside down, mirror logic is inversed.
++ *
++ * Sensor is a BSI (Back Side Illuminated) one,
++ * so image captured is physically mirrored.
++ * This is why mirror logic is inversed in
++ * order to cancel this mirror effect.
++ */
++
++ /*
++ * TIMING TC REG21:
++ * - [2]: ISP mirror
++ * - [1]: Sensor mirror
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG21,
++ BIT(2) | BIT(1),
++ (!(value ^ sensor->upside_down)) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov5640_set_ctrl_vflip(struct ov5640_dev *sensor, int value)
++{
++ /* If sensor is mounted upside down, flip logic is inversed */
++
++ /*
++ * TIMING TC REG20:
++ * - [2]: ISP vflip
++ * - [1]: Sensor vflip
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG20,
++ BIT(2) | BIT(1),
++ (value ^ sensor->upside_down) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ val = ov5640_get_gain(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.gain->val = val;
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ val = ov5640_get_exposure(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.exposure->val = val;
++ break;
++ }
++
++ return 0;
++}
++
++static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored right after power-up.
++ */
++ if (sensor->power_count == 0)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ ret = ov5640_set_ctrl_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ ret = ov5640_set_ctrl_exposure(sensor, ctrl->val);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = ov5640_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = ov5640_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = ov5640_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = ov5640_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = ov5640_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = ov5640_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = ov5640_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = ov5640_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov5640_ctrl_ops = {
++ .g_volatile_ctrl = ov5640_g_volatile_ctrl,
++ .s_ctrl = ov5640_s_ctrl,
++};
++
++static int ov5640_init_controls(struct ov5640_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &ov5640_ctrl_ops;
++ struct ov5640_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ ov5640_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 1);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 0);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 0);
++ /* Auto/manual exposure */
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ V4L2_EXPOSURE_AUTO);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 0);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 1);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0);
++
++ ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
++ 0, 255, 1, 64);
++ ctrls->hue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HUE,
++ 0, 359, 1, 0);
++ ctrls->contrast = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST,
++ 0, 255, 1, 0);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int ov5640_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= OV5640_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ ov5640_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ ov5640_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int ov5640_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ struct v4l2_fract tpf;
++ int ret;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++ if (fie->index >= OV5640_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = ov5640_framerates[fie->index];
++
++ ret = ov5640_try_frame_interval(sensor, &tpf,
++ fie->width, fie->height);
++ if (ret < 0)
++ return -EINVAL;
++
++ fie->interval = tpf;
++ return 0;
++}
++
++static int ov5640_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ const struct ov5640_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = ov5640_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = ov5640_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov5640_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++ if (code->index >= ARRAY_SIZE(ov5640_formats))
++ return -EINVAL;
++
++ code->code = ov5640_formats[code->index].code;
++ return 0;
++}
++
++static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable && sensor->pending_mode_change) {
++ ret = ov5640_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_fmt_change) {
++ ret = ov5640_set_framefmt(sensor, &sensor->fmt);
++ if (ret)
++ goto out;
++ sensor->pending_fmt_change = false;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov5640_set_stream_mipi(sensor, enable);
++ else
++ ret = ov5640_set_stream_dvp(sensor, enable);
++
++ if (ret)
++ goto out;
++ }
++ sensor->streaming += enable ? 1 : -1;
++ WARN_ON(sensor->streaming < 0);
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++int ov5640_skip_frames(struct v4l2_subdev *sd, u32 *frames)
++{
++ *frames = OV5640_SKIP_FRAMES;
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops ov5640_core_ops = {
++ .s_power = ov5640_s_power,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops ov5640_video_ops = {
++ .g_frame_interval = ov5640_g_frame_interval,
++ .s_frame_interval = ov5640_s_frame_interval,
++ .s_stream = ov5640_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops ov5640_pad_ops = {
++ .enum_mbus_code = ov5640_enum_mbus_code,
++ .get_fmt = ov5640_get_fmt,
++ .set_fmt = ov5640_set_fmt,
++ .enum_frame_size = ov5640_enum_frame_size,
++ .enum_frame_interval = ov5640_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_sensor_ops ov5640_sensor_ops = {
++ .g_skip_frames = ov5640_skip_frames,
++};
++
++static const struct v4l2_subdev_ops ov5640_subdev_ops = {
++ .core = &ov5640_core_ops,
++ .video = &ov5640_video_ops,
++ .pad = &ov5640_pad_ops,
++ .sensor = &ov5640_sensor_ops,
++};
++
++static int ov5640_get_regulators(struct ov5640_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < OV5640_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = ov5640_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ OV5640_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int ov5640_check_chip_id(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = ov5640_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ goto power_off;
++ }
++
++ if (chip_id != OV5640_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV5640_CHIP_ID, chip_id);
++ ret = -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++
++power_off:
++ ov5640_set_power_off(sensor);
++ return ret;
++}
++
++static int ov5640_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct ov5640_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ /*
++ * default init sequence initialize sensor to
++ * YUV422 UYVY VGA@30fps
++ */
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 640;
++ fmt->height = 480;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = ov5640_framerates[OV5640_30_FPS];
++ sensor->current_fr = OV5640_30_FPS;
++ sensor->current_mode =
++ &ov5640_mode_data[OV5640_MODE_VGA_640_480];
++ sensor->last_mode = sensor->current_mode;
++
++ sensor->ae_target = 52;
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_PARALLEL &&
++ sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY &&
++ sensor->ep.bus_type != V4L2_MBUS_BT656) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < OV5640_XCLK_MIN ||
++ sensor->xclk_freq > OV5640_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ /* request optional power down pin */
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ /* request optional reset pin */
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &ov5640_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = ov5640_get_regulators(sensor);
++ if (ret)
++ return ret;
++
++ mutex_init(&sensor->lock);
++
++ ret = ov5640_check_chip_id(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = ov5640_init_controls(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static int ov5640_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ return 0;
++}
++
++static const struct i2c_device_id ov5640_id[] = {
++ {"ov5640", 0},
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, ov5640_id);
++
++static const struct of_device_id ov5640_dt_ids[] = {
++ { .compatible = "ovti,ov5640" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ov5640_dt_ids);
++
++static struct i2c_driver ov5640_i2c_driver = {
++ .driver = {
++ .name = "ov5640",
++ .of_match_table = ov5640_dt_ids,
++ },
++ .id_table = ov5640_id,
++ .probe_new = ov5640_probe,
++ .remove = ov5640_remove,
++};
++
++module_i2c_driver(ov5640_i2c_driver);
++
++MODULE_DESCRIPTION("OV5640 MIPI Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/sc2235.c
+@@ -0,0 +1,1914 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++/* min/typical/max system clock (xclk) frequencies */
++#define SC2235_XCLK_MIN 6000000
++#define SC2235_XCLK_MAX 27000000
++
++#define SC2235_CHIP_ID (0x2235)
++
++#define SC2235_REG_CHIP_ID 0x3107
++#define SC2235_REG_AEC_PK_MANUAL 0x3e03
++#define SC2235_REG_AEC_PK_EXPOSURE_HI 0x3e01
++#define SC2235_REG_AEC_PK_EXPOSURE_LO 0x3e02
++#define SC2235_REG_AEC_PK_REAL_GAIN 0x3e08
++#define SC2235_REG_TIMING_HTS 0x320c
++#define SC2235_REG_TIMING_VTS 0x320e
++#define SC2235_REG_TEST_SET0 0x4501
++#define SC2235_REG_TEST_SET1 0x3902
++#define SC2235_REG_TIMING_TC_REG21 0x3221
++#define SC2235_REG_SC_PLL_CTRL0 0x3039
++#define SC2235_REG_SC_PLL_CTRL1 0x303a
++#define SC2235_REG_STREAM_ON 0x0100
++
++enum sc2235_mode_id {
++ SC2235_MODE_1080P_1920_1080 = 0,
++ SC2235_NUM_MODES,
++};
++
++enum sc2235_frame_rate {
++ SC2235_15_FPS = 0,
++ SC2235_30_FPS,
++ SC2235_NUM_FRAMERATES,
++};
++
++struct sc2235_pixfmt {
++ u32 code;
++ u32 colorspace;
++};
++
++static const struct sc2235_pixfmt sc2235_formats[] = {
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB, },
++};
++
++static const int sc2235_framerates[] = {
++ [SC2235_15_FPS] = 15,
++ [SC2235_30_FPS] = 30,
++};
++
++/* regulator supplies */
++static const char * const sc2235_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define SC2235_NUM_SUPPLIES ARRAY_SIZE(sc2235_supply_name)
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct sc2235_mode_info {
++ enum sc2235_mode_id id;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct sc2235_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *auto_exp;
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *auto_gain;
++ struct v4l2_ctrl *gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct sc2235_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to SC2235 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[SC2235_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ struct v4l2_mbus_framefmt fmt;
++ bool pending_fmt_change;
++
++ const struct sc2235_mode_info *current_mode;
++ const struct sc2235_mode_info *last_mode;
++ enum sc2235_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct sc2235_ctrls ctrls;
++
++ bool pending_mode_change;
++ int streaming;
++};
++
++static inline struct sc2235_dev *to_sc2235_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct sc2235_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct sc2235_dev,
++ ctrls.handler)->sd;
++}
++
++/* sc2235 initial register 30fps*/
++static struct reg_value sc2235_init_regs_tbl_1080[] = {
++ {0x0103, 0x01, 0, 50},
++ {0x0100, 0x00, 0, 0},
++ {0x3039, 0x80, 0, 0},
++ {0x3621, 0x28, 0, 0},
++
++ {0x3309, 0x60, 0, 0},
++ {0x331f, 0x4d, 0, 0},
++ {0x3321, 0x4f, 0, 0},
++ {0x33b5, 0x10, 0, 0},
++
++ {0x3303, 0x20, 0, 0},
++ {0x331e, 0x0d, 0, 0},
++ {0x3320, 0x0f, 0, 0},
++
++ {0x3622, 0x02, 0, 0},
++ {0x3633, 0x42, 0, 0},
++ {0x3634, 0x42, 0, 0},
++
++ {0x3306, 0x66, 0, 0},
++ {0x330b, 0xd1, 0, 0},
++
++ {0x3301, 0x0e, 0, 0},
++
++ {0x320c, 0x08, 0, 0},
++ {0x320d, 0x98, 0, 0},
++
++ {0x3364, 0x05, 0, 0}, // [2] 1: write at sampling ending
++
++ {0x363c, 0x28, 0, 0}, //bypass nvdd
++ {0x363b, 0x0a, 0, 0}, //HVDD
++ {0x3635, 0xa0, 0, 0}, //TXVDD
++
++ {0x4500, 0x59, 0, 0},
++ {0x3d08, 0x00, 0, 0},
++ {0x3908, 0x11, 0, 0},
++
++ {0x363c, 0x08, 0, 0},
++
++ {0x3e03, 0x03, 0, 0},
++ {0x3e01, 0x46, 0, 0},
++
++ //0703
++ {0x3381, 0x0a, 0, 0},
++ {0x3348, 0x09, 0, 0},
++ {0x3349, 0x50, 0, 0},
++ {0x334a, 0x02, 0, 0},
++ {0x334b, 0x60, 0, 0},
++
++ {0x3380, 0x04, 0, 0},
++ {0x3340, 0x06, 0, 0},
++ {0x3341, 0x50, 0, 0},
++ {0x3342, 0x02, 0, 0},
++ {0x3343, 0x60, 0, 0},
++
++ //0707
++
++ {0x3632, 0x88, 0, 0}, //anti sm
++ {0x3309, 0xa0, 0, 0},
++ {0x331f, 0x8d, 0, 0},
++ {0x3321, 0x8f, 0, 0},
++
++ {0x335e, 0x01, 0, 0}, //ana dithering
++ {0x335f, 0x03, 0, 0},
++ {0x337c, 0x04, 0, 0},
++ {0x337d, 0x06, 0, 0},
++ {0x33a0, 0x05, 0, 0},
++ {0x3301, 0x05, 0, 0},
++
++ {0x337f, 0x03, 0, 0},
++ {0x3368, 0x02, 0, 0},
++ {0x3369, 0x00, 0, 0},
++ {0x336a, 0x00, 0, 0},
++ {0x336b, 0x00, 0, 0},
++ {0x3367, 0x08, 0, 0},
++ {0x330e, 0x30, 0, 0},
++
++ {0x3366, 0x7c, 0, 0}, // div_rst gap
++
++ {0x3635, 0xc1, 0, 0},
++ {0x363b, 0x09, 0, 0},
++ {0x363c, 0x07, 0, 0},
++
++ {0x391e, 0x00, 0, 0},
++
++ {0x3637, 0x14, 0, 0}, //fullwell 7K
++
++ {0x3306, 0x54, 0, 0},
++ {0x330b, 0xd8, 0, 0},
++ {0x366e, 0x08, 0, 0}, // ofs auto en [3]
++ {0x366f, 0x2f, 0, 0},
++
++ {0x3631, 0x84, 0, 0},
++ {0x3630, 0x48, 0, 0},
++ {0x3622, 0x06, 0, 0},
++
++ //ramp by sc
++ {0x3638, 0x1f, 0, 0},
++ {0x3625, 0x02, 0, 0},
++ {0x3636, 0x24, 0, 0},
++
++ //0714
++ {0x3348, 0x08, 0, 0},
++ {0x3e03, 0x0b, 0, 0},
++
++ //7.17 fpn
++ {0x3342, 0x03, 0, 0},
++ {0x3343, 0xa0, 0, 0},
++ {0x334a, 0x03, 0, 0},
++ {0x334b, 0xa0, 0, 0},
++
++ //0718
++ {0x3343, 0xb0, 0, 0},
++ {0x334b, 0xb0, 0, 0},
++
++ //0720
++ //digital ctrl
++ {0x3802, 0x01, 0, 0},
++ {0x3235, 0x04, 0, 0},
++ {0x3236, 0x63, 0, 0}, // vts-2
++
++ //fpn
++ {0x3343, 0xd0, 0, 0},
++ {0x334b, 0xd0, 0, 0},
++ {0x3348, 0x07, 0, 0},
++ {0x3349, 0x80, 0, 0},
++
++ //0724
++ {0x391b, 0x4d, 0, 0},
++
++ {0x3342, 0x04, 0, 0},
++ {0x3343, 0x20, 0, 0},
++ {0x334a, 0x04, 0, 0},
++ {0x334b, 0x20, 0, 0},
++
++ //0804
++ {0x3222, 0x29, 0, 0},
++ {0x3901, 0x02, 0, 0},
++
++ //0808
++
++ // auto blc
++ {0x3900, 0xD5, 0, 0}, // Bit[0]: blc_enable
++ {0x3902, 0x45, 0, 0}, // Bit[6]: blc_auto_en
++
++ // blc target
++ {0x3907, 0x00, 0, 0},
++ {0x3908, 0x00, 0, 0},
++
++ // auto dpc
++ {0x5000, 0x00, 0, 0}, // Bit[2]: white dead pixel cancel enable, Bit[1]: black dead pixel cancel enable
++
++ //digital ctrl
++ {0x3f00, 0x07, 0, 0}, // bit[2] = 1
++ {0x3f04, 0x08, 0, 0},
++ {0x3f05, 0x74, 0, 0}, // hts - { 0x24
++
++ //0809
++ {0x330b, 0xc8, 0, 0},
++
++ //0817
++ {0x3306, 0x4a, 0, 0},
++ {0x330b, 0xca, 0, 0},
++ {0x3639, 0x09, 0, 0},
++
++ //manual DPC
++ {0x5780, 0xff, 0, 0},
++ {0x5781, 0x04, 0, 0},
++ {0x5785, 0x18, 0, 0},
++
++ //0822
++ {0x3039, 0x35, 0, 0}, //fps
++ {0x303a, 0x2e, 0, 0},
++ {0x3034, 0x05, 0, 0},
++ {0x3035, 0x2a, 0, 0},
++
++ {0x320c, 0x08, 0, 0},
++ {0x320d, 0xca, 0, 0},
++ {0x320e, 0x04, 0, 0},
++ {0x320f, 0xb0, 0, 0},
++
++ {0x3f04, 0x08, 0, 0},
++ {0x3f05, 0xa6, 0, 0}, // hts - { 0x24
++
++ {0x3235, 0x04, 0, 0},
++ {0x3236, 0xae, 0, 0}, // vts-2
++
++ //0825
++ {0x3313, 0x05, 0, 0},
++ {0x3678, 0x42, 0, 0},
++
++ //for AE control per frame
++ {0x3670, 0x00, 0, 0},
++ {0x3633, 0x42, 0, 0},
++
++ {0x3802, 0x00, 0, 0},
++
++ //20180126
++ {0x3677, 0x3f, 0, 0},
++ {0x3306, 0x44, 0, 0}, //20180126[3c },4a]
++ {0x330b, 0xca, 0, 0}, //20180126[c2 },d3]
++
++ //20180202
++ {0x3237, 0x08, 0, 0},
++ {0x3238, 0x9a, 0, 0}, //hts-0x30
++
++ //20180417
++ {0x3640, 0x01, 0, 0},
++ {0x3641, 0x02, 0, 0},
++
++ {0x3301, 0x12, 0, 0}, //[8 },15]20180126
++ {0x3631, 0x84, 0, 0},
++ {0x366f, 0x2f, 0, 0},
++ {0x3622, 0xc6, 0, 0}, //20180117
++
++ {0x3e03, 0x03, 0, 0}, // Bit[3]: AGC table mapping method, Bit[1]: AGC manual, BIt[0]: AEC manual
++
++ // {0x0100, 0x00, 0, 0},
++ // {0x4501, 0xc8, 0, 0}, //bar testing
++ // {0x3902, 0x45, 0, 0},
++};
++
++static struct reg_value sc2235_setting_1080P_1920_1080[] = {
++
++};
++
++/* power-on sensor init reg table */
++static const struct sc2235_mode_info sc2235_mode_init_data = {
++ SC2235_MODE_1080P_1920_1080,
++ 1920, 0x8ca, 1080, 0x4b0,
++ sc2235_init_regs_tbl_1080,
++ ARRAY_SIZE(sc2235_init_regs_tbl_1080),
++ SC2235_30_FPS,
++};
++
++static const struct sc2235_mode_info
++sc2235_mode_data[SC2235_NUM_MODES] = {
++ {SC2235_MODE_1080P_1920_1080,
++ 1920, 0x8ca, 1080, 0x4b0,
++ sc2235_setting_1080P_1920_1080,
++ ARRAY_SIZE(sc2235_setting_1080P_1920_1080),
++ SC2235_30_FPS},
++};
++
++static int sc2235_write_reg(struct sc2235_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int sc2235_read_reg(struct sc2235_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int sc2235_read_reg16(struct sc2235_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = sc2235_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = sc2235_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int sc2235_write_reg16(struct sc2235_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = sc2235_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return sc2235_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int sc2235_mod_reg(struct sc2235_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = sc2235_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return sc2235_write_reg(sensor, reg, val);
++}
++
++#define SC2235_PLL_PREDIV 3
++
++#define SC2235_SYSDIV_MIN 0
++#define SC2235_SYSDIV_MAX 7
++
++#define SC2235_PLL_MULT_MIN 0
++#define SC2235_PLL_MULT_MAX 63
++
++#ifdef UNUSED_CODE
++static unsigned long sc2235_compute_sys_clk(struct sc2235_dev *sensor,
++ u8 pll_pre, u8 pll_mult,
++ u8 sysdiv)
++{
++ unsigned long sysclk =
++ sensor->xclk_freq * (64 - pll_mult) / (pll_pre * (sysdiv + 1));
++
++ /* PLL1 output cannot exceed 1GHz. */
++ if (sysclk / 1000000 > 1000)
++ return 0;
++
++ return sysclk;
++}
++
++static unsigned long sc2235_calc_sys_clk(struct sc2235_dev *sensor,
++ unsigned long rate,
++ u8 *pll_prediv, u8 *pll_mult,
++ u8 *sysdiv)
++{
++ unsigned long best = ~0;
++ u8 best_sysdiv = 1, best_mult = 1;
++ u8 _sysdiv, _pll_mult;
++
++ for (_sysdiv = SC2235_SYSDIV_MIN;
++ _sysdiv <= SC2235_SYSDIV_MAX;
++ _sysdiv++) {
++ for (_pll_mult = SC2235_PLL_MULT_MIN;
++ _pll_mult <= SC2235_PLL_MULT_MAX;
++ _pll_mult++) {
++ unsigned long _rate;
++
++ _rate = sc2235_compute_sys_clk(sensor,
++ SC2235_PLL_PREDIV,
++ _pll_mult, _sysdiv);
++
++ /*
++ * We have reached the maximum allowed PLL1 output,
++ * increase sysdiv.
++ */
++ if (!_rate)
++ break;
++
++ /*
++ * Prefer rates above the expected clock rate than
++ * below, even if that means being less precise.
++ */
++ if (_rate < rate)
++ continue;
++
++ if (abs(rate - _rate) < abs(rate - best)) {
++ best = _rate;
++ best_sysdiv = _sysdiv;
++ best_mult = _pll_mult;
++ }
++
++ if (_rate == rate)
++ goto out;
++ }
++ }
++
++out:
++ *sysdiv = best_sysdiv;
++ *pll_prediv = SC2235_PLL_PREDIV;
++ *pll_mult = best_mult;
++
++ return best;
++}
++#endif
++
++static int sc2235_set_timings(struct sc2235_dev *sensor,
++ const struct sc2235_mode_info *mode)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int sc2235_load_regs(struct sc2235_dev *sensor,
++ const struct sc2235_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ if (mask)
++ ret = sc2235_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = sc2235_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return sc2235_set_timings(sensor, mode);
++}
++
++static int sc2235_set_autoexposure(struct sc2235_dev *sensor, bool on)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_AEC_PK_MANUAL,
++ BIT(0), on ? 0 : BIT(0));
++}
++
++static int sc2235_get_exposure(struct sc2235_dev *sensor)
++{
++ int exp = 0, ret = 0;
++ u8 temp;
++
++ ret = sc2235_read_reg(sensor, SC2235_REG_AEC_PK_EXPOSURE_HI, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp << 8;
++ ret = sc2235_read_reg(sensor, SC2235_REG_AEC_PK_EXPOSURE_LO, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp;
++
++ return exp >> 4;
++}
++
++static int sc2235_set_exposure(struct sc2235_dev *sensor, u32 exposure)
++{
++ int ret;
++
++ exposure <<= 4;
++
++ ret = sc2235_write_reg(sensor,
++ SC2235_REG_AEC_PK_EXPOSURE_LO,
++ exposure & 0xff);
++ if (ret)
++ return ret;
++ return sc2235_write_reg(sensor,
++ SC2235_REG_AEC_PK_EXPOSURE_HI,
++ (exposure >> 8) & 0xff);
++}
++
++static int sc2235_get_gain(struct sc2235_dev *sensor)
++{
++ u16 gain;
++ int ret;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_AEC_PK_REAL_GAIN, &gain);
++ if (ret)
++ return ret;
++
++ return gain & 0x1fff;
++}
++
++static int sc2235_set_gain(struct sc2235_dev *sensor, int gain)
++{
++ return sc2235_write_reg16(sensor, SC2235_REG_AEC_PK_REAL_GAIN,
++ (u16)gain & 0x1fff);
++}
++
++static int sc2235_set_autogain(struct sc2235_dev *sensor, bool on)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_AEC_PK_MANUAL,
++ BIT(1), on ? 0 : BIT(1));
++}
++
++#ifdef UNUSED_CODE
++static int sc2235_get_sysclk(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_night_mode(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_get_hts(struct sc2235_dev *sensor)
++{
++ u16 hts;
++ int ret;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++#endif
++
++static int sc2235_get_vts(struct sc2235_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++#ifdef UNUSED_CODE
++static int sc2235_set_vts(struct sc2235_dev *sensor, int vts)
++{
++ return sc2235_write_reg16(sensor, SC2235_REG_TIMING_VTS, vts);
++}
++
++static int sc2235_get_light_freq(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_bandingfilter(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_ae_target(struct sc2235_dev *sensor, int target)
++{
++ return 0;
++}
++
++static int sc2235_get_binning(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_binning(struct sc2235_dev *sensor, bool enable)
++{
++ return 0;
++}
++
++#endif
++
++static const struct sc2235_mode_info *
++sc2235_find_mode(struct sc2235_dev *sensor, enum sc2235_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct sc2235_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(sc2235_mode_data,
++ ARRAY_SIZE(sc2235_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (sc2235_framerates[fr] > sc2235_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 sc2235_calc_pixel_rate(struct sc2235_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vtot * sensor->current_mode->htot;
++ rate *= sc2235_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++#ifdef UNUSED_CODE
++/*
++ * sc2235_set_dvp_pclk() - Calculate the clock tree configuration values
++ * for the dvp output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * rate = HTOT * VTOT * FPS;
++ *
++ * This function use the requested bandwidth to calculate:
++ * - rate = xclk * (64 - M) / (N * (S + 1));
++ *
++ */
++
++#define PLL_PREDIV 1
++#define PLL_SYSEL 0
++
++static int sc2235_set_dvp_pclk(struct sc2235_dev *sensor,
++ unsigned long rate)
++{
++ u8 prediv, mult, sysdiv;
++ int ret = 0;
++
++ sc2235_calc_sys_clk(sensor, rate, &prediv, &mult,
++ &sysdiv);
++
++
++ return ret;
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int sc2235_set_mode_direct(struct sc2235_dev *sensor,
++ const struct sc2235_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return sc2235_load_regs(sensor, mode);
++}
++#endif
++
++static int sc2235_set_mode(struct sc2235_dev *sensor)
++{
++#ifdef UNUSED_CODE
++ bool auto_exp = sensor->ctrls.auto_exp->val == V4L2_EXPOSURE_AUTO;
++ const struct sc2235_mode_info *mode = sensor->current_mode;
++#endif
++ bool auto_gain = sensor->ctrls.auto_gain->val == 1;
++ int ret = 0;
++
++ /* auto gain and exposure must be turned off when changing modes */
++ if (auto_gain) {
++ ret = sc2235_set_autogain(sensor, false);
++ if (ret)
++ return ret;
++ }
++#ifdef UNUSED_CODE
++ /* This issue will be addressed in the EVB board*/
++ /* This action will result in poor image display 2021 1111*/
++ if (auto_exp) {
++ ret = sc2235_set_autoexposure(sensor, false);
++ if (ret)
++ goto restore_auto_gain;
++ }
++
++ rate = sc2235_calc_pixel_rate(sensor);
++
++ ret = sc2235_set_dvp_pclk(sensor, rate);
++ if (ret < 0)
++ return 0;
++
++ ret = sc2235_set_mode_direct(sensor, mode);
++ if (ret < 0)
++ goto restore_auto_exp_gain;
++
++ /* restore auto gain and exposure */
++ if (auto_gain)
++ sc2235_set_autogain(sensor, true);
++ if (auto_exp)
++ sc2235_set_autoexposure(sensor, true);
++
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++ return 0;
++
++restore_auto_exp_gain:
++ if (auto_exp)
++ sc2235_set_autoexposure(sensor, true);
++restore_auto_gain:
++ if (auto_gain)
++ sc2235_set_autogain(sensor, true);
++#endif
++ return ret;
++}
++
++static int sc2235_set_framefmt(struct sc2235_dev *sensor,
++ struct v4l2_mbus_framefmt *format);
++
++/* restore the last set video mode after chip power-on */
++static int sc2235_restore_mode(struct sc2235_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = sc2235_load_regs(sensor, &sc2235_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &sc2235_mode_init_data;
++ /* now restore the last capture mode */
++ ret = sc2235_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return sc2235_set_framefmt(sensor, &sensor->fmt);
++}
++
++static void sc2235_power(struct sc2235_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
++}
++
++static void sc2235_reset(struct sc2235_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++
++ /* camera power cycle */
++ sc2235_power(sensor, false);
++ usleep_range(5000, 10000);
++ sc2235_power(sensor, true);
++ usleep_range(5000, 10000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ usleep_range(1000, 2000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++ usleep_range(20000, 25000);
++}
++
++static int sc2235_set_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(SC2235_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ sc2235_reset(sensor);
++ sc2235_power(sensor, true);
++
++ return 0;
++
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static int sc2235_set_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++
++ sc2235_power(sensor, false);
++ regulator_bulk_disable(SC2235_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++
++ return 0;
++}
++
++static int sc2235_set_power(struct sc2235_dev *sensor, bool on)
++{
++ int ret = 0;
++
++ if (on) {
++ pm_runtime_get_sync(&sensor->i2c_client->dev);
++
++ ret = sc2235_restore_mode(sensor);
++ if (ret)
++ goto power_off;
++ }
++
++ if (!on)
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++
++ return 0;
++
++power_off:
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static int sc2235_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ ret = sc2235_set_power(sensor, !!on);
++ if (ret)
++ goto out;
++
++ mutex_unlock(&sensor->lock);
++ return 0;
++
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int sc2235_try_frame_interval(struct sc2235_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct sc2235_mode_info *mode;
++ enum sc2235_frame_rate rate = SC2235_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = sc2235_framerates[SC2235_15_FPS];
++ maxfps = sc2235_framerates[SC2235_30_FPS];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = SC2235_30_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(sc2235_framerates); i++) {
++ int curr_fps = sc2235_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = sc2235_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int sc2235_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int sc2235_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum sc2235_frame_rate fr,
++ const struct sc2235_mode_info **new_mode)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ const struct sc2235_mode_info *mode;
++ int i;
++
++ mode = sc2235_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ for (i = 0; i < ARRAY_SIZE(sc2235_formats); i++)
++ if (sc2235_formats[i].code == fmt->code)
++ break;
++ if (i >= ARRAY_SIZE(sc2235_formats))
++ i = 0;
++
++ fmt->code = sc2235_formats[i].code;
++ fmt->colorspace = sc2235_formats[i].colorspace;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++
++ return 0;
++}
++
++static int sc2235_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ const struct sc2235_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = sc2235_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ if (mbus_fmt->code != sensor->fmt.code)
++ sensor->pending_fmt_change = true;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ sc2235_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ sc2235_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int sc2235_set_framefmt(struct sc2235_dev *sensor,
++ struct v4l2_mbus_framefmt *format)
++{
++ int ret = 0;
++
++ switch (format->code) {
++ default:
++ return ret;
++ }
++ return ret;
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int sc2235_set_ctrl_hue(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_contrast(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_saturation(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_white_balance(struct sc2235_dev *sensor, int awb)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_exposure(struct sc2235_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct sc2235_ctrls *ctrls = &sensor->ctrls;
++ bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
++ int ret = 0;
++
++ if (ctrls->auto_exp->is_new) {
++ ret = sc2235_set_autoexposure(sensor, auto_exp);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_exp && ctrls->exposure->is_new) {
++ u16 max_exp = 0;
++
++ ret = sc2235_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ max_exp += ret - 4;
++ ret = 0;
++
++ if (ctrls->exposure->val < max_exp)
++ ret = sc2235_set_exposure(sensor, ctrls->exposure->val);
++ }
++
++ return ret;
++}
++
++static int sc2235_set_ctrl_gain(struct sc2235_dev *sensor, bool auto_gain)
++{
++ struct sc2235_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ if (ctrls->auto_gain->is_new) {
++ ret = sc2235_set_autogain(sensor, auto_gain);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_gain && ctrls->gain->is_new)
++ ret = sc2235_set_gain(sensor, ctrls->gain->val);
++
++ return ret;
++}
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Black bars",
++ "Auto Black bars",
++};
++
++#define SC2235_TEST_ENABLE BIT(3)
++#define SC2235_TEST_BLACK (3 << 0)
++
++static int sc2235_set_ctrl_test_pattern(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ /*
++ *For 7110 platform, refer to 1125 FW code configuration. This operation will cause the image to be white.
++ */
++#ifdef UNUSED_CODE
++ ret = sc2235_mod_reg(sensor, SC2235_REG_TEST_SET0, BIT(3),
++ !!value << 3);
++
++ ret |= sc2235_mod_reg(sensor, SC2235_REG_TEST_SET1, BIT(6),
++ (value >> 1) << 6);
++#endif
++ return ret;
++}
++
++static int sc2235_set_ctrl_light_freq(struct sc2235_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int sc2235_set_ctrl_hflip(struct sc2235_dev *sensor, int value)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_TIMING_TC_REG21,
++ BIT(2) | BIT(1),
++ (!(value ^ sensor->upside_down)) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int sc2235_set_ctrl_vflip(struct sc2235_dev *sensor, int value)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_TIMING_TC_REG21,
++ BIT(6) | BIT(5),
++ (value ^ sensor->upside_down) ?
++ (BIT(6) | BIT(5)) : 0);
++}
++
++static int sc2235_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ val = sc2235_get_gain(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.gain->val = val;
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ val = sc2235_get_exposure(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.exposure->val = val;
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return 0;
++}
++
++static int sc2235_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored at start streaming time.
++ */
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ ret = sc2235_set_ctrl_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ ret = sc2235_set_ctrl_exposure(sensor, ctrl->val);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = sc2235_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = sc2235_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = sc2235_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = sc2235_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = sc2235_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = sc2235_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = sc2235_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = sc2235_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops sc2235_ctrl_ops = {
++ .g_volatile_ctrl = sc2235_g_volatile_ctrl,
++ .s_ctrl = sc2235_s_ctrl,
++};
++
++static int sc2235_init_controls(struct sc2235_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &sc2235_ctrl_ops;
++ struct sc2235_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ sc2235_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 1);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 0);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 0);
++ /* Auto/manual exposure */
++#ifdef UNUSED_CODE
++ /*
++ *For 7110 platform, This operation will cause the image to be white.
++ */
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ V4L2_EXPOSURE_AUTO);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 0);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 1);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0);
++#else
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ 1);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 720);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 0);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0x10);
++#endif
++ ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
++ 0, 255, 1, 64);
++ ctrls->hue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HUE,
++ 0, 359, 1, 0);
++ ctrls->contrast = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST,
++ 0, 255, 1, 0);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu); //0x02
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 1);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int sc2235_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= SC2235_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ sc2235_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ sc2235_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int sc2235_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct v4l2_fract tpf;
++ int i;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++
++ if (fie->index >= SC2235_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = sc2235_framerates[fie->index];
++
++ for (i = 0; i < SC2235_NUM_MODES; i++) {
++ if (fie->width == sc2235_mode_data[i].hact &&
++ fie->height == sc2235_mode_data[i].vact)
++ break;
++ }
++ if (i == SC2235_NUM_MODES)
++ return -ENOTTY;
++
++ fie->interval = tpf;
++ return 0;
++}
++
++static int sc2235_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int sc2235_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ const struct sc2235_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = sc2235_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = sc2235_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ sc2235_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int sc2235_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++ if (code->index >= ARRAY_SIZE(sc2235_formats))
++ return -EINVAL;
++
++ code->code = sc2235_formats[code->index].code;
++ return 0;
++}
++
++static int sc2235_stream_start(struct sc2235_dev *sensor, int enable)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_STREAM_ON, BIT(0), !!enable);
++}
++
++static int sc2235_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret = 0;
++
++ if (enable) {
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ if (ret)
++ return ret;
++ }
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable && sensor->pending_mode_change) {
++ ret = sc2235_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_fmt_change) {
++ ret = sc2235_set_framefmt(sensor, &sensor->fmt);
++ if (ret)
++ goto out;
++ sensor->pending_fmt_change = false;
++ }
++
++ ret = sc2235_stream_start(sensor, enable);
++ if (ret)
++ goto out;
++ }
++ sensor->streaming += enable ? 1 : -1;
++ WARN_ON(sensor->streaming < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ return ret;
++}
++
++static const struct v4l2_subdev_core_ops sc2235_core_ops = {
++ .s_power = sc2235_s_power,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops sc2235_video_ops = {
++ .g_frame_interval = sc2235_g_frame_interval,
++ .s_frame_interval = sc2235_s_frame_interval,
++ .s_stream = sc2235_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops sc2235_pad_ops = {
++ .enum_mbus_code = sc2235_enum_mbus_code,
++ .get_fmt = sc2235_get_fmt,
++ .set_fmt = sc2235_set_fmt,
++ .enum_frame_size = sc2235_enum_frame_size,
++ .enum_frame_interval = sc2235_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops sc2235_subdev_ops = {
++ .core = &sc2235_core_ops,
++ .video = &sc2235_video_ops,
++ .pad = &sc2235_pad_ops,
++};
++
++static int sc2235_get_regulators(struct sc2235_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < SC2235_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = sc2235_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ SC2235_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int sc2235_check_chip_id(struct sc2235_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ return ret;
++ }
++
++ if (chip_id != SC2235_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, SC2235_CHIP_ID, chip_id);
++ return -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++
++ return 0;
++}
++
++static int sc2235_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct sc2235_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 1920;
++ fmt->height = 1080;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = sc2235_framerates[SC2235_30_FPS];
++ sensor->current_fr = SC2235_30_FPS;
++ sensor->current_mode =
++ &sc2235_mode_data[SC2235_MODE_1080P_1920_1080];
++ sensor->last_mode = sensor->current_mode;
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_PARALLEL) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < SC2235_XCLK_MIN ||
++ sensor->xclk_freq > SC2235_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &sc2235_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = sc2235_get_regulators(sensor);
++ if (ret)
++ return ret;
++ mutex_init(&sensor->lock);
++
++ ret = sc2235_set_power_on(dev);
++ if (ret) {
++ dev_err(dev, "failed to power on\n");
++ goto entity_cleanup;
++ }
++
++ ret = sc2235_check_chip_id(sensor);
++ if (ret)
++ goto entity_power_off;
++
++ ret = sc2235_init_controls(sensor);
++ if (ret)
++ goto entity_power_off;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++entity_power_off:
++ sc2235_set_power_off(dev);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static void sc2235_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ sc2235_set_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct i2c_device_id sc2235_id[] = {
++ { "sc2235", 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, sc2235_id);
++
++static const struct of_device_id sc2235_dt_ids[] = {
++ { .compatible = "smartsens,sc2235" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, sc2235_dt_ids);
++
++static const struct dev_pm_ops sc2235_pm_ops = {
++ SET_RUNTIME_PM_OPS(sc2235_set_power_off, sc2235_set_power_on, NULL)
++};
++
++static struct i2c_driver sc2235_i2c_driver = {
++ .driver = {
++ .name = "sc2235",
++ .of_match_table = sc2235_dt_ids,
++ .pm = &sc2235_pm_ops,
++ },
++ .id_table = sc2235_id,
++ .probe = sc2235_probe,
++ .remove = sc2235_remove,
++};
++
++module_i2c_driver(sc2235_i2c_driver);
++
++MODULE_DESCRIPTION("SC2235 Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_common.h
+@@ -0,0 +1,185 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_COMMON_H
++#define STF_COMMON_H
++
++#include <linux/kern_levels.h>
++
++// #define STF_DEBUG
++
++// #define USE_CSIDPHY_ONE_CLK_MODE 1
++
++enum {
++ ST_DVP = 0x0001,
++ ST_CSIPHY = 0x0002,
++ ST_CSI = 0x0004,
++ ST_ISP = 0x0008,
++ ST_VIN = 0x0010,
++ ST_VIDEO = 0x0020,
++ ST_CAMSS = 0x0040,
++ ST_SENSOR = 0x0080,
++};
++
++enum {
++ ST_NONE = 0x00,
++ ST_ERR = 0x01,
++ ST_WARN = 0x02,
++ ST_INFO = 0x03,
++ ST_DEBUG = 0x04,
++};
++
++extern unsigned int stdbg_level;
++extern unsigned int stdbg_mask;
++
++#define ST_MODULE2STRING(__module) ({ \
++ char *__str; \
++ \
++ switch (__module) { \
++ case ST_DVP: \
++ __str = "st_dvp"; \
++ break; \
++ case ST_CSIPHY: \
++ __str = "st_csiphy"; \
++ break; \
++ case ST_CSI: \
++ __str = "st_csi"; \
++ break; \
++ case ST_ISP: \
++ __str = "st_isp"; \
++ break; \
++ case ST_VIN: \
++ __str = "st_vin"; \
++ break; \
++ case ST_VIDEO: \
++ __str = "st_video"; \
++ break; \
++ case ST_CAMSS: \
++ __str = "st_camss"; \
++ break; \
++ case ST_SENSOR: \
++ __str = "st_sensor"; \
++ break; \
++ default: \
++ __str = "unknow"; \
++ break; \
++ } \
++ \
++ __str; \
++ })
++
++#define st_debug(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_INFO) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] debug: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_info(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_WARN) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] info: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_warn(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_ERR) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] warn: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_err(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_NONE) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] error: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_err_ratelimited(module, fmt, ...) \
++ do { \
++ static DEFINE_RATELIMIT_STATE(_rs, \
++ DEFAULT_RATELIMIT_INTERVAL, \
++ DEFAULT_RATELIMIT_BURST); \
++ if (__ratelimit(&_rs) && (stdbg_level > ST_NONE)) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] error: " fmt, \
++ ST_MODULE2STRING(module), \
++ ##__VA_ARGS__); \
++ } \
++ } while (0)
++
++#define set_bits(p, v, b, m) (((p) & ~(m)) | ((v) << (b)))
++
++static inline u32 reg_read(void __iomem *base, u32 reg)
++{
++ return ioread32(base + reg);
++}
++
++static inline void reg_write(void __iomem *base, u32 reg, u32 val)
++{
++ iowrite32(val, base + reg);
++}
++
++static inline void reg_set_bit(void __iomem *base, u32 reg, u32 mask, u32 val)
++{
++ u32 value;
++
++ value = ioread32(base + reg) & ~mask;
++ val &= mask;
++ val |= value;
++ iowrite32(val, base + reg);
++}
++
++static inline void reg_set(void __iomem *base, u32 reg, u32 mask)
++{
++ iowrite32(ioread32(base + reg) | mask, base + reg);
++}
++
++static inline void reg_clear(void __iomem *base, u32 reg, u32 mask)
++{
++ iowrite32(ioread32(base + reg) & ~mask, base + reg);
++}
++
++static inline void reg_set_highest_bit(void __iomem *base, u32 reg)
++{
++ u32 val;
++
++ val = ioread32(base + reg);
++ val &= ~(0x1 << 31);
++ val |= (0x1 & 0x1) << 31;
++ iowrite32(val, base + reg);
++}
++
++static inline void reg_clr_highest_bit(void __iomem *base, u32 reg)
++{
++ u32 val;
++
++ val = ioread32(base + reg);
++ val &= ~(0x1 << 31);
++ val |= (0x0 & 0x1) << 31;
++ iowrite32(val, base + reg);
++}
++
++static inline void print_reg(unsigned int module, void __iomem *base, u32 reg)
++{
++ //st_debug(module, "REG 0x%x = 0x%x\n",
++ // base + reg, ioread32(base + reg));
++}
++
++#endif /* STF_COMMON_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
+@@ -0,0 +1,465 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static const struct csi_format csi_formats_sink[] = {
++ { MEDIA_BUS_FMT_UYVY8_2X8, 16},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++/* this bpp need see csi controllor */
++static const struct csi_format csi_formats_src[] = {
++ { MEDIA_BUS_FMT_AYUV8_1X32, 32},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 16},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 16},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 16},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 16},
++};
++
++static int csi_find_format(u32 code,
++ const struct csi_format *formats,
++ unsigned int nformats)
++{
++ int i;
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].code == code)
++ return i;
++ return -EINVAL;
++}
++
++int stf_csi_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
++
++ csi_dev->s_type = SENSOR_VIN;
++ csi_dev->hw_ops = &csi_ops;
++ csi_dev->stfcamss = stfcamss;
++ csi_dev->formats_sink = csi_formats_sink;
++ csi_dev->nformats_sink = ARRAY_SIZE(csi_formats_sink);
++ csi_dev->formats_src = csi_formats_src;
++ csi_dev->nformats_src = ARRAY_SIZE(csi_formats_src);
++ mutex_init(&csi_dev->stream_lock);
++ return 0;
++}
++
++static int csi_set_power(struct v4l2_subdev *sd, int on)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++
++ csi_dev->hw_ops->csi_power_on(csi_dev, (u8)on);
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__csi_get_format(struct stf_csi_dev *csi_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(&csi_dev->subdev, state, pad);
++
++ return &csi_dev->fmt[pad];
++}
++
++static u32 code_to_data_type(int code)
++{
++ switch (code) {
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ return 0x2b;
++ case MEDIA_BUS_FMT_UYVY8_2X8:
++ return 0x1E;
++ default:
++ return 0x2b;
++ }
++}
++
++static int csi_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ int ret = 0;
++ u32 code, width, dt;
++ u8 bpp;
++
++ format = __csi_get_format(csi_dev, NULL, STF_CSI_PAD_SINK,
++ V4L2_SUBDEV_FORMAT_ACTIVE);
++ if (format == NULL)
++ return -EINVAL;
++
++ width = format->width;
++
++ ret = csi_find_format(format->code,
++ csi_dev->formats_sink,
++ csi_dev->nformats_sink);
++ if (ret < 0)
++ return ret;
++
++ code = csi_dev->formats_sink[ret].code;
++ bpp = csi_dev->formats_src[ret].bpp;
++ dt = code_to_data_type(code);
++
++ mutex_lock(&csi_dev->stream_lock);
++ if (enable) {
++ if (csi_dev->stream_count == 0) {
++ csi_dev->hw_ops->csi_clk_enable(csi_dev);
++ csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
++ }
++ csi_dev->stream_count++;
++ } else {
++ if (csi_dev->stream_count == 0)
++ goto exit;
++ if (csi_dev->stream_count == 1) {
++ csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
++ csi_dev->hw_ops->csi_clk_disable(csi_dev);
++ }
++ csi_dev->stream_count--;
++ }
++exit:
++ mutex_unlock(&csi_dev->stream_lock);
++ return 0;
++}
++
++static void csi_try_format(struct stf_csi_dev *csi_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_CSI_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < csi_dev->nformats_sink; i++)
++ if (fmt->code == csi_dev->formats_sink[i].code)
++ break;
++
++ if (i >= csi_dev->nformats_sink)
++ fmt->code = csi_dev->formats_sink[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width,
++ STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height,
++ STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_CSI_PAD_SRC:
++ /* Set format on src pad */
++
++ for (i = 0; i < csi_dev->nformats_src; i++)
++ if (fmt->code == csi_dev->formats_src[i].code)
++ break;
++
++ if (i >= csi_dev->nformats_src)
++ fmt->code = csi_dev->formats_src[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width,
++ STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height,
++ STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++ }
++}
++
++static int csi_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++
++ if (code->index >= csi_dev->nformats_sink)
++ return -EINVAL;
++ if (code->pad == STF_CSI_PAD_SINK) {
++ code->code = csi_dev->formats_sink[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __csi_get_format(csi_dev, state, STF_CSI_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++
++ return 0;
++}
++
++static int csi_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ csi_try_format(csi_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ csi_try_format(csi_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int csi_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __csi_get_format(csi_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int csi_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ struct v4l2_mbus_framefmt *format_src;
++ int ret;
++
++ format = __csi_get_format(csi_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&csi_dev->stream_lock);
++ if (csi_dev->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&csi_dev->stream_lock);
++ goto out;
++ } else {
++ csi_try_format(csi_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&csi_dev->stream_lock);
++
++ if (fmt->pad == STF_CSI_PAD_SINK) {
++ format_src = __csi_get_format(csi_dev, state, STF_DVP_PAD_SRC,
++ fmt->which);
++
++ ret = csi_find_format(format->code, csi_dev->formats_sink,
++ csi_dev->nformats_sink);
++ if (ret < 0)
++ return ret;
++
++ format_src->code = csi_dev->formats_src[ret].code;
++ csi_try_format(csi_dev, state, STF_DVP_PAD_SRC, format_src,
++ fmt->which);
++ }
++out:
++ return 0;
++}
++
++static int csi_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_CSI_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return csi_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int csi_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if ((local->flags & MEDIA_PAD_FL_SOURCE) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_csi_dev *csi_dev;
++ struct vin_line *line;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ csi_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ line = v4l2_get_subdevdata(sd);
++ if (line->sdev_type == VIN_DEV_TYPE)
++ csi_dev->s_type = SENSOR_VIN;
++ if (line->sdev_type == ISP_DEV_TYPE)
++ csi_dev->s_type = SENSOR_ISP;
++ st_info(ST_CSI, "CSI device sensor type: %d\n", csi_dev->s_type);
++ }
++
++ if ((local->flags & MEDIA_PAD_FL_SINK) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_csi_dev *csi_dev;
++ struct stf_csiphy_dev *csiphy_dev;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ csi_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ csiphy_dev = v4l2_get_subdevdata(sd);
++
++ st_info(ST_CSI, "CSI0 link to csiphy0\n");
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops csi_core_ops = {
++ .s_power = csi_set_power,
++};
++
++static const struct v4l2_subdev_video_ops csi_video_ops = {
++ .s_stream = csi_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops csi_pad_ops = {
++ .enum_mbus_code = csi_enum_mbus_code,
++ .enum_frame_size = csi_enum_frame_size,
++ .get_fmt = csi_get_format,
++ .set_fmt = csi_set_format,
++};
++
++static const struct v4l2_subdev_ops csi_v4l2_ops = {
++ .core = &csi_core_ops,
++ .video = &csi_video_ops,
++ .pad = &csi_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops csi_v4l2_internal_ops = {
++ .open = csi_init_formats,
++};
++
++static const struct media_entity_operations csi_media_ops = {
++ .link_setup = csi_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_csi_register(struct stf_csi_dev *csi_dev, struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &csi_dev->subdev;
++ struct device *dev = csi_dev->stfcamss->dev;
++ struct media_pad *pads = csi_dev->pads;
++ int ret;
++
++ csi_dev->mipirx_1p8 = devm_regulator_get(dev, "mipirx_1p8");
++ if (IS_ERR(csi_dev->mipirx_1p8))
++ return PTR_ERR(csi_dev->mipirx_1p8);
++
++ csi_dev->mipirx_0p9 = devm_regulator_get(dev, "mipirx_0p9");
++ if (IS_ERR(csi_dev->mipirx_0p9))
++ return PTR_ERR(csi_dev->mipirx_0p9);
++
++ v4l2_subdev_init(sd, &csi_v4l2_ops);
++ sd->internal_ops = &csi_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_CSI_NAME, 0);
++ v4l2_set_subdevdata(sd, csi_dev);
++
++ ret = csi_init_formats(sd, NULL);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_CSI_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &csi_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_CSI_PADS_NUM, pads);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ dev_err(dev, "Failed to register subdev: %d\n", ret);
++ goto err_sreg;
++ }
++
++ return 0;
++
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_csi_unregister(struct stf_csi_dev *csi_dev)
++{
++ v4l2_device_unregister_subdev(&csi_dev->subdev);
++ media_entity_cleanup(&csi_dev->subdev.entity);
++ mutex_destroy(&csi_dev->stream_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
+@@ -0,0 +1,61 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_CSI_H
++#define STF_CSI_H
++
++#include <linux/regulator/consumer.h>
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_CSI_NAME "stf_csi"
++
++#define STF_CSI_PAD_SINK 0
++#define STF_CSI_PAD_SRC 1
++#define STF_CSI_PADS_NUM 2
++
++struct csi_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct stf_csi_dev;
++
++struct csi_hw_ops {
++ int (*csi_power_on)(struct stf_csi_dev *csi_dev, u8 on);
++ int (*csi_clk_enable)(struct stf_csi_dev *csi_dev);
++ int (*csi_clk_disable)(struct stf_csi_dev *csi_dev);
++ int (*csi_stream_set)(struct stf_csi_dev *csi_dev, int on,
++ u32 dt, u32 width, u8 bpp);
++};
++
++struct stf_csi_dev {
++ struct stfcamss *stfcamss;
++ enum sensor_type s_type;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_CSI_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_CSI_PADS_NUM];
++ const struct csi_format *formats_sink;
++ unsigned int nformats_sink;
++ const struct csi_format *formats_src;
++ unsigned int nformats_src;
++ struct csi_hw_ops *hw_ops;
++ struct mutex stream_lock;
++ int stream_count;
++ struct regulator *mipirx_1p8;
++ struct regulator *mipirx_0p9;
++};
++
++extern int stf_csi_subdev_init(struct stfcamss *stfcamss);
++extern int stf_csi_register(struct stf_csi_dev *csi_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_csi_unregister(struct stf_csi_dev *csi_dev);
++extern struct csi_hw_ops csi_ops;
++extern void dump_csi_reg(void *__iomem csibase);
++
++#endif /* STF_CSI_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
+@@ -0,0 +1,310 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/regmap.h>
++
++#define CSI2RX_DEVICE_CFG_REG 0x000
++
++#define CSI2RX_SOFT_RESET_REG 0x004
++#define CSI2RX_SOFT_RESET_PROTOCOL BIT(1)
++#define CSI2RX_SOFT_RESET_FRONT BIT(0)
++
++#define CSI2RX_DPHY_LANE_CONTROL 0x040
++
++#define CSI2RX_STATIC_CFG_REG 0x008
++#define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane) \
++ ((plane) << (16 + (llane) * 4))
++#define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8)
++
++#define CSI2RX_STREAM_BASE(n) (((n) + 1) * 0x100)
++
++#define CSI2RX_STREAM_CTRL_REG(n) (CSI2RX_STREAM_BASE(n) + 0x000)
++#define CSI2RX_STREAM_CTRL_START BIT(0)
++
++#define CSI2RX_STREAM_DATA_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x008)
++#define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT BIT(31)
++#define CSI2RX_STREAM_DATA_CFG_EN_DATA_TYPE_0 BIT(7)
++#define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n) BIT((n) + 16)
++
++#define CSI2RX_STREAM_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x00c)
++#define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF (1 << 8)
++
++#define CSI2RX_LANES_MAX 4
++#define CSI2RX_STREAMS_MAX 4
++
++static int stf_csi_power_on(struct stf_csi_dev *csi_dev, u8 on)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++ int ret;
++
++ if (on) {
++ ret = regulator_enable(csi_dev->mipirx_1p8);
++ if (ret) {
++ st_err(ST_CSI, "Cannot enable mipirx_1p8 regulator\n");
++ goto err_1p8;
++ }
++
++ ret = regulator_enable(csi_dev->mipirx_0p9);
++ if (ret) {
++ st_err(ST_CSI, "Cannot enable mipirx_0p9 regulator\n");
++ goto err_0p9;
++ }
++ } else {
++ regulator_disable(csi_dev->mipirx_1p8);
++ regulator_disable(csi_dev->mipirx_0p9);
++ }
++
++ regmap_update_bits(stfcamss->stf_aon_syscon, stfcamss->aon_gp_reg,
++ BIT(31), BIT(31));
++
++ return 0;
++
++err_0p9:
++ regulator_disable(csi_dev->mipirx_1p8);
++err_1p8:
++ return ret;
++
++}
++
++static int stf_csi_clk_enable(struct stf_csi_dev *csi_dev)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++
++ clk_set_rate(stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk, 198000000);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF0].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF1].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF2].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF3].clk);
++
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF0].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF1].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF2].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF3].rstc);
++
++ switch (csi_dev->s_type) {
++ case SENSOR_VIN:
++ reset_control_deassert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ clk_set_parent(stfcamss->sys_clk[STFCLK_AXIWR].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ break;
++ case SENSOR_ISP:
++ clk_set_parent(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ break;
++ }
++
++ return 0;
++}
++
++static int stf_csi_clk_disable(struct stf_csi_dev *csi_dev)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++
++ switch (csi_dev->s_type) {
++ case SENSOR_VIN:
++ reset_control_assert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ break;
++ case SENSOR_ISP:
++ break;
++ }
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF3].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF2].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF1].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF0].rstc);
++
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF3].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF2].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF1].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF0].clk);
++
++ return 0;
++}
++
++static void csi2rx_reset(void *reg_base)
++{
++ writel(CSI2RX_SOFT_RESET_PROTOCOL | CSI2RX_SOFT_RESET_FRONT,
++ reg_base + CSI2RX_SOFT_RESET_REG);
++
++ udelay(10);
++
++ writel(0, reg_base + CSI2RX_SOFT_RESET_REG);
++}
++
++static int csi2rx_start(struct stf_csi_dev *csi_dev, void *reg_base, u32 dt)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++ struct csi2phy_cfg *csiphy =
++ stfcamss->csiphy_dev->csiphy;
++ unsigned int i;
++ unsigned long lanes_used = 0;
++ u32 reg;
++
++ if (!csiphy) {
++ st_err(ST_CSI, "csiphy0 config not exist\n");
++ return -EINVAL;
++ }
++
++ csi2rx_reset(reg_base);
++
++ reg = csiphy->num_data_lanes << 8;
++ for (i = 0; i < csiphy->num_data_lanes; i++) {
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++ reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csiphy->data_lanes[i]);
++ set_bit(csiphy->data_lanes[i] - 1, &lanes_used);
++#else
++ reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, i + 1);
++ set_bit(i, &lanes_used);
++#endif
++ }
++
++ /*
++ * Even the unused lanes need to be mapped. In order to avoid
++ * to map twice to the same physical lane, keep the lanes used
++ * in the previous loop, and only map unused physical lanes to
++ * the rest of our logical lanes.
++ */
++ for (i = csiphy->num_data_lanes; i < CSI2RX_LANES_MAX; i++) {
++ unsigned int idx = find_first_zero_bit(&lanes_used,
++ CSI2RX_LANES_MAX);
++
++ set_bit(idx, &lanes_used);
++ reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, idx + 1);
++ }
++
++ writel(reg, reg_base + CSI2RX_STATIC_CFG_REG);
++
++ // 0x40 DPHY_LANE_CONTROL
++ reg = 0;
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++ for (i = 0; i < csiphy->num_data_lanes; i++)
++ reg |= 1 << (csiphy->data_lanes[i] - 1)
++ | 1 << (csiphy->data_lanes[i] + 11);
++#else
++ for (i = 0; i < csiphy->num_data_lanes; i++)
++ reg |= 1 << i | 1 << (i + 12); //data_clane
++#endif
++
++ reg |= 1 << 4 | 1 << 16; //clk_lane
++ writel(reg, reg_base + CSI2RX_DPHY_LANE_CONTROL);
++
++ /*
++ * Create a static mapping between the CSI virtual channels
++ * and the output stream.
++ *
++ * This should be enhanced, but v4l2 lacks the support for
++ * changing that mapping dynamically.
++ *
++ * We also cannot enable and disable independent streams here,
++ * hence the reference counting.
++ */
++ for (i = 0; i < CSI2RX_STREAMS_MAX; i++) {
++ writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
++ reg_base + CSI2RX_STREAM_CFG_REG(i));
++
++ writel(CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT |
++ CSI2RX_STREAM_DATA_CFG_VC_SELECT(i) |
++ CSI2RX_STREAM_DATA_CFG_EN_DATA_TYPE_0 | dt,
++ reg_base + CSI2RX_STREAM_DATA_CFG_REG(i));
++
++ writel(CSI2RX_STREAM_CTRL_START,
++ reg_base + CSI2RX_STREAM_CTRL_REG(i));
++ }
++
++ return 0;
++}
++
++static void csi2rx_stop(struct stf_csi_dev *csi_dev, void *reg_base)
++{
++ unsigned int i;
++
++ for (i = 0; i < CSI2RX_STREAMS_MAX; i++)
++ writel(0, reg_base + CSI2RX_STREAM_CTRL_REG(i));
++}
++
++static void csi_set_vin_axiwr_pix(struct stf_csi_dev *csi_dev, u32 width, u8 bpp)
++{
++ struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
++ u32 value = 0;
++ int cnfg_axiwr_pix_ct = 64 / bpp;
++
++ if (cnfg_axiwr_pix_ct == 2)
++ value = 0;
++ else if (cnfg_axiwr_pix_ct == 4)
++ value = 1;
++ else if (cnfg_axiwr_pix_ct == 8)
++ value = 2;
++
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ BIT(14)|BIT(13), value << 13); //u0_vin_cnfg_axiwr0_pix_ct
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2),
++ (width / cnfg_axiwr_pix_ct - 1)<<2); //u0_vin_cnfg_axiwr0_pix_cnt_end
++}
++
++static int stf_csi_stream_set(struct stf_csi_dev *csi_dev,
++ int on, u32 dt, u32 width, u8 bpp)
++{
++ struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
++ void __iomem *reg_base = vin->csi2rx_base;
++
++ switch (csi_dev->s_type) {
++ case SENSOR_VIN:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_20,
++ BIT(3)|BIT(2)|BIT(1)|BIT(0),
++ 0<<0); //u0_vin_cnfg_axiwr0_channel_sel
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ BIT(16)|BIT(15),
++ 0<<15); //u0_vin_cnfg_axiwr0_pixel_high_bit_sel
++ csi_set_vin_axiwr_pix(csi_dev, width, bpp);
++ break;
++ case SENSOR_ISP:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(7)|BIT(6),
++ 0<<6); //u0_vin_cnfg_mipi_byte_en_isp
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(11)|BIT(10)|BIT(9)|BIT(8),
++ 0<<8); //u0_vin_cnfg_mipi_channel_sel0
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(16)|BIT(15)|BIT(14)|BIT(13),
++ 0<<13); //u0_vin_cnfg_pix_num
++
++ if (dt == 0x2b)
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(12),
++ 1<<12); //u0_vin_cnfg_p_i_mipi_header_en0
++ break;
++ }
++
++ if (on)
++ csi2rx_start(csi_dev, reg_base, dt);
++ else
++ csi2rx_stop(csi_dev, reg_base);
++
++ return 0;
++}
++
++void dump_csi_reg(void *__iomem csibase)
++{
++ st_info(ST_CSI, "DUMP CSI register:\n");
++ print_reg(ST_CSI, csibase, 0x00);
++ print_reg(ST_CSI, csibase, 0x04);
++ print_reg(ST_CSI, csibase, 0x08);
++ print_reg(ST_CSI, csibase, 0x10);
++
++ print_reg(ST_CSI, csibase, 0x40);
++ print_reg(ST_CSI, csibase, 0x48);
++ print_reg(ST_CSI, csibase, 0x4c);
++ print_reg(ST_CSI, csibase, 0x50);
++}
++
++struct csi_hw_ops csi_ops = {
++ .csi_power_on = stf_csi_power_on,
++ .csi_clk_enable = stf_csi_clk_enable,
++ .csi_clk_disable = stf_csi_clk_disable,
++ .csi_stream_set = stf_csi_stream_set,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
+@@ -0,0 +1,357 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static const struct csiphy_format csiphy_formats_st7110[] = {
++ { MEDIA_BUS_FMT_UYVY8_2X8, 16},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++int stf_csiphy_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
++
++ csiphy_dev->hw_ops = &csiphy_ops;
++ csiphy_dev->stfcamss = stfcamss;
++ csiphy_dev->formats = csiphy_formats_st7110;
++ csiphy_dev->nformats = ARRAY_SIZE(csiphy_formats_st7110);
++ mutex_init(&csiphy_dev->stream_lock);
++ return 0;
++}
++
++static int csiphy_set_power(struct v4l2_subdev *sd, int on)
++{
++ return 0;
++}
++
++static int csiphy_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++
++ mutex_lock(&csiphy_dev->stream_lock);
++ if (enable) {
++ if (csiphy_dev->stream_count == 0) {
++ csiphy_dev->hw_ops->csiphy_clk_enable(csiphy_dev);
++ csiphy_dev->hw_ops->csiphy_config_set(csiphy_dev);
++ csiphy_dev->hw_ops->csiphy_stream_set(csiphy_dev, 1);
++ }
++ csiphy_dev->stream_count++;
++ } else {
++ if (csiphy_dev->stream_count == 0)
++ goto exit;
++ if (csiphy_dev->stream_count == 1) {
++ csiphy_dev->hw_ops->csiphy_clk_disable(csiphy_dev);
++ csiphy_dev->hw_ops->csiphy_stream_set(csiphy_dev, 0);
++ }
++ csiphy_dev->stream_count--;
++ }
++exit:
++ mutex_unlock(&csiphy_dev->stream_lock);
++
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__csiphy_get_format(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(
++ &csiphy_dev->subdev,
++ state,
++ pad);
++
++ return &csiphy_dev->fmt[pad];
++}
++
++static void csiphy_try_format(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_CSIPHY_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < csiphy_dev->nformats; i++)
++ if (fmt->code == csiphy_dev->formats[i].code)
++ break;
++
++ if (i >= csiphy_dev->nformats)
++ fmt->code = csiphy_dev->formats[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width,
++ STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height,
++ STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_CSIPHY_PAD_SRC:
++
++ *fmt = *__csiphy_get_format(csiphy_dev,
++ state,
++ STF_CSIPHY_PAD_SINK, which);
++
++ break;
++ }
++}
++
++static int csiphy_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++
++ if (code->index >= csiphy_dev->nformats)
++ return -EINVAL;
++
++ if (code->pad == STF_CSIPHY_PAD_SINK) {
++ code->code = csiphy_dev->formats[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __csiphy_get_format(csiphy_dev, state,
++ STF_CSIPHY_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++ return 0;
++}
++
++static int csiphy_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ csiphy_try_format(csiphy_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ csiphy_try_format(csiphy_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int csiphy_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __csiphy_get_format(csiphy_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int csiphy_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __csiphy_get_format(csiphy_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&csiphy_dev->stream_lock);
++ if (csiphy_dev->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&csiphy_dev->stream_lock);
++ goto out;
++ } else {
++ csiphy_try_format(csiphy_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&csiphy_dev->stream_lock);
++
++ /* Propagate the format from sink to source */
++ if (fmt->pad == STF_CSIPHY_PAD_SINK) {
++ format = __csiphy_get_format(csiphy_dev,
++ state,
++ STF_CSIPHY_PAD_SRC,
++ fmt->which);
++
++ *format = fmt->format;
++ csiphy_try_format(csiphy_dev, state, STF_CSIPHY_PAD_SRC, format,
++ fmt->which);
++ }
++out:
++ return 0;
++}
++
++static int csiphy_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_CSIPHY_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return csiphy_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int csiphy_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if ((local->flags & MEDIA_PAD_FL_SOURCE) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_csiphy_dev *csiphy_dev;
++ struct stf_csi_dev *csi_dev;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ csiphy_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ csi_dev = v4l2_get_subdevdata(sd);
++ st_info(ST_CSIPHY, "CSIPHY0 link to CSI0\n");
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops csiphy_core_ops = {
++ .s_power = csiphy_set_power,
++};
++
++static const struct v4l2_subdev_video_ops csiphy_video_ops = {
++ .s_stream = csiphy_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops csiphy_pad_ops = {
++ .enum_mbus_code = csiphy_enum_mbus_code,
++ .enum_frame_size = csiphy_enum_frame_size,
++ .get_fmt = csiphy_get_format,
++ .set_fmt = csiphy_set_format,
++};
++
++static const struct v4l2_subdev_ops csiphy_v4l2_ops = {
++ .core = &csiphy_core_ops,
++ .video = &csiphy_video_ops,
++ .pad = &csiphy_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops csiphy_v4l2_internal_ops = {
++ .open = csiphy_init_formats,
++};
++
++static const struct media_entity_operations csiphy_media_ops = {
++ .link_setup = csiphy_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_csiphy_register(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &csiphy_dev->subdev;
++ struct device *dev = csiphy_dev->stfcamss->dev;
++ struct media_pad *pads = csiphy_dev->pads;
++ int ret;
++
++ v4l2_subdev_init(sd, &csiphy_v4l2_ops);
++ sd->internal_ops = &csiphy_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_CSIPHY_NAME, 0);
++ v4l2_set_subdevdata(sd, csiphy_dev);
++
++ ret = csiphy_init_formats(sd, NULL);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_CSIPHY_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_CSIPHY_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &csiphy_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_CSIPHY_PADS_NUM, pads);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ dev_err(dev, "Failed to register subdev: %d\n", ret);
++ goto err_sreg;
++ }
++
++ return 0;
++
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_csiphy_unregister(struct stf_csiphy_dev *csiphy_dev)
++{
++ v4l2_device_unregister_subdev(&csiphy_dev->subdev);
++ media_entity_cleanup(&csiphy_dev->subdev.entity);
++ mutex_destroy(&csiphy_dev->stream_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.h
+@@ -0,0 +1,188 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_CSIPHY_H
++#define STF_CSIPHY_H
++
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_CSIPHY_NAME "stf_csiphy"
++
++#define STF_CSIPHY_PAD_SINK 0
++#define STF_CSIPHY_PAD_SRC 1
++#define STF_CSIPHY_PADS_NUM 2
++
++#define STF_CSI2_MAX_DATA_LANES 4
++
++union static_config {
++ u32 raw;
++ struct {
++ u32 sel : 2;
++ u32 rsvd_6 : 2;
++ u32 v2p0_support_enable : 1;
++ u32 rsvd_5 : 3;
++ u32 lane_nb : 3;
++ u32 rsvd_4 : 5;
++ u32 dl0_map : 3;
++ u32 rsvd_3 : 1;
++ u32 dl1_map : 3;
++ u32 rsvd_2 : 1;
++ u32 dl2_map : 3;
++ u32 rsvd_1 : 1;
++ u32 dl3_map : 3;
++ u32 rsvd_0 : 1;
++ } bits;
++};
++
++union error_bypass_cfg {
++ u32 value;
++ struct {
++ u32 crc : 1;
++ u32 ecc : 1;
++ u32 data_id : 1;
++ u32 rsvd_0 : 29;
++ };
++};
++
++union stream_monitor_ctrl {
++ u32 value;
++ struct {
++ u32 lb_vc : 4;
++ u32 lb_en : 1;
++ u32 timer_vc : 4;
++ u32 timer_en : 1;
++ u32 timer_eof : 1;
++ u32 frame_mon_vc : 4;
++ u32 frame_mon_en : 1;
++ u32 frame_length : 16;
++ };
++};
++
++union stream_cfg {
++ u32 value;
++ struct {
++ u32 interface_mode : 1;
++ u32 ls_le_mode : 1;
++ u32 rsvd_3 : 2;
++ u32 num_pixels : 2;
++ u32 rsvd_2 : 2;
++ u32 fifo_mode : 2;
++ u32 rsvd_1 : 2;
++ u32 bpp_bypass : 3;
++ u32 rsvd_0 : 1;
++ u32 fifo_fill : 16;
++ };
++};
++
++union dphy_lane_ctrl {
++ u32 raw;
++ struct {
++ u32 dl0_en : 1;
++ u32 dl1_en : 1;
++ u32 dl2_en : 1;
++ u32 dl3_en : 1;
++ u32 cl_en : 1;
++ u32 rsvd_1 : 7;
++ u32 dl0_reset : 1;
++ u32 dl1_reset : 1;
++ u32 dl2_reset : 1;
++ u32 dl3_reset : 1;
++ u32 cl_reset : 1;
++ u32 rsvd_0 : 15;
++ } bits;
++};
++
++union dphy_lane_swap {
++ u32 raw;
++ struct {
++ u32 rx_1c2c_sel : 1;
++ u32 lane_swap_clk : 3;
++ u32 lane_swap_clk1 : 3;
++ u32 lane_swap_lan0 : 3;
++ u32 lane_swap_lan1 : 3;
++ u32 lane_swap_lan2 : 3;
++ u32 lane_swap_lan3 : 3;
++ u32 dpdn_swap_clk : 1;
++ u32 dpdn_swap_clk1 : 1;
++ u32 dpdn_swap_lan0 : 1;
++ u32 dpdn_swap_lan1 : 1;
++ u32 dpdn_swap_lan2 : 1;
++ u32 dpdn_swap_lan3 : 1;
++ u32 hs_freq_chang_clk0 : 1;
++ u32 hs_freq_chang_clk1 : 1;
++ u32 reserved : 5;
++ } bits;
++};
++
++union dphy_lane_en {
++ u32 raw;
++ struct {
++ u32 gpio_en : 6;
++ u32 mp_test_mode_sel : 5;
++ u32 mp_test_en : 1;
++ u32 dphy_enable_lan0 : 1;
++ u32 dphy_enable_lan1 : 1;
++ u32 dphy_enable_lan2 : 1;
++ u32 dphy_enable_lan3 : 1;
++ u32 rsvd_0 : 16;
++ } bits;
++};
++
++struct csiphy_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct csi2phy_cfg {
++ unsigned int flags;
++ unsigned char data_lanes[STF_CSI2_MAX_DATA_LANES];
++ unsigned char clock_lane;
++ unsigned char num_data_lanes;
++ bool lane_polarities[1 + STF_CSI2_MAX_DATA_LANES];
++};
++
++struct csi2phy_cfg2 {
++ unsigned char data_lanes[STF_CSI2_MAX_DATA_LANES];
++ unsigned char num_data_lanes;
++ unsigned char num_clks;
++ unsigned char clock_lane;
++ unsigned char clock1_lane;
++ bool lane_polarities[2 + STF_CSI2_MAX_DATA_LANES];
++};
++
++struct stf_csiphy_dev;
++
++struct csiphy_hw_ops {
++ int (*csiphy_clk_enable)(struct stf_csiphy_dev *csiphy_dev);
++ int (*csiphy_clk_disable)(struct stf_csiphy_dev *csiphy_dev);
++ int (*csiphy_config_set)(struct stf_csiphy_dev *csiphy_dev);
++ int (*csiphy_stream_set)(struct stf_csiphy_dev *csiphy_dev, int on);
++};
++
++struct stf_csiphy_dev {
++ struct stfcamss *stfcamss;
++ struct csi2phy_cfg *csiphy;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_CSIPHY_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_CSIPHY_PADS_NUM];
++ const struct csiphy_format *formats;
++ unsigned int nformats;
++ struct csiphy_hw_ops *hw_ops;
++ struct mutex stream_lock;
++ int stream_count;
++};
++
++extern int stf_csiphy_subdev_init(struct stfcamss *stfcamss);
++extern int stf_csiphy_register(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_csiphy_unregister(struct stf_csiphy_dev *csiphy_dev);
++
++extern struct csiphy_hw_ops csiphy_ops;
++
++#endif /* STF_CSIPHY_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy_hw_ops.c
+@@ -0,0 +1,335 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/sort.h>
++
++static int stf_csiphy_clk_set(struct stf_csiphy_dev *csiphy_dev, int on)
++{
++ struct stfcamss *stfcamss = csiphy_dev->stfcamss;
++ static int init_flag;
++ static struct mutex count_lock;
++ static int count;
++
++ if (!init_flag) {
++ init_flag = 1;
++ mutex_init(&count_lock);
++ }
++ mutex_lock(&count_lock);
++ if (on) {
++ clk_set_rate(stfcamss->sys_clk[STFCLK_M31DPHY_CFGCLK_IN].clk,
++ 99000000);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_M31DPHY_REFCLK_IN].clk,
++ 49500000);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_M31DPHY_TXCLKESC_LAN0].clk,
++ 19800000);
++
++ reset_control_deassert(stfcamss->sys_rst[STFRST_M31DPHY_HW].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_M31DPHY_B09_ALWAYS_ON].rstc);
++
++ count++;
++ } else {
++ if (count == 0)
++ goto exit;
++ if (count == 1) {
++ reset_control_assert(stfcamss->sys_rst[STFRST_M31DPHY_HW].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_M31DPHY_B09_ALWAYS_ON].rstc);
++ }
++ count--;
++ }
++exit:
++ mutex_unlock(&count_lock);
++ return 0;
++}
++
++static int stf_csiphy_clk_enable(struct stf_csiphy_dev *csiphy_dev)
++{
++ return stf_csiphy_clk_set(csiphy_dev, 1);
++}
++
++static int stf_csiphy_clk_disable(struct stf_csiphy_dev *csiphy_dev)
++{
++ return stf_csiphy_clk_set(csiphy_dev, 0);
++}
++
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++static int cmp_func(const void *x1, const void *x2)
++{
++ return *((unsigned char *)x1) - *((unsigned char *)x2);
++}
++#endif
++
++int try_cfg(struct csi2phy_cfg2 *cfg, struct csi2phy_cfg *cfg0,
++ struct csi2phy_cfg *cfg1)
++{
++ int i = 0;
++
++ cfg->clock_lane = 0;
++ cfg->clock1_lane = 5;
++ cfg->data_lanes[0] = 1;
++ cfg->data_lanes[1] = 2;
++ cfg->data_lanes[2] = 3;
++ cfg->data_lanes[3] = 4;
++
++ if (cfg0 && cfg1) {
++ st_debug(ST_CSIPHY, "CSIPHY use 2 clk mode\n");
++ cfg->num_clks = 2;
++ cfg->num_data_lanes =
++ cfg1->num_data_lanes + cfg0->num_data_lanes;
++ if (cfg->num_data_lanes > STF_CSI2_MAX_DATA_LANES)
++ return -EINVAL;
++ cfg->clock_lane = cfg0->clock_lane;
++ cfg->lane_polarities[0] = cfg0->lane_polarities[0];
++ cfg->clock1_lane = cfg1->clock_lane;
++ cfg->lane_polarities[1] = cfg1->lane_polarities[0];
++ for (i = 0; i < cfg0->num_data_lanes; i++) {
++ cfg->data_lanes[i] = cfg0->data_lanes[i];
++ cfg->lane_polarities[i + 2] =
++ cfg0->lane_polarities[i + 1];
++ }
++
++ for (i = cfg0->num_data_lanes; i < cfg->num_data_lanes; i++) {
++ cfg->data_lanes[i] =
++ cfg1->data_lanes[i - cfg0->num_data_lanes];
++ cfg->lane_polarities[i + 2] =
++ cfg1->lane_polarities[i - cfg0->num_data_lanes + 1];
++ }
++ } else if (cfg0 && !cfg1) {
++ st_debug(ST_CSIPHY, "CSIPHY cfg0 use 1 clk mode\n");
++ cfg->num_clks = 1;
++ cfg->num_data_lanes = cfg0->num_data_lanes;
++ cfg->clock_lane = cfg->clock1_lane = cfg0->clock_lane;
++ cfg->lane_polarities[0] = cfg->lane_polarities[1] =
++ cfg0->lane_polarities[0];
++ for (i = 0; i < cfg0->num_data_lanes; i++) {
++ cfg->data_lanes[i] = cfg0->data_lanes[i];
++ cfg->lane_polarities[i + 2] = cfg0->lane_polarities[i + 1];
++ }
++ } else if (!cfg0 && cfg1) {
++ st_debug(ST_CSIPHY, "CSIPHY cfg1 use 1 clk mode\n");
++ cfg->num_clks = 1;
++ cfg->num_data_lanes = cfg1->num_data_lanes;
++ cfg->clock_lane = cfg->clock1_lane = cfg1->clock_lane;
++ cfg->lane_polarities[0] = cfg->lane_polarities[1] =
++ cfg1->lane_polarities[0];
++ for (i = 0; i < cfg1->num_data_lanes; i++) {
++ cfg->data_lanes[i] = cfg1->data_lanes[i];
++ cfg->lane_polarities[i + 2] = cfg1->lane_polarities[i + 1];
++ }
++ } else {
++ return -EINVAL;
++ }
++
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++ sort(cfg->data_lanes, cfg->num_data_lanes,
++ sizeof(cfg->data_lanes[0]), cmp_func, NULL);
++#endif
++ for (i = 0; i < cfg->num_data_lanes; i++)
++ st_debug(ST_CSIPHY, "%d: %d\n", i, cfg->data_lanes[i]);
++ return 0;
++}
++
++static int csi2rx_dphy_config(struct stf_vin_dev *vin,
++ struct stf_csiphy_dev *csiphy_dev)
++{
++ struct csi2phy_cfg2 cfg2 = {0};
++ struct csi2phy_cfg2 *cfg = &cfg2;
++ struct csi2phy_cfg *phycfg = csiphy_dev->csiphy;
++
++ if (!phycfg)
++ return -EINVAL;
++
++ if (try_cfg(cfg, phycfg, NULL))
++ return -EINVAL;
++
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_4, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_8, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_12, 0xfff0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_16, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_20, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_24, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_28, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_32, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_36, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_40, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_44, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_48, 0x24000000);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_52, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_56, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_60, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_64, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_68, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_72, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_76, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_80, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_84, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_88, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_92, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_96, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_100, 0x02000000);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_104, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_108, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_112, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_116, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_120, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_124, 0xc);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_128, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_132, 0xcc500000);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_136, 0xcc);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_140, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_144, 0x0);
++
++ reg_set_bit(vin->rstgen_base, //r100_ctrl0_2d1c_efuse_en
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(6), 1<<6);
++ reg_set_bit(vin->rstgen_base, //r100_ctrl0_2d1c_efuse_in
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7), 0x1b<<7);
++ reg_set_bit(vin->rstgen_base, //r100_ctrl1_2d1c_efuse_en
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(13), 1<<13);
++ reg_set_bit(vin->rstgen_base, //r100_ctrl1_2d1c_efuse_in
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(19)|BIT(18)|BIT(17)|BIT(16)|BIT(15)|BIT(14), 0x1b<<14);
++
++ reg_set_bit(vin->rstgen_base, //data_bus16_8
++ M31DPHY_APBCFGSAIF__SYSCFG_184,
++ BIT(8), 0<<8);
++
++ reg_set_bit(vin->rstgen_base, //debug_mode_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_184,
++ BIT(15)|BIT(14)|BIT(13)|BIT(12)|BIT(11)|BIT(10)|BIT(9), 0x5a<<9);
++
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(0), cfg->lane_polarities[0]<<0);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(1), cfg->lane_polarities[1]<<1);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(2), cfg->lane_polarities[2]<<2);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(3), cfg->lane_polarities[3]<<3);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan2
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(4), cfg->lane_polarities[4]<<4);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan3
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(5), cfg->lane_polarities[5]<<5);
++ reg_set_bit(vin->rstgen_base, //enable clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(6), 1<<6);
++ reg_set_bit(vin->rstgen_base, //enable clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(7), 1<<7);
++ reg_set_bit(vin->rstgen_base, //enable lan0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(8), 1<<8);
++ reg_set_bit(vin->rstgen_base, //enable lan1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(9), 1<<9);
++ reg_set_bit(vin->rstgen_base, //enable lan2
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(10), 1<<10);
++ reg_set_bit(vin->rstgen_base, //enable lan3
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(11), 1<<11);
++ reg_set_bit(vin->rstgen_base, //gpi_en
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(17)|BIT(16)|BIT(15)|BIT(14)|BIT(13)|BIT(12),
++ 0<<12);
++ reg_set_bit(vin->rstgen_base, //hs_freq_change_clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(18), 0<<18);
++ reg_set_bit(vin->rstgen_base, //hs_freq_change_clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(19), 0<<19);
++
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(22)|BIT(21)|BIT(20), cfg->clock_lane<<20); //clock lane 0
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(25)|BIT(24)|BIT(23), cfg->clock1_lane<<23); //clock lane 1
++
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(28)|BIT(27)|BIT(26), cfg->data_lanes[0]<<26); //data lane 0
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(31)|BIT(30)|BIT(29), cfg->data_lanes[1]<<29); //data lane 1
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(2)|BIT(1)|BIT(0), cfg->data_lanes[2]<<0); //data lane 2
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(5)|BIT(4)|BIT(3), cfg->data_lanes[3]<<3); //data lane 3
++
++ reg_set_bit(vin->rstgen_base, //mp_test_en
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(6), 0<<6);
++ reg_set_bit(vin->rstgen_base, //mp_test_mode_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7), 0<<7);
++
++ reg_set_bit(vin->rstgen_base, //pll_clk_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(20)|BIT(19)|BIT(18)|BIT(17)|BIT(16)|BIT(15)|BIT(14)|BIT(13)|BIT(12),
++ 0x37c<<12);
++
++ reg_set_bit(vin->rstgen_base, //rx_1c2c_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_200,
++ BIT(8), 0<<8);
++
++ reg_set_bit(vin->rstgen_base, //precounter in clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(29)|BIT(28)|BIT(27)|BIT(26)|BIT(25)|BIT(24)|BIT(23)|BIT(22),
++ 8<<22);
++ reg_set_bit(vin->rstgen_base, //precounter in clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0),
++ 8<<0);
++ reg_set_bit(vin->rstgen_base, //precounter in lan0
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(15)|BIT(14)|BIT(13)|BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8),
++ 7<<8);
++ reg_set_bit(vin->rstgen_base, //precounter in lan1
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(23)|BIT(22)|BIT(21)|BIT(20)|BIT(19)|BIT(18)|BIT(17)|BIT(16),
++ 7<<16);
++ reg_set_bit(vin->rstgen_base, //precounter in lan2
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(31)|BIT(30)|BIT(29)|BIT(28)|BIT(27)|BIT(26)|BIT(25)|BIT(24),
++ 7<<24);
++ reg_set_bit(vin->rstgen_base, //precounter in lan3
++ M31DPHY_APBCFGSAIF__SYSCFG_200,
++ BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0),
++ 7<<0);
++
++ return 0;
++}
++
++static int stf_csiphy_config_set(struct stf_csiphy_dev *csiphy_dev)
++{
++ struct stf_vin_dev *vin = csiphy_dev->stfcamss->vin;
++
++ csi2rx_dphy_config(vin, csiphy_dev);
++ return 0;
++}
++
++static int stf_csiphy_stream_set(struct stf_csiphy_dev *csiphy_dev, int on)
++{
++ return 0;
++}
++
++struct csiphy_hw_ops csiphy_ops = {
++ .csiphy_clk_enable = stf_csiphy_clk_enable,
++ .csiphy_clk_disable = stf_csiphy_clk_disable,
++ .csiphy_config_set = stf_csiphy_config_set,
++ .csiphy_stream_set = stf_csiphy_stream_set,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.c
+@@ -0,0 +1,123 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/dma-buf.h>
++#include <media/v4l2-subdev.h>
++#include <media/videobuf2-dma-contig.h>
++
++#include "stf_isp_ioctl.h"
++#include "stf_dmabuf.h"
++
++#define TOTAL_SIZE_LIMIT (64 * 1024 * 1024)
++
++static size_t total_size;
++static struct vb2_queue vb2_queue = {
++ .dma_attrs = 0,
++ .gfp_flags = 0,
++ .dma_dir = DMA_TO_DEVICE,
++};
++static struct vb2_buffer vb = {
++ .vb2_queue = &vb2_queue,
++};
++
++static int dmabuf_create(struct device *dev,
++ struct dmabuf_create *head)
++{
++ struct dma_buf *dmabuf = NULL;
++ void *mem_priv = NULL;
++ dma_addr_t *paddr = NULL;
++ int ret = 0;
++
++ mem_priv = vb2_dma_contig_memops.alloc(&vb, dev, head->size);
++ if (IS_ERR_OR_NULL(mem_priv)) {
++ if (mem_priv)
++ ret = PTR_ERR(mem_priv);
++ goto exit;
++ }
++
++ dmabuf = vb2_dma_contig_memops.get_dmabuf(&vb, mem_priv, O_RDWR);
++ if (IS_ERR(dmabuf)) {
++ ret = PTR_ERR(dmabuf);
++ goto free;
++ }
++
++ head->fd = dma_buf_fd(dmabuf, O_CLOEXEC);
++ if (head->fd < 0) {
++ dma_buf_put(dmabuf);
++ ret = head->fd;
++ goto free;
++ }
++
++ paddr = vb2_dma_contig_memops.cookie(&vb, mem_priv);
++ head->paddr = *paddr;
++ return 0;
++free:
++ vb2_dma_contig_memops.put(mem_priv);
++exit:
++ return ret;
++}
++
++int stf_dmabuf_ioctl_alloc(struct device *dev, void *arg)
++{
++ struct dmabuf_create *head = arg;
++ int ret = -EINVAL;
++
++ if (IS_ERR_OR_NULL(head))
++ return -EFAULT;
++
++ head->size = PAGE_ALIGN(head->size);
++ if (!head->size)
++ return -EINVAL;
++ if ((head->size + total_size) > TOTAL_SIZE_LIMIT)
++ return -ENOMEM;
++
++ ret = dmabuf_create(dev, head);
++ if (ret)
++ return -EFAULT;
++
++ total_size += head->size;
++ return ret;
++}
++
++int stf_dmabuf_ioctl_free(struct device *dev, void *arg)
++{
++ struct dmabuf_create *head = arg;
++ struct dma_buf *dmabuf = NULL;
++ int ret = 0;
++
++ if (IS_ERR_OR_NULL(head))
++ return -EFAULT;
++ if (head->size != PAGE_ALIGN(head->size))
++ return -EINVAL;
++ if (head->size > total_size)
++ return -EINVAL;
++
++ dmabuf = dma_buf_get(head->fd);
++ if (IS_ERR_OR_NULL(dmabuf))
++ return -EINVAL;
++
++ dma_buf_put(dmabuf);
++ vb2_dma_contig_memops.put(dmabuf->priv);
++ total_size -= head->size;
++ return ret;
++}
++
++int stf_dmabuf_ioctl(struct device *dev, unsigned int cmd, void *arg)
++{
++ int ret = -ENOIOCTLCMD;
++
++ switch (cmd) {
++ case VIDIOC_STF_DMABUF_ALLOC:
++ ret = stf_dmabuf_ioctl_alloc(dev, arg);
++ break;
++ case VIDIOC_STF_DMABUF_FREE:
++ ret = stf_dmabuf_ioctl_free(dev, arg);
++ break;
++ default:
++ break;
++ }
++ return ret;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.h
+@@ -0,0 +1,12 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_DMABUF_H
++#define STF_DMABUF_H
++
++extern int stf_dmabuf_ioctl(struct device *dev, unsigned int cmd, void *arg);
++
++#endif /* STF_DMABUF_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dvp.c
+@@ -0,0 +1,385 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static const struct dvp_format dvp_formats_st7110[] = {
++ { MEDIA_BUS_FMT_YUYV8_2X8, 8},
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, 8},
++ { MEDIA_BUS_FMT_SRGGB8_1X8, 8},
++ { MEDIA_BUS_FMT_SGRBG8_1X8, 8},
++ { MEDIA_BUS_FMT_SGBRG8_1X8, 8},
++ { MEDIA_BUS_FMT_SBGGR8_1X8, 8},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 8},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 8},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 8},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 8},
++};
++
++static int dvp_find_format(u32 code,
++ const struct dvp_format *formats,
++ unsigned int nformats)
++{
++ int i;
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].code == code)
++ return i;
++ return -EINVAL;
++}
++
++int stf_dvp_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
++
++ dvp_dev->s_type = SENSOR_VIN;
++ dvp_dev->hw_ops = &dvp_ops;
++ dvp_dev->stfcamss = stfcamss;
++ dvp_dev->formats = dvp_formats_st7110;
++ dvp_dev->nformats = ARRAY_SIZE(dvp_formats_st7110);
++ mutex_init(&dvp_dev->stream_lock);
++ dvp_dev->stream_count = 0;
++ return 0;
++}
++
++static int dvp_set_power(struct v4l2_subdev *sd, int on)
++{
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__dvp_get_format(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(
++ &dvp_dev->subdev, state, pad);
++ return &dvp_dev->fmt[pad];
++}
++
++static int dvp_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ int ret = 0;
++
++ format = __dvp_get_format(dvp_dev, NULL, STF_DVP_PAD_SRC,
++ V4L2_SUBDEV_FORMAT_ACTIVE);
++ if (format == NULL)
++ return -EINVAL;
++ ret = dvp_find_format(format->code,
++ dvp_dev->formats,
++ dvp_dev->nformats);
++ if (ret < 0)
++ return ret;
++
++ mutex_lock(&dvp_dev->stream_lock);
++ if (enable) {
++ if (dvp_dev->stream_count == 0) {
++ dvp_dev->hw_ops->dvp_clk_enable(dvp_dev);
++ dvp_dev->hw_ops->dvp_config_set(dvp_dev);
++ dvp_dev->hw_ops->dvp_set_format(dvp_dev,
++ format->width, dvp_dev->formats[ret].bpp);
++ dvp_dev->hw_ops->dvp_stream_set(dvp_dev, 1);
++ }
++ dvp_dev->stream_count++;
++ } else {
++ if (dvp_dev->stream_count == 0)
++ goto exit;
++ if (dvp_dev->stream_count == 1) {
++ dvp_dev->hw_ops->dvp_stream_set(dvp_dev, 0);
++ dvp_dev->hw_ops->dvp_clk_disable(dvp_dev);
++ }
++ dvp_dev->stream_count--;
++ }
++exit:
++ mutex_unlock(&dvp_dev->stream_lock);
++ return 0;
++}
++
++static void dvp_try_format(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_DVP_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < dvp_dev->nformats; i++)
++ if (fmt->code == dvp_dev->formats[i].code)
++ break;
++
++ if (i >= dvp_dev->nformats)
++ fmt->code = dvp_dev->formats[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_DVP_PAD_SRC:
++
++ *fmt = *__dvp_get_format(dvp_dev, state, STF_DVP_PAD_SINK, which);
++
++ break;
++ }
++}
++
++static int dvp_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++
++ if (code->index >= dvp_dev->nformats)
++ return -EINVAL;
++
++ if (code->pad == STF_DVP_PAD_SINK) {
++ code->code = dvp_dev->formats[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __dvp_get_format(dvp_dev, state, STF_DVP_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++
++ return 0;
++}
++
++static int dvp_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ dvp_try_format(dvp_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ dvp_try_format(dvp_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int dvp_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __dvp_get_format(dvp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int dvp_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __dvp_get_format(dvp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&dvp_dev->stream_lock);
++ if (dvp_dev->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&dvp_dev->stream_lock);
++ goto out;
++ } else {
++ dvp_try_format(dvp_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&dvp_dev->stream_lock);
++
++ /* Propagate the format from sink to source */
++ if (fmt->pad == STF_DVP_PAD_SINK) {
++ format = __dvp_get_format(dvp_dev, state, STF_DVP_PAD_SRC,
++ fmt->which);
++
++ *format = fmt->format;
++ dvp_try_format(dvp_dev, state, STF_DVP_PAD_SRC, format,
++ fmt->which);
++ }
++
++out:
++ return 0;
++}
++
++static int dvp_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_DVP_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return dvp_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int dvp_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if ((local->flags & MEDIA_PAD_FL_SOURCE) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_dvp_dev *dvp_dev;
++ struct vin_line *line;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ dvp_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ line = v4l2_get_subdevdata(sd);
++ if (line->sdev_type == VIN_DEV_TYPE)
++ dvp_dev->s_type = SENSOR_VIN;
++ if (line->sdev_type == ISP_DEV_TYPE)
++ dvp_dev->s_type = SENSOR_ISP;
++ st_info(ST_DVP, "DVP device sensor type: %d\n", dvp_dev->s_type);
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops dvp_core_ops = {
++ .s_power = dvp_set_power,
++};
++
++static const struct v4l2_subdev_video_ops dvp_video_ops = {
++ .s_stream = dvp_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops dvp_pad_ops = {
++ .enum_mbus_code = dvp_enum_mbus_code,
++ .enum_frame_size = dvp_enum_frame_size,
++ .get_fmt = dvp_get_format,
++ .set_fmt = dvp_set_format,
++};
++
++static const struct v4l2_subdev_ops dvp_v4l2_ops = {
++ .core = &dvp_core_ops,
++ .video = &dvp_video_ops,
++ .pad = &dvp_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops dvp_v4l2_internal_ops = {
++ .open = dvp_init_formats,
++};
++
++static const struct media_entity_operations dvp_media_ops = {
++ .link_setup = dvp_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_dvp_register(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &dvp_dev->subdev;
++ struct media_pad *pads = dvp_dev->pads;
++ int ret;
++
++ v4l2_subdev_init(sd, &dvp_v4l2_ops);
++ sd->internal_ops = &dvp_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_DVP_NAME, 0);
++ v4l2_set_subdevdata(sd, dvp_dev);
++
++ ret = dvp_init_formats(sd, NULL);
++ if (ret < 0) {
++ st_err(ST_DVP, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_DVP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_DVP_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &dvp_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_DVP_PADS_NUM, pads);
++ if (ret < 0) {
++ st_err(ST_DVP, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ st_err(ST_DVP, "Failed to register subdev: %d\n", ret);
++ goto err_sreg;
++ }
++
++ return 0;
++
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_dvp_unregister(struct stf_dvp_dev *dvp_dev)
++{
++ v4l2_device_unregister_subdev(&dvp_dev->subdev);
++ media_entity_cleanup(&dvp_dev->subdev.entity);
++ mutex_destroy(&dvp_dev->stream_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dvp.h
+@@ -0,0 +1,67 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_DVP_H
++#define STF_DVP_H
++
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_DVP_NAME "stf_dvp"
++
++#define STF_DVP_PAD_SINK 0
++#define STF_DVP_PAD_SRC 1
++#define STF_DVP_PADS_NUM 2
++
++struct dvp_format {
++ u32 code;
++ u8 bpp;
++};
++
++enum sensor_type;
++enum subdev_type;
++
++struct dvp_cfg {
++ unsigned int flags;
++ unsigned char bus_width;
++ unsigned char data_shift;
++};
++
++struct stf_dvp_dev;
++
++struct dvp_hw_ops {
++ int (*dvp_clk_enable)(struct stf_dvp_dev *dvp_dev);
++ int (*dvp_clk_disable)(struct stf_dvp_dev *dvp_dev);
++ int (*dvp_config_set)(struct stf_dvp_dev *dvp_dev);
++ int (*dvp_set_format)(struct stf_dvp_dev *dvp_dev,
++ u32 pix_width, u8 bpp);
++ int (*dvp_stream_set)(struct stf_dvp_dev *dvp_dev, int on);
++};
++
++struct stf_dvp_dev {
++ struct stfcamss *stfcamss;
++ struct dvp_cfg *dvp;
++ enum sensor_type s_type;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_DVP_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_DVP_PADS_NUM];
++ const struct dvp_format *formats;
++ unsigned int nformats;
++ struct dvp_hw_ops *hw_ops;
++ struct mutex stream_lock;
++ int stream_count;
++};
++
++extern int stf_dvp_subdev_init(struct stfcamss *stfcamss);
++extern int stf_dvp_register(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_dvp_unregister(struct stf_dvp_dev *dvp_dev);
++
++extern struct dvp_hw_ops dvp_ops;
++
++#endif /* STF_DVP_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dvp_hw_ops.c
+@@ -0,0 +1,187 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++
++static int stf_dvp_clk_enable(struct stf_dvp_dev *dvp_dev)
++{
++ struct stfcamss *stfcamss = dvp_dev->stfcamss;
++
++ switch (dvp_dev->s_type) {
++ case SENSOR_VIN:
++ reset_control_deassert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ clk_set_phase(stfcamss->sys_clk[STFCLK_DVP_INV].clk, 0);
++ clk_set_parent(stfcamss->sys_clk[STFCLK_AXIWR].clk,
++ stfcamss->sys_clk[STFCLK_DVP_INV].clk);
++ break;
++ case SENSOR_ISP:
++ clk_set_phase(stfcamss->sys_clk[STFCLK_DVP_INV].clk, 0);
++ clk_set_parent(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk,
++ stfcamss->sys_clk[STFCLK_DVP_INV].clk);
++ break;
++ }
++
++ return 0;
++}
++
++static int stf_dvp_clk_disable(struct stf_dvp_dev *dvp_dev)
++{
++ struct stfcamss *stfcamss = dvp_dev->stfcamss;
++
++ switch (dvp_dev->s_type) {
++ case SENSOR_VIN:
++ clk_set_parent(stfcamss->sys_clk[STFCLK_AXIWR].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ reset_control_assert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ break;
++ case SENSOR_ISP:
++ clk_set_parent(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ break;
++ }
++
++ return 0;
++}
++
++static int stf_dvp_config_set(struct stf_dvp_dev *dvp_dev)
++{
++
++ struct stf_vin_dev *vin = dvp_dev->stfcamss->vin;
++ unsigned int flags = 0;
++ unsigned char data_shift = 0;
++ u32 polarities = 0;
++
++ if (!dvp_dev->dvp)
++ return -EINVAL;
++
++ flags = dvp_dev->dvp->flags;
++ data_shift = dvp_dev->dvp->data_shift;
++ st_info(ST_DVP, "%s, polarities = 0x%x, flags = 0x%x\n",
++ __func__, polarities, flags);
++
++ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
++ polarities |= BIT(1);
++ if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
++ polarities |= BIT(3);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_36);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_DVP_HS_POS
++ | U0_VIN_CNFG_DVP_VS_POS,
++ polarities);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_36);
++
++ switch (data_shift) {
++ case 0:
++ data_shift = 0;
++ break;
++ case 2:
++ data_shift = 1;
++ break;
++ case 4:
++ data_shift = 2;
++ break;
++ case 6:
++ data_shift = 3;
++ break;
++ default:
++ data_shift = 0;
++ break;
++ };
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ UO_VIN_CNFG_AXIWR0_PIXEL_HEIGH_BIT_SEL,
++ data_shift << 15);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++
++ return 0;
++}
++
++static int set_vin_axiwr_pix_ct(struct stf_vin_dev *vin, u8 bpp)
++{
++ u32 value = 0;
++ int cnfg_axiwr_pix_ct = 64 / bpp;
++
++ // need check
++ if (cnfg_axiwr_pix_ct == 2)
++ value = 1;
++ else if (cnfg_axiwr_pix_ct == 4)
++ value = 1;
++ else if (cnfg_axiwr_pix_ct == 8)
++ value = 0;
++ else
++ return 0;
++
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++ reg_set_bit(vin->sysctrl_base,
++ SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_PIX_CT,
++ value<<13);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++
++ return cnfg_axiwr_pix_ct;
++
++}
++
++static int stf_dvp_set_format(struct stf_dvp_dev *dvp_dev,
++ u32 pix_width, u8 bpp)
++{
++ struct stf_vin_dev *vin = dvp_dev->stfcamss->vin;
++ int val, pix_ct;
++
++ if (dvp_dev->s_type == SENSOR_VIN) {
++ pix_ct = set_vin_axiwr_pix_ct(vin, bpp);
++ val = (pix_width / pix_ct) - 1;
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCTRL_VIN_WR_PIX_TOTAL);
++ reg_set_bit(vin->sysctrl_base,
++ SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_PIX_CNT_END,
++ val << 2);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCTRL_VIN_WR_PIX_TOTAL);
++
++ }
++
++ return 0;
++}
++
++static int stf_dvp_stream_set(struct stf_dvp_dev *dvp_dev, int on)
++{
++ struct stf_vin_dev *vin = dvp_dev->stfcamss->vin;
++
++ switch (dvp_dev->s_type) {
++ case SENSOR_VIN:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_ISP_DVP_EN0,
++ 0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_0,
++ U0_VIN_CNFG_AXI_DVP_EN,
++ !!on<<2);
++ break;
++ case SENSOR_ISP:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_ISP_DVP_EN0,
++ !!on<<5);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_0,
++ U0_VIN_CNFG_AXI_DVP_EN,
++ 0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_DVP_SWAP_EN,
++ 0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_GEN_EN_AXIRD,
++ 0);
++ break;
++ }
++
++ return 0;
++}
++
++struct dvp_hw_ops dvp_ops = {
++ .dvp_clk_enable = stf_dvp_clk_enable,
++ .dvp_clk_disable = stf_dvp_clk_disable,
++ .dvp_config_set = stf_dvp_config_set,
++ .dvp_set_format = stf_dvp_set_format,
++ .dvp_stream_set = stf_dvp_stream_set,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_event.c
+@@ -0,0 +1,36 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/notifier.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++
++static ATOMIC_NOTIFIER_HEAD(vin_notifier_list);
++
++int vin_notifier_register(struct notifier_block *nb)
++{
++ return atomic_notifier_chain_register(&vin_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(vin_notifier_register);
++
++void vin_notifier_unregister(struct notifier_block *nb)
++{
++ atomic_notifier_chain_unregister(&vin_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(vin_notifier_unregister);
++
++int vin_notifier_call(unsigned long e, void *v)
++{
++ return atomic_notifier_call_chain(&vin_notifier_list, e, v);
++}
++EXPORT_SYMBOL_GPL(vin_notifier_call);
++
++MODULE_AUTHOR("StarFive Technology Co., Ltd.");
++MODULE_DESCRIPTION("Starfive VIC video in notifier");
++MODULE_LICENSE("GPL");
++//MODULE_SUPPORTED_DEVICE("video");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -0,0 +1,1521 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include <linux/firmware.h>
++#include <linux/jh7110-isp.h>
++#include "stf_isp_ioctl.h"
++#include "stf_dmabuf.h"
++
++static int user_config_isp;
++static int isp_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel);
++
++static struct v4l2_rect *
++__isp_get_compose(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which);
++
++static struct v4l2_rect *
++__isp_get_crop(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which);
++
++static struct v4l2_rect *
++__isp_get_scale(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel);
++
++static struct v4l2_rect *
++__isp_get_itiws(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which);
++
++// sink format and raw format must one by one
++static const struct isp_format isp_formats_st7110_sink[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++static const struct isp_format isp_formats_st7110_raw[] = {
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++};
++
++static const struct isp_format isp_formats_st7110_compat_10bit_raw[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++static const struct isp_format isp_formats_st7110_compat_8bit_raw[] = {
++ { MEDIA_BUS_FMT_SRGGB8_1X8, 8},
++ { MEDIA_BUS_FMT_SGRBG8_1X8, 8},
++ { MEDIA_BUS_FMT_SGBRG8_1X8, 8},
++ { MEDIA_BUS_FMT_SBGGR8_1X8, 8},
++};
++
++static const struct isp_format isp_formats_st7110_uo[] = {
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++};
++
++static const struct isp_format isp_formats_st7110_iti[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++ { MEDIA_BUS_FMT_YUV8_1X24, 8},
++};
++
++static const struct isp_format_table isp_formats_st7110[] = {
++ { isp_formats_st7110_sink, ARRAY_SIZE(isp_formats_st7110_sink) }, /* pad 0 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) }, /* pad 1 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) }, /* pad 2 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) }, /* pad 3 */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) }, /* pad 4 */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) }, /* pad 5 */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) }, /* pad 6 */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) }, /* pad 7 */
++};
++
++int stf_isp_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++
++ isp_dev->sdev_type = ISP_DEV_TYPE;
++ isp_dev->hw_ops = &isp_ops;
++ isp_dev->stfcamss = stfcamss;
++ isp_dev->formats = isp_formats_st7110;
++ isp_dev->nformats = ARRAY_SIZE(isp_formats_st7110);
++ mutex_init(&isp_dev->stream_lock);
++ mutex_init(&isp_dev->power_lock);
++ mutex_init(&isp_dev->setfile_lock);
++ atomic_set(&isp_dev->shadow_count, 0);
++ return 0;
++}
++
++/*
++ * ISP Controls.
++ */
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct stf_isp_dev,
++ ctrls.handler)->subdev;
++}
++
++static u64 isp_calc_pixel_rate(struct stf_isp_dev *isp_dev)
++{
++ u64 rate = 0;
++
++ return rate;
++}
++
++static int isp_set_ctrl_hue(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_contrast(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_saturation(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_white_balance(struct stf_isp_dev *isp_dev, int awb)
++{
++ struct isp_ctrls *ctrls = &isp_dev->ctrls;
++ int ret = 0;
++
++ if (!awb && (ctrls->red_balance->is_new
++ || ctrls->blue_balance->is_new)) {
++ u16 red = (u16)ctrls->red_balance->val;
++ u16 blue = (u16)ctrls->blue_balance->val;
++
++ st_debug(ST_ISP, "red = 0x%x, blue = 0x%x\n", red, blue);
++ //isp_dev->hw_ops->isp_set_awb_r_gain(isp_dev, red);
++ //if (ret)
++ // return ret;
++ //isp_dev->hw_ops->isp_set_awb_b_gain(isp_dev, blue);
++ }
++
++ return ret;
++}
++
++static int isp_set_ctrl_exposure(struct stf_isp_dev *isp_dev,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_gain(struct stf_isp_dev *isp_dev, bool auto_gain)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++#define ISP_TEST_ENABLE BIT(7)
++#define ISP_TEST_ROLLING BIT(6) /* rolling horizontal bar */
++#define ISP_TEST_TRANSPARENT BIT(5)
++#define ISP_TEST_SQUARE_BW BIT(4) /* black & white squares */
++#define ISP_TEST_BAR_STANDARD (0 << 2)
++#define ISP_TEST_BAR_VERT_CHANGE_1 (1 << 2)
++#define ISP_TEST_BAR_HOR_CHANGE (2 << 2)
++#define ISP_TEST_BAR_VERT_CHANGE_2 (3 << 2)
++#define ISP_TEST_BAR (0 << 0)
++#define ISP_TEST_RANDOM (1 << 0)
++#define ISP_TEST_SQUARE (2 << 0)
++#define ISP_TEST_BLACK (3 << 0)
++
++static const u8 test_pattern_val[] = {
++ 0,
++ ISP_TEST_ENABLE | ISP_TEST_BAR_VERT_CHANGE_1 |
++ ISP_TEST_BAR,
++ ISP_TEST_ENABLE | ISP_TEST_ROLLING |
++ ISP_TEST_BAR_VERT_CHANGE_1 | ISP_TEST_BAR,
++ ISP_TEST_ENABLE | ISP_TEST_SQUARE,
++ ISP_TEST_ENABLE | ISP_TEST_ROLLING | ISP_TEST_SQUARE,
++};
++
++static int isp_set_ctrl_test_pattern(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ // return isp_write_reg(isp_dev, ISP_REG_PRE_ISP_TEST_SET1,
++ // test_pattern_val[value]);
++ return ret;
++}
++
++static int isp_set_ctrl_light_freq(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_hflip(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_vflip(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ break;
++ }
++
++ return 0;
++}
++
++static int isp_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ int ret = 0;
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored right after power-up.
++ */
++ mutex_lock(&isp_dev->power_lock);
++ if (isp_dev->power_count == 0) {
++ mutex_unlock(&isp_dev->power_lock);
++ return 0;
++ }
++ mutex_unlock(&isp_dev->power_lock);
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ ret = isp_set_ctrl_gain(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ ret = isp_set_ctrl_exposure(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = isp_set_ctrl_white_balance(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = isp_set_ctrl_hue(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = isp_set_ctrl_contrast(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = isp_set_ctrl_saturation(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = isp_set_ctrl_test_pattern(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = isp_set_ctrl_light_freq(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = isp_set_ctrl_hflip(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = isp_set_ctrl_vflip(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_WB_SETTING:
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CAR_SETTING:
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CCM_SETTING:
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops isp_ctrl_ops = {
++ .g_volatile_ctrl = isp_g_volatile_ctrl,
++ .s_ctrl = isp_s_ctrl,
++};
++
++struct v4l2_ctrl_config isp_ctrl[] = {
++ [0] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "WB Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_WB_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_wb_setting),
++ .flags = 0,
++ },
++ [1] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "Car Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CAR_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_car_setting),
++ .flags = 0,
++ },
++ [2] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CCM Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CCM_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_ccm_setting),
++ .flags = 0,
++ },
++};
++
++static int isp_init_controls(struct stf_isp_dev *isp_dev)
++{
++ const struct v4l2_ctrl_ops *ops = &isp_ctrl_ops;
++ struct isp_ctrls *ctrls = &isp_dev->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++ int i;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ isp_calc_pixel_rate(isp_dev));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 1);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 0);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 0);
++ /* Auto/manual exposure */
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ V4L2_EXPOSURE_AUTO);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 0);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 1);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0);
++
++ ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
++ 0, 255, 1, 64);
++ ctrls->hue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HUE,
++ 0, 359, 1, 0);
++ ctrls->contrast = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST,
++ 0, 255, 1, 0);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++
++ for (i = 0; i < ARRAY_SIZE(isp_ctrl); i++)
++ v4l2_ctrl_new_custom(hdl, &isp_ctrl[i], NULL);
++
++
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
++
++ isp_dev->subdev.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int isp_set_power(struct v4l2_subdev *sd, int on)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++
++ st_debug(ST_ISP, "%s, %d\n", __func__, __LINE__);
++ mutex_lock(&isp_dev->power_lock);
++ if (on) {
++ if (isp_dev->power_count == 0)
++ st_debug(ST_ISP, "turn on isp\n");
++ isp_dev->power_count++;
++ } else {
++ if (isp_dev->power_count == 0)
++ goto exit;
++ isp_dev->power_count--;
++ }
++exit:
++ mutex_unlock(&isp_dev->power_lock);
++
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__isp_get_format(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(&isp_dev->subdev, state, pad);
++
++ return &isp_dev->fmt[pad];
++}
++
++static int isp_get_interface_type(struct media_entity *entity)
++{
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad = &entity->pads[0];
++
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ return -EINVAL;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ return -EINVAL;
++
++ subdev = media_entity_to_v4l2_subdev(pad->entity);
++
++ st_debug(ST_ISP, "interface subdev name %s\n", subdev->name);
++ if (!strncmp(subdev->name, STF_CSI_NAME, strlen(STF_CSI_NAME)))
++ return CSI_SENSOR;
++ if (!strncmp(subdev->name, STF_DVP_NAME, strlen(STF_DVP_NAME)))
++ return DVP_SENSOR;
++ return -EINVAL;
++}
++
++static int isp_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ int ret = 0, interface_type;
++ struct v4l2_mbus_framefmt *fmt;
++ struct v4l2_event src_ch = { 0 };
++
++ fmt = __isp_get_format(isp_dev, NULL, STF_ISP_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE);
++ mutex_lock(&isp_dev->stream_lock);
++ if (enable) {
++ if (isp_dev->stream_count == 0) {
++ isp_dev->hw_ops->isp_clk_enable(isp_dev);
++ if (!user_config_isp)
++ isp_dev->hw_ops->isp_config_set(isp_dev);
++ interface_type = isp_get_interface_type(&sd->entity);
++ if (interface_type < 0) {
++ st_err(ST_ISP, "%s, pipeline not config\n", __func__);
++ goto exit;
++ }
++ isp_dev->hw_ops->isp_set_format(isp_dev,
++ isp_dev->rect, fmt->code, interface_type);
++ isp_dev->hw_ops->isp_reset(isp_dev);
++ isp_dev->hw_ops->isp_stream_set(isp_dev, enable);
++ user_config_isp = 0;
++ }
++ isp_dev->stream_count++;
++ } else {
++ if (isp_dev->stream_count == 0)
++ goto exit;
++ if (isp_dev->stream_count == 1) {
++ isp_dev->hw_ops->isp_stream_set(isp_dev, enable);
++ isp_dev->hw_ops->isp_clk_disable(isp_dev);
++ }
++ isp_dev->stream_count--;
++ }
++ src_ch.type = V4L2_EVENT_SOURCE_CHANGE,
++ src_ch.u.src_change.changes = isp_dev->stream_count,
++
++ v4l2_subdev_notify_event(sd, &src_ch);
++exit:
++ mutex_unlock(&isp_dev->stream_lock);
++
++ mutex_lock(&isp_dev->power_lock);
++ /* restore controls */
++ if (enable && isp_dev->power_count == 1) {
++ mutex_unlock(&isp_dev->power_lock);
++ ret = v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
++ } else
++ mutex_unlock(&isp_dev->power_lock);
++
++ return ret;
++}
++
++/*Try to match sensor format with sink, and then get the index as default.*/
++static int isp_match_sensor_format_get_index(struct stf_isp_dev *isp_dev)
++{
++ int ret, idx;
++ struct media_entity *sensor;
++ struct v4l2_subdev *subdev;
++ struct v4l2_subdev_format fmt;
++ const struct isp_format_table *formats;
++
++ if (!isp_dev)
++ return -EINVAL;
++
++ sensor = stfcamss_find_sensor(&isp_dev->subdev.entity);
++ if (!sensor)
++ return -EINVAL;
++
++ subdev = media_entity_to_v4l2_subdev(sensor);
++ st_debug(ST_ISP, "Found sensor = %s\n", sensor->name);
++
++ fmt.pad = 0;
++ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
++ if (ret) {
++ st_warn(ST_ISP, "Sonser get format failed !!\n");
++ return -EINVAL;
++ }
++
++ st_debug(ST_ISP, "Got sensor format 0x%x !!\n", fmt.format.code);
++
++ formats = &isp_dev->formats[0]; /* isp sink format */
++ for (idx = 0; idx < formats->nfmts; idx++) {
++ if (formats->fmts[idx].code == fmt.format.code) {
++ st_info(ST_ISP,
++ "Match sensor format to isp_formats_st7110_sink index %d !!\n",
++ idx);
++ return idx;
++ }
++ }
++ return -ERANGE;
++}
++
++static int isp_match_format_get_index(const struct isp_format_table *f_table,
++ __u32 mbus_code,
++ unsigned int pad)
++{
++ int i;
++
++ for (i = 0; i < f_table->nfmts; i++) {
++ if (mbus_code == f_table->fmts[i].code) {
++ break;
++ } else {
++ if (pad == STF_ISP_PAD_SRC_RAW || pad == STF_ISP_PAD_SRC_SCD_Y) {
++ if (mbus_code == (isp_formats_st7110_compat_10bit_raw[i].code ||
++ isp_formats_st7110_compat_8bit_raw[i].code))
++ break;
++ }
++ }
++ }
++
++ return i;
++}
++
++static void isp_try_format(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ const struct isp_format_table *formats;
++ unsigned int i;
++ u32 code = fmt->code;
++ u32 bpp;
++
++ if (pad == STF_ISP_PAD_SINK) {
++ /* Set format on sink pad */
++
++ formats = &isp_dev->formats[pad];
++ fmt->width = clamp_t(u32,
++ fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++ fmt->height &= ~0x1;
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++ } else {
++ formats = &isp_dev->formats[pad];
++ }
++
++ i = isp_match_format_get_index(formats, fmt->code, pad);
++ st_debug(ST_ISP, "%s pad=%d, code=%x isp_match_format_get_index = %d\n",
++ __func__, pad, code, i);
++
++ if (i >= formats->nfmts &&
++ (pad == STF_ISP_PAD_SRC_RAW || pad == STF_ISP_PAD_SRC_SCD_Y)) {
++ int sensor_idx;
++
++ sensor_idx = isp_match_sensor_format_get_index(isp_dev);
++ if (sensor_idx)
++ i = sensor_idx;
++ }
++
++ if (pad != STF_ISP_PAD_SINK)
++ *fmt = *__isp_get_format(isp_dev, state, STF_ISP_PAD_SINK, which);
++
++ if (i >= formats->nfmts) {
++ fmt->code = formats->fmts[0].code;
++ bpp = formats->fmts[0].bpp;
++ st_info(ST_ISP, "Use default index 0 format = 0x%x\n", fmt->code);
++ } else {
++ // sink format and raw format must one by one
++ if (pad == STF_ISP_PAD_SRC_RAW || pad == STF_ISP_PAD_SRC_SCD_Y) {
++ fmt->code = formats->fmts[i].code;
++ bpp = formats->fmts[i].bpp;
++ st_info(ST_ISP, "Use mapping format from sink index %d = 0x%x\n",
++ i, fmt->code);
++ } else {
++ fmt->code = code;
++ bpp = formats->fmts[i].bpp;
++ st_info(ST_ISP, "Use input format = 0x%x\n", fmt->code);
++ }
++ }
++
++ switch (pad) {
++ case STF_ISP_PAD_SINK:
++ break;
++ case STF_ISP_PAD_SRC:
++ isp_dev->rect[ISP_COMPOSE].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_SS0:
++ isp_dev->rect[ISP_SCALE_SS0].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_SS1:
++ isp_dev->rect[ISP_SCALE_SS1].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_ITIW:
++ case STF_ISP_PAD_SRC_ITIR:
++ isp_dev->rect[ISP_ITIWS].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_RAW:
++ isp_dev->rect[ISP_CROP].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_SCD_Y:
++ break;
++ }
++}
++
++static int isp_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ const struct isp_format_table *formats;
++
++ if (code->index >= isp_dev->formats[code->pad].nfmts)
++ return -EINVAL;
++
++ formats = &isp_dev->formats[code->pad];
++ code->code = formats->fmts[code->index].code;
++ code->flags = 0;
++
++ return 0;
++}
++
++static int isp_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int isp_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int isp_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ struct v4l2_subdev_selection sel = { 0 };
++ struct v4l2_rect *rect = NULL;
++ int ret;
++
++ st_debug(ST_ISP, "%s pad=%d, code=%x, which=%d\n",
++ __func__, fmt->reserved[0], fmt->format.code, fmt->which);
++ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ fmt->format = *format;
++ if (fmt->reserved[0] != 0) {
++ sel.which = fmt->which;
++ sel.pad = fmt->reserved[0];
++
++ switch (fmt->reserved[0]) {
++ case STF_ISP_PAD_SRC:
++ rect = __isp_get_compose(isp_dev, state, fmt->which);
++ break;
++ case STF_ISP_PAD_SRC_SS0:
++ case STF_ISP_PAD_SRC_SS1:
++ rect = __isp_get_scale(isp_dev, state, &sel);
++ break;
++ case STF_ISP_PAD_SRC_ITIW:
++ case STF_ISP_PAD_SRC_ITIR:
++ rect = __isp_get_itiws(isp_dev, state, fmt->which);
++ break;
++ case STF_ISP_PAD_SRC_RAW:
++ case STF_ISP_PAD_SRC_SCD_Y:
++ rect = __isp_get_crop(isp_dev, state, fmt->which);
++ break;
++ default:
++ break;
++ }
++ if (rect != NULL) {
++ fmt->format.width = rect->width;
++ fmt->format.height = rect->height;
++ }
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++ goto out;
++ } else {
++ isp_try_format(isp_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Propagate the format from sink to source */
++ if (fmt->pad == STF_ISP_PAD_SINK) {
++ /* Reset sink pad compose selection */
++ sel.which = fmt->which;
++ sel.pad = STF_ISP_PAD_SINK;
++ sel.target = V4L2_SEL_TGT_CROP;
++ sel.r.width = fmt->format.width;
++ sel.r.height = fmt->format.height;
++ ret = isp_set_selection(sd, state, &sel);
++ if (ret < 0)
++ return ret;
++ }
++
++out:
++ return 0;
++}
++
++static struct v4l2_rect *
++__isp_get_compose(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_compose(&isp_dev->subdev, state,
++ STF_ISP_PAD_SINK);
++
++
++ return &isp_dev->rect[ISP_COMPOSE].rect;
++}
++
++static struct v4l2_rect *
++__isp_get_crop(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_crop(&isp_dev->subdev, state,
++ STF_ISP_PAD_SINK);
++
++ return &isp_dev->rect[ISP_CROP].rect;
++}
++
++static struct v4l2_rect *
++__isp_get_scale(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ int pad;
++
++ if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_compose(&isp_dev->subdev, state,
++ STF_ISP_PAD_SINK);
++ if (sel->pad != STF_ISP_PAD_SRC_SS0 && sel->pad != STF_ISP_PAD_SRC_SS1)
++ return NULL;
++
++ pad = sel->pad == STF_ISP_PAD_SRC_SS0 ? ISP_SCALE_SS0 : ISP_SCALE_SS1;
++ return &isp_dev->rect[pad].rect;
++}
++
++static struct v4l2_rect *
++__isp_get_itiws(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_crop(&isp_dev->subdev, state, STF_ISP_PAD_SINK);
++
++ return &isp_dev->rect[ISP_ITIWS].rect;
++}
++
++static void isp_try_crop(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_mbus_framefmt *fmt;
++
++ fmt = __isp_get_format(isp_dev, state, STF_ISP_PAD_SINK, which);
++
++ if (rect->width > fmt->width)
++ rect->width = fmt->width;
++
++ if (rect->width + rect->left > fmt->width)
++ rect->left = fmt->width - rect->width;
++
++ if (rect->height > fmt->height)
++ rect->height = fmt->height;
++
++ if (rect->height + rect->top > fmt->height)
++ rect->top = fmt->height - rect->height;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
++ rect->left = 0;
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++ }
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
++ rect->top = 0;
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ }
++ rect->height &= ~0x1;
++}
++
++static void isp_try_compose(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_rect *crop;
++
++ crop = __isp_get_crop(isp_dev, state, which);
++
++ if (rect->width > crop->width)
++ rect->width = crop->width;
++
++ if (rect->height > crop->height)
++ rect->height = crop->height;
++
++ if (crop->width > rect->width * SCALER_RATIO_MAX)
++ rect->width = (crop->width + SCALER_RATIO_MAX - 1) /
++ SCALER_RATIO_MAX;
++
++ if (crop->height > rect->height * SCALER_RATIO_MAX)
++ rect->height = (crop->height + SCALER_RATIO_MAX - 1) /
++ SCALER_RATIO_MAX;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH)
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT)
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ rect->height &= ~0x1;
++}
++
++static void isp_try_scale(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_rect *compose;
++
++ compose = __isp_get_compose(isp_dev, state, which);
++
++ if (rect->width > compose->width)
++ rect->width = compose->width;
++
++ if (rect->width + rect->left > compose->width)
++ rect->left = compose->width - rect->width;
++
++ if (rect->height > compose->height)
++ rect->height = compose->height;
++
++ if (rect->height + rect->top > compose->height)
++ rect->top = compose->height - rect->height;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
++ rect->left = 0;
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++ }
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
++ rect->top = 0;
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ }
++ rect->height &= ~0x1;
++}
++
++static void isp_try_itiws(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_rect *crop;
++
++ crop = __isp_get_crop(isp_dev, state, which);
++
++ if (rect->width > crop->width)
++ rect->width = crop->width;
++
++ if (rect->width + rect->left > crop->width)
++ rect->left = crop->width - rect->width;
++
++ if (rect->height > crop->height)
++ rect->height = crop->height;
++
++ if (rect->height + rect->top > crop->height)
++ rect->top = crop->height - rect->height;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
++ rect->left = 0;
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++ }
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
++ rect->top = 0;
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ }
++ rect->height &= ~0x1;
++}
++
++static int isp_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_subdev_format fmt = { 0 };
++ struct v4l2_rect *rect;
++ int ret;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ fmt.pad = sel->pad;
++ fmt.which = sel->which;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = fmt.format.width;
++ sel->r.height = fmt.format.height;
++ break;
++ case V4L2_SEL_TGT_CROP:
++ rect = __isp_get_crop(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ sel->r = *rect;
++ break;
++ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
++ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
++ if (sel->pad > STF_ISP_PAD_SRC_ITIR)
++ return -EINVAL;
++ rect = __isp_get_crop(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ sel->r.left = rect->left;
++ sel->r.top = rect->top;
++ sel->r.width = rect->width;
++ sel->r.height = rect->height;
++ break;
++ case V4L2_SEL_TGT_COMPOSE:
++ if (sel->pad > STF_ISP_PAD_SRC_ITIR)
++ return -EINVAL;
++ if (sel->pad == STF_ISP_PAD_SRC_SS0
++ || sel->pad == STF_ISP_PAD_SRC_SS1) {
++ rect = __isp_get_scale(isp_dev, state, sel);
++ if (rect == NULL)
++ return -EINVAL;
++ } else if (sel->pad == STF_ISP_PAD_SRC_ITIW
++ || sel->pad == STF_ISP_PAD_SRC_ITIR) {
++ rect = __isp_get_itiws(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++ } else {
++ rect = __isp_get_compose(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++ }
++ sel->r = *rect;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ st_info(ST_ISP, "%s pad = %d, left = %d, %d, %d, %d\n",
++ __func__, sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
++ return 0;
++}
++
++static int isp_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_rect *rect;
++ int ret = 0;
++
++ if (sel->target == V4L2_SEL_TGT_COMPOSE &&
++ ((sel->pad == STF_ISP_PAD_SINK)
++ || (sel->pad == STF_ISP_PAD_SRC))) {
++ struct v4l2_subdev_format fmt = { 0 };
++ int i;
++
++ rect = __isp_get_compose(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_compose(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source pad format width and height */
++ fmt.which = sel->which;
++ fmt.pad = STF_ISP_PAD_SRC;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++
++ /* Reset scale */
++ for (i = STF_ISP_PAD_SRC_SS0; i <= STF_ISP_PAD_SRC_ITIR; i++) {
++ struct v4l2_subdev_selection scale = { 0 };
++
++ scale.which = sel->which;
++ scale.target = V4L2_SEL_TGT_COMPOSE;
++ scale.r = *rect;
++ scale.pad = i;
++ ret = isp_set_selection(sd, state, &scale);
++ }
++ } else if (sel->target == V4L2_SEL_TGT_COMPOSE
++ && ((sel->pad == STF_ISP_PAD_SRC_SS0)
++ || (sel->pad == STF_ISP_PAD_SRC_SS1))) {
++ struct v4l2_subdev_format fmt = { 0 };
++
++ rect = __isp_get_scale(isp_dev, state, sel);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_scale(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source pad format width and height */
++ fmt.which = sel->which;
++ fmt.pad = sel->pad;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++ } else if (sel->target == V4L2_SEL_TGT_COMPOSE
++ && ((sel->pad == STF_ISP_PAD_SRC_ITIW)
++ || (sel->pad == STF_ISP_PAD_SRC_ITIR))) {
++ struct v4l2_subdev_format fmt = { 0 };
++
++ rect = __isp_get_itiws(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_itiws(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source pad format width and height */
++ fmt.which = sel->which;
++ fmt.pad = sel->pad;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++ } else if (sel->target == V4L2_SEL_TGT_CROP) {
++ struct v4l2_subdev_selection compose = { 0 };
++ int i;
++
++ rect = __isp_get_crop(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_crop(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source compose selection */
++ compose.which = sel->which;
++ compose.target = V4L2_SEL_TGT_COMPOSE;
++ compose.r.width = rect->width;
++ compose.r.height = rect->height;
++ compose.pad = STF_ISP_PAD_SINK;
++ ret = isp_set_selection(sd, state, &compose);
++
++ /* Reset source pad format width and height */
++ for (i = STF_ISP_PAD_SRC_RAW; i < STF_ISP_PAD_MAX; i++) {
++ struct v4l2_subdev_format fmt = { 0 };
++
++ fmt.which = sel->which;
++ fmt.pad = i;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++ }
++ } else {
++ ret = -EINVAL;
++ }
++
++ st_info(ST_ISP, "%s pad = %d, left = %d, %d, %d, %d\n",
++ __func__, sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
++out:
++ return ret;
++}
++
++static int isp_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_ISP_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return isp_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int isp_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if (flags & MEDIA_LNK_FL_ENABLED)
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++ return 0;
++}
++
++static int stf_isp_load_setfile(struct stf_isp_dev *isp_dev, char *file_name)
++{
++ struct device *dev = isp_dev->stfcamss->dev;
++ const struct firmware *fw;
++ u8 *buf = NULL;
++ int *regval_num;
++ int ret;
++
++ st_debug(ST_ISP, "%s, file_name %s\n", __func__, file_name);
++ ret = request_firmware(&fw, file_name, dev);
++ if (ret < 0) {
++ st_err(ST_ISP, "firmware request failed (%d)\n", ret);
++ return ret;
++ }
++ buf = devm_kzalloc(dev, fw->size, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++ memcpy(buf, fw->data, fw->size);
++
++ mutex_lock(&isp_dev->setfile_lock);
++ if (isp_dev->setfile.state == 1)
++ devm_kfree(dev, isp_dev->setfile.data);
++ isp_dev->setfile.data = buf;
++ isp_dev->setfile.size = fw->size;
++ isp_dev->setfile.state = 1;
++ regval_num = (int *)&buf[fw->size - sizeof(unsigned int)];
++ isp_dev->setfile.settings.regval_num = *regval_num;
++ isp_dev->setfile.settings.regval = (struct regval_t *)buf;
++ mutex_unlock(&isp_dev->setfile_lock);
++
++ st_debug(ST_ISP, "stf_isp setfile loaded size: %zu B, reg_nul: %d\n",
++ fw->size, isp_dev->setfile.settings.regval_num);
++
++ release_firmware(fw);
++ return ret;
++}
++
++static long stf_isp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct device *dev = isp_dev->stfcamss->dev;
++ int ret = -ENOIOCTLCMD;
++
++ switch (cmd) {
++ case VIDIOC_STFISP_LOAD_FW: {
++ struct stfisp_fw_info *fw_info = arg;
++
++ if (IS_ERR(fw_info)) {
++ st_err(ST_ISP, "fw_info failed, params invaild\n");
++ return -EINVAL;
++ }
++
++ ret = stf_isp_load_setfile(isp_dev, fw_info->filename);
++ break;
++ }
++ case VIDIOC_STF_DMABUF_ALLOC:
++ case VIDIOC_STF_DMABUF_FREE:
++ ret = stf_dmabuf_ioctl(dev, cmd, arg);
++ break;
++ case VIDIOC_STFISP_GET_REG:
++ ret = isp_dev->hw_ops->isp_reg_read(isp_dev, arg);
++ break;
++ case VIDIOC_STFISP_SET_REG:
++ ret = isp_dev->hw_ops->isp_reg_write(isp_dev, arg);
++ break;
++ case VIDIOC_STFISP_SHADOW_LOCK:
++ if (atomic_add_unless(&isp_dev->shadow_count, 1, 1))
++ ret = 0;
++ else
++ ret = -EBUSY;
++ st_debug(ST_ISP, "%s, %d, ret = %d\n", __func__, __LINE__, ret);
++ break;
++ case VIDIOC_STFISP_SHADOW_UNLOCK:
++ if (atomic_dec_if_positive(&isp_dev->shadow_count) < 0)
++ ret = -EINVAL;
++ else
++ ret = 0;
++ st_debug(ST_ISP, "%s, %d, ret = %d\n", __func__, __LINE__, ret);
++ break;
++ case VIDIOC_STFISP_SHADOW_UNLOCK_N_TRIGGER:
++ {
++ isp_dev->hw_ops->isp_shadow_trigger(isp_dev);
++ if (atomic_dec_if_positive(&isp_dev->shadow_count) < 0)
++ ret = -EINVAL;
++ else
++ ret = 0;
++ st_debug(ST_ISP, "%s, %d, ret = %d\n", __func__, __LINE__, ret);
++ }
++ break;
++ case VIDIOC_STFISP_SET_USER_CONFIG_ISP:
++ st_debug(ST_ISP, "%s, %d set user_config_isp\n", __func__, __LINE__);
++ user_config_isp = 1;
++ break;
++ default:
++ break;
++ }
++ return ret;
++}
++
++int isp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++
++ st_debug(ST_ISP, "%s, %d\n", __func__, __LINE__);
++ while (atomic_dec_if_positive(&isp_dev->shadow_count) > 0)
++ st_warn(ST_ISP, "user not unlocked the shadow lock, driver unlock it!\n");
++
++ return 0;
++}
++
++static int stf_isp_subscribe_event(struct v4l2_subdev *sd,
++ struct v4l2_fh *fh,
++ struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_SOURCE_CHANGE:
++ return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
++ case V4L2_EVENT_CTRL:
++ return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
++ default:
++ st_debug(ST_ISP, "unspport subscribe_event\n");
++ return -EINVAL;
++ }
++}
++
++static const struct v4l2_subdev_core_ops isp_core_ops = {
++ .s_power = isp_set_power,
++ .ioctl = stf_isp_ioctl,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ // .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .subscribe_event = stf_isp_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops isp_video_ops = {
++ .s_stream = isp_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops isp_pad_ops = {
++ .enum_mbus_code = isp_enum_mbus_code,
++ .enum_frame_size = isp_enum_frame_size,
++ .get_fmt = isp_get_format,
++ .set_fmt = isp_set_format,
++ .get_selection = isp_get_selection,
++ .set_selection = isp_set_selection,
++};
++
++static const struct v4l2_subdev_ops isp_v4l2_ops = {
++ .core = &isp_core_ops,
++ .video = &isp_video_ops,
++ .pad = &isp_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops isp_v4l2_internal_ops = {
++ .open = isp_init_formats,
++ .close = isp_close,
++};
++
++static const struct media_entity_operations isp_media_ops = {
++ .link_setup = isp_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_isp_register(struct stf_isp_dev *isp_dev,
++ struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &isp_dev->subdev;
++ struct media_pad *pads = isp_dev->pads;
++ int ret;
++
++ v4l2_subdev_init(sd, &isp_v4l2_ops);
++ sd->internal_ops = &isp_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_ISP_NAME, 0);
++ v4l2_set_subdevdata(sd, isp_dev);
++
++ ret = isp_init_formats(sd, NULL);
++ if (ret < 0) {
++ st_err(ST_ISP, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_ISP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_ISP_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_SS0].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_SS1].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_ITIW].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_ITIR].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_RAW].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_SCD_Y].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &isp_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_ISP_PAD_MAX, pads);
++ if (ret < 0) {
++ st_err(ST_ISP, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = isp_init_controls(isp_dev);
++ if (ret)
++ goto err_sreg;
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ st_err(ST_ISP, "Failed to register subdev: %d\n", ret);
++ goto free_ctrls;
++ }
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&isp_dev->ctrls.handler);
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_isp_unregister(struct stf_isp_dev *isp_dev)
++{
++ v4l2_device_unregister_subdev(&isp_dev->subdev);
++ media_entity_cleanup(&isp_dev->subdev.entity);
++ v4l2_ctrl_handler_free(&isp_dev->ctrls.handler);
++ mutex_destroy(&isp_dev->stream_lock);
++ mutex_destroy(&isp_dev->power_lock);
++ mutex_destroy(&isp_dev->setfile_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
+@@ -0,0 +1,222 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_ISP_H
++#define STF_ISP_H
++
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_ISP_NAME "stf_isp"
++#define STF_ISP_SETFILE "stf_isp0_fw.bin"
++
++#define ISP_SCD_BUFFER_SIZE (19 * 256 * 4) // align 128
++#define ISP_YHIST_BUFFER_SIZE (64 * 4)
++#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)
++#define ISP_RAW_DATA_BITS 12
++#define SCALER_RATIO_MAX 1 // no compose function
++#define STF_ISP_REG_OFFSET_MAX 0x0FFF
++#define STF_ISP_REG_DELAY_MAX 100
++
++#define ISP_REG_CSIINTS_ADDR 0x00000008
++#define ISP_REG_SENSOR 0x00000014
++#define ISP_REG_DUMP_CFG_0 0x00000024
++#define ISP_REG_DUMP_CFG_1 0x00000028
++#define ISP_REG_SCD_CFG_0 0x00000098
++#define ISP_REG_SCD_CFG_1 0x0000009C
++#define ISP_REG_SC_CFG_1 0x000000BC
++#define ISP_REG_IESHD_ADDR 0x00000A50
++#define ISP_REG_SS0AY 0x00000A94
++#define ISP_REG_SS0AUV 0x00000A98
++#define ISP_REG_SS0S 0x00000A9C
++#define ISP_REG_SS0IW 0x00000AA8
++#define ISP_REG_SS1AY 0x00000AAC
++#define ISP_REG_SS1AUV 0x00000AB0
++#define ISP_REG_SS1S 0x00000AB4
++#define ISP_REG_SS1IW 0x00000AC0
++#define ISP_REG_YHIST_CFG_4 0x00000CD8
++#define ISP_REG_ITIIWSR 0x00000B20
++#define ISP_REG_ITIDWLSR 0x00000B24
++#define ISP_REG_ITIDWYSAR 0x00000B28
++#define ISP_REG_ITIDWUSAR 0x00000B2C
++#define ISP_REG_ITIDRYSAR 0x00000B30
++#define ISP_REG_ITIDRUSAR 0x00000B34
++#define ISP_REG_ITIPDFR 0x00000B38
++#define ISP_REG_ITIDRLSR 0x00000B3C
++#define ISP_REG_ITIBSR 0x00000B40
++#define ISP_REG_ITIAIR 0x00000B44
++#define ISP_REG_ITIDPSR 0x00000B48
++
++/* The output line of a isp controller */
++enum isp_line_id {
++ STF_ISP_LINE_INVALID = -1,
++ STF_ISP_LINE_SRC = 1,
++ STF_ISP_LINE_SRC_SS0 = 2,
++ STF_ISP_LINE_SRC_SS1 = 3,
++ STF_ISP_LINE_SRC_ITIW = 4,
++ STF_ISP_LINE_SRC_ITIR = 5,
++ STF_ISP_LINE_SRC_RAW = 6,
++ STF_ISP_LINE_SRC_SCD_Y = 7,
++ STF_ISP_LINE_MAX = STF_ISP_LINE_SRC_SCD_Y
++};
++
++/* pad id for media framework */
++enum isp_pad_id {
++ STF_ISP_PAD_SINK = 0,
++ STF_ISP_PAD_SRC = 1,
++ STF_ISP_PAD_SRC_SS0 = 2,
++ STF_ISP_PAD_SRC_SS1 = 3,
++ STF_ISP_PAD_SRC_ITIW = 4,
++ STF_ISP_PAD_SRC_ITIR = 5,
++ STF_ISP_PAD_SRC_RAW = 6,
++ STF_ISP_PAD_SRC_SCD_Y = 7,
++ STF_ISP_PAD_MAX = 8
++};
++
++enum {
++ EN_INT_NONE = 0,
++ EN_INT_ISP_DONE = (0x1 << 24),
++ EN_INT_CSI_DONE = (0x1 << 25),
++ EN_INT_SC_DONE = (0x1 << 26),
++ EN_INT_LINE_INT = (0x1 << 27),
++ EN_INT_ALL = (0xF << 24),
++};
++
++enum {
++ DVP_SENSOR = 0,
++ CSI_SENSOR,
++};
++
++#define ISP_AWB_OECF_SKIP_FRAME 0
++// 0x0BC [31:30] SEL - sc0 input mux for sc awb
++// 00 : after DEC, 01 : after OBC, 10 : after OECF, 11 : after AWB
++enum scd_type {
++ DEC_TYPE = 0,
++ OBC_TYPE,
++ OECF_TYPE,
++ AWB_TYPE
++};
++
++struct isp_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct isp_format_table {
++ const struct isp_format *fmts;
++ int nfmts;
++};
++
++struct regval_t {
++ u32 addr;
++ u32 val;
++ u32 mask;
++ u32 delay_ms;
++};
++
++struct reg_table {
++ struct regval_t *regval;
++ int regval_num;
++};
++
++struct isp_stream_format {
++ struct v4l2_rect rect;
++ u32 bpp;
++};
++
++struct stf_isp_dev;
++enum subdev_type;
++
++struct isp_hw_ops {
++ int (*isp_clk_enable)(struct stf_isp_dev *isp_dev);
++ int (*isp_clk_disable)(struct stf_isp_dev *isp_dev);
++ int (*isp_reset)(struct stf_isp_dev *isp_dev);
++ int (*isp_config_set)(struct stf_isp_dev *isp_dev);
++ int (*isp_set_format)(struct stf_isp_dev *isp_dev,
++ struct isp_stream_format *crop, u32 mcode,
++ int type);
++ // u32 width, u32 height);
++ int (*isp_stream_set)(struct stf_isp_dev *isp_dev, int on);
++ int (*isp_reg_read)(struct stf_isp_dev *isp_dev, void *arg);
++ int (*isp_reg_write)(struct stf_isp_dev *isp_dev, void *arg);
++ int (*isp_shadow_trigger)(struct stf_isp_dev *isp_dev);
++};
++
++struct isp_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *auto_exp;
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *auto_gain;
++ struct v4l2_ctrl *gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct isp_setfile {
++ struct reg_table settings;
++ const u8 *data;
++ unsigned int size;
++ unsigned int state;
++};
++
++enum {
++ ISP_CROP = 0,
++ ISP_COMPOSE,
++ ISP_SCALE_SS0,
++ ISP_SCALE_SS1,
++ ISP_ITIWS,
++ ISP_RECT_MAX
++};
++
++struct stf_isp_dev {
++ enum subdev_type sdev_type; // must be frist
++ struct stfcamss *stfcamss;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_ISP_PAD_MAX];
++ struct v4l2_mbus_framefmt fmt[STF_ISP_PAD_MAX];
++ struct isp_stream_format rect[ISP_RECT_MAX];
++ const struct isp_format_table *formats;
++ unsigned int nformats;
++ struct isp_hw_ops *hw_ops;
++ struct mutex power_lock;
++ int power_count;
++ struct mutex stream_lock;
++ int stream_count;
++ atomic_t shadow_count;
++
++ struct isp_ctrls ctrls;
++ struct mutex setfile_lock;
++ struct isp_setfile setfile;
++ struct reg_table *context_regs;
++};
++
++extern int stf_isp_subdev_init(struct stfcamss *stfcamss);
++extern int stf_isp_register(struct stf_isp_dev *isp_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_isp_unregister(struct stf_isp_dev *isp_dev);
++extern struct isp_hw_ops isp_ops;
++extern void dump_isp_reg(void *__iomem ispbase);
++
++#endif /* STF_ISP_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp_hw_ops.c
+@@ -0,0 +1,1550 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/io.h>
++#include <linux/fb.h>
++#include <linux/module.h>
++#include <video/stf-vin.h>
++#include "stf_isp_ioctl.h"
++#include "stf_isp.h"
++#include <linux/delay.h>
++#include <linux/clk.h>
++#define USE_NEW_CONFIG_SETTING
++
++static struct regval_t isp_reg_init_config_list[] = {
++ /* config DC(0040H~0044H) */
++ {0x00000044, 0x00000000, 0, 0},
++ /* config DEC(0030H) */
++ {0x00000030, 0x00000000, 0, 0},
++ /* config OBC(0034H, 02E0H~02FCH) */
++ {0x00000034, 0x000000BB, 0, 0},
++ {0x000002E0, 0x40404040, 0, 0},
++ {0x000002E4, 0x40404040, 0, 0},
++ {0x000002E8, 0x40404040, 0, 0},
++ {0x000002EC, 0x40404040, 0, 0},
++ {0x000002F0, 0x00000000, 0, 0},
++ {0x000002F4, 0x00000000, 0, 0},
++ {0x000002F8, 0x00000000, 0, 0},
++ {0x000002FC, 0x00000000, 0, 0},
++ /* config LCBQ(0074H, 007CH, 0300H~039FH, and 0400H~049FH) */
++ {0x00000074, 0x00009900, 0, 0},
++ {0x0000007C, 0x01E40040, 0, 0},
++ {0x00000300, 0x01000100, 0, 0},
++ {0x00000304, 0x01000100, 0, 0},
++ {0x00000308, 0x01000100, 0, 0},
++ {0x0000030C, 0x01000100, 0, 0},
++ {0x00000310, 0x01000100, 0, 0},
++ {0x00000314, 0x01000100, 0, 0},
++ {0x00000318, 0x01000100, 0, 0},
++ {0x0000031C, 0x01000100, 0, 0},
++ {0x00000320, 0x01000100, 0, 0},
++ {0x00000324, 0x01000100, 0, 0},
++ {0x00000328, 0x01000100, 0, 0},
++ {0x0000032C, 0x01000100, 0, 0},
++ {0x00000330, 0x00000100, 0, 0},
++ {0x00000334, 0x01000100, 0, 0},
++ {0x00000338, 0x01000100, 0, 0},
++ {0x0000033C, 0x01000100, 0, 0},
++ {0x00000340, 0x01000100, 0, 0},
++ {0x00000344, 0x01000100, 0, 0},
++ {0x00000348, 0x01000100, 0, 0},
++ {0x0000034C, 0x01000100, 0, 0},
++ {0x00000350, 0x01000100, 0, 0},
++ {0x00000354, 0x01000100, 0, 0},
++ {0x00000358, 0x01000100, 0, 0},
++ {0x0000035C, 0x01000100, 0, 0},
++ {0x00000360, 0x01000100, 0, 0},
++ {0x00000364, 0x00000100, 0, 0},
++ {0x00000368, 0x01000100, 0, 0},
++ {0x0000036C, 0x01000100, 0, 0},
++ {0x00000370, 0x01000100, 0, 0},
++ {0x00000374, 0x01000100, 0, 0},
++ {0x00000378, 0x01000100, 0, 0},
++ {0x0000037C, 0x01000100, 0, 0},
++ {0x00000380, 0x01000100, 0, 0},
++ {0x00000384, 0x01000100, 0, 0},
++ {0x00000388, 0x01000100, 0, 0},
++ {0x0000038C, 0x01000100, 0, 0},
++ {0x00000390, 0x01000100, 0, 0},
++ {0x00000394, 0x01000100, 0, 0},
++ {0x00000398, 0x00000100, 0, 0},
++ {0x0000039C, 0x01000100, 0, 0},
++ {0x000003A0, 0x01000100, 0, 0},
++ {0x000003A4, 0x01000100, 0, 0},
++ {0x000003A8, 0x01000100, 0, 0},
++ {0x000003AC, 0x01000100, 0, 0},
++ {0x000003B0, 0x01000100, 0, 0},
++ {0x000003B4, 0x01000100, 0, 0},
++ {0x000003B8, 0x01000100, 0, 0},
++ {0x000003BC, 0x01000100, 0, 0},
++ {0x000003C0, 0x01000100, 0, 0},
++ {0x000003C4, 0x01000100, 0, 0},
++ {0x000003C8, 0x01000100, 0, 0},
++ {0x000003CC, 0x00000100, 0, 0},
++ {0x00000400, 0x00000000, 0, 0},
++ {0x00000404, 0x00000000, 0, 0},
++ {0x00000408, 0x00000000, 0, 0},
++ {0x0000040C, 0x00000000, 0, 0},
++ {0x00000410, 0x00000000, 0, 0},
++ {0x00000414, 0x00000000, 0, 0},
++ {0x00000418, 0x00000000, 0, 0},
++ {0x0000041C, 0x00000000, 0, 0},
++ {0x00000420, 0x00000000, 0, 0},
++ {0x00000424, 0x00000000, 0, 0},
++ {0x00000428, 0x00000000, 0, 0},
++ {0x0000042C, 0x00000000, 0, 0},
++ {0x00000430, 0x00000000, 0, 0},
++ {0x00000434, 0x00000000, 0, 0},
++ {0x00000438, 0x00000000, 0, 0},
++ {0x0000043C, 0x00000000, 0, 0},
++ {0x00000440, 0x00000000, 0, 0},
++ {0x00000444, 0x00000000, 0, 0},
++ {0x00000448, 0x00000000, 0, 0},
++ {0x0000044C, 0x00000000, 0, 0},
++ {0x00000450, 0x00000000, 0, 0},
++ {0x00000454, 0x00000000, 0, 0},
++ {0x00000458, 0x00000000, 0, 0},
++ {0x0000045C, 0x00000000, 0, 0},
++ {0x00000460, 0x00000000, 0, 0},
++ {0x00000464, 0x00000000, 0, 0},
++ {0x00000468, 0x00000000, 0, 0},
++ {0x0000046C, 0x00000000, 0, 0},
++ {0x00000470, 0x00000000, 0, 0},
++ {0x00000474, 0x00000000, 0, 0},
++ {0x00000478, 0x00000000, 0, 0},
++ {0x0000047C, 0x00000000, 0, 0},
++ {0x00000480, 0x00000000, 0, 0},
++ {0x00000484, 0x00000000, 0, 0},
++ {0x00000488, 0x00000000, 0, 0},
++ {0x0000048C, 0x00000000, 0, 0},
++ {0x00000490, 0x00000000, 0, 0},
++ {0x00000494, 0x00000000, 0, 0},
++ {0x00000498, 0x00000000, 0, 0},
++ {0x0000049C, 0x00000000, 0, 0},
++ {0x000004A0, 0x00000000, 0, 0},
++ {0x000004A4, 0x00000000, 0, 0},
++ {0x000004A8, 0x00000000, 0, 0},
++ {0x000004AC, 0x00000000, 0, 0},
++ {0x000004B0, 0x00000000, 0, 0},
++ {0x000004B4, 0x00000000, 0, 0},
++ {0x000004B8, 0x00000000, 0, 0},
++ {0x000004BC, 0x00000000, 0, 0},
++ {0x000004C0, 0x00000000, 0, 0},
++ {0x000004C4, 0x00000000, 0, 0},
++ {0x000004C8, 0x00000000, 0, 0},
++ {0x000004CC, 0x00000000, 0, 0},
++ /* config OECF(0100H~027CH) */
++ {0x00000100, 0x00100000, 0, 0},
++ {0x00000104, 0x00400020, 0, 0},
++ {0x00000108, 0x00800060, 0, 0},
++ {0x0000010C, 0x00C000A0, 0, 0},
++ {0x00000110, 0x010000E0, 0, 0},
++ {0x00000114, 0x02000180, 0, 0},
++ {0x00000118, 0x03000280, 0, 0},
++ {0x0000011C, 0x03FE0380, 0, 0},
++ {0x00000120, 0x00100000, 0, 0},
++ {0x00000124, 0x00400020, 0, 0},
++ {0x00000128, 0x00800060, 0, 0},
++ {0x0000012C, 0x00C000A0, 0, 0},
++ {0x00000130, 0x010000E0, 0, 0},
++ {0x00000134, 0x02000180, 0, 0},
++ {0x00000138, 0x03000280, 0, 0},
++ {0x0000013C, 0x03FE0380, 0, 0},
++ {0x00000140, 0x00100000, 0, 0},
++ {0x00000144, 0x00400020, 0, 0},
++ {0x00000148, 0x00800060, 0, 0},
++ {0x0000014C, 0x00C000A0, 0, 0},
++ {0x00000150, 0x010000E0, 0, 0},
++ {0x00000154, 0x02000180, 0, 0},
++ {0x00000158, 0x03000280, 0, 0},
++ {0x0000015C, 0x03FE0380, 0, 0},
++ {0x00000160, 0x00100000, 0, 0},
++ {0x00000164, 0x00400020, 0, 0},
++ {0x00000168, 0x00800060, 0, 0},
++ {0x0000016C, 0x00C000A0, 0, 0},
++ {0x00000170, 0x010000E0, 0, 0},
++ {0x00000174, 0x02000180, 0, 0},
++ {0x00000178, 0x03000280, 0, 0},
++ {0x0000017C, 0x03FE0380, 0, 0},
++ {0x00000180, 0x00100000, 0, 0},
++ {0x00000184, 0x00400020, 0, 0},
++ {0x00000188, 0x00800060, 0, 0},
++ {0x0000018C, 0x00C000A0, 0, 0},
++ {0x00000190, 0x010000E0, 0, 0},
++ {0x00000194, 0x02000180, 0, 0},
++ {0x00000198, 0x03000280, 0, 0},
++ {0x0000019C, 0x03FE0380, 0, 0},
++ {0x000001A0, 0x00100000, 0, 0},
++ {0x000001A4, 0x00400020, 0, 0},
++ {0x000001A8, 0x00800060, 0, 0},
++ {0x000001AC, 0x00C000A0, 0, 0},
++ {0x000001B0, 0x010000E0, 0, 0},
++ {0x000001B4, 0x02000180, 0, 0},
++ {0x000001B8, 0x03000280, 0, 0},
++ {0x000001BC, 0x03FE0380, 0, 0},
++ {0x000001C0, 0x00100000, 0, 0},
++ {0x000001C4, 0x00400020, 0, 0},
++ {0x000001C8, 0x00800060, 0, 0},
++ {0x000001CC, 0x00C000A0, 0, 0},
++ {0x000001D0, 0x010000E0, 0, 0},
++ {0x000001D4, 0x02000180, 0, 0},
++ {0x000001D8, 0x03000280, 0, 0},
++ {0x000001DC, 0x03FE0380, 0, 0},
++ {0x000001E0, 0x00100000, 0, 0},
++ {0x000001E4, 0x00400020, 0, 0},
++ {0x000001E8, 0x00800060, 0, 0},
++ {0x000001EC, 0x00C000A0, 0, 0},
++ {0x000001F0, 0x010000E0, 0, 0},
++ {0x000001F4, 0x02000180, 0, 0},
++ {0x000001F8, 0x03000280, 0, 0},
++ {0x000001FC, 0x03FE0380, 0, 0},
++ {0x00000200, 0x00800080, 0, 0},
++ {0x00000204, 0x00800080, 0, 0},
++ {0x00000208, 0x00800080, 0, 0},
++ {0x0000020C, 0x00800080, 0, 0},
++ {0x00000210, 0x00800080, 0, 0},
++ {0x00000214, 0x00800080, 0, 0},
++ {0x00000218, 0x00800080, 0, 0},
++ {0x0000021C, 0x00800080, 0, 0},
++ {0x00000220, 0x00800080, 0, 0},
++ {0x00000224, 0x00800080, 0, 0},
++ {0x00000228, 0x00800080, 0, 0},
++ {0x0000022C, 0x00800080, 0, 0},
++ {0x00000230, 0x00800080, 0, 0},
++ {0x00000234, 0x00800080, 0, 0},
++ {0x00000238, 0x00800080, 0, 0},
++ {0x0000023C, 0x00800080, 0, 0},
++ {0x00000240, 0x00800080, 0, 0},
++ {0x00000244, 0x00800080, 0, 0},
++ {0x00000248, 0x00800080, 0, 0},
++ {0x0000024C, 0x00800080, 0, 0},
++ {0x00000250, 0x00800080, 0, 0},
++ {0x00000254, 0x00800080, 0, 0},
++ {0x00000258, 0x00800080, 0, 0},
++ {0x0000025C, 0x00800080, 0, 0},
++ {0x00000260, 0x00800080, 0, 0},
++ {0x00000264, 0x00800080, 0, 0},
++ {0x00000268, 0x00800080, 0, 0},
++ {0x0000026C, 0x00800080, 0, 0},
++ {0x00000270, 0x00800080, 0, 0},
++ {0x00000274, 0x00800080, 0, 0},
++ {0x00000278, 0x00800080, 0, 0},
++ {0x0000027C, 0x00800080, 0, 0},
++ /* config OECFHM(03D0H~03E4H) */
++ {0x000003D0, 0x04000000, 0, 0},
++ {0x000003D4, 0x0C000800, 0, 0},
++ {0x000003D8, 0x00000FFF, 0, 0},
++ {0x000003DC, 0x08000800, 0, 0},
++ {0x000003E0, 0x08000800, 0, 0},
++ {0x000003E4, 0x00000800, 0, 0},
++ /* config LCCF(0050H, 0058H, 00E0H~00ECH) */
++ {0x00000050, 0x021C03C0, 0, 0},
++ {0x00000058, 0x0000000B, 0, 0},
++ {0x000000E0, 0x00000000, 0, 0},
++ {0x000000E4, 0x00000000, 0, 0},
++ {0x000000E8, 0x00000000, 0, 0},
++ {0x000000EC, 0x00000000, 0, 0},
++ /* config AWB(0280H~02DCH) */
++ {0x00000280, 0x00000000, 0, 0},
++ {0x00000284, 0x00000000, 0, 0},
++ {0x00000288, 0x00000000, 0, 0},
++ {0x0000028C, 0x00000000, 0, 0},
++ {0x00000290, 0x00000000, 0, 0},
++ {0x00000294, 0x00000000, 0, 0},
++ {0x00000298, 0x00000000, 0, 0},
++ {0x0000029C, 0x00000000, 0, 0},
++ {0x000002A0, 0x00000000, 0, 0},
++ {0x000002A4, 0x00000000, 0, 0},
++ {0x000002A8, 0x00000000, 0, 0},
++ {0x000002AC, 0x00000000, 0, 0},
++ {0x000002B0, 0x00000000, 0, 0},
++ {0x000002B4, 0x00000000, 0, 0},
++ {0x000002B8, 0x00000000, 0, 0},
++ {0x000002BC, 0x00000000, 0, 0},
++ {0x000002C0, 0x00800080, 0, 0},
++ {0x000002C4, 0x00800080, 0, 0},
++ {0x000002C8, 0x00800080, 0, 0},
++ {0x000002CC, 0x00800080, 0, 0},
++ {0x000002D0, 0x00800080, 0, 0},
++ {0x000002D4, 0x00800080, 0, 0},
++ {0x000002D8, 0x00800080, 0, 0},
++ {0x000002DC, 0x00800080, 0, 0},
++ /* config CTC(0A10H) and DBC(0A14H) filter */
++ {0x00000A10, 0x41400040, 0, 0},
++ {0x00000A14, 0x02000200, 0, 0},
++ /* config CFA(0018H, 0A1CH) */
++ {0x00000018, 0x000011BB, 0, 0},
++ {0x00000A1C, 0x00000032, 0, 0},
++ /* config CCM(0C40H~0CA4H) */
++ {0x00000C40, 0x00060000, 0, 0},
++ {0x00000C44, 0x00000000, 0, 0},
++ {0x00000C48, 0x00000000, 0, 0},
++ {0x00000C4C, 0x00000000, 0, 0},
++ {0x00000C50, 0x00000000, 0, 0},
++ {0x00000C54, 0x00000000, 0, 0},
++ {0x00000C58, 0x00000000, 0, 0},
++ {0x00000C5C, 0x00000000, 0, 0},
++ {0x00000C60, 0x00000000, 0, 0},
++ {0x00000C64, 0x00000000, 0, 0},
++ {0x00000C68, 0x00000000, 0, 0},
++ {0x00000C6C, 0x00000000, 0, 0},
++ {0x00000C70, 0x00000080, 0, 0},
++ {0x00000C74, 0x00000000, 0, 0},
++ {0x00000C78, 0x00000000, 0, 0},
++ {0x00000C7C, 0x00000000, 0, 0},
++ {0x00000C80, 0x00000080, 0, 0},
++ {0x00000C84, 0x00000000, 0, 0},
++ {0x00000C88, 0x00000000, 0, 0},
++ {0x00000C8C, 0x00000000, 0, 0},
++ {0x00000C90, 0x00000080, 0, 0},
++ {0x00000C94, 0x00000000, 0, 0},
++ {0x00000C98, 0x00000000, 0, 0},
++ {0x00000C9C, 0x00000000, 0, 0},
++ {0x00000CA0, 0x00000700, 0, 0},
++ {0x00000CA4, 0x00000200, 0, 0},
++ /* config GMARGB(0E00H~0E38H) */
++ {0x00000E00, 0x24000000, 0, 0},
++ {0x00000E04, 0x08000020, 0, 0},
++ {0x00000E08, 0x08000040, 0, 0},
++ {0x00000E0C, 0x08000060, 0, 0},
++ {0x00000E10, 0x08000080, 0, 0},
++ {0x00000E14, 0x080000A0, 0, 0},
++ {0x00000E18, 0x080000C0, 0, 0},
++ {0x00000E1C, 0x080000E0, 0, 0},
++ {0x00000E20, 0x08000100, 0, 0},
++ {0x00000E24, 0x08000180, 0, 0},
++ {0x00000E28, 0x08000200, 0, 0},
++ {0x00000E2C, 0x08000280, 0, 0},
++ {0x00000E30, 0x08000300, 0, 0},
++ {0x00000E34, 0x08000380, 0, 0},
++ {0x00000E38, 0x080003FE, 0, 0},
++ /* config R2Y(0E40H~0E60H) */
++ {0x00000E40, 0x0000004C, 0, 0},
++ {0x00000E44, 0x00000097, 0, 0},
++ {0x00000E48, 0x0000001D, 0, 0},
++ {0x00000E4C, 0x000001D5, 0, 0},
++ {0x00000E50, 0x000001AC, 0, 0},
++ {0x00000E54, 0x00000080, 0, 0},
++ {0x00000E58, 0x00000080, 0, 0},
++ {0x00000E5C, 0x00000194, 0, 0},
++ {0x00000E60, 0x000001EC, 0, 0},
++ /* config YCRV(0F00H~0FFCH) */
++ {0x00000F00, 0x00000000, 0, 0},
++ {0x00000F04, 0x00000010, 0, 0},
++ {0x00000F08, 0x00000020, 0, 0},
++ {0x00000F0C, 0x00000030, 0, 0},
++ {0x00000F10, 0x00000040, 0, 0},
++ {0x00000F14, 0x00000050, 0, 0},
++ {0x00000F18, 0x00000060, 0, 0},
++ {0x00000F1C, 0x00000070, 0, 0},
++ {0x00000F20, 0x00000080, 0, 0},
++ {0x00000F24, 0x00000090, 0, 0},
++ {0x00000F28, 0x000000A0, 0, 0},
++ {0x00000F2C, 0x000000B0, 0, 0},
++ {0x00000F30, 0x000000C0, 0, 0},
++ {0x00000F34, 0x000000D0, 0, 0},
++ {0x00000F38, 0x000000E0, 0, 0},
++ {0x00000F3C, 0x000000F0, 0, 0},
++ {0x00000F40, 0x00000100, 0, 0},
++ {0x00000F44, 0x00000110, 0, 0},
++ {0x00000F48, 0x00000120, 0, 0},
++ {0x00000F4C, 0x00000130, 0, 0},
++ {0x00000F50, 0x00000140, 0, 0},
++ {0x00000F54, 0x00000150, 0, 0},
++ {0x00000F58, 0x00000160, 0, 0},
++ {0x00000F5C, 0x00000170, 0, 0},
++ {0x00000F60, 0x00000180, 0, 0},
++ {0x00000F64, 0x00000190, 0, 0},
++ {0x00000F68, 0x000001A0, 0, 0},
++ {0x00000F6C, 0x000001B0, 0, 0},
++ {0x00000F70, 0x000001C0, 0, 0},
++ {0x00000F74, 0x000001D0, 0, 0},
++ {0x00000F78, 0x000001E0, 0, 0},
++ {0x00000F7C, 0x000001F0, 0, 0},
++ {0x00000F80, 0x00000200, 0, 0},
++ {0x00000F84, 0x00000210, 0, 0},
++ {0x00000F88, 0x00000220, 0, 0},
++ {0x00000F8C, 0x00000230, 0, 0},
++ {0x00000F90, 0x00000240, 0, 0},
++ {0x00000F94, 0x00000250, 0, 0},
++ {0x00000F98, 0x00000260, 0, 0},
++ {0x00000F9C, 0x00000270, 0, 0},
++ {0x00000FA0, 0x00000280, 0, 0},
++ {0x00000FA4, 0x00000290, 0, 0},
++ {0x00000FA8, 0x000002A0, 0, 0},
++ {0x00000FAC, 0x000002B0, 0, 0},
++ {0x00000FB0, 0x000002C0, 0, 0},
++ {0x00000FB4, 0x000002D0, 0, 0},
++ {0x00000FB8, 0x000002E0, 0, 0},
++ {0x00000FBC, 0x000002F0, 0, 0},
++ {0x00000FC0, 0x00000300, 0, 0},
++ {0x00000FC4, 0x00000310, 0, 0},
++ {0x00000FC8, 0x00000320, 0, 0},
++ {0x00000FCC, 0x00000330, 0, 0},
++ {0x00000FD0, 0x00000340, 0, 0},
++ {0x00000FD4, 0x00000350, 0, 0},
++ {0x00000FD8, 0x00000360, 0, 0},
++ {0x00000FDC, 0x00000370, 0, 0},
++ {0x00000FE0, 0x00000380, 0, 0},
++ {0x00000FE4, 0x00000390, 0, 0},
++ {0x00000FE8, 0x000003A0, 0, 0},
++ {0x00000FEC, 0x000003B0, 0, 0},
++ {0x00000FF0, 0x000003C0, 0, 0},
++ {0x00000FF4, 0x000003D0, 0, 0},
++ {0x00000FF8, 0x000003E0, 0, 0},
++ {0x00000FFC, 0x000003F0, 0, 0},
++ /* config Shrp(0E80H~0EE8H) */
++ {0x00000E80, 0x00070F00, 0, 0},
++ {0x00000E84, 0x00180F00, 0, 0},
++ {0x00000E88, 0x00800F00, 0, 0},
++ {0x00000E8C, 0x01000F00, 0, 0},
++ {0x00000E90, 0x00100F00, 0, 0},
++ {0x00000E94, 0x00600F00, 0, 0},
++ {0x00000E98, 0x01000F00, 0, 0},
++ {0x00000E9C, 0x01900F00, 0, 0},
++ {0x00000EA0, 0x00000F00, 0, 0},
++ {0x00000EA4, 0x00000F00, 0, 0},
++ {0x00000EA8, 0x00000F00, 0, 0},
++ {0x00000EAC, 0x00000F00, 0, 0},
++ {0x00000EB0, 0x00000F00, 0, 0},
++ {0x00000EB4, 0x00000F00, 0, 0},
++ {0x00000EB8, 0x00000F00, 0, 0},
++ {0x00000EBC, 0x10000000, 0, 0},
++ {0x00000EC0, 0x10000000, 0, 0},
++ {0x00000EC4, 0x10000000, 0, 0},
++ {0x00000EC8, 0x10000000, 0, 0},
++ {0x00000ECC, 0x10000000, 0, 0},
++ {0x00000ED0, 0x10000000, 0, 0},
++ {0x00000ED4, 0x88000D7C, 0, 0},
++ {0x00000ED8, 0x00C00040, 0, 0},
++ {0x00000EDC, 0xFF000000, 0, 0},
++ {0x00000EE0, 0x00A00040, 0, 0},
++ {0x00000EE4, 0x00000000, 0, 0},
++ {0x00000EE8, 0x00000000, 0, 0},
++ /* config DNYUV(0C00H~0C24H) */
++ {0x00000C00, 0x00777777, 0, 0},
++ {0x00000C04, 0x00007777, 0, 0},
++ {0x00000C08, 0x00777777, 0, 0},
++ {0x00000C0C, 0x00007777, 0, 0},
++ {0x00000C10, 0x00600040, 0, 0},
++ {0x00000C14, 0x00D80090, 0, 0},
++ {0x00000C18, 0x01E60144, 0, 0},
++ {0x00000C1C, 0x00600040, 0, 0},
++ {0x00000C20, 0x00D80090, 0, 0},
++ {0x00000C24, 0x01E60144, 0, 0},
++ /* config SAT(0A30H~0A40H, 0A54H~0A58H) */
++ {0x00000A30, 0x00000100, 0, 0},
++ {0x00000A34, 0x001F0001, 0, 0},
++ {0x00000A38, 0x00000000, 0, 0},
++ {0x00000A3C, 0x00000100, 0, 0},
++ {0x00000A40, 0x00000008, 0, 0},
++ {0x00000A54, 0x04010001, 0, 0},
++ {0x00000A58, 0x03FF0001, 0, 0},
++ /* config OBA(0090H~0094H) */
++ {0x00000090, 0x04380000, 0, 0},
++ {0x00000094, 0x04390780, 0, 0},
++ /* config SC(0098H~009CH, 00B8H~00BCH,
++ * 00C0H, 0C4H~0D4H, 04D0H~054CH, 5D0H~5D4H)
++ */
++ {0x0000009C, 0x01000000, 0, 0},
++ {0x000000B8, 0x000C0000, 0, 0},
++ {0x000000BC, 0xC010151D, 0, 0},
++ {0x000000C0, 0x01F1BF08, 0, 0},
++ {0x000000C4, 0xFF00FF00, 0, 0},
++ {0x000000C8, 0xFF00FF00, 0, 0},
++ {0x000000CC, 0xFFFF0000, 0, 0},
++ {0x000000D0, 0xFFFF0000, 0, 0},
++ {0x000000D4, 0xFFFF0000, 0, 0},
++ {0x000000D8, 0x01050107, 0, 0},
++ {0x000004D0, 0x00000000, 0, 0},
++ {0x000004D4, 0x00000000, 0, 0},
++ {0x000004D8, 0x00000000, 0, 0},
++ {0x000004DC, 0x00000000, 0, 0},
++ {0x000004E0, 0x00000000, 0, 0},
++ {0x000004E4, 0x00000000, 0, 0},
++ {0x000004E8, 0x00000000, 0, 0},
++ {0x000004EC, 0x00000000, 0, 0},
++ {0x000004F0, 0x00100000, 0, 0},
++ {0x000004F4, 0x00000000, 0, 0},
++ {0x000004F8, 0x03D20000, 0, 0},
++ {0x000004FC, 0x00000000, 0, 0},
++ {0x00000500, 0x00950000, 0, 0},
++ {0x00000504, 0x00000000, 0, 0},
++ {0x00000508, 0x00253000, 0, 0},
++ {0x0000050C, 0x00000000, 0, 0},
++ {0x00000510, 0x00000000, 0, 0},
++ {0x00000514, 0x00000000, 0, 0},
++ {0x00000518, 0x00000000, 0, 0},
++ {0x0000051C, 0x00000000, 0, 0},
++ {0x00000520, 0x00000000, 0, 0},
++ {0x00000524, 0x00000000, 0, 0},
++ {0x00000528, 0x00000000, 0, 0},
++ {0x0000052C, 0x00000000, 0, 0},
++ {0x00000530, 0x00000000, 0, 0},
++ {0x00000534, 0x00000000, 0, 0},
++ {0x00000538, 0xFFFFFFF0, 0, 0},
++ {0x0000053C, 0x8FFFFFFF, 0, 0},
++ {0x00000540, 0x0000001E, 0, 0},
++ {0x00000544, 0x00000000, 0, 0},
++ {0x00000548, 0x00000000, 0, 0},
++ {0x0000054C, 0xF0F20000, 0, 0},
++ {0x000005D0, 0xFF00FF00, 0, 0},
++ {0x000005D4, 0xFF00FF00, 0, 0},
++ /* config YHIST(0CC8H~0CD8H) */
++ {0x00000CC8, 0x00000000, 0, 0},
++ {0x00000CCC, 0x0437077F, 0, 0},
++ {0x00000CD0, 0x00010002, 0, 0},
++ {0x00000CD4, 0x00000000, 0, 0},
++ /* config CBAR(0600H-0653H) */
++ {0x00000600, 0x043E0782, 0, 0},
++ {0x00000604, 0x00000000, 0, 0},
++ {0x00000608, 0x0437077F, 0, 0},
++ {0x0000060C, 0x00443150, 0, 0},
++ {0x00000610, 0x00000000, 0, 0},
++ {0x00000614, 0x08880888, 0, 0},
++ {0x00000618, 0x02220222, 0, 0},
++ {0x0000061C, 0x04440444, 0, 0},
++ {0x00000620, 0x08880888, 0, 0},
++ {0x00000624, 0x0AAA0AAA, 0, 0},
++ {0x00000628, 0x0CCC0CCC, 0, 0},
++ {0x0000062C, 0x0EEE0EEE, 0, 0},
++ {0x00000630, 0x0FFF0FFF, 0, 0},
++ {0x00000634, 0x08880888, 0, 0},
++ {0x00000638, 0x02220222, 0, 0},
++ {0x0000063C, 0x04440444, 0, 0},
++ {0x00000640, 0x08880888, 0, 0},
++ {0x00000644, 0x0AAA0AAA, 0, 0},
++ {0x00000648, 0x0CCC0CCC, 0, 0},
++ {0x0000064C, 0x0EEE0EEE, 0, 0},
++ {0x00000650, 0x0FFF0FFF, 0, 0},
++ /* config sensor(0014H) */
++ {0x00000014, 0x0000000c, 0, 0},
++ /* config CROP(001CH, 0020H) */
++ {0x0000001C, 0x00000000, 0, 0},
++ {0x00000020, 0x0437077F, 0, 0},
++ /* config isp pileline X/Y size(A0CH) */
++ {0x00000A0C, 0x04380780, 0, 0},
++ /* config CSI dump (24H/28H) */
++ {0x00000028, 0x00030B80, 0, 0},
++ /* Video Output */
++ /* config UO(0A80H~0A90H) */
++ {0x00000A88, 0x00000780, 0, 0},
++ /* NV12 */
++ {0x00000A8C, 0x00000000, 0, 0},
++ /* NV21
++ *{0x00000A8C, 0x00000020, 0, 0},
++ */
++ {0x00000A90, 0x00000000, 0, 0},
++ {0x00000A9C, 0x00000780, 0, 0},
++ {0x00000AA0, 0x00000002, 0, 0},
++ {0x00000AA4, 0x00000002, 0, 0},
++ {0x00000AA8, 0x07800438, 0, 0},
++ {0x00000AB4, 0x00000780, 0, 0},
++ {0x00000AB8, 0x00000002, 0, 0},
++ {0x00000ABC, 0x00000002, 0, 0},
++ {0x00000AC0, 0x07800438, 0, 0},
++ {0x00000AC4, 0x00000000, 0, 0},
++ /* config TIL(0B20H~0B48H) */
++ {0x00000B20, 0x04380780, 0, 0},
++ {0x00000B24, 0x00000960, 0, 0},
++ {0x00000B38, 0x00030003, 0, 0},
++ {0x00000B3C, 0x00000960, 0, 0},
++ {0x00000B44, 0x00000000, 0, 0},
++ {0x00000B48, 0x00000000, 0, 0},
++ /* Enable DEC/OBC/OECF/LCCF/AWB/SC/DUMP */
++ {0x00000010, 0x000A00D6, 0x00000000, 0x00},
++ /* Enable CFA/CAR/CCM/GMARGB/R2Y/SHRP/SAT/DNYUV/YCRV/YHIST/CTC/DBC */
++ {0x00000A08, 0x107A01BE, 0x00000000, 0x00},
++};
++
++const struct reg_table isp_reg_init_settings[] = {
++ {isp_reg_init_config_list,
++ ARRAY_SIZE(isp_reg_init_config_list)},
++};
++
++static struct regval_t isp_reg_start_config_list[] = {
++#if defined(ENABLE_SS0_SS1)
++ /* ENABLE UO/SS0/SS1/Multi-Frame and Reset ISP */
++ {0x00000A00, 0x00121802, 0x00000000, 0x0A},
++ /* ENABLE UO/SS0/SS1/Multi-Frame and Leave ISP reset */
++ {0x00000A00, 0x00121800, 0x00000000, 0x0A},
++#else
++ /* ENABLE UO/Multi-Frame and Reset ISP */
++ {0x00000A00, 0x00120002, 0x00000000, 0x0A},
++ /* ENABLE UO/Multi-Frame and Leave ISP reset */
++ {0x00000A00, 0x00120000, 0x00000000, 0x0A},
++#endif
++ /* Config ISP shadow mode as next-vsync */
++ {0x00000A50, 0x00000002, 0x00000000, 0x00},
++#if defined(ENABLE_SS0_SS1)
++ /* ENABLE UO/SS0/SS1/Multi-Frame and Enable ISP */
++ {0x00000A00, 0x00121801, 0x00000000, 0x0A},
++#else
++ /* ENABLE UO/Multi-Frame and Enable ISP */
++ {0x00000A00, 0x00120001, 0x00000000, 0x0A},
++#endif
++ /* Config CSI shadow mode as immediate to fetch current setting */
++ {0x00000008, 0x00010004, 0x00000000, 0x0A},
++ /* Config CSI shadow mode as next-vsync */
++ {0x00000008, 0x00020004, 0x00000000, 0x00},
++ /* Enable CSI */
++ {0x00000000, 0x00000001, 0x00000000, 0x0A},
++};
++
++const struct reg_table isp_reg_start_settings[] = {
++ {isp_reg_start_config_list,
++ ARRAY_SIZE(isp_reg_start_config_list)},
++};
++
++static struct regval_t isp_imx_219_reg_config_list[] = {
++ /* MIPI sensor */
++ {0x00000014, 0x0000000D, 0, 0},
++ /* config CFA(0018H, 0A1CH) */
++ {0x00000A1C, 0x00000032, 0, 0},
++ {0x00000A8C, 0x00000000, 0, 0},
++ {0x00000A90, 0x00000000, 0, 0},
++ /* config R2Y(0E40H~0E60H) */
++ {0x00000E40, 0x0000004C, 0, 0},
++ {0x00000E44, 0x00000097, 0, 0},
++ {0x00000E48, 0x0000001D, 0, 0},
++ {0x00000E4C, 0x000001D5, 0, 0},
++ {0x00000E50, 0x000001AC, 0, 0},
++ {0x00000E54, 0x00000080, 0, 0},
++ {0x00000E58, 0x00000080, 0, 0},
++ {0x00000E5C, 0x00000194, 0, 0},
++ {0x00000E60, 0x000001EC, 0, 0},
++ /* Config AWB(0280H~02DCH). Fixed WB gain for IMX-219 sensor. */
++ {0x00000280, 0x00000000, 0, 0},
++ {0x00000284, 0x00000000, 0, 0},
++ {0x00000288, 0x00000000, 0, 0},
++ {0x0000028C, 0x00000000, 0, 0},
++ {0x00000290, 0x00000000, 0, 0},
++ {0x00000294, 0x00000000, 0, 0},
++ {0x00000298, 0x00000000, 0, 0},
++ {0x0000029C, 0x00000000, 0, 0},
++ {0x000002A0, 0x00000000, 0, 0},
++ {0x000002A4, 0x00000000, 0, 0},
++ {0x000002A8, 0x00000000, 0, 0},
++ {0x000002AC, 0x00000000, 0, 0},
++ {0x000002B0, 0x00000000, 0, 0},
++ {0x000002B4, 0x00000000, 0, 0},
++ {0x000002B8, 0x00000000, 0, 0},
++ {0x000002BC, 0x00000000, 0, 0},
++ {0x000002C0, 0x00F000F0, 0, 0},
++ {0x000002C4, 0x00F000F0, 0, 0},
++ {0x000002C8, 0x00800080, 0, 0},
++ {0x000002CC, 0x00800080, 0, 0},
++ {0x000002D0, 0x00800080, 0, 0},
++ {0x000002D4, 0x00800080, 0, 0},
++ {0x000002D8, 0x00B000B0, 0, 0},
++ {0x000002DC, 0x00B000B0, 0, 0},
++ /* config GMARGB(0E00H~0E38H)
++ * Gamma RGB 1.9 for IMX-219 sensor
++ */
++ {0x00000E00, 0x24000000, 0, 0},
++ {0x00000E04, 0x159500A5, 0, 0},
++ {0x00000E08, 0x0F9900EE, 0, 0},
++ {0x00000E0C, 0x0CE40127, 0, 0},
++ {0x00000E10, 0x0B410157, 0, 0},
++ {0x00000E14, 0x0A210181, 0, 0},
++ {0x00000E18, 0x094B01A8, 0, 0},
++ {0x00000E1C, 0x08A401CC, 0, 0},
++ {0x00000E20, 0x081D01EE, 0, 0},
++ {0x00000E24, 0x06B20263, 0, 0},
++ {0x00000E28, 0x05D802C7, 0, 0},
++ {0x00000E2C, 0x05420320, 0, 0},
++ {0x00000E30, 0x04D30370, 0, 0},
++ {0x00000E34, 0x047C03BB, 0, 0},
++ {0x00000E38, 0x043703FF, 0, 0},
++ {0x00000010, 0x00000080, 0, 0},
++ /* Enable CFA/GMARGB/R2Y */
++ {0x00000A08, 0x10000032, 0x0FFFFFFF, 0x00},
++ {0x00000A00, 0x00120002, 0, 0},
++ {0x00000A00, 0x00120000, 0, 0},
++ {0x00000A50, 0x00000002, 0, 0},
++ {0x00000008, 0x00010000, 0, 0},
++ {0x00000008, 0x0002000A, 0, 0},
++ {0x00000000, 0x00000001, 0, 0},
++};
++
++const struct reg_table isp_imx_219_settings[] = {
++ {isp_imx_219_reg_config_list,
++ ARRAY_SIZE(isp_imx_219_reg_config_list)},
++};
++
++static struct regval_t isp_format_reg_list[] = {
++ {0x0000001C, 0x00000000, 0x00000000, 0},
++ {0x00000020, 0x0437077F, 0x00000000, 0},
++ {0x00000A0C, 0x04380780, 0x00000000, 0},
++ {0x00000A88, 0x00000780, 0x00000000, 0},
++ {0x00000018, 0x000011BB, 0x00000000, 0},
++ {0x00000A08, 0x10000000, 0xF0000000, 0},
++ {0x00000028, 0x00030B80, 0x0003FFFF, 0},
++ {0x00000AA8, 0x07800438, 0x00000000, 0},
++ {0x00000A9C, 0x00000780, 0x00000000, 0},
++ {0x00000AC0, 0x07800438, 0x00000000, 0},
++ {0x00000AB4, 0x00000780, 0x00000000, 0},
++ {0x00000B20, 0x04380780, 0x00000000, 0},
++ {0x00000B24, 0x00000960, 0x00000000, 0},
++ {0x00000B3C, 0x00000960, 0x00000000, 0},
++ {0x00000014, 0x00000008, 0x00000000, 0},
++};
++
++const struct reg_table isp_format_settings[] = {
++ {isp_format_reg_list,
++ ARRAY_SIZE(isp_format_reg_list)},
++};
++
++#if defined(USE_NEW_CONFIG_SETTING)
++#else
++static struct reg_table *isp_settings = (struct reg_table *)isp_imx_219_settings;
++#endif
++
++static void isp_load_regs(void __iomem *ispbase, const struct reg_table *table)
++{
++ int j;
++ u32 delay_ms, reg_addr, mask, val;
++
++ for (j = 0; j < table->regval_num; j++) {
++ delay_ms = table->regval[j].delay_ms;
++ reg_addr = table->regval[j].addr;
++ val = table->regval[j].val;
++ mask = table->regval[j].mask;
++
++ if (reg_addr % 4
++ || reg_addr > STF_ISP_REG_OFFSET_MAX
++ || delay_ms > STF_ISP_REG_DELAY_MAX)
++ continue;
++
++ if (mask)
++ reg_set_bit(ispbase, reg_addr, mask, val);
++ else
++ reg_write(ispbase, reg_addr, val);
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++}
++
++static void isp_load_regs_exclude_csi_isp_enable(
++ void __iomem *ispbase,
++ const struct reg_table *table)
++{
++ int j;
++ u32 delay_ms, reg_addr, mask, val;
++
++ for (j = 0; j < table->regval_num; j++) {
++ delay_ms = table->regval[j].delay_ms;
++ reg_addr = table->regval[j].addr;
++ val = table->regval[j].val;
++ mask = table->regval[j].mask;
++
++ if (reg_addr % 4
++ || reg_addr > STF_ISP_REG_OFFSET_MAX
++ || delay_ms > STF_ISP_REG_DELAY_MAX
++ || ((reg_addr == ISP_REG_CSI_INPUT_EN_AND_STATUS) && (val & 0x01))
++ || ((reg_addr == ISP_REG_ISP_CTRL_0) && (val & 0x01)))
++ continue;
++
++ if (mask)
++ reg_set_bit(ispbase, reg_addr, mask, val);
++ else
++ reg_write(ispbase, reg_addr, val);
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++}
++
++static int stf_isp_clk_enable(struct stf_isp_dev *isp_dev)
++{
++ struct stfcamss *stfcamss = isp_dev->stfcamss;
++
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_WRAPPER_C].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_WRAPPER_P].rstc);
++
++ return 0;
++}
++
++static int stf_isp_clk_disable(struct stf_isp_dev *isp_dev)
++{
++ struct stfcamss *stfcamss = isp_dev->stfcamss;
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_WRAPPER_C].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_WRAPPER_P].rstc);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk);
++
++ return 0;
++}
++
++static void __iomem *stf_isp_get_ispbase(struct stf_vin_dev *vin)
++{
++ void __iomem *base = vin->isp_base;
++
++ return base;
++}
++
++static int stf_isp_save_ctx_regs(struct stf_isp_dev *isp_dev)
++{
++ int j;
++ u32 addr, val;
++ void __iomem *ispbase;
++ struct device *dev = isp_dev->stfcamss->dev;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ if (!isp_dev->context_regs) {
++ int regs_size =
++ sizeof(struct regval_t) * isp_reg_init_settings->regval_num;
++ isp_dev->context_regs =
++ devm_kzalloc(dev, sizeof(struct reg_table), GFP_KERNEL);
++ isp_dev->context_regs->regval =
++ devm_kzalloc(dev, regs_size, GFP_KERNEL);
++ isp_dev->context_regs->regval_num = isp_reg_init_settings->regval_num;
++ }
++
++ if (!isp_dev->context_regs || !isp_dev->context_regs->regval)
++ return -ENOMEM;
++
++ st_debug(ST_ISP, "Saving ISP context registers\n");
++ for (j = 0; j < isp_reg_init_settings->regval_num; j++) {
++ addr = isp_reg_init_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ isp_dev->context_regs->regval[j].addr = addr;
++ isp_dev->context_regs->regval[j].val = val;
++ }
++ st_debug(ST_ISP, "ISP context registers have been saved\n");
++
++ return 0;
++};
++
++static int stf_isp_restore_ctx_regs(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ if (isp_dev->context_regs) {
++ isp_load_regs(ispbase, isp_dev->context_regs);
++ st_debug(ST_ISP, "Restored ISP register: isp_reg_init_settings.\n");
++ }
++
++ return 0;
++}
++
++static int stf_isp_reset(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(1), BIT(1));
++ reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(1), 0);
++
++ return 0;
++}
++
++static int stf_isp_config_set(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ st_debug(ST_ISP, "%s\n", __func__);
++
++#if defined(USE_NEW_CONFIG_SETTING)
++ mutex_lock(&isp_dev->setfile_lock);
++
++ if (isp_dev->context_regs) {
++ stf_isp_restore_ctx_regs(isp_dev);
++ st_debug(ST_ISP, "%s context regs restore done\n", __func__);
++ } else {
++ isp_load_regs(ispbase, isp_reg_init_settings);
++ st_debug(ST_ISP, "%s isp_reg_init_settings done\n", __func__);
++ }
++ if (isp_dev->setfile.state) {
++ st_info(ST_ISP, "%s, Program extra ISP setting!\n", __func__);
++ isp_load_regs_exclude_csi_isp_enable(ispbase,
++ &isp_dev->setfile.settings);
++ }
++
++ mutex_unlock(&isp_dev->setfile_lock);
++#else
++ mutex_lock(&isp_dev->setfile_lock);
++ if (isp_dev->setfile.state)
++ isp_load_regs(ispbase, &isp_dev->setfile.settings);
++ else
++ isp_load_regs(ispbase, isp_settings);
++ mutex_unlock(&isp_dev->setfile_lock);
++
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[0].addr,
++ isp_format_reg_list[0].val);
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[1].addr,
++ isp_format_reg_list[1].val);
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[2].addr,
++ isp_format_reg_list[2].val);
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[3].addr,
++ isp_format_reg_list[3].val);
++#endif
++
++ return 0;
++}
++
++static int stf_isp_set_format(struct stf_isp_dev *isp_dev,
++ struct isp_stream_format *crop_array, u32 mcode,
++ int type)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ struct stf_dvp_dev *dvp_dev = isp_dev->stfcamss->dvp_dev;
++ struct v4l2_rect *crop = &crop_array[ISP_COMPOSE].rect;
++ u32 bpp = crop_array[ISP_COMPOSE].bpp;
++ void __iomem *ispbase;
++ u32 val, val1;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ st_debug(ST_ISP, "interface type is %d(%s)\n",
++ type, type == CSI_SENSOR ? "CSI" : "DVP");
++
++ if (type == DVP_SENSOR) {
++ unsigned int flags = dvp_dev->dvp->flags;
++
++ st_debug(ST_ISP, "dvp flags = 0x%x, hsync active is %s, vsync active is %s\n",
++ flags, flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH ? "high" : "low",
++ flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH ? "high" : "low");
++ }
++
++ val = crop->left + (crop->top << 16);
++ isp_format_reg_list[0].addr = ISP_REG_PIC_CAPTURE_START_CFG;
++ isp_format_reg_list[0].val = val;
++
++ val = (crop->width + crop->left - 1)
++ + ((crop->height + crop->top - 1) << 16);
++ isp_format_reg_list[1].addr = ISP_REG_PIC_CAPTURE_END_CFG;
++ isp_format_reg_list[1].val = val;
++
++ val = crop->width + (crop->height << 16);
++ isp_format_reg_list[2].addr = ISP_REG_PIPELINE_XY_SIZE;
++ isp_format_reg_list[2].val = val;
++
++ isp_format_reg_list[3].addr = ISP_REG_STRIDE;
++ isp_format_reg_list[3].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ switch (mcode) {
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ // 3 2 3 2 1 0 1 0 B Gb B Gb Gr R Gr R
++ val = 0x0000EE44;
++ val1 = 0x00000000;
++ break;
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ // 2 3 2 3 0 1 0 1, Gb B Gb B R Gr R Gr
++ val = 0x0000BB11;
++ val1 = 0x20000000;
++ break;
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ // 1 0 1 0 3 2 3 2, Gr R Gr R B Gb B Gb
++ val = 0x000044EE;
++ val1 = 0x30000000;
++ break;
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ // 0 1 0 1 2 3 2 3 R Gr R Gr Gb B Gb B
++ val = 0x000011BB;
++ val1 = 0x10000000;
++ break;
++ default:
++ st_err(ST_ISP, "UNKNOW format\n");
++ val = 0x000011BB;
++ val1 = 0x10000000;
++ break;
++ }
++
++ isp_format_reg_list[4].addr = ISP_REG_RAW_FORMAT_CFG;
++ isp_format_reg_list[4].val = val;
++
++ isp_format_reg_list[5].addr = ISP_REG_ISP_CTRL_1;
++ isp_format_reg_list[5].val = val1;
++ isp_format_reg_list[5].mask = 0xF0000000;
++
++ st_info(ST_ISP, "src left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ crop = &crop_array[ISP_CROP].rect;
++ bpp = crop_array[ISP_CROP].bpp;
++ val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_128);
++ isp_format_reg_list[6].addr = ISP_REG_DUMP_CFG_1;
++ isp_format_reg_list[6].val = val | 3 << 16;
++ isp_format_reg_list[6].mask = 0x0003FFFF;
++
++ st_info(ST_ISP, "raw left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ crop = &crop_array[ISP_SCALE_SS0].rect;
++ bpp = crop_array[ISP_SCALE_SS0].bpp;
++ isp_format_reg_list[7].addr = ISP_REG_SS0IW;
++ isp_format_reg_list[7].val = (crop->width << 16) + crop->height;
++ isp_format_reg_list[8].addr = ISP_REG_SS0S;
++ isp_format_reg_list[8].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ st_info(ST_ISP, "ss0 left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ crop = &crop_array[ISP_SCALE_SS1].rect;
++ bpp = crop_array[ISP_SCALE_SS1].bpp;
++ isp_format_reg_list[9].addr = ISP_REG_SS1IW;
++ isp_format_reg_list[9].val = (crop->width << 16) + crop->height;
++ isp_format_reg_list[10].addr = ISP_REG_SS1S;
++ isp_format_reg_list[10].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ crop = &crop_array[ISP_ITIWS].rect;
++ bpp = crop_array[ISP_ITIWS].bpp;
++ isp_format_reg_list[11].addr = ISP_REG_ITIIWSR;
++ isp_format_reg_list[11].val = (crop->height << 16) + crop->width;
++ isp_format_reg_list[12].addr = ISP_REG_ITIDWLSR;
++ isp_format_reg_list[12].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ isp_format_reg_list[13].addr = ISP_REG_ITIDRLSR;
++ isp_format_reg_list[13].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ st_info(ST_ISP, "iti left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ isp_format_reg_list[14].addr = ISP_REG_SENSOR;
++ isp_format_reg_list[14].val = 0x00000000;
++ if (type == DVP_SENSOR) {
++ unsigned int flags = dvp_dev->dvp->flags;
++
++ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
++ isp_format_reg_list[14].val |= 0x08;
++ if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
++ isp_format_reg_list[14].val |= 0x04;
++ } else {
++ isp_format_reg_list[14].val |= 0x01;
++ }
++
++ isp_load_regs(ispbase, isp_format_settings);
++ return 0;
++}
++
++static int stf_isp_stream_set(struct stf_isp_dev *isp_dev, int on)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ if (on) {
++#if defined(USE_NEW_CONFIG_SETTING)
++ isp_load_regs(ispbase, isp_reg_start_settings);
++#else
++ reg_set_bit(ispbase, ISP_REG_CSIINTS_ADDR, 0x3FFFF, 0x3000a);
++ reg_set_bit(ispbase, ISP_REG_IESHD_ADDR, BIT(1) | BIT(0), 0x3);
++ reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(0), 1);
++#endif //#if defined(USE_NEW_CONFIG_SETTING)
++ } else {
++ /* NOTE: Clear bit 0 of ISP_REG_ISP_CTRL_0 here will get crash. */
++ stf_isp_save_ctx_regs(isp_dev);
++ }
++
++ return 0;
++}
++
++static union reg_buf reg_buf;
++static int stf_isp_reg_read(struct stf_isp_dev *isp_dev, void *arg)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ struct isp_reg_param *reg_param = arg;
++ u32 size;
++ unsigned long r;
++
++ if (reg_param->reg_buf == NULL) {
++ st_err(ST_ISP, "Failed to access register. The pointer is NULL!!!\n");
++ return -EINVAL;
++ }
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ size = 0;
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ if (reg_param->reg_info.length > STF_ISP_REG_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_BUF_SIZE);
++ return -EINVAL;
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ /* This mode is not supported in the V4L2 version. */
++ st_err(ST_ISP, "Reg Read - Failed to access register. The method = \
++ STF_ISP_REG_METHOD_MODULE is not supported!!!\n");
++ return -ENOTTY;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_2_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_2_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 3;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_3_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_3_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 4;
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ st_err(ST_ISP, "Reg Read - Failed to access register. The method = \
++ STF_ISP_REG_METHOD_SMPL_PACK is not supported!!!\n");
++ return -ENOTTY;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ // This mode is not supported in the V4L2 version.
++ st_err(ST_ISP, "Reg Read - Failed to access register. The method = \
++ STF_ISP_REG_METHOD_SOFT_RDMA is not supported!!!\n");
++ return -ENOTTY;
++
++ default:
++ st_err(ST_ISP, "Failed to access register. The method=%d \
++ is not supported!!!\n", reg_param->reg_info.method);
++ return -ENOTTY;
++ }
++
++ memset(&reg_buf, 0, sizeof(union reg_buf));
++ if (size) {
++ r = copy_from_user((u8 *)reg_buf.buffer,
++ (u8 *)reg_param->reg_buf->buffer, size);
++ if (r) {
++ st_err(ST_ISP, "Failed to call copy_from_user for the \
++ reg_param->reg_buf value\n");
++ return -EIO;
++ }
++ }
++
++ size = 0;
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ reg_buf.buffer[0] = reg_read(ispbase, reg_param->reg_info.offset);
++ size = sizeof(u32);
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_buf.buffer[r] = reg_read(ispbase,
++ reg_param->reg_info.offset + (r * 4));
++ }
++ size = sizeof(u32) * reg_param->reg_info.length;
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_buf.reg_tbl[r].value = reg_read(ispbase,
++ reg_buf.reg_tbl[r].offset);
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl2[r].mask) {
++ reg_buf.reg_tbl2[r].value = (reg_read(ispbase,
++ reg_buf.reg_tbl2[r].offset)
++ & reg_buf.reg_tbl2[r].mask);
++ } else {
++ reg_buf.reg_tbl2[r].value = reg_read(ispbase,
++ reg_buf.reg_tbl2[r].offset);
++ }
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 3;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl3[r].mask) {
++ reg_buf.reg_tbl3[r].value = (reg_read(ispbase,
++ reg_buf.reg_tbl3[r].offset)
++ & reg_buf.reg_tbl3[r].mask);
++ } else {
++ reg_buf.reg_tbl3[r].value = reg_read(ispbase,
++ reg_buf.reg_tbl3[r].offset);
++ }
++ if (reg_buf.reg_tbl3[r].delay_ms) {
++ usleep_range(1000 * reg_buf.reg_tbl3[r].delay_ms,
++ 1000 * reg_buf.reg_tbl3[r].delay_ms + 100);
++ }
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 4;
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ break;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ break;
++
++ default:
++ break;
++ }
++
++ r = copy_to_user((u8 *)reg_param->reg_buf->buffer, (u8 *)reg_buf.buffer,
++ size);
++ if (r) {
++ st_err(ST_ISP, "Failed to call copy_to_user for the \
++ reg_param->buffer value\n");
++ return -EIO;
++ }
++
++ return 0;
++}
++
++static int stf_isp_soft_rdma(struct stf_isp_dev *isp_dev, u32 rdma_addr)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ struct isp_rdma_info *rdma_info = NULL;
++ s32 len;
++ u32 offset;
++ int ret = 0;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ rdma_info = phys_to_virt(rdma_addr);
++ while (1) {
++ if (rdma_info->tag == RDMA_WR_ONE) {
++ reg_write(ispbase, rdma_info->offset, rdma_info->param);
++ rdma_info++;
++ } else if (rdma_info->tag == RDMA_WR_SRL) {
++ offset = rdma_info->offset;
++ len = rdma_info->param;
++ rdma_info++;
++ while (len > 0) {
++ reg_write(ispbase, offset, rdma_info->param);
++ offset += 4;
++ len--;
++ if (len > 0) {
++ reg_write(ispbase, offset, rdma_info->value);
++ len--;
++ }
++ offset += 4;
++ rdma_info++;
++ }
++ } else if (rdma_info->tag == RDMA_LINK) {
++ rdma_info = phys_to_virt(rdma_info->param);
++ } else if (rdma_info->tag == RDMA_SINT) {
++ /* Software not support this command. */
++ rdma_info++;
++ } else if (rdma_info->tag == RDMA_END) {
++ break;
++ } else
++ rdma_info++;
++ }
++
++ return ret;
++}
++
++static int stf_isp_reg_write(struct stf_isp_dev *isp_dev, void *arg)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ struct isp_reg_param *reg_param = arg;
++ struct isp_rdma_info *rdma_info = NULL;
++ s32 len;
++ u32 offset;
++ u32 size;
++ unsigned long r;
++ int ret = 0;
++
++ if ((reg_param->reg_buf == NULL)
++ && (reg_param->reg_info.method != STF_ISP_REG_METHOD_SOFT_RDMA)) {
++ st_err(ST_ISP, "Failed to access register. \
++ The register buffer pointer is NULL!!!\n");
++ return -EINVAL;
++ }
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ size = 0;
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ size = sizeof(u32);
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ if (reg_param->reg_info.length > STF_ISP_REG_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length;
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ // This mode is not supported in the V4L2 version.
++ st_err(ST_ISP, "Reg Write - Failed to access register. \
++ The method = STF_ISP_REG_METHOD_MODULE is not supported!!!\n");
++ return -ENOTTY;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_2_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_2_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 3;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_3_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_3_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 4;
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ if (reg_param->reg_info.length > STF_ISP_REG_SMPL_PACK_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_SMPL_PACK_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ break;
++
++ default:
++ st_err(ST_ISP, "Failed to access register. The method=%d \
++ is not supported!!!\n", reg_param->reg_info.method);
++ return -ENOTTY;
++ }
++
++ memset(&reg_buf, 0, sizeof(union reg_buf));
++ if (size) {
++ r = copy_from_user((u8 *)reg_buf.buffer,
++ (u8 *)reg_param->reg_buf->buffer, size);
++ if (r) {
++ st_err(ST_ISP, "Failed to call copy_from_user for the \
++ reg_param->reg_buf value\n");
++ return -EIO;
++ }
++ }
++
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ reg_write(ispbase, reg_param->reg_info.offset, reg_buf.buffer[0]);
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_write(ispbase, reg_param->reg_info.offset + (r * 4),
++ reg_buf.buffer[r]);
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ /* This mode is not supported in the V4L2 version. */
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_write(ispbase, reg_buf.reg_tbl[r].offset,
++ reg_buf.reg_tbl[r].value);
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl2[r].mask) {
++ reg_set_bit(ispbase, reg_buf.reg_tbl2[r].offset,
++ reg_buf.reg_tbl2[r].mask, reg_buf.reg_tbl2[r].value);
++ } else {
++ reg_write(ispbase, reg_buf.reg_tbl2[r].offset,
++ reg_buf.reg_tbl2[r].value);
++ }
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl3[r].mask) {
++ reg_set_bit(ispbase, reg_buf.reg_tbl3[r].offset,
++ reg_buf.reg_tbl3[r].mask, reg_buf.reg_tbl3[r].value);
++ } else {
++ reg_write(ispbase, reg_buf.reg_tbl3[r].offset,
++ reg_buf.reg_tbl3[r].value);
++ }
++ if (reg_buf.reg_tbl3[r].delay_ms) {
++ usleep_range(1000 * reg_buf.reg_tbl3[r].delay_ms,
++ 1000 * reg_buf.reg_tbl3[r].delay_ms + 100);
++ }
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ size = reg_param->reg_info.length;
++ rdma_info = &reg_buf.rdma_cmd[0];
++ while (size) {
++ if (rdma_info->tag == RDMA_WR_ONE) {
++ reg_write(ispbase, rdma_info->offset, rdma_info->param);
++ rdma_info++;
++ size--;
++ } else if (rdma_info->tag == RDMA_WR_SRL) {
++ offset = rdma_info->offset;
++ len = rdma_info->param;
++ rdma_info++;
++ size--;
++ while (size && (len > 0)) {
++ reg_write(ispbase, offset, rdma_info->param);
++ offset += 4;
++ len--;
++ if (len > 0) {
++ reg_write(ispbase, offset, rdma_info->value);
++ len--;
++ }
++ offset += 4;
++ rdma_info++;
++ size--;
++ }
++ } else if (rdma_info->tag == RDMA_END) {
++ break;
++ } else {
++ rdma_info++;
++ size--;
++ }
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ /*
++ * Simulation the hardware RDMA behavior to debug and verify
++ * the RDMA chain.
++ */
++ ret = stf_isp_soft_rdma(isp_dev, reg_param->reg_info.offset);
++ break;
++
++ default:
++ break;
++ }
++
++ return ret;
++}
++
++static int stf_isp_shadow_trigger(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ // shadow update
++ reg_set_bit(ispbase, ISP_REG_CSIINTS_ADDR, (BIT(17) | BIT(16)), 0x30000);
++ reg_set_bit(ispbase, ISP_REG_IESHD_ADDR, (BIT(1) | BIT(0)), 0x3);
++ return 0;
++}
++
++void dump_isp_reg(void *__iomem ispbase)
++{
++ int j;
++ u32 addr, val;
++
++ st_debug(ST_ISP, "DUMP ISP register:\n -- isp_reg_init_settings --\n");
++ for (j = 0; j < isp_reg_init_settings->regval_num; j++) {
++ addr = isp_reg_init_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ st_debug(ST_ISP, "{0x%08x, 0x%08x}\n", addr, val);
++ }
++
++ st_debug(ST_ISP, " --- isp_format_settings ---\n");
++ for (j = 0; j < isp_format_settings->regval_num; j++) {
++ addr = isp_format_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ st_debug(ST_ISP, "{0x%08x, 0x%08x}\n", addr, val);
++ }
++
++ val = ioread32(ispbase + ISP_REG_Y_PLANE_START_ADDR);
++ st_debug(ST_ISP, "-- ISP_REG_Y_PLANE_START_ADDR --\n {0x%08x, 0x%08x}\n",
++ ISP_REG_Y_PLANE_START_ADDR, val);
++ val = ioread32(ispbase + ISP_REG_UV_PLANE_START_ADDR);
++ st_debug(ST_ISP, "-- ISP_REG_UV_PLANE_START_ADDR --\n {0x%08x, 0x%08x}\n",
++ ISP_REG_UV_PLANE_START_ADDR, val);
++ val = ioread32(ispbase + ISP_REG_DUMP_CFG_0);
++ st_debug(ST_ISP, "-- ISP_REG_DUMP_CFG_0 --\n {0x%08x, 0x%08x}\n",
++ ISP_REG_DUMP_CFG_0, val);
++ val = ioread32(ispbase + ISP_REG_DUMP_CFG_1);
++ st_debug(ST_ISP, " --- ISP_REG_DUMP_CFG_1 ---\n {0x%08x, 0x%08x}\n",
++ ISP_REG_DUMP_CFG_1, val);
++
++ st_debug(ST_ISP, " --- isp_reg_start_settings ---\n");
++ for (j = 0; j < isp_reg_start_settings->regval_num; j++) {
++ addr = isp_reg_start_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ st_debug(ST_ISP, "{0x%08x, 0x%08x}\n", addr, val);
++ }
++}
++
++struct isp_hw_ops isp_ops = {
++ .isp_clk_enable = stf_isp_clk_enable,
++ .isp_clk_disable = stf_isp_clk_disable,
++ .isp_reset = stf_isp_reset,
++ .isp_config_set = stf_isp_config_set,
++ .isp_set_format = stf_isp_set_format,
++ .isp_stream_set = stf_isp_stream_set,
++ .isp_reg_read = stf_isp_reg_read,
++ .isp_reg_write = stf_isp_reg_write,
++ .isp_shadow_trigger = stf_isp_shadow_trigger,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp_ioctl.h
+@@ -0,0 +1,133 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_ISP_IOCTL_H
++#define STF_ISP_IOCTL_H
++
++
++#include <media/v4l2-ctrls.h>
++
++
++#define FILENAME_MAX_LEN 30
++
++#define ISP_IOC ('V')
++#define STF_ISP_REG_BUF_SIZE (768)
++#define STF_ISP_REG_TBL_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 2)
++#define STF_ISP_REG_TBL_2_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 3)
++#define STF_ISP_REG_TBL_3_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 4)
++#define STF_ISP_REG_SMPL_PACK_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 2)
++#define RDMA_WR_ONE (0xA0)
++#define RDMA_WR_SRL (0xA1)
++#define RDMA_LINK (0xA2)
++#define RDMA_SINT (0xA3)
++#define RDMA_END (0xAF)
++#define ENABLE_SS0_SS1
++
++enum _STF_ISP_IOCTL {
++ STF_ISP_IOCTL_LOAD_FW = BASE_VIDIOC_PRIVATE + 1,
++ STF_ISP_IOCTL_DMABUF_ALLOC,
++ STF_ISP_IOCTL_DMABUF_FREE,
++ STF_ISP_IOCTL_GET_HW_VER,
++ STF_ISP_IOCTL_REG,
++ STF_ISP_IOCTL_SHADOW_LOCK,
++ STF_ISP_IOCTL_SHADOW_UNLOCK,
++ STF_ISP_IOCTL_SHADOW_UNLOCK_N_TRIGGER,
++ STF_ISP_IOCTL_SET_USER_CONFIG_ISP,
++ STF_ISP_IOCTL_MAX
++};
++
++enum _STF_ISP_REG_METHOD {
++ STF_ISP_REG_METHOD_ONE_REG = 0,
++ STF_ISP_REG_METHOD_SERIES,
++ STF_ISP_REG_METHOD_MODULE,
++ STF_ISP_REG_METHOD_TABLE,
++ STF_ISP_REG_METHOD_TABLE_2,
++ STF_ISP_REG_METHOD_TABLE_3,
++ STF_ISP_REG_METHOD_SMPL_PACK,
++ STF_ISP_REG_METHOD_SOFT_RDMA,
++ STF_ISP_REG_METHOD_MAX
++};
++
++
++struct stfisp_fw_info {
++ char __user filename[FILENAME_MAX_LEN];
++};
++
++struct dmabuf_create {
++ __u32 fd;
++ __u32 size;
++ __u32 paddr;
++};
++
++struct isp_rdma_info {
++ u32 param;
++ union {
++ u32 value;
++ struct {
++ u32 offset : 24;
++ u32 tag : 8;
++ };
++ };
++};
++
++struct isp_reg_info {
++ /** @brief [in] access method of register */
++ u8 method;
++ /** @brief [in] offset indicated which register will be read/write */
++ u32 offset;
++ /** @brief [in] length for indicated how much register will be read/write */
++ u32 length;
++};
++
++union reg_buf {
++ u32 buffer[STF_ISP_REG_BUF_SIZE];
++ struct {
++ u32 offset;
++ u32 value;
++ } reg_tbl[STF_ISP_REG_TBL_BUF_SIZE];
++ struct {
++ u32 offset;
++ u32 value;
++ u32 mask;
++ } reg_tbl2[STF_ISP_REG_TBL_2_BUF_SIZE];
++ struct {
++ u32 offset;
++ u32 value;
++ u32 mask;
++ u32 delay_ms;
++ } reg_tbl3[STF_ISP_REG_TBL_3_BUF_SIZE];
++ struct isp_rdma_info rdma_cmd[STF_ISP_REG_SMPL_PACK_BUF_SIZE];
++};
++
++struct isp_reg_param {
++ /** @brief [in, out] register read/write information */
++ struct isp_reg_info reg_info;
++ /** @brief [in, out] buffer */
++ union reg_buf *reg_buf;
++};
++
++
++#define VIDIOC_STFISP_LOAD_FW \
++ _IOW(ISP_IOC, STF_ISP_IOCTL_LOAD_FW, struct stfisp_fw_info)
++#define VIDIOC_STF_DMABUF_ALLOC \
++ _IOWR(ISP_IOC, STF_ISP_IOCTL_DMABUF_ALLOC, struct dmabuf_create)
++#define VIDIOC_STF_DMABUF_FREE \
++ _IOWR(ISP_IOC, STF_ISP_IOCTL_DMABUF_FREE, struct dmabuf_create)
++#define VIDIOC_STFISP_GET_REG \
++ _IOWR(ISP_IOC, STF_ISP_IOCTL_REG, struct isp_reg_param)
++#define VIDIOC_STFISP_SET_REG \
++ _IOW(ISP_IOC, STF_ISP_IOCTL_REG, struct isp_reg_param)
++#define VIDIOC_STFISP_SHADOW_LOCK \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SHADOW_LOCK)
++#define VIDIOC_STFISP_SHADOW_UNLOCK \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SHADOW_UNLOCK)
++#define VIDIOC_STFISP_SHADOW_UNLOCK_N_TRIGGER \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SHADOW_UNLOCK_N_TRIGGER)
++#define VIDIOC_STFISP_SET_USER_CONFIG_ISP \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SET_USER_CONFIG_ISP)
++
++
++#endif /* STF_ISP_IOCTL_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+@@ -0,0 +1,1552 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include "stf_video.h"
++#include <media/media-entity.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-mc.h>
++#include <media/videobuf2-dma-sg.h>
++#include <media/videobuf2-vmalloc.h>
++#include <media/videobuf2-dma-contig.h>
++
++static const struct stfcamss_format_info formats_pix_st7110_wr[] = {
++ { MEDIA_BUS_FMT_AYUV8_1X32, V4L2_PIX_FMT_AYUV32, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 32 } },
++ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_PIX_FMT_RGB565, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
++ { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++};
++
++static const struct stfcamss_format_info formats_raw_st7110_isp[] = {
++ { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++};
++
++static const struct stfcamss_format_info formats_pix_st7110_isp[] = {
++ // { MEDIA_BUS_FMT_YUYV12_2X12, V4L2_PIX_FMT_NV12M, 2,
++ // { { 1, 1 }, { 1, 1 } }, { { 1, 1 }, { 1, 1 } }, { 8 , 4 } },
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV12, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV21, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++};
++
++static const struct stfcamss_format_info formats_st7110_isp_iti[] = {
++ // raw format
++ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++
++ // YUV420
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV12, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV21, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++
++ // YUV444
++ { MEDIA_BUS_FMT_YUV8_1X24, V4L2_PIX_FMT_NV24, 1,
++ { { 1, 1 } }, { { 1, 3 } }, { 8 } },
++ { MEDIA_BUS_FMT_VUY8_1X24, V4L2_PIX_FMT_NV42, 1,
++ { { 1, 1 } }, { { 1, 3 } }, { 8 } },
++};
++
++static int video_find_format(u32 code, u32 pixelformat,
++ const struct stfcamss_format_info *formats,
++ unsigned int nformats)
++{
++ int i;
++
++ for (i = 0; i < nformats; i++) {
++ if (formats[i].code == code &&
++ formats[i].pixelformat == pixelformat)
++ return i;
++ }
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].code == code)
++ return i;
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].pixelformat == pixelformat)
++ return i;
++
++ return -EINVAL;
++}
++
++static int __video_try_fmt(struct stfcamss_video *video,
++ struct v4l2_format *f, int is_mp)
++{
++ struct v4l2_pix_format *pix;
++ struct v4l2_pix_format_mplane *pix_mp;
++ const struct stfcamss_format_info *fi;
++ u32 width, height;
++ u32 bpl;
++ int i, j;
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ pix = &f->fmt.pix;
++ pix_mp = &f->fmt.pix_mp;
++
++ if (is_mp) {
++ for (i = 0; i < video->nformats; i++)
++ if (pix_mp->pixelformat
++ == video->formats[i].pixelformat)
++ break;
++
++ if (i == video->nformats)
++ i = 0; /* default format */
++
++ fi = &video->formats[i];
++ width = pix_mp->width;
++ height = pix_mp->height;
++
++ memset(pix_mp, 0, sizeof(*pix_mp));
++
++ pix_mp->pixelformat = fi->pixelformat;
++ pix_mp->width = clamp_t(u32, width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ pix_mp->height = clamp_t(u32, height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++ pix_mp->num_planes = fi->planes;
++ for (j = 0; j < pix_mp->num_planes; j++) {
++ bpl = pix_mp->width / fi->hsub[j].numerator *
++ fi->hsub[j].denominator * fi->bpp[j] / 8;
++ bpl = ALIGN(bpl, video->bpl_alignment);
++ pix_mp->plane_fmt[j].bytesperline = bpl;
++ pix_mp->plane_fmt[j].sizeimage = pix_mp->height /
++ fi->vsub[j].numerator
++ * fi->vsub[j].denominator * bpl;
++ }
++
++ pix_mp->field = V4L2_FIELD_NONE;
++ pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
++ pix_mp->flags = 0;
++ pix_mp->ycbcr_enc =
++ V4L2_MAP_YCBCR_ENC_DEFAULT(pix_mp->colorspace);
++ pix_mp->quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ pix_mp->colorspace, pix_mp->ycbcr_enc);
++ pix_mp->xfer_func =
++ V4L2_MAP_XFER_FUNC_DEFAULT(pix_mp->colorspace);
++
++ st_info(ST_VIDEO, "w, h = %d, %d, bpp = %d\n", pix_mp->width,
++ pix_mp->height, fi->bpp[0]);
++ st_info(ST_VIDEO, "i = %d, p = %d, s = 0x%x\n", i,
++ pix_mp->num_planes, pix_mp->plane_fmt[0].sizeimage);
++
++ } else {
++ for (i = 0; i < video->nformats; i++)
++ if (pix->pixelformat == video->formats[i].pixelformat)
++ break;
++
++ if (i == video->nformats)
++ i = 0; /* default format */
++
++ fi = &video->formats[i];
++ width = pix->width;
++ height = pix->height;
++
++ memset(pix, 0, sizeof(*pix));
++
++ pix->pixelformat = fi->pixelformat;
++ pix->width = clamp_t(u32, width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ pix->height = clamp_t(u32, height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++ bpl = pix->width / fi->hsub[0].numerator *
++ fi->hsub[0].denominator * fi->bpp[0] / 8;
++ bpl = ALIGN(bpl, video->bpl_alignment);
++ pix->bytesperline = bpl;
++ pix->sizeimage = pix->height /
++ fi->vsub[0].numerator
++ * fi->vsub[0].denominator * bpl;
++
++ pix->field = V4L2_FIELD_NONE;
++ pix->colorspace = V4L2_COLORSPACE_SRGB;
++ pix->flags = 0;
++ pix->ycbcr_enc =
++ V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
++ pix->quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ pix->colorspace, pix->ycbcr_enc);
++ pix->xfer_func =
++ V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
++
++ st_info(ST_VIDEO, "w, h = %d, %d, bpp = %d\n", pix->width,
++ pix->height, fi->bpp[0]);
++ st_info(ST_VIDEO, "i = %d, s = 0x%x\n", i, pix->sizeimage);
++ }
++ return 0;
++}
++
++static int stf_video_init_format(struct stfcamss_video *video, int is_mp)
++{
++ int ret;
++ struct v4l2_format format = {
++ .type = video->type,
++ .fmt.pix = {
++ .width = 1920,
++ .height = 1080,
++ .pixelformat = V4L2_PIX_FMT_RGB565,
++ },
++ };
++
++ ret = __video_try_fmt(video, &format, is_mp);
++
++ if (ret < 0)
++ return ret;
++
++ video->active_fmt = format;
++
++ return 0;
++}
++
++static int video_queue_setup(struct vb2_queue *q,
++ unsigned int *num_buffers, unsigned int *num_planes,
++ unsigned int sizes[], struct device *alloc_devs[])
++{
++ struct stfcamss_video *video = vb2_get_drv_priv(q);
++ const struct v4l2_pix_format *format =
++ &video->active_fmt.fmt.pix;
++ const struct v4l2_pix_format_mplane *format_mp =
++ &video->active_fmt.fmt.pix_mp;
++ unsigned int i;
++
++ st_debug(ST_VIDEO, "%s, planes = %d\n", __func__, *num_planes);
++
++ if (video->is_mp) {
++ if (*num_planes) {
++ if (*num_planes != format_mp->num_planes)
++ return -EINVAL;
++
++ for (i = 0; i < *num_planes; i++)
++ if (sizes[i] <
++ format_mp->plane_fmt[i].sizeimage)
++ return -EINVAL;
++
++ return 0;
++ }
++
++ *num_planes = format_mp->num_planes;
++
++ for (i = 0; i < *num_planes; i++)
++ sizes[i] = format_mp->plane_fmt[i].sizeimage;
++ } else {
++ if (*num_planes) {
++ if (*num_planes != 1)
++ return -EINVAL;
++
++ if (sizes[0] < format->sizeimage)
++ return -EINVAL;
++ }
++
++ *num_planes = 1;
++ sizes[0] = format->sizeimage;
++ if (!sizes[0])
++ st_err(ST_VIDEO, "%s: error size is zero!!!\n", __func__);
++ }
++ if ((stf_vin_map_isp_pad(video->id, STF_ISP_PAD_SRC)
++ == STF_ISP_PAD_SRC_SCD_Y) &&
++ sizes[0] < ISP_SCD_Y_BUFFER_SIZE) {
++ sizes[0] = ISP_SCD_Y_BUFFER_SIZE;
++ }
++
++ st_info(ST_VIDEO, "%s, planes = %d, size = %d\n",
++ __func__, *num_planes, sizes[0]);
++ return 0;
++}
++
++static int video_buf_init(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
++ struct stfcamss_buffer *buffer =
++ container_of(vbuf, struct stfcamss_buffer, vb);
++ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
++ const struct v4l2_pix_format_mplane *fmt_mp =
++ &video->active_fmt.fmt.pix_mp;
++ //struct sg_table *sgt;
++ dma_addr_t *paddr;
++ unsigned int i;
++
++ buffer->sizeimage = 0;
++
++ if (video->is_mp) {
++ for (i = 0; i < fmt_mp->num_planes; i++) {
++ paddr = vb2_plane_cookie(vb, i);
++ buffer->addr[i] = *paddr;
++ buffer->sizeimage += vb2_plane_size(vb, i);
++ }
++
++ if (fmt_mp->num_planes == 1
++ && (fmt_mp->pixelformat == V4L2_PIX_FMT_NV12
++ || fmt_mp->pixelformat == V4L2_PIX_FMT_NV21
++ || fmt_mp->pixelformat == V4L2_PIX_FMT_NV16
++ || fmt_mp->pixelformat == V4L2_PIX_FMT_NV61))
++ buffer->addr[1] = buffer->addr[0] +
++ fmt_mp->plane_fmt[0].bytesperline *
++ fmt_mp->height;
++ } else {
++ paddr = vb2_plane_cookie(vb, 0);
++ buffer->sizeimage = vb2_plane_size(vb, 0);
++ buffer->addr[0] = *paddr;
++ if (fmt->pixelformat == V4L2_PIX_FMT_NV12
++ || fmt->pixelformat == V4L2_PIX_FMT_NV21
++ || fmt->pixelformat == V4L2_PIX_FMT_NV16
++ || fmt->pixelformat == V4L2_PIX_FMT_NV61)
++ buffer->addr[1] = buffer->addr[0] +
++ fmt->bytesperline *
++ fmt->height;
++ }
++
++ if (stf_vin_map_isp_pad(video->id, STF_ISP_PAD_SRC)
++ == STF_ISP_PAD_SRC_SCD_Y) {
++ buffer->addr[1] = buffer->addr[0] + ISP_YHIST_BUFFER_SIZE;
++ buffer->vaddr_sc = vb2_plane_vaddr(vb, 0);
++ }
++
++ return 0;
++}
++
++static int video_buf_prepare(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
++ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
++ const struct v4l2_pix_format_mplane *fmt_mp =
++ &video->active_fmt.fmt.pix_mp;
++ unsigned int i;
++
++ if (video->is_mp) {
++ for (i = 0; i < fmt_mp->num_planes; i++) {
++ if (fmt_mp->plane_fmt[i].sizeimage
++ > vb2_plane_size(vb, i))
++ return -EINVAL;
++
++ vb2_set_plane_payload(vb, i,
++ fmt_mp->plane_fmt[i].sizeimage);
++ }
++ } else {
++ if (fmt->sizeimage > vb2_plane_size(vb, 0)) {
++ st_err(ST_VIDEO, "sizeimage = %d, plane size = %d\n",
++ fmt->sizeimage, (unsigned int)vb2_plane_size(vb, 0));
++ return -EINVAL;
++ }
++ vb2_set_plane_payload(vb, 0, fmt->sizeimage);
++ }
++
++ vbuf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static void video_buf_queue(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
++ struct stfcamss_buffer *buffer =
++ container_of(vbuf, struct stfcamss_buffer, vb);
++
++ video->ops->queue_buffer(video, buffer);
++}
++
++static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus,
++ struct v4l2_pix_format_mplane *pix,
++ const struct stfcamss_format_info *f,
++ unsigned int alignment)
++{
++ unsigned int i;
++ u32 bytesperline;
++
++ memset(pix, 0, sizeof(*pix));
++ v4l2_fill_pix_format_mplane(pix, mbus);
++ pix->pixelformat = f->pixelformat;
++ pix->num_planes = f->planes;
++ for (i = 0; i < pix->num_planes; i++) {
++ bytesperline = pix->width / f->hsub[i].numerator *
++ f->hsub[i].denominator * f->bpp[i] / 8;
++ bytesperline = ALIGN(bytesperline, alignment);
++ pix->plane_fmt[i].bytesperline = bytesperline;
++ pix->plane_fmt[i].sizeimage = pix->height /
++ f->vsub[i].numerator * f->vsub[i].denominator *
++ bytesperline;
++ }
++
++ return 0;
++}
++
++static int video_mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
++ struct v4l2_pix_format *pix,
++ const struct stfcamss_format_info *f,
++ unsigned int alignment)
++{
++ u32 bytesperline;
++
++ memset(pix, 0, sizeof(*pix));
++ v4l2_fill_pix_format(pix, mbus);
++ pix->pixelformat = f->pixelformat;
++ bytesperline = pix->width / f->hsub[0].numerator *
++ f->hsub[0].denominator * f->bpp[0] / 8;
++ bytesperline = ALIGN(bytesperline, alignment);
++ pix->bytesperline = bytesperline;
++ pix->sizeimage = pix->height /
++ f->vsub[0].numerator * f->vsub[0].denominator *
++ bytesperline;
++ return 0;
++}
++
++static struct v4l2_subdev *video_remote_subdev(
++ struct stfcamss_video *video, u32 *pad)
++{
++ struct media_pad *remote;
++
++ remote = media_pad_remote_pad_first(&video->pad);
++
++ if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
++ return NULL;
++
++ if (pad)
++ *pad = remote->index;
++
++ return media_entity_to_v4l2_subdev(remote->entity);
++}
++
++static int video_get_subdev_format(struct stfcamss_video *video,
++ struct v4l2_format *format)
++{
++ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
++ struct v4l2_pix_format_mplane *pix_mp =
++ &video->active_fmt.fmt.pix_mp;
++ struct v4l2_subdev_format fmt;
++ struct v4l2_subdev *subdev;
++ u32 pixelformat;
++ u32 pad;
++ int ret;
++
++ subdev = video_remote_subdev(video, &pad);
++ if (subdev == NULL)
++ return -EPIPE;
++
++ fmt.pad = pad;
++ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
++ if (ret)
++ return ret;
++
++ if (video->is_mp)
++ pixelformat = pix_mp->pixelformat;
++ else
++ pixelformat = pix->pixelformat;
++ ret = video_find_format(fmt.format.code, pixelformat,
++ video->formats, video->nformats);
++ if (ret < 0)
++ return ret;
++
++ format->type = video->type;
++
++ if (video->is_mp)
++ return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp,
++ &video->formats[ret], video->bpl_alignment);
++ else
++ return video_mbus_to_pix(&fmt.format, &format->fmt.pix,
++ &video->formats[ret], video->bpl_alignment);
++}
++
++static int video_check_format(struct stfcamss_video *video)
++{
++ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
++ struct v4l2_pix_format_mplane *pix_mp =
++ &video->active_fmt.fmt.pix_mp;
++ struct v4l2_format format;
++ struct v4l2_pix_format *sd_pix = &format.fmt.pix;
++ struct v4l2_pix_format_mplane *sd_pix_mp = &format.fmt.pix_mp;
++ int ret;
++
++ if (video->is_mp) {
++ sd_pix_mp->pixelformat = pix_mp->pixelformat;
++ ret = video_get_subdev_format(video, &format);
++ if (ret < 0)
++ return ret;
++
++ if (pix_mp->pixelformat != sd_pix_mp->pixelformat ||
++ pix_mp->height > sd_pix_mp->height ||
++ pix_mp->width > sd_pix_mp->width ||
++ pix_mp->num_planes != sd_pix_mp->num_planes ||
++ pix_mp->field != format.fmt.pix_mp.field) {
++ st_err(ST_VIDEO,
++ "%s, not match:\n"
++ "0x%x 0x%x\n0x%x 0x%x\n0x%x 0x%x\n",
++ __func__,
++ pix_mp->pixelformat, sd_pix_mp->pixelformat,
++ pix_mp->height, sd_pix_mp->height,
++ pix_mp->field, format.fmt.pix_mp.field);
++ return -EPIPE;
++ }
++
++ } else {
++ sd_pix->pixelformat = pix->pixelformat;
++ ret = video_get_subdev_format(video, &format);
++ if (ret < 0)
++ return ret;
++
++ if (pix->pixelformat != sd_pix->pixelformat ||
++ pix->height > sd_pix->height ||
++ pix->width > sd_pix->width ||
++ pix->field != format.fmt.pix.field) {
++ st_err(ST_VIDEO,
++ "%s, not match:\n"
++ "0x%x 0x%x\n0x%x 0x%x\n0x%x 0x%x\n",
++ __func__,
++ pix->pixelformat, sd_pix->pixelformat,
++ pix->height, sd_pix->height,
++ pix->field, format.fmt.pix.field);
++ return -EPIPE;
++ }
++ }
++ return 0;
++}
++
++static int video_start_streaming(struct vb2_queue *q, unsigned int count)
++{
++ struct stfcamss_video *video = vb2_get_drv_priv(q);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++ int ret;
++
++ ret = video_device_pipeline_start(vdev, &video->stfcamss->pipe);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to video_device_pipeline_start: %d\n", ret);
++ return ret;
++ }
++
++ ret = video_check_format(video);
++ if (ret < 0)
++ goto error;
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, video, s_stream, 1);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ goto error;
++ }
++ return 0;
++
++error:
++ video_device_pipeline_stop(vdev);
++ video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
++ return ret;
++}
++
++static void video_stop_streaming(struct vb2_queue *q)
++{
++ struct stfcamss_video *video = vb2_get_drv_priv(q);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ v4l2_subdev_call(subdev, video, s_stream, 0);
++ }
++
++ video_device_pipeline_stop(vdev);
++ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
++}
++
++static const struct vb2_ops stf_video_vb2_q_ops = {
++ .queue_setup = video_queue_setup,
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++ .buf_init = video_buf_init,
++ .buf_prepare = video_buf_prepare,
++ .buf_queue = video_buf_queue,
++ .start_streaming = video_start_streaming,
++ .stop_streaming = video_stop_streaming,
++};
++
++/* -----------------------------------------------------
++ * V4L2 ioctls
++ */
++
++static int getcrop_pad_id(int video_id)
++{
++ return stf_vin_map_isp_pad(video_id, STF_ISP_PAD_SRC);
++}
++
++static int video_querycap(struct file *file, void *fh,
++ struct v4l2_capability *cap)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ strscpy(cap->driver, "stf camss", sizeof(cap->driver));
++ strscpy(cap->card, "Starfive Camera Subsystem", sizeof(cap->card));
++ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
++ dev_name(video->stfcamss->dev));
++ return 0;
++}
++
++static int video_get_unique_pixelformat_by_index(struct stfcamss_video *video,
++ int ndx)
++{
++ int i, j, k;
++
++ /* find index "i" of "k"th unique pixelformat in formats array */
++ k = -1;
++ for (i = 0; i < video->nformats; i++) {
++ for (j = 0; j < i; j++) {
++ if (video->formats[i].pixelformat ==
++ video->formats[j].pixelformat)
++ break;
++ }
++
++ if (j == i)
++ k++;
++
++ if (k == ndx)
++ return i;
++ }
++
++ return -EINVAL;
++}
++
++static int video_get_pixelformat_by_mbus_code(struct stfcamss_video *video,
++ u32 mcode)
++{
++ int i;
++
++ for (i = 0; i < video->nformats; i++) {
++ if (video->formats[i].code == mcode)
++ return i;
++ }
++
++ return -EINVAL;
++}
++
++static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ int i;
++
++ st_debug(ST_VIDEO, "%s:\n0x%x 0x%x\n 0x%x, 0x%x\n0x%x\n",
++ __func__,
++ f->type, video->type,
++ f->index, video->nformats,
++ f->mbus_code);
++
++ if (f->type != video->type)
++ return -EINVAL;
++ if (f->index >= video->nformats)
++ return -EINVAL;
++
++ if (f->mbus_code) {
++ /* Each entry in formats[] table has unique mbus_code */
++ if (f->index > 0)
++ return -EINVAL;
++
++ i = video_get_pixelformat_by_mbus_code(video, f->mbus_code);
++ } else {
++ i = video_get_unique_pixelformat_by_index(video, f->index);
++ }
++
++ if (i < 0)
++ return -EINVAL;
++
++ f->pixelformat = video->formats[i].pixelformat;
++
++ return 0;
++}
++
++static int video_enum_framesizes(struct file *file, void *fh,
++ struct v4l2_frmsizeenum *fsize)
++{
++ struct v4l2_subdev_frame_size_enum fse = {0};
++ struct v4l2_subdev_mbus_code_enum code = {0};
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity = &vdev->entity;
++ struct media_entity *sensor;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ bool support_selection = false;
++ int i;
++ int ret;
++
++ for (i = 0; i < video->nformats; i++) {
++ if (video->formats[i].pixelformat == fsize->pixel_format)
++ break;
++ }
++
++ if (i == video->nformats)
++ return -EINVAL;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ if (subdev->ops->pad->set_selection) {
++ support_selection = true;
++ break;
++ }
++ }
++
++ if (support_selection) {
++ if (fsize->index)
++ return -EINVAL;
++ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
++ fsize->stepwise.min_width = STFCAMSS_FRAME_MIN_WIDTH;
++ fsize->stepwise.max_width = STFCAMSS_FRAME_MAX_WIDTH;
++ fsize->stepwise.min_height = STFCAMSS_FRAME_MIN_HEIGHT;
++ fsize->stepwise.max_height = STFCAMSS_FRAME_MAX_HEIGHT;
++ fsize->stepwise.step_width = 1;
++ fsize->stepwise.step_height = 1;
++ } else {
++ entity = &vdev->entity;
++ sensor = stfcamss_find_sensor(entity);
++ if (!sensor)
++ return -ENOTTY;
++
++ subdev = media_entity_to_v4l2_subdev(sensor);
++ code.index = 0;
++ code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code);
++ if (ret < 0)
++ return -EINVAL;
++ fse.index = fsize->index;
++ fse.code = code.code;
++ fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ ret = v4l2_subdev_call(subdev, pad, enum_frame_size, NULL, &fse);
++ if (ret < 0)
++ return -EINVAL;
++ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
++ fsize->discrete.width = fse.min_width;
++ fsize->discrete.height = fse.min_height;
++ }
++
++ return 0;
++}
++
++static int video_enum_frameintervals(struct file *file, void *fh,
++ struct v4l2_frmivalenum *fival)
++{
++ int ret = 0;
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity = &vdev->entity;
++ struct media_entity *sensor;
++ struct v4l2_subdev *subdev;
++ struct v4l2_subdev_mbus_code_enum code = {0};
++ struct v4l2_subdev_frame_interval_enum fie = {0};
++
++ sensor = stfcamss_find_sensor(entity);
++ if (!sensor)
++ return -ENOTTY;
++ fie.index = fival->index;
++ fie.width = fival->width;
++ fie.height = fival->height;
++ fie.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ subdev = media_entity_to_v4l2_subdev(sensor);
++
++ code.index = 0;
++ code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++
++ /* Don't care about the code, just find by pixelformat */
++ ret = video_find_format(0, fival->pixel_format,
++ video->formats, video->nformats);
++ if (ret < 0)
++ return -EINVAL;
++
++ ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code);
++ if (ret < 0)
++ return -EINVAL;
++
++ fie.code = code.code;
++ ret = v4l2_subdev_call(subdev, pad, enum_frame_interval, NULL, &fie);
++ if (ret < 0)
++ return ret;
++
++ fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
++ fival->discrete = fie.interval;
++
++ return 0;
++}
++
++static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ st_debug(ST_VIDEO, "%s, active_fmt.type = 0x%x,0x%x\n",
++ __func__, video->active_fmt.type,
++ video->active_fmt.fmt.pix.pixelformat);
++ *f = video->active_fmt;
++ return 0;
++}
++
++static int video_g_fmt_mp(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ st_debug(ST_VIDEO, "%s, active_fmt.type = 0x%x\n",
++ __func__, video->active_fmt.type);
++ *f = video->active_fmt;
++ return 0;
++}
++
++static int video_entity_s_fmt(struct stfcamss_video *video,
++ struct media_entity *entity,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_mbus_framefmt *mf = &fmt->format;
++ struct v4l2_subdev_format fmt_src = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ u32 width, height, code;
++ int ret, index = 0;
++
++ code = mf->code;
++ width = mf->width;
++ height = mf->height;
++ subdev = media_entity_to_v4l2_subdev(entity);
++ while (1) {
++ if (index >= entity->num_pads)
++ break;
++ pad = &entity->pads[index];
++ pad = media_pad_remote_pad_first(pad);
++ if (pad && is_media_entity_v4l2_subdev(pad->entity)) {
++ fmt->pad = index;
++ ret = v4l2_subdev_call(subdev, pad, set_fmt, state, fmt);
++ if (mf->code != code ||
++ mf->width != width || mf->height != height) {
++ st_warn(ST_VIDEO,
++ "\"%s\":%d pad fmt has been"
++ " changed to 0x%x %ux%u\n",
++ subdev->name, fmt->pad, mf->code,
++ mf->width, mf->height);
++ }
++ if (index) {
++ fmt_src.pad = index;
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt_src);
++ if (ret)
++ return ret;
++
++ fmt->format.code = fmt_src.format.code;
++ ret = video_entity_s_fmt(video, pad->entity, state, fmt);
++ }
++ }
++
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ break;
++ index++;
++ }
++ return ret;
++}
++
++static int video_pipeline_s_fmt(struct stfcamss_video *video,
++ struct v4l2_subdev_state *state,
++ struct v4l2_format *f)
++{
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity = &vdev->entity;
++ struct v4l2_subdev *subdev;
++ int ret, index;
++ struct v4l2_subdev_format fmt = {
++ .pad = 0,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .reserved = {getcrop_pad_id(video->id)}
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
++ struct media_entity *sensor;
++ u32 width, height;
++ struct media_pad *pad;
++
++ /* pix to mbus format */
++ if (video->is_mp) {
++ index = video_find_format(mf->code,
++ pix_mp->pixelformat,
++ video->formats, video->nformats);
++ if (index < 0)
++ return index;
++ v4l2_fill_mbus_format_mplane(mf, pix_mp);
++ mf->code = video->formats[index].code;
++ } else {
++ index = video_find_format(mf->code,
++ pix->pixelformat,
++ video->formats, video->nformats);
++ if (index < 0)
++ return index;
++ v4l2_fill_mbus_format(mf, pix, video->formats[index].code);
++ }
++
++ width = mf->width;
++ height = mf->height;
++
++ sensor = stfcamss_find_sensor(entity);
++ if (!sensor) {
++ st_err(ST_VIDEO, "Can't find sensor\n");
++ return -ENOTTY;
++ }
++
++ subdev = media_entity_to_v4l2_subdev(sensor);
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt);
++ if (ret)
++ return ret;
++
++ /*
++ * Starting from sensor subdevice, walk within
++ * pipeline and set format on each subdevice
++ */
++ pad = media_pad_remote_pad_first(&sensor->pads[0]);
++ ret = video_entity_s_fmt(video, pad->entity, state, &fmt);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ return ret;
++
++ index = video_find_format(mf->code,
++ video->formats[index].pixelformat,
++ video->formats, video->nformats);
++ st_debug(ST_VIDEO, "%s, code=%x, index=%d\n",
++ __func__, mf->code, index);
++
++ if (index < 0)
++ return index;
++
++ if (video->is_mp)
++ video_mbus_to_pix_mp(mf, pix_mp,
++ &video->formats[index], video->bpl_alignment);
++ else
++ video_mbus_to_pix(mf, pix,
++ &video->formats[index], video->bpl_alignment);
++
++ ret = __video_try_fmt(video, f, video->is_mp);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x, v4l2fmt=%x\n",
++ __func__, f->type, f->fmt.pix.pixelformat);
++
++ if (vb2_is_busy(&video->vb2_q))
++ return -EBUSY;
++
++ ret = __video_try_fmt(video, f, false);
++ if (ret < 0)
++ return ret;
++
++ ret = video_pipeline_s_fmt(video, NULL, f);
++
++ st_debug(ST_VIDEO, "%s, pixelformat=0x%x, ret=%d\n",
++ __func__, f->fmt.pix.pixelformat, ret);
++ if (ret < 0)
++ return ret;
++
++ video->active_fmt = *f;
++
++ return 0;
++}
++
++static int video_s_fmt_mp(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ if (vb2_is_busy(&video->vb2_q))
++ return -EBUSY;
++
++ ret = __video_try_fmt(video, f, true);
++ if (ret < 0)
++ return ret;
++
++ ret = video_pipeline_s_fmt(video, NULL, f);
++ if (ret < 0)
++ return ret;
++
++ video->active_fmt = *f;
++
++ return 0;
++}
++
++static int video_try_fmt(struct file *file,
++ void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ return __video_try_fmt(video, f, false);
++}
++
++static int video_try_fmt_mp(struct file *file,
++ void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ return __video_try_fmt(video, f, true);
++}
++
++static int video_enum_input(struct file *file, void *fh,
++ struct v4l2_input *input)
++{
++ if (input->index > 0)
++ return -EINVAL;
++
++ strscpy(input->name, "camera", sizeof(input->name));
++ input->type = V4L2_INPUT_TYPE_CAMERA;
++
++ return 0;
++}
++
++static int video_g_input(struct file *file, void *fh, unsigned int *input)
++{
++ *input = 0;
++
++ return 0;
++}
++
++static int video_s_input(struct file *file, void *fh, unsigned int input)
++{
++ return input == 0 ? 0 : -EINVAL;
++}
++
++static int video_g_parm(struct file *file, void *priv,
++ struct v4l2_streamparm *p)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ int ret, is_support = 0;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_g_parm_cap(vdev, subdev, p);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ break;
++ if (!ret)
++ is_support = 1;
++ }
++
++ return is_support ? 0 : ret;
++}
++
++static int video_s_parm(struct file *file, void *priv,
++ struct v4l2_streamparm *p)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_streamparm tmp_p;
++ int ret, is_support = 0;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ tmp_p = *p;
++ ret = v4l2_s_parm_cap(vdev, subdev, &tmp_p);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ break;
++ if (!ret) {
++ is_support = 1;
++ *p = tmp_p;
++ }
++ }
++
++ return is_support ? 0 : ret;
++}
++
++/* Crop ioctls */
++int video_g_pixelaspect(struct file *file, void *fh,
++ int buf_type, struct v4l2_fract *aspect)
++{
++ return 0;
++}
++
++int video_g_selection(struct file *file, void *fh,
++ struct v4l2_selection *s)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_subdev_selection sel = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = getcrop_pad_id(video->id),
++ .target = s->target,
++ .r = s->r,
++ .flags = s->flags,
++ };
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, target = 0x%x, 0x%x\n",
++ __func__, sel.target, s->target);
++ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
++ && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
++ return -EINVAL;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sel);
++ if (!ret) {
++ s->r = sel.r;
++ s->flags = sel.flags;
++ break;
++ }
++ if (ret != -ENOIOCTLCMD)
++ break;
++ }
++
++ return ret;
++}
++
++int video_s_selection(struct file *file, void *fh,
++ struct v4l2_selection *s)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_subdev_selection sel = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = getcrop_pad_id(video->id),
++ .target = s->target,
++ .r = s->r,
++ .flags = s->flags,
++ };
++ struct v4l2_pix_format *format = &video->active_fmt.fmt.pix;
++ struct v4l2_pix_format_mplane *format_mp =
++ &video->active_fmt.fmt.pix_mp;
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, target = 0x%x, 0x%x\n",
++ __func__, sel.target, s->target);
++ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
++ && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
++ return -EINVAL;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sel);
++ if (!ret) {
++ s->r = sel.r;
++ s->flags = sel.flags;
++ format->width = s->r.width;
++ format->height = s->r.height;
++ format_mp->width = s->r.width;
++ format_mp->height = s->r.height;
++ ret = __video_try_fmt(video, &video->active_fmt,
++ video->is_mp);
++ if (ret < 0)
++ return ret;
++ break;
++ }
++ if (ret != -ENOIOCTLCMD)
++ break;
++ }
++
++ st_debug(ST_VIDEO, "ret = 0x%x, -EINVAL = 0x%x\n", ret, -EINVAL);
++
++ return ret;
++}
++
++static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = {
++ .vidioc_querycap = video_querycap,
++ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
++ .vidioc_enum_framesizes = video_enum_framesizes,
++ .vidioc_enum_frameintervals = video_enum_frameintervals,
++ .vidioc_g_fmt_vid_cap = video_g_fmt,
++ .vidioc_s_fmt_vid_cap = video_s_fmt,
++ .vidioc_try_fmt_vid_cap = video_try_fmt,
++ .vidioc_reqbufs = vb2_ioctl_reqbufs,
++ .vidioc_querybuf = vb2_ioctl_querybuf,
++ .vidioc_qbuf = vb2_ioctl_qbuf,
++ .vidioc_expbuf = vb2_ioctl_expbuf,
++ .vidioc_dqbuf = vb2_ioctl_dqbuf,
++ .vidioc_create_bufs = vb2_ioctl_create_bufs,
++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
++ .vidioc_enum_input = video_enum_input,
++ .vidioc_g_input = video_g_input,
++ .vidioc_s_input = video_s_input,
++ .vidioc_g_parm = video_g_parm,
++ .vidioc_s_parm = video_s_parm,
++ .vidioc_s_selection = video_s_selection,
++ .vidioc_g_selection = video_g_selection,
++};
++
++static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_mp = {
++ .vidioc_querycap = video_querycap,
++ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
++ .vidioc_enum_framesizes = video_enum_framesizes,
++ .vidioc_enum_frameintervals = video_enum_frameintervals,
++ .vidioc_g_fmt_vid_cap_mplane = video_g_fmt_mp,
++ .vidioc_s_fmt_vid_cap_mplane = video_s_fmt_mp,
++ .vidioc_try_fmt_vid_cap_mplane = video_try_fmt_mp,
++ .vidioc_reqbufs = vb2_ioctl_reqbufs,
++ .vidioc_querybuf = vb2_ioctl_querybuf,
++ .vidioc_qbuf = vb2_ioctl_qbuf,
++ .vidioc_expbuf = vb2_ioctl_expbuf,
++ .vidioc_dqbuf = vb2_ioctl_dqbuf,
++ .vidioc_create_bufs = vb2_ioctl_create_bufs,
++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
++ .vidioc_enum_input = video_enum_input,
++ .vidioc_g_input = video_g_input,
++ .vidioc_s_input = video_s_input,
++ .vidioc_g_parm = video_g_parm,
++ .vidioc_s_parm = video_s_parm,
++ .vidioc_s_selection = video_s_selection,
++ .vidioc_g_selection = video_g_selection,
++};
++
++static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_out = {
++ .vidioc_querycap = video_querycap,
++ .vidioc_enum_fmt_vid_out = video_enum_fmt,
++ .vidioc_enum_framesizes = video_enum_framesizes,
++ .vidioc_enum_frameintervals = video_enum_frameintervals,
++ .vidioc_g_fmt_vid_out = video_g_fmt,
++ .vidioc_s_fmt_vid_out = video_s_fmt,
++ .vidioc_try_fmt_vid_out = video_try_fmt,
++ .vidioc_reqbufs = vb2_ioctl_reqbufs,
++ .vidioc_querybuf = vb2_ioctl_querybuf,
++ .vidioc_qbuf = vb2_ioctl_qbuf,
++ .vidioc_expbuf = vb2_ioctl_expbuf,
++ .vidioc_dqbuf = vb2_ioctl_dqbuf,
++ .vidioc_create_bufs = vb2_ioctl_create_bufs,
++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
++};
++
++static int video_open(struct file *file)
++{
++ struct video_device *vdev = video_devdata(file);
++ struct stfcamss_video *video = video_drvdata(file);
++ struct v4l2_fh *vfh;
++ int ret;
++
++ mutex_lock(&video->lock);
++
++ vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
++ if (vfh == NULL) {
++ ret = -ENOMEM;
++ goto error_alloc;
++ }
++
++ v4l2_fh_init(vfh, vdev);
++ v4l2_fh_add(vfh);
++
++ file->private_data = vfh;
++
++ if (!video->pm_count) {
++ ret = v4l2_pipeline_pm_get(&vdev->entity);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to power up pipeline: %d\n", ret);
++ goto error_pm_use;
++ }
++ }
++
++ video->pm_count++;
++
++ mutex_unlock(&video->lock);
++
++ return 0;
++
++error_pm_use:
++ v4l2_fh_release(file);
++error_alloc:
++ mutex_unlock(&video->lock);
++ return ret;
++}
++
++static int video_release(struct file *file)
++{
++ struct video_device *vdev = video_devdata(file);
++ struct stfcamss_video *video = video_drvdata(file);
++
++ vb2_fop_release(file);
++
++ video->pm_count--;
++
++ if (!video->pm_count)
++ v4l2_pipeline_pm_put(&vdev->entity);
++
++ file->private_data = NULL;
++
++ return 0;
++}
++
++static const struct v4l2_file_operations stf_vid_fops = {
++ .owner = THIS_MODULE,
++ .unlocked_ioctl = video_ioctl2,
++ .open = video_open,
++ .release = video_release,
++ .poll = vb2_fop_poll,
++ .mmap = vb2_fop_mmap,
++ .read = vb2_fop_read,
++};
++
++static void stf_video_release(struct video_device *vdev)
++{
++ struct stfcamss_video *video = video_get_drvdata(vdev);
++
++ media_entity_cleanup(&vdev->entity);
++
++ mutex_destroy(&video->q_lock);
++ mutex_destroy(&video->lock);
++}
++
++int stf_video_register(struct stfcamss_video *video,
++ struct v4l2_device *v4l2_dev,
++ const char *name, int is_mp)
++{
++ struct video_device *vdev;
++ struct vb2_queue *q;
++ struct media_pad *pad = &video->pad;
++ int ret;
++ enum isp_pad_id isp_pad;
++
++ vdev = &video->vdev;
++
++ mutex_init(&video->q_lock);
++
++ q = &video->vb2_q;
++ q->drv_priv = video;
++ q->mem_ops = &vb2_dma_contig_memops;
++ q->ops = &stf_video_vb2_q_ops;
++ //q->type = is_mp ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
++ // V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ q->type = video->type;
++ q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ;
++ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ q->buf_struct_size = sizeof(struct stfcamss_buffer);
++ q->dev = video->stfcamss->dev;
++ q->lock = &video->q_lock;
++ q->min_buffers_needed = STFCAMSS_MIN_BUFFERS;
++ ret = vb2_queue_init(q);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to init vb2 queue: %d\n", ret);
++ goto err_vb2_init;
++ }
++
++ pad->flags = MEDIA_PAD_FL_SINK;
++ ret = media_entity_pads_init(&vdev->entity, 1, pad);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to init video entity: %d\n",
++ ret);
++ goto err_vb2_init;
++ }
++
++ mutex_init(&video->lock);
++
++ isp_pad = stf_vin_map_isp_pad(video->id, STF_ISP_PAD_SRC);
++ if (video->id == VIN_LINE_WR) {
++ video->formats = formats_pix_st7110_wr;
++ video->nformats = ARRAY_SIZE(formats_pix_st7110_wr);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
++ } else if (isp_pad == STF_ISP_PAD_SRC
++ || isp_pad == STF_ISP_PAD_SRC_SS0
++ || isp_pad == STF_ISP_PAD_SRC_SS1) {
++ video->formats = formats_pix_st7110_isp;
++ video->nformats = ARRAY_SIZE(formats_pix_st7110_isp);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
++ } else if (isp_pad == STF_ISP_PAD_SRC_ITIW
++ || isp_pad == STF_ISP_PAD_SRC_ITIR) {
++ video->formats = formats_st7110_isp_iti;
++ video->nformats = ARRAY_SIZE(formats_st7110_isp_iti);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
++ } else { // raw/scdump/yhist
++ video->formats = formats_raw_st7110_isp;
++ video->nformats = ARRAY_SIZE(formats_raw_st7110_isp);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_128;
++ }
++ video->is_mp = is_mp;
++
++ ret = stf_video_init_format(video, is_mp);
++ if (ret < 0) {
++ st_err(ST_VIDEO, "Failed to init format: %d\n", ret);
++ goto err_vid_init_format;
++ }
++
++ vdev->fops = &stf_vid_fops;
++ if (isp_pad == STF_ISP_PAD_SRC_ITIR) {
++ vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT;
++ vdev->vfl_dir = VFL_DIR_TX;
++ } else {
++ vdev->device_caps = is_mp ? V4L2_CAP_VIDEO_CAPTURE_MPLANE :
++ V4L2_CAP_VIDEO_CAPTURE;
++ vdev->vfl_dir = VFL_DIR_RX;
++ }
++ vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE | V4L2_CAP_IO_MC;
++ if (video->type == V4L2_CAP_VIDEO_OUTPUT)
++ vdev->ioctl_ops = &stf_vid_ioctl_ops_out;
++ else
++ vdev->ioctl_ops = is_mp ? &stf_vid_ioctl_ops_mp : &stf_vid_ioctl_ops;
++ vdev->release = stf_video_release;
++ vdev->v4l2_dev = v4l2_dev;
++ vdev->queue = &video->vb2_q;
++ vdev->lock = &video->lock;
++ //strlcpy(vdev->name, name, sizeof(vdev->name));
++ strscpy(vdev->name, name, sizeof(vdev->name));
++
++ ret = video_register_device(vdev, VFL_TYPE_VIDEO, video->id);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to register video device: %d\n",
++ ret);
++ goto err_vid_reg;
++ }
++
++ video_set_drvdata(vdev, video);
++ return 0;
++
++err_vid_reg:
++err_vid_init_format:
++ media_entity_cleanup(&vdev->entity);
++ mutex_destroy(&video->lock);
++err_vb2_init:
++ mutex_destroy(&video->q_lock);
++ return ret;
++}
++
++void stf_video_unregister(struct stfcamss_video *video)
++{
++ vb2_video_unregister_device(&video->vdev);
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.h
+@@ -0,0 +1,83 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_VIDEO_H
++#define STF_VIDEO_H
++
++#include <linux/mutex.h>
++#include <media/videobuf2-v4l2.h>
++#include <linux/videodev2.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-fh.h>
++#include <media/v4l2-ioctl.h>
++
++#define STFCAMSS_FRAME_MIN_WIDTH 64
++#define STFCAMSS_FRAME_MAX_WIDTH 1920
++#define STFCAMSS_FRAME_MIN_HEIGHT 64
++#define STFCAMSS_FRAME_MAX_HEIGHT 1080
++#define STFCAMSS_FRAME_WIDTH_ALIGN_8 8
++#define STFCAMSS_FRAME_WIDTH_ALIGN_128 128
++#define STFCAMSS_MIN_BUFFERS 2
++
++#define STFCAMSS_MAX_ENTITY_NAME_LEN 27
++
++struct stfcamss_buffer {
++ struct vb2_v4l2_buffer vb;
++ dma_addr_t addr[3];
++ void *vaddr_sc; /* Use for isp sc data */
++ struct list_head queue;
++ int sizeimage;
++};
++
++struct stfcamss_video;
++
++struct stfcamss_video_ops {
++ int (*queue_buffer)(struct stfcamss_video *vid,
++ struct stfcamss_buffer *buf);
++ int (*flush_buffers)(struct stfcamss_video *vid,
++ enum vb2_buffer_state state);
++};
++
++struct fract {
++ u8 numerator;
++ u8 denominator;
++};
++
++struct stfcamss_format_info {
++ u32 code;
++ u32 pixelformat;
++ u8 planes;
++ struct fract hsub[3];
++ struct fract vsub[3];
++ u8 bpp[3];
++};
++
++struct stfcamss_video {
++ struct stfcamss *stfcamss;
++ u8 id;
++ struct vb2_queue vb2_q;
++ struct video_device vdev;
++ struct media_pad pad;
++ struct media_pipeline pipe;
++ struct v4l2_format active_fmt;
++ enum v4l2_buf_type type;
++ const struct stfcamss_video_ops *ops;
++ struct mutex lock;
++ struct mutex q_lock;
++ unsigned int bpl_alignment;
++ const struct stfcamss_format_info *formats;
++ unsigned int nformats;
++ unsigned int is_mp;
++ unsigned int pm_count;
++};
++
++int stf_video_register(struct stfcamss_video *video,
++ struct v4l2_device *v4l2_dev, const char *name, int is_mp);
++
++void stf_video_unregister(struct stfcamss_video *video);
++
++#endif /* STF_VIDEO_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+@@ -0,0 +1,1515 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/pm_runtime.h>
++#include <media/v4l2-event.h>
++
++#include "stfcamss.h"
++
++#define vin_line_array(ptr_line) \
++ ((const struct vin_line (*)[]) &(ptr_line[-(ptr_line->id)]))
++
++#define line_to_vin2_dev(ptr_line) \
++ container_of(vin_line_array(ptr_line), struct stf_vin2_dev, line)
++
++#define VIN_FRAME_DROP_MAX_VAL 90
++#define VIN_FRAME_DROP_MIN_VAL 4
++#define VIN_FRAME_PER_SEC_MAX_VAL 90
++
++/* ISP ctrl need 1 sec to let frames become stable. */
++#define VIN_FRAME_DROP_SEC_FOR_ISP_CTRL 1
++
++
++// #define VIN_TWO_BUFFER
++
++static const struct vin2_format vin2_formats_st7110[] = {
++ { MEDIA_BUS_FMT_YUYV8_2X8, 16},
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, 16},
++ { MEDIA_BUS_FMT_SRGGB8_1X8, 8},
++ { MEDIA_BUS_FMT_SGRBG8_1X8, 8},
++ { MEDIA_BUS_FMT_SGBRG8_1X8, 8},
++ { MEDIA_BUS_FMT_SBGGR8_1X8, 8},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++ { MEDIA_BUS_FMT_YUV8_1X24, 8},
++ { MEDIA_BUS_FMT_AYUV8_1X32, 32},
++};
++
++static const struct vin2_format isp_formats_st7110_raw[] = {
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++};
++
++static const struct vin2_format isp_formats_st7110_uo[] = {
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++};
++
++static const struct vin2_format isp_formats_st7110_iti[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++ { MEDIA_BUS_FMT_YUV8_1X24, 8},
++};
++
++static const struct vin2_format_table vin2_formats_table[] = {
++ /* VIN_LINE_WR */
++ { vin2_formats_st7110, ARRAY_SIZE(vin2_formats_st7110) },
++ /* VIN_LINE_ISP */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) },
++ /* VIN_LINE_ISP_SS0 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) },
++ /* VIN_LINE_ISP_SS1 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) },
++ /* VIN_LINE_ISP_ITIW */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) },
++ /* VIN_LINE_ISP_ITIR */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) },
++ /* VIN_LINE_ISP_RAW */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) },
++ /* VIN_LINE_ISP_SCD_Y */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) },
++};
++
++static void vin_buffer_done(struct vin_line *line, struct vin_params *params);
++static void vin_change_buffer(struct vin_line *line);
++static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output);
++static void vin_output_init_addrs(struct vin_line *line);
++static void vin_init_outputs(struct vin_line *line);
++static struct v4l2_mbus_framefmt *
++__vin_get_format(struct vin_line *line,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which);
++
++static char *get_line_subdevname(int line_id)
++{
++ char *name = NULL;
++
++ switch (line_id) {
++ case VIN_LINE_WR:
++ name = "wr";
++ break;
++ case VIN_LINE_ISP:
++ name = "isp0";
++ break;
++ case VIN_LINE_ISP_SS0:
++ name = "isp0_ss0";
++ break;
++ case VIN_LINE_ISP_SS1:
++ name = "isp0_ss1";
++ break;
++ case VIN_LINE_ISP_ITIW:
++ name = "isp0_itiw";
++ break;
++ case VIN_LINE_ISP_ITIR:
++ name = "isp0_itir";
++ break;
++ case VIN_LINE_ISP_RAW:
++ name = "isp0_raw";
++ break;
++ case VIN_LINE_ISP_SCD_Y:
++ name = "isp0_scd_y";
++ break;
++ default:
++ name = "unknow";
++ break;
++ }
++ return name;
++}
++
++static enum isp_line_id stf_vin_map_isp_line(enum vin_line_id line)
++{
++ enum isp_line_id line_id;
++
++ if ((line > VIN_LINE_WR) && (line < VIN_LINE_MAX)) {
++ line_id = line % STF_ISP_LINE_MAX;
++ if (line_id == 0)
++ line_id = STF_ISP_LINE_SRC_SCD_Y;
++ } else
++ line_id = STF_ISP_LINE_INVALID;
++
++ return line_id;
++}
++
++enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line, enum isp_pad_id def)
++{
++ enum isp_pad_id pad_id;
++
++ if (line == VIN_LINE_WR)
++ pad_id = STF_ISP_PAD_SINK;
++ else if ((line > VIN_LINE_WR) && (line < VIN_LINE_MAX))
++ pad_id = stf_vin_map_isp_line(line);
++ else
++ pad_id = def;
++
++ return pad_id;
++}
++
++int stf_vin_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_vin_dev *vin;
++ struct device *dev = stfcamss->dev;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ int i, ret = 0;
++
++ vin_dev->stfcamss = stfcamss;
++ vin_dev->hw_ops = &vin_ops;
++ vin_dev->hw_ops->isr_buffer_done = vin_buffer_done;
++ vin_dev->hw_ops->isr_change_buffer = vin_change_buffer;
++
++ vin = stfcamss->vin;
++ atomic_set(&vin_dev->ref_count, 0);
++
++ ret = devm_request_irq(dev,
++ vin->irq, vin_dev->hw_ops->vin_wr_irq_handler,
++ 0, "vin_axiwr_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request irq\n");
++ goto out;
++ }
++
++ ret = devm_request_irq(dev,
++ vin->isp_irq, vin_dev->hw_ops->vin_isp_irq_handler,
++ 0, "vin_isp_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp irq\n");
++ goto out;
++ }
++
++ st_info(ST_CAMSS, "%s, %d!\n", __func__, __LINE__);
++#ifdef ISP_USE_CSI_AND_SC_DONE_INTERRUPT
++ ret = devm_request_irq(dev,
++ vin->isp_csi_irq, vin_dev->hw_ops->vin_isp_csi_irq_handler,
++ 0, "vin_isp_csi_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp raw irq\n");
++ goto out;
++ }
++
++ ret = devm_request_irq(dev,
++ vin->isp_scd_irq, vin_dev->hw_ops->vin_isp_scd_irq_handler,
++ 0, "vin_isp_scd_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp scd irq\n");
++ goto out;
++ }
++#endif
++
++ ret = devm_request_irq(dev,
++ vin->isp_irq_csiline, vin_dev->hw_ops->vin_isp_irq_csiline_handler,
++ 0, "vin_isp_irq_csiline", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp irq csiline\n");
++ goto out;
++ }
++
++ mutex_init(&vin_dev->power_lock);
++ vin_dev->power_count = 0;
++
++ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++) {
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[i];
++
++ mutex_init(&dummy_buffer->stream_lock);
++ dummy_buffer->nums = i == 0 ? VIN_DUMMY_BUFFER_NUMS : ISP_DUMMY_BUFFER_NUMS;
++ dummy_buffer->stream_count = 0;
++ dummy_buffer->buffer = devm_kzalloc(dev,
++ dummy_buffer->nums * sizeof(struct vin_dummy_buffer), GFP_KERNEL);
++ atomic_set(&dummy_buffer->frame_skip, 0);
++ }
++
++ for (i = VIN_LINE_WR;
++ i < STF_ISP_LINE_MAX + 1; i++) {
++ struct vin_line *l = &vin_dev->line[i];
++ int is_mp;
++
++ is_mp = i == VIN_LINE_WR ? false : true;
++ is_mp = false;
++ if (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIR)
++ l->video_out.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++ else
++ l->video_out.type = is_mp ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
++ V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ l->video_out.stfcamss = stfcamss;
++ l->id = i;
++ l->sdev_type = VIN_DEV_TYPE;
++ l->formats = vin2_formats_table[i].fmts;
++ l->nformats = vin2_formats_table[i].nfmts;
++ spin_lock_init(&l->output_lock);
++
++ mutex_init(&l->stream_lock);
++ l->stream_count = 0;
++ mutex_init(&l->power_lock);
++ l->power_count = 0;
++ }
++
++ return 0;
++out:
++ return ret;
++}
++
++static int vin_set_power(struct v4l2_subdev *sd, int on)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ struct stfcamss *stfcamss = vin_dev->stfcamss;
++
++ mutex_lock(&line->power_lock);
++ if (on) {
++ if (line->power_count == 0)
++ vin_init_outputs(line);
++ line->power_count++;
++ } else {
++ if (line->power_count == 0) {
++ st_err(ST_VIN,
++ "line power off on power_count == 0\n");
++ goto exit_line;
++ }
++ line->power_count--;
++ }
++exit_line:
++ mutex_unlock(&line->power_lock);
++
++ mutex_lock(&vin_dev->power_lock);
++ if (on) {
++ if (vin_dev->power_count == 0) {
++ pm_runtime_get_sync(stfcamss->dev);
++ vin_dev->hw_ops->vin_clk_enable(vin_dev);
++ vin_dev->hw_ops->vin_config_set(vin_dev);
++ }
++ vin_dev->power_count++;
++ } else {
++ if (vin_dev->power_count == 0) {
++ st_err(ST_VIN,
++ "vin_dev power off on power_count == 0\n");
++ goto exit;
++ }
++ if (vin_dev->power_count == 1) {
++ vin_dev->hw_ops->vin_clk_disable(vin_dev);
++ pm_runtime_put_sync(stfcamss->dev);
++ }
++ vin_dev->power_count--;
++ }
++exit:
++
++ mutex_unlock(&vin_dev->power_lock);
++
++ return 0;
++}
++
++static unsigned int get_frame_skip(struct vin_line *line)
++{
++ unsigned int frame_skip = 0;
++ unsigned int isp_ctrl_skip_frames = 0;
++ struct media_entity *sensor;
++ struct v4l2_subdev_frame_interval fi;
++
++ sensor = stfcamss_find_sensor(&line->subdev.entity);
++ if (sensor) {
++ int fps = 0;
++ struct v4l2_subdev *subdev =
++ media_entity_to_v4l2_subdev(sensor);
++
++ if (subdev->ops->video->g_frame_interval) {
++ if (!subdev->ops->video->g_frame_interval(subdev, &fi))
++ fps = fi.interval.denominator;
++
++ if (fps > 0 && fps <= 90)
++ isp_ctrl_skip_frames = fps * VIN_FRAME_DROP_SEC_FOR_ISP_CTRL;
++ }
++ if (!fps)
++ st_debug(ST_VIN, "%s, Failed to get sensor fps !\n", __func__);
++
++ if (isp_ctrl_skip_frames <= VIN_FRAME_DROP_MIN_VAL)
++ isp_ctrl_skip_frames = VIN_FRAME_DROP_MIN_VAL;
++
++ v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip);
++
++ frame_skip += isp_ctrl_skip_frames;
++
++ if (frame_skip > VIN_FRAME_DROP_MAX_VAL)
++ frame_skip = VIN_FRAME_DROP_MAX_VAL;
++ st_debug(ST_VIN, "%s, frame_skip %d\n", __func__, frame_skip);
++ }
++
++ return frame_skip;
++}
++
++static void vin_buf_l2cache_flush(struct vin_output *output)
++{
++ struct stfcamss_buffer *buffer = NULL;
++
++ if (!list_empty(&output->pending_bufs)) {
++ list_for_each_entry(buffer, &output->pending_bufs, queue) {
++ sifive_l2_flush64_range(buffer->addr[0], buffer->sizeimage);
++ }
++ }
++}
++
++static int vin_enable_output(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ output->state = VIN_OUTPUT_IDLE;
++
++ vin_buf_l2cache_flush(output);
++
++ output->buf[0] = vin_buf_get_pending(output);
++#ifdef VIN_TWO_BUFFER
++ if (line->id == VIN_LINE_WR)
++ output->buf[1] = vin_buf_get_pending(output);
++#endif
++ if (!output->buf[0] && output->buf[1]) {
++ output->buf[0] = output->buf[1];
++ output->buf[1] = NULL;
++ }
++
++ if (output->buf[0])
++ output->state = VIN_OUTPUT_SINGLE;
++
++#ifdef VIN_TWO_BUFFER
++ if (output->buf[1] && line->id == VIN_LINE_WR)
++ output->state = VIN_OUTPUT_CONTINUOUS;
++#endif
++ output->sequence = 0;
++
++ vin_output_init_addrs(line);
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return 0;
++}
++
++static int vin_disable_output(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ output->state = VIN_OUTPUT_OFF;
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return 0;
++}
++
++static u32 line_to_dummy_module(struct vin_line *line)
++{
++ u32 dummy_module = 0;
++
++ switch (line->id) {
++ case VIN_LINE_WR:
++ dummy_module = STF_DUMMY_VIN;
++ break;
++ case VIN_LINE_ISP:
++ case VIN_LINE_ISP_SS0:
++ case VIN_LINE_ISP_SS1:
++ case VIN_LINE_ISP_ITIW:
++ case VIN_LINE_ISP_ITIR:
++ case VIN_LINE_ISP_RAW:
++ case VIN_LINE_ISP_SCD_Y:
++ dummy_module = STF_DUMMY_ISP;
++ break;
++ default:
++ dummy_module = STF_DUMMY_VIN;
++ break;
++ }
++
++ return dummy_module;
++}
++
++static int vin_alloc_dummy_buffer(struct stf_vin2_dev *vin_dev,
++ struct v4l2_mbus_framefmt *fmt, int dummy_module)
++{
++ struct device *dev = vin_dev->stfcamss->dev;
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct vin_dummy_buffer *buffer = NULL;
++ int ret = 0, i;
++ u32 aligns;
++
++ for (i = 0; i < dummy_buffer->nums; i++) {
++ buffer = &vin_dev->dummy_buffer[dummy_module].buffer[i];
++ buffer->width = fmt->width;
++ buffer->height = fmt->height;
++ buffer->mcode = fmt->code;
++ if (i == STF_VIN_PAD_SINK) {
++ aligns = ALIGN(fmt->width * 4, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height);
++ } else if (i == STF_ISP_PAD_SRC
++ || i == STF_ISP_PAD_SRC_SS0
++ || i == STF_ISP_PAD_SRC_SS1) {
++ aligns = ALIGN(fmt->width, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height * 3 / 2);
++ } else if (i == STF_ISP_PAD_SRC_ITIW
++ || i == STF_ISP_PAD_SRC_ITIR) {
++ aligns = ALIGN(fmt->width, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height * 3);
++ } else if (i == STF_ISP_PAD_SRC_RAW) {
++ aligns = ALIGN(fmt->width * ISP_RAW_DATA_BITS / 8,
++ STFCAMSS_FRAME_WIDTH_ALIGN_128);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height);
++ } else if (i == STF_ISP_PAD_SRC_SCD_Y)
++ buffer->buffer_size = PAGE_ALIGN(ISP_SCD_Y_BUFFER_SIZE);
++ else
++ continue;
++
++ buffer->vaddr = dma_alloc_coherent(dev, buffer->buffer_size,
++ &buffer->paddr[0], GFP_DMA | GFP_KERNEL);
++
++ if (buffer->vaddr) {
++ if (i == STF_ISP_PAD_SRC
++ || i == STF_ISP_PAD_SRC_SS0
++ || i == STF_ISP_PAD_SRC_SS1
++ || i == STF_ISP_PAD_SRC_ITIW
++ || i == STF_ISP_PAD_SRC_ITIR)
++ buffer->paddr[1] = (dma_addr_t)(buffer->paddr[0] +
++ aligns * fmt->height);
++ else if (i == STF_ISP_PAD_SRC_SCD_Y)
++ buffer->paddr[1] = (dma_addr_t)(buffer->paddr[0] +
++ ISP_YHIST_BUFFER_SIZE);
++ else
++ st_debug(ST_VIN, "signal plane\n");
++ }
++ {
++ char szPadName[][32] = {
++ "VIN_PAD_SINK",
++ "ISP_PAD_SRC",
++ "ISP_PAD_SRC_SS0",
++ "ISP_PAD_SRC_SS1",
++ "ISP_PAD_SRC_ITIW",
++ "ISP_PAD_SRC_ITIR",
++ "ISP_PAD_SRC_RAW",
++ "ISP_PAD_SRC_SCD_Y",
++ "Unknown Pad"
++ };
++
++ st_debug(ST_VIN, "%s: i = %d(%s) addr[0] = %llx, addr[1] = %llx, size = %u bytes\n",
++ __func__,
++ i,
++ szPadName[i],
++ buffer->paddr[0],
++ buffer->paddr[1],
++ buffer->buffer_size
++ );
++ }
++ }
++
++ return ret;
++}
++
++static void vin_free_dummy_buffer(struct stf_vin2_dev *vin_dev, int dummy_module)
++{
++ struct device *dev = vin_dev->stfcamss->dev;
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct vin_dummy_buffer *buffer = NULL;
++ int i;
++
++ for (i = 0; i < dummy_buffer->nums; i++) {
++ buffer = &dummy_buffer->buffer[i];
++ if (buffer->vaddr)
++ dma_free_coherent(dev, buffer->buffer_size,
++ buffer->vaddr, buffer->paddr[0]);
++ memset(buffer, 0, sizeof(struct vin_dummy_buffer));
++ }
++}
++
++static void vin_set_dummy_buffer(struct vin_line *line, u32 pad)
++{
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ int dummy_module = line_to_dummy_module(line);
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct vin_dummy_buffer *buffer = NULL;
++
++ switch (pad) {
++ case STF_VIN_PAD_SINK:
++ if (line->id == VIN_LINE_WR) {
++ buffer = &dummy_buffer->buffer[STF_VIN_PAD_SINK];
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev, buffer->paddr[0]);
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev, buffer->paddr[0]);
++ } else {
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS0];
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS1];
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIW];
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIR];
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_RAW];
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, buffer->paddr[0]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SCD_Y];
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1], AWB_TYPE);
++ }
++ break;
++ case STF_ISP_PAD_SRC:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_SS0:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS0];
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_SS1:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS1];
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_ITIW:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIW];
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_ITIR:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIR];
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_RAW:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_RAW];
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, buffer->paddr[0]);
++ break;
++ case STF_ISP_PAD_SRC_SCD_Y:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SCD_Y];
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1], AWB_TYPE);
++ break;
++ default:
++ break;
++ }
++}
++
++static int vin_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ int dummy_module = line_to_dummy_module(line);
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct v4l2_mbus_framefmt *fmt;
++
++ st_debug(ST_VIN, "%s, %d\n", __func__, __LINE__);
++ fmt = __vin_get_format(line, NULL, STF_VIN_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE);
++ mutex_lock(&dummy_buffer->stream_lock);
++ if (enable) {
++ if (dummy_buffer->stream_count == 0) {
++ vin_alloc_dummy_buffer(vin_dev, fmt, dummy_module);
++ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
++ atomic_set(&dummy_buffer->frame_skip, get_frame_skip(line));
++ }
++ dummy_buffer->stream_count++;
++ } else {
++ if (dummy_buffer->stream_count == 1) {
++ vin_free_dummy_buffer(vin_dev, dummy_module);
++ // set buffer addr to zero
++ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
++ } else
++ vin_set_dummy_buffer(line,
++ stf_vin_map_isp_pad(line->id, STF_ISP_PAD_SINK));
++
++ dummy_buffer->stream_count--;
++ }
++ mutex_unlock(&dummy_buffer->stream_lock);
++
++ mutex_lock(&line->stream_lock);
++ if (enable) {
++ if (line->stream_count == 0) {
++ if (line->id == VIN_LINE_WR) {
++ vin_dev->hw_ops->vin_wr_irq_enable(vin_dev, 1);
++ vin_dev->hw_ops->vin_wr_stream_set(vin_dev, 1);
++ }
++ }
++ line->stream_count++;
++ } else {
++ if (line->stream_count == 1) {
++ if (line->id == VIN_LINE_WR) {
++ vin_dev->hw_ops->vin_wr_irq_enable(vin_dev, 0);
++ vin_dev->hw_ops->vin_wr_stream_set(vin_dev, 0);
++ }
++ }
++ line->stream_count--;
++ }
++ mutex_unlock(&line->stream_lock);
++
++ if (enable)
++ vin_enable_output(line);
++ else
++ vin_disable_output(line);
++
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__vin_get_format(struct vin_line *line,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(&line->subdev, state, pad);
++ return &line->fmt[pad];
++}
++
++static void vin_try_format(struct vin_line *line,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_VIN_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < line->nformats; i++)
++ if (fmt->code == line->formats[i].code)
++ break;
++
++ /* If not found, use UYVY as default */
++ if (i >= line->nformats)
++ fmt->code = line->formats[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width, STFCAMSS_FRAME_MIN_WIDTH, STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT, STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_VIN_PAD_SRC:
++ /* Set and return a format same as sink pad */
++ *fmt = *__vin_get_format(line, state, STF_VIN_PAD_SINK, which);
++ break;
++ }
++
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++}
++
++static int vin_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++
++ if (code->index >= line->nformats)
++ return -EINVAL;
++ if (code->pad == STF_VIN_PAD_SINK) {
++ code->code = line->formats[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __vin_get_format(line, state, STF_VIN_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++
++ return 0;
++}
++
++static int vin_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ vin_try_format(line, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ vin_try_format(line, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int vin_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __vin_get_format(line, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int vin_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ st_debug(ST_VIDEO, "%s, pad %d, fmt code %x\n",
++ __func__, fmt->pad, fmt->format.code);
++
++ format = __vin_get_format(line, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&line->stream_lock);
++ if (line->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&line->stream_lock);
++ goto out;
++ } else {
++ vin_try_format(line, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&line->stream_lock);
++
++ if (fmt->pad == STF_VIN_PAD_SINK) {
++ /* Propagate the format from sink to source */
++ format = __vin_get_format(line, state, STF_VIN_PAD_SRC,
++ fmt->which);
++
++ *format = fmt->format;
++ vin_try_format(line, state, STF_VIN_PAD_SRC, format,
++ fmt->which);
++ }
++
++out:
++ return 0;
++}
++
++static int vin_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_VIN_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return vin_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static void vin_output_init_addrs(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ dma_addr_t ping_addr;
++ dma_addr_t pong_addr;
++ dma_addr_t y_addr, uv_addr;
++
++ output->active_buf = 0;
++
++ if (output->buf[0]) {
++ ping_addr = output->buf[0]->addr[0];
++ y_addr = output->buf[0]->addr[0];
++ uv_addr = output->buf[0]->addr[1];
++ } else
++ return;
++
++ if (output->buf[1])
++ pong_addr = output->buf[1]->addr[0];
++ else
++ pong_addr = ping_addr;
++
++ switch (stf_vin_map_isp_line(line->id)) {
++ case STF_ISP_LINE_SRC:
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_SS0:
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_SS1:
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_ITIW:
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_ITIR:
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_RAW:
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, y_addr);
++ break;
++ case STF_ISP_LINE_SRC_SCD_Y:
++ output->frame_skip = ISP_AWB_OECF_SKIP_FRAME;
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ y_addr, uv_addr, AWB_TYPE);
++ break;
++ default:
++ if (line->id == VIN_LINE_WR) {
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev, ping_addr);
++#ifdef VIN_TWO_BUFFER
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev, pong_addr);
++#else
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev, ping_addr);
++#endif
++ }
++ break;
++ }
++}
++
++static void vin_init_outputs(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ output->state = VIN_OUTPUT_OFF;
++ output->buf[0] = NULL;
++ output->buf[1] = NULL;
++ output->active_buf = 0;
++ INIT_LIST_HEAD(&output->pending_bufs);
++ INIT_LIST_HEAD(&output->ready_bufs);
++}
++
++static void vin_buf_add_ready(struct vin_output *output,
++ struct stfcamss_buffer *buffer)
++{
++ INIT_LIST_HEAD(&buffer->queue);
++ list_add_tail(&buffer->queue, &output->ready_bufs);
++}
++
++static struct stfcamss_buffer *vin_buf_get_ready(struct vin_output *output)
++{
++ struct stfcamss_buffer *buffer = NULL;
++
++ if (!list_empty(&output->ready_bufs)) {
++ buffer = list_first_entry(&output->ready_bufs,
++ struct stfcamss_buffer,
++ queue);
++ list_del(&buffer->queue);
++ }
++
++ return buffer;
++}
++
++static void vin_buf_add_pending(struct vin_output *output,
++ struct stfcamss_buffer *buffer)
++{
++ INIT_LIST_HEAD(&buffer->queue);
++ list_add_tail(&buffer->queue, &output->pending_bufs);
++}
++
++static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output)
++{
++ struct stfcamss_buffer *buffer = NULL;
++
++ if (!list_empty(&output->pending_bufs)) {
++ buffer = list_first_entry(&output->pending_bufs,
++ struct stfcamss_buffer,
++ queue);
++ list_del(&buffer->queue);
++ }
++
++ return buffer;
++}
++
++#ifdef UNUSED_CODE
++static void vin_output_checkpending(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ if (output->state == VIN_OUTPUT_STOPPING) {
++ /* Release last buffer when hw is idle */
++ if (output->last_buffer) {
++ // vb2_buffer_done(&output->last_buffer->vb.vb2_buf,
++ // VB2_BUF_STATE_DONE);
++ vin_buf_add_pending(output, output->last_buffer);
++ output->last_buffer = NULL;
++ }
++ output->state = VIN_OUTPUT_IDLE;
++
++ /* Buffers received in stopping state are queued in */
++ /* dma pending queue, start next capture here */
++ output->buf[0] = vin_buf_get_pending(output);
++#ifdef VIN_TWO_BUFFER
++ if (line->id == VIN_LINE_WR)
++ output->buf[1] = vin_buf_get_pending(output);
++#endif
++
++ if (!output->buf[0] && output->buf[1]) {
++ output->buf[0] = output->buf[1];
++ output->buf[1] = NULL;
++ }
++
++ if (output->buf[0])
++ output->state = VIN_OUTPUT_SINGLE;
++
++#ifdef VIN_TWO_BUFFER
++ if (output->buf[1] && line->id == VIN_LINE_WR)
++ output->state = VIN_OUTPUT_CONTINUOUS;
++#endif
++ vin_output_init_addrs(line);
++ }
++}
++#endif
++
++static void vin_buf_update_on_last(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ switch (output->state) {
++ case VIN_OUTPUT_CONTINUOUS:
++ output->state = VIN_OUTPUT_SINGLE;
++ output->active_buf = !output->active_buf;
++ break;
++ case VIN_OUTPUT_SINGLE:
++ output->state = VIN_OUTPUT_STOPPING;
++ break;
++ default:
++ st_err_ratelimited(ST_VIN,
++ "Last buff in wrong state! %d\n",
++ output->state);
++ break;
++ }
++}
++
++static void vin_buf_update_on_next(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ switch (output->state) {
++ case VIN_OUTPUT_CONTINUOUS:
++ output->active_buf = !output->active_buf;
++ break;
++ case VIN_OUTPUT_SINGLE:
++ default:
++#ifdef VIN_TWO_BUFFER
++ if (line->id == VIN_LINE_WR)
++ st_err_ratelimited(ST_VIN,
++ "Next buf in wrong state! %d\n",
++ output->state);
++#endif
++ break;
++ }
++}
++
++static void vin_buf_update_on_new(struct vin_line *line,
++ struct vin_output *output,
++ struct stfcamss_buffer *new_buf)
++{
++#ifdef VIN_TWO_BUFFER
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ int inactive_idx;
++#endif
++
++ switch (output->state) {
++ case VIN_OUTPUT_SINGLE:
++#ifdef VIN_TWO_BUFFER
++ int inactive_idx = !output->active_buf;
++
++ if (!output->buf[inactive_idx] && line->id == VIN_LINE_WR) {
++ output->buf[inactive_idx] = new_buf;
++ if (inactive_idx)
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev,
++ output->buf[1]->addr[0]);
++ else
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev,
++ output->buf[0]->addr[0]);
++ output->state = VIN_OUTPUT_CONTINUOUS;
++
++ } else {
++ vin_buf_add_pending(output, new_buf);
++ if (line->id == VIN_LINE_WR)
++ st_warn(ST_VIN, "Inactive buffer is busy\n");
++ }
++#else
++ vin_buf_add_pending(output, new_buf);
++#endif
++ break;
++ case VIN_OUTPUT_IDLE:
++ st_warn(ST_VIN, "Output idle buffer set!\n");
++ if (!output->buf[0]) {
++ output->buf[0] = new_buf;
++ vin_output_init_addrs(line);
++ output->state = VIN_OUTPUT_SINGLE;
++ } else {
++ vin_buf_add_pending(output, new_buf);
++ st_warn(ST_VIN, "Output idle with buffer set!\n");
++ }
++ break;
++ case VIN_OUTPUT_STOPPING:
++ if (output->last_buffer) {
++ output->buf[output->active_buf] = output->last_buffer;
++ output->last_buffer = NULL;
++ } else
++ st_err(ST_VIN, "stop state lost lastbuffer!\n");
++ output->state = VIN_OUTPUT_SINGLE;
++ // vin_output_checkpending(line);
++ vin_buf_add_pending(output, new_buf);
++ break;
++ case VIN_OUTPUT_CONTINUOUS:
++ default:
++ vin_buf_add_pending(output, new_buf);
++ break;
++ }
++}
++
++static void vin_buf_flush(struct vin_output *output,
++ enum vb2_buffer_state state)
++{
++ struct stfcamss_buffer *buf;
++ struct stfcamss_buffer *t;
++
++ list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
++ vb2_buffer_done(&buf->vb.vb2_buf, state);
++ list_del(&buf->queue);
++ }
++ list_for_each_entry_safe(buf, t, &output->ready_bufs, queue) {
++ vb2_buffer_done(&buf->vb.vb2_buf, state);
++ list_del(&buf->queue);
++ }
++}
++
++static void vin_buffer_done(struct vin_line *line, struct vin_params *params)
++{
++ struct stfcamss_buffer *ready_buf;
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++ u64 ts = ktime_get_ns();
++ struct v4l2_event event = {
++ .type = V4L2_EVENT_FRAME_SYNC,
++ };
++
++ if (output->state == VIN_OUTPUT_OFF
++ || output->state == VIN_OUTPUT_RESERVED)
++ return;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ while ((ready_buf = vin_buf_get_ready(output))) {
++ if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
++ event.u.frame_sync.frame_sequence = output->sequence;
++ v4l2_event_queue(line->subdev.devnode, &event);
++ }
++
++ ready_buf->vb.vb2_buf.timestamp = ts;
++ ready_buf->vb.sequence = output->sequence++;
++
++ /* The stf_isp_ctrl currently buffered with mmap,
++ * which will not update cache by default.
++ * Flush L2 cache to make sure data is updated.
++ */
++ if (ready_buf->vb.vb2_buf.memory == VB2_MEMORY_MMAP)
++ sifive_l2_flush64_range(ready_buf->addr[0], ready_buf->sizeimage);
++
++ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
++ }
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++}
++
++static void vin_change_buffer(struct vin_line *line)
++{
++ struct stfcamss_buffer *ready_buf;
++ struct vin_output *output = &line->output;
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ dma_addr_t *new_addr;
++ unsigned long flags;
++ u32 active_index;
++ int scd_type;
++
++ if (output->state == VIN_OUTPUT_OFF
++ || output->state == VIN_OUTPUT_STOPPING
++ || output->state == VIN_OUTPUT_RESERVED
++ || output->state == VIN_OUTPUT_IDLE)
++ return;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ active_index = output->active_buf;
++
++ ready_buf = output->buf[active_index];
++ if (!ready_buf) {
++ st_err_ratelimited(ST_VIN,
++ "Missing ready buf %d %d!\n",
++ active_index, output->state);
++ active_index = !active_index;
++ ready_buf = output->buf[active_index];
++ if (!ready_buf) {
++ st_err_ratelimited(ST_VIN,
++ "Missing ready buf 2 %d %d!\n",
++ active_index, output->state);
++ goto out_unlock;
++ }
++ }
++
++ /* Get next buffer */
++ output->buf[active_index] = vin_buf_get_pending(output);
++ if (!output->buf[active_index]) {
++ /* No next buffer - set same address */
++ new_addr = ready_buf->addr;
++ vin_buf_update_on_last(line);
++ } else {
++ new_addr = output->buf[active_index]->addr;
++ vin_buf_update_on_next(line);
++ }
++
++ if (output->state == VIN_OUTPUT_STOPPING)
++ output->last_buffer = ready_buf;
++ else {
++ switch (stf_vin_map_isp_line(line->id)) {
++ case STF_ISP_LINE_SRC:
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_SS0:
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_SS1:
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_ITIW:
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_ITIR:
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_RAW:
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, new_addr[0]);
++ break;
++ case STF_ISP_LINE_SRC_SCD_Y:
++ scd_type = vin_dev->hw_ops->vin_isp_get_scd_type(vin_dev);
++ ready_buf->vb.flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME);
++ if (scd_type == AWB_TYPE)
++ ready_buf->vb.flags |= V4L2_BUF_FLAG_PFRAME;
++ else
++ ready_buf->vb.flags |= V4L2_BUF_FLAG_BFRAME;
++ if (!output->frame_skip) {
++ output->frame_skip = ISP_AWB_OECF_SKIP_FRAME;
++ scd_type = scd_type == AWB_TYPE ? OECF_TYPE : AWB_TYPE;
++ } else {
++ output->frame_skip--;
++ scd_type = scd_type == AWB_TYPE ? AWB_TYPE : OECF_TYPE;
++ }
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ new_addr[0], new_addr[1], scd_type);
++ break;
++ default:
++ if (line->id == VIN_LINE_WR) {
++#ifdef VIN_TWO_BUFFER
++ if (active_index)
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev,
++ new_addr[0]);
++ else
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev,
++ new_addr[0]);
++#else
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev,
++ new_addr[0]);
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev,
++ new_addr[0]);
++#endif
++ }
++ break;
++ }
++
++ vin_buf_add_ready(output, ready_buf);
++ }
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return;
++
++out_unlock:
++ spin_unlock_irqrestore(&line->output_lock, flags);
++}
++
++static int vin_queue_buffer(struct stfcamss_video *vid,
++ struct stfcamss_buffer *buf)
++{
++ struct vin_line *line = container_of(vid, struct vin_line, video_out);
++ struct vin_output *output;
++ unsigned long flags;
++
++
++ output = &line->output;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ vin_buf_update_on_new(line, output, buf);
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++
++ return 0;
++}
++
++static int vin_flush_buffers(struct stfcamss_video *vid,
++ enum vb2_buffer_state state)
++{
++ struct vin_line *line = container_of(vid, struct vin_line, video_out);
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ vin_buf_flush(output, state);
++ if (output->buf[0])
++ vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
++
++ if (output->buf[1])
++ vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
++
++ if (output->last_buffer) {
++ vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
++ output->last_buffer = NULL;
++ }
++ output->buf[0] = output->buf[1] = NULL;
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return 0;
++}
++
++static int vin_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if (flags & MEDIA_LNK_FL_ENABLED)
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++ return 0;
++}
++
++static int stf_vin_subscribe_event(struct v4l2_subdev *sd,
++ struct v4l2_fh *fh,
++ struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_FRAME_SYNC:
++ return v4l2_event_subscribe(fh, sub, 0, NULL);
++ default:
++ st_debug(ST_VIN, "unsupport subscribe_event\n");
++ return -EINVAL;
++ }
++}
++
++static const struct v4l2_subdev_core_ops vin_core_ops = {
++ .s_power = vin_set_power,
++ .subscribe_event = stf_vin_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops vin_video_ops = {
++ .s_stream = vin_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops vin_pad_ops = {
++ .enum_mbus_code = vin_enum_mbus_code,
++ .enum_frame_size = vin_enum_frame_size,
++ .get_fmt = vin_get_format,
++ .set_fmt = vin_set_format,
++};
++
++static const struct v4l2_subdev_ops vin_v4l2_ops = {
++ .core = &vin_core_ops,
++ .video = &vin_video_ops,
++ .pad = &vin_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops vin_v4l2_internal_ops = {
++ .open = vin_init_formats,
++};
++
++static const struct stfcamss_video_ops stfcamss_vin_video_ops = {
++ .queue_buffer = vin_queue_buffer,
++ .flush_buffers = vin_flush_buffers,
++};
++
++static const struct media_entity_operations vin_media_ops = {
++ .link_setup = vin_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_vin_register(struct stf_vin2_dev *vin_dev, struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd;
++ struct stfcamss_video *video_out;
++ struct media_pad *pads;
++ int ret;
++ int i;
++
++ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
++ char name[32];
++ char *sub_name = get_line_subdevname(i);
++ int is_mp;
++
++#ifdef STF_CAMSS_SKIP_ITI
++ if ((stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIW) ||
++ (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIR))
++ continue;
++#endif
++ is_mp = (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC) ? true : false;
++ is_mp = false;
++ sd = &vin_dev->line[i].subdev;
++ pads = vin_dev->line[i].pads;
++ video_out = &vin_dev->line[i].video_out;
++ video_out->id = i;
++
++ v4l2_subdev_init(sd, &vin_v4l2_ops);
++ sd->internal_ops = &vin_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
++ STF_VIN_NAME, 0, sub_name);
++ v4l2_set_subdevdata(sd, &vin_dev->line[i]);
++
++ ret = vin_init_formats(sd, NULL);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to init format: %d\n", ret);
++ goto err_init;
++ }
++
++ pads[STF_VIN_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_VIN_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function =
++ MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &vin_media_ops;
++ ret = media_entity_pads_init(&sd->entity,
++ STF_VIN_PADS_NUM, pads);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to init media entity: %d\n", ret);
++ goto err_init;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to register subdev: %d\n", ret);
++ goto err_reg_subdev;
++ }
++
++ video_out->ops = &stfcamss_vin_video_ops;
++ video_out->bpl_alignment = 16 * 8;
++
++ snprintf(name, ARRAY_SIZE(name), "%s_%s%d",
++ sd->name, "video", i);
++ ret = stf_video_register(video_out, v4l2_dev, name, is_mp);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to register video node: %d\n",
++ ret);
++ goto err_vid_reg;
++ }
++
++ ret = media_create_pad_link(
++ &sd->entity, STF_VIN_PAD_SRC,
++ &video_out->vdev.entity, 0,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to link %s->%s entities: %d\n",
++ sd->entity.name, video_out->vdev.entity.name,
++ ret);
++ goto err_create_link;
++ }
++ }
++
++ return 0;
++
++err_create_link:
++ stf_video_unregister(video_out);
++err_vid_reg:
++ v4l2_device_unregister_subdev(sd);
++err_reg_subdev:
++ media_entity_cleanup(&sd->entity);
++err_init:
++ for (i--; i >= 0; i--) {
++ sd = &vin_dev->line[i].subdev;
++ video_out = &vin_dev->line[i].video_out;
++
++ stf_video_unregister(video_out);
++ v4l2_device_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ }
++ return ret;
++}
++
++int stf_vin_unregister(struct stf_vin2_dev *vin_dev)
++{
++ struct v4l2_subdev *sd;
++ struct stfcamss_video *video_out;
++ int i;
++
++ mutex_destroy(&vin_dev->power_lock);
++ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++)
++ mutex_destroy(&vin_dev->dummy_buffer[i].stream_lock);
++
++ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
++ sd = &vin_dev->line[i].subdev;
++ video_out = &vin_dev->line[i].video_out;
++
++ stf_video_unregister(video_out);
++ v4l2_device_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ mutex_destroy(&vin_dev->line[i].stream_lock);
++ mutex_destroy(&vin_dev->line[i].power_lock);
++ }
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.h
+@@ -0,0 +1,182 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_VIN_H
++#define STF_VIN_H
++
++#include <media/v4l2-device.h>
++#include <media/v4l2-subdev.h>
++#include <linux/spinlock_types.h>
++#include <video/stf-vin.h>
++#include <linux/platform_device.h>
++
++#include "stf_video.h"
++
++#define STF_VIN_NAME "stf_vin"
++
++#define STF_VIN_PAD_SINK 0
++#define STF_VIN_PAD_SRC 1
++#define STF_VIN_PADS_NUM 2
++
++struct vin2_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct vin2_format_table {
++ const struct vin2_format *fmts;
++ int nfmts;
++};
++
++enum vin_output_state {
++ VIN_OUTPUT_OFF,
++ VIN_OUTPUT_RESERVED,
++ VIN_OUTPUT_SINGLE,
++ VIN_OUTPUT_CONTINUOUS,
++ VIN_OUTPUT_IDLE,
++ VIN_OUTPUT_STOPPING
++};
++
++struct vin_output {
++ int active_buf;
++ struct stfcamss_buffer *buf[2];
++ struct stfcamss_buffer *last_buffer;
++ struct list_head pending_bufs;
++ struct list_head ready_bufs;
++ enum vin_output_state state;
++ unsigned int sequence;
++ unsigned int frame_skip;
++};
++
++/* The vin output lines include all isp controller lines,
++ * and one vin_wr output line.
++ */
++enum vin_line_id {
++ VIN_LINE_NONE = -1,
++ VIN_LINE_WR = 0,
++ VIN_LINE_ISP = 1,
++ VIN_LINE_ISP_SS0 = 2,
++ VIN_LINE_ISP_SS1 = 3,
++ VIN_LINE_ISP_ITIW = 4,
++ VIN_LINE_ISP_ITIR = 5,
++ VIN_LINE_ISP_RAW = 6,
++ VIN_LINE_ISP_SCD_Y = 7,
++ VIN_LINE_MAX = 8,
++};
++
++enum subdev_type;
++
++struct vin_line {
++ enum subdev_type sdev_type; // must be frist
++ enum vin_line_id id;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_VIN_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_VIN_PADS_NUM];
++ struct stfcamss_video video_out;
++ struct mutex stream_lock;
++ int stream_count;
++ struct mutex power_lock;
++ int power_count;
++ struct vin_output output;
++ spinlock_t output_lock;
++ const struct vin2_format *formats;
++ unsigned int nformats;
++#ifdef CONFIG_PM_SLEEP
++ int pm_stream_count;
++ int pm_power_count;
++#endif
++};
++
++struct stf_vin2_dev;
++
++struct vin_hw_ops {
++ int (*vin_clk_enable)(struct stf_vin2_dev *vin_dev);
++ int (*vin_clk_disable)(struct stf_vin2_dev *vin_dev);
++ int (*vin_config_set)(struct stf_vin2_dev *vin_dev);
++ int (*vin_wr_stream_set)(struct stf_vin2_dev *vin_dev, int on);
++ void (*vin_wr_irq_enable)(struct stf_vin2_dev *vin_dev, int enable);
++ void (*vin_power_on)(struct stf_vin2_dev *vin_dev, int on);
++ void (*wr_rd_set_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t wr_addr, dma_addr_t rd_addr);
++ void (*vin_wr_set_ping_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t addr);
++ void (*vin_wr_set_pong_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t addr);
++ void (*vin_wr_get_ping_pong_status)(struct stf_vin2_dev *vin_dev);
++ void (*vin_isp_set_yuv_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_raw_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t raw_addr);
++ void (*vin_isp_set_ss0_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_ss1_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_itiw_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_itir_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_scd_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t yhist_addr,
++ dma_addr_t scd_addr, int scd_type);
++ int (*vin_isp_get_scd_type)(struct stf_vin2_dev *vin_dev);
++ irqreturn_t (*vin_wr_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_csi_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_scd_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_irq_csiline_handler)(int irq, void *priv);
++ void (*isr_buffer_done)(struct vin_line *line,
++ struct vin_params *params);
++ void (*isr_change_buffer)(struct vin_line *line);
++};
++
++#define ISP_DUMMY_BUFFER_NUMS STF_ISP_PAD_MAX
++#define VIN_DUMMY_BUFFER_NUMS 1
++
++enum {
++ STF_DUMMY_VIN,
++ STF_DUMMY_ISP,
++ STF_DUMMY_MODULE_NUMS,
++};
++
++struct vin_dummy_buffer {
++ dma_addr_t paddr[3];
++ void *vaddr;
++ u32 buffer_size;
++ u32 width;
++ u32 height;
++ u32 mcode;
++};
++
++struct dummy_buffer {
++ struct vin_dummy_buffer *buffer;
++ u32 nums;
++ struct mutex stream_lock;
++ int stream_count;
++ atomic_t frame_skip;
++};
++
++struct stf_vin2_dev {
++ struct stfcamss *stfcamss;
++ struct vin_line line[VIN_LINE_MAX];
++ struct dummy_buffer dummy_buffer[STF_DUMMY_MODULE_NUMS];
++ struct vin_hw_ops *hw_ops;
++ atomic_t ref_count;
++ struct mutex power_lock;
++ int power_count;
++};
++
++extern void sifive_l2_flush64_range(unsigned long start, unsigned long len);
++extern int stf_vin_subdev_init(struct stfcamss *stfcamss);
++extern int stf_vin_register(struct stf_vin2_dev *vin_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_vin_unregister(struct stf_vin2_dev *vin_dev);
++
++extern struct vin_hw_ops vin_ops;
++extern void dump_vin_reg(void *__iomem regbase);
++extern enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line,
++ enum isp_pad_id def);
++
++#endif /* STF_VIN_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c
+@@ -0,0 +1,433 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/of_graph.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static void vin_intr_clear(void __iomem *sysctrl_base)
++{
++ reg_set_bit(sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x1);
++ reg_set_bit(sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x0);
++}
++
++static irqreturn_t stf_vin_wr_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ struct dummy_buffer *dummy_buffer =
++ &vin_dev->dummy_buffer[STF_DUMMY_VIN];
++
++ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
++ vin_dev->hw_ops->isr_change_buffer(&vin_dev->line[VIN_LINE_WR]);
++ vin_dev->hw_ops->isr_buffer_done(&vin_dev->line[VIN_LINE_WR], &params);
++ }
++
++ vin_intr_clear(vin->sysctrl_base);
++
++ return IRQ_HANDLED;
++}
++
++static void __iomem *stf_vin_get_ispbase(struct stf_vin_dev *vin)
++{
++ void __iomem *base = vin->isp_base;
++
++ return base;
++}
++
++static irqreturn_t stf_vin_isp_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ u32 int_status, value;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++
++ if (int_status & BIT(24)) {
++ if ((int_status & BIT(11)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SS0], &params);
++
++ if ((int_status & BIT(12)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SS1], &params);
++
++ if ((int_status & BIT(20)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP], &params);
++
++ value = reg_read(ispbase, ISP_REG_ITIDPSR);
++ if ((value & BIT(17)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_ITIW], &params);
++ if ((value & BIT(16)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_ITIR], &params);
++
++#ifndef ISP_USE_CSI_AND_SC_DONE_INTERRUPT
++ if (int_status & BIT(25))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_RAW], &params);
++
++ if (int_status & BIT(26))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y], &params);
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0, (int_status & ~EN_INT_ALL)
++ | EN_INT_ISP_DONE | EN_INT_CSI_DONE | EN_INT_SC_DONE);
++#else
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0,
++ (int_status & ~EN_INT_ALL) | EN_INT_ISP_DONE);
++#endif
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t stf_vin_isp_csi_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ u32 int_status;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++
++ if (int_status & BIT(25)) {
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_RAW], &params);
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0,
++ (int_status & ~EN_INT_ALL) | EN_INT_CSI_DONE);
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t stf_vin_isp_scd_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ u32 int_status;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++
++ if (int_status & BIT(26)) {
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y], &params);
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0, (int_status & ~EN_INT_ALL) | EN_INT_SC_DONE);
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t stf_vin_isp_irq_csiline_handler(int irq, void *priv)
++{
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ struct stf_isp_dev *isp_dev;
++ void __iomem *ispbase;
++ u32 int_status, value;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ isp_dev = vin_dev->stfcamss->isp_dev;
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++ if (int_status & BIT(27)) {
++ struct dummy_buffer *dummy_buffer =
++ &vin_dev->dummy_buffer[STF_DUMMY_ISP];
++
++ if (!atomic_read(&isp_dev->shadow_count)) {
++ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
++ if ((int_status & BIT(11)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_SS0]);
++ if ((int_status & BIT(12)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_SS1]);
++ if ((int_status & BIT(20)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP]);
++
++ value = reg_read(ispbase, ISP_REG_ITIDPSR);
++ if ((value & BIT(17)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_ITIW]);
++ if ((value & BIT(16)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_ITIR]);
++
++ value = reg_read(ispbase, ISP_REG_CSI_MODULE_CFG);
++ if ((value & BIT(19)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_RAW]);
++ if ((value & BIT(17)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y]);
++ }
++
++ // shadow update
++ reg_set_bit(ispbase, ISP_REG_CSIINTS_ADDR, 0x30000, 0x30000);
++ reg_set_bit(ispbase, ISP_REG_IESHD_ADDR, BIT(1) | BIT(0), 0x3);
++ } else {
++ st_warn(ST_VIN, "isp shadow_lock locked. skip this frame\n");
++ }
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0,
++ (int_status & ~EN_INT_ALL) | EN_INT_LINE_INT);
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static int stf_vin_clk_enable(struct stf_vin2_dev *vin_dev)
++{
++ struct stfcamss *stfcamss = vin_dev->stfcamss;
++
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PCLK].clk);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_APB_FUNC].clk, 49500000);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_SYS_CLK].clk, 297000000);
++
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PCLK].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_SYS_CLK].rstc);
++
++ return 0;
++}
++
++
++static int stf_vin_clk_disable(struct stf_vin2_dev *vin_dev)
++{
++ struct stfcamss *stfcamss = vin_dev->stfcamss;
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_PCLK].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_SYS_CLK].rstc);
++
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PCLK].clk);
++
++ return 0;
++}
++
++static int stf_vin_config_set(struct stf_vin2_dev *vin_dev)
++{
++ return 0;
++}
++
++static int stf_vin_wr_stream_set(struct stf_vin2_dev *vin_dev, int on)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ //make the axiwr alway on
++ if (on)
++ reg_set(vin->sysctrl_base, SYSCONSAIF_SYSCFG_20, U0_VIN_CNFG_AXIWR0_EN);
++
++ return 0;
++}
++
++static void stf_vin_wr_irq_enable(struct stf_vin2_dev *vin_dev,
++ int enable)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ unsigned int value = 0;
++
++ if (enable) {
++ value = ~(0x1 << 1);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_MASK,
++ value);
++ } else {
++ /* clear vin interrupt */
++ value = 0x1 << 1;
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x1);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_MASK,
++ value);
++ }
++}
++
++static void stf_vin_wr_rd_set_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t wr_addr, dma_addr_t rd_addr)
++{
++#ifdef UNUSED_CODE
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ /* set the start address*/
++ reg_write(vin->sysctrl_base,
++ SYSCTRL_VIN_WR_START_ADDR, (long)wr_addr);
++ reg_write(vin->sysctrl_base,
++ SYSCTRL_VIN_RD_END_ADDR, (long)rd_addr);
++#endif
++}
++
++void stf_vin_wr_set_ping_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ /* set the start address */
++ reg_write(vin->sysctrl_base, SYSCONSAIF_SYSCFG_24, (long)addr);
++}
++
++void stf_vin_wr_set_pong_addr(struct stf_vin2_dev *vin_dev, dma_addr_t addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ /* set the start address */
++ reg_write(vin->sysctrl_base, SYSCONSAIF_SYSCFG_32, (long)addr);
++}
++
++void stf_vin_isp_set_yuv_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_Y_PLANE_START_ADDR, y_addr);
++ reg_write(ispbase, ISP_REG_UV_PLANE_START_ADDR, uv_addr);
++ // reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(0), 1);
++}
++
++void stf_vin_isp_set_raw_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t raw_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_DUMP_CFG_0, raw_addr);
++}
++
++void stf_vin_isp_set_ss0_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_SS0AY, y_addr);
++ reg_write(ispbase, ISP_REG_SS0AUV, uv_addr);
++}
++
++void stf_vin_isp_set_ss1_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_SS1AY, y_addr);
++ reg_write(ispbase, ISP_REG_SS1AUV, uv_addr);
++}
++
++void stf_vin_isp_set_itiw_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_ITIDWYSAR, y_addr);
++ reg_write(ispbase, ISP_REG_ITIDWUSAR, uv_addr);
++}
++
++void stf_vin_isp_set_itir_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_ITIDRYSAR, y_addr);
++ reg_write(ispbase, ISP_REG_ITIDRUSAR, uv_addr);
++}
++
++int stf_vin_isp_get_scd_type(struct stf_vin2_dev *vin_dev)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ return (reg_read(ispbase, ISP_REG_SC_CFG_1) & (0x3 << 30)) >> 30;
++}
++
++void stf_vin_isp_set_scd_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t yhist_addr, dma_addr_t scd_addr, int scd_type)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_set_bit(ispbase, ISP_REG_SC_CFG_1, 0x3 << 30, scd_type << 30);
++ reg_write(ispbase, ISP_REG_SCD_CFG_0, scd_addr);
++ reg_write(ispbase, ISP_REG_YHIST_CFG_4, yhist_addr);
++}
++
++void dump_vin_reg(void *__iomem regbase)
++{
++ st_debug(ST_VIN, "DUMP VIN register:\n");
++ print_reg(ST_VIN, regbase, 0x00);
++ print_reg(ST_VIN, regbase, 0x04);
++ print_reg(ST_VIN, regbase, 0x08);
++ print_reg(ST_VIN, regbase, 0x0c);
++ print_reg(ST_VIN, regbase, 0x10);
++ print_reg(ST_VIN, regbase, 0x14);
++ print_reg(ST_VIN, regbase, 0x18);
++ print_reg(ST_VIN, regbase, 0x1c);
++ print_reg(ST_VIN, regbase, 0x20);
++ print_reg(ST_VIN, regbase, 0x24);
++ print_reg(ST_VIN, regbase, 0x28);
++}
++
++struct vin_hw_ops vin_ops = {
++ .vin_clk_enable = stf_vin_clk_enable,
++ .vin_clk_disable = stf_vin_clk_disable,
++ .vin_config_set = stf_vin_config_set,
++ .vin_wr_stream_set = stf_vin_wr_stream_set,
++ .vin_wr_irq_enable = stf_vin_wr_irq_enable,
++ .wr_rd_set_addr = stf_vin_wr_rd_set_addr,
++ .vin_wr_set_ping_addr = stf_vin_wr_set_ping_addr,
++ .vin_wr_set_pong_addr = stf_vin_wr_set_pong_addr,
++ .vin_isp_set_yuv_addr = stf_vin_isp_set_yuv_addr,
++ .vin_isp_set_raw_addr = stf_vin_isp_set_raw_addr,
++ .vin_isp_set_ss0_addr = stf_vin_isp_set_ss0_addr,
++ .vin_isp_set_ss1_addr = stf_vin_isp_set_ss1_addr,
++ .vin_isp_set_itiw_addr = stf_vin_isp_set_itiw_addr,
++ .vin_isp_set_itir_addr = stf_vin_isp_set_itir_addr,
++ .vin_isp_set_scd_addr = stf_vin_isp_set_scd_addr,
++ .vin_isp_get_scd_type = stf_vin_isp_get_scd_type,
++ .vin_wr_irq_handler = stf_vin_wr_irq_handler,
++ .vin_isp_irq_handler = stf_vin_isp_irq_handler,
++ .vin_isp_csi_irq_handler = stf_vin_isp_csi_irq_handler,
++ .vin_isp_scd_irq_handler = stf_vin_isp_scd_irq_handler,
++ .vin_isp_irq_csiline_handler = stf_vin_isp_irq_csiline_handler,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stfcamss.c
+@@ -0,0 +1,1369 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/dmaengine.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_reserved_mem.h>
++#include <linux/of_graph.h>
++#include <linux/of_address.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/io.h>
++#include <linux/dma-mapping.h>
++#include <linux/uaccess.h>
++#include <linux/mfd/syscon.h>
++
++#include <linux/videodev2.h>
++
++#include <media/media-device.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-mc.h>
++#include <media/v4l2-fwnode.h>
++#include <linux/debugfs.h>
++
++#include "stfcamss.h"
++
++#ifdef STF_DEBUG
++unsigned int stdbg_level = ST_DEBUG;
++unsigned int stdbg_mask = 0x7F;
++#else
++unsigned int stdbg_level = ST_ERR;
++unsigned int stdbg_mask = 0x7F;
++#endif
++EXPORT_SYMBOL_GPL(stdbg_level);
++EXPORT_SYMBOL_GPL(stdbg_mask);
++
++static const struct reg_name mem_reg_name[] = {
++ {"csi2rx"},
++ {"vclk"},
++ {"vrst"},
++ {"sctrl"},
++ {"isp"},
++ {"trst"},
++ {"pmu"},
++ {"syscrg"},
++};
++
++static struct clk_bulk_data stfcamss_clocks[] = {
++ { .id = "clk_apb_func" },
++ { .id = "clk_pclk" },
++ { .id = "clk_sys_clk" },
++ { .id = "clk_wrapper_clk_c" },
++ { .id = "clk_dvp_inv" },
++ { .id = "clk_axiwr" },
++ { .id = "clk_mipi_rx0_pxl" },
++ { .id = "clk_pixel_clk_if0" },
++ { .id = "clk_pixel_clk_if1" },
++ { .id = "clk_pixel_clk_if2" },
++ { .id = "clk_pixel_clk_if3" },
++ { .id = "clk_m31dphy_cfgclk_in" },
++ { .id = "clk_m31dphy_refclk_in" },
++ { .id = "clk_m31dphy_txclkesc_lan0" },
++ { .id = "clk_ispcore_2x" },
++ { .id = "clk_isp_axi" },
++};
++
++static struct reset_control_bulk_data stfcamss_resets[] = {
++ { .id = "rst_wrapper_p" },
++ { .id = "rst_wrapper_c" },
++ { .id = "rst_pclk" },
++ { .id = "rst_sys_clk" },
++ { .id = "rst_axird" },
++ { .id = "rst_axiwr" },
++ { .id = "rst_pixel_clk_if0" },
++ { .id = "rst_pixel_clk_if1" },
++ { .id = "rst_pixel_clk_if2" },
++ { .id = "rst_pixel_clk_if3" },
++ { .id = "rst_m31dphy_hw" },
++ { .id = "rst_m31dphy_b09_always_on" },
++ { .id = "rst_isp_top_n" },
++ { .id = "rst_isp_top_axi" },
++};
++
++int stfcamss_get_mem_res(struct platform_device *pdev, struct stf_vin_dev *vin)
++{
++ struct device *dev = &pdev->dev;
++ struct resource *res;
++ char *name;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(mem_reg_name); i++) {
++ name = (char *)(&mem_reg_name[i]);
++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
++
++ if (!res)
++ return -EINVAL;
++
++ if (!strcmp(name, "csi2rx")) {
++ vin->csi2rx_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->csi2rx_base))
++ return PTR_ERR(vin->csi2rx_base);
++ } else if (!strcmp(name, "vclk")) {
++ vin->clkgen_base = ioremap(res->start, resource_size(res));
++ if (!vin->clkgen_base)
++ return -ENOMEM;
++ } else if (!strcmp(name, "vrst")) {
++ vin->rstgen_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->rstgen_base))
++ return PTR_ERR(vin->rstgen_base);
++ } else if (!strcmp(name, "sctrl")) {
++ vin->sysctrl_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->sysctrl_base))
++ return PTR_ERR(vin->sysctrl_base);
++ } else if (!strcmp(name, "isp")) {
++ vin->isp_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->isp_base))
++ return PTR_ERR(vin->isp_base);
++ } else if (!strcmp(name, "trst")) {
++ vin->vin_top_rstgen_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->vin_top_rstgen_base))
++ return PTR_ERR(vin->vin_top_rstgen_base);
++ } else if (!strcmp(name, "pmu")) {
++ vin->pmu_test = ioremap(res->start, resource_size(res));
++ if (!vin->pmu_test)
++ return -ENOMEM;
++ } else if (!strcmp(name, "syscrg")) {
++ vin->sys_crg = ioremap(res->start, resource_size(res));
++ if (!vin->sys_crg)
++ return -ENOMEM;
++ } else {
++ st_err(ST_CAMSS, "Could not match resource name\n");
++ }
++ }
++
++ return 0;
++}
++
++int vin_parse_dt(struct device *dev, struct stf_vin_dev *vin)
++{
++ int ret = 0;
++ struct device_node *np = dev->of_node;
++
++ if (!np)
++ return -EINVAL;
++
++ return ret;
++}
++
++struct media_entity *stfcamss_find_sensor(struct media_entity *entity)
++{
++ struct media_pad *pad;
++
++ while (1) {
++ if (!entity->pads)
++ return NULL;
++
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ return NULL;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ return NULL;
++
++ entity = pad->entity;
++
++ if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
++ return entity;
++ }
++}
++
++static int stfcamss_of_parse_endpoint_node(struct device *dev,
++ struct device_node *node,
++ struct stfcamss_async_subdev *csd)
++{
++ struct v4l2_fwnode_endpoint vep = { { 0 } };
++ struct v4l2_mbus_config_parallel *parallel_bus = &vep.bus.parallel;
++ struct v4l2_mbus_config_mipi_csi2 *csi2_bus = &vep.bus.mipi_csi2;
++ struct dvp_cfg *dvp = &csd->interface.dvp;
++ struct csi2phy_cfg *csiphy = &csd->interface.csiphy;
++
++ v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
++ st_debug(ST_CAMSS, "%s: vep.base.port = 0x%x, id = 0x%x\n",
++ __func__, vep.base.port, vep.base.id);
++
++ csd->port = vep.base.port;
++ switch (csd->port) {
++ case DVP_SENSOR_PORT_NUMBER:
++ st_debug(ST_CAMSS, "%s, flags = 0x%x\n", __func__,
++ parallel_bus->flags);
++ dvp->flags = parallel_bus->flags;
++ dvp->bus_width = parallel_bus->bus_width;
++ dvp->data_shift = parallel_bus->data_shift;
++ break;
++ case CSI2RX_SENSOR_PORT_NUMBER:
++ st_debug(ST_CAMSS, "%s, CSI2 flags = 0x%x\n",
++ __func__, parallel_bus->flags);
++ csiphy->flags = csi2_bus->flags;
++ memcpy(csiphy->data_lanes,
++ csi2_bus->data_lanes, csi2_bus->num_data_lanes);
++ csiphy->clock_lane = csi2_bus->clock_lane;
++ csiphy->num_data_lanes = csi2_bus->num_data_lanes;
++ memcpy(csiphy->lane_polarities,
++ csi2_bus->lane_polarities,
++ csi2_bus->num_data_lanes + 1);
++ break;
++ default:
++ break;
++ };
++
++ return 0;
++}
++
++static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
++{
++ struct device *dev = stfcamss->dev;
++ struct device_node *node = NULL;
++ struct device_node *remote = NULL;
++ int ret, num_subdevs = 0;
++
++ for_each_endpoint_of_node(dev->of_node, node) {
++ struct stfcamss_async_subdev *csd;
++
++ if (!of_device_is_available(node))
++ continue;
++
++ remote = of_graph_get_remote_port_parent(node);
++ if (!remote) {
++ st_err(ST_CAMSS, "Cannot get remote parent\n");
++ ret = -EINVAL;
++ goto err_cleanup;
++ }
++
++ csd = v4l2_async_nf_add_fwnode(&stfcamss->notifier,
++ of_fwnode_handle(remote),
++ struct stfcamss_async_subdev);
++ of_node_put(remote);
++ if (IS_ERR(csd)) {
++ ret = PTR_ERR(csd);
++ goto err_cleanup;
++ }
++
++ ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
++ if (ret < 0)
++ goto err_cleanup;
++
++ num_subdevs++;
++ }
++
++ return num_subdevs;
++
++err_cleanup:
++ of_node_put(node);
++ return ret;
++}
++
++static int stfcamss_init_subdevices(struct stfcamss *stfcamss)
++{
++ int ret;
++
++ ret = stf_dvp_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_dvp sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_csiphy_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_csiphy sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_csi_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_csi sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_isp_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_isp sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_vin_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_vin sub-device: %d\n",
++ ret);
++ return ret;
++ }
++ return ret;
++}
++
++static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
++{
++ int ret;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
++ struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
++ struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++
++ ret = stf_dvp_register(dvp_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf dvp%d entity: %d\n",
++ 0, ret);
++ goto err_reg_dvp;
++ }
++
++ ret = stf_csiphy_register(csiphy_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf csiphy%d entity: %d\n",
++ 0, ret);
++ goto err_reg_csiphy;
++ }
++
++ ret = stf_csi_register(csi_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf csi%d entity: %d\n",
++ 0, ret);
++ goto err_reg_csi;
++ }
++
++ ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf isp%d entity: %d\n",
++ 0, ret);
++ goto err_reg_isp;
++ }
++
++ ret = stf_vin_register(vin_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register vin entity: %d\n",
++ ret);
++ goto err_reg_vin;
++ }
++
++ ret = media_create_pad_link(
++ &dvp_dev->subdev.entity,
++ STF_DVP_PAD_SRC,
++ &vin_dev->line[VIN_LINE_WR].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->vin entities: %d\n",
++ dvp_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &csi_dev->subdev.entity,
++ STF_CSI_PAD_SRC,
++ &vin_dev->line[VIN_LINE_WR].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->vin entities: %d\n",
++ csi_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &csiphy_dev->subdev.entity,
++ STF_CSIPHY_PAD_SRC,
++ &csi_dev->subdev.entity,
++ STF_CSI_PAD_SINK,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ csiphy_dev->subdev.entity.name,
++ csi_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC,
++ &vin_dev->line[VIN_LINE_ISP].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_SS0,
++ &vin_dev->line[VIN_LINE_ISP_SS0].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_SS0]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_SS1,
++ &vin_dev->line[VIN_LINE_ISP_SS1].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_SS1]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++#ifndef STF_CAMSS_SKIP_ITI
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_ITIW,
++ &vin_dev->line[VIN_LINE_ISP_ITIW].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_ITIW]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_ITIR,
++ &vin_dev->line[VIN_LINE_ISP_ITIR].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_ITIR]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++#endif
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_RAW,
++ &vin_dev->line[VIN_LINE_ISP_RAW].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_RAW]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_SCD_Y,
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_SCD_Y]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &dvp_dev->subdev.entity,
++ STF_DVP_PAD_SRC,
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ dvp_dev->subdev.entity.name,
++ isp_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &csi_dev->subdev.entity,
++ STF_CSI_PAD_SRC,
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ csi_dev->subdev.entity.name,
++ isp_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ return ret;
++
++err_link:
++ stf_vin_unregister(stfcamss->vin_dev);
++err_reg_vin:
++ stf_isp_unregister(stfcamss->isp_dev);
++err_reg_isp:
++ stf_csi_unregister(stfcamss->csi_dev);
++err_reg_csi:
++ stf_csiphy_unregister(stfcamss->csiphy_dev);
++err_reg_csiphy:
++ stf_dvp_unregister(stfcamss->dvp_dev);
++err_reg_dvp:
++ return ret;
++}
++
++static void stfcamss_unregister_subdevices(struct stfcamss *stfcamss)
++{
++ stf_dvp_unregister(stfcamss->dvp_dev);
++ stf_csiphy_unregister(stfcamss->csiphy_dev);
++ stf_csi_unregister(stfcamss->csi_dev);
++ stf_isp_unregister(stfcamss->isp_dev);
++ stf_vin_unregister(stfcamss->vin_dev);
++}
++
++static int stfcamss_register_mediadevice_subdevnodes(
++ struct v4l2_async_notifier *async,
++ struct v4l2_subdev *sd)
++{
++ struct stfcamss *stfcamss =
++ container_of(async, struct stfcamss, notifier);
++ int ret;
++
++ if (sd->host_priv) {
++ struct media_entity *sensor = &sd->entity;
++ struct media_entity *input = sd->host_priv;
++ unsigned int i;
++
++ for (i = 0; i < sensor->num_pads; i++) {
++ if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
++ break;
++ }
++ if (i == sensor->num_pads) {
++ st_err(ST_CAMSS,
++ "No source pad in external entity\n");
++ return -EINVAL;
++ }
++
++ ret = media_create_pad_link(sensor, i,
++ input, STF_PAD_SINK,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ sensor->name, input->name, ret);
++ return ret;
++ }
++ }
++
++ ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
++ if (ret < 0)
++ return ret;
++
++ if (stfcamss->media_dev.devnode)
++ return ret;
++
++ st_debug(ST_CAMSS, "stfcamss register media device\n");
++ return media_device_register(&stfcamss->media_dev);
++}
++
++static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
++ struct v4l2_subdev *subdev,
++ struct v4l2_async_connection *asd)
++{
++ struct stfcamss *stfcamss =
++ container_of(async, struct stfcamss, notifier);
++ struct stfcamss_async_subdev *csd =
++ container_of(asd, struct stfcamss_async_subdev, asd);
++ enum port_num port = csd->port;
++ struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
++ struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
++
++ switch (port) {
++ case DVP_SENSOR_PORT_NUMBER:
++ dvp_dev->dvp = &csd->interface.dvp;
++ subdev->host_priv = &dvp_dev->subdev.entity;
++ break;
++ case CSI2RX_SENSOR_PORT_NUMBER:
++ csiphy_dev->csiphy = &csd->interface.csiphy;
++ subdev->host_priv = &csiphy_dev->subdev.entity;
++ break;
++ default:
++ break;
++ };
++
++ stfcamss_register_mediadevice_subdevnodes(async, subdev);
++
++ return 0;
++}
++
++#ifdef UNUSED_CODE
++static int stfcamss_subdev_notifier_complete(
++ struct v4l2_async_notifier *async)
++{
++ struct stfcamss *stfcamss =
++ container_of(async, struct stfcamss, notifier);
++ struct v4l2_device *v4l2_dev = &stfcamss->v4l2_dev;
++ struct v4l2_subdev *sd;
++ int ret;
++
++ list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
++ if (sd->host_priv) {
++ struct media_entity *sensor = &sd->entity;
++ struct media_entity *input = sd->host_priv;
++ unsigned int i;
++
++ for (i = 0; i < sensor->num_pads; i++) {
++ if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
++ break;
++ }
++ if (i == sensor->num_pads) {
++ st_err(ST_CAMSS,
++ "No source pad in external entity\n");
++ return -EINVAL;
++ }
++
++ ret = media_create_pad_link(sensor, i,
++ input, STF_PAD_SINK,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ sensor->name, input->name, ret);
++ return ret;
++ }
++ }
++ }
++
++ ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
++ if (ret < 0)
++ return ret;
++
++ return media_device_register(&stfcamss->media_dev);
++}
++#endif
++
++static const struct v4l2_async_notifier_operations
++stfcamss_subdev_notifier_ops = {
++ .bound = stfcamss_subdev_notifier_bound,
++};
++
++static const struct media_device_ops stfcamss_media_ops = {
++ .link_notify = v4l2_pipeline_link_notify,
++};
++
++#ifdef CONFIG_DEBUG_FS
++enum module_id {
++ VIN_MODULE = 0,
++ ISP_MODULE,
++ CSI_MODULE,
++ CSIPHY_MODULE,
++ DVP_MODULE,
++ CLK_MODULE,
++};
++
++static enum module_id id_num = ISP_MODULE;
++
++void dump_clk_reg(void __iomem *reg_base)
++{
++ int i;
++
++ st_info(ST_CAMSS, "DUMP Clk register:\n");
++ for (i = 0; i <= CLK_C_ISP_CTRL; i += 4)
++ print_reg(ST_CAMSS, reg_base, i);
++}
++
++static ssize_t vin_debug_read(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct device *dev = file->private_data;
++ void __iomem *reg_base;
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ struct stf_vin_dev *vin = stfcamss->vin;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++ struct stf_csi_dev *csi0_dev = stfcamss->csi_dev;
++
++ switch (id_num) {
++ case VIN_MODULE:
++ case CSIPHY_MODULE:
++ case DVP_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->sysctrl_base;
++ dump_vin_reg(reg_base);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ case ISP_MODULE:
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count > 0) {
++ reg_base = vin->isp_base;
++ dump_isp_reg(reg_base);
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++ break;
++ case CSI_MODULE:
++ mutex_lock(&csi0_dev->stream_lock);
++ if (csi0_dev->stream_count > 0) {
++ reg_base = vin->csi2rx_base;
++ dump_csi_reg(reg_base);
++ }
++ mutex_unlock(&csi0_dev->stream_lock);
++ break;
++ case CLK_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->clkgen_base;
++ dump_clk_reg(reg_base);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ default:
++ break;
++ }
++
++ return 0;
++}
++
++static void set_reg_val(struct stfcamss *stfcamss, int id, u32 offset, u32 val)
++{
++ struct stf_vin_dev *vin = stfcamss->vin;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++ struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
++ void __iomem *reg_base;
++
++ switch (id) {
++ case VIN_MODULE:
++ case CSIPHY_MODULE:
++ case DVP_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->sysctrl_base;
++ print_reg(ST_VIN, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_VIN, reg_base, offset);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ case ISP_MODULE:
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count > 0) {
++ reg_base = vin->isp_base;
++ print_reg(ST_ISP, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_ISP, reg_base, offset);
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++ break;
++ case CSI_MODULE:
++ mutex_lock(&csi_dev->stream_lock);
++ if (csi_dev->stream_count > 0) {
++ reg_base = vin->csi2rx_base;
++ print_reg(ST_CSI, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_CSI, reg_base, offset);
++ }
++ mutex_unlock(&csi_dev->stream_lock);
++ break;
++ case CLK_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->clkgen_base;
++ print_reg(ST_CAMSS, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_CAMSS, reg_base, offset);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ default:
++ break;
++
++ }
++}
++
++static u32 atoi(const char *s)
++{
++ u32 ret = 0, d = 0;
++ char ch;
++ int hex = 0;
++
++ if ((*s == '0') && (*(s+1) == 'x')) {
++ hex = 1;
++ s += 2;
++ }
++
++ while (1) {
++ if (!hex) {
++ d = (*s++) - '0';
++ if (d > 9)
++ break;
++ ret *= 10;
++ ret += d;
++ } else {
++ ch = tolower(*s++);
++ if (isdigit(ch))
++ d = ch - '0';
++ else if (islower(ch))
++ d = ch - 'a' + 10;
++ else
++ break;
++ if (d > 15)
++ break;
++ ret *= 16;
++ ret += d;
++ }
++ }
++
++ return ret;
++}
++
++static ssize_t vin_debug_write(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct device *dev = file->private_data;
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ char *buf;
++ char *line;
++ char *p;
++ static const char *delims = " \t\r";
++ char *token;
++ u32 offset, val;
++
++ buf = memdup_user_nul(user_buf, min_t(size_t, PAGE_SIZE, count));
++ if (IS_ERR(buf))
++ return PTR_ERR(buf);
++ p = buf;
++ st_debug(ST_CAMSS, "dup buf: %s, len: %lu, count: %lu\n", p, strlen(p), count);
++ while (p && *p) {
++ p = skip_spaces(p);
++ line = strsep(&p, "\n");
++ if (!*line || *line == '#')
++ break;
++ token = strsep(&line, delims);
++ if (!token)
++ goto out;
++ id_num = atoi(token);
++ token = strsep(&line, delims);
++ if (!token)
++ goto out;
++ offset = atoi(token);
++ token = strsep(&line, delims);
++ if (!token)
++ goto out;
++ val = atoi(token);
++ }
++ set_reg_val(stfcamss, id_num, offset, val);
++out:
++ kfree(buf);
++ st_info(ST_CAMSS, "id_num = %d, offset = 0x%x, 0x%x\n", id_num, offset, val);
++ return count;
++}
++
++static const struct file_operations vin_debug_fops = {
++ .open = simple_open,
++ .read = vin_debug_read,
++ .write = vin_debug_write,
++};
++#endif /* CONFIG_DEBUG_FS */
++
++
++static int stfcamss_probe(struct platform_device *pdev)
++{
++ struct stfcamss *stfcamss;
++ struct stf_vin_dev *vin;
++ struct device *dev = &pdev->dev;
++ struct of_phandle_args args;
++ int ret = 0, num_subdevs;
++
++ dev_info(dev, "stfcamss probe enter!\n");
++
++ stfcamss = devm_kzalloc(dev, sizeof(struct stfcamss), GFP_KERNEL);
++ if (!stfcamss)
++ return -ENOMEM;
++
++ stfcamss->dvp_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->dvp_dev), GFP_KERNEL);
++ if (!stfcamss->dvp_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->csiphy_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->csiphy_dev),
++ GFP_KERNEL);
++ if (!stfcamss->csiphy_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->csi_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->csi_dev),
++ GFP_KERNEL);
++ if (!stfcamss->csi_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->isp_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->isp_dev),
++ GFP_KERNEL);
++ if (!stfcamss->isp_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->vin_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->vin_dev),
++ GFP_KERNEL);
++ if (!stfcamss->vin_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->vin = devm_kzalloc(dev,
++ sizeof(struct stf_vin_dev),
++ GFP_KERNEL);
++ if (!stfcamss->vin) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ vin = stfcamss->vin;
++
++ vin->irq = platform_get_irq(pdev, 0);
++ if (vin->irq <= 0) {
++ st_err(ST_CAMSS, "Could not get irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_irq = platform_get_irq(pdev, 1);
++ if (vin->isp_irq <= 0) {
++ st_err(ST_CAMSS, "Could not get isp irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_csi_irq = platform_get_irq(pdev, 2);
++ if (vin->isp_csi_irq <= 0) {
++ st_err(ST_CAMSS, "Could not get isp csi irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_scd_irq = platform_get_irq(pdev, 3);
++ if (vin->isp_scd_irq <= 0) {
++ st_err(ST_CAMSS, "Could not get isp scd irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_irq_csiline = platform_get_irq(pdev, 4);
++ if (vin->isp_irq_csiline <= 0) {
++ st_err(ST_CAMSS, "Could not get isp irq csiline\n");
++ goto err_cam;
++ }
++
++ pm_runtime_enable(dev);
++
++ stfcamss->nclks = ARRAY_SIZE(stfcamss_clocks);
++ stfcamss->sys_clk = stfcamss_clocks;
++
++ ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
++ if (ret) {
++ st_err(ST_CAMSS, "Failed to get clk controls\n");
++ return ret;
++ }
++
++ stfcamss->nrsts = ARRAY_SIZE(stfcamss_resets);
++ stfcamss->sys_rst = stfcamss_resets;
++
++ ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
++ stfcamss->sys_rst);
++ if (ret) {
++ st_err(ST_CAMSS, "Failed to get reset controls\n");
++ return ret;
++ }
++
++ ret = of_parse_phandle_with_fixed_args(dev->of_node,
++ "starfive,aon-syscon", 1, 0, &args);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to parse starfive,aon-syscon\n");
++ return -EINVAL;
++ }
++
++ stfcamss->stf_aon_syscon = syscon_node_to_regmap(args.np);
++ of_node_put(args.np);
++ if (IS_ERR(stfcamss->stf_aon_syscon))
++ return PTR_ERR(stfcamss->stf_aon_syscon);
++
++ stfcamss->aon_gp_reg = args.args[0];
++
++ ret = stfcamss_get_mem_res(pdev, vin);
++ if (ret) {
++ st_err(ST_CAMSS, "Could not map registers\n");
++ goto err_cam;
++ }
++
++ ret = vin_parse_dt(dev, vin);
++ if (ret)
++ goto err_cam;
++
++ vin->dev = dev;
++ stfcamss->dev = dev;
++ platform_set_drvdata(pdev, stfcamss);
++
++ v4l2_async_nf_init(&stfcamss->notifier, &stfcamss->v4l2_dev);
++
++ num_subdevs = stfcamss_of_parse_ports(stfcamss);
++ if (num_subdevs < 0) {
++ ret = num_subdevs;
++ goto err_cam_noti;
++ }
++
++ ret = stfcamss_init_subdevices(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to init subdevice: %d\n", ret);
++ goto err_cam_noti;
++ }
++
++ stfcamss->media_dev.dev = stfcamss->dev;
++ strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
++ sizeof(stfcamss->media_dev.model));
++ strscpy(stfcamss->media_dev.serial, "0123456789ABCDEF",
++ sizeof(stfcamss->media_dev.serial));
++ snprintf(stfcamss->media_dev.bus_info, sizeof(stfcamss->media_dev.bus_info),
++ "%s:%s", dev_bus_name(dev), pdev->name);
++ stfcamss->media_dev.hw_revision = 0x01;
++ stfcamss->media_dev.ops = &stfcamss_media_ops;
++ media_device_init(&stfcamss->media_dev);
++
++ stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
++
++ ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to register V4L2 device: %d\n", ret);
++ goto err_cam_noti_med;
++ }
++
++ ret = stfcamss_register_subdevices(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to register subdevice: %d\n", ret);
++ goto err_cam_noti_med_vreg;
++ }
++
++ if (num_subdevs) {
++ stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
++ ret = v4l2_async_nf_register(&stfcamss->notifier);
++ if (ret) {
++ st_err(ST_CAMSS,
++ "Failed to register async subdev nodes: %d\n",
++ ret);
++ goto err_cam_noti_med_vreg_sub;
++ }
++ } else {
++ ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register subdev nodes: %d\n",
++ ret);
++ goto err_cam_noti_med_vreg_sub;
++ }
++
++ ret = media_device_register(&stfcamss->media_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to register media device: %d\n",
++ ret);
++ goto err_cam_noti_med_vreg_sub_medreg;
++ }
++ }
++
++#ifdef CONFIG_DEBUG_FS
++ stfcamss->debugfs_entry = debugfs_create_dir("stfcamss", NULL);
++ stfcamss->vin_debugfs = debugfs_create_file("stf_vin",
++ 0644, stfcamss->debugfs_entry,
++ (void *)dev, &vin_debug_fops);
++ debugfs_create_u32("dbg_level",
++ 0644, stfcamss->debugfs_entry,
++ &stdbg_level);
++ debugfs_create_u32("dbg_mask",
++ 0644, stfcamss->debugfs_entry,
++ &stdbg_mask);
++#endif
++ dev_info(dev, "stfcamss probe success!\n");
++
++ return 0;
++
++#ifdef CONFIG_DEBUG_FS
++ debugfs_remove(stfcamss->vin_debugfs);
++ debugfs_remove_recursive(stfcamss->debugfs_entry);
++ stfcamss->debugfs_entry = NULL;
++#endif
++
++err_cam_noti_med_vreg_sub_medreg:
++err_cam_noti_med_vreg_sub:
++ stfcamss_unregister_subdevices(stfcamss);
++err_cam_noti_med_vreg:
++ v4l2_device_unregister(&stfcamss->v4l2_dev);
++err_cam_noti_med:
++ media_device_cleanup(&stfcamss->media_dev);
++err_cam_noti:
++ v4l2_async_nf_cleanup(&stfcamss->notifier);
++err_cam:
++ // kfree(stfcamss);
++ return ret;
++}
++
++static int stfcamss_remove(struct platform_device *pdev)
++{
++ struct stfcamss *stfcamss = platform_get_drvdata(pdev);
++
++ dev_info(&pdev->dev, "remove done\n");
++
++#ifdef CONFIG_DEBUG_FS
++ debugfs_remove(stfcamss->vin_debugfs);
++ debugfs_remove_recursive(stfcamss->debugfs_entry);
++ stfcamss->debugfs_entry = NULL;
++#endif
++
++ stfcamss_unregister_subdevices(stfcamss);
++ v4l2_device_unregister(&stfcamss->v4l2_dev);
++ media_device_cleanup(&stfcamss->media_dev);
++ pm_runtime_disable(&pdev->dev);
++
++ kfree(stfcamss);
++
++ return 0;
++}
++
++static const struct of_device_id stfcamss_of_match[] = {
++ { .compatible = "starfive,jh7110-vin" },
++ { /* end node */ },
++};
++
++MODULE_DEVICE_TABLE(of, stfcamss_of_match);
++
++#ifdef CONFIG_PM_SLEEP
++static int stfcamss_suspend(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++ struct stfcamss_video *video;
++ struct video_device *vdev;
++ int i = 0;
++ int pm_power_count;
++ int pm_stream_count;
++
++ for (i = 0; i < VIN_LINE_MAX; i++) {
++ video = &vin_dev->line[i].video_out;
++ vdev = &vin_dev->line[i].video_out.vdev;
++ vin_dev->line[i].pm_power_count = vin_dev->line[i].power_count;
++ vin_dev->line[i].pm_stream_count = vin_dev->line[i].stream_count;
++ pm_power_count = vin_dev->line[i].pm_power_count;
++ pm_stream_count = vin_dev->line[i].pm_stream_count;
++
++ if (pm_stream_count) {
++ while (pm_stream_count--) {
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ v4l2_subdev_call(subdev, video, s_stream, 0);
++ }
++ }
++ video_device_pipeline_stop(vdev);
++ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
++ }
++
++ if (!pm_power_count)
++ continue;
++
++ v4l2_pipeline_pm_put(&vdev->entity);
++ }
++
++ return pm_runtime_force_suspend(dev);
++}
++
++static int stfcamss_resume(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++ struct stfcamss_video *video;
++ struct video_device *vdev;
++ int i = 0;
++ int pm_power_count;
++ int pm_stream_count;
++ int ret = 0;
++
++ pm_runtime_force_resume(dev);
++
++ for (i = 0; i < VIN_LINE_MAX; i++) {
++ video = &vin_dev->line[i].video_out;
++ vdev = &vin_dev->line[i].video_out.vdev;
++ pm_power_count = vin_dev->line[i].pm_power_count;
++ pm_stream_count = vin_dev->line[i].pm_stream_count;
++
++ if (!pm_power_count)
++ continue;
++
++ ret = v4l2_pipeline_pm_get(&vdev->entity);
++ if (ret < 0)
++ goto err;
++
++ if (pm_stream_count) {
++ ret = video_device_pipeline_start(vdev, &video->stfcamss->pipe);
++ if (ret < 0)
++ goto err_pm_put;
++
++ while (pm_stream_count--) {
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, video, s_stream, 1);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ goto err_pipeline_stop;
++ }
++ }
++ }
++ }
++
++ return 0;
++
++err_pipeline_stop:
++ video_device_pipeline_stop(vdev);
++err_pm_put:
++ v4l2_pipeline_pm_put(&vdev->entity);
++err:
++ return ret;
++}
++#endif /* CONFIG_PM_SLEEP */
++
++#ifdef CONFIG_PM
++static int stfcamss_runtime_suspend(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_ISP_TOP_AXI].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_ISP_TOP_N].rstc);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_ISP_AXI].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_ISPCORE_2X].clk);
++
++ return 0;
++}
++
++static int stfcamss_runtime_resume(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_ISPCORE_2X].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_ISP_AXI].clk);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_ISP_TOP_N].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_ISP_TOP_AXI].rstc);
++
++ return 0;
++}
++#endif /* CONFIG_PM */
++
++static const struct dev_pm_ops stfcamss_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(stfcamss_suspend, stfcamss_resume)
++ SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend, stfcamss_runtime_resume, NULL)
++};
++
++static struct platform_driver stfcamss_driver = {
++ .probe = stfcamss_probe,
++ .remove = stfcamss_remove,
++ .driver = {
++ .name = DRV_NAME,
++ .pm = &stfcamss_pm_ops,
++ .of_match_table = of_match_ptr(stfcamss_of_match),
++ },
++};
++
++static int __init stfcamss_init(void)
++{
++ return platform_driver_register(&stfcamss_driver);
++}
++
++static void __exit stfcamss_cleanup(void)
++{
++ platform_driver_unregister(&stfcamss_driver);
++}
++
++module_init(stfcamss_init);
++//fs_initcall(stfcamss_init);
++module_exit(stfcamss_cleanup);
++
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stfcamss.h
+@@ -0,0 +1,117 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STFCAMSS_H
++#define STFCAMSS_H
++
++#include <linux/io.h>
++#include <linux/delay.h>
++#include <linux/reset.h>
++#include <linux/clk.h>
++
++enum sensor_type {
++ SENSOR_VIN,
++ /* need replace sensor */
++ SENSOR_ISP,
++};
++
++enum subdev_type {
++ VIN_DEV_TYPE,
++ ISP_DEV_TYPE,
++};
++
++#include "stf_common.h"
++#include "stf_dvp.h"
++#include "stf_csi.h"
++#include "stf_csiphy.h"
++#include "stf_isp.h"
++#include "stf_vin.h"
++
++#define STF_PAD_SINK 0
++#define STF_PAD_SRC 1
++#define STF_PADS_NUM 2
++
++#define STF_CAMSS_SKIP_ITI
++
++enum port_num {
++ DVP_SENSOR_PORT_NUMBER = 0,
++ CSI2RX_SENSOR_PORT_NUMBER
++};
++
++enum stf_clk_num {
++ STFCLK_APB_FUNC = 0,
++ STFCLK_PCLK,
++ STFCLK_SYS_CLK,
++ STFCLK_WRAPPER_CLK_C,
++ STFCLK_DVP_INV,
++ STFCLK_AXIWR,
++ STFCLK_MIPI_RX0_PXL,
++ STFCLK_PIXEL_CLK_IF0,
++ STFCLK_PIXEL_CLK_IF1,
++ STFCLK_PIXEL_CLK_IF2,
++ STFCLK_PIXEL_CLK_IF3,
++ STFCLK_M31DPHY_CFGCLK_IN,
++ STFCLK_M31DPHY_REFCLK_IN,
++ STFCLK_M31DPHY_TXCLKESC_LAN0,
++ STFCLK_ISPCORE_2X,
++ STFCLK_ISP_AXI,
++ STFCLK_NUM
++};
++
++enum stf_rst_num {
++ STFRST_WRAPPER_P = 0,
++ STFRST_WRAPPER_C,
++ STFRST_PCLK,
++ STFRST_SYS_CLK,
++ STFRST_AXIRD,
++ STFRST_AXIWR,
++ STFRST_PIXEL_CLK_IF0,
++ STFRST_PIXEL_CLK_IF1,
++ STFRST_PIXEL_CLK_IF2,
++ STFRST_PIXEL_CLK_IF3,
++ STFRST_M31DPHY_HW,
++ STFRST_M31DPHY_B09_ALWAYS_ON,
++ STFRST_ISP_TOP_N,
++ STFRST_ISP_TOP_AXI,
++ STFRST_NUM
++};
++
++struct stfcamss {
++ struct stf_vin_dev *vin; // stfcamss phy res
++ struct v4l2_device v4l2_dev;
++ struct media_device media_dev;
++ struct media_pipeline pipe;
++ struct device *dev;
++ struct stf_vin2_dev *vin_dev; // subdev
++ struct stf_dvp_dev *dvp_dev; // subdev
++ struct stf_csi_dev *csi_dev; // subdev
++ struct stf_csiphy_dev *csiphy_dev; // subdev
++ struct stf_isp_dev *isp_dev; // subdev
++ struct v4l2_async_notifier notifier;
++ struct clk_bulk_data *sys_clk;
++ int nclks;
++ struct reset_control_bulk_data *sys_rst;
++ int nrsts;
++ struct regmap *stf_aon_syscon;
++ uint32_t aon_gp_reg;
++#ifdef CONFIG_DEBUG_FS
++ struct dentry *debugfs_entry;
++ struct dentry *vin_debugfs;
++#endif
++};
++
++struct stfcamss_async_subdev {
++ struct v4l2_async_connection asd; // must be first
++ enum port_num port;
++ struct {
++ struct dvp_cfg dvp;
++ struct csi2phy_cfg csiphy;
++ } interface;
++};
++
++extern struct media_entity *stfcamss_find_sensor(struct media_entity *entity);
++
++#endif /* STFCAMSS_H */
+--- /dev/null
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -0,0 +1,253 @@
++/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
++/*
++ * jh7110-isp.h
++ *
++ * JH7110 ISP driver - user space header file.
++ *
++ * Copyright © 2023 Starfive Technology Co., Ltd.
++ *
++ * Author: Su Zejian (zejian.su@starfivetech.com)
++ *
++ */
++
++#ifndef __JH7110_ISP_H_
++#define __JH7110_ISP_H_
++
++#include <linux/v4l2-controls.h>
++
++#define V4L2_CID_USER_JH7110_ISP_WB_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0001)
++#define V4L2_CID_USER_JH7110_ISP_CAR_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0002)
++#define V4L2_CID_USER_JH7110_ISP_CCM_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0003)
++#define V4L2_CID_USER_JH7110_ISP_CFA_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0004)
++#define V4L2_CID_USER_JH7110_ISP_CTC_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0005)
++#define V4L2_CID_USER_JH7110_ISP_DBC_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0006)
++#define V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0007)
++#define V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0008)
++#define V4L2_CID_USER_JH7110_ISP_LCCF_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0009)
++#define V4L2_CID_USER_JH7110_ISP_OBC_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000a)
++#define V4L2_CID_USER_JH7110_ISP_OECF_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000b)
++#define V4L2_CID_USER_JH7110_ISP_R2Y_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000c)
++#define V4L2_CID_USER_JH7110_ISP_SAT_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000d)
++#define V4L2_CID_USER_JH7110_ISP_SHRP_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000e)
++#define V4L2_CID_USER_JH7110_ISP_YCRV_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000f)
++
++struct jh7110_isp_wb_gain {
++ __u16 gain_r;
++ __u16 gain_g;
++ __u16 gain_b;
++};
++
++struct jh7110_isp_wb_setting {
++ __u32 enabled;
++ struct jh7110_isp_wb_gain gains;
++};
++
++struct jh7110_isp_car_setting {
++ __u32 enabled;
++};
++
++struct jh7110_isp_ccm_smlow {
++ __s32 ccm[3][3];
++ __s32 offsets[3];
++};
++
++struct jh7110_isp_ccm_setting {
++ __u32 enabled;
++ struct jh7110_isp_ccm_smlow ccm_smlow;
++};
++
++struct jh7110_isp_cfa_params {
++ __s32 hv_width;
++ __s32 cross_cov;
++};
++
++struct jh7110_isp_cfa_setting {
++ __u32 enabled;
++ struct jh7110_isp_cfa_params settings;
++};
++
++struct jh7110_isp_ctc_params {
++ __u8 saf_mode;
++ __u8 daf_mode;
++ __s32 max_gt;
++ __s32 min_gt;
++};
++
++struct jh7110_isp_ctc_setting {
++ __u32 enabled;
++ struct jh7110_isp_ctc_params settings;
++};
++
++struct jh7110_isp_dbc_params {
++ __s32 bad_gt;
++ __s32 bad_xt;
++};
++
++struct jh7110_isp_dbc_setting {
++ __u32 enabled;
++ struct jh7110_isp_dbc_params settings;
++};
++
++struct jh7110_isp_dnyuv_params {
++ __u8 y_sweight[10];
++ __u16 y_curve[7];
++ __u8 uv_sweight[10];
++ __u16 uv_curve[7];
++};
++
++struct jh7110_isp_dnyuv_setting {
++ __u32 enabled;
++ struct jh7110_isp_dnyuv_params settings;
++};
++
++struct jh7110_isp_gmargb_point {
++ __u16 g_val;
++ __u16 sg_val;
++};
++
++struct jh7110_isp_gmargb_setting {
++ __u32 enabled;
++ struct jh7110_isp_gmargb_point curve[15];
++};
++
++struct jh7110_isp_lccf_circle {
++ __s16 center_x;
++ __s16 center_y;
++ __u8 radius;
++};
++
++struct jh7110_isp_lccf_curve_param {
++ __s16 f1;
++ __s16 f2;
++};
++
++struct jh7110_isp_lccf_setting {
++ __u32 enabled;
++ struct jh7110_isp_lccf_circle circle;
++ struct jh7110_isp_lccf_curve_param r_param;
++ struct jh7110_isp_lccf_curve_param gr_param;
++ struct jh7110_isp_lccf_curve_param gb_param;
++ struct jh7110_isp_lccf_curve_param b_param;
++};
++
++struct jh7110_isp_blacklevel_win_size {
++ __u32 width;
++ __u32 height;
++};
++
++struct jh7110_isp_blacklevel_gain {
++ __u8 tl_gain;
++ __u8 tr_gain;
++ __u8 bl_gain;
++ __u8 br_gain;
++};
++
++struct jh7110_isp_blacklevel_offset {
++ __u8 tl_offset;
++ __u8 tr_offset;
++ __u8 bl_offset;
++ __u8 br_offset;
++};
++
++struct jh7110_isp_blacklevel_setting {
++ __u32 enabled;
++ struct jh7110_isp_blacklevel_win_size win_size;
++ struct jh7110_isp_blacklevel_gain gain[4];
++ struct jh7110_isp_blacklevel_offset offset[4];
++};
++
++struct jh7110_isp_oecf_point {
++ __u16 x;
++ __u16 y;
++ __s16 slope;
++};
++
++struct jh7110_isp_oecf_setting {
++ __u32 enabled;
++ struct jh7110_isp_oecf_point r_curve[16];
++ struct jh7110_isp_oecf_point gr_curve[16];
++ struct jh7110_isp_oecf_point gb_curve[16];
++ struct jh7110_isp_oecf_point b_curve[16];
++};
++
++struct jh7110_isp_r2y_matrix {
++ __s16 m[9];
++};
++
++struct jh7110_isp_r2y_setting {
++ __u32 enabled;
++ struct jh7110_isp_r2y_matrix matrix;
++};
++
++struct jh7110_isp_sat_curve {
++ __s16 yi_min;
++ __s16 yo_ir;
++ __s16 yo_min;
++ __s16 yo_max;
++};
++
++struct jh7110_isp_sat_hue_info {
++ __s16 sin;
++ __s16 cos;
++};
++
++struct jh7110_isp_sat_info {
++ __s16 gain_cmab;
++ __s16 gain_cmad;
++ __s16 threshold_cmb;
++ __s16 threshold_cmd;
++ __s16 offset_u;
++ __s16 offset_v;
++ __s16 cmsf;
++};
++
++struct jh7110_isp_sat_setting {
++ __u32 enabled;
++ struct jh7110_isp_sat_curve curve;
++ struct jh7110_isp_sat_hue_info hue_info;
++ struct jh7110_isp_sat_info sat_info;
++};
++
++struct jh7110_isp_sharp_weight {
++ __u8 weight[15];
++ __u32 recip_wei_sum;
++};
++
++struct jh7110_isp_sharp_strength {
++ __s16 diff[4];
++ __s16 f[4];
++};
++
++struct jh7110_isp_sharp_setting {
++ __u32 enabled;
++ struct jh7110_isp_sharp_weight weight;
++ struct jh7110_isp_sharp_strength strength;
++ __s8 pdirf;
++ __s8 ndirf;
++};
++
++struct jh7110_isp_ycrv_curve {
++ __s16 y[64];
++};
++
++struct jh7110_isp_ycrv_setting {
++ __u32 enabled;
++ struct jh7110_isp_ycrv_curve curve;
++};
++
++#endif
+--- a/include/uapi/linux/v4l2-controls.h
++++ b/include/uapi/linux/v4l2-controls.h
+@@ -203,6 +203,12 @@ enum v4l2_colorfx {
+ */
+ #define V4L2_CID_USER_ASPEED_BASE (V4L2_CID_USER_BASE + 0x11a0)
+
++/*
++ * The base for the jh7110-isp driver controls.
++ * We reserve 16 controls for this driver.
++ */
++#define V4L2_CID_USER_JH7110_ISP_BASE (V4L2_CID_USER_BASE + 0x1170)
++
+ /* MPEG-class control IDs */
+ /* The MPEG controls are applicable to all codec controls
+ * and the 'MPEG' part of the define is historical */
+--- /dev/null
++++ b/include/video/stf-vin.h
+@@ -0,0 +1,443 @@
++/* include/video/stf-vin.h
++ *
++ * Copyright 2020 starfive tech.
++ * Eric Tang <eric.tang@starfivetech.com>
++ *
++ * Generic vin notifier interface
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++*/
++#ifndef _VIDEO_VIN_H
++#define _VIDEO_VIN_H
++
++#include <linux/cdev.h>
++
++#define DRV_NAME "jh7110-vin"
++#define FB_FIRST_ADDR 0xf9000000
++#define FB_SECOND_ADDR 0xf97e9000
++
++#define RESERVED_MEM_SIZE 0x1000000
++
++#define VIN_MIPI_CONTROLLER0_OFFSET 0x00000
++#define VIN_CLKGEN_OFFSET 0x10000
++#define VIN_RSTGEN_OFFSET 0x20000
++#define VIN_MIPI_CONTROLLER1_OFFSET 0x30000
++#define VIN_SYSCONTROLLER_OFFSET 0x40000
++
++#define VD_1080P 1080
++#define VD_720P 720
++#define VD_PAL 480
++
++#define VD_HEIGHT_1080P VD_1080P
++#define VD_WIDTH_1080P 1920
++
++#define VD_HEIGHT_720P VD_720P
++#define VD_WIDTH_720P 1080
++
++#define VD_HEIGHT_480 480
++#define VD_WIDTH_640 640
++
++#define SEEED_WIDTH_800 800
++#define SEEED_HIGH_480 480
++
++#define VIN_TOP_CLKGEN_BASE_ADDR 0x11800000
++#define VIN_TOP_RSTGEN_BASE_ADDR 0x11840000
++#define VIN_TOP_IOPAD_BASE_ADDR 0x11858000
++
++#define ISP_BASE_MIPI0_ADDR 0x19800000
++#define ISP_BASE_CLKGEN_ADDR 0x19810000
++#define ISP_BASE_RSTGEN_ADDR 0x19820000
++#define ISP_BASE_MIPI1_ADDR 0x19830000
++#define ISP_BASE_SYSCTRL_ADDR 0x19840000
++#define ISP_BASE_ISP0_ADDR 0x19870000
++#define ISP_BASE_ISP1_ADDR 0x198a0000
++
++
++//vin clk registers
++#define CLK_VIN_SRC_CTRL 0x188
++#define CLK_ISP0_AXI_CTRL 0x190
++#define CLK_ISP0NOC_AXI_CTRL 0x194
++#define CLK_ISPSLV_AXI_CTRL 0x198
++#define CLK_ISP1_AXI_CTRL 0x1A0
++#define CLK_ISP1NOC_AXI_CTRL 0x1A4
++#define CLK_VIN_AXI 0x1AC
++#define CLK_VINNOC_AXI 0x1B0
++
++
++#define CLK_DOM4_APB_FUNC 0x0
++#define CLK_MUX_SEL 0xffffff
++
++#define CLK_MIPI_RX0_PXL 0x4
++
++#define CLK_DVP_INV 0x8
++#define CLK_U0_VIN_PCLK 0x18
++#define CLK_U0_VIN_PCLK_ICG (0x1<<31)
++
++#define CLK_U0_VIN_SYS_CLK 0x1c
++#define CLK_U0_VIN_CLK_P_AXIWR 0x30
++#define CLK_U0_VIN_MUX_SEL (BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28) | BIT(29))
++
++#define CLK_U0_VIN_PIXEL_CLK_IF0 0x20
++#define CLK_U0_VIN_PIXEL_CLK_IF1 0x24
++#define CLK_U0_VIN_PIXEL_CLK_IF2 0x28
++#define CLK_U0_VIN_PIXEL_CLK_IF3 0x2c
++
++#define CLK_U0_VIN_CLK_P_AXIWR 0x30
++
++#define CLK_U0_ISPV2_TOP_WRAPPER_CLK_C 0x34u
++#define CLK_U0_ISPV2_MUX_SEL (0x1<<24 | 0x1<<25 | 0x1<<26 | 0x1<<27 | 0x1<<28 | 0x1<< 29)
++
++#define CLK_U0_ISPV2_CLK_ICG (0x1<<31)
++
++#define SOFTWARE_RESET_ASSERT0_ASSERT_SET 0x38U
++#define SOFTWARE_RESET_ASSERT0_ASSERT_SET_STATE 0x3CU
++#define RST_U0_ISPV2_TOP_WRAPPER_RST_P BIT(0)
++#define RST_U0_ISPV2_TOP_WRAPPER_RST_C BIT(1)
++#define RSTN_U0_VIN_RST_N_PCLK BIT(4)
++#define RSTN_U0_VIN_RST_N_SYS_CLK BIT(9)
++#define RSTN_U0_VIN_RST_P_AXIRD BIT(10)
++#define RSTN_U0_VIN_RST_P_AXIWR BIT(11)
++
++
++#define CLK_POLARITY (0x1<<30)
++
++#define M31DPHY_APBCFGSAIF__SYSCFG_0 0x0
++#define M31DPHY_APBCFGSAIF__SYSCFG_4 0x4
++#define M31DPHY_APBCFGSAIF__SYSCFG_8 0x8
++#define M31DPHY_APBCFGSAIF__SYSCFG_12 0xc
++#define M31DPHY_APBCFGSAIF__SYSCFG_16 0x10
++#define M31DPHY_APBCFGSAIF__SYSCFG_20 0x14
++#define M31DPHY_APBCFGSAIF__SYSCFG_24 0x18
++#define M31DPHY_APBCFGSAIF__SYSCFG_28 0x1c
++#define M31DPHY_APBCFGSAIF__SYSCFG_32 0x20
++#define M31DPHY_APBCFGSAIF__SYSCFG_36 0x24
++#define M31DPHY_APBCFGSAIF__SYSCFG_40 0x28
++#define M31DPHY_APBCFGSAIF__SYSCFG_44 0x2c
++#define M31DPHY_APBCFGSAIF__SYSCFG_48 0x30
++#define M31DPHY_APBCFGSAIF__SYSCFG_52 0x34
++#define M31DPHY_APBCFGSAIF__SYSCFG_56 0x38
++#define M31DPHY_APBCFGSAIF__SYSCFG_60 0x3c
++#define M31DPHY_APBCFGSAIF__SYSCFG_64 0x40
++#define M31DPHY_APBCFGSAIF__SYSCFG_68 0x44
++#define M31DPHY_APBCFGSAIF__SYSCFG_72 0x48
++#define M31DPHY_APBCFGSAIF__SYSCFG_76 0x4c
++#define M31DPHY_APBCFGSAIF__SYSCFG_80 0x50
++#define M31DPHY_APBCFGSAIF__SYSCFG_84 0x54
++#define M31DPHY_APBCFGSAIF__SYSCFG_88 0x58
++#define M31DPHY_APBCFGSAIF__SYSCFG_92 0x5c
++#define M31DPHY_APBCFGSAIF__SYSCFG_96 0x60
++#define M31DPHY_APBCFGSAIF__SYSCFG_100 0x64
++#define M31DPHY_APBCFGSAIF__SYSCFG_104 0x68
++#define M31DPHY_APBCFGSAIF__SYSCFG_108 0x6c
++#define M31DPHY_APBCFGSAIF__SYSCFG_112 0x70
++#define M31DPHY_APBCFGSAIF__SYSCFG_116 0x74
++#define M31DPHY_APBCFGSAIF__SYSCFG_120 0x78
++#define M31DPHY_APBCFGSAIF__SYSCFG_124 0x7c
++#define M31DPHY_APBCFGSAIF__SYSCFG_128 0x80
++#define M31DPHY_APBCFGSAIF__SYSCFG_132 0x84
++#define M31DPHY_APBCFGSAIF__SYSCFG_136 0x88
++#define M31DPHY_APBCFGSAIF__SYSCFG_140 0x8c
++#define M31DPHY_APBCFGSAIF__SYSCFG_144 0x90
++#define M31DPHY_APBCFGSAIF__SYSCFG_184 0xb8
++
++//pmu registers
++#define SW_DEST_POWER_ON 0x0C
++#define SW_DEST_POWER_OFF 0x10
++#define SW_ENCOURAGE 0x44
++
++
++//isp clk registers
++#define CLK_DPHY_CFGCLK_ISPCORE_2X_CTRL 0x00
++#define CLK_DPHY_REFCLK_ISPCORE_2X_CTRL 0x04
++#define CLK_DPHY_TXCLKESC_IN_CTRL 0x08
++#define CLK_MIPI_RX0_PXL_CTRL 0x0c
++#define CLK_MIPI_RX1_PXL_CTRL 0x10
++#define CLK_MIPI_RX0_PXL_0_CTRL 0X14
++#define CLK_MIPI_RX0_PXL_1_CTRL 0X18
++#define CLK_MIPI_RX0_PXL_2_CTRL 0X1C
++#define CLK_MIPI_RX0_PXL_3_CTRL 0X20
++#define CLK_MIPI_RX0_SYS0_CTRL 0x24
++#define CLK_MIPI_RX1_PXL_0_CTRL 0X28
++#define CLK_MIPI_RX1_PXL_1_CTRL 0X2C
++#define CLK_MIPI_RX1_PXL_2_CTRL 0X30
++#define CLK_MIPI_RX1_PXL_3_CTRL 0X34
++#define CLK_MIPI_RX1_SYS1_CTRL 0x38
++#define CLK_ISP_CTRL 0x3c
++#define CLK_ISP_2X_CTRL 0x40
++#define CLK_ISP_MIPI_CTRL 0x44
++#define CLK_C_ISP_CTRL 0x64
++#define CLK_CSI2RX0_APB_CTRL 0x58
++
++
++#define CLK_VIN_AXI_WR_CTRL 0x5C
++
++#define SOFTWARE_RESET_ASSERT0 0x0
++#define SOFTWARE_RESET_ASSERT1 0x4
++#define SOFTWARE_RESET_STATUS 0x4
++
++#define IOPAD_REG81 0x144
++#define IOPAD_REG82 0x148
++#define IOPAD_REG83 0x14C
++#define IOPAD_REG84 0x150
++#define IOPAD_REG85 0x154
++#define IOPAD_REG86 0x158
++#define IOPAD_REG87 0x15C
++#define IOPAD_REG88 0x160
++#define IOPAD_REG89 0x164
++
++//sys control REG DEFINE
++#define SYSCONSAIF_SYSCFG_0 0X0
++#define U0_VIN_SCFG_SRAM_CONFIG (BIT(0) | BIT(1))
++
++#define SYSCONSAIF_SYSCFG_4 0x4
++#define U0_VIN_CNFG_AXIRD_END_ADDR 0xffffffff
++#define SYSCONSAIF_SYSCFG_8 0x8
++#define U0_VIN_CNFG_AXIRD_LINE_CNT_END (BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13))
++#define U0_VIN_CNFG_AXIRD_LINE_CNT_START (BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25))
++#define SYSCONSAIF_SYSCFG_12 0xc
++#define U0_VIN_CNFG_AXIRD_PIX_CNT_END (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12))
++#define U0_VIN_CNFG_AXIRD_PIX_CNT_START (BIT(13) | BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25))
++#define U0_VIN_CNFG_AXIRD_PIX_CT (BIT(26) | BIT(27))
++#define SYSCONSAIF_SYSCFG_16 0x10
++#define U0_VIN_CNFG_AXIRD_START_ADDR 0xFFFFFFFF
++#define SYSCONSAIF_SYSCFG_20 0x14
++#define U0_VIN_CNFG_AXIWR0_EN BIT(4)
++#define U0_VIN_CNFG_AXIWR0_CHANNEL_SEL (BIT(0) | BIT(1) | BIT(2) | BIT(3))
++#define SYSCONSAIF_SYSCFG_24 0x18
++#define U0_VIN_CNFG_AXIWR0_END_ADDR 0xFFFFFFFF
++
++#define SYSCONSAIF_SYSCFG_28 0x1c
++#define U0_VIN_CNFG_AXIWR0_INTR_CLEAN BIT(0)
++#define U0_VIN_CNFG_AXIWR0_MASK BIT(1)
++#define U0_VIN_CNFG_AXIWR0_PIX_CNT_END (BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12))
++#define U0_VIN_CNFG_AXIWR0_PIX_CT (BIT(13) | BIT(14))
++#define UO_VIN_CNFG_AXIWR0_PIXEL_HEIGH_BIT_SEL (BIT(15) | BIT(16))
++#define SYSCONSAIF_SYSCFG_32 0x20
++
++#define SYSCONSAIF_SYSCFG_36 0x24
++#define UO_VIN_CNFG_COLOR_BAR_EN BIT(0)
++#define U0_VIN_CNFG_DVP_HS_POS (0x1<<1)
++#define U0_VIN_CNFG_DVP_SWAP_EN BIT(2)
++#define U0_VIN_CNFG_DVP_VS_POS (0x1<<3)
++#define U0_VIN_CNFG_GEN_EN_AXIRD BIT(4)
++#define U0_VIN_CNFG_ISP_DVP_EN0 BIT(5)
++#define U0_VIN_CNFG_MIPI_BYTE_EN_ISP0 (BIT(6) |BIT(7))
++#define U0_VIN_CNFG_P_I_MIPI_CHANNEL_SEL0 (BIT(8) |BIT(9) | BIT(10) | BIT(11))
++#define U0_VIN_CNFG_P_I_MIPI_HEADER_EN0 BIT(12)
++
++#define U0_VIN_CNFG_PIX_NUM (0x1<<13 | 0x1<<14 | 0x1<<15 | 0x1<<16)
++#define U0_VIN_CNFG_AXIRD_AXI_CNT_END (BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13))
++
++#define U0_VIN_CNFG_AXI_DVP_EN BIT(2)
++#define U0_VIN_CNFG_AXIRD_INTR_MASK BIT(1)
++#define U0_VIN_CNFG_AXIWRD_INTR_MASK BIT(1)
++#define U0_VIN_CNFG_AXIWR0_START_ADDR 0xffffffff
++#define U0_VIN_CNFG_COLOR_BAR_EN 0X0
++#define U0_VIN_CNFG_AXIWR0_PIX_CNT_CT (BIT(13) | BIT(14))
++#define U0_VIN_CNFG_AXIWR0_PIX_CNT_CNT_END (BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12))
++#define U0_VIN_CNFG_AXIWR0_PIXEL_HITH_BIT_SEL (BIT(15) | BIT(16))
++
++#define SYSCTRL_REG4 0x10
++#define SYSCTRL_DPHY_CTRL 0x14
++#define SYSCTRL_VIN_AXI_CTRL 0x18
++#define SYSCTRL_VIN_WR_START_ADDR 0x28
++#define SYSCTRL_VIN_RD_END_ADDR 0x2C
++#define SYSCTRL_VIN_WR_PIX_TOTAL 0x30
++#define SYSCTRL_VIN_RD_PIX_TOTAL 0x34
++#define SYSCTRL_VIN_RW_CTRL 0x38
++#define SYSCTRL_VIN_SRC_CHAN_SEL 0x24
++#define SYSCTRL_VIN_SRC_DW_SEL 0x40
++#define SYSCTRL_VIN_RD_VBLANK 0x44
++#define SYSCTRL_VIN_RD_VEND 0x48
++#define SYSCTRL_VIN_RD_HBLANK 0x4C
++#define SYSCTRL_VIN_RD_HEND 0x50
++#define SYSCTRL_VIN_INTP_CTRL 0x54
++
++#define ISP_NO_SCALE_ENABLE (0x1<<20)
++#define ISP_MULTI_FRAME_ENABLE (0x1<<17)
++#define ISP_SS0_ENABLE (0x1<<11)
++#define ISP_SS1_ENABLE (0x1<<12)
++#define ISP_RESET (0x1<<1)
++#define ISP_ENBALE (0x1)
++
++
++
++ //ISP REG DEFINE
++#define ISP_REG_DVP_POLARITY_CFG 0x00000014
++#define ISP_REG_RAW_FORMAT_CFG 0x00000018
++#define ISP_REG_CFA_MODE 0x00000A1C
++#define ISP_REG_PIC_CAPTURE_START_CFG 0x0000001C
++#define ISP_REG_PIC_CAPTURE_END_CFG 0x00000020
++#define ISP_REG_PIPELINE_XY_SIZE 0x00000A0C
++#define ISP_REG_Y_PLANE_START_ADDR 0x00000A80
++#define ISP_REG_UV_PLANE_START_ADDR 0x00000A84
++#define ISP_REG_STRIDE 0x00000A88
++#define ISP_REG_PIXEL_COORDINATE_GEN 0x00000A8C
++#define ISP_REG_PIXEL_AXI_CONTROL 0x00000A90
++#define ISP_REG_SS_AXI_CONTROL 0x00000AC4
++#define ISP_REG_RGB_TO_YUV_COVERSION0 0x00000E40
++#define ISP_REG_RGB_TO_YUV_COVERSION1 0x00000E44
++#define ISP_REG_RGB_TO_YUV_COVERSION2 0x00000E48
++#define ISP_REG_RGB_TO_YUV_COVERSION3 0x00000E4C
++#define ISP_REG_RGB_TO_YUV_COVERSION4 0x00000E50
++#define ISP_REG_RGB_TO_YUV_COVERSION5 0x00000E54
++#define ISP_REG_RGB_TO_YUV_COVERSION6 0x00000E58
++#define ISP_REG_RGB_TO_YUV_COVERSION7 0x00000E5C
++#define ISP_REG_RGB_TO_YUV_COVERSION8 0x00000E60
++#define ISP_REG_CSI_MODULE_CFG 0x00000010
++#define ISP_REG_ISP_CTRL_1 0x00000A08
++#define ISP_REG_ISP_CTRL_0 0x00000A00
++#define ISP_REG_DC_AXI_ID 0x00000044
++#define ISP_REG_CSI_INPUT_EN_AND_STATUS 0x00000000
++
++//CSI registers
++#define DEVICE_CONFIG 0x00
++#define SOFT_RESET 0x04
++#define STATIC_CFG 0x08
++#define ERROR_BYPASS_CFG 0x10
++#define MONITOR_IRQS 0x18
++#define MONITOR_IRQS_MASK_CFG 0x1c
++#define INFO_IRQS 0x20
++#define INFO_IRQS_MASK_CFG 0x24
++#define ERROR_IRQS 0x28
++#define ERROR_IRQS_MASK_CFG 0x2c
++#define DPHY_LANE_CONTROL 0x40
++#define DPHY_STATUS 0x48
++#define DPHY_ERR_STATUS_IRQ 0x4C
++#define DPHY_ERR_IRQ_MASK_CFG 0x50
++#define INTEGRATION_DEBUG 0x60
++#define ERROR_DEBUG 0x74
++
++#define STREAM0_CTRL 0x100
++#define STREAM0_STATUS 0x104
++#define STREAM0_DATA_CFG 0x108
++#define STREAM0_CFG 0x10c
++#define STREAM0_MONITOR_CTRL 0x110
++#define STREAM0_MONITOR_FRAME 0x114
++#define STREAM0_MONITOR_LB 0x118
++#define STREAM0_TIMER 0x11c
++#define STREAM0_FCC_CFG 0x120
++#define STREAM0_FCC_CTRL 0x124
++#define STREAM0_FIFO_FILL_LVL 0x128
++
++//m31_dphy registers
++#define M31DPHY_APBCFGSAIF__SYSCFG_188 0xbc
++#define M31DPHY_APBCFGSAIF__SYSCFG_192 0xc0
++#define M31DPHY_APBCFGSAIF__SYSCFG_196 0xc4
++#define M31DPHY_APBCFGSAIF__SYSCFG_200 0xc8
++
++typedef enum
++{
++ DT_RAW6 = 0x28,
++ DT_RAW7 = 0x29,
++ DT_RAW8 = 0x2a,
++ DT_RAW10 = 0x2b,
++ DT_RAW12 = 0x2c,
++ DT_RAW14 = 0x2d,
++} mipicam_data_type_t;
++
++
++enum VIN_SOURCE_FORMAT {
++ SRC_COLORBAR_VIN_ISP = 0,
++ SRC_DVP_SENSOR_VIN,
++ SRC_DVP_SENSOR_VIN_ISP,//need replace sensor
++ SRC_CSI2RX_VIN_ISP,
++ SRC_DVP_SENSOR_VIN_OV5640,
++};
++
++struct reg_name {
++ char name[10];
++};
++
++typedef struct
++{
++ int dlane_nb;
++ int dlane_map[4];
++ int dlane_en[4];
++ int dlane_pn_swap[4];
++ int clane_nb;
++ int clane_map[2];
++ int clane_pn_swap[2];
++} csi2rx_dphy_cfg_t;
++
++typedef struct
++{
++ int lane_nb;
++ int dlane_map[4];
++ int dt;
++ int hsize;
++ int vsize;
++} csi2rx_cfg_t;
++
++
++typedef struct
++{
++ int mipi_id, w, h, dt, bpp, fps,lane;
++ u8 clane_swap;
++ u8 clane_pn_swap;
++ u8 dlane_swap[4];
++ u8 dlane_pn_swap[4];
++} csi_format;
++
++struct vin_params {
++ void *paddr;
++ unsigned long size;
++};
++
++struct vin_buf {
++ void *vaddr;
++ dma_addr_t paddr;
++ u32 size;
++};
++
++struct vin_framesize {
++ u32 width;
++ u32 height;
++};
++
++struct vin_format {
++ enum VIN_SOURCE_FORMAT format;
++ u8 fps;
++};
++
++struct stf_vin_dev {
++ /* Protects the access of variables shared within the interrupt */
++ spinlock_t irqlock;
++ int irq;
++ struct device *dev;
++ struct cdev vin_cdev;
++ void __iomem *base;
++ void __iomem *csi2rx_base;
++ void __iomem *clkgen_base;
++ void __iomem *rstgen_base;
++ void __iomem *sysctrl_base;
++ void __iomem *isp_base;
++ void __iomem *vin_top_clkgen_base;
++ void __iomem *vin_top_rstgen_base;
++ void __iomem *vin_top_iopad_base;
++ void __iomem *pmu_test;
++ void __iomem *sys_crg;
++ struct vin_framesize frame;
++ struct vin_format format;
++ bool isp;
++ int isp_irq;
++ int isp_csi_irq;
++ int isp_scd_irq;
++ int isp_irq_csiline;
++ u32 major;
++ struct vin_buf buf;
++
++ wait_queue_head_t wq;
++ bool condition;
++ int odd;
++
++ csi_format csi_fmt;
++};
++
++extern int vin_notifier_register(struct notifier_block *nb);
++extern void vin_notifier_unregister(struct notifier_block *nb);
++extern int vin_notifier_call(unsigned long e, void *v);
++#endif
diff --git a/target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch b/target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch
new file mode 100644
index 0000000000..c2a97a1873
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch
@@ -0,0 +1,135 @@
+From baec350a0994467584e7e390746e0bb365957a89 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Tue, 13 Jun 2023 16:55:23 +0800
+Subject: [PATCH 086/116] dt-bindings: media: i2c: Add IMX708 CMOS sensor
+ binding
+
+Add YAML devicetree binding for IMX708 CMOS image sensor.
+Let's also add a MAINTAINERS entry for the binding and driver.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ .../devicetree/bindings/media/i2c/imx708.yaml | 117 ++++++++++++++++++
+ 1 file changed, 117 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/i2c/imx708.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/i2c/imx708.yaml
+@@ -0,0 +1,117 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/media/i2c/imx708.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Sony 1/2.3-Inch 12Mpixel CMOS Digital Image Sensor
++
++maintainers:
++ - Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.om>
++
++description: |-
++ The Sony IMX708 is a 1/2.3-inch CMOS active pixel digital mage sensor
++ with an active array size of 4608H x 2592V. It is rogrammable through
++ I2C interface. The I2C address is fixed to 0x1A as per ensor data sheet.
++ Image data is sent through MIPI CSI-2, which is configured s either 2 or
++ 4 data lanes.
++
++properties:
++ compatible:
++ const: sony,imx708
++
++ reg:
++ description: I2C device address
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ VDIG-supply:
++ description:
++ Digital I/O voltage supply, 1.1 volts
++
++ VANA1-supply:
++ description:
++ Analog1 voltage supply, 2.8 volts
++
++ VANA2-supply:
++ description:
++ Analog2 voltage supply, 1.8 volts
++
++ VDDL-supply:
++ description:
++ Digital core voltage supply, 1.8 volts
++
++ reset-gpios:
++ description: |-
++ Reference to the GPIO connected to the xclr pin, if any.
++ Must be released (set high) after all supplies and INCK re applied.
++
++ # See ../video-interfaces.txt for more details
++ port:
++ type: object
++ properties:
++ endpoint:
++ type: object
++ properties:
++ data-lanes:
++ description: |-
++ The sensor supports either two-lane, or our-lane operation.
++ For two-lane operation the property must be set o <1 2>.
++ items:
++ - const: 1
++ - const: 2
++
++ clock-noncontinuous:
++ type: boolean
++ description: |-
++ MIPI CSI-2 clock is non-continuous if this roperty is present,
++ otherwise it's continuous.
++
++ link-frequencies:
++ allOf:
++ - $ref: /schemas/types.yaml#/definitions/int64-array
++ description:
++ Allowed data bus frequencies.
++
++ required:
++ - link-frequencies
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - VANA1-supply
++ - VANA2-supply
++ - VDIG-supply
++ - VDDL-supply
++ - port
++
++additionalProperties: false
++
++examples:
++ - |
++ i2c0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ imx708: sensor@1a {
++ compatible = "sony,imx708";
++ reg = <0x1a>;
++ clocks = <&imx708_clk>;
++ VANA1-supply = <&imx708_vana1>; /* 1.8v */
++ VANA2-supply = <&imx708_vana2>; /* 2.8v */
++ VDIG-supply = <&imx708_vdig>; /* 1.1v */
++ VDDL-supply = <&imx708_vddl>; /* 1.8v */
++
++ port {
++ imx708_0: endpoint {
++ remote-endpoint = <&csi1_ep>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies = /bits/ 64 <450000000>;
++ };
++ };
++ };
++ };
diff --git a/target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch b/target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch
new file mode 100644
index 0000000000..51e61817f8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch
@@ -0,0 +1,1971 @@
+From e89556802c5d29a80f5887995ab257d4e826a90f Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 3 Apr 2023 13:52:17 +0800
+Subject: [PATCH 087/116] media: i2c: Add imx708 support
+
+Add imx708 support.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/media/i2c/Kconfig | 13 +
+ drivers/media/i2c/Makefile | 1 +
+ drivers/media/i2c/imx708.c | 1921 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1935 insertions(+)
+ create mode 100644 drivers/media/i2c/imx708.c
+
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -201,6 +201,19 @@ config VIDEO_IMX415
+ To compile this driver as a module, choose M here: the
+ module will be called imx415.
+
++config VIDEO_IMX708
++ tristate "Sony IMX708 sensor support"
++ depends on I2C && VIDEO_DEV
++ select MEDIA_CONTROLLER
++ select VIDEO_V4L2_SUBDEV_API
++ select V4L2_FWNODE
++ help
++ This is a Video4Linux2 sensor driver for the Sony
++ IMX708 camera.
++
++ To compile this driver as a module, choose M here: the
++ module will be called imx708.
++
+ config VIDEO_MAX9271_LIB
+ tristate
+
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -53,6 +53,7 @@ obj-$(CONFIG_VIDEO_IMX335) += imx335.o
+ obj-$(CONFIG_VIDEO_IMX355) += imx355.o
+ obj-$(CONFIG_VIDEO_IMX412) += imx412.o
+ obj-$(CONFIG_VIDEO_IMX415) += imx415.o
++obj-$(CONFIG_VIDEO_IMX708) += imx708.o
+ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
+ obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
+ obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+--- /dev/null
++++ b/drivers/media/i2c/imx708.c
+@@ -0,0 +1,1921 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * A V4L2 driver for Sony IMX708 cameras.
++ * Copyright (C) 2022-2023, Raspberry Pi Ltd
++ *
++ * Based on Sony imx477 camera driver
++ * Copyright (C) 2020 Raspberry Pi Ltd
++ */
++#include <asm/unaligned.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-mediabus.h>
++
++#define IMX708_REG_VALUE_08BIT 1
++#define IMX708_REG_VALUE_16BIT 2
++
++/* Chip ID */
++#define IMX708_REG_CHIP_ID 0x0016
++#define IMX708_CHIP_ID 0x0708
++
++#define IMX708_REG_MODE_SELECT 0x0100
++#define IMX708_MODE_STANDBY 0x00
++#define IMX708_MODE_STREAMING 0x01
++
++#define IMX708_REG_ORIENTATION 0x101
++
++#define IMX708_XCLK_FREQ 24000000
++
++#define IMX708_DEFAULT_LINK_FREQ 450000000
++
++/* V_TIMING internal */
++#define IMX708_REG_FRAME_LENGTH 0x0340
++#define IMX708_FRAME_LENGTH_MAX 0xffff
++
++/* Long exposure multiplier */
++#define IMX708_LONG_EXP_SHIFT_MAX 7
++#define IMX708_LONG_EXP_SHIFT_REG 0x3100
++
++/* Exposure control */
++#define IMX708_REG_EXPOSURE 0x0202
++#define IMX708_EXPOSURE_OFFSET 48
++#define IMX708_EXPOSURE_DEFAULT 0x640
++#define IMX708_EXPOSURE_STEP 1
++#define IMX708_EXPOSURE_MIN 1
++#define IMX708_EXPOSURE_MAX (IMX708_FRAME_LENGTH_MAX - \
++ IMX708_EXPOSURE_OFFSET)
++
++/* Analog gain control */
++#define IMX708_REG_ANALOG_GAIN 0x0204
++#define IMX708_ANA_GAIN_MIN 112
++#define IMX708_ANA_GAIN_MAX 960
++#define IMX708_ANA_GAIN_STEP 1
++#define IMX708_ANA_GAIN_DEFAULT IMX708_ANA_GAIN_MIN
++
++/* Digital gain control */
++#define IMX708_REG_DIGITAL_GAIN 0x020e
++#define IMX708_DGTL_GAIN_MIN 0x0100
++#define IMX708_DGTL_GAIN_MAX 0xffff
++#define IMX708_DGTL_GAIN_DEFAULT 0x0100
++#define IMX708_DGTL_GAIN_STEP 1
++
++/* Colour balance controls */
++#define IMX708_REG_COLOUR_BALANCE_RED 0x0b90
++#define IMX708_REG_COLOUR_BALANCE_BLUE 0x0b92
++#define IMX708_COLOUR_BALANCE_MIN 0x01
++#define IMX708_COLOUR_BALANCE_MAX 0xffff
++#define IMX708_COLOUR_BALANCE_STEP 0x01
++#define IMX708_COLOUR_BALANCE_DEFAULT 0x100
++
++/* Test Pattern Control */
++#define IMX708_REG_TEST_PATTERN 0x0600
++#define IMX708_TEST_PATTERN_DISABLE 0
++#define IMX708_TEST_PATTERN_SOLID_COLOR 1
++#define IMX708_TEST_PATTERN_COLOR_BARS 2
++#define IMX708_TEST_PATTERN_GREY_COLOR 3
++#define IMX708_TEST_PATTERN_PN9 4
++
++/* Test pattern colour components */
++#define IMX708_REG_TEST_PATTERN_R 0x0602
++#define IMX708_REG_TEST_PATTERN_GR 0x0604
++#define IMX708_REG_TEST_PATTERN_B 0x0606
++#define IMX708_REG_TEST_PATTERN_GB 0x0608
++#define IMX708_TEST_PATTERN_COLOUR_MIN 0
++#define IMX708_TEST_PATTERN_COLOUR_MAX 0x0fff
++#define IMX708_TEST_PATTERN_COLOUR_STEP 1
++
++#define IMX708_REG_BASE_SPC_GAINS_L 0x7b10
++#define IMX708_REG_BASE_SPC_GAINS_R 0x7c00
++
++/* HDR exposure ratio (long:med == med:short) */
++#define IMX708_HDR_EXPOSURE_RATIO 4
++#define IMX708_REG_MID_EXPOSURE 0x3116
++#define IMX708_REG_SHT_EXPOSURE 0x0224
++#define IMX708_REG_MID_ANALOG_GAIN 0x3118
++#define IMX708_REG_SHT_ANALOG_GAIN 0x0216
++
++/* IMX708 native and active pixel array size. */
++#define IMX708_NATIVE_WIDTH 4640U
++#define IMX708_NATIVE_HEIGHT 2658U
++#define IMX708_PIXEL_ARRAY_LEFT 16U
++#define IMX708_PIXEL_ARRAY_TOP 24U
++#define IMX708_PIXEL_ARRAY_WIDTH 4608U
++#define IMX708_PIXEL_ARRAY_HEIGHT 2592U
++
++struct imx708_reg {
++ u16 address;
++ u8 val;
++};
++
++struct imx708_reg_list {
++ unsigned int num_of_regs;
++ const struct imx708_reg *regs;
++};
++
++/* Mode : resolution and related config&values */
++struct imx708_mode {
++ /* Frame width */
++ unsigned int width;
++
++ /* Frame height */
++ unsigned int height;
++
++ /* H-timing in pixels */
++ unsigned int line_length_pix;
++
++ /* Analog crop rectangle. */
++ struct v4l2_rect crop;
++
++ /* Highest possible framerate. */
++ unsigned int vblank_min;
++
++ /* Default framerate. */
++ unsigned int vblank_default;
++
++ /* Default register values */
++ struct imx708_reg_list reg_list;
++
++ /* Not all modes have the same pixel rate. */
++ u64 pixel_rate;
++
++ /* Not all modes have the same minimum exposure. */
++ u32 exposure_lines_min;
++
++ /* Not all modes have the same exposure lines step. */
++ u32 exposure_lines_step;
++
++ /* HDR flag, currently not used at runtime */
++ bool hdr;
++};
++
++/* Default PDAF pixel correction gains */
++static const u8 pdaf_gains[2][9] = {
++ { 0x4c, 0x4c, 0x4c, 0x46, 0x3e, 0x38, 0x35, 0x35, 0x35 },
++ { 0x35, 0x35, 0x35, 0x38, 0x3e, 0x46, 0x4c, 0x4c, 0x4c }
++};
++
++static const struct imx708_reg mode_common_regs[] = {
++ {0x0100, 0x00},
++ {0x0136, 0x18},
++ {0x0137, 0x00},
++ {0x33f0, 0x02},
++ {0x33f1, 0x05},
++ {0x3062, 0x00},
++ {0x3063, 0x12},
++ {0x3068, 0x00},
++ {0x3069, 0x12},
++ {0x306a, 0x00},
++ {0x306b, 0x30},
++ {0x3076, 0x00},
++ {0x3077, 0x30},
++ {0x3078, 0x00},
++ {0x3079, 0x30},
++ {0x5e54, 0x0c},
++ {0x6e44, 0x00},
++ {0xb0b6, 0x01},
++ {0xe829, 0x00},
++ {0xf001, 0x08},
++ {0xf003, 0x08},
++ {0xf00d, 0x10},
++ {0xf00f, 0x10},
++ {0xf031, 0x08},
++ {0xf033, 0x08},
++ {0xf03d, 0x10},
++ {0xf03f, 0x10},
++ {0x0112, 0x0a},
++ {0x0113, 0x0a},
++ {0x0114, 0x01},
++ {0x0b8e, 0x01},
++ {0x0b8f, 0x00},
++ {0x0b94, 0x01},
++ {0x0b95, 0x00},
++ {0x3400, 0x01},
++ {0x3478, 0x01},
++ {0x3479, 0x1c},
++ {0x3091, 0x01},
++ {0x3092, 0x00},
++ {0x3419, 0x00},
++ {0xbcf1, 0x02},
++ {0x3094, 0x01},
++ {0x3095, 0x01},
++ {0x3362, 0x00},
++ {0x3363, 0x00},
++ {0x3364, 0x00},
++ {0x3365, 0x00},
++ {0x0138, 0x01},
++};
++
++/* 10-bit. */
++static const struct imx708_reg mode_4608x2592_regs[] = {
++ {0x0342, 0x3d},
++ {0x0343, 0x20},
++ {0x0340, 0x0a},
++ {0x0341, 0x59},
++ {0x0344, 0x00},
++ {0x0345, 0x00},
++ {0x0346, 0x00},
++ {0x0347, 0x00},
++ {0x0348, 0x11},
++ {0x0349, 0xff},
++ {0x034a, 0x0a},
++ {0x034b, 0x1f},
++ {0x0220, 0x62},
++ {0x0222, 0x01},
++ {0x0900, 0x00},
++ {0x0901, 0x11},
++ {0x0902, 0x0a},
++ {0x3200, 0x01},
++ {0x3201, 0x01},
++ {0x32d5, 0x01},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x00},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x12},
++ {0x040d, 0x00},
++ {0x040e, 0x0a},
++ {0x040f, 0x20},
++ {0x034c, 0x12},
++ {0x034d, 0x00},
++ {0x034e, 0x0a},
++ {0x034f, 0x20},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0x7c},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x64},
++ {0x3ca4, 0x00},
++ {0x3ca5, 0x00},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x00},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x08},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x00},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x3c},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x00},
++ {0x0202, 0x0a},
++ {0x0203, 0x29},
++ {0x0224, 0x01},
++ {0x0225, 0xf4},
++ {0x3116, 0x01},
++ {0x3117, 0xf4},
++ {0x0204, 0x00},
++ {0x0205, 0x00},
++ {0x0216, 0x00},
++ {0x0217, 0x00},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x00},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x01},
++ {0x341f, 0x20},
++ {0x3420, 0x00},
++ {0x3421, 0xd8},
++ {0xc428, 0x00},
++ {0xc429, 0x04},
++ {0x3366, 0x00},
++ {0x3367, 0x00},
++ {0x3368, 0x00},
++ {0x3369, 0x00},
++};
++
++static const struct imx708_reg mode_2x2binned_regs[] = {
++ {0x0342, 0x1e},
++ {0x0343, 0x90},
++ {0x0340, 0x05},
++ {0x0341, 0x38},
++ {0x0344, 0x00},
++ {0x0345, 0x00},
++ {0x0346, 0x00},
++ {0x0347, 0x00},
++ {0x0348, 0x11},
++ {0x0349, 0xff},
++ {0x034a, 0x0a},
++ {0x034b, 0x1f},
++ {0x0220, 0x62},
++ {0x0222, 0x01},
++ {0x0900, 0x01},
++ {0x0901, 0x22},
++ {0x0902, 0x08},
++ {0x3200, 0x41},
++ {0x3201, 0x41},
++ {0x32d5, 0x00},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x00},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x09},
++ {0x040d, 0x00},
++ {0x040e, 0x05},
++ {0x040f, 0x10},
++ {0x034c, 0x09},
++ {0x034d, 0x00},
++ {0x034e, 0x05},
++ {0x034f, 0x10},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0x7a},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x3c},
++ {0x3ca4, 0x00},
++ {0x3ca5, 0x3c},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x00},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x1c},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x08},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x1e},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x0a},
++ {0x0202, 0x05},
++ {0x0203, 0x08},
++ {0x0224, 0x01},
++ {0x0225, 0xf4},
++ {0x3116, 0x01},
++ {0x3117, 0xf4},
++ {0x0204, 0x00},
++ {0x0205, 0x70},
++ {0x0216, 0x00},
++ {0x0217, 0x70},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x70},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x00},
++ {0x341f, 0x90},
++ {0x3420, 0x00},
++ {0x3421, 0x6c},
++ {0x3366, 0x00},
++ {0x3367, 0x00},
++ {0x3368, 0x00},
++ {0x3369, 0x00},
++};
++
++static const struct imx708_reg mode_2x2binned_720p_regs[] = {
++ {0x0342, 0x14},
++ {0x0343, 0x60},
++ {0x0340, 0x04},
++ {0x0341, 0xb6},
++ {0x0344, 0x03},
++ {0x0345, 0x00},
++ {0x0346, 0x01},
++ {0x0347, 0xb0},
++ {0x0348, 0x0e},
++ {0x0349, 0xff},
++ {0x034a, 0x08},
++ {0x034b, 0x6f},
++ {0x0220, 0x62},
++ {0x0222, 0x01},
++ {0x0900, 0x01},
++ {0x0901, 0x22},
++ {0x0902, 0x08},
++ {0x3200, 0x41},
++ {0x3201, 0x41},
++ {0x32d5, 0x00},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x01},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x06},
++ {0x040d, 0x00},
++ {0x040e, 0x03},
++ {0x040f, 0x60},
++ {0x034c, 0x06},
++ {0x034d, 0x00},
++ {0x034e, 0x03},
++ {0x034f, 0x60},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0x76},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x3c},
++ {0x3ca4, 0x01},
++ {0x3ca5, 0x5e},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x00},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x0c},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x04},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x1e},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x05},
++ {0x0202, 0x04},
++ {0x0203, 0x86},
++ {0x0224, 0x01},
++ {0x0225, 0xf4},
++ {0x3116, 0x01},
++ {0x3117, 0xf4},
++ {0x0204, 0x00},
++ {0x0205, 0x70},
++ {0x0216, 0x00},
++ {0x0217, 0x70},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x70},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x00},
++ {0x341f, 0x60},
++ {0x3420, 0x00},
++ {0x3421, 0x48},
++ {0x3366, 0x00},
++ {0x3367, 0x00},
++ {0x3368, 0x00},
++ {0x3369, 0x00},
++};
++
++static const struct imx708_reg mode_hdr_regs[] = {
++ {0x0342, 0x14},
++ {0x0343, 0x60},
++ {0x0340, 0x0a},
++ {0x0341, 0x5b},
++ {0x0344, 0x00},
++ {0x0345, 0x00},
++ {0x0346, 0x00},
++ {0x0347, 0x00},
++ {0x0348, 0x11},
++ {0x0349, 0xff},
++ {0x034a, 0x0a},
++ {0x034b, 0x1f},
++ {0x0220, 0x01},
++ {0x0222, IMX708_HDR_EXPOSURE_RATIO},
++ {0x0900, 0x00},
++ {0x0901, 0x11},
++ {0x0902, 0x0a},
++ {0x3200, 0x01},
++ {0x3201, 0x01},
++ {0x32d5, 0x00},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x00},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x09},
++ {0x040d, 0x00},
++ {0x040e, 0x05},
++ {0x040f, 0x10},
++ {0x034c, 0x09},
++ {0x034d, 0x00},
++ {0x034e, 0x05},
++ {0x034f, 0x10},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0xa2},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x00},
++ {0x3ca4, 0x00},
++ {0x3ca5, 0x00},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x28},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x30},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x00},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x32},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x00},
++ {0x0202, 0x0a},
++ {0x0203, 0x2b},
++ {0x0224, 0x0a},
++ {0x0225, 0x2b},
++ {0x3116, 0x0a},
++ {0x3117, 0x2b},
++ {0x0204, 0x00},
++ {0x0205, 0x00},
++ {0x0216, 0x00},
++ {0x0217, 0x00},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x00},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x00},
++ {0x341f, 0x90},
++ {0x3420, 0x00},
++ {0x3421, 0x6c},
++ {0x3360, 0x01},
++ {0x3361, 0x01},
++ {0x3366, 0x09},
++ {0x3367, 0x00},
++ {0x3368, 0x05},
++ {0x3369, 0x10},
++};
++
++/* Mode configs. Keep separate lists for when HDR is enabled or not. */
++static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
++ {
++ /* Full resolution. */
++ .width = 4608,
++ .height = 2592,
++ .line_length_pix = 0x3d20,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT,
++ .top = IMX708_PIXEL_ARRAY_TOP,
++ .width = 4608,
++ .height = 2592,
++ },
++ .vblank_min = 58,
++ .vblank_default = 58,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_4608x2592_regs),
++ .regs = mode_4608x2592_regs,
++ },
++ .pixel_rate = 595200000,
++ .exposure_lines_min = 8,
++ .exposure_lines_step = 1,
++ .hdr = false
++ },
++ {
++ /* regular 2x2 binned. */
++ .width = 2304,
++ .height = 1296,
++ .line_length_pix = 0x1e90,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT,
++ .top = IMX708_PIXEL_ARRAY_TOP,
++ .width = 4608,
++ .height = 2592,
++ },
++ .vblank_min = 40,
++ .vblank_default = 1198,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_2x2binned_regs),
++ .regs = mode_2x2binned_regs,
++ },
++ .pixel_rate = 585600000,
++ .exposure_lines_min = 4,
++ .exposure_lines_step = 2,
++ .hdr = false
++ },
++ {
++ /* 2x2 binned and cropped for 720p. */
++ .width = 1536,
++ .height = 864,
++ .line_length_pix = 0x1460,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT + 768,
++ .top = IMX708_PIXEL_ARRAY_TOP + 432,
++ .width = 3072,
++ .height = 1728,
++ },
++ .vblank_min = 40,
++ .vblank_default = 2755,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_2x2binned_720p_regs),
++ .regs = mode_2x2binned_720p_regs,
++ },
++ .pixel_rate = 566400000,
++ .exposure_lines_min = 4,
++ .exposure_lines_step = 2,
++ .hdr = false
++ },
++};
++
++static const struct imx708_mode supported_modes_10bit_hdr[] = {
++ {
++ /* There's only one HDR mode, which is 2x2 downscaled */
++ .width = 2304,
++ .height = 1296,
++ .line_length_pix = 0x1460,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT,
++ .top = IMX708_PIXEL_ARRAY_TOP,
++ .width = 4608,
++ .height = 2592,
++ },
++ .vblank_min = 3673,
++ .vblank_default = 3673,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_hdr_regs),
++ .regs = mode_hdr_regs,
++ },
++ .pixel_rate = 777600000,
++ .exposure_lines_min = 8 * IMX708_HDR_EXPOSURE_RATIO *
++ IMX708_HDR_EXPOSURE_RATIO,
++ .exposure_lines_step = 2 * IMX708_HDR_EXPOSURE_RATIO *
++ IMX708_HDR_EXPOSURE_RATIO,
++ .hdr = true
++ }
++};
++
++/*
++ * The supported formats.
++ * This table MUST contain 4 entries per format, to cover the various flip
++ * combinations in the order
++ * - no flip
++ * - h flip
++ * - v flip
++ * - h&v flips
++ */
++static const u32 codes[] = {
++ /* 10-bit modes. */
++ MEDIA_BUS_FMT_SRGGB10_1X10,
++ MEDIA_BUS_FMT_SGRBG10_1X10,
++ MEDIA_BUS_FMT_SGBRG10_1X10,
++ MEDIA_BUS_FMT_SBGGR10_1X10,
++};
++
++static const char * const imx708_test_pattern_menu[] = {
++ "Disabled",
++ "Color Bars",
++ "Solid Color",
++ "Grey Color Bars",
++ "PN9"
++};
++
++static const int imx708_test_pattern_val[] = {
++ IMX708_TEST_PATTERN_DISABLE,
++ IMX708_TEST_PATTERN_COLOR_BARS,
++ IMX708_TEST_PATTERN_SOLID_COLOR,
++ IMX708_TEST_PATTERN_GREY_COLOR,
++ IMX708_TEST_PATTERN_PN9,
++};
++
++/* regulator supplies */
++static const char * const imx708_supply_name[] = {
++ /* Supplies can be enabled in any order */
++ "VANA1", /* Analog1 (2.8V) supply */
++ "VANA2", /* Analog2 (1.8V) supply */
++ "VDIG", /* Digital Core (1.1V) supply */
++ "VDDL", /* IF (1.8V) supply */
++};
++
++#define IMX708_NUM_SUPPLIES ARRAY_SIZE(imx708_supply_name)
++
++/*
++ * Initialisation delay between XCLR low->high and the moment when the sensor
++ * can start capture (i.e. can leave software standby), given by T7 in the
++ * datasheet is 8ms. This does include I2C setup time as well.
++ *
++ * Note, that delay between XCLR low->high and reading the CCI ID register (T6
++ * in the datasheet) is much smaller - 600us.
++ */
++#define IMX708_XCLR_MIN_DELAY_US 8000
++#define IMX708_XCLR_DELAY_RANGE_US 1000
++
++struct imx708 {
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++
++ struct v4l2_mbus_framefmt fmt;
++
++ struct clk *xclk;
++ u32 xclk_freq;
++
++ struct gpio_desc *reset_gpio;
++ struct regulator_bulk_data supplies[IMX708_NUM_SUPPLIES];
++
++ struct v4l2_ctrl_handler ctrl_handler;
++ /* V4L2 Controls */
++ struct v4l2_ctrl *pixel_rate;
++ struct v4l2_ctrl *exposure;
++ struct v4l2_ctrl *vflip;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *hblank;
++ struct v4l2_ctrl *red_balance;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *notify_gains;
++ struct v4l2_ctrl *hdr_mode;
++
++ /* Current mode */
++ const struct imx708_mode *mode;
++
++ /* Mutex for serialized access */
++ struct mutex mutex;
++
++ /* Streaming on/off */
++ bool streaming;
++
++ /* Rewrite common registers on stream on? */
++ bool common_regs_written;
++
++ /* Current long exposure factor in use. Set through V4L2_CID_VBLANK */
++ unsigned int long_exp_shift;
++};
++
++static inline struct imx708 *to_imx708(struct v4l2_subdev *_sd)
++{
++ return container_of(_sd, struct imx708, sd);
++}
++
++static inline void get_mode_table(const struct imx708_mode **mode_list,
++ unsigned int *num_modes,
++ bool hdr_enable)
++{
++ if (hdr_enable) {
++ *mode_list = supported_modes_10bit_hdr;
++ *num_modes = ARRAY_SIZE(supported_modes_10bit_hdr);
++ } else {
++ *mode_list = supported_modes_10bit_no_hdr;
++ *num_modes = ARRAY_SIZE(supported_modes_10bit_no_hdr);
++ }
++}
++
++/* Read registers up to 2 at a time */
++static int imx708_read_reg(struct imx708 *imx708, u16 reg, u32 len, u32 *val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ struct i2c_msg msgs[2];
++ u8 addr_buf[2] = { reg >> 8, reg & 0xff };
++ u8 data_buf[4] = { 0, };
++ int ret;
++
++ if (len > 4)
++ return -EINVAL;
++
++ /* Write register address */
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = ARRAY_SIZE(addr_buf);
++ msgs[0].buf = addr_buf;
++
++ /* Read data from register */
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = len;
++ msgs[1].buf = &data_buf[4 - len];
++
++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
++ if (ret != ARRAY_SIZE(msgs))
++ return -EIO;
++
++ *val = get_unaligned_be32(data_buf);
++
++ return 0;
++}
++
++/* Write registers up to 2 at a time */
++static int imx708_write_reg(struct imx708 *imx708, u16 reg, u32 len, u32 val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ u8 buf[6];
++
++ if (len > 4)
++ return -EINVAL;
++
++ put_unaligned_be16(reg, buf);
++ put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
++ if (i2c_master_send(client, buf, len + 2) != len + 2)
++ return -EIO;
++
++ return 0;
++}
++
++/* Write a list of registers */
++static int imx708_write_regs(struct imx708 *imx708,
++ const struct imx708_reg *regs, u32 len)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ unsigned int i;
++ int ret;
++
++ for (i = 0; i < len; i++) {
++ ret = imx708_write_reg(imx708, regs[i].address, 1, regs[i].val);
++ if (ret) {
++ dev_err_ratelimited(&client->dev,
++ "Failed to write reg 0x%4.4x. error = %d\n",
++ regs[i].address, ret);
++
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++/* Get bayer order based on flip setting. */
++static u32 imx708_get_format_code(struct imx708 *imx708)
++{
++ unsigned int i;
++
++ lockdep_assert_held(&imx708->mutex);
++
++ i = (imx708->vflip->val ? 2 : 0) |
++ (imx708->hflip->val ? 1 : 0);
++
++ return codes[i];
++}
++
++static void imx708_set_default_format(struct imx708 *imx708)
++{
++ struct v4l2_mbus_framefmt *fmt = &imx708->fmt;
++
++ /* Set default mode to max resolution */
++ imx708->mode = &supported_modes_10bit_no_hdr[0];
++
++ /* fmt->code not set as it will always be computed based on flips */
++ fmt->colorspace = V4L2_COLORSPACE_RAW;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace,
++ fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = imx708->mode->width;
++ fmt->height = imx708->mode->height;
++ fmt->field = V4L2_FIELD_NONE;
++}
++
++static int imx708_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++ struct v4l2_mbus_framefmt *try_fmt_img =
++ v4l2_subdev_get_try_format(sd, fh->state, 0);
++ struct v4l2_rect *try_crop;
++
++ mutex_lock(&imx708->mutex);
++
++ /* Initialize try_fmt for the image pad */
++ if (imx708->hdr_mode->val) {
++ try_fmt_img->width = supported_modes_10bit_hdr[0].width;
++ try_fmt_img->height = supported_modes_10bit_hdr[0].height;
++ } else {
++ try_fmt_img->width = supported_modes_10bit_no_hdr[0].width;
++ try_fmt_img->height = supported_modes_10bit_no_hdr[0].height;
++ }
++ try_fmt_img->code = imx708_get_format_code(imx708);
++ try_fmt_img->field = V4L2_FIELD_NONE;
++
++ /* Initialize try_crop */
++ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
++ try_crop->left = IMX708_PIXEL_ARRAY_LEFT;
++ try_crop->top = IMX708_PIXEL_ARRAY_TOP;
++ try_crop->width = IMX708_PIXEL_ARRAY_WIDTH;
++ try_crop->height = IMX708_PIXEL_ARRAY_HEIGHT;
++
++ mutex_unlock(&imx708->mutex);
++
++ return 0;
++}
++
++static int imx708_set_exposure(struct imx708 *imx708, unsigned int val)
++{
++ int ret;
++
++ val = max(val, imx708->mode->exposure_lines_min);
++ val -= val % imx708->mode->exposure_lines_step;
++
++ /*
++ * In HDR mode this will set the longest exposure. The sensor
++ * will automatically divide the medium and short ones by 4,16.
++ */
++ ret = imx708_write_reg(imx708, IMX708_REG_EXPOSURE,
++ IMX708_REG_VALUE_16BIT,
++ val >> imx708->long_exp_shift);
++
++ return ret;
++}
++
++static void imx708_adjust_exposure_range(struct imx708 *imx708,
++ struct v4l2_ctrl *ctrl)
++{
++ int exposure_max, exposure_def;
++
++ /* Honour the VBLANK limits when setting exposure. */
++ exposure_max = imx708->mode->height + imx708->vblank->val -
++ IMX708_EXPOSURE_OFFSET;
++ exposure_def = min(exposure_max, imx708->exposure->val);
++ __v4l2_ctrl_modify_range(imx708->exposure, imx708->exposure->minimum,
++ exposure_max, imx708->exposure->step,
++ exposure_def);
++}
++
++static int imx708_set_analogue_gain(struct imx708 *imx708, unsigned int val)
++{
++ int ret;
++
++ /*
++ * In HDR mode this will set the gain for the longest exposure,
++ * and by default the sensor uses the same gain for all of them.
++ */
++ ret = imx708_write_reg(imx708, IMX708_REG_ANALOG_GAIN,
++ IMX708_REG_VALUE_16BIT, val);
++
++ return ret;
++}
++
++static int imx708_set_frame_length(struct imx708 *imx708, unsigned int val)
++{
++ int ret = 0;
++
++ imx708->long_exp_shift = 0;
++
++ while (val > IMX708_FRAME_LENGTH_MAX) {
++ imx708->long_exp_shift++;
++ val >>= 1;
++ }
++
++ ret = imx708_write_reg(imx708, IMX708_REG_FRAME_LENGTH,
++ IMX708_REG_VALUE_16BIT, val);
++ if (ret)
++ return ret;
++
++ return imx708_write_reg(imx708, IMX708_LONG_EXP_SHIFT_REG,
++ IMX708_REG_VALUE_08BIT, imx708->long_exp_shift);
++}
++
++static void imx708_set_framing_limits(struct imx708 *imx708)
++{
++ unsigned int hblank;
++ const struct imx708_mode *mode = imx708->mode;
++
++ /* Default to no long exposure multiplier */
++ imx708->long_exp_shift = 0;
++
++ __v4l2_ctrl_modify_range(imx708->pixel_rate,
++ mode->pixel_rate, mode->pixel_rate,
++ 1, mode->pixel_rate);
++
++ /* Update limits and set FPS to default */
++ __v4l2_ctrl_modify_range(imx708->vblank, mode->vblank_min,
++ ((1 << IMX708_LONG_EXP_SHIFT_MAX) *
++ IMX708_FRAME_LENGTH_MAX) - mode->height,
++ 1, mode->vblank_default);
++
++ /*
++ * Currently PPL is fixed to the mode specified value, so hblank
++ * depends on mode->width only, and is not changeable in any
++ * way other than changing the mode.
++ */
++ hblank = mode->line_length_pix - mode->width;
++ __v4l2_ctrl_modify_range(imx708->hblank, hblank, hblank, 1, hblank);
++}
++
++static int imx708_set_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct imx708 *imx708 =
++ container_of(ctrl->handler, struct imx708, ctrl_handler);
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ const struct imx708_mode *mode_list;
++ unsigned int num_modes;
++ int ret;
++
++ /*
++ * The VBLANK control may change the limits of usable exposure, so check
++ * and adjust if necessary.
++ */
++ if (ctrl->id == V4L2_CID_VBLANK)
++ imx708_adjust_exposure_range(imx708, ctrl);
++
++ /*
++ * Applying V4L2 control value only happens
++ * when power is up for streaming
++ */
++ if (!pm_runtime_get_if_in_use(&client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = imx708_set_analogue_gain(imx708, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = imx708_set_exposure(imx708, ctrl->val);
++ break;
++ case V4L2_CID_DIGITAL_GAIN:
++ ret = imx708_write_reg(imx708, IMX708_REG_DIGITAL_GAIN,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN,
++ IMX708_REG_VALUE_16BIT,
++ imx708_test_pattern_val[ctrl->val]);
++ break;
++ case V4L2_CID_TEST_PATTERN_RED:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_R,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENR:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_GR,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_BLUE:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_B,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENB:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_GB,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ ret = imx708_write_reg(imx708, IMX708_REG_ORIENTATION, 1,
++ imx708->hflip->val |
++ imx708->vflip->val << 1);
++ break;
++ case V4L2_CID_VBLANK:
++ ret = imx708_set_frame_length(imx708,
++ imx708->mode->height + ctrl->val);
++ break;
++ case V4L2_CID_NOTIFY_GAINS:
++ ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_BLUE,
++ IMX708_REG_VALUE_16BIT,
++ imx708->notify_gains->p_new.p_u32[0]);
++ if (ret)
++ break;
++ ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_RED,
++ IMX708_REG_VALUE_16BIT,
++ imx708->notify_gains->p_new.p_u32[3]);
++ break;
++ case V4L2_CID_WIDE_DYNAMIC_RANGE:
++ get_mode_table(&mode_list, &num_modes, ctrl->val);
++ imx708->mode = v4l2_find_nearest_size(mode_list,
++ num_modes,
++ width, height,
++ imx708->mode->width,
++ imx708->mode->height);
++ imx708_set_framing_limits(imx708);
++ ret = 0;
++ break;
++ default:
++ dev_info(&client->dev,
++ "ctrl(id:0x%x,val:0x%x) is not handled\n",
++ ctrl->id, ctrl->val);
++ ret = -EINVAL;
++ break;
++ }
++
++ pm_runtime_mark_last_busy(&client->dev);
++ pm_runtime_put_autosuspend(&client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops imx708_ctrl_ops = {
++ .s_ctrl = imx708_set_ctrl,
++};
++
++static int imx708_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++
++ if (code->index >= 1)
++ return -EINVAL;
++
++ code->code = imx708_get_format_code(imx708);
++
++ return 0;
++}
++
++static int imx708_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++ const struct imx708_mode *mode_list;
++ unsigned int num_modes;
++
++ get_mode_table(&mode_list, &num_modes, imx708->hdr_mode->val);
++
++ if (fse->index >= num_modes)
++ return -EINVAL;
++
++ if (fse->code != imx708_get_format_code(imx708))
++ return -EINVAL;
++
++ fse->min_width = mode_list[fse->index].width;
++ fse->max_width = fse->min_width;
++ fse->min_height = mode_list[fse->index].height;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static void imx708_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
++{
++ fmt->colorspace = V4L2_COLORSPACE_RAW;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace,
++ fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++}
++
++static void imx708_update_image_pad_format(struct imx708 *imx708,
++ const struct imx708_mode *mode,
++ struct v4l2_subdev_format *fmt)
++{
++ fmt->format.width = mode->width;
++ fmt->format.height = mode->height;
++ fmt->format.field = V4L2_FIELD_NONE;
++ imx708_reset_colorspace(&fmt->format);
++}
++
++static int imx708_get_pad_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++
++ mutex_lock(&imx708->mutex);
++
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(&imx708->sd, sd_state,
++ fmt->pad);
++ /* update the code which could change due to vflip or hflip */
++ try_fmt->code = imx708_get_format_code(imx708);
++ fmt->format = *try_fmt;
++ } else {
++ imx708_update_image_pad_format(imx708, imx708->mode, fmt);
++ fmt->format.code = imx708_get_format_code(imx708);
++ }
++
++ mutex_unlock(&imx708->mutex);
++ return 0;
++}
++
++static int imx708_set_pad_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct v4l2_mbus_framefmt *framefmt;
++ const struct imx708_mode *mode;
++ struct imx708 *imx708 = to_imx708(sd);
++ const struct imx708_mode *mode_list;
++ unsigned int num_modes;
++
++ mutex_lock(&imx708->mutex);
++
++ /* Bayer order varies with flips */
++ fmt->format.code = imx708_get_format_code(imx708);
++
++ get_mode_table(&mode_list, &num_modes, imx708->hdr_mode->val);
++
++ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
++ fmt->format.width, fmt->format.height);
++ imx708_update_image_pad_format(imx708, mode, fmt);
++
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
++ *framefmt = fmt->format;
++ } else {
++ imx708->mode = mode;
++ imx708_set_framing_limits(imx708);
++ }
++
++ mutex_unlock(&imx708->mutex);
++
++ return 0;
++}
++
++static const struct v4l2_rect *
++__imx708_get_pad_crop(struct imx708 *imx708, struct v4l2_subdev_state *sd_state,
++ unsigned int pad, enum v4l2_subdev_format_whence which)
++{
++ switch (which) {
++ case V4L2_SUBDEV_FORMAT_TRY:
++ return v4l2_subdev_get_try_crop(&imx708->sd, sd_state, pad);
++ case V4L2_SUBDEV_FORMAT_ACTIVE:
++ return &imx708->mode->crop;
++ }
++
++ return NULL;
++}
++
++static int imx708_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_selection *sel)
++{
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP: {
++ struct imx708 *imx708 = to_imx708(sd);
++
++ mutex_lock(&imx708->mutex);
++ sel->r = *__imx708_get_pad_crop(imx708, sd_state, sel->pad,
++ sel->which);
++ mutex_unlock(&imx708->mutex);
++
++ return 0;
++ }
++
++ case V4L2_SEL_TGT_NATIVE_SIZE:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = IMX708_NATIVE_WIDTH;
++ sel->r.height = IMX708_NATIVE_HEIGHT;
++
++ return 0;
++
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = IMX708_PIXEL_ARRAY_LEFT;
++ sel->r.top = IMX708_PIXEL_ARRAY_TOP;
++ sel->r.width = IMX708_PIXEL_ARRAY_WIDTH;
++ sel->r.height = IMX708_PIXEL_ARRAY_HEIGHT;
++
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++/* Start streaming */
++static int imx708_start_streaming(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ const struct imx708_reg_list *reg_list;
++ int i, ret;
++ u32 val;
++
++ if (!imx708->common_regs_written) {
++ ret = imx708_write_regs(imx708, mode_common_regs,
++ ARRAY_SIZE(mode_common_regs));
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set common settings\n",
++ __func__);
++ return ret;
++ }
++
++ ret = imx708_read_reg(imx708, IMX708_REG_BASE_SPC_GAINS_L,
++ IMX708_REG_VALUE_08BIT, &val);
++ if (ret == 0 && val == 0x40) {
++ for (i = 0; i < 54 && ret == 0; i++) {
++ u16 reg = IMX708_REG_BASE_SPC_GAINS_L + i;
++
++ ret = imx708_write_reg(imx708, reg,
++ IMX708_REG_VALUE_08BIT,
++ pdaf_gains[0][i % 9]);
++ }
++ for (i = 0; i < 54 && ret == 0; i++) {
++ u16 reg = IMX708_REG_BASE_SPC_GAINS_R + i;
++
++ ret = imx708_write_reg(imx708, reg,
++ IMX708_REG_VALUE_08BIT,
++ pdaf_gains[1][i % 9]);
++ }
++ }
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set PDAF gains\n",
++ __func__);
++ return ret;
++ }
++
++ imx708->common_regs_written = true;
++ }
++
++ /* Apply default values of current mode */
++ reg_list = &imx708->mode->reg_list;
++ ret = imx708_write_regs(imx708, reg_list->regs, reg_list->num_of_regs);
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set mode\n", __func__);
++ return ret;
++ }
++
++ /* Apply customized values from user */
++ ret = __v4l2_ctrl_handler_setup(imx708->sd.ctrl_handler);
++ if (ret)
++ return ret;
++
++ /* set stream on register */
++ return imx708_write_reg(imx708, IMX708_REG_MODE_SELECT,
++ IMX708_REG_VALUE_08BIT, IMX708_MODE_STREAMING);
++}
++
++/* Stop streaming */
++static void imx708_stop_streaming(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ int ret;
++
++ /* set stream off register */
++ ret = imx708_write_reg(imx708, IMX708_REG_MODE_SELECT,
++ IMX708_REG_VALUE_08BIT, IMX708_MODE_STANDBY);
++ if (ret)
++ dev_err(&client->dev, "%s failed to set stream\n", __func__);
++}
++
++static int imx708_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret = 0;
++
++ mutex_lock(&imx708->mutex);
++ if (imx708->streaming == enable) {
++ mutex_unlock(&imx708->mutex);
++ return 0;
++ }
++
++ if (enable) {
++ ret = pm_runtime_resume_and_get(&client->dev);
++ if (ret < 0)
++ goto err_unlock;
++
++ /*
++ * Apply default & customized values
++ * and then start streaming.
++ */
++ ret = imx708_start_streaming(imx708);
++ if (ret)
++ goto err_rpm_put;
++ } else {
++ imx708_stop_streaming(imx708);
++ pm_runtime_mark_last_busy(&client->dev);
++ pm_runtime_put_autosuspend(&client->dev);
++ }
++
++ imx708->streaming = enable;
++
++ /* vflip/hflip and hdr mode cannot change during streaming */
++ __v4l2_ctrl_grab(imx708->vflip, enable);
++ __v4l2_ctrl_grab(imx708->hflip, enable);
++ __v4l2_ctrl_grab(imx708->hdr_mode, enable);
++
++ mutex_unlock(&imx708->mutex);
++
++ return ret;
++
++err_rpm_put:
++ pm_runtime_put_sync(&client->dev);
++err_unlock:
++ mutex_unlock(&imx708->mutex);
++
++ return ret;
++}
++
++/* Power/clock management functions */
++static int imx708_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++ int ret;
++
++ ret = regulator_bulk_enable(IMX708_NUM_SUPPLIES,
++ imx708->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(imx708->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ goto reg_off;
++ }
++
++ gpiod_set_value_cansleep(imx708->reset_gpio, 1);
++ usleep_range(IMX708_XCLR_MIN_DELAY_US,
++ IMX708_XCLR_MIN_DELAY_US + IMX708_XCLR_DELAY_RANGE_US);
++
++ return 0;
++
++reg_off:
++ regulator_bulk_disable(IMX708_NUM_SUPPLIES, imx708->supplies);
++ return ret;
++}
++
++static int imx708_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++
++ gpiod_set_value_cansleep(imx708->reset_gpio, 0);
++ clk_disable_unprepare(imx708->xclk);
++ regulator_bulk_disable(IMX708_NUM_SUPPLIES, imx708->supplies);
++
++ /* Force reprogramming of the common registers when powered up again. */
++ imx708->common_regs_written = false;
++
++ return 0;
++}
++
++static int __maybe_unused imx708_suspend(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++
++ if (imx708->streaming)
++ imx708_stop_streaming(imx708);
++
++ return 0;
++}
++
++static int __maybe_unused imx708_resume(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++ int ret;
++
++ if (imx708->streaming) {
++ ret = imx708_start_streaming(imx708);
++ if (ret)
++ goto error;
++ }
++
++ return 0;
++
++error:
++ imx708_stop_streaming(imx708);
++ imx708->streaming = 0;
++ return ret;
++}
++
++static int imx708_get_regulators(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ unsigned int i;
++
++ for (i = 0; i < IMX708_NUM_SUPPLIES; i++)
++ imx708->supplies[i].supply = imx708_supply_name[i];
++
++ return devm_regulator_bulk_get(&client->dev,
++ IMX708_NUM_SUPPLIES,
++ imx708->supplies);
++}
++
++/* Verify chip ID */
++static int imx708_identify_module(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ int ret;
++ u32 val;
++
++ ret = imx708_read_reg(imx708, IMX708_REG_CHIP_ID,
++ IMX708_REG_VALUE_16BIT, &val);
++ if (ret) {
++ dev_err(&client->dev, "failed to read chip id %x, with error %d\n",
++ IMX708_CHIP_ID, ret);
++ return ret;
++ }
++
++ if (val != IMX708_CHIP_ID) {
++ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
++ IMX708_CHIP_ID, val);
++ return -EIO;
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops imx708_core_ops = {
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops imx708_video_ops = {
++ .s_stream = imx708_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops imx708_pad_ops = {
++ .enum_mbus_code = imx708_enum_mbus_code,
++ .get_fmt = imx708_get_pad_format,
++ .set_fmt = imx708_set_pad_format,
++ .get_selection = imx708_get_selection,
++ .enum_frame_size = imx708_enum_frame_size,
++};
++
++static const struct v4l2_subdev_ops imx708_subdev_ops = {
++ .core = &imx708_core_ops,
++ .video = &imx708_video_ops,
++ .pad = &imx708_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops imx708_internal_ops = {
++ .open = imx708_open,
++};
++
++static const struct v4l2_ctrl_config imx708_notify_gains_ctrl = {
++ .ops = &imx708_ctrl_ops,
++ .id = V4L2_CID_NOTIFY_GAINS,
++ .type = V4L2_CTRL_TYPE_U32,
++ .min = IMX708_COLOUR_BALANCE_MIN,
++ .max = IMX708_COLOUR_BALANCE_MAX,
++ .step = IMX708_COLOUR_BALANCE_STEP,
++ .def = IMX708_COLOUR_BALANCE_DEFAULT,
++ .dims = { 4 },
++ .elem_size = sizeof(u32),
++};
++
++/* Initialize control handlers */
++static int imx708_init_controls(struct imx708 *imx708)
++{
++ struct v4l2_ctrl_handler *ctrl_hdlr;
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ struct v4l2_fwnode_device_properties props;
++ unsigned int i;
++ int ret;
++
++ ctrl_hdlr = &imx708->ctrl_handler;
++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
++ if (ret)
++ return ret;
++
++ mutex_init(&imx708->mutex);
++ ctrl_hdlr->lock = &imx708->mutex;
++
++ /* By default, PIXEL_RATE is read only */
++ imx708->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_PIXEL_RATE,
++ imx708->mode->pixel_rate,
++ imx708->mode->pixel_rate, 1,
++ imx708->mode->pixel_rate);
++
++ /*
++ * Create the controls here, but mode specific limits are setup
++ * in the imx708_set_framing_limits() call below.
++ */
++ imx708->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_VBLANK, 0, 0xffff, 1, 0);
++ imx708->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_HBLANK, 0, 0xffff, 1, 0);
++
++ imx708->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_EXPOSURE,
++ IMX708_EXPOSURE_MIN,
++ IMX708_EXPOSURE_MAX,
++ IMX708_EXPOSURE_STEP,
++ IMX708_EXPOSURE_DEFAULT);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
++ IMX708_ANA_GAIN_MIN, IMX708_ANA_GAIN_MAX,
++ IMX708_ANA_GAIN_STEP, IMX708_ANA_GAIN_DEFAULT);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
++ IMX708_DGTL_GAIN_MIN, IMX708_DGTL_GAIN_MAX,
++ IMX708_DGTL_GAIN_STEP, IMX708_DGTL_GAIN_DEFAULT);
++
++ imx708->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++
++ imx708->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++
++ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(imx708_test_pattern_menu) - 1,
++ 0, 0, imx708_test_pattern_menu);
++ for (i = 0; i < 4; i++) {
++ /*
++ * The assumption is that
++ * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
++ * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
++ * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
++ */
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_TEST_PATTERN_RED + i,
++ IMX708_TEST_PATTERN_COLOUR_MIN,
++ IMX708_TEST_PATTERN_COLOUR_MAX,
++ IMX708_TEST_PATTERN_COLOUR_STEP,
++ IMX708_TEST_PATTERN_COLOUR_MAX);
++ /* The "Solid color" pattern is white by default */
++ }
++
++ imx708->notify_gains = v4l2_ctrl_new_custom(ctrl_hdlr,
++ &imx708_notify_gains_ctrl,
++ NULL);
++
++ imx708->hdr_mode = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_WIDE_DYNAMIC_RANGE,
++ 0, 1, 1, 0);
++
++ ret = v4l2_fwnode_device_parse(&client->dev, &props);
++ if (ret)
++ goto error;
++
++ v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx708_ctrl_ops, &props);
++
++ if (ctrl_hdlr->error) {
++ ret = ctrl_hdlr->error;
++ dev_err(&client->dev, "%s control init failed (%d)\n",
++ __func__, ret);
++ goto error;
++ }
++
++ imx708->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ imx708->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++ imx708->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++ imx708->hdr_mode->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
++ imx708->sd.ctrl_handler = ctrl_hdlr;
++
++ /* Setup exposure and frame/line length limits. */
++ imx708_set_framing_limits(imx708);
++
++ return 0;
++
++error:
++ v4l2_ctrl_handler_free(ctrl_hdlr);
++ mutex_destroy(&imx708->mutex);
++
++ return ret;
++}
++
++static void imx708_free_controls(struct imx708 *imx708)
++{
++ v4l2_ctrl_handler_free(imx708->sd.ctrl_handler);
++ mutex_destroy(&imx708->mutex);
++}
++
++static int imx708_check_hwcfg(struct device *dev)
++{
++ struct fwnode_handle *endpoint;
++ struct v4l2_fwnode_endpoint ep_cfg = {
++ .bus_type = V4L2_MBUS_CSI2_DPHY
++ };
++ int ret = -EINVAL;
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) {
++ dev_err(dev, "could not parse endpoint\n");
++ goto error_out;
++ }
++
++ /* Check the number of MIPI CSI2 data lanes */
++ if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) {
++ dev_err(dev, "only 2 data lanes are currently supported\n");
++ goto error_out;
++ }
++
++ /* Check the link frequency set in device tree */
++ if (!ep_cfg.nr_of_link_frequencies) {
++ dev_err(dev, "link-frequency property not found in DT\n");
++ goto error_out;
++ }
++
++ if (ep_cfg.nr_of_link_frequencies != 1 ||
++ ep_cfg.link_frequencies[0] != IMX708_DEFAULT_LINK_FREQ) {
++ dev_err(dev, "Link frequency not supported: %lld\n",
++ ep_cfg.link_frequencies[0]);
++ goto error_out;
++ }
++
++ ret = 0;
++
++error_out:
++ v4l2_fwnode_endpoint_free(&ep_cfg);
++ fwnode_handle_put(endpoint);
++
++ return ret;
++}
++
++static int imx708_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct imx708 *imx708;
++ int ret;
++
++ imx708 = devm_kzalloc(&client->dev, sizeof(*imx708), GFP_KERNEL);
++ if (!imx708)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&imx708->sd, client, &imx708_subdev_ops);
++
++ /* Check the hardware configuration in device tree */
++ if (imx708_check_hwcfg(dev))
++ return -EINVAL;
++
++ /* Get system clock (xclk) */
++ imx708->xclk = devm_clk_get(dev, NULL);
++ if (IS_ERR(imx708->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(imx708->xclk);
++ }
++
++ imx708->xclk_freq = clk_get_rate(imx708->xclk);
++ if (imx708->xclk_freq != IMX708_XCLK_FREQ) {
++ dev_err(dev, "xclk frequency not supported: %d Hz\n",
++ imx708->xclk_freq);
++ return -EINVAL;
++ }
++
++ ret = imx708_get_regulators(imx708);
++ if (ret) {
++ dev_err(dev, "failed to get regulators\n");
++ return ret;
++ }
++
++ /* Request optional enable pin */
++ imx708->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++
++ /*
++ * The sensor must be powered for imx708_identify_module()
++ * to be able to read the CHIP_ID register
++ */
++ ret = imx708_power_on(dev);
++ if (ret)
++ return ret;
++
++ ret = imx708_identify_module(imx708);
++ if (ret)
++ goto error_power_off;
++
++ /* Initialize default format */
++ imx708_set_default_format(imx708);
++
++ /*
++ * Enable runtime PM with autosuspend. As the device has been powered
++ * manually, mark it as active, and increase the usage count without
++ * resuming the device.
++ */
++ pm_runtime_set_active(dev);
++ pm_runtime_get_noresume(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_set_autosuspend_delay(dev, 1000);
++ pm_runtime_use_autosuspend(dev);
++
++ /* This needs the pm runtime to be registered. */
++ ret = imx708_init_controls(imx708);
++ if (ret)
++ goto error_power_off;
++
++ /* Initialize subdev */
++ imx708->sd.internal_ops = &imx708_internal_ops;
++ imx708->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ imx708->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++
++ /* Initialize source pad */
++ imx708->pad.flags = MEDIA_PAD_FL_SOURCE;
++
++ ret = media_entity_pads_init(&imx708->sd.entity, 1, &imx708->pad);
++ if (ret) {
++ dev_err(dev, "failed to init entity pads: %d\n", ret);
++ goto error_handler_free;
++ }
++
++ ret = v4l2_async_register_subdev_sensor(&imx708->sd);
++ if (ret < 0) {
++ dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
++ goto error_media_entity;
++ }
++
++ /*
++ * Decrease the PM usage count. The device will get suspended after the
++ * autosuspend delay, turning the power off.
++ */
++ pm_runtime_mark_last_busy(dev);
++ pm_runtime_put_autosuspend(dev);
++
++ return 0;
++
++error_media_entity:
++ media_entity_cleanup(&imx708->sd.entity);
++
++error_handler_free:
++ imx708_free_controls(imx708);
++
++error_power_off:
++ pm_runtime_disable(&client->dev);
++ pm_runtime_put_noidle(&client->dev);
++ imx708_power_off(&client->dev);
++
++ return ret;
++}
++
++static void imx708_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++
++ v4l2_async_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ imx708_free_controls(imx708);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ imx708_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct of_device_id imx708_dt_ids[] = {
++ { .compatible = "sony,imx708" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, imx708_dt_ids);
++
++static const struct dev_pm_ops imx708_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(imx708_suspend, imx708_resume)
++ SET_RUNTIME_PM_OPS(imx708_power_off, imx708_power_on, NULL)
++};
++
++static struct i2c_driver imx708_i2c_driver = {
++ .driver = {
++ .name = "imx708",
++ .of_match_table = imx708_dt_ids,
++ .pm = &imx708_pm_ops,
++ },
++ .probe = imx708_probe,
++ .remove = imx708_remove,
++};
++
++module_i2c_driver(imx708_i2c_driver);
++
++MODULE_AUTHOR("David Plowman <david.plowman@raspberrypi.com>");
++MODULE_DESCRIPTION("Sony IMX708 sensor driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch b/target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch
new file mode 100644
index 0000000000..c3971ed62b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch
@@ -0,0 +1,69 @@
+From 280ab217867d0b934454a837540eab665e854b47 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 3 Apr 2023 15:28:11 +0800
+Subject: [PATCH 088/116] media: i2c: imx708: Delete gain
+
+Delete gain.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/media/i2c/imx708.c | 27 ---------------------------
+ 1 file changed, 27 deletions(-)
+
+--- a/drivers/media/i2c/imx708.c
++++ b/drivers/media/i2c/imx708.c
+@@ -777,7 +777,6 @@ struct imx708 {
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *red_balance;
+ struct v4l2_ctrl *blue_balance;
+- struct v4l2_ctrl *notify_gains;
+ struct v4l2_ctrl *hdr_mode;
+
+ /* Current mode */
+@@ -1108,16 +1107,6 @@ static int imx708_set_ctrl(struct v4l2_c
+ ret = imx708_set_frame_length(imx708,
+ imx708->mode->height + ctrl->val);
+ break;
+- case V4L2_CID_NOTIFY_GAINS:
+- ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_BLUE,
+- IMX708_REG_VALUE_16BIT,
+- imx708->notify_gains->p_new.p_u32[0]);
+- if (ret)
+- break;
+- ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_RED,
+- IMX708_REG_VALUE_16BIT,
+- imx708->notify_gains->p_new.p_u32[3]);
+- break;
+ case V4L2_CID_WIDE_DYNAMIC_RANGE:
+ get_mode_table(&mode_list, &num_modes, ctrl->val);
+ imx708->mode = v4l2_find_nearest_size(mode_list,
+@@ -1584,18 +1573,6 @@ static const struct v4l2_subdev_internal
+ .open = imx708_open,
+ };
+
+-static const struct v4l2_ctrl_config imx708_notify_gains_ctrl = {
+- .ops = &imx708_ctrl_ops,
+- .id = V4L2_CID_NOTIFY_GAINS,
+- .type = V4L2_CTRL_TYPE_U32,
+- .min = IMX708_COLOUR_BALANCE_MIN,
+- .max = IMX708_COLOUR_BALANCE_MAX,
+- .step = IMX708_COLOUR_BALANCE_STEP,
+- .def = IMX708_COLOUR_BALANCE_DEFAULT,
+- .dims = { 4 },
+- .elem_size = sizeof(u32),
+-};
+-
+ /* Initialize control handlers */
+ static int imx708_init_controls(struct imx708 *imx708)
+ {
+@@ -1670,10 +1647,6 @@ static int imx708_init_controls(struct i
+ /* The "Solid color" pattern is white by default */
+ }
+
+- imx708->notify_gains = v4l2_ctrl_new_custom(ctrl_hdlr,
+- &imx708_notify_gains_ctrl,
+- NULL);
+-
+ imx708->hdr_mode = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
+ V4L2_CID_WIDE_DYNAMIC_RANGE,
+ 0, 1, 1, 0);
diff --git a/target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch b/target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch
new file mode 100644
index 0000000000..e8baa80eb9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch
@@ -0,0 +1,270 @@
+From aa4febf074cbaad81c981a5c6b55324a6f676fb7 Mon Sep 17 00:00:00 2001
+From: "shengyang.chen" <shengyang.chen@starfivetech.com>
+Date: Tue, 13 Jun 2023 14:22:29 +0800
+Subject: [PATCH 089/116] dt-bindings: display: Add yamls for JH7110 display
+ system and hdmi
+
+StarFive SoCs like the jh7110 use display system based on verisilicon IP, use hdmi
+base on innosilicon IP. Add bindings for them.
+
+Signed-off-by: Shengyang Chen <shengyang.chen@starfivetech.com>
+---
+ .../display/verisilicon/starfive-hdmi.yaml | 92 +++++++++++++++
+ .../display/verisilicon/verisilicon-dc.yaml | 109 ++++++++++++++++++
+ .../display/verisilicon/verisilicon-drm.yaml | 41 +++++++
+ 3 files changed, 242 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/display/verisilicon/starfive-hdmi.yaml
+ create mode 100644 Documentation/devicetree/bindings/display/verisilicon/verisilicon-dc.yaml
+ create mode 100644 Documentation/devicetree/bindings/display/verisilicon/verisilicon-drm.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/display/verisilicon/starfive-hdmi.yaml
+@@ -0,0 +1,92 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/display/verisilicon/starfive-hdmi.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive SoC HDMI transmiter
++
++description:
++ The StarFive SoC uses the HDMI signal transmiter based on innosilicon IP
++ to generate HDMI signal from its input and transmit the signal to the screen.
++
++maintainers:
++ - Keith Zhao <keith.zhao@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,hdmi
++
++ reg:
++ minItems: 1
++
++ interrupts:
++ items:
++ - description: The HDMI hot plug detection interrupt.
++
++ clocks:
++ items:
++ - description: System clock of HDMI module.
++ - description: Mclk clock of HDMI audio.
++ - description: Bclk clock of HDMI audio.
++ - description: Pixel clock generated by HDMI module.
++
++ clock-names:
++ items:
++ - const: sysclk
++ - const: mclk
++ - const: bclk
++ - const: pclk
++
++ resets:
++ items:
++ - description: Reset for HDMI module.
++
++ reset-names:
++ items:
++ - const: hdmi_tx
++
++ '#sound-dai-cells':
++ const: 0
++
++ port:
++ $ref: /schemas/graph.yaml#/properties/port
++ description:
++ Port node with one endpoint connected to a display connector node.
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - '#sound-dai-cells'
++ - port
++
++additionalProperties: false
++
++examples:
++ - |
++ hdmi: hdmi@29590000 {
++ compatible = "starfive,hdmi";
++ reg = <0x29590000 0x4000>;
++ interrupts = <99>;
++ clocks = <&voutcrg 17>,
++ <&voutcrg 15>,
++ <&voutcrg 16>,
++ <&hdmitx0_pixelclk>;
++ clock-names = "sysclk", "mclk","bclk","pclk";
++ resets = <&voutcrg 9>;
++ reset-names = "hdmi_tx";
++ #sound-dai-cells = <0>;
++ hdmi_in: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ hdmi_input: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi0>;
++ };
++ };
++ };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/display/verisilicon/verisilicon-dc.yaml
+@@ -0,0 +1,109 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/display/verisilicon/verisilicon-dc.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive SoC display controller
++
++description:
++ The StarFive SoC uses the display controller based on Verisilicon IP
++ to transfer the image data from a video memory
++ buffer to an external LCD interface.
++
++maintainers:
++ - Keith Zhao <keith.zhao@starfivetech.com>
++
++properties:
++ compatible:
++ const: verisilicon,dc8200
++
++ reg:
++ maxItems: 3
++
++ interrupts:
++ items:
++ - description: The interrupt will be generated when DC finish one frame
++
++ clocks:
++ items:
++ - description: Clock for display system noc bus.
++ - description: Pixel clock for display channel 0.
++ - description: Pixel clock for display channel 1.
++ - description: Clock for axi interface of display controller.
++ - description: Core clock for display controller.
++ - description: Clock for ahb interface of display controller.
++ - description: External HDMI pixel clock.
++ - description: Parent clock for pixel clock
++
++ clock-names:
++ items:
++ - const: clk_vout_noc_disp
++ - const: clk_vout_pix0
++ - const: clk_vout_pix1
++ - const: clk_vout_axi
++ - const: clk_vout_core
++ - const: clk_vout_vout_ahb
++ - const: hdmitx0_pixel
++ - const: clk_vout_dc8200
++
++ resets:
++ items:
++ - description: Reset for axi interface of display controller.
++ - description: Reset for ahb interface of display controller.
++ - description: Core reset of display controller.
++
++ reset-names:
++ items:
++ - const: rst_vout_axi
++ - const: rst_vout_ahb
++ - const: rst_vout_core
++
++ port:
++ $ref: /schemas/graph.yaml#/properties/port
++ description:
++ Port node with one endpoint connected to a hdmi node.
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - port
++
++additionalProperties: false
++
++examples:
++ - |
++ dc8200: dc8200@29400000 {
++ compatible = "verisilicon,dc8200";
++ reg = <0x29400000 0x100>,
++ <0x29400800 0x2000>,
++ <0x295B0000 0x90>;
++ interrupts = <95>;
++ clocks = <&syscrg 60>,
++ <&voutcrg 7>,
++ <&voutcrg 8>,
++ <&voutcrg 4>,
++ <&voutcrg 5>,
++ <&voutcrg 6>,
++ <&hdmitx0_pixelclk>,
++ <&voutcrg 1>;
++ clock-names = "clk_vout_noc_disp", "clk_vout_pix0", "clk_vout_pix1", "clk_vout_axi",
++ "clk_vout_core", "clk_vout_vout_ahb", "hdmitx0_pixel","clk_vout_dc8200";
++ resets = <&voutcrg 0>,
++ <&voutcrg 1>,
++ <&voutcrg 2>;
++ reset-names = "rst_vout_axi","rst_vout_ahb","rst_vout_core";
++ dc_out: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ dc_out_dpi0: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&hdmi_input>;
++ };
++ };
++ };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/display/verisilicon/verisilicon-drm.yaml
+@@ -0,0 +1,41 @@
++# SPDX-License-Identifier: (GPL-2.0-only)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/display/verisilicon/verisilicon-drm.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Verisilicon DRM master device
++
++maintainers:
++ - Keith Zhao <keith.zhao@starfivetech.com>
++
++description: |
++ The Verisilicon DRM master device is a virtual device needed to list all
++ display controller or other display interface nodes that comprise the
++ graphics subsystem.
++
++properties:
++ compatible:
++ const: verisilicon,display-subsystem
++
++ ports:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ items:
++ maxItems: 1
++ description: |
++ Should contain a list of phandles pointing to display interface ports
++ of display controller devices. Display controller definitions as defined in
++ Documentation/devicetree/bindings/display/verisilicon/verisilicon-dc.yaml
++
++required:
++ - compatible
++ - ports
++
++additionalProperties: false
++
++examples:
++ - |
++ display-subsystem {
++ compatible = "verisilicon,display-subsystem";
++ ports = <&dc_out>;
++ };
diff --git a/target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch b/target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch
new file mode 100644
index 0000000000..7a6bfa8c4f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch
@@ -0,0 +1,82 @@
+From 5cbf4154da600af8a2e6a2f8d57d1f212abf3f92 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 13 Oct 2023 14:10:24 +0800
+Subject: [PATCH 090/116] soc: starfive: jh71xx_pmu: Add EVENT_TURN_OFF
+ register writing support
+
+Add and export starfive_pmu_hw_event_turn_off_mask() to
+write EVENT_TURN_OFF register.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 11 ++++++++++
+ include/soc/starfive/jh7110_pmu.h | 29 ++++++++++++++++++++++++++
+ 2 files changed, 40 insertions(+)
+ create mode 100644 include/soc/starfive/jh7110_pmu.h
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -16,6 +16,7 @@
+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
+
+ /* register offset */
++#define JH71XX_PMU_HW_EVENT_TURN_OFF 0x08
+ #define JH71XX_PMU_SW_TURN_ON_POWER 0x0C
+ #define JH71XX_PMU_SW_TURN_OFF_POWER 0x10
+ #define JH71XX_PMU_SW_ENCOURAGE 0x44
+@@ -83,6 +84,14 @@ struct jh71xx_pmu_dev {
+ struct generic_pm_domain genpd;
+ };
+
++static void __iomem *pmu_base;
++
++void starfive_pmu_hw_event_turn_off_mask(u32 mask)
++{
++ writel(mask, pmu_base + JH71XX_PMU_HW_EVENT_TURN_OFF);
++}
++EXPORT_SYMBOL(starfive_pmu_hw_event_turn_off_mask);
++
+ static int jh71xx_pmu_get_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool *is_on)
+ {
+ struct jh71xx_pmu *pmu = pmd->pmu;
+@@ -334,6 +343,8 @@ static int jh71xx_pmu_probe(struct platf
+ if (IS_ERR(pmu->base))
+ return PTR_ERR(pmu->base);
+
++ pmu_base = pmu->base;
++
+ spin_lock_init(&pmu->lock);
+
+ match_data = of_device_get_match_data(dev);
+--- /dev/null
++++ b/include/soc/starfive/jh7110_pmu.h
+@@ -0,0 +1,29 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/*
++ * PMU driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 samin <samin.guo@starfivetech.com>
++ */
++
++#ifndef __SOC_STARFIVE_JH7110_PMU_H__
++#define __SOC_STARFIVE_JH7110_PMU_H__
++
++#include <linux/bits.h>
++#include <linux/types.h>
++
++enum PMU_HARD_EVENT {
++ PMU_HW_EVENT_RTC = BIT(0),
++ PMU_HW_EVENT_GMAC = BIT(1),
++ PMU_HW_EVENT_RFU = BIT(2),
++ PMU_HW_EVENT_RGPIO0 = BIT(3),
++ PMU_HW_EVENT_RGPIO1 = BIT(4),
++ PMU_HW_EVENT_RGPIO2 = BIT(5),
++ PMU_HW_EVENT_RGPIO3 = BIT(6),
++ PMU_HW_EVENT_GPU = BIT(7),
++ PMU_HW_EVENT_ALL = GENMASK(7, 0),
++};
++
++void starfive_pmu_hw_event_turn_off_mask(u32 mask);
++
++#endif /* __SOC_STARFIVE_JH7110_PMU_H__ */
++
diff --git a/target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch b/target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch
new file mode 100644
index 0000000000..a6b69660c3
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch
@@ -0,0 +1,22 @@
+From ab436ea7ffb6c464616addad98632c81a321844a Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 12 Dec 2023 17:56:58 +0800
+Subject: [PATCH 091/116] workqueue: Enable flush_scheduled_work()
+
+Enable flush_scheduled_work() for JH7110 GPU.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ include/linux/workqueue.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -636,7 +636,6 @@ extern void __warn_flushing_systemwide_w
+ /* Please stop using this function, for this function will be removed in near future. */
+ #define flush_scheduled_work() \
+ ({ \
+- __warn_flushing_systemwide_wq(); \
+ __flush_workqueue(system_wq); \
+ })
+
diff --git a/target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch b/target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch
new file mode 100644
index 0000000000..39c27237b0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch
@@ -0,0 +1,506 @@
+From dedbbfd891e4d0cdb825454eddfbf8386d0025b3 Mon Sep 17 00:00:00 2001
+From: Mason Huo <mason.huo@starfivetech.com>
+Date: Tue, 20 Jun 2023 13:37:52 +0800
+Subject: [PATCH 092/116] riscv: Optimize memcpy with aligned version
+
+Optimizing the 128 byte align case, this will improve the
+performance of large block memcpy.
+
+Here we combine the memcpy of glibc and kernel.
+
+Signed-off-by: Mason Huo <mason.huo@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/lib/Makefile | 3 +-
+ arch/riscv/lib/{memcpy.S => memcpy_aligned.S} | 36 +--
+ arch/riscv/lib/string.c | 266 ++++++++++++++++++
+ 3 files changed, 273 insertions(+), 32 deletions(-)
+ rename arch/riscv/lib/{memcpy.S => memcpy_aligned.S} (67%)
+ create mode 100644 arch/riscv/lib/string.c
+
+--- a/arch/riscv/lib/Makefile
++++ b/arch/riscv/lib/Makefile
+@@ -1,6 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ lib-y += delay.o
+-lib-y += memcpy.o
+ lib-y += memset.o
+ lib-y += memmove.o
+ lib-y += strcmp.o
+@@ -9,5 +8,7 @@ lib-y += strncmp.o
+ lib-$(CONFIG_MMU) += uaccess.o
+ lib-$(CONFIG_64BIT) += tishift.o
+ lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
++lib-y += string.o
++lib-y += memcpy_aligned.o
+
+ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
+--- a/arch/riscv/lib/memcpy.S
++++ /dev/null
+@@ -1,110 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-/*
+- * Copyright (C) 2013 Regents of the University of California
+- */
+-
+-#include <linux/linkage.h>
+-#include <asm/asm.h>
+-
+-/* void *memcpy(void *, const void *, size_t) */
+-ENTRY(__memcpy)
+-WEAK(memcpy)
+- move t6, a0 /* Preserve return value */
+-
+- /* Defer to byte-oriented copy for small sizes */
+- sltiu a3, a2, 128
+- bnez a3, 4f
+- /* Use word-oriented copy only if low-order bits match */
+- andi a3, t6, SZREG-1
+- andi a4, a1, SZREG-1
+- bne a3, a4, 4f
+-
+- beqz a3, 2f /* Skip if already aligned */
+- /*
+- * Round to nearest double word-aligned address
+- * greater than or equal to start address
+- */
+- andi a3, a1, ~(SZREG-1)
+- addi a3, a3, SZREG
+- /* Handle initial misalignment */
+- sub a4, a3, a1
+-1:
+- lb a5, 0(a1)
+- addi a1, a1, 1
+- sb a5, 0(t6)
+- addi t6, t6, 1
+- bltu a1, a3, 1b
+- sub a2, a2, a4 /* Update count */
+-
+-2:
+- andi a4, a2, ~((16*SZREG)-1)
+- beqz a4, 4f
+- add a3, a1, a4
+-3:
+- REG_L a4, 0(a1)
+- REG_L a5, SZREG(a1)
+- REG_L a6, 2*SZREG(a1)
+- REG_L a7, 3*SZREG(a1)
+- REG_L t0, 4*SZREG(a1)
+- REG_L t1, 5*SZREG(a1)
+- REG_L t2, 6*SZREG(a1)
+- REG_L t3, 7*SZREG(a1)
+- REG_L t4, 8*SZREG(a1)
+- REG_L t5, 9*SZREG(a1)
+- REG_S a4, 0(t6)
+- REG_S a5, SZREG(t6)
+- REG_S a6, 2*SZREG(t6)
+- REG_S a7, 3*SZREG(t6)
+- REG_S t0, 4*SZREG(t6)
+- REG_S t1, 5*SZREG(t6)
+- REG_S t2, 6*SZREG(t6)
+- REG_S t3, 7*SZREG(t6)
+- REG_S t4, 8*SZREG(t6)
+- REG_S t5, 9*SZREG(t6)
+- REG_L a4, 10*SZREG(a1)
+- REG_L a5, 11*SZREG(a1)
+- REG_L a6, 12*SZREG(a1)
+- REG_L a7, 13*SZREG(a1)
+- REG_L t0, 14*SZREG(a1)
+- REG_L t1, 15*SZREG(a1)
+- addi a1, a1, 16*SZREG
+- REG_S a4, 10*SZREG(t6)
+- REG_S a5, 11*SZREG(t6)
+- REG_S a6, 12*SZREG(t6)
+- REG_S a7, 13*SZREG(t6)
+- REG_S t0, 14*SZREG(t6)
+- REG_S t1, 15*SZREG(t6)
+- addi t6, t6, 16*SZREG
+- bltu a1, a3, 3b
+- andi a2, a2, (16*SZREG)-1 /* Update count */
+-
+-4:
+- /* Handle trailing misalignment */
+- beqz a2, 6f
+- add a3, a1, a2
+-
+- /* Use word-oriented copy if co-aligned to word boundary */
+- or a5, a1, t6
+- or a5, a5, a3
+- andi a5, a5, 3
+- bnez a5, 5f
+-7:
+- lw a4, 0(a1)
+- addi a1, a1, 4
+- sw a4, 0(t6)
+- addi t6, t6, 4
+- bltu a1, a3, 7b
+-
+- ret
+-
+-5:
+- lb a4, 0(a1)
+- addi a1, a1, 1
+- sb a4, 0(t6)
+- addi t6, t6, 1
+- bltu a1, a3, 5b
+-6:
+- ret
+-END(__memcpy)
+-SYM_FUNC_ALIAS(__pi_memcpy, __memcpy)
+-SYM_FUNC_ALIAS(__pi___memcpy, __memcpy)
+--- /dev/null
++++ b/arch/riscv/lib/memcpy_aligned.S
+@@ -0,0 +1,84 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2013 Regents of the University of California
++ */
++
++#include <linux/linkage.h>
++#include <asm/asm.h>
++
++/* void *__memcpy_aligned(void *, const void *, size_t) */
++ENTRY(__memcpy_aligned)
++ move t6, a0 /* Preserve return value */
++
++2:
++ andi a4, a2, ~((16*SZREG)-1)
++ beqz a4, 4f
++ add a3, a1, a4
++3:
++ REG_L a4, 0(a1)
++ REG_L a5, SZREG(a1)
++ REG_L a6, 2*SZREG(a1)
++ REG_L a7, 3*SZREG(a1)
++ REG_L t0, 4*SZREG(a1)
++ REG_L t1, 5*SZREG(a1)
++ REG_L t2, 6*SZREG(a1)
++ REG_L t3, 7*SZREG(a1)
++ REG_L t4, 8*SZREG(a1)
++ REG_L t5, 9*SZREG(a1)
++ REG_S a4, 0(t6)
++ REG_S a5, SZREG(t6)
++ REG_S a6, 2*SZREG(t6)
++ REG_S a7, 3*SZREG(t6)
++ REG_S t0, 4*SZREG(t6)
++ REG_S t1, 5*SZREG(t6)
++ REG_S t2, 6*SZREG(t6)
++ REG_S t3, 7*SZREG(t6)
++ REG_S t4, 8*SZREG(t6)
++ REG_S t5, 9*SZREG(t6)
++ REG_L a4, 10*SZREG(a1)
++ REG_L a5, 11*SZREG(a1)
++ REG_L a6, 12*SZREG(a1)
++ REG_L a7, 13*SZREG(a1)
++ REG_L t0, 14*SZREG(a1)
++ REG_L t1, 15*SZREG(a1)
++ addi a1, a1, 16*SZREG
++ REG_S a4, 10*SZREG(t6)
++ REG_S a5, 11*SZREG(t6)
++ REG_S a6, 12*SZREG(t6)
++ REG_S a7, 13*SZREG(t6)
++ REG_S t0, 14*SZREG(t6)
++ REG_S t1, 15*SZREG(t6)
++ addi t6, t6, 16*SZREG
++ bltu a1, a3, 3b
++ andi a2, a2, (16*SZREG)-1 /* Update count */
++
++4:
++ /* Handle trailing misalignment */
++ beqz a2, 6f
++ add a3, a1, a2
++
++ /* Use word-oriented copy if co-aligned to word boundary */
++ or a5, a1, t6
++ or a5, a5, a3
++ andi a5, a5, 3
++ bnez a5, 5f
++7:
++ lw a4, 0(a1)
++ addi a1, a1, 4
++ sw a4, 0(t6)
++ addi t6, t6, 4
++ bltu a1, a3, 7b
++
++ ret
++
++5:
++ lb a4, 0(a1)
++ addi a1, a1, 1
++ sb a4, 0(t6)
++ addi t6, t6, 1
++ bltu a1, a3, 5b
++6:
++ ret
++END(__memcpy_aligned)
++SYM_FUNC_ALIAS(__pi_memcpy, __memcpy_aligned)
++SYM_FUNC_ALIAS(__pi___memcpy, __memcpy_aligned)
+--- /dev/null
++++ b/arch/riscv/lib/string.c
+@@ -0,0 +1,266 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copy memory to memory until the specified number of bytes
++ * has been copied. Overlap is NOT handled correctly.
++ * Copyright (C) 1991-2020 Free Software Foundation, Inc.
++ * This file is part of the GNU C Library.
++ * Contributed by Torbjorn Granlund (tege@sics.se).
++ *
++ * The GNU C Library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * The GNU C Library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with the GNU C Library; if not, see
++ * <https://www.gnu.org/licenses/>.
++ *
++ */
++
++#define __NO_FORTIFY
++#include <linux/types.h>
++#include <linux/module.h>
++
++#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
++#define OP_T_THRES 16
++#define op_t unsigned long
++#define OPSIZ (sizeof(op_t))
++#define OPSIZ_MASK (sizeof(op_t) - 1)
++#define FAST_COPY_THRES (128)
++#define byte unsigned char
++
++static void _wordcopy_fwd_aligned(long dstp, long srcp, size_t len)
++{
++ op_t a0, a1;
++
++ switch (len % 8) {
++ case 2:
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 6 * OPSIZ;
++ dstp -= 7 * OPSIZ;
++ len += 6;
++ goto do1;
++ case 3:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= 5 * OPSIZ;
++ dstp -= 6 * OPSIZ;
++ len += 5;
++ goto do2;
++ case 4:
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 4 * OPSIZ;
++ dstp -= 5 * OPSIZ;
++ len += 4;
++ goto do3;
++ case 5:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= 3 * OPSIZ;
++ dstp -= 4 * OPSIZ;
++ len += 3;
++ goto do4;
++ case 6:
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 2 * OPSIZ;
++ dstp -= 3 * OPSIZ;
++ len += 2;
++ goto do5;
++ case 7:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= 1 * OPSIZ;
++ dstp -= 2 * OPSIZ;
++ len += 1;
++ goto do6;
++
++ case 0:
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ return;
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 0 * OPSIZ;
++ dstp -= 1 * OPSIZ;
++ goto do7;
++ case 1:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= -1 * OPSIZ;
++ dstp -= 0 * OPSIZ;
++ len -= 1;
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ goto do0;
++ goto do8; /* No-op. */
++ }
++
++ do {
++do8:
++ a0 = ((op_t *) srcp)[0];
++ ((op_t *) dstp)[0] = a1;
++do7:
++ a1 = ((op_t *) srcp)[1];
++ ((op_t *) dstp)[1] = a0;
++do6:
++ a0 = ((op_t *) srcp)[2];
++ ((op_t *) dstp)[2] = a1;
++do5:
++ a1 = ((op_t *) srcp)[3];
++ ((op_t *) dstp)[3] = a0;
++do4:
++ a0 = ((op_t *) srcp)[4];
++ ((op_t *) dstp)[4] = a1;
++do3:
++ a1 = ((op_t *) srcp)[5];
++ ((op_t *) dstp)[5] = a0;
++do2:
++ a0 = ((op_t *) srcp)[6];
++ ((op_t *) dstp)[6] = a1;
++do1:
++ a1 = ((op_t *) srcp)[7];
++ ((op_t *) dstp)[7] = a0;
++
++ srcp += 8 * OPSIZ;
++ dstp += 8 * OPSIZ;
++ len -= 8;
++ } while (len != 0);
++
++ /* This is the right position for do0. Please don't move
++ * it into the loop.
++ */
++do0:
++ ((op_t *) dstp)[0] = a1;
++}
++
++static void _wordcopy_fwd_dest_aligned(long dstp, long srcp, size_t len)
++{
++ op_t a0, a1, a2, a3;
++ int sh_1, sh_2;
++
++ /* Calculate how to shift a word read at the memory operation
++ * aligned srcp to make it aligned for copy.
++ */
++
++ sh_1 = 8 * (srcp % OPSIZ);
++ sh_2 = 8 * OPSIZ - sh_1;
++
++ /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
++ * it points in the middle of.
++ */
++ srcp &= -OPSIZ;
++
++ switch (len % 4) {
++ case 2:
++ a1 = ((op_t *) srcp)[0];
++ a2 = ((op_t *) srcp)[1];
++ srcp -= 1 * OPSIZ;
++ dstp -= 3 * OPSIZ;
++ len += 2;
++ goto do1;
++ case 3:
++ a0 = ((op_t *) srcp)[0];
++ a1 = ((op_t *) srcp)[1];
++ srcp -= 0 * OPSIZ;
++ dstp -= 2 * OPSIZ;
++ len += 1;
++ goto do2;
++ case 0:
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ return;
++ a3 = ((op_t *) srcp)[0];
++ a0 = ((op_t *) srcp)[1];
++ srcp -= -1 * OPSIZ;
++ dstp -= 1 * OPSIZ;
++ len += 0;
++ goto do3;
++ case 1:
++ a2 = ((op_t *) srcp)[0];
++ a3 = ((op_t *) srcp)[1];
++ srcp -= -2 * OPSIZ;
++ dstp -= 0 * OPSIZ;
++ len -= 1;
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ goto do0;
++ goto do4; /* No-op. */
++ }
++
++ do {
++do4:
++ a0 = ((op_t *) srcp)[0];
++ ((op_t *) dstp)[0] = MERGE(a2, sh_1, a3, sh_2);
++do3:
++ a1 = ((op_t *) srcp)[1];
++ ((op_t *) dstp)[1] = MERGE(a3, sh_1, a0, sh_2);
++do2:
++ a2 = ((op_t *) srcp)[2];
++ ((op_t *) dstp)[2] = MERGE(a0, sh_1, a1, sh_2);
++do1:
++ a3 = ((op_t *) srcp)[3];
++ ((op_t *) dstp)[3] = MERGE(a1, sh_1, a2, sh_2);
++
++ srcp += 4 * OPSIZ;
++ dstp += 4 * OPSIZ;
++ len -= 4;
++ } while (len != 0);
++
++ /* This is the right position for do0. Please don't move
++ * it into the loop.
++ */
++do0:
++ ((op_t *) dstp)[0] = MERGE(a2, sh_1, a3, sh_2);
++}
++
++#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
++do { \
++ size_t __nbytes = (nbytes); \
++ while (__nbytes > 0) { \
++ byte __x = ((byte *) src_bp)[0]; \
++ src_bp += 1; \
++ __nbytes -= 1; \
++ ((byte *) dst_bp)[0] = __x; \
++ dst_bp += 1; \
++ } \
++} while (0)
++
++#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
++do { \
++ if (src_bp % OPSIZ == 0) \
++ _wordcopy_fwd_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
++ else \
++ _wordcopy_fwd_dest_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
++ src_bp += (nbytes) & -OPSIZ; \
++ dst_bp += (nbytes) & -OPSIZ; \
++ (nbytes_left) = (nbytes) % OPSIZ; \
++} while (0)
++
++extern void *__memcpy_aligned(void *dest, const void *src, size_t len);
++void *__memcpy(void *dest, const void *src, size_t len)
++{
++ unsigned long dstp = (long) dest;
++ unsigned long srcp = (long) src;
++
++ /* If there not too few bytes to copy, use word copy. */
++ if (len >= OP_T_THRES) {
++ if ((len >= FAST_COPY_THRES) && ((dstp & OPSIZ_MASK) == 0) &&
++ ((srcp & OPSIZ_MASK) == 0)) {
++ __memcpy_aligned(dest, src, len);
++ return dest;
++ }
++ /* Copy just a few bytes to make DSTP aligned. */
++ len -= (-dstp) % OPSIZ;
++ BYTE_COPY_FWD(dstp, srcp, (-dstp) % OPSIZ);
++
++ /* Copy from SRCP to DSTP taking advantage of the known alignment of
++ * DSTP. Number of bytes remaining is put in the third argument,
++ * i.e. in LEN. This number may vary from machine to machine.
++ */
++ WORD_COPY_FWD(dstp, srcp, len, len);
++ /* Fall out and copy the tail. */
++ }
++
++ /* There are just a few bytes to copy. Use byte memory operations. */
++ BYTE_COPY_FWD(dstp, srcp, len);
++
++ return dest;
++}
++
++void *memcpy(void *dest, const void *src, size_t len) __weak __alias(__memcpy);
diff --git a/target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch b/target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch
new file mode 100644
index 0000000000..0b7418fcf9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch
@@ -0,0 +1,37 @@
+From 41c9e97bb70321f7848bd489e45246a9dc985974 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sun, 4 Feb 2024 15:27:09 +0800
+Subject: [PATCH 093/116] riscv/purgatory: Change memcpy to the aligned version
+
+Change memcpy to the aligned version, for purgatory.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/purgatory/Makefile | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/riscv/purgatory/Makefile
++++ b/arch/riscv/purgatory/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ OBJECT_FILES_NON_STANDARD := y
+
+-purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
++purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy_aligned.o memcpy.o memset.o
+ purgatory-y += strcmp.o strlen.o strncmp.o
+
+ targets += $(purgatory-y)
+@@ -13,9 +13,12 @@ $(obj)/string.o: $(srctree)/lib/string.c
+ $(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
+ $(call if_changed_rule,cc_o_c)
+
+-$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/memcpy.S FORCE
++$(obj)/memcpy_aligned.o: $(srctree)/arch/riscv/lib/memcpy_aligned.S FORCE
+ $(call if_changed_rule,as_o_S)
+
++$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/string.c FORCE
++ $(call if_changed_rule,cc_o_c)
++
+ $(obj)/memset.o: $(srctree)/arch/riscv/lib/memset.S FORCE
+ $(call if_changed_rule,as_o_S)
+
diff --git a/target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch b/target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch
new file mode 100644
index 0000000000..7ce12c6d58
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch
@@ -0,0 +1,856 @@
+From f36d458104101050478e290919ef4f05fbde0b3e Mon Sep 17 00:00:00 2001
+From: "zejian.su" <zejian.su@starfivetech.com>
+Date: Mon, 3 Jul 2023 16:52:13 +0800
+Subject: [PATCH 094/116] Add 16 ISP controls, remove the frame SYNC event to
+ video7 (SC) These controls are: WB, CAR, CCM, CFA, CTC, DBC, DNYUV, GMARGB,
+ LCCF, OBC, OECF, R2Y, SAT, SHRP, YCRV, SC
+
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 628 ++++++++++++++++++
+ .../platform/starfive/v4l2_driver/stf_video.c | 22 +
+ .../platform/starfive/v4l2_driver/stf_vin.c | 16 +-
+ include/uapi/linux/jh7110-isp.h | 48 +-
+ 4 files changed, 706 insertions(+), 8 deletions(-)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -195,6 +195,41 @@ static const char * const test_pattern_m
+ "Color squares w/ rolling bar",
+ };
+
++enum isp_modules_index {
++ imi_obc = 0,
++ imi_oecf,
++ imi_lccf,
++ imi_awb,
++ imi_dbc,
++ imi_ctc,
++ imi_cfa,
++ imi_car,
++ imi_ccm,
++ imi_gmargb,
++ imi_r2y,
++ imi_ycrv,
++ imi_shrp,
++ imi_dnyuv,
++ imi_sat,
++ imi_sc
++};
++
++#define MODULE_ENABLE_REGISTER0 0x10
++#define MODULE_ENABLE_REGISTER1 0xa08
++
++struct module_register_info {
++ __u32 en_reg;
++ __u32 en_nbit;
++ __u32 cfg_reg;
++};
++
++static const struct module_register_info mod_reg_info[] = {
++ {MODULE_ENABLE_REGISTER0, 2, 0x034}, {MODULE_ENABLE_REGISTER0, 4, 0x100}, {MODULE_ENABLE_REGISTER0, 6, 0x050}, {MODULE_ENABLE_REGISTER0, 7, 0x280},
++ {MODULE_ENABLE_REGISTER1, 22, 0xa14}, {MODULE_ENABLE_REGISTER1, 21, 0xa10}, {MODULE_ENABLE_REGISTER1, 1, 0xa1c}, {MODULE_ENABLE_REGISTER1, 2, 0x000},
++ {MODULE_ENABLE_REGISTER1, 3, 0xc40}, {MODULE_ENABLE_REGISTER1, 4, 0xe00}, {MODULE_ENABLE_REGISTER1, 5, 0xe40}, {MODULE_ENABLE_REGISTER1, 19, 0xf00},
++ {MODULE_ENABLE_REGISTER1, 7, 0xe80}, {MODULE_ENABLE_REGISTER1, 17, 0xc00}, {MODULE_ENABLE_REGISTER1, 8, 0xa30}, {MODULE_ENABLE_REGISTER0, 17, 0x09c}
++};
++
+ #define ISP_TEST_ENABLE BIT(7)
+ #define ISP_TEST_ROLLING BIT(6) /* rolling horizontal bar */
+ #define ISP_TEST_TRANSPARENT BIT(5)
+@@ -260,6 +295,401 @@ static int isp_g_volatile_ctrl(struct v4
+ return 0;
+ }
+
++#define CREATE_REG_VALUE_FUNCTION(type) \
++ static u32 create_reg_value_##type(const type * value, s32 size, u32 mask, s32 nbits) { \
++ s32 npos = 0; \
++ u32 res = 0; \
++ s32 sz = size; \
++ s32 i = 0; \
++ if(size * nbits > 32) sz = 32 / nbits; \
++ for(i = 0; i < sz; i++, npos += nbits, value++) res |= (u32)(value[0] & mask) << npos; \
++ return res; \
++}
++
++CREATE_REG_VALUE_FUNCTION(u8);
++CREATE_REG_VALUE_FUNCTION(u16);
++#define CREATE_REG_VALUE(type, value, size, mask, nbits) create_reg_value_##type(value, size, mask, nbits)
++
++#define FILL_ISP_REGS_FUNC(type) \
++static void fill_isp_regs_##type(void __iomem *ispbase, u32 offset, const type * value, s32 size, u32 mask, u32 nbits) { \
++ s32 i; \
++ for(i = 0; i < size; i++, value++) \
++ reg_write(ispbase, offset + i * 4, (u32)(value[0] & mask) << nbits); \
++}
++FILL_ISP_REGS_FUNC(u32);
++FILL_ISP_REGS_FUNC(u8);
++FILL_ISP_REGS_FUNC(u16);
++
++#define FILL_ISP_REGS(type, ispbase, offset, value, size, mask, nbits) \
++ fill_isp_regs_##type(ispbase, offset, value, size, mask, nbits)
++
++static int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_awb];
++ const struct jh7110_isp_wb_setting * setting = (const struct jh7110_isp_wb_setting *)value;
++ const struct jh7110_isp_wb_gain * gains = &setting->gains;
++ u32 r_g = (((u32)gains->gain_r << 16) | gains->gain_r) & 0x03ff03ff;
++ u32 g_g = (((u32)gains->gain_g << 16) | gains->gain_g) & 0x03ff03ff;
++ u32 b_g = (((u32)gains->gain_b << 16) | gains->gain_b) & 0x03ff03ff;
++ u32 reg_addr = reg_info->cfg_reg + 16 * sizeof(u32);
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, r_g);
++ reg_write(ispbase, reg_addr + 1 * 4, r_g);
++ reg_write(ispbase, reg_addr + 2 * 4, g_g);
++ reg_write(ispbase, reg_addr + 3 * 4, g_g);
++ reg_write(ispbase, reg_addr + 4 * 4, g_g);
++ reg_write(ispbase, reg_addr + 5 * 4, g_g);
++ reg_write(ispbase, reg_addr + 6 * 4, b_g);
++ reg_write(ispbase, reg_addr + 7 * 4, b_g);
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_car(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_car];
++ const struct jh7110_isp_car_setting * setting = (const struct jh7110_isp_car_setting *)value;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_ccm(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_ccm];
++ const struct jh7110_isp_ccm_setting * setting = (const struct jh7110_isp_ccm_setting *)value;
++ const struct jh7110_isp_ccm_smlow * ccm = (const struct jh7110_isp_ccm_smlow *)(&(setting->ccm_smlow));
++ u32 reg_addr = reg_info->cfg_reg + 12 * sizeof(u32);
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_info->cfg_reg, 6 << 16);
++ FILL_ISP_REGS(u32, ispbase, reg_addr, (u32 *)ccm, 12, 0x7ff, 0);
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_cfa(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_cfa];
++ const struct jh7110_isp_cfa_setting * setting = (const struct jh7110_isp_cfa_setting *)value;
++ const struct jh7110_isp_cfa_params * cfg = (const struct jh7110_isp_cfa_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, ((u32)(cfg->cross_cov & 0x3) << 4) | (cfg->hv_width & 0xf));
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_ctc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_ctc];
++ const struct jh7110_isp_ctc_setting * setting = (const struct jh7110_isp_ctc_setting *)value;
++ const struct jh7110_isp_ctc_params * cfg = (const struct jh7110_isp_ctc_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 reg_value = (u32)(((cfg->saf_mode & 1) << 1) | (cfg->daf_mode & 1)) << 30;
++
++ reg_value |= ((u32)(cfg->max_gt & 0x3ff) << 16) | (cfg->min_gt & 0x3ff);
++ reg_write(ispbase, reg_addr, reg_value);
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_dbc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_dbc];
++ const struct jh7110_isp_dbc_setting * setting = (const struct jh7110_isp_dbc_setting *)value;
++ const struct jh7110_isp_dbc_params * cfg = (const struct jh7110_isp_dbc_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, ((u32)(cfg->bad_gt & 0x3ff) << 16) | (cfg->bad_xt & 0x3ff));
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_dnyuv(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_dnyuv];
++ const struct jh7110_isp_dnyuv_setting * setting = (const struct jh7110_isp_dnyuv_setting *)value;
++ const struct jh7110_isp_dnyuv_params * cfg = (const struct jh7110_isp_dnyuv_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, cfg->y_sweight, 6, 0x7, 4));
++ reg_write(ispbase, reg_addr + 4, CREATE_REG_VALUE(u8, &cfg->y_sweight[6], 4, 0x7, 4));
++ reg_write(ispbase, reg_addr + 8, CREATE_REG_VALUE(u8, cfg->uv_sweight, 6, 0x7, 4));
++ reg_write(ispbase, reg_addr + 12, CREATE_REG_VALUE(u8, &cfg->uv_sweight[6], 4, 0x7, 4));
++ reg_write(ispbase, reg_addr + 16, CREATE_REG_VALUE(u16, &cfg->y_curve[0], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 20, CREATE_REG_VALUE(u16, &cfg->y_curve[2], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 24, CREATE_REG_VALUE(u16, &cfg->y_curve[4], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 28, CREATE_REG_VALUE(u16, &cfg->uv_curve[0], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 32, CREATE_REG_VALUE(u16, &cfg->uv_curve[2], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 36, CREATE_REG_VALUE(u16, &cfg->uv_curve[4], 2, 0x3ff, 16));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_gmargb(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_gmargb];
++ const struct jh7110_isp_gmargb_setting * setting = (const struct jh7110_isp_gmargb_setting *)value;
++ const struct jh7110_isp_gmargb_point * curve = setting->curve;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 15; i++, curve++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, ((u32)curve->sg_val << 16) | (curve->g_val & 0x3ff));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_lccf(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_lccf];
++ const struct jh7110_isp_lccf_setting * setting = (const struct jh7110_isp_lccf_setting *)value;
++ const s16 * params = (s16 *)(&setting->r_param);
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ reg_write(ispbase, reg_addr, ((u32)(setting->circle.center_y & 0x7fff) << 16) | (setting->circle.center_x & 0x7fff));
++ reg_write(ispbase, reg_addr + 8, setting->circle.radius & 0xf);
++ reg_addr += 0x90;
++ for(i = 0; i < 4; i++, reg_addr += 4, params += 2)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x1fff, 16));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_obc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_obc];
++ const struct jh7110_isp_blacklevel_setting * setting = (const struct jh7110_isp_blacklevel_setting *)value;
++ const u8 * params = (u8 *)setting->gain;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ reg_write(ispbase, reg_addr, ((u32)(setting->win_size.height & 0xf) << 4) | (setting->win_size.width & 0xf));
++
++ reg_addr += 0x2ac; //0x2e0
++ for(i = 0; i < 8; i++, reg_addr += 4, params += 4)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 4, 0xff, 8));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_oecf(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_oecf];
++ const struct jh7110_isp_oecf_setting * setting = (const struct jh7110_isp_oecf_setting *)value;
++ const struct jh7110_isp_oecf_point * pts = (struct jh7110_isp_oecf_point *)(setting->r_curve);
++ u32 reg_x_addr = reg_info->cfg_reg;
++ u32 reg_y_addr = reg_info->cfg_reg + 0x080;
++ u32 reg_s_addr = reg_info->cfg_reg + 0x100;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 x, y, slope;
++ s32 i;
++
++ for(i = 0; i < 32; i++, reg_x_addr += 4, reg_y_addr += 4, reg_s_addr += 4) {
++ x = pts->x & 0x3ff;
++ y = pts->y & 0x3ff;
++ slope = pts->slope & 0x3ff;
++ pts++;
++ x |= ((pts->x & 0x3ff) << 16);
++ y |= ((pts->y & 0x3ff) << 16);
++ slope |= ((pts->slope & 0x3ff) << 16);
++ pts++;
++
++ reg_write(ispbase, reg_x_addr, x);
++ reg_write(ispbase, reg_y_addr, y);
++ reg_write(ispbase, reg_s_addr, slope);
++ }
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_r2y(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_r2y];
++ const struct jh7110_isp_r2y_setting * setting = (const struct jh7110_isp_r2y_setting *)value;
++ const s16 * params = setting->matrix.m;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 9; i++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, (u32)(params[i] & 0x1ff));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++
++static int isp_set_ctrl_sat(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_sat];
++ const struct jh7110_isp_sat_setting * setting = (const struct jh7110_isp_sat_setting *)value;
++ const u16 * params = (u16 *)(&setting->sat_info);
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 3; i++, reg_addr += 4, params += 2)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0xfff, 16));
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, &setting->hue_info.cos, 2, 0x3ff, 16));
++ reg_addr += 4;
++ reg_write(ispbase, reg_addr, setting->sat_info.cmsf & 0xf);
++
++ params = (u16 *)(&setting->curve);
++ reg_addr += 0x14; // 0xa54
++ for(i = 0; i < 2; i++, reg_addr += 4, params += 2)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x3fff, 16));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_shrp(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_shrp];
++ const struct jh7110_isp_sharp_setting * setting = (const struct jh7110_isp_sharp_setting *)value;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 4; i++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, ((u32)(setting->strength.diff[i] & 0x3ff) << 16) | ((u32)(setting->weight.weight[i] & 0xf) << 8));
++ FILL_ISP_REGS(u8, ispbase, reg_addr, (u8 *)(&setting->weight.weight[4]), 15 - 4, 0xf, 8);
++ reg_addr += (15 - 4) * 4;
++
++ for(i = 0; i < 3; i++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, ((u32)(setting->strength.f[i] & 0x7f) << 24) | (setting->strength.s[i] & 0x1fffff));
++
++ reg_addr += 3 * 4;
++ reg_write(ispbase, reg_addr, ((u32)(setting->pdirf & 0xf) << 28) | ((u32)(setting->ndirf & 0xf) << 24) | (setting->weight.recip_wei_sum & 0x3fffff));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_ycrv(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_ycrv];
++ const struct jh7110_isp_ycrv_setting * setting = (const struct jh7110_isp_ycrv_setting *)value;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ FILL_ISP_REGS(u16, ispbase, reg_addr, (u16 *)(setting->curve.y), 64, 0x3ff, 0);
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_sc];
++ const struct jh7110_isp_sc_setting * setting = (const struct jh7110_isp_sc_setting *)value;
++ const u8 * params = setting->awb_config.awb_cw;
++ u32 reg_addr = 0x00;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 weight_cfg[6] = {0};
++ u32 * weight = weight_cfg;
++ u32 * w_diff = weight_cfg + 2;
++ s32 i;
++
++ // AF register
++ reg_write(ispbase, 0xc0,
++ ((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
++ ((u32)(setting->af_config.es_ver_thr & 0xff) << 8) |
++ ((setting->af_config.ver_en & 0x1) << 3) |
++ ((setting->af_config.hor_en & 0x1) << 2) |
++ ((setting->af_config.es_sum_mode & 0x1) << 1) |
++ (setting->af_config.es_hor_mode & 0x1));
++
++ // AWB weight sum register
++ reg_write(ispbase, 0x5d0, CREATE_REG_VALUE(u8, &setting->awb_config.ws_config.awb_ws_rl, 4, 0xff, 8));
++ reg_write(ispbase, 0x5d4, CREATE_REG_VALUE(u8, &setting->awb_config.ws_config.awb_ws_gbl, 4, 0xff, 8));
++
++ // AWB weight value point
++ reg_addr = 0x4d0;
++ for(i = 0; i < 13; i++) {
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 8, 0xf, 4));
++ reg_addr += 4;
++ params += 8;
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 5, 0xf, 4));
++ reg_addr += 4;
++ params += 5;
++ }
++
++ // AWB intensity weight curve register
++ reg_addr = 0x538;
++ for(i = 0; i < 4; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++ for(w_diff++; i < 8; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++ for(weight++, w_diff++; i < 12; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++ for(w_diff++; i < 16; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++
++ FILL_ISP_REGS(u32, ispbase, reg_addr, weight_cfg, 6, 0xffffffff, 0);
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
+ static int isp_s_ctrl(struct v4l2_ctrl *ctrl)
+ {
+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+@@ -310,10 +740,52 @@ static int isp_s_ctrl(struct v4l2_ctrl *
+ ret = isp_set_ctrl_vflip(isp_dev, ctrl->val);
+ break;
+ case V4L2_CID_USER_JH7110_ISP_WB_SETTING:
++ ret = isp_set_ctrl_wb(isp_dev, ctrl->p_new.p_u8);
+ break;
+ case V4L2_CID_USER_JH7110_ISP_CAR_SETTING:
++ ret = isp_set_ctrl_car(isp_dev, ctrl->p_new.p_u8);
+ break;
+ case V4L2_CID_USER_JH7110_ISP_CCM_SETTING:
++ ret = isp_set_ctrl_ccm(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CFA_SETTING:
++ ret = isp_set_ctrl_cfa(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CTC_SETTING:
++ ret = isp_set_ctrl_ctc(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_DBC_SETTING:
++ ret = isp_set_ctrl_dbc(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING:
++ ret = isp_set_ctrl_dnyuv(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING:
++ ret = isp_set_ctrl_gmargb(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_LCCF_SETTING:
++ ret = isp_set_ctrl_lccf(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_OBC_SETTING:
++ ret = isp_set_ctrl_obc(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_OECF_SETTING:
++ ret = isp_set_ctrl_oecf(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_R2Y_SETTING:
++ ret = isp_set_ctrl_r2y(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_SAT_SETTING:
++ ret = isp_set_ctrl_sat(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_SHRP_SETTING:
++ ret = isp_set_ctrl_shrp(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_YCRV_SETTING:
++ ret = isp_set_ctrl_ycrv(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_STAT_SETTING:
++ ret = isp_set_ctrl_sc(isp_dev, ctrl->p_new.p_u8);
+ break;
+ default:
+ ret = -EINVAL;
+@@ -365,6 +837,162 @@ struct v4l2_ctrl_config isp_ctrl[] = {
+ .dims[0] = sizeof(struct jh7110_isp_ccm_setting),
+ .flags = 0,
+ },
++ [3] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CFA Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CFA_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_cfa_setting),
++ .flags = 0,
++ },
++ [4] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CTC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CTC_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_ctc_setting),
++ .flags = 0,
++ },
++ [5] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CTC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_DBC_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_dbc_setting),
++ .flags = 0,
++ },
++ [6] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "DNYUV Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_dnyuv_setting),
++ .flags = 0,
++ },
++ [7] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "DNYUV Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_gmargb_setting),
++ .flags = 0,
++ },
++ [8] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "LCCF Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_LCCF_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_lccf_setting),
++ .flags = 0,
++ },
++ [9] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OBC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OBC_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_blacklevel_setting),
++ .flags = 0,
++ },
++ [10] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OECF Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OECF_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_oecf_setting),
++ .flags = 0,
++ },
++ [11] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "R2Y Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_R2Y_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_r2y_setting),
++ .flags = 0,
++ },
++ [12] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "SAT Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_SAT_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_sat_setting),
++ .flags = 0,
++ },
++ [13] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "SAT Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_SHRP_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_sharp_setting),
++ .flags = 0,
++ },
++ [14] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "YCRV Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_YCRV_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_ycrv_setting),
++ .flags = 0,
++ },
++ [15] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "SC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_STAT_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_sc_setting),
++ .flags = 0,
++ },
+ };
+
+ static int isp_init_controls(struct stf_isp_dev *isp_dev)
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+@@ -1281,6 +1281,22 @@ int video_s_selection(struct file *file,
+ return ret;
+ }
+
++static int stf_video_subscribe_event(struct v4l2_fh *fh,
++ const struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_FRAME_SYNC:
++ return v4l2_event_subscribe(fh, sub, 2, NULL);
++ //int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
++ //pr_info("subscribe ret: %d\n", ret);
++ //return ret;
++ default:
++ return v4l2_ctrl_subscribe_event(fh, sub);
++ //st_debug(ST_VIN, "unsupport subscribe_event\n");
++ //return -EINVAL;
++ }
++}
++
+ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = {
+ .vidioc_querycap = video_querycap,
+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
+@@ -1305,6 +1321,8 @@ static const struct v4l2_ioctl_ops stf_v
+ .vidioc_s_parm = video_s_parm,
+ .vidioc_s_selection = video_s_selection,
+ .vidioc_g_selection = video_g_selection,
++ .vidioc_subscribe_event = stf_video_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ };
+
+ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_mp = {
+@@ -1331,6 +1349,8 @@ static const struct v4l2_ioctl_ops stf_v
+ .vidioc_s_parm = video_s_parm,
+ .vidioc_s_selection = video_s_selection,
+ .vidioc_g_selection = video_g_selection,
++ .vidioc_subscribe_event = stf_video_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ };
+
+ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_out = {
+@@ -1350,6 +1370,8 @@ static const struct v4l2_ioctl_ops stf_v
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
++ .vidioc_subscribe_event = stf_video_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ };
+
+ static int video_open(struct file *file)
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+@@ -1145,9 +1145,12 @@ static void vin_buffer_done(struct vin_l
+ spin_lock_irqsave(&line->output_lock, flags);
+
+ while ((ready_buf = vin_buf_get_ready(output))) {
+- if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
++ //if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
++ if (line->id == VIN_LINE_ISP_SCD_Y) {
+ event.u.frame_sync.frame_sequence = output->sequence;
+- v4l2_event_queue(line->subdev.devnode, &event);
++ v4l2_event_queue(&(line->video_out.vdev), &event);
++ //v4l2_event_queue(line->subdev.devnode, &event);
++ //pr_info("----------frame sync-----------\n");
+ }
+
+ ready_buf->vb.vb2_buf.timestamp = ts;
+@@ -1346,7 +1349,10 @@ static int stf_vin_subscribe_event(struc
+ {
+ switch (sub->type) {
+ case V4L2_EVENT_FRAME_SYNC:
+- return v4l2_event_subscribe(fh, sub, 0, NULL);
++ //return v4l2_event_subscribe(fh, sub, 2, NULL);
++ int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
++ pr_info("subscribe ret: %d\n", ret);
++ return ret;
+ default:
+ st_debug(ST_VIN, "unsupport subscribe_event\n");
+ return -EINVAL;
+@@ -1355,8 +1361,8 @@ static int stf_vin_subscribe_event(struc
+
+ static const struct v4l2_subdev_core_ops vin_core_ops = {
+ .s_power = vin_set_power,
+- .subscribe_event = stf_vin_subscribe_event,
+- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++ //.subscribe_event = stf_vin_subscribe_event,
++ //.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+ };
+
+ static const struct v4l2_subdev_video_ops vin_video_ops = {
+--- a/include/uapi/linux/jh7110-isp.h
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -15,6 +15,8 @@
+
+ #include <linux/v4l2-controls.h>
+
++#define V4L2_CID_USER_JH7110_ISP_BASE (V4L2_CID_USER_BASE + 0x1170)
++
+ #define V4L2_CID_USER_JH7110_ISP_WB_SETTING \
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0001)
+ #define V4L2_CID_USER_JH7110_ISP_CAR_SETTING \
+@@ -45,6 +47,8 @@
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000e)
+ #define V4L2_CID_USER_JH7110_ISP_YCRV_SETTING \
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000f)
++#define V4L2_CID_USER_JH7110_ISP_STAT_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0010)
+
+ struct jh7110_isp_wb_gain {
+ __u16 gain_r;
+@@ -202,13 +206,13 @@ struct jh7110_isp_sat_curve {
+ };
+
+ struct jh7110_isp_sat_hue_info {
+- __s16 sin;
+ __s16 cos;
++ __s16 sin;
+ };
+
+ struct jh7110_isp_sat_info {
+ __s16 gain_cmab;
+- __s16 gain_cmad;
++ __s16 gain_cmmd;
+ __s16 threshold_cmb;
+ __s16 threshold_cmd;
+ __s16 offset_u;
+@@ -230,7 +234,8 @@ struct jh7110_isp_sharp_weight {
+
+ struct jh7110_isp_sharp_strength {
+ __s16 diff[4];
+- __s16 f[4];
++ __s16 f[3];
++ __s32 s[3];
+ };
+
+ struct jh7110_isp_sharp_setting {
+@@ -250,4 +255,41 @@ struct jh7110_isp_ycrv_setting {
+ struct jh7110_isp_ycrv_curve curve;
+ };
+
++struct jh7110_isp_sc_af_config {
++ __u8 es_hor_mode;
++ __u8 es_sum_mode;
++ __u8 hor_en;
++ __u8 ver_en;
++ __u8 es_ver_thr;
++ __u16 es_hor_thr;
++};
++
++struct jh7110_isp_sc_awb_ws {
++ __u8 awb_ws_rl;
++ __u8 awb_ws_ru;
++ __u8 awb_ws_grl;
++ __u8 awb_ws_gru;
++ __u8 awb_ws_gbl;
++ __u8 awb_ws_gbu;
++ __u8 awb_ws_bl;
++ __u8 awb_ws_bu;
++};
++
++struct jh7110_isp_sc_awb_point {
++ __u16 intensity;
++ __u8 weight;
++};
++
++struct jh7110_isp_sc_awb_config {
++ struct jh7110_isp_sc_awb_ws ws_config;
++ __u8 awb_cw[169];
++ struct jh7110_isp_sc_awb_point pts[17];
++};
++
++struct jh7110_isp_sc_setting {
++ __u32 enabled;
++ struct jh7110_isp_sc_af_config af_config;
++ struct jh7110_isp_sc_awb_config awb_config;
++};
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch b/target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch
new file mode 100644
index 0000000000..d023674f79
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch
@@ -0,0 +1,249 @@
+From 5d61c6fd10144605238311d68c99449c4667a345 Mon Sep 17 00:00:00 2001
+From: "zejian.su" <zejian.su@starfivetech.com>
+Date: Mon, 7 Aug 2023 10:38:36 +0800
+Subject: [PATCH 095/116] Expand 2 bytes after the SC buffer for the AE/AWB
+ flag and copy the histogram data to the SC buffer.
+
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 37 ++++++++++++++++++-
+ .../platform/starfive/v4l2_driver/stf_isp.h | 2 +-
+ .../platform/starfive/v4l2_driver/stf_video.c | 5 ---
+ .../platform/starfive/v4l2_driver/stf_vin.c | 36 +++++++++---------
+ include/uapi/linux/jh7110-isp.h | 33 +++++++++++++++++
+ 5 files changed, 87 insertions(+), 26 deletions(-)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -323,6 +323,13 @@ FILL_ISP_REGS_FUNC(u16);
+ #define FILL_ISP_REGS(type, ispbase, offset, value, size, mask, nbits) \
+ fill_isp_regs_##type(ispbase, offset, value, size, mask, nbits)
+
++static void fill_regs_with_zero(void __iomem *ispbase, u32 offset, u32 size)
++{
++ u32 i;
++ for(i = 0; i < size; i++, offset += 4)
++ reg_write(ispbase, offset, 0);
++}
++
+ static int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void * value)
+ {
+ const struct module_register_info * reg_info = &mod_reg_info[imi_awb];
+@@ -335,6 +342,8 @@ static int isp_set_ctrl_wb(struct stf_is
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+
++ fill_regs_with_zero(ispbase, reg_info->cfg_reg, 16);
++
+ reg_write(ispbase, reg_addr, r_g);
+ reg_write(ispbase, reg_addr + 1 * 4, r_g);
+ reg_write(ispbase, reg_addr + 2 * 4, g_g);
+@@ -370,8 +379,13 @@ static int isp_set_ctrl_ccm(struct stf_i
+ void __iomem *ispbase = vin->isp_base;
+
+ reg_write(ispbase, reg_info->cfg_reg, 6 << 16);
++ fill_regs_with_zero(ispbase, reg_info->cfg_reg + 4, 11);
++
+ FILL_ISP_REGS(u32, ispbase, reg_addr, (u32 *)ccm, 12, 0x7ff, 0);
+
++ reg_addr += 12 * 4;
++ fill_regs_with_zero(ispbase, reg_addr, 2);
++
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+
+ return 0;
+@@ -640,6 +654,27 @@ static int isp_set_ctrl_sc(struct stf_is
+ u32 * w_diff = weight_cfg + 2;
+ s32 i;
+
++ // SC dumping axi id
++ reg_write(ispbase, 0x9c, 1 << 24);
++
++ // SC frame crop
++ reg_write(ispbase, 0xb8, ((u32)(setting->crop_config.v_start) << 16) | setting->crop_config.h_start);
++
++ // SC config1
++ reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
++ ((u32)(setting->crop_config.sw_height) << 8) | setting->crop_config.sw_width);
++
++ // SC decimation config
++ reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
++ ((u32)(setting->crop_config.hkeep) << 8) | setting->crop_config.hperiod);
++
++ // SC AWB pixel sum config
++ reg_write(ispbase, 0xc4, CREATE_REG_VALUE(u8, &setting->awb_config.ws_ps_config.awb_ps_rl, 4, 0xff, 8));
++ reg_write(ispbase, 0xc8, CREATE_REG_VALUE(u8, &setting->awb_config.ws_ps_config.awb_ps_bl, 4, 0xff, 8));
++ reg_write(ispbase, 0xcc, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grl, 2, 0xffff, 16));
++ reg_write(ispbase, 0xd0, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_gbl, 2, 0xffff, 16));
++ reg_write(ispbase, 0xd4, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grbl, 2, 0xffff, 16));
++
+ // AF register
+ reg_write(ispbase, 0xc0,
+ ((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
+@@ -686,7 +721,7 @@ static int isp_set_ctrl_sc(struct stf_is
+ FILL_ISP_REGS(u32, ispbase, reg_addr, weight_cfg, 6, 0xffffffff, 0);
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
+@@ -18,7 +18,7 @@
+
+ #define ISP_SCD_BUFFER_SIZE (19 * 256 * 4) // align 128
+ #define ISP_YHIST_BUFFER_SIZE (64 * 4)
+-#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)
++#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE + 2)
+ #define ISP_RAW_DATA_BITS 12
+ #define SCALER_RATIO_MAX 1 // no compose function
+ #define STF_ISP_REG_OFFSET_MAX 0x0FFF
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+@@ -1287,13 +1287,8 @@ static int stf_video_subscribe_event(str
+ switch (sub->type) {
+ case V4L2_EVENT_FRAME_SYNC:
+ return v4l2_event_subscribe(fh, sub, 2, NULL);
+- //int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
+- //pr_info("subscribe ret: %d\n", ret);
+- //return ret;
+ default:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+- //st_debug(ST_VIN, "unsupport subscribe_event\n");
+- //return -EINVAL;
+ }
+ }
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+@@ -1147,6 +1147,17 @@ static void vin_buffer_done(struct vin_l
+ while ((ready_buf = vin_buf_get_ready(output))) {
+ //if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
+ if (line->id == VIN_LINE_ISP_SCD_Y) {
++#define ADDR_REG_YHIST_ACC_0 0x0D00
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 y_hist_reg_addr = ADDR_REG_YHIST_ACC_0;
++ u32 * y_hist_addr = (u32 *)ready_buf->vaddr_sc;
++ s32 i = 0;
++
++ for(i = 0; i < 64; i++, y_hist_reg_addr += 4)
++ y_hist_addr[i] = reg_read(ispbase, y_hist_reg_addr);
++
+ event.u.frame_sync.frame_sequence = output->sequence;
+ v4l2_event_queue(&(line->video_out.vdev), &event);
+ //v4l2_event_queue(line->subdev.devnode, &event);
+@@ -1246,9 +1257,14 @@ static void vin_change_buffer(struct vin
+ scd_type = vin_dev->hw_ops->vin_isp_get_scd_type(vin_dev);
+ ready_buf->vb.flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME);
+ if (scd_type == AWB_TYPE)
++ {
+ ready_buf->vb.flags |= V4L2_BUF_FLAG_PFRAME;
+- else
++ *((u16 *)(ready_buf->vaddr_sc + ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)) = 0xffff;
++ }else{
+ ready_buf->vb.flags |= V4L2_BUF_FLAG_BFRAME;
++ *((u16 *)(ready_buf->vaddr_sc + ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)) = 0;
++ }
++
+ if (!output->frame_skip) {
+ output->frame_skip = ISP_AWB_OECF_SKIP_FRAME;
+ scd_type = scd_type == AWB_TYPE ? OECF_TYPE : AWB_TYPE;
+@@ -1343,26 +1359,8 @@ static int vin_link_setup(struct media_e
+ return 0;
+ }
+
+-static int stf_vin_subscribe_event(struct v4l2_subdev *sd,
+- struct v4l2_fh *fh,
+- struct v4l2_event_subscription *sub)
+-{
+- switch (sub->type) {
+- case V4L2_EVENT_FRAME_SYNC:
+- //return v4l2_event_subscribe(fh, sub, 2, NULL);
+- int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
+- pr_info("subscribe ret: %d\n", ret);
+- return ret;
+- default:
+- st_debug(ST_VIN, "unsupport subscribe_event\n");
+- return -EINVAL;
+- }
+-}
+-
+ static const struct v4l2_subdev_core_ops vin_core_ops = {
+ .s_power = vin_set_power,
+- //.subscribe_event = stf_vin_subscribe_event,
+- //.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+ };
+
+ static const struct v4l2_subdev_video_ops vin_video_ops = {
+--- a/include/uapi/linux/jh7110-isp.h
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -255,6 +255,17 @@ struct jh7110_isp_ycrv_setting {
+ struct jh7110_isp_ycrv_curve curve;
+ };
+
++struct jh7110_isp_sc_config {
++ __u16 h_start;
++ __u16 v_start;
++ __u8 sw_width;
++ __u8 sw_height;
++ __u8 hperiod;
++ __u8 hkeep;
++ __u8 vperiod;
++ __u8 vkeep;
++};
++
+ struct jh7110_isp_sc_af_config {
+ __u8 es_hor_mode;
+ __u8 es_sum_mode;
+@@ -264,6 +275,23 @@ struct jh7110_isp_sc_af_config {
+ __u16 es_hor_thr;
+ };
+
++struct jh7110_isp_sc_awb_ps {
++ __u8 awb_ps_rl;
++ __u8 awb_ps_ru;
++ __u8 awb_ps_gl;
++ __u8 awb_ps_gu;
++ __u8 awb_ps_bl;
++ __u8 awb_ps_bu;
++ __u8 awb_ps_yl;
++ __u8 awb_ps_yu;
++ __u16 awb_ps_grl;
++ __u16 awb_ps_gru;
++ __u16 awb_ps_gbl;
++ __u16 awb_ps_gbu;
++ __u16 awb_ps_grbl;
++ __u16 awb_ps_grbu;
++};
++
+ struct jh7110_isp_sc_awb_ws {
+ __u8 awb_ws_rl;
+ __u8 awb_ws_ru;
+@@ -275,12 +303,16 @@ struct jh7110_isp_sc_awb_ws {
+ __u8 awb_ws_bu;
+ };
+
++
+ struct jh7110_isp_sc_awb_point {
+ __u16 intensity;
+ __u8 weight;
+ };
+
+ struct jh7110_isp_sc_awb_config {
++ struct jh7110_isp_sc_awb_ps ws_ps_config;
++ __u8 awb_ps_grb_ba;
++ __u8 sel;
+ struct jh7110_isp_sc_awb_ws ws_config;
+ __u8 awb_cw[169];
+ struct jh7110_isp_sc_awb_point pts[17];
+@@ -288,6 +320,7 @@ struct jh7110_isp_sc_awb_config {
+
+ struct jh7110_isp_sc_setting {
+ __u32 enabled;
++ struct jh7110_isp_sc_config crop_config;
+ struct jh7110_isp_sc_af_config af_config;
+ struct jh7110_isp_sc_awb_config awb_config;
+ };
diff --git a/target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch b/target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch
new file mode 100644
index 0000000000..5737fb255e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch
@@ -0,0 +1,117 @@
+From 04eff0f76091015cbecd39de41d45c493e7a91db Mon Sep 17 00:00:00 2001
+From: "zejian.su" <zejian.su@starfivetech.com>
+Date: Mon, 30 Oct 2023 16:09:58 +0800
+Subject: [PATCH 096/116] Add ISP control for video2 and video3.
+
+Signed-off-by: zejian.su <zejian.su@starfivetech.com>
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 46 +++++++++++++++++++
+ include/uapi/linux/jh7110-isp.h | 23 ++++++++++
+ 2 files changed, 69 insertions(+)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -725,6 +725,24 @@ static int isp_set_ctrl_sc(struct stf_is
+ return 0;
+ }
+
++static int isp_set_ctrl_outss(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct jh7110_isp_outss_setting * setting = (const struct jh7110_isp_outss_setting *)value;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 reg_addr = !setting->which ? 0xa9c : 0xab4;
++
++ if(!setting->stride)
++ return 0;
++
++ // Output Image Stride Register, 8-byte(64bit) granularity.
++ reg_write(ispbase, reg_addr, setting->stride);
++ reg_write(ispbase, reg_addr + 4, ((setting->hsm << 16) | (setting->hsm & 0x3)));
++ reg_write(ispbase, reg_addr + 8, ((setting->vsm << 16) | (setting->vsm & 0x3)));
++
++ return 0;
++}
++
+ static int isp_s_ctrl(struct v4l2_ctrl *ctrl)
+ {
+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+@@ -822,6 +840,10 @@ static int isp_s_ctrl(struct v4l2_ctrl *
+ case V4L2_CID_USER_JH7110_ISP_STAT_SETTING:
+ ret = isp_set_ctrl_sc(isp_dev, ctrl->p_new.p_u8);
+ break;
++ case V4L2_CID_USER_JH7110_ISP_OUTSS0_SETTING:
++ case V4L2_CID_USER_JH7110_ISP_OUTSS1_SETTING:
++ ret = isp_set_ctrl_outss(isp_dev, ctrl->p_new.p_u8);
++ break;
+ default:
+ ret = -EINVAL;
+ break;
+@@ -1028,6 +1050,30 @@ struct v4l2_ctrl_config isp_ctrl[] = {
+ .dims[0] = sizeof(struct jh7110_isp_sc_setting),
+ .flags = 0,
+ },
++ [16] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OUTSS Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OUTSS0_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_outss_setting),
++ .flags = 0,
++ },
++ [17] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OUTSS Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OUTSS1_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_outss_setting),
++ .flags = 0,
++ },
+ };
+
+ static int isp_init_controls(struct stf_isp_dev *isp_dev)
+--- a/include/uapi/linux/jh7110-isp.h
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -49,6 +49,10 @@
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000f)
+ #define V4L2_CID_USER_JH7110_ISP_STAT_SETTING \
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0010)
++#define V4L2_CID_USER_JH7110_ISP_OUTSS0_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0011)
++#define V4L2_CID_USER_JH7110_ISP_OUTSS1_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0012)
+
+ struct jh7110_isp_wb_gain {
+ __u16 gain_r;
+@@ -325,4 +329,23 @@ struct jh7110_isp_sc_setting {
+ struct jh7110_isp_sc_awb_config awb_config;
+ };
+
++struct jh7110_isp_outss_setting {
++ __u8 which;
++ __u16 stride; // Output Image Stride Register, 8-byte(64bit) granularity.
++ __u8 hsm; // horizontal scale mode
++ __u32 hsf; // horizontal scale factor (time 4096)
++ __u8 vsm; // vertical scale mode
++ __u32 vsf; // vertical scale factor (time 4096)
++};
++
++struct jh7110_isp_sc_buffer {
++ __u32 y_histogram[64];
++ __u32 reserv0[33];
++ __u32 bright_sc[4096];
++ __u32 reserv1[96];
++ __u32 ae_hist_y[128];
++ __u32 reserv2[511];
++ __u16 flag;
++};
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch b/target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch
new file mode 100644
index 0000000000..b1d857e3cf
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch
@@ -0,0 +1,226 @@
+From 883745d4728e524babfe7d04cbb8a925c22aa6b5 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 13 Nov 2023 14:46:50 +0800
+Subject: [PATCH 097/116] media: starfive: Update ISP initialzation
+
+ISP compatible stf_isp_ctrl and libcamera.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 55 ++++++++-----------
+ 1 file changed, 24 insertions(+), 31 deletions(-)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -402,7 +402,7 @@ static int isp_set_ctrl_cfa(struct stf_i
+
+ reg_write(ispbase, reg_addr, ((u32)(cfg->cross_cov & 0x3) << 4) | (cfg->hv_width & 0xf));
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -419,7 +419,7 @@ static int isp_set_ctrl_ctc(struct stf_i
+ reg_value |= ((u32)(cfg->max_gt & 0x3ff) << 16) | (cfg->min_gt & 0x3ff);
+ reg_write(ispbase, reg_addr, reg_value);
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -434,7 +434,7 @@ static int isp_set_ctrl_dbc(struct stf_i
+
+ reg_write(ispbase, reg_addr, ((u32)(cfg->bad_gt & 0x3ff) << 16) | (cfg->bad_xt & 0x3ff));
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -459,7 +459,7 @@ static int isp_set_ctrl_dnyuv(struct stf
+ reg_write(ispbase, reg_addr + 36, CREATE_REG_VALUE(u16, &cfg->uv_curve[4], 2, 0x3ff, 16));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -472,7 +472,7 @@ static int isp_set_ctrl_gmargb(struct st
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 15; i++, curve++, reg_addr += 4)
+ reg_write(ispbase, reg_addr, ((u32)curve->sg_val << 16) | (curve->g_val & 0x3ff));
+
+@@ -490,7 +490,7 @@ static int isp_set_ctrl_lccf(struct stf_
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ reg_write(ispbase, reg_addr, ((u32)(setting->circle.center_y & 0x7fff) << 16) | (setting->circle.center_x & 0x7fff));
+ reg_write(ispbase, reg_addr + 8, setting->circle.radius & 0xf);
+ reg_addr += 0x90;
+@@ -498,7 +498,7 @@ static int isp_set_ctrl_lccf(struct stf_
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x1fff, 16));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -511,7 +511,7 @@ static int isp_set_ctrl_obc(struct stf_i
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ reg_write(ispbase, reg_addr, ((u32)(setting->win_size.height & 0xf) << 4) | (setting->win_size.width & 0xf));
+
+ reg_addr += 0x2ac; //0x2e0
+@@ -519,7 +519,7 @@ static int isp_set_ctrl_obc(struct stf_i
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 4, 0xff, 8));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -535,7 +535,7 @@ static int isp_set_ctrl_oecf(struct stf_
+ void __iomem *ispbase = vin->isp_base;
+ u32 x, y, slope;
+ s32 i;
+-
++
+ for(i = 0; i < 32; i++, reg_x_addr += 4, reg_y_addr += 4, reg_s_addr += 4) {
+ x = pts->x & 0x3ff;
+ y = pts->y & 0x3ff;
+@@ -565,12 +565,12 @@ static int isp_set_ctrl_r2y(struct stf_i
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 9; i++, reg_addr += 4)
+ reg_write(ispbase, reg_addr, (u32)(params[i] & 0x1ff));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -584,7 +584,7 @@ static int isp_set_ctrl_sat(struct stf_i
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 3; i++, reg_addr += 4, params += 2)
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0xfff, 16));
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, &setting->hue_info.cos, 2, 0x3ff, 16));
+@@ -597,7 +597,7 @@ static int isp_set_ctrl_sat(struct stf_i
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x3fff, 16));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -609,7 +609,7 @@ static int isp_set_ctrl_shrp(struct stf_
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 4; i++, reg_addr += 4)
+ reg_write(ispbase, reg_addr, ((u32)(setting->strength.diff[i] & 0x3ff) << 16) | ((u32)(setting->weight.weight[i] & 0xf) << 8));
+ FILL_ISP_REGS(u8, ispbase, reg_addr, (u8 *)(&setting->weight.weight[4]), 15 - 4, 0xf, 8);
+@@ -622,7 +622,7 @@ static int isp_set_ctrl_shrp(struct stf_
+ reg_write(ispbase, reg_addr, ((u32)(setting->pdirf & 0xf) << 28) | ((u32)(setting->ndirf & 0xf) << 24) | (setting->weight.recip_wei_sum & 0x3fffff));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -633,11 +633,11 @@ static int isp_set_ctrl_ycrv(struct stf_
+ u32 reg_addr = reg_info->cfg_reg;
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+-
++
+ FILL_ISP_REGS(u16, ispbase, reg_addr, (u16 *)(setting->curve.y), 64, 0x3ff, 0);
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -661,11 +661,11 @@ static int isp_set_ctrl_sc(struct stf_is
+ reg_write(ispbase, 0xb8, ((u32)(setting->crop_config.v_start) << 16) | setting->crop_config.h_start);
+
+ // SC config1
+- reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
++ reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
+ ((u32)(setting->crop_config.sw_height) << 8) | setting->crop_config.sw_width);
+
+ // SC decimation config
+- reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
++ reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
+ ((u32)(setting->crop_config.hkeep) << 8) | setting->crop_config.hperiod);
+
+ // SC AWB pixel sum config
+@@ -676,7 +676,7 @@ static int isp_set_ctrl_sc(struct stf_is
+ reg_write(ispbase, 0xd4, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grbl, 2, 0xffff, 16));
+
+ // AF register
+- reg_write(ispbase, 0xc0,
++ reg_write(ispbase, 0xc0,
+ ((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
+ ((u32)(setting->af_config.es_ver_thr & 0xff) << 8) |
+ ((setting->af_config.ver_en & 0x1) << 3) |
+@@ -1217,7 +1217,7 @@ static int isp_get_interface_type(struct
+ static int isp_set_stream(struct v4l2_subdev *sd, int enable)
+ {
+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
+- int ret = 0, interface_type;
++ int interface_type;
+ struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_event src_ch = { 0 };
+
+@@ -1225,6 +1225,7 @@ static int isp_set_stream(struct v4l2_su
+ mutex_lock(&isp_dev->stream_lock);
+ if (enable) {
+ if (isp_dev->stream_count == 0) {
++ v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
+ isp_dev->hw_ops->isp_clk_enable(isp_dev);
+ if (!user_config_isp)
+ isp_dev->hw_ops->isp_config_set(isp_dev);
+@@ -1256,15 +1257,7 @@ static int isp_set_stream(struct v4l2_su
+ exit:
+ mutex_unlock(&isp_dev->stream_lock);
+
+- mutex_lock(&isp_dev->power_lock);
+- /* restore controls */
+- if (enable && isp_dev->power_count == 1) {
+- mutex_unlock(&isp_dev->power_lock);
+- ret = v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
+- } else
+- mutex_unlock(&isp_dev->power_lock);
+-
+- return ret;
++ return 0;
+ }
+
+ /*Try to match sensor format with sink, and then get the index as default.*/
diff --git a/target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch b/target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch
new file mode 100644
index 0000000000..ca36e5bf94
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch
@@ -0,0 +1,36 @@
+From 02f84ff43453b0f8dc2a1e4885e7003929349ee6 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 5 Mar 2024 11:00:21 +0800
+Subject: [PATCH 098/116] crypto: jh7110: Comment RSA algo register
+
+There are some issues in RSA algo, which will cause kernel crash.
+So comment RSA algo register temporarily.
+This commit should be reverted after the RSA issues are fixed.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/crypto/starfive/jh7110-cryp.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-cryp.c
++++ b/drivers/crypto/starfive/jh7110-cryp.c
+@@ -194,14 +194,14 @@ static int starfive_cryp_probe(struct pl
+ if (ret)
+ goto err_algs_hash;
+
+- ret = starfive_rsa_register_algs();
+- if (ret)
+- goto err_algs_rsa;
++// ret = starfive_rsa_register_algs();
++// if (ret)
++// goto err_algs_rsa;
+
+ return 0;
+
+-err_algs_rsa:
+- starfive_hash_unregister_algs();
++// err_algs_rsa:
++// starfive_hash_unregister_algs();
+ err_algs_hash:
+ starfive_aes_unregister_algs();
+ err_algs_aes:
diff --git a/target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch b/target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch
new file mode 100644
index 0000000000..d04b082d68
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch
@@ -0,0 +1,26 @@
+From a7ff2b51e2941526d6924dcf8f1760187d7e5d03 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 11 Mar 2024 11:10:45 +0800
+Subject: [PATCH 099/116] riscv: dts: starfive: jh7110-evb: Add qspi norflash
+ partition for uboot-env
+
+Add qspi norflash partition "uboot-env@f0000",
+for synchronizing with other branches.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-evb.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
+@@ -568,6 +568,9 @@
+ spl@0 {
+ reg = <0x0 0x40000>;
+ };
++ uboot-env@f0000 {
++ reg = <0xf0000 0x10000>;
++ };
+ uboot@100000 {
+ reg = <0x100000 0x300000>;
+ };
diff --git a/target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch b/target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch
new file mode 100644
index 0000000000..ad8b98d17b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch
@@ -0,0 +1,22 @@
+From f96ba2eb39ba950f67edf43e0c5c88ac660bc2a0 Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Wed, 13 Mar 2024 18:43:27 +0800
+Subject: [PATCH 100/116] driver: regulator: pmic driver support kernel 6.6
+
+pmic driver support kernel 6.6
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ drivers/regulator/axp20x-regulator.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/regulator/axp20x-regulator.c
++++ b/drivers/regulator/axp20x-regulator.c
+@@ -20,6 +20,7 @@
+ #include <linux/mfd/axp20x.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/driver.h>
diff --git a/target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch b/target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch
new file mode 100644
index 0000000000..8112243bc7
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch
@@ -0,0 +1,232 @@
+From c609818850807a1ae5fa17e165f2b66b914188b4 Mon Sep 17 00:00:00 2001
+From: "xingyu.wu" <xingyu.wu@starfivetech.com>
+Date: Tue, 28 Jun 2022 22:48:15 +0800
+Subject: [PATCH 101/116] spi-pl022:starfive:Add platform bus register to adapt
+ overlay
+
+Add platform bus register to adapt dtbo overlay.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 137 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 131 insertions(+), 6 deletions(-)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -34,6 +34,7 @@
+ #include <linux/of.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
++#include <linux/platform_device.h>
+
+ /*
+ * This macro is used to define some register default values.
+@@ -2088,7 +2089,10 @@ pl022_platform_data_dt_get(struct device
+ return NULL;
+ }
+
+- pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
++ if (strncmp(dev->bus->name, "platform", strlen("platform")))
++ pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
++ else
++ pd = kzalloc(sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ if (!pd)
+ return NULL;
+
+@@ -2108,6 +2112,14 @@ static int pl022_probe(struct amba_devic
+ struct spi_controller *host;
+ struct pl022 *pl022 = NULL; /*Data for this driver */
+ int status = 0;
++ int platform_flag = 0;
++
++ if (strncmp(dev->bus->name, "platform", strlen("platform")))
++ platform_flag = 0;
++ else
++ platform_flag = 1;
++ dev_dbg(&adev->dev, "bus name:%s platform flag:%d",
++ dev->bus->name, platform_flag);
+
+ dev_info(&adev->dev,
+ "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
+@@ -2161,7 +2173,11 @@ static int pl022_probe(struct amba_devic
+ goto err_no_ioregion;
+
+ pl022->phybase = adev->res.start;
+- pl022->virtbase = devm_ioremap(dev, adev->res.start,
++ if (platform_flag)
++ pl022->virtbase = ioremap(adev->res.start,
++ resource_size(&adev->res));
++ else
++ pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
+ if (pl022->virtbase == NULL) {
+ status = -ENOMEM;
+@@ -2170,7 +2186,10 @@ static int pl022_probe(struct amba_devic
+ dev_info(&adev->dev, "mapped registers from %pa to %p\n",
+ &adev->res.start, pl022->virtbase);
+
+- pl022->clk = devm_clk_get(&adev->dev, NULL);
++ if (platform_flag)
++ pl022->clk = clk_get(&adev->dev, NULL);
++ else
++ pl022->clk = devm_clk_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->clk)) {
+ status = PTR_ERR(pl022->clk);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
+@@ -2183,7 +2202,10 @@ static int pl022_probe(struct amba_devic
+ goto err_no_clk_en;
+ }
+
+- pl022->rst = devm_reset_control_get(&adev->dev, NULL);
++ if (platform_flag)
++ pl022->rst = reset_control_get_exclusive(&adev->dev, NULL);
++ else
++ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->rst)) {
+ status = PTR_ERR(pl022->rst);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
+@@ -2205,7 +2227,11 @@ static int pl022_probe(struct amba_devic
+ SSP_CR1(pl022->virtbase));
+ load_ssp_default_config(pl022);
+
+- status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
++ if (platform_flag)
++ status = request_irq(adev->irq[0], pl022_interrupt_handler,
++ 0, "pl022", pl022);
++ else
++ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ 0, "pl022", pl022);
+ if (status < 0) {
+ dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
+@@ -2230,7 +2256,10 @@ static int pl022_probe(struct amba_devic
+
+ /* Register with the SPI framework */
+ amba_set_drvdata(adev, pl022);
+- status = devm_spi_register_controller(&adev->dev, host);
++ if (platform_flag)
++ status = spi_register_controller(host);
++ else
++ status = devm_spi_register_controller(&adev->dev, host);
+ if (status != 0) {
+ dev_err_probe(&adev->dev, status,
+ "problem registering spi host\n");
+@@ -2255,15 +2284,26 @@ static int pl022_probe(struct amba_devic
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+ err_no_irq:
++ if (platform_flag)
++ free_irq(adev->irq[0], pl022);
++ reset_control_assert(pl022->rst);
+ err_no_rst_de:
++ if (platform_flag)
++ reset_control_put(pl022->rst);
+ err_no_rst:
+ clk_disable_unprepare(pl022->clk);
+ err_no_clk_en:
++ if (platform_flag)
++ clk_put(pl022->clk);
+ err_no_clk:
++ if (platform_flag)
++ iounmap(pl022->virtbase);
+ err_no_ioremap:
+ amba_release_regions(adev);
+ err_no_ioregion:
+ spi_controller_put(host);
++ if (platform_flag)
++ kfree(platform_info);
+ return status;
+ }
+
+@@ -2464,6 +2504,91 @@ static void __exit pl022_exit(void)
+ }
+ module_exit(pl022_exit);
+
++/*
++ * Register PL022 in platform bus to accommodate overlay use.
++ * Because overlay only trigger response from the platform bus
++ * not amba bus.
++ */
++static int starfive_of_pl022_probe(struct platform_device *pdev)
++{
++ int ret;
++ const struct amba_id id = {
++ .id = 0x00041022,
++ .mask = 0x000fffff,
++ .data = &vendor_arm
++ };
++ struct amba_device *pcdev;
++ struct device *dev = &pdev->dev;
++
++ pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
++ if (!pcdev)
++ return -ENOMEM;
++
++ pcdev->dev = pdev->dev;
++ pcdev->periphid = id.id;
++ pcdev->res = *(pdev->resource);
++
++ pcdev->irq[0] = platform_get_irq(pdev, 0);
++ if (pcdev->irq[0] < 0) {
++ dev_err(dev, "failed to get irq\n");
++ ret = -EINVAL;
++ }
++
++ ret = pl022_probe(pcdev, &id);
++
++ return ret;
++}
++
++static int starfive_of_pl022_remove(struct platform_device *pdev)
++{
++ u32 size;
++ int irq;
++ struct pl022 *pl022 = dev_get_drvdata(&pdev->dev);
++
++ if (!pl022)
++ return 0;
++
++ pm_runtime_get_noresume(&pdev->dev);
++
++ load_ssp_default_config(pl022);
++ if (pl022->host_info->enable_dma)
++ pl022_dma_remove(pl022);
++
++ irq = platform_get_irq(pdev, 0);
++ free_irq(irq, pl022);
++ reset_control_assert(pl022->rst);
++ reset_control_put(pl022->rst);
++ clk_disable_unprepare(pl022->clk);
++ clk_put(pl022->clk);
++ iounmap(pl022->virtbase);
++ kfree(pl022->host_info);
++
++ size = resource_size(pdev->resource);
++ release_mem_region(pdev->resource->start, size);
++ tasklet_disable(&pl022->pump_transfers);
++ return 0;
++}
++
++static const struct of_device_id starfive_of_pl022_match[] = {
++ { .compatible = "starfive,jh7110-spi-pl022" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, starfive_of_pl022_match);
++
++static struct platform_driver starfive_of_pl022_driver = {
++ .driver = {
++ .name = "starfive-spi-pl022",
++ .of_match_table = starfive_of_pl022_match,
++ .pm = &pl022_dev_pm_ops,
++ },
++ .probe = starfive_of_pl022_probe,
++ .remove = starfive_of_pl022_remove,
++};
++
++module_platform_driver(starfive_of_pl022_driver);
++/* platform register end */
++
++MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");
+ MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
+ MODULE_DESCRIPTION("PL022 SSP Controller Driver");
+ MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch b/target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch
new file mode 100644
index 0000000000..bd4709f01d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch
@@ -0,0 +1,92 @@
+From f94a07310f18720faa0cc773a1aec5a7b1bf3928 Mon Sep 17 00:00:00 2001
+From: "xingyu.wu" <xingyu.wu@starfivetech.com>
+Date: Tue, 19 Jul 2022 14:49:20 +0800
+Subject: [PATCH 102/116] spi:pl022-starfive:Avoid power device error when
+ CONFIG_PM enable
+
+It would be error when CONFIG_PM enable and use overlay by of-platform to register.
+
+Add some power manager operation in platform probe function.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 36 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -35,6 +35,8 @@
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
+ #include <linux/platform_device.h>
++#include <linux/clk/clk-conf.h>
++#include <linux/pm_domain.h>
+
+ /*
+ * This macro is used to define some register default values.
+@@ -2266,7 +2268,8 @@ static int pl022_probe(struct amba_devic
+ goto err_spi_register;
+ }
+ dev_dbg(dev, "probe succeeded\n");
+-
++ if (!platform_flag)
++ platform_info->autosuspend_delay = 100;
+ /* let runtime pm put suspend */
+ if (platform_info->autosuspend_delay > 0) {
+ dev_info(&adev->dev,
+@@ -2276,7 +2279,10 @@ static int pl022_probe(struct amba_devic
+ platform_info->autosuspend_delay);
+ pm_runtime_use_autosuspend(dev);
+ }
+- pm_runtime_put(dev);
++ if (platform_flag)
++ clk_disable_unprepare(pl022->clk);
++ else
++ pm_runtime_put(dev);
+
+ return 0;
+
+@@ -2534,8 +2540,33 @@ static int starfive_of_pl022_probe(struc
+ ret = -EINVAL;
+ }
+
++ ret = of_clk_set_defaults(dev->of_node, false);
++ if (ret < 0)
++ goto err_probe;
++
++ ret = dev_pm_domain_attach(dev, true);
++ if (ret)
++ goto err_probe;
++
+ ret = pl022_probe(pcdev, &id);
+
++ struct pl022 *pl022 = amba_get_drvdata(pcdev);
++
++ pl022->host->dev.parent = &pdev->dev;
++ platform_set_drvdata(pdev, pl022);
++
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
++ pm_runtime_use_autosuspend(&pdev->dev);
++
++ if (ret) {
++ pm_runtime_disable(dev);
++ pm_runtime_set_suspended(dev);
++ pm_runtime_put_noidle(dev);
++ dev_pm_domain_detach(dev, true);
++ }
++
++err_probe:
+ return ret;
+ }
+
+@@ -2566,6 +2597,7 @@ static int starfive_of_pl022_remove(stru
+ size = resource_size(pdev->resource);
+ release_mem_region(pdev->resource->start, size);
+ tasklet_disable(&pl022->pump_transfers);
++ pm_runtime_disable(&pdev->dev);
+ return 0;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch b/target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch
new file mode 100644
index 0000000000..3e36e84641
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch
@@ -0,0 +1,403 @@
+From 733e7bd23a1efad15a724fbdbce8d9f06aa6813a Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfive.com>
+Date: Wed, 23 Nov 2022 14:53:58 +0800
+Subject: [PATCH 103/116] spi-pl022-starfive:fix the problem of spi overlay
+ reload
+
+fix the problem of spi overlay reload
+
+Signed-off-by: ziv.xu <ziv.xu@starfive.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 270 ++++++++++++++++++++++++++++------------
+ 1 file changed, 188 insertions(+), 82 deletions(-)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -2106,6 +2106,172 @@ pl022_platform_data_dt_get(struct device
+ return pd;
+ }
+
++static int pl022_platform_probe(struct platform_device *pdev, const struct amba_id *id)
++{
++ struct device *dev = &pdev->dev;
++ struct spi_controller *host;
++ struct pl022_ssp_controller *platform_info;
++ struct amba_device *adev;
++ struct pl022 *pl022 = NULL;
++ struct resource *res;
++ int status = 0;
++ int irq;
++
++ dev_info(dev,
++ "ARM PL022 driver for StarFive SoC platform, device ID: 0x%08x\n",
++ id->id);
++
++ adev = devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL);
++ adev->dev = pdev->dev;
++ platform_info = pl022_platform_data_dt_get(dev);
++ if (!platform_info) {
++ dev_err(dev, "probe: no platform data defined\n");
++ return -ENODEV;
++ }
++ /* Allocate host with space for data */
++ host = spi_alloc_host(dev, sizeof(struct pl022));
++ if (host == NULL) {
++ dev_err(dev, "probe - cannot alloc SPI host\n");
++ return -ENOMEM;
++ }
++
++ pl022 = spi_controller_get_devdata(host);
++ pl022->host = host;
++ pl022->host_info = platform_info;
++ pl022->adev = adev;
++ pl022->vendor = id->data;
++ pl022->host->dev.parent = &pdev->dev;
++ /*
++ * Bus Number Which has been Assigned to this SSP controller
++ * on this board
++ */
++ host->bus_num = platform_info->bus_id;
++ host->cleanup = pl022_cleanup;
++ host->setup = pl022_setup;
++ /* If open CONFIG_PM, auto_runtime_pm should be false when of-platform.*/
++ host->auto_runtime_pm = true;
++ host->transfer_one_message = pl022_transfer_one_message;
++ host->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
++ host->rt = platform_info->rt;
++ host->dev.of_node = dev->of_node;
++ host->use_gpio_descriptors = true;
++
++ /*
++ * Supports mode 0-3, loopback, and active low CS. Transfers are
++ * always MS bit first on the original pl022.
++ */
++ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
++ if (pl022->vendor->extended_cr)
++ host->mode_bits |= SPI_LSB_FIRST;
++
++ dev_dbg(dev, "BUSNO: %d\n", host->bus_num);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ pl022->phybase = res->start;
++ pl022->virtbase = devm_ioremap_resource(dev, res);
++ if (pl022->virtbase == NULL) {
++ status = -ENOMEM;
++ goto err_no_ioremap;
++ }
++ dev_info(dev, "mapped registers from %llx to %llx\n",
++ pdev->resource->start, pdev->resource->end);
++
++ pl022->clk = devm_clk_get(dev, NULL);
++ if (IS_ERR(pl022->clk)) {
++ status = PTR_ERR(pl022->clk);
++ dev_err(dev, "could not retrieve SSP/SPI bus clock\n");
++ goto err_no_clk;
++ }
++ status = clk_prepare_enable(pl022->clk);
++ if (status) {
++ dev_err(dev, "could not enable SSP/SPI bus clock\n");
++ goto err_no_clk_en;
++ }
++
++ pl022->rst = devm_reset_control_get_exclusive(dev, NULL);
++ if (!IS_ERR(pl022->rst)) {
++ status = reset_control_deassert(pl022->rst);
++ if (status) {
++ dev_err(dev, "could not deassert SSP/SPI bus reset\n");
++ goto err_no_rst_clr;
++ }
++ } else {
++ status = PTR_ERR(pl022->rst);
++ dev_err(dev, "could not retrieve SSP/SPI bus reset\n");
++ goto err_no_rst;
++ }
++
++ /* Initialize transfer pump */
++ tasklet_init(&pl022->pump_transfers, pump_transfers,
++ (unsigned long)pl022);
++
++ /* Disable SSP */
++ writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
++ SSP_CR1(pl022->virtbase));
++ load_ssp_default_config(pl022);
++
++ /* Obtain IRQ line. */
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ status = -ENXIO;
++ goto err_no_irq;
++ }
++ status = devm_request_irq(dev, irq, pl022_interrupt_handler,
++ 0, "pl022", pl022);
++ if (status < 0) {
++ dev_err(dev, "probe - cannot get IRQ (%d)\n", status);
++ goto err_no_irq;
++ }
++
++ /* Get DMA channels, try autoconfiguration first */
++ status = pl022_dma_autoprobe(pl022);
++ if (status == -EPROBE_DEFER) {
++ dev_dbg(dev, "deferring probe to get DMA channel\n");
++ goto err_no_irq;
++ }
++
++ /* dma is not used unless configured in the device tree */
++ platform_info->enable_dma = 0;
++
++ /* If that failed, use channels from platform_info */
++ if (status == 0)
++ platform_info->enable_dma = 1;
++ else if (platform_info->enable_dma) {
++ status = pl022_dma_probe(pl022);
++ if (status != 0)
++ platform_info->enable_dma = 0;
++ }
++
++ /* Register with the SPI framework */
++ dev_set_drvdata(dev, pl022);
++
++ status = devm_spi_register_controller(dev, host);
++ if (status != 0) {
++ dev_err(dev,
++ "probe - problem registering spi host\n");
++ goto err_spi_register;
++ }
++ dev_dbg(dev, "probe succeeded\n");
++
++ clk_disable_unprepare(pl022->clk);
++
++ return 0;
++ err_spi_register:
++ if (platform_info->enable_dma)
++ pl022_dma_remove(pl022);
++ err_no_irq:
++ reset_control_assert(pl022->rst);
++ err_no_rst_clr:
++ err_no_rst:
++ clk_disable_unprepare(pl022->clk);
++ err_no_clk_en:
++ err_no_clk:
++ err_no_ioremap:
++ release_mem_region(pdev->resource->start, resource_size(pdev->resource));
++ spi_controller_put(host);
++ return status;
++}
++
+ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
+ {
+ struct device *dev = &adev->dev;
+@@ -2114,14 +2280,6 @@ static int pl022_probe(struct amba_devic
+ struct spi_controller *host;
+ struct pl022 *pl022 = NULL; /*Data for this driver */
+ int status = 0;
+- int platform_flag = 0;
+-
+- if (strncmp(dev->bus->name, "platform", strlen("platform")))
+- platform_flag = 0;
+- else
+- platform_flag = 1;
+- dev_dbg(&adev->dev, "bus name:%s platform flag:%d",
+- dev->bus->name, platform_flag);
+
+ dev_info(&adev->dev,
+ "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
+@@ -2175,11 +2333,7 @@ static int pl022_probe(struct amba_devic
+ goto err_no_ioregion;
+
+ pl022->phybase = adev->res.start;
+- if (platform_flag)
+- pl022->virtbase = ioremap(adev->res.start,
+- resource_size(&adev->res));
+- else
+- pl022->virtbase = devm_ioremap(dev, adev->res.start,
++ pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
+ if (pl022->virtbase == NULL) {
+ status = -ENOMEM;
+@@ -2188,10 +2342,7 @@ static int pl022_probe(struct amba_devic
+ dev_info(&adev->dev, "mapped registers from %pa to %p\n",
+ &adev->res.start, pl022->virtbase);
+
+- if (platform_flag)
+- pl022->clk = clk_get(&adev->dev, NULL);
+- else
+- pl022->clk = devm_clk_get(&adev->dev, NULL);
++ pl022->clk = devm_clk_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->clk)) {
+ status = PTR_ERR(pl022->clk);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
+@@ -2204,10 +2355,7 @@ static int pl022_probe(struct amba_devic
+ goto err_no_clk_en;
+ }
+
+- if (platform_flag)
+- pl022->rst = reset_control_get_exclusive(&adev->dev, NULL);
+- else
+- pl022->rst = devm_reset_control_get(&adev->dev, NULL);
++ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->rst)) {
+ status = PTR_ERR(pl022->rst);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
+@@ -2229,11 +2377,7 @@ static int pl022_probe(struct amba_devic
+ SSP_CR1(pl022->virtbase));
+ load_ssp_default_config(pl022);
+
+- if (platform_flag)
+- status = request_irq(adev->irq[0], pl022_interrupt_handler,
+- 0, "pl022", pl022);
+- else
+- status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
++ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ 0, "pl022", pl022);
+ if (status < 0) {
+ dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
+@@ -2258,18 +2402,16 @@ static int pl022_probe(struct amba_devic
+
+ /* Register with the SPI framework */
+ amba_set_drvdata(adev, pl022);
+- if (platform_flag)
+- status = spi_register_controller(host);
+- else
+- status = devm_spi_register_controller(&adev->dev, host);
++
++ status = devm_spi_register_controller(&adev->dev, host);
+ if (status != 0) {
+ dev_err_probe(&adev->dev, status,
+ "problem registering spi host\n");
+ goto err_spi_register;
+ }
+ dev_dbg(dev, "probe succeeded\n");
+- if (!platform_flag)
+- platform_info->autosuspend_delay = 100;
++
++ platform_info->autosuspend_delay = 100;
+ /* let runtime pm put suspend */
+ if (platform_info->autosuspend_delay > 0) {
+ dev_info(&adev->dev,
+@@ -2279,10 +2421,8 @@ static int pl022_probe(struct amba_devic
+ platform_info->autosuspend_delay);
+ pm_runtime_use_autosuspend(dev);
+ }
+- if (platform_flag)
+- clk_disable_unprepare(pl022->clk);
+- else
+- pm_runtime_put(dev);
++
++ pm_runtime_put(dev);
+
+ return 0;
+
+@@ -2290,26 +2430,17 @@ static int pl022_probe(struct amba_devic
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+ err_no_irq:
+- if (platform_flag)
+- free_irq(adev->irq[0], pl022);
+ reset_control_assert(pl022->rst);
+ err_no_rst_de:
+- if (platform_flag)
+- reset_control_put(pl022->rst);
+ err_no_rst:
+ clk_disable_unprepare(pl022->clk);
+ err_no_clk_en:
+- if (platform_flag)
+- clk_put(pl022->clk);
+ err_no_clk:
+- if (platform_flag)
+- iounmap(pl022->virtbase);
+ err_no_ioremap:
+ amba_release_regions(adev);
+ err_no_ioregion:
+ spi_controller_put(host);
+- if (platform_flag)
+- kfree(platform_info);
++
+ return status;
+ }
+
+@@ -2523,23 +2654,8 @@ static int starfive_of_pl022_probe(struc
+ .mask = 0x000fffff,
+ .data = &vendor_arm
+ };
+- struct amba_device *pcdev;
+ struct device *dev = &pdev->dev;
+
+- pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
+- if (!pcdev)
+- return -ENOMEM;
+-
+- pcdev->dev = pdev->dev;
+- pcdev->periphid = id.id;
+- pcdev->res = *(pdev->resource);
+-
+- pcdev->irq[0] = platform_get_irq(pdev, 0);
+- if (pcdev->irq[0] < 0) {
+- dev_err(dev, "failed to get irq\n");
+- ret = -EINVAL;
+- }
+-
+ ret = of_clk_set_defaults(dev->of_node, false);
+ if (ret < 0)
+ goto err_probe;
+@@ -2548,16 +2664,11 @@ static int starfive_of_pl022_probe(struc
+ if (ret)
+ goto err_probe;
+
+- ret = pl022_probe(pcdev, &id);
++ ret = pl022_platform_probe(pdev, &id);
+
+- struct pl022 *pl022 = amba_get_drvdata(pcdev);
+-
+- pl022->host->dev.parent = &pdev->dev;
+- platform_set_drvdata(pdev, pl022);
+-
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
+- pm_runtime_use_autosuspend(&pdev->dev);
++ pm_runtime_enable(dev);
++ pm_runtime_set_autosuspend_delay(dev, 100);
++ pm_runtime_use_autosuspend(dev);
+
+ if (ret) {
+ pm_runtime_disable(dev);
+@@ -2572,32 +2683,27 @@ err_probe:
+
+ static int starfive_of_pl022_remove(struct platform_device *pdev)
+ {
+- u32 size;
+- int irq;
+ struct pl022 *pl022 = dev_get_drvdata(&pdev->dev);
+
+ if (!pl022)
+ return 0;
+
++ pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_get_noresume(&pdev->dev);
+
+ load_ssp_default_config(pl022);
+ if (pl022->host_info->enable_dma)
+ pl022_dma_remove(pl022);
+
+- irq = platform_get_irq(pdev, 0);
+- free_irq(irq, pl022);
+- reset_control_assert(pl022->rst);
+- reset_control_put(pl022->rst);
+ clk_disable_unprepare(pl022->clk);
+- clk_put(pl022->clk);
+- iounmap(pl022->virtbase);
+- kfree(pl022->host_info);
+-
+- size = resource_size(pdev->resource);
+- release_mem_region(pdev->resource->start, size);
+ tasklet_disable(&pl022->pump_transfers);
++
++ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_set_suspended(&pdev->dev);
++ pm_runtime_put_noidle(&pdev->dev);
++ dev_pm_domain_detach(&pdev->dev, true);
++
+ return 0;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch b/target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch
new file mode 100644
index 0000000000..aecce737d9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch
@@ -0,0 +1,38 @@
+From 11a917bf429a5714e34584f90ab1ac376d399d8f Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfive.com>
+Date: Wed, 18 Jan 2023 15:50:47 +0800
+Subject: [PATCH 104/116] spi-pl022-starfive:Enable spi to be compiled into
+ modules
+
+Enable spi to be compiled into modules
+
+Signed-off-by: ziv.xu <ziv.xu@starfive.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -2633,7 +2633,11 @@ static int __init pl022_init(void)
+ {
+ return amba_driver_register(&pl022_driver);
+ }
++#if !IS_MODULE(CONFIG_SPI_PL022)
+ subsys_initcall(pl022_init);
++#else
++module_init(pl022_init);
++#endif
+
+ static void __exit pl022_exit(void)
+ {
+@@ -2723,7 +2727,9 @@ static struct platform_driver starfive_o
+ .remove = starfive_of_pl022_remove,
+ };
+
++#if !IS_MODULE(CONFIG_SPI_PL022)
+ module_platform_driver(starfive_of_pl022_driver);
++#endif
+ /* platform register end */
+
+ MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");
diff --git a/target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch b/target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch
new file mode 100644
index 0000000000..bc1d836c11
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch
@@ -0,0 +1,444 @@
+From e7b01c0a9ad79c1933ce85c4aeca6a037cc4f77f Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Wed, 13 Mar 2024 18:37:31 +0800
+Subject: [PATCH 105/116] riscv: configs: add visionfive2 defconfig to kernel
+ 6.6
+
+add visionfive2 defconfig to kernel 6.6
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ .../configs/starfive_visionfive2_defconfig | 427 ++++++++++++++++++
+ 1 file changed, 427 insertions(+)
+ create mode 100644 arch/riscv/configs/starfive_visionfive2_defconfig
+
+--- /dev/null
++++ b/arch/riscv/configs/starfive_visionfive2_defconfig
+@@ -0,0 +1,427 @@
++CONFIG_COMPILE_TEST=y
++# CONFIG_WERROR is not set
++CONFIG_DEFAULT_HOSTNAME="StarFive"
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_USELIB=y
++CONFIG_NO_HZ_IDLE=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_BPF_SYSCALL=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_CGROUPS=y
++CONFIG_CGROUP_SCHED=y
++CONFIG_CFS_BANDWIDTH=y
++CONFIG_CGROUP_BPF=y
++CONFIG_NAMESPACES=y
++CONFIG_USER_NS=y
++CONFIG_CHECKPOINT_RESTORE=y
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_EXPERT=y
++CONFIG_PERF_EVENTS=y
++CONFIG_SOC_STARFIVE=y
++CONFIG_NONPORTABLE=y
++CONFIG_SMP=y
++CONFIG_HZ_100=y
++CONFIG_HIBERNATION=y
++CONFIG_PM_DEBUG=y
++CONFIG_PM_ADVANCED_DEBUG=y
++CONFIG_PM_TEST_SUSPEND=y
++CONFIG_CPU_IDLE=y
++CONFIG_RISCV_SBI_CPUIDLE=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_SECCOMP is not set
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_BINFMT_MISC=y
++CONFIG_PAGE_REPORTING=y
++CONFIG_CMA=y
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++CONFIG_NETFILTER=y
++CONFIG_NETFILTER_NETLINK_ACCT=y
++CONFIG_NETFILTER_NETLINK_QUEUE=y
++CONFIG_NF_CONNTRACK=y
++CONFIG_NF_TABLES=y
++CONFIG_NFT_CT=y
++CONFIG_NFT_COMPAT=y
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
++CONFIG_NETFILTER_XT_MATCH_IPCOMP=y
++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
++CONFIG_NETFILTER_XT_MATCH_MAC=y
++CONFIG_NETFILTER_XT_MATCH_MARK=y
++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
++CONFIG_NETFILTER_XT_MATCH_SOCKET=y
++CONFIG_NETFILTER_XT_MATCH_STATE=y
++CONFIG_NETFILTER_XT_MATCH_STRING=y
++CONFIG_NETFILTER_XT_MATCH_U32=y
++CONFIG_NF_TABLES_IPV4=y
++CONFIG_NFT_DUP_IPV4=y
++CONFIG_NFT_FIB_IPV4=y
++CONFIG_IP_NF_IPTABLES=y
++CONFIG_IP_NF_FILTER=y
++CONFIG_IP_NF_TARGET_REJECT=y
++CONFIG_IP_NF_NAT=y
++CONFIG_IP_NF_TARGET_MASQUERADE=y
++CONFIG_IP_NF_TARGET_NETMAP=y
++CONFIG_IP_NF_TARGET_REDIRECT=y
++CONFIG_NETLINK_DIAG=y
++CONFIG_CAN=y
++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_HCIBTUSB=m
++# CONFIG_BT_HCIBTUSB_BCM is not set
++CONFIG_CFG80211=y
++CONFIG_MAC80211=y
++CONFIG_RFKILL=y
++CONFIG_NET_9P=y
++CONFIG_NET_9P_VIRTIO=y
++CONFIG_PCI=y
++# CONFIG_PCIEASPM is not set
++CONFIG_PCIE_STARFIVE_HOST=y
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_MTD=y
++CONFIG_MTD_BLOCK=y
++CONFIG_MTD_CFI=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_SPI_NOR=y
++CONFIG_OF_CONFIGFS=y
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_VIRTIO_BLK=y
++CONFIG_BLK_DEV_NVME=y
++CONFIG_EEPROM_AT24=y
++CONFIG_BLK_DEV_SD=y
++CONFIG_BLK_DEV_SR=y
++CONFIG_SCSI_VIRTIO=y
++CONFIG_ATA=y
++CONFIG_SATA_AHCI=y
++CONFIG_MD=y
++CONFIG_BLK_DEV_DM=m
++CONFIG_NETDEVICES=y
++CONFIG_VIRTIO_NET=y
++# 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_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_EZCHIP is not set
++# CONFIG_NET_VENDOR_GOOGLE 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_NI is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_NET_VENDOR_NETRONOME is not set
++# CONFIG_NET_VENDOR_PENSANDO is not set
++# CONFIG_NET_VENDOR_QUALCOMM 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_SOCIONEXT is not set
++CONFIG_STMMAC_ETH=y
++CONFIG_STMMAC_SELFTESTS=y
++CONFIG_DWMAC_DWC_QOS_ETH=y
++CONFIG_DWMAC_STARFIVE=y
++# 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_MARVELL_PHY=y
++CONFIG_MICREL_PHY=y
++CONFIG_MICROCHIP_PHY=y
++CONFIG_MOTORCOMM_PHY=y
++CONFIG_IPMS_CAN=y
++CONFIG_IWLWIFI=y
++CONFIG_IWLDVM=y
++CONFIG_IWLMVM=y
++CONFIG_HOSTAP=y
++# CONFIG_RTL_CARDS is not set
++CONFIG_USB_WIFI_ECR6600U=y
++CONFIG_AIC_WLAN_SUPPORT=y
++CONFIG_AIC8800_WLAN_SUPPORT=m
++CONFIG_AIC_LOADFW_SUPPORT=m
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++CONFIG_TOUCHSCREEN_GOODIX=y
++CONFIG_TOUCHSCREEN_TINKER_FT5406=y
++CONFIG_SERIO_LIBPS2=y
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=6
++CONFIG_SERIAL_8250_RUNTIME_UARTS=6
++CONFIG_SERIAL_8250_EXTENDED=y
++CONFIG_SERIAL_8250_MANY_PORTS=y
++CONFIG_SERIAL_8250_DW=y
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_TTY_PRINTK=y
++CONFIG_VIRTIO_CONSOLE=y
++CONFIG_HW_RANDOM=y
++CONFIG_HW_RANDOM_JH7110=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_DESIGNWARE_PLATFORM=y
++CONFIG_SPI=y
++CONFIG_SPI_CADENCE_QUADSPI=y
++CONFIG_SPI_PL022=y
++CONFIG_SPI_SIFIVE=y
++CONFIG_SPI_SPIDEV=y
++# CONFIG_PTP_1588_CLOCK is not set
++CONFIG_GPIO_SYSFS=y
++CONFIG_POWER_RESET=y
++CONFIG_POWER_RESET_GPIO_RESTART=y
++CONFIG_POWER_RESET_SYSCON=y
++CONFIG_POWER_RESET_SYSCON_POWEROFF=y
++CONFIG_SENSORS_SFCTEMP=y
++CONFIG_THERMAL=y
++CONFIG_THERMAL_WRITABLE_TRIPS=y
++CONFIG_CPU_THERMAL=y
++CONFIG_DEVFREQ_THERMAL=y
++CONFIG_THERMAL_EMULATION=y
++# CONFIG_HISI_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_SYSFS=y
++CONFIG_MFD_AXP20X_I2C=y
++CONFIG_REGULATOR=y
++CONFIG_REGULATOR_AXP20X=y
++CONFIG_REGULATOR_GPIO=y
++CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=y
++# CONFIG_MEDIA_CEC_SUPPORT is not set
++CONFIG_MEDIA_SUPPORT=y
++CONFIG_MEDIA_USB_SUPPORT=y
++CONFIG_USB_VIDEO_CLASS=y
++CONFIG_V4L_PLATFORM_DRIVERS=y
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++CONFIG_VIDEO_CADENCE_CSI2RX=y
++CONFIG_VIDEO_WAVE_VPU=m
++CONFIG_VIN_SENSOR_OV4689=y
++CONFIG_VIN_SENSOR_IMX219=y
++CONFIG_VIDEO_STF_VIN=y
++CONFIG_VIDEO_IMX219=y
++CONFIG_VIDEO_IMX708=y
++CONFIG_DRM_PANEL_SIMPLE=y
++CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=y
++CONFIG_DRM_TOSHIBA_TC358762=y
++CONFIG_DRM_VERISILICON=y
++CONFIG_STARFIVE_INNO_HDMI=y
++CONFIG_STARFIVE_DSI=y
++CONFIG_DRM_IMG_ROGUE=y
++CONFIG_DRM_LEGACY=y
++CONFIG_FB=y
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_SOUND=y
++CONFIG_SND=y
++CONFIG_SND_USB_AUDIO=y
++CONFIG_SND_SOC=y
++CONFIG_SND_DESIGNWARE_I2S=y
++CONFIG_SND_SOC_RZ=m
++CONFIG_SND_SOC_STARFIVE=y
++CONFIG_SND_SOC_JH7110_PWMDAC=y
++CONFIG_SND_SOC_JH7110_TDM=y
++CONFIG_SND_SOC_AC108=y
++CONFIG_SND_SOC_WM8960=y
++CONFIG_SND_SIMPLE_CARD=y
++CONFIG_UHID=y
++CONFIG_USB=y
++CONFIG_USB_OTG=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_RENESAS_USBHS=y
++CONFIG_USB_STORAGE=y
++CONFIG_USB_UAS=y
++CONFIG_USB_CDNS_SUPPORT=y
++CONFIG_USB_CDNS3=y
++CONFIG_USB_CDNS3_GADGET=y
++CONFIG_USB_CDNS3_HOST=y
++CONFIG_USB_CDNS3_STARFIVE=y
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++CONFIG_USB_SERIAL_AIRCABLE=m
++CONFIG_USB_SERIAL_ARK3116=m
++CONFIG_USB_SERIAL_BELKIN=m
++CONFIG_USB_SERIAL_CH341=m
++CONFIG_USB_SERIAL_WHITEHEAT=m
++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
++CONFIG_USB_SERIAL_CP210X=m
++CONFIG_USB_SERIAL_CYPRESS_M8=m
++CONFIG_USB_SERIAL_EMPEG=m
++CONFIG_USB_SERIAL_FTDI_SIO=m
++CONFIG_USB_SERIAL_VISOR=m
++CONFIG_USB_SERIAL_IPAQ=m
++CONFIG_USB_SERIAL_IR=m
++CONFIG_USB_SERIAL_EDGEPORT=m
++CONFIG_USB_SERIAL_EDGEPORT_TI=m
++CONFIG_USB_SERIAL_F81232=m
++CONFIG_USB_SERIAL_GARMIN=m
++CONFIG_USB_SERIAL_IPW=m
++CONFIG_USB_SERIAL_IUU=m
++CONFIG_USB_SERIAL_KEYSPAN_PDA=m
++CONFIG_USB_SERIAL_KEYSPAN=m
++CONFIG_USB_SERIAL_KLSI=m
++CONFIG_USB_SERIAL_KOBIL_SCT=m
++CONFIG_USB_SERIAL_MCT_U232=m
++CONFIG_USB_SERIAL_METRO=m
++CONFIG_USB_SERIAL_MOS7720=m
++CONFIG_USB_SERIAL_MOS7840=m
++CONFIG_USB_SERIAL_NAVMAN=m
++CONFIG_USB_SERIAL_PL2303=m
++CONFIG_USB_SERIAL_OTI6858=m
++CONFIG_USB_SERIAL_QCAUX=m
++CONFIG_USB_SERIAL_QUALCOMM=m
++CONFIG_USB_SERIAL_SPCP8X5=m
++CONFIG_USB_SERIAL_SAFE=m
++CONFIG_USB_SERIAL_SIERRAWIRELESS=m
++CONFIG_USB_SERIAL_SYMBOL=m
++CONFIG_USB_SERIAL_TI=m
++CONFIG_USB_SERIAL_CYBERJACK=m
++CONFIG_USB_SERIAL_OMNINET=m
++CONFIG_USB_SERIAL_OPTICON=m
++CONFIG_USB_SERIAL_XSENS_MT=m
++CONFIG_USB_SERIAL_WISHBONE=m
++CONFIG_USB_SERIAL_SSU100=m
++CONFIG_USB_SERIAL_DEBUG=m
++CONFIG_USB_GADGET=y
++CONFIG_USB_RENESAS_USBHS_UDC=m
++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_MMC=y
++CONFIG_MMC_DEBUG=y
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_PLTFM=y
++CONFIG_MMC_SDHCI_OF_DWCMSHC=y
++CONFIG_MMC_SPI=y
++CONFIG_MMC_SDHI=y
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_STARFIVE=y
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_DRV_STARFIVE=y
++CONFIG_RTC_DRV_GOLDFISH=y
++CONFIG_DMADEVICES=y
++CONFIG_AMBA_PL08X=y
++CONFIG_DW_AXI_DMAC=y
++CONFIG_DMATEST=y
++# CONFIG_VIRTIO_MENU is not set
++# CONFIG_VHOST_MENU is not set
++CONFIG_GOLDFISH=y
++CONFIG_CLK_STARFIVE_JH7110_AON=y
++CONFIG_CLK_STARFIVE_JH7110_STG=y
++CONFIG_CLK_STARFIVE_JH7110_ISP=y
++CONFIG_CLK_STARFIVE_JH7110_VOUT=y
++CONFIG_MAILBOX=y
++CONFIG_STARFIVE_MBOX=m
++CONFIG_STARFIVE_MBOX_TEST=m
++# CONFIG_IOMMU_SUPPORT is not set
++CONFIG_RPMSG_CHAR=y
++CONFIG_RPMSG_VIRTIO=y
++CONFIG_SIFIVE_CCACHE=y
++CONFIG_PM_DEVFREQ=y
++CONFIG_IIO=y
++CONFIG_IIO_ST_ACCEL_3AXIS=y
++CONFIG_PWM=y
++CONFIG_PWM_OCORES=y
++CONFIG_PHY_STARFIVE_JH7110_PCIE=y
++CONFIG_PHY_STARFIVE_JH7110_USB=y
++CONFIG_PHY_M31_DPHY_RX0=y
++CONFIG_RAS=y
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_BTRFS_FS=m
++CONFIG_BTRFS_FS_POSIX_ACL=y
++CONFIG_AUTOFS_FS=y
++CONFIG_FUSE_FS=y
++CONFIG_CUSE=y
++CONFIG_VIRTIO_FS=y
++CONFIG_FSCACHE=y
++CONFIG_FSCACHE_STATS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_UTF8=y
++CONFIG_EXFAT_FS=y
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_RW=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_HUGETLBFS=y
++CONFIG_JFFS2_FS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V4=y
++CONFIG_NFS_V4_1=y
++CONFIG_NFS_V4_2=y
++CONFIG_ROOT_NFS=y
++CONFIG_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_CIFS_DFS_UPCALL=y
++CONFIG_CIFS_FSCACHE=y
++CONFIG_SMB_SERVER=m
++CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_ISO8859_1=y
++CONFIG_INIT_STACK_NONE=y
++CONFIG_CRYPTO_USER=y
++CONFIG_CRYPTO_TEST=m
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_USER_API_RNG=y
++CONFIG_CRYPTO_USER_API_AEAD=y
++CONFIG_CRYPTO_DEV_VIRTIO=y
++CONFIG_CRYPTO_DEV_JH7110=y
++CONFIG_DMA_CMA=y
++CONFIG_PRINTK_TIME=y
++CONFIG_DEBUG_FS=y
++CONFIG_SOFTLOCKUP_DETECTOR=y
++CONFIG_WQ_WATCHDOG=y
++CONFIG_DEBUG_TIMEKEEPING=y
++CONFIG_DEBUG_RT_MUTEXES=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_RWSEMS=y
++CONFIG_DEBUG_LIST=y
++CONFIG_DEBUG_PLIST=y
++CONFIG_DEBUG_SG=y
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_EQS_DEBUG=y
++# CONFIG_FTRACE is not set
++# CONFIG_RUNTIME_TESTING_MENU is not set
++CONFIG_MEMTEST=y
diff --git a/target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch b/target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch
new file mode 100644
index 0000000000..defc0e669a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch
@@ -0,0 +1,759 @@
+From 51c1cccb202d741eeb1de57e0ecf8fcaa8f059e8 Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Wed, 13 Mar 2024 18:36:31 +0800
+Subject: [PATCH 106/116] riscv: dts: starfive: update dts to kernel 6.6
+
+update dts to kernel 6.6
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 5 +-
+ .../jh7110-starfive-visionfive-2-ac108.dts | 64 +++
+ .../jh7110-starfive-visionfive-2-tdm.dts | 59 +++
+ .../jh7110-starfive-visionfive-2-wm8960.dts | 71 +++
+ .../jh7110-starfive-visionfive-2.dtsi | 437 +++++++++++++++++-
+ 5 files changed, 633 insertions(+), 3 deletions(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-ac108.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -10,7 +10,10 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-be
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+-dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb \
++ jh7110-starfive-visionfive-2-ac108.dtb \
++ jh7110-starfive-visionfive-2-tdm.dtb \
++ jh7110-starfive-visionfive-2-wm8960.dtb
+
+ subdir-y += evb-overlay
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-ac108.dts
+@@ -0,0 +1,64 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2-v1.3b.dts"
++
++/ {
++ /* i2s + ac108 */
++ sound0: snd-card0 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "Starfive-AC108-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets =
++ "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing =
++ "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ cpu {
++ sound-dai = <&i2srx_mst>;
++ };
++
++ sndcodec1: codec {
++ sound-dai = <&ac108>;
++ clocks = <&ac108_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&i2c0 {
++ ac108: ac108@3b {
++ compatible = "x-power,ac108_0";
++ reg = <0x3b>;
++ #sound-dai-cells = <0>;
++ data-protocol = <0>;
++ };
++};
++
++&i2srx_mst {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
+@@ -0,0 +1,59 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2-v1.3b.dts"
++
++/ {
++ sound-tdm {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "Starfive-TDM-Sound-Card";
++ simple-audio-card,widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ simple-audio-card,routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "dsp_a";
++ bitclock-master = <&dailink_master>;
++ frame-master = <&dailink_master>;
++
++ cpu {
++ sound-dai = <&tdm>;
++ };
++ dailink_master: codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ };
++ };
++ };
++};
++
++&i2c0 {
++ wm8960: codec@1a {
++ compatible = "wlf,wm8960";
++ reg = <0x1a>;
++ wlf,shared-lrclk;
++ #sound-dai-cells = <0>;
++ };
++};
++
++&tdm {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
+@@ -0,0 +1,71 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2-v1.3b.dts"
++
++/ {
++ /* i2s + wm8960 */
++ sound-wm8960 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "Starfive-WM8960-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ status = "okay";
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets =
++ "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing =
++ "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++ cpu0 {
++ sound-dai = <&i2srx>;
++ };
++ cpu1 {
++ sound-dai = <&i2stx1>;
++ };
++
++ sndcodec1:codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&i2c0 {
++ wm8960: codec@1a {
++ compatible = "wlf,wm8960";
++ reg = <0x1a>;
++ wlf,shared-lrclk;
++ #sound-dai-cells = <0>;
++ };
++};
++
++&i2srx {
++ status = "okay";
++};
++
++&i2stx1 {
++ status = "okay";
++};
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -7,6 +7,7 @@
+ /dts-v1/;
+ #include "jh7110.dtsi"
+ #include "jh7110-pinfunc.h"
++#include <dt-bindings/leds/common.h>
+ #include <dt-bindings/gpio/gpio.h>
+
+ / {
+@@ -37,6 +38,44 @@
+ reg = <0x0 0x40000000 0x1 0x0>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ size = <0x0 0x20000000>;
++ alignment = <0x0 0x1000>;
++ alloc-ranges = <0x0 0x70000000 0x0 0x20000000>;
++ linux,cma-default;
++ };
++
++ e24_mem: e24@c0000000 {
++ reg = <0x0 0x6ce00000 0x0 0x1600000>;
++ };
++
++ xrp_reserved: xrpbuffer@f0000000 {
++ reg = <0x0 0x69c00000 0x0 0x01ffffff
++ 0x0 0x6bc00000 0x0 0x00001000
++ 0x0 0x6bc01000 0x0 0x00fff000
++ 0x0 0x6cc00000 0x0 0x00001000>;
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-ack {
++ gpios = <&aongpio 3 GPIO_ACTIVE_HIGH>;
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_HEARTBEAT;
++ linux,default-trigger = "heartbeat";
++ label = "ack";
++ };
++ };
++
+ gpio-restart {
+ compatible = "gpio-restart";
+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
+@@ -69,6 +108,48 @@
+ };
+ };
+ };
++
++ sound-hdmi {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-HDMI-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndi2s0>;
++ frame-master = <&sndi2s0>;
++ mclk-fs = <256>;
++ status = "okay";
++
++ sndi2s0: cpu {
++ sound-dai = <&i2stx0>;
++ };
++
++ codec {
++ sound-dai = <&hdmi>;
++ };
++ };
++ };
++
++ ac108_mclk: ac108_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ clk_ext_camera: clk-ext-camera {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ wm8960_mclk: wm8960_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ };
+ };
+
+ &dvp_clk {
+@@ -177,6 +258,42 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ status = "okay";
++
++ seeed_plane_i2c@45 {
++ compatible = "seeed_panel";
++ reg = <0x45>;
++
++ port {
++ panel_out0: endpoint {
++ remote-endpoint = <&dsi0_output>;
++ };
++ };
++ };
++
++ tinker_ft5406: tinker_ft5406@38 {
++ compatible = "tinker_ft5406";
++ reg = <0x38>;
++ };
++
++ touchscreen@14 {
++ compatible = "goodix,gt911";
++ reg = <0x14>;
++ irq-gpios = <&sysgpio 30 GPIO_ACTIVE_HIGH>;
++ reset-gpios = <&sysgpio 31 GPIO_ACTIVE_HIGH>;
++ };
++
++ panel_radxa@19 {
++ compatible ="starfive_jadard";
++ reg = <0x19>;
++ reset-gpio = <&sysgpio 23 0>;
++ enable-gpio = <&sysgpio 22 0>;
++
++ port {
++ panel_out1: endpoint {
++ remote-endpoint = <&dsi1_output>;
++ };
++ };
++ };
+ };
+
+ &i2c5 {
+@@ -195,11 +312,36 @@
+ #interrupt-cells = <1>;
+
+ regulators {
++ mipi_0p9: ALDO1 {
++ regulator-boot-on;
++ regulator-compatible = "aldo1";
++ regulator-name = "mipi_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++
++ hdmi_0p9: ALDO5 {
++ regulator-boot-on;
++ regulator-compatible = "aldo5";
++ regulator-name = "hdmi_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++
++ hdmi_1p8: ALDO3 {
++ regulator-boot-on;
++ regulator-compatible = "aldo3";
++ regulator-name = "hdmi_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
+ vcc_3v3: dcdc1 {
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
++ regulator-compatible = "dcdc1";
+ regulator-name = "vcc_3v3";
+ };
+
+@@ -207,6 +349,7 @@
+ regulator-always-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1540000>;
++ regulator-compatible = "dcdc2";
+ regulator-name = "vdd-cpu";
+ };
+
+@@ -215,6 +358,7 @@
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
++ regulator-compatible = "aldo4";
+ regulator-name = "emmc_vdd";
+ };
+ };
+@@ -229,12 +373,68 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_pins>;
+ status = "okay";
++
++ imx219: imx219@10 {
++ compatible = "sony,imx219";
++ reg = <0x10>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ reset-gpio = <&sysgpio 18 0>;
++ rotation = <0>;
++ orientation = <1>; //CAMERA_ORIENTATION_BACK
++
++ port {
++ /* CSI2 bus endpoint */
++ imx219_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx219>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ lane-polarities = <0 0 0>;
++ link-frequencies = /bits/ 64 <456000000>;
++ };
++ };
++ };
++
++ imx708: imx708@1a {
++ compatible = "sony,imx708";
++ reg = <0x1a>;
++ clocks = <&clk_ext_camera>;
++ reset-gpio = <&sysgpio 18 0>;
++
++ port {
++ imx708_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx708>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies = /bits/ 64 <450000000>;
++ };
++ };
++ };
++
++ ov4689: ov4689@36 {
++ compatible = "ovti,ov4689";
++ reg = <0x36>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ rotation = <180>;
++
++ port {
++ /* Parallel bus endpoint */
++ ov4689_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_ov4689>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ };
++ };
++ };
+ };
+
+ &i2srx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2srx_pins>;
+- status = "okay";
++ status = "disabled";
+ };
+
+ &i2stx0 {
+@@ -246,7 +446,7 @@
+ &i2stx1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2stx1_pins>;
+- status = "okay";
++ status = "disabled";
+ };
+
+ &mmc0 {
+@@ -661,6 +861,40 @@
+ slew-rate = <0>;
+ };
+ };
++
++ hdmi_pins: hdmi-0 {
++ scl-pins {
++ pinmux = <GPIOMUX(0, GPOUT_SYS_HDMI_DDC_SCL,
++ GPOEN_SYS_HDMI_DDC_SCL,
++ GPI_SYS_HDMI_DDC_SCL)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ sda-pins {
++ pinmux = <GPIOMUX(1, GPOUT_SYS_HDMI_DDC_SDA,
++ GPOEN_SYS_HDMI_DDC_SDA,
++ GPI_SYS_HDMI_DDC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ cec-pins {
++ pinmux = <GPIOMUX(14, GPOUT_SYS_HDMI_CEC_SDA,
++ GPOEN_SYS_HDMI_CEC_SDA,
++ GPI_SYS_HDMI_CEC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ hpd-pins {
++ pinmux = <GPIOMUX(15, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_HDMI_HPD)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ };
++ };
+ };
+
+ &uart0 {
+@@ -689,3 +923,202 @@
+ &U74_4 {
+ cpu-supply = <&vdd_cpu>;
+ };
++
++
++&display {
++ ports = <&dc_out_dpi0>;
++ status = "okay";
++};
++
++&dc8200 {
++ status = "okay";
++
++ dc_out: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ dc_out_dpi0: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&hdmi_input0>;
++ };
++ dc_out_dpi1: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&hdmi_in_lcdc>;
++ };
++
++ dc_out_dpi2: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&mipi_in>;
++ };
++ };
++};
++
++&hdmi {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&hdmi_pins>;
++ hpd-gpio = <&sysgpio 15 GPIO_ACTIVE_HIGH>;
++
++ hdmi_in: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ hdmi_in_lcdc: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi1>;
++ };
++ };
++};
++
++&rgb_output {
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ hdmi_input0:endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi0>;
++ };
++ };
++ };
++};
++
++&dsi_output {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ mipi_in: endpoint {
++ remote-endpoint = <&dc_out_dpi2>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ sf_dpi_output: endpoint {
++ remote-endpoint = <&dsi_in_port>;
++ };
++ };
++ };
++};
++
++&mipi_dsi {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ dsi0_output: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&panel_out0>;
++ };
++
++ dsi1_output: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&panel_out1>;
++ };
++
++ };
++
++ port@1{
++ reg = <1>;
++ dsi_in_port: endpoint {
++ remote-endpoint = <&sf_dpi_output>;
++ };
++ };
++
++ };
++};
++
++&mipi_dphy {
++ status = "okay";
++};
++
++&co_process {
++ memory-region = <&e24_mem>;
++ status = "okay";
++};
++
++
++&mailbox_contrl0 {
++ status = "okay";
++};
++
++&mailbox_client0 {
++ status = "okay";
++};
++
++&vpu_dec {
++ status = "okay";
++};
++
++&vpu_enc {
++ status = "okay";
++};
++
++&jpu {
++ status = "okay";
++};
++
++&gpu {
++ status = "okay";
++};
++
++&vin_sysctl {
++ /* when use dvp open this pinctrl*/
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ reg = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* CSI2 bus endpoint */
++ csi2rx0_from_imx219: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&imx219_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ lane-polarities = <0 0 0>;
++ status = "okay";
++ };
++
++ csi2rx0_from_imx708: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&imx708_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ lane-polarities = <0 0 0>;
++ status = "okay";
++ };
++
++ csi2rx0_from_ov4689: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&ov4689_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ status = "okay";
++ };
++ };
++ };
++};
diff --git a/target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch b/target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch
new file mode 100644
index 0000000000..873883101f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch
@@ -0,0 +1,71 @@
+From 17a781895079f8f9b2c089d13a1e4d9789e018c5 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Wed, 20 Mar 2024 17:36:14 +0800
+Subject: [PATCH 107/116] riscv: dts: starfive: evb-overlay: Support SPI
+ overlay
+
+Add new compatibles to support SPI overlay.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
+@@ -9,6 +9,7 @@
+ fragment@0 {
+ target-path = "/soc/spi@10060000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -17,6 +18,7 @@
+ fragment@1 {
+ target-path = "/soc/spi@10070000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -25,6 +27,7 @@
+ fragment@2 {
+ target-path = "/soc/spi@10080000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -33,6 +36,7 @@
+ fragment@3 {
+ target-path = "/soc/spi@12070000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -41,6 +45,7 @@
+ fragment@4 {
+ target-path = "/soc/spi@12080000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -49,6 +54,7 @@
+ fragment@5 {
+ target-path = "/soc/spi@12090000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -57,6 +63,7 @@
+ fragment@6 {
+ target-path = "/soc/spi@120a0000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
diff --git a/target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch b/target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch
new file mode 100644
index 0000000000..a4b2e14f9b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch
@@ -0,0 +1,23 @@
+From 49b818cdd08fca7ff761277635c0e5ab659becb8 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Thu, 21 Mar 2024 16:53:51 +0800
+Subject: [PATCH 108/116] riscv: configs: visionfive2: Add standard partition
+ for hibernation
+
+Add CONFIG_PM_STD_PARTITION="PARTLABEL=hibernation".
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/configs/starfive_visionfive2_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/riscv/configs/starfive_visionfive2_defconfig
++++ b/arch/riscv/configs/starfive_visionfive2_defconfig
+@@ -24,6 +24,7 @@ CONFIG_NONPORTABLE=y
+ CONFIG_SMP=y
+ CONFIG_HZ_100=y
+ CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION="PARTLABEL=hibernation"
+ CONFIG_PM_DEBUG=y
+ CONFIG_PM_ADVANCED_DEBUG=y
+ CONFIG_PM_TEST_SUSPEND=y
diff --git a/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch
new file mode 100644
index 0000000000..3f9499974c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch
@@ -0,0 +1,297 @@
+From 146eb94a08d12b5831e1d30455469750f7c5f2a3 Mon Sep 17 00:00:00 2001
+From: "minda.chen" <minda.chen@starfivetech.com>
+Date: Tue, 18 Oct 2022 09:57:39 +0800
+Subject: [PATCH 109/116] usb:xhci:To improve performance,usb using lowmem for
+ bulk xfer.
+
+Generate an usb low memory pool for usb 3.0 host
+read/write transfer, default size is 8M.
+
+Signed-off-by: minda.chen <minda.chen@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-evb.dts | 1 +
+ drivers/usb/core/hcd.c | 4 +-
+ drivers/usb/host/xhci-mem.c | 64 +++++++++++++++++++++
+ drivers/usb/host/xhci-plat.c | 8 +++
+ drivers/usb/host/xhci-ring.c | 3 +-
+ drivers/usb/host/xhci.c | 57 +++++++++++++++++-
+ drivers/usb/host/xhci.h | 11 ++++
+ 7 files changed, 145 insertions(+), 3 deletions(-)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-evb.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dts
+@@ -31,5 +31,6 @@
+ };
+
+ &usb0 {
++ xhci-lowmem-pool;
+ status = "okay";
+ };
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1439,7 +1439,9 @@ int usb_hcd_map_urb_for_dma(struct usb_h
+ if (ret == 0)
+ urb->transfer_flags |= URB_MAP_LOCAL;
+ } else if (hcd_uses_dma(hcd)) {
+- if (urb->num_sgs) {
++ if (urb->transfer_flags & URB_MAP_LOCAL)
++ return ret;
++ else if (urb->num_sgs) {
+ int n;
+
+ /* We don't support sg for isoc transfers ! */
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/dmapool.h>
+ #include <linux/dma-mapping.h>
++#include <linux/genalloc.h>
+
+ #include "xhci.h"
+ #include "xhci-trace.h"
+@@ -1842,6 +1843,7 @@ xhci_free_interrupter(struct xhci_hcd *x
+ void xhci_mem_cleanup(struct xhci_hcd *xhci)
+ {
+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
++ struct xhci_lowmem_pool *pool;
+ int i, j, num_ports;
+
+ cancel_delayed_work_sync(&xhci->cmd_timer);
+@@ -1887,6 +1889,13 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+ "Freed medium stream array pool");
+
++ if (xhci->lowmem_pool.pool) {
++ pool = &xhci->lowmem_pool;
++ dma_free_coherent(dev, pool->size, (void *)pool->cached_base, pool->dma_addr);
++ gen_pool_destroy(pool->pool);
++ pool->pool = NULL;
++ }
++
+ if (xhci->dcbaa)
+ dma_free_coherent(dev, sizeof(*xhci->dcbaa),
+ xhci->dcbaa, xhci->dcbaa->dma);
+@@ -2297,6 +2306,55 @@ xhci_add_interrupter(struct xhci_hcd *xh
+ return 0;
+ }
+
++int xhci_setup_local_lowmem(struct xhci_hcd *xhci, size_t size)
++{
++ int err;
++ void *buffer;
++ dma_addr_t dma_addr;
++ struct usb_hcd *hcd = xhci_to_hcd(xhci);
++ struct xhci_lowmem_pool *pool = &xhci->lowmem_pool;
++
++ if (!pool->pool) {
++ /* minimal alloc one page */
++ pool->pool = gen_pool_create(PAGE_SHIFT, dev_to_node(hcd->self.sysdev));
++ if (IS_ERR(pool->pool))
++ return PTR_ERR(pool->pool);
++ }
++
++ buffer = dma_alloc_coherent(hcd->self.sysdev, size, &dma_addr,
++ GFP_KERNEL | GFP_DMA32);
++
++ if (IS_ERR(buffer)) {
++ err = PTR_ERR(buffer);
++ goto destroy_pool;
++ }
++
++ /*
++ * Here we pass a dma_addr_t but the arg type is a phys_addr_t.
++ * It's not backed by system memory and thus there's no kernel mapping
++ * for it.
++ */
++ err = gen_pool_add_virt(pool->pool, (unsigned long)buffer,
++ dma_addr, size, dev_to_node(hcd->self.sysdev));
++ if (err < 0) {
++ dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n",
++ err);
++ dma_free_coherent(hcd->self.sysdev, size, buffer, dma_addr);
++ goto destroy_pool;
++ }
++
++ pool->cached_base = (u64)buffer;
++ pool->dma_addr = dma_addr;
++
++ return 0;
++
++destroy_pool:
++ gen_pool_destroy(pool->pool);
++ pool->pool = NULL;
++ return err;
++}
++EXPORT_SYMBOL_GPL(xhci_setup_local_lowmem);
++
+ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+ {
+ dma_addr_t dma;
+@@ -2433,6 +2491,12 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+
+ xhci->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
+
++ if (xhci->quirks & XHCI_LOCAL_BUFFER) {
++ if (xhci_setup_local_lowmem(xhci,
++ xhci->lowmem_pool.size))
++ goto fail;
++ }
++
+ /*
+ * XXX: Might need to set the Interrupter Moderation Register to
+ * something other than the default (~1ms minimum between interrupts).
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -253,6 +253,14 @@ int xhci_plat_probe(struct platform_devi
+ if (device_property_read_bool(tmpdev, "xhci-sg-trb-cache-size-quirk"))
+ xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK;
+
++ if (device_property_read_bool(tmpdev, "xhci-lowmem-pool")) {
++ xhci->quirks |= XHCI_LOCAL_BUFFER;
++ if (device_property_read_u32(tmpdev, "lowmem-pool-size",
++ &xhci->lowmem_pool.size)) {
++ xhci->lowmem_pool.size = 8 << 20;
++ } else
++ xhci->lowmem_pool.size <<= 20;
++ }
+ device_property_read_u32(tmpdev, "imod-interval-ns",
+ &xhci->imod_interval);
+ }
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3650,7 +3650,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+
+ full_len = urb->transfer_buffer_length;
+ /* If we have scatter/gather list, we use it. */
+- if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)) {
++ if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)
++ && !(urb->transfer_flags & URB_MAP_LOCAL)) {
+ num_sgs = urb->num_mapped_sgs;
+ sg = urb->sg;
+ addr = (u64) sg_dma_address(sg);
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -18,6 +18,8 @@
+ #include <linux/slab.h>
+ #include <linux/dmi.h>
+ #include <linux/dma-mapping.h>
++#include <linux/dma-map-ops.h>
++#include <linux/genalloc.h>
+
+ #include "xhci.h"
+ #include "xhci-trace.h"
+@@ -1285,6 +1287,55 @@ static void xhci_unmap_temp_buf(struct u
+ urb->transfer_buffer = NULL;
+ }
+
++static void xhci_map_urb_local(struct usb_hcd *hcd, struct urb *urb,
++ gfp_t mem_flags)
++{
++ void *buffer;
++ dma_addr_t dma_handle;
++ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++ struct xhci_lowmem_pool *lowmem_pool = &xhci->lowmem_pool;
++
++ if (lowmem_pool->pool
++ && (usb_endpoint_type(&urb->ep->desc) == USB_ENDPOINT_XFER_BULK)
++ && (urb->transfer_buffer_length > PAGE_SIZE)
++ && urb->num_sgs && urb->sg && (sg_phys(urb->sg) > 0xffffffff)) {
++ buffer = gen_pool_dma_alloc(lowmem_pool->pool,
++ urb->transfer_buffer_length, &dma_handle);
++ if (buffer) {
++ urb->transfer_dma = dma_handle;
++ urb->transfer_buffer = buffer;
++ urb->transfer_flags |= URB_MAP_LOCAL;
++ if (usb_urb_dir_out(urb))
++ sg_copy_to_buffer(urb->sg, urb->num_sgs,
++ (void *)buffer,
++ urb->transfer_buffer_length);
++ }
++ }
++
++}
++
++static void xhci_unmap_urb_local(struct usb_hcd *hcd, struct urb *urb)
++{
++ dma_addr_t dma_handle;
++ u64 cached_buffer;
++ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++ struct xhci_lowmem_pool *lowmem_pool = &xhci->lowmem_pool;
++
++ if (urb->transfer_flags & URB_MAP_LOCAL) {
++ dma_handle = urb->transfer_dma;
++ cached_buffer = lowmem_pool->cached_base +
++ ((u32)urb->transfer_dma & (lowmem_pool->size - 1));
++ if (usb_urb_dir_in(urb))
++ sg_copy_from_buffer(urb->sg, urb->num_sgs,
++ (void *)cached_buffer, urb->transfer_buffer_length);
++ gen_pool_free(lowmem_pool->pool, (unsigned long)urb->transfer_buffer,
++ urb->transfer_buffer_length);
++ urb->transfer_flags &= ~URB_MAP_LOCAL;
++ urb->transfer_buffer = NULL;
++ }
++}
++
++
+ /*
+ * Bypass the DMA mapping if URB is suitable for Immediate Transfer (IDT),
+ * we'll copy the actual data into the TRB address register. This is limited to
+@@ -1305,9 +1356,11 @@ static int xhci_map_urb_for_dma(struct u
+ if (xhci_urb_temp_buffer_required(hcd, urb))
+ return xhci_map_temp_buffer(hcd, urb);
+ }
++ xhci_map_urb_local(hcd, urb, mem_flags);
+ return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
+ }
+
++
+ static void xhci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+ {
+ struct xhci_hcd *xhci;
+@@ -1320,8 +1373,10 @@ static void xhci_unmap_urb_for_dma(struc
+
+ if ((xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) && unmap_temp_buf)
+ xhci_unmap_temp_buf(hcd, urb);
+- else
++ else {
++ xhci_unmap_urb_local(hcd, urb);
+ usb_hcd_unmap_urb_for_dma(hcd, urb);
++ }
+ }
+
+ /**
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1763,6 +1763,13 @@ struct xhci_hub {
+ u8 min_rev;
+ };
+
++struct xhci_lowmem_pool {
++ struct gen_pool *pool;
++ u64 cached_base;
++ dma_addr_t dma_addr;
++ unsigned int size;
++};
++
+ /* There is one xhci_hcd structure per controller */
+ struct xhci_hcd {
+ struct usb_hcd *main_hcd;
+@@ -1914,6 +1921,8 @@ struct xhci_hcd {
+ #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
+ #define XHCI_ZHAOXIN_HOST BIT_ULL(46)
+
++#define XHCI_LOCAL_BUFFER BIT_ULL(63)
++
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
+ struct xhci_port *hw_ports;
+@@ -1943,6 +1952,8 @@ struct xhci_hcd {
+ struct list_head regset_list;
+
+ void *dbc;
++ struct xhci_lowmem_pool lowmem_pool;
++
+ /* platform-specific data -- must come last */
+ unsigned long priv[] __aligned(sizeof(s64));
+ };
diff --git a/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch b/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch
new file mode 100644
index 0000000000..739bc76e71
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch
@@ -0,0 +1,106 @@
+From a170cb9936bb0b00d58aaea40984dbce1169fe42 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 3 Jul 2023 16:14:20 +0800
+Subject: [PATCH 110/116] usb: xhci: using dma_alloc_noncoherent to alloc low
+ memory pool
+
+For RISCV_NONCACHEHERENT is set, using dma_alloc_noncoherent
+to alloc cached large block low memory buffer. And set default
+size to 4M. (largest size of continuous memory can be supported)
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/usb/host/xhci-mem.c | 29 ++++++++++++++++-------------
+ drivers/usb/host/xhci-plat.c | 9 +++++----
+ 2 files changed, 21 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1891,7 +1891,8 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+
+ if (xhci->lowmem_pool.pool) {
+ pool = &xhci->lowmem_pool;
+- dma_free_coherent(dev, pool->size, (void *)pool->cached_base, pool->dma_addr);
++ dma_free_noncoherent(dev, pool->size, (void *)pool->cached_base,
++ pool->dma_addr, DMA_BIDIRECTIONAL);
+ gen_pool_destroy(pool->pool);
+ pool->pool = NULL;
+ }
+@@ -2317,15 +2318,15 @@ int xhci_setup_local_lowmem(struct xhci_
+ if (!pool->pool) {
+ /* minimal alloc one page */
+ pool->pool = gen_pool_create(PAGE_SHIFT, dev_to_node(hcd->self.sysdev));
+- if (IS_ERR(pool->pool))
+- return PTR_ERR(pool->pool);
++ if (!pool->pool)
++ return -ENOMEM;
+ }
+
+- buffer = dma_alloc_coherent(hcd->self.sysdev, size, &dma_addr,
+- GFP_KERNEL | GFP_DMA32);
++ buffer = dma_alloc_noncoherent(hcd->self.sysdev, size, &dma_addr,
++ DMA_BIDIRECTIONAL, GFP_ATOMIC);
+
+- if (IS_ERR(buffer)) {
+- err = PTR_ERR(buffer);
++ if (!buffer) {
++ err = -ENOMEM;
+ goto destroy_pool;
+ }
+
+@@ -2335,11 +2336,11 @@ int xhci_setup_local_lowmem(struct xhci_
+ * for it.
+ */
+ err = gen_pool_add_virt(pool->pool, (unsigned long)buffer,
+- dma_addr, size, dev_to_node(hcd->self.sysdev));
++ dma_addr, size, dev_to_node(hcd->self.sysdev));
+ if (err < 0) {
+ dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n",
+ err);
+- dma_free_coherent(hcd->self.sysdev, size, buffer, dma_addr);
++ dma_free_noncoherent(hcd->self.sysdev, size, buffer, dma_addr, DMA_BIDIRECTIONAL);
+ goto destroy_pool;
+ }
+
+@@ -2362,7 +2363,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ unsigned int val, val2;
+ u64 val_64;
+ u32 page_size, temp;
+- int i;
++ int i, ret;
+
+ INIT_LIST_HEAD(&xhci->cmd_list);
+
+@@ -2492,9 +2493,11 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ xhci->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
+
+ if (xhci->quirks & XHCI_LOCAL_BUFFER) {
+- if (xhci_setup_local_lowmem(xhci,
+- xhci->lowmem_pool.size))
+- goto fail;
++ ret = xhci_setup_local_lowmem(xhci, xhci->lowmem_pool.size);
++ if (ret) {
++ xhci->quirks &= ~XHCI_LOCAL_BUFFER;
++ xhci_warn(xhci, "WARN: Can't alloc lowmem pool\n");
++ }
+ }
+
+ /*
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -255,10 +255,11 @@ int xhci_plat_probe(struct platform_devi
+
+ if (device_property_read_bool(tmpdev, "xhci-lowmem-pool")) {
+ xhci->quirks |= XHCI_LOCAL_BUFFER;
+- if (device_property_read_u32(tmpdev, "lowmem-pool-size",
+- &xhci->lowmem_pool.size)) {
+- xhci->lowmem_pool.size = 8 << 20;
+- } else
++ ret = device_property_read_u32(tmpdev, "lowmem-pool-size",
++ &xhci->lowmem_pool.size);
++ if (ret || xhci->lowmem_pool.size >= 4)
++ xhci->lowmem_pool.size = 4 << 20;
++ else
+ xhci->lowmem_pool.size <<= 20;
+ }
+ device_property_read_u32(tmpdev, "imod-interval-ns",
diff --git a/target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch b/target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch
new file mode 100644
index 0000000000..451b1c16fd
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch
@@ -0,0 +1,139 @@
+From fc86405992c37b1898fd9b9bc077be673d774269 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 22 Mar 2024 09:54:28 +0800
+Subject: [PATCH 111/116] riscv: dts: starfive: Add vf2-overlay dtso subdir
+
+Create subdir vf2-overlay/ and add overlay .dtso for VF2 board.
+The code is ported from tag JH7110_VF2_6.1_v5.11.4
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 1 +
+ .../boot/dts/starfive/vf2-overlay/Makefile | 3 +
+ .../starfive/vf2-overlay/vf2-overlay-can.dtso | 23 ++++++
+ .../vf2-overlay/vf2-overlay-uart3-i2c.dtso | 75 +++++++++++++++++++
+ 4 files changed, 102 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/starfive/vf2-overlay/Makefile
+ create mode 100644 arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-can.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-uart3-i2c.dtso
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -9,6 +9,7 @@ DTC_FLAGS_jh7110-evb := -@
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
++subdir-y += vf2-overlay
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb \
+ jh7110-starfive-visionfive-2-ac108.dtb \
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/vf2-overlay/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++dtb-$(CONFIG_ARCH_STARFIVE) += vf2-overlay-uart3-i2c.dtbo \
++ vf2-overlay-can.dtbo
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-can.dtso
+@@ -0,0 +1,23 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //can0
++ fragment@0 {
++ target-path = "/soc/can@130d0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //can1
++ fragment@1 {
++ target-path = "/soc/can@130e0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-uart3-i2c.dtso
+@@ -0,0 +1,75 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_uart3_pins: dt-uart3-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(60, GPOUT_SYS_UART3_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART3_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
++ dt_i2c1_pins: dt-i2c1-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(42, GPOUT_LOW,
++ GPOEN_SYS_I2C1_CLK,
++ GPI_SYS_I2C1_CLK)>,
++ <GPIOMUX(43, GPOUT_LOW,
++ GPOEN_SYS_I2C1_DATA,
++ GPI_SYS_I2C1_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++ };
++ };
++
++ //uart3
++ fragment@1 {
++ target-path = "/soc/serial@12000000";
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_uart3_pins>;
++ status = "okay";
++ };
++ };
++
++ //i2c1
++ fragment@2 {
++ target-path = "/soc/i2c@10040000";
++ __overlay__ {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_i2c1_pins>;
++ status = "okay";
++ };
++ };
++};
diff --git a/target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch b/target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch
new file mode 100644
index 0000000000..17dcf726ef
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch
@@ -0,0 +1,34 @@
+From 2b098da69f9497e725683caf67fbecf79202b7fc Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 22 Mar 2024 11:33:40 +0800
+Subject: [PATCH 112/116] riscv: dts: starfive: visionfive 2: Add aliases for
+ i2c* and uart3
+
+Fix the numbers of i2c and uart3.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -15,7 +15,10 @@
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ i2c0 = &i2c0;
++ i2c1 = &i2c1;
+ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ mmc0 = &mmc0;
+@@ -23,6 +26,7 @@
+ pcie0 = &pcie0;
+ pcie1 = &pcie1;
+ serial0 = &uart0;
++ serial3 = &uart3;
+ };
+
+ chosen {
diff --git a/target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch b/target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch
new file mode 100644
index 0000000000..3651976081
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch
@@ -0,0 +1,6063 @@
+From 18b70b6f5192ee5363515b57e1f213d0698224ed Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfive.com>
+Date: Tue, 28 Nov 2023 15:37:14 +0800
+Subject: [PATCH 113/116] driver: bluetooth: add aic8800 driver support
+
+add aic8800 driver that can support sco profile
+
+Signed-off-by: ziv.xu <ziv.xu@starfive.com>
+---
+ .../configs/starfive_visionfive2_defconfig | 3 +-
+ drivers/bluetooth/Kconfig | 4 +
+ drivers/bluetooth/Makefile | 1 +
+ drivers/bluetooth/aic_btusb/Makefile | 80 +
+ drivers/bluetooth/aic_btusb/aic_btusb.c | 5031 +++++++++++++++++
+ drivers/bluetooth/aic_btusb/aic_btusb.h | 753 +++
+ .../aic_btusb/aic_btusb_external_featrue.c | 126 +
+ .../aic_btusb/aic_btusb_external_featrue.h | 3 +
+ 8 files changed, 5999 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/bluetooth/aic_btusb/Makefile
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb.c
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb.h
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.c
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.h
+
+--- a/arch/riscv/configs/starfive_visionfive2_defconfig
++++ b/arch/riscv/configs/starfive_visionfive2_defconfig
+@@ -87,8 +87,7 @@ CONFIG_BT_RFCOMM_TTY=y
+ CONFIG_BT_BNEP=y
+ CONFIG_BT_BNEP_MC_FILTER=y
+ CONFIG_BT_BNEP_PROTO_FILTER=y
+-CONFIG_BT_HCIBTUSB=m
+-# CONFIG_BT_HCIBTUSB_BCM is not set
++CONFIG_BT_AICUSB=y
+ CONFIG_CFG80211=y
+ CONFIG_MAC80211=y
+ CONFIG_RFKILL=y
+--- a/drivers/bluetooth/Kconfig
++++ b/drivers/bluetooth/Kconfig
+@@ -478,5 +478,9 @@ config BT_NXPUART
+ Say Y here to compile support for NXP Bluetooth UART device into
+ the kernel, or say M here to compile as a module (btnxpuart).
+
++config BT_AICUSB
++ tristate "AIC8800 btusb driver"
++ help
++ AIC8800 usb dongle bluetooth support driver
+
+ endmenu
+--- a/drivers/bluetooth/Makefile
++++ b/drivers/bluetooth/Makefile
+@@ -51,3 +51,4 @@ hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci
+ hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o
+ hci_uart-$(CONFIG_BT_HCIUART_MRVL) += hci_mrvl.o
+ hci_uart-objs := $(hci_uart-y)
++obj-$(CONFIG_BT_AICUSB) += aic_btusb/
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/Makefile
+@@ -0,0 +1,80 @@
++MODULE_NAME = aic_btusb
++
++CONFIG_AIC8800_BTUSB_SUPPORT = m
++CONFIG_SUPPORT_VENDOR_APCF = n
++# Need to set fw path in BOARD_KERNEL_CMDLINE
++CONFIG_USE_FW_REQUEST = n
++
++ifeq ($(CONFIG_SUPPORT_VENDOR_APCF), y)
++obj-$(CONFIG_AIC8800_BTUSB_SUPPORT) := $(MODULE_NAME).o aic_btusb_external_featrue.o
++else
++obj-$(CONFIG_AIC8800_BTUSB_SUPPORT) := $(MODULE_NAME).o
++endif
++
++ccflags-$(CONFIG_SUPPORT_VENDOR_APCF) += -DCONFIG_SUPPORT_VENDOR_APCF
++#$(MODULE_NAME)-y := aic_btusb_ioctl.o\
++# aic_btusb.o \
++
++ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST
++
++
++# Platform support list
++CONFIG_PLATFORM_ROCKCHIP ?= n
++CONFIG_PLATFORM_ALLWINNER ?= n
++CONFIG_PLATFORM_AMLOGIC ?= n
++CONFIG_PLATFORM_UBUNTU ?= y
++CONFIG_PLATFORM_ING ?= n
++
++ifeq ($(CONFIG_PLATFORM_ING), y)
++ARCH := mips
++KDIR ?= /home/yaya/E/Ingenic/T31/Ingenic-SDK-T31-1.1.5-20220428/opensource/kernel
++CROSS_COMPILE := /home/yaya/E/Ingenic/T31/Ingenic-SDK-T31-1.1.5-20220428/resource/toolchain/gcc_472/mips-gcc472-glibc216-32bit/bin/mips-linux-gnu-
++endif
++
++ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
++ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
++#KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
++#ARCH ?= arm
++#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
++#KDIR := /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/kernel
++#ARCH ?= arm
++#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
++ARCH := arm64
++KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
++CROSS_COMPILE := /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
++
++endif
++
++ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
++ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
++KDIR := /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9
++ARCH ?= arm64
++CROSS_COMPILE ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
++endif
++
++ifeq ($(CONFIG_PLATFORM_AMLOGIC), y)
++ ccflags-$(CONFIG_PLATFORM_AMLOGIC) += -DCONFIG_PLATFORM_AMLOGIC
++endif
++
++ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
++ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
++endif
++
++all: modules
++modules:
++ make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
++
++install:
++ mkdir -p $(MODDESTDIR)
++ install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR)/
++ /sbin/depmod -a ${KVER}
++ echo $(MODULE_NAME) >> /etc/modules-load.d/aic_bt.conf
++
++uninstall:
++ rm -rfv $(MODDESTDIR)/$(MODULE_NAME).ko
++ /sbin/depmod -a ${KVER}
++ rm -f /etc/modules-load.d/aic_bt.conf
++
++clean:
++ rm -rf *.o *.ko *.o.* *.mod.* modules.* Module.* .a* .o* .*.o.* *.mod .tmp* .cache.mk .Module.symvers.cmd .modules.order.cmd
++
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb.c
+@@ -0,0 +1,5031 @@
++/*
++ *
++ * AicSemi Bluetooth USB driver
++ *
++ *
++ *
++ * 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
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/skbuff.h>
++#include <linux/usb.h>
++
++#include <linux/ioctl.h>
++#include <linux/io.h>
++#include <linux/firmware.h>
++#include <linux/vmalloc.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/reboot.h>
++
++#include "aic_btusb.h"
++
++#ifdef CONFIG_USE_FW_REQUEST
++#include <linux/firmware.h>
++#endif
++
++#define AICBT_RELEASE_NAME "202012_ANDROID"
++#define VERSION "2.1.0"
++
++#define SUSPNED_DW_FW 0
++
++
++static spinlock_t queue_lock;
++static spinlock_t dlfw_lock;
++static volatile uint16_t dlfw_dis_state = 0;
++
++/* USB Device ID */
++#define USB_VENDOR_ID_AIC 0xA69C
++#define USB_PRODUCT_ID_AIC8801 0x8801
++#define USB_PRODUCT_ID_AIC8800DC 0x88dc
++#define USB_PRODUCT_ID_AIC8800D80 0x8d81
++
++enum AICWF_IC{
++ PRODUCT_ID_AIC8801 = 0,
++ PRODUCT_ID_AIC8800DC,
++ PRODUCT_ID_AIC8800DW,
++ PRODUCT_ID_AIC8800D80
++};
++
++u16 g_chipid = PRODUCT_ID_AIC8801;
++u8 chip_id = 0;
++u8 sub_chip_id = 0;
++
++struct btusb_data {
++ struct hci_dev *hdev;
++ struct usb_device *udev;
++ struct usb_interface *intf;
++ struct usb_interface *isoc;
++
++ spinlock_t lock;
++
++ unsigned long flags;
++
++ struct work_struct work;
++ struct work_struct waker;
++
++ struct usb_anchor tx_anchor;
++ struct usb_anchor intr_anchor;
++ struct usb_anchor bulk_anchor;
++ struct usb_anchor isoc_anchor;
++ struct usb_anchor deferred;
++ int tx_in_flight;
++ spinlock_t txlock;
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++ spinlock_t rxlock;
++ struct sk_buff *evt_skb;
++ struct sk_buff *acl_skb;
++ struct sk_buff *sco_skb;
++#endif
++#endif
++
++ struct usb_endpoint_descriptor *intr_ep;
++ struct usb_endpoint_descriptor *bulk_tx_ep;
++ struct usb_endpoint_descriptor *bulk_rx_ep;
++ struct usb_endpoint_descriptor *isoc_tx_ep;
++ struct usb_endpoint_descriptor *isoc_rx_ep;
++
++ __u8 cmdreq_type;
++
++ unsigned int sco_num;
++ int isoc_altsetting;
++ int suspend_count;
++ uint16_t sco_handle;
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++ int (*recv_bulk) (struct btusb_data * data, void *buffer, int count);
++#endif
++#endif
++
++//#ifdef CONFIG_HAS_EARLYSUSPEND
++#if 0
++ struct early_suspend early_suspend;
++#else
++ struct notifier_block pm_notifier;
++ struct notifier_block reboot_notifier;
++#endif
++ firmware_info *fw_info;
++
++#ifdef CONFIG_SCO_OVER_HCI
++ AIC_sco_card_t *pSCOSnd;
++#endif
++};
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 1)
++static bool reset_on_close = 0;
++#endif
++
++#ifdef CONFIG_SCO_OVER_HCI
++struct snd_sco_cap_timer {
++ struct timer_list cap_timer;
++ struct timer_list play_timer;
++ struct btusb_data snd_usb_data;
++ int snd_sco_length;
++};
++static struct snd_sco_cap_timer snd_cap_timer;
++#endif
++
++
++int bt_support = 0;
++module_param(bt_support, int, 0660);
++
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++int vendor_apcf_sent_done = 0;
++#endif
++
++static inline int check_set_dlfw_state_value(uint16_t change_value)
++{
++ spin_lock(&dlfw_lock);
++ if(!dlfw_dis_state) {
++ dlfw_dis_state = change_value;
++ }
++ spin_unlock(&dlfw_lock);
++ return dlfw_dis_state;
++}
++
++static inline void set_dlfw_state_value(uint16_t change_value)
++{
++ spin_lock(&dlfw_lock);
++ dlfw_dis_state = change_value;
++ spin_unlock(&dlfw_lock);
++}
++
++
++
++
++static void aic_free( struct btusb_data *data)
++{
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 1)
++ kfree(data);
++#endif
++ return;
++}
++
++static struct btusb_data *aic_alloc(struct usb_interface *intf)
++{
++ struct btusb_data *data;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 1)
++ data = kzalloc(sizeof(*data), GFP_KERNEL);
++#else
++ data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
++#endif
++ return data;
++}
++
++static void print_acl(struct sk_buff *skb, int direction)
++{
++#if PRINT_ACL_DATA
++ //uint wlength = skb->len;
++ u16 *handle = (u16 *)(skb->data);
++ u16 len = *(handle+1);
++ //u8 *acl_data = (u8 *)(skb->data);
++
++ AICBT_INFO("aic %s: direction %d, handle %04x, len %d",
++ __func__, direction, *handle, len);
++#endif
++}
++
++static void print_sco(struct sk_buff *skb, int direction)
++{
++#if PRINT_SCO_DATA
++ uint wlength = skb->len;
++ u16 *handle = (u16 *)(skb->data);
++ u8 len = *(u8 *)(handle+1);
++ //u8 *sco_data =(u8 *)(skb->data);
++
++ AICBT_INFO("aic %s: direction %d, handle %04x, len %d,wlength %d",
++ __func__, direction, *handle, len,wlength);
++#endif
++}
++
++static void print_error_command(struct sk_buff *skb)
++{
++ u16 *opcode = (u16*)(skb->data);
++ u8 *cmd_data = (u8*)(skb->data);
++ u8 len = *(cmd_data+2);
++
++ printk(" 0x%04x,len:%d,", *opcode, len);
++#if CONFIG_BLUEDROID
++ switch (*opcode) {
++ case HCI_OP_INQUIRY:
++ printk("HCI_OP_INQUIRY");
++ break;
++ case HCI_OP_INQUIRY_CANCEL:
++ printk("HCI_OP_INQUIRY_CANCEL");
++ break;
++ case HCI_OP_EXIT_PERIODIC_INQ:
++ printk("HCI_OP_EXIT_PERIODIC_INQ");
++ break;
++ case HCI_OP_CREATE_CONN:
++ printk("HCI_OP_CREATE_CONN");
++ break;
++ case HCI_OP_DISCONNECT:
++ printk("HCI_OP_DISCONNECT");
++ break;
++ case HCI_OP_CREATE_CONN_CANCEL:
++ printk("HCI_OP_CREATE_CONN_CANCEL");
++ break;
++ case HCI_OP_ACCEPT_CONN_REQ:
++ printk("HCI_OP_ACCEPT_CONN_REQ");
++ break;
++ case HCI_OP_REJECT_CONN_REQ:
++ printk("HCI_OP_REJECT_CONN_REQ");
++ break;
++ case HCI_OP_AUTH_REQUESTED:
++ printk("HCI_OP_AUTH_REQUESTED");
++ break;
++ case HCI_OP_SET_CONN_ENCRYPT:
++ printk("HCI_OP_SET_CONN_ENCRYPT");
++ break;
++ case HCI_OP_REMOTE_NAME_REQ:
++ printk("HCI_OP_REMOTE_NAME_REQ");
++ break;
++ case HCI_OP_READ_REMOTE_FEATURES:
++ printk("HCI_OP_READ_REMOTE_FEATURES");
++ break;
++ case HCI_OP_SNIFF_MODE:
++ printk("HCI_OP_SNIFF_MODE");
++ break;
++ case HCI_OP_EXIT_SNIFF_MODE:
++ printk("HCI_OP_EXIT_SNIFF_MODE");
++ break;
++ case HCI_OP_SWITCH_ROLE:
++ printk("HCI_OP_SWITCH_ROLE");
++ break;
++ case HCI_OP_SNIFF_SUBRATE:
++ printk("HCI_OP_SNIFF_SUBRATE");
++ break;
++ case HCI_OP_RESET:
++ printk("HCI_OP_RESET");
++ break;
++ case HCI_OP_Write_Extended_Inquiry_Response:
++ printk("HCI_Write_Extended_Inquiry_Response");
++ break;
++ case HCI_OP_Write_Simple_Pairing_Mode:
++ printk("HCI_OP_Write_Simple_Pairing_Mode");
++ break;
++ case HCI_OP_Read_Buffer_Size:
++ printk("HCI_OP_Read_Buffer_Size");
++ break;
++ case HCI_OP_Host_Buffer_Size:
++ printk("HCI_OP_Host_Buffer_Size");
++ break;
++ case HCI_OP_Read_Local_Version_Information:
++ printk("HCI_OP_Read_Local_Version_Information");
++ break;
++ case HCI_OP_Read_BD_ADDR:
++ printk("HCI_OP_Read_BD_ADDR");
++ break;
++ case HCI_OP_Read_Local_Supported_Commands:
++ printk("HCI_OP_Read_Local_Supported_Commands");
++ break;
++ case HCI_OP_Write_Scan_Enable:
++ printk("HCI_OP_Write_Scan_Enable");
++ break;
++ case HCI_OP_Write_Current_IAC_LAP:
++ printk("HCI_OP_Write_Current_IAC_LAP");
++ break;
++ case HCI_OP_Write_Inquiry_Scan_Activity:
++ printk("HCI_OP_Write_Inquiry_Scan_Activity");
++ break;
++ case HCI_OP_Write_Class_of_Device:
++ printk("HCI_OP_Write_Class_of_Device");
++ break;
++ case HCI_OP_LE_Rand:
++ printk("HCI_OP_LE_Rand");
++ break;
++ case HCI_OP_LE_Set_Random_Address:
++ printk("HCI_OP_LE_Set_Random_Address");
++ break;
++ case HCI_OP_LE_Set_Extended_Scan_Enable:
++ printk("HCI_OP_LE_Set_Extended_Scan_Enable");
++ break;
++ case HCI_OP_LE_Set_Extended_Scan_Parameters:
++ printk("HCI_OP_LE_Set_Extended_Scan_Parameters");
++ break;
++ case HCI_OP_Set_Event_Filter:
++ printk("HCI_OP_Set_Event_Filter");
++ break;
++ case HCI_OP_Write_Voice_Setting:
++ printk("HCI_OP_Write_Voice_Setting");
++ break;
++ case HCI_OP_Change_Local_Name:
++ printk("HCI_OP_Change_Local_Name");
++ break;
++ case HCI_OP_Read_Local_Name:
++ printk("HCI_OP_Read_Local_Name");
++ break;
++ case HCI_OP_Wirte_Page_Timeout:
++ printk("HCI_OP_Wirte_Page_Timeout");
++ break;
++ case HCI_OP_LE_Clear_Resolving_List:
++ printk("HCI_OP_LE_Clear_Resolving_List");
++ break;
++ case HCI_OP_LE_Set_Addres_Resolution_Enable_Command:
++ printk("HCI_OP_LE_Set_Addres_Resolution_Enable_Command");
++ break;
++ case HCI_OP_Write_Inquiry_mode:
++ printk("HCI_OP_Write_Inquiry_mode");
++ break;
++ case HCI_OP_Write_Page_Scan_Type:
++ printk("HCI_OP_Write_Page_Scan_Type");
++ break;
++ case HCI_OP_Write_Inquiry_Scan_Type:
++ printk("HCI_OP_Write_Inquiry_Scan_Type");
++ break;
++ case HCI_OP_Delete_Stored_Link_Key:
++ printk("HCI_OP_Delete_Stored_Link_Key");
++ break;
++ case HCI_OP_LE_Read_Local_Resolvable_Address:
++ printk("HCI_OP_LE_Read_Local_Resolvable_Address");
++ break;
++ case HCI_OP_LE_Extended_Create_Connection:
++ printk("HCI_OP_LE_Extended_Create_Connection");
++ break;
++ case HCI_OP_Read_Remote_Version_Information:
++ printk("HCI_OP_Read_Remote_Version_Information");
++ break;
++ case HCI_OP_LE_Start_Encryption:
++ printk("HCI_OP_LE_Start_Encryption");
++ break;
++ case HCI_OP_LE_Add_Device_to_Resolving_List:
++ printk("HCI_OP_LE_Add_Device_to_Resolving_List");
++ break;
++ case HCI_OP_LE_Set_Privacy_Mode:
++ printk("HCI_OP_LE_Set_Privacy_Mode");
++ break;
++ case HCI_OP_LE_Connection_Update:
++ printk("HCI_OP_LE_Connection_Update");
++ break;
++ default:
++ printk("UNKNOW_HCI_COMMAND");
++ break;
++ }
++#endif //CONFIG_BLUEDROID
++}
++
++static void print_command(struct sk_buff *skb)
++{
++#if PRINT_CMD_EVENT
++ print_error_command(skb);
++#endif
++}
++
++
++enum CODEC_TYPE{
++ CODEC_CVSD,
++ CODEC_MSBC,
++};
++
++static enum CODEC_TYPE codec_type = CODEC_CVSD;
++static void set_select_msbc(enum CODEC_TYPE type);
++static enum CODEC_TYPE check_select_msbc(void);
++
++
++#if CONFIG_BLUEDROID
++
++/* Global parameters for bt usb char driver */
++#define BT_CHAR_DEVICE_NAME "aicbt_dev"
++struct mutex btchr_mutex;
++static struct sk_buff_head btchr_readq;
++static wait_queue_head_t btchr_read_wait;
++static wait_queue_head_t bt_dlfw_wait;
++static int bt_char_dev_registered;
++static dev_t bt_devid; /* bt char device number */
++static struct cdev bt_char_dev; /* bt character device structure */
++static struct class *bt_char_class; /* device class for usb char driver */
++static int bt_reset = 0;
++
++/* HCI device & lock */
++DEFINE_RWLOCK(hci_dev_lock);
++struct hci_dev *ghdev = NULL;
++
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++static int bypass_event(struct sk_buff *skb)
++{
++ int ret = 0;
++ u8 *opcode = (u8*)(skb->data);
++ //u8 len = *(opcode+1);
++ u16 sub_opcpde;
++
++ switch(*opcode) {
++ case HCI_EV_CMD_COMPLETE:
++ sub_opcpde = ((u16)opcode[3]|(u16)(opcode[4])<<8);
++ if(sub_opcpde == 0xfd57){
++ if(vendor_apcf_sent_done){
++ vendor_apcf_sent_done--;
++ printk("apcf bypass\r\n");
++ ret = 1;
++ }
++ }
++ break;
++ default:
++ break;
++ }
++ return ret;
++}
++#endif//CONFIG_SUPPORT_VENDOR_APCF
++static void print_event(struct sk_buff *skb)
++{
++#if PRINT_CMD_EVENT
++ //uint wlength = skb->len;
++ //uint icount = 0;
++ u8 *opcode = (u8*)(skb->data);
++ //u8 len = *(opcode+1);
++
++ printk("aic %s ", __func__);
++ switch (*opcode) {
++ case HCI_EV_INQUIRY_COMPLETE:
++ printk("HCI_EV_INQUIRY_COMPLETE");
++ break;
++ case HCI_EV_INQUIRY_RESULT:
++ printk("HCI_EV_INQUIRY_RESULT");
++ break;
++ case HCI_EV_CONN_COMPLETE:
++ printk("HCI_EV_CONN_COMPLETE");
++ break;
++ case HCI_EV_CONN_REQUEST:
++ printk("HCI_EV_CONN_REQUEST");
++ break;
++ case HCI_EV_DISCONN_COMPLETE:
++ printk("HCI_EV_DISCONN_COMPLETE");
++ break;
++ case HCI_EV_AUTH_COMPLETE:
++ printk("HCI_EV_AUTH_COMPLETE");
++ break;
++ case HCI_EV_REMOTE_NAME:
++ printk("HCI_EV_REMOTE_NAME");
++ break;
++ case HCI_EV_ENCRYPT_CHANGE:
++ printk("HCI_EV_ENCRYPT_CHANGE");
++ break;
++ case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
++ printk("HCI_EV_CHANGE_LINK_KEY_COMPLETE");
++ break;
++ case HCI_EV_REMOTE_FEATURES:
++ printk("HCI_EV_REMOTE_FEATURES");
++ break;
++ case HCI_EV_REMOTE_VERSION:
++ printk("HCI_EV_REMOTE_VERSION");
++ break;
++ case HCI_EV_QOS_SETUP_COMPLETE:
++ printk("HCI_EV_QOS_SETUP_COMPLETE");
++ break;
++ case HCI_EV_CMD_COMPLETE:
++ printk("HCI_EV_CMD_COMPLETE");
++ break;
++ case HCI_EV_CMD_STATUS:
++ printk("HCI_EV_CMD_STATUS");
++ break;
++ case HCI_EV_ROLE_CHANGE:
++ printk("HCI_EV_ROLE_CHANGE");
++ break;
++ case HCI_EV_NUM_COMP_PKTS:
++ printk("HCI_EV_NUM_COMP_PKTS");
++ break;
++ case HCI_EV_MODE_CHANGE:
++ printk("HCI_EV_MODE_CHANGE");
++ break;
++ case HCI_EV_PIN_CODE_REQ:
++ printk("HCI_EV_PIN_CODE_REQ");
++ break;
++ case HCI_EV_LINK_KEY_REQ:
++ printk("HCI_EV_LINK_KEY_REQ");
++ break;
++ case HCI_EV_LINK_KEY_NOTIFY:
++ printk("HCI_EV_LINK_KEY_NOTIFY");
++ break;
++ case HCI_EV_CLOCK_OFFSET:
++ printk("HCI_EV_CLOCK_OFFSET");
++ break;
++ case HCI_EV_PKT_TYPE_CHANGE:
++ printk("HCI_EV_PKT_TYPE_CHANGE");
++ break;
++ case HCI_EV_PSCAN_REP_MODE:
++ printk("HCI_EV_PSCAN_REP_MODE");
++ break;
++ case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
++ printk("HCI_EV_INQUIRY_RESULT_WITH_RSSI");
++ break;
++ case HCI_EV_REMOTE_EXT_FEATURES:
++ printk("HCI_EV_REMOTE_EXT_FEATURES");
++ break;
++ case HCI_EV_SYNC_CONN_COMPLETE:
++ printk("HCI_EV_SYNC_CONN_COMPLETE");
++ break;
++ case HCI_EV_SYNC_CONN_CHANGED:
++ printk("HCI_EV_SYNC_CONN_CHANGED");
++ break;
++ case HCI_EV_SNIFF_SUBRATE:
++ printk("HCI_EV_SNIFF_SUBRATE");
++ break;
++ case HCI_EV_EXTENDED_INQUIRY_RESULT:
++ printk("HCI_EV_EXTENDED_INQUIRY_RESULT");
++ break;
++ case HCI_EV_IO_CAPA_REQUEST:
++ printk("HCI_EV_IO_CAPA_REQUEST");
++ break;
++ case HCI_EV_SIMPLE_PAIR_COMPLETE:
++ printk("HCI_EV_SIMPLE_PAIR_COMPLETE");
++ break;
++ case HCI_EV_REMOTE_HOST_FEATURES:
++ printk("HCI_EV_REMOTE_HOST_FEATURES");
++ break;
++ default:
++ printk("unknow event");
++ break;
++ }
++ printk("\n");
++#if 0
++ printk("%02x,len:%d,", *opcode,len);
++ for (icount = 2; (icount < wlength) && (icount < 24); icount++)
++ printk("%02x ", *(opcode+icount));
++ printk("\n");
++#endif
++#endif
++}
++
++static inline ssize_t usb_put_user(struct sk_buff *skb,
++ char __user *buf, int count)
++{
++ char __user *ptr = buf;
++ int len = min_t(unsigned int, skb->len, count);
++
++ if (copy_to_user(ptr, skb->data, len))
++ return -EFAULT;
++
++ return len;
++}
++
++static struct sk_buff *aic_skb_queue[QUEUE_SIZE];
++static int aic_skb_queue_front = 0;
++static int aic_skb_queue_rear = 0;
++
++static void aic_enqueue(struct sk_buff *skb)
++{
++ spin_lock(&queue_lock);
++ if (aic_skb_queue_front == (aic_skb_queue_rear + 1) % QUEUE_SIZE) {
++ /*
++ * If queue is full, current solution is to drop
++ * the following entries.
++ */
++ AICBT_WARN("%s: Queue is full, entry will be dropped", __func__);
++ } else {
++ aic_skb_queue[aic_skb_queue_rear] = skb;
++
++ aic_skb_queue_rear++;
++ aic_skb_queue_rear %= QUEUE_SIZE;
++
++ }
++ spin_unlock(&queue_lock);
++}
++
++static struct sk_buff *aic_dequeue_try(unsigned int deq_len)
++{
++ struct sk_buff *skb;
++ struct sk_buff *skb_copy;
++
++ if (aic_skb_queue_front == aic_skb_queue_rear) {
++ AICBT_WARN("%s: Queue is empty", __func__);
++ return NULL;
++ }
++
++ skb = aic_skb_queue[aic_skb_queue_front];
++ if (deq_len >= skb->len) {
++
++ aic_skb_queue_front++;
++ aic_skb_queue_front %= QUEUE_SIZE;
++
++ /*
++ * Return skb addr to be dequeued, and the caller
++ * should free the skb eventually.
++ */
++ return skb;
++ } else {
++ skb_copy = pskb_copy(skb, GFP_ATOMIC);
++ skb_pull(skb, deq_len);
++ /* Return its copy to be freed */
++ return skb_copy;
++ }
++}
++
++static inline int is_queue_empty(void)
++{
++ return (aic_skb_queue_front == aic_skb_queue_rear) ? 1 : 0;
++}
++
++static void aic_clear_queue(void)
++{
++ struct sk_buff *skb;
++ spin_lock(&queue_lock);
++ while(!is_queue_empty()) {
++ skb = aic_skb_queue[aic_skb_queue_front];
++ aic_skb_queue[aic_skb_queue_front] = NULL;
++ aic_skb_queue_front++;
++ aic_skb_queue_front %= QUEUE_SIZE;
++ if (skb) {
++ kfree_skb(skb);
++ }
++ }
++ spin_unlock(&queue_lock);
++}
++
++/*
++ * AicSemi - Integrate from hci_core.c
++ */
++
++/* Get HCI device by index.
++ * Device is held on return. */
++static struct hci_dev *hci_dev_get(int index)
++{
++ if (index != 0)
++ return NULL;
++
++ return ghdev;
++}
++
++/* ---- HCI ioctl helpers ---- */
++static int hci_dev_open(__u16 dev)
++{
++ struct hci_dev *hdev;
++ int ret = 0;
++
++ AICBT_DBG("%s: dev %d", __func__, dev);
++
++ hdev = hci_dev_get(dev);
++ if (!hdev) {
++ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__);
++ return -ENODEV;
++ }
++
++ if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
++ ret = -ENODEV;
++ goto done;
++ }
++
++ if (test_bit(HCI_UP, &hdev->flags)) {
++ ret = -EALREADY;
++ goto done;
++ }
++
++done:
++ return ret;
++}
++
++static int hci_dev_do_close(struct hci_dev *hdev)
++{
++ if (hdev->flush)
++ hdev->flush(hdev);
++ /* After this point our queues are empty
++ * and no tasks are scheduled. */
++ hdev->close(hdev);
++ /* Clear flags */
++ hdev->flags = 0;
++ return 0;
++}
++
++static int hci_dev_close(__u16 dev)
++{
++ struct hci_dev *hdev;
++ int err;
++ hdev = hci_dev_get(dev);
++ if (!hdev) {
++ AICBT_ERR("%s: failed to get hci dev[Null]", __func__);
++ return -ENODEV;
++ }
++
++ err = hci_dev_do_close(hdev);
++
++ return err;
++}
++
++#ifdef CONFIG_SCO_OVER_HCI
++/* copy data from the URB buffer into the ALSA ring buffer */
++static bool aic_copy_capture_data_to_alsa(struct btusb_data *data, uint8_t* p_data, unsigned int frames)
++{
++ struct snd_pcm_runtime *runtime;
++ unsigned int frame_bytes, frames1;
++ u8 *dest;
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++
++ runtime = pSCOSnd->capture.substream->runtime;
++ frame_bytes = 2;
++
++ dest = runtime->dma_area + pSCOSnd->capture.buffer_pos * frame_bytes;
++ if (pSCOSnd->capture.buffer_pos + frames <= runtime->buffer_size) {
++ memcpy(dest, p_data, frames * frame_bytes);
++ } else {
++ /* wrap around at end of ring buffer */
++ frames1 = runtime->buffer_size - pSCOSnd->capture.buffer_pos;
++ memcpy(dest, p_data, frames1 * frame_bytes);
++ memcpy(runtime->dma_area,
++ p_data + frames1 * frame_bytes,
++ (frames - frames1) * frame_bytes);
++ }
++
++ pSCOSnd->capture.buffer_pos += frames;
++ if (pSCOSnd->capture.buffer_pos >= runtime->buffer_size) {
++ pSCOSnd->capture.buffer_pos -= runtime->buffer_size;
++ }
++
++ if((pSCOSnd->capture.buffer_pos%runtime->period_size) == 0) {
++ snd_pcm_period_elapsed(pSCOSnd->capture.substream);
++ }
++
++ return false;
++}
++
++
++static void hci_send_to_alsa_ringbuffer(struct hci_dev *hdev, struct sk_buff *skb)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++ uint8_t* p_data;
++ int sco_length = skb->len - HCI_SCO_HDR_SIZE;
++ u16 *handle = (u16 *) (skb->data);
++ //u8 errflg = (u8)((*handle & 0x3000) >> 12);
++
++ pSCOSnd->usb_data->sco_handle = (*handle & 0x0fff);
++
++ AICBT_DBG("%s, %x, %x %x\n", __func__,pSCOSnd->usb_data->sco_handle, *handle, errflg);
++
++ if (!hdev) {
++ AICBT_INFO("%s: Frame for unknown HCI device", __func__);
++ return;
++ }
++
++ if (!test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) {
++ AICBT_INFO("%s: ALSA is not running", __func__);
++ return;
++ }
++ snd_cap_timer.snd_sco_length = sco_length;
++ p_data = (uint8_t *)skb->data + HCI_SCO_HDR_SIZE;
++ aic_copy_capture_data_to_alsa(data, p_data, sco_length/2);
++}
++
++#endif
++
++#if CONFIG_BLUEDROID
++static struct hci_dev *hci_alloc_dev(void)
++{
++ struct hci_dev *hdev;
++
++ hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
++ if (!hdev)
++ return NULL;
++
++ return hdev;
++}
++
++/* Free HCI device */
++static void hci_free_dev(struct hci_dev *hdev)
++{
++ kfree(hdev);
++}
++
++/* Register HCI device */
++static int hci_register_dev(struct hci_dev *hdev)
++{
++ int i, id;
++
++ AICBT_DBG("%s: %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus);
++ /* Do not allow HCI_AMP devices to register at index 0,
++ * so the index can be used as the AMP controller ID.
++ */
++ id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
++
++ write_lock(&hci_dev_lock);
++
++ sprintf(hdev->name, "hci%d", id);
++ hdev->id = id;
++ hdev->flags = 0;
++ hdev->dev_flags = 0;
++ mutex_init(&hdev->lock);
++
++ AICBT_DBG("%s: id %d, name %s", __func__, hdev->id, hdev->name);
++
++
++ for (i = 0; i < NUM_REASSEMBLY; i++)
++ hdev->reassembly[i] = NULL;
++
++ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
++ atomic_set(&hdev->promisc, 0);
++
++ if (ghdev) {
++ write_unlock(&hci_dev_lock);
++ AICBT_ERR("%s: Hci device has been registered already", __func__);
++ return -1;
++ } else
++ ghdev = hdev;
++
++ write_unlock(&hci_dev_lock);
++
++ return id;
++}
++
++/* Unregister HCI device */
++static void hci_unregister_dev(struct hci_dev *hdev)
++{
++ int i;
++
++ AICBT_DBG("%s: hdev %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus);
++ set_bit(HCI_UNREGISTER, &hdev->dev_flags);
++
++ write_lock(&hci_dev_lock);
++ ghdev = NULL;
++ write_unlock(&hci_dev_lock);
++
++ hci_dev_do_close(hdev);
++ for (i = 0; i < NUM_REASSEMBLY; i++)
++ kfree_skb(hdev->reassembly[i]);
++}
++
++static void hci_send_to_stack(struct hci_dev *hdev, struct sk_buff *skb)
++{
++ struct sk_buff *aic_skb_copy = NULL;
++
++ //AICBT_DBG("%s", __func__);
++
++ if (!hdev) {
++ AICBT_ERR("%s: Frame for unknown HCI device", __func__);
++ return;
++ }
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
++ AICBT_ERR("%s: HCI not running", __func__);
++ return;
++ }
++
++ aic_skb_copy = pskb_copy(skb, GFP_ATOMIC);
++ if (!aic_skb_copy) {
++ AICBT_ERR("%s: Copy skb error", __func__);
++ return;
++ }
++
++ memcpy(skb_push(aic_skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
++ aic_enqueue(aic_skb_copy);
++
++ /* Make sure bt char device existing before wakeup read queue */
++ hdev = hci_dev_get(0);
++ if (hdev) {
++ //AICBT_DBG("%s: Try to wakeup read queue", __func__);
++ AICBT_DBG("%s", __func__);
++ wake_up_interruptible(&btchr_read_wait);
++ }
++
++
++ return;
++}
++
++/* Receive frame from HCI drivers */
++static int hci_recv_frame(struct sk_buff *skb)
++{
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ if (!hdev ||
++ (!test_bit(HCI_UP, &hdev->flags) && !test_bit(HCI_INIT, &hdev->flags))) {
++ kfree_skb(skb);
++ return -ENXIO;
++ }
++
++ /* Incomming skb */
++ bt_cb(skb)->incoming = 1;
++
++ /* Time stamp */
++ __net_timestamp(skb);
++
++ if (atomic_read(&hdev->promisc)) {
++#ifdef CONFIG_SCO_OVER_HCI
++ if(bt_cb(skb)->pkt_type == HCI_SCODATA_PKT){
++ hci_send_to_alsa_ringbuffer(hdev, skb);
++ }else{
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++ if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){
++ if(bypass_event(skb)){
++ kfree_skb(skb);
++ return 0;
++ }
++ }
++#endif //CONFIG_SUPPORT_VENDOR_APCF
++ hci_send_to_stack(hdev, skb);
++ }
++#else
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++ if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){
++ if(bypass_event(skb)){
++ kfree_skb(skb);
++ return 0;
++ }
++ }
++#endif //CONFIG_SUPPORT_VENDOR_APCF
++ /* Send copy to the sockets */
++ hci_send_to_stack(hdev, skb);
++#endif
++
++ }
++
++ kfree_skb(skb);
++ return 0;
++}
++
++
++
++static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
++ int count, __u8 index)
++{
++ int len = 0;
++ int hlen = 0;
++ int remain = count;
++ struct sk_buff *skb;
++ struct bt_skb_cb *scb;
++
++ //AICBT_DBG("%s", __func__);
++
++ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
++ index >= NUM_REASSEMBLY)
++ return -EILSEQ;
++
++ skb = hdev->reassembly[index];
++
++ if (!skb) {
++ switch (type) {
++ case HCI_ACLDATA_PKT:
++ len = HCI_MAX_FRAME_SIZE;
++ hlen = HCI_ACL_HDR_SIZE;
++ break;
++ case HCI_EVENT_PKT:
++ len = HCI_MAX_EVENT_SIZE;
++ hlen = HCI_EVENT_HDR_SIZE;
++ break;
++ case HCI_SCODATA_PKT:
++ len = HCI_MAX_SCO_SIZE;
++ hlen = HCI_SCO_HDR_SIZE;
++ break;
++ }
++
++ skb = bt_skb_alloc(len, GFP_ATOMIC);
++ if (!skb)
++ return -ENOMEM;
++
++ scb = (void *) skb->cb;
++ scb->expect = hlen;
++ scb->pkt_type = type;
++
++ skb->dev = (void *) hdev;
++ hdev->reassembly[index] = skb;
++ }
++
++ while (count) {
++ scb = (void *) skb->cb;
++ len = min_t(uint, scb->expect, count);
++
++ memcpy(skb_put(skb, len), data, len);
++
++ count -= len;
++ data += len;
++ scb->expect -= len;
++ remain = count;
++
++ switch (type) {
++ case HCI_EVENT_PKT:
++ if (skb->len == HCI_EVENT_HDR_SIZE) {
++ struct hci_event_hdr *h = hci_event_hdr(skb);
++ scb->expect = h->plen;
++
++ if (skb_tailroom(skb) < scb->expect) {
++ kfree_skb(skb);
++ hdev->reassembly[index] = NULL;
++ return -ENOMEM;
++ }
++ }
++ break;
++
++ case HCI_ACLDATA_PKT:
++ if (skb->len == HCI_ACL_HDR_SIZE) {
++ struct hci_acl_hdr *h = hci_acl_hdr(skb);
++ scb->expect = __le16_to_cpu(h->dlen);
++
++ if (skb_tailroom(skb) < scb->expect) {
++ kfree_skb(skb);
++ hdev->reassembly[index] = NULL;
++ return -ENOMEM;
++ }
++ }
++ break;
++
++ case HCI_SCODATA_PKT:
++ if (skb->len == HCI_SCO_HDR_SIZE) {
++ struct hci_sco_hdr *h = hci_sco_hdr(skb);
++ scb->expect = h->dlen;
++
++ if (skb_tailroom(skb) < scb->expect) {
++ kfree_skb(skb);
++ hdev->reassembly[index] = NULL;
++ return -ENOMEM;
++ }
++ }
++ break;
++ }
++
++ if (scb->expect == 0) {
++ /* Complete frame */
++ if(HCI_ACLDATA_PKT == type)
++ print_acl(skb,0);
++ if(HCI_SCODATA_PKT == type)
++ print_sco(skb,0);
++ if(HCI_EVENT_PKT == type)
++ print_event(skb);
++
++ bt_cb(skb)->pkt_type = type;
++ hci_recv_frame(skb);
++
++ hdev->reassembly[index] = NULL;
++ return remain;
++ }
++ }
++
++ return remain;
++}
++
++static int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
++{
++ int rem = 0;
++
++ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
++ return -EILSEQ;
++
++ while (count) {
++ rem = hci_reassembly(hdev, type, data, count, type - 1);
++ if (rem < 0)
++ return rem;
++
++ data += (count - rem);
++ count = rem;
++ }
++
++ return rem;
++}
++#endif //CONFIG_BLUEDROID
++
++void hci_hardware_error(void)
++{
++ struct sk_buff *aic_skb_copy = NULL;
++ int len = 3;
++ uint8_t hardware_err_pkt[4] = {HCI_EVENT_PKT, 0x10, 0x01, HCI_VENDOR_USB_DISC_HARDWARE_ERROR};
++
++ aic_skb_copy = alloc_skb(len, GFP_ATOMIC);
++ if (!aic_skb_copy) {
++ AICBT_ERR("%s: Failed to allocate mem", __func__);
++ return;
++ }
++
++ memcpy(skb_put(aic_skb_copy, len), hardware_err_pkt, len);
++ aic_enqueue(aic_skb_copy);
++
++ wake_up_interruptible(&btchr_read_wait);
++}
++
++static int btchr_open(struct inode *inode_p, struct file *file_p)
++{
++ struct btusb_data *data;
++ struct hci_dev *hdev;
++
++ AICBT_DBG("%s: BT usb char device is opening", __func__);
++ /* Not open unless wanna tracing log */
++ /* trace_printk("%s: open....\n", __func__); */
++
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_DBG("%s: Failed to get hci dev[NULL]", __func__);
++ return -ENODEV;
++ }
++ data = GET_DRV_DATA(hdev);
++
++ atomic_inc(&hdev->promisc);
++ /*
++ * As bt device is not re-opened when hotplugged out, we cannot
++ * trust on file's private data(may be null) when other file ops
++ * are invoked.
++ */
++ file_p->private_data = data;
++
++ mutex_lock(&btchr_mutex);
++ hci_dev_open(0);
++ mutex_unlock(&btchr_mutex);
++
++ aic_clear_queue();
++ return nonseekable_open(inode_p, file_p);
++}
++
++static int btchr_close(struct inode *inode_p, struct file *file_p)
++{
++ struct btusb_data *data;
++ struct hci_dev *hdev;
++
++ AICBT_INFO("%s: BT usb char device is closing", __func__);
++ /* Not open unless wanna tracing log */
++ /* trace_printk("%s: close....\n", __func__); */
++
++ data = file_p->private_data;
++ file_p->private_data = NULL;
++
++#if CONFIG_BLUEDROID
++ /*
++ * If the upper layer closes bt char interfaces, no reset
++ * action required even bt device hotplugged out.
++ */
++ bt_reset = 0;
++#endif
++
++ hdev = hci_dev_get(0);
++ if (hdev) {
++ atomic_set(&hdev->promisc, 0);
++ mutex_lock(&btchr_mutex);
++ hci_dev_close(0);
++ mutex_unlock(&btchr_mutex);
++ }
++
++ return 0;
++}
++
++static ssize_t btchr_read(struct file *file_p,
++ char __user *buf_p,
++ size_t count,
++ loff_t *pos_p)
++{
++ struct hci_dev *hdev;
++ struct sk_buff *skb;
++ ssize_t ret = 0;
++
++ while (count) {
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ /*
++ * Note: Only when BT device hotplugged out, we wil get
++ * into such situation. In order to keep the upper layer
++ * stack alive (blocking the read), we should never return
++ * EFAULT or break the loop.
++ */
++ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__);
++ }
++
++ ret = wait_event_interruptible(btchr_read_wait, !is_queue_empty());
++ if (ret < 0) {
++ AICBT_ERR("%s: wait event is signaled %d", __func__, (int)ret);
++ break;
++ }
++
++ skb = aic_dequeue_try(count);
++ if (skb) {
++ ret = usb_put_user(skb, buf_p, count);
++ if (ret < 0)
++ AICBT_ERR("%s: Failed to put data to user space", __func__);
++ kfree_skb(skb);
++ break;
++ }
++ }
++
++ return ret;
++}
++
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++void btchr_external_write(char* buff, int len){
++ struct hci_dev *hdev;
++ struct sk_buff *skb;
++ int i;
++ struct btusb_data *data;
++
++ AICBT_INFO("%s \r\n", __func__);
++ for(i=0;i<len;i++){
++ printk("0x%x ",(u8)buff[i]);
++ }
++ printk("\r\n");
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_WARN("%s: Failed to get hci dev[Null]", __func__);
++ return;
++ }
++ /* Never trust on btusb_data, as bt device may be hotplugged out */
++ data = GET_DRV_DATA(hdev);
++ if (!data) {
++ AICBT_WARN("%s: Failed to get bt usb driver data[Null]", __func__);
++ return;
++ }
++ vendor_apcf_sent_done++;
++
++ skb = bt_skb_alloc(len, GFP_ATOMIC);
++ if (!skb)
++ return;
++ skb_reserve(skb, -1); // Add this line
++ skb->dev = (void *)hdev;
++ memcpy((__u8 *)skb->data,(__u8 *)buff,len);
++ skb_put(skb, len);
++ bt_cb(skb)->pkt_type = *((__u8 *)skb->data);
++ skb_pull(skb, 1);
++ data->hdev->send(skb);
++}
++
++EXPORT_SYMBOL(btchr_external_write);
++#endif //CONFIG_SUPPORT_VENDOR_APCF
++
++static ssize_t btchr_write(struct file *file_p,
++ const char __user *buf_p,
++ size_t count,
++ loff_t *pos_p)
++{
++ struct btusb_data *data = file_p->private_data;
++ struct hci_dev *hdev;
++ struct sk_buff *skb;
++
++ //AICBT_DBG("%s: BT usb char device is writing", __func__);
++ AICBT_DBG("%s", __func__);
++
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_WARN("%s: Failed to get hci dev[Null]", __func__);
++ /*
++ * Note: we bypass the data from the upper layer if bt device
++ * is hotplugged out. Fortunatelly, H4 or H5 HCI stack does
++ * NOT check btchr_write's return value. However, returning
++ * count instead of EFAULT is preferable.
++ */
++ /* return -EFAULT; */
++ return count;
++ }
++
++ /* Never trust on btusb_data, as bt device may be hotplugged out */
++ data = GET_DRV_DATA(hdev);
++ if (!data) {
++ AICBT_WARN("%s: Failed to get bt usb driver data[Null]", __func__);
++ return count;
++ }
++
++ if (count > HCI_MAX_FRAME_SIZE)
++ return -EINVAL;
++
++ skb = bt_skb_alloc(count, GFP_ATOMIC);
++ if (!skb)
++ return -ENOMEM;
++ skb_reserve(skb, -1); // Add this line
++
++ if (copy_from_user(skb_put(skb, count), buf_p, count)) {
++ AICBT_ERR("%s: Failed to get data from user space", __func__);
++ kfree_skb(skb);
++ return -EFAULT;
++ }
++
++ skb->dev = (void *)hdev;
++ bt_cb(skb)->pkt_type = *((__u8 *)skb->data);
++ skb_pull(skb, 1);
++ data->hdev->send(skb);
++
++ return count;
++}
++
++static unsigned int btchr_poll(struct file *file_p, poll_table *wait)
++{
++ struct btusb_data *data = file_p->private_data;
++ struct hci_dev *hdev;
++
++ //AICBT_DBG("%s: BT usb char device is polling", __func__);
++
++ if(!bt_char_dev_registered) {
++ AICBT_ERR("%s: char device has not registered!", __func__);
++ return POLLERR | POLLHUP;
++ }
++
++ poll_wait(file_p, &btchr_read_wait, wait);
++
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__);
++ mdelay(URB_CANCELING_DELAY_MS);
++ return POLLERR | POLLHUP;
++ return POLLOUT | POLLWRNORM;
++ }
++
++ /* Never trust on btusb_data, as bt device may be hotplugged out */
++ data = GET_DRV_DATA(hdev);
++ if (!data) {
++ /*
++ * When bt device is hotplugged out, btusb_data will
++ * be freed in disconnect.
++ */
++ AICBT_ERR("%s: Failed to get bt usb driver data[Null]", __func__);
++ mdelay(URB_CANCELING_DELAY_MS);
++ return POLLOUT | POLLWRNORM;
++ }
++
++ if (!is_queue_empty())
++ return POLLIN | POLLRDNORM;
++
++ return POLLOUT | POLLWRNORM;
++}
++static long btchr_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg)
++{
++ int ret = 0;
++ struct hci_dev *hdev;
++ struct btusb_data *data;
++ firmware_info *fw_info;
++
++ if(!bt_char_dev_registered) {
++ return -ENODEV;
++ }
++
++ if(check_set_dlfw_state_value(1) != 1) {
++ AICBT_ERR("%s bt controller is disconnecting!", __func__);
++ return 0;
++ }
++
++ hdev = hci_dev_get(0);
++ if(!hdev) {
++ AICBT_ERR("%s device is NULL!", __func__);
++ set_dlfw_state_value(0);
++ return 0;
++ }
++ data = GET_DRV_DATA(hdev);
++ fw_info = data->fw_info;
++
++ AICBT_INFO(" btchr_ioctl DOWN_FW_CFG with Cmd:%d",cmd);
++ switch (cmd) {
++ case DOWN_FW_CFG:
++ AICBT_INFO(" btchr_ioctl DOWN_FW_CFG");
++ ret = usb_autopm_get_interface(data->intf);
++ if (ret < 0){
++ goto failed;
++ }
++
++ //ret = download_patch(fw_info,1);
++ usb_autopm_put_interface(data->intf);
++ if(ret < 0){
++ AICBT_ERR("%s:Failed in download_patch with ret:%d",__func__,ret);
++ goto failed;
++ }
++
++ ret = hdev->open(hdev);
++ if(ret < 0){
++ AICBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret);
++ goto failed;
++ }
++ set_bit(HCI_UP, &hdev->flags);
++ set_dlfw_state_value(0);
++ wake_up_interruptible(&bt_dlfw_wait);
++ return 1;
++ case DWFW_CMPLT:
++ AICBT_INFO(" btchr_ioctl DWFW_CMPLT");
++#if 1
++ case SET_ISO_CFG:
++ AICBT_INFO("btchr_ioctl SET_ISO_CFG");
++ if(copy_from_user(&(hdev->voice_setting), (__u16*)arg, sizeof(__u16))){
++ AICBT_INFO(" voice settings err");
++ }
++ //hdev->voice_setting = *(uint16_t*)arg;
++ AICBT_INFO(" voice settings = %d", hdev->voice_setting);
++ //return 1;
++#endif
++ case GET_USB_INFO:
++ //ret = download_patch(fw_info,1);
++ AICBT_INFO(" btchr_ioctl GET_USB_INFO");
++ ret = hdev->open(hdev);
++ if(ret < 0){
++ AICBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret);
++ //goto done;
++ }
++ set_bit(HCI_UP, &hdev->flags);
++ set_dlfw_state_value(0);
++ wake_up_interruptible(&bt_dlfw_wait);
++ return 1;
++ case RESET_CONTROLLER:
++ AICBT_INFO(" btchr_ioctl RESET_CONTROLLER");
++ //reset_controller(fw_info);
++ return 1;
++ default:
++ AICBT_ERR("%s:Failed with wrong Cmd:%d",__func__,cmd);
++ goto failed;
++ }
++ failed:
++ set_dlfw_state_value(0);
++ wake_up_interruptible(&bt_dlfw_wait);
++ return ret;
++
++}
++
++#ifdef CONFIG_PLATFORM_UBUNTU//AIDEN
++typedef u32 compat_uptr_t;
++static inline void __user *compat_ptr(compat_uptr_t uptr)
++{
++ return (void __user *)(unsigned long)uptr;
++}
++#endif
++
++#ifdef CONFIG_COMPAT
++static long compat_btchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
++{
++ AICBT_DBG("%s: enter",__func__);
++ return btchr_ioctl(filp, cmd, (unsigned long) compat_ptr(arg));
++}
++#endif
++static struct file_operations bt_chrdev_ops = {
++ open : btchr_open,
++ release : btchr_close,
++ read : btchr_read,
++ write : btchr_write,
++ poll : btchr_poll,
++ unlocked_ioctl : btchr_ioctl,
++#ifdef CONFIG_COMPAT
++ compat_ioctl : compat_btchr_ioctl,
++#endif
++};
++
++static int btchr_init(void)
++{
++ int res = 0;
++ struct device *dev;
++
++ AICBT_INFO("Register usb char device interface for BT driver");
++ /*
++ * btchr mutex is used to sync between
++ * 1) downloading patch and opening bt char driver
++ * 2) the file operations of bt char driver
++ */
++ mutex_init(&btchr_mutex);
++
++ skb_queue_head_init(&btchr_readq);
++ init_waitqueue_head(&btchr_read_wait);
++ init_waitqueue_head(&bt_dlfw_wait);
++
++ bt_char_class = class_create(THIS_MODULE, BT_CHAR_DEVICE_NAME);
++ if (IS_ERR(bt_char_class)) {
++ AICBT_ERR("Failed to create bt char class");
++ return PTR_ERR(bt_char_class);
++ }
++
++ res = alloc_chrdev_region(&bt_devid, 0, 1, BT_CHAR_DEVICE_NAME);
++ if (res < 0) {
++ AICBT_ERR("Failed to allocate bt char device");
++ goto err_alloc;
++ }
++
++ dev = device_create(bt_char_class, NULL, bt_devid, NULL, BT_CHAR_DEVICE_NAME);
++ if (IS_ERR(dev)) {
++ AICBT_ERR("Failed to create bt char device");
++ res = PTR_ERR(dev);
++ goto err_create;
++ }
++
++ cdev_init(&bt_char_dev, &bt_chrdev_ops);
++ res = cdev_add(&bt_char_dev, bt_devid, 1);
++ if (res < 0) {
++ AICBT_ERR("Failed to add bt char device");
++ goto err_add;
++ }
++
++ return 0;
++
++err_add:
++ device_destroy(bt_char_class, bt_devid);
++err_create:
++ unregister_chrdev_region(bt_devid, 1);
++err_alloc:
++ class_destroy(bt_char_class);
++ return res;
++}
++
++static void btchr_exit(void)
++{
++ AICBT_INFO("Unregister usb char device interface for BT driver");
++
++ device_destroy(bt_char_class, bt_devid);
++ cdev_del(&bt_char_dev);
++ unregister_chrdev_region(bt_devid, 1);
++ class_destroy(bt_char_class);
++
++ return;
++}
++#endif
++
++int send_hci_cmd(firmware_info *fw_info)
++{
++
++ int len = 0;
++ int ret_val = -1;
++ int i = 0;
++
++ if(g_chipid == PRODUCT_ID_AIC8801 || g_chipid == PRODUCT_ID_AIC8800D80){
++ ret_val = usb_bulk_msg(fw_info->udev, fw_info->pipe_out, fw_info->send_pkt, fw_info->pkt_len,
++ &len, 3000);
++ if (ret_val || (len != fw_info->pkt_len)) {
++ AICBT_INFO("Error in send hci cmd = %d,"
++ "len = %d, size = %d", ret_val, len, fw_info->pkt_len);
++ }
++ }else if(g_chipid == PRODUCT_ID_AIC8800DC){
++ while((ret_val<0)&&(i++<3))
++ {
++ ret_val = usb_control_msg(
++ fw_info->udev, fw_info->pipe_out,
++ 0, USB_TYPE_CLASS, 0, 0,
++ (void *)(fw_info->send_pkt),
++ fw_info->pkt_len, MSG_TO);
++ }
++
++ }
++ return ret_val;
++
++}
++
++int rcv_hci_evt(firmware_info *fw_info)
++{
++ int ret_len = 0, ret_val = 0;
++ int i;
++
++ while (1) {
++ for(i = 0; i < 5; i++) {
++ ret_val = usb_interrupt_msg(
++ fw_info->udev, fw_info->pipe_in,
++ (void *)(fw_info->rcv_pkt), RCV_PKT_LEN,
++ &ret_len, MSG_TO);
++ if (ret_val >= 0)
++ break;
++ }
++
++ if (ret_val < 0)
++ return ret_val;
++
++ if (CMD_CMP_EVT == fw_info->evt_hdr->evt) {
++ if (fw_info->cmd_hdr->opcode == fw_info->cmd_cmp->opcode)
++ return ret_len;
++ }
++ }
++}
++
++int set_bt_onoff(firmware_info *fw_info, uint8_t onoff)
++{
++ int ret_val;
++
++ AICBT_INFO("%s: %s", __func__, onoff != 0 ? "on" : "off");
++
++ fw_info->cmd_hdr->opcode = cpu_to_le16(BTOFF_OPCODE);
++ fw_info->cmd_hdr->plen = 1;
++ fw_info->pkt_len = CMD_HDR_LEN + 1;
++ fw_info->send_pkt[CMD_HDR_LEN] = onoff;
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: Failed to send bt %s cmd, errno %d",
++ __func__, onoff != 0 ? "on" : "off", ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: Failed to receive bt %s event, errno %d",
++ __func__, onoff != 0 ? "on" : "off", ret_val);
++ return ret_val;
++ }
++
++ return ret_val;
++}
++
++//for 8800DC start
++u32 fwcfg_tbl[][2] = {
++ {0x40200028, 0x0021047e},
++ {0x40200024, 0x0000011d},
++};
++
++int fw_config(firmware_info* fw_info)
++{
++ int ret_val = -1;
++ struct hci_dbg_rd_mem_cmd *rd_cmd;
++ struct hci_dbg_rd_mem_cmd_evt *evt_para;
++ int len = 0, i = 0;
++ struct fw_status *evt_status;
++
++ rd_cmd = (struct hci_dbg_rd_mem_cmd *)(fw_info->req_para);
++ if (!rd_cmd)
++ return -ENOMEM;
++
++ rd_cmd->start_addr = 0x40200024;
++ rd_cmd->type = 32;
++ rd_cmd->length = 4;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_DBG_RD_MEM_CMD);
++ fw_info->cmd_hdr->plen = sizeof(struct hci_dbg_rd_mem_cmd);
++ fw_info->pkt_len = CMD_HDR_LEN + sizeof(struct hci_dbg_rd_mem_cmd);
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x, length %d, %x %x %x %x",
++ __func__, evt_para->status, evt_para->length,
++ evt_para->data[0],
++ evt_para->data[1],
++ evt_para->data[2],
++ evt_para->data[3]);
++
++ ret_val = evt_para->status;
++ if (evt_para->status == 0) {
++ uint16_t rd_data = (evt_para->data[0] | (evt_para->data[1] << 8));
++ printk("%s rd_data is %x\n", __func__, rd_data);
++ if (rd_data == 0x119) {
++ struct aicbt_patch_table_cmd *patch_table_cmd = (struct aicbt_patch_table_cmd *)(fw_info->req_para);
++ len = sizeof(fwcfg_tbl) / sizeof(u32) / 2;
++ patch_table_cmd->patch_num = len;
++ for (i = 0; i < len; i++) {
++ memcpy(&patch_table_cmd->patch_table_addr[i], &fwcfg_tbl[i][0], sizeof(uint32_t));
++ memcpy(&patch_table_cmd->patch_table_data[i], &fwcfg_tbl[i][1], sizeof(uint32_t));
++ printk("%s [%d] data: %08x %08x\n", __func__, i, patch_table_cmd->patch_table_addr[i],patch_table_cmd->patch_table_data[i]);
++ }
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_UPDATE_PT_CMD);
++ fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_SIZE;
++ fw_info->pkt_len = fw_info->cmd_hdr->plen + 3;
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ return ret_val;
++ }
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++ evt_status = (struct fw_status *)fw_info->rsp_para;
++ ret_val = evt_status->status;
++ if (0 != evt_status->status) {
++ ret_val = -1;
++ } else {
++ ret_val = 0;
++ }
++
++ }
++ }
++ return ret_val;
++}
++
++int system_config(firmware_info *fw_info)
++{
++ int ret_val = -1;
++ struct hci_dbg_rd_mem_cmd *rd_cmd;
++ struct hci_dbg_rd_mem_cmd_evt *evt_para;
++ //int len = 0, i = 0;
++ //struct fw_status *evt_status;
++
++ rd_cmd = (struct hci_dbg_rd_mem_cmd *)(fw_info->req_para);
++ if (!rd_cmd)
++ return -ENOMEM;
++
++ rd_cmd->start_addr = 0x40500000;
++ rd_cmd->type = 32;
++ rd_cmd->length = 4;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_DBG_RD_MEM_CMD);
++ fw_info->cmd_hdr->plen = sizeof(struct hci_dbg_rd_mem_cmd);
++ fw_info->pkt_len = CMD_HDR_LEN + sizeof(struct hci_dbg_rd_mem_cmd);
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x, length %d, %x %x %x %x",
++ __func__, evt_para->status, evt_para->length,
++ evt_para->data[0],
++ evt_para->data[1],
++ evt_para->data[2],
++ evt_para->data[3]);
++
++ ret_val = evt_para->status;
++ if (evt_para->status == 0)
++ {
++ uint32_t rd_data = (evt_para->data[0] | (evt_para->data[1] << 8) | (evt_para->data[2] << 16) | (evt_para->data[3] << 24));
++ //printk("%s 0x40500000 rd_data is %x\n", __func__, rd_data);
++ chip_id = (u8) (rd_data >> 16);
++ }
++
++ rd_cmd->start_addr = 0x20;
++ rd_cmd->type = 32;
++ rd_cmd->length = 4;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_DBG_RD_MEM_CMD);
++ fw_info->cmd_hdr->plen = sizeof(struct hci_dbg_rd_mem_cmd);
++ fw_info->pkt_len = CMD_HDR_LEN + sizeof(struct hci_dbg_rd_mem_cmd);
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x, length %d, %x %x %x %x",
++ __func__, evt_para->status, evt_para->length,
++ evt_para->data[0],
++ evt_para->data[1],
++ evt_para->data[2],
++ evt_para->data[3]);
++
++ ret_val = evt_para->status;
++ if (evt_para->status == 0)
++ {
++ uint32_t rd_data = (evt_para->data[0] | (evt_para->data[1] << 8) | (evt_para->data[2] << 16) | (evt_para->data[3] << 24));
++ //printk("%s 0x02 rd_data is %x\n", __func__, rd_data);
++ sub_chip_id = (u8) (rd_data);
++ }
++ printk("chip_id = %x, sub_chip_id = %x\n", chip_id, sub_chip_id);
++ return ret_val;
++}
++
++int check_fw_status(firmware_info* fw_info)
++{
++ struct fw_status *read_ver_rsp;
++ int ret_val = -1;
++
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_FW_STATUS_GET_CMD);
++ fw_info->cmd_hdr->plen = 0;
++ fw_info->pkt_len = CMD_HDR_LEN;
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ read_ver_rsp = (struct fw_status *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x",
++ __func__, read_ver_rsp->status);
++ return read_ver_rsp->status;
++}
++
++int download_data(firmware_info *fw_info, u32 fw_addr, char *filename)
++{
++ unsigned int i=0;
++ int size;
++ u8 *dst=NULL;
++ int err=0;
++ struct hci_dbg_wr_mem_cmd *dl_cmd;
++ int hdr_len = sizeof(__le32) + sizeof(__u8) + sizeof(__u8);
++ int data_len = HCI_VSC_MEM_WR_SIZE;
++ int frag_len = data_len + hdr_len;
++ int ret_val;
++ int ncmd = 1;
++ struct fw_status *evt_para;
++
++ /* load aic firmware */
++ size = aic_load_firmware(&dst, filename, NULL);
++ if(size <= 0){
++ printk("wrong size of firmware file\n");
++ vfree(dst);
++ dst = NULL;
++ return -1;
++ }
++
++ dl_cmd = (struct hci_dbg_wr_mem_cmd *)(fw_info->req_para);
++ if (!dl_cmd)
++ return -ENOMEM;
++ evt_para = (struct fw_status *)fw_info->rsp_para;
++
++ /* Copy the file on the Embedded side */
++ printk("### Upload %s firmware, @ = %x size=%d\n", filename, fw_addr, size);
++
++ if (size > HCI_VSC_MEM_WR_SIZE) {// > 1KB data
++ for (i = 0; i < (size - HCI_VSC_MEM_WR_SIZE); i += HCI_VSC_MEM_WR_SIZE) {//each time write 240 bytes
++ data_len = HCI_VSC_MEM_WR_SIZE;
++ frag_len = data_len + hdr_len;
++ memcpy(dl_cmd->data, dst + i, data_len);
++ dl_cmd->length = data_len;
++ dl_cmd->type = 32;
++ dl_cmd->start_addr = fw_addr + i;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(DOWNLOAD_OPCODE);
++ fw_info->cmd_hdr->plen = frag_len;
++ fw_info->pkt_len = frag_len + 3;
++ #if 0
++ printk("[%d] data_len %d, src %x, dst %x\n", i, data_len, dst + i, fw_addr + i);
++ printk("%p , %d\n", dl_cmd, fw_info->pkt_len);
++ print_hex_dump(KERN_ERR,"payload:",DUMP_PREFIX_NONE,16,1,dl_cmd->data,32,false);
++ /* Send download command */
++ print_hex_dump(KERN_ERR,"data:",DUMP_PREFIX_NONE,16,1,fw_info->send_pkt,32,false);
++ #endif
++ ret_val = send_hci_cmd(fw_info);
++
++ while (ncmd > 0) {
++ ret_val = rcv_hci_evt(fw_info);
++ printk("rcv_hci_evt %d\n", ret_val);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ goto out;
++ } else {
++ AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status);
++ ncmd--;
++ }
++ if (0 != evt_para->status) {
++ AICBT_ERR("%s: Receive acked frag num %d, err status %d",
++ __func__, ret_val, evt_para->status);
++ ret_val = -1;
++ goto out;
++ } else {
++ ret_val = 0;
++ }
++ }
++ ncmd = 1;
++ }
++ }
++
++ if (!err && (i < size)) {// <1KB data
++ data_len = size - i;
++ frag_len = data_len + hdr_len;
++ memcpy(dl_cmd->data, dst + i, data_len);
++ dl_cmd->length = data_len;
++ dl_cmd->type = 32;
++ dl_cmd->start_addr = fw_addr + i;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(DOWNLOAD_OPCODE);
++ fw_info->cmd_hdr->plen = frag_len;
++ fw_info->pkt_len = frag_len + 3;
++ ret_val = send_hci_cmd(fw_info);
++ //printk("(%d) data_len %d, src %x, dst %x\n", i, data_len, (dst + i), fw_addr + i);
++ //printk("%p , %d\n", dl_cmd, fw_info->pkt_len);
++ while (ncmd > 0) {
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ goto out;
++ } else {
++ AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status);
++ ncmd--;
++ }
++ if (0 != evt_para->status) {
++ AICBT_ERR("%s: Receive acked frag num %d, err status %d",
++ __func__, ret_val, evt_para->status);
++ ret_val = -1;
++ goto out;
++ } else {
++ ret_val = 0;
++ }
++ }
++ ncmd = 0;
++ }
++
++out:
++ if (dst) {
++ vfree(dst);
++ dst = NULL;
++ }
++
++ printk("fw download complete\n\n");
++ return ret_val;
++
++}
++
++
++struct aicbt_info_t {
++ uint32_t btmode;
++ uint32_t btport;
++ uint32_t uart_baud;
++ uint32_t uart_flowctrl;
++ uint32_t lpm_enable;
++ uint32_t txpwr_lvl;
++};
++
++struct aicbsp_info_t {
++ int hwinfo;
++ uint32_t cpmode;
++};
++
++enum aicbsp_cpmode_type {
++ AICBSP_CPMODE_WORK,
++ AICBSP_CPMODE_TEST,
++};
++
++/* btmode
++ * used for force bt mode,if not AICBSP_MODE_NULL
++ * efuse valid and vendor_info will be invalid, even has beed set valid
++*/
++enum aicbt_btmode_type {
++ AICBT_BTMODE_BT_ONLY_SW = 0x0, // bt only mode with switch
++ AICBT_BTMODE_BT_WIFI_COMBO, // wifi/bt combo mode
++ AICBT_BTMODE_BT_ONLY, // bt only mode without switch
++ AICBT_BTMODE_BT_ONLY_TEST, // bt only test mode
++ AICBT_BTMODE_BT_WIFI_COMBO_TEST, // wifi/bt combo test mode
++ AICBT_MODE_NULL = 0xFF, // invalid value
++};
++
++enum aicbt_btport_type {
++ AICBT_BTPORT_NULL,
++ AICBT_BTPORT_MB,
++ AICBT_BTPORT_UART,
++};
++
++enum aicbt_uart_baud_type {
++ AICBT_UART_BAUD_115200 = 115200,
++ AICBT_UART_BAUD_921600 = 921600,
++ AICBT_UART_BAUD_1_5M = 1500000,
++ AICBT_UART_BAUD_3_25M = 3250000,
++};
++
++enum aicbt_uart_flowctrl_type {
++ AICBT_UART_FLOWCTRL_DISABLE = 0x0, // uart without flow ctrl
++ AICBT_UART_FLOWCTRL_ENABLE, // uart with flow ctrl
++};
++
++#define AICBSP_HWINFO_DEFAULT (-1)
++#define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK
++#define AICBT_TXPWR_DFT 0x6F2F
++
++
++#define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_WIFI_COMBO
++#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_MB
++#define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_1_5M
++#define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE
++#define AICBT_LPM_ENABLE_DEFAULT 0
++#define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_DFT
++
++struct aicbsp_info_t aicbsp_info = {
++ .hwinfo = AICBSP_HWINFO_DEFAULT,
++ .cpmode = AICBSP_CPMODE_DEFAULT,
++};
++
++#ifndef CONFIG_USE_FW_REQUEST
++#define FW_PATH_MAX 200
++
++char aic_fw_path[FW_PATH_MAX];
++#if (CONFIG_BLUEDROID == 0)
++static const char* aic_default_fw_path = "/lib/firmware/aic8800DC";
++#else
++static const char* aic_default_fw_path = "/vendor/etc/firmware";
++#endif
++#endif //CONFIG_USE_FW_REQUEST
++
++static struct aicbt_info_t aicbt_info = {
++ .btmode = AICBT_BTMODE_DEFAULT,
++ .btport = AICBT_BTPORT_DEFAULT,
++ .uart_baud = AICBT_UART_BAUD_DEFAULT,
++ .uart_flowctrl = AICBT_UART_FC_DEFAULT,
++ .lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
++ .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT,
++};
++
++int patch_table_load(firmware_info *fw_info, struct aicbt_patch_table *_head)
++{
++ struct aicbt_patch_table *head, *p;
++ int i;
++ uint32_t *data = NULL;
++ struct aicbt_patch_table_cmd *patch_table_cmd = (struct aicbt_patch_table_cmd *)(fw_info->req_para);
++ struct fw_status *evt_para;
++ int ret_val = 0;
++ int ncmd = 1;
++ uint32_t len = 0;
++ uint32_t tot_len = 0;
++ head = _head;
++ for (p = head; p != NULL; p = p->next) {
++ data = p->data;
++ if(AICBT_PT_BTMODE == p->type){
++ *(data + 1) = aicbsp_info.hwinfo < 0;
++ *(data + 3) = aicbsp_info.hwinfo;
++ *(data + 5) = aicbsp_info.cpmode;
++
++ *(data + 7) = aicbt_info.btmode;
++ *(data + 9) = aicbt_info.btport;
++ *(data + 11) = aicbt_info.uart_baud;
++ *(data + 13) = aicbt_info.uart_flowctrl;
++ *(data + 15) = aicbt_info.lpm_enable;
++ *(data + 17) = aicbt_info.txpwr_lvl;
++
++ }
++ if (p->type == AICBT_PT_NULL || p->type == AICBT_PT_PWRON) {
++ continue;
++ }
++ if (p->type == AICBT_PT_VER) {
++ char *data_s = (char *)p->data;
++ printk("patch version %s\n", data_s);
++ continue;
++ }
++ if (p->len == 0) {
++ printk("len is 0\n");
++ continue;
++ }
++ tot_len = p->len;
++ while (tot_len) {
++ if (tot_len > HCI_PT_MAX_LEN) {
++ len = HCI_PT_MAX_LEN;
++ } else {
++ len = tot_len;
++ }
++ for (i = 0; i < len; i++) {
++ patch_table_cmd->patch_num = len;
++ memcpy(&patch_table_cmd->patch_table_addr[i], data, sizeof(uint32_t));
++ memcpy(&patch_table_cmd->patch_table_data[i], data + 1, sizeof(uint32_t));
++ printk("[%d] data: %08x %08x\n", i, patch_table_cmd->patch_table_addr[i],patch_table_cmd->patch_table_data[i]);
++ data += 2;
++ }
++ tot_len -= len;
++ evt_para = (struct fw_status *)fw_info->rsp_para;
++ //print_hex_dump(KERN_ERR,"data0:",DUMP_PREFIX_NONE,16,1,patch_table_cmd,sizeof(struct aicbt_patch_table_cmd),false);
++
++ //printk("patch num %x %d\n", patch_table_cmd->patch_num, sizeof(struct aicbt_patch_table_cmd));
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_UPDATE_PT_CMD);
++ fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_SIZE;
++ fw_info->pkt_len = fw_info->cmd_hdr->plen + 3;
++ AICBT_DBG("patch num 0x%x, plen 0x%x\n", patch_table_cmd->patch_num, fw_info->cmd_hdr->plen );
++ //print_hex_dump(KERN_ERR,"patch table:",DUMP_PREFIX_NONE,16,1,fw_info->send_pkt,32,false);
++ ret_val = send_hci_cmd(fw_info);
++ while (ncmd > 0) {
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ goto out;
++ } else {
++ AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status);
++ ncmd--;
++ }
++ if (0 != evt_para->status) {
++ AICBT_ERR("%s: Receive acked frag num %d, err status %d",
++ __func__, ret_val, evt_para->status);
++ ret_val = -1;
++ goto out;
++ }
++ }
++ ncmd = 1;
++ }
++ }
++out:
++ aicbt_patch_table_free(&head);
++ return ret_val;
++}
++
++int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device)
++{
++
++#ifdef CONFIG_USE_FW_REQUEST
++ const struct firmware *fw = NULL;
++ u32 *dst = NULL;
++ void *buffer=NULL;
++ int size = 0;
++ int ret = 0;
++
++ printk("%s: request firmware = %s \n", __func__ ,name);
++
++
++ ret = request_firmware(&fw, name, NULL);
++
++ if (ret < 0) {
++ printk("Load %s fail\n", name);
++ release_firmware(fw);
++ return -1;
++ }
++
++ size = fw->size;
++ dst = (u32 *)fw->data;
++
++ if (size <= 0) {
++ printk("wrong size of firmware file\n");
++ release_firmware(fw);
++ return -1;
++ }
++
++
++ buffer = vmalloc(size);
++ memset(buffer, 0, size);
++ memcpy(buffer, dst, size);
++
++ *fw_buf = buffer;
++
++ release_firmware(fw);
++
++ return size;
++
++#else
++ u8 *buffer=NULL;
++ char *path=NULL;
++ struct file *fp=NULL;
++ int size = 0, len=0;
++ ssize_t rdlen=0;
++
++ /* get the firmware path */
++ path = __getname();
++ if (!path){
++ *fw_buf=NULL;
++ return -1;
++ }
++
++ if (strlen(aic_fw_path) > 0) {
++ printk("%s: use customer define fw_path\n", __func__);
++ len = snprintf(path, FW_PATH_MAX, "%s/%s", aic_fw_path, name);
++ } else {
++ len = snprintf(path, FW_PATH_MAX, "%s/%s",aic_default_fw_path, name);
++ }
++
++ if (len >= FW_PATH_MAX) {
++ printk("%s: %s file's path too long\n", __func__, name);
++ *fw_buf=NULL;
++ __putname(path);
++ return -1;
++ }
++
++ printk("%s :firmware path = %s \n", __func__ ,path);
++
++
++ /* open the firmware file */
++ fp=filp_open(path, O_RDONLY, 0);
++ if(IS_ERR(fp) || (!fp)){
++ printk("%s: %s file failed to open\n", __func__, name);
++ if(IS_ERR(fp))
++ printk("is_Err\n");
++ if((!fp))
++ printk("null\n");
++ *fw_buf=NULL;
++ __putname(path);
++ fp=NULL;
++ return -1;
++ }
++
++ size = i_size_read(file_inode(fp));
++ if(size<=0){
++ printk("%s: %s file size invalid %d\n", __func__, name, size);
++ *fw_buf=NULL;
++ __putname(path);
++ filp_close(fp,NULL);
++ fp=NULL;
++ return -1;
++}
++
++ /* start to read from firmware file */
++ buffer = vmalloc(size);
++ memset(buffer, 0, size);
++ if(!buffer){
++ *fw_buf=NULL;
++ __putname(path);
++ filp_close(fp,NULL);
++ fp=NULL;
++ return -1;
++ }
++
++
++ #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 13, 16)
++ rdlen = kernel_read(fp, buffer, size, &fp->f_pos);
++ #else
++ rdlen = kernel_read(fp, fp->f_pos, buffer, size);
++ #endif
++
++ if(size != rdlen){
++ printk("%s: %s file rdlen invalid %d %d\n", __func__, name, (int)rdlen, size);
++ *fw_buf=NULL;
++ __putname(path);
++ filp_close(fp,NULL);
++ fp=NULL;
++ vfree(buffer);
++ buffer=NULL;
++ return -1;
++ }
++ if(rdlen > 0){
++ fp->f_pos += rdlen;
++ //printk("f_pos=%d\n", (int)fp->f_pos);
++ }
++ *fw_buf = buffer;
++
++#if 0
++ MD5Init(&md5);
++ MD5Update(&md5, (unsigned char *)dst, size);
++ MD5Final(&md5, decrypt);
++
++ printk(MD5PINRT, MD5(decrypt));
++
++#endif
++ return size;
++#endif
++}
++
++int aicbt_patch_table_free(struct aicbt_patch_table **head)
++{
++ struct aicbt_patch_table *p = *head, *n = NULL;
++ while (p) {
++ n = p->next;
++ kfree(p->name);
++ kfree(p->data);
++ kfree(p);
++ p = n;
++ }
++ *head = NULL;
++ return 0;
++}
++
++int get_patch_addr_from_patch_table(firmware_info *fw_info, char *filename, uint32_t *fw_patch_base_addr)
++{
++ int size;
++ int ret = 0;
++ uint8_t *rawdata=NULL;
++ uint8_t *p = NULL;
++ uint32_t *data = NULL;
++ uint32_t type = 0, len = 0;
++ int j;
++
++ /* load aic firmware */
++ size = aic_load_firmware((u8 **)&rawdata, filename, NULL);
++
++ /* Copy the file on the Embedded side */
++ printk("### Upload %s fw_patch_table, size=%d\n", filename, size);
++
++ if (size <= 0) {
++ printk("wrong size of firmware file\n");
++ ret = -1;
++ goto err;
++ }
++
++ p = rawdata;
++
++ if (memcmp(p, AICBT_PT_TAG, sizeof(AICBT_PT_TAG) < 16 ? sizeof(AICBT_PT_TAG) : 16)) {
++ printk("TAG err\n");
++ ret = -1;
++ goto err;
++ }
++ p += 16;
++
++ while (p - rawdata < size) {
++ printk("size = %d p - rawdata = 0x%0lx \r\n", size, p - rawdata);
++ p += 16;
++
++ type = *(uint32_t *)p;
++ p += 4;
++
++ len = *(uint32_t *)p;
++ p += 4;
++ printk("cur->type %x, len %d\n", type, len);
++
++ if(type >= 1000 ) {//Temp Workaround
++ len = 0;
++ }else{
++ data = (uint32_t *)p;
++ if (type == AICBT_PT_NULL) {
++ *(fw_patch_base_addr) = *(data + 3);
++ printk("addr found %x\n", *(fw_patch_base_addr));
++ for (j = 0; j < len; j++) {
++ printk("addr %x\n", *(data+j));
++ }
++ break;
++ }
++ p += len * 8;
++ }
++ }
++
++ vfree(rawdata);
++ return ret;
++err:
++ //aicbt_patch_table_free(&head);
++
++ if (rawdata){
++ vfree(rawdata);
++ }
++ return ret;
++}
++
++
++
++int patch_table_download(firmware_info *fw_info, char *filename)
++{
++ struct aicbt_patch_table *head = NULL;
++ struct aicbt_patch_table *new = NULL;
++ struct aicbt_patch_table *cur = NULL;
++ int size;
++ int ret = 0;
++ uint8_t *rawdata=NULL;
++ uint8_t *p = NULL;
++
++ /* load aic firmware */
++ size = aic_load_firmware((u8 **)&rawdata, filename, NULL);
++
++ /* Copy the file on the Embedded side */
++ printk("### Upload %s fw_patch_table, size=%d\n", filename, size);
++
++ if (size <= 0) {
++ printk("wrong size of firmware file\n");
++ ret = -1;
++ goto err;
++ }
++
++ p = rawdata;
++
++ if (memcmp(p, AICBT_PT_TAG, sizeof(AICBT_PT_TAG) < 16 ? sizeof(AICBT_PT_TAG) : 16)) {
++ printk("TAG err\n");
++ ret = -1;
++ goto err;
++ }
++ p += 16;
++
++ while (p - rawdata < size) {
++ printk("size = %d p - rawdata = 0x%0lx \r\n", size, p - rawdata);
++ new = (struct aicbt_patch_table *)kmalloc(sizeof(struct aicbt_patch_table), GFP_KERNEL);
++ memset(new, 0, sizeof(struct aicbt_patch_table));
++ if (head == NULL) {
++ head = new;
++ cur = new;
++ } else {
++ cur->next = new;
++ cur = cur->next;
++ }
++
++ cur->name = (char *)kmalloc(sizeof(char) * 16, GFP_KERNEL);
++ memset(cur->name, 0, sizeof(char) * 16);
++ memcpy(cur->name, p, 16);
++ p += 16;
++
++ cur->type = *(uint32_t *)p;
++ p += 4;
++
++ cur->len = *(uint32_t *)p;
++ p += 4;
++ printk("cur->type %x, len %d\n", cur->type, cur->len);
++
++ if((cur->type ) >= 1000 ) {//Temp Workaround
++ cur->len = 0;
++ }else{
++ cur->data = (uint32_t *)kmalloc(sizeof(uint8_t) * cur->len * 8, GFP_KERNEL);
++ memset(cur->data, 0, sizeof(uint8_t) * cur->len * 8);
++ memcpy(cur->data, p, cur->len * 8);
++ p += cur->len * 8;
++ }
++ }
++
++ vfree(rawdata);
++ patch_table_load(fw_info, head);
++ printk("fw_patch_table download complete\n\n");
++
++ return ret;
++err:
++ //aicbt_patch_table_free(&head);
++
++ if (rawdata){
++ vfree(rawdata);
++ }
++ return ret;
++}
++
++
++int download_patch(firmware_info *fw_info, int cached)
++{
++ int ret_val = 0;
++
++ printk("%s: Download fw patch start, cached %d", __func__, cached);
++
++ if (!fw_info) {
++ printk("%s: No patch entry exists(fw_info %p)", __func__, fw_info);
++ ret_val = -1;
++ goto end;
++ }
++
++ ret_val = fw_config(fw_info);
++ if (ret_val) {
++ printk("%s: fw config failed %d", __func__, ret_val);
++ goto free;
++ }
++
++ ret_val = system_config(fw_info);
++ if (ret_val)
++ {
++ printk("%s: system config failed %d", __func__, ret_val);
++ goto free;
++ }
++
++ /*
++ * step1: check firmware statis
++ * step2: download firmware if updated
++ */
++
++
++ ret_val = check_fw_status(fw_info);
++
++
++ if (ret_val) {
++ #if 0
++ ret_val = download_data(fw_info, FW_RAM_ADID_BASE_ADDR, FW_ADID_BASE_NAME);
++ if (ret_val) {
++ printk("aic load adid fail %d\n", ret_val);
++ goto free;
++ }
++ #endif
++ if (sub_chip_id == 0) {
++ ret_val= download_data(fw_info, FW_RAM_PATCH_BASE_ADDR, FW_PATCH_BASE_NAME);
++ if (ret_val) {
++ printk("aic load patch fail %d\n", ret_val);
++ goto free;
++ }
++
++ ret_val= patch_table_download(fw_info, FW_PATCH_TABLE_NAME);
++ if (ret_val) {
++ printk("aic load patch ftable ail %d\n", ret_val);
++ goto free;
++ }
++ } else if (sub_chip_id == 1) {
++ uint32_t fw_ram_patch_base_addr = FW_RAM_PATCH_BASE_ADDR;
++
++ ret_val = get_patch_addr_from_patch_table(fw_info, FW_PATCH_TABLE_NAME_U02, &fw_ram_patch_base_addr);
++ if (ret_val)
++ {
++ printk("aic get patch addr fail %d\n", ret_val);
++ goto free;
++ }
++ printk("%s %x\n", __func__, fw_ram_patch_base_addr);
++ ret_val = download_data(fw_info, fw_ram_patch_base_addr, FW_PATCH_BASE_NAME_U02);
++ if (ret_val)
++ {
++ printk("aic load patch fail %d\n", ret_val);
++ goto free;
++ }
++
++ ret_val = patch_table_download(fw_info, FW_PATCH_TABLE_NAME_U02);
++ if (ret_val)
++ {
++ printk("aic load patch ftable ail %d\n", ret_val);
++ goto free;
++ }
++ } else if (sub_chip_id == 2) {
++ uint32_t fw_ram_patch_base_addr = FW_RAM_PATCH_BASE_ADDR;
++
++ ret_val = get_patch_addr_from_patch_table(fw_info, FW_PATCH_TABLE_NAME_U02H, &fw_ram_patch_base_addr);
++ if (ret_val)
++ {
++ printk("aic get patch addr fail %d\n", ret_val);
++ goto free;
++ }
++ printk("U02H %s %x\n", __func__, fw_ram_patch_base_addr);
++ ret_val = download_data(fw_info, fw_ram_patch_base_addr, FW_PATCH_BASE_NAME_U02H);
++ if (ret_val)
++ {
++ printk("aic load patch fail %d\n", ret_val);
++ goto free;
++ }
++
++ ret_val = patch_table_download(fw_info, FW_PATCH_TABLE_NAME_U02H);
++ if (ret_val)
++ {
++ printk("aic load patch ftable ail %d\n", ret_val);
++ goto free;
++ }
++ } else {
++ printk("%s unsupported sub_chip_id %x\n", __func__, sub_chip_id);
++ }
++ }
++
++free:
++ /* Free fw data after download finished */
++ kfree(fw_info->fw_data);
++ fw_info->fw_data = NULL;
++
++end:
++ return ret_val;
++}
++
++//for 8800dc end
++
++firmware_info *firmware_info_init(struct usb_interface *intf)
++{
++ struct usb_device *udev = interface_to_usbdev(intf);
++ firmware_info *fw_info;
++
++ AICBT_DBG("%s: start", __func__);
++
++ fw_info = kzalloc(sizeof(*fw_info), GFP_KERNEL);
++ if (!fw_info)
++ return NULL;
++
++ fw_info->send_pkt = kzalloc(SEND_PKT_LEN, GFP_KERNEL);
++ if (!fw_info->send_pkt) {
++ kfree(fw_info);
++ return NULL;
++ }
++
++ fw_info->rcv_pkt = kzalloc(RCV_PKT_LEN, GFP_KERNEL);
++ if (!fw_info->rcv_pkt) {
++ kfree(fw_info->send_pkt);
++ kfree(fw_info);
++ return NULL;
++ }
++
++ fw_info->intf = intf;
++ fw_info->udev = udev;
++if(g_chipid == PRODUCT_ID_AIC8801 || g_chipid == PRODUCT_ID_AIC8800D80){
++ fw_info->pipe_in = usb_rcvbulkpipe(fw_info->udev, BULK_EP);
++ fw_info->pipe_out = usb_rcvbulkpipe(fw_info->udev, CTRL_EP);
++}else if(g_chipid == PRODUCT_ID_AIC8800DC){
++ fw_info->pipe_in = usb_rcvintpipe(fw_info->udev, INTR_EP);
++ fw_info->pipe_out = usb_sndctrlpipe(fw_info->udev, CTRL_EP);
++}
++ fw_info->cmd_hdr = (struct hci_command_hdr *)(fw_info->send_pkt);
++ fw_info->evt_hdr = (struct hci_event_hdr *)(fw_info->rcv_pkt);
++ fw_info->cmd_cmp = (struct hci_ev_cmd_complete *)(fw_info->rcv_pkt + EVT_HDR_LEN);
++ fw_info->req_para = fw_info->send_pkt + CMD_HDR_LEN;
++ fw_info->rsp_para = fw_info->rcv_pkt + EVT_HDR_LEN + CMD_CMP_LEN;
++
++#if BTUSB_RPM
++ AICBT_INFO("%s: Auto suspend is enabled", __func__);
++ usb_enable_autosuspend(udev);
++ pm_runtime_set_autosuspend_delay(&(udev->dev), 2000);
++#else
++ AICBT_INFO("%s: Auto suspend is disabled", __func__);
++ usb_disable_autosuspend(udev);
++#endif
++
++#if BTUSB_WAKEUP_HOST
++ device_wakeup_enable(&udev->dev);
++#endif
++
++ return fw_info;
++}
++
++
++void firmware_info_destroy(struct usb_interface *intf)
++{
++ firmware_info *fw_info;
++ struct usb_device *udev;
++ struct btusb_data *data;
++
++ udev = interface_to_usbdev(intf);
++ data = usb_get_intfdata(intf);
++
++ fw_info = data->fw_info;
++ if (!fw_info)
++ return;
++
++#if BTUSB_RPM
++ usb_disable_autosuspend(udev);
++#endif
++
++ /*
++ * In order to reclaim fw data mem, we free fw_data immediately
++ * after download patch finished instead of here.
++ */
++ kfree(fw_info->rcv_pkt);
++ kfree(fw_info->send_pkt);
++ kfree(fw_info);
++
++
++}
++
++static struct usb_driver btusb_driver;
++
++static struct usb_device_id btusb_table[] = {
++ #if 0
++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
++ USB_DEVICE_ID_MATCH_INT_INFO,
++ .idVendor = 0xa69d,
++ .bInterfaceClass = 0xe0,
++ .bInterfaceSubClass = 0x01,
++ .bInterfaceProtocol = 0x01 },
++ #endif
++ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8801, 0xe0, 0x01,0x01)},
++ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D80, 0xe0, 0x01,0x01)},
++ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xe0, 0x01,0x01)},
++ {}
++};
++
++MODULE_DEVICE_TABLE(usb, btusb_table);
++
++static int inc_tx(struct btusb_data *data)
++{
++ unsigned long flags;
++ int rv;
++
++ spin_lock_irqsave(&data->txlock, flags);
++ rv = test_bit(BTUSB_SUSPENDING, &data->flags);
++ if (!rv)
++ data->tx_in_flight++;
++ spin_unlock_irqrestore(&data->txlock, flags);
++
++ return rv;
++}
++
++void check_sco_event(struct urb *urb)
++{
++ u8* opcode = (u8*)(urb->transfer_buffer);
++ u8 status;
++ static uint16_t sco_handle = 0;
++ uint16_t handle;
++ u8 air_mode = 0;
++ struct hci_dev *hdev = urb->context;
++#ifdef CONFIG_SCO_OVER_HCI
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++#endif
++
++ switch (*opcode) {
++ case HCI_EV_SYNC_CONN_COMPLETE:
++ AICBT_INFO("%s: HCI_EV_SYNC_CONN_COMPLETE(0x%02x)", __func__, *opcode);
++ status = *(opcode + 2);
++ sco_handle = *(opcode + 3) | *(opcode + 4) << 8;
++ air_mode = *(opcode + 18);
++ printk("%s status:%d,air_mode:%d \r\n", __func__, status,air_mode);
++ if (status == 0) {
++ hdev->conn_hash.sco_num++;
++ hdev->notify(hdev, 0);
++ //schedule_work(&data->work);
++ if (air_mode == 0x03) {
++ set_select_msbc(CODEC_MSBC);
++ }
++ }
++ break;
++ case HCI_EV_DISCONN_COMPLETE:
++ AICBT_INFO("%s: HCI_EV_DISCONN_COMPLETE(0x%02x)", __func__, *opcode);
++ status = *(opcode + 2);
++ handle = *(opcode + 3) | *(opcode + 4) << 8;
++ if (status == 0 && sco_handle == handle) {
++ hdev->conn_hash.sco_num--;
++ hdev->notify(hdev, 0);
++ set_select_msbc(CODEC_CVSD);
++ //schedule_work(&data->work);
++#ifdef CONFIG_SCO_OVER_HCI
++ if (test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) {
++ mod_timer(&snd_cap_timer.cap_timer,jiffies + msecs_to_jiffies(3));
++ }
++#endif
++ }
++ break;
++ default:
++ AICBT_DBG("%s: event 0x%02x", __func__, *opcode);
++ break;
++ }
++}
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++static inline void btusb_free_frags(struct btusb_data *data)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&data->rxlock, flags);
++
++ kfree_skb(data->evt_skb);
++ data->evt_skb = NULL;
++
++ kfree_skb(data->acl_skb);
++ data->acl_skb = NULL;
++
++ kfree_skb(data->sco_skb);
++ data->sco_skb = NULL;
++
++ spin_unlock_irqrestore(&data->rxlock, flags);
++}
++
++static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
++{
++ struct sk_buff *skb;
++ int err = 0;
++
++ spin_lock(&data->rxlock);
++ skb = data->evt_skb;
++ //printk("%s count %d\n", __func__, count);
++
++#if 1
++ while (count) {
++ int len;
++
++ if (!skb) {
++ skb = bt_skb_alloc(HCI_MAX_EVENT_SIZE, GFP_ATOMIC);
++ if (!skb) {
++ err = -ENOMEM;
++ break;
++ }
++
++ bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
++ bt_cb(skb)->expect = HCI_EVENT_HDR_SIZE;
++ }
++
++ len = min_t(uint, bt_cb(skb)->expect, count);
++ memcpy(skb_put(skb, len), buffer, len);
++
++ count -= len;
++ buffer += len;
++ bt_cb(skb)->expect -= len;
++
++ if (skb->len == HCI_EVENT_HDR_SIZE) {
++ /* Complete event header */
++ bt_cb(skb)->expect = hci_event_hdr(skb)->plen;
++
++ if (skb_tailroom(skb) < bt_cb(skb)->expect) {
++ kfree_skb(skb);
++ skb = NULL;
++
++ err = -EILSEQ;
++ break;
++ }
++ }
++
++ if (bt_cb(skb)->expect == 0) {
++ /* Complete frame */
++ hci_recv_frame(data->hdev, skb);
++ skb = NULL;
++ }
++ }
++#endif
++
++ data->evt_skb = skb;
++ spin_unlock(&data->rxlock);
++
++ return err;
++}
++
++static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
++{
++ struct sk_buff *skb;
++ int err = 0;
++
++ spin_lock(&data->rxlock);
++ skb = data->acl_skb;
++
++ while (count) {
++ int len;
++
++ if (!skb) {
++ skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
++ if (!skb) {
++ err = -ENOMEM;
++ break;
++ }
++
++ bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
++ bt_cb(skb)->expect = HCI_ACL_HDR_SIZE;
++ }
++
++ len = min_t(uint, bt_cb(skb)->expect, count);
++ memcpy(skb_put(skb, len), buffer, len);
++
++ count -= len;
++ buffer += len;
++ bt_cb(skb)->expect -= len;
++
++ if (skb->len == HCI_ACL_HDR_SIZE) {
++ __le16 dlen = hci_acl_hdr(skb)->dlen;
++
++ /* Complete ACL header */
++ bt_cb(skb)->expect = __le16_to_cpu(dlen);
++
++ if (skb_tailroom(skb) < bt_cb(skb)->expect) {
++ kfree_skb(skb);
++ skb = NULL;
++
++ err = -EILSEQ;
++ break;
++ }
++ }
++
++ if (bt_cb(skb)->expect == 0) {
++ /* Complete frame */
++ hci_recv_frame(data->hdev, skb);
++ skb = NULL;
++ }
++ }
++
++ data->acl_skb = skb;
++ spin_unlock(&data->rxlock);
++
++ return err;
++}
++
++static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
++{
++ struct sk_buff *skb;
++ int err = 0;
++
++ spin_lock(&data->rxlock);
++ skb = data->sco_skb;
++
++ while (count) {
++ int len;
++
++ if (!skb) {
++ skb = bt_skb_alloc(HCI_MAX_SCO_SIZE, GFP_ATOMIC);
++ if (!skb) {
++ err = -ENOMEM;
++ break;
++ }
++
++ bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
++ bt_cb(skb)->expect = HCI_SCO_HDR_SIZE;
++ }
++
++ len = min_t(uint, bt_cb(skb)->expect, count);
++ memcpy(skb_put(skb, len), buffer, len);
++
++ count -= len;
++ buffer += len;
++ bt_cb(skb)->expect -= len;
++
++ if (skb->len == HCI_SCO_HDR_SIZE) {
++ /* Complete SCO header */
++ bt_cb(skb)->expect = hci_sco_hdr(skb)->dlen;
++
++ if (skb_tailroom(skb) < bt_cb(skb)->expect) {
++ kfree_skb(skb);
++ skb = NULL;
++
++ err = -EILSEQ;
++ break;
++ }
++ }
++
++ if (bt_cb(skb)->expect == 0) {
++ /* Complete frame */
++ hci_recv_frame(data->hdev, skb);
++ skb = NULL;
++ }
++ }
++
++ data->sco_skb = skb;
++ spin_unlock(&data->rxlock);
++
++ return err;
++}
++#endif
++#endif // (CONFIG_BLUEDROID == 0)
++
++
++static void btusb_intr_complete(struct urb *urb)
++{
++ struct hci_dev *hdev = urb->context;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int err;
++
++ AICBT_DBG("%s: urb %p status %d count %d ", __func__,
++ urb, urb->status, urb->actual_length);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
++ printk("%s return \n", __func__);
++ return;
++ }
++ if (urb->status == 0) {
++ hdev->stat.byte_rx += urb->actual_length;
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
++ if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
++ urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s: Corrupted event packet", __func__);
++ hdev->stat.err_rx++;
++ }
++#else
++ if (btusb_recv_intr(data, urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s corrupted event packet", hdev->name);
++ hdev->stat.err_rx++;
++ }
++#endif
++
++#ifdef CONFIG_SCO_OVER_HCI
++ check_sco_event(urb);
++#endif
++#ifdef CONFIG_USB_AIC_UART_SCO_DRIVER
++ check_sco_event(urb);
++#endif
++
++ }
++ /* Avoid suspend failed when usb_kill_urb */
++ else if(urb->status == -ENOENT) {
++ return;
++ }
++
++
++ if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
++ return;
++
++ usb_mark_last_busy(data->udev);
++ usb_anchor_urb(urb, &data->intr_anchor);
++
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ if (err != -EPERM && err != -ENODEV)
++ AICBT_ERR("%s: Failed to re-submit urb %p, err %d",
++ __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++}
++
++static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct urb *urb;
++ unsigned char *buf;
++ unsigned int pipe;
++ int err, size;
++
++ if (!data->intr_ep)
++ return -ENODEV;
++
++ urb = usb_alloc_urb(0, mem_flags);
++ if (!urb)
++ return -ENOMEM;
++
++ size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
++
++ buf = kmalloc(size, mem_flags);
++ if (!buf) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ AICBT_DBG("%s: mMaxPacketSize %d, bEndpointAddress 0x%02x",
++ __func__, size, data->intr_ep->bEndpointAddress);
++
++ pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
++
++ usb_fill_int_urb(urb, data->udev, pipe, buf, size,
++ btusb_intr_complete, hdev,
++ data->intr_ep->bInterval);
++
++ urb->transfer_flags |= URB_FREE_BUFFER;
++
++ usb_anchor_urb(urb, &data->intr_anchor);
++
++ err = usb_submit_urb(urb, mem_flags);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d",
++ __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++
++ usb_free_urb(urb);
++
++ return err;
++}
++
++static void btusb_bulk_complete(struct urb *urb)
++{
++ struct hci_dev *hdev = urb->context;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int err;
++
++ AICBT_DBG("%s: urb %p status %d count %d",
++ __func__, urb, urb->status, urb->actual_length);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
++ printk("%s HCI_RUNNING\n", __func__);
++ return;
++ }
++ if (urb->status == 0) {
++ hdev->stat.byte_rx += urb->actual_length;
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
++ if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
++ urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s: Corrupted ACL packet", __func__);
++ hdev->stat.err_rx++;
++ }
++#else
++ if (data->recv_bulk(data, urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s Corrupted ACL packet", hdev->name);
++ hdev->stat.err_rx++;
++ }
++#endif
++
++ }
++ /* Avoid suspend failed when usb_kill_urb */
++ else if(urb->status == -ENOENT) {
++ printk("%s ENOENT\n", __func__);
++ return;
++ }
++ AICBT_DBG("%s: OUT", __func__);
++
++ if (!test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
++ printk("%s BTUSB_BULK_RUNNING\n", __func__);
++ return;
++ }
++ usb_anchor_urb(urb, &data->bulk_anchor);
++ usb_mark_last_busy(data->udev);
++
++ //printk("LIULI bulk submit\n");
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ /* -EPERM: urb is being killed;
++ * -ENODEV: device got disconnected */
++ if (err != -EPERM && err != -ENODEV)
++ AICBT_ERR("btusb_bulk_complete %s urb %p failed to resubmit (%d)",
++ hdev->name, urb, -err);
++ usb_unanchor_urb(urb);
++ }
++}
++
++static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct urb *urb;
++ unsigned char *buf;
++ unsigned int pipe;
++ int err, size = HCI_MAX_FRAME_SIZE;
++
++ AICBT_DBG("%s: hdev name %s", __func__, hdev->name);
++ AICBT_DBG("%s: mMaxPacketSize %d, bEndpointAddress 0x%02x",
++ __func__, size, data->bulk_rx_ep->bEndpointAddress);
++
++ if (!data->bulk_rx_ep)
++ return -ENODEV;
++
++ urb = usb_alloc_urb(0, mem_flags);
++ if (!urb)
++ return -ENOMEM;
++
++ buf = kmalloc(size, mem_flags);
++ if (!buf) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
++
++ usb_fill_bulk_urb(urb, data->udev, pipe,
++ buf, size, btusb_bulk_complete, hdev);
++
++ urb->transfer_flags |= URB_FREE_BUFFER;
++
++ usb_mark_last_busy(data->udev);
++ usb_anchor_urb(urb, &data->bulk_anchor);
++
++ err = usb_submit_urb(urb, mem_flags);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d", __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++
++ usb_free_urb(urb);
++
++ return err;
++}
++
++static void btusb_isoc_complete(struct urb *urb)
++{
++ struct hci_dev *hdev = urb->context;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int i, err;
++ unsigned int total_length = 0;
++
++ AICBT_DBG("%s: urb %p status %d count %d",
++ __func__, urb, urb->status, urb->actual_length);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ return;
++
++ if (urb->status == 0) {
++ for (i = 0; i < urb->number_of_packets; i++) {
++ unsigned int offset = urb->iso_frame_desc[i].offset;
++ unsigned int length = urb->iso_frame_desc[i].actual_length;
++ //u8 *data = (u8 *)(urb->transfer_buffer + offset);
++ //AICBT_DBG("%d,%d ,%x,%x,%x s %d.",
++ //offset, length, data[0], data[1],data[2],urb->iso_frame_desc[i].status);
++
++ if(total_length >= urb->actual_length){
++ AICBT_ERR("total_len >= actual_length ,return");
++ break;
++ }
++ total_length += length;
++
++ if (urb->iso_frame_desc[i].status)
++ continue;
++
++ hdev->stat.byte_rx += length;
++ if(length){
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
++ if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
++ urb->transfer_buffer + offset,
++ length) < 0) {
++ AICBT_ERR("%s: Corrupted SCO packet", __func__);
++ hdev->stat.err_rx++;
++ }
++#else
++ if (btusb_recv_isoc(data, urb->transfer_buffer + offset,
++ length) < 0) {
++ AICBT_ERR("%s corrupted SCO packet",
++ hdev->name);
++ hdev->stat.err_rx++;
++ }
++#endif
++
++ }
++ }
++ }
++ /* Avoid suspend failed when usb_kill_urb */
++ else if(urb->status == -ENOENT) {
++ return;
++ }
++
++
++ if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
++ return;
++
++ usb_anchor_urb(urb, &data->isoc_anchor);
++ i = 0;
++retry:
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ /* -EPERM: urb is being killed;
++ * -ENODEV: device got disconnected */
++ if (err != -EPERM && err != -ENODEV)
++ AICBT_ERR("%s: Failed to re-sumbit urb %p, retry %d, err %d",
++ __func__, urb, i, err);
++ if (i < 10) {
++ i++;
++ mdelay(1);
++ goto retry;
++ }
++
++ usb_unanchor_urb(urb);
++ }
++}
++
++static inline void fill_isoc_descriptor(struct urb *urb, int len, int mtu)
++{
++ int i, offset = 0;
++
++ AICBT_DBG("%s: len %d mtu %d", __func__, len, mtu);
++
++ for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
++ i++, offset += mtu, len -= mtu) {
++ urb->iso_frame_desc[i].offset = offset;
++ urb->iso_frame_desc[i].length = mtu;
++ }
++
++ if (len && i < BTUSB_MAX_ISOC_FRAMES) {
++ urb->iso_frame_desc[i].offset = offset;
++ urb->iso_frame_desc[i].length = len;
++ i++;
++ }
++
++ urb->number_of_packets = i;
++}
++
++static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct urb *urb;
++ unsigned char *buf;
++ unsigned int pipe;
++ int err, size;
++ int interval;
++
++ if (!data->isoc_rx_ep)
++ return -ENODEV;
++ AICBT_DBG("%s: mMaxPacketSize %d, bEndpointAddress 0x%02x",
++ __func__, size, data->isoc_rx_ep->bEndpointAddress);
++
++ urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags);
++ if (!urb)
++ return -ENOMEM;
++
++ size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
++ BTUSB_MAX_ISOC_FRAMES;
++
++ buf = kmalloc(size, mem_flags);
++ if (!buf) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
++
++ urb->dev = data->udev;
++ urb->pipe = pipe;
++ urb->context = hdev;
++ urb->complete = btusb_isoc_complete;
++ if (urb->dev->speed == USB_SPEED_HIGH || urb->dev->speed >= USB_SPEED_SUPER) {
++ /* make sure interval is within allowed range */
++ interval = clamp((int)data->isoc_rx_ep->bInterval, 1, 16);
++ urb->interval = 1 << (interval - 1);
++ } else {
++ urb->interval = data->isoc_rx_ep->bInterval;
++ }
++
++ AICBT_INFO("urb->interval %d \r\n", urb->interval);
++
++ urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
++ urb->transfer_buffer = buf;
++ urb->transfer_buffer_length = size;
++
++ fill_isoc_descriptor(urb, size,
++ le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
++
++ usb_anchor_urb(urb, &data->isoc_anchor);
++
++ err = usb_submit_urb(urb, mem_flags);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d", __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++
++ usb_free_urb(urb);
++
++ return err;
++}
++
++static void btusb_tx_complete(struct urb *urb)
++{
++ struct sk_buff *skb = urb->context;
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ goto done;
++
++ if (!urb->status)
++ hdev->stat.byte_tx += urb->transfer_buffer_length;
++ else
++ hdev->stat.err_tx++;
++
++done:
++ spin_lock(&data->txlock);
++ data->tx_in_flight--;
++ spin_unlock(&data->txlock);
++
++ kfree(urb->setup_packet);
++
++ kfree_skb(skb);
++}
++
++static void btusb_isoc_tx_complete(struct urb *urb)
++{
++ struct sk_buff *skb = urb->context;
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ AICBT_DBG("%s: urb %p status %d count %d",
++ __func__, urb, urb->status, urb->actual_length);
++
++ if (skb && hdev) {
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ goto done;
++
++ if (!urb->status)
++ hdev->stat.byte_tx += urb->transfer_buffer_length;
++ else
++ hdev->stat.err_tx++;
++ } else
++ AICBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev);
++
++done:
++ kfree(urb->setup_packet);
++
++ kfree_skb(skb);
++}
++
++#if (CONFIG_BLUEDROID == 0)
++#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 0, 9)
++static int btusb_shutdown(struct hci_dev *hdev)
++{
++ struct sk_buff *skb;
++ printk("aic %s\n", __func__);
++
++ skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ printk("HCI reset during shutdown failed\n");
++ return PTR_ERR(skb);
++ }
++ kfree_skb(skb);
++
++ return 0;
++}
++#endif
++#endif //(CONFIG_BLUEDROID == 0)
++
++static int btusb_open(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int err = 0;
++
++ AICBT_INFO("%s: Start", __func__);
++
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ return err;
++
++ data->intf->needs_remote_wakeup = 1;
++
++#if (CONFIG_BLUEDROID == 0)
++ //err = download_patch(data->fw_info,1);
++ printk(" download_patch %d", err);
++ if (err < 0) {
++ goto failed;
++ }
++#endif
++
++
++ if (test_and_set_bit(HCI_RUNNING, &hdev->flags)){
++ goto done;
++ }
++
++ if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags)){
++ goto done;
++ }
++
++ err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
++ if (err < 0)
++ goto failed;
++
++ err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
++ if (err < 0) {
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->intr_anchor);
++ goto failed;
++ }
++
++ set_bit(BTUSB_BULK_RUNNING, &data->flags);
++ btusb_submit_bulk_urb(hdev, GFP_KERNEL);
++
++done:
++ usb_autopm_put_interface(data->intf);
++ AICBT_INFO("%s: End", __func__);
++ return 0;
++
++failed:
++ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
++ clear_bit(HCI_RUNNING, &hdev->flags);
++ usb_autopm_put_interface(data->intf);
++ AICBT_ERR("%s: Failed", __func__);
++ return err;
++}
++
++static void btusb_stop_traffic(struct btusb_data *data)
++{
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->intr_anchor);
++ usb_kill_anchored_urbs(&data->bulk_anchor);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++}
++
++static int btusb_close(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(4, 1, 0))
++ int i;
++#endif
++ int err;
++
++ AICBT_INFO("%s: hci running %lu", __func__, hdev->flags & HCI_RUNNING);
++
++ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)){
++ return 0;
++ }
++
++ if (!test_and_clear_bit(BTUSB_INTR_RUNNING, &data->flags)){
++ return 0;
++ }
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(4, 1, 0))
++ for (i = 0; i < NUM_REASSEMBLY; i++) {
++ if (hdev->reassembly[i]) {
++ AICBT_DBG("%s: free ressembly[%d]", __func__, i);
++ kfree_skb(hdev->reassembly[i]);
++ hdev->reassembly[i] = NULL;
++ }
++ }
++#endif
++
++ cancel_work_sync(&data->work);
++ cancel_work_sync(&data->waker);
++
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ clear_bit(BTUSB_BULK_RUNNING, &data->flags);
++ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
++
++ btusb_stop_traffic(data);
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ goto failed;
++
++ data->intf->needs_remote_wakeup = 0;
++ usb_autopm_put_interface(data->intf);
++
++failed:
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_scuttle_anchored_urbs(&data->deferred);
++ return 0;
++}
++
++static int btusb_flush(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ AICBT_DBG("%s", __func__);
++
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->tx_anchor);
++
++ return 0;
++}
++
++#ifdef CONFIG_SCO_OVER_HCI
++static void btusb_isoc_snd_tx_complete(struct urb *urb);
++
++static int snd_send_sco_frame(struct sk_buff *skb)
++{
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ //struct usb_ctrlrequest *dr;
++ struct urb *urb;
++ unsigned int pipe;
++ int err;
++
++ AICBT_DBG("%s:pkt type %d, packet_len : %d",
++ __func__,bt_cb(skb)->pkt_type, skb->len);
++
++ if (!hdev && !test_bit(HCI_RUNNING, &hdev->flags))
++ return -EBUSY;
++
++ if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) {
++ kfree(skb);
++ return -ENODEV;
++ }
++
++ urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
++ if (!urb) {
++ AICBT_ERR("%s: Failed to allocate mem for sco pkts", __func__);
++ kfree(skb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress);
++
++ usb_fill_int_urb(urb, data->udev, pipe,
++ skb->data, skb->len, btusb_isoc_snd_tx_complete,
++ skb, data->isoc_tx_ep->bInterval);
++
++ urb->transfer_flags = URB_ISO_ASAP;
++
++ fill_isoc_descriptor(urb, skb->len,
++ le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
++
++ hdev->stat.sco_tx++;
++
++ usb_anchor_urb(urb, &data->tx_anchor);
++
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d",
++ __func__, urb, bt_cb(skb)->pkt_type, err);
++ kfree(urb->setup_packet);
++ usb_unanchor_urb(urb);
++ } else
++ usb_mark_last_busy(data->udev);
++ usb_free_urb(urb);
++
++ return err;
++
++}
++
++static bool snd_copy_send_sco_data( AIC_sco_card_t *pSCOSnd)
++{
++ struct snd_pcm_runtime *runtime = pSCOSnd->playback.substream->runtime;
++ unsigned int frame_bytes = 2, frames1;
++ const u8 *source;
++
++ snd_pcm_uframes_t period_size = runtime->period_size;
++ int i, count;
++ u8 buffer[period_size * 3];
++ int sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes;
++ struct sk_buff *skb;
++
++ count = frames_to_bytes(runtime, period_size)/sco_packet_bytes;
++ skb = bt_skb_alloc(((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count), GFP_ATOMIC);
++ skb->dev = (void *)hci_dev_get(0);
++ bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
++ skb_put(skb, ((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count));
++ if(!skb)
++ return false;
++
++ AICBT_DBG("%s, buffer_pos:%d sco_handle:%d sco_packet_bytes:%d count:%d", __FUNCTION__, pSCOSnd->playback.buffer_pos, pSCOSnd->usb_data->sco_handle,
++ sco_packet_bytes, count);
++
++ source = runtime->dma_area + pSCOSnd->playback.buffer_pos * frame_bytes;
++
++ if (pSCOSnd->playback.buffer_pos + period_size <= runtime->buffer_size) {
++ memcpy(buffer, source, period_size * frame_bytes);
++ } else {
++ /* wrap around at end of ring buffer */
++ frames1 = runtime->buffer_size - pSCOSnd->playback.buffer_pos;
++ memcpy(buffer, source, frames1 * frame_bytes);
++ memcpy(&buffer[frames1 * frame_bytes],
++ runtime->dma_area, (period_size - frames1) * frame_bytes);
++ }
++
++ pSCOSnd->playback.buffer_pos += period_size;
++ if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size)
++ pSCOSnd->playback.buffer_pos -= runtime->buffer_size;
++
++ for(i = 0; i < count; i++) {
++ *((__u16 *)(skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE))) = pSCOSnd->usb_data->sco_handle;
++ *((__u8 *)(skb->data + i*(sco_packet_bytes + HCI_SCO_HDR_SIZE) + 2)) = sco_packet_bytes;
++ memcpy((skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE) + HCI_SCO_HDR_SIZE),
++ &buffer[sco_packet_bytes * i], sco_packet_bytes);
++ }
++
++ if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ snd_pcm_period_elapsed(pSCOSnd->playback.substream);
++ }
++ snd_send_sco_frame(skb);
++ return true;
++}
++
++static void btusb_isoc_snd_tx_complete(struct urb *urb)
++{
++ struct sk_buff *skb = urb->context;
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++
++ AICBT_DBG("%s: status %d count %d",
++ __func__,urb->status, urb->actual_length);
++
++ if (skb && hdev) {
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ goto done;
++
++ if (!urb->status)
++ hdev->stat.byte_tx += urb->transfer_buffer_length;
++ else
++ hdev->stat.err_tx++;
++ } else
++ AICBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev);
++
++done:
++ kfree(urb->setup_packet);
++ kfree_skb(skb);
++ if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)){
++ snd_copy_send_sco_data(pSCOSnd);
++ //schedule_work(&pSCOSnd->send_sco_work);
++ }
++}
++
++static void playback_work(struct work_struct *work)
++{
++ AIC_sco_card_t *pSCOSnd = container_of(work, AIC_sco_card_t, send_sco_work);
++
++ snd_copy_send_sco_data(pSCOSnd);
++}
++
++#endif
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
++int btusb_send_frame(struct sk_buff *skb)
++{
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++#else
++int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
++{
++#endif
++ //struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct usb_ctrlrequest *dr;
++ struct urb *urb;
++ unsigned int pipe;
++ int err = 0;
++ int retries = 0;
++ u16 *opcode = NULL;
++
++ AICBT_DBG("%s: hdev %p, btusb data %p, pkt type %d",
++ __func__, hdev, data, bt_cb(skb)->pkt_type);
++
++ //printk("aic %d %d\r\n", bt_cb(skb)->pkt_type, skb->len);
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ return -EBUSY;
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
++ skb->dev = (void *)hdev;
++#endif
++#endif
++
++ switch (bt_cb(skb)->pkt_type) {
++ case HCI_COMMAND_PKT:
++ print_command(skb);
++ urb = usb_alloc_urb(0, GFP_ATOMIC);
++ if (!urb)
++ return -ENOMEM;
++
++ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
++ if (!dr) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ dr->bRequestType = data->cmdreq_type;
++ dr->bRequest = 0;
++ dr->wIndex = 0;
++ dr->wValue = 0;
++ dr->wLength = __cpu_to_le16(skb->len);
++
++ pipe = usb_sndctrlpipe(data->udev, 0x00);
++
++ usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
++ skb->data, skb->len, btusb_tx_complete, skb);
++
++ hdev->stat.cmd_tx++;
++ break;
++
++ case HCI_ACLDATA_PKT:
++ if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
++ print_command(skb);
++ opcode = (u16*)(skb->data);
++ printk("aic cmd:0x%04x", *opcode);
++ } else {
++ print_acl(skb, 1);
++ }
++ if (!data->bulk_tx_ep)
++ return -ENODEV;
++
++ urb = usb_alloc_urb(0, GFP_ATOMIC);
++ if (!urb)
++ return -ENOMEM;
++
++ pipe = usb_sndbulkpipe(data->udev,
++ data->bulk_tx_ep->bEndpointAddress);
++
++ usb_fill_bulk_urb(urb, data->udev, pipe,
++ skb->data, skb->len, btusb_tx_complete, skb);
++
++ hdev->stat.acl_tx++;
++ break;
++
++ case HCI_SCODATA_PKT:
++ print_sco(skb, 1);
++ if (!data->isoc_tx_ep || SCO_NUM < 1) {
++ kfree(skb);
++ return -ENODEV;
++ }
++
++ urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
++ if (!urb) {
++ AICBT_ERR("%s: Failed to allocate mem for sco pkts", __func__);
++ kfree(skb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress);
++
++ usb_fill_int_urb(urb, data->udev, pipe,
++ skb->data, skb->len, btusb_isoc_tx_complete,
++ skb, data->isoc_tx_ep->bInterval);
++
++ urb->transfer_flags = URB_ISO_ASAP;
++
++ fill_isoc_descriptor(urb, skb->len,
++ le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
++
++ hdev->stat.sco_tx++;
++ goto skip_waking;
++
++ default:
++ return -EILSEQ;
++ }
++
++ err = inc_tx(data);
++ if (err) {
++ usb_anchor_urb(urb, &data->deferred);
++ schedule_work(&data->waker);
++ err = 0;
++ goto done;
++ }
++
++skip_waking:
++ usb_anchor_urb(urb, &data->tx_anchor);
++retry:
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d, retries %d",
++ __func__, urb, bt_cb(skb)->pkt_type, err, retries);
++ if ((bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) && (retries < 10)) {
++ mdelay(1);
++
++ if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT)
++ print_error_command(skb);
++ retries++;
++ goto retry;
++ }
++ kfree(urb->setup_packet);
++ usb_unanchor_urb(urb);
++ } else
++ usb_mark_last_busy(data->udev);
++ usb_free_urb(urb);
++
++done:
++ return err;
++}
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++static void btusb_destruct(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ AICBT_DBG("%s: name %s", __func__, hdev->name);
++
++ kfree(data);
++}
++#endif
++
++static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ AICBT_DBG("%s: name %s, evt %d", __func__, hdev->name, evt);
++
++ if (SCO_NUM != data->sco_num) {
++ data->sco_num = SCO_NUM;
++ schedule_work(&data->work);
++ }
++}
++
++static inline int set_isoc_interface(struct hci_dev *hdev, int altsetting)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct usb_interface *intf = data->isoc;
++ struct usb_endpoint_descriptor *ep_desc;
++ int i, err;
++
++ if (!data->isoc)
++ return -ENODEV;
++
++ err = usb_set_interface(data->udev, 1, altsetting);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to set interface, altsetting %d, err %d",
++ __func__, altsetting, err);
++ return err;
++ }
++
++ data->isoc_altsetting = altsetting;
++
++ data->isoc_tx_ep = NULL;
++ data->isoc_rx_ep = NULL;
++
++ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
++ ep_desc = &intf->cur_altsetting->endpoint[i].desc;
++
++ if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
++ data->isoc_tx_ep = ep_desc;
++ continue;
++ }
++
++ if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
++ data->isoc_rx_ep = ep_desc;
++ continue;
++ }
++ }
++
++ if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
++ AICBT_ERR("%s: Invalid SCO descriptors", __func__);
++ return -ENODEV;
++ }
++
++ AICBT_ERR("%s: hdev->reassembly implemant\r\n",
++ __func__);
++
++#if CONFIG_BLUEDROID
++ if(hdev->reassembly[HCI_SCODATA_PKT - 1]) {
++ kfree_skb(hdev->reassembly[HCI_SCODATA_PKT - 1]);
++ hdev->reassembly[HCI_SCODATA_PKT - 1] = NULL;
++ }
++#endif
++ return 0;
++}
++
++static void set_select_msbc(enum CODEC_TYPE type)
++{
++ printk("%s codec type = %d", __func__, (int)type);
++ codec_type = type;
++}
++
++static enum CODEC_TYPE check_select_msbc(void)
++{
++ return codec_type;
++}
++
++#ifdef CONFIG_SCO_OVER_HCI
++static int check_controller_support_msbc( struct usb_device *udev)
++{
++ //fix this in the future,when new card support msbc decode and encode
++ AICBT_INFO("%s:pid = 0x%02x, vid = 0x%02x",__func__,udev->descriptor.idProduct, udev->descriptor.idVendor);
++ switch (udev->descriptor.idProduct) {
++
++ default:
++ return 0;
++ }
++ return 0;
++}
++#endif
++static void btusb_work(struct work_struct *work)
++{
++ struct btusb_data *data = container_of(work, struct btusb_data, work);
++ struct hci_dev *hdev = data->hdev;
++ int err;
++ int new_alts;
++#ifdef CONFIG_SCO_OVER_HCI
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++#endif
++ printk("%s data->sco_num:%d \r\n", __func__, data->sco_num);
++
++ if (data->sco_num > 0) {
++ if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
++ err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
++ if (err < 0) {
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++ printk("%s usb_kill_anchored_urbs after \r\n", __func__);
++ return;
++ }
++
++ set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
++ }
++
++ hdev->voice_setting = 93;
++ AICBT_INFO("%s voice settings = 0x%04x", __func__, hdev->voice_setting);
++ if (!(hdev->voice_setting & 0x0003)) {
++ if(data->sco_num == 1)
++ if(check_select_msbc()) {
++ new_alts = 1;
++ } else {
++ new_alts = 2;
++ }
++ else {
++ AICBT_INFO("%s: we don't support mutiple sco link for cvsd", __func__);
++ return;
++ }
++ } else{
++ if(check_select_msbc()) {
++ if(data->sco_num == 1)
++ new_alts = 1;
++ else {
++ AICBT_INFO("%s: we don't support mutiple sco link for msbc", __func__);
++ return;
++ }
++ } else {
++ new_alts = 2;
++ }
++ }
++ if (data->isoc_altsetting != new_alts) {
++
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++
++ printk("%s set_isoc_interface in \r\n", __func__);
++ if (set_isoc_interface(hdev, new_alts) < 0)
++ return;
++
++ }
++
++ printk("%s set_isoc_interface out \r\n", __func__);
++
++ if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
++ printk("%s btusb_submit_isoc_urb\r\n", __func__);
++ if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ else
++ btusb_submit_isoc_urb(hdev, GFP_KERNEL);
++ }
++#ifdef CONFIG_SCO_OVER_HCI
++ if(test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
++ set_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states);
++ set_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states);
++ }
++ if (test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ schedule_work(&pSCOSnd->send_sco_work);
++ AICBT_INFO("%s: play_timer restart", __func__);
++ }
++#endif
++ } else {
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++#ifdef CONFIG_SCO_OVER_HCI
++ clear_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states);
++ clear_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states);
++ //AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++ if (test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(30));
++ AICBT_INFO("%s: play_timer start", __func__);
++ }
++#endif
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++
++ set_isoc_interface(hdev, 0);
++ if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
++ usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
++ }
++}
++
++static void btusb_waker(struct work_struct *work)
++{
++ struct btusb_data *data = container_of(work, struct btusb_data, waker);
++ int err;
++
++ AICBT_DBG("%s", __func__);
++
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ return;
++
++ usb_autopm_put_interface(data->intf);
++}
++
++int bt_pm_notify(struct notifier_block *notifier, ulong pm_event, void *unused)
++{
++ struct btusb_data *data;
++ firmware_info *fw_info;
++ struct usb_device *udev;
++
++ AICBT_INFO("%s: pm event %ld", __func__, pm_event);
++
++ data = container_of(notifier, struct btusb_data, pm_notifier);
++ fw_info = data->fw_info;
++ udev = fw_info->udev;
++
++ switch (pm_event) {
++ case PM_SUSPEND_PREPARE:
++ case PM_HIBERNATION_PREPARE:
++#if 0
++ patch_entry->fw_len = load_firmware(fw_info, &patch_entry->fw_cache);
++ if (patch_entry->fw_len <= 0) {
++ /* We may encount failure in loading firmware, just give a warning */
++ AICBT_WARN("%s: Failed to load firmware", __func__);
++ }
++#endif
++ if (!device_may_wakeup(&udev->dev)) {
++#if (CONFIG_RESET_RESUME || CONFIG_BLUEDROID)
++ AICBT_INFO("%s:remote wakeup not supported, reset resume supported", __func__);
++#else
++ fw_info->intf->needs_binding = 1;
++ AICBT_INFO("%s:remote wakeup not supported, binding needed", __func__);
++#endif
++ }
++ break;
++
++ case PM_POST_SUSPEND:
++ case PM_POST_HIBERNATION:
++ case PM_POST_RESTORE:
++#if 0
++ /* Reclaim fw buffer when bt usb resumed */
++ if (patch_entry->fw_len > 0) {
++ kfree(patch_entry->fw_cache);
++ patch_entry->fw_cache = NULL;
++ patch_entry->fw_len = 0;
++ }
++#endif
++
++#if BTUSB_RPM
++ usb_disable_autosuspend(udev);
++ usb_enable_autosuspend(udev);
++ pm_runtime_set_autosuspend_delay(&(udev->dev), 2000);
++#endif
++ break;
++
++ default:
++ break;
++ }
++
++ return NOTIFY_DONE;
++}
++
++int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unused)
++{
++ struct btusb_data *data;
++ firmware_info *fw_info;
++ struct usb_device *udev;
++
++ AICBT_INFO("%s: pm event %ld", __func__, pm_event);
++
++ data = container_of(notifier, struct btusb_data, reboot_notifier);
++ fw_info = data->fw_info;
++ udev = fw_info->udev;
++
++ switch (pm_event) {
++ case SYS_DOWN:
++ AICBT_DBG("%s:system down or restart", __func__);
++ break;
++
++ case SYS_HALT:
++ case SYS_POWER_OFF:
++#if SUSPNED_DW_FW
++ cancel_work_sync(&data->work);
++
++ btusb_stop_traffic(data);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->tx_anchor);
++
++
++ if(fw_info_4_suspend) {
++ download_suspend_patch(fw_info_4_suspend,1);
++ }
++ else
++ AICBT_ERR("%s: Failed to download suspend fw", __func__);
++#endif
++
++#ifdef SET_WAKEUP_DEVICE
++ set_wakeup_device_from_conf(fw_info_4_suspend);
++#endif
++ AICBT_DBG("%s:system halt or power off", __func__);
++ break;
++
++ default:
++ break;
++ }
++
++ return NOTIFY_DONE;
++}
++
++
++#ifdef CONFIG_SCO_OVER_HCI
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++void aic_snd_capture_timeout(ulong data)
++#else
++void aic_snd_capture_timeout(struct timer_list *t)
++#endif
++{
++ uint8_t null_data[255];
++ struct btusb_data *usb_data;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ usb_data = (struct btusb_data *)data;
++#else
++ usb_data = &snd_cap_timer.snd_usb_data;
++#endif
++ aic_copy_capture_data_to_alsa(usb_data, null_data, snd_cap_timer.snd_sco_length/2);
++ //printk("%s enter\r\n", __func__);
++ mod_timer(&snd_cap_timer.cap_timer,jiffies + msecs_to_jiffies(3));
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++void aic_snd_play_timeout(ulong data)
++#else
++void aic_snd_play_timeout(struct timer_list *t)
++#endif
++{
++ AIC_sco_card_t *pSCOSnd;
++ struct snd_pcm_runtime *runtime;
++ snd_pcm_uframes_t period_size;
++ int count;
++ struct btusb_data *usb_data;
++ int sco_packet_bytes;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ usb_data = (struct btusb_data *)data;
++#else
++ usb_data = &snd_cap_timer.snd_usb_data;
++#endif
++ pSCOSnd = usb_data->pSCOSnd;
++
++ if(test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ return;
++ }
++
++ if(!test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ return;
++ }
++
++ runtime = pSCOSnd->playback.substream->runtime;
++ period_size = runtime->period_size;
++ sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes;
++ count = frames_to_bytes(runtime, period_size)/sco_packet_bytes;
++
++ pSCOSnd->playback.buffer_pos += period_size;
++ if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size)
++ pSCOSnd->playback.buffer_pos -= runtime->buffer_size;
++
++ if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ snd_pcm_period_elapsed(pSCOSnd->playback.substream);
++ }
++ //AICBT_DBG("%s,play_timer restart buffer_pos:%d sco_handle:%d sco_packet_bytes:%d count:%d", __FUNCTION__, pSCOSnd->playback.buffer_pos, pSCOSnd->usb_data->sco_handle,
++ //sco_packet_bytes, count);
++ mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(3*count));
++}
++
++static const struct snd_pcm_hardware snd_card_sco_capture_default =
++{
++ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED |
++ SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
++ .rates = (SNDRV_PCM_RATE_8000),
++ .rate_min = 8000,
++ .rate_max = 8000,
++ .channels_min = 1,
++ .channels_max = 1,
++ .buffer_bytes_max = 8 * 768,
++ .period_bytes_min = 48,
++ .period_bytes_max = 768,
++ .periods_min = 1,
++ .periods_max = 8,
++ .fifo_size = 8,
++
++};
++
++static int snd_sco_capture_pcm_open(struct snd_pcm_substream * substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ AICBT_INFO("%s", __FUNCTION__);
++ pSCOSnd->capture.substream = substream;
++
++ memcpy(&substream->runtime->hw, &snd_card_sco_capture_default, sizeof(struct snd_pcm_hardware));
++ pSCOSnd->capture.buffer_pos = 0;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ init_timer(&snd_cap_timer.cap_timer);
++ snd_cap_timer.cap_timer.data = (unsigned long)pSCOSnd->usb_data;
++ snd_cap_timer.cap_timer.function = aic_snd_capture_timeout;
++#else
++ timer_setup(&snd_cap_timer.cap_timer, aic_snd_capture_timeout, 0);
++ snd_cap_timer.snd_usb_data = *(pSCOSnd->usb_data);
++#endif
++
++ if(check_controller_support_msbc(pSCOSnd->dev)) {
++ substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000;
++ substream->runtime->hw.rate_max = 16000;
++ substream->runtime->hw.period_bytes_min = 96;
++ substream->runtime->hw.period_bytes_max = 16 * 96;
++ substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96;
++ }
++ set_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states);
++ return 0;
++}
++
++static int snd_sco_capture_pcm_close(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ del_timer(&snd_cap_timer.cap_timer);
++ clear_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states);
++ return 0;
++}
++
++static int snd_sco_capture_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg)
++{
++ AICBT_DBG("%s, cmd = %d", __FUNCTION__, cmd);
++ switch (cmd)
++ {
++ default:
++ return snd_pcm_lib_ioctl(substream, cmd, arg);
++ }
++ return 0;
++}
++
++static int snd_sco_capture_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params)
++{
++
++ int err;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params));
++ AICBT_INFO("%s,err : %d, runtime state : %d", __FUNCTION__, err, runtime->status->state);
++ return err;
++}
++
++static int snd_sco_capture_pcm_hw_free(struct snd_pcm_substream * substream)
++{
++ AICBT_DBG("%s", __FUNCTION__);
++ return snd_pcm_lib_free_vmalloc_buffer(substream);;
++}
++
++static int snd_sco_capture_pcm_prepare(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++
++ AICBT_INFO("%s %d\n", __FUNCTION__, (int)runtime->period_size);
++ if (test_bit(DISCONNECTED, &pSCOSnd->states))
++ return -ENODEV;
++ if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states))
++ return -EIO;
++
++ if(runtime->rate == 8000) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 2)
++ return -ENOEXEC;
++ pSCOSnd->capture.sco_packet_bytes = 48;
++ }
++ else if(runtime->rate == 16000 && check_controller_support_msbc(pSCOSnd->dev)) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 4)
++ return -ENOEXEC;
++ pSCOSnd->capture.sco_packet_bytes = 96;
++ }
++ else if(pSCOSnd->usb_data->isoc_altsetting == 2) {
++ pSCOSnd->capture.sco_packet_bytes = 48;
++ }
++ else if(pSCOSnd->usb_data->isoc_altsetting == 1) {
++ pSCOSnd->capture.sco_packet_bytes = 24;
++ }
++ return 0;
++}
++
++static int snd_sco_capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ AICBT_INFO("%s, cmd : %d", __FUNCTION__, cmd);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states))
++ return -EIO;
++ set_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states);
++ return 0;
++ case SNDRV_PCM_TRIGGER_STOP:
++ clear_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states);
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static snd_pcm_uframes_t snd_sco_capture_pcm_pointer(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ return pSCOSnd->capture.buffer_pos;
++}
++
++
++static struct snd_pcm_ops snd_sco_capture_pcm_ops = {
++ .open = snd_sco_capture_pcm_open,
++ .close = snd_sco_capture_pcm_close,
++ .ioctl = snd_sco_capture_ioctl,
++ .hw_params = snd_sco_capture_pcm_hw_params,
++ .hw_free = snd_sco_capture_pcm_hw_free,
++ .prepare = snd_sco_capture_pcm_prepare,
++ .trigger = snd_sco_capture_pcm_trigger,
++ .pointer = snd_sco_capture_pcm_pointer,
++};
++
++
++static const struct snd_pcm_hardware snd_card_sco_playback_default =
++{
++ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED |
++ SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .rates = (SNDRV_PCM_RATE_8000),
++ .rate_min = 8000,
++ .rate_max = 8000,
++ .channels_min = 1,
++ .channels_max = 1,
++ .buffer_bytes_max = 8 * 768,
++ .period_bytes_min = 48,
++ .period_bytes_max = 768,
++ .periods_min = 1,
++ .periods_max = 8,
++ .fifo_size = 8,
++};
++
++static int snd_sco_playback_pcm_open(struct snd_pcm_substream * substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ int err = 0;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ init_timer(&snd_cap_timer.play_timer);
++ snd_cap_timer.play_timer.data = (unsigned long)pSCOSnd->usb_data;
++ snd_cap_timer.play_timer.function = aic_snd_play_timeout;
++#else
++ timer_setup(&snd_cap_timer.play_timer, aic_snd_play_timeout, 0);
++ snd_cap_timer.snd_usb_data = *(pSCOSnd->usb_data);
++#endif
++ pSCOSnd->playback.buffer_pos = 0;
++
++ AICBT_INFO("%s, rate : %d", __FUNCTION__, substream->runtime->rate);
++ memcpy(&substream->runtime->hw, &snd_card_sco_playback_default, sizeof(struct snd_pcm_hardware));
++ if(check_controller_support_msbc(pSCOSnd->dev)) {
++ substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000;
++ substream->runtime->hw.rate_max = 16000;
++ substream->runtime->hw.period_bytes_min = 96;
++ substream->runtime->hw.period_bytes_max = 16 * 96;
++ substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96;
++ }
++ pSCOSnd->playback.substream = substream;
++ set_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states);
++
++ return err;
++}
++
++static int snd_sco_playback_pcm_close(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ del_timer(&snd_cap_timer.play_timer);
++ AICBT_INFO("%s: play_timer delete", __func__);
++ clear_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states);
++ cancel_work_sync(&pSCOSnd->send_sco_work);
++ return 0;
++}
++
++static int snd_sco_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg)
++{
++ AICBT_DBG("%s, cmd : %d", __FUNCTION__, cmd);
++ switch (cmd)
++ {
++ default:
++ return snd_pcm_lib_ioctl(substream, cmd, arg);
++ break;
++ }
++ return 0;
++}
++
++static int snd_sco_playback_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params)
++{
++ int err;
++ err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params));
++ return err;
++}
++
++static int snd_sco_palyback_pcm_hw_free(struct snd_pcm_substream * substream)
++{
++ AICBT_DBG("%s", __FUNCTION__);
++ return snd_pcm_lib_free_vmalloc_buffer(substream);
++}
++
++static int snd_sco_playback_pcm_prepare(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++
++ AICBT_INFO("%s, bound_rate = %d", __FUNCTION__, runtime->rate);
++
++ if (test_bit(DISCONNECTED, &pSCOSnd->states))
++ return -ENODEV;
++ if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states))
++ return -EIO;
++
++ if(runtime->rate == 8000) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 2)
++ return -ENOEXEC;
++ pSCOSnd->playback.sco_packet_bytes = 48;
++ }
++ else if(runtime->rate == 16000) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 4)
++ return -ENOEXEC;
++ pSCOSnd->playback.sco_packet_bytes = 96;
++ }
++
++ return 0;
++}
++
++static int snd_sco_playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ AICBT_INFO("%s, cmd = %d", __FUNCTION__, cmd);
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states))
++ return -EIO;
++ set_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states);
++ schedule_work(&pSCOSnd->send_sco_work);
++#ifdef CONFIG_SCO_OVER_HCI
++ if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ AICBT_INFO("%s: play_timer cmd 1 start ", __func__);
++ mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(3));
++ }
++#endif
++ return 0;
++ case SNDRV_PCM_TRIGGER_STOP:
++ clear_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states);
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static snd_pcm_uframes_t snd_sco_playback_pcm_pointer(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ return pSCOSnd->playback.buffer_pos;
++}
++
++
++static struct snd_pcm_ops snd_sco_playback_pcm_ops = {
++ .open = snd_sco_playback_pcm_open,
++ .close = snd_sco_playback_pcm_close,
++ .ioctl = snd_sco_playback_ioctl,
++ .hw_params = snd_sco_playback_pcm_hw_params,
++ .hw_free = snd_sco_palyback_pcm_hw_free,
++ .prepare = snd_sco_playback_pcm_prepare,
++ .trigger = snd_sco_playback_pcm_trigger,
++ .pointer = snd_sco_playback_pcm_pointer,
++};
++
++
++static AIC_sco_card_t* btusb_snd_init(struct usb_interface *intf, const struct usb_device_id *id, struct btusb_data *data)
++{
++ struct snd_card *card;
++ AIC_sco_card_t *pSCOSnd;
++ int err=0;
++ AICBT_INFO("%s", __func__);
++ err = snd_card_new(&intf->dev,
++ -1, AIC_SCO_ID, THIS_MODULE,
++ sizeof(AIC_sco_card_t), &card);
++ if (err < 0) {
++ AICBT_ERR("%s: sco snd card create fail", __func__);
++ return NULL;
++ }
++ // private data
++ pSCOSnd = (AIC_sco_card_t *)card->private_data;
++ pSCOSnd->card = card;
++ pSCOSnd->dev = interface_to_usbdev(intf);
++ pSCOSnd->usb_data = data;
++
++ strcpy(card->driver, AIC_SCO_ID);
++ strcpy(card->shortname, "Aicsemi sco snd");
++ sprintf(card->longname, "Aicsemi sco over hci: VID:0x%04x, PID:0x%04x",
++ id->idVendor, pSCOSnd->dev->descriptor.idProduct);
++
++ err = snd_pcm_new(card, AIC_SCO_ID, 0, 1, 1, &pSCOSnd->pcm);
++ if (err < 0) {
++ AICBT_ERR("%s: sco snd card new pcm fail", __func__);
++ return NULL;
++ }
++ pSCOSnd->pcm->private_data = pSCOSnd;
++ sprintf(pSCOSnd->pcm->name, "sco_pcm:VID:0x%04x, PID:0x%04x",
++ id->idVendor, pSCOSnd->dev->descriptor.idProduct);
++
++ snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sco_playback_pcm_ops);
++ snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sco_capture_pcm_ops);
++
++ err = snd_card_register(card);
++ if (err < 0) {
++ AICBT_ERR("%s: sco snd card register card fail", __func__);
++ return NULL;
++ }
++
++ spin_lock_init(&pSCOSnd->capture_lock);
++ spin_lock_init(&pSCOSnd->playback_lock);
++ INIT_WORK(&pSCOSnd->send_sco_work, playback_work);
++ return pSCOSnd;
++}
++#endif
++
++static int aicwf_usb_chipmatch(u16 vid, u16 pid){
++
++ if(pid == USB_PRODUCT_ID_AIC8801){
++ g_chipid = PRODUCT_ID_AIC8801;
++ printk("%s USE AIC8801\r\n", __func__);
++ return 0;
++ }else if(pid == USB_PRODUCT_ID_AIC8800DC){
++ g_chipid = PRODUCT_ID_AIC8800DC;
++ printk("%s USE AIC8800DC\r\n", __func__);
++ return 0;
++ }else if(pid == USB_PRODUCT_ID_AIC8800D80){
++ g_chipid = PRODUCT_ID_AIC8800D80;
++ printk("%s USE AIC8800D80\r\n", __func__);
++ return 0;
++ }else{
++ return -1;
++ }
++}
++
++
++static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++ struct usb_device *udev = interface_to_usbdev(intf);
++ struct usb_endpoint_descriptor *ep_desc;
++ u8 endpoint_num;
++ struct btusb_data *data;
++ struct hci_dev *hdev;
++ firmware_info *fw_info;
++ int i, err=0;
++
++ bt_support = 1;
++
++ AICBT_INFO("%s: usb_interface %p, bInterfaceNumber %d, idVendor 0x%04x, "
++ "idProduct 0x%04x", __func__, intf,
++ intf->cur_altsetting->desc.bInterfaceNumber,
++ id->idVendor, id->idProduct);
++
++ aicwf_usb_chipmatch(id->idVendor, id->idProduct);
++
++ /* interface numbers are hardcoded in the spec */
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return -ENODEV;
++
++ AICBT_DBG("%s: can wakeup = %x, may wakeup = %x", __func__,
++ device_can_wakeup(&udev->dev), device_may_wakeup(&udev->dev));
++
++ data = aic_alloc(intf);
++ if (!data)
++ return -ENOMEM;
++
++ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
++ ep_desc = &intf->cur_altsetting->endpoint[i].desc;
++
++ endpoint_num = usb_endpoint_num(ep_desc);
++ printk("endpoint num %d\n", endpoint_num);
++
++ if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
++ data->intr_ep = ep_desc;
++ continue;
++ }
++
++ if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
++ data->bulk_tx_ep = ep_desc;
++ continue;
++ }
++
++ if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
++ data->bulk_rx_ep = ep_desc;
++ continue;
++ }
++ }
++
++ if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
++ aic_free(data);
++ return -ENODEV;
++ }
++
++ data->cmdreq_type = USB_TYPE_CLASS;
++
++ data->udev = udev;
++ data->intf = intf;
++
++ dlfw_dis_state = 0;
++ spin_lock_init(&queue_lock);
++ spin_lock_init(&dlfw_lock);
++ spin_lock_init(&data->lock);
++
++ INIT_WORK(&data->work, btusb_work);
++ INIT_WORK(&data->waker, btusb_waker);
++ spin_lock_init(&data->txlock);
++
++ init_usb_anchor(&data->tx_anchor);
++ init_usb_anchor(&data->intr_anchor);
++ init_usb_anchor(&data->bulk_anchor);
++ init_usb_anchor(&data->isoc_anchor);
++ init_usb_anchor(&data->deferred);
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++ spin_lock_init(&data->rxlock);
++ data->recv_bulk = btusb_recv_bulk;
++#endif
++#endif
++
++
++ fw_info = firmware_info_init(intf);
++ if (fw_info)
++ data->fw_info = fw_info;
++ else {
++ AICBT_WARN("%s: Failed to initialize fw info", __func__);
++ /* Skip download patch */
++ goto end;
++ }
++
++ AICBT_INFO("%s: download begining...", __func__);
++
++#if CONFIG_BLUEDROID
++ mutex_lock(&btchr_mutex);
++#endif
++ if(g_chipid == PRODUCT_ID_AIC8800DC){
++ err = download_patch(data->fw_info,1);
++ }
++
++#if CONFIG_BLUEDROID
++ mutex_unlock(&btchr_mutex);
++#endif
++
++ AICBT_INFO("%s: download ending...", __func__);
++ if (err < 0) {
++ return err;
++ }
++
++
++ hdev = hci_alloc_dev();
++ if (!hdev) {
++ aic_free(data);
++ data = NULL;
++ return -ENOMEM;
++ }
++
++ HDEV_BUS = HCI_USB;
++
++ data->hdev = hdev;
++
++ SET_HCIDEV_DEV(hdev, &intf->dev);
++
++ hdev->open = btusb_open;
++ hdev->close = btusb_close;
++ hdev->flush = btusb_flush;
++ hdev->send = btusb_send_frame;
++ hdev->notify = btusb_notify;
++#if (CONFIG_BLUEDROID == 0)
++#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 0, 9)
++ hdev->shutdown = btusb_shutdown;
++#endif
++#endif //(CONFIG_BLUEDROIF == 0)
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0)
++ hci_set_drvdata(hdev, data);
++#else
++ hdev->driver_data = data;
++ hdev->destruct = btusb_destruct;
++ hdev->owner = THIS_MODULE;
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 1)
++ if (!reset_on_close){
++ /* set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); */
++ AICBT_DBG("%s: Set HCI_QUIRK_RESET_ON_CLOSE", __func__);
++ }
++#endif
++
++ /* Interface numbers are hardcoded in the specification */
++ data->isoc = usb_ifnum_to_if(data->udev, 1);
++ if (data->isoc) {
++ err = usb_driver_claim_interface(&btusb_driver,
++ data->isoc, data);
++ if (err < 0) {
++ hci_free_dev(hdev);
++ hdev = NULL;
++ aic_free(data);
++ data = NULL;
++ return err;
++ }
++#ifdef CONFIG_SCO_OVER_HCI
++ data->pSCOSnd = btusb_snd_init(intf, id, data);
++#endif
++ }
++
++ err = hci_register_dev(hdev);
++ if (err < 0) {
++ hci_free_dev(hdev);
++ hdev = NULL;
++ aic_free(data);
++ data = NULL;
++ return err;
++ }
++
++ usb_set_intfdata(intf, data);
++
++//#ifdef CONFIG_HAS_EARLYSUSPEND
++#if 0
++ data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
++ data->early_suspend.suspend = btusb_early_suspend;
++ data->early_suspend.resume = btusb_late_resume;
++ register_early_suspend(&data->early_suspend);
++#else
++ data->pm_notifier.notifier_call = bt_pm_notify;
++ data->reboot_notifier.notifier_call = bt_reboot_notify;
++ register_pm_notifier(&data->pm_notifier);
++ register_reboot_notifier(&data->reboot_notifier);
++#endif
++
++#if CONFIG_BLUEDROID
++ AICBT_INFO("%s: Check bt reset flag %d", __func__, bt_reset);
++ /* Report hci hardware error after everthing is ready,
++ * especially hci register is completed. Or, btchr_poll
++ * will get null hci dev when hotplug in.
++ */
++ if (bt_reset == 1) {
++ hci_hardware_error();
++ bt_reset = 0;
++ } else
++ bt_reset = 0; /* Clear and reset it anyway */
++#endif
++
++end:
++ return 0;
++}
++
++static void btusb_disconnect(struct usb_interface *intf)
++{
++ struct btusb_data *data;
++ struct hci_dev *hdev = NULL;
++#if CONFIG_BLUEDROID
++ wait_event_interruptible(bt_dlfw_wait, (check_set_dlfw_state_value(2) == 2));
++#endif
++
++ bt_support = 0;
++
++ AICBT_INFO("%s: usb_interface %p, bInterfaceNumber %d",
++ __func__, intf, intf->cur_altsetting->desc.bInterfaceNumber);
++
++ data = usb_get_intfdata(intf);
++
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return;
++
++ if (data)
++ hdev = data->hdev;
++ else {
++ AICBT_WARN("%s: Failed to get bt usb data[Null]", __func__);
++ return;
++ }
++
++#ifdef CONFIG_SCO_OVER_HCI
++ if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++ if(!pSCOSnd) {
++ AICBT_ERR("%s: sco private data is null", __func__);
++ return;
++ }
++ set_bit(DISCONNECTED, &pSCOSnd->states);
++ snd_card_disconnect(pSCOSnd->card);
++ snd_card_free_when_closed(pSCOSnd->card);
++ }
++#endif
++
++//#ifdef CONFIG_HAS_EARLYSUSPEND
++#if 0
++ unregister_early_suspend(&data->early_suspend);
++#else
++ unregister_pm_notifier(&data->pm_notifier);
++ unregister_reboot_notifier(&data->reboot_notifier);
++#endif
++
++ firmware_info_destroy(intf);
++
++#if CONFIG_BLUEDROID
++ if (test_bit(HCI_RUNNING, &hdev->flags)) {
++ AICBT_INFO("%s: Set BT reset flag", __func__);
++ bt_reset = 1;
++ }
++#endif
++
++ usb_set_intfdata(data->intf, NULL);
++
++ if (data->isoc)
++ usb_set_intfdata(data->isoc, NULL);
++
++ hci_unregister_dev(hdev);
++
++ if (intf == data->isoc)
++ usb_driver_release_interface(&btusb_driver, data->intf);
++ else if (data->isoc)
++ usb_driver_release_interface(&btusb_driver, data->isoc);
++
++#if !CONFIG_BLUEDROID
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++ __hci_dev_put(hdev);
++#endif
++#endif
++
++ hci_free_dev(hdev);
++ aic_free(data);
++ data = NULL;
++ set_dlfw_state_value(0);
++}
++
++#ifdef CONFIG_PM
++static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
++{
++ struct btusb_data *data = usb_get_intfdata(intf);
++ //firmware_info *fw_info = data->fw_info;
++
++ AICBT_INFO("%s: event 0x%x, suspend count %d", __func__,
++ message.event, data->suspend_count);
++
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return 0;
++#if 0
++ if (!test_bit(HCI_RUNNING, &data->hdev->flags))
++ set_bt_onoff(fw_info, 1);
++#endif
++ if (data->suspend_count++)
++ return 0;
++
++ spin_lock_irq(&data->txlock);
++ if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
++ set_bit(BTUSB_SUSPENDING, &data->flags);
++ spin_unlock_irq(&data->txlock);
++ } else {
++ spin_unlock_irq(&data->txlock);
++ data->suspend_count--;
++ AICBT_ERR("%s: Failed to enter suspend", __func__);
++ return -EBUSY;
++ }
++
++ cancel_work_sync(&data->work);
++
++ btusb_stop_traffic(data);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->tx_anchor);
++
++ return 0;
++}
++
++static void play_deferred(struct btusb_data *data)
++{
++ struct urb *urb;
++ int err;
++
++ while ((urb = usb_get_from_anchor(&data->deferred))) {
++ usb_anchor_urb(urb, &data->tx_anchor);
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d",
++ __func__, urb, err);
++ kfree(urb->setup_packet);
++ usb_unanchor_urb(urb);
++ } else {
++ usb_mark_last_busy(data->udev);
++ }
++ usb_free_urb(urb);
++
++ data->tx_in_flight++;
++ }
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_scuttle_anchored_urbs(&data->deferred);
++}
++
++static int btusb_resume(struct usb_interface *intf)
++{
++ struct btusb_data *data = usb_get_intfdata(intf);
++ struct hci_dev *hdev = data->hdev;
++ int err = 0;
++
++ AICBT_INFO("%s: Suspend count %d", __func__, data->suspend_count);
++
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return 0;
++
++ if (--data->suspend_count)
++ return 0;
++
++ #if 0
++ /*check_fw_version to check the status of the BT Controller after USB Resume*/
++ err = check_fw_version(fw_info);
++ if (err !=0)
++ {
++ AICBT_INFO("%s: BT Controller Power OFF And Return hci_hardware_error:%d", __func__, err);
++ hci_hardware_error();
++ }
++ #endif
++
++ AICBT_INFO("%s g_chipid %x\n", __func__, g_chipid);
++ if(g_chipid == PRODUCT_ID_AIC8800DC){
++ if(data->fw_info){
++ err = download_patch(data->fw_info,1);
++ }else{
++ AICBT_WARN("%s: Failed to initialize fw info", __func__);
++ }
++ }
++
++ #if 1
++ if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
++ err = btusb_submit_intr_urb(hdev, GFP_NOIO);
++ if (err < 0) {
++ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
++ goto failed;
++ }
++ }
++ #endif
++
++ if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
++ err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
++ if (err < 0) {
++ clear_bit(BTUSB_BULK_RUNNING, &data->flags);
++ goto failed;
++ }
++
++ btusb_submit_bulk_urb(hdev, GFP_NOIO);
++ }
++
++ if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
++ if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ else
++ btusb_submit_isoc_urb(hdev, GFP_NOIO);
++ }
++
++ spin_lock_irq(&data->txlock);
++ play_deferred(data);
++ clear_bit(BTUSB_SUSPENDING, &data->flags);
++ spin_unlock_irq(&data->txlock);
++ schedule_work(&data->work);
++
++ return 0;
++
++failed:
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_scuttle_anchored_urbs(&data->deferred);
++ spin_lock_irq(&data->txlock);
++ clear_bit(BTUSB_SUSPENDING, &data->flags);
++ spin_unlock_irq(&data->txlock);
++
++ return err;
++}
++#endif
++
++static struct usb_driver btusb_driver = {
++ .name = "aic_btusb",
++ .probe = btusb_probe,
++ .disconnect = btusb_disconnect,
++#ifdef CONFIG_PM
++ .suspend = btusb_suspend,
++ .resume = btusb_resume,
++#if CONFIG_RESET_RESUME
++ .reset_resume = btusb_resume,
++#endif
++#endif
++ .id_table = btusb_table,
++ .supports_autosuspend = 1,
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1)
++ .disable_hub_initiated_lpm = 1,
++#endif
++};
++
++static int __init btusb_init(void)
++{
++ int err;
++
++ AICBT_INFO("AICBT_RELEASE_NAME: %s",AICBT_RELEASE_NAME);
++ AICBT_INFO("AicSemi Bluetooth USB driver module init, version %s", VERSION);
++ AICBT_INFO("RELEASE DATE: 2023_0506_1635 \r\n");
++#if CONFIG_BLUEDROID
++ err = btchr_init();
++ if (err < 0) {
++ /* usb register will go on, even bt char register failed */
++ AICBT_ERR("Failed to register usb char device interfaces");
++ } else
++ bt_char_dev_registered = 1;
++#endif
++ err = usb_register(&btusb_driver);
++ if (err < 0)
++ AICBT_ERR("Failed to register aic bluetooth USB driver");
++ return err;
++}
++
++static void __exit btusb_exit(void)
++{
++ AICBT_INFO("AicSemi Bluetooth USB driver module exit");
++#if CONFIG_BLUEDROID
++ if (bt_char_dev_registered > 0)
++ btchr_exit();
++#endif
++ usb_deregister(&btusb_driver);
++}
++
++module_init(btusb_init);
++module_exit(btusb_exit);
++
++
++module_param(mp_drv_mode, int, 0644);
++MODULE_PARM_DESC(mp_drv_mode, "0: NORMAL; 1: MP MODE");
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
++MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
++#endif
++
++MODULE_AUTHOR("AicSemi Corporation");
++MODULE_DESCRIPTION("AicSemi Bluetooth USB driver version");
++MODULE_VERSION(VERSION);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb.h
+@@ -0,0 +1,753 @@
++/*
++ *
++ * Aic Bluetooth USB driver
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/skbuff.h>
++#include <linux/errno.h>
++#include <linux/usb.h>
++#include <linux/cdev.h>
++#include <linux/device.h>
++#include <linux/poll.h>
++
++#include <linux/version.h>
++#include <linux/pm_runtime.h>
++#include <linux/firmware.h>
++#include <linux/suspend.h>
++
++
++#ifdef CONFIG_PLATFORM_UBUNTU
++#define CONFIG_BLUEDROID 0 /* bleuz 0, bluedroid 1 */
++#else
++#define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1 */
++#endif
++
++
++//#define CONFIG_SCO_OVER_HCI
++#define CONFIG_USB_AIC_UART_SCO_DRIVER
++
++#ifdef CONFIG_SCO_OVER_HCI
++#include <linux/usb/audio.h>
++#include <sound/core.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++
++#define AIC_SCO_ID "snd_sco_aic"
++enum {
++ USB_CAPTURE_RUNNING,
++ USB_PLAYBACK_RUNNING,
++ ALSA_CAPTURE_OPEN,
++ ALSA_PLAYBACK_OPEN,
++ ALSA_CAPTURE_RUNNING,
++ ALSA_PLAYBACK_RUNNING,
++ CAPTURE_URB_COMPLETED,
++ PLAYBACK_URB_COMPLETED,
++ DISCONNECTED,
++};
++
++// AIC sound card
++typedef struct AIC_sco_card {
++ struct snd_card *card;
++ struct snd_pcm *pcm;
++ struct usb_device *dev;
++ struct btusb_data *usb_data;
++ unsigned long states;
++ struct aic_sco_stream {
++ struct snd_pcm_substream *substream;
++ unsigned int sco_packet_bytes;
++ snd_pcm_uframes_t buffer_pos;
++ } capture, playback;
++ spinlock_t capture_lock;
++ spinlock_t playback_lock;
++ struct work_struct send_sco_work;
++} AIC_sco_card_t;
++#endif
++/* Some Android system may use standard Linux kernel, while
++ * standard Linux may also implement early suspend feature.
++ * So exclude earysuspend.h from CONFIG_BLUEDROID.
++ */
++#ifdef CONFIG_HAS_EARLYSUSPEND
++#include <linux/earlysuspend.h>
++#endif
++
++#if CONFIG_BLUEDROID
++#else
++#include <net/bluetooth/bluetooth.h>
++#include <net/bluetooth/hci_core.h>
++#include <net/bluetooth/hci.h>
++#endif
++
++
++/***********************************
++** AicSemi - For aic_btusb driver **
++***********************************/
++#define URB_CANCELING_DELAY_MS 10
++/* when OS suspended, module is still powered,usb is not powered,
++ * this may set to 1, and must comply with special patch code.
++ */
++#define CONFIG_RESET_RESUME 1
++#define PRINT_CMD_EVENT 0
++#define PRINT_ACL_DATA 0
++#define PRINT_SCO_DATA 0
++
++#define AICBT_DBG_FLAG 0
++
++#if AICBT_DBG_FLAG
++#define AICBT_DBG(fmt, arg...) printk( "aic_btusb: " fmt "\n" , ## arg)
++#else
++#define AICBT_DBG(fmt, arg...)
++#endif
++
++#define AICBT_INFO(fmt, arg...) printk("aic_btusb: " fmt "\n" , ## arg)
++#define AICBT_WARN(fmt, arg...) printk("aic_btusb: " fmt "\n" , ## arg)
++#define AICBT_ERR(fmt, arg...) printk("aic_btusb: " fmt "\n" , ## arg)
++
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 33)
++#define HDEV_BUS hdev->bus
++#define USB_RPM 1
++#else
++#define HDEV_BUS hdev->type
++#define USB_RPM 0
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
++#define NUM_REASSEMBLY 3
++#endif
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0)
++#define GET_DRV_DATA(x) hci_get_drvdata(x)
++#else
++#define GET_DRV_DATA(x) x->driver_data
++#endif
++
++#define SCO_NUM hdev->conn_hash.sco_num
++
++
++#define BTUSB_RPM (0 * USB_RPM) /* 1 SS enable; 0 SS disable */
++#define BTUSB_WAKEUP_HOST 0 /* 1 enable; 0 disable */
++#define BTUSB_MAX_ISOC_FRAMES 48
++#define BTUSB_INTR_RUNNING 0
++#define BTUSB_BULK_RUNNING 1
++#define BTUSB_ISOC_RUNNING 2
++#define BTUSB_SUSPENDING 3
++#define BTUSB_DID_ISO_RESUME 4
++
++#define HCI_VENDOR_USB_DISC_HARDWARE_ERROR 0xFF
++
++#define HCI_CMD_READ_BD_ADDR 0x1009
++#define HCI_VENDOR_READ_LMP_VERISION 0x1001
++#define HCI_VENDOR_RESET 0x0C03
++
++#define DRV_NORMAL_MODE 0
++#define DRV_MP_MODE 1
++int mp_drv_mode = 0; /* 1 Mptool Fw; 0 Normal Fw */
++
++
++#if CONFIG_BLUEDROID
++#define QUEUE_SIZE 500
++
++/***************************************
++** AicSemi - Integrate from bluetooth.h **
++*****************************************/
++/* Reserv for core and drivers use */
++#define BT_SKB_RESERVE 8
++
++/* BD Address */
++typedef struct {
++ __u8 b[6];
++} __packed bdaddr_t;
++
++/* Skb helpers */
++struct bt_skb_cb {
++ __u8 pkt_type;
++ __u8 incoming;
++ __u16 expect;
++ __u16 tx_seq;
++ __u8 retries;
++ __u8 sar;
++ __u8 force_active;
++};
++
++#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
++
++static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
++{
++ struct sk_buff *skb;
++
++ if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) {
++ skb_reserve(skb, BT_SKB_RESERVE);
++ bt_cb(skb)->incoming = 0;
++ }
++ return skb;
++}
++/* AicSemi - Integrate from bluetooth.h end */
++
++/***********************************
++** AicSemi - Integrate from hci.h **
++***********************************/
++#define HCI_MAX_ACL_SIZE 1024
++#define HCI_MAX_SCO_SIZE 255
++#define HCI_MAX_EVENT_SIZE 260
++#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
++
++/* HCI bus types */
++#define HCI_VIRTUAL 0
++#define HCI_USB 1
++#define HCI_PCCARD 2
++#define HCI_UART 3
++#define HCI_RS232 4
++#define HCI_PCI 5
++#define HCI_SDIO 6
++
++/* HCI controller types */
++#define HCI_BREDR 0x00
++#define HCI_AMP 0x01
++
++/* HCI device flags */
++enum {
++ HCI_UP,
++ HCI_INIT,
++ HCI_RUNNING,
++
++ HCI_PSCAN,
++ HCI_ISCAN,
++ HCI_AUTH,
++ HCI_ENCRYPT,
++ HCI_INQUIRY,
++
++ HCI_RAW,
++
++ HCI_RESET,
++};
++
++/*
++ * BR/EDR and/or LE controller flags: the flags defined here should represent
++ * states from the controller.
++ */
++enum {
++ HCI_SETUP,
++ HCI_AUTO_OFF,
++ HCI_MGMT,
++ HCI_PAIRABLE,
++ HCI_SERVICE_CACHE,
++ HCI_LINK_KEYS,
++ HCI_DEBUG_KEYS,
++ HCI_UNREGISTER,
++
++ HCI_LE_SCAN,
++ HCI_SSP_ENABLED,
++ HCI_HS_ENABLED,
++ HCI_LE_ENABLED,
++ HCI_CONNECTABLE,
++ HCI_DISCOVERABLE,
++ HCI_LINK_SECURITY,
++ HCI_PENDING_CLASS,
++};
++
++/* HCI data types */
++#define HCI_COMMAND_PKT 0x01
++#define HCI_ACLDATA_PKT 0x02
++#define HCI_SCODATA_PKT 0x03
++#define HCI_EVENT_PKT 0x04
++#define HCI_VENDOR_PKT 0xff
++
++#define HCI_MAX_NAME_LENGTH 248
++#define HCI_MAX_EIR_LENGTH 240
++
++#define HCI_OP_READ_LOCAL_VERSION 0x1001
++struct hci_rp_read_local_version {
++ __u8 status;
++ __u8 hci_ver;
++ __le16 hci_rev;
++ __u8 lmp_ver;
++ __le16 manufacturer;
++ __le16 lmp_subver;
++} __packed;
++
++#define HCI_EV_CMD_COMPLETE 0x0e
++struct hci_ev_cmd_complete {
++ __u8 ncmd;
++ __le16 opcode;
++} __packed;
++
++/* ---- HCI Packet structures ---- */
++#define HCI_COMMAND_HDR_SIZE 3
++#define HCI_EVENT_HDR_SIZE 2
++#define HCI_ACL_HDR_SIZE 4
++#define HCI_SCO_HDR_SIZE 3
++
++struct hci_command_hdr {
++ __le16 opcode; /* OCF & OGF */
++ __u8 plen;
++} __packed;
++
++struct hci_event_hdr {
++ __u8 evt;
++ __u8 plen;
++} __packed;
++
++struct hci_acl_hdr {
++ __le16 handle; /* Handle & Flags(PB, BC) */
++ __le16 dlen;
++} __packed;
++
++struct hci_sco_hdr {
++ __le16 handle;
++ __u8 dlen;
++} __packed;
++
++static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
++{
++ return (struct hci_event_hdr *) skb->data;
++}
++
++static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb)
++{
++ return (struct hci_acl_hdr *) skb->data;
++}
++
++static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
++{
++ return (struct hci_sco_hdr *) skb->data;
++}
++
++/* ---- HCI Ioctl requests structures ---- */
++struct hci_dev_stats {
++ __u32 err_rx;
++ __u32 err_tx;
++ __u32 cmd_tx;
++ __u32 evt_rx;
++ __u32 acl_tx;
++ __u32 acl_rx;
++ __u32 sco_tx;
++ __u32 sco_rx;
++ __u32 byte_rx;
++ __u32 byte_tx;
++};
++/* AicSemi - Integrate from hci.h end */
++
++/*****************************************
++** AicSemi - Integrate from hci_core.h **
++*****************************************/
++struct hci_conn_hash {
++ struct list_head list;
++ unsigned int acl_num;
++ unsigned int sco_num;
++ unsigned int le_num;
++};
++
++#define HCI_MAX_SHORT_NAME_LENGTH 10
++
++#define NUM_REASSEMBLY 4
++struct hci_dev {
++ struct mutex lock;
++
++ char name[8];
++ unsigned long flags;
++ __u16 id;
++ __u8 bus;
++ __u8 dev_type;
++
++ struct sk_buff *reassembly[NUM_REASSEMBLY];
++
++ struct hci_conn_hash conn_hash;
++
++ struct hci_dev_stats stat;
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++ atomic_t refcnt;
++ struct module *owner;
++ void *driver_data;
++#endif
++
++ atomic_t promisc;
++
++ struct device *parent;
++ struct device dev;
++
++ unsigned long dev_flags;
++
++ int (*open)(struct hci_dev *hdev);
++ int (*close)(struct hci_dev *hdev);
++ int (*flush)(struct hci_dev *hdev);
++ int (*send)(struct sk_buff *skb);
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++ void (*destruct)(struct hci_dev *hdev);
++#endif
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1)
++ __u16 voice_setting;
++#endif
++ void (*notify)(struct hci_dev *hdev, unsigned int evt);
++ int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
++ u8 *align_data;
++};
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
++{
++ atomic_inc(&d->refcnt);
++ return d;
++}
++
++static inline void __hci_dev_put(struct hci_dev *d)
++{
++ if (atomic_dec_and_test(&d->refcnt))
++ d->destruct(d);
++}
++#endif
++
++static inline void *hci_get_drvdata(struct hci_dev *hdev)
++{
++ return dev_get_drvdata(&hdev->dev);
++}
++
++static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)
++{
++ dev_set_drvdata(&hdev->dev, data);
++}
++
++#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
++/* AicSemi - Integrate from hci_core.h end */
++
++/* ----- HCI Commands ---- */
++#define HCI_OP_INQUIRY 0x0401
++#define HCI_OP_INQUIRY_CANCEL 0x0402
++#define HCI_OP_EXIT_PERIODIC_INQ 0x0404
++#define HCI_OP_CREATE_CONN 0x0405
++#define HCI_OP_DISCONNECT 0x0406
++#define HCI_OP_ADD_SCO 0x0407
++#define HCI_OP_CREATE_CONN_CANCEL 0x0408
++#define HCI_OP_ACCEPT_CONN_REQ 0x0409
++#define HCI_OP_REJECT_CONN_REQ 0x040a
++#define HCI_OP_LINK_KEY_REPLY 0x040b
++#define HCI_OP_LINK_KEY_NEG_REPLY 0x040c
++#define HCI_OP_PIN_CODE_REPLY 0x040d
++#define HCI_OP_PIN_CODE_NEG_REPLY 0x040e
++#define HCI_OP_CHANGE_CONN_PTYPE 0x040f
++#define HCI_OP_AUTH_REQUESTED 0x0411
++#define HCI_OP_SET_CONN_ENCRYPT 0x0413
++#define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415
++#define HCI_OP_REMOTE_NAME_REQ 0x0419
++#define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a
++#define HCI_OP_READ_REMOTE_FEATURES 0x041b
++#define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c
++#define HCI_OP_READ_REMOTE_VERSION 0x041d
++#define HCI_OP_SETUP_SYNC_CONN 0x0428
++#define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429
++#define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a
++#define HCI_OP_SNIFF_MODE 0x0803
++#define HCI_OP_EXIT_SNIFF_MODE 0x0804
++#define HCI_OP_ROLE_DISCOVERY 0x0809
++#define HCI_OP_SWITCH_ROLE 0x080b
++#define HCI_OP_READ_LINK_POLICY 0x080c
++#define HCI_OP_WRITE_LINK_POLICY 0x080d
++#define HCI_OP_READ_DEF_LINK_POLICY 0x080e
++#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f
++#define HCI_OP_SNIFF_SUBRATE 0x0811
++#define HCI_OP_Write_Link_Policy_Settings 0x080d
++#define HCI_OP_SET_EVENT_MASK 0x0c01
++#define HCI_OP_RESET 0x0c03
++#define HCI_OP_SET_EVENT_FLT 0x0c05
++#define HCI_OP_Write_Extended_Inquiry_Response 0x0c52
++#define HCI_OP_Write_Simple_Pairing_Mode 0x0c56
++#define HCI_OP_Read_Buffer_Size 0x1005
++#define HCI_OP_Host_Buffer_Size 0x0c33
++#define HCI_OP_Read_Local_Version_Information 0x1001
++#define HCI_OP_Read_BD_ADDR 0x1009
++#define HCI_OP_Read_Local_Supported_Commands 0x1002
++#define HCI_OP_Write_Scan_Enable 0x0c1a
++#define HCI_OP_Write_Current_IAC_LAP 0x0c3a
++#define HCI_OP_Write_Inquiry_Scan_Activity 0x0c1e
++#define HCI_OP_Write_Class_of_Device 0x0c24
++#define HCI_OP_LE_Rand 0x2018
++#define HCI_OP_LE_Set_Random_Address 0x2005
++#define HCI_OP_LE_Set_Extended_Scan_Enable 0x2042
++#define HCI_OP_LE_Set_Extended_Scan_Parameters 0x2041
++#define HCI_OP_Set_Event_Filter 0x0c05
++#define HCI_OP_Write_Voice_Setting 0x0c26
++#define HCI_OP_Change_Local_Name 0x0c13
++#define HCI_OP_Read_Local_Name 0x0c14
++#define HCI_OP_Wirte_Page_Timeout 0x0c18
++#define HCI_OP_LE_Clear_Resolving_List 0x0c29
++#define HCI_OP_LE_Set_Addres_Resolution_Enable_Command 0x0c2e
++#define HCI_OP_Write_Inquiry_mode 0x0c45
++#define HCI_OP_Write_Page_Scan_Type 0x0c47
++#define HCI_OP_Write_Inquiry_Scan_Type 0x0c43
++
++#define HCI_OP_Delete_Stored_Link_Key 0x0c12
++#define HCI_OP_LE_Read_Local_Resolvable_Address 0x202d
++#define HCI_OP_LE_Extended_Create_Connection 0x2043
++#define HCI_OP_Read_Remote_Version_Information 0x041d
++#define HCI_OP_LE_Start_Encryption 0x2019
++#define HCI_OP_LE_Add_Device_to_Resolving_List 0x2027
++#define HCI_OP_LE_Set_Privacy_Mode 0x204e
++#define HCI_OP_LE_Connection_Update 0x2013
++
++/* ----- HCI events---- */
++#define HCI_OP_DISCONNECT 0x0406
++#define HCI_EV_INQUIRY_COMPLETE 0x01
++#define HCI_EV_INQUIRY_RESULT 0x02
++#define HCI_EV_CONN_COMPLETE 0x03
++#define HCI_EV_CONN_REQUEST 0x04
++#define HCI_EV_DISCONN_COMPLETE 0x05
++#define HCI_EV_AUTH_COMPLETE 0x06
++#define HCI_EV_REMOTE_NAME 0x07
++#define HCI_EV_ENCRYPT_CHANGE 0x08
++#define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09
++
++#define HCI_EV_REMOTE_FEATURES 0x0b
++#define HCI_EV_REMOTE_VERSION 0x0c
++#define HCI_EV_QOS_SETUP_COMPLETE 0x0d
++#define HCI_EV_CMD_COMPLETE 0x0e
++#define HCI_EV_CMD_STATUS 0x0f
++
++#define HCI_EV_ROLE_CHANGE 0x12
++#define HCI_EV_NUM_COMP_PKTS 0x13
++#define HCI_EV_MODE_CHANGE 0x14
++#define HCI_EV_PIN_CODE_REQ 0x16
++#define HCI_EV_LINK_KEY_REQ 0x17
++#define HCI_EV_LINK_KEY_NOTIFY 0x18
++#define HCI_EV_CLOCK_OFFSET 0x1c
++#define HCI_EV_PKT_TYPE_CHANGE 0x1d
++#define HCI_EV_PSCAN_REP_MODE 0x20
++
++#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
++#define HCI_EV_REMOTE_EXT_FEATURES 0x23
++#define HCI_EV_SYNC_CONN_COMPLETE 0x2c
++#define HCI_EV_SYNC_CONN_CHANGED 0x2d
++#define HCI_EV_SNIFF_SUBRATE 0x2e
++#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f
++#define HCI_EV_IO_CAPA_REQUEST 0x31
++#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
++#define HCI_EV_REMOTE_HOST_FEATURES 0x3d
++#define HCI_EV_LE_Meta 0x3e
++
++#define CONFIG_MAC_OFFSET_GEN_1_2 (0x3C) //MAC's OFFSET in config/efuse for aic generation 1~2 bluetooth chip
++#define CONFIG_MAC_OFFSET_GEN_3PLUS (0x44) //MAC's OFFSET in config/efuse for aic generation 3+ bluetooth chip
++
++
++typedef struct {
++ uint16_t vid;
++ uint16_t pid;
++ uint16_t lmp_sub_default;
++ uint16_t lmp_sub;
++ uint16_t eversion;
++ char *mp_patch_name;
++ char *patch_name;
++ char *config_name;
++ uint8_t *fw_cache;
++ int fw_len;
++ uint16_t mac_offset;
++ uint32_t max_patch_size;
++} patch_info;
++
++//Define ioctl cmd the same as HCIDEVUP in the kernel
++#define DOWN_FW_CFG _IOW('E', 176, int)
++//#ifdef CONFIG_SCO_OVER_HCI
++//#define SET_ISO_CFG _IOW('H', 202, int)
++//#else
++#define SET_ISO_CFG _IOW('E', 177, int)
++//#endif
++#define RESET_CONTROLLER _IOW('E', 178, int)
++#define DWFW_CMPLT _IOW('E', 179, int)
++
++#define GET_USB_INFO _IOR('E', 180, int)
++
++/* for altsettings*/
++#include <linux/fs.h>
++#define BDADDR_FILE "/data/misc/bluetooth/bdaddr"
++#define FACTORY_BT_BDADDR_STORAGE_LEN 17
++#if 0
++static inline int getmacaddr(uint8_t * vnd_local_bd_addr)
++{
++ struct file *bdaddr_file;
++ mm_segment_t oldfs;
++ char buf[FACTORY_BT_BDADDR_STORAGE_LEN];
++ int32_t i = 0;
++ memset(buf, 0, FACTORY_BT_BDADDR_STORAGE_LEN);
++ bdaddr_file = filp_open(BDADDR_FILE, O_RDONLY, 0);
++ if (IS_ERR(bdaddr_file)){
++ AICBT_INFO("No Mac Config for BT\n");
++ return -1;
++ }
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ bdaddr_file->f_op->llseek(bdaddr_file, 0, 0);
++ bdaddr_file->f_op->read(bdaddr_file, buf, FACTORY_BT_BDADDR_STORAGE_LEN, &bdaddr_file->f_pos);
++ for (i = 0; i < 6; i++) {
++ if(buf[3*i]>'9')
++ {
++ if(buf[3*i]>'Z')
++ buf[3*i] -=('a'-'A'); //change a to A
++ buf[3*i] -= ('A'-'9'-1);
++ }
++ if(buf[3*i+1]>'9')
++ {
++ if(buf[3*i+1]>'Z')
++ buf[3*i+1] -=('a'-'A'); //change a to A
++ buf[3*i+1] -= ('A'-'9'-1);
++ }
++ vnd_local_bd_addr[5-i] = ((uint8_t)buf[3*i]-'0')*16 + ((uint8_t)buf[3*i+1]-'0');
++ }
++ set_fs(oldfs);
++ filp_close(bdaddr_file, NULL);
++ return 0;
++}
++#endif
++
++#endif /* CONFIG_BLUEDROID */
++
++
++typedef struct {
++ struct usb_interface *intf;
++ struct usb_device *udev;
++ int pipe_in, pipe_out;
++ uint8_t *send_pkt;
++ uint8_t *rcv_pkt;
++ struct hci_command_hdr *cmd_hdr;
++ struct hci_event_hdr *evt_hdr;
++ struct hci_ev_cmd_complete *cmd_cmp;
++ uint8_t *req_para, *rsp_para;
++ uint8_t *fw_data;
++ int pkt_len;
++ int fw_len;
++} firmware_info;
++
++/*******************************
++** Reasil patch code
++********************************/
++#define CMD_CMP_EVT 0x0e
++#define RCV_PKT_LEN 64
++#define SEND_PKT_LEN 300
++#define MSG_TO 1000
++#define PATCH_SEG_MAX 252
++#define DATA_END 0x80
++#define DOWNLOAD_OPCODE 0xfc02
++#define HCI_VSC_UPDATE_PT_CMD 0xFC75
++#define BTOFF_OPCODE 0xfc28
++#define TRUE 1
++#define FALSE 0
++#define CMD_HDR_LEN sizeof(struct hci_command_hdr)
++#define EVT_HDR_LEN sizeof(struct hci_event_hdr)
++#define CMD_CMP_LEN sizeof(struct hci_ev_cmd_complete)
++#define MAX_PATCH_SIZE_24K (1024*24)
++#define MAX_PATCH_SIZE_40K (1024*40)
++
++
++#define FW_RAM_ADID_BASE_ADDR 0x101788
++#define FW_RAM_PATCH_BASE_ADDR 0x184000
++#define FW_ADID_BASE_NAME "fw_adid_8800dc.bin"
++#define FW_PATCH_TABLE_NAME "fw_patch_table_8800dc.bin"
++#define FW_PATCH_BASE_NAME "fw_patch_8800dc.bin"
++#define FW_PATCH_TABLE_NAME_U02 "fw_patch_table_8800dc_u02.bin"
++#define FW_PATCH_BASE_NAME_U02 "fw_patch_8800dc_u02.bin"
++#define FW_PATCH_TABLE_NAME_U02H "fw_patch_table_8800dc_u02h.bin"
++#define FW_PATCH_BASE_NAME_U02H "fw_patch_8800dc_u02h.bin"
++#define AICBT_PT_TAG "AICBT_PT_TAG"
++
++enum aicbt_patch_table_type {
++ AICBT_PT_NULL = 0x00,
++ AICBT_PT_TRAP,
++ AICBT_PT_B4,
++ AICBT_PT_BTMODE,
++ AICBT_PT_PWRON,
++ AICBT_PT_AF,
++ AICBT_PT_VER,
++ AICBT_PT_MAX,
++};
++
++#define HCI_VSC_FW_STATUS_GET_CMD 0xFC78
++
++struct fw_status {
++ u8 status;
++} __packed;
++
++#define HCI_PATCH_DATA_MAX_LEN 240
++#define HCI_VSC_MEM_WR_SIZE 240
++#define HCI_VSC_MEM_RD_SIZE 128
++#define HCI_VSC_UPDATE_PT_SIZE 249
++#define HCI_PT_MAX_LEN 31
++
++#define HCI_VSC_DBG_RD_MEM_CMD 0xFC01
++
++struct hci_dbg_rd_mem_cmd {
++ __le32 start_addr;
++ __u8 type;
++ __u8 length;
++}__attribute__ ((packed));
++
++struct hci_dbg_rd_mem_cmd_evt {
++ __u8 status;
++ __u8 length;
++ __u8 data[HCI_VSC_MEM_RD_SIZE];
++}__attribute__ ((packed));
++
++struct long_buffer_tag {
++ __u8 length;
++ __u8 data[HCI_VSC_MEM_WR_SIZE];
++};
++
++struct hci_dbg_wr_mem_cmd {
++ __le32 start_addr;
++ __u8 type;
++ __u8 length;
++ __u8 data[HCI_VSC_MEM_WR_SIZE];
++};
++
++struct aicbt_patch_table {
++ char *name;
++ uint32_t type;
++ uint32_t *data;
++ uint32_t len;
++ struct aicbt_patch_table *next;
++};
++
++struct aicbt_patch_table_cmd {
++ uint8_t patch_num;
++ uint32_t patch_table_addr[31];
++ uint32_t patch_table_data[31];
++}__attribute__ ((packed));
++
++
++enum aic_endpoit {
++ CTRL_EP = 0,
++ INTR_EP = 3,
++ BULK_EP = 1,
++ ISOC_EP = 4
++};
++
++/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
++#define HCI_VERSION_CODE LINUX_VERSION_CODE
++
++int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device);
++int aicbt_patch_table_free(struct aicbt_patch_table **head);
++int download_patch(firmware_info *fw_info, int cached);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
++#define NUM_REASSEMBLY 3
++#else
++#define NUM_REASSEMBLY 4
++#endif
++
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.c
+@@ -0,0 +1,126 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/skbuff.h>
++#include <linux/usb.h>
++#include <linux/poll.h>
++#include <linux/cdev.h>
++#include <linux/device.h>
++
++
++
++#define IOCTL_CHAR_DEVICE_NAME "aic_btusb_ex_dev"
++
++#define SET_APCF_PARAMETER _IOR('E', 181, int)
++
++static dev_t ioctl_devid; /* bt char device number */
++static struct cdev ioctl_char_dev; /* bt character device structure */
++static struct class *ioctl_char_class; /* device class for usb char driver */
++
++extern struct file_operations ioctl_chrdev_ops;
++
++extern void btchr_external_write(char* data, int len);
++
++static long ioctl_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg)
++{
++ char data[1024];
++ int ret = 0;
++
++ printk("%s enter\r\n", __func__);
++ memset(data, 0, 1024);
++ switch(cmd)
++ {
++ case SET_APCF_PARAMETER:
++ printk("set apcf parameter\r\n");
++ ret = copy_from_user(data, (int __user *)arg, 1024);
++ btchr_external_write(&data[1], (int)data[0]);
++ break;
++
++ default:
++ printk("unknow cmdr\r\n");
++ break;
++ }
++ return 0;
++}
++
++
++#ifdef CONFIG_COMPAT
++static long compat_ioctlchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
++{
++ return ioctl_ioctl(filp, cmd, (unsigned long) compat_ptr(arg));
++}
++#endif
++
++
++struct file_operations ioctl_chrdev_ops = {
++ unlocked_ioctl : ioctl_ioctl,
++#ifdef CONFIG_COMPAT
++ compat_ioctl : compat_ioctlchr_ioctl,
++#endif
++
++};
++
++static int __init init_extenal_ioctl(void){
++ int res = 0;
++ struct device *dev;
++
++ printk("%s enter\r\n", __func__);
++
++ ioctl_char_class = class_create(THIS_MODULE, IOCTL_CHAR_DEVICE_NAME);
++ if (IS_ERR(ioctl_char_class)) {
++ printk("Failed to create ioctl char class");
++ }
++
++ res = alloc_chrdev_region(&ioctl_devid, 0, 1, IOCTL_CHAR_DEVICE_NAME);
++ if (res < 0) {
++ printk("Failed to allocate ioctl char device");
++ goto err_alloc;
++ }
++
++ dev = device_create(ioctl_char_class, NULL, ioctl_devid, NULL, IOCTL_CHAR_DEVICE_NAME);
++ if (IS_ERR(dev)) {
++ printk("Failed to create ioctl char device");
++ res = PTR_ERR(dev);
++ goto err_create;
++ }
++
++ cdev_init(&ioctl_char_dev, &ioctl_chrdev_ops);
++ res = cdev_add(&ioctl_char_dev, ioctl_devid, 1);
++ if (res < 0) {
++ printk("Failed to add ioctl char device");
++ goto err_add;
++ }
++
++ return res;
++
++err_add:
++ device_destroy(ioctl_char_class, ioctl_devid);
++err_create:
++ unregister_chrdev_region(ioctl_devid, 1);
++err_alloc:
++ class_destroy(ioctl_char_class);
++
++ return res;
++
++}
++static void __exit deinit_extenal_ioctl(void){
++ printk("%s enter\r\n", __func__);
++ device_destroy(ioctl_char_class, ioctl_devid);
++ cdev_del(&ioctl_char_dev);
++ unregister_chrdev_region(ioctl_devid, 1);
++ class_destroy(ioctl_char_class);
++
++}
++
++module_init(init_extenal_ioctl);
++module_exit(deinit_extenal_ioctl);
++
++
++MODULE_AUTHOR("AicSemi Corporation");
++MODULE_DESCRIPTION("AicSemi Bluetooth USB driver version");
++MODULE_LICENSE("GPL");
++
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.h
+@@ -0,0 +1,3 @@
++
++void btchr_external_write(char* data, int len);
++
diff --git a/target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch b/target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch
new file mode 100644
index 0000000000..c599a44cf7
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch
@@ -0,0 +1,67 @@
+From fdb2822982887c7048f34601688ae2406ccbcfcc Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 15 Apr 2024 11:29:17 +0800
+Subject: [PATCH 114/116] riscv: dts: starfive: visionfive 2: Sync the sound
+ card names with v5.15 and v6.1
+
+Sync the sound card names. So we can build Debian images with the
+same process.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../dts/starfive/jh7110-starfive-visionfive-2-tdm.dts | 2 +-
+ .../dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts | 2 +-
+ .../boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 8 ++++----
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
+@@ -8,7 +8,7 @@
+ #include "jh7110-starfive-visionfive-2-v1.3b.dts"
+
+ / {
+- sound-tdm {
++ sound5: snd-card5 {
+ compatible = "simple-audio-card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
+@@ -9,7 +9,7 @@
+
+ / {
+ /* i2s + wm8960 */
+- sound-wm8960 {
++ sound6: snd-card6 {
+ compatible = "simple-audio-card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -91,9 +91,9 @@
+ #sound-dai-cells = <0>;
+ };
+
+- sound-pwmdac {
++ sound3: snd-card3 {
+ compatible = "simple-audio-card";
+- simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
++ simple-audio-card,name = "Starfive-PWMDAC-Sound-Card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+@@ -113,12 +113,12 @@
+ };
+ };
+
+- sound-hdmi {
++ sound1: snd-card1 {
+ compatible = "simple-audio-card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- simple-audio-card,name = "StarFive-HDMI-Sound-Card";
++ simple-audio-card,name = "Starfive-HDMI-Sound-Card";
+ simple-audio-card,dai-link@0 {
+ reg = <0>;
+ format = "i2s";
diff --git a/target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch b/target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch
new file mode 100644
index 0000000000..6b34f0ec56
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch
@@ -0,0 +1,53 @@
+From dac6f3021895e7678552789edff22f1dc909e274 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 15 Apr 2024 20:59:35 +0800
+Subject: [PATCH 115/116] clk: starfive: jh7110: Change uart3-uart5 clk
+ register info
+
+The core_clk division register of uart3-uart5 include fractional and
+integral parts, but now only use the integral part, so include shift
+operation. The integral part include 8 bit, so the max value can be
+configed is 255.
+
+Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/clk/starfive/clk-starfive-jh71x0.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
+@@ -10,6 +10,8 @@
+ #include <linux/device.h>
+ #include <linux/io.h>
+
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++
+ #include "clk-starfive-jh71x0.h"
+
+ static struct jh71x0_clk *jh71x0_clk_from(struct clk_hw *hw)
+@@ -70,6 +72,11 @@ static unsigned long jh71x0_clk_recalc_r
+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+ u32 div = jh71x0_clk_reg_get(clk) & JH71X0_CLK_DIV_MASK;
+
++ if (clk->idx == JH7110_SYSCLK_UART3_CORE ||
++ clk->idx == JH7110_SYSCLK_UART4_CORE ||
++ clk->idx == JH7110_SYSCLK_UART5_CORE)
++ div >>= 8;
++
+ return div ? parent_rate / div : 0;
+ }
+
+@@ -110,6 +117,12 @@ static int jh71x0_clk_set_rate(struct cl
+ unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
+ 1UL, (unsigned long)clk->max_div);
+
++ /* UART3-5: [15:8]: integer part of the divisor. [7:0] fraction part of the divisor */
++ if (clk->idx == JH7110_SYSCLK_UART3_CORE ||
++ clk->idx == JH7110_SYSCLK_UART4_CORE ||
++ clk->idx == JH7110_SYSCLK_UART5_CORE)
++ div <<= 8;
++
+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, div);
+ return 0;
+ }
diff --git a/target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch b/target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch
new file mode 100644
index 0000000000..659c442c82
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch
@@ -0,0 +1,32 @@
+From 1ea169bb83d3b556eb9054f1a3e8ce0411370293 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Wed, 24 Apr 2024 14:23:07 +0800
+Subject: [PATCH 116/116] riscv: dts: starfive: visionfive 2: Quote
+ corresponding regulators in hdmi and vin
+
+So PMIC can start to work before HDMI and VIN.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -961,6 +961,8 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_pins>;
+ hpd-gpio = <&sysgpio 15 GPIO_ACTIVE_HIGH>;
++ hdmi_0p9-supply = <&hdmi_0p9>;
++ hdmi_1p8-supply = <&hdmi_1p8>;
+
+ hdmi_in: port {
+ #address-cells = <1>;
+@@ -1084,6 +1086,7 @@
+ &vin_sysctl {
+ /* when use dvp open this pinctrl*/
+ status = "okay";
++ mipi_0p9-supply = <&mipi_0p9>;
+
+ ports {
+ #address-cells = <1>;
diff --git a/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch b/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
new file mode 100644
index 0000000000..463c7eb7b6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
@@ -0,0 +1,25 @@
+From b7b4fad8784d7ab4fcd929a56c3e5366046fe7fc Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 14 Oct 2021 20:56:54 +0200
+Subject: [PATCH 1000/1024] serial: 8250_dw: Add starfive,jh7100-hsuart
+ compatible
+
+This adds a compatible for the high speed UARTs on the StarFive JH7100
+RISC-V SoC. Just like the regular uarts we also need to keep the input
+clocks at their default rate and rely only on the divisor in the UART.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/tty/serial/8250/8250_dw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -802,6 +802,7 @@ static const struct of_device_id dw8250_
+ { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
+ { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
+ { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
++ { .compatible = "starfive,jh7100-hsuart", .data = &dw8250_starfive_jh7100_data },
+ { .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
+ { /* Sentinel */ }
+ };
diff --git a/target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch b/target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
new file mode 100644
index 0000000000..4cfa2a1678
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
@@ -0,0 +1,32 @@
+From 3051ab0102aaf969dd85f07b6ab731dadf97ef6c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 17:13:22 +0100
+Subject: [PATCH 1001/1024] RISC-V: Add StarFive JH7100 audio clock node
+
+Add device tree node for the audio clocks on the StarFive JH7100 RISC-V
+SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -158,6 +158,16 @@
+ riscv,ndev = <133>;
+ };
+
++ audclk: clock-controller@10480000 {
++ compatible = "starfive,jh7100-audclk";
++ reg = <0x0 0x10480000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
++ <&clkgen JH7100_CLK_AUDIO_12288>,
++ <&clkgen JH7100_CLK_DOM7AHB_BUS>;
++ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
++ #clock-cells = <1>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch b/target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch
new file mode 100644
index 0000000000..73d25f5163
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch
@@ -0,0 +1,28 @@
+From 8ef30667e97363ca921416a60e50eb28bf88cc4f Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:11:04 +0800
+Subject: [PATCH 1002/1024] drivers/tty/serial/8250: update driver for JH7100
+
+---
+ drivers/tty/serial/8250/8250_port.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -72,8 +72,16 @@ static const struct serial8250_config ua
+ },
+ [PORT_16550] = {
+ .name = "16550",
++#ifdef CONFIG_SOC_STARFIVE
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
++ .rxtrig_bytes = {1, 4, 8, 14},
++ .flags = UART_CAP_FIFO,
++#else
+ .fifo_size = 1,
+ .tx_loadsz = 1,
++#endif
+ },
+ [PORT_16550A] = {
+ .name = "16550A",
diff --git a/target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch b/target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
new file mode 100644
index 0000000000..d0c692e1a5
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
@@ -0,0 +1,55 @@
+From 2d5b71006c6a93e26eb86b7efd37440c020bab46 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Wed, 17 Nov 2021 14:50:45 +0800
+Subject: [PATCH 1003/1024] dmaengine: dw-axi-dmac: Handle xfer start while
+ non-idle
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 +++++++++++-
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -382,11 +382,13 @@ static void axi_chan_block_xfer_start(st
+ u32 irq_mask;
+ u8 lms = 0; /* Select AXI0 master for LLI fetching */
+
++ chan->is_err = false;
+ if (unlikely(axi_chan_is_hw_enable(chan))) {
+ dev_err(chan2dev(chan), "%s is non-idle!\n",
+ axi_chan_name(chan));
+
+- return;
++ axi_chan_disable(chan);
++ chan->is_err = true;
+ }
+
+ axi_dma_enable(chan->chip);
+@@ -1028,6 +1030,14 @@ static noinline void axi_chan_handle_err
+ axi_chan_name(chan));
+ goto out;
+ }
++ if (chan->is_err) {
++ struct axi_dma_desc *desc = vd_to_axi_desc(vd);
++
++ axi_chan_block_xfer_start(chan, desc);
++ chan->is_err = false;
++ goto out;
++ }
++
+ /* Remove the completed descriptor from issued list */
+ list_del(&vd->node);
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -50,6 +50,7 @@ struct axi_dma_chan {
+ struct dma_slave_config config;
+ enum dma_transfer_direction direction;
+ bool cyclic;
++ bool is_err;
+ /* these other elements are all protected by vc.lock */
+ bool is_paused;
+ };
diff --git a/target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch b/target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
new file mode 100644
index 0000000000..74a05cf80a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
@@ -0,0 +1,64 @@
+From 933f8c33d466de20e9894ef8de5b6afe478a420d Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Wed, 17 Nov 2021 14:50:45 +0800
+Subject: [PATCH 1004/1024] dmaengine: dw-axi-dmac: Add StarFive JH7100 support
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 ++++++++++++
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 4 ++++
+ 2 files changed, 16 insertions(+)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -677,8 +677,13 @@ static int dw_axi_dma_set_hw_desc(struct
+
+ hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
+
++#ifdef CONFIG_SOC_STARFIVE
++ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
++ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
++#else
+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
++#endif
+ hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
+
+ set_desc_src_master(hw_desc);
+@@ -1502,7 +1507,11 @@ static int dw_probe(struct platform_devi
+ * Therefore, set constraint to 1024 * 4.
+ */
+ dw->dma.dev->dma_parms = &dw->dma_parms;
++#ifdef CONFIG_SOC_STARFIVE
++ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
++#else
+ dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
++#endif
+ platform_set_drvdata(pdev, chip);
+
+ pm_runtime_enable(chip->dev);
+@@ -1587,6 +1596,9 @@ static const struct of_device_id dw_dma_
+ .compatible = "intel,kmb-axi-dma",
+ .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
+ }, {
++ .compatible = "starfive,jh7100-axi-dma",
++ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
++ }, {
+ .compatible = "starfive,jh7110-axi-dma",
+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
+ },
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -284,7 +284,11 @@ enum {
+ #define CH_CTL_L_SRC_MAST BIT(0)
+
+ /* CH_CFG_H */
++#ifdef CONFIG_SOC_STARFIVE
++#define CH_CFG_H_PRIORITY_POS 15
++#else
+ #define CH_CFG_H_PRIORITY_POS 17
++#endif
+ #define CH_CFG_H_DST_PER_POS 12
+ #define CH_CFG_H_SRC_PER_POS 7
+ #define CH_CFG_H_HS_SEL_DST_POS 4
diff --git a/target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch b/target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch
new file mode 100644
index 0000000000..63a7a0cee9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch
@@ -0,0 +1,127 @@
+From c5019bf73d1e178beb6055cca254e7d3c916db7c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 17 Jul 2021 21:50:38 +0200
+Subject: [PATCH 1005/1024] pinctrl: starfive: Reset pinmux settings
+
+Current u-boot doesn't seem to take into account that some GPIOs are
+configured as inputs/outputs of certain peripherals on power-up. This
+means it ends up configuring some GPIOs as inputs to more than one
+peripheral which the documentation explicitly says is illegal. Similarly
+it also ends up configuring more than one GPIO as output of the same
+peripheral. While not explicitly mentioned by the documentation this
+also seems like a bad idea.
+
+The easiest way to remedy this mess is to just disconnect all GPIOs from
+peripherals and have our pinmux configuration set everything up
+properly. This, however, means that we'd disconnect the serial console
+from its pins for a while, so add a device tree property to keep
+certain GPIOs from being reset.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ .../pinctrl/starfive,jh7100-pinctrl.yaml | 4 ++
+ .../starfive/pinctrl-starfive-jh7100.c | 66 +++++++++++++++++++
+ 2 files changed, 70 insertions(+)
+
+--- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
+@@ -88,6 +88,10 @@ properties:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3, 4, 5, 6]
+
++ starfive,keep-gpiomux:
++ description: Keep pinmux for these GPIOs from being reset at boot.
++ $ref: /schemas/types.yaml#/definitions/uint32-array
++
+ required:
+ - compatible
+ - reg
+--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
+@@ -203,6 +203,10 @@ static u16 starfive_drive_strength_from_
+ return (clamp(i, 14U, 63U) - 14) / 7;
+ }
+
++static bool keepmux;
++module_param(keepmux, bool, 0644);
++MODULE_PARM_DESC(keepmux, "Keep pinmux settings from previous boot stage");
++
+ struct starfive_pinctrl {
+ struct gpio_chip gc;
+ struct pinctrl_gpio_range gpios;
+@@ -1225,6 +1229,65 @@ static void starfive_disable_clock(void
+ clk_disable_unprepare(data);
+ }
+
++#define GPI_END (GPI_USB_OVER_CURRENT + 1)
++static void starfive_pinmux_reset(struct starfive_pinctrl *sfp)
++{
++ static const DECLARE_BITMAP(defaults, GPI_END) = {
++ BIT_MASK(GPI_I2C0_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C0_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C1_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C1_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C2_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C2_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C3_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C3_PAD_SDA_IN) |
++ BIT_MASK(GPI_SDIO0_PAD_CARD_DETECT_N) |
++
++ BIT_MASK(GPI_SDIO1_PAD_CARD_DETECT_N) |
++ BIT_MASK(GPI_SPI0_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI1_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI2_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI2AHB_PAD_SS_N) |
++ BIT_MASK(GPI_SPI3_PAD_SS_IN_N),
++
++ BIT_MASK(GPI_UART0_PAD_SIN) |
++ BIT_MASK(GPI_UART1_PAD_SIN) |
++ BIT_MASK(GPI_UART2_PAD_SIN) |
++ BIT_MASK(GPI_UART3_PAD_SIN) |
++ BIT_MASK(GPI_USB_OVER_CURRENT)
++ };
++ DECLARE_BITMAP(keep, NR_GPIOS) = {};
++ struct device_node *np = sfp->gc.parent->of_node;
++ int len = of_property_count_u32_elems(np, "starfive,keep-gpiomux");
++ int i;
++
++ for (i = 0; i < len; i++) {
++ u32 gpio;
++
++ of_property_read_u32_index(np, "starfive,keep-gpiomux", i, &gpio);
++ if (gpio < NR_GPIOS)
++ set_bit(gpio, keep);
++ }
++
++ for (i = 0; i < NR_GPIOS; i++) {
++ if (test_bit(i, keep))
++ continue;
++
++ writel_relaxed(GPO_DISABLE, sfp->base + GPON_DOEN_CFG + 8 * i);
++ writel_relaxed(GPO_LOW, sfp->base + GPON_DOUT_CFG + 8 * i);
++ }
++
++ for (i = 0; i < GPI_END; i++) {
++ void __iomem *reg = sfp->base + GPI_CFG_OFFSET + 4 * i;
++ u32 din = readl_relaxed(reg);
++
++ if (din >= 2 && din < (NR_GPIOS + 2) && test_bit(din - 2, keep))
++ continue;
++
++ writel_relaxed(test_bit(i, defaults), reg);
++ }
++}
++
+ static int starfive_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -1286,6 +1349,9 @@ static int starfive_probe(struct platfor
+ writel(value, sfp->padctl + IO_PADSHARE_SEL);
+ }
+
++ if (!keepmux)
++ starfive_pinmux_reset(sfp);
++
+ value = readl(sfp->padctl + IO_PADSHARE_SEL);
+ switch (value) {
+ case 0:
diff --git a/target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch b/target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
new file mode 100644
index 0000000000..a6a1bb827e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
@@ -0,0 +1,302 @@
+From a4a2a8886c97e14643fe3e0ab8cf67a75c1bf14d Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Sat, 25 Mar 2023 22:57:06 +0100
+Subject: [PATCH 1006/1024] clk: starfive: Add flags argument to JH71X0__MUX
+ macro
+
+This flag is needed to add the CLK_SET_RATE_PARENT flag on the gmac_tx
+clock on the JH7100, which in turn is needed by the dwmac-starfive
+driver to set the clock properly for 1000, 100 and 10 Mbps links.
+
+This change was mostly made using coccinelle:
+
+@ match @
+expression idx, name, nparents;
+@@
+ JH71X0__MUX(
+-idx, name, nparents,
++idx, name, 0, nparents,
+ ...)
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ .../clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
+ drivers/clk/starfive/clk-starfive-jh7100.c | 32 +++++++++----------
+ .../clk/starfive/clk-starfive-jh7110-aon.c | 6 ++--
+ .../clk/starfive/clk-starfive-jh7110-isp.c | 2 +-
+ .../clk/starfive/clk-starfive-jh7110-sys.c | 26 +++++++--------
+ drivers/clk/starfive/clk-starfive-jh71x0.h | 4 +--
+ 6 files changed, 36 insertions(+), 36 deletions(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+@@ -79,7 +79,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
+ JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
+ JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
+- JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
++ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 0, 2,
+ JH7100_AUDCLK_VAD_INTMEM,
+ JH7100_AUDCLK_AUDIO_12288),
+ };
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -24,48 +24,48 @@
+ #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
+
+ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+- JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
++ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 0, 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
++ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
++ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 0, 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
++ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT),
+- JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
++ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 0, 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+ JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
+- JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
++ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
++ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT),
+- JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 0, 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+@@ -76,7 +76,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
+ JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
+ JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
+- JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
++ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_OSC_AUD),
+ JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+@@ -142,7 +142,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
+ JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
+- JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
++ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 0, 2,
+ JH7100_CLK_CPU_AXI,
+ JH7100_CLK_NNEBUS_SRC1),
+ JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
+@@ -166,7 +166,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
+ JH7100_CLK_USBPHY_ROOTDIV),
+- JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
++ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_USBPHY_PLLDIV25M),
+ JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
+@@ -200,12 +200,12 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
++ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+ JH7100_CLK_GMAC_RMII_TX),
+ JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
+- JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
++ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 0, 2,
+ JH7100_CLK_GMAC_GR_MII_RX,
+ JH7100_CLK_GMAC_RMII_RX),
+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
+--- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+@@ -26,7 +26,7 @@
+ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
+ /* source */
+ JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
+- JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
++ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 0, 2,
+ JH7110_AONCLK_OSC_DIV4,
+ JH7110_AONCLK_OSC),
+ /* gmac0 */
+@@ -39,7 +39,7 @@ static const struct jh71x0_clk_data jh71
+ JH7110_AONCLK_GMAC0_GTXCLK,
+ JH7110_AONCLK_GMAC0_RMII_RTX),
+ JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
+- JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
++ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 0, 2,
+ JH7110_AONCLK_GMAC0_RGMII_RXIN,
+ JH7110_AONCLK_GMAC0_RMII_RTX),
+ JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
+@@ -48,7 +48,7 @@ static const struct jh71x0_clk_data jh71
+ /* rtc */
+ JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
+ JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
+- JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
++ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 0, 2,
+ JH7110_AONCLK_RTC_OSC,
+ JH7110_AONCLK_RTC_INTERNAL),
+ JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
+--- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+@@ -53,7 +53,7 @@ static const struct jh71x0_clk_data jh71
+ JH7110_ISPCLK_MIPI_RX0_PXL),
+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
+ JH7110_ISPCLK_MIPI_RX0_PXL),
+- JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
++ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 0, 2,
+ JH7110_ISPCLK_MIPI_RX0_PXL,
+ JH7110_ISPCLK_DVP_INV),
+ /* ispv2_top_wrapper */
+--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+@@ -36,18 +36,18 @@
+
+ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ /* root */
+- JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 0, 2,
+ JH7110_SYSCLK_OSC,
+ JH7110_SYSCLK_PLL0_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
+ JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
+- JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 0, 2,
+ JH7110_SYSCLK_PLL2_OUT,
+ JH7110_SYSCLK_PLL1_OUT),
+ JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
+ JH7110_SYSCLK_PLL0_OUT,
+ JH7110_SYSCLK_PLL2_OUT),
+- JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 0, 2,
+ JH7110_SYSCLK_OSC,
+ JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
+@@ -62,7 +62,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
+- JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 0, 2,
+ JH7110_SYSCLK_MCLK_INNER,
+ JH7110_SYSCLK_MCLK_EXT),
+ JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
+@@ -96,7 +96,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
+- JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
++ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 0, 4,
+ JH7110_SYSCLK_OSC_DIV2,
+ JH7110_SYSCLK_PLL1_DIV2,
+ JH7110_SYSCLK_PLL1_DIV4,
+@@ -186,7 +186,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
+ JH7110_SYSCLK_GMAC1_RMII_REFIN),
+ JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
+- JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
++ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 0, 2,
+ JH7110_SYSCLK_GMAC1_RGMII_RXIN,
+ JH7110_SYSCLK_GMAC1_RMII_RTX),
+ JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
+@@ -270,11 +270,11 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
+ JH7110_SYSCLK_I2STX0_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 0, 2,
+ JH7110_SYSCLK_I2STX0_BCLK_MST,
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 0, 2,
+ JH7110_SYSCLK_I2STX0_LRCK_MST,
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
+ /* i2stx1 */
+@@ -285,11 +285,11 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
+ JH7110_SYSCLK_I2STX1_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 0, 2,
+ JH7110_SYSCLK_I2STX1_BCLK_MST,
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 0, 2,
+ JH7110_SYSCLK_I2STX1_LRCK_MST,
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
+ /* i2srx */
+@@ -300,11 +300,11 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
+ JH7110_SYSCLK_I2SRX_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 0, 2,
+ JH7110_SYSCLK_I2SRX_BCLK_MST,
+ JH7110_SYSCLK_I2SRX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 0, 2,
+ JH7110_SYSCLK_I2SRX_LRCK_MST,
+ JH7110_SYSCLK_I2SRX_LRCK_EXT),
+ /* pdm */
+@@ -314,7 +314,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
+ JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
+ JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
+- JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
++ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 0, 2,
+ JH7110_SYSCLK_TDM_INTERNAL,
+ JH7110_SYSCLK_TDM_EXT),
+ JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
+@@ -61,10 +61,10 @@ struct jh71x0_clk_data {
+ .parents = { [0] = _parent }, \
+ }
+
+-#define JH71X0__MUX(_idx, _name, _nparents, ...) \
++#define JH71X0__MUX(_idx, _name, _flags, _nparents, ...) \
+ [_idx] = { \
+ .name = _name, \
+- .flags = 0, \
++ .flags = _flags, \
+ .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
+ .parents = { __VA_ARGS__ }, \
+ }
diff --git a/target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch b/target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
new file mode 100644
index 0000000000..74e695c03c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
@@ -0,0 +1,25 @@
+From 7dfed4b67bd6ba8c33caf90c01821b67cf3260dd Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Sat, 25 Mar 2023 23:04:31 +0100
+Subject: [PATCH 1007/1024] clk: starfive: jh7100: Add CLK_SET_RATE_PARENT to
+ gmac_tx
+
+This is needed by the dwmac-starfive ethernet driver to set the clock
+for 1000, 100 and 10 Mbps links properly.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -200,7 +200,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
++ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+ JH7100_CLK_GMAC_RMII_TX),
diff --git a/target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch b/target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch
new file mode 100644
index 0000000000..27346b4df7
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch
@@ -0,0 +1,94 @@
+From f8d08ec17674e56c7c689f5ca43c4dd3a4b76d13 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 14 Oct 2021 20:35:43 +0200
+Subject: [PATCH 1008/1024] clk: starfive: jh7100: Keep more clocks alive
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/clk/starfive/clk-starfive-jh7100.c | 37 +++++++++++-----------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -94,9 +94,9 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
+ JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
+- JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
+- JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
+- JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
+ JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
+ JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
+ JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
+@@ -160,11 +160,12 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
+ JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+ JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
+- JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
++ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
++ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
+ JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
+- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
+- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
++ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", CLK_IGNORE_UNUSED, 8,
++ JH7100_CLK_USBPHY_ROOTDIV),
++ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", CLK_IGNORE_UNUSED, 32,
+ JH7100_CLK_USBPHY_ROOTDIV),
+ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
+ JH7100_CLK_OSC_SYS,
+@@ -183,23 +184,23 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
+ JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
+ JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
+- JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
++ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", CLK_IGNORE_UNUSED, 4, JH7100_CLK_VOUT_ROOT),
+ JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
+ JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
+- JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
+- JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
+ JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
+ JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
+ JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
+ JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
+- JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", CLK_IGNORE_UNUSED, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
+- JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
+- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", CLK_IGNORE_UNUSED, 31, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", CLK_IGNORE_UNUSED, 255, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+@@ -209,8 +210,8 @@ static const struct jh71x0_clk_data jh71
+ JH7100_CLK_GMAC_GR_MII_RX,
+ JH7100_CLK_GMAC_RMII_RX),
+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
+- JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", CLK_IGNORE_UNUSED, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", CLK_IGNORE_UNUSED, 127, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
+ JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
+@@ -223,7 +224,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
+ JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
+ JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
+- JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
diff --git a/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch b/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch
new file mode 100644
index 0000000000..ad8b92f715
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch
@@ -0,0 +1,30 @@
+From 980f1e9ef19d472e72c36e142db7fb4e224f0f3e Mon Sep 17 00:00:00 2001
+From: Matteo Croce <technoboy85@gmail.com>
+Date: Fri, 21 May 2021 03:26:38 +0200
+Subject: [PATCH 1009/1024] net: stmmac: use GFP_DMA32
+
+Signed-off-by: Matteo Croce <mcroce@microsoft.com>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1434,7 +1434,7 @@ static int stmmac_init_rx_buffers(struct
+ {
+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
+ struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
+- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
++ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
+
+ if (priv->dma_cap.host_dma_width <= 32)
+ gfp |= GFP_DMA32;
+@@ -4673,7 +4673,7 @@ static inline void stmmac_rx_refill(stru
+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
+ int dirty = stmmac_rx_dirty(priv, queue);
+ unsigned int entry = rx_q->dirty_rx;
+- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
++ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
+
+ if (priv->dma_cap.host_dma_width <= 32)
+ gfp |= GFP_DMA32;
diff --git a/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch b/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
new file mode 100644
index 0000000000..b625014dd9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
@@ -0,0 +1,477 @@
+From 4989e7aa5ed5ef9bc2532b3a47ff381572f389b5 Mon Sep 17 00:00:00 2001
+From: Huan Feng <huan.feng@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:35:42 +0800
+Subject: [PATCH 1010/1024] hwrng: Add StarFive JH7100 Random Number Generator
+ driver
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/char/hw_random/Kconfig | 13 ++
+ drivers/char/hw_random/Makefile | 1 +
+ drivers/char/hw_random/starfive-vic-rng.c | 256 ++++++++++++++++++++++
+ drivers/char/hw_random/starfive-vic-rng.h | 167 ++++++++++++++
+ 4 files changed, 437 insertions(+)
+ create mode 100644 drivers/char/hw_random/starfive-vic-rng.c
+ create mode 100644 drivers/char/hw_random/starfive-vic-rng.h
+
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -322,6 +322,19 @@ config HW_RANDOM_POWERNV
+
+ If unsure, say Y.
+
++config HW_RANDOM_STARFIVE_VIC
++ tristate "Starfive VIC Random Number Generator support"
++ depends on HW_RANDOM && (SOC_STARFIVE || COMPILE_TEST)
++ default SOC_STARFIVE
++ help
++ This driver provides kernel-side support for the Random Number
++ Generator hardware found on Starfive VIC SoC.
++
++ To compile this driver as a module, choose M here: the
++ module will be called starfive-vic-rng.
++
++ If unsure, say Y.
++
+ config HW_RANDOM_HISI
+ tristate "Hisilicon Random Number Generator support"
+ depends on ARCH_HISI || COMPILE_TEST
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -28,6 +28,7 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon
+ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
+ obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
+ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
++obj-$(CONFIG_HW_RANDOM_STARFIVE_VIC) += starfive-vic-rng.o
+ obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
+ obj-$(CONFIG_HW_RANDOM_HISTB) += histb-rng.o
+ obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
+--- /dev/null
++++ b/drivers/char/hw_random/starfive-vic-rng.c
+@@ -0,0 +1,256 @@
++/*
++ ******************************************************************************
++ * @file starfive-vic-rng.c
++ * @author StarFive Technology
++ * @version V1.0
++ * @date 08/13/2020
++ * @brief
++ ******************************************************************************
++ * @copy
++ *
++ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
++ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
++ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
++ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
++ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
++ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
++ *
++ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
++ */
++#include <linux/err.h>
++#include <linux/kernel.h>
++#include <linux/hw_random.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/random.h>
++
++#include "starfive-vic-rng.h"
++
++#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
++
++struct vic_rng {
++ struct device *dev;
++ void __iomem *base;
++ struct hwrng rng;
++};
++
++static inline void vic_wait_till_idle(struct vic_rng *hrng)
++{
++ while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
++ ;
++}
++
++static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
++{
++ // clear register: ISTAT
++ u32 data = readl(hrng->base + VIC_ISTAT);
++ writel(data, hrng->base + VIC_ISTAT);
++ writel(0, hrng->base + VIC_ALARM);
++}
++
++static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd) {
++ int res = 0;
++ // wait till idle
++ vic_wait_till_idle(hrng);
++ switch (cmd) {
++ case VIC_CTRL_CMD_NOP:
++ case VIC_CTRL_CMD_GEN_NOISE:
++ case VIC_CTRL_CMD_GEN_NONCE:
++ case VIC_CTRL_CMD_CREATE_STATE:
++ case VIC_CTRL_CMD_RENEW_STATE:
++ case VIC_CTRL_CMD_REFRESH_ADDIN:
++ case VIC_CTRL_CMD_GEN_RANDOM:
++ case VIC_CTRL_CMD_ADVANCE_STATE:
++ case VIC_CTRL_CMD_KAT:
++ case VIC_CTRL_CMD_ZEROIZE:
++ writel(cmd, hrng->base + VIC_CTRL);
++ break;
++ default:
++ res = -1;
++ break;
++ }
++
++ return res;
++}
++
++static int vic_rng_init(struct hwrng *rng)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ // wait till idle
++
++ // clear register: ISTAT
++ vic_rng_irq_mask_clear(hrng);
++
++ // set mission mode
++ writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
++
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
++ vic_wait_till_idle(hrng);
++
++ // set interrupt
++ writel(VIC_IE_ALL, hrng->base + VIC_IE);
++
++ // zeroize
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++
++ vic_wait_till_idle(hrng);
++
++ return 0;
++}
++
++static irqreturn_t vic_rng_irq(int irq, void *priv)
++{
++ u32 status, val;
++ struct vic_rng *hrng = (struct vic_rng *)priv;
++
++ /*
++ * clearing the interrupt will also clear the error register
++ * read error and status before clearing
++ */
++ status = readl(hrng->base + VIC_ISTAT);
++
++ if (status & VIC_ISTAT_ALARMS) {
++ writel(VIC_ISTAT_ALARMS, hrng->base + VIC_ISTAT);
++ val = readl(hrng->base + VIC_ALARM);
++ if (val & VIC_ALARM_ILLEGAL_CMD_SEQ) {
++ writel(VIC_ALARM_ILLEGAL_CMD_SEQ, hrng->base + VIC_ALARM);
++ //dev_info(hrng->dev, "ILLEGAL CMD SEQ: LAST_CMD=0x%x\r\n",
++ //VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)));
++ } else {
++ dev_info(hrng->dev, "Failed test: %x\r\n", val);
++ }
++ }
++
++ if (status & VIC_ISTAT_ZEROIZE) {
++ writel(VIC_ISTAT_ZEROIZE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "zeroized\r\n");
++ }
++
++ if (status & VIC_ISTAT_KAT_COMPLETE) {
++ writel(VIC_ISTAT_KAT_COMPLETE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "kat_completed\r\n");
++ }
++
++ if (status & VIC_ISTAT_NOISE_RDY) {
++ writel(VIC_ISTAT_NOISE_RDY, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "noise_rdy\r\n");
++ }
++
++ if (status & VIC_ISTAT_DONE) {
++ writel(VIC_ISTAT_DONE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "done\r\n");
++ /*
++ if (VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)) ==
++ VIC_CTRL_CMD_GEN_RANDOM) {
++ dev_info(hrng->dev, "Need Update Buffer\r\n");
++ }
++ */
++ }
++ vic_rng_irq_mask_clear(hrng);
++
++ return IRQ_HANDLED;
++}
++
++static void vic_rng_cleanup(struct hwrng *rng)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ writel(0, hrng->base + VIC_CTRL);
++}
++
++static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
++
++ vic_wait_till_idle(hrng);
++ max = min_t(size_t, max, (VIC_RAND_LEN * 4));
++
++ writel(0x0, hrng->base + VIC_MODE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
++
++ vic_wait_till_idle(hrng);
++ memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++
++ vic_wait_till_idle(hrng);
++ return max;
++}
++
++static int vic_rng_probe(struct platform_device *pdev)
++{
++ int ret;
++ int irq;
++ struct vic_rng *rng;
++ struct resource *res;
++
++ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
++ if (!rng){
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(pdev, rng);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ rng->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(rng->base)){
++ return PTR_ERR(rng->base);
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0) {
++ dev_err(&pdev->dev, "Couldn't get irq %d\n", irq);
++ return irq;
++ }
++
++ ret = devm_request_irq(&pdev->dev, irq, vic_rng_irq, 0, pdev->name,
++ (void *)rng);
++ if (ret) {
++ dev_err(&pdev->dev, "Can't get interrupt working.\n");
++ return ret;
++ }
++
++ rng->rng.name = pdev->name;
++ rng->rng.init = vic_rng_init;
++ rng->rng.cleanup = vic_rng_cleanup;
++ rng->rng.read = vic_rng_read;
++
++ rng->dev = &pdev->dev;
++
++ ret = devm_hwrng_register(&pdev->dev, &rng->rng);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to register hwrng\n");
++ return ret;
++ }
++
++ dev_info(&pdev->dev, "Initialized\n");
++
++ return 0;
++}
++
++static const struct of_device_id vic_rng_dt_ids[] = {
++ { .compatible = "starfive,vic-rng" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, vic_rng_dt_ids);
++
++static struct platform_driver vic_rng_driver = {
++ .probe = vic_rng_probe,
++ .driver = {
++ .name = "vic-rng",
++ .of_match_table = vic_rng_dt_ids,
++ },
++};
++
++module_platform_driver(vic_rng_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
++MODULE_DESCRIPTION("Starfive VIC random number generator driver");
+--- /dev/null
++++ b/drivers/char/hw_random/starfive-vic-rng.h
+@@ -0,0 +1,167 @@
++/*
++ ******************************************************************************
++ * @file starfive-vic-rng.h
++ * @author StarFive Technology
++ * @version V1.0
++ * @date 08/13/2020
++ * @brief
++ ******************************************************************************
++ * @copy
++ *
++ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
++ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
++ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
++ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
++ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
++ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
++ *
++ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
++ */
++
++#define VIC_CTRL 0x00
++#define VIC_MODE 0x04
++#define VIC_SMODE 0x08
++#define VIC_STAT 0x0C
++#define VIC_IE 0x10
++#define VIC_ISTAT 0x14
++#define VIC_ALARM 0x18
++#define VIC_BUILD_ID 0x1C
++#define VIC_FEATURES 0x20
++#define VIC_RAND0 0x24
++#define VIC_NPA_DATA0 0x34
++#define VIC_SEED0 0x74
++#define VIC_IA_RDATA 0xA4
++#define VIC_IA_WDATA 0xA8
++#define VIC_IA_ADDR 0xAC
++#define VIC_IA_CMD 0xB0
++
++/* CTRL */
++#define VIC_CTRL_CMD_NOP 0
++#define VIC_CTRL_CMD_GEN_NOISE 1
++#define VIC_CTRL_CMD_GEN_NONCE 2
++#define VIC_CTRL_CMD_CREATE_STATE 3
++#define VIC_CTRL_CMD_RENEW_STATE 4
++#define VIC_CTRL_CMD_REFRESH_ADDIN 5
++#define VIC_CTRL_CMD_GEN_RANDOM 6
++#define VIC_CTRL_CMD_ADVANCE_STATE 7
++#define VIC_CTRL_CMD_KAT 8
++#define VIC_CTRL_CMD_ZEROIZE 15
++
++/* MODE */
++#define _VIC_MODE_ADDIN_PRESENT 4
++#define _VIC_MODE_PRED_RESIST 3
++#define _VIC_MODE_KAT_SEL 2
++#define _VIC_MODE_KAT_VEC 1
++#define _VIC_MODE_SEC_ALG 0
++
++#define VIC_MODE_ADDIN_PRESENT (1UL << _VIC_MODE_ADDIN_PRESENT)
++#define VIC_MODE_PRED_RESIST (1UL << _VIC_MODE_PRED_RESIST)
++#define VIC_MODE_KAT_SEL (1UL << _VIC_MODE_KAT_SEL)
++#define VIC_MODE_KAT_VEC (1UL << _VIC_MODE_KAT_VEC)
++#define VIC_MODE_SEC_ALG (1UL << _VIC_MODE_SEC_ALG)
++
++/* SMODE */
++#define _VIC_SMODE_MAX_REJECTS 2
++#define _VIC_SMODE_SECURE_EN 1
++#define _VIC_SMODE_NONCE 0
++
++#define VIC_SMODE_MAX_REJECTS(x) ((x) << _VIC_SMODE_MAX_REJECTS)
++#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
++#define VIC_SMODE_NONCE (1UL << _VIC_SMODE_NONCE)
++
++/* STAT */
++#define _VIC_STAT_BUSY 31
++#define _VIC_STAT_DRBG_STATE 7
++#define _VIC_STAT_SECURE 6
++#define _VIC_STAT_NONCE_MODE 5
++#define _VIC_STAT_SEC_ALG 4
++#define _VIC_STAT_LAST_CMD 0
++
++#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
++#define VIC_STAT_DRBG_STATE (1UL << _VIC_STAT_DRBG_STATE)
++#define VIC_STAT_SECURE (1UL << _VIC_STAT_SECURE)
++#define VIC_STAT_NONCE_MODE (1UL << _VIC_STAT_NONCE_MODE)
++#define VIC_STAT_SEC_ALG (1UL << _VIC_STAT_SEC_ALG)
++#define VIC_STAT_LAST_CMD(x) (((x) >> _VIC_STAT_LAST_CMD) & 0xF)
++
++/* IE */
++#define _VIC_IE_GLBL 31
++#define _VIC_IE_DONE 4
++#define _VIC_IE_ALARMS 3
++#define _VIC_IE_NOISE_RDY 2
++#define _VIC_IE_KAT_COMPLETE 1
++#define _VIC_IE_ZEROIZE 0
++
++#define VIC_IE_GLBL (1UL << _VIC_IE_GLBL)
++#define VIC_IE_DONE (1UL << _VIC_IE_DONE)
++#define VIC_IE_ALARMS (1UL << _VIC_IE_ALARMS)
++#define VIC_IE_NOISE_RDY (1UL << _VIC_IE_NOISE_RDY)
++#define VIC_IE_KAT_COMPLETE (1UL << _VIC_IE_KAT_COMPLETE)
++#define VIC_IE_ZEROIZE (1UL << _VIC_IE_ZEROIZE)
++#define VIC_IE_ALL (VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
++ VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
++
++/* ISTAT */
++#define _VIC_ISTAT_DONE 4
++#define _VIC_ISTAT_ALARMS 3
++#define _VIC_ISTAT_NOISE_RDY 2
++#define _VIC_ISTAT_KAT_COMPLETE 1
++#define _VIC_ISTAT_ZEROIZE 0
++
++#define VIC_ISTAT_DONE (1UL << _VIC_ISTAT_DONE)
++#define VIC_ISTAT_ALARMS (1UL << _VIC_ISTAT_ALARMS)
++#define VIC_ISTAT_NOISE_RDY (1UL << _VIC_ISTAT_NOISE_RDY)
++#define VIC_ISTAT_KAT_COMPLETE (1UL << _VIC_ISTAT_KAT_COMPLETE)
++#define VIC_ISTAT_ZEROIZE (1UL << _VIC_ISTAT_ZEROIZE)
++
++/* ALARMS */
++#define VIC_ALARM_ILLEGAL_CMD_SEQ (1UL << 4)
++#define VIC_ALARM_FAILED_TEST_ID_OK 0
++#define VIC_ALARM_FAILED_TEST_ID_KAT_STAT 1
++#define VIC_ALARM_FAILED_TEST_ID_KAT 2
++#define VIC_ALARM_FAILED_TEST_ID_MONOBIT 3
++#define VIC_ALARM_FAILED_TEST_ID_RUN 4
++#define VIC_ALARM_FAILED_TEST_ID_LONGRUN 5
++#define VIC_ALARM_FAILED_TEST_ID_AUTOCORRELATION 6
++#define VIC_ALARM_FAILED_TEST_ID_POKER 7
++#define VIC_ALARM_FAILED_TEST_ID_REPETITION_COUNT 8
++#define VIC_ALARM_FAILED_TEST_ID_ADAPATIVE_PROPORTION 9
++
++/* BUILD_ID */
++#define VIC_BUILD_ID_STEPPING(x) (((x) >> 28) & 0xF)
++#define VIC_BUILD_ID_EPN(x) ((x) & 0xFFFF)
++
++/* FEATURES */
++#define VIC_FEATURES_AES_256(x) (((x) >> 9) & 1)
++#define VIC_FEATURES_EXTRA_PS_PRESENT(x) (((x) >> 8) & 1)
++#define VIC_FEATURES_DIAG_LEVEL_NS(x) (((x) >> 7) & 1)
++#define VIC_FEATURES_DIAG_LEVEL_CLP800(x) (((x) >> 4) & 7)
++#define VIC_FEATURES_DIAG_LEVEL_ST_HLT(x) (((x) >> 1) & 7)
++#define VIC_FEATURES_SECURE_RST_STATE(x) ((x) & 1)
++
++/* IA_CMD */
++#define VIC_IA_CMD_GO (1UL << 31)
++#define VIC_IA_CMD_WR (1)
++
++#define _VIC_SMODE_MAX_REJECTS_MASK 255UL
++#define _VIC_SMODE_SECURE_EN_MASK 1UL
++#define _VIC_SMODE_NONCE_MASK 1UL
++#define _VIC_MODE_SEC_ALG_MASK 1UL
++#define _VIC_MODE_ADDIN_PRESENT_MASK 1UL
++#define _VIC_MODE_PRED_RESIST_MASK 1UL
++
++#define VIC_SMODE_SET_MAX_REJECTS(y, x) (((y) & ~(_VIC_SMODE_MAX_REJECTS_MASK << _VIC_SMODE_MAX_REJECTS)) | ((x) << _VIC_SMODE_MAX_REJECTS))
++#define VIC_SMODE_SET_SECURE_EN(y, x) (((y) & ~(_VIC_SMODE_SECURE_EN_MASK << _VIC_SMODE_SECURE_EN)) | ((x) << _VIC_SMODE_SECURE_EN))
++#define VIC_SMODE_SET_NONCE(y, x) (((y) & ~(_VIC_SMODE_NONCE_MASK << _VIC_SMODE_NONCE)) | ((x) << _VIC_SMODE_NONCE))
++#define VIC_SMODE_GET_MAX_REJECTS(x) (((x) >> _VIC_SMODE_MAX_REJECTS) & _VIC_SMODE_MAX_REJECTS_MASK)
++#define VIC_SMODE_GET_SECURE_EN(x) (((x) >> _VIC_SMODE_SECURE_EN) & _VIC_SMODE_SECURE_EN_MASK)
++#define VIC_SMODE_GET_NONCE(x) (((x) >> _VIC_SMODE_NONCE) & _VIC_SMODE_NONCE_MASK)
++
++#define VIC_MODE_SET_SEC_ALG(y, x) (((y) & ~(_VIC_MODE_SEC_ALG_MASK << _VIC_MODE_SEC_ALG)) | ((x) << _VIC_MODE_SEC_ALG))
++#define VIC_MODE_SET_PRED_RESIST(y, x) (((y) & ~(_VIC_MODE_PRED_RESIST_MASK << _VIC_MODE_PRED_RESIST)) | ((x) << _VIC_MODE_PRED_RESIST))
++#define VIC_MODE_SET_ADDIN_PRESENT(y, x) (((y) & ~(_VIC_MODE_ADDIN_PRESENT_MASK << _VIC_MODE_ADDIN_PRESENT)) | ((x) << _VIC_MODE_ADDIN_PRESENT))
++#define VIC_MODE_GET_SEC_ALG(x) (((x) >> _VIC_MODE_SEC_ALG) & _VIC_MODE_SEC_ALG_MASK)
++#define VIC_MODE_GET_PRED_RESIST(x) (((x) >> _VIC_MODE_PRED_RESIST) & _VIC_MODE_PRED_RESIST_MASK)
++#define VIC_MODE_GET_ADDIN_PRESENT(x) (((x) >> _VIC_MODE_ADDIN_PRESENT) & _VIC_MODE_ADDIN_PRESENT_MASK)
++
++#define VIC_RAND_LEN 4
diff --git a/target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch b/target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
new file mode 100644
index 0000000000..7a588c27c4
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
@@ -0,0 +1,309 @@
+From 34fd7b7f92deef97f03c80d056e2f51bc08b7dc6 Mon Sep 17 00:00:00 2001
+From: Chenjieqin <Jessica.Chen@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:56:54 +0800
+Subject: [PATCH 1011/1024] pwm: sifive-ptc: Add SiFive PWM PTC driver
+
+yiming.li: clear CNTR of PWM after setting period & duty_cycle
+Emil: cleanups, clock, reset and div_u64
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/pwm/Kconfig | 11 ++
+ drivers/pwm/Makefile | 1 +
+ drivers/pwm/pwm-sifive-ptc.c | 260 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 272 insertions(+)
+ create mode 100644 drivers/pwm/pwm-sifive-ptc.c
+
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -549,6 +549,17 @@ config PWM_SIFIVE
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-sifive.
+
++config PWM_SIFIVE_PTC
++ tristate "SiFive PWM PTC support"
++ depends on SOC_SIFIVE || SOC_STARFIVE || COMPILE_TEST
++ depends on OF
++ depends on COMMON_CLK
++ help
++ Generic PWM framework driver for SiFive SoCs.
++
++ To compile this driver as a module, choose M here: the module
++ will be called pwm-sifive-ptc.
++
+ config PWM_SL28CPLD
+ tristate "Kontron sl28cpld PWM support"
+ depends on MFD_SL28CPLD || COMPILE_TEST
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -50,6 +50,7 @@ obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockch
+ obj-$(CONFIG_PWM_RZ_MTU3) += pwm-rz-mtu3.o
+ obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
+ obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
++obj-$(CONFIG_PWM_SIFIVE_PTC) += pwm-sifive-ptc.o
+ obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
+ obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
+ obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
+--- /dev/null
++++ b/drivers/pwm/pwm-sifive-ptc.c
+@@ -0,0 +1,260 @@
++/*
++ * Copyright (C) 2018 SiFive, Inc
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2, as published by
++ * the Free Software Foundation.
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/math64.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/reset.h>
++
++#include <dt-bindings/pwm/pwm.h>
++
++/* max channel of pwm */
++#define MAX_PWM 8
++
++/* PTC Register offsets */
++#define REG_RPTC_CNTR 0x0
++#define REG_RPTC_HRC 0x4
++#define REG_RPTC_LRC 0x8
++#define REG_RPTC_CTRL 0xC
++
++/* Bit for PWM clock */
++#define BIT_PWM_CLOCK_EN 31
++
++/* Bit for clock gen soft reset */
++#define BIT_CLK_GEN_SOFT_RESET 13
++
++#define NS_1 1000000000U
++
++/* Access PTC register (cntr hrc lrc and ctrl), need to replace PWM_BASE_ADDR */
++#define REG_PTC_BASE_ADDR_SUB(base, N) \
++ ((base) + (((N) > 3) ? (((N) - 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
++#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
++#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
++#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
++#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
++
++/* pwm ptc device */
++struct sifive_pwm_ptc_device {
++ struct pwm_chip chip;
++ struct clk *clk;
++ void __iomem *regs;
++};
++
++static inline struct sifive_pwm_ptc_device *chip_to_sifive_ptc(struct pwm_chip *c)
++{
++ return container_of(c, struct sifive_pwm_ptc_device, chip);
++}
++
++static int sifive_pwm_ptc_get_state(struct pwm_chip *chip, struct pwm_device *dev,
++ struct pwm_state *state)
++{
++ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
++ u32 data_lrc;
++ u32 data_hrc;
++ u32 pwm_clk_ns = 0;
++
++ /* get lrc and hrc data from registe */
++ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
++ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
++
++ /* how many ns does apb clock elapse */
++ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
++
++ /* pwm period(ns) */
++ state->period = data_lrc * pwm_clk_ns;
++
++ /* duty cycle(ns) means high level eclapse ns if it is normal polarity */
++ state->duty_cycle = data_hrc * pwm_clk_ns;
++
++ /* polarity, we don't use it now because it is not in dts */
++ state->polarity = PWM_POLARITY_NORMAL;
++
++ /* enabled or not */
++ state->enabled = 1;
++
++ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "data_hrc:0x%x 0x%x\n", data_hrc, data_lrc);
++ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
++ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
++ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
++ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
++
++ return 0;
++}
++
++static int sifive_pwm_ptc_apply(struct pwm_chip *chip, struct pwm_device *dev,
++ const struct pwm_state *state)
++{
++ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
++ void __iomem *reg_addr;
++ u32 pwm_clk_ns = 0;
++ u32 data_hrc = 0;
++ u32 data_lrc = 0;
++ u32 period_data = 0;
++ u32 duty_data = 0;
++
++ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
++ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
++ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
++ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
++
++ /* duty_cycle should be less or equal than period */
++ if (state->duty_cycle > state->period)
++ return -EINVAL;
++
++ /* calculate pwm real period (ns) */
++ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
++
++ dev_dbg(pwm->chip.dev, "pwm_clk_ns:%u\n", pwm_clk_ns);
++
++ /* calculate period count */
++ period_data = div_u64(state->period, pwm_clk_ns);
++
++ if (!state->enabled)
++ /* if disabled, just set duty_data to 0, which means low level always */
++ duty_data = 0;
++ else
++ /* calculate duty count */
++ duty_data = div_u64(state->duty_cycle, pwm_clk_ns);
++
++ dev_dbg(pwm->chip.dev, "period_data:%u, duty_data:%u\n",
++ period_data, duty_data);
++
++ if (state->polarity == PWM_POLARITY_NORMAL)
++ /* calculate data_hrc */
++ data_hrc = period_data - duty_data;
++ else
++ /* calculate data_hrc */
++ data_hrc = duty_data;
++
++ data_lrc = period_data;
++
++ /* set hrc */
++ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
++ __func__, reg_addr, data_hrc);
++
++ iowrite32(data_hrc, reg_addr);
++
++ dev_dbg(pwm->chip.dev, "%s: hrc ok\n", __func__);
++
++ /* set lrc */
++ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
++ __func__, reg_addr, data_lrc);
++
++ iowrite32(data_lrc, reg_addr);
++ dev_dbg(pwm->chip.dev, "%s: lrc ok\n", __func__);
++
++ /* Clear REG_RPTC_CNTR after setting period & duty_cycle */
++ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
++ iowrite32(0, reg_addr);
++ return 0;
++}
++
++static const struct pwm_ops sifive_pwm_ptc_ops = {
++ .get_state = sifive_pwm_ptc_get_state,
++ .apply = sifive_pwm_ptc_apply,
++ .owner = THIS_MODULE,
++};
++
++static void sifive_pwm_ptc_disable_action(void *data)
++{
++ clk_disable_unprepare(data);
++}
++
++static int sifive_pwm_ptc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *node = pdev->dev.of_node;
++ struct sifive_pwm_ptc_device *pwm;
++ struct pwm_chip *chip;
++ struct reset_control *rst;
++ int ret;
++
++ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
++ if (!pwm)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, pwm);
++
++ chip = &pwm->chip;
++ chip->dev = dev;
++ chip->ops = &sifive_pwm_ptc_ops;
++
++ /* how many parameters can be transferred to ptc, need to fix */
++ chip->of_pwm_n_cells = 3;
++ chip->base = -1;
++
++ /* get pwm channels count, max value is 8 */
++ ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
++ if (ret < 0 || chip->npwm > MAX_PWM)
++ chip->npwm = MAX_PWM;
++
++ dev_dbg(dev, "%s: npwm:0x%x\n", __func__, chip->npwm);
++
++ /* get IO base address */
++ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(pwm->regs))
++ return dev_err_probe(dev, PTR_ERR(pwm->regs),
++ "Unable to map IO resources\n");
++
++ pwm->clk = devm_clk_get(dev, NULL);
++ if (IS_ERR(pwm->clk))
++ return dev_err_probe(dev, PTR_ERR(pwm->clk),
++ "Unable to get controller clock\n");
++
++ ret = clk_prepare_enable(pwm->clk);
++ if (ret)
++ return dev_err_probe(dev, ret, "Unable to enable clock\n");
++
++ ret = devm_add_action_or_reset(dev, sifive_pwm_ptc_disable_action, pwm->clk);
++ if (ret)
++ return ret;
++
++ rst = devm_reset_control_get_exclusive(dev, NULL);
++ if (IS_ERR(rst))
++ return dev_err_probe(dev, PTR_ERR(rst), "Unable to get reset\n");
++
++ ret = reset_control_deassert(rst);
++ if (ret)
++ return dev_err_probe(dev, ret, "Unable to deassert reset\n");
++
++ /*
++ * after pwmchip_add it will show up as /sys/class/pwm/pwmchip0,
++ * 0 is chip->base, pwm0 can be seen after running echo 0 > export
++ */
++ ret = devm_pwmchip_add(dev, chip);
++ if (ret)
++ return dev_err_probe(dev, ret, "cannot register PTC: %d\n", ret);
++
++ dev_dbg(dev, "SiFive PWM PTC chip registered %d PWMs\n", chip->npwm);
++ return 0;
++}
++
++static const struct of_device_id sifive_pwm_ptc_of_match[] = {
++ { .compatible = "starfive,pwm0" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, sifive_pwm_ptc_of_match);
++
++static struct platform_driver sifive_pwm_ptc_driver = {
++ .probe = sifive_pwm_ptc_probe,
++ .driver = {
++ .name = "pwm-sifive-ptc",
++ .of_match_table = sifive_pwm_ptc_of_match,
++ },
++};
++module_platform_driver(sifive_pwm_ptc_driver);
++
++MODULE_DESCRIPTION("SiFive PWM PTC driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch b/target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
new file mode 100644
index 0000000000..6986d4b1cd
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
@@ -0,0 +1,48 @@
+From 4f3335c302b7f944b61f564095505b3c7a1b62ee Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 19:29:25 +0100
+Subject: [PATCH 1012/1024] dt-bindings: reset: Add StarFive JH7100 audio reset
+ definitions
+
+Add all resets for the StarFive JH7100 audio reset controller.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ .../dt-bindings/reset/starfive-jh7100-audio.h | 31 +++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+ create mode 100644 include/dt-bindings/reset/starfive-jh7100-audio.h
+
+--- /dev/null
++++ b/include/dt-bindings/reset/starfive-jh7100-audio.h
+@@ -0,0 +1,31 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++/*
++ * Copyright (C) 2021 Emil Renner Berthing
++ */
++
++#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
++#define __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
++
++#define JH7100_AUDRSTN_APB_BUS 0
++#define JH7100_AUDRSTN_I2SADC_APB 1
++#define JH7100_AUDRSTN_I2SADC_SRST 2
++#define JH7100_AUDRSTN_PDM_APB 3
++#define JH7100_AUDRSTN_I2SVAD_APB 4
++#define JH7100_AUDRSTN_I2SVAD_SRST 5
++#define JH7100_AUDRSTN_SPDIF_APB 6
++#define JH7100_AUDRSTN_PWMDAC_APB 7
++#define JH7100_AUDRSTN_I2SDAC_APB 8
++#define JH7100_AUDRSTN_I2SDAC_SRST 9
++#define JH7100_AUDRSTN_I2S1_APB 10
++#define JH7100_AUDRSTN_I2S1_SRST 11
++#define JH7100_AUDRSTN_I2SDAC16K_APB 12
++#define JH7100_AUDRSTN_I2SDAC16K_SRST 13
++#define JH7100_AUDRSTN_DMA1P_AHB 14
++#define JH7100_AUDRSTN_USB_APB 15
++#define JH7100_AUDRST_USB_AXI 16
++#define JH7100_AUDRST_USB_PWRUP_RST_N 17
++#define JH7100_AUDRST_USB_PONRST 18
++
++#define JH7100_AUDRSTN_END 19
++
++#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__ */
diff --git a/target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch b/target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
new file mode 100644
index 0000000000..5eac29e006
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
@@ -0,0 +1,56 @@
+From 1e428568e486b40f78febddf2958ba27289bd49f Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Tue, 7 Dec 2021 21:48:51 +0100
+Subject: [PATCH 1013/1024] dt-bindings: reset: Add starfive,jh7100-audrst
+ bindings
+
+Add bindings for the audio reset controller on the StarFive JH7100
+RISC-V SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ .../reset/starfive,jh7100-audrst.yaml | 38 +++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
+@@ -0,0 +1,38 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/reset/starfive,jh7100-audrst.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7100 SoC Audio Reset Controller Device Tree Bindings
++
++maintainers:
++ - Emil Renner Berthing <kernel@esmil.dk>
++
++properties:
++ compatible:
++ enum:
++ - starfive,jh7100-audrst
++
++ reg:
++ maxItems: 1
++
++ "#reset-cells":
++ const: 1
++
++required:
++ - compatible
++ - reg
++ - "#reset-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ reset-controller@10490000 {
++ compatible = "starfive,jh7100-audrst";
++ reg = <0x10490000 0x10000>;
++ #reset-cells = <1>;
++ };
++
++...
diff --git a/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch
new file mode 100644
index 0000000000..bc33188a44
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch
@@ -0,0 +1,144 @@
+From 91559ced47de9e6fb1e6dd65a5544fcc86dea806 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 19:30:49 +0100
+Subject: [PATCH 1014/1024] reset: starfive: Add JH7100 audio reset driver
+
+The audio resets are almost identical to the system resets, there are
+just fewer of them. So factor out and export a generic probe function,
+so most of the reset controller implementation can be shared.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ MAINTAINERS | 2 +-
+ drivers/reset/starfive/Kconfig | 7 ++
+ drivers/reset/starfive/Makefile | 2 +
+ .../starfive/reset-starfive-jh7100-audio.c | 66 +++++++++++++++++++
+ .../reset/starfive/reset-starfive-jh7100.h | 16 +++++
+ 5 files changed, 92 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/reset/starfive/reset-starfive-jh7100-audio.c
+ create mode 100644 drivers/reset/starfive/reset-starfive-jh7100.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -20554,7 +20554,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS
+ M: Emil Renner Berthing <kernel@esmil.dk>
+ M: Hal Feng <hal.feng@starfivetech.com>
+ S: Maintained
+-F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
++F: Documentation/devicetree/bindings/reset/starfive,jh7100-*.yaml
+ F: drivers/reset/starfive/reset-starfive-jh71*
+ F: include/dt-bindings/reset/starfive?jh71*.h
+
+--- a/drivers/reset/starfive/Kconfig
++++ b/drivers/reset/starfive/Kconfig
+@@ -11,6 +11,13 @@ config RESET_STARFIVE_JH7100
+ help
+ This enables the reset controller driver for the StarFive JH7100 SoC.
+
++config RESET_STARFIVE_JH7100_AUDIO
++ tristate "StarFive JH7100 Audio Reset Driver"
++ depends on RESET_STARFIVE_JH7100
++ default m if SOC_STARFIVE
++ help
++ This enables the audio reset driver for the StarFive JH7100 SoC.
++
+ config RESET_STARFIVE_JH7110
+ bool "StarFive JH7110 Reset Driver"
+ depends on CLK_STARFIVE_JH7110_SYS
+--- a/drivers/reset/starfive/Makefile
++++ b/drivers/reset/starfive/Makefile
+@@ -2,4 +2,6 @@
+ obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
+
+ obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
++obj-$(CONFIG_RESET_STARFIVE_JH7100_AUDIO) += reset-starfive-jh7100-audio.o
++
+ obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
+--- /dev/null
++++ b/drivers/reset/starfive/reset-starfive-jh7100-audio.c
+@@ -0,0 +1,66 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Audio reset driver for the StarFive JH7100 SoC
++ *
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include "reset-starfive-jh71x0.h"
++
++#include <dt-bindings/reset/starfive-jh7100-audio.h>
++
++/* register offsets */
++#define JH7100_AUDRST_ASSERT0 0x00
++#define JH7100_AUDRST_STATUS0 0x04
++
++/*
++ * Writing a 1 to the n'th bit of the ASSERT register asserts
++ * line n, and writing a 0 deasserts the same line.
++ * Most reset lines have their status inverted so a 0 bit in the STATUS
++ * register means the line is asserted and a 1 means it's deasserted. A few
++ * lines don't though, so store the expected value of the status registers when
++ * all lines are asserted.
++ */
++static const u32 jh7100_audrst_asserted[1] = {
++ BIT(JH7100_AUDRST_USB_AXI) |
++ BIT(JH7100_AUDRST_USB_PWRUP_RST_N) |
++ BIT(JH7100_AUDRST_USB_PONRST)
++};
++
++static int jh7100_audrst_probe(struct platform_device *pdev)
++{
++ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
++
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
++ base + JH7100_AUDRST_ASSERT0,
++ base + JH7100_AUDRST_STATUS0,
++ jh7100_audrst_asserted,
++ JH7100_AUDRSTN_END,
++ THIS_MODULE);
++}
++
++static const struct of_device_id jh7100_audrst_dt_ids[] = {
++ { .compatible = "starfive,jh7100-audrst" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7100_audrst_dt_ids);
++
++static struct platform_driver jh7100_audrst_driver = {
++ .probe = jh7100_audrst_probe,
++ .driver = {
++ .name = "jh7100-reset-audio",
++ .of_match_table = jh7100_audrst_dt_ids,
++ },
++};
++module_platform_driver(jh7100_audrst_driver);
++
++MODULE_AUTHOR("Emil Renner Berthing");
++MODULE_DESCRIPTION("StarFive JH7100 audio reset driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/reset/starfive/reset-starfive-jh7100.h
+@@ -0,0 +1,16 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#ifndef _RESET_STARFIVE_JH7100_H_
++#define _RESET_STARFIVE_JH7100_H_
++
++#include <linux/platform_device.h>
++
++int reset_starfive_jh7100_generic_probe(struct platform_device *pdev,
++ const u32 *asserted,
++ unsigned int status_offset,
++ unsigned int nr_resets);
++
++#endif
diff --git a/target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch b/target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
new file mode 100644
index 0000000000..521144c9f0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
@@ -0,0 +1,28 @@
+From 418603fdce51212d4547aacfe2b4801fc5e61978 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 21:33:08 +0100
+Subject: [PATCH 1015/1024] RISC-V: Add StarFive JH7100 audio reset node
+
+Add device tree node for the audio resets on the StarFive JH7100 RISC-V
+SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -168,6 +168,12 @@
+ #clock-cells = <1>;
+ };
+
++ audrst: reset-controller@10490000 {
++ compatible = "starfive,jh7100-audrst";
++ reg = <0x0 0x10490000 0x0 0x10000>;
++ #reset-cells = <1>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch b/target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch
new file mode 100644
index 0000000000..2906e1605c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch
@@ -0,0 +1,160 @@
+From 8e090d271683d5869cdab0729f54a8af8c79c476 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Tue, 31 Oct 2023 15:14:44 +0100
+Subject: [PATCH 1016/1024] soc: sifive: ccache: Add StarFive JH7100 support
+
+This adds support for the StarFive JH7100 SoC which also features this
+SiFive cache controller.
+
+The JH7100 has non-coherent DMAs but predate the standard RISC-V Zicbom
+exension, so instead we need to use this cache controller for
+non-standard cache management operations.
+
+Unfortunately the interrupt for uncorrected data is broken on the JH7100
+and fires continuously, so add a quirk to not register a handler for it.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/soc/sifive/sifive_ccache.c | 62 +++++++++++++++++++++++++++++-
+ 1 file changed, 60 insertions(+), 2 deletions(-)
+
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -8,13 +8,16 @@
+
+ #define pr_fmt(fmt) "CCACHE: " fmt
+
++#include <linux/align.h>
+ #include <linux/debugfs.h>
+ #include <linux/interrupt.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_address.h>
+ #include <linux/device.h>
+ #include <linux/bitfield.h>
++#include <asm/cacheflush.h>
+ #include <asm/cacheinfo.h>
++#include <asm/dma-noncoherent.h>
+ #include <soc/sifive/sifive_ccache.h>
+
+ #define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100
+@@ -39,10 +42,14 @@
+ #define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16)
+ #define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24)
+
++#define SIFIVE_CCACHE_FLUSH64 0x200
++#define SIFIVE_CCACHE_FLUSH32 0x240
++
+ #define SIFIVE_CCACHE_WAYENABLE 0x08
+ #define SIFIVE_CCACHE_ECCINJECTERR 0x40
+
+ #define SIFIVE_CCACHE_MAX_ECCINTR 4
++#define SIFIVE_CCACHE_LINE_SIZE 64
+
+ static void __iomem *ccache_base;
+ static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
+@@ -56,6 +63,11 @@ enum {
+ DIR_UNCORR,
+ };
+
++enum {
++ QUIRK_NONSTANDARD_CACHE_OPS = BIT(0),
++ QUIRK_BROKEN_DATA_UNCORR = BIT(1),
++};
++
+ #ifdef CONFIG_DEBUG_FS
+ static struct dentry *sifive_test;
+
+@@ -106,6 +118,8 @@ static void ccache_config_read(void)
+ static const struct of_device_id sifive_ccache_ids[] = {
+ { .compatible = "sifive,fu540-c000-ccache" },
+ { .compatible = "sifive,fu740-c000-ccache" },
++ { .compatible = "starfive,jh7100-ccache",
++ .data = (void *)(QUIRK_NONSTANDARD_CACHE_OPS | QUIRK_BROKEN_DATA_UNCORR) },
+ { .compatible = "sifive,ccache0" },
+ { /* end of table */ }
+ };
+@@ -124,6 +138,34 @@ int unregister_sifive_ccache_error_notif
+ }
+ EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
+
++#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
++static void ccache_flush_range(phys_addr_t start, size_t len)
++{
++ phys_addr_t end = start + len;
++ phys_addr_t line;
++
++ if (!len)
++ return;
++
++ mb();
++ for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end;
++ line += SIFIVE_CCACHE_LINE_SIZE) {
++#ifdef CONFIG_32BIT
++ writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
++#else
++ writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
++#endif
++ mb();
++ }
++}
++
++static const struct riscv_nonstd_cache_ops ccache_mgmt_ops __initconst = {
++ .wback = &ccache_flush_range,
++ .inv = &ccache_flush_range,
++ .wback_inv = &ccache_flush_range,
++};
++#endif /* CONFIG_RISCV_NONSTANDARD_CACHE_OPS */
++
+ static int ccache_largest_wayenabled(void)
+ {
+ return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
+@@ -210,11 +252,15 @@ static int __init sifive_ccache_init(voi
+ struct device_node *np;
+ struct resource res;
+ int i, rc, intr_num;
++ const struct of_device_id *match;
++ unsigned long quirks;
+
+- np = of_find_matching_node(NULL, sifive_ccache_ids);
++ np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
+ if (!np)
+ return -ENODEV;
+
++ quirks = (uintptr_t)match->data;
++
+ if (of_address_to_resource(np, 0, &res)) {
+ rc = -ENODEV;
+ goto err_node_put;
+@@ -240,6 +286,10 @@ static int __init sifive_ccache_init(voi
+
+ for (i = 0; i < intr_num; i++) {
+ g_irq[i] = irq_of_parse_and_map(np, i);
++
++ if (i == DATA_UNCORR && (quirks & QUIRK_BROKEN_DATA_UNCORR))
++ continue;
++
+ rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
+ NULL);
+ if (rc) {
+@@ -249,6 +299,14 @@ static int __init sifive_ccache_init(voi
+ }
+ of_node_put(np);
+
++#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
++ if (quirks & QUIRK_NONSTANDARD_CACHE_OPS) {
++ riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
++ riscv_noncoherent_supported();
++ riscv_noncoherent_register_cache_ops(&ccache_mgmt_ops);
++ }
++#endif
++
+ ccache_config_read();
+
+ ccache_cache_ops.get_priv_group = ccache_get_priv_group;
+@@ -269,4 +327,4 @@ err_node_put:
+ return rc;
+ }
+
+-device_initcall(sifive_ccache_init);
++arch_initcall(sifive_ccache_init);
diff --git a/target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch b/target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch
new file mode 100644
index 0000000000..91b3adfac1
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch
@@ -0,0 +1,44 @@
+From 30fb5963f4cf3b7d114a8212358147615480685c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:25 +0100
+Subject: [PATCH 1017/1024] riscv: errata: Add StarFive JH7100 errata
+
+This not really an errata, but since the JH7100 was made before
+the standard Zicbom extension it needs the DMA_GLOBAL_POOL and
+RISCV_NONSTANDARD_CACHE_OPS enabled to work correctly.
+
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/Kconfig.errata | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/riscv/Kconfig.errata
++++ b/arch/riscv/Kconfig.errata
+@@ -53,6 +53,23 @@ config ERRATA_SIFIVE_CIP_1200
+
+ If you don't know what to do here, say "Y".
+
++config ERRATA_STARFIVE_JH7100
++ bool "StarFive JH7100 support"
++ depends on ARCH_STARFIVE && NONPORTABLE
++ select DMA_GLOBAL_POOL
++ select RISCV_DMA_NONCOHERENT
++ select RISCV_NONSTANDARD_CACHE_OPS
++ select SIFIVE_CCACHE
++ default n
++ help
++ The StarFive JH7100 was a test chip for the JH7110 and has
++ caches that are non-coherent with respect to peripheral DMAs.
++ It was designed before the Zicbom extension so needs non-standard
++ cache operations through the SiFive cache controller.
++
++ Say "Y" if you want to support the BeagleV Starlight and/or
++ StarFive VisionFive V1 boards.
++
+ config ERRATA_THEAD
+ bool "T-HEAD errata"
+ depends on RISCV_ALTERNATIVE
diff --git a/target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch b/target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch
new file mode 100644
index 0000000000..0b223c5925
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch
@@ -0,0 +1,26 @@
+From 29e4bc0fafd9add93acc967f3992948b3afe7176 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 30 Nov 2023 16:19:27 +0100
+Subject: [PATCH 1018/1024] riscv: dts: starfive: Mark the JH7100 as having
+ non-coherent DMAs
+
+The StarFive JH7100 SoC has non-coherent device DMAs, so mark the
+soc bus as such.
+
+Link: https://github.com/starfive-tech/JH7100_Docs/blob/main/JH7100%20Cache%20Coherence%20V1.0.pdf
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -138,6 +138,7 @@
+ interrupt-parent = <&plic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
++ dma-noncoherent;
+ ranges;
+
+ clint: clint@2000000 {
diff --git a/target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch b/target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch
new file mode 100644
index 0000000000..cdc63fac65
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch
@@ -0,0 +1,50 @@
+From e1918356dcc285eb7c50f271795e6fcc18d6c092 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:28 +0100
+Subject: [PATCH 1019/1024] riscv: dts: starfive: Add JH7100 cache controller
+
+The StarFive JH7100 SoC also features the SiFive L2 cache controller,
+so add the device tree nodes for it.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -32,6 +32,7 @@
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
+
+@@ -57,6 +58,7 @@
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
+
+@@ -148,6 +150,17 @@
+ &cpu1_intc 3 &cpu1_intc 7>;
+ };
+
++ ccache: cache-controller@2010000 {
++ compatible = "starfive,jh7100-ccache", "sifive,ccache0", "cache";
++ reg = <0x0 0x2010000 0x0 0x1000>;
++ interrupts = <128>, <130>, <131>, <129>;
++ cache-block-size = <64>;
++ cache-level = <2>;
++ cache-sets = <2048>;
++ cache-size = <2097152>;
++ cache-unified;
++ };
++
+ plic: interrupt-controller@c000000 {
+ compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
+ reg = <0x0 0xc000000 0x0 0x4000000>;
diff --git a/target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch b/target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch
new file mode 100644
index 0000000000..c9ba3884f6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch
@@ -0,0 +1,61 @@
+From 3cbd661b811bda9a33253f65b5cf0c25b8c5447f Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:29 +0100
+Subject: [PATCH 1020/1024] riscv: dts: starfive: Add pool for coherent DMA
+ memory on JH7100 boards
+
+The StarFive JH7100 SoC has non-coherent device DMAs, but most drivers
+expect to be able to allocate coherent memory for DMA descriptors and
+such. However on the JH7100 DDR memory appears twice in the physical
+memory map, once cached and once uncached:
+
+ 0x00_8000_0000 - 0x08_7fff_ffff : Off chip DDR memory, cached
+ 0x10_0000_0000 - 0x17_ffff_ffff : Off chip DDR memory, uncached
+
+To use this uncached region we create a global DMA memory pool there and
+reserve the corresponding area in the cached region.
+
+However the uncached region is fully above the 32bit address limit, so add
+a dma-ranges map so the DMA address used for peripherals is still in the
+regular cached region below the limit.
+
+Link: https://github.com/starfive-tech/JH7100_Docs/blob/main/JH7100%20Data%20Sheet%20V01.01.04-EN%20(4-21-2021).pdf
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../boot/dts/starfive/jh7100-common.dtsi | 24 +++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -39,6 +39,30 @@
+ label = "ack";
+ };
+ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ dma-reserved@fa000000 {
++ reg = <0x0 0xfa000000 0x0 0x1000000>;
++ no-map;
++ };
++
++ linux,dma@107a000000 {
++ compatible = "shared-dma-pool";
++ reg = <0x10 0x7a000000 0x0 0x1000000>;
++ no-map;
++ linux,dma-default;
++ };
++ };
++
++ soc {
++ dma-ranges = <0x00 0x80000000 0x00 0x80000000 0x00 0x7a000000>,
++ <0x00 0xfa000000 0x10 0x7a000000 0x00 0x01000000>,
++ <0x00 0xfb000000 0x00 0xfb000000 0x07 0x85000000>;
++ };
+ };
+
+ &gpio {
diff --git a/target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch b/target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch
new file mode 100644
index 0000000000..fb3ba521c9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch
@@ -0,0 +1,49 @@
+From 7be159c760aa8a1ece1354892af215b2f8c21152 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:30 +0100
+Subject: [PATCH 1021/1024] riscv: dts: starfive: Add JH7100 MMC nodes
+
+Add device tree nodes for the Synopsis MMC controllers on the
+StarFive JH7100 SoC.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 26 ++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -188,6 +188,32 @@
+ #reset-cells = <1>;
+ };
+
++ sdio0: mmc@10000000 {
++ compatible = "snps,dw-mshc";
++ reg = <0x0 0x10000000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SDIO0_AHB>,
++ <&clkgen JH7100_CLK_SDIO0_CCLKINT_INV>;
++ clock-names = "biu", "ciu";
++ interrupts = <4>;
++ data-addr = <0>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ status = "disabled";
++ };
++
++ sdio1: mmc@10010000 {
++ compatible = "snps,dw-mshc";
++ reg = <0x0 0x10010000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SDIO1_AHB>,
++ <&clkgen JH7100_CLK_SDIO1_CCLKINT_INV>;
++ clock-names = "biu", "ciu";
++ interrupts = <5>;
++ data-addr = <0>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ status = "disabled";
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch b/target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch
new file mode 100644
index 0000000000..bf380eb833
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch
@@ -0,0 +1,85 @@
+From 015edaccef82200d913d5f1e99fd95641f526bc6 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:31 +0100
+Subject: [PATCH 1022/1024] riscv: dts: starfive: Enable SD-card on JH7100
+ boards
+
+Add pinctrl and MMC device tree nodes for the SD-card on the
+BeagleV Starlight and StarFive VisionFive V1 boards.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../boot/dts/starfive/jh7100-common.dtsi | 47 +++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -12,6 +12,7 @@
+
+ / {
+ aliases {
++ mmc0 = &sdio0;
+ serial0 = &uart3;
+ };
+
+@@ -108,6 +109,43 @@
+ };
+ };
+
++ sdio0_pins: sdio0-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(55, GPO_LOW, GPO_DISABLE,
++ GPI_SDIO0_PAD_CARD_DETECT_N)>,
++ <GPIOMUX(53,
++ GPO_SDIO0_PAD_CCMD_OUT,
++ GPO_SDIO0_PAD_CCMD_OEN,
++ GPI_SDIO0_PAD_CCMD_IN)>,
++ <GPIOMUX(49,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO0_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(50,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO0_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(51,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO0_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(52,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO0_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
+ uart3_pins: uart3-0 {
+ rx-pins {
+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
+@@ -178,6 +216,15 @@
+ clock-frequency = <27000000>;
+ };
+
++&sdio0 {
++ broken-cd;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio0_pins>;
++ status = "okay";
++};
++
+ &uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
diff --git a/target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch b/target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch
new file mode 100644
index 0000000000..2b782e1129
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch
@@ -0,0 +1,33 @@
+From 1e70a0772165dd552f82434c9072dabfaaaf4c2a Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Fri, 15 Dec 2023 20:09:09 +0100
+Subject: [PATCH 1023/1024] riscv: errata: Make ERRATA_STARFIVE_JH7100 depend
+ on !DMA_DIRECT_REMAP
+
+Similar to the Renesas RZ/Five[1] the JH7100 SoC needs the non-portable
+CONFIG_DMA_GLOBAL_POOL enabled which is incompatible with DMA_DIRECT_REMAP
+selected by RISCV_ISA_ZICBOM.
+
+[1]: commit 31b2daea0764 ("soc: renesas: Make RZ/Five depend on !DMA_DIRECT_REMAP")
+
+Link: https://lore.kernel.org/all/24942b4d-d16a-463f-b39a-f9dfcb89d742@infradead.org/
+Fixes: 64fc984a8a54 ("riscv: errata: Add StarFive JH7100 errata")
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/Kconfig.errata | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/arch/riscv/Kconfig.errata
++++ b/arch/riscv/Kconfig.errata
+@@ -55,7 +55,9 @@ config ERRATA_SIFIVE_CIP_1200
+
+ config ERRATA_STARFIVE_JH7100
+ bool "StarFive JH7100 support"
+- depends on ARCH_STARFIVE && NONPORTABLE
++ depends on ARCH_STARFIVE
++ depends on !DMA_DIRECT_REMAP
++ depends on NONPORTABLE
+ select DMA_GLOBAL_POOL
+ select RISCV_DMA_NONCOHERENT
+ select RISCV_NONSTANDARD_CACHE_OPS
diff --git a/target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch b/target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
new file mode 100644
index 0000000000..b20c2d8bf5
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
@@ -0,0 +1,1138 @@
+From 782f99cc437d975c9ef5a1f351bb8fb83d50039b Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sun, 1 Sep 2024 12:43:01 +0000
+Subject: [PATCH 1024/1024] riscv: dts: Add full JH7100, Starlight and
+ VisionFive support
+
+Based on the device tree in https://github.com/starfive-tech/u-boot/
+with contributions from:
+yanhong.wang <yanhong.wang@starfivetech.com>
+Huan.Feng <huan.feng@starfivetech.com>
+ke.zhu <ke.zhu@starfivetech.com>
+yiming.li <yiming.li@starfivetech.com>
+jack.zhu <jack.zhu@starfivetech.com>
+Samin Guo <samin.guo@starfivetech.com>
+Chenjieqin <Jessica.Chen@starfivetech.com>
+bo.li <bo.li@starfivetech.com>
+
+Rearranged, cleanups, fixes, pins and resets added by Emil.
+Cleanups, fixes, clocks added by Geert.
+Cleanups and GPIO fixes from Drew.
+Thermal zone added by Stephen.
+PWM pins added by Jianlong.
+cpu-map added by Jonas.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Stephen L Arnold <nerdboy@gentoo.org>
+Signed-off-by: Drew Fustini <drew@beagleboard.org>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Jonas Hahnfeld <hahnjo@hahnjo.de>
+---
+ .../dts/starfive/jh7100-beaglev-starlight.dts | 16 +
+ .../boot/dts/starfive/jh7100-common.dtsi | 432 +++++++++++++++
+ .../jh7100-starfive-visionfive-v1.dts | 19 +
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 503 ++++++++++++++++++
+ 4 files changed, 970 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
++++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+@@ -6,8 +6,24 @@
+
+ /dts-v1/;
+ #include "jh7100-common.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "BeagleV Starlight Beta";
+ compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
+ };
++
++&gmac {
++ snps,reset-gpios = <&gpio 63 GPIO_ACTIVE_LOW>;
++};
++
++&gpio {
++ /* don't reset gpio mux for serial console on uart3 */
++ starfive,keep-gpiomux = <13 14>;
++};
++
++&mdio {
++ phy: ethernet-phy@7 {
++ reg = <7>;
++ };
++};
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -14,6 +14,7 @@
+ aliases {
+ mmc0 = &sdio0;
+ serial0 = &uart3;
++ serial1 = &uart0;
+ };
+
+ chosen {
+@@ -64,9 +65,174 @@
+ <0x00 0xfa000000 0x10 0x7a000000 0x00 0x01000000>,
+ <0x00 0xfb000000 0x00 0xfb000000 0x07 0x85000000>;
+ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ size = <0x0 0x28000000>;
++ alignment = <0x0 0x1000>;
++ alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
++ linux,cma-default;
++ };
++
++ jpu_reserved: framebuffer@c9000000 {
++ reg = <0x0 0xc9000000 0x0 0x4000000>;
++ };
++
++ nvdla_reserved: framebuffer@d0000000 {
++ no-map;
++ reg = <0x0 0xd0000000 0x0 0x28000000>;
++ };
++
++ vin_reserved: framebuffer@f9000000 {
++ compatible = "shared-dma-pool";
++ no-map;
++ reg = <0x0 0xf9000000 0x0 0x1000000>;
++ };
++
++ sffb_reserved: framebuffer@fb000000 {
++ compatible = "shared-dma-pool";
++ no-map;
++ reg = <0x0 0xfb000000 0x0 0x2000000>;
++ };
++ };
++
++ wifi_pwrseq: wifi-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&display {
++ memory-region = <&sffb_reserved>;
++ status = "okay";
++};
++
++&crtc {
++ ddr-format = <4>; //<WIN_FMT_RGB565>;
++ status = "okay";
++
++ port: port@0 {
++ reg = <0>;
++
++ crtc_0_out: endpoint {
++ remote-endpoint = <&hdmi_input0>;
++ };
++ };
++};
++
++&encoder {
++ encoder-type = <2>; // 2-TMDS, 3-LVDS, 6-DSI, 8-DPI
++ status = "okay";
++
++ ports {
++ port@0 {
++ hdmi_out: endpoint {
++ remote-endpoint = <&tda998x_0_input>;
++ };
++ };
++
++ port@1 {
++ hdmi_input0: endpoint {
++ remote-endpoint = <&crtc_0_out>;
++ };
++ };
++
++ };
++};
++
++&gmac {
++ starfive,gtxclk-dlychain = <4>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac_pins>;
++ phy-mode = "rgmii-txid";
++ phy-handle = <&phy>;
++ status = "okay";
++
++ mdio: mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "snps,dwmac-mdio";
++ };
+ };
+
+ &gpio {
++ gmac_pins: gmac-0 {
++ gtxclk-pins {
++ pins = <PAD_FUNC_SHARE(115)>;
++ bias-pull-up;
++ drive-strength = <35>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ miitxclk-pins {
++ pins = <PAD_FUNC_SHARE(116)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ tx-pins {
++ pins = <PAD_FUNC_SHARE(117)>,
++ <PAD_FUNC_SHARE(119)>,
++ <PAD_FUNC_SHARE(120)>,
++ <PAD_FUNC_SHARE(121)>,
++ <PAD_FUNC_SHARE(122)>,
++ <PAD_FUNC_SHARE(123)>,
++ <PAD_FUNC_SHARE(124)>,
++ <PAD_FUNC_SHARE(125)>,
++ <PAD_FUNC_SHARE(126)>;
++ bias-pull-up;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ rxclk-pins {
++ pins = <PAD_FUNC_SHARE(127)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <6>;
++ };
++ rxer-pins {
++ pins = <PAD_FUNC_SHARE(129)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ rx-pins {
++ pins = <PAD_FUNC_SHARE(128)>,
++ <PAD_FUNC_SHARE(130)>,
++ <PAD_FUNC_SHARE(131)>,
++ <PAD_FUNC_SHARE(132)>,
++ <PAD_FUNC_SHARE(133)>,
++ <PAD_FUNC_SHARE(134)>,
++ <PAD_FUNC_SHARE(135)>,
++ <PAD_FUNC_SHARE(136)>,
++ <PAD_FUNC_SHARE(137)>,
++ <PAD_FUNC_SHARE(138)>,
++ <PAD_FUNC_SHARE(139)>,
++ <PAD_FUNC_SHARE(140)>,
++ <PAD_FUNC_SHARE(141)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
+ i2c0_pins: i2c0-0 {
+ i2c-pins {
+ pinmux = <GPIOMUX(62, GPO_LOW,
+@@ -146,6 +312,166 @@
+ };
+ };
+
++ pwmdac_pins: pwmdac-0 {
++ pwmdac-pins {
++ pinmux = <GPIOMUX(23, GPO_PWMDAC_LEFT_OUT,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(24, GPO_PWMDAC_RIGHT_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pwm_pins: pwm-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(7,
++ GPO_PWM_PAD_OUT_BIT0,
++ GPO_PWM_PAD_OE_N_BIT0,
++ GPI_NONE)>,
++ <GPIOMUX(5,
++ GPO_PWM_PAD_OUT_BIT1,
++ GPO_PWM_PAD_OE_N_BIT1,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ sdio0_pins: sdio0-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(55, GPO_LOW, GPO_DISABLE,
++ GPI_SDIO0_PAD_CARD_DETECT_N)>,
++ <GPIOMUX(53,
++ GPO_SDIO0_PAD_CCMD_OUT,
++ GPO_SDIO0_PAD_CCMD_OEN,
++ GPI_SDIO0_PAD_CCMD_IN)>,
++ <GPIOMUX(49,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO0_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(50,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO0_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(51,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO0_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(52,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO0_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ sdio1_pins: sdio1-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(33, GPO_SDIO1_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(29,
++ GPO_SDIO1_PAD_CCMD_OUT,
++ GPO_SDIO1_PAD_CCMD_OEN,
++ GPI_SDIO1_PAD_CCMD_IN)>,
++ <GPIOMUX(36,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO1_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(30,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO1_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(34,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO1_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(31,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO1_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ spi2_pins: spi2-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(18, GPO_SPI2_PAD_TXD,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ miso-pins {
++ pinmux = <GPIOMUX(16, GPO_LOW, GPO_DISABLE,
++ GPI_SPI2_PAD_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ sck-pins {
++ pinmux = <GPIOMUX(12, GPO_SPI2_PAD_SCK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ ss-pins {
++ pinmux = <GPIOMUX(15, GPO_SPI2_PAD_SS_0_N,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(11, GPO_SPI2_PAD_SS_1_N,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ uart0_pins: uart0-0 {
++ rx-pins {
++ pinmux = <GPIOMUX(40, GPO_LOW, GPO_DISABLE,
++ GPI_UART0_PAD_SIN)>,
++ <GPIOMUX(39, GPO_LOW, GPO_DISABLE,
++ GPI_UART0_PAD_CTSN)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-enable;
++ };
++ tx-pins {
++ pinmux = <GPIOMUX(41, GPO_UART0_PAD_SOUT,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(42, GPO_UART0_PAD_RTSN,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
+ uart3_pins: uart3-0 {
+ rx-pins {
+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
+@@ -186,6 +512,17 @@
+ regulators {
+ };
+ };
++
++ tda998x@70 {
++ compatible = "nxp,tda998x";
++ reg = <0x70>;
++
++ port {
++ tda998x_0_input: endpoint {
++ remote-endpoint = <&hdmi_out>;
++ };
++ };
++ };
+ };
+
+ &i2c1 {
+@@ -225,8 +562,104 @@
+ status = "okay";
+ };
+
++&ptc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_pins>;
++ status = "okay";
++};
++
++&pwmdac {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwmdac_pins>;
++ status = "okay";
++};
++
++&qspi {
++ nor_flash: nor-flash@0 {
++ compatible = "spi-flash";
++ reg = <0>;
++ spi-max-frequency = <31250000>;
++ page-size = <256>;
++ block-size = <16>;
++ cdns,read-delay = <4>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++ spi-tx-bus-width = <1>;
++ spi-rx-bus-width = <1>;
++ };
++
++ nand_flash: nand-flash@1 {
++ compatible = "spi-flash-nand";
++ reg = <1>;
++ spi-max-frequency = <31250000>;
++ page-size = <2048>;
++ block-size = <17>;
++ cdns,read-delay = <4>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++ spi-tx-bus-width = <1>;
++ spi-rx-bus-width = <1>;
++ };
++};
++
++&sdio0 {
++ broken-cd;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio0_pins>;
++ max-frequency = <10000000>;
++ status = "okay";
++};
++
++&sdio1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ cap-power-off-card;
++ mmc-pwrseq = <&wifi_pwrseq>;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio1_pins>;
++ status = "okay";
++
++ wifi@1 {
++ compatible = "brcm,bcm4329-fmac";
++ reg = <1>;
++ };
++};
++
++&spi2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins>;
++ status = "okay";
++
++ spi_dev0: spi@0 {
++ compatible = "rohm,dh2228fv";
++ spi-max-frequency = <10000000>;
++ reg = <0>;
++ };
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins>;
++ status = "okay";
++};
++
+ &uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ status = "okay";
+ };
++
++&usb3 {
++ dr_mode = "host";
++ status = "okay";
++};
+--- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
++++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+@@ -18,3 +18,22 @@
+ priority = <224>;
+ };
+ };
++
++&gpio {
++ /* don't reset gpio mux for serial console and reset gpio */
++ starfive,keep-gpiomux = <13 14 63>;
++};
++
++&i2c0 {
++ eeprom@50 {
++ compatible = "atmel,24c04";
++ reg = <0x50>;
++ pagesize = <16>;
++ };
++};
++
++&mdio {
++ phy: ethernet-phy@0 {
++ reg = <0>;
++ };
++};
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -6,7 +6,9 @@
+
+ /dts-v1/;
+ #include <dt-bindings/clock/starfive-jh7100.h>
++#include <dt-bindings/clock/starfive-jh7100-audio.h>
+ #include <dt-bindings/reset/starfive-jh7100.h>
++#include <dt-bindings/reset/starfive-jh7100-audio.h>
+
+ / {
+ compatible = "starfive,jh7100";
+@@ -135,6 +137,13 @@
+ clock-frequency = <0>;
+ };
+
++ /* gmac device configuration */
++ stmmac_axi_setup: stmmac-axi-config {
++ snps,wr_osr_lmt = <0xf>;
++ snps,rd_osr_lmt = <0xf>;
++ snps,blen = <256 128 64 32 0 0 0>;
++ };
++
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
+@@ -143,6 +152,24 @@
+ dma-noncoherent;
+ ranges;
+
++ dtim: dtim@1000000 {
++ compatible = "starfive,dtim0";
++ reg = <0x0 0x1000000 0x0 0x2000>;
++ reg-names = "mem";
++ };
++
++ itim0: itim@1808000 {
++ compatible = "starfive,itim0";
++ reg = <0x0 0x1808000 0x0 0x8000>;
++ reg-names = "mem";
++ };
++
++ itim1: itim@1820000 {
++ compatible = "starfive,itim0";
++ reg = <0x0 0x1820000 0x0 0x8000>;
++ reg-names = "mem";
++ };
++
+ clint: clint@2000000 {
+ compatible = "starfive,jh7100-clint", "sifive,clint0";
+ reg = <0x0 0x2000000 0x0 0x10000>;
+@@ -172,6 +199,151 @@
+ riscv,ndev = <133>;
+ };
+
++ gmac: ethernet@10020000 {
++ compatible = "starfive,jh7100-dwmac", "snps,dwmac";
++ reg = <0x0 0x10020000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_GMAC_ROOT_DIV>,
++ <&clkgen JH7100_CLK_GMAC_AHB>,
++ <&clkgen JH7100_CLK_GMAC_PTP_REF>,
++ <&clkgen JH7100_CLK_GMAC_TX_INV>,
++ <&clkgen JH7100_CLK_GMAC_GTX>;
++ clock-names = "stmmaceth", "pclk", "ptp_ref", "tx", "gtx";
++ resets = <&rstgen JH7100_RSTN_GMAC_AHB>;
++ reset-names = "ahb";
++ interrupts = <6>, <7>;
++ interrupt-names = "macirq", "eth_wake_irq";
++ max-frame-size = <9000>;
++ snps,multicast-filter-bins = <0>;
++ snps,perfect-filter-entries = <128>;
++ starfive,syscon = <&sysmain 0x70 0>;
++ rx-fifo-depth = <32768>;
++ tx-fifo-depth = <16384>;
++ snps,axi-config = <&stmmac_axi_setup>;
++ snps,fixed-burst;
++ /*snps,force_sf_dma_mode;*/
++ snps,force_thresh_dma_mode;
++ snps,no-pbl-x8;
++ status = "disabled";
++ };
++
++ dma2p: dma-controller@100b0000 {
++ compatible = "starfive,jh7100-axi-dma";
++ reg = <0x0 0x100b0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SGDMA2P_AXI>,
++ <&clkgen JH7100_CLK_SGDMA2P_AHB>;
++ clock-names = "core-clk", "cfgr-clk";
++ resets = <&rstgen JH7100_RSTN_SGDMA2P_AXI>,
++ <&rstgen JH7100_RSTN_SGDMA2P_AHB>;
++ reset-names = "axi", "ahb";
++ interrupts = <2>;
++ #dma-cells = <1>;
++ dma-channels = <4>;
++ snps,dma-masters = <1>;
++ snps,data-width = <4>;
++ snps,block-size = <4096 4096 4096 4096>;
++ snps,priority = <0 1 2 3>;
++ snps,axi-max-burst-len = <128>;
++ dma-coherent;
++ };
++
++ crypto: crypto@100d0000 {
++ compatible = "starfive,vic-sec";
++ reg = <0x0 0x100d0000 0x0 0x20000>,
++ <0x0 0x11800234 0x0 0xc>;
++ reg-names = "secmem", "secclk";
++ clocks = <&clkgen JH7100_CLK_SEC_AHB>;
++ interrupts = <31>;
++ };
++
++ i2sadc0: i2sadc0@10400000 {
++ compatible = "snps,designware-i2sadc0";
++ reg = <0x0 0x10400000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
++ clock-names = "i2sclk";
++ interrupt-parent = <&plic>;
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 28>;
++ dma-names = "rx";
++ };
++
++ i2svad: i2svad@10420000 {
++ compatible = "starfive,sf-i2svad";
++ reg = <0x0 0x10420000 0x0 0x1000> ;
++ clocks = <&audclk JH7100_AUDCLK_I2SVAD_APB>;
++ clock-names = "i2svad_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2SVAD_APB>,
++ <&audrst JH7100_AUDRSTN_I2SVAD_SRST>;
++ reset-names = "apb_i2svad", "i2svad_srst";
++ interrupts = <60>, <61>;
++ interrupt-names = "spintr", "slintr";
++ #sound-dai-cells = <0>;
++ };
++
++ pwmdac: pwmdac@10440000 {
++ compatible = "starfive,pwmdac";
++ reg = <0x0 0x10440000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_AUDIO_ROOT>,
++ <&clkgen JH7100_CLK_AUDIO_SRC>,
++ <&clkgen JH7100_CLK_AUDIO_12288>,
++ <&audclk JH7100_AUDCLK_DMA1P_AHB>,
++ <&audclk JH7100_AUDCLK_PWMDAC_APB>,
++ <&audclk JH7100_AUDCLK_DAC_MCLK>;
++ clock-names = "audio_root",
++ "audio_src",
++ "audio_12288",
++ "dma1p_ahb",
++ "pwmdac_apb",
++ "dac_mclk";
++ resets = <&audrst JH7100_AUDRSTN_APB_BUS>,
++ <&audrst JH7100_AUDRSTN_DMA1P_AHB>,
++ <&audrst JH7100_AUDRSTN_PWMDAC_APB>;
++ reset-names = "apb_bus", "dma1p_ahb", "apb_pwmdac";
++ dmas = <&dma2p 23>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ };
++
++ i2sdac0: i2sdac0@10450000 {
++ compatible = "snps,designware-i2sdac0";
++ reg = <0x0 0x10450000 0x0 0x1000>;
++ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_BCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_LRCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_APB>;
++ clock-names = "dac_mclk", "i2sdac0_bclk", "i2sdac0_lrclk", "i2sdac_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2SDAC_APB>,
++ <&audrst JH7100_AUDRSTN_I2SDAC_SRST>;
++ reset-names = "apb_i2sdac", "i2sdac_srst";
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 30>;
++ dma-names = "tx";
++ };
++
++ i2sdac1: i2sdac1@10460000 {
++ compatible = "snps,designware-i2sdac1";
++ reg = <0x0 0x10460000 0x0 0x1000>;
++ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_BCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_LRCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_APB>;
++ clock-names = "dac_mclk", "i2sdac1_bclk", "i2sdac1_lrclk", "i2s1_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2S1_APB>,
++ <&audrst JH7100_AUDRSTN_I2S1_SRST>;
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 31>;
++ dma-names = "tx";
++ };
++
++ i2sdac16k: i2sdac16k@10470000 {
++ compatible = "snps,designware-i2sdac16k";
++ reg = <0x0 0x10470000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
++ clock-names = "i2sclk";
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 29>;
++ dma-names = "tx";
++ };
++
+ audclk: clock-controller@10480000 {
+ compatible = "starfive,jh7100-audclk";
+ reg = <0x0 0x10480000 0x0 0x10000>;
+@@ -214,6 +386,82 @@
+ status = "disabled";
+ };
+
++ spdif_transmitter: spdif-transmitter {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ spdif_receiver: spdif-receiver {
++ compatible = "linux,spdif-dir";
++ #sound-dai-cells = <0>;
++ };
++
++ pwmdac_codec: pwmdac-transmitter {
++ compatible = "linux,pwmdac-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ dmic_codec: dmic {
++ compatible = "dmic-codec";
++ #sound-dai-cells = <0>;
++ };
++
++ sound: snd-card {
++ compatible = "simple-audio-card";
++ simple-audio-card,name = "Starfive-Multi-Sound-Card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* pwmdac */
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ status = "okay";
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&pwmdac>;
++ };
++
++ codec {
++ sound-dai = <&pwmdac_codec>;
++ };
++ };
++ };
++
++ usb3: usb@104c0000 {
++ compatible = "cdns,usb3";
++ reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers
++ <0x0 0x104d0000 0x0 0x10000>, // memory area for DEVICE registers
++ <0x0 0x104e0000 0x0 0x10000>; // memory area for OTG/DRD registers
++ reg-names = "otg", "xhci", "dev";
++ interrupts = <44>, <52>, <43>;
++ interrupt-names = "host", "peripheral", "otg";
++ phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy";
++ maximum-speed = "super-speed";
++ status = "disabled";
++ };
++
++ dma1p: dma-controller@10500000 {
++ compatible = "starfive,jh7100-axi-dma";
++ reg = <0x0 0x10500000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SGDMA1P_AXI>,
++ <&clkgen JH7100_CLK_SGDMA1P_BUS>;
++ clock-names = "core-clk", "cfgr-clk";
++ resets = <&rstgen JH7100_RSTN_DMA1P_AXI>,
++ <&rstgen JH7100_RSTN_SGDMA1P_AXI>;
++ reset-names = "axi", "ahb";
++ interrupts = <1>;
++ #dma-cells = <1>;
++ dma-channels = <16>;
++ snps,dma-masters = <1>;
++ snps,data-width = <3>;
++ snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
++ snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
++ snps,axi-max-burst-len = <64>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
+@@ -222,12 +470,93 @@
+ #clock-cells = <1>;
+ };
+
++ otp: otp@11810000 {
++ compatible = "starfive,fu740-otp";
++ reg = <0x0 0x11810000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_OTP_APB>;
++ fuse-count = <0x200>;
++ };
++
+ rstgen: reset-controller@11840000 {
+ compatible = "starfive,jh7100-reset";
+ reg = <0x0 0x11840000 0x0 0x10000>;
+ #reset-cells = <1>;
+ };
+
++ sysmain: syscon@11850000 {
++ compatible = "starfive,jh7100-sysmain", "syscon";
++ reg = <0x0 0x11850000 0x0 0x10000>;
++ };
++
++ qspi: spi@11860000 {
++ compatible = "cdns,qspi-nor";
++ reg = <0x0 0x11860000 0x0 0x10000>,
++ <0x0 0x20000000 0x0 0x20000000>;
++ clocks = <&clkgen JH7100_CLK_QSPI_AHB>;
++ interrupts = <3>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ cdns,fifo-depth = <256>;
++ cdns,fifo-width = <4>;
++ cdns,trigger-address = <0x0>;
++ spi-max-frequency = <250000000>;
++ status = "disabled";
++ };
++
++ uart0: serial@11870000 {
++ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
++ reg = <0x0 0x11870000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_UART0_CORE>,
++ <&clkgen JH7100_CLK_UART0_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&rstgen JH7100_RSTN_UART0_APB>;
++ interrupts = <92>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart1: serial@11880000 {
++ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
++ reg = <0x0 0x11880000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_UART1_CORE>,
++ <&clkgen JH7100_CLK_UART1_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&rstgen JH7100_RSTN_UART1_APB>;
++ interrupts = <93>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ spi0: spi@11890000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x11890000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI0_CORE>,
++ <&clkgen JH7100_CLK_SPI0_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI0_APB>;
++ reset-names = "spi";
++ interrupts = <94>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi1: spi@118a0000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x118a0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI1_CORE>,
++ <&clkgen JH7100_CLK_SPI1_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI1_APB>;
++ reset-names = "spi";
++ interrupts = <95>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ i2c0: i2c@118b0000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x118b0000 0x0 0x10000>;
+@@ -254,6 +583,41 @@
+ status = "disabled";
+ };
+
++ trng: trng@118d0000 {
++ compatible = "starfive,vic-rng";
++ reg = <0x0 0x118d0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_TRNG_APB>;
++ interrupts = <98>;
++ };
++
++ vpu_enc: vpu_enc@118e0000 {
++ compatible = "cm,cm521-vpu";
++ reg = <0x0 0x118e0000 0x0 0x4000>;
++ reg-names = "control";
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ clock-names = "vcodec";
++ interrupts = <26>;
++ };
++
++ vpu_dec: vpu_dec@118f0000 {
++ compatible = "c&m,cm511-vpu";
++ reg = <0 0x118f0000 0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ clock-names = "vcodec";
++ interrupts = <23>;
++ //memory-region = <&vpu_reserved>;
++ };
++
++ jpu: coadj12@11900000 {
++ compatible = "cm,codaj12-jpu-1";
++ reg = <0x0 0x11900000 0x0 0x300>;
++ reg-names = "control";
++ clocks = <&clkgen JH7100_CLK_JPEG_APB>;
++ clock-names = "jpege";
++ interrupts = <24>;
++ memory-region = <&jpu_reserved>;
++ };
++
+ gpio: pinctrl@11910000 {
+ compatible = "starfive,jh7100-pinctrl";
+ reg = <0x0 0x11910000 0x0 0x10000>,
+@@ -268,6 +632,86 @@
+ #interrupt-cells = <2>;
+ };
+
++ nvdla@11940000 {
++ compatible = "nvidia,nvdla_os_initial";
++ interrupts = <22>;
++ memory-region = <&nvdla_reserved>;
++ reg = <0x0 0x11940000 0x0 0x40000>;
++ status = "okay";
++ };
++
++ display: display-subsystem {
++ compatible = "starfive,display-subsystem";
++ dma-coherent;
++ status = "disabled";
++ };
++
++ encoder: display-encoder {
++ compatible = "starfive,display-encoder";
++ status = "disabled";
++ };
++
++ crtc: crtc@12000000 {
++ compatible = "starfive,jh7100-crtc";
++ reg = <0x0 0x12000000 0x0 0x10000>,
++ <0x0 0x12040000 0x0 0x10000>,
++ <0x0 0x12080000 0x0 0x10000>,
++ <0x0 0x120c0000 0x0 0x10000>,
++ <0x0 0x12240000 0x0 0x10000>,
++ <0x0 0x12250000 0x0 0x10000>,
++ <0x0 0x12260000 0x0 0x10000>;
++ reg-names = "lcdc", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
++ clocks = <&clkgen JH7100_CLK_DISP_AXI>, <&clkgen JH7100_CLK_VOUT_SRC>;
++ clock-names = "disp_axi", "vout_src";
++ resets = <&rstgen JH7100_RSTN_DISP_AXI>, <&rstgen JH7100_RSTN_VOUT_SRC>;
++ reset-names = "disp_axi", "vout_src";
++ interrupts = <101>, <103>;
++ interrupt-names = "lcdc_irq", "vpp1_irq";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pp1 {
++ pp-id = <1>;
++ fifo-out;
++ //sys-bus-out;
++ src-format = <11>; //<COLOR_RGB565>;
++ src-width = <1920>;
++ src-height = <1080>;
++ dst-format = <7>; //<COLOR_RGB888_ARGB>;
++ dst-width = <1920>;
++ dst-height = <1080>;
++ };
++ };
++
++ spi2: spi@12410000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x12410000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI2_CORE>,
++ <&clkgen JH7100_CLK_SPI2_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI2_APB>;
++ reset-names = "spi";
++ interrupts = <70>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi3: spi@12420000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x12420000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI3_CORE>,
++ <&clkgen JH7100_CLK_SPI3_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI3_APB>;
++ reset-names = "spi";
++ interrupts = <71>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ uart2: serial@12430000 {
+ compatible = "starfive,jh7100-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x12430000 0x0 0x10000>;
+@@ -341,5 +785,64 @@
+ reset-names = "sense", "bus";
+ #thermal-sensor-cells = <0>;
+ };
++
++ ptc: pwm@12490000 {
++ compatible = "starfive,pwm0";
++ reg = <0x0 0x12490000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_PWM_APB>;
++ resets = <&rstgen JH7100_RSTN_PWM_APB>;
++ #pwm-cells = <3>;
++ sifive,npwm = <8>;
++ status = "disabled";
++ };
++
++ thermal-zones {
++ cpu-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <15000>;
++
++ thermal-sensors = <&sfctemp>;
++
++ cooling-maps {
++ };
++
++ trips {
++ cpu_alert0: cpu_alert0 {
++ /* milliCelsius */
++ temperature = <75000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ cpu_crit: cpu_crit {
++ /* milliCelsius */
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++ };
++
++ xrp@f0000000 {
++ compatible = "cdns,xrp";
++ reg = <0x0 0xf0000000 0x0 0x01ffffff>,
++ <0x10 0x72000000 0x0 0x00001000>,
++ <0x10 0x72001000 0x0 0x00fff000>,
++ <0x0 0x124b0000 0x0 0x00010000>;
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ interrupts = <27>, <28>;
++ firmware-name = "vp6_elf";
++ dsp-irq = <19 20>;
++ dsp-irq-src = <0x20 0x21>;
++ intc-irq-mode = <1>;
++ intc-irq = <0 1>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x40000000 0x0 0x40000000 0x01000000>,
++ <0xb0000000 0x10 0x70000000 0x3000000>;
++ dsp@0 {
++ };
++ };
+ };
+ };
diff --git a/target/linux/sunxi/config-6.6 b/target/linux/sunxi/config-6.6
index 3e73f44c90..6a31400b48 100644
--- a/target/linux/sunxi/config-6.6
+++ b/target/linux/sunxi/config-6.6
@@ -168,7 +168,6 @@ CONFIG_FRAME_WARN=2048
CONFIG_FREEZER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
CONFIG_FW_LOADER_PAGED_BUF=y
@@ -482,7 +481,6 @@ CONFIG_THERMAL_OF=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TOUCHSCREEN_SUN4I=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch b/target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch
new file mode 100644
index 0000000000..538484dd82
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch
@@ -0,0 +1,32 @@
+From 9cf3415ade2d7598d78d2ce6d35d6d6d06132201 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:01 +0100
+Subject: [PATCH] firmware: smccc: Export revision soc_id function
+
+The "SoC ID revision" as provided via the SMCCC SOCID interface can be
+valuable information for drivers, when certain functionality depends
+on a die revision, for instance.
+One example is the sun50i-cpufreq-nvmem driver, which needs this
+information to determine the speed bin of the SoC.
+
+Export the arm_smccc_get_soc_id_revision() function so that it can be
+called by any driver.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/firmware/smccc/smccc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/firmware/smccc/smccc.c
++++ b/drivers/firmware/smccc/smccc.c
+@@ -69,6 +69,7 @@ s32 arm_smccc_get_soc_id_revision(void)
+ {
+ return smccc_soc_id_revision;
+ }
++EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
+
+ static int __init smccc_devices_init(void)
+ {
diff --git a/target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch b/target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch
new file mode 100644
index 0000000000..d67b35ee71
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch
@@ -0,0 +1,29 @@
+From 6ae07744cf334b750762ba881492c0cfba524b38 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:02 +0100
+Subject: [PATCH] cpufreq: dt-platdev: Blocklist Allwinner H616/618 SoCs
+
+The AllWinner H616 SoC will use the (extended) H6 OPP driver, so add
+them to the cpufreq-dt blocklist, to not create the device twice.
+This also affects the closely related sibling SoCs H618 and H700.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/cpufreq-dt-platdev.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -104,6 +104,9 @@ static const struct of_device_id allowli
+ */
+ static const struct of_device_id blocklist[] __initconst = {
+ { .compatible = "allwinner,sun50i-h6", },
++ { .compatible = "allwinner,sun50i-h616", },
++ { .compatible = "allwinner,sun50i-h618", },
++ { .compatible = "allwinner,sun50i-h700", },
+
+ { .compatible = "apple,arm-platform", },
+
diff --git a/target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch b/target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch
new file mode 100644
index 0000000000..9a81906996
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch
@@ -0,0 +1,149 @@
+From 6cc4bcceff9af0e6be9738096d95e4ba75e75123 Mon Sep 17 00:00:00 2001
+From: Brandon Cheo Fusi <fusibrandon13@gmail.com>
+Date: Thu, 18 Apr 2024 16:44:04 +0100
+Subject: [PATCH] cpufreq: sun50i: Refactor speed bin decoding
+
+Make converting the speed bin value into a speed grade generic and
+determined by a platform specific callback. Also change the prototypes
+involved to encode the speed bin directly in the return value.
+
+This allows to extend the driver more easily to support more SoCs.
+
+Signed-off-by: Brandon Cheo Fusi <fusibrandon13@gmail.com>
+[Andre: merge output into return value]
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 74 +++++++++++++++++---------
+ 1 file changed, 49 insertions(+), 25 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -25,19 +25,52 @@
+
+ static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev;
+
++struct sunxi_cpufreq_data {
++ u32 (*efuse_xlate)(u32 speedbin);
++};
++
++static u32 sun50i_h6_efuse_xlate(u32 speedbin)
++{
++ u32 efuse_value;
++
++ efuse_value = (speedbin >> NVMEM_SHIFT) & NVMEM_MASK;
++
++ /*
++ * We treat unexpected efuse values as if the SoC was from
++ * the slowest bin. Expected efuse values are 1-3, slowest
++ * to fastest.
++ */
++ if (efuse_value >= 1 && efuse_value <= 3)
++ return efuse_value - 1;
++ else
++ return 0;
++}
++
++static struct sunxi_cpufreq_data sun50i_h6_cpufreq_data = {
++ .efuse_xlate = sun50i_h6_efuse_xlate,
++};
++
++static const struct of_device_id cpu_opp_match_list[] = {
++ { .compatible = "allwinner,sun50i-h6-operating-points",
++ .data = &sun50i_h6_cpufreq_data,
++ },
++ {}
++};
++
+ /**
+ * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value
+- * @versions: Set to the value parsed from efuse
+ *
+- * Returns 0 if success.
++ * Returns non-negative speed bin index on success, a negative error
++ * value otherwise.
+ */
+-static int sun50i_cpufreq_get_efuse(u32 *versions)
++static int sun50i_cpufreq_get_efuse(void)
+ {
++ const struct sunxi_cpufreq_data *opp_data;
+ struct nvmem_cell *speedbin_nvmem;
++ const struct of_device_id *match;
+ struct device_node *np;
+ struct device *cpu_dev;
+- u32 *speedbin, efuse_value;
+- size_t len;
++ u32 *speedbin;
+ int ret;
+
+ cpu_dev = get_cpu_device(0);
+@@ -48,12 +81,12 @@ static int sun50i_cpufreq_get_efuse(u32
+ if (!np)
+ return -ENOENT;
+
+- ret = of_device_is_compatible(np,
+- "allwinner,sun50i-h6-operating-points");
+- if (!ret) {
++ match = of_match_node(cpu_opp_match_list, np);
++ if (!match) {
+ of_node_put(np);
+ return -ENOENT;
+ }
++ opp_data = match->data;
+
+ speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+ of_node_put(np);
+@@ -61,25 +94,16 @@ static int sun50i_cpufreq_get_efuse(u32
+ return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem),
+ "Could not get nvmem cell\n");
+
+- speedbin = nvmem_cell_read(speedbin_nvmem, &len);
++ speedbin = nvmem_cell_read(speedbin_nvmem, NULL);
+ nvmem_cell_put(speedbin_nvmem);
+ if (IS_ERR(speedbin))
+ return PTR_ERR(speedbin);
+
+- efuse_value = (*speedbin >> NVMEM_SHIFT) & NVMEM_MASK;
+-
+- /*
+- * We treat unexpected efuse values as if the SoC was from
+- * the slowest bin. Expected efuse values are 1-3, slowest
+- * to fastest.
+- */
+- if (efuse_value >= 1 && efuse_value <= 3)
+- *versions = efuse_value - 1;
+- else
+- *versions = 0;
++ ret = opp_data->efuse_xlate(*speedbin);
+
+ kfree(speedbin);
+- return 0;
++
++ return ret;
+ };
+
+ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
+@@ -87,7 +111,7 @@ static int sun50i_cpufreq_nvmem_probe(st
+ int *opp_tokens;
+ char name[MAX_NAME_LEN];
+ unsigned int cpu;
+- u32 speed = 0;
++ int speed;
+ int ret;
+
+ opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens),
+@@ -95,10 +119,10 @@ static int sun50i_cpufreq_nvmem_probe(st
+ if (!opp_tokens)
+ return -ENOMEM;
+
+- ret = sun50i_cpufreq_get_efuse(&speed);
+- if (ret) {
++ speed = sun50i_cpufreq_get_efuse();
++ if (speed < 0) {
+ kfree(opp_tokens);
+- return ret;
++ return speed;
+ }
+
+ snprintf(name, MAX_NAME_LEN, "speed%d", speed);
diff --git a/target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch b/target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch
new file mode 100644
index 0000000000..e0c68f9aad
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch
@@ -0,0 +1,132 @@
+From fa5aec9561cfc4f4370983ca5818c90227c9d90e Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Thu, 18 Apr 2024 16:44:05 +0100
+Subject: [PATCH] cpufreq: sun50i: Add support for opp_supported_hw
+
+The opp_supported_hw DT property allows the DT to specify a mask of chip
+revisions that a certain OPP is eligible for. This allows for easy
+limiting of maximum frequencies, for instance.
+
+Add support for that in the sun50i-cpufreq-nvmem driver. We support both
+the existing opp-microvolt suffix properties as well as the
+opp-supported-hw property, the generic code figures out which is needed
+automatically.
+However if none of the DT OPP nodes contain an opp-supported-hw
+property, the core code will ignore all OPPs and the driver will fail
+probing. So check the DT's eligibility first before using that feature.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 62 ++++++++++++++++++++++----
+ 1 file changed, 54 insertions(+), 8 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -58,6 +58,41 @@ static const struct of_device_id cpu_opp
+ };
+
+ /**
++ * dt_has_supported_hw() - Check if any OPPs use opp-supported-hw
++ *
++ * If we ask the cpufreq framework to use the opp-supported-hw feature, it
++ * will ignore every OPP node without that DT property. If none of the OPPs
++ * have it, the driver will fail probing, due to the lack of OPPs.
++ *
++ * Returns true if we have at least one OPP with the opp-supported-hw property.
++ */
++static bool dt_has_supported_hw(void)
++{
++ bool has_opp_supported_hw = false;
++ struct device_node *np, *opp;
++ struct device *cpu_dev;
++
++ cpu_dev = get_cpu_device(0);
++ if (!cpu_dev)
++ return -ENODEV;
++
++ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
++ if (!np)
++ return -ENOENT;
++
++ for_each_child_of_node(np, opp) {
++ if (of_find_property(opp, "opp-supported-hw", NULL)) {
++ has_opp_supported_hw = true;
++ break;
++ }
++ }
++
++ of_node_put(np);
++
++ return has_opp_supported_hw;
++}
++
++/**
+ * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value
+ *
+ * Returns non-negative speed bin index on success, a negative error
+@@ -110,7 +145,8 @@ static int sun50i_cpufreq_nvmem_probe(st
+ {
+ int *opp_tokens;
+ char name[MAX_NAME_LEN];
+- unsigned int cpu;
++ unsigned int cpu, supported_hw;
++ struct dev_pm_opp_config config = {};
+ int speed;
+ int ret;
+
+@@ -125,7 +161,18 @@ static int sun50i_cpufreq_nvmem_probe(st
+ return speed;
+ }
+
++ /*
++ * We need at least one OPP with the "opp-supported-hw" property,
++ * or else the upper layers will ignore every OPP and will bail out.
++ */
++ if (dt_has_supported_hw()) {
++ supported_hw = 1U << speed;
++ config.supported_hw = &supported_hw;
++ config.supported_hw_count = 1;
++ }
++
+ snprintf(name, MAX_NAME_LEN, "speed%d", speed);
++ config.prop_name = name;
+
+ for_each_possible_cpu(cpu) {
+ struct device *cpu_dev = get_cpu_device(cpu);
+@@ -135,12 +182,11 @@ static int sun50i_cpufreq_nvmem_probe(st
+ goto free_opp;
+ }
+
+- opp_tokens[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name);
+- if (opp_tokens[cpu] < 0) {
+- ret = opp_tokens[cpu];
+- pr_err("Failed to set prop name\n");
++ ret = dev_pm_opp_set_config(cpu_dev, &config);
++ if (ret < 0)
+ goto free_opp;
+- }
++
++ opp_tokens[cpu] = ret;
+ }
+
+ cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
+@@ -155,7 +201,7 @@ static int sun50i_cpufreq_nvmem_probe(st
+
+ free_opp:
+ for_each_possible_cpu(cpu)
+- dev_pm_opp_put_prop_name(opp_tokens[cpu]);
++ dev_pm_opp_clear_config(opp_tokens[cpu]);
+ kfree(opp_tokens);
+
+ return ret;
+@@ -169,7 +215,7 @@ static void sun50i_cpufreq_nvmem_remove(
+ platform_device_unregister(cpufreq_dt_pdev);
+
+ for_each_possible_cpu(cpu)
+- dev_pm_opp_put_prop_name(opp_tokens[cpu]);
++ dev_pm_opp_clear_config(opp_tokens[cpu]);
+
+ kfree(opp_tokens);
+ }
diff --git a/target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch b/target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch
new file mode 100644
index 0000000000..c891f5722a
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch
@@ -0,0 +1,122 @@
+From e2e2dcd2e944fe6167cb731864f8a1343f1bbee7 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:06 +0100
+Subject: [PATCH] cpufreq: sun50i: Add H616 support
+
+The Allwinner H616/H618 SoCs have different OPP tables per SoC version
+and die revision. The SoC version is stored in NVMEM, as before, though
+encoded differently. The die revision is in a different register, in the
+SRAM controller. Firmware already exports that value in a standardised
+way, through the SMCCC SoCID mechanism. We need both values, as some chips
+have the same SoC version, but they don't support the same frequencies and
+they get differentiated by the die revision.
+
+Add the new compatible string and tie the new translation function to
+it. This mechanism not only covers the original H616 SoC, but also its
+very close sibling SoCs H618 and H700, so add them to the list as well.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 67 ++++++++++++++++++++++++++
+ 1 file changed, 67 insertions(+)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -10,6 +10,7 @@
+
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
++#include <linux/arm-smccc.h>
+ #include <linux/cpu.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-consumer.h>
+@@ -46,14 +47,77 @@ static u32 sun50i_h6_efuse_xlate(u32 spe
+ return 0;
+ }
+
++static int get_soc_id_revision(void)
++{
++#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY
++ return arm_smccc_get_soc_id_revision();
++#else
++ return SMCCC_RET_NOT_SUPPORTED;
++#endif
++}
++
++/*
++ * Judging by the OPP tables in the vendor BSP, the quality order of the
++ * returned speedbin index is 4 -> 0/2 -> 3 -> 1, from worst to best.
++ * 0 and 2 seem identical from the OPP tables' point of view.
++ */
++static u32 sun50i_h616_efuse_xlate(u32 speedbin)
++{
++ int ver_bits = get_soc_id_revision();
++ u32 value = 0;
++
++ switch (speedbin & 0xffff) {
++ case 0x2000:
++ value = 0;
++ break;
++ case 0x2400:
++ case 0x7400:
++ case 0x2c00:
++ case 0x7c00:
++ if (ver_bits != SMCCC_RET_NOT_SUPPORTED && ver_bits <= 1) {
++ /* ic version A/B */
++ value = 1;
++ } else {
++ /* ic version C and later version */
++ value = 2;
++ }
++ break;
++ case 0x5000:
++ case 0x5400:
++ case 0x6000:
++ value = 3;
++ break;
++ case 0x5c00:
++ value = 4;
++ break;
++ case 0x5d00:
++ value = 0;
++ break;
++ default:
++ pr_warn("sun50i-cpufreq-nvmem: unknown speed bin 0x%x, using default bin 0\n",
++ speedbin & 0xffff);
++ value = 0;
++ break;
++ }
++
++ return value;
++}
++
+ static struct sunxi_cpufreq_data sun50i_h6_cpufreq_data = {
+ .efuse_xlate = sun50i_h6_efuse_xlate,
+ };
+
++static struct sunxi_cpufreq_data sun50i_h616_cpufreq_data = {
++ .efuse_xlate = sun50i_h616_efuse_xlate,
++};
++
+ static const struct of_device_id cpu_opp_match_list[] = {
+ { .compatible = "allwinner,sun50i-h6-operating-points",
+ .data = &sun50i_h6_cpufreq_data,
+ },
++ { .compatible = "allwinner,sun50i-h616-operating-points",
++ .data = &sun50i_h616_cpufreq_data,
++ },
+ {}
+ };
+
+@@ -230,6 +294,9 @@ static struct platform_driver sun50i_cpu
+
+ static const struct of_device_id sun50i_cpufreq_match_list[] = {
+ { .compatible = "allwinner,sun50i-h6" },
++ { .compatible = "allwinner,sun50i-h616" },
++ { .compatible = "allwinner,sun50i-h618" },
++ { .compatible = "allwinner,sun50i-h700" },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list);
diff --git a/target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch b/target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch
new file mode 100644
index 0000000000..4665286d0f
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch
@@ -0,0 +1,188 @@
+From 3e057e05b3b281bcc29db573eb51f87ee6b5afc0 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:07 +0100
+Subject: [PATCH] arm64: dts: allwinner: h616: Add CPU OPPs table
+
+Add an Operating Performance Points table for the CPU cores to enable
+Dynamic Voltage & Frequency Scaling (DVFS) on the H616.
+The values were taken from the BSP sources. There is a separate OPP set
+seen on some H700 devices, but they didn't really work out in testing, so
+they are not included for now.
+
+Also add the needed cpu_speed_grade nvmem cell and the cooling cells
+properties, to enable passive cooling.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+[Andre: rework to minimise opp-microvolt properties]
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ .../dts/allwinner/sun50i-h616-cpu-opp.dtsi | 115 ++++++++++++++++++
+ .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 8 ++
+ 2 files changed, 123 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
+@@ -0,0 +1,115 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++// Copyright (C) 2023 Martin Botka <martin@somainline.org>
++
++/ {
++ cpu_opp_table: opp-table-cpu {
++ compatible = "allwinner,sun50i-h616-operating-points";
++ nvmem-cells = <&cpu_speed_grade>;
++ opp-shared;
++
++ opp-480000000 {
++ opp-hz = /bits/ 64 <480000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1f>;
++ };
++
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x12>;
++ };
++
++ opp-720000000 {
++ opp-hz = /bits/ 64 <720000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-792000000 {
++ opp-hz = /bits/ 64 <792000000>;
++ opp-microvolt-speed1 = <900000>;
++ opp-microvolt-speed4 = <940000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x12>;
++ };
++
++ opp-936000000 {
++ opp-hz = /bits/ 64 <936000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-1008000000 {
++ opp-hz = /bits/ 64 <1008000000>;
++ opp-microvolt-speed0 = <950000>;
++ opp-microvolt-speed1 = <940000>;
++ opp-microvolt-speed2 = <950000>;
++ opp-microvolt-speed3 = <950000>;
++ opp-microvolt-speed4 = <1020000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1f>;
++ };
++
++ opp-1104000000 {
++ opp-hz = /bits/ 64 <1104000000>;
++ opp-microvolt-speed0 = <1000000>;
++ opp-microvolt-speed2 = <1000000>;
++ opp-microvolt-speed3 = <1000000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt-speed0 = <1050000>;
++ opp-microvolt-speed1 = <1020000>;
++ opp-microvolt-speed2 = <1050000>;
++ opp-microvolt-speed3 = <1050000>;
++ opp-microvolt-speed4 = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1f>;
++ };
++
++ opp-1320000000 {
++ opp-hz = /bits/ 64 <1320000000>;
++ opp-microvolt = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1d>;
++ };
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-1512000000 {
++ opp-hz = /bits/ 64 <1512000000>;
++ opp-microvolt-speed1 = <1100000>;
++ opp-microvolt-speed3 = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0a>;
++ };
++ };
++};
++
++&cpu0 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
++
++&cpu1 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
++
++&cpu2 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
++
++&cpu3 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+@@ -26,6 +26,7 @@
+ reg = <0>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+
+ cpu1: cpu@1 {
+@@ -34,6 +35,7 @@
+ reg = <1>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+
+ cpu2: cpu@2 {
+@@ -42,6 +44,7 @@
+ reg = <2>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+
+ cpu3: cpu@3 {
+@@ -50,6 +53,7 @@
+ reg = <3>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+ };
+
+@@ -143,6 +147,10 @@
+ ths_calibration: thermal-sensor-calibration@14 {
+ reg = <0x14 0x8>;
+ };
++
++ cpu_speed_grade: cpu-speed-grade@0 {
++ reg = <0x0 2>;
++ };
+ };
+
+ watchdog: watchdog@30090a0 {
diff --git a/target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch b/target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch
new file mode 100644
index 0000000000..8c91184117
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch
@@ -0,0 +1,86 @@
+From 09d0aaa0ae9c80ff9569393b206226c1008801b1 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Thu, 18 Apr 2024 16:44:08 +0100
+Subject: [PATCH] arm64: dts: allwinner: h616: enable DVFS for all boards
+
+With the DT bindings now describing the format of the CPU OPP tables, we
+can include the OPP table in each board's .dts file, and specify the CPU
+power supply.
+This allows to enable DVFS, and get up to 50% of performance benefit in
+the highest OPP, or up to 60% power savings in the lowest OPP, compared
+to the fixed 1GHz @ 1.0V OPP we are running in by default at the moment.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ .../boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi | 5 +++++
+ arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts | 5 +++++
+ arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts | 5 +++++
+ .../boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi | 5 +++++
+ .../arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts | 5 +++++
+ arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts | 5 +++++
+ .../boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts | 5 +++++
+ 7 files changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
+@@ -6,12 +6,17 @@
+ /dts-v1/;
+
+ #include "sun50i-h616-orangepi-zero.dtsi"
++#include "sun50i-h616-cpu-opp.dtsi"
+
+ / {
+ model = "OrangePi Zero2";
+ compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
+ };
+
++&cpu0 {
++ cpu-supply = <&reg_dcdca>;
++};
++
+ &emac0 {
+ allwinner,rx-delay-ps = <3100>;
+ allwinner,tx-delay-ps = <700>;
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
+@@ -6,6 +6,7 @@
+ /dts-v1/;
+
+ #include "sun50i-h616.dtsi"
++#include "sun50i-h616-cpu-opp.dtsi"
+
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+@@ -32,6 +33,10 @@
+ };
+ };
+
++&cpu0 {
++ cpu-supply = <&reg_dcdca>;
++};
++
+ &ehci0 {
+ status = "okay";
+ };
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
+@@ -6,12 +6,17 @@
+ /dts-v1/;
+
+ #include "sun50i-h616-orangepi-zero.dtsi"
++#include "sun50i-h616-cpu-opp.dtsi"
+
+ / {
+ model = "OrangePi Zero3";
+ compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618";
+ };
+
++&cpu0 {
++ cpu-supply = <&reg_dcdc2>;
++};
++
+ &emac0 {
+ allwinner,tx-delay-ps = <700>;
+ phy-mode = "rgmii-rxid";
diff --git a/target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch b/target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch
new file mode 100644
index 0000000000..8bfd6c2d09
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch
@@ -0,0 +1,51 @@
+From d2059d3b548409905b20b4f52495bffbd7c8da8b Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Mon, 22 Apr 2024 08:58:51 +0530
+Subject: [PATCH] cpufreq: sun50i: Fix build warning around snprint()
+
+The Sun50i driver generates a warning with W=1:
+
+warning: '%d' directive output may be truncated writing between 1 and 10 bytes into a region of size 2 [-Wformat-truncation=]
+
+Fix it by allocating a big enough array to print an integer.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202404191715.LDwMm2gP-lkp@intel.com/
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Chen-Yu Tsai <wens@csie.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Tested-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -19,8 +19,6 @@
+ #include <linux/pm_opp.h>
+ #include <linux/slab.h>
+
+-#define MAX_NAME_LEN 7
+-
+ #define NVMEM_MASK 0x7
+ #define NVMEM_SHIFT 5
+
+@@ -208,7 +206,7 @@ static int sun50i_cpufreq_get_efuse(void
+ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
+ {
+ int *opp_tokens;
+- char name[MAX_NAME_LEN];
++ char name[] = "speedXXXXXXXXXXX"; /* Integers can take 11 chars max */
+ unsigned int cpu, supported_hw;
+ struct dev_pm_opp_config config = {};
+ int speed;
+@@ -235,7 +233,7 @@ static int sun50i_cpufreq_nvmem_probe(st
+ config.supported_hw_count = 1;
+ }
+
+- snprintf(name, MAX_NAME_LEN, "speed%d", speed);
++ snprintf(name, sizeof(name), "speed%d", speed);
+ config.prop_name = name;
+
+ for_each_possible_cpu(cpu) {
diff --git a/target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch b/target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch
new file mode 100644
index 0000000000..2304a6af79
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch
@@ -0,0 +1,34 @@
+From 76a6fc5644b2a1c70868bec24a078f784600ef2a Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Wed, 24 Apr 2024 14:40:11 +0300
+Subject: [PATCH] cpufreq: sun50i: fix error returns in dt_has_supported_hw()
+
+The dt_has_supported_hw() function returns type bool. That means these
+negative error codes are cast to true but the function should return
+false instead.
+
+Fixes: fa5aec9561cf ("cpufreq: sun50i: Add support for opp_supported_hw")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -136,11 +136,11 @@ static bool dt_has_supported_hw(void)
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev)
+- return -ENODEV;
++ return false;
+
+ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+ if (!np)
+- return -ENOENT;
++ return false;
+
+ for_each_child_of_node(np, opp) {
+ if (of_find_property(opp, "opp-supported-hw", NULL)) {
diff --git a/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch b/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch
index 350d7f0403..f605292dcd 100644
--- a/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch
+++ b/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch
@@ -1,6 +1,6 @@
--- a/arch/arm/boot/dts/allwinner/Makefile
+++ b/arch/arm/boot/dts/allwinner/Makefile
-@@ -280,6 +280,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
+@@ -219,6 +219,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-a83t-cubietruck-plus.dtb \
sun8i-a83t-tbs-a711.dtb \
sun8i-h2-plus-bananapi-m2-zero.dtb \
diff --git a/target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch b/target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch
new file mode 100644
index 0000000000..c17d28c691
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch
@@ -0,0 +1,107 @@
+From 4c3a3af679bd59660ac80889b560bddaf475ba81 Mon Sep 17 00:00:00 2001
+From: Michel Promonet <michel.promonet@free.fr>
+Date: Sun, 21 Jul 2024 19:04:19 +0200
+Subject: [PATCH] sunxi: add csi video support for nanopi-neo-air
+
+---
+ .../dts/allwinner/sun8i-h3-nanopi-neo-air.dts | 85 +++++++++++++++++++
+ 1 file changed, 85 insertions(+)
+
+--- a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
++++ b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
+@@ -77,6 +77,39 @@
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+ };
++
++ cam_xclk: cam-xclk {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <24000000>;
++ clock-output-names = "cam-xclk";
++ };
++
++ reg_cam_avdd: cam-avdd {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-avdd";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ vin-supply = <&reg_vcc3v3>;
++ };
++
++ reg_cam_dovdd: cam-dovdd {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dovdd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&reg_vcc3v3>;
++ };
++
++ reg_cam_dvdd: cam-dvdd {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dvdd";
++ regulator-min-microvolt = <1500000>;
++ regulator-max-microvolt = <1500000>;
++ vin-supply = <&reg_vcc3v3>;
++ };
++
++
+ };
+
+ &mmc0 {
+@@ -141,3 +174,55 @@
+ /* USB VBUS is always on */
+ status = "okay";
+ };
++
++&csi {
++ status = "okay";
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* Parallel bus endpoint */
++ csi_from_ov5640: endpoint {
++ remote-endpoint = <&ov5640_to_csi>;
++ bus-width = <8>;
++ data-shift = <2>;
++ hsync-active = <1>; /* Active high */
++ vsync-active = <0>; /* Active low */
++ data-active = <1>; /* Active high */
++ pclk-sample = <1>; /* Rising */
++ };
++ };
++};
++
++&i2c2 {
++ status = "okay";
++
++ ov5640: camera@3c {
++ compatible = "ovti,ov5640";
++ reg = <0x3c>;
++ clocks = <&cam_xclk>;
++ clock-names = "xclk";
++
++ reset-gpios = <&pio 4 14 GPIO_ACTIVE_LOW>;
++ powerdown-gpios = <&pio 4 15 GPIO_ACTIVE_HIGH>;
++ AVDD-supply = <&reg_cam_avdd>;
++ DOVDD-supply = <&reg_cam_dovdd>;
++ DVDD-supply = <&reg_cam_dvdd>;
++
++ port {
++ ov5640_to_csi: endpoint {
++ remote-endpoint = <&csi_from_ov5640>;
++ bus-width = <8>;
++ data-shift = <2>;
++ hsync-active = <1>; /* Active high */
++ vsync-active = <0>; /* Active low */
++ data-active = <1>; /* Active high */
++ pclk-sample = <1>; /* Rising */
++ };
++ };
++ };
++};
++&i2c2_pins {
++ bias-pull-up;
++};
diff --git a/target/linux/tegra/Makefile b/target/linux/tegra/Makefile
index 3513e2751e..b917ea909d 100644
--- a/target/linux/tegra/Makefile
+++ b/target/linux/tegra/Makefile
@@ -12,8 +12,7 @@ CPU_TYPE := cortex-a9
CPU_SUBTYPE := vfpv3-d16
SUBTARGETS := generic
-KERNEL_PATCHVER := 5.15
-KERNEL_TESTING_PATCHVER := 6.6
+KERNEL_PATCHVER := 6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/tegra/config-5.15 b/target/linux/tegra/config-5.15
deleted file mode 100644
index c143c3f5a9..0000000000
--- a/target/linux/tegra/config-5.15
+++ /dev/null
@@ -1,506 +0,0 @@
-CONFIG_AC97_BUS=y
-# CONFIG_AHCI_TEGRA is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
-CONFIG_ARCH_NR_GPIO=1024
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_TEGRA=y
-# CONFIG_ARCH_TEGRA_114_SOC is not set
-# CONFIG_ARCH_TEGRA_124_SOC is not set
-CONFIG_ARCH_TEGRA_2x_SOC=y
-# CONFIG_ARCH_TEGRA_3x_SOC is not set
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_CRYPTO=y
-CONFIG_ARM_ERRATA_720789=y
-CONFIG_ARM_ERRATA_754327=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_HAS_SG_CHAIN=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_PL172_MPMC is not set
-# CONFIG_ARM_SMMU is not set
-# CONFIG_ARM_TEGRA124_CPUFREQ is not set
-CONFIG_ARM_TEGRA20_CPUFREQ=y
-CONFIG_ARM_TEGRA_CPUIDLE=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ASN1=y
-CONFIG_ATA=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_BSG=y
-CONFIG_BLK_DEV_BSG_COMMON=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-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 is not set
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_AES_ARM=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_ECHAINIV=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LZ4=y
-CONFIG_CRYPTO_LZ4HC=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SEQIV=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA1_ARM=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA256_ARM=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_SHA512_ARM=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_TWOFISH_COMMON=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_ALIGN_RODATA=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-# CONFIG_DEVFREQ_GOV_PASSIVE is not set
-# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
-# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
-CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
-# CONFIG_DEVFREQ_GOV_USERSPACE is not set
-CONFIG_DEVFREQ_THERMAL=y
-# CONFIG_DEVPORT is not set
-CONFIG_DMADEVICES=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_REMAP=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DNOTIFY=y
-CONFIG_DRM=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_DP_AUX_BUS=y
-CONFIG_DRM_FBDEV_EMULATION=y
-CONFIG_DRM_FBDEV_OVERALLOC=100
-CONFIG_DRM_KMS_HELPER=y
-CONFIG_DRM_MIPI_DSI=y
-CONFIG_DRM_PANEL=y
-CONFIG_DRM_PANEL_BRIDGE=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DRM_TEGRA=y
-# CONFIG_DRM_TEGRA_DEBUG is not set
-# CONFIG_DRM_TEGRA_STAGING is not set
-CONFIG_DTC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXT4_FS=y
-CONFIG_EXTCON=y
-CONFIG_F2FS_FS=y
-CONFIG_FB=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_CMDLINE=y
-CONFIG_FB_DEFERRED_IO=y
-CONFIG_FB_SYS_COPYAREA=y
-CONFIG_FB_SYS_FILLRECT=y
-CONFIG_FB_SYS_FOPS=y
-CONFIG_FB_SYS_IMAGEBLIT=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FUNCTION_ALIGNMENT=0
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=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_GENERIC_VDSO_32=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_TEGRA=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HDMI=y
-CONFIG_HID=y
-CONFIG_HIDRAW=y
-CONFIG_HID_GENERIC=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HWMON=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_TEGRA=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INTERCONNECT=y
-CONFIG_IOMMU_API=y
-# CONFIG_IOMMU_DEBUGFS is not set
-CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
-CONFIG_IOMMU_IOVA=y
-# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_KCMP=y
-CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZ4HC_COMPRESS=y
-CONFIG_LZ4_COMPRESS=y
-CONFIG_LZ4_DECOMPRESS=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_ISOLATION=y
-# CONFIG_MFD_ACER_A500_EC is not set
-# CONFIG_MFD_NVEC is not set
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CQHCI=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_IO_ACCESSORS=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_SDHCI_TEGRA=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MPILIB=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-# CONFIG_NEON is not set
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IOMMU=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_PME=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCI_TEGRA=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHY_TEGRA_XUSB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_TEGRA=y
-CONFIG_PINCTRL_TEGRA20=y
-CONFIG_PINCTRL_TEGRA_XUSB=y
-CONFIG_PL310_ERRATA_727915=y
-CONFIG_PL310_ERRATA_769419=y
-CONFIG_PL353_SMC=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_DEVFREQ=y
-# CONFIG_PM_DEVFREQ_EVENT is not set
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_PM_OPP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_SYSFS=y
-CONFIG_PWM_TEGRA=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_CMOS is not set
-CONFIG_RTC_DRV_TEGRA=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_NVMEM=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_TEGRA=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_TEGRA=y
-CONFIG_SERIO=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SND=y
-# CONFIG_SND_COMPRESS_OFFLOAD is not set
-CONFIG_SND_DMAENGINE_PCM=y
-# CONFIG_SND_HDA_TEGRA is not set
-CONFIG_SND_JACK=y
-CONFIG_SND_JACK_INPUT_DEV=y
-# CONFIG_SND_PCI is not set
-CONFIG_SND_PCM=y
-# CONFIG_SND_PROC_FS is not set
-CONFIG_SND_SIMPLE_CARD=y
-CONFIG_SND_SIMPLE_CARD_UTILS=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_AC97_BUS=y
-CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-CONFIG_SND_SOC_TEGRA=y
-# CONFIG_SND_SOC_TEGRA186_DSPK is not set
-CONFIG_SND_SOC_TEGRA20_AC97=y
-CONFIG_SND_SOC_TEGRA20_DAS=y
-CONFIG_SND_SOC_TEGRA20_I2S=y
-CONFIG_SND_SOC_TEGRA20_SPDIF=y
-# CONFIG_SND_SOC_TEGRA210_ADMAIF is not set
-# CONFIG_SND_SOC_TEGRA210_AHUB is not set
-# CONFIG_SND_SOC_TEGRA210_DMIC is not set
-# CONFIG_SND_SOC_TEGRA210_I2S is not set
-# CONFIG_SND_SOC_TEGRA30_AHUB is not set
-# CONFIG_SND_SOC_TEGRA30_I2S is not set
-# CONFIG_SND_SOC_TEGRA_ALC5632 is not set
-CONFIG_SND_SOC_TEGRA_MACHINE_DRV=y
-# CONFIG_SND_SOC_TEGRA_MAX98090 is not set
-# CONFIG_SND_SOC_TEGRA_RT5640 is not set
-# CONFIG_SND_SOC_TEGRA_RT5677 is not set
-# CONFIG_SND_SOC_TEGRA_SGTL5000 is not set
-CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
-# CONFIG_SND_SOC_TEGRA_WM8753 is not set
-# CONFIG_SND_SOC_TEGRA_WM8903 is not set
-# CONFIG_SND_SOC_TEGRA_WM9712 is not set
-CONFIG_SND_SOC_TLV320AIC23=y
-CONFIG_SND_SOC_TLV320AIC23_I2C=y
-# CONFIG_SND_USB is not set
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y
-CONFIG_SOC_TEGRA_FLOWCTRL=y
-CONFIG_SOC_TEGRA_FUSE=y
-CONFIG_SOC_TEGRA_PMC=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SOUND_OSS_CORE_PRECLAIM=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_TEGRA114 is not set
-CONFIG_SPI_TEGRA20_SFLASH=y
-CONFIG_SPI_TEGRA20_SLINK=y
-# CONFIG_SPI_TEGRA210_QUAD is not set
-CONFIG_SRCU=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_TEGRA20_APB_DMA=y
-CONFIG_TEGRA20_EMC=y
-CONFIG_TEGRA_AHB=y
-CONFIG_TEGRA_GMI=y
-CONFIG_TEGRA_HOST1X=y
-CONFIG_TEGRA_HOST1X_FIREWALL=y
-CONFIG_TEGRA_IOMMU_GART=y
-# CONFIG_TEGRA_IOMMU_SMMU is not set
-# CONFIG_TEGRA_IVC is not set
-CONFIG_TEGRA_MC=y
-# CONFIG_TEGRA_SOCTHERM is not set
-CONFIG_TEGRA_TIMER=y
-CONFIG_TEGRA_WATCHDOG=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-# CONFIG_UACCE is not set
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_CHIPIDEA=y
-CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_TEGRA=y
-CONFIG_USB_CHIPIDEA_UDC=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_CONN_GPIO=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_EHCI_TEGRA=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_HID=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_TEGRA_PHY=y
-# CONFIG_USB_TEGRA_XUDC is not set
-CONFIG_USB_ULPI=y
-CONFIG_USB_ULPI_BUS=y
-CONFIG_USB_ULPI_VIEWPORT=y
-# CONFIG_USB_XHCI_TEGRA is not set
-CONFIG_USE_OF=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XPS=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/tegra/image/Makefile b/target/linux/tegra/image/Makefile
index 7103b6d36e..96b095e649 100644
--- a/target/linux/tegra/image/Makefile
+++ b/target/linux/tegra/image/Makefile
@@ -32,11 +32,7 @@ DEVICE_VARS += BOOT_SCRIPT UBOOT
define Device/Default
BOOT_SCRIPT := generic-bootscript
-ifeq ($(KERNEL),6.6)
DEVICE_DTS_DIR := $$(DTS_DIR)/nvidia
-else
- DEVICE_DTS_DIR := $$(DTS_DIR)
-endif
IMAGES := sdcard.img.gz
IMAGE/sdcard.img.gz := append-rootfs | pad-extra 128k | tegra-sdcard | gzip | append-metadata
KERNEL_NAME := zImage
diff --git a/target/linux/tegra/patches-5.15/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch b/target/linux/tegra/patches-5.15/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch
deleted file mode 100644
index 8f01f73eb2..0000000000
--- a/target/linux/tegra/patches-5.15/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From patchwork Fri Jul 13 11:32:42 2018
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: serial8250 on tegra hsuart: recover from spurious interrupts due to
- tegra2 silicon bug
-X-Patchwork-Submitter: "David R. Piegdon" <lkml@p23q.org>
-X-Patchwork-Id: 943440
-Message-Id: <4676ea34-69ce-5422-1ded-94218b89f7d9@p23q.org>
-To: linux-tegra@vger.kernel.org
-Date: Fri, 13 Jul 2018 11:32:42 +0000
-From: "David R. Piegdon" <lkml@p23q.org>
-List-Id: <linux-tegra.vger.kernel.org>
-
-Hi,
-a while back I sent a few mails regarding spurious interrupts in the
-UARTA (hsuart) block of the Tegra2 SoC, when using the 8250 driver for
-it instead of the hsuart driver. After going down a pretty deep
-debugging/testing hole, I think I found a patch that fixes the issue. So
-far testing in a reboot-cycle suggests that the error frequency dropped
-from >3% of all reboots to at least <0.05% of all reboots. Tests
-continue to run over the weekend.
-
-The patch below already is a second iteration; the first did not reset
-the MCR or contain the lines below '// clear interrupts'. This resulted
-in no more spurious interrupts, but in a few % of spurious interrupts
-that were recovered the UART block did not receive any characters any
-more. So further resetting was required to fully reacquire operational
-state of the UART block.
-
-I'd love any comments/suggestions on this!
-
-Cheers,
-
-David
-
---- a/drivers/tty/serial/8250/8250_core.c
-+++ b/drivers/tty/serial/8250/8250_core.c
-@@ -134,6 +134,38 @@ static irqreturn_t serial8250_interrupt(
-
- if (l == i->head && pass_counter++ > PASS_LIMIT)
- break;
-+
-+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-+ if (!handled && (port->type == PORT_TEGRA)) {
-+ /*
-+ * Fix Tegra 2 CPU silicon bug where sometimes
-+ * "TX holding register empty" interrupts result in a
-+ * bad (metastable?) state in Tegras HSUART IP core.
-+ * Only way to recover seems to be to reset all
-+ * interrupts as well as the TX queue and the MCR.
-+ * But we don't want to loose any outgoing characters,
-+ * so only do it if the RX and TX queues are empty.
-+ */
-+ unsigned char lsr = port->serial_in(port, UART_LSR);
-+ const unsigned char fifo_empty_mask =
-+ (UART_LSR_TEMT | UART_LSR_THRE);
-+ if (((lsr & (UART_LSR_DR | fifo_empty_mask)) ==
-+ fifo_empty_mask)) {
-+ port->serial_out(port, UART_IER, 0);
-+ port->serial_out(port, UART_MCR, 0);
-+ serial8250_clear_and_reinit_fifos(up);
-+ port->serial_out(port, UART_MCR, up->mcr);
-+ port->serial_out(port, UART_IER, up->ier);
-+ // clear interrupts
-+ serial_port_in(port, UART_LSR);
-+ serial_port_in(port, UART_RX);
-+ serial_port_in(port, UART_IIR);
-+ serial_port_in(port, UART_MSR);
-+ up->lsr_saved_flags = 0;
-+ up->msr_saved_flags = 0;
-+ }
-+ }
-+#endif
- } while (l != end);
-
- spin_unlock(&i->lock);
diff --git a/target/linux/tegra/patches-5.15/101-ARM-dtc-tegra-enable-front-panel-leds-in-TrimSlice.patch b/target/linux/tegra/patches-5.15/101-ARM-dtc-tegra-enable-front-panel-leds-in-TrimSlice.patch
deleted file mode 100644
index b1e210b212..0000000000
--- a/target/linux/tegra/patches-5.15/101-ARM-dtc-tegra-enable-front-panel-leds-in-TrimSlice.patch
+++ /dev/null
@@ -1,46 +0,0 @@
---- a/arch/arm/boot/dts/tegra20-trimslice.dts
-+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
-@@ -201,16 +201,17 @@
- conf_ata {
- nvidia,pins = "ata", "atc", "atd", "ate",
- "crtp", "dap2", "dap3", "dap4", "dta",
-- "dtb", "dtc", "dtd", "dte", "gmb",
-- "gme", "i2cp", "pta", "slxc", "slxd",
-- "spdi", "spdo", "uda";
-+ "dtb", "dtc", "dtd", "gmb", "gme",
-+ "i2cp", "pta", "slxc", "slxd", "spdi",
-+ "spdo", "uda";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- };
- conf_atb {
- nvidia,pins = "atb", "cdev1", "cdev2", "dap1",
-- "gma", "gmc", "gmd", "gpu", "gpu7",
-- "gpv", "sdio1", "slxa", "slxk", "uac";
-+ "dte", "gma", "gmc", "gmd", "gpu",
-+ "gpu7", "gpv", "sdio1", "slxa", "slxk",
-+ "uac";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- };
-@@ -396,6 +397,20 @@
- };
- };
-
-+ gpio-leds {
-+ compatible = "gpio-leds";
-+
-+ ds2 {
-+ label = "trimslice:green:right";
-+ gpios = <&gpio TEGRA_GPIO(D, 2) GPIO_ACTIVE_LOW>;
-+ };
-+
-+ ds3 {
-+ label = "trimslice:green:left";
-+ gpios = <&gpio TEGRA_GPIO(BB, 5) GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
- poweroff {
- compatible = "gpio-poweroff";
- gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>;
diff --git a/target/linux/x86/64/config-6.6 b/target/linux/x86/64/config-6.6
index d5f86141b0..b443231120 100644
--- a/target/linux/x86/64/config-6.6
+++ b/target/linux/x86/64/config-6.6
@@ -255,7 +255,10 @@ CONFIG_HALTPOLL_CPUIDLE=y
CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y
CONFIG_HDMI=y
CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
CONFIG_HID_HYPERV_MOUSE=y
+CONFIG_HID_SUPPORT=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CORE_SYNC_FULL=y
@@ -540,6 +543,8 @@ CONFIG_TREE_SRCU=y
CONFIG_UCS2_STRING=y
CONFIG_UNACCEPTED_MEMORY=y
# CONFIG_UNWINDER_ORC is not set
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
CONFIG_USB_STORAGE=y
CONFIG_VIDEO_CMDLINE=y
# CONFIG_VIDEO_IPU3_CIO2 is not set
diff --git a/target/linux/x86/base-files/etc/board.d/02_network b/target/linux/x86/base-files/etc/board.d/02_network
index 5174906264..c4c2d3fa21 100644
--- a/target/linux/x86/base-files/etc/board.d/02_network
+++ b/target/linux/x86/base-files/etc/board.d/02_network
@@ -31,6 +31,9 @@ cisco-mx100-hw)
ucidef_set_network_device_path "eth11" "pci0000:00/0000:00:01.1/0000:02:00.2"
ucidef_set_interfaces_lan_wan "mgmt eth2 eth3 eth4 eth5 eth6 eth7 eth8 eth9 eth10 eth11" "wan"
;;
+dell-emc-edge620)
+ ucidef_set_interfaces_lan_wan "eth0 eth1 eth2 eth3 eth7" "eth6"
+ ;;
pc-engines-apu1|pc-engines-apu2|pc-engines-apu3)
ucidef_set_interfaces_lan_wan "eth1 eth2" "eth0"
;;
diff --git a/target/linux/x86/config-6.6 b/target/linux/x86/config-6.6
index d71e95f676..b8d38e60fa 100644
--- a/target/linux/x86/config-6.6
+++ b/target/linux/x86/config-6.6
@@ -9,6 +9,7 @@
CONFIG_AMD_NB=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_CLOCKSOURCE_INIT=y
+CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
diff --git a/target/linux/x86/generic/config-6.6 b/target/linux/x86/generic/config-6.6
index 4c0a052c7b..6729f0e9cd 100644
--- a/target/linux/x86/generic/config-6.6
+++ b/target/linux/x86/generic/config-6.6
@@ -182,7 +182,10 @@ CONFIG_GUP_GET_PXX_LOW_HIGH=y
CONFIG_HALTPOLL_CPUIDLE=y
CONFIG_HDMI=y
CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
CONFIG_HID_HYPERV_MOUSE=y
+CONFIG_HID_SUPPORT=y
# CONFIG_HIGHMEM4G is not set
CONFIG_HIGHMEM64G=y
CONFIG_HOTPLUG_CORE_SYNC=y
@@ -449,6 +452,8 @@ CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
# CONFIG_UCLAMP_TASK is not set
CONFIG_UCS2_STRING=y
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
CONFIG_USB_STORAGE=y
CONFIG_USER_RETURN_NOTIFIER=y
CONFIG_VHOST=y
diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile
index 6e59f2e465..29bebeb748 100644
--- a/target/linux/x86/image/Makefile
+++ b/target/linux/x86/image/Makefile
@@ -12,7 +12,7 @@ GRUB_TERMINAL_CONFIG =
GRUB_CONSOLE_CMDLINE =
ifneq ($(CONFIG_GRUB_CONSOLE),)
- GRUB_CONSOLE_CMDLINE += console=tty0
+ GRUB_CONSOLE_CMDLINE += console=tty1
GRUB_TERMINALS += console
endif
diff --git a/target/linux/x86/legacy/config-6.6 b/target/linux/x86/legacy/config-6.6
index 323f20dba6..d5c4a55e5e 100644
--- a/target/linux/x86/legacy/config-6.6
+++ b/target/linux/x86/legacy/config-6.6
@@ -133,6 +133,9 @@ CONFIG_FUNCTION_PADDING_CFI=0
# CONFIG_GIGABYTE_WMI is not set
CONFIG_GPIO_ACPI=y
CONFIG_HDMI=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
+CONFIG_HID_SUPPORT=y
# CONFIG_HIGHMEM4G is not set
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
@@ -253,6 +256,8 @@ CONFIG_SYNC_FILE=y
# CONFIG_THINKPAD_LMI is not set
# CONFIG_TOSHIBA_BT_RFKILL is not set
# CONFIG_TOSHIBA_WMI is not set
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
CONFIG_USB_STORAGE=y
CONFIG_VIDEO_CMDLINE=y
# CONFIG_VIDEO_IPU3_CIO2 is not set
diff --git a/target/linux/zynq/Makefile b/target/linux/zynq/Makefile
index 90e49df878..c570fae73b 100644
--- a/target/linux/zynq/Makefile
+++ b/target/linux/zynq/Makefile
@@ -18,7 +18,7 @@ define Target/Description
Build firmware image for Zynq 7000 SoC devices.
endef
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/zynq/config-6.1 b/target/linux/zynq/config-6.1
deleted file mode 100644
index b6318a776c..0000000000
--- a/target/linux/zynq/config-6.1
+++ /dev/null
@@ -1,566 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_ALTERA_FREEZE_BRIDGE is not set
-# CONFIG_ALTERA_PR_IP_CORE is not set
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=1024
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_VEXPRESS=y
-CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
-# CONFIG_ARCH_VEXPRESS_SPC is not set
-CONFIG_ARCH_ZYNQ=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_ERRATA_643719=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_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_PL172_MPMC is not set
-# CONFIG_ARM_SMMU is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_TIMER_SP804=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ARM_ZYNQ_CPUIDLE=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-# CONFIG_AXI_DMAC is not set
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CADENCE_TTC_TIMER=y
-CONFIG_CADENCE_WATCHDOG=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLKSRC_VERSATILE=y
-CONFIG_CLK_ICST=y
-CONFIG_CLK_SP810=y
-CONFIG_CLK_VEXPRESS_OSC=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_SI570=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONNECTOR=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_COREDUMP=y
-# CONFIG_CPUFREQ_DT is not set
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-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_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DMADEVICES=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DRM=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_NOMODESET=y
-CONFIG_DRM_PANEL=y
-CONFIG_DRM_PANEL_BRIDGE=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_E1000E=y
-CONFIG_EDAC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_SUPPORT=y
-# CONFIG_EDAC_SYNOPSYS is not set
-CONFIG_EEPROM_AT24=y
-CONFIG_EEPROM_AT25=y
-CONFIG_ELF_CORE=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXTCON=y
-CONFIG_F2FS_FS=y
-CONFIG_FB=y
-CONFIG_FB_CMDLINE=y
-# CONFIG_FB_XILINX is not set
-CONFIG_FHANDLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FPGA=y
-CONFIG_FPGA_BRIDGE=y
-# CONFIG_FPGA_DFL is not set
-# CONFIG_FPGA_MGR_ALTERA_CVP is not set
-# CONFIG_FPGA_MGR_ALTERA_PS_SPI is not set
-# CONFIG_FPGA_MGR_ICE40_SPI is not set
-# CONFIG_FPGA_MGR_MACHXO2_SPI is not set
-# CONFIG_FPGA_MGR_MICROCHIP_SPI is not set
-# CONFIG_FPGA_MGR_XILINX_SPI is not set
-CONFIG_FPGA_MGR_ZYNQ_FPGA=y
-CONFIG_FPGA_REGION=y
-CONFIG_FREEZER=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_CACHE=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=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_PINCONF=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_GENERIC_VDSO_32=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GPIO_ZYNQ=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAVE_SMP=y
-CONFIG_HDMI=y
-CONFIG_HID=y
-CONFIG_HID_GENERIC=y
-CONFIG_HID_MICROSOFT=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HWMON=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CADENCE=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_MUX=y
-CONFIG_I2C_MUX_PCA954x=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_TRIGGERED_BUFFER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_FF_MEMLESS=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_MOUSE=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_SPARSEKMAP=y
-CONFIG_INPUT_VIVALDIFMAP=y
-# CONFIG_IOMMU_DEBUGFS is not set
-# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISDN is not set
-CONFIG_JBD2=y
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_KCMP=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_XZ is not set
-CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_GPIO_POLLED=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
-CONFIG_LEDS_TRIGGER_CAMERA=y
-CONFIG_LEDS_TRIGGER_CPU=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_ONESHOT=y
-CONFIG_LEDS_TRIGGER_TRANSIENT=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_MACB=y
-# CONFIG_MACB_PCI is not set
-CONFIG_MACB_USE_HWSTAMP=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-# CONFIG_MDIO_GPIO is not set
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MFD_VEXPRESS_SYSREG=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CQHCI=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF_ARASAN=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_MODULE_STRIPPED is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_CYAPA is not set
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_BYD=y
-CONFIG_MOUSE_PS2_CYPRESS=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-CONFIG_MOUSE_PS2_FOCALTECH=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SMBUS=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEON=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-# CONFIG_NET_VENDOR_CIRRUS is not set
-# CONFIG_NET_VENDOR_FARADAY is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_MICROCHIP is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_SMSC is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_VIA is not set
-CONFIG_NLS=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NO_IOPORT_MAP=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-# CONFIG_OF_FPGA_REGION is not set
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_PCI=y
-CONFIG_PCIE_XILINX=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_ZYNQ=y
-CONFIG_PL310_ERRATA_588369=y
-CONFIG_PL310_ERRATA_727915=y
-CONFIG_PL310_ERRATA_753970=y
-CONFIG_PL310_ERRATA_769419=y
-CONFIG_PL330_DMA=y
-# CONFIG_PL353_SMC is not set
-CONFIG_PLAT_VERSATILE=y
-CONFIG_PM=y
-CONFIG_PMBUS=y
-CONFIG_PM_CLK=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_VEXPRESS=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PROC_EVENTS=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_R8169=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-# CONFIG_REGULATOR_VEXPRESS is not set
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_ZYNQ=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-# CONFIG_SCHED_CORE is not set
-CONFIG_SCHED_MC=y
-CONFIG_SCHED_SMT=y
-CONFIG_SENSORS_PMBUS=y
-CONFIG_SENSORS_UCD9000=y
-CONFIG_SENSORS_UCD9200=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_XILINX_PS_UART=y
-CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
-CONFIG_SERIO=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_CADENCE=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_XILINX=y
-CONFIG_SPI_ZYNQ_QSPI=y
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYSFS_SYSCALL=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_TEXTSEARCH is not set
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_OF=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_UIO=y
-# CONFIG_UIO_AEC is not set
-# CONFIG_UIO_CIF is not set
-# CONFIG_UIO_DMEM_GENIRQ is not set
-# CONFIG_UIO_MF624 is not set
-# CONFIG_UIO_NETX is not set
-# CONFIG_UIO_PCI_GENERIC is not set
-CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_PRUSS is not set
-# CONFIG_UIO_SERCOS3 is not set
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_CHIPIDEA=y
-CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_UDC=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_XILINX=y
-CONFIG_USB_HID=y
-CONFIG_USB_NET_DRIVERS=y
-CONFIG_USB_OTG=y
-CONFIG_USB_OTG_FSM=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ULPI=y
-CONFIG_USB_ULPI_BUS=y
-CONFIG_USB_ULPI_VIEWPORT=y
-CONFIG_USE_OF=y
-CONFIG_VEXPRESS_CONFIG=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VGA_ARB=y
-CONFIG_VGA_ARB_MAX_GPUS=16
-CONFIG_VITESSE_PHY=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XILINX_EMACLITE=y
-# CONFIG_XILINX_PR_DECOUPLER is not set
-CONFIG_XILINX_WATCHDOG=y
-CONFIG_XILINX_XADC=y
-CONFIG_XPS=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_XZ_DEC_IA64=y
-CONFIG_XZ_DEC_POWERPC=y
-CONFIG_XZ_DEC_SPARC=y
-CONFIG_XZ_DEC_X86=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/zynq/config-6.6 b/target/linux/zynq/config-6.6
new file mode 100644
index 0000000000..15716a12cd
--- /dev/null
+++ b/target/linux/zynq/config-6.6
@@ -0,0 +1,570 @@
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_ALTERA_FREEZE_BRIDGE is not set
+# CONFIG_ALTERA_PR_IP_CORE is not set
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
+# CONFIG_ARCH_VEXPRESS_SPC is not set
+CONFIG_ARCH_ZYNQ=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_ERRATA_643719=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_GIC=y
+CONFIG_ARM_GLOBAL_TIMER=y
+CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_PL172_MPMC is not set
+# CONFIG_ARM_SMMU is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_TIMER_SP804=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ARM_ZYNQ_CPUIDLE=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+# CONFIG_AXI_DMAC is not set
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BOUNCE=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CADENCE_TTC_TIMER=y
+CONFIG_CADENCE_WATCHDOG=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_VERSATILE=y
+CONFIG_CLK_ICST=y
+CONFIG_CLK_SP810=y
+CONFIG_CLK_VEXPRESS_OSC=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=16
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SYSFS is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_SI570=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONNECTOR=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_COREDUMP=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+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_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DMADEVICES=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DRM=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_E1000E=y
+CONFIG_EDAC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_LEGACY_SYSFS=y
+CONFIG_EDAC_SUPPORT=y
+# CONFIG_EDAC_SYNOPSYS is not set
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_ELF_CORE=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_F2FS_FS=y
+CONFIG_FB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_IOMEM_FOPS=y
+# CONFIG_FB_XILINX is not set
+CONFIG_FHANDLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FPGA=y
+CONFIG_FPGA_BRIDGE=y
+# CONFIG_FPGA_DFL is not set
+# CONFIG_FPGA_MGR_ALTERA_CVP is not set
+# CONFIG_FPGA_MGR_ALTERA_PS_SPI is not set
+# CONFIG_FPGA_MGR_ICE40_SPI is not set
+# CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI is not set
+# CONFIG_FPGA_MGR_MACHXO2_SPI is not set
+# CONFIG_FPGA_MGR_MICROCHIP_SPI is not set
+# CONFIG_FPGA_MGR_XILINX_SPI is not set
+CONFIG_FPGA_MGR_ZYNQ_FPGA=y
+CONFIG_FPGA_REGION=y
+CONFIG_FREEZER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_CACHE=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=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_PCI_IOMAP=y
+CONFIG_GENERIC_PINCONF=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_GENERIC_VDSO_32=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_ZYNQ=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAVE_SMP=y
+CONFIG_HDMI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CADENCE=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_MOUSE=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_VIVALDIFMAP=y
+# CONFIG_IOMMUFD is not set
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
+# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISDN is not set
+CONFIG_JBD2=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_KCMP=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_XZ is not set
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+CONFIG_KMAP_LOCAL=y
+CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MACB=y
+# CONFIG_MACB_PCI is not set
+CONFIG_MACB_USE_HWSTAMP=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_MEMORY=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_VEXPRESS_SYSREG=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CQHCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODULE_STRIPPED is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_CYAPA is not set
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_BYD=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+CONFIG_MOUSE_PS2_FOCALTECH=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SMBUS=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NEON=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_IOPORT_MAP=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+# CONFIG_OF_FPGA_REGION is not set
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PCI=y
+CONFIG_PCIE_XILINX=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PINCTRL_ZYNQ=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_PL330_DMA=y
+# CONFIG_PL353_SMC is not set
+CONFIG_PLAT_VERSATILE=y
+CONFIG_PM=y
+CONFIG_PMBUS=y
+CONFIG_PM_CLK=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_VEXPRESS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PROC_EVENTS=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_R8169=y
+CONFIG_R8169_LEDS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_VEXPRESS is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_ZYNQ=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+# CONFIG_SCHED_CORE is not set
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_SENSORS_PMBUS=y
+CONFIG_SENSORS_UCD9000=y
+CONFIG_SENSORS_UCD9200=y
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+CONFIG_SERIO=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BUS=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_CADENCE=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_XILINX=y
+CONFIG_SPI_ZYNQ_QSPI=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SRAM=y
+CONFIG_SRAM_EXEC=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWPHY=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_TEXTSEARCH is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=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_UIO=y
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_CIF is not set
+# CONFIG_UIO_DMEM_GENIRQ is not set
+# CONFIG_UIO_MF624 is not set
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_PRUSS is not set
+# CONFIG_UIO_SERCOS3 is not set
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_XILINX=y
+CONFIG_USB_NET_DRIVERS=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_FSM=y
+CONFIG_USB_PHY=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_BUS=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USE_OF=y
+CONFIG_VEXPRESS_CONFIG=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_VIDEO_NOMODESET=y
+CONFIG_VITESSE_PHY=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XILINX_EMACLITE=y
+# CONFIG_XILINX_PR_DECOUPLER is not set
+CONFIG_XILINX_WATCHDOG=y
+CONFIG_XILINX_XADC=y
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/zynq/image/Makefile b/target/linux/zynq/image/Makefile
index 0931871624..4a9c2f047d 100644
--- a/target/linux/zynq/image/Makefile
+++ b/target/linux/zynq/image/Makefile
@@ -29,6 +29,7 @@ endef
define Device/Default
PROFILES := Default
+ DTS_DIR := $(DTS_DIR)/xilinx
DEVICE_DTS := $(lastword $(subst _, ,$(1)))
KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
KERNEL_LOADADDR := 0x8000